diff --git a/drivers/staging/fw-api/fw/htt.h b/drivers/staging/fw-api/fw/htt.h index fe664eaef0e36863e652e55cfbf56e5c51e8510e..b1f72a3d06bac9153f87649c4306a066bf434eef 100644 --- a/drivers/staging/fw-api/fw/htt.h +++ b/drivers/staging/fw-api/fw/htt.h @@ -264,10 +264,9 @@ * 3.134 Add qdata_refill flag in rx_peer_metadata_v1a. * 3.135 Add HTT_HOST4_TO_FW_RXBUF_RING def. * 3.136 Add htt_ext_present flag in htt_tx_tcl_global_seq_metadata. - * 3.137 Add more HTT_SDWF_MSDUQ_CFG_IND_ERROR codes. */ #define HTT_CURRENT_VERSION_MAJOR 3 -#define HTT_CURRENT_VERSION_MINOR 137 +#define HTT_CURRENT_VERSION_MINOR 136 #define HTT_NUM_TX_FRAG_DESC 1024 @@ -834,11 +833,6 @@ typedef enum { HTT_STATS_TX_PDEV_WIFI_RADAR_TAG = 200, /* htt_stats_tx_pdev_wifi_radar_tlv */ HTT_STATS_TXBF_OFDMA_BE_PARBW_TAG = 201, /* htt_stats_txbf_ofdma_be_parbw_tlv */ HTT_STATS_RX_PDEV_RSSI_HIST_TAG = 202, /* htt_stats_rx_pdev_rssi_hist_tlv */ - HTT_STATS_TX_VDEV_NSS_TAG = 203, /* htt_stats_tx_vdev_nss_tlv */ - HTT_STATS_PDEV_SPECTRAL_TAG = 204, /* htt_stats_pdev_spectral_tlv */ - HTT_STATS_PDEV_RTT_DELAY_TAG = 205, /* htt_stats_pdev_rtt_delay_tlv */ - HTT_STATS_PDEV_AOA_TAG = 206, /* htt_stats_pdev_aoa_tlv */ - HTT_STATS_PDEV_FTM_TPCCAL_TAG = 207, /* htt_stats_pdev_ftm_tpccal_tlv */ HTT_STATS_MAX_TAG, } htt_stats_tlv_tag_t; @@ -23101,18 +23095,15 @@ typedef struct _htt_tx_latency_stats { /* HTT_T2H_MSG_TYPE_SDWF_MSDUQ_CFG_IND */ typedef enum { - HTT_SDWF_MSDUQ_CFG_IND_ERROR_NONE = 0x00, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_PEER_DELETE_IN_PROG = 0x01, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_SW_MSDUQ_NULL = 0x02, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_MSDUQ_LOCATE_ERROR = 0x03, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_QPEER_NULL = 0x04, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_DEACTIVATED_MSDUQ = 0x05, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_REACTIVATED_MSDUQ = 0x06, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_INVALID_SVC_CLASS = 0x07, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_TIDQ_LOCATE_ERROR = 0x08, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_INCORRECT_SVC_CLASS = 0x09, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_DISABLED_SVC_CLASS = 0x0a, - HTT_SDWF_MSDUQ_CFG_IND_ERROR_SVC_CLASS_OUT_OF_RANGE = 0x0b, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_NONE = 0x00, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_PEER_DELETE_IN_PROG = 0x01, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_SW_MSDUQ_NULL = 0x02, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_MSDUQ_LOCATE_ERROR = 0x03, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_QPEER_NULL = 0x04, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_DEACTIVATED_MSDUQ = 0x05, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_REACTIVATED_MSDUQ = 0x06, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_INVALID_SVC_CLASS = 0x07, + HTT_SDWF_MSDUQ_CFG_IND_ERROR_TIDQ_LOCATE_ERROR = 0x08, } HTT_SDWF_MSDUQ_CFG_IND_ERROR_CODE_E; PREPACK struct htt_t2h_sdwf_msduq_cfg_ind { diff --git a/drivers/staging/fw-api/fw/htt_stats.h b/drivers/staging/fw-api/fw/htt_stats.h index 75440dc6f63c1cc5b72c701a5efaa51b41db0dd7..f685062a133bdd1e7f71ec1f5e8f7b68cfd67b54 100644 --- a/drivers/staging/fw-api/fw/htt_stats.h +++ b/drivers/staging/fw-api/fw/htt_stats.h @@ -363,7 +363,7 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_FSE_RX = 28, - /** HTT_DBG_EXT_STATS_PEER_CTRL_PATH_TXRX + /** HTT_DBG_EXT_PEER_CTRL_PATH_TXRX_STATS * PARAMS: * - config_param0: [Bit0] : [1] for mac_addr based request * - config_param1: [Bit31 : Bit0] mac_addr31to0 @@ -371,10 +371,7 @@ enum htt_dbg_ext_stats_type { * RESP MSG: * - htt_ctrl_path_txrx_stats_t */ - HTT_DBG_EXT_STATS_PEER_CTRL_PATH_TXRX = 29, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PEER_CTRL_PATH_TXRX_STATS = - HTT_DBG_EXT_STATS_PEER_CTRL_PATH_TXRX, + HTT_DBG_EXT_PEER_CTRL_PATH_TXRX_STATS = 29, /** HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT * PARAMS: @@ -396,18 +393,15 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_TXBF_OFDMA = 32, - /** HTT_DBG_EXT_STATS_STA_11AX_UL + /** HTT_DBG_EXT_STA_11AX_UL_STATS * PARAMS: * - No Params * RESP MSG: * - htt_sta_11ax_ul_stats */ - HTT_DBG_EXT_STATS_STA_11AX_UL = 33, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_STA_11AX_UL_STATS = - HTT_DBG_EXT_STATS_STA_11AX_UL, + HTT_DBG_EXT_STA_11AX_UL_STATS = 33, - /** HTT_DBG_EXT_STATS_VDEV_RTT_RESP + /** HTT_DBG_EXT_VDEV_RTT_RESP_STATS * PARAMS: * - config_param0: * [Bit7 : Bit0] vdev_id:8 @@ -415,89 +409,61 @@ enum htt_dbg_ext_stats_type { * RESP MSG: * - */ - HTT_DBG_EXT_STATS_VDEV_RTT_RESP = 34, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_VDEV_RTT_RESP_STATS = - HTT_DBG_EXT_STATS_VDEV_RTT_RESP, + HTT_DBG_EXT_VDEV_RTT_RESP_STATS = 34, - /** HTT_DBG_EXT_STATS_PKTLOG_AND_HTT_RING + /** HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pktlog_and_htt_ring_stats_t */ - HTT_DBG_EXT_STATS_PKTLOG_AND_HTT_RING = 35, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS = - HTT_DBG_EXT_STATS_PKTLOG_AND_HTT_RING, + HTT_DBG_EXT_PKTLOG_AND_HTT_RING_STATS = 35, - /** HTT_DBG_EXT_STATS_DLPAGER + /** HTT_DBG_EXT_STATS_DLPAGER_STATS * PARAMS: * * RESP MSG: * - htt_dlpager_stats_t */ - HTT_DBG_EXT_STATS_DLPAGER = 36, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_STATS_DLPAGER_STATS = - HTT_DBG_EXT_STATS_DLPAGER, + HTT_DBG_EXT_STATS_DLPAGER_STATS = 36, - /** HTT_DBG_EXT_STATS_PHY + /** HTT_DBG_EXT_PHY_COUNTERS_AND_PHY_STATS * PARAMS: * - No Params * RESP MSG: * - htt_phy_counters_and_phy_stats_t */ - HTT_DBG_EXT_STATS_PHY = 37, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PHY_COUNTERS_AND_PHY_STATS = - HTT_DBG_EXT_STATS_PHY, + HTT_DBG_EXT_PHY_COUNTERS_AND_PHY_STATS = 37, - /** HTT_DBG_EXT_STATS_VDEVS_TXRX + /** HTT_DBG_EXT_VDEVS_TXRX_STATS * PARAMS: * - No Params * RESP MSG: * - htt_vdevs_txrx_stats_t */ - HTT_DBG_EXT_STATS_VDEVS_TXRX = 38, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_VDEVS_TXRX_STATS = - HTT_DBG_EXT_STATS_VDEVS_TXRX, + HTT_DBG_EXT_VDEVS_TXRX_STATS = 38, - HTT_DBG_EXT_STATS_VDEV_RTT_INITIATOR = 39, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_VDEV_RTT_INITIATOR_STATS = - HTT_DBG_EXT_STATS_VDEV_RTT_INITIATOR, + HTT_DBG_EXT_VDEV_RTT_INITIATOR_STATS = 39, - /** HTT_DBG_EXT_STATS_PDEV_PER + /** HTT_DBG_EXT_PDEV_PER_STATS * PARAMS: * - No Params * RESP MSG: * - htt_tx_pdev_per_stats_t */ - HTT_DBG_EXT_STATS_PDEV_PER = 40, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PDEV_PER_STATS = - HTT_DBG_EXT_STATS_PDEV_PER, + HTT_DBG_EXT_PDEV_PER_STATS = 40, - HTT_DBG_EXT_STATS_AST_ENTRIES = 41, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_AST_ENTRIES = - HTT_DBG_EXT_STATS_AST_ENTRIES, + HTT_DBG_EXT_AST_ENTRIES = 41, - /** HTT_DBG_EXT_STATS_RX_RING + /** HTT_DBG_EXT_RX_RING_STATS * PARAMS: * - No Params * RESP MSG: * - htt_rx_fw_ring_stats_tlv_v */ - HTT_DBG_EXT_STATS_RX_RING = 42, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_RX_RING_STATS = - HTT_DBG_EXT_STATS_RX_RING, + HTT_DBG_EXT_RX_RING_STATS = 42, - /** HTT_DBG_EXT_STATS_STRM_GEN_MPDUS, - * HTT_DBG_EXT_STATS_STRM_GEN_MPDUS_DETAILS + /** HTT_STRM_GEN_MPDUS_STATS, HTT_STRM_GEN_MPDUS_DETAILS_STATS * PARAMS: * - No params * RESP MSG: HTT_T2H STREAMING_STATS_IND (not EXT_STATS_CONF) @@ -506,36 +472,25 @@ enum htt_dbg_ext_stats_type { * - HTT_STRM_GEN_MPDUS_DETAILS_STATS: * htt_stats_strm_gen_mpdus_details_tlv_t */ - HTT_DBG_EXT_STATS_STRM_GEN_MPDUS = 43, - HTT_DBG_EXT_STATS_STRM_GEN_MPDUS_DETAILS = 44, - /* retain the deprecated names as aliases */ - HTT_STRM_GEN_MPDUS_STATS = - HTT_DBG_EXT_STATS_STRM_GEN_MPDUS, - HTT_STRM_GEN_MPDUS_DETAILS_STATS = - HTT_DBG_EXT_STATS_STRM_GEN_MPDUS_DETAILS, + HTT_STRM_GEN_MPDUS_STATS = 43, + HTT_STRM_GEN_MPDUS_DETAILS_STATS = 44, - /** HTT_DBG_EXT_STATS_SOC_ERROR + /** HTT_DBG_SOC_ERROR_STATS * PARAMS: * - No Params * RESP MSG: * - htt_dmac_reset_stats_tlv */ - HTT_DBG_EXT_STATS_SOC_ERROR = 45, - /* retain the deprecated name as an alias */ - HTT_DBG_SOC_ERROR_STATS = - HTT_DBG_EXT_STATS_SOC_ERROR, + HTT_DBG_SOC_ERROR_STATS = 45, - /** HTT_DBG_EXT_STATS_PDEV_PUNCTURE + /** HTT_DBG_PDEV_PUNCTURE_STATS * PARAMS: * - param 0: enum from htt_tx_pdev_puncture_stats_upload_t, indicating * the stats to upload * RESP MSG: * - one or more htt_pdev_puncture_stats_tlv, depending on param 0 */ - HTT_DBG_EXT_STATS_PDEV_PUNCTURE = 46, - /* retain the deprecated name as an alias */ - HTT_DBG_PDEV_PUNCTURE_STATS = - HTT_DBG_EXT_STATS_PDEV_PUNCTURE, + HTT_DBG_PDEV_PUNCTURE_STATS = 46, /** HTT_DBG_EXT_STATS_ML_PEERS_INFO * PARAMS: @@ -549,59 +504,44 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_ML_PEERS_INFO = 47, - /** HTT_DBG_EXT_STATS_ODD_MANDATORY + /** HTT_DBG_ODD_MANDATORY_STATS * params: * None * Response MSG: * htt_odd_mandatory_pdev_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_MANDATORY = 48, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_MANDATORY_STATS = - HTT_DBG_EXT_STATS_ODD_MANDATORY, + HTT_DBG_ODD_MANDATORY_STATS = 48, - /** HTT_DBG_EXT_STATS_PDEV_SCHED_ALGO + /** HTT_DBG_PDEV_SCHED_ALGO_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_sched_algo_ofdma_stats_tlv */ - HTT_DBG_EXT_STATS_PDEV_SCHED_ALGO = 49, - /* retain the deprecated name as an alias */ - HTT_DBG_PDEV_SCHED_ALGO_STATS = - HTT_DBG_EXT_STATS_PDEV_SCHED_ALGO, + HTT_DBG_PDEV_SCHED_ALGO_STATS = 49, - /** HTT_DBG_EXT_STATS_ODD_MANDATORY_MUMIMO + /** HTT_DBG_ODD_MANDATORY_MUMIMO_STATS * params: * None * Response MSG: * htt_odd_mandatory_mumimo_pdev_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_MANDATORY_MUMIMO = 50, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_MANDATORY_MUMIMO_STATS = - HTT_DBG_EXT_STATS_ODD_MANDATORY_MUMIMO, - /** HTT_DBG_EXT_STATS_ODD_MANDATORY_MUOFDMA + HTT_DBG_ODD_MANDATORY_MUMIMO_STATS = 50, + /** HTT_DBG_ODD_MANDATORY_MUOFDMA_STATS * params: * None * Response MSG: * htt_odd_mandatory_muofdma_pdev_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_MANDATORY_MUOFDMA = 51, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_MANDATORY_MUOFDMA_STATS = - HTT_DBG_EXT_STATS_ODD_MANDATORY_MUOFDMA, + HTT_DBG_ODD_MANDATORY_MUOFDMA_STATS = 51, - /** HTT_DBG_EXT_STATS_PHY_PROF_CAL + /** HTT_DBG_EXT_PHY_PROF_CAL_STATS * params: * None * Response MSG: * htt_stats_latency_prof_cal_data_tlv */ - HTT_DBG_EXT_STATS_PHY_PROF_CAL = 52, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PHY_PROF_CAL_STATS = - HTT_DBG_EXT_STATS_PHY_PROF_CAL, + HTT_DBG_EXT_PHY_PROF_CAL_STATS = 52, /** HTT_DBG_EXT_STATS_PDEV_BW_MGR * PARAMS: @@ -611,127 +551,94 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_PDEV_BW_MGR = 53, - /** HTT_DBG_EXT_STATS_PDEV_MBSSID_CTRL_FRAME + /** HTT_DBG_PDEV_MBSSID_CTRL_FRAME_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_mbssid_ctrl_frame_stats */ - HTT_DBG_EXT_STATS_PDEV_MBSSID_CTRL_FRAME = 54, - /* retain the deprecated name as an alias */ - HTT_DBG_PDEV_MBSSID_CTRL_FRAME_STATS = - HTT_DBG_EXT_STATS_PDEV_MBSSID_CTRL_FRAME, + HTT_DBG_PDEV_MBSSID_CTRL_FRAME_STATS = 54, - /** HTT_DBG_EXT_STATS_SOC_SSR + /** HTT_DBG_SOC_SSR_STATS * Used for non-MLO UMAC recovery stats. * PARAMS: * - No Params * RESP MSG: * - htt_umac_ssr_stats_tlv */ - HTT_DBG_EXT_STATS_SOC_SSR = 55, - /* retain the deprecated name as an alias */ - HTT_DBG_SOC_SSR_STATS = - HTT_DBG_EXT_STATS_SOC_SSR, + HTT_DBG_SOC_SSR_STATS = 55, - /** HTT_DBG_EXT_STATS_MLO_UMAC_SSR + /** HTT_DBG_MLO_UMAC_SSR_STATS * Used for MLO UMAC recovery stats. * PARAMS: * - No Params * RESP MSG: * - htt_mlo_umac_ssr_stats_tlv */ - HTT_DBG_EXT_STATS_MLO_UMAC_SSR = 56, - /* retain the deprecated name as an alias */ - HTT_DBG_MLO_UMAC_SSR_STATS = - HTT_DBG_EXT_STATS_MLO_UMAC_SSR, + HTT_DBG_MLO_UMAC_SSR_STATS = 56, - /** HTT_DBG_EXT_STATS_PDEV_TDMA + /** HTT_DBG_PDEV_TDMA_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_tdma_stats_tlv */ - HTT_DBG_EXT_STATS_PDEV_TDMA = 57, - /* retain the deprecated name as an alias */ - HTT_DBG_PDEV_TDMA_STATS = - HTT_DBG_EXT_STATS_PDEV_TDMA, + HTT_DBG_PDEV_TDMA_STATS = 57, - /** HTT_DBG_EXT_STATS_CODEL + /** HTT_DBG_CODEL_STATS * PARAMS: * - No Params * RESP MSG: * - htt_codel_svc_class_stats_tlv * - htt_codel_msduq_stats_tlv */ - HTT_DBG_EXT_STATS_CODEL = 58, - /* retain the deprecated name as an alias */ - HTT_DBG_CODEL_STATS = - HTT_DBG_EXT_STATS_CODEL, + HTT_DBG_CODEL_STATS = 58, - /** HTT_DBG_EXT_STATS_ODD_PDEV_BE_TX_MU_OFDMA + /** HTT_DBG_ODD_PDEV_BE_TX_MU_OFDMA_STATS * PARAMS: * - No Params * RESP MSG: * - htt_tx_pdev_mpdu_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_PDEV_BE_TX_MU_OFDMA = 59, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_PDEV_BE_TX_MU_OFDMA_STATS = - HTT_DBG_EXT_STATS_ODD_PDEV_BE_TX_MU_OFDMA, + HTT_DBG_ODD_PDEV_BE_TX_MU_OFDMA_STATS = 59, - /** HTT_DBG_EXT_STATS_ODD_UL_BE_OFDMA + /** HTT_DBG_EXT_STATS_PDEV_UL_TRIGGER * PARAMS: * - No Params * RESP MSG: * - htt_rx_pdev_be_ul_ofdma_user_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_UL_BE_OFDMA = 60, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_UL_BE_OFDMA_STATS = - HTT_DBG_EXT_STATS_ODD_UL_BE_OFDMA, + HTT_DBG_ODD_UL_BE_OFDMA_STATS = 60, - /** HTT_DBG_EXT_STATS_ODD_BE_TXBF_OFDMA + /** HTT_DBG_ODD_BE_TXBF_OFDMA_STATS */ - HTT_DBG_EXT_STATS_ODD_BE_TXBF_OFDMA = 61, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_BE_TXBF_OFDMA_STATS = - HTT_DBG_EXT_STATS_ODD_BE_TXBF_OFDMA, + HTT_DBG_ODD_BE_TXBF_OFDMA_STATS = 61, - /** HTT_DBG_EXT_STATS_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG + /** HTT_DBG_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG_STATS * PARAMS: * - No Params * RESP MSG: * - htt_rx_pdev_be_ul_ofdma_user_stats_tlv */ - HTT_DBG_EXT_STATS_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG = 62, - /* retain the deprecated name as an alias */ - HTT_DBG_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG_STATS = - HTT_DBG_EXT_STATS_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG, + HTT_DBG_ODD_STATS_PDEV_BE_UL_MUMIMO_TRIG_STATS = 62, - /** HTT_DBG_EXT_STATS_MLO_SCHED + /** HTT_DBG_MLO_SCHED_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_mlo_sched_stats_tlv */ - HTT_DBG_EXT_STATS_MLO_SCHED = 63, - /* retain the deprecated name as an alias */ - HTT_DBG_MLO_SCHED_STATS = - HTT_DBG_EXT_STATS_MLO_SCHED, + HTT_DBG_MLO_SCHED_STATS = 63, - /** HTT_DBG_EXT_STATS_PDEV_MLO_IPC + /** HTT_DBG_PDEV_MLO_IPC_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_mlo_ipc_stats_tlv */ - HTT_DBG_EXT_STATS_PDEV_MLO_IPC = 64, - /* retain the deprecated name as an alias */ - HTT_DBG_PDEV_MLO_IPC_STATS = - HTT_DBG_EXT_STATS_PDEV_MLO_IPC, + HTT_DBG_PDEV_MLO_IPC_STATS = 64, - /** HTT_DBG_EXT_STATS_PDEV_RTT_RESP + /** HTT_DBG_EXT_PDEV_RTT_RESP_STATS * PARAMS: * - No Params * RESP MSG: @@ -740,22 +647,16 @@ enum htt_dbg_ext_stats_type { * - htt_stats_pdev_rtt_tbr_selfgen_queued_stats_tlv * - htt_stats_pdev_rtt_tbr_cmd_result_stats_tlv */ - HTT_DBG_EXT_STATS_PDEV_RTT_RESP = 65, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PDEV_RTT_RESP_STATS = - HTT_DBG_EXT_STATS_PDEV_RTT_RESP, + HTT_DBG_EXT_PDEV_RTT_RESP_STATS = 65, - /** HTT_DBG_EXT_STATS_PDEV_RTT_INITIATOR + /** HTT_DBG_EXT_PDEV_RTT_INITIATOR_STATS * PARAMS: * - No Params * RESP MSG: * - htt_stats_pdev_rtt_init_stats_tlv * - htt_stats_pdev_rtt_hw_stats_tlv */ - HTT_DBG_EXT_STATS_PDEV_RTT_INITIATOR = 66, - /* retain the deprecated name as an alias */ - HTT_DBG_EXT_PDEV_RTT_INITIATOR_STATS = - HTT_DBG_EXT_STATS_PDEV_RTT_INITIATOR, + HTT_DBG_EXT_PDEV_RTT_INITIATOR_STATS = 66, /** HTT_DBG_EXT_STATS_LATENCY_PROF_STATS_LO * PARAMS: @@ -767,56 +668,13 @@ enum htt_dbg_ext_stats_type { */ HTT_DBG_EXT_STATS_LATENCY_PROF_STATS_LO = 67, - /** HTT_DBG_EXT_STATS_GTX + /** HTT_DBG_GTX_STATS * PARAMS: * - No Params * RESP MSG: * - htt_pdev_gtx_stats_tlv */ - HTT_DBG_EXT_STATS_GTX = 68, - /* retain the deprecated name as an alias */ - HTT_DBG_GTX_STATS = - HTT_DBG_EXT_STATS_GTX, - - /** HTT_DBG_EXT_STATS_TX_VDEV_NSS - * PARAMS: - * - No Params - * RESP MSG: - * - htt_stats_tx_vdev_nss_tlv - */ - HTT_DBG_EXT_STATS_TX_VDEV_NSS = 69, - - /** HTT_DBG_EXT_STATS_PDEV_RTT_DELAY - * PARAMS: - * - No Params - * RESP MSG: - * - htt_stats_pdev_rtt_delay_tlv - */ - HTT_DBG_EXT_STATS_PDEV_RTT_DELAY = 70, - - /** HTT_DBG_EXT_STATS_PDEV_SPECTRAL - * PARAMS: - * - No Params - * RESP MSG: - * - htt_stats_pdev_spectral_tlv - */ - HTT_DBG_EXT_STATS_PDEV_SPECTRAL = 71, - - /** HTT_DBG_EXT_STATS_PDEV_AOA - * PARAMS: - * - No Params - * RESP MSG: - * - htt_stats_pdev_aoa_tlv - */ - HTT_DBG_EXT_STATS_PDEV_AOA = 72, - - /** HTT_DBG_EXT_STATS_PDEV_FTM_TPCCAL - * PARAMS: - * - No Params - * RESP MSG: - * - htt_stats_pdev_ftm_tpccal_tlv - */ - HTT_DBG_EXT_STATS_PDEV_FTM_TPCCAL = 73, + HTT_DBG_GTX_STATS = 68, /* keep this last */ @@ -1213,13 +1071,6 @@ typedef struct { A_UINT32 pdev_up_time_us_high; /** count of ofdma sequences flushed */ A_UINT32 ofdma_seq_flush; - /* bytes (size of MPDUs) transmitted */ - struct { - /* lower 32 bits of the tx_bytes value */ - A_UINT32 low_32; - /* upper 32 bits of the tx_bytes value */ - A_UINT32 high_32; - } bytes_sent; } htt_stats_tx_pdev_cmn_tlv; /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_tx_pdev_cmn_tlv htt_tx_pdev_stats_cmn_tlv; @@ -4790,7 +4641,6 @@ typedef struct { A_UINT32 incomplete_llc; A_UINT32 eapol_duplicate_m3; A_UINT32 eapol_duplicate_m4; - A_UINT32 eapol_invalid_mac; } htt_stats_tx_de_classify_failed_tlv; /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_tx_de_classify_failed_tlv htt_tx_de_classify_failed_stats_tlv; @@ -5555,7 +5405,6 @@ typedef struct { #define HTT_TX_PDEV_STATS_NUM_LTF 4 #define HTT_TX_PDEV_STATS_NUM_11AX_TRIGGER_TYPES 6 #define HTT_TX_PDEV_STATS_NUM_11BE_TRIGGER_TYPES 6 -#define HTT_TX_VDEV_STATS_NUM_SPATIAL_STREAMS 4 #define HTT_TX_NUM_OF_SOUNDING_STATS_WORDS \ (HTT_TX_PDEV_STATS_NUM_BW_COUNTERS * \ HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS) @@ -5775,20 +5624,6 @@ typedef struct { /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_tx_pdev_rate_stats_tlv htt_tx_pdev_rate_stats_tlv; -typedef struct { - htt_tlv_hdr_t tlv_hdr; - A_UINT32 vdev_id; /* which vdev produced these per-Nss tx stats */ - /* tx_nss: - * Count how many MPDUs the vdev has sent using each possible number - * of spatial streams: - * tx_nss[0] -> number of MPDUs transmitted using Nss=1 - * tx_nss[1] -> number of MPDUs transmitted using Nss=2 - * tx_nss[2] -> number of MPDUs transmitted using Nss=3 - * tx_nss[3] -> number of MPDUs transmitted using Nss=4 - */ - A_UINT32 tx_nss[HTT_TX_VDEV_STATS_NUM_SPATIAL_STREAMS]; -} htt_stats_tx_vdev_nss_tlv; - typedef struct { /* 11be mode pdev rate stats; placed in a separate TLV to adhere to size restrictions */ htt_tlv_hdr_t tlv_hdr; @@ -6917,16 +6752,6 @@ typedef struct { A_UINT32 rx_flush_cnt; /** Num rx recovery */ A_UINT32 rx_recovery_reset_cnt; - /* Num prom filter disable */ - A_UINT32 rx_lwm_prom_filter_dis; - /* Num prom filter enable */ - A_UINT32 rx_hwm_prom_filter_en; - struct { - /* lower 32 bits of the rx_bytes value */ - A_UINT32 low_32; - /* upper 32 bits of the rx_bytes value */ - A_UINT32 high_32; - } bytes_received; } htt_stats_rx_pdev_fw_stats_tlv; /* preserve old name alias for new name consistent with the tag name */ typedef htt_stats_rx_pdev_fw_stats_tlv htt_rx_pdev_fw_stats_tlv; @@ -8937,381 +8762,6 @@ typedef struct { typedef htt_stats_pktlog_and_htt_ring_stats_tlv htt_pktlog_and_htt_ring_stats_tlv; -/* STATS_TYPE: HTT_DBG_EXT_STATS_PDEV_SPECTRAL - * TLV_TAGS: - * HTT_STATS_PDEV_SPECTRAL_TAG - */ -#define HTT_STATS_PDEV_SPECTRAL_PCFG_MAX_DET (3) -#define HTT_STATS_PDEV_SPECTRAL_MAX_PCSS_RING_FOR_IPC (3) - -typedef struct { - htt_tlv_hdr_t tlv_hdr; - - A_UINT32 dbg_num_buf; - A_UINT32 dbg_num_events; - - /* HOST_ring_HI */ - A_UINT32 host_head_idx; - A_UINT32 host_tail_idx; - A_UINT32 host_shadow_tail_idx; - - /* SHADOW_ring_HI */ - A_UINT32 in_ring_head_idx; - A_UINT32 in_ring_tail_idx; - A_UINT32 in_ring_shadow_tail_idx; - A_UINT32 in_ring_shadow_head_idx; - - /* OUT_ring_HI */ - A_UINT32 out_ring_head_idx; - A_UINT32 out_ring_tail_idx; - A_UINT32 out_ring_shadow_tail_idx; - A_UINT32 out_ring_shadow_head_idx; - - /* IPC_ring MAX_PCSS_RING_FOR_IPC */ - struct { - A_UINT32 head_idx; - A_UINT32 tail_idx; - A_UINT32 shadow_tail_idx; - A_UINT32 shadow_head_idx; - } ipc_rings[HTT_STATS_PDEV_SPECTRAL_MAX_PCSS_RING_FOR_IPC]; - - /* VREG Counters */ - struct { - A_UINT32 scan_priority; - A_UINT32 scan_count; - A_UINT32 scan_period; - A_UINT32 scan_chn_mask; - A_UINT32 scan_ena; - A_UINT32 scan_update_mask; - A_UINT32 scan_ready_intrpt; - A_UINT32 scans_performed; - A_UINT32 intrpts_sent; - A_UINT32 scan_pending_count; - A_UINT32 num_pcss_elem_zero; - A_UINT32 num_in_elem_zero; - A_UINT32 num_out_elem_zero; - A_UINT32 num_elem_moved; - } pcfg_stats_det[HTT_STATS_PDEV_SPECTRAL_PCFG_MAX_DET]; - - struct { - A_UINT32 scan_no_ipc_buf_avail; - A_UINT32 agile_scan_no_ipc_buf_avail; - A_UINT32 scan_FFT_discard_count; - A_UINT32 scan_recapture_FFT_discard_count; - A_UINT32 scan_recapture_count; - } pcfg_stats_vreg; -} htt_stats_pdev_spectral_tlv; - -/* STATS_TYPE: HTT_DBG_EXT_STATS_PDEV_RTT_DELAY - * TLV_TAGS: - * HTT_STATS_PDEV_RTT_DELAY_TAG - */ -#define HTT_STATS_PDEV_RTT_DELAY_NUM_INSTANCES (2) -/* HTT_STATS_PDEV_RTT_DELAY_PKT_BW: - * 0 -> 20 MHz - * 1 -> 40 MHz - * 2 -> 80 MHz - * 3 -> 160 MHz - * 4 -> 320 MHz - * 5: reserved - */ -#define HTT_STATS_PDEV_RTT_DELAY_PKT_BW (6) -/* HTT_STATS_PDEV_RTT_TX_RX_INSTANCES - * idx 0 -> Tx instance - * idx 1 -> Rx instance - */ -#define HTT_STATS_PDEV_RTT_TX_RX_INSTANCES (2) -typedef struct { - htt_tlv_hdr_t tlv_hdr; - - struct { - /* base_delay: picosecond units */ - A_INT32 base_delay[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES][HTT_STATS_PDEV_RTT_DELAY_PKT_BW]; - /* final_delay: picosecond units */ - A_INT32 final_delay[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES][HTT_STATS_PDEV_RTT_DELAY_PKT_BW]; - A_INT32 per_chan_bias[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES]; - A_INT32 off_chan_bias[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES]; - A_INT32 chan_bw_bias[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES]; - A_UINT32 rtt_11mc_chain_idx[HTT_STATS_PDEV_RTT_TX_RX_INSTANCES]; - A_UINT32 chan_freq; /* MHz units */ - A_UINT32 bandwidth; /* MHz units */ - A_UINT32 vreg_cache; - A_UINT32 rtt_11mc_vreg_set_cnt; - A_UINT32 cfr_vreg_set_cnt; - A_UINT32 cir_vreg_set_cnt; - A_UINT32 digital_block_status; - } rtt_delay[HTT_STATS_PDEV_RTT_DELAY_NUM_INSTANCES]; -} htt_stats_pdev_rtt_delay_tlv; - -/* STATS_TYPE: HTT_DBG_EXT_STATS_PDEV_AOA - * TLV_TAGS: - * HTT_STATS_PDEV_AOA_TAG - */ -#define HTT_STATS_PDEV_AOA_MAX_HISTOGRAM (10) -#define HTT_STATS_PDEV_AOA_MAX_CHAINS (4) -typedef struct { - htt_tlv_hdr_t tlv_hdr; - - A_UINT32 gain_idx[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM]; - /* gain table element values: - * 0 -> default gain - * 1 -> low gain - * 2 -> very low gain - */ - A_UINT32 gain_table[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM]; - A_UINT32 phase_calculated[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM][HTT_STATS_PDEV_AOA_MAX_CHAINS]; - A_INT32 phase_in_degree[HTT_STATS_PDEV_AOA_MAX_HISTOGRAM][HTT_STATS_PDEV_AOA_MAX_CHAINS]; -} htt_stats_pdev_aoa_tlv; - -/* RTT VREG MASK */ -#define HTT_STATS_RTT_CHAN_CAPTURE_MASK 0x00000001 -#define HTT_STATS_RTT_HW_FAC_MASK 0x00000002 -#define HTT_STATS_RTT_11AZ_DELAYED_FEEDBACK_MASK 0x00000004 -#define HTT_STATS_RTT_11AZ_DROP_FIRST_LMR_MASK 0x00000008 -#define HTT_STATS_RTT_CAPTURE_CFR_MASK 0x00000010 -#define HTT_STATS_RTT_CAPTURE_CIR_MASK 0x00000020 -#define HTT_STATS_RTT_DET0_REPETITIVE_CHAN_CAPTURE_EN_MASK 0x00000040 -#define HTT_STATS_RTT_CAPTURE_SPARE_1_MASK 0x00000080 -#define HTT_STATS_RTT_CAPTURE_SPARE_2_MASK 0x00000100 - -/* RTT Digital block compensation mask */ -#define HTT_STATS_RTT_TX_IQCORR_COMP_MASK 0x00000001 -#define HTT_STATS_RTT_TX_PREEMP_FIR_COMP_MASK 0x00000002 -#define HTT_STATS_RTT_LPC_FILTER_COMP_MASK 0x00000004 -#define HTT_STATS_RTT_SM_CFR_COMP_MASK 0x00000008 -#define HTT_STATS_RTT_CAL_PDC_DIS_COMP_MASK 0x00000010 -#define HTT_STATS_RTT_CAL_PAPRD_COMP_MASK 0x00000020 -#define HTT_STATS_RTT_CAL_RXCORR_IQCORR_COMP_MASK 0x00000040 -#define HTT_STATS_RTT_CAL_RXCORR_PHASE_COMP_MASK 0x00000080 -#define HTT_STATS_RTT_PHYRF_ICI_CORR_COMP_MASK 0x00000100 -#define HTT_STATS_RTT_VSRC_PRE_FIR_SEL_COMP_MASK 0x00000200 -#define HTT_STATS_RTT_CVSRC_PRE_FIR_SEL2_COMP_MASK 0x00000400 -#define HTT_STATS_RTT_CAL_ENABLE_GAINDEPCORR_COMP_MASK 0x00000800 -#define HTT_STATS_RTT_CAL_DC_NOTCH_FILTER_COMP_MASK 0x00001000 -#define HTT_STATS_RTT_CAL_DET_PATH_COMP_MASK 0x00002000 -#define HTT_STATS_RTT_CAL_RXCORR_ADC_DC_COMP_MASK 0x00004000 -#define HTT_STATS_RTT_CAL_RXCORR_ADC_GAIN_COMP_MASK 0x00008000 -#define HTT_STATS_RTT_CAL_SPUR_FILTER_PRI_DET_COMP_MASK 0x00010000 -#define HTT_STATS_RTT_CAL_SPUR_FILTER_PRI_COMP_MASK 0x00020000 - - -#define HTT_STATS_TPCCAL_LAST_IDX_M 0x000000ff -#define HTT_STATS_TPCCAL_LAST_IDX_S 0 - -#define HTT_STATS_TPCCAL_LAST_IDX_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_LAST_IDX_M) >> \ - HTT_STATS_TPCCAL_LAST_IDX_S) - -#define HTT_STATS_TPCCAL_STATS_MEASPWR_M 0x0000ffff -#define HTT_STATS_TPCCAL_STATS_MEASPWR_S 0 - -#define HTT_STATS_TPCCAL_STATS_MEASPWR_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_STATS_MEASPWR_M) >> \ - HTT_STATS_TPCCAL_STATS_MEASPWR_S) - -#define HTT_STATS_TPCCAL_STATS_PDADC_M 0x000000ff -#define HTT_STATS_TPCCAL_STATS_PDADC_S 0 - -#define HTT_STATS_TPCCAL_STATS_PDADC_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_STATS_PDADC_M) >> \ - HTT_STATS_TPCCAL_STATS_PDADC_S) - -#define HTT_STATS_TPCCAL_STATS_CHANNEL_M 0x0000ffff -#define HTT_STATS_TPCCAL_STATS_CHANNEL_S 0 - -#define HTT_STATS_TPCCAL_STATS_CHANNEL_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_STATS_CHANNEL_M) >> \ - HTT_STATS_TPCCAL_STATS_CHANNEL_S) - -#define HTT_STATS_TPCCAL_STATS_CHAIN_M 0x00ff0000 -#define HTT_STATS_TPCCAL_STATS_CHAIN_S 16 - -#define HTT_STATS_TPCCAL_STATS_CHAIN_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_STATS_CHAIN_M) >> \ - HTT_STATS_TPCCAL_STATS_CHAIN_S) - -#define HTT_STATS_TPCCAL_STATS_GAININDEX_M 0xff000000 -#define HTT_STATS_TPCCAL_STATS_GAININDEX_S 24 - -#define HTT_STATS_TPCCAL_STATS_GAININDEX_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_STATS_GAININDEX_M) >> \ - HTT_STATS_TPCCAL_STATS_GAININDEX_S) - -#define HTT_STATS_TPCCAL_POSTPROC_CHANNEL_M 0x0000ffff -#define HTT_STATS_TPCCAL_POSTPROC_CHANNEL_S 0 - -#define HTT_STATS_TPCCAL_POSTPROC_CHANNEL_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_POSTPROC_CHANNEL_M) >> \ - HTT_STATS_TPCCAL_POSTPROC_CHANNEL_S) - -#define HTT_STATS_TPCCAL_POSTPROC_CHAIN_M 0x00ff0000 -#define HTT_STATS_TPCCAL_POSTPROC_CHAIN_S 16 - -#define HTT_STATS_TPCCAL_POSTPROC_CHAIN_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_POSTPROC_CHAIN_M) >> \ - HTT_STATS_TPCCAL_POSTPROC_CHAIN_S) - -#define HTT_STATS_TPCCAL_POSTPROC_BAND_M 0xff000000 -#define HTT_STATS_TPCCAL_POSTPROC_BAND_S 24 - -#define HTT_STATS_TPCCAL_POSTPROC_BAND_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_POSTPROC_BAND_M) >> \ - HTT_STATS_TPCCAL_POSTPROC_BAND_S) - -#define HTT_STATS_TPCCAL_POSTPROC_NUMGAIN_M 0x000000ff -#define HTT_STATS_TPCCAL_POSTPROC_NUMGAIN_S 0 - -#define HTT_STATS_TPCCAL_POSTPROC_NUMGAIN_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_POSTPROC_NUMGAIN_M) >> \ - HTT_STATS_TPCCAL_POSTPROC_NUMGAIN_S) - -#define HTT_STATS_TPCCAL_POSTPROC_CALDBSTATUS_M 0x0000ff00 -#define HTT_STATS_TPCCAL_POSTPROC_CALDBSTATUS_S 8 - -#define HTT_STATS_TPCCAL_POSTPROC_CALDBSTATUS_GET(_var) \ - (((_var) & HTT_STATS_TPCCAL_POSTPROC_CALDBSTATUS_M) >> \ - HTT_STATS_TPCCAL_POSTPROC_CALDBSTATUS_S) - -/* STATS_TYPE : HTT_DBG_EXT_PDEV_STATS_FTM_TPCCAL - * TLV_TAGS: - * - HTT_STATS_PDEV_FTM_TPCCAL_TAG - */ -#define HTT_MAX_TPCCAL_STATS 25 -#define HTT_STATS_TPC_CAL_MAX_NUM_POINTS 64 - -typedef struct { - htt_tlv_hdr_t tlv_hdr; - - /* dword__tpccal_last_idx: - * Hold the last updated index for circular buffer of tpccal - * BIT [7 : 0] :- tpcccal_last_idx - * BIT [31 : 8] :- rsvd1 - */ - union { - A_UINT32 dword__tpccal_last_idx; - struct { - A_UINT32 tpccal_last_idx:8, - rsvd1:24; - }; - }; - - /* - * Below tpccal_stats struct will have latest values of tpccal data - * of array size HTT_MAX_TPCCAL_STATS. - * If there have been fewer than HTT_MAX_TPCCAL_STATS TPC calibrations, - * the unused elements will be filled with 0x0 values. - */ - struct { - /* - * dword__measPwr: - * BIT [15 : 0] :- measPwr - * BIT [31 : 16] :- rsvd2 - */ - union { - A_INT32 dword__measPwr; - struct { - A_INT32 measPwr:16, /* dBm units */ - rsvd2:16; - }; - }; - - /* - * dword__channel_chain_gainIndex: - * hold channel chain and gain index values - * BIT [15 : 0] :- channel - * BIT [23 : 16] :- chain - * BIT [24 : 31] :- gainIndex - */ - union { - A_UINT32 dword__channel_chain_gainIndex; - struct { - A_UINT32 channel:16, /* MHz units */ - chain:8, - gainIndex:8; - }; - }; - - /* - * dword__pdadc: - * BIT [7 : 0] :- pdadc - * BIT [31 : 8] :- rsvd3 - */ - union { - A_UINT32 dword__pdadc; - struct { - A_UINT32 pdadc:8, - rsvd3:24; - }; - }; - } tpccal_stats[HTT_MAX_TPCCAL_STATS]; - - /* - * Below tpccal_stats_postproc struct will have required tpccal data - * for failures during postprocessing. - */ - struct { - /* - * calStatus can be intrepreted with the below values: - * TPCCAL_CALDATA (1 << 0) - * TPCCAL_CALINFO (1 << 1) - * TPCCAL_CALERROR (1 << 2) - * bits 6:4 - reserved - * TPCCAL_DONE_MASK (1 << 7) - * bits 15:8 - reserved - * TPCCALRSP_MISCFLAGS_CALERROR_GLUTS_NOT_FILLED (1 << 16) - * TPCCALRSP_MISCFLAGS_CALERROR_PLUT_NON_LINEAR (1 << 17) - * TPCCALRSP_MISCFLAGS_CALERROR_ATTEMPTS_EXCEEDED (1 << 18) - * bits 31:19 - reserved - */ - A_UINT32 calStatus; - /* - * The numgain field specifies how many of the - * HTT_STATS_TPC_CAL_MAX_NUM_POINTS elements in the below arrays - * contain valid data. - */ - A_INT32 measPwr[HTT_STATS_TPC_CAL_MAX_NUM_POINTS]; /* dBm units */ - A_UINT32 pdadc[HTT_STATS_TPC_CAL_MAX_NUM_POINTS]; - A_UINT32 gainIndex[HTT_STATS_TPC_CAL_MAX_NUM_POINTS]; - - /* - * dword__channel_chain_band: - * channel, chain, and band values - * BIT [15 : 0] :- channel - * BIT [23 : 16] :- chain - * BIT [31 : 24] :- band - */ - union { - A_UINT32 dword__channel_chain_band; - struct { - A_UINT32 channel:16, /* MHz units */ - chain:8, - band:8; /* 0: 2GHz, 1: 5GHz, 2: 6GHz */ - }; - }; - - /* - * dword__numgain_caldbStatus: - * numgain and caldbstatus - * BIT [7 : 0] :- numgain - * BIT [15 : 8] :- caldbstatus - * BIT [31 : 16] :- rsvd4 - * - * caldbStatus can be interpreted as below - * CALDB_COMPLETED = 0 - * CALDB_SKIPPED = 1 - * CALDB_INPROGRESS = 2 - */ - union { - A_UINT32 dword__numgain_caldbStatus; - struct { - A_UINT32 numgain:8, - caldbStatus:8, - rsvd4:16; - }; - }; - } tpccal_stats_postproc; -} htt_stats_pdev_ftm_tpccal_tlv; - #define HTT_DLPAGER_STATS_MAX_HIST 10 #define HTT_DLPAGER_ASYNC_LOCKED_PAGE_COUNT_M 0x000000FF #define HTT_DLPAGER_ASYNC_LOCKED_PAGE_COUNT_S 0 diff --git a/drivers/staging/fw-api/fw/wlan_module_ids.h b/drivers/staging/fw-api/fw/wlan_module_ids.h index d1abb818665561bb41a5309fec9a1e4d000a9d60..4895eacf92c77495b12da500652c8ebd0b28bc68 100644 --- a/drivers/staging/fw-api/fw/wlan_module_ids.h +++ b/drivers/staging/fw-api/fw/wlan_module_ids.h @@ -191,8 +191,6 @@ typedef enum { WLAN_MODULE_PHYLIB_RRI, /* 0x94 */ WLAN_MODULE_PHYLIB_SSCAN, /* 0x95 */ WLAN_MODULE_PHYLIB_RSVD, /* 0x96 */ - WLAN_MODULE_USD, /* 0x97 */ - WLAN_MODULE_C2C, /* 0x98 */ WLAN_MODULE_ID_MAX, diff --git a/drivers/staging/fw-api/fw/wlan_nan_msg.h b/drivers/staging/fw-api/fw/wlan_nan_msg.h deleted file mode 100644 index 3d180ab4f5640b08ab24377b426b78547ba8e901..0000000000000000000000000000000000000000 --- a/drivers/staging/fw-api/fw/wlan_nan_msg.h +++ /dev/null @@ -1,1834 +0,0 @@ -/* - * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. - * SPDX-License-Identifier: ISC - * - */ - -#ifndef _WLAN_NAN_MSG_H_ -#define _WLAN_NAN_MSG_H_ -#include -#include - -#ifndef WLAN_NAN_MSG_COMMON_HEADER_V2 - /* - * For backwards compatibility, use the deprecated version of - * wlan_nan_msg_common.h in systems that have not been updated - * to use the defs from the replacement wlan_nan_msg_common_v2.h - */ - #include -#else - #include - typedef nan_msg_header_t tNanMsgHeader; - typedef nan_msg_header_tp tpNanMsgHeader; -#endif - -/*--------------------------------------------------------------------------- -* WLAN NAN CONSTANTS -*--------------------------------------------------------------------------*/ -#ifndef PACKED_PRE -#define PACKED_PRE PREPACK -#endif - -#ifndef PACKED_POST -#define PACKED_POST POSTPACK -#endif - -/* ALL THE INTERFACE DEFINITIONS ARE ASSUMED TO BE IN LITTLE ENDIAN ORDER. - * BIG ENDIAN HOST IS RESPONSIBLE TO SEND/INTERPRET MESSAGES IN LITTLE - * ENDIAN FORMAT ONLY - */ - -/** 2 word representation of MAC addr */ -typedef struct { - A_UINT32 mac_addr31to0; - A_UINT32 mac_addr47to32; -} wlan_nan_mac_addr; - -/* NAN Statistics Request ID Codes */ -typedef enum -{ - NAN_STATS_ID_FIRST = 0, - NAN_STATS_ID_DE_PUBLISH = NAN_STATS_ID_FIRST, - NAN_STATS_ID_DE_SUBSCRIBE, - NAN_STATS_ID_DE_MAC, - NAN_STATS_ID_DE_TIMING_SYNC, - NAN_STATS_ID_DE_DW, - NAN_STATS_ID_DE, - NAN_STATS_ID_LAST -} tNanStatsId; - -typedef enum -{ - NAN_TLV_TYPE_FIRST = 0, - - /* Service Discovery Frame types */ - NAN_TLV_TYPE_SDF_FIRST = NAN_TLV_TYPE_FIRST, - NAN_TLV_TYPE_SERVICE_NAME = NAN_TLV_TYPE_SDF_FIRST, - NAN_TLV_TYPE_SDF_MATCH_FILTER, - NAN_TLV_TYPE_TX_MATCH_FILTER, - NAN_TLV_TYPE_RX_MATCH_FILTER, - NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, - NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO = 5, - NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT = 6, - NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE = 7, - NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE = 8, - NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE = 9, - NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE = 10, - NAN_TLV_TYPE_NAN_DATA_PATH_PARAMS = 11, - NAN_TLV_TYPE_NAN_DATA_SUPPORTED_BAND = 12, - NAN_TLV_TYPE_2G_COMMITTED_DW = 13, - NAN_TLV_TYPE_5G_COMMITTED_DW = 14, - NAN_TLV_TYPE_NAN_DATA_RSPNR_MODE = 15, - NAN_TLV_TYPE_NAN_DATA_ENABLED_IN_MATCH = 16, - NAN_TLV_TYPE_NAN20_RSPNR_ACCEPT_POLICY = 17, - NAN_TLV_TYPE_NAN_CSID = 18, - NAN_TLV_TYPE_NAN_SCID = 19, - NAN_TLV_TYPE_NAN_PMK = 20, - NAN_TLV_TYPE_SDEA_CTRL_PARAMS = 21, - NAN_TLV_TYPE_NAN20_RANGING_CONFIGURATION = 22, - NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS = 23, - NAN_TLV_TYPE_NAN20_RANGING_REQUEST = 24, - NAN_TLV_TYPE_NAN20_RANGING_RESULT = 25, - NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED = 26, - NAN_TLV_TYPE_NAN_PASSPHRASE = 27, - NAN_TLV_TYPE_NAN_EXTENDED_SSI = 28, - NAN_TLV_TYPE_DEV_CAP_ATTR_CAPABILITY = 29, - NAN_TLV_TYPE_TRANSPORT_IP_PARAM = 30, - NAN_TLV_TYPE_SERVICE_ID = 31, - NAN_TLV_TYPE_PAIRING_CONFIGURATION = 32, - NAN_TLV_TYPE_PAIRING_MATCH_PARAMS = 33, - NAN_TLV_TYPE_BOOTSTRAPPING_PARAMS = 34, - NAN_TLV_TYPE_BOOTSTRAPPING_COOKIE = 35, - NAN_TLV_TYPE_NIRA_NOUNCE = 36, - NAN_TLV_TYPE_NIRA_TAG = 37, - NAN_TLV_TYPE_NAN_CSID_EXT = 38, /* replacement for NAN_TLV_TYPE_NAN_CSID */ - NAN_TLV_TYPE_CSIA_CAP = 39, - NAN_TLV_TYPE_SDF_LAST = 4095, - - /* Configuration types */ - NAN_TLV_TYPE_CONFIG_FIRST = 4096, - NAN_TLV_TYPE_24G_SUPPORT = NAN_TLV_TYPE_CONFIG_FIRST, //4096 - NAN_TLV_TYPE_24G_BEACON, //4097 - NAN_TLV_TYPE_24G_SDF, //4098 - NAN_TLV_TYPE_24G_RSSI_CLOSE, //4099 - NAN_TLV_TYPE_24G_RSSI_MIDDLE, //4100 - NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, //4101 - NAN_TLV_TYPE_5G_SUPPORT, //4102 - NAN_TLV_TYPE_5G_BEACON, //4103 - NAN_TLV_TYPE_5G_SDF, //4104 - NAN_TLV_TYPE_5G_RSSI_CLOSE, //4105 - NAN_TLV_TYPE_5G_RSSI_MIDDLE, //4106 - NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, //4107 - NAN_TLV_TYPE_SID_BEACON, //4108 - NAN_TLV_TYPE_HOP_COUNT_LIMIT, //4109 - NAN_TLV_TYPE_MASTER_PREFERENCE, //4110 - NAN_TLV_TYPE_CLUSTER_ID_LOW, //4111 - NAN_TLV_TYPE_CLUSTER_ID_HIGH, //4112 - NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, //4113 - NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, //4114 - NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, //4115 - NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, //4116 - NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, //4117 - NAN_TLV_TYPE_DEBUGGING_FLAGS, //4118 - NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, //4119 - NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, //4120 - NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, //4121 - NAN_TLV_TYPE_HOP_COUNT_FORCE, //4122 - NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, //4123 - NAN_TLV_TYPE_RANDOM_UPDATE_TIME, //4124 - NAN_TLV_TYPE_EARLY_WAKEUP, //4125 - NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, //4126 - // 4127 unused - NAN_TLV_TYPE_DW_INTERVAL = 4128, //4128 - NAN_TLV_TYPE_DB_INTERVAL, //4129 - NAN_TLV_TYPE_FURTHER_AVAILABILITY, //4130 - NAN_TLV_TYPE_24G_CHANNEL, //4131 - NAN_TLV_TYPE_5G_CHANNEL, //4132 - NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, //4133 - NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG, // 4134 - NAN_TLV_TYPE_RANGING_AUTO_RESPONE_CFG = - NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG, // 4134 - NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON, // 4135 - NAN_TLV_TYPE_DW_EARLY_TERMINATION, // 4136 - NAN_TLV_TYPE_TX_RX_CHAINS, // 4137 - NAN_TLV_TYPE_SYSTEM_RANGING_ENABLED, // 4138 - NAN_TLV_TYPE_UNSYNC_DISCOVERY_ENABLED, // 4139 - NAN_TLV_TYPE_FOLLOWUP_MGMT_RX_ENABLED, // 4140 - - NAN_TLV_TYPE_CONFIG_LAST = 8191, - - /* Attributes types */ - NAN_TLV_TYPE_ATTRS_FIRST = 8192, - - NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP = NAN_TLV_TYPE_ATTRS_FIRST, - NAN_TLV_TYPE_WLAN_MESH_ID, - NAN_TLV_TYPE_MAC_ADDRESS, - NAN_TLV_TYPE_RECEIVED_RSSI_VALUE, - NAN_TLV_TYPE_CLUSTER_ATTRIBUTE, - NAN_TLV_TYPE_WLAN_INFRA_SSID, - NAN_TLV_TYPE_NAN_SHARED_KEY_DESC_ATTR, - NAN_TLV_TYPE_ATTRS_LAST = 12287, - - /* Events types */ - NAN_TLV_TYPE_EVENTS_FIRST = 12288, - NAN_TLV_TYPE_SELF_STA_MAC_ADDR = NAN_TLV_TYPE_EVENTS_FIRST, - NAN_TLV_TYPE_STARTED_CLUSTER, - NAN_TLV_TYPE_JOINED_CLUSTER, - NAN_TLV_TYPE_CLUSTER_SCAN_RESULTS, - NAN_TLV_TYPE_FAW_MEM_AVAIL, - NAN_TLV_TYPE_EVENTS_LAST = 16383, - - /* TCA types */ - NAN_TLV_TYPE_TCA_FIRST = 16384, - NAN_TLV_TYPE_CLUSTER_SIZE_REQ = NAN_TLV_TYPE_TCA_FIRST, - NAN_TLV_TYPE_CLUSTER_SIZE_RSP, - NAN_TLV_TYPE_TCA_LAST = 32767, - - /* Statistics types */ - NAN_TLV_TYPE_STATS_FIRST = 32768, - NAN_TLV_TYPE_DE_PUBLISH_STATS = NAN_TLV_TYPE_STATS_FIRST, - NAN_TLV_TYPE_DE_SUBSCRIBE_STATS, - NAN_TLV_TYPE_DE_MAC_STATS, - NAN_TLV_TYPE_DE_TIMING_SYNC_STATS, - NAN_TLV_TYPE_DE_DW_STATS, - NAN_TLV_TYPE_DE_STATS, - NAN_TLV_TYPE_STATS_LAST = 36863, - - /* Testmode types */ - NAN_TLV_TYPE_TESTMODE_FIRST = 36864, - NAN_TLV_TYPE_TESTMODE_GENERIC_CMD = NAN_TLV_TYPE_TESTMODE_FIRST, - NAN_TLV_TYPE_TESTMODE_LAST = 37000, - - /* NAN Security types */ - NAN_TLV_TYPE_SEC_FIRST = 37001, - NAN_TLV_TYPE_SEC_IGTK_KDE = NAN_TLV_TYPE_SEC_FIRST, - NAN_TLV_TYPE_SEC_BIGTK_KDE, - NAN_TLV_TYPE_SEC_NM_TK, - NAN_TLV_TYPE_GROUP_KEYS_PARAM, - NAN_TLV_TYPE_SEC_LAST = 37100, - - /* NAN OEM Configuration types */ - NAN_TLV_TYPE_OEM_DATA_FIRST = 37101, - NAN_TLV_TYPE_OEM1_DATA = NAN_TLV_TYPE_OEM_DATA_FIRST, - NAN_TLV_TYPE_OEM_DATA_LAST = 37150, - - - NAN_TLV_TYPE_LAST = 65535 -} tNanTlvType; - - -/* NAN Publish Types */ -typedef enum -{ - NAN_PUBLISH_TYPE_UNSOLICITED = 0, - NAN_PUBLISH_TYPE_SOLICITED, - NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED, - NAN_PUBLISH_TYPE_LAST, -} tNanPublishType; - -/* NAN Transmit Types */ -typedef enum -{ - NAN_TX_TYPE_BROADCAST = 0, - NAN_TX_TYPE_UNICAST, - NAN_TX_TYPE_LAST -} tNanTxType; - -/* NAN Match Algorithms */ -typedef enum -{ - NAN_MATCH_ALG_FIRST = 0, - NAN_MATCH_ALG_MATCH_ONCE = NAN_MATCH_ALG_FIRST, - NAN_MATCH_ALG_MATCH_CONTINUOUS, - NAN_MATCH_ALG_NEVER, - NAN_MATCH_ALG_LAST -} tNanMatchAlg; - -/* NAN Indication Disable Flag */ -typedef enum -{ - NAN_IND_ALWAYS = 0, - NAN_IND_NEVER, -} tNanIndDisableFlag; - -/* NAN Transmit Priorities */ -typedef enum -{ - NAN_TX_PRIORITY_LOW = 0, - NAN_TX_PRIORITY_NORMAL, - NAN_TX_PRIORITY_HIGH, - /* This is for special case if the service - * want to respond in same DW */ - NAN_TX_PRIORITY_CRITICAL, - NAN_TX_PRIORITY_LAST -} tNanTxPriority; - -/* PMK length */ -#define NAN_PMK_LEN 32 -/* Passphrase length */ -#define NAN_PASSPHRASE_MIN_LEN 8 -#define NAN_PASSPHRASE_MAX_LEN 63 -/* Supported NAN SCID buffer length */ -#define NAN_SCID_BUF_LEN 256 - -/* NAN Status Codes */ -typedef enum -{ - /* Protocol Response Codes */ - NAN_STATUS_SUCCESS = 0, - NAN_STATUS_TIMEOUT = 1, - NAN_STATUS_DE_FAILURE = 2, - NAN_STATUS_INVALID_MSG_VERSION = 3, - NAN_STATUS_INVALID_MSG_LEN = 4, - NAN_STATUS_INVALID_MSG_ID = 5, - NAN_STATUS_INVALID_HANDLE = 6, - NAN_STATUS_NO_SPACE_AVAILABLE = 7, - NAN_STATUS_INVALID_PUBLISH_TYPE = 8, - NAN_STATUS_INVALID_TX_TYPE = 9, - NAN_STATUS_INVALID_MATCH_ALGORITHM = 10, - NAN_STATUS_DISABLE_IN_PROGRESS = 11, - NAN_STATUS_INVALID_TLV_LEN = 12, - NAN_STATUS_INVALID_TLV_TYPE =13, - NAN_STATUS_MISSING_TLV_TYPE = 14, - NAN_STATUS_INVALID_TOTAL_TLVS_LEN = 15, - NAN_STATUS_INVALID_MATCH_HANDLE = 16, - NAN_STATUS_INVALID_TLV_VALUE = 17, - NAN_STATUS_INVALID_TX_PRIORITY = 18, - NAN_STATUS_INVALID_CONNECTION_MAP = 19, - NAN_STATUS_INVALID_TCA_ID = 20, - NAN_STATUS_INVALID_STATS_ID = 21, - NAN_STATUS_NAN_NOT_ALLOWED = 22, - NAN_STATUS_NO_OTA_ACK = 23, - NAN_STATUS_TX_FAIL = 24, - NAN_STATUS_MULTIPLE_ENABLE = 25, - NAN_STATUS_FOLLOWUP_QUEUE_FULL = 26, - NAN_STATUS_INVALID_5G_CHANNEL = 27, - NAN_STATUS_POLICY_MANAGER_NOT_SINGLE_MAC_MODE = 28, - NAN_STATUS_VDEV_NOT_CREATED = 29, - - /* Configuration Response Codes */ - NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096, - NAN_STATUS_INVALID_RSSI_MEDIUM_VALUE = 4097, - NAN_STATUS_INVALID_HOP_COUNT_LIMIT = 4098, - NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099, - NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100, - NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101, - NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102, - NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103, - NAN_STATUS_INVALID_SCAN_CHANNEL = 4104, - NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE = 4106, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE = 4107, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE = 4108, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE = 4109, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110, - NAN_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID = 4111, - NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112, - NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113, - NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114, - NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115, - NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116, - NAN_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117, - NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE = 4118, - NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD = 4119, - NAN_STATUS_INVALID_DW_INTERVAL_VALUE = 4120, - NAN_STATUS_INVALID_DB_INTERVAL_VALUE = 4121, - - /* Protocol Termination Indication Reason Codes */ - NAN_TERMINATED_REASON_INVALID = 8192, - NAN_TERMINATED_REASON_TIMEOUT = 8193, - NAN_TERMINATED_REASON_USER_REQUEST = 8194, - NAN_TERMINATED_REASON_FAILURE = 8195, - NAN_TERMINATED_REASON_COUNT_REACHED = 8196, - NAN_TERMINATED_REASON_DE_SHUTDOWN = 8197, /* Deprecated */ - NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS = 8198, - NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED = 8199, - NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200, - NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201, - - /* Status related to Key Install and PN */ - NAN_STATUS_INVALID_IGTK_PARAMS = 8501, - NAN_STATUS_INVALID_BIGTK_PARAMS = 8502, - NAN_STATUS_INVALID_TX_KEY_NOT_PRESENT = 8503, - NAN_STATUS_INVALID_NO_PEER_ENTRY = 8504, - - /* 9000-9500 NDP Status type */ - NDP_UNSUPPORTED_CONCURRENCY = 9000, - NDP_NAN_DATA_IFACE_CREATE_FAILED = 9001, - NDP_NAN_DATA_IFACE_DELETE_FAILED = 9002, - NDP_DATA_INITIATOR_REQUEST_FAILED = 9003, - NDP_DATA_RESPONDER_REQUEST_FAILED = 9004, - NDP_INVALID_SERVICE_INSTANCE_ID = 9005, - NDP_INVALID_NDP_INSTANCE_ID = 9006, - NDP_INVALID_RESPONSE_CODE = 9007, - NDP_INVALID_APP_INFO_LEN = 9008, - /* OTA failures and timeouts during negotiation */ - NDP_MGMT_FRAME_REQUEST_FAILED = 9009, - NDP_MGMT_FRAME_RESPONSE_FAILED = 9010, - NDP_MGMT_FRAME_CONFIRM_FAILED = 9011, - NDP_END_FAILED = 9012, - NDP_MGMT_FRAME_END_REQUEST_FAILED = 9013, - NDP_MGMT_FRAME_SECURITY_INSTALL_FAILED = 9014, - - /* 9500 onwards vendor specific error codes */ - NDP_VENDOR_SPECIFIC_ERROR = 9500 - -} tNanStatusType; - -/* Enumeration for Version */ -typedef enum -{ - NAN_MSG_VERSION1 = 1, -}tNanMsgVersion; - -/* NAN Error Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanErrorRspMsg, *tpNanErrorRspMsg; - -/* NAN Configuration Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanConfigurationRspMsg, *tpNanConfigurationRspMsg; - -/* NAN Publish Service Cancel Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanPublishServiceCancelRspMsg, *tpNanPublishServiceCancelRspMsg; - -/* NAN Publish Service Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanPublishServiceRspMsg, *tpNanPublishServiceRspMsg; - -/* NAN Subscribe Service Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanSubscribeServiceRspMsg, *tpNanSubscribeServiceRspMsg; - -/* NAN Subscribe Service Cancel Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanSubscribeServiceCancelRspMsg, *tpNanSubscribeServiceCancelRspMsg; - -/* NAN Transmit Followup Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanTransmitFollowupRspMsg, *tpNanTransmitFollowupRspMsg; - -/* NAN Self Transmit Followup Indication */ -typedef PACKED_PRE struct PACKED_POST -{ - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanSelfTransmitFollowupIndMsg, *tpNanSelfTransmitFollowupIndMsg; - -/* NAN Statistics Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT16 status; - A_UINT16 value; - A_UINT8 statsId; - A_UINT8 reserved; -} tNanStatsRspParams, *tpNanStatsRspParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanStatsRspParams statsRspParams; - A_UINT8 ptlv[1]; -} tNanStatsRspMsg, *tpNanStatsRspMsg; - -/* NAN Enable Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; -} tNanEnableRspMsg, *tpNanEnableRspMsg; - -/* NAN Disable Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 reserved; -} tNanDisableRspMsg, *tpNanDisableRspMsg; - -/* NAN TCA Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* status of the request */ - A_UINT16 status; - A_UINT16 value; -} tNanTcaRspMsg, *tpNanTcaRspMsg; - -/* NAN Beacon Sdf Payload Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* status of the request */ - A_UINT16 status; - A_UINT16 value; -} tNanBcnSdfPayloadRspMsg, *tpNanBcnSdfPayloadRspMsg; - -/* NAN Capabilities Rsp */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 status; - A_UINT32 value; - A_UINT32 maxConcurrentNanClusters; - A_UINT32 maxNumPublishes; - A_UINT32 maxNumSubscribes; - A_UINT32 maxServiceNameLen; - A_UINT32 maxMatchFilterLen; - A_UINT32 maxTotalMatchFilterLen; - A_UINT32 maxServiceSpecificInfoLen; - A_UINT32 maxVsaDataLen; - A_UINT32 maxMeshDataLen; - A_UINT32 maxNanDataInterfaces; - A_UINT32 maxNanDataPathSessions; - A_UINT32 maxNanDataAppInfoLen; - A_UINT32 maxNanQueuedTransmitFollowupMsgs; - A_UINT32 nanDataSupportedBands; - A_UINT32 nanCSIDSupported; - /* Target capability max SCID buffer supported */ - A_UINT32 maxSCIDBufsupported; - - A_UINT32 nanSecuritySupported:1; - A_UINT32 maxExtServiceSpecificInfoLen:16; - A_UINT32 maxNanRttInitiatorSupported:5; - A_UINT32 maxNanRttResponderSupported:5; - A_UINT32 nanNDPESupported:1; - A_UINT32 nanPairingSupported:1; - A_UINT32 nanUSDPublisherSupported:1; - A_UINT32 nanUSDSubscriberSupported:1; - A_UINT32 reserved:1; - - A_UINT32 maxSubscribeAddress; - A_UINT32 maxNanPairingSessions; - A_UINT32 nanGroupMfpCap; -} tNanCapabilitiesRspParams, *tpNanCapabilitiesRspParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanCapabilitiesRspParams capabilitiesRspParams; -} tNanCapabilitiesRspMsg, *tpNanCapabilitiesRspMsg; - -/* NAN Beacon Sdf Payload Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: MAC Address (when VSA Receive is present) - * Optional: VSA Receive, Beacon SDF Payload Receive - */ - A_UINT8 ptlv[1]; -} tNanBcnSdfPayloadIndMsg, *tpNanBcnSdfPayloadIndMsg; - -/* NAN TCA Ind TLV */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 rising:1; - A_UINT32 falling:1; - A_UINT32 reserved:30; - A_UINT32 value; -} tNanTcaIndTlv, *tpNanTcaIndTlv; - -/* NAN TCA Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: TCA Ind TLV (Cluster Size Rsp). - */ - A_UINT8 ptlv[1]; -} tNanTcaIndMsg, *tpNanTcaIndMsg; - -/* NAN Disable Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* reason for the termination */ - A_UINT16 reason; - A_UINT16 reserved; -} tNanDisableIndMsg, *tpNanDisableIndMsg; - -/* Event Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * Excludes TLVs - * - * Optional: Self-Station MAC Address, Started Cluster, Joined Cluster - */ - A_UINT8 ptlv[1]; -} tNanEventIndMsg, *tpNanEventIndMsg; - -/* NAN Publish Followup Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 matchHandle; - A_UINT32 window:1; - A_UINT32 reserved:31; - /* - * Excludes TLVs - * - * Required: Service Specific Info or Extended Service Specific Info - */ -} tNanFollowupIndParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanFollowupIndParams followupIndParams; - /* - * Excludes TLVs - * - * Required: MAC Address, Service Specific Info (D bit is 0) - * Optional: Service Specific Info (D bit is 1) - */ - A_UINT8 ptlv[1]; -} tNanFollowupIndMsg, *tpNanFollowupIndMsg; - -/* NAN Subscribe Terminated Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* reason for the termination */ - A_UINT16 reason; - A_UINT16 reserved; -} tNanSubscribeTerminatedIndMsg, *tpNanSubscribeTerminatedIndMsg; - -/* NAN Unmatch Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 matchHandle; -} tNanUnmatchIndParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanUnmatchIndParams unmatchIndParams; -} tNanUnmatchIndMsg, *tpNanUnmatchIndMsg; - -/* NAN Match Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 matchHandle; - A_UINT32 beaconFrameFlag:1; - A_UINT32 cacheExhaustedFlag:1; - A_UINT32 reserved:30; -} tNanMatchIndParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanMatchIndParams matchIndParams; - /* - * Excludes TLVs - * - * Required: MAC Address - * Optional: Service Specific Info, SDF Match Filter - * Received RSSI Value, Post NAN Connectivity Capabilities Rx, - * Post NAN Discovery Attribute Rx, Further Availability Map, - * Cluster Attribute, Sdea ctrl params, NAN CSID, NAN SCID - */ - A_UINT8 ptlv[1]; -} tNanMatchIndMsg, *tpNanMatchIndMsg; - -/* NAN Publish Terminated Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 reason; - A_UINT16 reserved; -} tNanPublishTerminatedIndMsg, *tpNanPublishTerminatedIndMsg; - -/* NAN Publish Replied Ind */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 matchHandle; -} tNanPublishRepliedIndParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanPublishRepliedIndParams publishRepliedIndParams; - /* - * Excludes TLVs - * - * Required: MAC Address - * Optional: Received RSSI Value, Post NAN Connectivity Capabilities Rx, - * Post NAN Discovery Attribute Rx, Further Availability Map, - * Cluster Attribute, Sdea ctrl params, NAN CSID, NAN SCID buffer - */ - A_UINT8 ptlv[1]; -} tNanPublishRepliedIndMsg, *tpNanPublishRepliedIndMsg; - -/* NAN Enable Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: Master Preference, Cluster Low, Cluster High - * Optional: 2.4G Support, 2.4G Beacons, 2.4G Discovery, 2.4G RSSI Close, - * 2.4G RSSI Middle, 2.4G RSSI Close Proximity, 5G Support, - * 5G Beacons, 5G Discovery, 5G RSSI Close, 5G RSSI Middle, - * 5G RSSI Close Proximity, SID Beacon, Hop Count Limit, - * Random Factor Force, Hop Count Force, Master Preference, - * Cluster Low, Cluster High, RSSI Averaging Window Size, - * Cluster OUI Network ID, Source MAC Address, - * Cluster Attribute in SDF, Social Channel Scan Parameters, - * Debugging Flags, Post NAN Connectivity Capabilities Tx, - * Post NAN Discovery Attribute Tx, Further Availability Map - */ - A_UINT8 ptlv[1]; -} tNanEnableReqMsg, *tpNanEnableReqMsg; - -/* NAN Disable Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; -} tNanDisableReqMsg, *tpNanDisableReqMsg; - -/* NAN Configuration Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: None. - * Optional: 2.4G RSSI Close Proximity, 5G RSSI Close Proximity, - * SID Beacon, Random Factor Force, Hop Count Force, - * Master Preference, RSSI Averaging Window Size, - * Cluster Attribute, Social Channel Scan Parameters, - * Debugging Flags, Post NAN Connectivity Capabilities Tx, - * Post NAN Discovery Attribute Tx, Further Availability Map - */ - A_UINT8 ptlv[1]; -} tNanConfigurationReqMsg, *tpNanConfigurationReqMsg; - -/* NAN Publish Service Req */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT16 ttl; - A_UINT16 period; - A_UINT32 replyIndFlag:1; - A_UINT32 publishType:2; - A_UINT32 txType:1; - A_UINT32 useRssi:1; - A_UINT32 otaFlag:1; - A_UINT32 matchAlg:2; - A_UINT32 count:8; - A_UINT32 connMap:8; - A_UINT32 pubTerminatedIndDisableFlag:1; - A_UINT32 pubUnmatchIndDisableFlag:1; - A_UINT32 followupRxIndDisableFlag:1; - A_UINT32 reserved2:5; -} tNanPublishServiceReqParams, *tpNanPublishServiceReqParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanPublishServiceReqParams publishServiceReqParams; - /* - * Excludes TLVs - * - * Required: Service Name - * Optional: Service Specific Info, Tx Match Filter, Rx Match Filter - * Sdea ctrl params, NAN CSID, PMK, PASSPHRASE - */ - A_UINT8 ptlv[1]; -} tNanPublishServiceReqMsg, *tpNanPublishServiceReqMsg; - -/* NAN Publish Service Cancel Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; -} tNanPublishServiceCancelReqMsg, *tpNanPublishServiceCancelReqMsg; - -/* NAN Subscribe Service Req */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT16 ttl; - A_UINT16 period; - A_UINT32 subscribeType:1; - A_UINT32 srfAttr:1; - A_UINT32 srfInclude:1; - A_UINT32 srfSend:1; - A_UINT32 ssiRequired:1; - A_UINT32 matchAlg:2; - A_UINT32 reserved1:1; - A_UINT32 count:8; - A_UINT32 useRssi:1; - A_UINT32 otaFlag:1; - A_UINT32 subTerminatedIndDisableFlag:1; - A_UINT32 subUnmatchIndDisableFlag:1; - A_UINT32 followupRxIndDisableFlag:1; - A_UINT32 reserved2:3; - A_UINT32 connMap:8; - /* - * Excludes TLVs - * - * Required: Service Name - * Optional: Rx Match Filter, Tx Match Filter, Service Specific Info, - * Group Key - */ -} tNanSubscribeServiceReqParams, *tpNanSubscribeServiceReqParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanSubscribeServiceReqParams subscribeServiceReqParams; - /* - * Excludes TLVs - * - * Required: Service Name - * Optional: Rx Match Filter, Tx Match Filter, Service Specific Info, - * Sdea ctrl params, NAN CSID, PMK, PASSPHRASE - */ - A_UINT8 ptlv[1]; -} tNanSubscribeServiceReqMsg, *tpNanSubscribeServiceReqMsg; - -/* NAN Subscribe Service Cancel Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; -} tNanSubscribeServiceCancelReqMsg, *tpNanSubscribeServiceCancelReqMsg; - -/* NAN Transmit Followup Req */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 matchHandle; - A_UINT32 priority:4; - A_UINT32 window:1; - A_UINT32 followupTxRspDisableFlag:1; - A_UINT32 reserved:26; - /* - * Excludes TLVs - * - * Required: Service Specific Info or Extended Service Specific Info - */ -} tNanTransmitFollowupReqParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanTransmitFollowupReqParams transmitFollowupReqParams; - /* - * Excludes TLVs - * - * Required: MAC Address, Service Specific Info (D bit is 0) - * Optional: Service Specific Info (D bit is 1) - */ - A_UINT8 ptlv[1]; -} tNanTransmitFollowupReqMsg, *tpNanTransmitFollowupReqMsg; - -/* NAN Statistics Req */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 statsId:8; - A_UINT32 clear:1; - A_UINT32 reserved:23; -} tNanStatsReqParams, *tpNanStatsReqParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanStatsReqParams statsReqParams; -} tNanStatsReqMsg, *tpNanStatsReqMsg; - -/* NAN TCA Req TLV */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 rising:1; - A_UINT32 falling:1; - A_UINT32 clear:1; - A_UINT32 reserved:29; - A_UINT32 threshold; -} tNanTcaReqParams, *tpNanTcaReqParams; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: TCA Req TLV (Cluster Size Req). - */ - A_UINT8 ptlv[1]; -} tNanTcaReqMsg, *tpNanTcaReqMsg; - -/* Publish statistics. */ -typedef struct -{ - A_UINT32 validPublishServiceReqMsgs; - A_UINT32 validPublishServiceRspMsgs; - A_UINT32 validPublishServiceCancelReqMsgs; - A_UINT32 validPublishServiceCancelRspMsgs; - A_UINT32 validPublishRepliedIndMsgs; - A_UINT32 validPublishTerminatedIndMsgs; - A_UINT32 validActiveSubscribes; - A_UINT32 validMatches; - A_UINT32 validFollowups; - A_UINT32 invalidPublishServiceReqMsgs; - A_UINT32 invalidPublishServiceCancelReqMsgs; - A_UINT32 invalidActiveSubscribes; - A_UINT32 invalidMatches; - A_UINT32 invalidFollowups; - A_UINT32 publishCount; - A_UINT32 publishNewMatchCount; - A_UINT32 pubsubGlobalNewMatchCount; -} tNanPublishStats, *tpNanPublishStats; - -/* Subscribe statistics. */ -typedef struct -{ - A_UINT32 validSubscribeServiceReqMsgs; - A_UINT32 validSubscribeServiceRspMsgs; - A_UINT32 validSubscribeServiceCancelReqMsgs; - A_UINT32 validSubscribeServiceCancelRspMsgs; - A_UINT32 validSubscribeTerminatedIndMsgs; - A_UINT32 validSubscribeMatchIndMsgs; - A_UINT32 validSubscribeUnmatchIndMsgs; - A_UINT32 validSolicitedPublishes; - A_UINT32 validMatches; - A_UINT32 validFollowups; - A_UINT32 invalidSubscribeServiceReqMsgs; - A_UINT32 invalidSubscribeServiceCancelReqMsgs; - A_UINT32 invalidSubscribeFollowupReqMsgs; - A_UINT32 invalidSolicitedPublishes; - A_UINT32 invalidMatches; - A_UINT32 invalidFollowups; - A_UINT32 subscribeCount; - A_UINT32 bloomFilterIndex; - A_UINT32 subscribeNewMatchCount; - A_UINT32 pubsubGlobalNewMatchCount; -} tNanSubscribeStats, *tpNanSubscribeStats; - -/* NAN MAC Statistics. Used for MAC and DW statistics. */ -typedef struct -{ - /* RX stats */ - A_UINT32 validFrames; - A_UINT32 validActionFrames; - A_UINT32 validBeaconFrames; - A_UINT32 ignoredActionFrames; - A_UINT32 ignoredBeaconFrames; - A_UINT32 invalidFrames; - A_UINT32 invalidActionFrames; - A_UINT32 invalidBeaconFrames; - A_UINT32 invalidMacHeaders; - A_UINT32 invalidPafHeaders; - A_UINT32 nonNanBeaconFrames; - - A_UINT32 earlyActionFrames; - A_UINT32 inDwActionFrames; - A_UINT32 lateActionFrames; - - /* TX stats */ - A_UINT32 framesQueued; - A_UINT32 totalTRSpUpdates; - A_UINT32 completeByTRSp; - A_UINT32 completeByTp75DW; - A_UINT32 completeByTendDW; - A_UINT32 lateActionFramesTx; - - /* Misc stats - ignored for DW. */ - A_UINT32 twIncreases; - A_UINT32 twDecreases; - A_UINT32 twChanges; - A_UINT32 twHighwater; - A_UINT32 bloomFilterIndex; - -} tNanMacStats, *tpNanMacStats; - -/* NAN Sync Statistics: TBD */ -typedef struct -{ - A_UINT64 currTsf; - A_UINT64 myRank; - A_UINT64 currAmRank; - A_UINT64 lastAmRank; - A_UINT32 currAmBTT; - A_UINT32 lastAmBTT; - A_UINT8 currAmHopCount; - A_UINT8 currRole; - A_UINT16 currClusterId; - - A_UINT32 reserved1; /* NOTE: Needed for padding for uint64 alignment of following 4 fields */ - - A_UINT64 timeSpentInCurrRole; - A_UINT64 totalTimeSpentAsMaster; - A_UINT64 totalTimeSpentAsNonMasterSync; - A_UINT64 totalTimeSpentAsNonMasterNonSync; - A_UINT32 transitionsToAnchorMaster; - A_UINT32 transitionsToMaster; - A_UINT32 transitionsToNonMasterSync; - A_UINT32 transitionsToNonMasterNonSync; - A_UINT32 amrUpdateCount; - A_UINT32 amrUpdateRankChangedCount; - A_UINT32 amrUpdateBTTChangedCount; - A_UINT32 amrUpdateHcChangedCount; - A_UINT32 amrUpdateNewDeviceCount; - A_UINT32 amrExpireCount; - A_UINT32 mergeCount; - A_UINT32 beaconsAboveHcLimit; - A_UINT32 beaconsBelowRssiThresh; - A_UINT32 beaconsIgnoredNoSpace; - A_UINT32 beaconsForOurCluster; - A_UINT32 beaconsForOtherCluster; - A_UINT32 beaconCancelRequests; - A_UINT32 beaconCancelFailures; - A_UINT32 beaconUpdateRequests; - A_UINT32 beaconUpdateFailures; - A_UINT32 syncBeaconTxAttempts; - A_UINT32 syncBeaconTxFailures; - A_UINT32 discBeaconTxAttempts; - A_UINT32 discBeaconTxFailures; - A_UINT32 amHopCountExpireCount; - A_UINT32 ndpChannelFreq; - A_UINT32 ndpChannelFreq2; - A_UINT32 schedUpdateChannelFreq; - -} tNanSyncStats, *tpNanSyncStats; - -/* NAN Misc DE Statistics */ -typedef struct -{ - A_UINT32 validErrorRspMsgs; - A_UINT32 validTransmitFollowupReqMsgs; - A_UINT32 validTransmitFollowupRspMsgs; - A_UINT32 validFollowupIndMsgs; - A_UINT32 validConfigurationReqMsgs; - A_UINT32 validConfigurationRspMsgs; - A_UINT32 validStatsReqMsgs; - A_UINT32 validStatsRspMsgs; - A_UINT32 validEnableReqMsgs; - A_UINT32 validEnableRspMsgs; - A_UINT32 validDisableReqMsgs; - A_UINT32 validDisableRspMsgs; - A_UINT32 validDisableIndMsgs; - A_UINT32 validEventIndMsgs; - A_UINT32 validTcaReqMsgs; - A_UINT32 validTcaRspMsgs; - A_UINT32 validTcaIndMsgs; - A_UINT32 invalidTransmitFollowupReqMsgs; - A_UINT32 invalidConfigurationReqMsgs; - A_UINT32 invalidStatsReqMsgs; - A_UINT32 invalidEnableReqMsgs; - A_UINT32 invalidDisableReqMsgs; - A_UINT32 invalidTcaReqMsgs; - A_UINT32 validBcnSdfPayloadReqMsgs; - A_UINT32 validBcnSdfPayloadRspMsgs; - A_UINT32 validBcnSdfPayloadIndMsgs; - A_UINT32 invalidBcnSdfPayloadReqMsgs; - A_UINT32 validCapabilitiesReqMsgs; - A_UINT32 invalidCapabilitiesReqMsgs; - A_UINT32 validCapabilitiesRspMsgs; -} tNanDeStats, *tpNanDeStats; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 s:1; - A_UINT8 count:7; -} tNanSidAttr, *tpSidAttr; - -/* NAN BcnSdfPayload Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: VSA Transmit - * Optional: None - */ - A_UINT8 ptlv[1]; -} tNanBcnSdfPayloadReqMsg, *tpNanBcnSdfPayloadReqMsg; - -/* Get NAN Capabilities Req */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; -} tNanCapabilitiesReqMsg, *tpNanCapabilitiesReqMsg; - -/* These are in the same order as the Conn Types below. */ -#define NAN_CONN_MAP_NONE 0x00 -#define NAN_CONN_MAP_WLAN_INFRA 0x01 -#define NAN_CONN_MAP_P2P_OPERATION 0x02 -#define NAN_CONN_MAP_WLAN_IBSS 0x04 -#define NAN_CONN_MAP_WLAN_MESH 0x08 -#define NAN_CONN_MAP_FURTHER_SVC_AVAIL 0x10 -#define NAN_CONN_MAP_WLAN_RANGING 0x20 -#define NAN_CONN_MAP_RESERVED 0x40 -#define NAN_CONN_MAP_WILDCARD 0x80 - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 channel; - A_UINT8 dwellTime; - A_UINT16 scanPeriod; -} tNanSocialChannelScanParams, *tpSocialChannelScanParams; - -#define NAN_POST_NAN_CONN_CAP_WFD 0x0001 -#define NAN_POST_NAN_CONN_CAP_WFDS 0x0002 -#define NAN_POST_NAN_CONN_CAP_TDLS 0x0004 -#define NAN_POST_NAN_CONN_CAP_WLAN_INFRA 0x0008 -#define NAN_POST_NAN_CONN_CAP_IBSS 0x0010 -#define NAN_POST_NAN_CONN_CAP_MESH 0x0020 -#define NAN_POST_NAN_CONN_CAP_RESERVED 0xFFC0 - -/* Post-NAN Connectivity Capabilities Transmit TLV */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT16 connCap; - A_UINT16 repeat:1; - A_UINT16 reserved:15; -} tNanPostNanConnCapsTxTlv, *tpNanPostNanConnCapsTxTlv; - -/* Post-NAN Connectivity Capabilities Receive TLV */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT16 connCap; - A_UINT16 reserved; -} tNanPostNanConnCapsRxTlv, *tpNanPostNanConnCapsRxTlv; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 availIntDuration:2; - - A_UINT8 mapId:4; - A_UINT8 reserved:2; -} tNanApiEntryCtrl; - -typedef enum -{ - NAN_FAM_AID_FIRST = 0, - NAN_FAM_AID_16TU = NAN_FAM_AID_FIRST, - NAN_FAM_AID_32TU, - NAN_FAM_AID_64TU, - NAN_FAM_AID_RESERVED, - NAN_FAM_AID_LAST = NAN_FAM_AID_RESERVED, - NAN_NUM_FAM_AID = NAN_FAM_AID_LAST -} tNanFamAid; - -/* - * Convenience types for the Availability Intervals Bitmap. Could do - * these as arrays of U8s too. They may or may not be useful... - */ -typedef A_UINT8 tNanAiBitmap64tu; -typedef A_UINT16 tNanAiBitmap32tu; -typedef A_UINT32 tNanAiBitmap16tu; - -/* - * Valid Operating Classes were derived from IEEE Std. 802.11-2012 Annex E - * Table E-4 Global Operating Classes and, filtered by channel, are: 81, 83, - * 84, 103, 114, 115, 116, 124, 125. (I think). - */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 opClass; - A_UINT8 channel; - A_UINT8 availIntBitmap[4]; -} tNanFurtherAvailabilityChan, *tpNanFurtherAvailabilityChan; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 numChan; - tNanApiEntryCtrl entryCtrl; - A_UINT8 pFaChan[1]; -} tNanFurtherAvailabilityMapAttrTlv, *tpNanFurtherAvailabilityMapAttrTlv; - -typedef enum -{ - NAN_CONN_TYPE_FIRST = 0, - NAN_CONN_TYPE_WLAN_INFRA = NAN_CONN_TYPE_FIRST, - NAN_CONN_TYPE_P2P_OPERATION, - NAN_CONN_TYPE_WLAN_IBSS, - NAN_CONN_TYPE_WLAN_MESH, - NAN_CONN_TYPE_FURTHER_SVC_AVAIL, - NAN_CONN_TYPE_WLAN_RANGING, - NAN_CONN_TYPE_LAST, - NAN_CONN_TYPE_RESERVED = NAN_CONN_TYPE_LAST, - NAN_CONN_TYPE_WILDCARD -} tNanConnType; - -/* Device Roles */ -typedef enum -{ - NAN_DEVICE_ROLE_FIRST = 0, - NAN_DEVICE_ROLE_WLAN_INFRA_FIRST = NAN_DEVICE_ROLE_FIRST, - NAN_DEVICE_ROLE_WLAN_AP = NAN_DEVICE_ROLE_WLAN_INFRA_FIRST, - NAN_DEVICE_ROLE_WLAN_STA, - NAN_DEVICE_ROLE_WLAN_INFRA_LAST, - NAN_DEVICE_ROLE_P2P_OPERATION_FIRST = NAN_DEVICE_ROLE_WLAN_INFRA_LAST, - NAN_DEVICE_ROLE_P2P_GROUP_OWNER = NAN_DEVICE_ROLE_P2P_OPERATION_FIRST, - NAN_DEVICE_ROLE_P2P_DEVICE, - NAN_DEVICE_ROLE_P2P_CLIENT, - NAN_DEVICE_ROLE_P2P_OPERATION_LAST, - NAN_DEVICE_ROLE_LAST = NAN_DEVICE_ROLE_P2P_OPERATION_LAST -} tNanDeviceRole; - -/* - * Post-NAN Discovery Attribute MAC Address Usage: - * - * Connection Type | Device Role | MAC Address Usage - * --------------------+-----------------+------------------------- - * WLAN Infrastructure | N/A | MSSID of the AP - * P2P Operation | P2P_Group Owner | P2P Group Owner's address - * P2P Operation | P2P Device | P2P Client's address - * WLAN IBSS | N/A | BSSID - * WLAN Mesh | N/A | BSSID - * Other | ??? | ??? - * - */ - -/* Post-NAN Discovery Attribute Transmit TLV. */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 connType; - A_UINT8 deviceRole; - A_UINT16 repeat:1; - A_UINT16 duration:2; - A_UINT16 reserved:13; - A_UINT8 availIntBitmap[4]; - /* - * TLVs: - * - * Required: WLAN Mesh ID (if connType is WLAN_MESH), - * MAC Address (if connType is WLAN Infra, P2P, IBSS, or Mesh) - */ - A_UINT8 ptlv[1]; -} tNanPostNanDiscoveryAttrTxTlv, tpNanPostNanDiscoveryAttrTxTlv; - -/* Post-NAN Discovery Attribute Receive TLV. */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 connType; - A_UINT8 deviceRole; - A_UINT16 duration:2; - A_UINT16 mapId:4; - A_UINT16 reserved:10; - A_UINT8 availIntBitmap[4]; - /* - * TLVs: - * - * Required: WLAN Mesh ID (if connType is WLAN_MESH), - * MAC Address (if connType is WLAN Infra, P2P, IBSS, or Mesh) - */ - A_UINT8 ptlv[1]; -} tNanPostNanDiscoveryAttrRxTlv, tpNanPostNanDiscoveryAttrRxTlv; - -/* NAN Vendor Specific Attribute Transmit/Receive TLV */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 rflag:1; /* Ignored for receive case. */ - A_UINT8 pbits:3; - A_UINT8 reserved:4; - A_UINT8 oui[3]; - - A_UINT8 vsaData[1]; -} tNanVsaTlv, *tpNanVsaTlv; - -/*NAN 2.0 - SDEA*/ -typedef struct -{ - A_UINT32 data_path_type:1; - A_UINT32 reserved:31; -} tNanDataPathParamsTlv, *tpNanDataPathParamsTlv; - -/* NAN 2.0 - SDEA CTRL */ -typedef struct -{ - A_UINT32 fsd_required:1; - A_UINT32 fsd_with_gas:1; - A_UINT32 data_path_required:1; - A_UINT32 data_path_type:1; - A_UINT32 multicast_type:1; - A_UINT32 qos_required:1; - A_UINT32 security_required:1; - A_UINT32 ranging_required:1; - A_UINT32 range_limit_present:1; - A_UINT32 service_update_ind_present:1; - A_UINT32 reserved1:6; - // Above 16 bits are used to send Over The Air as part of SDEA control - // Below 16 bits are used for internal purposes - A_UINT32 range_report_needed:1; - A_UINT32 reserved2:15; -} tNanSdeaCtrlParamsTlv, *tpNanSdeaCtrlParamsTlv; - -typedef struct -{ - A_UINT32 data_path_enabled_in_match:1; - A_UINT32 reserved:31; -} tNanDataPathParmsEnabledMatchTlv, *tpNanDataPathParmsEnabledMatchTlv; - -/* NAN Data responder mode */ -typedef enum -{ - NAN_DATA_RSPNR_MODE_AUTO = 0, - NAN_DATA_RSPNR_MODE_ACCEPT = 1, - NAN_DATA_RSPNR_MODE_REJECT = 2, - NAN_DATA_RSPNR_MODE_COUNTER = 3, - NAN_DATA_RSPNR_MODE_COUNTER_NO_CHANNEL_CHANGE = 4, -} tNanDataRspnrMode; - -/** - * NDC respond mode - */ -typedef enum -{ - NAN_NDC_MODE_AUTO = 0, - NAN_NDC_MODE_COUNTER = 1, -} tNanNdcRspMode; - -/** - * Nan20 accept policy - */ -typedef enum { - NAN20_ACCEPT_POLICY_NONE = 0, - NAN20_ACCEPT_POLICY_ALL = 1, -} tNan20AcceptPolicy; - -/* NAN Cipher Suites Shared Key - to be deprecated */ -typedef enum { - NCS_SK_128 = 1, - NCS_SK_256 = 2, - NCS_SK_ALL = 3, -} NanCSID; - -/* New Host to use below to send CSID entries as a bitmap */ -typedef enum { - NAN_NCS_F_SK_128 = 0x00001, - NAN_NCS_F_SK_256 = 0x00002, - NAN_NCS_F_PK_2WDH_128 = 0x00004, - NAN_NCS_F_PK_2WDH_256 = 0x00008, - NAN_NCS_F_GTK_CCMP_128 = 0x00010, - NAN_NCS_F_GTK_GCMP_256 = 0x00020, - NAN_NCS_F_PK_PASN_128 = 0x00040, - NAN_NCS_F_PK_PASN_256 = 0x00080, -} NanCSIDBits; - -/** - * Security configuration rules between Upper layer and NAN target - * CSID and PMK are optional parameters - * Target usese the device capability CSID if Service layer provide. - * - * For these security parameter host will act as pass through - * Here are the rules for security parametrs between upper layer and target - * - * NDP Request - * 1. 4 byte CSID - * 2. 32 byte PMK - * 3. PASSPHRASE >=8 and <= 63 byte - * 4. Service Name (<=255) - * - * NDP Responder Request - * 1. 4 byte CSID - * 2. 32 byte PMK - * 3. PASSPHRASE >=8 and <= 63 byte - * 4. Service Name (<=255) - * - * NDP Indication - * 1. 4 byte CSID - * 2. 256 byte SCID buffer - */ - -/* NAN Cipher Version */ -typedef enum { - NAN_CIPHER_128 = 0, /* 0: 128-bit NIK, 64-bit Nonce, 64-bit Tag, HMAC-SHA-256 */ - /* 1 -7 reserved */ -} NanCipherVersion; - -/* NAN Group MFP support */ -#define NAN_GTKSA_IGTKSA_BIGTKSA_NOT_SUPPORTED 0x00 -#define NAN_GTKSA_IGTKSA_SUPPORTED_BIGTKSA_NOT_SUPPORTED 0x01 -#define NAN_GTKSA_IGTKSA_BIGTKSA_SUPPORTED 0x02 - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 inner_threshold; - A_UINT32 outer_threshold; -} t_nan_geo_fence_descriptor, *tp_nan_geo_fence_descriptor; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 range_resolution; - A_UINT32 range_interval; - A_UINT32 ranging_indication_event; - t_nan_geo_fence_descriptor geo_gence_threshold; - -} t_nan_range_config_params, *tp_nan_range_config_params; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 range_measurement; - A_UINT32 event_type; - A_UINT32 range_id; -} t_nan_range_result_params, *tp_nan_range_result_params; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* TLV Required: - MANDATORY - 1. MAC_ADDRESS - 2. t_nan_range_result_params - */ - A_UINT8 ptlv[1]; -} t_nan_range_result_ind, *tp_nan_range_result_ind; - -/* This is the TLV used to trigger ranging requests*/ -typedef PACKED_PRE struct PACKED_POST -{ - wlan_nan_mac_addr range_mac_addr; - A_UINT32 range_id; // Match handle in match_ind, publish_id in result ind - A_UINT32 ranging_accept:1; - A_UINT32 ranging_reject:1; - A_UINT32 ranging_cancel:1; - A_UINT32 reserved:29; -} t_nan_range_req_msg, *tp_nan_range_req_msg; - -typedef PACKED_PRE struct PACKED_POST -{ - wlan_nan_mac_addr range_mac_addr; - A_UINT32 range_id; // This will publish_id in case of receiving publish. -} t_nan_range_req_recvd_msg,*tp_nan_range_req_recvd_msg; - -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /*TLV Required - 1. t_nan_range_req_recvd_msg - */ - A_UINT8 ptlv[1]; -}t_nan_range_req_ind, *tp_nan_range_req_ind; - -/************************** Test Mode ***************************/ - -typedef PACKED_PRE struct PACKED_POST -{ - tNanMsgHeader nanHeader; - /* - * Excludes TLVs - * - * Optional: Nan Availability - * - */ - A_UINT8 ptlv[1]; -} tNanTestModeReqMsg, *tpNanTestModeReqMsg; - -typedef enum { - NAN_DATA_PATH_M4_RESPONSE_ACCEPT = 1, - NAN_DATA_PATH_M4_RESPONSE_REJECT = 2, - NAN_DATA_PATH_M4_RESPONSE_BAD_MIC = 3 -} tNdpM4ResponseType; - -typedef enum { - NAN_SCHED_VALID = 0, - NAN_SCHED_INVALID_BAD_FA = 1, - NAN_SCHED_INVALID_BAD_NDC = 2, - NAN_SCHED_INVALID_BAD_IMMU = 3, -} NanSchedType; - -typedef enum { - NMF_CLEAR_DISABLE = 0, - NMF_CLEAR_ENABLE = 1, -} NMFClearEnable; - -typedef enum -{ - NAN_TEST_MODE_CMD_NAN_AVAILABILITY = 1, - NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE = 2, - NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL = 3, - NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS = 4, - NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE = 5, - NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE = 6, - NAN_TEST_MODE_CMD_NAN_SCHED_TYPE =7, - NAN_TEST_MODE_CMD_NMF_CLEAR_CONFIG =8, - NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY = 9, - NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE = 10, - NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY = 11, - NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12, - NAN_TEST_MODE_CMD_NDL_QOS_TEST = 13, //CONFIG_QoS - NAN_TEST_MODE_CMD_DEVICE_TYPE = 14, - NAN_TEST_MODE_CMD_DISABLE_NDPE = 15, - NAN_TEST_MODE_CMD_ENABLE_NDP = 16, - NAN_TEST_MODE_CMD_DISABLE_IPV6_LINK_LOCAL = 17, - NAN_TEST_MODE_CMD_TRANSPORT_IP_PARAM = 18, - NAN_TEST_MODE_CMD_S3_ATTR_PARAMS = 19, - NAN_TEST_MODE_CMD_SCHED_UPDATE_S3_NOTIFY = 20, - NAN_TEST_MODE_CMD_PMK = 21, -} tNanTestModeCmd; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 cmd; - /* Followed by command data content (Aligned to A_UINT32 size) - * - * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY - * content: NAN Avaiability attribute blob - * - * command: NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE - * content: A_UINT32 value (0 - Ignore 1 - Include immuatable, 2 - Don't include immutable) - * - * command: NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL - * content: A_UINT32 channel_frequency; (0 - Ignore) - * - * command: NAN_TEST_MODE_CMD_NAN_SCHED_TYPE - * content: A_UINT32 value; (0 - valid schedule(default) 1 - Bad FA, 2 send bad NDC, 3 - Bad immuatable) - * - * command: NAN_TEST_MODE_CMD_NMF_CLEAR_CONFIG - * content: A_UINT32 value; (0 - Send NMF Encrypted(default), 1 - Send Clear NMF) - * - * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY - * content: A_UINT32 channelAvailabilityPresent; (0 - channel availability not present, 1 - channel availability present) - * content: A_UINT32 channelAvailabilityValue; (0 - channel not available, 1 - channel available) - * - * command: NAN_TEST_MODE_CMD_DEVICE_TYPE - * content: A_UINT32 deviceType; (0 - ignore, 1 - TestBed, 2 - DUT) - * - * command: NAN_TEST_MODE_CMD_DISABLE_NDPE - * content: A_UINT32 disableNDPE; (0 - Send NDPE based on NDPE parameters present, 1 - TestBed(Dont include the NDPE attribute)) - * - * command: NAN_TEST_MODE_CMD_ENABLE_NDP - * content: A_UINT32 enableNDP; (0 - Dont send the NDP attribute if we send the NDPE attribute, - * (1 - TestBed(Include the NDP attribute irrespective of the NDP attribute present or not)) - * - * command: NAN_TEST_MODE_CMD_DISABLE_IPV6_LINK_LOCAL - * content: A_UINT32 disableIPv6_linklocal; (0 - Send IPv6 link local based on IPv6 support, 1 - TestBed(Dont include the IPv6 TLV list)) - * - * command: NAN_TEST_MODE_CMD_TRANSPORT_IP_PARAM - * content: struct tNdpTransIpParams - * - * command: NAN_TEST_MODE_CMD_S3_ATTR_PARAMS - * content: struct tNanS3Params - * - * command: NAN_TEST_MODE_CMD_SCHED_UPDATE_S3_NOTIFY - * content: struct tNanS3Params - */ - A_UINT8 data[1]; -} t_nan_test_mode_cmd_params; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 dfs_master:1; - A_UINT32 ext_key_id:1; - A_UINT32 simu_ndp_data_recept:1; - A_UINT32 ndpe_attr_supp:1; - A_UINT32 reserved:28; -} tNanDevCapAttrCap, *tpNanDevCapAttrCap; - -/***************************************************************/ - -#define NAN_MSG_IPV6_INTF_ADDR_LEN 16 - -typedef struct { - /* Presence of ipv6_intf_addr */ - A_UINT32 ipv6_addr_present; - /* Presence of transport Port */ - A_UINT32 trans_port_present; - /* Presence of transport Protocol */ - A_UINT32 trans_proto_present; - /* ipv6 Interface address */ - A_UINT8 ipv6_intf_addr[NAN_MSG_IPV6_INTF_ADDR_LEN]; - /* Transport Port */ - A_UINT32 transport_port; - /* Transport Protocol */ - A_UINT32 transport_protocol; -} tNdpTransIpParams; - -typedef enum { - NAN_BOOTSTRAPPING_METHOD_PIN_CODE_DISPLAY = 1, - NAN_BOOTSTRAPPING_METHOD_PASSPHRASE_DISPLAY = 2, - NAN_BOOTSTRAPPING_METHOD_QR_CODE_DISPLAY = 3, - NAN_BOOTSTRAPPING_METHOD_NFC_TAG = 4, - NAN_BOOTSTRAPPING_METHOD_KEYPAD_PIN_CODE = 5, - NAN_BOOTSTRAPPING_METHOD_KEYPAD_PASSPHRASE = 6, - NAN_BOOTSTRAPPING_METHOD_QR_CODE_SCAN = 7, - NAN_BOOTSTRAPPING_METHOD_NFC_READER = 8, - /* Bit 9 to 13 reserved */ - NAN_BOOTSTRAPPING_METHOD_SERVICE_MANAGED_BOOTSTRAPPING = 14, - NAN_BOOTSTRAPPING_METHOD_BOOTSTRAPPING_HANDSHAKE_SKIPPED = 15, -} tNaNBootstrappingMethod; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 pairing_setup_required:1; - A_UINT32 npk_nik_caching_required:1; - A_UINT32 bootstapping_method_bitmap:16; - A_UINT32 reserved:14; -} tNanPairingConfigurationParams, *tpNanPairingConfigurationParams; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 pairing_setup_required:1; - A_UINT32 npk_nik_caching_required:1; - A_UINT32 bootstapping_method_bitmap:16; - A_UINT32 reserved:14; -} tNanPairingParamsMatchTlv, *tpNanPairingParamsMatchTlv; - -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT8 type; - A_UINT8 status; - A_UINT8 dialog_token; - A_UINT8 reason_code; - A_UINT16 bootstapping_method_bitmap; - A_UINT16 comeback_after; -} tNanBootstrappingParams, *tpNanBootstrappingParams; - -/* NAN Identity Resolution Params */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 cipher_version:8; - A_UINT32 reserved:24; -} tNanIdentityResolutionParams; - -/* NAN Identity Resolution Indication : HAL -> Target */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanIdentityResolutionParams identityresolutionParams; - /* - * Excludes TLVs - * - * Required: Nounce, Tag - */ - A_UINT8 ptlv[1]; -} tNanIdentityResolutionIndMsg, *tpNanIdentityResolutionIndMsg; - -/* NAN pairing roles */ -#define NAN_PAIRING_ROLE_INITIATOR 0 -#define NAN_PAIRING_ROLE_RESPONDER 1 - -/* NAN Pairing Request Params */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 pairing_handle; - A_UINT32 pairing_role:1; - A_UINT32 pairing_verification:1; - A_UINT32 cipher_suite:8; - A_UINT32 reserved:22; - A_UINT32 reserved2; - /* NOTE: - * This struct cannot be expanded, due to backwards-compatibility - * requirements. - */ -} tNanPairingIndParams; - -/* NAN Pairing Indication : HAL -> Target */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - tNanPairingIndParams pairingIndParams; - A_UINT32 reserved[2]; - /* TLVs Required: - * MANDATORY - * 1. MAC_ADDRESS (Peer NMI) - * 2. NM_TK (The TK derived from pairing) - */ - A_UINT8 ptlv[1]; - /* NOTE: - * This struct cannot be expanded, due to the above variable-length array. - */ -} tNanPairingIndMsg, *tpNanPairingIndMsg; - -/* NAN UnPairing Indication : HAL -> Target */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT32 pairing_handle; -} tNanUnPairingIndMsg, *tpNanUnPairingIndMsg; - -/* NAN OEM REQ */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - /* - * TLVs: - * - * Required: OEM request in the form of opaque data blob. - */ - A_UINT8 ptlv[1]; - /* NOTE: - * This struct cannot be expanded, due to the above variable-length array. - */ -} tNanOemReqMsg, *tpNanOemReqMsg; - -/* NAN OEM RSP */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; - A_UINT16 value; - /* - * TLVs: - * - * Required: OEM response in the form of opaque data blob. - */ - A_UINT8 ptlv[1]; - /* NOTE: - * This struct cannot be expanded, due to the above variable-length array. - */ -} tNanOemRspMsg, *tpNanOemRspMsg; - -/* NAN OEM IND */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 reserved[2]; - /* - * TLVs: - * - * Required: OEM indication in the form of opaque data blob. - */ - A_UINT8 ptlv[1]; - /* NOTE: - * This struct cannot be expanded, due to the above variable-length array. - */ -} tNanOemIndMsg, *tpNanOemIndMsg; - -typedef struct { - A_UINT32 entry_control:8; - A_UINT32 time_bitmap_control:16; - A_UINT32 reserved:8; - A_UINT32 time_bitmap; -} tNanS3Params, *tpNanS3Params; - -#define NAN_MAX_GROUP_KEY_LEN 32 -#define NAN_MAX_GROUP_KEY_RSC_LEN 6 - -/* NAN Group Key params */ -typedef PACKED_PRE struct PACKED_POST -{ - A_UINT32 key_cipher:16; - A_UINT32 key_idx:8; - A_UINT32 key_len:8; - A_UINT8 key_data[NAN_MAX_GROUP_KEY_LEN]; - A_UINT8 key_rsc[NAN_MAX_GROUP_KEY_RSC_LEN]; -} tNanGroupKeyParamsTlv, *tpNanGroupKeyParamsTlv; - -/* NAN Group Key Install Req Msg */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - - /* - * TLVs - * - * Required: MAC address, one or more tNanGroupKeyParamsTlv. - */ - A_UINT8 ptlv[1]; - /* NOTE: - * This struct cannot be expanded, due to the above variable-length array. - */ -} tNanGroupKeyInstallReqMsg, *tpNanGroupKeyInstallReqMsg; - -/* NAN Group Key Install Rsp Msg */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; /* tNanStatusType */ - A_UINT16 value; -} tNanGroupKeyInstallRspMsg, *tpNanGroupKeyInstallRspMsg; - -/* NAN Group Key TX PN fetch Req Msg */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT32 key_idx; -} tNanTxPnReqMsg, *tpNanTxPnReqMsg; - -/* NAN Group Key TX PN fetch Rsp Msg */ -typedef PACKED_PRE struct PACKED_POST -{ - NAN_PLATFORM_MSG_HEADER halHeader; - tNanMsgHeader nanHeader; - A_UINT16 status; /* tNanStatusType */ - A_UINT16 value; - A_UINT8 key_rsc[NAN_MAX_GROUP_KEY_RSC_LEN]; -} tNanTxPnRspMsg, *tpNanTxPnRspMsg; - - -#endif /* WLAN_NAN_MSG_H */ diff --git a/drivers/staging/fw-api/fw/wlan_nan_platform.h b/drivers/staging/fw-api/fw/wlan_nan_platform.h deleted file mode 100644 index 9a201f53aed326c2730705147402af57fa73ea49..0000000000000000000000000000000000000000 --- a/drivers/staging/fw-api/fw/wlan_nan_platform.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. - * SPDX-License-Identifier: ISC - */ - -#ifndef _WLAN_NAN_PLATFORM_H_ -#define _WLAN_NAN_PLATFORM_H_ - -typedef struct -{ -}NAN_PLATFORM_MSG_HEADER; - -#define WLAN_NAN_MSG_COMMON_HEADER_V2 - -#endif /* _WLAN_NAN_PLATFORM_H_ */ diff --git a/drivers/staging/fw-api/fw/wmi_services.h b/drivers/staging/fw-api/fw/wmi_services.h index 3ac9556d088a79788d6a25dbb11bc44312b71003..758afe77a62a856b28626a5d0c4781da785b4327 100644 --- a/drivers/staging/fw-api/fw/wmi_services.h +++ b/drivers/staging/fw-api/fw/wmi_services.h @@ -683,15 +683,6 @@ typedef enum { */ WMI_SERVICE_IS_TARGET_IPA = 425, WMI_SERVICE_THERM_THROT_TX_CHAIN_MASK = 426, /*FW supports thermal throttling dynamic Tx ChainMask update */ - WMI_SERVICE_SPLIT_PHY_PDEV_SUSPEND_RESUME_SUPPORT = 427, /* Indicates FW support pdev suspend/resume in split-phy radio */ - WMI_SERVICE_USD_SUPPORT = 428, /* Indicates FW supports Unsynchronized Service Discovery */ - WMI_SERVICE_THERM_THROT_5_LEVELS = 429, /* Indicates FW support 5 thermal throttling levels */ - WMI_SERVICE_PROTECTED_TWT = 430, /* Indicates FW supports protected TWT operation */ - WMI_SERVICE_SCAN_CACHE_REPORT_SUPPORT = 431, /* Indicates FW supports for sending scan cache report */ - WMI_SERVICE_SCC_TPC_POWER_SUPPORT = 432, /* Indicates FW supports setting TPC power for SCC vdevs */ - WMI_SERVICE_DYNAMIC_TWT_MODE_SUPPORT = 433, /* Indicates FW supports Dynamic TWT mode for vdevs */ - WMI_SERVICE_SPECTRAL_SPUR_BIN_INFO_SUPPORT = 434, /* Indicates FW supports indicating spur frequency and spectral bin that gets affected due to spur frequency */ - WMI_SERVICE_TWT_P2P_GO_CONCURRENCY_SUPPORT = 435, /* Indicates FW supports TWT in P2P GO concurrency mode */ WMI_MAX_EXT2_SERVICE diff --git a/drivers/staging/fw-api/fw/wmi_tlv_defs.h b/drivers/staging/fw-api/fw/wmi_tlv_defs.h index 13d7c3de3b1ba5f3b62c9a6f8af6e71ff26bb0ae..024814e85140db07022220e7f2b92618b0035704 100644 --- a/drivers/staging/fw-api/fw/wmi_tlv_defs.h +++ b/drivers/staging/fw-api/fw/wmi_tlv_defs.h @@ -1449,27 +1449,6 @@ typedef enum { WMITLV_TAG_STRUC_wmi_mlo_peer_tid_to_link_map_event_fixed_param, WMITLV_TAG_STRUC_wmi_usd_service_cmd_fixed_param, WMITLV_TAG_STRUC_wmi_usd_service_event_fixed_param, - WMITLV_TAG_STRUC_wmi_vdev_create_wfdr2_mode_params, - WMITLV_TAG_STRUC_wmi_pdev_power_boost_event_fixed_param, - WMITLV_TAG_STRUC_wmi_pdev_power_boost_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_pdev_power_boost_mem_addr_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_c2c_detect_event_fixed_param, - WMITLV_TAG_STRUC_wmi_get_scan_cache_result_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_scan_cache_result_event_fixed_param, - WMITLV_TAG_STRUC_wmi_scan_cache_info, - WMITLV_TAG_STRUC_wmi_POWER_BOOST_CAPABILITIES, - WMITLV_TAG_STRUC_wmi_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES, - WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_start_indication_event_fixed_param, - WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_fixed_param, - WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_complete_fixed_param, - WMITLV_TAG_STRUC_wmi_mlo_link_add_param, - WMITLV_TAG_STRUC_wmi_mlo_link_del_param, - WMITLV_TAG_STRUC_wmi_pdev_wifi_radar_cap_evt_fixed_param, - WMITLV_TAG_STRUC_wmi_wifi_radar_ltf_length_capabilities, - WMITLV_TAG_STRUC_wmi_wifi_radar_chain_capabilities, - WMITLV_TAG_STRUC_wmi_sawf_ezmesh_hop_count_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_ctrl_path_pdev_conn_stats_struct, - WMITLV_TAG_STRUC_wmi_pdev_sscan_spur_chan_impacted_bin_info, } WMITLV_TAG_ID; /* * IMPORTANT: Please add _ALL_ WMI Commands Here. @@ -2024,12 +2003,6 @@ typedef enum { OP(WMI_P2P_GO_DFS_AP_CONFIG_CMDID) \ OP(WMI_VDEV_REPORT_AP_OPER_BW_CMDID) \ OP(WMI_USD_SERVICE_CMDID) \ - OP(WMI_PDEV_POWER_BOOST_CMDID) \ - OP(WMI_PDEV_POWER_BOOST_MEM_ADDR_CMDID) \ - OP(WMI_GET_SCAN_CACHE_RESULT_CMDID) \ - OP(WMI_MLO_LINK_RECONFIG_CMDID) \ - OP(WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID) \ - OP(WMI_SAWF_EZMESH_HOP_COUNT_CMDID) \ /* add new CMD_LIST elements above this line */ @@ -2358,11 +2331,6 @@ typedef enum { OP(WMI_MLO_TLT_SELECTION_FOR_TID_SPRAY_EVENTID) \ OP(WMI_MLO_PEER_TID_TO_LINK_MAP_EVENTID) \ OP(WMI_USD_SERVICE_EVENTID) \ - OP(WMI_PDEV_POWER_BOOST_EVENTID) \ - OP(WMI_C2C_DETECT_EVENTID) \ - OP(WMI_SCAN_CACHE_RESULT_EVENTID) \ - OP(WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID) \ - OP(WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID) \ /* add new EVT_LIST elements above this line */ @@ -3589,8 +3557,7 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID); #define WMITLV_TABLE_WMI_VDEV_CREATE_CMDID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, wmi_vdev_create_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_txrx_streams, cfg_txrx_streams, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_create_mlo_params, mlo_params, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_create_wfdr2_mode_params, wfdr2_mode, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_create_mlo_params, mlo_params, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_CREATE_CMDID); @@ -5356,18 +5323,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_CMDID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mlo_peer_recommended_links, mlo_peer_recommended_links, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECOMMENDATION_CMDID); -/** WMI cmd to start STA initialized link reconfig */ -#define WMITLV_TABLE_WMI_MLO_LINK_RECONFIG_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_fixed_param, wmi_mlo_link_reconfig_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mlo_link_add_param, link_add_param, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mlo_link_del_param, link_del_param, WMITLV_SIZE_VAR) -WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECONFIG_CMDID); - -/** WMI cmd to notify fw completion of link reconfig */ -#define WMITLV_TABLE_WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_complete_fixed_param, wmi_mlo_link_reconfig_complete_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID); - /* Mcast ipv4 address filter list cmd */ #define WMITLV_TABLE_WMI_VDEV_IGMP_OFFLOAD_CMDID(id,op,buf,len) \ WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_igmp_offload_fixed_param, wmi_igmp_offload_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ @@ -5709,25 +5664,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_REPORT_AP_OPER_BW_CMDID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, service_specific_info, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_USD_SERVICE_CMDID); -/* WMI cmd used to send Power Boost status update from Host to Target */ -#define WMITLV_TABLE_WMI_PDEV_POWER_BOOST_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_power_boost_cmd_fixed_param, wmi_pdev_power_boost_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_POWER_BOOST_CMDID); - -/* WMI cmd used to exchange the DDR address to the target for Power Boost feature */ -#define WMITLV_TABLE_WMI_PDEV_POWER_BOOST_MEM_ADDR_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_power_boost_mem_addr_cmd_fixed_param, wmi_pdev_power_boost_mem_addr_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_POWER_BOOST_MEM_ADDR_CMDID); - -/* WMI command to send scan cache result */ -#define WMITLV_TABLE_WMI_GET_SCAN_CACHE_RESULT_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_get_scan_cache_result_cmd_fixed_param, wmi_get_scan_cache_result_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_GET_SCAN_CACHE_RESULT_CMDID); - -#define WMITLV_TABLE_WMI_SAWF_EZMESH_HOP_COUNT_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sawf_ezmesh_hop_count_cmd_fixed_param, wmi_sawf_ezmesh_hop_count_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_SAWF_EZMESH_HOP_COUNT_CMDID); - /************************** TLV definitions of WMI events *******************************/ @@ -5787,11 +5723,7 @@ WMITLV_CREATE_PARAM_STRUC(WMI_SERVICE_READY_EXT_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_aux_dev_capabilities, aux_dev_caps, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_enhanced_aoa_caps_param, aoa_caps_param, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_enhanced_aoa_per_band_caps_param, aoa_per_band_caps_param, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_sar_flag_tlv_param, sar_flags, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_POWER_BOOST_CAPABILITIES, power_boost_capabilities, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES, rssi_accuracy_improvement_capabilities, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wifi_radar_ltf_length_capabilities, wr_ltf_caps, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wifi_radar_chain_capabilities, wr_chain_caps, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_sar_flag_tlv_param, sar_flags, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_SERVICE_READY_EXT2_EVENTID); #define WMITLV_TABLE_WMI_SPECTRAL_CAPABILITIES_EVENTID(id,op,buf,len) \ @@ -5799,12 +5731,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_SERVICE_READY_EXT2_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_spectral_fft_size_capabilities, fft_size_caps, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_SPECTRAL_CAPABILITIES_EVENTID); -#define WMITLV_TABLE_WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_wifi_radar_cap_evt_fixed_param, wmi_pdev_wifi_radar_cap_evt_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wifi_radar_ltf_length_capabilities, wr_ltf_caps, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wifi_radar_chain_capabilities, wr_chain_caps, WMITLV_SIZE_VAR) -WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID); - #define WMITLV_TABLE_WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chan_rf_characterization_info_event_fixed_param, wmi_chan_rf_characterization_info_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_CHAN_RF_CHARACTERIZATION_INFO, wmi_chan_rf_characterization_info, WMITLV_SIZE_VAR) @@ -6945,11 +6871,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_REG_CHAN_LIST_CC_EXT_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_afc_chan_eirp_power_info, chan_eirp_power_info_array, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_AFC_EVENTID); -/* Indicate LPI AP detect or not to Host */ -#define WMITLV_TABLE_WMI_C2C_DETECT_EVENTID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_c2c_detect_event_fixed_param, wmi_c2c_detect_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_C2C_DETECT_EVENTID); - /* FIPS event */ #define WMITLV_TABLE_WMI_PDEV_FIPS_EVENTID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_fips_event_fixed_param, wmi_pdev_fips_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ @@ -7233,8 +7154,7 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PEER_STATS_INFO_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_vdev_stats_struct, ctrl_path_vdev_stats, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_sta_rrm_stats_struct, ctrl_path_sta_rrm_stats, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_vdev_bcn_tx_stats_struct, ctrl_path_vdev_bcn_tx_stats, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_bcn_tx_stats_struct, ctrl_path_pdev_bcn_tx_stats, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_conn_stats_struct, ctrl_path_pdev_conn_stats, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ctrl_path_pdev_bcn_tx_stats_struct, ctrl_path_pdev_bcn_tx_stats, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_CTRL_PATH_STATS_EVENTID); /* @@ -7497,8 +7417,7 @@ WMITLV_CREATE_PARAM_STRUC(WMI_AUDIO_AGGR_SCHED_METHOD_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_sscan_fw_cmd_fixed_param, wmi_pdev_sscan_fw_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_sscan_fft_bin_index, fft_bin_index, WMITLV_SIZE_VAR) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_sscan_chan_info, wmi_pdev_sscan_chan_info,chan_info, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_sscan_per_detector_info, det_info, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_sscan_spur_chan_impacted_bin_info, spur_chan_impacted_bin_info, WMITLV_SIZE_VAR) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_pdev_sscan_per_detector_info, det_info, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SSCAN_FW_PARAM_EVENTID); /* Send sscan related event start/stop trigger to host */ @@ -7808,29 +7727,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_MGMT_SRNG_REAP_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_peer_tid_to_link_map_event_fixed_param, wmi_mlo_peer_tid_to_link_map_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) WMITLV_CREATE_PARAM_STRUC(WMI_MLO_PEER_TID_TO_LINK_MAP_EVENTID); -/** Indicate host to start link reconfigure */ -#define WMITLV_TABLE_WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_start_indication_event_fixed_param, wmi_mlo_link_reconfig_start_indication_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mlo_link_add_param, link_add_param, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mlo_link_del_param, link_del_param, WMITLV_SIZE_VAR) -WMITLV_CREATE_PARAM_STRUC(WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID); - /* USD Service Event */ #define WMITLV_TABLE_WMI_USD_SERVICE_EVENTID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_usd_service_event_fixed_param, wmi_usd_service_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) WMITLV_CREATE_PARAM_STRUC(WMI_USD_SERVICE_EVENTID); -/* WMI Event used to send Power Boost status update */ -#define WMITLV_TABLE_WMI_PDEV_POWER_BOOST_EVENTID(id,op,buf,len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_power_boost_event_fixed_param, wmi_pdev_power_boost_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_POWER_BOOST_EVENTID); - -#define WMITLV_TABLE_WMI_SCAN_CACHE_RESULT_EVENTID(id, op , buf, len) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_scan_cache_result_event_fixed_param, wmi_scan_cache_result_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, scan_freq_list, WMITLV_SIZE_VAR) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_scan_cache_info, scan_cache_info, WMITLV_SIZE_VAR) -WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_CACHE_RESULT_EVENTID); - #ifdef __cplusplus } diff --git a/drivers/staging/fw-api/fw/wmi_unified.h b/drivers/staging/fw-api/fw/wmi_unified.h index b74ade68c3f0e72f84f584fb56a8ad0fef086395..936cb5a13bd4b92bc2f8013a196f66ffc7995fd2 100644 --- a/drivers/staging/fw-api/fw/wmi_unified.h +++ b/drivers/staging/fw-api/fw/wmi_unified.h @@ -588,13 +588,6 @@ typedef enum { * WMI cmd to set custom TX power backoff value per band/chain/MCS to PHY. */ WMI_PDEV_SET_CUSTOM_TX_POWER_PER_MCS_CMDID, - /* WMI cmd to send Power Boost status update from Host */ - WMI_PDEV_POWER_BOOST_CMDID, - /** - * WMI cmd to exchange the address of the DDR buffer allocated by the Host - * for Power Boost feature - */ - WMI_PDEV_POWER_BOOST_MEM_ADDR_CMDID, /* VDEV (virtual device) specific commands */ @@ -1350,9 +1343,6 @@ typedef enum { /** Unsynchronized Service Discovery */ WMI_USD_SERVICE_CMDID, - /** WMI command to get scan cached result */ - WMI_GET_SCAN_CACHE_RESULT_CMDID, - /* Offload 11k related requests */ WMI_11K_OFFLOAD_REPORT_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_11K_OFFLOAD), @@ -1696,18 +1686,12 @@ typedef enum { WMI_MLO_PRIMARY_LINK_PEER_MIGRATION_CMDID, /** WMI cmd to recommand preferred link */ WMI_MLO_LINK_RECOMMENDATION_CMDID, - /** WMI cmd to start STA initialized link reconfig */ - WMI_MLO_LINK_RECONFIG_CMDID, - /** WMI cmd to notify fw completion of link reconfig */ - WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID, /** WMI commands specific to Service Aware WiFi (SAWF) */ /** configure or reconfigure the parameters for a service class */ WMI_SAWF_SVC_CLASS_CFG_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_SAWF), /** disable a service class */ WMI_SAWF_SVC_CLASS_DISABLE_CMDID, - /** update hop count value for SDWF-Ezmesh scenario */ - WMI_SAWF_EZMESH_HOP_COUNT_CMDID, /* WMI commands specific to ODD */ WMI_ODD_LIVEDUMP_REQUEST_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_ODD), @@ -1894,16 +1878,6 @@ typedef enum { /* Event to indicate xLNA is enabled */ WMI_PDEV_ENABLE_XLNA_EVENTID, - /* Event to indicate ANN Power Boost update status from Target */ - WMI_PDEV_POWER_BOOST_EVENTID, - - /* - * WMI event to share Wi-Fi Radar - - * monostatic Wi-Fi sensing technique capabalites - */ - WMI_PDEV_WIFI_RADAR_CAPABILITIES_EVENTID, - - /* VDEV specific events */ /** VDEV started event in response to VDEV_START request */ WMI_VDEV_START_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_VDEV), @@ -2401,9 +2375,6 @@ typedef enum { */ WMI_USD_SERVICE_EVENTID, - /* WMI event to send scan cached results */ - WMI_SCAN_CACHE_RESULT_EVENTID, - /* GPIO Event */ WMI_GPIO_INPUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GPIO), @@ -2522,7 +2493,6 @@ typedef enum { WMI_REG_CHAN_LIST_CC_EXT_EVENTID, WMI_AFC_EVENTID, WMI_REG_CHAN_LIST_CC_EXT2_EVENTID, /* DEPRECATED */ - WMI_C2C_DETECT_EVENTID, /** Events for TWT(Target Wake Time) of STA and AP */ WMI_TWT_ENABLE_COMPLETE_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_TWT), @@ -2594,8 +2564,6 @@ typedef enum { WMI_MLO_TLT_SELECTION_FOR_TID_SPRAY_EVENTID, /** WMI Event to send the status of T2LM configured */ WMI_MLO_PEER_TID_TO_LINK_MAP_EVENTID, - /** Indicate host to start link reconfigure */ - WMI_MLO_LINK_RECONFIG_START_INDICATION_EVENTID, /* WMI event specific to Quiet handling */ WMI_QUIET_HANDLING_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_QUIET_OFL), @@ -3552,11 +3520,6 @@ typedef struct { #define WMI_TARGET_CAP_QDATA_TX_LCE_FILTER_SUPPORT_SET(target_cap_flags, value)\ WMI_SET_BITS(target_cap_flags, 15, 1, value) -#define WMI_TARGET_CAP_MPDU_STATS_PER_TX_NSS_SUPPORT_GET(target_cap_flags) \ - WMI_GET_BITS(target_cap_flags, 16, 1) -#define WMI_TARGET_CAP_MPDU_STATS_PER_TX_NSS_SUPPORT_SET(target_cap_flags, value)\ - WMI_SET_BITS(target_cap_flags, 16, 1, value) - /* * wmi_htt_msdu_idx_to_htt_msdu_qtype GET/SET APIs @@ -3618,58 +3581,6 @@ typedef enum { WMI_BDF_VERSION_FW_TOO_NEW = 5, } wmi_bdf_version_status_type; - -/* - * supported_wifi_generations GET/SET APIs - */ -#define WMI_SUPPORTED_WIFI_4_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 0, 1) -#define WMI_SUPPORTED_WIFI_5_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 1, 1) -#define WMI_SUPPORTED_WIFI_6_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 2, 1) -#define WMI_SUPPORTED_WIFI_7_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 3, 1) -#define WMI_SUPPORTED_WIFI_8_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 4, 1) - -#define WMI_SUPPORTED_WIFI_4_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 0, 1, value) -#define WMI_SUPPORTED_WIFI_5_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 1, 1, value) -#define WMI_SUPPORTED_WIFI_6_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 2, 1, value) -#define WMI_SUPPORTED_WIFI_7_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 3, 1, value) -#define WMI_SUPPORTED_WIFI_8_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 4, 1, value) - -/* - * supported_wifi_certified_generations GET/SET APIs - */ -#define WMI_SUPPORTED_WIFI_4_CERTIFIED_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 0, 1) -#define WMI_SUPPORTED_WIFI_5_CERTIFIED_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 1, 1) -#define WMI_SUPPORTED_WIFI_6_CERTIFIED_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 2, 1) -#define WMI_SUPPORTED_WIFI_7_CERTIFIED_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 3, 1) -#define WMI_SUPPORTED_WIFI_8_CERTIFIED_GENERATION_GET(wifi_generations) \ - WMI_GET_BITS(wifi_generations, 4, 1) - -#define WMI_SUPPORTED_WIFI_4_CERTIFIED_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 0, 1, value) -#define WMI_SUPPORTED_WIFI_5_CERTIFIED_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 1, 1, value) -#define WMI_SUPPORTED_WIFI_6_CERTIFIED_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 2, 1, value) -#define WMI_SUPPORTED_WIFI_7_CERTIFIED_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 3, 1, value) -#define WMI_SUPPORTED_WIFI_8_CERTIFIED_GENERATION_SET(wifi_generations, value) \ - WMI_SET_BITS(wifi_generations, 4, 1, value) - - typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_service_ready_ext2_event_fixed_param.*/ @@ -3755,8 +3666,7 @@ typedef struct { * Bit 13 - Support for multipass SAP * Bit 14 - Support for ML monitor mode * Bit 15 - Support for Qdata Tx LCE filter installation - * Bit 16 - Support for MPDU stats per tx Nss capability - * Bits 31:17 - Reserved + * Bits 31:16 - Reserved */ A_UINT32 target_cap_flags; @@ -3822,31 +3732,6 @@ typedef struct { */ A_UINT32 num_max_mlo_link_per_ml_sap_supp; - /* supported_wifi_generations: - * Indicate the transmitting STA's MAC/PHY feature support includes all the - * mandatory features of the particular Wi-Fi generation. - * Refer to the WMI_SUPPORTED_WIFI_x_GENERATION_GET/SET macros - * for interpreting which bit within this bitmap corresponds to which - * WiFi generation. - * The individual bits should only be checked if - * supported_wifi_generations != 0x0. - * This field is invalid and should be ignored unless it contains - * at least 1 set bit. - */ - A_UINT32 supported_wifi_generations; - - /* supported_wifi_certified_generations: - * Indicate the transmitting STA's Wi-Fi Alliance certifications. - * Refer to the WMI_SUPPORTED_WIFI_x_CERTIFIED_GENERATION_GET/SET macros - * for interpreting which bit within this bitmap corresponds to which - * WiFi generation. - * The individual bits should only be checked if - * supported_wifi_certified_generations != 0x0. - * This field is invalid and should be ignored unless it contains - * at least 1 set bit. - */ - A_UINT32 supported_wifi_certified_generations; - /* Followed by next TLVs: * WMI_DMA_RING_CAPABILITIES dma_ring_caps[]; * wmi_spectral_bin_scaling_params wmi_bin_scaling_params[]; @@ -3858,13 +3743,6 @@ typedef struct { * wmi_dbs_or_sbs_cap_ext dbs_or_sbs_cap_ext; * A_INT32 hw_tx_power_signed[WMI_HW_TX_POWER_CAPS_MAX]; * wmi_aux_dev_capabilities aux_dev_caps[]; - * WMI_POWER_BOOST_CAPABILITIES power_boost_capabilities[]; - * WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES - * rssi_accuracy_improvement_capabilities[]; - * wmi_wifi_radar_ltf_length_capabilities - * wifi_radar_ltf_length_capabilities[]; - * wmi_wifi_radar_chain_capabilities - * wifi_radar_chain_capabilities[]; */ } wmi_service_ready_ext2_event_fixed_param; @@ -4046,27 +3924,12 @@ typedef struct { /* Total number of "real" max_active_vdevs that FW supports. */ A_UINT32 num_max_active_vdevs; - /** max_num_ml_peers: - * Number of ml_peers for a SOC; used by Host to derive - * max number of peers in the system - */ - A_UINT32 max_num_ml_peers; - /* * This fixed_param TLV is followed by these additional TLVs: * mac_addr_list[num_extra_mac_addr]; */ } wmi_ready_event_fixed_param; -typedef enum { - WMI_C2C_INT_TYPE_STA = 0, - WMI_C2C_INT_TYPE_SAP = 1, - WMI_C2C_INT_TYPE_P2P = 2, - WMI_C2C_INT_TYPE_NAN = 3, - WMI_C2C_INT_TYPE_TDLS = 4, - WMI_C2C_INT_TYPE_XPAN_SAP = 5, -} WMI_C2C_INT_TYPE; - typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resource_config */ /** @@ -4819,16 +4682,8 @@ typedef struct { * 0 -> disable the feature * 1 -> enable the feature * Refer to below WMI_RSRC_CFG_FLAGS2_ENABLE_WDS_NULL_FRAME_SUPPORT - * Bits 24:23 - enable feature optimize power - * 00 -> default value - * (target will auto-select whether to enable the feature) - * 01 -> disable the feature - * 10 -> enable the feature - * 11 -> reserved - * Refer to the below WMI_RSRC_CFG_FLAGS2_OPTIMIZE_POWER_GET/SET - * macros. * - * Bits 31:25 - Reserved + * Bits 31:23 - Reserved */ A_UINT32 flags2; /** @brief host_service_flags - can be used by Host to indicate @@ -5055,20 +4910,6 @@ typedef struct { * number of max active partner links of a ML BSS */ A_UINT32 num_max_active_mlo_link_per_ml_bss; - - /** - * @brief c2c_int_type_config - * C2C interface type configuration, - * interface type defined in enum WMI_C2C_INT_TYPE: - * BIT 0 set -> Interface type STA enable C2C - * BIT 1 set -> Interface type SAP enable C2C - * BIT 2 set -> Interface type P2P enable C2C - * BIT 3 set -> Interface type NAN enable C2C - * BIT 4 set -> Interface type TDLS enable C2C - * BIT 5 set -> Interface type XPAN_SAP enable C2C - * BIT 6 : 31 Reserved - */ - A_UINT32 c2c_int_type_config; } wmi_resource_config; #define WMI_MSDU_FLOW_AST_ENABLE_GET(msdu_flow_config0, ast_x) \ @@ -5358,11 +5199,6 @@ typedef struct { #define WMI_RSRC_CFG_FLAGS2_ENABLE_WDS_NULL_FRAME_SUPPORT_SET(flags2, value) \ WMI_SET_BITS(flags2, 22, 1, value) -#define WMI_RSRC_CFG_FLAGS2_OPTIMIZE_POWER_GET(flags2) \ - WMI_GET_BITS(flags2, 23, 2) -#define WMI_RSRC_CFG_FLAGS2_OPTIMIZE_POWER_SET(flags2, value) \ - WMI_SET_BITS(flags2, 23, 2, value) - #define WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT_GET(host_service_flags) \ WMI_GET_BITS(host_service_flags, 0, 1) @@ -5535,7 +5371,6 @@ typedef enum { WMI_VENDOR1_REQ1_VERSION_3_40 = 4, WMI_VENDOR1_REQ1_VERSION_4_00 = 5, WMI_VENDOR1_REQ1_VERSION_4_10 = 6, - WMI_VENDOR1_REQ1_VERSION_4_20 = 7, } WMI_VENDOR1_REQ1_VERSION; typedef enum { @@ -5551,12 +5386,6 @@ typedef enum { WMI_HOST_BAND_CAP_6GHZ = 0x04, } WMI_HOST_BAND_CAP; -typedef enum { - WLAN_CONNECT_EXT_FEATURE_RSNO = 0, - - NUM_WLAN_CONNECT_EXT_FEATURES /* keep last */ -} wlan_connect_ext_features; - /* HW features supported info */ /* enum WMI_WIFI_STANDARD are possible values for WiFi standard bitfield */ #define WMI_GET_WIFI_STANDARD(var, feature_bitmap) \ @@ -6386,13 +6215,12 @@ typedef enum { /* Include MLO IE in Probe req */ #define WMI_SCAN_FLAG_EXT_INCL_MLIE_PRB_REQ 0x00004000 -#define WMI_SCAN_FLAG_EXT_LOW_LATENCY_SCAN 0x00008000 -#define WMI_SCAN_FLAG_EXT_RELIABLE_SCAN 0x00010000 -#define WMI_SCAN_FLAG_EXT_FAST_SCAN 0x00020000 -#define WMI_SCAN_FLAG_EXT_LOW_POWER_SCAN 0x00040000 -#define WMI_SCAN_FLAG_EXT_STOP_IF_BSSID_FOUND 0x00080000 -#define WMI_SCAN_FLAG_EXT_P2P_SCAN 0x00100000 -#define WMI_SCAN_FLAG_EXT_DISABLE_SINGLE_MAC_AUX 0x00200000 +#define WMI_SCAN_FLAG_EXT_LOW_LATENCY_SCAN 0x00008000 +#define WMI_SCAN_FLAG_EXT_RELIABLE_SCAN 0x00010000 +#define WMI_SCAN_FLAG_EXT_FAST_SCAN 0x00020000 +#define WMI_SCAN_FLAG_EXT_LOW_POWER_SCAN 0x00040000 +#define WMI_SCAN_FLAG_EXT_STOP_IF_BSSID_FOUND 0x00080000 +#define WMI_SCAN_FLAG_EXT_P2P_SCAN 0x00100000 /** @@ -6457,8 +6285,6 @@ typedef struct { #define WMI_APPEND_TO_EXISTING_CHAN_LIST 0x1 #define WMI_CHANNEL_MAX_BANDWIDTH_VALID 0x2 #define WMI_HONOR_HOST_6GHZ_CHANNEL_PASSIVE 0x4 -#define WMI_SCAN_TO_DETECT_6GHZ_C2C_AP 0x8 - /* * To preserve backwards compatibility, retain old names (without WMI_ prefix) * as aliases for the corrected names (with WMI_ prefix). @@ -8491,28 +8317,6 @@ typedef struct A_UINT32 end_freq; /* in MHz */ } wmi_pdev_sscan_per_detector_info; -typedef struct -{ - A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_sscan_spur_chan_info */ - /* spur_freqx10: - * Spur frequency in MHz multiplied by 10 to align with hardware spur - * characterized value. - * For example, a value of 24224 indicates spur frequency as 2422.4 MHz - */ - A_UINT32 spur_freqx10; - /* spur_start_bin_idx: - * Indicates the start spur bin index at which spur frequency impacts - * the spectral capture. Impact is from start to end indices, - * including both. - */ - A_UINT32 spur_start_bin_idx; - /* spur_end_bin_idx: - * Indicates the end spur bin index in which spur frequency impacts - * the spectral capture. - */ - A_UINT32 spur_end_bin_idx; -} wmi_pdev_sscan_spur_chan_impacted_bin_info; - typedef enum { /** Enum to indicate bmsk of spectral scan stop evt on scan count max out */ WMI_SSCAN_EVT_BMSK_SCAN_STOP_SCOUNT = 0X00000001, @@ -9927,9 +9731,6 @@ typedef enum { WMI_PDEV_PARAM_DSTALL_CONSECUTIVE_TX_NO_ACK_THRESHOLD, WMI_PDEV_PARAM_MGMT_SRNG_REAP_EVENT_THRESHOLD, - - /* To enable/disable DFS radar detection for scan radio */ - WMI_PDEV_PARAM_ENABLE_SCAN_RADIO_DFS, } WMI_PDEV_PARAM; #define WMI_PDEV_ONLY_BSR_TRIG_IS_ENABLED(trig_type) WMI_GET_BITS(trig_type, 0, 1) @@ -16627,55 +16428,8 @@ typedef struct { A_UINT32 beacon_stuck_cnt; A_UINT32 beacon_swba_cnt; A_UINT32 beacon_enque_fail; - A_UINT32 beacon_do_not_send_bcast_t2lm_exp; - A_UINT32 beacon_do_not_send_bcast_t2lm_proc_mst; - A_UINT32 beacon_do_not_send_off_chan; - A_UINT32 beacon_do_not_send_tx_paused; - A_UINT32 beacon_do_not_send_swba_delay; - A_UINT32 beacon_do_not_send_csa; - A_UINT32 beacon_wait_prev_txdone; } wmi_ctrl_path_pdev_bcn_tx_stats_struct; -typedef enum wmi_peer_sta_kickout_reason { - WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED = 0, /* default value to preserve legacy behavior */ - WMI_PEER_STA_KICKOUT_REASON_XRETRY = 1, - WMI_PEER_STA_KICKOUT_REASON_INACTIVITY = 2, - WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT = 3, - WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT = 4, /* TDLS peer has disappeared. All tx is failing */ - WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT = 5, - WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT = 6, /* Directly connected peer has roamed to a repeater */ - WMI_PEER_STA_KICKOUT_REASON_PMF_ERROR = 7, /* PMF error threshold is hit */ - - WMI_PEER_STA_KICKOUT_REASON_RESERVED1 = 8, /* available for future use */ - WMI_PEER_STA_KICKOUT_REASON_RESERVED2 = 9, /* available for future use */ - WMI_PEER_STA_KICKOUT_REASON_RESERVED3 = 10, /* available for future use */ - WMI_PEER_STA_KICKOUT_REASON_RESERVED4 = 11, /* available for future use */ - - /* WMI_MAX_PEER_STA_KICKOUT_REASON: - * For the sake of backwards compatibility, the below value - * cannot be changed. - */ - WMI_MAX_PEER_STA_KICKOUT_REASON = 12 -} PEER_KICKOUT_REASON; - -typedef struct { - A_UINT32 tlv_header; - A_UINT32 pdev_id; - A_UINT32 tx_mgmt_subtype_enq_ok[WMI_MGMT_FRAME_SUBTYPE_MAX]; - A_UINT32 tx_mgmt_subtype_tx_comp_ok[WMI_MGMT_FRAME_SUBTYPE_MAX]; - A_UINT32 tx_mgmt_subtype_tx_comp_fail[WMI_MGMT_FRAME_SUBTYPE_MAX]; - A_UINT32 tx_mgmt_subtype_enq_fail[WMI_MGMT_FRAME_SUBTYPE_MAX]; - A_UINT32 rx_mgmt_subtype[WMI_MGMT_FRAME_SUBTYPE_MAX]; - /* peer_sta_kickout_reason_cnt: - * Refer to wmi_peer_sta_kickout_reason for which array element - * corresponds to which STA kickout reason. - */ - A_UINT32 peer_sta_kickout_reason_cnt[WMI_MAX_PEER_STA_KICKOUT_REASON]; - A_UINT32 wmi_scan_start_cnt; - A_UINT32 wmi_scan_start_fail_cnt; - A_UINT32 foreign_chan_entry_cnt; -} wmi_ctrl_path_pdev_conn_stats_struct; - /** * peer statistics. */ @@ -16921,9 +16675,6 @@ typedef struct { * wmi_vdev_create_mlo_params mlo_params[0,1]; * optional TLV, only present for MLO vdev; * if the vdev is not MLO the array length should be 0. - * wmi_vdev_create_wfdr2_mode_params wfdr2_mode[0,1]; - * picked as per WMI_VDEV_CREATE_WFDR2_MODES - * to enable/disable NOA */ } wmi_vdev_create_cmd_fixed_param; @@ -16984,14 +16735,8 @@ typedef struct { #define WMI_MLO_FLAGS_SET_MLO_LINK_SWITCH(mlo_flags, value) WMI_SET_BITS(mlo_flags, 13, 1, value) #define WMI_MLO_FLAGS_GET_MLO_BRIDGE_LINK(mlo_flags) WMI_GET_BITS(mlo_flags, 14, 1) #define WMI_MLO_FLAGS_SET_MLO_BRIDGE_LINK(mlo_flags, value) WMI_SET_BITS(mlo_flags, 14, 1, value) -#define WMI_MLO_FLAGS_GET_LINK_ADD_CANCEL(mlo_flags) WMI_GET_BITS(mlo_flags, 15, 1) -#define WMI_MLO_FLAGS_SET_LINK_ADD_CANCEL(mlo_flags, value) WMI_SET_BITS(mlo_flags, 15, 1, value) -#define WMI_MLO_FLAGS_GET_LINK_DEL_CANCEL(mlo_flags) WMI_GET_BITS(mlo_flags, 16, 1) -#define WMI_MLO_FLAGS_SET_LINK_DEL_CANCEL(mlo_flags, value) WMI_SET_BITS(mlo_flags, 16, 1, value) -#define WMI_MLO_FLAGS_GET_START_AS_ACTIVE(mlo_flags) WMI_GET_BITS(mlo_flags, 17, 1) -#define WMI_MLO_FLAGS_SET_START_AS_ACTIVE(mlo_flags, value) WMI_SET_BITS(mlo_flags, 17, 1, value) -/* this structure used for passing MLO flags */ +/* this structure used for pass mlo flags*/ typedef struct { union { struct { @@ -17003,8 +16748,8 @@ typedef struct { mlo_mcast_vdev:1, /* indicate this is the MLO mcast primary vdev */ emlsr_support:1, /* indicate that eMLSR is supported */ mlo_force_link_inactive:1, /* indicate this link is forced inactive */ - mlo_link_add:1, /* Indicate dynamic link addition in an MLD VAP / ML peer */ - mlo_link_del:1, /* Indicate dynamic link deletion in an MLD VAP / ML peer */ + mlo_link_add:1, /* Indicate dynamic link addition in an MLD VAP */ + mlo_link_del:1, /* Indicate dynamic link deletion in an MLD VAP */ mlo_bridge_peer:1, /* Indicate if this link has bridge_peer */ nstr_bitmap_present:1, /* Indicate if at least one NSTR link pair is present in the MLD */ /* nstr_bitmap_size: @@ -17016,10 +16761,7 @@ typedef struct { nstr_bitmap_size:1, mlo_link_switch: 1, /* indicate the command is a part of link switch procedure */ mlo_bridge_link:1, /* indicate link is bridge link */ - mlo_link_add_cancel:1, /* rollback of previous dynamic link addition */ - mlo_link_del_cancel:1, /* rollback of previous dynamic link deletion */ - start_as_active:1, /* indicate link should be started in active status */ - unused: 14; + unused: 17; }; A_UINT32 mlo_flags; }; @@ -17046,22 +16788,6 @@ typedef struct { wmi_mac_addr mld_macaddr; } wmi_vdev_create_mlo_params; -/* - * this TLV structure is used to pass WFD R2 parameters on vdev create - * to enable/disable NOA - */ -typedef struct { - A_UINT32 tlv_header; /** TLV tag and len; */ - A_UINT32 wfdr2_mode; /** WFD R2 modes as per WMI_VDEV_CREATE_WFDR2_MODES */ -} wmi_vdev_create_wfdr2_mode_params; - -/** VDEV create WFD R2 modes */ -typedef enum { - WMI_VDEV_CREATE_WFDR2_MODE = 0, - WMI_VDEV_CREATE_WFDR2_PCC_MODE = 1, -} WMI_VDEV_CREATE_WFDR2_MODES; - - /* this TLV structure used for pass mlo parameters on vdev start*/ typedef struct { A_UINT32 tlv_header; /** TLV tag and len; */ @@ -18132,10 +17858,6 @@ typedef enum { * Disassoc Imminent bit set to 1. */ #define WMI_VDEV_ROAM_11KV_CTRL_DONOT_SEND_DISASSOC_ON_BTM_DI_SET 0x4 -/* WMI_VDEV_PARAM_ROAM_11KV_BTM_REJECT: - * DUT send BTM response with reject status code if the bit set to 1. - */ -#define WMI_VDEV_PARAM_ROAM_11KV_BTM_REJECT 0x8 /** NAN vdev config Feature flags */ @@ -19208,12 +18930,6 @@ typedef enum { /* Update TWT_UNAVAIL_MODE */ WMI_VDEV_PARAM_TWT_UNAVAIL_MODE, /* 0xC6 */ - /* - * Additional features supported for connection. - * Value is from enum wlan_connect_ext_features - */ - WMI_VDEV_PARAM_CONNECT_EXT_FEATURES, /* 0xC7 */ - /*=== ADD NEW VDEV PARAM TYPES ABOVE THIS LINE === * The below vdev param types are used for prototyping, and are @@ -19739,17 +19455,14 @@ typedef struct { } wmi_vdev_bss_max_idle_time_cmd_fixed_param; /** VDEV start response status codes */ -#define WMI_VDEV_START_RESPONSE_STATUS_SUCCESS 0x0 /** VDEV successfully started */ -#define WMI_VDEV_START_RESPONSE_INVALID_VDEVID 0x1 /** requested VDEV not found */ -#define WMI_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 /** unsupported VDEV combination */ -#define WMI_VDEV_START_RESPONSE_DFS_VIOLATION 0x3 /** DFS_VIOLATION since channel in the NOL is selected */ -#define WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN 0x4 /** Invalid regulatory domain in VDEV start */ -#define WMI_VDEV_START_RESPONSE_INVALID_BAND 0x5 /** Band unsupported by current hw mode in VDEV start */ +#define WMI_VDEV_START_RESPONSE_STATUS_SUCCESS 0x0 /** VDEV successfully started */ +#define WMI_VDEV_START_RESPONSE_INVALID_VDEVID 0x1 /** requested VDEV not found */ +#define WMI_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 /** unsupported VDEV combination */ +#define WMI_VDEV_START_RESPONSE_DFS_VIOLATION 0x3 /** DFS_VIOLATION since channel in the NOL is selected */ +#define WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN 0x4 /** Invalid regulatory domain in VDEV start */ +#define WMI_VDEV_START_RESPONSE_INVALID_BAND 0x5 /** Band unsupported by current hw mode in VDEV start */ #define WMI_VDEV_START_RESPONSE_INVALID_PREFERRED_TX_RX_STREAMS 0x6 /** Invalid preferred tx/rx streams */ -#define WMI_VDEV_START_RESPONSE_INVALID_TX_VAP_CONFIG 0x7 /** Invalid tx_vap config in VDEV start */ -#define WMI_VDEV_START_RESPONSE_BSS_PEER_NOT_FOUND 0x8 /** bss_peer is null/not found */ -#define WMI_VDEV_START_RESPONSE_INCORRECT_CHANNEL_PARAMS 0x9 /** home channel params are incorrect */ -#define WMI_VDEV_START_RESPONSE_GENERIC_VDEV_START_FAILURE 0xa /** generic reason code for vdev start request reject */ +#define WMI_VDEV_START_RESPONSE_INVALID_TX_VAP_CONFIG 0x7 /** Invalid tx_vap config in VDEV start */ /** Beacon processing related command and event structures */ typedef struct { @@ -21524,7 +21237,6 @@ typedef struct { #define WMI_PEER_EXT_HE_CAPS_6GHZ_VALID 0x00000008 /* param he_caps_6ghz is valid or not */ #define WMI_PEER_EXT_IS_QUALCOMM_NODE 0x00000010 /* Indicates if the peer connecting is a qualcomm node */ #define WMI_PEER_EXT_IS_MESH_NODE 0x00000020 /* Indicates if the peer connecting is a mesh node */ -#define WMI_PEER_EXT_PROTECTED_TWT 0x00000040 /* Protected TWT operation Support field in Extended RSN Capabilities element */ #define WMI_PEER_EXT_F_CRIT_PROTO_HINT_ENABLED 0x40000000 /** @@ -21593,14 +21305,6 @@ typedef struct { wmi_mac_addr self_mac; } wmi_peer_assoc_mlo_partner_link_params; -/* - * ml_reconfig for assoc mlo params: - * Bit 0: Indicate dynamic ML reconfig - */ -#define WMI_ASSOC_MLO_PEER_ML_RECONFIG 0x00000001 -#define WMI_ASSOC_MLO_PEER_ML_RECONFIG_GET(ml_reconfig_word) WMI_GET_BITS(ml_reconfig_word, 0, 1) -#define WMI_ASSOC_MLO_PEER_ML_RECONFIG_SET(ml_reconfig_word, value) WMI_SET_BITS(ml_reconfig_word, 0, 1, value) - /* This TLV structure used to pass mlo Parameters on peer assoc, only apply for mlo-peers */ typedef struct { A_UINT32 tlv_header; /** TLV tag and len; */ @@ -21644,14 +21348,6 @@ typedef struct { /** max num of active links recommended by AP or applications */ A_UINT32 recommended_max_num_simultaneous_links; - - union { - A_UINT32 ml_reconfig__word; - struct { - A_UINT32 ml_reconfig: 1, - unused: 31; - }; - }; } wmi_peer_assoc_mlo_params; typedef struct { @@ -22979,13 +22675,6 @@ typedef struct { * as mlo_etp_weightage_pcnt. */ A_UINT32 mlo_etp_weightage_pcnt; - /* mcc_score_factor_pcnt: - * This score factor will be applied to roam candidate score if the - * roaming to that candidate can form MCC with any other interface. - * Example: if value is 20, then only 20% of the score will be - * considered for the candidates for which MCC will be formed. - */ - A_UINT32 mcc_score_factor_pcnt; } wmi_roam_cnd_scoring_param; typedef struct { @@ -24221,6 +23910,17 @@ typedef struct { A_UINT32 time0; /* lower 32 bits of time stamp */ } A_TIME64; +typedef enum wmi_peer_sta_kickout_reason { + WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED = 0, /* default value to preserve legacy behavior */ + WMI_PEER_STA_KICKOUT_REASON_XRETRY = 1, + WMI_PEER_STA_KICKOUT_REASON_INACTIVITY = 2, + WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT = 3, + WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT = 4, /* TDLS peer has disappeared. All tx is failing */ + WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT = 5, + WMI_PEER_STA_KICKOUT_REASON_ROAMING_EVENT = 6, /* Directly connected peer has roamed to a repeater */ + WMI_PEER_STA_KICKOUT_REASON_PMF_ERROR = 7, /* PMF error threshold is hit */ +} PEER_KICKOUT_REASON; + typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_sta_kickout_event_fixed_param */ /** peer mac address */ @@ -24371,7 +24071,6 @@ typedef enum event_type_e { WOW_RTT_11AZ_EVENT, /* 32 + 13 */ WOW_P2P_NOA_EVENT, /* 32 + 14 */ WOW_XGAP_EVENT, /* 32 + 15 */ - WOW_PAGE_FAULT_EVENT, /* 32 + 16 */ } WOW_WAKE_EVENT_TYPE; typedef enum wake_reason_e { @@ -24467,13 +24166,6 @@ typedef enum wake_reason_e { WOW_REASON_STX_WOW_HIGH_DUTY_CYCLE, /* WoW exit reason MCC lite */ WOW_REASON_MCC_LITE, - /* P2P CLI detected BMISS from DFS master AP */ - WOW_REASON_P2P_CLI_DFS_AP_BMISS_DETECTED, - /* if Page Fault blocking feature enabled and PF observed under WoW */ - WOW_REASON_PF_BLOCKING_LAST_TIME, - /* C2C scan report LPI AP detect or not event */ - WOW_REASON_C2C_DETECT_EVENT, - /* add new WOW_REASON_ defs before this line */ WOW_REASON_MAX, @@ -26157,27 +25849,6 @@ typedef enum */ WMI_VENDOR_OUI_ACTION_FORCE_MLSR = 14, - /* - * Disable AUX learning and AUX listen if OUI matches - */ - WMI_VENDOR_OUI_ACTION_DISABLE_AUXL = 15, - - /* - * Used to downgrade to 2 link ML connection for specific AP matchs OUI. - * This is the preferred name, since it specifies that the downgraded - * number of links is 2. - */ - WMI_VENDOR_OUI_ACTION_RESTRICT_MAX_2_MLO_LINKS = 16, - /* alias for the above (less suitable, since it is less precise) */ - WMI_VENDOR_OUI_ACTION_RESTRICT_MAX_MLO_LINKS = - WMI_VENDOR_OUI_ACTION_RESTRICT_MAX_2_MLO_LINKS, - - /* - * Send Auth, Assoc request, Reassoc request frame with 6Mbps rate - * if specific vendor OUI recevied in beacon on 2GHz. - */ - WMI_VENDOR_OUI_ACTION_AUTH_ASSOC_6MBPS_2GHZ = 17, - /* Add any action before this line */ WMI_VENDOR_OUI_ACTION_MAX_ACTION_ID @@ -27820,19 +27491,16 @@ typedef struct A_UINT32 isLastResult; /*is this event a last event of the whole batch scan*/ } wmi_batch_scan_result_event_fixed_param; -typedef enum { /* DEPRECATED - DO NOT USE */ +typedef enum { /** beacons not received from P2P GO */ WMI_P2P_GO_BMISS = 0, /** beacons not received from P2 GO's STA's connected AP */ WMI_DFS_AP_BMISS = 1, -} wmi_dfs_ap_bmiss_reason; /* DEPRECATED - DO NOT USE */ +} wmi_dfs_ap_bmiss_reason; typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_cli_dfs_ap_bmiss_fixed_param*/ A_UINT32 vdev_id; - /* NOTE: - * The reason_code field is deprecated, and should be ignored. - */ A_UINT32 reason_code; /* contains a wmi_dfs_ap_bmiss_reason value */ } wmi_p2p_cli_dfs_ap_bmiss_fixed_param; @@ -30143,36 +29811,14 @@ typedef struct { A_UINT32 offset; /* offset of the stats from partner_link_data for this vdev */ } wmi_partner_link_stats; -typedef enum WMI_STATS_EXT_EVENT_DATA_TYPE { - /* OPAQUE: - * The data[] bytestream in the WMI_STATS_EXT_EVENT message contains - * opaque contents that the host driver cannot interpret. - */ - WMI_STATS_EXT_EVENT_DATA_TYPE_OPAQUE, - /* VDEV_STATS_EXT: - * The data[] bytestream in the WMI_STATS_EXT_EVENT message contains - * wmi_stats_ext_event_vdev_ext struct(s). - */ - WMI_STATS_EXT_EVENT_DATA_TYPE_VDEV_EXT, -} WMI_STATS_EXT_EVENT_DATA_TYPE_E; - typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stats1_event_fix_param */ A_UINT32 vdev_id; /** vdev ID */ A_UINT32 data_len; /** length in byte of data[]. */ - /** data_type: - * Contains a WMI_STATS_EXT_EVENT_DATA_TYPE_E value to show whether - * the host can interpret the data[] contents, and if so, how to - * interpret them. - */ - A_UINT32 data_type; /* This structure is used to send REQ binary blobs - * from firmware to application/service where Host drv is pass through. - * Alternatively, by specifying in the data_type field what kind of - * information is placed in data[], the target can allow the host to - * interpret the data[] contents. + * from firmware to application/service where Host drv is pass through . * Following this structure is the TLV: - * A_UINT8 data[]; <-- length in bytes given by field data_len. + * A_UINT8 data[]; <-- length in byte given by field data_len. */ /* This structure is used to send information of partner links. * Following this structure is the TLV: @@ -30188,71 +29834,6 @@ typedef struct { */ } wmi_stats_ext_event_fixed_param; -#define WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS 32 -#define WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32 1 - -typedef enum wmi_stats_ext_event_vdev_ext_bw_counters { - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_20MHz = 0, - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_40MHz, - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_80MHz, - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_160MHz, - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_320MHz, - /* values 5-7 reserved */ - WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX = 8 -} wmi_stats_ext_event_vdev_ext_bw_counters_t; - -#define WMI_STATS_EXT_EVENT_VDEV_EXT_FREQ_GET(word) \ - WMI_GET_BITS(word, 0, 16) -#define WMI_STATS_EXT_EVENT_VDEV_EXT_FREQ_SET(word, val) \ - WMI_SET_BITS(word, 0, 16, val) -#define WMI_STATS_EXT_EVENT_VDEV_EXT_VDEV_ID_GET(word) \ - WMI_GET_BITS(word, 16, 16) -#define WMI_STATS_EXT_EVENT_VDEV_EXT_VDEV_ID_SET(word, val) \ - WMI_SET_BITS(word, 16, 16, val) - -typedef struct wmi_stats_ext_event_vdev_ext { - /* version - * version = 1 means will use old/legacy struct - * version = 0 means will use new (wmi_stats_ext_event_vdev_ext) struct - * Some legacy target code branches use the old structure. - * Hence, control the backward compatibility through this - * version numbering. - */ - A_UINT32 version; - /* Number of MPDUs entering the queue */ - A_UINT32 mpdu_enqueue; - /* Number of MPDUs retried from SW */ - A_UINT32 mpdu_requeued; - /* Set of TX MCS counters */ - A_UINT32 tx_mcs[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS]; - /* Set of TX BW counters */ - A_UINT32 tx_bw[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX]; - /* Set of RX MCS counters */ - A_UINT32 rx_mcs[WMI_EXT_STATS_VDEV_EXT_MAX_MCS_COUNTERS]; - /* Set of RX BW counters */ - A_UINT32 rx_bw[WMI_STATS_EXT_EVENT_VDEV_EXT_BW_COUNTERS_MAX]; - /* Beacon RSSI (dBm units) */ - A_INT32 beacon_rssi; - /* Total number of bytes transmitted */ - A_UINT32 tx_bytes; - /* Total number of bytes received */ - A_UINT32 rx_bytes; - /* - * home channel frequency and vdev id: - * lower 16bits is frequency, upper 16bits is vdev_id - */ - union { - A_UINT32 freq__vdev_id__word32; - struct { - A_UINT32 - freq: 16, /* MHz units */ - vdev_id: 16; - }; - }; - /* opaque / unspecified contents, for debugging, etc */ - A_UINT32 opaque_dbg[WMI_EXT_STATS_VDEV_EXT_MAX_OPAQUE_DBG_WORDS32]; -} wmi_stats_ext_event_vdev_ext_t; - typedef enum { /** Default: no replay required. */ WMI_PEER_DELETE_NO_REPLAY = 0, @@ -31948,8 +31529,6 @@ typedef struct { A_UINT32 vdev_id; /* picks values from WMI_USD_MODE_STATUS */ A_UINT32 usd_mode_status; - /* Instance ID of the service */ - A_UINT32 instance_id; } wmi_usd_service_event_fixed_param; typedef enum { @@ -34408,55 +33987,6 @@ typedef enum { * A_INT8 6G 320M Channel Center Freq 6265 CTL Limit Power OFDMA */ - BIOS_PARAM_TYPE_PPAG_DATA, - /* - * BIOS_PARAM_TYPE_PPAG_DATA Structure has 12 bytes as below, - * antennaGain value unit is 0.25 dBm. - * If Enable flag is 0, FW will not use PPAG antennaGain value of bios. - * - * A_UINT8 version - * A_UINT8 enableFlag - * A_INT8 antennaGain[GAIN_BANDS]; // 9bytes - * A_UINT8 reserved - * ==================== A_INT8 antennaGain[GAIN_BANDS]; ================= - * A_INT8 atennaGain for [2400, 2483) - * A_INT8 atennaGain for [5150, 5250) - * A_INT8 atennaGain for [5250, 5350) - * A_INT8 atennaGain for [5470, 5725) - * A_INT8 atennaGain for [5725, 5895) - * A_INT8 atennaGain for [5925, 6425) - * A_INT8 atennaGain for [6425, 6525) - * A_INT8 atennaGain for [6525, 6875) - * A_INT8 atennaGain for [6875, 7125) - * ============================================================== - */ - - BIOS_PARAM_TYPE_COUNTRY_CTL_MCS_DATA, - /* - * BIOS_PARAM_TYPE_COUNTRY_CTL_MCS_DATA structure contains - * - fix length parameter: - * version, entryNum - * - variable length array - countryCtlMcsData[entryNum] - * - * A_UINT8 version; - * A_UINT8 entryNum; // 0~15 - * countryCtlMcsData countryCtlMcsData[entryNum]; // variable array, - * // 12 bytes * entryNum - * ====================struct countryCtlMcsData ====================== - * A_UINT16 countryCode; - * A_UINT8 frequencyBand; - * A_UINT8 powerMode; - * A_UINT8 ocbIndex; - * A_UINT8 mcs; - * A_UINT8 bf; - * A_UINT8 nss; - * A_UINT8 txChainNum; - * A_UINT8 compareCtl; - * A_UINT8 powerLimit; // per chain, 1/4 db - * A_UINT8 reserved; - * ============================================================== - */ - BIOS_PARAM_TYPE_MAX, } bios_param_type_e; @@ -36340,7 +35870,6 @@ typedef enum { WMI_REQUEST_CTRL_STA_RRM_STAT = 18, WMI_REQUEST_CTRL_PATH_VDEV_BCN_TX_STAT = 19, WMI_REQUEST_CTRL_PATH_PDEV_BCN_TX_STAT = 20, - WMI_REQUEST_CTRL_PATH_PDEV_CONN_STAT = 21, } wmi_ctrl_path_stats_id; typedef enum { @@ -36820,29 +36349,12 @@ typedef enum wmi_hw_mode_config_type { #define WMI_SUPPORT_AAR_GET(mld_capability) WMI_GET_BITS(mld_capability, 12, 1) #define WMI_SUPPORT_AAR_SET(mld_capability, value) WMI_SET_BITS(mld_capability, 12, 1, value) -#define WMI_SUPPORT_LINK_RECONFIG_SUPPORT_GET(mld_capability) WMI_GET_BITS(mld_capability, 13, 1) -#define WMI_SUPPORT_LINK_RECONFIG_SUPPORT_SET(mld_capability, value) WMI_SET_BITS(mld_capability, 13, 1, value) - - /* * 11BE Ext MLD Capability Set and Get macros */ #define WMI_EXT_MLD_OPERATION_PARAMETER_UPDATE_SUPP_GET(ext_mld_capability) WMI_GET_BITS(ext_mld_capability, 0, 1) #define WMI_EXT_MLD_OPERATION_PARAMETER_UPDATE_SUPP_SET(ext_mld_capability, value) WMI_SET_BITS(ext_mld_capability, 0, 1, value) -#define WMI_EXT_MLD_RECOMMENDED_MAX_SIMULTANEOUS_LINKS_GET(ext_mld_capability) WMI_GET_BITS(ext_mld_capability, 1, 4) -#define WMI_EXT_MLD_RECOMMENDED_MAX_SIMULTANEOUS_LINKS_SET(ext_mld_capability, value) WMI_SET_BITS(ext_mld_capability, 1, 4, value) - -#define WMI_EXT_MLD_NSTR_STATUS_UPDATE_SUPPORT_GET(ext_mld_capability) WMI_GET_BITS(ext_mld_capability, 5, 1) -#define WMI_EXT_MLD_NSTR_STATUS_UPDATE_SUPPORT_SET(ext_mld_capability, value) WMI_SET_BITS(ext_mld_capability, 1, 5, value) - -#define WMI_EXT_MLD_EMLSR_ONE_LINK_SUPPORT_GET(ext_mld_capability) WMI_GET_BITS(ext_mld_capability, 6, 1) -#define WMI_EXT_MLD_EMLSR_ONE_LINK_SUPPORT_SET(ext_mld_capability, value) WMI_SET_BITS(ext_mld_capability, 6, 1, value) - -#define WMI_EXT_MLD_BTM_MLD_RECOMMEND_FOR_MULTI_AP_SUPPORT_GET(ext_mld_capability) WMI_GET_BITS(ext_mld_capability, 7, 1) -#define WMI_EXT_MLD_BTM_MLD_RECOMMEND_FOR_MULTI_AP_SUPPORT_SET(ext_mld_capability, value) WMI_SET_BITS(ext_mld_capability, 7, 1, value) - - /* * 11BE MSD Capability Set and Get macros */ @@ -37126,8 +36638,7 @@ typedef struct { * Value 3 is reserved */ freq_separation_str:5, aar_support:1, - link_reconfig_support:1, - reserved2: 18; + reserved2: 19; }; A_UINT32 mld_capability; }; @@ -37135,11 +36646,7 @@ typedef struct { struct { A_UINT32 op_update_para_support:1, /* Indicates support of operation parameter update negotiation */ - recommended_max_simultaneous_links:4, - nstr_status_update_support:1, - emlsr_one_link_support:1, - btm_recommended_for_multi_ap:1, - reserved3: 24; + reserved3: 31; }; A_UINT32 ext_mld_capability; }; @@ -37587,8 +37094,6 @@ typedef struct { A_UINT32 pout_reduction_25db; /* tx chain mask: Chain mask to apply based on the temp level */ A_UINT32 tx_chain_mask; - /* duty cycle in ms for this level */ - A_UINT32 duty_cycle; } wmi_therm_throt_level_config_info; typedef enum { @@ -38546,13 +38051,6 @@ static INLINE A_UINT8 *wmi_id_to_name(A_UINT32 wmi_command) WMI_RETURN_STRING(WMI_SOC_TX_PACKET_CUSTOM_CLASSIFY_CMDID); WMI_RETURN_STRING(WMI_SET_AP_SUSPEND_RESUME_CMDID); WMI_RETURN_STRING(WMI_P2P_GO_DFS_AP_CONFIG_CMDID); - WMI_RETURN_STRING(WMI_USD_SERVICE_CMDID); - WMI_RETURN_STRING(WMI_PDEV_POWER_BOOST_CMDID); - WMI_RETURN_STRING(WMI_PDEV_POWER_BOOST_MEM_ADDR_CMDID); - WMI_RETURN_STRING(WMI_GET_SCAN_CACHE_RESULT_CMDID); - WMI_RETURN_STRING(WMI_MLO_LINK_RECONFIG_CMDID); - WMI_RETURN_STRING(WMI_MLO_LINK_RECONFIG_COMPLETE_CMDID); - WMI_RETURN_STRING(WMI_SAWF_EZMESH_HOP_COUNT_CMDID); } return (A_UINT8 *) "Invalid WMI cmd"; @@ -39254,12 +38752,6 @@ typedef struct { A_UINT32 new_alpha2; /** alpha2 characters representing the country code */ } wmi_11d_new_country_event_fixed_param; -/** FW indicating LPI AP detect or not to Host */ -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_c2c_detect_event_fixed_param */ - A_UINT32 lpi_ap_detect; /** flag to indicate LPI AP detect or not */ -} wmi_c2c_detect_event_fixed_param; - typedef struct { /** TLV tag and len; tag equals * WMITLV_TAG_STRUC_wmi_coex_get_antenna_isolation_cmd_fixed_param */ @@ -40357,7 +39849,6 @@ typedef enum _WMI_DEL_TWT_STATUS_T { WMI_DEL_TWT_STATUS_SCAN_IN_PROGRESS, /* Reason Scan in progress */ WMI_DEL_TWT_STATUS_CHANGE_CONGESTION_TIMEOUT, /* Congestion timeout changed */ WMI_DEL_TWT_STATUS_P2P_GO_NOA, /* P2P GO NOA */ - WMI_DEL_TWT_STATUS_UNSUPPORTED_MLMR_MODE, /* Teardown due to MLMR */ } WMI_DEL_TWT_STATUS_T; typedef struct { @@ -40819,109 +40310,6 @@ typedef struct { }; } wmi_spectral_fft_size_capabilities; -typedef struct { - /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_wifi_radar_cap_evt_fixed_param */ - A_UINT32 tlv_header; - /* ID of pdev to which capability is sent */ - A_UINT32 pdev_id; -} wmi_pdev_wifi_radar_cap_evt_fixed_param; - -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_PDEV_ID_GET(word32) \ - WMI_GET_BITS(word32, 0, 4) -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_PDEV_ID_SET(word32, value) \ - WMI_SET_BITS(word32, 0, 4, value) - -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_NUM_TX_GET(word32) \ - WMI_GET_BITS(word32, 4, 28) -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_NUM_TX_SET(word32, value) \ - WMI_SET_BITS(word32, 4, 28, value) - -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_EXPO_NUM_RX_GET(word32) \ - WMI_GET_BITS(word32, 0, 16) -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_EXPO_NUM_RX_SET(word32, value) \ - WMI_SET_BITS(word32, 0, 16, value) - -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_NUM_INITIAL_SKIP_RX_GET(word32) \ - WMI_GET_BITS(word32, 16, 16) -#define WMI_WIFI_RADAR_LTF_LENGTH_CAPABILITIES_LTF_MAX_NUM_INITIAL_SKIP_RX_SET(word32, value) \ - WMI_SET_BITS(word32, 16, 16, value) - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wifi_radar_ltf_length_capabilities */ - union { - A_UINT32 ltf_cap1_word32; - struct { - /* - * bits 3:0 -> PDEV ID - * bits 31:4 -> LTF at Tx configuration - */ - A_UINT32 - pdev_id: 4, - /* Max number of LTF at Tx configuration */ - ltf_max_num_tx: 28; - }; - }; - union { - A_UINT32 ltf_cap2_word32; - struct { - /* - * bits 15:0 -> LTF at Rx configuration in exponential term - * bits 31:16 -> LTF to skip intially at Rx configuration - */ - A_UINT32 - ltf_max_expo_num_rx: 16, - /* Max number of LTF at Rx configuration */ - ltf_max_num_initial_skip_rx: 16; - /* Max number of LTF to skip initially at Rx configuration */ - }; - }; - /** - * This TLV contains target LTF capability for Wi-Fi Radar sensing feature. - */ -} wmi_wifi_radar_ltf_length_capabilities; - -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_PDEV_ID_GET(word32) \ - WMI_GET_BITS(word32, 0, 4) -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_PDEV_ID_SET(word32, value) \ - WMI_SET_BITS(word32, 0, 4, value) - -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_MAX_NUM_RX_CHAIN_GET(word32) \ - WMI_GET_BITS(word32, 4, 7) -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_MAX_NUM_RX_CHAIN_SET(word32, value) \ - WMI_SET_BITS(word32, 4, 7, value) - -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_BEST_ISOLATED_CHAIN_PAIR_SEL_GET(word32) \ - WMI_GET_BITS(word32, 11, 1) -#define WMI_WIFI_RADAR_CHAIN_CAPABILITIES_BEST_ISOLATED_CHAIN_PAIR_SEL_SET(word32, value) \ - WMI_SET_BITS(word32, 11, 1, value) - -typedef struct { - /** TLV tag and len; tag equals - * WMITLV_TAG_STRUC_wmi_wifi_radar_chain_capabilities */ - A_UINT32 tlv_header; - union { - A_UINT32 chain_cap1_word32; - struct { - /* - * bits 3:0 -> PDEV ID - * bits 10:4 -> Max number of Rx chain capture in one shot - * bit 11 -> Best Isolated Chain pair selection enabled or not - * bits 31:12 -> reserved - */ - A_UINT32 - pdev_id: 4, - /* Max num of Rx chain can be used to capture at a time */ - max_num_rx_chain: 7, - /* Chain-to-Chain Isolation based chain pair support */ - best_isolated_chain_pair_sel: 1, - reserved:20; - }; - }; - /** - * This TLV contains target chain capability for Wi-Fi Radar sensing feature. - */ -} wmi_wifi_radar_chain_capabilities; - typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_ctl_failsafe_event_params */ A_UINT32 pdev_id; /* ID of pdev to which ctl failsafe status is sent */ @@ -41046,17 +40434,6 @@ typedef struct { * than rssi_6g_threshold. If rssi_6g_threshold is 0, it should be ignored. */ A_INT32 rssi_6g_threshold; /* units = dBm */ - /** bss_load_alpha_pct - * This parameter is used for updating the exponential average of the - * BSS load: - * new avg BSS load = - * new BSS load measurement * alpha / 100 + - * old avg BSS load * (100 - alpha) / 100 - * This parameter uses percent units. E.g. if bss_load_alpha_pct == 10, - * the new average will be the sum of 10% of the new measurement + 90% of - * the old average. - */ - A_UINT32 bss_load_alpha_pct; } wmi_roam_bss_load_config_cmd_fixed_param; /** Deauth roam trigger parameters */ @@ -41327,11 +40704,6 @@ typedef enum { WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY, WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU, WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU, - /* MLD_EXTRA_PARTIAL_SCAN: - * FW triggers extra partial scan when all ml links are not found - * during first partial scan. - */ - WMI_ROAM_TRIGGER_SUB_REASON_MLD_EXTRA_PARTIAL_SCAN, } WMI_ROAM_TRIGGER_SUB_REASON_ID; typedef enum wmi_roam_invoke_status_error { @@ -42014,9 +41386,6 @@ typedef struct { #define WMI_MLO_LINK_INFO_GET_IEEE_LINK_ID(link_info) WMI_GET_BITS(link_info, 10, 4) #define WMI_MLO_LINK_INFO_SET_IEEE_LINK_ID(link_info, val) WMI_SET_BITS(link_info, 10, 4, val) -#define WMI_MLO_LINK_INFO_GET_FREQ(link_info) WMI_GET_BITS(link_info, 14, 16) -#define WMI_MLO_LINK_INFO_SET_FREQ(link_info, val) WMI_SET_BITS(link_info, 14, 16, val) - typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_link_info_tlv_param */ wmi_mac_addr link_addr; @@ -42029,7 +41398,6 @@ typedef struct { * 1 - rejected * b[7-9] : Band - link band info (band value is from wmi_mlo_band_info) * b[10-13] : IEEE link id - Link id associated with AP - * b[14-29] : Frequency - Link channel frequency in MHz units */ } wmi_mlo_link_info; @@ -42493,7 +41861,6 @@ typedef enum { WMI_6GHZ_REG_PWRMODE_SP = 1, /* SP mode for AP and client products */ WMI_6GHZ_REG_PWRMODE_VLP = 2, /* VLP mode for AP and client products */ WMI_6GHZ_REG_PWRMODE_SP_STA = 3, /* SP client mode for AP products */ - WMI_6GHZ_REG_PWRMODE_C2C = 4, /*C2C client mode for AP and client products*/ WMI_6GHZ_REG_PWRMODE_MAX = 5 } WMI_6GHZ_REG_PWRMODE_TYPE; @@ -44583,13 +43950,6 @@ typedef struct { /****** End of 11BE EHT MAC Capabilities Information field ******/ -/****** 11BE EHT OPS Information field ******/ - -/* Bit 0 is for MCS15. If bit0 is 1 then we enable mcs15 */ -#define WMI_EHT_OPS_SUPMCS15_GET(eht_ops) WMI_GET_BITS(eht_ops, 0, 1) -#define WMI_EHT_OPS_SUPMCS15_SET(eht_ops, value) WMI_SET_BITS(eht_ops, 0, 1, value) - -/****** End of 11BE EHT OPS Information field ******/ typedef struct { /** TLV tag and len; tag equals @@ -46528,7 +45888,6 @@ typedef enum { WMI_MLO_LINK_FORCE_REASON_LINK_REMOVAL = 3, /* Set force specific links because of AP-side link removal */ WMI_MLO_LINK_FORCE_REASON_TDLS = 4, /* Set force specific links because of 11BE MLO TDLS setup/teardown */ WMI_MLO_LINK_FORCE_REASON_REVERT_FAILURE = 5, /* Set force specific links for revert previous failed due to host reject */ - WMI_MLO_LINK_FORCE_REASON_LINK_DELETE = 6, /* Set force specific links because link is deleted from associated link set */ } WMI_MLO_LINK_FORCE_REASON; #define WMI_MLO_CONTROL_FLAGS_GET_OVERWRITE_FORCE_ACTIVE(mlo_flags) \ @@ -46752,9 +46111,6 @@ typedef struct { A_UINT32 mld_group_id; /** pdev_id for identifying the MAC, See macros starting with WMI_PDEV_ID_ for values. */ A_UINT32 pdev_id; - - A_UINT32 max_num_ml_peers; - /* * Followed by TLVs: * A_UINT32 hw_link_ids[]; @@ -46839,31 +46195,6 @@ typedef struct { */ } wmi_mlo_link_recommendation_fixed_param; -typedef struct { - /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_fixed_param */ - A_UINT32 tlv_header; - /* unique id identifying the VDEV, generated by the caller */ - A_UINT32 vdev_id; - wmi_mac_addr mld_addr; /* MLD address of AP */ - /* The TLVs follows this structure: - * wmi_mlo_link_add_param link_add_param[]; - * wmi_mlo_link_del_param link_del_param[]; - */ -} wmi_mlo_link_reconfig_fixed_param; - -typedef struct { - /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_complete_fixed_param */ - A_UINT32 tlv_header; - /* unique id identifying the VDEV, generated by the caller */ - A_UINT32 vdev_id; - /* MLD address of AP */ - wmi_mac_addr mld_addr; - /* any non-zero values of status indicate link reconfig failure. */ - A_UINT32 status; - /* valid only when status is non-zero. fw will do reassociation if link reconfig failure */ - A_UINT32 reassoc_if_failure; -} wmi_mlo_link_reconfig_complete_fixed_param; - #define WMI_TID_TO_LINK_MAP_TID_NUM_GET(_var) WMI_GET_BITS(_var, 0, 5) #define WMI_TID_TO_LINK_MAP_TID_NUM_SET(_var, _val) WMI_SET_BITS(_var, 0, 5, _val) @@ -47018,7 +46349,7 @@ typedef struct { */ } wmi_peer_tid_to_link_map_fixed_param; -typedef struct { +typedef struct{ /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_ap_vdev_tid_to_link_map_cmd_fixed_param */ A_UINT32 tlv_header; /** pdev_id for identifying the MAC, See macros starting with WMI_PDEV_ID_ for values. */ @@ -47728,19 +47059,6 @@ typedef struct { A_UINT32 svc_class_id; /* which service class is being disabled */ } wmi_sawf_svc_class_disable_cmd_fixed_param; -/* Used to store Hop count info for SDWF-Ezmesh scenario based on topology changes */ -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sawf_ezmesh_hop_count_cmd_fixed_param */ - A_UINT32 peer_id; - A_UINT32 hop_count; - /* delay_bound: - * Placeholder for future functionality where delay bound will be directly - * passed to FW from host. - * (units = ms) - */ - A_UINT32 delay_bound; -} wmi_sawf_ezmesh_hop_count_cmd_fixed_param; - typedef struct { A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sw_cal_ver_cap */ A_UINT32 bdf_cal_ver; /* SW cal version in BDF */ @@ -48347,7 +47665,6 @@ typedef struct { #define WMI_PDEV_SET_CUSTOM_TX_PWR_MAX_CHAIN_NUM 4 #define WMI_PDEV_SET_CUSTOM_TX_PWR_MAX_2G_RATE_NUM 18 -#define WMI_PDEV_SET_CUSTOM_TX_PWR_MAX_2G_RATE_NUM_EXT 8 #define WMI_PDEV_SET_CUSTOM_TX_PWR_MAX_5G_6G_RATE_NUM 24 @@ -48361,14 +47678,14 @@ typedef struct { */ /* currently 2GHz band has 2 chains (though space is allocated for up - * to 4 chains) and each chain has 18 rates and 8 extended rates. + * to 4 chains) and each chain has 18 rates. * bitmap_of_2GHz_band[0] -> chain 0 bitmap: - * |bit 0|bit 1|......|bit 17| bit 18 |......| bit 25 | - * |rate 0|rate 1|......|rate 17|ext rate 0|......|ext rate 7| + * |bit 0|bit 1|......|bit 17| + * |rate 0|rate 1|......|rate 17| * * bitmap_of_2GHz_band[1] -> chain 1 bitmap: - * |bit 0|bit 1|......|bit 17| bit 18 |......| bit 25 | - * |rate 0|rate 1|......|rate 17|ext rate 0|......|ext rate 7| + * |bit 0|bit 1|......|bit 17| + * |rate 0|rate 1|......|rate 17| * * bitmap_of_2GHz_band[2] -> reserved * bitmap_of_2GHz_band[3] -> reserved @@ -48910,7 +48227,6 @@ typedef enum _WMI_VDEV_PAUSE_TYPE WMI_VDEV_PAUSE_TYPE_UNKNOWN = 0, WMI_VDEV_PAUSE_TYPE_MLO_LINK = 1, WMI_VDEV_PAUSE_TYPE_TX = 2, - WMI_VDEV_PAUSE_TYPE_TX_DATA = 3, } WMI_VDEV_PAUSE_TYPE; typedef struct { @@ -48925,18 +48241,10 @@ typedef struct { A_UINT32 pause_dur_ms; } wmi_vdev_pause_cmd_fixed_param; -typedef enum _WMI_MLO_link_BSS_OP_CODE -{ - MLO_LINK_BSS_OP_UPDATE = 0, - MLO_LINK_BSS_OP_ADD = 1, - MLO_LINK_BSS_OP_DEL = 2, -} WMI_MLO_link_BSS_OP_CODE; - typedef struct { A_UINT32 tlv_header; A_UINT32 ieee_link_id; /* key to identify a link */ wmi_channel wmi_chan; - A_UINT32 op_code; /* see definition of WMI_MLO_link_BSS_OP_CODE */ } wmi_mlo_link_bss_param; typedef struct { @@ -49492,15 +48800,13 @@ typedef struct { #define WMI_PEER_ACTIVE_TRAFFIC_TYPE_BACKGROUND_S 2 /* bits 3-15 are reserved for new non-interactive traffic types */ -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_M 0x00080000 -#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_WEB_BROWSING_S 19 -/* bits 20-31 are reserved for new interactive traffic types */ +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_M 0x00010000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_GAMING_S 16 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_M 0x00020000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VOIP_S 17 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_M 0x00040000 +#define WMI_PEER_ACTIVE_TRAFFIC_TYPE_VIDEO_CONF_S 18 +/* bits 19-31 are reserved for new interactive traffic types */ typedef struct { A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_active_traffic_map_cmd_fixed_param */ @@ -49557,279 +48863,8 @@ typedef struct { A_UINT32 tlv_header; /* status takes values from WMI_MLO_TID_TO_LINK_MAP_STATUS */ A_UINT32 status; - /* Vdev_id on which T2LM command request is received */ - A_UINT32 vdev_id; } wmi_mlo_peer_tid_to_link_map_event_fixed_param; -typedef struct { - /** TLV tag and len; tag equals - * WMITLV_TAG_STRUC_wmi_mlo_link_reconfig_start_indication_event_fixed_param */ - A_UINT32 tlv_header; - /* vdev_id on which link reconfig indicate event is received */ - A_UINT32 vdev_id; - /* MLD MAC address */ - wmi_mac_addr mld_mac_address; - /* trigger reason of request link reconfig to host, - * enum of WMI_ROAM_TRIGGER_REASON_ID. - * WMI_ROAM_TRIGGER_REASON_FORCED will be used for STA(User/Host) - * initiated link reconfig. - * WMI_ROAM_TRIGGER_REASON_BTM will be used for AP initiated link reconfig. - * Other will be used for STA(fw) initiated link reconfig. - */ - A_UINT32 trigger_reason; - /* trigger_result: - * This field is only valid when trigger_reason == - * WMI_ROAM_TRIGGER_REASON_FORCED. - * Any non-zero values of trigger_result indicate link reconfig failure. - */ - A_UINT32 trigger_result; - /* The TLVs follows this structure: - * wmi_mlo_link_add_param link_add_param[]; - * wmi_mlo_link_del_param link_del_param[]; - */ -} wmi_mlo_link_reconfig_start_indication_event_fixed_param; - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_link_add_param */ - A_UINT32 link_id; /* AP's link ID of add link */ - wmi_mac_addr link_addr; /* AP's link address of add link */ - /* vdev_id: - * which vdev to repurpose on with add link_id if it's not 0xff - */ - A_UINT32 vdev_id; -} wmi_mlo_link_add_param; - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mlo_link_del_param */ - A_UINT32 link_id; /* AP's link id of delete link */ - wmi_mac_addr link_addr; /* AP's link address of delete link */ -} wmi_mlo_link_del_param; - -typedef enum { - WMI_EVENT_POWER_BOOST_START_TRAINING = 0, - WMI_EVENT_POWER_BOOST_ABORT, - WMI_EVENT_POWER_BOOST_COMPLETE, - - WMI_EVENT_POWER_BOOST_MAX -} wmi_pdev_power_boost_event_type; - -typedef enum { - WMI_PDEV_POWER_BOOST_TS_FIRST_PASS = 0, - WMI_PDEV_POWER_BOOST_TS_SECOND_PASS, - - WMI_PDEV_POWER_BOOST_TS_MAX -} wmi_pdev_power_boost_training_stage; - -typedef struct { - /* WMITLV_TAG_STRUC_wmi_pdev_power_boost_event_fixed_param */ - A_UINT32 tlv_header; - /* to identify for which pdev the event is sent */ - A_UINT32 pdev_id; - /* enum wmi_pdev_power_boost_event_type to update the power boost status */ - A_UINT32 status; - /* training_stage: - * The training stage for which the I/Q samples are updated in DDR. - * This field holds a wmi_pdev_power_boost_training_stage value. - */ - A_UINT32 training_stage; - /* MCS value for which the current DPD training has been done */ - A_UINT32 mcs; - /* bandwidth: - * Bandwidth value in Mhz for which the current DPD training has been done - */ - A_UINT32 bandwidth; - /* current target temperature while training the DPD packet in degree C */ - A_INT32 temperature_degreeC; - /* primary channel frequency in MHz for which DPD training is done */ - A_UINT32 primary_chan_mhz; - /** Center frequency 1 in MHz */ - A_UINT32 band_center_freq1; - /** Center frequency 2 in MHz - valid only for 11ac/VHT 80+80 mode */ - A_UINT32 band_center_freq2; - /* phy_mode: - * PHY mode as listed by enum WLAN_PHY_MODE, for which the current DPD - * training has been done - */ - A_UINT32 phy_mode; - /* size_kb: - * Size of the buffer consumed to write the I/Q samples data by uCode, - * in units of KB - */ - A_UINT32 size_kb; -} wmi_pdev_power_boost_event_fixed_param; - -typedef enum { - WMI_CMD_POWER_BOOST_READY = 0, - WMI_CMD_POWER_BOOST_ESTIMATED_DATA, - WMI_CMD_POWER_BOOST_ABORT, - - WMI_CMD_POWER_BOOST_MAX -} wmi_pdev_power_boost_cmd_type; - -typedef struct { - /* WMITLV_TAG_STRUC_wmi_pdev_power_boost_cmd_fixed_param */ - A_UINT32 tlv_header; - /* to identify for which pdev the cmd is sent */ - A_UINT32 pdev_id; - /* enum wmi_pdev_power_boost_cmd_type to update the power boost status */ - A_UINT32 status; - /* wmi_pdev_power_boost_training_stage value to indicate training stage */ - A_UINT32 training_stage; - /* MCS value for which the Power Boost training has been done */ - A_UINT32 mcs; - /* Bandwidth in Mhz for which the Power Boost training has been done */ - A_UINT32 bandwidth; - /* current target temperature while training the DPD packet in degree C */ - A_INT32 temperature_degreeC; - /* primary 20 MHz channel frequency in MHz */ - A_UINT32 primary_chan_mhz; - /* Center frequency 1 in MHz*/ - A_UINT32 band_center_freq1; - /* Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode*/ - A_UINT32 band_center_freq2; - /* phy_mode: - * phy mode as listed by enum WLAN_PHY_MODE, for which the current - * Power Boost training has been done. - */ - A_UINT32 phy_mode; - /* tx_evm: - * Tx_evm value as calculated after the Power Boost training, - * in units of 1/4 (0.25dBm) steps. - */ - A_INT32 tx_evm; - /* tx_mask_margin: - * Tx spectral mask margin value as calculated after the Power Boost - * training, in units of 1/4 (0.25dBm) steps. - */ - A_INT32 tx_mask_margin; -} wmi_pdev_power_boost_cmd_fixed_param; - -typedef struct { - /* WMITLV_TAG_STRUC_wmi_pdev_power_boost_mem_addr_cmd_fixed_param */ - A_UINT32 tlv_header; - /* to identify for which pdev the cmd is sent */ - A_UINT32 pdev_id; - /* Lower 32 bit DDR address as allocated by the host */ - A_UINT32 paddr_aligned_lo; - /* Higher 32 bit DDR address as allocated by the host */ - A_UINT32 paddr_aligned_hi; - /* Size of the buffer been allocated by the Host in units of KB */ - A_UINT32 size; -} wmi_pdev_power_boost_mem_addr_cmd_fixed_param; - -typedef struct { - /* WMITLV_TAG_STRUC_wmi_get_scan_cache_result_cmd_fixed_param */ - A_UINT32 tlv_header; -} wmi_get_scan_cache_result_cmd_fixed_param; - -/* Element ID 61 (HT Operation) is present (see HT 7.3.2) */ -#define WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT_GET(flags) WMI_GET_BITS(flags, 0, 1) -#define WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT_SET(flags, value) WMI_SET_BITS(flags, 0, 1, value) - -/* Element ID 192 (VHT Operation) is present (see VHT 8.4.2) */ -#define WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT_GET(flags) WMI_GET_BITS(flags, 1, 1) -#define WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT_SET(flags, value) WMI_SET_BITS(flags, 1, 1, value) - -/* Element ID 255 + Extension 36 (HE Operation) is present (see 802.11ax 9.4.2.1) */ -#define WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT_GET(flags) WMI_GET_BITS(flags, 2, 1) -#define WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT_SET(flags, value) WMI_SET_BITS(flags, 2, 1, value) - -/* Element ID 255 + Extension 106 (EHT Operation) is present(see 802.11be D1.5 9.4.2.1) */ -#define WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT_GET(flags) WMI_GET_BITS(flags, 3, 1) -#define WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT_SET(flags, value) WMI_SET_BITS(flags, 3, 1, value) - -/* Element ID 127 (Extended Capabilities) is present, and bit 70 (Fine Timing Measurement Responder) is set to 1 (see IEEE Std 802.11-2016 9.4.2.27) */ -#define WIFI_CACHED_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER_GET(flags) WMI_GET_BITS(flags, 4, 1) -#define WIFI_CACHED_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER_SET(flags, value) WMI_SET_BITS(flags, 4, 1, value) - - -typedef struct { - wmi_channel_width width; - A_UINT32 center_frequency0; /* Frequency value in MHz */ - A_UINT32 center_frequency1; /* Frequency value in MHz */ - A_UINT32 primary_frequency; /* Frequency value in MHz */ -} wifi_channel_spec; - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_scan_cache_info */ - /* age_ms: - * Number of milliseconds prior to WMI_GET_SCAN_CACHE_RESULT_CMDID - * from when the probe response or beacon frame that was used to - * populate this info. - */ - A_UINT32 age_ms; - - /* The Capability Information field from beacon or probe response frame */ - A_UINT32 capability; - - wmi_ssid ssid; - - wmi_mac_addr bssid; - - /* A set of flags from WIFI_CACHED_SCAN_RESULT_FLAGS_* */ - A_UINT32 flags; - - A_INT32 rssi; /* units = dBm */ - - wifi_channel_spec chanspec; -} wmi_scan_cache_info; - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_scan_cache_result_event_fixed_param */ - - /* The below TLVs follow this TLV in the WMI_SCAN_CACHE_RESULT_EVENT msg: - * - A_UINT32 scan_freq_list[]; - * - struct wmi_scan_cache_info scan_cache_info[]; - */ -} wmi_scan_cache_result_fixed_param; - -#define WMI_POWER_BOOST_CAPABILITIES_PHY_ID_GET(word32) WMI_GET_BITS(word32, 0, 4) -#define WMI_POWER_BOOST_CAPABILITIES_PHY_ID_SET(word32, value) WMI_SET_BITS(word32, 0, 4, value) -#define WMI_POWER_BOOST_CAPABILITIES_POWER_BOOST_ENABLE_GET(word32) WMI_GET_BITS(word32, 4, 1) -#define WMI_POWER_BOOST_CAPABILITIES_POWER_BOOST_ENABLE_SET(word32, value) WMI_SET_BITS(word32, 4, 1, value) - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_POWER_BOOST_CAPABILITIES */ - union { - A_UINT32 phy_id__power_boost_enable__word32; - struct { - /* - * bits 3:0 -> PHY ID - * bit 4 -> power boost enable flag - * bits 31:5 -> reserved - */ - A_UINT32 - phy_id: 4, - /* Power Boost feature is enabled or not */ - power_boost_enable: 1, - reserved: 27; - }; - }; -} WMI_POWER_BOOST_CAPABILITIES; - -#define WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES_PHY_ID_GET(word32) WMI_GET_BITS(word32, 0, 4) -#define WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES_PHY_ID_SET(word32, value) WMI_SET_BITS(word32, 0, 4, value) -#define WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES_RSSI_ACCURACY_ENABLE_GET(word32) WMI_GET_BITS(word32, 4, 1) -#define WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES_RSSI_ACCURACY_ENABLE_SET(word32, value) WMI_SET_BITS(word32, 4, 1, value) - -typedef struct { - A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_RSSI_ACCURACY_CAPABILITIES */ - union { - struct { - /* - * bits 3:0 -> PHY ID - * bit 4 -> rssi accuracy enhancement using MultiGainRSSI - * offset correction enable flag - * bits 31:5 -> reserved - */ - A_UINT32 - phy_id: 4, - rssi_accuracy_enable: 1, - reserved: 27; - }; - }; -} WMI_RSSI_ACCURACY_IMPROVEMENT_CAPABILITIES; - /* ADD NEW DEFS HERE */ diff --git a/drivers/staging/fw-api/fw/wmi_version.h b/drivers/staging/fw-api/fw/wmi_version.h index c579a5f5830c9e140de856afb9819ee1bc749e86..656d21d73472ac1364764855a063e787ad30ab92 100644 --- a/drivers/staging/fw-api/fw/wmi_version.h +++ b/drivers/staging/fw-api/fw/wmi_version.h @@ -37,7 +37,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 1555 +#define __WMI_REVISION_ 1505 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work diff --git a/drivers/staging/fw-api/hw/kiwi/v1/wcss_seq_hwioreg_umac.h b/drivers/staging/fw-api/hw/kiwi/v1/wcss_seq_hwioreg_umac.h index 03a0e8f9dc2de42dc45c2ff352ed97a8cd8cfe30..69dac92cb19e850e46e1a76a60e369c733ec14d0 100644 --- a/drivers/staging/fw-api/hw/kiwi/v1/wcss_seq_hwioreg_umac.h +++ b/drivers/staging/fw-api/hw/kiwi/v1/wcss_seq_hwioreg_umac.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021,2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -386,11 +386,6 @@ #define HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(x) ((x) + 0x30d0) #define HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK 0xfffff00 #define HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT 8 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_ADDR(x) ((x) + 0x3b0) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_BMSK 0xffff0000 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_SHFT 16 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_BMSK 0xffff -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_SHFT 0 #define HWIO_REO_R0_REO2SW1_RING_MSI2_BASE_LSB_ADDR(x) ((x) + 0x3fc) #define HWIO_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_ADDR(x) ((x) + 0x400) #define HWIO_REO_R0_REO2SW1_RING_MSI2_DATA_ADDR(x) ((x) + 0x404) diff --git a/drivers/staging/fw-api/hw/kiwi/v2/wcss_seq_hwioreg_umac.h b/drivers/staging/fw-api/hw/kiwi/v2/wcss_seq_hwioreg_umac.h index 11cb09569e7d063583e564c5566f2a7eeef3b66c..f594c525deedaba32d495f371875580f04d43198 100644 --- a/drivers/staging/fw-api/hw/kiwi/v2/wcss_seq_hwioreg_umac.h +++ b/drivers/staging/fw-api/hw/kiwi/v2/wcss_seq_hwioreg_umac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -224,11 +224,6 @@ #define HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK 0xfffff00 #define HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT 8 #define HWIO_REO_R0_REO2SW1_RING_ID_ADDR(x) ((x) + 0x4ec) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_ADDR(x) ((x) + 0x4f0) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_BMSK 0xffff0000 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_SHFT 16 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_BMSK 0xffff -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_SHFT 0 #define HWIO_REO_R0_REO2SW1_RING_MISC_ADDR(x) ((x) + 0x4f4) #define HWIO_REO_R0_REO2SW1_RING_HP_ADDR_LSB_ADDR(x) ((x) + 0x4f8) #define HWIO_REO_R0_REO2SW1_RING_HP_ADDR_MSB_ADDR(x) ((x) + 0x4fc) diff --git a/drivers/staging/fw-api/hw/peach/v1/wcss_seq_hwioreg_umac.h b/drivers/staging/fw-api/hw/peach/v1/wcss_seq_hwioreg_umac.h index b56832a90289722cdbe69b8171d2bff2f1cc1b2b..70f00a5642055bef59e1bf288c831c6bfe349287 100644 --- a/drivers/staging/fw-api/hw/peach/v1/wcss_seq_hwioreg_umac.h +++ b/drivers/staging/fw-api/hw/peach/v1/wcss_seq_hwioreg_umac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -794,11 +794,6 @@ #define HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK 0xfffff00 #define HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT 8 #define HWIO_REO_R0_REO2SW1_RING_ID_ADDR(x) ((x) + 0x508) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_ADDR(x) ((x) + 0x50c) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_BMSK 0xffff0000 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_SHFT 16 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_BMSK 0xffff -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_SHFT 0 #define HWIO_REO_R0_REO2SW1_RING_MISC_ADDR(x) ((x) + 0x510) #define HWIO_REO_R0_REO2SW1_RING_MISC_TRANSACTION_TYPE_BMSK 0x8000000 #define HWIO_REO_R0_REO2SW1_RING_MISC_TRANSACTION_TYPE_SHFT 27 diff --git a/drivers/staging/fw-api/hw/peach/v2/wcss_seq_hwioreg_umac.h b/drivers/staging/fw-api/hw/peach/v2/wcss_seq_hwioreg_umac.h index a70dea57d36a9f1616a1ce601532f1c7251a0079..4bfd1cc759845272a3ac4dcb38020d4aa9547aba 100644 --- a/drivers/staging/fw-api/hw/peach/v2/wcss_seq_hwioreg_umac.h +++ b/drivers/staging/fw-api/hw/peach/v2/wcss_seq_hwioreg_umac.h @@ -797,11 +797,6 @@ #define HWIO_REO_R0_REO2SW1_RING_MISC_ADDR(x) ((x) + 0x510) #define HWIO_REO_R0_REO2SW1_RING_MISC_TRANSACTION_TYPE_BMSK 0x8000000 #define HWIO_REO_R0_REO2SW1_RING_MISC_TRANSACTION_TYPE_SHFT 27 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_ADDR(x) ((x) + 0x50c) -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_BMSK 0xffff0000 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_AVAIL_WORDS_SHFT 16 -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_BMSK 0xffff -#define HWIO_REO_R0_REO2SW1_RING_STATUS_NUM_VALID_WORDS_SHFT 0 #define HWIO_REO_R0_REO2SW1_RING_HP_ADDR_LSB_ADDR(x) ((x) + 0x514) #define HWIO_REO_R0_REO2SW1_RING_HP_ADDR_MSB_ADDR(x) ((x) + 0x518) #define HWIO_REO_R0_REO2SW1_RING_PRODUCER_INT_SETUP_ADDR(x) ((x) + 0x524) diff --git a/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h b/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h index a26ac6d1db6e5ac8c0bc608fb4b5f21f77d4ebcd..87eecad0f2854a7b74f47ec5059efd2c9813dd2e 100644 --- a/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h +++ b/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,7 @@ #include #include "cfg_dp.h" +#include "cfg_hif.h" #include #ifdef WLAN_SUPPORT_GREEN_AP #include "cfg_green_ap_params.h" @@ -38,7 +39,8 @@ CFG_DP \ CFG_EXTSCAN_ALL \ CFG_GREEN_AP_ALL \ - CFG_SPECTRAL_ALL + CFG_SPECTRAL_ALL \ + CFG_HIF #endif /* __CFG_CONVERGED_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h b/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h index 59423bd48362cb7b08dbff93a816cd0c7e42f852..375bce92154bc10b02ea8ecec5f2189068aff1b3 100644 --- a/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h +++ b/drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -85,10 +85,10 @@ enum cfg_fallback_behavior { (NON_INI, IPV6, struct qdf_ipv6_addr, name, -1, -1, -1, desc, def) /* utility macros/functions */ -#ifdef CONFIG_MCL -#define MCL_OR_WIN_VALUE(mcl_value, win_value) mcl_value +#ifdef CONFIG_AP_PLATFORM +#define PLATFORM_VALUE(non_ap_value, ap_value) ap_value #else -#define MCL_OR_WIN_VALUE(mcl_value, win_value) win_value +#define PLATFORM_VALUE(non_ap_value, ap_value) non_ap_value #endif #endif /* __CFG_DEFINE_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h b/drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h index afc240b808e3bd071ee35bac6e727c9fb11dd2c9..986ba246be297d2da901e784de1666d813f0d169 100644 --- a/drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h +++ b/drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h @@ -70,7 +70,8 @@ struct cfg_values { struct cfg_values *cfg_psoc_get_values(struct wlan_objmgr_psoc *psoc); -#define __cfg_get(psoc, id) (cfg_psoc_get_values(psoc)->id##_internal) +#define __cfg_get(psoc, id) (cfg_psoc_get_values( \ + (struct wlan_objmgr_psoc *)psoc)->id##_internal) #endif /* __I_CFG_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c b/drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c index a923ed04e893449f6941c1e615361143707151fd..297c3706a8228a6ed69bce8b649dcb8935b6e389 100644 --- a/drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c +++ b/drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c @@ -234,8 +234,8 @@ cfg_mac_item_handler(struct cfg_value_store *store, return; cfg_err("%s=%s - Invalid format (status %d); Using default " - QDF_MAC_ADDR_STR, meta->name, str_value, status, - QDF_MAC_ADDR_ARRAY(store_value->bytes)); + QDF_MAC_ADDR_FMT, meta->name, str_value, status, + QDF_MAC_ADDR_REF(store_value->bytes)); } static __attribute__((unused)) void @@ -539,7 +539,8 @@ cfg_store_print(struct wlan_objmgr_psoc *psoc) #undef __CFG_INI_MAC #define __CFG_INI_MAC(id, mtype, ctype, name, desc, def...) \ - cfg_nofl_debug("%s %pM", name, (&store->values.id##_internal)->bytes); + cfg_nofl_debug("%s "QDF_MAC_ADDR_FMT, name, \ + QDF_MAC_ADDR_REF((&store->values.id##_internal)->bytes)); #undef __CFG_INI_IPV4 #define __CFG_INI_IPV4(id, mtype, ctype, name, desc, def...) \ @@ -591,8 +592,8 @@ cfg_ini_config_print(struct wlan_objmgr_psoc *psoc, uint8_t *buf, #undef __CFG_INI_MAC #define __CFG_INI_MAC(id, mtype, ctype, name, desc, def...) \ do { \ - len = qdf_scnprintf(buf, buflen, "%s %pM\n", name, \ - (&store->values.id##_internal)->bytes); \ + len = qdf_scnprintf(buf, buflen, "%s "QDF_MAC_ADDR_FMT"\n", name, \ + QDF_MAC_ADDR_REF((&store->values.id##_internal)->bytes)); \ buf += len; \ buflen -= len; \ } while (0); diff --git a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_cal_client_api.c b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_cal_client_api.c index 37217434ac6f66fd325b51443df345c5cb9e42f0..08c8e55f42e2dee8b21d1d605b5e02c35e5b9eb8 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_cal_client_api.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_cal_client_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,9 +27,10 @@ * * return: void */ -void dp_cal_client_attach(void **cal_client_ctx, void *pdev, +void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx, + struct cdp_pdev *pdev, qdf_device_t osdev, - void (*dp_iterate_peer_list)(void *)) + void (*dp_iterate_peer_list)(struct cdp_pdev *)) { struct cal_client *cal_cl; @@ -54,7 +55,7 @@ qdf_export_symbol(dp_cal_client_attach); * * return: void */ -void dp_cal_client_detach(void **cal_client_ctx) +void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx) { struct cal_client *cal_cl; @@ -147,6 +148,14 @@ void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats) peer_stats->tx.tx_data_ucast_rate = temp_tx_ucast_pkts - peer_stats->tx.tx_data_ucast_last; + /* Check tx and rx packets in last one second, and increment + * inactive time for peer + */ + if (peer_stats->tx.tx_data_rate || peer_stats->rx.rx_data_rate) + peer_stats->tx.inactive_time = 0; + else + peer_stats->tx.inactive_time++; + peer_stats->rx.rx_bytes_success_last = temp_rx_bytes; peer_stats->rx.rx_data_success_last = temp_rx_data; peer_stats->tx.tx_bytes_success_last = temp_tx_bytes; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c index a11cbfe6f42d58251788fed43bad3671d8db63e1..78bc187a1b6d2aeff924329e9987b9fe6a52f6f1 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c @@ -3209,17 +3209,20 @@ enum DP_CMN_MODULATION_TYPE dp_getmodulation( * preamble - preamble * @bw - Transmission Bandwidth * @rix: rate index to be populated + * @ratecode: ratecode * * return - rate in kbps */ uint32_t dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, - uint8_t bw, uint32_t *rix) + uint8_t bw, uint32_t *rix, uint16_t *ratecode) { uint32_t ratekbps = 0, res = RT_INVALID_INDEX; /* represents failure */ uint16_t rc; enum DP_CMN_MODULATION_TYPE mod; + /* For error case, where idx exceeds bountry limit */ + *ratecode = 0; mod = dp_getmodulation(preamble, bw); rc = mcs; @@ -3269,6 +3272,7 @@ dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, break; } } + *ratecode = dp_11abgnratetable.info[res].ratecode; done: *rix = res; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h index 8809515d7bb4876027d08261b5c1064d1583468d..b22527a48590d14a58762d8299ed431a6a7b488e 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h @@ -166,7 +166,7 @@ enum DP_CMN_MODULATION_TYPE dp_getmodulation( uint32_t dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, - uint8_t bw, uint32_t *rix); + uint8_t bw, uint32_t *rix, uint16_t *ratecode); int dp_rate_idx_to_kbps(uint8_t rate_idx, uint8_t gintval); diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h index 28834cab8529abf56600c4ac7d971564cd648e15..99ad08adba05585639b168261518958f649e3b22 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,15 +25,15 @@ /** * cdp_bus_suspend() - suspend bus - * @soc - data path soc handle - * @ppdev: data path pdev handle + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle * * suspend bus * * return QDF_STATUS_SUCCESS suspend is not implemented or suspend done */ static inline QDF_STATUS cdp_bus_suspend(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -42,21 +42,21 @@ static inline QDF_STATUS cdp_bus_suspend(ol_txrx_soc_handle soc, } if (soc->ops->bus_ops->bus_suspend) - return soc->ops->bus_ops->bus_suspend(ppdev); + return soc->ops->bus_ops->bus_suspend(soc, pdev_id); return QDF_STATUS_E_NOSUPPORT; } /** * cdp_bus_resume() - resume bus - * @soc - data path soc handle - * @ppdev: data path pdev handle + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle * * resume bus * * return QDF_STATUS_SUCCESS resume is not implemented or suspend done */ static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -65,14 +65,14 @@ static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc, } if (soc->ops->bus_ops->bus_resume) - return soc->ops->bus_ops->bus_resume(ppdev); + return soc->ops->bus_ops->bus_resume(soc, pdev_id); return QDF_STATUS_E_NOSUPPORT; } /** * cdp_process_wow_ack() - Process wow ack response * @soc: data path soc handle - * @ppdev: data path pdev handle + * @pdev_id: id of dp pdev handle * * Do any required data path operations for target wow ack * suspend response. @@ -80,7 +80,7 @@ static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc, * Return: None */ static inline void cdp_process_wow_ack_rsp(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -89,7 +89,7 @@ static inline void cdp_process_wow_ack_rsp(ol_txrx_soc_handle soc, } if (soc->ops->bus_ops->process_wow_ack_rsp) - return soc->ops->bus_ops->process_wow_ack_rsp(soc, ppdev); + return soc->ops->bus_ops->process_wow_ack_rsp(soc, pdev_id); } /** @@ -102,7 +102,7 @@ static inline void cdp_process_wow_ack_rsp(ol_txrx_soc_handle soc, * Return: None */ static inline void cdp_process_target_suspend_req(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -112,6 +112,6 @@ static inline void cdp_process_target_suspend_req(ol_txrx_soc_handle soc, if (soc->ops->bus_ops->process_target_suspend_req) return soc->ops->bus_ops->process_target_suspend_req(soc, - ppdev); + pdev_id); } #endif /* _CDP_TXRX_BUS_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h index e3a624c5624ecae6e5b90b3551715c94a5806307..4c88b815d30fd12aaf97043943db00c987d9627e 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h @@ -112,7 +112,7 @@ static inline struct cdp_cfg /** * cdp_cfg_vdev_rx_set_intrabss_fwd() - enable/disable intra bass forwarding * @soc - data path soc handle - * @vdev - virtual interface instance + * @vdev_id - virtual interface id * @val - enable or disable intra bss forwarding * * ap isolate, do not forward intra bss traffic @@ -121,7 +121,7 @@ static inline struct cdp_cfg */ static inline void cdp_cfg_vdev_rx_set_intrabss_fwd(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, bool val) + uint8_t vdev_id, bool val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -134,7 +134,7 @@ cdp_cfg_vdev_rx_set_intrabss_fwd(ol_txrx_soc_handle soc, !soc->ops->cfg_ops->vdev_rx_set_intrabss_fwd) return; - soc->ops->cfg_ops->vdev_rx_set_intrabss_fwd(vdev, val); + soc->ops->cfg_ops->vdev_rx_set_intrabss_fwd(soc, vdev_id, val); } /** diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h index 4bd8046b0a132b7d283103d37518e05d7e60bfc8..f9b1f601edb0f72f20e59b2b89b919e55d0be581 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -81,6 +81,17 @@ enum verbose_debug_module { #define dp_verbose_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_DP, params) #endif +#define dp_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_DP, params) +#define dp_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_DP, params) +#define dp_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_DP, params) +#define dp_nofl_info(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_DP, params) +#define dp_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_DP, params) + #define dp_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_DP, params) #define dp_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_DP, params) #define dp_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_DP, params) @@ -116,42 +127,8 @@ cdp_soc_attach_target(ol_txrx_soc_handle soc) } -static inline int -cdp_soc_get_nss_cfg(ol_txrx_soc_handle soc) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_soc_get_nss_cfg) - return 0; - - return soc->ops->cmn_drv_ops->txrx_soc_get_nss_cfg(soc); -} - -static inline void -cdp_soc_set_nss_cfg(ol_txrx_soc_handle soc, uint32_t config) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_soc_set_nss_cfg) - return; - - soc->ops->cmn_drv_ops->txrx_soc_set_nss_cfg(soc, config); -} - -static inline struct cdp_vdev * -cdp_vdev_attach(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +static inline QDF_STATUS +cdp_vdev_attach(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t *vdev_mac_addr, uint8_t vdev_id, enum wlan_op_mode op_mode, enum wlan_op_subtype subtype) { @@ -159,30 +136,31 @@ cdp_vdev_attach(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return NULL; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_vdev_attach) - return NULL; + return QDF_STATUS_E_FAILURE; - return soc->ops->cmn_drv_ops->txrx_vdev_attach(pdev, - vdev_mac_addr, vdev_id, op_mode, subtype); + return soc->ops->cmn_drv_ops->txrx_vdev_attach(soc, pdev_id, + vdev_mac_addr, vdev_id, + op_mode, subtype); } -#ifdef CONFIG_MCL +#ifdef DP_FLOW_CTL /** * cdp_flow_pool_map() - Create flow pool for vdev - * @soc - data path soc handle - * @pdev - * @vdev_id - vdev_id corresponding to vdev start + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle + * @vdev_id: vdev_id corresponding to vdev start * * Create per vdev flow pool. * * return none */ static inline QDF_STATUS cdp_flow_pool_map(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t vdev_id) + uint8_t pdev_id, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -195,21 +173,22 @@ static inline QDF_STATUS cdp_flow_pool_map(ol_txrx_soc_handle soc, !soc->ops->flowctl_ops->flow_pool_map_handler) return QDF_STATUS_E_INVAL; - return soc->ops->flowctl_ops->flow_pool_map_handler(soc, pdev, vdev_id); + return soc->ops->flowctl_ops->flow_pool_map_handler(soc, pdev_id, + vdev_id); } /** * cdp_flow_pool_unmap() - Delete flow pool - * @soc - data path soc handle - * @pdev - * @vdev_id - vdev_id corresponding to vdev start + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle + * @vdev_id: vdev_id corresponding to vdev start * * Delete flow pool * * return none */ static inline void cdp_flow_pool_unmap(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t vdev_id) + uint8_t pdev_id, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -222,32 +201,32 @@ static inline void cdp_flow_pool_unmap(ol_txrx_soc_handle soc, !soc->ops->flowctl_ops->flow_pool_unmap_handler) return; - return soc->ops->flowctl_ops->flow_pool_unmap_handler(soc, pdev, + return soc->ops->flowctl_ops->flow_pool_unmap_handler(soc, pdev_id, vdev_id); } #endif -static inline void -cdp_vdev_detach(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - ol_txrx_vdev_delete_cb callback, void *cb_context) +static inline QDF_STATUS +cdp_vdev_detach(ol_txrx_soc_handle soc, uint8_t vdev_id, + ol_txrx_vdev_delete_cb callback, void *cb_context) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_vdev_detach) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_vdev_detach(vdev, - callback, cb_context); + return soc->ops->cmn_drv_ops->txrx_vdev_detach(soc, vdev_id, + callback, cb_context); } static inline int -cdp_pdev_attach_target(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_pdev_attach_target(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -260,30 +239,39 @@ cdp_pdev_attach_target(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) !soc->ops->cmn_drv_ops->txrx_pdev_attach_target) return 0; - return soc->ops->cmn_drv_ops->txrx_pdev_attach_target(pdev); + return soc->ops->cmn_drv_ops->txrx_pdev_attach_target(soc, pdev_id); } -static inline struct cdp_pdev *cdp_pdev_attach - (ol_txrx_soc_handle soc, struct cdp_ctrl_objmgr_pdev *ctrl_pdev, - HTC_HANDLE htc_pdev, qdf_device_t osdev, uint8_t pdev_id) +static inline QDF_STATUS cdp_pdev_attach + (ol_txrx_soc_handle soc, HTC_HANDLE htc_pdev, qdf_device_t osdev, + uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return NULL; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_pdev_attach) - return NULL; + return QDF_STATUS_E_FAILURE; - return soc->ops->cmn_drv_ops->txrx_pdev_attach(soc, ctrl_pdev, - htc_pdev, osdev, pdev_id); + return soc->ops->cmn_drv_ops->txrx_pdev_attach(soc, htc_pdev, osdev, + pdev_id); } -static inline int cdp_pdev_post_attach(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) +/** + * cdp_pdev_post_attach() - attach the data SW state + * @soc: datapath soc handle + * @pdev_id: the data physical device id being removed + * + * This function is used when the WLAN driver is being loaded to + * attach the host data component within the driver. + * + * Return: 0 for success or error code + */ +static inline int cdp_pdev_post_attach(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -296,11 +284,24 @@ static inline int cdp_pdev_post_attach(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->txrx_pdev_post_attach) return 0; - return soc->ops->cmn_drv_ops->txrx_pdev_post_attach(pdev); + return soc->ops->cmn_drv_ops->txrx_pdev_post_attach(soc, pdev_id); } +/** + * cdp_pdev_pre_detach() - detach the data SW state + * @soc: datapath soc handle + * @pdev_id: the data physical device id being removed + * @force: delete the pdev (and its vdevs and peers) even if + * there are outstanding references by the target to the vdevs + * and peers within the pdev + * + * This function is used when the WLAN driver is being removed to + * detach the host data component within the driver. + * + * Return: None + */ static inline void -cdp_pdev_pre_detach(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int force) +cdp_pdev_pre_detach(ol_txrx_soc_handle soc, uint8_t pdev_id, int force) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -313,28 +314,28 @@ cdp_pdev_pre_detach(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int force) !soc->ops->cmn_drv_ops->txrx_pdev_pre_detach) return; - soc->ops->cmn_drv_ops->txrx_pdev_pre_detach(pdev, force); + soc->ops->cmn_drv_ops->txrx_pdev_pre_detach(soc, pdev_id, force); } -static inline void -cdp_pdev_detach(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int force) +static inline QDF_STATUS +cdp_pdev_detach(ol_txrx_soc_handle soc, uint8_t pdev_id, int force) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_pdev_detach) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_pdev_detach(pdev, force); + return soc->ops->cmn_drv_ops->txrx_pdev_detach(soc, pdev_id, force); } static inline void -cdp_pdev_deinit(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int force) +cdp_pdev_deinit(ol_txrx_soc_handle soc, uint8_t pdev_id, int force) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -347,30 +348,30 @@ cdp_pdev_deinit(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int force) !soc->ops->cmn_drv_ops->txrx_pdev_deinit) return; - soc->ops->cmn_drv_ops->txrx_pdev_deinit(pdev, force); + soc->ops->cmn_drv_ops->txrx_pdev_deinit(soc, pdev_id, force); } -static inline void *cdp_peer_create - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - uint8_t *peer_mac_addr, struct cdp_ctrl_objmgr_peer *ctrl_peer) +static inline QDF_STATUS cdp_peer_create + (ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac_addr) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return NULL; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_peer_create) - return NULL; + return QDF_STATUS_E_FAILURE; - return soc->ops->cmn_drv_ops->txrx_peer_create(vdev, - peer_mac_addr, ctrl_peer); + return soc->ops->cmn_drv_ops->txrx_peer_create(soc, vdev_id, + peer_mac_addr); } static inline void cdp_peer_setup - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, void *peer) + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -383,36 +384,36 @@ static inline void cdp_peer_setup !soc->ops->cmn_drv_ops->txrx_peer_setup) return; - soc->ops->cmn_drv_ops->txrx_peer_setup(vdev, - peer); + soc->ops->cmn_drv_ops->txrx_peer_setup(soc, vdev_id, + peer_mac); } /* * cdp_cp_peer_del_response - Call the peer delete response handler * @soc: Datapath SOC handle - * @vdev_hdl: virtual device object + * @vdev_id: id of virtual device object * @peer_mac_addr: Mac address of the peer * * Return: void */ -static inline void cdp_cp_peer_del_response +static inline QDF_STATUS cdp_cp_peer_del_response (ol_txrx_soc_handle soc, - struct cdp_vdev *vdev_hdl, + uint8_t vdev_id, uint8_t *peer_mac_addr) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_cp_peer_del_response) - return; + return QDF_STATUS_E_FAILURE; return soc->ops->cmn_drv_ops->txrx_cp_peer_del_response(soc, - vdev_hdl, + vdev_id, peer_mac_addr); } /** @@ -559,8 +560,9 @@ static inline QDF_STATUS cdp_peer_ast_delete_by_pdev } static inline int cdp_peer_add_ast - (ol_txrx_soc_handle soc, struct cdp_peer *peer_handle, - uint8_t *mac_addr, enum cdp_txrx_ast_entry_type type, uint32_t flags) + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, + uint8_t *mac_addr, + enum cdp_txrx_ast_entry_type type, uint32_t flags) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -574,46 +576,47 @@ static inline int cdp_peer_add_ast return 0; return soc->ops->cmn_drv_ops->txrx_peer_add_ast(soc, - peer_handle, + vdev_id, + peer_mac, mac_addr, type, flags); } -static inline void cdp_peer_reset_ast +static inline QDF_STATUS cdp_peer_reset_ast (ol_txrx_soc_handle soc, uint8_t *wds_macaddr, uint8_t *peer_macaddr, - void *vdev_hdl) + uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_peer_reset_ast) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_peer_reset_ast(soc, wds_macaddr, - peer_macaddr, vdev_hdl); + return soc->ops->cmn_drv_ops->txrx_peer_reset_ast(soc, wds_macaddr, + peer_macaddr, vdev_id); } -static inline void cdp_peer_reset_ast_table - (ol_txrx_soc_handle soc, void *vdev_hdl) +static inline QDF_STATUS cdp_peer_reset_ast_table + (ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_peer_reset_ast_table) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_peer_reset_ast_table(soc, vdev_hdl); + return soc->ops->cmn_drv_ops->txrx_peer_reset_ast_table(soc, vdev_id); } static inline void cdp_peer_flush_ast_table @@ -634,8 +637,8 @@ static inline void cdp_peer_flush_ast_table } static inline int cdp_peer_update_ast - (ol_txrx_soc_handle soc, uint8_t *wds_macaddr, - struct cdp_peer *peer_handle, uint32_t flags) + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, + uint8_t *wds_macaddr, uint32_t flags) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -650,13 +653,14 @@ static inline int cdp_peer_update_ast return soc->ops->cmn_drv_ops->txrx_peer_update_ast(soc, - peer_handle, + vdev_id, + peer_mac, wds_macaddr, flags); } static inline void cdp_peer_teardown - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, void *peer) + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -669,29 +673,12 @@ static inline void cdp_peer_teardown !soc->ops->cmn_drv_ops->txrx_peer_teardown) return; - soc->ops->cmn_drv_ops->txrx_peer_teardown(vdev, peer); -} - -static inline void -cdp_vdev_flush_peers(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - bool unmap_only) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_vdev_flush_peers) - return; - - soc->ops->cmn_drv_ops->txrx_vdev_flush_peers(vdev, unmap_only); + soc->ops->cmn_drv_ops->txrx_peer_teardown(soc, vdev_id, peer_mac); } static inline void -cdp_peer_delete(ol_txrx_soc_handle soc, void *peer, uint32_t bitmap) +cdp_peer_delete(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, uint32_t bitmap) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -704,11 +691,21 @@ cdp_peer_delete(ol_txrx_soc_handle soc, void *peer, uint32_t bitmap) !soc->ops->cmn_drv_ops->txrx_peer_delete) return; - soc->ops->cmn_drv_ops->txrx_peer_delete(peer, bitmap); + soc->ops->cmn_drv_ops->txrx_peer_delete(soc, vdev_id, peer_mac, bitmap); } +/** + * cdp_peer_detach_sync() - peer detach sync callback + * @soc: datapath soc handle + * @vdev_id: virtual device/interface id + * @peer_mac: peer mac address + * @peer_unmap_sync: peer unmap sync cb. + * @bitmap: bitmap indicating special handling of request. + * + * Return: None + */ static inline void -cdp_peer_delete_sync(ol_txrx_soc_handle soc, void *peer, +cdp_peer_delete_sync(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, QDF_STATUS(*delete_cb)( uint8_t vdev_id, uint32_t peerid_cnt, @@ -726,14 +723,14 @@ cdp_peer_delete_sync(ol_txrx_soc_handle soc, void *peer, !soc->ops->cmn_drv_ops->txrx_peer_delete_sync) return; - soc->ops->cmn_drv_ops->txrx_peer_delete_sync(peer, + soc->ops->cmn_drv_ops->txrx_peer_delete_sync(soc, vdev_id, peer_mac, delete_cb, bitmap); } static inline int -cdp_set_monitor_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - uint8_t smart_monitor) +cdp_set_monitor_mode(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t smart_monitor) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -746,55 +743,56 @@ cdp_set_monitor_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->cmn_drv_ops->txrx_set_monitor_mode) return 0; - return soc->ops->cmn_drv_ops->txrx_set_monitor_mode(vdev, + return soc->ops->cmn_drv_ops->txrx_set_monitor_mode(soc, vdev_id, smart_monitor); } -static inline void +static inline QDF_STATUS cdp_set_curchan(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, uint32_t chan_mhz) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_set_curchan) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_set_curchan(pdev, chan_mhz); + return soc->ops->cmn_drv_ops->txrx_set_curchan(soc, pdev_id, chan_mhz); } -static inline void -cdp_set_privacy_filters(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - void *filter, uint32_t num) +static inline QDF_STATUS +cdp_set_privacy_filters(ol_txrx_soc_handle soc, uint8_t vdev_id, + void *filter, uint32_t num) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_set_privacy_filters) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_set_privacy_filters(vdev, + return soc->ops->cmn_drv_ops->txrx_set_privacy_filters(soc, vdev_id, filter, num); } static inline int -cdp_set_monitor_filter(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - struct cdp_monitor_filter *filter_val) +cdp_set_monitor_filter(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct cdp_monitor_filter *filter_val) { if (soc->ops->mon_ops->txrx_set_advance_monitor_filter) - return soc->ops->mon_ops->txrx_set_advance_monitor_filter(pdev, - filter_val); + return soc->ops->mon_ops->txrx_set_advance_monitor_filter(soc, + pdev_id, + filter_val); return 0; } @@ -803,9 +801,9 @@ cdp_set_monitor_filter(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, * Data Interface (B Interface) *****************************************************************************/ static inline void -cdp_vdev_register(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - void *osif_vdev, struct cdp_ctrl_objmgr_vdev *ctrl_vdev, - struct ol_txrx_ops *txrx_ops) +cdp_vdev_register(ol_txrx_soc_handle soc, uint8_t vdev_id, + ol_osif_vdev_handle osif_vdev, + struct ol_txrx_ops *txrx_ops) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -818,13 +816,13 @@ cdp_vdev_register(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->cmn_drv_ops->txrx_vdev_register) return; - soc->ops->cmn_drv_ops->txrx_vdev_register(vdev, - osif_vdev, ctrl_vdev, txrx_ops); + soc->ops->cmn_drv_ops->txrx_vdev_register(soc, vdev_id, + osif_vdev, txrx_ops); } static inline int -cdp_mgmt_send(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - qdf_nbuf_t tx_mgmt_frm, uint8_t type) +cdp_mgmt_send(ol_txrx_soc_handle soc, uint8_t vdev_id, + qdf_nbuf_t tx_mgmt_frm, uint8_t type) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -837,14 +835,14 @@ cdp_mgmt_send(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->cmn_drv_ops->txrx_mgmt_send) return 0; - return soc->ops->cmn_drv_ops->txrx_mgmt_send(vdev, + return soc->ops->cmn_drv_ops->txrx_mgmt_send(soc, vdev_id, tx_mgmt_frm, type); } static inline int -cdp_mgmt_send_ext(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - qdf_nbuf_t tx_mgmt_frm, uint8_t type, - uint8_t use_6mbps, uint16_t chanfreq) +cdp_mgmt_send_ext(ol_txrx_soc_handle soc, uint8_t vdev_id, + qdf_nbuf_t tx_mgmt_frm, uint8_t type, + uint8_t use_6mbps, uint16_t chanfreq) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -858,12 +856,12 @@ cdp_mgmt_send_ext(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, return 0; return soc->ops->cmn_drv_ops->txrx_mgmt_send_ext - (vdev, tx_mgmt_frm, type, use_6mbps, chanfreq); + (soc, vdev_id, tx_mgmt_frm, type, use_6mbps, chanfreq); } -static inline void -cdp_mgmt_tx_cb_set(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +static inline QDF_STATUS +cdp_mgmt_tx_cb_set(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t type, ol_txrx_mgmt_tx_cb download_cb, ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt) { @@ -871,20 +869,28 @@ cdp_mgmt_tx_cb_set(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_mgmt_tx_cb_set) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_mgmt_tx_cb_set - (pdev, type, download_cb, ota_ack_cb, ctxt); + return soc->ops->cmn_drv_ops->txrx_mgmt_tx_cb_set + (soc, pdev_id, type, download_cb, ota_ack_cb, ctxt); } +/** + * cdp_peer_unmap_sync_cb_set() - set peer unmap sync callback + * @soc: datapath soc handle + * @pdev_id: physical device instance id + * @peer_unmap_sync: peer unmap sync callback + * + * Return: None + */ static inline void cdp_peer_unmap_sync_cb_set(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, QDF_STATUS(*unmap_resp_cb)( uint8_t vdev_id, uint32_t peerid_cnt, @@ -901,30 +907,21 @@ cdp_peer_unmap_sync_cb_set(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->txrx_peer_unmap_sync_cb_set) return; - soc->ops->cmn_drv_ops->txrx_peer_unmap_sync_cb_set(pdev, unmap_resp_cb); -} - -static inline int cdp_get_tx_pending(ol_txrx_soc_handle soc, -struct cdp_pdev *pdev) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_get_tx_pending) - return 0; - - - return soc->ops->cmn_drv_ops->txrx_get_tx_pending(pdev); + soc->ops->cmn_drv_ops->txrx_peer_unmap_sync_cb_set(soc, pdev_id, + unmap_resp_cb); } +/* + * cdp_data_tx_cb_set(): set the callback for non standard tx + * @soc - datapath soc handle + * @vdev_id - virtual device/interface id + * @callback - callback function + * @ctxt: callback context + * + */ static inline void -cdp_data_tx_cb_set(ol_txrx_soc_handle soc, struct cdp_vdev *data_vdev, - ol_txrx_data_tx_cb callback, void *ctxt) +cdp_data_tx_cb_set(ol_txrx_soc_handle soc, uint8_t vdev_id, + ol_txrx_data_tx_cb callback, void *ctxt) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -937,8 +934,8 @@ cdp_data_tx_cb_set(ol_txrx_soc_handle soc, struct cdp_vdev *data_vdev, !soc->ops->cmn_drv_ops->txrx_data_tx_cb_set) return; - soc->ops->cmn_drv_ops->txrx_data_tx_cb_set(data_vdev, - callback, ctxt); + soc->ops->cmn_drv_ops->txrx_data_tx_cb_set(soc, vdev_id, + callback, ctxt); } /****************************************************************************** @@ -963,9 +960,9 @@ typedef uint32_t target_paddr_t; #endif /*HTT_PADDR64 */ static inline int -cdp_aggr_cfg(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - int max_subfrms_ampdu, - int max_subfrms_amsdu) +cdp_aggr_cfg(ol_txrx_soc_handle soc, uint8_t vdev_id, + int max_subfrms_ampdu, + int max_subfrms_amsdu) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -978,14 +975,14 @@ cdp_aggr_cfg(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->cmn_drv_ops->txrx_aggr_cfg) return 0; - return soc->ops->cmn_drv_ops->txrx_aggr_cfg(vdev, + return soc->ops->cmn_drv_ops->txrx_aggr_cfg(soc, vdev_id, max_subfrms_ampdu, max_subfrms_amsdu); } static inline int -cdp_fw_stats_get(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, bool per_vdev, - bool response_expected) +cdp_fw_stats_get(ol_txrx_soc_handle soc, uint8_t vdev_id, + struct ol_txrx_stats_req *req, bool per_vdev, + bool response_expected) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -998,12 +995,12 @@ cdp_fw_stats_get(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->cmn_drv_ops->txrx_fw_stats_get) return 0; - return soc->ops->cmn_drv_ops->txrx_fw_stats_get(vdev, req, + return soc->ops->cmn_drv_ops->txrx_fw_stats_get(soc, vdev_id, req, per_vdev, response_expected); } static inline int -cdp_debug(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, int debug_specs) +cdp_debug(ol_txrx_soc_handle soc, uint8_t vdev_id, int debug_specs) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1016,25 +1013,26 @@ cdp_debug(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, int debug_specs) !soc->ops->cmn_drv_ops->txrx_debug) return 0; - return soc->ops->cmn_drv_ops->txrx_debug(vdev, debug_specs); + return soc->ops->cmn_drv_ops->txrx_debug(soc, vdev_id, debug_specs); } -static inline void cdp_fw_stats_cfg(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint8_t cfg_stats_type, uint32_t cfg_val) +static inline QDF_STATUS +cdp_fw_stats_cfg(ol_txrx_soc_handle soc, + uint8_t vdev_id, uint8_t cfg_stats_type, uint32_t cfg_val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_fw_stats_cfg) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_fw_stats_cfg(vdev, - cfg_stats_type, cfg_val); + return soc->ops->cmn_drv_ops->txrx_fw_stats_cfg(soc, vdev_id, + cfg_stats_type, cfg_val); } static inline void cdp_print_level_set(ol_txrx_soc_handle soc, unsigned level) @@ -1053,58 +1051,16 @@ static inline void cdp_print_level_set(ol_txrx_soc_handle soc, unsigned level) soc->ops->cmn_drv_ops->txrx_print_level_set(level); } -static inline uint8_t * -cdp_get_vdev_mac_addr(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return NULL; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_get_vdev_mac_addr) - return NULL; - - return soc->ops->cmn_drv_ops->txrx_get_vdev_mac_addr(vdev); - -} - -/** - * cdp_get_vdev_struct_mac_addr() - Return handle to struct qdf_mac_addr of - * vdev - * @vdev: vdev handle +/* + * cdp_get_vdev_mac_addr() – Detach txrx peer + * @soc_hdl: Datapath soc handle + * @vdev_id: virtual device/interface id * - * Return: Handle to struct qdf_mac_addr - */ -static inline struct qdf_mac_addr *cdp_get_vdev_struct_mac_addr - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return NULL; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_get_vdev_struct_mac_addr) - return NULL; - - return soc->ops->cmn_drv_ops->txrx_get_vdev_struct_mac_addr - (vdev); - -} - -/** - * cdp_get_pdev_from_vdev() - Return handle to pdev of vdev - * @vdev: vdev handle + * Return: MAC address on success, NULL on failure. * - * Return: Handle to pdev */ -static inline struct cdp_pdev *cdp_get_pdev_from_vdev - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline uint8_t * +cdp_get_vdev_mac_addr(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1114,16 +1070,17 @@ static inline struct cdp_pdev *cdp_get_pdev_from_vdev } if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_get_pdev_from_vdev) + !soc->ops->cmn_drv_ops->txrx_get_vdev_mac_addr) return NULL; - return soc->ops->cmn_drv_ops->txrx_get_pdev_from_vdev(vdev); + return soc->ops->cmn_drv_ops->txrx_get_vdev_mac_addr(soc, vdev_id); + } /** * cdp_get_os_rx_handles_from_vdev() - Return os rx handles for a vdev * @soc: ol_txrx_soc_handle handle - * @vdev: vdev for which os rx handles are needed + * @vdev_id: vdev id for which os rx handles are needed * @stack_fn_p: pointer to stack function pointer * @osif_handle_p: pointer to ol_osif_vdev_handle * @@ -1131,7 +1088,7 @@ static inline struct cdp_pdev *cdp_get_pdev_from_vdev */ static inline void cdp_get_os_rx_handles_from_vdev(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, ol_txrx_rx_fp *stack_fn_p, ol_osif_vdev_handle *osif_handle_p) { @@ -1146,19 +1103,20 @@ void cdp_get_os_rx_handles_from_vdev(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->txrx_get_os_rx_handles_from_vdev) return; - soc->ops->cmn_drv_ops->txrx_get_os_rx_handles_from_vdev(vdev, + soc->ops->cmn_drv_ops->txrx_get_os_rx_handles_from_vdev(soc, vdev_id, stack_fn_p, osif_handle_p); } /** * cdp_get_ctrl_pdev_from_vdev() - Return control pdev of vdev - * @vdev: vdev handle + * @soc: datapath soc handle + * @vdev_id: virtual device/interface id * * Return: Handle to control pdev */ static inline struct cdp_cfg * -cdp_get_ctrl_pdev_from_vdev(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +cdp_get_ctrl_pdev_from_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1171,45 +1129,32 @@ cdp_get_ctrl_pdev_from_vdev(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) !soc->ops->cmn_drv_ops->txrx_get_ctrl_pdev_from_vdev) return NULL; - return soc->ops->cmn_drv_ops->txrx_get_ctrl_pdev_from_vdev - (vdev); -} - -static inline struct cdp_vdev * -cdp_get_vdev_from_vdev_id(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t vdev_id) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return NULL; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->txrx_get_vdev_from_vdev_id) - return NULL; - - return soc->ops->cmn_drv_ops->txrx_get_vdev_from_vdev_id - (pdev, vdev_id); + return soc->ops->cmn_drv_ops->txrx_get_ctrl_pdev_from_vdev(soc, + vdev_id); } -static inline struct cdp_vdev * -cdp_get_mon_vdev_from_pdev(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +/* + * cdp_get_mon_vdev_from_pdev() - Get vdev handle of monitor mode + * @soc: datapath soc handle + * @pdev_id: physical device instance id + * + * Return: virtual interface id + */ +static inline uint8_t +cdp_get_mon_vdev_from_pdev(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return NULL; + return -EINVAL; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev) - return NULL; + return -EINVAL; - return soc->ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev - (pdev); + return soc->ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev(soc, pdev_id); } static inline void @@ -1226,7 +1171,7 @@ cdp_soc_detach(ol_txrx_soc_handle soc) !soc->ops->cmn_drv_ops->txrx_soc_detach) return; - soc->ops->cmn_drv_ops->txrx_soc_detach((void *)soc); + soc->ops->cmn_drv_ops->txrx_soc_detach(soc); } /** @@ -1242,8 +1187,10 @@ cdp_soc_detach(ol_txrx_soc_handle soc) * Return: DP SOC handle on success, NULL on failure */ static inline ol_txrx_soc_handle -cdp_soc_init(ol_txrx_soc_handle soc, u_int16_t devid, void *hif_handle, - void *psoc, void *htc_handle, qdf_device_t qdf_dev, +cdp_soc_init(ol_txrx_soc_handle soc, u_int16_t devid, + void *hif_handle, + struct cdp_ctrl_objmgr_psoc *psoc, + HTC_HANDLE htc_handle, qdf_device_t qdf_dev, struct ol_if_ops *dp_ol_if_ops) { if (!soc || !soc->ops) { @@ -1283,7 +1230,7 @@ cdp_soc_deinit(ol_txrx_soc_handle soc) !soc->ops->cmn_drv_ops->txrx_soc_deinit) return; - soc->ops->cmn_drv_ops->txrx_soc_deinit((void *)soc); + soc->ops->cmn_drv_ops->txrx_soc_deinit(soc); } /** @@ -1309,7 +1256,7 @@ cdp_tso_soc_attach(ol_txrx_soc_handle soc) !soc->ops->cmn_drv_ops->txrx_tso_soc_attach) return 0; - return soc->ops->cmn_drv_ops->txrx_tso_soc_attach((void *)soc); + return soc->ops->cmn_drv_ops->txrx_tso_soc_attach(soc); } /** @@ -1335,21 +1282,23 @@ cdp_tso_soc_detach(ol_txrx_soc_handle soc) !soc->ops->cmn_drv_ops->txrx_tso_soc_detach) return 0; - return soc->ops->cmn_drv_ops->txrx_tso_soc_detach((void *)soc); + return soc->ops->cmn_drv_ops->txrx_tso_soc_detach(soc); } /** * cdp_addba_resp_tx_completion() - Indicate addba response tx * completion to dp to change tid state. * @soc: soc handle - * @peer_handle: peer handle + * @peer_mac: mac address of peer handle + * @vdev_id: id of vdev handle * @tid: tid * @status: Tx completion status * * Return: success/failure of tid update */ static inline int cdp_addba_resp_tx_completion(ol_txrx_soc_handle soc, - void *peer_handle, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status) { if (!soc || !soc->ops) { @@ -1363,12 +1312,12 @@ static inline int cdp_addba_resp_tx_completion(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->addba_resp_tx_completion) return 0; - return soc->ops->cmn_drv_ops->addba_resp_tx_completion(peer_handle, tid, - status); + return soc->ops->cmn_drv_ops->addba_resp_tx_completion(soc, peer_mac, + vdev_id, tid, status); } static inline int cdp_addba_requestprocess(ol_txrx_soc_handle soc, - void *peer_handle, uint8_t dialogtoken, uint16_t tid, + uint8_t *peer_mac, uint16_t vdev_id, uint8_t dialogtoken, uint16_t tid, uint16_t batimeout, uint16_t buffersize, uint16_t startseqnum) { if (!soc || !soc->ops) { @@ -1382,31 +1331,37 @@ static inline int cdp_addba_requestprocess(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->addba_requestprocess) return 0; - return soc->ops->cmn_drv_ops->addba_requestprocess(peer_handle, - dialogtoken, tid, batimeout, buffersize, startseqnum); + return soc->ops->cmn_drv_ops->addba_requestprocess(soc, peer_mac, + vdev_id, dialogtoken, tid, batimeout, buffersize, + startseqnum); } -static inline void cdp_addba_responsesetup(ol_txrx_soc_handle soc, - void *peer_handle, uint8_t tid, uint8_t *dialogtoken, - uint16_t *statuscode, uint16_t *buffersize, uint16_t *batimeout) +static inline QDF_STATUS +cdp_addba_responsesetup(ol_txrx_soc_handle soc, + uint8_t *peer_mac, uint16_t vdev_id, + uint8_t tid, uint8_t *dialogtoken, + uint16_t *statuscode, uint16_t *buffersize, + uint16_t *batimeout) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->addba_responsesetup) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->addba_responsesetup(peer_handle, tid, - dialogtoken, statuscode, buffersize, batimeout); + return soc->ops->cmn_drv_ops->addba_responsesetup(soc, peer_mac, + vdev_id, tid, dialogtoken, statuscode, buffersize, + batimeout); } -static inline int cdp_delba_process(ol_txrx_soc_handle soc, - void *peer_handle, int tid, uint16_t reasoncode) +static inline int cdp_delba_process(ol_txrx_soc_handle soc, uint8_t *peer_mac, + uint16_t vdev_id, int tid, + uint16_t reasoncode) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1419,15 +1374,16 @@ static inline int cdp_delba_process(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->delba_process) return 0; - return soc->ops->cmn_drv_ops->delba_process(peer_handle, - tid, reasoncode); + return soc->ops->cmn_drv_ops->delba_process(soc, peer_mac, + vdev_id, tid, reasoncode); } /** * cdp_delba_tx_completion() - Handle delba tx completion * to update stats and retry transmission if failed. * @soc: soc handle - * @peer_handle: peer handle + * @peer_mac: peer mac address + * @vdev_id: id of vdev handle * @tid: Tid number * @status: Tx completion status * @@ -1435,7 +1391,8 @@ static inline int cdp_delba_process(ol_txrx_soc_handle soc, */ static inline int cdp_delba_tx_completion(ol_txrx_soc_handle soc, - void *peer_handle, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status) { if (!soc || !soc->ops) { @@ -1449,90 +1406,97 @@ static inline int cdp_delba_tx_completion(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->delba_tx_completion) return 0; - return soc->ops->cmn_drv_ops->delba_tx_completion(peer_handle, + return soc->ops->cmn_drv_ops->delba_tx_completion(soc, peer_mac, + vdev_id, tid, status); } -static inline void cdp_set_addbaresponse(ol_txrx_soc_handle soc, - void *peer_handle, int tid, uint16_t statuscode) +static inline QDF_STATUS +cdp_set_addbaresponse(ol_txrx_soc_handle soc, + uint8_t *peer_mac, uint16_t vdev_id, int tid, + uint16_t statuscode) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->set_addba_response) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->set_addba_response(peer_handle, tid, statuscode); + return soc->ops->cmn_drv_ops->set_addba_response(soc, peer_mac, vdev_id, + tid, statuscode); } /** - * cdp_get_peer_mac_addr_frm_id: function to return vdev id and and peer - * mac address - * @soc: SOC handle - * @peer_id: peer id of the peer for which mac_address is required - * @mac_addr: reference to mac address + * cdp_set_vdev_dscp_tid_map(): function to set DSCP-tid map in the vap + * @soc : soc handle + * @vdev_id: id of vdev handle + * @map_id: id of the tid map * - * reutm: vdev_id of the vap + * Return: QDF_STATUS */ -static inline uint8_t -cdp_get_peer_mac_addr_frm_id(ol_txrx_soc_handle soc, uint16_t peer_id, - uint8_t *mac_addr) +static inline QDF_STATUS +cdp_set_vdev_dscp_tid_map(ol_txrx_soc_handle soc, + uint8_t vdev_id, uint8_t map_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return CDP_INVALID_VDEV_ID; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->get_peer_mac_addr_frm_id) - return CDP_INVALID_VDEV_ID; + !soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map) + return QDF_STATUS_E_FAILURE; - return soc->ops->cmn_drv_ops->get_peer_mac_addr_frm_id(soc, - peer_id, mac_addr); + return soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map(soc, vdev_id, + map_id); } +#ifdef QCA_MULTIPASS_SUPPORT /** - * cdp_set_vdev_dscp_tid_map(): function to set DSCP-tid map in the vap - * @vdev: vdev handle - * @map_id: id of the tid map + * cdp_set_vlan_groupkey(): function to set vlan ID - group key map in the vap + * @soc : soc handle + * @vdev_id: id of vdev handle + * @vlan_id: vlan id + * @group_key: corresponding group key to vlan ID * * Return: void */ -static inline void cdp_set_vdev_dscp_tid_map(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint8_t map_id) +static inline +QDF_STATUS cdp_set_vlan_groupkey(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint16_t vlan_id, uint16_t group_key) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return 0; } if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map) - return; + !soc->ops->cmn_drv_ops->set_vlan_groupkey) + return 0; - soc->ops->cmn_drv_ops->set_vdev_dscp_tid_map(vdev, - map_id); + return soc->ops->cmn_drv_ops->set_vlan_groupkey(soc, vdev_id, vlan_id, + group_key); } +#endif /** * cdp_ath_get_total_per(): function to get hw retries * @soc : soc handle - * @pdev: pdev handle + * @pdev_id: id of pdev handle * * Return: get hw retries */ static inline -int cdp_ath_get_total_per(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) +int cdp_ath_get_total_per(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1545,12 +1509,12 @@ int cdp_ath_get_total_per(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->txrx_get_total_per) return 0; - return soc->ops->cmn_drv_ops->txrx_get_total_per(pdev); + return soc->ops->cmn_drv_ops->txrx_get_total_per(soc, pdev_id); } /** * cdp_set_pdev_dscp_tid_map(): function to change tid values in DSCP-tid map - * @pdev: pdev handle + * @pdev_id: id of pdev handle * @map_id: id of the tid map * @tos: index value in map that needs to be changed * @tid: tid value passed by user @@ -1558,7 +1522,7 @@ int cdp_ath_get_total_per(ol_txrx_soc_handle soc, * Return: void */ static inline void cdp_set_pdev_dscp_tid_map(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t map_id, uint8_t tos, uint8_t tid) + uint8_t pdev_id, uint8_t map_id, uint8_t tos, uint8_t tid) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1571,60 +1535,10 @@ static inline void cdp_set_pdev_dscp_tid_map(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->set_pdev_dscp_tid_map) return; - soc->ops->cmn_drv_ops->set_pdev_dscp_tid_map(pdev, + soc->ops->cmn_drv_ops->set_pdev_dscp_tid_map(soc, pdev_id, map_id, tos, tid); } -/** - * cdp_hmmc_tid_override_en(): Function to enable hmmc tid override. - * @soc : soc handle - * @pdev: pdev handle - * @val: hmmc-dscp flag value - * - * Return: void - */ -static inline void cdp_hmmc_tid_override_en(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, bool val) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->hmmc_tid_override_en) - return; - - soc->ops->cmn_drv_ops->hmmc_tid_override_en(pdev, val); -} - -/** - * cdp_set_hmmc_tid_val(): Function to set hmmc tid value. - * @soc : soc handle - * @pdev: pdev handle - * @tid: tid value - * - * Return: void - */ -static inline void cdp_set_hmmc_tid_val(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t tid) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->set_hmmc_tid_val) - return; - - soc->ops->cmn_drv_ops->set_hmmc_tid_val(pdev, tid); -} - /** * cdp_flush_cache_rx_queue() - flush cache rx queue frame * @@ -1648,14 +1562,14 @@ static inline void cdp_flush_cache_rx_queue(ol_txrx_soc_handle soc) /** * cdp_txrx_stats_request(): function to map to host and firmware statistics * @soc: soc handle - * @vdev: virtual device + * @vdev_id: virtual device ID * @req: stats request container * * return: status */ static inline -int cdp_txrx_stats_request(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - struct cdp_txrx_stats_req *req) +int cdp_txrx_stats_request(ol_txrx_soc_handle soc, uint8_t vdev_id, + struct cdp_txrx_stats_req *req) { if (!soc || !soc->ops || !soc->ops->cmn_drv_ops || !req) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1665,7 +1579,8 @@ int cdp_txrx_stats_request(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, } if (soc->ops->cmn_drv_ops->txrx_stats_request) - return soc->ops->cmn_drv_ops->txrx_stats_request(vdev, req); + return soc->ops->cmn_drv_ops->txrx_stats_request(soc, vdev_id, + req); return 0; } @@ -1737,11 +1652,14 @@ cdp_display_stats(ol_txrx_soc_handle soc, uint16_t value, /** * cdp_set_pn_check(): function to set pn check * @soc: soc handle + * @vdev_id: id of virtual device + * @peer_mac: mac address of peer * @sec_type: security type - * #rx_pn: receive pn + * @rx_pn: receive pn */ static inline int cdp_set_pn_check(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, struct cdp_peer *peer_handle, enum cdp_sec_type sec_type, uint32_t *rx_pn) + uint8_t vdev_id, uint8_t *peer_mac, + enum cdp_sec_type sec_type, uint32_t *rx_pn) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1754,26 +1672,28 @@ static inline int cdp_set_pn_check(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->set_pn_check) return 0; - soc->ops->cmn_drv_ops->set_pn_check(vdev, peer_handle, + soc->ops->cmn_drv_ops->set_pn_check(soc, vdev_id, peer_mac, sec_type, rx_pn); return 0; } /** - * cdp_set_key_sec_type(): function to set pn check + * cdp_set_key_sec_type(): function to set sec mode of key * @soc: soc handle + * @vdev_id: id of virtual device + * @peer_mac: mac address of peer * @sec_type: security type * #is_unicast: ucast or mcast */ static inline int cdp_set_key_sec_type(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, - struct cdp_peer *peer_handle, + uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, bool is_unicast) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); return 0; } @@ -1782,29 +1702,30 @@ static inline int cdp_set_key_sec_type(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->set_key_sec_type) return 0; - soc->ops->cmn_drv_ops->set_key_sec_type(vdev, peer_handle, - sec_type, is_unicast); + soc->ops->cmn_drv_ops->set_key_sec_type(soc, vdev_id, + peer_mac, sec_type, is_unicast); return 0; } -static inline int cdp_set_key(ol_txrx_soc_handle soc, - struct cdp_peer *peer_handle, - bool is_unicast, uint32_t *key) +static inline QDF_STATUS +cdp_set_key(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac, + bool is_unicast, uint32_t *key) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return 0; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || !soc->ops->ctrl_ops->set_key) - return 0; + return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->set_key(peer_handle, + return soc->ops->ctrl_ops->set_key(soc, vdev_id, mac, is_unicast, key); - return 0; } /** @@ -1839,12 +1760,12 @@ QDF_STATUS cdp_update_config_parameters(ol_txrx_soc_handle soc, /** * cdp_pdev_get_dp_txrx_handle() - get advanced dp handle from pdev * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * * Return: opaque dp handle */ static inline void * -cdp_pdev_get_dp_txrx_handle(ol_txrx_soc_handle soc, void *pdev) +cdp_pdev_get_dp_txrx_handle(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1854,7 +1775,7 @@ cdp_pdev_get_dp_txrx_handle(ol_txrx_soc_handle soc, void *pdev) } if (soc->ops->cmn_drv_ops->get_dp_txrx_handle) - return soc->ops->cmn_drv_ops->get_dp_txrx_handle(pdev); + return soc->ops->cmn_drv_ops->get_dp_txrx_handle(soc, pdev_id); return 0; } @@ -1862,13 +1783,14 @@ cdp_pdev_get_dp_txrx_handle(ol_txrx_soc_handle soc, void *pdev) /** * cdp_pdev_set_dp_txrx_handle() - set advanced dp handle in pdev * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * @dp_hdl: opaque pointer for dp_txrx_handle * * Return: void */ static inline void -cdp_pdev_set_dp_txrx_handle(ol_txrx_soc_handle soc, void *pdev, void *dp_hdl) +cdp_pdev_set_dp_txrx_handle(ol_txrx_soc_handle soc, uint8_t pdev_id, + void *dp_hdl) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1881,7 +1803,59 @@ cdp_pdev_set_dp_txrx_handle(ol_txrx_soc_handle soc, void *pdev, void *dp_hdl) !soc->ops->cmn_drv_ops->set_dp_txrx_handle) return; - soc->ops->cmn_drv_ops->set_dp_txrx_handle(pdev, dp_hdl); + soc->ops->cmn_drv_ops->set_dp_txrx_handle(soc, pdev_id, dp_hdl); +} + +/** + * cdp_vdev_get_dp_ext_txrx_handle() - get extended dp handle from vdev + * @soc: opaque soc handle + * @vdev_id: vdev id + * + * Return: opaque dp handle + */ +static inline void * +cdp_vdev_get_dp_ext_txrx_handle(ol_txrx_soc_handle soc, uint8_t vdev_id) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return 0; + } + + if (soc->ops->cmn_drv_ops->get_vdev_dp_ext_txrx_handle) + return soc->ops->cmn_drv_ops->get_vdev_dp_ext_txrx_handle( + soc, vdev_id); + + return 0; +} + +/** + * cdp_vdev_set_dp_ext_txrx_handle() - set extended dp handle in vdev + * @soc: opaque soc handle + * @vdev_id: vdev id + * @size: size of the advance dp handle + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_vdev_set_dp_ext_txrx_handle(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint16_t size) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_vdev_dp_ext_txrx_handle) + return QDF_STATUS_E_FAILURE; + + return soc->ops->cmn_drv_ops->set_vdev_dp_ext_txrx_handle(soc, + vdev_id, + size); } /* @@ -1932,37 +1906,90 @@ cdp_soc_set_dp_txrx_handle(ol_txrx_soc_handle soc, void *dp_handle) dp_handle); } +/** + * cdp_soc_handle_mode_change() - Update pdev_id to lmac_id mapping + * @soc: opaque soc handle + * @pdev_id: id of data path pdev handle + * @lmac_id: lmac id + * Return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_soc_handle_mode_change(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint32_t lmac_id) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->map_pdev_to_lmac) + return QDF_STATUS_E_FAILURE; + + return soc->ops->cmn_drv_ops->handle_mode_change(soc, pdev_id, + lmac_id); +} + /** * cdp_soc_map_pdev_to_lmac() - Save pdev_id to lmac_id mapping * @soc: opaque soc handle - * @pdev_handle: data path pdev handle + * @pdev_id: id of data path pdev handle * @lmac_id: lmac id - * - * Return: void + * Return: QDF_STATUS */ -static inline void -cdp_soc_map_pdev_to_lmac(ol_txrx_soc_handle soc, void *pdev_handle, +static inline QDF_STATUS +cdp_soc_map_pdev_to_lmac(ol_txrx_soc_handle soc, uint8_t pdev_id, uint32_t lmac_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->map_pdev_to_lmac) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->map_pdev_to_lmac((struct cdp_pdev *)pdev_handle, + return soc->ops->cmn_drv_ops->map_pdev_to_lmac(soc, pdev_id, lmac_id); } +/** + * cdp_txrx_set_pdev_status_down() - set pdev down/up status + * @soc: soc opaque handle + * @pdev_id: id of data path pdev handle + * @is_pdev_down: pdev down/up status + * + * return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_txrx_set_pdev_status_down(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool is_pdev_down) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_pdev_status_down) + return QDF_STATUS_E_FAILURE; + + return soc->ops->cmn_drv_ops->set_pdev_status_down(soc, pdev_id, + is_pdev_down); +} + /** * cdp_tx_send() - enqueue frame for transmission * @soc: soc opaque handle - * @vdev: VAP device + * @vdev_id: id of VAP device * @nbuf: nbuf to be enqueued * * This API is used by Extended Datapath modules to enqueue frame for @@ -1971,7 +1998,7 @@ cdp_soc_map_pdev_to_lmac(ol_txrx_soc_handle soc, void *pdev_handle, * Return: void */ static inline void -cdp_tx_send(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, qdf_nbuf_t nbuf) +cdp_tx_send(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t nbuf) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -1984,96 +2011,13 @@ cdp_tx_send(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, qdf_nbuf_t nbuf) !soc->ops->cmn_drv_ops->tx_send) return; - soc->ops->cmn_drv_ops->tx_send(vdev, nbuf); -} - -/* - * cdp_get_pdev_id_frm_pdev() - return pdev_id from pdev - * @soc: opaque soc handle - * @pdev: data path pdev handle - * - * Return: pdev_id - */ -static inline -uint8_t cdp_get_pdev_id_frm_pdev(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) -{ - if (soc->ops->cmn_drv_ops->txrx_get_pdev_id_frm_pdev) - return soc->ops->cmn_drv_ops->txrx_get_pdev_id_frm_pdev(pdev); - return 0; -} - -/* - * cdp_get_vow_config_frm_pdev() - return carrier_vow_config from pdev - * @soc: opaque soc handle - * @pdev: data path pdev handle - * - * Return: carrier_vow_config - */ -static inline -bool cdp_get_vow_config_frm_pdev(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) -{ - if (soc->ops->cmn_drv_ops->txrx_get_vow_config_frm_pdev) - return soc->ops->cmn_drv_ops->txrx_get_vow_config_frm_pdev( - pdev); - return 0; -} - -/** - * cdp_pdev_set_chan_noise_floor() - Set channel noise floor to DP layer - * @soc: opaque soc handle - * @pdev: data path pdev handle - * @chan_noise_floor: Channel Noise Floor (in dbM) obtained from control path - * - * Return: None - */ -static inline -void cdp_pdev_set_chan_noise_floor(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, - int16_t chan_noise_floor) -{ - if (soc->ops->cmn_drv_ops->txrx_pdev_set_chan_noise_floor) - return soc->ops->cmn_drv_ops->txrx_pdev_set_chan_noise_floor( - pdev, chan_noise_floor); -} - -/** - * cdp_set_nac() - set nac - * @soc: opaque soc handle - * @peer: data path peer handle - * - */ -static inline -void cdp_set_nac(ol_txrx_soc_handle soc, - struct cdp_peer *peer) -{ - if (soc->ops->cmn_drv_ops->txrx_set_nac) - soc->ops->cmn_drv_ops->txrx_set_nac(peer); -} - -/** - * cdp_set_pdev_tx_capture() - set pdev tx_capture - * @soc: opaque soc handle - * @pdev: data path pdev handle - * @val: value of pdev_tx_capture - * - * Return: status: 0 - Success, non-zero: Failure - */ -static inline -QDF_STATUS cdp_set_pdev_tx_capture(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, int val) -{ - if (soc->ops->cmn_drv_ops->txrx_set_pdev_tx_capture) - return soc->ops->cmn_drv_ops->txrx_set_pdev_tx_capture(pdev, - val); - return QDF_STATUS_SUCCESS; + soc->ops->cmn_drv_ops->tx_send(soc, vdev_id, nbuf); } /** * cdp_set_pdev_pcp_tid_map() - set pdev pcp-tid-map * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * @pcp: pcp value * @tid: tid value * @@ -2084,7 +2028,7 @@ QDF_STATUS cdp_set_pdev_tx_capture(ol_txrx_soc_handle soc, */ static inline QDF_STATUS cdp_set_pdev_pcp_tid_map(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, uint32_t pcp, uint32_t tid) { if (!soc || !soc->ops) { @@ -2097,57 +2041,28 @@ QDF_STATUS cdp_set_pdev_pcp_tid_map(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->set_pdev_pcp_tid_map) return QDF_STATUS_E_INVAL; - return soc->ops->cmn_drv_ops->set_pdev_pcp_tid_map(pdev, pcp, tid); -} - -/** - * cdp_set_pdev_pcp_tidmap_prty() - set pdev tidmap priority - * @soc: opaque soc handle - * @pdev: data path pdev handle - * @val: priority value - * - * This API is used to configure the tidmap priority for a pdev. - * The tidmap priority decides which mapping, namely DSCP-TID, SVLAN_PCP-TID, - * CVLAN_PCP-TID will be used. - * - * Return: QDF_STATUS_SUCCESS if value set successfully - * QDF_STATUS_E_INVAL false if error - */ -static inline -QDF_STATUS cdp_set_pdev_tidmap_prty(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev_handle, - uint32_t val) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - return QDF_STATUS_E_INVAL; - } - - if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->set_pdev_tidmap_prty) - return QDF_STATUS_E_INVAL; - - return soc->ops->cmn_drv_ops->set_pdev_tidmap_prty(pdev_handle, val); + return soc->ops->cmn_drv_ops->set_pdev_pcp_tid_map(soc, pdev_id, + pcp, tid); } /** * cdp_get_peer_mac_from_peer_id() - get peer mac addr from peer id * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * @peer_id: data path peer id * @peer_mac: peer_mac * - * Return: void + * Return: QDF_STATUS */ static inline -void cdp_get_peer_mac_from_peer_id(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev_handle, - uint32_t peer_id, uint8_t *peer_mac) +QDF_STATUS cdp_get_peer_mac_from_peer_id(ol_txrx_soc_handle soc, + uint32_t peer_id, uint8_t *peer_mac) { if (soc->ops->cmn_drv_ops->txrx_get_peer_mac_from_peer_id) - soc->ops->cmn_drv_ops->txrx_get_peer_mac_from_peer_id( - pdev_handle, peer_id, peer_mac); + return soc->ops->cmn_drv_ops->txrx_get_peer_mac_from_peer_id( + soc, peer_id, peer_mac); + + return QDF_STATUS_E_INVAL; } /** @@ -2159,90 +2074,97 @@ void cdp_get_peer_mac_from_peer_id(ol_txrx_soc_handle soc, */ static inline void cdp_vdev_tx_lock(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) + uint8_t vdev_id) { if (soc->ops->cmn_drv_ops->txrx_vdev_tx_lock) - soc->ops->cmn_drv_ops->txrx_vdev_tx_lock(vdev); + soc->ops->cmn_drv_ops->txrx_vdev_tx_lock(soc, vdev_id); } /** * cdp_vdev_tx_unlock() - release lock * @soc: opaque soc handle - * @vdev: data path vdev handle + * @vdev_id: id of data path vdev handle * * Return: void */ static inline void cdp_vdev_tx_unlock(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) + uint8_t vdev_id) { if (soc->ops->cmn_drv_ops->txrx_vdev_tx_unlock) - soc->ops->cmn_drv_ops->txrx_vdev_tx_unlock(vdev); + soc->ops->cmn_drv_ops->txrx_vdev_tx_unlock(soc, vdev_id); } /** * cdp_ath_getstats() - get updated athstats * @soc: opaque soc handle - * @dev: dp interface handle + * @id: vdev_id/pdev_id based on type * @stats: cdp network device stats structure * @type: device type pdev/vdev * - * Return: void + * Return: QDF_STATUS */ -static inline void cdp_ath_getstats(ol_txrx_soc_handle soc, - void *dev, struct cdp_dev_stats *stats, - uint8_t type) +static inline QDF_STATUS +cdp_ath_getstats(ol_txrx_soc_handle soc, + uint8_t id, struct cdp_dev_stats *stats, + uint8_t type) { if (soc && soc->ops && soc->ops->cmn_drv_ops->txrx_ath_getstats) - soc->ops->cmn_drv_ops->txrx_ath_getstats(dev, stats, type); + return soc->ops->cmn_drv_ops->txrx_ath_getstats(soc, id, + stats, type); + + return QDF_STATUS_E_FAILURE; } /** * cdp_set_gid_flag() - set groupid flag * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * @mem_status: member status from grp management frame * @user_position: user position from grp management frame * - * Return: void + * Return: QDF_STATUS */ -static inline -void cdp_set_gid_flag(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, u_int8_t *mem_status, - u_int8_t *user_position) +static inline QDF_STATUS +cdp_set_gid_flag(ol_txrx_soc_handle soc, + uint8_t pdev_id, u_int8_t *mem_status, + u_int8_t *user_position) { if (soc->ops->cmn_drv_ops->txrx_set_gid_flag) - soc->ops->cmn_drv_ops->txrx_set_gid_flag(pdev, mem_status, user_position); + return soc->ops->cmn_drv_ops->txrx_set_gid_flag(soc, pdev_id, + mem_status, + user_position); + return QDF_STATUS_E_FAILURE; } /** * cdp_fw_supported_enh_stats_version() - returns the fw enhanced stats version * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * */ static inline uint32_t cdp_fw_supported_enh_stats_version(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) + uint8_t pdev_id) { if (soc->ops->cmn_drv_ops->txrx_fw_supported_enh_stats_version) - return soc->ops->cmn_drv_ops->txrx_fw_supported_enh_stats_version(pdev); + return soc->ops->cmn_drv_ops->txrx_fw_supported_enh_stats_version(soc, pdev_id); return 0; } /** * cdp_get_pdev_id_frm_pdev() - return pdev_id from pdev * @soc: opaque soc handle - * @ni: associated node + * @vdev_id: id of vdev device * @force: number of frame in SW queue * Return: void */ static inline void cdp_if_mgmt_drain(ol_txrx_soc_handle soc, - void *ni, int force) + uint8_t vdev_id, int force) { if (soc->ops->cmn_drv_ops->txrx_if_mgmt_drain) - soc->ops->cmn_drv_ops->txrx_if_mgmt_drain(ni, force); + soc->ops->cmn_drv_ops->txrx_if_mgmt_drain(soc, vdev_id, force); } /* cdp_peer_map_attach() - CDP API to allocate PEER map memory @@ -2268,25 +2190,6 @@ cdp_peer_map_attach(ol_txrx_soc_handle soc, uint32_t max_peers, return QDF_STATUS_SUCCESS; } -/** - - * cdp_pdev_set_ctrl_pdev() - set UMAC ctrl pdev to dp pdev - * @soc: opaque soc handle - * @pdev: opaque dp pdev handle - * @ctrl_pdev: opaque ctrl pdev handle - * - * Return: void - */ -static inline void -cdp_pdev_set_ctrl_pdev(ol_txrx_soc_handle soc, struct cdp_pdev *dp_pdev, - struct cdp_ctrl_objmgr_pdev *ctrl_pdev) -{ - if (soc && soc->ops && soc->ops->cmn_drv_ops && - soc->ops->cmn_drv_ops->txrx_pdev_set_ctrl_pdev) - soc->ops->cmn_drv_ops->txrx_pdev_set_ctrl_pdev(dp_pdev, - ctrl_pdev); -} - /* cdp_txrx_classify_and_update() - To classify the packet and update stats * @soc: opaque soc handle * @vdev: opaque dp vdev handle @@ -2298,7 +2201,7 @@ cdp_pdev_set_ctrl_pdev(ol_txrx_soc_handle soc, struct cdp_pdev *dp_pdev, */ static inline int cdp_txrx_classify_and_update(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, qdf_nbuf_t skb, + uint8_t vdev_id, qdf_nbuf_t skb, enum txrx_direction dir, struct ol_txrx_nbuf_classify *nbuf_class) { @@ -2313,7 +2216,7 @@ cdp_txrx_classify_and_update(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->txrx_classify_update) return 0; - return soc->ops->cmn_drv_ops->txrx_classify_update(vdev, + return soc->ops->cmn_drv_ops->txrx_classify_update(soc, vdev_id, skb, dir, nbuf_class); } @@ -2461,7 +2364,8 @@ static inline uint32_t cdp_cfg_get(ol_txrx_soc_handle soc, enum cdp_dp_cfg cfg) * Return: void */ static inline void -cdp_soc_set_rate_stats_ctx(ol_txrx_soc_handle soc, void *ctx) +cdp_soc_set_rate_stats_ctx(ol_txrx_soc_handle soc, + void *ctx) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -2504,11 +2408,11 @@ cdp_soc_get_rate_stats_ctx(ol_txrx_soc_handle soc) /** * cdp_peer_flush_rate_stats() - flush peer rate statistics * @soc: opaque soc handle - * @pdev: pdev handle + * @pdev_id: id of pdev handle * @buf: stats buffer */ static inline void -cdp_peer_flush_rate_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +cdp_peer_flush_rate_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, void *buf) { if (!soc || !soc->ops) { @@ -2522,35 +2426,36 @@ cdp_peer_flush_rate_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, !soc->ops->cmn_drv_ops->txrx_peer_flush_rate_stats) return; - soc->ops->cmn_drv_ops->txrx_peer_flush_rate_stats(soc, pdev, buf); + soc->ops->cmn_drv_ops->txrx_peer_flush_rate_stats(soc, pdev_id, buf); } /** * cdp_flush_rate_stats_request() - request flush rate statistics * @soc: opaque soc handle - * @pdev: pdev handle + * @pdev_id: id of pdev handle */ -static inline void -cdp_flush_rate_stats_request(struct cdp_soc_t *soc, struct cdp_pdev *pdev) +static inline QDF_STATUS +cdp_flush_rate_stats_request(struct cdp_soc_t *soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->cmn_drv_ops || !soc->ops->cmn_drv_ops->txrx_flush_rate_stats_request) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->cmn_drv_ops->txrx_flush_rate_stats_request(soc, pdev); + return soc->ops->cmn_drv_ops->txrx_flush_rate_stats_request(soc, + pdev_id); } /** * cdp_set_vdev_pcp_tid_map() - set vdev pcp-tid-map * @soc: opaque soc handle - * @vdev: data path vdev handle + * @vdev: id of data path vdev handle * @pcp: pcp value * @tid: tid value * @@ -2561,7 +2466,7 @@ cdp_flush_rate_stats_request(struct cdp_soc_t *soc, struct cdp_pdev *pdev) */ static inline QDF_STATUS cdp_set_vdev_pcp_tid_map(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev_handle, + uint8_t vdev_id, uint8_t pcp, uint8_t tid) { if (!soc || !soc->ops) { @@ -2574,71 +2479,87 @@ QDF_STATUS cdp_set_vdev_pcp_tid_map(ol_txrx_soc_handle soc, !soc->ops->cmn_drv_ops->set_vdev_pcp_tid_map) return QDF_STATUS_E_INVAL; - return soc->ops->cmn_drv_ops->set_vdev_pcp_tid_map(vdev_handle, + return soc->ops->cmn_drv_ops->set_vdev_pcp_tid_map(soc, vdev_id, pcp, tid); } /** - * cdp_set_vdev_tidmap_tbl_id() - set vdev tidmap table id + * cdp_tx_send_exc() - Transmit a frame on a given vdev in exception path * * @soc: opaque soc handle - * @vdev: data path vdev handle - * @mapid: value of mapid + * @vdev_id: vdev id + * @nbuf: skb + * @tx_exc_metadata: Handle that holds exception path meta data * - * This API is used to configure the table-id of the tid-mapping for a vdev. - * Table '0' is for using the pdev's pcp-tid mapping and '1' is for using - * the vdev's pcp-tid mapping. - * - * Return: QDF_STATUS_SUCCESS if value set successfully - * QDF_STATUS_E_INVAL false if error + * Return: NULL on success + * nbuf when it fails to send */ -static inline -QDF_STATUS cdp_set_vdev_tidmap_tbl_id(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev_handle, - uint8_t mapid) +static inline qdf_nbuf_t +cdp_tx_send_exc(ol_txrx_soc_handle soc, + uint8_t vdev_id, + qdf_nbuf_t nbuf, + struct cdp_tx_exception_metadata *tx_exc_metadata) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); - return QDF_STATUS_E_INVAL; + QDF_BUG(0); + return 0; } if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->set_vdev_tidmap_tbl_id) - return QDF_STATUS_E_INVAL; + !soc->ops->cmn_drv_ops->tx_send_exc) + return 0; - return soc->ops->cmn_drv_ops->set_vdev_tidmap_tbl_id(vdev_handle, - mapid); + return soc->ops->cmn_drv_ops->tx_send_exc + (soc, vdev_id, nbuf, tx_exc_metadata); } /** - * cdp_set_vdev_tidmap_prty() - set vdev tidmap priority - * @soc: opaque soc handle - * @vdev: data path vdev handle - * @prio: tidmap priority value - * - * This API is used to configure the tidmap priority for a vdev. - * The tidmap priority decides which mapping, namely DSCP-TID, SVLAN_PCP-TID, - * CVLAN_PCP-TID will be used. - * The vdev tidmap priority will be used only when the tidmap_tbl_id is '1'. + * cdp_vdev_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required * - * Return: QDF_STATUS_SUCCESS if value set successfully - * QDF_STATUS_E_INVAL false if error + * return: no of clients */ -static inline -QDF_STATUS cdp_set_vdev_tidmap_prty(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev_handle, uint8_t prio) +static inline uint16_t +cdp_vdev_get_peer_mac_list(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t newmac[][QDF_MAC_ADDR_SIZE], + uint16_t mac_cnt) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); - return QDF_STATUS_E_INVAL; + QDF_BUG(0); + return 0; } if (!soc->ops->cmn_drv_ops || - !soc->ops->cmn_drv_ops->set_vdev_tidmap_prty) - return QDF_STATUS_E_INVAL; + !soc->ops->cmn_drv_ops->get_peer_mac_list) + return 0; - return soc->ops->cmn_drv_ops->set_vdev_tidmap_prty(vdev_handle, prio); + return soc->ops->cmn_drv_ops->get_peer_mac_list + (soc, vdev_id, newmac, mac_cnt); +} + +/** + * cdp_rx_get_pending() - Get number of pending frames of RX threads + * @soc: opaque soc handle + * Return: number of pending frames + */ +static inline int +cdp_rx_get_pending(ol_txrx_soc_handle soc) +{ + if (!soc || !soc->ol_ops || + !soc->ol_ops->dp_rx_get_pending) + return 0; + + if (cdp_cfg_get(soc, cfg_dp_wow_check_rx_pending)) + return soc->ol_ops->dp_rx_get_pending(soc); + else + return 0; } #endif /* _CDP_TXRX_CMN_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h index 0200794d3fb53b0b742af88cc1506c1e190363c3..f99fd6b5c37e7f6ac8bff6e56da0e7f813cb3298 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,7 +30,16 @@ #define LITHIUM_DP 0xfffd/*FIXME Add Litium device ID */ /* Use these device IDs for attach in future */ -ol_txrx_soc_handle ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_if_ops); +#if defined(DP_TXRX_SOC_ATTACH) +static inline ol_txrx_soc_handle +ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_if_ops) +{ + return NULL; +} +#else +ol_txrx_soc_handle +ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_if_ops); +#endif /** * dp_soc_attach_wifi3() - Attach txrx SOC @@ -57,24 +66,32 @@ ol_txrx_soc_handle ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_ * Return: DP SOC handle on success, NULL on failure */ #if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) -void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, - HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, - struct ol_if_ops *ol_ops, uint16_t device_id); -void *dp_soc_init_wifi3(void *soc, void *ctrl_psoc, void *hif_handle, +struct cdp_soc_t * +dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, + HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, + struct ol_if_ops *ol_ops, uint16_t device_id); +void *dp_soc_init_wifi3(struct cdp_soc_t *soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id); #else -static inline void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, - HTC_HANDLE htc_handle, - qdf_device_t qdf_osdev, - struct ol_if_ops *ol_ops, - uint16_t device_id) +static inline struct cdp_soc_t * +dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, + HTC_HANDLE htc_handle, + qdf_device_t qdf_osdev, + struct ol_if_ops *ol_ops, + uint16_t device_id) { return NULL; } static inline -void *dp_soc_init_wifi3(void *soc, void *ctrl_psoc, void *hif_handle, +void *dp_soc_init_wifi3(struct cdp_soc_t *soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id) { @@ -82,16 +99,23 @@ void *dp_soc_init_wifi3(void *soc, void *ctrl_psoc, void *hif_handle, } #endif /* QCA_WIFI_QCA8074 */ -static inline ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid, - void *hif_handle, void *psoc, void *htc_handle, - qdf_device_t qdf_dev, struct ol_if_ops *dp_ol_if_ops) +static inline +ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid, + struct hif_opaque_softc *hif_handle, + struct cdp_ctrl_objmgr_psoc *psoc, + HTC_HANDLE htc_handle, + qdf_device_t qdf_dev, + struct ol_if_ops *dp_ol_if_ops) { switch (devid) { case LITHIUM_DP: /*FIXME Add lithium devide IDs */ case QCA8074_DEVICE_ID: /* Hawekeye */ case QCA8074V2_DEVICE_ID: /* Hawekeye V2*/ case QCA6290_DEVICE_ID: + case QCN9000_DEVICE_ID: case QCA6390_DEVICE_ID: + case QCA6490_DEVICE_ID: + case QCA6750_DEVICE_ID: case QCA6390_EMULATION_DEVICE_ID: case RUMIM2M_DEVICE_ID_NODE0: /*lithium emulation */ case RUMIM2M_DEVICE_ID_NODE1: /*lithium emulation */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h index d2127c695ea0836d475550d9831d6b6134e33772..33916952c6aa4aeba98821120034186ec1e99d6f 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,7 +35,7 @@ #include "qdf_types.h" #include "qdf_nbuf.h" #include "qdf_atomic.h" -#ifdef CONFIG_MCL +#ifdef DP_MOB_DEFS #include #endif #include @@ -56,6 +57,7 @@ #define CDP_BA_64_BIT_MAP_SIZE_DWORDS 2 #define CDP_RSSI_CHAIN_LEN 8 +#define OL_TXRX_INVALID_PDEV_ID 0xff #define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff #define CDP_INVALID_VDEV_ID 0xff /* Options for Dump Statistics */ @@ -78,6 +80,7 @@ #define CDP_BUNDLE_STATS 23 #define CDP_CREDIT_STATS 24 #define CDP_DISCONNECT_STATS 25 +#define CDP_DP_RX_FISA_STATS 26 #define WME_AC_TO_TID(_ac) ( \ ((_ac) == WME_AC_VO) ? 6 : \ @@ -100,6 +103,10 @@ #define CDP_DATA_TID_MAX 8 #define CDP_DATA_NON_QOS_TID 16 + +#define CDP_NUM_SA_BW 4 +#define CDP_PERCENT_MACRO 100 +#define CDP_NUM_KB_IN_MB 1000 /* * advance rx monitor filter * */ @@ -149,6 +156,36 @@ #define FILTER_DATA_DATA 0x0001 #define FILTER_DATA_NULL 0x0008 +/* + * Multiply rate by 2 to avoid float point + * and get rate in units of 500kbps + */ +#define CDP_11B_RATE_0MCS (11 * 2) +#define CDP_11B_RATE_1MCS (5.5 * 2) +#define CDP_11B_RATE_2MCS (2 * 2) +#define CDP_11B_RATE_3MCS (1 * 2) +#define CDP_11B_RATE_4MCS (11 * 2) +#define CDP_11B_RATE_5MCS (5.5 * 2) +#define CDP_11B_RATE_6MCS (2 * 2) + +#define CDP_11A_RATE_0MCS (48 * 2) +#define CDP_11A_RATE_1MCS (24 * 2) +#define CDP_11A_RATE_2MCS (12 * 2) +#define CDP_11A_RATE_3MCS (6 * 2) +#define CDP_11A_RATE_4MCS (54 * 2) +#define CDP_11A_RATE_5MCS (36 * 2) +#define CDP_11A_RATE_6MCS (18 * 2) +#define CDP_11A_RATE_7MCS (9 * 2) + +#define CDP_LEGACY_MCS0 0 +#define CDP_LEGACY_MCS1 1 +#define CDP_LEGACY_MCS2 2 +#define CDP_LEGACY_MCS3 3 +#define CDP_LEGACY_MCS4 4 +#define CDP_LEGACY_MCS5 5 +#define CDP_LEGACY_MCS6 6 +#define CDP_LEGACY_MCS7 7 + QDF_DECLARE_EWMA(tx_lag, 1024, 8) struct cdp_stats_cookie; @@ -161,6 +198,32 @@ enum cdp_cfg_param_type { CDP_CFG_NUM_PARAMS }; +/* + * PPDU TYPE from FW - + * @CDP_PPDU_STATS_PPDU_TYPE_SU: single user type + * @CDP_PPDU_STATS_PPDU_TYPE_MU_MIMO: multi user mu-mimo + * @CDP_PPDU_STATS_PPDU_TYPE_MU_OFDMA: multi user ofdma + * @CDP_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA: multi user mu-mimo ofdma + * @CDP_PPDU_STATS_PPDU_TYPE_UL_TRIG: ul trigger ppdu + * @CDP_PPDU_STATS_PPDU_TYPE_BURST_BCN: burst beacon + * @CDP_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP: bsr respond + * @CDP_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG: bsr trigger + * @CDP_PPDU_STATS_PPDU_TYPE_UL_RESP: ul response + * @CDP_PPDU_STATS_PPDU_TYPE_UNKNOWN + */ +enum CDP_PPDU_STATS_PPDU_TYPE { + CDP_PPDU_STATS_PPDU_TYPE_SU = 0, + CDP_PPDU_STATS_PPDU_TYPE_MU_MIMO = 1, + CDP_PPDU_STATS_PPDU_TYPE_MU_OFDMA = 2, + CDP_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA = 4, + CDP_PPDU_STATS_PPDU_TYPE_UL_TRIG = 5, + CDP_PPDU_STATS_PPDU_TYPE_BURST_BCN = 6, + CDP_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP = 7, + CDP_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG = 8, + CDP_PPDU_STATS_PPDU_TYPE_UL_RESP = 9, + CDP_PPDU_STATS_PPDU_TYPE_UNKNOWN = 0x1F, +}; + /* * htt_dbg_stats_type - * bit positions for each stats type within a stats type bitmask @@ -224,7 +287,9 @@ enum cdp_host_txrx_stats { TXRX_PDEV_CFG_PARAMS = 10, TXRX_NAPI_STATS = 11, TXRX_SOC_INTERRUPT_STATS = 12, + TXRX_SOC_FSE_STATS = 13, TXRX_HAL_REG_WRITE_STATS = 14, + TXRX_SOC_REO_HW_DESC_DUMP = 15, TXRX_HOST_STATS_MAX, }; @@ -360,8 +425,8 @@ enum cdp_ast_free_status { * @cookie: cookie * @cdp_ast_free_status: ast free status */ -typedef void (*txrx_ast_free_cb)(void *ctrl_soc, - void *cdp_soc, +typedef void (*txrx_ast_free_cb)(struct cdp_ctrl_objmgr_psoc *ctrl_soc, + struct cdp_soc *cdp_soc, void *cookie, enum cdp_ast_free_status); @@ -384,6 +449,39 @@ struct cdp_ast_entry_info { uint16_t peer_id; }; +#define MIC_SEQ_CTR_SIZE 6 + +enum cdp_rx_frame_type { + cdp_rx_frame_type_802_11, + cdp_rx_frame_type_802_3, +}; + +/** + * struct cdp_rx_mic_err_info - rx mic error information + * @frame_type: frame type - 0 - 802.11 frame + * - 1 - 802.3 frame + * @data: 802.11 frame + * @ta_mac_addr: transmitter mac address + * @da_mac_addr: destination mac address + * @tsc: sequence number + * @key_id: Key ID + * @multicast: flag for multicast + * @vdev_id: vdev ID + * + * This structure holds rx mic error information + * + */ +struct cdp_rx_mic_err_info { + uint8_t frame_type; + uint8_t *data; + struct qdf_mac_addr ta_mac_addr; + struct qdf_mac_addr da_mac_addr; + uint8_t tsc[MIC_SEQ_CTR_SIZE]; + uint8_t key_id; + bool multicast; + uint16_t vdev_id; +}; + /** * struct cdp_sec_type - security type information */ @@ -515,7 +613,6 @@ typedef struct ol_osif_vdev_t *ol_osif_vdev_handle; * @wlan_op_mode_sta: STA (client) mode * @wlan_op_mode_monitor: Monitor mode * @wlan_op_mode_ocb: OCB mode - * @wlan_op_mode_nan: NAN mode */ enum wlan_op_mode { wlan_op_mode_unknown, @@ -525,7 +622,6 @@ enum wlan_op_mode { wlan_op_mode_monitor, wlan_op_mode_ocb, wlan_op_mode_ndi, - wlan_op_mode_nan, }; /** @@ -586,19 +682,21 @@ typedef void /** * ol_txrx_tx_fp - top-level transmit function - * @data_vdev - handle to the virtual device object + * @soc - dp soc handle + * @vdev_id - handle to the virtual device object * @msdu_list - list of network buffers */ -typedef qdf_nbuf_t (*ol_txrx_tx_fp)(void *data_vdev, +typedef qdf_nbuf_t (*ol_txrx_tx_fp)(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t msdu_list); /** * ol_txrx_tx_exc_fp - top-level transmit function on exception path - * @data_vdev - handle to the virtual device object + * @soc - dp soc handle + * @vdev_id - handle to the virtual device object * @msdu_list - list of network buffers * @tx_exc_metadata - structure that holds parameters to exception path */ -typedef qdf_nbuf_t (*ol_txrx_tx_exc_fp)(void *data_vdev, +typedef qdf_nbuf_t (*ol_txrx_tx_exc_fp)(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t msdu_list, struct cdp_tx_exception_metadata *tx_exc_metadata); @@ -637,6 +735,11 @@ typedef bool (*ol_txrx_tx_flow_control_is_pause_fp)(void *osif_dev); */ typedef QDF_STATUS(*ol_txrx_rx_fp)(void *osif_dev, qdf_nbuf_t msdu_list); +typedef QDF_STATUS(*ol_txrx_fisa_rx_fp)(void *soc, + void *dp_vdev, + qdf_nbuf_t msdu_list); + +typedef QDF_STATUS(*ol_txrx_fisa_flush_fp)(void *soc, int ring_num); /** * ol_txrx_rx_flush_fp - receive function to hand batches of data * frames from txrx to OS shim @@ -682,12 +785,12 @@ typedef QDF_STATUS(*ol_txrx_get_key_fp)(void *osif_dev, uint8_t *key_buf, uint8_ * @osif_dev - the virtual device's OS shim object * @list_head - poniter to head of receive packet queue to decap * @list_tail - poniter to tail of receive packet queue to decap - * @peer - Peer handler + * @peer_mac - mac address of peer handler */ typedef QDF_STATUS(*ol_txrx_rsim_rx_decap_fp)(void *osif_dev, qdf_nbuf_t *list_head, qdf_nbuf_t *list_tail, - struct cdp_peer *peer); + uint8_t *peer_mac); /* ol_txrx_rx_fp - external tx free function to read per packet stats and * free tx buffer externally @@ -732,10 +835,11 @@ typedef void (*ol_txrx_stats_callback)(void *ctxt, * ol_txrx_pktdump_cb - callback for packet dump feature */ typedef void (*ol_txrx_pktdump_cb)(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, - qdf_nbuf_t netbuf, - uint8_t status, - uint8_t type); + uint8_t pdev_id, + uint8_t vdev_id, + qdf_nbuf_t netbuf, + uint8_t status, + uint8_t type); /** * ol_txrx_ops - (pointers to) the functions used for tx and rx @@ -812,6 +916,8 @@ struct ol_txrx_ops { ol_txrx_rx_mon_fp mon; ol_txrx_stats_rx_fp stats_rx; ol_txrx_rsim_rx_decap_fp rsim_rx_decap; + ol_txrx_fisa_rx_fp osif_fisa_rx; + ol_txrx_fisa_flush_fp osif_fisa_flush; } rx; /* proxy arp function pointer - specified by OS shim, stored by txrx */ ol_txrx_proxy_arp_fp proxy_arp; @@ -865,6 +971,17 @@ struct cdp_soc_t { struct ol_if_ops *ol_ops; }; +/* + * cdp_peer_param_type: different types of parameters + * to set values in peer + * @CDP_CONFIG_NAWDS: Enable nawds mode + * @CDP_CONFIG_NAC: Enable nac + */ +enum cdp_peer_param_type { + CDP_CONFIG_NAWDS, + CDP_CONFIG_NAC, +}; + /* * cdp_pdev_param_type: different types of parameters * to set values in pdev @@ -879,6 +996,22 @@ struct cdp_soc_t { * @CDP_INGRESS_STATS: Accumulate ingress statistics * @CDP_OSIF_DROP: Accumulate drops in OSIF layer * @CDP_CONFIG_ENH_RX_CAPTURE: Enable enhanced RX capture + * @CDP_CONFIG_ENH_TX_CAPTURE: Enable enhanced TX capture + * @CDP_CONFIG_HMMC_TID_OVERRIDE: Enable hmmc tid override + * @CDP_CONFIG_HMMC_TID_VALUE: set hmmc tid value + * @CDP_CONFIG_TX_CAPTURE: set tx capture + * @CDP_CHAN_NOISE_FLOOR: set channel noise floor + * @CDP_CONFIG_VOW: set/get vow config + * @CDP_TIDQ_OVERRIDE: set/get tid queue override + * @CDP_TIDMAP_PRTY: set/get tid map prty + * @CDP_TX_PENDING: get tx pending + * @CDP_FILTER_NEIGH_PEERS: filter neighbour peers + * @CDP_FILTER_UCAST_DATA: filter unicast data + * @CDP_FILTER_MCAST_DATA: filter multicast data + * @CDP_FILTER_NO_DATA: filter no data + * @CDP_MONITOR_CHANNEL: monitor channel + * @CDP_MONITOR_FREQUENCY: monitor frequency + * @CDP_CONFIG_BSS_COLOR: configure bss color */ enum cdp_pdev_param_type { CDP_CONFIG_DEBUG_SNIFFER, @@ -892,9 +1025,145 @@ enum cdp_pdev_param_type { CDP_INGRESS_STATS, CDP_OSIF_DROP, CDP_CONFIG_ENH_RX_CAPTURE, + CDP_CONFIG_ENH_TX_CAPTURE, + CDP_CONFIG_HMMC_TID_OVERRIDE, + CDP_CONFIG_HMMC_TID_VALUE, CDP_CONFIG_TX_CAPTURE, + CDP_CHAN_NOISE_FLOOR, + CDP_CONFIG_VOW, + CDP_TIDQ_OVERRIDE, + CDP_TIDMAP_PRTY, + CDP_TX_PENDING, + CDP_FILTER_NEIGH_PEERS, + CDP_FILTER_UCAST_DATA, + CDP_FILTER_MCAST_DATA, + CDP_FILTER_NO_DATA, + CDP_MONITOR_CHANNEL, + CDP_MONITOR_FREQUENCY, + CDP_CONFIG_BSS_COLOR, }; +/* + * cdp_config_param_type: union of different types of parameters + * to set values into dp handles. + * + * @cdp_peer_param_nawds: Enable nawds mode + * @cdp_peer_param_nac: Enable nac + * + * @cdp_vdev_param_nawds: set nawds enable/disable + * @cdp_vdev_param_mcast_en: enable/disable multicast enhancement + * @cdp_vdev_param_wds: wds sta + * @cdp_vdev_param_mec: MEC enable flags + * @cdp_vdev_param_proxysta: proxy sta + * @cdp_vdev_param_tdls_flags: tdls link flags + * @cdp_vdev_param_ap_brdg_en: set ap_bridging enable/disable + * @cdp_vdev_param_cipher_en: set cipher type based on security + * @cdp_vdev_param_qwrap_isolation: qwrap isolation mode + * @cdp_vdev_param_tx_encap: tx encap type + * @cdp_vdev_param_rx_decap: rx decap type + * @cdp_vdev_param_mesh_rx_filter: set mesh rx filter + * @cdp_vdev_param_tidmap_prty: set tid vdev prty + * @cdp_vdev_param_tidmap_tbl_id: set tidmap table id + * @cdp_vdev_param_mesh_mode: set mesh mode + * @cdp_vdev_param_safe_mode: set safe mode + * @cdp_vdev_param_drop_unenc: set drop unencrypted flag + * + * @cdp_pdev_param_dbg_snf: Enable debug sniffer feature + * @cdp_pdev_param_bpr_enable: Enable bcast probe feature + * @cdp_pdev_param_primary_radio: Configure radio as primary + * @cdp_pdev_param_en_perpkt_txstats: Enable per packet statistics + * @cdp_pdev_param_igmpmld_override: Override IGMP/MLD + * @cdp_pdev_param_igmpmld_tid: TID value when igmmld_override is set + * @cdp_pdev_param_arp_dbg_conf: Enable ARP debug + * @cdp_pdev_param_cptr_latcy: Capture time latency + * @cdp_pdev_param_ingrs_stats: Accumulate ingress statistics + * @cdp_pdev_param_osif_drop: Accumulate drops in OSIF layer + * @cdp_pdev_param_en_rx_cap: Enable enhanced RX capture + * @cdp_pdev_param_en_tx_cap: Enable enhanced TX capture + * @cdp_pdev_param_hmmc_tid_ovrd: Enable hmmc tid override + * @cdp_pdev_param_hmmc_tid: set hmmc tid value + * @cdp_pdev_param_tx_capture: set tx capture + * @cdp_pdev_param_chn_noise_flr: set channel noise floor + * @cdp_pdev_param_cfg_vow: set/get vow config + * @cdp_pdev_param_tidq_override: set/get tid queue override + * @cdp_pdev_param_mon_freq: set monitor frequency + * @cdp_pdev_param_bss_color: configure bss color + * @cdp_pdev_param_tidmap_prty: set/get tid map prty + * @cdp_pdev_param_tx_pending: get tx pending + * @cdp_pdev_param_fltr_neigh_peers: filter neighbour peers + * @cdp_pdev_param_fltr_ucast: filter unicast data + * @cdp_pdev_param_fltr_mcast: filter multicast data + * @cdp_pdev_param_fltr_none: filter no data + * @cdp_pdev_param_monitor_chan: monitor channel + * + * @cdp_psoc_param_en_rate_stats: set rate stats enable/disable + * @cdp_psoc_param_en_nss_cfg: set nss cfg + * + * @cdp_enable_tx_checksum: Flag to specify if HW Tx checksum enabled + */ +typedef union cdp_config_param_t { + /* peer params */ + bool cdp_peer_param_nawds; + uint8_t cdp_peer_param_nac; + + /* vdev params */ + bool cdp_vdev_param_wds; + bool cdp_vdev_param_mec; + bool cdp_vdev_param_nawds; + bool cdp_vdev_param_proxysta; + bool cdp_vdev_param_tdls_flags; + bool cdp_vdev_param_ap_brdg_en; + bool cdp_vdev_param_qwrap_isolation; + bool cdp_vdev_param_update_multipass; + uint8_t cdp_vdev_param_da_war; + uint8_t cdp_vdev_param_mcast_en; + uint8_t cdp_vdev_param_tidmap_prty; + uint8_t cdp_vdev_param_tidmap_tbl_id; + uint32_t cdp_vdev_param_aging_tmr; + uint32_t cdp_vdev_param_cipher_en; + uint32_t cdp_vdev_param_tx_encap; + uint32_t cdp_vdev_param_rx_decap; + uint32_t cdp_vdev_param_mesh_rx_filter; + uint32_t cdp_vdev_param_mesh_mode; + uint32_t cdp_vdev_param_safe_mode; + uint32_t cdp_vdev_param_drop_unenc; + + /* pdev params */ + bool cdp_pdev_param_cptr_latcy; + bool cdp_pdev_param_hmmc_tid_ovrd; + bool cdp_pdev_param_fltr_neigh_peers; + bool cdp_pdev_param_cfg_vow; + bool cdp_pdev_param_fltr_mcast; + bool cdp_pdev_param_fltr_none; + bool cdp_pdev_param_fltr_ucast; + uint8_t cdp_pdev_param_primary_radio; + uint8_t cdp_pdev_param_en_rx_cap; + uint8_t cdp_pdev_param_en_tx_cap; + uint8_t cdp_pdev_param_tx_capture; + uint8_t cdp_pdev_param_hmmc_tid; + uint8_t cdp_pdev_param_tidmap_prty; + uint8_t cdp_pdev_param_igmpmld_override; + uint8_t cdp_pdev_param_igmpmld_tid; + uint8_t cdp_pdev_param_arp_dbg_conf; + uint8_t cdp_pdev_param_tidq_override; + uint8_t cdp_pdev_param_bss_color; + uint16_t cdp_pdev_param_chn_noise_flr; + qdf_freq_t cdp_pdev_param_mon_freq; + int cdp_pdev_param_dbg_snf; + int cdp_pdev_param_bpr_enable; + int cdp_pdev_param_monitor_chan; + uint32_t cdp_pdev_param_ingrs_stats; + uint32_t cdp_pdev_param_osif_drop; + uint32_t cdp_pdev_param_en_perpkt_txstats; + uint32_t cdp_pdev_param_tx_pending; + + /* psoc params */ + bool cdp_psoc_param_en_rate_stats; + int cdp_psoc_param_en_nss_cfg; + + bool cdp_enable_tx_checksum; +} cdp_config_param_type; + /** * cdp_rx_enh_capture_mode - Rx enhanced capture modes * @CDP_RX_ENH_CAPTURE_DISABLED: Disable Rx enhance capture @@ -907,6 +1176,28 @@ enum cdp_rx_enh_capture_mode { CDP_RX_ENH_CAPTURE_MPDU_MSDU, }; +/** + * cdp_rx_enh_capture_peer - Rx enhanced capture peer filtering + * @CDP_RX_ENH_CAPTURE_PEER_DISABLED: Disable Rx ENH capture peer filtering + * @CDP_RX_ENH_CAPTURE_PEER_ENABLED: Enable Rx ENH capture peer filtering + */ +enum cdp_rx_enh_capture_peer { + CDP_RX_ENH_CAPTURE_PEER_DISABLED = 0, + CDP_RX_ENH_CAPTURE_PEER_ENABLED, +}; + +/** + * cdp_tx_enh_capture_mode - Tx enhanced capture modes + * @CDP_TX_ENH_CAPTURE_DISABLED: Disable Tx enhance capture for all peers + * @CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS: Enable tx capture for all peers + * @CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER: Enable/disable per peer as necessary + */ +enum cdp_tx_enh_capture_mode { + CDP_TX_ENH_CAPTURE_DISABLED = 0, + CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS, + CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER, +}; + /* * enum cdp_pdev_bpr_param - different types of parameters * to set value in pdev @@ -932,6 +1223,14 @@ enum cdp_pdev_bpr_param { * @CDP_ENABLE_AP_BRIDGE: set ap_bridging enable/disable * @CDP_ENABLE_CIPHER : set cipher type based on security * @CDP_ENABLE_QWRAP_ISOLATION: qwrap isolation mode + * @CDP_TX_ENCAP_TYPE: tx encap type + * @CDP_RX_DECAP_TYPE: rx decap type + * @CDP_MESH_RX_FILTER: set mesh rx filter + * @CDP_TID_VDEV_PRTY: set tid vdev prty + * @CDP_TIDMAP_TBL_ID: set tidmap table id + * @CDP_MESH_MODE: set mesh mode + * @CDP_SAFEMODE: set safe mode + * @CDP_DROP_UNENC: set drop unencrypted flag */ enum cdp_vdev_param_type { CDP_ENABLE_NAWDS, @@ -944,7 +1243,30 @@ enum cdp_vdev_param_type { CDP_CFG_WDS_AGING_TIMER, CDP_ENABLE_AP_BRIDGE, CDP_ENABLE_CIPHER, - CDP_ENABLE_QWRAP_ISOLATION + CDP_ENABLE_QWRAP_ISOLATION, + CDP_UPDATE_MULTIPASS, + CDP_TX_ENCAP_TYPE, + CDP_RX_DECAP_TYPE, + CDP_MESH_RX_FILTER, + CDP_TID_VDEV_PRTY, + CDP_TIDMAP_TBL_ID, +#ifdef MESH_MODE_SUPPORT + CDP_MESH_MODE, +#endif + CDP_SAFEMODE, + CDP_DROP_UNENC, + CDP_ENABLE_CSUM, +}; + +/* + * cdp_psoc_param_type: different types of parameters + * to set values in psoc + * @CDP_ENABLE_RATE_STATS: set rate stats enable/disable + * @CDP_SET_NSS_CFG: set nss cfg + */ +enum cdp_psoc_param_type { + CDP_ENABLE_RATE_STATS, + CDP_SET_NSS_CFG, }; #define TXRX_FW_STATS_TXSTATS 1 @@ -1158,11 +1480,63 @@ struct cdp_tx_sojourn_stats { struct cdp_stats_cookie *cookie; }; +/** + * struct cdp_delayed_tx_completion_ppdu_user - Delayed Tx PPDU completion + * per-user information + * @frame_ctrl: frame control field in 802.11 header + * @qos_ctrl: QoS control field in 802.11 header + * @mpdu_tried: number of mpdus tried + * @ltf_size: ltf_size + * @stbc: stbc + * @he_re: he_re (range extension) + * @txbf: txbf + * @bw: Transmission bandwidth + * + * + * + * + * @nss: NSS 1,2, ...8 + * @mcs: MCS index + * @preamble: preamble + * @gi: guard interval 800/400/1600/3200 ns + * @dcm: dcm + * @ldpc: ldpc + * @ru_start: RU start index + * @ru_tones: RU tones length + * @is_mcast: MCAST or UCAST + * @user_pos: user position + * @mu_group_id: mu group id + */ +struct cdp_delayed_tx_completion_ppdu_user { + uint32_t frame_ctrl:16, + qos_ctrl:16; + uint32_t mpdu_tried_ucast:16, + mpdu_tried_mcast:16; + uint32_t ltf_size:2, + stbc:1, + he_re:1, + txbf:4, + bw:4, + nss:4, + mcs:4, + preamble:4, + gi:4, + dcm:1, + ldpc:1, + delayed_ba:1; + uint16_t ru_start; + uint16_t ru_tones; + bool is_mcast; + uint32_t user_pos; + uint32_t mu_group_id; +}; + /** * struct cdp_tx_completion_ppdu_user - Tx PPDU completion per-user information * @completion_status: completion status - OK/Filter/Abort/Timeout * @tid: TID number * @peer_id: Peer ID + * @ba_size: Block-Ack size * @frame_ctrl: frame control field in 802.11 header * @qos_ctrl: QoS control field in 802.11 header * @mpdu_tried: number of mpdus tried @@ -1206,12 +1580,20 @@ struct cdp_tx_sojourn_stats { * @cookie: cookie to used by upper layer * @is_ppdu_cookie_valid : Indicates that ppdu_cookie is valid * @ppdu_cookie: 16-bit ppdu_cookie + * @sa_is_training: smart antenna training packets indication + * @rssi_chain: rssi chain per bandwidth + * @sa_tx_antenna: antenna in which packet is transmitted + * @sa_max_rates: smart antenna tx feedback info max rates + * @sa_goodput: smart antenna tx feedback info goodput + * @current_rate_per: Moving average per + * @last_enq_seq: last equeue sequence number */ struct cdp_tx_completion_ppdu_user { uint32_t completion_status:8, tid:8, peer_id:16; uint8_t mac_addr[6]; + uint16_t ba_size; uint32_t frame_ctrl:16, qos_ctrl:16; uint32_t mpdu_tried_ucast:16, @@ -1220,7 +1602,7 @@ struct cdp_tx_completion_ppdu_user { uint16_t mpdu_failed:16; uint32_t long_retries:4, short_retries:4, - tx_ratecode:8, + tx_ratecode:16, is_ampdu:1, ppdu_type:5; uint32_t success_bytes; @@ -1264,6 +1646,32 @@ struct cdp_tx_completion_ppdu_user { struct cdp_stats_cookie *cookie; uint8_t is_ppdu_cookie_valid; uint16_t ppdu_cookie; + uint8_t sa_is_training; + uint32_t rssi_chain[CDP_RSSI_CHAIN_LEN]; + uint32_t sa_tx_antenna; + /*Max rates for BW: 20MHZ, 40MHZ and 80MHZ and 160MHZ + * |---------------------------------------| + * | 16 bits | 16 bits | 16 bits | 16 bits | + * | BW-1 | BW-2 | BW-3 | BW-4 | + * | /\ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * |/ \ \ | + * |[11|8] [5|8] \ | + * | BW1 PADDED \ | + * |---------------------------------------| + */ + uint16_t sa_max_rates[CDP_NUM_SA_BW]; + uint32_t sa_goodput; + /* below field is used to calculate goodput in non-training period + * Note: As host is exposing goodput and hence current_rate_per is + * of no use. It is just for Host computation. + */ + uint32_t current_rate_per; + uint32_t last_enq_seq; }; /** @@ -1289,6 +1697,10 @@ struct cdp_tx_completion_ppdu_user { * @mcs: MCS index * @preamble: preamble * @gi: guard interval 800/400/1600/3200 ns + * @resp_type: response type + * @mprot_type: medium protection type + * @rts_success: rts success + * @rts failure: rts failure * @channel: frequency * @channel_num: channel number * @ack_rssi: ack rssi @@ -1301,6 +1713,9 @@ struct cdp_tx_completion_ppdu_user { * @ba_start_seq: Block Ack sequence number * @ba_bitmap: Block Ack bitmap * @ppdu_cookie: 16-bit ppdu_cookie + * @long_retries: long retries + * @short_retries: short retries + * @completion_status: completion status - OK/Filter/Abort/Timeout */ struct cdp_tx_indication_mpdu_info { uint32_t ppdu_id; @@ -1326,21 +1741,44 @@ struct cdp_tx_indication_mpdu_info { uint32_t tx_rate; uint8_t mac_address[QDF_MAC_ADDR_SIZE]; uint8_t bss_mac_address[QDF_MAC_ADDR_SIZE]; - uint32_t ppdu_start_timestamp; - uint32_t ppdu_end_timestamp; + uint64_t ppdu_start_timestamp; + uint64_t ppdu_end_timestamp; uint32_t ba_start_seq; uint32_t ba_bitmap[CDP_BA_256_BIT_MAP_SIZE_DWORDS]; uint16_t ppdu_cookie; + uint16_t long_retries:4, + short_retries:4, + completion_status:8; + uint16_t resp_type:4, + mprot_type:3, + rts_success:1, + rts_failure:1; }; /** * struct cdp_tx_indication_info - Tx capture information * @mpdu_info: Tx MPDU completion information * @mpdu_nbuf: reconstructed mpdu packet + * @ppdu_desc: tx completion ppdu */ struct cdp_tx_indication_info { struct cdp_tx_indication_mpdu_info mpdu_info; qdf_nbuf_t mpdu_nbuf; + struct cdp_tx_completion_ppdu *ppdu_desc; +}; + +/** + * struct cdp_tx_mgmt_comp_info - Tx mgmt comp info + * @ppdu_id: ppdu_id + * @is_sgen_pkt: payload recevied from wmi or htt path + * @retries_count: retries count + * @tx_tsf: 64 bit timestamp + */ +struct cdp_tx_mgmt_comp_info { + uint32_t ppdu_id; + bool is_sgen_pkt; + uint16_t retries_count; + uint64_t tx_tsf; }; /** @@ -1349,39 +1787,78 @@ struct cdp_tx_indication_info { * @ppdu_id: PPDU Id * @ppdu_seq_id: ppdu sequence id for sojourn stats * @vdev_id: VAP Id + * @bar_num_users: BA response user count, based on completion common TLV * @num_users: Number of users + * @pending_retries: pending MPDUs (retries) + * @drop_reason: drop reason from flush status + * @is_flush: is_flush is set based on flush tlv + * @flow_type: tx flow type from flush status + * @queue_type: queue type from flush status * @num_mpdu: Number of MPDUs in PPDU * @num_msdu: Number of MSDUs in PPDU * @frame_type: frame SU or MU + * @htt_frame_type: frame type from htt * @frame_ctrl: frame control of 80211 header * @channel: Channel informartion + * @resp_type: response type + * @mprot_type: medium protection type + * @rts_success: rts success + * @rts failure: rts failure + * @phymode: phy mode * @ack_rssi: RSSI value of last ack packet (units=dB above noise floor) * @tx_duration: PPDU airtime * @ppdu_start_timestamp: TSF at PPDU start * @ppdu_end_timestamp: TSF at PPDU end * @ack_timestamp: TSF at the reception of ACK + * @delayed_ba: Delayed ba flag + * @beam_change: beam change bit in ppdu for he-information + * @bss_color: 6 bit value for full bss color * @user: per-User stats (array of per-user structures) * @mpdu_q: queue of mpdu in a ppdu + * @mpdus: MPDU list based on enqueue sequence bitmap + * @bar_ppdu_id: BAR ppdu_id + * @bar_tx_duration: BAR tx duration + * @bar_ppdu_start_timestamp: BAR start timestamp + * @bar_ppdu_end_timestamp: BAR end timestamp */ struct cdp_tx_completion_ppdu { uint32_t ppdu_id; uint32_t ppdu_seq_id; uint16_t vdev_id; + uint16_t bar_num_users; uint32_t num_users; uint8_t last_usr_index; + uint32_t pending_retries; + uint32_t drop_reason; + uint32_t is_flush:1, + flow_type:8, + queue_type:8; uint32_t num_mpdu:9, num_msdu:16; uint16_t frame_type; + uint16_t htt_frame_type; uint16_t frame_ctrl; uint16_t channel; + uint16_t resp_type:4, + mprot_type:3, + rts_success:1, + rts_failure:1; uint16_t phy_mode; uint32_t ack_rssi; uint32_t tx_duration; - uint32_t ppdu_start_timestamp; - uint32_t ppdu_end_timestamp; - uint32_t ack_timestamp; + uint64_t ppdu_start_timestamp; + uint64_t ppdu_end_timestamp; + uint64_t ack_timestamp; + bool delayed_ba; + uint8_t beam_change; + uint8_t bss_color; struct cdp_tx_completion_ppdu_user user[CDP_MU_MAX_USERS]; qdf_nbuf_queue_t mpdu_q; + qdf_nbuf_t *mpdus; + uint32_t bar_ppdu_id; + uint32_t bar_tx_duration; + uint32_t bar_ppdu_start_timestamp; + uint32_t bar_ppdu_end_timestamp; }; /** @@ -1392,6 +1869,8 @@ struct cdp_tx_completion_ppdu { * @tx_dropped: Tx dropped is same as tx errors as above * @rx_packets: Rx total packets transmitted * @rx_bytes : Rx total bytes transmitted + * @rx_errors : Rx erros + * @rx_dropped: Rx dropped stats */ struct cdp_dev_stats { uint32_t tx_packets; @@ -1400,6 +1879,8 @@ struct cdp_dev_stats { uint32_t tx_dropped; uint32_t rx_packets; uint32_t rx_bytes; + uint32_t rx_errors; + uint32_t rx_dropped; }; /** @@ -1461,6 +1942,71 @@ struct cdp_tx_completion_msdu { struct cdp_rate_stats extd; }; +/** + * struct cdp_rx_stats_ppdu_user -- per user RX stats + * @peer_id: Peer ID + * @vdev_id: VAP ID + * @is_ampdu: mpdu aggregate or non-aggregate? + * @mu_ul_info_valid: MU UL info valid + * @ofdma_ru_start_index: RU index number(0-73) + * @ofdma_ru_width: size of RU in units of 1(26tone)RU + * @nss: NSS 1,2, ...8 + * @mcs: MCS index + * @user_index: user ID in multi-user case + * @ast_index: ast index in multi-user case + * @tid: TID number + * @num_msdu: Number of MSDUs in PPDU + * @udp_msdu_count: Number of UDP MSDUs in PPDU + * @tcp_msdu_count: Number of TCP MSDUs in PPDU + * @other_msdu_count: Number of MSDUs other than UDP and TCP MSDUs in PPDU + * @frame_control: frame control field + * @frame_control_info_valid: frame_control valid + * @data_sequence_control_info_valid: data_sequence_control_info valid + * @first_data_seq_ctrl: Sequence control field of first data frame + * @preamble: preamble + * @ht_flag: ht flag + * @vht_flag: vht flag + * @he_re: he_re (range extension) + * @mpdu_cnt_fcs_ok: Number of MPDUs in PPDU with fcs ok + * @mpdu_cnt_fcs_err: Number of MPDUs in PPDU with fcs err + * @mpdu_fcs_ok_bitmap - MPDU with fcs ok bitmap + * @retried - number of retries + * @mac_addr: Peer MAC Address + */ +struct cdp_rx_stats_ppdu_user { + uint16_t peer_id; + uint8_t vdev_id; + bool is_ampdu; + uint32_t mu_ul_info_valid:1, + ofdma_ru_start_index:7, + ofdma_ru_width:7, + nss:4, + mcs:4; + /* user id */ + uint8_t user_index; + uint32_t ast_index; + uint32_t tid; + uint32_t num_msdu; + uint16_t tcp_msdu_count; + uint16_t udp_msdu_count; + uint16_t other_msdu_count; + uint16_t frame_control; + uint8_t frame_control_info_valid; + uint8_t data_sequence_control_info_valid; + uint16_t first_data_seq_ctrl; + uint32_t preamble_type; + uint16_t ht_flags; + uint16_t vht_flags; + uint16_t he_flags; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + uint32_t mpdu_fcs_ok_bitmap[QDF_MON_STATUS_MPDU_FCS_BMAP_NWORDS]; + uint32_t mpdu_ok_byte_count; + uint32_t mpdu_err_byte_count; + uint32_t retries; + uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; +}; + /** * struct cdp_rx_indication_ppdu - Rx PPDU indication structure * @ppdu_id: PPDU Id @@ -1505,6 +2051,9 @@ struct cdp_tx_completion_msdu { * @rix: rate index * @rssi_chain: rssi chain per nss per bw * @cookie: cookie to used by upper layer + * @user: per user stats in MU-user case + * @nf: noise floor + * @per_chain_rssi: rssi per antenna */ struct cdp_rx_indication_ppdu { uint32_t ppdu_id; @@ -1551,11 +2100,21 @@ struct cdp_rx_indication_ppdu { uint32_t retries; uint32_t rx_byte_count; - uint8_t rx_ratecode; + uint16_t rx_ratecode; uint8_t fcs_error_mpdus; uint16_t frame_ctrl; - uint32_t rssi_chain[SS_COUNT][MAX_BW]; + int8_t rssi_chain[SS_COUNT][MAX_BW]; struct cdp_stats_cookie *cookie; + struct cdp_rx_su_evm_info evm_info; + uint32_t rx_antenna; + uint8_t num_users; + struct cdp_rx_stats_ppdu_user user[CDP_MU_MAX_USERS]; + uint32_t nf; + uint8_t per_chain_rssi[MAX_CHAIN]; + uint8_t is_mcast_bcast; +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) + struct cdp_rx_ppdu_cfr_info cfr_info; +#endif }; /** @@ -1587,7 +2146,11 @@ struct cdp_rx_indication_msdu { * @lro_enable: Enable/Disable LRO * @gro_enable: Enable/Disable GRO * @flow_steering_enable: Enable/Disable Rx Hash based flow steering - * @tcp_Udp_ChecksumOffload: Enable/Disable tcp-Udp checksum Offload + * @p2p_tcp_udp_checksumoffload: Enable/Disable TCP/UDP Checksum Offload for P2P + * @nan_tcp_udp_checksumoffload: Enable/Disable TCP/UDP Checksum Offload for NAN + * @tcp_udp_checksumoffload: Enable/Disable TCP/UDP Checksum Offload + * @legacy_mode_checksumoffload_disable: Disable TCP/UDP Checksum Offload for + * legacy modes. * @napi_enable: Enable/Disable Napi * @ipa_enable: Flag indicating if IPA is enabled or not * @tx_flow_stop_queue_threshold: Value to Pause tx queues @@ -1602,7 +2165,10 @@ struct cdp_config_params { unsigned int lro_enable:1; unsigned int gro_enable:1; unsigned int flow_steering_enable:1; + unsigned int p2p_tcp_udp_checksumoffload:1; + unsigned int nan_tcp_udp_checksumoffload:1; unsigned int tcp_udp_checksumoffload:1; + unsigned int legacy_mode_checksumoffload_disable:1; unsigned int napi_enable:1; unsigned int ipa_enable:1; /* Set when QCA_LL_TX_FLOW_CONTROL_V2 is enabled */ @@ -1657,14 +2223,41 @@ struct cdp_monitor_filter { }; /** - * cdp_dp_cfg - dp ini config enum + * enum cdp_dp_cfg - CDP ENUMs to get to DP configation + * @cfg_dp_enable_data_stall: context passed to be used by consumer + * @cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload: get P2P checksum config + * @cfg_dp_enable_nan_ip_tcp_udp_checksum_offload: get NAN TX checksum config + * @cfg_dp_enable_ip_tcp_udp_checksum_offload: get TX checksum config for others + * @cfg_dp_tso_enable: get TSO enable config + * @cfg_dp_lro_enable: get LRO enable config + * @cfg_dp_gro_enable: get GRP enable config + * @cfg_dp_tc_based_dyn_gro_enable: get TC based dynamic gro enable config + * @cfg_dp_tc_ingress_prio: priority value to be checked for tc filters + * @cfg_dp_tx_flow_start_queue_offset: get DP TX flow start queue offset + * @cfg_dp_tx_flow_stop_queue_threshold: get DP TX flow stop queue threshold + * @cfg_dp_ipa_uc_tx_buf_size: get IPA TX buf size config + * @cfg_dp_ipa_uc_tx_partition_base: get IPA UC TX partition base config + * @cfg_dp_ipa_uc_rx_ind_ring_count: get IPA rx indication ring count config + * @cfg_dp_enable_flow_steering: get flow steerint enable config + * @cfg_dp_reorder_offload_supported: get reorder offload support config + * @cfg_dp_ce_classify_enable: get CE classify enable config + * @cfg_dp_disable_intra_bss_fwd: get intra bss fwd config + * @cfg_dp_pktlog_buffer_size: get packet log buffer size config + * @cfg_dp_wow_check_rx_pending: get wow rx pending frame check config */ enum cdp_dp_cfg { cfg_dp_enable_data_stall, + cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload, + cfg_dp_enable_nan_ip_tcp_udp_checksum_offload, cfg_dp_enable_ip_tcp_udp_checksum_offload, + /* Disable checksum offload for legacy modes */ + cfg_dp_disable_legacy_mode_csum_offload, cfg_dp_tso_enable, cfg_dp_lro_enable, cfg_dp_gro_enable, + cfg_dp_sg_enable, + cfg_dp_tc_based_dyn_gro_enable, + cfg_dp_tc_ingress_prio, cfg_dp_tx_flow_start_queue_offset, cfg_dp_tx_flow_stop_queue_threshold, cfg_dp_ipa_uc_tx_buf_size, @@ -1675,19 +2268,105 @@ enum cdp_dp_cfg { cfg_dp_ce_classify_enable, cfg_dp_disable_intra_bss_fwd, cfg_dp_pktlog_buffer_size, + cfg_dp_wow_check_rx_pending, }; /** * struct cdp_peer_cookie - cookie used when creating peer - * @peer_id: peer id + * @ctx: context passed to be used by consumer * @mac_addr: MAC address of peer + * @peer_id: peer id + * @pdev_id: pdev_id * @cookie: cookie to be used by consumer - * @ctx: context passed to be used by consumer */ struct cdp_peer_cookie { - uint8_t peer_id; + struct cdp_stats_cookie *ctx; uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + uint8_t peer_id; + uint8_t pdev_id; uint8_t cookie; - struct cdp_stats_cookie *ctx; +}; + +#ifdef WLAN_SUPPORT_RX_FISA +struct cdp_flow_stats { + uint32_t aggr_count; + uint32_t curr_aggr_count; + uint32_t flush_count; + uint32_t bytes_aggregated; +}; +#else +/** + * cdp_flow_stats - Per-Flow (5-tuple) statistics + * @msdu_count: number of rx msdus matching this flow + * + * HW also includes msdu_byte_count and timestamp, which + * are not currently tracked in SW. + */ +struct cdp_flow_stats { + uint32_t msdu_count; +}; +#endif + +/** + * cdp_flow_fst_operation - RX FST operations allowed + */ +enum cdp_flow_fst_operation { + CDP_FLOW_FST_ENTRY_ADD, + CDP_FLOW_FST_ENTRY_DEL, + CDP_FLOW_FST_RX_BYPASS_ENABLE, + CDP_FLOW_FST_RX_BYPASS_DISABLE +}; + +/** + * cdp_flow_protocol_type - RX FST supported protocol types, mapped to HW spec + */ +enum cdp_flow_protocol_type { + CDP_FLOW_PROTOCOL_TYPE_TCP = 6, + CDP_FLOW_PROTOCOL_TYPE_UDP = 17, +}; + +/** + * cdp_rx_flow_tuple_info - RX flow tuple info used for addition/deletion + * @dest_ip_127_96: destination IP address bit fields 96-127 + * @dest_ip_95_64: destination IP address bit fields 64-95 + * @dest_ip_63_32: destination IP address bit fields 32-63 + * @dest_ip_31_0: destination IP address bit fields 0-31 + * @src_ip_127_96: source IP address bit fields 96-127 + * @src_ip_95_64: source IP address bit fields 64-95 + * @src_ip_63_32: source IP address bit fields 32-63 + * @src_ip_31_0: source IP address bit fields 0-31 + * @dest_port: destination port of flow + * @src_port: source port of flow + * @l4_protocol: protocol type in flow (TCP/UDP) + */ +struct cdp_rx_flow_tuple_info { +#ifdef WLAN_SUPPORT_RX_FISA + uint8_t tuple_populated; +#endif + uint32_t dest_ip_127_96; + uint32_t dest_ip_95_64; + uint32_t dest_ip_63_32; + uint32_t dest_ip_31_0; + uint32_t src_ip_127_96; + uint32_t src_ip_95_64; + uint32_t src_ip_63_32; + uint32_t src_ip_31_0; + uint16_t dest_port; + uint16_t src_port; + uint16_t l4_protocol; +}; + +/** + * cdp_rx_flow_info - RX flow info used for addition/deletion + * @is_addr_ipv4: indicates whether given IP address is IPv4/IPv6 + * @op_code: add/delete/enable/disable operation requested + * @flow_tupe_info: structure containing tuple info + * @fse_metadata: metadata to be set in RX flow + */ +struct cdp_rx_flow_info { + bool is_addr_ipv4; + enum cdp_flow_fst_operation op_code; + struct cdp_rx_flow_tuple_info flow_tuple_info; + uint16_t fse_metadata; }; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h index 187ab87daf68cebfb1c605399c97cae550ab816f..82f7ce6c943950d0f0ae9fdaf7d30443a919aa7b 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,7 +30,7 @@ #include "cdp_txrx_ops.h" static inline int cdp_is_target_ar900b - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev) + (ol_txrx_soc_handle soc) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -43,13 +43,13 @@ static inline int cdp_is_target_ar900b !soc->ops->ctrl_ops->txrx_is_target_ar900b) return 0; - return soc->ops->ctrl_ops->txrx_is_target_ar900b(vdev); + return soc->ops->ctrl_ops->txrx_is_target_ar900b(soc); } /* WIN */ static inline int -cdp_mempools_attach(ol_txrx_soc_handle soc, void *ctrl_pdev) +cdp_mempools_attach(ol_txrx_soc_handle soc) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -62,22 +62,26 @@ cdp_mempools_attach(ol_txrx_soc_handle soc, void *ctrl_pdev) !soc->ops->ctrl_ops->txrx_mempools_attach) return 0; - return soc->ops->ctrl_ops->txrx_mempools_attach(ctrl_pdev); + return soc->ops->ctrl_ops->txrx_mempools_attach(soc); } + +#if defined(ATH_SUPPORT_NAC) || defined(ATH_SUPPORT_NAC_RSSI) /** - * @brief set filter neighbour peers + * @brief update the neighbour peer addresses * @details - * This defines interface function to set neighbour peer filtering. + * This defines interface function to update neighbour peers addresses + * which needs to be filtered * * @param soc - the pointer to soc object - * @param pdev - the pointer physical device object - * @param val - the enable/disable value + * @param vdev_id - id of the pointer to vdev + * @param cmd - add/del entry into peer table + * @param macaddr - the address of neighbour peer * @return - int */ static inline int -cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, u_int32_t val) +cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, + uint8_t vdev_id, uint32_t cmd, uint8_t *macaddr) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -87,114 +91,103 @@ cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc, } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_filter_neighbour_peers) + !soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers) return 0; - return soc->ops->ctrl_ops->txrx_set_filter_neighbour_peers - (pdev, val); + return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers + (soc, vdev_id, cmd, macaddr); } +#endif /* ATH_SUPPORT_NAC || ATH_SUPPORT_NAC_RSSI*/ /** - * @brief update the neighbour peer addresses + * @brief set the Reo Destination ring for the pdev * @details - * This defines interface function to update neighbour peers addresses - * which needs to be filtered + * This will be used to configure the Reo Destination ring for this pdev. * - * @param soc - the pointer to soc object - * @param vdev - the pointer to vdev - * @param cmd - add/del entry into peer table - * @param macaddr - the address of neighbour peer - * @return - int + * @param soc - pointer to the soc + * @param pdev_id - id of the data physical device object + * @param val - the Reo destination ring index (1 to 4) + * @return - QDF_STATUS */ -static inline int -cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint32_t cmd, uint8_t *macaddr) +static inline QDF_STATUS +cdp_set_pdev_reo_dest(ol_txrx_soc_handle soc, + uint8_t pdev_id, enum cdp_host_reo_dest_ring val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return 0; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers) - return 0; + !soc->ops->ctrl_ops->txrx_set_pdev_reo_dest) + return QDF_STATUS_E_FAILURE; - return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers - (vdev, cmd, macaddr); + return soc->ops->ctrl_ops->txrx_set_pdev_reo_dest + (soc, pdev_id, val); } /** - * @brief set the safemode of the device - * @details - * This flag is used to bypass the encrypt and decrypt processes when send and - * receive packets. It works like open AUTH mode, HW will treate all packets - * as non-encrypt frames because no key installed. For rx fragmented frames, - * it bypasses all the rx defragmentaion. + * @brief get the Reo Destination ring for the pdev * - * @param vdev - the data virtual device object - * @param val - the safemode state - * @return - void + * @param soc - pointer to the soc + * @param pdev_id - id of physical device object + * @return - the Reo destination ring index (1 to 4), 0 if not supported. */ -static inline void -cdp_set_safemode(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, u_int32_t val) +static inline enum cdp_host_reo_dest_ring +cdp_get_pdev_reo_dest(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return cdp_host_reo_dest_ring_unknown; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_safemode) - return; + !soc->ops->ctrl_ops->txrx_get_pdev_reo_dest) + return cdp_host_reo_dest_ring_unknown; - soc->ops->ctrl_ops->txrx_set_safemode(vdev, val); + return soc->ops->ctrl_ops->txrx_get_pdev_reo_dest(soc, pdev_id); } + +/* Is this similar to ol_txrx_peer_state_update() in MCL */ /** - * @brief configure the drop unencrypted frame flag + * @brief Update the authorize peer object at association time * @details - * Rx related. When set this flag, all the unencrypted frames - * received over a secure connection will be discarded + * For the host-based implementation of rate-control, it + * updates the peer/node-related parameters within rate-control + * context of the peer at association. + * + * @param soc - pointer to the soc + * @param vdev_id - id of the pointer to vdev + * @param peer_mac - mac address of the node's object + * @authorize - either to authorize or unauthorize peer * - * @param vdev - the data virtual device object - * @param val - flag - * @return - void + * @return QDF_STATUS */ -static inline void -cdp_set_drop_unenc(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, u_int32_t val) +static inline QDF_STATUS +cdp_peer_authorize(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, + u_int32_t authorize) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_drop_unenc) - return; + !soc->ops->ctrl_ops->txrx_peer_authorize) + return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->txrx_set_drop_unenc(vdev, val); + return soc->ops->ctrl_ops->txrx_peer_authorize + (soc, vdev_id, peer_mac, authorize); } - -/** - * @brief set the Tx encapsulation type of the VDEV - * @details - * This will be used to populate the HTT desc packet type field during Tx - * - * @param vdev - the data virtual device object - * @param val - the Tx encap type (htt_cmn_pkt_type) - * @return - void - */ -static inline void -cdp_set_tx_encap_type(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, enum htt_cmn_pkt_type val) +static inline void cdp_tx_flush_buffers +(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -204,303 +197,416 @@ cdp_set_tx_encap_type(ol_txrx_soc_handle soc, } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_tx_encap_type) + !soc->ops->ctrl_ops->tx_flush_buffers) return; - soc->ops->ctrl_ops->txrx_set_tx_encap_type(vdev, val); + soc->ops->ctrl_ops->tx_flush_buffers(soc, vdev_id); } -/** - * @brief set the Rx decapsulation type of the VDEV - * @details - * This will be used to configure into firmware and hardware which format to - * decap all Rx packets into, for all peers under the VDEV. - * - * @param vdev - the data virtual device object - * @param val - the Rx decap mode (htt_cmn_pkt_type) - * @return - void - */ -static inline void -cdp_set_vdev_rx_decap_type(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, enum htt_cmn_pkt_type val) +static inline QDF_STATUS cdp_txrx_get_vdev_param(ol_txrx_soc_handle soc, + uint8_t vdev_id, + enum cdp_vdev_param_type type, + cdp_config_param_type *val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_vdev_rx_decap_type) - return; + !soc->ops->ctrl_ops->txrx_get_vdev_param) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: callback not registered:", __func__); + return QDF_STATUS_E_FAILURE; + } - soc->ops->ctrl_ops->txrx_set_vdev_rx_decap_type - (vdev, val); + return soc->ops->ctrl_ops->txrx_get_vdev_param(soc, vdev_id, + type, val); } -/** - * @brief get the Rx decapsulation type of the VDEV - * - * @param vdev - the data virtual device object - * @return - the Rx decap type (htt_cmn_pkt_type) - */ -static inline enum htt_cmn_pkt_type -cdp_get_vdev_rx_decap_type(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_txrx_set_vdev_param(ol_txrx_soc_handle soc, + uint8_t vdev_id, enum cdp_vdev_param_type type, + cdp_config_param_type val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return 0; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_get_vdev_rx_decap_type) - return 0; + !soc->ops->ctrl_ops->txrx_set_vdev_param) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "NULL vdev params callback"); + return QDF_STATUS_E_FAILURE; + } - return soc->ops->ctrl_ops->txrx_get_vdev_rx_decap_type(vdev); + return soc->ops->ctrl_ops->txrx_set_vdev_param(soc, vdev_id, + type, val); } -/** - * @brief set the Reo Destination ring for the pdev - * @details - * This will be used to configure the Reo Destination ring for this pdev. - * - * @param soc - pointer to the soc - * @param pdev - the data physical device object - * @param val - the Reo destination ring index (1 to 4) - * @return - void - */ -static inline void -cdp_set_pdev_reo_dest(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, enum cdp_host_reo_dest_ring val) +static inline QDF_STATUS +cdp_txrx_set_psoc_param(ol_txrx_soc_handle soc, + enum cdp_psoc_param_type type, + cdp_config_param_type val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_pdev_reo_dest) - return; + !soc->ops->ctrl_ops->txrx_set_psoc_param) + return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->txrx_set_pdev_reo_dest - (pdev, val); + return soc->ops->ctrl_ops->txrx_set_psoc_param(soc, type, val); } -/** - * @brief get the Reo Destination ring for the pdev - * - * @param soc - pointer to the soc - * @param pdev - the data physical device object - * @return - the Reo destination ring index (1 to 4), 0 if not supported. - */ -static inline enum cdp_host_reo_dest_ring -cdp_get_pdev_reo_dest(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +static inline QDF_STATUS +cdp_txrx_get_psoc_param(ol_txrx_soc_handle soc, + enum cdp_psoc_param_type type, + cdp_config_param_type *val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return cdp_host_reo_dest_ring_unknown; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_get_pdev_reo_dest) - return cdp_host_reo_dest_ring_unknown; + !soc->ops->ctrl_ops->txrx_get_psoc_param) + return QDF_STATUS_E_FAILURE; - return soc->ops->ctrl_ops->txrx_get_pdev_reo_dest(pdev); + return soc->ops->ctrl_ops->txrx_get_psoc_param(soc, type, val); } -/* Is this similar to ol_txrx_peer_state_update() in MCL */ +#ifdef VDEV_PEER_PROTOCOL_COUNT /** - * @brief Update the authorize peer object at association time - * @details - * For the host-based implementation of rate-control, it - * updates the peer/node-related parameters within rate-control - * context of the peer at association. + * cdp_set_vdev_peer_protocol_count() - set per-peer protocol count tracking * - * @param peer - pointer to the node's object - * @authorize - either to authorize or unauthorize peer + * @soc - pointer to the soc + * @vdev - the data virtual device object + * @enable - enable per-peer protocol count + * + * Set per-peer protocol count feature enable * - * @return none + * Return: void */ -static inline void -cdp_peer_authorize(ol_txrx_soc_handle soc, - struct cdp_peer *peer, u_int32_t authorize) +static inline +void cdp_set_vdev_peer_protocol_count(ol_txrx_soc_handle soc, int8_t vdev_id, + bool enable) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); return; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_peer_authorize) + !soc->ops->ctrl_ops->txrx_enable_peer_protocol_count) return; - soc->ops->ctrl_ops->txrx_peer_authorize - (peer, authorize); + soc->ops->ctrl_ops->txrx_enable_peer_protocol_count(soc, vdev_id, + enable); } -/* Should be ol_txrx_ctrl_api.h */ -static inline void cdp_set_mesh_mode -(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, u_int32_t val) +/** + * cdp_set_vdev_peer_protocol_drop_mask() - set per-peer protocol drop mask + * + * @soc - pointer to the soc + * @vdev - the data virtual device object + * @drop_mask - drop_mask + * + * Set per-peer protocol drop_mask + * + * Return - void + */ +static inline +void cdp_set_vdev_peer_protocol_drop_mask(ol_txrx_soc_handle soc, + int8_t vdev_id, int drop_mask) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); return; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_mesh_mode) + !soc->ops->ctrl_ops->txrx_set_peer_protocol_drop_mask) return; - soc->ops->ctrl_ops->txrx_set_mesh_mode(vdev, val); + soc->ops->ctrl_ops->txrx_set_peer_protocol_drop_mask(soc, vdev_id, + drop_mask); } /** - * @brief set mesh rx filter - * @details based on the bits enabled in the filter packets has to be dropped. + * cdp_is_vdev_peer_protocol_count_enabled() - whether peer-protocol tracking + * enabled * - * @param soc - pointer to the soc - * @param vdev - the data virtual device object - * @param val - value to be set - * @return - void + * @soc - pointer to the soc + * @vdev - the data virtual device object + * + * Get whether peer protocol count feature enabled or not + * + * Return: whether feature enabled or not */ static inline -void cdp_set_mesh_rx_filter(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint32_t val) +int cdp_is_vdev_peer_protocol_count_enabled(ol_txrx_soc_handle soc, + int8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return 0; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_mesh_rx_filter) - return; + !soc->ops->ctrl_ops->txrx_is_peer_protocol_count_enabled) + return 0; - soc->ops->ctrl_ops->txrx_set_mesh_rx_filter(vdev, val); + return soc->ops->ctrl_ops->txrx_is_peer_protocol_count_enabled(soc, + vdev_id); } -static inline void cdp_tx_flush_buffers -(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +/** + * cdp_get_peer_protocol_drop_mask() - get per-peer protocol count drop-mask + * + * @soc - pointer to the soc + * @vdev - the data virtual device object + * + * Get peer-protocol-count drop-mask + * + * Return: peer-protocol-count drop-mask + */ +static inline +int cdp_get_peer_protocol_drop_mask(ol_txrx_soc_handle soc, int8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return 0; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->tx_flush_buffers) - return; + !soc->ops->ctrl_ops->txrx_get_peer_protocol_drop_mask) + return 0; - soc->ops->ctrl_ops->tx_flush_buffers(vdev); + return soc->ops->ctrl_ops->txrx_get_peer_protocol_drop_mask(soc, + vdev_id); } -static inline uint32_t cdp_txrx_get_vdev_param(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, - enum cdp_vdev_param_type type) +/* + * Rx-Ingress and Tx-Egress are in the lower level DP layer + * Rx-Egress and Tx-ingress are handled in osif layer for DP + * So + * Rx-Ingress and Tx-Egress definitions are in DP layer + * Rx-Egress and Tx-ingress mask definitions are here below + */ +#define VDEV_PEER_PROTOCOL_RX_INGRESS_MASK 1 +#define VDEV_PEER_PROTOCOL_TX_INGRESS_MASK 2 +#define VDEV_PEER_PROTOCOL_RX_EGRESS_MASK 4 +#define VDEV_PEER_PROTOCOL_TX_EGRESS_MASK 8 + +#else +#define cdp_set_vdev_peer_protocol_count(soc, vdev_id, enable) +#define cdp_set_vdev_peer_protocol_drop_mask(soc, vdev_id, drop_mask) +#define cdp_is_vdev_peer_protocol_count_enabled(soc, vdev_id) 0 +#define cdp_get_peer_protocol_drop_mask(soc, vdev_id) 0 +#endif + +/** + * cdp_txrx_set_pdev_param() - set pdev parameter + * @soc: opaque soc handle + * @pdev_id: id of data path pdev handle + * @type: param type + * @val: value + * + * Return: status: 0 - Success, non-zero: Failure + */ +static inline QDF_STATUS cdp_txrx_set_pdev_param(ol_txrx_soc_handle soc, + uint8_t pdev_id, + enum cdp_pdev_param_type type, + cdp_config_param_type val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); - return -1; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_get_vdev_param) { + !soc->ops->ctrl_ops->txrx_set_pdev_param) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_set_pdev_param + (soc, pdev_id, type, val); +} + +/** + * cdp_txrx_set_peer_param() - set pdev parameter + * @soc: opaque soc handle + * @vdev_id: id of data path vdev handle + * @peer_mac: peer mac address + * @type: param type + * @val: value + * + * Return: status: 0 - Success, non-zero: Failure + */ +static inline QDF_STATUS cdp_txrx_set_peer_param(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_param_type type, + cdp_config_param_type val) +{ + if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: callback not registered:", __func__); - return -1; + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; } - return soc->ops->ctrl_ops->txrx_get_vdev_param(vdev, type); + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_set_peer_param) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_set_peer_param + (soc, vdev_id, peer_mac, type, val); } -static inline void cdp_txrx_set_vdev_param(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, enum cdp_vdev_param_type type, - uint32_t val) +/** + * cdp_txrx_get_peer_param() - set pdev parameter + * @soc: opaque soc handle + * @vdev_id: id of data path vdev handle + * @peer_mac: peer mac address + * @type: param type + * @val: address of buffer + * + * Return: status + */ +static inline QDF_STATUS cdp_txrx_get_peer_param(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_param_type type, + cdp_config_param_type *val) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_vdev_param) - return; + !soc->ops->ctrl_ops->txrx_get_peer_param) + return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->txrx_set_vdev_param(vdev, type, val); + return soc->ops->ctrl_ops->txrx_get_peer_param + (soc, vdev_id, peer_mac, type, val); } +#ifdef QCA_MULTIPASS_SUPPORT static inline void -cdp_peer_set_nawds(ol_txrx_soc_handle soc, - struct cdp_peer *peer, uint8_t value) +cdp_peer_set_vlan_id(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, uint8_t vlan_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance:", __func__); + "%s: Invalid Instance:", __func__); QDF_BUG(0); return; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_peer_set_nawds) + !soc->ops->ctrl_ops->txrx_peer_set_vlan_id) return; - soc->ops->ctrl_ops->txrx_peer_set_nawds - (peer, value); + soc->ops->ctrl_ops->txrx_peer_set_vlan_id(soc, vdev_id, peer_mac, + vlan_id); } +#endif /** - * cdp_txrx_set_pdev_param() - set pdev parameter + * cdp_txrx_get_pdev_param() - get pdev parameter * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id: id of data path pdev handle * @type: param type - * @val: value of pdev_tx_capture + * @value: address of value buffer * - * Return: status: 0 - Success, non-zero: Failure + * Return: status */ -static inline QDF_STATUS cdp_txrx_set_pdev_param(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, +static inline QDF_STATUS cdp_txrx_get_pdev_param(ol_txrx_soc_handle soc, + uint8_t pdev_id, enum cdp_pdev_param_type type, - uint8_t val) + cdp_config_param_type *value) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return QDF_STATUS_SUCCESS; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || - !soc->ops->ctrl_ops->txrx_set_pdev_param) - return QDF_STATUS_SUCCESS; + !soc->ops->ctrl_ops->txrx_get_pdev_param) + return QDF_STATUS_E_FAILURE; - return soc->ops->ctrl_ops->txrx_set_pdev_param - (pdev, type, val); + return soc->ops->ctrl_ops->txrx_get_pdev_param + (soc, pdev_id, type, value); +} + +/** + * cdp_txrx_peer_protocol_cnt() - set peer protocol count + * @soc: opaque soc handle + * @vdev: opaque vdev handle + * @nbuf: data packet + * @is_egress: whether egress or ingress + * @is_rx: whether tx or rx + * + * Return: void + */ +#ifdef VDEV_PEER_PROTOCOL_COUNT +static inline void +cdp_txrx_peer_protocol_cnt(ol_txrx_soc_handle soc, + int8_t vdev_id, + qdf_nbuf_t nbuf, + enum vdev_peer_protocol_enter_exit is_egress, + enum vdev_peer_protocol_tx_rx is_rx) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_peer_protocol_cnt) + return; + + soc->ops->ctrl_ops->txrx_peer_protocol_cnt(soc, vdev_id, nbuf, + is_egress, is_rx); } +#else +#define cdp_txrx_peer_protocol_cnt(soc, vdev_id, nbuf, is_egress, is_rx) +#endif /** * cdp_enable_peer_based_pktlog()- Set flag in peer structure * * @soc: pointer to the soc - * @pdev: the data physical device object + * @pdev_id: id of the data physical device object * @enable: enable or disable peer based filter based pktlog * @peer_macaddr: Mac address of peer which needs to be * filtered @@ -511,8 +617,8 @@ static inline QDF_STATUS cdp_txrx_set_pdev_param(ol_txrx_soc_handle soc, * Return: int */ static inline int -cdp_enable_peer_based_pktlog(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, char *peer_macaddr, +cdp_enable_peer_based_pktlog(ol_txrx_soc_handle soc, uint8_t pdev_id, + char *peer_macaddr, uint8_t enable) { if (!soc || !soc->ops) { @@ -527,37 +633,37 @@ cdp_enable_peer_based_pktlog(ol_txrx_soc_handle soc, return 0; return soc->ops->ctrl_ops->enable_peer_based_pktlog - (pdev, peer_macaddr, enable); + (soc, pdev_id, peer_macaddr, enable); } /** * cdp_calculate_delay_stats()- get rx delay stats * * @soc: pointer to the soc - * @vdev: vdev handle + * @vdev_id: id of vdev handle * @nbuf: nbuf which is passed * * This function will calculate rx delay statistics. */ -static inline void -cdp_calculate_delay_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, +static inline QDF_STATUS +cdp_calculate_delay_stats(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t nbuf) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || !soc->ops->ctrl_ops->calculate_delay_stats) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: callback not registered:", __func__); - return; + return QDF_STATUS_E_FAILURE; } - return soc->ops->ctrl_ops->calculate_delay_stats(vdev, nbuf); + return soc->ops->ctrl_ops->calculate_delay_stats(soc, vdev_id, nbuf); } /** @@ -571,19 +677,19 @@ cdp_calculate_delay_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, * invoked is unspecified. * * @param soc - pointer to the soc - * @param pdev - the data physical device object + * @param pdev_id - id of the data physical device object * @param event_cb_sub - the callback and context for the event subscriber * @param event - which event's notifications are being subscribed to * @return - int */ static inline int -cdp_wdi_event_sub(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, void *event_cb_sub, uint32_t event) +cdp_wdi_event_sub(ol_txrx_soc_handle soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, uint32_t event) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s invalid instance", __func__); + "%s invalid instance", __func__); QDF_BUG(0); return 0; } @@ -593,7 +699,7 @@ cdp_wdi_event_sub(ol_txrx_soc_handle soc, return 0; return soc->ops->ctrl_ops->txrx_wdi_event_sub - (pdev, event_cb_sub, event); + (soc, pdev_id, event_cb_sub, event); } /** @@ -605,14 +711,15 @@ cdp_wdi_event_sub(ol_txrx_soc_handle soc, * to event_sub() on the same wdi_event_subscribe object. * * @param soc - pointer to the soc - * @param pdev - the data physical device object + * @param pdev_id - id of the data physical device object * @param event_cb_sub - the callback and context for the event subscriber * @param event - which event's notifications are being subscribed to * @return - int */ static inline int cdp_wdi_event_unsub(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, void *event_cb_sub, uint32_t event) + uint8_t pdev_id, wdi_event_subscribe *event_cb_sub, + uint32_t event) { if (!soc || !soc->ops) { @@ -627,7 +734,7 @@ cdp_wdi_event_unsub(ol_txrx_soc_handle soc, return 0; return soc->ops->ctrl_ops->txrx_wdi_event_unsub - (pdev, event_cb_sub, event); + (soc, pdev_id, event_cb_sub, event); } /** @@ -638,16 +745,18 @@ cdp_wdi_event_unsub(ol_txrx_soc_handle soc, * to the peer handler. * * @param soc - pointer to the soc - * @param peer - peer handler + * @param vdev_id - id of vdev handle + * @param peer mac - peer mac address * @param sec_idx - mcast or ucast frame type. * @return - int */ static inline int -cdp_get_sec_type(ol_txrx_soc_handle soc, struct cdp_peer *peer, uint8_t sec_idx) +cdp_get_sec_type(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, + uint8_t sec_idx) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s invalid instance", __func__); + "%s invalid instance", __func__); QDF_BUG(0); return A_ERROR; } @@ -657,38 +766,45 @@ cdp_get_sec_type(ol_txrx_soc_handle soc, struct cdp_peer *peer, uint8_t sec_idx) return A_ERROR; return soc->ops->ctrl_ops->txrx_get_sec_type - (peer, sec_idx); + (soc, vdev_id, peer_mac, sec_idx); } /** * cdp_set_mgmt_tx_power(): function to set tx power for mgmt frames - * @vdev_handle: vdev handle + * @param soc - pointer to the soc + * @vdev_id : id of vdev handle * @subtype_index: subtype * @tx_power: Tx power - * Return: None + * Return: QDF_STATUS */ -static inline int cdp_set_mgmt_tx_power(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint8_t subtype, uint8_t tx_power) +static inline QDF_STATUS +cdp_set_mgmt_tx_power(ol_txrx_soc_handle soc, + uint8_t vdev_id, uint8_t subtype, uint8_t tx_power) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance:", __func__); QDF_BUG(0); - return 0; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->ctrl_ops || !soc->ops->ctrl_ops->txrx_update_mgmt_txpow_vdev) - return 0; + return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->txrx_update_mgmt_txpow_vdev(vdev, + return soc->ops->ctrl_ops->txrx_update_mgmt_txpow_vdev(soc, vdev_id, subtype, tx_power); - return 0; } +/** + * cdp_get_pldev() - function to get pktlog device handle + * @soc: datapath soc handle + * @pdev_id: physical device id + * + * Return: pktlog device handle or NULL + */ static inline void * -cdp_get_pldev(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) +cdp_get_pldev(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -700,15 +816,200 @@ cdp_get_pldev(ol_txrx_soc_handle soc, if (!soc->ops->ctrl_ops || !soc->ops->ctrl_ops->txrx_get_pldev) return NULL; - return soc->ops->ctrl_ops->txrx_get_pldev(pdev); + return soc->ops->ctrl_ops->txrx_get_pldev(soc, pdev_id); +} + +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * cdp_cfr_filter() - Configure Host RX monitor status ring for CFR + * @soc: SOC TXRX handle + * @pdev_id: ID of the physical device object + * @enable: Enable or disable CFR + * @filter_val: Flag to select filter for monitor mode + */ +static inline void +cdp_cfr_filter(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_cfr_filter) + return; + + soc->ops->cfr_ops->txrx_cfr_filter(soc, pdev_id, enable, filter_val); } +/** + * cdp_get_cfr_rcc() - get cfr rcc config + * @soc: Datapath soc handle + * @pdev_id: id of objmgr pdev + * + * Return: true/false based on cfr mode setting + */ +static inline +bool cdp_get_cfr_rcc(ol_txrx_soc_handle soc, uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return 0; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_get_cfr_rcc) + return 0; + + return soc->ops->cfr_ops->txrx_get_cfr_rcc(soc, pdev_id); +} + +/** + * cdp_set_cfr_rcc() - enable/disable cfr rcc config + * @soc: Datapath soc handle + * @pdev_id: id of objmgr pdev + * @enable: Enable/Disable cfr rcc mode + * + * Return: none + */ +static inline +void cdp_set_cfr_rcc(ol_txrx_soc_handle soc, uint8_t pdev_id, bool enable) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_set_cfr_rcc) + return; + + return soc->ops->cfr_ops->txrx_set_cfr_rcc(soc, pdev_id, enable); +} + +/** + * cdp_get_cfr_dbg_stats() - Get debug statistics for CFR + * + * @soc: SOC TXRX handle + * @pdev_id: ID of the physical device object + * @buf: CFR RCC debug statistics buffer + * + * Return: None + */ +static inline void +cdp_get_cfr_dbg_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct cdp_cfr_rcc_stats *buf) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_get_cfr_dbg_stats) + return; + + soc->ops->cfr_ops->txrx_get_cfr_dbg_stats(soc, pdev_id, buf); +} + +/** + * cdp_cfr_clr_dbg_stats() - Clear debug statistics for CFR + * + * @soc: SOC TXRX handle + * @pdev_id: ID of the physical device object + */ +static inline void +cdp_cfr_clr_dbg_stats(ol_txrx_soc_handle soc, uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_clear_cfr_dbg_stats) + return; + + soc->ops->cfr_ops->txrx_clear_cfr_dbg_stats(soc, pdev_id); +} + +/** + * cdp_enable_mon_reap_timer() - enable/disable reap timer + * @soc: Datapath soc handle + * @pdev_id: id of objmgr pdev + * @enable: enable/disable reap timer of monitor status ring + * + * Return: none + */ +static inline void +cdp_enable_mon_reap_timer(ol_txrx_soc_handle soc, uint8_t pdev_id, + bool enable) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || + !soc->ops->cfr_ops->txrx_enable_mon_reap_timer) + return; + + return soc->ops->cfr_ops->txrx_enable_mon_reap_timer(soc, pdev_id, + enable); +} +#endif + +#if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) +/** + * cdp_update_peer_pkt_capture_params() - Sets Rx & Tx Capture params for a peer + * @soc: SOC TXRX handle + * @pdev_id: id of CDP pdev pointer + * @is_rx_pkt_cap_enable: enable/disable rx pkt capture for this peer + * @is_tx_pkt_cap_enable: enable/disable tx pkt capture for this peer + * @peer_mac: MAC address of peer for which pkt_cap is to be enabled/disabled + * + * Return: Success when matching peer is found & flags are set, error otherwise + */ +static inline QDF_STATUS +cdp_update_peer_pkt_capture_params(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool is_rx_pkt_cap_enable, + bool is_tx_pkt_cap_enable, + uint8_t *peer_mac) +{ + if (!soc || !soc->ops) { + dp_err("Invalid SOC instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_update_peer_pkt_capture_params) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_update_peer_pkt_capture_params + (soc, pdev_id, is_rx_pkt_cap_enable, + is_tx_pkt_cap_enable, + peer_mac); +} +#endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */ + #ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG /** * cdp_update_pdev_rx_protocol_tag() - wrapper function to set the protocol * tag in CDP layer from cfg layer * @soc: SOC TXRX handle - * @pdev: CDP pdev pointer + * @pdev_id: id of CDP pdev pointer * @protocol_mask: Bitmap for protocol for which tagging is enabled * @protocol_type: Protocol type for which the tag should be update * @tag: Actual tag value for the given prototype @@ -716,7 +1017,7 @@ cdp_get_pldev(ol_txrx_soc_handle soc, */ static inline QDF_STATUS cdp_update_pdev_rx_protocol_tag(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint32_t protocol_mask, + uint8_t pdev_id, uint32_t protocol_mask, uint16_t protocol_type, uint16_t tag) { if (!soc || !soc->ops) { @@ -730,7 +1031,7 @@ cdp_update_pdev_rx_protocol_tag(ol_txrx_soc_handle soc, return QDF_STATUS_E_FAILURE; return soc->ops->ctrl_ops->txrx_update_pdev_rx_protocol_tag - (pdev, protocol_mask, protocol_type, tag); + (soc, pdev_id, protocol_mask, protocol_type, tag); } #ifdef WLAN_SUPPORT_RX_TAG_STATISTICS @@ -738,13 +1039,13 @@ cdp_update_pdev_rx_protocol_tag(ol_txrx_soc_handle soc, * cdp_dump_pdev_rx_protocol_tag_stats() - wrapper function to dump the protocol tag statistics for given or all protocols * @soc: SOC TXRX handle - * @pdev: CDP pdev pointer + * @pdev_id: id of CDP pdev pointer * @protocol_type: Protocol type for which the tag should be update * Return: Returns QDF_STATUS_SUCCESS/FAILURE */ static inline QDF_STATUS cdp_dump_pdev_rx_protocol_tag_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, uint16_t protocol_type) { if (!soc || !soc->ops) { @@ -757,7 +1058,7 @@ cdp_dump_pdev_rx_protocol_tag_stats(ol_txrx_soc_handle soc, !soc->ops->ctrl_ops->txrx_dump_pdev_rx_protocol_tag_stats) return QDF_STATUS_E_FAILURE; - soc->ops->ctrl_ops->txrx_dump_pdev_rx_protocol_tag_stats(pdev, + soc->ops->ctrl_ops->txrx_dump_pdev_rx_protocol_tag_stats(soc, pdev_id, protocol_type); return QDF_STATUS_SUCCESS; } @@ -768,7 +1069,7 @@ cdp_dump_pdev_rx_protocol_tag_stats(ol_txrx_soc_handle soc, /** * cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config * @soc: soc pointer - * @vdev: vdev pointer + * @vdev_id: id of vdev * @nac_cmd: specfies nac_rss config action add, del, list * @bssid: Neighbour bssid * @client_macaddr: Non-Associated client MAC @@ -777,7 +1078,7 @@ cdp_dump_pdev_rx_protocol_tag_stats(ol_txrx_soc_handle soc, * Return: QDF_STATUS */ static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, enum cdp_nac_param_cmd nac_cmd, + uint8_t vdev_id, enum cdp_nac_param_cmd nac_cmd, char *bssid, char *client_macaddr, uint8_t chan_num) { if (!soc || !soc->ops) { @@ -791,21 +1092,21 @@ static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc, !soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi) return QDF_STATUS_E_FAILURE; - return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev, + return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(soc, vdev_id, nac_cmd, bssid, client_macaddr, chan_num); } /* * cdp_vdev_get_neighbour_rssi(): To invoke dp callback to get rssi value of nac * @soc: soc pointer - * @vdev: vdev pointer + * @vdev_id: id of vdev * @macaddr: Non-Associated client MAC * @rssi: rssi * * Return: QDF_STATUS */ static inline QDF_STATUS cdp_vdev_get_neighbour_rssi(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, char *macaddr, uint8_t *rssi) { @@ -820,8 +1121,66 @@ static inline QDF_STATUS cdp_vdev_get_neighbour_rssi(ol_txrx_soc_handle soc, !soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi) return QDF_STATUS_E_FAILURE; - return soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi(vdev, macaddr, + return soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi(soc, vdev_id, + macaddr, rssi); } #endif -#endif + +#ifdef WLAN_SUPPORT_RX_FLOW_TAG +/** + * cdp_set_rx_flow_tag() - wrapper function to set the flow + * tag in CDP layer from cfg layer + * @soc: SOC TXRX handle + * @pdev_id: id of CDP pdev pointer + * @flow_info: Flow 5-tuple, along with tag, if any, that needs to added/deleted + * + * Return: Success when add/del operation is successful, error otherwise + */ +static inline QDF_STATUS +cdp_set_rx_flow_tag(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info) +{ + if (!soc || !soc->ops) { + dp_err("Invalid SOC instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_set_rx_flow_tag) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_set_rx_flow_tag(soc, pdev_id, + flow_info); +} + +/** + * cdp_dump_rx_flow_tag_stats() - wrapper function to dump the flow + * tag statistics for given flow + * @soc: SOC TXRX handle + * @pdev_id: id of CDP pdev + * @flow_info: Flow tuple for which we want to print the statistics + * + * Return: Success when flow is found and stats are printed, error otherwise + */ +static inline QDF_STATUS +cdp_dump_rx_flow_tag_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info) +{ + if (!soc || !soc->ops) { + dp_err("Invalid SOC instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_dump_rx_flow_tag_stats) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_dump_rx_flow_tag_stats(soc, + pdev_id, + flow_info); +} +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ +#endif /* _CDP_TXRX_CTRL_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h index a0811af57a457811900b5cf8a7ab523351c29f43..1a922f6b7e6ed5dc51f9b7cf844ce93b0c13b09b 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016,2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016,2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -73,9 +73,9 @@ void ol_ll_pdev_tx_unlock(void *); #else #define OSIF_VAP_TX_LOCK(_y, _x) cdp_vdev_tx_lock( \ - _y, wlan_vdev_get_dp_handle((_x)->ctrl_vdev)) + _y, wlan_vdev_get_id((_x)->ctrl_vdev)) #define OSIF_VAP_TX_UNLOCK(_y, _x) cdp_vdev_tx_unlock( \ - _y, wlan_vdev_get_dp_handle((_x)->ctrl_vdev)) + _y, wlan_vdev_get_id((_x)->ctrl_vdev)) #define OL_TX_FLOW_CTRL_LOCK(_x) #define OL_TX_FLOW_CTRL_UNLOCK(_x) diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h index d0ac40cb0b9ce3ce7b22f95134155e6e1e9b8a45..b00b905d3a9f7d8f1a9258f76f65b79bc410b463 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,13 +30,17 @@ /** * cdp_hl_fc_register() - Register HL flow control callback. - * @soc - data path soc handle - * @flowcontrol - callback function pointer to stop/start OS netdev queues + * @soc: data path soc handle + * @pdev_id: datapath pdev identifier + * @flowcontrol: callback function pointer to stop/start OS netdev queues + * * Register flow control callback. - * return 0 success + * + * Returns: 0 for success */ static inline int -cdp_hl_fc_register(ol_txrx_soc_handle soc, tx_pause_callback flowcontrol) +cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id, + tx_pause_callback flowcontrol) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -49,17 +53,18 @@ cdp_hl_fc_register(ol_txrx_soc_handle soc, tx_pause_callback flowcontrol) !soc->ops->l_flowctl_ops->register_tx_flow_control) return -EINVAL; - return soc->ops->l_flowctl_ops->register_tx_flow_control(soc, + return soc->ops->l_flowctl_ops->register_tx_flow_control(soc, pdev_id, flowcontrol); } static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc, - uint8_t vdev_id, uint8_t chan) + uint8_t vdev_id, uint32_t chan_freq) { if (!soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit) return 0; - return soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit(vdev_id, chan); + return soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit(soc, vdev_id, + chan_freq); } static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc, @@ -69,18 +74,20 @@ static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc, if (!soc->ops->l_flowctl_ops->set_vdev_os_queue_status) return -EINVAL; - return soc->ops->l_flowctl_ops->set_vdev_os_queue_status(vdev_id, + return soc->ops->l_flowctl_ops->set_vdev_os_queue_status(soc, + vdev_id, action); } #else static inline int -cdp_hl_fc_register(ol_txrx_soc_handle soc, tx_pause_callback flowcontrol) +cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id, + tx_pause_callback flowcontrol) { return 0; } static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc, - uint8_t vdev_id, uint8_t chan) + uint8_t vdev_id, uint32_t chan_freq) { return 0; } @@ -109,7 +116,7 @@ static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc, */ static inline int cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id, - ol_txrx_tx_flow_control_fp flowControl, void *osif_fc_ctx, + ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx, ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause) { if (!soc || !soc->ops) { @@ -124,7 +131,7 @@ cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id, return 0; return soc->ops->l_flowctl_ops->register_tx_flow_control( - vdev_id, flowControl, osif_fc_ctx, + soc, vdev_id, flowcontrol, osif_fc_ctx, flow_control_is_pause); } #else @@ -160,15 +167,16 @@ cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id) return 0; return soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb( - vdev_id); + soc, vdev_id); } /** * cdp_fc_get_tx_resource() - get data path resource count - * @soc - data path soc handle - * @sta_id - local peer id - * @low_watermark - low resource threshold - * @high_watermark_offset - high resource threshold + * @soc: data path soc handle + * @pdev_id: datapath pdev ID + * @peer_addr: peer mac address + * @low_watermark: low resource threshold + * @high_watermark_offset: high resource threshold * * get data path resource count * @@ -176,8 +184,10 @@ cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id) * false resource is not avaialbe */ static inline bool -cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t sta_id, - unsigned int low_watermark, unsigned int high_watermark_offset) +cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct qdf_mac_addr peer_addr, + unsigned int low_watermark, + unsigned int high_watermark_offset) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -190,8 +200,9 @@ cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t sta_id, !soc->ops->l_flowctl_ops->get_tx_resource) return false; - return soc->ops->l_flowctl_ops->get_tx_resource(sta_id, - low_watermark, high_watermark_offset); + return soc->ops->l_flowctl_ops->get_tx_resource(soc, pdev_id, peer_addr, + low_watermark, + high_watermark_offset); } /** @@ -220,21 +231,21 @@ cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc, return 0; return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth( - vdev_id, pause_q_depth); + soc, vdev_id, pause_q_depth); } /** * cdp_fc_vdev_flush() - flush tx queue - * @soc - data path soc handle - * @vdev - virtual interface context pointer + * @soc: data path soc handle + * @vdev_id: id of vdev * * flush tx queue * * return None */ static inline void -cdp_fc_vdev_flush(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +cdp_fc_vdev_flush(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -247,22 +258,23 @@ cdp_fc_vdev_flush(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) !soc->ops->l_flowctl_ops->vdev_flush) return; - soc->ops->l_flowctl_ops->vdev_flush(vdev); + soc->ops->l_flowctl_ops->vdev_flush(soc, vdev_id); } /** * cdp_fc_vdev_pause() - pause tx scheduler on vdev - * @soc - data path soc handle - * @vdev - virtual interface context pointer - * @reason - pause reason + * @soc: data path soc handle + * @vdev_id: id of vdev + * @reason: pause reason + * @pause_type: type of pause * * pause tx scheduler on vdev * * return None */ static inline void -cdp_fc_vdev_pause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - uint32_t reason) +cdp_fc_vdev_pause(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -275,22 +287,23 @@ cdp_fc_vdev_pause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->l_flowctl_ops->vdev_pause) return; - soc->ops->l_flowctl_ops->vdev_pause(vdev, reason); + soc->ops->l_flowctl_ops->vdev_pause(soc, vdev_id, reason, pause_type); } /** * cdp_fc_vdev_unpause() - resume tx scheduler on vdev - * @soc - data path soc handle - * @vdev - virtual interface context pointer - * @reason - pause reason + * @soc: data path soc handle + * @vdev_id: id of vdev + * @reason: pause reason + * @pause_type: type of pause * * resume tx scheduler on vdev * * return None */ static inline void -cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - uint32_t reason) +cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -302,6 +315,7 @@ cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, !soc->ops->l_flowctl_ops->vdev_unpause) return; - soc->ops->l_flowctl_ops->vdev_unpause(vdev, reason); + soc->ops->l_flowctl_ops->vdev_unpause(soc, vdev_id, reason, + pause_type); } #endif /* _CDP_TXRX_FC_LEG_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h index 9ef5cb5685d7a48a158be4ac7ff01497ca5593fe..630b8b9060116a08e9ab8d449eef8cb933fd17eb 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -92,8 +92,6 @@ cdp_set_desc_global_pool_size(ol_txrx_soc_handle soc, static inline void cdp_dump_flow_pool_info(struct cdp_soc_t *soc) { - void *dp_soc = (void *)soc; - if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s invalid instance", __func__); @@ -105,18 +103,18 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc) !soc->ops->flowctl_ops->dump_flow_pool_info) return; - soc->ops->flowctl_ops->dump_flow_pool_info(dp_soc); + soc->ops->flowctl_ops->dump_flow_pool_info(soc); } /** * cdp_tx_desc_thresh_reached() - Check if avail tx desc meet threshold - * @soc - data path soc handle - * @vdev - dp vdev handle + * @soc: data path soc handle + * @vdev_id: vdev_id corresponding to vdev start * * Return: true if threshold is met, false if not */ static inline bool -cdp_tx_desc_thresh_reached(struct cdp_soc_t *soc, struct cdp_vdev *vdev) +cdp_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -129,6 +127,6 @@ cdp_tx_desc_thresh_reached(struct cdp_soc_t *soc, struct cdp_vdev *vdev) !soc->ops->flowctl_ops->tx_desc_thresh_reached) return false; - return soc->ops->flowctl_ops->tx_desc_thresh_reached(vdev); + return soc->ops->flowctl_ops->tx_desc_thresh_reached(soc, vdev_id); } #endif /* _CDP_TXRX_FC_V2_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h index 8b59efc18b2ea9235a086ef6c20f931917522672..a3e448eb3e1bea4ddc8138aaca29c0a0eedd62a6 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,6 +33,11 @@ struct cdp_peer; struct cdp_raw_ast; struct cdp_soc; +/** + * cdp_ctrl_objmgr_psoc - opaque handle for UMAC psoc object + */ +struct cdp_ctrl_objmgr_psoc; + /** * cdp_ctrl_objmgr_pdev - opaque handle for UMAC pdev object */ @@ -48,4 +53,13 @@ struct cdp_ctrl_objmgr_vdev; */ struct cdp_ctrl_objmgr_peer; +/** + * cdp_cal_client - opaque handle for cal client object + */ +struct cdp_cal_client; + +/** + * cdp_ext_vdev - opaque handle for extended vdev data path handle + */ +struct cdp_ext_vdev; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h index 9a18113a63122a6814a1aa87028c383174dcdb2b..5db10b26e10e58ff608978dd1f8653a8ab40f90f 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,15 +24,17 @@ #ifndef _CDP_TXRX_HOST_STATS_H_ #define _CDP_TXRX_HOST_STATS_H_ #include "cdp_txrx_handle.h" +#include /** * cdp_host_stats_get: cdp call to get host stats * @soc: SOC handle + * @vdev_id: vdev id of vdev * @req: Requirement type * * return: 0 for Success, Failure returns error message */ static inline int cdp_host_stats_get(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, struct ol_txrx_stats_req *req) { if (!soc || !soc->ops) { @@ -46,7 +48,7 @@ static inline int cdp_host_stats_get(ol_txrx_soc_handle soc, !soc->ops->host_stats_ops->txrx_host_stats_get) return 0; - return soc->ops->host_stats_ops->txrx_host_stats_get(vdev, req); + return soc->ops->host_stats_ops->txrx_host_stats_get(soc, vdev_id, req); } /** @@ -81,46 +83,47 @@ static inline int cdp_host_stats_get_ratekbps(ol_txrx_soc_handle soc, /** * cdp_host_stats_clr: cdp call to clear host stats - * @vdev: vdev handle + * @soc: soc handle + * @vdev_id: vdev handle id * - * return: void + * return: QDF_STATUS */ -static inline void -cdp_host_stats_clr(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_host_stats_clr(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_host_stats_clr) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->txrx_host_stats_clr(vdev); + return soc->ops->host_stats_ops->txrx_host_stats_clr(soc, vdev_id); } -static inline void -cdp_host_ce_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_host_ce_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_host_ce_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->txrx_host_ce_stats(vdev); + return soc->ops->host_stats_ops->txrx_host_ce_stats(soc, vdev_id); } static inline int cdp_stats_publish - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, + (ol_txrx_soc_handle soc, uint8_t pdev_id, struct cdp_stats_extd *buf) { if (!soc || !soc->ops) { @@ -134,204 +137,176 @@ static inline int cdp_stats_publish !soc->ops->host_stats_ops->txrx_stats_publish) return 0; - return soc->ops->host_stats_ops->txrx_stats_publish(pdev, buf); + return soc->ops->host_stats_ops->txrx_stats_publish(soc, pdev_id, buf); } /** * @brief Enable enhanced stats functionality. * - * @param pdev - the physical device object - * @return - void + * @param soc - the soc object + * @param pdev_id - id of the physical device object + * @return - QDF_STATUS */ -static inline void -cdp_enable_enhanced_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +static inline QDF_STATUS +cdp_enable_enhanced_stats(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_enable_enhanced_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->txrx_enable_enhanced_stats - (pdev); + return soc->ops->host_stats_ops->txrx_enable_enhanced_stats + (soc, pdev_id); } /** * @brief Disable enhanced stats functionality. * - * @param pdev - the physical device object - * @return - void + * @param soc - the soc object + * @param pdev_id - id of the physical device object + * @return - QDF_STATUS */ -static inline void -cdp_disable_enhanced_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +static inline QDF_STATUS +cdp_disable_enhanced_stats(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_disable_enhanced_stats) - return; - - soc->ops->host_stats_ops->txrx_disable_enhanced_stats - (pdev); -} - -/** - * @brief Get the desired stats from the message. - * - * @param pdev - the physical device object - * @param stats_base - stats buffer received from FW - * @param type - stats type. - * @return - pointer to requested stat identified by type - */ -static inline uint32_t *cdp_get_stats_base - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint32_t *stats_base, uint32_t msg_len, uint8_t type) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->host_stats_ops || - !soc->ops->host_stats_ops->txrx_get_stats_base) - return 0; + return QDF_STATUS_E_FAILURE; - return (uint32_t *)soc->ops->host_stats_ops->txrx_get_stats_base - (pdev, stats_base, msg_len, type); + return soc->ops->host_stats_ops->txrx_disable_enhanced_stats + (soc, pdev_id); } -static inline void -cdp_tx_print_tso_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_tx_print_tso_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->tx_print_tso_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->tx_print_tso_stats(vdev); + return soc->ops->host_stats_ops->tx_print_tso_stats(soc, vdev_id); } -static inline void -cdp_tx_rst_tso_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_tx_rst_tso_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->tx_rst_tso_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->tx_rst_tso_stats(vdev); + return soc->ops->host_stats_ops->tx_rst_tso_stats(soc, vdev_id); } -static inline void -cdp_tx_print_sg_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_tx_print_sg_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->tx_print_sg_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->tx_print_sg_stats(vdev); + return soc->ops->host_stats_ops->tx_print_sg_stats(soc, vdev_id); } -static inline void -cdp_tx_rst_sg_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_tx_rst_sg_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->tx_rst_sg_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->tx_rst_sg_stats(vdev); + return soc->ops->host_stats_ops->tx_rst_sg_stats(soc, vdev_id); } -static inline void -cdp_print_rx_cksum_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_print_rx_cksum_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->print_rx_cksum_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->print_rx_cksum_stats(vdev); + return soc->ops->host_stats_ops->print_rx_cksum_stats(soc, vdev_id); } -static inline void -cdp_rst_rx_cksum_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_rst_rx_cksum_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->rst_rx_cksum_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->rst_rx_cksum_stats(vdev); + return soc->ops->host_stats_ops->rst_rx_cksum_stats(soc, vdev_id); } -static inline A_STATUS -cdp_host_me_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS +cdp_host_me_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return 0; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_host_me_stats) - return 0; + return QDF_STATUS_E_FAILURE; - return soc->ops->host_stats_ops->txrx_host_me_stats(vdev); + return soc->ops->host_stats_ops->txrx_host_me_stats(soc, vdev_id); } /** @@ -342,25 +317,25 @@ cdp_host_me_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) * * return: status */ -static inline void cdp_per_peer_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, char *addr) +static inline QDF_STATUS cdp_per_peer_stats(ol_txrx_soc_handle soc, + uint8_t *addr) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_per_peer_stats) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->txrx_per_peer_stats(pdev, addr); + return soc->ops->host_stats_ops->txrx_per_peer_stats(soc, addr); } static inline int cdp_host_msdu_ttl_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, struct ol_txrx_stats_req *req) { if (!soc || !soc->ops) { @@ -375,106 +350,113 @@ static inline int cdp_host_msdu_ttl_stats(ol_txrx_soc_handle soc, return 0; return soc->ops->host_stats_ops->txrx_host_msdu_ttl_stats - (vdev, req); + (soc, vdev_id, req); } -static inline void -cdp_print_lro_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS cdp_update_peer_stats(ol_txrx_soc_handle soc, + uint8_t vdev_id, uint8_t *mac, + void *stats, + uint32_t last_tx_rate_mcs, + uint32_t stats_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || - !soc->ops->host_stats_ops->print_lro_stats) - return; + !soc->ops->host_stats_ops->txrx_update_peer_stats) + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->print_lro_stats(vdev); + return soc->ops->host_stats_ops->txrx_update_peer_stats + (soc, vdev_id, mac, stats, last_tx_rate_mcs, stats_id); } -static inline void -cdp_reset_lro_stats(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +static inline QDF_STATUS cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, + uint8_t pdev_id, + uint8_t *mac, uint32_t caps, + uint32_t copy_stats) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || - !soc->ops->host_stats_ops->reset_lro_stats) - return; + !soc->ops->host_stats_ops->get_fw_peer_stats) + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->reset_lro_stats(vdev); + return soc->ops->host_stats_ops->get_fw_peer_stats + (soc, pdev_id, mac, caps, copy_stats); } -static inline void cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t *mac, uint32_t caps, - uint32_t copy_stats) +static inline QDF_STATUS cdp_get_dp_htt_stats(ol_txrx_soc_handle soc, + uint8_t pdev_id, + void *data, uint32_t data_len) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); + "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || - !soc->ops->host_stats_ops->get_fw_peer_stats) - return; + !soc->ops->host_stats_ops->get_htt_stats) + return QDF_STATUS_E_FAILURE; - soc->ops->host_stats_ops->get_fw_peer_stats - (pdev, mac, caps, copy_stats); -} - -static inline void cdp_get_dp_htt_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, - void *data, uint32_t data_len) -{ - if (soc && soc->ops && soc->ops->host_stats_ops && - soc->ops->host_stats_ops->get_htt_stats) - return soc->ops->host_stats_ops->get_htt_stats - (pdev, data, data_len); - return; + return soc->ops->host_stats_ops->get_htt_stats(soc, pdev_id, data, + data_len); } /** * @brief Update pdev host stats received from firmware * (wmi_host_pdev_stats and wmi_host_pdev_ext_stats) into dp * - * @param pdev - the physical device object + * @param soc - soc handle + * @param pdev_id - id of the physical device object * @param data - pdev stats - * @return - void + * @return - QDF_STATUS */ -static inline void +static inline QDF_STATUS cdp_update_pdev_host_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, void *data, uint16_t stats_id) { - if (soc && soc->ops && soc->ops->host_stats_ops && - soc->ops->host_stats_ops->txrx_update_pdev_stats) - return soc->ops->host_stats_ops->txrx_update_pdev_stats - (pdev, data, stats_id); + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_update_pdev_stats) + return QDF_STATUS_E_FAILURE; + + return soc->ops->host_stats_ops->txrx_update_pdev_stats(soc, pdev_id, + data, + stats_id); } /** * @brief Update vdev host stats * - * @param soc - soc handle - * @param vdev - the physical device object - * @param data - pdev stats - * @param stats_id - type of stats + * @soc: soc handle + * @vdev_id: id of the virtual device object + * @data: pdev stats + * @stats_id: type of stats * - * @return - void + * Return: QDF_STATUS */ -static inline void +static inline QDF_STATUS cdp_update_vdev_host_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, void *data, uint16_t stats_id) { @@ -482,98 +464,148 @@ cdp_update_vdev_host_stats(ol_txrx_soc_handle soc, QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_update_vdev_stats) - return; + return QDF_STATUS_E_FAILURE; - return soc->ops->host_stats_ops->txrx_update_vdev_stats(vdev, data, + return soc->ops->host_stats_ops->txrx_update_vdev_stats(soc, vdev_id, + data, stats_id); } +/** + * @brief Call to get specified peer stats + * + * @param soc - soc handle + * @param vdev_id - vdev_id of vdev object + * @param peer_mac - mac address of the peer + * @param type - enum of required stats + * @param buf - buffer to hold the value + * @return - QDF_STATUS + */ +static inline QDF_STATUS +cdp_txrx_get_peer_stats_param(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_stats_type type, + cdp_peer_stats_param_t *buf) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->host_stats_ops || + !soc->ops->host_stats_ops->txrx_get_peer_stats_param) + return QDF_STATUS_E_FAILURE; + + return soc->ops->host_stats_ops->txrx_get_peer_stats_param(soc, + vdev_id, + peer_mac, + type, + buf); +} + /** * @brief Call to get peer stats * - * @param peer - dp peer object + * @param soc - soc handle + * @param vdev_id - vdev_id of vdev object + * @param peer_mac - mac address of the peer * @return - struct cdp_peer_stats */ -static inline struct cdp_peer_stats * -cdp_host_get_peer_stats(ol_txrx_soc_handle soc, struct cdp_peer *peer) +static inline QDF_STATUS +cdp_host_get_peer_stats(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_peer_stats *peer_stats) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return NULL; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_get_peer_stats) - return NULL; + return QDF_STATUS_E_FAILURE; - return soc->ops->host_stats_ops->txrx_get_peer_stats(peer); + return soc->ops->host_stats_ops->txrx_get_peer_stats(soc, vdev_id, + peer_mac, + peer_stats); } /** * @brief Call to reset ald stats * - * @param peer - dp peer object + * @param soc - soc handle + * @param vdev_id - vdev_id of vdev object + * @param peer_mac - mac address of the peer * @return - void */ -static inline void -cdp_host_reset_peer_ald_stats(ol_txrx_soc_handle soc, - struct cdp_peer *peer) +static inline QDF_STATUS +cdp_host_reset_peer_ald_stats(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_reset_peer_ald_stats) - return; + return QDF_STATUS_E_FAILURE; - return soc->ops->host_stats_ops->txrx_reset_peer_ald_stats(peer); + return soc->ops->host_stats_ops->txrx_reset_peer_ald_stats(soc, + vdev_id, + peer_mac); } /** * @brief Call to reset peer stats * - * @param peer - dp peer object - * @return - void + * @param soc - soc handle + * @param vdev_id - vdev_id of vdev object + * @param peer_mac - mac address of the peer + * @return - QDF_STATUS */ -static inline void +static inline QDF_STATUS cdp_host_reset_peer_stats(ol_txrx_soc_handle soc, - struct cdp_peer *peer) + uint8_t vdev_id, uint8_t *peer_mac) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->host_stats_ops || !soc->ops->host_stats_ops->txrx_reset_peer_stats) - return; + return QDF_STATUS_E_FAILURE; - return soc->ops->host_stats_ops->txrx_reset_peer_stats(peer); + return soc->ops->host_stats_ops->txrx_reset_peer_stats(soc, + vdev_id, + peer_mac); } /** * @brief Call to get vdev stats * - * @param vdev - dp vdev object + * @param soc - dp soc object + * @param vdev_id - id of dp vdev object * @param buf - buffer * @return - int */ static inline int cdp_host_get_vdev_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, struct cdp_vdev_stats *buf, bool is_aggregate) { @@ -588,7 +620,7 @@ cdp_host_get_vdev_stats(ol_txrx_soc_handle soc, !soc->ops->host_stats_ops->txrx_get_vdev_stats) return 0; - return soc->ops->host_stats_ops->txrx_get_vdev_stats(vdev, + return soc->ops->host_stats_ops->txrx_get_vdev_stats(soc, vdev_id, buf, is_aggregate); } @@ -629,14 +661,15 @@ cdp_update_host_vdev_stats(ol_txrx_soc_handle soc, /** * @brief Call to get vdev extd stats * - * @param vdev - dp vdev object + * @param soc - soc handle + * @param vdev_id - id of dp vdev object * @param buf - buffer * @return - int */ static inline int cdp_get_vdev_extd_stats(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, - void *buf) + uint8_t vdev_id, + wmi_host_vdev_extd_stats *buf) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -649,18 +682,21 @@ cdp_get_vdev_extd_stats(ol_txrx_soc_handle soc, !soc->ops->host_stats_ops->txrx_get_vdev_extd_stats) return 0; - return soc->ops->host_stats_ops->txrx_get_vdev_extd_stats(vdev, buf); + return soc->ops->host_stats_ops->txrx_get_vdev_extd_stats(soc, vdev_id, + buf); } /** * @brief Call to get cdp_pdev_stats * - * @param pdev - dp pdev object - * @return - cdp_pdev_stats + * @param soc - soc handle + * @param pdev_id - id of dp pdev object + * @param buf - buffer to hold cdp_pdev_stats + * @return - success/failure */ -static inline struct cdp_pdev_stats* +static inline int cdp_host_get_pdev_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) + uint8_t pdev_id, struct cdp_pdev_stats *buf) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -673,19 +709,20 @@ cdp_host_get_pdev_stats(ol_txrx_soc_handle soc, !soc->ops->host_stats_ops->txrx_get_pdev_stats) return 0; - return soc->ops->host_stats_ops->txrx_get_pdev_stats(pdev); + return soc->ops->host_stats_ops->txrx_get_pdev_stats(soc, pdev_id, buf); } /** * @brief Call to get radio stats * - * @param pdev - dp pdev object + * @param soc - soc handle + * @param pdev_id - id of dp pdev object * @param scn_stats_user - stats buffer * @return - int */ static inline int cdp_host_get_radio_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, void *buf) { if (!soc || !soc->ops) { @@ -699,47 +736,7 @@ cdp_host_get_radio_stats(ol_txrx_soc_handle soc, !soc->ops->host_stats_ops->txrx_get_radio_stats) return 0; - return soc->ops->host_stats_ops->txrx_get_radio_stats(pdev, + return soc->ops->host_stats_ops->txrx_get_radio_stats(soc, pdev_id, buf); } - -/** - * @brief confgure rate stats at soc - * - * @param soc - opaque soc handle - * @param vap - capabilities - * @return - void - */ -static inline void -cdp_soc_configure_rate_stats(ol_txrx_soc_handle soc, uint8_t val) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->host_stats_ops || - !soc->ops->host_stats_ops->configure_rate_stats) - return; - - return soc->ops->host_stats_ops->configure_rate_stats(soc, val); -} - -/** - * @brief Parse the stats header and get the payload from the message. - * - * @param pdev - the physical device object - * @param msg_word - stats buffer received from FW - * @param msg_len - length of the message - * @param type - place holder for parsed message type - * @param status - place holder for parsed message status - * @return - pointer to received stat payload - */ - -#if defined(QCA_SUPPORT_SON) || defined(ENHANCED_STATS) -uint32_t *ol_txrx_get_en_stats_base(struct cdp_pdev *pdev, uint32_t *msg_word, - uint32_t msg_len, enum htt_cmn_t2h_en_stats_type *type, enum htt_cmn_t2h_en_stats_status *status); -#endif #endif /* _CDP_TXRX_HOST_STATS_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h index e989df69f036b5bc0e24b0bb68c87ef00c6a4198..9073aa90466692d24d04f5a243c967b3e9b095f2 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h @@ -35,23 +35,23 @@ /** * cdp_ipa_get_resource() - Get allocated WLAN resources for IPA data path * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * * Get allocated WLAN resources for IPA data path * * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_get_resource(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_get_resource(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_get_resource) - return soc->ops->ipa_ops->ipa_get_resource(pdev); + return soc->ops->ipa_ops->ipa_get_resource(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -59,23 +59,23 @@ cdp_ipa_get_resource(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) /** * cdp_ipa_set_doorbell_paddr() - give IPA db paddr to FW * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * * give IPA db paddr to FW * * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_set_doorbell_paddr) - return soc->ops->ipa_ops->ipa_set_doorbell_paddr(pdev); + return soc->ops->ipa_ops->ipa_set_doorbell_paddr(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -83,7 +83,7 @@ cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) /** * cdp_ipa_set_active() - activate/de-ctivate IPA offload path * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * @uc_active - activate or de-activate * @is_tx - toggle tx or rx data path * @@ -92,18 +92,18 @@ cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_set_active(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - bool uc_active, bool is_tx) +cdp_ipa_set_active(ol_txrx_soc_handle soc, uint8_t pdev_id, bool uc_active, + bool is_tx) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_set_active) - return soc->ops->ipa_ops->ipa_set_active(pdev, uc_active, - is_tx); + return soc->ops->ipa_ops->ipa_set_active(soc, pdev_id, + uc_active, is_tx); return QDF_STATUS_SUCCESS; } @@ -111,7 +111,7 @@ cdp_ipa_set_active(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_ipa_op_response() - event handler from FW * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * @op_msg - event contents from firmware * * event handler from FW @@ -119,17 +119,16 @@ cdp_ipa_set_active(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_op_response(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t *op_msg) +cdp_ipa_op_response(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t *op_msg) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_op_response) - return soc->ops->ipa_ops->ipa_op_response(pdev, op_msg); + return soc->ops->ipa_ops->ipa_op_response(soc, pdev_id, op_msg); return QDF_STATUS_SUCCESS; } @@ -137,7 +136,7 @@ cdp_ipa_op_response(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_ipa_register_op_cb() - register event handler function pointer * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * @op_cb - event handler callback function pointer * @usr_ctxt - user context to registered * @@ -146,18 +145,18 @@ cdp_ipa_op_response(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - ipa_uc_op_cb_type op_cb, void *usr_ctxt) +cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, uint8_t pdev_id, + ipa_uc_op_cb_type op_cb, void *usr_ctxt) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_register_op_cb) - return soc->ops->ipa_ops->ipa_register_op_cb(pdev, op_cb, - usr_ctxt); + return soc->ops->ipa_ops->ipa_register_op_cb(soc, pdev_id, + op_cb, usr_ctxt); return QDF_STATUS_SUCCESS; } @@ -165,52 +164,55 @@ cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_ipa_get_stat() - get IPA data path stats from FW * @soc - data path soc handle - * @pdev - device instance pointer + * @pdev_id - device instance id * * get IPA data path stats from FW async * * return QDF_STATUS_SUCCESS */ static inline QDF_STATUS -cdp_ipa_get_stat(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_get_stat(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_get_stat) - return soc->ops->ipa_ops->ipa_get_stat(pdev); + return soc->ops->ipa_ops->ipa_get_stat(soc, pdev_id); return QDF_STATUS_SUCCESS; } /** * cdp_tx_send_ipa_data_frame() - send IPA data frame - * @vdev: vdev + * @soc - data path soc handle + * @vdev_id: vdev id * @skb: skb * * Return: skb/ NULL is for success */ static inline qdf_nbuf_t cdp_ipa_tx_send_data_frame(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, qdf_nbuf_t skb) + uint8_t vdev_id, + qdf_nbuf_t skb) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !vdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return skb; } if (soc->ops->ipa_ops->ipa_tx_data_frame) - return soc->ops->ipa_ops->ipa_tx_data_frame(vdev, skb); + return soc->ops->ipa_ops->ipa_tx_data_frame(soc, vdev_id, skb); return skb; } /** * cdp_ipa_set_uc_tx_partition_base() - set tx packet partition base - * @pdev: physical device instance + * @soc - data path soc handle + * @cfg_pdev: physical device instance config * @value: partition base value * * Return: QDF_STATUS @@ -235,23 +237,24 @@ cdp_ipa_set_uc_tx_partition_base(ol_txrx_soc_handle soc, #ifdef FEATURE_METERING /** * cdp_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW - * @pdev: physical device instance + * @soc - data path soc handle + * @pdev_id: physical device instance number * @value: reset stats * * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_uc_get_share_stats(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint8_t value) +cdp_ipa_uc_get_share_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint8_t value) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_uc_get_share_stats) - return soc->ops->ipa_ops->ipa_uc_get_share_stats(pdev, + return soc->ops->ipa_ops->ipa_uc_get_share_stats(soc, pdev_id, value); return QDF_STATUS_SUCCESS; @@ -259,24 +262,23 @@ cdp_ipa_uc_get_share_stats(ol_txrx_soc_handle soc, /** * cdp_ipa_uc_set_quota() - set quota limit to FW - * @pdev: physical device instance + * @soc - data path soc handle + * @pdev_id: physical device instance number * @value: quota limit bytes * * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint64_t value) +cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, uint8_t pdev_id, uint64_t value) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_uc_set_quota) - return soc->ops->ipa_ops->ipa_uc_set_quota(pdev, - value); + return soc->ops->ipa_ops->ipa_uc_set_quota(soc, pdev_id, value); return QDF_STATUS_SUCCESS; } @@ -285,7 +287,7 @@ cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, /** * cdp_ipa_enable_autonomy() - Enable autonomy RX data path * @soc: data path soc handle - * @pdev: handle to the device instance + * @pdev_id: physical device instance number * * IPA Data path is enabled and resumed. * All autonomy data path elements are ready to deliver packet @@ -295,16 +297,16 @@ cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_enable_autonomy) - return soc->ops->ipa_ops->ipa_enable_autonomy(pdev); + return soc->ops->ipa_ops->ipa_enable_autonomy(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -312,7 +314,7 @@ cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) /** * cdp_ipa_disable_autonomy() - Disable autonomy RX data path * @soc: data path soc handle - * @pdev: handle to the device instance + * @pdev_id: physical device instance number * * IPA Data path is enabled and resumed. * All autonomy datapath elements are ready to deliver packet @@ -322,15 +324,15 @@ cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } - if (soc->ops->ipa_ops->ipa_enable_autonomy) - return soc->ops->ipa_ops->ipa_disable_autonomy(pdev); + if (soc->ops->ipa_ops->ipa_disable_autonomy) + return soc->ops->ipa_ops->ipa_disable_autonomy(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -339,7 +341,7 @@ cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) /** * cdp_ipa_setup() - Setup and connect IPA pipes * @soc: data path soc handle - * @pdev: handle to the device instance + * @pdev_id: handle to the device instance number * @ipa_i2w_cb: IPA to WLAN callback * @ipa_w2i_cb: WLAN to IPA callback * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback @@ -355,21 +357,21 @@ cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, +cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb, void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_setup) - return soc->ops->ipa_ops->ipa_setup(pdev, ipa_i2w_cb, + return soc->ops->ipa_ops->ipa_setup(soc, pdev_id, ipa_i2w_cb, ipa_w2i_cb, ipa_wdi_meter_notifier_cb, ipa_desc_size, ipa_priv, @@ -385,7 +387,7 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, /** * cdp_ipa_setup() - Setup and connect IPA pipes * @soc: data path soc handle - * @pdev: handle to the device instance + * @pdev_id: handle to the device instance number * @ipa_i2w_cb: IPA to WLAN callback * @ipa_w2i_cb: WLAN to IPA callback * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback @@ -398,19 +400,19 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, +cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb, void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_setup) - return soc->ops->ipa_ops->ipa_setup(pdev, ipa_i2w_cb, + return soc->ops->ipa_ops->ipa_setup(soc, pdev_id, ipa_i2w_cb, ipa_w2i_cb, ipa_wdi_meter_notifier_cb, ipa_desc_size, ipa_priv, @@ -425,14 +427,15 @@ cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, /** * cdp_ipa_cleanup() - Disconnect IPA pipes * @soc: data path soc handle + * @pdev_id: handle to the device instance number * @tx_pipe_handle: Tx pipe handle * @rx_pipe_handle: Rx pipe handle * * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint32_t tx_pipe_handle, - uint32_t rx_pipe_handle) +cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint32_t tx_pipe_handle, uint32_t rx_pipe_handle) { if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -441,7 +444,8 @@ cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint32_t tx_pipe_handle, } if (soc->ops->ipa_ops->ipa_cleanup) - return soc->ops->ipa_ops->ipa_cleanup(tx_pipe_handle, + return soc->ops->ipa_ops->ipa_cleanup(soc, pdev_id, + tx_pipe_handle, rx_pipe_handle); return QDF_STATUS_SUCCESS; @@ -508,22 +512,22 @@ cdp_ipa_cleanup_iface(ol_txrx_soc_handle soc, char *ifname, /** * cdp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes - * @soc: data path soc handle - * @pdev: handle to the device instance + * @soc - data path soc handle + * @pdev_id - device instance id * * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_enable_pipes(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_enable_pipes(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_enable_pipes) - return soc->ops->ipa_ops->ipa_enable_pipes(pdev); + return soc->ops->ipa_ops->ipa_enable_pipes(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -531,21 +535,21 @@ cdp_ipa_enable_pipes(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) /** * cdp_ipa_uc_disable_pipes() - Suspend traffic and disable Tx/Rx pipes * @soc: data path soc handle - * @pdev: handle to the device instance + * @pdev_id - device instance id * * Return: QDF_STATUS */ static inline QDF_STATUS -cdp_ipa_disable_pipes(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_ipa_disable_pipes(ol_txrx_soc_handle soc, uint8_t pdev_id) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { + if (!soc || !soc->ops || !soc->ops->ipa_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_disable_pipes) - return soc->ops->ipa_ops->ipa_disable_pipes(pdev); + return soc->ops->ipa_ops->ipa_disable_pipes(soc, pdev_id); return QDF_STATUS_SUCCESS; } @@ -579,7 +583,7 @@ cdp_ipa_set_perf_level(ol_txrx_soc_handle soc, int client, * cdp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path * * @soc: data path soc handle - * @vdev: vdev handle + * @vdev_id: vdev id * @nbuf: pointer to skb of ethernet packet received from IPA RX path * @fwd_success: pointer to indicate if skb succeeded in intra-bss TX * @@ -589,17 +593,18 @@ cdp_ipa_set_perf_level(ol_txrx_soc_handle soc, int client, * network stack. false if packet needs to be passed to network stack. */ static inline bool -cdp_ipa_rx_intrabss_fwd(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, +cdp_ipa_rx_intrabss_fwd(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t nbuf, bool *fwd_success) { - if (!soc || !soc->ops || !soc->ops->ipa_ops || !vdev || !fwd_success) { + if (!soc || !soc->ops || !soc->ops->ipa_ops || !fwd_success) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } if (soc->ops->ipa_ops->ipa_rx_intrabss_fwd) - return soc->ops->ipa_ops->ipa_rx_intrabss_fwd(vdev, nbuf, + return soc->ops->ipa_ops->ipa_rx_intrabss_fwd(soc, vdev_id, + nbuf, fwd_success); /* Fall back to pass up to stack */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h index f897febe745ee82b71643846f06355d8ec3e058e..010b4c383a8a4714b12560d7c2c22467ac52430e 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,67 +28,8 @@ /* TODO: adf need to be replaced with qdf */ #include "cdp_txrx_handle.h" -static inline u_int16_t -cdp_tx_desc_alloc_and_mark_for_mcast_clone(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, u_int16_t buf_count) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->me_ops || - !soc->ops->me_ops->tx_desc_alloc_and_mark_for_mcast_clone) - return 0; - - return soc->ops->me_ops-> - tx_desc_alloc_and_mark_for_mcast_clone - (pdev, buf_count); -} - -static inline u_int16_t -cdp_tx_desc_free_and_unmark_for_mcast_clone(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, u_int16_t buf_count) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->me_ops || - !soc->ops->me_ops->tx_desc_free_and_unmark_for_mcast_clone) - return 0; - - return soc->ops->me_ops-> - tx_desc_free_and_unmark_for_mcast_clone - (pdev, buf_count); -} - -static inline u_int16_t -cdp_tx_get_mcast_buf_allocated_marked(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->me_ops || - !soc->ops->me_ops->tx_get_mcast_buf_allocated_marked) - return 0; - - return soc->ops->me_ops->tx_get_mcast_buf_allocated_marked - (pdev); -} - static inline void -cdp_tx_me_alloc_descriptor(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_tx_me_alloc_descriptor(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -101,11 +42,11 @@ cdp_tx_me_alloc_descriptor(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) !soc->ops->me_ops->tx_me_alloc_descriptor) return; - soc->ops->me_ops->tx_me_alloc_descriptor(pdev); + soc->ops->me_ops->tx_me_alloc_descriptor(soc, pdev_id); } static inline void -cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -118,12 +59,13 @@ cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) !soc->ops->me_ops->tx_me_free_descriptor) return; - soc->ops->me_ops->tx_me_free_descriptor(pdev); + soc->ops->me_ops->tx_me_free_descriptor(soc, pdev_id); } static inline uint16_t -cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - qdf_nbuf_t wbuf, u_int8_t newmac[][6], uint8_t newmaccnt) +cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, uint8_t vdev_id, + qdf_nbuf_t wbuf, u_int8_t newmac[][6], + uint8_t newmaccnt) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -137,35 +79,7 @@ cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, return 0; return soc->ops->me_ops->tx_me_convert_ucast - (vdev, wbuf, newmac, newmaccnt); + (soc, vdev_id, wbuf, newmac, newmaccnt); } -/* Should be a function pointer in ol_txrx_osif_ops{} */ -/** - * @brief notify mcast frame indication from FW. - * @details - * This notification will be used to convert - * multicast frame to unicast. - * - * @param pdev - handle to the ctrl SW's physical device object - * @param vdev_id - ID of the virtual device received the special data - * @param msdu - the multicast msdu returned by FW for host inspect - */ - -static inline int cdp_mcast_notify(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, u_int8_t vdev_id, qdf_nbuf_t msdu) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; - } - - if (!soc->ops->me_ops || - !soc->ops->me_ops->mcast_notify) - return 0; - - return soc->ops->me_ops->mcast_notify(pdev, vdev_id, msdu); -} #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h index f5a97956340813211fb9a66b717b2d66d4dece75..1db265f6ffe06860fc5b0e703104fbcdf5b83f47 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h @@ -27,11 +27,10 @@ #include "cdp_txrx_handle.h" /** * cdp_tx_non_std() - Allow the control-path SW to send data frames - * - * @soc - data path soc handle - * @data_vdev - which vdev should transmit the tx data frames - * @tx_spec - what non-standard handling to apply to the tx data frames - * @msdu_list - NULL-terminated list of tx MSDUs + * @soc: data path soc handle + * @vdev_id: id of vdev + * @tx_spec: what non-standard handling to apply to the tx data frames + * @msdu_list: NULL-terminated list of tx MSDUs * * Generally, all tx data frames come from the OS shim into the txrx layer. * However, there are rare cases such as TDLS messaging where the UMAC @@ -49,8 +48,8 @@ * Return: null - success, skb - failure */ static inline qdf_nbuf_t -cdp_tx_non_std(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) +cdp_tx_non_std(ol_txrx_soc_handle soc, uint8_t vdev_id, + enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -59,23 +58,23 @@ cdp_tx_non_std(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, } if (soc->ops->misc_ops->tx_non_std) - return soc->ops->misc_ops->tx_non_std( - vdev, tx_spec, msdu_list); + return soc->ops->misc_ops->tx_non_std(soc, vdev_id, tx_spec, + msdu_list); return NULL; } /** * cdp_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart * beat timer - * @soc - data path soc handle - * @vdev - vdev handle - * @timer_value_sec - new heart beat timer value + * @soc: data path soc handle + * @vdev_id: id of vdev + * @timer_value_sec: new heart beat timer value * * Return: Old timer value set in vdev. */ static inline uint16_t cdp_set_ibss_vdev_heart_beat_timer(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint16_t timer_value_sec) + uint8_t vdev_id, uint16_t timer_value_sec) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -85,21 +84,21 @@ cdp_set_ibss_vdev_heart_beat_timer(ol_txrx_soc_handle soc, if (soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer) return soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer( - vdev, timer_value_sec); + soc, vdev_id, timer_value_sec); return 0; } /** * cdp_set_wisa_mode() - set wisa mode - * @soc - data path soc handle - * @vdev - vdev handle - * @enable - enable or disable + * @soc: data path soc handle + * @vdev_id: vdev_id + * @enable: enable or disable * * Return: QDF_STATUS_SUCCESS mode enable success */ static inline QDF_STATUS -cdp_set_wisa_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool enable) +cdp_set_wisa_mode(ol_txrx_soc_handle soc, uint8_t vdev_id, bool enable) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -108,20 +107,20 @@ cdp_set_wisa_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool enable) } if (soc->ops->misc_ops->set_wisa_mode) - return soc->ops->misc_ops->set_wisa_mode(vdev, enable); + return soc->ops->misc_ops->set_wisa_mode(soc, vdev_id, enable); return QDF_STATUS_SUCCESS; } /** * cdp_data_stall_cb_register() - register data stall callback - * @soc - data path soc handle - * @pdev - device instance pointer - * @cb - callback function + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle + * @cb: callback function * * Return: QDF_STATUS_SUCCESS register success */ static inline QDF_STATUS cdp_data_stall_cb_register(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, data_stall_detect_cb cb) { if (!soc || !soc->ops || !soc->ops->misc_ops) { @@ -132,21 +131,20 @@ static inline QDF_STATUS cdp_data_stall_cb_register(ol_txrx_soc_handle soc, if (soc->ops->misc_ops->txrx_data_stall_cb_register) return soc->ops->misc_ops->txrx_data_stall_cb_register( - pdev, - cb); + soc, pdev_id, cb); return QDF_STATUS_SUCCESS; } /** * cdp_data_stall_cb_deregister() - de-register data stall callback - * @soc - data path soc handle - * @pdev - device instance pointer + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * @cb - callback function * * Return: QDF_STATUS_SUCCESS de-register success */ static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, data_stall_detect_cb cb) { if (!soc || !soc->ops || !soc->ops->misc_ops) { @@ -157,15 +155,13 @@ static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc, if (soc->ops->misc_ops->txrx_data_stall_cb_deregister) return soc->ops->misc_ops->txrx_data_stall_cb_deregister( - pdev, - cb); + soc, pdev_id, cb); return QDF_STATUS_SUCCESS; } /** * cdp_post_data_stall_event() - post data stall event - * @soc - data path soc handle - * @pdev - device instance pointer + * @soc: data path soc handle * @indicator: Module triggering data stall * @data_stall_type: data stall event type * @pdev_id: pdev id @@ -176,7 +172,6 @@ static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc, */ static inline void cdp_post_data_stall_event(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, enum data_stall_log_event_indicator indicator, enum data_stall_log_event_type data_stall_type, uint32_t pdev_id, uint32_t vdev_id_bitmap, @@ -194,22 +189,21 @@ cdp_post_data_stall_event(ol_txrx_soc_handle soc, return; soc->ops->misc_ops->txrx_post_data_stall_event( - pdev, - indicator, data_stall_type, pdev_id, + soc, indicator, data_stall_type, pdev_id, vdev_id_bitmap, recovery_type); } /** * cdp_set_wmm_param() - set wmm parameter - * @soc - data path soc handle - * @pdev - device instance pointer - * @wmm_param - wmm parameter + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle + * @wmm_param: wmm parameter * * Return: none */ static inline void -cdp_set_wmm_param(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - struct ol_tx_wmm_param_t wmm_param) +cdp_set_wmm_param(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct ol_tx_wmm_param_t wmm_param) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -218,21 +212,21 @@ cdp_set_wmm_param(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->misc_ops->set_wmm_param) - return soc->ops->misc_ops->set_wmm_param( - pdev, wmm_param); + return soc->ops->misc_ops->set_wmm_param(soc, pdev_id, + wmm_param); return; } /** * cdp_runtime_suspend() - suspend - * @soc - data path soc handle - * @pdev - device instance pointer + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * * Return: QDF_STATUS_SUCCESS suspend success */ static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -241,20 +235,20 @@ static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->runtime_suspend) - return soc->ops->misc_ops->runtime_suspend(pdev); + return soc->ops->misc_ops->runtime_suspend(soc, pdev_id); return QDF_STATUS_SUCCESS; } /** * cdp_runtime_resume() - resume - * @soc - data path soc handle - * @pdev - device instance pointer + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * * Return: QDF_STATUS_SUCCESS suspend success */ static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -263,21 +257,21 @@ static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->runtime_resume) - return soc->ops->misc_ops->runtime_resume(pdev); + return soc->ops->misc_ops->runtime_resume(soc, pdev_id); return QDF_STATUS_SUCCESS; } /** * cdp_hl_tdls_flag_reset() - tdls flag reset - * @soc - data path soc handle - * @vdev - virtual interface handle pointer - * @flag + * @soc: data path soc handle + * @vdev_id: id of vdev + * @flag: flag indicating to set/reset tdls * * Return: none */ static inline void -cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag) +cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, uint8_t vdev_id, bool flag) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -286,15 +280,16 @@ cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag) } if (soc->ops->misc_ops->hl_tdls_flag_reset) - return soc->ops->misc_ops->hl_tdls_flag_reset(vdev, flag); + return soc->ops->misc_ops->hl_tdls_flag_reset(soc, vdev_id, + flag); return; } /** * cdp_get_opmode() - get vdev operation mode - * @soc - data path soc handle - * @vdev - virtual interface instance + * @soc: data path soc handle + * @vdev_id: id of vdev * * Return virtual device operational mode * op_mode_ap, @@ -307,7 +302,7 @@ cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag) * 0 unknown interface */ static inline int -cdp_get_opmode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +cdp_get_opmode(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -316,7 +311,8 @@ cdp_get_opmode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) } if (soc->ops->misc_ops->get_opmode) - return soc->ops->misc_ops->get_opmode(vdev); + return soc->ops->misc_ops->get_opmode(soc, vdev_id); + return 0; } @@ -347,15 +343,13 @@ cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) /** * cdp_get_tx_ack_stats() - get tx ack count for vdev * @soc - data path soc handle - * @pdev - data path device instance * @vdev_id - vdev id * * return tx ack count * 0 invalid count */ static inline uint32_t -cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t vdev_id) +cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -364,26 +358,24 @@ cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->misc_ops->get_tx_ack_stats) - return soc->ops->misc_ops->get_tx_ack_stats(pdev, vdev_id); + return soc->ops->misc_ops->get_tx_ack_stats(soc, vdev_id); return 0; } /** - * cdp_bad_peer_txctl_set_setting() - TBD - * @soc - data path soc handle - * @pdev - data path device instance - * @enable - - * @period - - * @txq_limit - - * - * TBD + * cdp_bad_peer_txctl_set_setting() - Set peer timer balance parameters + * @soc: data path soc handle + * @pdev_id: id of datapath pdev handle + * @enable: enable/disable peer balance state + * @period: balance timer period for peer + * @txq_limit: txp limit for peer * * Return: none */ static inline void -cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - int enable, int period, int txq_limit) +cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, uint8_t pdev_id, + int enable, int period, int txq_limit) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -392,18 +384,19 @@ cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->misc_ops->bad_peer_txctl_set_setting) - return soc->ops->misc_ops->bad_peer_txctl_set_setting(pdev, - enable, period, txq_limit); + return soc->ops->misc_ops->bad_peer_txctl_set_setting( + soc, pdev_id, enable, period, + txq_limit); return; } /** * cdp_bad_peer_txctl_update_threshold() - TBD - * @soc - data path soc handle - * @pdev - data path device instance - * @level - - * @tput_thresh - - * @tx_limit - + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle + * @level: index of the threshold configuration + * @tput_thresh: peer balance throughput threshold + * @tx_limit: peer balance tx limit threshold * * TBD * @@ -411,8 +404,8 @@ cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, */ static inline void cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, - int level, int tput_thresh, int tx_limit) + uint8_t pdev_id, int level, + int tput_thresh, int tx_limit) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -422,20 +415,21 @@ cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc, if (soc->ops->misc_ops->bad_peer_txctl_update_threshold) return soc->ops->misc_ops->bad_peer_txctl_update_threshold( - pdev, level, tput_thresh, tx_limit); + soc, pdev_id, level, tput_thresh, tx_limit); return; } /** * cdp_mark_first_wakeup_packet() - set flag to indicate that * fw is compatible for marking first packet after wow wakeup - * @soc - data path soc handle + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * @value: 1 for enabled/ 0 for disabled * * Return: None */ static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc, - uint8_t value) + uint8_t pdev_id, uint8_t value) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -444,21 +438,22 @@ static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->mark_first_wakeup_packet) - return soc->ops->misc_ops->mark_first_wakeup_packet(value); + return soc->ops->misc_ops->mark_first_wakeup_packet( + soc, pdev_id, value); return; } /** * cds_update_mac_id() - update mac_id for vdev - * @soc - data path soc handle + * @psoc: data path soc handle * @vdev_id: vdev id * @mac_id: mac id * * Return: none */ static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id, - uint8_t mac_id) + uint8_t mac_id) { ol_txrx_soc_handle soc = psoc; @@ -469,20 +464,21 @@ static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id, } if (soc->ops->misc_ops->update_mac_id) - return soc->ops->misc_ops->update_mac_id(vdev_id, mac_id); + return soc->ops->misc_ops->update_mac_id(soc, vdev_id, mac_id); return; } /** * cdp_flush_rx_frames() - flush cached rx frames - * @soc - data path soc handle - * @peer: peer + * @soc: data path soc handle + * @pdev_id: datapath pdev identifier + * @peer_mac: peer mac address * @drop: set flag to drop frames * * Return: None */ -static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, void *peer, - bool drop) +static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint8_t *peer_mac, bool drop) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -491,13 +487,15 @@ static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, void *peer, } if (soc->ops->misc_ops->flush_rx_frames) - return soc->ops->misc_ops->flush_rx_frames(peer, drop); + return soc->ops->misc_ops->flush_rx_frames(soc, pdev_id, + peer_mac, drop); return; } /* * cdp_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets * that has been forwarded from txrx layer without going to upper layers. + * @soc: Datapath soc handle * @vdev_id: vdev id * @fwd_tx_packets: pointer to forwarded tx packets count parameter * @fwd_rx_packets: pointer to forwarded rx packets count parameter @@ -516,20 +514,21 @@ static inline A_STATUS cdp_get_intra_bss_fwd_pkts_count( if (soc->ops->misc_ops->get_intra_bss_fwd_pkts_count) return soc->ops->misc_ops->get_intra_bss_fwd_pkts_count( - vdev_id, fwd_tx_packets, fwd_rx_packets); + soc, vdev_id, fwd_tx_packets, fwd_rx_packets); return 0; } /** * cdp_pkt_log_init() - API to initialize packet log - * @handle: pdev handle + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * @scn: HIF context * * Return: void */ static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, void *scn) + uint8_t pdev_id, void *scn) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -538,20 +537,21 @@ static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->pkt_log_init) - return soc->ops->misc_ops->pkt_log_init(pdev, scn); + return soc->ops->misc_ops->pkt_log_init(soc, pdev_id, scn); return; } /** * cdp_pkt_log_con_service() - API to connect packet log service - * @handle: pdev handle + * @soc: data path soc handle + * @pdev_id: id of data path pdev handle * @scn: HIF context * * Return: void */ static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, void *scn) + uint8_t pdev_id, void *scn) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -560,7 +560,8 @@ static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->pkt_log_con_service) - return soc->ops->misc_ops->pkt_log_con_service(pdev, scn); + return soc->ops->misc_ops->pkt_log_con_service( + soc, pdev_id, scn); return; } @@ -592,12 +593,14 @@ static inline int cdp_get_num_rx_contexts(ol_txrx_soc_handle soc) * stats will be passed to user-space by @tx_cb/@rx_cb. * * @soc: soc handle + * @pdev_id: id of data path pdev handle * @tx_cb: tx packet callback * @rx_cb: rx packet callback * * Return: void */ static inline void cdp_register_packetdump_cb(ol_txrx_soc_handle soc, + uint8_t pdev_id, ol_txrx_pktdump_cb tx_cb, ol_txrx_pktdump_cb rx_cb) { @@ -608,7 +611,8 @@ static inline void cdp_register_packetdump_cb(ol_txrx_soc_handle soc, } if (soc->ops->misc_ops->register_pktdump_cb) - return soc->ops->misc_ops->register_pktdump_cb(tx_cb, rx_cb); + return soc->ops->misc_ops->register_pktdump_cb( + soc, pdev_id, tx_cb, rx_cb); } /** @@ -617,10 +621,12 @@ static inline void cdp_register_packetdump_cb(ol_txrx_soc_handle soc, * Deregister callback for TX/RX data packets. * * @soc: soc handle + * @pdev_id: id of data path pdev handle * * Return: void */ -static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc) +static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc, + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->misc_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -629,18 +635,44 @@ static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc) } if (soc->ops->misc_ops->unregister_pktdump_cb) - return soc->ops->misc_ops->unregister_pktdump_cb(); + return soc->ops->misc_ops->unregister_pktdump_cb(soc, pdev_id); +} + +typedef void (*rx_mic_error_callback)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, + struct cdp_rx_mic_err_info *info); + +/** + * cdp_register_rx_mic_error_ind_handler() - API to register mic error + * indication handler + * + * @soc: soc handle + * @rx_mic_cb: rx mic error indication callback + * + * Return: void + */ +static inline void +cdp_register_rx_mic_error_ind_handler(ol_txrx_soc_handle soc, + rx_mic_error_callback rx_mic_cb) +{ + if (!soc || !soc->ol_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return; + } + + soc->ol_ops->rx_mic_error = rx_mic_cb; } /** * cdp_pdev_reset_driver_del_ack() - reset driver TCP delayed ack flag - * @soc - data path soc handle - * @pdev - data path device instance + * @soc: data path soc handle + * @pdev_id: pdev id * * Return: none */ static inline void cdp_pdev_reset_driver_del_ack(void *psoc, - struct cdp_pdev *pdev) + uint8_t pdev_id) { ol_txrx_soc_handle soc = psoc; @@ -651,12 +683,13 @@ static inline void cdp_pdev_reset_driver_del_ack(void *psoc, } if (soc->ops->misc_ops->pdev_reset_driver_del_ack) - return soc->ops->misc_ops->pdev_reset_driver_del_ack(pdev); + return soc->ops->misc_ops->pdev_reset_driver_del_ack(soc, + pdev_id); } /* * cdp_vdev_set_driver_del_ack_enable() - set driver delayed ack enabled flag - * @soc - data path soc handle + * @soc: data path soc handle * @vdev_id: vdev id * @rx_packets: number of rx packets * @time_in_ms: time in ms @@ -680,19 +713,51 @@ static inline void cdp_vdev_set_driver_del_ack_enable(ol_txrx_soc_handle soc, if (soc->ops->misc_ops->vdev_set_driver_del_ack_enable) return soc->ops->misc_ops->vdev_set_driver_del_ack_enable( - vdev_id, rx_packets, time_in_ms, high_th, low_th); + soc, vdev_id, rx_packets, time_in_ms, high_th, low_th); +} + +static inline void cdp_vdev_set_bundle_require_flag(ol_txrx_soc_handle soc, + uint8_t vdev_id, + unsigned long tx_bytes, + uint32_t time_in_ms, + uint32_t high_th, + uint32_t low_th) +{ + if (!soc || !soc->ops || !soc->ops->misc_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return; + } + + if (soc->ops->misc_ops->vdev_set_bundle_require_flag) + return soc->ops->misc_ops->vdev_set_bundle_require_flag( + vdev_id, tx_bytes, time_in_ms, high_th, low_th); +} + +static inline void cdp_pdev_reset_bundle_require_flag(ol_txrx_soc_handle soc, + uint8_t pdev_id) +{ + if (!soc || !soc->ops || !soc->ops->misc_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return; + } + + if (soc->ops->misc_ops->pdev_reset_bundle_require_flag) + return soc->ops->misc_ops->pdev_reset_bundle_require_flag( + soc, pdev_id); } /** * cdp_txrx_ext_stats_request(): request dp tx and rx extended stats * @soc: soc handle - * @pdev: pdev handle + * @pdev_id: pdev id * @req: stats request structure to fill * * return: status */ static inline QDF_STATUS -cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, uint8_t pdev_id, struct cdp_txrx_ext_stats *req) { if (!soc || !soc->ops || !soc->ops->misc_ops || !req) { @@ -702,7 +767,8 @@ cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->misc_ops->txrx_ext_stats_request) - return soc->ops->misc_ops->txrx_ext_stats_request(pdev, req); + return soc->ops->misc_ops->txrx_ext_stats_request(soc, pdev_id, + req); return QDF_STATUS_SUCCESS; } @@ -710,7 +776,7 @@ cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_request_rx_hw_stats(): request rx hw stats * @soc: soc handle - * @vdev: vdev handle + * @vdev_id: vdev id * * return: none */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h index c706d6d2acfda169c6080dd94206898bb32ca4a9..96638a716f26275b5c0cc912090a999dcbbf29f3 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -232,14 +233,14 @@ enum peer_debug_id_type { /** * struct ol_txrx_desc_type - txrx descriptor type - * @sta_id: sta id * @is_qos_enabled: is station qos enabled * @is_wapi_supported: is station wapi supported + * @peer_addr: peer mac address */ struct ol_txrx_desc_type { - uint8_t sta_id; uint8_t is_qos_enabled; uint8_t is_wapi_supported; + struct qdf_mac_addr peer_addr; }; /** @@ -284,14 +285,22 @@ struct txrx_pdev_cfg_param_t { uint32_t uc_tx_partition_base; /* IP, TCP and UDP checksum offload */ bool ip_tcp_udp_checksum_offload; + /* IP, TCP and UDP checksum offload for NAN Mode */ + bool nan_ip_tcp_udp_checksum_offload; + /* IP, TCP and UDP checksum offload for P2P Mode*/ + bool p2p_ip_tcp_udp_checksum_offload; + /* Checksum offload override flag for Legcay modes */ + bool legacy_mode_csum_disable; /* Rx processing in thread from TXRX */ bool enable_rxthread; /* CE classification enabled through INI */ bool ce_classify_enabled; +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /* Threshold to stop queue in percentage */ uint32_t tx_flow_stop_queue_th; /* Start queue offset in percentage */ uint32_t tx_flow_start_queue_offset; +#endif #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK /* enable the tcp delay ack feature in the driver */ @@ -304,11 +313,19 @@ struct txrx_pdev_cfg_param_t { struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM]; bool gro_enable; + bool tc_based_dyn_gro; + uint32_t tc_ingress_prio; bool tso_enable; bool lro_enable; + bool sg_enable; bool enable_data_stall_detection; bool enable_flow_steering; bool disable_intra_bss_fwd; + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + uint16_t bundle_timer_value; + uint16_t bundle_size; +#endif uint8_t pktlog_buffer_size; }; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h index 5cefc1d4a34bfe89090f23e8bf6ae02d9e62ea19..a11bb95846bfb2eacebc7601d7b52800909dd6ae 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,168 +25,187 @@ #ifndef _CDP_TXRX_MON_H_ #define _CDP_TXRX_MON_H_ #include "cdp_txrx_handle.h" -static inline void cdp_monitor_set_filter_ucast_data - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, u_int8_t val) + +static inline QDF_STATUS cdp_reset_monitor_mode(ol_txrx_soc_handle soc, + uint8_t pdev_id, + u_int8_t smart_monitor) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return 0; } if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_set_filter_ucast_data) - return; + !soc->ops->mon_ops->txrx_reset_monitor_mode) + return 0; - soc->ops->mon_ops->txrx_monitor_set_filter_ucast_data - (pdev, val); + return soc->ops->mon_ops->txrx_reset_monitor_mode(soc, pdev_id, + smart_monitor); } -static inline void cdp_monitor_set_filter_mcast_data - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, u_int8_t val) +/** + * cdp_deliver_tx_mgmt() - Deliver mgmt frame for tx capture + * @soc: Datapath SOC handle + * @pdev_id: id of datapath PDEV handle + * @nbuf: Management frame buffer + */ +static inline QDF_STATUS +cdp_deliver_tx_mgmt(ol_txrx_soc_handle soc, uint8_t pdev_id, + qdf_nbuf_t nbuf) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); + "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_set_filter_mcast_data) - return; + !soc->ops->mon_ops->txrx_deliver_tx_mgmt) + return QDF_STATUS_E_FAILURE; - soc->ops->mon_ops->txrx_monitor_set_filter_mcast_data - (pdev, val); + return soc->ops->mon_ops->txrx_deliver_tx_mgmt(soc, pdev_id, nbuf); } -static inline void cdp_monitor_set_filter_non_data - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, u_int8_t val) +#ifdef WLAN_FEATURE_PKT_CAPTURE +static inline void +cdp_pktcapture_record_channel( + ol_txrx_soc_handle soc, + uint8_t pdev_id, + int chan_num) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s invalid instance", __func__); QDF_BUG(0); return; } - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_set_filter_non_data) + if (!soc->ops->pktcapture_ops || + !soc->ops->pktcapture_ops->txrx_pktcapture_record_channel) return; - soc->ops->mon_ops->txrx_monitor_set_filter_non_data - (pdev, val); + soc->ops->pktcapture_ops->txrx_pktcapture_record_channel(soc, + pdev_id, + chan_num); } -static inline bool cdp_monitor_get_filter_ucast_data -(ol_txrx_soc_handle soc, struct cdp_vdev *vdev_txrx_handle) +static inline void +cdp_set_packet_capture_mode(ol_txrx_soc_handle soc, + uint8_t pdev_id, + uint8_t val) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s invalid instance", __func__); QDF_BUG(0); - return 0; + return; } - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_get_filter_ucast_data) - return 0; + if (!soc->ops->pktcapture_ops || + !soc->ops->pktcapture_ops->txrx_pktcapture_set_mode) + return; - return soc->ops->mon_ops->txrx_monitor_get_filter_ucast_data - (vdev_txrx_handle); + soc->ops->pktcapture_ops->txrx_pktcapture_set_mode(soc, pdev_id, val); } -static inline bool cdp_monitor_get_filter_mcast_data -(ol_txrx_soc_handle soc, struct cdp_vdev *vdev_txrx_handle) +static inline uint8_t +cdp_get_packet_capture_mode(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s invalid instance", __func__); QDF_BUG(0); return 0; } - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_get_filter_mcast_data) + if (!soc->ops->pktcapture_ops || + !soc->ops->pktcapture_ops->txrx_pktcapture_get_mode) return 0; - return soc->ops->mon_ops->txrx_monitor_get_filter_mcast_data - (vdev_txrx_handle); + return soc->ops->pktcapture_ops->txrx_pktcapture_get_mode(soc, + pdev_id); } -static inline bool cdp_monitor_get_filter_non_data -(ol_txrx_soc_handle soc, struct cdp_vdev *vdev_txrx_handle) +static inline QDF_STATUS +cdp_register_pktcapture_cb( + ol_txrx_soc_handle soc, uint8_t pdev_id, void *ctx, + QDF_STATUS(txrx_pktcapture_cb)(void *, qdf_nbuf_t)) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return QDF_STATUS_E_INVAL; } - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_get_filter_non_data) - return 0; - - return soc->ops->mon_ops->txrx_monitor_get_filter_non_data - (vdev_txrx_handle); + if (!soc->ops->pktcapture_ops || + !soc->ops->pktcapture_ops->txrx_pktcapture_cb_register) + return QDF_STATUS_E_INVAL; + + return soc->ops->pktcapture_ops->txrx_pktcapture_cb_register( + soc, + pdev_id, + ctx, + txrx_pktcapture_cb); } -static inline QDF_STATUS cdp_reset_monitor_mode -(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) +static inline QDF_STATUS +cdp_deregister_pktcapture_cb(ol_txrx_soc_handle soc, uint8_t pdev_id) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return 0; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return QDF_STATUS_E_INVAL; } - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_reset_monitor_mode) - return 0; + if (!soc->ops->pktcapture_ops || + !soc->ops->pktcapture_ops->txrx_pktcapture_cb_deregister) + return QDF_STATUS_E_INVAL; - return soc->ops->mon_ops->txrx_reset_monitor_mode(pdev); + return soc->ops->pktcapture_ops->txrx_pktcapture_cb_deregister(soc, + pdev_id); } -static inline void cdp_record_monitor_chan_num -(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int chan_num) +static inline QDF_STATUS +cdp_pktcapture_mgmtpkt_process( + ol_txrx_soc_handle soc, + uint8_t pdev_id, + struct mon_rx_status *txrx_status, + qdf_nbuf_t nbuf, + uint8_t status) { if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, - "%s: Invalid Instance", __func__); - QDF_BUG(0); - return; - } - - if (!soc->ops->mon_ops || - !soc->ops->mon_ops->txrx_monitor_record_channel) - return; - - soc->ops->mon_ops->txrx_monitor_record_channel(pdev, chan_num); -} -#ifdef WLAN_FEATURE_PKT_CAPTURE -static inline void -cdp_pktcapture_record_channel( - ol_txrx_soc_handle soc, - uint8_t pdev_id, - int chan_num) -{ - if (!soc || !soc->ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - QDF_BUG(0); - return; + return QDF_STATUS_E_INVAL; } if (!soc->ops->pktcapture_ops || - !soc->ops->pktcapture_ops->txrx_pktcapture_record_channel) - return; + !soc->ops->pktcapture_ops->txrx_pktcapture_mgmtpkt_process) + return QDF_STATUS_E_INVAL; + + return soc->ops->pktcapture_ops->txrx_pktcapture_mgmtpkt_process( + soc, + pdev_id, + txrx_status, + nbuf, + status); +} +#else +static inline uint8_t +cdp_get_packet_capture_mode(ol_txrx_soc_handle soc, uint8_t pdev_id) +{ + return 0; +} - soc->ops->pktcapture_ops->txrx_pktcapture_record_channel(soc, - pdev_id, - chan_num); +static inline void +cdp_pktcapture_record_channel(ol_txrx_soc_handle soc, + uint8_t pdev_id, + int chan_num) +{ } -#endif +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h index 189c0e47519ddf3d723235e6ea81114f3beba9de..edb12c95eda99f0ee16572541f92f32ae13be2aa 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h @@ -102,6 +102,8 @@ enum { }; struct cdp_mon_status { + /* bss color value 1-63 used for update on ppdu_desc bsscolor */ + uint8_t bsscolor; int rs_numchains; int rs_flags; #define IEEE80211_RX_FCS_ERROR 0x01 @@ -236,7 +238,7 @@ struct cdp_pdev_mon_stats { uint32_t stat_ring_ppdu_id_hist[MAX_PPDU_ID_HIST]; uint32_t dest_ring_ppdu_id_hist[MAX_PPDU_ID_HIST]; uint32_t ppdu_id_hist_idx; - uint32_t tlv_tag_status_err; uint32_t mon_rx_dest_stuck; + uint32_t tlv_tag_status_err; }; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h index 5fd6d682f0cac3bcc511f8f54ba7d0cef51ffe6f..abab53af194eea28df204fd2c65d589d4e173008 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,14 +23,14 @@ /** * cdp_set_ocb_chan_info() - set OCB channel info to vdev. * @soc - data path soc handle - * @vdev: vdev handle + * @vdev_id: vdev_id corresponding to vdev start * @ocb_set_chan: OCB channel information to be set in vdev. * * Return: NONE */ static inline void -cdp_set_ocb_chan_info(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, - struct ol_txrx_ocb_set_chan ocb_set_chan) +cdp_set_ocb_chan_info(ol_txrx_soc_handle soc, uint8_t vdev_id, + struct ol_txrx_ocb_set_chan ocb_set_chan) { if (!soc || !soc->ops || !soc->ops->ocb_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -39,19 +39,19 @@ cdp_set_ocb_chan_info(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, } if (soc->ops->ocb_ops->set_ocb_chan_info) - soc->ops->ocb_ops->set_ocb_chan_info(vdev, + soc->ops->ocb_ops->set_ocb_chan_info(soc, vdev_id, ocb_set_chan); } /** * cdp_get_ocb_chan_info() - return handle to vdev ocb_channel_info * @soc - data path soc handle - * @vdev: vdev handle + * @vdev_id: vdev_id corresponding to vdev start * * Return: handle to struct ol_txrx_ocb_chan_info */ static inline struct ol_txrx_ocb_chan_info * -cdp_get_ocb_chan_info(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) +cdp_get_ocb_chan_info(ol_txrx_soc_handle soc, uint8_t vdev_id) { if (!soc || !soc->ops || !soc->ops->ocb_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -60,7 +60,7 @@ cdp_get_ocb_chan_info(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) } if (soc->ops->ocb_ops->get_ocb_chan_info) - return soc->ops->ocb_ops->get_ocb_chan_info(vdev); + return soc->ops->ocb_ops->get_ocb_chan_info(soc, vdev_id); return NULL; } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h index 1b080200452500b3ddb6fde4dc0f0a994869162b..243f1a87d503f67d664a120b7bad045878825412 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -29,6 +29,8 @@ #include "cdp_txrx_handle.h" #include #include "wlan_objmgr_psoc_obj.h" +#include +#include #ifdef IPA_OFFLOAD #ifdef CONFIG_IPA_WDI_UNIFIED_API @@ -44,6 +46,8 @@ #define CDP_PEER_DELETE_NO_SPECIAL 0 #define CDP_PEER_DO_NOT_START_UNMAP_TIMER 1 +struct hif_opaque_softc; + /* same as ieee80211_nac_param */ enum cdp_nac_param_cmd { /* IEEE80211_NAC_PARAM_ADD */ @@ -53,6 +57,31 @@ enum cdp_nac_param_cmd { /* IEEE80211_NAC_PARAM_LIST */ CDP_NAC_PARAM_LIST, }; + +/** + * enum vdev_peer_protocol_enter_exit - whether ingress or egress + * @CDP_VDEV_PEER_PROTOCOL_IS_INGRESS: ingress + * @CDP_VDEV_PEER_PROTOCOL_IS_EGRESS: egress + * + * whether ingress or egress + */ +enum vdev_peer_protocol_enter_exit { + CDP_VDEV_PEER_PROTOCOL_IS_INGRESS, + CDP_VDEV_PEER_PROTOCOL_IS_EGRESS +}; + +/** + * enum vdev_peer_protocol_tx_rx - whether tx or rx + * @CDP_VDEV_PEER_PROTOCOL_IS_TX: tx + * @CDP_VDEV_PEER_PROTOCOL_IS_RX: rx + * + * whether tx or rx + */ +enum vdev_peer_protocol_tx_rx { + CDP_VDEV_PEER_PROTOCOL_IS_TX, + CDP_VDEV_PEER_PROTOCOL_IS_RX +}; + /****************************************************************************** * * Control Interface (A Interface) @@ -63,57 +92,69 @@ struct cdp_cmn_ops { QDF_STATUS (*txrx_soc_attach_target)(ol_txrx_soc_handle soc); - int (*txrx_pdev_attach_target)(struct cdp_pdev *pdev); + int (*txrx_pdev_attach_target)(ol_txrx_soc_handle soc, uint8_t pdev_id); - struct cdp_vdev *(*txrx_vdev_attach) - (struct cdp_pdev *pdev, uint8_t *vdev_mac_addr, + QDF_STATUS (*txrx_vdev_attach) + (struct cdp_soc_t *soc, uint8_t pdev_id, uint8_t *mac, uint8_t vdev_id, enum wlan_op_mode op_mode, enum wlan_op_subtype subtype); - void (*txrx_vdev_detach) - (struct cdp_vdev *vdev, ol_txrx_vdev_delete_cb callback, - void *cb_context); + QDF_STATUS + (*txrx_vdev_detach)(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + ol_txrx_vdev_delete_cb callback, + void *cb_context); - struct cdp_pdev *(*txrx_pdev_attach) - (ol_txrx_soc_handle soc, struct cdp_ctrl_objmgr_pdev *ctrl_pdev, - HTC_HANDLE htc_pdev, qdf_device_t osdev, uint8_t pdev_id); + QDF_STATUS (*txrx_pdev_attach) + (ol_txrx_soc_handle soc, HTC_HANDLE htc_pdev, + qdf_device_t osdev, uint8_t pdev_id); - int (*txrx_pdev_post_attach)(struct cdp_pdev *pdev); + int (*txrx_pdev_post_attach)(struct cdp_soc_t *soc, uint8_t pdev_id); - void (*txrx_pdev_pre_detach)(struct cdp_pdev *pdev, int force); + void + (*txrx_pdev_pre_detach)(struct cdp_soc_t *soc, uint8_t pdev_id, + int force); - void (*txrx_pdev_detach)(struct cdp_pdev *pdev, int force); + QDF_STATUS + (*txrx_pdev_detach)(struct cdp_soc_t *psoc, uint8_t pdev_id, + int force); /** * txrx_pdev_deinit() - Deinitialize pdev and dp ring memory - * @pdev: Dp pdev handle + * @soc: soc dp handle + * @pdev_id: id of Dp pdev handle * @force: Force deinit or not * - * Return: None + * Return: QDF_STATUS */ - void (*txrx_pdev_deinit)(struct cdp_pdev *pdev, int force); + QDF_STATUS + (*txrx_pdev_deinit)(struct cdp_soc_t *soc, uint8_t pdev_id, + int force); - void *(*txrx_peer_create) - (struct cdp_vdev *vdev, uint8_t *peer_mac_addr, - struct cdp_ctrl_objmgr_peer *ctrl_peer); + QDF_STATUS + (*txrx_peer_create) + (ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac_addr); - void (*txrx_peer_setup) - (struct cdp_vdev *vdev_hdl, void *peer_hdl); + QDF_STATUS + (*txrx_peer_setup)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac); - void (*txrx_cp_peer_del_response) - (ol_txrx_soc_handle soc, struct cdp_vdev *vdev_hdl, + QDF_STATUS + (*txrx_cp_peer_del_response) + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac_addr); - void (*txrx_peer_teardown) - (struct cdp_vdev *vdev_hdl, void *peer_hdl); + QDF_STATUS + (*txrx_peer_teardown) + (struct cdp_soc_t *soc, uint8_t vdev_id, uint8_t *peer_mac); int (*txrx_peer_add_ast) - (ol_txrx_soc_handle soc, struct cdp_peer *peer_hdl, + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, uint8_t *mac_addr, enum cdp_txrx_ast_entry_type type, uint32_t flags); int (*txrx_peer_update_ast) - (ol_txrx_soc_handle soc, struct cdp_peer *peer_hdl, + (ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac, uint8_t *mac_addr, uint32_t flags); bool (*txrx_peer_get_ast_info_by_soc) @@ -136,94 +177,91 @@ struct cdp_cmn_ops { txrx_ast_free_cb callback, void *cookie); - void (*txrx_peer_delete)(void *peer, uint32_t bitmap); - - void (*txrx_vdev_flush_peers)(struct cdp_vdev *vdev, bool unmap_only); + QDF_STATUS + (*txrx_peer_delete)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, uint32_t bitmap); - QDF_STATUS (*txrx_set_monitor_mode)(struct cdp_vdev *vdev, + QDF_STATUS (*txrx_set_monitor_mode)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t smart_monitor); - void (*txrx_peer_delete_sync)(void *peer, + void (*txrx_peer_delete_sync)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, QDF_STATUS(*delete_cb)( uint8_t vdev_id, uint32_t peerid_cnt, uint16_t *peerid_list), uint32_t bitmap); - void (*txrx_peer_unmap_sync_cb_set)(struct cdp_pdev *pdev, - QDF_STATUS(*unmap_resp_cb)( - uint8_t vdev_id, - uint32_t peerid_cnt, - uint16_t *peerid_list)); - - uint8_t (*txrx_get_pdev_id_frm_pdev)(struct cdp_pdev *pdev); - bool (*txrx_get_vow_config_frm_pdev)(struct cdp_pdev *pdev); - - void (*txrx_pdev_set_chan_noise_floor)(struct cdp_pdev *pdev, - int16_t chan_noise_floor); + void (*txrx_peer_unmap_sync_cb_set)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + ol_txrx_peer_unmap_sync_cb + peer_unmap_sync); - void (*txrx_set_nac)(struct cdp_peer *peer); - - /** - * txrx_set_pdev_tx_capture() - callback to set pdev tx_capture - * @soc: opaque soc handle - * @pdev: data path pdev handle - * @val: value of pdev_tx_capture - * - * Return: status: 0 - Success, non-zero: Failure - */ - QDF_STATUS (*txrx_set_pdev_tx_capture)(struct cdp_pdev *pdev, int val); - - void (*txrx_get_peer_mac_from_peer_id) - (struct cdp_pdev *pdev_handle, + QDF_STATUS + (*txrx_get_peer_mac_from_peer_id) + (struct cdp_soc_t *cdp_soc, uint32_t peer_id, uint8_t *peer_mac); - void (*txrx_vdev_tx_lock)(struct cdp_vdev *vdev); + void + (*txrx_vdev_tx_lock)(struct cdp_soc_t *soc, uint8_t vdev_id); - void (*txrx_vdev_tx_unlock)(struct cdp_vdev *vdev); + void + (*txrx_vdev_tx_unlock)(struct cdp_soc_t *soc, uint8_t vdev_id); - void (*txrx_ath_getstats)(void *pdev, - struct cdp_dev_stats *stats, uint8_t type); + QDF_STATUS + (*txrx_ath_getstats)(struct cdp_soc_t *soc, uint8_t id, + struct cdp_dev_stats *stats, uint8_t type); - void (*txrx_set_gid_flag)(struct cdp_pdev *pdev, u_int8_t *mem_status, - u_int8_t *user_position); + QDF_STATUS + (*txrx_set_gid_flag)(struct cdp_soc_t *soc, uint8_t pdev_id, + u_int8_t *mem_status, + u_int8_t *user_position); - uint32_t (*txrx_fw_supported_enh_stats_version)(struct cdp_pdev *pdev); + uint32_t (*txrx_fw_supported_enh_stats_version)(struct cdp_soc_t *soc, + uint8_t pdev_id); - void (*txrx_if_mgmt_drain)(void *ni, int force); + QDF_STATUS + (*txrx_if_mgmt_drain)(struct cdp_soc_t *soc, uint8_t pdev_id, + int force); - void (*txrx_set_curchan)(struct cdp_pdev *pdev, uint32_t chan_mhz); + QDF_STATUS + (*txrx_set_curchan)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint32_t chan_mhz); - void (*txrx_set_privacy_filters) - (struct cdp_vdev *vdev, void *filter, uint32_t num); + QDF_STATUS + (*txrx_set_privacy_filters) + (struct cdp_soc_t *soc, uint8_t vdev_id, void *filter, + uint32_t num); - uint32_t (*txrx_get_cfg)(void *soc, enum cdp_dp_cfg cfg); + uint32_t (*txrx_get_cfg)(struct cdp_soc_t *soc, enum cdp_dp_cfg cfg); /******************************************************************** * Data Interface (B Interface) ********************************************************************/ - void (*txrx_vdev_register)(struct cdp_vdev *vdev, - void *osif_vdev, struct cdp_ctrl_objmgr_vdev *ctrl_vdev, - struct ol_txrx_ops *txrx_ops); + QDF_STATUS + (*txrx_vdev_register)(struct cdp_soc_t *soc, uint8_t vdev_id, + ol_osif_vdev_handle osif_vdev, + struct ol_txrx_ops *txrx_ops); - int (*txrx_mgmt_send)(struct cdp_vdev *vdev, - qdf_nbuf_t tx_mgmt_frm, uint8_t type); + int (*txrx_mgmt_send)(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t tx_mgmt_frm, uint8_t type); - int (*txrx_mgmt_send_ext)(struct cdp_vdev *vdev, - qdf_nbuf_t tx_mgmt_frm, uint8_t type, uint8_t use_6mbps, - uint16_t chanfreq); + int (*txrx_mgmt_send_ext)(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t tx_mgmt_frm, uint8_t type, + uint8_t use_6mbps, uint16_t chanfreq); /** * ol_txrx_mgmt_tx_cb - tx management delivery notification * callback function */ - void (*txrx_mgmt_tx_cb_set)(struct cdp_pdev *pdev, uint8_t type, - ol_txrx_mgmt_tx_cb download_cb, - ol_txrx_mgmt_tx_cb ota_ack_cb, - void *ctxt); - - int (*txrx_get_tx_pending)(struct cdp_pdev *pdev); + QDF_STATUS + (*txrx_mgmt_tx_cb_set)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t type, + ol_txrx_mgmt_tx_cb download_cb, + ol_txrx_mgmt_tx_cb ota_ack_cb, + void *ctxt); /** * ol_txrx_data_tx_cb - Function registered with the data path @@ -231,95 +269,87 @@ struct cdp_cmn_ops { * done being transmitted */ - void (*txrx_data_tx_cb_set)(struct cdp_vdev *data_vdev, - ol_txrx_data_tx_cb callback, void *ctxt); + void (*txrx_data_tx_cb_set)(struct cdp_soc_t *soc, uint8_t vdev_id, + ol_txrx_data_tx_cb callback, void *ctxt); + + qdf_nbuf_t (*tx_send_exc) + (ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t msdu_list, + struct cdp_tx_exception_metadata *tx_exc_metadata); /******************************************************************* * Statistics and Debugging Interface (C Interface) ********************************************************************/ - int (*txrx_aggr_cfg)(struct cdp_vdev *vdev, int max_subfrms_ampdu, - int max_subfrms_amsdu); + int (*txrx_aggr_cfg)(struct cdp_soc_t *soc, uint8_t vdev_id, + int max_subfrms_ampdu, + int max_subfrms_amsdu); - A_STATUS (*txrx_fw_stats_get)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req, - bool per_vdev, bool response_expected); + A_STATUS + (*txrx_fw_stats_get)(struct cdp_soc_t *soc, uint8_t vdev_id, + struct ol_txrx_stats_req *req, + bool per_vdev, bool response_expected); - int (*txrx_debug)(struct cdp_vdev *vdev, int debug_specs); + int (*txrx_debug)(struct cdp_soc_t *soc, uint8_t vdev_id, + int debug_specs); - void (*txrx_fw_stats_cfg)(struct cdp_vdev *vdev, - uint8_t cfg_stats_type, uint32_t cfg_val); + QDF_STATUS + (*txrx_fw_stats_cfg)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t cfg_stats_type, uint32_t cfg_val); void (*txrx_print_level_set)(unsigned level); /** * ol_txrx_get_vdev_mac_addr() - Return mac addr of vdev - * @vdev: vdev handle + * @soc: datapath soc handle + * @vdev_id: vdev id * * Return: vdev mac address */ - uint8_t * (*txrx_get_vdev_mac_addr)(struct cdp_vdev *vdev); - - /** - * ol_txrx_get_vdev_struct_mac_addr() - Return handle to struct qdf_mac_addr of - * vdev - * @vdev: vdev handle - * - * Return: Handle to struct qdf_mac_addr - */ - struct qdf_mac_addr * - (*txrx_get_vdev_struct_mac_addr)(struct cdp_vdev *vdev); - - /** - * ol_txrx_get_pdev_from_vdev() - Return handle to pdev of vdev - * @vdev: vdev handle - * - * Return: Handle to pdev - */ - struct cdp_pdev *(*txrx_get_pdev_from_vdev) - (struct cdp_vdev *vdev); + uint8_t * (*txrx_get_vdev_mac_addr)(struct cdp_soc_t *soc, + uint8_t vdev_id); /** * ol_txrx_get_ctrl_pdev_from_vdev() - Return control pdev of vdev - * @vdev: vdev handle + * @soc: datapath soc handle + * @vdev_id: vdev id * * Return: Handle to control pdev */ - struct cdp_cfg * - (*txrx_get_ctrl_pdev_from_vdev)(struct cdp_vdev *vdev); + struct cdp_cfg *(*txrx_get_ctrl_pdev_from_vdev)(struct cdp_soc_t *soc, + uint8_t vdev_id); /** * txrx_get_mon_vdev_from_pdev() - Return monitor mode vdev - * @pdev: pdev handle + * @soc: datapath soc handle + * @pdev: pdev id * - * Return: Handle to vdev + * Return: vdev_id */ - struct cdp_vdev * - (*txrx_get_mon_vdev_from_pdev)(struct cdp_pdev *pdev); + uint8_t (*txrx_get_mon_vdev_from_pdev)(struct cdp_soc_t *soc, + uint8_t pdev_id); - struct cdp_vdev * - (*txrx_get_vdev_from_vdev_id)(struct cdp_pdev *pdev, - uint8_t vdev_id); - - void (*txrx_soc_detach)(void *soc); + void (*txrx_soc_detach)(struct cdp_soc_t *soc); /** * txrx_soc_deinit() - Deinitialize dp soc and dp ring memory * @soc: Opaque Dp handle * - * Return: None + * Return None */ - void (*txrx_soc_deinit)(void *soc); + void (*txrx_soc_deinit)(struct cdp_soc_t *soc); /** * txrx_soc_init() - Initialize dp soc and dp ring memory * @soc: Opaque Dp handle + * @ctrl_psoc: Opaque Cp handle * @htchdl: Opaque htc handle * @hifhdl: Opaque hif handle * * Return: None */ - void *(*txrx_soc_init)(void *soc, void *ctrl_psoc, void *hif_handle, + void *(*txrx_soc_init)(struct cdp_soc_t *soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id); @@ -330,7 +360,7 @@ struct cdp_cmn_ops { * * Return: QDF status */ - QDF_STATUS (*txrx_tso_soc_attach)(void *soc); + QDF_STATUS (*txrx_tso_soc_attach)(struct cdp_soc_t *soc); /** * txrx_tso_soc_detach() - TSO detach handler triggered during @@ -339,87 +369,112 @@ struct cdp_cmn_ops { * * Return: QDF status */ - QDF_STATUS (*txrx_tso_soc_detach)(void *soc); - int (*addba_resp_tx_completion)(void *peer_handle, uint8_t tid, + QDF_STATUS (*txrx_tso_soc_detach)(struct cdp_soc_t *soc); + int (*addba_resp_tx_completion)(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status); - int (*addba_requestprocess)(void *peer_handle, uint8_t dialogtoken, - uint16_t tid, uint16_t batimeout, - uint16_t buffersize, - uint16_t startseqnum); + int (*addba_requestprocess)(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, + uint8_t dialogtoken, + uint16_t tid, uint16_t batimeout, + uint16_t buffersize, + uint16_t startseqnum); - void (*addba_responsesetup)(void *peer_handle, uint8_t tid, - uint8_t *dialogtoken, uint16_t *statuscode, - uint16_t *buffersize, uint16_t *batimeout); + QDF_STATUS + (*addba_responsesetup)(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, + uint8_t *dialogtoken, uint16_t *statuscode, + uint16_t *buffersize, uint16_t *batimeout); - int (*delba_process)(void *peer_handle, - int tid, uint16_t reasoncode); + int (*delba_process)(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, int tid, uint16_t reasoncode); /** * delba_tx_completion() - Indicate delba tx status - * @peer_handle: Peer handle + * @cdp_soc: soc handle + * @peer_mac: Peer mac address + * @vdev_id: vdev id * @tid: Tid number * @status: Tx completion status * * Return: 0 on Success, 1 on failure */ - int (*delba_tx_completion)(void *peer_handle, + int (*delba_tx_completion)(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status); - void (*set_addba_response)(void *peer_handle, - uint8_t tid, uint16_t statuscode); - - uint8_t (*get_peer_mac_addr_frm_id)(struct cdp_soc_t *soc_handle, - uint16_t peer_id, uint8_t *mac_addr); + QDF_STATUS + (*set_addba_response)(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, + uint16_t statuscode); - void (*set_vdev_dscp_tid_map)(struct cdp_vdev *vdev_handle, - uint8_t map_id); - int (*txrx_get_total_per)(struct cdp_pdev *pdev_handle); + QDF_STATUS + (*set_vdev_dscp_tid_map)(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, uint8_t map_id); + int (*txrx_get_total_per)(struct cdp_soc_t *soc, uint8_t pdev_id); void (*flush_cache_rx_queue)(void); - void (*set_pdev_dscp_tid_map)(struct cdp_pdev *pdev, uint8_t map_id, - uint8_t tos, uint8_t tid); - void (*hmmc_tid_override_en)(struct cdp_pdev *pdev, bool val); - void (*set_hmmc_tid_val)(struct cdp_pdev *pdev, uint8_t tid); - QDF_STATUS (*txrx_stats_request)(struct cdp_vdev *vdev, + QDF_STATUS (*set_pdev_dscp_tid_map)(struct cdp_soc_t *soc_handle, + uint8_t pdev_id, + uint8_t map_id, + uint8_t tos, uint8_t tid); + + QDF_STATUS (*txrx_stats_request)(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, struct cdp_txrx_stats_req *req); - QDF_STATUS (*display_stats)(void *psoc, uint16_t value, + QDF_STATUS (*display_stats)(struct cdp_soc_t *psoc, uint16_t value, enum qdf_stats_verbosity_level level); - void (*txrx_soc_set_nss_cfg)(ol_txrx_soc_handle soc, int config); - - int(*txrx_soc_get_nss_cfg)(ol_txrx_soc_handle soc); - QDF_STATUS (*txrx_intr_attach)(void *soc); - void (*txrx_intr_detach)(void *soc); - void (*set_pn_check)(struct cdp_vdev *vdev, - struct cdp_peer *peer_handle, enum cdp_sec_type sec_type, - uint32_t *rx_pn); - void (*set_key_sec_type)(struct cdp_vdev *vdev, - struct cdp_peer *peer_handle, - enum cdp_sec_type sec_type, - bool is_unicast); + + QDF_STATUS (*txrx_intr_attach)(struct cdp_soc_t *soc_handle); + void (*txrx_intr_detach)(struct cdp_soc_t *soc_handle); + QDF_STATUS (*set_pn_check)(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, uint8_t *peermac, + enum cdp_sec_type sec_type, + uint32_t *rx_pn); + + QDF_STATUS(*set_key_sec_type)(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, uint8_t *peermac, + enum cdp_sec_type sec_type, + bool is_unicast); QDF_STATUS (*update_config_parameters)(struct cdp_soc *psoc, struct cdp_config_params *params); - void *(*get_dp_txrx_handle)(struct cdp_pdev *pdev_hdl); - void (*set_dp_txrx_handle)(struct cdp_pdev *pdev_hdl, - void *dp_txrx_hdl); + void *(*get_dp_txrx_handle)(ol_txrx_soc_handle soc, uint8_t pdev_id); + void (*set_dp_txrx_handle)(ol_txrx_soc_handle soc, uint8_t pdev_id, + void *dp_hdl); + + void *(*get_vdev_dp_ext_txrx_handle)(struct cdp_soc_t *soc, + uint8_t vdev_id); + QDF_STATUS (*set_vdev_dp_ext_txrx_handle)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint16_t size); void *(*get_soc_dp_txrx_handle)(struct cdp_soc *soc_handle); void (*set_soc_dp_txrx_handle)(struct cdp_soc *soc_handle, void *dp_txrx_handle); - void (*map_pdev_to_lmac)(struct cdp_pdev *pdev_hdl, - uint32_t lmac_id); + QDF_STATUS (*map_pdev_to_lmac)(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint32_t lmac_id); - void (*txrx_peer_reset_ast) + QDF_STATUS (*handle_mode_change)(ol_txrx_soc_handle soc, + uint8_t pdev_id, uint32_t lmac_id); + + QDF_STATUS (*set_pdev_status_down)(struct cdp_soc_t *soc_handle, + uint8_t pdev_id, bool is_pdev_down); + + QDF_STATUS (*txrx_peer_reset_ast) (ol_txrx_soc_handle soc, uint8_t *ast_macaddr, - uint8_t *peer_macaddr, void *vdev_hdl); + uint8_t *peer_macaddr, uint8_t vdev_id); - void (*txrx_peer_reset_ast_table)(ol_txrx_soc_handle soc, - void *vdev_hdl); + QDF_STATUS (*txrx_peer_reset_ast_table)(ol_txrx_soc_handle soc, + uint8_t vdev_id); void (*txrx_peer_flush_ast_table)(ol_txrx_soc_handle soc); void (*txrx_set_ba_aging_timeout)(struct cdp_soc_t *soc_handle, @@ -432,125 +487,61 @@ struct cdp_cmn_ops { uint32_t max_ast_index, bool peer_map_unmap_v2); - void (*txrx_pdev_set_ctrl_pdev)(struct cdp_pdev *pdev_hdl, - struct cdp_ctrl_objmgr_pdev *ctrl_pdev); - ol_txrx_tx_fp tx_send; /** * txrx_get_os_rx_handles_from_vdev() - Return function, osif vdev * to deliver pkt to stack. - * @vdev: vdev handle + * @soc: datapath soc handle + * @vdev: vdev id * @stack_fn: pointer to - function pointer to deliver RX pkt to stack * @osif_vdev: pointer to - osif vdev to deliver RX packet to. */ void (*txrx_get_os_rx_handles_from_vdev) - (struct cdp_vdev *vdev, + (ol_txrx_soc_handle soc, + uint8_t vdev_id, ol_txrx_rx_fp *stack_fn, ol_osif_vdev_handle *osif_vdev); + + void (*set_rate_stats_ctx)(struct cdp_soc_t *soc, + void *ctx); + int (*txrx_classify_update) - (struct cdp_vdev *vdev, qdf_nbuf_t skb, + (struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t skb, enum txrx_direction, struct ol_txrx_nbuf_classify *nbuf_class); bool (*get_dp_capabilities)(struct cdp_soc_t *soc, enum cdp_capabilities dp_caps); - void (*set_rate_stats_ctx)(struct cdp_soc_t *soc, void *ctx); void* (*get_rate_stats_ctx)(struct cdp_soc_t *soc); - void (*txrx_peer_flush_rate_stats)(struct cdp_soc_t *soc, - struct cdp_pdev *pdev, - void *buf); - void (*txrx_flush_rate_stats_request)(struct cdp_soc_t *soc, - struct cdp_pdev *pdev); - QDF_STATUS (*set_pdev_pcp_tid_map)(struct cdp_pdev *pdev, + QDF_STATUS (*txrx_peer_flush_rate_stats)(struct cdp_soc_t *soc, + uint8_t pdev_id, + void *buf); + + QDF_STATUS (*txrx_flush_rate_stats_request)(struct cdp_soc_t *soc, + uint8_t pdev_id); + QDF_STATUS (*set_pdev_pcp_tid_map)(struct cdp_soc_t *soc, + uint8_t pdev_id, uint8_t pcp, uint8_t tid); - QDF_STATUS (*set_pdev_tidmap_prty)(struct cdp_pdev *pdev, uint8_t prty); - QDF_STATUS (*set_vdev_pcp_tid_map)(struct cdp_vdev *vdev, + QDF_STATUS (*set_vdev_pcp_tid_map)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t pcp, uint8_t tid); - QDF_STATUS (*set_vdev_tidmap_prty)(struct cdp_vdev *vdev, uint8_t prty); - QDF_STATUS (*set_vdev_tidmap_tbl_id)(struct cdp_vdev *vdev, - uint8_t mapid); +#ifdef QCA_MULTIPASS_SUPPORT + QDF_STATUS (*set_vlan_groupkey)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint16_t vlan_id, uint16_t group_key); +#endif + + uint16_t (*get_peer_mac_list) + (ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], uint16_t mac_cnt); }; struct cdp_ctrl_ops { int - (*txrx_mempools_attach)(void *ctrl_pdev); - int - (*txrx_set_filter_neighbour_peers)( - struct cdp_pdev *pdev, - uint32_t val); + (*txrx_mempools_attach)(ol_txrx_soc_handle dp_soc); int (*txrx_update_filter_neighbour_peers)( - struct cdp_vdev *vdev, + struct cdp_soc_t *soc, uint8_t vdev_id, uint32_t cmd, uint8_t *macaddr); - /** - * @brief set the safemode of the device - * @details - * This flag is used to bypass the encrypt and decrypt processes when - * send and receive packets. It works like open AUTH mode, HW will - * ctreate all packets as non-encrypt frames because no key installed. - * For rx fragmented frames,it bypasses all the rx defragmentaion. - * - * @param vdev - the data virtual device object - * @param val - the safemode state - * @return - void - */ - - void - (*txrx_set_safemode)( - struct cdp_vdev *vdev, - u_int32_t val); - /** - * @brief configure the drop unencrypted frame flag - * @details - * Rx related. When set this flag, all the unencrypted frames - * received over a secure connection will be discarded - * - * @param vdev - the data virtual device object - * @param val - flag - * @return - void - */ - void - (*txrx_set_drop_unenc)( - struct cdp_vdev *vdev, - u_int32_t val); - - - /** - * @brief set the Tx encapsulation type of the VDEV - * @details - * This will be used to populate the HTT desc packet type field - * during Tx - * @param vdev - the data virtual device object - * @param val - the Tx encap type - * @return - void - */ - void - (*txrx_set_tx_encap_type)( - struct cdp_vdev *vdev, - enum htt_cmn_pkt_type val); - /** - * @brief set the Rx decapsulation type of the VDEV - * @details - * This will be used to configure into firmware and hardware - * which format to decap all Rx packets into, for all peers under - * the VDEV. - * @param vdev - the data virtual device object - * @param val - the Rx decap mode - * @return - void - */ - void - (*txrx_set_vdev_rx_decap_type)( - struct cdp_vdev *vdev, - enum htt_cmn_pkt_type val); - - /** - * @brief get the Rx decapsulation type of the VDEV - * - * @param vdev - the data virtual device object - * @return - the Rx decap type - */ - enum htt_cmn_pkt_type - (*txrx_get_vdev_rx_decap_type)(struct cdp_vdev *vdev); /* Is this similar to ol_txrx_peer_state_update() in MCL */ /** @@ -560,47 +551,42 @@ struct cdp_ctrl_ops { * updates the peer/node-related parameters within rate-control * context of the peer at association. * - * @param peer - pointer to the node's object + * @param soc_hdl - pointer to the soc object + * @param vdev_id - id of the virtual object + * @param peer_mac - mac address of the node's object * @authorize - either to authorize or unauthorize peer * - * @return none - */ - void - (*txrx_peer_authorize)(struct cdp_peer *peer, - u_int32_t authorize); - - /* Should be ol_txrx_ctrl_api.h */ - void (*txrx_set_mesh_mode)(struct cdp_vdev *vdev, u_int32_t val); - - /** - * @brief setting mesh rx filter - * @details - * based on the bits enabled in the filter packets has to be dropped. - * - * @param vdev - the data virtual device object - * @param val - value to set + * @return QDF_STATUS */ - void (*txrx_set_mesh_rx_filter)(struct cdp_vdev *vdev, uint32_t val); + QDF_STATUS + (*txrx_peer_authorize)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_mac, + u_int32_t authorize); - void (*tx_flush_buffers)(struct cdp_vdev *vdev); + void (*tx_flush_buffers)(struct cdp_soc_t *soc, uint8_t vdev_id); - int (*txrx_is_target_ar900b)(struct cdp_vdev *vdev); + int (*txrx_is_target_ar900b)(struct cdp_soc_t *soc_hdl); - void (*txrx_set_vdev_param)(struct cdp_vdev *vdev, - enum cdp_vdev_param_type param, uint32_t val); + QDF_STATUS + (*txrx_set_vdev_param)(struct cdp_soc_t *soc, uint8_t vdev_id, + enum cdp_vdev_param_type param, + cdp_config_param_type val); - void (*txrx_peer_set_nawds)(struct cdp_peer *peer, uint8_t value); /** * @brief Set the reo dest ring num of the radio * @details * Set the reo destination ring no on which we will receive * pkts for this radio. * - * @param pdev - the data physical device object + * @txrx_soc - soc handle + * @param pdev_id - id of physical device + * @return the reo destination ring number * @param reo_dest_ring_num - value ranges between 1 - 4 */ - void (*txrx_set_pdev_reo_dest)( - struct cdp_pdev *pdev, + QDF_STATUS (*txrx_set_pdev_reo_dest)( + struct cdp_soc_t *txrx_soc, + uint8_t pdev_id, enum cdp_host_reo_dest_ring reo_dest_ring_num); /** @@ -609,274 +595,361 @@ struct cdp_ctrl_ops { * Get the reo destination ring no on which we will receive * pkts for this radio. * - * @param pdev - the data physical device object + * @txrx_soc - soc handle + * @param pdev_id - id of physical device * @return the reo destination ring number */ enum cdp_host_reo_dest_ring (*txrx_get_pdev_reo_dest)( - struct cdp_pdev *pdev); + struct cdp_soc_t *txrx_soc, + uint8_t pdev_id); + + int (*txrx_wdi_event_sub)(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, + uint32_t event); - int (*txrx_wdi_event_sub)(struct cdp_pdev *pdev, void *event_cb_sub, - uint32_t event); + int (*txrx_wdi_event_unsub)(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, + uint32_t event); - int (*txrx_wdi_event_unsub)(struct cdp_pdev *pdev, void *event_cb_sub, - uint32_t event); - int (*txrx_get_sec_type)(struct cdp_peer *peer, uint8_t sec_idx); + int (*txrx_get_sec_type)(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, uint8_t sec_idx); - void (*txrx_update_mgmt_txpow_vdev)(struct cdp_vdev *vdev, - uint8_t subtype, uint8_t tx_power); + QDF_STATUS + (*txrx_update_mgmt_txpow_vdev)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t subtype, uint8_t tx_power); /** * txrx_set_pdev_param() - callback to set pdev parameter * @soc: opaque soc handle - * @pdev: data path pdev handle + * @pdev_id:id of data path pdev handle * @val: value of pdev_tx_capture * * Return: status: 0 - Success, non-zero: Failure */ - QDF_STATUS (*txrx_set_pdev_param)(struct cdp_pdev *pdev, + QDF_STATUS (*txrx_set_pdev_param)(struct cdp_soc_t *soc, + uint8_t pdev_id, enum cdp_pdev_param_type type, - uint8_t val); - void * (*txrx_get_pldev)(struct cdp_pdev *pdev); + cdp_config_param_type val); + QDF_STATUS (*txrx_get_pdev_param)(struct cdp_soc_t *soc, + uint8_t pdev_id, + enum cdp_pdev_param_type type, + cdp_config_param_type *val); + + QDF_STATUS (*txrx_set_peer_param)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t *peer_mac, + enum cdp_peer_param_type param, + cdp_config_param_type val); + + QDF_STATUS (*txrx_get_peer_param)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t *peer_mac, + enum cdp_peer_param_type param, + cdp_config_param_type *val); + + void * (*txrx_get_pldev)(struct cdp_soc_t *soc, uint8_t pdev_id); +#ifdef VDEV_PEER_PROTOCOL_COUNT + void (*txrx_peer_protocol_cnt)(struct cdp_soc_t *soc, + int8_t vdev_id, + qdf_nbuf_t nbuf, + bool is_egress, + bool is_rx); +#endif #ifdef ATH_SUPPORT_NAC_RSSI - QDF_STATUS (*txrx_vdev_config_for_nac_rssi)(struct cdp_vdev *vdev, - enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, - uint8_t chan_num); - QDF_STATUS (*txrx_vdev_get_neighbour_rssi)(struct cdp_vdev *vdev, + QDF_STATUS (*txrx_vdev_config_for_nac_rssi)(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, + enum cdp_nac_param_cmd cmd, + char *bssid, + char *client_macaddr, + uint8_t chan_num); + + QDF_STATUS (*txrx_vdev_get_neighbour_rssi)(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, char *macaddr, uint8_t *rssi); #endif - void (*set_key)(struct cdp_peer *peer_handle, - bool is_unicast, uint32_t *key); + QDF_STATUS + (*set_key)(struct cdp_soc_t *soc, uint8_t vdev_id, uint8_t *mac, + bool is_unicast, uint32_t *key); - uint32_t (*txrx_get_vdev_param)(struct cdp_vdev *vdev, - enum cdp_vdev_param_type param); - int (*enable_peer_based_pktlog)(struct cdp_pdev - *txrx_pdev_handle, char *macaddr, uint8_t enb_dsb); + QDF_STATUS (*txrx_get_vdev_param)(struct cdp_soc_t *soc, + uint8_t vdev_id, + enum cdp_vdev_param_type param, + cdp_config_param_type *val); + int (*enable_peer_based_pktlog)(struct cdp_soc_t *cdp_soc, + uint8_t pdev_id, + uint8_t *macaddr, uint8_t enb_dsb); - void (*calculate_delay_stats)(struct cdp_vdev *vdev, qdf_nbuf_t nbuf); + QDF_STATUS + (*calculate_delay_stats)(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, qdf_nbuf_t nbuf); #ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG QDF_STATUS (*txrx_update_pdev_rx_protocol_tag)( - struct cdp_pdev *txrx_pdev_handle, + struct cdp_soc_t *soc, uint8_t pdev_id, uint32_t protocol_mask, uint16_t protocol_type, uint16_t tag); #ifdef WLAN_SUPPORT_RX_TAG_STATISTICS void (*txrx_dump_pdev_rx_protocol_tag_stats)( - struct cdp_pdev *txrx_pdev_handle, + struct cdp_soc_t *soc, uint8_t pdev_id, uint16_t protocol_type); #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#ifdef WLAN_SUPPORT_RX_FLOW_TAG + QDF_STATUS (*txrx_set_rx_flow_tag)( + struct cdp_soc_t *cdp_soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info); + QDF_STATUS (*txrx_dump_rx_flow_tag_stats)( + struct cdp_soc_t *cdp_soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info); +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ +#ifdef QCA_MULTIPASS_SUPPORT + void (*txrx_peer_set_vlan_id)(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, uint8_t *peer_mac, + uint16_t vlan_id); +#endif +#if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) + QDF_STATUS (*txrx_update_peer_pkt_capture_params)( + ol_txrx_soc_handle soc, uint8_t pdev_id, + bool is_rx_pkt_cap_enable, bool is_tx_pkt_cap_enable, + uint8_t *peer_mac); +#endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */ + QDF_STATUS + (*txrx_set_psoc_param)(struct cdp_soc_t *soc, + enum cdp_psoc_param_type param, + cdp_config_param_type val); + + QDF_STATUS (*txrx_get_psoc_param)(ol_txrx_soc_handle soc, + enum cdp_psoc_param_type type, + cdp_config_param_type *val); +#ifdef VDEV_PEER_PROTOCOL_COUNT + /* + * Enable per-peer protocol counters + */ + void (*txrx_enable_peer_protocol_count)(struct cdp_soc_t *soc, + int8_t vdev_id, bool enable); + void (*txrx_set_peer_protocol_drop_mask)(struct cdp_soc_t *soc, + int8_t vdev_id, int mask); + int (*txrx_is_peer_protocol_count_enabled)(struct cdp_soc_t *soc, + int8_t vdev_id); + int (*txrx_get_peer_protocol_drop_mask)(struct cdp_soc_t *soc, + int8_t vdev_id); + +#endif }; struct cdp_me_ops { - u_int16_t (*tx_desc_alloc_and_mark_for_mcast_clone) - (struct cdp_pdev *pdev, u_int16_t buf_count); - - u_int16_t (*tx_desc_free_and_unmark_for_mcast_clone)( - struct cdp_pdev *pdev, - u_int16_t buf_count); - - u_int16_t - (*tx_get_mcast_buf_allocated_marked) - (struct cdp_pdev *pdev); - void - (*tx_me_alloc_descriptor)(struct cdp_pdev *pdev); - - void - (*tx_me_free_descriptor)(struct cdp_pdev *pdev); + void (*tx_me_alloc_descriptor)(struct cdp_soc_t *soc, + uint8_t pdev_id); - uint16_t - (*tx_me_convert_ucast)(struct cdp_vdev *vdev, - qdf_nbuf_t wbuf, u_int8_t newmac[][6], - uint8_t newmaccnt); - /* Should be a function pointer in ol_txrx_osif_ops{} */ - /** - * @brief notify mcast frame indication from FW. - * @details - * This notification will be used to convert - * multicast frame to unicast. - * - * @param pdev - handle to the ctrl SW's physical device object - * @param vdev_id - ID of the virtual device received the special data - * @param msdu - the multicast msdu returned by FW for host inspect - */ + void (*tx_me_free_descriptor)(struct cdp_soc_t *soc, uint8_t pdev_id); - int (*mcast_notify)(struct cdp_pdev *pdev, - u_int8_t vdev_id, qdf_nbuf_t msdu); + uint16_t (*tx_me_convert_ucast)(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t wbuf, u_int8_t newmac[][6], + uint8_t newmaccnt); }; struct cdp_mon_ops { - void (*txrx_monitor_set_filter_ucast_data) - (struct cdp_pdev *, u_int8_t val); - void (*txrx_monitor_set_filter_mcast_data) - (struct cdp_pdev *, u_int8_t val); - void (*txrx_monitor_set_filter_non_data) - (struct cdp_pdev *, u_int8_t val); - - bool (*txrx_monitor_get_filter_ucast_data) - (struct cdp_vdev *vdev_txrx_handle); - bool (*txrx_monitor_get_filter_mcast_data) - (struct cdp_vdev *vdev_txrx_handle); - bool (*txrx_monitor_get_filter_non_data) - (struct cdp_vdev *vdev_txrx_handle); - QDF_STATUS (*txrx_reset_monitor_mode)(struct cdp_pdev *pdev); + QDF_STATUS (*txrx_reset_monitor_mode) + (ol_txrx_soc_handle soc, uint8_t pdev_id, u_int8_t smart_monitor); + + QDF_STATUS (*txrx_deliver_tx_mgmt) + (struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf); /* HK advance monitor filter support */ QDF_STATUS (*txrx_set_advance_monitor_filter) - (struct cdp_pdev *pdev, struct cdp_monitor_filter *filter_val); - - void (*txrx_monitor_record_channel) - (struct cdp_pdev *, int val); + (struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct cdp_monitor_filter *filter_val); }; #ifdef WLAN_FEATURE_PKT_CAPTURE -/* - * struct cdp_pktcapture_ops - packet capture ops - * @txrx_pktcapture_record_channel: update channel information for packet - * capture mode - */ struct cdp_pktcapture_ops { + void (*txrx_pktcapture_set_mode) + (struct cdp_soc_t *soc, + uint8_t pdev_id, + uint8_t mode); + + uint8_t (*txrx_pktcapture_get_mode) + (struct cdp_soc_t *soc, + uint8_t pdev_id); + + QDF_STATUS (*txrx_pktcapture_cb_register) + (struct cdp_soc_t *soc, + uint8_t pdev_id, + void *context, + QDF_STATUS(cb)(void *, qdf_nbuf_t)); + + QDF_STATUS (*txrx_pktcapture_cb_deregister) + (struct cdp_soc_t *soc, + uint8_t pdev_id); + + QDF_STATUS (*txrx_pktcapture_mgmtpkt_process) + (struct cdp_soc_t *soc, + uint8_t pdev_id, + struct mon_rx_status *txrx_status, + qdf_nbuf_t nbuf, uint8_t status); + void (*txrx_pktcapture_record_channel) (struct cdp_soc_t *soc, - uint8_t pdev_id, - int chan_no); + uint8_t pdev_id, + int chan_no); }; #endif /* #ifdef WLAN_FEATURE_PKT_CAPTURE */ struct cdp_host_stats_ops { - int (*txrx_host_stats_get)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req); + int (*txrx_host_stats_get)(struct cdp_soc_t *soc, uint8_t vdev_id, + struct ol_txrx_stats_req *req); - void (*txrx_host_stats_clr)(struct cdp_vdev *vdev); + QDF_STATUS (*txrx_host_stats_clr)(struct cdp_soc_t *soc, + uint8_t vdev_id); - void (*txrx_host_ce_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*txrx_host_ce_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - int (*txrx_stats_publish)(struct cdp_pdev *pdev, - struct cdp_stats_extd *buf); + int (*txrx_stats_publish)(struct cdp_soc_t *soc, uint8_t pdev_id, + struct cdp_stats_extd *buf); /** * @brief Enable enhanced stats functionality. * - * @param pdev - the physical device object - * @return - void + * @param soc - the soc handle + * @param pdev_id - pdev_id of pdev + * @return - QDF_STATUS */ - void (*txrx_enable_enhanced_stats)(struct cdp_pdev *pdev); + QDF_STATUS (*txrx_enable_enhanced_stats)(struct cdp_soc_t *soc, + uint8_t pdev_id); /** * @brief Disable enhanced stats functionality. * - * @param pdev - the physical device object - * @return - void + * @param soc - the soc handle + * @param pdev_id - pdev_id of pdev + * @return - QDF_STATUS */ - void (*txrx_disable_enhanced_stats)(struct cdp_pdev *pdev); + QDF_STATUS (*txrx_disable_enhanced_stats)(struct cdp_soc_t *soc, + uint8_t pdev_id); - /** - * @brief Get the desired stats from the message. - * - * @param pdev - the physical device object - * @param stats_base - stats buffer received from FW - * @param type - stats type. - * @return - pointer to requested stat identified by type - */ - uint32_t * (*txrx_get_stats_base)(struct cdp_pdev *pdev, - uint32_t *stats_base, uint32_t msg_len, uint8_t type); - void - (*tx_print_tso_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*tx_print_tso_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*tx_rst_tso_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*tx_rst_tso_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*tx_print_sg_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*tx_print_sg_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*tx_rst_sg_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*tx_rst_sg_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*print_rx_cksum_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*print_rx_cksum_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*rst_rx_cksum_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*rst_rx_cksum_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - A_STATUS - (*txrx_host_me_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*txrx_host_me_stats)(struct cdp_soc_t *soc, uint8_t vdev_id); - void - (*txrx_per_peer_stats)(struct cdp_pdev *pdev, char *addr); + QDF_STATUS + (*txrx_per_peer_stats)(struct cdp_soc_t *soc, uint8_t *addr); - int (*txrx_host_msdu_ttl_stats)(struct cdp_vdev *vdev, - struct ol_txrx_stats_req *req); + int (*txrx_host_msdu_ttl_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, + struct ol_txrx_stats_req *req); - void - (*print_lro_stats)(struct cdp_vdev *vdev); + int (*ol_txrx_update_peer_stats)(struct cdp_soc_t *soc, + uint8_t pdev_id, + uint8_t *addr, void *stats, + uint32_t last_tx_rate_mcs, + uint32_t stats_id); - void - (*reset_lro_stats)(struct cdp_vdev *vdev); + QDF_STATUS + (*get_fw_peer_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t *addr, + uint32_t cap, uint32_t copy_stats); - void - (*get_fw_peer_stats)(struct cdp_pdev *pdev, uint8_t *addr, - uint32_t cap, uint32_t copy_stats); - void - (*get_htt_stats)(struct cdp_pdev *pdev, void *data, - uint32_t data_len); - void - (*txrx_update_pdev_stats)(struct cdp_pdev *pdev, void *data, + QDF_STATUS + (*get_htt_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, + void *data, + uint32_t data_len); + QDF_STATUS + (*txrx_update_pdev_stats)(struct cdp_soc_t *soc, + uint8_t pdev_id, void *data, uint16_t stats_id); - struct cdp_peer_stats* - (*txrx_get_peer_stats)(struct cdp_peer *peer); - void - (*txrx_reset_peer_ald_stats)(struct cdp_peer *peer); - void - (*txrx_reset_peer_stats)(struct cdp_peer *peer); + QDF_STATUS + (*txrx_get_peer_stats_param)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_stats_type type, + cdp_peer_stats_param_t *buf); + QDF_STATUS + (*txrx_get_peer_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, + struct cdp_peer_stats *peer_stats); + QDF_STATUS + (*txrx_reset_peer_ald_stats)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t *peer_mac); + QDF_STATUS + (*txrx_reset_peer_stats)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t *peer_mac); int - (*txrx_get_vdev_stats)(struct cdp_vdev *vdev, void *buf, - bool is_aggregate); + (*txrx_get_vdev_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, + void *buf, bool is_aggregate); int (*txrx_process_wmi_host_vdev_stats)(ol_txrx_soc_handle soc, void *data, uint32_t len, uint32_t stats_id); int - (*txrx_get_vdev_extd_stats)(struct cdp_vdev *vdev_handle, - void *buffer); - void - (*txrx_update_vdev_stats)(struct cdp_vdev *vdev, void *buf, + (*txrx_get_vdev_extd_stats)(struct cdp_soc_t *soc, + uint8_t vdev_id, + wmi_host_vdev_extd_stats *buffer); + QDF_STATUS + (*txrx_update_vdev_stats)(struct cdp_soc_t *soc, + uint8_t vdev_id, void *buf, uint16_t stats_id); int - (*txrx_get_radio_stats)(struct cdp_pdev *pdev, + (*txrx_get_radio_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, void *buf); - struct cdp_pdev_stats* - (*txrx_get_pdev_stats)(struct cdp_pdev *pdev); + QDF_STATUS + (*txrx_get_pdev_stats)(struct cdp_soc_t *soc, uint8_t pdev_id, + struct cdp_pdev_stats *buf); int (*txrx_get_ratekbps)(int preamb, int mcs, int htflag, int gintval); - void - (*configure_rate_stats)(struct cdp_soc_t *soc, - uint8_t val); + + QDF_STATUS + (*txrx_update_peer_stats)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, void *stats, + uint32_t last_tx_rate_mcs, + uint32_t stats_id); }; struct cdp_wds_ops { - void - (*txrx_set_wds_rx_policy)(struct cdp_vdev *vdev, - u_int32_t val); - void - (*txrx_wds_peer_tx_policy_update)(struct cdp_peer *peer, - int wds_tx_ucast, int wds_tx_mcast); - int (*vdev_set_wds)(void *vdev, uint32_t val); + QDF_STATUS + (*txrx_set_wds_rx_policy)(struct cdp_soc_t *soc, uint8_t vdev_id, + u_int32_t val); + QDF_STATUS + (*txrx_wds_peer_tx_policy_update)(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t *peer_mac, + int wds_tx_ucast, int wds_tx_mcast); + int (*vdev_set_wds)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint32_t val); }; struct cdp_raw_ops { - int (*txrx_get_nwifi_mode)(struct cdp_vdev *vdev); + int (*txrx_get_nwifi_mode)(struct cdp_soc_t *soc, uint8_t vdev_id); - void (*rsim_get_astentry)(struct cdp_vdev *vdev, - qdf_nbuf_t *pnbuf, - struct cdp_raw_ast *raw_ast); + QDF_STATUS + (*rsim_get_astentry)(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t *pnbuf, struct cdp_raw_ast *raw_ast); }; #ifdef PEER_FLOW_CONTROL struct cdp_pflow_ops { - uint32_t(*pflow_update_pdev_params)(void *, - enum _ol_ath_param_t, uint32_t, void *); + uint32_t (*pflow_update_pdev_params)(struct cdp_soc_t *soc, + uint8_t pdev_id, + enum _ol_ath_param_t, + uint32_t, void *); }; #endif /* PEER_FLOW_CONTROL */ @@ -906,196 +979,380 @@ struct cdp_lro_hash_config { struct ol_if_ops { void - (*peer_set_default_routing)(struct cdp_ctrl_objmgr_pdev *ctrl_pdev, - uint8_t *peer_macaddr, uint8_t vdev_id, + (*peer_set_default_routing)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + uint8_t pdev_id, uint8_t *peer_macaddr, + uint8_t vdev_id, bool hash_based, uint8_t ring_num); QDF_STATUS - (*peer_rx_reorder_queue_setup)(struct cdp_ctrl_objmgr_pdev *ctrl_pdev, + (*peer_rx_reorder_queue_setup)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_mac, qdf_dma_addr_t hw_qdesc, int tid, uint16_t queue_num, uint8_t ba_window_size_valid, uint16_t ba_window_size); QDF_STATUS - (*peer_rx_reorder_queue_remove)(struct cdp_ctrl_objmgr_pdev *ctrl_pdev, + (*peer_rx_reorder_queue_remove)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, uint32_t tid_mask); - int (*peer_unref_delete)(void *scn_handle, uint8_t *peer_mac, - uint8_t *vdev_mac, enum wlan_op_mode opmode, - void *old_peer, void *new_peer); + int (*peer_unref_delete)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, + uint8_t *peer_mac, + uint8_t *vdev_mac, enum wlan_op_mode opmode); bool (*is_hw_dbs_2x2_capable)(struct wlan_objmgr_psoc *psoc); - int (*peer_add_wds_entry)(void *vdev_handle, - struct cdp_peer *peer_handle, + int (*peer_add_wds_entry)(struct cdp_ctrl_objmgr_psoc *soc, + uint8_t vdev_id, + uint8_t *peer_macaddr, const uint8_t *dest_macaddr, uint8_t *next_node_mac, - uint32_t flags); - int (*peer_update_wds_entry)(void *ol_soc_handle, - uint8_t *dest_macaddr, uint8_t *peer_macaddr, - uint32_t flags); - void (*peer_del_wds_entry)(void *ol_soc_handle, + uint32_t flags, + uint8_t type); + int (*peer_update_wds_entry)(struct cdp_ctrl_objmgr_psoc *soc, + uint8_t vdev_id, + uint8_t *dest_macaddr, + uint8_t *peer_macaddr, + uint32_t flags); + void (*peer_del_wds_entry)(struct cdp_ctrl_objmgr_psoc *soc, + uint8_t vdev_id, uint8_t *wds_macaddr, uint8_t type); QDF_STATUS - (*lro_hash_config)(struct cdp_ctrl_objmgr_pdev *ctrl_pdev, + (*lro_hash_config)(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, struct cdp_lro_hash_config *rx_offld_hash); + void (*update_dp_stats)(void *soc, void *stats, uint16_t id, uint8_t type); -#ifdef CONFIG_MCL - uint8_t (*rx_invalid_peer)(uint8_t vdev_id, void *wh); +#ifdef FEATURE_NAC_RSSI + uint8_t (*rx_invalid_peer)(struct cdp_ctrl_objmgr_psoc *soc, + uint8_t pdev_id, void *msg); #else - uint8_t (*rx_invalid_peer)(void *ctrl_pdev, void *msg); + uint8_t (*rx_invalid_peer)(uint8_t vdev_id, void *wh); #endif - int (*peer_map_event)(void *ol_soc_handle, uint16_t peer_id, uint16_t hw_peer_id, - uint8_t vdev_id, uint8_t *peer_mac_addr, - enum cdp_txrx_ast_entry_type peer_type, - uint32_t tx_ast_hashidx); - int (*peer_unmap_event)(void *ol_soc_handle, uint16_t peer_id, + + int (*peer_map_event)(struct cdp_ctrl_objmgr_psoc *psoc, + uint16_t peer_id, uint16_t hw_peer_id, + uint8_t vdev_id, uint8_t *peer_mac_addr, + enum cdp_txrx_ast_entry_type peer_type, + uint32_t tx_ast_hashidx); + int (*peer_unmap_event)(struct cdp_ctrl_objmgr_psoc *psoc, + uint16_t peer_id, uint8_t vdev_id); - int (*get_dp_cfg_param)(void *ol_soc_handle, enum cdp_cfg_param_type param_num); + int (*get_dp_cfg_param)(struct cdp_ctrl_objmgr_psoc *psoc, + enum cdp_cfg_param_type param_num); + + void (*rx_mic_error)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, + struct cdp_rx_mic_err_info *info); - void (*rx_mic_error)(void *ol_soc_handle, - uint16_t vdev_id, void *wh); - bool (*rx_frag_tkip_demic)(struct wlan_objmgr_peer *ctrl_peer, + bool (*rx_frag_tkip_demic)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *peer_mac_addr, qdf_nbuf_t nbuf, uint16_t hdr_space); - uint8_t (*freq_to_channel)(void *ol_soc_handle, uint16_t vdev_id); - void (*record_act_change)(struct wlan_objmgr_pdev *pdev, - u_int8_t *dstmac, bool active); + uint8_t (*freq_to_channel)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t freq); + #ifdef ATH_SUPPORT_NAC_RSSI - int (*config_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev, - u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid, - char *client_macaddr, uint8_t chan_num); - int (*config_bssid_in_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev, - u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid); + int (*config_fw_for_nac_rssi)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, + u_int8_t vdev_id, + enum cdp_nac_param_cmd cmd, char *bssid, + char *client_macaddr, uint8_t chan_num); + + int + (*config_bssid_in_fw_for_nac_rssi)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, u_int8_t vdev_id, + enum cdp_nac_param_cmd cmd, + char *bssid, char *client_mac); #endif - int (*peer_sta_kickout)(void *ctrl_pdev, uint8_t *peer_macaddr); + int (*peer_sta_kickout)(struct cdp_ctrl_objmgr_psoc *psoc, + uint16_t pdev_id, uint8_t *peer_macaddr); /** * send_delba() - Send delba to peer - * @pdev_handle: Dp pdev handle - * @ctrl_peer: Peer handle + * @psoc: Objmgr soc handle + * @vdev_id: dp vdev id * @peer_macaddr: Peer mac addr * @tid: Tid number * * Return: 0 for success, non-zero for failure */ - int (*send_delba)(void *pdev_handle, void *ctrl_peer, - uint8_t *peer_macaddr, uint8_t tid, void *vdev_handle, + int (*send_delba)(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t vdev_id, + uint8_t *peer_macaddr, uint8_t tid, uint8_t reason_code); - int (*peer_delete_multiple_wds_entries)(void *vdev_handle, - uint8_t *dest_macaddr, - uint8_t *peer_macaddr, - uint32_t flags); + int + (*peer_delete_multiple_wds_entries)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t vdev_id, + uint8_t *dest_macaddr, + uint8_t *peer_macaddr, + uint32_t flags); + int + (*pdev_update_lmac_n_target_pdev_id)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t *pdev_id, + uint8_t *lmac_id, + uint8_t *target_pdev_id); bool (*is_roam_inprogress)(uint32_t vdev_id); enum QDF_GLOBAL_MODE (*get_con_mode)(void); +#ifdef QCA_PEER_MULTIQ_SUPPORT + int (*peer_ast_flowid_map)(struct cdp_ctrl_objmgr_psoc *ol_soc_handle, + uint16_t peer_id, uint8_t vdev_id, + uint8_t *peer_mac_addr); +#endif +#ifdef DP_MEM_PRE_ALLOC + void *(*dp_prealloc_get_context)(uint32_t ctxt_type); + + QDF_STATUS(*dp_prealloc_put_context)(uint32_t ctxt_type, void *vaddr); + void *(*dp_prealloc_get_consistent)(uint32_t *size, + void **base_vaddr_unaligned, + qdf_dma_addr_t *paddr_unaligned, + qdf_dma_addr_t *paddr_aligned, + uint32_t align, + uint32_t ring_type); + void (*dp_prealloc_put_consistent)(qdf_size_t size, + void *vaddr_unligned, + qdf_dma_addr_t paddr); + void (*dp_get_multi_pages)(uint32_t desc_type, + size_t element_size, + uint16_t element_num, + struct qdf_mem_multi_page_t *pages, + bool cacheable); + void (*dp_put_multi_pages)(uint32_t desc_type, + struct qdf_mem_multi_page_t *pages); +#endif + int (*dp_rx_get_pending)(ol_txrx_soc_handle soc); /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; -#ifdef CONFIG_MCL -/* From here MCL specific OPs */ + +#ifdef DP_PEER_EXTENDED_API /** * struct cdp_misc_ops - mcl ops not classified - * @set_ibss_vdev_heart_beat_timer: - * @bad_peer_txctl_set_setting: - * @bad_peer_txctl_update_threshold: - * @hl_tdls_flag_reset: - * @tx_non_std: - * @get_vdev_id: - * @set_wisa_mode: - * @txrx_data_stall_cb_register: - * @txrx_data_stall_cb_deregister: - * @txrx_post_data_stall_event - * @runtime_suspend: - * @runtime_resume: - * @register_packetdump_cb: - * @unregister_packetdump_cb: - * @pdev_reset_driver_del_ack: - * @vdev_set_driver_del_ack_enable: + * @set_ibss_vdev_heart_beat_timer: Update ibss vdev heart beat timer + * @set_wmm_param: set wmm parameters + * @bad_peer_txctl_set_setting: configure bad peer tx limit setting + * @bad_peer_txctl_update_threshold: configure bad peer tx threshold limit + * @hl_tdls_flag_reset: reset tdls flag for vdev + * @tx_non_std: Allow the control-path SW to send data frames + * @get_vdev_id: get vdev id + * @set_wisa_mode: set wisa mode for a vdev + * @txrx_data_stall_cb_register: register data stall callback + * @txrx_data_stall_cb_deregister: deregister data stall callback + * @txrx_post_data_stall_event: post data stall event + * @runtime_suspend: ensure TXRX is ready to runtime suspend + * @runtime_resume: ensure TXRX is ready to runtime resume + * @get_opmode: get operation mode of vdev + * @mark_first_wakeup_packet: set flag to indicate that fw is compatible for + marking first packet after wow wakeup + * @update_mac_id: update mac_id for vdev + * @flush_rx_frames: flush rx frames on the queue + * @get_intra_bss_fwd_pkts_count: to get the total tx and rx packets that + has been forwarded from txrx layer + without going to upper layers + * @pkt_log_init: handler to initialize packet log + * @pkt_log_con_service: handler to connect packet log service + * @get_num_rx_contexts: handler to get number of RX contexts + * @register_packetdump_cb: register callback for different pktlog + * @unregister_packetdump_cb: unregister callback for different pktlog + * @pdev_reset_driver_del_ack: reset driver delayed ack enabled flag + * @vdev_set_driver_del_ack_enable: set driver delayed ack enabled flag + * + * Function pointers for miscellaneous soc/pdev/vdev related operations. */ struct cdp_misc_ops { - uint16_t (*set_ibss_vdev_heart_beat_timer)(struct cdp_vdev *vdev, - uint16_t timer_value_sec); - void (*set_wmm_param)(struct cdp_pdev *cfg_pdev, - struct ol_tx_wmm_param_t wmm_param); - void (*bad_peer_txctl_set_setting)(struct cdp_pdev *pdev, int enable, - int period, int txq_limit); - void (*bad_peer_txctl_update_threshold)(struct cdp_pdev *pdev, - int level, int tput_thresh, int tx_limit); - void (*hl_tdls_flag_reset)(struct cdp_vdev *vdev, bool flag); - qdf_nbuf_t (*tx_non_std)(struct cdp_vdev *vdev, - enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); + uint16_t (*set_ibss_vdev_heart_beat_timer)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint16_t timer_value_sec); + void (*set_wmm_param)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct ol_tx_wmm_param_t wmm_param); + void (*bad_peer_txctl_set_setting)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int enable, + int period, int txq_limit); + void (*bad_peer_txctl_update_threshold)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + int level, int tput_thresh, + int tx_limit); + void (*hl_tdls_flag_reset)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool flag); + qdf_nbuf_t (*tx_non_std)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); uint16_t (*get_vdev_id)(struct cdp_vdev *vdev); - uint32_t (*get_tx_ack_stats)(struct cdp_pdev *pdev, uint8_t vdev_id); - QDF_STATUS (*set_wisa_mode)(struct cdp_vdev *vdev, bool enable); - QDF_STATUS (*txrx_data_stall_cb_register)( - struct cdp_pdev *pdev, - data_stall_detect_cb cb); - QDF_STATUS (*txrx_data_stall_cb_deregister)( - struct cdp_pdev *pdev, - data_stall_detect_cb cb); + uint32_t (*get_tx_ack_stats)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id); + QDF_STATUS (*set_wisa_mode)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool enable); + QDF_STATUS (*txrx_data_stall_cb_register)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + data_stall_detect_cb cb); + QDF_STATUS (*txrx_data_stall_cb_deregister)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + data_stall_detect_cb cb); void (*txrx_post_data_stall_event)( - struct cdp_pdev *pdev, + struct cdp_soc_t *soc_hdl, enum data_stall_log_event_indicator indicator, enum data_stall_log_event_type data_stall_type, uint32_t pdev_id, uint32_t vdev_id_bitmap, enum data_stall_log_recovery_type recovery_type); - QDF_STATUS (*runtime_suspend)(struct cdp_pdev *pdev); - QDF_STATUS (*runtime_resume)(struct cdp_pdev *pdev); - int (*get_opmode)(struct cdp_vdev *vdev); - void (*mark_first_wakeup_packet)(uint8_t value); - void (*update_mac_id)(uint8_t vdev_id, uint8_t mac_id); - void (*flush_rx_frames)(void *peer, bool drop); - A_STATUS (*get_intra_bss_fwd_pkts_count)(uint8_t vdev_id, - uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets); - void (*pkt_log_init)(struct cdp_pdev *handle, void *scn); - void (*pkt_log_con_service)(struct cdp_pdev *pdev, void *scn); - int (*get_num_rx_contexts)(struct cdp_soc_t *soc); - void (*register_pktdump_cb)(ol_txrx_pktdump_cb tx_cb, + QDF_STATUS (*runtime_suspend)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*runtime_resume)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + int (*get_opmode)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id); + void (*mark_first_wakeup_packet)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t value); + void (*update_mac_id)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t mac_id); + void (*flush_rx_frames)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *peer, bool drop); + A_STATUS(*get_intra_bss_fwd_pkts_count)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint64_t *fwd_tx_packets, + uint64_t *fwd_rx_packets); + void (*pkt_log_init)(struct cdp_soc_t *soc_hdl, uint8_t pdev, + void *scn); + void (*pkt_log_con_service)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *scn); + int (*get_num_rx_contexts)(struct cdp_soc_t *soc_hdl); + void (*register_pktdump_cb)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + ol_txrx_pktdump_cb tx_cb, ol_txrx_pktdump_cb rx_cb); - void (*unregister_pktdump_cb)(void); - void (*pdev_reset_driver_del_ack)(struct cdp_pdev *ppdev); - void (*vdev_set_driver_del_ack_enable)(uint8_t vdev_id, + void (*unregister_pktdump_cb)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + void (*pdev_reset_driver_del_ack)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + void (*vdev_set_driver_del_ack_enable)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, unsigned long rx_packets, uint32_t time_in_ms, uint32_t high_th, uint32_t low_th); - QDF_STATUS (*txrx_ext_stats_request)(struct cdp_pdev *pdev, + void (*vdev_set_bundle_require_flag)(uint8_t vdev_id, + unsigned long tx_bytes, + uint32_t time_in_ms, + uint32_t high_th, + uint32_t low_th); + void (*pdev_reset_bundle_require_flag)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*txrx_ext_stats_request)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, struct cdp_txrx_ext_stats *req); QDF_STATUS (*request_rx_hw_stats)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id); }; /** - * struct cdp_tx_delay_ops - mcl tx delay ops - * @tx_delay: - * @tx_delay_hist: - * @tx_packet_count: - * @tx_set_compute_interval: + * struct cdp_ocb_ops - mcl ocb ops + * @set_ocb_chan_info: set OCB channel info + * @get_ocb_chan_info: get OCB channel info + * + * Function pointers for operations related to OCB. */ -struct cdp_tx_delay_ops { - void (*tx_delay)(struct cdp_pdev *pdev, uint32_t *queue_delay_microsec, - uint32_t *tx_delay_microsec, int category); - void (*tx_delay_hist)(struct cdp_pdev *pdev, - uint16_t *bin_values, int category); - void (*tx_packet_count)(struct cdp_pdev *pdev, - uint16_t *out_packet_count, - uint16_t *out_packet_loss_count, int category); - void (*tx_set_compute_interval)(struct cdp_pdev *pdev, - uint32_t interval); +struct cdp_ocb_ops { + void (*set_ocb_chan_info)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + struct ol_txrx_ocb_set_chan ocb_set_chan); + struct ol_txrx_ocb_chan_info *(*get_ocb_chan_info)( + struct cdp_soc_t *soc_hdl, uint8_t vdev_id); +}; + +/** + * struct cdp_peer_ops - mcl peer related ops + * @register_peer: + * @clear_peer: + * @find_peer_exist + * @find_peer_exist_on_vdev + * @find_peer_exist_on_other_vdev + * @peer_state_update: + * @get_vdevid: + * @register_ocb_peer: + * @peer_get_peer_mac_addr: + * @get_peer_state: + * @update_ibss_add_peer_num_of_vdev: + * @copy_mac_addr_raw: + * @add_last_real_peer: + * @is_vdev_restore_last_peer: + * @update_last_real_peer: + */ +struct cdp_peer_ops { + QDF_STATUS (*register_peer)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct ol_txrx_desc_type *sta_desc); + QDF_STATUS (*clear_peer)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr); + bool (*find_peer_exist)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t *peer_addr); + bool (*find_peer_exist_on_vdev)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_addr); + bool (*find_peer_exist_on_other_vdev)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t *peer_addr, + uint16_t max_bssid); + QDF_STATUS (*peer_state_update)(struct cdp_soc_t *soc, + uint8_t *peer_addr, + enum ol_txrx_peer_state state); + QDF_STATUS (*get_vdevid)(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t *vdev_id); + struct cdp_vdev * (*get_vdev_by_peer_addr)(struct cdp_pdev *pdev, + struct qdf_mac_addr peer_addr); + QDF_STATUS (*register_ocb_peer)(uint8_t *mac_addr); + uint8_t * (*peer_get_peer_mac_addr)(void *peer); + int (*get_peer_state)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac); + struct cdp_vdev * (*get_vdev_for_peer)(void *peer); + int16_t (*update_ibss_add_peer_num_of_vdev)(struct cdp_soc_t *soc, + uint8_t vdev_id, + int16_t peer_num_delta); + void (*remove_peers_for_vdev)(struct cdp_vdev *vdev, + ol_txrx_vdev_peer_remove_cb callback, + void *callback_context, bool remove_last_peer); + void (*remove_peers_for_vdev_no_lock)(struct cdp_vdev *vdev, + ol_txrx_vdev_peer_remove_cb callback, + void *callback_context); + void (*copy_mac_addr_raw)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *bss_addr); + void (*add_last_real_peer)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id); + bool (*is_vdev_restore_last_peer)(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t *peer_mac); + void (*update_last_real_peer)(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id, bool restore_last_peer); + void (*peer_detach_force_delete)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_addr); + void (*set_tdls_offchan_enabled)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val); + void (*set_peer_as_tdls_peer)(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val); + void (*peer_flush_frags)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_mac); +}; + +/** + * struct cdp_mob_stats_ops - mcl mob stats ops + * @clear_stats: handler to clear ol txrx stats + * @stats: handler to update ol txrx stats + */ +struct cdp_mob_stats_ops { + QDF_STATUS(*clear_stats)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t bitmap); + int (*stats)(uint8_t vdev_id, char *buffer, unsigned buf_len); }; /** * struct cdp_pmf_ops - mcl protected management frame ops - * @get_pn_info: + * @get_pn_info: handler to get pn info from peer + * + * Function pointers for pmf related operations. */ struct cdp_pmf_ops { - void (*get_pn_info)(void *peer, uint8_t **last_pn_valid, - uint64_t **last_pn, uint32_t **rmf_pn_replays); + void (*get_pn_info)(struct cdp_soc_t *soc, uint8_t *peer_mac, + uint8_t vdev_id, uint8_t **last_pn_valid, + uint64_t **last_pn, uint32_t **rmf_pn_replays); }; +#endif + +#ifdef DP_FLOW_CTL /** * struct cdp_cfg_ops - mcl configuration ops * @set_cfg_rx_fwd_disabled: set rx_fwd_disabled flag @@ -1127,7 +1384,8 @@ struct cdp_cfg_ops { void (*set_cfg_packet_log_enabled)(struct cdp_cfg *cfg_pdev, uint8_t val); struct cdp_cfg * (*cfg_attach)(qdf_device_t osdev, void *cfg_param); - void (*vdev_rx_set_intrabss_fwd)(struct cdp_vdev *vdev, bool val); + void (*vdev_rx_set_intrabss_fwd)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool val); uint8_t (*is_rx_fwd_disabled)(struct cdp_vdev *vdev); void (*tx_set_is_mgmt_over_wmi_enabled)(uint8_t value); int (*is_high_latency)(struct cdp_cfg *cfg_pdev); @@ -1144,59 +1402,94 @@ struct cdp_cfg_ops { /** * struct cdp_flowctl_ops - mcl flow control - * @register_pause_cb: - * @set_desc_global_pool_size: - * @dump_flow_pool_info: + * @flow_pool_map_handler: handler to map flow_id and pool descriptors + * @flow_pool_unmap_handler: handler to unmap flow_id and pool descriptors + * @register_pause_cb: handler to register tx pause callback + * @set_desc_global_pool_size: handler to set global pool size + * @dump_flow_pool_info: handler to dump global and flow pool info + * @tx_desc_thresh_reached: handler to set tx desc threshold + * + * Function pointers for operations related to flow control */ struct cdp_flowctl_ops { QDF_STATUS (*flow_pool_map_handler)(struct cdp_soc_t *soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, uint8_t vdev_id); void (*flow_pool_unmap_handler)(struct cdp_soc_t *soc, - struct cdp_pdev *pdev, + uint8_t pdev_id, uint8_t vdev_id); QDF_STATUS (*register_pause_cb)(struct cdp_soc_t *soc, tx_pause_callback); void (*set_desc_global_pool_size)(uint32_t num_msdu_desc); - void (*dump_flow_pool_info)(void *); + void (*dump_flow_pool_info)(struct cdp_soc_t *soc_hdl); - bool (*tx_desc_thresh_reached)(struct cdp_vdev *vdev); + bool (*tx_desc_thresh_reached)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id); }; /** * struct cdp_lflowctl_ops - mcl legacy flow control ops - * @register_tx_flow_control: - * @deregister_tx_flow_control_cb: - * @flow_control_cb: - * @get_tx_resource: - * @ll_set_tx_pause_q_depth: - * @vdev_flush: - * @vdev_pause: - * @vdev_unpause: + * @register_tx_flow_control: Register tx flow control callback + * @set_vdev_tx_desc_limit: Set tx descriptor limit for a vdev + * @set_vdev_os_queue_status: Set vdev queue status + * @deregister_tx_flow_control_cb: Deregister tx flow control callback + * @flow_control_cb: Call osif flow control callback + * @get_tx_resource: Get tx resources and comapre with watermark + * @ll_set_tx_pause_q_depth: set pause queue depth + * @vdev_flush: Flush all packets on a particular vdev + * @vdev_pause: Pause a particular vdev + * @vdev_unpause: Unpause a particular vdev + * + * Function pointers for operations related to flow control */ struct cdp_lflowctl_ops { #ifdef QCA_HL_NETDEV_FLOW_CONTROL - int (*register_tx_flow_control)(struct cdp_soc_t *soc, + int (*register_tx_flow_control)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, tx_pause_callback flowcontrol); - int (*set_vdev_tx_desc_limit)(uint8_t vdev_id, uint8_t chan); - int (*set_vdev_os_queue_status)(uint8_t vdev_id, + int (*set_vdev_tx_desc_limit)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint32_t chan_freq); + int (*set_vdev_os_queue_status)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, enum netif_action_type action); #else - int (*register_tx_flow_control)(uint8_t vdev_id, + int (*register_tx_flow_control)( + struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, ol_txrx_tx_flow_control_fp flowControl, void *osif_fc_ctx, ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause); #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ - int (*deregister_tx_flow_control_cb)(uint8_t vdev_id); - void (*flow_control_cb)(struct cdp_vdev *vdev, bool tx_resume); - bool (*get_tx_resource)(uint8_t sta_id, - unsigned int low_watermark, - unsigned int high_watermark_offset); - int (*ll_set_tx_pause_q_depth)(uint8_t vdev_id, int pause_q_depth); - void (*vdev_flush)(struct cdp_vdev *vdev); - void (*vdev_pause)(struct cdp_vdev *vdev, uint32_t reason); - void (*vdev_unpause)(struct cdp_vdev *vdev, uint32_t reason); + int (*deregister_tx_flow_control_cb)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id); + void (*flow_control_cb)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + bool tx_resume); + bool (*get_tx_resource)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr, + unsigned int low_watermark, + unsigned int high_watermark_offset); + int (*ll_set_tx_pause_q_depth)(struct cdp_soc_t *soc, uint8_t vdev_id, + int pause_q_depth); + void (*vdev_flush)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id); + void (*vdev_pause)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type); + void (*vdev_unpause)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type); +}; + +/** + * struct cdp_throttle_ops - mcl throttle ops + * @throttle_init_period: handler to initialize tx throttle time + * @throttle_set_level: handler to set tx throttle level + */ +struct cdp_throttle_ops { + void (*throttle_init_period)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int period, + uint8_t *dutycycle_level); + void (*throttle_set_level)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int level); }; +#endif #ifdef IPA_OFFLOAD /** @@ -1210,176 +1503,109 @@ struct cdp_lflowctl_ops { * @ipa_tx_data_frame: */ struct cdp_ipa_ops { - QDF_STATUS (*ipa_get_resource)(struct cdp_pdev *pdev); - QDF_STATUS (*ipa_set_doorbell_paddr)(struct cdp_pdev *pdev); - QDF_STATUS (*ipa_set_active)(struct cdp_pdev *pdev, bool uc_active, - bool is_tx); - QDF_STATUS (*ipa_op_response)(struct cdp_pdev *pdev, uint8_t *op_msg); - QDF_STATUS (*ipa_register_op_cb)(struct cdp_pdev *pdev, - void (*ipa_uc_op_cb_type)(uint8_t *op_msg, void *osif_ctxt), - void *usr_ctxt); - QDF_STATUS (*ipa_get_stat)(struct cdp_pdev *pdev); - qdf_nbuf_t (*ipa_tx_data_frame)(struct cdp_vdev *vdev, qdf_nbuf_t skb); + QDF_STATUS (*ipa_get_resource)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*ipa_set_doorbell_paddr)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*ipa_set_active)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool uc_active, bool is_tx); + QDF_STATUS (*ipa_op_response)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t *op_msg); + QDF_STATUS (*ipa_register_op_cb)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + void (*ipa_uc_op_cb_type) + (uint8_t *op_msg, void *osif_ctxt), + void *usr_ctxt); + QDF_STATUS (*ipa_get_stat)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + qdf_nbuf_t (*ipa_tx_data_frame)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, qdf_nbuf_t skb); void (*ipa_set_uc_tx_partition_base)(struct cdp_cfg *pdev, uint32_t value); #ifdef FEATURE_METERING - QDF_STATUS (*ipa_uc_get_share_stats)(struct cdp_pdev *pdev, - uint8_t reset_stats); - QDF_STATUS (*ipa_uc_set_quota)(struct cdp_pdev *pdev, - uint64_t quota_bytes); + QDF_STATUS (*ipa_uc_get_share_stats)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + uint8_t reset_stats); + QDF_STATUS (*ipa_uc_set_quota)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint64_t quota_bytes); #endif - QDF_STATUS (*ipa_enable_autonomy)(struct cdp_pdev *pdev); - QDF_STATUS (*ipa_disable_autonomy)(struct cdp_pdev *pdev); + QDF_STATUS (*ipa_enable_autonomy)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*ipa_disable_autonomy)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); #ifdef CONFIG_IPA_WDI_UNIFIED_API - QDF_STATUS (*ipa_setup)(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, - uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, - uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, - bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, - bool over_gsi); + QDF_STATUS (*ipa_setup)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, + uint32_t ipa_desc_size, void *ipa_priv, + bool is_rm_enabled, uint32_t *tx_pipe_handle, + uint32_t *rx_pipe_handle, bool is_smmu_enabled, + qdf_ipa_sys_connect_params_t *sys_in, + bool over_gsi); #else /* CONFIG_IPA_WDI_UNIFIED_API */ - QDF_STATUS (*ipa_setup)(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, - uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, - uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle); + QDF_STATUS (*ipa_setup)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, + uint32_t ipa_desc_size, void *ipa_priv, + bool is_rm_enabled, uint32_t *tx_pipe_handle, + uint32_t *rx_pipe_handle); #endif /* CONFIG_IPA_WDI_UNIFIED_API */ - QDF_STATUS (*ipa_cleanup)(uint32_t tx_pipe_handle, - uint32_t rx_pipe_handle); + QDF_STATUS (*ipa_cleanup)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, + uint32_t rx_pipe_handle); QDF_STATUS (*ipa_setup_iface)(char *ifname, uint8_t *mac_addr, qdf_ipa_client_type_t prod_client, qdf_ipa_client_type_t cons_client, uint8_t session_id, bool is_ipv6_enabled); QDF_STATUS (*ipa_cleanup_iface)(char *ifname, bool is_ipv6_enabled); - QDF_STATUS (*ipa_enable_pipes)(struct cdp_pdev *pdev); - QDF_STATUS (*ipa_disable_pipes)(struct cdp_pdev *pdev); + QDF_STATUS (*ipa_enable_pipes)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS (*ipa_disable_pipes)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); QDF_STATUS (*ipa_set_perf_level)(int client, uint32_t max_supported_bw_mbps); - bool (*ipa_rx_intrabss_fwd)(struct cdp_vdev *vdev, qdf_nbuf_t nbuf, - bool *fwd_success); + bool (*ipa_rx_intrabss_fwd)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t nbuf, bool *fwd_success); }; #endif +#ifdef DP_POWER_SAVE +/** + * struct cdp_tx_delay_ops - mcl tx delay ops + * @tx_delay: handler to get tx packet delay + * @tx_delay_hist: handler to get tx packet delay histogram + * @tx_packet_count: handler to get tx packet count + * @tx_set_compute_interval: update compute interval period for TSM stats + * + * Function pointer for operations related to tx delay. + */ +struct cdp_tx_delay_ops { + void (*tx_delay)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t *queue_delay_microsec, + uint32_t *tx_delay_microsec, int category); + void (*tx_delay_hist)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint16_t *bin_values, int category); + void (*tx_packet_count)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint16_t *out_packet_count, + uint16_t *out_packet_loss_count, int category); + void (*tx_set_compute_interval)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint32_t interval); +}; + /** * struct cdp_bus_ops - mcl bus suspend/resume ops - * @bus_suspend: - * @bus_resume: + * @bus_suspend: handler for bus suspend + * @bus_resume: handler for bus resume * @process_wow_ack_rsp: handler for wow ack response * @process_target_suspend_req: handler for target suspend request */ struct cdp_bus_ops { - QDF_STATUS (*bus_suspend)(struct cdp_pdev *opaque_pdev); - QDF_STATUS (*bus_resume)(struct cdp_pdev *opaque_pdev); - void (*process_wow_ack_rsp)(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *opaque_pdev); + QDF_STATUS (*bus_suspend)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + QDF_STATUS (*bus_resume)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + void (*process_wow_ack_rsp)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); void (*process_target_suspend_req)(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *opaque_pdev); -}; - -/** - * struct cdp_ocb_ops - mcl ocb ops - * @set_ocb_chan_info: - * @get_ocb_chan_info: - */ -struct cdp_ocb_ops { - void (*set_ocb_chan_info)(struct cdp_vdev *vdev, - struct ol_txrx_ocb_set_chan ocb_set_chan); - struct ol_txrx_ocb_chan_info * - (*get_ocb_chan_info)(struct cdp_vdev *vdev); -}; - -/** - * struct cdp_peer_ops - mcl peer related ops - * @register_peer: - * @clear_peer: - * @cfg_attach: - * @find_peer_by_addr: - * @find_peer_by_addr_and_vdev: - * @local_peer_id: - * @peer_find_by_local_id: - * @peer_state_update: - * @get_vdevid: - * @get_vdev_by_sta_id: - * @register_ocb_peer: - * @peer_get_peer_mac_addr: - * @get_peer_state: - * @get_vdev_for_peer: - * @update_ibss_add_peer_num_of_vdev: - * @remove_peers_for_vdev: - * @remove_peers_for_vdev_no_lock: - * @copy_mac_addr_raw: - * @add_last_real_peer: - * @is_vdev_restore_last_peer: - * @update_last_real_peer: - */ -struct cdp_peer_ops { - QDF_STATUS (*register_peer)(struct cdp_pdev *pdev, - struct ol_txrx_desc_type *sta_desc); - QDF_STATUS (*clear_peer)(struct cdp_pdev *pdev, uint8_t sta_id); - QDF_STATUS (*change_peer_state)(uint8_t sta_id, - enum ol_txrx_peer_state sta_state, - bool roam_synch_in_progress); - void * (*peer_get_ref_by_addr)(struct cdp_pdev *pdev, - uint8_t *peer_addr, uint8_t *peer_id, - enum peer_debug_id_type debug_id); - void (*peer_release_ref)(void *peer, enum peer_debug_id_type debug_id); - void * (*find_peer_by_addr)(struct cdp_pdev *pdev, - uint8_t *peer_addr, uint8_t *peer_id); - void * (*find_peer_by_addr_and_vdev)(struct cdp_pdev *pdev, - struct cdp_vdev *vdev, - uint8_t *peer_addr, uint8_t *peer_id); - uint16_t (*local_peer_id)(void *peer); - void * (*peer_find_by_local_id)(struct cdp_pdev *pdev, - uint8_t local_peer_id); - QDF_STATUS (*peer_state_update)(struct cdp_pdev *pdev, - uint8_t *peer_addr, - enum ol_txrx_peer_state state); - QDF_STATUS (*get_vdevid)(void *peer, uint8_t *vdev_id); - struct cdp_vdev * (*get_vdev_by_sta_id)(struct cdp_pdev *pdev, - uint8_t sta_id); - QDF_STATUS (*register_ocb_peer)(uint8_t *mac_addr, uint8_t *peer_id); - uint8_t * (*peer_get_peer_mac_addr)(void *peer); - int (*get_peer_state)(void *peer); - struct cdp_vdev * (*get_vdev_for_peer)(void *peer); - int16_t (*update_ibss_add_peer_num_of_vdev)(struct cdp_vdev *vdev, - int16_t peer_num_delta); - void (*remove_peers_for_vdev)(struct cdp_vdev *vdev, - ol_txrx_vdev_peer_remove_cb callback, - void *callback_context, bool remove_last_peer); - void (*remove_peers_for_vdev_no_lock)(struct cdp_vdev *vdev, - ol_txrx_vdev_peer_remove_cb callback, - void *callback_context); - void (*copy_mac_addr_raw)(struct cdp_vdev *vdev, uint8_t *bss_addr); - void (*add_last_real_peer)(struct cdp_pdev *pdev, - struct cdp_vdev *vdev, uint8_t *peer_id); - bool (*is_vdev_restore_last_peer)(void *peer); - void (*update_last_real_peer)(struct cdp_pdev *pdev, void *vdev, - uint8_t *peer_id, bool restore_last_peer); - void (*peer_detach_force_delete)(void *peer); - void (*peer_flush_frags)(struct cdp_pdev *pdev, - uint8_t vdev_id, uint8_t *peer_mac); + uint8_t pdev_id); }; - -/** - * struct cdp_ocb_ops - mcl ocb ops - * @throttle_init_period: - * @throttle_set_level: - */ -struct cdp_throttle_ops { - void (*throttle_init_period)(struct cdp_pdev *pdev, int period, - uint8_t *dutycycle_level); - void (*throttle_set_level)(struct cdp_pdev *pdev, int level); -}; - -/** - * struct cdp_ocb_ops - mcl ocb ops - * @clear_stats: - * @stats: - */ -struct cdp_mob_stats_ops { - void (*clear_stats)(uint16_t bitmap); - int (*stats)(uint8_t vdev_id, char *buffer, unsigned buf_len); -}; -#endif /* CONFIG_MCL */ +#endif #ifdef RECEIVE_OFFLOAD /** @@ -1393,6 +1619,37 @@ struct cdp_rx_offld_ops { }; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * struct cdp_cfr_ops - host cfr ops + * @txrx_cfr_filter: Handler to configure host rx monitor status ring + * @txrx_get_cfr_rcc: Handler to get CFR mode + * @txrx_set_cfr_rcc: Handler to enable/disable CFR mode + * @txrx_get_cfr_dbg_stats: Handler to get debug statistics for CFR mode + * @txrx_clear_cfr_dbg_stats: Handler to clear debug statistics for CFR mode + * @txrx_enable_mon_reap_timer: Enable/Disable reap timer of monitor status ring + */ +struct cdp_cfr_ops { + void (*txrx_cfr_filter)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val); + bool (*txrx_get_cfr_rcc)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + void (*txrx_set_cfr_rcc)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable); + void (*txrx_get_cfr_dbg_stats)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + struct cdp_cfr_rcc_stats *buf); + void (*txrx_clear_cfr_dbg_stats)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + void (*txrx_enable_mon_reap_timer)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable); +}; +#endif + struct cdp_ops { struct cdp_cmn_ops *cmn_drv_ops; struct cdp_ctrl_ops *ctrl_ops; @@ -1402,27 +1659,35 @@ struct cdp_ops { struct cdp_wds_ops *wds_ops; struct cdp_raw_ops *raw_ops; struct cdp_pflow_ops *pflow_ops; -#ifdef CONFIG_MCL +#ifdef DP_PEER_EXTENDED_API struct cdp_misc_ops *misc_ops; + struct cdp_peer_ops *peer_ops; + struct cdp_ocb_ops *ocb_ops; + struct cdp_mob_stats_ops *mob_stats_ops; + struct cdp_pmf_ops *pmf_ops; +#endif +#ifdef DP_FLOW_CTL struct cdp_cfg_ops *cfg_ops; struct cdp_flowctl_ops *flowctl_ops; struct cdp_lflowctl_ops *l_flowctl_ops; + struct cdp_throttle_ops *throttle_ops; +#endif +#ifdef DP_POWER_SAVE + struct cdp_bus_ops *bus_ops; + struct cdp_tx_delay_ops *delay_ops; +#endif #ifdef IPA_OFFLOAD struct cdp_ipa_ops *ipa_ops; #endif #ifdef RECEIVE_OFFLOAD struct cdp_rx_offld_ops *rx_offld_ops; -#endif - struct cdp_bus_ops *bus_ops; - struct cdp_ocb_ops *ocb_ops; - struct cdp_peer_ops *peer_ops; - struct cdp_throttle_ops *throttle_ops; - struct cdp_mob_stats_ops *mob_stats_ops; - struct cdp_tx_delay_ops *delay_ops; - struct cdp_pmf_ops *pmf_ops; #endif #ifdef WLAN_FEATURE_PKT_CAPTURE struct cdp_pktcapture_ops *pktcapture_ops; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) + struct cdp_cfr_ops *cfr_ops; +#endif + }; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h index 19604ab93af6c3907b73d2fa85f18024838dcbba..2a394392029b78ca56f297e18268c655337c29ea 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,7 +29,7 @@ /** * cdp_peer_register() - Register peer into physical device * @soc - data path soc handle - * @pdev - data path device instance + * @pdev_id - data path device instance id * @sta_desc - peer description * * Register peer into physical device @@ -38,8 +38,8 @@ * QDF_STATUS_E_NOSUPPORT not support this feature */ static inline QDF_STATUS -cdp_peer_register(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - struct ol_txrx_desc_type *sta_desc) +cdp_peer_register(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct ol_txrx_desc_type *sta_desc) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -48,7 +48,8 @@ cdp_peer_register(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->peer_ops->register_peer) - return soc->ops->peer_ops->register_peer(pdev, sta_desc); + return soc->ops->peer_ops->register_peer(soc, pdev_id, + sta_desc); return QDF_STATUS_E_NOSUPPORT; } @@ -56,8 +57,8 @@ cdp_peer_register(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_clear_peer() - remove peer from physical device * @soc - data path soc handle - * @pdev - data path device instance - * @sta_id - local peer id + * @pdev_id - data path device instance id + * @peer_addr - peer mac address * * remove peer from physical device * @@ -65,7 +66,8 @@ cdp_peer_register(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, * QDF_STATUS_E_NOSUPPORT not support this feature */ static inline QDF_STATUS -cdp_clear_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, uint8_t sta_id) +cdp_clear_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct qdf_mac_addr peer_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -74,7 +76,7 @@ cdp_clear_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, uint8_t sta_id) } if (soc->ops->peer_ops->clear_peer) - return soc->ops->peer_ops->clear_peer(pdev, sta_id); + return soc->ops->peer_ops->clear_peer(soc, pdev_id, peer_addr); return QDF_STATUS_E_NOSUPPORT; } @@ -84,7 +86,6 @@ cdp_clear_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, uint8_t sta_id) * @soc - data path soc handle * @cds_ctx - cds void context * @mac_addr - mac address for ocb self peer - * @peer_id - local peer id * * register ocb peer from physical device * @@ -93,7 +94,7 @@ cdp_clear_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, uint8_t sta_id) */ static inline QDF_STATUS cdp_peer_register_ocb_peer(ol_txrx_soc_handle soc, - uint8_t *mac_addr, uint8_t *peer_id) + uint8_t *mac_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -102,213 +103,94 @@ cdp_peer_register_ocb_peer(ol_txrx_soc_handle soc, } if (soc->ops->peer_ops->register_ocb_peer) - return soc->ops->peer_ops->register_ocb_peer(mac_addr, peer_id); + return soc->ops->peer_ops->register_ocb_peer(mac_addr); return QDF_STATUS_E_NOSUPPORT; } /** - * cdp_peer_remove_for_vdev() - remove peer instance from virtual interface - * @soc - data path soc handle - * @vdev - virtual interface instance - * @callback - remove done notification callback function pointer - * @callback_context - callback caller context - * @remove_last_peer - removed peer is last peer or not - * - * remove peer instance from virtual interface - * - * Return: NONE - */ -static inline void -cdp_peer_remove_for_vdev(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, ol_txrx_vdev_peer_remove_cb callback, - void *callback_context, bool remove_last_peer) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return; - } - - if (soc->ops->peer_ops->remove_peers_for_vdev) - return soc->ops->peer_ops->remove_peers_for_vdev( - vdev, callback, callback_context, remove_last_peer); - - return; -} - -/** - * cdp_peer_remove_for_vdev_no_lock() - remove peer instance from vdev - * @soc - data path soc handle - * @vdev - virtual interface instance - * @callback - remove done notification callback function pointer - * @callback_context - callback caller context - * - * remove peer instance from virtual interface without lock - * - * Return: NONE - */ -static inline void -cdp_peer_remove_for_vdev_no_lock(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, - ol_txrx_vdev_peer_remove_cb callback, - void *callback_context) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return; - } - - if (soc->ops->peer_ops->remove_peers_for_vdev_no_lock) - return soc->ops->peer_ops->remove_peers_for_vdev_no_lock( - vdev, callback, callback_context); -} - -/** - * cdp_peer_get_ref_by_addr() - Find peer by peer mac address and inc peer ref - * @soc - data path soc handle - * @pdev - data path device instance - * @peer_addr - peer mac address - * @peer_id - local peer id with target mac address - * @debug_id - debug_id to track caller - * - * To release the peer ref, cdp_peer_release_ref needs to be called. - * - * Return: peer instance void pointer - * NULL cannot find target peer - */ -static inline void -*cdp_peer_get_ref_by_addr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t *peer_addr, uint8_t *peer_id, - enum peer_debug_id_type debug_id) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return NULL; - } - - if (soc->ops->peer_ops->peer_get_ref_by_addr) - return soc->ops->peer_ops->peer_get_ref_by_addr( - pdev, peer_addr, peer_id, debug_id); - - return NULL; -} - -/** - * cdp_peer_release_ref() - Release peer reference - * @soc - data path soc handle - * @peer - peer pointer - * @debug_id - debug_id to track caller - * - * Return:void - */ -static inline void -cdp_peer_release_ref(ol_txrx_soc_handle soc, void *peer, - enum peer_debug_id_type debug_id) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return; - } - - if (soc->ops->peer_ops->peer_release_ref) - soc->ops->peer_ops->peer_release_ref(peer, debug_id); -} - -/** - * cdp_peer_find_by_addr() - Find peer by peer mac address + * cdp_find_peer_exist - Find if peer already exists * @soc - data path soc handle - * @pdev - data path device instance + * @pdev_id - data path device instance id * @peer_addr - peer mac address - * @peer_id - local peer id with target mac address * - * Find peer and local peer id by peer mac address - * - * Return: peer instance void pointer - * NULL cannot find target peer + * Return: true or false */ -static inline void -*cdp_peer_find_by_addr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t *peer_addr, uint8_t *peer_id) +static inline bool +cdp_find_peer_exist(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint8_t *peer_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - return NULL; + return false; } - if (soc->ops->peer_ops->find_peer_by_addr) - return soc->ops->peer_ops->find_peer_by_addr( - pdev, peer_addr, peer_id); + if (soc->ops->peer_ops->find_peer_exist) + return soc->ops->peer_ops->find_peer_exist(soc, pdev_id, + peer_addr); - return NULL; + return false; } /** - * cdp_peer_find_by_addr_and_vdev() - Find peer by peer mac address within vdev + * cdp_find_peer_exist_on_vdev - Find if duplicate peer exists + * on the given vdev * @soc - data path soc handle - * @pdev - data path device instance - * @vdev - virtual interface instance + * @vdev_id - data path virtual interface id * @peer_addr - peer mac address - * @peer_id - local peer id with target mac address * - * Find peer by peer mac address within vdev - * - * Return: peer instance void pointer - * NULL cannot find target peer + * Return: true or false */ -static inline void -*cdp_peer_find_by_addr_and_vdev(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - struct cdp_vdev *vdev, uint8_t *peer_addr, uint8_t *peer_id) +static inline bool +cdp_find_peer_exist_on_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - return NULL; + return false; } - if (soc->ops->peer_ops->find_peer_by_addr_and_vdev) - return soc->ops->peer_ops->find_peer_by_addr_and_vdev( - pdev, vdev, peer_addr, peer_id); + if (soc->ops->peer_ops->find_peer_exist_on_vdev) + return soc->ops->peer_ops->find_peer_exist_on_vdev(soc, vdev_id, + peer_addr); - return NULL; + return false; } /** - * cdp_peer_find_by_local_id() - Find peer by local peer id + * cdp_find_peer_exist_on_other_vdev - Find if duplicate peer exists + * on other than the given vdev * @soc - data path soc handle - * @pdev - data path device instance - * @local_peer_id - local peer id want to find - * - * Find peer by local peer id within physical device + * @vdev_id - data path virtual interface id + * @peer_addr - peer mac address + * @max_bssid - max number of bssids * - * Return: peer instance void pointer - * NULL cannot find target peer + * Return: true or false */ -static inline void -*cdp_peer_find_by_local_id(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t local_peer_id) +static inline bool +cdp_find_peer_exist_on_other_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_addr, uint16_t max_bssid) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - return NULL; + return false; } - if (soc->ops->peer_ops->peer_find_by_local_id) - return soc->ops->peer_ops->peer_find_by_local_id( - pdev, local_peer_id); + if (soc->ops->peer_ops->find_peer_exist_on_other_vdev) + return soc->ops->peer_ops->find_peer_exist_on_other_vdev( + soc, vdev_id, + peer_addr, + max_bssid); - return NULL; + return false; } /** * cdp_peer_state_update() - update peer local state * @soc - data path soc handle - * @pdev - data path device instance * @peer_addr - peer mac address * @state - new peer local state * @@ -318,8 +200,8 @@ static inline void * QDF_STATUS_E_NOSUPPORT not support this feature */ static inline QDF_STATUS -cdp_peer_state_update(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t *peer_addr, enum ol_txrx_peer_state state) +cdp_peer_state_update(ol_txrx_soc_handle soc, uint8_t *peer_addr, + enum ol_txrx_peer_state state) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -328,8 +210,8 @@ cdp_peer_state_update(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->peer_ops->peer_state_update) - return soc->ops->peer_ops->peer_state_update( - pdev, peer_addr, state); + return soc->ops->peer_ops->peer_state_update(soc, peer_addr, + state); return QDF_STATUS_E_NOSUPPORT; } @@ -337,14 +219,15 @@ cdp_peer_state_update(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_peer_state_get() - Get local peer state * @soc - data path soc handle - * @peer - peer instance + * @vdev_id - virtual interface id + * @peer_mac - peer mac addr * * Get local peer state * * Return: peer status */ static inline int -cdp_peer_state_get(ol_txrx_soc_handle soc, void *peer) +cdp_peer_state_get(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -353,40 +236,16 @@ cdp_peer_state_get(ol_txrx_soc_handle soc, void *peer) } if (soc->ops->peer_ops->get_peer_state) - return soc->ops->peer_ops->get_peer_state(peer); + return soc->ops->peer_ops->get_peer_state(soc, vdev_id, + peer_mac); return 0; } -/** - * cdp_peer_get_local_peer_id() - Find local peer id within peer instance - * @soc - data path soc handle - * @peer - peer instance - * - * Find local peer id within peer instance - * - * Return: local peer id - * HTT_INVALID_PEER Invalid peer - */ -static inline uint16_t -cdp_peer_get_local_peer_id(ol_txrx_soc_handle soc, void *peer) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return HTT_INVALID_PEER; - } - - if (soc->ops->peer_ops->local_peer_id) - return soc->ops->peer_ops->local_peer_id(peer); - - return HTT_INVALID_PEER; -} - /** * cdp_peer_get_vdevid() - Get virtual interface id which peer registered * @soc - data path soc handle - * @peer - peer instance + * @peer_mac - peer mac address * @vdev_id - virtual interface id which peer registered * * Get virtual interface id which peer registered @@ -395,7 +254,8 @@ cdp_peer_get_local_peer_id(ol_txrx_soc_handle soc, void *peer) * QDF_STATUS_E_NOSUPPORT not support this feature */ static inline QDF_STATUS -cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id) +cdp_peer_get_vdevid(ol_txrx_soc_handle soc, + uint8_t *peer_mac, uint8_t *vdev_id) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -404,7 +264,7 @@ cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id) } if (soc->ops->peer_ops->get_vdevid) - return soc->ops->peer_ops->get_vdevid(peer, vdev_id); + return soc->ops->peer_ops->get_vdevid(soc, peer_mac, vdev_id); return QDF_STATUS_E_NOSUPPORT; } @@ -413,7 +273,7 @@ cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id) * cdp_peer_get_vdev_by_sta_id() - Get vdev instance by local peer id * @soc - data path soc handle * @pdev - data path device instance - * @sta_id - local peer id + * @peer_addr - peer mac address * * Get virtual interface id by local peer id * @@ -421,8 +281,8 @@ cdp_peer_get_vdevid(ol_txrx_soc_handle soc, void *peer, uint8_t *vdev_id) * NULL in case cannot find */ static inline struct cdp_vdev -*cdp_peer_get_vdev_by_sta_id(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t sta_id) +*cdp_peer_get_vdev_by_peer_addr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, + struct qdf_mac_addr peer_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -430,8 +290,9 @@ static inline struct cdp_vdev return NULL; } - if (soc->ops->peer_ops->get_vdev_by_sta_id) - return soc->ops->peer_ops->get_vdev_by_sta_id(pdev, sta_id); + if (soc->ops->peer_ops->get_vdev_by_peer_addr) + return soc->ops->peer_ops->get_vdev_by_peer_addr(pdev, + peer_addr); return NULL; } @@ -461,35 +322,10 @@ static inline uint8_t return NULL; } -/** - * cdp_peer_get_vdev() - Get virtual interface instance which peer belongs - * @soc - data path soc handle - * @peer - peer instance - * - * Get virtual interface instance which peer belongs - * - * Return: virtual interface instance pointer - * NULL in case cannot find - */ -static inline struct cdp_vdev -*cdp_peer_get_vdev(ol_txrx_soc_handle soc, void *peer) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return NULL; - } - - if (soc->ops->peer_ops->get_vdev_for_peer) - return soc->ops->peer_ops->get_vdev_for_peer(peer); - - return NULL; -} - /** * cdp_peer_update_ibss_add_peer_num_of_vdev() - update number of peer * @soc - data path soc handle - * @vdev - virtual interface instance + * @vdev_id - virtual interface instance id * @peer_num_delta - number of peer should be updated * * update number of peer @@ -499,7 +335,8 @@ static inline struct cdp_vdev */ static inline int16_t cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, int16_t peer_num_delta) + uint8_t vdev_id, + int16_t peer_num_delta) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -509,7 +346,8 @@ cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc, if (soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev) return soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev( - vdev, peer_num_delta); + soc, vdev_id, + peer_num_delta); return 0; } @@ -517,7 +355,7 @@ cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc, /** * cdp_peer_copy_mac_addr_raw() - copy peer mac address * @soc - data path soc handle - * @vdev - virtual interface instance + * @vdev_id - virtual interface instance id * @bss_addr - mac address should be copied * * copy peer mac address @@ -526,7 +364,7 @@ cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc, */ static inline void cdp_peer_copy_mac_addr_raw(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, uint8_t *bss_addr) + uint8_t vdev_id, uint8_t *bss_addr) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -535,7 +373,8 @@ cdp_peer_copy_mac_addr_raw(ol_txrx_soc_handle soc, } if (soc->ops->peer_ops->copy_mac_addr_raw) - return soc->ops->peer_ops->copy_mac_addr_raw(vdev, bss_addr); + return soc->ops->peer_ops->copy_mac_addr_raw(soc, vdev_id, + bss_addr); return; } @@ -543,17 +382,16 @@ cdp_peer_copy_mac_addr_raw(ol_txrx_soc_handle soc, /** * cdp_peer_add_last_real_peer() - Add peer with last peer marking * @soc - data path soc handle - * @pdev - data path device instance - * @vdev - virtual interface instance - * @peer_id - local peer id + * @pdev_id - data path device instance id + * @vdev_id - virtual interface instance id * * copy peer mac address * * Return: none */ static inline void -cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, struct cdp_vdev *vdev, uint8_t *peer_id) +cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint8_t vdev_id) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -562,15 +400,16 @@ cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, } if (soc->ops->peer_ops->add_last_real_peer) - return soc->ops->peer_ops->add_last_real_peer( - pdev, vdev, peer_id); + return soc->ops->peer_ops->add_last_real_peer(soc, pdev_id, + vdev_id); return; } /** * cdp_peer_is_vdev_restore_last_peer() - restore last peer * @soc - data path soc handle - * @peer - peer instance pointer + * @vdev_id - virtual interface id + * @peer_mac - peer mac address * * restore last peer * @@ -578,7 +417,8 @@ cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, * fasle, restore fail */ static inline bool -cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, void *peer) +cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -587,7 +427,9 @@ cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, void *peer) } if (soc->ops->peer_ops->is_vdev_restore_last_peer) - return soc->ops->peer_ops->is_vdev_restore_last_peer(peer); + return soc->ops->peer_ops->is_vdev_restore_last_peer(soc, + vdev_id, + peer_mac); return false; } @@ -595,9 +437,8 @@ cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, void *peer) /** * cdp_peer_update_last_real_peer() - update last real peer * @soc - data path soc handle - * @pdev - data path device instance - * @peer - peer instance pointer - * @peer_id - local peer id + * @pdev_id - data path device instance id + * @vdev_id - virtual interface id * @restore_last_peer - restore last peer or not * * update last real peer @@ -605,8 +446,8 @@ cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, void *peer) * Return: none */ static inline void -cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - void *vdev, uint8_t *peer_id, bool restore_last_peer) +cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint8_t vdev_id, bool restore_last_peer) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -615,8 +456,9 @@ cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->peer_ops->update_last_real_peer) - return soc->ops->peer_ops->update_last_real_peer(pdev, vdev, - peer_id, restore_last_peer); + return soc->ops->peer_ops->update_last_real_peer( + soc, pdev_id, vdev_id, + restore_last_peer); return; } @@ -633,7 +475,8 @@ cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, * Return: None */ static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc, - void *peer) + uint8_t vdev_id, + uint8_t *peer_mac) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -642,7 +485,9 @@ static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc, } if (soc->ops->peer_ops->peer_detach_force_delete) - return soc->ops->peer_ops->peer_detach_force_delete(peer); + return soc->ops->peer_ops->peer_detach_force_delete(soc, + vdev_id, + peer_mac); return; } @@ -674,18 +519,66 @@ is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc) return false; } +/* + * cdp_peer_set_peer_as_tdls() - To set peer as tdls peer + * @soc: pointer to SOC handle + * @vdev_id: virtual interface id + * @peer_mac: peer mac address + * @var: true or false + * + * Return: void + */ +static inline void +cdp_peer_set_peer_as_tdls(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val) +{ + if (!soc || !soc->ops || !soc->ops->peer_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return; + } + + if (soc->ops->peer_ops->set_peer_as_tdls_peer) + soc->ops->peer_ops->set_peer_as_tdls_peer(soc, vdev_id, + peer_mac, val); +} + +/** + * cdp_peer_set_tdls_offchan_enabled() - Set tdls offchan operation as enabled + * @soc: pointer to SOC handle + * @vdev_id: virtual interface id + * @peer_mac: peer mac address + * @val: true or false + * + * update tdls_offchan_enabled + * + * Return: none + */ +static inline void +cdp_peer_set_tdls_offchan_enabled(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val) +{ + if (!soc || !soc->ops || !soc->ops->peer_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return; + } + + if (soc->ops->peer_ops->set_tdls_offchan_enabled) + soc->ops->peer_ops->set_tdls_offchan_enabled(soc, vdev_id, + peer_mac, val); +} + /** * cdp_peer_flush_frags() - Flush frags on peer * @soc - data path soc handle - * @pdev - data path device instance * @vdev_id - virtual interface id * @peer_mac - peer mac addr * * Return: None */ static inline void -cdp_peer_flush_frags(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint8_t vdev_id, uint8_t *peer_mac) +cdp_peer_flush_frags(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -694,6 +587,6 @@ cdp_peer_flush_frags(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->peer_ops->peer_flush_frags) - soc->ops->peer_ops->peer_flush_frags(pdev, vdev_id, peer_mac); + soc->ops->peer_ops->peer_flush_frags(soc, vdev_id, peer_mac); } #endif /* _CDP_TXRX_PEER_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h index 1a7ea9038aa702cb7e3008f1b34dd21e623f2bb2..ecb2bddc91d8ae195a40f8a9f7ecb134e04f26df 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,7 +29,7 @@ #include "cdp_txrx_handle.h" static inline uint32_t cdp_pflow_update_pdev_params - (ol_txrx_soc_handle soc, struct cdp_pdev *pdev, + (ol_txrx_soc_handle soc, uint8_t pdev_id, enum _ol_ath_param_t param, uint32_t val, void *ctx) { if (!soc || !soc->ops) { @@ -44,6 +44,6 @@ static inline uint32_t cdp_pflow_update_pdev_params return 0; return soc->ops->pflow_ops->pflow_update_pdev_params - (pdev, param, val, ctx); + (soc, pdev_id, param, val, ctx); } #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h index 48f644bbd0fc640e41a96385a3d1897cd1a6b2e9..c869eac2b70cc445d703cc5eb03aa2242e6257cc 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,7 +22,8 @@ /** * cdp_get_pn_info() - Returns pn info from peer * @soc - data path soc handle - * @peer: handle to peer + * @peer_mac: peer mac address + * @vdev_id: virtual device/interface id * @last_pn_valid: return last_rmf_pn_valid value from peer. * @last_pn: return last_rmf_pn value from peer. * @rmf_pn_replays: return rmf_pn_replays value from peer. @@ -30,8 +31,9 @@ * Return: NONE */ static inline void -cdp_get_pn_info(ol_txrx_soc_handle soc, void *peer, uint8_t **last_pn_valid, - uint64_t **last_pn, uint32_t **rmf_pn_replays) +cdp_get_pn_info(ol_txrx_soc_handle soc, uint8_t *peer_mac, uint8_t vdev_id, + uint8_t **last_pn_valid, uint64_t **last_pn, + uint32_t **rmf_pn_replays) { if (!soc || !soc->ops || !soc->ops->pmf_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -40,8 +42,9 @@ cdp_get_pn_info(ol_txrx_soc_handle soc, void *peer, uint8_t **last_pn_valid, } if (soc->ops->pmf_ops->get_pn_info) - return soc->ops->pmf_ops->get_pn_info( - peer, last_pn_valid, last_pn, rmf_pn_replays); + return soc->ops->pmf_ops->get_pn_info(soc, peer_mac, vdev_id, + last_pn_valid, + last_pn, rmf_pn_replays); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h index a15e37a3713ea144cf87a2ab8593aa82a546ea9c..0eb40e6a0efc3640f44519299271a9a9b557e3c6 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,7 +28,7 @@ #include "cdp_txrx_ops.h" /* TODO: adf need to be replaced with qdf */ static inline int cdp_get_nwifi_mode(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev) + uint8_t vdev_id) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -41,7 +41,7 @@ static inline int cdp_get_nwifi_mode(ol_txrx_soc_handle soc, !soc->ops->raw_ops->txrx_get_nwifi_mode) return 0; - return soc->ops->raw_ops->txrx_get_nwifi_mode(vdev); + return soc->ops->raw_ops->txrx_get_nwifi_mode(soc, vdev_id); } /** @@ -49,15 +49,16 @@ static inline int cdp_get_nwifi_mode(ol_txrx_soc_handle soc, * @details: Finds the ast entry i.e 4th address for the packet based on the * details in the netbuf. * - * @param vdev - the data virtual device object + * @param soc - soc handle + * @param vdev_id - id of the data virtual device object * @param pnbuf - pointer to nbuf * @param raw_ast - pointer to fill ast information * * @return - 0 on success, -1 on error, 1 if more nbufs need to be consumed. */ -static inline void -cdp_rawsim_get_astentry (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, +static inline QDF_STATUS +cdp_rawsim_get_astentry(ol_txrx_soc_handle soc, uint8_t vdev_id, qdf_nbuf_t *pnbuf, struct cdp_raw_ast *raw_ast) { @@ -65,14 +66,15 @@ cdp_rawsim_get_astentry (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_FAILURE; } if (!soc->ops->raw_ops || !soc->ops->raw_ops->rsim_get_astentry) - return; + return QDF_STATUS_E_FAILURE; - soc->ops->raw_ops->rsim_get_astentry(vdev, pnbuf, raw_ast); + return soc->ops->raw_ops->rsim_get_astentry(soc, vdev_id, + pnbuf, raw_ast); } #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h index 69814a071e22dd0a16d25dca813065b2132388d8..c912591248ba4b336523918ea5fe74599e6bfd31 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017,2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,22 +25,22 @@ #define _CDP_TXRX_STATS_H_ #include -static inline void -cdp_clear_stats(ol_txrx_soc_handle soc, uint16_t bitmap) +static inline QDF_STATUS +cdp_clear_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t bitmap) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, "%s: Invalid Instance", __func__); QDF_BUG(0); - return; + return QDF_STATUS_E_INVAL; } if (!soc->ops->mob_stats_ops || !soc->ops->mob_stats_ops->clear_stats) - return; + return QDF_STATUS_E_INVAL; - soc->ops->mob_stats_ops->clear_stats(bitmap); + return soc->ops->mob_stats_ops->clear_stats(soc, pdev_id, bitmap); } static inline int diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h index 2036ad14bbfeccd53c1f5a7bd3f238d9b1553411..1612a3513687cc7369a3c25e903306e54315fc0a 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,9 +23,9 @@ */ #ifndef _CDP_TXRX_STATS_STRUCT_H_ #define _CDP_TXRX_STATS_STRUCT_H_ -#ifdef CONFIG_MCL -#include -#endif + +#include + #define TXRX_STATS_LEVEL_OFF 0 #define TXRX_STATS_LEVEL_BASIC 1 #define TXRX_STATS_LEVEL_FULL 2 @@ -73,6 +73,8 @@ #define CDP_MAX_RX_RINGS 4 /* max rx rings */ #define CDP_MAX_TX_COMP_RINGS 3 /* max tx completion rings */ +#define CDP_MAX_TX_TQM_STATUS 9 /* max tx tqm completion status */ +#define CDP_MAX_TX_HTT_STATUS 7 /* max tx htt completion status */ /* TID level VoW stats macros * to add and get stats @@ -114,7 +116,84 @@ #define INVALID_RSSI 255 +#define CDP_RSSI_MULTIPLIER BIT(8) +#define CDP_RSSI_MUL(x, mul) ((x) * (mul)) +#define CDP_RSSI_RND(x, mul) ((((x) % (mul)) >= ((mul) / 2)) ?\ + ((x) + ((mul) - 1)) / (mul) : (x) / (mul)) + +#define CDP_RSSI_OUT(x) (CDP_RSSI_RND((x), CDP_RSSI_MULTIPLIER)) +#define CDP_RSSI_IN(x) (CDP_RSSI_MUL((x), CDP_RSSI_MULTIPLIER)) +#define CDP_RSSI_AVG(x, y) ((((x) << 2) + (y) - (x)) >> 2) + +#define CDP_RSSI_UPDATE_AVG(x, y) x = CDP_RSSI_AVG((x), CDP_RSSI_IN((y))) + +/*Max SU EVM count */ +#define DP_RX_MAX_SU_EVM_COUNT 32 + #define WDI_EVENT_BASE 0x100 + +#define CDP_TXRX_RATECODE_MCS_MASK 0xF +#define CDP_TXRX_RATECODE_NSS_MASK 0x3 +#define CDP_TXRX_RATECODE_NSS_LSB 4 +#define CDP_TXRX_RATECODE_PREM_MASK 0x3 +#define CDP_TXRX_RATECODE_PREM_LSB 6 + +/* Below BW_GAIN should be added to the SNR value of every ppdu based on the + * bandwidth. This table is obtained from HALPHY. + * BW BW_Gain + * 20 0 + * 40 3dBm + * 80 6dBm + * 160/80P80 9dBm + */ + +#define PKT_BW_GAIN_20MHZ 0 +#define PKT_BW_GAIN_40MHZ 3 +#define PKT_BW_GAIN_80MHZ 6 +#define PKT_BW_GAIN_160MHZ 9 + +/* + * cdp_tx_transmit_type: Transmit type index + * SU: SU Transmit type index + * MU_MIMO: MU_MIMO Transmit type index + * MU_OFDMA: MU_OFDMA Transmit type index + * MU_MIMO_OFDMA: MU MIMO OFDMA Transmit type index + */ +enum cdp_tx_transmit_type { + SU = 0, + MU_MIMO, + MU_OFDMA, + MU_MIMO_OFDMA, +}; + +/* + * cdp_ru_index: Different RU index + * + * RU_26_INDEX : 26-tone Resource Unit index + * RU_52_INDEX : 52-tone Resource Unit index + * RU_106_INDEX: 106-tone Resource Unit index + * RU_242_INDEX: 242-tone Resource Unit index + * RU_484_INDEX: 484-tone Resource Unit index + * RU_996_INDEX: 996-tone Resource Unit index + */ +enum cdp_ru_index { + RU_26_INDEX = 0, + RU_52_INDEX, + RU_106_INDEX, + RU_242_INDEX, + RU_484_INDEX, + RU_996_INDEX, +}; + +#ifdef FEATURE_TSO_STATS +/* Number of TSO Packet Statistics captured */ +#define CDP_MAX_TSO_PACKETS 5 +/* Information for Number of Segments for a TSO Packet captured */ +#define CDP_MAX_TSO_SEGMENTS 2 +/* Information for Number of Fragments for a TSO Segment captured */ +#define CDP_MAX_TSO_FRAGMENTS 6 +#endif /* FEATURE_TSO_STATS */ + /* Different Packet Types */ enum cdp_packet_type { DOT11_A = 0, @@ -125,6 +204,18 @@ enum cdp_packet_type { DOT11_MAX = 5, }; +/* + * cdp_mu_packet_type: MU Rx type index + * RX_TYPE_MU_MIMO: MU MIMO Rx type index + * RX_TYPE_MU_OFDMA: MU OFDMA Rx type index + * MU_MIMO_OFDMA: MU Rx MAX type index + */ +enum cdp_mu_packet_type { + RX_TYPE_MU_MIMO = 0, + RX_TYPE_MU_OFDMA = 1, + RX_TYPE_MU_MAX = 2, +}; + enum WDI_EVENT { WDI_EVENT_TX_STATUS = WDI_EVENT_BASE, WDI_EVENT_OFFLOAD_ALL, @@ -205,6 +296,78 @@ struct cdp_tidq_stats { uint32_t stats[TIDQ_STATS_MAX]; }; +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * struct cdp_rx_ppdu_cfr_info - struct for storing ppdu info extracted from HW + * TLVs, this will be used for CFR correlation + * + * @bb_captured_channel : Set by RXPCU when MACRX_FREEZE_CAPTURE_CHANNEL TLV is + * sent to PHY, SW checks it to correlate current PPDU TLVs with uploaded + * channel information. + * + * @bb_captured_timeout : Set by RxPCU to indicate channel capture condition is + * met, but MACRX_FREEZE_CAPTURE_CHANNEL is not sent to PHY due to AST delay, + * which means the rx_frame_falling edge to FREEZE TLV ready time exceeds + * the threshold time defined by RXPCU register FREEZE_TLV_DELAY_CNT_THRESH. + * Bb_captured_reason is still valid in this case. + * + * @bb_captured_reason : Copy capture_reason of MACRX_FREEZE_CAPTURE_CHANNEL + * TLV to here for FW usage. Valid when bb_captured_channel or + * bb_captured_timeout is set. + * + * + * + * + * + * + * + * + * @rx_location_info_valid: Indicates whether CFR DMA address in the PPDU TLV + * is valid + * + * + * + * + * @chan_capture_status : capture status reported by ucode + * a. CAPTURE_IDLE: FW has disabled "REPETITIVE_CHE_CAPTURE_CTRL" + * b. CAPTURE_BUSY: previous PPDU’s channel capture upload DMA ongoing. (Note + * that this upload is triggered after receiving freeze_channel_capture TLV + * after last PPDU is rx) + * c. CAPTURE_ACTIVE: channel capture is enabled and no previous channel + * capture ongoing + * d. CAPTURE_NO_BUFFER: next buffer in IPC ring not available + * + * @rtt_che_buffer_pointer_high8 : The high 8 bits of the 40 bits pointer to + * external RTT channel information buffer + * + * @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to + * external RTT channel information buffer + * + */ + +struct cdp_rx_ppdu_cfr_info { + bool bb_captured_channel; + bool bb_captured_timeout; + uint8_t bb_captured_reason; + bool rx_location_info_valid; + uint8_t chan_capture_status; + uint8_t rtt_che_buffer_pointer_high8; + uint32_t rtt_che_buffer_pointer_low32; +}; +#endif +/* + * struct cdp_rx_su_evm_info: Rx evm info + * @number_of_symbols: number of symbols + * @nss_count: number of spatial streams + * @pilot_count: number of pilot count + */ +struct cdp_rx_su_evm_info { + uint16_t number_of_symbols; + uint8_t nss_count; + uint8_t pilot_count; + uint32_t pilot_evm[DP_RX_MAX_SU_EVM_COUNT]; +}; + /* * cdp_delay_stats_mode: Different types of delay statistics * @@ -294,6 +457,8 @@ struct cdp_delay_stats { * @success_cnt: total successful transmit count * @comp_fail_cnt: firmware drop found in tx completion path * @swdrop_cnt: software drop in tx path + * @tqm_status_cnt: TQM completion status count + * @htt_status_cnt: HTT completion status count */ struct cdp_tid_tx_stats { struct cdp_delay_stats swq_delay; @@ -302,6 +467,8 @@ struct cdp_tid_tx_stats { uint64_t success_cnt; uint64_t comp_fail_cnt; uint64_t swdrop_cnt[TX_MAX_DROP]; + uint64_t tqm_status_cnt[CDP_MAX_TX_TQM_STATUS]; + uint64_t htt_status_cnt[CDP_MAX_TX_HTT_STATUS]; }; /* @@ -358,14 +525,183 @@ struct cdp_pkt_type { uint32_t mcs_count[MAX_MCS]; }; +/* + * struct cdp_rx_mu - Rx MU Stats + * @ppdu_nss[SS_COUNT]: Packet Count in spatial streams + * @mpdu_cnt_fcs_ok: Rx success mpdu count + * @mpdu_cnt_fcs_err: Rx fail mpdu count + * @cdp_pkt_type: counter array for each MCS index + */ +struct cdp_rx_mu { + uint32_t ppdu_nss[SS_COUNT]; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + struct cdp_pkt_type ppdu; +}; + +/* struct cdp_tx_pkt_info - tx packet info + * num_msdu - successful msdu + * num_mpdu - successful mpdu from compltn common + * mpdu_tried - mpdu tried + * + * tx packet info counter field for mpdu success/tried and msdu + */ +struct cdp_tx_pkt_info { + uint32_t num_msdu; + uint32_t num_mpdu; + uint32_t mpdu_tried; +}; + +#ifdef FEATURE_TSO_STATS +/** + * struct cdp_tso_seg_histogram - Segment histogram for TCP Packets + * @segs_1: packets with single segments + * @segs_2_5: packets with 2-5 segments + * @segs_6_10: packets with 6-10 segments + * @segs_11_15: packets with 11-15 segments + * @segs_16_20: packets with 16-20 segments + * @segs_20_plus: packets with 20 plus segments + */ +struct cdp_tso_seg_histogram { + uint64_t segs_1; + uint64_t segs_2_5; + uint64_t segs_6_10; + uint64_t segs_11_15; + uint64_t segs_16_20; + uint64_t segs_20_plus; +}; + +/** + * struct cdp_tso_packet_info - Stats for TSO segments within a TSO packet + * @tso_seg: TSO Segment information + * @num_seg: Number of segments + * @tso_packet_len: Size of the tso packet + * @tso_seg_idx: segment number + */ +struct cdp_tso_packet_info { + struct qdf_tso_seg_t tso_seg[CDP_MAX_TSO_SEGMENTS]; + uint8_t num_seg; + size_t tso_packet_len; + uint32_t tso_seg_idx; +}; + +/** + * struct cdp_tso_info - stats for tso packets + * @tso_packet_info: TSO packet information + */ +struct cdp_tso_info { + struct cdp_tso_packet_info tso_packet_info[CDP_MAX_TSO_PACKETS]; +}; +#endif /* FEATURE_TSO_STATS */ + +/** + * struct cdp_tso_stats - TSO stats information + * @num_tso_pkts: Total number of TSO Packets + * @tso_comp: Total tso packet completions + * @dropped_host: TSO packets dropped by host + * @tso_no_mem_dropped: TSO packets dropped by host due to descriptor + unavailablity + * @dropped_target: TSO packets_dropped by target + * @tso_info: Per TSO packet counters + * @seg_histogram: TSO histogram stats + */ +struct cdp_tso_stats { + struct cdp_pkt_info num_tso_pkts; + uint32_t tso_comp; + struct cdp_pkt_info dropped_host; + struct cdp_pkt_info tso_no_mem_dropped; + uint32_t dropped_target; +#ifdef FEATURE_TSO_STATS + struct cdp_tso_info tso_info; + struct cdp_tso_seg_histogram seg_histogram; +#endif /* FEATURE_TSO_STATS */ +}; + +#define CDP_PEER_STATS_START 0 + +enum cdp_peer_stats_type { + cdp_peer_stats_min = CDP_PEER_STATS_START, + + /* Tx types */ + cdp_peer_tx_ucast = cdp_peer_stats_min, + cdp_peer_tx_mcast, + cdp_peer_tx_rate, + cdp_peer_tx_last_tx_rate, + cdp_peer_tx_inactive_time, + cdp_peer_tx_ratecode, + cdp_peer_tx_flags, + cdp_peer_tx_power, + + /* Rx types */ + cdp_peer_rx_rate, + cdp_peer_rx_last_rx_rate, + cdp_peer_rx_ratecode, + cdp_peer_rx_ucast, + cdp_peer_rx_flags, + cdp_peer_rx_avg_rssi, + cdp_peer_stats_max, +}; + +/* + * The max size of cdp_peer_stats_param_t is limited to 16 bytes. + * If the buffer size is exceeding this size limit, + * dp_txrx_get_peer_stats is to be used instead. + */ +typedef union cdp_peer_stats_buf { + /* Tx types */ + struct cdp_pkt_info tx_ucast; + struct cdp_pkt_info tx_mcast; + uint32_t tx_rate; + uint32_t last_tx_rate; + uint32_t tx_inactive_time; + uint32_t tx_flags; + uint32_t tx_power; + uint16_t tx_ratecode; + + /* Rx types */ + struct cdp_pkt_info rx_ucast; + uint32_t rx_rate; + uint32_t last_rx_rate; + uint32_t rx_ratecode; + uint32_t rx_flags; + uint32_t rx_avg_rssi; +} cdp_peer_stats_param_t; /* Max union size 16 bytes */ + +/** + * enum cdp_protocol_trace - Protocols supported by per-peer protocol trace + * @CDP_TRACE_ICMP: ICMP packets + * @CDP_TRACE_EAP: EAPOL packets + * @CDP_TRACE_ARP: ARP packets + * + * Enumeration of all protocols supported by per-peer protocol trace feature + */ +enum cdp_protocol_trace { + CDP_TRACE_ICMP, + CDP_TRACE_EAP, + CDP_TRACE_ARP, + CDP_TRACE_MAX +}; + +/** + * struct protocol_trace_count - type of count on per-peer protocol trace + * @egress_cnt: how many packets go out of host driver + * @ingress_cnt: how many packets come into the host driver + * + * Type of count on per-peer protocol trace + */ +struct protocol_trace_count { + uint16_t egress_cnt; + uint16_t ingress_cnt; +}; /* struct cdp_tx_stats - tx stats * @cdp_pkt_info comp_pkt: Pkt Info for which completions were received * @cdp_pkt_info ucast: Unicast Packet Count * @cdp_pkt_info mcast: Multicast Packet Count * @cdp_pkt_info bcast: Broadcast Packet Count * @cdp_pkt_info nawds_mcast: NAWDS Multicast Packet Count - * @nawds_mcast_drop: NAWDS Multicast Drop Count * @cdp_pkt_info tx_success: Successful Tx Packets + * @nawds_mcast_drop: NAWDS Multicast Drop Count + * @protocol_trace_cnt: per-peer protocol counter * @tx_failed: Total Tx failure * @ofdma: Total Packets as ofdma * @stbc: Packets in STBC @@ -391,6 +727,7 @@ struct cdp_pkt_type { * @bw[MAX_BW]: Packet Count for different bandwidths * @wme_ac_type[WME_AC_MAX]: Wireless Multimedia type Count * @excess_retries_per_ac[WME_AC_MAX]: Wireless Multimedia type Count + * @dot11_tx_pkts: dot11 tx packets * @fw_rem: Discarded by firmware * @fw_rem_notx: firmware_discard_untransmitted * @fw_rem_tx: firmware_discard_transmitted @@ -399,7 +736,6 @@ struct cdp_pkt_type { * @fw_reason2: discarded by firmware reason 2 * @fw_reason3: discarded by firmware reason 3 * @mcs_count: MCS Count - * @dot11_tx_pkts: dot11 tx packets * @an_tx_cnt: ald tx count * @an_tx_rates_used: ald rx rate used * @an_tx_bytes: ald tx bytes @@ -412,10 +748,10 @@ struct cdp_pkt_type { * @ald_ac_excretries: #pkts dropped after excessive retries per node per AC * @rssi_chain: rssi chain * @inactive_time: inactive time in secs - * @tx_ratecode: Tx rate code of last frame * @tx_flags: tx flags * @tx_power: Tx power latest * @is_tx_no_ack: no ack received + * @tx_ratecode: Tx rate code of last frame * @is_tx_nodefkey: tx failed 'cuz no defkey * @is_tx_noheadroom: tx failed 'cuz no space * @is_crypto_enmicfail: @@ -427,11 +763,11 @@ struct cdp_pkt_type { * @failed_retry_count: packets failed due to retry above 802.11 retry limit * @retry_count: packets successfully send after one or more retry * @multiple_retry_count: packets successfully sent after more than one retry - * @transmit_type: tx transmit type + * @transmit_type: pkt info for tx transmit type * @mu_group_id: mumimo mu group id * @ru_start: RU start index * @ru_tones: RU tones size - * @ru_loc: RU location 26/ 52/ 106/ 242/ 484 counter + * @ru_loc: pkt info for RU location 26/ 52/ 106/ 242/ 484 counter * @num_ppdu_cookie_valid : Number of comp received with valid ppdu cookie */ struct cdp_tx_stats { @@ -440,8 +776,11 @@ struct cdp_tx_stats { struct cdp_pkt_info mcast; struct cdp_pkt_info bcast; struct cdp_pkt_info nawds_mcast; - uint32_t nawds_mcast_drop; +#ifdef VDEV_PEER_PROTOCOL_COUNT + struct protocol_trace_count protocol_trace_cnt[CDP_TRACE_MAX]; +#endif struct cdp_pkt_info tx_success; + uint32_t nawds_mcast_drop; uint32_t tx_failed; uint32_t ofdma; uint32_t stbc; @@ -474,6 +813,7 @@ struct cdp_tx_stats { uint32_t wme_ac_type[WME_AC_MAX]; uint32_t excess_retries_per_ac[WME_AC_MAX]; + struct cdp_pkt_info dot11_tx_pkts; struct { struct cdp_pkt_info fw_rem; @@ -485,10 +825,8 @@ struct cdp_tx_stats { uint32_t fw_reason3; } dropped; - struct cdp_pkt_info dot11_tx_pkts; uint32_t fw_tx_cnt; - uint32_t fw_tx_rates_used; uint32_t fw_tx_bytes; uint32_t fw_txcount; uint32_t fw_max4msframelen; @@ -498,12 +836,12 @@ struct cdp_tx_stats { uint32_t rssi_chain[WME_AC_MAX]; uint32_t inactive_time; - uint32_t tx_ratecode; uint32_t tx_flags; uint32_t tx_power; /* MSDUs which the target sent but couldn't get an ack for */ struct cdp_pkt_info is_tx_no_ack; + uint16_t tx_ratecode; /*add for peer and upadted from ppdu*/ uint32_t ampdu_cnt; @@ -513,11 +851,12 @@ struct cdp_tx_stats { uint32_t multiple_retry_count; uint32_t last_tx_rate_used; - uint32_t transmit_type[MAX_TRANSMIT_TYPES]; + struct cdp_tx_pkt_info transmit_type[MAX_TRANSMIT_TYPES]; uint32_t mu_group_id[MAX_MU_GROUP_ID]; uint32_t ru_start; uint32_t ru_tones; - uint32_t ru_loc[MAX_RU_LOCATIONS]; + struct cdp_tx_pkt_info ru_loc[MAX_RU_LOCATIONS]; + uint32_t num_ppdu_cookie_valid; uint32_t no_ack_count[QDF_PROTO_SUBTYPE_MAX]; }; @@ -534,6 +873,7 @@ struct cdp_tx_stats { * @pkts: Intra BSS packets received * @fail: Intra BSS packets failed * @mdns_no_fwd: Intra BSS MDNS packets not forwarded + * @protocol_trace_cnt: per-peer protocol counters * @mic_err: Rx MIC errors CCMP * @decrypt_err: Rx Decryption Errors CRC * @fcserr: rx MIC check failed (CCMP) @@ -541,15 +881,19 @@ struct cdp_tx_stats { * @reception_type[MAX_RECEPTION_TYPES]: Reception type os packets * @mcs_count[MAX_MCS]: mcs count * @sgi_count[MAX_GI]: sgi count - * @nss[SS_COUNT]: Packet count in spatiel Streams + * @nss[SS_COUNT]: packet count in spatiel Streams + * @ppdu_nss[SS_COUNT]: PPDU packet count in spatial streams + * @mpdu_cnt_fcs_ok: SU Rx success mpdu count + * @mpdu_cnt_fcs_err: SU Rx fail mpdu count + * @su_ax_ppdu_cnt: SU Rx packet count + * @ppdu_cnt[MAX_RECEPTION_TYPES]: PPDU packet count in reception type + * @rx_mu[RX_TYPE_MU_MAX]: Rx MU stats * @bw[MAX_BW]: Packet Count in different bandwidths * @non_ampdu_cnt: Number of MSDUs with no MPDU level aggregation * @ampdu_cnt: Number of MSDUs part of AMSPU * @non_amsdu_cnt: Number of MSDUs with no MSDU level aggregation * @amsdu_cnt: Number of MSDUs part of AMSDU * @bar_recv_cnt: Number of bar received - * @rssi: RSSI of received signal - * @last_rssi: Previous rssi * @avg_rssi: Average rssi * @rx_rate: Rx rate * @last_rx_rate: Previous rx rate @@ -575,6 +919,9 @@ struct cdp_tx_stats { * @rx_ratecode: Rx rate code of last frame * @rx_flags: rx flags * @rx_rssi_measured_time: Time at which rssi is measured + * @rssi: RSSI of received signal + * @last_rssi: Previous rssi + * @multipass_rx_pkt_drop: Dropped multipass rx pkt * @rx_mpdu_cnt: rx mpdu count per MCS rate */ struct cdp_rx_stats { @@ -591,6 +938,9 @@ struct cdp_rx_stats { struct cdp_pkt_info fail; uint32_t mdns_no_fwd; } intra_bss; +#ifdef VDEV_PEER_PROTOCOL_COUNT + struct protocol_trace_count protocol_trace_cnt[CDP_TRACE_MAX]; +#endif struct { uint32_t mic_err; @@ -603,14 +953,18 @@ struct cdp_rx_stats { struct cdp_pkt_type pkt_type[DOT11_MAX]; uint32_t sgi_count[MAX_GI]; uint32_t nss[SS_COUNT]; + uint32_t ppdu_nss[SS_COUNT]; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + struct cdp_pkt_type su_ax_ppdu_cnt; + uint32_t ppdu_cnt[MAX_RECEPTION_TYPES]; + struct cdp_rx_mu rx_mu[RX_TYPE_MU_MAX]; uint32_t bw[MAX_BW]; uint32_t non_ampdu_cnt; uint32_t ampdu_cnt; uint32_t non_amsdu_cnt; uint32_t amsdu_cnt; uint32_t bar_recv_cnt; - uint32_t rssi; - uint32_t last_rssi; uint32_t avg_rssi; uint32_t rx_rate; uint32_t last_rx_rate; @@ -633,6 +987,9 @@ struct cdp_rx_stats { uint32_t rx_ratecode; uint32_t rx_flags; uint32_t rx_rssi_measured_time; + uint8_t rssi; + uint8_t last_rssi; + uint32_t multipass_rx_pkt_drop; uint32_t rx_mpdu_cnt[MAX_MCS]; }; @@ -648,8 +1005,6 @@ struct cdp_rx_stats { * @tso_pkt:total no of TSO packets * @non_tso_pkts: non - TSO packets * @dropped_host: TSO packets dropped by host - * @tso_no_mem_dropped: TSO packets dropped by host due to descriptor - unavailability * @dropped_target:TSO packets dropped by target * @sg_pkt: Total scatter gather packets * @non_sg_pkts: non SG packets @@ -689,16 +1044,6 @@ struct cdp_tx_ingress_stats { uint32_t invalid_raw_pkt_datatype; } raw; - /* TSO packets info */ - struct { - uint32_t num_seg; - struct cdp_pkt_info tso_pkt; - struct cdp_pkt_info non_tso_pkts; - struct cdp_pkt_info dropped_host; - struct cdp_pkt_info tso_no_mem_dropped; - uint32_t dropped_target; - } tso; - /* Scatter Gather packet info */ struct { struct cdp_pkt_info sg_pkt; @@ -740,17 +1085,20 @@ struct cdp_tx_ingress_stats { uint32_t cce_classified; uint32_t cce_classified_raw; struct cdp_pkt_info sniffer_rcvd; + struct cdp_tso_stats tso_stats; }; /* struct cdp_vdev_stats - vdev stats structure * @tx_i: ingress tx stats * @tx: cdp tx stats * @rx: cdp rx stats + * @tso_stats: tso stats */ struct cdp_vdev_stats { struct cdp_tx_ingress_stats tx_i; struct cdp_tx_stats tx; struct cdp_rx_stats rx; + struct cdp_tso_stats tso_stats; }; /* struct cdp_peer_stats - peer stats structure @@ -765,7 +1113,8 @@ struct cdp_peer_stats { }; /* struct cdp_interface_peer_stats - interface structure for txrx peer stats - * @peer_hdl: control path peer handle + * @peer_mac: peer mac address + * @vdev_id : vdev_id for the peer * @last_peer_tx_rate: peer tx rate for last transmission * @peer_tx_rate: tx rate for current transmission * @peer_rssi: current rssi value of peer @@ -778,17 +1127,18 @@ struct cdp_peer_stats { * @rssi_changed: denotes rssi is changed */ struct cdp_interface_peer_stats { - void *peer_hdl; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t vdev_id; + uint8_t rssi_changed; uint32_t last_peer_tx_rate; uint32_t peer_tx_rate; - uint32_t peer_rssi; + uint32_t peer_rssi; uint32_t tx_packet_count; uint32_t rx_packet_count; uint32_t tx_byte_count; uint32_t rx_byte_count; uint32_t per; uint32_t ack_rssi; - uint8_t rssi_changed; }; /* Tx completions per interrupt */ @@ -1203,12 +1553,92 @@ struct cdp_htt_rx_pdev_stats { #define RX_PROTOCOL_TAG_ALL 0xff #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#define OFDMA_NUM_RU_SIZE 7 + +#define OFDMA_NUM_USERS 37 + +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/* + * mac_freeze_capture_reason - capture reason counters + * @FREEZE_REASON_TM: When m_directed_ftm is enabled, this CFR data is + * captured for a Timing Measurement (TM) frame. + * @FREEZE_REASON_FTM: When m_directed_ftm is enabled, this CFR data is + * captured for a Fine Timing Measurement (FTM) frame. + * @FREEZE_REASON_ACK_RESP_TO_TM_FTM: When m_all_ftm_ack is enabled, this CFR + * data is captured for an ACK received for the FTM/TM frame sent to a station. + * @FREEZE_REASON_TA_RA_TYPE_FILTER: When m_ta_ra_filter is enabled, this CFR + * data is captured for a PPDU received,since the CFR TA_RA filter is met. + * @FREEZE_REASON_NDPA_NDP: When m_ndpa_ndp_directed(or)m_ndpa_ndp_all is + * enabled, this CFR data is captured for an NDP frame received. + * @FREEZE_REASON_ALL_PACKET: When m_all_packet is enabled, this CFR data is + * captured for an incoming PPDU. + */ +enum mac_freeze_capture_reason { + FREEZE_REASON_TM = 0, + FREEZE_REASON_FTM, + FREEZE_REASON_ACK_RESP_TO_TM_FTM, + FREEZE_REASON_TA_RA_TYPE_FILTER, + FREEZE_REASON_NDPA_NDP, + FREEZE_REASON_ALL_PACKET, + FREEZE_REASON_MAX, +}; + +/* + * chan_capture_status: capture status counters + * @CAPTURE_IDLE: CFR data is not captured, since VCSR setting for CFR/RCC is + * not enabled. + * @CAPTURE_BUSY: CFR data is not available, since previous channel + * upload is in progress + * @CAPTURE_ACTIVE: CFR data is captured in HW registers + * @CAPTURE_NO_BUFFER: CFR data is not captured, since no buffer is available + * in IPC ring to DMA CFR data + */ +enum chan_capture_status { + CAPTURE_IDLE = 0, + CAPTURE_BUSY, + CAPTURE_ACTIVE, + CAPTURE_NO_BUFFER, + CAPTURE_MAX, +}; + +/* struct cdp_cfr_rcc_stats - CFR RCC debug statistics + * @bb_captured_channel_cnt: No. of PPDUs for which MAC sent Freeze TLV to PHY + * @bb_captured_timeout_cnt: No. of PPDUs for which CFR filter criteria matched + * but MAC did not send Freeze TLV to PHY as time exceeded freeze tlv delay + * count threshold + * @rx_loc_info_valid_cnt: No. of PPDUs for which PHY could find a valid buffer + * in ucode IPC ring + * @chan_capture_status[]: capture status counters + * [0] - No. of PPDUs with capture status CAPTURE_IDLE + * [1] - No. of PPDUs with capture status CAPTURE_BUSY + * [2] - No. of PPDUs with capture status CAPTURE_ACTIVE + * [3] - No. of PPDUs with capture status CAPTURE_NO_BUFFER + * @reason_cnt[]: capture reason counters + * [0] - No. PPDUs filtered due to freeze_reason_TM + * [1] - No. PPDUs filtered due to freeze_reason_FTM + * [2] - No. PPDUs filtered due to freeze_reason_ACK_resp_to_TM_FTM + * [3] - No. PPDUs filtered due to freeze_reason_TA_RA_TYPE_FILTER + * [4] - No. PPDUs filtered due to freeze_reason_NDPA_NDP + * [5] - No. PPDUs filtered due to freeze_reason_ALL_PACKET + */ +struct cdp_cfr_rcc_stats { + uint64_t bb_captured_channel_cnt; + uint64_t bb_captured_timeout_cnt; + uint64_t rx_loc_info_valid_cnt; + uint64_t chan_capture_status[CAPTURE_MAX]; + uint64_t reason_cnt[FREEZE_REASON_MAX]; +}; +#else +struct cdp_cfr_rcc_stats { +}; +#endif /* struct cdp_pdev_stats - pdev stats * @msdu_not_done: packets dropped because msdu done bit not set * @mec:Multicast Echo check * @mesh_filter: Mesh Filtered packets * @mon_rx_drop: packets dropped on monitor vap * @wifi_parse: rxdma errors due to wifi parse error + * @mon_radiotap_update_err: not enough space to update radiotap * @pkts: total packets replenished * @rxdma_err: rxdma errors for replenished * @nbuf_alloc_fail: nbuf alloc failed @@ -1230,16 +1660,23 @@ struct cdp_htt_rx_pdev_stats { * @tx_comp_histogram: Number of Tx completions per interrupt * @rx_ind_histogram: Number of Rx ring descriptors reaped per interrupt * @ppdu_stats_counter: ppdu stats counter + * @cdp_delayed_ba_not_recev: counter for delayed ba not received * @htt_tx_pdev_stats: htt pdev stats for tx * @htt_rx_pdev_stats: htt pdev stats for rx + * @data_rx_ru_size: UL ofdma data ru size counter array + * @nondata_rx_ru_size: UL ofdma non data ru size counter array + * @data_rx_ppdu: data rx ppdu counter + * @data_user: data user counter array */ struct cdp_pdev_stats { struct { uint32_t msdu_not_done; uint32_t mec; uint32_t mesh_filter; - uint32_t mon_rx_drop; uint32_t wifi_parse; + /* Monitor mode related */ + uint32_t mon_rx_drop; + uint32_t mon_radiotap_update_err; } dropped; struct { @@ -1262,6 +1699,8 @@ struct cdp_pdev_stats { uint32_t desc_alloc_fail; uint32_t ip_csum_err; uint32_t tcp_udp_csum_err; + uint32_t rxdma_error; + uint32_t reo_error; } err; uint32_t buf_freelist; @@ -1271,6 +1710,7 @@ struct cdp_pdev_stats { struct cdp_hist_tx_comp tx_comp_histogram; struct cdp_hist_rx_ind rx_ind_histogram; uint64_t ppdu_stats_counter[CDP_PPDU_STATS_MAX_TAG]; + uint32_t cdp_delayed_ba_not_recev; struct cdp_htt_tx_pdev_stats htt_tx_pdev_stats; struct cdp_htt_rx_pdev_stats htt_rx_pdev_stats; @@ -1278,9 +1718,20 @@ struct cdp_pdev_stats { /* Received wdi messages from fw */ uint32_t wdi_event[CDP_WDI_NUM_EVENTS]; struct cdp_tid_stats tid_stats; + + /* numbers of data/nondata per RU sizes */ + struct { + uint32_t data_rx_ru_size[OFDMA_NUM_RU_SIZE]; + uint32_t nondata_rx_ru_size[OFDMA_NUM_RU_SIZE]; + uint32_t data_rx_ppdu; + uint32_t data_users[OFDMA_NUM_USERS]; + } ul_ofdma; + + struct cdp_tso_stats tso_stats; + struct cdp_cfr_rcc_stats rcc; }; -#ifndef CONFIG_MCL +#ifdef QCA_ENH_V3_STATS_SUPPORT /* * Enumeration of PDEV Configuration parameter */ @@ -1615,6 +2066,8 @@ enum _ol_ath_param_t { OL_ATH_PARAM_ACS_NEAR_RANGE_WEIGHTAGE = 413, OL_ATH_PARAM_ACS_MID_RANGE_WEIGHTAGE = 414, OL_ATH_PARAM_ACS_FAR_RANGE_WEIGHTAGE = 415, + /* Set SELF AP OBSS_PD_THRESHOLD value */ + OL_ATH_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 416, /* Enable/Disable/Set MGMT_TTL in milliseconds. */ OL_ATH_PARAM_MGMT_TTL = 417, /* Enable/Disable/Set PROBE_RESP_TTL in milliseconds */ @@ -1623,6 +2076,44 @@ enum _ol_ath_param_t { OL_ATH_PARAM_MU_PPDU_DURATION = 419, /* Set TBTT_CTRL_CFG */ OL_ATH_PARAM_TBTT_CTRL = 420, + /* Enable/disable AP OBSS_PD_THRESHOLD */ + OL_ATH_PARAM_SET_CMD_OBSS_PD_THRESHOLD_ENABLE = 421, + /* Get baseline radio level channel width */ + OL_ATH_PARAM_RCHWIDTH = 422, + /* Whether external ACS request is in progress */ + OL_ATH_EXT_ACS_REQUEST_IN_PROGRESS = 423, + /* set/get hw mode */ + OL_ATH_PARAM_HW_MODE = 424, +#if DBDC_REPEATER_SUPPORT + /* same ssid feature global disable */ + OL_ATH_PARAM_SAME_SSID_DISABLE = 425, +#endif + /* get MBSS enable flag */ + OL_ATH_PARAM_MBSS_EN = 426, + /* UNII-1 and UNII-2A channel coexistance */ + OL_ATH_PARAM_CHAN_COEX = 427, + /* Out of Band Advertisement feature */ + OL_ATH_PARAM_OOB_ENABLE = 428, + /* set/get opmode-notification timer for hw-mode switch */ + OL_ATH_PARAM_HW_MODE_SWITCH_OMN_TIMER = 429, + /* enable opmode-notification when doing hw-mode switch */ + OL_ATH_PARAM_HW_MODE_SWITCH_OMN_ENABLE = 430, + /* set primary interface for hw-mode switch */ + OL_ATH_PARAM_HW_MODE_SWITCH_PRIMARY_IF = 431, + /* Number of vdevs configured per PSOC */ + OL_ATH_PARAM_GET_PSOC_NUM_VDEVS = 432, + /* Number of peers configured per PSOC */ + OL_ATH_PARAM_GET_PSOC_NUM_PEERS = 433, + /* Number of vdevs configured per PDEV */ + OL_ATH_PARAM_GET_PDEV_NUM_VDEVS = 434, + /* Number of peers configured per PDEV */ + OL_ATH_PARAM_GET_PDEV_NUM_PEERS = 435, + /* Number of monitor vdevs configured per PDEV */ + OL_ATH_PARAM_GET_PDEV_NUM_MONITOR_VDEVS = 436, +#ifdef CE_TASKLET_DEBUG_ENABLE + /* Enable/disable CE stats print */ + OL_ATH_PARAM_ENABLE_CE_LATENCY_STATS = 437, +#endif }; #endif /* Bitmasks for stats that can block */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h index 34e3cbe9355b7bd867bd4cc4796c1ad2d45d6c4c..044052dd7d14ad3471991b5d69b754a2c271c3ae 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,7 +27,7 @@ /** * cdp_tx_delay() - get tx packet delay * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @queue_delay_microsec: tx packet delay within queue, usec * @tx_delay_microsec: tx packet delay, usec * @category: packet category @@ -35,9 +35,9 @@ * Return: NONE */ static inline void -cdp_tx_delay(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint32_t *queue_delay_microsec, uint32_t *tx_delay_microsec, - int category) +cdp_tx_delay(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint32_t *queue_delay_microsec, uint32_t *tx_delay_microsec, + int category) { if (!soc || !soc->ops || !soc->ops->delay_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -46,7 +46,7 @@ cdp_tx_delay(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->delay_ops->tx_delay) - return soc->ops->delay_ops->tx_delay(pdev, + return soc->ops->delay_ops->tx_delay(soc, pdev_id, queue_delay_microsec, tx_delay_microsec, category); return; } @@ -54,15 +54,15 @@ cdp_tx_delay(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_tx_delay_hist() - get tx packet delay histogram * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @bin_values: bin * @category: packet category * * Return: NONE */ static inline void -cdp_tx_delay_hist(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint16_t *bin_values, int category) +cdp_tx_delay_hist(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint16_t *bin_values, int category) { if (!soc || !soc->ops || !soc->ops->delay_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -71,7 +71,7 @@ cdp_tx_delay_hist(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->delay_ops->tx_delay_hist) - return soc->ops->delay_ops->tx_delay_hist(pdev, + return soc->ops->delay_ops->tx_delay_hist(soc, pdev_id, bin_values, category); return; } @@ -79,16 +79,16 @@ cdp_tx_delay_hist(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_tx_packet_count() - get tx packet count * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @out_packet_loss_count: packet loss count * @category: packet category * * Return: NONE */ static inline void -cdp_tx_packet_count(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint16_t *out_packet_count, uint16_t *out_packet_loss_count, - int category) +cdp_tx_packet_count(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint16_t *out_packet_count, uint16_t *out_packet_loss_count, + int category) { if (!soc || !soc->ops || !soc->ops->delay_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -97,7 +97,7 @@ cdp_tx_packet_count(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->delay_ops->tx_packet_count) - return soc->ops->delay_ops->tx_packet_count(pdev, + return soc->ops->delay_ops->tx_packet_count(soc, pdev_id, out_packet_count, out_packet_loss_count, category); return; } @@ -105,14 +105,14 @@ cdp_tx_packet_count(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, /** * cdp_tx_set_compute_interval() - set tx packet stat compute interval * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @interval: compute interval * * Return: NONE */ static inline void -cdp_tx_set_compute_interval(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - uint32_t interval) +cdp_tx_set_compute_interval(ol_txrx_soc_handle soc, uint8_t pdev_id, + uint32_t interval) { if (!soc || !soc->ops || !soc->ops->delay_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -121,8 +121,9 @@ cdp_tx_set_compute_interval(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->delay_ops->tx_set_compute_interval) - return soc->ops->delay_ops->tx_set_compute_interval(pdev, - interval); + return soc->ops->delay_ops->tx_set_compute_interval(soc, + pdev_id, + interval); return; } #endif /* _CDP_TXRX_COMPUTE_TX_DELAY_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_throttle.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_throttle.h index 9716f27c4bd017ba648b81c995631b1566565a06..a17d1237bc06b23043e4c004096959c40b7138e9 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_throttle.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_throttle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,15 +29,15 @@ /** * cdp_throttle_init_period() - init tx throttle period * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @period: throttle period * @dutycycle_level: duty cycle level * * Return: NONE */ static inline void -cdp_throttle_init_period(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - int period, uint8_t *dutycycle_level) +cdp_throttle_init_period(ol_txrx_soc_handle soc, uint8_t pdev_id, + int period, uint8_t *dutycycle_level) { if (!soc || !soc->ops || !soc->ops->throttle_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -46,21 +46,21 @@ cdp_throttle_init_period(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, } if (soc->ops->throttle_ops->throttle_init_period) - return soc->ops->throttle_ops->throttle_init_period(pdev, - period, dutycycle_level); + return soc->ops->throttle_ops->throttle_init_period( + soc, pdev_id, period, dutycycle_level); return; } /** * cdp_throttle_init_period() - init tx throttle period * @soc: data path soc handle - * @pdev: physical device instance + * @pdev_id: id of data path pdev handle * @level: throttle level * * Return: NONE */ static inline void -cdp_throttle_set_level(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int level) +cdp_throttle_set_level(ol_txrx_soc_handle soc, uint8_t pdev_id, int level) { if (!soc || !soc->ops || !soc->ops->throttle_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -69,7 +69,8 @@ cdp_throttle_set_level(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int level) } if (soc->ops->throttle_ops->throttle_set_level) - return soc->ops->throttle_ops->throttle_set_level(pdev, level); + return soc->ops->throttle_ops->throttle_set_level(soc, pdev_id, + level); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h index db28e80bed9a07ebea9d8ed1783718d83b6e03db..24c253f03540c6eb82dfdfecdd789dd438c2f325 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,24 +30,24 @@ * This flag sets the wds rx policy on the vdev. Rx frames not compliant * with the policy will be dropped. * - * @param vdev - the data virtual device object + * @param vdev_id - id of the data virtual device object * @param val - the wds rx policy bitmask - * @return - void + * @return - QDF_STATUS */ -static inline void +static inline QDF_STATUS cdp_set_wds_rx_policy(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, + uint8_t vdev_id, u_int32_t val) { if (!soc || !soc->ops || !soc->ops->wds_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - return; + return QDF_STATUS_E_FAILURE; } if (soc->ops->wds_ops->txrx_set_wds_rx_policy) - return soc->ops->wds_ops->txrx_set_wds_rx_policy(vdev, val); - return; + soc->ops->wds_ops->txrx_set_wds_rx_policy(soc, vdev_id, val); + return QDF_STATUS_SUCCESS; } /** @@ -56,31 +56,34 @@ cdp_set_wds_rx_policy(ol_txrx_soc_handle soc, * This flag sets the wds rx policy on the vdev. Rx frames not compliant * with the policy will be dropped. * - * @param vdev - the data virtual device object + * @param psoc - psoc object + * @param vdev_id - id of the data virtual device object + * @param peer_mac - peer mac address * @param val - the wds rx policy bitmask - * @return - void + * @return - QDF_STATUS */ -static inline void +static inline QDF_STATUS cdp_set_wds_tx_policy_update(ol_txrx_soc_handle soc, - struct cdp_peer *peer, + uint8_t vdev_id, uint8_t *peer_mac, int wds_tx_ucast, int wds_tx_mcast) { if (!soc || !soc->ops || !soc->ops->wds_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, "%s invalid instance", __func__); - return; + return QDF_STATUS_E_FAILURE; } if (soc->ops->wds_ops->txrx_wds_peer_tx_policy_update) - return soc->ops->wds_ops->txrx_wds_peer_tx_policy_update( - peer, wds_tx_ucast, wds_tx_mcast); - return; + soc->ops->wds_ops->txrx_wds_peer_tx_policy_update( + soc, vdev_id, peer_mac, wds_tx_ucast, + wds_tx_mcast); + return QDF_STATUS_SUCCESS; } /** * cdp_vdev_set_wds() - Set/unset wds_enable flag in vdev * @soc - data path soc handle - * @vdev - data path vap handle + * @vdev_id - id of data path vap handle * @val - value to be set in wds_en flag * * This flag enables WDS source port learning feature on a vdev @@ -88,10 +91,10 @@ cdp_set_wds_tx_policy_update(ol_txrx_soc_handle soc, * return 1 on success */ static inline int -cdp_vdev_set_wds(ol_txrx_soc_handle soc, void *vdev, uint32_t val) +cdp_vdev_set_wds(ol_txrx_soc_handle soc, uint8_t vdev_id, uint32_t val) { if (soc->ops->wds_ops->vdev_set_wds) - return soc->ops->wds_ops->vdev_set_wds(vdev, val); + return soc->ops->wds_ops->vdev_set_wds(soc, vdev_id, val); return 0; } #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_cal_client_api.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_cal_client_api.h index 7bf9ec43b39fdb825702180469e8c9a97449c52b..d7c8815bff8f647472996f550f715c2daf04b2be 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_cal_client_api.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_cal_client_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,31 +26,34 @@ #include #include #include +#include /*timer will run every 1 sec*/ #define DP_CAL_CLIENT_TIME 1000 struct cal_client { qdf_timer_t cal_client_timer; - void (*iterate_update_peer_list)(void *ctx); - void *pdev_hdl; + void (*iterate_update_peer_list)(struct cdp_pdev *ctx); + struct cdp_pdev *pdev_hdl; }; -void dp_cal_client_attach(void **cal_client_ctx, void *pdev, qdf_device_t osdev, - void (*iterate_peer_list)(void *)); -void dp_cal_client_detach(void **cal_client_ctx); +void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx, + struct cdp_pdev *pdev, qdf_device_t osdev, + void (*iterate_peer_list)(struct cdp_pdev *)); +void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx); void dp_cal_client_timer_start(void *ctx); void dp_cal_client_timer_stop(void *ctx); void dp_cal_client_stats_timer_fn(void *pdev_hdl); void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats); #ifndef ATH_SUPPORT_EXT_STAT -void dp_cal_client_attach(void **cal_client_ctx, void *pdev, qdf_device_t osdev, - void (*iterate_peer_list)(void *)) +void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx, + struct cdp_pdev *pdev, qdf_device_t osdev, + void (*iterate_peer_list)(struct cdp_pdev *)) { } -void dp_cal_client_detach(void **cal_client_ctx) +void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx) { } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c index 71a7c7326c24c6eb7c916520cd7eb43c7fd0d20a..55cd09fa630c6ea7529cbac8421f85d41035f128 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,7 @@ #include "htt_stats.h" #include "htt_ppdu_stats.h" #include "dp_htt.h" +#include "dp_rx.h" #include "qdf_mem.h" /* qdf_mem_malloc,free */ #include "cdp_txrx_cmn_struct.h" @@ -43,20 +44,16 @@ #define HTT_PID_BIT_MASK 0x3 #define DP_EXT_MSG_LENGTH 2048 -#define DP_HTT_SEND_HTC_PKT(soc, pkt) \ -do { \ - if (htc_send_pkt(soc->htc_soc, &pkt->htc_pkt) == \ - QDF_STATUS_SUCCESS) { \ - htt_htc_misc_pkt_list_add(soc, pkt); \ - } else { \ - dp_err("htc_send_pkt failure!!"); \ - qdf_nbuf_free((qdf_nbuf_t)(pkt->htc_pkt.pNetBufContext)); \ - htt_htc_pkt_free(soc, pkt); \ - } \ -} while (0) #define HTT_MGMT_CTRL_TLV_HDR_RESERVERD_LEN 16 +#define HTT_SHIFT_UPPER_TIMESTAMP 32 +#define HTT_MASK_UPPER_TIMESTAMP 0xFFFFFFFF00000000 + +#define HTT_HTC_PKT_STATUS_SUCCESS \ + ((pkt->htc_pkt.Status != QDF_STATUS_E_CANCELED) && \ + (pkt->htc_pkt.Status != QDF_STATUS_E_RESOURCES)) + /* * dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap() - Get ppdu stats tlv * bitmap for sniffer mode @@ -77,6 +74,108 @@ dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap) } #ifdef FEATURE_PERPKT_INFO +/* + * dp_peer_copy_delay_stats() - copy ppdu stats to peer delayed stats. + * @peer: Datapath peer handle + * @ppdu: PPDU Descriptor + * + * Return: None + * + * on Tx data frame, we may get delayed ba set + * in htt_ppdu_stats_user_common_tlv. which mean we get Block Ack(BA) after we + * request Block Ack Request(BAR). Successful msdu is received only after Block + * Ack. To populate peer stats we need successful msdu(data frame). + * So we hold the Tx data stats on delayed_ba for stats update. + */ +static inline void +dp_peer_copy_delay_stats(struct dp_peer *peer, + struct cdp_tx_completion_ppdu_user *ppdu) +{ + struct dp_pdev *pdev; + struct dp_vdev *vdev; + + if (peer->last_delayed_ba) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "BA not yet recv for prev delayed ppdu[%d]\n", + peer->last_delayed_ba_ppduid); + vdev = peer->vdev; + if (vdev) { + pdev = vdev->pdev; + pdev->stats.cdp_delayed_ba_not_recev++; + } + } + + peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size; + peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc; + peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re; + peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf; + peer->delayed_ba_ppdu_stats.bw = ppdu->bw; + peer->delayed_ba_ppdu_stats.nss = ppdu->nss; + peer->delayed_ba_ppdu_stats.preamble = ppdu->preamble; + peer->delayed_ba_ppdu_stats.gi = ppdu->gi; + peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; + peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc; + peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; + peer->delayed_ba_ppdu_stats.mpdu_tried_ucast = ppdu->mpdu_tried_ucast; + peer->delayed_ba_ppdu_stats.mpdu_tried_mcast = ppdu->mpdu_tried_mcast; + peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl; + peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl; + peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm; + + peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start; + peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones; + peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast; + + peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos; + peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id; + + peer->last_delayed_ba = true; +} + +/* + * dp_peer_copy_stats_to_bar() - copy delayed stats to ppdu stats. + * @peer: Datapath peer handle + * @ppdu: PPDU Descriptor + * + * Return: None + * + * For Tx BAR, PPDU stats TLV include Block Ack info. PPDU info + * from Tx BAR frame not required to populate peer stats. + * But we need successful MPDU and MSDU to update previous + * transmitted Tx data frame. Overwrite ppdu stats with the previous + * stored ppdu stats. + */ +static void +dp_peer_copy_stats_to_bar(struct dp_peer *peer, + struct cdp_tx_completion_ppdu_user *ppdu) +{ + ppdu->ltf_size = peer->delayed_ba_ppdu_stats.ltf_size; + ppdu->stbc = peer->delayed_ba_ppdu_stats.stbc; + ppdu->he_re = peer->delayed_ba_ppdu_stats.he_re; + ppdu->txbf = peer->delayed_ba_ppdu_stats.txbf; + ppdu->bw = peer->delayed_ba_ppdu_stats.bw; + ppdu->nss = peer->delayed_ba_ppdu_stats.nss; + ppdu->preamble = peer->delayed_ba_ppdu_stats.preamble; + ppdu->gi = peer->delayed_ba_ppdu_stats.gi; + ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm; + ppdu->ldpc = peer->delayed_ba_ppdu_stats.ldpc; + ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm; + ppdu->mpdu_tried_ucast = peer->delayed_ba_ppdu_stats.mpdu_tried_ucast; + ppdu->mpdu_tried_mcast = peer->delayed_ba_ppdu_stats.mpdu_tried_mcast; + ppdu->frame_ctrl = peer->delayed_ba_ppdu_stats.frame_ctrl; + ppdu->qos_ctrl = peer->delayed_ba_ppdu_stats.qos_ctrl; + ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm; + + ppdu->ru_start = peer->delayed_ba_ppdu_stats.ru_start; + ppdu->ru_tones = peer->delayed_ba_ppdu_stats.ru_tones; + ppdu->is_mcast = peer->delayed_ba_ppdu_stats.is_mcast; + + ppdu->user_pos = peer->delayed_ba_ppdu_stats.user_pos; + ppdu->mu_group_id = peer->delayed_ba_ppdu_stats.mu_group_id; + + peer->last_delayed_ba = false; +} + /* * dp_tx_rate_stats_update() - Update rate per-peer statistics * @peer: Datapath peer handle @@ -91,6 +190,7 @@ dp_tx_rate_stats_update(struct dp_peer *peer, uint32_t ratekbps = 0; uint64_t ppdu_tx_rate = 0; uint32_t rix; + uint16_t ratecode = 0; if (!peer || !ppdu) return; @@ -100,15 +200,25 @@ dp_tx_rate_stats_update(struct dp_peer *peer, ppdu->nss, ppdu->preamble, ppdu->bw, - &rix); + &rix, + &ratecode); DP_STATS_UPD(peer, tx.last_tx_rate, ratekbps); if (!ratekbps) return; + /* Calculate goodput in non-training period + * In training period, don't do anything as + * pending pkt is send as goodput. + */ + if ((!peer->bss_peer) && (!ppdu->sa_is_training)) { + ppdu->sa_goodput = ((ratekbps / CDP_NUM_KB_IN_MB) * + (CDP_PERCENT_MACRO - ppdu->current_rate_per)); + } ppdu->rix = rix; ppdu->tx_ratekbps = ratekbps; + ppdu->tx_ratecode = ratecode; peer->stats.tx.avg_tx_rate = dp_ath_rate_lpf(peer->stats.tx.avg_tx_rate, ratekbps); ppdu_tx_rate = dp_ath_rate_out(peer->stats.tx.avg_tx_rate); @@ -135,7 +245,7 @@ dp_tx_rate_stats_update(struct dp_peer *peer, /* * dp_tx_stats_update() - Update per-peer statistics - * @soc: Datapath soc handle + * @pdev: Datapath pdev handle * @peer: Datapath peer handle * @ppdu: PPDU Descriptor * @ack_rssi: RSSI of last ack received @@ -143,27 +253,37 @@ dp_tx_rate_stats_update(struct dp_peer *peer, * Return: None */ static void -dp_tx_stats_update(struct dp_soc *soc, struct dp_peer *peer, +dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, struct cdp_tx_completion_ppdu_user *ppdu, uint32_t ack_rssi) { - struct dp_pdev *pdev = peer->vdev->pdev; uint8_t preamble, mcs; uint16_t num_msdu; + uint16_t num_mpdu; + uint16_t mpdu_tried; + uint16_t mpdu_failed; preamble = ppdu->preamble; mcs = ppdu->mcs; num_msdu = ppdu->num_msdu; + num_mpdu = ppdu->mpdu_success; + mpdu_tried = ppdu->mpdu_tried_ucast + ppdu->mpdu_tried_mcast; + mpdu_failed = mpdu_tried - num_mpdu; /* If the peer statistics are already processed as part of * per-MSDU completion handler, do not process these again in per-PPDU * indications */ - if (soc->process_tx_status) + if (pdev->soc->process_tx_status) return; if (ppdu->completion_status != HTT_PPDU_STATS_USER_STATUS_OK) { - DP_STATS_INC(peer, tx.retries, - (ppdu->long_retries + ppdu->short_retries)); + /* + * All failed mpdu will be retried, so incrementing + * retries mpdu based on mpdu failed. Even for + * ack failure i.e for long retries we get + * mpdu failed equal mpdu tried. + */ + DP_STATS_INC(peer, tx.retries, mpdu_failed); DP_STATS_INC(peer, tx.tx_failed, ppdu->failed_msdus); return; } @@ -187,27 +307,72 @@ dp_tx_stats_update(struct dp_soc *soc, struct dp_peer *peer, DP_STATS_UPD(peer, tx.ru_start, ppdu->ru_start); switch (ppdu->ru_tones) { case RU_26: - DP_STATS_INC(peer, tx.ru_loc[0], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_26_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_26_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_26_INDEX].mpdu_tried, + mpdu_tried); break; case RU_52: - DP_STATS_INC(peer, tx.ru_loc[1], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_52_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_52_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_52_INDEX].mpdu_tried, + mpdu_tried); break; case RU_106: - DP_STATS_INC(peer, tx.ru_loc[2], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_106_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_106_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_106_INDEX].mpdu_tried, + mpdu_tried); break; case RU_242: - DP_STATS_INC(peer, tx.ru_loc[3], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_242_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_242_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_242_INDEX].mpdu_tried, + mpdu_tried); break; case RU_484: - DP_STATS_INC(peer, tx.ru_loc[4], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_484_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_484_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_484_INDEX].mpdu_tried, + mpdu_tried); break; case RU_996: - DP_STATS_INC(peer, tx.ru_loc[5], num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_996_INDEX].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.ru_loc[RU_996_INDEX].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.ru_loc[RU_996_INDEX].mpdu_tried, + mpdu_tried); break; } } - DP_STATS_INC(peer, tx.transmit_type[ppdu->ppdu_type], num_msdu); + /* + * All failed mpdu will be retried, so incrementing + * retries mpdu based on mpdu failed. Even for + * ack failure i.e for long retries we get + * mpdu failed equal mpdu tried. + */ + DP_STATS_INC(peer, tx.retries, mpdu_failed); + DP_STATS_INC(peer, tx.tx_failed, ppdu->failed_msdus); + + DP_STATS_INC(peer, tx.transmit_type[ppdu->ppdu_type].num_msdu, + num_msdu); + DP_STATS_INC(peer, tx.transmit_type[ppdu->ppdu_type].num_mpdu, + num_mpdu); + DP_STATS_INC(peer, tx.transmit_type[ppdu->ppdu_type].mpdu_tried, + mpdu_tried); + DP_STATS_INC_PKT(peer, tx.comp_pkt, num_msdu, (ppdu->success_bytes + ppdu->retry_bytes + ppdu->failed_bytes)); @@ -215,7 +380,9 @@ dp_tx_stats_update(struct dp_soc *soc, struct dp_peer *peer, DP_STATS_INC(peer, tx.sgi_count[ppdu->gi], num_msdu); DP_STATS_INC(peer, tx.bw[ppdu->bw], num_msdu); DP_STATS_INC(peer, tx.nss[ppdu->nss], num_msdu); - DP_STATS_INC(peer, tx.wme_ac_type[TID_TO_WME_AC(ppdu->tid)], num_msdu); + if (ppdu->tid < CDP_DATA_TID_MAX) + DP_STATS_INC(peer, tx.wme_ac_type[TID_TO_WME_AC(ppdu->tid)], + num_msdu); DP_STATS_INCC(peer, tx.stbc, num_msdu, ppdu->stbc); DP_STATS_INCC(peer, tx.ldpc, num_msdu, ppdu->ldpc); if (!(ppdu->is_mcast) && ppdu->ack_rssi_valid) @@ -254,7 +421,7 @@ dp_tx_stats_update(struct dp_soc *soc, struct dp_peer *peer, DP_STATS_INCC(peer, tx.ampdu_cnt, num_msdu, ppdu->is_ampdu); DP_STATS_INCC(peer, tx.non_ampdu_cnt, num_msdu, !(ppdu->is_ampdu)); - dp_peer_stats_notify(peer); + dp_peer_stats_notify(pdev, peer); #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, @@ -394,6 +561,30 @@ htt_htc_misc_pkt_list_add(struct htt_soc *soc, struct dp_htt_htc_pkt *pkt) htt_htc_misc_pkt_list_trim(soc, misclist_trim_level); } +/** + * DP_HTT_SEND_HTC_PKT() - Send htt packet from host + * @soc : HTT SOC handle + * @pkt: pkt to be send + * @cmd : command to be recorded in dp htt logger + * @buf : Pointer to buffer needs to be recored for above cmd + * + * Return: None + */ +static inline QDF_STATUS DP_HTT_SEND_HTC_PKT(struct htt_soc *soc, + struct dp_htt_htc_pkt *pkt, + uint8_t cmd, uint8_t *buf) +{ + QDF_STATUS status; + + htt_command_record(soc->htt_logger_handle, cmd, buf); + + status = htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); + if (status == QDF_STATUS_SUCCESS && HTT_HTC_PKT_STATUS_SUCCESS) + htt_htc_misc_pkt_list_add(soc, pkt); + + return status; +} + /* * htt_htc_misc_pkt_pool_free() - free pkts in misc list * @htt_soc: HTT SOC handle @@ -404,6 +595,7 @@ htt_htc_misc_pkt_pool_free(struct htt_soc *soc) struct dp_htt_htc_pkt_union *pkt, *next; qdf_nbuf_t netbuf; + HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex); pkt = soc->htt_htc_pkt_misclist; while (pkt) { @@ -421,6 +613,7 @@ htt_htc_misc_pkt_pool_free(struct htt_soc *soc) pkt = next; } soc->htt_htc_pkt_misclist = NULL; + HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex); } /* @@ -513,6 +706,7 @@ static int htt_h2t_ver_req_msg(struct htt_soc *soc) struct dp_htt_htc_pkt *pkt; qdf_nbuf_t msg; uint32_t *msg_word; + QDF_STATUS status; msg = qdf_nbuf_alloc( soc->osdev, @@ -554,11 +748,18 @@ static int htt_h2t_ver_req_msg(struct htt_soc *soc) SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt, dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg), qdf_nbuf_len(msg), soc->htc_endpoint, - 1); /* tag - not relevant here */ + HTC_TX_PACKET_TAG_RTPM_PUT_RC); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); - DP_HTT_SEND_HTC_PKT(soc, pkt); - return 0; + status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_VERSION_REQ, + NULL); + + if (status != QDF_STATUS_SUCCESS) { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; } /* @@ -570,10 +771,10 @@ static int htt_h2t_ver_req_msg(struct htt_soc *soc) * * Return: 0 on success; error code on failure */ -int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, - int hal_ring_type) +int htt_srng_setup(struct htt_soc *soc, int mac_id, + hal_ring_handle_t hal_ring_hdl, + int hal_ring_type) { - struct htt_soc *soc = (struct htt_soc *)htt_soc; struct dp_htt_htc_pkt *pkt; qdf_nbuf_t htt_msg; uint32_t *msg_word; @@ -582,6 +783,10 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, uint32_t ring_entry_size = hal_srng_get_entrysize(soc->hal_soc, hal_ring_type); int htt_ring_type, htt_ring_id; + uint8_t *htt_logger_bufp; + int target_pdev_id; + int lmac_id = dp_get_lmac_id_for_pdev_id(soc->dp_soc, 0, mac_id); + QDF_STATUS status; /* Sizes should be set in 4-byte words */ ring_entry_size = ring_entry_size >> 2; @@ -593,9 +798,9 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, if (!htt_msg) goto fail0; - hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params); - hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_srng); - tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_srng); + hal_get_srng_params(soc->hal_soc, hal_ring_hdl, &srng_params); + hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_ring_hdl); + tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_ring_hdl); switch (hal_ring_type) { case RXDMA_BUF: @@ -613,7 +818,7 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, #else if (srng_params.ring_id == (HAL_SRNG_WMAC1_SW2RXDMA0_BUF0 + - (mac_id * HAL_MAX_RINGS_PER_LMAC))) { + (lmac_id * HAL_MAX_RINGS_PER_LMAC))) { htt_ring_id = HTT_RXDMA_HOST_BUF_RING; htt_ring_type = HTT_SW_TO_HW_RING; #endif @@ -623,7 +828,7 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, #else (HAL_SRNG_WMAC1_SW2RXDMA1_BUF + #endif - (mac_id * HAL_MAX_RINGS_PER_LMAC))) { + (lmac_id * HAL_MAX_RINGS_PER_LMAC))) { htt_ring_id = HTT_RXDMA_HOST_BUF_RING; htt_ring_type = HTT_SW_TO_HW_RING; } else { @@ -685,12 +890,14 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, /* word 0 */ *msg_word = 0; + htt_logger_bufp = (uint8_t *)msg_word; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SRING_SETUP); + target_pdev_id = + dp_get_target_pdev_id_for_host_pdev_id(soc->dp_soc, mac_id); if ((htt_ring_type == HTT_SW_TO_HW_RING) || (htt_ring_type == HTT_HW_TO_SW_RING)) - HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, - DP_SW2HW_MACID(mac_id)); + HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, target_pdev_id); else HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, mac_id); @@ -812,9 +1019,15 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, HTC_TX_PACKET_TAG_RUNTIME_PUT); /* tag for no FW response msg */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg); - DP_HTT_SEND_HTC_PKT(soc, pkt); + status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_SRING_SETUP, + htt_logger_bufp); - return QDF_STATUS_SUCCESS; + if (status != QDF_STATUS_SUCCESS) { + qdf_nbuf_free(htt_msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; fail1: qdf_nbuf_free(htt_msg); @@ -826,16 +1039,17 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng, * htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter * config message to target * @htt_soc: HTT SOC handle - * @pdev_id: PDEV Id + * @pdev_id: WIN- PDEV Id, MCL- mac id * @hal_srng: Opaque HAL SRNG pointer * @hal_ring_type: SRNG ring type * @ring_buf_size: SRNG buffer size * @htt_tlv_filter: Rx SRNG TLV and filter setting * Return: 0 on success; error code on failure */ -int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, - int hal_ring_type, int ring_buf_size, - struct htt_rx_ring_tlv_filter *htt_tlv_filter) +int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id, + hal_ring_handle_t hal_ring_hdl, + int hal_ring_type, int ring_buf_size, + struct htt_rx_ring_tlv_filter *htt_tlv_filter) { struct htt_soc *soc = (struct htt_soc *)htt_soc; struct dp_htt_htc_pkt *pkt; @@ -844,6 +1058,11 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, struct hal_srng_params srng_params; uint32_t htt_ring_type, htt_ring_id; uint32_t tlv_filter; + uint8_t *htt_logger_bufp; + struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = soc->dp_soc->wlan_cfg_ctx; + uint32_t mon_drop_th = wlan_cfg_get_mon_drop_thresh(wlan_cfg_ctx); + int target_pdev_id; + QDF_STATUS status; htt_msg = qdf_nbuf_alloc(soc->osdev, HTT_MSG_BUF_SIZE(HTT_RX_RING_SELECTION_CFG_SZ), @@ -852,7 +1071,7 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, if (!htt_msg) goto fail0; - hal_get_srng_params(soc->hal_soc, hal_srng, &srng_params); + hal_get_srng_params(soc->hal_soc, hal_ring_hdl, &srng_params); switch (hal_ring_type) { case RXDMA_BUF: @@ -905,6 +1124,7 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING); /* word 0 */ + htt_logger_bufp = (uint8_t *)msg_word; *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG); @@ -912,10 +1132,13 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, * pdev_id is indexed from 0 whereas mac_id is indexed from 1 * SW_TO_SW and SW_TO_HW rings are unaffected by this */ + target_pdev_id = + dp_get_target_pdev_id_for_host_pdev_id(soc->dp_soc, pdev_id); + if (htt_ring_type == HTT_SW_TO_SW_RING || htt_ring_type == HTT_SW_TO_HW_RING) HTT_RX_RING_SELECTION_CFG_PDEV_ID_SET(*msg_word, - DP_SW2HW_MACID(pdev_id)); + target_pdev_id); /* TODO: Discuss with FW on changing this to unique ID and using * htt_ring_type to send the type of ring @@ -931,6 +1154,13 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, HTT_RX_RING_SELECTION_CFG_RX_OFFSETS_VALID_SET(*msg_word, htt_tlv_filter->offset_valid); + if (mon_drop_th > 0) + HTT_RX_RING_SELECTION_CFG_DROP_THRESHOLD_VALID_SET(*msg_word, + 1); + else + HTT_RX_RING_SELECTION_CFG_DROP_THRESHOLD_VALID_SET(*msg_word, + 0); + /* word 1 */ msg_word++; *msg_word = 0; @@ -1494,8 +1724,17 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, *msg_word = 0; HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET_SET(*msg_word, htt_tlv_filter->rx_attn_offset); + msg_word++; + *msg_word = 0; + } else { + msg_word += 4; + *msg_word = 0; } + if (mon_drop_th > 0) + HTT_RX_RING_SELECTION_CFG_RX_DROP_THRESHOLD_SET(*msg_word, + mon_drop_th); + /* "response_required" field should be set if a HTT response message is * required after setting up the ring. */ @@ -1511,11 +1750,19 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, qdf_nbuf_data(htt_msg), qdf_nbuf_len(htt_msg), soc->htc_endpoint, - 1); /* tag - not relevant here */ + HTC_TX_PACKET_TAG_RUNTIME_PUT); /* tag for no FW response msg */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg); - DP_HTT_SEND_HTC_PKT(soc, pkt); - return QDF_STATUS_SUCCESS; + status = DP_HTT_SEND_HTC_PKT(soc, pkt, + HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG, + htt_logger_bufp); + + if (status != QDF_STATUS_SUCCESS) { + qdf_nbuf_free(htt_msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; fail1: qdf_nbuf_free(htt_msg); @@ -1668,9 +1915,13 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, } if (copy_stats) - dp_htt_stats_copy_tag(pdev, tlv_type, tlv_start); + dp_htt_stats_copy_tag(pdev, + tlv_type, + tlv_start); else - dp_htt_stats_print_tag(tlv_type, tlv_start); + dp_htt_stats_print_tag(pdev, + tlv_type, + tlv_start); if (tlv_type == HTT_STATS_PEER_DETAILS_TAG || tlv_type == HTT_STATS_PEER_STATS_CMN_TAG) @@ -1737,12 +1988,18 @@ void htt_t2h_stats_handler(void *context) uint32_t *msg_word; qdf_nbuf_t htt_msg = NULL; uint8_t done; - uint8_t rem_stats; + uint32_t rem_stats; + + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "soc is NULL"); + return; + } - if (!soc || !qdf_atomic_read(&soc->cmn_init_done)) { + if (!qdf_atomic_read(&soc->cmn_init_done)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "soc: 0x%pK, init_done: %d", soc, - qdf_atomic_read(&soc->cmn_init_done)); + "soc: 0x%pK, init_done: %d", soc, + qdf_atomic_read(&soc->cmn_init_done)); return; } @@ -1770,10 +2027,14 @@ void htt_t2h_stats_handler(void *context) rem_stats = --soc->htt_stats.num_stats; qdf_spin_unlock_bh(&soc->htt_stats.lock); - dp_process_htt_stat_msg(&htt_stats, soc); - /* If there are more stats to process, schedule stats work again */ + /* If there are more stats to process, schedule stats work again. + * Scheduling prior to processing ht_stats to queue with early + * index + */ if (rem_stats) qdf_sched_work(0, &soc->htt_stats.work); + + dp_process_htt_stat_msg(&htt_stats, soc); } /* @@ -1828,28 +2089,37 @@ static void dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev, uint32_t *tag_buf, struct ppdu_info *ppdu_info) { uint16_t frame_type; + uint16_t frame_ctrl; uint16_t freq; struct dp_soc *soc = NULL; struct cdp_tx_completion_ppdu *ppdu_desc = NULL; + uint64_t ppdu_start_timestamp; + uint32_t *start_tag_buf; + start_tag_buf = tag_buf; ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); - tag_buf += 2; + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RING_ID_SCH_CMD_ID); ppdu_info->sched_cmdid = HTT_PPDU_STATS_COMMON_TLV_SCH_CMDID_GET(*tag_buf); ppdu_desc->num_users = HTT_PPDU_STATS_COMMON_TLV_NUM_USERS_GET(*tag_buf); - tag_buf++; + + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(QTYPE_FRM_TYPE); frame_type = HTT_PPDU_STATS_COMMON_TLV_FRM_TYPE_GET(*tag_buf); + ppdu_desc->htt_frame_type = frame_type; + + frame_ctrl = ppdu_desc->frame_ctrl; switch (frame_type) { case HTT_STATS_FTYPE_TIDQ_DATA_SU: case HTT_STATS_FTYPE_TIDQ_DATA_MU: + case HTT_STATS_FTYPE_SGEN_QOS_NULL: /* * for management packet, frame type come as DATA_SU * need to check frame_ctrl before setting frame_type */ - if (HTT_GET_FRAME_CTRL_TYPE(frame_type) <= FRAME_CTRL_TYPE_CTRL) + if (HTT_GET_FRAME_CTRL_TYPE(frame_ctrl) <= FRAME_CTRL_TYPE_CTRL) ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL; else ppdu_desc->frame_type = CDP_PPDU_FTYPE_DATA; @@ -1857,34 +2127,58 @@ static void dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev, case HTT_STATS_FTYPE_SGEN_MU_BAR: case HTT_STATS_FTYPE_SGEN_BAR: ppdu_desc->frame_type = CDP_PPDU_FTYPE_BAR; + ppdu_desc->bar_ppdu_id = ppdu_info->ppdu_id; break; default: ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL; break; } - tag_buf += 2; + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(FES_DUR_US); ppdu_desc->tx_duration = *tag_buf; - tag_buf += 3; - ppdu_desc->ppdu_start_timestamp = *tag_buf; - - ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp + - ppdu_desc->tx_duration; - /* Ack time stamp is same as end time stamp*/ - ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp; - tag_buf++; + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_L32_US); + ppdu_desc->ppdu_start_timestamp = *tag_buf; + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(CHAN_MHZ_PHY_MODE); freq = HTT_PPDU_STATS_COMMON_TLV_CHAN_MHZ_GET(*tag_buf); if (freq != ppdu_desc->channel) { soc = pdev->soc; ppdu_desc->channel = freq; if (soc && soc->cdp_soc.ol_ops->freq_to_channel) pdev->operating_channel = - soc->cdp_soc.ol_ops->freq_to_channel(pdev->ctrl_pdev, freq); + soc->cdp_soc.ol_ops->freq_to_channel(soc->ctrl_psoc, + pdev->pdev_id, freq); } ppdu_desc->phy_mode = HTT_PPDU_STATS_COMMON_TLV_PHY_MODE_GET(*tag_buf); + + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RESV_NUM_UL_BEAM); + ppdu_desc->beam_change = + HTT_PPDU_STATS_COMMON_TLV_BEAM_CHANGE_GET(*tag_buf); + + dp_tx_capture_htt_frame_counter(pdev, frame_type); + + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_U32_US); + ppdu_start_timestamp = *tag_buf; + ppdu_desc->ppdu_start_timestamp |= ((ppdu_start_timestamp << + HTT_SHIFT_UPPER_TIMESTAMP) & + HTT_MASK_UPPER_TIMESTAMP); + + ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp + + ppdu_desc->tx_duration; + /* Ack time stamp is same as end time stamp*/ + ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp; + + ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp + + ppdu_desc->tx_duration; + + ppdu_desc->bar_ppdu_start_timestamp = ppdu_desc->ppdu_start_timestamp; + ppdu_desc->bar_ppdu_end_timestamp = ppdu_desc->ppdu_end_timestamp; + ppdu_desc->bar_tx_duration = ppdu_desc->tx_duration; + + /* Ack time stamp is same as end time stamp*/ + ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp; } /* @@ -1902,6 +2196,8 @@ static void dp_process_ppdu_stats_user_common_tlv( struct cdp_tx_completion_ppdu *ppdu_desc; struct cdp_tx_completion_ppdu_user *ppdu_user_desc; uint8_t curr_user_index = 0; + struct dp_peer *peer; + struct dp_vdev *vdev; ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); @@ -1917,9 +2213,20 @@ static void dp_process_ppdu_stats_user_common_tlv( if (peer_id == DP_SCAN_PEER_ID) { ppdu_desc->vdev_id = HTT_PPDU_STATS_USER_COMMON_TLV_VAP_ID_GET(*tag_buf); + vdev = + dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc, + ppdu_desc->vdev_id); + if (!vdev) + return; + qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw, + QDF_MAC_ADDR_SIZE); } else { - if (!dp_peer_find_by_id_valid(pdev->soc, peer_id)) + peer = dp_peer_find_by_id(pdev->soc, peer_id); + if (!peer) return; + qdf_mem_copy(ppdu_user_desc->mac_addr, + peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); + dp_peer_unref_del_find_by_id(peer); } ppdu_user_desc->peer_id = peer_id; @@ -1928,6 +2235,7 @@ static void dp_process_ppdu_stats_user_common_tlv( if (HTT_PPDU_STATS_USER_COMMON_TLV_DELAYED_BA_GET(*tag_buf)) { ppdu_user_desc->delayed_ba = 1; + ppdu_desc->delayed_ba = 1; } if (HTT_PPDU_STATS_USER_COMMON_TLV_MCAST_GET(*tag_buf)) { @@ -1948,11 +2256,8 @@ static void dp_process_ppdu_stats_user_common_tlv( HTT_PPDU_STATS_USER_COMMON_TLV_FRAME_CTRL_GET(*tag_buf); ppdu_desc->frame_ctrl = ppdu_user_desc->frame_ctrl; - if (ppdu_user_desc->delayed_ba) { + if (ppdu_user_desc->delayed_ba) ppdu_user_desc->mpdu_success = 0; - ppdu_user_desc->mpdu_tried_mcast = 0; - ppdu_user_desc->mpdu_tried_ucast = 0; - } tag_buf += 3; @@ -1998,14 +2303,10 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev, ppdu_desc->vdev_id); if (!vdev) return; - qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw, - QDF_MAC_ADDR_SIZE); } else { peer = dp_peer_find_by_id(pdev->soc, peer_id); if (!peer) return; - qdf_mem_copy(ppdu_user_desc->mac_addr, - peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); dp_peer_unref_del_find_by_id(peer); } @@ -2167,6 +2468,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv( struct cdp_tx_completion_ppdu *ppdu_desc; struct cdp_tx_completion_ppdu_user *ppdu_user_desc; uint8_t curr_user_index = 0; + uint8_t bw_iter; htt_ppdu_stats_user_cmpltn_common_tlv *dp_stats_buf = (htt_ppdu_stats_user_cmpltn_common_tlv *)tag_buf; @@ -2206,6 +2508,10 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv( ppdu_user_desc->mpdu_success = HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_SUCCESS_GET(*tag_buf); + ppdu_user_desc->mpdu_failed = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_TRIED_GET(*tag_buf) - + ppdu_user_desc->mpdu_success; + tag_buf++; ppdu_user_desc->long_retries = @@ -2220,6 +2526,56 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv( HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_AMPDU_GET(*tag_buf); ppdu_info->is_ampdu = ppdu_user_desc->is_ampdu; + ppdu_desc->resp_type = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RESP_TYPE_GET(*tag_buf); + ppdu_desc->mprot_type = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPROT_TYPE_GET(*tag_buf); + ppdu_desc->rts_success = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_SUCCESS_GET(*tag_buf); + ppdu_desc->rts_failure = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_FAILURE_GET(*tag_buf); + + /* + * increase successful mpdu counter from + * htt_ppdu_stats_user_cmpltn_common_tlv + */ + ppdu_info->mpdu_compltn_common_tlv += ppdu_user_desc->mpdu_success; + + /* + * MU BAR may send request to n users but we may received ack only from + * m users. To have count of number of users respond back, we have a + * separate counter bar_num_users per PPDU that get increment for every + * htt_ppdu_stats_user_cmpltn_common_tlv + */ + ppdu_desc->bar_num_users++; + + tag_buf++; + for (bw_iter = 0; bw_iter < CDP_RSSI_CHAIN_LEN; bw_iter++) { + ppdu_user_desc->rssi_chain[bw_iter] = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CHAIN_RSSI_GET(*tag_buf); + tag_buf++; + } + + ppdu_user_desc->sa_tx_antenna = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TX_ANTENNA_MASK_GET(*tag_buf); + + tag_buf++; + ppdu_user_desc->sa_is_training = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_TRAINING_GET(*tag_buf); + if (ppdu_user_desc->sa_is_training) { + ppdu_user_desc->sa_goodput = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PENDING_TRAINING_PKTS_GET(*tag_buf); + } + + tag_buf++; + for (bw_iter = 0; bw_iter < CDP_NUM_SA_BW; bw_iter++) { + ppdu_user_desc->sa_max_rates[bw_iter] = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(tag_buf[bw_iter]); + } + + tag_buf += CDP_NUM_SA_BW; + ppdu_user_desc->current_rate_per = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CURRENT_RATE_PER_GET(*tag_buf); } /* @@ -2260,6 +2616,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv( ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no; qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap, sizeof(uint32_t) * CDP_BA_64_BIT_MAP_SIZE_DWORDS); + ppdu_user_desc->ba_size = CDP_BA_64_BIT_MAP_SIZE_DWORDS * 32; } /* @@ -2300,6 +2657,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv( ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no; qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap, sizeof(uint32_t) * CDP_BA_256_BIT_MAP_SIZE_DWORDS); + ppdu_user_desc->ba_size = CDP_BA_256_BIT_MAP_SIZE_DWORDS * 32; } /* @@ -2335,8 +2693,7 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv( ppdu_user_desc->peer_id = peer_id; tag_buf++; - ppdu_user_desc->tid = - HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_TID_NUM_GET(*tag_buf); + /* not to update ppdu_desc->tid from this TLV */ ppdu_user_desc->num_mpdu = HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MPDU_GET(*tag_buf); @@ -2345,9 +2702,16 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv( ppdu_user_desc->success_msdus = ppdu_user_desc->num_msdu; - tag_buf += 2; + tag_buf++; + ppdu_user_desc->start_seq = + HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_START_SEQ_GET( + *tag_buf); + + tag_buf++; ppdu_user_desc->success_bytes = *tag_buf; + /* increase successful mpdu counter */ + ppdu_info->mpdu_ack_ba_tlv += ppdu_user_desc->num_mpdu; } /* @@ -2406,37 +2770,50 @@ static void dp_process_ppdu_stats_user_common_array_tlv( * htt_ppdu_stats_flush_tlv * @pdev: DP PDEV handle * @tag_buf: buffer containing the htt_ppdu_stats_flush_tlv + * @ppdu_info: per ppdu tlv structure * * return:void */ -static void dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev, - uint32_t *tag_buf) +static void +dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev, + uint32_t *tag_buf, + struct ppdu_info *ppdu_info) { + struct cdp_tx_completion_ppdu *ppdu_desc; uint32_t peer_id; - uint32_t drop_reason; uint8_t tid; - uint32_t num_msdu; struct dp_peer *peer; + ppdu_desc = (struct cdp_tx_completion_ppdu *) + qdf_nbuf_data(ppdu_info->nbuf); + ppdu_desc->is_flush = 1; + tag_buf++; - drop_reason = *tag_buf; + ppdu_desc->drop_reason = *tag_buf; tag_buf++; - num_msdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MSDU_GET(*tag_buf); + ppdu_desc->num_msdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MSDU_GET(*tag_buf); + ppdu_desc->num_mpdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MPDU_GET(*tag_buf); + ppdu_desc->flow_type = HTT_PPDU_STATS_FLUSH_TLV_FLOW_TYPE_GET(*tag_buf); tag_buf++; - peer_id = - HTT_PPDU_STATS_FLUSH_TLV_SW_PEER_ID_GET(*tag_buf); + peer_id = HTT_PPDU_STATS_FLUSH_TLV_SW_PEER_ID_GET(*tag_buf); + tid = HTT_PPDU_STATS_FLUSH_TLV_TID_NUM_GET(*tag_buf); + + ppdu_desc->user[0].peer_id = peer_id; + ppdu_desc->user[0].tid = tid; + + ppdu_desc->queue_type = + HTT_PPDU_STATS_FLUSH_TLV_QUEUE_TYPE_GET(*tag_buf); peer = dp_peer_find_by_id(pdev->soc, peer_id); if (!peer) return; - tid = HTT_PPDU_STATS_FLUSH_TLV_TID_NUM_GET(*tag_buf); - - if (drop_reason == HTT_FLUSH_EXCESS_RETRIES) { - DP_STATS_INC(peer, tx.excess_retries_per_ac[TID_TO_WME_AC(tid)], - num_msdu); + if (ppdu_desc->drop_reason == HTT_FLUSH_EXCESS_RETRIES) { + DP_STATS_INC(peer, + tx.excess_retries_per_ac[TID_TO_WME_AC(tid)], + ppdu_desc->num_msdu); } dp_peer_unref_del_find_by_id(peer); @@ -2450,7 +2827,7 @@ static void dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev, * * return: void */ -static void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf) +void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf) { if (pdev->tx_sniffer_enable || pdev->mcopy_mode) { dp_wdi_event_handler(WDI_EVENT_TX_MGMT_CTRL, pdev->soc, @@ -2476,11 +2853,22 @@ dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev *pdev, { uint32_t *nbuf_ptr; uint8_t trim_size; + size_t head_size; + struct cdp_tx_mgmt_comp_info *ptr_mgmt_comp_info; + uint32_t *msg_word; + uint32_t tsf_hdr; if ((!pdev->tx_sniffer_enable) && (!pdev->mcopy_mode) && (!pdev->bpr_enable) && (!pdev->tx_capture_enabled)) return QDF_STATUS_SUCCESS; + /* + * get timestamp from htt_t2h_ppdu_stats_ind_hdr_t + */ + msg_word = (uint32_t *)qdf_nbuf_data(tag_buf); + msg_word = msg_word + 2; + tsf_hdr = *msg_word; + trim_size = ((pdev->mgmtctrl_frm_info.mgmt_buf + HTT_MGMT_CTRL_TLV_HDR_RESERVERD_LEN) - qdf_nbuf_data(tag_buf)); @@ -2491,9 +2879,25 @@ dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev *pdev, qdf_nbuf_trim_tail(tag_buf, qdf_nbuf_len(tag_buf) - pdev->mgmtctrl_frm_info.mgmt_buf_len); - nbuf_ptr = (uint32_t *)qdf_nbuf_push_head( - tag_buf, sizeof(ppdu_id)); - *nbuf_ptr = ppdu_id; + if (pdev->tx_capture_enabled) { + head_size = sizeof(struct cdp_tx_mgmt_comp_info); + if (qdf_unlikely(qdf_nbuf_headroom(tag_buf) < head_size)) { + qdf_err("Fail to get headroom h_sz %d h_avail %d\n", + head_size, qdf_nbuf_headroom(tag_buf)); + qdf_assert_always(0); + return QDF_STATUS_E_NOMEM; + } + ptr_mgmt_comp_info = (struct cdp_tx_mgmt_comp_info *) + qdf_nbuf_push_head(tag_buf, head_size); + qdf_assert_always(ptr_mgmt_comp_info); + ptr_mgmt_comp_info->ppdu_id = ppdu_id; + ptr_mgmt_comp_info->is_sgen_pkt = true; + ptr_mgmt_comp_info->tx_tsf = tsf_hdr; + } else { + head_size = sizeof(ppdu_id); + nbuf_ptr = (uint32_t *)qdf_nbuf_push_head(tag_buf, head_size); + *nbuf_ptr = ppdu_id; + } if (pdev->bpr_enable) { dp_wdi_event_handler(WDI_EVENT_TX_BEACON, pdev->soc, @@ -2635,8 +3039,8 @@ static void dp_process_ppdu_tag(struct dp_pdev *pdev, uint32_t *tag_buf, tlv_expected_size = sizeof(htt_ppdu_stats_flush_tlv); tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf, tlv_expected_size, tlv_len); - dp_process_ppdu_stats_user_compltn_flush_tlv( - pdev, tlv_desc); + dp_process_ppdu_stats_user_compltn_flush_tlv(pdev, tlv_desc, + ppdu_info); break; default: break; @@ -2659,6 +3063,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, uint32_t tlv_bitmap_expected; uint32_t tlv_bitmap_default; uint16_t i; + uint32_t num_users; ppdu_desc = (struct cdp_tx_completion_ppdu *) qdf_nbuf_data(ppdu_info->nbuf); @@ -2667,7 +3072,8 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, ppdu_desc->ppdu_id = ppdu_info->ppdu_id; tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP; - if (pdev->tx_sniffer_enable || pdev->mcopy_mode) { + if (pdev->tx_sniffer_enable || pdev->mcopy_mode || + pdev->tx_capture_enabled) { if (ppdu_info->is_ampdu) tlv_bitmap_expected = dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap( @@ -2675,7 +3081,15 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, } tlv_bitmap_default = tlv_bitmap_expected; - for (i = 0; i < ppdu_desc->num_users; i++) { + + if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) { + num_users = ppdu_desc->bar_num_users; + ppdu_desc->num_users = ppdu_desc->bar_num_users; + } else { + num_users = ppdu_desc->num_users; + } + + for (i = 0; i < num_users; i++) { ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu; ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu; @@ -2689,23 +3103,40 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, continue; ppdu_desc->user[i].cookie = (void *)peer->wlanstats_ctx; - if (ppdu_desc->user[i].completion_status != - HTT_PPDU_STATS_USER_STATUS_OK) - tlv_bitmap_expected = tlv_bitmap_expected & 0xFF; - if (ppdu_info->tlv_bitmap != tlv_bitmap_expected) { + /* + * different frame like DATA, BAR or CTRL has different + * tlv bitmap expected. Apart from ACK_BA_STATUS TLV, we + * receive other tlv in-order/sequential from fw. + * Since ACK_BA_STATUS TLV come from Hardware it is + * asynchronous So we need to depend on some tlv to confirm + * all tlv is received for a ppdu. + * So we depend on both HTT_PPDU_STATS_COMMON_TLV and + * ACK_BA_STATUS_TLV. for failure packet we won't get + * ACK_BA_STATUS_TLV. + */ + if (!(ppdu_info->tlv_bitmap & + (1 << HTT_PPDU_STATS_COMMON_TLV)) || + (!(ppdu_info->tlv_bitmap & + (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)) && + (ppdu_desc->user[i].completion_status == + HTT_PPDU_STATS_USER_STATUS_OK))) { dp_peer_unref_del_find_by_id(peer); continue; } + /** * Update tx stats for data frames having Qos as well as * non-Qos data tid */ + if ((ppdu_desc->user[i].tid < CDP_DATA_TID_MAX || - (ppdu_desc->user[i].tid == CDP_DATA_NON_QOS_TID)) && - (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA)) { + (ppdu_desc->user[i].tid == CDP_DATA_NON_QOS_TID) || + (ppdu_desc->htt_frame_type == + HTT_STATS_FTYPE_SGEN_QOS_NULL)) && + (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL)) { - dp_tx_stats_update(pdev->soc, peer, + dp_tx_stats_update(pdev, peer, &ppdu_desc->user[i], ppdu_desc->ack_rssi); dp_tx_rate_stats_update(peer, &ppdu_desc->user[i]); @@ -2815,6 +3246,15 @@ struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV))) return ppdu_info; + /** + * apart from ACK BA STATUS TLV rest all comes in order + * so if tlv type not ACK BA STATUS TLV we can deliver + * ppdu_info + */ + if (tlv_type == + HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) + return ppdu_info; + dp_ppdu_desc_deliver(pdev, ppdu_info); } else { return ppdu_info; @@ -2889,6 +3329,8 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, uint8_t *tlv_buf; struct ppdu_info *ppdu_info = NULL; struct cdp_tx_completion_ppdu *ppdu_desc = NULL; + struct dp_peer *peer; + uint32_t i = 0; uint32_t *msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg); @@ -2918,8 +3360,10 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, */ if (tlv_type == HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) { pdev->mgmtctrl_frm_info.mgmt_buf = tlv_buf; - pdev->mgmtctrl_frm_info.mgmt_buf_len = tlv_length; pdev->mgmtctrl_frm_info.ppdu_id = ppdu_id; + pdev->mgmtctrl_frm_info.mgmt_buf_len = + HTT_PPDU_STATS_TX_MGMTCTRL_TLV_FRAME_LENGTH_GET + (*(msg_word + 1)); msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length); length -= (tlv_length); @@ -2929,6 +3373,9 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type); if (!ppdu_info) return NULL; + ppdu_info->ppdu_desc->bss_color = + pdev->rx_mon_recv_status.bsscolor; + ppdu_info->ppdu_id = ppdu_id; ppdu_info->tlv_bitmap |= (1 << tlv_type); @@ -2951,26 +3398,111 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP; + if (pdev->tx_sniffer_enable || pdev->mcopy_mode || + pdev->tx_capture_enabled) { + if (ppdu_info->is_ampdu) + tlv_bitmap_expected = + dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap( + ppdu_info->tlv_bitmap); + } + ppdu_desc = ppdu_info->ppdu_desc; - if (ppdu_desc && - ppdu_desc->user[ppdu_desc->last_usr_index].completion_status != + + if (!ppdu_desc) + return NULL; + + if (ppdu_desc->user[ppdu_desc->last_usr_index].completion_status != HTT_PPDU_STATS_USER_STATUS_OK) { tlv_bitmap_expected = tlv_bitmap_expected & 0xFF; } - if (pdev->tx_sniffer_enable || pdev->mcopy_mode) { - if (ppdu_info->is_ampdu) - tlv_bitmap_expected = - dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap( - ppdu_info->tlv_bitmap); + if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_COMMON_TLV)) && + ppdu_desc->delayed_ba) { + for (i = 0; i < ppdu_desc->num_users; i++) { + uint32_t ppdu_id; + + ppdu_id = ppdu_desc->ppdu_id; + peer = dp_peer_find_by_id(pdev->soc, + ppdu_desc->user[i].peer_id); + /** + * This check is to make sure peer is not deleted + * after processing the TLVs. + */ + if (!peer) + continue; + + /** + * save delayed ba user info + */ + if (ppdu_desc->user[i].delayed_ba) { + dp_peer_copy_delay_stats(peer, + &ppdu_desc->user[i]); + peer->last_delayed_ba_ppduid = ppdu_id; + } + dp_peer_unref_del_find_by_id(peer); + } + } + + /* + * when frame type is BAR and STATS_COMMON_TLV is set + * copy the store peer delayed info to BAR status + */ + if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_COMMON_TLV))) { + for (i = 0; i < ppdu_desc->bar_num_users; i++) { + peer = dp_peer_find_by_id(pdev->soc, + ppdu_desc->user[i].peer_id); + /** + * This check is to make sure peer is not deleted + * after processing the TLVs. + */ + if (!peer) + continue; + + if (peer->last_delayed_ba) { + dp_peer_copy_stats_to_bar(peer, + &ppdu_desc->user[i]); + ppdu_desc->bar_ppdu_id = ppdu_desc->ppdu_id; + ppdu_desc->ppdu_id = + peer->last_delayed_ba_ppduid; + } + dp_peer_unref_del_find_by_id(peer); + } + } + + /* + * for frame type DATA and BAR, we update stats based on MSDU, + * successful msdu and mpdu are populate from ACK BA STATUS TLV + * which comes out of order. successful mpdu also populated from + * COMPLTN COMMON TLV which comes in order. for every ppdu_info + * we store successful mpdu from both tlv and compare before delivering + * to make sure we received ACK BA STATUS TLV. For some self generated + * frame we won't get ack ba status tlv so no need to wait for + * ack ba status tlv. + */ + if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL && + ppdu_desc->htt_frame_type != HTT_STATS_FTYPE_SGEN_QOS_NULL) { + /* + * successful mpdu count should match with both tlv + */ + if (ppdu_info->mpdu_compltn_common_tlv != + ppdu_info->mpdu_ack_ba_tlv) + return NULL; } /** * Once all the TLVs for a given PPDU has been processed, - * return PPDU status to be delivered to higher layer + * return PPDU status to be delivered to higher layer. + * tlv_bitmap_expected can't be available for different frame type. + * But STATS COMMON TLV is the last TLV from the FW for a ppdu. + * apart from ACK BA TLV, FW sends other TLV in sequential order. + * flush tlv comes separate. */ - if (ppdu_info->tlv_bitmap != 0 && - ppdu_info->tlv_bitmap == tlv_bitmap_expected) + if ((ppdu_info->tlv_bitmap != 0 && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_COMMON_TLV))) || + (ppdu_info->tlv_bitmap & + (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV))) return ppdu_info; return NULL; @@ -3008,17 +3540,15 @@ static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, (pdev, htt_t2h_msg, pdev->mgmtctrl_frm_info.ppdu_id) != QDF_STATUS_SUCCESS) free_buf = false; - - if (free_buf) { - pdev->mgmtctrl_frm_info.mgmt_buf = NULL; - pdev->mgmtctrl_frm_info.mgmt_buf_len = 0; - pdev->mgmtctrl_frm_info.ppdu_id = 0; - } } if (ppdu_info) dp_ppdu_desc_deliver(pdev, ppdu_info); + pdev->mgmtctrl_frm_info.mgmt_buf = NULL; + pdev->mgmtctrl_frm_info.mgmt_buf_len = 0; + pdev->mgmtctrl_frm_info.ppdu_id = 0; + return free_buf; } #else @@ -3100,34 +3630,85 @@ static inline void dp_txrx_fw_stats_handler(struct dp_soc *soc, * * Return: 0 on success; error code on failure */ -int htt_soc_attach_target(void *htt_soc) +int htt_soc_attach_target(struct htt_soc *htt_soc) { struct htt_soc *soc = (struct htt_soc *)htt_soc; return htt_h2t_ver_req_msg(soc); } +void htt_set_htc_handle(struct htt_soc *htt_soc, HTC_HANDLE htc_soc) +{ + htt_soc->htc_soc = htc_soc; +} -#if defined(WDI_EVENT_ENABLE) && !defined(REMOVE_PKT_LOG) -/* - * dp_ppdu_stats_ind_handler() - PPDU stats msg handler - * @htt_soc: HTT SOC handle - * @msg_word: Pointer to payload - * @htt_t2h_msg: HTT msg nbuf - * - * Return: True if buffer should be freed by caller. - */ -static bool -dp_ppdu_stats_ind_handler(struct htt_soc *soc, - uint32_t *msg_word, - qdf_nbuf_t htt_t2h_msg) +HTC_HANDLE htt_get_htc_handle(struct htt_soc *htt_soc) { - u_int8_t pdev_id; - bool free_buf; - qdf_nbuf_set_pktlen(htt_t2h_msg, HTT_T2H_MAX_MSG_SIZE); - pdev_id = HTT_T2H_PPDU_STATS_PDEV_ID_GET(*msg_word); - pdev_id = DP_HW2SW_MACID(pdev_id); - free_buf = dp_txrx_ppdu_stats_handler(soc->dp_soc, pdev_id, + return htt_soc->htc_soc; +} + +struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_handle) +{ + int i; + int j; + int alloc_size = HTT_SW_UMAC_RING_IDX_MAX * sizeof(unsigned long); + struct htt_soc *htt_soc = NULL; + + htt_soc = qdf_mem_malloc(sizeof(*htt_soc)); + if (!htt_soc) { + dp_err("HTT attach failed"); + return NULL; + } + + for (i = 0; i < MAX_PDEV_CNT; i++) { + htt_soc->pdevid_tt[i].umac_ttt = qdf_mem_malloc(alloc_size); + if (!htt_soc->pdevid_tt[i].umac_ttt) + break; + qdf_mem_set(htt_soc->pdevid_tt[i].umac_ttt, alloc_size, -1); + htt_soc->pdevid_tt[i].lmac_ttt = qdf_mem_malloc(alloc_size); + if (!htt_soc->pdevid_tt[i].lmac_ttt) { + qdf_mem_free(htt_soc->pdevid_tt[i].umac_ttt); + break; + } + qdf_mem_set(htt_soc->pdevid_tt[i].lmac_ttt, alloc_size, -1); + } + if (i != MAX_PDEV_CNT) { + for (j = 0; j < i; j++) { + qdf_mem_free(htt_soc->pdevid_tt[i].umac_ttt); + qdf_mem_free(htt_soc->pdevid_tt[i].lmac_ttt); + } + return NULL; + } + + htt_soc->dp_soc = soc; + htt_soc->htc_soc = htc_handle; + HTT_TX_MUTEX_INIT(&htt_soc->htt_tx_mutex); + + return htt_soc; +} + +#if defined(WDI_EVENT_ENABLE) && !defined(REMOVE_PKT_LOG) +/* + * dp_ppdu_stats_ind_handler() - PPDU stats msg handler + * @htt_soc: HTT SOC handle + * @msg_word: Pointer to payload + * @htt_t2h_msg: HTT msg nbuf + * + * Return: True if buffer should be freed by caller. + */ +static bool +dp_ppdu_stats_ind_handler(struct htt_soc *soc, + uint32_t *msg_word, + qdf_nbuf_t htt_t2h_msg) +{ + u_int8_t pdev_id; + u_int8_t target_pdev_id; + bool free_buf; + qdf_nbuf_set_pktlen(htt_t2h_msg, HTT_T2H_MAX_MSG_SIZE); + target_pdev_id = HTT_T2H_PPDU_STATS_PDEV_ID_GET(*msg_word); + pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc, + target_pdev_id); + free_buf = dp_txrx_ppdu_stats_handler(soc->dp_soc, pdev_id, htt_t2h_msg); dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc, htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL, @@ -3158,10 +3739,12 @@ dp_pktlog_msg_handler(struct htt_soc *soc, uint32_t *msg_word) { uint8_t pdev_id; + uint8_t target_pdev_id; uint32_t *pl_hdr; - pdev_id = HTT_T2H_PKTLOG_PDEV_ID_GET(*msg_word); - pdev_id = DP_HW2SW_MACID(pdev_id); + target_pdev_id = HTT_T2H_PKTLOG_PDEV_ID_GET(*msg_word); + pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc, + target_pdev_id); pl_hdr = (msg_word + 1); dp_wdi_event_handler(WDI_EVENT_OFFLOAD_ALL, soc->dp_soc, pl_hdr, HTT_INVALID_PEER, WDI_NO_VAL, @@ -3174,6 +3757,109 @@ dp_pktlog_msg_handler(struct htt_soc *soc, { } #endif + +/* + * time_allow_print() - time allow print + * @htt_ring_tt: ringi_id array of timestamps + * @ring_id: ring_id (index) + * + * Return: 1 for successfully saving timestamp in array + * and 0 for timestamp falling within 2 seconds after last one + */ +static bool time_allow_print(unsigned long *htt_ring_tt, u_int8_t ring_id) +{ + unsigned long tstamp; + unsigned long delta; + + tstamp = qdf_get_system_timestamp(); + + if (!htt_ring_tt) + return 0; //unable to print backpressure messages + + if (htt_ring_tt[ring_id] == -1) { + htt_ring_tt[ring_id] = tstamp; + return 1; + } + delta = tstamp - htt_ring_tt[ring_id]; + if (delta >= 2000) { + htt_ring_tt[ring_id] = tstamp; + return 1; + } + + return 0; +} + +static void dp_htt_alert_print(enum htt_t2h_msg_type msg_type, + u_int8_t pdev_id, u_int8_t ring_id, + u_int16_t hp_idx, u_int16_t tp_idx, + u_int32_t bkp_time, char *ring_stype) +{ + dp_alert("msg_type: %d pdev_id: %d ring_type: %s ", + msg_type, pdev_id, ring_stype); + dp_alert("ring_id: %d hp_idx: %d tp_idx: %d bkpressure_time_ms: %d ", + ring_id, hp_idx, tp_idx, bkp_time); +} + +/* + * dp_htt_bkp_event_alert() - htt backpressure event alert + * @msg_word: htt packet context + * @htt_soc: HTT SOC handle + * + * Return: after attempting to print stats + */ +static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc) +{ + u_int8_t ring_type; + u_int8_t pdev_id; + uint8_t target_pdev_id; + u_int8_t ring_id; + u_int16_t hp_idx; + u_int16_t tp_idx; + u_int32_t bkp_time; + enum htt_t2h_msg_type msg_type; + struct dp_soc *dpsoc; + struct dp_pdev *pdev; + struct dp_htt_timestamp *radio_tt; + + if (!soc) + return; + + dpsoc = (struct dp_soc *)soc->dp_soc; + msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); + ring_type = HTT_T2H_RX_BKPRESSURE_RING_TYPE_GET(*msg_word); + target_pdev_id = HTT_T2H_RX_BKPRESSURE_PDEV_ID_GET(*msg_word); + pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc, + target_pdev_id); + pdev = (struct dp_pdev *)dpsoc->pdev_list[pdev_id]; + ring_id = HTT_T2H_RX_BKPRESSURE_RINGID_GET(*msg_word); + hp_idx = HTT_T2H_RX_BKPRESSURE_HEAD_IDX_GET(*(msg_word + 1)); + tp_idx = HTT_T2H_RX_BKPRESSURE_TAIL_IDX_GET(*(msg_word + 1)); + bkp_time = HTT_T2H_RX_BKPRESSURE_TIME_MS_GET(*(msg_word + 2)); + radio_tt = &soc->pdevid_tt[pdev_id]; + + switch (ring_type) { + case HTT_SW_RING_TYPE_UMAC: + if (!time_allow_print(radio_tt->umac_ttt, ring_id)) + return; + dp_htt_alert_print(msg_type, pdev_id, ring_id, hp_idx, tp_idx, + bkp_time, "HTT_SW_RING_TYPE_UMAC"); + break; + case HTT_SW_RING_TYPE_LMAC: + if (!time_allow_print(radio_tt->lmac_ttt, ring_id)) + return; + dp_htt_alert_print(msg_type, pdev_id, ring_id, hp_idx, tp_idx, + bkp_time, "HTT_SW_RING_TYPE_LMAC"); + break; + default: + dp_htt_alert_print(msg_type, pdev_id, ring_id, hp_idx, tp_idx, + bkp_time, "UNKNOWN"); + break; + } + + dp_print_ring_stats(pdev); + dp_print_napi_stats(pdev->soc); +} + /* * dp_htt_t2h_msg_handler() - Generic Target to host Msg/event handler * @context: Opaque context (HTT SOC handle) @@ -3200,7 +3886,14 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) msg_word = (u_int32_t *) qdf_nbuf_data(htt_t2h_msg); msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); + htt_event_record(soc->htt_logger_handle, + msg_type, (uint8_t *)msg_word); switch (msg_type) { + case HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND: + { + dp_htt_bkp_event_alert(msg_word, soc); + break; + } case HTT_T2H_MSG_TYPE_PEER_MAP: { u_int8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE]; @@ -3280,17 +3973,27 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) case HTT_T2H_MSG_TYPE_VERSION_CONF: { - htc_pm_runtime_put(soc->htc_soc); + /* + * HTC maintains runtime pm count for H2T messages that + * have a response msg from FW. This count ensures that + * in the case FW does not sent out the response or host + * did not process this indication runtime_put happens + * properly in the cleanup path. + */ + if (htc_dec_return_runtime_cnt(soc->htc_soc) >= 0) + htc_pm_runtime_put(soc->htc_soc); + else + soc->stats.htt_ver_req_put_skip++; soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word); soc->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW, "target uses HTT version %d.%d; host uses %d.%d", soc->tgt_ver.major, soc->tgt_ver.minor, HTT_CURRENT_VERSION_MAJOR, HTT_CURRENT_VERSION_MINOR); if (soc->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR) { QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_ERROR, + QDF_TRACE_LEVEL_WARN, "*** Incompatible host/target HTT versions!"); } /* abort if the target is incompatible with the host */ @@ -3298,7 +4001,7 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) HTT_CURRENT_VERSION_MAJOR); if (soc->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) { QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_WARN, + QDF_TRACE_LEVEL_INFO_LOW, "*** Warning: host/target HTT versions" " are different, though compatible!"); } @@ -3326,8 +4029,10 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) * using just 8 bits */ if (peer) { - status = dp_addba_requestprocess_wifi3(peer, - 0, tid, 0, win_sz + 1, 0xffff); + status = dp_addba_requestprocess_wifi3( + (struct cdp_soc_t *)soc->dp_soc, + peer->mac_addr.raw, peer->vdev->vdev_id, + 0, tid, 0, win_sz + 1, 0xffff); /* * If PEER_LOCK_REF_PROTECT enbled dec ref @@ -3362,6 +4067,10 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) u_int8_t vdev_id; bool is_wds; u_int16_t ast_hash; + struct dp_ast_flow_override_info ast_flow_info; + + qdf_mem_set(&ast_flow_info, 0, + sizeof(struct dp_ast_flow_override_info)); peer_id = HTT_RX_PEER_MAP_V2_SW_PEER_ID_GET(*msg_word); hw_peer_id = @@ -3374,6 +4083,40 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) HTT_RX_PEER_MAP_V2_NEXT_HOP_GET(*(msg_word + 3)); ast_hash = HTT_RX_PEER_MAP_V2_AST_HASH_VALUE_GET(*(msg_word + 3)); + /* + * Update 4 ast_index per peer, ast valid mask + * and TID flow valid mask. + * AST valid mask is 3 bit field corresponds to + * ast_index[3:1]. ast_index 0 is always valid. + */ + ast_flow_info.ast_valid_mask = + HTT_RX_PEER_MAP_V2_AST_VALID_MASK_GET(*(msg_word + 3)); + ast_flow_info.ast_idx[0] = hw_peer_id; + ast_flow_info.ast_flow_mask[0] = + HTT_RX_PEER_MAP_V2_AST_0_FLOW_MASK_GET(*(msg_word + 4)); + ast_flow_info.ast_idx[1] = + HTT_RX_PEER_MAP_V2_AST_INDEX_1_GET(*(msg_word + 4)); + ast_flow_info.ast_flow_mask[1] = + HTT_RX_PEER_MAP_V2_AST_1_FLOW_MASK_GET(*(msg_word + 4)); + ast_flow_info.ast_idx[2] = + HTT_RX_PEER_MAP_V2_AST_INDEX_2_GET(*(msg_word + 5)); + ast_flow_info.ast_flow_mask[2] = + HTT_RX_PEER_MAP_V2_AST_2_FLOW_MASK_GET(*(msg_word + 4)); + ast_flow_info.ast_idx[3] = + HTT_RX_PEER_MAP_V2_AST_INDEX_3_GET(*(msg_word + 6)); + ast_flow_info.ast_flow_mask[3] = + HTT_RX_PEER_MAP_V2_AST_3_FLOW_MASK_GET(*(msg_word + 4)); + /* + * TID valid mask is applicable only + * for HI and LOW priority flows. + * tid_valid_mas is 8 bit field corresponds + * to TID[7:0] + */ + ast_flow_info.tid_valid_low_pri_mask = + HTT_RX_PEER_MAP_V2_TID_VALID_LOW_PRI_GET(*(msg_word + 5)); + ast_flow_info.tid_valid_hi_pri_mask = + HTT_RX_PEER_MAP_V2_TID_VALID_HI_PRI_GET(*(msg_word + 5)); + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, "HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n", @@ -3383,6 +4126,16 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) hw_peer_id, vdev_id, peer_mac_addr, ast_hash, is_wds); + + /* + * Update ast indexes for flow override support + * Applicable only for non wds peers + */ + dp_peer_ast_index_flow_queue_map_create( + soc->dp_soc, is_wds, + peer_id, peer_mac_addr, + &ast_flow_info); + break; } case HTT_T2H_MSG_TYPE_PEER_UNMAP_V2: @@ -3532,6 +4285,8 @@ htt_htc_soc_attach(struct htt_soc *soc) soc->htc_endpoint = response.Endpoint; hif_save_htc_htt_config_endpoint(dpsoc->hif_handle, soc->htc_endpoint); + + htt_interface_logging_init(&soc->htt_logger_handle); dp_hif_update_pipe_callback(soc->dp_soc, (void *)soc, dp_htt_hif_t2h_hp_callback, DP_HTT_T2H_HP_PIPE); @@ -3549,15 +4304,17 @@ htt_htc_soc_attach(struct htt_soc *soc) * Return: HTT handle on success; NULL on failure */ void * -htt_soc_initialize(void *htt_soc, void *ctrl_psoc, HTC_HANDLE htc_soc, - void *hal_soc, qdf_device_t osdev) +htt_soc_initialize(struct htt_soc *htt_soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + HTC_HANDLE htc_soc, + hal_soc_handle_t hal_soc_hdl, qdf_device_t osdev) { struct htt_soc *soc = (struct htt_soc *)htt_soc; soc->osdev = osdev; soc->ctrl_psoc = ctrl_psoc; soc->htc_soc = htc_soc; - soc->hal_soc = hal_soc; + soc->hal_soc = hal_soc_hdl; if (htt_htc_soc_attach(soc)) goto fail2; @@ -3570,6 +4327,7 @@ htt_soc_initialize(void *htt_soc, void *ctrl_psoc, HTC_HANDLE htc_soc, void htt_soc_htc_dealloc(struct htt_soc *htt_handle) { + htt_interface_logging_deinit(htt_handle->htt_logger_handle); htt_htc_misc_pkt_pool_free(htt_handle); htt_htc_pkt_pool_free(htt_handle); } @@ -3585,8 +4343,6 @@ QDF_STATUS htt_soc_htc_prealloc(struct htt_soc *soc) { int i; - HTT_TX_MUTEX_INIT(&soc->htt_tx_mutex); - soc->htt_htc_pkt_freelist = NULL; /* pre-allocate some HTC_PACKET objects */ for (i = 0; i < HTT_HTC_PKT_POOL_INIT_SIZE; i++) { @@ -3604,12 +4360,19 @@ QDF_STATUS htt_soc_htc_prealloc(struct htt_soc *soc) * htt_soc_detach() - Free SOC level HTT handle * @htt_hdl: HTT SOC handle */ -void htt_soc_detach(void *htt_hdl) +void htt_soc_detach(struct htt_soc *htt_hdl) { + int i; struct htt_soc *htt_handle = (struct htt_soc *)htt_hdl; + for (i = 0; i < MAX_PDEV_CNT; i++) { + qdf_mem_free(htt_handle->pdevid_tt[i].umac_ttt); + qdf_mem_free(htt_handle->pdevid_tt[i].lmac_ttt); + } + HTT_TX_MUTEX_DESTROY(&htt_handle->htt_tx_mutex); qdf_mem_free(htt_handle); + } /** @@ -3635,6 +4398,10 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, qdf_nbuf_t msg; uint32_t *msg_word; uint8_t pdev_mask = 0; + uint8_t *htt_logger_bufp; + int mac_for_pdev; + int target_pdev_id; + QDF_STATUS status; msg = qdf_nbuf_alloc( soc->osdev, @@ -3650,9 +4417,11 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, * Bit 2: Pdev stats for pdev id 1 * Bit 3: Pdev stats for pdev id 2 */ - mac_id = dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); + mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); + target_pdev_id = + dp_get_target_pdev_id_for_host_pdev_id(pdev->soc, mac_for_pdev); - pdev_mask = 1 << DP_SW2HW_MACID(mac_id); + pdev_mask = 1 << target_pdev_id; /* * Set the length of the message. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added @@ -3676,6 +4445,7 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, msg_word = (uint32_t *) qdf_nbuf_data(msg); qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + htt_logger_bufp = (uint8_t *)msg_word; *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_EXT_STATS_REQ); HTT_H2T_EXT_STATS_REQ_PDEV_MASK_SET(*msg_word, pdev_mask); @@ -3734,8 +4504,15 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, HTC_TX_PACKET_TAG_RUNTIME_PUT); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); - DP_HTT_SEND_HTC_PKT(soc, pkt); - return 0; + status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_EXT_STATS_REQ, + htt_logger_bufp); + + if (status != QDF_STATUS_SUCCESS) { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; } /* This macro will revert once proper HTT header will define for @@ -3758,6 +4535,7 @@ QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, qdf_nbuf_t msg; uint32_t *msg_word; uint8_t pdev_mask; + QDF_STATUS status; msg = qdf_nbuf_alloc( soc->osdev, @@ -3777,7 +4555,8 @@ QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, * Bit 2: Pdev stats for pdev id 1 * Bit 3: Pdev stats for pdev id 2 */ - pdev_mask = 1 << DP_SW2HW_MACID(mac_id); + pdev_mask = 1 << dp_get_target_pdev_id_for_host_pdev_id(pdev->soc, + mac_id); /* * Set the length of the message. @@ -3816,11 +4595,19 @@ QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg), qdf_nbuf_len(msg), soc->htc_endpoint, - 1); /* tag - not relevant here */ + /* tag for no FW response msg */ + HTC_TX_PACKET_TAG_RUNTIME_PUT); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); - DP_HTT_SEND_HTC_PKT(soc, pkt); - return 0; + status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_PPDU_STATS_CFG, + (uint8_t *)msg_word); + + if (status != QDF_STATUS_SUCCESS) { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; } #endif @@ -3858,3 +4645,404 @@ dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, qdf_err("Invalid tag_type"); } } + +/** + * dp_htt_rx_flow_fst_setup(): Send HTT Rx FST setup message to FW + * @pdev: DP pdev handle + * @fse_setup_info: FST setup parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev, + struct dp_htt_rx_flow_fst_setup *fse_setup_info) +{ + struct htt_soc *soc = pdev->soc->htt_handle; + struct dp_htt_htc_pkt *pkt; + qdf_nbuf_t msg; + u_int32_t *msg_word; + struct htt_h2t_msg_rx_fse_setup_t *fse_setup; + uint8_t *htt_logger_bufp; + u_int32_t *key; + QDF_STATUS status; + + msg = qdf_nbuf_alloc( + soc->osdev, + HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_rx_fse_setup_t)), + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + + if (!msg) + return QDF_STATUS_E_NOMEM; + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to qdf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + if (!qdf_nbuf_put_tail(msg, + sizeof(struct htt_h2t_msg_rx_fse_setup_t))) { + qdf_err("Failed to expand head for HTT RX_FSE_SETUP msg"); + return QDF_STATUS_E_FAILURE; + } + + /* fill in the message contents */ + msg_word = (u_int32_t *)qdf_nbuf_data(msg); + + memset(msg_word, 0, sizeof(struct htt_h2t_msg_rx_fse_setup_t)); + /* rewind beyond alignment pad to get to the HTC header reserved area */ + qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + htt_logger_bufp = (uint8_t *)msg_word; + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG); + + fse_setup = (struct htt_h2t_msg_rx_fse_setup_t *)msg_word; + + HTT_RX_FSE_SETUP_PDEV_ID_SET(*msg_word, fse_setup_info->pdev_id); + + msg_word++; + HTT_RX_FSE_SETUP_NUM_REC_SET(*msg_word, fse_setup_info->max_entries); + HTT_RX_FSE_SETUP_MAX_SEARCH_SET(*msg_word, fse_setup_info->max_search); + HTT_RX_FSE_SETUP_IP_DA_SA_PREFIX_SET(*msg_word, + fse_setup_info->ip_da_sa_prefix); + + msg_word++; + HTT_RX_FSE_SETUP_BASE_ADDR_LO_SET(*msg_word, + fse_setup_info->base_addr_lo); + msg_word++; + HTT_RX_FSE_SETUP_BASE_ADDR_HI_SET(*msg_word, + fse_setup_info->base_addr_hi); + + key = (u_int32_t *)fse_setup_info->hash_key; + fse_setup->toeplitz31_0 = *key++; + fse_setup->toeplitz63_32 = *key++; + fse_setup->toeplitz95_64 = *key++; + fse_setup->toeplitz127_96 = *key++; + fse_setup->toeplitz159_128 = *key++; + fse_setup->toeplitz191_160 = *key++; + fse_setup->toeplitz223_192 = *key++; + fse_setup->toeplitz255_224 = *key++; + fse_setup->toeplitz287_256 = *key++; + fse_setup->toeplitz314_288 = *key; + + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz31_0); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz63_32); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz95_64); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz127_96); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz159_128); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz191_160); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz223_192); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz255_224); + msg_word++; + HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz287_256); + msg_word++; + HTT_RX_FSE_SETUP_HASH_314_288_SET(*msg_word, + fse_setup->toeplitz314_288); + + pkt = htt_htc_pkt_alloc(soc); + if (!pkt) { + qdf_err("Fail to allocate dp_htt_htc_pkt buffer"); + qdf_assert(0); + qdf_nbuf_free(msg); + return QDF_STATUS_E_RESOURCES; /* failure */ + } + + pkt->soc_ctxt = NULL; /* not used during send-done callback */ + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + dp_htt_h2t_send_complete_free_netbuf, + qdf_nbuf_data(msg), + qdf_nbuf_len(msg), + soc->htc_endpoint, + HTC_TX_PACKET_TAG_RUNTIME_PUT); + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + + status = DP_HTT_SEND_HTC_PKT(soc, pkt, + HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG, + htt_logger_bufp); + + if (status == QDF_STATUS_SUCCESS) { + dp_info("HTT_H2T RX_FSE_SETUP sent to FW for pdev = %u", + fse_setup_info->pdev_id); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, + (void *)fse_setup_info->hash_key, + fse_setup_info->hash_key_len); + } else { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; +} + +/** + * dp_htt_rx_flow_fse_operation(): Send HTT Flow Search Entry msg to + * add/del a flow in HW + * @pdev: DP pdev handle + * @fse_op_info: Flow entry parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev, + struct dp_htt_rx_flow_fst_operation *fse_op_info) +{ + struct htt_soc *soc = pdev->soc->htt_handle; + struct dp_htt_htc_pkt *pkt; + qdf_nbuf_t msg; + u_int32_t *msg_word; + struct htt_h2t_msg_rx_fse_operation_t *fse_operation; + uint8_t *htt_logger_bufp; + QDF_STATUS status; + + msg = qdf_nbuf_alloc( + soc->osdev, + HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_rx_fse_operation_t)), + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + if (!msg) + return QDF_STATUS_E_NOMEM; + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to qdf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + if (!qdf_nbuf_put_tail(msg, + sizeof(struct htt_h2t_msg_rx_fse_operation_t))) { + qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg"); + qdf_nbuf_free(msg); + return QDF_STATUS_E_FAILURE; + } + + /* fill in the message contents */ + msg_word = (u_int32_t *)qdf_nbuf_data(msg); + + memset(msg_word, 0, sizeof(struct htt_h2t_msg_rx_fse_operation_t)); + /* rewind beyond alignment pad to get to the HTC header reserved area */ + qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + htt_logger_bufp = (uint8_t *)msg_word; + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG); + + fse_operation = (struct htt_h2t_msg_rx_fse_operation_t *)msg_word; + + HTT_RX_FSE_OPERATION_PDEV_ID_SET(*msg_word, fse_op_info->pdev_id); + msg_word++; + HTT_RX_FSE_IPSEC_VALID_SET(*msg_word, false); + if (fse_op_info->op_code == DP_HTT_FST_CACHE_INVALIDATE_ENTRY) { + HTT_RX_FSE_OPERATION_SET(*msg_word, + HTT_RX_FSE_CACHE_INVALIDATE_ENTRY); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_31_0)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_63_32)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_95_64)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_127_96)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_31_0)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_63_32)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_95_64)); + msg_word++; + HTT_RX_FSE_OPERATION_IP_ADDR_SET( + *msg_word, + qdf_htonl( + fse_op_info->rx_flow->flow_tuple_info.dest_ip_127_96)); + msg_word++; + HTT_RX_FSE_SOURCEPORT_SET( + *msg_word, + fse_op_info->rx_flow->flow_tuple_info.src_port); + HTT_RX_FSE_DESTPORT_SET( + *msg_word, + fse_op_info->rx_flow->flow_tuple_info.dest_port); + msg_word++; + HTT_RX_FSE_L4_PROTO_SET( + *msg_word, + fse_op_info->rx_flow->flow_tuple_info.l4_protocol); + } else if (fse_op_info->op_code == DP_HTT_FST_CACHE_INVALIDATE_FULL) { + HTT_RX_FSE_OPERATION_SET(*msg_word, + HTT_RX_FSE_CACHE_INVALIDATE_FULL); + } else if (fse_op_info->op_code == DP_HTT_FST_DISABLE) { + HTT_RX_FSE_OPERATION_SET(*msg_word, HTT_RX_FSE_DISABLE); + } else if (fse_op_info->op_code == DP_HTT_FST_ENABLE) { + HTT_RX_FSE_OPERATION_SET(*msg_word, HTT_RX_FSE_ENABLE); + } + + pkt = htt_htc_pkt_alloc(soc); + if (!pkt) { + qdf_err("Fail to allocate dp_htt_htc_pkt buffer"); + qdf_assert(0); + qdf_nbuf_free(msg); + return QDF_STATUS_E_RESOURCES; /* failure */ + } + + pkt->soc_ctxt = NULL; /* not used during send-done callback */ + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + dp_htt_h2t_send_complete_free_netbuf, + qdf_nbuf_data(msg), + qdf_nbuf_len(msg), + soc->htc_endpoint, + HTC_TX_PACKET_TAG_RUNTIME_PUT); + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + + status = DP_HTT_SEND_HTC_PKT(soc, pkt, + HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG, + htt_logger_bufp); + + if (status == QDF_STATUS_SUCCESS) { + dp_info("HTT_H2T RX_FSE_OPERATION_CFG sent to FW for pdev = %u", + fse_op_info->pdev_id); + } else { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; +} + +/** + * dp_htt_rx_fisa_config(): Send HTT msg to configure FISA + * @pdev: DP pdev handle + * @fse_op_info: Flow entry parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_fisa_config(struct dp_pdev *pdev, + struct dp_htt_rx_fisa_cfg *fisa_config) +{ + struct htt_soc *soc = pdev->soc->htt_handle; + struct dp_htt_htc_pkt *pkt; + qdf_nbuf_t msg; + u_int32_t *msg_word; + struct htt_h2t_msg_type_fisa_config_t *htt_fisa_config; + uint8_t *htt_logger_bufp; + uint32_t len; + QDF_STATUS status; + + len = HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_type_fisa_config_t)); + + msg = qdf_nbuf_alloc(soc->osdev, + len, + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, + 4, + TRUE); + if (!msg) + return QDF_STATUS_E_NOMEM; + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to qdf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + if (!qdf_nbuf_put_tail(msg, + sizeof(struct htt_h2t_msg_type_fisa_config_t))) { + qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg"); + qdf_nbuf_free(msg); + return QDF_STATUS_E_FAILURE; + } + + /* fill in the message contents */ + msg_word = (u_int32_t *)qdf_nbuf_data(msg); + + memset(msg_word, 0, sizeof(struct htt_h2t_msg_type_fisa_config_t)); + /* rewind beyond alignment pad to get to the HTC header reserved area */ + qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + htt_logger_bufp = (uint8_t *)msg_word; + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FISA_CFG); + + htt_fisa_config = (struct htt_h2t_msg_type_fisa_config_t *)msg_word; + + HTT_RX_FSE_OPERATION_PDEV_ID_SET(*msg_word, htt_fisa_config->pdev_id); + + msg_word++; + HTT_RX_FISA_CONFIG_FISA_ENABLE_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_IPSEC_SKIP_SEARCH_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_NON_TCP_SKIP_SEARCH_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_IPV4_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_IPV6_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_TCP_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_UDP_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_CHKSUM_CUM_IP_LEN_EN_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_TID_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_TA_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_QOS_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_RAW_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_DECRYPT_ERR_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_MSDU_DROP_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_FISA_AGGR_LIMIT_SET(*msg_word, 0xf); + + msg_word++; + htt_fisa_config->fisa_timeout_threshold = fisa_config->fisa_timeout; + + pkt = htt_htc_pkt_alloc(soc); + if (!pkt) { + qdf_err("Fail to allocate dp_htt_htc_pkt buffer"); + qdf_assert(0); + qdf_nbuf_free(msg); + return QDF_STATUS_E_RESOURCES; /* failure */ + } + + pkt->soc_ctxt = NULL; /* not used during send-done callback */ + + SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt, + dp_htt_h2t_send_complete_free_netbuf, + qdf_nbuf_data(msg), + qdf_nbuf_len(msg), + soc->htc_endpoint, + HTC_TX_PACKET_TAG_RUNTIME_PUT); + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + + status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_RX_FISA_CFG, + htt_logger_bufp); + + if (status == QDF_STATUS_SUCCESS) { + dp_info("HTT_H2T_MSG_TYPE_RX_FISA_CFG sent to FW for pdev = %u", + fisa_config->pdev_id); + } else { + qdf_nbuf_free(msg); + htt_htc_pkt_free(soc, pkt); + } + + return status; +} diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h index 09d7d7c71e6447a9be487431da695c1df4cbbae9..6843904df22655e9a5e9c72e3a7991dd6e8f2754 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,42 @@ #include "cdp_txrx_cmn_struct.h" #include "dp_types.h" +#ifdef HTT_LOGGER +#include "dp_htt_logger.h" +#else +struct htt_logger; +static inline +void htt_interface_logging_init(struct htt_logger **htt_logger_handle) +{ +} + +static inline +void htt_interface_logging_deinit(struct htt_logger *htt_logger_handle) +{ +} + +static inline +int htt_command_record(struct htt_logger *h, uint8_t msg_type, + uint8_t *msg_data) +{ + return 0; +} + +static inline +int htt_event_record(struct htt_logger *h, uint8_t msg_type, + uint8_t *msg_data) +{ + return 0; +} + +static inline +int htt_wbm_event_record(struct htt_logger *h, uint8_t tx_status, + uint8_t *msg_data) +{ + return 0; +} + +#endif #define HTT_TX_MUTEX_TYPE qdf_spinlock_t @@ -62,7 +98,7 @@ #define HTT_RX_DELBA_WIN_SIZE_M 0x0000FC00 #define HTT_RX_DELBA_WIN_SIZE_S 10 -#define HTT_RX_DELBA_WIN_SIZE_GET(word) \ +#define HTT_RX_DELBA_WIN_SIZE_GET(word) \ (((word) & HTT_RX_DELBA_WIN_SIZE_M) >> HTT_RX_DELBA_WIN_SIZE_S) /* @@ -75,6 +111,30 @@ #define HTT_T2H_EXT_STATS_TLV_START_OFFSET 3 +/* + * Below offset are based on htt_ppdu_stats_common_tlv + * defined in htt_ppdu_stats.h + */ +#define HTT_PPDU_STATS_COMMON_TLV_TLV_HDR_OFFSET 0 +#define HTT_PPDU_STATS_COMMON_TLV_PPDU_ID_OFFSET 1 +#define HTT_PPDU_STATS_COMMON_TLV_RING_ID_SCH_CMD_ID_OFFSET 2 +#define HTT_PPDU_STATS_COMMON_TLV_QTYPE_FRM_TYPE_OFFSET 3 +#define HTT_PPDU_STATS_COMMON_TLV_CHAIN_MASK_OFFSET 4 +#define HTT_PPDU_STATS_COMMON_TLV_FES_DUR_US_OFFSET 5 +#define HTT_PPDU_STATS_COMMON_TLV_SCH_EVAL_START_TSTMP_L32_US_OFFSET 6 +#define HTT_PPDU_STATS_COMMON_TLV_SCH_END_TSTMP_US_OFFSET 7 +#define HTT_PPDU_STATS_COMMON_TLV_START_TSTMP_L32_US_OFFSET 8 +#define HTT_PPDU_STATS_COMMON_TLV_CHAN_MHZ_PHY_MODE_OFFSET 9 +#define HTT_PPDU_STATS_COMMON_TLV_CCA_DELTA_TIME_US_OFFSET 10 +#define HTT_PPDU_STATS_COMMON_TLV_RXFRM_DELTA_TIME_US_OFFSET 11 +#define HTT_PPDU_STATS_COMMON_TLV_TXFRM_DELTA_TIME_US_OFFSET 12 +#define HTT_PPDU_STATS_COMMON_TLV_RESV_NUM_UL_BEAM_OFFSET 13 +#define HTT_PPDU_STATS_COMMON_TLV_START_TSTMP_U32_US_OFFSET 14 + +/* get index for field in htt_ppdu_stats_common_tlv */ +#define HTT_GET_STATS_CMN_INDEX(index) \ + HTT_PPDU_STATS_COMMON_TLV_##index##_OFFSET + struct dp_htt_htc_pkt { void *soc_ctxt; qdf_dma_addr_t nbuf_paddr; @@ -88,10 +148,18 @@ struct dp_htt_htc_pkt_union { } u; }; +struct dp_htt_timestamp { + long *umac_ttt; + long *lmac_ttt; +}; + struct htt_soc { - void *ctrl_psoc; - void *dp_soc; - void *hal_soc; + struct cdp_ctrl_objmgr_psoc *ctrl_psoc; + struct dp_soc *dp_soc; + hal_soc_handle_t hal_soc; + struct dp_htt_timestamp pdevid_tt[MAX_PDEV_CNT]; + /* htt_logger handle */ + struct htt_logger *htt_logger_handle; HTC_HANDLE htc_soc; qdf_device_t osdev; HTC_ENDPOINT_ID htc_endpoint; @@ -109,6 +177,8 @@ struct htt_soc { struct { int htc_err_cnt; int htc_pkt_free; + /* rtpm put skip count for ver req msg */ + int htt_ver_req_put_skip; } stats; HTT_TX_MUTEX_TYPE htt_tx_mutex; @@ -143,6 +213,8 @@ struct htt_soc { * @rx_msdu_end_offset: Offset of rx_msdu_end tlv * @rx_msdu_start_offset: Offset of rx_msdu_start tlv * @rx_attn_offset: Offset of rx_attention tlv + * + * NOTE: Do not change the layout of this structure */ struct htt_rx_ring_tlv_filter { u_int32_t mpdu_start:1, @@ -180,6 +252,69 @@ struct htt_rx_ring_tlv_filter { uint16_t rx_attn_offset; }; +/** + * struct dp_htt_rx_flow_fst_setup - Rx FST setup message + * @pdev_id: DP Pdev identifier + * @max_entries: Size of Rx FST in number of entries + * @max_search: Number of collisions allowed + * @base_addr_lo: lower 32-bit physical address + * @base_addr_hi: upper 32-bit physical address + * @ip_da_sa_prefix: IPv4 prefix to map to IPv6 address scheme + * @hash_key_len: Rx FST hash key size + * @hash_key: Rx FST Toeplitz hash key + */ +struct dp_htt_rx_flow_fst_setup { + uint8_t pdev_id; + uint32_t max_entries; + uint32_t max_search; + uint32_t base_addr_lo; + uint32_t base_addr_hi; + uint32_t ip_da_sa_prefix; + uint32_t hash_key_len; + uint8_t *hash_key; +}; + +/** + * enum dp_htt_flow_fst_operation - FST related operations allowed + * @DP_HTT_FST_CACHE_OP_NONE: Cache no-op + * @DP_HTT_FST_CACHE_INVALIDATE_ENTRY: Invalidate single cache entry + * @DP_HTT_FST_CACHE_INVALIDATE_FULL: Invalidate entire cache + * @DP_HTT_FST_ENABLE: Bypass FST is enabled + * @DP_HTT_FST_DISABLE: Disable bypass FST + */ +enum dp_htt_flow_fst_operation { + DP_HTT_FST_CACHE_OP_NONE, + DP_HTT_FST_CACHE_INVALIDATE_ENTRY, + DP_HTT_FST_CACHE_INVALIDATE_FULL, + DP_HTT_FST_ENABLE, + DP_HTT_FST_DISABLE +}; + +/** + * struct dp_htt_rx_flow_fst_setup - Rx FST setup message + * @pdev_id: DP Pdev identifier + * @op_code: FST operation to be performed by FW/HW + * @rx_flow: Rx Flow information on which operation is to be performed + */ +struct dp_htt_rx_flow_fst_operation { + uint8_t pdev_id; + enum dp_htt_flow_fst_operation op_code; + struct cdp_rx_flow_info *rx_flow; +}; + +/** + * struct dp_htt_rx_fisa_config - Rx fisa config + * @pdev_id: DP Pdev identifier + * @fisa_timeout: fisa aggregation timeout + */ +struct dp_htt_rx_fisa_cfg { + uint8_t pdev_id; + uint32_t fisa_timeout; +}; + +QDF_STATUS dp_htt_rx_fisa_config(struct dp_pdev *pdev, + struct dp_htt_rx_fisa_cfg *fisa_config); + /* * htt_soc_initialize() - SOC level HTT initialization * @htt_soc: Opaque htt SOC handle @@ -191,8 +326,36 @@ struct htt_rx_ring_tlv_filter { * Return: HTT handle on success; NULL on failure */ void * -htt_soc_initialize(void *htt_soc, void *ctrl_psoc, HTC_HANDLE htc_soc, - void *hal_soc, qdf_device_t osdev); +htt_soc_initialize(struct htt_soc *htt_soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + HTC_HANDLE htc_soc, + hal_soc_handle_t hal_soc_hdl, qdf_device_t osdev); + +/* + * htt_soc_attach() - attach DP and HTT SOC + * @soc: DP SOC handle + * @htc_hdl: HTC handle + * + * Return: htt_soc handle on Success, NULL on Failure + */ +struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_hdl); + +/* + * htt_set_htc_handle_() - set HTC handle + * @htt_hdl: HTT handle/SOC + * @htc_soc: HTC handle + * + * Return: None + */ +void htt_set_htc_handle(struct htt_soc *htt_hdl, HTC_HANDLE htc_soc); + +/* + * htt_get_htc_handle_() - set HTC handle + * @htt_hdl: HTT handle/SOC + * + * Return: HTC_HANDLE + */ +HTC_HANDLE htt_get_htc_handle(struct htt_soc *htt_hdl); /* * htt_soc_htc_dealloc() - HTC memory de-alloc @@ -211,12 +374,13 @@ void htt_soc_htc_dealloc(struct htt_soc *htt_handle); */ QDF_STATUS htt_soc_htc_prealloc(struct htt_soc *htt_soc); -void htt_soc_detach(void *soc); +void htt_soc_detach(struct htt_soc *soc); -int htt_srng_setup(void *htt_soc, int pdev_id, void *hal_srng, - int hal_ring_type); +int htt_srng_setup(struct htt_soc *htt_soc, int pdev_id, + hal_ring_handle_t hal_ring_hdl, + int hal_ring_type); -int htt_soc_attach_target(void *htt_soc); +int htt_soc_attach_target(struct htt_soc *htt_soc); /* * htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter @@ -230,9 +394,10 @@ int htt_soc_attach_target(void *htt_soc); * * Return: 0 on success; error code on failure */ -int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, - int hal_ring_type, int ring_buf_size, - struct htt_rx_ring_tlv_filter *htt_tlv_filter); +int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id, + hal_ring_handle_t hal_ring_hdl, + int hal_ring_type, int ring_buf_size, + struct htt_rx_ring_tlv_filter *htt_tlv_filter); /* * htt_t2h_stats_handler() - target to host stats work handler @@ -268,4 +433,26 @@ void dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, struct ppdu_info *ppdu_info); +/** + * dp_htt_rx_flow_fst_setup(): Send HTT Rx FST setup message to FW + * @pdev: DP pdev handle + * @fse_setup_info: FST setup parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev, + struct dp_htt_rx_flow_fst_setup *setup_info); + +/** + * dp_htt_rx_flow_fse_operation(): Send HTT Flow Search Entry msg to + * add/del a flow in HW + * @pdev: DP pdev handle + * @fse_op_info: Flow entry parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev, + struct dp_htt_rx_flow_fst_operation *op_info); #endif /* _DP_HTT_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h index 495fb647e87726abda99bf3ff93a31aa0b17aea6..69e821a5e4b658095752e3426248bbeee186d2be 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,8 +22,11 @@ #include "dp_types.h" #define RX_BUFFER_SIZE_PKTLOG_LITE 1024 +/* Alignment for consistent memory for DP rings*/ +#define DP_RING_BASE_ALIGN 8 +#define DP_RSSI_INVAL 0x80 #define DP_RSSI_AVG_WEIGHT 2 /* * Formula to derive avg_rssi is taken from wifi2.o firmware @@ -62,6 +65,21 @@ (1 << HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV) | \ (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) +/** + * Bitmap of HTT PPDU delayed ba TLV types for Default mode + */ +#define HTT_PPDU_DELAYED_BA_TLV_BITMAP \ + (1 << HTT_PPDU_STATS_COMMON_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMMON_TLV) | \ + (1 << HTT_PPDU_STATS_USR_RATE_TLV) + +/** + * Bitmap of HTT PPDU TLV types for Delayed BA + */ +#define HTT_PPDU_STATUS_TLV_BITMAP \ + (1 << HTT_PPDU_STATS_COMMON_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) + /** * Bitmap of HTT PPDU TLV types for Sniffer mode bitmap 64 */ @@ -90,7 +108,7 @@ #ifdef WLAN_TX_PKT_CAPTURE_ENH extern uint8_t -dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS]; +dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS_MAX]; #endif #define DP_MAX_TIMER_EXEC_TIME_TICKS \ @@ -147,7 +165,7 @@ while (0) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_##LVL, \ fmt, ## args) -#ifdef CONFIG_MCL +#ifdef DP_PRINT_NO_CONSOLE /* Stat prints should not go to console or kernel logs.*/ #define DP_PRINT_STATS(fmt, args ...)\ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, \ @@ -315,7 +333,6 @@ while (0) } \ } while (0) - #else #define DP_HIST_INIT() #define DP_HIST_PACKET_COUNT_INC(_pdev_id) @@ -323,7 +340,134 @@ while (0) #define DP_RX_HISTOGRAM_UPDATE(_pdev, _p_cntrs) #define DP_RX_HIST_STATS_PER_PDEV() #define DP_TX_HIST_STATS_PER_PDEV() -#endif +#endif /* DISABLE_DP_STATS */ + +#ifdef FEATURE_TSO_STATS +/** + * dp_init_tso_stats() - Clear tso stats + * @pdev: pdev handle + * + * Return: None + */ +static inline +void dp_init_tso_stats(struct dp_pdev *pdev) +{ + if (pdev) { + qdf_mem_zero(&((pdev)->stats.tso_stats), + sizeof((pdev)->stats.tso_stats)); + qdf_atomic_init(&pdev->tso_idx); + } +} + +/** + * dp_stats_tso_segment_histogram_update() - TSO Segment Histogram + * @pdev: pdev handle + * @_p_cntrs: number of tso segments for a tso packet + * + * Return: None + */ +void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev, + uint8_t _p_cntrs); + +/** + * dp_tso_segment_update() - Collect tso segment information + * @pdev: pdev handle + * @stats_idx: tso packet number + * @idx: tso segment number + * @seg: tso segment + * + * Return: None + */ +void dp_tso_segment_update(struct dp_pdev *pdev, + uint32_t stats_idx, + uint8_t idx, + struct qdf_tso_seg_t seg); + +/** + * dp_tso_packet_update() - TSO Packet information + * @pdev: pdev handle + * @stats_idx: tso packet number + * @msdu: nbuf handle + * @num_segs: tso segments + * + * Return: None + */ +void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx, + qdf_nbuf_t msdu, uint16_t num_segs); + +/** + * dp_tso_segment_stats_update() - TSO Segment stats + * @pdev: pdev handle + * @stats_seg: tso segment list + * @stats_idx: tso packet number + * + * Return: None + */ +void dp_tso_segment_stats_update(struct dp_pdev *pdev, + struct qdf_tso_seg_elem_t *stats_seg, + uint32_t stats_idx); + +/** + * dp_print_tso_stats() - dump tso statistics + * @soc:soc handle + * @level: verbosity level + * + * Return: None + */ +void dp_print_tso_stats(struct dp_soc *soc, + enum qdf_stats_verbosity_level level); + +/** + * dp_txrx_clear_tso_stats() - clear tso stats + * @soc: soc handle + * + * Return: None + */ +void dp_txrx_clear_tso_stats(struct dp_soc *soc); +#else +static inline +void dp_init_tso_stats(struct dp_pdev *pdev) +{ +} + +static inline +void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev, + uint8_t _p_cntrs) +{ +} + +static inline +void dp_tso_segment_update(struct dp_pdev *pdev, + uint32_t stats_idx, + uint32_t idx, + struct qdf_tso_seg_t seg) +{ +} + +static inline +void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx, + qdf_nbuf_t msdu, uint16_t num_segs) +{ +} + +static inline +void dp_tso_segment_stats_update(struct dp_pdev *pdev, + struct qdf_tso_seg_elem_t *stats_seg, + uint32_t stats_idx) +{ +} + +static inline +void dp_print_tso_stats(struct dp_soc *soc, + enum qdf_stats_verbosity_level level) +{ +} + +static inline +void dp_txrx_clear_tso_stats(struct dp_soc *soc) +{ +} +#endif /* FEATURE_TSO_STATS */ #define DP_HTT_T2H_HP_PIPE 5 static inline void dp_update_pdev_stats(struct dp_pdev *tgtobj, @@ -465,6 +609,8 @@ static inline void dp_update_pdev_stats(struct dp_pdev *tgtobj, srcobj->tx.last_ack_rssi; tgtobj->stats.rx.mec_drop.num += srcobj->rx.mec_drop.num; tgtobj->stats.rx.mec_drop.bytes += srcobj->rx.mec_drop.bytes; + tgtobj->stats.rx.multipass_rx_pkt_drop += + srcobj->rx.multipass_rx_pkt_drop; } static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, @@ -478,10 +624,6 @@ static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.inspect_pkts); DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.raw.raw_pkt); DP_STATS_AGGR(tgtobj, srcobj, tx_i.raw.dma_map_error); - DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.tso.tso_pkt); - DP_STATS_AGGR(tgtobj, srcobj, tx_i.tso.dropped_host.num); - DP_STATS_AGGR(tgtobj, srcobj, tx_i.tso.tso_no_mem_dropped.num); - DP_STATS_AGGR(tgtobj, srcobj, tx_i.tso.dropped_target); DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_host.num); DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_target); DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sg.sg_pkt); @@ -512,8 +654,6 @@ static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, tgtobj->stats.tx_i.dropped.desc_na.num + tgtobj->stats.tx_i.dropped.res_full; - tgtobj->stats.tx_i.tso.num_seg = - srcobj->stats.tx_i.tso.num_seg; } static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj, @@ -654,6 +794,8 @@ static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj, srcobj->stats.tx.last_ack_rssi; tgtobj->rx.mec_drop.num += srcobj->stats.rx.mec_drop.num; tgtobj->rx.mec_drop.bytes += srcobj->stats.rx.mec_drop.bytes; + tgtobj->rx.multipass_rx_pkt_drop += + srcobj->stats.rx.multipass_rx_pkt_drop; } #define DP_UPDATE_STATS(_tgtobj, _srcobj) \ @@ -748,6 +890,7 @@ static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj, \ _tgtobj->stats.tx.last_ack_rssi = \ _srcobj->stats.tx.last_ack_rssi; \ + DP_STATS_AGGR(_tgtobj, _srcobj, rx.multipass_rx_pkt_drop); \ } while (0) extern int dp_peer_find_attach(struct dp_soc *soc); @@ -755,43 +898,163 @@ extern void dp_peer_find_detach(struct dp_soc *soc); extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer); extern void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer); extern void dp_peer_find_hash_erase(struct dp_soc *soc); + +/* + * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer + * @peer: Datapath peer + * + * return: void + */ +void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer); + +/* + * dp_peer_ppdu_delayed_ba_cleanup() free ppdu allocated in peer + * @peer: Datapath peer + * + * return: void + */ +void dp_peer_ppdu_delayed_ba_cleanup(struct dp_peer *peer); + extern void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer); void dp_peer_tx_init(struct dp_pdev *pdev, struct dp_peer *peer); void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer, bool reuse); void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer, bool reuse); -extern void dp_peer_unref_delete(void *peer_handle); -extern void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer, - unsigned tid, qdf_nbuf_t msdu_list); +void dp_peer_unref_delete(struct dp_peer *peer); extern void *dp_find_peer_by_addr(struct cdp_pdev *dev, - uint8_t *peer_mac_addr, uint8_t *peer_id); + uint8_t *peer_mac_addr); extern struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id); -#ifndef CONFIG_WIN -QDF_STATUS dp_register_peer(struct cdp_pdev *pdev_handle, - struct ol_txrx_desc_type *sta_desc); -QDF_STATUS dp_clear_peer(struct cdp_pdev *pdev_handle, uint8_t local_id); +#ifdef DP_PEER_EXTENDED_API +/** + * dp_register_peer() - Register peer into physical device + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @sta_desc - peer description + * + * Register peer into physical device + * + * Return: QDF_STATUS_SUCCESS registration success + * QDF_STATUS_E_FAULT peer not found + */ +QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct ol_txrx_desc_type *sta_desc); + +/** + * dp_clear_peer() - remove peer from physical device + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @peer_addr - peer mac address + * + * remove peer from physical device + * + * Return: QDF_STATUS_SUCCESS registration success + * QDF_STATUS_E_FAULT peer not found + */ +QDF_STATUS dp_clear_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr); + +/* + * dp_find_peer_exist - find peer if already exists + * @soc: datapath soc handle + * @pdev_id: physical device instance id + * @peer_mac_addr: peer mac address + * + * Return: true or false + */ +bool dp_find_peer_exist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t *peer_addr); + +/* + * dp_find_peer_exist_on_vdev - find if peer exists on the given vdev + * @soc: datapath soc handle + * @vdev_id: vdev instance id + * @peer_mac_addr: peer mac address + * + * Return: true or false + */ +bool dp_find_peer_exist_on_vdev(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_addr); + +/* + * dp_find_peer_exist_on_other_vdev - find if peer exists + * on other than the given vdev + * @soc: datapath soc handle + * @vdev_id: vdev instance id + * @peer_mac_addr: peer mac address + * @max_bssid: max number of bssids + * + * Return: true or false + */ +bool dp_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_addr, + uint16_t max_bssid); + void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, struct cdp_vdev *vdev, - uint8_t *peer_addr, uint8_t *local_id); -uint16_t dp_local_peer_id(void *peer); -void *dp_peer_find_by_local_id(struct cdp_pdev *pdev_handle, uint8_t local_id); -QDF_STATUS dp_peer_state_update(struct cdp_pdev *pdev_handle, uint8_t *peer_mac, - enum ol_txrx_peer_state state); -QDF_STATUS dp_get_vdevid(void *peer_handle, uint8_t *vdev_id); -struct cdp_vdev *dp_get_vdev_by_sta_id(struct cdp_pdev *pdev_handle, - uint8_t sta_id); + uint8_t *peer_addr); + +/** + * dp_peer_state_update() - update peer local state + * @pdev - data path device instance + * @peer_addr - peer mac address + * @state - new peer local state + * + * update peer local state + * + * Return: QDF_STATUS_SUCCESS registration success + */ +QDF_STATUS dp_peer_state_update(struct cdp_soc_t *soc, uint8_t *peer_mac, + enum ol_txrx_peer_state state); + +/** + * dp_get_vdevid() - Get virtual interface id which peer registered + * @soc - datapath soc handle + * @peer_mac - peer mac address + * @vdev_id - virtual interface id which peer registered + * + * Get virtual interface id which peer registered + * + * Return: QDF_STATUS_SUCCESS registration success + */ +QDF_STATUS dp_get_vdevid(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t *vdev_id); +struct cdp_vdev *dp_get_vdev_by_peer_addr(struct cdp_pdev *pdev_handle, + struct qdf_mac_addr peer_addr); struct cdp_vdev *dp_get_vdev_for_peer(void *peer); uint8_t *dp_peer_get_peer_mac_addr(void *peer); -int dp_get_peer_state(void *peer_handle); + +/** + * dp_get_peer_state() - Get local peer state + * @soc - datapath soc handle + * @vdev_id - vdev id + * @peer_mac - peer mac addr + * + * Get local peer state + * + * Return: peer status + */ +int dp_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac); void dp_local_peer_id_pool_init(struct dp_pdev *pdev); void dp_local_peer_id_alloc(struct dp_pdev *pdev, struct dp_peer *peer); void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer); #else +/** + * dp_get_vdevid() - Get virtual interface id which peer registered + * @soc - datapath soc handle + * @peer_mac - peer mac address + * @vdev_id - virtual interface id which peer registered + * + * Get virtual interface id which peer registered + * + * Return: QDF_STATUS_SUCCESS registration success + */ static inline -QDF_STATUS dp_get_vdevid(void *peer_handle, uint8_t *vdev_id) +QDF_STATUS dp_get_vdevid(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t *vdev_id) { return QDF_STATUS_E_NOSUPPORT; } @@ -810,30 +1073,44 @@ void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer) { } #endif -int dp_addba_resp_tx_completion_wifi3(void *peer_handle, uint8_t tid, - int status); -extern int dp_addba_requestprocess_wifi3(void *peer_handle, - uint8_t dialogtoken, uint16_t tid, uint16_t batimeout, - uint16_t buffersize, uint16_t startseqnum); -extern void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid, - uint8_t *dialogtoken, uint16_t *statuscode, - uint16_t *buffersize, uint16_t *batimeout); -extern void dp_set_addba_response(void *peer_handle, uint8_t tid, - uint16_t statuscode); -extern int dp_delba_process_wifi3(void *peer_handle, - int tid, uint16_t reasoncode); +int dp_addba_resp_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, uint16_t vdev_id, + uint8_t tid, + int status); +int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, uint16_t vdev_id, + uint8_t dialogtoken, uint16_t tid, + uint16_t batimeout, + uint16_t buffersize, + uint16_t startseqnum); +QDF_STATUS dp_addba_responsesetup_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, uint16_t vdev_id, + uint8_t tid, uint8_t *dialogtoken, + uint16_t *statuscode, + uint16_t *buffersize, + uint16_t *batimeout); +QDF_STATUS dp_set_addba_response(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, + uint16_t statuscode); +int dp_delba_process_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, int tid, + uint16_t reasoncode); /* * dp_delba_tx_completion_wifi3() - Handle delba tx completion * - * @peer_handle: Peer handle + * @cdp_soc: soc handle + * @vdev_id: id of the vdev handle + * @peer_mac: peer mac address * @tid: Tid number * @status: Tx completion status * Indicate status of delba Tx to DP for stats update and retry * delba if tx failed. * */ -int dp_delba_tx_completion_wifi3(void *peer_handle, uint8_t tid, - int status); +int dp_delba_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, + int status); extern QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, uint32_t ba_window_size, uint32_t start_seq); @@ -859,37 +1136,46 @@ void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); void dp_rx_bar_stats_cb(struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); -uint16_t dp_tx_me_send_convert_ucast(struct cdp_vdev *vdev_handle, - qdf_nbuf_t nbuf, uint8_t newmac[][QDF_MAC_ADDR_SIZE], - uint8_t new_mac_cnt); -void dp_tx_me_alloc_descriptor(struct cdp_pdev *pdev); +uint16_t dp_tx_me_send_convert_ucast(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t nbuf, + uint8_t newmac[][QDF_MAC_ADDR_SIZE], + uint8_t new_mac_cnt); +void dp_tx_me_alloc_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id); -void dp_tx_me_free_descriptor(struct cdp_pdev *pdev); +void dp_tx_me_free_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id); QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, uint32_t stats_type_upload_mask, uint32_t config_param_0, uint32_t config_param_1, uint32_t config_param_2, uint32_t config_param_3, int cookie, int cookie_msb, uint8_t mac_id); -void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf); +void dp_htt_stats_print_tag(struct dp_pdev *pdev, + uint8_t tag_type, uint32_t *tag_buf); void dp_htt_stats_copy_tag(struct dp_pdev *pdev, uint8_t tag_type, uint32_t *tag_buf); -int dp_peer_rxtid_stats(struct dp_peer *peer, void (*callback_fn), +/** + * dp_rxtid_stats_cmd_cb - function pointer for peer + * rx tid stats cmd call_back + */ +typedef void (*dp_rxtid_stats_cmd_cb)(struct dp_soc *soc, void *cb_ctxt, + union hal_reo_status *reo_status); +int dp_peer_rxtid_stats(struct dp_peer *peer, + dp_rxtid_stats_cmd_cb dp_stats_cmd_cb, void *cb_ctxt); -void dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, - struct cdp_peer *peer_handle, enum cdp_sec_type sec_type, - uint32_t *rx_pn); +QDF_STATUS +dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, + uint32_t *rx_pn); -void dp_set_key_sec_type_wifi3(struct cdp_vdev *vdev_handle, - struct cdp_peer *peer_handle, - enum cdp_sec_type sec_type, - bool is_unicast); +QDF_STATUS +dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, + bool is_unicast); void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id); -void dp_set_michael_key(struct cdp_peer *peer_handle, - bool is_unicast, uint32_t *key); -#ifdef CONFIG_WIN -uint32_t dp_pdev_tid_stats_display(void *pdev_handle, - enum _ol_ath_param_t param, uint32_t value, void *buff); -#endif + +QDF_STATUS +dp_set_michael_key(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, + bool is_unicast, uint32_t *key); /** * dp_check_pdev_exists() - Validate pdev before use @@ -1067,6 +1353,121 @@ static inline int dp_get_mac_id_for_pdev(uint32_t mac_id, uint32_t pdev_id) return (mac_id + pdev_id); } +/** + * dp_get_lmac_id_for_pdev_id() - Return lmac id corresponding to host pdev id + * @soc: soc pointer + * @mac_id: MAC id + * @pdev_id: pdev_id corresponding to pdev, 0 for MCL + * + * For MCL, Single pdev using both MACs will operate on both MAC rings. + * + * For WIN, each PDEV will operate one ring. + * + */ +static inline int +dp_get_lmac_id_for_pdev_id + (struct dp_soc *soc, uint32_t mac_id, uint32_t pdev_id) +{ + if (!wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) { + if (mac_id && pdev_id) { + qdf_print("Both mac_id and pdev_id cannot be non zero"); + QDF_BUG(0); + return 0; + } + return (mac_id + pdev_id); + } + + return soc->pdev_list[pdev_id]->lmac_id; +} + +/** + * dp_get_pdev_for_lmac_id() - Return pdev pointer corresponding to lmac id + * @soc: soc pointer + * @lmac_id: LMAC id + * + * For MCL, Single pdev exists + * + * For WIN, each PDEV will operate one ring. + * + */ +static inline struct dp_pdev * + dp_get_pdev_for_lmac_id(struct dp_soc *soc, uint32_t lmac_id) +{ + int i = 0; + + if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) { + i = wlan_cfg_get_pdev_idx(soc->wlan_cfg_ctx, lmac_id); + qdf_assert_always(i < MAX_PDEV_CNT); + + return soc->pdev_list[i]; + } + + /* Typically for MCL as there only 1 PDEV*/ + return soc->pdev_list[0]; +} + +/** + * dp_get_target_pdev_id_for_host_pdev_id() - Return target pdev corresponding + * to host pdev id + * @soc: soc pointer + * @mac_for_pdev: pdev_id corresponding to host pdev for WIN, mac id for MCL + * + * returns target pdev_id for host pdev id. For WIN, this is derived through + * a two step process: + * 1. Get lmac_id corresponding to host pdev_id (lmac_id can change + * during mode switch) + * 2. Get target pdev_id (set up during WMI ready) from lmac_id + * + * For MCL, return the offset-1 translated mac_id + */ +static inline int +dp_get_target_pdev_id_for_host_pdev_id + (struct dp_soc *soc, uint32_t mac_for_pdev) +{ + struct dp_pdev *pdev; + + if (!wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) + return DP_SW2HW_MACID(mac_for_pdev); + + pdev = soc->pdev_list[mac_for_pdev]; + + /*non-MCL case, get original target_pdev mapping*/ + return wlan_cfg_get_target_pdev_id(soc->wlan_cfg_ctx, pdev->lmac_id); +} + +/** + * dp_get_host_pdev_id_for_target_pdev_id() - Return host pdev corresponding + * to target pdev id + * @soc: soc pointer + * @pdev_id: pdev_id corresponding to target pdev + * + * returns host pdev_id for target pdev id. For WIN, this is derived through + * a two step process: + * 1. Get lmac_id corresponding to target pdev_id + * 2. Get host pdev_id (set up during WMI ready) from lmac_id + * + * For MCL, return the 0-offset pdev_id + */ +static inline int +dp_get_host_pdev_id_for_target_pdev_id + (struct dp_soc *soc, uint32_t pdev_id) +{ + struct dp_pdev *pdev; + int lmac_id; + + if (!wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) + return DP_HW2SW_MACID(pdev_id); + + /*non-MCL case, get original target_lmac mapping from target pdev*/ + lmac_id = wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, + DP_HW2SW_MACID(pdev_id)); + + /*Get host pdev from lmac*/ + pdev = dp_get_pdev_for_lmac_id(soc, lmac_id); + + return pdev->pdev_id; +} + /* * dp_get_mac_id_for_mac() - Return mac corresponding WIN and MCL mac_ids * @@ -1122,30 +1523,40 @@ QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, uint32_t stats_type_upload_mask, uint8_t mac_id); -int dp_wdi_event_unsub(struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, - uint32_t event); +int dp_wdi_event_unsub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, + uint32_t event); -int dp_wdi_event_sub(struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, - uint32_t event); +int dp_wdi_event_sub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, + uint32_t event); -void dp_wdi_event_handler(enum WDI_EVENT event, void *soc, - void *data, u_int16_t peer_id, - int status, u_int8_t pdev_id); +void dp_wdi_event_handler(enum WDI_EVENT event, struct dp_soc *soc, + void *data, u_int16_t peer_id, + int status, u_int8_t pdev_id); int dp_wdi_event_attach(struct dp_pdev *txrx_pdev); int dp_wdi_event_detach(struct dp_pdev *txrx_pdev); int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, bool enable); -void *dp_get_pldev(struct cdp_pdev *txrx_pdev); -void dp_pkt_log_init(struct cdp_pdev *ppdev, void *scn); -static inline void dp_hif_update_pipe_callback(void *soc, void *cb_context, - QDF_STATUS (*callback)(void *, qdf_nbuf_t, uint8_t), uint8_t pipe_id) +/** + * dp_get_pldev() - function to get pktlog device handle + * @soc_hdl: datapath soc handle + * @pdev_id: physical device id + * + * Return: pktlog device handle or NULL + */ +void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); +void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn); + +static inline void +dp_hif_update_pipe_callback(struct dp_soc *dp_soc, + void *cb_context, + QDF_STATUS (*callback)(void *, qdf_nbuf_t, uint8_t), + uint8_t pipe_id) { struct hif_msg_callbacks hif_pipe_callbacks; - struct dp_soc *dp_soc = (struct dp_soc *)soc; /* TODO: Temporary change to bypass HTC connection for this new * HIF pipe, which will be used for packet log and other high- @@ -1158,26 +1569,28 @@ static inline void dp_hif_update_pipe_callback(void *soc, void *cb_context, DP_HTT_T2H_HP_PIPE, &hif_pipe_callbacks); } -QDF_STATUS dp_peer_stats_notify(struct dp_peer *peer); +QDF_STATUS dp_peer_stats_notify(struct dp_pdev *pdev, struct dp_peer *peer); #else -static inline int dp_wdi_event_unsub(struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, - uint32_t event) +static inline int dp_wdi_event_unsub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, + uint32_t event) { return 0; } -static inline int dp_wdi_event_sub(struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, - uint32_t event) +static inline int dp_wdi_event_sub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, + uint32_t event) { return 0; } -static inline void dp_wdi_event_handler(enum WDI_EVENT event, void *soc, - void *data, u_int16_t peer_id, - int status, u_int8_t pdev_id) +static inline +void dp_wdi_event_handler(enum WDI_EVENT event, + struct dp_soc *soc, + void *data, u_int16_t peer_id, + int status, u_int8_t pdev_id) { } @@ -1201,19 +1614,70 @@ static inline QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev, { return 0; } -static inline void dp_hif_update_pipe_callback(void *soc, void *cb_context, - QDF_STATUS (*callback)(void *, qdf_nbuf_t, uint8_t), uint8_t pipe_id) + +static inline void +dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn) +{ +} + +static inline void +dp_hif_update_pipe_callback(struct dp_soc *dp_soc, void *cb_context, + QDF_STATUS (*callback)(void *, qdf_nbuf_t, uint8_t), + uint8_t pipe_id) { } -static inline QDF_STATUS dp_peer_stats_notify(struct dp_peer *peer) +static inline QDF_STATUS dp_peer_stats_notify(struct dp_pdev *pdev, + struct dp_peer *peer) { return QDF_STATUS_SUCCESS; } #endif /* CONFIG_WIN */ + +#ifdef VDEV_PEER_PROTOCOL_COUNT +/** + * dp_vdev_peer_stats_update_protocol_cnt() - update per-peer protocol counters + * @vdev: VDEV DP object + * @nbuf: data packet + * @peer: Peer DP object + * @is_egress: whether egress or ingress + * @is_rx: whether rx or tx + * + * This function updates the per-peer protocol counters + * Return: void + */ +void dp_vdev_peer_stats_update_protocol_cnt(struct dp_vdev *vdev, + qdf_nbuf_t nbuf, + struct dp_peer *peer, + bool is_egress, + bool is_rx); + +/** + * dp_vdev_peer_stats_update_protocol_cnt() - update per-peer protocol counters + * @soc: SOC DP object + * @vdev_id: vdev_id + * @nbuf: data packet + * @is_egress: whether egress or ingress + * @is_rx: whether rx or tx + * + * This function updates the per-peer protocol counters + * Return: void + */ + +void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc, + int8_t vdev_id, + qdf_nbuf_t nbuf, + bool is_egress, + bool is_rx); + +#else +#define dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, peer, \ + is_egress, is_rx) +#endif + #ifdef QCA_LL_TX_FLOW_CONTROL_V2 -void dp_tx_dump_flow_pool_info(void *soc); +void dp_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl); int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool, bool force); #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ @@ -1246,7 +1710,7 @@ static inline void dp_peer_unref_del_find_by_id(struct dp_peer *peer) * Return: 0 on success; error on failure */ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, - void *hal_ring); + hal_ring_handle_t hal_ring_hdl); /** * dp_srng_access_end() - Wrapper function to log access end of a hal ring @@ -1257,28 +1721,30 @@ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, * Return: void */ void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc, - void *hal_ring); + hal_ring_handle_t hal_ring_hdl); #else static inline int dp_srng_access_start(struct dp_intr *int_ctx, - struct dp_soc *dp_soc, void *hal_ring) + struct dp_soc *dp_soc, + hal_ring_handle_t hal_ring_hdl) { - void *hal_soc = dp_soc->hal_soc; + hal_soc_handle_t hal_soc = dp_soc->hal_soc; - return hal_srng_access_start(hal_soc, hal_ring); + return hal_srng_access_start(hal_soc, hal_ring_hdl); } static inline void dp_srng_access_end(struct dp_intr *int_ctx, - struct dp_soc *dp_soc, void *hal_ring) + struct dp_soc *dp_soc, + hal_ring_handle_t hal_ring_hdl) { - void *hal_soc = dp_soc->hal_soc; + hal_soc_handle_t hal_soc = dp_soc->hal_soc; - return hal_srng_access_end(hal_soc, hal_ring); + return hal_srng_access_end(hal_soc, hal_ring_hdl); } #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ -#ifdef CONFIG_WIN +#ifdef QCA_ENH_V3_STATS_SUPPORT /** * dp_pdev_print_delay_stats(): Print pdev level delay stats * @pdev: DP_PDEV handle @@ -1346,8 +1812,225 @@ QDF_STATUS dp_tx_add_to_comp_queue(struct dp_soc *soc, { return QDF_STATUS_E_FAILURE; } + +/* + * dp_tx_capture_htt_frame_counter: increment counter for htt_frame_type + * pdev: DP pdev handle + * htt_frame_type: htt frame type received from fw + * + * return: void + */ +static inline +void dp_tx_capture_htt_frame_counter(struct dp_pdev *pdev, + uint32_t htt_frame_type) +{ +} + +/* + * dp_tx_cature_stats: print tx capture stats + * @pdev: DP PDEV handle + * + * return: void + */ +static inline +void dp_print_pdev_tx_capture_stats(struct dp_pdev *pdev) +{ +} + #endif +#ifdef FEATURE_PERPKT_INFO +void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf); +#else +static inline +void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf) +{ +} +#endif + +/** + * dp_vdev_to_cdp_vdev() - typecast dp vdev to cdp vdev + * @vdev: DP vdev handle + * + * Return: struct cdp_vdev pointer + */ +static inline +struct cdp_vdev *dp_vdev_to_cdp_vdev(struct dp_vdev *vdev) +{ + return (struct cdp_vdev *)vdev; +} + +/** + * dp_pdev_to_cdp_pdev() - typecast dp pdev to cdp pdev + * @pdev: DP pdev handle + * + * Return: struct cdp_pdev pointer + */ +static inline +struct cdp_pdev *dp_pdev_to_cdp_pdev(struct dp_pdev *pdev) +{ + return (struct cdp_pdev *)pdev; +} + +/** + * dp_soc_to_cdp_soc() - typecast dp psoc to cdp psoc + * @psoc: DP psoc handle + * + * Return: struct cdp_soc pointer + */ +static inline +struct cdp_soc *dp_soc_to_cdp_soc(struct dp_soc *psoc) +{ + return (struct cdp_soc *)psoc; +} + +/** + * dp_soc_to_cdp_soc_t() - typecast dp psoc to + * ol txrx soc handle + * @psoc: DP psoc handle + * + * Return: struct cdp_soc_t pointer + */ +static inline +struct cdp_soc_t *dp_soc_to_cdp_soc_t(struct dp_soc *psoc) +{ + return (struct cdp_soc_t *)psoc; +} + +/** + * cdp_soc_t_to_dp_soc() - typecast cdp_soc_t to + * dp soc handle + * @psoc: CDP psoc handle + * + * Return: struct dp_soc pointer + */ +static inline +struct dp_soc *cdp_soc_t_to_dp_soc(struct cdp_soc_t *psoc) +{ + return (struct dp_soc *)psoc; +} + +#if defined(WLAN_SUPPORT_RX_FLOW_TAG) || defined(WLAN_SUPPORT_RX_FISA) +/** + * dp_rx_flow_update_fse_stats() - Update a flow's statistics + * @pdev: pdev handle + * @flow_id: flow index (truncated hash) in the Rx FST + * + * Return: Success when flow statistcs is updated, error on failure + */ +QDF_STATUS dp_rx_flow_get_fse_stats(struct dp_pdev *pdev, + struct cdp_rx_flow_info *rx_flow_info, + struct cdp_flow_stats *stats); + +/** + * dp_rx_flow_delete_entry() - Delete a flow entry from flow search table + * @pdev: pdev handle + * @rx_flow_info: DP flow parameters + * + * Return: Success when flow is deleted, error on failure + */ +QDF_STATUS dp_rx_flow_delete_entry(struct dp_pdev *pdev, + struct cdp_rx_flow_info *rx_flow_info); + +/** + * dp_rx_flow_add_entry() - Add a flow entry to flow search table + * @pdev: DP pdev instance + * @rx_flow_info: DP flow paramaters + * + * Return: Success when flow is added, no-memory or already exists on error + */ +QDF_STATUS dp_rx_flow_add_entry(struct dp_pdev *pdev, + struct cdp_rx_flow_info *rx_flow_info); + +/** + * dp_rx_fst_attach() - Initialize Rx FST and setup necessary parameters + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: Handle to flow search table entry + */ +QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev); + +/** + * dp_rx_fst_detach() - De-initialize Rx FST + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: None + */ +void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev); + +/** + * dp_rx_flow_send_fst_fw_setup() - Program FST parameters in FW/HW post-attach + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: Success when fst parameters are programmed in FW, error otherwise + */ +QDF_STATUS dp_rx_flow_send_fst_fw_setup(struct dp_soc *soc, + struct dp_pdev *pdev); +#else /* !((WLAN_SUPPORT_RX_FLOW_TAG) || defined(WLAN_SUPPORT_RX_FISA)) */ + +/** + * dp_rx_fst_attach() - Initialize Rx FST and setup necessary parameters + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: Handle to flow search table entry + */ +static inline +QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * dp_rx_fst_detach() - De-initialize Rx FST + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: None + */ +static inline +void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev) +{ +} +#endif + +/** + * dp_get_vdev_from_soc_vdev_id_wifi3() - Returns vdev object given the vdev id + * @soc: core DP soc context + * @vdev_id: vdev id from vdev object can be retrieved + * + * Return: struct dp_vdev*: Pointer to DP vdev object + */ +static inline struct dp_vdev * +dp_get_vdev_from_soc_vdev_id_wifi3(struct dp_soc *soc, + uint8_t vdev_id) +{ + if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT)) + return NULL; + + return soc->vdev_id_map[vdev_id]; +} + +/** + * dp_get_pdev_from_soc_pdev_id_wifi3() - Returns pdev object given the pdev id + * @soc: core DP soc context + * @pdev_id: pdev id from pdev object can be retrieved + * + * Return: struct dp_pdev*: Pointer to DP pdev object + */ +static inline struct dp_pdev * +dp_get_pdev_from_soc_pdev_id_wifi3(struct dp_soc *soc, + uint8_t pdev_id) +{ + if (qdf_unlikely(pdev_id >= MAX_PDEV_CNT)) + return NULL; + + return soc->pdev_list[pdev_id]; +} + /* * dp_rx_tid_update_wifi3() – Update receive TID state * @peer: Datapath peer handle @@ -1360,39 +2043,275 @@ QDF_STATUS dp_tx_add_to_comp_queue(struct dp_soc *soc, QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t ba_window_size, uint32_t start_seq); +/** + * dp_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required + * + * return: no of clients + */ +uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], + u_int16_t mac_cnt); /* - * dp_get_vdev_from_soc_vdev_id_wifi3() - - * Returns vdev object given the vdev id - * vdev id is unique across pdev's + * dp_is_hw_dbs_enable() - Procedure to check if DBS is supported + * @soc: DP SoC context + * @max_mac_rings: No of MAC rings * - * @soc : core DP soc context - * @vdev_id : vdev id from vdev object can be retrieved + * Return: None + */ +void dp_is_hw_dbs_enable(struct dp_soc *soc, + int *max_mac_rings); + + +#if defined(WLAN_SUPPORT_RX_FISA) +void dp_rx_dump_fisa_table(struct dp_soc *soc); +#endif /* WLAN_SUPPORT_RX_FISA */ + +/** + * dp_rx_skip_tlvs() - Skip TLVs len + L2 hdr_offset, save in nbuf->cb + * @nbuf: nbuf cb to be updated + * @l2_hdr_offset: l2_hdr_offset * - * Return: struct dp_vdev*: Pointer to DP vdev object + * Return: None */ -static inline struct dp_vdev * -dp_get_vdev_from_soc_vdev_id_wifi3(struct dp_soc *soc, - uint8_t vdev_id) -{ - struct dp_pdev *pdev = NULL; - struct dp_vdev *vdev = NULL; - int i; - - for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) { - pdev = soc->pdev_list[i]; - qdf_spin_lock_bh(&pdev->vdev_list_lock); - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - if (vdev->vdev_id == vdev_id) { - qdf_spin_unlock_bh(&pdev->vdev_list_lock); - return vdev; - } - } - qdf_spin_unlock_bh(&pdev->vdev_list_lock); - } - dp_err("Failed to find vdev for vdev_id %d", vdev_id); +void dp_rx_skip_tlvs(qdf_nbuf_t nbuf, uint32_t l3_padding); + +#ifdef MAX_ALLOC_PAGE_SIZE +/** + * dp_set_page_size() - Set the max page size for hw link desc. + * For MCL the page size is set to OS defined value and for WIN + * the page size is set to the max_alloc_size cfg ini + * param. + * This is to ensure that WIN gets contiguous memory allocations + * as per requirement. + * @pages: link desc page handle + * @max_alloc_size: max_alloc_size + * + * Return: None + */ +static inline +void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages, + uint32_t max_alloc_size) +{ + pages->page_size = qdf_page_size; +} + +#else +static inline +void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages, + uint32_t max_alloc_size) +{ + pages->page_size = max_alloc_size; +} +#endif /* MAX_ALLOC_PAGE_SIZE */ + +/** + * dp_history_get_next_index() - get the next entry to record an entry + * in the history. + * @curr_idx: Current index where the last entry is written. + * @max_entries: Max number of entries in the history + * + * This function assumes that the max number os entries is a power of 2. + * + * Returns: The index where the next entry is to be written. + */ +static inline uint32_t dp_history_get_next_index(qdf_atomic_t *curr_idx, + uint32_t max_entries) +{ + uint32_t idx = qdf_atomic_inc_return(curr_idx); + + return idx & (max_entries - 1); +} + +#ifdef DP_MEM_PRE_ALLOC +/** + * dp_context_alloc_mem() - allocate memory for DP context + * @soc: datapath soc handle + * @ctxt_type: DP context type + * @ctxt_size: DP context size + * + * Return: DP context address + */ +void *dp_context_alloc_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + size_t ctxt_size); + +/** + * dp_context_free_mem() - Free memory of DP context + * @soc: datapath soc handle + * @ctxt_type: DP context type + * @vaddr: Address of context memory + * + * Return: None + */ +void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + void *vaddr); + +/** + * dp_desc_multi_pages_mem_alloc() - alloc memory over multiple pages + * @soc: datapath soc handle + * @desc_type: memory request source type + * @pages: multi page information storage + * @element_size: each element size + * @element_num: total number of elements should be allocated + * @memctxt: memory context + * @cacheable: coherent memory or cacheable memory + * + * This function is a wrapper for memory allocation over multiple + * pages, if dp prealloc method is registered, then will try prealloc + * firstly. if prealloc failed, fall back to regular way over + * qdf_mem_multi_pages_alloc(). + * + * Return: None + */ +void dp_desc_multi_pages_mem_alloc(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + size_t element_size, + uint16_t element_num, + qdf_dma_context_t memctxt, + bool cacheable); + +/** + * dp_desc_multi_pages_mem_free() - free multiple pages memory + * @soc: datapath soc handle + * @desc_type: memory request source type + * @pages: multi page information storage + * @memctxt: memory context + * @cacheable: coherent memory or cacheable memory + * + * This function is a wrapper for multiple pages memory free, + * if memory is got from prealloc pool, put it back to pool. + * otherwise free by qdf_mem_multi_pages_free(). + * + * Return: None + */ +void dp_desc_multi_pages_mem_free(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, + bool cacheable); + +#else +static inline +void *dp_context_alloc_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + size_t ctxt_size) +{ + return qdf_mem_malloc(ctxt_size); +} + +static inline +void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + void *vaddr) +{ + qdf_mem_free(vaddr); +} + +static inline +void dp_desc_multi_pages_mem_alloc(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + size_t element_size, + uint16_t element_num, + qdf_dma_context_t memctxt, + bool cacheable) +{ + qdf_mem_multi_pages_alloc(soc->osdev, pages, element_size, + element_num, memctxt, cacheable); +} + +static inline +void dp_desc_multi_pages_mem_free(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, + bool cacheable) +{ + qdf_mem_multi_pages_free(soc->osdev, pages, + memctxt, cacheable); +} + +#endif +#ifdef FEATURE_RUNTIME_PM +/** + * dp_runtime_get() - Get dp runtime refcount + * @soc: Datapath soc handle + * + * Get dp runtime refcount by increment of an atomic variable, which can block + * dp runtime resume to wait to flush pending tx by runtime suspend. + * + * Return: Current refcount + */ +static inline int32_t dp_runtime_get(struct dp_soc *soc) +{ + return qdf_atomic_inc_return(&soc->dp_runtime_refcount); +} + +/** + * dp_runtime_put() - Return dp runtime refcount + * @soc: Datapath soc handle + * + * Return dp runtime refcount by decrement of an atomic variable, allow dp + * runtime resume finish. + * + * Return: Current refcount + */ +static inline int32_t dp_runtime_put(struct dp_soc *soc) +{ + return qdf_atomic_dec_return(&soc->dp_runtime_refcount); +} + +/** + * dp_runtime_get_refcount() - Get dp runtime refcount + * @soc: Datapath soc handle + * + * Get dp runtime refcount by returning an atomic variable + * + * Return: Current refcount + */ +static inline int32_t dp_runtime_get_refcount(struct dp_soc *soc) +{ + return qdf_atomic_read(&soc->dp_runtime_refcount); +} + +/** + * dp_runtime_init() - Init dp runtime refcount when dp soc init + * @soc: Datapath soc handle + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) +{ + return qdf_atomic_init(&soc->dp_runtime_refcount); +} +#else +static inline int32_t dp_runtime_get(struct dp_soc *soc) +{ + return 0; +} - return NULL; +static inline int32_t dp_runtime_put(struct dp_soc *soc) +{ + return 0; +} +static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; } +#endif +/** + * dp_peer_flush_frags() - Flush all fragments for a particular + * peer + * @soc_hdl - data path soc handle + * @vdev_id - vdev id + * @peer_addr - peer mac address + * + * Return: None + */ +void dp_peer_flush_frags(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac); #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c index 6a9d28259cafc9dbb9a7b605affd7427b1ab5054..2f6ecb3510760081fe47b4691c98c73091d34b3c 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c @@ -31,6 +31,9 @@ #include "dp_rx.h" #include "dp_ipa.h" +/* Ring index for WBM2SW2 release ring */ +#define IPA_TX_COMP_RING_IDX HAL_IPA_TX_COMP_RING_IDX + /* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */ #define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT (2048) @@ -290,7 +293,7 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) uint32_t tx_buffer_count; uint32_t ring_base_align = 8; qdf_dma_addr_t buffer_paddr; - struct hal_srng *wbm_srng = + struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; struct hal_srng_params srng_params; uint32_t paddr_lo; @@ -309,7 +312,8 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) unsigned int uc_tx_buf_sz = CFG_IPA_UC_TX_BUF_SIZE_DEFAULT; unsigned int alloc_size = uc_tx_buf_sz + ring_base_align - 1; - hal_get_srng_params(soc->hal_soc, (void *)wbm_srng, &srng_params); + hal_get_srng_params(soc->hal_soc, hal_srng_to_hal_ring_handle(wbm_srng), + &srng_params); num_entries = srng_params.num_entries; max_alloc_count = @@ -330,7 +334,8 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) return -ENOMEM; } - hal_srng_access_start_unlocked(soc->hal_soc, (void *)wbm_srng); + hal_srng_access_start_unlocked(soc->hal_soc, + hal_srng_to_hal_ring_handle(wbm_srng)); /* * Allocate Tx buffers as many as possible. @@ -346,7 +351,7 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) break; ring_entry = hal_srng_dst_get_next_hp(soc->hal_soc, - (void *)wbm_srng); + hal_srng_to_hal_ring_handle(wbm_srng)); if (!ring_entry) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s: Failed to get WBM ring entry", @@ -373,7 +378,8 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) __dp_ipa_handle_buf_smmu_mapping(soc, nbuf, true); } - hal_srng_access_end_unlocked(soc->hal_soc, wbm_srng); + hal_srng_access_end_unlocked(soc->hal_soc, + hal_srng_to_hal_ring_handle(wbm_srng)); soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count; @@ -454,8 +460,11 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, return QDF_STATUS_SUCCESS; /* IPA TCL_DATA Ring - HAL_SRNG_SW2TCL3 */ - hal_srng = soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng; - hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params); + hal_srng = (struct hal_srng *) + soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); soc->ipa_uc_tx_rsc.ipa_tcl_ring_base_paddr = srng_params.ring_base_paddr; @@ -485,8 +494,11 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, soc->ipa_uc_tx_rsc.ipa_tcl_ring_size); /* IPA TX COMP Ring - HAL_SRNG_WBM2SW2_RELEASE */ - hal_srng = soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; - hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params); + hal_srng = (struct hal_srng *) + soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); soc->ipa_uc_tx_rsc.ipa_wbm_ring_base_paddr = srng_params.ring_base_paddr; @@ -494,6 +506,9 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, srng_params.ring_base_vaddr; soc->ipa_uc_tx_rsc.ipa_wbm_ring_size = (srng_params.num_entries * srng_params.entry_size) << 2; + soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr = + hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng)); addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) - (unsigned long)(hal_soc->dev_base_addr); soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr = @@ -509,8 +524,11 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, soc->ipa_uc_tx_rsc.ipa_wbm_ring_size); /* IPA REO_DEST Ring - HAL_SRNG_REO2SW4 */ - hal_srng = soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng; - hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params); + hal_srng = (struct hal_srng *) + soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); soc->ipa_uc_rx_rsc.ipa_reo_ring_base_paddr = srng_params.ring_base_paddr; @@ -532,15 +550,19 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, srng_params.num_entries, soc->ipa_uc_rx_rsc.ipa_reo_ring_size); - hal_srng = pdev->rx_refill_buf_ring2.hal_srng; - hal_get_srng_params(hal_soc, (void *)hal_srng, &srng_params); + hal_srng = (struct hal_srng *) + pdev->rx_refill_buf_ring2.hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_paddr = srng_params.ring_base_paddr; soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_base_vaddr = srng_params.ring_base_vaddr; soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_ring_size = (srng_params.num_entries * srng_params.entry_size) << 2; - hp_addr = hal_srng_get_hp_addr(hal_soc, (void *)hal_srng); + hp_addr = hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng)); soc->ipa_uc_rx_rsc.ipa_rx_refill_buf_hp_paddr = qdf_mem_paddr_from_dmaaddr(soc->osdev, hp_addr); @@ -555,14 +577,14 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, * Set DEST_RING_MAPPING_4 to SW2 as default value for * DESTINATION_RING_CTRL_IX_0. */ - ix0 = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | - HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW1) | - HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW3) | - HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | - HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | - HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); + ix0 = HAL_REO_REMAP_IX0(REO_REMAP_TCL, 0) | + HAL_REO_REMAP_IX0(REO_REMAP_SW1, 1) | + HAL_REO_REMAP_IX0(REO_REMAP_SW2, 2) | + HAL_REO_REMAP_IX0(REO_REMAP_SW3, 3) | + HAL_REO_REMAP_IX0(REO_REMAP_SW2, 4) | + HAL_REO_REMAP_IX0(REO_REMAP_RELEASE, 5) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 6) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 7); hal_reo_read_write_ctrl_ix(soc->hal_soc, false, &ix0, NULL, NULL, NULL); @@ -597,22 +619,19 @@ static QDF_STATUS dp_ipa_get_shared_mem_info(qdf_device_t osdev, return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_uc_get_resource() - Client request resource information - * @ppdev - handle to the device instance - * - * IPA client will request IPA UC related resource information - * Resource information will be distributed to IPA module - * All of the required resources should be pre-allocated - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_ipa_get_resource(struct cdp_pdev *ppdev) +QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; - struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_ipa_resources *ipa_res; + + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ipa_res = &pdev->ipa_resource; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -648,27 +667,45 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_pdev *ppdev) return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_set_doorbell_paddr () - Set doorbell register physical address to SRNG - * @ppdev - handle to the device instance - * - * Set TX_COMP_DOORBELL register physical address to WBM Head_Ptr_MemAddr_LSB - * Set RX_READ_DOORBELL register physical address to REO Head_Ptr_MemAddr_LSB - * - * Return: none - */ -QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_pdev *ppdev) +static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc, + struct dp_ipa_resources *ipa_res) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; - struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; - struct hal_srng *wbm_srng = + struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; - struct hal_srng *reo_srng = + + hal_srng_dst_set_hp_paddr_confirm(wbm_srng, + ipa_res->tx_comp_doorbell_paddr); + + dp_info("paddr %pK vaddr %pK", + (void *)ipa_res->tx_comp_doorbell_paddr, + (void *)ipa_res->tx_comp_doorbell_vaddr); +} + +#ifdef IPA_SET_RESET_TX_DB_PA +#define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) +#else +#define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) \ + dp_ipa_set_tx_doorbell_paddr(soc, ipa_res) +#endif + +QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_ipa_resources *ipa_res; + struct hal_srng *reo_srng = (struct hal_srng *) soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng; uint32_t tx_comp_doorbell_dmaaddr; uint32_t rx_ready_doorbell_dmaaddr; + int ret = 0; + + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ipa_res = &pdev->ipa_resource; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -676,20 +713,22 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_pdev *ppdev) ioremap(ipa_res->tx_comp_doorbell_paddr, 4); if (qdf_mem_smmu_s1_enabled(soc->osdev)) { - pld_smmu_map(soc->osdev->dev, ipa_res->tx_comp_doorbell_paddr, - &tx_comp_doorbell_dmaaddr, sizeof(uint32_t)); + ret = pld_smmu_map(soc->osdev->dev, + ipa_res->tx_comp_doorbell_paddr, + &tx_comp_doorbell_dmaaddr, + sizeof(uint32_t)); ipa_res->tx_comp_doorbell_paddr = tx_comp_doorbell_dmaaddr; + qdf_assert_always(!ret); - pld_smmu_map(soc->osdev->dev, ipa_res->rx_ready_doorbell_paddr, - &rx_ready_doorbell_dmaaddr, sizeof(uint32_t)); + ret = pld_smmu_map(soc->osdev->dev, + ipa_res->rx_ready_doorbell_paddr, + &rx_ready_doorbell_dmaaddr, + sizeof(uint32_t)); ipa_res->rx_ready_doorbell_paddr = rx_ready_doorbell_dmaaddr; + qdf_assert_always(!ret); } - hal_srng_dst_set_hp_paddr(wbm_srng, ipa_res->tx_comp_doorbell_paddr); - - dp_info("paddr %pK vaddr %pK", - (void *)ipa_res->tx_comp_doorbell_paddr, - (void *)ipa_res->tx_comp_doorbell_vaddr); + DP_IPA_SET_TX_DB_PADDR(soc, ipa_res); /* * For RX, REO module on Napier/Hastings does reordering on incoming @@ -698,20 +737,22 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_pdev *ppdev) * to IPA. * Set the doorbell addr for the REO ring. */ - hal_srng_dst_set_hp_paddr(reo_srng, ipa_res->rx_ready_doorbell_paddr); + hal_srng_dst_set_hp_paddr_confirm(reo_srng, + ipa_res->rx_ready_doorbell_paddr); return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_op_response() - Handle OP command response from firmware - * @ppdev - handle to the device instance - * @op_msg: op response message from firmware - * - * Return: none - */ -QDF_STATUS dp_ipa_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg) +QDF_STATUS dp_ipa_op_response(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t *op_msg) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } if (!wlan_cfg_is_ipa_enabled(pdev->soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -728,18 +769,18 @@ QDF_STATUS dp_ipa_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg) return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_register_op_cb() - Register OP handler function - * @ppdev - handle to the device instance - * @op_cb: handler function pointer - * - * Return: none - */ -QDF_STATUS dp_ipa_register_op_cb(struct cdp_pdev *ppdev, +QDF_STATUS dp_ipa_register_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, ipa_uc_op_cb_type op_cb, void *usr_ctxt) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } if (!wlan_cfg_is_ipa_enabled(pdev->soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -750,13 +791,7 @@ QDF_STATUS dp_ipa_register_op_cb(struct cdp_pdev *ppdev, return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_get_stat() - Get firmware wdi status - * @ppdev - handle to the device instance - * - * Return: none - */ -QDF_STATUS dp_ipa_get_stat(struct cdp_pdev *ppdev) +QDF_STATUS dp_ipa_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { /* TBD */ return QDF_STATUS_SUCCESS; @@ -764,18 +799,20 @@ QDF_STATUS dp_ipa_get_stat(struct cdp_pdev *ppdev) /** * dp_tx_send_ipa_data_frame() - send IPA data frame - * @vdev: vdev - * @skb: skb + * @soc_hdl: datapath soc handle + * @vdev_id: id of the virtual device + * @skb: skb to transmit * * Return: skb/ NULL is for success */ -qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb) +qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t skb) { qdf_nbuf_t ret; /* Terminate the (single-element) list of tx frames */ qdf_nbuf_set_next(skb, NULL); - ret = dp_tx_send((struct dp_vdev_t *)vdev, skb); + ret = dp_tx_send(soc_hdl, vdev_id, skb); if (ret) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Failed to tx", __func__); @@ -785,23 +822,19 @@ qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb) return NULL; } -/** - * dp_ipa_enable_autonomy() – Enable autonomy RX path - * @pdev - handle to the device instance - * - * Set all RX packet route to IPA REO ring - * Program Destination_Ring_Ctrl_IX_0 REO register to point IPA REO ring - * - * Return: QDF_STATUS_SUCCESS in case of success - * QDF error code in failure cases - */ -QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *ppdev) +QDF_STATUS dp_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); uint32_t ix0; uint32_t ix2; + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -809,20 +842,24 @@ QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *ppdev) return QDF_STATUS_E_AGAIN; /* Call HAL API to remap REO rings to REO2IPA ring */ - ix0 = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | - HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW4) | - HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | - HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | - HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); + ix0 = HAL_REO_REMAP_IX0(REO_REMAP_TCL, 0) | + HAL_REO_REMAP_IX0(REO_REMAP_SW4, 1) | + HAL_REO_REMAP_IX0(REO_REMAP_SW1, 2) | + HAL_REO_REMAP_IX0(REO_REMAP_SW4, 3) | + HAL_REO_REMAP_IX0(REO_REMAP_SW4, 4) | + HAL_REO_REMAP_IX0(REO_REMAP_RELEASE, 5) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 6) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 7); if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { - ix2 = ((REO_REMAP_SW4 << 0) | (REO_REMAP_SW4 << 3) | - (REO_REMAP_SW4 << 6) | (REO_REMAP_SW4 << 9) | - (REO_REMAP_SW4 << 12) | (REO_REMAP_SW4 << 15) | - (REO_REMAP_SW4 << 18) | (REO_REMAP_SW4 << 21)) << 8; + ix2 = HAL_REO_REMAP_IX2(REO_REMAP_SW4, 16) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 17) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 18) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 19) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 20) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 21) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 22) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 23); hal_reo_read_write_ctrl_ix(soc->hal_soc, false, &ix0, NULL, &ix2, &ix2); @@ -836,24 +873,20 @@ QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *ppdev) return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_disable_autonomy() – Disable autonomy RX path - * @ppdev - handle to the device instance - * - * Disable RX packet routing to IPA REO - * Program Destination_Ring_Ctrl_IX_0 REO register to disable - * - * Return: QDF_STATUS_SUCCESS in case of success - * QDF error code in failure cases - */ -QDF_STATUS dp_ipa_disable_autonomy(struct cdp_pdev *ppdev) +QDF_STATUS dp_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); uint32_t ix0; uint32_t ix2; uint32_t ix3; + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -861,14 +894,14 @@ QDF_STATUS dp_ipa_disable_autonomy(struct cdp_pdev *ppdev) return QDF_STATUS_E_AGAIN; /* Call HAL API to remap REO rings to REO2IPA ring */ - ix0 = HAL_REO_REMAP_VAL(REO_REMAP_TCL, REO_REMAP_TCL) | - HAL_REO_REMAP_VAL(REO_REMAP_SW1, REO_REMAP_SW1) | - HAL_REO_REMAP_VAL(REO_REMAP_SW2, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_SW3, REO_REMAP_SW3) | - HAL_REO_REMAP_VAL(REO_REMAP_SW4, REO_REMAP_SW2) | - HAL_REO_REMAP_VAL(REO_REMAP_RELEASE, REO_REMAP_RELEASE) | - HAL_REO_REMAP_VAL(REO_REMAP_FW, REO_REMAP_FW) | - HAL_REO_REMAP_VAL(REO_REMAP_UNUSED, REO_REMAP_FW); + ix0 = HAL_REO_REMAP_IX0(REO_REMAP_TCL, 0) | + HAL_REO_REMAP_IX0(REO_REMAP_SW1, 1) | + HAL_REO_REMAP_IX0(REO_REMAP_SW2, 2) | + HAL_REO_REMAP_IX0(REO_REMAP_SW3, 3) | + HAL_REO_REMAP_IX0(REO_REMAP_SW2, 4) | + HAL_REO_REMAP_IX0(REO_REMAP_RELEASE, 5) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 6) | + HAL_REO_REMAP_IX0(REO_REMAP_FW, 7); if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { dp_reo_remap_config(soc, &ix2, &ix3); @@ -1105,32 +1138,18 @@ dp_ipa_wdi_rx_smmu_params(struct dp_soc *soc, RX_PKT_TLVS_LEN + L3_HEADER_PADDING; } -/** - * dp_ipa_setup() - Setup and connect IPA pipes - * @ppdev - handle to the device instance - * @ipa_i2w_cb: IPA to WLAN callback - * @ipa_w2i_cb: WLAN to IPA callback - * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback - * @ipa_desc_size: IPA descriptor size - * @ipa_priv: handle to the HTT instance - * @is_rm_enabled: Is IPA RM enabled or not - * @tx_pipe_handle: pointer to Tx pipe handle - * @rx_pipe_handle: pointer to Rx pipe handle - * @is_smmu_enabled: Is SMMU enabled or not - * @sys_in: parameters to setup sys pipe in mcc mode - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; - struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_ipa_resources *ipa_res; qdf_ipa_ep_cfg_t *tx_cfg; qdf_ipa_ep_cfg_t *rx_cfg; qdf_ipa_wdi_pipe_setup_info_t *tx = NULL; @@ -1141,6 +1160,12 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, qdf_ipa_wdi_conn_out_params_t pipe_out; int ret; + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -1262,7 +1287,9 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, struct dp_ipa_uc_tx_hdr uc_tx_hdr_v6; int ret = -EINVAL; - dp_debug("Add Partial hdr: %s, %pM", ifname, mac_addr); + dp_debug("Add Partial hdr: %s, "QDF_MAC_ADDR_FMT, ifname, + QDF_MAC_ADDR_REF(mac_addr)); + qdf_mem_zero(&in, sizeof(qdf_ipa_wdi_reg_intf_in_params_t)); qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t)); qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr); @@ -1309,30 +1336,17 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, } #else /* CONFIG_IPA_WDI_UNIFIED_API */ - -/** - * dp_ipa_setup() - Setup and connect IPA pipes - * @ppdev - handle to the device instance - * @ipa_i2w_cb: IPA to WLAN callback - * @ipa_w2i_cb: WLAN to IPA callback - * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback - * @ipa_desc_size: IPA descriptor size - * @ipa_priv: handle to the HTT instance - * @is_rm_enabled: Is IPA RM enabled or not - * @tx_pipe_handle: pointer to Tx pipe handle - * @rx_pipe_handle: pointer to Rx pipe handle - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; - struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_ipa_resources *ipa_res; qdf_ipa_wdi_pipe_setup_info_t *tx; qdf_ipa_wdi_pipe_setup_info_t *rx; qdf_ipa_wdi_conn_in_params_t pipe_in; @@ -1342,6 +1356,12 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, uint32_t desc_size; int ret; + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) return QDF_STATUS_SUCCESS; @@ -1524,9 +1544,10 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, int ret = -EINVAL; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "%s: Add Partial hdr: %s, %pM", - __func__, ifname, mac_addr); + "%s: Add Partial hdr: %s, "QDF_MAC_ADDR_FMT, + __func__, ifname, QDF_MAC_ADDR_REF(mac_addr)); + qdf_mem_zero(&in, sizeof(qdf_ipa_wdi_reg_intf_in_params_t)); qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t)); qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr); @@ -1571,23 +1592,53 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, /** * dp_ipa_cleanup() - Disconnect IPA pipes + * @soc_hdl: dp soc handle + * @pdev_id: dp pdev id * @tx_pipe_handle: Tx pipe handle * @rx_pipe_handle: Rx pipe handle * * Return: QDF_STATUS */ -QDF_STATUS dp_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle) +QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, uint32_t rx_pipe_handle) { + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_ipa_resources *ipa_res; + struct dp_pdev *pdev; int ret; ret = qdf_ipa_wdi_disconn_pipes(); if (ret) { dp_err("ipa_wdi_disconn_pipes: IPA pipe cleanup failed: ret=%d", ret); - return QDF_STATUS_E_FAILURE; + status = QDF_STATUS_E_FAILURE; } - return QDF_STATUS_SUCCESS; + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (qdf_unlikely(!pdev)) { + dp_err_rl("Invalid pdev for pdev_id %d", pdev_id); + status = QDF_STATUS_E_FAILURE; + goto exit; + } + + if (qdf_mem_smmu_s1_enabled(soc->osdev)) { + ipa_res = &pdev->ipa_resource; + + /* unmap has to be the reverse order of smmu map */ + ret = pld_smmu_unmap(soc->osdev->dev, + ipa_res->rx_ready_doorbell_paddr, + sizeof(uint32_t)); + qdf_assert_always(!ret); + + ret = pld_smmu_unmap(soc->osdev->dev, + ipa_res->tx_comp_doorbell_paddr, + sizeof(uint32_t)); + qdf_assert_always(!ret); + } + +exit: + return status; } /** @@ -1612,24 +1663,55 @@ QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled) return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes - * @ppdev - handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_ipa_enable_pipes(struct cdp_pdev *ppdev) +#ifdef IPA_SET_RESET_TX_DB_PA +static +QDF_STATUS dp_ipa_reset_tx_doorbell_pa(struct dp_soc *soc, + struct dp_ipa_resources *ipa_res) +{ + hal_ring_handle_t wbm_srng = + soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; + qdf_dma_addr_t hp_addr; + + if (!wbm_srng) + return QDF_STATUS_E_FAILURE; + + hp_addr = soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr; + + hal_srng_dst_set_hp_paddr_confirm((struct hal_srng *)wbm_srng, hp_addr); + + dp_info("Reset WBM HP addr paddr: %pK", (void *)hp_addr); + + return QDF_STATUS_SUCCESS; +} + +#define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) \ + dp_ipa_set_tx_doorbell_paddr((soc), (ipa_res)) +#define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) \ + dp_ipa_reset_tx_doorbell_pa((soc), (ipa_res)) +#else +#define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) +#define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) +#endif + +QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); struct hal_srng *wbm_srng = (struct hal_srng *) soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng; struct dp_ipa_resources *ipa_res; QDF_STATUS result; + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ipa_res = &pdev->ipa_resource; qdf_atomic_set(&soc->ipa_pipes_enabled, 1); + DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, true); result = qdf_ipa_wdi_enable_pipes(); @@ -1638,29 +1720,43 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_pdev *ppdev) "%s: Enable WDI PIPE fail, code %d", __func__, result); qdf_atomic_set(&soc->ipa_pipes_enabled, 0); + DP_IPA_RESET_TX_DB_PA(soc, ipa_res); dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, false); return QDF_STATUS_E_FAILURE; } if (soc->ipa_first_tx_db_access) { - hal_srng_dst_init_hp(wbm_srng, ipa_res->tx_comp_doorbell_vaddr); + hal_srng_dst_init_hp( + soc->hal_soc, wbm_srng, + ipa_res->tx_comp_doorbell_vaddr); soc->ipa_first_tx_db_access = false; } return QDF_STATUS_SUCCESS; } -/** - * dp_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes - * @ppdev - handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_ipa_disable_pipes(struct cdp_pdev *ppdev) +QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); QDF_STATUS result; + struct dp_ipa_resources *ipa_res; + + if (!pdev) { + dp_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; + + qdf_sleep(TX_COMP_DRAIN_WAIT_TIMEOUT_MS); + /* + * Reset the tx completion doorbell address before invoking IPA disable + * pipes API to ensure that there is no access to IPA tx doorbell + * address post disable pipes. + */ + DP_IPA_RESET_TX_DB_PA(soc, ipa_res); result = qdf_ipa_wdi_disable_pipes(); if (result) { @@ -1725,7 +1821,7 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev, qdf_mem_zero(nbuf->cb, sizeof(nbuf->cb)); len = qdf_nbuf_len(nbuf); - if (dp_tx_send(vdev, nbuf)) { + if (dp_tx_send((struct cdp_soc_t *)pdev->soc, vdev->vdev_id, nbuf)) { DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len); return nbuf; } @@ -1734,17 +1830,18 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev, return NULL; } -bool dp_ipa_rx_intrabss_fwd(struct cdp_vdev *pvdev, qdf_nbuf_t nbuf, - bool *fwd_success) +bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t nbuf, bool *fwd_success) { - struct dp_vdev *vdev = (struct dp_vdev *)pvdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); struct dp_pdev *pdev; struct dp_peer *da_peer; struct dp_peer *sa_peer; qdf_nbuf_t nbuf_copy; uint8_t da_is_bcmc; struct ethhdr *eh; - uint8_t local_id; *fwd_success = false; /* set default as failure */ @@ -1785,22 +1882,20 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_vdev *pvdev, qdf_nbuf_t nbuf, if (!qdf_mem_cmp(eh->h_dest, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE)) return false; - da_peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, eh->h_dest, - &local_id); + da_peer = dp_find_peer_by_addr_and_vdev(dp_pdev_to_cdp_pdev(pdev), + dp_vdev_to_cdp_vdev(vdev), + eh->h_dest); + if (!da_peer) return false; - if (da_peer->vdev != vdev) - return false; + sa_peer = dp_find_peer_by_addr_and_vdev(dp_pdev_to_cdp_pdev(pdev), + dp_vdev_to_cdp_vdev(vdev), + eh->h_source); - sa_peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, eh->h_source, - &local_id); if (!sa_peer) return false; - if (sa_peer->vdev != vdev) - return false; - /* * In intra-bss forwarding scenario, skb is allocated by IPA driver. * Need to add skb to internal tracking table to avoid nbuf memory @@ -1846,16 +1941,16 @@ static qdf_nbuf_t dp_ipa_frag_nbuf_linearize(struct dp_soc *soc, bool is_nbuf_head = true; uint32_t copy_len = 0; - dst_nbuf = qdf_nbuf_alloc(soc->osdev, RX_BUFFER_SIZE, - RX_BUFFER_RESERVATION, RX_BUFFER_ALIGNMENT, - FALSE); + dst_nbuf = qdf_nbuf_alloc(soc->osdev, RX_DATA_BUFFER_SIZE, + RX_BUFFER_RESERVATION, + RX_DATA_BUFFER_ALIGNMENT, FALSE); if (!dst_nbuf) { dp_err_rl("nbuf allocate fail"); return NULL; } - if ((nbuf_len + L3_HEADER_PADDING) > RX_BUFFER_SIZE) { + if ((nbuf_len + L3_HEADER_PADDING) > RX_DATA_BUFFER_SIZE) { qdf_nbuf_free(dst_nbuf); dp_err_rl("nbuf is jumbo data"); return NULL; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h index 48b071a8c9857490fc899132194453de0b3128be..0ec21d3ce1892e432a44b9baf2f48376267d5f6c 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,10 +21,13 @@ #define DP_IPA_MAX_IFACE 3 #define IPA_TCL_DATA_RING_IDX 2 -#define IPA_TX_COMP_RING_IDX 2 #define IPA_REO_DEST_RING_IDX 3 #define IPA_RX_REFILL_BUF_RING_IDX 2 +/* Adding delay before disabling ipa pipes if any Tx Completions are pending */ +#define TX_COMP_DRAIN_WAIT_MS 50 +#define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 200 + /** * struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware * @eth: ether II header @@ -45,34 +48,150 @@ struct dp_ipa_uc_rx_hdr { #define DP_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct dp_ipa_uc_rx_hdr) #define DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 0 -QDF_STATUS dp_ipa_get_resource(struct cdp_pdev *pdev); -QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_pdev *pdev); -QDF_STATUS dp_ipa_uc_set_active(struct cdp_pdev *pdev, bool uc_active, - bool is_tx); -QDF_STATUS dp_ipa_op_response(struct cdp_pdev *pdev, uint8_t *op_msg); -QDF_STATUS dp_ipa_register_op_cb(struct cdp_pdev *pdev, ipa_uc_op_cb_type op_cb, - void *usr_ctxt); -QDF_STATUS dp_ipa_get_stat(struct cdp_pdev *pdev); -qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb); -QDF_STATUS dp_ipa_enable_autonomy(struct cdp_pdev *pdev); -QDF_STATUS dp_ipa_disable_autonomy(struct cdp_pdev *pdev); +/** + * dp_ipa_get_resource() - Client request resource information + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * IPA client will request IPA UC related resource information + * Resource information will be distributed to IPA module + * All of the required resources should be pre-allocated + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * dp_ipa_set_doorbell_paddr () - Set doorbell register physical address to SRNG + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * Set TX_COMP_DOORBELL register physical address to WBM Head_Ptr_MemAddr_LSB + * Set RX_READ_DOORBELL register physical address to REO Head_Ptr_MemAddr_LSB + * + * Return: none + */ +QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); +QDF_STATUS dp_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool uc_active, bool is_tx); + +/** + * dp_ipa_op_response() - Handle OP command response from firmware + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @op_msg: op response message from firmware + * + * Return: none + */ +QDF_STATUS dp_ipa_op_response(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t *op_msg); + +/** + * dp_ipa_register_op_cb() - Register OP handler function + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @op_cb: handler function pointer + * + * Return: none + */ +QDF_STATUS dp_ipa_register_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + ipa_uc_op_cb_type op_cb, void *usr_ctxt); + +/** + * dp_ipa_get_stat() - Get firmware wdi status + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * Return: none + */ +QDF_STATUS dp_ipa_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * dp_tx_send_ipa_data_frame() - send IPA data frame + * @soc_hdl: datapath soc handle + * @vdev_id: virtual device/interface id + * @skb: skb + * + * Return: skb/ NULL is for success + */ +qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t skb); + +/** + * dp_ipa_enable_autonomy() – Enable autonomy RX path + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * Set all RX packet route to IPA REO ring + * Program Destination_Ring_Ctrl_IX_0 REO register to point IPA REO ring + * Return: none + */ +QDF_STATUS dp_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * dp_ipa_disable_autonomy() – Disable autonomy RX path + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * Disable RX packet routing to IPA REO + * Program Destination_Ring_Ctrl_IX_0 REO register to disable + * Return: none + */ +QDF_STATUS dp_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + #ifdef CONFIG_IPA_WDI_UNIFIED_API -QDF_STATUS dp_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +/** + * dp_ipa_setup() - Setup and connect IPA pipes + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @ipa_i2w_cb: IPA to WLAN callback + * @ipa_w2i_cb: WLAN to IPA callback + * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback + * @ipa_desc_size: IPA descriptor size + * @ipa_priv: handle to the HTT instance + * @is_rm_enabled: Is IPA RM enabled or not + * @tx_pipe_handle: pointer to Tx pipe handle + * @rx_pipe_handle: pointer to Rx pipe handle + * @is_smmu_enabled: Is SMMU enabled or not + * @sys_in: parameters to setup sys pipe in mcc mode + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi); #else /* CONFIG_IPA_WDI_UNIFIED_API */ -QDF_STATUS dp_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +/** + * dp_ipa_setup() - Setup and connect IPA pipes + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * @ipa_i2w_cb: IPA to WLAN callback + * @ipa_w2i_cb: WLAN to IPA callback + * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback + * @ipa_desc_size: IPA descriptor size + * @ipa_priv: handle to the HTT instance + * @is_rm_enabled: Is IPA RM enabled or not + * @tx_pipe_handle: pointer to Tx pipe handle + * @rx_pipe_handle: pointer to Rx pipe handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle); #endif /* CONFIG_IPA_WDI_UNIFIED_API */ -QDF_STATUS dp_ipa_cleanup(uint32_t tx_pipe_handle, - uint32_t rx_pipe_handle); +QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, + uint32_t rx_pipe_handle); QDF_STATUS dp_ipa_remove_header(char *name); int dp_ipa_add_header_info(char *ifname, uint8_t *mac_addr, uint8_t session_id, bool is_ipv6_enabled); @@ -82,15 +201,32 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, qdf_ipa_client_type_t cons_client, uint8_t session_id, bool is_ipv6_enabled); QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled); -QDF_STATUS dp_ipa_enable_pipes(struct cdp_pdev *pdev); -QDF_STATUS dp_ipa_disable_pipes(struct cdp_pdev *pdev); + +/** + * dp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes + * @soc_hdl - handle to the soc + * @pdev_id - pdev id number, to get the handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * dp_ipa_disable_pipes() – Suspend traffic and disable Tx/Rx pipes + * @soc_hdl - handle to the soc + * @pdev_id - pdev id number, to get the handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); QDF_STATUS dp_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps); /** * dp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path * - * @pvdev: pointer to dp_vdev structure + * @soc_hdl: data path soc handle + * @vdev_id: virtual device/interface id * @nbuf: pointer to skb of ethernet packet received from IPA RX path * @fwd_success: pointer to indicate if skb succeeded in intra-bss TX * @@ -99,8 +235,8 @@ QDF_STATUS dp_ipa_set_perf_level(int client, * Return: true if packet is intra-bss fwd-ed and no need to pass to * network stack. false if packet needs to be passed to network stack. */ -bool dp_ipa_rx_intrabss_fwd(struct cdp_vdev *pvdev, qdf_nbuf_t nbuf, - bool *fwd_success); +bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t nbuf, bool *fwd_success); int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev); int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev); int dp_ipa_ring_resource_setup(struct dp_soc *soc, diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c index 12041016ad1791d9e7d1da28484b3def678f07e7..926543b156e86d426de96e2450a562fa665d1c8a 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -45,10 +46,14 @@ #include "dp_peer.h" #include "dp_rx_mon.h" #include "htt_stats.h" -#include "htt_ppdu_stats.h" #include "dp_htt.h" +#ifdef WLAN_SUPPORT_RX_FISA +#include +#endif +#include "htt_ppdu_stats.h" #include "qdf_mem.h" /* qdf_mem_malloc,free */ #include "cfg_ucfg_api.h" +#include "dp_mon_filter.h" #ifdef QCA_LL_TX_FLOW_CONTROL_V2 #include "cdp_txrx_flow_ctrl_v2.h" #else @@ -63,7 +68,10 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc) #ifdef FEATURE_WDS #include "dp_txrx_wds.h" #endif -#ifdef CONFIG_MCL +#ifdef ATH_SUPPORT_IQUE +#include "dp_txrx_me.h" +#endif +#if defined(DP_CON_MON) #ifndef REMOVE_PKT_LOG #include #include @@ -87,6 +95,14 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc) #define SET_PEER_REF_CNT_ONE(_peer) #endif +/* + * The max size of cdp_peer_stats_param_t is limited to 16 bytes. + * If the buffer size is exceeding this size limit, + * dp_txrx_get_peer_stats is to be used instead. + */ +QDF_COMPILE_TIME_ASSERT(cdp_peer_stats_param_t_max_size, + (sizeof(cdp_peer_stats_param_t) <= 16)); + #ifdef WLAN_FEATURE_DP_EVENT_HISTORY /* * If WLAN_CFG_INT_NUM_CONTEXTS is changed, HIF_NUM_INT_CONTEXTS @@ -102,6 +118,14 @@ QDF_COMPILE_TIME_ASSERT(hif_event_history_size, (HIF_EVENT_HIST_MAX & (HIF_EVENT_HIST_MAX - 1)) == 0); #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ +/* + * If WLAN_CFG_INT_NUM_CONTEXTS is changed, + * WLAN_CFG_INT_NUM_CONTEXTS_MAX should also be updated + */ +QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs, + WLAN_CFG_INT_NUM_CONTEXTS_MAX >= + WLAN_CFG_INT_NUM_CONTEXTS); + #ifdef WLAN_RX_PKT_CAPTURE_ENH #include "dp_rx_mon_feature.h" #else @@ -113,7 +137,7 @@ QDF_COMPILE_TIME_ASSERT(hif_event_history_size, * Return: QDF_STATUS */ static QDF_STATUS -dp_config_enh_rx_capture(struct cdp_pdev *pdev_handle, uint8_t val) +dp_config_enh_rx_capture(struct dp_pdev *pdev_handle, uint8_t val) { return QDF_STATUS_E_INVAL; } @@ -130,30 +154,51 @@ dp_config_enh_rx_capture(struct cdp_pdev *pdev_handle, uint8_t val) * Return: QDF_STATUS */ static QDF_STATUS -dp_config_enh_tx_capture(struct cdp_pdev *pdev_handle, int val) +dp_config_enh_tx_capture(struct dp_pdev *pdev_handle, uint8_t val) { return QDF_STATUS_E_INVAL; } #endif -void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle); +void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, + struct hif_opaque_softc *hif_handle); static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force); static struct dp_soc * -dp_soc_attach(void *ctrl_psoc, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, +dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, HTC_HANDLE htc_handle, + qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id); static void dp_pktlogmod_exit(struct dp_pdev *handle); -static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, - uint8_t *peer_mac_addr, - struct cdp_ctrl_objmgr_peer *ctrl_peer); -static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap); -static void dp_ppdu_ring_reset(struct dp_pdev *pdev); -static void dp_ppdu_ring_cfg(struct dp_pdev *pdev); +static inline QDF_STATUS dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_mac_addr); +static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_mac, uint32_t bitmap); static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only); #ifdef ENABLE_VERBOSE_DEBUG bool is_dp_verbose_debug_enabled; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +static void dp_cfr_filter(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val); +static bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); +static void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool enable); +static inline void +dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct cdp_cfr_rcc_stats *cfr_rcc_stats); +static inline void +dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); +static inline void +dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool enable); +#endif +static inline bool +dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev); static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc, enum hal_ring_type ring_type, int ring_num); @@ -234,37 +279,17 @@ static uint8_t default_pcp_tid_map[PCP_TID_MAP_MAX] = { /** * @brief Cpu to tx ring map */ -#ifdef CONFIG_WIN -#ifdef WLAN_TX_PKT_CAPTURE_ENH uint8_t -dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS] = { +dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS_MAX] = { {0x0, 0x1, 0x2, 0x0, 0x0, 0x1, 0x2, 0x0, 0x0, 0x1, 0x2}, {0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1}, {0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0}, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, +#ifdef WLAN_TX_PKT_CAPTURE_ENH {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1} -}; -#else -static uint8_t -dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS] = { - {0x0, 0x1, 0x2, 0x0, 0x0, 0x1, 0x2, 0x0, 0x0, 0x1, 0x2}, - {0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1}, - {0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0}, - {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}, - {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3} -}; #endif -#else -static uint8_t -dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS] = { - {0x0, 0x1, 0x2, 0x0, 0x0, 0x1, 0x2}, - {0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x1}, - {0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0}, - {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}, - {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3} }; -#endif /** * @brief Select the type of statistics @@ -321,11 +346,13 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { {TXRX_FW_STATS_INVALID, TXRX_SOC_CFG_PARAMS}, {TXRX_FW_STATS_INVALID, TXRX_PDEV_CFG_PARAMS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS}, {TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_SOC_REO_HW_DESC_DUMP}, }; /* MCL specific functions */ -#ifdef CONFIG_MCL +#if defined(DP_CON_MON) /** * dp_soc_get_mon_mask_for_interrupt_mode() - get mon mode mask for intr mode * @soc: pointer to dp_soc handle @@ -357,23 +384,18 @@ uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx */ static void dp_service_mon_rings(struct dp_soc *soc, uint32_t quota) { - int ring = 0, work_done, mac_id; + int ring = 0, work_done; struct dp_pdev *pdev = NULL; - for (ring = 0 ; ring < MAX_PDEV_CNT; ring++) { - pdev = soc->pdev_list[ring]; + for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) { + pdev = dp_get_pdev_for_lmac_id(soc, ring); if (!pdev) continue; - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - work_done = dp_mon_process(soc, mac_for_pdev, - QCA_NAPI_BUDGET); + work_done = dp_mon_process(soc, ring, quota); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("Reaped %d descs from Monitor rings"), - work_done); - } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + FL("Reaped %d descs from Monitor rings"), + work_done); } } @@ -397,14 +419,22 @@ static void dp_mon_reap_timer_handler(void *arg) #ifndef REMOVE_PKT_LOG /** * dp_pkt_log_init() - API to initialize packet log - * @ppdev: physical device handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @scn: HIF context * * Return: none */ -void dp_pkt_log_init(struct cdp_pdev *ppdev, void *scn) +void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn) { - struct dp_pdev *handle = (struct dp_pdev *)ppdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *handle = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!handle) { + dp_err("pdev handle is NULL"); + return; + } if (handle->pkt_log_init) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -413,6 +443,7 @@ void dp_pkt_log_init(struct cdp_pdev *ppdev, void *scn) } pktlog_sethandle(&handle->pl_dev, scn); + pktlog_set_pdev_id(handle->pl_dev, pdev_id); pktlog_set_callback_regtype(PKTLOG_DEFAULT_CALLBACK_REGISTRATION); if (pktlogmod_init(scn)) { @@ -426,39 +457,19 @@ void dp_pkt_log_init(struct cdp_pdev *ppdev, void *scn) /** * dp_pkt_log_con_service() - connect packet log service - * @ppdev: physical device handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @scn: device context * * Return: none */ -static void dp_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn) +static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *scn) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - - dp_pkt_log_init((struct cdp_pdev *)pdev, scn); + dp_pkt_log_init(soc_hdl, pdev_id, scn); pktlog_htc_attach(); } -/** - * dp_get_num_rx_contexts() - get number of RX contexts - * @soc_hdl: cdp opaque soc handle - * - * Return: number of RX contexts - */ -static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl) -{ - int i; - int num_rx_contexts = 0; - - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - - for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) - if (wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, i)) - num_rx_contexts++; - - return num_rx_contexts; -} - /** * dp_pktlogmod_exit() - API to cleanup pktlog info * @pdev: Pdev handle @@ -477,13 +488,40 @@ static void dp_pktlogmod_exit(struct dp_pdev *pdev) /* stop mon_reap_timer if it has been started */ if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED && - soc->reap_timer_init) + soc->reap_timer_init && (!dp_is_enable_reap_timer_non_pkt(pdev))) qdf_timer_sync_cancel(&soc->mon_reap_timer); pktlogmod_exit(scn); pdev->pkt_log_init = false; } +#else +static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *scn) +{ +} + +static void dp_pktlogmod_exit(struct dp_pdev *handle) { } #endif +/** + * dp_get_num_rx_contexts() - get number of RX contexts + * @soc_hdl: cdp opaque soc handle + * + * Return: number of RX contexts + */ +static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl) +{ + int i; + int num_rx_contexts = 0; + + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) + if (wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, i)) + num_rx_contexts++; + + return num_rx_contexts; +} + #else static void dp_pktlogmod_exit(struct dp_pdev *handle) { } @@ -499,43 +537,101 @@ uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx { return wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, intr_ctx_num); } -#endif -/** - * dp_get_dp_vdev_from_cdp_vdev() - get dp_vdev from cdp_vdev by type-casting - * @cdp_opaque_vdev: pointer to cdp_vdev +/* + * dp_service_lmac_rings()- timer to reap lmac rings + * @arg: SoC Handle + * + * Return: * - * Return: pointer to dp_vdev */ -static -struct dp_vdev *dp_get_dp_vdev_from_cdp_vdev(struct cdp_vdev *cdp_opaque_vdev) +static void dp_service_lmac_rings(void *arg) { - return (struct dp_vdev *)cdp_opaque_vdev; + struct dp_soc *soc = (struct dp_soc *)arg; + int ring = 0, i; + struct dp_pdev *pdev = NULL; + union dp_rx_desc_list_elem_t *desc_list = NULL; + union dp_rx_desc_list_elem_t *tail = NULL; + + /* Process LMAC interrupts */ + for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) { + int mac_for_pdev = ring; + struct dp_srng *rx_refill_buf_ring; + + pdev = dp_get_pdev_for_lmac_id(soc, mac_for_pdev); + if (!pdev) + continue; + + rx_refill_buf_ring = &soc->rx_refill_buf_ring[mac_for_pdev]; + + dp_mon_process(soc, mac_for_pdev, + QCA_NAPI_BUDGET); + + for (i = 0; + i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) + dp_rxdma_err_process(&soc->intr_ctx[i], soc, + mac_for_pdev, + QCA_NAPI_BUDGET); + + if (!dp_soc_ring_if_nss_offloaded(soc, RXDMA_BUF, + mac_for_pdev)) + dp_rx_buffers_replenish(soc, mac_for_pdev, + rx_refill_buf_ring, + &soc->rx_desc_buf[mac_for_pdev], + 0, &desc_list, &tail); + } + + qdf_timer_mod(&soc->lmac_reap_timer, DP_INTR_POLL_TIMER_MS); } +#endif static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl, - struct cdp_peer *peer_hdl, - uint8_t *mac_addr, - enum cdp_txrx_ast_entry_type type, - uint32_t flags) + uint8_t vdev_id, + uint8_t *peer_mac, + uint8_t *mac_addr, + enum cdp_txrx_ast_entry_type type, + uint32_t flags) { - return dp_peer_add_ast((struct dp_soc *)soc_hdl, - (struct dp_peer *)peer_hdl, - mac_addr, - type, - flags); + int ret = -1; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl, + peer_mac, 0, vdev_id); + + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + goto fail; + } + + ret = dp_peer_add_ast((struct dp_soc *)soc_hdl, + peer, + mac_addr, + type, + flags); +fail: + if (peer) + dp_peer_unref_delete(peer); + + return ret; } static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl, - struct cdp_peer *peer_hdl, + uint8_t vdev_id, + uint8_t *peer_mac, uint8_t *wds_macaddr, uint32_t flags) { int status = -1; struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_ast_entry *ast_entry = NULL; - struct dp_peer *peer = (struct dp_peer *)peer_hdl; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl, + peer_mac, 0, vdev_id); + + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + goto fail; + } qdf_spin_lock_bh(&soc->ast_lock); ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr, @@ -546,9 +642,12 @@ static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl, peer, ast_entry, flags); } - qdf_spin_unlock_bh(&soc->ast_lock); +fail: + if (peer) + dp_peer_unref_delete(peer); + return status; } @@ -556,30 +655,39 @@ static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl, * dp_wds_reset_ast_wifi3() - Reset the is_active param for ast entry * @soc_handle: Datapath SOC handle * @wds_macaddr: WDS entry MAC Address - * Return: None + * @peer_macaddr: WDS entry MAC Address + * @vdev_id: id of vdev handle + * Return: QDF_STATUS */ -static void dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl, - uint8_t *wds_macaddr, - uint8_t *peer_mac_addr, - void *vdev_handle) +static QDF_STATUS dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t *wds_macaddr, + uint8_t *peer_mac_addr, + uint8_t vdev_id) { struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_ast_entry *ast_entry = NULL; struct dp_ast_entry *tmp_ast_entry; struct dp_peer *peer; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); if (!vdev) - return; + return QDF_STATUS_E_FAILURE; pdev = vdev->pdev; if (peer_mac_addr) { peer = dp_peer_find_hash_find(soc, peer_mac_addr, 0, vdev->vdev_id); - if (!peer) - return; + if (!peer) { + return QDF_STATUS_E_FAILURE; + } + + if (peer->delete_in_progress) { + dp_peer_unref_delete(peer); + return QDF_STATUS_E_FAILURE; + } + qdf_spin_lock_bh(&soc->ast_lock); DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, tmp_ast_entry) { if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) || @@ -589,6 +697,7 @@ static void dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl, qdf_spin_unlock_bh(&soc->ast_lock); dp_peer_unref_delete(peer); + return QDF_STATUS_SUCCESS; } else if (wds_macaddr) { qdf_spin_lock_bh(&soc->ast_lock); ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr, @@ -601,16 +710,19 @@ static void dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl, } qdf_spin_unlock_bh(&soc->ast_lock); } + + return QDF_STATUS_SUCCESS; } /* * dp_wds_reset_ast_table_wifi3() - Reset the is_active param for all ast entry * @soc: Datapath SOC handle * - * Return: None + * Return: QDF_STATUS */ -static void dp_wds_reset_ast_table_wifi3(struct cdp_soc_t *soc_hdl, - void *vdev_hdl) +static QDF_STATUS +dp_wds_reset_ast_table_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { struct dp_soc *soc = (struct dp_soc *) soc_hdl; struct dp_pdev *pdev; @@ -639,6 +751,8 @@ static void dp_wds_reset_ast_table_wifi3(struct cdp_soc_t *soc_hdl, } qdf_spin_unlock_bh(&soc->ast_lock); + + return QDF_STATUS_SUCCESS; } /* @@ -715,7 +829,7 @@ static bool dp_peer_get_ast_info_by_soc_wifi3 } ast_entry_info->type = ast_entry->type; ast_entry_info->pdev_id = ast_entry->pdev_id; - ast_entry_info->vdev_id = ast_entry->vdev_id; + ast_entry_info->vdev_id = ast_entry->peer->vdev->vdev_id; ast_entry_info->peer_id = ast_entry->peer->peer_ids[0]; qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], &ast_entry->peer->mac_addr.raw[0], @@ -760,7 +874,7 @@ static bool dp_peer_get_ast_info_by_pdevid_wifi3 } ast_entry_info->type = ast_entry->type; ast_entry_info->pdev_id = ast_entry->pdev_id; - ast_entry_info->vdev_id = ast_entry->vdev_id; + ast_entry_info->vdev_id = ast_entry->peer->vdev->vdev_id; ast_entry_info->peer_id = ast_entry->peer->peer_ids[0]; qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], &ast_entry->peer->mac_addr.raw[0], @@ -819,7 +933,7 @@ static QDF_STATUS dp_peer_ast_entry_del_by_soc(struct cdp_soc_t *soc_handle, qdf_spin_unlock_bh(&soc->ast_lock); if (cb) { cb(soc->ctrl_psoc, - soc, + dp_soc_to_cdp_soc(soc), arg, CDP_TXRX_AST_DELETE_IN_PROGRESS); } @@ -881,7 +995,7 @@ static QDF_STATUS dp_peer_ast_entry_del_by_pdev(struct cdp_soc_t *soc_handle, if (cb) { cb(soc->ctrl_psoc, - soc, + dp_soc_to_cdp_soc(soc), arg, CDP_TXRX_AST_DELETE_IN_PROGRESS); } @@ -1066,6 +1180,8 @@ void dp_print_ast_stats(struct dp_soc *soc) DP_PRINT_STATS(" Entries Added = %d", soc->stats.ast.added); DP_PRINT_STATS(" Entries Deleted = %d", soc->stats.ast.deleted); DP_PRINT_STATS(" Entries Agedout = %d", soc->stats.ast.aged_out); + DP_PRINT_STATS(" Entries MAP ERR = %d", soc->stats.ast.map_err); + DP_PRINT_STATS("AST Table:"); qdf_spin_lock_bh(&soc->ast_lock); @@ -1075,29 +1191,29 @@ void dp_print_ast_stats(struct dp_soc *soc) DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) { DP_VDEV_ITERATE_PEER_LIST(vdev, peer) { DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) { - DP_PRINT_STATS("%6d mac_addr = %pM" - " peer_mac_addr = %pM" - " peer_id = %u" - " type = %s" - " next_hop = %d" - " is_active = %d" - " ast_idx = %d" - " ast_hash = %d" - " delete_in_progress = %d" - " pdev_id = %d" - " vdev_id = %d", - ++num_entries, - ase->mac_addr.raw, - ase->peer->mac_addr.raw, - ase->peer->peer_ids[0], - type[ase->type], - ase->next_hop, - ase->is_active, - ase->ast_idx, - ase->ast_hash_value, - ase->delete_in_progress, - ase->pdev_id, - vdev->vdev_id); + DP_PRINT_STATS("%6d mac_addr = "QDF_MAC_ADDR_FMT + " peer_mac_addr = "QDF_MAC_ADDR_FMT + " peer_id = %u" + " type = %s" + " next_hop = %d" + " is_active = %d" + " ast_idx = %d" + " ast_hash = %d" + " delete_in_progress = %d" + " pdev_id = %d" + " vdev_id = %d", + ++num_entries, + QDF_MAC_ADDR_REF(ase->mac_addr.raw), + QDF_MAC_ADDR_REF(ase->peer->mac_addr.raw), + ase->peer->peer_ids[0], + type[ase->type], + ase->next_hop, + ase->is_active, + ase->ast_idx, + ase->ast_hash_value, + ase->delete_in_progress, + ase->pdev_id, + vdev->vdev_id); } } } @@ -1129,101 +1245,25 @@ static void dp_print_peer_table(struct dp_vdev *vdev) DP_PRINT_STATS("Invalid Peer"); return; } - DP_PRINT_STATS(" peer_mac_addr = %pM" + DP_PRINT_STATS(" peer_mac_addr = "QDF_MAC_ADDR_FMT " nawds_enabled = %d" " bss_peer = %d" - " wapi = %d" " wds_enabled = %d" + " tx_cap_enabled = %d" + " rx_cap_enabled = %d" " delete in progress = %d" " peer id = %d", - peer->mac_addr.raw, + QDF_MAC_ADDR_REF(peer->mac_addr.raw), peer->nawds_enabled, peer->bss_peer, - peer->wapi, peer->wds_enabled, + peer->tx_cap_enabled, + peer->rx_cap_enabled, peer->delete_in_progress, peer->peer_ids[0]); } } -/* - * dp_srng_mem_alloc() - Allocate memory for SRNG - * @soc : Data path soc handle - * @srng : SRNG pointer - * @align : Align size - * - * return: QDF_STATUS_SUCCESS on successful allocation - * QDF_STATUS_E_NOMEM on failure - */ -static QDF_STATUS -dp_srng_mem_alloc(struct dp_soc *soc, struct dp_srng *srng, uint32_t align, - bool cached) -{ - uint32_t align_alloc_size; - - if (!cached) { - srng->base_vaddr_unaligned = - qdf_mem_alloc_consistent(soc->osdev, - soc->osdev->dev, - srng->alloc_size, - &srng->base_paddr_unaligned); - } else { - srng->base_vaddr_unaligned = qdf_mem_malloc(srng->alloc_size); - srng->base_paddr_unaligned = - qdf_mem_virt_to_phys(srng->base_vaddr_unaligned); - } - - if (!srng->base_vaddr_unaligned) { - return QDF_STATUS_E_NOMEM; - } - - /* Re-allocate additional bytes to align base address only if - * above allocation returns unaligned address. Reason for - * trying exact size allocation above is, OS tries to allocate - * blocks of size power-of-2 pages and then free extra pages. - * e.g., of a ring size of 1MB, the allocation below will - * request 1MB plus 7 bytes for alignment, which will cause a - * 2MB block allocation,and that is failing sometimes due to - * memory fragmentation. - * dp_srng_mem_alloc should be replaced with - * qdf_aligned_mem_alloc_consistent after fixing some known - * shortcomings with this QDF function - */ - if ((unsigned long)(srng->base_paddr_unaligned) & - (align - 1)) { - align_alloc_size = srng->alloc_size + align - 1; - - if (!cached) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - srng->alloc_size, - srng->base_vaddr_unaligned, - srng->base_paddr_unaligned, 0); - - srng->base_vaddr_unaligned = - qdf_mem_alloc_consistent(soc->osdev, - soc->osdev->dev, - align_alloc_size, - &srng->base_paddr_unaligned); - - } else { - qdf_mem_free(srng->base_vaddr_unaligned); - srng->base_vaddr_unaligned = - qdf_mem_malloc(align_alloc_size); - - srng->base_paddr_unaligned = - qdf_mem_virt_to_phys(srng->base_vaddr_unaligned); - } - - srng->alloc_size = align_alloc_size; - - if (!srng->base_vaddr_unaligned) { - return QDF_STATUS_E_NOMEM; - } - } - - return QDF_STATUS_SUCCESS; -} - #ifdef WLAN_DP_PER_RING_TYPE_CONFIG /** * dp_srng_configure_interrupt_thresholds() - Retrieve interrupt @@ -1304,6 +1344,191 @@ dp_srng_configure_interrupt_thresholds(struct dp_soc *soc, } #endif + +#ifdef DP_MEM_PRE_ALLOC +void *dp_context_alloc_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + size_t ctxt_size) +{ + void *ctxt_mem; + + if (!soc->cdp_soc.ol_ops->dp_prealloc_get_context) { + dp_warn("dp_prealloc_get_context null!"); + goto dynamic_alloc; + } + + ctxt_mem = soc->cdp_soc.ol_ops->dp_prealloc_get_context(ctxt_type); + + if (ctxt_mem) + goto end; + +dynamic_alloc: + dp_info("Pre-alloc of ctxt failed. Dynamic allocation"); + ctxt_mem = qdf_mem_malloc(ctxt_size); +end: + return ctxt_mem; +} + +void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type, + void *vaddr) +{ + QDF_STATUS status; + + if (soc->cdp_soc.ol_ops->dp_prealloc_put_context) { + status = soc->cdp_soc.ol_ops->dp_prealloc_put_context( + ctxt_type, + vaddr); + } else { + dp_warn("dp_prealloc_get_context null!"); + status = QDF_STATUS_E_NOSUPPORT; + } + + if (QDF_IS_STATUS_ERROR(status)) { + dp_info("Context not pre-allocated"); + qdf_mem_free(vaddr); + } +} + +static inline +void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc, + struct dp_srng *srng, + struct hal_srng_params *ring_params, + uint32_t ring_type) +{ + void *mem; + + qdf_assert(!srng->is_mem_prealloc); + + if (!soc->cdp_soc.ol_ops->dp_prealloc_get_consistent) { + dp_warn("dp_prealloc_get_consistent is null!"); + goto qdf; + } + + mem = + soc->cdp_soc.ol_ops->dp_prealloc_get_consistent + (&srng->alloc_size, + &srng->base_vaddr_unaligned, + &srng->base_paddr_unaligned, + &ring_params->ring_base_paddr, + DP_RING_BASE_ALIGN, ring_type); + + if (mem) { + srng->is_mem_prealloc = true; + goto end; + } +qdf: + mem = qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size, + &srng->base_vaddr_unaligned, + &srng->base_paddr_unaligned, + &ring_params->ring_base_paddr, + DP_RING_BASE_ALIGN); +end: + dp_info("%s memory %pK dp_srng %pK alloc_size %d num_entries %d", + srng->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", mem, + srng, srng->alloc_size, srng->num_entries); + return mem; +} + +static inline void dp_srng_mem_free_consistent(struct dp_soc *soc, + struct dp_srng *srng) +{ + if (srng->is_mem_prealloc) { + if (!soc->cdp_soc.ol_ops->dp_prealloc_put_consistent) { + dp_warn("dp_prealloc_put_consistent is null!"); + QDF_BUG(0); + return; + } + soc->cdp_soc.ol_ops->dp_prealloc_put_consistent + (srng->alloc_size, + srng->base_vaddr_unaligned, + srng->base_paddr_unaligned); + + } else { + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + srng->alloc_size, + srng->base_vaddr_unaligned, + srng->base_paddr_unaligned, 0); + } +} + +void dp_desc_multi_pages_mem_alloc(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + size_t element_size, + uint16_t element_num, + qdf_dma_context_t memctxt, + bool cacheable) +{ + if (!soc->cdp_soc.ol_ops->dp_get_multi_pages) { + dp_warn("dp_get_multi_pages is null!"); + goto qdf; + } + + pages->num_pages = 0; + pages->is_mem_prealloc = 0; + soc->cdp_soc.ol_ops->dp_get_multi_pages(desc_type, + element_size, + element_num, + pages, + cacheable); + if (pages->num_pages) + goto end; + +qdf: + qdf_mem_multi_pages_alloc(soc->osdev, pages, element_size, + element_num, memctxt, cacheable); +end: + dp_info("%s desc_type %d element_size %d element_num %d cacheable %d", + pages->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", + desc_type, (int)element_size, element_num, cacheable); +} + +void dp_desc_multi_pages_mem_free(struct dp_soc *soc, + enum dp_desc_type desc_type, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, + bool cacheable) +{ + if (pages->is_mem_prealloc) { + if (!soc->cdp_soc.ol_ops->dp_put_multi_pages) { + dp_warn("dp_put_multi_pages is null!"); + QDF_BUG(0); + return; + } + + soc->cdp_soc.ol_ops->dp_put_multi_pages(desc_type, pages); + qdf_mem_zero(pages, sizeof(*pages)); + } else { + qdf_mem_multi_pages_free(soc->osdev, pages, + memctxt, cacheable); + } +} + +#else + +static inline +void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc, + struct dp_srng *srng, + struct hal_srng_params *ring_params, + uint32_t ring_type) + +{ + return qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size, + &srng->base_vaddr_unaligned, + &srng->base_paddr_unaligned, + &ring_params->ring_base_paddr, + DP_RING_BASE_ALIGN); +} + +static inline void dp_srng_mem_free_consistent(struct dp_soc *soc, + struct dp_srng *srng) +{ + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + srng->alloc_size, + srng->base_vaddr_unaligned, + srng->base_paddr_unaligned, 0); +} + +#endif /* DP_MEM_PRE_ALLOC */ /** * dp_srng_setup() - Internal function to setup SRNG rings used by data path * @soc: datapath soc handle @@ -1318,17 +1543,15 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng, int ring_type, int ring_num, int mac_id, uint32_t num_entries, bool cached) { - void *hal_soc = soc->hal_soc; + hal_soc_handle_t hal_soc = soc->hal_soc; uint32_t entry_size = hal_srng_get_entrysize(hal_soc, ring_type); - /* TODO: See if we should get align size from hal */ - uint32_t ring_base_align = 8; struct hal_srng_params ring_params; uint32_t max_entries = hal_srng_max_entries(hal_soc, ring_type); /* TODO: Currently hal layer takes care of endianness related settings. * See if these settings need to passed from DP layer */ - ring_params.flags = 0; + qdf_mem_zero(&ring_params, sizeof(struct hal_srng_params)); num_entries = (num_entries > max_entries) ? max_entries : num_entries; srng->hal_srng = NULL; @@ -1336,32 +1559,45 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng, srng->num_entries = num_entries; if (!dp_is_soc_reinit(soc)) { - if (dp_srng_mem_alloc(soc, srng, ring_base_align, cached) != - QDF_STATUS_SUCCESS) { + if (!cached) { + ring_params.ring_base_vaddr = + dp_srng_aligned_mem_alloc_consistent(soc, srng, + &ring_params, + ring_type); + } else { + ring_params.ring_base_vaddr = qdf_aligned_malloc( + &srng->alloc_size, + &srng->base_vaddr_unaligned, + &srng->base_paddr_unaligned, + &ring_params.ring_base_paddr, + DP_RING_BASE_ALIGN); + } + + if (!ring_params.ring_base_vaddr) { dp_err("alloc failed - ring_type: %d, ring_num %d", - ring_type, ring_num); + ring_type, ring_num); return QDF_STATUS_E_NOMEM; } - } - ring_params.ring_base_paddr = - (qdf_dma_addr_t)qdf_align( + ring_params.ring_base_paddr = (qdf_dma_addr_t)qdf_align( (unsigned long)(srng->base_paddr_unaligned), - ring_base_align); + DP_RING_BASE_ALIGN); - ring_params.ring_base_vaddr = - (void *)((unsigned long)(srng->base_vaddr_unaligned) + + ring_params.ring_base_vaddr = (void *)( + (unsigned long)(srng->base_vaddr_unaligned) + ((unsigned long)(ring_params.ring_base_paddr) - - (unsigned long)(srng->base_paddr_unaligned))); + (unsigned long)(srng->base_paddr_unaligned))); + + qdf_assert_always(ring_params.ring_base_vaddr); ring_params.num_entries = num_entries; - dp_verbose_debug("Ring type: %d, num:%d vaddr %pK paddr %pK entries %u", - ring_type, ring_num, - (void *)ring_params.ring_base_vaddr, - (void *)ring_params.ring_base_paddr, - ring_params.num_entries); + dp_info("Ring type: %d, num:%d vaddr %pK paddr %pK entries %u", + ring_type, ring_num, + (void *)ring_params.ring_base_vaddr, + (void *)ring_params.ring_base_paddr, + ring_params.num_entries); if (soc->intr_mode == DP_INTR_MSI) { dp_srng_msi_setup(soc, &ring_params, ring_type, ring_num); @@ -1391,10 +1627,7 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng, if (cached) { qdf_mem_free(srng->base_vaddr_unaligned); } else { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - srng->alloc_size, - srng->base_vaddr_unaligned, - srng->base_paddr_unaligned, 0); + dp_srng_mem_free_consistent(soc, srng); } } @@ -1448,10 +1681,7 @@ static void dp_srng_cleanup(struct dp_soc *soc, struct dp_srng *srng, if (srng->alloc_size && srng->base_vaddr_unaligned) { if (!srng->cached) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - srng->alloc_size, - srng->base_vaddr_unaligned, - srng->base_paddr_unaligned, 0); + dp_srng_mem_free_consistent(soc, srng); } else { qdf_mem_free(srng->base_vaddr_unaligned); } @@ -1462,39 +1692,39 @@ static void dp_srng_cleanup(struct dp_soc *soc, struct dp_srng *srng, } /* TODO: Need this interface from HIF */ -void *hif_get_hal_handle(void *hif_handle); +void *hif_get_hal_handle(struct hif_opaque_softc *hif_handle); #ifdef WLAN_FEATURE_DP_EVENT_HISTORY int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, - void *hal_ring) + hal_ring_handle_t hal_ring_hdl) { - void *hal_soc = dp_soc->hal_soc; + hal_soc_handle_t hal_soc = dp_soc->hal_soc; uint32_t hp, tp; uint8_t ring_id; - hal_get_sw_hptp(hal_soc, hal_ring, &tp, &hp); - ring_id = hal_srng_ring_id_get(hal_ring); + hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); + ring_id = hal_srng_ring_id_get(hal_ring_hdl); hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id, ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_START); - return hal_srng_access_start(hal_soc, hal_ring); + return hal_srng_access_start(hal_soc, hal_ring_hdl); } void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc, - void *hal_ring) + hal_ring_handle_t hal_ring_hdl) { - void *hal_soc = dp_soc->hal_soc; + hal_soc_handle_t hal_soc = dp_soc->hal_soc; uint32_t hp, tp; uint8_t ring_id; - hal_get_sw_hptp(hal_soc, hal_ring, &tp, &hp); - ring_id = hal_srng_ring_id_get(hal_ring); + hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); + ring_id = hal_srng_ring_id_get(hal_ring_hdl); hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id, ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_END); - return hal_srng_access_end(hal_soc, hal_ring); + return hal_srng_access_end(hal_soc, hal_ring_hdl); } #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ @@ -1537,59 +1767,61 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget) uint32_t work_done = 0; int budget = total_budget; int ring = 0; - int mac_id; /* Process LMAC interrupts */ - for (ring = 0 ; ring < MAX_PDEV_CNT; ring++) { - pdev = soc->pdev_list[ring]; + for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) { + int mac_for_pdev = ring; + + pdev = dp_get_pdev_for_lmac_id(soc, mac_for_pdev); if (!pdev) continue; - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - if (int_ctx->rx_mon_ring_mask & (1 << mac_for_pdev)) { - work_done = dp_mon_process(soc, mac_for_pdev, - remaining_quota); - if (work_done) - intr_stats->num_rx_mon_ring_masks++; - budget -= work_done; - if (budget <= 0) - goto budget_done; - remaining_quota = budget; - } + if (int_ctx->rx_mon_ring_mask & (1 << mac_for_pdev)) { + work_done = dp_mon_process(soc, mac_for_pdev, + remaining_quota); + if (work_done) + intr_stats->num_rx_mon_ring_masks++; + budget -= work_done; + if (budget <= 0) + goto budget_done; + remaining_quota = budget; + } - if (int_ctx->rxdma2host_ring_mask & - (1 << mac_for_pdev)) { - work_done = dp_rxdma_err_process(int_ctx, soc, - mac_for_pdev, - remaining_quota); - if (work_done) - intr_stats->num_rxdma2host_ring_masks++; - budget -= work_done; - if (budget <= 0) - goto budget_done; - remaining_quota = budget; - } + if (int_ctx->rxdma2host_ring_mask & + (1 << mac_for_pdev)) { + work_done = dp_rxdma_err_process(int_ctx, soc, + mac_for_pdev, + remaining_quota); + if (work_done) + intr_stats->num_rxdma2host_ring_masks++; + budget -= work_done; + if (budget <= 0) + goto budget_done; + remaining_quota = budget; + } - if (int_ctx->host2rxdma_ring_mask & - (1 << mac_for_pdev)) { - union dp_rx_desc_list_elem_t *desc_list = NULL; - union dp_rx_desc_list_elem_t *tail = NULL; - struct dp_srng *rx_refill_buf_ring = - &pdev->rx_refill_buf_ring; - - intr_stats->num_host2rxdma_ring_masks++; - DP_STATS_INC(pdev, replenish.low_thresh_intrs, - 1); - dp_rx_buffers_replenish(soc, mac_for_pdev, - rx_refill_buf_ring, - &soc->rx_desc_buf[mac_for_pdev], - 0, &desc_list, &tail); - } + if (int_ctx->host2rxdma_ring_mask & + (1 << mac_for_pdev)) { + union dp_rx_desc_list_elem_t *desc_list = NULL; + union dp_rx_desc_list_elem_t *tail = NULL; + struct dp_srng *rx_refill_buf_ring; + + if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) + rx_refill_buf_ring = + &soc->rx_refill_buf_ring[mac_for_pdev]; + else + rx_refill_buf_ring = + &soc->rx_refill_buf_ring[pdev->lmac_id]; + + intr_stats->num_host2rxdma_ring_masks++; + DP_STATS_INC(pdev, replenish.low_thresh_intrs, + 1); + dp_rx_buffers_replenish(soc, mac_for_pdev, + rx_refill_buf_ring, + &soc->rx_desc_buf[mac_for_pdev], + 0, &desc_list, &tail); } } - budget_done: return total_budget - budget; } @@ -1792,7 +2024,7 @@ static void dp_interrupt_timer(void *arg) * * Return: 0 for success, nonzero for failure. */ -static QDF_STATUS dp_soc_attach_poll(void *txrx_soc) +static QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; @@ -1837,7 +2069,7 @@ static void dp_soc_set_interrupt_mode(struct dp_soc *soc) uint32_t msi_base_data, msi_vector_start; int msi_vector_count, ret; - soc->intr_mode = DP_INTR_LEGACY; + soc->intr_mode = DP_INTR_INTEGRATED; if (!(soc->wlan_cfg_ctx->napi_enabled) || (soc->cdp_soc.ol_ops->get_con_mode && @@ -1855,8 +2087,8 @@ static void dp_soc_set_interrupt_mode(struct dp_soc *soc) } } -static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc); -#if defined(CONFIG_MCL) +static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc); +#if defined(DP_INTR_POLL_BOTH) /* * dp_soc_interrupt_attach_wrapper() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle @@ -1866,7 +2098,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc); * * Return: 0 for success. nonzero for failure. */ -static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -1874,24 +2106,21 @@ static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) (soc->cdp_soc.ol_ops->get_con_mode && soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s: Poll mode", __func__); + dp_info("Poll mode"); return dp_soc_attach_poll(txrx_soc); } else { - - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s: Interrupt mode", __func__); + dp_info("Interrupt mode"); return dp_soc_interrupt_attach(txrx_soc); } } #else #if defined(DP_INTR_POLL_BASED) && DP_INTR_POLL_BASED -static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) { return dp_soc_attach_poll(txrx_soc); } #else -static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -1928,7 +2157,7 @@ static void dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc, int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask( soc->wlan_cfg_ctx, intr_ctx_num); - soc->intr_mode = DP_INTR_LEGACY; + soc->intr_mode = DP_INTR_INTEGRATED; for (j = 0; j < HIF_MAX_GRP_IRQ; j++) { @@ -1944,29 +2173,24 @@ static void dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc, if (rxdma2host_ring_mask & (1 << j)) { irq_id_map[num_irq++] = - rxdma2host_destination_ring_mac1 - - wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + rxdma2host_destination_ring_mac1 - j; } if (host2rxdma_ring_mask & (1 << j)) { irq_id_map[num_irq++] = - host2rxdma_host_buf_ring_mac1 - - wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + host2rxdma_host_buf_ring_mac1 - j; } if (host2rxdma_mon_ring_mask & (1 << j)) { irq_id_map[num_irq++] = - host2rxdma_monitor_ring1 - - wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + host2rxdma_monitor_ring1 - j; } if (rx_mon_mask & (1 << j)) { irq_id_map[num_irq++] = - ppdu_end_interrupts_mac1 - - wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + ppdu_end_interrupts_mac1 - j; irq_id_map[num_irq++] = - rxdma2host_monitor_status_ring_mac1 - - wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + rxdma2host_monitor_status_ring_mac1 - j; } if (rx_wbm_rel_ring_mask & (1 << j)) @@ -2045,7 +2269,7 @@ static void dp_soc_interrupt_map_calculate(struct dp_soc *soc, int intr_ctx_num, * * Return: 0 for success. nonzero for failure. */ -static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -2112,7 +2336,6 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) } hif_configure_ext_group_interrupts(soc->hif_handle); - hif_config_irq_set_perf_affinity_hint(soc->hif_handle); return QDF_STATUS_SUCCESS; } @@ -2121,9 +2344,9 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) * dp_soc_interrupt_detach() - Deregister any allocations done for interrupts * @txrx_soc: DP SOC handle * - * Return: void + * Return: none */ -static void dp_soc_interrupt_detach(void *txrx_soc) +static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; @@ -2131,6 +2354,7 @@ static void dp_soc_interrupt_detach(void *txrx_soc) if (soc->intr_mode == DP_INTR_POLL) { qdf_timer_free(&soc->int_timer); } else { + hif_deconfigure_ext_group_interrupts(soc->hif_handle); hif_deregister_exec_group(soc->hif_handle, "dp_intr"); } @@ -2174,12 +2398,16 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) uint32_t total_link_descs, total_mem_size; uint32_t num_mpdu_link_descs, num_mpdu_queue_descs; uint32_t num_tx_msdu_link_descs, num_rx_msdu_link_descs; - uint32_t num_link_desc_banks; - uint32_t last_bank_size = 0; uint32_t entry_size, num_entries; int i; - uint32_t desc_id = 0; + uint32_t cookie = 0; qdf_dma_addr_t *baseaddr = NULL; + uint32_t page_idx = 0; + struct qdf_mem_multi_page_t *pages; + struct qdf_mem_dma_page_t *dma_pages; + uint32_t offset = 0; + uint32_t count = 0; + uint32_t num_descs_per_page; /* Only Tx queue descriptors are allocated from common link descriptor * pool Rx queue descriptors are not included in this because (REO queue @@ -2214,86 +2442,28 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) total_mem_size += link_desc_align; - if (total_mem_size <= max_alloc_size) { - num_link_desc_banks = 0; - last_bank_size = total_mem_size; - } else { - num_link_desc_banks = (total_mem_size) / - (max_alloc_size - link_desc_align); - last_bank_size = total_mem_size % - (max_alloc_size - link_desc_align); - } - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("total_mem_size: %d, num_link_desc_banks: %u"), - total_mem_size, num_link_desc_banks); - - for (i = 0; i < num_link_desc_banks; i++) { - if (!dp_is_soc_reinit(soc)) { - baseaddr = &soc->link_desc_banks[i]. - base_paddr_unaligned; - soc->link_desc_banks[i].base_vaddr_unaligned = - qdf_mem_alloc_consistent(soc->osdev, - soc->osdev->dev, - max_alloc_size, - baseaddr); - } - soc->link_desc_banks[i].size = max_alloc_size; - - soc->link_desc_banks[i].base_vaddr = (void *)((unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned) + - ((unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned) % - link_desc_align)); - - soc->link_desc_banks[i].base_paddr = (unsigned long)( - soc->link_desc_banks[i].base_paddr_unaligned) + - ((unsigned long)(soc->link_desc_banks[i].base_vaddr) - - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned)); - - if (!soc->link_desc_banks[i].base_vaddr_unaligned) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("Link descriptor memory alloc failed")); - goto fail; - } - qdf_minidump_log((void *)(soc->link_desc_banks[i].base_vaddr), - soc->link_desc_banks[i].size, "link_desc_bank"); - } + FL("total_mem_size: %d"), total_mem_size); - if (last_bank_size) { - /* Allocate last bank in case total memory required is not exact - * multiple of max_alloc_size - */ - if (!dp_is_soc_reinit(soc)) { - baseaddr = &soc->link_desc_banks[i]. - base_paddr_unaligned; - soc->link_desc_banks[i].base_vaddr_unaligned = - qdf_mem_alloc_consistent(soc->osdev, - soc->osdev->dev, - last_bank_size, - baseaddr); + pages = &soc->link_desc_pages; + dp_set_max_page_size(pages, max_alloc_size); + if (!dp_is_soc_reinit(soc)) { + dp_desc_multi_pages_mem_alloc(soc, DP_HW_LINK_DESC_TYPE, + pages, + link_desc_size, + total_link_descs, + 0, false); + if (!pages->num_pages) { + dp_err("Multi page alloc fail for hw link desc pool"); + goto fail_page_alloc; } - soc->link_desc_banks[i].size = last_bank_size; - - soc->link_desc_banks[i].base_vaddr = (void *)((unsigned long) - (soc->link_desc_banks[i].base_vaddr_unaligned) + - ((unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned) % - link_desc_align)); - - soc->link_desc_banks[i].base_paddr = - (unsigned long)( - soc->link_desc_banks[i].base_paddr_unaligned) + - ((unsigned long)(soc->link_desc_banks[i].base_vaddr) - - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned)); - - qdf_minidump_log((void *)(soc->link_desc_banks[i].base_vaddr), - soc->link_desc_banks[i].size, "link_desc_bank"); + qdf_minidump_log( + (void *)(pages->dma_pages->page_v_addr_start), + pages->num_pages * + sizeof(struct qdf_mem_dma_page_t), + "hw_link_desc_bank"); } - /* Allocate and setup link descriptor idle list for HW internal use */ entry_size = hal_srng_get_entrysize(soc->hal_soc, WBM_IDLE_LINK); total_mem_size = entry_size * total_link_descs; @@ -2308,34 +2478,33 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) goto fail; } - qdf_minidump_log( - (void *)(soc->wbm_idle_link_ring.base_vaddr_unaligned), - soc->wbm_idle_link_ring.alloc_size, - "wbm_idle_link_ring"); + qdf_minidump_log(soc->wbm_idle_link_ring.base_vaddr_unaligned, + soc->wbm_idle_link_ring.alloc_size, + "wbm_idle_link_ring"); hal_srng_access_start_unlocked(soc->hal_soc, soc->wbm_idle_link_ring.hal_srng); - - for (i = 0; i < MAX_LINK_DESC_BANKS && - soc->link_desc_banks[i].base_paddr; i++) { - uint32_t num_entries = (soc->link_desc_banks[i].size - - ((unsigned long)( - soc->link_desc_banks[i].base_vaddr) - - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned))) - / link_desc_size; - unsigned long paddr = (unsigned long)( - soc->link_desc_banks[i].base_paddr); - - while (num_entries && (desc = hal_srng_src_get_next( + page_idx = 0; count = 0; + offset = 0; + pages = &soc->link_desc_pages; + if (pages->dma_pages) + dma_pages = pages->dma_pages; + else + goto fail; + num_descs_per_page = + pages->num_element_per_page; + while ((desc = hal_srng_src_get_next( soc->hal_soc, - soc->wbm_idle_link_ring.hal_srng))) { - hal_set_link_desc_addr(desc, - LINK_DESC_COOKIE(desc_id, i), paddr); - num_entries--; - desc_id++; - paddr += link_desc_size; - } + soc->wbm_idle_link_ring.hal_srng)) && + (count < total_link_descs)) { + page_idx = count / num_descs_per_page; + offset = count % num_descs_per_page; + cookie = LINK_DESC_COOKIE(count, page_idx); + hal_set_link_desc_addr( + desc, cookie, + dma_pages[page_idx].page_p_addr + + (offset * link_desc_size)); + count++; } hal_srng_access_end_unlocked(soc->hal_soc, soc->wbm_idle_link_ring.hal_srng); @@ -2387,40 +2556,38 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) scatter_buf_ptr = (uint8_t *)( soc->wbm_idle_scatter_buf_base_vaddr[scatter_buf_num]); rem_entries = num_entries_per_buf; - - for (i = 0; i < MAX_LINK_DESC_BANKS && - soc->link_desc_banks[i].base_paddr; i++) { - uint32_t num_link_descs = - (soc->link_desc_banks[i].size - - ((unsigned long)( - soc->link_desc_banks[i].base_vaddr) - - (unsigned long)( - soc->link_desc_banks[i].base_vaddr_unaligned))) - / link_desc_size; - unsigned long paddr = (unsigned long)( - soc->link_desc_banks[i].base_paddr); - - while (num_link_descs) { - hal_set_link_desc_addr((void *)scatter_buf_ptr, - LINK_DESC_COOKIE(desc_id, i), paddr); - num_link_descs--; - desc_id++; - paddr += link_desc_size; - rem_entries--; - if (rem_entries) { - scatter_buf_ptr += entry_size; - } else { - rem_entries = num_entries_per_buf; - scatter_buf_num++; - - if (scatter_buf_num >= num_scatter_bufs) - break; - - scatter_buf_ptr = (uint8_t *)( - soc->wbm_idle_scatter_buf_base_vaddr[ - scatter_buf_num]); - } + pages = &soc->link_desc_pages; + page_idx = 0; count = 0; + offset = 0; + num_descs_per_page = + pages->num_element_per_page; + if (pages->dma_pages) + dma_pages = pages->dma_pages; + else + goto fail; + while (count < total_link_descs) { + page_idx = count / num_descs_per_page; + offset = count % num_descs_per_page; + cookie = LINK_DESC_COOKIE(count, page_idx); + hal_set_link_desc_addr( + (void *)scatter_buf_ptr, + cookie, + dma_pages[page_idx].page_p_addr + + (offset * link_desc_size)); + rem_entries--; + if (rem_entries) { + scatter_buf_ptr += entry_size; + } else { + rem_entries = num_entries_per_buf; + scatter_buf_num++; + if (scatter_buf_num >= num_scatter_bufs) + break; + scatter_buf_ptr = + (uint8_t *) + (soc->wbm_idle_scatter_buf_base_vaddr[ + scatter_buf_num]); } + count++; } /* Setup link descriptor idle list in HW */ hal_setup_link_idle_list(soc->hal_soc, @@ -2449,17 +2616,15 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) } } - for (i = 0; i < MAX_LINK_DESC_BANKS; i++) { - if (soc->link_desc_banks[i].base_vaddr_unaligned) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - soc->link_desc_banks[i].size, - soc->link_desc_banks[i].base_vaddr_unaligned, - soc->link_desc_banks[i].base_paddr_unaligned, - 0); - soc->link_desc_banks[i].base_vaddr_unaligned = NULL; - } - } + pages = &soc->link_desc_pages; + qdf_minidump_remove( + (void *)pages->dma_pages->page_v_addr_start); + dp_desc_multi_pages_mem_free(soc, DP_HW_LINK_DESC_TYPE, + pages, 0, false); return QDF_STATUS_E_FAILURE; + +fail_page_alloc: + return QDF_STATUS_E_FAULT; } /* @@ -2468,8 +2633,11 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc) { int i; + struct qdf_mem_multi_page_t *pages; if (soc->wbm_idle_link_ring.hal_srng) { + qdf_minidump_remove( + soc->wbm_idle_link_ring.base_vaddr_unaligned); dp_srng_cleanup(soc, &soc->wbm_idle_link_ring, WBM_IDLE_LINK, 0); } @@ -2484,34 +2652,33 @@ static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc) } } - for (i = 0; i < MAX_LINK_DESC_BANKS; i++) { - if (soc->link_desc_banks[i].base_vaddr_unaligned) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - soc->link_desc_banks[i].size, - soc->link_desc_banks[i].base_vaddr_unaligned, - soc->link_desc_banks[i].base_paddr_unaligned, - 0); - soc->link_desc_banks[i].base_vaddr_unaligned = NULL; - } - } + pages = &soc->link_desc_pages; + qdf_minidump_remove( + (void *)pages->dma_pages->page_v_addr_start); + dp_desc_multi_pages_mem_free(soc, DP_HW_LINK_DESC_TYPE, + pages, 0, false); } #ifdef IPA_OFFLOAD #define REO_DST_RING_SIZE_QCA6290 1023 -#ifndef QCA_WIFI_QCA8074_VP +#ifndef CONFIG_WIFI_EMULATION_WIFI_3_0 #define REO_DST_RING_SIZE_QCA8074 1023 +#define REO_DST_RING_SIZE_QCN9000 2048 #else #define REO_DST_RING_SIZE_QCA8074 8 -#endif /* QCA_WIFI_QCA8074_VP */ +#define REO_DST_RING_SIZE_QCN9000 8 +#endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */ #else #define REO_DST_RING_SIZE_QCA6290 1024 -#ifndef QCA_WIFI_QCA8074_VP +#ifndef CONFIG_WIFI_EMULATION_WIFI_3_0 #define REO_DST_RING_SIZE_QCA8074 2048 +#define REO_DST_RING_SIZE_QCN9000 2048 #else #define REO_DST_RING_SIZE_QCA8074 8 -#endif /* QCA_WIFI_QCA8074_VP */ +#define REO_DST_RING_SIZE_QCN9000 8 +#endif /* CONFIG_WIFI_EMULATION_WIFI_3_0 */ #endif /* IPA_OFFLOAD */ #ifndef FEATURE_WDS @@ -2600,6 +2767,38 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc, enum hal_ring_ty return status; } +/* + * dp_soc_disable_mac2_intr_mask() - reset interrupt mask for WMAC2 hw rings + * @dp_soc - DP Soc handle + * + * Return: Return void + */ +static void dp_soc_disable_mac2_intr_mask(struct dp_soc *soc) +{ + int *grp_mask = NULL; + int group_number; + + grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_ring_mask[0]; + group_number = dp_srng_find_ring_in_mask(0x2, grp_mask); + wlan_cfg_set_host2rxdma_ring_mask(soc->wlan_cfg_ctx, + group_number, 0x0); + + grp_mask = &soc->wlan_cfg_ctx->int_rx_mon_ring_mask[0]; + group_number = dp_srng_find_ring_in_mask(0x2, grp_mask); + wlan_cfg_set_rx_mon_ring_mask(soc->wlan_cfg_ctx, + group_number, 0x0); + + grp_mask = &soc->wlan_cfg_ctx->int_rxdma2host_ring_mask[0]; + group_number = dp_srng_find_ring_in_mask(0x2, grp_mask); + wlan_cfg_set_rxdma2host_ring_mask(soc->wlan_cfg_ctx, + group_number, 0x0); + + grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[0]; + group_number = dp_srng_find_ring_in_mask(0x2, grp_mask); + wlan_cfg_set_host2rxdma_mon_ring_mask(soc->wlan_cfg_ctx, + group_number, 0x0); +} + /* * dp_soc_reset_intr_mask() - reset interrupt mask * @dp_soc - DP Soc handle @@ -2689,6 +2888,8 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc) /* loop and reset the mask for only offloaded ring */ for (j = 0; j < MAX_PDEV_CNT; j++) { + int lmac_id = wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j); + if (!dp_soc_ring_if_nss_offloaded(soc, RXDMA_BUF, j)) { continue; } @@ -2696,18 +2897,18 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc) /* * Group number corresponding to rx offloaded ring. */ - group_number = dp_srng_find_ring_in_mask(j, grp_mask); + group_number = dp_srng_find_ring_in_mask(lmac_id, grp_mask); if (group_number < 0) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, FL("ring not part of any group; ring_type: %d,ring_num %d"), - REO_DST, j); + REO_DST, lmac_id); return; } /* set the interrupt mask for offloaded ring */ mask = wlan_cfg_get_host2rxdma_ring_mask(soc->wlan_cfg_ctx, group_number); - mask &= (~(1 << j)); + mask &= (~(1 << lmac_id)); /* * set the interrupt mask to zero for rx offloaded radio. @@ -2735,53 +2936,126 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc) */ bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, uint32_t *remap2) { - *remap1 = ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x1 << 9) | - (0x2 << 12) | (0x3 << 15) | (0x1 << 18) | (0x2 << 21)) << 8; - - *remap2 = ((0x3 << 0) | (0x1 << 3) | (0x2 << 6) | (0x3 << 9) | - (0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x1 << 21)) << 8; + *remap1 = HAL_REO_REMAP_IX2(REO_REMAP_SW1, 16) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 17) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 18) | + HAL_REO_REMAP_IX2(REO_REMAP_SW1, 19) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 20) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 21) | + HAL_REO_REMAP_IX2(REO_REMAP_SW1, 22) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 23); + + *remap2 = HAL_REO_REMAP_IX3(REO_REMAP_SW3, 24) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 25) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 26) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 27) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 28) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 29) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 30) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 31); dp_debug("remap1 %x remap2 %x", *remap1, *remap2); return true; } + +/** + * dp_ipa_get_tx_ring_size() - Get Tx ring size for IPA + * + * @tx_ring_num: Tx ring number + * @tx_ipa_ring_sz: Return param only updated for IPA. + * + * Return: None + */ +static void dp_ipa_get_tx_ring_size(int tx_ring_num, int *tx_ipa_ring_sz) +{ + if (tx_ring_num == WLAN_CFG_IPA_TX_N_TXCMPL_RING) + *tx_ipa_ring_sz = WLAN_CFG_IPA_TX_RING_SIZE; +} + +/** + * dp_ipa_get_tx_comp_ring_size() - Get Tx comp ring size for IPA + * + * @tx_comp_ring_num: Tx comp ring number + * @tx_comp_ipa_ring_sz: Return param only updated for IPA. + * + * Return: None + */ +static void dp_ipa_get_tx_comp_ring_size(int tx_comp_ring_num, + int *tx_comp_ipa_ring_sz) +{ + if (tx_comp_ring_num == WLAN_CFG_IPA_TX_N_TXCMPL_RING) + *tx_comp_ipa_ring_sz = WLAN_CFG_IPA_TX_COMP_RING_SIZE; +} #else static bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1, uint32_t *remap2) { uint8_t offload_radio = wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx); + uint8_t target_type; + + target_type = hal_get_target_type(soc->hal_soc); switch (offload_radio) { case dp_nss_cfg_default: - *remap1 = ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | - (0x4 << 9) | (0x1 << 12) | (0x2 << 15) | - (0x3 << 18) | (0x4 << 21)) << 8; - - *remap2 = ((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | - (0x4 << 9) | (0x1 << 12) | (0x2 << 15) | - (0x3 << 18) | (0x4 << 21)) << 8; + *remap1 = HAL_REO_REMAP_IX2(REO_REMAP_SW1, 16) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 17) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 18) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 19) | + HAL_REO_REMAP_IX2(REO_REMAP_SW1, 20) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 21) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 22) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 23); + + *remap2 = HAL_REO_REMAP_IX3(REO_REMAP_SW1, 24) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 25) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 26) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 27) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 28) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 29) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 30) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 31); break; case dp_nss_cfg_first_radio: - *remap1 = ((0x2 << 0) | (0x3 << 3) | (0x4 << 6) | - (0x2 << 9) | (0x3 << 12) | (0x4 << 15) | - (0x2 << 18) | (0x3 << 21)) << 8; - - *remap2 = ((0x4 << 0) | (0x2 << 3) | (0x3 << 6) | - (0x4 << 9) | (0x2 << 12) | (0x3 << 15) | - (0x4 << 18) | (0x2 << 21)) << 8; + *remap1 = HAL_REO_REMAP_IX2(REO_REMAP_SW2, 16) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 17) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 18) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 19) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 20) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 21) | + HAL_REO_REMAP_IX2(REO_REMAP_SW2, 22) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 23); + + *remap2 = HAL_REO_REMAP_IX3(REO_REMAP_SW4, 24) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 25) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 26) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 27) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 28) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 29) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 30) | + HAL_REO_REMAP_IX3(REO_REMAP_SW2, 31); break; - case dp_nss_cfg_second_radio: - *remap1 = ((0x1 << 0) | (0x3 << 3) | (0x4 << 6) | - (0x1 << 9) | (0x3 << 12) | (0x4 << 15) | - (0x1 << 18) | (0x3 << 21)) << 8; + *remap1 = HAL_REO_REMAP_IX2(REO_REMAP_SW1, 16) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 17) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 18) | + HAL_REO_REMAP_IX2(REO_REMAP_SW1, 19) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 20) | + HAL_REO_REMAP_IX2(REO_REMAP_SW4, 21) | + HAL_REO_REMAP_IX2(REO_REMAP_SW1, 22) | + HAL_REO_REMAP_IX2(REO_REMAP_SW3, 23); + + *remap2 = HAL_REO_REMAP_IX3(REO_REMAP_SW4, 24) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 25) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 26) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 27) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 28) | + HAL_REO_REMAP_IX3(REO_REMAP_SW3, 29) | + HAL_REO_REMAP_IX3(REO_REMAP_SW4, 30) | + HAL_REO_REMAP_IX3(REO_REMAP_SW1, 31); - *remap2 = ((0x4 << 0) | (0x1 << 3) | (0x3 << 6) | - (0x4 << 9) | (0x1 << 12) | (0x3 << 15) | - (0x4 << 18) | (0x1 << 21)) << 8; break; - case dp_nss_cfg_dbdc: case dp_nss_cfg_dbtc: /* return false if both or all are offloaded to NSS */ @@ -2792,7 +3066,16 @@ static bool dp_reo_remap_config(struct dp_soc *soc, *remap1, *remap2, offload_radio); return true; } -#endif + +static void dp_ipa_get_tx_ring_size(int ring_num, int *tx_ipa_ring_sz) +{ +} + +static void dp_ipa_get_tx_comp_ring_size(int tx_comp_ring_num, + int *tx_comp_ipa_ring_sz) +{ +} +#endif /* IPA_OFFLOAD */ /* * dp_reo_frag_dst_set() - configure reo register to set the @@ -2820,6 +3103,11 @@ static void dp_reo_frag_dst_set(struct dp_soc *soc, uint8_t *frag_dst_ring) case dp_nss_cfg_default: *frag_dst_ring = REO_REMAP_TCL; break; + case dp_nss_cfg_first_radio: + /* + * This configuration is valid for single band radio which + * is also NSS offload. + */ case dp_nss_cfg_dbdc: case dp_nss_cfg_dbtc: *frag_dst_ring = HAL_SRNG_REO_ALTERNATE_SELECT; @@ -2872,7 +3160,7 @@ static inline void dp_create_ext_stats_event(struct dp_soc *soc) */ static int dp_soc_cmn_setup(struct dp_soc *soc) { - int i; + int i, cached; struct hal_reo_params reo_params; int tx_ring_size; int tx_comp_ring_size; @@ -2901,9 +3189,9 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) goto fail1; } - qdf_minidump_log( - (void *)(soc->wbm_desc_rel_ring.base_vaddr_unaligned), - soc->wbm_desc_rel_ring.alloc_size, "wbm_desc_rel_ring"); + qdf_minidump_log(soc->wbm_desc_rel_ring.base_vaddr_unaligned, + soc->wbm_desc_rel_ring.alloc_size, + "wbm_desc_rel_ring"); soc->num_tcl_data_rings = 0; /* Tx data rings */ @@ -2915,6 +3203,8 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) tx_ring_size = wlan_cfg_tx_ring_size(soc_cfg_ctx); for (i = 0; i < soc->num_tcl_data_rings; i++) { + dp_ipa_get_tx_ring_size(i, &tx_ring_size); + if (dp_srng_setup(soc, &soc->tcl_data_ring[i], TCL_DATA, i, 0, tx_ring_size, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, @@ -2922,6 +3212,13 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) FL("dp_srng_setup failed for tcl_data_ring[%d]"), i); goto fail1; } + + /* Disable cached desc if NSS offload is enabled */ + cached = WLAN_CFG_DST_RING_CACHED_DESC; + if (wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx)) + cached = 0; + + dp_ipa_get_tx_comp_ring_size(i, &tx_comp_ring_size); /* * TBD: Set IPA WBM ring size with ini IPA UC tx buffer * count @@ -2929,7 +3226,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) if (dp_srng_setup(soc, &soc->tx_comp_ring[i], WBM2SW_RELEASE, i, 0, tx_comp_ring_size, - WLAN_CFG_DST_RING_CACHED_DESC)) { + cached)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for tx_comp_ring[%d]"), i); @@ -2953,7 +3250,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for tcl_cmd_ring")); - goto fail1; + goto fail2; } entries = wlan_cfg_get_dp_soc_tcl_status_ring_size(soc_cfg_ctx); @@ -2961,7 +3258,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for tcl_status_ring")); - goto fail1; + goto fail2; } reo_dst_ring_size = wlan_cfg_get_reo_dst_ring_size(soc->wlan_cfg_ctx); @@ -2977,14 +3274,19 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, FL("num_reo_dest_rings %d"), soc->num_reo_dest_rings); + + /* Disable cached desc if NSS offload is enabled */ + cached = WLAN_CFG_DST_RING_CACHED_DESC; + if (wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx)) + cached = 0; + for (i = 0; i < soc->num_reo_dest_rings; i++) { if (dp_srng_setup(soc, &soc->reo_dest_ring[i], REO_DST, - i, 0, reo_dst_ring_size, - WLAN_CFG_DST_RING_CACHED_DESC)) { + i, 0, reo_dst_ring_size, cached)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL(RNG_ERR "reo_dest_ring [%d]"), i); - goto fail1; + goto fail2; } } } else { @@ -2995,16 +3297,14 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) entries = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx); /* LMAC RxDMA to SW Rings configuration */ if (!wlan_cfg_per_pdev_lmac_ring(soc_cfg_ctx)) { - /* Only valid for MCL */ - struct dp_pdev *pdev = soc->pdev_list[0]; for (i = 0; i < MAX_RX_MAC_RINGS; i++) { - if (dp_srng_setup(soc, &pdev->rxdma_err_dst_ring[i], + if (dp_srng_setup(soc, &soc->rxdma_err_dst_ring[i], RXDMA_DST, 0, i, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL(RNG_ERR "rxdma_err_dst_ring")); - goto fail1; + goto fail2; } } } @@ -3016,7 +3316,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for reo_reinject_ring")); - goto fail1; + goto fail2; } @@ -3026,7 +3326,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for rx_rel_ring")); - goto fail1; + goto fail2; } @@ -3036,7 +3336,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) REO_EXCEPTION, 0, MAX_REO_DEST_RINGS, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for reo_exception_ring")); - goto fail1; + goto fail2; } @@ -3046,7 +3346,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for reo_cmd_ring")); - goto fail1; + goto fail2; } hal_reo_init_cmd_ring(soc->hal_soc, soc->reo_cmd_ring.hal_srng); @@ -3058,9 +3358,16 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for reo_status_ring")); - goto fail1; + goto fail2; } + /* + * Skip registering hw ring interrupts for WMAC2 on IPQ6018 + * WMAC2 is not there in IPQ6018 platform. + */ + if (hal_get_target_type(soc->hal_soc) == TARGET_TYPE_QCA6018) { + dp_soc_disable_mac2_intr_mask(soc); + } /* Reset the cpu ring map if radio is NSS offloaded */ if (wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx)) { @@ -3111,6 +3418,8 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) qdf_nbuf_queue_init(&soc->htt_stats.msg); return 0; +fail2: + dp_tx_soc_detach(soc); fail1: /* * Cleanup will be done as part of soc_detach, which will @@ -3132,13 +3441,17 @@ static int dp_soc_cmn_setup(struct dp_soc *soc) */ static void dp_soc_cmn_cleanup(struct dp_soc *soc) { - dp_tx_soc_detach(soc); + if (!dp_is_soc_reinit(soc)) { + dp_tx_soc_detach(soc); + } qdf_spinlock_destroy(&soc->rx.defrag.defrag_lock); qdf_spinlock_destroy(&soc->rx.reo_cmd_lock); } -static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force); +static QDF_STATUS +dp_pdev_detach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, + int force); static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) { @@ -3178,7 +3491,8 @@ static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) return QDF_STATUS_E_FAILURE; } - status = soc->cdp_soc.ol_ops->lro_hash_config(pdev->ctrl_pdev, + status = soc->cdp_soc.ol_ops->lro_hash_config(soc->ctrl_psoc, + pdev->pdev_id, &lro_hash); if (!QDF_IS_STATUS_SUCCESS(status)) { dp_err("failed to send lro_hash_config to FW %u", status); @@ -3191,13 +3505,13 @@ static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) dp_info("toeplitz_hash_ipv4:"); qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - (void *)lro_hash.toeplitz_hash_ipv4, + lro_hash.toeplitz_hash_ipv4, (sizeof(lro_hash.toeplitz_hash_ipv4[0]) * LRO_IPV4_SEED_ARR_SZ)); dp_info("toeplitz_hash_ipv6:"); qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - (void *)lro_hash.toeplitz_hash_ipv6, + lro_hash.toeplitz_hash_ipv6, (sizeof(lro_hash.toeplitz_hash_ipv6[0]) * LRO_IPV6_SEED_ARR_SZ)); @@ -3366,14 +3680,14 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) pdev_cfg_ctx = pdev->wlan_cfg_ctx; for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); + int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); if (soc->wlan_cfg_ctx->rxdma1_enable) { entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev_cfg_ctx); if (dp_srng_setup(soc, - &pdev->rxdma_mon_buf_ring[mac_id], - RXDMA_MONITOR_BUF, 0, mac_for_pdev, + &soc->rxdma_mon_buf_ring[lmac_id], + RXDMA_MONITOR_BUF, 0, lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3384,8 +3698,8 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) entries = wlan_cfg_get_dma_mon_dest_ring_size(pdev_cfg_ctx); if (dp_srng_setup(soc, - &pdev->rxdma_mon_dst_ring[mac_id], - RXDMA_MONITOR_DST, 0, mac_for_pdev, + &soc->rxdma_mon_dst_ring[lmac_id], + RXDMA_MONITOR_DST, 0, lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3396,8 +3710,8 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) entries = wlan_cfg_get_dma_mon_stat_ring_size(pdev_cfg_ctx); if (dp_srng_setup(soc, - &pdev->rxdma_mon_status_ring[mac_id], - RXDMA_MONITOR_STATUS, 0, mac_for_pdev, + &soc->rxdma_mon_status_ring[lmac_id], + RXDMA_MONITOR_STATUS, 0, lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3408,8 +3722,8 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) entries = wlan_cfg_get_dma_mon_desc_ring_size(pdev_cfg_ctx); if (dp_srng_setup(soc, - &pdev->rxdma_mon_desc_ring[mac_id], - RXDMA_MONITOR_DESC, 0, mac_for_pdev, + &soc->rxdma_mon_desc_ring[lmac_id], + RXDMA_MONITOR_DESC, 0, lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3420,8 +3734,8 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) entries = wlan_cfg_get_dma_mon_stat_ring_size(pdev_cfg_ctx); if (dp_srng_setup(soc, - &pdev->rxdma_mon_status_ring[mac_id], - RXDMA_MONITOR_STATUS, 0, mac_for_pdev, + &soc->rxdma_mon_status_ring[lmac_id], + RXDMA_MONITOR_STATUS, 0, lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3445,7 +3759,7 @@ QDF_STATUS dp_mon_rings_setup(struct dp_soc *soc, struct dp_pdev *pdev) * @pdev_hdl: pdev handle */ #ifdef ATH_SUPPORT_EXT_STAT -void dp_iterate_update_peer_list(void *pdev_hdl) +void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; struct dp_soc *soc = pdev->soc; @@ -3463,7 +3777,7 @@ void dp_iterate_update_peer_list(void *pdev_hdl) qdf_spin_unlock_bh(&soc->peer_ref_mutex); } #else -void dp_iterate_update_peer_list(void *pdev_hdl) +void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl) { } #endif @@ -3487,40 +3801,141 @@ static QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev) return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +#ifndef RX_DEFRAG_DO_NOT_REINJECT +/** + * dp_soc_rx_reinject_ring_history_attach - Attach the reo reinject ring + * history. + * @soc: DP soc handle + * + * Return: None + */ +static void dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc) +{ + soc->rx_reinject_ring_history = dp_context_alloc_mem( + soc, DP_RX_REINJECT_RING_HIST_TYPE, rx_ring_hist_size); + if (soc->rx_reinject_ring_history) + qdf_atomic_init(&soc->rx_reinject_ring_history->index); +} +#else /* RX_DEFRAG_DO_NOT_REINJECT */ +static inline void +dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc) +{ +} +#endif /* RX_DEFRAG_DO_NOT_REINJECT */ + +/** + * dp_soc_rx_history_attach() - Attach the ring history record buffers + * @soc: DP soc structure + * + * This function allocates the memory for recording the rx ring, rx error + * ring and the reinject ring entries. There is no error returned in case + * of allocation failure since the record function checks if the history is + * initialized or not. We do not want to fail the driver load in case of + * failure to allocate memory for debug history. + * + * Returns: None + */ +static void dp_soc_rx_history_attach(struct dp_soc *soc) +{ + int i; + uint32_t rx_ring_hist_size; + uint32_t rx_err_ring_hist_size; + uint32_t rx_reinject_hist_size; + + rx_ring_hist_size = sizeof(*soc->rx_ring_history[0]); + rx_err_ring_hist_size = sizeof(*soc->rx_err_ring_history); + rx_reinject_hist_size = sizeof(*soc->rx_reinject_ring_history); + + for (i = 0; i < MAX_REO_DEST_RINGS; i++) { + soc->rx_ring_history[i] = dp_context_alloc_mem( + soc, DP_RX_RING_HIST_TYPE, rx_ring_hist_size); + if (soc->rx_ring_history[i]) + qdf_atomic_init(&soc->rx_ring_history[i]->index); + } + + soc->rx_err_ring_history = dp_context_alloc_mem( + soc, DP_RX_ERR_RING_HIST_TYPE, rx_ring_hist_size); + if (soc->rx_err_ring_history) + qdf_atomic_init(&soc->rx_err_ring_history->index); + + dp_soc_rx_reinject_ring_history_attach(soc); +} + +static void dp_soc_rx_history_detach(struct dp_soc *soc) +{ + int i; + + for (i = 0; i < MAX_REO_DEST_RINGS; i++) + dp_context_free_mem(soc, DP_RX_RING_HIST_TYPE, + soc->rx_ring_history[i]); + + dp_context_free_mem(soc, DP_RX_ERR_RING_HIST_TYPE, + soc->rx_err_ring_history); + + /* + * No need for a featurized detach since qdf_mem_free takes + * care of NULL pointer. + */ + dp_context_free_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE, + soc->rx_reinject_ring_history); +} + +#else +static inline void dp_soc_rx_history_attach(struct dp_soc *soc) +{ +} + +static inline void dp_soc_rx_history_detach(struct dp_soc *soc) +{ +} +#endif + /* * dp_pdev_attach_wifi3() - attach txrx pdev -* @ctrl_pdev: Opaque PDEV object * @txrx_soc: Datapath SOC handle * @htc_handle: HTC handle for host-target interface * @qdf_osdev: QDF OS device * @pdev_id: PDEV ID * -* Return: DP PDEV handle on success, NULL on failure +* Return: QDF_STATUS */ -static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, - struct cdp_ctrl_objmgr_pdev *ctrl_pdev, - HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, uint8_t pdev_id) +static inline QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, + HTC_HANDLE htc_handle, + qdf_device_t qdf_osdev, + uint8_t pdev_id) { int ring_size; int entries; struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; int nss_cfg; void *sojourn_buf; - struct dp_soc *soc = (struct dp_soc *)txrx_soc; struct dp_pdev *pdev = NULL; + QDF_STATUS ret; - if (dp_is_soc_reinit(soc)) + if (dp_is_soc_reinit(soc)) { pdev = soc->pdev_list[pdev_id]; - else - pdev = qdf_mem_malloc(sizeof(*pdev)); + } else { + pdev = dp_context_alloc_mem(soc, DP_PDEV_TYPE, sizeof(*pdev)); + qdf_minidump_log(pdev, sizeof(*pdev), "dp_pdev"); + } if (!pdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("DP PDEV memory allocation failed")); + ret = QDF_STATUS_E_NOMEM; + goto fail0; + } + + pdev->filter = dp_mon_filter_alloc(pdev); + if (!pdev->filter) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Memory allocation failed for monitor filters")); + qdf_mem_free(pdev); + ret = QDF_STATUS_E_NOMEM; goto fail0; } - qdf_minidump_log((void *)pdev, sizeof(*pdev), "dp_pdev"); /* * Variable to prevent double pdev deinitialization during @@ -3532,7 +3947,9 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, if (!pdev->invalid_peer) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("Invalid peer memory allocation failed")); + dp_mon_filter_dealloc(pdev); qdf_mem_free(pdev); + ret = QDF_STATUS_E_NOMEM; goto fail0; } @@ -3544,7 +3961,9 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, FL("pdev cfg_attach failed")); qdf_mem_free(pdev->invalid_peer); + dp_mon_filter_dealloc(pdev); qdf_mem_free(pdev); + ret = QDF_STATUS_E_FAILURE; goto fail0; } @@ -3556,7 +3975,6 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, (nss_cfg & (1 << pdev_id))); pdev->soc = soc; - pdev->ctrl_pdev = ctrl_pdev; pdev->pdev_id = pdev_id; soc->pdev_list[pdev_id] = pdev; @@ -3572,10 +3990,12 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, TAILQ_INIT(&pdev->neighbour_peers_list); pdev->neighbour_peers_added = false; pdev->monitor_configured = false; + pdev->enable_reap_timer_non_pkt = false; if (dp_soc_cmn_setup(soc)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_soc_cmn_setup failed")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } @@ -3588,6 +4008,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, pdev_id, pdev_id, ring_size, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for tcl_data_ring")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } @@ -3599,6 +4020,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, ring_size, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for tx_comp_ring")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } soc->num_tcl_data_rings++; @@ -3608,6 +4030,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, if (dp_tx_pdev_attach(pdev)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_tx_pdev_attach failed")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } @@ -3618,53 +4041,64 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, pdev_id, pdev_id, ring_size, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed for reo_dest_ringn")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } soc->num_reo_dest_rings++; - } ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc->wlan_cfg_ctx); - if (dp_srng_setup(soc, &pdev->rx_refill_buf_ring, RXDMA_BUF, 0, pdev_id, - ring_size, 0)) { + if (dp_srng_setup(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], + RXDMA_BUF, 0, pdev->lmac_id, ring_size, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_srng_setup failed rx refill ring")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } if (dp_rxdma_ring_setup(soc, pdev)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("RXDMA ring config failed")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } if (dp_mon_rings_setup(soc, pdev)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("MONITOR rings setup failed")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } entries = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx); if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) { - if (dp_srng_setup(soc, &pdev->rxdma_err_dst_ring[0], RXDMA_DST, - 0, pdev_id, entries, 0)) { + if (dp_srng_setup(soc, + &soc->rxdma_err_dst_ring[pdev->lmac_id], + RXDMA_DST, + 0, pdev->lmac_id, entries, 0)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL(RNG_ERR "rxdma_err_dst_ring")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } } - if (dp_setup_ipa_rx_refill_buf_ring(soc, pdev)) + if (dp_setup_ipa_rx_refill_buf_ring(soc, pdev)) { + ret = QDF_STATUS_E_FAILURE; goto fail1; + } - if (dp_ipa_ring_resource_setup(soc, pdev)) + if (dp_ipa_ring_resource_setup(soc, pdev)) { + ret = QDF_STATUS_E_FAILURE; goto fail1; + } if (dp_ipa_uc_attach(soc, pdev) != QDF_STATUS_SUCCESS) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_ipa_uc_attach failed")); + ret = QDF_STATUS_E_FAILURE; goto fail1; } @@ -3672,6 +4106,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, if (dp_rx_pdev_attach(pdev)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("dp_rx_pdev_attach failed")); + ret = QDF_STATUS_E_FAILURE; goto fail2; } @@ -3695,12 +4130,14 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, if (dp_rx_pdev_mon_attach(pdev)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "dp_rx_pdev_mon_attach failed"); + ret = QDF_STATUS_E_FAILURE; goto fail2; } if (dp_wdi_event_attach(pdev)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "dp_wdi_evet_attach failed"); + ret = QDF_STATUS_E_FAILURE; goto wdi_attach_fail; } @@ -3725,18 +4162,24 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, qdf_mem_zero(sojourn_buf, sizeof(struct cdp_tx_sojourn_stats)); } /* initlialize cal client timer */ - dp_cal_client_attach(&pdev->cal_client_ctx, pdev, pdev->soc->osdev, + dp_cal_client_attach(&pdev->cal_client_ctx, + dp_pdev_to_cdp_pdev(pdev), + pdev->soc->osdev, &dp_iterate_update_peer_list); qdf_event_create(&pdev->fw_peer_stats_event); pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); - if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS) + dp_init_tso_stats(pdev); + + if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS) { + ret = QDF_STATUS_E_FAILURE; goto fail1; + } dp_tx_ppdu_stats_attach(pdev); - return (struct cdp_pdev *)pdev; + return QDF_STATUS_SUCCESS; wdi_attach_fail: /* @@ -3753,10 +4196,13 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, soc->pdev_count--; if (pdev->invalid_peer) qdf_mem_free(pdev->invalid_peer); - dp_pdev_detach((struct cdp_pdev *)pdev, 0); + if (pdev->filter) + dp_mon_filter_dealloc(pdev); + + dp_pdev_detach((struct cdp_pdev *)pdev, 0); fail0: - return NULL; + return ret; } /* @@ -3785,6 +4231,11 @@ static void dp_rxdma_ring_cleanup(struct dp_soc *soc, static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev) { + if (soc->lmac_timer_init) { + qdf_timer_stop(&soc->lmac_reap_timer); + qdf_timer_free(&soc->lmac_reap_timer); + soc->lmac_timer_init = 0; + } } #endif @@ -3840,35 +4291,35 @@ static void dp_mon_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev, int mac_id) { - if (soc->wlan_cfg_ctx->rxdma1_enable) { - dp_srng_cleanup(soc, - &pdev->rxdma_mon_buf_ring[mac_id], - RXDMA_MONITOR_BUF, 0); + if (soc->wlan_cfg_ctx->rxdma1_enable) { + dp_srng_cleanup(soc, + &soc->rxdma_mon_buf_ring[mac_id], + RXDMA_MONITOR_BUF, 0); - dp_srng_cleanup(soc, - &pdev->rxdma_mon_dst_ring[mac_id], - RXDMA_MONITOR_DST, 0); + dp_srng_cleanup(soc, + &soc->rxdma_mon_dst_ring[mac_id], + RXDMA_MONITOR_DST, 0); - dp_srng_cleanup(soc, - &pdev->rxdma_mon_status_ring[mac_id], - RXDMA_MONITOR_STATUS, 0); + dp_srng_cleanup(soc, + &soc->rxdma_mon_status_ring[mac_id], + RXDMA_MONITOR_STATUS, 0); - dp_srng_cleanup(soc, - &pdev->rxdma_mon_desc_ring[mac_id], - RXDMA_MONITOR_DESC, 0); + dp_srng_cleanup(soc, + &soc->rxdma_mon_desc_ring[mac_id], + RXDMA_MONITOR_DESC, 0); - dp_srng_cleanup(soc, - &pdev->rxdma_err_dst_ring[mac_id], - RXDMA_DST, 0); - } else { - dp_srng_cleanup(soc, - &pdev->rxdma_mon_status_ring[mac_id], - RXDMA_MONITOR_STATUS, 0); + dp_srng_cleanup(soc, + &soc->rxdma_err_dst_ring[mac_id], + RXDMA_DST, 0); + } else { + dp_srng_cleanup(soc, + &soc->rxdma_mon_status_ring[mac_id], + RXDMA_MONITOR_STATUS, 0); - dp_srng_cleanup(soc, - &pdev->rxdma_err_dst_ring[mac_id], - RXDMA_DST, 0); - } + dp_srng_cleanup(soc, + &soc->rxdma_err_dst_ring[mac_id], + RXDMA_DST, 0); + } } #else @@ -3991,6 +4442,7 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) dp_pktlogmod_exit(pdev); + dp_rx_fst_detach(soc, pdev); dp_rx_pdev_detach(pdev); dp_rx_pdev_mon_detach(pdev); dp_neighbour_peers_detach(pdev); @@ -4007,13 +4459,18 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) REO_DST, pdev->pdev_id); } - dp_srng_deinit(soc, &pdev->rx_refill_buf_ring, RXDMA_BUF, 0); + dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], + RXDMA_BUF, 0); dp_rxdma_ring_cleanup(soc, pdev); for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - dp_mon_ring_deinit(soc, pdev, mac_id); - dp_srng_deinit(soc, &pdev->rxdma_err_dst_ring[mac_id], + int lmac_id = + dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); + + dp_mon_ring_deinit(soc, pdev, lmac_id); + + dp_srng_deinit(soc, &soc->rxdma_err_dst_ring[lmac_id], RXDMA_DST, 0); } @@ -4028,7 +4485,10 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) dp_htt_ppdu_stats_detach(pdev); + dp_tx_ppdu_stats_detach(pdev); + qdf_nbuf_free(pdev->sojourn_buf); + qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q); dp_cal_client_detach(&pdev->cal_client_ctx); @@ -4041,25 +4501,42 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx); if (pdev->invalid_peer) qdf_mem_free(pdev->invalid_peer); + + /* + * Fee the monitor filter allocated and stored + */ + if (pdev->filter) + dp_mon_filter_dealloc(pdev); + qdf_mem_free(pdev->dp_txrx_handle); dp_pdev_mem_reset(pdev); } /** * dp_pdev_deinit_wifi3() - Deinit txrx pdev - * @txrx_pdev: Datapath PDEV handle + * @psoc: Datapath psoc handle + * @pdev_id: Id of datapath PDEV handle * @force: Force deinit * - * Return: None + * Return: QDF_STATUS */ -static void dp_pdev_deinit_wifi3(struct cdp_pdev *txrx_pdev, int force) +static QDF_STATUS +dp_pdev_deinit_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, + int force) { - struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)psoc; + struct dp_pdev *txrx_pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc, + pdev_id); + + if (!txrx_pdev) + return QDF_STATUS_E_FAILURE; soc->dp_soc_reinit = TRUE; - dp_pdev_deinit(txrx_pdev, force); + dp_pdev_deinit((struct cdp_pdev *)txrx_pdev, force); + + return QDF_STATUS_SUCCESS; } /* @@ -4075,6 +4552,7 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) struct dp_soc *soc = pdev->soc; struct rx_desc_pool *rx_desc_pool; int mac_id, mac_for_pdev; + int lmac_id; if (wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) { dp_srng_cleanup(soc, &soc->tcl_data_ring[pdev->pdev_id], @@ -4085,8 +4563,6 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) dp_mon_link_free(pdev); - dp_tx_ppdu_stats_detach(pdev); - /* Cleanup per PDEV REO rings if configured */ if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) { dp_srng_cleanup(soc, &soc->reo_dest_ring[pdev->pdev_id], @@ -4095,16 +4571,21 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) dp_rxdma_ring_cleanup(soc, pdev); wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx); - dp_srng_cleanup(soc, &pdev->rx_refill_buf_ring, RXDMA_BUF, 0); + dp_srng_cleanup(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], + RXDMA_BUF, 0); dp_cleanup_ipa_rx_refill_buf_ring(soc, pdev); for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - dp_mon_ring_cleanup(soc, pdev, mac_id); - dp_srng_cleanup(soc, &pdev->rxdma_err_dst_ring[mac_id], + lmac_id = + dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); + dp_mon_ring_cleanup(soc, pdev, lmac_id); + dp_srng_cleanup(soc, &soc->rxdma_err_dst_ring[lmac_id], RXDMA_DST, 0); + if (dp_is_soc_reinit(soc)) { - mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); + mac_for_pdev = + dp_get_lmac_id_for_pdev_id(soc, mac_id, + pdev->pdev_id); rx_desc_pool = &soc->rx_desc_status[mac_for_pdev]; dp_rx_desc_pool_free(soc, rx_desc_pool); rx_desc_pool = &soc->rx_desc_mon[mac_for_pdev]; @@ -4113,7 +4594,7 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) } if (dp_is_soc_reinit(soc)) { - rx_desc_pool = &soc->rx_desc_buf[pdev->pdev_id]; + rx_desc_pool = &soc->rx_desc_buf[pdev->lmac_id]; dp_rx_desc_pool_free(soc, rx_desc_pool); } @@ -4122,27 +4603,39 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) dp_soc_cmn_cleanup(soc); soc->pdev_list[pdev->pdev_id] = NULL; - qdf_mem_free(pdev); + qdf_minidump_remove(pdev); + dp_context_free_mem(soc, DP_PDEV_TYPE, pdev); } /* * dp_pdev_detach_wifi3() - detach txrx pdev - * @txrx_pdev: Datapath PDEV handle + * @psoc: Datapath soc handle + * @pdev_id: pdev id of pdev * @force: Force detach * - * Return: None + * Return: QDF_STATUS */ -static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force) +static QDF_STATUS dp_pdev_detach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, + int force) { - struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)psoc; + struct dp_pdev *txrx_pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc, + pdev_id); + + if (!txrx_pdev) { + dp_err("Couldn't find dp pdev"); + return QDF_STATUS_E_FAILURE; + } if (dp_is_soc_reinit(soc)) { - dp_pdev_detach(txrx_pdev, force); + dp_pdev_detach((struct cdp_pdev *)txrx_pdev, force); } else { - dp_pdev_deinit(txrx_pdev, force); - dp_pdev_detach(txrx_pdev, force); + dp_pdev_deinit((struct cdp_pdev *)txrx_pdev, force); + dp_pdev_detach((struct cdp_pdev *)txrx_pdev, force); } + + return QDF_STATUS_SUCCESS; } /* @@ -4286,7 +4779,7 @@ static void dp_soc_deinit(void *txrx_soc) * * Return: None */ -static void dp_soc_deinit_wifi3(void *txrx_soc) +static void dp_soc_deinit_wifi3(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -4300,7 +4793,7 @@ static void dp_soc_deinit_wifi3(void *txrx_soc) * * Return: None */ -static void dp_soc_detach(void *txrx_soc) +static void dp_soc_detach(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; @@ -4319,8 +4812,13 @@ static void dp_soc_detach(void *txrx_soc) /* Free the ring memories */ /* Common rings */ + qdf_minidump_remove(soc->wbm_desc_rel_ring.base_vaddr_unaligned); dp_srng_cleanup(soc, &soc->wbm_desc_rel_ring, SW2WBM_RELEASE, 0); + if (dp_is_soc_reinit(soc)) { + dp_tx_soc_detach(soc); + } + /* Tx data rings */ if (!wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) { for (i = 0; i < soc->num_tcl_data_rings; i++) { @@ -4369,7 +4867,9 @@ static void dp_soc_detach(void *txrx_soc) soc->dp_soc_reinit = 0; wlan_cfg_soc_detach(soc->wlan_cfg_ctx); + dp_soc_rx_history_detach(soc); + qdf_minidump_remove(soc); qdf_mem_free(soc); } @@ -4379,7 +4879,7 @@ static void dp_soc_detach(void *txrx_soc) * * Return: None */ -static void dp_soc_detach_wifi3(void *txrx_soc) +static void dp_soc_detach_wifi3(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -4389,7 +4889,6 @@ static void dp_soc_detach_wifi3(void *txrx_soc) dp_soc_deinit(txrx_soc); dp_soc_detach(txrx_soc); } - } #if !defined(DISABLE_MON_CONFIG) @@ -4411,7 +4910,7 @@ static QDF_STATUS dp_mon_htt_srng_setup(struct dp_soc *soc, if (soc->wlan_cfg_ctx->rxdma1_enable) { status = htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_buf_ring[mac_id] + soc->rxdma_mon_buf_ring[mac_id] .hal_srng, RXDMA_MONITOR_BUF); @@ -4421,7 +4920,7 @@ static QDF_STATUS dp_mon_htt_srng_setup(struct dp_soc *soc, } status = htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_dst_ring[mac_id] + soc->rxdma_mon_dst_ring[mac_id] .hal_srng, RXDMA_MONITOR_DST); @@ -4431,7 +4930,7 @@ static QDF_STATUS dp_mon_htt_srng_setup(struct dp_soc *soc, } status = htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id] + soc->rxdma_mon_status_ring[mac_id] .hal_srng, RXDMA_MONITOR_STATUS); @@ -4441,7 +4940,7 @@ static QDF_STATUS dp_mon_htt_srng_setup(struct dp_soc *soc, } status = htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_desc_ring[mac_id] + soc->rxdma_mon_desc_ring[mac_id] .hal_srng, RXDMA_MONITOR_DESC); @@ -4451,7 +4950,7 @@ static QDF_STATUS dp_mon_htt_srng_setup(struct dp_soc *soc, } } else { status = htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id] + soc->rxdma_mon_status_ring[mac_id] .hal_srng, RXDMA_MONITOR_STATUS); @@ -4500,10 +4999,12 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) int max_mac_rings = wlan_cfg_get_num_mac_rings (pdev->wlan_cfg_ctx); + int lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i); htt_srng_setup(soc->htt_handle, 0, - pdev->rx_refill_buf_ring.hal_srng, - RXDMA_BUF); + soc->rx_refill_buf_ring[lmac_id] + .hal_srng, + RXDMA_BUF); if (pdev->rx_refill_buf_ring2.hal_srng) htt_srng_setup(soc->htt_handle, 0, @@ -4513,7 +5014,8 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) if (soc->cdp_soc.ol_ops-> is_hw_dbs_2x2_capable) { dbs_enable = soc->cdp_soc.ol_ops-> - is_hw_dbs_2x2_capable(soc->ctrl_psoc); + is_hw_dbs_2x2_capable( + (void *)soc->ctrl_psoc); } if (dbs_enable) { @@ -4534,9 +5036,17 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) pdev->pdev_id, max_mac_rings); for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev( - mac_id, pdev->pdev_id); - + int mac_for_pdev = + dp_get_mac_id_for_pdev(mac_id, + pdev->pdev_id); + /* + * Obtain lmac id from pdev to access the LMAC + * ring in soc context + */ + lmac_id = + dp_get_lmac_id_for_pdev_id(soc, + mac_id, + pdev->pdev_id); QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, FL("mac_id %d"), mac_for_pdev); @@ -4546,13 +5056,13 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) .hal_srng, RXDMA_BUF); htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_err_dst_ring[mac_id] - .hal_srng, + soc->rxdma_err_dst_ring[lmac_id] + .hal_srng, RXDMA_DST); /* Configure monitor mode rings */ status = dp_mon_htt_srng_setup(soc, pdev, - mac_id, + lmac_id, mac_for_pdev); if (status != QDF_STATUS_SUCCESS) { dp_err("Failed to send htt monitor messages to target"); @@ -4578,38 +5088,52 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) { int i; - int mac_id; QDF_STATUS status = QDF_STATUS_SUCCESS; + int mac_for_pdev; + int lmac_id; for (i = 0; i < MAX_PDEV_CNT; i++) { - struct dp_pdev *pdev = soc->pdev_list[i]; + struct dp_pdev *pdev = soc->pdev_list[i]; if (!pdev) continue; - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, i); + mac_for_pdev = i; + lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i); - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rx_refill_buf_ring.hal_srng, RXDMA_BUF); + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rx_refill_buf_ring[lmac_id]. + hal_srng, RXDMA_BUF); #ifndef DISABLE_MON_CONFIG - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_buf_ring[mac_id].hal_srng, - RXDMA_MONITOR_BUF); - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_dst_ring[mac_id].hal_srng, - RXDMA_MONITOR_DST); - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS); - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_desc_ring[mac_id].hal_srng, - RXDMA_MONITOR_DESC); + + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rxdma_mon_buf_ring[lmac_id].hal_srng, + RXDMA_MONITOR_BUF); + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rxdma_mon_dst_ring[lmac_id].hal_srng, + RXDMA_MONITOR_DST); + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rxdma_mon_status_ring[lmac_id].hal_srng, + RXDMA_MONITOR_STATUS); + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rxdma_mon_desc_ring[lmac_id].hal_srng, + RXDMA_MONITOR_DESC); #endif - htt_srng_setup(soc->htt_handle, mac_for_pdev, - pdev->rxdma_err_dst_ring[mac_id].hal_srng, - RXDMA_DST); - } + htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->rxdma_err_dst_ring[lmac_id].hal_srng, + RXDMA_DST); + } + + /* Configure LMAC rings in Polled mode */ + if (soc->lmac_polled_mode) { + /* + * Timer to reap lmac rings. + */ + qdf_timer_init(soc->osdev, &soc->lmac_reap_timer, + dp_service_lmac_rings, (void *)soc, + QDF_TIMER_TYPE_WAKE_APPS); + soc->lmac_timer_init = 1; + qdf_timer_mod(&soc->lmac_reap_timer, DP_INTR_POLL_TIMER_MS); } return status; } @@ -4675,12 +5199,20 @@ dp_rxdma_ring_sel_cfg(struct dp_soc *soc) continue; for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); + int mac_for_pdev = + dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); + /* + * Obtain lmac id from pdev to access the LMAC ring + * in soc context + */ + int lmac_id = + dp_get_lmac_id_for_pdev_id(soc, mac_id, + pdev->pdev_id); htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rx_refill_buf_ring.hal_srng, - RXDMA_BUF, RX_BUFFER_SIZE, + soc->rx_refill_buf_ring[lmac_id]. + hal_srng, + RXDMA_BUF, RX_DATA_BUFFER_SIZE, &htt_tlv_filter); } } @@ -4695,83 +5227,139 @@ dp_rxdma_ring_sel_cfg(struct dp_soc *soc) #endif /* - * dp_soc_attach_target_wifi3() - SOC initialization in the target - * @cdp_soc: Opaque Datapath SOC handle + * dp_rx_target_fst_config() - configure the RXOLE Flow Search Engine + * + * This function is used to configure the FSE HW block in RX OLE on a + * per pdev basis. Here, we will be programming parameters related to + * the Flow Search Table. + * + * @soc: data path SoC handle * * Return: zero on success, non-zero on failure */ +#ifdef WLAN_SUPPORT_RX_FLOW_TAG static QDF_STATUS -dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) +dp_rx_target_fst_config(struct dp_soc *soc) { - struct dp_soc *soc = (struct dp_soc *)cdp_soc; + int i; QDF_STATUS status = QDF_STATUS_SUCCESS; - htt_soc_attach_target(soc->htt_handle); + for (i = 0; i < MAX_PDEV_CNT; i++) { + struct dp_pdev *pdev = soc->pdev_list[i]; - status = dp_rxdma_ring_config(soc); - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send htt srng setup messages to target"); - return status; + /* Flow search is not enabled if NSS offload is enabled */ + if (pdev && + !wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { + status = dp_rx_flow_send_fst_fw_setup(pdev->soc, pdev); + if (status != QDF_STATUS_SUCCESS) + break; + } } - - status = dp_rxdma_ring_sel_cfg(soc); - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send htt ring config message to target"); - return status; + return status; +} +#elif defined(WLAN_SUPPORT_RX_FISA) +/** + * dp_rx_target_fst_config() - Configure RX OLE FSE engine in HW + * @soc: SoC handle + * + * Return: Success + */ +static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) +{ + /* Check if it is enabled in the INI */ + if (!soc->fisa_enable) { + dp_err("RX FISA feature is disabled"); + return QDF_STATUS_E_NOSUPPORT; } - DP_STATS_INIT(soc); + return dp_rx_flow_send_fst_fw_setup(soc, soc->pdev_list[0]); +} - /* initialize work queue for stats processing */ - qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); +#define FISA_MAX_TIMEOUT 0xffffffff +#define FISA_DISABLE_TIMEOUT 0 +static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) +{ + struct dp_htt_rx_fisa_cfg fisa_config; - qdf_minidump_log((void *)soc, sizeof(*soc), "dp_soc"); + fisa_config.pdev_id = 0; + fisa_config.fisa_timeout = FISA_MAX_TIMEOUT; + return dp_htt_rx_fisa_config(soc->pdev_list[0], &fisa_config); +} +#else /* !WLAN_SUPPORT_RX_FISA */ +static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) +{ return QDF_STATUS_SUCCESS; } +#endif /* !WLAN_SUPPORT_RX_FISA */ -/* - * dp_soc_get_nss_cfg_wifi3() - SOC get nss config - * @txrx_soc: Datapath SOC handle - */ -static int dp_soc_get_nss_cfg_wifi3(struct cdp_soc_t *cdp_soc) +#ifndef WLAN_SUPPORT_RX_FISA +static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; +} + +static void dp_rx_dump_fisa_table(struct dp_soc *soc) { - struct dp_soc *dsoc = (struct dp_soc *)cdp_soc; - return wlan_cfg_get_dp_soc_nss_cfg(dsoc->wlan_cfg_ctx); } +#endif /* !WLAN_SUPPORT_RX_FISA */ /* - * dp_soc_set_nss_cfg_wifi3() - SOC set nss config - * @txrx_soc: Datapath SOC handle - * @nss_cfg: nss config + * dp_soc_attach_target_wifi3() - SOC initialization in the target + * @cdp_soc: Opaque Datapath SOC handle + * + * Return: zero on success, non-zero on failure */ -static void dp_soc_set_nss_cfg_wifi3(struct cdp_soc_t *cdp_soc, int config) +static QDF_STATUS +dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) { - struct dp_soc *dsoc = (struct dp_soc *)cdp_soc; - struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = dsoc->wlan_cfg_ctx; + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + QDF_STATUS status = QDF_STATUS_SUCCESS; - wlan_cfg_set_dp_soc_nss_cfg(wlan_cfg_ctx, config); + htt_soc_attach_target(soc->htt_handle); - /* - * TODO: masked out based on the per offloaded radio - */ - switch (config) { - case dp_nss_cfg_default: - break; - case dp_nss_cfg_dbdc: - case dp_nss_cfg_dbtc: - wlan_cfg_set_num_tx_desc_pool(wlan_cfg_ctx, 0); - wlan_cfg_set_num_tx_ext_desc_pool(wlan_cfg_ctx, 0); - wlan_cfg_set_num_tx_desc(wlan_cfg_ctx, 0); - wlan_cfg_set_num_tx_ext_desc(wlan_cfg_ctx, 0); - break; - default: - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Invalid offload config %d", config); + status = dp_rxdma_ring_config(soc); + if (status != QDF_STATUS_SUCCESS) { + dp_err("Failed to send htt srng setup messages to target"); + return status; } - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - FL("nss-wifi<0> nss config is enabled")); + status = dp_rxdma_ring_sel_cfg(soc); + if (status != QDF_STATUS_SUCCESS) { + dp_err("Failed to send htt ring config message to target"); + return status; + } + + status = dp_rx_target_fst_config(soc); + if (status != QDF_STATUS_SUCCESS && + status != QDF_STATUS_E_NOSUPPORT) { + dp_err("Failed to send htt fst setup config message to target"); + return status; + } + + if (status == QDF_STATUS_SUCCESS) { + status = dp_rx_fisa_config(soc); + if (status != QDF_STATUS_SUCCESS) { + dp_err("Failed to send htt FISA config message to target"); + return status; + } + } + + DP_STATS_INIT(soc); + + dp_runtime_init(soc); + + /* initialize work queue for stats processing */ + qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); + + qdf_minidump_log(soc, sizeof(*soc), "dp_soc"); + + return QDF_STATUS_SUCCESS; } /* @@ -4782,16 +5370,28 @@ static void dp_soc_set_nss_cfg_wifi3(struct cdp_soc_t *cdp_soc, int config) * @wlan_op_mode: VDEV operating mode * @subtype: VDEV operating subtype * -* Return: DP VDEV handle on success, NULL on failure +* Return: status */ -static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, - uint8_t *vdev_mac_addr, uint8_t vdev_id, enum wlan_op_mode op_mode, - enum wlan_op_subtype subtype) +static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t pdev_id, + uint8_t *vdev_mac_addr, + uint8_t vdev_id, + enum wlan_op_mode op_mode, + enum wlan_op_subtype subtype) { - struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); struct dp_vdev *vdev = qdf_mem_malloc(sizeof(*vdev)); + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("DP PDEV is Null for pdev id %d"), pdev_id); + qdf_mem_free(vdev); + goto fail0; + } + if (!vdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("DP VDEV memory allocation failed")); @@ -4815,6 +5415,7 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, vdev->safemode = 0; vdev->drop_unenc = 1; vdev->sec_type = cdp_sec_type_none; + vdev->multipass_en = false; #ifdef notyet vdev->filters_num = 0; #endif @@ -4827,6 +5428,7 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, */ TAILQ_INIT(&vdev->peer_list); + dp_peer_multipass_list_init(vdev); if ((soc->intr_mode == DP_INTR_POLL) && wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) { @@ -4835,9 +5437,11 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); } + soc->vdev_id_map[vdev_id] = vdev; + if (wlan_op_mode_monitor == vdev->opmode) { pdev->monitor_vdev = vdev; - return (struct cdp_vdev *)vdev; + return QDF_STATUS_SUCCESS; } vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); @@ -4854,46 +5458,63 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, qdf_spin_unlock_bh(&pdev->vdev_list_lock); pdev->vdev_count++; + if (wlan_op_mode_sta != vdev->opmode && + wlan_op_mode_ndi != vdev->opmode) + vdev->ap_bridge_enabled = true; + else + vdev->ap_bridge_enabled = false; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s: wlan_cfg_ap_bridge_enabled %d", + __func__, vdev->ap_bridge_enabled); + dp_tx_vdev_attach(vdev); if (pdev->vdev_count == 1) dp_lro_hash_setup(soc, pdev); - dp_info("Created vdev %pK (%pM)", vdev, vdev->mac_addr.raw); + dp_info("Created vdev %pK ("QDF_MAC_ADDR_FMT")", vdev, + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); DP_STATS_INIT(vdev); if (wlan_op_mode_sta == vdev->opmode) - dp_peer_create_wifi3((struct cdp_vdev *)vdev, - vdev->mac_addr.raw, - NULL); + dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id, + vdev->mac_addr.raw); - return (struct cdp_vdev *)vdev; + return QDF_STATUS_SUCCESS; fail0: - return NULL; + return QDF_STATUS_E_FAILURE; } /** * dp_vdev_register_wifi3() - Register VDEV operations from osif layer - * @vdev: Datapath VDEV handle + * @soc: Datapath soc handle + * @vdev_id: id of Datapath VDEV handle * @osif_vdev: OSIF vdev handle - * @ctrl_vdev: UMAC vdev handle * @txrx_ops: Tx and Rx operations * * Return: DP VDEV handle on success, NULL on failure */ -static void dp_vdev_register_wifi3(struct cdp_vdev *vdev_handle, - void *osif_vdev, struct cdp_ctrl_objmgr_vdev *ctrl_vdev, - struct ol_txrx_ops *txrx_ops) +static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc, + uint8_t vdev_id, + ol_osif_vdev_handle osif_vdev, + struct ol_txrx_ops *txrx_ops) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (!vdev) + return QDF_STATUS_E_FAILURE; + vdev->osif_vdev = osif_vdev; - vdev->ctrl_vdev = ctrl_vdev; vdev->osif_rx = txrx_ops->rx.rx; vdev->osif_rx_stack = txrx_ops->rx.rx_stack; vdev->osif_rx_flush = txrx_ops->rx.rx_flush; vdev->osif_gro_flush = txrx_ops->rx.rx_gro_flush; vdev->osif_rsim_rx_decap = txrx_ops->rx.rsim_rx_decap; + vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx; + vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush; vdev->osif_get_key = txrx_ops->get_key; vdev->osif_rx_mon = txrx_ops->rx.mon; vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext; @@ -4918,6 +5539,8 @@ static void dp_vdev_register_wifi3(struct cdp_vdev *vdev_handle, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, "DP Vdev Register success"); + + return QDF_STATUS_SUCCESS; } /** @@ -5001,11 +5624,13 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) for (m = 0; m < n ; m++) { peer = peer_array[m]; - dp_info("peer: %pM is getting deleted", - peer->mac_addr.raw); + dp_info("peer: "QDF_MAC_ADDR_FMT" is getting deleted", + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* only if peer valid is true */ if (peer->valid) - dp_peer_delete_wifi3(peer, 0); + dp_peer_delete_wifi3((struct cdp_soc_t *)soc, + vdev->vdev_id, + peer->mac_addr.raw, 0); } qdf_mem_free(peer_array); } @@ -5022,8 +5647,8 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) * with ref count leak */ SET_PEER_REF_CNT_ONE(peer); - dp_info("peer: %pM is getting unmap", - peer->mac_addr.raw); + dp_info("peer: "QDF_MAC_ADDR_FMT" is getting unmap", + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* free AST entries of peer */ dp_peer_flush_ast_entry(soc, peer, peer_ids[i], @@ -5040,27 +5665,31 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) /* * dp_vdev_detach_wifi3() - Detach txrx vdev - * @txrx_vdev: Datapath VDEV handle - * @callback: Callback OL_IF on completion of detach + * @cdp_soc: Datapath soc handle + * @vdev_id: VDEV Id + * @callback: Callback OL_IF on completion of detach * @cb_context: Callback context * */ -static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, - ol_txrx_vdev_delete_cb callback, void *cb_context) +static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, + ol_txrx_vdev_delete_cb callback, + void *cb_context) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_soc *soc = (struct dp_soc *)cdp_soc; struct dp_pdev *pdev; - struct dp_soc *soc; struct dp_neighbour_peer *peer = NULL; struct dp_neighbour_peer *temp_peer = NULL; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) + return QDF_STATUS_E_FAILURE; - /* preconditions */ - qdf_assert_always(vdev); pdev = vdev->pdev; - soc = pdev->soc; if (wlan_op_mode_sta == vdev->opmode) - dp_peer_delete_wifi3(vdev->vap_self_peer, 0); + dp_peer_delete_wifi3((struct cdp_soc_t *)soc, vdev->vdev_id, + vdev->vap_self_peer->mac_addr.raw, 0); /* * If Target is hung, flush all peers before detaching vdev @@ -5069,8 +5698,16 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, */ if (!hif_is_target_ready(HIF_GET_SOFTC(soc->hif_handle))) dp_vdev_flush_peers((struct cdp_vdev *)vdev, false); + else if (hif_get_target_status(soc->hif_handle) == TARGET_STATUS_RESET) + dp_vdev_flush_peers((struct cdp_vdev *)vdev, true); dp_rx_vdev_detach(vdev); + /* + * move it after dp_rx_vdev_detach(), + * as the call back done in dp_rx_vdev_detach() + * still need to get vdev pointer by vdev_id. + */ + soc->vdev_id_map[vdev->vdev_id] = NULL; /* * Use peer_ref_mutex while accessing peer_list, in case * a peer is in the process of being removed from the list. @@ -5079,14 +5716,19 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, /* check that the vdev has no peers allocated */ if (!TAILQ_EMPTY(&vdev->peer_list)) { /* debug print - will be removed later */ - dp_warn("not deleting vdev object %pK (%pM) until deletion finishes for all its peers", - vdev, vdev->mac_addr.raw); + dp_warn("not deleting vdev object %pK ("QDF_MAC_ADDR_FMT") until deletion finishes for all its peers", + vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); + + if (vdev->vdev_dp_ext_handle) { + qdf_mem_free(vdev->vdev_dp_ext_handle); + vdev->vdev_dp_ext_handle = NULL; + } /* indicate that the vdev needs to be deleted */ vdev->delete.pending = 1; vdev->delete.callback = callback; vdev->delete.context = cb_context; qdf_spin_unlock_bh(&soc->peer_ref_mutex); - return; + return QDF_STATUS_E_FAILURE; } qdf_spin_unlock_bh(&soc->peer_ref_mutex); @@ -5124,11 +5766,20 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, pdev->monitor_vdev = NULL; } - dp_info("deleting vdev object %pK (%pM)", vdev, vdev->mac_addr.raw); + if (vdev->vdev_dp_ext_handle) { + qdf_mem_free(vdev->vdev_dp_ext_handle); + vdev->vdev_dp_ext_handle = NULL; + } + + dp_info("deleting vdev object %pK ("QDF_MAC_ADDR_FMT")", vdev, + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); + qdf_mem_free(vdev); if (callback) callback(cb_context); + + return QDF_STATUS_SUCCESS; } #ifdef FEATURE_AST @@ -5144,6 +5795,7 @@ static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, { struct dp_ast_entry *ast_entry, *temp_ast_entry; + dp_debug("peer: %pK, self_ast: %pK", peer, peer->self_ast_entry); DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry) dp_peer_del_ast(soc, ast_entry); @@ -5227,25 +5879,26 @@ static inline void dp_peer_rx_bufq_resources_init(struct dp_peer *peer) /* * dp_peer_create_wifi3() - attach txrx peer - * @txrx_vdev: Datapath VDEV handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @peer_mac_addr: Peer MAC address * - * Return: DP peeer handle on success, NULL on failure + * Return: 0 on success, -1 on failure */ -static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, - uint8_t *peer_mac_addr, struct cdp_ctrl_objmgr_peer *ctrl_peer) +static QDF_STATUS +dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac_addr) { struct dp_peer *peer; int i; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_pdev *pdev; - struct dp_soc *soc; struct cdp_peer_cookie peer_cookie; enum cdp_txrx_ast_entry_type ast_type = CDP_TXRX_AST_TYPE_STATIC; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); - /* preconditions */ - qdf_assert(vdev); - qdf_assert(peer_mac_addr); + if (!vdev || !peer_mac_addr) + return QDF_STATUS_E_FAILURE; pdev = vdev->pdev; soc = pdev->soc; @@ -5279,11 +5932,12 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, * increment the count back. */ if (soc->cdp_soc.ol_ops->peer_unref_delete) { - soc->cdp_soc.ol_ops->peer_unref_delete(pdev->ctrl_pdev, + soc->cdp_soc.ol_ops->peer_unref_delete( + soc->ctrl_psoc, + pdev->pdev_id, peer->mac_addr.raw, vdev->mac_addr.raw, - vdev->opmode, peer->ctrl_peer, ctrl_peer); + vdev->opmode); } - peer->ctrl_peer = ctrl_peer; peer->valid = 1; dp_local_peer_id_alloc(pdev, peer); @@ -5294,7 +5948,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, DP_STATS_INIT(peer); DP_STATS_UPD(peer, rx.avg_rssi, INVALID_RSSI); - return (void *)peer; + return QDF_STATUS_SUCCESS; } else { /* * When a STA roams from RPTR AP to ROOT AP and vice versa, we @@ -5314,7 +5968,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, #endif if (!peer) - return NULL; /* failure */ + return QDF_STATUS_E_FAILURE; /* failure */ qdf_mem_zero(peer, sizeof(struct dp_peer)); @@ -5322,7 +5976,6 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, /* store provided params */ peer->vdev = vdev; - peer->ctrl_peer = ctrl_peer; if ((vdev->opmode == wlan_op_mode_sta) && !qdf_mem_cmp(peer_mac_addr, &vdev->mac_addr.raw[0], @@ -5337,13 +5990,13 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, qdf_mem_copy( &peer->mac_addr.raw[0], peer_mac_addr, QDF_MAC_ADDR_SIZE); - /* TODO: See of rx_opt_proc is really required */ - peer->rx_opt_proc = soc->rx_opt_proc; - /* initialize the peer_id */ for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) peer->peer_ids[i] = HTT_INVALID_PEER; + /* reset the ast index to flowid table */ + dp_peer_reset_flowq_map(peer); + qdf_spin_lock_bh(&soc->peer_ref_mutex); qdf_atomic_init(&peer->ref_cnt); @@ -5365,8 +6018,8 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, /* Initialize the peer state */ peer->state = OL_TXRX_PEER_STATE_DISC; - dp_info("vdev %pK created peer %pK (%pM) ref_cnt: %d", - vdev, peer, peer->mac_addr.raw, + dp_info("vdev %pK created peer %pK ("QDF_MAC_ADDR_FMT") ref_cnt: %d", + vdev, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw), qdf_atomic_read(&peer->ref_cnt)); /* * For every peer MAp message search and set if bss_peer @@ -5396,6 +6049,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); peer_cookie.ctx = NULL; + peer_cookie.pdev_id = pdev->pdev_id; peer_cookie.cookie = pdev->next_peer_cookie++; #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE dp_wdi_event_handler(WDI_EVENT_PEER_CREATE, pdev->soc, @@ -5407,10 +6061,11 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, pdev->next_peer_cookie--; qdf_err("Failed to initialize peer rate stats"); } else { - peer->wlanstats_ctx = (void *)peer_cookie.ctx; + peer->wlanstats_ctx = (struct cdp_peer_rate_stats_ctx *) + peer_cookie.ctx; } } - return (void *)peer; + return QDF_STATUS_SUCCESS; } /* @@ -5533,27 +6188,32 @@ static void dp_peer_setup_get_reo_hash(struct dp_vdev *vdev, /* * dp_peer_setup_wifi3() - initialize the peer - * @vdev_hdl: virtual device object - * @peer: Peer object + * @soc_hdl: soc handle object + * @vdev_id : vdev_id of vdev object + * @peer_mac: Peer's mac address * - * Return: void + * Return: QDF_STATUS */ -static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) +static QDF_STATUS +dp_peer_setup_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) { - struct dp_peer *peer = (struct dp_peer *)peer_hdl; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_pdev *pdev; - struct dp_soc *soc; bool hash_based = 0; enum cdp_host_reo_dest_ring reo_dest; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + struct dp_peer *peer = + dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id); - /* preconditions */ - qdf_assert(vdev); - qdf_assert(peer); + if (!vdev || !peer || peer->delete_in_progress) { + status = QDF_STATUS_E_FAILURE; + goto fail; + } pdev = vdev->pdev; - soc = pdev->soc; - dp_peer_setup_get_reo_hash(vdev, &reo_dest, &hash_based); dp_info("pdev: %d vdev :%d opmode:%u hash-based-steering:%d default-reo_dest:%u", @@ -5568,13 +6228,17 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) * which is REO2TCL ring. for this reason we should * not setup reo_queues and default route for bss_peer. */ - if (peer->bss_peer && vdev->opmode == wlan_op_mode_ap) - return; + if (peer->bss_peer && vdev->opmode == wlan_op_mode_ap) { + status = QDF_STATUS_E_FAILURE; + goto fail; + } if (soc->cdp_soc.ol_ops->peer_set_default_routing) { /* TODO: Check the destination ring number to be passed to FW */ soc->cdp_soc.ol_ops->peer_set_default_routing( - pdev->ctrl_pdev, peer->mac_addr.raw, + soc->ctrl_psoc, + peer->vdev->pdev->pdev_id, + peer->mac_addr.raw, peer->vdev->vdev_id, hash_based, reo_dest); } @@ -5583,26 +6247,34 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) dp_peer_rx_init(pdev, peer); dp_peer_tx_init(pdev, peer); - return; + dp_peer_ppdu_delayed_ba_init(peer); + +fail: + if (peer) + dp_peer_unref_delete(peer); + return status; } /* * dp_cp_peer_del_resp_handler - Handle the peer delete response * @soc_hdl: Datapath SOC handle - * @vdev_hdl: virtual device object + * @vdev_id: id of virtual device object * @mac_addr: Mac address of the peer * - * Return: void + * Return: QDF_STATUS */ -static void dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl, - struct cdp_vdev *vdev_hdl, - uint8_t *mac_addr) +static QDF_STATUS dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *mac_addr) { struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_ast_entry *ast_entry = NULL; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; txrx_ast_free_cb cb = NULL; void *cookie; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) + return QDF_STATUS_E_FAILURE; qdf_spin_lock_bh(&soc->ast_lock); @@ -5621,7 +6293,7 @@ static void dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl, */ if (!ast_entry || ast_entry->peer || !ast_entry->delete_in_progress) { qdf_spin_unlock_bh(&soc->ast_lock); - return; + return QDF_STATUS_E_FAILURE; } if (ast_entry->is_mapped) @@ -5640,39 +6312,13 @@ static void dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl, if (cb) { cb(soc->ctrl_psoc, - soc, + dp_soc_to_cdp_soc(soc), cookie, CDP_TXRX_AST_DELETED); } qdf_mem_free(ast_entry); -} - -/* - * dp_set_vdev_tx_encap_type() - set the encap type of the vdev - * @vdev_handle: virtual device object - * @htt_pkt_type: type of pkt - * - * Return: void - */ -static void dp_set_vdev_tx_encap_type(struct cdp_vdev *vdev_handle, - enum htt_cmn_pkt_type val) -{ - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - vdev->tx_encap_type = val; -} -/* - * dp_set_vdev_rx_decap_type() - set the decap type of the vdev - * @vdev_handle: virtual device object - * @htt_pkt_type: type of pkt - * - * Return: void - */ -static void dp_set_vdev_rx_decap_type(struct cdp_vdev *vdev_handle, - enum htt_cmn_pkt_type val) -{ - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - vdev->rx_decap_type = val; + return QDF_STATUS_SUCCESS; } /* @@ -5709,30 +6355,41 @@ static void dp_get_ba_aging_timeout(struct cdp_soc_t *txrx_soc, /* * dp_set_pdev_reo_dest() - set the reo destination ring for this pdev - * @pdev_handle: physical device object + * @txrx_soc: cdp soc handle + * @pdev_id: id of physical device object * @val: reo destination ring index (1 - 4) * - * Return: void + * Return: QDF_STATUS */ -static void dp_set_pdev_reo_dest(struct cdp_pdev *pdev_handle, - enum cdp_host_reo_dest_ring val) +static QDF_STATUS +dp_set_pdev_reo_dest(struct cdp_soc_t *txrx_soc, uint8_t pdev_id, + enum cdp_host_reo_dest_ring val) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)txrx_soc, + pdev_id); - if (pdev) + if (pdev) { pdev->reo_dest = val; + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; } /* * dp_get_pdev_reo_dest() - get the reo destination for this pdev - * @pdev_handle: physical device object + * @txrx_soc: cdp soc handle + * @pdev_id: id of physical device object * * Return: reo destination ring index */ static enum cdp_host_reo_dest_ring -dp_get_pdev_reo_dest(struct cdp_pdev *pdev_handle) +dp_get_pdev_reo_dest(struct cdp_soc_t *txrx_soc, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)txrx_soc, + pdev_id); if (pdev) return pdev->reo_dest; @@ -5740,42 +6397,58 @@ dp_get_pdev_reo_dest(struct cdp_pdev *pdev_handle) return cdp_host_reo_dest_ring_unknown; } +#ifdef ATH_SUPPORT_NAC /* - * dp_set_filter_neighbour_peers() - set filter neighbour peers for smart mesh + * dp_set_filter_neigh_peers() - set filter neighbour peers for smart mesh * @pdev_handle: device object * @val: value to be set * * Return: void */ -static int dp_set_filter_neighbour_peers(struct cdp_pdev *pdev_handle, - uint32_t val) +static int dp_set_filter_neigh_peers(struct dp_pdev *pdev, + bool val) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - /* Enable/Disable smart mesh filtering. This flag will be checked * during rx processing to check if packets are from NAC clients. */ pdev->filter_neighbour_peers = val; return 0; } +#else +static int dp_set_filter_neigh_peers(struct dp_pdev *pdev, + bool val) +{ + return 0; +} +#endif /* ATH_SUPPORT_NAC */ +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) /* * dp_update_filter_neighbour_peers() - set neighbour peers(nac clients) * address for smart mesh filtering - * @vdev_handle: virtual device object + * @txrx_soc: cdp soc handle + * @vdev_id: id of virtual device object * @cmd: Add/Del command * @macaddr: nac client mac address * - * Return: void + * Return: success/failure */ -static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, +static int dp_update_filter_neighbour_peers(struct cdp_soc_t *soc, + uint8_t vdev_id, uint32_t cmd, uint8_t *macaddr) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - struct dp_pdev *pdev = vdev->pdev; + struct dp_pdev *pdev; struct dp_neighbour_peer *peer = NULL; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); - if (!macaddr) + if (!vdev || !macaddr) + goto fail0; + + pdev = vdev->pdev; + + if (!pdev) goto fail0; /* Store address of NAC (neighbour peer) which will be checked @@ -5804,8 +6477,18 @@ static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, /* first neighbour */ if (!pdev->neighbour_peers_added) { + QDF_STATUS status = QDF_STATUS_SUCCESS; + pdev->neighbour_peers_added = true; - dp_ppdu_ring_cfg(pdev); + dp_mon_filter_setup_smart_monitor(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("smart mon filter setup failed")); + dp_mon_filter_reset_smart_monitor(pdev); + pdev->neighbour_peers_added = false; + } } return 1; @@ -5824,15 +6507,20 @@ static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, } /* last neighbour deleted */ if (TAILQ_EMPTY(&pdev->neighbour_peers_list)) { + QDF_STATUS status = QDF_STATUS_SUCCESS; + pdev->neighbour_peers_added = false; - dp_ppdu_ring_cfg(pdev); + dp_mon_filter_reset_smart_monitor(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("smart mon filter clear failed")); + } + } qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); - - if (!pdev->mcopy_mode && !pdev->neighbour_peers_added && - !pdev->enhanced_stats_en) - dp_ppdu_ring_reset(pdev); return 1; } @@ -5840,38 +6528,69 @@ static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, fail0: return 0; } +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ /* * dp_get_sec_type() - Get the security type - * @peer: Datapath peer handle + * @soc: soc handle + * @vdev_id: id of dp handle + * @peer_mac: mac of datapath PEER handle * @sec_idx: Security id (mcast, ucast) * * return sec_type: Security type */ -static int dp_get_sec_type(struct cdp_peer *peer, uint8_t sec_idx) +static int dp_get_sec_type(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, uint8_t sec_idx) { - struct dp_peer *dpeer = (struct dp_peer *)peer; + int sec_type = 0; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); - return dpeer->security[sec_idx].sec_type; + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + goto fail; + } + + sec_type = peer->security[sec_idx].sec_type; +fail: + if (peer) + dp_peer_unref_delete(peer); + return sec_type; } /* * dp_peer_authorize() - authorize txrx peer - * @peer_handle: Datapath peer handle + * @soc: soc handle + * @vdev_id: id of dp handle + * @peer_mac: mac of datapath PEER handle * @authorize * */ -static void dp_peer_authorize(struct cdp_peer *peer_handle, uint32_t authorize) +static QDF_STATUS +dp_peer_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, uint32_t authorize) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - struct dp_soc *soc; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_peer *peer = dp_peer_find_hash_find(soc, + peer_mac, + 0, vdev_id); - if (peer) { - soc = peer->vdev->pdev->soc; + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + } else { qdf_spin_lock_bh(&soc->peer_ref_mutex); peer->authorize = authorize ? 1 : 0; qdf_spin_unlock_bh(&soc->peer_ref_mutex); } + + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* @@ -5921,10 +6640,10 @@ static void dp_peer_release_mem(struct dp_soc *soc, { if (soc->cdp_soc.ol_ops->peer_unref_delete) soc->cdp_soc.ol_ops->peer_unref_delete( - pdev->ctrl_pdev, + soc->ctrl_psoc, + pdev->pdev_id, peer->mac_addr.raw, vdev_mac_addr, - vdev_opmode, peer->ctrl_peer, - NULL); + vdev_opmode); /* * Peer AST list hast to be empty here @@ -5954,13 +6673,15 @@ static void dp_delete_pending_vdev(struct dp_pdev *pdev, struct dp_vdev *vdev, vdev_delete_cb = vdev->delete.callback; vdev_delete_context = vdev->delete.context; - dp_info("deleting vdev object %pK (%pM)- its last peer is done", - vdev, vdev->mac_addr.raw); + dp_info("deleting vdev object %pK ("QDF_MAC_ADDR_FMT")- its last peer is done", + vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); /* all peers are gone, go ahead and delete it */ dp_tx_flow_pool_unmap_handler(pdev, vdev_id, FLOW_TYPE_VDEV, vdev_id); dp_tx_vdev_detach(vdev); + pdev->soc->vdev_id_map[vdev_id] = NULL; + if (wlan_op_mode_monitor == vdev->opmode) { pdev->monitor_vdev = NULL; } else { @@ -5969,8 +6690,8 @@ static void dp_delete_pending_vdev(struct dp_pdev *pdev, struct dp_vdev *vdev, qdf_spin_unlock_bh(&pdev->vdev_list_lock); } - dp_info("deleting vdev object %pK (%pM)", - vdev, vdev->mac_addr.raw); + dp_info("deleting vdev object %pK ("QDF_MAC_ADDR_FMT")", + vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); qdf_mem_free(vdev); vdev = NULL; @@ -5983,9 +6704,8 @@ static void dp_delete_pending_vdev(struct dp_pdev *pdev, struct dp_vdev *vdev, * @peer_handle: Datapath peer handle * */ -void dp_peer_unref_delete(void *peer_handle) +void dp_peer_unref_delete(struct dp_peer *peer) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; struct dp_vdev *vdev = peer->vdev; struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; @@ -5998,7 +6718,6 @@ void dp_peer_unref_delete(void *peer_handle) enum wlan_op_mode vdev_opmode; uint8_t vdev_mac_addr[QDF_MAC_ADDR_SIZE]; - /* * Hold the lock all the way from checking if the peer ref count * is zero until the peer references are removed from the hash @@ -6022,7 +6741,8 @@ void dp_peer_unref_delete(void *peer_handle) soc->peer_id_to_obj_map[peer_id] = NULL; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "Deleting peer %pK (%pM)", peer, peer->mac_addr.raw); + "Deleting peer %pK ("QDF_MAC_ADDR_FMT")", peer, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* remove the reference to the peer from the hash table */ dp_peer_find_hash_remove(soc, peer); @@ -6030,7 +6750,6 @@ void dp_peer_unref_delete(void *peer_handle) qdf_spin_lock_bh(&soc->ast_lock); if (peer->self_ast_entry) { dp_peer_del_ast(soc, peer->self_ast_entry); - peer->self_ast_entry = NULL; } qdf_spin_unlock_bh(&soc->ast_lock); @@ -6055,7 +6774,8 @@ void dp_peer_unref_delete(void *peer_handle) qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); peer_cookie.ctx = NULL; - peer_cookie.ctx = (void *)peer->wlanstats_ctx; + peer_cookie.ctx = (struct cdp_stats_cookie *) + peer->wlanstats_ctx; #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE dp_wdi_event_handler(WDI_EVENT_PEER_DESTROY, pdev->soc, @@ -6119,39 +6839,39 @@ static inline void dp_peer_rx_bufq_resources_deinit(struct dp_peer *peer) /* * dp_peer_detach_wifi3() – Detach txrx peer - * @peer_handle: Datapath peer handle + * @soc_hdl: soc handle + * @vdev_id: id of dp handle + * @peer_mac: mac of datapath PEER handle * @bitmap: bitmap indicating special handling of request. * */ -static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap) +static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_mac, uint32_t bitmap) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - struct dp_soc *soc = peer->vdev->pdev->soc; - - /* redirect the peer's rx delivery function to point to a - * discard func - */ - - peer->rx_opt_proc = dp_rx_discard; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, + 0, vdev_id); - /* Do not make ctrl_peer to NULL for connected sta peers. - * We need ctrl_peer to release the reference during dp - * peer free. This reference was held for - * obj_mgr peer during the creation of dp peer. - */ - if (!(peer->vdev && (peer->vdev->opmode != wlan_op_mode_sta) && - !peer->bss_peer)) - peer->ctrl_peer = NULL; + /* Peer can be null for monitor vap mac address */ + if (!peer) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid peer\n", __func__); + return QDF_STATUS_E_FAILURE; + } if (!peer->valid) { - dp_err("Invalid peer: %pM", peer->mac_addr.raw); - return; + dp_peer_unref_delete(peer); + dp_err("Invalid peer: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); + return QDF_STATUS_E_ALREADY; } peer->valid = 0; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("peer %pK (%pM)"), peer, peer->mac_addr.raw); + FL("peer %pK ("QDF_MAC_ADDR_FMT")"), peer, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); dp_local_peer_id_free(peer->vdev->pdev, peer); @@ -6161,6 +6881,7 @@ static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap) dp_peer_rx_bufq_resources_deinit(peer); qdf_spinlock_destroy(&peer->peer_info_lock); + dp_peer_multipass_list_remove(peer); /* * Remove the reference added during peer_attach. @@ -6168,103 +6889,132 @@ static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap) * PEER_UNMAP message arrives to remove the other * reference, added by the PEER_MAP message. */ - dp_peer_unref_delete(peer_handle); + dp_peer_unref_delete(peer); + /* + * Remove the reference taken above + */ + dp_peer_unref_delete(peer); + + return QDF_STATUS_SUCCESS; } /* * dp_get_vdev_mac_addr_wifi3() – Detach txrx peer - * @peer_handle: Datapath peer handle + * @soc_hdl: Datapath soc handle + * @vdev_id: virtual interface id + * + * Return: MAC address on success, NULL on failure. * */ -static uint8 *dp_get_vdev_mac_addr_wifi3(struct cdp_vdev *pvdev) +static uint8 *dp_get_vdev_mac_addr_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { - struct dp_vdev *vdev = (struct dp_vdev *)pvdev; - return vdev->mac_addr.raw; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) + return NULL; + + return vdev->mac_addr.raw; } /* * dp_vdev_set_wds() - Enable per packet stats - * @vdev_handle: DP VDEV handle + * @soc: DP soc handle + * @vdev_id: id of DP VDEV handle * @val: value * * Return: none */ -static int dp_vdev_set_wds(void *vdev_handle, uint32_t val) +static int dp_vdev_set_wds(struct cdp_soc_t *soc, uint8_t vdev_id, uint32_t val) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (!vdev) + return QDF_STATUS_E_FAILURE; vdev->wds_enabled = val; - return 0; + return QDF_STATUS_SUCCESS; } /* - * dp_get_vdev_from_vdev_id_wifi3() – Detach txrx peer - * @peer_handle: Datapath peer handle + * dp_get_mon_vdev_from_pdev_wifi3() - Get vdev id of monitor mode + * @soc_hdl: datapath soc handle + * @pdev_id: physical device instance id * + * Return: virtual interface id */ -static struct cdp_vdev *dp_get_vdev_from_vdev_id_wifi3(struct cdp_pdev *dev, - uint8_t vdev_id) +static uint8_t dp_get_mon_vdev_from_pdev_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)dev; - struct dp_vdev *vdev = NULL; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (qdf_unlikely(!pdev)) - return NULL; + return -EINVAL; - qdf_spin_lock_bh(&pdev->vdev_list_lock); - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - if (vdev->delete.pending) - continue; - - if (vdev->vdev_id == vdev_id) - break; - } - qdf_spin_unlock_bh(&pdev->vdev_list_lock); - - return (struct cdp_vdev *)vdev; + return pdev->monitor_vdev->vdev_id; } -/* - * dp_get_mon_vdev_from_pdev_wifi3() - Get vdev handle of monitor mode - * @dev: PDEV handle - * - * Return: VDEV handle of monitor mode - */ - -static struct cdp_vdev *dp_get_mon_vdev_from_pdev_wifi3(struct cdp_pdev *dev) +static int dp_get_opmode(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)dev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); - if (qdf_unlikely(!pdev)) - return NULL; - - return (struct cdp_vdev *)pdev->monitor_vdev; -} - -static int dp_get_opmode(struct cdp_vdev *vdev_handle) -{ - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + if (!vdev) { + dp_err("vdev for id %d is NULL", vdev_id); + return -EINVAL; + } return vdev->opmode; } +/** + * dp_get_os_rx_handles_from_vdev_wifi3() - Get os rx handles for a vdev + * @soc_hdl: ol_txrx_soc_handle handle + * @vdev_id: vdev id for which os rx handles are needed + * @stack_fn_p: pointer to stack function pointer + * @osif_handle_p: pointer to ol_osif_vdev_handle + * + * Return: void + */ static -void dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_vdev *pvdev, +void dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, ol_txrx_rx_fp *stack_fn_p, ol_osif_vdev_handle *osif_vdev_p) { - struct dp_vdev *vdev = dp_get_dp_vdev_from_cdp_vdev(pvdev); + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) + return; - qdf_assert(vdev); *stack_fn_p = vdev->osif_rx_stack; *osif_vdev_p = vdev->osif_vdev; } -static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_vdev *pvdev) +/** + * dp_get_ctrl_pdev_from_vdev() - Get control pdev of vdev + * @soc_hdl: datapath soc handle + * @vdev_id: virtual device/interface id + * + * Return: Handle to control pdev + */ +static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3( + struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { - struct dp_vdev *vdev = (struct dp_vdev *)pvdev; - struct dp_pdev *pdev = vdev->pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + struct dp_pdev *pdev; + if (!vdev || !vdev->pdev) + return NULL; + + pdev = vdev->pdev; return (struct cdp_cfg *)pdev->wlan_cfg_ctx; } @@ -6272,7 +7022,7 @@ static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_vdev *pvdev) * dp_monitor_mode_ring_config() - Send the tlv config to fw for monitor buffer * ring based on target * @soc: soc handle - * @mac_for_pdev: pdev_id + * @mac_for_pdev: WIN- pdev_id, MCL- mac id * @pdev: physical device handle * @ring_num: mac id * @htt_tlv_filter: tlv filter @@ -6288,90 +7038,89 @@ QDF_STATUS dp_monitor_mode_ring_config(struct dp_soc *soc, uint8_t mac_for_pdev, if (soc->wlan_cfg_ctx->rxdma1_enable) status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_buf_ring[ring_num] + soc->rxdma_mon_buf_ring[ring_num] .hal_srng, - RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, + RXDMA_MONITOR_BUF, + RX_MONITOR_BUFFER_SIZE, &htt_tlv_filter); else status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, pdev->rx_mac_buf_ring[ring_num] .hal_srng, - RXDMA_BUF, RX_BUFFER_SIZE, + RXDMA_BUF, RX_DATA_BUFFER_SIZE, &htt_tlv_filter); return status; } +static inline void +dp_pdev_disable_mcopy_code(struct dp_pdev *pdev) +{ + pdev->mcopy_mode = 0; + pdev->monitor_configured = false; + pdev->monitor_vdev = NULL; + qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q); +} + /** * dp_reset_monitor_mode() - Disable monitor mode - * @pdev_handle: Datapath PDEV handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of datapath PDEV handle * * Return: QDF_STATUS */ -QDF_STATUS dp_reset_monitor_mode(struct cdp_pdev *pdev_handle) +QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + uint8_t special_monitor) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct htt_rx_ring_tlv_filter htt_tlv_filter; - struct dp_soc *soc = pdev->soc; - uint8_t pdev_id; - int mac_id; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); QDF_STATUS status = QDF_STATUS_SUCCESS; - pdev_id = pdev->pdev_id; - soc = pdev->soc; + if (!pdev) + return QDF_STATUS_E_FAILURE; qdf_spin_lock_bh(&pdev->mon_lock); - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); - - status = dp_monitor_mode_ring_config(soc, mac_for_pdev, - pdev, mac_id, - htt_tlv_filter); - - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send tlv filter for monitor mode rings"); - qdf_spin_unlock_bh(&pdev->mon_lock); - return status; - } + pdev->monitor_vdev = NULL; + pdev->monitor_configured = false; - htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, - &htt_tlv_filter); + /* + * Lite monitor mode, smart monitor mode and monitor + * mode uses this APIs to filter reset and mode disable + */ + if (pdev->mcopy_mode) { +#if defined(FEATURE_PERPKT_INFO) + dp_pdev_disable_mcopy_code(pdev); + dp_mon_filter_reset_mcopy_mode(pdev); +#endif /* FEATURE_PERPKT_INFO */ + } else if (special_monitor) { +#if defined(ATH_SUPPORT_NAC) + dp_mon_filter_reset_smart_monitor(pdev); +#endif /* ATH_SUPPORT_NAC */ + } else { + dp_mon_filter_reset_mon_mode(pdev); } - pdev->monitor_vdev = NULL; - pdev->mcopy_mode = 0; - pdev->monitor_configured = false; + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to reset monitor filters")); + } qdf_spin_unlock_bh(&pdev->mon_lock); - return QDF_STATUS_SUCCESS; } -/** - * dp_set_nac() - set peer_nac - * @peer_handle: Datapath PEER handle - * - * Return: void - */ -static void dp_set_nac(struct cdp_peer *peer_handle) -{ - struct dp_peer *peer = (struct dp_peer *)peer_handle; - - peer->nac = 1; -} - /** * dp_get_tx_pending() - read pending tx * @pdev_handle: Datapath PDEV handle * * Return: outstanding tx */ -static int dp_get_tx_pending(struct cdp_pdev *pdev_handle) +static uint32_t dp_get_tx_pending(struct cdp_pdev *pdev_handle) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; @@ -6384,172 +7133,26 @@ static int dp_get_tx_pending(struct cdp_pdev *pdev_handle) * @peer_id: Peer ID * @peer_mac: MAC addr of PEER * - * Return: void + * Return: QDF_STATUS */ -static void dp_get_peer_mac_from_peer_id(struct cdp_pdev *pdev_handle, - uint32_t peer_id, uint8_t *peer_mac) +static QDF_STATUS dp_get_peer_mac_from_peer_id(struct cdp_soc_t *soc, + uint32_t peer_id, + uint8_t *peer_mac) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; struct dp_peer *peer; - if (pdev && peer_mac) { - peer = dp_peer_find_by_id(pdev->soc, (uint16_t)peer_id); + if (soc && peer_mac) { + peer = dp_peer_find_by_id((struct dp_soc *)soc, + (uint16_t)peer_id); if (peer) { qdf_mem_copy(peer_mac, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); dp_peer_unref_del_find_by_id(peer); + return QDF_STATUS_SUCCESS; } } -} - -/** - * dp_pdev_configure_monitor_rings() - configure monitor rings - * @vdev_handle: Datapath VDEV handle - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_pdev_configure_monitor_rings(struct dp_pdev *pdev) -{ - struct htt_rx_ring_tlv_filter htt_tlv_filter; - struct dp_soc *soc; - uint8_t pdev_id; - int mac_id; - QDF_STATUS status = QDF_STATUS_SUCCESS; - - pdev_id = pdev->pdev_id; - soc = pdev->soc; - - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]", - pdev->mon_filter_mode, pdev->fp_mgmt_filter, - pdev->fp_ctrl_filter, pdev->fp_data_filter, - pdev->mo_mgmt_filter, pdev->mo_ctrl_filter, - pdev->mo_data_filter); - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 1; - htt_tlv_filter.packet = 1; - htt_tlv_filter.msdu_end = 1; - htt_tlv_filter.mpdu_end = 1; - htt_tlv_filter.packet_header = 1; - htt_tlv_filter.attention = 1; - htt_tlv_filter.ppdu_start = 0; - htt_tlv_filter.ppdu_end = 0; - htt_tlv_filter.ppdu_end_user_stats = 0; - htt_tlv_filter.ppdu_end_user_stats_ext = 0; - htt_tlv_filter.ppdu_end_status_done = 0; - htt_tlv_filter.header_per_msdu = 1; - htt_tlv_filter.enable_fp = - (pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; - htt_tlv_filter.enable_md = 0; - htt_tlv_filter.enable_mo = - (pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; - htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter; - htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter; - - if (pdev->mcopy_mode) { - htt_tlv_filter.fp_data_filter = 0; - htt_tlv_filter.mo_data_filter = 0; - } else { - htt_tlv_filter.fp_data_filter = pdev->fp_data_filter; - htt_tlv_filter.mo_data_filter = pdev->mo_data_filter; - } - htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter; - htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter; - htt_tlv_filter.offset_valid = false; - - if ((pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) || - (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU)) { - htt_tlv_filter.fp_mgmt_filter = 0; - htt_tlv_filter.fp_ctrl_filter = 0; - htt_tlv_filter.fp_data_filter = 0; - htt_tlv_filter.mo_mgmt_filter = 0; - htt_tlv_filter.mo_ctrl_filter = 0; - htt_tlv_filter.mo_data_filter = 0; - } - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); - - status = dp_monitor_mode_ring_config(soc, mac_for_pdev, - pdev, mac_id, - htt_tlv_filter); - - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send tlv filter for monitor mode rings"); - return status; - } - } - - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 0; - htt_tlv_filter.packet = 0; - htt_tlv_filter.msdu_end = 0; - htt_tlv_filter.mpdu_end = 0; - if ((pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) || - (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU)) { - htt_tlv_filter.mpdu_end = 1; - } - htt_tlv_filter.attention = 0; - htt_tlv_filter.ppdu_start = 1; - htt_tlv_filter.ppdu_end = 1; - htt_tlv_filter.ppdu_end_user_stats = 1; - htt_tlv_filter.ppdu_end_user_stats_ext = 1; - htt_tlv_filter.ppdu_end_status_done = 1; - htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.enable_md = 0; - htt_tlv_filter.enable_mo = 1; - if (pdev->mcopy_mode || - (pdev->rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) { - htt_tlv_filter.packet_header = 1; - if (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) { - htt_tlv_filter.header_per_msdu = 0; - htt_tlv_filter.enable_mo = 0; - } else if (pdev->rx_enh_capture_mode == - CDP_RX_ENH_CAPTURE_MPDU_MSDU) { - htt_tlv_filter.header_per_msdu = 1; - htt_tlv_filter.enable_mo = 0; - if (pdev->is_rx_protocol_tagging_enabled || - pdev->is_rx_enh_capture_trailer_enabled) - htt_tlv_filter.msdu_end = 1; - } - } - - htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - /* - * If two back to back HTT msg sending happened in - * short time, the second HTT msg source SRNG HP - * writing has chance to fail, this has been confirmed - * by HST HW. - * for monitor mode, here is the last HTT msg for sending. - * if the 2nd HTT msg for monitor status ring sending failed, - * HW won't provide anything into 2nd monitor status ring. - * as a WAR, add some delay before 2nd HTT msg start sending, - * > 2us is required per HST HW, delay 100 us for safe. - */ - if (mac_id) - qdf_udelay(100); - - htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - } - - return status; + return QDF_STATUS_E_FAILURE; } /** @@ -6559,13 +7162,18 @@ QDF_STATUS dp_pdev_configure_monitor_rings(struct dp_pdev *pdev) * * Return: 0 on success, not 0 on failure */ -static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, +static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t special_monitor) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + QDF_STATUS status = QDF_STATUS_SUCCESS; - qdf_assert(vdev); + if (!vdev) + return QDF_STATUS_E_FAILURE; pdev = vdev->pdev; pdev->monitor_vdev = vdev; @@ -6585,40 +7193,55 @@ static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, /*Check if current pdev's monitor_vdev exists */ if (pdev->monitor_configured) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "monitor vap already created vdev=%pK\n", vdev); - qdf_assert(vdev); return QDF_STATUS_E_RESOURCES; } pdev->monitor_configured = true; + dp_mon_buf_delayed_replenish(pdev); + + dp_mon_filter_setup_mon_mode(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to reset monitor filters")); + dp_mon_filter_reset_mon_mode(pdev); + pdev->monitor_configured = false; + pdev->monitor_vdev = NULL; + } - return dp_pdev_configure_monitor_rings(pdev); + return status; } /** * dp_pdev_set_advance_monitor_filter() - Set DP PDEV monitor filter - * @pdev_handle: Datapath PDEV handle + * @soc: soc handle + * @pdev_id: id of Datapath PDEV handle * @filter_val: Flag to select Filter for monitor mode * Return: 0 on success, not 0 on failure */ static QDF_STATUS -dp_pdev_set_advance_monitor_filter(struct cdp_pdev *pdev_handle, +dp_pdev_set_advance_monitor_filter(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct cdp_monitor_filter *filter_val) { /* Many monitor VAPs can exists in a system but only one can be up at * anytime */ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct dp_vdev *vdev = pdev->monitor_vdev; - struct htt_rx_ring_tlv_filter htt_tlv_filter; - struct dp_soc *soc; - uint8_t pdev_id; - int mac_id; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_vdev *vdev; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); QDF_STATUS status = QDF_STATUS_SUCCESS; - pdev_id = pdev->pdev_id; - soc = pdev->soc; + if (!pdev) + return QDF_STATUS_E_FAILURE; + + vdev = pdev->monitor_vdev; + + if (!vdev) + return QDF_STATUS_E_FAILURE; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN, "pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK", @@ -6640,182 +7263,58 @@ dp_pdev_set_advance_monitor_filter(struct cdp_pdev *pdev_handle, pdev->mo_ctrl_filter = filter_val->mo_ctrl; pdev->mo_data_filter = filter_val->mo_data; - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]", - pdev->mon_filter_mode, pdev->fp_mgmt_filter, - pdev->fp_ctrl_filter, pdev->fp_data_filter, - pdev->mo_mgmt_filter, pdev->mo_ctrl_filter, - pdev->mo_data_filter); - - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); - - status = dp_monitor_mode_ring_config(soc, mac_for_pdev, - pdev, mac_id, - htt_tlv_filter); - - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send tlv filter for monitor mode rings"); - return status; - } - - htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - } - - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 1; - htt_tlv_filter.packet = 1; - htt_tlv_filter.msdu_end = 1; - htt_tlv_filter.mpdu_end = 1; - htt_tlv_filter.packet_header = 1; - htt_tlv_filter.attention = 1; - htt_tlv_filter.ppdu_start = 0; - htt_tlv_filter.ppdu_end = 0; - htt_tlv_filter.ppdu_end_user_stats = 0; - htt_tlv_filter.ppdu_end_user_stats_ext = 0; - htt_tlv_filter.ppdu_end_status_done = 0; - htt_tlv_filter.header_per_msdu = 1; - htt_tlv_filter.enable_fp = - (pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; - htt_tlv_filter.enable_md = 0; - htt_tlv_filter.enable_mo = - (pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; - htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter; - htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter; - if (pdev->mcopy_mode) - htt_tlv_filter.fp_data_filter = 0; - else - htt_tlv_filter.fp_data_filter = pdev->fp_data_filter; - htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter; - htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter; - htt_tlv_filter.mo_data_filter = pdev->mo_data_filter; - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); - - status = dp_monitor_mode_ring_config(soc, mac_for_pdev, - pdev, mac_id, - htt_tlv_filter); - - if (status != QDF_STATUS_SUCCESS) { - dp_err("Failed to send tlv filter for monitor mode rings"); - return status; - } - } - - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 0; - htt_tlv_filter.packet = 0; - htt_tlv_filter.msdu_end = 0; - htt_tlv_filter.mpdu_end = 0; - htt_tlv_filter.attention = 0; - htt_tlv_filter.ppdu_start = 1; - htt_tlv_filter.ppdu_end = 1; - htt_tlv_filter.ppdu_end_user_stats = 1; - htt_tlv_filter.ppdu_end_user_stats_ext = 1; - htt_tlv_filter.ppdu_end_status_done = 1; - htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.enable_md = 0; - htt_tlv_filter.enable_mo = 1; - if (pdev->mcopy_mode) { - htt_tlv_filter.packet_header = 1; - } - htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); + dp_mon_filter_setup_mon_mode(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to set filter for advance mon mode")); + dp_mon_filter_reset_mon_mode(pdev); } - return QDF_STATUS_SUCCESS; + return status; } /** - * dp_pdev_set_monitor_channel() - set monitor channel num in pdev - * @pdev_handle: Datapath PDEV handle - * - * Return: None + * dp_deliver_tx_mgmt() - Deliver mgmt frame for tx capture + * @cdp_soc : data path soc handle + * @pdev_id : pdev_id + * @nbuf: Management frame buffer */ -static -void dp_pdev_set_monitor_channel(struct cdp_pdev *pdev_handle, int chan_num) +static QDF_STATUS +dp_deliver_tx_mgmt(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - - pdev->mon_chan_num = chan_num; -} + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, + pdev_id); -/** - * dp_get_pdev_id_frm_pdev() - get pdev_id - * @pdev_handle: Datapath PDEV handle - * - * Return: pdev_id - */ -static -uint8_t dp_get_pdev_id_frm_pdev(struct cdp_pdev *pdev_handle) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + if (!pdev) + return QDF_STATUS_E_FAILURE; - return pdev->pdev_id; -} + dp_deliver_mgmt_frm(pdev, nbuf); -/** - * dp_get_delay_stats_flag() - get delay stats flag - * @pdev_handle: Datapath PDEV handle - * - * Return: 0 if flag is disabled else 1 - */ -static -bool dp_get_delay_stats_flag(struct cdp_pdev *pdev_handle) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - - return pdev->delay_stats_flag; + return QDF_STATUS_SUCCESS; } /** - * dp_pdev_set_chan_noise_floor() - set channel noise floor - * @pdev_handle: Datapath PDEV handle - * @chan_noise_floor: Channel Noise Floor - * - * Return: void + * dp_set_bsscolor() - sets bsscolor for tx capture + * @pdev: Datapath PDEV handle + * @bsscolor: new bsscolor */ -static -void dp_pdev_set_chan_noise_floor(struct cdp_pdev *pdev_handle, - int16_t chan_noise_floor) +static void +dp_mon_set_bsscolor(struct dp_pdev *pdev, uint8_t bsscolor) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - - pdev->chan_noise_floor = chan_noise_floor; + pdev->rx_mon_recv_status.bsscolor = bsscolor; } /** - * dp_vdev_get_filter_ucast_data() - get DP VDEV monitor ucast filter - * @vdev_handle: Datapath VDEV handle + * dp_pdev_get_filter_ucast_data() - get DP PDEV monitor ucast filter + * @soc : data path soc handle + * @pdev_id : pdev_id * Return: true on ucast filter flag set */ -static bool dp_vdev_get_filter_ucast_data(struct cdp_vdev *vdev_handle) +static bool dp_pdev_get_filter_ucast_data(struct cdp_pdev *pdev_handle) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - struct dp_pdev *pdev; - - pdev = vdev->pdev; + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; if ((pdev->fp_data_filter & FILTER_DATA_UCAST) || (pdev->mo_data_filter & FILTER_DATA_UCAST)) @@ -6825,16 +7324,13 @@ static bool dp_vdev_get_filter_ucast_data(struct cdp_vdev *vdev_handle) } /** - * dp_vdev_get_filter_mcast_data() - get DP VDEV monitor mcast filter - * @vdev_handle: Datapath VDEV handle + * dp_pdev_get_filter_mcast_data() - get DP PDEV monitor mcast filter + * @pdev_handle: Datapath PDEV handle * Return: true on mcast filter flag set */ -static bool dp_vdev_get_filter_mcast_data(struct cdp_vdev *vdev_handle) +static bool dp_pdev_get_filter_mcast_data(struct cdp_pdev *pdev_handle) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - struct dp_pdev *pdev; - - pdev = vdev->pdev; + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; if ((pdev->fp_data_filter & FILTER_DATA_MCAST) || (pdev->mo_data_filter & FILTER_DATA_MCAST)) @@ -6844,16 +7340,13 @@ static bool dp_vdev_get_filter_mcast_data(struct cdp_vdev *vdev_handle) } /** - * dp_vdev_get_filter_non_data() - get DP VDEV monitor non_data filter - * @vdev_handle: Datapath VDEV handle + * dp_pdev_get_filter_non_data() - get DP PDEV monitor non_data filter + * @pdev_handle: Datapath PDEV handle * Return: true on non data filter flag set */ -static bool dp_vdev_get_filter_non_data(struct cdp_vdev *vdev_handle) +static bool dp_pdev_get_filter_non_data(struct cdp_pdev *pdev_handle) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - struct dp_pdev *pdev; - - pdev = vdev->pdev; + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; if ((pdev->fp_mgmt_filter & FILTER_MGMT_ALL) || (pdev->mo_mgmt_filter & FILTER_MGMT_ALL)) { @@ -6893,6 +7386,57 @@ void dp_peer_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val) } #endif +#ifdef VDEV_PEER_PROTOCOL_COUNT +static void dp_enable_vdev_peer_protocol_count(struct cdp_soc_t *soc, + int8_t vdev_id, + bool enable) +{ + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + dp_info("enable %d vdev_id %d", enable, vdev_id); + vdev->peer_protocol_count_track = enable; +} + +static void dp_enable_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc, + int8_t vdev_id, + int drop_mask) +{ + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + dp_info("drop_mask %d vdev_id %d", drop_mask, vdev_id); + vdev->peer_protocol_count_dropmask = drop_mask; +} + +static int dp_is_vdev_peer_protocol_count_enabled(struct cdp_soc_t *soc, + int8_t vdev_id) +{ + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + dp_info("enable %d vdev_id %d", vdev->peer_protocol_count_track, + vdev_id); + return vdev->peer_protocol_count_track; +} + +static int dp_get_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc, + int8_t vdev_id) +{ + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + dp_info("drop_mask %d vdev_id %d", vdev->peer_protocol_count_dropmask, + vdev_id); + return vdev->peer_protocol_count_dropmask; +} + +#endif + bool dp_check_pdev_exists(struct dp_soc *soc, struct dp_pdev *data) { uint8_t pdev_count; @@ -7012,10 +7556,10 @@ void dp_aggregate_pdev_stats(struct dp_pdev *pdev) * @vdev_handle: Datapath VDEV handle * @stats: cdp network device stats structure * - * Return: void + * Return: QDF_STATUS */ -static void dp_vdev_getstats(void *vdev_handle, - struct cdp_dev_stats *stats) +static QDF_STATUS dp_vdev_getstats(struct cdp_vdev *vdev_handle, + struct cdp_dev_stats *stats) { struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev; @@ -7023,11 +7567,11 @@ static void dp_vdev_getstats(void *vdev_handle, struct cdp_vdev_stats *vdev_stats; if (!vdev) - return; + return QDF_STATUS_E_FAILURE; pdev = vdev->pdev; if (!pdev) - return; + return QDF_STATUS_E_FAILURE; soc = pdev->soc; @@ -7036,7 +7580,7 @@ static void dp_vdev_getstats(void *vdev_handle, if (!vdev_stats) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "DP alloc failure - unable to get alloc vdev stats"); - return; + return QDF_STATUS_E_FAILURE; } qdf_spin_lock_bh(&soc->peer_ref_mutex); @@ -7059,6 +7603,7 @@ static void dp_vdev_getstats(void *vdev_handle, qdf_mem_free(vdev_stats); + return QDF_STATUS_SUCCESS; } @@ -7067,10 +7612,10 @@ static void dp_vdev_getstats(void *vdev_handle, * @pdev_handle: Datapath PDEV handle * @stats: cdp network device stats structure * - * Return: void + * Return: QDF_STATUS */ -static void dp_pdev_getstats(void *pdev_handle, - struct cdp_dev_stats *stats) +static void dp_pdev_getstats(struct cdp_pdev *pdev_handle, + struct cdp_dev_stats *stats) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; @@ -7089,25 +7634,51 @@ static void dp_pdev_getstats(void *pdev_handle, stats->rx_bytes = pdev->stats.rx.unicast.bytes + pdev->stats.rx.multicast.bytes + pdev->stats.rx.bcast.bytes; + stats->rx_errors = pdev->stats.err.desc_alloc_fail + + pdev->stats.err.ip_csum_err + + pdev->stats.err.tcp_udp_csum_err + + pdev->stats.rx.err.mic_err + + pdev->stats.rx.err.decrypt_err + + pdev->stats.err.rxdma_error + + pdev->stats.err.reo_error; + stats->rx_dropped = pdev->stats.dropped.msdu_not_done + + pdev->stats.dropped.mec + + pdev->stats.dropped.mesh_filter + + pdev->stats.dropped.wifi_parse + + pdev->stats.dropped.mon_rx_drop + + pdev->stats.dropped.mon_radiotap_update_err; } /** * dp_get_device_stats() - get interface level packet stats - * @handle: device handle + * @soc: soc handle + * @id : vdev_id or pdev_id based on type * @stats: cdp network device stats structure * @type: device type pdev/vdev * - * Return: void + * Return: QDF_STATUS */ -static void dp_get_device_stats(void *handle, - struct cdp_dev_stats *stats, uint8_t type) +static QDF_STATUS dp_get_device_stats(struct cdp_soc_t *soc, uint8_t id, + struct cdp_dev_stats *stats, + uint8_t type) { switch (type) { case UPDATE_VDEV_STATS: - dp_vdev_getstats(handle, stats); - break; + return dp_vdev_getstats( + (struct cdp_vdev *)dp_get_vdev_from_soc_vdev_id_wifi3( + (struct dp_soc *)soc, id), stats); case UPDATE_PDEV_STATS: - dp_pdev_getstats(handle, stats); + { + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3( + (struct dp_soc *)soc, + id); + if (pdev) { + dp_pdev_getstats((struct cdp_pdev *)pdev, + stats); + return QDF_STATUS_SUCCESS; + } + } break; default: QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -7116,6 +7687,7 @@ static void dp_get_device_stats(void *handle, break; } + return QDF_STATUS_E_FAILURE; } const @@ -7163,7 +7735,7 @@ char *dp_srng_get_str_from_hal_ring_type(enum hal_ring_type ring_type) * dp_print_napi_stats(): NAPI stats * @soc - soc handle */ -static void dp_print_napi_stats(struct dp_soc *soc) +void dp_print_napi_stats(struct dp_soc *soc) { hif_print_napi_stats(soc->hif_handle); } @@ -7172,15 +7744,15 @@ static void dp_print_napi_stats(struct dp_soc *soc) * dp_txrx_host_stats_clr(): Reinitialize the txrx stats * @vdev: DP_VDEV handle * - * Return:void + * Return: QDF_STATUS */ -static inline void +static inline QDF_STATUS dp_txrx_host_stats_clr(struct dp_vdev *vdev) { struct dp_peer *peer = NULL; if (!vdev || !vdev->pdev) - return; + return QDF_STATUS_E_FAILURE; DP_STATS_CLR(vdev->pdev); DP_STATS_CLR(vdev->pdev->soc); @@ -7190,7 +7762,7 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev) TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { if (!peer) - return; + return QDF_STATUS_E_FAILURE; DP_STATS_CLR(peer); #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE @@ -7205,45 +7777,37 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev) &vdev->stats, vdev->vdev_id, UPDATE_VDEV_STATS, vdev->pdev->pdev_id); #endif + return QDF_STATUS_SUCCESS; } /* * dp_get_host_peer_stats()- function to print peer stats - * @pdev_handle: DP_PDEV handle + * @soc: dp_soc handle * @mac_addr: mac address of the peer * - * Return: void + * Return: QDF_STATUS */ -static void -dp_get_host_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr) +static QDF_STATUS +dp_get_host_peer_stats(struct cdp_soc_t *soc, uint8_t *mac_addr) { - struct dp_peer *peer; - uint8_t local_id; - - if (!mac_addr) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Invalid MAC address\n"); - return; - } - - peer = (struct dp_peer *)dp_find_peer_by_addr(pdev_handle, mac_addr, - &local_id); - - if (!peer) { + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + mac_addr, 0, + DP_VDEV_ALL); + if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Invalid peer\n", __func__); - return; - } - - /* Making sure the peer is for the specific pdev */ - if ((struct dp_pdev *)pdev_handle != peer->vdev->pdev) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s: Peer is not for this pdev\n", __func__); - return; + status = QDF_STATUS_E_FAILURE; + goto fail; } dp_print_peer_stats(peer); dp_peer_rxtid_stats(peer, dp_rx_tid_stats_cb, NULL); +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /** @@ -7284,6 +7848,7 @@ static void dp_txrx_stats_help(void) dp_info(" 28 -- Host REO Queue Statistics"); dp_info(" 29 -- Host Soc cfg param Statistics"); dp_info(" 30 -- Host pdev cfg param Statistics"); + dp_info(" 31 -- Host FISA stats"); dp_info(" 32 -- Host Register Work stats"); } @@ -7295,10 +7860,9 @@ static void dp_txrx_stats_help(void) * Return: 0 on success, print error message in case of failure */ static int -dp_print_host_stats(struct cdp_vdev *vdev_handle, +dp_print_host_stats(struct dp_vdev *vdev, struct cdp_txrx_stats_req *req) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; enum cdp_host_txrx_stats type = dp_stats_mapping_table[req->stats][STATS_HOST]; @@ -7334,7 +7898,8 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, dp_print_pdev_rx_mon_stats(pdev); break; case TXRX_REO_QUEUE_STATS: - dp_get_host_peer_stats((struct cdp_pdev *)pdev, req->peer_addr); + dp_get_host_peer_stats((struct cdp_soc_t *)pdev->soc, + req->peer_addr); break; case TXRX_SOC_CFG_PARAMS: dp_print_soc_cfg_params(pdev->soc); @@ -7348,10 +7913,17 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, case TXRX_SOC_INTERRUPT_STATS: dp_print_soc_interrupt_stats(pdev->soc); break; + case TXRX_SOC_FSE_STATS: + dp_rx_dump_fisa_table(pdev->soc); + break; case TXRX_HAL_REG_WRITE_STATS: hal_dump_reg_write_stats(pdev->soc->hal_soc); hal_dump_reg_write_srng_stats(pdev->soc->hal_soc); break; + case TXRX_SOC_REO_HW_DESC_DUMP: + dp_get_rx_reo_queue_info((struct cdp_soc_t *)pdev->soc, + vdev->vdev_id); + break; default: dp_info("Wrong Input For TxRx Host Stats"); dp_txrx_stats_help(); @@ -7360,86 +7932,6 @@ dp_print_host_stats(struct cdp_vdev *vdev_handle, return 0; } -/* - * dp_ppdu_ring_reset()- Reset PPDU Stats ring - * @pdev: DP_PDEV handle - * - * Return: void - */ -static void -dp_ppdu_ring_reset(struct dp_pdev *pdev) -{ - struct htt_rx_ring_tlv_filter htt_tlv_filter; - int mac_id; - - qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter)); - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - } -} - -/* - * dp_ppdu_ring_cfg()- Configure PPDU Stats ring - * @pdev: DP_PDEV handle - * - * Return: void - */ -static void -dp_ppdu_ring_cfg(struct dp_pdev *pdev) -{ - struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; - int mac_id; - - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 0; - htt_tlv_filter.packet = 0; - htt_tlv_filter.msdu_end = 0; - htt_tlv_filter.mpdu_end = 0; - htt_tlv_filter.attention = 0; - htt_tlv_filter.ppdu_start = 1; - htt_tlv_filter.ppdu_end = 1; - htt_tlv_filter.ppdu_end_user_stats = 1; - htt_tlv_filter.ppdu_end_user_stats_ext = 1; - htt_tlv_filter.ppdu_end_status_done = 1; - htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.enable_md = 0; - if (pdev->neighbour_peers_added && - pdev->soc->hw_nac_monitor_support) { - htt_tlv_filter.enable_md = 1; - htt_tlv_filter.packet_header = 1; - } - if (pdev->mcopy_mode) { - htt_tlv_filter.packet_header = 1; - htt_tlv_filter.enable_mo = 1; - } - htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; - if (pdev->neighbour_peers_added && - pdev->soc->hw_nac_monitor_support) - htt_tlv_filter.md_data_filter = FILTER_DATA_ALL; - - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id].hal_srng, - RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - } -} - /* * is_ppdu_txrx_capture_enabled() - API to check both pktlog and debug_sniffer * modes are enabled or not. @@ -7464,10 +7956,8 @@ static inline bool is_ppdu_txrx_capture_enabled(struct dp_pdev *pdev) *Return: 0 for success. nonzero for failure. */ static QDF_STATUS -dp_set_bpr_enable(struct cdp_pdev *pdev_handle, int val) +dp_set_bpr_enable(struct dp_pdev *pdev, int val) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - switch (val) { case CDP_BPR_DISABLE: pdev->bpr_enable = CDP_BPR_DISABLE; @@ -7516,11 +8006,9 @@ dp_set_bpr_enable(struct cdp_pdev *pdev_handle, int val) * Return: void */ static void -dp_pdev_tid_stats_ingress_inc(struct cdp_pdev *pdev, uint32_t val) +dp_pdev_tid_stats_ingress_inc(struct dp_pdev *pdev, uint32_t val) { - struct dp_pdev *dp_pdev = (struct dp_pdev *)pdev; - - dp_pdev->stats.tid_stats.ingress_stack += val; + pdev->stats.tid_stats.ingress_stack += val; } /* @@ -7531,39 +8019,55 @@ dp_pdev_tid_stats_ingress_inc(struct cdp_pdev *pdev, uint32_t val) * Return: void */ static void -dp_pdev_tid_stats_osif_drop(struct cdp_pdev *pdev, uint32_t val) +dp_pdev_tid_stats_osif_drop(struct dp_pdev *pdev, uint32_t val) { - struct dp_pdev *dp_pdev = (struct dp_pdev *)pdev; - - dp_pdev->stats.tid_stats.osif_drop += val; + pdev->stats.tid_stats.osif_drop += val; } + /* * dp_config_debug_sniffer()- API to enable/disable debug sniffer - * @pdev_handle: DP_PDEV handle + * @pdev: DP_PDEV handle * @val: user provided value * * Return: 0 for success. nonzero for failure. */ static QDF_STATUS -dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val) +dp_config_debug_sniffer(struct dp_pdev *pdev, int val) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; QDF_STATUS status = QDF_STATUS_SUCCESS; - if (pdev->mcopy_mode) - dp_reset_monitor_mode(pdev_handle); + /* + * Note: The mirror copy mode cannot co-exist with any other + * monitor modes. Hence disabling the filter for this mode will + * reset the monitor destination ring filters. + */ + if (pdev->mcopy_mode) { +#ifdef FEATURE_PERPKT_INFO + dp_pdev_disable_mcopy_code(pdev); + dp_mon_filter_reset_mcopy_mode(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to reset AM copy mode filters")); + } +#endif /* FEATURE_PERPKT_INFO */ + } switch (val) { case 0: pdev->tx_sniffer_enable = 0; - pdev->mcopy_mode = 0; pdev->monitor_configured = false; + /* + * We don't need to reset the Rx monitor status ring or call + * the API dp_ppdu_ring_reset() if all debug sniffer mode is + * disabled. The Rx monitor status ring will be disabled when + * the last mode using the monitor status ring get disabled. + */ if (!pdev->pktlog_ppdu_stats && !pdev->enhanced_stats_en && !pdev->bpr_enable) { dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id); - dp_ppdu_ring_reset(pdev); } else if (pdev->enhanced_stats_en && !pdev->bpr_enable) { dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ENH_STATS, pdev->pdev_id); @@ -7580,7 +8084,6 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val) case 1: pdev->tx_sniffer_enable = 1; - pdev->mcopy_mode = 0; pdev->monitor_configured = false; if (!pdev->pktlog_ppdu_stats) @@ -7593,14 +8096,28 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val) break; } +#ifdef FEATURE_PERPKT_INFO pdev->mcopy_mode = 1; - dp_pdev_configure_monitor_rings(pdev); - pdev->monitor_configured = true; pdev->tx_sniffer_enable = 0; + pdev->monitor_configured = true; + + /* + * Setup the M copy mode filter. + */ + dp_mon_filter_setup_mcopy_mode(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to set M_copy mode filters")); + dp_mon_filter_reset_mcopy_mode(pdev); + dp_pdev_disable_mcopy_code(pdev); + return status; + } if (!pdev->pktlog_ppdu_stats) dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_SNIFFER, pdev->pdev_id); +#endif /* FEATURE_PERPKT_INFO */ break; default: @@ -7611,25 +8128,41 @@ dp_config_debug_sniffer(struct cdp_pdev *pdev_handle, int val) return status; } +#ifdef FEATURE_PERPKT_INFO /* * dp_enable_enhanced_stats()- API to enable enhanced statistcs - * @pdev_handle: DP_PDEV handle + * @soc_handle: DP_SOC handle + * @pdev_id: id of DP_PDEV handle * - * Return: void + * Return: QDF_STATUS */ -static void -dp_enable_enhanced_stats(struct cdp_pdev *pdev_handle) +static QDF_STATUS +dp_enable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; if (pdev->enhanced_stats_en == 0) dp_cal_client_timer_start(pdev->cal_client_ctx); pdev->enhanced_stats_en = 1; - if (!pdev->mcopy_mode && !pdev->neighbour_peers_added && - !pdev->monitor_vdev) - dp_ppdu_ring_cfg(pdev); + dp_mon_filter_setup_enhanced_stats(pdev); + status = dp_mon_filter_update(pdev); + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to set enhanced mode filters")); + dp_mon_filter_reset_enhanced_stats(pdev); + dp_cal_client_timer_stop(pdev->cal_client_ctx); + pdev->enhanced_stats_en = 0; + return QDF_STATUS_E_FAILURE; + } if (is_ppdu_txrx_capture_enabled(pdev) && !pdev->bpr_enable) { dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ENH_STATS, pdev->pdev_id); @@ -7638,18 +8171,26 @@ dp_enable_enhanced_stats(struct cdp_pdev *pdev_handle) DP_PPDU_STATS_CFG_BPR_ENH, pdev->pdev_id); } + + return QDF_STATUS_SUCCESS; } /* * dp_disable_enhanced_stats()- API to disable enhanced statistcs - * @pdev_handle: DP_PDEV handle * - * Return: void + * @param soc - the soc handle + * @param pdev_id - pdev_id of pdev + * @return - QDF_STATUS */ -static void -dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) +static QDF_STATUS +dp_disable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; if (pdev->enhanced_stats_en == 1) dp_cal_client_timer_stop(pdev->cal_client_ctx); @@ -7664,14 +8205,20 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) pdev->pdev_id); } - if (!pdev->mcopy_mode && !pdev->neighbour_peers_added && - !pdev->monitor_vdev) - dp_ppdu_ring_reset(pdev); + dp_mon_filter_reset_enhanced_stats(pdev); + if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Failed to reset enhanced mode filters")); + } + + return QDF_STATUS_SUCCESS; } +#endif /* FEATURE_PERPKT_INFO */ /* * dp_get_fw_peer_stats()- function to print peer stats - * @pdev_handle: DP_PDEV handle + * @soc: soc handle + * @pdev_id : id of the pdev handle * @mac_addr: mac address of the peer * @cap: Type of htt stats requested * @is_wait: if set, wait on completion from firmware response @@ -7681,18 +8228,24 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) * 2: HTT_PEER_STATS_REQ_MODE_QUERY_TQM * 3: HTT_PEER_STATS_REQ_MODE_FLUSH_TQM * - * Return: void + * Return: QDF_STATUS */ -static void -dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, - uint32_t cap, uint32_t is_wait) +static QDF_STATUS +dp_get_fw_peer_stats(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t *mac_addr, + uint32_t cap, uint32_t is_wait) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; int i; uint32_t config_param0 = 0; uint32_t config_param1 = 0; uint32_t config_param2 = 0; uint32_t config_param3 = 0; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; HTT_DBG_EXT_STATS_PEER_INFO_IS_MAC_ADDR_SET(config_param0, 1); config_param0 |= (1 << (cap + 1)); @@ -7724,6 +8277,8 @@ dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr, 0, 0, 0); } + return QDF_STATUS_SUCCESS; + } /* This struct definition will be removed from here @@ -7739,62 +8294,229 @@ struct httstats_cmd_req { /* * dp_get_htt_stats: function to process the httstas request - * @pdev_handle: DP pdev handle + * @soc: DP soc handle + * @pdev_id: id of pdev handle * @data: pointer to request data * @data_len: length for request data * - * return: void + * return: QDF_STATUS */ -static void -dp_get_htt_stats(struct cdp_pdev *pdev_handle, void *data, uint32_t data_len) +static QDF_STATUS +dp_get_htt_stats(struct cdp_soc_t *soc, uint8_t pdev_id, void *data, + uint32_t data_len) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; struct httstats_cmd_req *req = (struct httstats_cmd_req *)data; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; QDF_ASSERT(data_len == sizeof(struct httstats_cmd_req)); dp_h2t_ext_stats_msg_send(pdev, req->stats_id, req->config_param0, req->config_param1, req->config_param2, req->config_param3, req->cookie, 0, 0); + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_set_pdev_tidmap_prty_wifi3(): update tidmap priority in pdev + * @pdev: DP_PDEV handle + * @prio: tidmap priority value passed by the user + * + * Return: QDF_STATUS_SUCCESS on success + */ +static QDF_STATUS dp_set_pdev_tidmap_prty_wifi3(struct dp_pdev *pdev, + uint8_t prio) +{ + struct dp_soc *soc = pdev->soc; + + soc->tidmap_prty = prio; + + hal_tx_set_tidmap_prty(soc->hal_soc, prio); + return QDF_STATUS_SUCCESS; +} + +/* + * dp_get_peer_param: function to get parameters in peer + * @cdp_soc: DP soc handle + * @vdev_id: id of vdev handle + * @peer_mac: peer mac address + * @param: parameter type to be set + * @val : address of buffer + * + * Return: val + */ +static QDF_STATUS dp_get_peer_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_param_type param, + cdp_config_param_type *val) +{ + return QDF_STATUS_SUCCESS; +} + +/* + * dp_set_peer_param: function to set parameters in peer + * @cdp_soc: DP soc handle + * @vdev_id: id of vdev handle + * @peer_mac: peer mac address + * @param: parameter type to be set + * @val: value of parameter to be set + * + * Return: 0 for success. nonzero for failure. + */ +static QDF_STATUS dp_set_peer_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + uint8_t *peer_mac, + enum cdp_peer_param_type param, + cdp_config_param_type val) +{ + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); + + if (!peer || peer->delete_in_progress) + goto fail; + + switch (param) { + case CDP_CONFIG_NAWDS: + peer->nawds_enabled = val.cdp_peer_param_nawds; + break; + case CDP_CONFIG_NAC: + peer->nac = !!(val.cdp_peer_param_nac); + break; + default: + break; + } + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return QDF_STATUS_SUCCESS; +} + +/* + * dp_get_pdev_param: function to get parameters from pdev + * @cdp_soc: DP soc handle + * @pdev_id: id of pdev handle + * @param: parameter type to be get + * @value : buffer for value + * + * Return: status + */ +static QDF_STATUS dp_get_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, + enum cdp_pdev_param_type param, + cdp_config_param_type *val) +{ + struct cdp_pdev *pdev = (struct cdp_pdev *) + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, + pdev_id); + if (!pdev) + return QDF_STATUS_E_FAILURE; + + switch (param) { + case CDP_CONFIG_VOW: + val->cdp_pdev_param_cfg_vow = + ((struct dp_pdev *)pdev)->delay_stats_flag; + break; + case CDP_TX_PENDING: + val->cdp_pdev_param_tx_pending = dp_get_tx_pending(pdev); + break; + case CDP_FILTER_MCAST_DATA: + val->cdp_pdev_param_fltr_mcast = + dp_pdev_get_filter_mcast_data(pdev); + break; + case CDP_FILTER_NO_DATA: + val->cdp_pdev_param_fltr_none = + dp_pdev_get_filter_non_data(pdev); + break; + case CDP_FILTER_UCAST_DATA: + val->cdp_pdev_param_fltr_ucast = + dp_pdev_get_filter_ucast_data(pdev); + break; + default: + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; } /* * dp_set_pdev_param: function to set parameters in pdev - * @pdev_handle: DP pdev handle + * @cdp_soc: DP soc handle + * @pdev_id: id of pdev handle * @param: parameter type to be set * @val: value of parameter to be set * * Return: 0 for success. nonzero for failure. */ -static QDF_STATUS dp_set_pdev_param(struct cdp_pdev *pdev_handle, +static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, enum cdp_pdev_param_type param, - uint8_t val) + cdp_config_param_type val) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc, + pdev_id); + if (!pdev) + return QDF_STATUS_E_FAILURE; + switch (param) { + case CDP_CONFIG_TX_CAPTURE: + return dp_config_debug_sniffer(pdev, + val.cdp_pdev_param_tx_capture); case CDP_CONFIG_DEBUG_SNIFFER: - return dp_config_debug_sniffer(pdev_handle, val); + return dp_config_debug_sniffer(pdev, + val.cdp_pdev_param_dbg_snf); case CDP_CONFIG_BPR_ENABLE: - return dp_set_bpr_enable(pdev_handle, val); + return dp_set_bpr_enable(pdev, val.cdp_pdev_param_bpr_enable); case CDP_CONFIG_PRIMARY_RADIO: - pdev->is_primary = val; + pdev->is_primary = val.cdp_pdev_param_primary_radio; break; case CDP_CONFIG_CAPTURE_LATENCY: - if (val == 1) - pdev->latency_capture_enable = true; - else - pdev->latency_capture_enable = false; + pdev->latency_capture_enable = val.cdp_pdev_param_cptr_latcy; break; case CDP_INGRESS_STATS: - dp_pdev_tid_stats_ingress_inc(pdev_handle, val); + dp_pdev_tid_stats_ingress_inc(pdev, + val.cdp_pdev_param_ingrs_stats); break; case CDP_OSIF_DROP: - dp_pdev_tid_stats_osif_drop(pdev_handle, val); + dp_pdev_tid_stats_osif_drop(pdev, + val.cdp_pdev_param_osif_drop); break; case CDP_CONFIG_ENH_RX_CAPTURE: - return dp_config_enh_rx_capture(pdev_handle, val); - case CDP_CONFIG_TX_CAPTURE: - return dp_config_enh_tx_capture(pdev_handle, val); + return dp_config_enh_rx_capture(pdev, + val.cdp_pdev_param_en_rx_cap); + case CDP_CONFIG_ENH_TX_CAPTURE: + return dp_config_enh_tx_capture(pdev, + val.cdp_pdev_param_en_tx_cap); + case CDP_CONFIG_HMMC_TID_OVERRIDE: + pdev->hmmc_tid_override_en = val.cdp_pdev_param_hmmc_tid_ovrd; + break; + case CDP_CONFIG_HMMC_TID_VALUE: + pdev->hmmc_tid = val.cdp_pdev_param_hmmc_tid; + break; + case CDP_CHAN_NOISE_FLOOR: + pdev->chan_noise_floor = val.cdp_pdev_param_chn_noise_flr; + break; + case CDP_TIDMAP_PRTY: + dp_set_pdev_tidmap_prty_wifi3(pdev, + val.cdp_pdev_param_tidmap_prty); + break; + case CDP_FILTER_NEIGH_PEERS: + dp_set_filter_neigh_peers(pdev, + val.cdp_pdev_param_fltr_neigh_peers); + break; + case CDP_MONITOR_CHANNEL: + pdev->mon_chan_num = val.cdp_pdev_param_monitor_chan; + break; + case CDP_MONITOR_FREQUENCY: + pdev->mon_chan_freq = val.cdp_pdev_param_mon_freq; + break; + case CDP_CONFIG_BSS_COLOR: + dp_mon_set_bsscolor(pdev, val.cdp_pdev_param_bss_color); + break; default: return QDF_STATUS_E_INVAL; } @@ -7803,149 +8525,311 @@ static QDF_STATUS dp_set_pdev_param(struct cdp_pdev *pdev_handle, /* * dp_calculate_delay_stats: function to get rx delay stats - * @vdev_handle: DP vdev handle + * @cdp_soc: DP soc handle + * @vdev_id: id of DP vdev handle * @nbuf: skb * - * Return: void + * Return: QDF_STATUS */ -static void dp_calculate_delay_stats(struct cdp_vdev *vdev_handle, - qdf_nbuf_t nbuf) +static QDF_STATUS +dp_calculate_delay_stats(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + qdf_nbuf_t nbuf) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)cdp_soc, + vdev_id); + if (vdev) { + dp_rx_compute_delay(vdev, nbuf); + return QDF_STATUS_E_FAILURE; + } - dp_rx_compute_delay(vdev, nbuf); + return QDF_STATUS_SUCCESS; } /* * dp_get_vdev_param: function to get parameters from vdev + * @cdp_soc : DP soc handle + * @vdev_id: id of DP vdev handle * @param: parameter type to get value + * @val: buffer address * - * return: void + * return: status */ -static uint32_t dp_get_vdev_param(struct cdp_vdev *vdev_handle, - enum cdp_vdev_param_type param) +static QDF_STATUS dp_get_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + enum cdp_vdev_param_type param, + cdp_config_param_type *val) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - uint32_t val; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)cdp_soc, + vdev_id); + if (!vdev) + return QDF_STATUS_E_FAILURE; switch (param) { case CDP_ENABLE_WDS: - val = vdev->wds_enabled; + val->cdp_vdev_param_wds = vdev->wds_enabled; break; case CDP_ENABLE_MEC: - val = vdev->mec_enabled; + val->cdp_vdev_param_mec = vdev->mec_enabled; break; case CDP_ENABLE_DA_WAR: - val = vdev->pdev->soc->da_war_enabled; + val->cdp_vdev_param_da_war = vdev->pdev->soc->da_war_enabled; break; default: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "param value %d is wrong\n", param); - val = -1; - break; + return QDF_STATUS_E_FAILURE; } - return val; + return QDF_STATUS_SUCCESS; } /* * dp_set_vdev_param: function to set parameters in vdev - * @param: parameter type to be set - * @val: value of parameter to be set + * @cdp_soc : DP soc handle + * @vdev_id: id of DP vdev handle + * @param: parameter type to get value + * @val: value * - * return: void + * return: QDF_STATUS */ -static void dp_set_vdev_param(struct cdp_vdev *vdev_handle, - enum cdp_vdev_param_type param, uint32_t val) +static QDF_STATUS +dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + enum cdp_vdev_param_type param, cdp_config_param_type val) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_soc *dsoc = (struct dp_soc *)cdp_soc; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3(dsoc, vdev_id); + uint32_t var = 0; + + if (!vdev) + return QDF_STATUS_E_FAILURE; + switch (param) { case CDP_ENABLE_WDS: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "wds_enable %d for vdev(%pK) id(%d)\n", - val, vdev, vdev->vdev_id); - vdev->wds_enabled = val; + val.cdp_vdev_param_wds, vdev, vdev->vdev_id); + vdev->wds_enabled = val.cdp_vdev_param_wds; break; case CDP_ENABLE_MEC: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "mec_enable %d for vdev(%pK) id(%d)\n", - val, vdev, vdev->vdev_id); - vdev->mec_enabled = val; + val.cdp_vdev_param_mec, vdev, vdev->vdev_id); + vdev->mec_enabled = val.cdp_vdev_param_mec; break; case CDP_ENABLE_DA_WAR: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "da_war_enable %d for vdev(%pK) id(%d)\n", - val, vdev, vdev->vdev_id); - vdev->pdev->soc->da_war_enabled = val; + val.cdp_vdev_param_da_war, vdev, vdev->vdev_id); + vdev->pdev->soc->da_war_enabled = val.cdp_vdev_param_da_war; dp_wds_flush_ast_table_wifi3(((struct cdp_soc_t *) vdev->pdev->soc)); break; case CDP_ENABLE_NAWDS: - vdev->nawds_enabled = val; + vdev->nawds_enabled = val.cdp_vdev_param_nawds; break; case CDP_ENABLE_MCAST_EN: - vdev->mcast_enhancement_en = val; + vdev->mcast_enhancement_en = val.cdp_vdev_param_mcast_en; break; case CDP_ENABLE_PROXYSTA: - vdev->proxysta_vdev = val; + vdev->proxysta_vdev = val.cdp_vdev_param_proxysta; break; case CDP_UPDATE_TDLS_FLAGS: - vdev->tdls_link_connected = val; + vdev->tdls_link_connected = val.cdp_vdev_param_tdls_flags; break; case CDP_CFG_WDS_AGING_TIMER: - if (val == 0) + var = val.cdp_vdev_param_aging_tmr; + if (!var) qdf_timer_stop(&vdev->pdev->soc->ast_aging_timer); - else if (val != vdev->wds_aging_timer_val) - qdf_timer_mod(&vdev->pdev->soc->ast_aging_timer, val); + else if (var != vdev->wds_aging_timer_val) + qdf_timer_mod(&vdev->pdev->soc->ast_aging_timer, var); - vdev->wds_aging_timer_val = val; + vdev->wds_aging_timer_val = var; break; case CDP_ENABLE_AP_BRIDGE: if (wlan_op_mode_sta != vdev->opmode) - vdev->ap_bridge_enabled = val; + vdev->ap_bridge_enabled = val.cdp_vdev_param_ap_brdg_en; else vdev->ap_bridge_enabled = false; break; case CDP_ENABLE_CIPHER: - vdev->sec_type = val; + vdev->sec_type = val.cdp_vdev_param_cipher_en; break; case CDP_ENABLE_QWRAP_ISOLATION: - vdev->isolation_vdev = val; + vdev->isolation_vdev = val.cdp_vdev_param_qwrap_isolation; + break; + case CDP_UPDATE_MULTIPASS: + vdev->multipass_en = val.cdp_vdev_param_update_multipass; + break; + case CDP_TX_ENCAP_TYPE: + vdev->tx_encap_type = val.cdp_vdev_param_tx_encap; + break; + case CDP_RX_DECAP_TYPE: + vdev->rx_decap_type = val.cdp_vdev_param_rx_decap; + break; + case CDP_TID_VDEV_PRTY: + vdev->tidmap_prty = val.cdp_vdev_param_tidmap_prty; + break; + case CDP_TIDMAP_TBL_ID: + vdev->tidmap_tbl_id = val.cdp_vdev_param_tidmap_tbl_id; + break; +#ifdef MESH_MODE_SUPPORT + case CDP_MESH_RX_FILTER: + dp_peer_set_mesh_rx_filter((struct cdp_vdev *)vdev, + val.cdp_vdev_param_mesh_rx_filter); + break; + case CDP_MESH_MODE: + dp_peer_set_mesh_mode((struct cdp_vdev *)vdev, + val.cdp_vdev_param_mesh_mode); + break; +#endif + case CDP_ENABLE_CSUM: + dp_info("vdev_id %d enable Checksum %d", vdev_id, + val.cdp_enable_tx_checksum); + vdev->csum_enabled = val.cdp_enable_tx_checksum; + break; + default: + break; + } + + dp_tx_vdev_update_search_flags((struct dp_vdev *)vdev); + + return QDF_STATUS_SUCCESS; +} + +/* + * dp_set_psoc_param: function to set parameters in psoc + * @cdp_soc : DP soc handle + * @param: parameter type to be set + * @val: value of parameter to be set + * + * return: QDF_STATUS + */ +static QDF_STATUS +dp_set_psoc_param(struct cdp_soc_t *cdp_soc, + enum cdp_psoc_param_type param, cdp_config_param_type val) +{ + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = soc->wlan_cfg_ctx; + + switch (param) { + case CDP_ENABLE_RATE_STATS: + soc->wlanstats_enabled = val.cdp_psoc_param_en_rate_stats; + break; + case CDP_SET_NSS_CFG: + wlan_cfg_set_dp_soc_nss_cfg(wlan_cfg_ctx, + val.cdp_psoc_param_en_nss_cfg); + /* + * TODO: masked out based on the per offloaded radio + */ + switch (val.cdp_psoc_param_en_nss_cfg) { + case dp_nss_cfg_default: + break; + case dp_nss_cfg_first_radio: + /* + * This configuration is valid for single band radio which + * is also NSS offload. + */ + case dp_nss_cfg_dbdc: + case dp_nss_cfg_dbtc: + wlan_cfg_set_num_tx_desc_pool(wlan_cfg_ctx, 0); + wlan_cfg_set_num_tx_ext_desc_pool(wlan_cfg_ctx, 0); + wlan_cfg_set_num_tx_desc(wlan_cfg_ctx, 0); + wlan_cfg_set_num_tx_ext_desc(wlan_cfg_ctx, 0); + break; + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid offload config %d", + val.cdp_psoc_param_en_nss_cfg); + } + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + FL("nss-wifi<0> nss config is enabled")); break; + default: break; } - dp_tx_vdev_update_search_flags(vdev); + return QDF_STATUS_SUCCESS; } -/** - * dp_peer_set_nawds: set nawds bit in peer - * @peer_handle: pointer to peer - * @value: enable/disable nawds +/* + * dp_get_psoc_param: function to get parameters in soc + * @cdp_soc : DP soc handle + * @param: parameter type to be set + * @val: address of buffer * - * return: void + * return: status */ -static void dp_peer_set_nawds(struct cdp_peer *peer_handle, uint8_t value) +static QDF_STATUS dp_get_psoc_param(struct cdp_soc_t *cdp_soc, + enum cdp_psoc_param_type param, + cdp_config_param_type *val) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * dp_peer_update_pkt_capture_params: Set Rx & Tx Capture flags for a peer + * @soc: DP_SOC handle + * @pdev_id: id of DP_PDEV handle + * @is_rx_pkt_cap_enable: enable/disable Rx packet capture in monitor mode + * @is_tx_pkt_cap_enable: enable/disable Tx packet capture in monitor mode + * @peer_mac: MAC address for which the above need to be enabled/disabled + * + * Return: Success if Rx & Tx capture is enabled for peer, false otherwise + */ +QDF_STATUS +dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool is_rx_pkt_cap_enable, + bool is_tx_pkt_cap_enable, + uint8_t *peer_mac) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - peer->nawds_enabled = value; + struct dp_peer *peer; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + peer = (struct dp_peer *)dp_find_peer_by_addr((struct cdp_pdev *)pdev, + peer_mac); + if (!peer) { + dp_err("Invalid Peer"); + return QDF_STATUS_E_FAILURE; + } + + dp_peer_set_rx_capture_enabled(peer, is_rx_pkt_cap_enable); + dp_peer_set_tx_capture_enabled(peer, is_tx_pkt_cap_enable); + + return QDF_STATUS_SUCCESS; } /* * dp_set_vdev_dscp_tid_map_wifi3(): Update Map ID selected for particular vdev - * @vdev_handle: DP_VDEV handle + * @soc: DP_SOC handle + * @vdev_id: id of DP_VDEV handle * @map_id:ID of map that needs to be updated * - * Return: void + * Return: QDF_STATUS */ -static void dp_set_vdev_dscp_tid_map_wifi3(struct cdp_vdev *vdev_handle, - uint8_t map_id) +static QDF_STATUS dp_set_vdev_dscp_tid_map_wifi3(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t map_id) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - vdev->dscp_tid_map_id = map_id; - return; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + if (vdev) { + vdev->dscp_tid_map_id = map_id; + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; } #ifdef DP_RATETABLE_SUPPORT @@ -7953,9 +8837,10 @@ static int dp_txrx_get_ratekbps(int preamb, int mcs, int htflag, int gintval) { uint32_t rix; + uint16_t ratecode; return dp_getrateindex((uint32_t)gintval, (uint16_t)mcs, 1, - (uint8_t)preamb, 1, &rix); + (uint8_t)preamb, 1, &rix, &ratecode); } #else static int dp_txrx_get_ratekbps(int preamb, int mcs, @@ -7966,39 +8851,39 @@ static int dp_txrx_get_ratekbps(int preamb, int mcs, #endif /* dp_txrx_get_pdev_stats - Returns cdp_pdev_stats - * @peer_handle: DP pdev handle + * @soc: DP soc handle + * @pdev_id: id of DP pdev handle + * @pdev_stats: buffer to copy to * - * return : cdp_pdev_stats pointer + * return : status success/failure */ -static struct cdp_pdev_stats* -dp_txrx_get_pdev_stats(struct cdp_pdev *pdev_handle) +static QDF_STATUS +dp_txrx_get_pdev_stats(struct cdp_soc_t *soc, uint8_t pdev_id, + struct cdp_pdev_stats *pdev_stats) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + if (!pdev) + return QDF_STATUS_E_FAILURE; dp_aggregate_pdev_stats(pdev); - return &pdev->stats; + qdf_mem_copy(pdev_stats, &pdev->stats, sizeof(struct cdp_pdev_stats)); + return QDF_STATUS_SUCCESS; } /* dp_txrx_update_vdev_me_stats(): Update vdev ME stats sent from CDP - * @vdev_handle: DP vdev handle + * @vdev: DP vdev handle * @buf: buffer containing specific stats structure * * Returns: void */ -static void dp_txrx_update_vdev_me_stats(struct cdp_vdev *vdev_handle, +static void dp_txrx_update_vdev_me_stats(struct dp_vdev *vdev, void *buf) { - struct dp_vdev *vdev = NULL; struct cdp_tx_ingress_stats *host_stats = NULL; - if (!vdev_handle) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Invalid vdev handle"); - return; - } - vdev = (struct dp_vdev *)vdev_handle; - if (!buf) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "Invalid host stats buf"); @@ -8024,55 +8909,179 @@ static void dp_txrx_update_vdev_me_stats(struct cdp_vdev *vdev_handle, } /* dp_txrx_update_vdev_host_stats(): Update stats sent through CDP - * @vdev_handle: DP vdev handle + * @soc: DP soc handle + * @vdev_id: id of DP vdev handle * @buf: buffer containing specific stats structure * @stats_id: stats type * - * Returns: void + * Returns: QDF_STATUS */ -static void dp_txrx_update_vdev_host_stats(struct cdp_vdev *vdev_handle, - void *buf, - uint16_t stats_id) +static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc, + uint8_t vdev_id, + void *buf, + uint16_t stats_id) { + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + if (!vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid vdev handle"); + return QDF_STATUS_E_FAILURE; + } + switch (stats_id) { case DP_VDEV_STATS_PKT_CNT_ONLY: break; case DP_VDEV_STATS_TX_ME: - dp_txrx_update_vdev_me_stats(vdev_handle, buf); + dp_txrx_update_vdev_me_stats(vdev, buf); break; default: qdf_info("Invalid stats_id %d", stats_id); break; } + + return QDF_STATUS_SUCCESS; } /* dp_txrx_get_peer_stats - will return cdp_peer_stats - * @peer_handle: DP_PEER handle - * - * return : cdp_peer_stats pointer + * @soc: soc handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle + * @peer_stats: buffer to copy to + * return : status success/failure + */ +static QDF_STATUS +dp_txrx_get_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, struct cdp_peer_stats *peer_stats) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); + + if (!peer || peer->delete_in_progress) { + status = QDF_STATUS_E_FAILURE; + } else + qdf_mem_copy(peer_stats, &peer->stats, + sizeof(struct cdp_peer_stats)); + + if (peer) + dp_peer_unref_delete(peer); + + return status; +} + +/* dp_txrx_get_peer_stats_param - will return specified cdp_peer_stats + * @param soc - soc handle + * @param vdev_id - vdev_id of vdev object + * @param peer_mac - mac address of the peer + * @param type - enum of required stats + * @param buf - buffer to hold the value + * return : status success/failure */ -static struct cdp_peer_stats* - dp_txrx_get_peer_stats(struct cdp_peer *peer_handle) +static QDF_STATUS +dp_txrx_get_peer_stats_param(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_peer_stats_type type, + cdp_peer_stats_param_t *buf) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + QDF_STATUS ret = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); + + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid Peer for Mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); + ret = QDF_STATUS_E_FAILURE; + } else if (type < cdp_peer_stats_max) { + switch (type) { + case cdp_peer_tx_ucast: + buf->tx_ucast = peer->stats.tx.ucast; + break; + case cdp_peer_tx_mcast: + buf->tx_mcast = peer->stats.tx.mcast; + break; + case cdp_peer_tx_rate: + buf->tx_rate = peer->stats.tx.tx_rate; + break; + case cdp_peer_tx_last_tx_rate: + buf->last_tx_rate = peer->stats.tx.last_tx_rate; + break; + case cdp_peer_tx_inactive_time: + buf->tx_inactive_time = peer->stats.tx.inactive_time; + break; + case cdp_peer_tx_ratecode: + buf->tx_ratecode = peer->stats.tx.tx_ratecode; + break; + case cdp_peer_tx_flags: + buf->tx_flags = peer->stats.tx.tx_flags; + break; + case cdp_peer_tx_power: + buf->tx_power = peer->stats.tx.tx_power; + break; + case cdp_peer_rx_rate: + buf->rx_rate = peer->stats.rx.rx_rate; + break; + case cdp_peer_rx_last_rx_rate: + buf->last_rx_rate = peer->stats.rx.last_rx_rate; + break; + case cdp_peer_rx_ratecode: + buf->rx_ratecode = peer->stats.rx.rx_ratecode; + break; + case cdp_peer_rx_ucast: + buf->rx_ucast = peer->stats.rx.unicast; + break; + case cdp_peer_rx_flags: + buf->rx_flags = peer->stats.rx.rx_flags; + break; + case cdp_peer_rx_avg_rssi: + buf->rx_avg_rssi = peer->stats.rx.avg_rssi; + break; + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid value"); + ret = QDF_STATUS_E_FAILURE; + break; + } + } else { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid value"); + ret = QDF_STATUS_E_FAILURE; + } - qdf_assert(peer); + if (peer) + dp_peer_unref_delete(peer); - return &peer->stats; + return ret; } /* dp_txrx_reset_peer_stats - reset cdp_peer_stats for particular peer - * @peer_handle: DP_PEER handle + * @soc: soc handle + * @vdev_id: id of vdev handle + * @peer_mac: mac of DP_PEER handle * - * return : void + * return : QDF_STATUS */ -static void dp_txrx_reset_peer_stats(struct cdp_peer *peer_handle) +static QDF_STATUS +dp_txrx_reset_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); - qdf_assert(peer); + if (!peer || peer->delete_in_progress) { + status = QDF_STATUS_E_FAILURE; + goto fail; + } qdf_mem_zero(&peer->stats, sizeof(peer->stats)); + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* dp_txrx_get_vdev_stats - Update buffer with cdp_vdev_stats @@ -8081,13 +9090,14 @@ static void dp_txrx_reset_peer_stats(struct cdp_peer *peer_handle) * * return : int */ -static int dp_txrx_get_vdev_stats(struct cdp_vdev *vdev_handle, void *buf, - bool is_aggregate) +static int dp_txrx_get_vdev_stats(struct cdp_soc_t *soc, uint8_t vdev_id, + void *buf, bool is_aggregate) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct cdp_vdev_stats *vdev_stats; struct dp_pdev *pdev; - struct dp_soc *soc; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); if (!vdev) return 1; @@ -8096,13 +9106,12 @@ static int dp_txrx_get_vdev_stats(struct cdp_vdev *vdev_handle, void *buf, if (!pdev) return 1; - soc = pdev->soc; vdev_stats = (struct cdp_vdev_stats *)buf; if (is_aggregate) { - qdf_spin_lock_bh(&soc->peer_ref_mutex); + qdf_spin_lock_bh(&((struct dp_soc *)soc)->peer_ref_mutex); dp_aggregate_vdev_stats(vdev, buf); - qdf_spin_unlock_bh(&soc->peer_ref_mutex); + qdf_spin_unlock_bh(&((struct dp_soc *)soc)->peer_ref_mutex); } else { qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); } @@ -8112,13 +9121,19 @@ static int dp_txrx_get_vdev_stats(struct cdp_vdev *vdev_handle, void *buf, /* * dp_get_total_per(): get total per - * @pdev_handle: DP_PDEV handle + * @soc: DP soc handle + * @pdev_id: id of DP_PDEV handle * * Return: % error rate using retries per packet and success packets */ -static int dp_get_total_per(struct cdp_pdev *pdev_handle) +static int dp_get_total_per(struct cdp_soc_t *soc, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return 0; dp_aggregate_pdev_stats(pdev); if ((pdev->stats.tx.tx_success.num + pdev->stats.tx.retries) == 0) @@ -8129,17 +9144,23 @@ static int dp_get_total_per(struct cdp_pdev *pdev_handle) /* * dp_txrx_stats_publish(): publish pdev stats into a buffer - * @pdev_handle: DP_PDEV handle + * @soc: DP soc handle + * @pdev_id: id of DP_PDEV handle * @buf: to hold pdev_stats * * Return: int */ static int -dp_txrx_stats_publish(struct cdp_pdev *pdev_handle, struct cdp_stats_extd *buf) +dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id, + struct cdp_stats_extd *buf) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct cdp_pdev_stats *buffer = (struct cdp_pdev_stats *) buf; struct cdp_txrx_stats_req req = {0,}; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return TXRX_STATS_LEVEL_OFF; dp_aggregate_pdev_stats(pdev); req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_TX; @@ -8157,29 +9178,33 @@ dp_txrx_stats_publish(struct cdp_pdev *pdev_handle, struct cdp_stats_extd *buf) req.cookie_val, 0); msleep(DP_MAX_SLEEP_TIME); - qdf_mem_copy(buffer, &pdev->stats, sizeof(pdev->stats)); + qdf_mem_copy(buf, &pdev->stats, sizeof(struct cdp_pdev_stats)); return TXRX_STATS_LEVEL; } /** * dp_set_pdev_dscp_tid_map_wifi3(): update dscp tid map in pdev - * @pdev: DP_PDEV handle + * @soc: soc handle + * @pdev_id: id of DP_PDEV handle * @map_id: ID of map that needs to be updated * @tos: index value in map * @tid: tid value passed by the user * - * Return: void + * Return: QDF_STATUS */ -static void dp_set_pdev_dscp_tid_map_wifi3(struct cdp_pdev *pdev_handle, - uint8_t map_id, uint8_t tos, uint8_t tid) +static QDF_STATUS +dp_set_pdev_dscp_tid_map_wifi3(struct cdp_soc_t *soc_handle, + uint8_t pdev_id, + uint8_t map_id, + uint8_t tos, uint8_t tid) { uint8_t dscp; - struct dp_pdev *pdev = (struct dp_pdev *) pdev_handle; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)soc_handle; + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); - if (!soc) - return; + if (!pdev) + return QDF_STATUS_E_FAILURE; dscp = (tos >> DP_IP_DSCP_SHIFT) & DP_IP_DSCP_MASK; pdev->dscp_tid_map[map_id][dscp] = tid; @@ -8187,37 +9212,10 @@ static void dp_set_pdev_dscp_tid_map_wifi3(struct cdp_pdev *pdev_handle, if (map_id < soc->num_hw_dscp_tid_map) hal_tx_update_dscp_tid(soc->hal_soc, tid, map_id, dscp); - return; -} - -/** - * dp_hmmc_tid_override_en_wifi3(): Function to enable hmmc tid override. - * @pdev_handle: pdev handle - * @val: hmmc-dscp flag value - * - * Return: void - */ -static void dp_hmmc_tid_override_en_wifi3(struct cdp_pdev *pdev_handle, - bool val) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - - pdev->hmmc_tid_override_en = val; -} - -/** - * dp_set_hmmc_tid_val_wifi3(): Function to set hmmc tid value. - * @pdev_handle: pdev handle - * @tid: tid value - * - * Return: void - */ -static void dp_set_hmmc_tid_val_wifi3(struct cdp_pdev *pdev_handle, - uint8_t tid) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + else + return QDF_STATUS_E_FAILURE; - pdev->hmmc_tid = tid; + return QDF_STATUS_SUCCESS; } /** @@ -8227,10 +9225,9 @@ static void dp_set_hmmc_tid_val_wifi3(struct cdp_pdev *pdev_handle, * * return: int */ -static int dp_fw_stats_process(struct cdp_vdev *vdev_handle, - struct cdp_txrx_stats_req *req) +static int dp_fw_stats_process(struct dp_vdev *vdev, + struct cdp_txrx_stats_req *req) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev = NULL; uint32_t stats = req->stats; uint8_t mac_id = req->mac_id; @@ -8267,19 +9264,24 @@ static int dp_fw_stats_process(struct cdp_vdev *vdev_handle, /** * dp_txrx_stats_request - function to map to firmware and host stats - * @vdev: virtual handle + * @soc: soc handle + * @vdev_id: virtual device ID * @req: stats request * * Return: QDF_STATUS */ static -QDF_STATUS dp_txrx_stats_request(struct cdp_vdev *vdev, +QDF_STATUS dp_txrx_stats_request(struct cdp_soc_t *soc_handle, + uint8_t vdev_id, struct cdp_txrx_stats_req *req) { + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_handle); int host_stats; int fw_stats; enum cdp_stats stats; int num_stats; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, + vdev_id); if (!vdev || !req) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -8338,7 +9340,7 @@ QDF_STATUS dp_txrx_stats_request(struct cdp_vdev *vdev, * dp_txrx_dump_stats() - Dump statistics * @value - Statistics option */ -static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value, +static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value, enum qdf_stats_verbosity_level level) { struct dp_soc *soc = @@ -8363,11 +9365,12 @@ static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value, break; case CDP_TXRX_TSO_STATS: - /* TODO: NOT IMPLEMENTED */ + dp_print_tso_stats(soc, level); break; case CDP_DUMP_TX_FLOW_POOL_INFO: - cdp_dump_flow_pool_info((struct cdp_soc_t *)soc); + if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH) + cdp_dump_flow_pool_info((struct cdp_soc_t *)soc); break; case CDP_DP_NAPI_STATS: @@ -8378,6 +9381,10 @@ static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value, /* TODO: NOT IMPLEMENTED */ break; + case CDP_DP_RX_FISA_STATS: + dp_rx_dump_fisa_stats(soc); + break; + default: status = QDF_STATUS_E_INVAL; break; @@ -8387,6 +9394,38 @@ static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value, } +/** + * dp_txrx_clear_dump_stats() - clear dumpStats + * @soc- soc handle + * @value - stats option + * + * Return: 0 - Success, non-zero - failure + */ +static +QDF_STATUS dp_txrx_clear_dump_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t value) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!soc) { + dp_err("%s: soc is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + + switch (value) { + case CDP_TXRX_TSO_STATS: + dp_txrx_clear_tso_stats(soc); + break; + + default: + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + #ifdef QCA_LL_TX_FLOW_CONTROL_V2 /** * dp_update_flow_control_parameters() - API to store datapath @@ -8480,6 +9519,10 @@ QDF_STATUS dp_update_config_parameters(struct cdp_soc *psoc, soc->wlan_cfg_ctx->tso_enabled = params->tso_enable; soc->wlan_cfg_ctx->lro_enabled = params->lro_enable; soc->wlan_cfg_ctx->rx_hash = params->flow_steering_enable; + soc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload = + params->p2p_tcp_udp_checksumoffload; + soc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload = + params->nan_tcp_udp_checksumoffload; soc->wlan_cfg_ctx->tcp_udp_checksumoffload = params->tcp_udp_checksumoffload; soc->wlan_cfg_ctx->napi_enabled = params->napi_enable; @@ -8502,16 +9545,21 @@ static struct cdp_wds_ops dp_ops_wds = { /* * dp_txrx_data_tx_cb_set(): set the callback for non standard tx - * @vdev_handle - datapath vdev handle + * @soc_hdl - datapath soc handle + * @vdev_id - virtual interface id * @callback - callback function * @ctxt: callback context * */ static void -dp_txrx_data_tx_cb_set(struct cdp_vdev *vdev_handle, +dp_txrx_data_tx_cb_set(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, ol_txrx_data_tx_cb callback, void *ctxt) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) + return; vdev->tx_non_std_data_callback.func = callback; vdev->tx_non_std_data_callback.ctxt = ctxt; @@ -8519,32 +9567,92 @@ dp_txrx_data_tx_cb_set(struct cdp_vdev *vdev_handle, /** * dp_pdev_get_dp_txrx_handle() - get dp handle from pdev - * @pdev_hdl: datapath pdev handle + * @soc: datapath soc handle + * @pdev_id: id of datapath pdev handle * * Return: opaque pointer to dp txrx handle */ -static void *dp_pdev_get_dp_txrx_handle(struct cdp_pdev *pdev_hdl) +static void *dp_pdev_get_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + if (qdf_unlikely(!pdev)) + return NULL; return pdev->dp_txrx_handle; } /** * dp_pdev_set_dp_txrx_handle() - set dp handle in pdev - * @pdev_hdl: datapath pdev handle + * @soc: datapath soc handle + * @pdev_id: id of datapath pdev handle * @dp_txrx_hdl: opaque pointer for dp_txrx_handle * * Return: void */ static void -dp_pdev_set_dp_txrx_handle(struct cdp_pdev *pdev_hdl, void *dp_txrx_hdl) +dp_pdev_set_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id, + void *dp_txrx_hdl) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return; pdev->dp_txrx_handle = dp_txrx_hdl; } +/** + * dp_vdev_get_dp_ext_handle() - get dp handle from vdev + * @soc: datapath soc handle + * @vdev_id: vdev id + * + * Return: opaque pointer to dp txrx handle + */ +static void *dp_vdev_get_dp_ext_handle(ol_txrx_soc_handle soc, uint8_t vdev_id) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (!vdev) + return NULL; + + return vdev->vdev_dp_ext_handle; +} + +/** + * dp_vdev_set_dp_ext_handle() - set dp handle in vdev + * @soc: datapath soc handle + * @vdev_id: vdev id + * @size: size of advance dp handle + * + * Return: QDF_STATUS + */ +static QDF_STATUS +dp_vdev_set_dp_ext_handle(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint16_t size) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + void *dp_ext_handle; + + if (!vdev) + return QDF_STATUS_E_FAILURE; + + dp_ext_handle = qdf_mem_malloc(size); + + if (!dp_ext_handle) + return QDF_STATUS_E_FAILURE; + + vdev->vdev_dp_ext_handle = dp_ext_handle; + return QDF_STATUS_SUCCESS; +} + /** * dp_soc_get_dp_txrx_handle() - get context for external-dp from dp soc * @soc_handle: datapath soc handle @@ -8575,21 +9683,111 @@ dp_soc_set_dp_txrx_handle(struct cdp_soc *soc_handle, void *txrx_handle) /** * dp_soc_map_pdev_to_lmac() - Save pdev_id to lmac_id mapping - * @pdev_hdl: datapath pdev handle + * @soc_hdl: datapath soc handle + * @pdev_id: id of the datapath pdev handle * @lmac_id: lmac id * - * Return: void + * Return: QDF_STATUS */ -static void -dp_soc_map_pdev_to_lmac(struct cdp_pdev *pdev_hdl, uint32_t lmac_id) +static QDF_STATUS +dp_soc_map_pdev_to_lmac + (struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t lmac_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + wlan_cfg_set_hw_mac_idx(soc->wlan_cfg_ctx, + pdev_id, + lmac_id); + + /*Set host PDEV ID for lmac_id*/ + wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx, + pdev_id, + lmac_id); + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_soc_handle_pdev_mode_change() - Update pdev to lmac mapping + * @soc_hdl: datapath soc handle + * @pdev_id: id of the datapath pdev handle + * @lmac_id: lmac id + * + * In the event of a dynamic mode change, update the pdev to lmac mapping + * + * Return: QDF_STATUS + */ +static QDF_STATUS +dp_soc_handle_pdev_mode_change + (struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t lmac_id) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_vdev *vdev = NULL; + uint8_t hw_pdev_id, mac_id; + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, + pdev_id); + int nss_config = wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx); + + if (qdf_unlikely(!pdev)) + return QDF_STATUS_E_FAILURE; pdev->lmac_id = lmac_id; - wlan_cfg_set_hw_macid(soc->wlan_cfg_ctx, + dp_info(" mode change %d %d\n", pdev->pdev_id, pdev->lmac_id); + + /*Set host PDEV ID for lmac_id*/ + wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx, pdev->pdev_id, - (lmac_id + 1)); + lmac_id); + + hw_pdev_id = + dp_get_target_pdev_id_for_host_pdev_id(soc, + pdev->pdev_id); + + /* + * When NSS offload is enabled, send pdev_id->lmac_id + * and pdev_id to hw_pdev_id to NSS FW + */ + if (nss_config) { + mac_id = pdev->lmac_id; + if (soc->cdp_soc.ol_ops->pdev_update_lmac_n_target_pdev_id) + soc->cdp_soc.ol_ops-> + pdev_update_lmac_n_target_pdev_id( + soc->ctrl_psoc, + &pdev_id, &mac_id, &hw_pdev_id); + } + + qdf_spin_lock_bh(&pdev->vdev_list_lock); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + HTT_TX_TCL_METADATA_PDEV_ID_SET(vdev->htt_tcl_metadata, + hw_pdev_id); + } + qdf_spin_unlock_bh(&pdev->vdev_list_lock); + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_soc_set_pdev_status_down() - set pdev down/up status + * @soc: datapath soc handle + * @pdev_id: id of datapath pdev handle + * @is_pdev_down: pdev down/up status + * + * Return: QDF_STATUS + */ +static QDF_STATUS +dp_soc_set_pdev_status_down(struct cdp_soc_t *soc, uint8_t pdev_id, + bool is_pdev_down) +{ + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + if (!pdev) + return QDF_STATUS_E_FAILURE; + + pdev->is_pdev_down = is_pdev_down; + return QDF_STATUS_SUCCESS; } /** @@ -8609,48 +9807,73 @@ dp_get_cfg_capabilities(struct cdp_soc_t *soc_handle, } #ifdef FEATURE_AST -static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) +static QDF_STATUS +dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; - struct dp_peer *peer = (struct dp_peer *)peer_hdl; - struct dp_soc *soc = (struct dp_soc *)vdev->pdev->soc; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = + dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id); + /* Peer can be null for monitor vap mac address */ + if (!peer) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid peer\n", __func__); + return QDF_STATUS_E_FAILURE; + } /* * For BSS peer, new peer is not created on alloc_node if the * peer with same address already exists , instead refcnt is * increased for existing peer. Correspondingly in delete path, * only refcnt is decreased; and peer is only deleted , when all * references are deleted. So delete_in_progress should not be set - * for bss_peer, unless only 2 reference remains (peer map reference - * and peer hash table reference). + * for bss_peer, unless only 3 reference remains (peer map reference, + * peer hash table reference and above local reference). */ - if (peer->bss_peer && (qdf_atomic_read(&peer->ref_cnt) > 2)) - return; + if (peer->bss_peer && (qdf_atomic_read(&peer->ref_cnt) > 3)) { + status = QDF_STATUS_E_FAILURE; + goto fail; + } qdf_spin_lock_bh(&soc->ast_lock); peer->delete_in_progress = true; dp_peer_delete_ast_entries(soc, peer); qdf_spin_unlock_bh(&soc->ast_lock); + +fail: + if (peer) + dp_peer_unref_delete(peer); + return status; } #endif #ifdef ATH_SUPPORT_NAC_RSSI /** * dp_vdev_get_neighbour_rssi(): Store RSSI for configured NAC - * @vdev_hdl: DP vdev handle + * @soc_hdl: DP soc handle + * @vdev_id: id of DP vdev handle + * @mac_addr: neighbour mac * @rssi: rssi value * * Return: 0 for success. nonzero for failure. */ -static QDF_STATUS dp_vdev_get_neighbour_rssi(struct cdp_vdev *vdev_hdl, +static QDF_STATUS dp_vdev_get_neighbour_rssi(struct cdp_soc_t *soc, + uint8_t vdev_id, char *mac_addr, uint8_t *rssi) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; - struct dp_pdev *pdev = vdev->pdev; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + struct dp_pdev *pdev; struct dp_neighbour_peer *peer = NULL; QDF_STATUS status = QDF_STATUS_E_FAILURE; + if (!vdev) + return status; + + pdev = vdev->pdev; *rssi = 0; qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); TAILQ_FOREACH(peer, &pdev->neighbour_peers_list, @@ -8666,33 +9889,42 @@ static QDF_STATUS dp_vdev_get_neighbour_rssi(struct cdp_vdev *vdev_hdl, return status; } -static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle, - enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, - uint8_t chan_num) +static QDF_STATUS +dp_config_for_nac_rssi(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, + enum cdp_nac_param_cmd cmd, char *bssid, + char *client_macaddr, + uint8_t chan_num) { + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3(soc, + vdev_id); + struct dp_pdev *pdev; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; - struct dp_soc *soc = (struct dp_soc *) vdev->pdev->soc; + if (!vdev) + return QDF_STATUS_E_FAILURE; + pdev = (struct dp_pdev *)vdev->pdev; pdev->nac_rssi_filtering = 1; /* Store address of NAC (neighbour peer) which will be checked * against TA of received packets. */ if (cmd == CDP_NAC_PARAM_ADD) { - dp_update_filter_neighbour_peers(vdev_handle, DP_NAC_PARAM_ADD, - client_macaddr); + dp_update_filter_neighbour_peers(cdp_soc, vdev->vdev_id, + DP_NAC_PARAM_ADD, + (uint8_t *)client_macaddr); } else if (cmd == CDP_NAC_PARAM_DEL) { - dp_update_filter_neighbour_peers(vdev_handle, + dp_update_filter_neighbour_peers(cdp_soc, vdev->vdev_id, DP_NAC_PARAM_DEL, - client_macaddr); + (uint8_t *)client_macaddr); } if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi) soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi - ((void *)vdev->pdev->ctrl_pdev, - vdev->vdev_id, cmd, bssid); + (soc->ctrl_psoc, pdev->pdev_id, + vdev->vdev_id, cmd, bssid, client_macaddr); return QDF_STATUS_SUCCESS; } @@ -8701,22 +9933,29 @@ static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle, /** * dp_enable_peer_based_pktlog() - Set Flag for peer based filtering * for pktlog - * @txrx_pdev_handle: cdp_pdev handle + * @soc: cdp_soc handle + * @pdev_id: id of dp pdev handle + * @mac_addr: Peer mac address * @enb_dsb: Enable or disable peer based filtering * * Return: QDF_STATUS */ static int -dp_enable_peer_based_pktlog( - struct cdp_pdev *txrx_pdev_handle, - char *mac_addr, uint8_t enb_dsb) +dp_enable_peer_based_pktlog(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t *mac_addr, uint8_t enb_dsb) { struct dp_peer *peer; - uint8_t local_id; - struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) { + dp_err("Invalid Pdev for pdev_id %d", pdev_id); + return QDF_STATUS_E_FAILURE; + } - peer = (struct dp_peer *)dp_find_peer_by_addr(txrx_pdev_handle, - mac_addr, &local_id); + peer = (struct dp_peer *)dp_find_peer_by_addr((struct cdp_pdev *)pdev, + mac_addr); if (!peer) { dp_err("Invalid Peer"); @@ -8729,139 +9968,79 @@ dp_enable_peer_based_pktlog( return QDF_STATUS_SUCCESS; } -#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG -#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS -/** - * dp_summarize_tag_stats - sums up the given protocol type's counters - * across all the rings and dumps the same - * @pdev_handle: cdp_pdev handle - * @protocol_type: protocol type for which stats should be displayed - * - * Return: none - */ -static uint64_t dp_summarize_tag_stats(struct cdp_pdev *pdev_handle, - uint16_t protocol_type) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - uint8_t ring_idx; - uint64_t total_tag_cnt = 0; - - for (ring_idx = 0; ring_idx < MAX_REO_DEST_RINGS; ring_idx++) { - total_tag_cnt += - pdev->reo_proto_tag_stats[ring_idx][protocol_type].tag_ctr; - } - total_tag_cnt += pdev->rx_err_proto_tag_stats[protocol_type].tag_ctr; - DP_PRINT_STATS("ProtoID: %d, Tag: %u Tagged MSDU cnt: %llu", - protocol_type, - pdev->rx_proto_tag_map[protocol_type].tag, - total_tag_cnt); - return total_tag_cnt; -} - +#ifndef WLAN_SUPPORT_RX_TAG_STATISTICS /** * dp_dump_pdev_rx_protocol_tag_stats - dump the number of packets tagged for * given protocol type (RX_PROTOCOL_TAG_ALL indicates for all protocol) - * @pdev_handle: cdp_pdev handle + * @soc: cdp_soc handle + * @pdev_id: id of cdp_pdev handle * @protocol_type: protocol type for which stats should be displayed * * Return: none */ -static void -dp_dump_pdev_rx_protocol_tag_stats(struct cdp_pdev *pdev_handle, +static inline void +dp_dump_pdev_rx_protocol_tag_stats(struct cdp_soc_t *soc, uint8_t pdev_id, uint16_t protocol_type) { - uint16_t proto_idx; - - if (protocol_type != RX_PROTOCOL_TAG_ALL && - protocol_type >= RX_PROTOCOL_TAG_MAX) { - DP_PRINT_STATS("Invalid protocol type : %u", protocol_type); - return; - } - - /* protocol_type in [0 ... RX_PROTOCOL_TAG_MAX] */ - if (protocol_type != RX_PROTOCOL_TAG_ALL) { - dp_summarize_tag_stats(pdev_handle, protocol_type); - return; - } - - /* protocol_type == RX_PROTOCOL_TAG_ALL */ - for (proto_idx = 0; proto_idx < RX_PROTOCOL_TAG_MAX; proto_idx++) - dp_summarize_tag_stats(pdev_handle, proto_idx); -} -#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ - -/** - * dp_reset_pdev_rx_protocol_tag_stats - resets the stats counters for - * given protocol type - * @pdev_handle: cdp_pdev handle - * @protocol_type: protocol type for which stats should be reset - * - * Return: none - */ -#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS -static void -dp_reset_pdev_rx_protocol_tag_stats(struct cdp_pdev *pdev_handle, - uint16_t protocol_type) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - uint8_t ring_idx; - - for (ring_idx = 0; ring_idx < MAX_REO_DEST_RINGS; ring_idx++) - pdev->reo_proto_tag_stats[ring_idx][protocol_type].tag_ctr = 0; - pdev->rx_err_proto_tag_stats[protocol_type].tag_ctr = 0; -} -#else -static void -dp_reset_pdev_rx_protocol_tag_stats(struct cdp_pdev *pdev_handle, - uint16_t protocol_type) -{ - /** Stub API */ } #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#ifndef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG /** * dp_update_pdev_rx_protocol_tag - Add/remove a protocol tag that should be * applied to the desired protocol type packets - * @txrx_pdev_handle: cdp_pdev handle + * @soc: soc handle + * @pdev_id: id of cdp_pdev handle * @enable_rx_protocol_tag - bitmask that indicates what protocol types * are enabled for tagging. zero indicates disable feature, non-zero indicates * enable feature * @protocol_type: new protocol type for which the tag is being added * @tag: user configured tag for the new protocol * - * Return: QDF_STATUS + * Return: Success */ -static QDF_STATUS -dp_update_pdev_rx_protocol_tag(struct cdp_pdev *pdev_handle, +static inline QDF_STATUS +dp_update_pdev_rx_protocol_tag(struct cdp_soc_t *soc, uint8_t pdev_id, uint32_t enable_rx_protocol_tag, uint16_t protocol_type, uint16_t tag) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - /* - * dynamically enable/disable tagging based on enable_rx_protocol_tag - * flag. - */ - if (enable_rx_protocol_tag) { - /* Tagging for one or more protocols has been set by user */ - pdev->is_rx_protocol_tagging_enabled = true; - } else { - /* - * No protocols being tagged, disable feature till next add - * operation - */ - pdev->is_rx_protocol_tagging_enabled = false; - } - - /** Reset stats counter across all rings for given protocol */ - dp_reset_pdev_rx_protocol_tag_stats(pdev_handle, protocol_type); - - pdev->rx_proto_tag_map[protocol_type].tag = tag; - return QDF_STATUS_SUCCESS; } #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#ifndef WLAN_SUPPORT_RX_FLOW_TAG +/** + * dp_set_rx_flow_tag - add/delete a flow + * @soc: soc handle + * @pdev_id: id of cdp_pdev handle + * @flow_info: flow tuple that is to be added to/deleted from flow search table + * + * Return: Success + */ +static inline QDF_STATUS +dp_set_rx_flow_tag(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info) +{ + return QDF_STATUS_SUCCESS; +} +/** + * dp_dump_rx_flow_tag_stats - dump the number of packets tagged for + * given flow 5-tuple + * @cdp_soc: soc handle + * @pdev_id: id of cdp_pdev handle + * @flow_info: flow 5-tuple for which stats should be displayed + * + * Return: Success + */ +static inline QDF_STATUS +dp_dump_rx_flow_tag_stats(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, + struct cdp_rx_flow_info *flow_info) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ + static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t *soc_hdl, uint32_t max_peers, uint32_t max_ast_index, @@ -8883,86 +10062,71 @@ static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t *soc_hdl, return QDF_STATUS_SUCCESS; } -/** - * dp_pdev_set_ctrl_pdev() - set ctrl pdev handle in dp pdev - * @dp_pdev: dp pdev handle - * @ctrl_pdev: UMAC ctrl pdev handle - * - * Return: void - */ -static void dp_pdev_set_ctrl_pdev(struct cdp_pdev *dp_pdev, - struct cdp_ctrl_objmgr_pdev *ctrl_pdev) -{ - struct dp_pdev *pdev = (struct dp_pdev *)dp_pdev; - - pdev->ctrl_pdev = ctrl_pdev; -} - -static void dp_set_rate_stats_cap(struct cdp_soc_t *soc_hdl, - uint8_t val) -{ - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - - soc->wlanstats_enabled = val; -} - static void dp_soc_set_rate_stats_ctx(struct cdp_soc_t *soc_handle, void *stats_ctx) { struct dp_soc *soc = (struct dp_soc *)soc_handle; - soc->rate_stats_ctx = stats_ctx; + soc->rate_stats_ctx = (struct cdp_soc_rate_stats_ctx *)stats_ctx; } #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE -static void dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *pdev_hdl) +static QDF_STATUS dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; - struct dp_soc *soc = (struct dp_soc *)pdev->soc; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_vdev *vdev = NULL; struct dp_peer *peer = NULL; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; qdf_spin_lock_bh(&soc->peer_ref_mutex); qdf_spin_lock_bh(&pdev->vdev_list_lock); TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { - if (peer) + if (peer && !peer->bss_peer) dp_wdi_event_handler( WDI_EVENT_FLUSH_RATE_STATS_REQ, - pdev->soc, peer->wlanstats_ctx, + soc, peer->wlanstats_ctx, peer->peer_ids[0], - WDI_NO_VAL, pdev->pdev_id); + WDI_NO_VAL, pdev_id); } } qdf_spin_unlock_bh(&pdev->vdev_list_lock); qdf_spin_unlock_bh(&soc->peer_ref_mutex); + + return QDF_STATUS_SUCCESS; } #else -static inline void +static inline QDF_STATUS dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *pdev_hdl) + uint8_t pdev_id) { + return QDF_STATUS_SUCCESS; } #endif #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE -static void dp_peer_flush_rate_stats(struct cdp_soc_t *soc, - struct cdp_pdev *pdev_handle, - void *buf) +static QDF_STATUS dp_peer_flush_rate_stats(struct cdp_soc_t *soc, + uint8_t pdev_id, + void *buf) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - dp_wdi_event_handler(WDI_EVENT_PEER_FLUSH_RATE_STATS, - pdev->soc, buf, HTT_INVALID_PEER, - WDI_NO_VAL, pdev->pdev_id); + (struct dp_soc *)soc, buf, HTT_INVALID_PEER, + WDI_NO_VAL, pdev_id); + return QDF_STATUS_SUCCESS; } #else -static inline void +static inline QDF_STATUS dp_peer_flush_rate_stats(struct cdp_soc_t *soc, - struct cdp_pdev *pdev_handle, + uint8_t pdev_id, void *buf) { + return QDF_STATUS_SUCCESS; } #endif @@ -8980,7 +10144,7 @@ static void *dp_soc_get_rate_stats_ctx(struct cdp_soc_t *soc_handle) * * Return: cfg value */ -static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) +static uint32_t dp_get_cfg(struct cdp_soc_t *soc, enum cdp_dp_cfg cfg) { struct dp_soc *dpsoc = (struct dp_soc *)soc; uint32_t value = 0; @@ -8989,9 +10153,19 @@ static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) case cfg_dp_enable_data_stall: value = dpsoc->wlan_cfg_ctx->enable_data_stall_detection; break; + case cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload: + value = dpsoc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload; + break; + case cfg_dp_enable_nan_ip_tcp_udp_checksum_offload: + value = dpsoc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload; + break; case cfg_dp_enable_ip_tcp_udp_checksum_offload: value = dpsoc->wlan_cfg_ctx->tcp_udp_checksumoffload; break; + case cfg_dp_disable_legacy_mode_csum_offload: + value = dpsoc->wlan_cfg_ctx-> + legacy_mode_checksumoffload_disable; + break; case cfg_dp_tso_enable: value = dpsoc->wlan_cfg_ctx->tso_enabled; break; @@ -9001,6 +10175,15 @@ static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) case cfg_dp_gro_enable: value = dpsoc->wlan_cfg_ctx->gro_enabled; break; + case cfg_dp_sg_enable: + value = dpsoc->wlan_cfg_ctx->sg_enabled; + break; + case cfg_dp_tc_based_dyn_gro_enable: + value = dpsoc->wlan_cfg_ctx->tc_based_dynamic_gro; + break; + case cfg_dp_tc_ingress_prio: + value = dpsoc->wlan_cfg_ctx->tc_ingress_prio; + break; case cfg_dp_tx_flow_start_queue_offset: value = dpsoc->wlan_cfg_ctx->tx_flow_start_queue_offset; break; @@ -9013,6 +10196,9 @@ static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) case cfg_dp_pktlog_buffer_size: value = dpsoc->wlan_cfg_ctx->pktlog_buffer_size; break; + case cfg_dp_wow_check_rx_pending: + value = dpsoc->wlan_cfg_ctx->wow_check_rx_pending_enable; + break; default: value = 0; } @@ -9020,10 +10206,11 @@ static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) return value; } -#ifdef CONFIG_WIN +#ifdef PEER_FLOW_CONTROL /** * dp_tx_flow_ctrl_configure_pdev() - Configure flow control params - * @pdev_hdl: datapath pdev handle + * @soc_handle: datapath soc handle + * @pdev_id: id of datapath pdev handle * @param: ol ath params * @value: value of the flag * @buff: Buffer to be passed @@ -9033,12 +10220,15 @@ static uint32_t dp_get_cfg(void *soc, enum cdp_dp_cfg cfg) * * Return: 0 for success. nonzero for failure. */ -static uint32_t dp_tx_flow_ctrl_configure_pdev(void *pdev_handle, +static uint32_t dp_tx_flow_ctrl_configure_pdev(struct cdp_soc_t *soc_handle, + uint8_t pdev_id, enum _ol_ath_param_t param, uint32_t value, void *buff) { - struct dp_soc *soc = NULL; - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_soc *soc = (struct dp_soc *)soc_handle; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); if (qdf_unlikely(!pdev)) return 1; @@ -9048,6 +10238,7 @@ static uint32_t dp_tx_flow_ctrl_configure_pdev(void *pdev_handle, return 1; switch (param) { +#ifdef QCA_ENH_V3_STATS_SUPPORT case OL_ATH_PARAM_VIDEO_DELAY_STATS_FC: if (value) pdev->delay_stats_flag = true; @@ -9060,6 +10251,7 @@ static uint32_t dp_tx_flow_ctrl_configure_pdev(void *pdev_handle, qdf_print("------ Delay Stats ------\n"); dp_pdev_print_delay_stats(pdev); break; +#endif case OL_ATH_PARAM_TOTAL_Q_SIZE: { uint32_t tx_min, tx_max; @@ -9094,17 +10286,18 @@ static uint32_t dp_tx_flow_ctrl_configure_pdev(void *pdev_handle, /** * dp_set_pdev_pcp_tid_map_wifi3(): update pcp tid map in pdev - * @vdev: DP_PDEV handle + * @psoc: dp soc handle + * @pdev_id: id of DP_PDEV handle * @pcp: pcp value * @tid: tid value passed by the user * * Return: QDF_STATUS_SUCCESS on success */ -static QDF_STATUS dp_set_pdev_pcp_tid_map_wifi3(struct cdp_pdev *pdev_handle, +static QDF_STATUS dp_set_pdev_pcp_tid_map_wifi3(ol_txrx_soc_handle psoc, + uint8_t pdev_id, uint8_t pcp, uint8_t tid) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = (struct dp_soc *)psoc; soc->pcp_tid_map[pcp] = tid; @@ -9112,73 +10305,27 @@ static QDF_STATUS dp_set_pdev_pcp_tid_map_wifi3(struct cdp_pdev *pdev_handle, return QDF_STATUS_SUCCESS; } -/** - * dp_set_pdev_tidmap_prty_wifi3(): update tidmap priority in pdev - * @vdev: DP_PDEV handle - * @prio: tidmap priority value passed by the user - * - * Return: QDF_STATUS_SUCCESS on success - */ -static QDF_STATUS dp_set_pdev_tidmap_prty_wifi3(struct cdp_pdev *pdev_handle, - uint8_t prio) -{ - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct dp_soc *soc = pdev->soc; - - soc->tidmap_prty = prio; - - hal_tx_set_tidmap_prty(soc->hal_soc, prio); - return QDF_STATUS_SUCCESS; -} - /** * dp_set_vdev_pcp_tid_map_wifi3(): update pcp tid map in vdev - * @vdev: DP_VDEV handle + * @soc: DP soc handle + * @vdev_id: id of DP_VDEV handle * @pcp: pcp value * @tid: tid value passed by the user * * Return: QDF_STATUS_SUCCESS on success */ -static QDF_STATUS dp_set_vdev_pcp_tid_map_wifi3(struct cdp_vdev *vdev_handle, +static QDF_STATUS dp_set_vdev_pcp_tid_map_wifi3(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t pcp, uint8_t tid) { - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - - vdev->pcp_tid_map[pcp] = tid; - - return QDF_STATUS_SUCCESS; -} - -/** - * dp_set_vdev_tidmap_tbl_id_wifi3(): update tidmapi tbl id in vdev - * @vdev: DP_VDEV handle - * @mapid: map_id value passed by the user - * - * Return: QDF_STATUS_SUCCESS on success - */ -static QDF_STATUS dp_set_vdev_tidmap_tbl_id_wifi3(struct cdp_vdev *vdev_handle, - uint8_t mapid) -{ - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; - - vdev->tidmap_tbl_id = mapid; - - return QDF_STATUS_SUCCESS; -} + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); -/** - * dp_set_vdev_tidmap_prty_wifi3(): update tidmap priority in vdev - * @vdev: DP_VDEV handle - * @prio: tidmap priority value passed by the user - * - * Return: QDF_STATUS_SUCCESS on success - */ -static QDF_STATUS dp_set_vdev_tidmap_prty_wifi3(struct cdp_vdev *vdev_handle, - uint8_t prio) -{ - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + if (!vdev) + return QDF_STATUS_E_FAILURE; - vdev->tidmap_prty = prio; + vdev->pcp_tid_map[pcp] = tid; return QDF_STATUS_SUCCESS; } @@ -9208,14 +10355,12 @@ static struct cdp_cmn_ops dp_ops_cmn = { dp_peer_ast_entry_del_by_pdev, .txrx_peer_delete = dp_peer_delete_wifi3, .txrx_vdev_register = dp_vdev_register_wifi3, - .txrx_vdev_flush_peers = dp_vdev_flush_peers, .txrx_soc_detach = dp_soc_detach_wifi3, .txrx_soc_deinit = dp_soc_deinit_wifi3, .txrx_soc_init = dp_soc_init_wifi3, .txrx_tso_soc_attach = dp_tso_soc_attach, .txrx_tso_soc_detach = dp_tso_soc_detach, .txrx_get_vdev_mac_addr = dp_get_vdev_mac_addr_wifi3, - .txrx_get_vdev_from_vdev_id = dp_get_vdev_from_vdev_id_wifi3, .txrx_get_mon_vdev_from_pdev = dp_get_mon_vdev_from_pdev_wifi3, .txrx_get_ctrl_pdev_from_vdev = dp_get_ctrl_pdev_from_vdev_wifi3, .txrx_ath_getstats = dp_get_device_stats, @@ -9224,26 +10369,15 @@ static struct cdp_cmn_ops dp_ops_cmn = { .addba_resp_tx_completion = dp_addba_resp_tx_completion_wifi3, .delba_process = dp_delba_process_wifi3, .set_addba_response = dp_set_addba_response, - .get_peer_mac_addr_frm_id = dp_get_peer_mac_addr_frm_id, .flush_cache_rx_queue = NULL, /* TODO: get API's for dscp-tid need to be added*/ .set_vdev_dscp_tid_map = dp_set_vdev_dscp_tid_map_wifi3, .set_pdev_dscp_tid_map = dp_set_pdev_dscp_tid_map_wifi3, - .hmmc_tid_override_en = dp_hmmc_tid_override_en_wifi3, - .set_hmmc_tid_val = dp_set_hmmc_tid_val_wifi3, .txrx_get_total_per = dp_get_total_per, .txrx_stats_request = dp_txrx_stats_request, .txrx_set_monitor_mode = dp_vdev_set_monitor_mode, - .txrx_get_pdev_id_frm_pdev = dp_get_pdev_id_frm_pdev, - .txrx_get_vow_config_frm_pdev = dp_get_delay_stats_flag, - .txrx_pdev_set_chan_noise_floor = dp_pdev_set_chan_noise_floor, - .txrx_set_nac = dp_set_nac, - .txrx_get_tx_pending = dp_get_tx_pending, - .txrx_set_pdev_tx_capture = dp_config_debug_sniffer, .txrx_get_peer_mac_from_peer_id = dp_get_peer_mac_from_peer_id, .display_stats = dp_txrx_dump_stats, - .txrx_soc_set_nss_cfg = dp_soc_set_nss_cfg_wifi3, - .txrx_soc_get_nss_cfg = dp_soc_get_nss_cfg_wifi3, .txrx_intr_attach = dp_soc_interrupt_attach_wrapper, .txrx_intr_detach = dp_soc_interrupt_detach, .set_pn_check = dp_set_pn_check_wifi3, @@ -9253,9 +10387,13 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_data_tx_cb_set = dp_txrx_data_tx_cb_set, .get_dp_txrx_handle = dp_pdev_get_dp_txrx_handle, .set_dp_txrx_handle = dp_pdev_set_dp_txrx_handle, + .get_vdev_dp_ext_txrx_handle = dp_vdev_get_dp_ext_handle, + .set_vdev_dp_ext_txrx_handle = dp_vdev_set_dp_ext_handle, .get_soc_dp_txrx_handle = dp_soc_get_dp_txrx_handle, .set_soc_dp_txrx_handle = dp_soc_set_dp_txrx_handle, .map_pdev_to_lmac = dp_soc_map_pdev_to_lmac, + .handle_mode_change = dp_soc_handle_pdev_mode_change, + .set_pdev_status_down = dp_soc_set_pdev_status_down, .txrx_set_ba_aging_timeout = dp_set_ba_aging_timeout, .txrx_get_ba_aging_timeout = dp_get_ba_aging_timeout, .tx_send = dp_tx_send, @@ -9263,7 +10401,6 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_peer_reset_ast_table = dp_wds_reset_ast_table_wifi3, .txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3, .txrx_peer_map_attach = dp_peer_map_attach_wifi3, - .txrx_pdev_set_ctrl_pdev = dp_pdev_set_ctrl_pdev, .txrx_get_os_rx_handles_from_vdev = dp_get_os_rx_handles_from_vdev_wifi3, .delba_tx_completion = dp_delba_tx_completion_wifi3, @@ -9275,37 +10412,48 @@ static struct cdp_cmn_ops dp_ops_cmn = { .txrx_flush_rate_stats_request = dp_flush_rate_stats_req, .set_pdev_pcp_tid_map = dp_set_pdev_pcp_tid_map_wifi3, - .set_pdev_tidmap_prty = dp_set_pdev_tidmap_prty_wifi3, .set_vdev_pcp_tid_map = dp_set_vdev_pcp_tid_map_wifi3, - .set_vdev_tidmap_prty = dp_set_vdev_tidmap_prty_wifi3, - .set_vdev_tidmap_tbl_id = dp_set_vdev_tidmap_tbl_id_wifi3, .txrx_cp_peer_del_response = dp_cp_peer_del_resp_handler, +#ifdef QCA_MULTIPASS_SUPPORT + .set_vlan_groupkey = dp_set_vlan_groupkey, +#endif + .get_peer_mac_list = dp_get_peer_mac_list, + .tx_send_exc = dp_tx_send_exception, }; static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_peer_authorize = dp_peer_authorize, - .txrx_set_vdev_rx_decap_type = dp_set_vdev_rx_decap_type, - .txrx_set_tx_encap_type = dp_set_vdev_tx_encap_type, -#ifdef MESH_MODE_SUPPORT - .txrx_set_mesh_mode = dp_peer_set_mesh_mode, - .txrx_set_mesh_rx_filter = dp_peer_set_mesh_rx_filter, +#ifdef VDEV_PEER_PROTOCOL_COUNT + .txrx_enable_peer_protocol_count = dp_enable_vdev_peer_protocol_count, + .txrx_set_peer_protocol_drop_mask = + dp_enable_vdev_peer_protocol_drop_mask, + .txrx_is_peer_protocol_count_enabled = + dp_is_vdev_peer_protocol_count_enabled, + .txrx_get_peer_protocol_drop_mask = dp_get_vdev_peer_protocol_drop_mask, #endif .txrx_set_vdev_param = dp_set_vdev_param, - .txrx_peer_set_nawds = dp_peer_set_nawds, + .txrx_set_psoc_param = dp_set_psoc_param, + .txrx_get_psoc_param = dp_get_psoc_param, .txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest, .txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest, - .txrx_set_filter_neighbour_peers = dp_set_filter_neighbour_peers, +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) .txrx_update_filter_neighbour_peers = dp_update_filter_neighbour_peers, +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ .txrx_get_sec_type = dp_get_sec_type, - /* TODO: Add other functions */ .txrx_wdi_event_sub = dp_wdi_event_sub, .txrx_wdi_event_unsub = dp_wdi_event_unsub, #ifdef WDI_EVENT_ENABLE .txrx_get_pldev = dp_get_pldev, #endif .txrx_set_pdev_param = dp_set_pdev_param, + .txrx_get_pdev_param = dp_get_pdev_param, + .txrx_set_peer_param = dp_set_peer_param, + .txrx_get_peer_param = dp_get_peer_param, +#ifdef VDEV_PEER_PROTOCOL_COUNT + .txrx_peer_protocol_cnt = dp_peer_stats_update_protocol_cnt, +#endif #ifdef ATH_SUPPORT_NAC_RSSI .txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi, .txrx_vdev_get_neighbour_rssi = dp_vdev_get_neighbour_rssi, @@ -9321,6 +10469,17 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { dp_dump_pdev_rx_protocol_tag_stats, #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#ifdef WLAN_SUPPORT_RX_FLOW_TAG + .txrx_set_rx_flow_tag = dp_set_rx_flow_tag, + .txrx_dump_rx_flow_tag_stats = dp_dump_rx_flow_tag_stats, +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ +#ifdef QCA_MULTIPASS_SUPPORT + .txrx_peer_set_vlan_id = dp_peer_set_vlan_id, +#endif /*QCA_MULTIPASS_SUPPORT*/ +#if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) + .txrx_update_peer_pkt_capture_params = + dp_peer_update_pkt_capture_params, +#endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */ }; static struct cdp_me_ops dp_ops_me = { @@ -9332,31 +10491,27 @@ static struct cdp_me_ops dp_ops_me = { }; static struct cdp_mon_ops dp_ops_mon = { - .txrx_monitor_set_filter_ucast_data = NULL, - .txrx_monitor_set_filter_mcast_data = NULL, - .txrx_monitor_set_filter_non_data = NULL, - .txrx_monitor_get_filter_ucast_data = dp_vdev_get_filter_ucast_data, - .txrx_monitor_get_filter_mcast_data = dp_vdev_get_filter_mcast_data, - .txrx_monitor_get_filter_non_data = dp_vdev_get_filter_non_data, .txrx_reset_monitor_mode = dp_reset_monitor_mode, /* Added support for HK advance filter */ .txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter, - .txrx_monitor_record_channel = dp_pdev_set_monitor_channel, + .txrx_deliver_tx_mgmt = dp_deliver_tx_mgmt, }; static struct cdp_host_stats_ops dp_ops_host_stats = { .txrx_per_peer_stats = dp_get_host_peer_stats, .get_fw_peer_stats = dp_get_fw_peer_stats, .get_htt_stats = dp_get_htt_stats, +#ifdef FEATURE_PERPKT_INFO .txrx_enable_enhanced_stats = dp_enable_enhanced_stats, .txrx_disable_enhanced_stats = dp_disable_enhanced_stats, +#endif /* FEATURE_PERPKT_INFO */ .txrx_stats_publish = dp_txrx_stats_publish, .txrx_get_vdev_stats = dp_txrx_get_vdev_stats, .txrx_get_peer_stats = dp_txrx_get_peer_stats, + .txrx_get_peer_stats_param = dp_txrx_get_peer_stats_param, .txrx_reset_peer_stats = dp_txrx_reset_peer_stats, .txrx_get_pdev_stats = dp_txrx_get_pdev_stats, .txrx_get_ratekbps = dp_txrx_get_ratekbps, - .configure_rate_stats = dp_set_rate_stats_cap, .txrx_update_vdev_stats = dp_txrx_update_vdev_host_stats, /* TODO */ }; @@ -9365,39 +10520,24 @@ static struct cdp_raw_ops dp_ops_raw = { /* TODO */ }; -#ifdef CONFIG_WIN +#ifdef PEER_FLOW_CONTROL static struct cdp_pflow_ops dp_ops_pflow = { dp_tx_flow_ctrl_configure_pdev, }; #endif /* CONFIG_WIN */ -#ifdef FEATURE_RUNTIME_PM -/** - * dp_runtime_suspend() - ensure DP is ready to runtime suspend - * @opaque_pdev: DP pdev context - * - * DP is ready to runtime suspend if there are no pending TX packets. - * - * Return: QDF_STATUS - */ -static QDF_STATUS dp_runtime_suspend(struct cdp_pdev *opaque_pdev) -{ - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; - - /* Abort if there are any pending TX packets */ - if (dp_get_tx_pending(opaque_pdev) > 0) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - FL("Abort suspend due to pending TX packets")); - return QDF_STATUS_E_AGAIN; - } - - if (soc->intr_mode == DP_INTR_POLL) - qdf_timer_stop(&soc->int_timer); - - return QDF_STATUS_SUCCESS; -} +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +static struct cdp_cfr_ops dp_ops_cfr = { + .txrx_cfr_filter = dp_cfr_filter, + .txrx_get_cfr_rcc = dp_get_cfr_rcc, + .txrx_set_cfr_rcc = dp_set_cfr_rcc, + .txrx_get_cfr_dbg_stats = dp_get_cfr_dbg_stats, + .txrx_clear_cfr_dbg_stats = dp_clear_cfr_dbg_stats, + .txrx_enable_mon_reap_timer = dp_enable_mon_reap_timer, +}; +#endif +#ifdef FEATURE_RUNTIME_PM /** * dp_flush_ring_hptp() - Update ring shadow * register HP/TP address when runtime @@ -9407,10 +10547,8 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_pdev *opaque_pdev) * Return: None */ static -void dp_flush_ring_hptp(struct dp_soc *soc, void *hal_ring) +void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { - struct hal_srng *hal_srng = (struct hal_srng *)hal_ring; - if (hal_srng && hal_srng_get_clear_event(hal_srng, HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ @@ -9419,26 +10557,91 @@ void dp_flush_ring_hptp(struct dp_soc *soc, void *hal_ring) hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); + dp_debug("flushed"); + } +} + +/** + * dp_runtime_suspend() - ensure DP is ready to runtime suspend + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * + * DP is ready to runtime suspend if there are no pending TX packets. + * + * Return: QDF_STATUS + */ +static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev; + uint8_t i; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* Abort if there are any pending TX packets */ + if (dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)) > 0) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + FL("Abort suspend due to pending TX packets")); + + /* perform a force flush if tx is pending */ + for (i = 0; i < soc->num_tcl_data_rings; i++) { +#ifdef IPA_OFFLOAD + if (i == IPA_TCL_DATA_RING_IDX) + continue; +#endif + hal_srng_set_event(soc->tcl_data_ring[i].hal_srng, + HAL_SRNG_FLUSH_EVENT); + dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); + } + + return QDF_STATUS_E_AGAIN; + } + + if (dp_runtime_get_refcount(soc)) { + dp_info("refcount: %d", dp_runtime_get_refcount(soc)); + + return QDF_STATUS_E_AGAIN; } + + if (soc->intr_mode == DP_INTR_POLL) + qdf_timer_stop(&soc->int_timer); + + return QDF_STATUS_SUCCESS; } +#define DP_FLUSH_WAIT_CNT 10 +#define DP_RUNTIME_SUSPEND_WAIT_MS 10 /** * dp_runtime_resume() - ensure DP is ready to runtime resume - * @opaque_pdev: DP pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * Resume DP for runtime PM. * * Return: QDF_STATUS */ -static QDF_STATUS dp_runtime_resume(struct cdp_pdev *opaque_pdev) +static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; - int i; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + int i, suspend_wait = 0; if (soc->intr_mode == DP_INTR_POLL) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); + /* + * Wait until dp runtime refcount becomes zero or time out, then flush + * pending tx for runtime suspend. + */ + while (dp_runtime_get_refcount(soc) && + suspend_wait < DP_FLUSH_WAIT_CNT) { + qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS); + suspend_wait++; + } + for (i = 0; i < MAX_TCL_DATA_RINGS; i++) { dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); } @@ -9451,20 +10654,20 @@ static QDF_STATUS dp_runtime_resume(struct cdp_pdev *opaque_pdev) /** * dp_tx_get_success_ack_stats() - get tx success completion count - * @opaque_pdev: dp pdev context + * @soc_hdl: Datapath soc handle * @vdevid: vdev identifier * * Return: tx success ack count */ -static uint32_t dp_tx_get_success_ack_stats(struct cdp_pdev *pdev, +static uint32_t dp_tx_get_success_ack_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct dp_vdev *vdev = - (struct dp_vdev *)dp_get_vdev_from_vdev_id_wifi3(pdev, - vdev_id); - struct dp_soc *soc = ((struct dp_pdev *)pdev)->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct cdp_vdev_stats *vdev_stats = NULL; uint32_t tx_success; + struct dp_vdev *vdev = + (struct dp_vdev *)dp_get_vdev_from_soc_vdev_id_wifi3(soc, + vdev_id); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -9492,49 +10695,59 @@ static uint32_t dp_tx_get_success_ack_stats(struct cdp_pdev *pdev, #ifdef WLAN_SUPPORT_DATA_STALL /** * dp_register_data_stall_detect_cb() - register data stall callback - * @opaque_pdev: DP pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @data_stall_detect_callback: data stall callback function * * Return: QDF_STATUS Enumeration */ -static QDF_STATUS dp_register_data_stall_detect_cb( - struct cdp_pdev *opaque_pdev, - data_stall_detect_cb data_stall_detect_callback) +static +QDF_STATUS dp_register_data_stall_detect_cb( + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + data_stall_detect_cb data_stall_detect_callback) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev; + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { dp_err("pdev NULL!"); return QDF_STATUS_E_INVAL; } + pdev->data_stall_detect_callback = data_stall_detect_callback; return QDF_STATUS_SUCCESS; } /** * dp_deregister_data_stall_detect_cb() - de-register data stall callback - * @opaque_pdev: DP pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @data_stall_detect_callback: data stall callback function * * Return: QDF_STATUS Enumeration */ -static QDF_STATUS dp_deregister_data_stall_detect_cb( - struct cdp_pdev *opaque_pdev, - data_stall_detect_cb data_stall_detect_callback) +static +QDF_STATUS dp_deregister_data_stall_detect_cb( + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + data_stall_detect_cb data_stall_detect_callback) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev; + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { dp_err("pdev NULL!"); return QDF_STATUS_E_INVAL; } + pdev->data_stall_detect_callback = NULL; return QDF_STATUS_SUCCESS; } /** * dp_txrx_post_data_stall_event() - post data stall event - * @opaque_pdev: DP pdev context + * @soc_hdl: Datapath soc handle * @indicator: Module triggering data stall * @data_stall_type: data stall event type * @pdev_id: pdev id @@ -9543,17 +10756,18 @@ static QDF_STATUS dp_deregister_data_stall_detect_cb( * * Return: None */ -static void dp_txrx_post_data_stall_event( - struct cdp_pdev *opaque_pdev, - enum data_stall_log_event_indicator indicator, - enum data_stall_log_event_type data_stall_type, - uint32_t pdev_id, uint32_t vdev_id_bitmap, - enum data_stall_log_recovery_type recovery_type) +static void +dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl, + enum data_stall_log_event_indicator indicator, + enum data_stall_log_event_type data_stall_type, + uint32_t pdev_id, uint32_t vdev_id_bitmap, + enum data_stall_log_recovery_type recovery_type) { + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct data_stall_event_info data_stall_info; struct dp_pdev *pdev; - pdev = (struct dp_pdev *)opaque_pdev; + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { dp_err("pdev NULL!"); return; @@ -9577,6 +10791,7 @@ static void dp_txrx_post_data_stall_event( } #endif /* WLAN_SUPPORT_DATA_STALL */ +#ifdef DP_PEER_EXTENDED_API /** * dp_peer_get_ref_find_by_addr - get peer with addr by ref count inc * @dev: physical device instance @@ -9587,7 +10802,6 @@ static void dp_txrx_post_data_stall_event( */ static void * dp_peer_get_ref_find_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr, - uint8_t *local_id, enum peer_debug_id_type debug_id) { struct dp_pdev *pdev = (struct dp_pdev *)dev; @@ -9604,35 +10818,36 @@ dp_peer_get_ref_find_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr, return NULL; } - *local_id = peer->local_id; - dp_info_rl("peer %pK mac: %pM", peer, peer->mac_addr.raw); + dp_info_rl("peer %pK mac: "QDF_MAC_ADDR_FMT, peer, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); return peer; } +#endif /* DP_PEER_EXTENDED_API */ #ifdef WLAN_FEATURE_STATS_EXT /* rx hw stats event wait timeout in ms */ #define DP_REO_STATUS_STATS_TIMEOUT 1500 /** * dp_txrx_ext_stats_request - request dp txrx extended stats request - * @ppdev: pdev handle + * @soc_hdl: soc handle + * @pdev_id: pdev id * @req: stats request * * Return: QDF_STATUS */ static QDF_STATUS -dp_txrx_ext_stats_request(struct cdp_pdev *ppdev, +dp_txrx_ext_stats_request(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct cdp_txrx_ext_stats *req) { - struct dp_pdev *pdev = (struct dp_pdev *)ppdev; - struct dp_soc *soc = NULL; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { dp_err("pdev is null"); return QDF_STATUS_E_INVAL; } - soc = pdev->soc; dp_aggregate_pdev_stats(pdev); req->tx_msdu_enqueue = pdev->stats.tx_i.processed.num; @@ -9640,8 +10855,8 @@ dp_txrx_ext_stats_request(struct cdp_pdev *ppdev, req->rx_mpdu_received = soc->ext_stats.rx_mpdu_received; req->rx_mpdu_delivered = soc->ext_stats.rx_mpdu_received; req->rx_mpdu_missed = soc->ext_stats.rx_mpdu_missed; - req->rx_mpdu_error = soc->stats.rx.err_ring_pkts - - soc->stats.rx.rx_frags; + /* only count error source from RXDMA */ + req->rx_mpdu_error = pdev->stats.err.rxdma_error; return QDF_STATUS_SUCCESS; } @@ -9684,7 +10899,7 @@ static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt, soc->ext_stats.rx_mpdu_received += queue_status->mpdu_frms_cnt; soc->ext_stats.rx_mpdu_missed += - queue_status->late_recv_mpdu_cnt; + queue_status->hole_cnt; } qdf_spin_unlock_bh(&soc->rx_hw_stats_lock); } @@ -9692,7 +10907,7 @@ static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt, /** * dp_request_rx_hw_stats - request rx hardware stats * @soc_hdl: soc handle - * @pvdev: vdev handle + * @vdev_id: vdev id * * Return: None */ @@ -9700,13 +10915,13 @@ static QDF_STATUS dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { struct dp_soc *soc = (struct dp_soc *)soc_hdl; - struct dp_vdev *vdev = - dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); struct dp_peer *peer; - uint8_t local_id = 0; QDF_STATUS status; struct dp_req_rx_hw_stats_t *rx_hw_stats; int rx_stats_sent_cnt = 0; + uint32_t last_rx_mpdu_received; + uint32_t last_rx_mpdu_missed; if (!vdev) { dp_err("vdev is null for vdev_id: %u", vdev_id); @@ -9714,9 +10929,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) } peer = dp_peer_get_ref_find_by_addr((struct cdp_pdev *)vdev->pdev, - vdev->vap_bss_peer_mac_addr, - &local_id, - 0); + vdev->vap_bss_peer_mac_addr, 0); if (!peer) { dp_err("Peer is NULL"); @@ -9733,6 +10946,12 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) qdf_event_reset(&soc->rx_hw_stats_event); qdf_spin_lock_bh(&soc->rx_hw_stats_lock); + /* save the last soc cumulative stats and reset it to 0 */ + last_rx_mpdu_received = soc->ext_stats.rx_mpdu_received; + last_rx_mpdu_missed = soc->ext_stats.rx_mpdu_missed; + soc->ext_stats.rx_mpdu_received = 0; + soc->ext_stats.rx_mpdu_missed = 0; + rx_stats_sent_cnt = dp_peer_rxtid_stats(peer, dp_rx_hw_stats_cb, rx_hw_stats); if (!rx_stats_sent_cnt) { @@ -9756,6 +10975,12 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) dp_info("rx hw stats event timeout"); if (soc->is_last_stats_ctx_init) rx_hw_stats->is_query_timeout = true; + /** + * If query timeout happened, use the last saved stats + * for this time query. + */ + soc->ext_stats.rx_mpdu_received = last_rx_mpdu_received; + soc->ext_stats.rx_mpdu_missed = last_rx_mpdu_missed; } qdf_spin_unlock_bh(&soc->rx_hw_stats_lock); dp_peer_unref_delete(peer); @@ -9764,7 +10989,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) } #endif /* WLAN_FEATURE_STATS_EXT */ -#ifndef CONFIG_WIN +#ifdef DP_PEER_EXTENDED_API static struct cdp_misc_ops dp_ops_misc = { #ifdef FEATURE_WLAN_TDLS .tx_non_std = dp_tx_non_std, @@ -9789,7 +11014,9 @@ static struct cdp_misc_ops dp_ops_misc = { .request_rx_hw_stats = dp_request_rx_hw_stats, #endif /* WLAN_FEATURE_STATS_EXT */ }; +#endif +#ifdef DP_FLOW_CTL static struct cdp_flowctl_ops dp_ops_flowctl = { /* WIFI 3.0 DP implement as required. */ #ifdef QCA_LL_TX_FLOW_CONTROL_V2 @@ -9804,6 +11031,7 @@ static struct cdp_flowctl_ops dp_ops_flowctl = { static struct cdp_lflowctl_ops dp_ops_l_flowctl = { /* WIFI 3.0 DP NOT IMPLEMENTED YET */ }; +#endif #ifdef IPA_OFFLOAD static struct cdp_ipa_ops dp_ops_ipa = { @@ -9826,15 +11054,21 @@ static struct cdp_ipa_ops dp_ops_ipa = { }; #endif -static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) +#ifdef DP_POWER_SAVE +static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); int timeout = SUSPEND_DRAIN_WAIT; int drain_wait_delay = 50; /* 50 ms */ + if (qdf_unlikely(!pdev)) { + dp_err("pdev is NULL"); + return QDF_STATUS_E_INVAL; + } + /* Abort if there are any pending TX packets */ - while (dp_get_tx_pending(opaque_pdev) > 0) { + while (dp_get_tx_pending((struct cdp_pdev *)pdev) > 0) { qdf_sleep(drain_wait_delay); if (timeout <= 0) { dp_err("TX frames are pending, abort suspend"); @@ -9847,7 +11081,8 @@ static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) qdf_timer_stop(&soc->int_timer); /* Stop monitor reap timer and reap any pending frames in ring */ - if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED && + if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) || + dp_is_enable_reap_timer_non_pkt(pdev)) && soc->reap_timer_init) { qdf_timer_sync_cancel(&soc->mon_reap_timer); dp_service_mon_rings(soc, DP_MON_REAP_BUDGET); @@ -9856,16 +11091,22 @@ static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) return QDF_STATUS_SUCCESS; } -static QDF_STATUS dp_bus_resume(struct cdp_pdev *opaque_pdev) +static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (qdf_unlikely(!pdev)) { + dp_err("pdev is NULL"); + return QDF_STATUS_E_INVAL; + } if (soc->intr_mode == DP_INTR_POLL) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); /* Start monitor reap timer */ - if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED && + if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) || + dp_is_enable_reap_timer_non_pkt(pdev)) && soc->reap_timer_init) qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS); @@ -9876,22 +11117,27 @@ static QDF_STATUS dp_bus_resume(struct cdp_pdev *opaque_pdev) /** * dp_process_wow_ack_rsp() - process wow ack response * @soc_hdl: datapath soc handle - * @opaque_pdev: data path pdev handle + * @pdev_id: data path pdev handle id * * Return: none */ -static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *opaque_pdev) +static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (qdf_unlikely(!pdev)) { + dp_err("pdev is NULL"); + return; + } /* * As part of wow enable FW disables the mon status ring and in wow ack * response from FW reap mon status ring to make sure no packets pending * in the ring. */ - if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED && + if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) || + dp_is_enable_reap_timer_non_pkt(pdev)) && soc->reap_timer_init) { dp_service_mon_rings(soc, DP_MON_REAP_BUDGET); } @@ -9905,10 +11151,10 @@ static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, * Return: none */ static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl, - struct cdp_pdev *opaque_pdev) + uint8_t pdev_id) { - struct dp_soc *soc = (struct dp_soc *)soc_hdl; - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (qdf_unlikely(!pdev)) { dp_err("pdev is NULL"); @@ -9916,7 +11162,8 @@ static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl, } /* Stop monitor reap timer and reap any pending frames in ring */ - if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED && + if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) || + dp_is_enable_reap_timer_non_pkt(pdev)) && soc->reap_timer_init) { qdf_timer_sync_cancel(&soc->mon_reap_timer); dp_service_mon_rings(soc, DP_MON_REAP_BUDGET); @@ -9929,52 +11176,39 @@ static struct cdp_bus_ops dp_ops_bus = { .process_wow_ack_rsp = dp_process_wow_ack_rsp, .process_target_suspend_req = dp_process_target_suspend_req }; +#endif -static struct cdp_ocb_ops dp_ops_ocb = { - /* WIFI 3.0 DP NOT IMPLEMENTED YET */ -}; - - +#ifdef DP_FLOW_CTL static struct cdp_throttle_ops dp_ops_throttle = { /* WIFI 3.0 DP NOT IMPLEMENTED YET */ }; -static struct cdp_mob_stats_ops dp_ops_mob_stats = { +static struct cdp_cfg_ops dp_ops_cfg = { /* WIFI 3.0 DP NOT IMPLEMENTED YET */ }; +#endif -static struct cdp_cfg_ops dp_ops_cfg = { +#ifdef DP_PEER_EXTENDED_API +static struct cdp_ocb_ops dp_ops_ocb = { /* WIFI 3.0 DP NOT IMPLEMENTED YET */ }; -/* - * dp_peer_release_ref - release peer ref count - * @peer: peer handle - * @debug_id: to track enum peer access - * - * Return: None - */ -static inline -void dp_peer_release_ref(void *peer, enum peer_debug_id_type debug_id) -{ - dp_peer_unref_delete(peer); -} +static struct cdp_mob_stats_ops dp_ops_mob_stats = { + .clear_stats = dp_txrx_clear_dump_stats, +}; static struct cdp_peer_ops dp_ops_peer = { .register_peer = dp_register_peer, .clear_peer = dp_clear_peer, - .find_peer_by_addr = dp_find_peer_by_addr, - .find_peer_by_addr_and_vdev = dp_find_peer_by_addr_and_vdev, - .peer_get_ref_by_addr = dp_peer_get_ref_find_by_addr, - .peer_release_ref = dp_peer_release_ref, - .local_peer_id = dp_local_peer_id, - .peer_find_by_local_id = dp_peer_find_by_local_id, + .find_peer_exist = dp_find_peer_exist, + .find_peer_exist_on_vdev = dp_find_peer_exist_on_vdev, + .find_peer_exist_on_other_vdev = dp_find_peer_exist_on_other_vdev, .peer_state_update = dp_peer_state_update, .get_vdevid = dp_get_vdevid, - .get_vdev_by_sta_id = dp_get_vdev_by_sta_id, + .get_vdev_by_peer_addr = dp_get_vdev_by_peer_addr, .peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr, - .get_vdev_for_peer = dp_get_vdev_for_peer, .get_peer_state = dp_get_peer_state, + .peer_flush_frags = dp_peer_flush_frags, }; #endif @@ -9986,22 +11220,29 @@ static struct cdp_ops dp_txrx_ops = { .host_stats_ops = &dp_ops_host_stats, .wds_ops = &dp_ops_wds, .raw_ops = &dp_ops_raw, -#ifdef CONFIG_WIN +#ifdef PEER_FLOW_CONTROL .pflow_ops = &dp_ops_pflow, -#endif /* CONFIG_WIN */ -#ifndef CONFIG_WIN +#endif /* PEER_FLOW_CONTROL */ +#ifdef DP_PEER_EXTENDED_API .misc_ops = &dp_ops_misc, + .ocb_ops = &dp_ops_ocb, + .peer_ops = &dp_ops_peer, + .mob_stats_ops = &dp_ops_mob_stats, +#endif +#ifdef DP_FLOW_CTL .cfg_ops = &dp_ops_cfg, .flowctl_ops = &dp_ops_flowctl, .l_flowctl_ops = &dp_ops_l_flowctl, + .throttle_ops = &dp_ops_throttle, +#endif #ifdef IPA_OFFLOAD .ipa_ops = &dp_ops_ipa, #endif +#ifdef DP_POWER_SAVE .bus_ops = &dp_ops_bus, - .ocb_ops = &dp_ops_ocb, - .peer_ops = &dp_ops_peer, - .throttle_ops = &dp_ops_throttle, - .mob_stats_ops = &dp_ops_mob_stats, +#endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) + .cfr_ops = &dp_ops_cfr, #endif }; @@ -10034,9 +11275,11 @@ void dp_soc_set_txrx_ring_map(struct dp_soc *soc) * * Return: DP SOC handle on success, NULL on failure */ -void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, - HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, - struct ol_if_ops *ol_ops, uint16_t device_id) +struct cdp_soc_t * +dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, + HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, + struct ol_if_ops *ol_ops, uint16_t device_id) { struct dp_soc *dp_soc = NULL; @@ -10048,7 +11291,7 @@ void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, if (!dp_soc_init(dp_soc, htc_handle, hif_handle)) return NULL; - return (void *)dp_soc; + return dp_soc_to_cdp_soc_t(dp_soc); } #else @@ -10063,15 +11306,17 @@ void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, * * Return: DP SOC handle on success, NULL on failure */ -void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, - HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, - struct ol_if_ops *ol_ops, uint16_t device_id) +struct cdp_soc_t * +dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, + HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, + struct ol_if_ops *ol_ops, uint16_t device_id) { struct dp_soc *dp_soc = NULL; dp_soc = dp_soc_attach(ctrl_psoc, htc_handle, qdf_osdev, ol_ops, device_id); - return (void *)dp_soc; + return dp_soc_to_cdp_soc_t(dp_soc); } #endif @@ -10087,12 +11332,13 @@ void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, * Return: DP SOC handle on success, NULL on failure */ static struct dp_soc * -dp_soc_attach(void *ctrl_psoc, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, +dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id) { int int_ctx; struct dp_soc *soc = NULL; - struct htt_soc *htt_soc = NULL; + struct htt_soc *htt_soc; soc = qdf_mem_malloc(sizeof(*soc)); @@ -10109,7 +11355,9 @@ dp_soc_attach(void *ctrl_psoc, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, soc->osdev = qdf_osdev; soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS; + dp_soc_rx_history_attach(soc); wlan_set_srng_cfg(&soc->wlan_srng_cfg); + qdf_mem_zero(&soc->vdev_id_map, sizeof(soc->vdev_id_map)); soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); if (!soc->wlan_cfg_ctx) { @@ -10118,22 +11366,22 @@ dp_soc_attach(void *ctrl_psoc, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, } dp_soc_set_interrupt_mode(soc); - htt_soc = qdf_mem_malloc(sizeof(*htt_soc)); - if (!htt_soc) { - dp_err("HTT attach failed"); + + htt_soc = htt_soc_attach(soc, htc_handle); + + if (!htt_soc) goto fail1; - } + soc->htt_handle = htt_soc; - htt_soc->dp_soc = soc; - htt_soc->htc_soc = htc_handle; if (htt_soc_htc_prealloc(htt_soc) != QDF_STATUS_SUCCESS) goto fail2; - return (void *)soc; + return soc; fail2: - qdf_mem_free(htt_soc); + htt_soc_detach(htt_soc); fail1: + dp_soc_rx_history_detach(soc); qdf_mem_free(soc); fail0: return NULL; @@ -10147,20 +11395,22 @@ dp_soc_attach(void *ctrl_psoc, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, * * Return: DP SOC handle on success, NULL on failure */ -void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) +void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, + struct hif_opaque_softc *hif_handle) { int target_type; - struct dp_soc *soc = (struct dp_soc *)dpsoc; struct htt_soc *htt_soc = (struct htt_soc *)soc->htt_handle; + bool is_monitor_mode = false; - htt_soc->htc_soc = htc_handle; + htt_set_htc_handle(htt_soc, htc_handle); soc->hif_handle = hif_handle; soc->hal_soc = hif_get_hal_handle(soc->hif_handle); if (!soc->hal_soc) return NULL; - htt_soc_initialize(soc->htt_handle, soc->ctrl_psoc, htt_soc->htc_soc, + htt_soc_initialize(soc->htt_handle, soc->ctrl_psoc, + htt_get_htc_handle(htt_soc), soc->hal_soc, soc->osdev); target_type = hal_get_target_type(soc->hal_soc); switch (target_type) { @@ -10170,8 +11420,11 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) soc->ast_override_support = 1; soc->da_war_enabled = false; break; -#ifdef QCA_WIFI_QCA6390 +#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750) case TARGET_TYPE_QCA6390: + case TARGET_TYPE_QCA6490: + case TARGET_TYPE_QCA6750: wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx, REO_DST_RING_SIZE_QCA6290); wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, true); @@ -10188,13 +11441,14 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) } soc->wlan_cfg_ctx->rxdma1_enable = 0; break; -#endif +#endif /* QCA_WIFI_QCA6390 || QCA_WIFI_QCA6490 || QCA_WIFI_QCA6750 */ + case TARGET_TYPE_QCA8074: wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx, REO_DST_RING_SIZE_QCA8074); wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, true); - soc->hw_nac_monitor_support = 1; soc->da_war_enabled = true; + soc->is_rx_fse_full_cache_invalidate_war_enabled = true; break; case TARGET_TYPE_QCA8074V2: case TARGET_TYPE_QCA6018: @@ -10206,6 +11460,18 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) soc->per_tid_basize_max_tid = 8; soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_V2_MAPS; soc->da_war_enabled = false; + soc->is_rx_fse_full_cache_invalidate_war_enabled = true; + break; + case TARGET_TYPE_QCN9000: + wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx, + REO_DST_RING_SIZE_QCN9000); + soc->ast_override_support = 1; + soc->da_war_enabled = false; + wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, false); + soc->hw_nac_monitor_support = 1; + soc->per_tid_basize_max_tid = 8; + soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_V2_MAPS; + soc->lmac_polled_mode = 1; break; default: qdf_print("%s: Unknown tgt type %d\n", __func__, target_type); @@ -10213,10 +11479,22 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) break; } + dp_soc_set_interrupt_mode(soc); + if (soc->cdp_soc.ol_ops->get_con_mode && + soc->cdp_soc.ol_ops->get_con_mode() == + QDF_GLOBAL_MONITOR_MODE) + is_monitor_mode = true; + + wlan_cfg_fill_interrupt_mask(soc->wlan_cfg_ctx, soc->intr_mode, + is_monitor_mode); wlan_cfg_set_rx_hash(soc->wlan_cfg_ctx, cfg_get(soc->ctrl_psoc, CFG_DP_RX_HASH)); soc->cce_disable = false; + qdf_atomic_init(&soc->num_tx_outstanding); + soc->num_tx_allowed = + wlan_cfg_get_dp_soc_tx_device_limit(soc->wlan_cfg_ctx); + if (soc->cdp_soc.ol_ops->get_dp_cfg_param) { int ret = soc->cdp_soc.ol_ops->get_dp_cfg_param(soc->ctrl_psoc, CDP_CFG_MAX_PEER_ID); @@ -10251,7 +11529,7 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) /** * dp_soc_init_wifi3() - Initialize txrx SOC - * @dp_soc: Opaque DP SOC handle + * @soc: Opaque DP SOC handle * @ctrl_psoc: Opaque SOC handle from control plane(Unused) * @hif_handle: Opaque HIF handle * @htc_handle: Opaque HTC handle @@ -10261,11 +11539,13 @@ void *dp_soc_init(void *dpsoc, HTC_HANDLE htc_handle, void *hif_handle) * * Return: DP SOC handle on success, NULL on failure */ -void *dp_soc_init_wifi3(void *dpsoc, void *ctrl_psoc, void *hif_handle, +void *dp_soc_init_wifi3(struct cdp_soc_t *soc, + struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct hif_opaque_softc *hif_handle, HTC_HANDLE htc_handle, qdf_device_t qdf_osdev, struct ol_if_ops *ol_ops, uint16_t device_id) { - return dp_soc_init(dpsoc, htc_handle, hif_handle); + return dp_soc_init((struct dp_soc *)soc, htc_handle, hif_handle); } #endif @@ -10294,18 +11574,240 @@ void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id) * * Return: None */ -static void dp_is_hw_dbs_enable(struct dp_soc *soc, int *max_mac_rings) { bool dbs_enable = false; if (soc->cdp_soc.ol_ops->is_hw_dbs_2x2_capable) dbs_enable = soc->cdp_soc.ol_ops-> - is_hw_dbs_2x2_capable(soc->ctrl_psoc); + is_hw_dbs_2x2_capable((void *)soc->ctrl_psoc); *max_mac_rings = (dbs_enable)?(*max_mac_rings):1; } +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/* + * dp_cfr_filter() - Configure HOST RX monitor status ring for CFR + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * @enable: Enable/Disable CFR + * @filter_val: Flag to select Filter for monitor mode + */ +static void dp_cfr_filter(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = NULL; + struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; + int max_mac_rings; + uint8_t mac_id = 0; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return; + } + + if (pdev->monitor_vdev) { + dp_info("No action is needed since monitor mode is enabled\n"); + return; + } + soc = pdev->soc; + pdev->cfr_rcc_mode = false; + max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); + dp_is_hw_dbs_enable(soc, &max_mac_rings); + + dp_debug("Max_mac_rings %d", max_mac_rings); + dp_info("enable : %d, mode: 0x%x", enable, filter_val->mode); + + if (enable) { + pdev->cfr_rcc_mode = true; + + htt_tlv_filter.ppdu_start = 1; + htt_tlv_filter.ppdu_end = 1; + htt_tlv_filter.ppdu_end_user_stats = 1; + htt_tlv_filter.ppdu_end_user_stats_ext = 1; + htt_tlv_filter.ppdu_end_status_done = 1; + htt_tlv_filter.mpdu_start = 1; + htt_tlv_filter.offset_valid = false; + + htt_tlv_filter.enable_fp = + (filter_val->mode & MON_FILTER_PASS) ? 1 : 0; + htt_tlv_filter.enable_md = 0; + htt_tlv_filter.enable_mo = + (filter_val->mode & MON_FILTER_OTHER) ? 1 : 0; + htt_tlv_filter.fp_mgmt_filter = filter_val->fp_mgmt; + htt_tlv_filter.fp_ctrl_filter = filter_val->fp_ctrl; + htt_tlv_filter.fp_data_filter = filter_val->fp_data; + htt_tlv_filter.mo_mgmt_filter = filter_val->mo_mgmt; + htt_tlv_filter.mo_ctrl_filter = filter_val->mo_ctrl; + htt_tlv_filter.mo_data_filter = filter_val->mo_data; + } + + for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { + int mac_for_pdev = + dp_get_mac_id_for_pdev(mac_id, + pdev->pdev_id); + + htt_h2t_rx_ring_cfg(soc->htt_handle, + mac_for_pdev, + soc->rxdma_mon_status_ring[mac_id] + .hal_srng, + RXDMA_MONITOR_STATUS, + RX_DATA_BUFFER_SIZE, + &htt_tlv_filter); + } +} + +/** + * dp_get_cfr_rcc() - get cfr rcc config + * @soc_hdl: Datapath soc handle + * @pdev_id: id of objmgr pdev + * + * Return: true/false based on cfr mode setting + */ +static +bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = NULL; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return false; + } + + return pdev->cfr_rcc_mode; +} + +/** + * dp_set_cfr_rcc() - enable/disable cfr rcc config + * @soc_hdl: Datapath soc handle + * @pdev_id: id of objmgr pdev + * @enable: Enable/Disable cfr rcc mode + * + * Return: none + */ +static +void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = NULL; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return; + } + + pdev->cfr_rcc_mode = enable; +} + +/* + * dp_get_cfr_dbg_stats - Get the debug statistics for CFR + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * @cfr_rcc_stats: CFR RCC debug statistics buffer + * + * Return: none + */ +static inline void +dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct cdp_cfr_rcc_stats *cfr_rcc_stats) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) { + dp_err("Invalid pdev"); + return; + } + + qdf_mem_copy(cfr_rcc_stats, &pdev->stats.rcc, + sizeof(struct cdp_cfr_rcc_stats)); +} + +/* + * dp_clear_cfr_dbg_stats - Clear debug statistics for CFR + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * + * Return: none + */ +static void dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) { + dp_err("dp pdev is NULL"); + return; + } + + qdf_mem_zero(&pdev->stats.rcc, sizeof(pdev->stats.rcc)); +} + +/* + * dp_enable_mon_reap_timer() - enable/disable reap timer + * @soc_hdl: Datapath soc handle + * @pdev_id: id of objmgr pdev + * @enable: Enable/Disable reap timer of monitor status ring + * + * Return: none + */ +static void +dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool enable) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = NULL; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return; + } + + pdev->enable_reap_timer_non_pkt = enable; + if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) { + dp_debug("pktlog enabled %d", pdev->rx_pktlog_mode); + return; + } + + if (!soc->reap_timer_init) { + dp_err("reap timer not init"); + return; + } + + if (enable) + qdf_timer_mod(&soc->mon_reap_timer, + DP_INTR_POLL_TIMER_MS); + else + qdf_timer_sync_cancel(&soc->mon_reap_timer); +} +#endif + +/* + * dp_is_enable_reap_timer_non_pkt() - check if mon reap timer is + * enabled by non-pkt log or not + * @pdev: point to dp pdev + * + * Return: true if mon reap timer is enabled by non-pkt log + */ +static bool dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev) +{ + if (!pdev) { + dp_err("null pdev"); + return false; + } + + return pdev->enable_reap_timer_non_pkt; +} + /* * dp_is_soc_reinit() - Check if soc reinit is true * @soc: DP SoC context @@ -10330,7 +11832,6 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, bool enable) { struct dp_soc *soc = NULL; - struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; int max_mac_rings = wlan_cfg_get_num_mac_rings (pdev->wlan_cfg_ctx); uint8_t mac_id = 0; @@ -10351,45 +11852,22 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, */ return 0; } + if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_FULL) { pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL; - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.msdu_start = 1; - htt_tlv_filter.msdu_end = 1; - htt_tlv_filter.mpdu_end = 1; - htt_tlv_filter.packet_header = 1; - htt_tlv_filter.attention = 1; - htt_tlv_filter.ppdu_start = 1; - htt_tlv_filter.ppdu_end = 1; - htt_tlv_filter.ppdu_end_user_stats = 1; - htt_tlv_filter.ppdu_end_user_stats_ext = 1; - htt_tlv_filter.ppdu_end_status_done = 1; - htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < max_mac_rings; - mac_id++) { - int mac_for_pdev = - dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(soc->htt_handle, - mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id] - .hal_srng, - RXDMA_MONITOR_STATUS, - RX_BUFFER_SIZE, - &htt_tlv_filter); - + dp_mon_filter_setup_rx_pkt_log_full(pdev); + if (dp_mon_filter_update(pdev) != + QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("Pktlog full filters set failed")); + dp_mon_filter_reset_rx_pkt_log_full(pdev); + pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED; + return 0; } - if (soc->reap_timer_init) + if (soc->reap_timer_init && + (!dp_is_enable_reap_timer_non_pkt(pdev))) qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS); } @@ -10402,41 +11880,25 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, */ return 0; } - if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_LITE) { pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE; - htt_tlv_filter.ppdu_start = 1; - htt_tlv_filter.ppdu_end = 1; - htt_tlv_filter.ppdu_end_user_stats = 1; - htt_tlv_filter.ppdu_end_user_stats_ext = 1; - htt_tlv_filter.ppdu_end_status_done = 1; - htt_tlv_filter.mpdu_start = 1; - htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; - htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; - htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; - htt_tlv_filter.offset_valid = false; - - for (mac_id = 0; mac_id < max_mac_rings; - mac_id++) { - int mac_for_pdev = - dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(soc->htt_handle, - mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id] - .hal_srng, - RXDMA_MONITOR_STATUS, - RX_BUFFER_SIZE_PKTLOG_LITE, - &htt_tlv_filter); + /* + * Set the packet log lite mode filter. + */ + dp_mon_filter_setup_rx_pkt_log_lite(pdev); + if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("Pktlog lite filters set failed")); + dp_mon_filter_reset_rx_pkt_log_lite(pdev); + pdev->rx_pktlog_mode = + DP_RX_PKTLOG_DISABLED; + return 0; } - if (soc->reap_timer_init) + if (soc->reap_timer_init && + (!dp_is_enable_reap_timer_non_pkt(pdev))) qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS); } @@ -10477,23 +11939,26 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, } if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) { pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED; + dp_mon_filter_reset_rx_pkt_log_full(pdev); + if (dp_mon_filter_update(pdev) != + QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("Pktlog filters reset failed")); + return 0; + } - for (mac_id = 0; mac_id < max_mac_rings; - mac_id++) { - int mac_for_pdev = - dp_get_mac_id_for_pdev(mac_id, - pdev->pdev_id); - - htt_h2t_rx_ring_cfg(soc->htt_handle, - mac_for_pdev, - pdev->rxdma_mon_status_ring[mac_id] - .hal_srng, - RXDMA_MONITOR_STATUS, - RX_BUFFER_SIZE, - &htt_tlv_filter); + dp_mon_filter_reset_rx_pkt_log_lite(pdev); + if (dp_mon_filter_update(pdev) != + QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + FL("Pktlog filters reset failed")); + return 0; } - if (soc->reap_timer_init) + if (soc->reap_timer_init && + (!dp_is_enable_reap_timer_non_pkt(pdev))) qdf_timer_stop(&soc->mon_reap_timer); } break; @@ -10548,7 +12013,7 @@ static uint8_t dp_bucket_index(uint32_t delay, uint16_t *array) { uint8_t i = CDP_DELAY_BUCKET_0; - for (; i < CDP_DELAY_BUCKET_MAX; i++) { + for (; i < CDP_DELAY_BUCKET_MAX - 1; i++) { if (delay >= array[i] && delay <= array[i + 1]) return i; } @@ -10687,3 +12152,39 @@ void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay, dstats->avg_delay = ((delay + dstats->avg_delay) / 2); } } + +/** + * dp_get_peer_mac_list(): function to get peer mac list of vdev + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @newmac: Table of the clients mac + * @mac_cnt: No. of MACs required + * + * return: no of clients + */ +uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, + u_int8_t newmac[][QDF_MAC_ADDR_SIZE], + u_int16_t mac_cnt) +{ + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + struct dp_soc *dp_soc = (struct dp_soc *)soc; + struct dp_peer *peer; + uint16_t new_mac_cnt = 0; + + if (!vdev) + return new_mac_cnt; + + qdf_spin_lock_bh(&dp_soc->peer_ref_mutex); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + if (peer->bss_peer) + continue; + if (new_mac_cnt < mac_cnt) { + WLAN_ADDR_COPY(newmac[new_mac_cnt], peer->mac_addr.raw); + new_mac_cnt++; + } + } + qdf_spin_unlock_bh(&dp_soc->peer_ref_mutex); + return new_mac_cnt; +} diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.c new file mode 100644 index 0000000000000000000000000000000000000000..cfd9619be4c033726173b01f40b58628271e70d4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.c @@ -0,0 +1,1182 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include "dp_types.h" +#include "dp_internal.h" +#include "dp_htt.h" +#include "dp_mon_filter.h" + +/** + * dp_mon_filter_mode_type_to_str + * Monitor Filter mode to string + */ +static int8_t *dp_mon_filter_mode_type_to_str[DP_MON_FILTER_MAX_MODE] = { +#ifdef FEATURE_PERPKT_INFO + "DP MON FILTER ENHACHED STATS MODE", + "DP MON FILTER MCOPY MODE", +#endif /* FEATURE_PERPKT_INFO */ +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) + "DP MON FILTER SMART MONITOR MODE", +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ + "DP_MON FILTER MONITOR MODE", +#ifdef WLAN_RX_PKT_CAPTURE_ENH + "DP MON FILTER RX CAPTURE MODE", +#endif /* WLAN_RX_PKT_CAPTURE_ENH */ +#ifdef WDI_EVENT_ENABLE + "DP MON FILTER PKT LOG FULL MODE", + "DP MON FILTER PKT LOG LITE_MODE", +#endif /* WDI_EVENT_ENABLE */ +}; + +/** + * dp_mon_filter_show_filter() - Show the set filters + * @pdev: DP pdev handle + * @mode: The filter modes + * @tlv_filter: tlv filter + */ +static void dp_mon_filter_show_filter(struct dp_pdev *pdev, + enum dp_mon_filter_mode mode, + struct dp_mon_filter *filter) +{ + struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; + + DP_MON_FILTER_PRINT("[%s]: Valid: %d", + dp_mon_filter_mode_type_to_str[mode], + filter->valid); + DP_MON_FILTER_PRINT("mpdu_start: %d", tlv_filter->mpdu_start); + DP_MON_FILTER_PRINT("msdu_start: %d", tlv_filter->msdu_start); + DP_MON_FILTER_PRINT("packet: %d", tlv_filter->packet); + DP_MON_FILTER_PRINT("msdu_end: %d", tlv_filter->msdu_end); + DP_MON_FILTER_PRINT("mpdu_end: %d", tlv_filter->mpdu_end); + DP_MON_FILTER_PRINT("packet_header: %d", + tlv_filter->packet_header); + DP_MON_FILTER_PRINT("attention: %d", tlv_filter->attention); + DP_MON_FILTER_PRINT("ppdu_start: %d", tlv_filter->ppdu_start); + DP_MON_FILTER_PRINT("ppdu_end: %d", tlv_filter->ppdu_end); + DP_MON_FILTER_PRINT("ppdu_end_user_stats: %d", + tlv_filter->ppdu_end_user_stats); + DP_MON_FILTER_PRINT("ppdu_end_user_stats_ext: %d", + tlv_filter->ppdu_end_user_stats_ext); + DP_MON_FILTER_PRINT("ppdu_end_status_done: %d", + tlv_filter->ppdu_end_status_done); + DP_MON_FILTER_PRINT("header_per_msdu: %d", tlv_filter->header_per_msdu); + DP_MON_FILTER_PRINT("enable_fp: %d", tlv_filter->enable_fp); + DP_MON_FILTER_PRINT("enable_md: %d", tlv_filter->enable_md); + DP_MON_FILTER_PRINT("enable_mo: %d", tlv_filter->enable_mo); + DP_MON_FILTER_PRINT("fp_mgmt_filter: 0x%x", tlv_filter->fp_mgmt_filter); + DP_MON_FILTER_PRINT("mo_mgmt_filter: 0x%x", tlv_filter->mo_mgmt_filter); + DP_MON_FILTER_PRINT("fp_ctrl_filter: 0x%x", tlv_filter->fp_ctrl_filter); + DP_MON_FILTER_PRINT("mo_ctrl_filter: 0x%x", tlv_filter->mo_ctrl_filter); + DP_MON_FILTER_PRINT("fp_data_filter: 0x%x", tlv_filter->fp_data_filter); + DP_MON_FILTER_PRINT("mo_data_filter: 0x%x", tlv_filter->mo_data_filter); + DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter); + DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter); + DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter); +} + +/** + * dp_mon_ht2_rx_ring_cfg() - Send the tlv config to fw for a srng_type + * based on target + * @soc: DP soc handle + * @pdev: DP pdev handle + * @srng_type: The srng type for which filter wll be set + * @tlv_filter: tlv filter + */ +static QDF_STATUS +dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc, + struct dp_pdev *pdev, + enum dp_mon_filter_srng_type srng_type, + struct htt_rx_ring_tlv_filter *tlv_filter) +{ + int mac_id; + int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); + QDF_STATUS status = QDF_STATUS_SUCCESS; + + /* + * Overwrite the max_mac_rings for the status rings. + */ + if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS) + dp_is_hw_dbs_enable(soc, &max_mac_rings); + + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_INFO, + FL("srng type %d Max_mac_rings %d "), + srng_type, + max_mac_rings); + + /* + * Loop through all MACs per radio and set the filter to the individual + * macs. For MCL + */ + for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { + int mac_for_pdev = + dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); + int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); + int hal_ring_type, ring_buf_size; + hal_ring_handle_t hal_ring_hdl; + + switch (srng_type) { + case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: + hal_ring_hdl = pdev->rx_mac_buf_ring[lmac_id].hal_srng; + hal_ring_type = RXDMA_BUF; + ring_buf_size = RX_DATA_BUFFER_SIZE; + break; + + case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: + /* + * If two back to back HTT msg sending happened in + * short time, the second HTT msg source SRNG HP + * writing has chance to fail, this has been confirmed + * by HST HW. + * for monitor mode, here is the last HTT msg for sending. + * if the 2nd HTT msg for monitor status ring sending failed, + * HW won't provide anything into 2nd monitor status ring. + * as a WAR, add some delay before 2nd HTT msg start sending, + * > 2us is required per HST HW, delay 100 us for safe. + */ + if (mac_id) + qdf_udelay(100); + + hal_ring_hdl = + soc->rxdma_mon_status_ring[lmac_id].hal_srng; + hal_ring_type = RXDMA_MONITOR_STATUS; + ring_buf_size = RX_DATA_BUFFER_SIZE; + break; + + case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: + hal_ring_hdl = + soc->rxdma_mon_buf_ring[lmac_id].hal_srng; + hal_ring_type = RXDMA_MONITOR_BUF; + ring_buf_size = RX_DATA_BUFFER_SIZE; + break; + + default: + return QDF_STATUS_E_FAILURE; + } + + status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, + hal_ring_hdl, hal_ring_type, + ring_buf_size, + tlv_filter); + if (status != QDF_STATUS_SUCCESS) + return status; + } + + return status; +} + +/** + * dp_mon_filter_ht2_setup() - Setup the filter for the Target setup + * @soc: DP soc handle + * @pdev: DP pdev handle + * @srng_type: The srng type for which filter wll be set + * @tlv_filter: tlv filter + */ +static void dp_mon_filter_ht2_setup(struct dp_soc *soc, struct dp_pdev *pdev, + enum dp_mon_filter_srng_type srng_type, + struct dp_mon_filter *filter) +{ + int32_t current_mode = 0; + struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; + + /* + * Loop through all the modes. + */ + for (current_mode = 0; current_mode < DP_MON_FILTER_MAX_MODE; + current_mode++) { + struct dp_mon_filter *mon_filter = + &pdev->filter[current_mode][srng_type]; + uint32_t src_filter = 0, dst_filter = 0; + + /* + * Check if the correct mode is enabled or not. + */ + if (!mon_filter->valid) + continue; + + filter->valid = true; + + /* + * Set the super bit fields + */ + src_filter = + DP_MON_FILTER_GET(&mon_filter->tlv_filter, FILTER_TLV); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_TLV); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_TLV, dst_filter); + + /* + * Set the filter management filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_FP_MGMT); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_MGMT); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_FP_MGMT, dst_filter); + + /* + * Set the monitor other management filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MO_MGMT); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_MGMT); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_MO_MGMT, dst_filter); + + /* + * Set the filter pass control filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_FP_CTRL); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_CTRL); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_FP_CTRL, dst_filter); + + /* + * Set the monitor other control filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MO_CTRL); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_CTRL); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_MO_CTRL, dst_filter); + + /* + * Set the filter pass data filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_FP_DATA); + dst_filter = DP_MON_FILTER_GET(tlv_filter, + FILTER_FP_DATA); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, + FILTER_FP_DATA, dst_filter); + + /* + * Set the monitor other data filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MO_DATA); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_DATA); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_MO_DATA, dst_filter); + + /* + * Set the monitor direct data filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MD_DATA); + dst_filter = DP_MON_FILTER_GET(tlv_filter, + FILTER_MD_DATA); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, + FILTER_MD_DATA, dst_filter); + + /* + * Set the monitor direct management filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MD_MGMT); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_MGMT); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_MD_MGMT, dst_filter); + + /* + * Set the monitor direct management filter. + */ + src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, + FILTER_MD_CTRL); + dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL); + dst_filter |= src_filter; + DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter); + } + + dp_mon_filter_show_filter(pdev, 0, filter); +} + +/** + * dp_mon_filter_reset_mon_srng() + * @soc: DP SoC handle + * @pdev: DP pdev handle + * @mon_srng_type: Monitor srng type + */ +static void +dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev, + enum dp_mon_filter_srng_type mon_srng_type) +{ + struct htt_rx_ring_tlv_filter tlv_filter = {0}; + + if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type, + &tlv_filter) != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Monitor destinatin ring filter setting failed")); + } +} + +#if defined(FEATURE_PERPKT_INFO) || defined(ATH_SUPPORT_NAC_RSSI) \ + || defined(ATH_SUPPORT_NAC) || defined(WLAN_RX_PKT_CAPTURE_ENH) +/** + * dp_mon_filter_check_co_exist() - Check the co-existing of the + * enabled modes. + * @pdev: DP pdev handle + * + * Return: QDF_STATUS + */ +static QDF_STATUS dp_mon_filter_check_co_exist(struct dp_pdev *pdev) +{ + /* + * Check if the Rx Enhanced capture mode, monitor mode, + * smart_monitor_mode and mcopy mode can co-exist together. + */ + if ((pdev->rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED) && + ((pdev->neighbour_peers_added && pdev->monitor_vdev) || + pdev->mcopy_mode)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Rx Capture mode can't exist with modes:\n" + "Smart Monitor Mode:%d\n" + "M_Copy Mode:%d"), + pdev->neighbour_peers_added, + pdev->mcopy_mode); + return QDF_STATUS_E_FAILURE; + } + + /* + * Check if the monitor mode cannot co-exist with any other mode. + */ + if ((pdev->monitor_vdev && pdev->monitor_configured) && + (pdev->mcopy_mode || pdev->neighbour_peers_added)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Monitor mode can't exist with modes\n" + "M_Copy Mode:%d\n" + "Smart Monitor Mode:%d"), + pdev->mcopy_mode, + pdev->neighbour_peers_added); + return QDF_STATUS_E_FAILURE; + } + + /* + * Check if the smart monitor mode can co-exist with any other mode + */ + if (pdev->neighbour_peers_added && + ((pdev->mcopy_mode) || pdev->monitor_configured)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Smart Monitor mode can't exist with modes\n" + "M_Copy Mode:%d\n" + "Monitor Mode:%d"), + pdev->mcopy_mode, + pdev->monitor_configured); + return QDF_STATUS_E_FAILURE; + } + + /* + * Check if the m_copy, monitor mode and the smart_monitor_mode + * can co-exist togther. + */ + if (pdev->mcopy_mode && + (pdev->monitor_vdev || pdev->neighbour_peers_added)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("mcopy mode can't exist with modes\n" + "Monitor Mode:%d\n" + "Smart Monitor Mode:%d"), + pdev->monitor_vdev, + pdev->neighbour_peers_added); + return QDF_STATUS_E_FAILURE; + } + + /* + * Check if the Rx packet log lite or full can co-exist with + * the enable modes. + */ + if ((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) && + (pdev->monitor_vdev || pdev->monitor_configured)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Rx pktlog full/lite can't exist with modes\n" + "Monitor Mode:%d"), + pdev->monitor_configured); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS dp_mon_filter_check_co_exist(struct dp_pdev *pdev) +{ + /* + * Check if the Rx packet log lite or full can co-exist with + * the enable modes. + */ + if ((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) && + (pdev->monitor_vdev || pdev->monitor_configured)) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Rx pktlog full/lite can't exist with modes\n" + "Monitor Mode:%d"), + pdev->monitor_configured); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * dp_mon_filter_set_mon_cmn() - Setp the common mon filters + * @pdev: DP pdev handle + * @filter: DP mon filter + * + * Return: QDF_STATUS + */ +static void dp_mon_filter_set_mon_cmn(struct dp_pdev *pdev, + struct dp_mon_filter *filter) +{ + filter->tlv_filter.mpdu_start = 1; + filter->tlv_filter.msdu_start = 1; + filter->tlv_filter.packet = 1; + filter->tlv_filter.msdu_end = 1; + filter->tlv_filter.mpdu_end = 1; + filter->tlv_filter.packet_header = 1; + filter->tlv_filter.attention = 1; + filter->tlv_filter.ppdu_start = 0; + filter->tlv_filter.ppdu_end = 0; + filter->tlv_filter.ppdu_end_user_stats = 0; + filter->tlv_filter.ppdu_end_user_stats_ext = 0; + filter->tlv_filter.ppdu_end_status_done = 0; + filter->tlv_filter.header_per_msdu = 1; + filter->tlv_filter.enable_fp = + (pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; + filter->tlv_filter.enable_mo = + (pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; + + filter->tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter; + filter->tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter; + filter->tlv_filter.fp_data_filter = pdev->fp_data_filter; + filter->tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter; + filter->tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter; + filter->tlv_filter.mo_data_filter = pdev->mo_data_filter; + filter->tlv_filter.offset_valid = false; +} + +/** + * dp_mon_filter_set_status_cmn() - Setp the common status filters + * @pdev: DP pdev handle + * @filter: Dp mon filters + * + * Return: QDF_STATUS + */ +static void dp_mon_filter_set_status_cmn(struct dp_pdev *pdev, + struct dp_mon_filter *filter) +{ + filter->tlv_filter.mpdu_start = 1; + filter->tlv_filter.msdu_start = 0; + filter->tlv_filter.packet = 0; + filter->tlv_filter.msdu_end = 0; + filter->tlv_filter.mpdu_end = 0; + filter->tlv_filter.attention = 0; + filter->tlv_filter.ppdu_start = 1; + filter->tlv_filter.ppdu_end = 1; + filter->tlv_filter.ppdu_end_user_stats = 1; + filter->tlv_filter.ppdu_end_user_stats_ext = 1; + filter->tlv_filter.ppdu_end_status_done = 1; + filter->tlv_filter.enable_fp = 1; + filter->tlv_filter.enable_md = 0; + filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; + filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; + filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL; + filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; + filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; + filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL; + filter->tlv_filter.offset_valid = false; +} + +#ifdef FEATURE_PERPKT_INFO +/** + * dp_mon_filter_setup_enhanced_stats() - Setup the enhanced stats filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_ENHACHED_STATS_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + + dp_mon_filter_set_status_cmn(pdev, &filter); + dp_mon_filter_show_filter(pdev, mode, &filter); + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_enhanced_stats() - Reset the enhanced stats filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_ENHACHED_STATS_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_MCOPY_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_mon_cmn(pdev, &filter); + + filter.tlv_filter.fp_data_filter = 0; + filter.tlv_filter.mo_data_filter = 0; + + dp_mon_filter_show_filter(pdev, mode, &filter); + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + /* Clear the filter as the same filter will be used to set the + * monitor status ring + */ + qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter)); + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + + /* Setup the filter */ + filter.tlv_filter.enable_mo = 1; + filter.tlv_filter.packet_header = 1; + dp_mon_filter_show_filter(pdev, mode, &filter); + + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_mcopy_mode() - Reset the m_copy mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_MCOPY_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} +#endif /* FEATURE_PERPKT_INFO */ + +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) +/** + * dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_SMART_MONITOR_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + + if (soc->hw_nac_monitor_support) { + filter.tlv_filter.enable_md = 1; + filter.tlv_filter.packet_header = 1; + filter.tlv_filter.md_data_filter = FILTER_DATA_ALL; + } + + dp_mon_filter_show_filter(pdev, mode, &filter); + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_smart_monitor() - Reset the smart monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_SMART_MONITOR_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + pdev->filter[mode][srng_type] = filter; +} +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ + +#ifdef WLAN_RX_PKT_CAPTURE_ENH +/** + * dp_mon_filter_setup_rx_enh_capture() - Setup the Rx capture mode filters + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_RX_CAPTURE_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_mon_cmn(pdev, &filter); + + filter.tlv_filter.fp_mgmt_filter = 0; + filter.tlv_filter.fp_ctrl_filter = 0; + filter.tlv_filter.fp_data_filter = 0; + filter.tlv_filter.mo_mgmt_filter = 0; + filter.tlv_filter.mo_ctrl_filter = 0; + filter.tlv_filter.mo_data_filter = 0; + + dp_mon_filter_show_filter(pdev, mode, &filter); + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + /* Clear the filter as the same filter will be used to set the + * monitor status ring + */ + qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter)); + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + + /* Setup the filter */ + filter.tlv_filter.mpdu_end = 1; + filter.tlv_filter.enable_mo = 1; + filter.tlv_filter.packet_header = 1; + + if (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) { + filter.tlv_filter.header_per_msdu = 0; + filter.tlv_filter.enable_mo = 0; + } else if (pdev->rx_enh_capture_mode == + CDP_RX_ENH_CAPTURE_MPDU_MSDU) { + bool is_rx_mon_proto_flow_tag_enabled = + wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx); + filter.tlv_filter.header_per_msdu = 1; + filter.tlv_filter.enable_mo = 0; + if (pdev->is_rx_enh_capture_trailer_enabled || + is_rx_mon_proto_flow_tag_enabled) + filter.tlv_filter.msdu_end = 1; + } + + dp_mon_filter_show_filter(pdev, mode, &filter); + + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_rx_enh_capture() - Reset the Rx capture mode filters + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_RX_CAPTURE_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} +#endif /* WLAN_RX_PKT_CAPTURE_ENH */ + +/** + * dp_mon_filter_setup_mon_mode() - Setup the Rx monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + filter.valid = true; + dp_mon_filter_set_mon_cmn(pdev, &filter); + dp_mon_filter_show_filter(pdev, mode, &filter); + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + /* Clear the filter as the same filter will be used to set the + * monitor status ring + */ + qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter)); + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + filter.tlv_filter.enable_mo = 1; + + dp_mon_filter_show_filter(pdev, mode, &filter); + + /* Store the above filter */ + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_mon_mode() - Reset the Rx monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + struct dp_soc *soc = NULL; + enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return; + } + + srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ? + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF : + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF); + pdev->filter[mode][srng_type] = filter; + + srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + pdev->filter[mode][srng_type] = filter; +} + +#ifdef WDI_EVENT_ENABLE +/** + * dp_mon_filter_setup_rx_pkt_log_full() - Setup the Rx pktlog full mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_FULL_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + + /* Setup the filter */ + filter.tlv_filter.packet_header = 1; + filter.tlv_filter.msdu_start = 1; + filter.tlv_filter.msdu_end = 1; + filter.tlv_filter.mpdu_end = 1; + filter.tlv_filter.attention = 1; + + dp_mon_filter_show_filter(pdev, mode, &filter); + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_rx_pkt_log_full() - Reset the Rx pktlog full mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_FULL_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_setup_rx_pkt_log_lite() - Setup the Rx pktlog lite mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_LITE_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + /* Enabled the filter */ + filter.valid = true; + dp_mon_filter_set_status_cmn(pdev, &filter); + + dp_mon_filter_show_filter(pdev, mode, &filter); + pdev->filter[mode][srng_type] = filter; +} + +/** + * dp_mon_filter_reset_rx_pkt_log_lite() - Reset the Rx pktlog lite mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev) +{ + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_LITE_MODE; + enum dp_mon_filter_srng_type srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + pdev->filter[mode][srng_type] = filter; +} +#endif /* WDI_EVENT_ENABLE */ + +/** + * dp_mon_filter_update() - Setup the monitor filter setting for a srng + * type + * @pdev: DP pdev handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev) +{ + struct dp_soc *soc; + bool mon_mode_set = false; + struct dp_mon_filter filter = {0}; + enum dp_mon_filter_srng_type mon_srng_type = + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return QDF_STATUS_E_FAILURE; + } + + soc = pdev->soc; + if (!soc) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Soc Context is null")); + return QDF_STATUS_E_FAILURE; + } + + status = dp_mon_filter_check_co_exist(pdev); + if (status != QDF_STATUS_SUCCESS) + return status; + + /* + * Setup the filters for the monitor destination ring. + */ + if (!soc->wlan_cfg_ctx->rxdma1_enable) + mon_srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF; + + /* + * Setup the filters for the monitor mode. + */ + qdf_mem_zero(&(filter), sizeof(filter)); + dp_mon_filter_ht2_setup(soc, pdev, mon_srng_type, &filter); + + mon_mode_set = filter.valid; + if (mon_mode_set) { + status = dp_mon_ht2_rx_ring_cfg(soc, pdev, + mon_srng_type, + &filter.tlv_filter); + } else { + /* + * For WIN case the monitor buffer ring is used and it does need + * reset when monitor mode gets disabled. + */ + if (soc->wlan_cfg_ctx->rxdma1_enable) { + status = dp_mon_ht2_rx_ring_cfg(soc, pdev, + mon_srng_type, + &filter.tlv_filter); + } + } + + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Monitor destination ring filter setting failed")); + return QDF_STATUS_E_FAILURE; + } + + /* + * Setup the filters for the status ring. + */ + qdf_mem_zero(&(filter), sizeof(filter)); + dp_mon_filter_ht2_setup(soc, pdev, + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS, + &filter); + + /* + * Reset the monitor filters if the all the modes for the status rings + * are disabled. This is done to prevent the HW backpressure from the + * monitor destination ring in case the status ring filters + * are not enabled. + */ + if (!filter.valid && mon_mode_set) + dp_mon_filter_reset_mon_srng(soc, pdev, mon_srng_type); + + if (dp_mon_ht2_rx_ring_cfg(soc, pdev, + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS, + &filter.tlv_filter) != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Monitor status ring filter setting failed")); + dp_mon_filter_reset_mon_srng(soc, pdev, mon_srng_type); + return QDF_STATUS_E_FAILURE; + } + + return status; +} + +/** + * dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in + * the radio object. + * @pdev: DP pdev handle + */ +void dp_mon_filter_dealloc(struct dp_pdev *pdev) +{ + enum dp_mon_filter_mode mode; + struct dp_mon_filter **mon_filter = NULL; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return; + } + + mon_filter = pdev->filter; + + /* + * Check if the monitor filters are already allocated to the pdev. + */ + if (!mon_filter) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Found NULL memmory for the Monitor filter")); + return; + } + + /* + * Iterate through the every mode and free the filter object. + */ + for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { + if (!mon_filter[mode]) { + continue; + } + + qdf_mem_free(mon_filter[mode]); + mon_filter[mode] = NULL; + } + + qdf_mem_free(mon_filter); + pdev->filter = NULL; +} + +/** + * dp_mon_filter_alloc() - Allocate the filter objects to be stored in + * the radio object. + * @pdev: DP pdev handle + */ +struct dp_mon_filter **dp_mon_filter_alloc(struct dp_pdev *pdev) +{ + struct dp_mon_filter **mon_filter = NULL; + enum dp_mon_filter_mode mode; + + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("pdev Context is null")); + return NULL; + } + + mon_filter = (struct dp_mon_filter **)qdf_mem_malloc( + (sizeof(struct dp_mon_filter *) * + DP_MON_FILTER_MAX_MODE)); + if (!mon_filter) { + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR, + FL("Monitor filter mem allocation failed")); + return NULL; + } + + qdf_mem_zero(mon_filter, + sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE); + + /* + * Allocate the memory for filters for different srngs for each modes. + */ + for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { + mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) * + DP_MON_FILTER_SRNG_TYPE_MAX); + /* Assign the mon_filter to the pdev->filter such + * that the dp_mon_filter_dealloc() can free up the filters. */ + if (!mon_filter[mode]) { + pdev->filter = mon_filter; + goto fail; + } + } + + return mon_filter; +fail: + dp_mon_filter_dealloc(pdev); + return NULL; +} diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.h new file mode 100644 index 0000000000000000000000000000000000000000..711185f28b424457655d71670686ab9c57b3ed31 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _DP_MON_FILTER_H_ +#define _DP_MON_FILTER_H_ + +/** + * Accessor Macros to access the software + * defined HTT filter htt_rx_ring_tlv_filter. + */ +#define DP_MON_FILTER_TLV_OFFSET 0x00000000 +#define DP_MON_FILTER_TLV_MASK 0xffffffff +#define DP_MON_FILTER_TLV_LSB 0 + +#define DP_MON_FILTER_FP_MGMT_OFFSET 0x00000004 +#define DP_MON_FILTER_FP_MGMT_MASK 0x0000ffff +#define DP_MON_FILTER_FP_MGMT_LSB 0 + +#define DP_MON_FILTER_MO_MGMT_OFFSET 0x00000004 +#define DP_MON_FILTER_MO_MGMT_MASK 0xffff0000 +#define DP_MON_FILTER_MO_MGMT_LSB 16 + +#define DP_MON_FILTER_FP_CTRL_OFFSET 0x00000008 +#define DP_MON_FILTER_FP_CTRL_MASK 0x0000ffff +#define DP_MON_FILTER_FP_CTRL_LSB 0 + +#define DP_MON_FILTER_MO_CTRL_OFFSET 0x00000008 +#define DP_MON_FILTER_MO_CTRL_MASK 0xffff0000 +#define DP_MON_FILTER_MO_CTRL_LSB 16 + +#define DP_MON_FILTER_FP_DATA_OFFSET 0x0000000c +#define DP_MON_FILTER_FP_DATA_MASK 0x0000ffff +#define DP_MON_FILTER_FP_DATA_LSB 0 + +#define DP_MON_FILTER_MO_DATA_OFFSET 0x0000000c +#define DP_MON_FILTER_MO_DATA_MASK 0xffff0000 +#define DP_MON_FILTER_MO_DATA_LSB 16 + +#define DP_MON_FILTER_MD_DATA_OFFSET 0x00000010 +#define DP_MON_FILTER_MD_DATA_MASK 0x0000ffff +#define DP_MON_FILTER_MD_DATA_LSB 0 + +#define DP_MON_FILTER_MD_MGMT_OFFSET 0x00000010 +#define DP_MON_FILTER_MD_MGMT_MASK 0xffff0000 +#define DP_MON_FILTER_MD_MGMT_LSB 16 + +#define DP_MON_FILTER_MD_CTRL_OFFSET 0x00000014 +#define DP_MON_FILTER_MD_CTRL_MASK 0x0000ffff +#define DP_MON_FILTER_MD_CTRL_LSB 0 + +#define DP_MON_FILTER_GET(src, field) \ + ((*((uint32_t *)((uint8_t *)(src) + DP_MON_ ## field ## _OFFSET)) & \ + (DP_MON_ ## field ## _MASK)) >> DP_MON_ ## field ## _LSB) \ + +#define DP_MON_FILTER_SET(dst, field, value) \ +do { \ + uint32_t *val = \ + ((uint32_t *)((uint8_t *)(dst) + DP_MON_ ## field ## _OFFSET)); \ + *val &= ~(DP_MON_ ## field ## _MASK); \ + *val |= ((value) << DP_MON_ ## field ## _LSB); \ +} while (0) + +#define DP_MON_FILTER_PRINT(fmt, args ...) \ + QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_DEBUG, \ + fmt, ## args) +/** + * struct dp_mon_filter - Monitor TLV filter + * @valid: enable/disable TLV filter + * @tlv_filter: Rx ring TLV filter + */ +struct dp_mon_filter { + bool valid; + struct htt_rx_ring_tlv_filter tlv_filter; +}; + +/** + * enum dp_mon_filter_mode - Different modes for SRNG filters + * @DP_MON_FILTER_ENHACHED_STATS_MODE: PPDU enhanced stats mode + * @DP_MON_FILTER_SMART_MONITOR_MODE: Smart monitor mode + * @DP_MON_FILTER_MCOPY_MODE: AM copy mode + * @DP_MON_FILTER_MONITOR_MODE: Monitor mode + * @DP_MON_FILTER_RX_CAPTURE_MODE: Rx Capture mode + * @DP_MON_FILTER_PKT_LOG_FULL_MODE: Packet log full mode + * @DP_MON_FILTER_PKT_LOG_LITE_MODE: Packet log lite mode + */ +enum dp_mon_filter_mode { +#ifdef FEATURE_PERPKT_INFO + DP_MON_FILTER_ENHACHED_STATS_MODE, + DP_MON_FILTER_MCOPY_MODE, +#endif /* FEATURE_PERPKT_INFO */ +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) + DP_MON_FILTER_SMART_MONITOR_MODE, +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ + DP_MON_FILTER_MONITOR_MODE, +#ifdef WLAN_RX_PKT_CAPTURE_ENH + DP_MON_FILTER_RX_CAPTURE_MODE, +#endif /* WLAN_RX_PKT_CAPTURE_ENH */ + +#ifdef WDI_EVENT_ENABLE + DP_MON_FILTER_PKT_LOG_FULL_MODE, + DP_MON_FILTER_PKT_LOG_LITE_MODE, +#endif /* WDI_EVENT_ENABLE */ + DP_MON_FILTER_MAX_MODE +}; + +/** + * enum dp_mon_filter_srng_type - Srng types dynamic mode filter + * settings. + * @DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: RXDMA srng type + * @DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: RxDMA monitor status srng + * @DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: RxDMA destination srng + * @DP_MON_FILTER_SRNG_TYPE_MAX: Srng max type + */ +enum dp_mon_filter_srng_type { + DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF, + DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS, + DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF, + DP_MON_FILTER_SRNG_TYPE_MAX +}; + +/** + * enum dp_mon_filter_action - Action for storing the filters + * into the radio structure. + * @DP_MON_FILTER_CLEAR - Clears the filter for a mode + * @DP_MON_FILTER_SET - Set the filtes for a mode + */ +enum dp_mon_filter_action { + DP_MON_FILTER_CLEAR, + DP_MON_FILTER_SET, +}; + +#ifdef FEATURE_PERPKT_INFO +/** + * dp_mon_filter_setup_enhanced_stats() - Setup the enhanced stats filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev); + +/*** + * dp_mon_filter_reset_enhanced_stats() - Reset the enhanced stats filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev); + +/** + * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_mcopy_mode() - Reset the m_copy mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev); +#endif /* FEATURE_PERPKT_INFO */ + +#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) +/** + * dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_smart_monitor() - Reset the smart monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev); +#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ + +#ifdef WLAN_RX_PKT_CAPTURE_ENH +/** + * dp_mon_filter_setup_rx_enh_capture() - Setup the Rx capture mode filters + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_rx_enh_capture() - Reset the Rx capture mode filters + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev); +#endif /* WLAN_RX_PKT_CAPTURE_ENH */ + +/** + * dp_mon_filter_setup_mon_mode() - Setup the Rx monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_mon_mode() - Reset the Rx monitor mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev); + +#ifdef WDI_EVENT_ENABLE +/** + * dp_mon_filter_setup_rx_pkt_log_full() - Setup the Rx pktlog full mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_rx_pkt_log_full() - Reset the Rx pktlog full mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev); + +/** + * dp_mon_filter_setup_rx_pkt_log_lite() - Setup the Rx pktlog lite mode filter + * in the radio object. + * @pdev: DP pdev handle + */ +void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev); + +/** + * dp_mon_filter_reset_rx_pkt_log_lite() - Reset the Rx pktlog lite mode filter + * @pdev: DP pdev handle + */ +void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev); +#endif /* WDI_EVENT_ENABLE */ + +/** + * dp_mon_filter_update() - Setup the monitor filter setting for a srng + * type + * @pdev: DP pdev handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev); + +/** + * dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in + * the radio object. + * @pdev: DP pdev handle + */ +void dp_mon_filter_dealloc(struct dp_pdev *pdev); + +/** + * dp_mon_filter_alloc() - Allocate the filter objects to be stored in + * the radio object. + * @pdev: DP pdev handle + */ +struct dp_mon_filter **dp_mon_filter_alloc(struct dp_pdev *pdev); +#endif /* #ifndef _DP_MON_FILTER_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c index b332621f7691d2d01098fb3aafc09d634de60fd5..9cc238688bd8eb270ec54cea220039dd3e5af6b8 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,10 +28,6 @@ #include "dp_rx.h" #include #include -#ifdef CONFIG_MCL -#include -#include -#endif #include #include @@ -38,7 +35,34 @@ #include "dp_tx_capture.h" #endif -#ifdef DP_LFR +#ifdef FEATURE_WDS +static inline bool +dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer, + struct dp_ast_entry *ast_entry) +{ + /* if peer map v2 is enabled we are not freeing ast entry + * here and it is supposed to be freed in unmap event (after + * we receive delete confirmation from target) + * + * if peer_id is invalid we did not get the peer map event + * for the peer free ast entry from here only in this case + */ + + if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) && + (ast_entry->type != CDP_TXRX_AST_TYPE_SELF)) + return true; + + return false; +} +#else +static inline bool +dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer, + struct dp_ast_entry *ast_entry) +{ + return false; +} +#endif + static inline void dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params, uint8_t valid) @@ -49,11 +73,6 @@ dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params, "%s: Setting SSN valid bit to %d", __func__, valid); } -#else -static inline void -dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params, - uint8_t valid) {}; -#endif static inline int dp_peer_find_mac_addr_cmp( union dp_align_mac_addr *mac_addr1, @@ -268,12 +287,15 @@ static inline void dp_peer_ast_cleanup(struct dp_soc *soc, txrx_ast_free_cb cb = ast->callback; void *cookie = ast->cookie; + dp_debug("mac_addr: " QDF_MAC_ADDR_FMT ", cb: %pK, cookie: %pK", + QDF_MAC_ADDR_REF(ast->mac_addr.raw), cb, cookie); + /* Call the callbacks to free up the cookie */ if (cb) { ast->callback = NULL; ast->cookie = NULL; cb(soc->ctrl_psoc, - soc, + dp_soc_to_cdp_soc(soc), cookie, CDP_TXRX_AST_DELETE_IN_PROGRESS); } @@ -296,6 +318,8 @@ static void dp_peer_ast_hash_detach(struct dp_soc *soc) if (!soc->ast_hash.bins) return; + dp_debug("%pK: num_ast_entries: %u", soc, soc->num_ast_entries); + qdf_spin_lock_bh(&soc->ast_lock); for (index = 0; index <= soc->ast_hash.mask; index++) { if (!TAILQ_EMPTY(&soc->ast_hash.bins[index])) { @@ -372,6 +396,9 @@ void dp_peer_ast_hash_remove(struct dp_soc *soc, /* Check if tail is not empty before delete*/ QDF_ASSERT(!TAILQ_EMPTY(&soc->ast_hash.bins[index])); + dp_debug("ast_idx: %u idx: %u mac_addr: " QDF_MAC_ADDR_FMT, + ase->ast_idx, index, QDF_MAC_ADDR_REF(ase->mac_addr.raw)); + TAILQ_FOREACH(tmpase, &soc->ast_hash.bins[index], hash_list_elem) { if (tmpase == ase) { found = 1; @@ -496,10 +523,9 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, } QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: peer %pK ID %d vid %d mac %02x:%02x:%02x:%02x:%02x:%02x", - __func__, peer, hw_peer_id, vdev_id, mac_addr[0], - mac_addr[1], mac_addr[2], mac_addr[3], - mac_addr[4], mac_addr[5]); + "%s: peer %pK ID %d vid %d mac "QDF_MAC_ADDR_FMT, + __func__, peer, hw_peer_id, vdev_id, + QDF_MAC_ADDR_REF(mac_addr)); qdf_spin_lock_bh(&soc->ast_lock); @@ -530,8 +556,8 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, return; } -void dp_peer_free_hmwds_cb(void *ctrl_psoc, - void *dp_soc, +void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct cdp_soc *dp_soc, void *cookie, enum cdp_ast_free_status status) { @@ -577,34 +603,53 @@ int dp_peer_add_ast(struct dp_soc *soc, uint32_t flags) { struct dp_ast_entry *ast_entry = NULL; - struct dp_vdev *vdev = NULL; + struct dp_vdev *vdev = NULL, *tmp_vdev = NULL; struct dp_pdev *pdev = NULL; uint8_t next_node_mac[6]; int ret = -1; txrx_ast_free_cb cb = NULL; void *cookie = NULL; - - qdf_spin_lock_bh(&soc->ast_lock); - if (peer->delete_in_progress) { - qdf_spin_unlock_bh(&soc->ast_lock); - return ret; - } + struct dp_peer *tmp_peer = NULL; + bool is_peer_found = false; vdev = peer->vdev; if (!vdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("Peers vdev is NULL")); QDF_ASSERT(0); - qdf_spin_unlock_bh(&soc->ast_lock); return ret; } pdev = vdev->pdev; + tmp_peer = dp_peer_find_hash_find(soc, mac_addr, 0, + DP_VDEV_ALL); + if (tmp_peer) { + tmp_vdev = tmp_peer->vdev; + if (!tmp_vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Peers vdev is NULL")); + QDF_ASSERT(0); + dp_peer_unref_delete(tmp_peer); + return ret; + } + if (tmp_vdev->pdev->pdev_id == pdev->pdev_id) + is_peer_found = true; + + dp_peer_unref_delete(tmp_peer); + } + + qdf_spin_lock_bh(&soc->ast_lock); + if (peer->delete_in_progress) { + qdf_spin_unlock_bh(&soc->ast_lock); + return ret; + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s: pdevid: %u vdev: %u ast_entry->type: %d flags: 0x%x peer_mac: %pM peer: %pK mac %pM", + "%s: pdevid: %u vdev: %u ast_entry->type: %d flags: 0x%x peer_mac: "QDF_MAC_ADDR_FMT" peer: %pK mac "QDF_MAC_ADDR_FMT, __func__, pdev->pdev_id, vdev->vdev_id, type, flags, - peer->mac_addr.raw, peer, mac_addr); + QDF_MAC_ADDR_REF(peer->mac_addr.raw), peer, + QDF_MAC_ADDR_REF(mac_addr)); /* fw supports only 2 times the max_peers ast entries */ @@ -632,6 +677,17 @@ int dp_peer_add_ast(struct dp_soc *soc, qdf_spin_unlock_bh(&soc->ast_lock); return 0; } + if (is_peer_found) { + /* During WDS to static roaming, peer is added + * to the list before static AST entry create. + * So, allow AST entry for STATIC type + * even if peer is present + */ + if (type != CDP_TXRX_AST_TYPE_STATIC) { + qdf_spin_unlock_bh(&soc->ast_lock); + return 0; + } + } } else { /* For HWMWDS_SEC entries can be added for same mac address * do not check for existing entry @@ -660,8 +716,7 @@ int dp_peer_add_ast(struct dp_soc *soc, * can take care of adding HMWDS ast enty on delete * confirmation from target */ - if ((type == CDP_TXRX_AST_TYPE_WDS_HM) && - soc->is_peer_map_unmap_v2) { + if (type == CDP_TXRX_AST_TYPE_WDS_HM) { struct dp_ast_free_cb_params *param = NULL; if (ast_entry->type == @@ -709,8 +764,8 @@ int dp_peer_add_ast(struct dp_soc *soc, * packet from station to the root via the repeater * should not remove the wds entry. */ - if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS) && - (type == CDP_TXRX_AST_TYPE_MEC) && + else if ((type == CDP_TXRX_AST_TYPE_MEC) && + (ast_entry->type == CDP_TXRX_AST_TYPE_WDS) && (ast_entry->peer == peer)) { ast_entry->is_active = FALSE; dp_peer_del_ast(soc, ast_entry); @@ -719,7 +774,9 @@ int dp_peer_add_ast(struct dp_soc *soc, /* Call the saved callback*/ if (cb) { - cb(soc->ctrl_psoc, soc, cookie, + cb(soc->ctrl_psoc, + dp_soc_to_cdp_soc(soc), + cookie, CDP_TXRX_AST_DELETE_IN_PROGRESS); } return 0; @@ -740,7 +797,6 @@ int dp_peer_add_ast(struct dp_soc *soc, qdf_mem_copy(&ast_entry->mac_addr.raw[0], mac_addr, QDF_MAC_ADDR_SIZE); ast_entry->pdev_id = vdev->pdev->pdev_id; - ast_entry->vdev_id = vdev->vdev_id; ast_entry->is_mapped = false; ast_entry->delete_in_progress = false; @@ -801,11 +857,13 @@ int dp_peer_add_ast(struct dp_soc *soc, (ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC)) { if (QDF_STATUS_SUCCESS == soc->cdp_soc.ol_ops->peer_add_wds_entry( - peer->vdev->osif_vdev, - (struct cdp_peer *)peer, + soc->ctrl_psoc, + peer->vdev->vdev_id, + peer->mac_addr.raw, mac_addr, next_node_mac, - flags)) { + flags, + ast_entry->type)) { qdf_spin_unlock_bh(&soc->ast_lock); return 0; } @@ -815,6 +873,71 @@ int dp_peer_add_ast(struct dp_soc *soc, return ret; } +/* + * dp_peer_free_ast_entry() - Free up the ast entry memory + * @soc: SoC handle + * @ast_entry: Address search entry + * + * This API is used to free up the memory associated with + * AST entry. + * + * Return: None + */ +void dp_peer_free_ast_entry(struct dp_soc *soc, + struct dp_ast_entry *ast_entry) +{ + /* + * NOTE: Ensure that call to this API is done + * after soc->ast_lock is taken + */ + dp_debug("type: %d ast_idx: %u mac_addr: " QDF_MAC_ADDR_FMT, + ast_entry->type, ast_entry->ast_idx, + QDF_MAC_ADDR_REF(ast_entry->mac_addr.raw)); + + ast_entry->callback = NULL; + ast_entry->cookie = NULL; + + DP_STATS_INC(soc, ast.deleted, 1); + dp_peer_ast_hash_remove(soc, ast_entry); + dp_peer_ast_cleanup(soc, ast_entry); + qdf_mem_free(ast_entry); + soc->num_ast_entries--; +} + +/* + * dp_peer_unlink_ast_entry() - Free up the ast entry memory + * @soc: SoC handle + * @ast_entry: Address search entry + * + * This API is used to remove/unlink AST entry from the peer list + * and hash list. + * + * Return: None + */ +void dp_peer_unlink_ast_entry(struct dp_soc *soc, + struct dp_ast_entry *ast_entry) +{ + /* + * NOTE: Ensure that call to this API is done + * after soc->ast_lock is taken + */ + struct dp_peer *peer = ast_entry->peer; + + TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); + + if (ast_entry == peer->self_ast_entry) + peer->self_ast_entry = NULL; + + /* + * release the reference only if it is mapped + * to ast_table + */ + if (ast_entry->is_mapped) + soc->ast_table[ast_entry->ast_idx] = NULL; + + ast_entry->peer = NULL; +} + /* * dp_peer_del_ast() - Delete and free AST entry * @soc: SoC handle @@ -833,45 +956,44 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) if (!ast_entry) return; - peer = ast_entry->peer; + if (ast_entry->delete_in_progress) + return; + + dp_debug("call by %ps: ast_idx: %u mac_addr: " QDF_MAC_ADDR_FMT, + (void *)_RET_IP_, ast_entry->ast_idx, + QDF_MAC_ADDR_REF(ast_entry->mac_addr.raw)); + + ast_entry->delete_in_progress = true; + peer = ast_entry->peer; dp_peer_ast_send_wds_del(soc, ast_entry); - /* - * release the reference only if it is mapped - * to ast_table - */ + /* Remove SELF and STATIC entries in teardown itself */ + if (!ast_entry->next_hop) + dp_peer_unlink_ast_entry(soc, ast_entry); + if (ast_entry->is_mapped) soc->ast_table[ast_entry->ast_idx] = NULL; - /* - * if peer map v2 is enabled we are not freeing ast entry + /* if peer map v2 is enabled we are not freeing ast entry * here and it is supposed to be freed in unmap event (after * we receive delete confirmation from target) * * if peer_id is invalid we did not get the peer map event * for the peer free ast entry from here only in this case */ - if (soc->is_peer_map_unmap_v2) { - - /* - * For HM_SEC and SELF type we do not receive unmap event - * free ast_entry from here it self - */ - if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) && - (ast_entry->type != CDP_TXRX_AST_TYPE_SELF)) - return; - } + if (dp_peer_ast_free_in_unmap_supported(peer, ast_entry)) + return; - /* SELF and STATIC entries are removed in teardown itself */ - if (ast_entry->next_hop) - TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); + /* for WDS secondary entry ast_entry->next_hop would be set so + * unlinking has to be done explicitly here. + * As this entry is not a mapped entry unmap notification from + * FW wil not come. Hence unlinkling is done right here. + */ + if (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC) + dp_peer_unlink_ast_entry(soc, ast_entry); - DP_STATS_INC(soc, ast.deleted, 1); - dp_peer_ast_hash_remove(soc, ast_entry); - dp_peer_ast_cleanup(soc, ast_entry); - qdf_mem_free(ast_entry); - soc->num_ast_entries--; + dp_peer_free_ast_entry(soc, ast_entry); } /* @@ -895,12 +1017,19 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, struct dp_peer *old_peer; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s: ast_entry->type: %d pdevid: %u vdevid: %u flags: 0x%x mac_addr: %pM peer_mac: %pM\n", + "%s: ast_entry->type: %d pdevid: %u vdevid: %u flags: 0x%x mac_addr: "QDF_MAC_ADDR_FMT" peer_mac: "QDF_MAC_ADDR_FMT"\n", __func__, ast_entry->type, peer->vdev->pdev->pdev_id, - peer->vdev->vdev_id, flags, ast_entry->mac_addr.raw, - peer->mac_addr.raw); - - if (ast_entry->delete_in_progress) + peer->vdev->vdev_id, flags, + QDF_MAC_ADDR_REF(ast_entry->mac_addr.raw), + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); + + /* Do not send AST update in below cases + * 1) Ast entry delete has already triggered + * 2) Peer delete is already triggered + * 3) We did not get the HTT map for create event + */ + if (ast_entry->delete_in_progress || peer->delete_in_progress || + !ast_entry->is_mapped) return ret; if ((ast_entry->type == CDP_TXRX_AST_TYPE_STATIC) || @@ -914,7 +1043,7 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, */ if (qdf_unlikely(ast_entry->peer == peer) && (ast_entry->type == CDP_TXRX_AST_TYPE_WDS) && - (ast_entry->vdev_id == peer->vdev->vdev_id) && + (ast_entry->peer->vdev == peer->vdev) && (ast_entry->is_active)) return 0; @@ -924,12 +1053,12 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, ast_entry->peer = peer; ast_entry->type = CDP_TXRX_AST_TYPE_WDS; ast_entry->pdev_id = peer->vdev->pdev->pdev_id; - ast_entry->vdev_id = peer->vdev->vdev_id; ast_entry->is_active = TRUE; TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ase_list_elem); ret = soc->cdp_soc.ol_ops->peer_update_wds_entry( - peer->vdev->osif_vdev, + soc->ctrl_psoc, + peer->vdev->vdev_id, ast_entry->mac_addr.raw, peer->mac_addr.raw, flags); @@ -1062,35 +1191,39 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc, struct dp_peer *peer = ast_entry->peer; struct cdp_soc_t *cdp_soc = &soc->cdp_soc; - if (ast_entry->delete_in_progress) - return; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_TRACE, - "%s: ast_entry->type: %d pdevid: %u vdev: %u mac_addr: %pM next_hop: %u peer_mac: %pM\n", + "%s: ast_entry->type: %d pdevid: %u vdev: %u mac_addr: "QDF_MAC_ADDR_FMT" next_hop: %u peer_mac: "QDF_MAC_ADDR_FMT"\n", __func__, ast_entry->type, peer->vdev->pdev->pdev_id, - peer->vdev->vdev_id, ast_entry->mac_addr.raw, - ast_entry->next_hop, ast_entry->peer->mac_addr.raw); + peer->vdev->vdev_id, + QDF_MAC_ADDR_REF(ast_entry->mac_addr.raw), + ast_entry->next_hop, + QDF_MAC_ADDR_REF(ast_entry->peer->mac_addr.raw)); if (ast_entry->next_hop) { - cdp_soc->ol_ops->peer_del_wds_entry(peer->vdev->osif_vdev, + cdp_soc->ol_ops->peer_del_wds_entry(soc->ctrl_psoc, + peer->vdev->vdev_id, ast_entry->mac_addr.raw, ast_entry->type); } - /* Remove SELF and STATIC entries in teardown itself */ - if (!ast_entry->next_hop) { - TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); - peer->self_ast_entry = NULL; - ast_entry->peer = NULL; - } - - ast_entry->delete_in_progress = true; } -static void dp_peer_ast_free_entry(struct dp_soc *soc, - struct dp_ast_entry *ast_entry) +/** + * dp_peer_ast_free_entry_by_mac() - find ast entry by MAC address and delete + * @soc: soc handle + * @peer: peer handle + * @mac_addr: mac address of the AST entry to searc and delete + * + * find the ast entry from the peer list using the mac address and free + * the entry. + * + * Return: SUCCESS or NOENT + */ +static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc, + struct dp_peer *peer, + uint8_t *mac_addr) { - struct dp_peer *peer = ast_entry->peer; + struct dp_ast_entry *ast_entry; void *cookie = NULL; txrx_ast_free_cb cb = NULL; @@ -1100,31 +1233,32 @@ static void dp_peer_ast_free_entry(struct dp_soc *soc, */ qdf_spin_lock_bh(&soc->ast_lock); - if (ast_entry->is_mapped) - soc->ast_table[ast_entry->ast_idx] = NULL; - TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); - DP_STATS_INC(soc, ast.deleted, 1); - dp_peer_ast_hash_remove(soc, ast_entry); + ast_entry = dp_peer_ast_list_find(soc, peer, mac_addr); + if (!ast_entry) { + qdf_spin_unlock_bh(&soc->ast_lock); + return QDF_STATUS_E_NOENT; + } else if (ast_entry->is_mapped) { + soc->ast_table[ast_entry->ast_idx] = NULL; + } cb = ast_entry->callback; cookie = ast_entry->cookie; - ast_entry->callback = NULL; - ast_entry->cookie = NULL; - if (ast_entry == peer->self_ast_entry) - peer->self_ast_entry = NULL; + + dp_peer_unlink_ast_entry(soc, ast_entry); + dp_peer_free_ast_entry(soc, ast_entry); qdf_spin_unlock_bh(&soc->ast_lock); if (cb) { cb(soc->ctrl_psoc, - soc, + dp_soc_to_cdp_soc(soc), cookie, CDP_TXRX_AST_DELETED); } - qdf_mem_free(ast_entry); - soc->num_ast_entries--; + + return QDF_STATUS_SUCCESS; } struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, @@ -1145,16 +1279,9 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, index = dp_peer_find_hash_index(soc, mac_addr); qdf_spin_lock_bh(&soc->peer_ref_mutex); TAILQ_FOREACH(peer, &soc->peer_hash.bins[index], hash_list_elem) { -#if ATH_SUPPORT_WRAP - /* ProxySTA may have multiple BSS peer with same MAC address, - * modified find will take care of finding the correct BSS peer. - */ if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && ((peer->vdev->vdev_id == vdev_id) || (vdev_id == DP_VDEV_ALL))) { -#else - if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) { -#endif /* found it - increment the ref count before releasing * the lock */ @@ -1286,6 +1413,9 @@ void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt, struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; struct hal_reo_queue_status *queue_status = &(reo_status->queue_status); + if (queue_status->header.status == HAL_REO_CMD_DRAIN) + return; + if (queue_status->header.status != HAL_REO_CMD_SUCCESS) { DP_PRINT_STATS("REO stats failure %d for TID %d\n", queue_status->header.status, rx_tid->tid); @@ -1383,10 +1513,9 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc, peer = dp_peer_find_hash_find(soc, peer_mac_addr, 0 /* is aligned */, vdev_id); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: peer %pK ID %d vid %d mac %02x:%02x:%02x:%02x:%02x:%02x", - __func__, peer, peer_id, vdev_id, peer_mac_addr[0], - peer_mac_addr[1], peer_mac_addr[2], peer_mac_addr[3], - peer_mac_addr[4], peer_mac_addr[5]); + "%s: peer %pK ID %d vid %d mac "QDF_MAC_ADDR_FMT, + __func__, peer, peer_id, vdev_id, + QDF_MAC_ADDR_REF(peer_mac_addr)); if (peer) { /* peer's ref count was already incremented by @@ -1432,33 +1561,64 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc, */ void -dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, +dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint16_t hw_peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr, uint16_t ast_hash, uint8_t is_wds) { - struct dp_soc *soc = (struct dp_soc *)soc_handle; struct dp_peer *peer = NULL; enum cdp_txrx_ast_entry_type type = CDP_TXRX_AST_TYPE_STATIC; - dp_info("peer_map_event (soc:%pK): peer_id %d, hw_peer_id %d, peer_mac %02x:%02x:%02x:%02x:%02x:%02x, vdev_id %d", - soc, peer_id, hw_peer_id, peer_mac_addr[0], peer_mac_addr[1], - peer_mac_addr[2], peer_mac_addr[3], peer_mac_addr[4], - peer_mac_addr[5], vdev_id); - - if ((hw_peer_id < 0) || - (hw_peer_id >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "invalid hw_peer_id: %d", hw_peer_id); - qdf_assert_always(0); - } + dp_info("peer_map_event (soc:%pK): peer_id %d, hw_peer_id %d, peer_mac "QDF_MAC_ADDR_FMT", vdev_id %d", + soc, peer_id, hw_peer_id, + QDF_MAC_ADDR_REF(peer_mac_addr), vdev_id); /* Peer map event for WDS ast entry get the peer from * obj map */ if (is_wds) { peer = soc->peer_id_to_obj_map[peer_id]; + /* + * In certain cases like Auth attack on a repeater + * can result in the number of ast_entries falling + * in the same hash bucket to exceed the max_skid + * length supported by HW in root AP. In these cases + * the FW will return the hw_peer_id (ast_index) as + * 0xffff indicating HW could not add the entry in + * its table. Host has to delete the entry from its + * table in these cases. + */ + if (hw_peer_id == HTT_INVALID_PEER) { + DP_STATS_INC(soc, ast.map_err, 1); + if (!dp_peer_ast_free_entry_by_mac(soc, + peer, + peer_mac_addr)) + return; + + dp_alert("AST entry not found with peer %pK peer_id %u peer_mac "QDF_MAC_ADDR_FMT" mac_addr "QDF_MAC_ADDR_FMT" vdev_id %u next_hop %u", + peer, peer->peer_ids[0], + QDF_MAC_ADDR_REF(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(peer_mac_addr), vdev_id, + is_wds); + + return; + } + } else { + /* + * It's the responsibility of the CP and FW to ensure + * that peer is created successfully. Ideally DP should + * not hit the below condition for directly assocaited + * peers. + */ + if ((hw_peer_id < 0) || + (hw_peer_id >= + wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "invalid hw_peer_id: %d", hw_peer_id); + qdf_assert_always(0); + } + peer = dp_peer_find_add_id(soc, peer_mac_addr, peer_id, hw_peer_id, vdev_id); @@ -1475,8 +1635,10 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, QDF_MAC_ADDR_SIZE); } - if (peer->vdev->opmode == wlan_op_mode_sta) + if (peer->vdev->opmode == wlan_op_mode_sta) { peer->vdev->bss_ast_hash = ast_hash; + peer->vdev->bss_ast_idx = hw_peer_id; + } /* Add ast entry incase self ast entry is * deleted due to DP CP sync issue @@ -1487,8 +1649,8 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, * referring it */ if (!peer->self_ast_entry) { - dp_info("Add self ast from map %pM", - peer_mac_addr); + dp_info("Add self ast from map "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac_addr)); dp_peer_add_ast(soc, peer, peer_mac_addr, type, 0); @@ -1511,13 +1673,11 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, * Return: none */ void -dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id, +dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t vdev_id, uint8_t *mac_addr, uint8_t is_wds) { struct dp_peer *peer; - struct dp_ast_entry *ast_entry; - struct dp_soc *soc = (struct dp_soc *)soc_handle; uint8_t i; peer = __dp_peer_find_by_id(soc, peer_id); @@ -1534,21 +1694,14 @@ dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id, /* If V2 Peer map messages are enabled AST entry has to be freed here */ - if (soc->is_peer_map_unmap_v2 && is_wds) { - - qdf_spin_lock_bh(&soc->ast_lock); - ast_entry = dp_peer_ast_list_find(soc, peer, - mac_addr); - qdf_spin_unlock_bh(&soc->ast_lock); - - if (ast_entry) { - dp_peer_ast_free_entry(soc, ast_entry); + if (is_wds) { + if (!dp_peer_ast_free_entry_by_mac(soc, peer, mac_addr)) return; - } - dp_alert("AST entry not found with peer %pK peer_id %u peer_mac %pM mac_addr %pM vdev_id %u next_hop %u", + dp_alert("AST entry not found with peer %pK peer_id %u peer_mac "QDF_MAC_ADDR_FMT" mac_addr "QDF_MAC_ADDR_FMT" vdev_id %u next_hop %u", peer, peer->peer_ids[0], - peer->mac_addr.raw, mac_addr, vdev_id, + QDF_MAC_ADDR_REF(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(mac_addr), vdev_id, is_wds); return; @@ -1565,6 +1718,11 @@ dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id, } } + /* + * Reset ast flow mapping table + */ + dp_peer_reset_flowq_map(peer); + if (soc->cdp_soc.ol_ops->peer_unmap_event) { soc->cdp_soc.ol_ops->peer_unmap_event(soc->ctrl_psoc, peer_id, vdev_id); @@ -1608,12 +1766,10 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt, * dp_find_peer_by_addr - find peer instance by mac address * @dev: physical device instance * @peer_mac_addr: peer mac address - * @local_id: local id for the peer * * Return: peer instance pointer */ -void *dp_find_peer_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr, - uint8_t *local_id) +void *dp_find_peer_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr) { struct dp_pdev *pdev = (struct dp_pdev *)dev; struct dp_peer *peer; @@ -1623,9 +1779,8 @@ void *dp_find_peer_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr, if (!peer) return NULL; - /* Multiple peer ids? How can know peer id? */ - *local_id = peer->local_id; - dp_verbose_debug("peer %pK id %d", peer, *local_id); + dp_verbose_debug("peer %pK mac: "QDF_MAC_ADDR_FMT, peer, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. @@ -1640,20 +1795,23 @@ static bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer) struct ol_if_ops *ol_ops = NULL; bool is_roaming = false; uint8_t vdev_id = -1; + struct cdp_soc_t *soc; if (!peer) { dp_info("Peer is NULL. No roaming possible"); return false; } + + soc = dp_soc_to_cdp_soc_t(peer->vdev->pdev->soc); ol_ops = peer->vdev->pdev->soc->cdp_soc.ol_ops; if (ol_ops && ol_ops->is_roam_inprogress) { - dp_get_vdevid(peer, &vdev_id); + dp_get_vdevid(soc, peer->mac_addr.raw, &vdev_id); is_roaming = ol_ops->is_roam_inprogress(vdev_id); } - dp_info("peer: %pM, vdev_id: %d, is_roaming: %d", - peer->mac_addr.raw, vdev_id, is_roaming); + dp_info("peer: "QDF_MAC_ADDR_FMT", vdev_id: %d, is_roaming: %d", + QDF_MAC_ADDR_REF(peer->mac_addr.raw), vdev_id, is_roaming); return is_roaming; } @@ -1676,9 +1834,10 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t if (start_seq < IEEE80211_SEQ_MAX) { params.u.upd_queue_params.update_ssn = 1; params.u.upd_queue_params.ssn = start_seq; + } else { + dp_set_ssn_valid_flag(¶ms, 0); } - dp_set_ssn_valid_flag(¶ms, 0); if (dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, ¶ms, dp_rx_tid_update_cb, rx_tid)) { dp_err_log("failed to send reo cmd CMD_UPDATE_RX_REO_QUEUE"); @@ -1692,7 +1851,7 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup( - peer->vdev->pdev->ctrl_pdev, + soc->ctrl_psoc, peer->vdev->pdev->pdev_id, peer->vdev->vdev_id, peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid, 1, ba_window_size); @@ -1737,7 +1896,7 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, qdf_mem_free(freedesc); } -#if defined(QCA_WIFI_QCA8074_VP) && defined(BUILD_X86) +#if defined(CONFIG_WIFI_EMULATION_WIFI_3_0) && defined(BUILD_X86) /* Hawkeye emulation requires bus address to be >= 0x50000000 */ static inline int dp_reo_desc_addr_chk(qdf_dma_addr_t dma_addr) { @@ -1856,6 +2015,7 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, } else { hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned; } + rx_tid->hw_qdesc_vaddr_aligned = hw_qdesc_vaddr; /* TODO: Ensure that sec_type is set before ADDBA is received. * Currently this is set based on htt indication @@ -1909,7 +2069,9 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) { if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup( - vdev->pdev->ctrl_pdev, peer->vdev->vdev_id, + soc->ctrl_psoc, + peer->vdev->pdev->pdev_id, + peer->vdev->vdev_id, peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid, 1, ba_window_size)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -2010,10 +2172,13 @@ static inline void dp_reo_limit_clean_batch_sz(uint32_t *list_size) * @desc: desc with resend update cmd flag set * @rx_tid: Desc RX tid associated with update cmd for resetting * valid field to 0 in h/w + * + * Return: QDF status */ -static void dp_resend_update_reo_cmd(struct dp_soc *soc, - struct reo_desc_list_node *desc, - struct dp_rx_tid *rx_tid) +static QDF_STATUS +dp_resend_update_reo_cmd(struct dp_soc *soc, + struct reo_desc_list_node *desc, + struct dp_rx_tid *rx_tid) { struct hal_reo_cmd_params params; @@ -2042,7 +2207,10 @@ static void dp_resend_update_reo_cmd(struct dp_soc *soc, (qdf_list_node_t *)desc); dp_err_log("failed to send reo cmd CMD_UPDATE_RX_REO_QUEUE"); DP_STATS_INC(soc, rx.err.reo_cmd_send_fail, 1); + return QDF_STATUS_E_FAILURE; } + + return QDF_STATUS_SUCCESS; } /* @@ -2063,6 +2231,7 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, unsigned long curr_ts = qdf_get_system_timestamp(); uint32_t desc_size, tot_desc_size; struct hal_reo_cmd_params params; + bool flush_failure = false; if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) { qdf_mem_zero(reo_status, sizeof(*reo_status)); @@ -2073,11 +2242,10 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, } else if (reo_status->rx_queue_status.header.status != HAL_REO_CMD_SUCCESS) { /* Should not happen normally. Just print error for now */ - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Rx tid HW desc deletion failed(%d): tid %d", - __func__, - reo_status->rx_queue_status.header.status, - freedesc->rx_tid.tid); + dp_info_rl("%s: Rx tid HW desc deletion failed(%d): tid %d", + __func__, + reo_status->rx_queue_status.header.status, + freedesc->rx_tid.tid); } QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, @@ -2112,13 +2280,19 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, /* First process descs with resend_update_reo_cmd set */ if (desc->resend_update_reo_cmd) { - dp_resend_update_reo_cmd(soc, desc, rx_tid); - continue; + if (dp_resend_update_reo_cmd(soc, desc, rx_tid) != + QDF_STATUS_SUCCESS) + break; + else + continue; } /* Flush and invalidate REO descriptor from HW cache: Base and * extension descriptors should be flushed separately */ - tot_desc_size = rx_tid->hw_qdesc_alloc_size; + if (desc->pending_ext_desc_size) + tot_desc_size = desc->pending_ext_desc_size; + else + tot_desc_size = rx_tid->hw_qdesc_alloc_size; /* Get base descriptor size by passing non-qos TID */ desc_size = hal_get_reo_qdesc_size(soc->hal_soc, 0, DP_NON_QOS_TID); @@ -2137,13 +2311,22 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, ¶ms, NULL, NULL)) { - dp_err_rl("fail to send CMD_CACHE_FLUSH:" - "tid %d desc %pK", rx_tid->tid, - (void *)(rx_tid->hw_qdesc_paddr)); - DP_STATS_INC(soc, rx.err.reo_cmd_send_fail, 1); + dp_info_rl("fail to send CMD_CACHE_FLUSH:" + "tid %d desc %pK", rx_tid->tid, + (void *)(rx_tid->hw_qdesc_paddr)); + desc->pending_ext_desc_size = tot_desc_size + + desc_size; + dp_reo_desc_clean_up(soc, desc, reo_status); + flush_failure = true; + break; } } + if (flush_failure) + break; + else + desc->pending_ext_desc_size = desc_size; + /* Flush base descriptor */ qdf_mem_zero(¶ms, sizeof(params)); params.std.need_status = 1; @@ -2167,10 +2350,11 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, * In case of MCL path add the desc back to the free * desc list and defer deletion. */ - dp_err_log("%s: fail to send REO cmd to flush cache: tid %d", + dp_info_rl("%s: fail to send REO cmd to flush cache: tid %d", __func__, rx_tid->tid); dp_reo_desc_clean_up(soc, desc, &reo_status); DP_STATS_INC(soc, rx.err.reo_cmd_send_fail, 1); + break; } } qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock); @@ -2382,7 +2566,8 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer, bool reuse) } #ifdef notyet /* See if FW can remove queues as part of peer cleanup */ if (soc->ol_ops->peer_rx_reorder_queue_remove) { - soc->ol_ops->peer_rx_reorder_queue_remove(vdev->pdev->ctrl_pdev, + soc->ol_ops->peer_rx_reorder_queue_remove(soc->ctrl_psoc, + peer->vdev->pdev->pdev_id, peer->vdev->vdev_id, peer->mac_addr.raw, tid_delete_mask); } @@ -2392,6 +2577,32 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer, bool reuse) qdf_spinlock_destroy(&peer->rx_tid[tid].tid_lock); } +#ifdef FEATURE_PERPKT_INFO +/* + * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer + * @peer: Datapath peer + * + * return: void + */ +void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer) +{ + qdf_mem_zero(&peer->delayed_ba_ppdu_stats, + sizeof(struct cdp_delayed_tx_completion_ppdu_user)); + peer->last_delayed_ba = false; + peer->last_delayed_ba_ppduid = 0; +} +#else +/* + * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer + * @peer: Datapath peer + * + * return: void + */ +void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer) +{ +} +#endif + /* * dp_peer_cleanup() – Cleanup peer information * @vdev: Datapath vdev @@ -2448,11 +2659,10 @@ static void dp_teardown_256_ba_sessions(struct dp_peer *peer) qdf_spin_unlock_bh(&rx_tid->tid_lock); if (peer->vdev->pdev->soc->cdp_soc.ol_ops->send_delba) peer->vdev->pdev->soc->cdp_soc.ol_ops->send_delba( - peer->vdev->pdev->ctrl_pdev, - peer->ctrl_peer, - peer->mac_addr.raw, - tid, peer->vdev->ctrl_vdev, - delba_rcode); + peer->vdev->pdev->soc->ctrl_psoc, + peer->vdev->vdev_id, + peer->mac_addr.raw, + tid, delba_rcode); } else { qdf_spin_unlock_bh(&rx_tid->tid_lock); } @@ -2466,21 +2676,26 @@ static void dp_teardown_256_ba_sessions(struct dp_peer *peer) /* * dp_rx_addba_resp_tx_completion_wifi3() – Update Rx Tid State * -* @peer: Datapath peer handle +* @soc: Datapath soc handle +* @peer_mac: Datapath peer mac address +* @vdev_id: id of atapath vdev * @tid: TID number * @status: tx completion status * Return: 0 on success, error code on failure */ -int dp_addba_resp_tx_completion_wifi3(void *peer_handle, +int dp_addba_resp_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); struct dp_rx_tid *rx_tid = NULL; if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s: Peer is NULL!\n", __func__); - return QDF_STATUS_E_FAILURE; + goto fail; } rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); @@ -2491,7 +2706,8 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle, rx_tid->ba_status = DP_RX_BA_INACTIVE; qdf_spin_unlock_bh(&rx_tid->tid_lock); dp_err("RxTid- %d addba rsp tx completion failed", tid); - return QDF_STATUS_SUCCESS; + + goto success; } rx_tid->num_addba_rsp_success++; @@ -2500,15 +2716,15 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "%s: Rx Tid- %d hw qdesc is not in IN_PROGRESS", __func__, tid); - return QDF_STATUS_E_FAILURE; + goto fail; } if (!qdf_atomic_read(&peer->is_default_route_set)) { qdf_spin_unlock_bh(&rx_tid->tid_lock); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s: default route is not set for peer: %pM", - __func__, peer->mac_addr.raw); - return QDF_STATUS_E_FAILURE; + "%s: default route is not set for peer: "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); + goto fail; } if (dp_rx_tid_update_wifi3(peer, tid, @@ -2543,30 +2759,46 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle, dp_teardown_256_ba_sessions(peer); peer->kill_256_sessions = 0; } + +success: + dp_peer_unref_delete(peer); return QDF_STATUS_SUCCESS; + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return QDF_STATUS_E_FAILURE; } /* * dp_rx_addba_responsesetup_wifi3() – Process ADDBA request from peer * -* @peer: Datapath peer handle +* @soc: Datapath soc handle +* @peer_mac: Datapath peer mac address +* @vdev_id: id of atapath vdev * @tid: TID number * @dialogtoken: output dialogtoken * @statuscode: output dialogtoken * @buffersize: Output BA window size * @batimeout: Output BA timeout */ -void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid, - uint8_t *dialogtoken, uint16_t *statuscode, - uint16_t *buffersize, uint16_t *batimeout) +QDF_STATUS +dp_addba_responsesetup_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, + uint8_t *dialogtoken, uint16_t *statuscode, + uint16_t *buffersize, uint16_t *batimeout) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; struct dp_rx_tid *rx_tid = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s: Peer is NULL!\n", __func__); - return; + status = QDF_STATUS_E_FAILURE; + goto fail; } rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); @@ -2577,6 +2809,12 @@ void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid, *buffersize = rx_tid->ba_win_size; *batimeout = 0; qdf_spin_unlock_bh(&rx_tid->tid_lock); + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* dp_check_ba_buffersize() - Check buffer size in request @@ -2626,7 +2864,9 @@ static void dp_check_ba_buffersize(struct dp_peer *peer, /* * dp_addba_requestprocess_wifi3() - Process ADDBA request from peer * - * @peer: Datapath peer handle + * @soc: Datapath soc handle + * @peer_mac: Datapath peer mac address + * @vdev_id: id of atapath vdev * @dialogtoken: dialogtoken from ADDBA frame * @tid: TID number * @batimeout: BA timeout @@ -2635,19 +2875,25 @@ static void dp_check_ba_buffersize(struct dp_peer *peer, * * Return: 0 on success, error code on failure */ -int dp_addba_requestprocess_wifi3(void *peer_handle, +int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc, + uint8_t *peer_mac, + uint16_t vdev_id, uint8_t dialogtoken, uint16_t tid, uint16_t batimeout, uint16_t buffersize, uint16_t startseqnum) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + QDF_STATUS status = QDF_STATUS_SUCCESS; struct dp_rx_tid *rx_tid = NULL; + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct dp_peer *peer = dp_peer_find_hash_find(soc, + peer_mac, 0, vdev_id); if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s: Peer is NULL!\n", __func__); - return QDF_STATUS_E_FAILURE; + status = QDF_STATUS_E_FAILURE; + goto fail; } rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); @@ -2658,32 +2904,38 @@ int dp_addba_requestprocess_wifi3(void *peer_handle, rx_tid->ba_status = DP_RX_BA_INACTIVE; peer->active_ba_session_cnt--; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s: Addba recvd for Rx Tid-%d hw qdesc is already setup", - __func__, tid); + "%s: Rx Tid- %d hw qdesc is already setup", + __func__, tid); } if (rx_tid->ba_status == DP_RX_BA_IN_PROGRESS) { qdf_spin_unlock_bh(&rx_tid->tid_lock); - return QDF_STATUS_E_FAILURE; + status = QDF_STATUS_E_FAILURE; + goto fail; + } + + if (wlan_cfg_is_dp_force_rx_64_ba(soc->wlan_cfg_ctx)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "force use BA64 scheme"); + buffersize = qdf_min((uint16_t)64, buffersize); } if (rx_tid->rx_ba_win_size_override == DP_RX_BA_SESSION_DISABLE) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s disable BA session by refuse addba req", - __func__); + "%s disable BA session", + __func__); buffersize = 1; } else if (rx_tid->rx_ba_win_size_override) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s override BA win to %d", __func__, - rx_tid->rx_ba_win_size_override); + rx_tid->rx_ba_win_size_override); buffersize = rx_tid->rx_ba_win_size_override; } else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "%s restore BA win %d based on addba req", - __func__, buffersize); - + __func__, buffersize); } dp_check_ba_buffersize(peer, tid, buffersize); @@ -2692,7 +2944,8 @@ int dp_addba_requestprocess_wifi3(void *peer_handle, rx_tid->ba_win_size, startseqnum)) { rx_tid->ba_status = DP_RX_BA_INACTIVE; qdf_spin_unlock_bh(&rx_tid->tid_lock); - return QDF_STATUS_E_FAILURE; + status = QDF_STATUS_E_FAILURE; + goto fail; } rx_tid->ba_status = DP_RX_BA_IN_PROGRESS; @@ -2709,46 +2962,80 @@ int dp_addba_requestprocess_wifi3(void *peer_handle, qdf_spin_unlock_bh(&rx_tid->tid_lock); - return QDF_STATUS_SUCCESS; +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* * dp_set_addba_response() – Set a user defined ADDBA response status code * -* @peer: Datapath peer handle +* @soc: Datapath soc handle +* @peer_mac: Datapath peer mac address +* @vdev_id: id of atapath vdev * @tid: TID number * @statuscode: response status code to be set */ -void dp_set_addba_response(void *peer_handle, uint8_t tid, - uint16_t statuscode) +QDF_STATUS +dp_set_addba_response(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, uint16_t statuscode) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); + struct dp_rx_tid *rx_tid; + QDF_STATUS status = QDF_STATUS_SUCCESS; + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + goto fail; + } + + rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); rx_tid->userstatuscode = statuscode; qdf_spin_unlock_bh(&rx_tid->tid_lock); +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* * dp_rx_delba_process_wifi3() – Process DELBA from peer -* @peer: Datapath peer handle +* @soc: Datapath soc handle +* @peer_mac: Datapath peer mac address +* @vdev_id: id of atapath vdev * @tid: TID number * @reasoncode: Reason code received in DELBA frame * * Return: 0 on success, error code on failure */ -int dp_delba_process_wifi3(void *peer_handle, - int tid, uint16_t reasoncode) +int dp_delba_process_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, int tid, uint16_t reasoncode) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_rx_tid *rx_tid; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + goto fail; + } + rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); if (rx_tid->ba_status == DP_RX_BA_INACTIVE || rx_tid->ba_status == DP_RX_BA_IN_PROGRESS) { qdf_spin_unlock_bh(&rx_tid->tid_lock); - return QDF_STATUS_E_FAILURE; + status = QDF_STATUS_E_FAILURE; + goto fail; } /* TODO: See if we can delete the existing REO queue descriptor and * replace with a new one without queue extenstion descript to save @@ -2761,28 +3048,38 @@ int dp_delba_process_wifi3(void *peer_handle, rx_tid->ba_status = DP_RX_BA_INACTIVE; peer->active_ba_session_cnt--; qdf_spin_unlock_bh(&rx_tid->tid_lock); - return 0; +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /* * dp_rx_delba_tx_completion_wifi3() – Send Delba Request * - * @peer: Datapath peer handle + * @soc: Datapath soc handle + * @peer_mac: Datapath peer mac address + * @vdev_id: id of atapath vdev * @tid: TID number * @status: tx completion status * Return: 0 on success, error code on failure */ -int dp_delba_tx_completion_wifi3(void *peer_handle, +int dp_delba_tx_completion_wifi3(struct cdp_soc_t *cdp_soc, uint8_t *peer_mac, + uint16_t vdev_id, uint8_t tid, int status) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + QDF_STATUS ret = QDF_STATUS_SUCCESS; struct dp_rx_tid *rx_tid = NULL; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)cdp_soc, + peer_mac, 0, vdev_id); if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s: Peer is NULL!", __func__); - return QDF_STATUS_E_FAILURE; + ret = QDF_STATUS_E_FAILURE; + goto end; } rx_tid = &peer->rx_tid[tid]; qdf_spin_lock_bh(&rx_tid->tid_lock); @@ -2798,11 +3095,12 @@ int dp_delba_tx_completion_wifi3(void *peer_handle, qdf_spin_unlock_bh(&rx_tid->tid_lock); if (peer->vdev->pdev->soc->cdp_soc.ol_ops->send_delba) peer->vdev->pdev->soc->cdp_soc.ol_ops->send_delba( - peer->vdev->pdev->ctrl_pdev, peer->ctrl_peer, - peer->mac_addr.raw, tid, peer->vdev->ctrl_vdev, + peer->vdev->pdev->soc->ctrl_psoc, + peer->vdev->vdev_id, + peer->mac_addr.raw, tid, rx_tid->delba_rcode); } - return QDF_STATUS_SUCCESS; + goto end; } else { rx_tid->delba_tx_success_cnt++; rx_tid->delba_tx_retry = 0; @@ -2819,30 +3117,18 @@ int dp_delba_tx_completion_wifi3(void *peer_handle, } qdf_spin_unlock_bh(&rx_tid->tid_lock); - return QDF_STATUS_SUCCESS; -} - -void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer, unsigned tid, - qdf_nbuf_t msdu_list) -{ - while (msdu_list) { - qdf_nbuf_t msdu = msdu_list; +end: + if (peer) + dp_peer_unref_delete(peer); - msdu_list = qdf_nbuf_next(msdu_list); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "discard rx %pK from partly-deleted peer %pK (%02x:%02x:%02x:%02x:%02x:%02x)", - msdu, peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5]); - qdf_nbuf_free(msdu); - } + return ret; } - /** * dp_set_pn_check_wifi3() - enable PN check in REO for security - * @peer: Datapath peer handle + * @soc: Datapath soc handle + * @peer_mac: Datapath peer mac address + * @vdev_id: id of atapath vdev * @vdev: Datapath vdev * @pdev - data path device instance * @sec_type - security type @@ -2850,24 +3136,30 @@ void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer, unsigned tid, * */ -void -dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle, enum cdp_sec_type sec_type, uint32_t *rx_pn) +QDF_STATUS +dp_set_pn_check_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, + uint32_t *rx_pn) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; - struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev; - struct dp_soc *soc; int i; uint8_t pn_size; struct hal_reo_cmd_params params; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); - /* preconditions */ - qdf_assert(vdev); + if (!vdev || !peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + goto fail; + } pdev = vdev->pdev; - soc = pdev->soc; - - qdf_mem_zero(¶ms, sizeof(params)); params.std.need_status = 1; @@ -2929,13 +3221,15 @@ dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle params.u.upd_queue_params.pn_127_96 = rx_pn[3]; } rx_tid->pn_size = pn_size; - if (dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, + if (dp_reo_send_cmd(cdp_soc_t_to_dp_soc(soc), + CMD_UPDATE_RX_REO_QUEUE, ¶ms, dp_rx_tid_update_cb, rx_tid)) { dp_err_log("fail to send CMD_UPDATE_RX_REO_QUEUE" "tid %d desc %pK", rx_tid->tid, (void *)(rx_tid->hw_qdesc_paddr)); - DP_STATS_INC(soc, rx.err.reo_cmd_send_fail, 1); + DP_STATS_INC(cdp_soc_t_to_dp_soc(soc), + rx.err.reo_cmd_send_fail, 1); } } else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -2943,48 +3237,66 @@ dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle } qdf_spin_unlock_bh(&rx_tid->tid_lock); } +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } /** - * dp_set_key_sec_type_wifi3() - * @peer: Datapath peer handle + * dp_set_key_sec_type_wifi3() - set security mode of key + * @soc: Datapath soc handle + * @peer_mac: Datapath peer mac address + * @vdev_id: id of atapath vdev * @vdev: Datapath vdev * @pdev - data path device instance * @sec_type - security type - * @rx_pn - Receive pn starting number - * #is_unicast ucast/mcast key type + * #is_unicast - key type + * */ -void -dp_set_key_sec_type_wifi3(struct cdp_vdev *vdev_handle, - struct cdp_peer *peer_handle, - enum cdp_sec_type sec_type, +QDF_STATUS +dp_set_key_sec_type_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, enum cdp_sec_type sec_type, bool is_unicast) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); + QDF_STATUS status = QDF_STATUS_SUCCESS; int sec_index; + if (!peer || peer->delete_in_progress) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + status = QDF_STATUS_E_FAILURE; + goto fail; + } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "sec type for peer %pK (%02x:%02x:%02x:%02x:%02x:%02x): %s key of type %d", + "key sec spec for peer %pK "QDF_MAC_ADDR_FMT": %s key of type %d", peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5], + QDF_MAC_ADDR_REF(peer->mac_addr.raw), is_unicast ? "ucast" : "mcast", sec_type); sec_index = is_unicast ? dp_sec_ucast : dp_sec_mcast; peer->security[sec_index].sec_type = sec_type; -} +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; +} void -dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id, - enum cdp_sec_type sec_type, int is_unicast, u_int32_t *michael_key, - u_int32_t *rx_pn) +dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id, + enum cdp_sec_type sec_type, int is_unicast, + u_int32_t *michael_key, + u_int32_t *rx_pn) { - struct dp_soc *soc = (struct dp_soc *)soc_handle; struct dp_peer *peer; int sec_index; @@ -2996,11 +3308,9 @@ dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id, return; } QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "sec spec for peer %pK (%02x:%02x:%02x:%02x:%02x:%02x): %s key of type %d", + "sec spec for peer %pK "QDF_MAC_ADDR_FMT": %s key of type %d", peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5], + QDF_MAC_ADDR_REF(peer->mac_addr.raw), is_unicast ? "ucast" : "mcast", sec_type); sec_index = is_unicast ? dp_sec_ucast : dp_sec_mcast; @@ -3089,11 +3399,10 @@ dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id, if (soc->cdp_soc.ol_ops->send_delba) soc->cdp_soc.ol_ops->send_delba( - peer->vdev->pdev->ctrl_pdev, - peer->ctrl_peer, + peer->vdev->pdev->soc->ctrl_psoc, + peer->vdev->vdev_id, peer->mac_addr.raw, tid, - peer->vdev->ctrl_vdev, rx_tid->delba_rcode); } } else { @@ -3106,25 +3415,21 @@ dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id, return status; } -#ifdef CONFIG_MCL -/** - * dp_register_peer() - Register peer into physical device - * @pdev - data path device instance - * @sta_desc - peer description - * - * Register peer into physical device - * - * Return: QDF_STATUS_SUCCESS registration success - * QDF_STATUS_E_FAULT peer not found - */ -QDF_STATUS dp_register_peer(struct cdp_pdev *pdev_handle, - struct ol_txrx_desc_type *sta_desc) + +#ifdef DP_PEER_EXTENDED_API +QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct ol_txrx_desc_type *sta_desc) { struct dp_peer *peer; - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAULT; + + peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, + sta_desc->peer_addr.bytes); - peer = dp_peer_find_by_local_id((struct cdp_pdev *)pdev, - sta_desc->sta_id); if (!peer) return QDF_STATUS_E_FAULT; @@ -3137,29 +3442,22 @@ QDF_STATUS dp_register_peer(struct cdp_pdev *pdev_handle, return QDF_STATUS_SUCCESS; } -/** - * dp_clear_peer() - remove peer from physical device - * @pdev - data path device instance - * @sta_id - local peer id - * - * remove peer from physical device - * - * Return: QDF_STATUS_SUCCESS registration success - * QDF_STATUS_E_FAULT peer not found - */ -QDF_STATUS dp_clear_peer(struct cdp_pdev *pdev_handle, uint8_t local_id) +QDF_STATUS +dp_clear_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr) { struct dp_peer *peer; - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - struct dp_soc *soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAULT; - peer = dp_peer_find_by_local_id((struct cdp_pdev *)pdev, local_id); + peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, peer_addr.bytes); if (!peer || !peer->valid) return QDF_STATUS_E_FAULT; - soc = pdev->soc; dp_clear_peer_internal(soc, peer); - return QDF_STATUS_SUCCESS; } @@ -3168,7 +3466,6 @@ QDF_STATUS dp_clear_peer(struct cdp_pdev *pdev_handle, uint8_t local_id) * @pdev - data path device instance * @vdev - virtual interface instance * @peer_addr - peer mac address - * @peer_id - local peer id with target mac address * * Find peer by peer mac address within vdev * @@ -3177,13 +3474,13 @@ QDF_STATUS dp_clear_peer(struct cdp_pdev *pdev_handle, uint8_t local_id) */ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, struct cdp_vdev *vdev_handle, - uint8_t *peer_addr, uint8_t *local_id) + uint8_t *peer_addr) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_peer *peer; - peer = dp_peer_find_hash_find(pdev->soc, peer_addr, 0, 0); + peer = dp_peer_find_hash_find(pdev->soc, peer_addr, 0, DP_VDEV_ALL); if (!peer) return NULL; @@ -3193,8 +3490,6 @@ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, return NULL; } - *local_id = peer->local_id; - /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. */ @@ -3203,70 +3498,23 @@ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, return peer; } -/** - * dp_local_peer_id() - Find local peer id within peer instance - * @peer - peer instance - * - * Find local peer id within peer instance - * - * Return: local peer id - */ -uint16_t dp_local_peer_id(void *peer) -{ - return ((struct dp_peer *)peer)->local_id; -} - -/** - * dp_peer_find_by_local_id() - Find peer by local peer id - * @pdev - data path device instance - * @local_peer_id - local peer id want to find - * - * Find peer by local peer id within physical device - * - * Return: peer instance void pointer - * NULL cannot find target peer - */ -void *dp_peer_find_by_local_id(struct cdp_pdev *pdev_handle, uint8_t local_id) -{ - struct dp_peer *peer; - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; - - if (local_id >= OL_TXRX_NUM_LOCAL_PEER_IDS) { - QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_DP, - "Incorrect local id %u", local_id); - return NULL; - } - qdf_spin_lock_bh(&pdev->local_peer_ids.lock); - peer = pdev->local_peer_ids.map[local_id]; - qdf_spin_unlock_bh(&pdev->local_peer_ids.lock); - DP_TRACE(DEBUG, "peer %pK local id %d", peer, local_id); - return peer; -} - -/** - * dp_peer_state_update() - update peer local state - * @pdev - data path device instance - * @peer_addr - peer mac address - * @state - new peer local state - * - * update peer local state - * - * Return: QDF_STATUS_SUCCESS registration success - */ -QDF_STATUS dp_peer_state_update(struct cdp_pdev *pdev_handle, uint8_t *peer_mac, - enum ol_txrx_peer_state state) +QDF_STATUS dp_peer_state_update(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + enum ol_txrx_peer_state state) { struct dp_peer *peer; - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); - peer = dp_peer_find_hash_find(pdev->soc, peer_mac, 0, DP_VDEV_ALL); + peer = dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL); if (!peer) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Failed to find peer for: [%pM]", peer_mac); + "Failed to find peer for: ["QDF_MAC_ADDR_FMT"]", + QDF_MAC_ADDR_REF(peer_mac)); return QDF_STATUS_E_FAILURE; } peer->state = state; + peer->authorize = (state == OL_TXRX_PEER_STATE_AUTH) ? 1 : 0; + dp_info("peer %pK state %d", peer, peer->state); /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. @@ -3276,47 +3524,46 @@ QDF_STATUS dp_peer_state_update(struct cdp_pdev *pdev_handle, uint8_t *peer_mac, return QDF_STATUS_SUCCESS; } -/** - * dp_get_vdevid() - Get virtual interface id which peer registered - * @peer - peer instance - * @vdev_id - virtual interface id which peer registered - * - * Get virtual interface id which peer registered - * - * Return: QDF_STATUS_SUCCESS registration success - */ -QDF_STATUS dp_get_vdevid(void *peer_handle, uint8_t *vdev_id) +QDF_STATUS dp_get_vdevid(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t *vdev_id) { - struct dp_peer *peer = peer_handle; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_peer *peer = + dp_peer_find_hash_find(soc, peer_mac, 0, DP_VDEV_ALL); + + if (!peer) + return QDF_STATUS_E_FAILURE; dp_info("peer %pK vdev %pK vdev id %d", peer, peer->vdev, peer->vdev->vdev_id); *vdev_id = peer->vdev->vdev_id; + /* ref_cnt is incremented inside dp_peer_find_hash_find(). + * Decrement it here. + */ + dp_peer_unref_delete(peer); + return QDF_STATUS_SUCCESS; } -struct cdp_vdev *dp_get_vdev_by_sta_id(struct cdp_pdev *pdev_handle, - uint8_t sta_id) +struct cdp_vdev * +dp_get_vdev_by_peer_addr(struct cdp_pdev *pdev_handle, + struct qdf_mac_addr peer_addr) { struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; struct dp_peer *peer = NULL; - if (sta_id >= WLAN_MAX_STA_COUNT) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "Invalid sta id passed"); - return NULL; - } - if (!pdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "PDEV not found for sta_id [%d]", sta_id); + "PDEV not found for peer_addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr.bytes)); return NULL; } - peer = dp_peer_find_by_local_id((struct cdp_pdev *)pdev, sta_id); + peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, peer_addr.bytes); if (!peer) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - "PEER [%d] not found", sta_id); + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, + "PDEV not found for peer_addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr.bytes)); return NULL; } @@ -3360,20 +3607,22 @@ uint8_t *dp_peer_get_peer_mac_addr(void *peer_handle) return peer->mac_addr.raw; } -/** - * dp_get_peer_state() - Get local peer state - * @peer - peer instance - * - * Get local peer state - * - * Return: peer status - */ -int dp_get_peer_state(void *peer_handle) +int dp_get_peer_state(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) { - struct dp_peer *peer = peer_handle; + enum ol_txrx_peer_state peer_state; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 0, + vdev_id); + + if (!peer) + return QDF_STATUS_E_FAILURE; DP_TRACE(DEBUG, "peer %pK stats %d", peer, peer->state); - return peer->state; + peer_state = peer->state; + dp_peer_unref_delete(peer); + + return peer_state; } /** @@ -3457,40 +3706,60 @@ void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer) pdev->local_peer_ids.map[i] = NULL; qdf_spin_unlock_bh(&pdev->local_peer_ids.lock); } -#endif -/** - * dp_get_peer_mac_addr_frm_id(): get mac address of the peer - * @soc_handle: DP SOC handle - * @peer_id:peer_id of the peer - * - * return: vdev_id of the vap - */ -uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle, - uint16_t peer_id, uint8_t *peer_mac) +bool dp_find_peer_exist_on_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_addr) { - struct dp_soc *soc = (struct dp_soc *)soc_handle; - struct dp_peer *peer; - uint8_t vdev_id; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); - peer = dp_peer_find_by_id(soc, peer_id); + if (!vdev) + return false; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "soc %pK peer_id %d", soc, peer_id); + return !!dp_find_peer_by_addr_and_vdev( + dp_pdev_to_cdp_pdev(vdev->pdev), + dp_vdev_to_cdp_vdev(vdev), + peer_addr); +} - if (!peer) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "peer not found "); - return CDP_INVALID_VDEV_ID; +bool dp_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_addr, + uint16_t max_bssid) +{ + int i; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev; + + for (i = 0; i < max_bssid; i++) { + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, i); + /* Need to check vdevs other than the vdev_id */ + if (vdev_id == i || !vdev) + continue; + if (dp_find_peer_by_addr_and_vdev( + dp_pdev_to_cdp_pdev(vdev->pdev), + dp_vdev_to_cdp_vdev(vdev), + peer_addr)) { + dp_err("%s: Duplicate peer "QDF_MAC_ADDR_FMT" already exist on vdev %d", + __func__, QDF_MAC_ADDR_REF(peer_addr), i); + return true; + } } - qdf_mem_copy(peer_mac, peer->mac_addr.raw, 6); - vdev_id = peer->vdev->vdev_id; + return false; +} - dp_peer_unref_del_find_by_id(peer); +bool dp_find_peer_exist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t *peer_addr) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) + return false; - return vdev_id; + return !!dp_find_peer_by_addr(dp_pdev_to_cdp_pdev(pdev), peer_addr); } +#endif /** * dp_peer_rxtid_stats: Retried Rx TID (REO queue) stats from HW @@ -3500,7 +3769,8 @@ uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle, * * Return: count of tid stats cmd send succeeded */ -int dp_peer_rxtid_stats(struct dp_peer *peer, void (*dp_stats_cmd_cb), +int dp_peer_rxtid_stats(struct dp_peer *peer, + dp_rxtid_stats_cmd_cb dp_stats_cmd_cb, void *cb_ctxt) { struct dp_soc *soc = peer->vdev->pdev->soc; @@ -3554,20 +3824,32 @@ int dp_peer_rxtid_stats(struct dp_peer *peer, void (*dp_stats_cmd_cb), return stats_cmd_sent_cnt; } -void dp_set_michael_key(struct cdp_peer *peer_handle, - bool is_unicast, uint32_t *key) +QDF_STATUS +dp_set_michael_key(struct cdp_soc_t *soc, + uint8_t vdev_id, + uint8_t *peer_mac, + bool is_unicast, uint32_t *key) { - struct dp_peer *peer = (struct dp_peer *)peer_handle; + QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t sec_index = is_unicast ? 1 : 0; + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id); - if (!peer) { + if (!peer || peer->delete_in_progress) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "peer not found "); - return; + status = QDF_STATUS_E_FAILURE; + goto fail; } qdf_mem_copy(&peer->security[sec_index].michael_key[0], key, IEEE80211_WEP_MICLEN); + +fail: + if (peer) + dp_peer_unref_delete(peer); + + return status; } bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id) @@ -3586,3 +3868,112 @@ bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id) return false; } + +void dp_peer_flush_frags(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac, 0, + vdev_id); + struct dp_rx_tid *rx_tid; + uint8_t tid; + + if (!peer) + return; + + dp_info("Flushing fragments for peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); + + for (tid = 0; tid < DP_MAX_TIDS; tid++) { + rx_tid = &peer->rx_tid[tid]; + + qdf_spin_lock_bh(&rx_tid->tid_lock); + dp_rx_defrag_waitlist_remove(peer, tid); + dp_rx_reorder_flush_frag(peer, tid); + qdf_spin_unlock_bh(&rx_tid->tid_lock); + } + + dp_peer_unref_delete(peer); +} + +#ifdef DUMP_REO_QUEUE_INFO_IN_DDR +void dp_dump_rx_reo_queue_info( + struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status) +{ + struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; + + if (!rx_tid) + return; + + if (reo_status->fl_cache_status.header.status != + HAL_REO_CMD_SUCCESS) { + dp_err_rl("Rx tid REO HW desc flush failed(%d)", + reo_status->rx_queue_status.header.status); + return; + } + qdf_spin_lock_bh(&rx_tid->tid_lock); + hal_dump_rx_reo_queue_desc(rx_tid->hw_qdesc_vaddr_aligned); + qdf_spin_unlock_bh(&rx_tid->tid_lock); +} + +void dp_send_cache_flush_for_rx_tid( + struct dp_soc *soc, struct dp_peer *peer) +{ + int i; + struct dp_rx_tid *rx_tid; + struct hal_reo_cmd_params params; + + if (!peer) { + dp_err_rl("Peer is NULL"); + return; + } + + for (i = 0; i < DP_MAX_TIDS; i++) { + rx_tid = &peer->rx_tid[i]; + if (!rx_tid) + continue; + qdf_spin_lock_bh(&rx_tid->tid_lock); + if (rx_tid->hw_qdesc_vaddr_aligned) { + qdf_mem_zero(¶ms, sizeof(params)); + params.std.need_status = 1; + params.std.addr_lo = + rx_tid->hw_qdesc_paddr & 0xffffffff; + params.std.addr_hi = + (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; + params.u.fl_cache_params.flush_no_inval = 0; + if (QDF_STATUS_SUCCESS != + dp_reo_send_cmd( + soc, CMD_FLUSH_CACHE, + ¶ms, dp_dump_rx_reo_queue_info, + (void *)rx_tid)) { + dp_err_rl("cache flush send failed tid %d", + rx_tid->tid); + qdf_spin_unlock_bh(&rx_tid->tid_lock); + break; + } + } + qdf_spin_unlock_bh(&rx_tid->tid_lock); + } +} + +void dp_get_rx_reo_queue_info( + struct cdp_soc_t *soc_hdl, uint8_t vdev_id) +{ + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + struct dp_peer *peer = NULL; + + if (!vdev) { + dp_err_rl("vdev is null for vdev_id: %u", vdev_id); + return; + } + + peer = vdev->vap_bss_peer; + + if (!peer) { + dp_err_rl("Peer is NULL"); + return; + } + dp_send_cache_flush_for_rx_tid(soc, peer); +} +#endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h index 28e402b46f6c9b527669cc9f4a6c4d6240330ee2..4992673a76aa2c710da317ff746be7a01845362f 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,6 +23,10 @@ #include #include "dp_types.h" +#ifdef DUMP_REO_QUEUE_INFO_IN_DDR +#include "hal_reo.h" +#endif + #define DP_INVALID_PEER_ID 0xffff #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 @@ -115,16 +120,16 @@ dp_clear_peer_internal(struct dp_soc *soc, struct dp_peer *peer) } void dp_print_ast_stats(struct dp_soc *soc); -void dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, +void dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint16_t hw_peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr, uint16_t ast_hash, uint8_t is_wds); -void dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id, +void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr, uint8_t is_wds); -void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id, - enum cdp_sec_type sec_type, int is_unicast, - u_int32_t *michael_key, u_int32_t *rx_pn); +void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id, + enum cdp_sec_type sec_type, int is_unicast, + u_int32_t *michael_key, u_int32_t *rx_pn); QDF_STATUS dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id, uint8_t tid, uint16_t win_sz); @@ -169,14 +174,20 @@ void dp_peer_ast_set_type(struct dp_soc *soc, void dp_peer_ast_send_wds_del(struct dp_soc *soc, struct dp_ast_entry *ast_entry); -void dp_peer_free_hmwds_cb(void *ctrl_psoc, - void *dp_soc, +void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct cdp_soc *dp_soc, void *cookie, enum cdp_ast_free_status status); void dp_peer_ast_hash_remove(struct dp_soc *soc, struct dp_ast_entry *ase); +void dp_peer_free_ast_entry(struct dp_soc *soc, + struct dp_ast_entry *ast_entry); + +void dp_peer_unlink_ast_entry(struct dp_soc *soc, + struct dp_ast_entry *ast_entry); + /* * dp_peer_find_by_id_exist - check if peer exists for given id * @soc: core DP soc context @@ -204,6 +215,123 @@ void dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, uint32_t *tag_buf); +#ifndef QCA_MULTIPASS_SUPPORT +/** + * dp_peer_set_vlan_id: set vlan_id for this peer + * @cdp_soc: soc handle + * @vdev_id: id of vdev object + * @peer_mac: mac address + * @vlan_id: vlan id for peer + * + * return: void + */ +static inline +void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, uint8_t *peer_mac, + uint16_t vlan_id) +{ +} + +/** + * dp_set_vlan_groupkey: set vlan map for vdev + * @soc: pointer to soc + * @vdev_id: id of vdev handle + * @vlan_id: vlan_id + * @group_key: group key for vlan + * + * return: set success/failure + */ +static inline +QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id, + uint16_t vlan_id, uint16_t group_key) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * dp_peer_multipass_list_init: initialize multipass peer list + * @vdev: pointer to vdev + * + * return: void + */ +static inline +void dp_peer_multipass_list_init(struct dp_vdev *vdev) +{ +} + +/** + * dp_peer_multipass_list_remove: remove peer from special peer list + * @peer: peer handle + * + * return: void + */ +static inline +void dp_peer_multipass_list_remove(struct dp_peer *peer) +{ +} +#else +void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc, + uint8_t vdev_id, uint8_t *peer_mac, + uint16_t vlan_id); +QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id, + uint16_t vlan_id, uint16_t group_key); +void dp_peer_multipass_list_init(struct dp_vdev *vdev); +void dp_peer_multipass_list_remove(struct dp_peer *peer); +#endif + + +#ifndef QCA_PEER_MULTIQ_SUPPORT +/** + * dp_peer_reset_flowq_map() - reset peer flowq map table + * @peer - dp peer handle + * + * Return: none + */ +static inline +void dp_peer_reset_flowq_map(struct dp_peer *peer) +{ +} + +/** + * dp_peer_ast_index_flow_queue_map_create() - create ast index flow queue map + * @soc - genereic soc handle + * @is_wds - flag to indicate if peer is wds + * @peer_id - peer_id from htt peer map message + * @peer_mac_addr - mac address of the peer + * @ast_info - ast flow override information from peer map + * + * Return: none + */ +static inline +void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl, + bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr, + struct dp_ast_flow_override_info *ast_info) +{ +} +#else +void dp_peer_reset_flowq_map(struct dp_peer *peer); +void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl, + bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr, + struct dp_ast_flow_override_info *ast_info); +#endif + +/** + * dp_peer_update_pkt_capture_params: Set Rx & Tx Capture flags for a peer + * @soc: DP SOC handle + * @pdev_id: id of DP pdev handle + * @is_rx_pkt_cap_enable: enable/disable Rx packet capture in monitor mode + * @is_tx_pkt_cap_enable: enable/disable Tx packet capture in monitor mode + * @peer_mac: MAC address for which the above need to be enabled/disabled + * + * Return: Success if Rx & Tx capture is enabled for peer, false otherwise + */ +QDF_STATUS +dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool is_rx_pkt_cap_enable, + bool is_tx_pkt_cap_enable, + uint8_t *peer_mac); + /* * dp_rx_tid_delete_cb() - Callback to flush reo descriptor HW cache * after deleting the entries (ie., setting valid=0) @@ -215,4 +343,55 @@ dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); + +#ifdef DUMP_REO_QUEUE_INFO_IN_DDR +/** + * dp_send_cache_flush_for_rx_tid() - Send cache flush cmd to REO per tid + * @soc : dp_soc handle + * @peer: peer + * + * This function is used to send cache flush cmd to reo and + * to register the callback to handle the dumping of the reo + * queue stas from DDR + * + * Return: none + */ +void dp_send_cache_flush_for_rx_tid( + struct dp_soc *soc, struct dp_peer *peer); + +/** + * dp_get_rx_reo_queue_info() - Handler to get rx tid info + * @soc : cdp_soc_t handle + * @vdev_id: vdev id + * + * Handler to get rx tid info from DDR after h/w cache is + * invalidated first using the cache flush cmd. + * + * Return: none + */ +void dp_get_rx_reo_queue_info( + struct cdp_soc_t *soc_hdl, uint8_t vdev_id); + +/** + * dp_dump_rx_reo_queue_info() - Callback function to dump reo queue stats + * @soc : dp_soc handle + * @cb_ctxt - callback context + * @reo_status: vdev id + * + * This is the callback function registered after sending the reo cmd + * to flush the h/w cache and invalidate it. In the callback the reo + * queue desc info is dumped from DDR. + * + * Return: none + */ +void dp_dump_rx_reo_queue_info( + struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status); + +#else /* DUMP_REO_QUEUE_INFO_IN_DDR */ + +static inline void dp_get_rx_reo_queue_info( + struct cdp_soc_t *soc_hdl, uint8_t vdev_id) +{ +} +#endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ #endif /* _DP_PEER_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c index 0b490131f6cb0de059cb0421ba716661439a4173..352c8fd3db4d5483a995a9bc21209908fbbd1c76 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c @@ -61,8 +61,20 @@ QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, enum hal_reo_cmd_type type, struct hal_reo_cmd_params *params, void (*callback_fn), void *data) { - struct dp_reo_cmd_info *reo_cmd; + struct dp_reo_cmd_info *reo_cmd = NULL; int num; + QDF_STATUS ret; + + if (callback_fn) { + reo_cmd = qdf_mem_malloc(sizeof(*reo_cmd)); + if (!reo_cmd) { + dp_err_log("alloc failed for REO cmd:%d!!", + type); + ret = QDF_STATUS_E_NOMEM; + goto fail; + } + qdf_spin_lock_bh(&soc->rx.reo_cmd_lock); + } switch (type) { case CMD_GET_QUEUE_STATS: @@ -91,34 +103,36 @@ QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, enum hal_reo_cmd_type type, break; default: dp_err_log("Invalid REO command type: %d", type); - return QDF_STATUS_E_INVAL; + ret = QDF_STATUS_E_INVAL; + goto fail_unlock; }; dp_reo_cmd_srng_event_record(soc, type, num); if (num < 0) { - return QDF_STATUS_E_FAILURE; + ret = QDF_STATUS_E_FAILURE; + goto fail_unlock; } if (callback_fn) { - reo_cmd = qdf_mem_malloc(sizeof(*reo_cmd)); - if (!reo_cmd) { - dp_err_log("alloc failed for REO cmd:%d!!", - type); - return QDF_STATUS_E_NOMEM; - } - reo_cmd->cmd = num; reo_cmd->cmd_type = type; reo_cmd->handler = callback_fn; reo_cmd->data = data; - qdf_spin_lock_bh(&soc->rx.reo_cmd_lock); TAILQ_INSERT_TAIL(&soc->rx.reo_cmd_list, reo_cmd, reo_cmd_list_elem); - qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock); + reo_cmd = NULL; } - return QDF_STATUS_SUCCESS; + ret = QDF_STATUS_SUCCESS; + +fail_unlock: + if (callback_fn) + qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock); +fail: + if (reo_cmd) + qdf_mem_free(reo_cmd); + return ret; } uint32_t dp_reo_status_ring_handler(struct dp_intr *int_ctx, struct dp_soc *soc) @@ -153,7 +167,7 @@ uint32_t dp_reo_status_ring_handler(struct dp_intr *int_ctx, struct dp_soc *soc) num = reo_status.fl_queue_status.header.cmd_num; break; case HAL_REO_FLUSH_CACHE_STATUS_TLV: - hal_reo_flush_cache_status(reo_desc, soc->hal_soc, + hal_reo_flush_cache_status(reo_desc, &reo_status.fl_cache_status, soc->hal_soc); num = reo_status.fl_cache_status.header.cmd_num; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c index 4a9420ecb57ea3b85b65f05ad44bc273dab56fb2..b4107090a023c528abfc52e113c8c694e5a2fbe2 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -58,25 +58,16 @@ bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf) return true; } #endif - -#ifdef CONFIG_MCL -static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev) -{ - if (vdev->opmode != wlan_op_mode_sta) - return true; - else - return false; -} -#else static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev) { return vdev->ap_bridge_enabled; } -#endif #ifdef DUP_RX_DESC_WAR -void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring, - void *ring_desc, struct dp_rx_desc *rx_desc) +void dp_rx_dump_info_and_assert(struct dp_soc *soc, + hal_ring_handle_t hal_ring, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) { void *hal_soc = soc->hal_soc; @@ -84,18 +75,65 @@ void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring, dp_rx_desc_dump(rx_desc); } #else -void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring, - void *ring_desc, struct dp_rx_desc *rx_desc) +void dp_rx_dump_info_and_assert(struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) { - void *hal_soc = soc->hal_soc; + hal_soc_handle_t hal_soc = soc->hal_soc; dp_rx_desc_dump(rx_desc); - hal_srng_dump_ring_desc(hal_soc, hal_ring, ring_desc); - hal_srng_dump_ring(hal_soc, hal_ring); + hal_srng_dump_ring_desc(hal_soc, hal_ring_hdl, ring_desc); + hal_srng_dump_ring(hal_soc, hal_ring_hdl); qdf_assert_always(0); } #endif +#ifdef RX_DESC_SANITY_WAR +static inline +QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) +{ + uint8_t return_buffer_manager; + + if (qdf_unlikely(!rx_desc)) { + /* + * This is an unlikely case where the cookie obtained + * from the ring_desc is invalid and hence we are not + * able to find the corresponding rx_desc + */ + goto fail; + } + + return_buffer_manager = hal_rx_ret_buf_manager_get(ring_desc); + if (qdf_unlikely(!(return_buffer_manager == HAL_RX_BUF_RBM_SW1_BM || + return_buffer_manager == HAL_RX_BUF_RBM_SW3_BM))) { + goto fail; + } + + return QDF_STATUS_SUCCESS; + +fail: + DP_STATS_INC(soc, rx.err.invalid_cookie, 1); + dp_err("Ring Desc:"); + hal_srng_dump_ring_desc(hal_soc, hal_ring_hdl, + ring_desc); + return QDF_STATUS_E_NULL_VALUE; + +} +#else +static inline +QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization @@ -123,7 +161,7 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, { uint32_t num_alloc_desc; uint16_t num_desc_to_free = 0; - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(dp_soc, mac_id); + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(dp_soc, mac_id); uint32_t num_entries_avail; uint32_t count; int sync_hw_ptr = 1; @@ -132,6 +170,8 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, void *rxdma_ring_entry; union dp_rx_desc_list_elem_t *next; QDF_STATUS ret; + uint16_t buf_size = rx_desc_pool->buf_size; + uint8_t buf_alignment = rx_desc_pool->buf_alignment; void *rxdma_srng; @@ -199,14 +239,14 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, while (count < num_req_buffers) { rx_netbuf = qdf_nbuf_alloc(dp_soc->osdev, - RX_BUFFER_SIZE, + buf_size, RX_BUFFER_RESERVATION, - RX_BUFFER_ALIGNMENT, + buf_alignment, FALSE); if (qdf_unlikely(!rx_netbuf)) { DP_STATS_INC(dp_pdev, replenish.nbuf_alloc_fail, 1); - continue; + break; } ret = qdf_nbuf_map_single(dp_soc->osdev, rx_netbuf, @@ -226,7 +266,7 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, * allocating new nbuf. We can try for 100 times. * this is a temp WAR till we fix it properly. */ - ret = check_x86_paddr(dp_soc, &rx_netbuf, &paddr, dp_pdev); + ret = check_x86_paddr(dp_soc, &rx_netbuf, &paddr, rx_desc_pool); if (ret == QDF_STATUS_E_FAILURE) { DP_STATS_INC(dp_pdev, replenish.x86_fail, 1); break; @@ -246,6 +286,7 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, qdf_assert_always((*desc_list)->rx_desc.in_use == 0); (*desc_list)->rx_desc.in_use = 1; + (*desc_list)->rx_desc.in_err_state = 0; dp_rx_desc_update_dbg_info(&(*desc_list)->rx_desc, func_name, RX_DESC_REPLENISHED); dp_verbose_debug("rx_netbuf=%pK, buf=%pK, paddr=0x%llx, cookie=%d", @@ -264,10 +305,12 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, hal_srng_access_end(dp_soc->hal_soc, rxdma_srng); dp_verbose_debug("replenished buffers %d, rx desc added back to free list %u", - num_req_buffers, num_desc_to_free); + count, num_desc_to_free); - DP_STATS_INC_PKT(dp_pdev, replenish.pkts, num_req_buffers, - (RX_BUFFER_SIZE * num_req_buffers)); + /* No need to count the number of bytes received during replenish. + * Therefore set replenish.pkts.bytes as 0. + */ + DP_STATS_INC_PKT(dp_pdev, replenish.pkts, count, 0); free_descs: DP_STATS_INC(dp_pdev, buf_freelist, num_desc_to_free); @@ -323,7 +366,7 @@ dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list, } vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head, - &deliver_list_tail, (struct cdp_peer*) peer); + &deliver_list_tail, peer->mac_addr.raw); vdev->osif_rx(vdev->osif_vdev, deliver_list_head); } @@ -345,14 +388,14 @@ dp_get_vdev_from_peer(struct dp_soc *soc, if (unlikely(!peer)) { if (peer_id != HTT_INVALID_PEER) { - vdev_id = DP_PEER_METADATA_ID_GET( + vdev_id = DP_PEER_METADATA_VDEV_ID_GET( mpdu_desc_info.peer_meta_data); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, FL("PeerID %d not found use vdevID %d"), peer_id, vdev_id); vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, - vdev_id); + vdev_id); } else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -407,9 +450,9 @@ static bool dp_rx_intrabss_fwd(struct dp_soc *soc, struct dp_peer *ta_peer, uint8_t *rx_tlv_hdr, - qdf_nbuf_t nbuf) + qdf_nbuf_t nbuf, + struct hal_rx_msdu_metadata msdu_metadata) { - uint16_t da_idx; uint16_t len; uint8_t is_frag; struct dp_peer *da_peer; @@ -426,9 +469,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, */ if ((qdf_nbuf_is_da_valid(nbuf) && !qdf_nbuf_is_da_mcbc(nbuf))) { - da_idx = hal_rx_msdu_end_da_idx_get(soc->hal_soc, rx_tlv_hdr); - ast_entry = soc->ast_table[da_idx]; + ast_entry = soc->ast_table[msdu_metadata.da_idx]; if (!ast_entry) return false; @@ -476,7 +518,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, } } - if (!dp_tx_send(ta_peer->vdev, nbuf)) { + if (!dp_tx_send((struct cdp_soc_t *)soc, + ta_peer->vdev->vdev_id, nbuf)) { DP_STATS_INC_PKT(ta_peer, rx.intra_bss.pkts, 1, len); return true; @@ -508,7 +551,10 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb)); - if (dp_tx_send(ta_peer->vdev, nbuf_copy)) { + /* Set cb->ftype to intrabss FWD */ + qdf_nbuf_set_tx_ftype(nbuf_copy, CB_FTYPE_INTRABSS_FWD); + if (dp_tx_send((struct cdp_soc_t *)soc, + ta_peer->vdev->vdev_id, nbuf_copy)) { DP_STATS_INC_PKT(ta_peer, rx.intra_bss.fail, 1, len); tid_stats->fail_cnt[INTRABSS_DROP]++; qdf_nbuf_free(nbuf_copy); @@ -617,23 +663,29 @@ QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr) { union dp_align_mac_addr mac_addr; + struct dp_soc *soc = vdev->pdev->soc; if (qdf_unlikely(vdev->mesh_rx_filter)) { if (vdev->mesh_rx_filter & MESH_FILTER_OUT_FROMDS) - if (hal_rx_mpdu_get_fr_ds(rx_tlv_hdr)) + if (hal_rx_mpdu_get_fr_ds(soc->hal_soc, + rx_tlv_hdr)) return QDF_STATUS_SUCCESS; if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TODS) - if (hal_rx_mpdu_get_to_ds(rx_tlv_hdr)) + if (hal_rx_mpdu_get_to_ds(soc->hal_soc, + rx_tlv_hdr)) return QDF_STATUS_SUCCESS; if (vdev->mesh_rx_filter & MESH_FILTER_OUT_NODS) - if (!hal_rx_mpdu_get_fr_ds(rx_tlv_hdr) - && !hal_rx_mpdu_get_to_ds(rx_tlv_hdr)) + if (!hal_rx_mpdu_get_fr_ds(soc->hal_soc, + rx_tlv_hdr) && + !hal_rx_mpdu_get_to_ds(soc->hal_soc, + rx_tlv_hdr)) return QDF_STATUS_SUCCESS; if (vdev->mesh_rx_filter & MESH_FILTER_OUT_RA) { - if (hal_rx_mpdu_get_addr1(rx_tlv_hdr, + if (hal_rx_mpdu_get_addr1(soc->hal_soc, + rx_tlv_hdr, &mac_addr.raw[0])) return QDF_STATUS_E_FAILURE; @@ -644,8 +696,9 @@ QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf, } if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TA) { - if (hal_rx_mpdu_get_addr2(rx_tlv_hdr, - &mac_addr.raw[0])) + if (hal_rx_mpdu_get_addr2(soc->hal_soc, + rx_tlv_hdr, + &mac_addr.raw[0])) return QDF_STATUS_E_FAILURE; if (!qdf_mem_cmp(&mac_addr.raw[0], @@ -740,7 +793,7 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); - if (!HAL_IS_DECAP_FORMAT_RAW(rx_tlv_hdr)) { + if (!HAL_IS_DECAP_FORMAT_RAW(soc->hal_soc, rx_tlv_hdr)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "Drop decapped frames"); goto free; @@ -760,11 +813,11 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, goto free; } - pdev = dp_get_pdev_for_mac_id(soc, mac_id); + pdev = dp_get_pdev_for_lmac_id(soc, mac_id); - if (!pdev) { + if (!pdev || qdf_unlikely(pdev->is_pdev_down)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "PDEV not found"); + "PDEV %s", !pdev ? "not found" : "down"); goto free; } @@ -783,7 +836,6 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, } } - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, @@ -804,8 +856,9 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, msg.nbuf = mpdu; msg.vdev_id = vdev->vdev_id; if (pdev->soc->cdp_soc.ol_ops->rx_invalid_peer) - pdev->soc->cdp_soc.ol_ops->rx_invalid_peer(pdev->ctrl_pdev, - &msg); + pdev->soc->cdp_soc.ol_ops->rx_invalid_peer( + (struct cdp_ctrl_objmgr_psoc *)soc->ctrl_psoc, + pdev->pdev_id, &msg); free: /* Drop and free packet */ @@ -862,7 +915,7 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, goto free; } - pdev = dp_get_pdev_for_mac_id(soc, mac_id); + pdev = dp_get_pdev_for_lmac_id(soc, mac_id); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -891,7 +944,7 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, soc->cdp_soc.ol_ops->rx_invalid_peer(vdev->vdev_id, wh); free: /* reset the head and tail pointers */ - pdev = dp_get_pdev_for_mac_id(soc, mac_id); + pdev = dp_get_pdev_for_lmac_id(soc, mac_id); if (pdev) { pdev->invalid_peer_head_msdu = NULL; pdev->invalid_peer_tail_msdu = NULL; @@ -905,6 +958,13 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, curr_nbuf = next_nbuf; } + /* Reset the head and tail pointers */ + pdev = dp_get_pdev_for_mac_id(soc, mac_id); + if (pdev) { + pdev->invalid_peer_head_msdu = NULL; + pdev->invalid_peer_tail_msdu = NULL; + } + return 0; } @@ -920,16 +980,18 @@ void dp_rx_process_invalid_peer_wrapper(struct dp_soc *soc, #ifdef RECEIVE_OFFLOAD /** * dp_rx_print_offload_info() - Print offload info from RX TLV + * @soc: dp soc handle * @rx_tlv: RX TLV for which offload information is to be printed * * Return: None */ -static void dp_rx_print_offload_info(uint8_t *rx_tlv) +static void dp_rx_print_offload_info(struct dp_soc *soc, uint8_t *rx_tlv) { dp_verbose_debug("----------------------RX DESC LRO/GRO----------------------"); dp_verbose_debug("lro_eligible 0x%x", HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv)); dp_verbose_debug("pure_ack 0x%x", HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv)); - dp_verbose_debug("chksum 0x%x", HAL_RX_TLV_GET_TCP_CHKSUM(rx_tlv)); + dp_verbose_debug("chksum 0x%x", hal_rx_tlv_get_tcp_chksum(soc->hal_soc, + rx_tlv)); dp_verbose_debug("TCP seq num 0x%x", HAL_RX_TLV_GET_TCP_SEQ(rx_tlv)); dp_verbose_debug("TCP ack num 0x%x", HAL_RX_TLV_GET_TCP_ACK(rx_tlv)); dp_verbose_debug("TCP window 0x%x", HAL_RX_TLV_GET_TCP_WIN(rx_tlv)); @@ -966,7 +1028,8 @@ void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, QDF_NBUF_CB_RX_TCP_PURE_ACK(msdu) = HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv); QDF_NBUF_CB_RX_TCP_CHKSUM(msdu) = - HAL_RX_TLV_GET_TCP_CHKSUM(rx_tlv); + hal_rx_tlv_get_tcp_chksum(soc->hal_soc, + rx_tlv); QDF_NBUF_CB_RX_TCP_SEQ_NUM(msdu) = HAL_RX_TLV_GET_TCP_SEQ(rx_tlv); QDF_NBUF_CB_RX_TCP_ACK_NUM(msdu) = @@ -982,7 +1045,7 @@ void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, QDF_NBUF_CB_RX_FLOW_ID(msdu) = HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ(rx_tlv); - dp_rx_print_offload_info(rx_tlv); + dp_rx_print_offload_info(soc, rx_tlv); } #else static void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, @@ -996,29 +1059,67 @@ static void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, * * @nbuf: pointer to msdu. * @mpdu_len: mpdu length + * @l3_pad_len: L3 padding length by HW * * Return: returns true if nbuf is last msdu of mpdu else retuns false. */ -static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, uint16_t *mpdu_len) +static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, + uint16_t *mpdu_len, + uint32_t l3_pad_len) { bool last_nbuf; + uint32_t pkt_hdr_size; + + pkt_hdr_size = RX_PKT_TLVS_LEN + l3_pad_len; - if (*mpdu_len > (RX_BUFFER_SIZE - RX_PKT_TLVS_LEN)) { - qdf_nbuf_set_pktlen(nbuf, RX_BUFFER_SIZE); + if ((*mpdu_len + pkt_hdr_size) > RX_DATA_BUFFER_SIZE) { + qdf_nbuf_set_pktlen(nbuf, RX_DATA_BUFFER_SIZE); last_nbuf = false; + *mpdu_len -= (RX_DATA_BUFFER_SIZE - pkt_hdr_size); } else { - qdf_nbuf_set_pktlen(nbuf, (*mpdu_len + RX_PKT_TLVS_LEN)); + qdf_nbuf_set_pktlen(nbuf, (*mpdu_len + pkt_hdr_size)); last_nbuf = true; + *mpdu_len = 0; } - *mpdu_len -= (RX_BUFFER_SIZE - RX_PKT_TLVS_LEN); - return last_nbuf; } +/** + * dp_get_l3_hdr_pad_len() - get L3 header padding length. + * + * @soc: DP soc handle + * @nbuf: pointer to msdu. + * + * Return: returns padding length in bytes. + */ +static inline uint32_t dp_get_l3_hdr_pad_len(struct dp_soc *soc, + qdf_nbuf_t nbuf) +{ + uint32_t l3_hdr_pad = 0; + uint8_t *rx_tlv_hdr; + struct hal_rx_msdu_metadata msdu_metadata; + + while (nbuf) { + if (!qdf_nbuf_is_rx_chfrag_cont(nbuf)) { + /* scattered msdu end with continuation is 0 */ + rx_tlv_hdr = qdf_nbuf_data(nbuf); + hal_rx_msdu_metadata_get(soc->hal_soc, + rx_tlv_hdr, + &msdu_metadata); + l3_hdr_pad = msdu_metadata.l3_hdr_pad; + break; + } + nbuf = nbuf->next; + } + + return l3_hdr_pad; +} + /** * dp_rx_sg_create() - create a frag_list for MSDUs which are spread across * multiple nbufs. + * @soc: DP SOC handle * @nbuf: pointer to the first msdu of an amsdu. * * This function implements the creation of RX frag_list for cases @@ -1026,12 +1127,13 @@ static inline bool dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, uint16_t *mpdu_len) * * Return: returns the head nbuf which contains complete frag_list. */ -qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) +qdf_nbuf_t dp_rx_sg_create(struct dp_soc *soc, qdf_nbuf_t nbuf) { - qdf_nbuf_t parent, next, frag_list; + qdf_nbuf_t parent, frag_list, next = NULL; uint16_t frag_list_len = 0; uint16_t mpdu_len; bool last_nbuf; + uint32_t l3_hdr_pad_offset = 0; /* * Use msdu len got from REO entry descriptor instead since @@ -1039,6 +1141,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) * from REO descriptor is right for non-raw RX scatter msdu. */ mpdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); + /* * this is a case where the complete msdu fits in one single nbuf. * in this case HW sets both start and end bit and we only need to @@ -1051,6 +1154,8 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) return nbuf; } + l3_hdr_pad_offset = dp_get_l3_hdr_pad_len(soc, nbuf); + /* * This is a case where we have multiple msdus (A-MSDU) spread across * multiple nbufs. here we create a fraglist out of these nbufs. @@ -1070,7 +1175,24 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) * nbufs will form the frag_list of the parent nbuf. */ qdf_nbuf_set_rx_chfrag_start(parent, 1); - last_nbuf = dp_rx_adjust_nbuf_len(parent, &mpdu_len); + /* + * L3 header padding is only needed for the 1st buffer + * in a scattered msdu + */ + last_nbuf = dp_rx_adjust_nbuf_len(parent, &mpdu_len, + l3_hdr_pad_offset); + + /* + * HW issue: MSDU cont bit is set but reported MPDU length can fit + * in to single buffer + * + * Increment error stats and avoid SG list creation + */ + if (last_nbuf) { + qdf_nbuf_pull_head(parent, + RX_PKT_TLVS_LEN + l3_hdr_pad_offset); + return parent; + } /* * this is where we set the length of the fragments which are @@ -1078,7 +1200,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) * till we hit the last_nbuf of the list. */ do { - last_nbuf = dp_rx_adjust_nbuf_len(nbuf, &mpdu_len); + last_nbuf = dp_rx_adjust_nbuf_len(nbuf, &mpdu_len, 0); qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN); frag_list_len += qdf_nbuf_len(nbuf); @@ -1095,7 +1217,8 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf) qdf_nbuf_append_ext_list(parent, frag_list, frag_list_len); parent->next = next; - qdf_nbuf_pull_head(parent, RX_PKT_TLVS_LEN); + qdf_nbuf_pull_head(parent, + RX_PKT_TLVS_LEN + l3_hdr_pad_offset); return parent; } @@ -1312,7 +1435,12 @@ static void dp_rx_check_delivery_to_stack(struct dp_soc *soc, struct dp_peer *peer, qdf_nbuf_t nbuf_head) { - vdev->osif_rx(vdev->osif_vdev, nbuf_head); + /* Function pointer initialized only when FISA is enabled */ + if (vdev->osif_fisa_rx) + /* on failure send it via regular path */ + vdev->osif_fisa_rx(soc, vdev, nbuf_head); + else + vdev->osif_rx(vdev->osif_vdev, nbuf_head); } #else @@ -1338,7 +1466,11 @@ static void dp_rx_check_delivery_to_stack(struct dp_soc *soc, int num_nbuf = 0; QDF_STATUS ret_val = QDF_STATUS_E_FAILURE; - if (vdev->osif_rx) + /* Function pointer initialized only when FISA is enabled */ + if (vdev->osif_fisa_rx) + /* on failure send it via regular path */ + ret_val = vdev->osif_fisa_rx(soc, vdev, nbuf_head); + else if (vdev->osif_rx) ret_val = vdev->osif_rx(vdev->osif_vdev, nbuf_head); if (!QDF_IS_STATUS_SUCCESS(ret_val)) { @@ -1387,8 +1519,9 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc, if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) || (vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi)) { vdev->osif_rsim_rx_decap(vdev->osif_vdev, &nbuf_head, - &nbuf_tail, (struct cdp_peer *) peer); + &nbuf_tail, peer->mac_addr.raw); } + dp_rx_check_delivery_to_stack(soc, vdev, peer, nbuf_head); } @@ -1419,6 +1552,30 @@ static inline void dp_rx_cksum_offload(struct dp_pdev *pdev, } } +#ifdef VDEV_PEER_PROTOCOL_COUNT +#define dp_rx_msdu_stats_update_prot_cnts(vdev_hdl, nbuf, peer) \ +{ \ + qdf_nbuf_t nbuf_local; \ + struct dp_peer *peer_local; \ + struct dp_vdev *vdev_local = vdev_hdl; \ + do { \ + if (qdf_likely(!((vdev_local)->peer_protocol_count_track))) \ + break; \ + nbuf_local = nbuf; \ + peer_local = peer; \ + if (qdf_unlikely(qdf_nbuf_is_frag((nbuf_local)))) \ + break; \ + else if (qdf_unlikely(qdf_nbuf_is_raw_frame((nbuf_local)))) \ + break; \ + dp_vdev_peer_stats_update_protocol_cnt((vdev_local), \ + (nbuf_local), \ + (peer_local), 0, 1); \ + } while (0); \ +} +#else +#define dp_rx_msdu_stats_update_prot_cnts(vdev_hdl, nbuf, peer) +#endif + /** * dp_rx_msdu_stats_update() - update per msdu stats. * @soc: core txrx main context @@ -1444,6 +1601,7 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc, qdf_ether_header_t *eh; uint16_t msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); + dp_rx_msdu_stats_update_prot_cnts(vdev, nbuf, peer); is_not_amsdu = qdf_nbuf_is_rx_chfrag_start(nbuf) & qdf_nbuf_is_rx_chfrag_end(nbuf); @@ -1544,16 +1702,15 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc, } static inline bool is_sa_da_idx_valid(struct dp_soc *soc, - void *rx_tlv_hdr, - qdf_nbuf_t nbuf) + uint8_t *rx_tlv_hdr, + qdf_nbuf_t nbuf, + struct hal_rx_msdu_metadata msdu_info) { if ((qdf_nbuf_is_sa_valid(nbuf) && - (hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr) > - wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) || + (msdu_info.sa_idx > wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) || (!qdf_nbuf_is_da_mcbc(nbuf) && qdf_nbuf_is_da_valid(nbuf) && - (hal_rx_msdu_end_da_idx_get(soc->hal_soc, rx_tlv_hdr) > - wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)))) + (msdu_info.da_idx > wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)))) return false; return true; @@ -1578,20 +1735,25 @@ int dp_wds_rx_policy_check(uint8_t *rx_tlv_hdr, * * Return: NONE */ -static inline void dp_rx_desc_nbuf_sanity_check(void *ring_desc, - struct dp_rx_desc *rx_desc) +static inline +QDF_STATUS dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) { struct hal_buf_info hbi; hal_rx_reo_buf_paddr_get(ring_desc, &hbi); /* Sanity check for possible buffer paddr corruption */ - qdf_assert_always((&hbi)->paddr == - qdf_nbuf_get_frag_paddr(rx_desc->nbuf, 0)); + if (dp_rx_desc_paddr_sanity_check(rx_desc, (&hbi)->paddr)) + return QDF_STATUS_SUCCESS; + + return QDF_STATUS_E_FAILURE; } #else -static inline void dp_rx_desc_nbuf_sanity_check(void *ring_desc, - struct dp_rx_desc *rx_desc) +static inline +QDF_STATUS dp_rx_desc_nbuf_sanity_check(hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) { + return QDF_STATUS_SUCCESS; } #endif @@ -1646,7 +1808,6 @@ static inline bool dp_rx_enable_eol_data_check(struct dp_soc *soc) static void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) { - uint32_t peer_mdata; uint16_t peer_id; uint8_t vdev_id; struct dp_vdev *vdev; @@ -1657,13 +1818,11 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) uint32_t frame_mask = FRAME_MASK_IPV4_ARP | FRAME_MASK_IPV4_DHCP | FRAME_MASK_IPV4_EAPOL | FRAME_MASK_IPV6_DHCP; - peer_mdata = QDF_NBUF_CB_RX_PEER_ID(nbuf); - - peer_id = DP_PEER_METADATA_PEER_ID_GET(peer_mdata); + peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf); if (peer_id > soc->max_peers) goto deliver_fail; - vdev_id = DP_PEER_METADATA_ID_GET(peer_mdata); + vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); if (!vdev || vdev->delete.pending || !vdev->osif_rx) goto deliver_fail; @@ -1673,7 +1832,7 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) rx_tlv_hdr = qdf_nbuf_data(nbuf); l2_hdr_offset = - hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); + hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_tlv_hdr); msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN; @@ -1685,7 +1844,10 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) l2_hdr_offset); if (dp_rx_is_special_frame(nbuf, frame_mask)) { - vdev->osif_rx(vdev->osif_vdev, nbuf); + qdf_nbuf_set_exc_frame(nbuf, 1); + if (QDF_STATUS_SUCCESS != + vdev->osif_rx(vdev->osif_vdev, nbuf)) + goto deliver_fail; DP_STATS_INC(soc, rx.err.pkt_delivered_no_peer, 1); return; } @@ -1720,11 +1882,11 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) * entries. It should not be called within a SRNG lock. HW pointer value is * synced into cached_hp. * - * Return: Number of pending entries in the hal_ring + * Return: Number of pending entries if any */ static -uint32_t dp_rx_srng_get_num_pending(void *hal_soc, - void *hal_ring_hdl, +uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, uint32_t num_entries, bool *near_full) { @@ -1742,6 +1904,145 @@ uint32_t dp_rx_srng_get_num_pending(void *hal_soc, return num_pending; } +#ifdef WLAN_SUPPORT_RX_FISA +void dp_rx_skip_tlvs(qdf_nbuf_t nbuf, uint32_t l3_padding) +{ + QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(nbuf) = l3_padding; + qdf_nbuf_pull_head(nbuf, l3_padding + RX_PKT_TLVS_LEN); +} + +/** + * dp_rx_set_hdr_pad() - set l3 padding in nbuf cb + * @nbuf: pkt skb pointer + * @l3_padding: l3 padding + * + * Return: None + */ +static inline +void dp_rx_set_hdr_pad(qdf_nbuf_t nbuf, uint32_t l3_padding) +{ + QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(nbuf) = l3_padding; +} +#else +void dp_rx_skip_tlvs(qdf_nbuf_t nbuf, uint32_t l3_padding) +{ + qdf_nbuf_pull_head(nbuf, l3_padding + RX_PKT_TLVS_LEN); +} + +static inline +void dp_rx_set_hdr_pad(qdf_nbuf_t nbuf, uint32_t l3_padding) +{ +} +#endif + +#ifdef DP_RX_DROP_RAW_FRM +/** + * dp_rx_is_raw_frame_dropped() - if raw frame nbuf, free and drop + * @nbuf: pkt skb pointer + * + * Return: true - raw frame, dropped + * false - not raw frame, do nothing + */ +static inline +bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf) +{ + if (qdf_nbuf_is_raw_frame(nbuf)) { + qdf_nbuf_free(nbuf); + return true; + } + + return false; +} +#else +static inline +bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf) +{ + return false; +} +#endif + +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +/** + * dp_rx_ring_record_entry() - Record an entry into the rx ring history. + * @soc: Datapath soc structure + * @ring_num: REO ring number + * @ring_desc: REO ring descriptor + * + * Returns: None + */ +static inline void +dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, + hal_ring_desc_t ring_desc) +{ + struct dp_buf_info_record *record; + uint8_t rbm; + struct hal_buf_info hbi; + uint32_t idx; + + if (qdf_unlikely(!soc->rx_ring_history[ring_num])) + return; + + hal_rx_reo_buf_paddr_get(ring_desc, &hbi); + rbm = hal_rx_ret_buf_manager_get(ring_desc); + + idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index, + DP_RX_HIST_MAX); + + /* No NULL check needed for record since its an array */ + record = &soc->rx_ring_history[ring_num]->entry[idx]; + + record->timestamp = qdf_get_log_timestamp(); + record->hbi.paddr = hbi.paddr; + record->hbi.sw_cookie = hbi.sw_cookie; + record->hbi.rbm = rbm; +} +#else +static inline void +dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, + hal_ring_desc_t ring_desc) +{ +} +#endif + +#ifdef DISABLE_EAPOL_INTRABSS_FWD +/* + * dp_rx_intrabss_fwd_wrapper() - Wrapper API for intrabss fwd. For EAPOL + * pkt with DA not equal to vdev mac addr, fwd is not allowed. + * @soc: core txrx main context + * @ta_peer: source peer entry + * @rx_tlv_hdr: start address of rx tlvs + * @nbuf: nbuf that has to be intrabss forwarded + * @msdu_metadata: msdu metadata + * + * Return: true if it is forwarded else false + */ +static inline +bool dp_rx_intrabss_fwd_wrapper(struct dp_soc *soc, struct dp_peer *ta_peer, + uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf, + struct hal_rx_msdu_metadata msdu_metadata) +{ + if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(nbuf) && + qdf_mem_cmp(qdf_nbuf_data(nbuf) + + QDF_NBUF_DEST_MAC_OFFSET, + ta_peer->vdev->mac_addr.raw, + QDF_MAC_ADDR_SIZE))) { + qdf_nbuf_free(nbuf); + DP_STATS_INC(soc, rx.err.intrabss_eapol_drop, 1); + return true; + } + + return dp_rx_intrabss_fwd(soc, ta_peer, rx_tlv_hdr, nbuf, + msdu_metadata); + +} +#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \ + dp_rx_intrabss_fwd_wrapper(soc, peer, rx_tlv_hdr, nbuf, \ + msdu_metadata) +#else +#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \ + dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) +#endif + /** * dp_rx_process() - Brain of the Rx processing functionality * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) @@ -1755,11 +2056,11 @@ uint32_t dp_rx_srng_get_num_pending(void *hal_soc, * * Return: uint32_t: No. of elements processed */ -uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, - uint8_t reo_ring_num, uint32_t quota) +uint32_t dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl, + uint8_t reo_ring_num, uint32_t quota) { - void *hal_soc; - void *ring_desc; + hal_ring_desc_t ring_desc; + hal_soc_handle_t hal_soc; struct dp_rx_desc *rx_desc = NULL; qdf_nbuf_t nbuf, next; bool near_full; @@ -1767,9 +2068,9 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT]; uint32_t num_pending; uint32_t rx_bufs_used = 0, rx_buf_cookie; - uint32_t l2_hdr_offset = 0; uint16_t msdu_len = 0; uint16_t peer_id; + uint8_t vdev_id; struct dp_peer *peer; struct dp_vdev *vdev; uint32_t pkt_len = 0; @@ -1780,7 +2081,6 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint8_t *rx_tlv_hdr; uint32_t rx_bufs_reaped[MAX_PDEV_CNT]; uint8_t mac_id = 0; - struct dp_pdev *pdev; struct dp_pdev *rx_pdev; struct dp_srng *dp_rxdma_srng; struct rx_desc_pool *rx_desc_pool; @@ -1800,18 +2100,19 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t num_entries_avail = 0; uint32_t rx_ol_pkt_cnt = 0; uint32_t num_entries = 0; + struct hal_rx_msdu_metadata msdu_metadata; + QDF_STATUS status; DP_HIST_INIT(); - qdf_assert_always(soc && hal_ring); + qdf_assert_always(soc && hal_ring_hdl); hal_soc = soc->hal_soc; qdf_assert_always(hal_soc); scn = soc->hif_handle; hif_pm_runtime_mark_dp_rx_busy(scn); intr_id = int_ctx->dp_intr_id; - num_entries = hal_srng_get_num_entries(hal_soc, - hal_ring); + num_entries = hal_srng_get_num_entries(hal_soc, hal_ring_hdl); more_data: /* reset local variables here to be re-used in the function */ @@ -1829,7 +2130,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, qdf_mem_zero(head, sizeof(head)); qdf_mem_zero(tail, sizeof(tail)); - if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring))) { + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) { /* * Need API to convert from hal_ring pointer to @@ -1837,7 +2138,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, */ DP_STATS_INC(soc, rx.err.hal_ring_access_fail, 1); QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - FL("HAL RING Access Failed -- %pK"), hal_ring); + FL("HAL RING Access Failed -- %pK"), hal_ring_hdl); goto done; } @@ -1847,23 +2148,50 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, * Process the received pkts in a different per vdev loop. */ while (qdf_likely(quota && - (ring_desc = hal_srng_dst_peek(hal_soc, hal_ring)))) { + (ring_desc = hal_srng_dst_peek(hal_soc, + hal_ring_hdl)))) { error = HAL_RX_ERROR_STATUS_GET(ring_desc); - ring_id = hal_srng_ring_id_get(hal_ring); + ring_id = hal_srng_ring_id_get(hal_ring_hdl); if (qdf_unlikely(error == HAL_REO_ERROR_DETECTED)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("HAL RING 0x%pK:error %d"), hal_ring, error); + FL("HAL RING 0x%pK:error %d"), hal_ring_hdl, error); DP_STATS_INC(soc, rx.err.hal_reo_error[ring_id], 1); /* Don't know how to deal with this -- assert */ qdf_assert(0); } + dp_rx_ring_record_entry(soc, reo_ring_num, ring_desc); rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(ring_desc); + status = dp_rx_cookie_check_and_invalidate(ring_desc); + if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) { + DP_STATS_INC(soc, rx.err.stale_cookie, 1); + break; + } rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie); - qdf_assert(rx_desc); + status = dp_rx_desc_sanity(soc, hal_soc, hal_ring_hdl, + ring_desc, rx_desc); + if (QDF_IS_STATUS_ERROR(status)) { + if (qdf_unlikely(rx_desc && rx_desc->nbuf)) { + qdf_assert_always(rx_desc->unmapped); + dp_ipa_handle_rx_buf_smmu_mapping(soc, + rx_desc->nbuf, + false); + qdf_nbuf_unmap_single(soc->osdev, + rx_desc->nbuf, + QDF_DMA_FROM_DEVICE); + rx_desc->unmapped = 1; + qdf_nbuf_free(rx_desc->nbuf); + dp_rx_add_to_free_desc_list( + &head[rx_desc->pool_id], + &tail[rx_desc->pool_id], + rx_desc); + } + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); + continue; + } /* * this is a unlikely scenario where the host is reaping @@ -1872,26 +2200,33 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, * In this case host will dump the last 128 descriptors * including the software descriptor rx_desc and assert. */ + if (qdf_unlikely(!rx_desc->in_use)) { DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1); dp_info_rl("Reaping rx_desc not in use!"); - dp_rx_dump_info_and_assert(soc, hal_ring, + dp_rx_dump_info_and_assert(soc, hal_ring_hdl, ring_desc, rx_desc); /* ignore duplicate RX desc and continue to process */ - /* Pop out the descriptor*/ - hal_srng_dst_get_next(hal_soc, hal_ring); + /* Pop out the descriptor */ + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); + continue; + } + + status = dp_rx_desc_nbuf_sanity_check(ring_desc, rx_desc); + if (QDF_IS_STATUS_ERROR(status)) { + DP_STATS_INC(soc, rx.err.nbuf_sanity_fail, 1); + rx_desc->in_err_state = 1; + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); continue; } if (qdf_unlikely(!dp_rx_desc_check_magic(rx_desc))) { dp_err("Invalid rx_desc cookie=%d", rx_buf_cookie); DP_STATS_INC(soc, rx.err.rx_desc_invalid_magic, 1); - dp_rx_dump_info_and_assert(soc, hal_ring, + dp_rx_dump_info_and_assert(soc, hal_ring_hdl, ring_desc, rx_desc); } - dp_rx_desc_nbuf_sanity_check(ring_desc, rx_desc); - /* Get MPDU DESC info */ hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); @@ -1906,7 +2241,8 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, if (is_prev_msdu_last) { /* Get number of entries available in HW ring */ num_entries_avail = - hal_srng_dst_num_valid(hal_soc, hal_ring, 1); + hal_srng_dst_num_valid(hal_soc, + hal_ring_hdl, 1); /* For new MPDU check if we can read complete * MPDU by comparing the number of buffers @@ -1914,8 +2250,8 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, * reap this MPDU */ if (((msdu_desc_info.msdu_len / - (RX_BUFFER_SIZE - RX_PKT_TLVS_LEN) + 1)) > - num_entries_avail) { + (RX_DATA_BUFFER_SIZE - RX_PKT_TLVS_LEN) + + 1)) > num_entries_avail) { DP_STATS_INC( soc, rx.msdu_scatter_wait_break, @@ -1951,12 +2287,14 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, is_prev_msdu_last = true; /* Pop out the descriptor*/ - hal_srng_dst_get_next(hal_soc, hal_ring); + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); rx_bufs_reaped[rx_desc->pool_id]++; peer_mdata = mpdu_desc_info.peer_meta_data; QDF_NBUF_CB_RX_PEER_ID(rx_desc->nbuf) = DP_PEER_METADATA_PEER_ID_GET(peer_mdata); + QDF_NBUF_CB_RX_VDEV_ID(rx_desc->nbuf) = + DP_PEER_METADATA_VDEV_ID_GET(peer_mdata); /* * save msdu flags first, last and continuation msdu in @@ -1986,6 +2324,9 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, qdf_nbuf_set_tid_val(rx_desc->nbuf, HAL_RX_REO_QUEUE_NUMBER_GET(ring_desc)); + qdf_nbuf_set_rx_reo_dest_ind( + rx_desc->nbuf, + HAL_RX_REO_MSDU_REO_DST_IND_GET(ring_desc)); QDF_NBUF_CB_RX_PKT_LEN(rx_desc->nbuf) = msdu_desc_info.msdu_len; @@ -2015,7 +2356,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, break; } done: - dp_srng_access_end(int_ctx, soc, hal_ring); + dp_srng_access_end(int_ctx, soc, hal_ring_hdl); for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { /* @@ -2025,8 +2366,8 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, if (!rx_bufs_reaped[mac_id]) continue; - pdev = soc->pdev_list[mac_id]; - dp_rxdma_srng = &pdev->rx_refill_buf_ring; + dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id]; + rx_desc_pool = &soc->rx_desc_buf[mac_id]; dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng, @@ -2049,39 +2390,43 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, nbuf = nbuf_head; while (nbuf) { next = nbuf->next; + if (qdf_unlikely(dp_rx_is_raw_frame_dropped(nbuf))) { + nbuf = next; + DP_STATS_INC(soc, rx.err.raw_frm_drop, 1); + continue; + } + rx_tlv_hdr = qdf_nbuf_data(nbuf); + vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); + + if (deliver_list_head && vdev && (vdev->vdev_id != vdev_id)) { + dp_rx_deliver_to_stack(soc, vdev, peer, + deliver_list_head, + deliver_list_tail); + deliver_list_head = NULL; + deliver_list_tail = NULL; + } + /* Get TID from struct cb->tid_val, save to tid */ - if (qdf_nbuf_is_rx_chfrag_start(nbuf)) + if (qdf_nbuf_is_rx_chfrag_start(nbuf)) { tid = qdf_nbuf_get_tid_val(nbuf); + if (tid >= CDP_MAX_DATA_TIDS) { + DP_STATS_INC(soc, rx.err.rx_invalid_tid_err, 1); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } + } - /* - * Check if DMA completed -- msdu_done is the last bit - * to be written - */ - rx_pdev = soc->pdev_list[rx_desc->pool_id]; - DP_RX_TID_SAVE(nbuf, tid); - if (qdf_unlikely(rx_pdev->delay_stats_flag)) - qdf_nbuf_set_timestamp(nbuf); + peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf); - tid_stats = &rx_pdev->stats.tid_stats. - tid_rx_stats[ring_id][tid]; - if (qdf_unlikely(!qdf_nbuf_is_rx_chfrag_cont(nbuf) && - !hal_rx_attn_msdu_done_get(rx_tlv_hdr))) { - dp_err("MSDU DONE failure"); - DP_STATS_INC(soc, rx.err.msdu_done_fail, 1); - hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, - QDF_TRACE_LEVEL_INFO); - tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; - qdf_nbuf_free(nbuf); - qdf_assert(0); - nbuf = next; - continue; + if (qdf_unlikely(!peer)) { + peer = dp_peer_find_by_id(soc, peer_id); + } else if (peer && peer->peer_ids[0] != peer_id) { + dp_peer_unref_del_find_by_id(peer); + peer = dp_peer_find_by_id(soc, peer_id); } - peer_mdata = QDF_NBUF_CB_RX_PEER_ID(nbuf); - peer_id = DP_PEER_METADATA_PEER_ID_GET(peer_mdata); - peer = dp_peer_find_by_id(soc, peer_id); - if (peer) { QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) = false; qdf_dp_trace_set_track(nbuf, QDF_RX); @@ -2092,18 +2437,9 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, rx_bufs_used++; - if (deliver_list_head && peer && (vdev != peer->vdev)) { - dp_rx_deliver_to_stack(soc, vdev, peer, - deliver_list_head, - deliver_list_tail); - deliver_list_head = NULL; - deliver_list_tail = NULL; - } - if (qdf_likely(peer)) { vdev = peer->vdev; } else { - tid_stats->fail_cnt[INVALID_PEER_VDEV]++; nbuf->next = NULL; dp_rx_deliver_to_stack_no_peer(soc, nbuf); nbuf = next; @@ -2111,14 +2447,46 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, } if (qdf_unlikely(!vdev)) { - tid_stats->fail_cnt[INVALID_PEER_VDEV]++; qdf_nbuf_free(nbuf); nbuf = next; DP_STATS_INC(soc, rx.err.invalid_vdev, 1); - dp_peer_unref_del_find_by_id(peer); continue; } + rx_pdev = vdev->pdev; + DP_RX_TID_SAVE(nbuf, tid); + if (qdf_unlikely(rx_pdev->delay_stats_flag)) + qdf_nbuf_set_timestamp(nbuf); + + ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); + tid_stats = + &rx_pdev->stats.tid_stats.tid_rx_stats[ring_id][tid]; + + /* + * Check if DMA completed -- msdu_done is the last bit + * to be written + */ + if (qdf_likely(!qdf_nbuf_is_rx_chfrag_cont(nbuf))) { + if (qdf_unlikely(!hal_rx_attn_msdu_done_get( + rx_tlv_hdr))) { + dp_err_rl("MSDU DONE failure"); + DP_STATS_INC(soc, rx.err.msdu_done_fail, 1); + hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO); + tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; + qdf_assert(0); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } else if (qdf_unlikely(hal_rx_attn_msdu_len_err_get( + rx_tlv_hdr))) { + DP_STATS_INC(soc, rx.err.msdu_len_err, 1); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } + } + DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id); /* * First IF condition: @@ -2145,12 +2513,18 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, * This is the most likely case, we receive 802.3 pkts * decapsulated by HW, here we need to set the pkt length. */ + hal_rx_msdu_metadata_get(hal_soc, rx_tlv_hdr, &msdu_metadata); if (qdf_unlikely(qdf_nbuf_is_frag(nbuf))) { bool is_mcbc, is_sa_vld, is_da_vld; - is_mcbc = hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr); - is_sa_vld = hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr); - is_da_vld = hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr); + is_mcbc = hal_rx_msdu_end_da_is_mcbc_get(soc->hal_soc, + rx_tlv_hdr); + is_sa_vld = + hal_rx_msdu_end_sa_is_valid_get(soc->hal_soc, + rx_tlv_hdr); + is_da_vld = + hal_rx_msdu_end_da_is_valid_get(soc->hal_soc, + rx_tlv_hdr); qdf_nbuf_set_da_mcbc(nbuf, is_mcbc); qdf_nbuf_set_da_valid(nbuf, is_da_vld); @@ -2159,7 +2533,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN); } else if (qdf_nbuf_is_rx_chfrag_cont(nbuf)) { msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); - nbuf = dp_rx_sg_create(nbuf); + nbuf = dp_rx_sg_create(soc, nbuf); next = nbuf->next; if (qdf_nbuf_is_raw_frame(nbuf)) { @@ -2168,22 +2542,32 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, } else { qdf_nbuf_free(nbuf); DP_STATS_INC(soc, rx.err.scatter_msdu, 1); - dp_info_rl("scatter msdu len %d, dropped", msdu_len); + dp_info_rl("scatter msdu len %d, dropped", + msdu_len); nbuf = next; - dp_peer_unref_del_find_by_id(peer); continue; } } else { - l2_hdr_offset = - hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); - pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN; + pkt_len = msdu_len + + msdu_metadata.l3_hdr_pad + + RX_PKT_TLVS_LEN; qdf_nbuf_set_pktlen(nbuf, pkt_len); - qdf_nbuf_pull_head(nbuf, - RX_PKT_TLVS_LEN + - l2_hdr_offset); + dp_rx_skip_tlvs(nbuf, msdu_metadata.l3_hdr_pad); + } + + /* + * process frame for mulitpass phrase processing + */ + if (qdf_unlikely(vdev->multipass_en)) { + if (dp_rx_multipass_process(peer, nbuf, tid) == false) { + DP_STATS_INC(peer, rx.multipass_rx_pkt_drop, 1); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } } if (!dp_wds_rx_policy_check(rx_tlv_hdr, vdev, peer)) { @@ -2195,22 +2579,38 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, qdf_nbuf_free(nbuf); /* Statistics */ nbuf = next; - dp_peer_unref_del_find_by_id(peer); continue; } if (qdf_unlikely(peer && (peer->nawds_enabled) && (qdf_nbuf_is_da_mcbc(nbuf)) && - (hal_rx_get_mpdu_mac_ad4_valid(rx_tlv_hdr) == + (hal_rx_get_mpdu_mac_ad4_valid(soc->hal_soc, + rx_tlv_hdr) == false))) { tid_stats->fail_cnt[NAWDS_MCAST_DROP]++; DP_STATS_INC(peer, rx.nawds_mcast_drop, 1); qdf_nbuf_free(nbuf); nbuf = next; - dp_peer_unref_del_find_by_id(peer); continue; } + /* + * Drop non-EAPOL frames from unauthorized peer. + */ + if (qdf_likely(peer) && qdf_unlikely(!peer->authorize)) { + bool is_eapol = qdf_nbuf_is_ipv4_eapol_pkt(nbuf) || + qdf_nbuf_is_ipv4_wapi_pkt(nbuf); + + if (!is_eapol) { + DP_STATS_INC(soc, + rx.err.peer_unauth_rx_pkt_drop, + 1); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } + } + if (soc->process_rx_status) dp_rx_cksum_offload(vdev->pdev, nbuf, rx_tlv_hdr); @@ -2218,6 +2618,9 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, dp_rx_update_protocol_tag(soc, vdev, nbuf, rx_tlv_hdr, reo_ring_num, false, true); + /* Update the flow tag in SKB based on FSE metadata */ + dp_rx_update_flow_tag(soc, vdev, nbuf, rx_tlv_hdr, true); + dp_rx_msdu_stats_update(soc, nbuf, rx_tlv_hdr, peer, ring_id, tid_stats); @@ -2233,7 +2636,6 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, qdf_nbuf_free(nbuf); nbuf = next; - dp_peer_unref_del_find_by_id(peer); continue; } dp_rx_fill_mesh_stats(vdev, nbuf, rx_tlv_hdr, peer); @@ -2255,26 +2657,29 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, * Drop the packet if sa_idx and da_idx OOB or * sa_sw_peerid is 0 */ - if (!is_sa_da_idx_valid(soc, rx_tlv_hdr, nbuf)) { + if (!is_sa_da_idx_valid(soc, rx_tlv_hdr, nbuf, + msdu_metadata)) { qdf_nbuf_free(nbuf); nbuf = next; DP_STATS_INC(soc, rx.err.invalid_sa_da_idx, 1); - dp_peer_unref_del_find_by_id(peer); continue; } /* WDS Source Port Learning */ if (qdf_likely(vdev->wds_enabled)) - dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, - peer, nbuf); + dp_rx_wds_srcport_learn(soc, + rx_tlv_hdr, + peer, + nbuf, + msdu_metadata); /* Intrabss-fwd */ if (dp_rx_check_ap_bridge(vdev)) - if (dp_rx_intrabss_fwd(soc, + if (DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, - nbuf)) { + nbuf, + msdu_metadata)) { nbuf = next; - dp_peer_unref_del_find_by_id(peer); tid_stats->intrabss_cnt++; continue; /* Get next desc */ } @@ -2290,19 +2695,32 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, tid_stats->delivered_to_stack++; nbuf = next; - dp_peer_unref_del_find_by_id(peer); } - if (deliver_list_head && peer) - dp_rx_deliver_to_stack(soc, vdev, peer, - deliver_list_head, - deliver_list_tail); + if (qdf_likely(deliver_list_head)) { + if (qdf_likely(peer)) + dp_rx_deliver_to_stack(soc, vdev, peer, + deliver_list_head, + deliver_list_tail); + else { + nbuf = deliver_list_head; + while (nbuf) { + next = nbuf->next; + nbuf->next = NULL; + dp_rx_deliver_to_stack_no_peer(soc, nbuf); + nbuf = next; + } + } + } + + if (qdf_likely(peer)) + dp_peer_unref_del_find_by_id(peer); if (dp_rx_enable_eol_data_check(soc) && rx_bufs_used) { if (quota) { num_pending = dp_rx_srng_get_num_pending(hal_soc, - hal_ring, + hal_ring_hdl, num_entries, &near_full); if (num_pending) { @@ -2318,6 +2736,9 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, } } + if (vdev && vdev->osif_fisa_flush) + vdev->osif_fisa_flush(soc, reo_ring_num); + if (vdev && vdev->osif_gro_flush && rx_ol_pkt_cnt) { vdev->osif_gro_flush(vdev->osif_vdev, reo_ring_num); @@ -2358,15 +2779,15 @@ QDF_STATUS dp_rx_vdev_detach(struct dp_vdev *vdev) void dp_rx_pdev_detach(struct dp_pdev *pdev) { - uint8_t pdev_id = pdev->pdev_id; + uint8_t mac_for_pdev = pdev->lmac_id; struct dp_soc *soc = pdev->soc; struct rx_desc_pool *rx_desc_pool; - rx_desc_pool = &soc->rx_desc_buf[pdev_id]; + rx_desc_pool = &soc->rx_desc_buf[mac_for_pdev]; if (rx_desc_pool->pool_size != 0) { if (!dp_is_soc_reinit(soc)) - dp_rx_desc_nbuf_and_pool_free(soc, pdev_id, + dp_rx_desc_nbuf_and_pool_free(soc, mac_for_pdev, rx_desc_pool); else dp_rx_desc_nbuf_free(soc, rx_desc_pool); @@ -2377,14 +2798,15 @@ dp_rx_pdev_detach(struct dp_pdev *pdev) static QDF_STATUS dp_pdev_nbuf_alloc_and_map(struct dp_soc *dp_soc, qdf_nbuf_t *nbuf, - struct dp_pdev *dp_pdev) + struct dp_pdev *dp_pdev, + struct rx_desc_pool *rx_desc_pool) { qdf_dma_addr_t paddr; QDF_STATUS ret = QDF_STATUS_E_FAILURE; - *nbuf = qdf_nbuf_alloc(dp_soc->osdev, RX_BUFFER_SIZE, - RX_BUFFER_RESERVATION, RX_BUFFER_ALIGNMENT, - FALSE); + *nbuf = qdf_nbuf_alloc(dp_soc->osdev, rx_desc_pool->buf_size, + RX_BUFFER_RESERVATION, + rx_desc_pool->buf_alignment, FALSE); if (!(*nbuf)) { dp_err("nbuf alloc failed"); DP_STATS_INC(dp_pdev, replenish.nbuf_alloc_fail, 1); @@ -2402,7 +2824,7 @@ dp_pdev_nbuf_alloc_and_map(struct dp_soc *dp_soc, qdf_nbuf_t *nbuf, paddr = qdf_nbuf_get_frag_paddr(*nbuf, 0); - ret = check_x86_paddr(dp_soc, nbuf, &paddr, dp_pdev); + ret = check_x86_paddr(dp_soc, nbuf, &paddr, rx_desc_pool); if (ret == QDF_STATUS_E_FAILURE) { qdf_nbuf_unmap_single(dp_soc->osdev, *nbuf, QDF_DMA_FROM_DEVICE); @@ -2415,14 +2837,14 @@ dp_pdev_nbuf_alloc_and_map(struct dp_soc *dp_soc, qdf_nbuf_t *nbuf, return QDF_STATUS_SUCCESS; } -static QDF_STATUS +QDF_STATUS dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, struct dp_srng *dp_rxdma_srng, struct rx_desc_pool *rx_desc_pool, uint32_t num_req_buffers) { - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(dp_soc, mac_id); - void *rxdma_srng = dp_rxdma_srng->hal_srng; + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(dp_soc, mac_id); + hal_ring_handle_t rxdma_srng = dp_rxdma_srng->hal_srng; union dp_rx_desc_list_elem_t *next; void *rxdma_ring_entry; qdf_dma_addr_t paddr; @@ -2490,7 +2912,7 @@ dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, break; ret = dp_pdev_nbuf_alloc_and_map(dp_soc, &rx_nbuf_arr[nr_nbuf], - dp_pdev); + dp_pdev, rx_desc_pool); if (QDF_IS_STATUS_ERROR(ret)) break; @@ -2536,8 +2958,11 @@ dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, QDF_BUG(0); return QDF_STATUS_E_RESOURCES; } - DP_STATS_INC_PKT(dp_pdev, replenish.pkts, nr_nbuf, - RX_BUFFER_SIZE * nr_nbuf_total); + + /* No need to count the number of bytes received during replenish. + * Therefore set replenish.pkts.bytes as 0. + */ + DP_STATS_INC_PKT(dp_pdev, replenish.pkts, nr_nbuf, 0); return QDF_STATUS_SUCCESS; } @@ -2559,8 +2984,11 @@ dp_rx_pdev_attach(struct dp_pdev *pdev) uint8_t pdev_id = pdev->pdev_id; struct dp_soc *soc = pdev->soc; uint32_t rxdma_entries; + uint32_t rx_sw_desc_weight; struct dp_srng *dp_rxdma_srng; struct rx_desc_pool *rx_desc_pool; + QDF_STATUS ret_val; + int mac_for_pdev; if (wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, @@ -2569,20 +2997,37 @@ dp_rx_pdev_attach(struct dp_pdev *pdev) } pdev = soc->pdev_list[pdev_id]; - dp_rxdma_srng = &pdev->rx_refill_buf_ring; + mac_for_pdev = pdev->lmac_id; + dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_for_pdev]; + rxdma_entries = dp_rxdma_srng->num_entries; soc->process_rx_status = CONFIG_PROCESS_RX_STATUS; - rx_desc_pool = &soc->rx_desc_buf[pdev_id]; - dp_rx_desc_pool_alloc(soc, pdev_id, - DP_RX_DESC_ALLOC_MULTIPLIER * rxdma_entries, + rx_desc_pool = &soc->rx_desc_buf[mac_for_pdev]; + rx_sw_desc_weight = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc->wlan_cfg_ctx); + + rx_desc_pool->desc_type = DP_RX_DESC_BUF_TYPE; + dp_rx_desc_pool_alloc(soc, mac_for_pdev, + rx_sw_desc_weight * rxdma_entries, rx_desc_pool); rx_desc_pool->owner = DP_WBM2SW_RBM; + rx_desc_pool->buf_size = RX_DATA_BUFFER_SIZE; + rx_desc_pool->buf_alignment = RX_DATA_BUFFER_ALIGNMENT; + /* For Rx buffers, WBM release ring is SW RING 3,for all pdev's */ - return dp_pdev_rx_buffers_attach(soc, pdev_id, dp_rxdma_srng, + ret_val = dp_rx_fst_attach(soc, pdev); + if ((ret_val != QDF_STATUS_SUCCESS) && + (ret_val != QDF_STATUS_E_NOSUPPORT)) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "RX Flow Search Table attach failed: pdev %d err %d", + pdev_id, ret_val); + return ret_val; + } + + return dp_pdev_rx_buffers_attach(soc, mac_for_pdev, dp_rxdma_srng, rx_desc_pool, rxdma_entries - 1); } @@ -2609,9 +3054,9 @@ dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev) nbuf_retry_count++) { /* Allocate a new skb */ nbuf = qdf_nbuf_alloc(soc->osdev, - RX_BUFFER_SIZE, + RX_DATA_BUFFER_SIZE, RX_BUFFER_RESERVATION, - RX_BUFFER_ALIGNMENT, + RX_DATA_BUFFER_ALIGNMENT, FALSE); if (!nbuf) { @@ -2622,7 +3067,7 @@ dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev) buf = qdf_nbuf_data(nbuf); - memset(buf, 0, RX_BUFFER_SIZE); + memset(buf, 0, RX_DATA_BUFFER_SIZE); ret = qdf_nbuf_map_single(soc->osdev, nbuf, QDF_DMA_FROM_DEVICE); @@ -2655,7 +3100,7 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, struct dp_peer *peer, uint32_t skip_len; l2_hdr_offset = - hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); + hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_tlv_hdr); if (qdf_unlikely(qdf_nbuf_is_frag(nbuf))) { skip_len = l2_hdr_offset; @@ -2666,9 +3111,11 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, struct dp_peer *peer, } QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf) = 1; + dp_rx_set_hdr_pad(nbuf, l2_hdr_offset); qdf_nbuf_pull_head(nbuf, skip_len); if (dp_rx_is_special_frame(nbuf, frame_mask)) { + qdf_nbuf_set_exc_frame(nbuf, 1); dp_rx_deliver_to_stack(soc, peer->vdev, peer, nbuf, NULL); return true; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h index 236df33e6407a863de0555ce7a807bfa8e291acd..9e30da08facefb99d9fef1242fa2aee3c9325c61 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h @@ -23,54 +23,40 @@ #include "dp_tx.h" #include "dp_peer.h" #include "dp_internal.h" -#include #ifdef RXDMA_OPTIMIZATION -#ifdef NO_RX_PKT_HDR_TLV -#define RX_BUFFER_ALIGNMENT 0 -#else -#define RX_BUFFER_ALIGNMENT 128 -#endif /* NO_RX_PKT_HDR_TLV */ +#ifndef RX_DATA_BUFFER_ALIGNMENT +#define RX_DATA_BUFFER_ALIGNMENT 128 +#endif +#ifndef RX_MONITOR_BUFFER_ALIGNMENT +#define RX_MONITOR_BUFFER_ALIGNMENT 128 +#endif #else /* RXDMA_OPTIMIZATION */ -#define RX_BUFFER_ALIGNMENT 4 +#define RX_DATA_BUFFER_ALIGNMENT 4 +#define RX_MONITOR_BUFFER_ALIGNMENT 4 #endif /* RXDMA_OPTIMIZATION */ #ifdef QCA_HOST2FW_RXBUF_RING +#define DP_WBM2SW_RBM HAL_RX_BUF_RBM_SW1_BM /* RBM value used for re-injecting defragmented packets into REO */ #define DP_DEFRAG_RBM HAL_RX_BUF_RBM_SW3_BM -#define DP_WBM2SW_RBM HAL_RX_BUF_RBM_SW1_BM - -/** - * For MCL cases, allocate as many RX descriptors as buffers in the SW2RXDMA - * ring. This value may need to be tuned later. - */ -#define DP_RX_DESC_ALLOC_MULTIPLIER 1 #else -#define DP_DEFRAG_RBM DP_WBM2SW_RBM #define DP_WBM2SW_RBM HAL_RX_BUF_RBM_SW3_BM - -/** - * AP use cases need to allocate more RX Descriptors than the number of - * entries avaialable in the SW2RXDMA buffer replenish ring. This is to account - * for frames sitting in REO queues, HW-HW DMA rings etc. Hence using a - * multiplication factor of 3, to allocate three times as many RX descriptors - * as RX buffers. - */ -#define DP_RX_DESC_ALLOC_MULTIPLIER 3 +#define DP_DEFRAG_RBM DP_WBM2SW_RBM #endif /* QCA_HOST2FW_RXBUF_RING */ #define RX_BUFFER_RESERVATION 0 #define DP_PEER_METADATA_PEER_ID_MASK 0x0000ffff #define DP_PEER_METADATA_PEER_ID_SHIFT 0 -#define DP_PEER_METADATA_VDEV_ID_MASK 0x00070000 +#define DP_PEER_METADATA_VDEV_ID_MASK 0x003f0000 #define DP_PEER_METADATA_VDEV_ID_SHIFT 16 #define DP_PEER_METADATA_PEER_ID_GET(_peer_metadata) \ (((_peer_metadata) & DP_PEER_METADATA_PEER_ID_MASK) \ >> DP_PEER_METADATA_PEER_ID_SHIFT) -#define DP_PEER_METADATA_ID_GET(_peer_metadata) \ +#define DP_PEER_METADATA_VDEV_ID_GET(_peer_metadata) \ (((_peer_metadata) & DP_PEER_METADATA_VDEV_ID_MASK) \ >> DP_PEER_METADATA_VDEV_ID_SHIFT) @@ -122,6 +108,7 @@ struct dp_rx_desc_dbg_info { * @in_use rx_desc is in use * @unmapped used to mark rx_desc an unmapped if the corresponding * nbuf is already unmapped + * @in_err_state : Nbuf sanity failed for this descriptor. */ struct dp_rx_desc { qdf_nbuf_t nbuf; @@ -133,7 +120,8 @@ struct dp_rx_desc { struct dp_rx_desc_dbg_info *dbg_info; #endif uint8_t in_use:1, - unmapped:1; + unmapped:1, + in_err_state:1; }; /* RX Descriptor Multi Page memory alloc related */ @@ -549,6 +537,24 @@ void *dp_rx_cookie_2_va_mon_status(struct dp_soc *soc, uint32_t cookie) } #endif /* RX_DESC_MULTI_PAGE_ALLOC */ +#ifdef DP_RX_DESC_COOKIE_INVALIDATE +static inline QDF_STATUS +dp_rx_cookie_check_and_invalidate(hal_ring_desc_t ring_desc) +{ + if (qdf_unlikely(HAL_RX_REO_BUF_COOKIE_INVALID_GET(ring_desc))) + return QDF_STATUS_E_FAILURE; + + HAL_RX_REO_BUF_COOKIE_INVALID_SET(ring_desc); + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS +dp_rx_cookie_check_and_invalidate(hal_ring_desc_t ring_desc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + void dp_rx_add_desc_list_to_free_list(struct dp_soc *soc, union dp_rx_desc_list_elem_t **local_desc_list, union dp_rx_desc_list_elem_t **tail, @@ -566,6 +572,7 @@ QDF_STATUS dp_rx_pdev_attach(struct dp_pdev *pdev); void dp_rx_pdev_detach(struct dp_pdev *pdev); +void dp_print_napi_stats(struct dp_soc *soc); /** * dp_rx_vdev_detach() - detach vdev from dp rx @@ -577,7 +584,8 @@ void dp_rx_pdev_detach(struct dp_pdev *pdev); QDF_STATUS dp_rx_vdev_detach(struct dp_vdev *vdev); uint32_t -dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint8_t reo_ring_num, +dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl, + uint8_t reo_ring_num, uint32_t quota); /** @@ -593,7 +601,7 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint8_t reo_ring_num, * Return: uint32_t: No. of elements processed */ uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_ring, uint32_t quota); + hal_ring_handle_t hal_ring_hdl, uint32_t quota); /** * dp_rx_wbm_err_process() - Processes error frames routed to WBM release ring @@ -609,11 +617,12 @@ uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, */ uint32_t dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_ring, uint32_t quota); + hal_ring_handle_t hal_ring_hdl, uint32_t quota); /** * dp_rx_sg_create() - create a frag_list for MSDUs which are spread across * multiple nbufs. + * @soc: core txrx main context * @nbuf: pointer to the first msdu of an amsdu. * * This function implements the creation of RX frag_list for cases @@ -621,7 +630,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, * * Return: returns the head nbuf which contains complete frag_list. */ -qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf); +qdf_nbuf_t dp_rx_sg_create(struct dp_soc *soc, qdf_nbuf_t nbuf); /* * dp_rx_desc_pool_alloc() - create a pool of software rx_descs @@ -679,6 +688,20 @@ void dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list, struct dp_peer *peer); #ifdef RX_DESC_DEBUG_CHECK +/** + * dp_rx_desc_paddr_sanity_check() - paddr sanity for ring desc vs rx_desc + * @rx_desc: rx descriptor + * @ring_paddr: paddr obatined from the ring + * + * Returns: QDF_STATUS + */ +static inline +bool dp_rx_desc_paddr_sanity_check(struct dp_rx_desc *rx_desc, + uint64_t ring_paddr) +{ + return (ring_paddr == qdf_nbuf_get_frag_paddr(rx_desc->nbuf, 0)); +} + /* * dp_rx_desc_alloc_dbg_info() - Alloc memory for rx descriptor debug * structure @@ -733,6 +756,13 @@ void dp_rx_desc_update_dbg_info(struct dp_rx_desc *rx_desc, } #else +static inline +bool dp_rx_desc_paddr_sanity_check(struct dp_rx_desc *rx_desc, + uint64_t ring_paddr) +{ + return true; +} + static inline void dp_rx_desc_alloc_dbg_info(struct dp_rx_desc *rx_desc) { @@ -785,8 +815,8 @@ void dp_rx_process_invalid_peer_wrapper(struct dp_soc *soc, qdf_nbuf_t mpdu, bool mpdu_done, uint8_t mac_id); void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, struct dp_peer *peer); -void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, - uint16_t peer_id, uint8_t tid, uint8_t *rx_tlv_hdr); +void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, + uint16_t peer_id, uint8_t tid); #define DP_RX_LIST_APPEND(head, tail, elem) \ @@ -802,16 +832,17 @@ void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, qdf_nbuf_set_next((tail), NULL); \ } while (0) -#ifndef BUILD_X86 +/*for qcn9000 emulation the pcie is complete phy and no address restrictions*/ +#if !defined(BUILD_X86) || defined(QCA_WIFI_QCN9000) static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, - qdf_dma_addr_t *paddr, struct dp_pdev *pdev) + qdf_dma_addr_t *paddr, struct rx_desc_pool *rx_desc_pool) { return QDF_STATUS_SUCCESS; } #else #define MAX_RETRY 100 static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, - qdf_dma_addr_t *paddr, struct dp_pdev *pdev) + qdf_dma_addr_t *paddr, struct rx_desc_pool *rx_desc_pool) { uint32_t nbuf_retry = 0; int32_t ret; @@ -842,10 +873,10 @@ static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, } *rx_netbuf = qdf_nbuf_alloc(dp_soc->osdev, - RX_BUFFER_SIZE, - RX_BUFFER_RESERVATION, - RX_BUFFER_ALIGNMENT, - FALSE); + rx_desc_pool->buf_size, + RX_BUFFER_RESERVATION, + rx_desc_pool->buf_alignment, + FALSE); if (qdf_unlikely(!(*rx_netbuf))) return QDF_STATUS_E_FAILURE; @@ -877,8 +908,9 @@ static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, * dp_rx_cookie_2_link_desc_va() - Converts cookie to a virtual address of * the MSDU Link Descriptor * @soc: core txrx main context - * @buf_info: buf_info include cookie that used to lookup virtual address of - * link descriptor Normally this is just an index into a per SOC array. + * @buf_info: buf_info includes cookie that is used to lookup + * virtual address of link descriptor after deriving the page id + * and the offset or index of the desc on the associatde page. * * This is the VA of the link descriptor, that HAL layer later uses to * retrieve the list of MSDU's for a given MPDU. @@ -890,16 +922,16 @@ void *dp_rx_cookie_2_link_desc_va(struct dp_soc *soc, struct hal_buf_info *buf_info) { void *link_desc_va; - uint32_t bank_id = LINK_DESC_COOKIE_BANK_ID(buf_info->sw_cookie); - - - /* TODO */ - /* Add sanity for cookie */ - - link_desc_va = soc->link_desc_banks[bank_id].base_vaddr + - (buf_info->paddr - - soc->link_desc_banks[bank_id].base_paddr); + struct qdf_mem_multi_page_t *pages; + uint16_t page_id = LINK_DESC_COOKIE_PAGE_ID(buf_info->sw_cookie); + pages = &soc->link_desc_pages; + if (!pages) + return NULL; + if (qdf_unlikely(page_id >= pages->num_pages)) + return NULL; + link_desc_va = pages->dma_pages[page_id].page_v_addr_start + + (buf_info->paddr - pages->dma_pages[page_id].page_p_addr); return link_desc_va; } @@ -921,15 +953,16 @@ void *dp_rx_cookie_2_mon_link_desc_va(struct dp_pdev *pdev, int mac_id) { void *link_desc_va; - int mac_for_pdev = dp_get_mac_id_for_mac(pdev->soc, mac_id); /* TODO */ /* Add sanity for cookie */ link_desc_va = - pdev->link_desc_banks[mac_for_pdev][buf_info->sw_cookie].base_vaddr + + pdev->soc->mon_link_desc_banks[mac_id][buf_info->sw_cookie] + .base_vaddr + (buf_info->paddr - - pdev->link_desc_banks[mac_for_pdev][buf_info->sw_cookie].base_paddr); + pdev->soc->mon_link_desc_banks[mac_id][buf_info->sw_cookie] + .base_paddr); return link_desc_va; } @@ -974,7 +1007,8 @@ static inline void dp_rx_wds_srcport_learn(struct dp_soc *soc, uint8_t *rx_tlv_hdr, struct dp_peer *ta_peer, - qdf_nbuf_t nbuf) + qdf_nbuf_t nbuf, + struct hal_rx_msdu_metadata msdu_metadata) { } #endif @@ -987,8 +1021,8 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, static inline void dp_rx_desc_dump(struct dp_rx_desc *rx_desc) { dp_info("rx_desc->nbuf: %pK, rx_desc->cookie: %d, rx_desc->pool_id: %d, rx_desc->in_use: %d, rx_desc->unmapped: %d", - rx_desc->nbuf, rx_desc->cookie, rx_desc->pool_id, - rx_desc->in_use, rx_desc->unmapped); + rx_desc->nbuf, rx_desc->cookie, rx_desc->pool_id, + rx_desc->in_use, rx_desc->unmapped); } /* @@ -1036,76 +1070,13 @@ static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, } #endif -#if defined(WLAN_SUPPORT_RX_TAG_STATISTICS) && \ - defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) -/** - * dp_rx_update_rx_protocol_tag_stats() - Increments the protocol tag stats - * for the given protocol type - * @soc: core txrx main context - * @pdev: TXRX pdev context for which stats should be incremented - * @protocol_index: Protocol index for which the stats should be incremented - * @ring_index: REO ring number from which this tag was received. - * - * Since HKv2 is a SMP, two or more cores may simultaneously receive packets - * of same type, and hence attempt to increment counters for the same protocol - * type at the same time. This creates the possibility of missing stats. - * - * For example, when two or more CPUs have each read the old tag value, V, - * for protocol type, P and each increment the value to V+1. Instead, the - * operations should have been sequenced to achieve a final value of V+2. - * - * In order to avoid this scenario, we can either use locks or store stats - * on a per-CPU basis. Since tagging happens in the core data path, locks - * are not preferred. Instead, we use a per-ring counter, since each CPU - * operates on a REO ring. - * - * Return: void - */ -static inline void dp_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev, - uint16_t protocol_index, - uint16_t ring_index) -{ - if (ring_index >= MAX_REO_DEST_RINGS) - return; - - pdev->reo_proto_tag_stats[ring_index][protocol_index].tag_ctr++; -} -#else -static inline void dp_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev, - uint16_t protocol_index, - uint16_t ring_index) -{ -} -#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\ + defined(WLAN_SUPPORT_RX_TAG_STATISTICS) ||\ + defined(WLAN_SUPPORT_RX_FLOW_TAG) +#include "dp_rx_tag.h" +#endif -#if defined(WLAN_SUPPORT_RX_TAG_STATISTICS) && \ - defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) -/** - * dp_rx_update_rx_err_protocol_tag_stats() - Increments the protocol tag stats - * for the given protocol type - * received from exception ring - * @soc: core txrx main context - * @pdev: TXRX pdev context for which stats should be incremented - * @protocol_index: Protocol index for which the stats should be incremented - * - * In HKv2, all exception packets are received on Ring-0 (along with normal - * Rx). Hence tags are maintained separately for exception ring as well. - * - * Return: void - */ -static inline -void dp_rx_update_rx_err_protocol_tag_stats(struct dp_pdev *pdev, - uint16_t protocol_index) -{ - pdev->rx_err_proto_tag_stats[protocol_index].tag_ctr++; -} -#else -static inline -void dp_rx_update_rx_err_protocol_tag_stats(struct dp_pdev *pdev, - uint16_t protocol_index) -{ -} -#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#ifndef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG /** * dp_rx_update_protocol_tag() - Reads CCE metadata from the RX MSDU end TLV * and set the corresponding tag in QDF packet @@ -1118,159 +1089,53 @@ void dp_rx_update_rx_err_protocol_tag_stats(struct dp_pdev *pdev, * @is_update_stats: flag to indicate whether to update stats or not * Return: void */ -#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG static inline void dp_rx_update_protocol_tag(struct dp_soc *soc, struct dp_vdev *vdev, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, uint16_t ring_index, bool is_reo_exception, bool is_update_stats) { - uint16_t cce_metadata = RX_PROTOCOL_TAG_START_OFFSET; - bool cce_match = false; - struct dp_pdev *pdev; - uint16_t protocol_tag = 0; - - if (qdf_unlikely(!vdev)) - return; - - pdev = vdev->pdev; - - if (qdf_likely(!pdev->is_rx_protocol_tagging_enabled)) - return; - - /* - * In case of raw frames, rx_attention and rx_msdu_end tlv - * may be stale or invalid. Do not tag such frames. - * Default decap_type is set to ethernet for monitor vdev, - * therefore, cannot check decap_type for monitor mode. - * We will call this only for eth frames from dp_rx_mon_dest.c. - */ - if (qdf_likely(!(pdev->monitor_vdev && pdev->monitor_vdev == vdev) && - (vdev->rx_decap_type != htt_cmn_pkt_type_ethernet))) - return; - - /* - * Check whether HW has filled in the CCE metadata in - * this packet, if not filled, just return - */ - if (qdf_likely(!hal_rx_msdu_cce_match_get(rx_tlv_hdr))) - return; - - cce_match = true; - /* Get the cce_metadata from RX MSDU TLV */ - cce_metadata = (hal_rx_msdu_cce_metadata_get(rx_tlv_hdr) & - RX_MSDU_END_16_CCE_METADATA_MASK); - /* - * Received CCE metadata should be within the - * valid limits - */ - qdf_assert_always((cce_metadata >= RX_PROTOCOL_TAG_START_OFFSET) && - (cce_metadata < (RX_PROTOCOL_TAG_START_OFFSET + - RX_PROTOCOL_TAG_MAX))); - - /* - * The CCE metadata received is just the - * packet_type + RX_PROTOCOL_TAG_START_OFFSET - */ - cce_metadata -= RX_PROTOCOL_TAG_START_OFFSET; - - /* - * Update the QDF packet with the user-specified - * tag/metadata by looking up tag value for - * received protocol type. - */ - protocol_tag = pdev->rx_proto_tag_map[cce_metadata].tag; - qdf_nbuf_set_rx_protocol_tag(nbuf, protocol_tag); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, - "Seq:%u decap:%u CCE Match:%d ProtoID:%u Tag:%u US:%d", - hal_rx_get_rx_sequence(rx_tlv_hdr), - vdev->rx_decap_type, cce_match, cce_metadata, - protocol_tag, is_update_stats); - - if (qdf_likely(!is_update_stats)) - return; - - if (qdf_unlikely(is_reo_exception)) { - dp_rx_update_rx_err_protocol_tag_stats(pdev, - cce_metadata); - } else { - dp_rx_update_rx_protocol_tag_stats(pdev, - cce_metadata, - ring_index); - } - } -#else +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + +#ifndef WLAN_SUPPORT_RX_FLOW_TAG +/** + * dp_rx_update_flow_tag() - Reads FSE metadata from the RX MSDU end TLV + * and set the corresponding tag in QDF packet + * @soc: core txrx main context + * @vdev: vdev on which the packet is received + * @nbuf: QDF pkt buffer on which the protocol tag should be set + * @rx_tlv_hdr: base address where the RX TLVs starts + * @is_update_stats: flag to indicate whether to update stats or not + * + * Return: void + */ static inline void -dp_rx_update_protocol_tag(struct dp_soc *soc, struct dp_vdev *vdev, - qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, - uint16_t ring_index, - bool is_reo_exception, bool is_update_stats) +dp_rx_update_flow_tag(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, bool update_stats) { - /* Stub API */ } -#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ +#if !defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) &&\ + !defined(WLAN_SUPPORT_RX_FLOW_TAG) /** - * dp_rx_mon_update_protocol_tag() - Performs necessary checks for monitor mode - * and then tags appropriate packets + * dp_rx_mon_update_protocol_flow_tag() - Performs necessary checks for monitor + * mode and then tags appropriate packets * @soc: core txrx main context * @vdev: pdev on which packet is received * @msdu: QDF packet buffer on which the protocol tag should be set * @rx_desc: base address where the RX TLVs start * Return: void */ -#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG static inline -void dp_rx_mon_update_protocol_tag(struct dp_soc *soc, struct dp_pdev *dp_pdev, - qdf_nbuf_t msdu, void *rx_desc) +void dp_rx_mon_update_protocol_flow_tag(struct dp_soc *soc, + struct dp_pdev *dp_pdev, + qdf_nbuf_t msdu, void *rx_desc) { - uint32_t msdu_ppdu_id = 0; - struct mon_rx_status *mon_recv_status; - - if (qdf_likely(!dp_pdev->is_rx_protocol_tagging_enabled)) - return; - - if (qdf_likely(!dp_pdev->monitor_vdev)) - return; - - if (qdf_likely(1 != dp_pdev->ppdu_info.rx_status.rxpcu_filter_pass)) - return; - - msdu_ppdu_id = HAL_RX_HW_DESC_GET_PPDUID_GET(rx_desc); - - if (msdu_ppdu_id != dp_pdev->ppdu_info.com_info.ppdu_id) { - QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_ERROR, - "msdu_ppdu_id=%x,com_info.ppdu_id=%x", - msdu_ppdu_id, - dp_pdev->ppdu_info.com_info.ppdu_id); - return; - } - - /* - * Update the protocol tag in SKB for packets received on BSS. - * Do not update tag stats since it would double actual received count - */ - mon_recv_status = &dp_pdev->ppdu_info.rx_status; - if (mon_recv_status->frame_control_info_valid && - ((mon_recv_status->frame_control & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_DATA)) { - dp_rx_update_protocol_tag(soc, - dp_pdev->monitor_vdev, - msdu, rx_desc, - MAX_REO_DEST_RINGS, - false, false); - } } -#else -static inline -void dp_rx_mon_update_protocol_tag(struct dp_soc *soc, struct dp_pdev *dp_pdev, - qdf_nbuf_t msdu, void *rx_desc) -{ - /* Stub API */ -} -#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG || WLAN_SUPPORT_RX_FLOW_TAG */ + /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization @@ -1296,6 +1161,24 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, union dp_rx_desc_list_elem_t **tail, const char *func_name); +/* + * dp_pdev_rx_buffers_attach() - replenish rxdma ring with rx nbufs + * called during dp rx initialization + * + * @soc: core txrx main context + * @mac_id: mac_id which is one of 3 mac_ids + * @dp_rxdma_srng: dp rxdma circular ring + * @rx_desc_pool: Pointer to free Rx descriptor pool + * @num_req_buffers: number of buffer to be replenished + * + * Return: return success or failure + */ +QDF_STATUS +dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, + struct dp_srng *dp_rxdma_srng, + struct rx_desc_pool *rx_desc_pool, + uint32_t num_req_buffers); + /** * dp_rx_link_desc_return() - Return a MPDU link descriptor to HW * (WBM), following error handling @@ -1304,14 +1187,13 @@ QDF_STATUS __dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, * @buf_addr_info: opaque pointer to the REO error ring descriptor * @buf_addr_info: void pointer to the buffer_addr_info * @bm_action: put to idle_list or release to msdu_list - * Return: QDF_STATUS + * + * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS */ QDF_STATUS -dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc, uint8_t bm_action); +dp_rx_link_desc_return(struct dp_soc *soc, hal_ring_desc_t ring_desc, + uint8_t bm_action); -QDF_STATUS -dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng, - void *buf_addr_info, uint8_t bm_action); /** * dp_rx_link_desc_return_by_addr - Return a MPDU link descriptor to * (WBM) by address @@ -1319,11 +1201,12 @@ dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng, * @soc: core DP main context * @link_desc_addr: link descriptor addr * - * Return: QDF_STATUS + * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS */ QDF_STATUS -dp_rx_link_desc_return_by_addr(struct dp_soc *soc, void *link_desc_addr, - uint8_t bm_action); +dp_rx_link_desc_return_by_addr(struct dp_soc *soc, + hal_buff_addrinfo_t link_desc_addr, + uint8_t bm_action); /** * dp_rxdma_err_process() - RxDMA error processing functionality @@ -1359,8 +1242,10 @@ dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev); * * Return: void */ -void dp_rx_dump_info_and_assert(struct dp_soc *soc, void *hal_ring, - void *ring_desc, struct dp_rx_desc *rx_desc); +void dp_rx_dump_info_and_assert(struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc); void dp_rx_compute_delay(struct dp_vdev *vdev, qdf_nbuf_t nbuf); #ifdef RX_DESC_DEBUG_CHECK @@ -1413,6 +1298,24 @@ void dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, struct dp_peer *peer, uint8_t err_code, uint8_t mac_id); +#ifndef QCA_MULTIPASS_SUPPORT +static inline +bool dp_rx_multipass_process(struct dp_peer *peer, qdf_nbuf_t nbuf, uint8_t tid) +{ + return false; +} +#else +bool dp_rx_multipass_process(struct dp_peer *peer, qdf_nbuf_t nbuf, + uint8_t tid); +#endif + +#ifndef WLAN_RX_PKT_CAPTURE_ENH +static inline +void dp_peer_set_rx_capture_enabled(struct dp_peer *peer_handle, bool value) +{ +} +#endif + /** * dp_rx_deliver_to_stack() - deliver pkts to network stack * Caller to hold peer refcount and check for valid peer @@ -1430,4 +1333,17 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc, qdf_nbuf_t nbuf_head, qdf_nbuf_t nbuf_tail); +/* + * dp_rx_link_desc_refill_duplicate_check() - check if link desc duplicate + to refill + * @soc: DP SOC handle + * @buf_info: the last link desc buf info + * @ring_buf_info: current buf address pointor including link desc + * + * return: none. + */ +void dp_rx_link_desc_refill_duplicate_check( + struct dp_soc *soc, + struct hal_buf_info *buf_info, + hal_buff_addrinfo_t ring_buf_info); #endif /* _DP_RX_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c index 2b1d1e04b2a4f92ad114afbcc7a8d3140676a603..e807a6d00ee3bba9df329ac94fac0acabb8b3f3e 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -96,13 +96,15 @@ static void dp_rx_return_head_frag_desc(struct dp_peer *peer, struct rx_desc_pool *rx_desc_pool; union dp_rx_desc_list_elem_t *head = NULL; union dp_rx_desc_list_elem_t *tail = NULL; + uint8_t pool_id; pdev = peer->vdev->pdev; soc = pdev->soc; if (peer->rx_tid[tid].head_frag_desc) { - dp_rxdma_srng = &pdev->rx_refill_buf_ring; - rx_desc_pool = &soc->rx_desc_buf[pdev->pdev_id]; + pool_id = peer->rx_tid[tid].head_frag_desc->pool_id; + dp_rxdma_srng = &soc->rx_refill_buf_ring[pool_id]; + rx_desc_pool = &soc->rx_desc_buf[pool_id]; dp_rx_add_to_free_desc_list(&head, &tail, peer->rx_tid[tid].head_frag_desc); @@ -132,8 +134,7 @@ static void dp_rx_return_head_frag_desc(struct dp_peer *peer, void dp_rx_reorder_flush_frag(struct dp_peer *peer, unsigned int tid) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Flushing TID %d"), tid); + dp_info_rl("Flushing TID %d", tid); if (!peer) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -237,8 +238,8 @@ static void dp_rx_defrag_waitlist_add(struct dp_peer *peer, unsigned tid) struct dp_soc *psoc = peer->vdev->pdev->soc; struct dp_rx_tid *rx_reorder = &peer->rx_tid[tid]; - dp_debug("Adding TID %u to waitlist for peer %pK at MAC address %pM", - tid, peer, peer->mac_addr.raw); + dp_debug("Adding TID %u to waitlist for peer %pK at MAC address "QDF_MAC_ADDR_FMT, + tid, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* TODO: use LIST macros instead of TAIL macros */ qdf_spin_lock_bh(&psoc->rx.defrag.defrag_lock); @@ -266,8 +267,8 @@ void dp_rx_defrag_waitlist_remove(struct dp_peer *peer, unsigned tid) struct dp_rx_tid *rx_reorder; struct dp_rx_tid *tmp; - dp_debug("Removing TID %u to waitlist for peer %pK at MAC address %pM", - tid, peer, peer->mac_addr.raw); + dp_debug("Removing TID %u to waitlist for peer %pK at MAC address "QDF_MAC_ADDR_FMT, + tid, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); if (tid >= DP_MAX_TIDS) { dp_err("TID out of bounds: %d", tid); @@ -328,6 +329,7 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti rx_desc_info = qdf_nbuf_data(frag); cur_fragno = dp_rx_frag_get_mpdu_frag_number(rx_desc_info); + dp_debug("cur_fragno %d\n", cur_fragno); /* If this is the first fragment */ if (!(*head_addr)) { *head_addr = *tail_addr = frag; @@ -360,10 +362,12 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti while ((cur_fragno > head_fragno) && cur) { prev = cur; cur = qdf_nbuf_next(cur); - rx_desc_info = qdf_nbuf_data(cur); - head_fragno = - dp_rx_frag_get_mpdu_frag_number( + if (cur) { + rx_desc_info = qdf_nbuf_data(cur); + head_fragno = + dp_rx_frag_get_mpdu_frag_number( rx_desc_info); + } } if (cur_fragno == head_fragno) { @@ -399,6 +403,8 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti if (!next) { *all_frag_present = 1; return QDF_STATUS_SUCCESS; + } else { + /* revisit */ } } @@ -422,7 +428,7 @@ static QDF_STATUS dp_rx_defrag_fraglist_insert(struct dp_peer *peer, unsigned ti static QDF_STATUS dp_rx_defrag_tkip_decap(qdf_nbuf_t msdu, uint16_t hdrlen) { uint8_t *ivp, *orig_hdr; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; /* start of 802.11 header info */ orig_hdr = (uint8_t *)(qdf_nbuf_data(msdu) + rx_desc_len); @@ -452,7 +458,7 @@ static QDF_STATUS dp_rx_defrag_tkip_decap(qdf_nbuf_t msdu, uint16_t hdrlen) static QDF_STATUS dp_rx_defrag_ccmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen) { uint8_t *ivp, *orig_hdr; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; /* start of the 802.11 header */ orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len); @@ -479,7 +485,7 @@ static QDF_STATUS dp_rx_defrag_ccmp_demic(qdf_nbuf_t nbuf, uint16_t hdrlen) static QDF_STATUS dp_rx_defrag_ccmp_decap(qdf_nbuf_t nbuf, uint16_t hdrlen) { uint8_t *ivp, *origHdr; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; origHdr = (uint8_t *) (qdf_nbuf_data(nbuf) + rx_desc_len); ivp = origHdr + hdrlen; @@ -504,7 +510,7 @@ static QDF_STATUS dp_rx_defrag_ccmp_decap(qdf_nbuf_t nbuf, uint16_t hdrlen) static QDF_STATUS dp_rx_defrag_wep_decap(qdf_nbuf_t msdu, uint16_t hdrlen) { uint8_t *origHdr; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; origHdr = (uint8_t *) (qdf_nbuf_data(msdu) + rx_desc_len); qdf_mem_move(origHdr + dp_f_wep.ic_header, origHdr, hdrlen); @@ -516,13 +522,14 @@ static QDF_STATUS dp_rx_defrag_wep_decap(qdf_nbuf_t msdu, uint16_t hdrlen) /* * dp_rx_defrag_hdrsize(): Calculate the header size of the received fragment + * @soc: soc handle * @nbuf: Pointer to the fragment * * Calculate the header size of the received fragment * * Returns: header size (uint16_t) */ -static uint16_t dp_rx_defrag_hdrsize(qdf_nbuf_t nbuf) +static uint16_t dp_rx_defrag_hdrsize(struct dp_soc *soc, qdf_nbuf_t nbuf) { uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf); uint16_t size = sizeof(struct ieee80211_frame); @@ -531,9 +538,11 @@ static uint16_t dp_rx_defrag_hdrsize(qdf_nbuf_t nbuf) uint8_t frm_ctrl_valid; uint16_t frm_ctrl_field; - to_ds = hal_rx_mpdu_get_to_ds(rx_tlv_hdr); - fr_ds = hal_rx_mpdu_get_fr_ds(rx_tlv_hdr); - frm_ctrl_valid = hal_rx_get_mpdu_frame_control_valid(rx_tlv_hdr); + to_ds = hal_rx_mpdu_get_to_ds(soc->hal_soc, rx_tlv_hdr); + fr_ds = hal_rx_mpdu_get_fr_ds(soc->hal_soc, rx_tlv_hdr); + frm_ctrl_valid = + hal_rx_get_mpdu_frame_control_valid(soc->hal_soc, + rx_tlv_hdr); frm_ctrl_field = hal_rx_get_frame_ctrl_field(rx_tlv_hdr); if (to_ds && fr_ds) @@ -634,7 +643,7 @@ static QDF_STATUS dp_rx_defrag_mic(const uint8_t *key, qdf_nbuf_t wbuf, uint32_t l, r; const uint8_t *data; uint32_t space; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; dp_rx_defrag_michdr((struct ieee80211_frame *)(qdf_nbuf_data(wbuf) + rx_desc_len), hdr); @@ -802,14 +811,55 @@ static QDF_STATUS dp_rx_defrag_tkip_demic(const uint8_t *key, */ static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf, uint16_t hdrsize) { - qdf_nbuf_pull_head(nbuf, - RX_PKT_TLVS_LEN + hdrsize); + struct rx_pkt_tlvs *rx_pkt_tlv = + (struct rx_pkt_tlvs *)qdf_nbuf_data(nbuf); + struct rx_mpdu_info *rx_mpdu_info_details = + &rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + dp_debug("pn_31_0 0x%x pn_63_32 0x%x pn_95_64 0x%x pn_127_96 0x%x\n", + rx_mpdu_info_details->pn_31_0, rx_mpdu_info_details->pn_63_32, + rx_mpdu_info_details->pn_95_64, + rx_mpdu_info_details->pn_127_96); + + qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + hdrsize); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "%s: final pktlen %d .11len %d", __func__, (uint32_t)qdf_nbuf_len(nbuf), hdrsize); } +/* + * dp_rx_defrag_pn_check(): Check the PN of current fragmented with prev PN + * @msdu: msdu to get the current PN + * @cur_pn128: PN extracted from current msdu + * @prev_pn128: Prev PN + * + * Returns: 0 on success, non zero on failure + */ +static int dp_rx_defrag_pn_check(qdf_nbuf_t msdu, + uint64_t *cur_pn128, uint64_t *prev_pn128) +{ + struct rx_pkt_tlvs *rx_pkt_tlv = + (struct rx_pkt_tlvs *)qdf_nbuf_data(msdu); + struct rx_mpdu_info *rx_mpdu_info_details = + &rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + int out_of_order = 0; + + cur_pn128[0] = rx_mpdu_info_details->pn_31_0; + cur_pn128[0] |= + ((uint64_t)rx_mpdu_info_details->pn_63_32 << 32); + cur_pn128[1] = rx_mpdu_info_details->pn_95_64; + cur_pn128[1] |= + ((uint64_t)rx_mpdu_info_details->pn_127_96 << 32); + + if (cur_pn128[1] == prev_pn128[1]) + out_of_order = (cur_pn128[0] - prev_pn128[0] != 1); + else + out_of_order = (cur_pn128[1] - prev_pn128[1] != 1); + + return out_of_order; +} + /* * dp_rx_construct_fraglist(): Construct a nbuf fraglist * @peer: Pointer to the peer @@ -820,15 +870,53 @@ static void dp_rx_frag_pull_hdr(qdf_nbuf_t nbuf, uint16_t hdrsize) * * Returns: None */ -static void -dp_rx_construct_fraglist(struct dp_peer *peer, - qdf_nbuf_t head, uint16_t hdrsize) +static int +dp_rx_construct_fraglist(struct dp_peer *peer, int tid, qdf_nbuf_t head, + uint16_t hdrsize) { qdf_nbuf_t msdu = qdf_nbuf_next(head); qdf_nbuf_t rx_nbuf = msdu; + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; uint32_t len = 0; + uint64_t cur_pn128[2] = {0, 0}, prev_pn128[2]; + int out_of_order = 0; + int index; + int needs_pn_check = 0; + + prev_pn128[0] = rx_tid->pn128[0]; + prev_pn128[1] = rx_tid->pn128[1]; + + index = hal_rx_msdu_is_wlan_mcast(msdu) ? dp_sec_mcast : dp_sec_ucast; + if (qdf_likely(peer->security[index].sec_type != cdp_sec_type_none)) + needs_pn_check = 1; while (msdu) { + if (qdf_likely(needs_pn_check)) + out_of_order = dp_rx_defrag_pn_check(msdu, + &cur_pn128[0], + &prev_pn128[0]); + + if (qdf_unlikely(out_of_order)) { + dp_info_rl("cur_pn128[0] 0x%llx cur_pn128[1] 0x%llx prev_pn128[0] 0x%llx prev_pn128[1] 0x%llx", + cur_pn128[0], cur_pn128[1], + prev_pn128[0], prev_pn128[1]); + return QDF_STATUS_E_FAILURE; + } + + prev_pn128[0] = cur_pn128[0]; + prev_pn128[1] = cur_pn128[1]; + + /* + * Broadcast and multicast frames should never be fragmented. + * Iterating through all msdus and dropping fragments if even + * one of them has mcast/bcast destination address. + */ + if (hal_rx_msdu_is_wlan_mcast(msdu)) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "Dropping multicast/broadcast fragments"); + return QDF_STATUS_E_FAILURE; + } + dp_rx_frag_pull_hdr(msdu, hdrsize); len += qdf_nbuf_len(msdu); msdu = qdf_nbuf_next(msdu); @@ -844,6 +932,8 @@ dp_rx_construct_fraglist(struct dp_peer *peer, (uint32_t)qdf_nbuf_len(head), (uint32_t)qdf_nbuf_len(rx_nbuf), (uint32_t)(head->data_len)); + + return QDF_STATUS_SUCCESS; } /** @@ -866,21 +956,36 @@ static void dp_rx_defrag_err(struct dp_vdev *vdev, qdf_nbuf_t nbuf) { struct ol_if_ops *tops = NULL; struct dp_pdev *pdev = vdev->pdev; - int rx_desc_len = sizeof(struct rx_pkt_tlvs); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; uint8_t *orig_hdr; struct ieee80211_frame *wh; + struct cdp_rx_mic_err_info mic_failure_info; orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len); wh = (struct ieee80211_frame *)orig_hdr; + qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.da_mac_addr, + (struct qdf_mac_addr *)&wh->i_addr1); + qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.ta_mac_addr, + (struct qdf_mac_addr *)&wh->i_addr2); + mic_failure_info.key_id = 0; + mic_failure_info.multicast = + IEEE80211_IS_MULTICAST(wh->i_addr1); + qdf_mem_zero(mic_failure_info.tsc, MIC_SEQ_CTR_SIZE); + mic_failure_info.frame_type = cdp_rx_frame_type_802_11; + mic_failure_info.data = (uint8_t *)wh; + mic_failure_info.vdev_id = vdev->vdev_id; + tops = pdev->soc->cdp_soc.ol_ops; if (tops->rx_mic_error) - tops->rx_mic_error(pdev->ctrl_pdev, vdev->vdev_id, wh); + tops->rx_mic_error(pdev->soc->ctrl_psoc, pdev->pdev_id, + &mic_failure_info); } /* * dp_rx_defrag_nwifi_to_8023(): Transcap 802.11 to 802.3 + * @soc: dp soc handle * @nbuf: Pointer to the fragment buffer * @hdrsize: Size of headers * @@ -889,7 +994,8 @@ static void dp_rx_defrag_err(struct dp_vdev *vdev, qdf_nbuf_t nbuf) * Returns: None */ static void -dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf, uint16_t hdrsize) +dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc, struct dp_peer *peer, int tid, + qdf_nbuf_t nbuf, uint16_t hdrsize) { struct llc_snap_hdr_t *llchdr; struct ethernet_hdr_t *eth_hdr; @@ -897,6 +1003,21 @@ dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf, uint16_t hdrsize) uint16_t fc = 0; union dp_align_mac_addr mac_addr; uint8_t *rx_desc_info = qdf_mem_malloc(RX_PKT_TLVS_LEN); + struct rx_pkt_tlvs *rx_pkt_tlv = + (struct rx_pkt_tlvs *)qdf_nbuf_data(nbuf); + struct rx_mpdu_info *rx_mpdu_info_details = + &rx_pkt_tlv->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + + dp_debug("head_nbuf pn_31_0 0x%x pn_63_32 0x%x pn_95_64 0x%x pn_127_96 0x%x\n", + rx_mpdu_info_details->pn_31_0, rx_mpdu_info_details->pn_63_32, + rx_mpdu_info_details->pn_95_64, + rx_mpdu_info_details->pn_127_96); + + rx_tid->pn128[0] = rx_mpdu_info_details->pn_31_0; + rx_tid->pn128[0] |= ((uint64_t)rx_mpdu_info_details->pn_63_32 << 32); + rx_tid->pn128[1] = rx_mpdu_info_details->pn_95_64; + rx_tid->pn128[1] |= ((uint64_t)rx_mpdu_info_details->pn_127_96 << 32); if (!rx_desc_info) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -917,50 +1038,51 @@ dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf, uint16_t hdrsize) eth_hdr = (struct ethernet_hdr_t *)(qdf_nbuf_data(nbuf)); - if (hal_rx_get_mpdu_frame_control_valid(rx_desc_info)) + if (hal_rx_get_mpdu_frame_control_valid(soc->hal_soc, + rx_desc_info)) fc = hal_rx_get_frame_ctrl_field(rx_desc_info); dp_debug("%s: frame control type: 0x%x", __func__, fc); switch (((fc & 0xff00) >> 8) & IEEE80211_FC1_DIR_MASK) { case IEEE80211_FC1_DIR_NODS: - hal_rx_mpdu_get_addr1(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr1(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->dest_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); - hal_rx_mpdu_get_addr2(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr2(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->src_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); break; case IEEE80211_FC1_DIR_TODS: - hal_rx_mpdu_get_addr3(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr3(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->dest_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); - hal_rx_mpdu_get_addr2(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr2(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->src_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); break; case IEEE80211_FC1_DIR_FROMDS: - hal_rx_mpdu_get_addr1(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr1(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->dest_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); - hal_rx_mpdu_get_addr3(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr3(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->src_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); break; case IEEE80211_FC1_DIR_DSTODS: - hal_rx_mpdu_get_addr3(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr3(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->dest_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); - hal_rx_mpdu_get_addr4(rx_desc_info, - &mac_addr.raw[0]); + hal_rx_mpdu_get_addr4(soc->hal_soc, rx_desc_info, + &mac_addr.raw[0]); qdf_mem_copy(eth_hdr->src_addr, &mac_addr.raw[0], QDF_MAC_ADDR_SIZE); break; @@ -978,6 +1100,102 @@ dp_rx_defrag_nwifi_to_8023(qdf_nbuf_t nbuf, uint16_t hdrsize) qdf_mem_free(rx_desc_info); } +#ifdef RX_DEFRAG_DO_NOT_REINJECT +/* + * dp_rx_defrag_deliver(): Deliver defrag packet to stack + * @peer: Pointer to the peer + * @tid: Transmit Identifier + * @head: Nbuf to be delivered + * + * Returns: None + */ +static inline void dp_rx_defrag_deliver(struct dp_peer *peer, + unsigned int tid, + qdf_nbuf_t head) +{ + struct dp_vdev *vdev = peer->vdev; + struct dp_soc *soc = vdev->pdev->soc; + qdf_nbuf_t deliver_list_head = NULL; + qdf_nbuf_t deliver_list_tail = NULL; + uint8_t *rx_tlv_hdr; + + rx_tlv_hdr = qdf_nbuf_data(head); + + QDF_NBUF_CB_RX_VDEV_ID(head) = vdev->vdev_id; + qdf_nbuf_set_tid_val(head, tid); + qdf_nbuf_pull_head(head, RX_PKT_TLVS_LEN); + + DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, + head); + dp_rx_deliver_to_stack(soc, vdev, peer, deliver_list_head, + deliver_list_tail); +} + +/* + * dp_rx_defrag_reo_reinject(): Reinject the fragment chain back into REO + * @peer: Pointer to the peer + * @tid: Transmit Identifier + * @head: Buffer to be reinjected back + * + * Reinject the fragment chain back into REO + * + * Returns: QDF_STATUS + */ +static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, + unsigned int tid, qdf_nbuf_t head) +{ + struct dp_rx_reorder_array_elem *rx_reorder_array_elem; + + rx_reorder_array_elem = peer->rx_tid[tid].array; + + dp_rx_defrag_deliver(peer, tid, head); + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + dp_rx_return_head_frag_desc(peer, tid); + + return QDF_STATUS_SUCCESS; +} +#else + +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +/** + * dp_rx_reinject_ring_record_entry() - Record reinject ring history + * @soc: Datapath soc structure + * @paddr: paddr of the buffer reinjected to SW2REO ring + * @sw_cookie: SW cookie of the buffer reinjected to SW2REO ring + * @rbm: Return buffer manager of the buffer reinjected to SW2REO ring + * + * Returns: None + */ +static inline void +dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr, + uint32_t sw_cookie, uint8_t rbm) +{ + struct dp_buf_info_record *record; + uint32_t idx; + + if (qdf_unlikely(!soc->rx_reinject_ring_history)) + return; + + idx = dp_history_get_next_index(&soc->rx_reinject_ring_history->index, + DP_RX_REINJECT_HIST_MAX); + + /* No NULL check needed for record since its an array */ + record = &soc->rx_reinject_ring_history->entry[idx]; + + record->timestamp = qdf_get_log_timestamp(); + record->hbi.paddr = paddr; + record->hbi.sw_cookie = sw_cookie; + record->hbi.rbm = rbm; +} +#else +static inline void +dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr, + uint32_t sw_cookie, uint8_t rbm) +{ +} +#endif + /* * dp_rx_defrag_reo_reinject(): Reinject the fragment chain back into REO * @peer: Pointer to the peer @@ -1002,14 +1220,21 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, uint32_t nbuf_len, seq_no, dst_ind; uint32_t *mpdu_wrd; uint32_t ret, cookie; - - void *dst_ring_desc = + hal_ring_desc_t dst_ring_desc = peer->rx_tid[tid].dst_ring_desc; - void *hal_srng = soc->reo_reinject_ring.hal_srng; + hal_ring_handle_t hal_srng = soc->reo_reinject_ring.hal_srng; struct dp_rx_desc *rx_desc = peer->rx_tid[tid].head_frag_desc; struct dp_rx_reorder_array_elem *rx_reorder_array_elem = peer->rx_tid[tid].array; qdf_nbuf_t nbuf_head; + struct rx_desc_pool *rx_desc_pool = NULL; + void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(dst_ring_desc); + + /* do duplicate link desc address check */ + dp_rx_link_desc_refill_duplicate_check( + soc, + &soc->last_op_info.reo_reinject_link_desc, + buf_addr_info); nbuf_head = dp_ipa_handle_rx_reo_reinject(soc, head); if (qdf_unlikely(!nbuf_head)) { @@ -1026,8 +1251,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, ent_ring_desc = hal_srng_src_get_next(soc->hal_soc, hal_srng); if (!ent_ring_desc) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "HAL src ring next entry NULL"); + dp_err_rl("HAL src ring next entry NULL"); return QDF_STATUS_E_FAILURE; } @@ -1035,11 +1259,9 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info); - qdf_assert(link_desc_va); - - msdu0 = (uint8_t *)link_desc_va + - RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET; + qdf_assert_always(link_desc_va); + msdu0 = hal_rx_msdu0_buffer_addr_lsb(soc->hal_soc, link_desc_va); nbuf_len = qdf_nbuf_len(head) - RX_PKT_TLVS_LEN; HAL_RX_UNIFORM_HDR_SET(link_desc_va, OWNER, UNI_DESC_OWNER_SW); @@ -1047,8 +1269,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, UNI_DESC_BUF_TYPE_RX_MSDU_LINK); /* msdu reconfig */ - msdu_desc_info = (uint8_t *)msdu0 + - RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET; + msdu_desc_info = hal_rx_msdu_desc_info_ptr_get(soc->hal_soc, msdu0); dst_ind = hal_rx_msdu_reo_dst_ind_get(soc->hal_soc, link_desc_va); @@ -1094,8 +1315,9 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, dp_ipa_handle_rx_buf_smmu_mapping(soc, head, true); paddr = qdf_nbuf_get_frag_paddr(head, 0); + rx_desc_pool = &soc->rx_desc_buf[pdev->lmac_id]; - ret = check_x86_paddr(soc, &head, &paddr, pdev); + ret = check_x86_paddr(soc, &head, &paddr, rx_desc_pool); if (ret == QDF_STATUS_E_FAILURE) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -1114,17 +1336,17 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, return QDF_STATUS_E_FAILURE; } + dp_rx_reinject_ring_record_entry(soc, paddr, cookie, DP_DEFRAG_RBM); paddr = (uint64_t)buf_info.paddr; /* buf addr */ hal_rxdma_buff_addr_info_set(ent_ring_desc, paddr, buf_info.sw_cookie, HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST); /* mpdu desc info */ - ent_mpdu_desc_info = (uint8_t *)ent_ring_desc + - RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET; - - dst_mpdu_desc_info = (uint8_t *)dst_ring_desc + - REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET; + ent_mpdu_desc_info = hal_ent_mpdu_desc_info(soc->hal_soc, + ent_ring_desc); + dst_mpdu_desc_info = hal_dst_mpdu_desc_info(soc->hal_soc, + dst_ring_desc); qdf_mem_copy(ent_mpdu_desc_info, dst_mpdu_desc_info, sizeof(struct rx_mpdu_desc_info)); @@ -1167,6 +1389,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer, "%s: reinjection done !", __func__); return QDF_STATUS_SUCCESS; } +#endif /* * dp_rx_defrag(): Defragment the fragment chain @@ -1191,7 +1414,7 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, struct dp_soc *soc = vdev->pdev->soc; uint8_t status = 0; - hdr_space = dp_rx_defrag_hdrsize(cur); + hdr_space = dp_rx_defrag_hdrsize(soc, cur); index = hal_rx_msdu_is_wlan_mcast(cur) ? dp_sec_mcast : dp_sec_ucast; @@ -1278,41 +1501,34 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, hdr_space += dp_f_wep.ic_header; break; default: - QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_ERROR, - "dp_rx_defrag: Did not match any security type"); break; } if (tkip_demic) { msdu = frag_list_head; - if (soc->cdp_soc.ol_ops->rx_frag_tkip_demic) { - status = soc->cdp_soc.ol_ops->rx_frag_tkip_demic( - (void *)peer->ctrl_peer, msdu, hdr_space); - } else { - qdf_mem_copy(key, - &peer->security[index].michael_key[0], - IEEE80211_WEP_MICLEN); - status = dp_rx_defrag_tkip_demic(key, msdu, - RX_PKT_TLVS_LEN + - hdr_space); + qdf_mem_copy(key, + &peer->security[index].michael_key[0], + IEEE80211_WEP_MICLEN); + status = dp_rx_defrag_tkip_demic(key, msdu, + RX_PKT_TLVS_LEN + + hdr_space); - if (status) { - dp_rx_defrag_err(vdev, frag_list_head); + if (status) { + dp_rx_defrag_err(vdev, frag_list_head); - QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_ERROR, - "%s: TKIP demic failed status %d", - __func__, status); + QDF_TRACE(QDF_MODULE_ID_TXRX, + QDF_TRACE_LEVEL_ERROR, + "%s: TKIP demic failed status %d", + __func__, status); - return QDF_STATUS_E_DEFRAG_ERROR; - } + return QDF_STATUS_E_DEFRAG_ERROR; } } /* Convert the header to 802.3 header */ - dp_rx_defrag_nwifi_to_8023(frag_list_head, hdr_space); - dp_rx_construct_fraglist(peer, frag_list_head, hdr_space); + dp_rx_defrag_nwifi_to_8023(soc, peer, tid, frag_list_head, hdr_space); + if (dp_rx_construct_fraglist(peer, tid, frag_list_head, hdr_space)) + return QDF_STATUS_E_DEFRAG_ERROR; return QDF_STATUS_SUCCESS; } @@ -1335,8 +1551,8 @@ void dp_rx_defrag_cleanup(struct dp_peer *peer, unsigned tid) rx_reorder_array_elem->head = NULL; rx_reorder_array_elem->tail = NULL; } else { - dp_info("Cleanup self peer %pK and TID %u at MAC address %pM", - peer, tid, peer->mac_addr.raw); + dp_info("Cleanup self peer %pK and TID %u at MAC address "QDF_MAC_ADDR_FMT, + peer, tid, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); } /* Free up saved ring descriptors */ @@ -1355,8 +1571,11 @@ void dp_rx_defrag_cleanup(struct dp_peer *peer, unsigned tid) * * Returns: None */ -static QDF_STATUS dp_rx_defrag_save_info_from_ring_desc(void *ring_desc, - struct dp_rx_desc *rx_desc, struct dp_peer *peer, unsigned tid) +static QDF_STATUS +dp_rx_defrag_save_info_from_ring_desc(hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + struct dp_peer *peer, + unsigned int tid) { void *dst_ring_desc = qdf_mem_malloc( sizeof(struct reo_destination_ring)); @@ -1388,13 +1607,14 @@ static QDF_STATUS dp_rx_defrag_save_info_from_ring_desc(void *ring_desc, * * Returns: QDF_STATUS */ -static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, - void *ring_desc, - union dp_rx_desc_list_elem_t **head, - union dp_rx_desc_list_elem_t **tail, - struct hal_rx_mpdu_desc_info *mpdu_desc_info, - unsigned tid, struct dp_rx_desc *rx_desc, - uint32_t *rx_bfs) +static QDF_STATUS +dp_rx_defrag_store_fragment(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail, + struct hal_rx_mpdu_desc_info *mpdu_desc_info, + unsigned int tid, struct dp_rx_desc *rx_desc, + uint32_t *rx_bfs) { struct dp_rx_reorder_array_elem *rx_reorder_array_elem; struct dp_pdev *pdev; @@ -1442,13 +1662,15 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, if (tid >= DP_MAX_TIDS) { dp_info("TID out of bounds: %d", tid); qdf_assert_always(0); + goto discard_frag; } pdev = peer->vdev->pdev; rx_tid = &peer->rx_tid[tid]; mpdu_sequence_control_valid = - hal_rx_get_mpdu_sequence_control_valid(rx_desc->rx_buf_start); + hal_rx_get_mpdu_sequence_control_valid(soc->hal_soc, + rx_desc->rx_buf_start); /* Invalid MPDU sequence control field, MPDU is of no use */ if (!mpdu_sequence_control_valid) { @@ -1460,7 +1682,8 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, } mpdu_frame_control_valid = - hal_rx_get_mpdu_frame_control_valid(rx_desc->rx_buf_start); + hal_rx_get_mpdu_frame_control_valid(soc->hal_soc, + rx_desc->rx_buf_start); /* Invalid frame control field */ if (!mpdu_frame_control_valid) { @@ -1505,21 +1728,21 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, } /* Check if the fragment is for the same sequence or a different one */ + dp_debug("rx_tid %d", tid); if (rx_reorder_array_elem->head) { + dp_debug("rxseq %d\n", rxseq); if (rxseq != rx_tid->curr_seq_num) { + dp_debug("mismatch cur_seq %d rxseq %d\n", + rx_tid->curr_seq_num, rxseq); /* Drop stored fragments if out of sequence * fragment is received */ dp_rx_reorder_flush_frag(peer, tid); - DP_STATS_INC(soc, rx.rx_frag_err, 1); - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s mismatch, dropping earlier sequence ", - (rxseq == rx_tid->curr_seq_num) - ? "address" - : "seq number"); + DP_STATS_INC(soc, rx.rx_frag_oor, 1); + dp_debug("cur rxseq %d\n", rxseq); /* * The sequence number for this fragment becomes the * new sequence number to be processed @@ -1527,9 +1750,11 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, rx_tid->curr_seq_num = rxseq; } } else { + dp_debug("cur rxseq %d\n", rxseq); /* Start of a new sequence */ dp_rx_defrag_cleanup(peer, tid); rx_tid->curr_seq_num = rxseq; + /* store PN number also */ } /* @@ -1671,7 +1896,7 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc, * * Return: uint32_t: No. of elements processed */ -uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, +uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc, struct hal_rx_mpdu_desc_info *mpdu_desc_info, struct dp_rx_desc *rx_desc, uint8_t *mac_id, @@ -1702,6 +1927,9 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, pdev = soc->pdev_list[rx_desc->pool_id]; *mac_id = rx_desc->pool_id; + if (rx_desc->unmapped) + return rx_bufs_used; + msdu = rx_desc->nbuf; dp_ipa_handle_rx_buf_smmu_mapping(soc, msdu, false); @@ -1751,9 +1979,9 @@ QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc, */ if (!rx_reorder_array_elem) { dp_verbose_debug( - "peer id:%d mac:" QDF_MAC_ADDR_STR "drop rx frame!", + "peer id:%d mac: "QDF_MAC_ADDR_FMT" drop rx frame!", peer->peer_ids[0], - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); DP_STATS_INC(soc, rx.err.defrag_peer_uninit, 1); qdf_nbuf_free(nbuf); goto fail; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h index 0c24f88cf314edd2278562a4846bec9bb290149f..02d2b1df7c480751312a3c94b9acf63164c0da21 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -21,10 +21,6 @@ #include "hal_rx.h" -#ifdef CONFIG_MCL -#include -#endif - #define DEFRAG_IEEE80211_KEY_LEN 8 #define DEFRAG_IEEE80211_FCS_LEN 4 @@ -52,11 +48,11 @@ struct dp_rx_defrag_cipher { uint8_t ic_miclen; }; -uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, - struct hal_rx_mpdu_desc_info *mpdu_desc_info, - struct dp_rx_desc *rx_desc, - uint8_t *mac_id, - uint32_t quota); +uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc, + struct hal_rx_mpdu_desc_info *mpdu_desc_info, + struct dp_rx_desc *rx_desc, + uint8_t *mac_id, + uint32_t quota); /* * dp_rx_frag_get_mac_hdr() - Return pointer to the mac hdr @@ -73,7 +69,7 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, static inline struct ieee80211_frame *dp_rx_frag_get_mac_hdr(uint8_t *rx_desc_info) { - int rx_desc_len = hal_rx_get_desc_len(); + int rx_desc_len = SIZE_OF_DATA_RX_TLV; return (struct ieee80211_frame *)(rx_desc_info + rx_desc_len); } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c index 55654b526d391ff2c7762327549ad8b2f15b8792..e80121e85612c0e1079bf22e870514ef88fae4b6 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c @@ -36,8 +36,9 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id, desc_size = sizeof(*rx_desc_elem); rx_desc_pool->elem_size = desc_size; if (!dp_is_soc_reinit(soc)) { - qdf_mem_multi_pages_alloc(soc->osdev, &rx_desc_pool->desc_pages, - desc_size, num_elem, 0, true); + dp_desc_multi_pages_mem_alloc(soc, rx_desc_pool->desc_type, + &rx_desc_pool->desc_pages, + desc_size, num_elem, 0, true); if (!rx_desc_pool->desc_pages.num_pages) { qdf_err("Multi page alloc fail,size=%d, elem=%d", desc_size, num_elem); @@ -163,8 +164,8 @@ void dp_rx_desc_pool_free(struct dp_soc *soc, { if (qdf_unlikely(!(rx_desc_pool->desc_pages.cacheable_pages))) return; - qdf_mem_multi_pages_free(soc->osdev, - &rx_desc_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, rx_desc_pool->desc_type, + &rx_desc_pool->desc_pages, 0, true); } #else QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id, @@ -333,6 +334,7 @@ void dp_rx_add_desc_list_to_free_list(struct dp_soc *soc, rx_desc_pool->freelist = *local_desc_list; (*tail)->next = temp_list; *tail = NULL; + *local_desc_list = NULL; qdf_spin_unlock_bh(&rx_desc_pool->lock); } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c index 3889a23be360fecff33004fd7c0ec8144ad3c1ea..b9fded46fe9cdd289aabc1b5e19e04c36862889c 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,9 +25,6 @@ #include "hal_api.h" #include "qdf_trace.h" #include "qdf_nbuf.h" -#ifdef CONFIG_MCL -#include -#endif #include "dp_rx_defrag.h" #include "dp_ipa.h" #ifdef FEATURE_WDS @@ -35,6 +33,9 @@ #include /* LLC_SNAP_HDR_LEN */ #include "qdf_net_types.h" +/* Max buffer in invalid peer SG list*/ +#define DP_MAX_INVALID_BUFFERS 10 + /** * dp_rx_mcast_echo_check() - check if the mcast pkt is a loop * back on same vap or a different vap. @@ -65,7 +66,7 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, if (vdev->opmode != wlan_op_mode_sta) return false; - if (!hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr)) + if (!hal_rx_msdu_end_da_is_mcbc_get(soc->hal_soc, rx_tlv_hdr)) return false; data = qdf_nbuf_data(nbuf); @@ -93,8 +94,8 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, * then drop the pkt as it is looped back */ qdf_spin_lock_bh(&soc->ast_lock); - if (hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr)) { - sa_idx = hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr); + if (hal_rx_msdu_end_sa_is_valid_get(soc->hal_soc, rx_tlv_hdr)) { + sa_idx = hal_rx_msdu_end_sa_idx_get(soc->hal_soc, rx_tlv_hdr); if ((sa_idx < 0) || (sa_idx >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) { @@ -134,8 +135,9 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, qdf_spin_unlock_bh(&soc->ast_lock); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "Detected DBDC Root AP %pM, %d %d", - &data[QDF_MAC_ADDR_SIZE], vdev->pdev->pdev_id, + "Detected DBDC Root AP "QDF_MAC_ADDR_FMT", %d %d", + QDF_MAC_ADDR_REF(&data[QDF_MAC_ADDR_SIZE]), + vdev->pdev->pdev_id, ase->pdev_id); return false; } @@ -145,8 +147,8 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, qdf_spin_unlock_bh(&soc->ast_lock); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "received pkt with same src mac %pM", - &data[QDF_MAC_ADDR_SIZE]); + "received pkt with same src mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(&data[QDF_MAC_ADDR_SIZE])); return true; } @@ -155,6 +157,26 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, return false; } +void dp_rx_link_desc_refill_duplicate_check( + struct dp_soc *soc, + struct hal_buf_info *buf_info, + hal_buff_addrinfo_t ring_buf_info) +{ + struct hal_buf_info current_link_desc_buf_info = { 0 }; + + /* do duplicate link desc address check */ + hal_rx_buffer_addr_info_get_paddr(ring_buf_info, + ¤t_link_desc_buf_info); + if (qdf_unlikely(current_link_desc_buf_info.paddr == + buf_info->paddr)) { + dp_info_rl("duplicate link desc addr: %llu, cookie: 0x%x", + current_link_desc_buf_info.paddr, + current_link_desc_buf_info.sw_cookie); + DP_STATS_INC(soc, rx.err.dup_refill_link_desc, 1); + } + *buf_info = current_link_desc_buf_info; +} + /** * dp_rx_link_desc_return_by_addr - Return a MPDU link descriptor to * (WBM) by address @@ -165,12 +187,13 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, * Return: QDF_STATUS */ QDF_STATUS -dp_rx_link_desc_return_by_addr(struct dp_soc *soc, void *link_desc_addr, - uint8_t bm_action) +dp_rx_link_desc_return_by_addr(struct dp_soc *soc, + hal_buff_addrinfo_t link_desc_addr, + uint8_t bm_action) { struct dp_srng *wbm_desc_rel_ring = &soc->wbm_desc_rel_ring; - void *wbm_rel_srng = wbm_desc_rel_ring->hal_srng; - void *hal_soc = soc->hal_soc; + hal_ring_handle_t wbm_rel_srng = wbm_desc_rel_ring->hal_srng; + hal_soc_handle_t hal_soc = soc->hal_soc; QDF_STATUS status = QDF_STATUS_E_FAILURE; void *src_srng_desc; @@ -180,6 +203,12 @@ dp_rx_link_desc_return_by_addr(struct dp_soc *soc, void *link_desc_addr, return status; } + /* do duplicate link desc address check */ + dp_rx_link_desc_refill_duplicate_check( + soc, + &soc->last_op_info.wbm_rel_link_desc, + link_desc_addr); + if (qdf_unlikely(hal_srng_access_start(hal_soc, wbm_rel_srng))) { /* TODO */ @@ -230,9 +259,11 @@ dp_rx_link_desc_return_by_addr(struct dp_soc *soc, void *link_desc_addr, * Return: QDF_STATUS */ QDF_STATUS -dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc, uint8_t bm_action) +dp_rx_link_desc_return(struct dp_soc *soc, hal_ring_desc_t ring_desc, + uint8_t bm_action) { void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(ring_desc); + return dp_rx_link_desc_return_by_addr(soc, buf_addr_info, bm_action); } @@ -250,10 +281,11 @@ dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc, uint8_t bm_action) * * Return: uint32_t: No. of elements processed */ -static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, - struct hal_rx_mpdu_desc_info *mpdu_desc_info, - uint8_t *mac_id, - uint32_t quota) +static uint32_t +dp_rx_msdus_drop(struct dp_soc *soc, hal_ring_desc_t ring_desc, + struct hal_rx_mpdu_desc_info *mpdu_desc_info, + uint8_t *mac_id, + uint32_t quota) { uint32_t rx_bufs_used = 0; void *link_desc_va; @@ -281,7 +313,7 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, /* all buffers from a MSDU link link belong to same pdev */ *mac_id = rx_desc->pool_id; - pdev = soc->pdev_list[rx_desc->pool_id]; + pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id); if (!dp_rx_desc_check_magic(rx_desc)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -303,8 +335,8 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, "Packet received with PN error for tid :%d", tid); rx_tlv_hdr = qdf_nbuf_data(rx_desc->nbuf); - if (hal_rx_encryption_info_valid(rx_tlv_hdr)) - hal_rx_print_pn(rx_tlv_hdr); + if (hal_rx_encryption_info_valid(soc->hal_soc, rx_tlv_hdr)) + hal_rx_print_pn(soc->hal_soc, rx_tlv_hdr); /* Just free the buffers */ qdf_nbuf_free(rx_desc->nbuf); @@ -338,7 +370,7 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, * Return: uint32_t: No. of elements processed */ static uint32_t -dp_rx_pn_error_handle(struct dp_soc *soc, void *ring_desc, +dp_rx_pn_error_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc, struct hal_rx_mpdu_desc_info *mpdu_desc_info, uint8_t *mac_id, uint32_t quota) @@ -359,12 +391,8 @@ dp_rx_pn_error_handle(struct dp_soc *soc, void *ring_desc, * TODO: Check for peer specific policies & set peer_pn_policy */ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "discard rx due to PN error for peer %pK " - "(%02x:%02x:%02x:%02x:%02x:%02x)", - peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + "discard rx due to PN error for peer %pK "QDF_MAC_ADDR_FMT, + peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); dp_peer_unref_del_find_by_id(peer); } @@ -479,7 +507,7 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc, qdf_assert_always(rx_desc); /* all buffers from a MSDU link belong to same pdev */ - pdev = soc->pdev_list[rx_desc->pool_id]; + pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id); nbuf = rx_desc->nbuf; dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, false); @@ -501,7 +529,7 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc, rx_tlv_hdr_last = qdf_nbuf_data(tail_nbuf); if (qdf_unlikely(head_nbuf != tail_nbuf)) { - nbuf = dp_rx_sg_create(head_nbuf); + nbuf = dp_rx_sg_create(soc, head_nbuf); qdf_nbuf_set_is_frag(nbuf, 1); DP_STATS_INC(soc, rx.err.reo_err_oor_sg_count, 1); } @@ -512,12 +540,13 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc, * only first msdu, mpdu start description tlv valid? * and use it for following msdu. */ - if (hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr_last)) + if (hal_rx_msdu_end_first_msdu_get(soc->hal_soc, + rx_tlv_hdr_last)) tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr_first); - dp_2k_jump_handle(soc, nbuf, peer_id, tid, - rx_tlv_hdr_last); + dp_2k_jump_handle(soc, nbuf, rx_tlv_hdr_last, + peer_id, tid); break; case HAL_REO_ERR_REGULAR_FRAME_OOR: @@ -559,12 +588,13 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc, dp_rx_link_desc_return_by_addr(soc, buf_addr_info, HAL_BM_ACTION_PUT_IN_IDLE_LIST); - QDF_BUG(msdu_processed == mpdu_desc_info->msdu_count); + if (qdf_unlikely(msdu_processed != mpdu_desc_info->msdu_count)) + DP_STATS_INC(soc, rx.err.msdu_count_mismatch, 1); return rx_bufs_used; } -#ifdef CONFIG_MCL +#ifdef DP_INVALID_PEER_ASSERT #define DP_PDEV_INVALID_PEER_MSDU_CHECK(head, tail) \ do { \ qdf_assert_always(!(head)); \ @@ -586,8 +616,8 @@ dp_rx_reo_err_entry_process(struct dp_soc *soc, * Return: bool: true for last msdu of mpdu */ static bool -dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, - uint8_t mac_id) +dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, + uint8_t *rx_tlv_hdr, uint8_t mac_id) { bool mpdu_done = false; qdf_nbuf_t curr_nbuf = NULL; @@ -596,11 +626,22 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, /* TODO: Currently only single radio is supported, hence * pdev hard coded to '0' index */ - struct dp_pdev *dp_pdev = soc->pdev_list[mac_id]; - - if (!dp_pdev->first_nbuf) { + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + + /* if invalid peer SG list has max values free the buffers in list + * and treat current buffer as start of list + * + * current logic to detect the last buffer from attn_tlv is not reliable + * in OFDMA UL scenario hence add max buffers check to avoid list pile + * up + */ + if (!dp_pdev->first_nbuf || + (dp_pdev->invalid_peer_head_msdu && + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST + (dp_pdev->invalid_peer_head_msdu) >= DP_MAX_INVALID_BUFFERS)) { qdf_nbuf_set_rx_chfrag_start(nbuf, 1); - dp_pdev->ppdu_id = HAL_RX_HW_DESC_GET_PPDUID_GET(rx_tlv_hdr); + dp_pdev->ppdu_id = hal_rx_hw_desc_get_ppduid_get(soc->hal_soc, + rx_tlv_hdr); dp_pdev->first_nbuf = true; /* If the new nbuf received is the first msdu of the @@ -648,9 +689,9 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, } static -void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, - struct dp_peer *peer, - qdf_nbuf_t nbuf) +void dp_rx_err_handle_bar(struct dp_soc *soc, + struct dp_peer *peer, + qdf_nbuf_t nbuf) { uint8_t *rx_tlv_hdr; unsigned char type, subtype; @@ -665,8 +706,7 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, */ rx_tlv_hdr = qdf_nbuf_data(nbuf); - bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + - sizeof(struct rx_pkt_tlvs)); + bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + SIZE_OF_DATA_RX_TLV); type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK; subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; @@ -690,15 +730,99 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, start_seq_num); } +/** + * dp_rx_bar_frame_handle() - Function to handle err BAR frames + * @soc: core DP main context + * @ring_desc: Hal ring desc + * @rx_desc: dp rx desc + * @mpdu_desc_info: mpdu desc info + * + * Handle the error BAR frames received. Ensure the SOC level + * stats are updated based on the REO error code. The BAR frames + * are further processed by updating the Rx tids with the start + * sequence number (SSN) and BA window size. Desc is returned + * to the free desc list + * + * Return: none + */ +static void +dp_rx_bar_frame_handle(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + struct hal_rx_mpdu_desc_info *mpdu_desc_info) +{ + qdf_nbuf_t nbuf; + struct dp_pdev *pdev; + struct dp_peer *peer; + struct rx_desc_pool *rx_desc_pool; + uint16_t peer_id; + uint8_t *rx_tlv_hdr; + uint32_t tid; + uint8_t reo_err_code; + + nbuf = rx_desc->nbuf; + rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id]; + dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, + false); + qdf_nbuf_unmap_single(soc->osdev, nbuf, + QDF_DMA_FROM_DEVICE); + rx_desc->unmapped = 1; + rx_tlv_hdr = qdf_nbuf_data(nbuf); + peer_id = + hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc, + rx_tlv_hdr); + peer = dp_peer_find_by_id(soc, peer_id); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, + rx_tlv_hdr); + pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id); + + if (!peer) + goto next; + + reo_err_code = HAL_RX_REO_ERROR_GET(ring_desc); + dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT + " peer_id = %d" + " tid = %u" + " SSN = %d" + " error code = %d", + QDF_MAC_ADDR_REF(peer->mac_addr.raw), + peer_id, + tid, + mpdu_desc_info->mpdu_seq, + reo_err_code); + + switch (reo_err_code) { + case HAL_REO_ERR_BAR_FRAME_2K_JUMP: + DP_STATS_INC(soc, + rx.err.reo_error[reo_err_code], 1); + case HAL_REO_ERR_BAR_FRAME_OOR: + dp_rx_err_handle_bar(soc, peer, nbuf); + DP_STATS_INC(soc, + rx.err.reo_error[reo_err_code], 1); + break; + default: + DP_STATS_INC(soc, rx.bar_frame, 1); + } + + dp_peer_unref_del_find_by_id(peer); +next: + dp_rx_link_desc_return(soc, ring_desc, + HAL_BM_ACTION_PUT_IN_IDLE_LIST); + dp_rx_add_to_free_desc_list(&pdev->free_list_head, + &pdev->free_list_tail, + rx_desc); + qdf_nbuf_free(nbuf); +} + /** * dp_2k_jump_handle() - Function to handle 2k jump exception * on WBM ring * * @soc: core DP main context * @nbuf: buffer pointer + * @rx_tlv_hdr: start of rx tlv header * @peer_id: peer id of first msdu * @tid: Tid for which exception occurred - * @rx_tlv_hdr: start of rx tlv header * * This function handles 2k jump violations arising out * of receiving aggregates in non BA case. This typically @@ -712,9 +836,9 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, + uint8_t *rx_tlv_hdr, uint16_t peer_id, - uint8_t tid, - uint8_t *rx_tlv_hdr) + uint8_t tid) { struct dp_peer *peer = NULL; struct dp_rx_tid *rx_tid = NULL; @@ -749,12 +873,11 @@ dp_2k_jump_handle(struct dp_soc *soc, if (soc->cdp_soc.ol_ops->send_delba) { DP_STATS_INC(soc, rx.err.rx_2k_jump_delba_sent, 1); soc->cdp_soc.ol_ops->send_delba( - peer->vdev->pdev->ctrl_pdev, - peer->ctrl_peer, - peer->mac_addr.raw, - tid, - peer->vdev->ctrl_vdev, - rx_tid->delba_rcode); + peer->vdev->pdev->soc->ctrl_psoc, + peer->vdev->vdev_id, + peer->mac_addr.raw, + tid, + rx_tid->delba_rcode); } } else { qdf_spin_unlock_bh(&rx_tid->tid_lock); @@ -776,7 +899,8 @@ dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_free(nbuf); } -#ifdef QCA_WIFI_QCA6390 +#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750) /** * dp_rx_null_q_handle_invalid_peer_id_exception() - to find exception * @soc: pointer to dp_soc struct @@ -797,10 +921,9 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc, uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf) { - uint8_t local_id; struct dp_peer *peer = NULL; uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); - struct dp_pdev *pdev = soc->pdev_list[pool_id]; + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, pool_id); struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr; /* @@ -810,7 +933,7 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc, */ if (wh) peer = dp_find_peer_by_addr((struct cdp_pdev *)pdev, - wh->i_addr2, &local_id); + wh->i_addr2); if (peer) { dp_verbose_debug("MPDU sw_peer_id & ast_idx is corrupted"); hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr, @@ -835,7 +958,7 @@ dp_rx_null_q_handle_invalid_peer_id_exception(struct dp_soc *soc, static inline bool dp_rx_check_pkt_len(struct dp_soc *soc, uint32_t pkt_len) { - if (qdf_unlikely(pkt_len > RX_BUFFER_SIZE)) { + if (qdf_unlikely(pkt_len > RX_DATA_BUFFER_SIZE)) { DP_STATS_INC_PKT(soc, rx.err.rx_invalid_pkt_len, 1, pkt_len); return true; @@ -889,34 +1012,40 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, uint8_t pool_id, struct dp_peer *peer) { - uint32_t pkt_len, l2_hdr_offset; + uint32_t pkt_len; uint16_t msdu_len; struct dp_vdev *vdev; uint8_t tid; qdf_ether_header_t *eh; + struct hal_rx_msdu_metadata msdu_metadata; uint16_t sa_idx = 0; qdf_nbuf_set_rx_chfrag_start(nbuf, - hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)); + hal_rx_msdu_end_first_msdu_get(soc->hal_soc, + rx_tlv_hdr)); qdf_nbuf_set_rx_chfrag_end(nbuf, - hal_rx_msdu_end_last_msdu_get(rx_tlv_hdr)); - qdf_nbuf_set_da_mcbc(nbuf, hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr)); + hal_rx_msdu_end_last_msdu_get(soc->hal_soc, + rx_tlv_hdr)); + qdf_nbuf_set_da_mcbc(nbuf, hal_rx_msdu_end_da_is_mcbc_get(soc->hal_soc, + rx_tlv_hdr)); qdf_nbuf_set_da_valid(nbuf, - hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr)); + hal_rx_msdu_end_da_is_valid_get(soc->hal_soc, + rx_tlv_hdr)); qdf_nbuf_set_sa_valid(nbuf, - hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr)); + hal_rx_msdu_end_sa_is_valid_get(soc->hal_soc, + rx_tlv_hdr)); - l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); + hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata); msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr); - pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN; + pkt_len = msdu_len + msdu_metadata.l3_hdr_pad + RX_PKT_TLVS_LEN; if (qdf_likely(!qdf_nbuf_is_frag(nbuf))) { if (dp_rx_check_pkt_len(soc, pkt_len)) goto drop_nbuf; /* Set length in nbuf */ - qdf_nbuf_set_pktlen(nbuf, - qdf_min(pkt_len, (uint32_t)RX_BUFFER_SIZE)); + qdf_nbuf_set_pktlen( + nbuf, qdf_min(pkt_len, (uint32_t)RX_DATA_BUFFER_SIZE)); qdf_assert_always(nbuf->data == rx_tlv_hdr); } @@ -939,7 +1068,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, if (!peer) { bool mpdu_done = false; - struct dp_pdev *pdev = soc->pdev_list[pool_id]; + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, pool_id); dp_err_rl("peer is NULL"); DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1, @@ -955,6 +1084,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, pdev->invalid_peer_head_msdu = NULL; pdev->invalid_peer_tail_msdu = NULL; } + return QDF_STATUS_E_FAILURE; } @@ -972,10 +1102,13 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, if (qdf_nbuf_is_frag(nbuf)) qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN); else - qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN)); + qdf_nbuf_pull_head(nbuf, (msdu_metadata.l3_hdr_pad + + RX_PKT_TLVS_LEN)); + + dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL, 0, 1); - if (hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr)) { - sa_idx = hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr); + if (hal_rx_msdu_end_sa_is_valid_get(soc->hal_soc, rx_tlv_hdr)) { + sa_idx = hal_rx_msdu_end_sa_idx_get(soc->hal_soc, rx_tlv_hdr); if ((sa_idx < 0) || (sa_idx >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) { @@ -1002,7 +1135,8 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, if (qdf_unlikely((peer->nawds_enabled == true) && - hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) { + hal_rx_msdu_end_da_is_mcbc_get(soc->hal_soc, + rx_tlv_hdr))) { dp_err_rl("free buffer for multicast packet"); DP_STATS_INC(peer, rx.nawds_mcast_drop, 1); goto drop_nbuf; @@ -1015,57 +1149,51 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, /* WDS Source Port Learning */ if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet && vdev->wds_enabled)) - dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf); + dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf, + msdu_metadata); - if (hal_rx_mpdu_start_mpdu_qos_control_valid_get(rx_tlv_hdr)) { - /* TODO: Assuming that qos_control_valid also indicates - * unicast. Should we check this? - */ - tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr); - if (peer && !peer->rx_tid[tid].hw_qdesc_vaddr_unaligned) { - /* IEEE80211_SEQ_MAX indicates invalid start_seq */ + if (hal_rx_is_unicast(soc->hal_soc, rx_tlv_hdr)) { + tid = hal_rx_tid_get(soc->hal_soc, rx_tlv_hdr); + if (!peer->rx_tid[tid].hw_qdesc_vaddr_unaligned) dp_rx_tid_setup_wifi3(peer, tid, 1, IEEE80211_SEQ_MAX); - } + /* IEEE80211_SEQ_MAX indicates invalid start_seq */ } if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) { qdf_nbuf_set_next(nbuf, NULL); dp_rx_deliver_raw(vdev, nbuf, peer); } else { - if (vdev->osif_rx) { - qdf_nbuf_set_next(nbuf, NULL); - DP_STATS_INC_PKT(peer, rx.to_stack, 1, - qdf_nbuf_len(nbuf)); - - /* - * Update the protocol tag in SKB based on - * CCE metadata - */ - dp_rx_update_protocol_tag(soc, vdev, nbuf, rx_tlv_hdr, - EXCEPTION_DEST_RING_ID, - true, true); + qdf_nbuf_set_next(nbuf, NULL); + DP_STATS_INC_PKT(peer, rx.to_stack, 1, + qdf_nbuf_len(nbuf)); - if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get( - rx_tlv_hdr) && - (vdev->rx_decap_type == - htt_cmn_pkt_type_ethernet))) { - eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); + /* + * Update the protocol tag in SKB based on + * CCE metadata + */ + dp_rx_update_protocol_tag(soc, vdev, nbuf, rx_tlv_hdr, + EXCEPTION_DEST_RING_ID, + true, true); + + /* Update the flow tag in SKB based on FSE metadata */ + dp_rx_update_flow_tag(soc, vdev, nbuf, + rx_tlv_hdr, true); + + if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get( + soc->hal_soc, rx_tlv_hdr) && + (vdev->rx_decap_type == + htt_cmn_pkt_type_ethernet))) { + eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); + DP_STATS_INC_PKT(peer, rx.multicast, 1, + qdf_nbuf_len(nbuf)); - DP_STATS_INC_PKT(peer, rx.multicast, 1, + if (QDF_IS_ADDR_BROADCAST(eh->ether_dhost)) + DP_STATS_INC_PKT(peer, rx.bcast, 1, qdf_nbuf_len(nbuf)); - if (QDF_IS_ADDR_BROADCAST(eh->ether_dhost)) { - DP_STATS_INC_PKT(peer, rx.bcast, 1, - qdf_nbuf_len(nbuf)); - } - } - - vdev->osif_rx(vdev->osif_vdev, nbuf); - - } else { - dp_err_rl("INVALID osif_rx. vdev %pK", vdev); - DP_STATS_INC(soc, rx.err.invalid_vdev, 1); - goto drop_nbuf; } + + qdf_nbuf_set_exc_frame(nbuf, 1); + dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL); } return QDF_STATUS_SUCCESS; @@ -1111,7 +1239,8 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, qdf_assert(0); } - l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr); + l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, + rx_tlv_hdr); msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr); pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN; @@ -1151,23 +1280,22 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, * Advance the packet start pointer by total size of * pre-header TLV's */ - qdf_nbuf_pull_head(nbuf, l2_hdr_offset + RX_PKT_TLVS_LEN); + dp_rx_skip_tlvs(nbuf, l2_hdr_offset); if (err_code == HAL_RXDMA_ERR_WIFI_PARSE) { uint8_t *pkt_type; pkt_type = qdf_nbuf_data(nbuf) + (2 * QDF_MAC_ADDR_SIZE); - if (*(uint16_t *)pkt_type == htons(QDF_ETH_TYPE_8021Q) && - *(uint16_t *)(pkt_type + DP_SKIP_VLAN) == htons(QDF_LLC_STP)) { - DP_STATS_INC(vdev->pdev, vlan_tag_stp_cnt, 1); - goto process_mesh; - } else { - DP_STATS_INC(vdev->pdev, dropped.wifi_parse, 1); - qdf_nbuf_free(nbuf); - return; + if (*(uint16_t *)pkt_type == htons(QDF_ETH_TYPE_8021Q)) { + if (*(uint16_t *)(pkt_type + DP_SKIP_VLAN) == + htons(QDF_LLC_STP)) { + DP_STATS_INC(vdev->pdev, vlan_tag_stp_cnt, 1); + goto process_mesh; + } else { + goto process_rx; + } } } - if (vdev->rx_decap_type == htt_cmn_pkt_type_raw) goto process_mesh; @@ -1210,8 +1338,9 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, dp_rx_fill_mesh_stats(vdev, nbuf, rx_tlv_hdr, peer); } process_rx: - if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr) && - (vdev->rx_decap_type == + if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get(soc->hal_soc, + rx_tlv_hdr) && + (vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))) { eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); is_broadcast = (QDF_IS_ADDR_BROADCAST @@ -1229,7 +1358,10 @@ dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, /* Update the protocol tag in SKB based on CCE metadata */ dp_rx_update_protocol_tag(soc, vdev, nbuf, rx_tlv_hdr, EXCEPTION_DEST_RING_ID, true, true); + /* Update the flow tag in SKB based on FSE metadata */ + dp_rx_update_flow_tag(soc, vdev, nbuf, rx_tlv_hdr, true); DP_STATS_INC(peer, rx.to_stack.num, 1); + qdf_nbuf_set_exc_frame(nbuf, 1); dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL); } @@ -1251,18 +1383,16 @@ void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, struct dp_vdev *vdev = NULL; struct dp_pdev *pdev = NULL; struct ol_if_ops *tops = NULL; - struct ieee80211_frame *wh; - uint8_t *rx_pkt_hdr; uint16_t rx_seq, fragno; + uint8_t is_raw; unsigned int tid; QDF_STATUS status; + struct cdp_rx_mic_err_info mic_failure_info; - if (!hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)) + if (!hal_rx_msdu_end_first_msdu_get(soc->hal_soc, + rx_tlv_hdr)) return; - rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(nbuf)); - wh = (struct ieee80211_frame *)rx_pkt_hdr; - if (!peer) { dp_info_rl("peer not found"); goto fail; @@ -1280,37 +1410,139 @@ void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, goto fail; } - tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, qdf_nbuf_data(nbuf)); - rx_seq = (((*(uint16_t *)wh->i_seq) & - IEEE80211_SEQ_SEQ_MASK) >> - IEEE80211_SEQ_SEQ_SHIFT); + is_raw = HAL_IS_DECAP_FORMAT_RAW(soc->hal_soc, qdf_nbuf_data(nbuf)); + if (is_raw) { + fragno = dp_rx_frag_get_mpdu_frag_number(qdf_nbuf_data(nbuf)); + /* Can get only last fragment */ + if (fragno) { + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, + qdf_nbuf_data(nbuf)); + rx_seq = hal_rx_get_rx_sequence(soc->hal_soc, + qdf_nbuf_data(nbuf)); + + status = dp_rx_defrag_add_last_frag(soc, peer, + tid, rx_seq, nbuf); + dp_info_rl("Frag pkt seq# %d frag# %d consumed " + "status %d !", rx_seq, fragno, status); + return; + } + } - fragno = dp_rx_frag_get_mpdu_frag_number(qdf_nbuf_data(nbuf)); + if (hal_rx_mpdu_get_addr1(soc->hal_soc, qdf_nbuf_data(nbuf), + &mic_failure_info.da_mac_addr.bytes[0])) { + dp_err_rl("Failed to get da_mac_addr"); + goto fail; + } - /* Can get only last fragment */ - if (fragno) { - status = dp_rx_defrag_add_last_frag(soc, peer, - tid, rx_seq, nbuf); - dp_info_rl("Frag pkt seq# %d frag# %d consumed status %d !", - rx_seq, fragno, status); - return; + if (hal_rx_mpdu_get_addr2(soc->hal_soc, qdf_nbuf_data(nbuf), + &mic_failure_info.ta_mac_addr.bytes[0])) { + dp_err_rl("Failed to get ta_mac_addr"); + goto fail; } + mic_failure_info.key_id = 0; + mic_failure_info.multicast = + IEEE80211_IS_MULTICAST(mic_failure_info.da_mac_addr.bytes); + qdf_mem_zero(mic_failure_info.tsc, MIC_SEQ_CTR_SIZE); + mic_failure_info.frame_type = cdp_rx_frame_type_802_11; + mic_failure_info.data = NULL; + mic_failure_info.vdev_id = vdev->vdev_id; + tops = pdev->soc->cdp_soc.ol_ops; if (tops->rx_mic_error) - tops->rx_mic_error(pdev->ctrl_pdev, vdev->vdev_id, wh); + tops->rx_mic_error(soc->ctrl_psoc, pdev->pdev_id, + &mic_failure_info); fail: qdf_nbuf_free(nbuf); return; } +#ifdef DP_RX_DESC_COOKIE_INVALIDATE +/** + * dp_rx_link_cookie_check() - Validate link desc cookie + * @ring_desc: ring descriptor + * + * Return: qdf status + */ +static inline QDF_STATUS +dp_rx_link_cookie_check(hal_ring_desc_t ring_desc) +{ + if (qdf_unlikely(HAL_RX_REO_BUF_LINK_COOKIE_INVALID_GET(ring_desc))) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_rx_link_cookie_invalidate() - Invalidate link desc cookie + * @ring_desc: ring descriptor + * + * Return: None + */ +static inline void +dp_rx_link_cookie_invalidate(hal_ring_desc_t ring_desc) +{ + HAL_RX_REO_BUF_LINK_COOKIE_INVALID_SET(ring_desc); +} +#else +static inline QDF_STATUS +dp_rx_link_cookie_check(hal_ring_desc_t ring_desc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +dp_rx_link_cookie_invalidate(hal_ring_desc_t ring_desc) +{ +} +#endif + +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +/** + * dp_rx_err_ring_record_entry() - Record rx err ring history + * @soc: Datapath soc structure + * @paddr: paddr of the buffer in RX err ring + * @sw_cookie: SW cookie of the buffer in RX err ring + * @rbm: Return buffer manager of the buffer in RX err ring + * + * Returns: None + */ +static inline void +dp_rx_err_ring_record_entry(struct dp_soc *soc, uint64_t paddr, + uint32_t sw_cookie, uint8_t rbm) +{ + struct dp_buf_info_record *record; + uint32_t idx; + + if (qdf_unlikely(!soc->rx_err_ring_history)) + return; + + idx = dp_history_get_next_index(&soc->rx_err_ring_history->index, + DP_RX_ERR_HIST_MAX); + + /* No NULL check needed for record since its an array */ + record = &soc->rx_err_ring_history->entry[idx]; + + record->timestamp = qdf_get_log_timestamp(); + record->hbi.paddr = paddr; + record->hbi.sw_cookie = sw_cookie; + record->hbi.rbm = rbm; +} +#else +static inline void +dp_rx_err_ring_record_entry(struct dp_soc *soc, uint64_t paddr, + uint32_t sw_cookie, uint8_t rbm) +{ +} +#endif + uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_ring, uint32_t quota) + hal_ring_handle_t hal_ring_hdl, uint32_t quota) { - void *hal_soc; - void *ring_desc; + hal_ring_desc_t ring_desc; + hal_soc_handle_t hal_soc; uint32_t count = 0; uint32_t rx_bufs_used = 0; uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 }; @@ -1327,16 +1559,18 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, struct hal_rx_msdu_list msdu_list; /* MSDU's per MPDU */ uint16_t num_msdus; struct dp_rx_desc *rx_desc = NULL; + QDF_STATUS status; + bool ret; /* Debug -- Remove later */ - qdf_assert(soc && hal_ring); + qdf_assert(soc && hal_ring_hdl); hal_soc = soc->hal_soc; /* Debug -- Remove later */ qdf_assert(hal_soc); - if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring))) { + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) { /* TODO */ /* @@ -1345,20 +1579,26 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, */ DP_STATS_INC(soc, rx.err.hal_ring_access_fail, 1); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("HAL RING Access Failed -- %pK"), hal_ring); + FL("HAL RING Access Failed -- %pK"), hal_ring_hdl); goto done; } while (qdf_likely(quota-- && (ring_desc = - hal_srng_dst_get_next(hal_soc, hal_ring)))) { + hal_srng_dst_peek(hal_soc, + hal_ring_hdl)))) { DP_STATS_INC(soc, rx.err_ring_pkts, 1); error = HAL_RX_ERROR_STATUS_GET(ring_desc); - qdf_assert(error == HAL_REO_ERROR_DETECTED); - buf_type = HAL_RX_REO_BUF_TYPE_GET(ring_desc); + + /* Get the MPDU DESC info */ + hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); + + if (mpdu_desc_info.msdu_count == 0) + goto next_entry; + /* * For REO error ring, expect only MSDU LINK DESC */ @@ -1371,6 +1611,12 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, qdf_assert_always((cookie >> LINK_DESC_ID_SHIFT) & LINK_DESC_ID_START); + status = dp_rx_link_cookie_check(ring_desc); + if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) { + DP_STATS_INC(soc, rx.err.invalid_link_cookie, 1); + break; + } + /* * Check if the buffer is to be processed on this processor */ @@ -1380,7 +1626,9 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &hbi); hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list, &num_msdus); - + dp_rx_err_ring_record_entry(soc, msdu_list.paddr[0], + msdu_list.sw_cookie[0], + msdu_list.rbm[0]); if (qdf_unlikely((msdu_list.rbm[0] != DP_WBM2SW_RBM) && (msdu_list.rbm[0] != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST) && @@ -1398,7 +1646,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, /* Return link descriptor through WBM ring (SW2WBM)*/ dp_rx_link_desc_return(soc, ring_desc, HAL_BM_ACTION_RELEASE_MSDU_LIST); - continue; + goto next_entry; } rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, @@ -1407,8 +1655,19 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, mac_id = rx_desc->pool_id; - /* Get the MPDU DESC info */ - hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); + if (mpdu_desc_info.bar_frame) { + qdf_assert_always(mpdu_desc_info.msdu_count == 1); + + dp_rx_bar_frame_handle(soc, + ring_desc, + rx_desc, + &mpdu_desc_info); + + rx_bufs_reaped[mac_id] += 1; + goto next_entry; + } + + dp_info("Got pkt with REO ERROR: %d", error); if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_FRAGMENT) { /* @@ -1421,7 +1680,33 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, &mpdu_desc_info, &mac_id, quota); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; + } + + /* + * this is a unlikely scenario where the host is reaping + * a descriptor which it already reaped just a while ago + * but is yet to replenish it back to HW. + * In this case host will dump the last 128 descriptors + * including the software descriptor rx_desc and assert. + */ + + if (qdf_unlikely(!rx_desc->in_use)) { + DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1); + dp_info_rl("Reaping rx_desc not in use!"); + dp_rx_dump_info_and_assert(soc, hal_ring_hdl, + ring_desc, rx_desc); + /* ignore duplicate RX desc and continue */ + /* Pop out the descriptor */ + goto next_entry; + } + + ret = dp_rx_desc_paddr_sanity_check(rx_desc, + msdu_list.paddr[0]); + if (!ret) { + DP_STATS_INC(soc, rx.err.nbuf_sanity_fail, 1); + rx_desc->in_err_state = 1; + goto next_entry; } count = dp_rx_frag_handle(soc, @@ -1430,22 +1715,31 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx_bufs_reaped[mac_id] += count; DP_STATS_INC(soc, rx.rx_frags, 1); - continue; + goto next_entry; } + /* + * Expect REO errors to be handled after this point + */ + qdf_assert_always(error == HAL_REO_ERROR_DETECTED); + if (hal_rx_reo_is_pn_error(ring_desc)) { /* TOD0 */ DP_STATS_INC(soc, rx.err. reo_error[HAL_REO_ERR_PN_CHECK_FAILED], 1); + /* increment @pdev level */ + dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + if (dp_pdev) + DP_STATS_INC(dp_pdev, err.reo_error, 1); count = dp_rx_pn_error_handle(soc, ring_desc, &mpdu_desc_info, &mac_id, quota); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } if (hal_rx_reo_is_2k_jump(ring_desc)) { @@ -1454,6 +1748,10 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx.err. reo_error[HAL_REO_ERR_REGULAR_FRAME_2K_JUMP], 1); + /* increment @pdev level */ + dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + if (dp_pdev) + DP_STATS_INC(dp_pdev, err.reo_error, 1); count = dp_rx_reo_err_entry_process( soc, @@ -1463,7 +1761,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, HAL_REO_ERR_REGULAR_FRAME_2K_JUMP); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } if (hal_rx_reo_is_oor_error(ring_desc)) { @@ -1472,7 +1770,10 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx.err. reo_error[HAL_REO_ERR_REGULAR_FRAME_OOR], 1); - + /* increment @pdev level */ + dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + if (dp_pdev) + DP_STATS_INC(dp_pdev, err.reo_error, 1); count = dp_rx_reo_err_entry_process( soc, ring_desc, @@ -1481,12 +1782,17 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, HAL_REO_ERR_REGULAR_FRAME_OOR); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } + /* Assert if unexpected error type */ + qdf_assert_always(0); +next_entry: + dp_rx_link_cookie_invalidate(ring_desc); + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); } done: - dp_srng_access_end(int_ctx, soc, hal_ring); + dp_srng_access_end(int_ctx, soc, hal_ring_hdl); if (soc->rx.flags.defrag_timeout_check) { uint32_t now_ms = @@ -1498,8 +1804,8 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { if (rx_bufs_reaped[mac_id]) { - dp_pdev = soc->pdev_list[mac_id]; - dp_rxdma_srng = &dp_pdev->rx_refill_buf_ring; + dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id]; rx_desc_pool = &soc->rx_desc_buf[mac_id]; dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng, @@ -1533,10 +1839,10 @@ static inline bool dp_handle_rxdma_decrypt_err(void) uint32_t dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_ring, uint32_t quota) + hal_ring_handle_t hal_ring_hdl, uint32_t quota) { - void *hal_soc; - void *ring_desc; + hal_ring_desc_t ring_desc; + hal_soc_handle_t hal_soc; struct dp_rx_desc *rx_desc; union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL }; union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL }; @@ -1557,14 +1863,14 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, uint8_t tid = 0; /* Debug -- Remove later */ - qdf_assert(soc && hal_ring); + qdf_assert(soc && hal_ring_hdl); hal_soc = soc->hal_soc; /* Debug -- Remove later */ qdf_assert(hal_soc); - if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring))) { + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) { /* TODO */ /* @@ -1572,12 +1878,13 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, * Ring Type / Ring Id combo */ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("HAL RING Access Failed -- %pK"), hal_ring); + FL("HAL RING Access Failed -- %pK"), hal_ring_hdl); goto done; } while (qdf_likely(quota-- && (ring_desc = - hal_srng_dst_get_next(hal_soc, hal_ring)))) { + hal_srng_dst_get_next(hal_soc, + hal_ring_hdl)))) { /* XXX */ buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc); @@ -1627,7 +1934,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, */ if (qdf_unlikely(!rx_desc->in_use)) { DP_STATS_INC(soc, rx.err.hal_wbm_rel_dup, 1); - dp_rx_dump_info_and_assert(soc, hal_ring, + dp_rx_dump_info_and_assert(soc, hal_ring_hdl, ring_desc, rx_desc); } @@ -1652,12 +1959,12 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx_desc); } done: - dp_srng_access_end(int_ctx, soc, hal_ring); + dp_srng_access_end(int_ctx, soc, hal_ring_hdl); for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { if (rx_bufs_reaped[mac_id]) { - dp_pdev = soc->pdev_list[mac_id]; - dp_rxdma_srng = &dp_pdev->rx_refill_buf_ring; + dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id]; rx_desc_pool = &soc->rx_desc_buf[mac_id]; dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng, @@ -1681,7 +1988,8 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, */ hal_rx_wbm_err_info_get_from_tlv(rx_tlv_hdr, &wbm_err_info); - peer_id = hal_rx_mpdu_start_sw_peer_id_get(rx_tlv_hdr); + peer_id = hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc, + rx_tlv_hdr); peer = dp_peer_find_by_id(soc, peer_id); if (!peer) @@ -1701,6 +2009,12 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, DP_STATS_INC(soc, rx.err.reo_error [wbm_err_info.reo_err_code], 1); + /* increment @pdev level */ + pool_id = wbm_err_info.pool_id; + dp_pdev = dp_get_pdev_for_lmac_id(soc, pool_id); + if (dp_pdev) + DP_STATS_INC(dp_pdev, err.reo_error, + 1); switch (wbm_err_info.reo_err_code) { /* @@ -1722,9 +2036,11 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, case HAL_REO_ERR_REGULAR_FRAME_2K_JUMP: pool_id = wbm_err_info.pool_id; - if (hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)) { + if (hal_rx_msdu_end_first_msdu_get(soc->hal_soc, + rx_tlv_hdr)) { peer_id = - hal_rx_mpdu_start_sw_peer_id_get(rx_tlv_hdr); + hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc, + rx_tlv_hdr); tid = hal_rx_mpdu_start_tid_get(hal_soc, rx_tlv_hdr); } @@ -1733,8 +2049,8 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx_tlv_hdr); nbuf->next = NULL; dp_2k_jump_handle(soc, nbuf, - peer_id, tid, - rx_tlv_hdr); + rx_tlv_hdr, + peer_id, tid); nbuf = next; if (peer) dp_peer_unref_del_find_by_id( @@ -1743,9 +2059,10 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, case HAL_REO_ERR_BAR_FRAME_2K_JUMP: case HAL_REO_ERR_BAR_FRAME_OOR: if (peer) - dp_rx_wbm_err_handle_bar(soc, - peer, - nbuf); + dp_rx_err_handle_bar(soc, + peer, + nbuf); + qdf_nbuf_free(nbuf); break; default: @@ -1761,6 +2078,12 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, DP_STATS_INC(soc, rx.err.rxdma_error [wbm_err_info.rxdma_err_code], 1); + /* increment @pdev level */ + pool_id = wbm_err_info.pool_id; + dp_pdev = dp_get_pdev_for_lmac_id(soc, pool_id); + if (dp_pdev) + DP_STATS_INC(dp_pdev, + err.rxdma_error, 1); switch (wbm_err_info.rxdma_err_code) { case HAL_RXDMA_ERR_UNENCRYPTED: @@ -1845,14 +2168,15 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, * Return: void */ static void dup_desc_dbg(struct dp_soc *soc, - void *rxdma_dst_ring_desc, + hal_rxdma_desc_t rxdma_dst_ring_desc, void *rx_desc) { DP_STATS_INC(soc, rx.err.hal_rxdma_err_dup, 1); - dp_rx_dump_info_and_assert(soc, - soc->rx_rel_ring.hal_srng, - rxdma_dst_ring_desc, - rx_desc); + dp_rx_dump_info_and_assert( + soc, + soc->rx_rel_ring.hal_srng, + hal_rxdma_desc_to_hal_ring_desc(rxdma_dst_ring_desc), + rx_desc); } /** @@ -1868,7 +2192,7 @@ static void dup_desc_dbg(struct dp_soc *soc, */ static inline uint32_t dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, - void *rxdma_dst_ring_desc, + hal_rxdma_desc_t rxdma_dst_ring_desc, union dp_rx_desc_list_elem_t **head, union dp_rx_desc_list_elem_t **tail) { @@ -1878,23 +2202,22 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, struct hal_rx_msdu_list msdu_list; uint16_t num_msdus; struct hal_buf_info buf_info; - void *p_buf_addr_info; - void *p_last_buf_addr_info; uint32_t rx_bufs_used = 0; uint32_t msdu_cnt; uint32_t i; uint8_t push_reason; uint8_t rxdma_error_code = 0; uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); - void *ring_desc; + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; + hal_rxdma_desc_t ring_desc; msdu = 0; last = NULL; hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, - &p_last_buf_addr_info, &msdu_cnt); + &msdu_cnt); push_reason = hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc); @@ -1907,7 +2230,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, rx_msdu_link_desc = dp_rx_cookie_2_link_desc_va(soc, &buf_info); - qdf_assert(rx_msdu_link_desc); + qdf_assert_always(rx_msdu_link_desc); hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, &msdu_list, &num_msdus); @@ -1973,15 +2296,23 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, rxdma_error_code = HAL_RXDMA_ERR_WAR; } - hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info, - &p_buf_addr_info); - - dp_rx_link_desc_return(soc, p_last_buf_addr_info, bm_action); - p_last_buf_addr_info = p_buf_addr_info; - + /* + * Store the current link buffer into to the local structure + * to be used for release purpose. + */ + hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr, + buf_info.sw_cookie, buf_info.rbm); + + hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info); + dp_rx_link_desc_return_by_addr(soc, + (hal_buff_addrinfo_t) + rx_link_buf_info, + bm_action); } while (buf_info.paddr); DP_STATS_INC(soc, rx.err.rxdma_error[rxdma_error_code], 1); + if (pdev) + DP_STATS_INC(pdev, err.rxdma_error, 1); if (rxdma_error_code == HAL_RXDMA_ERR_DECRYPT) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -1995,10 +2326,9 @@ uint32_t dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); - int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); - void *hal_soc; - void *rxdma_dst_ring_desc; + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + hal_rxdma_desc_t rxdma_dst_ring_desc; + hal_soc_handle_t hal_soc; void *err_dst_srng; union dp_rx_desc_list_elem_t *head = NULL; union dp_rx_desc_list_elem_t *tail = NULL; @@ -2010,7 +2340,7 @@ dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, if (!pdev) return 0; - err_dst_srng = pdev->rxdma_err_dst_ring[mac_for_pdev].hal_srng; + err_dst_srng = soc->rxdma_err_dst_ring[mac_id].hal_srng; if (!err_dst_srng) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -2043,7 +2373,10 @@ dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, dp_srng_access_end(int_ctx, soc, err_dst_srng); if (rx_bufs_used) { - dp_rxdma_srng = &pdev->rx_refill_buf_ring; + if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx)) + dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id]; + else + dp_rxdma_srng = &soc->rx_refill_buf_ring[pdev->lmac_id]; rx_desc_pool = &soc->rx_desc_buf[mac_id]; dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng, @@ -2054,3 +2387,154 @@ dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, return work_done; } + +static inline uint32_t +dp_wbm_int_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, + hal_rxdma_desc_t rxdma_dst_ring_desc, + union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail) +{ + void *rx_msdu_link_desc; + qdf_nbuf_t msdu; + qdf_nbuf_t last; + struct hal_rx_msdu_list msdu_list; + uint16_t num_msdus; + struct hal_buf_info buf_info; + uint32_t rx_bufs_used = 0, msdu_cnt, i; + uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; + + msdu = 0; + + last = NULL; + + hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, + &msdu_cnt); + + do { + rx_msdu_link_desc = + dp_rx_cookie_2_link_desc_va(soc, &buf_info); + + if (!rx_msdu_link_desc) { + DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_LINK_DESC], 1); + break; + } + + hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, + &msdu_list, &num_msdus); + + if (msdu_list.sw_cookie[0] != HAL_RX_COOKIE_SPECIAL) { + for (i = 0; i < num_msdus; i++) { + struct dp_rx_desc *rx_desc = + dp_rx_cookie_2_va_rxdma_buf( + soc, + msdu_list.sw_cookie[i]); + qdf_assert_always(rx_desc); + msdu = rx_desc->nbuf; + + qdf_nbuf_unmap_single(soc->osdev, msdu, + QDF_DMA_FROM_DEVICE); + + qdf_nbuf_free(msdu); + rx_bufs_used++; + dp_rx_add_to_free_desc_list(head, + tail, rx_desc); + } + } + + /* + * Store the current link buffer into to the local structure + * to be used for release purpose. + */ + hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr, + buf_info.sw_cookie, buf_info.rbm); + + hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info); + dp_rx_link_desc_return_by_addr(soc, (hal_buff_addrinfo_t) + rx_link_buf_info, + HAL_BM_ACTION_PUT_IN_IDLE_LIST); + } while (buf_info.paddr); + + return rx_bufs_used; +} + +/* + * + * dp_handle_wbm_internal_error() - handles wbm_internal_error case + * + * @soc: core DP main context + * @hal_desc: hal descriptor + * @buf_type: indicates if the buffer is of type link disc or msdu + * Return: None + * + * wbm_internal_error is seen in following scenarios : + * + * 1. Null pointers detected in WBM_RELEASE_RING descriptors + * 2. Null pointers detected during delinking process + * + * Some null pointer cases: + * + * a. MSDU buffer pointer is NULL + * b. Next_MSDU_Link_Desc pointer is NULL, with no last msdu flag + * c. MSDU buffer pointer is NULL or Next_Link_Desc pointer is NULL + */ +void +dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc, + uint32_t buf_type) +{ + struct hal_buf_info buf_info = {0}; + struct dp_pdev *dp_pdev; + struct dp_rx_desc *rx_desc = NULL; + uint32_t rx_buf_cookie; + uint32_t rx_bufs_reaped = 0; + union dp_rx_desc_list_elem_t *head = NULL; + union dp_rx_desc_list_elem_t *tail = NULL; + uint8_t pool_id; + + hal_rx_reo_buf_paddr_get(hal_desc, &buf_info); + + if (!buf_info.paddr) { + DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_BUFFER], 1); + return; + } + + rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(hal_desc); + pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(rx_buf_cookie); + + if (buf_type == HAL_WBM_RELEASE_RING_2_BUFFER_TYPE) { + DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_MSDU_BUFF], 1); + rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie); + + if (rx_desc && rx_desc->nbuf) { + qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf, + QDF_DMA_FROM_DEVICE); + + rx_desc->unmapped = 1; + + qdf_nbuf_free(rx_desc->nbuf); + dp_rx_add_to_free_desc_list(&head, + &tail, + rx_desc); + + rx_bufs_reaped++; + } + } else if (buf_type == HAL_WBM_RELEASE_RING_2_DESC_TYPE) { + rx_bufs_reaped = dp_wbm_int_err_mpdu_pop(soc, pool_id, + hal_desc, + &head, &tail); + } + + if (rx_bufs_reaped) { + struct rx_desc_pool *rx_desc_pool; + struct dp_srng *dp_rxdma_srng; + + DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_BUFF_REAPED], 1); + dp_pdev = dp_get_pdev_for_lmac_id(soc, pool_id); + dp_rxdma_srng = &soc->rx_refill_buf_ring[pool_id]; + rx_desc_pool = &soc->rx_desc_buf[pool_id]; + + dp_rx_buffers_replenish(soc, pool_id, dp_rxdma_srng, + rx_desc_pool, + rx_bufs_reaped, + &head, &tail); + } +} diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h index 975b2418877c4287c0857e0e1cb1712c19a13ff0..80eda34f67425be62faf80f6817ae52a6fc6e430 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -45,15 +45,9 @@ QDF_STATUS dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev, int mac_id); * * Return: QDF_STATUS */ -QDF_STATUS dp_reset_monitor_mode(struct cdp_pdev *pdev_handle); - -/** - * dp_pdev_configure_monitor_rings() - configure monitor rings - * @vdev_handle: Datapath VDEV handle - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_pdev_configure_monitor_rings(struct dp_pdev *pdev); +QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + uint8_t smart_monitor); /** * dp_mon_link_free() - free monitor link desc pool @@ -95,6 +89,13 @@ QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, uint32_t mac_id); uint32_t dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, uint32_t mac_id, uint32_t quota); +/** + * dp_mon_buf_delayed_replenish() - Helper routine to replenish monitor dest buf + * @pdev: DP pdev object + * + * Return: None + */ +void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev); #ifndef REMOVE_MON_DBG_STATS /* * dp_rx_mon_update_dbg_ppdu_stats() - Update status ring TLV count diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c index 39cb49200440e6635b61af035cf8cec369a5556a..07a9760e4ee3b1e95cca6c842ff8067eb92a8645 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -55,23 +55,22 @@ */ static QDF_STATUS dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, - void *buf_addr_info, int mac_id) + hal_buff_addrinfo_t buf_addr_info, int mac_id) { struct dp_srng *dp_srng; - void *hal_srng; - void *hal_soc; + hal_ring_handle_t hal_ring_hdl; + hal_soc_handle_t hal_soc; QDF_STATUS status = QDF_STATUS_E_FAILURE; void *src_srng_desc; - int mac_for_pdev = dp_get_mac_id_for_mac(dp_pdev->soc, mac_id); hal_soc = dp_pdev->soc->hal_soc; - dp_srng = &dp_pdev->rxdma_mon_desc_ring[mac_for_pdev]; - hal_srng = dp_srng->hal_srng; + dp_srng = &dp_pdev->soc->rxdma_mon_desc_ring[mac_id]; + hal_ring_hdl = dp_srng->hal_srng; - qdf_assert(hal_srng); + qdf_assert(hal_ring_hdl); - if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_srng))) { + if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_ring_hdl))) { /* TODO */ /* @@ -81,11 +80,11 @@ dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : \ HAL RING Access For WBM Release SRNG Failed -- %pK", - __func__, __LINE__, hal_srng); + __func__, __LINE__, hal_ring_hdl); goto done; } - src_srng_desc = hal_srng_src_get_next(hal_soc, hal_srng); + src_srng_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (qdf_likely(src_srng_desc)) { /* Return link descriptor through WBM ring (SW2WBM)*/ @@ -98,7 +97,7 @@ dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, __func__, __LINE__); } done: - hal_srng_access_end(hal_soc, hal_srng); + hal_srng_access_end(hal_soc, hal_ring_hdl); return status; } @@ -114,8 +113,8 @@ dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, static inline void dp_mon_adjust_frag_len(uint32_t *total_len, uint32_t *frag_len) { - if (*total_len >= (RX_BUFFER_SIZE - RX_PKT_TLVS_LEN)) { - *frag_len = RX_BUFFER_SIZE - RX_PKT_TLVS_LEN; + if (*total_len >= (RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN)) { + *frag_len = RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN; *total_len -= *frag_len; } else { *frag_len = *total_len; @@ -153,14 +152,15 @@ void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev, */ static inline QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev, - void *p_last_buf_addr_info, + hal_buff_addrinfo_t + p_last_buf_addr_info, uint8_t mac_id, uint8_t bm_action) { if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info, mac_id); - return dp_rx_link_desc_return(pdev->soc, p_last_buf_addr_info, + return dp_rx_link_desc_return_by_addr(pdev->soc, p_last_buf_addr_info, bm_action); } @@ -177,9 +177,9 @@ void *dp_rxdma_get_mon_dst_ring(struct dp_pdev *pdev, uint8_t mac_for_pdev) { if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) - return pdev->rxdma_mon_dst_ring[mac_for_pdev].hal_srng; + return pdev->soc->rxdma_mon_dst_ring[mac_for_pdev].hal_srng; - return pdev->rxdma_err_dst_ring[mac_for_pdev].hal_srng; + return pdev->soc->rxdma_err_dst_ring[mac_for_pdev].hal_srng; } /** @@ -195,9 +195,10 @@ struct dp_srng *dp_rxdma_get_mon_buf_ring(struct dp_pdev *pdev, uint8_t mac_for_pdev) { if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) - return &pdev->rxdma_mon_buf_ring[mac_for_pdev]; + return &pdev->soc->rxdma_mon_buf_ring[mac_for_pdev]; - return &pdev->rx_refill_buf_ring; + /* For MCL there is only 1 rx refill ring */ + return &pdev->soc->rx_refill_buf_ring[0]; } /** @@ -255,12 +256,12 @@ struct dp_rx_desc *dp_rx_get_mon_desc(struct dp_soc *soc, */ static inline uint32_t dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, - void *rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu, + hal_rxdma_desc_t rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *npackets, uint32_t *ppdu_id, union dp_rx_desc_list_elem_t **head, union dp_rx_desc_list_elem_t **tail) { - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); void *rx_desc_tlv; void *rx_msdu_link_desc; qdf_nbuf_t msdu; @@ -269,8 +270,6 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, uint16_t num_msdus; uint32_t rx_buf_size, rx_pkt_offset; struct hal_buf_info buf_info; - void *p_buf_addr_info; - void *p_last_buf_addr_info; uint32_t rx_bufs_used = 0; uint32_t msdu_ppdu_id, msdu_cnt; uint8_t *data; @@ -280,13 +279,13 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, bool drop_mpdu = false; uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; uint64_t nbuf_paddr = 0; + uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; msdu = 0; last = NULL; - hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, - &p_last_buf_addr_info, &msdu_cnt); + hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, &msdu_cnt); if ((hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc) == HAL_RX_WBM_RXDMA_PSH_RSN_ERROR)) { @@ -316,7 +315,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, dp_rx_cookie_2_mon_link_desc(dp_pdev, buf_info, mac_id); - qdf_assert(rx_msdu_link_desc); + qdf_assert_always(rx_msdu_link_desc); hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, &msdu_list, &num_msdus); @@ -383,7 +382,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, goto next_msdu; } - msdu_ppdu_id = HAL_RX_HW_DESC_GET_PPDUID_GET( + msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get( + soc->hal_soc, rx_desc_tlv); is_first_msdu = false; @@ -415,7 +415,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, buf_info.paddr; } - if (hal_rx_desc_is_first_msdu(rx_desc_tlv)) + if (hal_rx_desc_is_first_msdu(soc->hal_soc, + rx_desc_tlv)) hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc, rx_desc_tlv, &(dp_pdev->ppdu_info.rx_status)); @@ -446,7 +447,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, __func__, total_frag_len, frag_len, msdu_list.msdu_info[i].msdu_flags); - rx_pkt_offset = HAL_RX_MON_HW_RX_DESC_SIZE(); + rx_pkt_offset = SIZE_OF_MONITOR_TLV; /* * HW structures call this L3 header padding * -- even though this is actually the offset @@ -454,7 +455,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, * header begins. */ l2_hdr_offset = - hal_rx_msdu_end_l3_hdr_padding_get(data); + hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, data); rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; @@ -503,18 +504,21 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, tail, rx_desc); } - hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info, - &p_buf_addr_info); + /* + * Store the current link buffer into to the local + * structure to be used for release purpose. + */ + hal_rxdma_buff_addr_info_set(rx_link_buf_info, buf_info.paddr, + buf_info.sw_cookie, buf_info.rbm); + hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info); if (dp_rx_monitor_link_desc_return(dp_pdev, - p_last_buf_addr_info, + (hal_buff_addrinfo_t) + rx_link_buf_info, mac_id, bm_action) != QDF_STATUS_SUCCESS) dp_err_rl("monitor link desc return failed"); - - p_last_buf_addr_info = p_buf_addr_info; - } while (buf_info.paddr && msdu_cnt); if (last) @@ -527,14 +531,14 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, } static inline -void dp_rx_msdus_set_payload(qdf_nbuf_t msdu) +void dp_rx_msdus_set_payload(struct dp_soc *soc, qdf_nbuf_t msdu) { uint8_t *data; uint32_t rx_pkt_offset, l2_hdr_offset; data = qdf_nbuf_data(msdu); - rx_pkt_offset = HAL_RX_MON_HW_RX_DESC_SIZE(); - l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(data); + rx_pkt_offset = SIZE_OF_MONITOR_TLV; + l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, data); qdf_nbuf_pull_head(msdu, rx_pkt_offset + l2_hdr_offset); } @@ -552,7 +556,7 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, unsigned char *dest; struct ieee80211_frame *wh; struct ieee80211_qoscntl *qos; - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); head_frag_list = NULL; mpdu_buf = NULL; @@ -594,7 +598,7 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, * - but the RX status is usually enough */ - dp_rx_msdus_set_payload(head_msdu); + dp_rx_msdus_set_payload(soc, head_msdu); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK", @@ -611,7 +615,7 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, while (msdu) { - dp_rx_msdus_set_payload(msdu); + dp_rx_msdus_set_payload(soc, msdu); if (is_first_frag) { is_first_frag = 0; @@ -757,8 +761,9 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, is_first_frag = 0; } - /* Update protocol tag for MSDU */ - dp_rx_mon_update_protocol_tag(soc, dp_pdev, msdu_orig, rx_desc); + /* Update protocol and flow tag for MSDU */ + dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, + msdu_orig, rx_desc); dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad); @@ -769,7 +774,7 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, dest += amsdu_pad; qdf_mem_copy(dest, hdr_desc, msdu_llc_len); - dp_rx_msdus_set_payload(msdu); + dp_rx_msdus_set_payload(soc, msdu); /* Push the MSDU buffer beyond the decap header */ qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes); @@ -930,7 +935,7 @@ void dp_rx_extract_radiotap_info(struct cdp_mon_status *rx_status, QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); struct cdp_mon_status *rs = &pdev->rx_mon_recv_status; qdf_nbuf_t mon_skb, skb_next; qdf_nbuf_t mon_mpdu = NULL; @@ -955,15 +960,14 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, pdev->ppdu_info.rx_status.device_id = soc->device_id; pdev->ppdu_info.rx_status.chan_noise_floor = pdev->chan_noise_floor; - /* - * if chan_num is not fetched correctly from ppdu RX TLV, - * get it from pdev saved. - */ - if (pdev->ppdu_info.rx_status.chan_num == 0) - pdev->ppdu_info.rx_status.chan_num = pdev->mon_chan_num; - qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), - mon_mpdu, sizeof(struct rx_pkt_tlvs)); + if (!qdf_nbuf_update_radiotap(&pdev->ppdu_info.rx_status, + mon_mpdu, + qdf_nbuf_headroom(mon_mpdu))) { + DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); + goto mon_deliver_fail; + } + pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev, mon_mpdu, &pdev->ppdu_info.rx_status); @@ -1006,7 +1010,7 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, uint32_t mac_id) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); ol_txrx_rx_mon_fp osif_rx_mon; qdf_nbuf_t dummy_msdu; @@ -1028,8 +1032,12 @@ QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, pdev->ppdu_info.com_info.ppdu_id; /* Apply the radio header to this dummy skb */ - qdf_nbuf_update_radiotap(&pdev->ppdu_info.rx_status, - dummy_msdu, MAX_MONITOR_HEADER); + if (!qdf_nbuf_update_radiotap(&pdev->ppdu_info.rx_status, dummy_msdu, + qdf_nbuf_headroom(dummy_msdu))) { + DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); + qdf_nbuf_free(dummy_msdu); + goto mon_deliver_non_std_fail; + } /* deliver to the user layer application */ osif_rx_mon(pdev->monitor_vdev->osif_vdev, @@ -1064,17 +1072,17 @@ QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, */ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); uint8_t pdev_id; - void *hal_soc; - void *rxdma_dst_ring_desc; + hal_rxdma_desc_t rxdma_dst_ring_desc; + hal_soc_handle_t hal_soc; void *mon_dst_srng; union dp_rx_desc_list_elem_t *head = NULL; union dp_rx_desc_list_elem_t *tail = NULL; uint32_t ppdu_id; uint32_t rx_bufs_used; uint32_t mpdu_rx_bufs_used; - int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); + int mac_for_pdev = mac_id; struct cdp_pdev_mon_stats *rx_mon_stats; mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev); @@ -1178,7 +1186,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) } #ifndef DISABLE_MON_CONFIG -#ifndef QCA_WIFI_QCA6390 +#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \ + !defined(QCA_WIFI_QCA6750) /** * dp_rx_pdev_mon_buf_attach() - Allocate the monitor descriptor pool * @@ -1187,20 +1196,18 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) * * Return: QDF_STATUS */ +#define MON_BUF_MIN_ALLOC_ENTRIES 128 static QDF_STATUS dp_rx_pdev_mon_buf_attach(struct dp_pdev *pdev, int mac_id) { uint8_t pdev_id = pdev->pdev_id; struct dp_soc *soc = pdev->soc; - union dp_rx_desc_list_elem_t *desc_list = NULL; - union dp_rx_desc_list_elem_t *tail = NULL; struct dp_srng *mon_buf_ring; uint32_t num_entries; struct rx_desc_pool *rx_desc_pool; QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); - uint32_t rx_desc_pool_size; + uint32_t rx_desc_pool_size, replenish_size; - mon_buf_ring = &pdev->rxdma_mon_buf_ring[mac_for_pdev]; + mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id]; num_entries = mon_buf_ring->num_entries; @@ -1209,17 +1216,20 @@ dp_rx_pdev_mon_buf_attach(struct dp_pdev *pdev, int mac_id) { dp_debug("Mon RX Desc Pool[%d] entries=%u", pdev_id, num_entries); - rx_desc_pool_size = DP_RX_DESC_ALLOC_MULTIPLIER * num_entries; + rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc->wlan_cfg_ctx) * num_entries; status = dp_rx_desc_pool_alloc(soc, mac_id, rx_desc_pool_size, rx_desc_pool); if (!QDF_IS_STATUS_SUCCESS(status)) return status; rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM; + rx_desc_pool->buf_size = RX_MONITOR_BUFFER_SIZE; + rx_desc_pool->buf_alignment = RX_MONITOR_BUFFER_ALIGNMENT; - status = dp_rx_buffers_replenish(soc, mac_id, mon_buf_ring, - rx_desc_pool, num_entries, - &desc_list, &tail); + replenish_size = ((num_entries - 1) < MON_BUF_MIN_ALLOC_ENTRIES) ? + (num_entries - 1) : MON_BUF_MIN_ALLOC_ENTRIES; + status = dp_pdev_rx_buffers_attach(soc, mac_id, mon_buf_ring, + rx_desc_pool, replenish_size); return status; } @@ -1255,8 +1265,6 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id) static QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) { - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(soc, mac_id); - int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); int link_desc_size = hal_get_link_desc_size(soc->hal_soc); int link_desc_align = hal_get_link_desc_align(soc->hal_soc); uint32_t max_alloc_size = wlan_cfg_max_alloc_size(soc->wlan_cfg_ctx); @@ -1270,7 +1278,7 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) int i; qdf_dma_addr_t *baseaddr = NULL; - dp_srng = &dp_pdev->rxdma_mon_desc_ring[mac_for_pdev]; + dp_srng = &soc->rxdma_mon_desc_ring[mac_id]; num_entries = dp_srng->alloc_size/hal_srng_get_entrysize( soc->hal_soc, RXDMA_MONITOR_DESC); @@ -1306,17 +1314,17 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) __func__, max_alloc_size, last_bank_size); for (i = 0; i < num_link_desc_banks; i++) { - baseaddr = &dp_pdev->link_desc_banks[mac_for_pdev][i]. + baseaddr = &soc->mon_link_desc_banks[mac_id][i]. base_paddr_unaligned; if (!dp_is_soc_reinit(soc)) { - dp_pdev->link_desc_banks[mac_for_pdev][i]. + soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned = qdf_mem_alloc_consistent(soc->osdev, soc->osdev->dev, max_alloc_size, baseaddr); - if (!dp_pdev->link_desc_banks[mac_for_pdev][i]. + if (!soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1325,25 +1333,25 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) goto fail; } } - dp_pdev->link_desc_banks[mac_for_pdev][i].size = max_alloc_size; + soc->mon_link_desc_banks[mac_id][i].size = max_alloc_size; - dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr = + soc->mon_link_desc_banks[mac_id][i].base_vaddr = (void *)((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. + (soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned) + ((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. + (soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned) % link_desc_align)); - dp_pdev->link_desc_banks[mac_for_pdev][i].base_paddr = + soc->mon_link_desc_banks[mac_id][i].base_paddr = (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. + (soc->mon_link_desc_banks[mac_id][i]. base_paddr_unaligned) + ((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr) - + (soc->mon_link_desc_banks[mac_id][i].base_vaddr) - (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. + (soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned)); } @@ -1351,17 +1359,17 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) /* Allocate last bank in case total memory required is not exact * multiple of max_alloc_size */ - baseaddr = &dp_pdev->link_desc_banks[mac_for_pdev][i]. + baseaddr = &soc->mon_link_desc_banks[mac_id][i]. base_paddr_unaligned; if (!dp_is_soc_reinit(soc)) { - dp_pdev->link_desc_banks[mac_for_pdev][i]. + soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned = qdf_mem_alloc_consistent(soc->osdev, soc->osdev->dev, last_bank_size, baseaddr); - if (!dp_pdev->link_desc_banks[mac_for_pdev][i]. + if (!soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1370,33 +1378,34 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) goto fail; } } - dp_pdev->link_desc_banks[mac_for_pdev][i].size = last_bank_size; + soc->mon_link_desc_banks[mac_id][i].size = + last_bank_size; - dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr = + soc->mon_link_desc_banks[mac_id][i].base_vaddr = (void *)((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned) + + (soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned) + ((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned) % + (soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned) % link_desc_align)); - dp_pdev->link_desc_banks[mac_for_pdev][i].base_paddr = + soc->mon_link_desc_banks[mac_id][i].base_paddr = (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_paddr_unaligned) + + (soc->mon_link_desc_banks[mac_id][i]. + base_paddr_unaligned) + ((unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr) - + (soc->mon_link_desc_banks[mac_id][i].base_vaddr) - (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned)); + (soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned)); } /* Allocate and setup link descriptor idle list for HW internal use */ entry_size = hal_srng_get_entrysize(soc->hal_soc, RXDMA_MONITOR_DESC); total_mem_size = entry_size * total_link_descs; - mon_desc_srng = dp_pdev->rxdma_mon_desc_ring[mac_for_pdev].hal_srng; + mon_desc_srng = soc->rxdma_mon_desc_ring[mac_id].hal_srng; num_replenish_buf = 0; @@ -1405,22 +1414,22 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) for (i = 0; - i < MAX_MON_LINK_DESC_BANKS && - dp_pdev->link_desc_banks[mac_for_pdev][i].base_paddr; - i++) { + i < MAX_MON_LINK_DESC_BANKS && + soc->mon_link_desc_banks[mac_id][i].base_paddr; + i++) { uint32_t num_entries = - (dp_pdev->link_desc_banks[mac_for_pdev][i].size - + (soc->mon_link_desc_banks[mac_id][i].size - (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr) - + (soc->mon_link_desc_banks[mac_id][i].base_vaddr) - (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i]. + (soc->mon_link_desc_banks[mac_id][i]. base_vaddr_unaligned)) / link_desc_size; unsigned long paddr = (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i].base_paddr); + (soc->mon_link_desc_banks[mac_id][i].base_paddr); unsigned long vaddr = (unsigned long) - (dp_pdev->link_desc_banks[mac_for_pdev][i].base_vaddr); + (soc->mon_link_desc_banks[mac_id][i].base_vaddr); hal_srng_access_start_unlocked(soc->hal_soc, mon_desc_srng); @@ -1429,7 +1438,7 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) hal_srng_src_get_next(soc->hal_soc, mon_desc_srng))) { - hal_set_link_desc_addr(desc, i, paddr); + hal_set_link_desc_addr(desc, i, paddr); num_entries--; num_replenish_buf++; paddr += link_desc_size; @@ -1450,16 +1459,17 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) fail: for (i = 0; i < MAX_MON_LINK_DESC_BANKS; i++) { - if (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - dp_pdev->link_desc_banks[mac_for_pdev][i].size, - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned, - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_paddr_unaligned, 0); - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned = NULL; + if (soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned) { + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + soc->mon_link_desc_banks[mac_id][i]. + size, + soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned, + soc->mon_link_desc_banks[mac_id][i]. + base_paddr_unaligned, 0); + soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned = NULL; } } return QDF_STATUS_E_FAILURE; @@ -1471,24 +1481,62 @@ QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) static void dp_mon_link_desc_pool_cleanup(struct dp_soc *soc, uint32_t mac_id) { - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(soc, mac_id); - int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); int i; for (i = 0; i < MAX_MON_LINK_DESC_BANKS; i++) { - if (dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned) { - qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, - dp_pdev->link_desc_banks[mac_for_pdev][i].size, - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned, - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_paddr_unaligned, 0); - dp_pdev->link_desc_banks[mac_for_pdev][i]. - base_vaddr_unaligned = NULL; + if (soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned) { + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + soc->mon_link_desc_banks[mac_id][i]. + size, + soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned, + soc->mon_link_desc_banks[mac_id][i]. + base_paddr_unaligned, 0); + soc->mon_link_desc_banks[mac_id][i]. + base_vaddr_unaligned = NULL; } } } + +/** + * dp_mon_buf_delayed_replenish() - Helper routine to replenish monitor dest buf + * @pdev: DP pdev object + * + * Return: None + */ +void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev) +{ + struct dp_soc *soc; + uint32_t mac_for_pdev; + union dp_rx_desc_list_elem_t *tail = NULL; + union dp_rx_desc_list_elem_t *desc_list = NULL; + uint32_t num_entries; + uint32_t id; + + soc = pdev->soc; + num_entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev->wlan_cfg_ctx); + + for (id = 0; id < NUM_RXDMA_RINGS_PER_PDEV; id++) { + /* + * Get mac_for_pdev appropriately for both MCL & WIN, + * since MCL have multiple mon buf rings and WIN just + * has one mon buffer ring mapped per pdev, below API + * helps identify accurate buffer_ring for both cases + * + */ + mac_for_pdev = + dp_get_lmac_id_for_pdev_id(soc, id, pdev->pdev_id); + + dp_rx_buffers_replenish(soc, mac_for_pdev, + dp_rxdma_get_mon_buf_ring(pdev, + mac_for_pdev), + dp_rx_get_mon_desc_pool(soc, + mac_for_pdev, + pdev->pdev_id), + num_entries, &desc_list, &tail); + } +} #else static QDF_STATUS dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) @@ -1512,6 +1560,9 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id) { return QDF_STATUS_SUCCESS; } + +void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev) +{} #endif /** @@ -1529,7 +1580,7 @@ static QDF_STATUS dp_rx_pdev_mon_cmn_detach(struct dp_pdev *pdev, int mac_id) { struct dp_soc *soc = pdev->soc; uint8_t pdev_id = pdev->pdev_id; - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); + int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); dp_mon_link_desc_pool_cleanup(soc, mac_for_pdev); dp_rx_pdev_mon_status_detach(pdev, mac_for_pdev); @@ -1553,7 +1604,7 @@ static QDF_STATUS dp_rx_pdev_mon_cmn_attach(struct dp_pdev *pdev, int mac_id) { struct dp_soc *soc = pdev->soc; uint8_t pdev_id = pdev->pdev_id; - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); + int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); QDF_STATUS status; status = dp_rx_pdev_mon_buf_attach(pdev, mac_for_pdev); @@ -1635,7 +1686,8 @@ dp_mon_link_free(struct dp_pdev *pdev) { int mac_id; for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); + int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, + mac_id, pdev_id); dp_mon_link_desc_pool_cleanup(soc, mac_for_pdev); } @@ -1660,7 +1712,8 @@ dp_rx_pdev_mon_detach(struct dp_pdev *pdev) { qdf_spinlock_destroy(&pdev->mon_lock); for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { - int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id); + int mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, + mac_id, pdev_id); dp_rx_pdev_mon_status_detach(pdev, mac_for_pdev); dp_rx_pdev_mon_buf_detach(pdev, mac_for_pdev); @@ -1683,4 +1736,7 @@ QDF_STATUS dp_mon_link_free(struct dp_pdev *pdev) { return QDF_STATUS_SUCCESS; } + +void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev) +{} #endif /* DISABLE_MON_CONFIG */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c index 61afbb9193a30671ef2fb584b2ce0391047ab9a4..251b6d4a0d60193fec1056b22845b62c5cd27a56 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,10 +28,17 @@ #include "dp_internal.h" #include "qdf_mem.h" /* qdf_mem_malloc,free */ +#include "htt.h" + #ifdef FEATURE_PERPKT_INFO #include "dp_ratetable.h" #endif +static inline void +dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu); + #ifdef WLAN_RX_PKT_CAPTURE_ENH #include "dp_rx_mon_feature.h" #else @@ -51,99 +58,354 @@ dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status, } #endif -/** -* dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure -* @pdev: pdev ctx -* @ppdu_info: ppdu info structure from ppdu ring -* @ppdu_nbuf: qdf nbuf abstraction for linux skb -* -* Return: none -*/ +#ifdef WLAN_TX_PKT_CAPTURE_ENH +#include "dp_rx_mon_feature.h" +#else +static QDF_STATUS +dp_send_ack_frame_to_stack(struct dp_soc *soc, + struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef FEATURE_PERPKT_INFO static inline void -dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, - struct hal_rx_ppdu_info *ppdu_info, - qdf_nbuf_t ppdu_nbuf) +dp_rx_populate_rx_rssi_chain(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + uint8_t chain, bw; + int8_t rssi; + + for (chain = 0; chain < SS_COUNT; chain++) { + for (bw = 0; bw < MAX_BW; bw++) { + rssi = ppdu_info->rx_status.rssi_chain[chain][bw]; + if (rssi != DP_RSSI_INVAL) + cdp_rx_ppdu->rssi_chain[chain][bw] = rssi; + else + cdp_rx_ppdu->rssi_chain[chain][bw] = 0; + } + } +} + +/* + * dp_rx_populate_su_evm_details() - Populate su evm info + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu: rx ppdu indication structure + */ +static inline void +dp_rx_populate_su_evm_details(struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + uint8_t pilot_evm; + uint8_t nss_count; + uint8_t pilot_count; + + nss_count = ppdu_info->evm_info.nss_count; + pilot_count = ppdu_info->evm_info.pilot_count; + + if ((nss_count * pilot_count) > DP_RX_MAX_SU_EVM_COUNT) { + qdf_err("pilot evm count is more than expected"); + return; + } + cdp_rx_ppdu->evm_info.pilot_count = pilot_count; + cdp_rx_ppdu->evm_info.nss_count = nss_count; + + /* Populate evm for pilot_evm = nss_count*pilot_count */ + for (pilot_evm = 0; pilot_evm < nss_count * pilot_count; pilot_evm++) { + cdp_rx_ppdu->evm_info.pilot_evm[pilot_evm] = + ppdu_info->evm_info.pilot_evm[pilot_evm]; + } +} + +/** + * dp_rx_inc_rusize_cnt() - increment pdev stats based on RU size + * @pdev: pdev ctx + * @rx_user_status: mon rx user status + * + * Return: bool + */ +static inline bool +dp_rx_inc_rusize_cnt(struct dp_pdev *pdev, + struct mon_rx_user_status *rx_user_status) +{ + uint32_t ru_size; + bool is_data; + + ru_size = rx_user_status->ofdma_ru_size; + + if (dp_is_subtype_data(rx_user_status->frame_control)) { + DP_STATS_INC(pdev, + ul_ofdma.data_rx_ru_size[ru_size], 1); + is_data = true; + } else { + DP_STATS_INC(pdev, + ul_ofdma.nondata_rx_ru_size[ru_size], 1); + is_data = false; + } + + return is_data; +} + +/** + * dp_rx_populate_cdp_indication_ppdu_user() - Populate per user cdp indication + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu: Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu + *cdp_rx_ppdu) { struct dp_peer *peer; struct dp_soc *soc = pdev->soc; struct dp_ast_entry *ast_entry; - struct cdp_rx_indication_ppdu *cdp_rx_ppdu; uint32_t ast_index; + int i; + struct mon_rx_user_status *rx_user_status; + struct cdp_rx_stats_ppdu_user *rx_stats_peruser; + int ru_size; + bool is_data = false; + uint32_t num_users; + + num_users = ppdu_info->com_info.num_users; + for (i = 0; i < num_users; i++) { + if (i > OFDMA_NUM_USERS) + return; + + rx_user_status = &ppdu_info->rx_user_status[i]; + rx_stats_peruser = &cdp_rx_ppdu->user[i]; + + ast_index = rx_user_status->ast_index; + if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } + + ast_entry = soc->ast_table[ast_index]; + if (!ast_entry) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } + + peer = ast_entry->peer; + if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } - cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; + rx_stats_peruser->first_data_seq_ctrl = + rx_user_status->first_data_seq_ctrl; + + rx_stats_peruser->frame_control_info_valid = + rx_user_status->frame_control_info_valid; + rx_stats_peruser->frame_control = + rx_user_status->frame_control; + + rx_stats_peruser->tcp_msdu_count = + rx_user_status->tcp_msdu_count; + rx_stats_peruser->udp_msdu_count = + rx_user_status->udp_msdu_count; + rx_stats_peruser->other_msdu_count = + rx_user_status->other_msdu_count; + + rx_stats_peruser->num_msdu = + rx_stats_peruser->tcp_msdu_count + + rx_stats_peruser->udp_msdu_count + + rx_stats_peruser->other_msdu_count; + + rx_stats_peruser->preamble_type = + rx_user_status->preamble_type; + rx_stats_peruser->mpdu_cnt_fcs_ok = + rx_user_status->mpdu_cnt_fcs_ok; + rx_stats_peruser->mpdu_cnt_fcs_err = + rx_user_status->mpdu_cnt_fcs_err; + qdf_mem_copy(&rx_stats_peruser->mpdu_fcs_ok_bitmap, + &rx_user_status->mpdu_fcs_ok_bitmap, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(rx_user_status->mpdu_fcs_ok_bitmap[0])); + rx_stats_peruser->mpdu_ok_byte_count = + rx_user_status->mpdu_ok_byte_count; + rx_stats_peruser->mpdu_err_byte_count = + rx_user_status->mpdu_err_byte_count; + + cdp_rx_ppdu->num_mpdu += rx_user_status->mpdu_cnt_fcs_ok; + cdp_rx_ppdu->num_msdu += rx_stats_peruser->num_msdu; + rx_stats_peruser->retries = + CDP_FC_IS_RETRY_SET(rx_stats_peruser->frame_control) ? + rx_stats_peruser->mpdu_cnt_fcs_ok : 0; + + if (rx_stats_peruser->mpdu_cnt_fcs_ok > 1) + rx_stats_peruser->is_ampdu = 1; + else + rx_stats_peruser->is_ampdu = 0; + + rx_stats_peruser->tid = ppdu_info->rx_status.tid; + + qdf_mem_copy(rx_stats_peruser->mac_addr, + peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); + rx_stats_peruser->peer_id = peer->peer_ids[0]; + cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; + rx_stats_peruser->vdev_id = peer->vdev->vdev_id; + rx_stats_peruser->mu_ul_info_valid = 0; + + if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || + cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { + if (rx_user_status->mu_ul_info_valid) { + rx_stats_peruser->nss = rx_user_status->nss; + rx_stats_peruser->mcs = rx_user_status->mcs; + rx_stats_peruser->mu_ul_info_valid = + rx_user_status->mu_ul_info_valid; + rx_stats_peruser->ofdma_ru_start_index = + rx_user_status->ofdma_ru_start_index; + rx_stats_peruser->ofdma_ru_width = + rx_user_status->ofdma_ru_width; + rx_stats_peruser->user_index = i; + ru_size = rx_user_status->ofdma_ru_size; + /* + * max RU size will be equal to + * HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2 + */ + if (ru_size >= OFDMA_NUM_RU_SIZE) { + dp_err("invalid ru_size %d\n", + ru_size); + return; + } + is_data = dp_rx_inc_rusize_cnt(pdev, + rx_user_status); + } + if (is_data) { + /* counter to get number of MU OFDMA */ + pdev->stats.ul_ofdma.data_rx_ppdu++; + pdev->stats.ul_ofdma.data_users[num_users]++; + } + } + } +} + +/** + * dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu: Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + struct dp_peer *peer; + struct dp_soc *soc = pdev->soc; + struct dp_ast_entry *ast_entry; + uint32_t ast_index; + uint32_t i; cdp_rx_ppdu->first_data_seq_ctrl = ppdu_info->rx_status.first_data_seq_ctrl; cdp_rx_ppdu->frame_ctrl = ppdu_info->rx_status.frame_control; - cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; - cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len; - cdp_rx_ppdu->duration = ppdu_info->rx_status.duration; - cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw; cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count; cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count; cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count; - cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss; - cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs; - if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && - (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) - cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; - else - cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; - cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type; - cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; - cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >> - QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3; + /* num mpdu is consolidated and added together in num user loop */ cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok; - cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb; - cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; - cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num; - cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; + /* num msdu is consolidated and added together in num user loop */ cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count + - cdp_rx_ppdu->udp_msdu_count + - cdp_rx_ppdu->other_msdu_count); - cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; + cdp_rx_ppdu->udp_msdu_count + + cdp_rx_ppdu->other_msdu_count); + cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ? - ppdu_info->com_info.mpdu_cnt_fcs_ok : 0; + ppdu_info->com_info.mpdu_cnt_fcs_ok : 0; if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1) cdp_rx_ppdu->is_ampdu = 1; else cdp_rx_ppdu->is_ampdu = 0; - cdp_rx_ppdu->tid = ppdu_info->rx_status.tid; - cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; + ast_index = ppdu_info->rx_status.ast_index; if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; - return; + cdp_rx_ppdu->num_users = 0; + goto end; } ast_entry = soc->ast_table[ast_index]; if (!ast_entry) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; - return; + cdp_rx_ppdu->num_users = 0; + goto end; } peer = ast_entry->peer; if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; - return; + cdp_rx_ppdu->num_users = 0; + goto end; } qdf_mem_copy(cdp_rx_ppdu->mac_addr, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); cdp_rx_ppdu->peer_id = peer->peer_ids[0]; cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; + + cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; + cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len; + cdp_rx_ppdu->duration = ppdu_info->rx_status.duration; + cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw; + cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss; + cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs; + if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && + (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) + cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; + else + cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; + cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; + cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; + cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >> + QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3; + cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb; + cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; + cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num; + cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; + cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; + cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; + + dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu); + dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); + cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; + + cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor; + for (i = 0; i < MAX_CHAIN; i++) + cdp_rx_ppdu->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i]; + + cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast; + + cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; + + cdp_rx_ppdu->num_mpdu = 0; + cdp_rx_ppdu->num_msdu = 0; + + dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu); + + return; +end: + dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu); } #else static inline void dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, - struct hal_rx_ppdu_info *ppdu_info, - qdf_nbuf_t ppdu_nbuf) + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) { } #endif @@ -157,27 +419,33 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, */ #ifdef FEATURE_PERPKT_INFO static inline void dp_rx_rate_stats_update(struct dp_peer *peer, - struct cdp_rx_indication_ppdu *ppdu) + struct cdp_rx_indication_ppdu *ppdu, + uint32_t user) { uint32_t ratekbps = 0; uint32_t ppdu_rx_rate = 0; uint32_t nss = 0; uint32_t rix; + uint16_t ratecode; + struct cdp_rx_stats_ppdu_user *ppdu_user; if (!peer || !ppdu) return; - if (ppdu->u.nss == 0) + ppdu_user = &ppdu->user[user]; + + if (ppdu_user->nss == 0) nss = 0; else - nss = ppdu->u.nss - 1; + nss = ppdu_user->nss - 1; ratekbps = dp_getrateindex(ppdu->u.gi, - ppdu->u.mcs, + ppdu_user->mcs, nss, ppdu->u.preamble, ppdu->u.bw, - &rix); + &rix, + &ratecode); if (!ratekbps) return; @@ -188,109 +456,290 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, ppdu_rx_rate = dp_ath_rate_out(peer->stats.rx.avg_rx_rate); DP_STATS_UPD(peer, rx.rnd_avg_rx_rate, ppdu_rx_rate); ppdu->rx_ratekbps = ratekbps; + ppdu->rx_ratecode = ratecode; if (peer->vdev) peer->vdev->stats.rx.last_rx_rate = ratekbps; } -static void dp_rx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, +static void dp_rx_stats_update(struct dp_pdev *pdev, struct cdp_rx_indication_ppdu *ppdu) { struct dp_soc *soc = NULL; - uint8_t mcs, preamble, ac = 0; + uint8_t mcs, preamble, ac = 0, nss, ppdu_type; uint16_t num_msdu; - bool is_invalid_peer = false; - - mcs = ppdu->u.mcs; - preamble = ppdu->u.preamble; - num_msdu = ppdu->num_msdu; + uint8_t pkt_bw_offset; + struct dp_peer *peer; + struct cdp_rx_stats_ppdu_user *ppdu_user; + uint32_t i; + enum cdp_mu_packet_type mu_pkt_type; if (pdev) soc = pdev->soc; else return; - if (!peer) { - is_invalid_peer = true; - peer = pdev->invalid_peer; - } - if (!soc || soc->process_rx_status) return; - DP_STATS_UPD(peer, rx.rssi, ppdu->rssi); - if (peer->stats.rx.avg_rssi == INVALID_RSSI) - peer->stats.rx.avg_rssi = ppdu->rssi; - else - peer->stats.rx.avg_rssi = - DP_GET_AVG_RSSI(peer->stats.rx.avg_rssi, ppdu->rssi); - - if ((preamble == DOT11_A) || (preamble == DOT11_B)) - ppdu->u.nss = 1; - - if (ppdu->u.nss) - DP_STATS_INC(peer, rx.nss[ppdu->u.nss - 1], num_msdu); - - DP_STATS_INC(peer, rx.sgi_count[ppdu->u.gi], num_msdu); - DP_STATS_INC(peer, rx.bw[ppdu->u.bw], num_msdu); - DP_STATS_INC(peer, rx.reception_type[ppdu->u.ppdu_type], num_msdu); - DP_STATS_INCC(peer, rx.ampdu_cnt, num_msdu, ppdu->is_ampdu); - DP_STATS_INCC(peer, rx.non_ampdu_cnt, num_msdu, !(ppdu->is_ampdu)); - DP_STATS_UPD(peer, rx.rx_rate, mcs); - DP_STATS_INCC(peer, + preamble = ppdu->u.preamble; + ppdu_type = ppdu->u.ppdu_type; + + for (i = 0; i < ppdu->num_users; i++) { + ppdu_user = &ppdu->user[i]; + peer = dp_peer_find_by_id(soc, ppdu_user->peer_id); + + if (!peer) + peer = pdev->invalid_peer; + + ppdu->cookie = (void *)peer->wlanstats_ctx; + + if (ppdu_type == HAL_RX_TYPE_SU) { + mcs = ppdu->u.mcs; + nss = ppdu->u.nss; + } else { + mcs = ppdu_user->mcs; + nss = ppdu_user->nss; + } + + num_msdu = ppdu_user->num_msdu; + switch (ppdu->u.bw) { + case CMN_BW_20MHZ: + pkt_bw_offset = PKT_BW_GAIN_20MHZ; + break; + case CMN_BW_40MHZ: + pkt_bw_offset = PKT_BW_GAIN_40MHZ; + break; + case CMN_BW_80MHZ: + pkt_bw_offset = PKT_BW_GAIN_80MHZ; + break; + case CMN_BW_160MHZ: + pkt_bw_offset = PKT_BW_GAIN_160MHZ; + break; + default: + pkt_bw_offset = 0; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "Invalid BW index = %d", ppdu->u.bw); + } + + DP_STATS_UPD(peer, rx.rssi, (ppdu->rssi + pkt_bw_offset)); + + if (peer->stats.rx.avg_rssi == INVALID_RSSI) + peer->stats.rx.avg_rssi = + CDP_RSSI_IN(peer->stats.rx.rssi); + else + CDP_RSSI_UPDATE_AVG(peer->stats.rx.avg_rssi, + peer->stats.rx.rssi); + + if ((preamble == DOT11_A) || (preamble == DOT11_B)) + nss = 1; + + if (ppdu_type == HAL_RX_TYPE_SU) { + if (nss) { + DP_STATS_INC(peer, rx.nss[nss - 1], num_msdu); + DP_STATS_INC(peer, rx.ppdu_nss[nss - 1], 1); + } + + DP_STATS_INC(peer, rx.mpdu_cnt_fcs_ok, + ppdu_user->mpdu_cnt_fcs_ok); + DP_STATS_INC(peer, rx.mpdu_cnt_fcs_err, + ppdu_user->mpdu_cnt_fcs_err); + } + + if (ppdu_type >= HAL_RX_TYPE_MU_MIMO && + ppdu_type <= HAL_RX_TYPE_MU_OFDMA) { + if (ppdu_type == HAL_RX_TYPE_MU_MIMO) + mu_pkt_type = RX_TYPE_MU_MIMO; + else + mu_pkt_type = RX_TYPE_MU_OFDMA; + + if (nss) { + DP_STATS_INC(peer, rx.nss[nss - 1], num_msdu); + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].ppdu_nss[nss - 1], + 1); + } + + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_ok, + ppdu_user->mpdu_cnt_fcs_ok); + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_err, + ppdu_user->mpdu_cnt_fcs_err); + } + + DP_STATS_INC(peer, rx.sgi_count[ppdu->u.gi], num_msdu); + DP_STATS_INC(peer, rx.bw[ppdu->u.bw], num_msdu); + DP_STATS_INC(peer, rx.reception_type[ppdu->u.ppdu_type], + num_msdu); + DP_STATS_INC(peer, rx.ppdu_cnt[ppdu->u.ppdu_type], 1); + DP_STATS_INCC(peer, rx.ampdu_cnt, num_msdu, + ppdu_user->is_ampdu); + DP_STATS_INCC(peer, rx.non_ampdu_cnt, num_msdu, + !(ppdu_user->is_ampdu)); + DP_STATS_UPD(peer, rx.rx_rate, mcs); + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11A) && (preamble == DOT11_A))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11A) && (preamble == DOT11_A))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11B) && (preamble == DOT11_B))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11B) && (preamble == DOT11_B))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11A) && (preamble == DOT11_N))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11A) && (preamble == DOT11_N))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11AC) && (preamble == DOT11_AC))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11AC) && (preamble == DOT11_AC))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= (MAX_MCS - 1)) && (preamble == DOT11_AX))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < (MAX_MCS - 1)) && (preamble == DOT11_AX))); - /* - * If invalid TID, it could be a non-qos frame, hence do not update - * any AC counters - */ - ac = TID_TO_WME_AC(ppdu->tid); - if (ppdu->tid != HAL_TID_INVALID) - DP_STATS_INC(peer, rx.wme_ac_type[ac], num_msdu); - dp_peer_stats_notify(peer); - DP_STATS_UPD(peer, rx.last_rssi, ppdu->rssi); + DP_STATS_INCC(peer, + rx.su_ax_ppdu_cnt.mcs_count[MAX_MCS - 1], 1, + ((mcs >= (MAX_MCS - 1)) && (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.su_ax_ppdu_cnt.mcs_count[mcs], 1, + ((mcs < (MAX_MCS - 1)) && (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_OFDMA].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_OFDMA].ppdu.mcs_count[mcs], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_MIMO].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_MIMO].ppdu.mcs_count[mcs], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); - if (is_invalid_peer) - return; + /* + * If invalid TID, it could be a non-qos frame, hence do not + * update any AC counters + */ + ac = TID_TO_WME_AC(ppdu_user->tid); + + if (ppdu->tid != HAL_TID_INVALID) + DP_STATS_INC(peer, rx.wme_ac_type[ac], num_msdu); + dp_peer_stats_notify(pdev, peer); + DP_STATS_UPD(peer, rx.last_rssi, ppdu->rssi); + + if (peer == pdev->invalid_peer) + continue; - if (dp_is_subtype_data(ppdu->frame_ctrl)) - dp_rx_rate_stats_update(peer, ppdu); + if (dp_is_subtype_data(ppdu->frame_ctrl)) + dp_rx_rate_stats_update(peer, ppdu, i); #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE - dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, - &peer->stats, ppdu->peer_id, - UPDATE_PEER_STATS, pdev->pdev_id); + dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, + &peer->stats, ppdu->peer_id, + UPDATE_PEER_STATS, pdev->pdev_id); #endif + dp_peer_unref_del_find_by_id(peer); + } } #endif +/* + * dp_rx_get_fcs_ok_msdu() - get ppdu status buffer containing fcs_ok msdu + * @pdev: pdev object + * @ppdu_info: ppdu info object + * + * Return: nbuf + */ + +static inline qdf_nbuf_t +dp_rx_get_fcs_ok_msdu(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + uint16_t mpdu_fcs_ok; + qdf_nbuf_t status_nbuf = NULL; + unsigned long *fcs_ok_bitmap; + + if (qdf_unlikely(qdf_nbuf_is_queue_empty(&pdev->rx_ppdu_buf_q))) + return NULL; + + /* Obtain fcs_ok passed index from bitmap + * this index is used to get fcs passed first msdu payload + */ + + fcs_ok_bitmap = + (unsigned long *)&ppdu_info->com_info.mpdu_fcs_ok_bitmap[0]; + mpdu_fcs_ok = qdf_find_first_bit(fcs_ok_bitmap, + HAL_RX_MAX_MPDU); + + if (qdf_unlikely(mpdu_fcs_ok >= HAL_RX_MAX_MPDU)) + goto end; + + if (qdf_unlikely(!ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf)) + goto end; + + /* Get status buffer by indexing mpdu_fcs_ok index + * containing first msdu payload with fcs passed + * and clone the buffer + */ + status_nbuf = ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf; + ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].nbuf = NULL; + + /* Take ref of status nbuf as this nbuf is to be + * freeed by upper layer. + */ + qdf_nbuf_ref(status_nbuf); + ppdu_info->fcs_ok_msdu_info.first_msdu_payload = + ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].first_msdu_payload; + ppdu_info->fcs_ok_msdu_info.payload_len = + ppdu_info->ppdu_msdu_info[mpdu_fcs_ok].payload_len; + + +end: + /* Free the ppdu status buffer queue */ + qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q); + + qdf_mem_zero(&ppdu_info->ppdu_msdu_info, + (ppdu_info->com_info.mpdu_cnt_fcs_ok + + ppdu_info->com_info.mpdu_cnt_fcs_err) + * sizeof(struct hal_rx_msdu_payload_info)); + return status_nbuf; +} + +static inline void +dp_rx_handle_ppdu_status_buf(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + qdf_nbuf_t status_nbuf) +{ + qdf_nbuf_t dropnbuf; + + if (qdf_nbuf_queue_len(&pdev->rx_ppdu_buf_q) > + HAL_RX_MAX_MPDU) { + dropnbuf = qdf_nbuf_queue_remove(&pdev->rx_ppdu_buf_q); + qdf_nbuf_free(dropnbuf); + } + qdf_nbuf_queue_add(&pdev->rx_ppdu_buf_q, status_nbuf); +} /** * dp_rx_handle_mcopy_mode() - Allocate and deliver first MSDU payload * @soc: core txrx main context @@ -309,7 +758,7 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, struct ieee80211_frame *wh; uint32_t *nbuf_data; - if (!ppdu_info->msdu_info.first_msdu_payload) + if (!ppdu_info->fcs_ok_msdu_info.first_msdu_payload) return QDF_STATUS_SUCCESS; if (pdev->m_copy_id.rx_ppdu_id == ppdu_info->com_info.ppdu_id) @@ -317,11 +766,11 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id; - wh = (struct ieee80211_frame *)(ppdu_info->msdu_info.first_msdu_payload - + 4); - size = (ppdu_info->msdu_info.first_msdu_payload - + wh = (struct ieee80211_frame *) + (ppdu_info->fcs_ok_msdu_info.first_msdu_payload + 4); + + size = (ppdu_info->fcs_ok_msdu_info.first_msdu_payload - qdf_nbuf_data(nbuf)); - ppdu_info->msdu_info.first_msdu_payload = NULL; if (qdf_nbuf_pull_head(nbuf, size) == NULL) return QDF_STATUS_SUCCESS; @@ -333,11 +782,12 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, return QDF_STATUS_SUCCESS; } + ppdu_info->fcs_ok_msdu_info.first_msdu_payload = NULL; nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf); *nbuf_data = pdev->ppdu_info.com_info.ppdu_id; /* only retain RX MSDU payload in the skb */ qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - - ppdu_info->msdu_info.payload_len); + ppdu_info->fcs_ok_msdu_info.payload_len); dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc, nbuf, HTT_INVALID_PEER, WDI_NO_VAL, pdev->pdev_id); return QDF_STATUS_E_ALREADY; @@ -351,6 +801,55 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, } #endif +#ifdef FEATURE_PERPKT_INFO +static inline void +dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + uint32_t tlv_status, + qdf_nbuf_t status_nbuf) +{ + QDF_STATUS mcopy_status; + + if (qdf_unlikely(!ppdu_info->com_info.mpdu_cnt)) { + qdf_nbuf_free(status_nbuf); + return; + } + /* Add buffers to queue until we receive + * HAL_TLV_STATUS_PPDU_DONE + */ + dp_rx_handle_ppdu_status_buf(pdev, ppdu_info, status_nbuf); + + /* If tlv_status is PPDU_DONE, process rx_ppdu_buf_q + * and devliver fcs_ok msdu buffer + */ + if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { + if (qdf_unlikely(ppdu_info->com_info.mpdu_cnt != + (ppdu_info->com_info.mpdu_cnt_fcs_ok + + ppdu_info->com_info.mpdu_cnt_fcs_err))) { + qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q); + return; + } + /* Get rx ppdu status buffer having fcs ok msdu */ + status_nbuf = dp_rx_get_fcs_ok_msdu(pdev, ppdu_info); + if (status_nbuf) { + mcopy_status = dp_rx_handle_mcopy_mode(soc, pdev, + ppdu_info, + status_nbuf); + if (mcopy_status == QDF_STATUS_SUCCESS) + qdf_nbuf_free(status_nbuf); + } + } +} +#else +static inline void +dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + uint32_t tlv_status, + qdf_nbuf_t status_nbuf) +{ +} +#endif + /** * dp_rx_handle_smart_mesh_mode() - Deliver header for smart mesh * @soc: Datapath SOC handle @@ -395,14 +894,321 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev, /* Only retain RX MSDU payload in the skb */ qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - ppdu_info->msdu_info.payload_len); - qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), - nbuf, sizeof(struct rx_pkt_tlvs)); + if (!qdf_nbuf_update_radiotap(&pdev->ppdu_info.rx_status, nbuf, + qdf_nbuf_headroom(nbuf))) { + DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); + return 1; + } + pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev, nbuf, NULL); pdev->ppdu_info.rx_status.monitor_direct_used = 0; return 0; } +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/* + * dp_rx_mon_handle_cfr_mu_info() - Gather macaddr and ast_index of peer(s) in + * the PPDU received, this will be used for correlation of CFR data captured + * for an UL-MU-PPDU + * @pdev: pdev ctx + * @ppdu_info: pointer to ppdu info structure populated from ppdu status TLVs + * @cdp_rx_ppdu: Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + struct dp_peer *peer; + struct dp_soc *soc = pdev->soc; + struct dp_ast_entry *ast_entry; + struct mon_rx_user_status *rx_user_status; + struct cdp_rx_stats_ppdu_user *rx_stats_peruser; + uint32_t num_users; + int user_id; + uint32_t ast_index; + + qdf_spin_lock_bh(&soc->ast_lock); + + num_users = ppdu_info->com_info.num_users; + for (user_id = 0; user_id < num_users; user_id++) { + if (user_id > OFDMA_NUM_USERS) { + qdf_spin_unlock_bh(&soc->ast_lock); + return; + } + + rx_user_status = &ppdu_info->rx_user_status[user_id]; + rx_stats_peruser = &cdp_rx_ppdu->user[user_id]; + ast_index = rx_user_status->ast_index; + + if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } + + ast_entry = soc->ast_table[ast_index]; + if (!ast_entry) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } + + peer = ast_entry->peer; + if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) { + rx_stats_peruser->peer_id = HTT_INVALID_PEER; + continue; + } + + qdf_mem_copy(rx_stats_peruser->mac_addr, + peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); + } + + qdf_spin_unlock_bh(&soc->ast_lock); +} + +/* + * dp_rx_mon_populate_cfr_ppdu_info() - Populate cdp ppdu info from hal ppdu + * info + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu : Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + int chain; + + cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; + cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; + cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; + cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; + + for (chain = 0; chain < MAX_CHAIN; chain++) + cdp_rx_ppdu->per_chain_rssi[chain] = + ppdu_info->rx_status.rssi[chain]; + dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu); +} + +/** + * dp_cfr_rcc_mode_status() - Return status of cfr rcc mode + * @pdev: pdev ctx + * + * Return: True or False + */ + +static inline bool +dp_cfr_rcc_mode_status(struct dp_pdev *pdev) +{ + return pdev->cfr_rcc_mode; +} + +/* + * dp_rx_mon_populate_cfr_info() - Populate cdp ppdu info from hal cfr info + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu: Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + struct cdp_rx_ppdu_cfr_info *cfr_info; + + if (!dp_cfr_rcc_mode_status(pdev)) + return; + + cfr_info = &cdp_rx_ppdu->cfr_info; + + cfr_info->bb_captured_channel + = ppdu_info->cfr_info.bb_captured_channel; + cfr_info->bb_captured_timeout + = ppdu_info->cfr_info.bb_captured_timeout; + cfr_info->bb_captured_reason + = ppdu_info->cfr_info.bb_captured_reason; + cfr_info->rx_location_info_valid + = ppdu_info->cfr_info.rx_location_info_valid; + cfr_info->chan_capture_status + = ppdu_info->cfr_info.chan_capture_status; + cfr_info->rtt_che_buffer_pointer_high8 + = ppdu_info->cfr_info.rtt_che_buffer_pointer_high8; + cfr_info->rtt_che_buffer_pointer_low32 + = ppdu_info->cfr_info.rtt_che_buffer_pointer_low32; +} + +/** + * dp_update_cfr_dbg_stats() - Increment RCC debug statistics + * @pdev: pdev structure + * @ppdu_info: structure for rx ppdu ring + * + * Return: none + */ +static inline void +dp_update_cfr_dbg_stats(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info; + + DP_STATS_INC(pdev, + rcc.chan_capture_status[cfr->chan_capture_status], 1); + if (cfr->rx_location_info_valid) { + DP_STATS_INC(pdev, rcc.rx_loc_info_valid_cnt, 1); + if (cfr->bb_captured_channel) { + DP_STATS_INC(pdev, rcc.bb_captured_channel_cnt, 1); + DP_STATS_INC(pdev, + rcc.reason_cnt[cfr->bb_captured_reason], + 1); + } else if (cfr->bb_captured_timeout) { + DP_STATS_INC(pdev, rcc.bb_captured_timeout_cnt, 1); + DP_STATS_INC(pdev, + rcc.reason_cnt[cfr->bb_captured_reason], + 1); + } + } +} + +/* + * dp_rx_handle_cfr() - Gather cfr info from hal ppdu info + * @soc: core txrx main context + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * + * Return: none + */ +static inline void +dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + qdf_nbuf_t ppdu_nbuf; + struct cdp_rx_indication_ppdu *cdp_rx_ppdu; + + dp_update_cfr_dbg_stats(pdev, ppdu_info); + if (!ppdu_info->cfr_info.bb_captured_channel) + return; + + ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, + sizeof(struct cdp_rx_indication_ppdu), + 0, + 0, + FALSE); + if (ppdu_nbuf) { + cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; + + dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu); + dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu); + qdf_nbuf_put_tail(ppdu_nbuf, + sizeof(struct cdp_rx_indication_ppdu)); + dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, + ppdu_nbuf, HTT_INVALID_PEER, + WDI_NO_VAL, pdev->pdev_id); + } +} + +/** + * dp_rx_populate_cfr_non_assoc_sta() - Populate cfr ppdu info for PPDUs from + * non-associated stations + * @pdev: pdev ctx + * @ppdu_info: ppdu info structure from ppdu ring + * @cdp_rx_ppdu: Rx PPDU indication structure + * + * Return: none + */ +static inline void +dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ + if (!dp_cfr_rcc_mode_status(pdev)) + return; + + if (ppdu_info->cfr_info.bb_captured_channel) + dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu); +} + +/** + * dp_bb_captured_chan_status() - Get the bb_captured_channel status + * @ppdu_info: structure for rx ppdu ring + * + * Return: Success/ Failure + */ + +static inline QDF_STATUS +dp_bb_captured_chan_status(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info; + + if (dp_cfr_rcc_mode_status(pdev)) { + if (cfr->bb_captured_channel) + status = QDF_STATUS_SUCCESS; + } + + return status; +} +#else +static inline void +dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ +} + +static inline void +dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ +} + +static inline void +dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ +} + +static inline void +dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline void +dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + struct cdp_rx_indication_ppdu *cdp_rx_ppdu) +{ +} + +static inline void +dp_update_cfr_dbg_stats(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline QDF_STATUS +dp_bb_captured_chan_status(struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline bool +dp_cfr_rcc_mode_status(struct dp_pdev *pdev) +{ + return false; +} +#endif + /** * dp_rx_handle_ppdu_stats() - Allocate and deliver ppdu stats to cdp layer * @soc: core txrx main context @@ -417,12 +1223,13 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info) { qdf_nbuf_t ppdu_nbuf; - struct dp_peer *peer; struct cdp_rx_indication_ppdu *cdp_rx_ppdu; /* * Do not allocate if fcs error, * ast idx invalid / fctl invalid + * + * In CFR RCC mode - PPDU status TLVs of error pkts are also needed */ if (ppdu_info->com_info.mpdu_cnt_fcs_ok == 0) return; @@ -448,41 +1255,46 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); } - /* need not generate wdi event when mcopy and + /* need not generate wdi event when mcopy, cfr rcc mode and * enhanced stats are not enabled */ - if (!pdev->mcopy_mode && !pdev->enhanced_stats_en) + if (!pdev->mcopy_mode && !pdev->enhanced_stats_en && + !dp_cfr_rcc_mode_status(pdev)) return; - if (!pdev->mcopy_mode) { - if (!ppdu_info->rx_status.frame_control_info_valid) - return; + if (dp_cfr_rcc_mode_status(pdev)) + dp_update_cfr_dbg_stats(pdev, ppdu_info); - if (ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID) + if (!ppdu_info->rx_status.frame_control_info_valid || + (ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)) { + if (!(pdev->mcopy_mode || + (dp_bb_captured_chan_status(pdev, ppdu_info) == + QDF_STATUS_SUCCESS))) return; } + ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, - sizeof(struct cdp_rx_indication_ppdu), 0, 0, FALSE); + sizeof(struct cdp_rx_indication_ppdu), + 0, 0, FALSE); if (ppdu_nbuf) { - dp_rx_populate_cdp_indication_ppdu(pdev, ppdu_info, ppdu_nbuf); - qdf_nbuf_put_tail(ppdu_nbuf, - sizeof(struct cdp_rx_indication_ppdu)); cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; - peer = dp_peer_find_by_id(soc, cdp_rx_ppdu->peer_id); - if (peer) { - cdp_rx_ppdu->cookie = (void *)peer->wlanstats_ctx; - dp_rx_stats_update(pdev, peer, cdp_rx_ppdu); - dp_peer_unref_del_find_by_id(peer); - } + + dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu); + dp_rx_populate_cdp_indication_ppdu(pdev, + ppdu_info, cdp_rx_ppdu); + qdf_nbuf_put_tail(ppdu_nbuf, + sizeof(struct cdp_rx_indication_ppdu)); + dp_rx_stats_update(pdev, cdp_rx_ppdu); + if (cdp_rx_ppdu->peer_id != HTT_INVALID_PEER) { dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, ppdu_nbuf, cdp_rx_ppdu->peer_id, WDI_NO_VAL, pdev->pdev_id); - } else if (pdev->mcopy_mode) { + } else if (pdev->mcopy_mode || dp_cfr_rcc_mode_status(pdev)) { dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, - ppdu_nbuf, HTT_INVALID_PEER, - WDI_NO_VAL, pdev->pdev_id); + ppdu_nbuf, HTT_INVALID_PEER, + WDI_NO_VAL, pdev->pdev_id); } else { qdf_nbuf_free(ppdu_nbuf); } @@ -516,7 +1328,7 @@ dp_rx_process_peer_based_pktlog(struct dp_soc *soc, uint32_t ast_index; ast_index = ppdu_info->rx_status.ast_index; - if (ast_index < (WLAN_UMAC_PSOC_MAX_PEERS * 2)) { + if (ast_index < wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { ast_entry = soc->ast_table[ast_index]; if (ast_entry) { peer = ast_entry->peer; @@ -533,6 +1345,102 @@ dp_rx_process_peer_based_pktlog(struct dp_soc *soc, } } +#if defined(HTT_UL_OFDMA_USER_INFO_V0_W0_VALID_M) +static inline void +dp_rx_ul_ofdma_ru_size_to_width( + uint32_t ru_size, + uint32_t *ru_width) +{ + uint32_t width; + + width = 0; + switch (ru_size) { + case HTT_UL_OFDMA_V0_RU_SIZE_RU_26: + width = 1; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_52: + width = 2; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_106: + width = 4; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_242: + width = 9; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_484: + width = 18; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_996: + width = 37; + break; + case HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2: + width = 74; + break; + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "RU size to width convert err"); + break; + } + *ru_width = width; +} + +static inline void +dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) +{ + struct mon_rx_user_status *mon_rx_user_status; + uint32_t num_users; + uint32_t i; + uint32_t mu_ul_user_v0_word0; + uint32_t mu_ul_user_v0_word1; + uint32_t ru_width; + uint32_t ru_size; + + if (!(ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_OFDMA || + ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_MIMO)) + return; + + num_users = ppdu_info->com_info.num_users; + if (num_users > HAL_MAX_UL_MU_USERS) + num_users = HAL_MAX_UL_MU_USERS; + for (i = 0; i < num_users; i++) { + mon_rx_user_status = &ppdu_info->rx_user_status[i]; + mu_ul_user_v0_word0 = + mon_rx_user_status->mu_ul_user_v0_word0; + mu_ul_user_v0_word1 = + mon_rx_user_status->mu_ul_user_v0_word1; + + if (HTT_UL_OFDMA_USER_INFO_V0_W0_VALID_GET( + mu_ul_user_v0_word0) && + !HTT_UL_OFDMA_USER_INFO_V0_W0_VER_GET( + mu_ul_user_v0_word0)) { + mon_rx_user_status->mcs = + HTT_UL_OFDMA_USER_INFO_V0_W1_MCS_GET( + mu_ul_user_v0_word1); + mon_rx_user_status->nss = + HTT_UL_OFDMA_USER_INFO_V0_W1_NSS_GET( + mu_ul_user_v0_word1) + 1; + + mon_rx_user_status->mu_ul_info_valid = 1; + mon_rx_user_status->ofdma_ru_start_index = + HTT_UL_OFDMA_USER_INFO_V0_W1_RU_START_GET( + mu_ul_user_v0_word1); + + ru_size = + HTT_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE_GET( + mu_ul_user_v0_word1); + dp_rx_ul_ofdma_ru_size_to_width(ru_size, &ru_width); + mon_rx_user_status->ofdma_ru_width = ru_width; + mon_rx_user_status->ofdma_ru_size = ru_size; + } + } +} +#else +static inline void +dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) +{ +} +#endif + /** * dp_rx_mon_status_process_tlv() - Process status TLV in status * buffer on Rx status Queue posted by status SRNG processing. @@ -545,13 +1453,12 @@ static inline void dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); struct hal_rx_ppdu_info *ppdu_info; qdf_nbuf_t status_nbuf; uint8_t *rx_tlv; uint8_t *rx_tlv_start; uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE; - QDF_STATUS m_copy_status = QDF_STATUS_SUCCESS; QDF_STATUS enh_log_status = QDF_STATUS_SUCCESS; struct cdp_pdev_mon_stats *rx_mon_stats; int smart_mesh_status; @@ -577,11 +1484,12 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, nbuf_used = false; if ((pdev->monitor_vdev) || (pdev->enhanced_stats_en) || - pdev->mcopy_mode || + (pdev->mcopy_mode) || (dp_cfr_rcc_mode_status(pdev)) || (rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) { do { tlv_status = hal_rx_status_get_tlv_info(rx_tlv, - ppdu_info, pdev->soc->hal_soc); + ppdu_info, pdev->soc->hal_soc, + status_nbuf); dp_rx_mon_update_dbg_ppdu_stats(ppdu_info, rx_mon_stats); @@ -592,7 +1500,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, rx_tlv = hal_rx_status_get_next_tlv(rx_tlv); - if ((rx_tlv - rx_tlv_start) >= RX_BUFFER_SIZE) + if ((rx_tlv - rx_tlv_start) >= + RX_DATA_BUFFER_SIZE) break; } while ((tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE) || @@ -623,11 +1532,10 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, pdev, ppdu_info, status_nbuf); if (smart_mesh_status) qdf_nbuf_free(status_nbuf); - } else if (pdev->mcopy_mode) { - m_copy_status = dp_rx_handle_mcopy_mode(soc, - pdev, ppdu_info, status_nbuf); - if (m_copy_status == QDF_STATUS_SUCCESS) - qdf_nbuf_free(status_nbuf); + } else if (qdf_unlikely(pdev->mcopy_mode)) { + dp_rx_process_mcopy_mode(soc, pdev, + ppdu_info, tlv_status, + status_nbuf); } else if (rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED) { if (!nbuf_used) qdf_nbuf_free(status_nbuf); @@ -644,11 +1552,36 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, dp_rx_mon_deliver_non_std(soc, mac_id); } else if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; + dp_rx_mon_handle_mu_ul_info(ppdu_info); + + if (pdev->tx_capture_enabled + != CDP_TX_ENH_CAPTURE_DISABLED) + dp_send_ack_frame_to_stack(soc, pdev, + ppdu_info); + if (pdev->enhanced_stats_en || pdev->mcopy_mode || pdev->neighbour_peers_added) dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); + else if (dp_cfr_rcc_mode_status(pdev)) + dp_rx_handle_cfr(soc, pdev, ppdu_info); pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; + + /* + * if chan_num is not fetched correctly from ppdu RX TLV, + * get it from pdev saved. + */ + if (qdf_unlikely(pdev->ppdu_info.rx_status.chan_num == 0)) + pdev->ppdu_info.rx_status.chan_num = pdev->mon_chan_num; + /* + * if chan_freq is not fetched correctly from ppdu RX TLV, + * get it from pdev saved. + */ + if (qdf_unlikely(pdev->ppdu_info.rx_status.chan_freq == 0)) { + pdev->ppdu_info.rx_status.chan_freq = + pdev->mon_chan_freq; + } + dp_rx_mon_dest_process(soc, mac_id, quota); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -673,15 +1606,14 @@ static inline uint32_t dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id); - void *hal_soc; + struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); + hal_soc_handle_t hal_soc; void *mon_status_srng; void *rxdma_mon_status_ring_entry; QDF_STATUS status; uint32_t work_done = 0; - int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); - mon_status_srng = pdev->rxdma_mon_status_ring[mac_for_pdev].hal_srng; + mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng; qdf_assert(mon_status_srng); if (!mon_status_srng || !hal_srng_initialized(mon_status_srng)) { @@ -748,7 +1680,7 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id, hal_srng_src_get_next(hal_soc, mon_status_srng); continue; } - qdf_nbuf_set_pktlen(status_nbuf, RX_BUFFER_SIZE); + qdf_nbuf_set_pktlen(status_nbuf, RX_DATA_BUFFER_SIZE); qdf_nbuf_unmap_single(soc->osdev, status_nbuf, QDF_DMA_FROM_DEVICE); @@ -848,6 +1780,8 @@ dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { return work_done; } + +#ifndef DISABLE_MON_CONFIG /** * dp_mon_process() - Main monitor mode processing roution. * This call monitor status ring process then monitor @@ -863,6 +1797,12 @@ uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { return dp_rx_mon_status_process(soc, mac_id, quota); } +#else +uint32_t +dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { + return 0; +} +#endif /** * dp_rx_pdev_mon_status_detach() - detach dp rx for status ring @@ -931,7 +1871,7 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, void *rxdma_ring_entry; union dp_rx_desc_list_elem_t *next; void *rxdma_srng; - struct dp_pdev *dp_pdev = dp_get_pdev_for_mac_id(dp_soc, mac_id); + struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(dp_soc, mac_id); rxdma_srng = dp_rxdma_srng->hal_srng; @@ -1066,9 +2006,8 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int ring_id) { uint32_t i; struct rx_desc_pool *rx_desc_pool; QDF_STATUS status; - int mac_for_pdev = dp_get_mac_id_for_mac(soc, ring_id); - mon_status_ring = &pdev->rxdma_mon_status_ring[mac_for_pdev]; + mon_status_ring = &soc->rxdma_mon_status_ring[ring_id]; num_entries = mon_status_ring->num_entries; @@ -1077,11 +2016,15 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int ring_id) { dp_info("Mon RX Status Pool[%d] entries=%d", ring_id, num_entries); + rx_desc_pool->desc_type = DP_RX_DESC_STATUS_TYPE; status = dp_rx_desc_pool_alloc(soc, ring_id, num_entries + 1, rx_desc_pool); if (!QDF_IS_STATUS_SUCCESS(status)) return status; + rx_desc_pool->buf_size = RX_DATA_BUFFER_SIZE; + rx_desc_pool->buf_alignment = RX_DATA_BUFFER_ALIGNMENT; + dp_debug("Mon RX Status Buffers Replenish ring_id=%d", ring_id); status = dp_rx_mon_status_buffers_replenish(soc, ring_id, @@ -1095,6 +2038,7 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int ring_id) { return status; qdf_nbuf_queue_init(&pdev->rx_status_q); + qdf_nbuf_queue_init(&pdev->rx_ppdu_buf_q); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c index 6162e734e77fdecd8488eb97240e8944f207f21e..094e1214f2587ca00633fb4218432e8c24df1445 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -56,7 +57,7 @@ #define DP_NSS_LENGTH (6 * SS_COUNT) #define DP_MU_GROUP_LENGTH (6 * DP_MU_GROUP_SHOW) #define DP_MU_GROUP_SHOW 16 -#define DP_MAX_MCS_STRING_LEN 30 +#define DP_MAX_MCS_STRING_LEN 34 #define DP_RXDMA_ERR_LENGTH (6 * HAL_RXDMA_ERR_MAX) #define DP_REO_ERR_LENGTH (6 * HAL_REO_ERR_MAX) #define STATS_PROC_TIMEOUT (HZ / 1000) @@ -153,7 +154,62 @@ static const struct dp_rate_debug dp_rate_string[DOT11_MAX][MAX_MCS] = { } }; -#ifdef CONFIG_WIN +static const struct dp_rate_debug dp_ppdu_rate_string[DOT11_MAX][MAX_MCS] = { + { + {"HE MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + } +}; + +static const struct dp_rate_debug dp_mu_rate_string[RX_TYPE_MU_MAX][MAX_MCS] = { + { + {"HE MU-MIMO MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE MU-MIMO MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE MU-MIMO MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE MU-MIMO MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE MU-MIMO MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + }, + { + {"HE OFDMA MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE OFDMA MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE OFDMA MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE OFDMA MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE OFDMA MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + }, +}; + +const char *mu_reception_mode[RX_TYPE_MU_MAX] = { + "MU MIMO", "MU OFDMA" +}; + +#ifdef QCA_ENH_V3_STATS_SUPPORT const char *fw_to_hw_delay_bucket[CDP_DELAY_BUCKET_MAX + 1] = { "0 to 10 ms", "11 to 20 ms", "21 to 30 ms", "31 to 40 ms", @@ -2894,7 +2950,8 @@ static void dp_print_tx_pdev_rate_stats_tlv(uint32_t *tag_buf) * * return:void */ -static inline void dp_print_rx_pdev_rate_stats_tlv(uint32_t *tag_buf) +static void dp_print_rx_pdev_rate_stats_tlv(struct dp_pdev *pdev, + uint32_t *tag_buf) { htt_rx_pdev_rate_stats_tlv *dp_stats_buf = (htt_rx_pdev_rate_stats_tlv *)tag_buf; @@ -2932,6 +2989,34 @@ static inline void dp_print_rx_pdev_rate_stats_tlv(uint32_t *tag_buf) } } + DP_PRINT_STATS("ul_ofdma_data_rx_ppdu = %d", + pdev->stats.ul_ofdma.data_rx_ppdu); + + for (i = 0; i < OFDMA_NUM_USERS; i++) { + DP_PRINT_STATS("ul_ofdma data %d user = %d", + i, pdev->stats.ul_ofdma.data_users[i]); + } + + index = 0; + qdf_mem_zero(str_buf, DP_MAX_STRING_LEN); + for (i = 0; i < OFDMA_NUM_RU_SIZE; i++) { + index += qdf_snprint(&str_buf[index], + DP_MAX_STRING_LEN - index, + " %u:%u,", i, + pdev->stats.ul_ofdma.data_rx_ru_size[i]); + } + DP_PRINT_STATS("ul_ofdma_data_rx_ru_size= %s", str_buf); + + index = 0; + qdf_mem_zero(str_buf, DP_MAX_STRING_LEN); + for (i = 0; i < OFDMA_NUM_RU_SIZE; i++) { + index += qdf_snprint(&str_buf[index], + DP_MAX_STRING_LEN - index, + " %u:%u,", i, + pdev->stats.ul_ofdma.nondata_rx_ru_size[i]); + } + DP_PRINT_STATS("ul_ofdma_nondata_rx_ru_size= %s", str_buf); + DP_PRINT_STATS("HTT_RX_PDEV_RATE_STATS_TLV:"); DP_PRINT_STATS("mac_id__word = %u", dp_stats_buf->mac_id__word); @@ -2947,7 +3032,7 @@ static inline void dp_print_rx_pdev_rate_stats_tlv(uint32_t *tag_buf) dp_stats_buf->rssi_data); DP_PRINT_STATS("rssi_comb = %u", dp_stats_buf->rssi_comb); - DP_PRINT_STATS("rx_in_dbm = %u", + DP_PRINT_STATS("rssi_in_dbm = %d", dp_stats_buf->rssi_in_dbm); DP_PRINT_STATS("rx_11ax_su_ext = %u", dp_stats_buf->rx_11ax_su_ext); @@ -2960,6 +3045,7 @@ static inline void dp_print_rx_pdev_rate_stats_tlv(uint32_t *tag_buf) DP_PRINT_STATS("txbf = %u", dp_stats_buf->txbf); + index = 0; qdf_mem_zero(str_buf, DP_MAX_STRING_LEN); for (i = 0; i < DP_HTT_RX_MCS_LEN; i++) { index += qdf_snprint(&str_buf[index], @@ -3592,12 +3678,14 @@ static inline void dp_print_rx_pdev_fw_stats_phy_err_tlv(uint32_t *tag_buf) /* * dp_htt_stats_print_tag: function to select the tag type and * print the corresponding tag structure + * @pdev: pdev pointer * @tag_type: tag type that is to be printed * @tag_buf: pointer to the tag structure * * return: void */ -void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf) +void dp_htt_stats_print_tag(struct dp_pdev *pdev, + uint8_t tag_type, uint32_t *tag_buf) { switch (tag_type) { case HTT_STATS_TX_PDEV_CMN_TAG: @@ -3739,7 +3827,7 @@ void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf) break; case HTT_STATS_RX_PDEV_RATE_STATS_TAG: - dp_print_rx_pdev_rate_stats_tlv(tag_buf); + dp_print_rx_pdev_rate_stats_tlv(pdev, tag_buf); break; case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG: @@ -3834,11 +3922,9 @@ void dp_htt_stats_print_tag(uint8_t tag_type, uint32_t *tag_buf) dp_print_tx_tid_stats_tlv(tag_buf); break; -#ifdef CONFIG_WIN case HTT_STATS_TX_TID_DETAILS_V1_TAG: dp_print_tx_tid_stats_v1_tlv(tag_buf); break; -#endif case HTT_STATS_RX_TID_DETAILS_TAG: dp_print_rx_tid_stats_tlv(tag_buf); @@ -3955,16 +4041,128 @@ void dp_htt_stats_copy_tag(struct dp_pdev *pdev, uint8_t tag_type, uint32_t *tag if (dest_ptr) qdf_mem_copy(dest_ptr, tag_buf, size); } -QDF_STATUS dp_peer_stats_notify(struct dp_peer *peer) + +#ifdef VDEV_PEER_PROTOCOL_COUNT +#ifdef VDEV_PEER_PROTOCOL_COUNT_TESTING +static QDF_STATUS dp_peer_stats_update_protocol_test_cnt(struct dp_vdev *vdev, + bool is_egress, + bool is_rx) +{ + int mask; + + if (is_egress) + if (is_rx) + mask = VDEV_PEER_PROTOCOL_RX_EGRESS_MASK; + else + mask = VDEV_PEER_PROTOCOL_TX_EGRESS_MASK; + else + if (is_rx) + mask = VDEV_PEER_PROTOCOL_RX_INGRESS_MASK; + else + mask = VDEV_PEER_PROTOCOL_TX_INGRESS_MASK; + + if (qdf_unlikely(vdev->peer_protocol_count_dropmask & mask)) { + dp_info("drop mask set %x", vdev->peer_protocol_count_dropmask); + return QDF_STATUS_SUCCESS; + } + return QDF_STATUS_E_FAILURE; +} + +#else +static QDF_STATUS dp_peer_stats_update_protocol_test_cnt(struct dp_vdev *vdev, + bool is_egress, + bool is_rx) +{ + return QDF_STATUS_E_FAILURE; +} +#endif + +void dp_vdev_peer_stats_update_protocol_cnt(struct dp_vdev *vdev, + qdf_nbuf_t nbuf, + struct dp_peer *peer, + bool is_egress, + bool is_rx) +{ + struct cdp_peer_stats *peer_stats; + struct protocol_trace_count *protocol_trace_cnt; + enum cdp_protocol_trace prot; + struct dp_soc *soc; + struct ether_header *eh; + char *mac; + bool new_peer_ref = false; + + if (qdf_likely(!vdev->peer_protocol_count_track)) + return; + if (qdf_unlikely(dp_peer_stats_update_protocol_test_cnt(vdev, + is_egress, + is_rx) == + QDF_STATUS_SUCCESS)) + return; + + soc = vdev->pdev->soc; + eh = (struct ether_header *)qdf_nbuf_data(nbuf); + if (is_rx) + mac = eh->ether_shost; + else + mac = eh->ether_dhost; + + if (!peer) { + peer = dp_peer_find_hash_find(soc, mac, 0, vdev->vdev_id); + new_peer_ref = true; + if (!peer) + return; + } + peer_stats = &peer->stats; + + if (qdf_nbuf_is_icmp_pkt(nbuf) == true) + prot = CDP_TRACE_ICMP; + else if (qdf_nbuf_is_ipv4_arp_pkt(nbuf) == true) + prot = CDP_TRACE_ARP; + else if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf) == true) + prot = CDP_TRACE_EAP; + else + goto dp_vdev_peer_stats_update_protocol_cnt_free_peer; + + if (is_rx) + protocol_trace_cnt = peer_stats->rx.protocol_trace_cnt; + else + protocol_trace_cnt = peer_stats->tx.protocol_trace_cnt; + + if (is_egress) + protocol_trace_cnt[prot].egress_cnt++; + else + protocol_trace_cnt[prot].ingress_cnt++; +dp_vdev_peer_stats_update_protocol_cnt_free_peer: + if (new_peer_ref) + dp_peer_unref_delete(peer); +} + +void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc, + int8_t vdev_id, + qdf_nbuf_t nbuf, + bool is_egress, + bool is_rx) +{ + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + if (qdf_likely(!vdev->peer_protocol_count_track)) + return; + dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, NULL, is_egress, + is_rx); +} +#endif + +#ifdef WDI_EVENT_ENABLE +QDF_STATUS dp_peer_stats_notify(struct dp_pdev *dp_pdev, struct dp_peer *peer) { - struct dp_pdev *dp_pdev; struct cdp_interface_peer_stats peer_stats_intf; struct cdp_peer_stats *peer_stats = &peer->stats; if (!peer->vdev) return QDF_STATUS_E_FAULT; - dp_pdev = peer->vdev->pdev; qdf_mem_zero(&peer_stats_intf, sizeof(peer_stats_intf)); if (peer_stats->rx.last_rssi != peer_stats->rx.rssi) peer_stats_intf.rssi_changed = true; @@ -3972,7 +4170,9 @@ QDF_STATUS dp_peer_stats_notify(struct dp_peer *peer) if ((peer_stats->rx.rssi && peer_stats_intf.rssi_changed) || (peer_stats->tx.tx_rate && peer_stats->tx.tx_rate != peer_stats->tx.last_tx_rate)) { - peer_stats_intf.peer_hdl = peer->ctrl_peer; + qdf_mem_copy(peer_stats_intf.peer_mac, peer->mac_addr.raw, + QDF_MAC_ADDR_SIZE); + peer_stats_intf.vdev_id = peer->vdev->vdev_id; peer_stats_intf.last_peer_tx_rate = peer_stats->tx.last_tx_rate; peer_stats_intf.peer_tx_rate = peer_stats->tx.tx_rate; peer_stats_intf.peer_rssi = peer_stats->rx.rssi; @@ -3989,8 +4189,9 @@ QDF_STATUS dp_peer_stats_notify(struct dp_peer *peer) return QDF_STATUS_SUCCESS; } +#endif -#ifdef CONFIG_WIN +#ifdef QCA_ENH_V3_STATS_SUPPORT /** * dp_vow_str_fw_to_hw_delay() - Return string for a delay * @index: Index of delay @@ -4068,7 +4269,7 @@ dp_accumulate_tid_stats(struct dp_pdev *pdev, uint8_t tid, struct cdp_tid_tx_stats *total_tx, struct cdp_tid_rx_stats *total_rx, uint8_t type) { - uint8_t ring_id = 0, drop = 0; + uint8_t ring_id = 0, drop = 0, tqm_status_idx = 0, htt_status_idx = 0; struct cdp_tid_stats *tid_stats = &pdev->stats.tid_stats; struct cdp_tid_tx_stats *per_ring_tx = NULL; struct cdp_tid_rx_stats *per_ring_rx = NULL; @@ -4090,7 +4291,16 @@ dp_accumulate_tid_stats(struct dp_pdev *pdev, uint8_t tid, for (ring_id = 0; ring_id < CDP_MAX_TX_COMP_RINGS; ring_id++) { per_ring_tx = &tid_stats->tid_tx_stats[ring_id][tid]; total_tx->success_cnt += per_ring_tx->success_cnt; - total_tx->comp_fail_cnt += per_ring_tx->comp_fail_cnt; + for (tqm_status_idx = 0; tqm_status_idx < CDP_MAX_TX_TQM_STATUS; tqm_status_idx++) { + total_tx->tqm_status_cnt[tqm_status_idx] += + per_ring_tx->tqm_status_cnt[tqm_status_idx]; + } + + for (htt_status_idx = 0; htt_status_idx < CDP_MAX_TX_HTT_STATUS; htt_status_idx++) { + total_tx->htt_status_cnt[htt_status_idx] += + per_ring_tx->htt_status_cnt[htt_status_idx]; + } + for (drop = 0; drop < TX_MAX_DROP; drop++) total_tx->swdrop_cnt[drop] += per_ring_tx->swdrop_cnt[drop]; @@ -4141,7 +4351,7 @@ void dp_pdev_print_tid_stats(struct dp_pdev *pdev) { struct cdp_tid_tx_stats total_tx; struct cdp_tid_rx_stats total_rx; - uint8_t tid; + uint8_t tid, tqm_status_idx, htt_status_idx; DP_PRINT_STATS("Packets received in hardstart: %llu ", pdev->stats.tid_stats.ingress_stack); @@ -4153,9 +4363,24 @@ void dp_pdev_print_tid_stats(struct dp_pdev *pdev) dp_accumulate_tid_stats(pdev, tid, &total_tx, &total_rx, TID_COUNTER_STATS); DP_PRINT_STATS("----TID: %d----", tid); - DP_PRINT_STATS("Tx Success Count: %llu", total_tx.success_cnt); - DP_PRINT_STATS("Tx Firmware Drop Count: %llu", - total_tx.comp_fail_cnt); + DP_PRINT_STATS("Tx TQM Success Count: %llu", + total_tx.tqm_status_cnt[HAL_TX_TQM_RR_FRAME_ACKED]); + DP_PRINT_STATS("Tx HTT Success Count: %llu", + total_tx.htt_status_cnt[HTT_TX_FW2WBM_TX_STATUS_OK]); + for (tqm_status_idx = 1; tqm_status_idx < CDP_MAX_TX_TQM_STATUS; tqm_status_idx++) { + if (total_tx.tqm_status_cnt[tqm_status_idx]) { + DP_PRINT_STATS("Tx TQM Drop Count[%d]: %llu", + tqm_status_idx, total_tx.tqm_status_cnt[tqm_status_idx]); + } + } + + for (htt_status_idx = 1; htt_status_idx < CDP_MAX_TX_HTT_STATUS; htt_status_idx++) { + if (total_tx.htt_status_cnt[htt_status_idx]) { + DP_PRINT_STATS("Tx HTT Drop Count[%d]: %llu", + htt_status_idx, total_tx.htt_status_cnt[htt_status_idx]); + } + } + DP_PRINT_STATS("Tx Hardware Drop Count: %llu", total_tx.swdrop_cnt[TX_HW_ENQUEUE]); DP_PRINT_STATS("Tx Software Drop Count: %llu", @@ -4453,12 +4678,20 @@ void dp_print_soc_cfg_params(struct dp_soc *soc) soc_cfg_ctx->sg_enabled); DP_PRINT_STATS("Gro enabled: %u ", soc_cfg_ctx->gro_enabled); + DP_PRINT_STATS("TC based dynamic GRO: %u ", + soc_cfg_ctx->tc_based_dynamic_gro); + DP_PRINT_STATS("TC ingress prio: %u ", + soc_cfg_ctx->tc_ingress_prio); DP_PRINT_STATS("rawmode enabled: %u ", soc_cfg_ctx->rawmode_enabled); DP_PRINT_STATS("peer flow ctrl enabled: %u ", soc_cfg_ctx->peer_flow_ctrl_enabled); DP_PRINT_STATS("napi enabled: %u ", soc_cfg_ctx->napi_enabled); + DP_PRINT_STATS("P2P Tcp Udp checksum offload: %u ", + soc_cfg_ctx->p2p_tcp_udp_checksumoffload); + DP_PRINT_STATS("NAN Tcp Udp checksum offload: %u ", + soc_cfg_ctx->nan_tcp_udp_checksumoffload); DP_PRINT_STATS("Tcp Udp checksum offload: %u ", soc_cfg_ctx->tcp_udp_checksumoffload); DP_PRINT_STATS("Defrag timeout check: %u ", @@ -4483,8 +4716,24 @@ void dp_print_soc_cfg_params(struct dp_soc *soc) soc_cfg_ctx->reo_status_ring); DP_PRINT_STATS("RXDMA refill ring: %u ", soc_cfg_ctx->rxdma_refill_ring); + DP_PRINT_STATS("TX_desc limit_0: %u ", + soc_cfg_ctx->tx_desc_limit_0); + DP_PRINT_STATS("TX_desc limit_1: %u ", + soc_cfg_ctx->tx_desc_limit_1); + DP_PRINT_STATS("TX_desc limit_2: %u ", + soc_cfg_ctx->tx_desc_limit_2); + DP_PRINT_STATS("TX device limit: %u ", + soc_cfg_ctx->tx_device_limit); + DP_PRINT_STATS("TX sw internode queue: %u ", + soc_cfg_ctx->tx_sw_internode_queue); DP_PRINT_STATS("RXDMA err dst ring: %u ", soc_cfg_ctx->rxdma_err_dst_ring); + DP_PRINT_STATS("RX Flow Tag Enabled: %u ", + soc_cfg_ctx->is_rx_flow_tag_enabled); + DP_PRINT_STATS("RX Flow Search Table Size (# of entries): %u ", + soc_cfg_ctx->rx_flow_search_table_size); + DP_PRINT_STATS("RX Flow Search Table Per PDev : %u ", + soc_cfg_ctx->is_rx_flow_search_table_per_pdev); } void @@ -4555,6 +4804,62 @@ dp_print_ring_stat_from_hal(struct dp_soc *soc, struct dp_srng *srng, } } +#ifdef FEATURE_TSO_STATS +/** + * dp_print_tso_seg_stats - tso segment stats + * @pdev: pdev handle + * @id: tso packet id + * + * Return: None + */ +static void dp_print_tso_seg_stats(struct dp_pdev *pdev, uint32_t id) +{ + uint8_t num_seg; + uint32_t segid; + + /* TSO LEVEL 2 - SEGMENT INFO */ + num_seg = pdev->stats.tso_stats.tso_info.tso_packet_info[id].num_seg; + for (segid = 0; segid < CDP_MAX_TSO_SEGMENTS && segid < num_seg; segid++) { + DP_PRINT_STATS( + "Segment id:[%u] fragments: %u | Segment Length %u | TCP Seq no.: %u | ip_id: %u", + segid, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].num_frags, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].total_len, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.tcp_seq_num, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.ip_id); + DP_PRINT_STATS( + "fin: %u syn: %u rst: %u psh: %u ack: %u urg: %u ece: %u cwr: %u ns: %u", + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.fin, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.syn, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.rst, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.psh, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.ack, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.urg, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.ece, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.cwr, + pdev->stats.tso_stats.tso_info.tso_packet_info[id] + .tso_seg[segid].tso_flags.ns); + } +} +#else +static inline +void dp_print_tso_seg_stats(struct dp_pdev *pdev, uint32_t id) +{ +} +#endif /* FEATURE_TSO_STATS */ + /** * dp_print_mon_ring_stats_from_hal() - Print stat for monitor rings based * on target @@ -4568,19 +4873,19 @@ void dp_print_mon_ring_stat_from_hal(struct dp_pdev *pdev, uint8_t mac_id) { if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) { dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rxdma_mon_buf_ring[mac_id], - RXDMA_MONITOR_BUF); + &pdev->soc->rxdma_mon_buf_ring[mac_id], + RXDMA_MONITOR_BUF); dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rxdma_mon_dst_ring[mac_id], - RXDMA_MONITOR_DST); + &pdev->soc->rxdma_mon_dst_ring[mac_id], + RXDMA_MONITOR_DST); dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rxdma_mon_desc_ring[mac_id], - RXDMA_MONITOR_DESC); + &pdev->soc->rxdma_mon_desc_ring[mac_id], + RXDMA_MONITOR_DESC); } dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rxdma_mon_status_ring[mac_id], - RXDMA_MONITOR_STATUS); + &pdev->soc->rxdma_mon_status_ring[mac_id], + RXDMA_MONITOR_STATUS); } void @@ -4588,6 +4893,7 @@ dp_print_ring_stats(struct dp_pdev *pdev) { uint32_t i; int mac_id; + int lmac_id; if (hif_pm_runtime_get_sync(pdev->soc->hif_handle, RTPM_ID_DP_PRINT_RING_STATS)) @@ -4631,9 +4937,10 @@ dp_print_ring_stats(struct dp_pdev *pdev) &pdev->soc->tx_comp_ring[i], WBM2SW_RELEASE); + lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc, 0, pdev->pdev_id); dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rx_refill_buf_ring, - RXDMA_BUF); + &pdev->soc->rx_refill_buf_ring[lmac_id], + RXDMA_BUF); dp_print_ring_stat_from_hal(pdev->soc, &pdev->rx_refill_buf_ring2, @@ -4644,14 +4951,22 @@ dp_print_ring_stats(struct dp_pdev *pdev) &pdev->rx_mac_buf_ring[i], RXDMA_BUF); - for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) - dp_print_mon_ring_stat_from_hal(pdev, mac_id); + for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { + lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc, + mac_id, pdev->pdev_id); + + dp_print_mon_ring_stat_from_hal(pdev, lmac_id); + } + + for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) { + lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc, + i, pdev->pdev_id); - for (i = 0; i < NUM_RXDMA_RINGS_PER_PDEV; i++) dp_print_ring_stat_from_hal(pdev->soc, - &pdev->rxdma_err_dst_ring[i], + &pdev->soc->rxdma_err_dst_ring + [lmac_id], RXDMA_DST); - + } hif_pm_runtime_put(pdev->soc->hif_handle, RTPM_ID_DP_PRINT_RING_STATS); } @@ -4667,6 +4982,7 @@ dp_print_common_rates_info(struct cdp_pkt_type *pkt_type_array) { uint8_t mcs, pkt_type; + DP_PRINT_STATS("MSDU Count"); for (pkt_type = 0; pkt_type < DOT11_MAX; pkt_type++) { for (mcs = 0; mcs < MAX_MCS; mcs++) { if (!dp_rate_string[pkt_type][mcs].valid) @@ -4681,6 +4997,56 @@ dp_print_common_rates_info(struct cdp_pkt_type *pkt_type_array) } } +/** + * dp_print_common_ppdu_rates_info(): Print common rate for tx or rx + * @pkt_type_array: rate type array contains rate info + * + * Return:void + */ +static inline void +dp_print_common_ppdu_rates_info(struct cdp_pkt_type *pkt_type_array) +{ + uint8_t mcs; + + DP_PRINT_STATS("PPDU Count"); + for (mcs = 0; mcs < MAX_MCS; mcs++) { + if (!dp_ppdu_rate_string[0][mcs].valid) + continue; + + DP_PRINT_STATS(" %s = %d", + dp_ppdu_rate_string[0][mcs].mcs_type, + pkt_type_array->mcs_count[mcs]); + } + + DP_PRINT_STATS("\n"); +} + +/** + * dp_print_mu_ppdu_rates_info(): Print mu rate for tx or rx + * @rx_mu: rx MU stats array + * + * Return:void + */ +static inline void +dp_print_mu_ppdu_rates_info(struct cdp_rx_mu *rx_mu) +{ + uint8_t mcs, pkt_type; + + DP_PRINT_STATS("PPDU Count"); + for (pkt_type = 0; pkt_type < RX_TYPE_MU_MAX; pkt_type++) { + for (mcs = 0; mcs < MAX_MCS; mcs++) { + if (!dp_mu_rate_string[pkt_type][mcs].valid) + continue; + + DP_PRINT_STATS(" %s = %d", + dp_mu_rate_string[pkt_type][mcs].mcs_type, + rx_mu[pkt_type].ppdu.mcs_count[mcs]); + } + + DP_PRINT_STATS("\n"); + } +} + void dp_print_rx_rates(struct dp_vdev *vdev) { struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; @@ -4758,6 +5124,26 @@ void dp_print_tx_rates(struct dp_vdev *vdev) pdev->stats.tx.non_amsdu_cnt); } +/** + * dp_print_nss(): Print nss count + * @nss: printable nss count array + * @pnss: nss count array + * @ss_count: number of nss + * + * Return:void + */ +static void dp_print_nss(char *nss, uint32_t *pnss, uint32_t ss_count) +{ + uint32_t index; + uint8_t i; + + index = 0; + for (i = 0; i < ss_count; i++) { + index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, + " %d", *(pnss + i)); + } +} + void dp_print_peer_stats(struct dp_peer *peer) { uint8_t i; @@ -4765,6 +5151,12 @@ void dp_print_peer_stats(struct dp_peer *peer) uint32_t j; char nss[DP_NSS_LENGTH]; char mu_group_id[DP_MU_GROUP_LENGTH]; + struct dp_pdev *pdev; + uint32_t *pnss; + enum cdp_mu_packet_type rx_mu_type; + struct cdp_rx_mu *rx_mu; + + pdev = peer->vdev->pdev; DP_PRINT_STATS("Node Tx Stats:\n"); DP_PRINT_STATS("Total Packet Completions = %d", @@ -4807,8 +5199,10 @@ void dp_print_peer_stats(struct dp_peer *peer) peer->stats.tx.last_ack_rssi); DP_PRINT_STATS("Dropped At FW: Removed Pkts = %u", peer->stats.tx.dropped.fw_rem.num); - DP_PRINT_STATS("Dropped At FW: Removed bytes = %llu", - peer->stats.tx.dropped.fw_rem.bytes); + if (pdev && !wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) { + DP_PRINT_STATS("Dropped At FW: Removed bytes = %llu", + peer->stats.tx.dropped.fw_rem.bytes); + } DP_PRINT_STATS("Dropped At FW: Removed transmitted = %d", peer->stats.tx.dropped.fw_rem_tx); DP_PRINT_STATS("Dropped At FW: Removed Untransmitted = %d", @@ -4844,19 +5238,17 @@ void dp_print_peer_stats(struct dp_peer *peer) peer->stats.tx.bw[0], peer->stats.tx.bw[1], peer->stats.tx.bw[2], peer->stats.tx.bw[3]); - index = 0; - for (i = 0; i < SS_COUNT; i++) { - index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, - " %d", peer->stats.tx.nss[i]); - } + pnss = &peer->stats.tx.nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS("NSS(1-8) = %s", nss); DP_PRINT_STATS("Transmit Type :"); DP_PRINT_STATS("SU %d, MU_MIMO %d, MU_OFDMA %d, MU_MIMO_OFDMA %d", - peer->stats.tx.transmit_type[0], - peer->stats.tx.transmit_type[1], - peer->stats.tx.transmit_type[2], - peer->stats.tx.transmit_type[3]); + peer->stats.tx.transmit_type[SU].num_msdu, + peer->stats.tx.transmit_type[MU_MIMO].num_msdu, + peer->stats.tx.transmit_type[MU_OFDMA].num_msdu, + peer->stats.tx.transmit_type[MU_MIMO_OFDMA].num_msdu); for (i = 0; i < MAX_MU_GROUP_ID;) { index = 0; @@ -4876,12 +5268,18 @@ void dp_print_peer_stats(struct dp_peer *peer) DP_PRINT_STATS("Last Packet RU index [%d], Size [%d]", peer->stats.tx.ru_start, peer->stats.tx.ru_tones); DP_PRINT_STATS("RU Locations RU[26 52 106 242 484 996]:"); - DP_PRINT_STATS("RU_26: %d", peer->stats.tx.ru_loc[0]); - DP_PRINT_STATS("RU 52: %d", peer->stats.tx.ru_loc[1]); - DP_PRINT_STATS("RU 106: %d", peer->stats.tx.ru_loc[2]); - DP_PRINT_STATS("RU 242: %d", peer->stats.tx.ru_loc[3]); - DP_PRINT_STATS("RU 484: %d", peer->stats.tx.ru_loc[4]); - DP_PRINT_STATS("RU 996: %d", peer->stats.tx.ru_loc[5]); + DP_PRINT_STATS("RU_26: %d", + peer->stats.tx.ru_loc[RU_26_INDEX].num_msdu); + DP_PRINT_STATS("RU 52: %d", + peer->stats.tx.ru_loc[RU_52_INDEX].num_msdu); + DP_PRINT_STATS("RU 106: %d", + peer->stats.tx.ru_loc[RU_106_INDEX].num_msdu); + DP_PRINT_STATS("RU 242: %d", + peer->stats.tx.ru_loc[RU_242_INDEX].num_msdu); + DP_PRINT_STATS("RU 484: %d", + peer->stats.tx.ru_loc[RU_484_INDEX].num_msdu); + DP_PRINT_STATS("RU 996: %d", + peer->stats.tx.ru_loc[RU_996_INDEX].num_msdu); DP_PRINT_STATS("Aggregation:"); DP_PRINT_STATS("Number of Msdu's Part of Amsdu = %d", @@ -4946,21 +5344,53 @@ void dp_print_peer_stats(struct dp_peer *peer) DP_PRINT_STATS("BW Counts = 20MHZ %d 40MHZ %d 80MHZ %d 160MHZ %d", peer->stats.rx.bw[0], peer->stats.rx.bw[1], peer->stats.rx.bw[2], peer->stats.rx.bw[3]); - DP_PRINT_STATS("Reception Type = SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", + DP_PRINT_STATS("MSDU Reception Type"); + DP_PRINT_STATS("SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", peer->stats.rx.reception_type[0], peer->stats.rx.reception_type[1], peer->stats.rx.reception_type[2], peer->stats.rx.reception_type[3]); + DP_PRINT_STATS("PPDU Reception Type"); + DP_PRINT_STATS("SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", + peer->stats.rx.ppdu_cnt[0], + peer->stats.rx.ppdu_cnt[1], + peer->stats.rx.ppdu_cnt[2], + peer->stats.rx.ppdu_cnt[3]); dp_print_common_rates_info(peer->stats.rx.pkt_type); + dp_print_common_ppdu_rates_info(&peer->stats.rx.su_ax_ppdu_cnt); + dp_print_mu_ppdu_rates_info(&peer->stats.rx.rx_mu[0]); - index = 0; - for (i = 0; i < SS_COUNT; i++) { - index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, - " %d", peer->stats.rx.nss[i]); + pnss = &peer->stats.rx.nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS("MSDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS("reception mode SU"); + pnss = &peer->stats.rx.ppdu_nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + + DP_PRINT_STATS(" PPDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS(" MPDU OK = %d, MPDU Fail = %d", + peer->stats.rx.mpdu_cnt_fcs_ok, + peer->stats.rx.mpdu_cnt_fcs_err); + + for (rx_mu_type = 0; rx_mu_type < RX_TYPE_MU_MAX; rx_mu_type++) { + DP_PRINT_STATS("reception mode %s", + mu_reception_mode[rx_mu_type]); + rx_mu = &peer->stats.rx.rx_mu[rx_mu_type]; + + pnss = &rx_mu->ppdu_nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS(" PPDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS(" MPDU OK = %d, MPDU Fail = %d", + rx_mu->mpdu_cnt_fcs_ok, + rx_mu->mpdu_cnt_fcs_err); } - DP_PRINT_STATS("NSS(1-8) = %s", - nss); DP_PRINT_STATS("Aggregation:"); DP_PRINT_STATS(" Msdu's Part of Ampdu = %d", @@ -4977,6 +5407,8 @@ void dp_print_peer_stats(struct dp_peer *peer) peer->stats.rx.rx_byte_rate); DP_PRINT_STATS(" Data received in last sec: %d", peer->stats.rx.rx_data_rate); + DP_PRINT_STATS("Multipass Rx Packet Drop = %d", + peer->stats.rx.multipass_rx_pkt_drop); } void dp_print_per_ring_stats(struct dp_soc *soc) @@ -5094,6 +5526,8 @@ void dp_txrx_path_stats(struct dp_soc *soc) pdev->stats.rx.intra_bss.fail.bytes); DP_PRINT_STATS("intra-bss no mdns fwds %u msdus", pdev->stats.rx.intra_bss.mdns_no_fwd); + DP_PRINT_STATS("intra-bss EAPOL drops: %u", + soc->stats.rx.err.intrabss_eapol_drop); DP_PRINT_STATS("raw packets %u msdus ( %llu bytes),", pdev->stats.rx.raw.num, @@ -5112,6 +5546,10 @@ void dp_txrx_path_stats(struct dp_soc *soc) pdev->soc->stats.rx.err.defrag_peer_uninit); DP_PRINT_STATS("pkts delivered no peer %u", pdev->soc->stats.rx.err.pkt_delivered_no_peer); + DP_PRINT_STATS("RX invalid cookie: %d", + soc->stats.rx.err.invalid_cookie); + DP_PRINT_STATS("RX stale cookie: %d", + soc->stats.rx.err.stale_cookie); DP_PRINT_STATS("2k jump delba sent: %u", pdev->soc->stats.rx.err.rx_2k_jump_delba_sent); DP_PRINT_STATS("2k jump msdu to stack: %u", @@ -5124,6 +5562,14 @@ void dp_txrx_path_stats(struct dp_soc *soc) pdev->soc->stats.rx.err.reo_err_oor_drop); DP_PRINT_STATS("Rx err msdu rejected: %d", soc->stats.rx.err.rejected); + DP_PRINT_STATS("Rx raw frame dropped: %d", + soc->stats.rx.err.raw_frm_drop); + DP_PRINT_STATS("Rx stale link desc cookie: %d", + pdev->soc->stats.rx.err.invalid_link_cookie); + DP_PRINT_STATS("Rx nbuf sanity fails: %d", + pdev->soc->stats.rx.err.nbuf_sanity_fail); + DP_PRINT_STATS("Rx refill duplicate link desc: %d", + pdev->soc->stats.rx.err.dup_refill_link_desc); DP_PRINT_STATS("Reo Statistics"); DP_PRINT_STATS("near_full: %u ", soc->stats.rx.near_full); @@ -5135,6 +5581,8 @@ void dp_txrx_path_stats(struct dp_soc *soc) DP_PRINT_STATS("hal ring access full fail: %u msdus", pdev->soc->stats.rx.err.hal_ring_access_full_fail); + DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame); + for (error_code = 0; error_code < HAL_REO_ERR_MAX; error_code++) { if (!pdev->soc->stats.rx.err.reo_error[error_code]) @@ -5306,17 +5754,6 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev) pdev->stats.tx_i.sg.dropped_host.num); DP_PRINT_STATS(" Dropped By Target = %d", pdev->stats.tx_i.sg.dropped_target); - DP_PRINT_STATS("TSO:"); - DP_PRINT_STATS(" Number of Segments = %d", - pdev->stats.tx_i.tso.num_seg); - DP_PRINT_STATS(" Packets = %d", - pdev->stats.tx_i.tso.tso_pkt.num); - DP_PRINT_STATS(" Bytes = %llu", - pdev->stats.tx_i.tso.tso_pkt.bytes); - DP_PRINT_STATS(" Dropped By Host = %d", - pdev->stats.tx_i.tso.dropped_host.num); - DP_PRINT_STATS(" Dropped By Host(no free TSO desc) = %d", - pdev->stats.tx_i.tso.tso_no_mem_dropped.num); DP_PRINT_STATS("Mcast Enhancement:"); DP_PRINT_STATS(" Packets = %d", pdev->stats.tx_i.mcast_en.mcast_pkt.num); @@ -5369,6 +5806,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev) DP_PRINT_STATS(" Tag[%d] = %llu", index, pdev->stats.ppdu_stats_counter[index]); } + DP_PRINT_STATS("BA not received for delayed_ba: %d", + pdev->stats.cdp_delayed_ba_not_recev); DP_PRINT_STATS("tx_ppdu_proc: %llu\n", pdev->tx_ppdu_proc); @@ -5377,6 +5816,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev) DP_PRINT_STATS("Wdi msgs received from fw[%d]:%d", i, pdev->stats.wdi_event[i]); } + + dp_print_pdev_tx_capture_stats(pdev); } void @@ -5397,8 +5838,6 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev) DP_PRINT_STATS("Replenished:"); DP_PRINT_STATS(" Packets = %d", pdev->stats.replenish.pkts.num); - DP_PRINT_STATS(" Bytes = %llu", - pdev->stats.replenish.pkts.bytes); DP_PRINT_STATS(" Buffers Added To Freelist = %d", pdev->stats.buf_freelist); DP_PRINT_STATS(" Low threshold intr = %d", @@ -5410,6 +5849,8 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev) pdev->stats.dropped.wifi_parse); DP_PRINT_STATS(" mon_rx_drop = %d", pdev->stats.dropped.mon_rx_drop); + DP_PRINT_STATS(" mon_radiotap_update_err = %d", + pdev->stats.dropped.mon_radiotap_update_err); DP_PRINT_STATS(" mec_drop = %d", pdev->stats.rx.mec_drop.num); DP_PRINT_STATS(" Bytes = %llu", @@ -5538,8 +5979,12 @@ dp_print_soc_tx_stats(struct dp_soc *soc) soc->stats.tx.tcl_ring_full[2]); DP_PRINT_STATS("Tx invalid completion release = %d", soc->stats.tx.invalid_release_source); - DP_PRINT_STATS("Tx comp wbm internal error = %d", - soc->stats.tx.wbm_internal_error); + DP_PRINT_STATS("Tx comp wbm internal error = %d : [%d %d %d %d]", + soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_ALL], + soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_BUFFER], + soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_LINK_DESC], + soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_MSDU_BUFF], + soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_REO_BUFF_REAPED]); DP_PRINT_STATS("Tx comp non wbm internal error = %d", soc->stats.tx.non_wbm_internal_err); DP_PRINT_STATS("Tx comp loop pkt limit hit = %d", @@ -5602,6 +6047,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc) soc->stats.rx.err.defrag_peer_uninit); DP_PRINT_STATS("Pkts delivered no peer = %d", soc->stats.rx.err.pkt_delivered_no_peer); + DP_PRINT_STATS("Pkts drop due to no peer auth :%d", + soc->stats.rx.err.peer_unauth_rx_pkt_drop); DP_PRINT_STATS("Invalid Pdev = %d", soc->stats.rx.err.invalid_pdev); DP_PRINT_STATS("Invalid Peer = %d", @@ -5615,6 +6062,7 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("RX frags: %d", soc->stats.rx.rx_frags); DP_PRINT_STATS("RX frag wait: %d", soc->stats.rx.rx_frag_wait); DP_PRINT_STATS("RX frag err: %d", soc->stats.rx.rx_frag_err); + DP_PRINT_STATS("RX frag OOR: %d", soc->stats.rx.rx_frag_oor); DP_PRINT_STATS("RX HP out_of_sync: %d", soc->stats.rx.hp_oos2); DP_PRINT_STATS("RX Ring Near Full: %d", soc->stats.rx.near_full); @@ -5634,6 +6082,12 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("RX scatter msdu: %d", soc->stats.rx.err.scatter_msdu); + DP_PRINT_STATS("RX invalid cookie: %d", + soc->stats.rx.err.invalid_cookie); + + DP_PRINT_STATS("RX stale cookie: %d", + soc->stats.rx.err.stale_cookie); + DP_PRINT_STATS("RX wait completed msdu break: %d", soc->stats.rx.msdu_scatter_wait_break); @@ -5655,6 +6109,12 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("Rx err msdu rejected: %d", soc->stats.rx.err.rejected); + DP_PRINT_STATS("Rx stale link desc cookie: %d", + soc->stats.rx.err.invalid_link_cookie); + + DP_PRINT_STATS("Rx nbuf sanity fail: %d", + soc->stats.rx.err.nbuf_sanity_fail); + for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) { index += qdf_snprint(&rxdma_error[index], DP_RXDMA_ERR_LENGTH - index, @@ -5671,5 +6131,167 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("REO Error(0-14):%s", reo_error); DP_PRINT_STATS("REO CMD SEND FAIL: %d", soc->stats.rx.err.reo_cmd_send_fail); + + DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame); + DP_PRINT_STATS("Rx invalid TID count:%d", + soc->stats.rx.err.rx_invalid_tid_err); +} + +#ifdef FEATURE_TSO_STATS +void dp_print_tso_stats(struct dp_soc *soc, + enum qdf_stats_verbosity_level level) +{ + uint8_t loop_pdev; + uint32_t id; + struct dp_pdev *pdev; + + for (loop_pdev = 0; loop_pdev < soc->pdev_count; loop_pdev++) { + pdev = soc->pdev_list[loop_pdev]; + DP_PRINT_STATS("TSO Statistics\n"); + DP_PRINT_STATS( + "From stack: %d | Successful completions: %d | TSO Packets: %d | TSO Completions: %d", + pdev->stats.tx_i.rcvd.num, + pdev->stats.tx.tx_success.num, + pdev->stats.tso_stats.num_tso_pkts.num, + pdev->stats.tso_stats.tso_comp); + + for (id = 0; id < CDP_MAX_TSO_PACKETS; id++) { + /* TSO LEVEL 1 - PACKET INFO */ + DP_PRINT_STATS( + "Packet_Id:[%u]: Packet Length %zu | No. of segments: %u", + id, + pdev->stats.tso_stats.tso_info + .tso_packet_info[id].tso_packet_len, + pdev->stats.tso_stats.tso_info + .tso_packet_info[id].num_seg); + /* TSO LEVEL 2 */ + if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH) + dp_print_tso_seg_stats(pdev, id); + } + + DP_PRINT_STATS( + "TSO Histogram: Single: %llu | 2-5 segs: %llu | 6-10: %llu segs | 11-15 segs: %llu | 16-20 segs: %llu | 20+ segs: %llu", + pdev->stats.tso_stats.seg_histogram.segs_1, + pdev->stats.tso_stats.seg_histogram.segs_2_5, + pdev->stats.tso_stats.seg_histogram.segs_6_10, + pdev->stats.tso_stats.seg_histogram.segs_11_15, + pdev->stats.tso_stats.seg_histogram.segs_16_20, + pdev->stats.tso_stats.seg_histogram.segs_20_plus); + } } +void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev, + uint8_t _p_cntrs) +{ + if (_p_cntrs == 1) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_1, 1); + } else if (_p_cntrs >= 2 && _p_cntrs <= 5) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_2_5, 1); + } else if (_p_cntrs > 5 && _p_cntrs <= 10) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_6_10, 1); + } else if (_p_cntrs > 10 && _p_cntrs <= 15) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_11_15, 1); + } else if (_p_cntrs > 15 && _p_cntrs <= 20) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_16_20, 1); + } else if (_p_cntrs > 20) { + DP_STATS_INC(pdev, + tso_stats.seg_histogram.segs_20_plus, 1); + } +} + +void dp_tso_segment_update(struct dp_pdev *pdev, + uint32_t stats_idx, + uint8_t idx, + struct qdf_tso_seg_t seg) +{ + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].num_frags, + seg.num_frags); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].total_len, + seg.total_len); + + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.tso_enable, + seg.tso_flags.tso_enable); + + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.fin, + seg.tso_flags.fin); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.syn, + seg.tso_flags.syn); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.rst, + seg.tso_flags.rst); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.psh, + seg.tso_flags.psh); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.ack, + seg.tso_flags.ack); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.urg, + seg.tso_flags.urg); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.ece, + seg.tso_flags.ece); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.cwr, + seg.tso_flags.cwr); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.ns, + seg.tso_flags.ns); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.tcp_seq_num, + seg.tso_flags.tcp_seq_num); + DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_seg[idx].tso_flags.ip_id, + seg.tso_flags.ip_id); +} + +void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx, + qdf_nbuf_t msdu, uint16_t num_segs) +{ + DP_STATS_UPD(pdev, + tso_stats.tso_info.tso_packet_info[stats_idx] + .num_seg, + num_segs); + + DP_STATS_UPD(pdev, + tso_stats.tso_info.tso_packet_info[stats_idx] + .tso_packet_len, + qdf_nbuf_get_tcp_payload_len(msdu)); +} + +void dp_tso_segment_stats_update(struct dp_pdev *pdev, + struct qdf_tso_seg_elem_t *stats_seg, + uint32_t stats_idx) +{ + uint8_t tso_seg_idx = 0; + + while (stats_seg && (tso_seg_idx < CDP_MAX_TSO_SEGMENTS)) { + dp_tso_segment_update(pdev, stats_idx, + tso_seg_idx, + stats_seg->seg); + ++tso_seg_idx; + stats_seg = stats_seg->next; + } +} + +void dp_txrx_clear_tso_stats(struct dp_soc *soc) +{ + uint8_t loop_pdev; + struct dp_pdev *pdev; + + for (loop_pdev = 0; loop_pdev < soc->pdev_count; loop_pdev++) { + pdev = soc->pdev_list[loop_pdev]; + dp_init_tso_stats(pdev); + } +} +#endif /* FEATURE_TSO_STATS */ diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c index bbe07bf72a063b9e7c6701511c5a8d6502acee8d..b29c353632849cc79f8d893b795586ac782ee19a 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c @@ -17,6 +17,7 @@ */ #include "htt.h" +#include "dp_htt.h" #include "hal_hw_headers.h" #include "dp_tx.h" #include "dp_tx_desc.h" @@ -27,7 +28,7 @@ #include "qdf_nbuf.h" #include "qdf_net_types.h" #include -#ifdef MESH_MODE_SUPPORT +#if defined(MESH_MODE_SUPPORT) || defined(FEATURE_PERPKT_INFO) #include "if_meta_hdr.h" #endif #include "enet.h" @@ -35,8 +36,10 @@ #ifdef FEATURE_WDS #include "dp_txrx_wds.h" #endif +#ifdef ATH_SUPPORT_IQUE +#include "dp_txrx_me.h" +#endif -#define DP_TX_QUEUE_MASK 0x3 /* TODO Add support in TSO */ #define DP_DESC_NUM_FRAG(x) 0 @@ -63,56 +66,90 @@ static const uint8_t sec_type_map[MAX_CDP_SEC_TYPE] = { HAL_TX_ENCRYPT_TYPE_AES_GCMP_256, HAL_TX_ENCRYPT_TYPE_WAPI_GCM_SM4}; -#ifdef WLAN_TX_PKT_CAPTURE_ENH -#include "dp_tx_capture.h" -#endif - +#ifdef QCA_TX_LIMIT_CHECK /** - * dp_tx_get_queue() - Returns Tx queue IDs to be used for this Tx frame - * @vdev: DP Virtual device handle - * @nbuf: Buffer pointer - * @queue: queue ids container for nbuf + * dp_tx_limit_check - Check if allocated tx descriptors reached + * soc max limit and pdev max limit + * @vdev: DP vdev handle * - * TX packet queue has 2 instances, software descriptors id and dma ring id - * Based on tx feature and hardware configuration queue id combination - * could be different. - * For example - - * With XPS enabled,all TX descriptor pools and dma ring are assigned - * per cpu id - * With no XPS,lock based resource protection, Descriptor pool ids are - * different for each vdev, dma ring id will be same as single pdev id + * Return: true if allocated tx descriptors reached max configured value, else + * false + */ +static inline bool +dp_tx_limit_check(struct dp_vdev *vdev) +{ + struct dp_pdev *pdev = vdev->pdev; + struct dp_soc *soc = pdev->soc; + + if (qdf_atomic_read(&soc->num_tx_outstanding) >= + soc->num_tx_allowed) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s: queued packets are more than max tx, drop the frame", + __func__); + DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1); + return true; + } + + if (qdf_atomic_read(&pdev->num_tx_outstanding) >= + pdev->num_tx_allowed) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s: queued packets are more than max tx, drop the frame", + __func__); + DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1); + return true; + } + return false; +} + +/** + * dp_tx_outstanding_inc - Increment outstanding tx desc values on pdev and soc + * @vdev: DP pdev handle * - * Return: None + * Return: void */ -#ifdef QCA_OL_TX_MULTIQ_SUPPORT -static inline void dp_tx_get_queue(struct dp_vdev *vdev, - qdf_nbuf_t nbuf, struct dp_tx_queue *queue) +static inline void +dp_tx_outstanding_inc(struct dp_pdev *pdev) { - uint16_t queue_offset = qdf_nbuf_get_queue_mapping(nbuf) & DP_TX_QUEUE_MASK; - queue->desc_pool_id = queue_offset; - queue->ring_id = vdev->pdev->soc->tx_ring_map[queue_offset]; + struct dp_soc *soc = pdev->soc; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s, pool_id:%d ring_id: %d", - __func__, queue->desc_pool_id, queue->ring_id); + qdf_atomic_inc(&pdev->num_tx_outstanding); + qdf_atomic_inc(&soc->num_tx_outstanding); +} - return; +/** + * dp_tx_outstanding__dec - Decrement outstanding tx desc values on pdev and soc + * @vdev: DP pdev handle + * + * Return: void + */ +static inline void +dp_tx_outstanding_dec(struct dp_pdev *pdev) +{ + struct dp_soc *soc = pdev->soc; + + qdf_atomic_dec(&pdev->num_tx_outstanding); + qdf_atomic_dec(&soc->num_tx_outstanding); } -#else /* QCA_OL_TX_MULTIQ_SUPPORT */ -static inline void dp_tx_get_queue(struct dp_vdev *vdev, - qdf_nbuf_t nbuf, struct dp_tx_queue *queue) + +#else //QCA_TX_LIMIT_CHECK +static inline bool +dp_tx_limit_check(struct dp_vdev *vdev) { - /* get flow id */ - queue->desc_pool_id = DP_TX_GET_DESC_POOL_ID(vdev); - queue->ring_id = DP_TX_GET_RING_ID(vdev); + return false; +} - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "%s, pool_id:%d ring_id: %d", - __func__, queue->desc_pool_id, queue->ring_id); +static inline void +dp_tx_outstanding_inc(struct dp_pdev *pdev) +{ + qdf_atomic_inc(&pdev->num_tx_outstanding); +} - return; +static inline void +dp_tx_outstanding_dec(struct dp_pdev *pdev) +{ + qdf_atomic_dec(&pdev->num_tx_outstanding); } -#endif +#endif //QCA_TX_LIMIT_CHECK #if defined(FEATURE_TSO) /** @@ -180,6 +217,7 @@ static void dp_tx_tso_desc_release(struct dp_soc *soc, dp_tso_num_seg_free(soc, tx_desc->pool_id, tx_desc->tso_num_desc); tx_desc->tso_num_desc = NULL; + DP_STATS_INC(tx_desc->pdev, tso_stats.tso_comp, 1); } /* Add the tso segment into the free list*/ @@ -232,7 +270,7 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id) if (tx_desc->flags & DP_TX_DESC_FLAG_ME) dp_tx_me_free_buf(tx_desc->pdev, tx_desc->me_buffer); - qdf_atomic_dec(&pdev->num_tx_outstanding); + dp_tx_outstanding_dec(pdev); if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW) qdf_atomic_dec(&pdev->num_tx_exception); @@ -269,7 +307,7 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id) * */ static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf, - struct dp_tx_msdu_info_s *msdu_info) + struct dp_tx_msdu_info_s *msdu_info) { uint32_t *meta_data = msdu_info->meta_data; struct htt_tx_msdu_desc_ext2_t *desc_ext = @@ -288,12 +326,26 @@ static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf, htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext2_t); htt_desc_size_aligned = (htt_desc_size + 7) & ~0x7; - if (vdev->mesh_vdev || msdu_info->is_tx_sniffer) { + if (vdev->mesh_vdev || msdu_info->is_tx_sniffer || + HTT_TX_MSDU_EXT2_DESC_FLAG_VALID_KEY_FLAGS_GET(msdu_info-> + meta_data[0])) { if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < - htt_desc_size_aligned)) { - DP_STATS_INC(vdev, - tx_i.dropped.headroom_insufficient, 1); - return 0; + htt_desc_size_aligned)) { + nbuf = qdf_nbuf_realloc_headroom(nbuf, + htt_desc_size_aligned); + if (!nbuf) { + /* + * qdf_nbuf_realloc_headroom won't do skb_clone + * as skb_realloc_headroom does. so, no free is + * needed here. + */ + DP_STATS_INC(vdev, + tx_i.dropped.headroom_insufficient, + 1); + qdf_print(" %s[%d] skb_realloc_headroom failed", + __func__, __LINE__); + return 0; + } } /* Fill and add HTT metaheader */ hdr = qdf_nbuf_push_head(nbuf, htt_desc_size_aligned); @@ -448,6 +500,28 @@ static void dp_tx_unmap_tso_seg_list( } } +#ifdef FEATURE_TSO_STATS +/** + * dp_tso_get_stats_idx: Retrieve the tso packet id + * @pdev - pdev handle + * + * Return: id + */ +static uint32_t dp_tso_get_stats_idx(struct dp_pdev *pdev) +{ + uint32_t stats_idx; + + stats_idx = (((uint32_t)qdf_atomic_inc_return(&pdev->tso_idx)) + % CDP_MAX_TSO_PACKETS); + return stats_idx; +} +#else +static int dp_tso_get_stats_idx(struct dp_pdev *pdev) +{ + return 0; +} +#endif /* FEATURE_TSO_STATS */ + /** * dp_tx_free_remaining_tso_desc() - do dma unmap for tso segments if any, * free the tso segments descriptor and @@ -493,9 +567,9 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev, struct qdf_tso_seg_elem_t *tso_seg; int num_seg = qdf_nbuf_get_tso_num_seg(msdu); struct dp_soc *soc = vdev->pdev->soc; + struct dp_pdev *pdev = vdev->pdev; struct qdf_tso_info_t *tso_info; struct qdf_tso_num_seg_elem_t *tso_num_seg; - tso_info = &msdu_info->u.tso_info; tso_info->curr_seg = NULL; tso_info->tso_seg_list = NULL; @@ -514,7 +588,8 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev, num_seg--; } else { dp_err_rl("Failed to alloc tso seg desc"); - DP_STATS_INC_PKT(vdev, tx_i.tso.tso_no_mem_dropped, 1, + DP_STATS_INC_PKT(vdev->pdev, + tso_stats.tso_no_mem_dropped, 1, qdf_nbuf_len(msdu)); dp_tx_free_remaining_tso_desc(soc, msdu_info, false); @@ -557,6 +632,12 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev, tso_info->curr_seg = tso_info->tso_seg_list; + tso_info->msdu_stats_idx = dp_tso_get_stats_idx(pdev); + dp_tso_packet_update(pdev, tso_info->msdu_stats_idx, + msdu, msdu_info->num_seg); + dp_tso_segment_stats_update(pdev, tso_info->tso_seg_list, + tso_info->msdu_stats_idx); + dp_stats_tso_segment_histogram_update(pdev, msdu_info->num_seg); return QDF_STATUS_SUCCESS; } #else @@ -567,6 +648,10 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev, } #endif +QDF_COMPILE_TIME_ASSERT(dp_tx_htt_metadata_len_check, + (DP_TX_MSDU_INFO_META_DATA_DWORDS * 4 >= + sizeof(struct htt_tx_msdu_desc_ext2_t))); + /** * dp_tx_prepare_ext_desc() - Allocate and prepare MSDU extension descriptor * @vdev: DP Vdev handle @@ -600,6 +685,7 @@ struct dp_tx_ext_desc_elem_s *dp_tx_prepare_ext_desc(struct dp_vdev *vdev, &msdu_info->meta_data[0], sizeof(struct htt_tx_msdu_desc_ext2_t)); qdf_atomic_inc(&vdev->pdev->num_tx_exception); + msdu_ext_desc->flags |= DP_TX_EXT_DESC_FLAG_METADATA_VALID; } switch (msdu_info->frm_type) { @@ -664,39 +750,6 @@ static void dp_tx_trace_pkt(qdf_nbuf_t skb, uint16_t msdu_id, msdu_id, QDF_TX)); } -#ifdef QCA_512M_CONFIG -/** - * dp_tx_pdev_pflow_control - Check if allocated tx descriptors reached max - * tx descriptor configured value - * @vdev: DP vdev handle - * - * Return: true if allocated tx descriptors reached max configured value, else - * false. - */ -static inline bool -dp_tx_pdev_pflow_control(struct dp_vdev *vdev) -{ - struct dp_pdev *pdev = vdev->pdev; - - if (qdf_atomic_read(&pdev->num_tx_outstanding) >= - pdev->num_tx_allowed) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s: queued packets are more than max tx, drop the frame", - __func__); - DP_STATS_INC(vdev, tx_i.dropped.desc_na.num, 1); - return true; - } - - return false; -} -#else -static inline bool -dp_tx_pdev_pflow_control(struct dp_vdev *vdev) -{ - return false; -} -#endif - /** * dp_tx_desc_prepare_single - Allocate and prepare Tx descriptor * @vdev: DP vdev handle @@ -723,7 +776,7 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; - if (dp_tx_pdev_pflow_control(vdev)) + if (dp_tx_limit_check(vdev)) return NULL; /* Allocate software Tx descriptor */ @@ -733,8 +786,7 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, return NULL; } - /* Flow control/Congestion Control counters */ - qdf_atomic_inc(&pdev->num_tx_outstanding); + dp_tx_outstanding_inc(pdev); /* Initialize the SW tx descriptor */ tx_desc->nbuf = nbuf; @@ -749,6 +801,11 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, dp_tx_trace_pkt(nbuf, tx_desc->id, vdev->vdev_id); + if (qdf_unlikely(vdev->multipass_en)) { + if (!dp_tx_multipass_process(soc, vdev, nbuf, msdu_info)) + goto failure; + } + /* * For special modes (vdev_type == ocb or mesh), data frames should be * transmitted using varying transmit parameters (tx spec) which include @@ -864,7 +921,7 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev, struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; - if (dp_tx_pdev_pflow_control(vdev)) + if (dp_tx_limit_check(vdev)) return NULL; /* Allocate software Tx descriptor */ @@ -874,8 +931,7 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev, return NULL; } - /* Flow control/Congestion Control counters */ - qdf_atomic_inc(&pdev->num_tx_outstanding); + dp_tx_outstanding_inc(pdev); /* Initialize the SW tx descriptor */ tx_desc->nbuf = nbuf; @@ -999,6 +1055,113 @@ static qdf_nbuf_t dp_tx_prepare_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf, } +/** + * dp_tx_raw_prepare_unset() - unmap the chain of nbufs belonging to RAW frame. + * @soc: DP soc handle + * @nbuf: Buffer pointer + * + * unmap the chain of nbufs that belong to this RAW frame. + * + * Return: None + */ +static void dp_tx_raw_prepare_unset(struct dp_soc *soc, + qdf_nbuf_t nbuf) +{ + qdf_nbuf_t cur_nbuf = nbuf; + + do { + qdf_nbuf_unmap(soc->osdev, cur_nbuf, QDF_DMA_TO_DEVICE); + cur_nbuf = qdf_nbuf_next(cur_nbuf); + } while (cur_nbuf); +} + +#ifdef VDEV_PEER_PROTOCOL_COUNT +#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, nbuf) \ +{ \ + qdf_nbuf_t nbuf_local; \ + struct dp_vdev *vdev_local = vdev_hdl; \ + do { \ + if (qdf_likely(!((vdev_local)->peer_protocol_count_track))) \ + break; \ + nbuf_local = nbuf; \ + if (qdf_unlikely(((vdev_local)->tx_encap_type) == \ + htt_cmn_pkt_type_raw)) \ + break; \ + else if (qdf_unlikely(qdf_nbuf_is_nonlinear((nbuf_local)))) \ + break; \ + else if (qdf_nbuf_is_tso((nbuf_local))) \ + break; \ + dp_vdev_peer_stats_update_protocol_cnt((vdev_local), \ + (nbuf_local), \ + NULL, 1, 0); \ + } while (0); \ +} +#else +#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb) +#endif + +#ifdef FEATURE_RUNTIME_PM +/** + * dp_tx_ring_access_end_wrapper() - Wrapper for ring access end + * @soc: Datapath soc handle + * @hal_ring_hdl: HAL ring handle + * + * Wrapper for HAL ring access end for data transmission for + * FEATURE_RUNTIME_PM + * + * Returns: none + */ +static inline void +dp_tx_ring_access_end_wrapper(struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + int ret; + + ret = hif_pm_runtime_get(soc->hif_handle, + RTPM_ID_DW_TX_HW_ENQUEUE); + switch (ret) { + case 0: + hal_srng_access_end(soc->hal_soc, hal_ring_hdl); + hif_pm_runtime_put(soc->hif_handle, + RTPM_ID_DW_TX_HW_ENQUEUE); + break; + /* + * If hif_pm_runtime_get returns -EBUSY or -EINPROGRESS, + * take the dp runtime refcount using dp_runtime_get, + * check link state,if up, write TX ring HP, else just set flush event. + * In dp_runtime_resume, wait until dp runtime refcount becomes + * zero or time out, then flush pending tx. + */ + case -EBUSY: + case -EINPROGRESS: + dp_runtime_get(soc); + if (hif_pm_get_link_state(soc->hif_handle) == + HIF_PM_LINK_STATE_UP) { + hal_srng_access_end(soc->hal_soc, hal_ring_hdl); + } else { + hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); + } + dp_runtime_put(soc); + break; + default: + dp_runtime_get(soc); + hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); + dp_runtime_put(soc); + } +} +#else +static inline void +dp_tx_ring_access_end_wrapper(struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + hal_srng_access_end(soc->hal_soc, hal_ring_hdl); +} +#endif + /** * dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit * @soc: DP Soc Handle @@ -1032,7 +1195,7 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, /* Return Buffer Manager ID */ uint8_t bm_id = ring_id; - void *hal_srng = soc->tcl_data_ring[ring_id].hal_srng; + hal_ring_handle_t hal_ring_hdl = soc->tcl_data_ring[ring_id].hal_srng; hal_tx_desc_cached = (void *) cached_desc; qdf_mem_zero(hal_tx_desc_cached, HAL_TX_DESC_LEN_BYTES); @@ -1041,6 +1204,12 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, length = HAL_TX_EXT_DESC_WITH_META_DATA; type = HAL_TX_BUF_TYPE_EXT_DESC; dma_addr = tx_desc->msdu_ext_desc->paddr; + + if (tx_desc->msdu_ext_desc->flags & + DP_TX_EXT_DESC_FLAG_METADATA_VALID) + length = HAL_TX_EXT_DESC_WITH_META_DATA; + else + length = HAL_TX_EXTENSION_DESC_LEN_BYTES; } else { length = qdf_nbuf_len(tx_desc->nbuf) - tx_desc->pkt_offset; type = HAL_TX_BUF_TYPE_BUFFER; @@ -1065,11 +1234,13 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, hal_tx_desc_set_search_type(soc->hal_soc, hal_tx_desc_cached, vdev->search_type); hal_tx_desc_set_search_index(soc->hal_soc, hal_tx_desc_cached, - vdev->bss_ast_hash); + vdev->bss_ast_idx); hal_tx_desc_set_dscp_tid_table_id(soc->hal_soc, hal_tx_desc_cached, vdev->dscp_tid_map_id); hal_tx_desc_set_encrypt_type(hal_tx_desc_cached, sec_type_map[sec_type]); + hal_tx_desc_set_cache_set_num(soc->hal_soc, hal_tx_desc_cached, + (vdev->bss_ast_hash & 0xF)); dp_verbose_debug("length:%d , type = %d, dma_addr %llx, offset %d desc id %u", length, type, (uint64_t)dma_addr, @@ -1082,8 +1253,8 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, vdev->hal_desc_addr_search_flags); /* verify checksum offload configuration*/ - if ((wlan_cfg_get_checksum_offload(soc->wlan_cfg_ctx)) && - ((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) == QDF_NBUF_TX_CKSUM_TCP_UDP) + if (vdev->csum_enabled && + ((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) == QDF_NBUF_TX_CKSUM_TCP_UDP) || qdf_nbuf_is_tso(tx_desc->nbuf))) { hal_tx_desc_set_l3_checksum_en(hal_tx_desc_cached, 1); hal_tx_desc_set_l4_checksum_en(hal_tx_desc_cached, 1); @@ -1093,12 +1264,12 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid); if (tx_desc->flags & DP_TX_DESC_FLAG_MESH) - hal_tx_desc_set_mesh_en(hal_tx_desc_cached, 1); + hal_tx_desc_set_mesh_en(soc->hal_soc, hal_tx_desc_cached, 1); tx_desc->timestamp = qdf_ktime_to_ms(qdf_ktime_get()); /* Sync cached descriptor with HW */ - hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_srng); + hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl); if (!hal_tx_desc) { dp_verbose_debug("TCL ring full ring_id:%d", ring_id); @@ -1108,6 +1279,7 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, } tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX; + dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf); hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc); DP_STATS_INC_PKT(vdev, tx_i.processed, 1, length); @@ -1249,7 +1421,7 @@ static void dp_tx_get_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf, DP_TX_TID_OVERRIDE(msdu_info, nbuf); if (qdf_likely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) { eh = (qdf_ether_header_t *)nbuf->data; - hdr_ptr = eh->ether_dhost; + hdr_ptr = (uint8_t *)(eh->ether_dhost); L3datap = hdr_ptr + sizeof(qdf_ether_header_t); } else { qdf_dot3_qosframe_t *qos_wh = @@ -1443,6 +1615,39 @@ static inline void dp_non_std_tx_comp_free_buff(struct dp_soc *soc, } #endif +/** + * dp_tx_frame_is_drop() - checks if the packet is loopback + * @vdev: DP vdev handle + * @nbuf: skb + * + * Return: 1 if frame needs to be dropped else 0 + */ +int dp_tx_frame_is_drop(struct dp_vdev *vdev, uint8_t *srcmac, uint8_t *dstmac) +{ + struct dp_pdev *pdev = NULL; + struct dp_ast_entry *src_ast_entry = NULL; + struct dp_ast_entry *dst_ast_entry = NULL; + struct dp_soc *soc = NULL; + + qdf_assert(vdev); + pdev = vdev->pdev; + qdf_assert(pdev); + soc = pdev->soc; + + dst_ast_entry = dp_peer_ast_hash_find_by_pdevid + (soc, dstmac, vdev->pdev->pdev_id); + + src_ast_entry = dp_peer_ast_hash_find_by_pdevid + (soc, srcmac, vdev->pdev->pdev_id); + if (dst_ast_entry && src_ast_entry) { + if (dst_ast_entry->peer->peer_ids[0] == + src_ast_entry->peer->peer_ids[0]) + return 1; + } + + return 0; +} + /** * dp_tx_send_msdu_single() - Setup descriptor and enqueue single MSDU to TCL * @vdev: DP vdev handle @@ -1456,16 +1661,18 @@ static inline void dp_non_std_tx_comp_free_buff(struct dp_soc *soc, * Return: NULL on success, * nbuf when it fails to send */ -static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, - struct dp_tx_msdu_info_s *msdu_info, uint16_t peer_id, - struct cdp_tx_exception_metadata *tx_exc_metadata) +qdf_nbuf_t +dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info, uint16_t peer_id, + struct cdp_tx_exception_metadata *tx_exc_metadata) { struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; struct dp_tx_desc_s *tx_desc; QDF_STATUS status; struct dp_tx_queue *tx_q = &(msdu_info->tx_queue); - void *hal_srng = soc->tcl_data_ring[tx_q->ring_id].hal_srng; + hal_ring_handle_t hal_ring_hdl = + soc->tcl_data_ring[tx_q->ring_id].hal_srng; uint16_t htt_tcl_metadata = 0; uint8_t tid = msdu_info->tid; struct cdp_tid_tx_stats *tid_stats = NULL; @@ -1493,10 +1700,10 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, dp_tx_update_tdls_flags(tx_desc); - if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) { + if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_ring_hdl))) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL RING Access Failed -- %pK", - __func__, __LINE__, hal_srng); + __func__, __LINE__, hal_ring_hdl); dp_tx_get_tid(vdev, nbuf, msdu_info); tid_stats = &pdev->stats.tid_stats. tid_tx_stats[tx_q->ring_id][tid]; @@ -1543,20 +1750,62 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, nbuf = NULL; fail_return: - if (hif_pm_runtime_get(soc->hif_handle, - RTPM_ID_DW_TX_HW_ENQUEUE) == 0) { - hal_srng_access_end(soc->hal_soc, hal_srng); - hif_pm_runtime_put(soc->hif_handle, - RTPM_ID_DW_TX_HW_ENQUEUE); - } else { - hal_srng_access_end_reap(soc->hal_soc, hal_srng); - hal_srng_set_event(hal_srng, HAL_SRNG_FLUSH_EVENT); - hal_srng_inc_flush_cnt(hal_srng); - } + dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl); return nbuf; } +/** + * dp_tx_comp_free_buf() - Free nbuf associated with the Tx Descriptor + * @soc: Soc handle + * @desc: software Tx descriptor to be processed + * + * Return: none + */ +static inline void dp_tx_comp_free_buf(struct dp_soc *soc, + struct dp_tx_desc_s *desc) +{ + struct dp_vdev *vdev = desc->vdev; + qdf_nbuf_t nbuf = desc->nbuf; + + /* nbuf already freed in vdev detach path */ + if (!nbuf) + return; + + /* If it is TDLS mgmt, don't unmap or free the frame */ + if (desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME) + return dp_non_std_tx_comp_free_buff(soc, desc, vdev); + + /* 0 : MSDU buffer, 1 : MLE */ + if (desc->msdu_ext_desc) { + /* TSO free */ + if (hal_tx_ext_desc_get_tso_enable( + desc->msdu_ext_desc->vaddr)) { + /* unmap eash TSO seg before free the nbuf */ + dp_tx_tso_unmap_segment(soc, desc->tso_desc, + desc->tso_num_desc); + qdf_nbuf_free(nbuf); + return; + } + } + + qdf_nbuf_unmap(soc->osdev, nbuf, QDF_DMA_TO_DEVICE); + + if (qdf_unlikely(!vdev)) { + qdf_nbuf_free(nbuf); + return; + } + + if (qdf_likely(!vdev->mesh_vdev)) + qdf_nbuf_free(nbuf); + else { + if (desc->flags & DP_TX_DESC_FLAG_TO_FW) { + qdf_nbuf_free(nbuf); + DP_STATS_INC(vdev, tx_i.mesh.completion_fw, 1); + } else + vdev->osif_tx_free_ext((nbuf)); + } +} /** * dp_tx_send_msdu_multiple() - Enqueue multiple MSDUs * @vdev: DP vdev handle @@ -1569,9 +1818,8 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, * nbuf when it fails to send */ #if QDF_LOCK_STATS -static noinline +noinline #else -static #endif qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, struct dp_tx_msdu_info_s *msdu_info) @@ -1583,15 +1831,15 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, bool is_cce_classified = false; QDF_STATUS status; uint16_t htt_tcl_metadata = 0; - struct dp_tx_queue *tx_q = &msdu_info->tx_queue; - void *hal_srng = soc->tcl_data_ring[tx_q->ring_id].hal_srng; + hal_ring_handle_t hal_ring_hdl = + soc->tcl_data_ring[tx_q->ring_id].hal_srng; struct cdp_tid_tx_stats *tid_stats = NULL; - if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) { + if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_ring_hdl))) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL RING Access Failed -- %pK", - __func__, __LINE__, hal_srng); + __func__, __LINE__, hal_ring_hdl); dp_tx_get_tid(vdev, nbuf, msdu_info); tid_stats = &pdev->stats.tid_stats. tid_tx_stats[tx_q->ring_id][msdu_info->tid]; @@ -1630,7 +1878,25 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, dp_tx_me_free_buf(pdev, (void *)(msdu_info->u.sg_info .curr_seg->frags[0].vaddr)); + i++; + continue; } + + if (msdu_info->frm_type == dp_tx_frm_tso) { + dp_tx_tso_unmap_segment(soc, + msdu_info->u.tso_info. + curr_seg, + msdu_info->u.tso_info. + tso_num_seg_list); + + if (msdu_info->u.tso_info.curr_seg->next) { + msdu_info->u.tso_info.curr_seg = + msdu_info->u.tso_info.curr_seg->next; + i++; + continue; + } + } + goto done; } @@ -1658,15 +1924,17 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, msdu_info->u.tso_info.curr_seg->next; /* - * If this is a jumbo nbuf, then increment the number of - * nbuf users for each additional segment of the msdu. - * This will ensure that the skb is freed only after - * receiving tx completion for all segments of an nbuf + * If this is a jumbo nbuf, then increment the + * number of nbuf users for each additional + * segment of the msdu. This will ensure that + * the skb is freed only after receiving tx + * completion for all segments of an nbuf */ qdf_nbuf_inc_users(nbuf); /* Check with MCL if this is needed */ - /* nbuf = msdu_info->u.tso_info.curr_seg->nbuf; */ + /* nbuf = msdu_info->u.tso_info.curr_seg->nbuf; + */ } } @@ -1685,19 +1953,29 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, tid_stats = &pdev->stats.tid_stats. tid_tx_stats[tx_q->ring_id][msdu_info->tid]; tid_stats->swdrop_cnt[TX_HW_ENQUEUE]++; - if (tx_desc->flags & DP_TX_DESC_FLAG_ME) - dp_tx_me_free_buf(pdev, tx_desc->me_buffer); dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); + if (msdu_info->frm_type == dp_tx_frm_me) { + i++; + continue; + } + /* * For TSO frames, the nbuf users increment done for * the current segment has to be reverted, since the * hw enqueue for this segment failed */ if (msdu_info->frm_type == dp_tx_frm_tso && - msdu_info->u.tso_info.curr_seg) { - qdf_nbuf_free(nbuf); + msdu_info->u.tso_info.curr_seg) { + /* + * unmap and free current, + * retransmit remaining segments + */ + dp_tx_comp_free_buf(soc, tx_desc); + i++; + continue; } + goto done; } @@ -1729,13 +2007,13 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, done: if (hif_pm_runtime_get(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE) == 0) { - hal_srng_access_end(soc->hal_soc, hal_srng); + hal_srng_access_end(soc->hal_soc, hal_ring_hdl); hif_pm_runtime_put(soc->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE); } else { - hal_srng_access_end_reap(soc->hal_soc, hal_srng); - hal_srng_set_event(hal_srng, HAL_SRNG_FLUSH_EVENT); - hal_srng_inc_flush_cnt(hal_srng); + hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } return nbuf; @@ -1944,8 +2222,9 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc) { bool invalid_tid = (tx_exc->tid > DP_MAX_TIDS && tx_exc->tid != HTT_INVALID_TID); - bool invalid_encap_type = (tx_exc->tid > DP_MAX_TIDS && tx_exc->tid != - HTT_INVALID_TID); + bool invalid_encap_type = + (tx_exc->tx_encap_type > htt_cmn_pkt_num_types && + tx_exc->tx_encap_type != CDP_INVALID_TX_ENCAP_TYPE); bool invalid_sec_type = (tx_exc->sec_type > cdp_num_sec_types && tx_exc->sec_type != CDP_INVALID_SEC_TYPE); bool invalid_cookie = (tx_exc->is_tx_sniffer == 1 && @@ -1961,7 +2240,8 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc) /** * dp_tx_send_exception() - Transmit a frame on a given VAP in exception path - * @vap_dev: DP vdev handle + * @soc: DP soc handle + * @vdev_id: id of DP vdev handle * @nbuf: skb * @tx_exc_metadata: Handle that holds exception path meta data * @@ -1971,12 +2251,18 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc) * Return: NULL on success, * nbuf when it fails to send */ -qdf_nbuf_t dp_tx_send_exception(void *vap_dev, qdf_nbuf_t nbuf, - struct cdp_tx_exception_metadata *tx_exc_metadata) +qdf_nbuf_t +dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf, + struct cdp_tx_exception_metadata *tx_exc_metadata) { qdf_ether_header_t *eh = NULL; - struct dp_vdev *vdev = (struct dp_vdev *) vap_dev; struct dp_tx_msdu_info_s msdu_info; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (qdf_unlikely(!vdev)) + goto fail; qdf_mem_zero(&msdu_info, sizeof(msdu_info)); @@ -1986,7 +2272,8 @@ qdf_nbuf_t dp_tx_send_exception(void *vap_dev, qdf_nbuf_t nbuf, msdu_info.tid = tx_exc_metadata->tid; eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); - dp_verbose_debug("skb %pM", nbuf->data); + dp_verbose_debug("skb "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(nbuf->data)); DP_STATS_INC_PKT(vdev, tx_i.rcvd, 1, qdf_nbuf_len(nbuf)); @@ -2067,7 +2354,8 @@ qdf_nbuf_t dp_tx_send_exception(void *vap_dev, qdf_nbuf_t nbuf, /** * dp_tx_send_mesh() - Transmit mesh frame on a given VAP - * @vap_dev: DP vdev handle + * @soc: DP soc handle + * @vdev_id: DP vdev handle * @nbuf: skb * * Entry point for Core Tx layer (DP_TX) invoked from @@ -2077,12 +2365,13 @@ qdf_nbuf_t dp_tx_send_exception(void *vap_dev, qdf_nbuf_t nbuf, * nbuf when it fails to send */ #ifdef MESH_MODE_SUPPORT -qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) +qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t nbuf) { struct meta_hdr_s *mhdr; qdf_nbuf_t nbuf_mesh = NULL; qdf_nbuf_t nbuf_clone = NULL; - struct dp_vdev *vdev = (struct dp_vdev *) vap_dev; + struct dp_vdev *vdev; uint8_t no_enc_frame = 0; nbuf_mesh = qdf_nbuf_unshare(nbuf); @@ -2091,6 +2380,15 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) "qdf_nbuf_unshare failed"); return nbuf; } + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + if (!vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "vdev is NULL for vdev_id %d", vdev_id); + return nbuf; + } + nbuf = nbuf_mesh; mhdr = (struct meta_hdr_s *)qdf_nbuf_data(nbuf); @@ -2114,7 +2412,7 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) } if (nbuf_clone) { - if (!dp_tx_send(vap_dev, nbuf_clone)) { + if (!dp_tx_send(soc, vdev_id, nbuf_clone)) { DP_STATS_INC(vdev, tx_i.mesh.exception_fw, 1); } else { qdf_nbuf_free(nbuf_clone); @@ -2126,7 +2424,7 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) else qdf_nbuf_set_tx_ftype(nbuf, CB_FTYPE_INVALID); - nbuf = dp_tx_send(vap_dev, nbuf); + nbuf = dp_tx_send(soc, vdev_id, nbuf); if ((!nbuf) && no_enc_frame) { DP_STATS_INC(vdev, tx_i.mesh.exception_fw, 1); } @@ -2136,16 +2434,18 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) #else -qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) +qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t nbuf) { - return dp_tx_send(vap_dev, nbuf); + return dp_tx_send(soc, vdev_id, nbuf); } #endif /** * dp_tx_send() - Transmit a frame on a given VAP - * @vap_dev: DP vdev handle + * @soc: DP soc handle + * @vdev_id: id of DP vdev handle * @nbuf: skb * * Entry point for Core Tx layer (DP_TX) invoked from @@ -2155,21 +2455,27 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf) * Return: NULL on success, * nbuf when it fails to send */ -qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) +qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf) { qdf_ether_header_t *eh = NULL; struct dp_tx_msdu_info_s msdu_info; struct dp_tx_seg_info_s seg_info; - struct dp_vdev *vdev = (struct dp_vdev *) vap_dev; uint16_t peer_id = HTT_INVALID_PEER; qdf_nbuf_t nbuf_mesh = NULL; + struct dp_vdev *vdev = + dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc, + vdev_id); + + if (qdf_unlikely(!vdev)) + return nbuf; qdf_mem_zero(&msdu_info, sizeof(msdu_info)); qdf_mem_zero(&seg_info, sizeof(seg_info)); eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); - dp_verbose_debug("skb %pM", nbuf->data); + dp_verbose_debug("skb "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(nbuf->data)); /* * Set Default Host TID value to invalid TID @@ -2219,11 +2525,11 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) */ if (qdf_nbuf_is_tso(nbuf)) { dp_verbose_debug("TSO frame %pK", vdev); - DP_STATS_INC_PKT(vdev, tx_i.tso.tso_pkt, 1, - qdf_nbuf_len(nbuf)); + DP_STATS_INC_PKT(vdev->pdev, tso_stats.num_tso_pkts, 1, + qdf_nbuf_len(nbuf)); if (dp_tx_prepare_tso(vdev, nbuf, &msdu_info)) { - DP_STATS_INC_PKT(vdev, tx_i.tso.dropped_host, 1, + DP_STATS_INC_PKT(vdev->pdev, tso_stats.dropped_host, 1, qdf_nbuf_len(nbuf)); return nbuf; } @@ -2290,6 +2596,9 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf) send_multiple: nbuf = dp_tx_send_msdu_multiple(vdev, nbuf, &msdu_info); + if (qdf_unlikely(nbuf && msdu_info.frm_type == dp_tx_frm_raw)) + dp_tx_raw_prepare_unset(vdev->pdev->soc, nbuf); + return nbuf; } @@ -2605,58 +2914,6 @@ dp_send_completion_to_stack(struct dp_soc *soc, struct dp_pdev *pdev, } #endif -/** - * dp_tx_comp_free_buf() - Free nbuf associated with the Tx Descriptor - * @soc: Soc handle - * @desc: software Tx descriptor to be processed - * - * Return: none - */ -static inline void dp_tx_comp_free_buf(struct dp_soc *soc, - struct dp_tx_desc_s *desc) -{ - struct dp_vdev *vdev = desc->vdev; - qdf_nbuf_t nbuf = desc->nbuf; - - /* nbuf already freed in vdev detach path */ - if (!nbuf) - return; - - /* If it is TDLS mgmt, don't unmap or free the frame */ - if (desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME) - return dp_non_std_tx_comp_free_buff(soc, desc, vdev); - - /* 0 : MSDU buffer, 1 : MLE */ - if (desc->msdu_ext_desc) { - /* TSO free */ - if (hal_tx_ext_desc_get_tso_enable( - desc->msdu_ext_desc->vaddr)) { - /* unmap eash TSO seg before free the nbuf */ - dp_tx_tso_unmap_segment(soc, desc->tso_desc, - desc->tso_num_desc); - qdf_nbuf_free(nbuf); - return; - } - } - - qdf_nbuf_unmap(soc->osdev, nbuf, QDF_DMA_TO_DEVICE); - - if (qdf_unlikely(!vdev)) { - qdf_nbuf_free(nbuf); - return; - } - - if (qdf_likely(!vdev->mesh_vdev)) - qdf_nbuf_free(nbuf); - else { - if (desc->flags & DP_TX_DESC_FLAG_TO_FW) { - qdf_nbuf_free(nbuf); - DP_STATS_INC(vdev, tx_i.mesh.completion_fw, 1); - } else - vdev->osif_tx_free_ext((nbuf)); - } -} - #ifdef MESH_MODE_SUPPORT /** * dp_tx_comp_fill_tx_completion_stats() - Fill per packet Tx completion stats @@ -2836,14 +3093,30 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc, DP_STATS_INCC(peer, tx.dropped.fw_reason3, 1, (ts->status == HAL_TX_TQM_RR_FW_REASON3)); + /* + * tx_failed is ideally supposed to be updated from HTT ppdu completion + * stats. But in IPQ807X/IPQ6018 chipsets owing to hw limitation there + * are no completions for failed cases. Hence updating tx_failed from + * data path. Please note that if tx_failed is fixed to be from ppdu, + * then this has to be removed + */ + peer->stats.tx.tx_failed = peer->stats.tx.dropped.fw_rem.num + + peer->stats.tx.dropped.fw_rem_notx + + peer->stats.tx.dropped.fw_rem_tx + + peer->stats.tx.dropped.age_out + + peer->stats.tx.dropped.fw_reason1 + + peer->stats.tx.dropped.fw_reason2 + + peer->stats.tx.dropped.fw_reason3; + + if (ts->status < CDP_MAX_TX_TQM_STATUS) { + tid_stats->tqm_status_cnt[ts->status]++; + } + if (ts->status != HAL_TX_TQM_RR_FRAME_ACKED) { - tid_stats->comp_fail_cnt++; dp_update_no_ack_stats(tx_desc->nbuf, peer); return; } - tid_stats->success_cnt++; - DP_STATS_INCC(peer, tx.ofdma, 1, ts->ofdma); DP_STATS_INCC(peer, tx.amsdu_cnt, 1, ts->msdu_part_of_amsdu); @@ -3027,6 +3300,7 @@ static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, } #else static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev, + struct dp_peer *peer, uint8_t tid, uint64_t txdesc_ts, uint32_t ppdu_id) @@ -3085,6 +3359,7 @@ dp_tx_comp_process_desc(struct dp_soc *soc, /** * dp_tx_comp_process_tx_status() - Parse and Dump Tx completion status info + * @soc: DP soc handle * @tx_desc: software descriptor head pointer * @ts: Tx completion status * @peer: peer handle @@ -3093,13 +3368,13 @@ dp_tx_comp_process_desc(struct dp_soc *soc, * Return: none */ static inline -void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, +void dp_tx_comp_process_tx_status(struct dp_soc *soc, + struct dp_tx_desc_s *tx_desc, struct hal_tx_completion_status *ts, struct dp_peer *peer, uint8_t ring_id) { uint32_t length; qdf_ether_header_t *eh; - struct dp_soc *soc = NULL; struct dp_vdev *vdev = tx_desc->vdev; qdf_nbuf_t nbuf = tx_desc->nbuf; @@ -3109,6 +3384,7 @@ void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, } eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); + length = qdf_nbuf_len(nbuf); DPTRACE(qdf_dp_trace_ptr(tx_desc->nbuf, QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD, @@ -3147,26 +3423,22 @@ void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, ts->tones_in_ru, ts->tsf, ts->ppdu_id, ts->transmit_cnt, ts->tid, ts->peer_id); - soc = vdev->pdev->soc; - /* Update SoC level stats */ DP_STATS_INCC(soc, tx.dropped_fw_removed, 1, (ts->status == HAL_TX_TQM_RR_REM_CMD_REM)); + if (!peer) { + dp_err_rl("peer is null or deletion in progress"); + DP_STATS_INC_PKT(soc, tx.tx_invalid_peer, 1, length); + goto out; + } + /* Update per-packet stats for mesh mode */ if (qdf_unlikely(vdev->mesh_vdev) && !(tx_desc->flags & DP_TX_DESC_FLAG_TO_FW)) dp_tx_comp_fill_tx_completion_stats(tx_desc, ts); - length = qdf_nbuf_len(nbuf); /* Update peer level stats */ - if (!peer) { - QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_DP, - "peer is null or deletion in progress"); - DP_STATS_INC_PKT(soc, tx.tx_invalid_peer, 1, length); - goto out; - } - if (qdf_unlikely(peer->bss_peer && vdev->opmode == wlan_op_mode_ap)) { if (ts->status != HAL_TX_TQM_RR_REM_CMD_REM) { DP_STATS_INC_PKT(peer, tx.mcast, 1, length); @@ -3195,6 +3467,7 @@ void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc, out: return; } + /** * dp_tx_comp_process_desc_list() - Tx complete software descriptor handler * @soc: core txrx main context @@ -3221,7 +3494,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc, while (desc) { hal_tx_comp_get_status(&desc->comp, &ts, soc->hal_soc); peer = dp_peer_find_by_id(soc, ts.peer_id); - dp_tx_comp_process_tx_status(desc, &ts, peer, ring_id); + dp_tx_comp_process_tx_status(soc, desc, &ts, peer, ring_id); netbuf = desc->nbuf; /* check tx complete notification */ @@ -3263,6 +3536,7 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status, uint32_t *htt_desc = (uint32_t *)status; struct dp_peer *peer; struct cdp_tid_tx_stats *tid_stats = NULL; + struct htt_soc *htt_handle; qdf_assert(tx_desc->pdev); @@ -3272,8 +3546,9 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status, if (!vdev) return; - tx_status = HTT_TX_WBM_COMPLETION_V2_TX_STATUS_GET(htt_desc[0]); + htt_handle = (struct htt_soc *)soc->htt_handle; + htt_wbm_event_record(htt_handle->htt_logger_handle, tx_status, status); switch (tx_status) { case HTT_TX_FW2WBM_TX_STATUS_OK: @@ -3309,11 +3584,8 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status, if (qdf_unlikely(pdev->delay_stats_flag)) dp_tx_compute_delay(vdev, tx_desc, tid, ring_id); - if (qdf_unlikely(tx_status != HTT_TX_FW2WBM_TX_STATUS_OK)) { - ts.status = HAL_TX_TQM_RR_REM_CMD_REM; - tid_stats->comp_fail_cnt++; - } else { - tid_stats->success_cnt++; + if (tx_status < CDP_MAX_TX_HTT_STATUS) { + tid_stats->htt_status_cnt[tx_status]++; } peer = dp_peer_find_by_id(soc, ts.peer_id); @@ -3321,7 +3593,7 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status, if (qdf_likely(peer)) dp_peer_unref_del_find_by_id(peer); - dp_tx_comp_process_tx_status(tx_desc, &ts, peer, ring_id); + dp_tx_comp_process_tx_status(soc, tx_desc, &ts, peer, ring_id); dp_tx_comp_process_desc(soc, tx_desc, &ts, peer); dp_tx_desc_release(tx_desc, tx_desc->pool_id); @@ -3384,7 +3656,8 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc) #endif uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_srng, uint8_t ring_id, uint32_t quota) + hal_ring_handle_t hal_ring_hdl, uint8_t ring_id, + uint32_t quota) { void *tx_comp_hal_desc; uint8_t buffer_src; @@ -3405,14 +3678,14 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, tail_desc = NULL; count = 0; - if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_srng))) { - dp_err("HAL RING Access Failed -- %pK", hal_srng); + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) { + dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl); return 0; } /* Find head descriptor from completion ring */ while (qdf_likely(tx_comp_hal_desc = - hal_srng_dst_get_next(soc->hal_soc, hal_srng))) { + hal_srng_dst_get_next(soc->hal_soc, hal_ring_hdl))) { buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc); @@ -3436,13 +3709,22 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, * completion ring. These errors are not related to * Tx completions, and should just be ignored */ - - wbm_internal_error = - hal_get_wbm_internal_error(tx_comp_hal_desc); + wbm_internal_error = hal_get_wbm_internal_error( + soc->hal_soc, + tx_comp_hal_desc); if (wbm_internal_error) { dp_err_rl("Tx comp wbm_internal_error!!"); - DP_STATS_INC(soc, tx.wbm_internal_error, 1); + DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_ALL], 1); + + if (HAL_TX_COMP_RELEASE_SOURCE_REO == + buffer_src) + dp_handle_wbm_internal_error( + soc, + tx_comp_hal_desc, + hal_tx_comp_get_buffer_type( + tx_comp_hal_desc)); + } else { dp_err_rl("Tx comp wbm_internal_error false"); DP_STATS_INC(soc, tx.non_wbm_internal_err, 1); @@ -3477,6 +3759,20 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, continue; } + if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_INFO, + "pdev in down state %d", + tx_desc_id); + + num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK); + count++; + + dp_tx_comp_free_buf(soc, tx_desc); + dp_tx_desc_release(tx_desc, tx_desc->pool_id); + continue; + } + /* * If the release source is FW, process the HTT status */ @@ -3542,7 +3838,7 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, break; } - dp_srng_access_end(int_ctx, soc, hal_srng); + dp_srng_access_end(int_ctx, soc, hal_ring_hdl); /* Process the reaped descriptors */ if (head_desc) @@ -3550,7 +3846,8 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, if (dp_tx_comp_enable_eol_data_check(soc)) { if (!force_break && - hal_srng_dst_peek_sync_locked(soc, hal_srng)) { + hal_srng_dst_peek_sync_locked(soc->hal_soc, + hal_ring_hdl)) { DP_STATS_INC(soc, tx.hp_oos2, 1); if (!hif_exec_should_yield(soc->hif_handle, int_ctx->dp_intr_id)) @@ -3563,27 +3860,48 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, } #ifdef FEATURE_WLAN_TDLS -/** - * dp_tx_non_std() - Allow the control-path SW to send data frames - * - * @data_vdev - which vdev should transmit the tx data frames - * @tx_spec - what non-standard handling to apply to the tx data frames - * @msdu_list - NULL-terminated list of tx MSDUs - * - * Return: NULL on success, - * nbuf when it fails to send - */ -qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle, - enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) +qdf_nbuf_t dp_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) { - struct dp_vdev *vdev = (struct dp_vdev *) vdev_handle; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + + if (!vdev) { + dp_err("vdev handle for id %d is NULL", vdev_id); + return NULL; + } if (tx_spec & OL_TX_SPEC_NO_FREE) vdev->is_tdls_frame = true; - return dp_tx_send(vdev_handle, msdu_list); + + return dp_tx_send(soc_hdl, vdev_id, msdu_list); } #endif +static void dp_tx_vdev_update_feature_flags(struct dp_vdev *vdev) +{ + struct wlan_cfg_dp_soc_ctxt *cfg; + + struct dp_soc *soc; + + soc = vdev->pdev->soc; + if (!soc) + return; + + cfg = soc->wlan_cfg_ctx; + if (!cfg) + return; + + if (vdev->opmode == wlan_op_mode_ndi) + vdev->csum_enabled = wlan_cfg_get_nan_checksum_offload(cfg); + else if ((vdev->subtype == wlan_op_subtype_p2p_device) || + (vdev->subtype == wlan_op_subtype_p2p_cli) || + (vdev->subtype == wlan_op_subtype_p2p_go)) + vdev->csum_enabled = wlan_cfg_get_p2p_checksum_offload(cfg); + else + vdev->csum_enabled = wlan_cfg_get_checksum_offload(cfg); +} + /** * dp_tx_vdev_attach() - attach vdev to dp tx * @vdev: virtual device instance @@ -3593,6 +3911,7 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle, */ QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev) { + int pdev_id; /* * Fill HTT TCL Metadata with Vdev ID and MAC ID */ @@ -3602,8 +3921,10 @@ QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev) HTT_TX_TCL_METADATA_VDEV_ID_SET(vdev->htt_tcl_metadata, vdev->vdev_id); - HTT_TX_TCL_METADATA_PDEV_ID_SET(vdev->htt_tcl_metadata, - DP_SW2HW_MACID(vdev->pdev->pdev_id)); + pdev_id = + dp_get_target_pdev_id_for_host_pdev_id(vdev->pdev->soc, + vdev->pdev->pdev_id); + HTT_TX_TCL_METADATA_PDEV_ID_SET(vdev->htt_tcl_metadata, pdev_id); /* * Set HTT Extension Valid bit to 0 by default @@ -3612,6 +3933,8 @@ QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev) dp_tx_vdev_update_search_flags(vdev); + dp_tx_vdev_update_feature_flags(vdev); + return QDF_STATUS_SUCCESS; } @@ -3841,6 +4164,7 @@ QDF_STATUS dp_tx_vdev_detach(struct dp_vdev *vdev) /* Reset TX desc associated to this Vdev as NULL */ dp_tx_desc_flush(pdev, vdev, false); + dp_tx_vdev_multipass_deinit(vdev); return QDF_STATUS_SUCCESS; } @@ -3983,7 +4307,7 @@ QDF_STATUS dp_tso_detach_wifi3(void *txrx_soc) } #endif -QDF_STATUS dp_tso_soc_detach(void *txrx_soc) +QDF_STATUS dp_tso_soc_detach(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; uint8_t i; @@ -4017,7 +4341,7 @@ QDF_STATUS dp_tso_soc_detach(void *txrx_soc) * Return: QDF_STATUS_E_FAILURE on failure or * QDF_STATUS_SUCCESS on success */ -QDF_STATUS dp_tso_soc_attach(void *txrx_soc) +QDF_STATUS dp_tso_soc_attach(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; uint8_t i; @@ -4121,7 +4445,12 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc) num_desc = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); num_ext_desc = wlan_cfg_get_num_tx_ext_desc(soc->wlan_cfg_ctx); - if (num_pool > MAX_TXDESC_POOLS) + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s Tx Desc Alloc num_pool = %d, descs = %d", + __func__, num_pool, num_desc); + + if ((num_pool > MAX_TXDESC_POOLS) || + (num_desc > WLAN_CFG_NUM_TX_DESC_MAX)) goto fail; if (dp_tx_alloc_static_pools(soc, num_pool, num_desc)) @@ -4129,10 +4458,6 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc) dp_tx_flow_control_init(soc); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s Tx Desc Alloc num_pool = %d, descs = %d", - __func__, num_pool, num_desc); - /* Allocate extension tx descriptor pools */ for (i = 0; i < num_pool; i++) { if (dp_tx_ext_desc_pool_alloc(soc, i, num_ext_desc)) { @@ -4181,232 +4506,3 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc) dp_tx_soc_detach(soc); return QDF_STATUS_E_RESOURCES; } - -/* - * dp_tx_me_mem_free(): Function to free allocated memory in mcast enahncement - * pdev: pointer to DP PDEV structure - * seg_info_head: Pointer to the head of list - * - * return: void - */ -static void dp_tx_me_mem_free(struct dp_pdev *pdev, - struct dp_tx_seg_info_s *seg_info_head) -{ - struct dp_tx_me_buf_t *mc_uc_buf; - struct dp_tx_seg_info_s *seg_info_new = NULL; - qdf_nbuf_t nbuf = NULL; - uint64_t phy_addr; - - while (seg_info_head) { - nbuf = seg_info_head->nbuf; - mc_uc_buf = (struct dp_tx_me_buf_t *) - seg_info_head->frags[0].vaddr; - phy_addr = seg_info_head->frags[0].paddr_hi; - phy_addr = (phy_addr << 32) | seg_info_head->frags[0].paddr_lo; - qdf_mem_unmap_nbytes_single(pdev->soc->osdev, - phy_addr, - QDF_DMA_TO_DEVICE , QDF_MAC_ADDR_SIZE); - dp_tx_me_free_buf(pdev, mc_uc_buf); - qdf_nbuf_free(nbuf); - seg_info_new = seg_info_head; - seg_info_head = seg_info_head->next; - qdf_mem_free(seg_info_new); - } -} - -/** - * dp_tx_me_send_convert_ucast(): function to convert multicast to unicast - * @vdev: DP VDEV handle - * @nbuf: Multicast nbuf - * @newmac: Table of the clients to which packets have to be sent - * @new_mac_cnt: No of clients - * - * return: no of converted packets - */ -uint16_t -dp_tx_me_send_convert_ucast(struct cdp_vdev *vdev_handle, qdf_nbuf_t nbuf, - uint8_t newmac[][QDF_MAC_ADDR_SIZE], uint8_t new_mac_cnt) -{ - struct dp_vdev *vdev = (struct dp_vdev *) vdev_handle; - struct dp_pdev *pdev = vdev->pdev; - qdf_ether_header_t *eh; - uint8_t *data; - uint16_t len; - - /* reference to frame dst addr */ - uint8_t *dstmac; - /* copy of original frame src addr */ - uint8_t srcmac[QDF_MAC_ADDR_SIZE]; - - /* local index into newmac */ - uint8_t new_mac_idx = 0; - struct dp_tx_me_buf_t *mc_uc_buf; - qdf_nbuf_t nbuf_clone; - struct dp_tx_msdu_info_s msdu_info; - struct dp_tx_seg_info_s *seg_info_head = NULL; - struct dp_tx_seg_info_s *seg_info_tail = NULL; - struct dp_tx_seg_info_s *seg_info_new; - qdf_dma_addr_t paddr_data; - qdf_dma_addr_t paddr_mcbuf = 0; - uint8_t empty_entry_mac[QDF_MAC_ADDR_SIZE] = {0}; - QDF_STATUS status; - - qdf_mem_zero(&msdu_info, sizeof(msdu_info)); - - dp_tx_get_queue(vdev, nbuf, &msdu_info.tx_queue); - - eh = (qdf_ether_header_t *)nbuf; - qdf_mem_copy(srcmac, eh->ether_shost, QDF_MAC_ADDR_SIZE); - - len = qdf_nbuf_len(nbuf); - - data = qdf_nbuf_data(nbuf); - - status = qdf_nbuf_map(vdev->osdev, nbuf, - QDF_DMA_TO_DEVICE); - - if (status) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Mapping failure Error:%d", status); - DP_STATS_INC(vdev, tx_i.mcast_en.dropped_map_error, 1); - qdf_nbuf_free(nbuf); - return 1; - } - - paddr_data = qdf_nbuf_mapped_paddr_get(nbuf) + QDF_MAC_ADDR_SIZE; - - for (new_mac_idx = 0; new_mac_idx < new_mac_cnt; new_mac_idx++) { - dstmac = newmac[new_mac_idx]; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "added mac addr (%pM)", dstmac); - - /* Check for NULL Mac Address */ - if (!qdf_mem_cmp(dstmac, empty_entry_mac, QDF_MAC_ADDR_SIZE)) - continue; - - /* frame to self mac. skip */ - if (!qdf_mem_cmp(dstmac, srcmac, QDF_MAC_ADDR_SIZE)) - continue; - - /* - * TODO: optimize to avoid malloc in per-packet path - * For eg. seg_pool can be made part of vdev structure - */ - seg_info_new = qdf_mem_malloc(sizeof(*seg_info_new)); - - if (!seg_info_new) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "alloc failed"); - DP_STATS_INC(vdev, tx_i.mcast_en.fail_seg_alloc, 1); - goto fail_seg_alloc; - } - - mc_uc_buf = dp_tx_me_alloc_buf(pdev); - if (!mc_uc_buf) - goto fail_buf_alloc; - - /* - * TODO: Check if we need to clone the nbuf - * Or can we just use the reference for all cases - */ - if (new_mac_idx < (new_mac_cnt - 1)) { - nbuf_clone = qdf_nbuf_clone((qdf_nbuf_t)nbuf); - if (!nbuf_clone) { - DP_STATS_INC(vdev, tx_i.mcast_en.clone_fail, 1); - goto fail_clone; - } - } else { - /* - * Update the ref - * to account for frame sent without cloning - */ - qdf_nbuf_ref(nbuf); - nbuf_clone = nbuf; - } - - qdf_mem_copy(mc_uc_buf->data, dstmac, QDF_MAC_ADDR_SIZE); - - status = qdf_mem_map_nbytes_single(vdev->osdev, mc_uc_buf->data, - QDF_DMA_TO_DEVICE, QDF_MAC_ADDR_SIZE, - &paddr_mcbuf); - - if (status) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Mapping failure Error:%d", status); - DP_STATS_INC(vdev, tx_i.mcast_en.dropped_map_error, 1); - goto fail_map; - } - - seg_info_new->frags[0].vaddr = (uint8_t *)mc_uc_buf; - seg_info_new->frags[0].paddr_lo = (uint32_t) paddr_mcbuf; - seg_info_new->frags[0].paddr_hi = - (uint16_t)((uint64_t)paddr_mcbuf >> 32); - seg_info_new->frags[0].len = QDF_MAC_ADDR_SIZE; - - /*preparing data fragment*/ - seg_info_new->frags[1].vaddr = - qdf_nbuf_data(nbuf) + QDF_MAC_ADDR_SIZE; - seg_info_new->frags[1].paddr_lo = (uint32_t)paddr_data; - seg_info_new->frags[1].paddr_hi = - (uint16_t)(((uint64_t)paddr_data) >> 32); - seg_info_new->frags[1].len = len - QDF_MAC_ADDR_SIZE; - - seg_info_new->nbuf = nbuf_clone; - seg_info_new->frag_cnt = 2; - seg_info_new->total_len = len; - - seg_info_new->next = NULL; - - if (!seg_info_head) - seg_info_head = seg_info_new; - else - seg_info_tail->next = seg_info_new; - - seg_info_tail = seg_info_new; - } - - if (!seg_info_head) { - goto free_return; - } - - msdu_info.u.sg_info.curr_seg = seg_info_head; - msdu_info.num_seg = new_mac_cnt; - msdu_info.frm_type = dp_tx_frm_me; - - msdu_info.tid = HTT_INVALID_TID; - if (qdf_unlikely(vdev->mcast_enhancement_en > 0) && - qdf_unlikely(pdev->hmmc_tid_override_en)) - msdu_info.tid = pdev->hmmc_tid; - - DP_STATS_INC(vdev, tx_i.mcast_en.ucast, new_mac_cnt); - dp_tx_send_msdu_multiple(vdev, nbuf, &msdu_info); - - while (seg_info_head->next) { - seg_info_new = seg_info_head; - seg_info_head = seg_info_head->next; - qdf_mem_free(seg_info_new); - } - qdf_mem_free(seg_info_head); - - qdf_nbuf_unmap(pdev->soc->osdev, nbuf, QDF_DMA_TO_DEVICE); - qdf_nbuf_free(nbuf); - return new_mac_cnt; - -fail_map: - qdf_nbuf_free(nbuf_clone); - -fail_clone: - dp_tx_me_free_buf(pdev, mc_uc_buf); - -fail_buf_alloc: - qdf_mem_free(seg_info_new); - -fail_seg_alloc: - dp_tx_me_mem_free(pdev, seg_info_head); - -free_return: - qdf_nbuf_unmap(pdev->soc->osdev, nbuf, QDF_DMA_TO_DEVICE); - qdf_nbuf_free(nbuf); - return 1; -} - diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h index 494fc1bd251178b47bd290a7264a4595788d04df..570e780fb6a1ad044d41ae820e8dcd827fb7d2f9 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +36,8 @@ #define DP_TX_DESC_FLAG_ME 0x80 #define DP_TX_DESC_FLAG_TDLS_FRAME 0x100 +#define DP_TX_EXT_DESC_FLAG_METADATA_VALID 0x1 + #define DP_TX_FREE_SINGLE_BUF(soc, buf) \ do { \ qdf_nbuf_unmap(soc->osdev, buf, QDF_DMA_TO_DEVICE); \ @@ -43,6 +46,22 @@ do { \ #define OCB_HEADER_VERSION 1 +#ifdef TX_PER_PDEV_DESC_POOL +#ifdef QCA_LL_TX_FLOW_CONTROL_V2 +#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id) +#else /* QCA_LL_TX_FLOW_CONTROL_V2 */ +#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->pdev->pdev_id) +#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ + #define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id) +#else + #ifdef TX_PER_VDEV_DESC_POOL + #define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id) + #define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id) + #endif /* TX_PER_VDEV_DESC_POOL */ +#endif /* TX_PER_PDEV_DESC_POOL */ +#define DP_TX_QUEUE_MASK 0x3 +#define DP_TX_MSDU_INFO_META_DATA_DWORDS 9 + /** * struct dp_tx_frag_info_s * @vaddr: hlos vritual address for buffer @@ -133,7 +152,7 @@ struct dp_tx_msdu_info_s { struct qdf_tso_info_t tso_info; struct dp_tx_sg_info_s sg_info; } u; - uint32_t meta_data[7]; + uint32_t meta_data[DP_TX_MSDU_INFO_META_DATA_DWORDS]; uint8_t exception_fw; uint16_t ppdu_cookie; uint8_t is_tx_sniffer; @@ -155,7 +174,7 @@ QDF_STATUS dp_tx_soc_detach(struct dp_soc *soc); * Return: QDF_STATUS_E_FAILURE on failure or * QDF_STATUS_SUCCESS on success */ -QDF_STATUS dp_tso_soc_attach(void *txrx_soc); +QDF_STATUS dp_tso_soc_attach(struct cdp_soc_t *txrx_soc); /** * dp_tso_detach() - TSO Detach handler @@ -166,20 +185,46 @@ QDF_STATUS dp_tso_soc_attach(void *txrx_soc); * Return: QDF_STATUS_E_FAILURE on failure or * QDF_STATUS_SUCCESS on success */ -QDF_STATUS dp_tso_soc_detach(void *txrx_soc); +QDF_STATUS dp_tso_soc_detach(struct cdp_soc_t *txrx_soc); QDF_STATUS dp_tx_pdev_detach(struct dp_pdev *pdev); QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev); -qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf); -qdf_nbuf_t dp_tx_send_exception(void *data_vdev, qdf_nbuf_t nbuf, +qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf); + +qdf_nbuf_t dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t nbuf, struct cdp_tx_exception_metadata *tx_exc); -qdf_nbuf_t dp_tx_send_mesh(void *data_vdev, qdf_nbuf_t nbuf); +qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id, + qdf_nbuf_t nbuf); +qdf_nbuf_t +dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info, uint16_t peer_id, + struct cdp_tx_exception_metadata *tx_exc_metadata); +#if QDF_LOCK_STATS +noinline qdf_nbuf_t +dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info); +#else +qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info); +#endif #ifdef FEATURE_WLAN_TDLS -qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle, - enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); +/** + * dp_tx_non_std() - Allow the control-path SW to send data frames + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev + * @tx_spec: what non-standard handling to apply to the tx data frames + * @msdu_list: NULL-terminated list of tx MSDUs + * + * Return: NULL on success, + * nbuf when it fails to send + */ +qdf_nbuf_t dp_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); #endif +int dp_tx_frame_is_drop(struct dp_vdev *vdev, uint8_t *srcmac, uint8_t *dstmac); /** * dp_tx_comp_handler() - Tx completion handler @@ -196,7 +241,8 @@ qdf_nbuf_t dp_tx_non_std(struct cdp_vdev *vdev_handle, * Return: Number of TX completions processed */ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc, - void *hal_srng, uint8_t ring_id, uint32_t quota); + hal_ring_handle_t hal_srng, uint8_t ring_id, + uint32_t quota); QDF_STATUS dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf); @@ -208,15 +254,78 @@ static inline void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status) } #endif -#ifdef ATH_SUPPORT_IQUE -void dp_tx_me_exit(struct dp_pdev *pdev); -#else +#ifndef ATH_SUPPORT_IQUE static inline void dp_tx_me_exit(struct dp_pdev *pdev) { return; } #endif +#ifndef QCA_MULTIPASS_SUPPORT +static inline +bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info) +{ + return true; +} + +static inline +void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev) +{ +} + +#else +bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, + struct dp_tx_msdu_info_s *msdu_info); + +void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev); +#endif + +/** + * dp_tx_get_queue() - Returns Tx queue IDs to be used for this Tx frame + * @vdev: DP Virtual device handle + * @nbuf: Buffer pointer + * @queue: queue ids container for nbuf + * + * TX packet queue has 2 instances, software descriptors id and dma ring id + * Based on tx feature and hardware configuration queue id combination could be + * different. + * For example - + * With XPS enabled,all TX descriptor pools and dma ring are assigned per cpu id + * With no XPS,lock based resource protection, Descriptor pool ids are different + * for each vdev, dma ring id will be same as single pdev id + * + * Return: None + */ +#ifdef QCA_OL_TX_MULTIQ_SUPPORT +static inline void dp_tx_get_queue(struct dp_vdev *vdev, + qdf_nbuf_t nbuf, struct dp_tx_queue *queue) +{ + uint16_t queue_offset = qdf_nbuf_get_queue_mapping(nbuf) & + DP_TX_QUEUE_MASK; + + queue->desc_pool_id = queue_offset; + queue->ring_id = vdev->pdev->soc->tx_ring_map[queue_offset]; + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s, pool_id:%d ring_id: %d", + __func__, queue->desc_pool_id, queue->ring_id); +} +#else /* QCA_OL_TX_MULTIQ_SUPPORT */ +static inline void dp_tx_get_queue(struct dp_vdev *vdev, + qdf_nbuf_t nbuf, struct dp_tx_queue *queue) +{ + /* get flow id */ + queue->desc_pool_id = DP_TX_GET_DESC_POOL_ID(vdev); + queue->ring_id = DP_TX_GET_RING_ID(vdev); + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s, pool_id:%d ring_id: %d", + __func__, queue->desc_pool_id, queue->ring_id); +} +#endif #ifdef FEATURE_PERPKT_INFO QDF_STATUS dp_get_completion_indication_for_stack(struct dp_soc *soc, @@ -231,7 +340,7 @@ void dp_send_completion_to_stack(struct dp_soc *soc, struct dp_pdev *pdev, qdf_nbuf_t netbuf); #endif -void dp_iterate_update_peer_list(void *pdev_hdl); +void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl); #ifdef ATH_TX_PRI_OVERRIDE #define DP_TX_TID_OVERRIDE(_msdu_info, _nbuf) \ @@ -240,6 +349,10 @@ void dp_iterate_update_peer_list(void *pdev_hdl); #define DP_TX_TID_OVERRIDE(_msdu_info, _nbuf) #endif +void +dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc, + uint32_t buf_type); + /* TODO TX_FEATURE_NOT_YET */ static inline void dp_tx_comp_process_exception(struct dp_tx_desc_s *tx_desc) { @@ -247,6 +360,12 @@ static inline void dp_tx_comp_process_exception(struct dp_tx_desc_s *tx_desc) } /* TODO TX_FEATURE_NOT_YET */ +#ifndef WLAN_TX_PKT_CAPTURE_ENH +static inline +void dp_peer_set_tx_capture_enabled(struct dp_peer *peer_handle, bool value) +{ +} +#endif void dp_tx_desc_flush(struct dp_pdev *pdev, struct dp_vdev *vdev, bool force_free); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c index dc3e34eb60a627441b288794cf024a4cdd8bdb0f..0e0fdb6e04cd89c01234cc9ad2b6d547e72bed87 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c @@ -102,16 +102,15 @@ QDF_STATUS dp_tx_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, desc_size = DP_TX_DESC_SIZE(sizeof(*tx_desc_elem)); tx_desc_pool->elem_size = desc_size; if (!dp_is_soc_reinit(soc)) - qdf_mem_multi_pages_alloc(soc->osdev, - &tx_desc_pool->desc_pages, - desc_size, num_elem, - 0, true); + dp_desc_multi_pages_mem_alloc(soc, DP_TX_DESC_TYPE, + &tx_desc_pool->desc_pages, + desc_size, num_elem, + 0, true); if (!tx_desc_pool->desc_pages.num_pages) { dp_err("Multi page alloc fail, tx desc"); goto fail_exit; } - num_desc_per_page = tx_desc_pool->desc_pages.num_element_per_page; tx_desc_pool->freelist = (struct dp_tx_desc_s *) @@ -144,8 +143,8 @@ QDF_STATUS dp_tx_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, return QDF_STATUS_SUCCESS; free_tx_desc: - qdf_mem_multi_pages_free(soc->osdev, - &tx_desc_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_DESC_TYPE, + &tx_desc_pool->desc_pages, 0, true); fail_exit: return QDF_STATUS_E_FAULT; @@ -164,8 +163,9 @@ QDF_STATUS dp_tx_desc_pool_free(struct dp_soc *soc, uint8_t pool_id) struct dp_tx_desc_pool_s *tx_desc_pool = &((soc)->tx_desc[(pool_id)]); - qdf_mem_multi_pages_free(soc->osdev, - &tx_desc_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_DESC_TYPE, + &tx_desc_pool->desc_pages, + 0, true); TX_DESC_LOCK_DESTROY(&tx_desc_pool->lock); TX_DESC_POOL_MEMBER_CLEAN(tx_desc_pool); return QDF_STATUS_SUCCESS; @@ -194,12 +194,13 @@ QDF_STATUS dp_tx_ext_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, soc->tx_ext_desc[pool_id].elem_count = num_elem; memctx = qdf_get_dma_mem_context((&soc->tx_ext_desc[pool_id]), memctx); if (!dp_is_soc_reinit(soc)) { - qdf_mem_multi_pages_alloc(soc->osdev, - &soc->tx_ext_desc[pool_id]. - desc_pages, - soc->tx_ext_desc[pool_id].elem_size, - soc->tx_ext_desc[pool_id].elem_count, - memctx, false); + dp_desc_multi_pages_mem_alloc(soc, + DP_TX_EXT_DESC_TYPE, + &soc->tx_ext_desc[pool_id]. + desc_pages, + soc->tx_ext_desc[pool_id].elem_size, + soc->tx_ext_desc[pool_id].elem_count, + memctx, false); } if (!soc->tx_ext_desc[pool_id].desc_pages.num_pages) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -218,14 +219,12 @@ QDF_STATUS dp_tx_ext_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, soc->tx_ext_desc[pool_id].link_elem_size = sizeof(struct dp_tx_ext_desc_elem_s); if (!dp_is_soc_reinit(soc)) { - qdf_mem_multi_pages_alloc(soc->osdev, - &soc->tx_ext_desc[pool_id]. - desc_link_pages, - soc->tx_ext_desc[pool_id]. - link_elem_size, - soc->tx_ext_desc[pool_id]. - elem_count, - 0, true); + dp_desc_multi_pages_mem_alloc(soc, + DP_TX_EXT_DESC_LINK_TYPE, + &soc->tx_ext_desc[pool_id].desc_link_pages, + soc->tx_ext_desc[pool_id].link_elem_size, + soc->tx_ext_desc[pool_id].elem_count, + 0, true); } if (!soc->tx_ext_desc[pool_id].desc_link_pages.num_pages) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -285,11 +284,11 @@ QDF_STATUS dp_tx_ext_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, return QDF_STATUS_SUCCESS; free_ext_link_desc_page: - qdf_mem_multi_pages_free(soc->osdev, + dp_desc_multi_pages_mem_free(soc, DP_TX_EXT_DESC_LINK_TYPE, &soc->tx_ext_desc[pool_id].desc_link_pages, 0, true); free_ext_desc_page: - qdf_mem_multi_pages_free(soc->osdev, + dp_desc_multi_pages_mem_free(soc, DP_TX_EXT_DESC_TYPE, &soc->tx_ext_desc[pool_id].desc_pages, qdf_get_dma_mem_context((&soc->tx_ext_desc[pool_id]), memctx), false); @@ -308,10 +307,10 @@ QDF_STATUS dp_tx_ext_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, */ QDF_STATUS dp_tx_ext_desc_pool_free(struct dp_soc *soc, uint8_t pool_id) { - qdf_mem_multi_pages_free(soc->osdev, + dp_desc_multi_pages_mem_free(soc, DP_TX_EXT_DESC_LINK_TYPE, &soc->tx_ext_desc[pool_id].desc_link_pages, 0, true); - qdf_mem_multi_pages_free(soc->osdev, + dp_desc_multi_pages_mem_free(soc, DP_TX_EXT_DESC_TYPE, &soc->tx_ext_desc[pool_id].desc_pages, qdf_get_dma_mem_context((&soc->tx_ext_desc[pool_id]), memctx), false); @@ -339,10 +338,11 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, tso_desc_pool->num_free = 0; desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_seg_elem_t)); if (!dp_is_soc_reinit(soc)) - qdf_mem_multi_pages_alloc(soc->osdev, - &tso_desc_pool->desc_pages, - desc_size, - num_elem, 0, true); + dp_desc_multi_pages_mem_alloc(soc, + DP_TX_TSO_DESC_TYPE, + &tso_desc_pool->desc_pages, + desc_size, + num_elem, 0, true); if (!tso_desc_pool->desc_pages.num_pages) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -369,8 +369,8 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, return QDF_STATUS_SUCCESS; free_tso_desc: - qdf_mem_multi_pages_free(soc->osdev, - &tso_desc_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_DESC_TYPE, + &tso_desc_pool->desc_pages, 0, true); return QDF_STATUS_E_FAULT; } @@ -390,8 +390,8 @@ void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t pool_id) qdf_spin_lock_bh(&tso_desc_pool->lock); - qdf_mem_multi_pages_free(soc->osdev, - &tso_desc_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_DESC_TYPE, + &tso_desc_pool->desc_pages, 0, true); tso_desc_pool->freelist = NULL; tso_desc_pool->num_free = 0; tso_desc_pool->pool_size = 0; @@ -417,10 +417,11 @@ QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t pool_id, tso_num_seg_pool->num_free = 0; desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_num_seg_elem_t)); if (!dp_is_soc_reinit(soc)) - qdf_mem_multi_pages_alloc(soc->osdev, - &tso_num_seg_pool->desc_pages, - desc_size, - num_elem, 0, true); + dp_desc_multi_pages_mem_alloc(soc, + DP_TX_TSO_NUM_SEG_TYPE, + &tso_num_seg_pool->desc_pages, + desc_size, + num_elem, 0, true); if (!tso_num_seg_pool->desc_pages.num_pages) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, FL("Alloc Failed %pK pool_id %d"), @@ -447,8 +448,8 @@ QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t pool_id, return QDF_STATUS_SUCCESS; fail: - qdf_mem_multi_pages_free(soc->osdev, - &tso_num_seg_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_NUM_SEG_TYPE, + &tso_num_seg_pool->desc_pages, 0, true); return QDF_STATUS_E_NOMEM; } @@ -468,8 +469,8 @@ void dp_tx_tso_num_seg_pool_free(struct dp_soc *soc, uint8_t pool_id) tso_num_seg_pool = &soc->tx_tso_num_seg[pool_id]; qdf_spin_lock_bh(&tso_num_seg_pool->lock); - qdf_mem_multi_pages_free(soc->osdev, - &tso_num_seg_pool->desc_pages, 0, true); + dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_NUM_SEG_TYPE, + &tso_num_seg_pool->desc_pages, 0, true); tso_num_seg_pool->freelist = NULL; tso_num_seg_pool->num_free = 0; tso_num_seg_pool->num_seg_pool_size = 0; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h index c73b828c67abfaac6dc34b7e7e1cf2802514c180..07ed3741f60ff9956b311559fb56711875385381 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h @@ -23,20 +23,6 @@ #include "dp_tx.h" #include "dp_internal.h" -#ifdef TX_PER_PDEV_DESC_POOL -#ifdef QCA_LL_TX_FLOW_CONTROL_V2 -#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id) -#else /* QCA_LL_TX_FLOW_CONTROL_V2 */ -#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->pdev->pdev_id) -#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ - #define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id) -#else - #ifdef TX_PER_VDEV_DESC_POOL - #define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id) - #define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id) - #endif /* TX_PER_VDEV_DESC_POOL */ -#endif /* TX_PER_PDEV_DESC_POOL */ - /** * 21 bits cookie * 2 bits pool id 0 ~ 3, @@ -110,9 +96,9 @@ void dp_tx_flow_control_deinit(struct dp_soc *); QDF_STATUS dp_txrx_register_pause_cb(struct cdp_soc_t *soc, tx_pause_callback pause_cb); -QDF_STATUS dp_tx_flow_pool_map(struct cdp_soc_t *soc, struct cdp_pdev *pdev, - uint8_t vdev_id); -void dp_tx_flow_pool_unmap(struct cdp_soc_t *soc, struct cdp_pdev *pdev, +QDF_STATUS dp_tx_flow_pool_map(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id); +void dp_tx_flow_pool_unmap(struct cdp_soc_t *handle, uint8_t pdev_id, uint8_t vdev_id); void dp_tx_clear_flow_pool_stats(struct dp_soc *soc); struct dp_tx_desc_pool_s *dp_tx_create_flow_pool(struct dp_soc *soc, @@ -505,15 +491,17 @@ dp_tx_desc_free(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, #endif /* QCA_AC_BASED_FLOW_CONTROL */ static inline bool -dp_tx_desc_thresh_reached(struct cdp_vdev *vdev) +dp_tx_desc_thresh_reached(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct dp_vdev *dp_vdev = (struct dp_vdev *)vdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, + vdev_id); struct dp_tx_desc_pool_s *pool; if (!vdev) return false; - pool = dp_vdev->pool; + pool = vdev->pool; return dp_tx_is_threshold_reached(pool, pool->avail_desc); } @@ -817,7 +805,7 @@ static inline void dp_tx_ext_desc_free_multiple(struct dp_soc *soc, uint8_t freed = num_free; /* caller should always guarantee atleast list of num_free nodes */ - qdf_assert_always(head); + qdf_assert_always(elem); head = elem; c_elem = head; diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_flow_control.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_flow_control.c index 7e674a0c2f24b4b92de59b7b291fb013b2cde141..4e5a5a620dc4090e90aa528232156826b72fc2d9 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_flow_control.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_flow_control.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -90,8 +90,8 @@ dp_tx_flow_pool_reattach(struct dp_tx_desc_pool_s *pool) if (pool->avail_desc > pool->start_th[DP_TH_BE_BK]) pool->status = FLOW_POOL_ACTIVE_UNPAUSED; - if (pool->avail_desc <= pool->start_th[DP_TH_BE_BK] && - pool->avail_desc > pool->start_th[DP_TH_VI]) + else if (pool->avail_desc <= pool->start_th[DP_TH_BE_BK] && + pool->avail_desc > pool->start_th[DP_TH_VI]) pool->status = FLOW_POOL_BE_BK_PAUSED; else if (pool->avail_desc <= pool->start_th[DP_TH_VI] && pool->avail_desc > pool->start_th[DP_TH_VO]) @@ -173,9 +173,9 @@ dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool) * * Return: none */ -void dp_tx_dump_flow_pool_info(void *ctx) +void dp_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { - struct dp_soc *soc = ctx; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_txrx_pool_stats *pool_stats = &soc->pool_stats; struct dp_tx_desc_pool_s *pool = NULL; struct dp_tx_desc_pool_s tmp_pool; @@ -364,8 +364,7 @@ static void dp_tx_flow_pool_vdev_map(struct dp_pdev *pdev, struct dp_vdev *vdev; struct dp_soc *soc = pdev->soc; - vdev = (struct dp_vdev *)cdp_get_vdev_from_vdev_id((void *)soc, - (struct cdp_pdev *)pdev, vdev_id); + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "%s: invalid vdev_id %d", @@ -394,8 +393,7 @@ static void dp_tx_flow_pool_vdev_unmap(struct dp_pdev *pdev, struct dp_vdev *vdev; struct dp_soc *soc = pdev->soc; - vdev = (struct dp_vdev *)cdp_get_vdev_from_vdev_id((void *)soc, - (struct cdp_pdev *)pdev, vdev_id); + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "%s: invalid vdev_id %d", @@ -523,12 +521,12 @@ void dp_tx_flow_control_init(struct dp_soc *soc) } /** - * dp_tx_flow_control_deinit() - Deregister fw based tx flow control + * dp_tx_desc_pool_dealloc() - De-allocate tx desc pool * @tx_desc_pool: Handle to flow_pool * * Return: none */ -void dp_tx_flow_control_deinit(struct dp_soc *soc) +static inline void dp_tx_desc_pool_dealloc(struct dp_soc *soc) { struct dp_tx_desc_pool_s *tx_desc_pool; int i; @@ -538,11 +536,20 @@ void dp_tx_flow_control_deinit(struct dp_soc *soc) if (!tx_desc_pool->desc_pages.num_pages) continue; - if (dp_tx_desc_pool_free(soc, i)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "%s Tx Desc Pool Free failed", __func__); - } + if (dp_tx_desc_pool_free(soc, i) != QDF_STATUS_SUCCESS) + dp_err("Tx Desc Pool:%d Free failed", i); } +} + +/** + * dp_tx_flow_control_deinit() - Deregister fw based tx flow control + * @tx_desc_pool: Handle to flow_pool + * + * Return: none + */ +void dp_tx_flow_control_deinit(struct dp_soc *soc) +{ + dp_tx_desc_pool_dealloc(soc); qdf_spinlock_destroy(&soc->flow_pool_array_lock); } @@ -569,19 +576,35 @@ QDF_STATUS dp_txrx_register_pause_cb(struct cdp_soc_t *handle, return QDF_STATUS_SUCCESS; } -QDF_STATUS dp_tx_flow_pool_map(struct cdp_soc_t *handle, struct cdp_pdev *pdev, - uint8_t vdev_id) +QDF_STATUS dp_tx_flow_pool_map(struct cdp_soc_t *handle, uint8_t pdev_id, + uint8_t vdev_id) { - struct dp_soc *soc = (struct dp_soc *)handle; - int tx_ring_size = wlan_cfg_tx_ring_size(soc->wlan_cfg_ctx); + struct dp_soc *soc = cdp_soc_t_to_dp_soc(handle); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + int tx_ring_size = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx); + + if (!pdev) { + dp_err("pdev is NULL"); + return QDF_STATUS_E_INVAL; + } - return (dp_tx_flow_pool_map_handler((struct dp_pdev *)pdev, vdev_id, - FLOW_TYPE_VDEV, vdev_id, tx_ring_size)); + return dp_tx_flow_pool_map_handler(pdev, vdev_id, FLOW_TYPE_VDEV, + vdev_id, tx_ring_size); } -void dp_tx_flow_pool_unmap(struct cdp_soc_t *soc, struct cdp_pdev *pdev, +void dp_tx_flow_pool_unmap(struct cdp_soc_t *handle, uint8_t pdev_id, uint8_t vdev_id) { - return(dp_tx_flow_pool_unmap_handler((struct dp_pdev *)pdev, vdev_id, - FLOW_TYPE_VDEV, vdev_id)); + struct dp_soc *soc = cdp_soc_t_to_dp_soc(handle); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) { + dp_err("pdev is NULL"); + return; + } + + return dp_tx_flow_pool_unmap_handler(pdev, vdev_id, + FLOW_TYPE_VDEV, vdev_id); } diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_me.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_me.c deleted file mode 100644 index 8637ece92d91306e7b3983eec8ce33e8ed89c62d..0000000000000000000000000000000000000000 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_me.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. - * - * 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. - */ - -#include "hal_hw_headers.h" -#include "dp_types.h" -#include "qdf_nbuf.h" -#include "qdf_atomic.h" -#include "qdf_types.h" -#include "dp_tx.h" -#include "dp_tx_desc.h" -#include "dp_internal.h" - -#ifdef ATH_SUPPORT_IQUE -#define MAX_ME_BUF_CHUNK 1424 -#define ME_US_TO_SEC(_x) ((_x)/(1000 * 1000)) -#define ME_CLEAN_WAIT_TIMEOUT (200000) /*200ms*/ -#define ME_CLEAN_WAIT_COUNT 400 - -/** - * dp_tx_me_init():Initialize ME buffer ppol - * @pdev: DP PDEV handle - * - * Return:0 on Succes 1 on failure - */ -static inline uint16_t -dp_tx_me_init(struct dp_pdev *pdev) -{ - - uint16_t i, mc_uc_buf_len, num_pool_elems; - uint32_t pool_size; - - struct dp_tx_me_buf_t *p; - - mc_uc_buf_len = sizeof(struct dp_tx_me_buf_t); - - num_pool_elems = MAX_ME_BUF_CHUNK; - /* Add flow control buffer count */ - pool_size = (mc_uc_buf_len) * num_pool_elems; - pdev->me_buf.size = mc_uc_buf_len; - if (!pdev->me_buf.vaddr) { - qdf_spin_lock_bh(&pdev->tx_mutex); - pdev->me_buf.vaddr = qdf_mem_malloc(pool_size); - if (!pdev->me_buf.vaddr) { - qdf_spin_unlock_bh(&pdev->tx_mutex); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "Error allocating memory pool"); - return 1; - } - pdev->me_buf.buf_in_use = 0; - pdev->me_buf.freelist = - (struct dp_tx_me_buf_t *) pdev->me_buf.vaddr; - /* - * me_buf looks like this - * |=======+==========================| - * | ptr | Dst MAC | - * |=======+==========================| - */ - p = pdev->me_buf.freelist; - for (i = 0; i < num_pool_elems-1; i++) { - p->next = (struct dp_tx_me_buf_t *) - ((char *)p + pdev->me_buf.size); - p = p->next; - } - p->next = NULL; - qdf_spin_unlock_bh(&pdev->tx_mutex); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "ME Pool successfully initialized vaddr - %x \ - paddr - %x\n num_elems = %d buf_size - %d" - "pool_size = %d", - pdev->me_buf.vaddr, - (unsigned int)pdev->me_buf.paddr, - (unsigned int)num_pool_elems, - (unsigned int)pdev->me_buf.size, - (unsigned int)pool_size); - } else { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "ME Already Enabled!!"); - } - return 0; -} - -/** - * dp_tx_me_alloc_descriptor():Allocate ME descriptor - * @pdev_handle: DP PDEV handle - * - * Return:void - */ -void -dp_tx_me_alloc_descriptor(struct cdp_pdev *pdev_handle) -{ - struct dp_pdev *pdev = (struct dp_pdev *) pdev_handle; - if (qdf_atomic_read(&pdev->mc_num_vap_attached) == 0) { - dp_tx_me_init(pdev); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - FL("Enable MCAST_TO_UCAST ")); - } - qdf_atomic_inc(&pdev->mc_num_vap_attached); -} - -/** - * dp_tx_me_exit():Free memory and other cleanup required for - * multicast unicast conversion - * @pdev - DP_PDEV handle - * - * Return:void - */ -void -dp_tx_me_exit(struct dp_pdev *pdev) -{ - /* Add flow control buffer count */ - uint32_t wait_time = ME_US_TO_SEC(ME_CLEAN_WAIT_TIMEOUT * - ME_CLEAN_WAIT_COUNT); - - if (pdev->me_buf.vaddr) { - uint16_t wait_cnt = 0; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "Disabling Mcastenhance" - "This may take some time"); - qdf_spin_lock_bh(&pdev->tx_mutex); - while ((pdev->me_buf.buf_in_use > 0) && - (wait_cnt < ME_CLEAN_WAIT_COUNT)) { - qdf_spin_unlock_bh(&pdev->tx_mutex); - OS_SLEEP(ME_CLEAN_WAIT_TIMEOUT); - wait_cnt++; - qdf_spin_lock_bh(&pdev->tx_mutex); - } - if (pdev->me_buf.buf_in_use > 0) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "Tx-comp pending for %d " - "ME frames after waiting %ds!!", - pdev->me_buf.buf_in_use, wait_time); - qdf_assert_always(0); - } - - qdf_mem_free(pdev->me_buf.vaddr); - pdev->me_buf.vaddr = NULL; - pdev->me_buf.freelist = NULL; - qdf_spin_unlock_bh(&pdev->tx_mutex); - } else { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "ME Already Disabled !!!"); - } -} - -/** - * dp_tx_me_free_descriptor():free ME descriptor - * @pdev_handle:DP_PDEV handle - * - * Return:void - */ -void -dp_tx_me_free_descriptor(struct cdp_pdev *pdev_handle) -{ - struct dp_pdev *pdev = (struct dp_pdev *) pdev_handle; - qdf_atomic_dec(&pdev->mc_num_vap_attached); - if (atomic_read(&pdev->mc_num_vap_attached) == 0) { - dp_tx_me_exit(pdev); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "Disable MCAST_TO_UCAST"); - } -} - -/** - * dp_tx_prepare_send_me(): Call to the umac to get the list of clients - * @vdev: DP VDEV handle - * @nbuf: Multicast buffer - * - * Return: no of packets transmitted - */ -QDF_STATUS -dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf) -{ - if (vdev->me_convert) { - if (vdev->me_convert(vdev->osif_vdev, nbuf) > 0) - return QDF_STATUS_SUCCESS; - } - - return QDF_STATUS_E_FAILURE; -} - -#endif diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h index 363e98087873f3e590ff03215d4653befc1c9017..cefa475982f5e75fe71b747188df62ac416e14bb 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,10 +31,10 @@ #include #include -#ifdef CONFIG_MCL +#ifdef DP_MOB_DEFS #include -#include /* WDI subscriber event list */ #endif +#include /* WDI subscriber event list */ #include "hal_hw_headers.h" #include @@ -43,6 +44,7 @@ #include #include #include "hal_rx.h" +//#include "hal_rx_flow.h" #define MAX_BW 7 #define MAX_RETRIES 4 @@ -71,13 +73,19 @@ #define MAX_MON_LINK_DESC_BANKS 2 #define DP_VDEV_ALL 0xff -#if defined(CONFIG_MCL) +#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) #define MAX_PDEV_CNT 1 #else #define MAX_PDEV_CNT 3 #endif -#define MAX_LINK_DESC_BANKS 8 +/* Max no. of VDEV per PSOC */ +#ifdef WLAN_PSOC_MAX_VDEVS +#define MAX_VDEV_CNT WLAN_PSOC_MAX_VDEVS +#else +#define MAX_VDEV_CNT 51 +#endif + #define MAX_TXDESC_POOLS 4 #define MAX_RXDESC_POOLS 4 #define MAX_REO_DEST_RINGS 4 @@ -87,6 +95,13 @@ #define DP_MAX_IRQ_PER_CONTEXT 12 #define DEFAULT_HW_PEER_ID 0xffff +#define WBM_INT_ERROR_ALL 0 +#define WBM_INT_ERROR_REO_NULL_BUFFER 1 +#define WBM_INT_ERROR_REO_NULL_LINK_DESC 2 +#define WBM_INT_ERROR_REO_NULL_MSDU_BUFF 3 +#define WBM_INT_ERROR_REO_BUFF_REAPED 4 +#define MAX_WBM_INT_ERROR_REASONS 5 + #define MAX_TX_HW_QUEUES MAX_TCL_DATA_RINGS /* Maximum retries for Delba per tid per peer */ #define DP_MAX_DELBA_RETRY 3 @@ -96,13 +111,11 @@ #define REO_CMD_EVENT_HIST_MAX 64 -#ifndef REMOVE_PKT_LOG enum rx_pktlog_mode { DP_RX_PKTLOG_DISABLED = 0, DP_RX_PKTLOG_FULL, DP_RX_PKTLOG_LITE, }; -#endif struct msdu_list { qdf_nbuf_t head; @@ -118,6 +131,8 @@ struct dp_soc; union dp_rx_desc_list_elem_t; struct cdp_peer_rate_stats_ctx; struct cdp_soc_rate_stats_ctx; +struct dp_rx_fst; +struct dp_mon_filter; #define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \ TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem) @@ -184,12 +199,12 @@ enum dp_fl_ctrl_threshold { /** * enum dp_intr_mode - * @DP_INTR_LEGACY: Legacy/Line interrupts, for WIN - * @DP_INTR_MSI: MSI interrupts, for MCL + * @DP_INTR_INTEGRATED: Line interrupts + * @DP_INTR_MSI: MSI interrupts * @DP_INTR_POLL: Polling */ enum dp_intr_mode { - DP_INTR_LEGACY = 0, + DP_INTR_INTEGRATED = 0, DP_INTR_MSI, DP_INTR_POLL, }; @@ -267,6 +282,42 @@ enum dp_cpu_ring_map_types { DP_NSS_CPU_RING_MAP_MAX }; +/** + * enum dp_ctxt - context type + * @DP_PDEV_TYPE: PDEV context + * @DP_RX_RING_HIST_TYPE: Datapath rx ring history + * @DP_RX_ERR_RING_HIST_TYPE: Datapath rx error ring history + * @DP_RX_REINJECT_RING_HIST_TYPE: Datapath reinject ring history + */ +enum dp_ctxt_type { + DP_PDEV_TYPE, + DP_RX_RING_HIST_TYPE, + DP_RX_ERR_RING_HIST_TYPE, + DP_RX_REINJECT_RING_HIST_TYPE, +}; + +/** + * enum dp_desc_type - source type for multiple pages allocation + * @DP_TX_DESC_TYPE: DP SW TX descriptor + * @DP_TX_EXT_DESC_TYPE: DP TX msdu extension descriptor + * @DP_TX_EXT_DESC_LINK_TYPE: DP link descriptor for msdu ext_desc + * @DP_TX_TSO_DESC_TYPE: DP TX TSO descriptor + * @DP_TX_TSO_NUM_SEG_TYPE: DP TX number of segments + * @DP_RX_DESC_BUF_TYPE: DP RX SW descriptor + * @DP_RX_DESC_STATUS_TYPE: DP RX SW descriptor for monitor status + * @DP_HW_LINK_DESC_TYPE: DP HW link descriptor + */ +enum dp_desc_type { + DP_TX_DESC_TYPE, + DP_TX_EXT_DESC_TYPE, + DP_TX_EXT_DESC_LINK_TYPE, + DP_TX_TSO_DESC_TYPE, + DP_TX_TSO_NUM_SEG_TYPE, + DP_RX_DESC_BUF_TYPE, + DP_RX_DESC_STATUS_TYPE, + DP_HW_LINK_DESC_TYPE, +}; + /** * struct rx_desc_pool * @pool_size: number of RX descriptor in the pool @@ -276,6 +327,9 @@ enum dp_cpu_ring_map_types { * @freelist: pointer to free RX descriptor link list * @lock: Protection for the RX descriptor pool * @owner: owner for nbuf + * @buf_size: Buffer size + * @buf_alignment: Buffer alignment + * @desc_type: type of desc this pool serves */ struct rx_desc_pool { uint32_t pool_size; @@ -288,6 +342,9 @@ struct rx_desc_pool { union dp_rx_desc_list_elem_t *freelist; qdf_spinlock_t lock; uint8_t owner; + uint16_t buf_size; + uint8_t buf_alignment; + enum dp_desc_type desc_type; }; /** @@ -295,11 +352,13 @@ struct rx_desc_pool { * @next: next extension descriptor pointer * @vaddr: hlos virtual address pointer * @paddr: physical address pointer for descriptor + * @flags: mark features for extension descriptor */ struct dp_tx_ext_desc_elem_s { struct dp_tx_ext_desc_elem_s *next; void *vaddr; qdf_dma_addr_t paddr; + uint16_t flags; }; /** @@ -476,13 +535,16 @@ struct dp_txrx_pool_stats { }; struct dp_srng { - void *hal_srng; + hal_ring_handle_t hal_srng; void *base_vaddr_unaligned; qdf_dma_addr_t base_paddr_unaligned; uint32_t alloc_size; uint8_t cached; int irq; uint32_t num_entries; +#ifdef DP_MEM_PRE_ALLOC + uint8_t is_mem_prealloc; +#endif }; struct dp_rx_reorder_array_elem { @@ -525,6 +587,7 @@ struct dp_rx_tid { uint8_t pn_size; /* REO TID queue descriptors */ void *hw_qdesc_vaddr_unaligned; + void *hw_qdesc_vaddr_aligned; qdf_dma_addr_t hw_qdesc_paddr_unaligned; qdf_dma_addr_t hw_qdesc_paddr; uint32_t hw_qdesc_alloc_size; @@ -547,7 +610,7 @@ struct dp_rx_tid { TAILQ_ENTRY(dp_rx_tid) defrag_waitlist_elem; /* Store dst desc for reinjection */ - void *dst_ring_desc; + hal_ring_desc_t dst_ring_desc; struct dp_rx_desc *head_frag_desc; /* rx_tid lock */ @@ -557,6 +620,9 @@ struct dp_rx_tid { uint32_t curr_seq_num; uint32_t curr_frag_num; + /* head PN number */ + uint64_t pn128[2]; + uint32_t defrag_timeout_ms; uint16_t dialogtoken; uint16_t statuscode; @@ -581,7 +647,6 @@ struct dp_rx_tid { /* Coex Override preserved windows size 1 based */ uint16_t rx_ba_win_size_override; - }; /** @@ -642,6 +707,7 @@ struct reo_desc_list_node { unsigned long free_ts; struct dp_rx_tid rx_tid; bool resend_update_reo_cmd; + uint32_t pending_ext_desc_size; }; #ifdef WLAN_FEATURE_DP_EVENT_HISTORY @@ -674,6 +740,7 @@ struct dp_soc_stats { uint32_t added; uint32_t deleted; uint32_t aged_out; + uint32_t map_err; } ast; /* SOC level TX stats */ @@ -689,7 +756,7 @@ struct dp_soc_stats { /* tx completion release_src != TQM or FW */ uint32_t invalid_release_source; /* tx completion wbm_internal_error */ - uint32_t wbm_internal_error; + uint32_t wbm_internal_error[MAX_WBM_INT_ERROR_REASONS]; /* tx completion non_wbm_internal_error */ uint32_t non_wbm_internal_err; /* TX Comp loop packet limit hit */ @@ -709,6 +776,8 @@ struct dp_soc_stats { uint32_t rx_frag_wait; /* Fragments dropped due to errors */ uint32_t rx_frag_err; + /* Fragments received OOR causing sequence num mismatch */ + uint32_t rx_frag_oor; /* Fragments dropped due to len errors in skb */ uint32_t rx_frag_err_len_error; /* Fragments dropped due to no peer found */ @@ -723,6 +792,8 @@ struct dp_soc_stats { uint32_t near_full; /* Break ring reaping as not all scattered msdu received */ uint32_t msdu_scatter_wait_break; + /* Number of bar frames received */ + uint32_t bar_frame; struct { /* Invalid RBM error count */ @@ -770,6 +841,10 @@ struct dp_soc_stats { uint32_t reo_cmd_send_drain; /* RX msdu drop count due to scatter */ uint32_t scatter_msdu; + /* RX msdu drop count due to invalid cookie */ + uint32_t invalid_cookie; + /* Count of stale cookie read in RX path */ + uint32_t stale_cookie; /* Delba sent count due to RX 2k jump */ uint32_t rx_2k_jump_delba_sent; /* RX 2k jump msdu indicated to stack count */ @@ -784,6 +859,24 @@ struct dp_soc_stats { uint32_t reo_err_oor_sg_count; /* RX msdu rejected count on delivery to vdev stack_fn*/ uint32_t rejected; + /* Incorrect msdu count in MPDU desc info */ + uint32_t msdu_count_mismatch; + /* RX raw frame dropped count */ + uint32_t raw_frm_drop; + /* Stale link desc cookie count*/ + uint32_t invalid_link_cookie; + /* Nbuf sanity failure */ + uint32_t nbuf_sanity_fail; + /* Duplicate link desc refilled */ + uint32_t dup_refill_link_desc; + /* EAPOL drop count in intrabss scenario */ + uint32_t intrabss_eapol_drop; + /* Non Eapol pkt drop cnt due to peer not authorized */ + uint32_t peer_unauth_rx_pkt_drop; + /* MSDU len err count */ + uint32_t msdu_len_err; + /* Rx invalid tid count */ + uint32_t rx_invalid_tid_err; } err; /* packet count per core - per ring */ @@ -859,10 +952,8 @@ struct dp_ast_entry { struct dp_peer *peer; bool next_hop; bool is_active; - bool is_bss; bool is_mapped; uint8_t pdev_id; - uint8_t vdev_id; uint16_t ast_hash_value; qdf_atomic_t ref_cnt; enum cdp_txrx_ast_entry_type type; @@ -888,6 +979,69 @@ struct htt_t2h_stats { uint32_t num_stats; }; +/* + * The logic for get current index of these history is dependent on this + * value being power of 2. + */ +#define DP_RX_HIST_MAX 2048 +#define DP_RX_ERR_HIST_MAX 4096 +#define DP_RX_REINJECT_HIST_MAX 1024 + +QDF_COMPILE_TIME_ASSERT(rx_history_size, + (DP_RX_HIST_MAX & + (DP_RX_HIST_MAX - 1)) == 0); +QDF_COMPILE_TIME_ASSERT(rx_err_history_size, + (DP_RX_ERR_HIST_MAX & + (DP_RX_ERR_HIST_MAX - 1)) == 0); +QDF_COMPILE_TIME_ASSERT(rx_reinject_history_size, + (DP_RX_REINJECT_HIST_MAX & + (DP_RX_REINJECT_HIST_MAX - 1)) == 0); + +/** + * struct dp_buf_info_record - ring buffer info + * @hbi: HW ring buffer info + * @timestamp: timestamp when this entry was recorded + */ +struct dp_buf_info_record { + struct hal_buf_info hbi; + uint64_t timestamp; +}; + +/* struct dp_rx_history - rx ring hisotry + * @index: Index where the last entry is written + * @entry: history entries + */ +struct dp_rx_history { + qdf_atomic_t index; + struct dp_buf_info_record entry[DP_RX_HIST_MAX]; +}; + +/* struct dp_rx_err_history - rx err ring hisotry + * @index: Index where the last entry is written + * @entry: history entries + */ +struct dp_rx_err_history { + qdf_atomic_t index; + struct dp_buf_info_record entry[DP_RX_ERR_HIST_MAX]; +}; + +/* struct dp_rx_reinject_history - rx reinject ring hisotry + * @index: Index where the last entry is written + * @entry: history entries + */ +struct dp_rx_reinject_history { + qdf_atomic_t index; + struct dp_buf_info_record entry[DP_RX_REINJECT_HIST_MAX]; +}; + +/* structure to record recent operation related variable */ +struct dp_last_op_info { + /* last link desc buf info through WBM release ring */ + struct hal_buf_info wbm_rel_link_desc; + /* last link desc buf info through REO reinject ring */ + struct hal_buf_info reo_reinject_link_desc; +}; + /* SOC level structure for data path */ struct dp_soc { /** @@ -898,7 +1052,7 @@ struct dp_soc { struct cdp_soc_t cdp_soc; /* SoC Obj */ - void *ctrl_psoc; + struct cdp_ctrl_objmgr_psoc *ctrl_psoc; /* OS device abstraction */ qdf_device_t osdev; @@ -907,7 +1061,7 @@ struct dp_soc { struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx; /* HTT handle for host-fw interaction */ - void *htt_handle; + struct htt_soc *htt_handle; /* Commint init done */ qdf_atomic_t cmn_init_done; @@ -918,6 +1072,32 @@ struct dp_soc { /* PDEVs on this SOC */ struct dp_pdev *pdev_list[MAX_PDEV_CNT]; + /* Ring used to replenish rx buffers (maybe to the firmware of MAC) */ + struct dp_srng rx_refill_buf_ring[MAX_PDEV_CNT]; + + struct dp_srng rxdma_mon_desc_ring[MAX_NUM_LMAC_HW]; + + /* RXDMA error destination ring */ + struct dp_srng rxdma_err_dst_ring[MAX_NUM_LMAC_HW]; + + /* Link descriptor memory banks */ + struct { + void *base_vaddr_unaligned; + void *base_vaddr; + qdf_dma_addr_t base_paddr_unaligned; + qdf_dma_addr_t base_paddr; + uint32_t size; + } mon_link_desc_banks[MAX_NUM_LMAC_HW][MAX_MON_LINK_DESC_BANKS]; + + /* RXDMA monitor buffer replenish ring */ + struct dp_srng rxdma_mon_buf_ring[MAX_NUM_LMAC_HW]; + + /* RXDMA monitor destination ring */ + struct dp_srng rxdma_mon_dst_ring[MAX_NUM_LMAC_HW]; + + /* RXDMA monitor status ring. TBD: Check format of this ring */ + struct dp_srng rxdma_mon_status_ring[MAX_NUM_LMAC_HW]; + /* Number of PDEVs */ uint8_t pdev_count; @@ -931,19 +1111,13 @@ struct dp_soc { uint8_t num_hw_dscp_tid_map; /* HAL SOC handle */ - void *hal_soc; + hal_soc_handle_t hal_soc; /* Device ID coming from Bus sub-system */ uint32_t device_id; - /* Link descriptor memory banks */ - struct { - void *base_vaddr_unaligned; - void *base_vaddr; - qdf_dma_addr_t base_paddr_unaligned; - qdf_dma_addr_t base_paddr; - uint32_t size; - } link_desc_banks[MAX_LINK_DESC_BANKS]; + /* Link descriptor pages */ + struct qdf_mem_multi_page_t link_desc_pages; /* Link descriptor Idle list for HW internal use (SRNG mode) */ struct dp_srng wbm_idle_link_ring; @@ -1016,6 +1190,10 @@ struct dp_soc { /* Number of REO destination rings */ uint8_t num_reo_dest_rings; + struct dp_rx_history *rx_ring_history[MAX_REO_DEST_RINGS]; + struct dp_rx_err_history *rx_err_ring_history; + struct dp_rx_reinject_history *rx_reinject_ring_history; + #ifdef QCA_LL_TX_FLOW_CONTROL_V2 /* lock to control access to soc TX descriptors */ qdf_spinlock_t flow_pool_array_lock; @@ -1038,6 +1216,9 @@ struct dp_soc { uint32_t wbm_idle_scatter_buf_size; + /* VDEVs on this SOC */ + struct dp_vdev *vdev_id_map[MAX_VDEV_CNT]; + /* Tx H/W queues lock */ qdf_spinlock_t tx_queue_lock[MAX_TX_HW_QUEUES]; @@ -1123,8 +1304,11 @@ struct dp_soc { /*interrupt timer*/ qdf_timer_t mon_reap_timer; uint8_t reap_timer_init; + qdf_timer_t lmac_reap_timer; + uint8_t lmac_timer_init; qdf_timer_t int_timer; uint8_t intr_mode; + uint8_t lmac_polled_mode; qdf_list_t reo_desc_freelist; qdf_spinlock_t reo_desc_freelist_lock; @@ -1147,6 +1331,8 @@ struct dp_soc { void *ipa_wbm_ring_base_vaddr; uint32_t ipa_wbm_ring_size; qdf_dma_addr_t ipa_wbm_tp_paddr; + /* WBM2SW HP shadow paddr */ + qdf_dma_addr_t ipa_wbm_hp_shadow_paddr; /* TX buffers populated into the WBM ring */ void **tx_buf_pool_vaddr_unaligned; @@ -1203,6 +1389,41 @@ struct dp_soc { uint8_t tidmap_prty; /* Pointer to global per ring type specific configuration table */ struct wlan_srng_cfg *wlan_srng_cfg; + /* Num Tx outstanding on device */ + qdf_atomic_t num_tx_outstanding; + /* Num Tx allowed */ + uint32_t num_tx_allowed; + + /** + * Flag to indicate whether WAR to address single cache entry + * invalidation bug is enabled or not + */ + bool is_rx_fse_full_cache_invalidate_war_enabled; +#if defined(WLAN_SUPPORT_RX_FLOW_TAG) || defined(WLAN_SUPPORT_RX_FISA) + /** + * Pointer to DP RX Flow FST at SOC level if + * is_rx_flow_search_table_per_pdev is false + * TBD: rx_fst[num_macs] if we decide to have per mac FST + */ + struct dp_rx_fst *rx_fst; +#ifdef WLAN_SUPPORT_RX_FISA + uint8_t fisa_enable; + + /** + * Params used for controlling the fisa aggregation dynamically + */ + struct { + qdf_atomic_t skip_fisa; + uint8_t fisa_force_flush[MAX_REO_DEST_RINGS]; + } skip_fisa_param; +#endif +#endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */ + /* Save recent operation related variable */ + struct dp_last_op_info last_op_info; +#ifdef FEATURE_RUNTIME_PM + /* Dp runtime refcount */ + qdf_atomic_t dp_runtime_refcount; +#endif }; #ifdef IPA_OFFLOAD @@ -1228,21 +1449,37 @@ struct dp_ipa_resources { /* Same as NAC_MAX_CLENT */ #define DP_NAC_MAX_CLIENT 24 +/* + * 24 bits cookie size + * 10 bits page id 0 ~ 1023 for MCL + * 3 bits page id 0 ~ 7 for WIN + * WBM Idle List Desc size = 128, + * Num descs per page = 4096/128 = 32 for MCL + * Num descs per page = 2MB/128 = 16384 for WIN + */ /* * Macros to setup link descriptor cookies - for link descriptors, we just - * need first 3 bits to store bank ID. The remaining bytes will be used set a - * unique ID, which will be useful in debugging + * need first 3 bits to store bank/page ID for WIN. The + * remaining bytes will be used to set a unique ID, which will + * be useful in debugging */ -#define LINK_DESC_BANK_ID_MASK 0x7 -#define LINK_DESC_ID_SHIFT 3 +#ifdef MAX_ALLOC_PAGE_SIZE +#define LINK_DESC_PAGE_ID_MASK 0x007FE0 +#define LINK_DESC_ID_SHIFT 5 +#define LINK_DESC_COOKIE(_desc_id, _page_id) \ + ((((_page_id) + LINK_DESC_ID_START) << LINK_DESC_ID_SHIFT) | (_desc_id)) +#define LINK_DESC_COOKIE_PAGE_ID(_cookie) \ + (((_cookie) & LINK_DESC_PAGE_ID_MASK) >> LINK_DESC_ID_SHIFT) +#else +#define LINK_DESC_PAGE_ID_MASK 0x7 +#define LINK_DESC_ID_SHIFT 3 +#define LINK_DESC_COOKIE(_desc_id, _page_id) \ + ((((_desc_id) + LINK_DESC_ID_START) << LINK_DESC_ID_SHIFT) | (_page_id)) +#define LINK_DESC_COOKIE_PAGE_ID(_cookie) \ + ((_cookie) & LINK_DESC_PAGE_ID_MASK) +#endif #define LINK_DESC_ID_START 0x8000 -#define LINK_DESC_COOKIE(_desc_id, _bank_id) \ - ((((_desc_id) + LINK_DESC_ID_START) << LINK_DESC_ID_SHIFT) | (_bank_id)) - -#define LINK_DESC_COOKIE_BANK_ID(_cookie) \ - ((_cookie) & LINK_DESC_BANK_ID_MASK) - /* same as ieee80211_nac_param */ enum dp_nac_param_cmd { /* IEEE80211_NAC_PARAM_ADD */ @@ -1286,8 +1523,10 @@ struct dp_neighbour_peer { * @is_ampdu - set if Ampdu aggregate * @nbuf - ppdu descriptor payload * @ppdu_desc - ppdu descriptor - * @ppdu_info_list_elem - linked list of ppdu tlvs + * @ppdu_info_list_elem - linked list of ppdu tlvs * @ppdu_info_queue_elem - Singly linked list (queue) of ppdu tlvs + * @mpdu_compltn_common_tlv - Successful MPDU counter from COMPLTN COMMON tlv + * @mpdu_ack_ba_tlv - Successful MPDU from ACK BA tlv */ struct ppdu_info { uint32_t ppdu_id; @@ -1309,6 +1548,8 @@ struct ppdu_info { #else TAILQ_ENTRY(ppdu_info) ppdu_info_list_elem; #endif + uint16_t mpdu_compltn_common_tlv; + uint16_t mpdu_ack_ba_tlv; }; /** @@ -1320,6 +1561,7 @@ struct ppdu_info { * @last_msdu - last msdu indication * @msdu_part_of_amsdu - msdu part of amsdu * @transmit_cnt - retried count + * @status - transmit status * @tsf - timestamp which it transmitted */ struct msdu_completion_info { @@ -1330,6 +1572,7 @@ struct msdu_completion_info { last_msdu:1, msdu_part_of_amsdu:1; uint8_t transmit_cnt; + uint8_t status; uint32_t tsf; }; @@ -1363,13 +1606,13 @@ struct dp_peer_tx_capture { * at end of each MSDU in monitor-lite mode * @reserved1: reserved for future use * @reserved2: reserved for future use - * @reserved3: reserved for future use + * @flow_tag: flow tag value read from skb->cb * @protocol_tag: protocol tag value read from skb->cb */ struct dp_rx_mon_enh_trailer_data { uint16_t reserved1; uint16_t reserved2; - uint16_t reserved3; + uint16_t flow_tag; uint16_t protocol_tag; }; #endif /* WLAN_RX_PKT_CAPTURE_ENH */ @@ -1379,8 +1622,6 @@ struct dp_pdev { /** * Re-use Memory Section Starts */ - /* PDEV handle from OSIF layer TBD: see if we really need osif_pdev */ - struct cdp_ctrl_objmgr_pdev *ctrl_pdev; /* PDEV Id */ int pdev_id; @@ -1391,32 +1632,6 @@ struct dp_pdev { /* TXRX SOC handle */ struct dp_soc *soc; - /* Ring used to replenish rx buffers (maybe to the firmware of MAC) */ - struct dp_srng rx_refill_buf_ring; - - /* RXDMA error destination ring */ - struct dp_srng rxdma_err_dst_ring[NUM_RXDMA_RINGS_PER_PDEV]; - - /* Link descriptor memory banks */ - struct { - void *base_vaddr_unaligned; - void *base_vaddr; - qdf_dma_addr_t base_paddr_unaligned; - qdf_dma_addr_t base_paddr; - uint32_t size; - } link_desc_banks[NUM_RXDMA_RINGS_PER_PDEV][MAX_MON_LINK_DESC_BANKS]; - - /* RXDMA monitor buffer replenish ring */ - struct dp_srng rxdma_mon_buf_ring[NUM_RXDMA_RINGS_PER_PDEV]; - - /* RXDMA monitor destination ring */ - struct dp_srng rxdma_mon_dst_ring[NUM_RXDMA_RINGS_PER_PDEV]; - - /* RXDMA monitor status ring. TBD: Check format of this ring */ - struct dp_srng rxdma_mon_status_ring[NUM_RXDMA_RINGS_PER_PDEV]; - - struct dp_srng rxdma_mon_desc_ring[NUM_RXDMA_RINGS_PER_PDEV]; - /* Stuck count on monitor destination ring MPDU process */ uint32_t mon_dest_ring_stuck_cnt; @@ -1428,6 +1643,13 @@ struct dp_pdev { */ bool pdev_deinit; + /* pdev status down or up required to handle dynamic hw + * mode switch between DBS and DBS_SBS. + * 1 = down + * 0 = up + */ + bool is_pdev_down; + /* Second ring used to replenish rx buffers */ struct dp_srng rx_refill_buf_ring2; @@ -1471,6 +1693,9 @@ struct dp_pdev { /* Monitor mode operation channel */ int mon_chan_num; + /* Monitor mode operation frequency */ + qdf_freq_t mon_chan_freq; + /* monitor mode lock */ qdf_spinlock_t mon_lock; @@ -1552,11 +1777,14 @@ struct dp_pdev { struct msdu_list msdu_list[MAX_MU_USERS]; /* RX enhanced capture mode */ uint8_t rx_enh_capture_mode; + /* Rx per peer enhanced capture mode */ + bool rx_enh_capture_peer; + struct dp_vdev *rx_enh_monitor_vdev; /* RX enhanced capture trailer enable/disable flag */ bool is_rx_enh_capture_trailer_enabled; #ifdef WLAN_RX_PKT_CAPTURE_ENH /* RX per MPDU/PPDU information */ - struct cdp_rx_indication_mpdu mpdu_ind[MAX_MU_USERS]; + struct cdp_rx_indication_mpdu mpdu_ind; #endif /* pool addr for mcast enhance buff */ struct { @@ -1587,10 +1815,8 @@ struct dp_pdev { /* map this pdev to a particular Reo Destination ring */ enum cdp_host_reo_dest_ring reo_dest; -#ifndef REMOVE_PKT_LOG /* Packet log mode */ uint8_t rx_pktlog_mode; -#endif /* WDI event handlers */ struct wdi_event_subscribe_t **wdi_event_list; @@ -1605,6 +1831,8 @@ struct dp_pdev { bool tx_sniffer_enable; /* mirror copy mode */ bool mcopy_mode; + bool cfr_rcc_mode; + bool enable_reap_timer_non_pkt; bool bpr_enable; /* enable time latency check for tx completion */ @@ -1654,7 +1882,7 @@ struct dp_pdev { */ uint8_t is_primary; /* Context of cal client timer */ - void *cal_client_ctx; + struct cdp_cal_client *cal_client_ctx; struct cdp_tx_sojourn_stats sojourn_stats; qdf_nbuf_t sojourn_buf; @@ -1707,16 +1935,35 @@ struct dp_pdev { #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ /* tx packet capture enhancement */ - bool tx_capture_enabled; + enum cdp_tx_enh_capture_mode tx_capture_enabled; struct dp_pdev_tx_capture tx_capture; /* stats counter for tx ppdu processed */ uint64_t tx_ppdu_proc; uint32_t *ppdu_tlv_buf; /* Buffer to hold HTT ppdu stats TLVs*/ + /* nbuf queue to maintain rx ppdu status buffer + * belonging to one ppdu + */ + qdf_nbuf_queue_t rx_ppdu_buf_q; +#ifdef WLAN_SUPPORT_RX_FLOW_TAG + /** + * Pointer to DP Flow FST at SOC level if + * is_rx_flow_search_table_per_pdev is true + */ + struct dp_rx_fst *rx_fst; +#endif /* WLAN_SUPPORT_RX_FLOW_TAG */ + +#ifdef FEATURE_TSO_STATS + /* TSO Id to index into TSO packet information */ + qdf_atomic_t tso_idx; +#endif /* FEATURE_TSO_STATS */ + #ifdef WLAN_SUPPORT_DATA_STALL data_stall_detect_cb data_stall_detect_callback; #endif /* WLAN_SUPPORT_DATA_STALL */ + + struct dp_mon_filter **filter; /* Monitor Filter pointer */ }; struct dp_peer; @@ -1728,11 +1975,12 @@ struct dp_vdev { /* physical device that is the parent of this virtual device */ struct dp_pdev *pdev; + /* HW TX Checksum Enabled Flag */ + uint8_t csum_enabled; + /* Handle to the OS shim SW's virtual device */ ol_osif_vdev_handle osif_vdev; - /* Handle to the UMAC handle */ - struct cdp_ctrl_objmgr_vdev *ctrl_vdev; /* vdev_id - ID used to specify a particular vdev to the target */ uint8_t vdev_id; @@ -1751,6 +1999,10 @@ struct dp_vdev { ol_txrx_rx_fp osif_rx; /* callback to deliver rx frames to the OS */ ol_txrx_rx_fp osif_rx_stack; + /* Callback to handle rx fisa frames */ + ol_txrx_fisa_rx_fp osif_fisa_rx; + ol_txrx_fisa_flush_fp osif_fisa_flush; + /* call back function to flush out queued rx packets*/ ol_txrx_rx_flush_fp osif_rx_flush; ol_txrx_rsim_rx_decap_fp osif_rsim_rx_decap; @@ -1869,7 +2121,7 @@ struct dp_vdev { struct dp_tx_desc_pool_s *pool; #endif /* AP BRIDGE enabled */ - uint32_t ap_bridge_enabled; + bool ap_bridge_enabled; enum cdp_sec_type sec_type; @@ -1882,6 +2134,9 @@ struct dp_vdev { /* AST hash value for BSS peer in HW valid for STA VAP*/ uint16_t bss_ast_hash; + /* AST hash index for BSS peer in HW valid for STA VAP*/ + uint16_t bss_ast_idx; + /* Capture timestamp of previous tx packet enqueued */ uint64_t prev_tx_enq_tstamp; @@ -1899,8 +2154,42 @@ struct dp_vdev { /* Self Peer in STA mode */ struct dp_peer *vap_self_peer; + bool multipass_en; +#ifdef QCA_MULTIPASS_SUPPORT + uint16_t *iv_vlan_map; + + /* dp_peer special list */ + TAILQ_HEAD(, dp_peer) mpass_peer_list; + DP_MUTEX_TYPE mpass_peer_mutex; +#endif + /* Extended data path handle */ + struct cdp_ext_vdev *vdev_dp_ext_handle; +#ifdef VDEV_PEER_PROTOCOL_COUNT + /* + * Rx-Ingress and Tx-Egress are in the lower level DP layer + * Rx-Egress and Tx-ingress are handled in osif layer for DP + * So + * Rx-Egress and Tx-ingress mask definitions are in OSIF layer + * Rx-Ingress and Tx-Egress definitions are here below + */ +#define VDEV_PEER_PROTOCOL_RX_INGRESS_MASK 1 +#define VDEV_PEER_PROTOCOL_TX_INGRESS_MASK 2 +#define VDEV_PEER_PROTOCOL_RX_EGRESS_MASK 4 +#define VDEV_PEER_PROTOCOL_TX_EGRESS_MASK 8 + bool peer_protocol_count_track; + int peer_protocol_count_dropmask; +#endif + /* vap bss peer mac addr */ uint8_t vap_bss_peer_mac_addr[QDF_MAC_ADDR_SIZE]; + +#ifdef WLAN_SUPPORT_RX_FISA + /** + * Params used for controlling the fisa aggregation dynamically + */ + uint8_t fisa_disallowed[MAX_REO_DEST_RINGS]; + uint8_t fisa_force_flushed[MAX_REO_DEST_RINGS]; +#endif }; @@ -1936,13 +2225,56 @@ struct dp_peer_cached_bufq { uint32_t dropped; }; +/** + * enum dp_peer_ast_flowq + * @DP_PEER_AST_FLOWQ_HI_PRIO: Hi Priority flow queue + * @DP_PEER_AST_FLOWQ_LOW_PRIO: Low priority flow queue + * @DP_PEER_AST_FLOWQ_UDP: flow queue type is UDP + * @DP_PEER_AST_FLOWQ_NON_UDP: flow queue type is Non UDP + */ +enum dp_peer_ast_flowq { + DP_PEER_AST_FLOWQ_HI_PRIO, + DP_PEER_AST_FLOWQ_LOW_PRIO, + DP_PEER_AST_FLOWQ_UDP, + DP_PEER_AST_FLOWQ_NON_UDP, + DP_PEER_AST_FLOWQ_MAX, +}; + +/* + * struct dp_ast_flow_override_info - ast override info + * @ast_index - ast indexes in peer map message + * @ast_valid_mask - ast valid mask for each ast index + * @ast_flow_mask - ast flow mask for each ast index + * @tid_valid_low_pri_mask - per tid mask for low priority flow + * @tid_valid_hi_pri_mask - per tid mask for hi priority flow + */ +struct dp_ast_flow_override_info { + uint16_t ast_idx[DP_PEER_AST_FLOWQ_MAX]; + uint8_t ast_valid_mask; + uint8_t ast_flow_mask[DP_PEER_AST_FLOWQ_MAX]; + uint8_t tid_valid_low_pri_mask; + uint8_t tid_valid_hi_pri_mask; +}; + +/* + * struct dp_peer_ast_params - ast parameters for a msdu flow-queue + * @ast_index - ast index populated by FW + * @is_valid - ast flow valid mask + * @valid_tid_mask - per tid mask for this ast index + * @flowQ - flow queue id associated with this ast index + */ +struct dp_peer_ast_params { + uint16_t ast_idx; + uint8_t is_valid; + uint8_t valid_tid_mask; + uint8_t flowQ; +}; + /* Peer structure for data path state */ struct dp_peer { /* VDEV to which this peer is associated */ struct dp_vdev *vdev; - struct cdp_ctrl_objmgr_peer *ctrl_peer; - struct dp_ast_entry *self_ast_entry; qdf_atomic_t ref_cnt; @@ -1970,29 +2302,15 @@ struct dp_peer { u_int32_t michael_key[2]; /* relevant for TKIP */ } security[2]; /* 0 -> multicast, 1 -> unicast */ - /* - * rx proc function: this either is a copy of pdev's rx_opt_proc for - * regular rx processing, or has been redirected to a /dev/null discard - * function when peer deletion is in progress. - */ - void (*rx_opt_proc)(struct dp_vdev *vdev, struct dp_peer *peer, - unsigned tid, qdf_nbuf_t msdu_list); - - /* set when node is authorized */ - uint8_t authorize:1; - - u_int8_t nac; - - /* Band steering: Set when node is inactive */ - uint8_t peer_bs_inact_flag:1; - u_int16_t peer_bs_inact; /* inactivity mark count */ - /* NAWDS Flag and Bss Peer bit */ - uint8_t nawds_enabled:1, - bss_peer:1, - wapi:1, - wds_enabled:1, - valid:1; + uint8_t nawds_enabled:1, /* NAWDS flag */ + bss_peer:1, /* set for bss peer */ + wds_enabled:1, /* WDS peer */ + authorize:1, /* Set when authorized */ + nac:1, /* NAC Peer*/ + tx_cap_enabled:1, /* Peer's tx-capture is enabled */ + rx_cap_enabled:1, /* Peer's rx-capture is enabled */ + valid:1; /* valid bit */ /* MCL specific peer local id */ uint16_t local_id; @@ -2032,10 +2350,28 @@ struct dp_peer { /* average sojourn time */ qdf_ewma_tx_lag avg_sojourn_msdu[CDP_DATA_TID_MAX]; +#ifdef QCA_MULTIPASS_SUPPORT + /* node in the special peer list element */ + TAILQ_ENTRY(dp_peer) mpass_peer_list_elem; + /* vlan id for key */ + uint16_t vlan_id; +#endif + #ifdef PEER_CACHE_RX_PKTS qdf_atomic_t flush_in_progress; struct dp_peer_cached_bufq bufq_info; #endif +#ifdef FEATURE_PERPKT_INFO + /* delayed ba ppdu stats handling */ + struct cdp_delayed_tx_completion_ppdu_user delayed_ba_ppdu_stats; + /* delayed ba flag */ + bool last_delayed_ba; + /* delayed ba ppdu id */ + uint32_t last_delayed_ba_ppduid; +#endif +#ifdef QCA_PEER_MULTIQ_SUPPORT + struct dp_peer_ast_params peer_ast_flowq_idx[DP_PEER_AST_FLOWQ_MAX]; +#endif }; /* @@ -2062,6 +2398,151 @@ struct dp_tx_me_buf_t { uint8_t data[QDF_MAC_ADDR_SIZE]; }; +#if defined(WLAN_SUPPORT_RX_FLOW_TAG) || defined(WLAN_SUPPORT_RX_FISA) +struct hal_rx_fst; + +#ifdef WLAN_SUPPORT_RX_FLOW_TAG +struct dp_rx_fse { + /* HAL Rx Flow Search Entry which matches HW definition */ + void *hal_rx_fse; + /* Toeplitz hash value */ + uint32_t flow_hash; + /* Flow index, equivalent to hash value truncated to FST size */ + uint32_t flow_id; + /* Stats tracking for this flow */ + struct cdp_flow_stats stats; + /* Flag indicating whether flow is IPv4 address tuple */ + uint8_t is_ipv4_addr_entry; + /* Flag indicating whether flow is valid */ + uint8_t is_valid; +}; + +struct dp_rx_fst { + /* Software (DP) FST */ + uint8_t *base; + /* Pointer to HAL FST */ + struct hal_rx_fst *hal_rx_fst; + /* Base physical address of HAL RX HW FST */ + uint64_t hal_rx_fst_base_paddr; + /* Maximum number of flows FSE supports */ + uint16_t max_entries; + /* Num entries in flow table */ + uint16_t num_entries; + /* SKID Length */ + uint16_t max_skid_length; + /* Hash mask to obtain legitimate hash entry */ + uint32_t hash_mask; + /* Timer for bundling of flows */ + qdf_timer_t cache_invalidate_timer; + /** + * Flag which tracks whether cache update + * is needed on timer expiry + */ + qdf_atomic_t is_cache_update_pending; + /* Flag to indicate completion of FSE setup in HW/FW */ + bool fse_setup_done; +}; + +#define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_rx_fse) +#elif WLAN_SUPPORT_RX_FISA + +struct dp_fisa_stats { + /* flow index invalid from RX HW TLV */ + uint32_t invalid_flow_index; +}; + +enum fisa_aggr_ret { + FISA_AGGR_DONE, + FISA_AGGR_NOT_ELIGIBLE, + FISA_FLUSH_FLOW +}; + +struct dp_fisa_rx_sw_ft { + /* HAL Rx Flow Search Entry which matches HW definition */ + void *hw_fse; + /* Toeplitz hash value */ + uint32_t flow_hash; + /* Flow index, equivalent to hash value truncated to FST size */ + uint32_t flow_id; + /* Stats tracking for this flow */ + struct cdp_flow_stats stats; + /* Flag indicating whether flow is IPv4 address tuple */ + uint8_t is_ipv4_addr_entry; + /* Flag indicating whether flow is valid */ + uint8_t is_valid; + uint8_t is_populated; + uint8_t is_flow_udp; + uint8_t is_flow_tcp; + qdf_nbuf_t head_skb; + uint16_t cumulative_l4_checksum; + uint16_t adjusted_cumulative_ip_length; + uint16_t cur_aggr; + uint16_t napi_flush_cumulative_l4_checksum; + uint16_t napi_flush_cumulative_ip_length; + qdf_nbuf_t last_skb; + uint32_t head_skb_ip_hdr_offset; + uint32_t head_skb_l4_hdr_offset; + struct cdp_rx_flow_tuple_info rx_flow_tuple_info; + uint8_t napi_id; + struct dp_vdev *vdev; + uint64_t bytes_aggregated; + uint32_t flush_count; + uint32_t aggr_count; + uint8_t do_not_aggregate; + uint16_t hal_cumultive_ip_len; + struct dp_soc *soc_hdl; + /* last aggregate count fetched from RX PKT TLV */ + uint32_t last_hal_aggr_count; + uint32_t cur_aggr_gso_size; + struct udphdr *head_skb_udp_hdr; + uint32_t reo_dest_indication; +}; + +#define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_fisa_rx_sw_ft) +#define MAX_FSE_CACHE_FL_HST 10 +/** + * struct fse_cache_flush_history - Debug history cache flush + * @timestamp: Entry update timestamp + * @flows_added: Number of flows added for this flush + * @flows_deleted: Number of flows deleted for this flush + */ +struct fse_cache_flush_history { + uint64_t timestamp; + uint32_t flows_added; + uint32_t flows_deleted; +}; + +struct dp_rx_fst { + /* Software (DP) FST */ + uint8_t *base; + /* Pointer to HAL FST */ + struct hal_rx_fst *hal_rx_fst; + /* Base physical address of HAL RX HW FST */ + uint64_t hal_rx_fst_base_paddr; + /* Maximum number of flows FSE supports */ + uint16_t max_entries; + /* Num entries in flow table */ + uint16_t num_entries; + /* SKID Length */ + uint16_t max_skid_length; + /* Hash mask to obtain legitimate hash entry */ + uint32_t hash_mask; + /* Lock for adding/deleting entries of FST */ + qdf_spinlock_t dp_rx_fst_lock; + uint32_t add_flow_count; + uint32_t del_flow_count; + uint32_t hash_collision_cnt; + struct dp_soc *soc_hdl; + qdf_atomic_t fse_cache_flush_posted; + qdf_timer_t fse_cache_flush_timer; + struct fse_cache_flush_history cache_fl_rec[MAX_FSE_CACHE_FL_HST]; + /* FISA DP stats */ + struct dp_fisa_stats stats; +}; + +#endif /* WLAN_SUPPORT_RX_FISA */ +#endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */ + #ifdef WLAN_FEATURE_STATS_EXT /* * dp_req_rx_hw_stats_t: RX peer HW stats query structure diff --git a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c index 3417b95ce2342b9da41831f110daf2a22d58b2fc..697a570ac53069c4fb35ca806227151aac2a1434 100644 --- a/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c +++ b/drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -21,9 +21,14 @@ #include "qdf_mem.h" /* qdf_mem_malloc,free */ #ifdef WDI_EVENT_ENABLE -void *dp_get_pldev(struct cdp_pdev *txrx_pdev) +void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + + if (!pdev) + return NULL; + return pdev->pl_dev; } /* @@ -110,7 +115,7 @@ dp_wdi_event_iter_sub( void dp_wdi_event_handler( enum WDI_EVENT event, - void *soc, + struct dp_soc *soc, void *data, uint16_t peer_id, int status, uint8_t pdev_id) @@ -149,7 +154,8 @@ dp_wdi_event_handler( /* * dp_wdi_event_sub() - Subscribe WDI event - * @txrx_pdev_handle: cdp_pdev handle + * @soc: soc handle + * @pdev_id: id of pdev * @event_cb_sub_handle: subcribe evnet handle * @event: Event to be subscribe * @@ -157,13 +163,15 @@ dp_wdi_event_handler( */ int dp_wdi_event_sub( - struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, + struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, uint32_t event) { uint32_t event_index; wdi_event_subscribe *wdi_sub; - struct dp_pdev *txrx_pdev = (struct dp_pdev *)txrx_pdev_handle; + struct dp_pdev *txrx_pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); wdi_event_subscribe *event_cb_sub = (wdi_event_subscribe *) event_cb_sub_handle; @@ -206,7 +214,8 @@ dp_wdi_event_sub( /* * dp_wdi_event_unsub() - WDI event unsubscribe - * @txrx_pdev_handle: cdp_pdev handle + * @soc: soc handle + * @pdev_id: id of pdev * @event_cb_sub_handle: subscribed event handle * @event: Event to be unsubscribe * @@ -215,18 +224,20 @@ dp_wdi_event_sub( */ int dp_wdi_event_unsub( - struct cdp_pdev *txrx_pdev_handle, - void *event_cb_sub_handle, + struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub_handle, uint32_t event) { uint32_t event_index = event - WDI_EVENT_BASE; - struct dp_pdev *txrx_pdev = (struct dp_pdev *)txrx_pdev_handle; + struct dp_pdev *txrx_pdev = + dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc, + pdev_id); wdi_event_subscribe *event_cb_sub = (wdi_event_subscribe *) event_cb_sub_handle; - if (!event_cb_sub) { + if (!txrx_pdev || !event_cb_sub) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Invalid callback in %s", __func__); + "Invalid callback or pdev in %s", __func__); return -EINVAL; } diff --git a/drivers/staging/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c b/drivers/staging/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c index 0d4ef2e96e6f8fadf6bcea2129c23d8df9523396..f304973bf93d07dbe5cc4bca8c794e6f56c8fba1 100644 --- a/drivers/staging/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c +++ b/drivers/staging/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c @@ -25,6 +25,8 @@ #ifdef WLAN_CONV_SPECTRAL_ENABLE #include #endif +#include + /* Function pointer to call DA/OL specific tx_ops registration function */ QDF_STATUS (*wlan_global_lmac_if_tx_ops_register[MAX_DEV_TYPE]) (struct wlan_lmac_if_tx_ops *tx_ops); @@ -135,6 +137,8 @@ QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc) /* Function call to register rx-ops handlers */ wlan_global_lmac_if_rx_ops_register(&psoc->soc_cb.rx_ops); + target_if_wake_lock_init(psoc); + return QDF_STATUS_SUCCESS; } qdf_export_symbol(wlan_global_lmac_if_open); @@ -149,6 +153,7 @@ qdf_export_symbol(wlan_global_lmac_if_open); */ QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc) { + target_if_wake_lock_deinit(psoc); qdf_mem_zero(&psoc->soc_cb.tx_ops, sizeof(psoc->soc_cb.tx_ops)); qdf_mem_zero(&psoc->soc_cb.rx_ops, sizeof(psoc->soc_cb.rx_ops)); diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_api.h b/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_api.h new file mode 100644 index 0000000000000000000000000000000000000000..5989812fb2001d6a0cb935ecc568e0c541f785d3 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_api.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_gpio_api.h + * + * This header file provide API declarations required for gpio cfg + * that called by other components + */ + +#ifndef __WLAN_GPIO_CFG_API_H__ +#define __WLAN_GPIO_CFG_API_H__ + +#include + +#ifdef WLAN_FEATURE_GPIO_CFG + +/** + * wlan_gpio_init() - API to init component + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wlan_gpio_init(void); + +/** + * wlan_gpio_deinit() - API to deinit component + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wlan_gpio_deinit(void); + +#else +static inline +QDF_STATUS wlan_gpio_init(void) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS wlan_gpio_deinit(void) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /*__WLAN_GPIO_CFG_API_H__*/ + diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_priv_api.h b/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_priv_api.h new file mode 100644 index 0000000000000000000000000000000000000000..4ea4ead5727a43afb85337b8aa24f4e87e509fa0 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/core/inc/wlan_gpio_priv_api.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_gpio_priv_api.h + * + * This header file provide API declarations required for gpio cfg + * that called internally + */ + +#ifndef __WLAN_GPIO_CFG_PRIV_API_H__ +#define __WLAN_GPIO_CFG_PRIV_API_H__ + +#include +#include +#include + +#define gpio_debug(args ...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_GPIO, ## args) +#define gpio_err(args ...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_GPIO, ## args) + +/** + * struct gpio_psoc_priv_obj - psoc private object + * @lock: qdf spin lock + * @soc: pointer to psoc object + */ +struct gpio_psoc_priv_obj { + qdf_spinlock_t lock; + struct wlan_objmgr_psoc *soc; +}; + +/** + * gpio_get_psoc_priv_obj() - get priv object from psoc object + * @psoc: pointer to psoc object + * + * Return: pointer to gpio psoc private object + */ +static inline +struct gpio_psoc_priv_obj * +gpio_get_psoc_priv_obj(struct wlan_objmgr_psoc *psoc) +{ + struct gpio_psoc_priv_obj *obj; + + if (!psoc) + return NULL; + obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_GPIO); + + return obj; +} + +/** + * wlan_psoc_get_gpio_txops() - get TX ops from the private object + * @psoc: pointer to psoc object + * + * Return: pointer to TX op callback + */ + +static inline struct wlan_lmac_if_gpio_tx_ops * +wlan_psoc_get_gpio_txops(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_tx_ops *tx_ops; + + tx_ops = wlan_psoc_get_lmac_if_txops(psoc); + if (!tx_ops) { + gpio_err("tx_ops is NULL"); + return NULL; + } + + return &tx_ops->gpio_ops; +} +#endif /*__WLAN_GPIO_CFG_PRIV_API_H__*/ diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/core/src/wlan_gpio_api.c b/drivers/staging/qca-wifi-host-cmn/gpio/core/src/wlan_gpio_api.c new file mode 100644 index 0000000000000000000000000000000000000000..8525368d67aae9ad12b1395c8bb90d144a32e391 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/core/src/wlan_gpio_api.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_gpio_api.c + */ +#include +#include +#include + +/** + * gpio_psoc_obj_created_notification() - PSOC obj create callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is created. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS +gpio_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct gpio_psoc_priv_obj *gpio_obj; + + gpio_obj = qdf_mem_malloc(sizeof(*gpio_obj)); + if (!gpio_obj) + return QDF_STATUS_E_NOMEM; + + qdf_spinlock_create(&gpio_obj->lock); + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_GPIO, + gpio_obj, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + gpio_err("obj attach with psoc failed"); + goto gpio_psoc_attach_failed; + } + + return QDF_STATUS_SUCCESS; + +gpio_psoc_attach_failed: + qdf_spinlock_destroy(&gpio_obj->lock); + qdf_mem_free(gpio_obj); + return status; +} + +/** + * gpio_psoc_obj_destroyed_notification() - obj delete callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is deleted. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS +gpio_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct gpio_psoc_priv_obj *gpio_obj; + + gpio_obj = gpio_get_psoc_priv_obj(psoc); + + if (!gpio_obj) { + gpio_err("gpio_obj is NULL"); + return QDF_STATUS_E_FAULT; + } + + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_GPIO, + gpio_obj); + if (QDF_IS_STATUS_ERROR(status)) + gpio_err("gpio_obj detach failed"); + + qdf_spinlock_destroy(&gpio_obj->lock); + qdf_mem_free(gpio_obj); + + return status; +} + +QDF_STATUS wlan_gpio_init(void) +{ + QDF_STATUS status; + + /* register psoc create handler functions. */ + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_GPIO, + gpio_psoc_obj_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + gpio_err("register create handler failed"); + return status; + } + + /* register psoc delete handler functions. */ + status = wlan_objmgr_register_psoc_destroy_handler( + WLAN_UMAC_COMP_GPIO, + gpio_psoc_obj_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + gpio_err("register destroy handler failed"); + goto fail_delete_psoc; + } + + return status; + +fail_delete_psoc: + wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_GPIO, + gpio_psoc_obj_created_notification, + NULL); + return status; +} + +QDF_STATUS wlan_gpio_deinit(void) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS, status; + + /* unregister psoc delete handler functions. */ + status = wlan_objmgr_unregister_psoc_destroy_handler( + WLAN_UMAC_COMP_GPIO, + gpio_psoc_obj_destroyed_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + gpio_err("unregister destroy handler failed"); + ret = status; + } + + /* unregister psoc create handler functions. */ + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_GPIO, + gpio_psoc_obj_created_notification, + NULL); + if (QDF_IS_STATUS_ERROR(status)) { + gpio_err("unregister create handler failed"); + ret = status; + } + + return ret; +} diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_tgt_api.h new file mode 100644 index 0000000000000000000000000000000000000000..0b706f516f2c07e7cd911561991e025876eb0019 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_tgt_api.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_gpio_tgt_api.h + * + * This header file provide with API declarations to interface with Southbound + */ +#ifndef __WLAN_GPIO_CFG_TGT_API_H__ +#define __WLAN_GPIO_CFG_TGT_API_H__ + +#ifdef WLAN_FEATURE_GPIO_CFG +#include +#include +struct wlan_objmgr_psoc; + +/** + * tgt_set_gpio_config_req(): API to set GPIO configuration to lmac + * @psoc: the pointer to psoc object manager + * @param: the pointer to gpio cfg info + * + * Return: status of operation + */ +QDF_STATUS +tgt_set_gpio_config_req(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param); + +/** + * tgt_set_gpio_output_req(): API to set GPIO output info to lmac + * @psoc: the pointer to psoc object manager + * @param: the pointer to gpio output info + * + * Return: status of operation + */ + +QDF_STATUS +tgt_set_gpio_output_req(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param); + +/** + * tgt_if_gpio_config() - API to send gpio config request + * @psoc: pointer to psoc object + * @gpio_num: gpio pin number + * @input: enable/disable the gpio pin + * @pull_type: gpio pull type + * @intr_mode: gpio interrupt mode + * @mux_config_val: gpio MUX value + * @drive: gpio drive + * @init_enable: gpio init_enable + * + * Return: status of operation + */ +QDF_STATUS tgt_gpio_config(struct wlan_objmgr_psoc *psoc, uint32_t gpio_num, + uint32_t input, uint32_t pull_type, + uint32_t intr_mode, uint32_t mux_config_val, + uint32_t drive, uint32_t init_enable); +/** + * tgt_if_gpio_output() - API to send gpio output request + * @psoc: pointer to psoc object + * @gpio_num: gpio pin number + * @set: enable/disable the gpio pin + * + * Return: status of operation + */ +QDF_STATUS tgt_gpio_output(struct wlan_objmgr_psoc *psoc, uint32_t gpio_num, + uint32_t set); +#else +static QDF_STATUS tgt_gpio_config(struct wlan_objmgr_psoc *psoc, + uint32_t gpio_num, uint32_t input, + uint32_t pull_type, uint32_t intr_mode) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tgt_gpio_output(struct wlan_objmgr_psoc *psoc, + uint32_t gpio_num, uint32_t set) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /* __WLAN_GPIO_TGT_API_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_ucfg_api.h new file mode 100644 index 0000000000000000000000000000000000000000..933825f8a1a64e0414e15d16d2530668fb41b4c7 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/inc/wlan_gpio_ucfg_api.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_gpio_ucfg_api.h + * + * This header file maintain API declaration required for northbound interaction + */ + +#ifndef __WLAN_GPIO_CFG_UCFG_API_H__ +#define __WLAN_GPIO_CFG_UCFG_API_H__ + +#include +#include +struct wlan_objmgr_psoc; + +#ifdef WLAN_FEATURE_GPIO_CFG + +/** + * ucfg_set_gpio_config() - API to set gpio config + * @psoc: the pointer of psoc object + * @param: the pointer of gpio configuration info + * + * Return:QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS ucfg_set_gpio_config(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param); + +/** + * ucfg_set_gpio_output() - API to set gpio output + * @psoc: the pointer of psoc object + * @param: the pointer of gpio output info + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS ucfg_set_gpio_output(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param); +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /* __WLAN_GPIO_CFG_UCFG_API_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_tgt_api.c new file mode 100644 index 0000000000000000000000000000000000000000..293cfdf0bb24dcd875827ef1deee794c7ef29497 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_tgt_api.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC:wlan_gpio_tgt_api.c + * + * This file provide API definitions to update gpio configuration from interface + */ +#include +#include +#include +#include + +QDF_STATUS tgt_set_gpio_config_req(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param) +{ + struct wlan_lmac_if_gpio_tx_ops *gpio_tx_ops; + + if (!psoc) { + gpio_err("NULL psoc"); + return QDF_STATUS_E_NULL_VALUE; + } + gpio_tx_ops = wlan_psoc_get_gpio_txops(psoc); + if (!gpio_tx_ops) + return QDF_STATUS_E_NULL_VALUE; + + return gpio_tx_ops->set_gpio_config(psoc, param); +} + +QDF_STATUS tgt_set_gpio_output_req(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param) +{ + struct wlan_lmac_if_gpio_tx_ops *gpio_tx_ops; + + if (!psoc) { + gpio_err("NULL psoc"); + return QDF_STATUS_E_NULL_VALUE; + } + + gpio_tx_ops = wlan_psoc_get_gpio_txops(psoc); + if (!gpio_tx_ops) + return QDF_STATUS_E_NULL_VALUE; + + return gpio_tx_ops->set_gpio_output(psoc, param); +} + +QDF_STATUS tgt_gpio_config(struct wlan_objmgr_psoc *psoc, uint32_t gpio_num, + uint32_t input, uint32_t pull_type, + uint32_t intr_mode, uint32_t mux_config_val, + uint32_t drive, uint32_t init_enable) +{ + struct gpio_config_params param; + + if (!psoc) { + gpio_err("psoc_obj is null"); + return QDF_STATUS_E_INVAL; + } + + qdf_mem_set(¶m, sizeof(param), 0); + param.pin_pull_type = pull_type; + param.pin_num = gpio_num; + param.pin_dir = input; + param.pin_intr_mode = intr_mode; + param.mux_config_val = mux_config_val; + param.drive = drive; + param.init_enable = init_enable; + + return tgt_set_gpio_config_req(psoc, ¶m); +} + +qdf_export_symbol(tgt_gpio_config); + +static bool tgt_gpio_disabled(struct wlan_objmgr_psoc *psoc) +{ + uint32_t target_type = 0; + struct wlan_lmac_if_target_tx_ops *target_type_tx_ops; + struct wlan_lmac_if_tx_ops *tx_ops; + + tx_ops = wlan_psoc_get_lmac_if_txops(psoc); + if (!tx_ops) { + gpio_err("tx_ops is NULL"); + return false; + } + target_type_tx_ops = &tx_ops->target_tx_ops; + + if (target_type_tx_ops->tgt_get_tgt_type) + target_type = target_type_tx_ops->tgt_get_tgt_type(psoc); + + if ((target_type == TARGET_TYPE_QCA8074) || + (target_type == TARGET_TYPE_QCN6122) || + (target_type == TARGET_TYPE_QCA8074V2) || + (target_type == TARGET_TYPE_QCA5018) || + (target_type == TARGET_TYPE_QCA6018)) { + return true; + } + + return false; +} + +QDF_STATUS tgt_gpio_output(struct wlan_objmgr_psoc *psoc, uint32_t gpio_num, + uint32_t set) +{ + struct gpio_output_params param; + + if (!psoc) { + gpio_err("psoc_obj is null"); + return QDF_STATUS_E_INVAL; + } + + if (tgt_gpio_disabled(psoc)) + return QDF_STATUS_E_INVAL; + + qdf_mem_set(¶m, sizeof(param), 0); + param.pin_num = gpio_num; + param.pin_set = set; + + return tgt_set_gpio_output_req(psoc, ¶m); +} + +qdf_export_symbol(tgt_gpio_output); diff --git a/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_ucfg_api.c new file mode 100644 index 0000000000000000000000000000000000000000..648658a7fbe331cff4f6d83be71d6bb611ea6890 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/gpio/dispatcher/src/wlan_gpio_ucfg_api.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: This file contains gpio north bound interface definitions + */ +#include +#include +#include "qdf_module.h" + +QDF_STATUS +ucfg_set_gpio_config(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param) +{ + return tgt_set_gpio_config_req(psoc, param); +} +qdf_export_symbol(ucfg_set_gpio_config); + +QDF_STATUS +ucfg_set_gpio_output(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param) +{ + return tgt_set_gpio_output_req(psoc, param); +} +qdf_export_symbol(ucfg_set_gpio_output); diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h index d048a3fb5112761cdc4a83055ac300b98ac24761..649852dcac214a381a563ae4171dcf4ebc743cc5 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,10 +24,36 @@ #include "qdf_util.h" #include "qdf_atomic.h" #include "hal_internal.h" +#include "hif.h" +#include "hif_io32.h" #include "qdf_platform.h" +#ifdef DUMP_REO_QUEUE_INFO_IN_DDR +#include "hal_hw_headers.h" +#endif + +/* Ring index for WBM2SW2 release ring */ +#define HAL_IPA_TX_COMP_RING_IDX 2 + +/* calculate the register address offset from bar0 of shadow register x */ +#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750) +#define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x000008FC +#define SHADOW_REGISTER_END_ADDRESS_OFFSET \ + ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (MAX_SHADOW_REGISTERS))) +#define SHADOW_REGISTER(x) ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (x))) +#elif defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCN9000) +#define SHADOW_REGISTER_START_ADDRESS_OFFSET 0x00003024 +#define SHADOW_REGISTER_END_ADDRESS_OFFSET \ + ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (MAX_SHADOW_REGISTERS))) +#define SHADOW_REGISTER(x) ((SHADOW_REGISTER_START_ADDRESS_OFFSET) + (4 * (x))) +#else +#define SHADOW_REGISTER(x) 0 +#endif /* QCA_WIFI_QCA6390 || QCA_WIFI_QCA6490 || QCA_WIFI_QCA6750 */ + #define MAX_UNWINDOWED_ADDRESS 0x80000 -#ifdef QCA_WIFI_QCA6390 +#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCN9000) || defined(QCA_WIFI_QCA6750) #define WINDOW_ENABLE_BIT 0x40000000 #else #define WINDOW_ENABLE_BIT 0x80000000 @@ -36,21 +63,36 @@ #define WINDOW_VALUE_MASK 0x3F #define WINDOW_START MAX_UNWINDOWED_ADDRESS #define WINDOW_RANGE_MASK 0x7FFFF - /* * BAR + 4K is always accessible, any access outside this * space requires force wake procedure. - * OFFSET = 4K - 32 bytes = 0x4063 + * OFFSET = 4K - 32 bytes = 0xFE0 */ -#define MAPPED_REF_OFF 0x4063 +#define MAPPED_REF_OFF 0xFE0 -#ifdef HAL_CONFIG_SLUB_DEBUG_ON -#define FORCE_WAKE_DELAY_TIMEOUT 500 -#else -#define FORCE_WAKE_DELAY_TIMEOUT 50 -#endif /* HAL_CONFIG_SLUB_DEBUG_ON */ +/** + * hal_ring_desc - opaque handle for DP ring descriptor + */ +struct hal_ring_desc; +typedef struct hal_ring_desc *hal_ring_desc_t; -#define FORCE_WAKE_DELAY_MS 5 +/** + * hal_link_desc - opaque handle for DP link descriptor + */ +struct hal_link_desc; +typedef struct hal_link_desc *hal_link_desc_t; + +/** + * hal_rxdma_desc - opaque handle for DP rxdma dst ring descriptor + */ +struct hal_rxdma_desc; +typedef struct hal_rxdma_desc *hal_rxdma_desc_t; + +/** + * hal_buff_addrinfo - opaque handle for DP buffer address info + */ +struct hal_buff_addrinfo; +typedef struct hal_buff_addrinfo *hal_buff_addrinfo_t; #ifdef ENABLE_VERBOSE_DEBUG static inline void @@ -99,6 +141,7 @@ static inline int hal_history_get_next_index(qdf_atomic_t *table_index, * @hal_soc: HAL soc handle * @offset: register offset to read * @exp_val: the expected value of register + * @ret_confirm: result confirm flag * * Return: none */ @@ -115,17 +158,7 @@ static inline void hal_reg_write_result_check(struct hal_soc *hal_soc, } } -#ifndef QCA_WIFI_QCA6390 -static inline int hal_force_wake_request(struct hal_soc *soc) -{ - return 0; -} - -static inline int hal_force_wake_release(struct hal_soc *soc) -{ - return 0; -} - +#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) static inline void hal_lock_reg_access(struct hal_soc *soc, unsigned long *flags) { @@ -137,36 +170,7 @@ static inline void hal_unlock_reg_access(struct hal_soc *soc, { qdf_spin_unlock_irqrestore(&soc->register_access_lock); } - #else -static inline int hal_force_wake_request(struct hal_soc *soc) -{ - int ret; - - ret = pld_force_wake_request_sync(soc->qdf_dev->dev, - FORCE_WAKE_DELAY_TIMEOUT * 1000); - if (ret) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Request send failed %d\n", __func__, ret); - return -EINVAL; - } - - /* If device's M1 state-change event races here, it can be ignored, - * as the device is expected to immediately move from M2 to M0 - * without entering low power state. - */ - if (!pld_is_device_awake(soc->qdf_dev->dev)) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, - "%s: state-change event races, ignore\n", __func__); - - return 0; -} - -static inline int hal_force_wake_release(struct hal_soc *soc) -{ - return pld_force_wake_release(soc->qdf_dev->dev); -} - static inline void hal_lock_reg_access(struct hal_soc *soc, unsigned long *flags) { @@ -182,7 +186,7 @@ static inline void hal_unlock_reg_access(struct hal_soc *soc, #ifdef PCIE_REG_WINDOW_LOCAL_NO_CACHE /** - * hal_select_window_confirm() - write window register and + * hal_select_window_confirm() - write remap window register and check writing result * */ @@ -217,33 +221,86 @@ static inline void hal_select_window_confirm(struct hal_soc *hal_soc, } #endif +static inline qdf_iomem_t hal_get_window_address(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return hal_soc->ops->hal_get_window_address(hal_soc, addr); +} + /** + * hal_write32_mb() - Access registers to update configuration + * @hal_soc: hal soc handle + * @offset: offset address from the BAR + * @value: value to write + * + * Return: None + * + * Description: Register address space is split below: + * SHADOW REGION UNWINDOWED REGION WINDOWED REGION + * |--------------------|-------------------|------------------| + * BAR NO FORCE WAKE BAR+4K FORCE WAKE BAR+512K FORCE WAKE + * + * 1. Any access to the shadow region, doesn't need force wake + * and windowing logic to access. + * 2. Any access beyond BAR + 4K: + * If init_phase enabled, no force wake is needed and access + * should be based on windowed or unwindowed access. + * If init_phase disabled, force wake is needed and access + * should be based on windowed or unwindowed access. + * * note1: WINDOW_RANGE_MASK = (1 << WINDOW_SHIFT) -1 * note2: 1 << WINDOW_SHIFT = MAX_UNWINDOWED_ADDRESS - * note3: WINDOW_VALUE_MASK = big enough that trying to write past that window - * would be a bug + * note3: WINDOW_VALUE_MASK = big enough that trying to write past + * that window would be a bug */ -#ifndef QCA_WIFI_QCA6390 +#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \ + !defined(QCA_WIFI_QCA6750) static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, uint32_t value) { unsigned long flags; + qdf_iomem_t new_addr; if (!hal_soc->use_register_windowing || offset < MAX_UNWINDOWED_ADDRESS) { qdf_iowrite32(hal_soc->dev_base_addr + offset, value); + } else if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, + hal_soc->dev_base_addr + offset); + qdf_iowrite32(new_addr, value); } else { hal_lock_reg_access(hal_soc, &flags); hal_select_window_confirm(hal_soc, offset); qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + (offset & WINDOW_RANGE_MASK), value); - hal_unlock_reg_access(hal_soc, &flags); } } +/** + * hal_write_address_32_mb - write a value to a register + * + */ +static inline +void hal_write_address_32_mb(struct hal_soc *hal_soc, + qdf_iomem_t addr, uint32_t value) +{ + uint32_t offset; + qdf_iomem_t new_addr; + + if (!hal_soc->use_register_windowing) + return qdf_iowrite32(addr, value); + + offset = addr - hal_soc->dev_base_addr; + if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, addr); + return qdf_iowrite32(new_addr, value); + } + hal_write32_mb(hal_soc, offset, value); +} + #define hal_write32_mb_confirm(_hal_soc, _offset, _value) \ - hal_write32_mb(_hal_soc, _offset, _value) + hal_write32_mb(_hal_soc, _offset, _value) #else static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, uint32_t value) @@ -251,12 +308,17 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, int ret; unsigned long flags; - if (offset > MAPPED_REF_OFF) { - ret = hal_force_wake_request(hal_soc); + /* Region < BAR + 4K can be directly accessed */ + if (offset < MAPPED_REF_OFF) { + qdf_iowrite32(hal_soc->dev_base_addr + offset, value); + return; + } + + /* Region greater than BAR + 4K */ + if (!hal_soc->init_phase) { + ret = hif_force_wake_request(hal_soc->hif_handle); if (ret) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up request failed %d\n", - __func__, ret); + hal_err("Wake up request failed"); qdf_check_state_before_panic(); return; } @@ -270,18 +332,22 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, hal_select_window_confirm(hal_soc, offset); qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_START + (offset & WINDOW_RANGE_MASK), value); - hal_unlock_reg_access(hal_soc, &flags); } - if ((offset > MAPPED_REF_OFF) && - hal_force_wake_release(hal_soc)) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up release failed\n", __func__); + if (!hal_soc->init_phase) { + ret = hif_force_wake_release(hal_soc->hif_handle); + if (ret) { + hal_err("Wake up release failed"); + qdf_check_state_before_panic(); + return; + } + } } /** - * hal_write32_mb_confirm() - write register and check writing result + * hal_write32_mb_confirm() - write register and check wirting result + * */ static inline void hal_write32_mb_confirm(struct hal_soc *hal_soc, uint32_t offset, @@ -290,12 +356,17 @@ static inline void hal_write32_mb_confirm(struct hal_soc *hal_soc, int ret; unsigned long flags; - if (offset > MAPPED_REF_OFF) { - ret = hal_force_wake_request(hal_soc); + /* Region < BAR + 4K can be directly accessed */ + if (offset < MAPPED_REF_OFF) { + qdf_iowrite32(hal_soc->dev_base_addr + offset, value); + return; + } + + /* Region greater than BAR + 4K */ + if (!hal_soc->init_phase) { + ret = hif_force_wake_request(hal_soc->hif_handle); if (ret) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up request failed %d\n", - __func__, ret); + hal_err("Wake up request failed"); qdf_check_state_before_panic(); return; } @@ -319,21 +390,23 @@ static inline void hal_write32_mb_confirm(struct hal_soc *hal_soc, hal_unlock_reg_access(hal_soc, &flags); } - if ((offset > MAPPED_REF_OFF) && - hal_force_wake_release(hal_soc)) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up release failed\n", __func__); + if (!hal_soc->init_phase) { + ret = hif_force_wake_release(hal_soc->hif_handle); + if (ret) { + hal_err("Wake up release failed"); + qdf_check_state_before_panic(); + return; + } + } } -#endif /** * hal_write_address_32_mb - write a value to a register * */ -static inline void hal_write_address_32_mb(struct hal_soc *hal_soc, - void __iomem *addr, uint32_t value, - bool wr_confirm) - +static inline +void hal_write_address_32_mb(struct hal_soc *hal_soc, + qdf_iomem_t addr, uint32_t value, bool wr_confirm) { uint32_t offset; @@ -342,14 +415,23 @@ static inline void hal_write_address_32_mb(struct hal_soc *hal_soc, offset = addr - hal_soc->dev_base_addr; - if (qdf_unlikely(wr_confirm)) hal_write32_mb_confirm(hal_soc, offset, value); else hal_write32_mb(hal_soc, offset, value); } +#endif -#if defined(FEATURE_HAL_DELAYED_REG_WRITE) + +#ifdef DP_HAL_MULTIWINDOW_DIRECT_ACCESS +static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, + struct hal_srng *srng, + void __iomem *addr, + uint32_t value) +{ + qdf_iowrite32(addr, value); +} +#elif defined(FEATURE_HAL_DELAYED_REG_WRITE) static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, struct hal_srng *srng, void __iomem *addr, @@ -367,7 +449,8 @@ static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc, } #endif -#ifndef QCA_WIFI_QCA6390 +#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) && \ + !defined(QCA_WIFI_QCA6750) /** * hal_read32_mb() - Access registers to read configuration * @hal_soc: hal soc handle @@ -393,10 +476,14 @@ static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) { uint32_t ret; unsigned long flags; + qdf_iomem_t new_addr; if (!hal_soc->use_register_windowing || offset < MAX_UNWINDOWED_ADDRESS) { return qdf_ioread32(hal_soc->dev_base_addr + offset); + } else if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, hal_soc->dev_base_addr + offset); + return qdf_ioread32(new_addr); } hal_lock_reg_access(hal_soc, &flags); @@ -407,59 +494,225 @@ static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) return ret; } - -/** - * hal_read_address_32_mb() - Read 32-bit value from the register - * @soc: soc handle - * @addr: register address to read - * - * Return: 32-bit value - */ -static inline uint32_t hal_read_address_32_mb(struct hal_soc *soc, - void __iomem *addr) -{ - uint32_t offset; - uint32_t ret; - - if (!soc->use_register_windowing) - return qdf_ioread32(addr); - - offset = addr - soc->dev_base_addr; - ret = hal_read32_mb(soc, offset); - return ret; -} #else -static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) +static +uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) { uint32_t ret; unsigned long flags; - if ((offset > MAPPED_REF_OFF) && - hal_force_wake_request(hal_soc)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up request failed\n", __func__); - return -EINVAL; + /* Region < BAR + 4K can be directly accessed */ + if (offset < MAPPED_REF_OFF) + return qdf_ioread32(hal_soc->dev_base_addr + offset); + + if ((!hal_soc->init_phase) && + hif_force_wake_request(hal_soc->hif_handle)) { + hal_err("Wake up request failed"); + qdf_check_state_before_panic(); + return 0; } if (!hal_soc->use_register_windowing || offset < MAX_UNWINDOWED_ADDRESS) { - return qdf_ioread32(hal_soc->dev_base_addr + offset); + ret = qdf_ioread32(hal_soc->dev_base_addr + offset); + } else { + hal_lock_reg_access(hal_soc, &flags); + hal_select_window_confirm(hal_soc, offset); + ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START + + (offset & WINDOW_RANGE_MASK)); + hal_unlock_reg_access(hal_soc, &flags); } - hal_lock_reg_access(hal_soc, &flags); - hal_select_window_confirm(hal_soc, offset); - ret = qdf_ioread32(hal_soc->dev_base_addr + WINDOW_START + - (offset & WINDOW_RANGE_MASK)); - hal_unlock_reg_access(hal_soc, &flags); + if ((!hal_soc->init_phase) && + hif_force_wake_release(hal_soc->hif_handle)) { + hal_err("Wake up release failed"); + qdf_check_state_before_panic(); + return 0; + } + + return ret; +} +#endif - if ((offset > MAPPED_REF_OFF) && - hal_force_wake_release(hal_soc)) - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Wake up release failed\n", __func__); +#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE +/* To check shadow config index range between 0..31 */ +#define HAL_SHADOW_REG_INDEX_LOW 32 +/* To check shadow config index range between 32..39 */ +#define HAL_SHADOW_REG_INDEX_HIGH 40 +/* Dirty bit reg offsets corresponding to shadow config index */ +#define HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET 0x30C8 +#define HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET 0x30C4 +/* PCIE_PCIE_TOP base addr offset */ +#define HAL_PCIE_PCIE_TOP_WRAPPER 0x01E00000 +/* Max retry attempts to read the dirty bit reg */ +#ifdef HAL_CONFIG_SLUB_DEBUG_ON +#define HAL_SHADOW_DIRTY_BIT_POLL_MAX 10000 +#else +#define HAL_SHADOW_DIRTY_BIT_POLL_MAX 2000 +#endif +/* Delay in usecs for polling dirty bit reg */ +#define HAL_SHADOW_DIRTY_BIT_POLL_DELAY 5 + +/** + * hal_poll_dirty_bit_reg() - Poll dirty register bit to confirm + * write was successful + * @hal_soc: hal soc handle + * @shadow_config_index: index of shadow reg used to confirm + * write + * + * Return: QDF_STATUS_SUCCESS on success + */ +static inline QDF_STATUS hal_poll_dirty_bit_reg(struct hal_soc *hal, + int shadow_config_index) +{ + uint32_t read_value = 0; + int retry_cnt = 0; + uint32_t reg_offset = 0; + + if (shadow_config_index > 0 && + shadow_config_index < HAL_SHADOW_REG_INDEX_LOW) { + reg_offset = + HAL_SHADOW_REG_DIRTY_BIT_DATA_LOW_OFFSET; + } else if (shadow_config_index >= HAL_SHADOW_REG_INDEX_LOW && + shadow_config_index < HAL_SHADOW_REG_INDEX_HIGH) { + reg_offset = + HAL_SHADOW_REG_DIRTY_BIT_DATA_HIGH_OFFSET; + } else { + hal_err("Invalid shadow_config_index = %d", + shadow_config_index); + return QDF_STATUS_E_INVAL; + } + while (retry_cnt < HAL_SHADOW_DIRTY_BIT_POLL_MAX) { + read_value = hal_read32_mb( + hal, HAL_PCIE_PCIE_TOP_WRAPPER + reg_offset); + /* Check if dirty bit corresponding to shadow_index is set */ + if (read_value & BIT(shadow_config_index)) { + /* Dirty reg bit not reset */ + qdf_udelay(HAL_SHADOW_DIRTY_BIT_POLL_DELAY); + retry_cnt++; + } else { + hal_debug("Shadow write: offset 0x%x read val 0x%x", + reg_offset, read_value); + return QDF_STATUS_SUCCESS; + } + } + return QDF_STATUS_E_TIMEOUT; +} +/** + * hal_write32_mb_shadow_confirm() - write to shadow reg and + * poll dirty register bit to confirm write + * @hal_soc: hal soc handle + * @reg_offset: target reg offset address from BAR + * @value: value to write + * + * Return: QDF_STATUS_SUCCESS on success + */ +static inline QDF_STATUS hal_write32_mb_shadow_confirm( + struct hal_soc *hal, + uint32_t reg_offset, + uint32_t value) +{ + int i; + QDF_STATUS ret; + uint32_t shadow_reg_offset; + uint32_t read_value; + int shadow_config_index; + bool is_reg_offset_present = false; + + for (i = 0; i < MAX_GENERIC_SHADOW_REG; i++) { + /* Found the shadow config for the reg_offset */ + struct shadow_reg_config *hal_shadow_reg_list = + &hal->list_shadow_reg_config[i]; + if (hal_shadow_reg_list->target_register == + reg_offset) { + shadow_config_index = + hal_shadow_reg_list->shadow_config_index; + shadow_reg_offset = + SHADOW_REGISTER(shadow_config_index); + hal_write32_mb_confirm( + hal, shadow_reg_offset, value); + is_reg_offset_present = true; + break; + } + ret = QDF_STATUS_E_FAILURE; + } + if (is_reg_offset_present) { + ret = hal_poll_dirty_bit_reg(hal, shadow_config_index); + read_value = hal_read32_mb(hal, reg_offset); + hal_info("Shadow retry:reg 0x%x val 0x%x readval 0x%x ret %d", + reg_offset, value, read_value, ret); + if (QDF_IS_STATUS_ERROR(ret)) { + HAL_STATS_INC(hal, shadow_reg_write_fail, 1); + return ret; + } + HAL_STATS_INC(hal, shadow_reg_write_succ, 1); + } return ret; } +#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ + +static inline QDF_STATUS hal_write32_mb_shadow_confirm( + struct hal_soc *hal_soc, + uint32_t offset, + uint32_t value) +{ + return QDF_STATUS_SUCCESS; +} + +#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ + +/* Max times allowed for register writing retry */ +#define HAL_REG_WRITE_RETRY_MAX 5 +/* Delay milliseconds for each time retry */ +#define HAL_REG_WRITE_RETRY_DELAY 1 + +/** + * hal_write32_mb_confirm_retry() - write register with confirming and + do retry/recovery if writing failed + * @hal_soc: hal soc handle + * @offset: offset address from the BAR + * @value: value to write + * @recovery: is recovery needed or not. + * + * Write the register value with confirming and read it back, if + * read back value is not as expected, do retry for writing, if + * retry hit max times allowed but still fail, check if recovery + * needed. + * + * Return: None + */ +static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc, + uint32_t offset, + uint32_t value, + bool recovery) +{ + uint8_t retry_cnt = 0; + uint32_t read_value; + QDF_STATUS ret; + + while (retry_cnt <= HAL_REG_WRITE_RETRY_MAX) { + hal_write32_mb_confirm(hal_soc, offset, value); + read_value = hal_read32_mb(hal_soc, offset); + if (qdf_likely(read_value == value)) + break; + + /* write failed, do retry */ + hal_warn("Retry reg offset 0x%x, value 0x%x, read value 0x%x", + offset, value, read_value); + qdf_mdelay(HAL_REG_WRITE_RETRY_DELAY); + retry_cnt++; + } + + if (retry_cnt > HAL_REG_WRITE_RETRY_MAX) { + ret = hal_write32_mb_shadow_confirm(hal_soc, offset, value); + if (QDF_IS_STATUS_ERROR(ret) && recovery) + qdf_trigger_self_recovery( + NULL, QDF_HAL_REG_WRITE_FAILURE); + } +} + #ifdef FEATURE_HAL_DELAYED_REG_WRITE /** * hal_dump_reg_write_srng_stats() - dump SRNG reg write stats @@ -467,7 +720,7 @@ static inline uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) * * Return: none */ -void hal_dump_reg_write_srng_stats(struct hal_soc *hal_soc_hdl); +void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl); /** * hal_dump_reg_write_stats() - dump reg write stats @@ -475,7 +728,7 @@ void hal_dump_reg_write_srng_stats(struct hal_soc *hal_soc_hdl); * * Return: none */ -void hal_dump_reg_write_stats(struct hal_soc *hal_soc_hdl); +void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl); /** * hal_get_reg_write_pending_work() - get the number of entries @@ -487,11 +740,11 @@ void hal_dump_reg_write_stats(struct hal_soc *hal_soc_hdl); int hal_get_reg_write_pending_work(void *hal_soc); #else -static inline void hal_dump_reg_write_srng_stats(struct hal_soc *hal_soc_hdl) +static inline void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl) { } -static inline void hal_dump_reg_write_stats(struct hal_soc *hal_soc_hdl) +static inline void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl) { } @@ -509,21 +762,25 @@ static inline int hal_get_reg_write_pending_work(void *hal_soc) * Return: 32-bit value */ static inline -uint32_t hal_read_address_32_mb(struct hal_soc *soc, void __iomem *addr) +uint32_t hal_read_address_32_mb(struct hal_soc *soc, + qdf_iomem_t addr) { uint32_t offset; uint32_t ret; + qdf_iomem_t new_addr; if (!soc->use_register_windowing) return qdf_ioread32(addr); offset = addr - soc->dev_base_addr; + if (soc->static_window_map) { + new_addr = hal_get_window_address(soc, addr); + return qdf_ioread32(new_addr); + } + ret = hal_read32_mb(soc, offset); return ret; } -#endif - -#include "hif_io32.h" /** * hal_attach - Initialize HAL layer @@ -536,7 +793,7 @@ uint32_t hal_read_address_32_mb(struct hal_soc *soc, void __iomem *addr) * This function should be called as part of HIF initialization (for accessing * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle() */ -extern void *hal_attach(void *hif_handle, qdf_device_t qdf_dev); +void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev); /** * hal_detach - Detach HAL layer @@ -585,10 +842,34 @@ enum hal_ring_type { #define HAL_SRNG_MSI_INTR 0x00020000 #define HAL_SRNG_CACHED_DESC 0x00040000 +#ifdef QCA_WIFI_QCA6490 +#define HAL_SRNG_PREFETCH_TIMER 1 +#else +#define HAL_SRNG_PREFETCH_TIMER 0 +#endif + #define PN_SIZE_24 0 #define PN_SIZE_48 1 #define PN_SIZE_128 2 +#ifdef FORCE_WAKE +/** + * hal_set_init_phase() - Indicate initialization of + * datapath rings + * @soc: hal_soc handle + * @init_phase: flag to indicate datapath rings + * initialization status + * + * Return: None + */ +void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase); +#else +static inline +void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase) +{ +} +#endif /* FORCE_WAKE */ + /** * hal_srng_get_entrysize - Returns size of ring entry in bytes. Should be * used by callers for calculating the size of memory to be allocated before @@ -672,14 +953,17 @@ struct hal_srng_params { uint32_t entry_size; /* hw register base address */ void *hwreg_base[MAX_SRNG_REG_GROUPS]; + /* prefetch timer config - in micro seconds */ + uint32_t prefetch_timer; }; -/* hal_construct_shadow_config() - initialize the shadow registers for dp rings +/* hal_construct_srng_shadow_regs() - initialize the shadow + * registers for srngs * @hal_soc: hal handle * * Return: QDF_STATUS_OK on success */ -extern QDF_STATUS hal_construct_shadow_config(void *hal_soc); +QDF_STATUS hal_construct_srng_shadow_regs(void *hal_soc); /* hal_set_one_shadow_config() - add a config for the specified ring * @hal_soc: hal handle @@ -696,8 +980,8 @@ extern QDF_STATUS hal_construct_shadow_config(void *hal_soc); * * Return: QDF_STATUS_OK on success */ -extern QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type, - int ring_num); +QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type, + int ring_num); /** * hal_get_shadow_config() - retrieve the config table * @hal_soc: hal handle @@ -749,54 +1033,83 @@ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, DESTINATION_RING_ ## _OFFSET ## _SHFT)) /* - * currently this macro only works for IX0 since all the rings we are remapping - * can be remapped from HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0 - */ -#define HAL_REO_REMAP_VAL(_ORIGINAL_DEST, _NEW_DEST) \ - HAL_REO_REMAP_VAL_(_ORIGINAL_DEST, _NEW_DEST) -/* allow the destination macros to be expanded */ -#define HAL_REO_REMAP_VAL_(_ORIGINAL_DEST, _NEW_DEST) \ - (_NEW_DEST << \ + * Macro to access HWIO_REO_R0_ERROR_DESTINATION_RING_CTRL_IX_1 + * to map destination to rings + */ +#define HAL_REO_ERR_REMAP_IX1(_VALUE, _OFFSET) \ + ((_VALUE) << \ + (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ERROR_ ## \ + DESTINATION_RING_ ## _OFFSET ## _SHFT)) + +/* + * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0 + * to map destination to rings + */ +#define HAL_REO_REMAP_IX0(_VALUE, _OFFSET) \ + ((_VALUE) << \ (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_DEST_RING_MAPPING_ ## \ - _ORIGINAL_DEST ## _SHFT)) + _OFFSET ## _SHFT)) + +/* + * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1 + * to map destination to rings + */ +#define HAL_REO_REMAP_IX2(_VALUE, _OFFSET) \ + ((_VALUE) << \ + (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_DEST_RING_MAPPING_ ## \ + _OFFSET ## _SHFT)) + +/* + * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3 + * to map destination to rings + */ +#define HAL_REO_REMAP_IX3(_VALUE, _OFFSET) \ + ((_VALUE) << \ + (HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_DEST_RING_MAPPING_ ## \ + _OFFSET ## _SHFT)) /** * hal_reo_read_write_ctrl_ix - Read or write REO_DESTINATION_RING_CTRL_IX - * @hal: HAL SOC handle + * @hal_soc_hdl: HAL SOC handle * @read: boolean value to indicate if read or write * @ix0: pointer to store IX0 reg value * @ix1: pointer to store IX1 reg value * @ix2: pointer to store IX2 reg value * @ix3: pointer to store IX3 reg value */ -extern void hal_reo_read_write_ctrl_ix(struct hal_soc *hal, bool read, - uint32_t *ix0, uint32_t *ix1, - uint32_t *ix2, uint32_t *ix3); +void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read, + uint32_t *ix0, uint32_t *ix1, + uint32_t *ix2, uint32_t *ix3); /** - * hal_srng_set_hp_paddr() - Set physical address to dest SRNG head pointer + * hal_srng_set_hp_paddr_confirm() - Set physical address to dest SRNG head + * pointer and confirm that write went through by reading back the value * @sring: sring pointer * @paddr: physical address */ -extern void hal_srng_dst_set_hp_paddr(struct hal_srng *sring, uint64_t paddr); +extern void hal_srng_dst_set_hp_paddr_confirm(struct hal_srng *sring, + uint64_t paddr); /** * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer + * @hal_soc: hal_soc handle * @srng: sring pointer * @vaddr: virtual address */ -extern void hal_srng_dst_init_hp(struct hal_srng *srng, uint32_t *vaddr); +void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, + struct hal_srng *srng, + uint32_t *vaddr); /** * hal_srng_cleanup - Deinitialize HW SRNG ring. * @hal_soc: Opaque HAL SOC handle * @hal_srng: Opaque HAL SRNG pointer */ -extern void hal_srng_cleanup(void *hal_soc, void *hal_srng); +void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl); -static inline bool hal_srng_initialized(void *hal_ring) +static inline bool hal_srng_initialized(hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; return !!srng->initialized; } @@ -804,16 +1117,17 @@ static inline bool hal_srng_initialized(void *hal_ring) /** * hal_srng_dst_peek - Check if there are any entries in the ring (peek) * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * * Caller takes responsibility for any locking needs. * * Return: Opaque pointer for next ring entry; NULL on failire */ static inline -void *hal_srng_dst_peek(void *hal_soc, void *hal_ring) +void *hal_srng_dst_peek(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) return (void *)(&srng->ring_base_vaddr[srng->u.dst_ring.tp]); @@ -826,14 +1140,16 @@ void *hal_srng_dst_peek(void *hal_soc, void *hal_ring) * hal_srng_access_start if locked access is required * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * * Return: 0 on success; error on failire */ -static inline int hal_srng_access_start_unlocked(void *hal_soc, void *hal_ring) +static inline int +hal_srng_access_start_unlocked(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; - struct hal_soc *soc = (struct hal_soc *)hal_soc; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; uint32_t *desc; if (srng->ring_dir == HAL_SRNG_SRC_RING) @@ -844,7 +1160,7 @@ static inline int hal_srng_access_start_unlocked(void *hal_soc, void *hal_ring) *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); if (srng->flags & HAL_SRNG_CACHED_DESC) { - desc = hal_srng_dst_peek(hal_soc, hal_ring); + desc = hal_srng_dst_peek(hal_soc_hdl, hal_ring_hdl); if (qdf_likely(desc)) { qdf_mem_dma_cache_sync(soc->qdf_dev, qdf_mem_virt_to_phys @@ -864,22 +1180,23 @@ static inline int hal_srng_access_start_unlocked(void *hal_soc, void *hal_ring) * hal_srng_access_start - Start (locked) ring access * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * * Return: 0 on success; error on failire */ -static inline int hal_srng_access_start(void *hal_soc, void *hal_ring) +static inline int hal_srng_access_start(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; - if (qdf_unlikely(!hal_ring)) { + if (qdf_unlikely(!hal_ring_hdl)) { qdf_print("Error: Invalid hal_ring\n"); return -EINVAL; } SRNG_LOCK(&(srng->lock)); - return hal_srng_access_start_unlocked(hal_soc, hal_ring); + return hal_srng_access_start_unlocked(hal_soc_hdl, hal_ring_hdl); } /** @@ -887,13 +1204,15 @@ static inline int hal_srng_access_start(void *hal_soc, void *hal_ring) * cached tail pointer * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_dst_get_next(void *hal_soc, void *hal_ring) +static inline +void *hal_srng_dst_get_next(void *hal_soc, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; struct hal_soc *soc = (struct hal_soc *)hal_soc; uint32_t *desc; uint32_t *desc_next; @@ -932,13 +1251,15 @@ static inline void *hal_srng_dst_get_next(void *hal_soc, void *hal_ring) * cached head pointer * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_dst_get_next_hp(void *hal_soc, void *hal_ring) +static inline void * +hal_srng_dst_get_next_hp(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; /* TODO: Using % is expensive, but we have to do this since * size of some SRNG rings is not power of 2 (due to descriptor @@ -961,7 +1282,7 @@ static inline void *hal_srng_dst_get_next_hp(void *hal_soc, void *hal_ring) /** * hal_srng_dst_peek_sync - Check if there are any entries in the ring (peek) * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * * Sync cached head pointer with HW. * Caller takes responsibility for any locking needs. @@ -969,9 +1290,10 @@ static inline void *hal_srng_dst_get_next_hp(void *hal_soc, void *hal_ring) * Return: Opaque pointer for next ring entry; NULL on failire */ static inline -void *hal_srng_dst_peek_sync(void *hal_soc, void *hal_ring) +void *hal_srng_dst_peek_sync(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; srng->u.dst_ring.cached_hp = *(volatile uint32_t *)(srng->u.dst_ring.hp_addr); @@ -985,7 +1307,7 @@ void *hal_srng_dst_peek_sync(void *hal_soc, void *hal_ring) /** * hal_srng_dst_peek_sync_locked - Peek for any entries in the ring * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * * Sync cached head pointer with HW. * This function takes up SRNG_LOCK. Should not be called with SRNG lock held. @@ -993,19 +1315,20 @@ void *hal_srng_dst_peek_sync(void *hal_soc, void *hal_ring) * Return: Opaque pointer for next ring entry; NULL on failire */ static inline -void *hal_srng_dst_peek_sync_locked(void *hal_soc, void *hal_ring) +void *hal_srng_dst_peek_sync_locked(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; void *ring_desc_ptr = NULL; - if (qdf_unlikely(!hal_ring)) { + if (qdf_unlikely(!hal_ring_hdl)) { qdf_print("Error: Invalid hal_ring\n"); return NULL; } SRNG_LOCK(&srng->lock); - ring_desc_ptr = hal_srng_dst_peek_sync(hal_soc, hal_ring); + ring_desc_ptr = hal_srng_dst_peek_sync(hal_soc_hdl, hal_ring_hdl); SRNG_UNLOCK(&srng->lock); @@ -1017,14 +1340,16 @@ void *hal_srng_dst_peek_sync_locked(void *hal_soc, void *hal_ring) * by SW) in destination ring * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Destination ring pointer + * @hal_ring_hdl: Destination ring pointer * @sync_hw_ptr: Sync cached head pointer with HW * */ -static inline uint32_t hal_srng_dst_num_valid(void *hal_soc, void *hal_ring, - int sync_hw_ptr) +static inline +uint32_t hal_srng_dst_num_valid(void *hal_soc, + hal_ring_handle_t hal_ring_hdl, + int sync_hw_ptr) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t hp; uint32_t tp = srng->u.dst_ring.tp; @@ -1054,8 +1379,8 @@ static inline uint32_t hal_srng_dst_num_valid(void *hal_soc, void *hal_ring, * Return: Number of valid destination entries */ static inline uint32_t -hal_srng_dst_num_valid_locked(void *hal_soc, - void *hal_ring_hdl, +hal_srng_dst_num_valid_locked(hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, int sync_hw_ptr) { uint32_t num_valid; @@ -1076,13 +1401,14 @@ hal_srng_dst_num_valid_locked(void *hal_soc, * hal_srng_src_get_next_reaped when this function is used for reaping. * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_src_reap_next(void *hal_soc, void *hal_ring) +static inline void * +hal_srng_src_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; /* TODO: Using % is expensive, but we have to do this since @@ -1109,13 +1435,14 @@ static inline void *hal_srng_src_reap_next(void *hal_soc, void *hal_ring) * the ring * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next (reaped) source ring entry; NULL on failire */ -static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring) +static inline void * +hal_srng_src_get_next_reaped(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; if (srng->u.src_ring.hp != srng->u.src_ring.reap_hp) { @@ -1135,13 +1462,14 @@ static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring) * associated with ring entries which are pending reap. * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_src_pending_reap_next(void *hal_soc, void *hal_ring) +static inline void * +hal_srng_src_pending_reap_next(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % @@ -1160,13 +1488,14 @@ static inline void *hal_srng_src_pending_reap_next(void *hal_soc, void *hal_ring * hal_srng_src_done_val - * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline uint32_t hal_srng_src_done_val(void *hal_soc, void *hal_ring) +static inline uint32_t +hal_srng_src_done_val(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; /* TODO: Using % is expensive, but we have to do this since * size of some SRNG rings is not power of 2 (due to descriptor * sizes). Need to create separate API for rings used @@ -1189,14 +1518,14 @@ static inline uint32_t hal_srng_src_done_val(void *hal_soc, void *hal_ring) /** * hal_get_entrysize_from_srng() - Retrieve ring entry size - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: uint8_t */ static inline -uint8_t hal_get_entrysize_from_srng(void *hal_ring) +uint8_t hal_get_entrysize_from_srng(hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; return srng->entry_size; } @@ -1204,16 +1533,17 @@ uint8_t hal_get_entrysize_from_srng(void *hal_ring) /** * hal_get_sw_hptp - Get SW head and tail pointer location for any ring * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * @tailp: Tail Pointer * @headp: Head Pointer * * Return: Update tail pointer and head pointer in arguments. */ -static inline void hal_get_sw_hptp(void *hal_soc, void *hal_ring, - uint32_t *tailp, uint32_t *headp) +static inline +void hal_get_sw_hptp(void *hal_soc, hal_ring_handle_t hal_ring_hdl, + uint32_t *tailp, uint32_t *headp) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; if (srng->ring_dir == HAL_SRNG_SRC_RING) { *headp = srng->u.src_ring.hp; @@ -1228,13 +1558,15 @@ static inline void hal_get_sw_hptp(void *hal_soc, void *hal_ring, * hal_srng_src_get_next - Get next entry from a source ring and move cached tail pointer * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_src_get_next(void *hal_soc, void *hal_ring) +static inline +void *hal_srng_src_get_next(void *hal_soc, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; /* TODO: Using % is expensive, but we have to do this since * size of some SRNG rings is not power of 2 (due to descriptor @@ -1265,13 +1597,15 @@ static inline void *hal_srng_src_get_next(void *hal_soc, void *hal_ring) * hal_srng_src_get_next should be called subsequently to move the head pointer * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: Opaque pointer for next ring entry; NULL on failire */ -static inline void *hal_srng_src_peek(void *hal_soc, void *hal_ring) +static inline +void *hal_srng_src_peek(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; /* TODO: Using % is expensive, but we have to do this since @@ -1293,14 +1627,15 @@ static inline void *hal_srng_src_peek(void *hal_soc, void *hal_ring) * hal_srng_src_num_avail - Returns number of available entries in src ring * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * @sync_hw_ptr: Sync cached tail pointer with HW * */ -static inline uint32_t hal_srng_src_num_avail(void *hal_soc, - void *hal_ring, int sync_hw_ptr) +static inline uint32_t +hal_srng_src_num_avail(void *hal_soc, + hal_ring_handle_t hal_ring_hdl, int sync_hw_ptr) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t tp; uint32_t hp = srng->u.src_ring.hp; @@ -1324,13 +1659,14 @@ static inline uint32_t hal_srng_src_num_avail(void *hal_soc, * access * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * * Return: 0 on success; error on failire */ -static inline void hal_srng_access_end_unlocked(void *hal_soc, void *hal_ring) +static inline void +hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; /* TODO: See if we need a write memory barrier here */ if (srng->flags & HAL_SRNG_LMAC_RING) { @@ -1362,20 +1698,21 @@ static inline void hal_srng_access_end_unlocked(void *hal_soc, void *hal_ring) * This should be used only if hal_srng_access_start to start ring access * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * * Return: 0 on success; error on failire */ -static inline void hal_srng_access_end(void *hal_soc, void *hal_ring) +static inline void +hal_srng_access_end(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; - if (qdf_unlikely(!hal_ring)) { + if (qdf_unlikely(!hal_ring_hdl)) { qdf_print("Error: Invalid hal_ring\n"); return; } - hal_srng_access_end_unlocked(hal_soc, hal_ring); + hal_srng_access_end_unlocked(hal_soc, hal_ring_hdl); SRNG_UNLOCK(&(srng->lock)); } @@ -1385,13 +1722,14 @@ static inline void hal_srng_access_end(void *hal_soc, void *hal_ring) * and should be used only while reaping SRC ring completions * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * * Return: 0 on success; error on failire */ -static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring) +static inline void +hal_srng_access_end_reap(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; SRNG_UNLOCK(&(srng->lock)); } @@ -1425,7 +1763,8 @@ static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_idle_list_scatter_buf_size(void *hal_soc) +static inline +uint32_t hal_idle_list_scatter_buf_size(hal_soc_handle_t hal_soc_hdl) { return WBM_IDLE_SCATTER_BUF_SIZE; } @@ -1436,8 +1775,10 @@ static inline uint32_t hal_idle_list_scatter_buf_size(void *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_get_link_desc_size(struct hal_soc *hal_soc) +static inline uint32_t hal_get_link_desc_size(hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + if (!hal_soc || !hal_soc->ops) { qdf_print("Error: Invalid ops\n"); QDF_BUG(0); @@ -1458,7 +1799,8 @@ static inline uint32_t hal_get_link_desc_size(struct hal_soc *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_get_link_desc_align(void *hal_soc) +static inline +uint32_t hal_get_link_desc_align(hal_soc_handle_t hal_soc_hdl) { return LINK_DESC_ALIGN; } @@ -1469,7 +1811,8 @@ static inline uint32_t hal_get_link_desc_align(void *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_num_mpdus_per_link_desc(void *hal_soc) +static inline +uint32_t hal_num_mpdus_per_link_desc(hal_soc_handle_t hal_soc_hdl) { return NUM_MPDUS_PER_LINK_DESC; } @@ -1480,7 +1823,8 @@ static inline uint32_t hal_num_mpdus_per_link_desc(void *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_num_msdus_per_link_desc(void *hal_soc) +static inline +uint32_t hal_num_msdus_per_link_desc(hal_soc_handle_t hal_soc_hdl) { return NUM_MSDUS_PER_LINK_DESC; } @@ -1492,7 +1836,8 @@ static inline uint32_t hal_num_msdus_per_link_desc(void *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_num_mpdu_links_per_queue_desc(void *hal_soc) +static inline +uint32_t hal_num_mpdu_links_per_queue_desc(hal_soc_handle_t hal_soc_hdl) { return NUM_MPDU_LINKS_PER_QUEUE_DESC; } @@ -1505,11 +1850,12 @@ static inline uint32_t hal_num_mpdu_links_per_queue_desc(void *hal_soc) * @scatter_buf_size: Size of scatter buffer * */ -static inline uint32_t hal_idle_scatter_buf_num_entries(void *hal_soc, - uint32_t scatter_buf_size) +static inline +uint32_t hal_idle_scatter_buf_num_entries(hal_soc_handle_t hal_soc_hdl, + uint32_t scatter_buf_size) { return (scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) / - hal_srng_get_entrysize(hal_soc, WBM_IDLE_LINK); + hal_srng_get_entrysize(hal_soc_hdl, WBM_IDLE_LINK); } /** @@ -1521,8 +1867,10 @@ static inline uint32_t hal_idle_scatter_buf_num_entries(void *hal_soc, * @scatter_buf_size: Size of scatter buffer * */ -static inline uint32_t hal_idle_list_num_scatter_bufs(void *hal_soc, - uint32_t total_mem, uint32_t scatter_buf_size) +static inline +uint32_t hal_idle_list_num_scatter_bufs(hal_soc_handle_t hal_soc_hdl, + uint32_t total_mem, + uint32_t scatter_buf_size) { uint8_t rem = (total_mem % (scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) ? 1 : 0; @@ -1533,21 +1881,6 @@ static inline uint32_t hal_idle_list_num_scatter_bufs(void *hal_soc, return num_scatter_bufs; } -/* REO parameters to be passed to hal_reo_setup */ -struct hal_reo_params { - /** rx hash steering enabled or disabled */ - bool rx_hash_enabled; - /** reo remap 1 register */ - uint32_t remap1; - /** reo remap 2 register */ - uint32_t remap2; - /** fragment destination ring */ - uint8_t frag_dst_ring; - /** padding */ - uint8_t padding[3]; -}; - - enum hal_pn_type { HAL_PN_NONE, HAL_PN_WPA, @@ -1564,7 +1897,8 @@ enum hal_pn_type { * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_get_reo_qdesc_align(void *hal_soc) +static inline +uint32_t hal_get_reo_qdesc_align(hal_soc_handle_t hal_soc_hdl) { return REO_QUEUE_DESC_ALIGN; } @@ -1580,20 +1914,24 @@ static inline uint32_t hal_get_reo_qdesc_align(void *hal_soc) * @pn_type: PN type (one of the types defined in 'enum hal_pn_type') * */ -extern void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size, - uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type); +void hal_reo_qdesc_setup(hal_soc_handle_t hal_soc_hdl, + int tid, uint32_t ba_window_size, + uint32_t start_seq, void *hw_qdesc_vaddr, + qdf_dma_addr_t hw_qdesc_paddr, + int pn_type); /** * hal_srng_get_hp_addr - Get head pointer physical address * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * */ -static inline qdf_dma_addr_t hal_srng_get_hp_addr(void *hal_soc, void *hal_ring) +static inline qdf_dma_addr_t +hal_srng_get_hp_addr(void *hal_soc, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; struct hal_soc *hal = (struct hal_soc *)hal_soc; if (srng->ring_dir == HAL_SRNG_SRC_RING) { @@ -1611,12 +1949,13 @@ static inline qdf_dma_addr_t hal_srng_get_hp_addr(void *hal_soc, void *hal_ring) * hal_srng_get_tp_addr - Get tail pointer physical address * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * */ -static inline qdf_dma_addr_t hal_srng_get_tp_addr(void *hal_soc, void *hal_ring) +static inline qdf_dma_addr_t +hal_srng_get_tp_addr(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; struct hal_soc *hal = (struct hal_soc *)hal_soc; if (srng->ring_dir == HAL_SRNG_SRC_RING) { @@ -1639,8 +1978,8 @@ static inline qdf_dma_addr_t hal_srng_get_tp_addr(void *hal_soc, void *hal_ring) * Return: total number of entries in hal ring */ static inline -uint32_t hal_srng_get_num_entries(void *hal_soc_hdl, - void *hal_ring_hdl) +uint32_t hal_srng_get_num_entries(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; @@ -1651,11 +1990,12 @@ uint32_t hal_srng_get_num_entries(void *hal_soc_hdl, * hal_get_srng_params - Retrieve SRNG parameters for a given ring from HAL * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Ring pointer (Source or Destination ring) + * @hal_ring_hdl: Ring pointer (Source or Destination ring) * @ring_params: SRNG parameters will be returned through this structure */ -extern void hal_get_srng_params(void *hal_soc, void *hal_ring, - struct hal_srng_params *ring_params); +void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + struct hal_srng_params *ring_params); /** * hal_mem_info - Retrieve hal memory base address @@ -1663,14 +2003,14 @@ extern void hal_get_srng_params(void *hal_soc, void *hal_ring, * @hal_soc: Opaque HAL SOC handle * @mem: pointer to structure to be updated with hal mem info */ -extern void hal_get_meminfo(void *hal_soc,struct hal_mem_info *mem ); +void hal_get_meminfo(hal_soc_handle_t hal_soc_hdl, struct hal_mem_info *mem); /** * hal_get_target_type - Return target type * * @hal_soc: Opaque HAL SOC handle */ -uint32_t hal_get_target_type(struct hal_soc *hal); +uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl); /** * hal_get_ba_aging_timeout - Retrieve BA aging timeout @@ -1679,7 +2019,7 @@ uint32_t hal_get_target_type(struct hal_soc *hal); * @ac: Access category * @value: timeout duration in millisec */ -void hal_get_ba_aging_timeout(void *hal_soc, uint8_t ac, +void hal_get_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac, uint32_t *value); /** * hal_set_aging_timeout - Set BA aging timeout @@ -1688,7 +2028,7 @@ void hal_get_ba_aging_timeout(void *hal_soc, uint8_t ac, * @ac: Access category in millisec * @value: timeout duration value */ -void hal_set_ba_aging_timeout(void *hal_soc, uint8_t ac, +void hal_set_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac, uint32_t value); /** * hal_srng_dst_hw_init - Private function to initialize SRNG @@ -1717,18 +2057,23 @@ static inline void hal_srng_src_hw_init(struct hal_soc *hal, /** * hal_get_hw_hptp() - Get HW head and tail pointer value for any ring * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * @headp: Head Pointer * @tailp: Tail Pointer * @ring_type: Ring * * Return: Update tail pointer and head pointer in arguments. */ -static inline void hal_get_hw_hptp(struct hal_soc *hal, void *hal_ring, - uint32_t *headp, uint32_t *tailp, - uint8_t ring_type) +static inline +void hal_get_hw_hptp(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + uint32_t *headp, uint32_t *tailp, + uint8_t ring_type) { - hal->ops->hal_get_hw_hptp(hal, hal_ring, headp, tailp, ring_type); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + hal_soc->ops->hal_get_hw_hptp(hal_soc, hal_ring_hdl, + headp, tailp, ring_type); } /** @@ -1737,12 +2082,12 @@ static inline void hal_get_hw_hptp(struct hal_soc *hal, void *hal_ring, * @hal_soc: Opaque HAL SOC handle * @reo_params: parameters needed by HAL for REO config */ -static inline void hal_reo_setup(void *halsoc, - void *reoparams) +static inline void hal_reo_setup(hal_soc_handle_t hal_soc_hdl, + void *reoparams) { - struct hal_soc *hal_soc = (struct hal_soc *)halsoc; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - hal_soc->ops->hal_reo_setup(halsoc, reoparams); + hal_soc->ops->hal_reo_setup(hal_soc, reoparams); } /** @@ -1758,32 +2103,108 @@ static inline void hal_reo_setup(void *halsoc, * @num_entries: Total entries of all scatter bufs * */ -static inline void hal_setup_link_idle_list(void *halsoc, - qdf_dma_addr_t scatter_bufs_base_paddr[], - void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs, - uint32_t scatter_buf_size, uint32_t last_buf_end_offset, - uint32_t num_entries) +static inline +void hal_setup_link_idle_list(hal_soc_handle_t hal_soc_hdl, + qdf_dma_addr_t scatter_bufs_base_paddr[], + void *scatter_bufs_base_vaddr[], + uint32_t num_scatter_bufs, + uint32_t scatter_buf_size, + uint32_t last_buf_end_offset, + uint32_t num_entries) { - struct hal_soc *hal_soc = (struct hal_soc *)halsoc; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - hal_soc->ops->hal_setup_link_idle_list(halsoc, scatter_bufs_base_paddr, + hal_soc->ops->hal_setup_link_idle_list(hal_soc, scatter_bufs_base_paddr, scatter_bufs_base_vaddr, num_scatter_bufs, scatter_buf_size, last_buf_end_offset, num_entries); } +#ifdef DUMP_REO_QUEUE_INFO_IN_DDR +/** + * hal_dump_rx_reo_queue_desc() - Dump reo queue descriptor fields + * @hw_qdesc_vaddr_aligned: Pointer to hw reo queue desc virtual addr + * + * Use the virtual addr pointer to reo h/w queue desc to read + * the values from ddr and log them. + * + * Return: none + */ +static inline void hal_dump_rx_reo_queue_desc( + void *hw_qdesc_vaddr_aligned) +{ + struct rx_reo_queue *hw_qdesc = + (struct rx_reo_queue *)hw_qdesc_vaddr_aligned; + + if (!hw_qdesc) + return; + + hal_info("receive_queue_number %u vld %u window_jump_2k %u" + " hole_count %u ba_window_size %u ignore_ampdu_flag %u" + " svld %u ssn %u current_index %u" + " disable_duplicate_detection %u soft_reorder_enable %u" + " chk_2k_mode %u oor_mode %u mpdu_frames_processed_count %u" + " msdu_frames_processed_count %u total_processed_byte_count %u" + " late_receive_mpdu_count %u seq_2k_error_detected_flag %u" + " pn_error_detected_flag %u current_mpdu_count %u" + " current_msdu_count %u timeout_count %u" + " forward_due_to_bar_count %u duplicate_count %u" + " frames_in_order_count %u bar_received_count %u" + " pn_check_needed %u pn_shall_be_even %u" + " pn_shall_be_uneven %u pn_size %u", + hw_qdesc->receive_queue_number, + hw_qdesc->vld, + hw_qdesc->window_jump_2k, + hw_qdesc->hole_count, + hw_qdesc->ba_window_size, + hw_qdesc->ignore_ampdu_flag, + hw_qdesc->svld, + hw_qdesc->ssn, + hw_qdesc->current_index, + hw_qdesc->disable_duplicate_detection, + hw_qdesc->soft_reorder_enable, + hw_qdesc->chk_2k_mode, + hw_qdesc->oor_mode, + hw_qdesc->mpdu_frames_processed_count, + hw_qdesc->msdu_frames_processed_count, + hw_qdesc->total_processed_byte_count, + hw_qdesc->late_receive_mpdu_count, + hw_qdesc->seq_2k_error_detected_flag, + hw_qdesc->pn_error_detected_flag, + hw_qdesc->current_mpdu_count, + hw_qdesc->current_msdu_count, + hw_qdesc->timeout_count, + hw_qdesc->forward_due_to_bar_count, + hw_qdesc->duplicate_count, + hw_qdesc->frames_in_order_count, + hw_qdesc->bar_received_count, + hw_qdesc->pn_check_needed, + hw_qdesc->pn_shall_be_even, + hw_qdesc->pn_shall_be_uneven, + hw_qdesc->pn_size); +} + +#else /* DUMP_REO_QUEUE_INFO_IN_DDR */ + +static inline void hal_dump_rx_reo_queue_desc( + void *hw_qdesc_vaddr_aligned) +{ +} +#endif /* DUMP_REO_QUEUE_INFO_IN_DDR */ + /** * hal_srng_dump_ring_desc() - Dump ring descriptor info * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer * @ring_desc: Opaque ring descriptor handle */ -static inline void hal_srng_dump_ring_desc(struct hal_soc *hal, void *hal_ring, - void *ring_desc) +static inline void hal_srng_dump_ring_desc(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, ring_desc, (srng->entry_size << 2)); @@ -1793,11 +2214,12 @@ static inline void hal_srng_dump_ring_desc(struct hal_soc *hal, void *hal_ring, * hal_srng_dump_ring() - Dump last 128 descs of the ring * * @hal_soc: Opaque HAL SOC handle - * @hal_ring: Source ring pointer + * @hal_ring_hdl: Source ring pointer */ -static inline void hal_srng_dump_ring(struct hal_soc *hal, void *hal_ring) +static inline void hal_srng_dump_ring(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; uint32_t *desc; uint32_t tp, i; @@ -1816,61 +2238,86 @@ static inline void hal_srng_dump_ring(struct hal_soc *hal, void *hal_ring) } } +/* + * hal_rxdma_desc_to_hal_ring_desc - API to convert rxdma ring desc + * to opaque dp_ring desc type + * @ring_desc - rxdma ring desc + * + * Return: hal_rxdma_desc_t type + */ +static inline +hal_ring_desc_t hal_rxdma_desc_to_hal_ring_desc(hal_rxdma_desc_t ring_desc) +{ + return (hal_ring_desc_t)ring_desc; +} + /** * hal_srng_set_event() - Set hal_srng event - * @srng: SRNG ring pointer + * @hal_ring_hdl: Source ring pointer * @event: SRNG ring event * * Return: None */ -static inline void hal_srng_set_event(struct hal_srng *srng, int event) +static inline void hal_srng_set_event(hal_ring_handle_t hal_ring_hdl, int event) { + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + qdf_atomic_set_bit(event, &srng->srng_event); } /** * hal_srng_clear_event() - Clear hal_srng event - * @srng: SRNG ring pointer + * @hal_ring_hdl: Source ring pointer * @event: SRNG ring event * * Return: None */ -static inline void hal_srng_clear_event(struct hal_srng *srng, int event) +static inline +void hal_srng_clear_event(hal_ring_handle_t hal_ring_hdl, int event) { + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + qdf_atomic_clear_bit(event, &srng->srng_event); } /** * hal_srng_get_clear_event() - Clear srng event and return old value - * @srng: SRNG ring pointer + * @hal_ring_hdl: Source ring pointer * @event: SRNG ring event * * Return: Return old event value */ -static inline int hal_srng_get_clear_event(struct hal_srng *srng, int event) +static inline +int hal_srng_get_clear_event(hal_ring_handle_t hal_ring_hdl, int event) { + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + return qdf_atomic_test_and_clear_bit(event, &srng->srng_event); } /** * hal_srng_set_flush_last_ts() - Record last flush time stamp - * @srng: SRNG ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: None */ -static inline void hal_srng_set_flush_last_ts(struct hal_srng *srng) +static inline void hal_srng_set_flush_last_ts(hal_ring_handle_t hal_ring_hdl) { + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + srng->last_flush_ts = qdf_get_log_timestamp(); } /** * hal_srng_inc_flush_cnt() - Increment flush counter - * @srng: Source ring pointer + * @hal_ring_hdl: Source ring pointer * * Return: None */ -static inline void hal_srng_inc_flush_cnt(struct hal_srng *srng) +static inline void hal_srng_inc_flush_cnt(hal_ring_handle_t hal_ring_hdl) { + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + srng->flush_count++; } @@ -1878,12 +2325,70 @@ static inline void hal_srng_inc_flush_cnt(struct hal_srng *srng) * hal_reo_set_err_dst_remap() - Set REO error destination ring remap * register value. * - * @hal_soc: Opaque HAL soc handle + * @hal_soc_hdl: Opaque HAL soc handle * * Return: None */ -static inline void hal_reo_set_err_dst_remap(struct hal_soc *hal_soc) +static inline void hal_reo_set_err_dst_remap(hal_soc_handle_t hal_soc_hdl) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (hal_soc->ops->hal_reo_set_err_dst_remap) + hal_soc->ops->hal_reo_set_err_dst_remap(hal_soc); +} + +#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE + +/** + * hal_set_one_target_reg_config() - Populate the target reg + * offset in hal_soc for one non srng related register at the + * given list index + * @hal_soc: hal handle + * @target_reg_offset: target register offset + * @list_index: index in hal list for shadow regs + * + * Return: none + */ +void hal_set_one_target_reg_config(struct hal_soc *hal, + uint32_t target_reg_offset, + int list_index); + +/** + * hal_set_shadow_regs() - Populate register offset for + * registers that need to be populated in list_shadow_reg_config + * in order to be sent to FW. These reg offsets will be mapped + * to shadow registers. + * @hal_soc: hal handle + * + * Return: QDF_STATUS_OK on success + */ +QDF_STATUS hal_set_shadow_regs(void *hal_soc); + +/** + * hal_construct_shadow_regs() - initialize the shadow registers + * for non-srng related register configs + * @hal_soc: hal handle + * + * Return: QDF_STATUS_OK on success + */ +QDF_STATUS hal_construct_shadow_regs(void *hal_soc); + +#else /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ +static inline void hal_set_one_target_reg_config( + struct hal_soc *hal, + uint32_t target_reg_offset, + int list_index) +{ +} + +static inline QDF_STATUS hal_set_shadow_regs(void *hal_soc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS hal_construct_shadow_regs(void *hal_soc) { - hal_soc->ops->hal_reo_set_err_dst_remap(hal_soc); + return QDF_STATUS_SUCCESS; } +#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */ #endif /* _HAL_APIH_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h index c4ff12da3b72b6318dcf1df03586ca6de5759735..5913d9a7ab02091660dd7dcf58bd019664524a99 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -148,18 +148,32 @@ #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs) #endif +/* Max MPDUs per status buffer */ +#define HAL_RX_MAX_MPDU 256 +#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) + +/* Max pilot count */ +#define HAL_RX_MAX_SU_EVM_COUNT 32 + +/* + * Struct hal_rx_su_evm_info - SU evm info + * @number_of_symbols: number of symbols + * @nss_count: nss count + * @pilot_count: pilot count + * @pilot_evm: Array of pilot evm values + */ +struct hal_rx_su_evm_info { + uint32_t number_of_symbols; + uint8_t nss_count; + uint8_t pilot_count; + uint32_t pilot_evm[HAL_RX_MAX_SU_EVM_COUNT]; +}; + enum { DP_PPDU_STATUS_START, DP_PPDU_STATUS_DONE, }; -static inline -uint32_t HAL_RX_MON_HW_RX_DESC_SIZE(void) -{ - /* return the HW_RX_DESC size */ - return sizeof(struct rx_pkt_tlvs); -} - static inline uint8_t *HAL_RX_MON_DEST_GET_DESC(uint8_t *data) { @@ -170,7 +184,8 @@ static inline uint32_t HAL_RX_DESC_GET_MPDU_LENGTH_ERR(void *hw_desc_addr) { struct rx_attention *rx_attn; - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_mon_pkt_tlvs *rx_desc = + (struct rx_mon_pkt_tlvs *)hw_desc_addr; rx_attn = &rx_desc->attn_tlv.rx_attn; @@ -181,7 +196,8 @@ static inline uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr) { struct rx_attention *rx_attn; - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_mon_pkt_tlvs *rx_desc = + (struct rx_mon_pkt_tlvs *)hw_desc_addr; rx_attn = &rx_desc->attn_tlv.rx_attn; @@ -198,7 +214,8 @@ uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr) static inline bool HAL_RX_HW_DESC_MPDU_VALID(void *hw_desc_addr) { - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_mon_pkt_tlvs *rx_desc = + (struct rx_mon_pkt_tlvs *)hw_desc_addr; uint32_t tlv_tag; tlv_tag = HAL_RX_GET_USER_TLV32_TYPE( @@ -207,17 +224,6 @@ bool HAL_RX_HW_DESC_MPDU_VALID(void *hw_desc_addr) return tlv_tag == WIFIRX_MPDU_START_E ? true : false; } -static inline -uint32_t HAL_RX_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) -{ - struct rx_mpdu_info *rx_mpdu_info; - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; - - rx_mpdu_info = - &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; - - return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); -} /* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ @@ -253,10 +259,9 @@ uint32_t HAL_RX_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) * Return: void */ static inline -void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, - struct hal_buf_info *buf_info, - void **pp_buf_addr_info, - uint32_t *msdu_cnt +void hal_rx_reo_ent_buf_paddr_get(hal_rxdma_desc_t rx_desc, + struct hal_buf_info *buf_info, + uint32_t *msdu_cnt ) { struct reo_entrance_ring *reo_ent_ring = @@ -282,18 +287,17 @@ void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); + buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d", __func__, __LINE__, reo_ent_ring, buf_addr_info, (unsigned long long)buf_info->paddr, loop_cnt); - - *pp_buf_addr_info = (void *)buf_addr_info; } static inline void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc, - struct hal_buf_info *buf_info, void **pp_buf_addr_info) + struct hal_buf_info *buf_info) { struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)rx_msdu_link_desc; @@ -307,8 +311,7 @@ void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc, (HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32)); buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info); - - *pp_buf_addr_info = (void *)buf_addr_info; + buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info); } /** @@ -321,8 +324,10 @@ void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc, * Return: void */ -static inline void hal_rx_mon_msdu_link_desc_set(struct hal_soc *soc, - void *src_srng_desc, void *buf_addr_info) +static inline +void hal_rx_mon_msdu_link_desc_set(hal_soc_handle_t hal_soc_hdl, + void *src_srng_desc, + hal_buff_addrinfo_t buf_addr_info) { struct buffer_addr_info *wbm_srng_buffer_addr_info = (struct buffer_addr_info *)src_srng_desc; @@ -390,16 +395,37 @@ enum { HAL_RX_MON_PPDU_END, }; +/* struct hal_rx_ppdu_common_info - common ppdu info + * @ppdu_id - ppdu id number + * @ppdu_timestamp - timestamp at ppdu received + * @mpdu_cnt_fcs_ok - mpdu count in ppdu with fcs ok + * @mpdu_cnt_fcs_err - mpdu count in ppdu with fcs err + * @mpdu_fcs_ok_bitmap - fcs ok mpdu count in ppdu bitmap + * @last_ppdu_id - last received ppdu id + * @mpdu_cnt - total mpdu count + * @num_users - num users + */ struct hal_rx_ppdu_common_info { uint32_t ppdu_id; uint32_t ppdu_timestamp; uint32_t mpdu_cnt_fcs_ok; uint32_t mpdu_cnt_fcs_err; + uint32_t mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + uint32_t last_ppdu_id; + uint32_t mpdu_cnt; + uint8_t num_users; }; +/** + * struct hal_rx_msdu_payload_info - msdu payload info + * @first_msdu_payload: pointer to first msdu payload + * @payload_len: payload len + * @nbuf: status network buffer to which msdu belongs to + */ struct hal_rx_msdu_payload_info { uint8_t *first_msdu_payload; uint32_t payload_len; + qdf_nbuf_t nbuf; }; /** @@ -409,6 +435,7 @@ struct hal_rx_msdu_payload_info { * @to_ds_flag: flag indicate to_ds bit * @mac_addr2_valid: flag indicate if mac_addr2 is valid * @mac_addr2: mac address2 in wh + * @mcast_bcast: multicast/broadcast */ struct hal_rx_nac_info { uint8_t fc_valid; @@ -416,21 +443,123 @@ struct hal_rx_nac_info { uint8_t to_ds_flag; uint8_t mac_addr2_valid; uint8_t mac_addr2[QDF_MAC_ADDR_SIZE]; + uint8_t mcast_bcast; }; /** * struct hal_rx_ppdu_msdu_info - struct for msdu info from HW TLVs - * @cce_metadata: cached metadata value received in the MSDU_END TLV + * @cce_metadata: cached CCE metadata value received in the MSDU_END TLV + * @is_flow_idx_timeout: flag to indicate if flow search timeout occurred + * @is_flow_idx_invalid: flag to indicate if flow idx is valid or not + * @fse_metadata: cached FSE metadata value received in the MSDU END TLV + * @flow_idx: flow idx matched in FSE received in the MSDU END TLV */ struct hal_rx_ppdu_msdu_info { uint16_t cce_metadata; + bool is_flow_idx_timeout; + bool is_flow_idx_invalid; + uint32_t fse_metadata; + uint32_t flow_idx; +}; + +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * struct hal_rx_ppdu_cfr_user_info - struct for storing peer info extracted + * from HW TLVs, this will be used for correlating CFR data with multiple peers + * in MU PPDUs + * + * @peer_macaddr: macaddr of the peer + * @ast_index: AST index of the peer + */ +struct hal_rx_ppdu_cfr_user_info { + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; + uint32_t ast_index; +}; + +/** + * struct hal_rx_ppdu_cfr_info - struct for storing ppdu info extracted from HW + * TLVs, this will be used for CFR correlation + * + * @bb_captured_channel : Set by RXPCU when MACRX_FREEZE_CAPTURE_CHANNEL TLV is + * sent to PHY, SW checks it to correlate current PPDU TLVs with uploaded + * channel information. + * + * @bb_captured_timeout : Set by RxPCU to indicate channel capture condition is + * met, but MACRX_FREEZE_CAPTURE_CHANNEL is not sent to PHY due to AST delay, + * which means the rx_frame_falling edge to FREEZE TLV ready time exceeds + * the threshold time defined by RXPCU register FREEZE_TLV_DELAY_CNT_THRESH. + * Bb_captured_reason is still valid in this case. + * + * @rx_location_info_valid: Indicates whether CFR DMA address in the PPDU TLV + * is valid + * + * + * + * + * @bb_captured_reason : Copy capture_reason of MACRX_FREEZE_CAPTURE_CHANNEL + * TLV to here for FW usage. Valid when bb_captured_channel or + * bb_captured_timeout is set. + * + * + * + * + * + * + * + * + * @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to + * external RTT channel information buffer + * + * @rtt_che_buffer_pointer_high8 : The high 8 bits of the 40 bits pointer to + * external RTT channel information buffer + * + * @chan_capture_status : capture status reported by ucode + * a. CAPTURE_IDLE: FW has disabled "REPETITIVE_CHE_CAPTURE_CTRL" + * b. CAPTURE_BUSY: previous PPDU’s channel capture upload DMA ongoing. (Note + * that this upload is triggered after receiving freeze_channel_capture TLV + * after last PPDU is rx) + * c. CAPTURE_ACTIVE: channel capture is enabled and no previous channel + * capture ongoing + * d. CAPTURE_NO_BUFFER: next buffer in IPC ring not available + * + * @cfr_user_info: Peer mac for upto 4 MU users + */ + +struct hal_rx_ppdu_cfr_info { + bool bb_captured_channel; + bool bb_captured_timeout; + uint8_t bb_captured_reason; + bool rx_location_info_valid; + uint8_t chan_capture_status; + uint8_t rtt_che_buffer_pointer_high8; + uint32_t rtt_che_buffer_pointer_low32; + struct hal_rx_ppdu_cfr_user_info cfr_user_info[HAL_MAX_UL_MU_USERS]; +}; +#else +struct hal_rx_ppdu_cfr_info {}; +#endif + +struct mon_rx_info { + uint8_t qos_control_info_valid; + uint16_t qos_control; + uint8_t mac_addr1_valid; + uint8_t mac_addr1[QDF_MAC_ADDR_SIZE]; +}; + +struct mon_rx_user_info { + uint16_t qos_control; + uint8_t qos_control_info_valid; + uint32_t bar_frame:1; }; struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct mon_rx_status rx_status; struct mon_rx_user_status rx_user_status[HAL_MAX_UL_MU_USERS]; + struct mon_rx_info rx_info; + struct mon_rx_user_info rx_user_info[HAL_MAX_UL_MU_USERS]; struct hal_rx_msdu_payload_info msdu_info; + struct hal_rx_msdu_payload_info fcs_ok_msdu_info; struct hal_rx_nac_info nac_info; /* status ring PPDU start and end state */ uint32_t rx_state; @@ -442,7 +571,18 @@ struct hal_rx_ppdu_info { uint32_t hdr_len; /* MPDU FCS error */ bool fcs_err; + /* Id to indicate how to process mpdu */ + uint8_t sw_frame_group_id; struct hal_rx_ppdu_msdu_info rx_msdu_info[HAL_MAX_UL_MU_USERS]; + /* first msdu payload for all mpdus in ppdu */ + struct hal_rx_msdu_payload_info ppdu_msdu_info[HAL_RX_MAX_MPDU]; + /* evm info */ + struct hal_rx_su_evm_info evm_info; + /** + * Will be used to store ppdu info extracted from HW TLVs, + * and for CFR correlation as well + */ + struct hal_rx_ppdu_cfr_info cfr_info; }; static inline uint32_t @@ -491,19 +631,27 @@ static inline void hal_rx_proc_phyrx_other_receive_info_tlv(struct hal_soc *hal_ * hal_rx_status_get_tlv_info() - process receive info TLV * @rx_tlv_hdr: pointer to TLV header * @ppdu_info: pointer to ppdu_info + * @hal_soc: HAL soc handle + * @nbuf: PPDU status netowrk buffer * * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv */ static inline uint32_t hal_rx_status_get_tlv_info(void *rx_tlv_hdr, void *ppdu_info, - struct hal_soc *hal_soc) + hal_soc_handle_t hal_soc_hdl, + qdf_nbuf_t nbuf) { - return hal_soc->ops->hal_rx_status_get_tlv_info(rx_tlv_hdr, - ppdu_info, hal_soc); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_status_get_tlv_info( + rx_tlv_hdr, + ppdu_info, + hal_soc_hdl, + nbuf); } static inline -uint32_t hal_get_rx_status_done_tlv_size(void *hal_soc) +uint32_t hal_get_rx_status_done_tlv_size(hal_soc_handle_t hal_soc_hdl) { return HAL_RX_TLV32_HDR_SIZE; } diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_flow.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_flow.h new file mode 100644 index 0000000000000000000000000000000000000000..b89146d10ab1b650f0908d0f94645df1d6e1cba6 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_flow.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ +#ifndef __HAL_FLOW_H +#define __HAL_FLOW_H + +#define HAL_SET_FLD_SM(block, field, value) \ + (((value) << (block ## _ ## field ## _LSB)) & \ + (block ## _ ## field ## _MASK)) + +#define HAL_SET_FLD_MS(block, field, value) \ + (((value) & (block ## _ ## field ## _MASK)) >> \ + (block ## _ ## field ## _LSB)) + +#define HAL_CLR_FLD(desc, block, field) \ +do { \ + uint32_t val; \ + typeof(desc) desc_ = desc; \ + val = *((uint32_t *)((uint8_t *)(desc_) + \ + HAL_OFFSET(block, field))); \ + val &= ~(block ## _ ## field ## _MASK); \ + HAL_SET_FLD(desc_, block, field) = val; \ +} while (0) + +#define HAL_GET_FLD(desc, block, field) \ + ((*((uint32_t *)((uint8_t *)(desc) + HAL_OFFSET(block, field))) & \ + (block ## _ ## field ## _MASK)) >> (block ## _ ## field ## _LSB)) + +/** + * struct hal_flow_tuple_info - Hal Flow 5-tuple + * @dest_ip_127_96: Destination IP address bits 96-127 + * @dest_ip_95_64: Destination IP address bits 64-95 + * @dest_ip_63_32: Destination IP address bits 32-63 + * @dest_ip_31_0: Destination IP address bits 0-31 + * @src_ip_127_96: Source IP address bits 96-127 + * @src_ip_95_64: Source IP address bits 64-95 + * @src_ip_63_32: Source IP address bits 32-63 + * @src_ip_31_0: Source IP address bits 0-31 + * @dest_port: Destination Port + * @src_port: Source Port + * @l4_protocol: Layer-4 protocol type (TCP/UDP) + */ +struct hal_flow_tuple_info { + uint32_t dest_ip_127_96; + uint32_t dest_ip_95_64; + uint32_t dest_ip_63_32; + uint32_t dest_ip_31_0; + uint32_t src_ip_127_96; + uint32_t src_ip_95_64; + uint32_t src_ip_63_32; + uint32_t src_ip_31_0; + uint16_t dest_port; + uint16_t src_port; + uint16_t l4_protocol; +}; + +/** + * key_bitwise_shift_left() - Bitwise left shift (in place) an array of bytes + * @key: Pointer to array to key bytes + * @len: size of array (number of key bytes) + * @shift: number of shift operations to be performed + * + * Return: + */ +static inline void +key_bitwise_shift_left(uint8_t *key, int len, int shift) +{ + int i; + int next; + + while (shift--) { + for (i = len - 1; i >= 0 ; i--) { + if (i > 0) + next = (key[i - 1] & 0x80 ? 1 : 0); + else + next = 0; + key[i] = (key[i] << 1) | next; + } + } +} + +/** + * key_reverse() - Reverse the key buffer from MSB to LSB + * @dest: pointer to the destination key + * @src: pointer to the source key which should be shifted + * @len: size of key in bytes + * + * Return: + */ +static inline void +key_reverse(uint8_t *dest, uint8_t *src, int len) +{ + int i, j; + + for (i = 0, j = len - 1; i < len; i++, j--) + dest[i] = src[j]; +} +#endif /* HAL_FLOW_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h index 9abdb17ae1b7fecc73cb89de34a01d710843d33e..3f02ab4daa9c1e65e2ed58a648311c8591aaf172 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -18,37 +18,7 @@ #ifndef _HAL_GENERIC_API_H_ #define _HAL_GENERIC_API_H_ -#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ - ((struct rx_msdu_desc_info *) \ - _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ -UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) -/** - * hal_rx_msdu_desc_info_get_ptr_generic() - Get msdu desc info ptr - * @msdu_details_ptr - Pointer to msdu_details_ptr - * Return - Pointer to rx_msdu_desc_info structure. - * - */ -static void *hal_rx_msdu_desc_info_get_ptr_generic(void *msdu_details_ptr) -{ - return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); -} - - -#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ - ((struct rx_msdu_details *) \ - _OFFSET_TO_BYTE_PTR((link_desc),\ - UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) -/** - * hal_rx_link_desc_msdu0_ptr_generic - Get pointer to rx_msdu details - * @link_desc - Pointer to link desc - * Return - Pointer to rx_msdu_details structure - * - */ - -static void *hal_rx_link_desc_msdu0_ptr_generic(void *link_desc) -{ - return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); -} +#include /** * hal_tx_comp_get_status() - TQM Release reason @@ -59,8 +29,10 @@ static void *hal_rx_link_desc_msdu0_ptr_generic(void *link_desc) * * Return: none */ -static inline void hal_tx_comp_get_status_generic(void *desc, - void *ts1, void *hal) +static inline +void hal_tx_comp_get_status_generic(void *desc, + void *ts1, + struct hal_soc *hal) { uint8_t rate_stats_valid = 0; uint32_t rate_stats = 0; @@ -109,7 +81,9 @@ static inline void hal_tx_comp_get_status_generic(void *desc, } ts->release_src = hal_tx_comp_get_buffer_source(desc); - ts->status = hal_tx_comp_get_release_reason(desc, hal); + ts->status = hal_tx_comp_get_release_reason( + desc, + hal_soc_to_hal_soc_handle(hal)); ts->tsf = HAL_TX_DESC_GET(desc, UNIFIED_WBM_RELEASE_RING_6, TX_RATE_STATS_INFO_TX_RATE_STATS); @@ -157,7 +131,7 @@ static inline void hal_tx_desc_set_buf_addr_generic(void *desc, HAL_TX_SM(UNIFIED_TCL_DATA_CMD_2, BUF_OR_EXT_DESC_TYPE, type); } -#if defined(CONFIG_MCL) && defined(QCA_WIFI_QCA6290_11AX) +#if defined(QCA_WIFI_QCA6290_11AX_MU_UL) && defined(QCA_WIFI_QCA6290_11AX) /** * hal_rx_handle_other_tlvs() - handle special TLVs like MU_UL * tlv_tag: Taf of the TLVs @@ -239,32 +213,218 @@ hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv, { return false; } -#endif /* CONFIG_MCL && QCA_WIFI_QCA6290_11AX */ +#endif /* QCA_WIFI_QCA6290_11AX_MU_UL && QCA_WIFI_QCA6290_11AX */ + +#if defined(RX_PPDU_END_USER_STATS_1_OFDMA_INFO_VALID_OFFSET) && \ +defined(RX_PPDU_END_USER_STATS_22_SW_RESPONSE_REFERENCE_PTR_EXT_OFFSET) -#if defined(RX_PPDU_END_USER_STATS_1_OFDMA_INFO_VALID_OFFSET) static inline void -hal_rx_handle_ofdma_info( +hal_rx_handle_mu_ul_info( void *rx_tlv, struct mon_rx_user_status *mon_rx_user_status) { - mon_rx_user_status->ofdma_info_valid = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, - OFDMA_INFO_VALID); - mon_rx_user_status->dl_ofdma_ru_start_index = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, - DL_OFDMA_RU_START_INDEX); - mon_rx_user_status->dl_ofdma_ru_width = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2, - DL_OFDMA_RU_WIDTH); + mon_rx_user_status->mu_ul_user_v0_word0 = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_11, + SW_RESPONSE_REFERENCE_PTR); + + mon_rx_user_status->mu_ul_user_v0_word1 = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_22, + SW_RESPONSE_REFERENCE_PTR_EXT); +} + +static inline void +hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo, + struct mon_rx_user_status *mon_rx_user_status) +{ + uint32_t mpdu_ok_byte_count; + uint32_t mpdu_err_byte_count; + + mpdu_ok_byte_count = HAL_RX_GET(rx_tlv, + RX_PPDU_END_USER_STATS_17, + MPDU_OK_BYTE_COUNT); + mpdu_err_byte_count = HAL_RX_GET(rx_tlv, + RX_PPDU_END_USER_STATS_19, + MPDU_ERR_BYTE_COUNT); + + mon_rx_user_status->mpdu_ok_byte_count = mpdu_ok_byte_count; + mon_rx_user_status->mpdu_err_byte_count = mpdu_err_byte_count; } #else static inline void -hal_rx_handle_ofdma_info(void *rx_tlv, +hal_rx_handle_mu_ul_info(void *rx_tlv, struct mon_rx_user_status *mon_rx_user_status) { } + +static inline void +hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo, + struct mon_rx_user_status *mon_rx_user_status) +{ + struct hal_rx_ppdu_info *ppdu_info = + (struct hal_rx_ppdu_info *)ppduinfo; + + /* HKV1: doesn't support mpdu byte count */ + mon_rx_user_status->mpdu_ok_byte_count = ppdu_info->rx_status.ppdu_len; + mon_rx_user_status->mpdu_err_byte_count = 0; +} +#endif + +static inline void +hal_rx_populate_mu_user_info(void *rx_tlv, void *ppduinfo, + struct mon_rx_user_status *mon_rx_user_status) +{ + struct hal_rx_ppdu_info *ppdu_info = + (struct hal_rx_ppdu_info *)ppduinfo; + + mon_rx_user_status->ast_index = ppdu_info->rx_status.ast_index; + mon_rx_user_status->tid = ppdu_info->rx_status.tid; + mon_rx_user_status->tcp_msdu_count = + ppdu_info->rx_status.tcp_msdu_count; + mon_rx_user_status->udp_msdu_count = + ppdu_info->rx_status.udp_msdu_count; + mon_rx_user_status->other_msdu_count = + ppdu_info->rx_status.other_msdu_count; + mon_rx_user_status->frame_control = ppdu_info->rx_status.frame_control; + mon_rx_user_status->frame_control_info_valid = + ppdu_info->rx_status.frame_control_info_valid; + mon_rx_user_status->data_sequence_control_info_valid = + ppdu_info->rx_status.data_sequence_control_info_valid; + mon_rx_user_status->first_data_seq_ctrl = + ppdu_info->rx_status.first_data_seq_ctrl; + mon_rx_user_status->preamble_type = ppdu_info->rx_status.preamble_type; + mon_rx_user_status->ht_flags = ppdu_info->rx_status.ht_flags; + mon_rx_user_status->rtap_flags = ppdu_info->rx_status.rtap_flags; + mon_rx_user_status->vht_flags = ppdu_info->rx_status.vht_flags; + mon_rx_user_status->he_flags = ppdu_info->rx_status.he_flags; + mon_rx_user_status->rs_flags = ppdu_info->rx_status.rs_flags; + + mon_rx_user_status->mpdu_cnt_fcs_ok = + ppdu_info->com_info.mpdu_cnt_fcs_ok; + mon_rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->com_info.mpdu_cnt_fcs_err; + qdf_mem_copy(&mon_rx_user_status->mpdu_fcs_ok_bitmap, + &ppdu_info->com_info.mpdu_fcs_ok_bitmap, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->com_info.mpdu_fcs_ok_bitmap[0])); + + hal_rx_populate_byte_count(rx_tlv, ppdu_info, mon_rx_user_status); +} + +#ifdef WLAN_TX_PKT_CAPTURE_ENH +static inline void +hal_rx_populate_tx_capture_user_info(void *ppduinfo, + uint32_t user_id) +{ + struct hal_rx_ppdu_info *ppdu_info; + struct mon_rx_info *mon_rx_info; + struct mon_rx_user_info *mon_rx_user_info; + + ppdu_info = (struct hal_rx_ppdu_info *)ppduinfo; + mon_rx_info = &ppdu_info->rx_info; + mon_rx_user_info = &ppdu_info->rx_user_info[user_id]; + mon_rx_user_info->qos_control_info_valid = + mon_rx_info->qos_control_info_valid; + mon_rx_user_info->qos_control = mon_rx_info->qos_control; +} +#else +static inline void +hal_rx_populate_tx_capture_user_info(void *ppduinfo, + uint32_t user_id) +{ +} #endif +#define HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(chain, word_1, word_2, \ + ppdu_info, rssi_info_tlv) \ + { \ + ppdu_info->rx_status.rssi_chain[chain][0] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\ + RSSI_PRI20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][1] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\ + RSSI_EXT20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][2] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\ + RSSI_EXT40_LOW20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][3] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\ + RSSI_EXT40_HIGH20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][4] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\ + RSSI_EXT80_LOW20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][5] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\ + RSSI_EXT80_LOW_HIGH20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][6] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\ + RSSI_EXT80_HIGH_LOW20_CHAIN##chain); \ + ppdu_info->rx_status.rssi_chain[chain][7] = \ + HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\ + RSSI_EXT80_HIGH20_CHAIN##chain); \ + } \ + +#define HAL_RX_PPDU_UPDATE_RSSI(ppdu_info, rssi_info_tlv) \ + {HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(0, 0, 1, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(1, 2, 3, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(2, 4, 5, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(3, 6, 7, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(4, 8, 9, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(5, 10, 11, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(6, 12, 13, ppdu_info, rssi_info_tlv) \ + HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(7, 14, 15, ppdu_info, rssi_info_tlv)} \ + +static inline uint32_t +hal_rx_update_rssi_chain(struct hal_rx_ppdu_info *ppdu_info, + uint8_t *rssi_info_tlv) +{ + HAL_RX_PPDU_UPDATE_RSSI(ppdu_info, rssi_info_tlv) + return 0; +} + +#ifdef WLAN_TX_PKT_CAPTURE_ENH +static inline void +hal_get_qos_control(void *rx_tlv, + struct hal_rx_ppdu_info *ppdu_info) +{ + ppdu_info->rx_info.qos_control_info_valid = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, + QOS_CONTROL_INFO_VALID); + + if (ppdu_info->rx_info.qos_control_info_valid) + ppdu_info->rx_info.qos_control = + HAL_RX_GET(rx_tlv, + RX_PPDU_END_USER_STATS_5, + QOS_CONTROL_FIELD); +} + +static inline void +hal_get_mac_addr1(uint8_t *rx_mpdu_start, + struct hal_rx_ppdu_info *ppdu_info) +{ + if (ppdu_info->sw_frame_group_id + == HAL_MPDU_SW_FRAME_GROUP_MGMT_PROBE_REQ) { + ppdu_info->rx_info.mac_addr1_valid = + HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start); + + *(uint32_t *)&ppdu_info->rx_info.mac_addr1[0] = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_15, + MAC_ADDR_AD1_31_0); + } +} +#else +static inline void +hal_get_qos_control(void *rx_tlv, + struct hal_rx_ppdu_info *ppdu_info) +{ +} + +static inline void +hal_get_mac_addr1(uint8_t *rx_mpdu_start, + struct hal_rx_ppdu_info *ppdu_info) +{ +} +#endif /** * hal_rx_status_get_tlv_info() - process receive info TLV * @rx_tlv_hdr: pointer to TLV header @@ -274,9 +434,10 @@ hal_rx_handle_ofdma_info(void *rx_tlv, */ static inline uint32_t hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, - void *halsoc) + hal_soc_handle_t hal_soc_hdl, + qdf_nbuf_t nbuf) { - struct hal_soc *hal = (struct hal_soc *)halsoc; + struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl; uint32_t tlv_tag, user_id, tlv_len, value; uint8_t group_id = 0; uint8_t he_dcm = 0; @@ -301,20 +462,42 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, switch (tlv_tag) { case WIFIRX_PPDU_START_E: + { + struct hal_rx_ppdu_common_info *com_info = &ppdu_info->com_info; + ppdu_info->com_info.ppdu_id = HAL_RX_GET(rx_tlv, RX_PPDU_START_0, PHY_PPDU_ID); /* channel number is set in PHY meta data */ ppdu_info->rx_status.chan_num = - HAL_RX_GET(rx_tlv, RX_PPDU_START_1, - SW_PHY_META_DATA); + (HAL_RX_GET(rx_tlv, RX_PPDU_START_1, + SW_PHY_META_DATA) & 0x0000FFFF); + ppdu_info->rx_status.chan_freq = + (HAL_RX_GET(rx_tlv, RX_PPDU_START_1, + SW_PHY_META_DATA) & 0xFFFF0000)>>16; ppdu_info->com_info.ppdu_timestamp = HAL_RX_GET(rx_tlv, RX_PPDU_START_2, PPDU_START_TIMESTAMP); ppdu_info->rx_status.ppdu_timestamp = ppdu_info->com_info.ppdu_timestamp; ppdu_info->rx_state = HAL_RX_MON_PPDU_START; + + /* If last ppdu_id doesn't match new ppdu_id, + * 1. reset mpdu_cnt + * 2. update last_ppdu_id with new + * 3. reset mpdu fcs bitmap + */ + if (com_info->ppdu_id != com_info->last_ppdu_id) { + com_info->mpdu_cnt = 0; + com_info->last_ppdu_id = + com_info->ppdu_id; + com_info->num_users = 0; + qdf_mem_zero(&com_info->mpdu_fcs_ok_bitmap, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(com_info->mpdu_fcs_ok_bitmap[0])); + } break; + } case WIFIRX_PPDU_START_USER_INFO_E: break; @@ -327,7 +510,13 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->rx_state = HAL_RX_MON_PPDU_END; break; + case WIFIPHYRX_PKT_END_E: + hal_rx_get_rtt_info(hal_soc_hdl, rx_tlv, ppdu_info); + break; + case WIFIRXPCU_PPDU_END_INFO_E: + ppdu_info->rx_status.rx_antenna = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_2, RX_ANTENNA); ppdu_info->rx_status.tsft = HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, WB_TIMESTAMP_UPPER_32); @@ -337,8 +526,13 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->rx_status.duration = HAL_RX_GET(rx_tlv, UNIFIED_RXPCU_PPDU_END_INFO_8, RX_PPDU_DURATION); + hal_rx_get_bb_info(hal_soc_hdl, rx_tlv, ppdu_info); break; + /* + * WIFIRX_PPDU_END_USER_STATS_E comes for each user received. + * for MU, based on num users we see this tlv that many times. + */ case WIFIRX_PPDU_END_USER_STATS_E: { unsigned long tid = 0; @@ -367,14 +561,20 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10, OTHER_MSDU_COUNT); - ppdu_info->rx_status.frame_control_info_valid = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, - FRAME_CONTROL_INFO_VALID); + if (ppdu_info->sw_frame_group_id + != HAL_MPDU_SW_FRAME_GROUP_NULL_DATA) { + ppdu_info->rx_status.frame_control_info_valid = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, + FRAME_CONTROL_INFO_VALID); - if (ppdu_info->rx_status.frame_control_info_valid) - ppdu_info->rx_status.frame_control = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4, - FRAME_CONTROL_FIELD); + if (ppdu_info->rx_status.frame_control_info_valid) + ppdu_info->rx_status.frame_control = + HAL_RX_GET(rx_tlv, + RX_PPDU_END_USER_STATS_4, + FRAME_CONTROL_FIELD); + + hal_get_qos_control(rx_tlv, ppdu_info); + } ppdu_info->rx_status.data_sequence_control_info_valid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, @@ -402,19 +602,6 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, default: break; } - if (user_id < HAL_MAX_UL_MU_USERS) { - mon_rx_user_status = - &ppdu_info->rx_user_status[user_id]; - - mon_rx_user_status->mcs = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, - MCS); - mon_rx_user_status->nss = - HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_1, - NSS); - - hal_rx_handle_ofdma_info(rx_tlv, mon_rx_user_status); - } ppdu_info->com_info.mpdu_cnt_fcs_ok = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3, @@ -428,10 +615,57 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, else ppdu_info->rx_status.rs_flags &= (~IEEE80211_AMPDU_FLAG); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[0] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_7, + FCS_OK_BITMAP_31_0); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[1] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_8, + FCS_OK_BITMAP_63_32); + + if (user_id < HAL_MAX_UL_MU_USERS) { + mon_rx_user_status = + &ppdu_info->rx_user_status[user_id]; + + hal_rx_handle_mu_ul_info(rx_tlv, mon_rx_user_status); + + ppdu_info->com_info.num_users++; + + hal_rx_populate_mu_user_info(rx_tlv, ppdu_info, + mon_rx_user_status); + + hal_rx_populate_tx_capture_user_info(ppdu_info, + user_id); + + } break; } case WIFIRX_PPDU_END_USER_STATS_EXT_E: + ppdu_info->com_info.mpdu_fcs_ok_bitmap[2] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_1, + FCS_OK_BITMAP_95_64); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[3] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_2, + FCS_OK_BITMAP_127_96); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[4] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_3, + FCS_OK_BITMAP_159_128); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[5] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_4, + FCS_OK_BITMAP_191_160); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[6] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_5, + FCS_OK_BITMAP_223_192); + + ppdu_info->com_info.mpdu_fcs_ok_bitmap[7] = + HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_6, + FCS_OK_BITMAP_255_224); break; case WIFIRX_PPDU_END_STATUS_DONE_E: @@ -578,6 +812,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, case TARGET_TYPE_QCA8074: case TARGET_TYPE_QCA8074V2: case TARGET_TYPE_QCA6018: + case TARGET_TYPE_QCN9000: #ifdef QCA_WIFI_QCA6390 case TARGET_TYPE_QCA6390: #endif @@ -586,6 +821,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, VHT_SIG_A_INFO_0, STBC); value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, N_STS); + value = value & VHT_SIG_SU_NSS_MASK; if (ppdu_info->rx_status.is_stbc && (value > 0)) value = ((value + 1) >> 1) - 1; ppdu_info->rx_status.nss = @@ -599,6 +835,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, VHT_SIG_A_INFO_0, STBC); value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, N_STS); + value = value & VHT_SIG_SU_NSS_MASK; if (ppdu_info->rx_status.is_stbc && (value > 0)) value = ((value + 1) >> 1) - 1; ppdu_info->rx_status.nss = @@ -607,6 +844,10 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, ppdu_info->rx_status.nss = 0; #endif break; + case TARGET_TYPE_QCA6490: + case TARGET_TYPE_QCA6750: + ppdu_info->rx_status.nss = 0; + break; default: break; } @@ -1078,6 +1319,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, case WIFIPHYRX_RSSI_LEGACY_E: { uint8_t reception_type; + int8_t rssi_value; uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + HAL_RX_OFFSET(UNIFIED_PHYRX_RSSI_LEGACY_19, RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS); @@ -1092,64 +1334,74 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, RECEPTION_TYPE); switch (reception_type) { case QDF_RECEPTION_TYPE_ULOFMDA: + ppdu_info->rx_status.reception_type = + HAL_RX_TYPE_MU_OFDMA; ppdu_info->rx_status.ulofdma_flag = 1; ppdu_info->rx_status.he_data1 = QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE; break; case QDF_RECEPTION_TYPE_ULMIMO: + ppdu_info->rx_status.reception_type = + HAL_RX_TYPE_MU_MIMO; ppdu_info->rx_status.he_data1 = QDF_MON_STATUS_HE_MU_FORMAT_TYPE; break; default: + ppdu_info->rx_status.reception_type = + HAL_RX_TYPE_SU; break; } - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); - ppdu_info->rx_status.rssi[0] = value; + hal_rx_update_rssi_chain(ppdu_info, rssi_info_tlv); + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); + ppdu_info->rx_status.rssi[0] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN0: %d\n", value); + "RSSI_PRI20_CHAIN0: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_2, RSSI_PRI20_CHAIN1); - ppdu_info->rx_status.rssi[1] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_2, RSSI_PRI20_CHAIN1); + ppdu_info->rx_status.rssi[1] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN1: %d\n", value); + "RSSI_PRI20_CHAIN1: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_4, RSSI_PRI20_CHAIN2); - ppdu_info->rx_status.rssi[2] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_4, RSSI_PRI20_CHAIN2); + ppdu_info->rx_status.rssi[2] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN2: %d\n", value); + "RSSI_PRI20_CHAIN2: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_6, RSSI_PRI20_CHAIN3); - ppdu_info->rx_status.rssi[3] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_6, RSSI_PRI20_CHAIN3); + ppdu_info->rx_status.rssi[3] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN3: %d\n", value); + "RSSI_PRI20_CHAIN3: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_8, RSSI_PRI20_CHAIN4); - ppdu_info->rx_status.rssi[4] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_8, RSSI_PRI20_CHAIN4); + ppdu_info->rx_status.rssi[4] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN4: %d\n", value); + "RSSI_PRI20_CHAIN4: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_10, RSSI_PRI20_CHAIN5); - ppdu_info->rx_status.rssi[5] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_10, + RSSI_PRI20_CHAIN5); + ppdu_info->rx_status.rssi[5] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN5: %d\n", value); + "RSSI_PRI20_CHAIN5: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_12, RSSI_PRI20_CHAIN6); - ppdu_info->rx_status.rssi[6] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_12, + RSSI_PRI20_CHAIN6); + ppdu_info->rx_status.rssi[6] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN1: %d\n", value); + "RSSI_PRI20_CHAIN6: %d\n", rssi_value); - value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_14, RSSI_PRI20_CHAIN7); - ppdu_info->rx_status.rssi[7] = value; + rssi_value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_14, + RSSI_PRI20_CHAIN7); + ppdu_info->rx_status.rssi[7] = rssi_value; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "RSSI_PRI20_CHAIN7: %d\n", value); + "RSSI_PRI20_CHAIN7: %d\n", rssi_value); break; } case WIFIPHYRX_OTHER_RECEIVE_INFO_E: @@ -1157,41 +1409,68 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, ppdu_info); break; case WIFIRX_HEADER_E: + { + struct hal_rx_ppdu_common_info *com_info = &ppdu_info->com_info; + uint16_t mpdu_cnt = com_info->mpdu_cnt; + + if (mpdu_cnt >= HAL_RX_MAX_MPDU) { + hal_alert("Number of MPDUs per PPDU exceeded"); + break; + } + /* Update first_msdu_payload for every mpdu and increment + * com_info->mpdu_cnt for every WIFIRX_HEADER_E TLV + */ + ppdu_info->ppdu_msdu_info[mpdu_cnt].first_msdu_payload = + rx_tlv; + ppdu_info->ppdu_msdu_info[mpdu_cnt].payload_len = tlv_len; + ppdu_info->ppdu_msdu_info[mpdu_cnt].nbuf = nbuf; ppdu_info->msdu_info.first_msdu_payload = rx_tlv; ppdu_info->msdu_info.payload_len = tlv_len; ppdu_info->user_id = user_id; ppdu_info->hdr_len = tlv_len; ppdu_info->data = rx_tlv; ppdu_info->data += 4; + + /* for every RX_HEADER TLV increment mpdu_cnt */ + com_info->mpdu_cnt++; return HAL_TLV_STATUS_HEADER; + } case WIFIRX_MPDU_START_E: { uint8_t *rx_mpdu_start = (uint8_t *)rx_tlv + HAL_RX_OFFSET(UNIFIED_RX_MPDU_START_0, RX_MPDU_INFO_RX_MPDU_INFO_DETAILS); - uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, - PHY_PPDU_ID); + uint32_t ppdu_id = + HAL_RX_GET_PPDU_ID(rx_mpdu_start); uint8_t filter_category = 0; ppdu_info->nac_info.fc_valid = - HAL_RX_GET(rx_mpdu_start, - RX_MPDU_INFO_2, - MPDU_FRAME_CONTROL_VALID); + HAL_RX_GET_FC_VALID(rx_mpdu_start); ppdu_info->nac_info.to_ds_flag = - HAL_RX_GET(rx_mpdu_start, - RX_MPDU_INFO_2, - TO_DS); + HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start); ppdu_info->nac_info.frame_control = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_14, MPDU_FRAME_CONTROL_FIELD); + ppdu_info->sw_frame_group_id = + HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start); + + if (ppdu_info->sw_frame_group_id == + HAL_MPDU_SW_FRAME_GROUP_NULL_DATA) { + ppdu_info->rx_status.frame_control_info_valid = + ppdu_info->nac_info.fc_valid; + ppdu_info->rx_status.frame_control = + ppdu_info->nac_info.frame_control; + } + + hal_get_mac_addr1(rx_mpdu_start, + ppdu_info); + ppdu_info->nac_info.mac_addr2_valid = - HAL_RX_GET(rx_mpdu_start, - RX_MPDU_INFO_2, - MAC_ADDR_AD2_VALID); + HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start); *(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] = HAL_RX_GET(rx_mpdu_start, @@ -1214,14 +1493,18 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, MPDU_LENGTH); } - filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, - RXPCU_MPDU_FILTER_IN_CATEGORY); + filter_category = + HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start); if (filter_category == 0) ppdu_info->rx_status.rxpcu_filter_pass = 1; else if (filter_category == 1) ppdu_info->rx_status.monitor_direct_used = 1; + ppdu_info->nac_info.mcast_bcast = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_13, + MCAST_BCAST); break; } case WIFIRX_MPDU_END_E: @@ -1231,8 +1514,18 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, FCS_ERR); return HAL_TLV_STATUS_MPDU_END; case WIFIRX_MSDU_END_E: - ppdu_info->rx_msdu_info[user_id].cce_metadata = - HAL_RX_MSDU_END_CCE_METADATA_GET(rx_tlv); + if (user_id < HAL_MAX_UL_MU_USERS) { + ppdu_info->rx_msdu_info[user_id].cce_metadata = + HAL_RX_MSDU_END_CCE_METADATA_GET(rx_tlv); + ppdu_info->rx_msdu_info[user_id].fse_metadata = + HAL_RX_MSDU_END_FSE_METADATA_GET(rx_tlv); + ppdu_info->rx_msdu_info[user_id].is_flow_idx_timeout = + HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(rx_tlv); + ppdu_info->rx_msdu_info[user_id].is_flow_idx_invalid = + HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(rx_tlv); + ppdu_info->rx_msdu_info[user_id].flow_idx = + HAL_RX_MSDU_END_FLOW_IDX_GET(rx_tlv); + } return HAL_TLV_STATUS_MSDU_END; case 0: return HAL_TLV_STATUS_PPDU_DONE; @@ -1256,101 +1549,6 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, return HAL_TLV_STATUS_PPDU_NOT_DONE; } -/** - * hal_reo_status_get_header_generic - Process reo desc info - * @d - Pointer to reo descriptior - * @b - tlv type info - * @h1 - Pointer to hal_reo_status_header where info to be stored - * - * Return - none. - * - */ -static void hal_reo_status_get_header_generic(uint32_t *d, int b, void *h1) -{ - - uint32_t val1 = 0; - struct hal_reo_status_header *h = - (struct hal_reo_status_header *)h1; - - switch (b) { - case HAL_REO_QUEUE_STATS_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_FLUSH_QUEUE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_FLUSH_CACHE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_UNBLK_CACHE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_TIMOUT_LIST_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_DESC_THRES_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; - break; - default: - pr_err("ERROR: Unknown tlv\n"); - break; - } - h->cmd_num = - HAL_GET_FIELD( - UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, - val1); - h->exec_time = - HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, - CMD_EXECUTION_TIME, val1); - h->status = - HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, - REO_CMD_EXECUTION_STATUS, val1); - switch (b) { - case HAL_REO_QUEUE_STATS_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_FLUSH_QUEUE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_FLUSH_CACHE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_UNBLK_CACHE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_TIMOUT_LIST_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_DESC_THRES_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: - val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, - UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; - break; - default: - pr_err("ERROR: Unknown tlv\n"); - break; - } - h->tstamp = - HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); -} /** * hal_reo_setup - Initialize HW REO block @@ -1358,28 +1556,16 @@ static void hal_reo_status_get_header_generic(uint32_t *d, int b, void *h1) * @hal_soc: Opaque HAL SOC handle * @reo_params: parameters needed by HAL for REO config */ -static void hal_reo_setup_generic(void *hal_soc, - void *reoparams) +static void hal_reo_setup_generic(struct hal_soc *soc, + void *reoparams) { - struct hal_soc *soc = (struct hal_soc *)hal_soc; uint32_t reg_val; struct hal_reo_params *reo_params = (struct hal_reo_params *)reoparams; reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET)); - reg_val &= ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK | - HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | - HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); - - reg_val |= HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, - FRAGMENT_DEST_RING, reo_params->frag_dst_ring) | - HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_LIST_ENABLE, 1) | - HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_FLUSH_ENABLE, 1); - - HAL_REG_WRITE(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), reg_val); - + hal_reo_config(soc, reg_val, reo_params); /* Other ring enable bits and REO_ENABLE will be set by FW */ /* TODO: Setup destination ring mapping if enabled */ @@ -1427,22 +1613,20 @@ static void hal_reo_setup_generic(void *hal_soc, SEQ_WCSS_UMAC_REO_REG_OFFSET), reo_params->remap1); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x"), - HAL_REG_READ(soc, - HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET))); + hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x", + HAL_REG_READ(soc, + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET))); HAL_REG_WRITE(soc, HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET), reo_params->remap2); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x"), - HAL_REG_READ(soc, - HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET))); + hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x", + HAL_REG_READ(soc, + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET))); } /* TODO: Check if the following registers shoould be setup by host: @@ -1464,21 +1648,22 @@ static void hal_reo_setup_generic(void *hal_soc, * Return: Update tail pointer and head pointer in arguments. */ static inline -void hal_get_hw_hptp_generic(struct hal_soc *soc, void *hal_ring, +void hal_get_hw_hptp_generic(struct hal_soc *hal_soc, + hal_ring_handle_t hal_ring_hdl, uint32_t *headp, uint32_t *tailp, uint8_t ring) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; struct hal_hw_srng_config *ring_config; enum hal_ring_type ring_type = (enum hal_ring_type)ring; - if (!soc || !srng) { + if (!hal_soc || !srng) { QDF_TRACE(QDF_MODULE_ID_HAL, QDF_TRACE_LEVEL_ERROR, "%s: Context is Null", __func__); return; } - ring_config = HAL_SRNG_CONFIG(soc, ring_type); + ring_config = HAL_SRNG_CONFIG(hal_soc, ring_type); if (!ring_config->lmac_ring) { if (srng->ring_dir == HAL_SRNG_SRC_RING) { *headp = SRNG_SRC_REG_READ(srng, HP); @@ -1496,10 +1681,10 @@ void hal_get_hw_hptp_generic(struct hal_soc *soc, void *hal_ring, * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer */ -static inline void hal_srng_src_hw_init_generic(void *halsoc, - struct hal_srng *srng) +static inline +void hal_srng_src_hw_init_generic(struct hal_soc *hal, + struct hal_srng *srng) { - struct hal_soc *hal = (struct hal_soc *)halsoc; uint32_t reg_val = 0; uint64_t tp_addr = 0; @@ -1609,10 +1794,10 @@ static inline void hal_srng_src_hw_init_generic(void *halsoc, * @hal_soc: HAL SOC handle * @srng: SRNG ring pointer */ -static inline void hal_srng_dst_hw_init_generic(void *halsoc, - struct hal_srng *srng) +static inline +void hal_srng_dst_hw_init_generic(struct hal_soc *hal, + struct hal_srng *srng) { - struct hal_soc *hal = (struct hal_soc *)halsoc; uint32_t reg_val = 0; uint64_t hp_addr = 0; @@ -1756,6 +1941,24 @@ static inline uint8_t hal_tx_comp_get_release_reason_generic(void *hal_desc) WBM_RELEASE_RING_2_TQM_RELEASE_REASON_LSB; } +/** + * hal_get_wbm_internal_error_generic() - is WBM internal error + * @hal_desc: completion ring descriptor pointer + * + * This function will return 0 or 1 - is it WBM internal error or not + * + * Return: uint8_t + */ +static inline uint8_t hal_get_wbm_internal_error_generic(void *hal_desc) +{ + uint32_t comp_desc = + *(uint32_t *)(((uint8_t *)hal_desc) + + WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_OFFSET); + + return (comp_desc & WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_MASK) >> + WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_LSB; +} + /** * hal_rx_dump_mpdu_start_tlv_generic: dump RX mpdu_start TLV in structured * human readable format. @@ -2005,6 +2208,33 @@ static void hal_tx_desc_set_search_index_generic(void *desc, } #endif +/** + * hal_tx_desc_set_cache_set_num_generic - Set the cache-set-num value + * @desc: Handle to Tx Descriptor + * @cache_num: Cache set number that should be used to cache the index + * based search results, for address and flow search. + * This value should be equal to LSB four bits of the hash value + * of match data, in case of search index points to an entry + * which may be used in content based search also. The value can + * be anything when the entry pointed by search index will not be + * used for content based search. + * + * Return: void + */ +#ifdef TCL_DATA_CMD_5_CACHE_SET_NUM_OFFSET +static void hal_tx_desc_set_cache_set_num_generic(void *desc, + uint8_t cache_num) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, CACHE_SET_NUM) |= + HAL_TX_SM(TCL_DATA_CMD_5, CACHE_SET_NUM, cache_num); +} +#else +static void hal_tx_desc_set_cache_set_num_generic(void *desc, + uint8_t cache_num) +{ +} +#endif + /** * hal_tx_set_pcp_tid_map_generic() - Configure default PCP to TID map table * @soc: HAL SoC context @@ -2016,12 +2246,10 @@ static void hal_tx_desc_set_search_index_generic(void *desc, * * Return: none */ -static void hal_tx_set_pcp_tid_map_generic(void *hal_soc, uint8_t *map) +static void hal_tx_set_pcp_tid_map_generic(struct hal_soc *soc, uint8_t *map) { uint32_t addr, value; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); @@ -2047,12 +2275,11 @@ static void hal_tx_set_pcp_tid_map_generic(void *hal_soc, uint8_t *map) * Return: void */ static -void hal_tx_update_pcp_tid_generic(void *hal_soc, uint8_t pcp, uint8_t tid) +void hal_tx_update_pcp_tid_generic(struct hal_soc *soc, + uint8_t pcp, uint8_t tid) { uint32_t addr, value, regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); @@ -2077,16 +2304,38 @@ void hal_tx_update_pcp_tid_generic(void *hal_soc, uint8_t pcp, uint8_t tid) * Return: void */ static -void hal_tx_update_tidmap_prty_generic(void *hal_soc, uint8_t value) +void hal_tx_update_tidmap_prty_generic(struct hal_soc *soc, uint8_t value) { uint32_t addr; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - addr = HWIO_TCL_R0_TID_MAP_PRTY_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); HAL_REG_WRITE(soc, addr, (value & HWIO_TCL_R0_TID_MAP_PRTY_RMSK)); } + +/** + * hal_rx_msdu_packet_metadata_get(): API to get the + * msdu information from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * @ hal_rx_msdu_metadata: pointer to the msdu info structure + */ +static void +hal_rx_msdu_packet_metadata_get_generic(uint8_t *buf, + void *pkt_msdu_metadata) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + struct hal_rx_msdu_metadata *msdu_metadata = + (struct hal_rx_msdu_metadata *)pkt_msdu_metadata; + + msdu_metadata->l3_hdr_pad = + HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + msdu_metadata->sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + msdu_metadata->da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); + msdu_metadata->sa_sw_peer_id = + HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} #endif /* _HAL_GENERIC_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h index 89a0f9be3436fe12c1e350f68256abe78b351ec7..49aff583a367982b9c41c3931d3035b0cd2d88d3 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h @@ -38,7 +38,12 @@ #include "mac_tcl_reg_seq_hwioreg.h" #include "ce_src_desc.h" #include "ce_stat_desc.h" +#ifdef QCA_WIFI_QCA6490 +#include "wfss_ce_channel_dst_reg_seq_hwioreg.h" +#include "wfss_ce_channel_src_reg_seq_hwioreg.h" +#else #include "wfss_ce_reg_seq_hwioreg.h" +#endif /* QCA_WIFI_QCA6490 */ #include "wbm_link_descriptor_ring.h" #include "wbm_reg_seq_hwioreg.h" #include "wbm_buffer_ring.h" @@ -57,7 +62,7 @@ #include "rxpcu_ppdu_end_info.h" #include "phyrx_he_sig_a_su.h" #include "phyrx_he_sig_a_mu_dl.h" -#if defined(CONFIG_MCL) && defined(QCA_WIFI_QCA6290_11AX) +#if defined(QCA_WIFI_QCA6290_11AX_MU_UL) && defined(QCA_WIFI_QCA6290_11AX) #include "phyrx_he_sig_a_mu_ul.h" #endif #include "phyrx_he_sig_b1_mu.h" @@ -73,22 +78,19 @@ #include "phyrx_rssi_legacy.h" #include "wcss_version.h" #include "rx_msdu_link.h" +#include "hal_internal.h" #define HAL_SRNG_REO_EXCEPTION HAL_SRNG_REO2SW1 #define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 #define HAL_NON_QOS_TID 16 -/* calculate the register address offset from bar0 of shadow register x */ -#ifdef QCA_WIFI_QCA6390 -#define SHADOW_REGISTER(x) (0x000008FC + (4 * (x))) -#else -#define SHADOW_REGISTER(x) (0x00003024 + (4 * (x))) -#endif - /* TODO: Check if the following can be provided directly by HW headers */ #define SRNG_LOOP_CNT_MASK REO_DESTINATION_RING_15_LOOPING_COUNT_MASK #define SRNG_LOOP_CNT_LSB REO_DESTINATION_RING_15_LOOPING_COUNT_LSB +/* HAL Macro to get the buffer info size */ +#define HAL_RX_BUFFINFO_NUM_DWORDS NUM_OF_DWORDS_BUFFER_ADDR_INFO + #define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS 100 /* milliseconds */ #define HAL_DEFAULT_VO_REO_TIMEOUT_MS 40 /* milliseconds */ @@ -114,6 +116,9 @@ #define HAL_REG_WRITE_CONFIRM(_soc, _reg, _value) \ hal_write32_mb_confirm(_soc, (_reg), (_value)) +#define HAL_REG_WRITE_CONFIRM_RETRY(_soc, _reg, _value, _recovery) \ + hal_write32_mb_confirm_retry(_soc, (_reg), (_value), (_recovery)) + #define HAL_REG_READ(_soc, _offset) \ hal_read32_mb(_soc, (_offset)) @@ -339,8 +344,9 @@ static inline void hal_set_link_desc_addr(void *desc, uint32_t cookie, * @tid: TID number * */ -static inline uint32_t hal_get_reo_qdesc_size(void *hal_soc, - uint32_t ba_window_size, int tid) +static inline +uint32_t hal_get_reo_qdesc_size(hal_soc_handle_t hal_soc_hdl, + uint32_t ba_window_size, int tid) { /* Return descriptor size corresponding to window size of 2 since * we set ba_window_size to 2 while setting up REO descriptors as diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h index aced2ab0fb012f7f1ea3d3ddbb35ddec2bcc7e09..6c796e3764255800676ef9d601b749a83ed16f74 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -62,6 +62,11 @@ extern bool is_hal_verbose_debug_enabled; params) #endif +/* + * dp_hal_soc - opaque handle for DP HAL soc + */ +struct hal_soc_handle; +typedef struct hal_soc_handle *hal_soc_handle_t; /* TBD: This should be movded to shared HW header file */ enum hal_srng_ring_id { @@ -178,6 +183,13 @@ enum hal_srng_dir { #define SRNG_LOCK_DESTROY(_lock) qdf_spinlock_destroy(_lock) struct hal_soc; + +/** + * dp_hal_ring - opaque handle for DP HAL SRNG + */ +struct hal_ring_handle; +typedef struct hal_ring_handle *hal_ring_handle_t; + #define MAX_SRNG_REG_GROUPS 2 /* Hal Srng bit mask @@ -195,6 +207,7 @@ struct hal_soc; * @dequeue_val: register value at the time of delayed write dequeue * @valid: whether this entry is valid or not * @enqueue_time: enqueue time (qdf_log_timestamp) + * @work_scheduled_time: work scheduled time (qdf_log_timestamp) * @dequeue_time: dequeue time (qdf_log_timestamp) */ struct hal_reg_write_q_elem { @@ -204,6 +217,7 @@ struct hal_reg_write_q_elem { uint32_t dequeue_val; uint8_t valid; qdf_time_t enqueue_time; + qdf_time_t work_scheduled_time; qdf_time_t dequeue_time; }; @@ -213,12 +227,14 @@ struct hal_reg_write_q_elem { * @dequeues: writes dequeued from delayed work (not written yet) * @coalesces: writes not enqueued since srng is already queued up * @direct: writes not enqueued and written to register directly + * @dequeue_delay: dequeue operation be delayed */ struct hal_reg_write_srng_stats { uint32_t enqueues; uint32_t dequeues; uint32_t coalesces; uint32_t direct; + uint32_t dequeue_delay; }; /** @@ -226,14 +242,14 @@ struct hal_reg_write_srng_stats { * @REG_WRITE_SCHED_DELAY_SUB_100us: index for delay < 100us * @REG_WRITE_SCHED_DELAY_SUB_1000us: index for delay < 1000us * @REG_WRITE_SCHED_DELAY_SUB_5000us: index for delay < 5000us - * @REG_WRITE_SCHED_DELAY_GE_5000us: index for delay >= 5000us + * @REG_WRITE_SCHED_DELAY_GT_5000us: index for delay >= 5000us * @REG_WRITE_SCHED_DELAY_HIST_MAX: Max value (nnsize of histogram array) */ enum hal_reg_sched_delay { REG_WRITE_SCHED_DELAY_SUB_100us, REG_WRITE_SCHED_DELAY_SUB_1000us, REG_WRITE_SCHED_DELAY_SUB_5000us, - REG_WRITE_SCHED_DELAY_GE_5000us, + REG_WRITE_SCHED_DELAY_GT_5000us, REG_WRITE_SCHED_DELAY_HIST_MAX, }; @@ -247,6 +263,7 @@ enum hal_reg_sched_delay { * @q_depth: current queue depth in delayed register write queue * @max_q_depth: maximum queue for delayed register write queue * @sched_delay: = kernel work sched delay + bus wakeup delay, histogram + * @dequeue_delay: dequeue operation be delayed */ struct hal_reg_write_soc_stats { qdf_atomic_t enqueues; @@ -257,6 +274,7 @@ struct hal_reg_write_soc_stats { qdf_atomic_t q_depth; uint32_t max_q_depth; uint32_t sched_delay[REG_WRITE_SCHED_DELAY_HIST_MAX]; + uint32_t dequeue_delay; }; #endif @@ -295,6 +313,9 @@ struct hal_srng { /* Interrupt batch counter threshold – in number of ring entries */ uint32_t intr_batch_cntr_thres_entries; + /* Applicable only for CE dest ring */ + uint32_t prefetch_timer; + /* MSI Address */ qdf_dma_addr_t msi_addr; @@ -373,6 +394,8 @@ struct hal_srng { #ifdef FEATURE_HAL_DELAYED_REG_WRITE /* flag to indicate whether srng is already queued for delayed write */ uint8_t reg_write_in_progress; + /* last dequeue elem time stamp */ + qdf_time_t last_dequeue_time; /* srng specific delayed write stats */ struct hal_reg_write_srng_stats wstats; @@ -392,38 +415,83 @@ struct hal_hw_srng_config { }; #define MAX_SHADOW_REGISTERS 36 +#define MAX_GENERIC_SHADOW_REG 5 + +/** + * struct shadow_reg_config - Hal soc structure that contains + * the list of generic shadow registers + * @target_register: target reg offset + * @shadow_config_index: shadow config index in shadow config + * list sent to FW + * @va: virtual addr of shadow reg + * + * This structure holds the generic registers that are mapped to + * the shadow region and holds the mapping of the target + * register offset to shadow config index provided to FW during + * init + */ +struct shadow_reg_config { + uint32_t target_register; + int shadow_config_index; + uint64_t va; +}; + +/* REO parameters to be passed to hal_reo_setup */ +struct hal_reo_params { + /** rx hash steering enabled or disabled */ + bool rx_hash_enabled; + /** reo remap 1 register */ + uint32_t remap1; + /** reo remap 2 register */ + uint32_t remap2; + /** fragment destination ring */ + uint8_t frag_dst_ring; + /** padding */ + uint8_t padding[3]; +}; struct hal_hw_txrx_ops { /* init and setup */ - void (*hal_srng_dst_hw_init)(void *hal, - struct hal_srng *srng); - void (*hal_srng_src_hw_init)(void *hal, - struct hal_srng *srng); - void (*hal_get_hw_hptp)(struct hal_soc *hal, void *hal_ring, + void (*hal_srng_dst_hw_init)(struct hal_soc *hal, + struct hal_srng *srng); + void (*hal_srng_src_hw_init)(struct hal_soc *hal, + struct hal_srng *srng); + void (*hal_get_hw_hptp)(struct hal_soc *hal, + hal_ring_handle_t hal_ring_hdl, uint32_t *headp, uint32_t *tailp, uint8_t ring_type); - void (*hal_reo_setup)(void *hal_soc, void *reoparams); - void (*hal_setup_link_idle_list)(void *hal_soc, - qdf_dma_addr_t scatter_bufs_base_paddr[], - void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs, - uint32_t scatter_buf_size, uint32_t last_buf_end_offset, - uint32_t num_entries); + void (*hal_reo_setup)(struct hal_soc *hal_soc, void *reoparams); + void (*hal_setup_link_idle_list)( + struct hal_soc *hal_soc, + qdf_dma_addr_t scatter_bufs_base_paddr[], + void *scatter_bufs_base_vaddr[], + uint32_t num_scatter_bufs, + uint32_t scatter_buf_size, + uint32_t last_buf_end_offset, + uint32_t num_entries); + qdf_iomem_t (*hal_get_window_address)(struct hal_soc *hal_soc, + qdf_iomem_t addr); void (*hal_reo_set_err_dst_remap)(void *hal_soc); /* tx */ void (*hal_tx_desc_set_dscp_tid_table_id)(void *desc, uint8_t id); - void (*hal_tx_set_dscp_tid_map)(void *hal_soc, uint8_t *map, + void (*hal_tx_set_dscp_tid_map)(struct hal_soc *hal_soc, uint8_t *map, uint8_t id); - void (*hal_tx_update_dscp_tid)(void *hal_soc, uint8_t tid, uint8_t id, + void (*hal_tx_update_dscp_tid)(struct hal_soc *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp); void (*hal_tx_desc_set_lmac_id)(void *desc, uint8_t lmac_id); void (*hal_tx_desc_set_buf_addr)(void *desc, dma_addr_t paddr, uint8_t pool_id, uint32_t desc_id, uint8_t type); void (*hal_tx_desc_set_search_type)(void *desc, uint8_t search_type); void (*hal_tx_desc_set_search_index)(void *desc, uint32_t search_index); - void (*hal_tx_comp_get_status)(void *desc, void *ts, void *hal); + void (*hal_tx_desc_set_cache_set_num)(void *desc, uint8_t search_index); + void (*hal_tx_comp_get_status)(void *desc, void *ts, + struct hal_soc *hal); uint8_t (*hal_tx_comp_get_release_reason)(void *hal_desc); + uint8_t (*hal_get_wbm_internal_error)(void *hal_desc); + void (*hal_tx_desc_set_mesh_en)(void *desc, uint8_t en); /* rx */ uint32_t (*hal_rx_msdu_start_nss_get)(uint8_t *); @@ -443,23 +511,93 @@ struct hal_hw_txrx_ops { void* (*hal_rx_link_desc_msdu0_ptr)(void *msdu_link_ptr); void (*hal_reo_status_get_header)(uint32_t *d, int b, void *h); uint32_t (*hal_rx_status_get_tlv_info)(void *rx_tlv_hdr, - void *ppdu_info, - void *hal); + void *ppdu_info, + hal_soc_handle_t hal_soc_hdl, + qdf_nbuf_t nbuf); void (*hal_rx_wbm_err_info_get)(void *wbm_desc, void *wbm_er_info); void (*hal_rx_dump_mpdu_start_tlv)(void *mpdustart, uint8_t dbg_level); - void (*hal_tx_set_pcp_tid_map)(void *hal_soc, uint8_t *map); - void (*hal_tx_update_pcp_tid_map)(void *hal_soc, uint8_t pcp, + void (*hal_tx_set_pcp_tid_map)(struct hal_soc *hal_soc, uint8_t *map); + void (*hal_tx_update_pcp_tid_map)(struct hal_soc *hal_soc, uint8_t pcp, uint8_t id); - void (*hal_tx_set_tidmap_prty)(void *hal_soc, uint8_t prio); + void (*hal_tx_set_tidmap_prty)(struct hal_soc *hal_soc, uint8_t prio); + uint8_t (*hal_rx_get_rx_fragment_number)(uint8_t *buf); + uint8_t (*hal_rx_msdu_end_da_is_mcbc_get)(uint8_t *buf); + uint8_t (*hal_rx_msdu_end_sa_is_valid_get)(uint8_t *buf); + uint16_t (*hal_rx_msdu_end_sa_idx_get)(uint8_t *buf); + uint32_t (*hal_rx_desc_is_first_msdu)(void *hw_desc_addr); + uint32_t (*hal_rx_msdu_end_l3_hdr_padding_get)(uint8_t *buf); + uint32_t (*hal_rx_encryption_info_valid)(uint8_t *buf); + void (*hal_rx_print_pn)(uint8_t *buf); + uint8_t (*hal_rx_msdu_end_first_msdu_get)(uint8_t *buf); + uint8_t (*hal_rx_msdu_end_da_is_valid_get)(uint8_t *buf); + uint8_t (*hal_rx_msdu_end_last_msdu_get)(uint8_t *buf); + bool (*hal_rx_get_mpdu_mac_ad4_valid)(uint8_t *buf); + uint32_t (*hal_rx_mpdu_start_sw_peer_id_get)(uint8_t *buf); + uint32_t (*hal_rx_mpdu_get_to_ds)(uint8_t *buf); + uint32_t (*hal_rx_mpdu_get_fr_ds)(uint8_t *buf); + uint8_t (*hal_rx_get_mpdu_frame_control_valid)(uint8_t *buf); + QDF_STATUS + (*hal_rx_mpdu_get_addr1)(uint8_t *buf, uint8_t *mac_addr); + QDF_STATUS + (*hal_rx_mpdu_get_addr2)(uint8_t *buf, uint8_t *mac_addr); + QDF_STATUS + (*hal_rx_mpdu_get_addr3)(uint8_t *buf, uint8_t *mac_addr); + QDF_STATUS + (*hal_rx_mpdu_get_addr4)(uint8_t *buf, uint8_t *mac_addr); + uint8_t (*hal_rx_get_mpdu_sequence_control_valid)(uint8_t *buf); + bool (*hal_rx_is_unicast)(uint8_t *buf); + uint32_t (*hal_rx_tid_get)(hal_soc_handle_t hal_soc_hdl, uint8_t *buf); + uint32_t (*hal_rx_hw_desc_get_ppduid_get)(void *hw_desc_addr); + uint32_t (*hal_rx_mpdu_start_mpdu_qos_control_valid_get)(uint8_t *buf); + uint32_t (*hal_rx_msdu_end_sa_sw_peer_id_get)(uint8_t *buf); + void * (*hal_rx_msdu0_buffer_addr_lsb)(void *link_desc_addr); + void * (*hal_rx_msdu_desc_info_ptr_get)(void *msdu0); + void * (*hal_ent_mpdu_desc_info)(void *hw_addr); + void * (*hal_dst_mpdu_desc_info)(void *hw_addr); + uint8_t (*hal_rx_get_fc_valid)(uint8_t *buf); + uint8_t (*hal_rx_get_to_ds_flag)(uint8_t *buf); + uint8_t (*hal_rx_get_mac_addr2_valid)(uint8_t *buf); + uint8_t (*hal_rx_get_filter_category)(uint8_t *buf); + uint32_t (*hal_rx_get_ppdu_id)(uint8_t *buf); + void (*hal_reo_config)(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params); + uint32_t (*hal_rx_msdu_flow_idx_get)(uint8_t *buf); + bool (*hal_rx_msdu_flow_idx_invalid)(uint8_t *buf); + bool (*hal_rx_msdu_flow_idx_timeout)(uint8_t *buf); + uint32_t (*hal_rx_msdu_fse_metadata_get)(uint8_t *buf); + uint16_t (*hal_rx_msdu_cce_metadata_get)(uint8_t *buf); + void + (*hal_rx_msdu_get_flow_params)( + uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index); + uint16_t (*hal_rx_tlv_get_tcp_chksum)(uint8_t *buf); + uint16_t (*hal_rx_get_rx_sequence)(uint8_t *buf); + void (*hal_rx_get_bb_info)(void *rx_tlv, void *ppdu_info_handle); + void (*hal_rx_get_rtt_info)(void *rx_tlv, void *ppdu_info_handle); + void (*hal_rx_msdu_packet_metadata_get)(uint8_t *buf, + void *msdu_pkt_metadata); + uint16_t (*hal_rx_get_fisa_cumulative_l4_checksum)(uint8_t *buf); + uint16_t (*hal_rx_get_fisa_cumulative_ip_length)(uint8_t *buf); + bool (*hal_rx_get_udp_proto)(uint8_t *buf); + bool (*hal_rx_get_fisa_flow_agg_continuation)(uint8_t *buf); + uint8_t (*hal_rx_get_fisa_flow_agg_count)(uint8_t *buf); + bool (*hal_rx_get_fisa_timeout)(uint8_t *buf); + void (*hal_rx_msdu_get_reo_destination_indication)(uint8_t *buf, + uint32_t *reo_destination_indication); }; /** * struct hal_soc_stats - Hal layer stats * @reg_write_fail: number of failed register writes * @wstats: delayed register write stats + * @shadow_reg_write_fail: shadow reg write failure stats + * @shadow_reg_write_succ: shadow reg write success stats * * This structure holds all the statistics at HAL layer. */ @@ -468,6 +606,10 @@ struct hal_soc_stats { #ifdef FEATURE_HAL_DELAYED_REG_WRITE struct hal_reg_write_soc_stats wstats; #endif +#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE + uint32_t shadow_reg_write_fail; + uint32_t shadow_reg_write_succ; +#endif }; #ifdef ENABLE_HAL_REG_WR_HISTORY @@ -505,12 +647,17 @@ struct hal_reg_write_fail_history { #endif /** - * HAL context to be used to access SRNG APIs (currently used by data path - * and transport (CE) modules) + * struct hal_soc - HAL context to be used to access SRNG APIs + * (currently used by data path and + * transport (CE) modules) + * @list_shadow_reg_config: array of generic regs mapped to + * shadow regs + * @num_generic_shadow_regs_configured: number of generic regs + * mapped to shadow regs */ struct hal_soc { /* HIF handle to access HW registers */ - void *hif_handle; + struct hif_opaque_softc *hif_handle; /* QDF device handle */ qdf_device_t qdf_dev; @@ -543,11 +690,16 @@ struct hal_soc { uint32_t register_window; qdf_spinlock_t register_access_lock; + /* Static window map configuration for multiple window write*/ + bool static_window_map; + /* srng table */ struct hal_hw_srng_config *hw_srng_table; int32_t *hal_hw_reg_offset; struct hal_hw_txrx_ops *ops; + /* Indicate srngs initialization */ + bool init_phase; /* Hal level stats */ struct hal_soc_stats stats; #ifdef ENABLE_HAL_REG_WR_HISTORY @@ -566,6 +718,11 @@ struct hal_soc { uint32_t read_idx; #endif qdf_atomic_t active_work_cnt; +#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE + struct shadow_reg_config + list_shadow_reg_config[MAX_GENERIC_SHADOW_REG]; + int num_generic_shadow_regs_configured; +#endif }; #ifdef FEATURE_HAL_DELAYED_REG_WRITE @@ -583,7 +740,48 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, void __iomem *addr, uint32_t value); #endif + +void hal_qca6750_attach(struct hal_soc *hal_soc); +void hal_qca6490_attach(struct hal_soc *hal_soc); void hal_qca6390_attach(struct hal_soc *hal_soc); void hal_qca6290_attach(struct hal_soc *hal_soc); void hal_qca8074_attach(struct hal_soc *hal_soc); + +/* + * hal_soc_to_dp_hal_roc - API to convert hal_soc to opaque + * dp_hal_soc handle type + * @hal_soc - hal_soc type + * + * Return: hal_soc_handle_t type + */ +static inline +hal_soc_handle_t hal_soc_to_hal_soc_handle(struct hal_soc *hal_soc) +{ + return (hal_soc_handle_t)hal_soc; +} + +/* + * hal_srng_to_hal_ring_handle - API to convert hal_srng to opaque + * dp_hal_ring handle type + * @hal_srng - hal_srng type + * + * Return: hal_ring_handle_t type + */ +static inline +hal_ring_handle_t hal_srng_to_hal_ring_handle(struct hal_srng *hal_srng) +{ + return (hal_ring_handle_t)hal_srng; +} + +/* + * hal_ring_handle_to_hal_srng - API to convert dp_hal_ring to hal_srng handle + * @hal_ring - hal_ring_handle_t type + * + * Return: hal_srng pointer type + */ +static inline +struct hal_srng *hal_ring_handle_to_hal_srng(hal_ring_handle_t hal_ring) +{ + return (struct hal_srng *)hal_ring; +} #endif /* _HAL_INTERNAL_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c index 97b1d28f2a6826b808b523628f17be2bf43ec04d..6a0b155a022b4b1f7f167134c85d7bb190ce4ec8 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -91,9 +92,11 @@ static inline uint32_t hal_update_non_ba_win_size(int tid, * @tid: TID * */ -void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size, - uint32_t start_seq, void *hw_qdesc_vaddr, qdf_dma_addr_t hw_qdesc_paddr, - int pn_type) +void hal_reo_qdesc_setup(hal_soc_handle_t hal_soc_hdl, int tid, + uint32_t ba_window_size, + uint32_t start_seq, void *hw_qdesc_vaddr, + qdf_dma_addr_t hw_qdesc_paddr, + int pn_type) { uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr; uint32_t *reo_queue_ext_desc; @@ -172,8 +175,10 @@ void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size, HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_SHALL_BE_UNEVEN, 1); - HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_HANDLING_ENABLE, - pn_enable); + /* + * TODO: Need to check if PN handling in SW needs to be enabled + * So far this is not a requirement + */ HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, PN_SIZE, pn_size); @@ -273,10 +278,10 @@ qdf_export_symbol(hal_reo_qdesc_setup); * @ac: Access category * @value: window size to get */ -void hal_get_ba_aging_timeout(void *hal_soc, uint8_t ac, +void hal_get_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac, uint32_t *value) { - struct hal_soc *soc = (struct hal_soc *)hal_soc; + struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; switch (ac) { case WME_AC_BE: @@ -315,10 +320,10 @@ qdf_export_symbol(hal_get_ba_aging_timeout); * ac: 0 - Background, 1 - Best Effort, 2 - Video, 3 - Voice * @value: Input value to set */ -void hal_set_ba_aging_timeout(void *hal_soc, uint8_t ac, +void hal_set_ba_aging_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t ac, uint32_t value) { - struct hal_soc *soc = (struct hal_soc *)hal_soc; + struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; switch (ac) { case WME_AC_BE: @@ -413,18 +418,20 @@ inline void hal_reo_cmd_set_descr_addr(uint32_t *reo_desc, } } -inline int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_queue_stats(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { uint32_t *reo_desc, val; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - hal_srng_access_start(soc, reo_ring); - reo_desc = hal_srng_src_get_next(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Out of cmd ring entries", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } @@ -434,7 +441,7 @@ inline int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_get_queue_stats) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -448,15 +455,15 @@ inline int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, HAL_DESC_SET_FIELD(reo_desc, REO_GET_QUEUE_STATS_2, CLEAR_STATS, cmd->u.stats_params.clear); - if (hif_pm_runtime_get(soc->hif_handle, + if (hif_pm_runtime_get(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD) == 0) { - hal_srng_access_end(soc, reo_ring); - hif_pm_runtime_put(soc->hif_handle, + hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); + hif_pm_runtime_put(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD); } else { - hal_srng_access_end_reap(soc, reo_ring); - hal_srng_set_event(reo_ring, HAL_SRNG_FLUSH_EVENT); - hal_srng_inc_flush_cnt(reo_ring); + hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } val = reo_desc[CMD_HEADER_DW_OFFSET]; @@ -465,17 +472,19 @@ inline int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, } qdf_export_symbol(hal_reo_cmd_queue_stats); -inline int hal_reo_cmd_flush_queue(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_flush_queue(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { uint32_t *reo_desc, val; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - hal_srng_access_start(soc, reo_ring); - reo_desc = hal_srng_src_get_next(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Out of cmd ring entries", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } @@ -485,7 +494,7 @@ inline int hal_reo_cmd_flush_queue(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_flush_queue) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -504,43 +513,45 @@ inline int hal_reo_cmd_flush_queue(void *reo_ring, struct hal_soc *soc, BLOCK_RESOURCE_INDEX, cmd->u.fl_queue_params.index); } - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); val = reo_desc[CMD_HEADER_DW_OFFSET]; return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER_0, REO_CMD_NUMBER, val); } qdf_export_symbol(hal_reo_cmd_flush_queue); -inline int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_flush_cache(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { uint32_t *reo_desc, val; struct hal_reo_cmd_flush_cache_params *cp; uint8_t index = 0; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; cp = &cmd->u.fl_cache_params; - hal_srng_access_start(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); /* We need a cache block resource for this operation, and REO HW has * only 4 such blocking resources. These resources are managed using * reo_res_bitmap, and we return failure if none is available. */ if (cp->block_use_after_flush) { - index = hal_find_zero_bit(soc->reo_res_bitmap); + index = hal_find_zero_bit(hal_soc->reo_res_bitmap); if (index > 3) { qdf_print("%s, No blocking resource available!", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } - soc->index = index; + hal_soc->index = index; } - reo_desc = hal_srng_src_get_next(soc, reo_ring); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { - hal_srng_access_end(soc, reo_ring); - hal_srng_dump(reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); + hal_srng_dump(hal_ring_handle_to_hal_srng(hal_ring_hdl)); return -EBUSY; } @@ -550,7 +561,7 @@ inline int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_flush_cache) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -580,17 +591,17 @@ inline int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, BLOCK_CACHE_USAGE_AFTER_FLUSH, cp->block_use_after_flush); HAL_DESC_SET_FIELD(reo_desc, REO_FLUSH_CACHE_2, FLUSH_ENTIRE_CACHE, - cp->flush_all); + cp->flush_entire_cache); - if (hif_pm_runtime_get(soc->hif_handle, + if (hif_pm_runtime_get(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD) == 0) { - hal_srng_access_end(soc, reo_ring); - hif_pm_runtime_put(soc->hif_handle, + hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); + hif_pm_runtime_put(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD); } else { - hal_srng_access_end_reap(soc, reo_ring); - hal_srng_set_event(reo_ring, HAL_SRNG_FLUSH_EVENT); - hal_srng_inc_flush_cnt(reo_ring); + hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } val = reo_desc[CMD_HEADER_DW_OFFSET]; @@ -599,30 +610,32 @@ inline int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, } qdf_export_symbol(hal_reo_cmd_flush_cache); -inline int hal_reo_cmd_unblock_cache(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_unblock_cache(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t *reo_desc, val; uint8_t index = 0; - hal_srng_access_start(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); if (cmd->u.unblk_cache_params.type == UNBLOCK_RES_INDEX) { - index = hal_find_one_bit(soc->reo_res_bitmap); + index = hal_find_one_bit(hal_soc->reo_res_bitmap); if (index > 3) { - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); qdf_print("%s: No blocking resource to unblock!", __func__); return -EBUSY; } } - reo_desc = hal_srng_src_get_next(soc, reo_ring); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Out of cmd ring entries", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } @@ -632,7 +645,7 @@ inline int hal_reo_cmd_unblock_cache(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_unblock_cache) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -648,24 +661,26 @@ inline int hal_reo_cmd_unblock_cache(void *reo_ring, struct hal_soc *soc, cmd->u.unblk_cache_params.index); } - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); val = reo_desc[CMD_HEADER_DW_OFFSET]; return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER_0, REO_CMD_NUMBER, val); } qdf_export_symbol(hal_reo_cmd_unblock_cache); -inline int hal_reo_cmd_flush_timeout_list(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_flush_timeout_list(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t *reo_desc, val; - hal_srng_access_start(soc, reo_ring); - reo_desc = hal_srng_src_get_next(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Out of cmd ring entries", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } @@ -675,7 +690,7 @@ inline int hal_reo_cmd_flush_timeout_list(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_flush_timeout_list) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -693,27 +708,29 @@ inline int hal_reo_cmd_flush_timeout_list(void *reo_ring, struct hal_soc *soc, MINIMUM_FORWARD_BUF_COUNT, cmd->u.fl_tim_list_params.min_fwd_buf); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); val = reo_desc[CMD_HEADER_DW_OFFSET]; return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER_0, REO_CMD_NUMBER, val); } qdf_export_symbol(hal_reo_cmd_flush_timeout_list); -inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, - struct hal_reo_cmd_params *cmd) +inline int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_cmd_params *cmd) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t *reo_desc, val; struct hal_reo_cmd_update_queue_params *p; p = &cmd->u.upd_queue_params; - hal_srng_access_start(soc, reo_ring); - reo_desc = hal_srng_src_get_next(soc, reo_ring); + hal_srng_access_start(hal_soc_hdl, hal_ring_hdl); + reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); if (!reo_desc) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Out of cmd ring entries", __func__); - hal_srng_access_end(soc, reo_ring); + hal_srng_access_end(hal_soc, hal_ring_hdl); return -EBUSY; } @@ -723,7 +740,7 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); - qdf_mem_zero((void *)(reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), + qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER), sizeof(struct reo_update_rx_reo_queue) - (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2)); @@ -901,15 +918,15 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_8, PN_127_96, p->pn_127_96); - if (hif_pm_runtime_get(soc->hif_handle, + if (hif_pm_runtime_get(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD) == 0) { - hal_srng_access_end(soc, reo_ring); - hif_pm_runtime_put(soc->hif_handle, + hal_srng_access_end(hal_soc_hdl, hal_ring_hdl); + hif_pm_runtime_put(hal_soc->hif_handle, RTPM_ID_HAL_REO_CMD); } else { - hal_srng_access_end_reap(soc, reo_ring); - hal_srng_set_event(reo_ring, HAL_SRNG_FLUSH_EVENT); - hal_srng_inc_flush_cnt(reo_ring); + hal_srng_access_end_reap(hal_soc_hdl, hal_ring_hdl); + hal_srng_set_event(hal_ring_hdl, HAL_SRNG_FLUSH_EVENT); + hal_srng_inc_flush_cnt(hal_ring_hdl); } val = reo_desc[CMD_HEADER_DW_OFFSET]; @@ -918,10 +935,12 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, } qdf_export_symbol(hal_reo_cmd_update_rx_queue); -inline void hal_reo_queue_stats_status(uint32_t *reo_desc, - struct hal_reo_queue_status *st, - struct hal_soc *hal_soc) +inline void +hal_reo_queue_stats_status(uint32_t *reo_desc, + struct hal_reo_queue_status *st, + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1111,10 +1130,12 @@ inline void hal_reo_queue_stats_status(uint32_t *reo_desc, } qdf_export_symbol(hal_reo_queue_stats_status); -inline void hal_reo_flush_queue_status(uint32_t *reo_desc, - struct hal_reo_flush_queue_status *st, - struct hal_soc *hal_soc) +inline void +hal_reo_flush_queue_status(uint32_t *reo_desc, + struct hal_reo_flush_queue_status *st, + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1133,10 +1154,12 @@ inline void hal_reo_flush_queue_status(uint32_t *reo_desc, } qdf_export_symbol(hal_reo_flush_queue_status); -inline void hal_reo_flush_cache_status(uint32_t *reo_desc, struct hal_soc *soc, - struct hal_reo_flush_cache_status *st, - struct hal_soc *hal_soc) +inline void +hal_reo_flush_cache_status(uint32_t *reo_desc, + struct hal_reo_flush_cache_status *st, + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1160,7 +1183,8 @@ inline void hal_reo_flush_cache_status(uint32_t *reo_desc, struct hal_soc *soc, BLOCK_ERROR_DETAILS, val); if (!st->block_error) - qdf_set_bit(soc->index, (unsigned long *)&soc->reo_res_bitmap); + qdf_set_bit(hal_soc->index, + (unsigned long *)&hal_soc->reo_res_bitmap); /* cache flush status */ val = reo_desc[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_2, @@ -1189,9 +1213,10 @@ inline void hal_reo_flush_cache_status(uint32_t *reo_desc, struct hal_soc *soc, qdf_export_symbol(hal_reo_flush_cache_status); inline void hal_reo_unblock_cache_status(uint32_t *reo_desc, - struct hal_soc *soc, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_unblk_cache_status *st) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1200,7 +1225,7 @@ inline void hal_reo_unblock_cache_status(uint32_t *reo_desc, /* header */ hal_reo_status_get_header(reo_desc, HAL_REO_UNBLK_CACHE_STATUS_TLV, - &(st->header), soc); + &st->header, hal_soc); /* error bit */ val = reo_desc[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_2, @@ -1217,17 +1242,18 @@ inline void hal_reo_unblock_cache_status(uint32_t *reo_desc, val); if (!st->error && (st->unblock_type == UNBLOCK_RES_INDEX)) - qdf_clear_bit(soc->index, - (unsigned long *)&soc->reo_res_bitmap); + qdf_clear_bit(hal_soc->index, + (unsigned long *)&hal_soc->reo_res_bitmap); } qdf_export_symbol(hal_reo_unblock_cache_status); inline void hal_reo_flush_timeout_list_status( uint32_t *reo_desc, struct hal_reo_flush_timeout_list_status *st, - struct hal_soc *hal_soc) + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1271,8 +1297,9 @@ qdf_export_symbol(hal_reo_flush_timeout_list_status); inline void hal_reo_desc_thres_reached_status( uint32_t *reo_desc, struct hal_reo_desc_thres_reached_status *st, - struct hal_soc *hal_soc) + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; uint32_t val; /* Offsets of descriptor fields defined in HW headers start @@ -1328,10 +1355,13 @@ inline void hal_reo_desc_thres_reached_status( } qdf_export_symbol(hal_reo_desc_thres_reached_status); -inline void hal_reo_rx_update_queue_status(uint32_t *reo_desc, - struct hal_reo_update_rx_queue_status *st, - struct hal_soc *hal_soc) +inline void +hal_reo_rx_update_queue_status(uint32_t *reo_desc, + struct hal_reo_update_rx_queue_status *st, + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + /* Offsets of descriptor fields defined in HW headers start * from the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); @@ -1351,15 +1381,17 @@ qdf_export_symbol(hal_reo_rx_update_queue_status); * * Return: none */ -inline void hal_reo_init_cmd_ring(struct hal_soc *soc, void *hal_srng) +inline void hal_reo_init_cmd_ring(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { int cmd_num; uint32_t *desc_addr; struct hal_srng_params srng_params; uint32_t desc_size; uint32_t num_desc; + struct hal_soc *soc = (struct hal_soc *)hal_soc_hdl; - hal_get_srng_params(soc, hal_srng, &srng_params); + hal_get_srng_params(hal_soc_hdl, hal_ring_hdl, &srng_params); desc_addr = (uint32_t *)(srng_params.ring_base_vaddr); desc_addr += (sizeof(struct tlv_32_hdr) >> 2); diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h index c9b1265afa199593a5fbe1ab4933ddf0333a05fd..e6d4ba1fede6810aea743829afd0de0cdcff9139 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -179,7 +180,7 @@ struct hal_reo_cmd_flush_queue_params { * @cache_block_res_index: Blocking resource to be used * @flush_no_inval: Flush without invalidatig descriptor * @use_after_flush: Block usage after flush till unblock command - * @flush_all: Flush entire REO cache + * @flush_entire_cache: Flush entire REO cache */ struct hal_reo_cmd_flush_cache_params { bool fwd_mpdus_in_queue; @@ -187,7 +188,7 @@ struct hal_reo_cmd_flush_cache_params { uint8_t cache_block_res_index; bool flush_no_inval; bool block_use_after_flush; - bool flush_all; + bool flush_entire_cache; }; /** @@ -496,43 +497,51 @@ void hal_reo_cmd_set_descr_addr(uint32_t *reo_desc, enum hal_reo_cmd_type type, uint32_t paddr_lo, uint8_t paddr_hi); -int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_queue_stats(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); -int hal_reo_cmd_flush_queue(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_flush_queue(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); -int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_flush_cache(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); -int hal_reo_cmd_unblock_cache(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_unblock_cache(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); -int hal_reo_cmd_flush_timeout_list(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_flush_timeout_list(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); -int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, +int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl, + hal_soc_handle_t hal_soc_hdl, struct hal_reo_cmd_params *cmd); /* REO status ring routines */ void hal_reo_queue_stats_status(uint32_t *reo_desc, struct hal_reo_queue_status *st, - struct hal_soc *hal_soc); + hal_soc_handle_t hal_soc_hdl); void hal_reo_flush_queue_status(uint32_t *reo_desc, - struct hal_reo_flush_queue_status *st, - struct hal_soc *hal_soc); -void hal_reo_flush_cache_status(uint32_t *reo_desc, struct hal_soc *soc, - struct hal_reo_flush_cache_status *st, - struct hal_soc *hal_soc); -void hal_reo_unblock_cache_status(uint32_t *reo_desc, struct hal_soc *soc, - struct hal_reo_unblk_cache_status *st); + struct hal_reo_flush_queue_status *st, + hal_soc_handle_t hal_soc_hdl); +void hal_reo_flush_cache_status(uint32_t *reo_desc, + struct hal_reo_flush_cache_status *st, + hal_soc_handle_t hal_soc_hdl); +void hal_reo_unblock_cache_status(uint32_t *reo_desc, + hal_soc_handle_t hal_soc_hdl, + struct hal_reo_unblk_cache_status *st); void hal_reo_flush_timeout_list_status( uint32_t *reo_desc, struct hal_reo_flush_timeout_list_status *st, - struct hal_soc *hal_soc); + hal_soc_handle_t hal_soc_hdl); void hal_reo_desc_thres_reached_status( uint32_t *reo_desc, struct hal_reo_desc_thres_reached_status *st, - struct hal_soc *hal_soc); + hal_soc_handle_t hal_soc_hdl); void hal_reo_rx_update_queue_status(uint32_t *reo_desc, struct hal_reo_update_rx_queue_status *st, - struct hal_soc *hal_soc); + hal_soc_handle_t hal_soc_hdl); -void hal_reo_init_cmd_ring(struct hal_soc *soc, void *hal_srng); +void hal_reo_init_cmd_ring(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl); #endif /* _HAL_REO_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h index d49fba1e46275259e2146bd2ed4139b9e9f28011..2de9b90d51f41e876ba986f76fcd0a7598af276b 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,7 +19,7 @@ #ifndef _HAL_RX_H_ #define _HAL_RX_H_ -#include +#include #define HAL_RX_OFFSET(block, field) block##_##field##_OFFSET #define HAL_RX_LSB(block, field) block##_##field##_LSB @@ -30,16 +30,18 @@ HAL_RX_MASk(block, field)) >> \ HAL_RX_LSB(block, field)) -#ifdef NO_RX_PKT_HDR_TLV -/* RX_BUFFER_SIZE = 1536 data bytes + 256 RX TLV bytes. We are avoiding - * 128 bytes of RX_PKT_HEADER_TLV. - */ -#define RX_BUFFER_SIZE 1792 -#else -/* RX_BUFFER_SIZE = 1536 data bytes + 384 RX TLV bytes + some spare bytes */ -#define RX_BUFFER_SIZE 2048 +/* BUFFER_SIZE = 1536 data bytes + 384 RX TLV bytes + some spare bytes */ +#ifndef RX_DATA_BUFFER_SIZE +#define RX_DATA_BUFFER_SIZE 2048 +#endif + +#ifndef RX_MONITOR_BUFFER_SIZE +#define RX_MONITOR_BUFFER_SIZE 2048 #endif +/* HAL_RX_NON_QOS_TID = NON_QOS_TID which is 16 */ +#define HAL_RX_NON_QOS_TID 16 + enum { HAL_HW_RX_DECAP_FORMAT_RAW = 0, HAL_HW_RX_DECAP_FORMAT_NWIFI, @@ -70,6 +72,22 @@ struct hal_wbm_err_desc_info { reserved_2:3; }; +/** + * struct hal_rx_msdu_metadata:Structure to hold rx fast path information. + * + * @l3_hdr_pad: l3 header padding + * @reserved: Reserved bits + * @sa_sw_peer_id: sa sw peer id + * @sa_idx: sa index + * @da_idx: da index + */ +struct hal_rx_msdu_metadata { + uint32_t l3_hdr_pad:16, + sa_sw_peer_id:16; + uint32_t sa_idx:16, + da_idx:16; +}; + /** * enum hal_reo_error_code: Enum which encapsulates "reo_push_reason" * @@ -128,12 +146,14 @@ enum hal_rx_msdu_desc_flags { * [2] AMPDU flag * [3] raw_ampdu * @peer_meta_data: Upper bits containing peer id, vdev id + * @bar_frame: indicates if received frame is a bar frame */ struct hal_rx_mpdu_desc_info { uint16_t msdu_count; uint16_t mpdu_seq; /* 12 bits for length */ uint32_t mpdu_flags; uint32_t peer_meta_data; /* sw progamed meta-data:MAC Id & peer Id */ + uint16_t bar_frame; }; /** @@ -209,6 +229,24 @@ enum hal_rx_ret_buf_manager { (paddr_hi << BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB) & \ BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK) +#define HAL_RX_COOKIE_INVALID_MASK 0x80000000 + +/* + * macro to get the invalid bit for sw cookie + */ +#define HAL_RX_BUF_COOKIE_INVALID_GET(buff_addr_info) \ + ((*(((unsigned int *) buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) & \ + HAL_RX_COOKIE_INVALID_MASK) + +/* + * macro to set the invalid bit for sw cookie + */ +#define HAL_RX_BUF_COOKIE_INVALID_SET(buff_addr_info) \ + ((*(((unsigned int *) buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) |= \ + HAL_RX_COOKIE_INVALID_MASK) + /* * macro to set the cookie into the rxdma ring entry */ @@ -263,6 +301,28 @@ enum hal_rx_ret_buf_manager { BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK, \ BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB)) +#define HAL_RX_LINK_COOKIE_INVALID_MASK 0x40000000 + +#define HAL_RX_BUF_LINK_COOKIE_INVALID_GET(buff_addr_info) \ + ((*(((unsigned int *)buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) & \ + HAL_RX_LINK_COOKIE_INVALID_MASK) + +#define HAL_RX_BUF_LINK_COOKIE_INVALID_SET(buff_addr_info) \ + ((*(((unsigned int *)buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) |= \ + HAL_RX_LINK_COOKIE_INVALID_MASK) + +#define HAL_RX_REO_BUF_LINK_COOKIE_INVALID_GET(reo_desc) \ + (HAL_RX_BUF_LINK_COOKIE_INVALID_GET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + +#define HAL_RX_REO_BUF_LINK_COOKIE_INVALID_SET(reo_desc) \ + (HAL_RX_BUF_LINK_COOKIE_INVALID_SET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + /* TODO: Convert the following structure fields accesseses to offsets */ #define HAL_RX_REO_BUFFER_ADDR_39_32_GET(reo_desc) \ @@ -275,6 +335,16 @@ enum hal_rx_ret_buf_manager { (((struct reo_destination_ring *) \ reo_desc)->buf_or_link_desc_addr_info))) +#define HAL_RX_REO_BUF_COOKIE_INVALID_GET(reo_desc) \ + (HAL_RX_BUF_COOKIE_INVALID_GET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + +#define HAL_RX_REO_BUF_COOKIE_INVALID_SET(reo_desc) \ + (HAL_RX_BUF_COOKIE_INVALID_SET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + #define HAL_RX_REO_BUF_COOKIE_GET(reo_desc) \ (HAL_RX_BUF_COOKIE_GET(& \ (((struct reo_destination_ring *) \ @@ -319,6 +389,11 @@ enum hal_rx_ret_buf_manager { HAL_RX_MPDU_AMPDU_FLAG_GET(mpdu_info_ptr) | \ HAL_RX_MPDU_RAW_MPDU_GET(mpdu_info_ptr)) +#define HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info_ptr) \ + ((mpdu_info_ptr[RX_MPDU_DESC_INFO_0_BAR_FRAME_OFFSET >> 2] & \ + RX_MPDU_DESC_INFO_0_BAR_FRAME_MASK) >> \ + RX_MPDU_DESC_INFO_0_BAR_FRAME_LSB) + #define HAL_RX_MSDU_PKT_LENGTH_GET(msdu_info_ptr) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \ @@ -396,6 +471,10 @@ enum hal_rx_ret_buf_manager { RX_MSDU_DESC_INFO_0_DA_IDX_TIMEOUT_OFFSET)) & \ RX_MSDU_DESC_INFO_0_DA_IDX_TIMEOUT_MASK) +#define HAL_RX_REO_MSDU_REO_DST_IND_GET(reo_desc) \ + (HAL_RX_MSDU_REO_DST_IND_GET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->rx_msdu_desc_info_details))) #define HAL_RX_MSDU_FLAGS_GET(msdu_info_ptr) \ (HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_GET(msdu_info_ptr) | \ @@ -407,43 +486,12 @@ enum hal_rx_ret_buf_manager { HAL_RX_MSDU_DA_IS_MCBC_FLAG_GET(msdu_info_ptr) | \ HAL_RX_MSDU_DA_IDX_TIMEOUT_FLAG_GET(msdu_info_ptr)) - -#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_4_PN_31_0_OFFSET)), \ - RX_MPDU_INFO_4_PN_31_0_MASK, \ - RX_MPDU_INFO_4_PN_31_0_LSB)) - -#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_5_PN_63_32_OFFSET)), \ - RX_MPDU_INFO_5_PN_63_32_MASK, \ - RX_MPDU_INFO_5_PN_63_32_LSB)) - -#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_6_PN_95_64_OFFSET)), \ - RX_MPDU_INFO_6_PN_95_64_MASK, \ - RX_MPDU_INFO_6_PN_95_64_LSB)) - -#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_7_PN_127_96_OFFSET)), \ - RX_MPDU_INFO_7_PN_127_96_MASK, \ - RX_MPDU_INFO_7_PN_127_96_LSB)) - #define HAL_RX_MPDU_ENCRYPT_TYPE_GET(_rx_mpdu_info) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ RX_MPDU_INFO_3_ENCRYPT_TYPE_OFFSET)), \ RX_MPDU_INFO_3_ENCRYPT_TYPE_MASK, \ RX_MPDU_INFO_3_ENCRYPT_TYPE_LSB)) -#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ - RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_MASK, \ - RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_LSB)) - #define HAL_RX_FLD_SET(_ptr, _wrd, _field, _val) \ (*(uint32_t *)(((uint8_t *)_ptr) + \ _wrd ## _ ## _field ## _OFFSET) |= \ @@ -477,6 +525,7 @@ static inline void hal_rx_mpdu_desc_info_get(void *desc_addr, mpdu_desc_info->mpdu_flags = HAL_RX_MPDU_FLAGS_GET(mpdu_info); mpdu_desc_info->peer_meta_data = HAL_RX_MPDU_DESC_PEER_META_DATA_GET(mpdu_info); + mpdu_desc_info->bar_frame = HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info); } /* @@ -605,6 +654,9 @@ struct rx_pkt_hdr_tlv { #define RXDMA_OPTIMIZATION +/* rx_pkt_tlvs structure should be used to process Data buffers, monitor status + * buffers, monitor destination buffers and monitor descriptor buffers. + */ #ifdef RXDMA_OPTIMIZATION /* * The RX_PADDING_BYTES is required so that the TLV's don't @@ -639,7 +691,33 @@ struct rx_pkt_tlvs { }; #endif /* RXDMA_OPTIMIZATION */ -#define RX_PKT_TLVS_LEN (sizeof(struct rx_pkt_tlvs)) +/* rx_mon_pkt_tlvs structure should be used to process monitor data buffers */ +#ifdef RXDMA_OPTIMIZATION +struct rx_mon_pkt_tlvs { + struct rx_msdu_end_tlv msdu_end_tlv; /* 72 bytes */ + struct rx_attention_tlv attn_tlv; /* 16 bytes */ + struct rx_msdu_start_tlv msdu_start_tlv;/* 40 bytes */ + uint8_t rx_padding0[RX_PADDING0_BYTES]; /* 4 bytes */ + struct rx_mpdu_start_tlv mpdu_start_tlv;/* 96 bytes */ + struct rx_mpdu_end_tlv mpdu_end_tlv; /* 12 bytes */ + uint8_t rx_padding1[RX_PADDING1_BYTES]; /* 16 bytes */ + struct rx_pkt_hdr_tlv pkt_hdr_tlv; /* 128 bytes */ +}; +#else /* RXDMA_OPTIMIZATION */ +struct rx_mon_pkt_tlvs { + struct rx_attention_tlv attn_tlv; + struct rx_mpdu_start_tlv mpdu_start_tlv; + struct rx_msdu_start_tlv msdu_start_tlv; + struct rx_msdu_end_tlv msdu_end_tlv; + struct rx_mpdu_end_tlv mpdu_end_tlv; + struct rx_pkt_hdr_tlv pkt_hdr_tlv; +}; +#endif + +#define SIZE_OF_MONITOR_TLV sizeof(struct rx_mon_pkt_tlvs) +#define SIZE_OF_DATA_RX_TLV sizeof(struct rx_pkt_tlvs) + +#define RX_PKT_TLVS_LEN SIZE_OF_DATA_RX_TLV #ifdef NO_RX_PKT_HDR_TLV static inline uint8_t @@ -678,45 +756,35 @@ static inline uint8_t } /* - * @ hal_rx_encryption_info_valid: Returns encryption type. + * hal_rx_encryption_info_valid(): Returns encryption type. * - * @ buf: rx_tlv_hdr of the received packet - * @ Return: encryption type + * @hal_soc_hdl: hal soc handle + * @buf: rx_tlv_hdr of the received packet + * + * Return: encryption type */ static inline uint32_t -hal_rx_encryption_info_valid(uint8_t *buf) +hal_rx_encryption_info_valid(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - struct rx_mpdu_info *mpdu_info = &(mpdu_start->rx_mpdu_info_details); - uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_encryption_info_valid(buf); - return encryption_info; } /* - * @ hal_rx_print_pn: Prints the PN of rx packet. + * hal_rx_print_pn: Prints the PN of rx packet. + * @hal_soc_hdl: hal soc handle + * @buf: rx_tlv_hdr of the received packet * - * @ buf: rx_tlv_hdr of the received packet - * @ Return: void + * Return: void */ static inline void -hal_rx_print_pn(uint8_t *buf) +hal_rx_print_pn(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - struct rx_mpdu_info *mpdu_info = &(mpdu_start->rx_mpdu_info_details); - - uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); - uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); - uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); - uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", - pn_127_96, pn_95_64, pn_63_32, pn_31_0); + hal_soc->ops->hal_rx_print_pn(buf); } /* @@ -938,12 +1006,6 @@ hal_rx_mpdu_peer_meta_data_set(uint8_t *buf, uint32_t peer_mdata) HAL_RX_MPDU_PEER_META_DATA_SET(mpdu_info, peer_mdata); } -#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_L3_HEADER_PADDING_OFFSET)), \ - RX_MSDU_END_5_L3_HEADER_PADDING_MASK, \ - RX_MSDU_END_5_L3_HEADER_PADDING_LSB)) - /** * LRO information needed from the TLVs */ @@ -955,14 +1017,6 @@ hal_rx_mpdu_peer_meta_data_set(uint8_t *buf, uint32_t peer_mdata) RX_MSDU_END_9_LRO_ELIGIBLE_MASK, \ RX_MSDU_END_9_LRO_ELIGIBLE_LSB)) -#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ - (_HAL_MS( \ - (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ - msdu_end_tlv.rx_msdu_end), \ - RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \ - RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \ - RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB)) - #define HAL_RX_TLV_GET_TCP_ACK(buf) \ (_HAL_MS( \ (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ @@ -1003,6 +1057,14 @@ hal_rx_mpdu_peer_meta_data_set(uint8_t *buf, uint32_t peer_mdata) RX_MSDU_START_2_TCP_PROTO_MASK, \ RX_MSDU_START_2_TCP_PROTO_LSB)) +#define HAL_RX_TLV_GET_UDP_PROTO(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_start_tlv.rx_msdu_start), \ + RX_MSDU_START_2_UDP_PROTO_OFFSET)), \ + RX_MSDU_START_2_UDP_PROTO_MASK, \ + RX_MSDU_START_2_UDP_PROTO_LSB)) + #define HAL_RX_TLV_GET_IPV6(buf) \ (_HAL_MS( \ (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ @@ -1035,32 +1097,23 @@ hal_rx_mpdu_peer_meta_data_set(uint8_t *buf, uint32_t peer_mdata) RX_MSDU_START_4_FLOW_ID_TOEPLITZ_MASK, \ RX_MSDU_START_4_FLOW_ID_TOEPLITZ_LSB)) - /** +/** * hal_rx_msdu_end_l3_hdr_padding_get(): API to get the * l3_header padding from rx_msdu_end TLV * - * @ buf: pointer to the start of RX PKT TLV headers + * @buf: pointer to the start of RX PKT TLV headers * Return: number of l3 header padding bytes */ static inline uint32_t -hal_rx_msdu_end_l3_hdr_padding_get(uint8_t *buf) +hal_rx_msdu_end_l3_hdr_padding_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint32_t l3_header_padding; - - l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return l3_header_padding; + return hal_soc->ops->hal_rx_msdu_end_l3_hdr_padding_get(buf); } -#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_13_SA_IDX_OFFSET)), \ - RX_MSDU_END_13_SA_IDX_MASK, \ - RX_MSDU_END_13_SA_IDX_LSB)) - - /** +/** * hal_rx_msdu_end_sa_idx_get(): API to get the * sa_idx from rx_msdu_end TLV * @@ -1068,23 +1121,14 @@ hal_rx_msdu_end_l3_hdr_padding_get(uint8_t *buf) * Return: sa_idx (SA AST index) */ static inline uint16_t -hal_rx_msdu_end_sa_idx_get(uint8_t *buf) +hal_rx_msdu_end_sa_idx_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint16_t sa_idx; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); - - return sa_idx; + return hal_soc->ops->hal_rx_msdu_end_sa_idx_get(buf); } -#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \ - RX_MSDU_END_5_SA_IS_VALID_MASK, \ - RX_MSDU_END_5_SA_IS_VALID_LSB)) - /** * hal_rx_msdu_end_sa_is_valid_get(): API to get the * sa_is_valid bit from rx_msdu_end TLV @@ -1093,40 +1137,12 @@ hal_rx_msdu_end_sa_idx_get(uint8_t *buf) * Return: sa_is_valid bit */ static inline uint8_t -hal_rx_msdu_end_sa_is_valid_get(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint8_t sa_is_valid; - - sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); - - return sa_is_valid; -} - -#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_16_SA_SW_PEER_ID_OFFSET)), \ - RX_MSDU_END_16_SA_SW_PEER_ID_MASK, \ - RX_MSDU_END_16_SA_SW_PEER_ID_LSB)) - - /** - * hal_rx_msdu_end_sa_sw_peer_id_get(): API to get the - * sa_sw_peer_id from rx_msdu_end TLV - * - * @ buf: pointer to the start of RX PKT TLV headers - * Return: sa_sw_peer_id index - */ -static inline uint32_t -hal_rx_msdu_end_sa_sw_peer_id_get(uint8_t *buf) +hal_rx_msdu_end_sa_is_valid_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint32_t sa_sw_peer_id; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - sa_sw_peer_id = HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); - - return sa_sw_peer_id; + return hal_soc->ops->hal_rx_msdu_end_sa_is_valid_get(buf); } #define HAL_RX_MSDU_START_MSDU_LEN_GET(_rx_msdu_start) \ @@ -1227,51 +1243,108 @@ hal_rx_msdu_start_toeplitz_get(uint8_t *buf) return HAL_RX_MSDU_START_FLOWID_TOEPLITZ_GET(msdu_start); } -/* - * Get qos_control_valid from RX_MPDU_START - */ -#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) +/** + * enum hal_rx_mpdu_info_sw_frame_group_id_type: Enum for group id in MPDU_INFO + * + * @ HAL_MPDU_SW_FRAME_GROUP_NDP_FRAME: NDP frame + * @ HAL_MPDU_SW_FRAME_GROUP_MULTICAST_DATA: multicast data frame + * @ HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA: unicast data frame + * @ HAL_MPDU_SW_FRAME_GROUP_NULL_DATA: NULL data frame + * @ HAL_MPDU_SW_FRAME_GROUP_MGMT: management frame + * @ HAL_MPDU_SW_FRAME_GROUP_MGMT_PROBE_REQ: probe req frame + * @ HAL_MPDU_SW_FRAME_GROUP_CTRL: control frame + * @ HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR: BAR frame + * @ HAL_MPDU_SW_FRAME_GROUP_CTRL_RTS: RTS frame + * @ HAL_MPDU_SW_FRAME_GROUP_UNSUPPORTED: unsupported + * @ HAL_MPDU_SW_FRAME_GROUP_MAX: max limit + */ +enum hal_rx_mpdu_info_sw_frame_group_id_type { + HAL_MPDU_SW_FRAME_GROUP_NDP_FRAME = 0, + HAL_MPDU_SW_FRAME_GROUP_MULTICAST_DATA, + HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA, + HAL_MPDU_SW_FRAME_GROUP_NULL_DATA, + HAL_MPDU_SW_FRAME_GROUP_MGMT, + HAL_MPDU_SW_FRAME_GROUP_MGMT_PROBE_REQ = 8, + HAL_MPDU_SW_FRAME_GROUP_MGMT_BEACON = 12, + HAL_MPDU_SW_FRAME_GROUP_CTRL = 20, + HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR = 28, + HAL_MPDU_SW_FRAME_GROUP_CTRL_RTS = 31, + HAL_MPDU_SW_FRAME_GROUP_UNSUPPORTED = 36, + HAL_MPDU_SW_FRAME_GROUP_MAX = 37, +}; +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get(): + * Retrieve qos control valid bit from the tlv. + * @hal_soc_hdl: hal_soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ static inline uint32_t -hal_rx_mpdu_start_mpdu_qos_control_valid_get(uint8_t *buf) +hal_rx_mpdu_start_mpdu_qos_control_valid_get( + hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - uint32_t qos_control_valid; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - qos_control_valid = HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( - &(mpdu_start->rx_mpdu_info_details)); + if ((!hal_soc) || (!hal_soc->ops)) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return QDF_STATUS_E_INVAL; + } - return qos_control_valid; -} + if (hal_soc->ops->hal_rx_mpdu_start_mpdu_qos_control_valid_get) + return hal_soc->ops-> + hal_rx_mpdu_start_mpdu_qos_control_valid_get(buf); + return QDF_STATUS_E_INVAL; +} -/* - * Get SW peer id from RX_MPDU_START +/** + * hal_rx_is_unicast: check packet is unicast frame or not. + * @hal_soc_hdl: hal_soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: true on unicast. */ -#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ - RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \ - RX_MPDU_INFO_1_SW_PEER_ID_MASK, \ - RX_MPDU_INFO_1_SW_PEER_ID_LSB)) +static inline bool +hal_rx_is_unicast(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + return hal_soc->ops->hal_rx_is_unicast(buf); +} + +/** + * hal_rx_tid_get: get tid based on qos control valid. + * @hal_soc_hdl: hal soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: tid + */ static inline uint32_t -hal_rx_mpdu_start_sw_peer_id_get(uint8_t *buf) +hal_rx_tid_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - uint32_t sw_peer_id; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_tid_get(hal_soc_hdl, buf); +} - sw_peer_id = HAL_RX_MPDU_INFO_SW_PEER_ID_GET( - &(mpdu_start->rx_mpdu_info_details)); +/** + * hal_rx_mpdu_start_sw_peer_id_get() - Retrieve sw peer id + * @hal_soc_hdl: hal soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: sw peer_id + */ +static inline uint32_t +hal_rx_mpdu_start_sw_peer_id_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return sw_peer_id; + return hal_soc->ops->hal_rx_mpdu_start_sw_peer_id_get(buf); } #define HAL_RX_MSDU_START_SGI_GET(_rx_msdu_start) \ @@ -1462,12 +1535,6 @@ hal_rx_msdu_start_get_pkt_type(uint8_t *buf) return pkt_type; } -#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_TO_DS_OFFSET)), \ - RX_MPDU_INFO_2_TO_DS_MASK, \ - RX_MPDU_INFO_2_TO_DS_LSB)) - /* * hal_rx_mpdu_get_tods(): API to get the tods info * from rx_mpdu_start @@ -1477,109 +1544,30 @@ hal_rx_msdu_start_get_pkt_type(uint8_t *buf) */ static inline uint32_t -hal_rx_mpdu_get_to_ds(uint8_t *buf) +hal_rx_mpdu_get_to_ds(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - uint32_t to_ds; - - to_ds = HAL_RX_MPDU_GET_TODS(mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return to_ds; + return hal_soc->ops->hal_rx_mpdu_get_to_ds(buf); } -#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_FR_DS_OFFSET)), \ - RX_MPDU_INFO_2_FR_DS_MASK, \ - RX_MPDU_INFO_2_FR_DS_LSB)) /* * hal_rx_mpdu_get_fr_ds(): API to get the from ds info * from rx_mpdu_start - * + * @hal_soc_hdl: hal soc handle * @buf: pointer to the start of RX PKT TLV header + * * Return: uint32_t(fr_ds) */ - static inline uint32_t -hal_rx_mpdu_get_fr_ds(uint8_t *buf) +hal_rx_mpdu_get_fr_ds(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - uint32_t fr_ds; - - fr_ds = HAL_RX_MPDU_GET_FROMDS(mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return fr_ds; + return hal_soc->ops->hal_rx_mpdu_get_fr_ds(buf); } -#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \ - RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB)) - -#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \ - RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB)) - -#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \ - RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB)) - -#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) - -#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ - RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ - RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) - -#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ - RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ - RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) - -#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ - RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ - RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) - -#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ - RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ - RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) - -#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ - RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ - RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) - -#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ - RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ - RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) - #define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ @@ -1594,141 +1582,72 @@ hal_rx_mpdu_get_fr_ds(uint8_t *buf) /* * hal_rx_mpdu_get_addr1(): API to check get address1 of the mpdu - * + * @hal_soc_hdl: hal soc handle * @buf: pointer to the start of RX PKT TLV headera * @mac_addr: pointer to mac address + * * Return: success/failure */ static inline -QDF_STATUS hal_rx_mpdu_get_addr1(uint8_t *buf, uint8_t *mac_addr) +QDF_STATUS hal_rx_mpdu_get_addr1(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, uint8_t *mac_addr) { - struct __attribute__((__packed__)) hal_addr1 { - uint32_t ad1_31_0; - uint16_t ad1_47_32; - }; - - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; - uint32_t mac_addr_ad1_valid; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); - - if (mac_addr_ad1_valid) { - addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); - addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); - return QDF_STATUS_SUCCESS; - } - - return QDF_STATUS_E_FAILURE; + return hal_soc->ops->hal_rx_mpdu_get_addr1(buf, mac_addr); } /* * hal_rx_mpdu_get_addr2(): API to check get address2 of the mpdu * in the packet - * + * @hal_soc_hdl: hal soc handle * @buf: pointer to the start of RX PKT TLV header * @mac_addr: pointer to mac address + * * Return: success/failure */ static inline -QDF_STATUS hal_rx_mpdu_get_addr2(uint8_t *buf, uint8_t *mac_addr) +QDF_STATUS hal_rx_mpdu_get_addr2(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, uint8_t *mac_addr) { - struct __attribute__((__packed__)) hal_addr2 { - uint16_t ad2_15_0; - uint32_t ad2_47_16; - }; - - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; - uint32_t mac_addr_ad2_valid; - - mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - if (mac_addr_ad2_valid) { - addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); - addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); - return QDF_STATUS_SUCCESS; - } - - return QDF_STATUS_E_FAILURE; + return hal_soc->ops->hal_rx_mpdu_get_addr2(buf, mac_addr); } /* * hal_rx_mpdu_get_addr3(): API to get address3 of the mpdu * in the packet - * + * @hal_soc_hdl: hal soc handle * @buf: pointer to the start of RX PKT TLV header * @mac_addr: pointer to mac address + * * Return: success/failure */ static inline -QDF_STATUS hal_rx_mpdu_get_addr3(uint8_t *buf, uint8_t *mac_addr) +QDF_STATUS hal_rx_mpdu_get_addr3(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, uint8_t *mac_addr) { - struct __attribute__((__packed__)) hal_addr3 { - uint32_t ad3_31_0; - uint16_t ad3_47_32; - }; - - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; - uint32_t mac_addr_ad3_valid; - - mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); - - if (mac_addr_ad3_valid) { - addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); - addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); - return QDF_STATUS_SUCCESS; - } - - return QDF_STATUS_E_FAILURE; + return hal_soc->ops->hal_rx_mpdu_get_addr3(buf, mac_addr); } /* * hal_rx_mpdu_get_addr4(): API to get address4 of the mpdu * in the packet - * + * @hal_soc_hdl: hal_soc handle * @buf: pointer to the start of RX PKT TLV header * @mac_addr: pointer to mac address * Return: success/failure */ static inline -QDF_STATUS hal_rx_mpdu_get_addr4(uint8_t *buf, uint8_t *mac_addr) +QDF_STATUS hal_rx_mpdu_get_addr4(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, uint8_t *mac_addr) { - struct __attribute__((__packed__)) hal_addr4 { - uint32_t ad4_31_0; - uint16_t ad4_47_32; - }; - - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - - struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; - struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; - uint32_t mac_addr_ad4_valid; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); - - if (mac_addr_ad4_valid) { - addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); - addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); - return QDF_STATUS_SUCCESS; - } - - return QDF_STATUS_E_FAILURE; + return hal_soc->ops->hal_rx_mpdu_get_addr4(buf, mac_addr); } /** @@ -1739,133 +1658,93 @@ QDF_STATUS hal_rx_mpdu_get_addr4(uint8_t *buf, uint8_t *mac_addr) * Return: da index */ static inline uint16_t -hal_rx_msdu_end_da_idx_get(struct hal_soc *hal_soc, uint8_t *buf) +hal_rx_msdu_end_da_idx_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + return hal_soc->ops->hal_rx_msdu_end_da_idx_get(buf); } -#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \ - RX_MSDU_END_5_DA_IS_VALID_MASK, \ - RX_MSDU_END_5_DA_IS_VALID_LSB)) - - /** +/** * hal_rx_msdu_end_da_is_valid_get: API to check if da is valid * from rx_msdu_end TLV - * + * @hal_soc_hdl: hal soc handle * @ buf: pointer to the start of RX PKT TLV headers + * * Return: da_is_valid */ static inline uint8_t -hal_rx_msdu_end_da_is_valid_get(uint8_t *buf) +hal_rx_msdu_end_da_is_valid_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint8_t da_is_valid; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); - - return da_is_valid; + return hal_soc->ops->hal_rx_msdu_end_da_is_valid_get(buf); } -#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \ - RX_MSDU_END_5_DA_IS_MCBC_MASK, \ - RX_MSDU_END_5_DA_IS_MCBC_LSB)) - - /** +/** * hal_rx_msdu_end_da_is_mcbc_get: API to check if pkt is MCBC * from rx_msdu_end TLV * - * @ buf: pointer to the start of RX PKT TLV headers + * @buf: pointer to the start of RX PKT TLV headers + * * Return: da_is_mcbc */ static inline uint8_t -hal_rx_msdu_end_da_is_mcbc_get(uint8_t *buf) +hal_rx_msdu_end_da_is_mcbc_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint8_t da_is_mcbc; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - da_is_mcbc = HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); - - return da_is_mcbc; + return hal_soc->ops->hal_rx_msdu_end_da_is_mcbc_get(buf); } -#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_FIRST_MSDU_OFFSET)), \ - RX_MSDU_END_5_FIRST_MSDU_MASK, \ - RX_MSDU_END_5_FIRST_MSDU_LSB)) - - /** +/** * hal_rx_msdu_end_first_msdu_get: API to get first msdu status * from rx_msdu_end TLV + * @hal_soc_hdl: hal soc handle + * @buf: pointer to the start of RX PKT TLV headers * - * @ buf: pointer to the start of RX PKT TLV headers * Return: first_msdu */ static inline uint8_t -hal_rx_msdu_end_first_msdu_get(uint8_t *buf) +hal_rx_msdu_end_first_msdu_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint8_t first_msdu; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); - - return first_msdu; + return hal_soc->ops->hal_rx_msdu_end_first_msdu_get(buf); } -#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_5_LAST_MSDU_OFFSET)), \ - RX_MSDU_END_5_LAST_MSDU_MASK, \ - RX_MSDU_END_5_LAST_MSDU_LSB)) - - /** +/** * hal_rx_msdu_end_last_msdu_get: API to get last msdu status * from rx_msdu_end TLV + * @hal_soc_hdl: hal soc handle + * @buf: pointer to the start of RX PKT TLV headers * - * @ buf: pointer to the start of RX PKT TLV headers * Return: last_msdu */ static inline uint8_t -hal_rx_msdu_end_last_msdu_get(uint8_t *buf) +hal_rx_msdu_end_last_msdu_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint8_t last_msdu; - - last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return last_msdu; + return hal_soc->ops->hal_rx_msdu_end_last_msdu_get(buf); } -#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ - RX_MSDU_END_16_CCE_METADATA_MASK, \ - RX_MSDU_END_16_CCE_METADATA_LSB)) - /** * hal_rx_msdu_cce_metadata_get: API to get CCE metadata * from rx_msdu_end TLV - * @ buf: pointer to the start of RX PKT TLV headers - * Return: last_msdu + * @buf: pointer to the start of RX PKT TLV headers + * Return: cce_meta_data */ - -static inline uint32_t -hal_rx_msdu_cce_metadata_get(uint8_t *buf) +static inline uint16_t +hal_rx_msdu_cce_metadata_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint32_t cce_metadata; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - cce_metadata = HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); - return cce_metadata; + return hal_soc->ops->hal_rx_msdu_cce_metadata_get(buf); } /******************************************************************************* @@ -1943,6 +1822,7 @@ struct hal_rx_msdu_list { struct hal_buf_info { uint64_t paddr; uint32_t sw_cookie; + uint8_t rbm; }; /** @@ -1952,10 +1832,10 @@ struct hal_buf_info { * Return - Pointer to rx_msdu_details structure * */ -static inline void *hal_rx_link_desc_msdu0_ptr(void *msdu_link_ptr, void *hal) +static inline +void *hal_rx_link_desc_msdu0_ptr(void *msdu_link_ptr, + struct hal_soc *hal_soc) { - struct hal_soc *hal_soc = (struct hal_soc *)hal; - return hal_soc->ops->hal_rx_link_desc_msdu0_ptr(msdu_link_ptr); } @@ -1966,10 +1846,10 @@ static inline void *hal_rx_link_desc_msdu0_ptr(void *msdu_link_ptr, void *hal) * Return - Pointer to rx_msdu_desc_info structure. * */ -static inline void *hal_rx_msdu_desc_info_get_ptr(void *msdu_details_ptr, void *hal) +static inline +void *hal_rx_msdu_desc_info_get_ptr(void *msdu_details_ptr, + struct hal_soc *hal_soc) { - struct hal_soc *hal_soc = (struct hal_soc *)hal; - return hal_soc->ops->hal_rx_msdu_desc_info_get_ptr(msdu_details_ptr); } @@ -1991,11 +1871,12 @@ static inline void *hal_rx_msdu_desc_info_get_ptr(void *msdu_details_ptr, void * * * Return: void */ -static inline void hal_rx_msdu_list_get(struct hal_soc *hal_soc, +static inline void hal_rx_msdu_list_get(hal_soc_handle_t hal_soc_hdl, void *msdu_link_desc, struct hal_rx_msdu_list *msdu_list, uint16_t *num_msdus) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; struct rx_msdu_details *msdu_details; struct rx_msdu_desc_info *msdu_desc_info; struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc; @@ -2011,6 +1892,9 @@ static inline void hal_rx_msdu_list_get(struct hal_soc *hal_soc, /* num_msdus received in mpdu descriptor may be incorrect * sometimes due to HW issue. Check msdu buffer address also */ + if (!i && (HAL_RX_BUFFER_ADDR_31_0_GET( + &msdu_details[i].buffer_addr_info_details) == 0)) + break; if (HAL_RX_BUFFER_ADDR_31_0_GET( &msdu_details[i].buffer_addr_info_details) == 0) { /* set the last msdu bit in the prev msdu_desc_info */ @@ -2058,8 +1942,9 @@ static inline void hal_rx_msdu_list_get(struct hal_soc *hal_soc, * Return: dst_ind (REO destination ring ID) */ static inline uint32_t -hal_rx_msdu_reo_dst_ind_get(struct hal_soc *hal_soc, void *msdu_link_desc) +hal_rx_msdu_reo_dst_ind_get(hal_soc_handle_t hal_soc_hdl, void *msdu_link_desc) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; struct rx_msdu_details *msdu_details; struct rx_msdu_desc_info *msdu_desc_info; struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc; @@ -2083,8 +1968,9 @@ hal_rx_msdu_reo_dst_ind_get(struct hal_soc *hal_soc, void *msdu_link_desc) * @ buf_info: structure to return the buffer information * Return: void */ -static inline void hal_rx_reo_buf_paddr_get(void *rx_desc, - struct hal_buf_info *buf_info) +static inline +void hal_rx_reo_buf_paddr_get(hal_ring_desc_t rx_desc, + struct hal_buf_info *buf_info) { struct reo_destination_ring *reo_ring = (struct reo_destination_ring *)rx_desc; @@ -2265,7 +2151,7 @@ enum hal_rx_wbm_buf_type { * * Return: true: error caused by PN check, false: other error */ -static inline bool hal_rx_reo_is_pn_error(void *rx_desc) +static inline bool hal_rx_reo_is_pn_error(hal_ring_desc_t rx_desc) { struct reo_destination_ring *reo_desc = (struct reo_destination_ring *)rx_desc; @@ -2285,7 +2171,7 @@ static inline bool hal_rx_reo_is_pn_error(void *rx_desc) * * Return: true: error caused by 2K jump, false: other error */ -static inline bool hal_rx_reo_is_2k_jump(void *rx_desc) +static inline bool hal_rx_reo_is_2k_jump(hal_ring_desc_t rx_desc) { struct reo_destination_ring *reo_desc = (struct reo_destination_ring *)rx_desc; @@ -2339,7 +2225,7 @@ static inline void hal_dump_wbm_rel_desc(void *src_srng_desc) /** * hal_rx_msdu_link_desc_set: Retrieves MSDU Link Descriptor to WBM * - * @ soc : HAL version of the SOC pointer + * @ hal_soc_hdl : HAL version of the SOC pointer * @ src_srng_desc : void pointer to the WBM Release Ring descriptor * @ buf_addr_info : void pointer to the buffer_addr_info * @ bm_action : put in IDLE list or release to MSDU_LIST @@ -2347,9 +2233,11 @@ static inline void hal_dump_wbm_rel_desc(void *src_srng_desc) * Return: void */ /* look at implementation at dp_hw_link_desc_pool_setup()*/ -static inline void hal_rx_msdu_link_desc_set(struct hal_soc *soc, - void *src_srng_desc, void *buf_addr_info, - uint8_t bm_action) +static inline +void hal_rx_msdu_link_desc_set(hal_soc_handle_t hal_soc_hdl, + void *src_srng_desc, + hal_buff_addrinfo_t buf_addr_info, + uint8_t bm_action) { struct wbm_release_ring *wbm_rel_srng = (struct wbm_release_ring *)src_srng_desc; @@ -2409,7 +2297,8 @@ static inline void hal_rx_msdu_link_desc_reinject(struct hal_soc *soc, * (Assumption -- BUFFER_ADDR_INFO is the * first field in the descriptor structure) */ -#define HAL_RX_BUF_ADDR_INFO_GET(ring_desc) ((void *)(ring_desc)) +#define HAL_RX_BUF_ADDR_INFO_GET(ring_desc) \ + ((hal_link_desc_t)(ring_desc)) #define HAL_RX_REO_BUF_ADDR_INFO_GET HAL_RX_BUF_ADDR_INFO_GET @@ -2424,7 +2313,7 @@ static inline void hal_rx_msdu_link_desc_reinject(struct hal_soc *soc, * Return: uint8_t (value of the return_buffer_manager) */ static inline -uint8_t hal_rx_ret_buf_manager_get(void *ring_desc) +uint8_t hal_rx_ret_buf_manager_get(hal_ring_desc_t ring_desc) { /* * The following macro takes buf_addr_info as argument, @@ -2716,9 +2605,9 @@ static inline void hal_rx_dump_pkt_hdr_tlv(struct rx_pkt_tlvs *pkt_tlvs, * * Return: ring_id */ -static inline uint8_t hal_srng_ring_id_get(void *hal_ring) +static inline uint8_t hal_srng_ring_id_get(hal_ring_handle_t hal_ring_hdl) { - return ((struct hal_srng *)hal_ring)->ring_id; + return ((struct hal_srng *)hal_ring_hdl)->ring_id; } /* Rx MSDU link pointer info */ @@ -2751,32 +2640,9 @@ struct rx_mpdu_info *hal_rx_get_mpdu_info(struct rx_pkt_tlvs *pkt_tlvs) return &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; } -/** - * hal_rx_get_rx_sequence(): Function to retrieve rx sequence number - * - * @nbuf: Network buffer - * Returns: rx sequence number - */ #define DOT11_SEQ_FRAG_MASK 0x000f #define DOT11_FC1_MORE_FRAG_OFFSET 0x04 -#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB)) -static inline -uint16_t hal_rx_get_rx_sequence(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); - struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); - uint16_t seq_number = 0; - - seq_number = HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); - - return seq_number; -} - /** * hal_rx_get_rx_fragment_number(): Function to retrieve rx fragment number * @@ -2784,17 +2650,10 @@ uint16_t hal_rx_get_rx_sequence(uint8_t *buf) * Returns: rx fragment number */ static inline -uint8_t hal_rx_get_rx_fragment_number(uint8_t *buf) +uint8_t hal_rx_get_rx_fragment_number(struct hal_soc *hal_soc, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); - struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); - uint8_t frag_number = 0; - - frag_number = HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & - DOT11_SEQ_FRAG_MASK; - - /* Return first 4 bits as fragment number */ - return frag_number; + return hal_soc->ops->hal_rx_get_rx_fragment_number(buf); } #define HAL_RX_MPDU_GET_FRAME_CONTROL_FIELD(_rx_mpdu_info) \ @@ -2858,75 +2717,51 @@ uint32_t hal_rx_msdu_is_wlan_mcast(qdf_nbuf_t nbuf) return rx_attn->mcast_bcast; } -#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ - RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) /* * hal_rx_get_mpdu_sequence_control_valid(): Get mpdu sequence control valid - * + * @hal_soc_hdl: hal soc handle * @nbuf: Network buffer - * Returns: value of sequence control valid field + * + * Return: value of sequence control valid field */ static inline -uint8_t hal_rx_get_mpdu_sequence_control_valid(uint8_t *buf) +uint8_t hal_rx_get_mpdu_sequence_control_valid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); - struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); - uint8_t seq_ctrl_valid = 0; - - seq_ctrl_valid = - HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return seq_ctrl_valid; + return hal_soc->ops->hal_rx_get_mpdu_sequence_control_valid(buf); } -#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \ - RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB)) /* * hal_rx_get_mpdu_frame_control_valid(): Retrieves mpdu frame control valid - * + * @hal_soc_hdl: hal soc handle * @nbuf: Network buffer + * * Returns: value of frame control valid field */ static inline -uint8_t hal_rx_get_mpdu_frame_control_valid(uint8_t *buf) +uint8_t hal_rx_get_mpdu_frame_control_valid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); - struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); - uint8_t frm_ctrl_valid = 0; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - frm_ctrl_valid = - HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); - - return frm_ctrl_valid; + return hal_soc->ops->hal_rx_get_mpdu_frame_control_valid(buf); } -#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ - RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) -/* +/** * hal_rx_get_mpdu_mac_ad4_valid(): Retrieves if mpdu 4th addr is valid - * + * @hal_soc_hdl: hal soc handle * @nbuf: Network buffer * Returns: value of mpdu 4th address valid field */ static inline -bool hal_rx_get_mpdu_mac_ad4_valid(uint8_t *buf) +bool hal_rx_get_mpdu_mac_ad4_valid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) { - struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); - struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); - bool ad4_valid = 0; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); - - return ad4_valid; + return hal_soc->ops->hal_rx_get_mpdu_mac_ad4_valid(buf); } /* @@ -3019,7 +2854,7 @@ int hal_rx_chain_msdu_links(struct hal_soc *hal_soc, qdf_nbuf_t msdu, if (num_msdus < HAL_RX_NUM_MSDU_DESC) { /* mark first and last MSDUs */ rx_desc_info = qdf_nbuf_data(msdu); - fragno = hal_rx_get_rx_fragment_number(rx_desc_info); + fragno = hal_rx_get_rx_fragment_number(hal_soc, rx_desc_info); more_frag = hal_rx_get_rx_more_frag_bit(rx_desc_info); /* TODO: create skb->fragslist[] */ @@ -3061,9 +2896,10 @@ int hal_rx_chain_msdu_links(struct hal_soc *hal_soc, qdf_nbuf_t msdu, * Returns: None */ static inline -void hal_rx_defrag_update_src_ring_desc(void *ring_desc, - void *saved_mpdu_desc_info, - struct hal_rx_msdu_link_ptr_info *saved_msdu_link_ptr) +void hal_rx_defrag_update_src_ring_desc( + hal_ring_desc_t ring_desc, + void *saved_mpdu_desc_info, + struct hal_rx_msdu_link_ptr_info *saved_msdu_link_ptr) { struct reo_entrance_ring *reo_ent_ring; struct rx_mpdu_desc_info *reo_ring_mpdu_desc_info; @@ -3125,7 +2961,7 @@ void hal_rx_defrag_save_info_from_ring_desc(void *msdu_link_desc_va, static inline uint16_t hal_rx_get_desc_len(void) { - return sizeof(struct rx_pkt_tlvs); + return SIZE_OF_DATA_RX_TLV; } /* @@ -3136,7 +2972,7 @@ uint16_t hal_rx_get_desc_len(void) * Returns: value of rxdma_push_reason */ static inline -uint8_t hal_rx_reo_ent_rxdma_push_reason_get(void *reo_ent_desc) +uint8_t hal_rx_reo_ent_rxdma_push_reason_get(hal_rxdma_desc_t reo_ent_desc) { return _HAL_MS((*_OFFSET_TO_WORD_PTR(reo_ent_desc, REO_ENTRANCE_RING_6_RXDMA_PUSH_REASON_OFFSET)), @@ -3151,7 +2987,7 @@ uint8_t hal_rx_reo_ent_rxdma_push_reason_get(void *reo_ent_desc) * Return: value of rxdma_error_code */ static inline -uint8_t hal_rx_reo_ent_rxdma_error_code_get(void *reo_ent_desc) +uint8_t hal_rx_reo_ent_rxdma_error_code_get(hal_rxdma_desc_t reo_ent_desc) { return _HAL_MS((*_OFFSET_TO_WORD_PTR(reo_ent_desc, REO_ENTRANCE_RING_6_RXDMA_ERROR_CODE_OFFSET)), @@ -3168,8 +3004,10 @@ uint8_t hal_rx_reo_ent_rxdma_error_code_get(void *reo_ent_desc) */ static inline void hal_rx_wbm_err_info_get(void *wbm_desc, struct hal_wbm_err_desc_info *wbm_er_info, - struct hal_soc *hal_soc) + hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_rx_wbm_err_info_get(wbm_desc, (void *)wbm_er_info); } @@ -3220,10 +3058,13 @@ static inline void hal_rx_wbm_err_info_get_from_tlv(uint8_t *buf, * * Return: void */ -static inline void hal_rx_mon_hw_desc_get_mpdu_status(struct hal_soc *hal_soc, - void *hw_desc_addr, - struct mon_rx_status *rs) +static inline +void hal_rx_mon_hw_desc_get_mpdu_status(hal_soc_handle_t hal_soc_hdl, + void *hw_desc_addr, + struct mon_rx_status *rs) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_rx_mon_hw_desc_get_mpdu_status(hw_desc_addr, rs); } @@ -3247,9 +3088,11 @@ static inline uint8_t hal_rx_get_tlv(struct hal_soc *hal_soc, void *rx_tlv) * @buf: pointer to the start of RX PKT TLV header * Return: uint32_t(nss) */ -static inline uint32_t hal_rx_msdu_start_nss_get(struct hal_soc *hal_soc, - uint8_t *buf) +static inline +uint32_t hal_rx_msdu_start_nss_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + return hal_soc->ops->hal_rx_msdu_start_nss_get(buf); } @@ -3276,9 +3119,11 @@ static inline void hal_rx_dump_msdu_start_tlv(struct hal_soc *hal_soc, * * */ -static inline uint32_t hal_rx_mpdu_start_tid_get(struct hal_soc *hal_soc, +static inline uint32_t hal_rx_mpdu_start_tid_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + return hal_soc->ops->hal_rx_mpdu_start_tid_get(buf); } @@ -3290,9 +3135,11 @@ static inline uint32_t hal_rx_mpdu_start_tid_get(struct hal_soc *hal_soc, * Return: uint32_t(reception_type) */ static inline -uint32_t hal_rx_msdu_start_reception_type_get(struct hal_soc *hal_soc, +uint32_t hal_rx_msdu_start_reception_type_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + return hal_soc->ops->hal_rx_msdu_start_reception_type_get(buf); } @@ -3304,7 +3151,7 @@ uint32_t hal_rx_msdu_start_reception_type_get(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_rx_dump_pkt_tlvs(struct hal_soc *hal_soc, +static inline void hal_rx_dump_pkt_tlvs(hal_soc_handle_t hal_soc_hdl, uint8_t *buf, uint8_t dbg_level) { struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; @@ -3315,6 +3162,7 @@ static inline void hal_rx_dump_pkt_tlvs(struct hal_soc *hal_soc, &pkt_tlvs->msdu_start_tlv.rx_msdu_start; struct rx_mpdu_end *mpdu_end = &pkt_tlvs->mpdu_end_tlv.rx_mpdu_end; struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; hal_rx_dump_rx_attention_tlv(rx_attn, dbg_level); hal_rx_dump_mpdu_start_tlv(mpdu_start, dbg_level, hal_soc); @@ -3334,21 +3182,28 @@ static inline void hal_rx_dump_pkt_tlvs(struct hal_soc *hal_soc, * Return - none. * */ -static inline void hal_reo_status_get_header(uint32_t *d, int b, - void *h, void *hal) +static inline +void hal_reo_status_get_header(uint32_t *d, int b, + void *h, struct hal_soc *hal_soc) { - struct hal_soc *hal_soc = (struct hal_soc *)hal; - hal_soc->ops->hal_reo_status_get_header(d, b, h); } +/** + * hal_rx_desc_is_first_msdu() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ static inline -uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) +uint32_t hal_rx_desc_is_first_msdu(hal_soc_handle_t hal_soc_hdl, + void *hw_desc_addr) { - struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; - struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); + return hal_soc->ops->hal_rx_desc_is_first_msdu(hw_desc_addr); } static inline @@ -3366,10 +3221,13 @@ HAL_RX_DESC_GET_DECAP_FORMAT(void *hw_desc_addr) { static inline uint8_t * HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "[%s][%d] decap format not raw", __func__, __LINE__); - QDF_ASSERT(0); - return 0; + uint8_t *rx_pkt_hdr; + struct rx_mon_pkt_tlvs *rx_desc = + (struct rx_mon_pkt_tlvs *)hw_desc_addr; + + rx_pkt_hdr = &rx_desc->pkt_hdr_tlv.rx_pkt_hdr[0]; + + return rx_pkt_hdr; } #else static inline @@ -3384,13 +3242,13 @@ HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) { } #endif -#ifdef NO_RX_PKT_HDR_TLV static inline -bool HAL_IS_DECAP_FORMAT_RAW(uint8_t *rx_tlv_hdr) +bool HAL_IS_DECAP_FORMAT_RAW(hal_soc_handle_t hal_soc_hdl, + uint8_t *rx_tlv_hdr) { uint8_t decap_format; - if (hal_rx_desc_is_first_msdu(rx_tlv_hdr)) { + if (hal_rx_desc_is_first_msdu(hal_soc_hdl, rx_tlv_hdr)) { decap_format = HAL_RX_DESC_GET_DECAP_FORMAT(rx_tlv_hdr); if (decap_format == HAL_HW_RX_DECAP_FORMAT_RAW) return true; @@ -3398,13 +3256,473 @@ bool HAL_IS_DECAP_FORMAT_RAW(uint8_t *rx_tlv_hdr) return false; } -#else + +/** + * hal_rx_msdu_fse_metadata_get: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static inline uint32_t +hal_rx_msdu_fse_metadata_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_fse_metadata_get(buf); +} + +/** + * hal_rx_msdu_flow_idx_get: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t +hal_rx_msdu_flow_idx_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_flow_idx_get(buf); +} + +/** + * hal_rx_msdu_get_reo_destination_indication: API to get reo + * destination index from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @reo_destination_indication: pointer to return value of + * reo_destination_indication + * + * Return: reo_destination_indication value from MSDU END TLV + */ +static inline void +hal_rx_msdu_get_reo_destination_indication(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, + uint32_t *reo_destination_indication) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if ((!hal_soc) || (!hal_soc->ops)) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return; + } + + hal_soc->ops->hal_rx_msdu_get_reo_destination_indication(buf, + reo_destination_indication); +} + +/** + * hal_rx_msdu_flow_idx_timeout: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static inline bool +hal_rx_msdu_flow_idx_timeout(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_flow_idx_timeout(buf); +} + +/** + * hal_rx_msdu_flow_idx_invalid: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static inline bool +hal_rx_msdu_flow_idx_invalid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_flow_idx_invalid(buf); +} + +/** + * hal_rx_hw_desc_get_ppduid_get() - Retrieve ppdu id + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ static inline -bool HAL_IS_DECAP_FORMAT_RAW(uint8_t *rx_tlv_hdr) +uint32_t hal_rx_hw_desc_get_ppduid_get(hal_soc_handle_t hal_soc_hdl, + void *hw_desc_addr) { - return true; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_hw_desc_get_ppduid_get(hw_desc_addr); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get() - get sw peer id + * @hal_soc_hdl: hal_soc handle + * @buf: rx tlv address + * + * Return: sw peer id + */ +static inline +uint32_t hal_rx_msdu_end_sa_sw_peer_id_get(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if ((!hal_soc) || (!hal_soc->ops)) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return QDF_STATUS_E_INVAL; + } + + if (hal_soc->ops->hal_rx_msdu_end_sa_sw_peer_id_get) + return hal_soc->ops->hal_rx_msdu_end_sa_sw_peer_id_get(buf); + + return QDF_STATUS_E_INVAL; +} + +static inline +void *hal_rx_msdu0_buffer_addr_lsb(hal_soc_handle_t hal_soc_hdl, + void *link_desc_addr) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu0_buffer_addr_lsb(link_desc_addr); +} + +static inline +void *hal_rx_msdu_desc_info_ptr_get(hal_soc_handle_t hal_soc_hdl, + void *msdu_addr) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_desc_info_ptr_get(msdu_addr); +} + +static inline +void *hal_ent_mpdu_desc_info(hal_soc_handle_t hal_soc_hdl, + void *hw_addr) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_ent_mpdu_desc_info(hw_addr); +} + +static inline +void *hal_dst_mpdu_desc_info(hal_soc_handle_t hal_soc_hdl, + void *hw_addr) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_dst_mpdu_desc_info(hw_addr); +} + +static inline +uint8_t hal_rx_get_fc_valid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_fc_valid(buf); +} + +static inline +uint8_t hal_rx_get_to_ds_flag(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_to_ds_flag(buf); +} + +static inline +uint8_t hal_rx_get_mac_addr2_valid(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_mac_addr2_valid(buf); +} + +static inline +uint8_t hal_rx_get_filter_category(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_filter_category(buf); +} + +static inline +uint32_t hal_rx_get_ppdu_id(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_ppdu_id(buf); +} + +/** + * hal_reo_config(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static inline +void hal_reo_config(struct hal_soc *hal_soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + hal_soc->ops->hal_reo_config(hal_soc, + reg_val, + reo_params); +} + +/** + * hal_rx_msdu_get_flow_params: API to get flow index, + * flow index invalid and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if ((!hal_soc) || (!hal_soc->ops)) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return; + } + + if (hal_soc->ops->hal_rx_msdu_get_flow_params) + hal_soc->ops-> + hal_rx_msdu_get_flow_params(buf, + flow_invalid, + flow_timeout, + flow_index); +} + +static inline +uint16_t hal_rx_tlv_get_tcp_chksum(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_tlv_get_tcp_chksum(buf); +} + +static inline +uint16_t hal_rx_get_rx_sequence(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_get_rx_sequence(buf); +} + +static inline void +hal_rx_get_bb_info(hal_soc_handle_t hal_soc_hdl, + void *rx_tlv, + void *ppdu_info) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (hal_soc->ops->hal_rx_get_bb_info) + hal_soc->ops->hal_rx_get_bb_info(rx_tlv, ppdu_info); +} + +static inline void +hal_rx_get_rtt_info(hal_soc_handle_t hal_soc_hdl, + void *rx_tlv, + void *ppdu_info) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (hal_soc->ops->hal_rx_get_rtt_info) + hal_soc->ops->hal_rx_get_rtt_info(rx_tlv, ppdu_info); +} + +/** + * hal_rx_msdu_metadata_get(): API to get the + * fast path information from rx_msdu_end TLV + * + * @ hal_soc_hdl: DP soc handle + * @ buf: pointer to the start of RX PKT TLV headers + * @ msdu_metadata: Structure to hold msdu end information + * Return: none + */ +static inline void +hal_rx_msdu_metadata_get(hal_soc_handle_t hal_soc_hdl, uint8_t *buf, + struct hal_rx_msdu_metadata *msdu_md) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_rx_msdu_packet_metadata_get(buf, msdu_md); +} + +/** + * hal_rx_get_fisa_cumulative_l4_checksum: API to get cumulative_l4_checksum + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cumulative_l4_checksum + */ +static inline uint16_t +hal_rx_get_fisa_cumulative_l4_checksum(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (!hal_soc->ops->hal_rx_get_fisa_cumulative_l4_checksum) + return 0; + + return hal_soc->ops->hal_rx_get_fisa_cumulative_l4_checksum(buf); +} + +/** + * hal_rx_get_fisa_cumulative_ip_length: API to get cumulative_ip_length + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cumulative_ip_length + */ +static inline uint16_t +hal_rx_get_fisa_cumulative_ip_length(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (hal_soc->ops->hal_rx_get_fisa_cumulative_ip_length) + return hal_soc->ops->hal_rx_get_fisa_cumulative_ip_length(buf); + + return 0; +} + +/** + * hal_rx_get_udp_proto: API to get UDP proto field + * from rx_msdu_start TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: UDP proto field value + */ +static inline bool +hal_rx_get_udp_proto(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (hal_soc->ops->hal_rx_get_udp_proto) + return hal_soc->ops->hal_rx_get_udp_proto(buf); + + return 0; +} + +/** + * hal_rx_get_fisa_flow_agg_continuation: API to get fisa flow_agg_continuation + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow_agg_continuation bit field value + */ +static inline bool +hal_rx_get_fisa_flow_agg_continuation(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (hal_soc->ops->hal_rx_get_fisa_flow_agg_continuation) + return hal_soc->ops->hal_rx_get_fisa_flow_agg_continuation(buf); + + return 0; +} + +/** + * hal_rx_get_fisa_flow_agg_count: API to get fisa flow_agg count from + * rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow_agg count value + */ +static inline uint8_t +hal_rx_get_fisa_flow_agg_count(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (hal_soc->ops->hal_rx_get_fisa_flow_agg_count) + return hal_soc->ops->hal_rx_get_fisa_flow_agg_count(buf); + + return 0; +} + +/** + * hal_rx_get_fisa_timeout: API to get fisa time out from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fisa flow_agg timeout bit value + */ +static inline bool +hal_rx_get_fisa_timeout(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + if (!hal_soc || !hal_soc->ops) { + hal_err("hal handle is NULL"); + QDF_BUG(0); + return 0; + } + + if (hal_soc->ops->hal_rx_get_fisa_timeout) + return hal_soc->ops->hal_rx_get_fisa_timeout(buf); + + return 0; } -#endif /** * hal_rx_buffer_addr_info_get_paddr(): get paddr/sw_cookie from @@ -3464,4 +3782,26 @@ bool hal_rx_is_buf_addr_info_valid( return (HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) == 0) ? false : true; } + +#define HAL_RX_ATTN_MSDU_LEN_ERR_GET(_rx_attn) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_attn, \ + RX_ATTENTION_1_MSDU_LENGTH_ERR_OFFSET)), \ + RX_ATTENTION_1_MSDU_LENGTH_ERR_MASK, \ + RX_ATTENTION_1_MSDU_LENGTH_ERR_LSB)) + +/** + * hal_rx_attn_msdu_len_err_get(): Get msdu_len_err value from + * rx attention tlvs + * @buf: pointer to rx pkt tlvs hdr + * + * Return: msdu_len_err value + */ +static inline uint32_t +hal_rx_attn_msdu_len_err_get(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_attention *rx_attn = &pkt_tlvs->attn_tlv.rx_attn; + + return HAL_RX_ATTN_MSDU_LEN_ERR_GET(rx_attn); +} #endif /* _HAL_RX_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.c new file mode 100644 index 0000000000000000000000000000000000000000..98d0923ea48c584612df6b89e3412eb9a69b3cbb --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.c @@ -0,0 +1,774 @@ +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "qdf_module.h" +#include "dp_types.h" +#include "hal_rx_flow.h" + +#if defined(WLAN_SUPPORT_RX_FISA) +void hal_rx_dump_fse_table(struct hal_rx_fst *fst) +{ + int i = 0; + struct rx_flow_search_entry *fse = + (struct rx_flow_search_entry *)fst->base_vaddr; + + dp_info("Number flow table entries %d", fst->add_flow_count); + for (i = 0; i < fst->max_entries; i++) { + if (fse[i].valid) { + dp_info("index %d:" + " src_ip_127_96 0x%x" + " src_ip_95_640 0x%x" + " src_ip_63_32 0x%x" + " src_ip_31_0 0x%x" + " dest_ip_127_96 0x%x" + " dest_ip_95_64 0x%x" + " dest_ip_63_32 0x%x" + " dest_ip_31_0 0x%x" + " src_port 0x%x" + " dest_port 0x%x" + " l4_protocol 0x%x" + " valid 0x%x" + " reo_destination_indication 0x%x" + " msdu_drop 0x%x" + " reo_destination_handler 0x%x" + " metadata 0x%x" + " aggregation_count0x%x" + " lro_eligible 0x%x" + " msdu_count 0x%x" + " msdu_byte_count 0x%x" + " timestamp 0x%x" + " cumulative_l4_checksum 0x%x" + " cumulative_ip_length 0x%x" + " tcp_sequence_number 0x%x", + i, + fse[i].src_ip_127_96, + fse[i].src_ip_95_64, + fse[i].src_ip_63_32, + fse[i].src_ip_31_0, + fse[i].dest_ip_127_96, + fse[i].dest_ip_95_64, + fse[i].dest_ip_63_32, + fse[i].dest_ip_31_0, + fse[i].src_port, + fse[i].dest_port, + fse[i].l4_protocol, + fse[i].valid, + fse[i].reo_destination_indication, + fse[i].msdu_drop, + fse[i].reo_destination_handler, + fse[i].metadata, + fse[i].aggregation_count, + fse[i].lro_eligible, + fse[i].msdu_count, + fse[i].msdu_byte_count, + fse[i].timestamp, + fse[i].cumulative_l4_checksum, + fse[i].cumulative_ip_length, + fse[i].tcp_sequence_number); + } + } +} +#else +void hal_rx_dump_fse_table(struct hal_rx_fst *fst) +{ +} +#endif + +/** + * hal_rx_flow_setup_fse() - Setup a flow search entry in HW FST + * @fst: Pointer to the Rx Flow Search Table + * @table_offset: offset into the table where the flow is to be setup + * @flow: Flow Parameters + * + * Return: Success/Failure + */ +#ifdef WLAN_SUPPORT_RX_FLOW_TAG +void * +hal_rx_flow_setup_fse(struct hal_rx_fst *fst, uint32_t table_offset, + struct hal_rx_flow *flow) +{ + uint8_t *fse; + bool fse_valid; + + if (table_offset >= fst->max_entries) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "HAL FSE table offset %u exceeds max entries %u", + table_offset, fst->max_entries); + return NULL; + } + + fse = (uint8_t *)fst->base_vaddr + + (table_offset * HAL_RX_FST_ENTRY_SIZE); + + fse_valid = HAL_GET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID); + + if (fse_valid) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "HAL FSE %pK already valid", fse); + return NULL; + } + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_0, SRC_IP_127_96) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_0, SRC_IP_127_96, + qdf_htonl(flow->tuple_info.src_ip_127_96)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_1, SRC_IP_95_64) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_1, SRC_IP_95_64, + qdf_htonl(flow->tuple_info.src_ip_95_64)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_2, SRC_IP_63_32) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_2, SRC_IP_63_32, + qdf_htonl(flow->tuple_info.src_ip_63_32)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_3, SRC_IP_31_0) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_3, SRC_IP_31_0, + qdf_htonl(flow->tuple_info.src_ip_31_0)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_4, DEST_IP_127_96) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_4, DEST_IP_127_96, + qdf_htonl(flow->tuple_info.dest_ip_127_96)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_5, DEST_IP_95_64) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_5, DEST_IP_95_64, + qdf_htonl(flow->tuple_info.dest_ip_95_64)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_6, DEST_IP_63_32) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_6, DEST_IP_63_32, + qdf_htonl(flow->tuple_info.dest_ip_63_32)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_7, DEST_IP_31_0) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_7, DEST_IP_31_0, + qdf_htonl(flow->tuple_info.dest_ip_31_0)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, DEST_PORT); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, DEST_PORT) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_8, DEST_PORT, + (flow->tuple_info.dest_port)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, SRC_PORT); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, SRC_PORT) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_8, SRC_PORT, + (flow->tuple_info.src_port)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL, + flow->tuple_info.l4_protocol); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER, + flow->reo_destination_handler); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, VALID, 1); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_10, METADATA); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_10, METADATA) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_10, METADATA, + flow->fse_metadata); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, REO_DESTINATION_INDICATION); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, REO_DESTINATION_INDICATION) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_11, + REO_DESTINATION_INDICATION, + flow->reo_destination_indication); + + /* Reset all the other fields in FSE */ + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, RESERVED_9); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, MSDU_DROP); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, RESERVED_11); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, MSDU_COUNT); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_12, MSDU_BYTE_COUNT); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_13, TIMESTAMP); + + return fse; +} +#elif defined(WLAN_SUPPORT_RX_FISA) +/** + * hal_rx_flow_setup_fse() - Setup a flow search entry in HW FST + * @fst: Pointer to the Rx Flow Search Table + * @table_offset: offset into the table where the flow is to be setup + * @flow: Flow Parameters + * + * Flow table entry fields are updated in host byte order, little endian order. + * + * Return: Success/Failure + */ +void * +hal_rx_flow_setup_fse(struct hal_rx_fst *fst, uint32_t table_offset, + struct hal_rx_flow *flow) +{ + uint8_t *fse; + bool fse_valid; + + if (table_offset >= fst->max_entries) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "HAL FSE table offset %u exceeds max entries %u", + table_offset, fst->max_entries); + return NULL; + } + + fse = (uint8_t *)fst->base_vaddr + + (table_offset * HAL_RX_FST_ENTRY_SIZE); + + fse_valid = HAL_GET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID); + + if (fse_valid) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "HAL FSE %pK already valid", fse); + return NULL; + } + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_0, SRC_IP_127_96) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_0, SRC_IP_127_96, + (flow->tuple_info.src_ip_127_96)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_1, SRC_IP_95_64) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_1, SRC_IP_95_64, + (flow->tuple_info.src_ip_95_64)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_2, SRC_IP_63_32) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_2, SRC_IP_63_32, + (flow->tuple_info.src_ip_63_32)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_3, SRC_IP_31_0) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_3, SRC_IP_31_0, + (flow->tuple_info.src_ip_31_0)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_4, DEST_IP_127_96) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_4, DEST_IP_127_96, + (flow->tuple_info.dest_ip_127_96)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_5, DEST_IP_95_64) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_5, DEST_IP_95_64, + (flow->tuple_info.dest_ip_95_64)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_6, DEST_IP_63_32) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_6, DEST_IP_63_32, + (flow->tuple_info.dest_ip_63_32)); + + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_7, DEST_IP_31_0) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_7, DEST_IP_31_0, + (flow->tuple_info.dest_ip_31_0)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, DEST_PORT); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, DEST_PORT) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_8, DEST_PORT, + (flow->tuple_info.dest_port)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, SRC_PORT); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_8, SRC_PORT) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_8, SRC_PORT, + (flow->tuple_info.src_port)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, L4_PROTOCOL, + flow->tuple_info.l4_protocol); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_HANDLER, + flow->reo_destination_handler); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, VALID, 1); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_10, METADATA); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_10, METADATA) = + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_10, METADATA, + (flow->fse_metadata)); + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_INDICATION); + HAL_SET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, REO_DESTINATION_INDICATION) |= + HAL_SET_FLD_SM(RX_FLOW_SEARCH_ENTRY_9, + REO_DESTINATION_INDICATION, + flow->reo_destination_indication); + + /* Reset all the other fields in FSE */ + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, RESERVED_9); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, MSDU_DROP); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_11, MSDU_COUNT); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_12, MSDU_BYTE_COUNT); + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_13, TIMESTAMP); + + return fse; +} +#endif /* WLAN_SUPPORT_RX_FISA */ +qdf_export_symbol(hal_rx_flow_setup_fse); + +/** + * hal_rx_flow_delete_entry() - Delete a flow from the Rx Flow Search Table + * @fst: Pointer to the Rx Flow Search Table + * @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST + * + * Return: Success/Failure + */ +inline QDF_STATUS +hal_rx_flow_delete_entry(struct hal_rx_fst *fst, void *hal_rx_fse) +{ + uint8_t *fse = (uint8_t *)hal_rx_fse; + + if (!HAL_GET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID)) + return QDF_STATUS_E_NOENT; + + HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID); + + return QDF_STATUS_SUCCESS; +} +qdf_export_symbol(hal_rx_flow_delete_entry); + +#ifndef WLAN_SUPPORT_RX_FISA +/** + * hal_rx_fst_key_configure() - Configure the Toeplitz key in the FST + * @fst: Pointer to the Rx Flow Search Table + * + * Return: Success/Failure + */ +static void hal_rx_fst_key_configure(struct hal_rx_fst *fst) +{ + uint8_t key_bytes[HAL_FST_HASH_KEY_SIZE_BYTES]; + + qdf_mem_copy(key_bytes, fst->key, HAL_FST_HASH_KEY_SIZE_BYTES); + + /** + * The Toeplitz algorithm as per the Microsoft spec works in a + * “big-endian” manner, using the MSBs of the key to hash the + * initial bytes of the input going on to use up the lower order bits + * of the key to hash further bytes of the input until the LSBs of the + * key are used finally. + * + * So first, rightshift 320-bit input key 5 times to get 315 MS bits + */ + key_bitwise_shift_left(key_bytes, HAL_FST_HASH_KEY_SIZE_BYTES, 5); + key_reverse(fst->shifted_key, key_bytes, HAL_FST_HASH_KEY_SIZE_BYTES); +} +#else +static void hal_rx_fst_key_configure(struct hal_rx_fst *fst) +{ +} +#endif + +/** + * hal_rx_fst_get_base() - Retrieve the virtual base address of the Rx FST + * @fst: Pointer to the Rx Flow Search Table + * + * Return: Success/Failure + */ +static inline void *hal_rx_fst_get_base(struct hal_rx_fst *fst) +{ + return fst->base_vaddr; +} + +/** + * hal_rx_fst_get_fse_size() - Retrieve the size of each entry(flow) in Rx FST + * + * Return: size of each entry/flow in Rx FST + */ +static inline uint32_t hal_rx_fst_get_fse_size(void) +{ + return HAL_RX_FST_ENTRY_SIZE; +} + +/** + * hal_rx_flow_get_tuple_info() - Retrieve the 5-tuple flow info for an entry + * @hal_fse: Pointer to the Flow in Rx FST + * @tuple_info: 5-tuple info of the flow returned to the caller + * + * Return: Success/Failure + */ +QDF_STATUS hal_rx_flow_get_tuple_info(void *hal_fse, + struct hal_flow_tuple_info *tuple_info) +{ + if (!hal_fse || !tuple_info) + return QDF_STATUS_E_INVAL; + + if (!HAL_GET_FLD(hal_fse, RX_FLOW_SEARCH_ENTRY_9, VALID)) + return QDF_STATUS_E_NOENT; + + tuple_info->src_ip_127_96 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_0, + SRC_IP_127_96)); + tuple_info->src_ip_95_64 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_1, + SRC_IP_95_64)); + tuple_info->src_ip_63_32 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_2, + SRC_IP_63_32)); + tuple_info->src_ip_31_0 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_3, + SRC_IP_31_0)); + tuple_info->dest_ip_127_96 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_4, + DEST_IP_127_96)); + tuple_info->dest_ip_95_64 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_5, + DEST_IP_95_64)); + tuple_info->dest_ip_63_32 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_6, + DEST_IP_63_32)); + tuple_info->dest_ip_31_0 = + qdf_ntohl(HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_7, + DEST_IP_31_0)); + tuple_info->dest_port = HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_8, + DEST_PORT); + tuple_info->src_port = HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_8, + SRC_PORT); + tuple_info->l4_protocol = HAL_GET_FLD(hal_fse, + RX_FLOW_SEARCH_ENTRY_9, + L4_PROTOCOL); + + return QDF_STATUS_SUCCESS; +} + +#ifndef WLAN_SUPPORT_RX_FISA +/** + * hal_flow_toeplitz_create_cache() - Calculate hashes for each possible + * byte value with the key taken as is + * + * @fst: FST Handle + * @key: Hash Key + * + * Return: Success/Failure + */ +static void hal_flow_toeplitz_create_cache(struct hal_rx_fst *fst) +{ + int bit; + int val; + int i; + uint8_t *key = fst->shifted_key; + + /* + * Initialise to first 32 bits of the key; shift in further key material + * through the loop + */ + uint32_t cur_key = (key[0] << 24) | (key[1] << 16) | (key[2] << 8) | + key[3]; + + for (i = 0; i < HAL_FST_HASH_KEY_SIZE_BYTES; i++) { + uint8_t new_key_byte; + uint32_t shifted_key[8]; + + if (i + 4 < HAL_FST_HASH_KEY_SIZE_BYTES) + new_key_byte = key[i + 4]; + else + new_key_byte = 0; + + shifted_key[0] = cur_key; + + for (bit = 1; bit < 8; bit++) { + /* + * For each iteration, shift out one more bit of the + * current key and shift in one more bit of the new key + * material + */ + shifted_key[bit] = cur_key << bit | + new_key_byte >> (8 - bit); + } + + for (val = 0; val < (1 << 8); val++) { + uint32_t hash = 0; + int mask; + + /* + * For each bit set in the input, XOR in + * the appropriately shifted key + */ + for (bit = 0, mask = 1 << 7; bit < 8; bit++, mask >>= 1) + if ((val & mask)) + hash ^= shifted_key[bit]; + + fst->key_cache[i][val] = hash; + } + + cur_key = cur_key << 8 | new_key_byte; + } +} +#else +static void hal_flow_toeplitz_create_cache(struct hal_rx_fst *fst) +{ +} +#endif + +/** + * hal_rx_fst_attach() - Initialize Rx flow search table in HW FST + * + * @qdf_dev: QDF device handle + * @hal_fst_base_paddr: Pointer to the physical base address of the Rx FST + * @max_entries: Max number of flows allowed in the FST + * @max_search: Number of collisions allowed in the hash-based FST + * @hash_key: Toeplitz key used for the hash FST + * + * Return: + */ +struct hal_rx_fst * +hal_rx_fst_attach(qdf_device_t qdf_dev, + uint64_t *hal_fst_base_paddr, uint16_t max_entries, + uint16_t max_search, uint8_t *hash_key) +{ + struct hal_rx_fst *fst = qdf_mem_malloc(sizeof(struct hal_rx_fst)); + + if (!fst) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + FL("hal fst allocation failed,")); + return NULL; + } + + qdf_mem_set(fst, 0, sizeof(struct hal_rx_fst)); + + fst->key = hash_key; + fst->max_skid_length = max_search; + fst->max_entries = max_entries; + fst->hash_mask = max_entries - 1; + + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "HAL FST allocation %pK %d * %d\n", fst, + fst->max_entries, HAL_RX_FST_ENTRY_SIZE); + + fst->base_vaddr = (uint8_t *)qdf_mem_alloc_consistent(qdf_dev, + qdf_dev->dev, + (fst->max_entries * HAL_RX_FST_ENTRY_SIZE), + &fst->base_paddr); + + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, + "hal_rx_fst base address 0x%pK", (void *)fst->base_paddr); + if (!fst->base_vaddr) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + FL("hal fst->base_vaddr allocation failed")); + qdf_mem_free(fst); + return NULL; + } + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, + (void *)fst->key, HAL_FST_HASH_KEY_SIZE_BYTES); + + qdf_mem_set((uint8_t *)fst->base_vaddr, 0, + (fst->max_entries * HAL_RX_FST_ENTRY_SIZE)); + + hal_rx_fst_key_configure(fst); + hal_flow_toeplitz_create_cache(fst); + *hal_fst_base_paddr = (uint64_t)fst->base_paddr; + return fst; +} +qdf_export_symbol(hal_rx_fst_attach); + +/** + * hal_rx_fst_detach() - De-init the Rx flow search table from HW + * + * @rx_fst: Pointer to the Rx FST + * @qdf_dev: QDF device handle + * + * Return: + */ +void hal_rx_fst_detach(struct hal_rx_fst *rx_fst, + qdf_device_t qdf_dev) +{ + if (!rx_fst || !qdf_dev) + return; + + qdf_mem_free_consistent(qdf_dev, qdf_dev->dev, + rx_fst->max_entries * HAL_RX_FST_ENTRY_SIZE, + rx_fst->base_vaddr, rx_fst->base_paddr, 0); + + qdf_mem_free(rx_fst); +} +qdf_export_symbol(hal_rx_fst_detach); + +#ifndef WLAN_SUPPORT_RX_FISA +/** + * hal_flow_toeplitz_hash() - Calculate Toeplitz hash by using the cached key + * + * @hal_fst: FST Handle + * @flow: Flow Parameters + * + * Return: Success/Failure + */ +uint32_t +hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow) +{ + int i, j; + uint32_t hash = 0; + struct hal_rx_fst *fst = (struct hal_rx_fst *)hal_fst; + uint32_t input[HAL_FST_HASH_KEY_SIZE_WORDS]; + uint8_t *tuple; + + qdf_mem_zero(input, HAL_FST_HASH_KEY_SIZE_BYTES); + *(uint32_t *)&input[0] = qdf_htonl(flow->tuple_info.src_ip_127_96); + *(uint32_t *)&input[1] = qdf_htonl(flow->tuple_info.src_ip_95_64); + *(uint32_t *)&input[2] = qdf_htonl(flow->tuple_info.src_ip_63_32); + *(uint32_t *)&input[3] = qdf_htonl(flow->tuple_info.src_ip_31_0); + *(uint32_t *)&input[4] = qdf_htonl(flow->tuple_info.dest_ip_127_96); + *(uint32_t *)&input[5] = qdf_htonl(flow->tuple_info.dest_ip_95_64); + *(uint32_t *)&input[6] = qdf_htonl(flow->tuple_info.dest_ip_63_32); + *(uint32_t *)&input[7] = qdf_htonl(flow->tuple_info.dest_ip_31_0); + *(uint32_t *)&input[8] = (flow->tuple_info.dest_port << 16) | + (flow->tuple_info.src_port); + *(uint32_t *)&input[9] = flow->tuple_info.l4_protocol; + + tuple = (uint8_t *)input; + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + tuple, sizeof(input)); + for (i = 0, j = HAL_FST_HASH_DATA_SIZE - 1; + i < HAL_FST_HASH_KEY_SIZE_BYTES && j >= 0; i++, j--) { + hash ^= fst->key_cache[i][tuple[j]]; + } + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, + "Hash value %u %u truncated hash %u\n", hash, + (hash >> 12), (hash >> 12) % (fst->max_entries)); + + hash >>= 12; + hash &= (fst->max_entries - 1); + + return hash; +} +#else +uint32_t +hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow) +{ + return 0; +} +#endif +qdf_export_symbol(hal_flow_toeplitz_hash); + +/** + * hal_rx_get_hal_hash() - Retrieve hash index of a flow in the FST table + * + * @hal_fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * + * Return: hash index truncated to the size of the hash table + */ +uint32_t hal_rx_get_hal_hash(struct hal_rx_fst *hal_fst, uint32_t flow_hash) +{ + uint32_t trunc_hash = flow_hash; + + /* Take care of hash wrap around scenario */ + if (flow_hash >= hal_fst->max_entries) + trunc_hash &= hal_fst->hash_mask; + return trunc_hash; +} +qdf_export_symbol(hal_rx_get_hal_hash); + +/** + * hal_rx_insert_flow_entry() - Add a flow into the FST table + * + * @hal_fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * @flow_tuple_info: Flow tuple used to compute the hash + * @flow_index: Hash index of the flow in the table when inserted successfully + * + * Return: Success if flow is inserted into the table, error otherwise + */ +QDF_STATUS +hal_rx_insert_flow_entry(struct hal_rx_fst *fst, uint32_t flow_hash, + void *flow_tuple_info, uint32_t *flow_idx) +{ + int i; + void *hal_fse = NULL; + uint32_t hal_hash = 0; + struct hal_flow_tuple_info hal_tuple_info = { 0 }; + QDF_STATUS status; + + for (i = 0; i < fst->max_skid_length; i++) { + hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i)); + hal_fse = (uint8_t *)fst->base_vaddr + + (hal_hash * HAL_RX_FST_ENTRY_SIZE); + status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info); + if (status == QDF_STATUS_E_NOENT) + break; + + /* Find the matching flow entry in HW FST */ + if (!qdf_mem_cmp(&hal_tuple_info, + flow_tuple_info, + sizeof(struct hal_flow_tuple_info))) { + dp_err("Duplicate flow entry in FST %u at skid %u ", + hal_hash, i); + return QDF_STATUS_E_EXISTS; + } + } + if (i == fst->max_skid_length) { + dp_err("Max skid length reached for hash %u", flow_hash); + return QDF_STATUS_E_RANGE; + } + *flow_idx = hal_hash; + dp_info("flow_hash = %u, skid_entry = %d, flow_addr = %pK flow_idx = %d", + flow_hash, i, hal_fse, *flow_idx); + + return QDF_STATUS_SUCCESS; +} +qdf_export_symbol(hal_rx_insert_flow_entry); + +/** + * hal_rx_find_flow_from_tuple() - Find a flow in the FST table + * + * @fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * @flow_tuple_info: Flow tuple used to compute the hash + * @flow_index: Hash index of the flow in the table when found + * + * Return: Success if matching flow is found in the table, error otherwise + */ +QDF_STATUS +hal_rx_find_flow_from_tuple(struct hal_rx_fst *fst, uint32_t flow_hash, + void *flow_tuple_info, uint32_t *flow_idx) +{ + int i; + void *hal_fse = NULL; + uint32_t hal_hash = 0; + struct hal_flow_tuple_info hal_tuple_info = { 0 }; + QDF_STATUS status; + + for (i = 0; i < fst->max_skid_length; i++) { + hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i)); + hal_fse = (uint8_t *)fst->base_vaddr + + (hal_hash * HAL_RX_FST_ENTRY_SIZE); + status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info); + if (status != QDF_STATUS_SUCCESS) + continue; + + /* Find the matching flow entry in HW FST */ + if (!qdf_mem_cmp(&hal_tuple_info, + flow_tuple_info, + sizeof(struct hal_flow_tuple_info))) { + break; + } + } + + if (i == fst->max_skid_length) { + dp_err("Max skid length reached for hash %u", flow_hash); + return QDF_STATUS_E_RANGE; + } + + *flow_idx = hal_hash; + dp_info("flow_hash = %u, skid_entry = %d, flow_addr = %pK flow_idx = %d", + flow_hash, i, hal_fse, *flow_idx); + + return QDF_STATUS_SUCCESS; +} +qdf_export_symbol(hal_rx_find_flow_from_tuple); diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.h new file mode 100644 index 0000000000000000000000000000000000000000..6101034e74be5946310620184def12858572dd3c --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ +#ifndef __HAL_RX_FLOW_H +#define __HAL_RX_FLOW_H + +#include "hal_flow.h" +#include "wlan_cfg.h" +#include "hal_api.h" +#include "qdf_mem.h" +#include "rx_flow_search_entry.h" + +#define HAL_FST_HASH_KEY_SIZE_BITS 315 +#define HAL_FST_HASH_KEY_SIZE_BYTES 40 +#define HAL_FST_HASH_KEY_SIZE_WORDS 10 +#define HAL_FST_HASH_DATA_SIZE 37 +#define HAL_FST_HASH_MASK 0x7ffff +#define HAL_RX_FST_ENTRY_SIZE (NUM_OF_DWORDS_RX_FLOW_SEARCH_ENTRY * 4) + +/** + * Four possible options for IP SA/DA prefix, currently use 0x0 which + * maps to type 2 in HW spec + */ +#define HAL_FST_IP_DA_SA_PFX_TYPE_IPV4_COMPATIBLE_IPV6 2 + +#define HAL_IP_DA_SA_PREFIX_IPV4_COMPATIBLE_IPV6 0x0 + +/** + * REO destination indication is a lower 4-bits of hash value + * This should match the REO destination used in Rx hash based routing. + */ +#define HAL_REO_DEST_IND_HASH_MASK 0xF + +/** + * REO destinations are valid from 16-31 for Hawkeye + * and 0-15 are not setup for SW + */ +#define HAL_REO_DEST_IND_START_OFFSET 0x10 + +/** + * struct hal_rx_flow - Rx Flow parameters to be sent to HW + * @tuple_info: Rx Flow 5-tuple (src & dest IP, src & dest ports, L4 protocol) + * @reo_destination_handler: REO destination for this flow + * @reo_destination_indication: REO indication for this flow + * @fse_metadata: Flow metadata or tag passed to HW for marking packets + */ +struct hal_rx_flow { + struct hal_flow_tuple_info tuple_info; + uint8_t reo_destination_handler; + uint8_t reo_destination_indication; + uint32_t fse_metadata; +}; + +/** + * enum hal_rx_fse_reo_destination_handler + * @HAL_RX_FSE_REO_DEST_FT: Use this entry's destination indication + * @HAL_RX_FSE_REO_DEST_ASPT: Use Address Search + Peer Table's entry + * @HAL_RX_FSE_REO_DEST_FT2: Use FT2's destination indication + * @HAL_RX_FSE_REO_DEST_CCE: Use CCE's destination indication for this entry + */ +enum hal_rx_fse_reo_destination_handler { + HAL_RX_FSE_REO_DEST_FT = 0, + HAL_RX_FSE_REO_DEST_ASPT = 1, + HAL_RX_FSE_REO_DEST_FT2 = 2, + HAL_RX_FSE_REO_DEST_CCE = 3, +}; + +/** + * struct hal_rx_fst - HAL RX Flow search table context + * @base_vaddr: Virtual Base address of HW FST + * @base_paddr: Physical Base address of HW FST + * @key: Pointer to 320-bit Key read from cfg + * @shifted_key: Pointer to left-shifted 320-bit Key used for Toeplitz Hash + * @max_entries : Max number of entries in flow searchh table + * @max_skid_length : Max search length if there is hash collision + * @hash_mask: Hash mask to apply to index into FST + * @key_cache: Toepliz Key Cache configured key + */ +struct hal_rx_fst { + uint8_t *base_vaddr; + qdf_dma_addr_t base_paddr; + uint8_t *key; +#ifndef WLAN_SUPPORT_RX_FISA + uint8_t shifted_key[HAL_FST_HASH_KEY_SIZE_BYTES]; + uint32_t key_cache[HAL_FST_HASH_KEY_SIZE_BYTES][1 << 8]; +#endif + uint16_t max_entries; + uint16_t max_skid_length; + uint16_t hash_mask; + uint32_t add_flow_count; + uint32_t del_flow_count; +}; + +/** + * hal_rx_flow_setup_fse() - Setup a flow search entry in HW FST + * @fst: Pointer to the Rx Flow Search Table + * @table_offset: offset into the table where the flow is to be setup + * @flow: Flow Parameters + * + * Return: Success/Failure + */ +void *hal_rx_flow_setup_fse(struct hal_rx_fst *fst, + uint32_t table_offset, + struct hal_rx_flow *flow); + +/** + * hal_rx_flow_delete_entry() - Delete a flow from the Rx Flow Search Table + * @fst: Pointer to the Rx Flow Search Table + * @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST + * + * Return: Success/Failure + */ +QDF_STATUS +hal_rx_flow_delete_entry(struct hal_rx_fst *fst, void *hal_rx_fse); + +/** + * hal_rx_flow_get_tuple_info() - Retrieve the 5-tuple flow info for an entry + * @hal_fse: Pointer to the Flow in Rx FST + * @tuple_info: 5-tuple info of the flow returned to the caller + * + * Return: Success/Failure + */ +QDF_STATUS hal_rx_flow_get_tuple_info(void *hal_fse, + struct hal_flow_tuple_info *tuple_info); + +/** + * hal_rx_fst_attach() - Initialize Rx flow search table in HW FST + * + * @qdf_dev: QDF device handle + * @hal_fst_base_paddr: Pointer to the physical base address of the Rx FST + * @max_entries: Max number of flows allowed in the FST + * @max_search: Number of collisions allowed in the hash-based FST + * @hash_key: Toeplitz key used for the hash FST + * + * Return: + */ +struct hal_rx_fst * +hal_rx_fst_attach(qdf_device_t qdf_dev, + uint64_t *hal_fst_base_paddr, uint16_t max_entries, + uint16_t max_search, uint8_t *hash_key); + +/** + * hal_rx_fst_detach() - De-init the Rx flow search table from HW + * + * @rx_fst: Pointer to the Rx FST + * @qdf_dev: QDF device handle + * + * Return: + */ +void hal_rx_fst_detach(struct hal_rx_fst *rx_fst, qdf_device_t qdf_dev); + +/** + * hal_rx_insert_flow_entry() - Add a flow into the FST table + * + * @hal_fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * @flow_tuple_info: Flow tuple used to compute the hash + * @flow_index: Hash index of the flow in the table when inserted successfully + * + * Return: Success if flow is inserted into the table, error otherwise + */ +QDF_STATUS +hal_rx_insert_flow_entry(struct hal_rx_fst *fst, uint32_t flow_hash, + void *flow_tuple_info, uint32_t *flow_idx); + +/** + * hal_rx_find_flow_from_tuple() - Find a flow in the FST table + * + * @fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * @flow_tuple_info: Flow tuple used to compute the hash + * @flow_index: Hash index of the flow in the table when found + * + * Return: Success if matching flow is found in the table, error otherwise + */ +QDF_STATUS +hal_rx_find_flow_from_tuple(struct hal_rx_fst *fst, uint32_t flow_hash, + void *flow_tuple_info, uint32_t *flow_idx); + +/** + * hal_rx_get_hal_hash() - Retrieve hash index of a flow in the FST table + * + * @hal_fst: HAL Rx FST Handle + * @flow_hash: Flow hash computed from flow tuple + * + * Return: hash index truncated to the size of the hash table + */ +uint32_t hal_rx_get_hal_hash(struct hal_rx_fst *hal_fst, uint32_t flow_hash); + +/** + * hal_flow_toeplitz_hash() - Calculate Toeplitz hash by using the cached key + * + * @hal_fst: FST Handle + * @flow: Flow Parameters + * + * Return: Success/Failure + */ +uint32_t +hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow); + +void hal_rx_dump_fse_table(struct hal_rx_fst *fst); +#endif /* HAL_RX_FLOW_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c index d8ae29eefa7a490be10d43a932434225aeddd3ba..1290984f77497e3b2d8696473b3fe2865e58933a 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,14 +28,20 @@ void hal_qca6290_attach(struct hal_soc *hal); #ifdef QCA_WIFI_QCA8074 void hal_qca8074_attach(struct hal_soc *hal); #endif -#ifdef QCA_WIFI_QCA8074V2 +#if defined(QCA_WIFI_QCA8074V2) || defined(QCA_WIFI_QCA6018) void hal_qca8074v2_attach(struct hal_soc *hal); #endif #ifdef QCA_WIFI_QCA6390 void hal_qca6390_attach(struct hal_soc *hal); #endif -#ifdef QCA_WIFI_QCA6018 -void hal_qca6018_attach(struct hal_soc *hal); +#ifdef QCA_WIFI_QCA6490 +void hal_qca6490_attach(struct hal_soc *hal); +#endif +#ifdef QCA_WIFI_QCN9000 +void hal_qcn9000_attach(struct hal_soc *hal); +#endif +#ifdef QCA_WIFI_QCA6750 +void hal_qca6750_attach(struct hal_soc *hal); #endif #ifdef ENABLE_VERBOSE_DEBUG @@ -117,16 +123,15 @@ static struct hal_srng *hal_get_srng(struct hal_soc *hal, int ring_id) #define HP_OFFSET_IN_REG_START 1 #define OFFSET_FROM_HP_TO_TP 4 -static void hal_update_srng_hp_tp_address(void *hal_soc, +static void hal_update_srng_hp_tp_address(struct hal_soc *hal_soc, int shadow_config_index, int ring_type, int ring_num) { struct hal_srng *srng; - struct hal_soc *hal = (struct hal_soc *)hal_soc; int ring_id; struct hal_hw_srng_config *ring_config = - HAL_SRNG_CONFIG(hal, ring_type); + HAL_SRNG_CONFIG(hal_soc, ring_type); ring_id = hal_get_srng_ring_id(hal_soc, ring_type, ring_num, 0); if (ring_id < 0) @@ -136,20 +141,93 @@ static void hal_update_srng_hp_tp_address(void *hal_soc, if (ring_config->ring_dir == HAL_SRNG_DST_RING) { srng->u.dst_ring.tp_addr = SHADOW_REGISTER(shadow_config_index) - + hal->dev_base_addr; + + hal_soc->dev_base_addr; hal_debug("tp_addr=%pK dev base addr %pK index %u", - srng->u.dst_ring.tp_addr, hal->dev_base_addr, + srng->u.dst_ring.tp_addr, hal_soc->dev_base_addr, shadow_config_index); } else { srng->u.src_ring.hp_addr = SHADOW_REGISTER(shadow_config_index) - + hal->dev_base_addr; + + hal_soc->dev_base_addr; hal_debug("hp_addr=%pK dev base addr %pK index %u", srng->u.src_ring.hp_addr, - hal->dev_base_addr, shadow_config_index); + hal_soc->dev_base_addr, shadow_config_index); + } + +} + +#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE +void hal_set_one_target_reg_config(struct hal_soc *hal, + uint32_t target_reg_offset, + int list_index) +{ + int i = list_index; + + qdf_assert_always(i < MAX_GENERIC_SHADOW_REG); + hal->list_shadow_reg_config[i].target_register = + target_reg_offset; + hal->num_generic_shadow_regs_configured++; +} + +qdf_export_symbol(hal_set_one_target_reg_config); + +#define REO_R0_DESTINATION_RING_CTRL_ADDR_OFFSET 0x4 +#define MAX_REO_REMAP_SHADOW_REGS 4 +QDF_STATUS hal_set_shadow_regs(void *hal_soc) +{ + uint32_t target_reg_offset; + struct hal_soc *hal = (struct hal_soc *)hal_soc; + int i; + struct hal_hw_srng_config *srng_config = + &hal->hw_srng_table[WBM2SW_RELEASE]; + + target_reg_offset = + HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET); + + for (i = 0; i < MAX_REO_REMAP_SHADOW_REGS; i++) { + hal_set_one_target_reg_config(hal, target_reg_offset, i); + target_reg_offset += REO_R0_DESTINATION_RING_CTRL_ADDR_OFFSET; } + target_reg_offset = srng_config->reg_start[HP_OFFSET_IN_REG_START]; + target_reg_offset += (srng_config->reg_size[HP_OFFSET_IN_REG_START] + * HAL_IPA_TX_COMP_RING_IDX); + + hal_set_one_target_reg_config(hal, target_reg_offset, i); + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(hal_set_shadow_regs); + +QDF_STATUS hal_construct_shadow_regs(void *hal_soc) +{ + struct hal_soc *hal = (struct hal_soc *)hal_soc; + int shadow_config_index = hal->num_shadow_registers_configured; + int i; + int num_regs = hal->num_generic_shadow_regs_configured; + + for (i = 0; i < num_regs; i++) { + qdf_assert_always(shadow_config_index < MAX_SHADOW_REGISTERS); + hal->shadow_config[shadow_config_index].addr = + hal->list_shadow_reg_config[i].target_register; + hal->list_shadow_reg_config[i].shadow_config_index = + shadow_config_index; + hal->list_shadow_reg_config[i].va = + SHADOW_REGISTER(shadow_config_index) + + (uintptr_t)hal->dev_base_addr; + hal_debug("target_reg %x, shadow register 0x%x shadow_index 0x%x", + hal->shadow_config[shadow_config_index].addr, + SHADOW_REGISTER(shadow_config_index), + shadow_config_index); + shadow_config_index++; + hal->num_shadow_registers_configured++; + } + return QDF_STATUS_SUCCESS; } +qdf_export_symbol(hal_construct_shadow_regs); +#endif + QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type, int ring_num) @@ -191,7 +269,7 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc, qdf_export_symbol(hal_set_one_shadow_config); -QDF_STATUS hal_construct_shadow_config(void *hal_soc) +QDF_STATUS hal_construct_srng_shadow_regs(void *hal_soc) { int ring_type, ring_num; struct hal_soc *hal = (struct hal_soc *)hal_soc; @@ -216,7 +294,7 @@ QDF_STATUS hal_construct_shadow_config(void *hal_soc) return QDF_STATUS_SUCCESS; } -qdf_export_symbol(hal_construct_shadow_config); +qdf_export_symbol(hal_construct_srng_shadow_regs); void hal_get_shadow_config(void *hal_soc, struct pld_shadow_reg_v2_cfg **shadow_config, @@ -227,17 +305,14 @@ void hal_get_shadow_config(void *hal_soc, *shadow_config = hal->shadow_config; *num_shadow_registers_configured = hal->num_shadow_registers_configured; - - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s", __func__); } qdf_export_symbol(hal_get_shadow_config); -static void hal_validate_shadow_register(struct hal_soc *hal, - uint32_t *destination, - uint32_t *shadow_address) +static bool hal_validate_shadow_register(struct hal_soc *hal, + uint32_t *destination, + uint32_t *shadow_address) { unsigned int index; uint32_t *shadow_0_offset = SHADOW_REGISTER(0) + hal->dev_base_addr; @@ -257,17 +332,23 @@ static void hal_validate_shadow_register(struct hal_soc *hal, hal->shadow_config[index].addr); goto error; } - return; + return true; error: qdf_print("%s: baddr %pK, desination %pK, shadow_address %pK s0offset %pK index %x", __func__, hal->dev_base_addr, destination, shadow_address, shadow_0_offset, index); QDF_BUG(0); - return; + return false; } static void hal_target_based_configure(struct hal_soc *hal) { + /** + * Indicate Initialization of srngs to avoid force wake + * as umac power collapse is not enabled yet + */ + hal->init_phase = true; + switch (hal->target_type) { #ifdef QCA_WIFI_QCA6290 case TARGET_TYPE_QCA6290: @@ -281,21 +362,46 @@ static void hal_target_based_configure(struct hal_soc *hal) hal_qca6390_attach(hal); break; #endif -#if defined(QCA_WIFI_QCA8074) && defined(CONFIG_WIN) +#ifdef QCA_WIFI_QCA6490 + case TARGET_TYPE_QCA6490: + hal->use_register_windowing = true; + hal_qca6490_attach(hal); + hal->init_phase = false; + break; +#endif +#ifdef QCA_WIFI_QCA6750 + case TARGET_TYPE_QCA6750: + hal->use_register_windowing = true; + hal_qca6750_attach(hal); + break; +#endif +#if defined(QCA_WIFI_QCA8074) && defined(WIFI_TARGET_TYPE_3_0) case TARGET_TYPE_QCA8074: hal_qca8074_attach(hal); break; #endif -#if defined(QCA_WIFI_QCA8074V2) && defined(CONFIG_WIN) +#if defined(QCA_WIFI_QCA8074V2) case TARGET_TYPE_QCA8074V2: hal_qca8074v2_attach(hal); break; #endif -#if defined(QCA_WIFI_QCA6018) && defined(CONFIG_WIN) +#if defined(QCA_WIFI_QCA6018) case TARGET_TYPE_QCA6018: - hal_qca6018_attach(hal); + hal_qca8074v2_attach(hal); + break; +#endif + +#ifdef QCA_WIFI_QCN9000 + case TARGET_TYPE_QCN9000: + hal->use_register_windowing = true; + /* + * Static window map is enabled for qcn9000 to use 2mb bar + * size and use multiple windows to write into registers. + */ + hal->static_window_map = true; + hal_qcn9000_attach(hal); break; #endif default: @@ -303,10 +409,11 @@ static void hal_target_based_configure(struct hal_soc *hal) } } -uint32_t hal_get_target_type(struct hal_soc *hal) +uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; struct hif_target_info *tgt_info = - hif_get_target_info_handle(hal->hif_handle); + hif_get_target_info_handle(hal_soc->hif_handle); return tgt_info->target_type; } @@ -317,7 +424,7 @@ qdf_export_symbol(hal_get_target_type); #ifdef MEMORY_DEBUG /* * Length of the queue(array) used to hold delayed register writes. - * Must be a power of 2. + * Must be a multiple of 2. */ #define HAL_REG_WRITE_QUEUE_LEN 128 #else @@ -371,6 +478,7 @@ hal_process_reg_write_q_elem(struct hal_soc *hal, } q_elem->valid = 0; + srng->last_dequeue_time = q_elem->dequeue_time; SRNG_UNLOCK(&srng->lock); return write_val; @@ -397,9 +505,67 @@ static inline void hal_reg_write_fill_sched_delay_hist(struct hal_soc *hal, else if (delay_us < 5000) hist[REG_WRITE_SCHED_DELAY_SUB_5000us]++; else - hist[REG_WRITE_SCHED_DELAY_GE_5000us]++; + hist[REG_WRITE_SCHED_DELAY_GT_5000us]++; } +#ifdef SHADOW_WRITE_DELAY + +#define SHADOW_WRITE_MIN_DELTA_US 5 +#define SHADOW_WRITE_DELAY_US 50 + +/* + * Never add those srngs which are performance relate. + * The delay itself will hit performance heavily. + */ +#define IS_SRNG_MATCH(s) ((s)->ring_id == HAL_SRNG_CE_1_DST_STATUS || \ + (s)->ring_id == HAL_SRNG_CE_1_DST) + +static inline bool hal_reg_write_need_delay(struct hal_reg_write_q_elem *elem) +{ + struct hal_srng *srng = elem->srng; + struct hal_soc *hal; + qdf_time_t now; + qdf_iomem_t real_addr; + + if (qdf_unlikely(!srng)) + return false; + + hal = srng->hal_soc; + if (qdf_unlikely(!hal)) + return false; + + /* Check if it is target srng, and valid shadow reg */ + if (qdf_likely(!IS_SRNG_MATCH(srng))) + return false; + + if (srng->ring_dir == HAL_SRNG_SRC_RING) + real_addr = SRNG_SRC_ADDR(srng, HP); + else + real_addr = SRNG_DST_ADDR(srng, TP); + if (!hal_validate_shadow_register(hal, real_addr, elem->addr)) + return false; + + /* Check the time delta from last write of same srng */ + now = qdf_get_log_timestamp(); + if (qdf_log_timestamp_to_usecs(now - srng->last_dequeue_time) > + SHADOW_WRITE_MIN_DELTA_US) + return false; + + /* Delay dequeue, and record */ + qdf_udelay(SHADOW_WRITE_DELAY_US); + + srng->wstats.dequeue_delay++; + hal->stats.wstats.dequeue_delay++; + + return true; +} +#else +static inline bool hal_reg_write_need_delay(struct hal_reg_write_q_elem *elem) +{ + return false; +} +#endif + /** * hal_reg_write_work() - Worker to process delayed writes * @arg: hal_soc pointer @@ -416,7 +582,10 @@ static void hal_reg_write_work(void *arg) uint32_t *addr; q_elem = &hal->reg_write_queue[(hal->read_idx)]; + q_elem->work_scheduled_time = qdf_get_log_timestamp(); + /* Make sure q_elem consistent in the memory for multi-cores */ + qdf_rmb(); if (!q_elem->valid) return; @@ -429,7 +598,11 @@ static void hal_reg_write_work(void *arg) return; } - while (q_elem->valid) { + while (true) { + qdf_rmb(); + if (!q_elem->valid) + break; + q_elem->dequeue_time = qdf_get_log_timestamp(); ring_id = q_elem->srng->ring_id; addr = q_elem->addr; @@ -440,6 +613,10 @@ static void hal_reg_write_work(void *arg) hal->stats.wstats.dequeues++; qdf_atomic_dec(&hal->stats.wstats.q_depth); + if (hal_reg_write_need_delay(q_elem)) + hal_verbose_debug("Delay reg writer for srng 0x%x, addr 0x%pK", + q_elem->srng->ring_id, q_elem->addr); + write_val = hal_process_reg_write_q_elem(hal, q_elem); hal_verbose_debug("read_idx %u srng 0x%x, addr 0x%pK dequeue_val %u sched delay %llu us", hal->read_idx, ring_id, addr, write_val, delta_us); @@ -524,6 +701,17 @@ static void hal_reg_write_enqueue(struct hal_soc *hal_soc, qdf_wmb(); q_elem->valid = true; + /* + * After all other fields in the q_elem has been updated + * in memory successfully, the valid flag needs to be updated + * in memory in time too. + * Else there is a chance that the dequeuing worker thread + * might read stale valid flag and the work will be bypassed + * for this round. And if there is no other work scheduled + * later, this hal register writing won't be updated any more. + */ + qdf_wmb(); + srng->reg_write_in_progress = true; qdf_atomic_inc(&hal_soc->active_work_cnt); @@ -606,7 +794,7 @@ char *hal_fill_reg_write_srng_stats(struct hal_srng *srng, /* bytes for local buffer */ #define HAL_REG_WRITE_SRNG_STATS_LEN 100 -void hal_dump_reg_write_srng_stats(struct hal_soc *hal_soc_hdl) +void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl) { struct hal_srng *srng; char buf[HAL_REG_WRITE_SRNG_STATS_LEN]; @@ -633,7 +821,7 @@ void hal_dump_reg_write_srng_stats(struct hal_soc *hal_soc_hdl) hal_fill_reg_write_srng_stats(srng, buf, sizeof(buf))); } -void hal_dump_reg_write_stats(struct hal_soc *hal_soc_hdl) +void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl) { uint32_t *hist; struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl; @@ -650,7 +838,7 @@ void hal_dump_reg_write_stats(struct hal_soc *hal_soc_hdl) hist[REG_WRITE_SCHED_DELAY_SUB_100us], hist[REG_WRITE_SCHED_DELAY_SUB_1000us], hist[REG_WRITE_SCHED_DELAY_SUB_5000us], - hist[REG_WRITE_SCHED_DELAY_GE_5000us]); + hist[REG_WRITE_SCHED_DELAY_GT_5000us]); } int hal_get_reg_write_pending_work(void *hal_soc) @@ -683,7 +871,7 @@ static inline void hal_delayed_reg_write_deinit(struct hal_soc *hal) * copy engines). DP layer will get hal_soc handle using hif_get_hal_handle() * */ -void *hal_attach(void *hif_handle, qdf_device_t qdf_dev) +void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev) { struct hal_soc *hal; int i; @@ -695,7 +883,7 @@ void *hal_attach(void *hif_handle, qdf_device_t qdf_dev) "%s: hal_soc allocation failed", __func__); goto fail0; } - qdf_minidump_log((void *)hal, sizeof(*hal), "hal_soc"); + qdf_minidump_log(hal, sizeof(*hal), "hal_soc"); hal->hif_handle = hif_handle; hal->dev_base_addr = hif_get_dev_ba(hif_handle); hal->qdf_dev = qdf_dev; @@ -731,9 +919,10 @@ void *hal_attach(void *hif_handle, qdf_device_t qdf_dev) qdf_spinlock_create(&hal->register_access_lock); hal->register_window = 0; - hal->target_type = hal_get_target_type(hal); + hal->target_type = hal_get_target_type(hal_soc_to_hal_soc_handle(hal)); hal_target_based_configure(hal); + hal_reg_write_fail_history_init(hal); qdf_atomic_init(&hal->active_work_cnt); @@ -758,15 +947,16 @@ qdf_export_symbol(hal_attach); * @hal_soc: Opaque HAL SOC handle * @mem: pointer to structure to be updated with hal mem info */ -void hal_get_meminfo(void *hal_soc, struct hal_mem_info *mem ) +void hal_get_meminfo(hal_soc_handle_t hal_soc_hdl, struct hal_mem_info *mem) { - struct hal_soc *hal = (struct hal_soc *)hal_soc; + struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl; mem->dev_base_addr = (void *)hal->dev_base_addr; mem->shadow_rdptr_mem_vaddr = (void *)hal->shadow_rdptr_mem_vaddr; mem->shadow_wrptr_mem_vaddr = (void *)hal->shadow_wrptr_mem_vaddr; mem->shadow_rdptr_mem_paddr = (void *)hal->shadow_rdptr_mem_paddr; mem->shadow_wrptr_mem_paddr = (void *)hal->shadow_wrptr_mem_paddr; - hif_read_phy_mem_base(hal->hif_handle, (qdf_dma_addr_t *)&mem->dev_base_paddr); + hif_read_phy_mem_base((void *)hal->hif_handle, + (qdf_dma_addr_t *)&mem->dev_base_paddr); return; } qdf_export_symbol(hal_get_meminfo); @@ -794,13 +984,13 @@ extern void hal_detach(void *hal_soc) qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev, sizeof(*(hal->shadow_wrptr_mem_vaddr)) * HAL_MAX_LMAC_RINGS, hal->shadow_wrptr_mem_vaddr, hal->shadow_wrptr_mem_paddr, 0); + qdf_minidump_remove(hal); qdf_mem_free(hal); return; } qdf_export_symbol(hal_detach); - /** * hal_ce_dst_setup - Initialize CE destination ring registers * @hal_soc: HAL SOC handle @@ -824,6 +1014,19 @@ static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng, reg_val |= srng->u.dst_ring.max_buffer_length & HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK; HAL_REG_WRITE(hal, reg_addr, reg_val); + + if (srng->prefetch_timer) { + reg_addr = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_CONSUMER_PREFETCH_TIMER_ADDR( + ring_config->reg_start[R0_INDEX] + + (ring_num * ring_config->reg_size[R0_INDEX])); + + reg_val = HAL_REG_READ(hal, reg_addr); + reg_val &= ~HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_CONSUMER_PREFETCH_TIMER_RMSK; + reg_val |= srng->prefetch_timer; + HAL_REG_WRITE(hal, reg_addr, reg_val); + reg_val = HAL_REG_READ(hal, reg_addr); + } + } /** @@ -835,10 +1038,12 @@ static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng, * @ix2: pointer to store IX2 reg value * @ix3: pointer to store IX3 reg value */ -void hal_reo_read_write_ctrl_ix(struct hal_soc *hal, bool read, uint32_t *ix0, - uint32_t *ix1, uint32_t *ix2, uint32_t *ix3) +void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read, + uint32_t *ix0, uint32_t *ix1, + uint32_t *ix2, uint32_t *ix3) { uint32_t reg_offset; + struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl; if (read) { if (ix0) { @@ -873,59 +1078,69 @@ void hal_reo_read_write_ctrl_ix(struct hal_soc *hal, bool read, uint32_t *ix0, reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET); - HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix0); + HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset, + *ix0, true); } if (ix1) { reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_1_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET); - HAL_REG_WRITE(hal, reg_offset, *ix1); + HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset, + *ix1, true); } if (ix2) { reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET); - HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix2); + HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset, + *ix2, true); } if (ix3) { reg_offset = HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET); - HAL_REG_WRITE_CONFIRM(hal, reg_offset, *ix3); + HAL_REG_WRITE_CONFIRM_RETRY(hal, reg_offset, + *ix3, true); } } } /** - * hal_srng_dst_set_hp_paddr() - Set physical address to dest ring head pointer + * hal_srng_dst_set_hp_paddr_confirm() - Set physical address to dest ring head + * pointer and confirm that write went through by reading back the value * @srng: sring pointer * @paddr: physical address */ -void hal_srng_dst_set_hp_paddr(struct hal_srng *srng, - uint64_t paddr) +void hal_srng_dst_set_hp_paddr_confirm(struct hal_srng *srng, uint64_t paddr) { - SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, - paddr & 0xffffffff); - SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, - paddr >> 32); + SRNG_DST_REG_WRITE_CONFIRM(srng, HP_ADDR_LSB, paddr & 0xffffffff); + SRNG_DST_REG_WRITE_CONFIRM(srng, HP_ADDR_MSB, paddr >> 32); } /** - * hal_srng_dst_init_hp() - Initilaize destination ring head pointer + * hal_srng_dst_init_hp() - Initialize destination ring head + * pointer + * @hal_soc: hal_soc handle * @srng: sring pointer * @vaddr: virtual address */ -void hal_srng_dst_init_hp(struct hal_srng *srng, +void hal_srng_dst_init_hp(struct hal_soc_handle *hal_soc, + struct hal_srng *srng, uint32_t *vaddr) { + uint32_t reg_offset; + struct hal_soc *hal = (struct hal_soc *)hal_soc; + if (!srng) return; srng->u.dst_ring.hp_addr = vaddr; - SRNG_DST_REG_WRITE_CONFIRM(srng, HP, srng->u.dst_ring.cached_hp); + reg_offset = SRNG_DST_ADDR(srng, HP) - hal->dev_base_addr; + HAL_REG_WRITE_CONFIRM_RETRY( + hal, reg_offset, srng->u.dst_ring.cached_hp, true); if (vaddr) { *srng->u.dst_ring.hp_addr = srng->u.dst_ring.cached_hp; @@ -1016,6 +1231,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, srng->intr_timer_thres_us = ring_params->intr_timer_thres_us; srng->intr_batch_cntr_thres_entries = ring_params->intr_batch_cntr_thres_entries; + srng->prefetch_timer = ring_params->prefetch_timer; srng->hal_soc = hal_soc; for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) { @@ -1052,7 +1268,9 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, HAL_SRNG_LMAC1_ID_START]); srng->flags |= HAL_SRNG_LMAC_RING; } else if (ignore_shadow || (srng->u.src_ring.hp_addr == 0)) { - srng->u.src_ring.hp_addr = SRNG_SRC_ADDR(srng, HP); + srng->u.src_ring.hp_addr = + hal_get_window_address(hal, + SRNG_SRC_ADDR(srng, HP)); if (CHECK_SHADOW_REGISTERS) { QDF_TRACE(QDF_MODULE_ID_TXRX, @@ -1087,7 +1305,9 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, HAL_SRNG_LMAC1_ID_START]); srng->flags |= HAL_SRNG_LMAC_RING; } else if (ignore_shadow || srng->u.dst_ring.tp_addr == 0) { - srng->u.dst_ring.tp_addr = SRNG_DST_ADDR(srng, TP); + srng->u.dst_ring.tp_addr = + hal_get_window_address(hal, + SRNG_DST_ADDR(srng, TP)); if (CHECK_SHADOW_REGISTERS) { QDF_TRACE(QDF_MODULE_ID_TXRX, @@ -1126,9 +1346,9 @@ qdf_export_symbol(hal_srng_setup); * @hal_soc: Opaque HAL SOC handle * @hal_srng: Opaque HAL SRNG pointer */ -void hal_srng_cleanup(void *hal_soc, void *hal_srng) +void hal_srng_cleanup(void *hal_soc, hal_ring_handle_t hal_ring_hdl) { - struct hal_srng *srng = (struct hal_srng *)hal_srng; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; SRNG_LOCK_DESTROY(&srng->lock); srng->initialized = 0; } @@ -1205,10 +1425,11 @@ void hal_srng_dump(struct hal_srng *srng) * @hal_ring: Ring pointer (Source or Destination ring) * @ring_params: SRNG parameters will be returned through this structure */ -extern void hal_get_srng_params(void *hal_soc, void *hal_ring, - struct hal_srng_params *ring_params) +extern void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + struct hal_srng_params *ring_params) { - struct hal_srng *srng = (struct hal_srng *)hal_ring; + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; int i =0; ring_params->ring_id = srng->ring_id; ring_params->ring_dir = srng->ring_dir; @@ -1229,3 +1450,12 @@ extern void hal_get_srng_params(void *hal_soc, void *hal_ring, ring_params->hwreg_base[i] = srng->hwreg_base[i]; } qdf_export_symbol(hal_get_srng_params); + +#ifdef FORCE_WAKE +void hal_set_init_phase(hal_soc_handle_t soc, bool init_phase) +{ + struct hal_soc *hal_soc = (struct hal_soc *)soc; + + hal_soc->init_phase = init_phase; +} +#endif /* FORCE_WAKE */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h index d5c87adc32e72bdeb96a16b11df2d67383a39f90..b5d7020ad58563225b7e7ef97332ab6544c13d0c 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,6 +29,8 @@ #define WBM_RELEASE_RING_5_TX_RATE_STATS_LSB 0 #define WBM_RELEASE_RING_5_TX_RATE_STATS_MASK 0xffffffff +#define HAL_WBM_RELEASE_RING_2_BUFFER_TYPE 0 +#define HAL_WBM_RELEASE_RING_2_DESC_TYPE 1 /*--------------------------------------------------------------------------- Preprocessor definitions and constants @@ -91,6 +93,7 @@ do { \ #define HAL_TX_COMPLETION_DESC_BASE_LEN 12 #define HAL_TX_COMP_RELEASE_SOURCE_TQM 0 +#define HAL_TX_COMP_RELEASE_SOURCE_REO 2 #define HAL_TX_COMP_RELEASE_SOURCE_FW 3 /* Define a place-holder release reason for FW */ @@ -260,6 +263,8 @@ enum hal_tx_encap_type { * remove reason is fw_reason2 * @HAL_TX_TQM_RR_FW_REASON3 : Remove command where fw indicated that * remove reason is fw_reason3 + * @HAL_TX_TQM_RR_REM_CMD_DISABLE_QUEUE : Remove command where fw indicated that + * remove reason is remove disable queue */ enum hal_tx_tqm_release_reason { HAL_TX_TQM_RR_FRAME_ACKED, @@ -270,6 +275,7 @@ enum hal_tx_tqm_release_reason { HAL_TX_TQM_RR_FW_REASON1, HAL_TX_TQM_RR_FW_REASON2, HAL_TX_TQM_RR_FW_REASON3, + HAL_TX_TQM_RR_REM_CMD_DISABLE_QUEUE, }; /* enum - Table IDs for 2 DSCP-TID mapping Tables that TCL H/W supports @@ -426,6 +432,7 @@ static inline void hal_tx_desc_set_to_fw(void *desc, uint8_t to_fw) /** * hal_tx_desc_set_mesh_en - Set mesh_enable flag in Tx descriptor + * @hal_soc_hdl: hal soc handle * @desc: Handle to Tx Descriptor * @en: For raw WiFi frames, this indicates transmission to a mesh STA, * enabling the interpretation of the 'Mesh Control Present' bit @@ -435,10 +442,12 @@ static inline void hal_tx_desc_set_to_fw(void *desc, uint8_t to_fw) * * Return: void */ -static inline void hal_tx_desc_set_mesh_en(void *desc, uint8_t en) +static inline void hal_tx_desc_set_mesh_en(hal_soc_handle_t hal_soc_hdl, + void *desc, uint8_t en) { - HAL_SET_FLD(desc, TCL_DATA_CMD_4, MESH_ENABLE) |= - HAL_TX_SM(TCL_DATA_CMD_4, MESH_ENABLE, en); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + hal_soc->ops->hal_tx_desc_set_mesh_en(desc, en); } /** @@ -790,14 +799,15 @@ static inline uint32_t hal_tx_comp_get_buffer_type(void *hal_desc) * * Return: buffer type */ -static inline uint8_t hal_tx_comp_get_release_reason(void *hal_desc, void *hal) +static inline +uint8_t hal_tx_comp_get_release_reason(void *hal_desc, + hal_soc_handle_t hal_soc_hdl) { - struct hal_soc *hal_soc = hal; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; return hal_soc->ops->hal_tx_comp_get_release_reason(hal_desc); } - /** * hal_tx_comp_desc_sync() - collect hardware descriptor contents * @hal_desc: hardware descriptor pointer @@ -862,19 +872,20 @@ static inline void hal_tx_comp_get_htt_desc(void *hw_desc, uint8_t *htt_desc) /** * hal_tx_init_data_ring() - Initialize all the TCL Descriptors in SRNG - * @hal_soc: Handle to HAL SoC structure + * @hal_soc_hdl: Handle to HAL SoC structure * @hal_srng: Handle to HAL SRNG structure * * Return: none */ -static inline void hal_tx_init_data_ring(void *hal_soc, void *hal_srng) +static inline void hal_tx_init_data_ring(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) { uint8_t *desc_addr; struct hal_srng_params srng_params; uint32_t desc_size; uint32_t num_desc; - hal_get_srng_params(hal_soc, hal_srng, &srng_params); + hal_get_srng_params(hal_soc_hdl, hal_ring_hdl, &srng_params); desc_addr = (uint8_t *)srng_params.ring_base_vaddr; desc_size = sizeof(struct tcl_data_cmd); @@ -896,9 +907,12 @@ static inline void hal_tx_init_data_ring(void *hal_soc, void *hal_srng) * * Return: void */ -static inline void hal_tx_desc_set_dscp_tid_table_id(struct hal_soc *hal_soc, - void *desc, uint8_t id) +static inline +void hal_tx_desc_set_dscp_tid_table_id(hal_soc_handle_t hal_soc_hdl, + void *desc, uint8_t id) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_desc_set_dscp_tid_table_id(desc, id); } @@ -911,9 +925,11 @@ static inline void hal_tx_desc_set_dscp_tid_table_id(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_set_dscp_tid_map(struct hal_soc *hal_soc, +static inline void hal_tx_set_dscp_tid_map(hal_soc_handle_t hal_soc_hdl, uint8_t *map, uint8_t id) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_set_dscp_tid_map(hal_soc, map, id); } @@ -927,9 +943,12 @@ static inline void hal_tx_set_dscp_tid_map(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_update_dscp_tid(struct hal_soc *hal_soc, uint8_t tid, - uint8_t id, uint8_t dscp) +static inline +void hal_tx_update_dscp_tid(hal_soc_handle_t hal_soc_hdl, uint8_t tid, + uint8_t id, uint8_t dscp) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_update_dscp_tid(hal_soc, tid, id, dscp); } @@ -944,9 +963,11 @@ static inline void hal_tx_update_dscp_tid(struct hal_soc *hal_soc, uint8_t tid, * * Return: void */ -static inline void hal_tx_desc_set_lmac_id(struct hal_soc *hal_soc, +static inline void hal_tx_desc_set_lmac_id(hal_soc_handle_t hal_soc_hdl, void *desc, uint8_t lmac_id) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_desc_set_lmac_id(desc, lmac_id); } @@ -960,9 +981,11 @@ static inline void hal_tx_desc_set_lmac_id(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_desc_set_search_type(struct hal_soc *hal_soc, +static inline void hal_tx_desc_set_search_type(hal_soc_handle_t hal_soc_hdl, void *desc, uint8_t search_type) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_desc_set_search_type(desc, search_type); } @@ -975,13 +998,37 @@ static inline void hal_tx_desc_set_search_type(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_desc_set_search_index(struct hal_soc *hal_soc, +static inline void hal_tx_desc_set_search_index(hal_soc_handle_t hal_soc_hdl, void *desc, uint32_t search_index) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_desc_set_search_index(desc, search_index); } +/** + * hal_tx_desc_set_cache_set_num - Set the cache-set-num value + * @desc: Handle to Tx Descriptor + * @cache_num: Cache set number that should be used to cache the index + * based search results, for address and flow search. + * This value should be equal to LSB four bits of the hash value + * of match data, in case of search index points to an entry + * which may be used in content based search also. The value can + * be anything when the entry pointed by search index will not be + * used for content based search. + * + * Return: void + */ +static inline void hal_tx_desc_set_cache_set_num(hal_soc_handle_t hal_soc_hdl, + void *desc, + uint8_t cache_num) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + hal_soc->ops->hal_tx_desc_set_cache_set_num(desc, cache_num); +} + /** * hal_tx_comp_get_status() - TQM Release reason * @hal_desc: completion ring Tx status @@ -991,11 +1038,12 @@ static inline void hal_tx_desc_set_search_index(struct hal_soc *hal_soc, * * Return: none */ -static inline void hal_tx_comp_get_status(void *desc, void *ts, void *hal) +static inline void hal_tx_comp_get_status(void *desc, void *ts, + hal_soc_handle_t hal_soc_hdl) { - struct hal_soc *hal_soc = hal; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - hal_soc->ops->hal_tx_comp_get_status(desc, ts, hal); + hal_soc->ops->hal_tx_comp_get_status(desc, ts, hal_soc); } @@ -1010,10 +1058,12 @@ static inline void hal_tx_comp_get_status(void *desc, void *ts, void *hal) * * Return: void */ -static inline void hal_tx_desc_set_buf_addr(void *desc, dma_addr_t paddr, - uint8_t pool_id, uint32_t desc_id, uint8_t type, void *hal) +static inline +void hal_tx_desc_set_buf_addr(void *desc, dma_addr_t paddr, + uint8_t pool_id, uint32_t desc_id, + uint8_t type, hal_soc_handle_t hal_soc_hdl) { - struct hal_soc *hal_soc = hal; + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; hal_soc->ops->hal_tx_desc_set_buf_addr(desc, paddr, pool_id, desc_id, type); @@ -1028,9 +1078,11 @@ static inline void hal_tx_desc_set_buf_addr(void *desc, dma_addr_t paddr, * * Return: void */ -static inline void hal_tx_set_pcp_tid_map_default(struct hal_soc *hal_soc, +static inline void hal_tx_set_pcp_tid_map_default(hal_soc_handle_t hal_soc_hdl, uint8_t *map) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_set_pcp_tid_map(hal_soc, map); } @@ -1043,9 +1095,11 @@ static inline void hal_tx_set_pcp_tid_map_default(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_update_pcp_tid_map(struct hal_soc *hal_soc, +static inline void hal_tx_update_pcp_tid_map(hal_soc_handle_t hal_soc_hdl, uint8_t pcp, uint8_t tid) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_update_pcp_tid_map(hal_soc, tid, tid); } @@ -1057,8 +1111,11 @@ static inline void hal_tx_update_pcp_tid_map(struct hal_soc *hal_soc, * * Return: void */ -static inline void hal_tx_set_tidmap_prty(struct hal_soc *hal_soc, uint8_t val) +static inline +void hal_tx_set_tidmap_prty(hal_soc_handle_t hal_soc_hdl, uint8_t val) { + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + hal_soc->ops->hal_tx_set_tidmap_prty(hal_soc, val); } @@ -1070,13 +1127,12 @@ static inline void hal_tx_set_tidmap_prty(struct hal_soc *hal_soc, uint8_t val) * * Return: buffer type */ -static inline uint8_t hal_get_wbm_internal_error(void *hal_desc) +static inline +uint8_t hal_get_wbm_internal_error(hal_soc_handle_t hal_soc_hdl, void *hal_desc) { - uint32_t comp_desc = - *(uint32_t *)(((uint8_t *)hal_desc) + - WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_OFFSET); + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; - return (comp_desc & WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_MASK) >> - WBM_RELEASE_RING_2_WBM_INTERNAL_ERROR_LSB; + return hal_soc->ops->hal_get_wbm_internal_error(hal_desc); } + #endif /* HAL_TX_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h index b31497cb47e7fc27b7f2bcf60f84add8a4781850..f78d1ac862df57618f199f2f49dffce6a6f9c09c 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h @@ -29,15 +29,17 @@ * @num_entries: Total entries of all scatter bufs * */ -static void hal_setup_link_idle_list_generic(void *hal_soc, - qdf_dma_addr_t scatter_bufs_base_paddr[], - void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs, - uint32_t scatter_buf_size, uint32_t last_buf_end_offset, - uint32_t num_entries) +static void +hal_setup_link_idle_list_generic(struct hal_soc *soc, + qdf_dma_addr_t scatter_bufs_base_paddr[], + void *scatter_bufs_base_vaddr[], + uint32_t num_scatter_bufs, + uint32_t scatter_buf_size, + uint32_t last_buf_end_offset, + uint32_t num_entries) { int i; uint32_t *prev_buf_link_ptr = NULL; - struct hal_soc *soc = (struct hal_soc *)hal_soc; uint32_t reg_scatter_buf_size, reg_tot_scatter_buf_size; uint32_t val; diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018.c deleted file mode 100644 index e4fd12348637ab2fb43473fde371e0b41131284a..0000000000000000000000000000000000000000 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. - * - * 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. - */ -#include "hal_hw_headers.h" -#include "hal_internal.h" -#include "hal_api.h" -#include "target_type.h" -#include "wcss_version.h" -#include "qdf_module.h" - -#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_OFFSET \ - RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_OFFSET -#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_MASK \ - RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_MASK -#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_LSB \ - RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_LSB -#define UNIFIED_PHYRX_HT_SIG_0_HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS_OFFSET \ - PHYRX_HT_SIG_0_PHYRX_HT_SIG_INFO_DETAILS_MCS_OFFSET -#define UNIFIED_PHYRX_L_SIG_B_0_L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS_OFFSET \ - PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET -#define UNIFIED_PHYRX_L_SIG_A_0_L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS_OFFSET \ - PHYRX_L_SIG_A_0_PHYRX_L_SIG_A_INFO_DETAILS_RATE_OFFSET -#define UNIFIED_PHYRX_VHT_SIG_A_0_VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS_OFFSET \ - PHYRX_VHT_SIG_A_0_PHYRX_VHT_SIG_A_INFO_DETAILS_BANDWIDTH_OFFSET -#define UNIFIED_PHYRX_HE_SIG_A_SU_0_HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS_OFFSET \ - PHYRX_HE_SIG_A_SU_0_PHYRX_HE_SIG_A_SU_INFO_DETAILS_FORMAT_INDICATION_OFFSET -#define UNIFIED_PHYRX_HE_SIG_A_MU_DL_0_HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_OFFSET \ - PHYRX_HE_SIG_A_MU_DL_0_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_DL_UL_FLAG_OFFSET -#define UNIFIED_PHYRX_HE_SIG_B1_MU_0_HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_OFFSET \ - PHYRX_HE_SIG_B1_MU_0_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_RU_ALLOCATION_OFFSET -#define UNIFIED_PHYRX_HE_SIG_B2_MU_0_HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_OFFSET \ - PHYRX_HE_SIG_B2_MU_0_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_STA_ID_OFFSET -#define UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0_HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_OFFSET \ - PHYRX_HE_SIG_B2_OFDMA_0_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_STA_ID_OFFSET -#define UNIFIED_PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET \ - PHYRX_RSSI_LEGACY_3_PRE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET -#define UNIFIED_PHYRX_RSSI_LEGACY_19_RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS_OFFSET \ - PHYRX_RSSI_LEGACY_19_PREAMBLE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET -#define UNIFIED_RX_MPDU_START_0_RX_MPDU_INFO_RX_MPDU_INFO_DETAILS_OFFSET \ - RX_MPDU_START_0_RX_MPDU_INFO_DETAILS_RXPCU_MPDU_FILTER_IN_CATEGORY_OFFSET -#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ - RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET -#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ - RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET -#define UNIFIED_RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ - RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET -#define UNIFIED_REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ - REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET -#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER \ - STATUS_HEADER_REO_STATUS_NUMBER -#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC \ - STATUS_HEADER_TIMESTAMP -#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ - RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET -#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ - RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET -#define UNIFIED_TCL_DATA_CMD_0_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ - TCL_DATA_CMD_0_BUF_ADDR_INFO_BUFFER_ADDR_31_0_OFFSET -#define UNIFIED_TCL_DATA_CMD_1_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ - TCL_DATA_CMD_1_BUF_ADDR_INFO_BUFFER_ADDR_39_32_OFFSET -#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET \ - TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET -#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB \ - BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB -#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK \ - BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK -#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB \ - BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB -#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK \ - BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK -#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB \ - BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB -#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK \ - BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK -#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB \ - BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB -#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK \ - BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK -#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB \ - TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB -#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK \ - TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK -#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_MASK \ - WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_MASK -#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_OFFSET \ - WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_OFFSET -#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \ - WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_LSB -#include "hal_6018_tx.h" -#include "hal_6018_rx.h" -#include -#include - -struct hal_hw_txrx_ops qca6018_hal_hw_txrx_ops = { - /* init and setup */ - hal_srng_dst_hw_init_generic, - hal_srng_src_hw_init_generic, - hal_get_hw_hptp_generic, - hal_reo_setup_generic, - hal_setup_link_idle_list_generic, - NULL, - - /* tx */ - hal_tx_desc_set_dscp_tid_table_id_6018, - hal_tx_set_dscp_tid_map_6018, - hal_tx_update_dscp_tid_6018, - hal_tx_desc_set_lmac_id_6018, - hal_tx_desc_set_buf_addr_generic, - hal_tx_desc_set_search_type_generic, - hal_tx_desc_set_search_index_generic, - hal_tx_comp_get_status_generic, - hal_tx_comp_get_release_reason_generic, - - /* rx */ - hal_rx_msdu_start_nss_get_6018, - hal_rx_mon_hw_desc_get_mpdu_status_6018, - hal_rx_get_tlv_6018, - hal_rx_proc_phyrx_other_receive_info_tlv_6018, - hal_rx_dump_msdu_start_tlv_6018, - hal_rx_dump_msdu_end_tlv_6018, - hal_get_link_desc_size_6018, - hal_rx_mpdu_start_tid_get_6018, - hal_rx_msdu_start_reception_type_get_6018, - hal_rx_msdu_end_da_idx_get_6018, - hal_rx_msdu_desc_info_get_ptr_generic, - hal_rx_link_desc_msdu0_ptr_generic, - hal_reo_status_get_header_generic, - hal_rx_status_get_tlv_info_generic, - hal_rx_wbm_err_info_get_generic, - hal_rx_dump_mpdu_start_tlv_generic, - - hal_tx_set_pcp_tid_map_generic, - hal_tx_update_pcp_tid_generic, - hal_tx_update_tidmap_prty_generic, -}; - -struct hal_hw_srng_config hw_srng_table_6018[] = { - /* TODO: max_rings can populated by querying HW capabilities */ - { /* REO_DST */ - .start_ring_id = HAL_SRNG_REO2SW1, - .max_rings = 4, - .entry_size = sizeof(struct reo_destination_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO2SW1_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - .reg_size = { - HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - - HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), - HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - - HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), - }, - .max_size = - HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_EXCEPTION */ - /* Designating REO2TCL ring as exception ring. This ring is - * similar to other REO2SW rings though it is named as REO2TCL. - * Any of theREO2SW rings can be used as exception ring. - */ - .start_ring_id = HAL_SRNG_REO2TCL, - .max_rings = 1, - .entry_size = sizeof(struct reo_destination_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO2TCL_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_REINJECT */ - .start_ring_id = HAL_SRNG_SW2REO, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_SW2REO_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_CMD */ - .start_ring_id = HAL_SRNG_REO_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct reo_get_queue_stats)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO_CMD_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_STATUS */ - .start_ring_id = HAL_SRNG_REO_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct reo_get_queue_stats_status)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_DATA */ - .start_ring_id = HAL_SRNG_SW2TCL1, - .max_rings = 3, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_data_cmd)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - .reg_size = { - HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - - HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), - HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - - HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), - }, - .max_size = - HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_CMD */ - .start_ring_id = HAL_SRNG_SW2TCL_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_gse_cmd)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_SW2TCL_CMD_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_STATUS */ - .start_ring_id = HAL_SRNG_TCL_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_status_ring)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_SRC */ - .start_ring_id = HAL_SRNG_CE_0_SRC, - .max_rings = 12, - .entry_size = sizeof(struct ce_src_desc) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), - }, - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, - }, - .max_size = - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_DST */ - .start_ring_id = HAL_SRNG_CE_0_DST, - .max_rings = 12, - .entry_size = 8 >> 2, - /*TODO: entry_size above should actually be - * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition - * of struct ce_dst_desc in HW header files - */ - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - }, - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - }, - .max_size = - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_DST_STATUS */ - .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, - .max_rings = 12, - .entry_size = sizeof(struct ce_stat_desc) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - }, - /* TODO: check destination status ring registers */ - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - }, - .max_size = - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* WBM_IDLE_LINK */ - .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, - .max_rings = 1, - .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* SW2WBM_RELEASE */ - .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct wbm_release_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported - */ - .reg_size = {}, - .max_size = - HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* WBM2SW_RELEASE */ - .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, - .max_rings = 4, - .entry_size = sizeof(struct wbm_release_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - .reg_size = { - HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - - HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - .max_size = - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* RXDMA_BUF */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, -#ifdef IPA_OFFLOAD - .max_rings = 3, -#else - .max_rings = 2, -#endif - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_DST */ - .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_DST_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_BUF */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_STATUS */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_DST */ - .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_DST_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_DESC */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* DIR_BUF_RX_DMA_SRC */ - .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, - .max_rings = 1, - .entry_size = 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, -#ifdef WLAN_FEATURE_CIF_CFR - { /* WIFI_POS_SRC */ - .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, - .max_rings = 1, - .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, -#endif -}; - -int32_t hal_hw_reg_offset_qca6018[] = { - /* dst */ - REG_OFFSET(DST, HP), - REG_OFFSET(DST, TP), - REG_OFFSET(DST, ID), - REG_OFFSET(DST, MISC), - REG_OFFSET(DST, HP_ADDR_LSB), - REG_OFFSET(DST, HP_ADDR_MSB), - REG_OFFSET(DST, MSI1_BASE_LSB), - REG_OFFSET(DST, MSI1_BASE_MSB), - REG_OFFSET(DST, MSI1_DATA), - REG_OFFSET(DST, BASE_LSB), - REG_OFFSET(DST, BASE_MSB), - REG_OFFSET(DST, PRODUCER_INT_SETUP), - /* src */ - REG_OFFSET(SRC, HP), - REG_OFFSET(SRC, TP), - REG_OFFSET(SRC, ID), - REG_OFFSET(SRC, MISC), - REG_OFFSET(SRC, TP_ADDR_LSB), - REG_OFFSET(SRC, TP_ADDR_MSB), - REG_OFFSET(SRC, MSI1_BASE_LSB), - REG_OFFSET(SRC, MSI1_BASE_MSB), - REG_OFFSET(SRC, MSI1_DATA), - REG_OFFSET(SRC, BASE_LSB), - REG_OFFSET(SRC, BASE_MSB), - REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), - REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), -}; - -/** - * hal_qca6018_attach() - Attach 6018 target specific hal_soc ops, - * offset and srng table - */ -void hal_qca6018_attach(struct hal_soc *hal_soc) -{ - hal_soc->hw_srng_table = hw_srng_table_6018; - hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca6018; - hal_soc->ops = &qca6018_hal_hw_txrx_ops; -} diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_rx.h deleted file mode 100644 index 30d827ebfffb8c16c7a6e18bda03f5079cc80eae..0000000000000000000000000000000000000000 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_rx.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. - * - * 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. - */ -#include "hal_hw_headers.h" -#include "hal_internal.h" -#include "cdp_txrx_mon_struct.h" -#include "qdf_trace.h" -#include "hal_rx.h" -#include "hal_tx.h" -#include "dp_types.h" -#include "hal_api_mon.h" - -#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ - RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ - RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ - RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) -/* - * hal_rx_msdu_start_nss_get_6018(): API to get the NSS - * Interval from rx_msdu_start - * - * @buf: pointer to the start of RX PKT TLV header - * Return: uint32_t(nss) - */ -static uint32_t hal_rx_msdu_start_nss_get_6018(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - uint8_t mimo_ss_bitmap; - - mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); - - return qdf_get_hweight8(mimo_ss_bitmap); -} - -/** - * hal_rx_mon_hw_desc_get_mpdu_status_6018(): Retrieve MPDU status - * - * @ hw_desc_addr: Start address of Rx HW TLVs - * @ rs: Status for monitor mode - * - * Return: void - */ -static void hal_rx_mon_hw_desc_get_mpdu_status_6018(void *hw_desc_addr, - struct mon_rx_status *rs) -{ - struct rx_msdu_start *rx_msdu_start; - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; - uint32_t reg_value; - const uint32_t sgi_hw_to_cdp[] = { - CDP_SGI_0_8_US, - CDP_SGI_0_4_US, - CDP_SGI_1_6_US, - CDP_SGI_3_2_US, - }; - - rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; - - HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); - - rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, - RX_MSDU_START_5, USER_RSSI); - rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); - rs->sgi = sgi_hw_to_cdp[reg_value]; - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); - switch (reg_value) { - case HAL_RX_PKT_TYPE_11N: - rs->ht_flags = 1; - break; - case HAL_RX_PKT_TYPE_11AC: - rs->vht_flags = 1; - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, - RECEIVE_BANDWIDTH); - rs->vht_flag_values2 = reg_value; - break; - case HAL_RX_PKT_TYPE_11AX: - rs->he_flags = 1; - break; - default: - break; - } - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); - rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; - /* TODO: rs->beamformed should be set for SU beamforming also */ -} - -#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) -static uint32_t hal_get_link_desc_size_6018(void) -{ - return LINK_DESC_SIZE; -} - -/* - * hal_rx_get_tlv_6018(): API to get the tlv - * - * @rx_tlv: TLV data extracted from the rx packet - * Return: uint8_t - */ -static uint8_t hal_rx_get_tlv_6018(void *rx_tlv) -{ - return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); -} - -/** - * hal_rx_proc_phyrx_other_receive_info_tlv_6018() - * -process other receive info TLV - * @rx_tlv_hdr: pointer to TLV header - * @ppdu_info: pointer to ppdu_info - * - * Return: None - */ -static -void hal_rx_proc_phyrx_other_receive_info_tlv_6018(void *rx_tlv_hdr, - void *ppdu_info) -{ -} - - -/** - * hal_rx_dump_msdu_start_tlv_6018() : dump RX msdu_start TLV in structured - * human readable format. - * @ msdu_start: pointer the msdu_start TLV in pkt. - * @ dbg_level: log level. - * - * Return: void - */ -static void hal_rx_dump_msdu_start_tlv_6018(void *msdustart, - uint8_t dbg_level) -{ - struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; - - QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, - "rx_msdu_start tlv - " - "rxpcu_mpdu_filter_in_category: %d " - "sw_frame_group_id: %d " - "phy_ppdu_id: %d " - "msdu_length: %d " - "ipsec_esp: %d " - "l3_offset: %d " - "ipsec_ah: %d " - "l4_offset: %d " - "msdu_number: %d " - "decap_format: %d " - "ipv4_proto: %d " - "ipv6_proto: %d " - "tcp_proto: %d " - "udp_proto: %d " - "ip_frag: %d " - "tcp_only_ack: %d " - "da_is_bcast_mcast: %d " - "ip4_protocol_ip6_next_header: %d " - "toeplitz_hash_2_or_4: %d " - "flow_id_toeplitz: %d " - "user_rssi: %d " - "pkt_type: %d " - "stbc: %d " - "sgi: %d " - "rate_mcs: %d " - "receive_bandwidth: %d " - "reception_type: %d " - "ppdu_start_timestamp: %d " - "sw_phy_meta_data: %d ", - msdu_start->rxpcu_mpdu_filter_in_category, - msdu_start->sw_frame_group_id, - msdu_start->phy_ppdu_id, - msdu_start->msdu_length, - msdu_start->ipsec_esp, - msdu_start->l3_offset, - msdu_start->ipsec_ah, - msdu_start->l4_offset, - msdu_start->msdu_number, - msdu_start->decap_format, - msdu_start->ipv4_proto, - msdu_start->ipv6_proto, - msdu_start->tcp_proto, - msdu_start->udp_proto, - msdu_start->ip_frag, - msdu_start->tcp_only_ack, - msdu_start->da_is_bcast_mcast, - msdu_start->ip4_protocol_ip6_next_header, - msdu_start->toeplitz_hash_2_or_4, - msdu_start->flow_id_toeplitz, - msdu_start->user_rssi, - msdu_start->pkt_type, - msdu_start->stbc, - msdu_start->sgi, - msdu_start->rate_mcs, - msdu_start->receive_bandwidth, - msdu_start->reception_type, - msdu_start->ppdu_start_timestamp, - msdu_start->sw_phy_meta_data); -} - -/** - * hal_rx_dump_msdu_end_tlv_6018: dump RX msdu_end TLV in structured - * human readable format. - * @ msdu_end: pointer the msdu_end TLV in pkt. - * @ dbg_level: log level. - * - * Return: void - */ -static void hal_rx_dump_msdu_end_tlv_6018(void *msduend, - uint8_t dbg_level) -{ - struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; - - QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, - "rx_msdu_end tlv - " - "rxpcu_mpdu_filter_in_category: %d " - "sw_frame_group_id: %d " - "phy_ppdu_id: %d " - "ip_hdr_chksum: %d " - "tcp_udp_chksum: %d " - "key_id_octet: %d " - "cce_super_rule: %d " - "cce_classify_not_done_truncat: %d " - "cce_classify_not_done_cce_dis: %d " - "ext_wapi_pn_63_48: %d " - "ext_wapi_pn_95_64: %d " - "ext_wapi_pn_127_96: %d " - "reported_mpdu_length: %d " - "first_msdu: %d " - "last_msdu: %d " - "sa_idx_timeout: %d " - "da_idx_timeout: %d " - "msdu_limit_error: %d " - "flow_idx_timeout: %d " - "flow_idx_invalid: %d " - "wifi_parser_error: %d " - "amsdu_parser_error: %d " - "sa_is_valid: %d " - "da_is_valid: %d " - "da_is_mcbc: %d " - "l3_header_padding: %d " - "ipv6_options_crc: %d " - "tcp_seq_number: %d " - "tcp_ack_number: %d " - "tcp_flag: %d " - "lro_eligible: %d " - "window_size: %d " - "da_offset: %d " - "sa_offset: %d " - "da_offset_valid: %d " - "sa_offset_valid: %d " - "rule_indication_31_0: %d " - "rule_indication_63_32: %d " - "sa_idx: %d " - "msdu_drop: %d " - "reo_destination_indication: %d " - "flow_idx: %d " - "fse_metadata: %d " - "cce_metadata: %d " - "sa_sw_peer_id: %d ", - msdu_end->rxpcu_mpdu_filter_in_category, - msdu_end->sw_frame_group_id, - msdu_end->phy_ppdu_id, - msdu_end->ip_hdr_chksum, - msdu_end->tcp_udp_chksum, - msdu_end->key_id_octet, - msdu_end->cce_super_rule, - msdu_end->cce_classify_not_done_truncate, - msdu_end->cce_classify_not_done_cce_dis, - msdu_end->ext_wapi_pn_63_48, - msdu_end->ext_wapi_pn_95_64, - msdu_end->ext_wapi_pn_127_96, - msdu_end->reported_mpdu_length, - msdu_end->first_msdu, - msdu_end->last_msdu, - msdu_end->sa_idx_timeout, - msdu_end->da_idx_timeout, - msdu_end->msdu_limit_error, - msdu_end->flow_idx_timeout, - msdu_end->flow_idx_invalid, - msdu_end->wifi_parser_error, - msdu_end->amsdu_parser_error, - msdu_end->sa_is_valid, - msdu_end->da_is_valid, - msdu_end->da_is_mcbc, - msdu_end->l3_header_padding, - msdu_end->ipv6_options_crc, - msdu_end->tcp_seq_number, - msdu_end->tcp_ack_number, - msdu_end->tcp_flag, - msdu_end->lro_eligible, - msdu_end->window_size, - msdu_end->da_offset, - msdu_end->sa_offset, - msdu_end->da_offset_valid, - msdu_end->sa_offset_valid, - msdu_end->rule_indication_31_0, - msdu_end->rule_indication_63_32, - msdu_end->sa_idx, - msdu_end->msdu_drop, - msdu_end->reo_destination_indication, - msdu_end->flow_idx, - msdu_end->fse_metadata, - msdu_end->cce_metadata, - msdu_end->sa_sw_peer_id); -} - -/* - * Get tid from RX_MPDU_START - */ -#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ - RX_MPDU_INFO_3_TID_OFFSET)), \ - RX_MPDU_INFO_3_TID_MASK, \ - RX_MPDU_INFO_3_TID_LSB)) - -static uint32_t hal_rx_mpdu_start_tid_get_6018(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - uint32_t tid; - - tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); - - return tid; -} - -#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ - RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ - RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ - RX_MSDU_START_5_RECEPTION_TYPE_LSB)) - -/* - * hal_rx_msdu_start_reception_type_get(): API to get the reception type - * Interval from rx_msdu_start - * - * @buf: pointer to the start of RX PKT TLV header - * Return: uint32_t(reception_type) - */ -static uint32_t hal_rx_msdu_start_reception_type_get_6018(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - uint32_t reception_type; - - reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); - - return reception_type; -} - -/* RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_OFFSET */ -#define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ - RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ - RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_MASK, \ - RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_LSB)) - /** - * hal_rx_msdu_end_da_idx_get_6018: API to get da_idx - * from rx_msdu_end TLV - * - * @ buf: pointer to the start of RX PKT TLV headers - * Return: da index - */ -static uint16_t hal_rx_msdu_end_da_idx_get_6018(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - uint16_t da_idx; - - da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); - - return da_idx; -} - diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290.c index 7612caf8045f8f7c282eda9337c3edd3ea6cf529..dc22c00a99e093bd5b9cf1a8a2dce3dd30af1356 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -110,6 +110,886 @@ #include #include +/** + * hal_rx_get_rx_fragment_number_6290(): Function to retrieve rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get: API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static inline uint8_t +hal_rx_msdu_end_da_is_mcbc_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_6290(): API to get_6290 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_6290(): API to get_6290 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static +uint16_t hal_rx_msdu_end_sa_idx_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_6290() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_6290(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_6290(): API to get_6290 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_6290: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * hal_rx_print_pn_6290: Prints the PN of rx packet. + * @buf: rx_tlv_hdr of the received packet + * + * Return: void + */ +static void hal_rx_print_pn_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_6290: API to get first msdu status + * from rx_msdu_end TLV + * + * @buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t +hal_rx_msdu_end_first_msdu_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_6290: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_6290: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_6290(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_6290: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id: + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/* + * hal_rx_mpdu_get_to_ds_6290(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ + +static uint32_t hal_rx_mpdu_get_to_ds_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_6290(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_6290(): Retrieves mpdu frame + * control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_6290(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_6290(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_6290(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_6290(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_6290(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_6290(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_6290(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_6290(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_6290(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_6290: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_6290: get tid based on qos control valid. + * @hal_soc_hdl: hal soc handle + * @ buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_6290(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_6290(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_6290(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_6290(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_6290 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_6290(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get_6290(): + * Retrieve qos control valid bit from the tlv. + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ +static inline uint32_t +hal_rx_mpdu_start_mpdu_qos_control_valid_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get_6290(): API to get the + * sa_sw_peer_id from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: sa_sw_peer_id index + */ +static inline uint32_t +hal_rx_msdu_end_sa_sw_peer_id_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +/** + * hal_tx_desc_set_mesh_en_6290 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_6290(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_4, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_6290(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_6290(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_6290(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_6290(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_6290(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_6290(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_6290(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_6290(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_6290(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_6290(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static +void hal_reo_config_6290(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_6290() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_6290(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_6290 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_6290(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_6290: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_6290: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_6290: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_6290: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_6290: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_6290: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_6290(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_6290() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_6290(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_6290(): Function to retrieve rx sequence number + * @nbuf: Network buffer + * + * Return: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_6290(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6290(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { /* init and setup */ hal_srng_dst_hw_init_generic, @@ -117,6 +997,7 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_6290, NULL, /* tx */ @@ -127,9 +1008,11 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { hal_tx_desc_set_buf_addr_generic, hal_tx_desc_set_search_type_generic, hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, hal_tx_comp_get_status_generic, hal_tx_comp_get_release_reason_generic, - + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_6290, /* rx */ hal_rx_msdu_start_nss_get_6290, hal_rx_mon_hw_desc_get_mpdu_status_6290, @@ -141,9 +1024,9 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { hal_rx_mpdu_start_tid_get_6290, hal_rx_msdu_start_reception_type_get_6290, hal_rx_msdu_end_da_idx_get_6290, - hal_rx_msdu_desc_info_get_ptr_generic, - hal_rx_link_desc_msdu0_ptr_generic, - hal_reo_status_get_header_generic, + hal_rx_msdu_desc_info_get_ptr_6290, + hal_rx_link_desc_msdu0_ptr_6290, + hal_reo_status_get_header_6290, hal_rx_status_get_tlv_info_generic, hal_rx_wbm_err_info_get_generic, hal_rx_dump_mpdu_start_tlv_generic, @@ -151,6 +1034,60 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { hal_tx_set_pcp_tid_map_generic, hal_tx_update_pcp_tid_generic, hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_6290, + hal_rx_msdu_end_da_is_mcbc_get_6290, + hal_rx_msdu_end_sa_is_valid_get_6290, + hal_rx_msdu_end_sa_idx_get_6290, + hal_rx_desc_is_first_msdu_6290, + hal_rx_msdu_end_l3_hdr_padding_get_6290, + hal_rx_encryption_info_valid_6290, + hal_rx_print_pn_6290, + hal_rx_msdu_end_first_msdu_get_6290, + hal_rx_msdu_end_da_is_valid_get_6290, + hal_rx_msdu_end_last_msdu_get_6290, + hal_rx_get_mpdu_mac_ad4_valid_6290, + hal_rx_mpdu_start_sw_peer_id_get_6290, + hal_rx_mpdu_get_to_ds_6290, + hal_rx_mpdu_get_fr_ds_6290, + hal_rx_get_mpdu_frame_control_valid_6290, + hal_rx_mpdu_get_addr1_6290, + hal_rx_mpdu_get_addr2_6290, + hal_rx_mpdu_get_addr3_6290, + hal_rx_mpdu_get_addr4_6290, + hal_rx_get_mpdu_sequence_control_valid_6290, + hal_rx_is_unicast_6290, + hal_rx_tid_get_6290, + hal_rx_hw_desc_get_ppduid_get_6290, + hal_rx_mpdu_start_mpdu_qos_control_valid_get_6290, + hal_rx_msdu_end_sa_sw_peer_id_get_6290, + hal_rx_msdu0_buffer_addr_lsb_6290, + hal_rx_msdu_desc_info_ptr_get_6290, + hal_ent_mpdu_desc_info_6290, + hal_dst_mpdu_desc_info_6290, + hal_rx_get_fc_valid_6290, + hal_rx_get_to_ds_flag_6290, + hal_rx_get_mac_addr2_valid_6290, + hal_rx_get_filter_category_6290, + hal_rx_get_ppdu_id_6290, + hal_reo_config_6290, + hal_rx_msdu_flow_idx_get_6290, + hal_rx_msdu_flow_idx_invalid_6290, + hal_rx_msdu_flow_idx_timeout_6290, + hal_rx_msdu_fse_metadata_get_6290, + hal_rx_msdu_cce_metadata_get_6290, + hal_rx_msdu_get_flow_params_6290, + hal_rx_tlv_get_tcp_chksum_6290, + hal_rx_get_rx_sequence_6290, + NULL, + NULL, + /* rx - msdu end fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, }; struct hal_hw_srng_config hw_srng_table_6290[] = { diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_rx.h index f4e387f747fb88f1ea7588b833dc0ee79654b0ca..9417cf728f59706fb1ddd4c4e7e25abc64e30bbc 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +35,309 @@ #include "hal_api_mon.h" #include "phyrx_other_receive_info_ru_details.h" +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_5_DA_IS_MCBC_MASK, \ + RX_MSDU_END_5_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_SA_IS_VALID_MASK, \ + RX_MSDU_END_5_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_SA_IDX_OFFSET)), \ + RX_MSDU_END_13_SA_IDX_MASK, \ + RX_MSDU_END_13_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_5_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_5_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_4_PN_31_0_MASK, \ + RX_MPDU_INFO_4_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_5_PN_63_32_MASK, \ + RX_MPDU_INFO_5_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_6_PN_95_64_MASK, \ + RX_MPDU_INFO_6_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_7_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_7_PN_127_96_MASK, \ + RX_MPDU_INFO_7_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_5_FIRST_MSDU_MASK, \ + RX_MSDU_END_5_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_DA_IS_VALID_MASK, \ + RX_MSDU_END_5_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_5_LAST_MSDU_MASK, \ + RX_MSDU_END_5_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_1_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_1_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_TO_DS_OFFSET)), \ + RX_MPDU_INFO_2_TO_DS_MASK, \ + RX_MPDU_INFO_2_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FR_DS_OFFSET)), \ + RX_MPDU_INFO_2_FR_DS_MASK, \ + RX_MPDU_INFO_2_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_16_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_16_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + (reg_val) &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK);\ + (reg_val) |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring) | \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ +UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_14_FLOW_IDX_MASK, \ + RX_MSDU_END_14_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_15_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_15_FSE_METADATA_MASK, \ + RX_MSDU_END_15_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_16_CCE_METADATA_MASK, \ + RX_MSDU_END_16_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB)) + #if defined(QCA_WIFI_QCA6290_11AX) #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_tx.h index 09b022fb75d96441e40b6190a3d4a77536fbed7e..2d4cc75acc8d1aa8081d3a0f5f2bb072bf5b3443 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -46,7 +46,6 @@ static void hal_tx_desc_set_dscp_tid_table_id_6290(void *desc, DSCP_TID_TABLE_NUM, id); } #else -#ifdef CONFIG_MCL static void hal_tx_desc_set_dscp_tid_table_id_6290(void *desc, uint8_t id) { @@ -56,7 +55,6 @@ static void hal_tx_desc_set_dscp_tid_table_id_6290(void *desc, DSCP_TO_TID_PRIORITY_TABLE_ID, id); } #endif -#endif #define DSCP_TID_TABLE_SIZE 24 @@ -74,7 +72,8 @@ static void hal_tx_desc_set_dscp_tid_table_id_6290(void *desc, * * Return: none */ -static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, +static void hal_tx_set_dscp_tid_map_6290(struct hal_soc *soc, + uint8_t *map, uint8_t id) { int i; @@ -82,8 +81,6 @@ static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, uint32_t value = 0, regval; uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX) return; @@ -112,7 +109,7 @@ static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, (map[i + 6] << 0x12) | (map[i + 7] << 0x15)); - qdf_mem_copy(&val[cnt], (void *)&value, 3); + qdf_mem_copy(&val[cnt], &value, 3); cnt += 3; } @@ -131,15 +128,14 @@ static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, HAL_REG_WRITE(soc, cmn_reg_addr, regval); } #else -static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, +static void hal_tx_set_dscp_tid_map_6290(struct hal_soc *soc, + uint8_t *map, uint8_t id) { int i; uint32_t addr; uint32_t value; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) { addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( @@ -181,14 +177,13 @@ static void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, * * Return: void */ -static void hal_tx_update_dscp_tid_6290(void *hal_soc, uint8_t tid, +static void hal_tx_update_dscp_tid_6290(struct hal_soc *soc, uint8_t tid, uint8_t id, uint8_t dscp) { int index; uint32_t addr; uint32_t value; uint32_t regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, id); @@ -204,7 +199,7 @@ static void hal_tx_update_dscp_tid_6290(void *hal_soc, uint8_t tid, HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); } #else -static void hal_tx_update_dscp_tid_6290(void *hal_soc, uint8_t tid, +static void hal_tx_update_dscp_tid_6290(struct hal_soc *soc, uint8_t tid, uint8_t id, uint8_t dscp) { int index; @@ -212,8 +207,6 @@ static void hal_tx_update_dscp_tid_6290(void *hal_soc, uint8_t tid, uint32_t value; uint32_t regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390.c index 830f38d82588089e03e90c960c8189cadea19bc8..af5479b2c0195e0fe240100e2643f85a3b1d01fc 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -110,6 +110,882 @@ #include #include +/** + * hal_rx_get_rx_fragment_number_6390(): Function to retrieve rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_6390(): API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_6390(): API to get_6390 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_6390(): API to get_6390 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static +uint16_t hal_rx_msdu_end_sa_idx_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_6390() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_6390(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_6390(): API to get_6390 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_6390: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_6390: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msduget_6390: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t hal_rx_msdu_end_first_msdu_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_6390: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_6390: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_6390(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_6390: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/* + * hal_rx_mpdu_get_to_ds_6390(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ +static uint32_t hal_rx_mpdu_get_to_ds_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_6390(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_6390(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_6390(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_6390(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_6390(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_6390(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_6390(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_6390(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_6390(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_6390(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_6390(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_6390: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_6390: get tid based on qos control valid. + * @hal_soc_hdl: hal soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_6390(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_6390(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_6390(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_6390(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_6390 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_6390(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get_6390(): + * Retrieve qos control valid bit from the tlv. + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ +static inline uint32_t +hal_rx_mpdu_start_mpdu_qos_control_valid_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get_6390(): API to get the + * sa_sw_peer_id from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: sa_sw_peer_id index + */ +static inline uint32_t +hal_rx_msdu_end_sa_sw_peer_id_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +/** + * hal_tx_desc_set_mesh_en_6390 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_6390(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_4, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_6390(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_6390(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_6390(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_6390(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_6390(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_6390(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_6390(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_6390(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_6390(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_6390(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static +void hal_reo_config_6390(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_6390() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_6390(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_6390 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_6390(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_6390: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_6390: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_6390: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_6390: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_6390: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_6390: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_6390(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_6390() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_6390(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_6390(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_6390(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_6390(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6390(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + /** * hal_reo_set_err_dst_remap_6390(): Function to set REO error destination * ring remap register @@ -131,9 +1007,9 @@ hal_reo_set_err_dst_remap_6390(void *hal_soc) HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) | - HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 6) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7) | - HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 8) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 8) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 9); HAL_REG_WRITE(hal_soc, @@ -155,6 +1031,7 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_6390, hal_reo_set_err_dst_remap_6390, /* tx */ @@ -165,9 +1042,11 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { hal_tx_desc_set_buf_addr_generic, hal_tx_desc_set_search_type_generic, hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, hal_tx_comp_get_status_generic, hal_tx_comp_get_release_reason_generic, - + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_6390, /* rx */ hal_rx_msdu_start_nss_get_6390, hal_rx_mon_hw_desc_get_mpdu_status_6390, @@ -179,9 +1058,9 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { hal_rx_mpdu_start_tid_get_6390, hal_rx_msdu_start_reception_type_get_6390, hal_rx_msdu_end_da_idx_get_6390, - hal_rx_msdu_desc_info_get_ptr_generic, - hal_rx_link_desc_msdu0_ptr_generic, - hal_reo_status_get_header_generic, + hal_rx_msdu_desc_info_get_ptr_6390, + hal_rx_link_desc_msdu0_ptr_6390, + hal_reo_status_get_header_6390, hal_rx_status_get_tlv_info_generic, hal_rx_wbm_err_info_get_generic, hal_rx_dump_mpdu_start_tlv_generic, @@ -189,6 +1068,61 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { hal_tx_set_pcp_tid_map_generic, hal_tx_update_pcp_tid_generic, hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_6390, + hal_rx_msdu_end_da_is_mcbc_get_6390, + hal_rx_msdu_end_sa_is_valid_get_6390, + hal_rx_msdu_end_sa_idx_get_6390, + hal_rx_desc_is_first_msdu_6390, + hal_rx_msdu_end_l3_hdr_padding_get_6390, + hal_rx_encryption_info_valid_6390, + hal_rx_print_pn_6390, + hal_rx_msdu_end_first_msdu_get_6390, + hal_rx_msdu_end_da_is_valid_get_6390, + hal_rx_msdu_end_last_msdu_get_6390, + hal_rx_get_mpdu_mac_ad4_valid_6390, + hal_rx_mpdu_start_sw_peer_id_get_6390, + hal_rx_mpdu_get_to_ds_6390, + hal_rx_mpdu_get_fr_ds_6390, + hal_rx_get_mpdu_frame_control_valid_6390, + hal_rx_mpdu_get_addr1_6390, + hal_rx_mpdu_get_addr2_6390, + hal_rx_mpdu_get_addr3_6390, + hal_rx_mpdu_get_addr4_6390, + hal_rx_get_mpdu_sequence_control_valid_6390, + hal_rx_is_unicast_6390, + hal_rx_tid_get_6390, + hal_rx_hw_desc_get_ppduid_get_6390, + hal_rx_mpdu_start_mpdu_qos_control_valid_get_6390, + hal_rx_msdu_end_sa_sw_peer_id_get_6390, + hal_rx_msdu0_buffer_addr_lsb_6390, + hal_rx_msdu_desc_info_ptr_get_6390, + hal_ent_mpdu_desc_info_6390, + hal_dst_mpdu_desc_info_6390, + hal_rx_get_fc_valid_6390, + hal_rx_get_to_ds_flag_6390, + hal_rx_get_mac_addr2_valid_6390, + hal_rx_get_filter_category_6390, + hal_rx_get_ppdu_id_6390, + hal_reo_config_6390, + hal_rx_msdu_flow_idx_get_6390, + hal_rx_msdu_flow_idx_invalid_6390, + hal_rx_msdu_flow_idx_timeout_6390, + hal_rx_msdu_fse_metadata_get_6390, + hal_rx_msdu_cce_metadata_get_6390, + hal_rx_msdu_get_flow_params_6390, + hal_rx_tlv_get_tcp_chksum_6390, + hal_rx_get_rx_sequence_6390, + NULL, + NULL, + /* rx - msdu end fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL }; struct hal_hw_srng_config hw_srng_table_6390[] = { diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_rx.h index 601032de1408c153ec5cb4cd9ee8eb2132ba8e07..095b9f8de03b820cad9e29bbf7d5dd900d870599 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,12 +35,325 @@ #include "hal_api_mon.h" #include "phyrx_other_receive_info_ru_details.h" +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_5_DA_IS_MCBC_MASK, \ + RX_MSDU_END_5_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_SA_IS_VALID_MASK, \ + RX_MSDU_END_5_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_SA_IDX_OFFSET)), \ + RX_MSDU_END_13_SA_IDX_MASK, \ + RX_MSDU_END_13_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_5_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_5_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_4_PN_31_0_MASK, \ + RX_MPDU_INFO_4_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_5_PN_63_32_MASK, \ + RX_MPDU_INFO_5_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_6_PN_95_64_MASK, \ + RX_MPDU_INFO_6_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_7_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_7_PN_127_96_MASK, \ + RX_MPDU_INFO_7_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_5_FIRST_MSDU_MASK, \ + RX_MSDU_END_5_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_DA_IS_VALID_MASK, \ + RX_MSDU_END_5_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_5_LAST_MSDU_MASK, \ + RX_MSDU_END_5_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_1_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_1_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_TO_DS_OFFSET)), \ + RX_MPDU_INFO_2_TO_DS_MASK, \ + RX_MPDU_INFO_2_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FR_DS_OFFSET)), \ + RX_MPDU_INFO_2_FR_DS_MASK, \ + RX_MPDU_INFO_2_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_16_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_16_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | \ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring) | \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + (~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\ + (REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ +UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_14_FLOW_IDX_MASK, \ + RX_MSDU_END_14_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_15_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_15_FSE_METADATA_MASK, \ + RX_MSDU_END_15_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_16_CCE_METADATA_MASK, \ + RX_MSDU_END_16_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB)) /* * hal_rx_msdu_start_nss_get_6390(): API to get the NSS * Interval from rx_msdu_start diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_tx.h index b827d4add7c630e1984929f2bcfbb56ccf267572..ddd25873247bbfd39c847025dba587727c94fb75 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -57,7 +57,7 @@ static void hal_tx_desc_set_dscp_tid_table_id_6390(void *desc, uint8_t id) * * Return: none */ -static void hal_tx_set_dscp_tid_map_6390(void *hal_soc, uint8_t *map, +static void hal_tx_set_dscp_tid_map_6390(struct hal_soc *soc, uint8_t *map, uint8_t id) { int i; @@ -65,8 +65,6 @@ static void hal_tx_set_dscp_tid_map_6390(void *hal_soc, uint8_t *map, uint32_t value = 0, regval; uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX) return; @@ -95,7 +93,7 @@ static void hal_tx_set_dscp_tid_map_6390(void *hal_soc, uint8_t *map, (map[i + 6] << 0x12) | (map[i + 7] << 0x15)); - qdf_mem_copy(&val[cnt], (void *)&value, 3); + qdf_mem_copy(&val[cnt], &value, 3); cnt += 3; } @@ -124,14 +122,13 @@ static void hal_tx_set_dscp_tid_map_6390(void *hal_soc, uint8_t *map, * * Return: void */ -static void hal_tx_update_dscp_tid_6390(void *hal_soc, uint8_t tid, +static void hal_tx_update_dscp_tid_6390(struct hal_soc *soc, uint8_t tid, uint8_t id, uint8_t dscp) { int index; uint32_t addr; uint32_t value; uint32_t regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, id); diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490.c new file mode 100644 index 0000000000000000000000000000000000000000..6124a42d9dfd725cf83a94f897118700596ea3eb --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490.c @@ -0,0 +1,2054 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "qdf_types.h" +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "hal_api.h" +#include "target_type.h" +#include "wcss_version.h" +#include "qdf_module.h" + +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_OFFSET \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_OFFSET +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_MASK \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_MASK +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_LSB \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_LSB +#define UNIFIED_PHYRX_HT_SIG_0_HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_L_SIG_B_0_L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_L_SIG_A_0_L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_A_0_PHYRX_L_SIG_A_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_VHT_SIG_A_0_VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_VHT_SIG_A_0_PHYRX_VHT_SIG_A_INFO_DETAILS_BANDWIDTH_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_SU_0_HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_SU_0_PHYRX_HE_SIG_A_SU_INFO_DETAILS_FORMAT_INDICATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_MU_DL_0_HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_MU_DL_0_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_DL_UL_FLAG_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B1_MU_0_HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B1_MU_0_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_RU_ALLOCATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_MU_0_HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_MU_0_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_STA_ID_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0_HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_OFDMA_0_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_STA_ID_OFFSET + +#define UNIFIED_PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET +#define UNIFIED_PHYRX_RSSI_LEGACY_19_RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_19_PREAMBLE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET +#define UNIFIED_RX_MPDU_START_0_RX_MPDU_INFO_RX_MPDU_INFO_DETAILS_OFFSET \ + RX_MPDU_START_0_RX_MPDU_INFO_DETAILS_RXPT_CLASSIFY_INFO_DETAILS_REO_DESTINATION_INDICATION_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET +#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC \ + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_0_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_0_BUF_ADDR_INFO_BUFFER_ADDR_31_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_1_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_1_BUF_ADDR_INFO_BUFFER_ADDR_39_32_OFFSET +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_MASK \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_OFFSET \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_OFFSET +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_LSB + +#include "hal_6490_tx.h" +#include "hal_6490_rx.h" +#include +#include + +/* + * hal_rx_msdu_start_nss_get_6490(): API to get the NSS + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +static uint32_t +hal_rx_msdu_start_nss_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint8_t mimo_ss_bitmap; + + mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); + + return qdf_get_hweight8(mimo_ss_bitmap); +} + +/** + * hal_rx_mon_hw_desc_get_mpdu_status_6490(): Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +static void hal_rx_mon_hw_desc_get_mpdu_status_6490(void *hw_desc_addr, + struct mon_rx_status *rs) +{ + struct rx_msdu_start *rx_msdu_start; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + uint32_t reg_value; + const uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; + + rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; + + HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); + + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, + RX_MSDU_START_5, USER_RSSI); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ +} + +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) + +static uint32_t hal_get_link_desc_size_6490(void) +{ + return LINK_DESC_SIZE; +} + +/* + * hal_rx_get_tlv_6490(): API to get the tlv + * + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +static uint8_t hal_rx_get_tlv_6490(void *rx_tlv) +{ + return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); +} + +/** + * hal_rx_proc_phyrx_other_receive_info_tlv_6490() + * - process other receive info TLV + * @rx_tlv_hdr: pointer to TLV header + * @ppdu_info: pointer to ppdu_info + * + * Return: None + */ +static +void hal_rx_proc_phyrx_other_receive_info_tlv_6490(void *rx_tlv_hdr, + void *ppdu_info_handle) +{ + uint32_t tlv_tag, tlv_len; + uint32_t temp_len, other_tlv_len, other_tlv_tag; + void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + void *other_tlv_hdr = NULL; + void *other_tlv = NULL; + + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); + tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); + temp_len = 0; + + other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; + + other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); + other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); + temp_len += other_tlv_len; + other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + + switch (other_tlv_tag) { + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s unhandled TLV type: %d, TLV len:%d", + __func__, other_tlv_tag, other_tlv_len); + break; + } +} + +/** + * hal_rx_dump_msdu_start_tlv_6490() : dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_start_tlv_6490(void *msdustart, uint8_t dbg_level) +{ + struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; + + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_start tlv (1/2) - " + "rxpcu_mpdu_filter_in_category: %x " + "sw_frame_group_id: %x " + "phy_ppdu_id: %x " + "msdu_length: %x " + "ipsec_esp: %x " + "l3_offset: %x " + "ipsec_ah: %x " + "l4_offset: %x " + "msdu_number: %x " + "decap_format: %x " + "ipv4_proto: %x " + "ipv6_proto: %x " + "tcp_proto: %x " + "udp_proto: %x " + "ip_frag: %x " + "tcp_only_ack: %x " + "da_is_bcast_mcast: %x " + "ip4_protocol_ip6_next_header: %x " + "toeplitz_hash_2_or_4: %x " + "flow_id_toeplitz: %x " + "user_rssi: %x " + "pkt_type: %x " + "stbc: %x " + "sgi: %x " + "rate_mcs: %x " + "receive_bandwidth: %x " + "reception_type: %x " + "ppdu_start_timestamp: %u ", + msdu_start->rxpcu_mpdu_filter_in_category, + msdu_start->sw_frame_group_id, + msdu_start->phy_ppdu_id, + msdu_start->msdu_length, + msdu_start->ipsec_esp, + msdu_start->l3_offset, + msdu_start->ipsec_ah, + msdu_start->l4_offset, + msdu_start->msdu_number, + msdu_start->decap_format, + msdu_start->ipv4_proto, + msdu_start->ipv6_proto, + msdu_start->tcp_proto, + msdu_start->udp_proto, + msdu_start->ip_frag, + msdu_start->tcp_only_ack, + msdu_start->da_is_bcast_mcast, + msdu_start->ip4_protocol_ip6_next_header, + msdu_start->toeplitz_hash_2_or_4, + msdu_start->flow_id_toeplitz, + msdu_start->user_rssi, + msdu_start->pkt_type, + msdu_start->stbc, + msdu_start->sgi, + msdu_start->rate_mcs, + msdu_start->receive_bandwidth, + msdu_start->reception_type, + msdu_start->ppdu_start_timestamp); + + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_start tlv (2/2) - " + "sw_phy_meta_data: %x ", + msdu_start->sw_phy_meta_data); +} + +/** + * hal_rx_dump_msdu_end_tlv_6490: dump RX msdu_end TLV in structured + * human readable format. + * @ msdu_end: pointer the msdu_end TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_end_tlv_6490(void *msduend, + uint8_t dbg_level) +{ + struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; + + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_end tlv (1/3) - " + "rxpcu_mpdu_filter_in_category: %x " + "sw_frame_group_id: %x " + "phy_ppdu_id: %x " + "ip_hdr_chksum: %x " + "tcp_udp_chksum: %x " + "key_id_octet: %x " + "cce_super_rule: %x " + "cce_classify_not_done_truncat: %x " + "cce_classify_not_done_cce_dis: %x " + "ext_wapi_pn_63_48: %x " + "ext_wapi_pn_95_64: %x " + "ext_wapi_pn_127_96: %x " + "reported_mpdu_length: %x " + "first_msdu: %x " + "last_msdu: %x " + "sa_idx_timeout: %x " + "da_idx_timeout: %x " + "msdu_limit_error: %x " + "flow_idx_timeout: %x " + "flow_idx_invalid: %x " + "wifi_parser_error: %x " + "amsdu_parser_error: %x", + msdu_end->rxpcu_mpdu_filter_in_category, + msdu_end->sw_frame_group_id, + msdu_end->phy_ppdu_id, + msdu_end->ip_hdr_chksum, + msdu_end->tcp_udp_chksum, + msdu_end->key_id_octet, + msdu_end->cce_super_rule, + msdu_end->cce_classify_not_done_truncate, + msdu_end->cce_classify_not_done_cce_dis, + msdu_end->ext_wapi_pn_63_48, + msdu_end->ext_wapi_pn_95_64, + msdu_end->ext_wapi_pn_127_96, + msdu_end->reported_mpdu_length, + msdu_end->first_msdu, + msdu_end->last_msdu, + msdu_end->sa_idx_timeout, + msdu_end->da_idx_timeout, + msdu_end->msdu_limit_error, + msdu_end->flow_idx_timeout, + msdu_end->flow_idx_invalid, + msdu_end->wifi_parser_error, + msdu_end->amsdu_parser_error); + + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_end tlv (2/3)- " + "sa_is_valid: %x " + "da_is_valid: %x " + "da_is_mcbc: %x " + "l3_header_padding: %x " + "ipv6_options_crc: %x " + "tcp_seq_number: %x " + "tcp_ack_number: %x " + "tcp_flag: %x " + "lro_eligible: %x " + "window_size: %x " + "da_offset: %x " + "sa_offset: %x " + "da_offset_valid: %x " + "sa_offset_valid: %x " + "rule_indication_31_0: %x " + "rule_indication_63_32: %x " + "sa_idx: %x " + "da_idx: %x " + "msdu_drop: %x " + "reo_destination_indication: %x " + "flow_idx: %x " + "fse_metadata: %x " + "cce_metadata: %x " + "sa_sw_peer_id: %x ", + msdu_end->sa_is_valid, + msdu_end->da_is_valid, + msdu_end->da_is_mcbc, + msdu_end->l3_header_padding, + msdu_end->ipv6_options_crc, + msdu_end->tcp_seq_number, + msdu_end->tcp_ack_number, + msdu_end->tcp_flag, + msdu_end->lro_eligible, + msdu_end->window_size, + msdu_end->da_offset, + msdu_end->sa_offset, + msdu_end->da_offset_valid, + msdu_end->sa_offset_valid, + msdu_end->rule_indication_31_0, + msdu_end->rule_indication_63_32, + msdu_end->sa_idx, + msdu_end->da_idx_or_sw_peer_id, + msdu_end->msdu_drop, + msdu_end->reo_destination_indication, + msdu_end->flow_idx, + msdu_end->fse_metadata, + msdu_end->cce_metadata, + msdu_end->sa_sw_peer_id); + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_end tlv (3/3)" + "aggregation_count %x " + "flow_aggregation_continuation %x " + "fisa_timeout %x " + "cumulative_l4_checksum %x " + "cumulative_ip_length %x", + msdu_end->aggregation_count, + msdu_end->flow_aggregation_continuation, + msdu_end->fisa_timeout, + msdu_end->cumulative_l4_checksum, + msdu_end->cumulative_ip_length); +} + +/* + * Get tid from RX_MPDU_START + */ +#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_7_TID_OFFSET)), \ + RX_MPDU_INFO_7_TID_MASK, \ + RX_MPDU_INFO_7_TID_LSB)) + +static uint32_t hal_rx_mpdu_start_tid_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t tid; + + tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); + + return tid; +} + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +static +uint32_t hal_rx_msdu_start_reception_type_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + +/** + * hal_rx_msdu_end_da_idx_get_6490: API to get da_idx + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da index + */ +static uint16_t hal_rx_msdu_end_da_idx_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t da_idx; + + da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); + + return da_idx; +} +/** + * hal_rx_get_rx_fragment_number_6490(): Function to retrieve rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_6490(): API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_6490(): API to get_6490 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_6490(): API to get_6490 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static +uint16_t hal_rx_msdu_end_sa_idx_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_6490() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_6490(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_10, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_6490(): API to get_6490 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_6490: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_6490: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_6490: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t hal_rx_msdu_end_first_msdu_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_6490: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_6490: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_6490(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_6490: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_mpdu_get_to_ds_6490(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ +static uint32_t hal_rx_mpdu_get_to_ds_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_6490(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_6490(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_6490(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_6490(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_6490(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_6490(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_6490(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_6490(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_6490(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_6490(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_6490(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_6490: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_6490: get tid based on qos control valid. + * @hal_soc_hdl: hal_soc handle + * @ buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_6490(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_6490(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_6490(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_6490(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_9, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_6490 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_6490(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_tx_desc_set_mesh_en_6490 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_6490(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_5, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_6490(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_6490(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_6490(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_6490(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_6490(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_6490(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_6490(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_6490(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_6490(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_6490(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static +void hal_reo_config_6490(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_6490() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_6490(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_6490 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_6490(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_6490: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_reo_destination_indication_6490: API to get + * reo_destination_indication from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @reo_destination_indication: pointer to return value of reo_destination_indication + * + * Return: none + */ +static inline void +hal_rx_msdu_get_reo_destination_indication_6490(uint8_t *buf, + uint32_t *reo_destination_indication) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *reo_destination_indication = HAL_RX_MSDU_END_REO_DEST_IND_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_6490: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_6490: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_6490: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_6490: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_6490: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_6490(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_6490() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_6490(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_6490(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6490(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + +/** + * hal_rx_get_fisa_cumulative_l4_checksum_6490() - Retrieve cumulative + * checksum + * @buf: buffer pointer + * + * Return: cumulative checksum + */ +static inline +uint16_t hal_rx_get_fisa_cumulative_l4_checksum_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_FISA_CUMULATIVE_L4_CHECKSUM(buf); +} + +/** + * hal_rx_get_fisa_cumulative_ip_length_6490() - Retrieve cumulative + * ip length + * @buf: buffer pointer + * + * Return: cumulative length + */ +static inline +uint16_t hal_rx_get_fisa_cumulative_ip_length_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_FISA_CUMULATIVE_IP_LENGTH(buf); +} + +/** + * hal_rx_get_udp_proto_6490() - Retrieve udp proto value + * @buf: buffer + * + * Return: udp proto bit + */ +static inline +bool hal_rx_get_udp_proto_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_UDP_PROTO(buf); +} + +/** + * hal_rx_get_flow_agg_continuation_6490() - retrieve flow agg + * continuation + * @buf: buffer + * + * Return: flow agg + */ +static inline +bool hal_rx_get_flow_agg_continuation_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_FLOW_AGGR_CONT(buf); +} + +/** + * hal_rx_get_flow_agg_count_6490()- Retrieve flow agg count + * @buf: buffer + * + * Return: flow agg count + */ +static inline +uint8_t hal_rx_get_flow_agg_count_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_FLOW_AGGR_COUNT(buf); +} + +/** + * hal_rx_get_fisa_timeout_6490() - Retrieve fisa timeout + * @buf: buffer + * + * Return: fisa timeout + */ +static inline +bool hal_rx_get_fisa_timeout_6490(uint8_t *buf) +{ + return HAL_RX_TLV_GET_FISA_TIMEOUT(buf); +} + +/** + * hal_reo_set_err_dst_remap_6490(): Function to set REO error destination + * ring remap register + * @hal_soc: Pointer to hal_soc + * + * Return: none. + */ +static void +hal_reo_set_err_dst_remap_6490(void *hal_soc) +{ + /* + * Set REO error 2k jump (error code 5) / OOR (error code 7) + * frame routed to REO2TCL ring. + */ + uint32_t dst_remap_ix0 = + HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 0) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 1) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 2) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7); + + uint32_t dst_remap_ix1 = + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 14) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 13) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 12) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 11) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 10) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 9) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_TCL, 8); + + HAL_REG_WRITE(hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + dst_remap_ix0); + + hal_info("HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0 0x%x", + HAL_REG_READ( + hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET))); + + HAL_REG_WRITE(hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + dst_remap_ix1); + + hal_info("HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1 0x%x", + HAL_REG_READ( + hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET))); +} + +struct hal_hw_txrx_ops qca6490_hal_hw_txrx_ops = { + /* init and setup */ + hal_srng_dst_hw_init_generic, + hal_srng_src_hw_init_generic, + hal_get_hw_hptp_generic, + hal_reo_setup_generic, + hal_setup_link_idle_list_generic, + hal_get_window_address_6490, + hal_reo_set_err_dst_remap_6490, + + /* tx */ + hal_tx_desc_set_dscp_tid_table_id_6490, + hal_tx_set_dscp_tid_map_6490, + hal_tx_update_dscp_tid_6490, + hal_tx_desc_set_lmac_id_6490, + hal_tx_desc_set_buf_addr_generic, + hal_tx_desc_set_search_type_generic, + hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, + hal_tx_comp_get_status_generic, + hal_tx_comp_get_release_reason_generic, + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_6490, + + /* rx */ + hal_rx_msdu_start_nss_get_6490, + hal_rx_mon_hw_desc_get_mpdu_status_6490, + hal_rx_get_tlv_6490, + hal_rx_proc_phyrx_other_receive_info_tlv_6490, + hal_rx_dump_msdu_start_tlv_6490, + hal_rx_dump_msdu_end_tlv_6490, + hal_get_link_desc_size_6490, + hal_rx_mpdu_start_tid_get_6490, + hal_rx_msdu_start_reception_type_get_6490, + hal_rx_msdu_end_da_idx_get_6490, + hal_rx_msdu_desc_info_get_ptr_6490, + hal_rx_link_desc_msdu0_ptr_6490, + hal_reo_status_get_header_6490, + hal_rx_status_get_tlv_info_generic, + hal_rx_wbm_err_info_get_generic, + hal_rx_dump_mpdu_start_tlv_generic, + + hal_tx_set_pcp_tid_map_generic, + hal_tx_update_pcp_tid_generic, + hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_6490, + hal_rx_msdu_end_da_is_mcbc_get_6490, + hal_rx_msdu_end_sa_is_valid_get_6490, + hal_rx_msdu_end_sa_idx_get_6490, + hal_rx_desc_is_first_msdu_6490, + hal_rx_msdu_end_l3_hdr_padding_get_6490, + hal_rx_encryption_info_valid_6490, + hal_rx_print_pn_6490, + hal_rx_msdu_end_first_msdu_get_6490, + hal_rx_msdu_end_da_is_valid_get_6490, + hal_rx_msdu_end_last_msdu_get_6490, + hal_rx_get_mpdu_mac_ad4_valid_6490, + hal_rx_mpdu_start_sw_peer_id_get_6490, + hal_rx_mpdu_get_to_ds_6490, + hal_rx_mpdu_get_fr_ds_6490, + hal_rx_get_mpdu_frame_control_valid_6490, + hal_rx_mpdu_get_addr1_6490, + hal_rx_mpdu_get_addr2_6490, + hal_rx_mpdu_get_addr3_6490, + hal_rx_mpdu_get_addr4_6490, + hal_rx_get_mpdu_sequence_control_valid_6490, + hal_rx_is_unicast_6490, + hal_rx_tid_get_6490, + hal_rx_hw_desc_get_ppduid_get_6490, + NULL, + NULL, + hal_rx_msdu0_buffer_addr_lsb_6490, + hal_rx_msdu_desc_info_ptr_get_6490, + hal_ent_mpdu_desc_info_6490, + hal_dst_mpdu_desc_info_6490, + hal_rx_get_fc_valid_6490, + hal_rx_get_to_ds_flag_6490, + hal_rx_get_mac_addr2_valid_6490, + hal_rx_get_filter_category_6490, + hal_rx_get_ppdu_id_6490, + hal_reo_config_6490, + hal_rx_msdu_flow_idx_get_6490, + hal_rx_msdu_flow_idx_invalid_6490, + hal_rx_msdu_flow_idx_timeout_6490, + hal_rx_msdu_fse_metadata_get_6490, + hal_rx_msdu_cce_metadata_get_6490, + hal_rx_msdu_get_flow_params_6490, + hal_rx_tlv_get_tcp_chksum_6490, + hal_rx_get_rx_sequence_6490, +#if defined(QCA_WIFI_QCA6490) && defined(WLAN_CFR_ENABLE) && \ + defined(WLAN_ENH_CFR_ENABLE) + hal_rx_get_bb_info_6490, + hal_rx_get_rtt_info_6490, +#else + NULL, + NULL, +#endif + /* rx - msdu end fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic, + hal_rx_get_fisa_cumulative_l4_checksum_6490, + hal_rx_get_fisa_cumulative_ip_length_6490, + hal_rx_get_udp_proto_6490, + hal_rx_get_flow_agg_continuation_6490, + hal_rx_get_flow_agg_count_6490, + hal_rx_get_fisa_timeout_6490, + hal_rx_msdu_get_reo_destination_indication_6490 +}; + +struct hal_hw_srng_config hw_srng_table_6490[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + { /* REO_DST */ + .start_ring_id = HAL_SRNG_REO2SW1, + .max_rings = 4, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2SW1_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + .reg_size = { + HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), + HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - + HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_EXCEPTION */ + /* Designating REO2TCL ring as exception ring. This ring is + * similar to other REO2SW rings though it is named as REO2TCL. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_REO2TCL, + .max_rings = 1, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2TCL_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_REINJECT */ + .start_ring_id = HAL_SRNG_SW2REO, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_SW2REO_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_CMD */ + .start_ring_id = HAL_SRNG_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_STATUS */ + .start_ring_id = HAL_SRNG_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats_status)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_DATA */ + .start_ring_id = HAL_SRNG_SW2TCL1, + .max_rings = 3, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_data_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + .reg_size = { + HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), + HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_CMD */ + .start_ring_id = HAL_SRNG_SW2TCL_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_gse_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL_CREDIT_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_STATUS */ + .start_ring_id = HAL_SRNG_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_status_ring)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_SRC */ + .start_ring_id = HAL_SRNG_CE_0_SRC, + .max_rings = 12, + .entry_size = sizeof(struct ce_src_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST */ + .start_ring_id = HAL_SRNG_CE_0_DST, + .max_rings = 12, + .entry_size = 8 >> 2, + /*TODO: entry_size above should actually be + * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition + * of struct ce_dst_desc in HW header files + */ + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST_STATUS */ + .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, + .max_rings = 12, + .entry_size = sizeof(struct ce_stat_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + /* TODO: check destination status ring registers */ + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM_IDLE_LINK */ + .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* SW2WBM_RELEASE */ + .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM2SW_RELEASE */ + .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, +#ifdef CONFIG_PLD_PCIE_FW_SIM + .max_rings = 5, +#else + .max_rings = 4, +#endif + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .reg_size = { + HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .max_size = + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* RXDMA_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, +#ifdef IPA_OFFLOAD + .max_rings = 3, +#else + .max_rings = 2, +#endif + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_STATUS */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DESC */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* DIR_BUF_RX_DMA_SRC */ + .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, + /* + * one ring is for spectral scan + * the other is for cfr + */ + .max_rings = 2, + .entry_size = 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#ifdef WLAN_FEATURE_CIF_CFR + { /* WIFI_POS_SRC */ + .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, + .max_rings = 1, + .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#endif +}; + +int32_t hal_hw_reg_offset_qca6490[] = { + /* dst */ + REG_OFFSET(DST, HP), + REG_OFFSET(DST, TP), + REG_OFFSET(DST, ID), + REG_OFFSET(DST, MISC), + REG_OFFSET(DST, HP_ADDR_LSB), + REG_OFFSET(DST, HP_ADDR_MSB), + REG_OFFSET(DST, MSI1_BASE_LSB), + REG_OFFSET(DST, MSI1_BASE_MSB), + REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, BASE_LSB), + REG_OFFSET(DST, BASE_MSB), + REG_OFFSET(DST, PRODUCER_INT_SETUP), + /* src */ + REG_OFFSET(SRC, HP), + REG_OFFSET(SRC, TP), + REG_OFFSET(SRC, ID), + REG_OFFSET(SRC, MISC), + REG_OFFSET(SRC, TP_ADDR_LSB), + REG_OFFSET(SRC, TP_ADDR_MSB), + REG_OFFSET(SRC, MSI1_BASE_LSB), + REG_OFFSET(SRC, MSI1_BASE_MSB), + REG_OFFSET(SRC, MSI1_DATA), + REG_OFFSET(SRC, BASE_LSB), + REG_OFFSET(SRC, BASE_MSB), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), +}; + +/** + * hal_qca6490_attach() - Attach 6490 target specific hal_soc ops, + * offset and srng table + */ +void hal_qca6490_attach(struct hal_soc *hal_soc) +{ + hal_soc->hw_srng_table = hw_srng_table_6490; + hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca6490; + hal_soc->ops = &qca6490_hal_hw_txrx_ops; +} diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..8859e95eb02febc828f1bbd0bb665ae9611a28af --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_rx.h @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _HAL_6490_RX_H_ +#define _HAL_6490_RX_H_ +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" +#include "rx_msdu_start.h" +#include "tlv_tag_def.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" +#include "phyrx_other_receive_info_ru_details.h" + +#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ + RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ + RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ + RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_10_DA_IS_MCBC_MASK, \ + RX_MSDU_END_10_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_SA_IS_VALID_MASK, \ + RX_MSDU_END_10_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_SA_IDX_OFFSET)), \ + RX_MSDU_END_11_SA_IDX_MASK, \ + RX_MSDU_END_11_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_10_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_10_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_3_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_3_PN_31_0_MASK, \ + RX_MPDU_INFO_3_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_4_PN_63_32_MASK, \ + RX_MPDU_INFO_4_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_5_PN_95_64_MASK, \ + RX_MPDU_INFO_5_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_6_PN_127_96_MASK, \ + RX_MPDU_INFO_6_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_10_FIRST_MSDU_MASK, \ + RX_MSDU_END_10_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_DA_IS_VALID_MASK, \ + RX_MSDU_END_10_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_10_LAST_MSDU_MASK, \ + RX_MSDU_END_10_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_10_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_10_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_10_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_TO_DS_OFFSET)), \ + RX_MPDU_INFO_11_TO_DS_MASK, \ + RX_MPDU_INFO_11_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FR_DS_OFFSET)), \ + RX_MPDU_INFO_11_FR_DS_MASK, \ + RX_MPDU_INFO_11_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_OFFSET)),\ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_14_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_14_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MPDU_SEQUENCE_NUMBER_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_MISC_CTL_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + ~(HWIO_REO_R0_MISC_CTL_FRAGMENT_DEST_RING_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_MISC_CTL, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_MISC_CTL_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + (~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\ + (REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ +RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_RESERVED_0A_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_12_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_12_FLOW_IDX_MASK, \ + RX_MSDU_END_12_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_REO_DEST_IND_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_12_REO_DESTINATION_INDICATION_OFFSET)), \ + RX_MSDU_END_12_REO_DESTINATION_INDICATION_MASK, \ + RX_MSDU_END_12_REO_DESTINATION_INDICATION_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_13_FSE_METADATA_MASK, \ + RX_MSDU_END_13_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_14_CCE_METADATA_MASK, \ + RX_MSDU_END_14_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_LSB)) + +#define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_MASK, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_LSB)) + +#define HAL_RX_TLV_GET_FLOW_AGGR_CONT(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_17_FLOW_AGGREGATION_CONTINUATION_OFFSET)), \ + RX_MSDU_END_17_FLOW_AGGREGATION_CONTINUATION_MASK, \ + RX_MSDU_END_17_FLOW_AGGREGATION_CONTINUATION_LSB)) + +#define HAL_RX_TLV_GET_FLOW_AGGR_COUNT(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_17_AGGREGATION_COUNT_OFFSET)), \ + RX_MSDU_END_17_AGGREGATION_COUNT_MASK, \ + RX_MSDU_END_17_AGGREGATION_COUNT_LSB)) + +#define HAL_RX_TLV_GET_FISA_TIMEOUT(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_17_FISA_TIMEOUT_OFFSET)), \ + RX_MSDU_END_17_FISA_TIMEOUT_MASK, \ + RX_MSDU_END_17_FISA_TIMEOUT_LSB)) + +#define HAL_RX_TLV_GET_FISA_CUMULATIVE_L4_CHECKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_18_CUMULATIVE_L4_CHECKSUM_OFFSET)), \ + RX_MSDU_END_18_CUMULATIVE_L4_CHECKSUM_MASK, \ + RX_MSDU_END_18_CUMULATIVE_L4_CHECKSUM_LSB)) + +#define HAL_RX_TLV_GET_FISA_CUMULATIVE_IP_LENGTH(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_18_CUMULATIVE_IP_LENGTH_OFFSET)), \ + RX_MSDU_END_18_CUMULATIVE_IP_LENGTH_MASK, \ + RX_MSDU_END_18_CUMULATIVE_IP_LENGTH_LSB)) + +#if defined(QCA_WIFI_QCA6490) && defined(WLAN_CFR_ENABLE) && \ + defined(WLAN_ENH_CFR_ENABLE) +static inline +void hal_rx_get_bb_info_6490(void *rx_tlv, + void *ppdu_info_hdl) +{ + struct hal_rx_ppdu_info *ppdu_info = ppdu_info_hdl; + + ppdu_info->cfr_info.bb_captured_channel = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_CHANNEL); + + ppdu_info->cfr_info.bb_captured_timeout = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_TIMEOUT); + + ppdu_info->cfr_info.bb_captured_reason = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_REASON); +} + +static inline +void hal_rx_get_rtt_info_6490(void *rx_tlv, + void *ppdu_info_hdl) +{ + struct hal_rx_ppdu_info *ppdu_info = ppdu_info_hdl; + + ppdu_info->cfr_info.rx_location_info_valid = + HAL_RX_GET(rx_tlv, PHYRX_PKT_END_13_RX_PKT_END_DETAILS, + RX_LOCATION_INFO_DETAILS_RX_LOCATION_INFO_VALID); + + ppdu_info->cfr_info.rtt_che_buffer_pointer_low32 = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_12_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RTT_CHE_BUFFER_POINTER_LOW32); + + ppdu_info->cfr_info.rtt_che_buffer_pointer_high8 = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_11_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RTT_CHE_BUFFER_POINTER_HIGH8); + + ppdu_info->cfr_info.chan_capture_status = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_13_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RESERVED_8); +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_tx.h similarity index 81% rename from drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_tx.h rename to drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_tx.h index fc915795c4e23adc02f61c6e21ec21eefd71c43c..90cf14fc337297e3436d0a63518ee1057484e41a 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6018/hal_6018_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6490/hal_6490_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -15,6 +15,9 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" #include "hal_hw_headers.h" #include "hal_internal.h" #include "cdp_txrx_mon_struct.h" @@ -25,39 +28,36 @@ #include "hal_api_mon.h" /** - * hal_tx_desc_set_dscp_tid_table_id_6018() - Sets DSCP to TID conversion + * hal_tx_desc_set_dscp_tid_table_id_6490() - Sets DSCP to TID conversion * table ID * @desc: Handle to Tx Descriptor * @id: DSCP to tid conversion table to be used for this frame * * Return: void */ - -static void hal_tx_desc_set_dscp_tid_table_id_6018(void *desc, uint8_t id) +static void hal_tx_desc_set_dscp_tid_table_id_6490(void *desc, uint8_t id) { HAL_SET_FLD(desc, TCL_DATA_CMD_5, DSCP_TID_TABLE_NUM) |= - HAL_TX_SM(TCL_DATA_CMD_5, - DSCP_TID_TABLE_NUM, id); + HAL_TX_SM(TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM, id); } #define DSCP_TID_TABLE_SIZE 24 #define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4) + /** - * hal_tx_set_dscp_tid_map_6018() - Configure default DSCP to TID map table + * hal_tx_set_dscp_tid_map_6490() - Configure default DSCP to TID map table * @soc: HAL SoC context * @map: DSCP-TID mapping table - * @id: mapping table ID - 0,1 + * @id: mapping table ID - 0-31 * * DSCP are mapped to 8 TID values using TID values programmed - * in two set of mapping registers DSCP_TID1_MAP_<0 to 6> (id = 0) - * and DSCP_TID2_MAP_<0 to 6> (id = 1) - * Each mapping register has TID mapping for 10 DSCP values + * in any of the 32 DSCP_TID_MAPS (id = 0-31). * * Return: none */ - -static void hal_tx_set_dscp_tid_map_6018(void *hal_soc, uint8_t *map, +static void hal_tx_set_dscp_tid_map_6490(struct hal_soc *hal_soc, uint8_t *map, uint8_t id) { int i; @@ -80,7 +80,8 @@ static void hal_tx_set_dscp_tid_map_6018(void *hal_soc, uint8_t *map, /* Enable read/write access */ regval = HAL_REG_READ(soc, cmn_reg_addr); regval |= - (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); + (1 << + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); HAL_REG_WRITE(soc, cmn_reg_addr, regval); @@ -115,8 +116,8 @@ static void hal_tx_set_dscp_tid_map_6018(void *hal_soc, uint8_t *map, } /** - * hal_tx_update_dscp_tid_6018() - Update the dscp tid map table as - updated by user + * hal_tx_update_dscp_tid_6490() - Update the dscp tid map table as updated + * by the user * @soc: HAL SoC context * @map: DSCP-TID mapping table * @id : MAP ID @@ -124,8 +125,7 @@ static void hal_tx_set_dscp_tid_map_6018(void *hal_soc, uint8_t *map, * * Return: void */ - -static void hal_tx_update_dscp_tid_6018(void *hal_soc, uint8_t tid, +static void hal_tx_update_dscp_tid_6490(struct hal_soc *hal_soc, uint8_t tid, uint8_t id, uint8_t dscp) { int index; @@ -159,10 +159,8 @@ static void hal_tx_update_dscp_tid_6018(void *hal_soc, uint8_t tid, * * Return: void */ - -static void hal_tx_desc_set_lmac_id_6018(void *desc, uint8_t lmac_id) +static void hal_tx_desc_set_lmac_id_6490(void *desc, uint8_t lmac_id) { HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |= HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id); } - diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750.c new file mode 100644 index 0000000000000000000000000000000000000000..0542cb8fbdf71548e009bbfc87d6cb95fbdb6bd2 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750.c @@ -0,0 +1,1835 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "qdf_types.h" +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "hal_api.h" +#include "target_type.h" +#include "wcss_version.h" +#include "qdf_module.h" + +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_OFFSET \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_OFFSET +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_MASK \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_MASK +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_LSB \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_LSB +#define UNIFIED_PHYRX_HT_SIG_0_HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_L_SIG_B_0_L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_L_SIG_A_0_L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_A_0_PHYRX_L_SIG_A_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_VHT_SIG_A_0_VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_VHT_SIG_A_0_PHYRX_VHT_SIG_A_INFO_DETAILS_BANDWIDTH_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_SU_0_HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_SU_0_PHYRX_HE_SIG_A_SU_INFO_DETAILS_FORMAT_INDICATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_MU_DL_0_HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_MU_DL_0_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_DL_UL_FLAG_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B1_MU_0_HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B1_MU_0_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_RU_ALLOCATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_MU_0_HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_MU_0_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_STA_ID_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0_HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_OFDMA_0_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_STA_ID_OFFSET + +#define UNIFIED_PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET +#define UNIFIED_PHYRX_RSSI_LEGACY_19_RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_19_PREAMBLE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET +#define UNIFIED_RX_MPDU_START_0_RX_MPDU_INFO_RX_MPDU_INFO_DETAILS_OFFSET \ + RX_MPDU_START_0_RX_MPDU_INFO_DETAILS_RXPT_CLASSIFY_INFO_DETAILS_REO_DESTINATION_INDICATION_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET +#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC \ + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_0_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_0_BUF_ADDR_INFO_BUFFER_ADDR_31_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_1_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_1_BUF_ADDR_INFO_BUFFER_ADDR_39_32_OFFSET +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_MASK \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_OFFSET \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_OFFSET +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_LSB + +#include "hal_6750_tx.h" +#include "hal_6750_rx.h" +#include +#include + +/* + * hal_rx_msdu_start_nss_get_6750(): API to get the NSS + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +static uint32_t +hal_rx_msdu_start_nss_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint8_t mimo_ss_bitmap; + + mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); + + return qdf_get_hweight8(mimo_ss_bitmap); +} + +/** + * hal_rx_mon_hw_desc_get_mpdu_status_6750(): Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +static void hal_rx_mon_hw_desc_get_mpdu_status_6750(void *hw_desc_addr, + struct mon_rx_status *rs) +{ + struct rx_msdu_start *rx_msdu_start; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + uint32_t reg_value; + const uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; + + rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; + + HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); + + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, + RX_MSDU_START_5, USER_RSSI); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ +} + +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) + +static uint32_t hal_get_link_desc_size_6750(void) +{ + return LINK_DESC_SIZE; +} + +/* + * hal_rx_get_tlv_6750(): API to get the tlv + * + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +static uint8_t hal_rx_get_tlv_6750(void *rx_tlv) +{ + return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); +} + +/** + * hal_rx_proc_phyrx_other_receive_info_tlv_6750() + * - process other receive info TLV + * @rx_tlv_hdr: pointer to TLV header + * @ppdu_info: pointer to ppdu_info + * + * Return: None + */ +static +void hal_rx_proc_phyrx_other_receive_info_tlv_6750(void *rx_tlv_hdr, + void *ppdu_info_handle) +{ + uint32_t tlv_tag, tlv_len; + uint32_t temp_len, other_tlv_len, other_tlv_tag; + void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + void *other_tlv_hdr = NULL; + void *other_tlv = NULL; + + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); + tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); + temp_len = 0; + + other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; + + other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); + other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); + temp_len += other_tlv_len; + other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + + switch (other_tlv_tag) { + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s unhandled TLV type: %d, TLV len:%d", + __func__, other_tlv_tag, other_tlv_len); + break; + } +} + +/** + * hal_rx_dump_msdu_start_tlv_6750() : dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_start_tlv_6750(void *msdustart, uint8_t dbg_level) +{ + struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; + + hal_verbose_debug( + "rx_msdu_start tlv (1/2) - " + "rxpcu_mpdu_filter_in_category: %x " + "sw_frame_group_id: %x " + "phy_ppdu_id: %x " + "msdu_length: %x " + "ipsec_esp: %x " + "l3_offset: %x " + "ipsec_ah: %x " + "l4_offset: %x " + "msdu_number: %x " + "decap_format: %x " + "ipv4_proto: %x " + "ipv6_proto: %x " + "tcp_proto: %x " + "udp_proto: %x " + "ip_frag: %x " + "tcp_only_ack: %x " + "da_is_bcast_mcast: %x " + "ip4_protocol_ip6_next_header: %x " + "toeplitz_hash_2_or_4: %x " + "flow_id_toeplitz: %x " + "user_rssi: %x " + "pkt_type: %x " + "stbc: %x " + "sgi: %x " + "rate_mcs: %x " + "receive_bandwidth: %x " + "reception_type: %x " + "ppdu_start_timestamp: %u ", + msdu_start->rxpcu_mpdu_filter_in_category, + msdu_start->sw_frame_group_id, + msdu_start->phy_ppdu_id, + msdu_start->msdu_length, + msdu_start->ipsec_esp, + msdu_start->l3_offset, + msdu_start->ipsec_ah, + msdu_start->l4_offset, + msdu_start->msdu_number, + msdu_start->decap_format, + msdu_start->ipv4_proto, + msdu_start->ipv6_proto, + msdu_start->tcp_proto, + msdu_start->udp_proto, + msdu_start->ip_frag, + msdu_start->tcp_only_ack, + msdu_start->da_is_bcast_mcast, + msdu_start->ip4_protocol_ip6_next_header, + msdu_start->toeplitz_hash_2_or_4, + msdu_start->flow_id_toeplitz, + msdu_start->user_rssi, + msdu_start->pkt_type, + msdu_start->stbc, + msdu_start->sgi, + msdu_start->rate_mcs, + msdu_start->receive_bandwidth, + msdu_start->reception_type, + msdu_start->ppdu_start_timestamp); + + hal_verbose_debug( + "rx_msdu_start tlv (2/2) - " + "sw_phy_meta_data: %x ", + msdu_start->sw_phy_meta_data); +} + +/** + * hal_rx_dump_msdu_end_tlv_6750: dump RX msdu_end TLV in structured + * human readable format. + * @ msdu_end: pointer the msdu_end TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_end_tlv_6750(void *msduend, + uint8_t dbg_level) +{ + struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_end tlv (1/2) - " + "rxpcu_mpdu_filter_in_category: %x " + "sw_frame_group_id: %x " + "phy_ppdu_id: %x " + "ip_hdr_chksum: %x " + "tcp_udp_chksum: %x " + "key_id_octet: %x " + "cce_super_rule: %x " + "cce_classify_not_done_truncat: %x " + "cce_classify_not_done_cce_dis: %x " + "reported_mpdu_length: %x " + "first_msdu: %x " + "last_msdu: %x " + "sa_idx_timeout: %x " + "da_idx_timeout: %x " + "msdu_limit_error: %x " + "flow_idx_timeout: %x " + "flow_idx_invalid: %x " + "wifi_parser_error: %x " + "amsdu_parser_error: %x", + msdu_end->rxpcu_mpdu_filter_in_category, + msdu_end->sw_frame_group_id, + msdu_end->phy_ppdu_id, + msdu_end->ip_hdr_chksum, + msdu_end->tcp_udp_chksum, + msdu_end->key_id_octet, + msdu_end->cce_super_rule, + msdu_end->cce_classify_not_done_truncate, + msdu_end->cce_classify_not_done_cce_dis, + msdu_end->reported_mpdu_length, + msdu_end->first_msdu, + msdu_end->last_msdu, + msdu_end->sa_idx_timeout, + msdu_end->da_idx_timeout, + msdu_end->msdu_limit_error, + msdu_end->flow_idx_timeout, + msdu_end->flow_idx_invalid, + msdu_end->wifi_parser_error, + msdu_end->amsdu_parser_error); + __QDF_TRACE_RL(dbg_level, QDF_MODULE_ID_DP, + "rx_msdu_end tlv (2/2)- " + "sa_is_valid: %x " + "da_is_valid: %x " + "da_is_mcbc: %x " + "l3_header_padding: %x " + "ipv6_options_crc: %x " + "tcp_seq_number: %x " + "tcp_ack_number: %x " + "tcp_flag: %x " + "lro_eligible: %x " + "window_size: %x " + "da_offset: %x " + "sa_offset: %x " + "da_offset_valid: %x " + "sa_offset_valid: %x " + "rule_indication_31_0: %x " + "rule_indication_63_32: %x " + "sa_idx: %x " + "da_idx: %x " + "msdu_drop: %x " + "reo_destination_indication: %x " + "flow_idx: %x " + "fse_metadata: %x " + "cce_metadata: %x " + "sa_sw_peer_id: %x ", + msdu_end->sa_is_valid, + msdu_end->da_is_valid, + msdu_end->da_is_mcbc, + msdu_end->l3_header_padding, + msdu_end->ipv6_options_crc, + msdu_end->tcp_seq_number, + msdu_end->tcp_ack_number, + msdu_end->tcp_flag, + msdu_end->lro_eligible, + msdu_end->window_size, + msdu_end->da_offset, + msdu_end->sa_offset, + msdu_end->da_offset_valid, + msdu_end->sa_offset_valid, + msdu_end->rule_indication_31_0, + msdu_end->rule_indication_63_32, + msdu_end->sa_idx, + msdu_end->da_idx_or_sw_peer_id, + msdu_end->msdu_drop, + msdu_end->reo_destination_indication, + msdu_end->flow_idx, + msdu_end->fse_metadata, + msdu_end->cce_metadata, + msdu_end->sa_sw_peer_id); +} + +/* + * Get tid from RX_MPDU_START + */ +#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_7_TID_OFFSET)), \ + RX_MPDU_INFO_7_TID_MASK, \ + RX_MPDU_INFO_7_TID_LSB)) + +static uint32_t hal_rx_mpdu_start_tid_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t tid; + + tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); + + return tid; +} + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +static +uint32_t hal_rx_msdu_start_reception_type_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + +/** + * hal_rx_msdu_end_da_idx_get_6750: API to get da_idx + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da index + */ +static uint16_t hal_rx_msdu_end_da_idx_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t da_idx; + + da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); + + return da_idx; +} + +/** + * hal_rx_get_rx_fragment_number_6750(): Function to retrieve rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_6750(): API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_6750(): API to get_6750 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_6750(): API to get_6750 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static +uint16_t hal_rx_msdu_end_sa_idx_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_6750() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_6750(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_10, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_6750(): API to get_6750 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_6750: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_6750: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_6750: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t hal_rx_msdu_end_first_msdu_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_6750: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_6750: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_6750(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_6750: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_mpdu_get_to_ds_6750(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ +static uint32_t hal_rx_mpdu_get_to_ds_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_6750(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_6750(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_6750(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_6750(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_6750(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_6750(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_6750(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_6750(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_6750(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_6750(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_6750(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_6750: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_6750: get tid based on qos control valid. + * @hal_soc_hdl: hal_soc handle + * @ buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_6750(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_6750(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_6750(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_6750(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_9, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_6750 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_6750(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + STATUS_HEADER_REO_STATUS_NUMBER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + STATUS_HEADER_TIMESTAMP)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_tx_desc_set_mesh_en_6750 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_6750(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_5, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_6750(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_6750(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_6750(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_6750(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_6750(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_6750(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_6750(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_6750(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_6750(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_6750(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static +void hal_reo_config_6750(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_6750() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_6750(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_6750 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_6750(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_6750: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_6750: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_6750: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_6750: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_6750: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_6750() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_6750(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_6750(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_6750(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_6750(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6750(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + +struct hal_hw_txrx_ops qca6750_hal_hw_txrx_ops = { + /* init and setup */ + hal_srng_dst_hw_init_generic, + hal_srng_src_hw_init_generic, + hal_get_hw_hptp_generic, + hal_reo_setup_generic, + hal_setup_link_idle_list_generic, + hal_get_window_address_6750, + NULL, + + /* tx */ + hal_tx_desc_set_dscp_tid_table_id_6750, + hal_tx_set_dscp_tid_map_6750, + hal_tx_update_dscp_tid_6750, + hal_tx_desc_set_lmac_id_6750, + hal_tx_desc_set_buf_addr_generic, + hal_tx_desc_set_search_type_generic, + hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, + hal_tx_comp_get_status_generic, + hal_tx_comp_get_release_reason_generic, + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_6750, + + /* rx */ + hal_rx_msdu_start_nss_get_6750, + hal_rx_mon_hw_desc_get_mpdu_status_6750, + hal_rx_get_tlv_6750, + hal_rx_proc_phyrx_other_receive_info_tlv_6750, + hal_rx_dump_msdu_start_tlv_6750, + hal_rx_dump_msdu_end_tlv_6750, + hal_get_link_desc_size_6750, + hal_rx_mpdu_start_tid_get_6750, + hal_rx_msdu_start_reception_type_get_6750, + hal_rx_msdu_end_da_idx_get_6750, + hal_rx_msdu_desc_info_get_ptr_6750, + hal_rx_link_desc_msdu0_ptr_6750, + hal_reo_status_get_header_6750, + hal_rx_status_get_tlv_info_generic, + hal_rx_wbm_err_info_get_generic, + hal_rx_dump_mpdu_start_tlv_generic, + + hal_tx_set_pcp_tid_map_generic, + hal_tx_update_pcp_tid_generic, + hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_6750, + hal_rx_msdu_end_da_is_mcbc_get_6750, + hal_rx_msdu_end_sa_is_valid_get_6750, + hal_rx_msdu_end_sa_idx_get_6750, + hal_rx_desc_is_first_msdu_6750, + hal_rx_msdu_end_l3_hdr_padding_get_6750, + hal_rx_encryption_info_valid_6750, + hal_rx_print_pn_6750, + hal_rx_msdu_end_first_msdu_get_6750, + hal_rx_msdu_end_da_is_valid_get_6750, + hal_rx_msdu_end_last_msdu_get_6750, + hal_rx_get_mpdu_mac_ad4_valid_6750, + hal_rx_mpdu_start_sw_peer_id_get_6750, + hal_rx_mpdu_get_to_ds_6750, + hal_rx_mpdu_get_fr_ds_6750, + hal_rx_get_mpdu_frame_control_valid_6750, + hal_rx_mpdu_get_addr1_6750, + hal_rx_mpdu_get_addr2_6750, + hal_rx_mpdu_get_addr3_6750, + hal_rx_mpdu_get_addr4_6750, + hal_rx_get_mpdu_sequence_control_valid_6750, + hal_rx_is_unicast_6750, + hal_rx_tid_get_6750, + hal_rx_hw_desc_get_ppduid_get_6750, + NULL, + NULL, + hal_rx_msdu0_buffer_addr_lsb_6750, + hal_rx_msdu_desc_info_ptr_get_6750, + hal_ent_mpdu_desc_info_6750, + hal_dst_mpdu_desc_info_6750, + hal_rx_get_fc_valid_6750, + hal_rx_get_to_ds_flag_6750, + hal_rx_get_mac_addr2_valid_6750, + hal_rx_get_filter_category_6750, + hal_rx_get_ppdu_id_6750, + hal_reo_config_6750, + hal_rx_msdu_flow_idx_get_6750, + hal_rx_msdu_flow_idx_invalid_6750, + hal_rx_msdu_flow_idx_timeout_6750, + hal_rx_msdu_fse_metadata_get_6750, + hal_rx_msdu_cce_metadata_get_6750, + NULL, + hal_rx_tlv_get_tcp_chksum_6750, + hal_rx_get_rx_sequence_6750, + NULL, + NULL, + /* rx - msdu end fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic +}; + +struct hal_hw_srng_config hw_srng_table_6750[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + { /* REO_DST */ + .start_ring_id = HAL_SRNG_REO2SW1, + .max_rings = 4, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2SW1_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + .reg_size = { + HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), + HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - + HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_EXCEPTION */ + /* Designating REO2TCL ring as exception ring. This ring is + * similar to other REO2SW rings though it is named as REO2TCL. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_REO2TCL, + .max_rings = 1, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2TCL_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_REINJECT */ + .start_ring_id = HAL_SRNG_SW2REO, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_SW2REO_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_CMD */ + .start_ring_id = HAL_SRNG_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_STATUS */ + .start_ring_id = HAL_SRNG_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats_status)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_DATA */ + .start_ring_id = HAL_SRNG_SW2TCL1, + .max_rings = 3, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_data_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + .reg_size = { + HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), + HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_CMD */ + .start_ring_id = HAL_SRNG_SW2TCL_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_gse_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL_CREDIT_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_STATUS */ + .start_ring_id = HAL_SRNG_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_status_ring)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_SRC */ + .start_ring_id = HAL_SRNG_CE_0_SRC, + .max_rings = 12, + .entry_size = sizeof(struct ce_src_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_SOC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R2_SRC_RING_HP_ADDR, + }, + .reg_size = { + HWIO_SOC_CE_1_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_1_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_BASE_LSB_ADDR, + }, + .max_size = + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT + }, + { /* CE_DST */ + .start_ring_id = HAL_SRNG_CE_0_DST, + .max_rings = 12, + .entry_size = 8 >> 2, + /*TODO: entry_size above should actually be + * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition + * of struct ce_dst_desc in HW header files + */ + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR, + }, + .reg_size = { + HWIO_SOC_CE_1_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_1_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR + }, + .max_size = + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT + }, + { /* CE_DST_STATUS */ + .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, + .max_rings = 12, + .entry_size = sizeof(struct ce_stat_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR, + }, + /* TODO: check destination status ring registers */ + .reg_size = { + HWIO_SOC_CE_1_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR, + HWIO_SOC_CE_1_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR - + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR + }, + .max_size = + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_SOC_CE_0_DST_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM_IDLE_LINK */ + .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* SW2WBM_RELEASE */ + .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM2SW_RELEASE */ + .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, + .max_rings = 4, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .reg_size = { + HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .max_size = + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* RXDMA_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, +#ifdef IPA_OFFLOAD + .max_rings = 3, +#else + .max_rings = 2, +#endif + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_STATUS */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DESC */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* DIR_BUF_RX_DMA_SRC */ + .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, + .max_rings = 1, + .entry_size = 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#ifdef WLAN_FEATURE_CIF_CFR + { /* WIFI_POS_SRC */ + .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, + .max_rings = 1, + .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#endif +}; + +int32_t hal_hw_reg_offset_qca6750[] = { + /* dst */ + REG_OFFSET(DST, HP), + REG_OFFSET(DST, TP), + REG_OFFSET(DST, ID), + REG_OFFSET(DST, MISC), + REG_OFFSET(DST, HP_ADDR_LSB), + REG_OFFSET(DST, HP_ADDR_MSB), + REG_OFFSET(DST, MSI1_BASE_LSB), + REG_OFFSET(DST, MSI1_BASE_MSB), + REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, BASE_LSB), + REG_OFFSET(DST, BASE_MSB), + REG_OFFSET(DST, PRODUCER_INT_SETUP), + /* src */ + REG_OFFSET(SRC, HP), + REG_OFFSET(SRC, TP), + REG_OFFSET(SRC, ID), + REG_OFFSET(SRC, MISC), + REG_OFFSET(SRC, TP_ADDR_LSB), + REG_OFFSET(SRC, TP_ADDR_MSB), + REG_OFFSET(SRC, MSI1_BASE_LSB), + REG_OFFSET(SRC, MSI1_BASE_MSB), + REG_OFFSET(SRC, MSI1_DATA), + REG_OFFSET(SRC, BASE_LSB), + REG_OFFSET(SRC, BASE_MSB), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), +}; + +/** + * hal_qca6750_attach() - Attach 6750 target specific hal_soc ops, + * offset and srng table + */ +void hal_qca6750_attach(struct hal_soc *hal_soc) +{ + hal_soc->hw_srng_table = hw_srng_table_6750; + hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca6750; + hal_soc->ops = &qca6750_hal_hw_txrx_ops; +} diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..10f70c5e0cc5f6113abe837eac2a378fee7274e4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_rx.h @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _HAL_6750_RX_H_ +#define _HAL_6750_RX_H_ +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" +#include "rx_msdu_start.h" +#include "tlv_tag_def.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" +#include "phyrx_other_receive_info_ru_details.h" + +#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ + RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ + RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ + RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_10_DA_IS_MCBC_MASK, \ + RX_MSDU_END_10_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_SA_IS_VALID_MASK, \ + RX_MSDU_END_10_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_SA_IDX_OFFSET)), \ + RX_MSDU_END_11_SA_IDX_MASK, \ + RX_MSDU_END_11_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_10_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_10_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_3_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_3_PN_31_0_MASK, \ + RX_MPDU_INFO_3_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_4_PN_63_32_MASK, \ + RX_MPDU_INFO_4_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_5_PN_95_64_MASK, \ + RX_MPDU_INFO_5_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_6_PN_127_96_MASK, \ + RX_MPDU_INFO_6_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_10_FIRST_MSDU_MASK, \ + RX_MSDU_END_10_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_DA_IS_VALID_MASK, \ + RX_MSDU_END_10_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_10_LAST_MSDU_MASK, \ + RX_MSDU_END_10_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_10_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_10_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_10_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_TO_DS_OFFSET)), \ + RX_MPDU_INFO_11_TO_DS_MASK, \ + RX_MPDU_INFO_11_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FR_DS_OFFSET)), \ + RX_MPDU_INFO_11_FR_DS_MASK, \ + RX_MPDU_INFO_11_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_OFFSET)),\ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_14_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_14_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MPDU_SEQUENCE_NUMBER_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_MISC_CTL_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + ~(HWIO_REO_R0_MISC_CTL_FRAGMENT_DEST_RING_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_MISC_CTL, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_MISC_CTL_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR(msdu_details_ptr, \ +RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_RESERVED_0A_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_12_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_12_FLOW_IDX_MASK, \ + RX_MSDU_END_12_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_13_FSE_METADATA_MASK, \ + RX_MSDU_END_13_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_14_CCE_METADATA_MASK, \ + RX_MSDU_END_14_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_LSB)) + +#define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_MASK, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_LSB)) +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_tx.h new file mode 100644 index 0000000000000000000000000000000000000000..422b775ef8e1a56ad0abc5b4652b5ac31ad7ad05 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca6750/hal_6750_tx.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _HAL_6750_TX_H_ +#define _HAL_6750_TX_H_ +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" + +/** + * hal_tx_desc_set_dscp_tid_table_id_6750() - Sets DSCP to TID conversion + * table ID + * @desc: Handle to Tx Descriptor + * @id: DSCP to tid conversion table to be used for this frame + * + * Return: void + */ +static void hal_tx_desc_set_dscp_tid_table_id_6750(void *desc, uint8_t id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM) |= + HAL_TX_SM(TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM, id); +} + +#define DSCP_TID_TABLE_SIZE 24 +#define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4) + +/** + * hal_tx_set_dscp_tid_map_6750() - Configure default DSCP to TID map table + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id: mapping table ID - 0-31 + * + * DSCP are mapped to 8 TID values using TID values programmed + * in any of the 32 DSCP_TID_MAPS (id = 0-31). + * + * Return: none + */ +static void hal_tx_set_dscp_tid_map_6750(struct hal_soc *hal_soc, uint8_t *map, + uint8_t id) +{ + int i; + uint32_t addr, cmn_reg_addr; + uint32_t value = 0, regval; + uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; + + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX) + return; + + cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, + id * NUM_WORDS_PER_DSCP_TID_TABLE); + + /* Enable read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval |= + (1 << + HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); + + /* Write 8 (24 bits) DSCP-TID mappings in each interation */ + for (i = 0; i < 64; i += 8) { + value = (map[i] | + (map[i + 1] << 0x3) | + (map[i + 2] << 0x6) | + (map[i + 3] << 0x9) | + (map[i + 4] << 0xc) | + (map[i + 5] << 0xf) | + (map[i + 6] << 0x12) | + (map[i + 7] << 0x15)); + + qdf_mem_copy(&val[cnt], (void *)&value, 3); + cnt += 3; + } + + for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) { + regval = *(uint32_t *)(val + i); + HAL_REG_WRITE(soc, addr, + (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); + addr += 4; + } + + /* Diasble read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= + ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +/** + * hal_tx_update_dscp_tid_6750() - Update the dscp tid map table as updated + * by the user + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +static void hal_tx_update_dscp_tid_6750(struct hal_soc *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + int index; + uint32_t addr; + uint32_t value; + uint32_t regval; + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, id); + + index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; + addr += 4 * (dscp / HAL_TX_NUM_DSCP_PER_REGISTER); + value = tid << (HAL_TX_BITS_PER_TID * index); + + regval = HAL_REG_READ(soc, addr); + regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * index)); + regval |= value; + + HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); +} + +/** + * hal_tx_desc_set_lmac_id_6750 - Set the lmac_id value + * @desc: Handle to Tx Descriptor + * @lmac_id: mac Id to ast matching + * b00 – mac 0 + * b01 – mac 1 + * b10 – mac 2 + * b11 – all macs (legacy HK way) + * + * Return: void + */ +static void hal_tx_desc_set_lmac_id_6750(void *desc, uint8_t lmac_id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |= + HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1.c index 4be906748e2cb1bdcf707279336f25f191b0f561..2296029949a67cd38057f1c774977477001f1070 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -104,6 +104,886 @@ #include #include +/** + * hal_get_window_address_8074(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_8074(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + +/** + * hal_rx_get_rx_fragment_number_8074v1(): Function to retrieve + * rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_8074v1(): API to check if + * pkt is MCBC from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_8074v1(): API to get_8074v1 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_8074v1(): API to get_8074v1 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static uint16_t hal_rx_msdu_end_sa_idx_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_8074v1() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_8074v1(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_8074v1(): API to get_8074v1 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_8074v1: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_8074v1: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_8074v1: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t +hal_rx_msdu_end_first_msdu_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_8074v1: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_8074v1: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_8074v1(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_8074v1: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/* + * hal_rx_mpdu_get_to_ds_8074v1(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ + +static uint32_t hal_rx_mpdu_get_to_ds_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_8074v1(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_8074v1(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_8074v1(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_8074v1(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_8074v1(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_8074v1(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_8074v1(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_8074v1(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_8074v1(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_8074v1(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_8074v1(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_8074v1: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_8074v1: get tid based on qos control valid. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_8074v1(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_8074(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_8074v1(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_8074v1(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_8074v1 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_8074v1(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v1(): + * Retrieve qos control valid bit from the tlv. + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ +static inline uint32_t +hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get_8074v1(): API to get the + * sa_sw_peer_id from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: sa_sw_peer_id index + */ +static inline uint32_t +hal_rx_msdu_end_sa_sw_peer_id_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +/** + * hal_tx_desc_set_mesh_en_8074v1 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_8074v1(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_4, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_8074v1(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_8074v1(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_8074v1(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_8074v1(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_8074v1(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_8074v1(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_8074v1(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_8074v1(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_8074v1(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_8074v1(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static void +hal_reo_config_8074v1(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_8074v1() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_8074v1(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_8074v1 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_8074v1(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_8074v1: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_8074v1: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_8074v1: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_8074v1: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_8074v1: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_8074v1: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_8074v1(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_8074v1() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_8074v1(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_8074v1(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_8074v1(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { @@ -113,6 +993,7 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_8074, NULL, /* tx */ @@ -123,9 +1004,11 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { hal_tx_desc_set_buf_addr_generic, hal_tx_desc_set_search_type_generic, hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, hal_tx_comp_get_status_generic, hal_tx_comp_get_release_reason_generic, - + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_8074v1, /* rx */ hal_rx_msdu_start_nss_get_8074, hal_rx_mon_hw_desc_get_mpdu_status_8074, @@ -137,9 +1020,9 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { hal_rx_mpdu_start_tid_get_8074, hal_rx_msdu_start_reception_type_get_8074, hal_rx_msdu_end_da_idx_get_8074, - hal_rx_msdu_desc_info_get_ptr_generic, - hal_rx_link_desc_msdu0_ptr_generic, - hal_reo_status_get_header_generic, + hal_rx_msdu_desc_info_get_ptr_8074v1, + hal_rx_link_desc_msdu0_ptr_8074v1, + hal_reo_status_get_header_8074v1, hal_rx_status_get_tlv_info_generic, hal_rx_wbm_err_info_get_generic, hal_rx_dump_mpdu_start_tlv_generic, @@ -147,6 +1030,60 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { hal_tx_set_pcp_tid_map_generic, hal_tx_update_pcp_tid_generic, hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_8074v1, + hal_rx_msdu_end_da_is_mcbc_get_8074v1, + hal_rx_msdu_end_sa_is_valid_get_8074v1, + hal_rx_msdu_end_sa_idx_get_8074v1, + hal_rx_desc_is_first_msdu_8074v1, + hal_rx_msdu_end_l3_hdr_padding_get_8074v1, + hal_rx_encryption_info_valid_8074v1, + hal_rx_print_pn_8074v1, + hal_rx_msdu_end_first_msdu_get_8074v1, + hal_rx_msdu_end_da_is_valid_get_8074v1, + hal_rx_msdu_end_last_msdu_get_8074v1, + hal_rx_get_mpdu_mac_ad4_valid_8074v1, + hal_rx_mpdu_start_sw_peer_id_get_8074v1, + hal_rx_mpdu_get_to_ds_8074v1, + hal_rx_mpdu_get_fr_ds_8074v1, + hal_rx_get_mpdu_frame_control_valid_8074v1, + hal_rx_mpdu_get_addr1_8074v1, + hal_rx_mpdu_get_addr2_8074v1, + hal_rx_mpdu_get_addr3_8074v1, + hal_rx_mpdu_get_addr4_8074v1, + hal_rx_get_mpdu_sequence_control_valid_8074v1, + hal_rx_is_unicast_8074v1, + hal_rx_tid_get_8074v1, + hal_rx_hw_desc_get_ppduid_get_8074v1, + hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v1, + hal_rx_msdu_end_sa_sw_peer_id_get_8074v1, + hal_rx_msdu0_buffer_addr_lsb_8074v1, + hal_rx_msdu_desc_info_ptr_get_8074v1, + hal_ent_mpdu_desc_info_8074v1, + hal_dst_mpdu_desc_info_8074v1, + hal_rx_get_fc_valid_8074v1, + hal_rx_get_to_ds_flag_8074v1, + hal_rx_get_mac_addr2_valid_8074v1, + hal_rx_get_filter_category_8074v1, + hal_rx_get_ppdu_id_8074v1, + hal_reo_config_8074v1, + hal_rx_msdu_flow_idx_get_8074v1, + hal_rx_msdu_flow_idx_invalid_8074v1, + hal_rx_msdu_flow_idx_timeout_8074v1, + hal_rx_msdu_fse_metadata_get_8074v1, + hal_rx_msdu_cce_metadata_get_8074v1, + hal_rx_msdu_get_flow_params_8074v1, + hal_rx_tlv_get_tcp_chksum_8074v1, + hal_rx_get_rx_sequence_8074v1, + NULL, + NULL, + /* rx - msdu fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, }; struct hal_hw_srng_config hw_srng_table_8074[] = { diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_rx.h index 597ab7b782c4a1c04939acf908b31224fba674b2..6df3e2d79928ab6328aafa2825c7d904a13c89e9 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,6 +24,309 @@ #include "dp_types.h" #include "hal_api_mon.h" +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_5_DA_IS_MCBC_MASK, \ + RX_MSDU_END_5_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_SA_IS_VALID_MASK, \ + RX_MSDU_END_5_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_SA_IDX_OFFSET)), \ + RX_MSDU_END_13_SA_IDX_MASK, \ + RX_MSDU_END_13_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_5_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_5_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_4_PN_31_0_MASK, \ + RX_MPDU_INFO_4_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_5_PN_63_32_MASK, \ + RX_MPDU_INFO_5_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_6_PN_95_64_MASK, \ + RX_MPDU_INFO_6_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_7_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_7_PN_127_96_MASK, \ + RX_MPDU_INFO_7_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_5_FIRST_MSDU_MASK, \ + RX_MSDU_END_5_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_DA_IS_VALID_MASK, \ + RX_MSDU_END_5_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_5_LAST_MSDU_MASK, \ + RX_MSDU_END_5_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_1_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_1_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_TO_DS_OFFSET)), \ + RX_MPDU_INFO_2_TO_DS_MASK, \ + RX_MPDU_INFO_2_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FR_DS_OFFSET)), \ + RX_MPDU_INFO_2_FR_DS_MASK, \ + RX_MPDU_INFO_2_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_16_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_16_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | \ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring) | \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET),\ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR((msdu_details_ptr), \ +UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_14_FLOW_IDX_MASK, \ + RX_MSDU_END_14_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_15_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_15_FSE_METADATA_MASK, \ + RX_MSDU_END_15_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_16_CCE_METADATA_MASK, \ + RX_MSDU_END_16_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB)) + /* * hal_rx_msdu_start_nss_get_8074(): API to get the NSS * Interval from rx_msdu_start diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_tx.h index 1ae1ef3d97c196acd9b18e30974f844a5afcdc49..b051e18c8bf352ea79f407cc1f15f714a2beaae2 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v1/hal_8074v1_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,15 +54,13 @@ static void hal_tx_desc_set_dscp_tid_table_id_8074(void *desc, uint8_t id) * * Return: none */ -static void hal_tx_set_dscp_tid_map_8074(void *hal_soc, uint8_t *map, +static void hal_tx_set_dscp_tid_map_8074(struct hal_soc *soc, uint8_t *map, uint8_t id) { int i; uint32_t addr; uint32_t value; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) { addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); @@ -102,7 +100,7 @@ static void hal_tx_set_dscp_tid_map_8074(void *hal_soc, uint8_t *map, * Return: void */ static -void hal_tx_update_dscp_tid_8074(void *hal_soc, uint8_t tid, +void hal_tx_update_dscp_tid_8074(struct hal_soc *soc, uint8_t tid, uint8_t id, uint8_t dscp) { int index; @@ -110,8 +108,6 @@ void hal_tx_update_dscp_tid_8074(void *hal_soc, uint8_t tid, uint32_t value; uint32_t regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2.c index 0b107786b03a55229a5790b0580115eedb4eb809..0fa5fac63d8c9b061a5626502b069f39dc2c7399 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2.c +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -105,6 +105,884 @@ #include #include +/** + * hal_rx_get_rx_fragment_number_8074v2(): Function to retrieve + * rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK; +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_8074v2: API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_8074v2(): API to get_8074v2 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_8074v2(): API to get_8074v2 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static uint16_t hal_rx_msdu_end_sa_idx_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_8074v2() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_8074v2(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_8074v2(): API to get_8074v2 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/* + * @ hal_rx_encryption_info_valid_8074v2: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +static uint32_t hal_rx_encryption_info_valid_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_8074v2: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_8074v2: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t hal_rx_msdu_end_first_msdu_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_8074v2: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_8074v2: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid_8074v2(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +static bool hal_rx_get_mpdu_mac_ad4_valid_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_GET_MAC_AD4_VALID(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_8074v2: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/* + * hal_rx_mpdu_get_to_ds_8074v2(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ +static uint32_t hal_rx_mpdu_get_to_ds_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_8074v2(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_8074v2(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_8074v2(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_8074v2(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_8074v2(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_8074v2(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_8074v2(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_8074v2(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_8074v2(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_8074v2(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_8074v2(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_8074v2: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_0_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_8074v2: get tid based on qos control valid. + * @hal_soc_hdl: hal soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_8074v2(hal_soc_handle_t hal_soc_hdl, + uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_8074v2(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_8074v2(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_8074v2(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_8074v2 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_8074v2(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v2(): + * Retrieve qos control valid bit from the tlv. + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ +static inline uint32_t +hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get_8074v2(): API to get the + * sa_sw_peer_id from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: sa_sw_peer_id index + */ +static inline uint32_t +hal_rx_msdu_end_sa_sw_peer_id_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +/** + * hal_tx_desc_set_mesh_en_8074v2 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_8074v2(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_4, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_8074v2(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_8074v2(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_8074v2(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_8074v2(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_8074v2(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_8074v2(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_8074v2(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_8074v2(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_8074v2(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_8074v2(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static void +hal_reo_config_8074v2(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_8074v2() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_8074v2(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_8074v2 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_8074v2(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_8074v2: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_8074v2: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_8074v2: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_8074v2: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_8074v2: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_8074v2: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_8074v2(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_8074v2() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_8074v2(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_8074v2(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_8074v2(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_8074v2(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_8074v2(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { /* init and setup */ @@ -113,6 +991,7 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_8074v2, NULL, /* tx */ @@ -123,8 +1002,11 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { hal_tx_desc_set_buf_addr_generic, hal_tx_desc_set_search_type_generic, hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, hal_tx_comp_get_status_generic, hal_tx_comp_get_release_reason_generic, + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_8074v2, /* rx */ hal_rx_msdu_start_nss_get_8074v2, @@ -137,9 +1019,9 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { hal_rx_mpdu_start_tid_get_8074v2, hal_rx_msdu_start_reception_type_get_8074v2, hal_rx_msdu_end_da_idx_get_8074v2, - hal_rx_msdu_desc_info_get_ptr_generic, - hal_rx_link_desc_msdu0_ptr_generic, - hal_reo_status_get_header_generic, + hal_rx_msdu_desc_info_get_ptr_8074v2, + hal_rx_link_desc_msdu0_ptr_8074v2, + hal_reo_status_get_header_8074v2, hal_rx_status_get_tlv_info_generic, hal_rx_wbm_err_info_get_generic, hal_rx_dump_mpdu_start_tlv_generic, @@ -147,6 +1029,66 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { hal_tx_set_pcp_tid_map_generic, hal_tx_update_pcp_tid_generic, hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_8074v2, + hal_rx_msdu_end_da_is_mcbc_get_8074v2, + hal_rx_msdu_end_sa_is_valid_get_8074v2, + hal_rx_msdu_end_sa_idx_get_8074v2, + hal_rx_desc_is_first_msdu_8074v2, + hal_rx_msdu_end_l3_hdr_padding_get_8074v2, + hal_rx_encryption_info_valid_8074v2, + hal_rx_print_pn_8074v2, + hal_rx_msdu_end_first_msdu_get_8074v2, + hal_rx_msdu_end_da_is_valid_get_8074v2, + hal_rx_msdu_end_last_msdu_get_8074v2, + hal_rx_get_mpdu_mac_ad4_valid_8074v2, + hal_rx_mpdu_start_sw_peer_id_get_8074v2, + hal_rx_mpdu_get_to_ds_8074v2, + hal_rx_mpdu_get_fr_ds_8074v2, + hal_rx_get_mpdu_frame_control_valid_8074v2, + hal_rx_mpdu_get_addr1_8074v2, + hal_rx_mpdu_get_addr2_8074v2, + hal_rx_mpdu_get_addr3_8074v2, + hal_rx_mpdu_get_addr4_8074v2, + hal_rx_get_mpdu_sequence_control_valid_8074v2, + hal_rx_is_unicast_8074v2, + hal_rx_tid_get_8074v2, + hal_rx_hw_desc_get_ppduid_get_8074v2, + hal_rx_mpdu_start_mpdu_qos_control_valid_get_8074v2, + hal_rx_msdu_end_sa_sw_peer_id_get_8074v2, + hal_rx_msdu0_buffer_addr_lsb_8074v2, + hal_rx_msdu_desc_info_ptr_get_8074v2, + hal_ent_mpdu_desc_info_8074v2, + hal_dst_mpdu_desc_info_8074v2, + hal_rx_get_fc_valid_8074v2, + hal_rx_get_to_ds_flag_8074v2, + hal_rx_get_mac_addr2_valid_8074v2, + hal_rx_get_filter_category_8074v2, + hal_rx_get_ppdu_id_8074v2, + hal_reo_config_8074v2, + hal_rx_msdu_flow_idx_get_8074v2, + hal_rx_msdu_flow_idx_invalid_8074v2, + hal_rx_msdu_flow_idx_timeout_8074v2, + hal_rx_msdu_fse_metadata_get_8074v2, + hal_rx_msdu_cce_metadata_get_8074v2, + hal_rx_msdu_get_flow_params_8074v2, + hal_rx_tlv_get_tcp_chksum_8074v2, + hal_rx_get_rx_sequence_8074v2, +#if defined(QCA_WIFI_QCA6018) && defined(WLAN_CFR_ENABLE) && \ + defined(WLAN_ENH_CFR_ENABLE) + hal_rx_get_bb_info_8074v2, + hal_rx_get_rtt_info_8074v2, +#else + NULL, + NULL, +#endif + /* rx - msdu fast path info fields */ + hal_rx_msdu_packet_metadata_get_generic, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, }; struct hal_hw_srng_config hw_srng_table_8074v2[] = { @@ -603,6 +1545,3 @@ void hal_qca8074v2_attach(struct hal_soc *hal_soc) hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca8074v2; hal_soc->ops = &qca8074v2_hal_hw_txrx_ops; } - - - diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h index a9bd0430300c225cbdb76edef07c5bd81eb925b5..8ceae38232775f6d6a8f646515f388737d7e2a09 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,12 +23,319 @@ #include "hal_tx.h" #include "dp_types.h" #include "hal_api_mon.h" +#ifndef QCA_WIFI_QCA6018 +#include "phyrx_other_receive_info_su_evm_details.h" +#endif + +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_5_DA_IS_MCBC_MASK, \ + RX_MSDU_END_5_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_SA_IS_VALID_MASK, \ + RX_MSDU_END_5_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_SA_IDX_OFFSET)), \ + RX_MSDU_END_13_SA_IDX_MASK, \ + RX_MSDU_END_13_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_5_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_5_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_2_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_4_PN_31_0_MASK, \ + RX_MPDU_INFO_4_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_5_PN_63_32_MASK, \ + RX_MPDU_INFO_5_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_6_PN_95_64_MASK, \ + RX_MPDU_INFO_6_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_7_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_7_PN_127_96_MASK, \ + RX_MPDU_INFO_7_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_5_FIRST_MSDU_MASK, \ + RX_MSDU_END_5_FIRST_MSDU_LSB)) #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_5_DA_IS_VALID_MASK, \ + RX_MSDU_END_5_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_5_LAST_MSDU_MASK, \ + RX_MSDU_END_5_LAST_MSDU_LSB)) + +#define HAL_RX_MPDU_GET_MAC_AD4_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_1_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_1_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_TO_DS_OFFSET)), \ + RX_MPDU_INFO_2_TO_DS_MASK, \ + RX_MPDU_INFO_2_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_FR_DS_OFFSET)), \ + RX_MPDU_INFO_2_FR_DS_MASK, \ + RX_MPDU_INFO_2_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_2_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_2_MPDU_QOS_CONTROL_VALID_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_16_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_16_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + (uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + (uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + (uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + (uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_2, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | \ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring) | \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR((msdu_details_ptr), \ +UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_14_FLOW_IDX_MASK, \ + RX_MSDU_END_14_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_5_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_5_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_15_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_15_FSE_METADATA_MASK, \ + RX_MSDU_END_15_FSE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_16_CCE_METADATA_MASK, \ + RX_MSDU_END_16_CCE_METADATA_LSB)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_1_TCP_UDP_CHKSUM_LSB)) + /* * hal_rx_msdu_start_nss_get_8074v2(): API to get the NSS * Interval from rx_msdu_start @@ -101,6 +408,52 @@ static uint8_t hal_rx_get_tlv_8074v2(void *rx_tlv) return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); } +#ifndef QCA_WIFI_QCA6018 +#define HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, evm, pilot) \ + (ppdu_info)->evm_info.pilot_evm[pilot] = HAL_RX_GET(rx_tlv, \ + PHYRX_OTHER_RECEIVE_INFO, \ + SU_EVM_DETAILS_##evm##_PILOT_##pilot##_EVM) + +static inline void +hal_rx_update_su_evm_info(void *rx_tlv, + void *ppdu_info_hdl) +{ + struct hal_rx_ppdu_info *ppdu_info = + (struct hal_rx_ppdu_info *)ppdu_info_hdl; + + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 1, 0); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 2, 1); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 3, 2); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 4, 3); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 5, 4); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 6, 5); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 7, 6); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 8, 7); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 9, 8); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 10, 9); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 11, 10); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 12, 11); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 13, 12); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 14, 13); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 15, 14); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 16, 15); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 17, 16); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 18, 17); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 19, 18); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 20, 19); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 21, 20); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 22, 21); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 23, 22); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 24, 23); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 25, 24); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 26, 25); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 27, 26); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 28, 27); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 29, 28); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 30, 29); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 31, 30); + HAL_RX_UPDATE_SU_EVM_INFO(rx_tlv, ppdu_info, 32, 31); +} /** * hal_rx_proc_phyrx_other_receive_info_tlv_8074v2() * -process other receive info TLV @@ -111,10 +464,89 @@ static uint8_t hal_rx_get_tlv_8074v2(void *rx_tlv) */ static void hal_rx_proc_phyrx_other_receive_info_tlv_8074v2(void *rx_tlv_hdr, - void *ppdu_info) + void *ppdu_info_hdl) { + uint16_t tlv_tag; + void *rx_tlv; + struct hal_rx_ppdu_info *ppdu_info = ppdu_info_hdl; + + /* Skip TLV_HDR for OTHER_RECEIVE_INFO and follows the + * embedded TLVs inside + */ + rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); + + switch (tlv_tag) { + case WIFIPHYRX_OTHER_RECEIVE_INFO_SU_EVM_DETAILS_E: + + /* Skip TLV length to get TLV content */ + rx_tlv = (uint8_t *)rx_tlv + HAL_RX_TLV32_HDR_SIZE; + + ppdu_info->evm_info.number_of_symbols = HAL_RX_GET(rx_tlv, + PHYRX_OTHER_RECEIVE_INFO, + SU_EVM_DETAILS_0_NUMBER_OF_SYMBOLS); + ppdu_info->evm_info.pilot_count = HAL_RX_GET(rx_tlv, + PHYRX_OTHER_RECEIVE_INFO, + SU_EVM_DETAILS_0_PILOT_COUNT); + ppdu_info->evm_info.nss_count = HAL_RX_GET(rx_tlv, + PHYRX_OTHER_RECEIVE_INFO, + SU_EVM_DETAILS_0_NSS_COUNT); + hal_rx_update_su_evm_info(rx_tlv, ppdu_info_hdl); + break; + } +} +#else +static inline +void hal_rx_proc_phyrx_other_receive_info_tlv_8074v2(void *rx_tlv_hdr, + void *ppdu_info_hdl) +{ +} +#endif + +#if defined(QCA_WIFI_QCA6018) && defined(WLAN_CFR_ENABLE) && \ + defined(WLAN_ENH_CFR_ENABLE) +static inline +void hal_rx_get_bb_info_8074v2(void *rx_tlv, + void *ppdu_info_hdl) +{ + struct hal_rx_ppdu_info *ppdu_info = ppdu_info_hdl; + + ppdu_info->cfr_info.bb_captured_channel = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_CHANNEL); + + ppdu_info->cfr_info.bb_captured_timeout = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_TIMEOUT); + + ppdu_info->cfr_info.bb_captured_reason = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_REASON); } +static inline +void hal_rx_get_rtt_info_8074v2(void *rx_tlv, + void *ppdu_info_hdl) +{ + struct hal_rx_ppdu_info *ppdu_info = ppdu_info_hdl; + + ppdu_info->cfr_info.rx_location_info_valid = + HAL_RX_GET(rx_tlv, PHYRX_PKT_END_13_RX_PKT_END_DETAILS, + RX_LOCATION_INFO_DETAILS_RX_LOCATION_INFO_VALID); + + ppdu_info->cfr_info.rtt_che_buffer_pointer_low32 = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_12_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RTT_CHE_BUFFER_POINTER_LOW32); + + ppdu_info->cfr_info.rtt_che_buffer_pointer_high8 = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_11_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RTT_CHE_BUFFER_POINTER_HIGH8); + + ppdu_info->cfr_info.chan_capture_status = + HAL_RX_GET(rx_tlv, + PHYRX_PKT_END_13_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS, + RESERVED_8); +} +#endif /** * hal_rx_dump_msdu_start_tlv_8074v2() : dump RX msdu_start TLV in structured @@ -368,4 +800,3 @@ static uint16_t hal_rx_msdu_end_da_idx_get_8074v2(uint8_t *buf) return da_idx; } - diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_tx.h index b95b4535f32781f7d4953d49e7933a889b6adb98..4cde5a5d1cae430c7aee13d1c2021b9520c1bd17 100644 --- a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_tx.h +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca8074v2/hal_8074v2_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -59,16 +59,15 @@ static void hal_tx_desc_set_dscp_tid_table_id_8074v2(void *desc, uint8_t id) * Return: none */ -static void hal_tx_set_dscp_tid_map_8074v2(void *hal_soc, uint8_t *map, - uint8_t id) +static void hal_tx_set_dscp_tid_map_8074v2(struct hal_soc *soc, + uint8_t *map, + uint8_t id) { int i; uint32_t addr, cmn_reg_addr; uint32_t value = 0, regval; uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; - struct hal_soc *soc = (struct hal_soc *)hal_soc; - if (id >= HAL_MAX_HW_DSCP_TID_V2_MAPS) return; @@ -97,7 +96,7 @@ static void hal_tx_set_dscp_tid_map_8074v2(void *hal_soc, uint8_t *map, (map[i + 6] << 0x12) | (map[i + 7] << 0x15)); - qdf_mem_copy(&val[cnt], (void *)&value, 3); + qdf_mem_copy(&val[cnt], &value, 3); cnt += 3; } @@ -126,13 +125,12 @@ static void hal_tx_set_dscp_tid_map_8074v2(void *hal_soc, uint8_t *map, * * Return: void */ -static void hal_tx_update_dscp_tid_8074v2(void *hal_soc, uint8_t tid, - uint8_t id, uint8_t dscp) +static void hal_tx_update_dscp_tid_8074v2(struct hal_soc *soc, uint8_t tid, + uint8_t id, uint8_t dscp) { uint32_t addr, addr1, cmn_reg_addr; uint32_t start_value = 0, end_value = 0; uint32_t regval; - struct hal_soc *soc = (struct hal_soc *)hal_soc; uint8_t end_bits = 0; uint8_t start_bits = 0; uint32_t start_index, end_index; diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000.c b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000.c new file mode 100644 index 0000000000000000000000000000000000000000..41272e9b08177f644015efec91fa9fd0a7ad9001 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000.c @@ -0,0 +1,1927 @@ +/* + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "hal_api.h" +#include "target_type.h" +#include "wcss_version.h" +#include "qdf_module.h" +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_OFFSET \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_OFFSET +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_MASK \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_MASK +#define UNIFIED_RXPCU_PPDU_END_INFO_8_RX_PPDU_DURATION_LSB \ + RXPCU_PPDU_END_INFO_9_RX_PPDU_DURATION_LSB +#define UNIFIED_PHYRX_HT_SIG_0_HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS_OFFSET \ + PHYRX_HT_SIG_0_PHYRX_HT_SIG_INFO_DETAILS_MCS_OFFSET +#define UNIFIED_PHYRX_L_SIG_B_0_L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_B_0_PHYRX_L_SIG_B_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_L_SIG_A_0_L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_L_SIG_A_0_PHYRX_L_SIG_A_INFO_DETAILS_RATE_OFFSET +#define UNIFIED_PHYRX_VHT_SIG_A_0_VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS_OFFSET \ + PHYRX_VHT_SIG_A_0_PHYRX_VHT_SIG_A_INFO_DETAILS_BANDWIDTH_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_SU_0_HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_SU_0_PHYRX_HE_SIG_A_SU_INFO_DETAILS_FORMAT_INDICATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_A_MU_DL_0_HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_A_MU_DL_0_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS_DL_UL_FLAG_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B1_MU_0_HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B1_MU_0_PHYRX_HE_SIG_B1_MU_INFO_DETAILS_RU_ALLOCATION_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_MU_0_HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_MU_0_PHYRX_HE_SIG_B2_MU_INFO_DETAILS_STA_ID_OFFSET +#define UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0_HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_OFFSET \ + PHYRX_HE_SIG_B2_OFDMA_0_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS_STA_ID_OFFSET +#define UNIFIED_PHYRX_RSSI_LEGACY_3_RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_3_PRE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET +#define UNIFIED_PHYRX_RSSI_LEGACY_19_RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS_OFFSET \ + PHYRX_RSSI_LEGACY_19_PREAMBLE_RSSI_INFO_DETAILS_RSSI_PRI20_CHAIN0_OFFSET +#define UNIFIED_RX_MPDU_START_0_RX_MPDU_INFO_RX_MPDU_INFO_DETAILS_OFFSET \ + RX_MPDU_START_9_RX_MPDU_INFO_DETAILS_RXPCU_MPDU_FILTER_IN_CATEGORY_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET +#define UNIFIED_RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET +#define UNIFIED_REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_RX_MPDU_DESC_INFO_DETAILS_OFFSET \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET +#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER \ + STATUS_HEADER_REO_STATUS_NUMBER +#define UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC \ + STATUS_HEADER_TIMESTAMP +#define UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET +#define UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_0_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_0_BUF_ADDR_INFO_BUFFER_ADDR_31_0_OFFSET +#define UNIFIED_TCL_DATA_CMD_1_BUFFER_ADDR_INFO_BUF_ADDR_INFO_OFFSET \ + TCL_DATA_CMD_1_BUF_ADDR_INFO_BUFFER_ADDR_39_32_OFFSET +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_OFFSET +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB +#define UNIFIED_BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK \ + BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK \ + BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK \ + BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_LSB +#define UNIFIED_BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK \ + BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_MASK +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_LSB +#define UNIFIED_TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK \ + TCL_DATA_CMD_2_BUF_OR_EXT_DESC_TYPE_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_MASK \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_MASK +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_OFFSET \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_OFFSET +#define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \ + WBM_RELEASE_RING_6_TX_RATE_STATS_PPDU_TRANSMISSION_TSF_LSB + +#define CE_WINDOW_ADDRESS_9000 \ + ((CE_WFSS_CE_REG_BASE >> WINDOW_SHIFT) & WINDOW_VALUE_MASK) + +#define UMAC_WINDOW_ADDRESS_9000 \ + ((SEQ_WCSS_UMAC_OFFSET >> WINDOW_SHIFT) & WINDOW_VALUE_MASK) + +#define WINDOW_CONFIGURATION_VALUE_9000 \ + ((CE_WINDOW_ADDRESS_9000 << 6) |\ + (UMAC_WINDOW_ADDRESS_9000 << 12) | \ + WINDOW_ENABLE_BIT) + +#include +#include +#include +#include + +/** + * hal_rx_msdu_start_nss_get_9000(): API to get the NSS + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +static uint32_t hal_rx_msdu_start_nss_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint8_t mimo_ss_bitmap; + + mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); + + return qdf_get_hweight8(mimo_ss_bitmap); +} + +/** + * hal_rx_mon_hw_desc_get_mpdu_status_9000(): Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +static void hal_rx_mon_hw_desc_get_mpdu_status_9000(void *hw_desc_addr, + struct mon_rx_status *rs) +{ + struct rx_msdu_start *rx_msdu_start; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + uint32_t reg_value; + const uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; + + rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; + + HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); + + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, + RX_MSDU_START_5, USER_RSSI); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ +} + +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) +/** + * hal_get_link_desc_size_9000(): API to get the link desc size + * + * Return: uint32_t + */ +static uint32_t hal_get_link_desc_size_9000(void) +{ + return LINK_DESC_SIZE; +} + +/** + * hal_rx_get_tlv_9000(): API to get the tlv + * + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +static uint8_t hal_rx_get_tlv_9000(void *rx_tlv) +{ + return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); +} + +/** + * hal_rx_proc_phyrx_other_receive_info_tlv_9000(): API to get tlv info + * + * Return: uint32_t + */ +static inline +void hal_rx_proc_phyrx_other_receive_info_tlv_9000(void *rx_tlv_hdr, + void *ppdu_info_hdl) +{ +} + +/** + * hal_rx_dump_msdu_start_tlv_9000() : dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_start_tlv_9000(void *msdustart, + uint8_t dbg_level) +{ + struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; + + QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, + "rx_msdu_start tlv - " + "rxpcu_mpdu_filter_in_category: %d " + "sw_frame_group_id: %d " + "phy_ppdu_id: %d " + "msdu_length: %d " + "ipsec_esp: %d " + "l3_offset: %d " + "ipsec_ah: %d " + "l4_offset: %d " + "msdu_number: %d " + "decap_format: %d " + "ipv4_proto: %d " + "ipv6_proto: %d " + "tcp_proto: %d " + "udp_proto: %d " + "ip_frag: %d " + "tcp_only_ack: %d " + "da_is_bcast_mcast: %d " + "ip4_protocol_ip6_next_header: %d " + "toeplitz_hash_2_or_4: %d " + "flow_id_toeplitz: %d " + "user_rssi: %d " + "pkt_type: %d " + "stbc: %d " + "sgi: %d " + "rate_mcs: %d " + "receive_bandwidth: %d " + "reception_type: %d " + "ppdu_start_timestamp: %d " + "sw_phy_meta_data: %d ", + msdu_start->rxpcu_mpdu_filter_in_category, + msdu_start->sw_frame_group_id, + msdu_start->phy_ppdu_id, + msdu_start->msdu_length, + msdu_start->ipsec_esp, + msdu_start->l3_offset, + msdu_start->ipsec_ah, + msdu_start->l4_offset, + msdu_start->msdu_number, + msdu_start->decap_format, + msdu_start->ipv4_proto, + msdu_start->ipv6_proto, + msdu_start->tcp_proto, + msdu_start->udp_proto, + msdu_start->ip_frag, + msdu_start->tcp_only_ack, + msdu_start->da_is_bcast_mcast, + msdu_start->ip4_protocol_ip6_next_header, + msdu_start->toeplitz_hash_2_or_4, + msdu_start->flow_id_toeplitz, + msdu_start->user_rssi, + msdu_start->pkt_type, + msdu_start->stbc, + msdu_start->sgi, + msdu_start->rate_mcs, + msdu_start->receive_bandwidth, + msdu_start->reception_type, + msdu_start->ppdu_start_timestamp, + msdu_start->sw_phy_meta_data); +} + +/** + * hal_rx_dump_msdu_end_tlv_9000: dump RX msdu_end TLV in structured + * human readable format. + * @ msdu_end: pointer the msdu_end TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static void hal_rx_dump_msdu_end_tlv_9000(void *msduend, + uint8_t dbg_level) +{ + struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend; + + QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, + "rx_msdu_end tlv - " + "rxpcu_mpdu_filter_in_category: %d " + "sw_frame_group_id: %d " + "phy_ppdu_id: %d " + "ip_hdr_chksum: %d " + "reported_mpdu_length: %d " + "key_id_octet: %d " + "cce_super_rule: %d " + "cce_classify_not_done_truncat: %d " + "cce_classify_not_done_cce_dis: %d " + "rule_indication_31_0: %d " + "rule_indication_63_32: %d " + "da_offset: %d " + "sa_offset: %d " + "da_offset_valid: %d " + "sa_offset_valid: %d " + "ipv6_options_crc: %d " + "tcp_seq_number: %d " + "tcp_ack_number: %d " + "tcp_flag: %d " + "lro_eligible: %d " + "window_size: %d " + "tcp_udp_chksum: %d " + "sa_idx_timeout: %d " + "da_idx_timeout: %d " + "msdu_limit_error: %d " + "flow_idx_timeout: %d " + "flow_idx_invalid: %d " + "wifi_parser_error: %d " + "amsdu_parser_error: %d " + "sa_is_valid: %d " + "da_is_valid: %d " + "da_is_mcbc: %d " + "l3_header_padding: %d " + "first_msdu: %d " + "last_msdu: %d " + "sa_idx: %d " + "msdu_drop: %d " + "reo_destination_indication: %d " + "flow_idx: %d " + "fse_metadata: %d " + "cce_metadata: %d " + "sa_sw_peer_id: %d ", + msdu_end->rxpcu_mpdu_filter_in_category, + msdu_end->sw_frame_group_id, + msdu_end->phy_ppdu_id, + msdu_end->ip_hdr_chksum, + msdu_end->reported_mpdu_length, + msdu_end->key_id_octet, + msdu_end->cce_super_rule, + msdu_end->cce_classify_not_done_truncate, + msdu_end->cce_classify_not_done_cce_dis, + msdu_end->rule_indication_31_0, + msdu_end->rule_indication_63_32, + msdu_end->da_offset, + msdu_end->sa_offset, + msdu_end->da_offset_valid, + msdu_end->sa_offset_valid, + msdu_end->ipv6_options_crc, + msdu_end->tcp_seq_number, + msdu_end->tcp_ack_number, + msdu_end->tcp_flag, + msdu_end->lro_eligible, + msdu_end->window_size, + msdu_end->tcp_udp_chksum, + msdu_end->sa_idx_timeout, + msdu_end->da_idx_timeout, + msdu_end->msdu_limit_error, + msdu_end->flow_idx_timeout, + msdu_end->flow_idx_invalid, + msdu_end->wifi_parser_error, + msdu_end->amsdu_parser_error, + msdu_end->sa_is_valid, + msdu_end->da_is_valid, + msdu_end->da_is_mcbc, + msdu_end->l3_header_padding, + msdu_end->first_msdu, + msdu_end->last_msdu, + msdu_end->sa_idx, + msdu_end->msdu_drop, + msdu_end->reo_destination_indication, + msdu_end->flow_idx, + msdu_end->fse_metadata, + msdu_end->cce_metadata, + msdu_end->sa_sw_peer_id); +} + +/** + * hal_rx_mpdu_start_tid_get_9000(): API to get tid + * from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(tid value) + */ +static uint32_t hal_rx_mpdu_start_tid_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t tid; + + tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); + + return tid; +} + +/** + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +static uint32_t hal_rx_msdu_start_reception_type_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + + /** + * hal_rx_msdu_end_da_idx_get_9000: API to get da_idx + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da index + */ +static uint16_t hal_rx_msdu_end_da_idx_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t da_idx; + + da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); + + return da_idx; +} + +/** + * hal_rx_get_rx_fragment_number_9000(): Function to retrieve rx fragment number + * + * @nbuf: Network buffer + * Returns: rx fragment number + */ +static +uint8_t hal_rx_get_rx_fragment_number_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + /* Return first 4 bits as fragment number */ + return (HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) & + DOT11_SEQ_FRAG_MASK); +} + +/** + * hal_rx_msdu_end_da_is_mcbc_get_9000(): API to check if pkt is MCBC + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_mcbc + */ +static uint8_t +hal_rx_msdu_end_da_is_mcbc_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end); +} + +/** + * hal_rx_msdu_end_sa_is_valid_get_9000(): API to get_9000 the + * sa_is_valid bit from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_is_valid bit + */ +static uint8_t +hal_rx_msdu_end_sa_is_valid_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t sa_is_valid; + + sa_is_valid = HAL_RX_MSDU_END_SA_IS_VALID_GET(msdu_end); + + return sa_is_valid; +} + +/** + * hal_rx_msdu_end_sa_idx_get_9000(): API to get_9000 the + * sa_idx from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: sa_idx (SA AST index) + */ +static uint16_t hal_rx_msdu_end_sa_idx_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint16_t sa_idx; + + sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + + return sa_idx; +} + +/** + * hal_rx_desc_is_first_msdu_9000() - Check if first msdu + * + * @hal_soc_hdl: hal_soc handle + * @hw_desc_addr: hardware descriptor address + * + * Return: 0 - success/ non-zero failure + */ +static uint32_t hal_rx_desc_is_first_msdu_9000(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_10, FIRST_MSDU); +} + +/** + * hal_rx_msdu_end_l3_hdr_padding_get_9000(): API to get_9000 the + * l3_header padding from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: number of l3 header padding bytes + */ +static uint32_t hal_rx_msdu_end_l3_hdr_padding_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t l3_header_padding; + + l3_header_padding = HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + + return l3_header_padding; +} + +/** + * @ hal_rx_encryption_info_valid_9000: Returns encryption type. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: encryption type + */ +inline uint32_t hal_rx_encryption_info_valid_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + uint32_t encryption_info = HAL_RX_MPDU_ENCRYPTION_INFO_VALID(mpdu_info); + + return encryption_info; +} + +/* + * @ hal_rx_print_pn_9000: Prints the PN of rx packet. + * + * @ buf: rx_tlv_hdr of the received packet + * @ Return: void + */ +static void hal_rx_print_pn_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + uint32_t pn_31_0 = HAL_RX_MPDU_PN_31_0_GET(mpdu_info); + uint32_t pn_63_32 = HAL_RX_MPDU_PN_63_32_GET(mpdu_info); + uint32_t pn_95_64 = HAL_RX_MPDU_PN_95_64_GET(mpdu_info); + uint32_t pn_127_96 = HAL_RX_MPDU_PN_127_96_GET(mpdu_info); + + hal_debug("PN number pn_127_96 0x%x pn_95_64 0x%x pn_63_32 0x%x pn_31_0 0x%x ", + pn_127_96, pn_95_64, pn_63_32, pn_31_0); +} + +/** + * hal_rx_msdu_end_first_msdu_get_9000: API to get first msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: first_msdu + */ +static uint8_t hal_rx_msdu_end_first_msdu_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t first_msdu; + + first_msdu = HAL_RX_MSDU_END_FIRST_MSDU_GET(msdu_end); + + return first_msdu; +} + +/** + * hal_rx_msdu_end_da_is_valid_get_9000: API to check if da is valid + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: da_is_valid + */ +static uint8_t hal_rx_msdu_end_da_is_valid_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t da_is_valid; + + da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end); + + return da_is_valid; +} + +/** + * hal_rx_msdu_end_last_msdu_get_9000: API to get last msdu status + * from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ +static uint8_t hal_rx_msdu_end_last_msdu_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint8_t last_msdu; + + last_msdu = HAL_RX_MSDU_END_LAST_MSDU_GET(msdu_end); + + return last_msdu; +} + +/* + * hal_rx_get_mpdu_mac_ad4_valid(): Retrieves if mpdu 4th addr is valid + * + * @nbuf: Network buffer + * Returns: value of mpdu 4th address valid field + */ +inline bool hal_rx_get_mpdu_mac_ad4_valid_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + bool ad4_valid = 0; + + ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(rx_mpdu_info); + + return ad4_valid; +} + +/** + * hal_rx_mpdu_start_sw_peer_id_get_9000: Retrieve sw peer_id + * @buf: network buffer + * + * Return: sw peer_id + */ +static uint32_t hal_rx_mpdu_start_sw_peer_id_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_SW_PEER_ID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/* + * hal_rx_mpdu_get_to_ds_9000(): API to get the tods info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(to_ds) + */ +static uint32_t hal_rx_mpdu_get_to_ds_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_TODS(mpdu_info); +} + +/* + * hal_rx_mpdu_get_fr_ds_9000(): API to get the from ds info + * from rx_mpdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(fr_ds) + */ +static uint32_t hal_rx_mpdu_get_fr_ds_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + + return HAL_RX_MPDU_GET_FROMDS(mpdu_info); +} + +/* + * hal_rx_get_mpdu_frame_control_valid_9000(): Retrieves mpdu + * frame control valid + * + * @nbuf: Network buffer + * Returns: value of frame control valid field + */ +static uint8_t hal_rx_get_mpdu_frame_control_valid_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info); +} + +/* + * hal_rx_mpdu_get_addr1_9000(): API to check get address1 of the mpdu + * + * @buf: pointer to the start of RX PKT TLV headera + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr1_9000(uint8_t *buf, + uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr1 { + uint32_t ad1_31_0; + uint16_t ad1_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr; + uint32_t mac_addr_ad1_valid; + + mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info); + + if (mac_addr_ad1_valid) { + addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info); + addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr2_9000(): API to check get address2 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr2_9000(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr2 { + uint16_t ad2_15_0; + uint32_t ad2_47_16; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr; + uint32_t mac_addr_ad2_valid; + + mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info); + + if (mac_addr_ad2_valid) { + addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info); + addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr3_9000(): API to get address3 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr3_9000(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr3 { + uint32_t ad3_31_0; + uint16_t ad3_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr3 *addr = (struct hal_addr3 *)mac_addr; + uint32_t mac_addr_ad3_valid; + + mac_addr_ad3_valid = HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(mpdu_info); + + if (mac_addr_ad3_valid) { + addr->ad3_31_0 = HAL_RX_MPDU_AD3_31_0_GET(mpdu_info); + addr->ad3_47_32 = HAL_RX_MPDU_AD3_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_mpdu_get_addr4_9000(): API to get address4 of the mpdu + * in the packet + * + * @buf: pointer to the start of RX PKT TLV header + * @mac_addr: pointer to mac address + * Return: success/failure + */ +static QDF_STATUS hal_rx_mpdu_get_addr4_9000(uint8_t *buf, uint8_t *mac_addr) +{ + struct __attribute__((__packed__)) hal_addr4 { + uint32_t ad4_31_0; + uint16_t ad4_47_32; + }; + + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details; + struct hal_addr4 *addr = (struct hal_addr4 *)mac_addr; + uint32_t mac_addr_ad4_valid; + + mac_addr_ad4_valid = HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(mpdu_info); + + if (mac_addr_ad4_valid) { + addr->ad4_31_0 = HAL_RX_MPDU_AD4_31_0_GET(mpdu_info); + addr->ad4_47_32 = HAL_RX_MPDU_AD4_47_32_GET(mpdu_info); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_E_FAILURE; +} + +/* + * hal_rx_get_mpdu_sequence_control_valid_9000(): Get mpdu + * sequence control valid + * + * @nbuf: Network buffer + * Returns: value of sequence control valid field + */ +static uint8_t hal_rx_get_mpdu_sequence_control_valid_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info); +} + +/** + * hal_rx_is_unicast_9000: check packet is unicast frame or not. + * + * @ buf: pointer to rx pkt TLV. + * + * Return: true on unicast. + */ +static bool hal_rx_is_unicast_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t grp_id; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + + grp_id = (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_OFFSET)), + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_MASK, + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_LSB)); + + return (HAL_MPDU_SW_FRAME_GROUP_UNICAST_DATA == grp_id) ? true : false; +} + +/** + * hal_rx_tid_get_9000: get tid based on qos control valid. + * @hal_soc_hdl: hal soc handle + * @buf: pointer to rx pkt TLV. + * + * Return: tid + */ +static uint32_t hal_rx_tid_get_9000(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint8_t *rx_mpdu_info = (uint8_t *)&mpdu_start->rx_mpdu_info_details; + uint8_t qos_control_valid = + (_HAL_MS((*_OFFSET_TO_WORD_PTR((rx_mpdu_info), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_OFFSET)), + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_MASK, + RX_MPDU_INFO_11_MPDU_QOS_CONTROL_VALID_LSB)); + + if (qos_control_valid) + return hal_rx_mpdu_start_tid_get_9000(buf); + + return HAL_RX_NON_QOS_TID; +} + +/** + * hal_rx_hw_desc_get_ppduid_get_9000(): retrieve ppdu id + * @hw_desc_addr: hw addr + * + * Return: ppdu id + */ +static uint32_t hal_rx_hw_desc_get_ppduid_get_9000(void *hw_desc_addr) +{ + struct rx_mpdu_info *rx_mpdu_info; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; + + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_9, PHY_PPDU_ID); +} + +/** + * hal_reo_status_get_header_9000 - Process reo desc info + * @d - Pointer to reo descriptior + * @b - tlv type info + * @h1 - Pointer to hal_reo_status_header where info to be stored + * + * Return - none. + * + */ +static void hal_reo_status_get_header_9000(uint32_t *d, int b, void *h1) +{ + uint32_t val1 = 0; + struct hal_reo_status_header *h = + (struct hal_reo_status_header *)h1; + + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->cmd_num = + HAL_GET_FIELD( + UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER, + val1); + h->exec_time = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + CMD_EXECUTION_TIME, val1); + h->status = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0, + REO_CMD_EXECUTION_STATUS, val1); + switch (b) { + case HAL_REO_QUEUE_STATS_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_FLUSH_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UNBLK_CACHE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_TIMOUT_LIST_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_DESC_THRES_STATUS_TLV: + val1 = + d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV: + val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1, + UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)]; + break; + default: + qdf_nofl_err("ERROR: Unknown tlv\n"); + break; + } + h->tstamp = + HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1); +} + +/** + * hal_rx_mpdu_start_mpdu_qos_control_valid_get_9000(): + * Retrieve qos control valid bit from the tlv. + * @buf: pointer to rx pkt TLV. + * + * Return: qos control value. + */ +static inline uint32_t +hal_rx_mpdu_start_mpdu_qos_control_valid_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + + return HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET( + &mpdu_start->rx_mpdu_info_details); +} + +/** + * hal_rx_msdu_end_sa_sw_peer_id_get_9000(): API to get the + * sa_sw_peer_id from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: sa_sw_peer_id index + */ +static inline uint32_t +hal_rx_msdu_end_sa_sw_peer_id_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +/** + * hal_tx_desc_set_mesh_en_9000 - Set mesh_enable flag in Tx descriptor + * @desc: Handle to Tx Descriptor + * @en: For raw WiFi frames, this indicates transmission to a mesh STA, + * enabling the interpretation of the 'Mesh Control Present' bit + * (bit 8) of QoS Control (otherwise this bit is ignored), + * For native WiFi frames, this indicates that a 'Mesh Control' field + * is present between the header and the LLC. + * + * Return: void + */ +static inline +void hal_tx_desc_set_mesh_en_9000(void *desc, uint8_t en) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, MESH_ENABLE) |= + HAL_TX_SM(TCL_DATA_CMD_5, MESH_ENABLE, en); +} + +static +void *hal_rx_msdu0_buffer_addr_lsb_9000(void *link_desc_va) +{ + return (void *)HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va); +} + +static +void *hal_rx_msdu_desc_info_ptr_get_9000(void *msdu0) +{ + return (void *)HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0); +} + +static +void *hal_ent_mpdu_desc_info_9000(void *ent_ring_desc) +{ + return (void *)HAL_ENT_MPDU_DESC_INFO(ent_ring_desc); +} + +static +void *hal_dst_mpdu_desc_info_9000(void *dst_ring_desc) +{ + return (void *)HAL_DST_MPDU_DESC_INFO(dst_ring_desc); +} + +static +uint8_t hal_rx_get_fc_valid_9000(uint8_t *buf) +{ + return HAL_RX_GET_FC_VALID(buf); +} + +static uint8_t hal_rx_get_to_ds_flag_9000(uint8_t *buf) +{ + return HAL_RX_GET_TO_DS_FLAG(buf); +} + +static uint8_t hal_rx_get_mac_addr2_valid_9000(uint8_t *buf) +{ + return HAL_RX_GET_MAC_ADDR2_VALID(buf); +} + +static uint8_t hal_rx_get_filter_category_9000(uint8_t *buf) +{ + return HAL_RX_GET_FILTER_CATEGORY(buf); +} + +static uint32_t +hal_rx_get_ppdu_id_9000(uint8_t *buf) +{ + return HAL_RX_GET_PPDU_ID(buf); +} + +/** + * hal_reo_config_9000(): Set reo config parameters + * @soc: hal soc handle + * @reg_val: value to be set + * @reo_params: reo parameters + * + * Return: void + */ +static void +hal_reo_config_9000(struct hal_soc *soc, + uint32_t reg_val, + struct hal_reo_params *reo_params) +{ + HAL_REO_R0_CONFIG(soc, reg_val, reo_params); +} + +/** + * hal_rx_msdu_desc_info_get_ptr_9000() - Get msdu desc info ptr + * @msdu_details_ptr - Pointer to msdu_details_ptr + * + * Return - Pointer to rx_msdu_desc_info structure. + * + */ +static void *hal_rx_msdu_desc_info_get_ptr_9000(void *msdu_details_ptr) +{ + return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr); +} + +/** + * hal_rx_link_desc_msdu0_ptr_9000 - Get pointer to rx_msdu details + * @link_desc - Pointer to link desc + * + * Return - Pointer to rx_msdu_details structure + * + */ +static void *hal_rx_link_desc_msdu0_ptr_9000(void *link_desc) +{ + return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc); +} + +/** + * hal_rx_msdu_flow_idx_get_9000: API to get flow index + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index value from MSDU END TLV + */ +static inline uint32_t hal_rx_msdu_flow_idx_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_invalid_9000: API to get flow index invalid + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index invalid value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_invalid_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); +} + +/** + * hal_rx_msdu_flow_idx_timeout_9000: API to get flow index timeout + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: flow index timeout value from MSDU END TLV + */ +static bool hal_rx_msdu_flow_idx_timeout_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); +} + +/** + * hal_rx_msdu_fse_metadata_get_9000: API to get FSE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: fse metadata value from MSDU END TLV + */ +static uint32_t hal_rx_msdu_fse_metadata_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_FSE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_cce_metadata_get_9000: API to get CCE metadata + * from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * + * Return: cce_metadata + */ +static uint16_t +hal_rx_msdu_cce_metadata_get_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); +} + +/** + * hal_rx_msdu_get_flow_params_9000: API to get flow index, flow index invalid + * and flow index timeout from rx_msdu_end TLV + * @buf: pointer to the start of RX PKT TLV headers + * @flow_invalid: pointer to return value of flow_idx_valid + * @flow_timeout: pointer to return value of flow_idx_timeout + * @flow_index: pointer to return value of flow_idx + * + * Return: none + */ +static inline void +hal_rx_msdu_get_flow_params_9000(uint8_t *buf, + bool *flow_invalid, + bool *flow_timeout, + uint32_t *flow_index) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + *flow_invalid = HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(msdu_end); + *flow_timeout = HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(msdu_end); + *flow_index = HAL_RX_MSDU_END_FLOW_IDX_GET(msdu_end); +} + +/** + * hal_rx_tlv_get_tcp_chksum_9000() - API to get tcp checksum + * @buf: rx_tlv_hdr + * + * Return: tcp checksum + */ +static uint16_t +hal_rx_tlv_get_tcp_chksum_9000(uint8_t *buf) +{ + return HAL_RX_TLV_GET_TCP_CHKSUM(buf); +} + +/** + * hal_rx_get_rx_sequence_9000(): Function to retrieve rx sequence number + * + * @nbuf: Network buffer + * Returns: rx sequence number + */ +static +uint16_t hal_rx_get_rx_sequence_9000(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); + + return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); +} + +/** + * hal_get_window_address_9000(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_9000(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + uint32_t offset = addr - hal_soc->dev_base_addr; + qdf_iomem_t new_offset; + + /* + * If offset lies within DP register range, use 3rd window to write + * into DP region. + */ + if ((offset ^ SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) { + new_offset = (hal_soc->dev_base_addr + (3 * WINDOW_START) + + (offset & WINDOW_RANGE_MASK)); + /* + * If offset lies within CE register range, use 2nd window to write + * into CE region. + */ + } else if ((offset ^ CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) { + new_offset = (hal_soc->dev_base_addr + (2 * WINDOW_START) + + (offset & WINDOW_RANGE_MASK)); + } else { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s: ERROR: Accessing Wrong register\n", __func__); + qdf_assert_always(0); + return 0; + } + return new_offset; +} + +static inline void hal_write_window_register(struct hal_soc *hal_soc) +{ + /* Write value into window configuration register */ + qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS, + WINDOW_CONFIGURATION_VALUE_9000); +} + +/** + * hal_rx_msdu_packet_metadata_get_9000(): API to get the + * msdu information from rx_msdu_end TLV + * + * @ buf: pointer to the start of RX PKT TLV headers + * @ hal_rx_msdu_metadata: pointer to the msdu info structure + */ +static void +hal_rx_msdu_packet_metadata_get_9000(uint8_t *buf, + void *msdu_pkt_metadata) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + struct hal_rx_msdu_metadata *msdu_metadata = + (struct hal_rx_msdu_metadata *)msdu_pkt_metadata; + + msdu_metadata->l3_hdr_pad = + HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(msdu_end); + msdu_metadata->sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end); + msdu_metadata->da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end); + msdu_metadata->sa_sw_peer_id = + HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(msdu_end); +} + +struct hal_hw_txrx_ops qcn9000_hal_hw_txrx_ops = { + + /* init and setup */ + hal_srng_dst_hw_init_generic, + hal_srng_src_hw_init_generic, + hal_get_hw_hptp_generic, + hal_reo_setup_generic, + hal_setup_link_idle_list_generic, + hal_get_window_address_9000, + NULL, + + /* tx */ + hal_tx_desc_set_dscp_tid_table_id_9000, + hal_tx_set_dscp_tid_map_9000, + hal_tx_update_dscp_tid_9000, + hal_tx_desc_set_lmac_id_9000, + hal_tx_desc_set_buf_addr_generic, + hal_tx_desc_set_search_type_generic, + hal_tx_desc_set_search_index_generic, + hal_tx_desc_set_cache_set_num_generic, + hal_tx_comp_get_status_generic, + hal_tx_comp_get_release_reason_generic, + hal_get_wbm_internal_error_generic, + hal_tx_desc_set_mesh_en_9000, + + /* rx */ + hal_rx_msdu_start_nss_get_9000, + hal_rx_mon_hw_desc_get_mpdu_status_9000, + hal_rx_get_tlv_9000, + hal_rx_proc_phyrx_other_receive_info_tlv_9000, + hal_rx_dump_msdu_start_tlv_9000, + hal_rx_dump_msdu_end_tlv_9000, + hal_get_link_desc_size_9000, + hal_rx_mpdu_start_tid_get_9000, + hal_rx_msdu_start_reception_type_get_9000, + hal_rx_msdu_end_da_idx_get_9000, + hal_rx_msdu_desc_info_get_ptr_9000, + hal_rx_link_desc_msdu0_ptr_9000, + hal_reo_status_get_header_9000, + hal_rx_status_get_tlv_info_generic, + hal_rx_wbm_err_info_get_generic, + hal_rx_dump_mpdu_start_tlv_generic, + + hal_tx_set_pcp_tid_map_generic, + hal_tx_update_pcp_tid_generic, + hal_tx_update_tidmap_prty_generic, + hal_rx_get_rx_fragment_number_9000, + hal_rx_msdu_end_da_is_mcbc_get_9000, + hal_rx_msdu_end_sa_is_valid_get_9000, + hal_rx_msdu_end_sa_idx_get_9000, + hal_rx_desc_is_first_msdu_9000, + hal_rx_msdu_end_l3_hdr_padding_get_9000, + hal_rx_encryption_info_valid_9000, + hal_rx_print_pn_9000, + hal_rx_msdu_end_first_msdu_get_9000, + hal_rx_msdu_end_da_is_valid_get_9000, + hal_rx_msdu_end_last_msdu_get_9000, + hal_rx_get_mpdu_mac_ad4_valid_9000, + hal_rx_mpdu_start_sw_peer_id_get_9000, + hal_rx_mpdu_get_to_ds_9000, + hal_rx_mpdu_get_fr_ds_9000, + hal_rx_get_mpdu_frame_control_valid_9000, + hal_rx_mpdu_get_addr1_9000, + hal_rx_mpdu_get_addr2_9000, + hal_rx_mpdu_get_addr3_9000, + hal_rx_mpdu_get_addr4_9000, + hal_rx_get_mpdu_sequence_control_valid_9000, + hal_rx_is_unicast_9000, + hal_rx_tid_get_9000, + hal_rx_hw_desc_get_ppduid_get_9000, + hal_rx_mpdu_start_mpdu_qos_control_valid_get_9000, + hal_rx_msdu_end_sa_sw_peer_id_get_9000, + hal_rx_msdu0_buffer_addr_lsb_9000, + hal_rx_msdu_desc_info_ptr_get_9000, + hal_ent_mpdu_desc_info_9000, + hal_dst_mpdu_desc_info_9000, + hal_rx_get_fc_valid_9000, + hal_rx_get_to_ds_flag_9000, + hal_rx_get_mac_addr2_valid_9000, + hal_rx_get_filter_category_9000, + hal_rx_get_ppdu_id_9000, + hal_reo_config_9000, + hal_rx_msdu_flow_idx_get_9000, + hal_rx_msdu_flow_idx_invalid_9000, + hal_rx_msdu_flow_idx_timeout_9000, + hal_rx_msdu_fse_metadata_get_9000, + hal_rx_msdu_cce_metadata_get_9000, + hal_rx_msdu_get_flow_params_9000, + hal_rx_tlv_get_tcp_chksum_9000, + hal_rx_get_rx_sequence_9000, + NULL, + NULL, + /* rx - msdu fast path info fields */ + hal_rx_msdu_packet_metadata_get_9000, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +struct hal_hw_srng_config hw_srng_table_9000[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + { /* REO_DST */ + .start_ring_id = HAL_SRNG_REO2SW1, + .max_rings = 4, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2SW1_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + .reg_size = { + HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), + HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - + HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_EXCEPTION */ + /* Designating REO2TCL ring as exception ring. This ring is + * similar to other REO2SW rings though it is named as REO2TCL. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_REO2TCL, + .max_rings = 1, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2TCL_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_REINJECT */ + .start_ring_id = HAL_SRNG_SW2REO, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_SW2REO_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_CMD */ + .start_ring_id = HAL_SRNG_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_STATUS */ + .start_ring_id = HAL_SRNG_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats_status)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_DATA */ + .start_ring_id = HAL_SRNG_SW2TCL1, + .max_rings = 3, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_data_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + .reg_size = { + HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), + HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_CMD */ + .start_ring_id = HAL_SRNG_SW2TCL_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_gse_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL_CREDIT_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL_CREDIT_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_STATUS */ + .start_ring_id = HAL_SRNG_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_status_ring)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_SRC */ + .start_ring_id = HAL_SRNG_CE_0_SRC, + .max_rings = 12, + .entry_size = sizeof(struct ce_src_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST */ + .start_ring_id = HAL_SRNG_CE_0_DST, + .max_rings = 12, + .entry_size = 8 >> 2, + /*TODO: entry_size above should actually be + * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition + * of struct ce_dst_desc in HW header files + */ + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST_STATUS */ + .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, + .max_rings = 12, + .entry_size = sizeof(struct ce_stat_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + /* TODO: check destination status ring registers */ + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM_IDLE_LINK */ + .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* SW2WBM_RELEASE */ + .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM2SW_RELEASE */ + .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, + .max_rings = 4, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .reg_size = { + HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .max_size = + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* RXDMA_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, +#ifdef IPA_OFFLOAD + .max_rings = 3, +#else + .max_rings = 2, +#endif + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_STATUS */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DESC */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* DIR_BUF_RX_DMA_SRC */ + .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, + /* one ring for spectral and one ring for cfr */ + .max_rings = 2, + .entry_size = 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#ifdef WLAN_FEATURE_CIF_CFR + { /* WIFI_POS_SRC */ + .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, + .max_rings = 1, + .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#endif +}; + +int32_t hal_hw_reg_offset_qcn9000[] = { + /* dst */ + REG_OFFSET(DST, HP), + REG_OFFSET(DST, TP), + REG_OFFSET(DST, ID), + REG_OFFSET(DST, MISC), + REG_OFFSET(DST, HP_ADDR_LSB), + REG_OFFSET(DST, HP_ADDR_MSB), + REG_OFFSET(DST, MSI1_BASE_LSB), + REG_OFFSET(DST, MSI1_BASE_MSB), + REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, BASE_LSB), + REG_OFFSET(DST, BASE_MSB), + REG_OFFSET(DST, PRODUCER_INT_SETUP), + /* src */ + REG_OFFSET(SRC, HP), + REG_OFFSET(SRC, TP), + REG_OFFSET(SRC, ID), + REG_OFFSET(SRC, MISC), + REG_OFFSET(SRC, TP_ADDR_LSB), + REG_OFFSET(SRC, TP_ADDR_MSB), + REG_OFFSET(SRC, MSI1_BASE_LSB), + REG_OFFSET(SRC, MSI1_BASE_MSB), + REG_OFFSET(SRC, MSI1_DATA), + REG_OFFSET(SRC, BASE_LSB), + REG_OFFSET(SRC, BASE_MSB), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), +}; + +/** + * hal_qcn9000_attach()- Attach 9000 target specific hal_soc ops, + * offset and srng table + * Return: void + */ +void hal_qcn9000_attach(struct hal_soc *hal_soc) +{ + hal_soc->hw_srng_table = hw_srng_table_9000; + hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qcn9000; + hal_soc->ops = &qcn9000_hal_hw_txrx_ops; + if (hal_soc->static_window_map) + hal_write_window_register(hal_soc); +} diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_rx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..45528561301e4d30ccaa86511db482864ee714f7 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_rx.h @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#define HAL_RX_MSDU0_BUFFER_ADDR_LSB(link_desc_va) \ + ((uint8_t *)(link_desc_va) + \ + RX_MSDU_LINK_8_MSDU_0_BUFFER_ADDR_INFO_DETAILS_BUFFER_ADDR_31_0_OFFSET) + +#define HAL_RX_MSDU_DESC_INFO_PTR_GET(msdu0) \ + ((uint8_t *)(msdu0) + \ + RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_FIRST_MSDU_IN_MPDU_FLAG_OFFSET) + +#define HAL_ENT_MPDU_DESC_INFO(ent_ring_desc) \ + ((uint8_t *)(ent_ring_desc) + \ + RX_MPDU_DETAILS_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET) + +#define HAL_DST_MPDU_DESC_INFO(dst_ring_desc) \ + ((uint8_t *)(dst_ring_desc) + \ + REO_DESTINATION_RING_2_RX_MPDU_DESC_INFO_DETAILS_MSDU_COUNT_OFFSET) + +#define HAL_RX_GET_FC_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MPDU_FRAME_CONTROL_VALID) + +#define HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, TO_DS) + +#define HAL_RX_GET_MAC_ADDR1_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD1_VALID) + +#define HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_11, MAC_ADDR_AD2_VALID) + +#define HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, RXPCU_MPDU_FILTER_IN_CATEGORY) + +#define HAL_RX_GET_PPDU_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, PHY_PPDU_ID) + +#define HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start) \ + HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_9, SW_FRAME_GROUP_ID) + +#define HAL_REO_R0_CONFIG(soc, reg_val, reo_params) \ + do { \ + reg_val &= \ + ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |\ + HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK | \ + HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK); \ + reg_val |= \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + FRAGMENT_DEST_RING, \ + (reo_params)->frag_dst_ring) | \ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_LIST_ENABLE, 1) |\ + HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, \ + AGING_FLUSH_ENABLE, 1);\ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ + } while (0) + +#define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ + ((struct rx_msdu_desc_info *) \ + _OFFSET_TO_BYTE_PTR((msdu_details_ptr), \ + UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET)) + +#define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc) \ + ((struct rx_msdu_details *) \ + _OFFSET_TO_BYTE_PTR((link_desc),\ + UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET)) + +#define HAL_RX_TLV_GET_TCP_CHKSUM(buf) \ + (_HAL_MS( \ + (*_OFFSET_TO_WORD_PTR(&(((struct rx_pkt_tlvs *)(buf))->\ + msdu_end_tlv.rx_msdu_end), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_OFFSET)), \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_MASK, \ + RX_MSDU_END_10_TCP_UDP_CHKSUM_LSB)) + +#define HAL_RX_MSDU_END_FIRST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FIRST_MSDU_OFFSET)), \ + RX_MSDU_END_10_FIRST_MSDU_MASK, \ + RX_MSDU_END_10_FIRST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_LAST_MSDU_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_LAST_MSDU_OFFSET)), \ + RX_MSDU_END_10_LAST_MSDU_MASK, \ + RX_MSDU_END_10_LAST_MSDU_LSB)) + +#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_SA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_SA_IS_VALID_MASK, \ + RX_MSDU_END_10_SA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_VALID_OFFSET)), \ + RX_MSDU_END_10_DA_IS_VALID_MASK, \ + RX_MSDU_END_10_DA_IS_VALID_LSB)) + +#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_DA_IS_MCBC_OFFSET)), \ + RX_MSDU_END_10_DA_IS_MCBC_MASK, \ + RX_MSDU_END_10_DA_IS_MCBC_LSB)) + +#define HAL_RX_MSDU_END_L3_HEADER_PADDING_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_L3_HEADER_PADDING_OFFSET)), \ + RX_MSDU_END_10_L3_HEADER_PADDING_MASK, \ + RX_MSDU_END_10_L3_HEADER_PADDING_LSB)) + +#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_SA_IDX_OFFSET)), \ + RX_MSDU_END_11_SA_IDX_MASK, \ + RX_MSDU_END_11_SA_IDX_LSB)) + +#define HAL_RX_MSDU_END_SA_SW_PEER_ID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_SA_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_14_SA_SW_PEER_ID_MASK, \ + RX_MSDU_END_14_SA_SW_PEER_ID_LSB)) + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_14_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_14_CCE_METADATA_MASK, \ + RX_MSDU_END_14_CCE_METADATA_LSB)) + +#define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_OFFSET)), \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_MASK, \ + RX_MSDU_END_11_DA_IDX_OR_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_SW_FRAME_GROUP_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_OFFSET)), \ + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_MASK, \ + RX_MPDU_INFO_9_SW_FRAME_GROUP_ID_LSB)) \ + +#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_10_SW_PEER_ID_OFFSET)), \ + RX_MPDU_INFO_10_SW_PEER_ID_MASK, \ + RX_MPDU_INFO_10_SW_PEER_ID_LSB)) + +#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_FRAME_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD1_VALID_LSB)) + +#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \ + RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB)) + +#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD2_VALID_LSB)) + +#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \ + RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB)) + +#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \ + RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD3_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD3_VALID_LSB)) + +#define HAL_RX_MPDU_AD3_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_OFFSET)), \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_MASK, \ + RX_MPDU_INFO_18_MAC_ADDR_AD3_31_0_LSB)) + +#define HAL_RX_MPDU_AD3_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_OFFSET)), \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_MASK, \ + RX_MPDU_INFO_19_MAC_ADDR_AD3_47_32_LSB)) + +#define HAL_RX_MPDU_MAC_ADDR_AD4_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_MASK, \ + RX_MPDU_INFO_11_MAC_ADDR_AD4_VALID_LSB)) + +#define HAL_RX_MPDU_AD4_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_OFFSET)), \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_MASK, \ + RX_MPDU_INFO_20_MAC_ADDR_AD4_31_0_LSB)) + +#define HAL_RX_MPDU_AD4_47_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_OFFSET)), \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_MASK, \ + RX_MPDU_INFO_21_MAC_ADDR_AD4_47_32_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_CONTROL_VALID_LSB)) + +#define HAL_RX_MPDU_ENCRYPTION_INFO_VALID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_OFFSET)), \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_MASK, \ + RX_MPDU_INFO_11_FRAME_ENCRYPTION_INFO_VALID_LSB)) + +#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_FR_DS_OFFSET)), \ + RX_MPDU_INFO_11_FR_DS_MASK, \ + RX_MPDU_INFO_11_FR_DS_LSB)) + +#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_TO_DS_OFFSET)), \ + RX_MPDU_INFO_11_TO_DS_MASK, \ + RX_MPDU_INFO_11_TO_DS_LSB)) + +#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_OFFSET)), \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_MASK, \ + RX_MPDU_INFO_11_MPDU_SEQUENCE_NUMBER_LSB)) + +#define HAL_RX_MPDU_PN_31_0_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_3_PN_31_0_OFFSET)), \ + RX_MPDU_INFO_3_PN_31_0_MASK, \ + RX_MPDU_INFO_3_PN_31_0_LSB)) + +#define HAL_RX_MPDU_PN_63_32_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_4_PN_63_32_OFFSET)), \ + RX_MPDU_INFO_4_PN_63_32_MASK, \ + RX_MPDU_INFO_4_PN_63_32_LSB)) + +#define HAL_RX_MPDU_PN_95_64_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_5_PN_95_64_OFFSET)), \ + RX_MPDU_INFO_5_PN_95_64_MASK, \ + RX_MPDU_INFO_5_PN_95_64_LSB)) + +#define HAL_RX_MPDU_PN_127_96_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ + RX_MPDU_INFO_6_PN_127_96_OFFSET)), \ + RX_MPDU_INFO_6_PN_127_96_MASK, \ + RX_MPDU_INFO_6_PN_127_96_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_MASK, \ + RX_MSDU_END_10_FLOW_IDX_TIMEOUT_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_OFFSET)), \ + RX_MSDU_END_10_FLOW_IDX_INVALID_MASK, \ + RX_MSDU_END_10_FLOW_IDX_INVALID_LSB)) + +#define HAL_RX_MSDU_END_FLOW_IDX_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_12_FLOW_IDX_OFFSET)), \ + RX_MSDU_END_12_FLOW_IDX_MASK, \ + RX_MSDU_END_12_FLOW_IDX_LSB)) + +#define HAL_RX_MSDU_END_FSE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_13_FSE_METADATA_OFFSET)), \ + RX_MSDU_END_13_FSE_METADATA_MASK, \ + RX_MSDU_END_13_FSE_METADATA_LSB)) + +#define HAL_RX_MPDU_GET_PHY_PPDU_ID(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_9_PHY_PPDU_ID_OFFSET)), \ + RX_MPDU_INFO_9_PHY_PPDU_ID_MASK, \ + RX_MPDU_INFO_9_PHY_PPDU_ID_LSB)) \ + +#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ + RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ + RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ + RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) + +#ifdef GET_MSDU_AGGREGATION +#define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)\ +{\ + struct rx_msdu_end *rx_msdu_end;\ + bool first_msdu, last_msdu; \ + rx_msdu_end = &rx_desc->msdu_end_tlv.rx_msdu_end;\ + first_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_10, FIRST_MSDU);\ + last_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_10, LAST_MSDU);\ + if (first_msdu && last_msdu)\ + rs->rs_flags &= (~IEEE80211_AMSDU_FLAG);\ + else\ + rs->rs_flags |= (IEEE80211_AMSDU_FLAG); \ +} \ + +#else +#define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs) +#endif + +#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_7_TID_OFFSET)), \ + RX_MPDU_INFO_7_TID_MASK, \ + RX_MPDU_INFO_7_TID_LSB)) + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) diff --git a/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_tx.h b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_tx.h new file mode 100644 index 0000000000000000000000000000000000000000..c6c2856df85ea40c69d69e6e225807870d2530d0 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qcn9000/hal_9000_tx.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * 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. + */ +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" + +/** + * hal_tx_desc_set_dscp_tid_table_id_9000() - Sets DSCP to TID conversion + * table ID + * @desc: Handle to Tx Descriptor + * @id: DSCP to tid conversion table to be used for this frame + * + * Return: void + */ +static void hal_tx_desc_set_dscp_tid_table_id_9000(void *desc, uint8_t id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM) |= + HAL_TX_SM(TCL_DATA_CMD_5, DSCP_TID_TABLE_NUM, id); +} + +#define DSCP_TID_TABLE_SIZE 24 +#define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4) +#define HAL_TX_NUM_DSCP_REGISTER_SIZE 32 + +/** + * hal_tx_set_dscp_tid_map_9000() - Configure default DSCP to TID map table + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id: mapping table ID - 0,1 + * + * DSCP are mapped to 8 TID values using TID values programmed + * in two set of mapping registers DSCP_TID1_MAP_<0 to 6> (id = 0) + * and DSCP_TID2_MAP_<0 to 6> (id = 1) + * Each mapping register has TID mapping for 10 DSCP values + * + * Return: none + */ +static void hal_tx_set_dscp_tid_map_9000(struct hal_soc *soc, + uint8_t *map, uint8_t id) +{ + int i; + uint32_t addr, cmn_reg_addr; + uint32_t value = 0, regval; + uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; + + if (id >= HAL_MAX_HW_DSCP_TID_V2_MAPS) + return; + + cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, + id * NUM_WORDS_PER_DSCP_TID_TABLE); + + /* Enable read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval |= + (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); + + /* Write 8 (24 bits) DSCP-TID mappings in each interation */ + for (i = 0; i < 64; i += 8) { + value = (map[i] | + (map[i + 1] << 0x3) | + (map[i + 2] << 0x6) | + (map[i + 3] << 0x9) | + (map[i + 4] << 0xc) | + (map[i + 5] << 0xf) | + (map[i + 6] << 0x12) | + (map[i + 7] << 0x15)); + + qdf_mem_copy(&val[cnt], &value, 3); + cnt += 3; + } + + for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) { + regval = *(uint32_t *)(val + i); + HAL_REG_WRITE(soc, addr, + (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); + addr += 4; + } + + /* Diasble read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= + ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +/** + * hal_tx_update_dscp_tid_9000() - Update the dscp tid map table as + updated by user + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +static void hal_tx_update_dscp_tid_9000(struct hal_soc *soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + uint32_t addr, addr1, cmn_reg_addr; + uint32_t start_value = 0, end_value = 0; + uint32_t regval; + uint8_t end_bits = 0; + uint8_t start_bits = 0; + uint32_t start_index, end_index; + + cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, + id * NUM_WORDS_PER_DSCP_TID_TABLE); + + start_index = dscp * HAL_TX_BITS_PER_TID; + end_index = (start_index + (HAL_TX_BITS_PER_TID - 1)) + % HAL_TX_NUM_DSCP_REGISTER_SIZE; + start_index = start_index % HAL_TX_NUM_DSCP_REGISTER_SIZE; + addr += (4 * ((dscp * HAL_TX_BITS_PER_TID) / + HAL_TX_NUM_DSCP_REGISTER_SIZE)); + + if (end_index < start_index) { + end_bits = end_index + 1; + start_bits = HAL_TX_BITS_PER_TID - end_bits; + start_value = tid << start_index; + end_value = tid >> start_bits; + addr1 = addr + 4; + } else { + start_bits = HAL_TX_BITS_PER_TID - end_bits; + start_value = tid << start_index; + addr1 = 0; + } + + /* Enable read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval |= + (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); + + regval = HAL_REG_READ(soc, addr); + + if (end_index < start_index) + regval &= (~0) >> start_bits; + else + regval &= ~(7 << start_index); + + regval |= start_value; + + HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); + + if (addr1) { + regval = HAL_REG_READ(soc, addr1); + regval &= (~0) << end_bits; + regval |= end_value; + + HAL_REG_WRITE(soc, addr1, (regval & + HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); + } + + /* Diasble read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= + ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK); + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +/** + * hal_tx_desc_set_lmac_id_9000 - Set the lmac_id value + * @desc: Handle to Tx Descriptor + * @lmac_id: mac Id to ast matching + * b00 – mac 0 + * b01 – mac 1 + * b10 – mac 2 + * b11 – all macs (legacy HK way) + * + * Return: void + */ +static void hal_tx_desc_set_lmac_id_9000(void *desc, uint8_t lmac_id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |= + HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id); +} diff --git a/drivers/staging/qca-wifi-host-cmn/hif/configs/ap_hif.config b/drivers/staging/qca-wifi-host-cmn/hif/configs/ap_hif.config deleted file mode 100644 index ac35e75eaba1ea056c8cad34304c58c91831c249..0000000000000000000000000000000000000000 --- a/drivers/staging/qca-wifi-host-cmn/hif/configs/ap_hif.config +++ /dev/null @@ -1 +0,0 @@ -EXTRA_CFLAGS += -DQCA_NAPI_DEF_SCALE_BIN_SHIFT=1 diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/cfg_hif.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/cfg_hif.h new file mode 100644 index 0000000000000000000000000000000000000000..41f0fd0bb77f6984e420e751a583908f9c520022 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/cfg_hif.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _CFG_HIF_H_ +#define _CFG_HIF_H_ + +/* Min/Max/default CE status srng timer threshold */ +#define WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_MIN 0 +#define WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_MAX 4096 +#define WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_DEFAULT 4096 + +/* Min/Max/default CE status srng batch count threshold */ +#define WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_MIN 0 +#define WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_MAX 512 +#define WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_DEFAULT 1 + +#ifdef WLAN_CE_INTERRUPT_THRESHOLD_CONFIG +/** + * + * ce_status_ring_timer_thresh - ce status srng timer threshold + * @Min: 0 + * @Max: 4096 + * @Default: 0 + * + * This ini specifies the timer threshold for CE status srng to + * indicate the interrupt to be fired whenever the timer threshold + * runs out. + * + * Supported Feature: interrupt threshold for CE status srng + * + * Usage: Internal + * + * + */ +#define CFG_CE_STATUS_RING_TIMER_THRESHOLD \ + CFG_INI_UINT("ce_status_ring_timer_threshold", \ + WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_MIN, \ + WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_MAX, \ + WLAN_CFG_CE_STATUS_RING_TIMER_THRESH_DEFAULT, \ + CFG_VALUE_OR_DEFAULT, \ + "CE Status ring timer threshold") + +/** + * + * ce_status_ring_batch_count_thresh - ce status srng batch count threshold + * @Min: 0 + * @Max: 512 + * @Default: 1 + * + * This ini specifies the batch count threshold for CE status srng to + * indicate the interrupt to be fired for a given number of packets in + * the ring. + * + * Supported Feature: interrupt threshold for CE status srng + * + * Usage: Internal + * + * + */ +#define CFG_CE_STATUS_RING_BATCH_COUNT_THRESHOLD \ + CFG_INI_UINT("ce_status_ring_batch_count_threshold", \ + WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_MIN, \ + WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_MAX, \ + WLAN_CFG_CE_STATUS_RING_BATCH_COUNT_THRESH_DEFAULT, \ + CFG_VALUE_OR_DEFAULT, \ + "CE Status ring batch count threshold") + +#define CFG_HIF \ + CFG(CFG_CE_STATUS_RING_TIMER_THRESHOLD) \ + CFG(CFG_CE_STATUS_RING_BATCH_COUNT_THRESHOLD) +#else +#define CFG_HIF +#endif /* WLAN_CE_INTERRUPT_THRESHOLD_CONFIG */ +#endif /* _CFG_HIF_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/hif.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/hif.h index 5cb23350f00ce06a22507192e5f0de547a3f0b9b..d29cf3bb59efe8f91f04e7e72d3ea7c452ef3163 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/inc/hif.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/hif.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,6 +38,7 @@ extern "C" { #ifdef IPA_OFFLOAD #include #endif +#include "cfg_ucfg_api.h" #include "qdf_dev.h" #define ENABLE_MBOX_DUMMY_SPACE_FEATURE 1 @@ -63,6 +64,9 @@ typedef void *hif_handle_t; #define HIF_TYPE_QCA6390 18 #define HIF_TYPE_QCA8074V2 19 #define HIF_TYPE_QCA6018 20 +#define HIF_TYPE_QCN9000 21 +#define HIF_TYPE_QCA6490 22 +#define HIF_TYPE_QCA6750 23 #ifdef IPA_OFFLOAD #define DMA_COHERENT_MASK_IPA_VER_3_AND_ABOVE 37 @@ -115,18 +119,10 @@ struct CE_state; #define CE_COUNT_MAX 12 #define HIF_MAX_GRP_IRQ 16 -#ifdef CONFIG_WIN -#define HIF_MAX_GROUP 12 -#else +#ifndef HIF_MAX_GROUP #define HIF_MAX_GROUP 7 #endif -#ifdef CONFIG_SLUB_DEBUG_ON -#ifndef CONFIG_WIN -#define HIF_CONFIG_SLUB_DEBUG_ON -#endif -#endif - #ifndef NAPI_YIELD_BUDGET_BASED #ifndef QCA_NAPI_DEF_SCALE_BIN_SHIFT #define QCA_NAPI_DEF_SCALE_BIN_SHIFT 4 @@ -326,6 +322,23 @@ enum hif_event_type { HIF_EVENT_BH_SCHED, HIF_EVENT_SRNG_ACCESS_START, HIF_EVENT_SRNG_ACCESS_END, + /* Do check hif_hist_skip_event_record when adding new events */ +}; + +/** + * enum hif_system_pm_state - System PM state + * HIF_SYSTEM_PM_STATE_ON: System in active state + * HIF_SYSTEM_PM_STATE_BUS_RESUMING: bus resume in progress as part of + * system resume + * HIF_SYSTEM_PM_STATE_BUS_SUSPENDING: bus suspend in progress as part of + * system suspend + * HIF_SYSTEM_PM_STATE_BUS_SUSPENDED: bus suspended as part of system suspend + */ +enum hif_system_pm_state { + HIF_SYSTEM_PM_STATE_ON, + HIF_SYSTEM_PM_STATE_BUS_RESUMING, + HIF_SYSTEM_PM_STATE_BUS_SUSPENDING, + HIF_SYSTEM_PM_STATE_BUS_SUSPENDED, }; #ifdef WLAN_FEATURE_DP_EVENT_HISTORY @@ -356,6 +369,16 @@ struct hif_event_record { enum hif_event_type type; }; +/** + * struct hif_event_misc - history related misc info + * @last_irq_index: last irq event index in history + * @last_irq_ts: last irq timestamp + */ +struct hif_event_misc { + int32_t last_irq_index; + uint64_t last_irq_ts; +}; + /** * struct hif_event_history - history for one interrupt group * @index: index to store new event @@ -366,6 +389,7 @@ struct hif_event_record { */ struct hif_event_history { qdf_atomic_t index; + struct hif_event_misc misc; struct hif_event_record event[HIF_EVENT_HIST_MAX]; }; @@ -470,8 +494,8 @@ enum hif_disable_type { * enum hif_device_config_opcode: configure mode * * @HIF_DEVICE_POWER_STATE: device power state - * @HIF_DEVICE_GET_MBOX_BLOCK_SIZE: get mbox block size - * @HIF_DEVICE_GET_MBOX_ADDR: get mbox block address + * @HIF_DEVICE_GET_BLOCK_SIZE: get block size + * @HIF_DEVICE_GET_ADDR: get block address * @HIF_DEVICE_GET_PENDING_EVENTS_FUNC: get pending events functions * @HIF_DEVICE_GET_IRQ_PROC_MODE: get irq proc mode * @HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC: receive event function @@ -539,6 +563,8 @@ struct htc_callbacks { * @is_load_unload_in_progress: Query if driver state Load/Unload in Progress * @is_driver_unloading: Query if driver is unloading. * @get_bandwidth_level: Query current bandwidth level for the driver + * @prealloc_get_consistent_mem_unligned: get prealloc unaligned consistent mem + * @prealloc_put_consistent_mem_unligned: put unaligned consistent mem to pool * This Structure provides callback pointer for HIF to query hdd for driver * states. */ @@ -550,6 +576,12 @@ struct hif_driver_state_callbacks { bool (*is_driver_unloading)(void *context); bool (*is_target_ready)(void *context); int (*get_bandwidth_level)(void *context); +#ifdef DP_MEM_PRE_ALLOC + void *(*prealloc_get_consistent_mem_unaligned)(qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type); + void (*prealloc_put_consistent_mem_unaligned)(void *vaddr); +#endif }; /* This API detaches the HTC layer from the HIF device */ @@ -676,6 +708,7 @@ struct hif_msg_callbacks { uint8_t pipeID); void (*txResourceAvailHandler)(void *context, uint8_t pipe); void (*fwEventHandler)(void *context, QDF_STATUS status); + void (*update_bundle_stats)(void *context, uint8_t no_of_pkt_in_bundle); }; enum hif_target_status { @@ -836,15 +869,35 @@ void hif_disable_isr(struct hif_opaque_softc *hif_ctx); void hif_reset_soc(struct hif_opaque_softc *hif_ctx); void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx, int htc_htt_tx_endpoint); -struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode, + +/** + * hif_open() - Create hif handle + * @qdf_ctx: qdf context + * @mode: Driver Mode + * @bus_type: Bus Type + * @cbk: CDS Callbacks + * @psoc: psoc object manager + * + * API to open HIF Context + * + * Return: HIF Opaque Pointer + */ +struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, + uint32_t mode, enum qdf_bus_type bus_type, - struct hif_driver_state_callbacks *cbk); + struct hif_driver_state_callbacks *cbk, + struct wlan_objmgr_psoc *psoc); + void hif_close(struct hif_opaque_softc *hif_ctx); QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev, void *bdev, const struct hif_bus_id *bid, enum qdf_bus_type bus_type, enum hif_enable_type type); void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type); +#ifdef CE_TASKLET_DEBUG_ENABLE +void hif_enable_ce_latency_stats(struct hif_opaque_softc *hif_ctx, + uint8_t value); +#endif void hif_display_stats(struct hif_opaque_softc *hif_ctx); void hif_clear_stats(struct hif_opaque_softc *hif_ctx); @@ -908,8 +961,19 @@ static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id) return (char *)strings[id]; } +/** + * enum hif_pm_link_state - hif link state + * HIF_PM_LINK_STATE_DOWN: hif link state is down + * HIF_PM_LINK_STATE_UP: hif link state is up + */ +enum hif_pm_link_state { + HIF_PM_LINK_STATE_DOWN, + HIF_PM_LINK_STATE_UP +}; + #ifdef FEATURE_RUNTIME_PM struct hif_pm_runtime_lock; + void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_get_sync(struct hif_opaque_softc *hif_ctx, wlan_rtpm_dbgid rtpm_dbgid); @@ -942,6 +1006,22 @@ void hif_pm_runtime_mark_dp_rx_busy(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_is_dp_rx_busy(struct hif_opaque_softc *hif_ctx); qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx); int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx); + +/** + * hif_pm_set_link_state() - set link state during RTPM + * @hif_sc: HIF Context + * + * Return: None + */ +void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val); + +/** + * hif_is_link_state_up() - Is link state up + * @hif_sc: HIF Context + * + * Return: 1 link is up, 0 link is down + */ +uint8_t hif_pm_get_link_state(struct hif_opaque_softc *hif_handle); #else struct hif_pm_runtime_lock { const char *name; @@ -1010,6 +1090,10 @@ hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) { return 0; } static inline int hif_pm_runtime_sync_resume(struct hif_opaque_softc *hif_ctx) { return 0; } +static inline +void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val) +{} + #endif void hif_enable_power_management(struct hif_opaque_softc *hif_ctx, @@ -1182,6 +1266,7 @@ int32_t hif_get_int_ctx_irq_num(struct hif_opaque_softc *softc, uint8_t id); uint32_t hif_configure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx); +void hif_deconfigure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx); uint32_t hif_register_ext_group(struct hif_opaque_softc *hif_ctx, uint32_t numirq, uint32_t irq[], ext_intr_handler handler, void *cb_ctx, const char *context_name, @@ -1214,6 +1299,50 @@ void hif_clear_napi_stats(struct hif_opaque_softc *hif_ctx); } #endif +#ifdef FORCE_WAKE +/** + * hif_force_wake_request() - Function to wake from power collapse + * @handle: HIF opaque handle + * + * Description: API to check if the device is awake or not before + * read/write to BAR + 4K registers. If device is awake return + * success otherwise write '1' to + * PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG which will interrupt + * the device and does wakeup the PCI and MHI within 50ms + * and then the device writes a value to + * PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG to complete the + * handshake process to let the host know the device is awake. + * + * Return: zero - success/non-zero - failure + */ +int hif_force_wake_request(struct hif_opaque_softc *handle); + +/** + * hif_force_wake_release() - API to release/reset the SOC wake register + * from interrupting the device. + * @handle: HIF opaque handle + * + * Description: API to set the + * PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG to '0' + * to release the interrupt line. + * + * Return: zero - success/non-zero - failure + */ +int hif_force_wake_release(struct hif_opaque_softc *handle); +#else +static inline +int hif_force_wake_request(struct hif_opaque_softc *handle) +{ + return 0; +} + +static inline +int hif_force_wake_release(struct hif_opaque_softc *handle) +{ + return 0; +} +#endif /* FORCE_WAKE */ + #ifdef FEATURE_HAL_DELAYED_REG_WRITE /** * hif_prevent_link_low_power_states() - Prevent from going to low power states @@ -1308,7 +1437,8 @@ hif_get_ce_service_max_yield_time(struct hif_opaque_softc *hif); * Return: void */ void hif_set_ce_service_max_rx_ind_flush(struct hif_opaque_softc *hif, - uint8_t ce_service_max_rx_ind_flush); + uint8_t ce_service_max_rx_ind_flush); + #ifdef OL_ATH_SMART_LOGGING /* * hif_log_ce_dump() - Copy all the CE DEST ring to buf @@ -1329,6 +1459,39 @@ uint8_t *hif_log_dump_ce(struct hif_softc *scn, uint8_t *buf_cur, uint32_t ce, uint32_t skb_sz); #endif /* OL_ATH_SMART_LOGGING */ +/* + * hif_softc_to_hif_opaque_softc - API to convert hif_softc handle + * to hif_opaque_softc handle + * @hif_handle - hif_softc type + * + * Return: hif_opaque_softc type + */ +static inline struct hif_opaque_softc * +hif_softc_to_hif_opaque_softc(struct hif_softc *hif_handle) +{ + return (struct hif_opaque_softc *)hif_handle; +} + +#ifdef FORCE_WAKE +/** + * hif_srng_init_phase(): Indicate srng initialization phase + * to avoid force wake as UMAC power collapse is not yet + * enabled + * @hif_ctx: hif opaque handle + * @init_phase: initialization phase + * + * Return: None + */ +void hif_srng_init_phase(struct hif_opaque_softc *hif_ctx, + bool init_phase); +#else +static inline +void hif_srng_init_phase(struct hif_opaque_softc *hif_ctx, + bool init_phase) +{ +} +#endif /* FORCE_WAKE */ + #ifdef HIF_CPU_PERF_AFFINE_MASK /** * hif_config_irq_set_perf_affinity_hint() - API to set affinity @@ -1348,4 +1511,137 @@ static inline void hif_config_irq_set_perf_affinity_hint( { } #endif + +#ifdef HIF_CE_LOG_INFO +/** + * hif_log_ce_info() - API to log ce info + * @scn: hif handle + * @data: hang event data buffer + * @offset: offset at which data needs to be written + * + * Return: None + */ +void hif_log_ce_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset); +#else +static inline +void hif_log_ce_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ +} +#endif + +#ifdef SYSTEM_PM_CHECK +/** + * __hif_system_pm_set_state() - Set system pm state + * @hif: hif opaque handle + * @state: system state + * + * Return: None + */ +void __hif_system_pm_set_state(struct hif_opaque_softc *hif, + enum hif_system_pm_state state); + +/** + * hif_system_pm_set_state_on() - Set system pm state to ON + * @hif: hif opaque handle + * + * Return: None + */ +static inline +void hif_system_pm_set_state_on(struct hif_opaque_softc *hif) +{ + __hif_system_pm_set_state(hif, HIF_SYSTEM_PM_STATE_ON); +} + +/** + * hif_system_pm_set_state_resuming() - Set system pm state to resuming + * @hif: hif opaque handle + * + * Return: None + */ +static inline +void hif_system_pm_set_state_resuming(struct hif_opaque_softc *hif) +{ + __hif_system_pm_set_state(hif, HIF_SYSTEM_PM_STATE_BUS_RESUMING); +} + +/** + * hif_system_pm_set_state_suspending() - Set system pm state to suspending + * @hif: hif opaque handle + * + * Return: None + */ +static inline +void hif_system_pm_set_state_suspending(struct hif_opaque_softc *hif) +{ + __hif_system_pm_set_state(hif, HIF_SYSTEM_PM_STATE_BUS_SUSPENDING); +} + +/** + * hif_system_pm_set_state_suspended() - Set system pm state to suspended + * @hif: hif opaque handle + * + * Return: None + */ +static inline +void hif_system_pm_set_state_suspended(struct hif_opaque_softc *hif) +{ + __hif_system_pm_set_state(hif, HIF_SYSTEM_PM_STATE_BUS_SUSPENDED); +} + +/** + * hif_system_pm_get_state() - Get system pm state + * @hif: hif opaque handle + * + * Return: system state + */ +int32_t hif_system_pm_get_state(struct hif_opaque_softc *hif); + +/** + * hif_system_pm_state_check() - Check system state and trigger resume + * if required + * @hif: hif opaque handle + * + * Return: 0 if system is in on state else error code + */ +int hif_system_pm_state_check(struct hif_opaque_softc *hif); +#else +static inline +void __hif_system_pm_set_state(struct hif_opaque_softc *hif, + enum hif_system_pm_state state) +{ +} + +static inline +void hif_system_pm_set_state_on(struct hif_opaque_softc *hif) +{ +} + +static inline +void hif_system_pm_set_state_resuming(struct hif_opaque_softc *hif) +{ +} + +static inline +void hif_system_pm_set_state_suspending(struct hif_opaque_softc *hif) +{ +} + +static inline +void hif_system_pm_set_state_suspended(struct hif_opaque_softc *hif) +{ +} + +static inline +int32_t hif_system_pm_get_state(struct hif_opaque_softc *hif) +{ + return 0; +} + +static inline int hif_system_pm_state_check(struct hif_opaque_softc *hif) +{ + return 0; +} +#endif #endif /* _HIF_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/hostdef.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/hostdef.h index 9b0e4d1874dacb3d27ec23e5038ee76903e87bb5..a94df8efb53a7bd210fe29942a3875ea6000f83b 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/inc/hostdef.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/hostdef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016,2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016,2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,11 +35,14 @@ extern struct hostdef_s *QCA9984_HOSTdef; extern struct hostdef_s *QCA9888_HOSTdef; extern struct hostdef_s *QCA6290_HOSTdef; extern struct hostdef_s *QCA6390_HOSTdef; +extern struct hostdef_s *QCA6490_HOSTdef; +extern struct hostdef_s *QCA6750_HOSTdef; + #ifdef ATH_AHB extern struct hostdef_s *IPQ4019_HOSTdef; #endif extern struct hostdef_s *QCA8074_HOSTdef; extern struct hostdef_s *QCA8074V2_HOSTDEF; extern struct hostdef_s *QCA6018_HOSTDEF; - +extern struct hostdef_s *QCN9000_HOSTDEF; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable.h index 31cc83609cfe6d9b46ec6c4f492ee3a343d1f4bc..fb058bcfe1ae130b407b16b7c97ef9e5d05abe44 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,4 +32,8 @@ #include "regtable_usb.h" #endif +#if defined(HIF_IPCI) +#include "reg_struct.h" +#include "regtable_ipcie.h" +#endif #endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable_ipcie.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable_ipcie.h new file mode 100644 index 0000000000000000000000000000000000000000..a19b417916a95b40d087d6fb50ec1cafaaf427ec --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/regtable_ipcie.h @@ -0,0 +1,662 @@ +/* + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _REGTABLE_IPCIE_H_ +#define _REGTABLE_IPCIE_H_ + +#define MISSING 0 + +#define A_SOC_CORE_PCIE_INTR_ENABLE_GRP0_Q6_MASK \ + (scn->targetdef->d_A_SOC_CORE_PCIE_INTR_ENABLE_GRP0_Q6_MASK) +#define A_SOC_CORE_PCIE_INTR_CAUSE_GRP1 \ + (scn->targetdef->d_A_SOC_CORE_PCIE_INTR_CAUSE_GRP1) +#define A_SOC_CORE_SPARE_1_REGISTER \ + (scn->targetdef->d_A_SOC_CORE_SPARE_1_REGISTER) +#define A_SOC_CORE_PCIE_INTR_CLR_GRP1 \ + (scn->targetdef->d_A_SOC_CORE_PCIE_INTR_CLR_GRP1) +#define A_SOC_CORE_PCIE_INTR_ENABLE_GRP1 \ + (scn->targetdef->d_A_SOC_CORE_PCIE_INTR_ENABLE_GRP1) +#define A_SOC_PCIE_PCIE_SCRATCH_0 \ + (scn->targetdef->d_A_SOC_PCIE_PCIE_SCRATCH_0) +#define A_SOC_PCIE_PCIE_SCRATCH_1 \ + (scn->targetdef->d_A_SOC_PCIE_PCIE_SCRATCH_1) +#define A_WIFI_APB_1_A_WFSS_CE_TARGET_HOST_DELTA \ + (scn->targetdef->d_A_WIFI_APB_1_A_WFSS_CE_TARGET_HOST_DELTA) +#define A_SOC_PCIE_PCIE_SCRATCH_2 \ + (scn->targetdef->d_A_SOC_PCIE_PCIE_SCRATCH_2) +/* end Q6 iHelium emu registers */ + +#define PCIE_INTR_FIRMWARE_ROUTE_MASK \ + (scn->targetdef->d_PCIE_INTR_FIRMWARE_ROUTE_MASK) +#define A_SOC_CORE_SPARE_0_REGISTER \ + (scn->targetdef->d_A_SOC_CORE_SPARE_0_REGISTER) +#define A_SOC_CORE_SCRATCH_0_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_0_ADDRESS) +#define A_SOC_CORE_SCRATCH_1_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_1_ADDRESS) +#define A_SOC_CORE_SCRATCH_2_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_2_ADDRESS) +#define A_SOC_CORE_SCRATCH_3_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_3_ADDRESS) +#define A_SOC_CORE_SCRATCH_4_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_4_ADDRESS) +#define A_SOC_CORE_SCRATCH_5_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_5_ADDRESS) +#define A_SOC_CORE_SCRATCH_6_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_6_ADDRESS) +#define A_SOC_CORE_SCRATCH_7_ADDRESS \ + (scn->targetdef->d_A_SOC_CORE_SCRATCH_7_ADDRESS) +#define RTC_SOC_BASE_ADDRESS (scn->targetdef->d_RTC_SOC_BASE_ADDRESS) +#define RTC_WMAC_BASE_ADDRESS (scn->targetdef->d_RTC_WMAC_BASE_ADDRESS) +#define SYSTEM_SLEEP_OFFSET (scn->targetdef->d_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_OFFSET \ + (scn->targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB \ + (scn->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB) +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK \ + (scn->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define CLOCK_CONTROL_OFFSET (scn->targetdef->d_CLOCK_CONTROL_OFFSET) +#define CLOCK_CONTROL_SI0_CLK_MASK \ + (scn->targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK) +#define RESET_CONTROL_OFFSET (scn->targetdef->d_RESET_CONTROL_OFFSET) +#define RESET_CONTROL_MBOX_RST_MASK \ + (scn->targetdef->d_RESET_CONTROL_MBOX_RST_MASK) +#define RESET_CONTROL_SI0_RST_MASK \ + (scn->targetdef->d_RESET_CONTROL_SI0_RST_MASK) +#define WLAN_RESET_CONTROL_OFFSET \ + (scn->targetdef->d_WLAN_RESET_CONTROL_OFFSET) +#define WLAN_RESET_CONTROL_COLD_RST_MASK \ + (scn->targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_WARM_RST_MASK \ + (scn->targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK) +#define GPIO_BASE_ADDRESS (scn->targetdef->d_GPIO_BASE_ADDRESS) +#define GPIO_PIN0_OFFSET (scn->targetdef->d_GPIO_PIN0_OFFSET) +#define GPIO_PIN1_OFFSET (scn->targetdef->d_GPIO_PIN1_OFFSET) +#define GPIO_PIN0_CONFIG_MASK (scn->targetdef->d_GPIO_PIN0_CONFIG_MASK) +#define GPIO_PIN1_CONFIG_MASK (scn->targetdef->d_GPIO_PIN1_CONFIG_MASK) +#define A_SOC_CORE_SCRATCH_0 (scn->targetdef->d_A_SOC_CORE_SCRATCH_0) +#define SI_CONFIG_BIDIR_OD_DATA_LSB \ + (scn->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB) +#define SI_CONFIG_BIDIR_OD_DATA_MASK \ + (scn->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_LSB (scn->targetdef->d_SI_CONFIG_I2C_LSB) +#define SI_CONFIG_I2C_MASK \ + (scn->targetdef->d_SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_LSB \ + (scn->targetdef->d_SI_CONFIG_POS_SAMPLE_LSB) +#define SI_CONFIG_POS_SAMPLE_MASK \ + (scn->targetdef->d_SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_LSB \ + (scn->targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB) +#define SI_CONFIG_INACTIVE_CLK_MASK \ + (scn->targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_LSB \ + (scn->targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB) +#define SI_CONFIG_INACTIVE_DATA_MASK \ + (scn->targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_LSB (scn->targetdef->d_SI_CONFIG_DIVIDER_LSB) +#define SI_CONFIG_DIVIDER_MASK (scn->targetdef->d_SI_CONFIG_DIVIDER_MASK) +#define SI_BASE_ADDRESS (scn->targetdef->d_SI_BASE_ADDRESS) +#define SI_CONFIG_OFFSET (scn->targetdef->d_SI_CONFIG_OFFSET) +#define SI_TX_DATA0_OFFSET (scn->targetdef->d_SI_TX_DATA0_OFFSET) +#define SI_TX_DATA1_OFFSET (scn->targetdef->d_SI_TX_DATA1_OFFSET) +#define SI_RX_DATA0_OFFSET (scn->targetdef->d_SI_RX_DATA0_OFFSET) +#define SI_RX_DATA1_OFFSET (scn->targetdef->d_SI_RX_DATA1_OFFSET) +#define SI_CS_OFFSET (scn->targetdef->d_SI_CS_OFFSET) +#define SI_CS_DONE_ERR_MASK (scn->targetdef->d_SI_CS_DONE_ERR_MASK) +#define SI_CS_DONE_INT_MASK (scn->targetdef->d_SI_CS_DONE_INT_MASK) +#define SI_CS_START_LSB (scn->targetdef->d_SI_CS_START_LSB) +#define SI_CS_START_MASK (scn->targetdef->d_SI_CS_START_MASK) +#define SI_CS_RX_CNT_LSB (scn->targetdef->d_SI_CS_RX_CNT_LSB) +#define SI_CS_RX_CNT_MASK (scn->targetdef->d_SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_LSB (scn->targetdef->d_SI_CS_TX_CNT_LSB) +#define SI_CS_TX_CNT_MASK (scn->targetdef->d_SI_CS_TX_CNT_MASK) +#define EEPROM_SZ (scn->targetdef->d_BOARD_DATA_SZ) +#define EEPROM_EXT_SZ (scn->targetdef->d_BOARD_EXT_DATA_SZ) +#define MBOX_BASE_ADDRESS (scn->targetdef->d_MBOX_BASE_ADDRESS) +#define LOCAL_SCRATCH_OFFSET (scn->targetdef->d_LOCAL_SCRATCH_OFFSET) +#define CPU_CLOCK_OFFSET (scn->targetdef->d_CPU_CLOCK_OFFSET) +#define LPO_CAL_OFFSET (scn->targetdef->d_LPO_CAL_OFFSET) +#define GPIO_PIN10_OFFSET (scn->targetdef->d_GPIO_PIN10_OFFSET) +#define GPIO_PIN11_OFFSET (scn->targetdef->d_GPIO_PIN11_OFFSET) +#define GPIO_PIN12_OFFSET (scn->targetdef->d_GPIO_PIN12_OFFSET) +#define GPIO_PIN13_OFFSET (scn->targetdef->d_GPIO_PIN13_OFFSET) +#define CLOCK_GPIO_OFFSET (scn->targetdef->d_CLOCK_GPIO_OFFSET) +#define CPU_CLOCK_STANDARD_LSB (scn->targetdef->d_CPU_CLOCK_STANDARD_LSB) +#define CPU_CLOCK_STANDARD_MASK (scn->targetdef->d_CPU_CLOCK_STANDARD_MASK) +#define LPO_CAL_ENABLE_LSB (scn->targetdef->d_LPO_CAL_ENABLE_LSB) +#define LPO_CAL_ENABLE_MASK (scn->targetdef->d_LPO_CAL_ENABLE_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB \ + (scn->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB) +#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK \ + (scn->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +#define ANALOG_INTF_BASE_ADDRESS (scn->targetdef->d_ANALOG_INTF_BASE_ADDRESS) +#define WLAN_MAC_BASE_ADDRESS (scn->targetdef->d_WLAN_MAC_BASE_ADDRESS) +#define FW_INDICATOR_ADDRESS (scn->targetdef->d_FW_INDICATOR_ADDRESS) +#define DRAM_BASE_ADDRESS (scn->targetdef->d_DRAM_BASE_ADDRESS) +#define SOC_CORE_BASE_ADDRESS (scn->targetdef->d_SOC_CORE_BASE_ADDRESS) +#define CORE_CTRL_ADDRESS (scn->targetdef->d_CORE_CTRL_ADDRESS) +#define CE_COUNT (scn->targetdef->d_CE_COUNT) +#define PCIE_INTR_ENABLE_ADDRESS (scn->targetdef->d_PCIE_INTR_ENABLE_ADDRESS) +#define PCIE_INTR_CLR_ADDRESS (scn->targetdef->d_PCIE_INTR_CLR_ADDRESS) +#define PCIE_INTR_FIRMWARE_MASK (scn->targetdef->d_PCIE_INTR_FIRMWARE_MASK) +#define PCIE_INTR_CE_MASK_ALL (scn->targetdef->d_PCIE_INTR_CE_MASK_ALL) +#define CORE_CTRL_CPU_INTR_MASK (scn->targetdef->d_CORE_CTRL_CPU_INTR_MASK) +#define PCIE_INTR_CAUSE_ADDRESS (scn->targetdef->d_PCIE_INTR_CAUSE_ADDRESS) +#define SOC_RESET_CONTROL_ADDRESS (scn->targetdef->d_SOC_RESET_CONTROL_ADDRESS) +#define HOST_GROUP0_MASK (PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL | \ + A_SOC_CORE_PCIE_INTR_ENABLE_GRP0_Q6_MASK) +#define SOC_RESET_CONTROL_CE_RST_MASK \ + (scn->targetdef->d_SOC_RESET_CONTROL_CE_RST_MASK) +#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK \ + (scn->targetdef->d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK) +#define CPU_INTR_ADDRESS (scn->targetdef->d_CPU_INTR_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ADDRESS \ + (scn->targetdef->d_SOC_LF_TIMER_CONTROL0_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK \ + (scn->targetdef->d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK) +#define SOC_LF_TIMER_STATUS0_ADDRESS \ + (scn->targetdef->d_SOC_LF_TIMER_STATUS0_ADDRESS) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB \ + (scn->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK \ + (scn->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) \ + (((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> \ + SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) \ + (((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & \ + SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +/* hif_ipci.c */ +#define CHIP_ID_ADDRESS (scn->targetdef->d_SOC_CHIP_ID_ADDRESS) +#define SOC_CHIP_ID_REVISION_MASK (scn->targetdef->d_SOC_CHIP_ID_REVISION_MASK) +#define SOC_CHIP_ID_REVISION_LSB (scn->targetdef->d_SOC_CHIP_ID_REVISION_LSB) +#define SOC_CHIP_ID_VERSION_MASK (scn->targetdef->d_SOC_CHIP_ID_VERSION_MASK) +#define SOC_CHIP_ID_VERSION_LSB (scn->targetdef->d_SOC_CHIP_ID_VERSION_LSB) +#define CHIP_ID_REVISION_GET(x) \ + (((x) & SOC_CHIP_ID_REVISION_MASK) >> SOC_CHIP_ID_REVISION_LSB) +#define CHIP_ID_VERSION_GET(x) \ + (((x) & SOC_CHIP_ID_VERSION_MASK) >> SOC_CHIP_ID_VERSION_LSB) +/* hif_ipci.c end */ + +/* misc */ +#define SR_WR_INDEX_ADDRESS (scn->targetdef->d_SR_WR_INDEX_ADDRESS) +#define DST_WATERMARK_ADDRESS (scn->targetdef->d_DST_WATERMARK_ADDRESS) +#define SOC_POWER_REG_OFFSET (scn->targetdef->d_SOC_POWER_REG_OFFSET) +/* end */ + +/* copy_engine.c */ +/* end */ +/* PLL start */ +#define EFUSE_OFFSET (scn->targetdef->d_EFUSE_OFFSET) +#define EFUSE_XTAL_SEL_MSB (scn->targetdef->d_EFUSE_XTAL_SEL_MSB) +#define EFUSE_XTAL_SEL_LSB (scn->targetdef->d_EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_MASK (scn->targetdef->d_EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OFFSET (scn->targetdef->d_BB_PLL_CONFIG_OFFSET) +#define BB_PLL_CONFIG_OUTDIV_MSB (scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_MSB) +#define BB_PLL_CONFIG_OUTDIV_LSB (scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_MASK (scn->targetdef->d_BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_MSB (scn->targetdef->d_BB_PLL_CONFIG_FRAC_MSB) +#define BB_PLL_CONFIG_FRAC_LSB (scn->targetdef->d_BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_MASK (scn->targetdef->d_BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_MSB (scn->targetdef->d_WLAN_PLL_SETTLE_TIME_MSB) +#define WLAN_PLL_SETTLE_TIME_LSB (scn->targetdef->d_WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_MASK (scn->targetdef->d_WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_SETTLE_OFFSET (scn->targetdef->d_WLAN_PLL_SETTLE_OFFSET) +#define WLAN_PLL_SETTLE_SW_MASK (scn->targetdef->d_WLAN_PLL_SETTLE_SW_MASK) +#define WLAN_PLL_SETTLE_RSTMASK (scn->targetdef->d_WLAN_PLL_SETTLE_RSTMASK) +#define WLAN_PLL_SETTLE_RESET (scn->targetdef->d_WLAN_PLL_SETTLE_RESET) +#define WLAN_PLL_CONTROL_NOPWD_MSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MSB) +#define WLAN_PLL_CONTROL_NOPWD_LSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_MASK \ + (scn->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_MSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MSB) +#define WLAN_PLL_CONTROL_BYPASS_LSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_MASK \ + (scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_BYPASS_RESET \ + (scn->targetdef->d_WLAN_PLL_CONTROL_BYPASS_RESET) +#define WLAN_PLL_CONTROL_CLK_SEL_MSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MSB) +#define WLAN_PLL_CONTROL_CLK_SEL_LSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_MASK \ + (scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_RESET \ + (scn->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_RESET) +#define WLAN_PLL_CONTROL_REFDIV_MSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MSB) +#define WLAN_PLL_CONTROL_REFDIV_LSB \ + (scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_MASK \ + (scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_REFDIV_RESET \ + (scn->targetdef->d_WLAN_PLL_CONTROL_REFDIV_RESET) +#define WLAN_PLL_CONTROL_DIV_MSB (scn->targetdef->d_WLAN_PLL_CONTROL_DIV_MSB) +#define WLAN_PLL_CONTROL_DIV_LSB (scn->targetdef->d_WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_MASK (scn->targetdef->d_WLAN_PLL_CONTROL_DIV_MASK) +#define WLAN_PLL_CONTROL_DIV_RESET \ + (scn->targetdef->d_WLAN_PLL_CONTROL_DIV_RESET) +#define WLAN_PLL_CONTROL_OFFSET (scn->targetdef->d_WLAN_PLL_CONTROL_OFFSET) +#define WLAN_PLL_CONTROL_SW_MASK (scn->targetdef->d_WLAN_PLL_CONTROL_SW_MASK) +#define WLAN_PLL_CONTROL_RSTMASK (scn->targetdef->d_WLAN_PLL_CONTROL_RSTMASK) +#define WLAN_PLL_CONTROL_RESET (scn->targetdef->d_WLAN_PLL_CONTROL_RESET) +#define SOC_CORE_CLK_CTRL_OFFSET (scn->targetdef->d_SOC_CORE_CLK_CTRL_OFFSET) +#define SOC_CORE_CLK_CTRL_DIV_MSB (scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MSB) +#define SOC_CORE_CLK_CTRL_DIV_LSB (scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_MASK \ + (scn->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_MSB \ + (scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_LSB \ + (scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_MASK \ + (scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_RESET \ + (scn->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_RESET) +#define RTC_SYNC_STATUS_OFFSET (scn->targetdef->d_RTC_SYNC_STATUS_OFFSET) +#define SOC_CPU_CLOCK_OFFSET (scn->targetdef->d_SOC_CPU_CLOCK_OFFSET) +#define SOC_CPU_CLOCK_STANDARD_MSB \ + (scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_MSB) +#define SOC_CPU_CLOCK_STANDARD_LSB \ + (scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_MASK \ + (scn->targetdef->d_SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ + +#define FW_CPU_PLL_CONFIG \ + (scn->targetdef->d_FW_CPU_PLL_CONFIG) + +#define WIFICMN_PCIE_BAR_REG_ADDRESS \ + (sc->targetdef->d_WIFICMN_PCIE_BAR_REG_ADDRESS) + + /* htt tx */ +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_MASK \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_MASK) +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_MASK \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_MASK) +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_MASK \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_MASK) +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_MASK \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_MASK) +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_LSB \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_LSB) +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_LSB \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_LSB) +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_LSB \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_LSB) +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_LSB \ + (pdev->targetdef->d_MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_LSB) + +#define CE_CMD_ADDRESS \ + (scn->targetdef->d_CE_CMD_ADDRESS) +#define CE_CMD_HALT_MASK \ + (scn->targetdef->d_CE_CMD_HALT_MASK) +#define CE_CMD_HALT_STATUS_MASK \ + (scn->targetdef->d_CE_CMD_HALT_STATUS_MASK) +#define CE_CMD_HALT_STATUS_LSB \ + (scn->targetdef->d_CE_CMD_HALT_STATUS_LSB) + +#define SI_CONFIG_ERR_INT_MASK \ + (scn->targetdef->d_SI_CONFIG_ERR_INT_MASK) +#define SI_CONFIG_ERR_INT_LSB \ + (scn->targetdef->d_SI_CONFIG_ERR_INT_LSB) +#define GPIO_ENABLE_W1TS_LOW_ADDRESS \ + (scn->targetdef->d_GPIO_ENABLE_W1TS_LOW_ADDRESS) +#define GPIO_PIN0_CONFIG_LSB \ + (scn->targetdef->d_GPIO_PIN0_CONFIG_LSB) +#define GPIO_PIN0_PAD_PULL_LSB \ + (scn->targetdef->d_GPIO_PIN0_PAD_PULL_LSB) +#define GPIO_PIN0_PAD_PULL_MASK \ + (scn->targetdef->d_GPIO_PIN0_PAD_PULL_MASK) + +#define SOC_CHIP_ID_REVISION_MSB \ + (scn->targetdef->d_SOC_CHIP_ID_REVISION_MSB) + +#define FW_AXI_MSI_ADDR \ + (scn->targetdef->d_FW_AXI_MSI_ADDR) +#define FW_AXI_MSI_DATA \ + (scn->targetdef->d_FW_AXI_MSI_DATA) +#define WLAN_SUBSYSTEM_CORE_ID_ADDRESS \ + (scn->targetdef->d_WLAN_SUBSYSTEM_CORE_ID_ADDRESS) +#define FPGA_VERSION_ADDRESS \ + (scn->targetdef->d_FPGA_VERSION_ADDRESS) + +/* SET macros */ +#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) \ + (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & \ + WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_SET(x) \ + (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_SET(x) \ + (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_SET(x) \ + (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_SET(x) \ + (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_SET(x) \ + (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK) +#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK) +#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK) +#define LPO_CAL_ENABLE_SET(x) \ + (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK) +#define CPU_CLOCK_STANDARD_SET(x) \ + (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) \ + (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +/* copy_engine.c */ +/* end */ +/* PLL start */ +#define EFUSE_XTAL_SEL_GET(x) \ + (((x) & EFUSE_XTAL_SEL_MASK) >> EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_SET(x) \ + (((x) << EFUSE_XTAL_SEL_LSB) & EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OUTDIV_GET(x) \ + (((x) & BB_PLL_CONFIG_OUTDIV_MASK) >> BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_SET(x) \ + (((x) << BB_PLL_CONFIG_OUTDIV_LSB) & BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_GET(x) \ + (((x) & BB_PLL_CONFIG_FRAC_MASK) >> BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_SET(x) \ + (((x) << BB_PLL_CONFIG_FRAC_LSB) & BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_GET(x) \ + (((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_SET(x) \ + (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_CONTROL_NOPWD_GET(x) \ + (((x) & WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_SET(x) \ + (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_GET(x) \ + (((x) & WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_SET(x) \ + (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_GET(x) \ + (((x) & WLAN_PLL_CONTROL_CLK_SEL_MASK) >> WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_SET(x) \ + (((x) << WLAN_PLL_CONTROL_CLK_SEL_LSB) & WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_REFDIV_GET(x) \ + (((x) & WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_SET(x) \ + (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_DIV_GET(x) \ + (((x) & WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_SET(x) \ + (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK) +#define SOC_CORE_CLK_CTRL_DIV_GET(x) \ + (((x) & SOC_CORE_CLK_CTRL_DIV_MASK) >> SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_SET(x) \ + (((x) << SOC_CORE_CLK_CTRL_DIV_LSB) & SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_GET(x) \ + (((x) & RTC_SYNC_STATUS_PLL_CHANGING_MASK) >> \ + RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_SET(x) \ + (((x) << RTC_SYNC_STATUS_PLL_CHANGING_LSB) & \ + RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define SOC_CPU_CLOCK_STANDARD_GET(x) \ + (((x) & SOC_CPU_CLOCK_STANDARD_MASK) >> SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_SET(x) \ + (((x) << SOC_CPU_CLOCK_STANDARD_LSB) & SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ +#define WLAN_GPIO_PIN0_CONFIG_SET(x) \ + (((x) << GPIO_PIN0_CONFIG_LSB) & GPIO_PIN0_CONFIG_MASK) +#define WLAN_GPIO_PIN0_PAD_PULL_SET(x) \ + (((x) << GPIO_PIN0_PAD_PULL_LSB) & GPIO_PIN0_PAD_PULL_MASK) +#define SI_CONFIG_ERR_INT_SET(x) \ + (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK) + +#ifdef QCA_WIFI_3_0_ADRASTEA +#define Q6_ENABLE_REGISTER_0 \ + (scn->targetdef->d_Q6_ENABLE_REGISTER_0) +#define Q6_ENABLE_REGISTER_1 \ + (scn->targetdef->d_Q6_ENABLE_REGISTER_1) +#define Q6_CAUSE_REGISTER_0 \ + (scn->targetdef->d_Q6_CAUSE_REGISTER_0) +#define Q6_CAUSE_REGISTER_1 \ + (scn->targetdef->d_Q6_CAUSE_REGISTER_1) +#define Q6_CLEAR_REGISTER_0 \ + (scn->targetdef->d_Q6_CLEAR_REGISTER_0) +#define Q6_CLEAR_REGISTER_1 \ + (scn->targetdef->d_Q6_CLEAR_REGISTER_1) +#endif + +#ifdef CONFIG_BYPASS_QMI +#define BYPASS_QMI_TEMP_REGISTER \ + (scn->targetdef->d_BYPASS_QMI_TEMP_REGISTER) +#endif + +#define A_SOC_PCIE_PCIE_BAR0_START (scn->hostdef->d_A_SOC_PCIE_PCIE_BAR0_START) +#define DESC_DATA_FLAG_MASK (scn->hostdef->d_DESC_DATA_FLAG_MASK) +#define MUX_ID_MASK (scn->hostdef->d_MUX_ID_MASK) +#define TRANSACTION_ID_MASK (scn->hostdef->d_TRANSACTION_ID_MASK) +#define HOST_CE_COUNT (scn->hostdef->d_HOST_CE_COUNT) +#define ENABLE_MSI (scn->hostdef->d_ENABLE_MSI) +#define INT_STATUS_ENABLE_ERROR_LSB \ + (scn->hostdef->d_INT_STATUS_ENABLE_ERROR_LSB) +#define INT_STATUS_ENABLE_ERROR_MASK \ + (scn->hostdef->d_INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_LSB (scn->hostdef->d_INT_STATUS_ENABLE_CPU_LSB) +#define INT_STATUS_ENABLE_CPU_MASK (scn->hostdef->d_INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_LSB \ + (scn->hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB) +#define INT_STATUS_ENABLE_COUNTER_MASK \ + (scn->hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_LSB \ + (scn->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB) +#define INT_STATUS_ENABLE_MBOX_DATA_MASK \ + (scn->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB \ + (scn->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK \ + (scn->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB \ + (scn->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK \ + (scn->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB \ + (scn->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB) +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK \ + (scn->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define INT_STATUS_ENABLE_ADDRESS \ + (scn->hostdef->d_INT_STATUS_ENABLE_ADDRESS) +#define CPU_INT_STATUS_ENABLE_BIT_LSB \ + (scn->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB) +#define CPU_INT_STATUS_ENABLE_BIT_MASK \ + (scn->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK) +#define HOST_INT_STATUS_ADDRESS (scn->hostdef->d_HOST_INT_STATUS_ADDRESS) +#define CPU_INT_STATUS_ADDRESS (scn->hostdef->d_CPU_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_ADDRESS (scn->hostdef->d_ERROR_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_WAKEUP_MASK \ + (scn->hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK) +#define ERROR_INT_STATUS_WAKEUP_LSB \ + (scn->hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK \ + (scn->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK) +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB \ + (scn->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK \ + (scn->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK) +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB \ + (scn->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define COUNT_DEC_ADDRESS (scn->hostdef->d_COUNT_DEC_ADDRESS) +#define HOST_INT_STATUS_CPU_MASK (scn->hostdef->d_HOST_INT_STATUS_CPU_MASK) +#define HOST_INT_STATUS_CPU_LSB (scn->hostdef->d_HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_MASK (scn->hostdef->d_HOST_INT_STATUS_ERROR_MASK) +#define HOST_INT_STATUS_ERROR_LSB (scn->hostdef->d_HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_MASK \ + (scn->hostdef->d_HOST_INT_STATUS_COUNTER_MASK) +#define HOST_INT_STATUS_COUNTER_LSB \ + (scn->hostdef->d_HOST_INT_STATUS_COUNTER_LSB) +#define RX_LOOKAHEAD_VALID_ADDRESS (scn->hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS) +#define WINDOW_DATA_ADDRESS (scn->hostdef->d_WINDOW_DATA_ADDRESS) +#define WINDOW_READ_ADDR_ADDRESS (scn->hostdef->d_WINDOW_READ_ADDR_ADDRESS) +#define WINDOW_WRITE_ADDR_ADDRESS (scn->hostdef->d_WINDOW_WRITE_ADDR_ADDRESS) +#define SOC_GLOBAL_RESET_ADDRESS (scn->hostdef->d_SOC_GLOBAL_RESET_ADDRESS) +#define RTC_STATE_ADDRESS (scn->hostdef->d_RTC_STATE_ADDRESS) +#define RTC_STATE_COLD_RESET_MASK (scn->hostdef->d_RTC_STATE_COLD_RESET_MASK) +#define PCIE_LOCAL_BASE_ADDRESS (scn->hostdef->d_PCIE_LOCAL_BASE_ADDRESS) +#define PCIE_SOC_WAKE_RESET (scn->hostdef->d_PCIE_SOC_WAKE_RESET) +#define PCIE_SOC_WAKE_ADDRESS (scn->hostdef->d_PCIE_SOC_WAKE_ADDRESS) +#define PCIE_SOC_WAKE_V_MASK (scn->hostdef->d_PCIE_SOC_WAKE_V_MASK) +#define RTC_STATE_V_MASK (scn->hostdef->d_RTC_STATE_V_MASK) +#define RTC_STATE_V_LSB (scn->hostdef->d_RTC_STATE_V_LSB) +#define FW_IND_EVENT_PENDING (scn->hostdef->d_FW_IND_EVENT_PENDING) +#define FW_IND_INITIALIZED (scn->hostdef->d_FW_IND_INITIALIZED) +#define FW_IND_HELPER (scn->hostdef->d_FW_IND_HELPER) +#define RTC_STATE_V_ON (scn->hostdef->d_RTC_STATE_V_ON) + +#define FW_IND_HOST_READY (scn->hostdef->d_FW_IND_HOST_READY) + +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_MASK \ + (scn->hostdef->d_HOST_INT_STATUS_MBOX_DATA_MASK) +#define HOST_INT_STATUS_MBOX_DATA_LSB \ + (scn->hostdef->d_HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#if !defined(SOC_PCIE_BASE_ADDRESS) +#define SOC_PCIE_BASE_ADDRESS 0 +#endif + +#if !defined(PCIE_SOC_RDY_STATUS_ADDRESS) +#define PCIE_SOC_RDY_STATUS_ADDRESS 0 +#define PCIE_SOC_RDY_STATUS_BAR_MASK 0 +#endif + +#if !defined(MSI_MAGIC_ADR_ADDRESS) +#define MSI_MAGIC_ADR_ADDRESS 0 +#define MSI_MAGIC_ADDRESS 0 +#endif + +/* SET/GET macros */ +#define INT_STATUS_ENABLE_ERROR_SET(x) \ + (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_SET(x) \ + (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_SET(x) \ + (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & \ + INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) \ + (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & \ + INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define CPU_INT_STATUS_ENABLE_BIT_SET(x) \ + (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & \ + CPU_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) \ + (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & \ + ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) \ + (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & \ + ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) \ + (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & \ + COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_INT_STATUS_WAKEUP_GET(x) \ + (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> \ + ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) \ + (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> \ + ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) \ + (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> \ + ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define HOST_INT_STATUS_CPU_GET(x) \ + (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_GET(x) \ + (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_GET(x) \ + (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) +#define RTC_STATE_V_GET(x) \ + (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_GET(x) \ + (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> \ + HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#define INVALID_REG_LOC_DUMMY_DATA 0xAA + +#define AR6320_CORE_CLK_DIV_ADDR 0x403fa8 +#define AR6320_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320_CPU_SPEED_ADDR 0x403fa4 +#define AR6320V2_CORE_CLK_DIV_ADDR 0x403fd8 +#define AR6320V2_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320V2_CPU_SPEED_ADDR 0x403fd4 +#define AR6320V3_CORE_CLK_DIV_ADDR 0x404028 +#define AR6320V3_CPU_PLL_INIT_DONE_ADDR 0x404020 +#define AR6320V3_CPU_SPEED_ADDR 0x404024 + +enum a_refclk_speed_t { + SOC_REFCLK_UNKNOWN = -1, /* Unsupported ref clock -- use PLL Bypass */ + SOC_REFCLK_48_MHZ = 0, + SOC_REFCLK_19_2_MHZ = 1, + SOC_REFCLK_24_MHZ = 2, + SOC_REFCLK_26_MHZ = 3, + SOC_REFCLK_37_4_MHZ = 4, + SOC_REFCLK_38_4_MHZ = 5, + SOC_REFCLK_40_MHZ = 6, + SOC_REFCLK_52_MHZ = 7, +}; + +#define A_REFCLK_UNKNOWN SOC_REFCLK_UNKNOWN +#define A_REFCLK_48_MHZ SOC_REFCLK_48_MHZ +#define A_REFCLK_19_2_MHZ SOC_REFCLK_19_2_MHZ +#define A_REFCLK_24_MHZ SOC_REFCLK_24_MHZ +#define A_REFCLK_26_MHZ SOC_REFCLK_26_MHZ +#define A_REFCLK_37_4_MHZ SOC_REFCLK_37_4_MHZ +#define A_REFCLK_38_4_MHZ SOC_REFCLK_38_4_MHZ +#define A_REFCLK_40_MHZ SOC_REFCLK_40_MHZ +#define A_REFCLK_52_MHZ SOC_REFCLK_52_MHZ + +#define TARGET_CPU_FREQ 176000000 + +struct wlan_pll_s { + uint32_t refdiv; + uint32_t div; + uint32_t rnfrac; + uint32_t outdiv; +}; + +struct cmnos_clock_s { + enum a_refclk_speed_t refclk_speed; + uint32_t refclk_hz; + uint32_t pll_settling_time; /* 50us */ + struct wlan_pll_s wlan_pll; +}; + +struct tgt_reg_section { + uint32_t start_addr; + uint32_t end_addr; +}; + +struct tgt_reg_table { + const struct tgt_reg_section *section; + uint32_t section_size; +}; + +struct hif_softc; +void hif_target_register_tbl_attach(struct hif_softc *scn, u32 target_type); +void hif_register_tbl_attach(struct hif_softc *scn, u32 hif_type); + +#endif /* _REGTABLE_IPCIE_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/target_type.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/target_type.h index 7aa3d0f0049e221a2accf530a69c372ac65436cf..8a5fc373e1ee54985e10096da16e8e21c8d3fc72 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/inc/target_type.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/target_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,35 +24,12 @@ extern "C" { #endif /* __cplusplus */ /* Header files */ +#include "bmi_msg.h" /* TARGET definition needs to be abstracted in fw common * header files, below is the placeholder till WIN codebase * moved to latest copy of fw common header files. */ -#ifdef CONFIG_WIN -#define TARGET_TYPE_UNKNOWN 0 -#define TARGET_TYPE_AR6001 1 -#define TARGET_TYPE_AR6002 2 -#define TARGET_TYPE_AR6003 3 -#define TARGET_TYPE_AR6004 5 -#define TARGET_TYPE_AR6006 6 -#define TARGET_TYPE_AR9888 7 -#define TARGET_TYPE_AR900B 9 -#define TARGET_TYPE_QCA9984 10 -#define TARGET_TYPE_IPQ4019 11 -#define TARGET_TYPE_QCA9888 12 -/* For attach Peregrine 2.0 board target_reg_tbl only */ -#define TARGET_TYPE_AR9888V2 13 -/* For attach Rome1.0 target_reg_tbl only*/ -#define TARGET_TYPE_AR6320V1 14 -/* For Rome2.0/2.1 target_reg_tbl ID*/ -#define TARGET_TYPE_AR6320V2 15 -/* For Rome3.0 target_reg_tbl ID*/ -#define TARGET_TYPE_AR6320V3 16 -/* For Tufello1.0 target_reg_tbl ID*/ -#define TARGET_TYPE_QCA9377V1 17 -#endif /* CONFIG_WIN */ -#define TARGET_TYPE_AR6320 8 /* For Adrastea target */ #define TARGET_TYPE_ADRASTEA 19 #ifndef TARGET_TYPE_QCA8074 @@ -74,6 +51,26 @@ extern "C" { #ifndef TARGET_TYPE_QCA6018 #define TARGET_TYPE_QCA6018 25 #endif +#ifndef TARGET_TYPE_QCN9000 +#define TARGET_TYPE_QCN9000 26 +#endif +/* HastingsPrime */ +#ifndef TARGET_TYPE_QCA6490 +#define TARGET_TYPE_QCA6490 27 +#endif + +/* Moselle */ +#ifndef TARGET_TYPE_QCA6750 +#define TARGET_TYPE_QCA6750 28 +#endif + +#ifndef TARGET_TYPE_QCA5018 +#define TARGET_TYPE_QCA5018 29 +#endif + +#ifndef TARGET_TYPE_QCN6122 +#define TARGET_TYPE_QCN6122 30 +#endif #ifdef __cplusplus } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/inc/targetdef.h b/drivers/staging/qca-wifi-host-cmn/hif/inc/targetdef.h index 180ac8ab31f314f845df524c8eeb0c431c2a09fe..8bd957216bc19d8360282ceb839733216b83a38a 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/inc/targetdef.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/inc/targetdef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016,2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016,2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,12 +35,16 @@ extern struct targetdef_s *QCA9984_TARGETdef; extern struct targetdef_s *QCA9888_TARGETdef; extern struct targetdef_s *QCA6290_TARGETdef; extern struct targetdef_s *QCA6390_TARGETdef; +extern struct targetdef_s *QCA6490_TARGETdef; +extern struct targetdef_s *QCA6750_TARGETdef; + #ifdef ATH_AHB extern struct targetdef_s *IPQ4019_TARGETdef; #endif extern struct targetdef_s *QCA8074_TARGETdef; extern struct targetdef_s *QCA8074V2_TARGETDEF; extern struct targetdef_s *QCA6018_TARGETDEF; +extern struct targetdef_s *QCN9000_TARGETDEF; extern struct ce_reg_def *AR6002_CE_TARGETdef; extern struct ce_reg_def *AR6003_CE_TARGETdef; @@ -53,12 +57,15 @@ extern struct ce_reg_def *QCA9984_CE_TARGETdef; extern struct ce_reg_def *QCA9888_CE_TARGETdef; extern struct ce_reg_def *QCA6290_CE_TARGETdef; extern struct ce_reg_def *QCA6390_CE_TARGETdef; +extern struct ce_reg_def *QCA6490_CE_TARGETdef; +extern struct ce_reg_def *QCA6750_CE_TARGETdef; #ifdef ATH_AHB extern struct ce_reg_def *IPQ4019_CE_TARGETdef; #endif extern struct ce_reg_def *QCA8074_CE_TARGETdef; extern struct ce_reg_def *QCA8074V2_CE_TARGETDEF; extern struct ce_reg_def *QCA6018_CE_TARGETDEF; +extern struct ce_reg_def *QCN9000_CE_TARGETDEF; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320def.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320def.h index 3014f6549b59561ff8e8f88fee2501a75a60b8f9..7fdfb3de2bf9747eed5f814d27f4b4dd5a3d3add 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320def.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -97,7 +97,8 @@ #define AR6320_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 #define AR6320_RX_MPDU_START_2_TID_LSB 28 #define AR6320_RX_MPDU_START_2_TID_MASK 0xf0000000 -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) #define AR6320_SOC_PCIE_BASE_ADDRESS 0x00038000 #define AR6320_CE_WRAPPER_BASE_ADDRESS 0x00034000 #define AR6320_CE0_BASE_ADDRESS 0x00034400 @@ -218,7 +219,8 @@ #define AR6320_SOC_CHIP_ID_VERSION_LSB 18 #define AR6320_SOC_CHIP_ID_REVISION_MASK 0x00000f00 #define AR6320_SOC_CHIP_ID_REVISION_LSB 8 -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) #define AR6320_SOC_POWER_REG_OFFSET 0x0000010c /* Copy Engine Debug */ #define AR6320_WLAN_DEBUG_INPUT_SEL_OFFSET 0x0000010c @@ -452,7 +454,8 @@ struct targetdef_s ar6320_targetdef = { .d_DRAM_BASE_ADDRESS = AR6320_DRAM_BASE_ADDRESS, .d_SOC_CORE_BASE_ADDRESS = AR6320_SOC_CORE_BASE_ADDRESS, .d_CORE_CTRL_ADDRESS = AR6320_CORE_CTRL_ADDRESS, -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, #endif @@ -513,7 +516,8 @@ struct targetdef_s ar6320_targetdef = { AR6320_RX_ATTENTION_0_MSDU_DONE_MASK, .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) .d_CE_COUNT = AR6320_CE_COUNT, .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, .d_PCIE_INTR_ENABLE_ADDRESS = AR6320_PCIE_INTR_ENABLE_ADDRESS, @@ -696,7 +700,8 @@ struct hostdef_s ar6320_hostdef = { .d_SOC_GLOBAL_RESET_ADDRESS = AR6320_SOC_GLOBAL_RESET_ADDRESS, .d_RTC_STATE_ADDRESS = AR6320_RTC_STATE_ADDRESS, .d_RTC_STATE_COLD_RESET_MASK = AR6320_RTC_STATE_COLD_RESET_MASK, -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) .d_PCIE_LOCAL_BASE_ADDRESS = AR6320_PCIE_LOCAL_BASE_ADDRESS, .d_PCIE_SOC_WAKE_RESET = AR6320_PCIE_SOC_WAKE_RESET, .d_PCIE_SOC_WAKE_ADDRESS = AR6320_PCIE_SOC_WAKE_ADDRESS, @@ -725,7 +730,8 @@ struct hostdef_s ar6320_hostdef = { #endif }; -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) struct ce_reg_def ar6320_ce_targetdef = { /* copy_engine.c */ .d_DST_WR_INDEX_ADDRESS = AR6320_DST_WR_INDEX_ADDRESS, diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320v2def.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320v2def.h index fdb4e92ae3f4d2d6840dbad664f1d370a3c7f25c..0985ae6cfff0b0abc320df889e3a422f0a3d1eb5 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320v2def.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ar6320v2def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -182,7 +182,8 @@ #if defined(HIF_SDIO) #define AR6320V2_FW_IND_HELPER 4 #endif -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) #define AR6320V2_CE_WRAPPER_BASE_ADDRESS 0x00034000 #define AR6320V2_CE0_BASE_ADDRESS 0x00034400 #define AR6320V2_CE1_BASE_ADDRESS 0x00034800 @@ -459,7 +460,8 @@ struct targetdef_s ar6320v2_targetdef = { .d_DRAM_BASE_ADDRESS = AR6320V2_DRAM_BASE_ADDRESS, .d_SOC_CORE_BASE_ADDRESS = AR6320V2_SOC_CORE_BASE_ADDRESS, .d_CORE_CTRL_ADDRESS = AR6320V2_CORE_CTRL_ADDRESS, -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, #endif @@ -526,7 +528,8 @@ struct targetdef_s ar6320v2_targetdef = { AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK, .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) .d_CE_COUNT = AR6320V2_CE_COUNT, .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, .d_PCIE_INTR_ENABLE_ADDRESS = AR6320V2_PCIE_INTR_ENABLE_ADDRESS, @@ -728,7 +731,8 @@ struct hostdef_s ar6320v2_hostdef = { .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB, #endif -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) .d_FW_IND_HELPER = AR6320V2_FW_IND_HELPER, .d_MUX_ID_MASK = AR6320V2_MUX_ID_MASK, .d_TRANSACTION_ID_MASK = AR6320V2_TRANSACTION_ID_MASK, @@ -749,7 +753,8 @@ struct hostdef_s ar6320v2_hostdef = { #endif }; -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) struct ce_reg_def ar6320v2_ce_targetdef = { /* copy_engine.c */ .d_DST_WR_INDEX_ADDRESS = AR6320V2_DST_WR_INDEX_ADDRESS, diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ath_procfs.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ath_procfs.c index 16a707fd4ab46456b9bb88767b1232b6461dccc4..8e63dc8a7da86e759651717aeb8daa33a5f07811 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ath_procfs.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ath_procfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -83,9 +83,13 @@ static ssize_t ath_procfs_diag_read(struct file *file, char __user *buf, (scn->bus_type == QDF_BUS_TYPE_PCI && ((tgt_info->target_type == TARGET_TYPE_QCA6290) || (tgt_info->target_type == TARGET_TYPE_QCA6390) || + (tgt_info->target_type == TARGET_TYPE_QCA6490) || (tgt_info->target_type == TARGET_TYPE_QCA8074) || (tgt_info->target_type == TARGET_TYPE_QCA8074V2) || - (tgt_info->target_type == TARGET_TYPE_QCA6018)))) { + (tgt_info->target_type == TARGET_TYPE_QCN9000) || + (tgt_info->target_type == TARGET_TYPE_QCA6018))) || + (scn->bus_type == QDF_BUS_TYPE_IPCI && + (tgt_info->target_type == TARGET_TYPE_QCA6750))) { memtype = ((uint32_t)(*pos) & 0xff000000) >> 24; offset = (uint32_t)(*pos) & 0xffffff; HIF_DBG("%s: offset 0x%x memtype 0x%x, datalen %zu\n", @@ -158,9 +162,13 @@ static ssize_t ath_procfs_diag_write(struct file *file, ((scn->bus_type == QDF_BUS_TYPE_PCI) && ((tgt_info->target_type == TARGET_TYPE_QCA6290) || (tgt_info->target_type == TARGET_TYPE_QCA6390) || + (tgt_info->target_type == TARGET_TYPE_QCA6490) || (tgt_info->target_type == TARGET_TYPE_QCA8074) || (tgt_info->target_type == TARGET_TYPE_QCA8074V2) || - (tgt_info->target_type == TARGET_TYPE_QCA6018)))) { + (tgt_info->target_type == TARGET_TYPE_QCN9000) || + (tgt_info->target_type == TARGET_TYPE_QCA6018))) || + (scn->bus_type == QDF_BUS_TYPE_IPCI && + (tgt_info->target_type == TARGET_TYPE_QCA6750))) { memtype = ((uint32_t)(*pos) & 0xff000000) >> 24; offset = (uint32_t)(*pos) & 0xffffff; HIF_DBG("%s: offset 0x%x memtype 0x%x, datalen %zu\n", diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_api.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_api.h index 5ff48e0d16944ed8a13afa53b321ee2409f3eb3b..7b6b97be4814c4a7c1d61309993177777e41f6fe 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_api.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -546,6 +546,8 @@ struct ce_ops { void (*ce_prepare_shadow_register_v2_cfg)(struct hif_softc *scn, struct pld_shadow_reg_v2_cfg **shadow_config, int *num_shadow_registers_configured); + int (*ce_get_index_info)(struct hif_softc *scn, void *ce_state, + struct ce_index *info); }; int hif_ce_bus_early_suspend(struct hif_softc *scn); diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_assignment.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_assignment.h index 4f5b67f72e7995947df73c1c769291276ad91759..dce741cffa2531e371ca56ee5754b228bf365a92 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_assignment.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_assignment.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -63,7 +63,10 @@ static void hif_target_dump_access_log(void); /* Maximum number of Copy Engine's supported */ #define CE_HTT_H2T_MSG_SRC_NENTRIES 2048 +#define CE_HTT_H2T_MSG_SRC_NENTRIES_QCA6390 256 +#define CE_HTT_H2T_MSG_SRC_NENTRIES_QCA6490 256 #define CE_HTT_H2T_MSG_SRC_NENTRIES_AR900B 4096 +#define CE_HTT_H2T_MSG_SRC_NENTRIES_QCN7605 4096 #define EPPING_CE_FLAGS_POLL \ (CE_ATTR_DISABLE_INTR|CE_ATTR_ENABLE_POLL|CE_ATTR_FLAGS) @@ -85,7 +88,7 @@ static struct CE_attr host_ce_config_wlan_qcn7605[] = { { /* CE3 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, /* host->target HTT */ { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, - CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, + CE_HTT_H2T_MSG_SRC_NENTRIES_QCN7605, 256, 0, NULL,}, #ifdef IPA_OFFLOAD /* ipa_uc->target HTC control */ { /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, @@ -676,7 +679,11 @@ static struct CE_attr host_ce_config_wlan_qca8074[] = { { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, /* target -> host PKTLOG */ +#ifdef REMOVE_PKT_LOG + { /* CE5 */ 0, 0, 0, 0, 0, NULL,}, +#else { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, +#endif /* Target autonomous HIF_memcpy */ { /* CE6 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0, 0, 0, 0, NULL,}, @@ -691,13 +698,18 @@ static struct CE_attr host_ce_config_wlan_qca8074[] = { { /* CE11 unused */ 0, 0, 0, 0, 0, NULL,}, }; +#if defined(QCA_LOWMEM_CONFIG) || defined(QCA_512M_CONFIG) +#define T2H_WMI_RING_SIZE 32 +#else +#define T2H_WMI_RING_SIZE 512 +#endif static struct CE_pipe_config target_ce_config_wlan_qca8074[] = { /* host->target HTC control and raw streams */ { /* CE0 */ 0, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, /* target->host HTT */ { /* CE1 */ 1, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, /* target->host WMI + HTC control */ - { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + { /* CE2 */ 2, PIPEDIR_IN, T2H_WMI_RING_SIZE, 2048, CE_ATTR_FLAGS, 0,}, /* host->target WMI */ { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, /* host->target HTT */ @@ -705,7 +717,11 @@ static struct CE_pipe_config target_ce_config_wlan_qca8074[] = { (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, /* NB: 50% of src nentries, since tx has 2 frags */ /* Target -> host PKTLOG */ +#ifdef REMOVE_PKT_LOG + { /* CE5 */ 5, PIPEDIR_NONE, 0, 0, 0, 0,}, +#else { /* CE5 */ 5, PIPEDIR_IN, 32, 2048, 0, 0,}, +#endif /* Reserved for target autonomous HIF_memcpy */ { /* CE6 */ 6, PIPEDIR_INOUT, 32, 65535, 64, 0,}, /* CE7 used only by Host */ @@ -733,7 +749,11 @@ static struct CE_attr host_ce_config_wlan_qca8074_pci[] = { { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, /* target -> host PKTLOG */ +#ifdef REMOVE_PKT_LOG + { /* CE5 */ 0, 0, 0, 0, 0, NULL,}, +#else { /* CE5 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 512, NULL,}, +#endif /* Target autonomous HIF_memcpy */ { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, /* host->target WMI (mac1) */ @@ -901,6 +921,58 @@ static struct CE_pipe_config target_ce_config_wlan_adrastea[] = { { /* CE11 */ 11, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, }; +#define QCN_9000_CE_COUNT 6 +/* QCN9000 enable polling mode */ +static struct CE_attr host_ce_config_wlan_qcn9000[] = { + /* host->target HTC control and raw streams */ + {/*CE0*/ (CE_ATTR_FLAGS), 0, 16, 2048, 0, NULL,}, + /* target->host HTT + HTC control */ + {/*CE1*/ (CE_ATTR_FLAGS), 0, 0, 2048, + 512, NULL,}, + /* target->host WMI */ + {/*CE2*/ (CE_ATTR_FLAGS), 0, 0, 2048, + 32, NULL,}, + /* host->target WMI */ + {/*CE3*/ (CE_ATTR_FLAGS), 0, 32, 2048, 0, NULL,}, + /* host->target HTT */ + {/*CE4*/ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, + CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, + /* target -> host PKTLOG */ + {/*CE5*/ (CE_ATTR_FLAGS), 0, 0, 2048, + 512, NULL,}, + /* Target autonomous HIF_memcpy */ + {/*CE6*/ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* host->target WMI (mac1) */ + {/*CE7*/ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, + /* Reserved for target */ + {/*CE8*/ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; + +static struct CE_pipe_config target_ce_config_wlan_qcn9000[] = { + /* host->target HTC control and raw streams */ + { /* CE0 */ 0, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host HTT */ + { /* CE1 */ 1, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host WMI + HTC control */ + { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target WMI */ + { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target HTT */ + { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, + (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + /* Target -> host PKTLOG */ + { /* CE5 */ 5, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* Reserved for target autonomous HIF_memcpy */ + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE7 used only by Host */ + { /* CE7 */ 7, PIPEDIR_OUT, 32, 2048, + 8192, 0,}, + /* Reserved for target */ + { /* CE8 */ 8, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; + #define QCA_6290_CE_COUNT 9 #ifdef QCA_6290_AP_MODE static struct CE_attr host_ce_config_wlan_qca6290[] = { @@ -1014,7 +1086,7 @@ static struct CE_attr host_ce_config_wlan_qca6390[] = { { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, /* host->target HTT */ { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, - CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, + CE_HTT_H2T_MSG_SRC_NENTRIES_QCA6390, 256, 0, NULL,}, /* target -> host PKTLOG */ { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, /* Target autonomous HIF_memcpy */ @@ -1050,4 +1122,102 @@ static struct CE_pipe_config target_ce_config_wlan_qca6390[] = { { /* CE8 */ 8, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ }; + +#define QCA_6490_CE_COUNT 9 +static struct CE_attr host_ce_config_wlan_qca6490[] = { + /* host->target HTC control and raw streams */ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 2048, 0, NULL,}, + /* target->host HTT + HTC control */ + { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* target->host WMI */ + { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 4096, 64, NULL,}, + /* host->target WMI */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, + /* host->target HTT */ + { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, + CE_HTT_H2T_MSG_SRC_NENTRIES_QCA6490, 256, 0, NULL,}, + /* target -> host PKTLOG */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* Target autonomous HIF_memcpy */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* ce_diag, the Diagnostic Window */ + { /* CE7 */ (CE_ATTR_DIAG_FLAGS | CE_ATTR_DISABLE_INTR), 0, + 0, DIAG_TRANSFER_LIMIT, 0, NULL,}, + /* Reserved for target */ + { /* CE8 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; + +static struct CE_pipe_config target_ce_config_wlan_qca6490[] = { + /* host->target HTC control and raw streams */ + { /* CE0 */ 0, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host HTT */ + { /* CE1 */ 1, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host WMI + HTC control */ + { /* CE2 */ 2, PIPEDIR_IN, 32, 4096, CE_ATTR_FLAGS, 0,}, + /* host->target WMI */ + { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target HTT */ + { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, + (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + /* Target -> host PKTLOG */ + { /* CE5 */ 5, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* Reserved for target autonomous HIF_memcpy */ + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE7 used only by Host */ + { /* CE7 */ 7, PIPEDIR_INOUT_H2H, 0, 0, + (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + /* Reserved for target */ + { /* CE8 */ 8, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; + +#define QCA_6750_CE_COUNT 9 +static struct CE_attr host_ce_config_wlan_qca6750[] = { + /* host->target HTC control and raw streams */ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 2048, 0, NULL,}, + /* target->host HTT + HTC control */ + { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* target->host WMI */ + { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL,}, + /* host->target WMI */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, + /* host->target HTT */ + { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, + CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, + /* target -> host PKTLOG */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* Target autonomous HIF_memcpy */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* ce_diag, the Diagnostic Window */ + { /* CE7 */ (CE_ATTR_DIAG_FLAGS | CE_ATTR_DISABLE_INTR), 0, + 0, DIAG_TRANSFER_LIMIT, 0, NULL,}, + /* Reserved for target */ + { /* CE8 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; + +static struct CE_pipe_config target_ce_config_wlan_qca6750[] = { + /* host->target HTC control and raw streams */ + { /* CE0 */ 0, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host HTT */ + { /* CE1 */ 1, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* target->host WMI + HTC control */ + { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target WMI */ + { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target HTT */ + { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, + (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + /* Target -> host PKTLOG */ + { /* CE5 */ 5, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* Reserved for target autonomous HIF_memcpy */ + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE7 used only by Host */ + { /* CE7 */ 7, PIPEDIR_INOUT_H2H, 0, 0, + (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,}, + /* Reserved for target */ + { /* CE8 */ 8, PIPEDIR_INOUT, 32, 16384, CE_ATTR_FLAGS, 0,}, + /* CE 9, 10, 11 belong to CoreBsp & MHI driver */ +}; #endif /* __HIF_PCI_INTERNAL_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_internal.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_internal.h index 1694e70015bb4e068a6f70a88b45b1c2a50846ab..94b148746e26962c854d3960ad7a5eee4e781ed9 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -89,6 +89,12 @@ struct CE_ring_state { unsigned int high_water_mark_nentries; void *srng_ctx; void **per_transfer_context; + + /* HAL CE ring type */ + uint32_t hal_ring_type; + /* ring memory prealloc */ + uint8_t is_ring_prealloc; + OS_DMA_MEM_CONTEXT(ce_dmacontext); /* OS Specific DMA context */ }; @@ -468,6 +474,8 @@ enum hif_ce_event_type { HIF_RX_DESC_PRE_NBUF_ALLOC, HIF_RX_DESC_PRE_NBUF_MAP, HIF_RX_DESC_POST_NBUF_MAP, + + HIF_EVENT_TYPE_MAX, }; void ce_init_ce_desc_event_log(struct hif_softc *scn, int ce_id, int size); @@ -554,6 +562,7 @@ int hif_get_wake_ce_id(struct hif_softc *scn, uint8_t *ce_id); /** * struct hif_ce_desc_event - structure for detailing a ce event + * @index: location of the descriptor in the ce ring; * @type: what the event was * @time: when it happened * @current_hp: holds the current ring hp value @@ -563,7 +572,6 @@ int hif_get_wake_ce_id(struct hif_softc *scn, uint8_t *ce_id); * @dma_addr: physical/iova address based on smmu status * @dma_to_phy: physical address from iova address * @virt_to_phy: physical address from virtual address - * @index: location of the descriptor in the ce ring; * @actual_data_len: length of the data * @data: data pointed by descriptor */ @@ -571,6 +579,7 @@ struct hif_ce_desc_event { int index; enum hif_ce_event_type type; uint64_t time; + int cpu_id; #ifdef HELIUMPLUS union ce_desc descriptor; #else @@ -665,6 +674,7 @@ void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event) * Return: */ void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len); + QDF_STATUS alloc_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id); void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id); #else diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.c index 5991690222310acbec5f078b1efbbdd2775a1d1b..ccf04ce52f13b66ed5e4e331135bd8d76d6ce90a 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -37,9 +37,6 @@ #include "ce_reg.h" #include "ce_assignment.h" #include "ce_tasklet.h" -#ifndef CONFIG_WIN -#include "qwlan_version.h" -#endif #include "qdf_module.h" #define CE_POLL_TIMEOUT 10 /* ms */ @@ -51,12 +48,19 @@ #define PCIE_ACCESS_DUMP 4 #endif #include "mp_dev.h" +#ifdef HIF_CE_LOG_INFO +#include "qdf_hang_event_notifier.h" +#endif #if (defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6290) || \ defined(QCA_WIFI_QCA6018)) && !defined(QCA_WIFI_SUPPORT_SRNG) #define QCA_WIFI_SUPPORT_SRNG #endif +#ifdef QCA_WIFI_SUPPORT_SRNG +#include +#endif + /* Forward references */ QDF_STATUS hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info); @@ -482,6 +486,33 @@ static struct service_to_pipe target_service_to_ce_map_qca6018[] = { }; #endif +#if (defined(QCA_WIFI_QCN9000)) +static struct service_to_pipe target_service_to_ce_map_qcn9000[] = { + { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BK_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BK_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, + { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, + { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 1, }, + { HTC_RAW_STREAMS_SVC, PIPEDIR_OUT, 0}, + { HTC_RAW_STREAMS_SVC, PIPEDIR_IN, 1 }, + { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, + { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, + { PACKET_LOG_SVC, PIPEDIR_IN, 5, }, + /* (Additions here) */ + { 0, 0, 0, }, +}; +#else +static struct service_to_pipe target_service_to_ce_map_qcn9000[] = { +}; +#endif + /* PIPEDIR_OUT = HOST to Target */ /* PIPEDIR_IN = TARGET to HOST */ #ifdef QCN7605_SUPPORT @@ -587,6 +618,51 @@ static struct service_to_pipe target_service_to_ce_map_qca6390[] = { }; #endif +static struct service_to_pipe target_service_to_ce_map_qca6490[] = { + { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BK_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BK_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, + { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, + { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 2, }, + { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, + { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, + { PACKET_LOG_SVC, PIPEDIR_IN, 5, }, + /* (Additions here) */ + { 0, 0, 0, }, +}; + +#if (defined(QCA_WIFI_QCA6750)) +static struct service_to_pipe target_service_to_ce_map_qca6750[] = { + { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BK_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BK_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, + { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, + { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, + { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, + { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, + { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 2, }, + { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, + { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, + { PACKET_LOG_SVC, PIPEDIR_IN, 5, }, + /* (Additions here) */ + { 0, 0, 0, }, +}; +#else +static struct service_to_pipe target_service_to_ce_map_qca6750[] = { +}; +#endif + static struct service_to_pipe target_service_to_ce_map_ar900b[] = { { WMI_DATA_VO_SVC, @@ -778,6 +854,16 @@ static void hif_select_service_to_pipe_map(struct hif_softc *scn, *sz_tgt_svc_map_to_use = sizeof(target_service_to_ce_map_qca6390); break; + case TARGET_TYPE_QCA6490: + *tgt_svc_map_to_use = target_service_to_ce_map_qca6490; + *sz_tgt_svc_map_to_use = + sizeof(target_service_to_ce_map_qca6490); + break; + case TARGET_TYPE_QCA6750: + *tgt_svc_map_to_use = target_service_to_ce_map_qca6750; + *sz_tgt_svc_map_to_use = + sizeof(target_service_to_ce_map_qca6750); + break; case TARGET_TYPE_QCA8074: *tgt_svc_map_to_use = target_service_to_ce_map_qca8074; *sz_tgt_svc_map_to_use = @@ -795,6 +881,12 @@ static void hif_select_service_to_pipe_map(struct hif_softc *scn, *sz_tgt_svc_map_to_use = sizeof(target_service_to_ce_map_qca6018); break; + case TARGET_TYPE_QCN9000: + *tgt_svc_map_to_use = + target_service_to_ce_map_qcn9000; + *sz_tgt_svc_map_to_use = + sizeof(target_service_to_ce_map_qcn9000); + break; } } } @@ -895,11 +987,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, scn->ipa_ce_ring->vaddr; } else { ce_ring->base_addr_owner_space_unaligned = - qdf_mem_alloc_consistent(scn->qdf_dev, - scn->qdf_dev->dev, - (nentries * desc_size + - CE_DESC_RING_ALIGN), - base_addr); + hif_mem_alloc_consistent_unaligned + (scn, + (nentries * desc_size + + CE_DESC_RING_ALIGN), + base_addr, + ce_ring->hal_ring_type, + &ce_ring->is_ring_prealloc); + if (!ce_ring->base_addr_owner_space_unaligned) { HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u", __func__, CE_id); @@ -930,10 +1025,12 @@ static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id, } ce_ring->base_addr_owner_space_unaligned = NULL; } else { - qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, - ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_CE_space, 0); + hif_mem_free_consistent_unaligned + (scn, + ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, + ce_ring->base_addr_owner_space_unaligned, + ce_ring->base_addr_CE_space, 0, + ce_ring->is_ring_prealloc); ce_ring->base_addr_owner_space_unaligned = NULL; } } @@ -944,9 +1041,14 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, unsigned int nentries, uint32_t desc_size) { ce_ring->base_addr_owner_space_unaligned = - qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev, + hif_mem_alloc_consistent_unaligned + (scn, (nentries * desc_size + - CE_DESC_RING_ALIGN), base_addr); + CE_DESC_RING_ALIGN), + base_addr, + ce_ring->hal_ring_type, + &ce_ring->is_ring_prealloc); + if (!ce_ring->base_addr_owner_space_unaligned) { HIF_ERROR("%s: Failed to allocate DMA memory for ce ring id : %u", __func__, CE_id); @@ -958,10 +1060,12 @@ static QDF_STATUS ce_alloc_desc_ring(struct hif_softc *scn, unsigned int CE_id, static void ce_free_desc_ring(struct hif_softc *scn, unsigned int CE_id, struct CE_ring_state *ce_ring, uint32_t desc_size) { - qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, - ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_CE_space, 0); + hif_mem_free_consistent_unaligned + (scn, + ce_ring->nentries * desc_size + CE_DESC_RING_ALIGN, + ce_ring->base_addr_owner_space_unaligned, + ce_ring->base_addr_CE_space, 0, + ce_ring->is_ring_prealloc); ce_ring->base_addr_owner_space_unaligned = NULL; } #endif /* IPA_OFFLOAD */ @@ -1002,7 +1106,10 @@ bool ce_srng_based(struct hif_softc *scn) case TARGET_TYPE_QCA8074V2: case TARGET_TYPE_QCA6290: case TARGET_TYPE_QCA6390: + case TARGET_TYPE_QCA6490: + case TARGET_TYPE_QCA6750: case TARGET_TYPE_QCA6018: + case TARGET_TYPE_QCN9000: return true; default: return false; @@ -1054,7 +1161,26 @@ static inline uint32_t ce_get_desc_size(struct hif_softc *scn, return hif_state->ce_services->ce_get_desc_size(ring_type); } - +#ifdef QCA_WIFI_SUPPORT_SRNG +static inline int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type) +{ + switch (ce_ring_type) { + case CE_RING_SRC: + return CE_SRC; + case CE_RING_DEST: + return CE_DST; + case CE_RING_STATUS: + return CE_DST_STATUS; + default: + return -EINVAL; + } +} +#else +static int32_t ce_ring_type_to_hal_ring_type(uint32_t ce_ring_type) +{ + return 0; +} +#endif static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state, uint8_t ring_type, uint32_t nentries) { @@ -1079,6 +1205,7 @@ static struct CE_ring_state *ce_alloc_ring_state(struct CE_state *CE_state, ce_ring->low_water_mark_nentries = 0; ce_ring->high_water_mark_nentries = nentries; ce_ring->per_transfer_context = (void **)ptr; + ce_ring->hal_ring_type = ce_ring_type_to_hal_ring_type(ring_type); desc_size = ce_get_desc_size(scn, ring_type); @@ -1282,7 +1409,7 @@ void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id) } #endif /* HIF_CE_DEBUG_DATA_BUF */ -#if defined(CONFIG_MCL) +#ifndef HIF_CE_DEBUG_DATA_DYNAMIC_BUF #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) struct hif_ce_desc_event hif_ce_desc_history[CE_COUNT_MAX][HIF_CE_HISTORY_MAX]; @@ -1339,7 +1466,7 @@ alloc_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id, static inline void free_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) { } #endif /* (HIF_CONFIG_SLUB_DEBUG_ON) || (HIF_CE_DEBUG_DATA_BUF) */ -#elif defined(CONFIG_WIN) +#else #if defined(HIF_CE_DEBUG_DATA_BUF) static QDF_STATUS @@ -1388,7 +1515,7 @@ alloc_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id, static inline void free_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) { } #endif /* HIF_CE_DEBUG_DATA_BUF */ -#endif /* CONFIG_MCL */ +#endif /* HIF_CE_DEBUG_DATA_DYNAMIC_BUF */ #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) /** @@ -2328,7 +2455,9 @@ static void hif_post_recv_buffers_failure(struct HIF_CE_pipe_info *pipe_info, * there is no trigger to refill the ce and we will * eventually crash */ - if (bufs_needed_tmp == CE_state->dest_ring->nentries - 1) + if (bufs_needed_tmp == CE_state->dest_ring->nentries - 1 || + (ce_srng_based(scn) && + bufs_needed_tmp == CE_state->dest_ring->nentries - 2)) qdf_sched_work(scn->qdf_dev, &CE_state->oom_allocation_work); } @@ -2969,6 +3098,8 @@ int hif_wlan_enable(struct hif_softc *scn) mode = PLD_FTM; else if (QDF_GLOBAL_COLDBOOT_CALIB_MODE == con_mode) mode = PLD_COLDBOOT_CALIBRATION; + else if (QDF_GLOBAL_FTM_COLDBOOT_CALIB_MODE == con_mode) + mode = PLD_FTM_COLDBOOT_CALIBRATION; else if (QDF_IS_EPPING_ENABLED(con_mode)) mode = PLD_EPPING; else @@ -2977,8 +3108,7 @@ int hif_wlan_enable(struct hif_softc *scn) if (BYPASS_QMI) return 0; else - return pld_wlan_enable(scn->qdf_dev->dev, &cfg, - mode, QWLAN_VERSIONSTR); + return pld_wlan_enable(scn->qdf_dev->dev, &cfg, mode); } #ifdef WLAN_FEATURE_EPPING @@ -3131,6 +3261,14 @@ void hif_ce_prepare_config(struct hif_softc *scn) scn->ce_count = QCA_6290_CE_COUNT; break; + case TARGET_TYPE_QCN9000: + hif_state->host_ce_config = host_ce_config_wlan_qcn9000; + hif_state->target_ce_config = target_ce_config_wlan_qcn9000; + hif_state->target_ce_config_sz = + sizeof(target_ce_config_wlan_qcn9000); + scn->ce_count = QCN_9000_CE_COUNT; + scn->disable_wake_irq = 1; + break; case TARGET_TYPE_QCA6390: hif_state->host_ce_config = host_ce_config_wlan_qca6390; hif_state->target_ce_config = target_ce_config_wlan_qca6390; @@ -3139,6 +3277,22 @@ void hif_ce_prepare_config(struct hif_softc *scn) scn->ce_count = QCA_6390_CE_COUNT; break; + case TARGET_TYPE_QCA6490: + hif_state->host_ce_config = host_ce_config_wlan_qca6490; + hif_state->target_ce_config = target_ce_config_wlan_qca6490; + hif_state->target_ce_config_sz = + sizeof(target_ce_config_wlan_qca6490); + + scn->ce_count = QCA_6490_CE_COUNT; + break; + case TARGET_TYPE_QCA6750: + hif_state->host_ce_config = host_ce_config_wlan_qca6750; + hif_state->target_ce_config = target_ce_config_wlan_qca6750; + hif_state->target_ce_config_sz = + sizeof(target_ce_config_wlan_qca6750); + + scn->ce_count = QCA_6750_CE_COUNT; + break; case TARGET_TYPE_ADRASTEA: if (hif_is_attribute_set(scn, HIF_LOWDESC_CE_NO_PKTLOG_CFG)) { hif_state->host_ce_config = @@ -3235,7 +3389,6 @@ void hif_unconfig_ce(struct hif_softc *hif_sc) */ static void hif_post_static_buf_to_target(struct hif_softc *scn) { - void *target_va; phys_addr_t target_pa; struct ce_info *ce_info_ptr; uint32_t msi_data_start; @@ -3244,15 +3397,19 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn) uint32_t i = 0; int ret; - target_va = qdf_mem_alloc_consistent(scn->qdf_dev, - scn->qdf_dev->dev, - FW_SHARED_MEM + - sizeof(struct ce_info), - &target_pa); - if (!target_va) + scn->vaddr_qmi_bypass = + (uint32_t *)qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + FW_SHARED_MEM, + &target_pa); + if (!scn->vaddr_qmi_bypass) { + hif_err("Memory allocation failed could not post target buf"); return; + } - ce_info_ptr = (struct ce_info *)target_va; + scn->paddr_qmi_bypass = target_pa; + + ce_info_ptr = (struct ce_info *)scn->vaddr_qmi_bypass; if (scn->vaddr_rri_on_ddr) { ce_info_ptr->rri_over_ddr_low_paddr = @@ -3276,7 +3433,26 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn) } hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, target_pa); - hif_info("target va %pK target pa %pa", target_va, &target_pa); + hif_info("target va %pK target pa %pa", scn->vaddr_qmi_bypass, + &target_pa); +} + +/** + * hif_cleanup_static_buf_to_target() - clean up static buffer to WLAN FW + * @scn: pointer to HIF structure + * + * + * Return: void + */ +void hif_cleanup_static_buf_to_target(struct hif_softc *scn) +{ + void *target_va = scn->vaddr_qmi_bypass; + phys_addr_t target_pa = scn->paddr_qmi_bypass; + + qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + FW_SHARED_MEM, target_va, + target_pa, 0); + hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, 0); } #else /** @@ -3289,17 +3465,38 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn) */ static void hif_post_static_buf_to_target(struct hif_softc *scn) { - void *target_va; - phys_addr_t target_pa; - - target_va = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev, - FW_SHARED_MEM, &target_pa); - if (!target_va) { - HIF_TRACE("Memory allocation failed could not post target buf"); + qdf_dma_addr_t target_pa; + + scn->vaddr_qmi_bypass = + (uint32_t *)qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + FW_SHARED_MEM, + &target_pa); + if (!scn->vaddr_qmi_bypass) { + hif_err("Memory allocation failed could not post target buf"); return; } + + scn->paddr_qmi_bypass = target_pa; hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, target_pa); - HIF_TRACE("target va %pK target pa %pa", target_va, &target_pa); +} + +/** + * hif_cleanup_static_buf_to_target() - clean up static buffer to WLAN FW + * @scn: pointer to HIF structure + * + * + * Return: void + */ +void hif_cleanup_static_buf_to_target(struct hif_softc *scn) +{ + void *target_va = scn->vaddr_qmi_bypass; + phys_addr_t target_pa = scn->paddr_qmi_bypass; + + qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + FW_SHARED_MEM, target_va, + target_pa, 0); + hif_write32_mb(snc, scn->mem + BYPASS_QMI_TEMP_REGISTER, 0); } #endif @@ -3307,6 +3504,10 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn) static inline void hif_post_static_buf_to_target(struct hif_softc *scn) { } + +void hif_cleanup_static_buf_to_target(struct hif_softc *scn) +{ +} #endif static int hif_srng_sleep_state_adjust(struct hif_softc *scn, bool sleep_ok, @@ -4043,3 +4244,61 @@ int hif_get_wake_ce_id(struct hif_softc *scn, uint8_t *ce_id) return 0; } + +#ifdef HIF_CE_LOG_INFO +/** + * ce_get_index_info(): Get CE index info + * @scn: HIF Context + * @ce_state: CE opaque handle + * @info: CE info + * + * Return: 0 for success and non zero for failure + */ +static +int ce_get_index_info(struct hif_softc *scn, void *ce_state, + struct ce_index *info) +{ + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + + return hif_state->ce_services->ce_get_index_info(scn, ce_state, info); +} + +void hif_log_ce_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ + struct hang_event_info info = {0}; + static uint32_t tracked_ce = BIT(CE_ID_1) | BIT(CE_ID_2) | + BIT(CE_ID_3) | BIT(CE_ID_4) | BIT(CE_ID_9) | BIT(CE_ID_10); + uint8_t curr_index = 0; + uint8_t i; + uint16_t size; + + info.active_tasklet_count = qdf_atomic_read(&scn->active_tasklet_cnt); + info.active_grp_tasklet_cnt = + qdf_atomic_read(&scn->active_grp_tasklet_cnt); + + for (i = 0; i < scn->ce_count; i++) { + if (!(tracked_ce & BIT(i)) || !scn->ce_id_to_state[i]) + continue; + + if (ce_get_index_info(scn, scn->ce_id_to_state[i], + &info.ce_info[curr_index])) + continue; + + curr_index++; + } + + info.ce_count = curr_index; + size = sizeof(info) - + (CE_COUNT_MAX - info.ce_count) * sizeof(struct ce_index); + + if (*offset + size > QDF_WLAN_HANG_FW_OFFSET) + return; + + QDF_HANG_EVT_SET_HDR(&info.tlv_header, HANG_EVT_TAG_CE_INFO, + size - QDF_HANG_EVENT_TLV_HDR_SIZE); + + qdf_mem_copy(data + *offset, &info, size); + *offset = *offset + size; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.h index e54f04348d523683ff48ff07deada7138964fd72..d2875343644291a148ef480cb6b80d228bcde370 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,6 +49,7 @@ #define CE_USEFUL_SIZE 0x00000058 #define CE_ALL_BITMAP 0xFFFF +#define HIF_REQUESTED_EVENTS 20 /** * enum ce_id_type * @@ -70,16 +71,36 @@ enum ce_id_type { CE_ID_MAX }; +/** + * enum ce_buckets + * + * @ce_buckets: CE tasklet time buckets + * @CE_BUCKET_500_US: tasklet bucket to store 0-0.5ms + * @CE_BUCKET_1_MS: tasklet bucket to store 0.5-1ms + * @CE_BUCKET_2_MS: tasklet bucket to store 1-2ms + * @CE_BUCKET_5_MS: tasklet bucket to store 2-5ms + * @CE_BUCKET_10_MS: tasklet bucket to store 5-10ms + * @CE_BUCKET_BEYOND: tasklet bucket to store > 10ms + * @CE_BUCKET_MAX: enum max value + */ +#ifdef CE_TASKLET_DEBUG_ENABLE +enum ce_buckets { + CE_BUCKET_500_US, + CE_BUCKET_1_MS, + CE_BUCKET_2_MS, + CE_BUCKET_5_MS, + CE_BUCKET_10_MS, + CE_BUCKET_BEYOND, + CE_BUCKET_MAX, +}; +#endif + enum ce_target_type { CE_SVC_LEGACY, CE_SVC_SRNG, CE_MAX_TARGET_TYPE }; -#ifdef CONFIG_WIN -#define QWLAN_VERSIONSTR "WIN" -#endif - enum ol_ath_hif_pkt_ecodes { HIF_PIPE_NO_RESOURCE = 0 }; @@ -138,8 +159,33 @@ static inline bool hif_dummy_grp_done(struct hif_exec_context *grp_entry, int extern struct hif_execution_ops tasklet_sched_ops; extern struct hif_execution_ops napi_sched_ops; +/** + * struct ce_stats + * + * @ce_per_cpu: Stats of the CEs running per CPU + * @record_index: Current index to store in time record + * @tasklet_sched_entry_ts: Timestamp when tasklet is scheduled + * @tasklet_exec_entry_ts: Timestamp when tasklet is started execuiton + * @tasklet_exec_time_record: Last N number of tasklets execution time + * @tasklet_sched_time_record: Last N number of tasklets scheduled time + * @ce_tasklet_exec_bucket: Tasklet execution time buckets + * @ce_tasklet_sched_bucket: Tasklet time in queue buckets + * @ce_tasklet_exec_last_update: Latest timestamp when bucket is updated + * @ce_tasklet_sched_last_update: Latest timestamp when bucket is updated + */ struct ce_stats { uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU]; +#ifdef CE_TASKLET_DEBUG_ENABLE + uint32_t record_index[CE_COUNT_MAX]; + uint64_t tasklet_sched_entry_ts[CE_COUNT_MAX]; + uint64_t tasklet_exec_entry_ts[CE_COUNT_MAX]; + uint64_t tasklet_exec_time_record[CE_COUNT_MAX][HIF_REQUESTED_EVENTS]; + uint64_t tasklet_sched_time_record[CE_COUNT_MAX][HIF_REQUESTED_EVENTS]; + uint64_t ce_tasklet_exec_bucket[CE_COUNT_MAX][CE_BUCKET_MAX]; + uint64_t ce_tasklet_sched_bucket[CE_COUNT_MAX][CE_BUCKET_MAX]; + uint64_t ce_tasklet_exec_last_update[CE_COUNT_MAX][CE_BUCKET_MAX]; + uint64_t ce_tasklet_sched_last_update[CE_COUNT_MAX][CE_BUCKET_MAX]; +#endif }; struct HIF_CE_state { @@ -219,6 +265,49 @@ struct ce_info { #endif #endif +/** + * struct ce_index + * + * @id: CE id + * @sw_index: sw index + * @write_index: write index + * @hp: ring head pointer + * @tp: ring tail pointer + * @status_hp: status ring head pointer + * @status_tp: status ring tail pointer + */ +struct ce_index { + uint8_t id; + union { + struct { + uint16_t sw_index; + uint16_t write_index; + } legacy_info; + struct { + uint16_t hp; + uint16_t tp; + uint16_t status_hp; + uint16_t status_tp; + } srng_info; + } u; +} qdf_packed; + +/** + * struct hang_event_info + * + * @tlv_header: tlv header + * @active_tasklet_count: active tasklet count + * @active_grp_tasklet_cnt: active grp tasklet count + * @ce_info: CE info + */ +struct hang_event_info { + uint16_t tlv_header; + uint8_t active_tasklet_count; + uint8_t active_grp_tasklet_cnt; + uint8_t ce_count; + struct ce_index ce_info[CE_COUNT_MAX]; +} qdf_packed; + void hif_ce_stop(struct hif_softc *scn); int hif_dump_ce_registers(struct hif_softc *scn); void diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service.c index 7731328a0453030071b9fe8a2ca3420e498f5396..4494e23d2fe1408cfeafbfa31d6ecd90326962f0 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service.c @@ -105,6 +105,8 @@ int get_next_record_index(qdf_atomic_t *table_index, int array_size) return record_index; } +qdf_export_symbol(get_next_record_index); + #ifdef HIF_CE_DEBUG_DATA_BUF void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len) { @@ -129,16 +131,22 @@ void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len) } } +qdf_export_symbol(hif_ce_desc_data_record); + void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event) { qdf_mem_zero(event, offsetof(struct hif_ce_desc_event, data)); } + +qdf_export_symbol(hif_clear_ce_desc_debug_data); #else void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event) { qdf_mem_zero(event, sizeof(struct hif_ce_desc_event)); } + +qdf_export_symbol(hif_clear_ce_desc_debug_data); #endif /* HIF_CE_DEBUG_DATA_BUF */ #if defined(HIF_RECORD_PADDR) @@ -202,6 +210,7 @@ void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id, event->type = type; event->time = qdf_get_log_timestamp(); + event->cpu_id = qdf_get_cpu(); if (descriptor) qdf_mem_copy(&event->descriptor, descriptor, @@ -1637,13 +1646,13 @@ ssize_t hif_input_desc_trace_buf_index(struct hif_softc *scn, ce_hist = &scn->hif_ce_desc_hist; if (!size) { - pr_err("%s: Invalid input buffer.\n", __func__); + qdf_nofl_err("%s: Invalid input buffer.", __func__); return -EINVAL; } if (sscanf(buf, "%u %u", (unsigned int *)&ce_hist->hist_id, (unsigned int *)&ce_hist->hist_index) != 2) { - pr_err("%s: Invalid input value.\n", __func__); + qdf_nofl_err("%s: Invalid input value.", __func__); return -EINVAL; } if ((ce_hist->hist_id >= CE_COUNT_MAX) || @@ -1682,13 +1691,14 @@ ssize_t hif_ce_en_desc_hist(struct hif_softc *scn, const char *buf, size_t size) ce_hist = &scn->hif_ce_desc_hist; if (!size) { - pr_err("%s: Invalid input buffer.\n", __func__); + qdf_nofl_err("%s: Invalid input buffer.", __func__); return -EINVAL; } if (sscanf(buf, "%u %u", (unsigned int *)&ce_id, (unsigned int *)&cfg) != 2) { - pr_err("%s: Invalid input: Enter CE Id<1/0>.\n", __func__); + qdf_nofl_err("%s: Invalid input: Enter CE Id<1/0>.", + __func__); return -EINVAL; } if (ce_id >= CE_COUNT_MAX) { diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_legacy.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_legacy.c index 68faf5d4e45b58771fc6a8f2c2fbbc390d0243fe..366069e97a25567979b72ceb27fc4b8361bf71fd 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_legacy.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_legacy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1267,6 +1267,34 @@ static bool ce_check_int_watermark(struct CE_state *CE_state, return false; } +#ifdef HIF_CE_LOG_INFO +/** + * ce_get_index_info_legacy(): Get CE index info + * @scn: HIF Context + * @ce_state: CE opaque handle + * @info: CE info + * + * Return: 0 for success and non zero for failure + */ +static +int ce_get_index_info_legacy(struct hif_softc *scn, void *ce_state, + struct ce_index *info) +{ + struct CE_state *state = (struct CE_state *)ce_state; + + info->id = state->id; + if (state->src_ring) { + info->u.legacy_info.sw_index = state->src_ring->sw_index; + info->u.legacy_info.write_index = state->src_ring->write_index; + } else if (state->dest_ring) { + info->u.legacy_info.sw_index = state->dest_ring->sw_index; + info->u.legacy_info.write_index = state->dest_ring->write_index; + } + + return 0; +} +#endif + struct ce_ops ce_service_legacy = { .ce_get_desc_size = ce_get_desc_size_legacy, .ce_ring_setup = ce_ring_setup_legacy, @@ -1283,6 +1311,10 @@ struct ce_ops ce_service_legacy = { .ce_send_entries_done_nolock = ce_send_entries_done_nolock_legacy, .ce_prepare_shadow_register_v2_cfg = ce_prepare_shadow_register_v2_cfg_legacy, +#ifdef HIF_CE_LOG_INFO + .ce_get_index_info = + ce_get_index_info_legacy, +#endif }; struct ce_ops *ce_services_legacy(void) diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_srng.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_srng.c index 102667ab82a10ae9f0e00ad8ef43b6af92f1ff84..013f7d98c61998185ae775426510b85b669ce868 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_srng.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_service_srng.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -112,6 +112,7 @@ void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, event->type = type; event->time = qdf_get_log_timestamp(); + event->cpu_id = qdf_get_cpu(); if (descriptor) qdf_mem_copy(&event->descriptor, descriptor, @@ -308,7 +309,7 @@ ce_recv_buf_enqueue_srng(struct CE_handle *copyeng, unsigned int sw_index; uint64_t dma_addr = buffer; struct hif_softc *scn = CE_state->scn; - struct ce_srng_dest_desc *dest_desc; + struct ce_srng_dest_desc *dest_desc = NULL; qdf_spin_lock_bh(&CE_state->ce_index_lock); write_index = dest_ring->write_index; @@ -739,8 +740,8 @@ static void ce_srng_msi_ring_params_setup(struct hif_softc *scn, uint32_t ce_id, } static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id, - struct CE_ring_state *src_ring, - struct CE_attr *attr) + struct CE_ring_state *src_ring, + struct CE_attr *attr) { struct hal_srng_params ring_params = {0}; @@ -761,6 +762,7 @@ static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id, ring_params.intr_timer_thres_us = 0; ring_params.intr_batch_cntr_thres_entries = 1; + ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER; } src_ring->srng_ctx = hal_srng_setup(scn->hal_soc, CE_SRC, ce_id, 0, @@ -786,8 +788,9 @@ static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id, * fails to post the last entry due to the race condition. */ static void ce_srng_initialize_dest_timer_interrupt_war( - struct CE_ring_state *dest_ring, - struct hal_srng_params *ring_params) { + struct CE_ring_state *dest_ring, + struct hal_srng_params *ring_params) +{ int num_buffers_when_fully_posted = dest_ring->nentries - 2; ring_params->low_threshold = num_buffers_when_fully_posted - 1; @@ -796,9 +799,10 @@ static void ce_srng_initialize_dest_timer_interrupt_war( ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE; } -static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id, - struct CE_ring_state *dest_ring, - struct CE_attr *attr) +static void ce_srng_dest_ring_setup(struct hif_softc *scn, + uint32_t ce_id, + struct CE_ring_state *dest_ring, + struct CE_attr *attr) { struct hal_srng_params ring_params = {0}; bool status_ring_timer_thresh_work_arround = true; @@ -822,6 +826,7 @@ static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id, ring_params.intr_batch_cntr_thres_entries = 0; ring_params.flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE; } + ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER; } /*Dest ring is also source ring*/ @@ -829,6 +834,34 @@ static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id, &ring_params); } +#ifdef WLAN_CE_INTERRUPT_THRESHOLD_CONFIG +/** + * ce_status_ring_config_int_threshold() - configure ce status ring interrupt + * thresholds + * @scn: hif handle + * @ring_params: ce srng params + * + * Return: None + */ +static inline +void ce_status_ring_config_int_threshold(struct hif_softc *scn, + struct hal_srng_params *ring_params) +{ + ring_params->intr_timer_thres_us = + scn->ini_cfg.ce_status_ring_timer_threshold; + ring_params->intr_batch_cntr_thres_entries = + scn->ini_cfg.ce_status_ring_batch_count_threshold; +} +#else +static inline +void ce_status_ring_config_int_threshold(struct hif_softc *scn, + struct hal_srng_params *ring_params) +{ + ring_params->intr_timer_thres_us = 0x1000; + ring_params->intr_batch_cntr_thres_entries = 0x1; +} +#endif /* WLAN_CE_INTERRUPT_THRESHOLD_CONFIG */ + static void ce_srng_status_ring_setup(struct hif_softc *scn, uint32_t ce_id, struct CE_ring_state *status_ring, struct CE_attr *attr) @@ -844,8 +877,7 @@ static void ce_srng_status_ring_setup(struct hif_softc *scn, uint32_t ce_id, ring_params.num_entries = status_ring->nentries; if (!(CE_ATTR_DISABLE_INTR & attr->flags)) { - ring_params.intr_timer_thres_us = 0x1000; - ring_params.intr_batch_cntr_thres_entries = 0x1; + ce_status_ring_config_int_threshold(scn, &ring_params); } status_ring->srng_ctx = hal_srng_setup(scn->hal_soc, CE_DST_STATUS, @@ -914,15 +946,52 @@ static void ce_prepare_shadow_register_v2_cfg_srng(struct hif_softc *scn, /* return with original configuration*/ return; } - - hal_construct_shadow_config(scn->hal_soc); + hal_construct_srng_shadow_regs(scn->hal_soc); ce_construct_shadow_config_srng(scn); - + hal_set_shadow_regs(scn->hal_soc); + hal_construct_shadow_regs(scn->hal_soc); /* get updated configuration */ hal_get_shadow_config(scn->hal_soc, shadow_config, num_shadow_registers_configured); } +#ifdef HIF_CE_LOG_INFO +/** + * ce_get_index_info_srng(): Get CE index info + * @scn: HIF Context + * @ce_state: CE opaque handle + * @info: CE info + * + * Return: 0 for success and non zero for failure + */ +static +int ce_get_index_info_srng(struct hif_softc *scn, void *ce_state, + struct ce_index *info) +{ + struct CE_state *CE_state = (struct CE_state *)ce_state; + uint32_t tp, hp; + + info->id = CE_state->id; + if (CE_state->src_ring) { + hal_get_sw_hptp(scn->hal_soc, CE_state->src_ring->srng_ctx, + &tp, &hp); + info->u.srng_info.tp = tp; + info->u.srng_info.hp = hp; + } else if (CE_state->dest_ring && CE_state->status_ring) { + hal_get_sw_hptp(scn->hal_soc, CE_state->status_ring->srng_ctx, + &tp, &hp); + info->u.srng_info.status_tp = tp; + info->u.srng_info.status_hp = hp; + hal_get_sw_hptp(scn->hal_soc, CE_state->dest_ring->srng_ctx, + &tp, &hp); + info->u.srng_info.tp = tp; + info->u.srng_info.hp = hp; + } + + return 0; +} +#endif + static struct ce_ops ce_service_srng = { .ce_get_desc_size = ce_get_desc_size_srng, .ce_ring_setup = ce_ring_setup_srng, @@ -939,9 +1008,13 @@ static struct ce_ops ce_service_srng = { .ce_send_entries_done_nolock = ce_send_entries_done_nolock_srng, .ce_prepare_shadow_register_v2_cfg = ce_prepare_shadow_register_v2_cfg_srng, +#ifdef HIF_CE_LOG_INFO + .ce_get_index_info = + ce_get_index_info_srng, +#endif }; -struct ce_ops *ce_services_srng() +struct ce_ops *ce_services_srng(void) { return &ce_service_srng; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.c index 9a5b61599d498a3f0be503b54a36738cff1c3bd4..ced2765a91d058dcbaba123dd86c422e4aeff547 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,7 +35,6 @@ #include "hif_debug.h" #include "hif_napi.h" - /** * struct tasklet_work * @@ -139,6 +138,200 @@ static inline void ce_schedule_tasklet(struct ce_tasklet_entry *tasklet_entry) tasklet_schedule(&tasklet_entry->intr_tq); } +#ifdef CE_TASKLET_DEBUG_ENABLE +/** + * hif_record_tasklet_exec_entry_ts() - Record ce tasklet execution + * entry time + * @scn: hif_softc + * @ce_id: ce_id + * + * Return: None + */ +static inline void +hif_record_tasklet_exec_entry_ts(struct hif_softc *scn, uint8_t ce_id) +{ + struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(scn); + + hif_ce_state->stats.tasklet_exec_entry_ts[ce_id] = + qdf_get_log_timestamp_usecs(); +} + +/** + * hif_record_tasklet_sched_entry_ts() - Record ce tasklet scheduled + * entry time + * @scn: hif_softc + * @ce_id: ce_id + * + * Return: None + */ +static inline void +hif_record_tasklet_sched_entry_ts(struct hif_softc *scn, uint8_t ce_id) +{ + struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(scn); + + hif_ce_state->stats.tasklet_sched_entry_ts[ce_id] = + qdf_get_log_timestamp_usecs(); +} + +/** + * hif_ce_latency_stats() - Display ce latency information + * @hif_ctx: hif_softc struct + * + * Return: None + */ +static void +hif_ce_latency_stats(struct hif_softc *hif_ctx) +{ + uint8_t i, j; + uint32_t index, start_index; + static const char * const buck_str[] = {"0 - 0.5", "0.5 - 1", "1 - 2", + "2 - 5", "5 - 10", " > 10"}; + struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(hif_ctx); + struct ce_stats *stats = &hif_ce_state->stats; + + hif_err("\tCE TASKLET ARRIVAL AND EXECUTION STATS"); + for (i = 0; i < CE_COUNT_MAX; i++) { + hif_nofl_err("\n\t\tCE Ring %d Tasklet Execution Bucket", i); + for (j = 0; j < CE_BUCKET_MAX; j++) { + hif_nofl_err("\t Bucket %sms :%llu\t last update:%llu", + buck_str[j], + stats->ce_tasklet_exec_bucket[i][j], + stats->ce_tasklet_exec_last_update[i][j]); + } + + hif_nofl_err("\n\t\tCE Ring %d Tasklet Scheduled Bucket", i); + for (j = 0; j < CE_BUCKET_MAX; j++) { + hif_nofl_err("\t Bucket %sms :%llu\t last update :%lld", + buck_str[j], + stats->ce_tasklet_sched_bucket[i][j], + stats-> + ce_tasklet_sched_last_update[i][j]); + } + + hif_nofl_err("\n\t\t CE RING %d Last %d time records", + i, HIF_REQUESTED_EVENTS); + index = stats->record_index[i]; + start_index = stats->record_index[i]; + + for (j = 0; j < HIF_REQUESTED_EVENTS; j++) { + hif_nofl_err("\t Execuiton time: %luus Total Scheduled time: %luus", + stats->tasklet_exec_time_record[i][index], + stats-> + tasklet_sched_time_record[i][index]); + index = (index - 1) % HIF_REQUESTED_EVENTS; + if (index == start_index) + break; + } + } +} + +/** + * ce_tasklet_update_bucket() - update ce execution and scehduled time latency + * in corresponding time buckets + * @stats: struct ce_stats + * @ce_id: ce_id_type + * @entry_us: timestamp when tasklet is started to execute + * @exit_us: timestamp when tasklet is completed execution + * + * Return: N/A + */ +static void ce_tasklet_update_bucket(struct HIF_CE_state *hif_ce_state, + uint8_t ce_id) +{ + uint32_t index; + uint64_t exec_time, exec_ms; + uint64_t sched_time, sched_ms; + uint64_t curr_time = qdf_get_log_timestamp_usecs(); + struct ce_stats *stats = &hif_ce_state->stats; + + exec_time = curr_time - (stats->tasklet_exec_entry_ts[ce_id]); + sched_time = (stats->tasklet_exec_entry_ts[ce_id]) - + (stats->tasklet_sched_entry_ts[ce_id]); + + index = stats->record_index[ce_id]; + index = (index + 1) % HIF_REQUESTED_EVENTS; + + stats->tasklet_exec_time_record[ce_id][index] = exec_time; + stats->tasklet_sched_time_record[ce_id][index] = sched_time; + stats->record_index[ce_id] = index; + + exec_ms = qdf_do_div(exec_time, 1000); + sched_ms = qdf_do_div(sched_time, 1000); + + if (exec_ms > 10) { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_BEYOND]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_BEYOND] + = curr_time; + } else if (exec_ms > 5) { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_10_MS]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_10_MS] + = curr_time; + } else if (exec_ms > 2) { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_5_MS]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_5_MS] + = curr_time; + } else if (exec_ms > 1) { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_2_MS]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_2_MS] + = curr_time; + } else if (exec_time > 500) { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_1_MS]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_1_MS] + = curr_time; + } else { + stats->ce_tasklet_exec_bucket[ce_id][CE_BUCKET_500_US]++; + stats->ce_tasklet_exec_last_update[ce_id][CE_BUCKET_500_US] + = curr_time; + } + + if (sched_ms > 10) { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_BEYOND]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_BEYOND] + = curr_time; + } else if (sched_ms > 5) { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_10_MS]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_10_MS] + = curr_time; + } else if (sched_ms > 2) { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_5_MS]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_5_MS] + = curr_time; + } else if (sched_ms > 1) { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_2_MS]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_2_MS] + = curr_time; + } else if (sched_time > 500) { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_1_MS]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_1_MS] + = curr_time; + } else { + stats->ce_tasklet_sched_bucket[ce_id][CE_BUCKET_500_US]++; + stats->ce_tasklet_sched_last_update[ce_id][CE_BUCKET_500_US] + = curr_time; + } +} +#else +static inline void +hif_record_tasklet_exec_entry_ts(struct hif_softc *scn, uint8_t ce_id) +{ +} + +static void ce_tasklet_update_bucket(struct HIF_CE_state *hif_ce_state, + uint8_t ce_id) +{ +} + +static inline void +hif_record_tasklet_sched_entry_ts(struct hif_softc *scn, uint8_t ce_id) +{ +} + +static void +hif_ce_latency_stats(struct hif_softc *hif_ctx) +{ +} +#endif /*CE_TASKLET_DEBUG_ENABLE*/ + /** * ce_tasklet() - ce_tasklet * @data: data @@ -153,8 +346,11 @@ static void ce_tasklet(unsigned long data) struct hif_softc *scn = HIF_GET_SOFTC(hif_ce_state); struct CE_state *CE_state = scn->ce_id_to_state[tasklet_entry->ce_id]; + if (scn->ce_latency_stats) + hif_record_tasklet_exec_entry_ts(scn, tasklet_entry->ce_id); + hif_record_ce_desc_event(scn, tasklet_entry->ce_id, - HIF_CE_TASKLET_ENTRY, NULL, NULL, -1, 0); + HIF_CE_TASKLET_ENTRY, NULL, NULL, -1, 0); if (qdf_atomic_read(&scn->link_suspended)) { HIF_ERROR("%s: ce %d tasklet fired after link suspend.", @@ -183,6 +379,9 @@ static void ce_tasklet(unsigned long data) hif_record_ce_desc_event(scn, tasklet_entry->ce_id, HIF_CE_TASKLET_EXIT, NULL, NULL, -1, 0); + if (scn->ce_latency_stats) + ce_tasklet_update_bucket(hif_ce_state, tasklet_entry->ce_id); + qdf_atomic_dec(&scn->active_tasklet_cnt); } @@ -339,12 +538,13 @@ hif_ce_increment_interrupt_count(struct HIF_CE_state *hif_ce_state, int ce_id) * * Return: none */ -void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) +void hif_display_ce_stats(struct hif_softc *hif_ctx) { #define STR_SIZE 128 uint8_t i, j, pos; char str_buffer[STR_SIZE]; int size, ret; + struct HIF_CE_state *hif_ce_state = HIF_GET_CE_STATE(hif_ctx); qdf_debug("CE interrupt statistics:"); for (i = 0; i < CE_COUNT_MAX; i++) { @@ -352,7 +552,7 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) pos = 0; for (j = 0; j < QDF_MAX_AVAILABLE_CPU; j++) { ret = snprintf(str_buffer + pos, size, "[%d]:%d ", - j, hif_ce_state->stats.ce_per_cpu[i][j]); + j, hif_ce_state->stats.ce_per_cpu[i][j]); if (ret <= 0 || ret >= size) break; size -= ret; @@ -360,6 +560,9 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state) } qdf_debug("CE id[%2d] - %s", i, str_buffer); } + + if (hif_ctx->ce_latency_stats) + hif_ce_latency_stats(hif_ctx); #undef STR_SIZE } @@ -393,6 +596,9 @@ static inline bool hif_tasklet_schedule(struct hif_opaque_softc *hif_ctx, } tasklet_schedule(&tasklet_entry->intr_tq); + if (scn->ce_latency_stats) + hif_record_tasklet_sched_entry_ts(scn, tasklet_entry->ce_id); + return true; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.h index 05da16872781430932bba3edce11020403640b42..d5ab58cefb11be0e7016e0d916ba1e654d183654 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ce/ce_tasklet.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016,2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016,2018,2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,6 +28,6 @@ QDF_STATUS ce_register_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask); QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask); irqreturn_t ce_dispatch_interrupt(int irq, struct ce_tasklet_entry *tasklet_entry); -void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state); +void hif_display_ce_stats(struct hif_softc *hif_ctx); void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state); #endif /* __CE_TASKLET_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ahb_api.h b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ahb_api.h index 103114b87e529c9c02a4b3830348ef3d87dcb620..c7fca4c195607ffd276063a9eccff92acca6ff8c 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ahb_api.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ahb_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018,2020-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,5 +49,8 @@ int hif_ahb_enable_radio(struct hif_pci_softc *sc, int hif_ahb_configure_irq(struct hif_pci_softc *sc); int hif_ahb_configure_grp_irq(struct hif_softc *scn, struct hif_exec_context *hif_ext_grp); +void hif_ahb_deconfigure_grp_irq(struct hif_softc *scn); bool hif_ahb_needs_bmi(struct hif_softc *scn); +void hif_ahb_display_stats(struct hif_softc *scn); +void hif_ahb_clear_stats(struct hif_softc *scn); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.c index de0b195cb9429b2bf0e0fa91fa5ebc6377c8b021..f4d323dcd2c3987ce6709c4b10d694843ca96aea 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.c @@ -262,6 +262,16 @@ int hif_dummy_grp_irq_configure(struct hif_softc *hif_sc, return 0; } +/** + * hif_dummy_grp_irq_deconfigure - dummy call + * hif_sc: hif context + * + * Return: none + */ +void hif_dummy_grp_irq_deconfigure(struct hif_softc *hif_sc) +{ +} + /** * hif_dummy_dump_registers - dummy call * hif_sc: hif context @@ -377,3 +387,17 @@ int hif_dummy_addr_in_boundary(struct hif_softc *scn, uint32_t offset) void hif_dummy_config_irq_affinity(struct hif_softc *scn) { } + +/** + * hif_dummy_log_bus_info - dummy call + * @scn: hif context + * @data: hang event data buffer + * @offset: offset at which data needs to be written + * + * Return: bool + */ +bool hif_dummy_log_bus_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ + return false; +} diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.h b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.h index 99c440a937574a23d88684e60f61cea404db4c73..c048803d152a7736f1cba5aca5ba6105ed57709c 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/dummy.h @@ -44,6 +44,7 @@ void hif_dummy_grp_irq_enable(struct hif_softc *hif_sc, uint32_t grp_id); void hif_dummy_grp_irq_disable(struct hif_softc *hif_sc, uint32_t grp_id); int hif_dummy_grp_irq_configure(struct hif_softc *hif_sc, struct hif_exec_context *exec); +void hif_dummy_grp_irq_deconfigure(struct hif_softc *hif_sc); int hif_dummy_dump_registers(struct hif_softc *hif_sc); void hif_dummy_dump_target_memory(struct hif_softc *hif_sc, void *ramdump_base, uint32_t address, uint32_t size); @@ -60,3 +61,5 @@ int hif_dummy_bus_reset_resume(struct hif_softc *hif_ctx); int hif_dummy_map_ce_to_irq(struct hif_softc *scn, int ce_id); int hif_dummy_addr_in_boundary(struct hif_softc *scn, uint32_t offset); void hif_dummy_config_irq_affinity(struct hif_softc *scn); +bool hif_dummy_log_bus_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset); diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ipci_api.h b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ipci_api.h new file mode 100644 index 0000000000000000000000000000000000000000..17353428912c9f88eda4ac264c654533f2e24881 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/ipci_api.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _IPCI_API_H_ +#define _IPCI_API_H_ +struct hif_exec_context; + +/** + * hif_ipci_open(): hif_bus_open + * @hif_ctx: hif context + * @bus_type: bus type + * + * Return: 0 for success or QDF_STATUS_E_NOMEM + */ +QDF_STATUS hif_ipci_open(struct hif_softc *hif_ctx, + enum qdf_bus_type bus_type); + +/** + * hif_ipci_close(): hif_bus_close + * @hif_ctx: hif context + * + * Return: n/a + */ +void hif_ipci_close(struct hif_softc *hif_ctx); + +/** + * hif_bus_prevent_linkdown(): allow or permit linkdown + * @scn: struct hif_softc + * @flag: true prevents linkdown, false allows + * + * Calls into the platform driver to vote against taking down the + * pcie link. + * + * Return: n/a + */ +void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag); + +/** + * hif_ipci_bus_suspend(): prepare hif for suspend + * @scn: struct hif_softc + * + * Return: Errno + */ +int hif_ipci_bus_suspend(struct hif_softc *scn); + +/** + * hif_ipci_bus_suspend_noirq() - ensure there are no pending transactions + * @scn: hif context + * + * Ensure that if we received the wakeup message before the irq + * was disabled that the message is pocessed before suspending. + * + * Return: -EBUSY if we fail to flush the tasklets. + */ +int hif_ipci_bus_suspend_noirq(struct hif_softc *scn); + +/** + * hif_ipci_bus_resume(): prepare hif for resume + * @scn: struct hif_softc + * + * Return: Errno + */ +int hif_ipci_bus_resume(struct hif_softc *scn); + +/** + * hif_ipci_bus_resume_noirq() - ensure there are no pending transactions + * @scn: hif context + * + * Ensure that if we received the wakeup message before the irq + * was disabled that the message is pocessed before suspending. + * + * Return: -EBUSY if we fail to flush the tasklets. + */ +int hif_ipci_bus_resume_noirq(struct hif_softc *scn); + +/** + * hif_ipci_disable_isr(): disable interrupt + * @scn: struct hif_softc + * + * Return: n/a + */ +void hif_ipci_disable_isr(struct hif_softc *scn); + +/** + * hif_ipci_nointrs(): disable IRQ + * @scn: struct hif_softc + * + * This function stops interrupt(s) + * + * Return: none + */ +void hif_ipci_nointrs(struct hif_softc *scn); + +/** + * hif_ipci_dump_registers(): dump bus debug registers + * @scn: struct hif_opaque_softc + * + * This function dumps hif bus debug registers + * + * Return: 0 for success or error code + */ +int hif_ipci_dump_registers(struct hif_softc *scn); + +/** + * hif_ipci_enable_bus(): enable bus + * + * This function enables the bus + * + * @ol_sc: soft_sc struct + * @dev: device pointer + * @bdev: bus dev pointer + * bid: bus id pointer + * type: enum hif_enable_type such as HIF_ENABLE_TYPE_PROBE + * Return: QDF_STATUS + */ +QDF_STATUS hif_ipci_enable_bus( + struct hif_softc *scn, + struct device *dev, void *bdev, + const struct hif_bus_id *bid, + enum hif_enable_type type); + +/** + * hif_ipci_disable_bus(): hif_disable_bus + * + * This function disables the bus + * + * @scn: struct hif_softc + * + * Return: none + */ +void hif_ipci_disable_bus(struct hif_softc *scn); + +/** + * hif_ipci_bus_configure() - configure the pcie bus + * @hif_sc: pointer to the hif context. + * + * return: 0 for success. nonzero for failure. + */ +int hif_ipci_bus_configure(struct hif_softc *scn); + +/** + * hif_ipci_enable_power_management() - enable power management + * @hif_ctx: hif context + * @is_packet_log_enabled: pktlog enabled or disabled + * + * Return: none + */ +void hif_ipci_enable_power_management( + struct hif_softc *hif_ctx, + bool is_packet_log_enabled); + +/** + * hif_ipci_disable_power_management() - disable power management + * @hif_ctx: hif context + * + * Return: none + */ +void hif_ipci_disable_power_management(struct hif_softc *hif_ctx); + +/** + * hif_ipci_configure_grp_irq() - configure HW block irq + * @scn: hif context + * @exec: hif exec context + * + * Return:Errno + */ +int hif_ipci_configure_grp_irq( + struct hif_softc *scn, + struct hif_exec_context *exec); + +/** + * hif_ipci_deconfigure_grp_irq() - deconfigure HW block irq + * @scn: hif context + * + * Return: None + */ +void hif_ipci_deconfigure_grp_irq(struct hif_softc *scn); + +/** + * hif_ipci_display_stats() - display stats + * @hif_ctx: hif context + * + * Return: none + */ +void hif_ipci_display_stats(struct hif_softc *hif_ctx); + +/** + * hif_ipci_clear_stats() - clear stats + * @hif_ctx: hif context + * + * Return: none + */ +void hif_ipci_clear_stats(struct hif_softc *hif_ctx); + +/** + * hif_ipci_needs_bmi() - return true if the soc needs bmi through the driver + * @scn: hif context + * + * Return: true if soc needs driver bmi otherwise false + */ +bool hif_ipci_needs_bmi(struct hif_softc *scn); + +/** + * hif_ipci_get_irq_name() - get irqname + * This function gives irqnumber to irqname + * mapping. + * + * @irq_no: irq number + * + * Return: irq name + */ +const char *hif_ipci_get_irq_name(int irq_no); + +#endif /* _IPCI_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.c index 8c1dbbb273f9e03ca0d8ef1a9d9b85470c23e78d..aa80361d6a8456f46dae343e79adc2222ee11327 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,7 +23,8 @@ #include "hif_io32.h" #include "multibus.h" #include "dummy.h" -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) #include "ce_main.h" #include "ce_api.h" #include "ce_internal.h" @@ -57,6 +58,7 @@ static void hif_initialize_default_ops(struct hif_softc *hif_sc) bus_ops->hif_bus_late_resume = &hif_dummy_bus_resume; bus_ops->hif_map_ce_to_irq = &hif_dummy_map_ce_to_irq; bus_ops->hif_grp_irq_configure = &hif_dummy_grp_irq_configure; + bus_ops->hif_grp_irq_deconfigure = &hif_dummy_grp_irq_deconfigure; bus_ops->hif_config_irq_affinity = &hif_dummy_config_irq_affinity; } @@ -98,6 +100,8 @@ int hif_bus_get_context_size(enum qdf_bus_type bus_type) switch (bus_type) { case QDF_BUS_TYPE_PCI: return hif_pci_get_context_size(); + case QDF_BUS_TYPE_IPCI: + return hif_ipci_get_context_size(); case QDF_BUS_TYPE_AHB: return hif_ahb_get_context_size(); case QDF_BUS_TYPE_SNOC: @@ -129,6 +133,9 @@ QDF_STATUS hif_bus_open(struct hif_softc *hif_sc, case QDF_BUS_TYPE_PCI: status = hif_initialize_pci_ops(hif_sc); break; + case QDF_BUS_TYPE_IPCI: + status = hif_initialize_ipci_ops(hif_sc); + break; case QDF_BUS_TYPE_SNOC: status = hif_initialize_snoc_ops(&hif_sc->bus_ops); break; @@ -325,6 +332,11 @@ int hif_grp_irq_configure(struct hif_softc *hif_sc, return hif_sc->bus_ops.hif_grp_irq_configure(hif_sc, hif_exec); } +void hif_grp_irq_deconfigure(struct hif_softc *hif_sc) +{ + hif_sc->bus_ops.hif_grp_irq_deconfigure(hif_sc); +} + int hif_dump_registers(struct hif_opaque_softc *hif_hdl) { struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); @@ -526,3 +538,14 @@ void hif_config_irq_affinity(struct hif_softc *hif_sc) { hif_sc->bus_ops.hif_config_irq_affinity(hif_sc); } + +#ifdef HIF_BUS_LOG_INFO +bool hif_log_bus_info(struct hif_softc *hif_sc, uint8_t *data, + unsigned int *offset) +{ + if (hif_sc->bus_ops.hif_log_bus_info) + return hif_sc->bus_ops.hif_log_bus_info(hif_sc, data, offset); + + return false; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.h b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.h index 53a04e46a98bb976baf7d55fa3e4c71c249cbfd5..104a7924bacff51dfa9bc2289810f4ad4d612fc1 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -60,6 +60,7 @@ struct hif_bus_ops { void (*hif_irq_enable)(struct hif_softc *hif_sc, int ce_id); int (*hif_grp_irq_configure)(struct hif_softc *hif_sc, struct hif_exec_context *exec); + void (*hif_grp_irq_deconfigure)(struct hif_softc *hif_sc); int (*hif_dump_registers)(struct hif_softc *hif_sc); void (*hif_dump_target_memory)(struct hif_softc *hif_sc, void *ramdump_base, @@ -81,6 +82,8 @@ struct hif_bus_ops { int (*hif_addr_in_boundary)(struct hif_softc *scn, uint32_t offset); bool (*hif_needs_bmi)(struct hif_softc *hif_sc); void (*hif_config_irq_affinity)(struct hif_softc *hif_sc); + bool (*hif_log_bus_info)(struct hif_softc *scn, uint8_t *data, + unsigned int *offset); }; #ifdef HIF_SNOC @@ -123,6 +126,39 @@ static inline int hif_pci_get_context_size(void) } #endif /* HIF_PCI */ +#ifdef HIF_IPCI +/** + * hif_initialize_ipci_ops() - initialize the pci ops + * @hif_sc: pointer to hif context + * + * Return: QDF_STATUS_SUCCESS + */ +QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc); + +/** + * hif_ipci_get_context_size() - return the size of the ipci context + * + * Return the size of the context. (0 for invalid bus) + */ +int hif_ipci_get_context_size(void); +#else +static inline QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc) +{ + HIF_ERROR("%s: not supported", __func__); + return QDF_STATUS_E_NOSUPPORT; +} + +/** + * hif_ipci_get_context_size() - dummy when ipci isn't supported + * + * Return: 0 as an invalid size to indicate no support + */ +static inline int hif_ipci_get_context_size(void) +{ + return 0; +} +#endif /* HIF_IPCI */ + #ifdef HIF_AHB QDF_STATUS hif_initialize_ahb_ops(struct hif_bus_ops *bus_ops); int hif_ahb_get_context_size(void); @@ -178,6 +214,7 @@ static inline int hif_sdio_get_context_size(void) int hif_grp_irq_configure(struct hif_softc *hif_sc, struct hif_exec_context *hif_exec); +void hif_grp_irq_deconfigure(struct hif_softc *hif_sc); #ifdef HIF_USB QDF_STATUS hif_initialize_usb_ops(struct hif_bus_ops *bus_ops); int hif_usb_get_context_size(void); @@ -208,4 +245,24 @@ static inline int hif_usb_get_context_size(void) * Return: None */ void hif_config_irq_affinity(struct hif_softc *hif_sc); + +#ifdef HIF_BUS_LOG_INFO +/** + * hif_log_bus_info() - API to log bus related info + * @scn: hif handle + * @data: hang event data buffer + * @offset: offset at which data needs to be written + * + * Return: true if bus_id is invalid else false + */ +bool hif_log_bus_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset); +#else +static inline +bool hif_log_bus_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ + return false; +} +#endif #endif /* _MULTIBUS_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ahb.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ahb.c index 7ab211e1296f77c5c10122a1641393de448e147d..e6fc2440024feebb5694949f3606573e91ea8dac 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ahb.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ahb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018,2020-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -67,10 +67,14 @@ QDF_STATUS hif_initialize_ahb_ops(struct hif_bus_ops *bus_ops) bus_ops->hif_disable_power_management = &hif_dummy_disable_power_management; bus_ops->hif_grp_irq_configure = &hif_ahb_configure_grp_irq; + bus_ops->hif_grp_irq_deconfigure = &hif_ahb_deconfigure_grp_irq; bus_ops->hif_addr_in_boundary = &hif_dummy_addr_in_boundary; bus_ops->hif_needs_bmi = &hif_ahb_needs_bmi; + bus_ops->hif_display_stats = &hif_ahb_display_stats; + bus_ops->hif_clear_stats = &hif_ahb_clear_stats; bus_ops->hif_config_irq_affinity = &hif_dummy_config_irq_affinity; + bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ipci.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ipci.c new file mode 100644 index 0000000000000000000000000000000000000000..b67e5e382a41982b32ed83b2a73612e2c130cd72 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_ipci.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "hif.h" +#include "hif_main.h" +#include "multibus.h" +#include "ipci_api.h" +#include "hif_io32.h" +#include "dummy.h" +#include "ce_api.h" + +/** + * hif_initialize_ipci_ops() - initialize the pci ops + * @bus_ops: hif_bus_ops table pointer to initialize + * + * Return: QDF_STATUS_SUCCESS + */ +QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc) +{ + struct hif_bus_ops *bus_ops = &hif_sc->bus_ops; + + bus_ops->hif_bus_open = &hif_ipci_open; + bus_ops->hif_bus_close = &hif_ipci_close; + bus_ops->hif_bus_prevent_linkdown = &hif_ipci_prevent_linkdown; + bus_ops->hif_reset_soc = &hif_dummy_reset_soc; + bus_ops->hif_bus_suspend = &hif_ipci_bus_suspend; + bus_ops->hif_bus_resume = &hif_ipci_bus_resume; + bus_ops->hif_bus_suspend_noirq = &hif_ipci_bus_suspend_noirq; + bus_ops->hif_bus_resume_noirq = &hif_ipci_bus_resume_noirq; + bus_ops->hif_target_sleep_state_adjust = + &hif_dummy_target_sleep_state_adjust; + bus_ops->hif_disable_isr = &hif_ipci_disable_isr; + bus_ops->hif_nointrs = &hif_ipci_nointrs; + bus_ops->hif_enable_bus = &hif_ipci_enable_bus; + bus_ops->hif_disable_bus = &hif_ipci_disable_bus; + bus_ops->hif_bus_configure = &hif_ipci_bus_configure; + bus_ops->hif_get_config_item = &hif_dummy_get_config_item; + bus_ops->hif_set_mailbox_swap = &hif_dummy_set_mailbox_swap; + bus_ops->hif_claim_device = &hif_dummy_claim_device; + bus_ops->hif_shutdown_device = &hif_ce_stop; + bus_ops->hif_stop = &hif_ce_stop; + bus_ops->hif_cancel_deferred_target_sleep = + &hif_dummy_cancel_deferred_target_sleep; + bus_ops->hif_irq_disable = &hif_dummy_irq_disable; + bus_ops->hif_irq_enable = &hif_dummy_irq_enable; + bus_ops->hif_dump_registers = &hif_ipci_dump_registers; + bus_ops->hif_dump_target_memory = &hif_ce_dump_target_memory; + bus_ops->hif_ipa_get_ce_resource = &hif_ce_ipa_get_ce_resource; + bus_ops->hif_mask_interrupt_call = &hif_dummy_mask_interrupt_call; + bus_ops->hif_enable_power_management = + &hif_ipci_enable_power_management; + bus_ops->hif_disable_power_management = + &hif_ipci_disable_power_management; + bus_ops->hif_grp_irq_configure = &hif_ipci_configure_grp_irq; + bus_ops->hif_grp_irq_deconfigure = &hif_ipci_deconfigure_grp_irq; + bus_ops->hif_display_stats = + &hif_ipci_display_stats; + bus_ops->hif_clear_stats = + &hif_ipci_clear_stats; + bus_ops->hif_addr_in_boundary = &hif_dummy_addr_in_boundary; + bus_ops->hif_needs_bmi = &hif_ipci_needs_bmi; + bus_ops->hif_config_irq_affinity = + &hif_dummy_config_irq_affinity; + bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info; + + return QDF_STATUS_SUCCESS; +} + +/** + * hif_ipci_get_context_size() - return the size of the ipci context + * + * Return the size of the context. (0 for invalid bus) + */ +int hif_ipci_get_context_size(void) +{ + return sizeof(struct hif_ipci_softc); +} diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_pci.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_pci.c index f28053dd16b6f26da97f3801db0db2ba9d02b0de..35010a9f534c29cfe61ccc72a2639c7b6db08ee6 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_pci.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_pci.c @@ -75,6 +75,7 @@ QDF_STATUS hif_initialize_pci_ops(struct hif_softc *hif_sc) bus_ops->hif_disable_power_management = &hif_pci_disable_power_management; bus_ops->hif_grp_irq_configure = &hif_pci_configure_grp_irq; + bus_ops->hif_grp_irq_deconfigure = &hif_pci_deconfigure_grp_irq; bus_ops->hif_display_stats = &hif_pci_display_stats; bus_ops->hif_clear_stats = @@ -87,6 +88,8 @@ QDF_STATUS hif_initialize_pci_ops(struct hif_softc *hif_sc) bus_ops->hif_config_irq_affinity = &hif_pci_config_irq_affinity; + bus_ops->hif_log_bus_info = &hif_log_pcie_info; + return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_sdio.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_sdio.c index 3c220be0b42ad8d827a6e0bef192443227e802e4..97a3e194ebc40b89824c11e1a3235bc8a025d3ba 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_sdio.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_sdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,8 +25,8 @@ #include "if_sdio.h" /** - * hif_initialize_sdio_ops() - initialize the pci ops - * @bus_ops: hif_bus_ops table pointer to initialize + * hif_initialize_sdio_ops() - initialize the sdio ops + * @hif_sc: hif soft context * * Return: QDF_STATUS_SUCCESS */ @@ -66,6 +66,7 @@ QDF_STATUS hif_initialize_sdio_ops(struct hif_softc *hif_sc) &hif_dummy_disable_power_management; bus_ops->hif_addr_in_boundary = &hif_dummy_addr_in_boundary; bus_ops->hif_needs_bmi = &hif_sdio_needs_bmi; + bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_snoc.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_snoc.c index 3c0253ca060f38104ffa20142943d7a4a2519ef4..0834315a4005eb295fc049d30d43e316183066a8 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_snoc.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_snoc.c @@ -75,6 +75,7 @@ QDF_STATUS hif_initialize_snoc_ops(struct hif_bus_ops *bus_ops) bus_ops->hif_map_ce_to_irq = &hif_snoc_map_ce_to_irq; bus_ops->hif_addr_in_boundary = &hif_dummy_addr_in_boundary; bus_ops->hif_needs_bmi = &hif_snoc_needs_bmi; + bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_usb.c b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_usb.c index e632a40134868060b6c1ca2a4b59be0dcecc7632..08b08ee15afc3bfae4e433b760adde27edb23eaa 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_usb.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/multibus_usb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018,2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -67,6 +67,7 @@ QDF_STATUS hif_initialize_usb_ops(struct hif_bus_ops *bus_ops) bus_ops->hif_bus_reset_resume = &hif_usb_bus_reset_resume; bus_ops->hif_map_ce_to_irq = &hif_dummy_map_ce_to_irq; bus_ops->hif_needs_bmi = &hif_usb_needs_bmi; + bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/pci_api.h b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/pci_api.h index 0fc67e1af0a054d29a5f5039e77c208052b27223..dddcedec779468dfc6da0f88a27d171b10f9b471 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/pci_api.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/dispatcher/pci_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -48,6 +48,7 @@ void hif_pci_enable_power_management(struct hif_softc *hif_ctx, void hif_pci_disable_power_management(struct hif_softc *hif_ctx); int hif_pci_configure_grp_irq(struct hif_softc *scn, struct hif_exec_context *exec); +void hif_pci_deconfigure_grp_irq(struct hif_softc *scn); void hif_pci_display_stats(struct hif_softc *hif_ctx); void hif_pci_clear_stats(struct hif_softc *hif_ctx); int hif_pci_legacy_map_ce_to_irq(struct hif_softc *scn, int ce_id); diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.c b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.c index 7d3117a1510714490ea37b32bb6eb44ae0f5449d..8f014ff8dd2d41cfc93ea140e3d6c0a1f12e7371 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.c @@ -43,6 +43,89 @@ int hif_get_next_record_index(qdf_atomic_t *table_index, return record_index & (array_size - 1); } +/** + * hif_hist_is_prev_record() - Check if index is the immediate + * previous record wrt curr_index + * @curr_index: curr index in the event history + * @index: index to be checked + * @hist_size: history size + * + * Return: true if index is immediately behind curr_index else false + */ +static inline +bool hif_hist_is_prev_record(int32_t curr_index, int32_t index, + uint32_t hist_size) +{ + return (((index + 1) & (hist_size - 1)) == curr_index) ? + true : false; +} + +/** + * hif_hist_skip_event_record() - Check if current event needs to be + * recorded or not + * @hist_ev: HIF event history + * @event: DP event entry + * + * Return: true if current event needs to be skipped else false + */ +static bool +hif_hist_skip_event_record(struct hif_event_history *hist_ev, + struct hif_event_record *event) +{ + struct hif_event_record *rec; + struct hif_event_record *last_irq_rec; + int32_t index; + + index = qdf_atomic_read(&hist_ev->index); + if (index < 0) + return false; + + index &= (HIF_EVENT_HIST_MAX - 1); + rec = &hist_ev->event[index]; + + switch (event->type) { + case HIF_EVENT_IRQ_TRIGGER: + /* + * The prev record check is to prevent skipping the IRQ event + * record in case where BH got re-scheduled due to force_break + * but there are no entries to be reaped in the rings. + */ + if (rec->type == HIF_EVENT_BH_SCHED && + hif_hist_is_prev_record(index, + hist_ev->misc.last_irq_index, + HIF_EVENT_HIST_MAX)) { + last_irq_rec = + &hist_ev->event[hist_ev->misc.last_irq_index]; + last_irq_rec->timestamp = qdf_get_log_timestamp(); + last_irq_rec->cpu_id = qdf_get_cpu(); + last_irq_rec->hp++; + last_irq_rec->tp = last_irq_rec->timestamp - + hist_ev->misc.last_irq_ts; + return true; + } + break; + case HIF_EVENT_BH_SCHED: + if (rec->type == HIF_EVENT_BH_SCHED) { + rec->timestamp = qdf_get_log_timestamp(); + rec->cpu_id = qdf_get_cpu(); + return true; + } + break; + case HIF_EVENT_SRNG_ACCESS_START: + if (event->hp == event->tp) + return true; + break; + case HIF_EVENT_SRNG_ACCESS_END: + if (rec->type != HIF_EVENT_SRNG_ACCESS_START) + return true; + break; + default: + break; + } + + return false; +} + void hif_hist_record_event(struct hif_opaque_softc *hif_ctx, struct hif_event_record *event, uint8_t intr_grp_id) { @@ -67,11 +150,19 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx, hif_ext_group = hif_state->hif_ext_group[intr_grp_id]; hist_ev = hif_ext_group->evt_hist; + if (hif_hist_skip_event_record(hist_ev, event)) + return; + record_index = hif_get_next_record_index( &hist_ev->index, HIF_EVENT_HIST_MAX); record = &hist_ev->event[record_index]; + if (event->type == HIF_EVENT_IRQ_TRIGGER) { + hist_ev->misc.last_irq_index = record_index; + hist_ev->misc.last_irq_ts = qdf_get_log_timestamp(); + } + record->hal_ring_id = event->hal_ring_id; record->hp = event->hp; record->tp = event->tp; @@ -467,7 +558,8 @@ static void hif_latency_profile_measure(struct hif_exec_context *hif_ext_group) hif_ext_group->sched_latency_stats[7]++; } #else -static void hif_latency_profile_measure(struct hif_exec_context *hif_ext_group) +static inline +void hif_latency_profile_measure(struct hif_exec_context *hif_ext_group) { } #endif @@ -484,11 +576,13 @@ static void hif_latency_profile_start(struct hif_exec_context *hif_ext_group) hif_ext_group->tstamp = qdf_ktime_to_ms(qdf_ktime_get()); } #else -static void hif_latency_profile_start(struct hif_exec_context *hif_ext_group) +static inline +void hif_latency_profile_start(struct hif_exec_context *hif_ext_group) { } #endif +#ifdef FEATURE_NAPI /** * hif_exec_poll() - napi poll * napi: napi struct @@ -585,7 +679,6 @@ struct hif_execution_ops napi_sched_ops = { .kill = &hif_exec_napi_kill, }; -#ifdef FEATURE_NAPI /** * hif_exec_napi_create() - allocate and initialize a napi exec context * @scale: a binary shift factor to map NAPI budget from\to internal @@ -612,7 +705,7 @@ static struct hif_exec_context *hif_exec_napi_create(uint32_t scale) #else static struct hif_exec_context *hif_exec_napi_create(uint32_t scale) { - HIF_WARN("%s: FEATURE_NAPI not defined, making tasklet"); + HIF_WARN("%s: FEATURE_NAPI not defined, making tasklet", __func__); return hif_exec_tasklet_create(); } #endif @@ -738,6 +831,21 @@ uint32_t hif_configure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx) qdf_export_symbol(hif_configure_ext_group_interrupts); +void hif_deconfigure_ext_group_interrupts(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + if (!scn || !scn->ext_grp_irq_configured) { + hif_err("scn(%pk) is NULL or grp irq not configured", scn); + return; + } + + hif_grp_irq_deconfigure(scn); + scn->ext_grp_irq_configured = false; +} + +qdf_export_symbol(hif_deconfigure_ext_group_interrupts); + #ifdef WLAN_SUSPEND_RESUME_TEST /** * hif_check_and_trigger_ut_resume() - check if unit-test command was used to diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.h b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.h index 6a2b7868ed1ac8fb6073243d0488d980e10c587b..42756e81882700a92ef82561a0e65b4b940d6e97 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_exec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -155,6 +155,7 @@ void hif_exec_destroy(struct hif_exec_context *ctx); int hif_grp_irq_configure(struct hif_softc *scn, struct hif_exec_context *hif_exec); +void hif_grp_irq_deconfigure(struct hif_softc *scn); irqreturn_t hif_ext_group_interrupt_handler(int irq, void *context); struct hif_exec_context *hif_exec_get_ctx(struct hif_opaque_softc *hif, @@ -166,18 +167,47 @@ void hif_exec_kill(struct hif_opaque_softc *scn); * hif_pci_irq_set_affinity_hint() - API to set IRQ affinity * @hif_ext_group: hif_ext_group to extract the irq info * - * This function will set the IRQ affinity to the gold cores - * only for defconfig builds + * This function will set the WLAN IRQ affinity to the gold + * cores only for defconfig builds * * Return: none */ void hif_pci_irq_set_affinity_hint( struct hif_exec_context *hif_ext_group); + +/** + * hif_pci_ce_irq_set_affinity_hint() - API to set IRQ affinity + * + * This function will set the CE IRQ affinity to the gold cores + * only for defconfig builds + * + * @hif_softc: hif_softc to extract the CE irq info + * + * Return: none + */ +void hif_pci_ce_irq_set_affinity_hint( + struct hif_softc *scn); + +/** + * hif_pci_ce_irq_remove_affinity_hint() - remove affinity for the irq + * @irq: irq number to remove affinity from + */ +static inline void hif_pci_ce_irq_remove_affinity_hint(int irq) +{ + hif_irq_affinity_remove(irq); +} #else static inline void hif_pci_irq_set_affinity_hint( struct hif_exec_context *hif_ext_group) { } +static inline void hif_pci_ce_irq_set_affinity_hint( + struct hif_softc *scn) +{ +} +static inline void hif_pci_ce_irq_remove_affinity_hint(int irq) +{ +} #endif /* ifdef HIF_CPU_PERF_AFFINE_MASK */ #endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_io32.h b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_io32.h index 63674e26ffe5fd013e89f005bd01210634945a62..4a8f93a992a327e08b8f9fab9b891d5127dd3ea9 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_io32.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_io32.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,15 +23,15 @@ #include "hif.h" #include "hif_main.h" -#if defined(HIF_REG_WINDOW_SUPPORT) && defined(HIF_PCI) +#if defined(HIF_REG_WINDOW_SUPPORT) && (defined(HIF_PCI) || \ + defined(HIF_IPCI)) static inline void hif_write32_mb_reg_window(void *sc, void __iomem *addr, uint32_t value); - -static inline uint32_t hif_read32_mb_reg_window(void *sc, - void __iomem *addr); - +static inline +uint32_t hif_read32_mb_reg_window(void *sc, + void __iomem *addr); #define hif_read32_mb(scn, addr) \ hif_read32_mb_reg_window((void *)scn, \ (void __iomem *)addr) @@ -40,11 +40,9 @@ static inline uint32_t hif_read32_mb_reg_window(void *sc, (void __iomem *)addr, value) #else - #define hif_read32_mb(scn, addr) ioread32((void __iomem *)addr) #define hif_write32_mb(scn, addr, value) \ iowrite32((u32)(value), (void __iomem *)(addr)) - #endif #define Q_TARGET_ACCESS_BEGIN(scn) \ @@ -96,9 +94,14 @@ static inline uint32_t hif_read32_mb_reg_window(void *sc, #endif #ifdef HIF_SNOC #include "hif_io32_snoc.h" -#endif /* HIF_PCI */ +#endif +#ifdef HIF_IPCI +#include "hif_io32_ipci.h" +#endif + +#if defined(HIF_REG_WINDOW_SUPPORT) && (defined(HIF_PCI) || \ + defined(HIF_IPCI)) -#if defined(HIF_REG_WINDOW_SUPPORT) && defined(HIF_PCI) #include "qdf_lock.h" #include "qdf_util.h" diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.c b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.c index 10527e69743e53ab9dad808ea5fdf8a5df0991ab..45bd30103d8cbc7311b18d66fea09f6fda397d22 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,7 +30,8 @@ #include #include "hif_main.h" #include "hif_hw_version.h" -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if (defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI)) #include "ce_tasklet.h" #include "ce_api.h" #endif @@ -44,6 +45,10 @@ #include "hif_napi.h" #include "hif_unit_test_suspend_i.h" #include "qdf_module.h" +#ifdef HIF_CE_LOG_INFO +#include +#include +#endif void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start) { @@ -77,6 +82,17 @@ void *hif_get_targetdef(struct hif_opaque_softc *hif_ctx) return scn->targetdef; } +#ifdef FORCE_WAKE +void hif_srng_init_phase(struct hif_opaque_softc *hif_ctx, + bool init_phase) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + if (ce_srng_based(scn)) + hal_set_init_phase(scn->hal_soc, init_phase); +} +#endif /* FORCE_WAKE */ + /** * hif_vote_link_down(): unvote for link up * @@ -397,6 +413,35 @@ void *hif_get_dev_ba(struct hif_opaque_softc *hif_handle) } qdf_export_symbol(hif_get_dev_ba); +#ifdef WLAN_CE_INTERRUPT_THRESHOLD_CONFIG +/** + * hif_get_cfg_from_psoc() - Retrieve ini cfg from psoc + * @scn: hif context + * @psoc: psoc objmgr handle + * + * Return: None + */ +static inline +void hif_get_cfg_from_psoc(struct hif_softc *scn, + struct wlan_objmgr_psoc *psoc) +{ + if (psoc) { + scn->ini_cfg.ce_status_ring_timer_threshold = + cfg_get(psoc, + CFG_CE_STATUS_RING_TIMER_THRESHOLD); + scn->ini_cfg.ce_status_ring_batch_count_threshold = + cfg_get(psoc, + CFG_CE_STATUS_RING_BATCH_COUNT_THRESHOLD); + } +} +#else +static inline +void hif_get_cfg_from_psoc(struct hif_softc *scn, + struct wlan_objmgr_psoc *psoc) +{ +} +#endif /* WLAN_CE_INTERRUPT_THRESHOLD_CONFIG */ + #ifdef HIF_CPU_PERF_AFFINE_MASK /** * __hif_cpu_hotplug_notify() - CPU hotplug event handler @@ -484,20 +529,98 @@ static void hif_cpuhp_unregister(struct hif_softc *scn) } #endif /* ifdef HIF_CPU_PERF_AFFINE_MASK */ +#if defined(HIF_CE_LOG_INFO) || defined(HIF_BUS_LOG_INFO) /** - * hif_open(): hif_open - * @qdf_ctx: QDF Context - * @mode: Driver Mode - * @bus_type: Bus Type - * @cbk: CDS Callbacks + * hif_recovery_notifier_cb - Recovery notifier callback to log + * hang event data + * @block: notifier block + * @state: state + * @data: notifier data * - * API to open HIF Context + * Return: status + */ +static +int hif_recovery_notifier_cb(struct notifier_block *block, unsigned long state, + void *data) +{ + struct qdf_notifer_data *notif_data = data; + qdf_notif_block *notif_block; + struct hif_softc *hif_handle; + bool bus_id_invalid; + + if (!data || !block) + return -EINVAL; + + notif_block = qdf_container_of(block, qdf_notif_block, notif_block); + + hif_handle = notif_block->priv_data; + if (!hif_handle) + return -EINVAL; + + bus_id_invalid = hif_log_bus_info(hif_handle, notif_data->hang_data, + ¬if_data->offset); + if (bus_id_invalid) + return NOTIFY_STOP_MASK; + + hif_log_ce_info(hif_handle, notif_data->hang_data, + ¬if_data->offset); + + return 0; +} + +/** + * hif_register_recovery_notifier - Register hif recovery notifier + * @hif_handle: hif handle + * + * Return: status + */ +static +QDF_STATUS hif_register_recovery_notifier(struct hif_softc *hif_handle) +{ + qdf_notif_block *hif_notifier; + + if (!hif_handle) + return QDF_STATUS_E_FAILURE; + + hif_notifier = &hif_handle->hif_recovery_notifier; + + hif_notifier->notif_block.notifier_call = hif_recovery_notifier_cb; + hif_notifier->priv_data = hif_handle; + return qdf_hang_event_register_notifier(hif_notifier); +} + +/** + * hif_unregister_recovery_notifier - Un-register hif recovery notifier + * @hif_handle: hif handle * - * Return: HIF Opaque Pointer + * Return: status */ -struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode, +static +QDF_STATUS hif_unregister_recovery_notifier(struct hif_softc *hif_handle) +{ + qdf_notif_block *hif_notifier = &hif_handle->hif_recovery_notifier; + + return qdf_hang_event_unregister_notifier(hif_notifier); +} +#else +static inline +QDF_STATUS hif_register_recovery_notifier(struct hif_softc *hif_handle) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS hif_unregister_recovery_notifier(struct hif_softc *hif_handle) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, + uint32_t mode, enum qdf_bus_type bus_type, - struct hif_driver_state_callbacks *cbk) + struct hif_driver_state_callbacks *cbk, + struct wlan_objmgr_psoc *psoc) { struct hif_softc *scn; QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -521,9 +644,14 @@ struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode, qdf_atomic_init(&scn->active_grp_tasklet_cnt); qdf_atomic_init(&scn->link_suspended); qdf_atomic_init(&scn->tasklet_from_intr); + hif_system_pm_set_state_on(GET_HIF_OPAQUE_HDL(scn)); qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks)); scn->bus_type = bus_type; + + hif_pm_set_link_state(GET_HIF_OPAQUE_HDL(scn), HIF_PM_LINK_STATE_DOWN); + hif_get_cfg_from_psoc(scn, psoc); + hif_set_event_hist_mask(GET_HIF_OPAQUE_HDL(scn)); status = hif_bus_open(scn, bus_type); if (status != QDF_STATUS_SUCCESS) { @@ -582,9 +710,11 @@ void hif_close(struct hif_opaque_softc *hif_ctx) } hif_uninit_rri_on_ddr(scn); + hif_cleanup_static_buf_to_target(scn); hif_cpuhp_unregister(scn); hif_bus_close(scn); + qdf_mem_free(scn); } @@ -656,12 +786,16 @@ QDF_STATUS hif_try_complete_tasks(struct hif_softc *scn) return QDF_STATUS_SUCCESS; } -#if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \ - defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if (defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \ + defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCN9000) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750)) static QDF_STATUS hif_hal_attach(struct hif_softc *scn) { if (ce_srng_based(scn)) { - scn->hal_soc = hal_attach(scn, scn->qdf_dev); + scn->hal_soc = hal_attach( + hif_softc_to_hif_opaque_softc(scn), + scn->qdf_dev); if (!scn->hal_soc) return QDF_STATUS_E_FAILURE; } @@ -722,6 +856,7 @@ QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev, return status; } + hif_pm_set_link_state(GET_HIF_OPAQUE_HDL(scn), HIF_PM_LINK_STATE_UP); status = hif_hal_attach(scn); if (status != QDF_STATUS_SUCCESS) { HIF_ERROR("%s: hal attach failed", __func__); @@ -735,6 +870,7 @@ QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev, } hif_ut_suspend_init(scn); + hif_register_recovery_notifier(scn); /* * Flag to avoid potential unallocated memory access from MSI @@ -764,6 +900,8 @@ void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type) if (!scn) return; + hif_unregister_recovery_notifier(scn); + hif_nointrs(scn); if (scn->hif_init_done == false) hif_shutdown_device(hif_ctx); @@ -772,6 +910,7 @@ void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type) hif_hal_detach(scn); + hif_pm_set_link_state(hif_ctx, HIF_PM_LINK_STATE_DOWN); hif_disable_bus(scn); hif_wlan_disable(scn); @@ -781,11 +920,25 @@ void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type) HIF_DBG("%s: X", __func__); } +#ifdef CE_TASKLET_DEBUG_ENABLE +void hif_enable_ce_latency_stats(struct hif_opaque_softc *hif_ctx, uint8_t val) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + if (!scn) + return; + + scn->ce_latency_stats = val; +} +#endif + void hif_display_stats(struct hif_opaque_softc *hif_ctx) { hif_display_bus_stats(hif_ctx); } +qdf_export_symbol(hif_display_stats); + void hif_clear_stats(struct hif_opaque_softc *hif_ctx) { hif_clear_bus_stats(hif_ctx); @@ -982,9 +1135,17 @@ int hif_get_device_type(uint32_t device_id, HIF_INFO(" *********** QCA6290EMU *************\n"); break; + case QCN9000_DEVICE_ID: + *hif_type = HIF_TYPE_QCN9000; + *target_type = TARGET_TYPE_QCN9000; + HIF_INFO(" *********** QCN9000 *************\n"); + break; + case QCN7605_DEVICE_ID: case QCN7605_COMPOSITE: case QCN7605_STANDALONE: + case QCN7605_STANDALONE_V2: + case QCN7605_COMPOSITE_V2: *hif_type = HIF_TYPE_QCN7605; *target_type = TARGET_TYPE_QCN7605; HIF_INFO(" *********** QCN7605 *************\n"); @@ -997,6 +1158,20 @@ int hif_get_device_type(uint32_t device_id, HIF_INFO(" *********** QCA6390 *************\n"); break; + case QCA6490_DEVICE_ID: + case QCA6490_EMULATION_DEVICE_ID: + *hif_type = HIF_TYPE_QCA6490; + *target_type = TARGET_TYPE_QCA6490; + HIF_INFO(" *********** QCA6490 *************\n"); + break; + + case QCA6750_DEVICE_ID: + case QCA6750_EMULATION_DEVICE_ID: + *hif_type = HIF_TYPE_QCA6750; + *target_type = TARGET_TYPE_QCA6750; + HIF_INFO(" *********** QCA6750 *************\n"); + break; + case QCA8074V2_DEVICE_ID: *hif_type = HIF_TYPE_QCA8074V2; *target_type = TARGET_TYPE_QCA8074V2; @@ -1256,7 +1431,8 @@ bool hif_is_recovery_in_progress(struct hif_softc *scn) return false; } -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) /** * hif_update_pipe_callback() - API to register pipe specific callbacks @@ -1323,6 +1499,64 @@ int hif_get_bandwidth_level(struct hif_opaque_softc *hif_handle) qdf_export_symbol(hif_get_bandwidth_level); +#ifdef DP_MEM_PRE_ALLOC +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc) +{ + void *vaddr = NULL; + struct hif_driver_state_callbacks *cbk = + hif_get_callbacks_handle(scn); + + *is_mem_prealloc = false; + if (cbk && cbk->prealloc_get_consistent_mem_unaligned) { + vaddr = cbk->prealloc_get_consistent_mem_unaligned(size, + paddr, + ring_type); + if (vaddr) { + *is_mem_prealloc = true; + goto end; + } + } + + vaddr = qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + size, + paddr); +end: + dp_info("%s va_unaligned %pK pa_unaligned %pK size %d ring_type %d", + *is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", vaddr, + (void *)*paddr, (int)size, ring_type); + + return vaddr; +} + +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc) +{ + struct hif_driver_state_callbacks *cbk = + hif_get_callbacks_handle(scn); + + if (is_mem_prealloc) { + if (cbk && cbk->prealloc_put_consistent_mem_unaligned) { + cbk->prealloc_put_consistent_mem_unaligned(vaddr); + } else { + dp_warn("dp_prealloc_put_consistent_unligned NULL"); + QDF_BUG(0); + } + } else { + qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + size, vaddr, paddr, memctx); + } +} +#endif + /** * hif_batch_send() - API to access hif specific function * ce_batch_send. @@ -1491,3 +1725,41 @@ void hif_set_ce_service_max_rx_ind_flush(struct hif_opaque_softc *hif, hif_ctx->ce_service_max_rx_ind_flush = ce_service_max_rx_ind_flush; } + +#ifdef SYSTEM_PM_CHECK +void __hif_system_pm_set_state(struct hif_opaque_softc *hif, + enum hif_system_pm_state state) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif); + + qdf_atomic_set(&hif_ctx->sys_pm_state, state); +} + +int32_t hif_system_pm_get_state(struct hif_opaque_softc *hif) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif); + + return qdf_atomic_read(&hif_ctx->sys_pm_state); +} + +int hif_system_pm_state_check(struct hif_opaque_softc *hif) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif); + int32_t sys_pm_state; + + if (!hif_ctx) { + hif_err("hif context is null"); + return -EFAULT; + } + + sys_pm_state = qdf_atomic_read(&hif_ctx->sys_pm_state); + if (sys_pm_state == HIF_SYSTEM_PM_STATE_BUS_SUSPENDING || + sys_pm_state == HIF_SYSTEM_PM_STATE_BUS_SUSPENDED) { + hif_info("Triggering system wakeup"); + qdf_pm_system_wakeup(); + return -EAGAIN; + } + + return 0; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.h b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.h index eab38f9a8e0e7688e94041f08cb359f8ef076f5e..f6d5134d87d83dac08f8c569287bdcafd107bb44 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_main.h @@ -39,13 +39,20 @@ #include "hif.h" #include "multibus.h" #include "hif_unit_test_suspend_i.h" -#include "qdf_cpuhp.h" +#ifdef HIF_CE_LOG_INFO +#include "qdf_notifier.h" +#endif #define HIF_MIN_SLEEP_INACTIVITY_TIME_MS 50 #define HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS 60 #define HIF_MAX_BUDGET 0xFFFF +#define HIF_STATS_INC(_handle, _field, _delta) \ +{ \ + (_handle)->stats._field += _delta; \ +} + /* * This macro implementation is exposed for efficiency only. * The implementation may change and callers should @@ -81,8 +88,17 @@ #define AR6320_FW_3_2 (0x32) #define QCA6290_EMULATION_DEVICE_ID (0xabcd) #define QCA6290_DEVICE_ID (0x1100) +#define QCN9000_DEVICE_ID (0x1104) #define QCA6390_EMULATION_DEVICE_ID (0x0108) #define QCA6390_DEVICE_ID (0x1101) +/* TODO: change IDs for HastingsPrime */ +#define QCA6490_EMULATION_DEVICE_ID (0x010a) +#define QCA6490_DEVICE_ID (0x1103) + +/* TODO: change IDs for Moselle */ +#define QCA6750_EMULATION_DEVICE_ID (0x010c) +#define QCA6750_DEVICE_ID (0x1105) + #define ADRASTEA_DEVICE_ID_P2_E12 (0x7021) #define AR9887_DEVICE_ID (0x0050) #define AR900B_DEVICE_ID (0x0040) @@ -99,8 +115,10 @@ #define QCA6018_DEVICE_ID (0xfffd) /* Todo: replace this with actual number */ /* Genoa */ #define QCN7605_DEVICE_ID (0x1102) /* Genoa PCIe device ID*/ -#define QCN7605_COMPOSITE (0x9900) -#define QCN7605_STANDALONE (0x9901) +#define QCN7605_COMPOSITE (0x9901) +#define QCN7605_STANDALONE (0x9900) +#define QCN7605_STANDALONE_V2 (0x9902) +#define QCN7605_COMPOSITE_V2 (0x9903) #define RUMIM2M_DEVICE_ID_NODE0 0xabc0 #define RUMIM2M_DEVICE_ID_NODE1 0xabc1 @@ -110,6 +128,7 @@ #define RUMIM2M_DEVICE_ID_NODE5 0xaa11 #define HIF_GET_PCI_SOFTC(scn) ((struct hif_pci_softc *)scn) +#define HIF_GET_IPCI_SOFTC(scn) ((struct hif_ipci_softc *)scn) #define HIF_GET_CE_STATE(scn) ((struct HIF_CE_state *)scn) #define HIF_GET_SDIO_SOFTC(scn) ((struct hif_sdio_softc *)scn) #define HIF_GET_USB_SOFTC(scn) ((struct hif_usb_softc *)scn) @@ -138,6 +157,16 @@ struct ce_desc_hist { }; #endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/ +/** + * struct hif_cfg() - store ini config parameters in hif layer + * @ce_status_ring_timer_threshold: ce status ring timer threshold + * @ce_status_ring_batch_count_threshold: ce status ring batch count threshold + */ +struct hif_cfg { + uint16_t ce_status_ring_timer_threshold; + uint8_t ce_status_ring_batch_count_threshold; +}; + struct hif_softc { struct hif_opaque_softc osc; struct hif_config_info hif_config; @@ -150,6 +179,7 @@ struct hif_softc { bool hif_init_done; bool request_irq_done; bool ext_grp_irq_configured; + uint8_t ce_latency_stats; /* Packet statistics */ struct hif_ce_stats pkt_stats; enum hif_target_status target_status; @@ -171,6 +201,10 @@ struct hif_softc { atomic_t link_suspended; uint32_t *vaddr_rri_on_ddr; qdf_dma_addr_t paddr_rri_on_ddr; +#ifdef CONFIG_BYPASS_QMI + uint32_t *vaddr_qmi_bypass; + qdf_dma_addr_t paddr_qmi_bypass; +#endif int linkstate_vote; bool fastpath_mode_on; atomic_t tasklet_from_intr; @@ -192,6 +226,7 @@ struct hif_softc { struct hif_ut_suspend_context ut_suspend_ctx; uint32_t hif_attribute; int wake_irq; + int disable_wake_irq; void (*initial_wakeup_cb)(void *); void *initial_wakeup_priv; #ifdef REMOVE_PKT_LOG @@ -206,17 +241,28 @@ struct hif_softc { #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) struct ce_desc_hist hif_ce_desc_hist; #endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/ - #ifdef IPA_OFFLOAD qdf_shared_mem_t *ipa_ce_ring; #endif + struct hif_cfg ini_cfg; #ifdef HIF_CPU_PERF_AFFINE_MASK /* The CPU hotplug event registration handle */ struct qdf_cpuhp_handler *cpuhp_event_handle; #endif +#ifdef HIF_CE_LOG_INFO + qdf_notif_block hif_recovery_notifier; +#endif +#ifdef FEATURE_RUNTIME_PM + /* Variable to track the link state change in RTPM */ + qdf_atomic_t pm_link_state; +#endif +#ifdef SYSTEM_PM_CHECK + qdf_atomic_t sys_pm_state; +#endif }; -static inline void *hif_get_hal_handle(void *hif_hdl) +static inline +void *hif_get_hal_handle(struct hif_opaque_softc *hif_hdl) { struct hif_softc *sc = (struct hif_softc *)hif_hdl; @@ -331,6 +377,47 @@ void hif_wlan_disable(struct hif_softc *scn); int hif_target_sleep_state_adjust(struct hif_softc *scn, bool sleep_ok, bool wait_for_it); + +#ifdef DP_MEM_PRE_ALLOC +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc); + +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc); +#else +static inline +void *hif_mem_alloc_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type, + uint8_t *is_mem_prealloc) +{ + return qdf_mem_alloc_consistent(scn->qdf_dev, + scn->qdf_dev->dev, + size, + paddr); +} + +static inline +void hif_mem_free_consistent_unaligned(struct hif_softc *scn, + qdf_size_t size, + void *vaddr, + qdf_dma_addr_t paddr, + qdf_dma_context_t memctx, + uint8_t is_mem_prealloc) +{ + return qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev, + size, vaddr, paddr, memctx); +} +#endif + /** * hif_get_rx_ctx_id() - Returns NAPI instance ID based on CE ID * @ctx_id: Rx CE context ID @@ -373,4 +460,5 @@ void hif_uninit_rri_on_ddr(struct hif_softc *scn); static inline void hif_uninit_rri_on_ddr(struct hif_softc *scn) {} #endif +void hif_cleanup_static_buf_to_target(struct hif_softc *scn); #endif /* __HIF_MAIN_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_napi.h b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_napi.h index 0d164f155f7dd5145a5d5d61f8c9b9058e45e4ac..23084c001456d2fb94782051baaaddca34a07e33 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/hif_napi.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/hif_napi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -237,6 +237,10 @@ static inline struct qca_napi_data *hif_napi_get_all( struct hif_opaque_softc *hif) { return NULL; } +static inline struct qca_napi_info *hif_get_napi(int napi_id, + struct qca_napi_data *napid) +{ return NULL; } + static inline int hif_napi_event(struct hif_opaque_softc *hif, enum qca_napi_event event, void *data) diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/hif_io32_ipci.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/hif_io32_ipci.h new file mode 100644 index 0000000000000000000000000000000000000000..d5fcb89c7a7de68690babdcc29e2419c08f80dd9 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/hif_io32_ipci.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef __HIF_IO32_IPCI_H__ +#define __HIF_IO32_IPCI_H__ + +#ifdef HIF_IPCI + +#include "hif_main.h" +#include "regtable.h" +#include "ce_reg.h" +#include "qdf_atomic.h" +#include "if_ipci.h" +/* + * For maximum performance and no power management, set this to 1. + * For power management at the cost of performance, set this to 0. + */ +#ifndef CONFIG_ATH_IPCIE_MAX_PERF +#define CONFIG_ATH_IPCIE_MAX_PERF 0 +#endif + +/* + * PCIE_ACCESS_LOG_NUM specifies the number of + * read/write records to store + */ +#ifdef CONFIG_ATH_IPCIE_ACCESS_DEBUG +#define IPCIE_ACCESS_LOG_NUM 500 +#endif + +/* 64-bit MSI support */ +#define CONFIG_IPCIE_64BIT_MSI 0 + +/* AXI gating when L1, L2 to reduce power consumption */ +#define CONFIG_IPCIE_ENABLE_AXI_CLK_GATE 0 + +irqreturn_t hif_fw_interrupt_handler(int irq, void *arg); +#endif /* HIF_IPCI */ +#endif /* __HIF_IO32_IPCI_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.c b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.c new file mode 100644 index 0000000000000000000000000000000000000000..4f52c7fab3b36fe288eefb738495c592fe708e24 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.c @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#ifdef CONFIG_PCI_MSM +#include +#endif +#include "hif_io32.h" +#include "if_ipci.h" +#include "hif.h" +#include "target_type.h" +#include "hif_main.h" +#include "ce_main.h" +#include "ce_api.h" +#include "ce_internal.h" +#include "ce_reg.h" +#include "ce_bmi.h" +#include "regtable.h" +#include "hif_hw_version.h" +#include +#include +#include "qdf_status.h" +#include "qdf_atomic.h" +#include "pld_common.h" +#include "mp_dev.h" +#include "hif_debug.h" + +#include "ce_tasklet.h" +#include "targaddrs.h" +#include "hif_exec.h" + +#include "ipci_api.h" + +void hif_ipci_enable_power_management(struct hif_softc *hif_sc, + bool is_packet_log_enabled) +{ +} + +void hif_ipci_disable_power_management(struct hif_softc *hif_ctx) +{ +} + +void hif_ipci_display_stats(struct hif_softc *hif_ctx) +{ + hif_display_ce_stats(hif_ctx); +} + +void hif_ipci_clear_stats(struct hif_softc *hif_ctx) +{ + struct hif_ipci_softc *ipci_ctx = HIF_GET_IPCI_SOFTC(hif_ctx); + + if (!ipci_ctx) { + HIF_ERROR("%s, hif_ctx null", __func__); + return; + } + hif_clear_ce_stats(&ipci_ctx->ce_sc); +} + +QDF_STATUS hif_ipci_open(struct hif_softc *hif_ctx, enum qdf_bus_type bus_type) +{ + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(hif_ctx); + + hif_ctx->bus_type = bus_type; + + qdf_spinlock_create(&sc->irq_lock); + + return hif_ce_open(hif_ctx); +} + +int hif_ipci_bus_configure(struct hif_softc *hif_sc) +{ + int status = 0; + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_sc); + + hif_ce_prepare_config(hif_sc); + + /* initialize sleep state adjust variables */ + hif_state->sleep_timer_init = true; + hif_state->keep_awake_count = 0; + hif_state->fake_sleep = false; + hif_state->sleep_ticks = 0; + + status = hif_wlan_enable(hif_sc); + if (status) { + HIF_ERROR("%s: hif_wlan_enable error = %d", + __func__, status); + goto timer_free; + } + + A_TARGET_ACCESS_LIKELY(hif_sc); + + status = hif_config_ce(hif_sc); + if (status) + goto disable_wlan; + + status = hif_configure_irq(hif_sc); + if (status < 0) + goto unconfig_ce; + + A_TARGET_ACCESS_UNLIKELY(hif_sc); + + return status; + +unconfig_ce: + hif_unconfig_ce(hif_sc); +disable_wlan: + A_TARGET_ACCESS_UNLIKELY(hif_sc); + hif_wlan_disable(hif_sc); + +timer_free: + qdf_timer_stop(&hif_state->sleep_timer); + qdf_timer_free(&hif_state->sleep_timer); + hif_state->sleep_timer_init = false; + + HIF_ERROR("%s: failed, status = %d", __func__, status); + return status; +} + +void hif_ipci_close(struct hif_softc *hif_sc) +{ + hif_ce_close(hif_sc); +} + +/** + * hif_ce_srng_msi_free_irq(): free CE msi IRQ + * @scn: struct hif_softc + * + * Return: ErrorNo + */ +static int hif_ce_srng_msi_free_irq(struct hif_softc *scn) +{ + int ret; + int ce_id, irq; + uint32_t msi_data_start; + uint32_t msi_data_count; + uint32_t msi_irq_start; + struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); + + ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE", + &msi_data_count, &msi_data_start, + &msi_irq_start); + if (ret) + return ret; + + /* needs to match the ce_id -> irq data mapping + * used in the srng parameter configuration + */ + for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { + unsigned int msi_data; + + if (!ce_sc->tasklets[ce_id].inited) + continue; + + msi_data = (ce_id % msi_data_count) + msi_irq_start; + irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); + + hif_debug("%s: (ce_id %d, msi_data %d, irq %d)", __func__, + ce_id, msi_data, irq); + + free_irq(irq, &ce_sc->tasklets[ce_id]); + } + + return ret; +} + +/** + * hif_ipci_deconfigure_grp_irq(): deconfigure HW block IRQ + * @scn: struct hif_softc + * + * Return: none + */ +void hif_ipci_deconfigure_grp_irq(struct hif_softc *scn) +{ + int i, j, irq; + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + struct hif_exec_context *hif_ext_group; + + for (i = 0; i < hif_state->hif_num_extgroup; i++) { + hif_ext_group = hif_state->hif_ext_group[i]; + if (hif_ext_group->irq_requested) { + hif_ext_group->irq_requested = false; + for (j = 0; j < hif_ext_group->numirq; j++) { + irq = hif_ext_group->os_irq[j]; + free_irq(irq, hif_ext_group); + } + hif_ext_group->numirq = 0; + } + } +} + +void hif_ipci_nointrs(struct hif_softc *scn) +{ + int ret; + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + + ce_unregister_irq(hif_state, CE_ALL_BITMAP); + + if (scn->request_irq_done == false) + return; + + hif_ipci_deconfigure_grp_irq(scn); + + ret = hif_ce_srng_msi_free_irq(scn); + if (ret != -EINVAL) { + /* ce irqs freed in hif_ce_srng_msi_free_irq */ + + if (scn->wake_irq) + free_irq(scn->wake_irq, scn); + scn->wake_irq = 0; + } + + scn->request_irq_done = false; +} + +void hif_ipci_disable_bus(struct hif_softc *scn) +{ + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(scn); + void __iomem *mem; + + /* Attach did not succeed, all resources have been + * freed in error handler + */ + if (!sc) + return; + + mem = (void __iomem *)sc->mem; + if (mem) { + hif_dump_pipe_debug_count(scn); + if (scn->athdiag_procfs_inited) { + athdiag_procfs_remove(); + scn->athdiag_procfs_inited = false; + } + scn->mem = NULL; + } + HIF_INFO("%s: X", __func__); +} + +#if defined(CONFIG_PCI_MSM) +void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) +{ + int errno; + + HIF_INFO("wlan: %s pcie power collapse", flag ? "disable" : "enable"); + + errno = pld_wlan_pm_control(scn->qdf_dev->dev, flag); + if (errno) + HIF_ERROR("%s: Failed pld_wlan_pm_control; errno %d", + __func__, errno); +} +#else +void hif_ipci_prevent_linkdown(struct hif_softc *scn, bool flag) +{ + HIF_INFO("wlan: %s pcie power collapse", (flag ? "disable" : "enable")); +} +#endif + +int hif_ipci_bus_suspend(struct hif_softc *scn) +{ + QDF_STATUS ret; + + hif_apps_irqs_disable(GET_HIF_OPAQUE_HDL(scn)); + + ret = hif_try_complete_tasks(scn); + if (QDF_IS_STATUS_ERROR(ret)) { + hif_apps_irqs_enable(GET_HIF_OPAQUE_HDL(scn)); + return -EBUSY; + } + + return 0; +} + +int hif_ipci_bus_resume(struct hif_softc *scn) +{ + hif_apps_irqs_enable(GET_HIF_OPAQUE_HDL(scn)); + + return 0; +} + +int hif_ipci_bus_suspend_noirq(struct hif_softc *scn) +{ + if (hif_can_suspend_link(GET_HIF_OPAQUE_HDL(scn))) + qdf_atomic_set(&scn->link_suspended, 1); + + hif_apps_wake_irq_enable(GET_HIF_OPAQUE_HDL(scn)); + + return 0; +} + +int hif_ipci_bus_resume_noirq(struct hif_softc *scn) +{ + hif_apps_wake_irq_disable(GET_HIF_OPAQUE_HDL(scn)); + + if (hif_can_suspend_link(GET_HIF_OPAQUE_HDL(scn))) + qdf_atomic_set(&scn->link_suspended, 0); + + return 0; +} + +void hif_ipci_disable_isr(struct hif_softc *scn) +{ + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(scn); + + hif_exec_kill(&scn->osc); + hif_nointrs(scn); + /* Cancel the pending tasklet */ + ce_tasklet_kill(scn); + tasklet_kill(&sc->intr_tq); + qdf_atomic_set(&scn->active_tasklet_cnt, 0); + qdf_atomic_set(&scn->active_grp_tasklet_cnt, 0); +} + +int hif_ipci_dump_registers(struct hif_softc *hif_ctx) +{ + int status; + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + status = hif_dump_ce_registers(scn); + + if (status) + HIF_ERROR("%s: Dump CE Registers Failed", __func__); + + return 0; +} + +/** + * hif_ce_interrupt_handler() - interrupt handler for copy engine + * @irq: irq number + * @context: tasklet context + * + * Return: irqreturn_t + */ +static irqreturn_t hif_ce_interrupt_handler(int irq, void *context) +{ + struct ce_tasklet_entry *tasklet_entry = context; + + return ce_dispatch_interrupt(tasklet_entry->ce_id, tasklet_entry); +} + +extern const char *ce_name[]; + +/** + * hif_ce_msi_map_ce_to_irq() - map CE to IRQ + * @scn: hif context + * @ce_id: CE Id + * + * Return: IRQ number + */ +static int hif_ce_msi_map_ce_to_irq(struct hif_softc *scn, int ce_id) +{ + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + + return ipci_scn->ce_msi_irq_num[ce_id]; +} + +/* hif_ce_srng_msi_irq_disable() - disable the irq for msi + * @hif_sc: hif context + * @ce_id: which ce to disable copy complete interrupts for + * + * @Return: none + */ +static void hif_ce_srng_msi_irq_disable(struct hif_softc *hif_sc, int ce_id) +{ + disable_irq_nosync(hif_ce_msi_map_ce_to_irq(hif_sc, ce_id)); +} + +/* hif_ce_srng_msi_irq_enable() - enable the irq for msi + * @hif_sc: hif context + * @ce_id: which ce to enable copy complete interrupts for + * + * @Return: none + */ +static void hif_ce_srng_msi_irq_enable(struct hif_softc *hif_sc, int ce_id) +{ + enable_irq(hif_ce_msi_map_ce_to_irq(hif_sc, ce_id)); +} + +/* hif_ce_msi_configure_irq() - configure the irq + * @scn: hif context + * + * @Return: none + */ +static int hif_ce_msi_configure_irq(struct hif_softc *scn) +{ + int ret; + int ce_id, irq; + uint32_t msi_data_start; + uint32_t msi_data_count; + uint32_t msi_irq_start; + struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); + struct hif_ipci_softc *ipci_sc = HIF_GET_IPCI_SOFTC(scn); + + /* do wake irq assignment */ + ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "WAKE", + &msi_data_count, &msi_data_start, + &msi_irq_start); + if (ret) + return ret; + + scn->wake_irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_irq_start); + ret = request_irq(scn->wake_irq, hif_wake_interrupt_handler, + IRQF_NO_SUSPEND, "wlan_wake_irq", scn); + if (ret) + return ret; + + /* do ce irq assignments */ + ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE", + &msi_data_count, &msi_data_start, + &msi_irq_start); + if (ret) + goto free_wake_irq; + + scn->bus_ops.hif_irq_disable = &hif_ce_srng_msi_irq_disable; + scn->bus_ops.hif_irq_enable = &hif_ce_srng_msi_irq_enable; + scn->bus_ops.hif_map_ce_to_irq = &hif_ce_msi_map_ce_to_irq; + + /* needs to match the ce_id -> irq data mapping + * used in the srng parameter configuration + */ + for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { + unsigned int msi_data = (ce_id % msi_data_count) + + msi_irq_start; + irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); + HIF_DBG("%s: (ce_id %d, msi_data %d, irq %d tasklet %pK)", + __func__, ce_id, msi_data, irq, + &ce_sc->tasklets[ce_id]); + + /* implies the ce is also initialized */ + if (!ce_sc->tasklets[ce_id].inited) + continue; + + ipci_sc->ce_msi_irq_num[ce_id] = irq; + ret = request_irq(irq, hif_ce_interrupt_handler, + IRQF_SHARED, + ce_name[ce_id], + &ce_sc->tasklets[ce_id]); + if (ret) + goto free_irq; + } + + return ret; + +free_irq: + /* the request_irq for the last ce_id failed so skip it. */ + while (ce_id > 0 && ce_id < scn->ce_count) { + unsigned int msi_data; + + ce_id--; + msi_data = (ce_id % msi_data_count) + msi_irq_start; + irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); + free_irq(irq, &ce_sc->tasklets[ce_id]); + } + +free_wake_irq: + free_irq(scn->wake_irq, scn->qdf_dev->dev); + scn->wake_irq = 0; + + return ret; +} + +/** + * hif_exec_grp_irq_disable() - disable the irq for group + * @hif_ext_group: hif exec context + * + * Return: none + */ +static void hif_exec_grp_irq_disable(struct hif_exec_context *hif_ext_group) +{ + int i; + + for (i = 0; i < hif_ext_group->numirq; i++) + disable_irq_nosync(hif_ext_group->os_irq[i]); +} + +/** + * hif_exec_grp_irq_enable() - enable the irq for group + * @hif_ext_group: hif exec context + * + * Return: none + */ +static void hif_exec_grp_irq_enable(struct hif_exec_context *hif_ext_group) +{ + int i; + + for (i = 0; i < hif_ext_group->numirq; i++) + enable_irq(hif_ext_group->os_irq[i]); +} + +const char *hif_ipci_get_irq_name(int irq_no) +{ + return "pci-dummy"; +} + +int hif_ipci_configure_grp_irq(struct hif_softc *scn, + struct hif_exec_context *hif_ext_group) +{ + int ret = 0; + int irq = 0; + int j; + + hif_ext_group->irq_enable = &hif_exec_grp_irq_enable; + hif_ext_group->irq_disable = &hif_exec_grp_irq_disable; + hif_ext_group->irq_name = &hif_ipci_get_irq_name; + hif_ext_group->work_complete = &hif_dummy_grp_done; + + for (j = 0; j < hif_ext_group->numirq; j++) { + irq = hif_ext_group->irq[j]; + + hif_info("request_irq = %d for grp %d", + irq, hif_ext_group->grp_id); + ret = request_irq(irq, + hif_ext_group_interrupt_handler, + IRQF_SHARED | IRQF_NO_SUSPEND, + "wlan_EXT_GRP", + hif_ext_group); + if (ret) { + HIF_ERROR("%s: request_irq failed ret = %d", + __func__, ret); + return -EFAULT; + } + hif_ext_group->os_irq[j] = irq; + } + hif_ext_group->irq_requested = true; + return 0; +} + +int hif_configure_irq(struct hif_softc *scn) +{ + int ret = 0; + + HIF_TRACE("%s: E", __func__); + + if (hif_is_polled_mode_enabled(GET_HIF_OPAQUE_HDL(scn))) { + scn->request_irq_done = false; + return 0; + } + + ret = hif_ce_msi_configure_irq(scn); + if (ret == 0) + goto end; + + if (ret < 0) { + HIF_ERROR("%s: hif_ipci_configure_irq error = %d", + __func__, ret); + return ret; + } +end: + scn->request_irq_done = true; + return 0; +} + +/** + * hif_ipci_get_soc_info_pld() - get soc info for ipcie bus from pld target + * @sc: ipci context + * @dev: device structure + * + * Return: none + */ +static void hif_ipci_get_soc_info_pld(struct hif_ipci_softc *sc, + struct device *dev) +{ + struct pld_soc_info info; + + pld_get_soc_info(dev, &info); + sc->mem = info.v_addr; + sc->ce_sc.ol_sc.mem = info.v_addr; + sc->ce_sc.ol_sc.mem_pa = info.p_addr; +} + +/** + * hif_ipci_get_soc_info_nopld() - get soc info for ipcie bus for non pld target + * @sc: ipci context + * @dev: device structure + * + * Return: none + */ +static void hif_ipci_get_soc_info_nopld(struct hif_ipci_softc *sc, + struct device *dev) +{} + +/** + * hif_is_pld_based_target() - verify if the target is pld based + * @sc: ipci context + * @device_id: device id + * + * Return: none + */ +static bool hif_is_pld_based_target(struct hif_ipci_softc *sc, + int device_id) +{ + if (!pld_have_platform_driver_support(sc->dev)) + return false; + + switch (device_id) { +#ifdef QCA_WIFI_QCA6750 + case QCA6750_DEVICE_ID: +#endif + return true; + } + return false; +} + +/** + * hif_ipci_init_deinit_ops_attach() - attach ops for ipci + * @sc: ipci context + * @device_id: device id + * + * Return: none + */ +static void hif_ipci_init_deinit_ops_attach(struct hif_ipci_softc *sc, + int device_id) +{ + if (hif_is_pld_based_target(sc, device_id)) + sc->hif_ipci_get_soc_info = hif_ipci_get_soc_info_pld; + else + sc->hif_ipci_get_soc_info = hif_ipci_get_soc_info_nopld; +} + +QDF_STATUS hif_ipci_enable_bus(struct hif_softc *ol_sc, + struct device *dev, void *bdev, + const struct hif_bus_id *bid, + enum hif_enable_type type) +{ + int ret = 0; + uint32_t hif_type, target_type; + struct hif_ipci_softc *sc = HIF_GET_IPCI_SOFTC(ol_sc); + struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(ol_sc); + uint16_t revision_id = 0; + struct pci_dev *pdev = bdev; + struct hif_target_info *tgt_info; + int device_id = QCA6750_DEVICE_ID; + + if (!ol_sc) { + HIF_ERROR("%s: hif_ctx is NULL", __func__); + return QDF_STATUS_E_NOMEM; + } + + sc->dev = dev; + tgt_info = hif_get_target_info_handle(hif_hdl); + hif_ipci_init_deinit_ops_attach(sc, device_id); + sc->hif_ipci_get_soc_info(sc, dev); + HIF_TRACE("%s: hif_enable_pci done", __func__); + + device_disable_async_suspend(&pdev->dev); + + ret = hif_get_device_type(device_id, revision_id, + &hif_type, &target_type); + if (ret < 0) { + HIF_ERROR("%s: invalid device id/revision_id", __func__); + return QDF_STATUS_E_ABORTED; + } + HIF_TRACE("%s: hif_type = 0x%x, target_type = 0x%x", + __func__, hif_type, target_type); + + hif_register_tbl_attach(ol_sc, hif_type); + hif_target_register_tbl_attach(ol_sc, target_type); + sc->use_register_windowing = false; + tgt_info->target_type = target_type; + + if (!ol_sc->mem_pa) { + HIF_ERROR("%s: ERROR - BAR0 uninitialized", __func__); + ret = -EIO; + return QDF_STATUS_E_ABORTED; + } + + return 0; +} + +bool hif_ipci_needs_bmi(struct hif_softc *scn) +{ + return !ce_srng_based(scn); +} + +#ifdef FORCE_WAKE +int hif_force_wake_request(struct hif_opaque_softc *hif_handle) +{ + uint32_t timeout = 0, value; + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + + if (pld_force_wake_request(scn->qdf_dev->dev)) { + hif_err("force wake request send failed"); + return -EINVAL; + } + + HIF_STATS_INC(ipci_scn, mhi_force_wake_request_vote, 1); + while (!pld_is_device_awake(scn->qdf_dev->dev) && + timeout <= FORCE_WAKE_DELAY_TIMEOUT_MS) { + qdf_mdelay(FORCE_WAKE_DELAY_MS); + timeout += FORCE_WAKE_DELAY_MS; + } + + if (pld_is_device_awake(scn->qdf_dev->dev) <= 0) { + hif_err("Unable to wake up mhi"); + HIF_STATS_INC(ipci_scn, mhi_force_wake_failure, 1); + return -EINVAL; + } + HIF_STATS_INC(ipci_scn, mhi_force_wake_success, 1); + hif_write32_mb(scn, + scn->mem + + PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG, + 0); + hif_write32_mb(scn, + scn->mem + + PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG, + 1); + + HIF_STATS_INC(ipci_scn, soc_force_wake_register_write_success, 1); + /* + * do not reset the timeout + * total_wake_time = MHI_WAKE_TIME + PCI_WAKE_TIME < 50 ms + */ + do { + value = + hif_read32_mb(scn, + scn->mem + + PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG); + if (value) + break; + qdf_mdelay(FORCE_WAKE_DELAY_MS); + timeout += FORCE_WAKE_DELAY_MS; + } while (timeout <= FORCE_WAKE_DELAY_TIMEOUT_MS); + + if (!value) { + hif_err("failed handshake mechanism"); + HIF_STATS_INC(ipci_scn, soc_force_wake_failure, 1); + return -ETIMEDOUT; + } + + HIF_STATS_INC(ipci_scn, soc_force_wake_success, 1); + + return 0; +} + +int hif_force_wake_release(struct hif_opaque_softc *hif_handle) +{ + int ret; + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + + ret = pld_force_wake_release(scn->qdf_dev->dev); + if (ret) { + hif_err("force wake release failure"); + HIF_STATS_INC(ipci_scn, mhi_force_wake_release_failure, 1); + return ret; + } + + HIF_STATS_INC(ipci_scn, mhi_force_wake_release_success, 1); + hif_write32_mb(scn, + scn->mem + + PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG, + 0); + HIF_STATS_INC(ipci_scn, soc_force_wake_release_success, 1); + return 0; +} + +void hif_print_ipci_stats(struct hif_ipci_softc *ipci_handle) +{ + hif_debug("mhi_force_wake_request_vote: %d", + ipci_handle->stats.mhi_force_wake_request_vote); + hif_debug("mhi_force_wake_failure: %d", + ipci_handle->stats.mhi_force_wake_failure); + hif_debug("mhi_force_wake_success: %d", + ipci_handle->stats.mhi_force_wake_success); + hif_debug("soc_force_wake_register_write_success: %d", + ipci_handle->stats.soc_force_wake_register_write_success); + hif_debug("soc_force_wake_failure: %d", + ipci_handle->stats.soc_force_wake_failure); + hif_debug("soc_force_wake_success: %d", + ipci_handle->stats.soc_force_wake_success); + hif_debug("mhi_force_wake_release_failure: %d", + ipci_handle->stats.mhi_force_wake_release_failure); + hif_debug("mhi_force_wake_release_success: %d", + ipci_handle->stats.mhi_force_wake_release_success); + hif_debug("oc_force_wake_release_success: %d", + ipci_handle->stats.soc_force_wake_release_success); +} +#endif /* FORCE_WAKE */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.h b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.h new file mode 100644 index 0000000000000000000000000000000000000000..b7464b5beb78af63a89ffb7dfd84bd4d2caa7d09 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/ipcie/if_ipci.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef __ATH_IPCI_H__ +#define __ATH_IPCI_H__ + +#include +#include +#include + +#define ATH_DBG_DEFAULT 0 +#define DRAM_SIZE 0x000a8000 +#include "hif.h" +#include "cepci.h" +#include "ce_main.h" + +#ifdef FORCE_WAKE +/** + * struct hif_pci_stats - Account for hif pci based statistics + * @mhi_force_wake_request_vote: vote for mhi + * @mhi_force_wake_failure: mhi force wake failure + * @mhi_force_wake_success: mhi force wake success + * @soc_force_wake_register_write_success: write to soc wake + * @soc_force_wake_failure: soc force wake failure + * @soc_force_wake_success: soc force wake success + * @mhi_force_wake_release_success: mhi force wake release success + * @soc_force_wake_release_success: soc force wake release + */ +struct hif_ipci_stats { + uint32_t mhi_force_wake_request_vote; + uint32_t mhi_force_wake_failure; + uint32_t mhi_force_wake_success; + uint32_t soc_force_wake_register_write_success; + uint32_t soc_force_wake_failure; + uint32_t soc_force_wake_success; + uint32_t mhi_force_wake_release_failure; + uint32_t mhi_force_wake_release_success; + uint32_t soc_force_wake_release_success; +}; + +/* Register to wake the UMAC from power collapse */ +#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40) +/* Register used for handshake mechanism to validate UMAC is awake */ +#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004) +/* Timeout duration to validate UMAC wake status */ +#ifdef HAL_CONFIG_SLUB_DEBUG_ON +#define FORCE_WAKE_DELAY_TIMEOUT_MS 500 +#else +#define FORCE_WAKE_DELAY_TIMEOUT_MS 50 +#endif /* HAL_CONFIG_SLUB_DEBUG_ON */ +/* Validate UMAC status every 5ms */ +#define FORCE_WAKE_DELAY_MS 5 +#endif /* FORCE_WAKE */ + +struct hif_ipci_softc { + struct HIF_CE_state ce_sc; + void __iomem *mem; /* PCI address. */ + + struct device *dev; /* For efficiency, should be first in struct */ + struct tasklet_struct intr_tq; /* tasklet */ + int ce_msi_irq_num[CE_COUNT_MAX]; + bool use_register_windowing; + uint32_t register_window; + qdf_spinlock_t register_access_lock; + qdf_spinlock_t irq_lock; + + void (*hif_ipci_get_soc_info)(struct hif_ipci_softc *sc, + struct device *dev); +#ifdef FORCE_WAKE + struct hif_ipci_stats stats; +#endif +}; + +int hif_configure_irq(struct hif_softc *sc); + +/* + * There may be some pending tx frames during platform suspend. + * Suspend operation should be delayed until those tx frames are + * transferred from the host to target. This macro specifies how + * long suspend thread has to sleep before checking pending tx + * frame count. + */ +#define OL_ATH_TX_DRAIN_WAIT_DELAY 50 /* ms */ + +#ifdef FORCE_WAKE +/** + * hif_print_ipci_stats() - Display HIF IPCI stats + * @ipci_scn - HIF ipci handle + * + * Return: None + */ +void hif_print_ipci_stats(struct hif_ipci_softc *ipci_scn); +#else +static inline +void hif_print_ipci_stats(struct hif_ipci_softc *ipci_scn) +{ +} +#endif /* FORCE_WAKE */ + +#endif /* __IATH_PCI_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.c b/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.c index b32293ec6c5a7c8074e5d4c2a8ca80461f6d8c99..76d167684e6821799193ee1772d9afa03d5daa0a 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.c @@ -50,6 +50,7 @@ #include "pci_api.h" #include "ahb_api.h" +#include "qdf_hang_event_notifier.h" #include "qdf_platform.h" /* Maximum ms timeout for host to wake up target */ @@ -881,7 +882,7 @@ void wlan_tasklet(unsigned long data) goto end; if (!ADRASTEA_BU) { - (irqreturn_t) hif_fw_interrupt_handler(sc->irq_event, scn); + hif_fw_interrupt_handler(sc->irq_event, scn); if (scn->target_status == TARGET_STATUS_RESET) goto end; } @@ -993,7 +994,7 @@ static void hif_pci_runtime_pm_warn(struct hif_pci_softc *sc, const char *msg) return; } - QDF_DEBUG_PANIC("hif_pci_runtime_pm_warn"); + QDF_ASSERT(0); } /** @@ -1479,7 +1480,9 @@ void hif_pci_display_stats(struct hif_softc *hif_ctx) HIF_ERROR("%s, hif_ctx null", __func__); return; } - hif_display_ce_stats(&pci_ctx->ce_sc); + hif_display_ce_stats(hif_ctx); + + hif_print_pci_stats(pci_ctx); } void hif_pci_clear_stats(struct hif_softc *hif_ctx) @@ -1577,10 +1580,11 @@ static void hif_sleep_entry(void *arg) return; qdf_spin_lock_irqsave(&hif_state->keep_awake_lock); - if (hif_state->verified_awake == false) { + if (hif_state->fake_sleep) { idle_ms = qdf_system_ticks_to_msecs(qdf_system_ticks() - hif_state->sleep_ticks); - if (idle_ms >= HIF_MIN_SLEEP_INACTIVITY_TIME_MS) { + if (!hif_state->verified_awake && + idle_ms >= HIF_MIN_SLEEP_INACTIVITY_TIME_MS) { if (!qdf_atomic_read(&scn->link_suspended)) { soc_wake_reset(scn); hif_state->fake_sleep = false; @@ -1588,12 +1592,8 @@ static void hif_sleep_entry(void *arg) } else { qdf_timer_stop(&hif_state->sleep_timer); qdf_timer_start(&hif_state->sleep_timer, - HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); - } - } else { - qdf_timer_stop(&hif_state->sleep_timer); - qdf_timer_start(&hif_state->sleep_timer, HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); + } } qdf_spin_unlock_irqrestore(&hif_state->keep_awake_lock); } @@ -2098,7 +2098,6 @@ int hif_pci_bus_configure(struct hif_softc *hif_sc) if (status) goto disable_wlan; - /* QCA_WIFI_QCA8074_VP:Should not be executed on 8074 VP platform */ if (hif_needs_bmi(hif_osc)) { status = hif_set_hia(hif_sc); if (status) @@ -2429,6 +2428,7 @@ static int hif_ce_srng_msi_free_irq(struct hif_softc *scn) uint32_t msi_data_count; uint32_t msi_irq_start; struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); + struct CE_attr *host_ce_conf = ce_sc->host_ce_config; ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE", &msi_data_count, &msi_data_start, @@ -2442,12 +2442,17 @@ static int hif_ce_srng_msi_free_irq(struct hif_softc *scn) for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { unsigned int msi_data; + if (host_ce_conf[ce_id].flags & CE_ATTR_DISABLE_INTR) + continue; + if (!ce_sc->tasklets[ce_id].inited) continue; msi_data = (ce_id % msi_data_count) + msi_irq_start; irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); + hif_pci_ce_irq_remove_affinity_hint(irq); + hif_debug("%s: (ce_id %d, msi_data %d, irq %d)", __func__, ce_id, msi_data, irq); @@ -2457,7 +2462,7 @@ static int hif_ce_srng_msi_free_irq(struct hif_softc *scn) return ret; } -static void hif_pci_deconfigure_grp_irq(struct hif_softc *scn) +void hif_pci_deconfigure_grp_irq(struct hif_softc *scn) { int i, j, irq; struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); @@ -2477,6 +2482,41 @@ static void hif_pci_deconfigure_grp_irq(struct hif_softc *scn) } } +#ifdef HIF_BUS_LOG_INFO +bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn); + struct hang_event_bus_info info = {0}; + size_t size; + + if (!sc) { + hif_err("HIF Bus Context is Invalid"); + return false; + } + + pfrm_read_config_word(sc->pdev, PCI_DEVICE_ID, &info.dev_id); + + size = sizeof(info); + QDF_HANG_EVT_SET_HDR(&info.tlv_header, HANG_EVT_TAG_BUS_INFO, + size - QDF_HANG_EVENT_TLV_HDR_SIZE); + + if (*offset + size > QDF_WLAN_HANG_FW_OFFSET) + return false; + + qdf_mem_copy(data + *offset, &info, size); + *offset = *offset + size; + + if (info.dev_id == sc->devid) + return false; + + qdf_recovery_reason_update(QCA_HANG_BUS_FAILURE); + qdf_get_bus_reg_dump(scn->qdf_dev->dev, data, + (QDF_WLAN_HANG_FW_OFFSET - size)); + return true; +} +#endif + /** * hif_nointrs(): disable IRQ * @@ -2656,6 +2696,7 @@ int hif_pci_bus_suspend(struct hif_softc *scn) return 0; } +#ifdef PCI_LINK_STATUS_SANITY /** * __hif_check_link_status() - API to check if PCIe link is active/not * @scn: HIF Context @@ -2694,6 +2735,13 @@ static int __hif_check_link_status(struct hif_softc *scn) pld_is_pci_link_down(sc->dev); return -EACCES; } +#else +static inline int __hif_check_link_status(struct hif_softc *scn) +{ + return 0; +} +#endif + /** * hif_pci_bus_resume(): prepare hif for resume @@ -2728,6 +2776,7 @@ int hif_pci_bus_suspend_noirq(struct hif_softc *scn) qdf_atomic_set(&scn->link_suspended, 1); hif_apps_wake_irq_enable(GET_HIF_OPAQUE_HDL(scn)); + return 0; } @@ -3013,9 +3062,14 @@ void hif_fastpath_resume(struct hif_opaque_softc *hif_ctx) */ int hif_runtime_resume(struct hif_opaque_softc *hif_ctx) { + int errno; + QDF_BUG(!hif_bus_resume_noirq(hif_ctx)); - QDF_BUG(!hif_bus_resume(hif_ctx)); - return 0; + errno = hif_bus_resume(hif_ctx); + if (errno) + HIF_ERROR("%s: failed runtime resume: %d", __func__, errno); + + return errno; } #endif /* #ifdef FEATURE_RUNTIME_PM */ @@ -3421,6 +3475,9 @@ static void hif_ce_srng_msi_irq_disable(struct hif_softc *hif_sc, int ce_id) static void hif_ce_srng_msi_irq_enable(struct hif_softc *hif_sc, int ce_id) { + if (__hif_check_link_status(hif_sc)) + return; + pfrm_enable_irq(hif_sc->qdf_dev->dev, hif_ce_msi_map_ce_to_irq(hif_sc, ce_id)); } @@ -3444,20 +3501,27 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) uint32_t msi_irq_start; struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn); + struct CE_attr *host_ce_conf = ce_sc->host_ce_config; + + if (!scn->disable_wake_irq) { + /* do wake irq assignment */ + ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "WAKE", + &msi_data_count, + &msi_data_start, + &msi_irq_start); + if (ret) + return ret; - /* do wake irq assignment */ - ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "WAKE", - &msi_data_count, &msi_data_start, - &msi_irq_start); - if (ret) - return ret; + scn->wake_irq = pld_get_msi_irq(scn->qdf_dev->dev, + msi_irq_start); - scn->wake_irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_irq_start); - ret = pfrm_request_irq(scn->qdf_dev->dev, scn->wake_irq, - hif_wake_interrupt_handler, - IRQF_NO_SUSPEND, "wlan_wake_irq", scn); - if (ret) - return ret; + ret = pfrm_request_irq(scn->qdf_dev->dev, scn->wake_irq, + hif_wake_interrupt_handler, + IRQF_NO_SUSPEND, "wlan_wake_irq", scn); + + if (ret) + return ret; + } /* do ce irq assignments */ ret = pld_get_user_msi_assignment(scn->qdf_dev->dev, "CE", @@ -3482,6 +3546,8 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { unsigned int msi_data = (ce_id % msi_data_count) + msi_irq_start; + if (host_ce_conf[ce_id].flags & CE_ATTR_DISABLE_INTR) + continue; irq = pld_get_msi_irq(scn->qdf_dev->dev, msi_data); HIF_DBG("%s: (ce_id %d, msi_data %d, irq %d tasklet %pK)", __func__, ce_id, msi_data, irq, @@ -3516,9 +3582,11 @@ static int hif_ce_msi_configure_irq(struct hif_softc *scn) } free_wake_irq: - pfrm_free_irq(scn->qdf_dev->dev, - scn->wake_irq, scn->qdf_dev->dev); - scn->wake_irq = 0; + if (!scn->disable_wake_irq) { + pfrm_free_irq(scn->qdf_dev->dev, + scn->wake_irq, scn->qdf_dev->dev); + scn->wake_irq = 0; + } return ret; } @@ -3561,8 +3629,8 @@ const char *hif_pci_get_irq_name(int irq_no) * hif_pci_irq_set_affinity_hint() - API to set IRQ affinity * @hif_ext_group: hif_ext_group to extract the irq info * - * This function will set the IRQ affinity to the gold cores - * only for defconfig builds + * This function will set the WLAN DP IRQ affinity to the gold + * cores only for defconfig builds * * @hif_ext_group: hif_ext_group to extract the irq info * @@ -3615,6 +3683,61 @@ void hif_pci_irq_set_affinity_hint( } } } + +void hif_pci_ce_irq_set_affinity_hint( + struct hif_softc *scn) +{ + int ret; + unsigned int cpus; + struct HIF_CE_state *ce_sc = HIF_GET_CE_STATE(scn); + struct hif_pci_softc *pci_sc = HIF_GET_PCI_SOFTC(scn); + struct CE_attr *host_ce_conf; + int ce_id; + qdf_cpu_mask ce_cpu_mask; + + host_ce_conf = ce_sc->host_ce_config; + qdf_cpumask_clear(&ce_cpu_mask); + + qdf_for_each_online_cpu(cpus) { + if (qdf_topology_physical_package_id(cpus) == + CPU_CLUSTER_TYPE_PERF) { + qdf_cpumask_set_cpu(cpus, + &ce_cpu_mask); + } else { + hif_err_rl("Unable to set cpu mask for offline CPU %d" + , cpus); + } + } + if (qdf_cpumask_empty(&ce_cpu_mask)) { + hif_err_rl("Empty cpu_mask, unable to set CE IRQ affinity"); + return; + } + for (ce_id = 0; ce_id < scn->ce_count; ce_id++) { + if (host_ce_conf[ce_id].flags & CE_ATTR_DISABLE_INTR) + continue; + qdf_cpumask_clear(&pci_sc->ce_irq_cpu_mask[ce_id]); + qdf_cpumask_copy(&pci_sc->ce_irq_cpu_mask[ce_id], + &ce_cpu_mask); + qdf_dev_modify_irq_status(pci_sc->ce_msi_irq_num[ce_id], + IRQ_NO_BALANCING, 0); + ret = + qdf_dev_set_irq_affinity(pci_sc->ce_msi_irq_num[ce_id], + (struct qdf_cpu_mask *) + &pci_sc->ce_irq_cpu_mask[ce_id]); + qdf_dev_modify_irq_status(pci_sc->ce_msi_irq_num[ce_id], + 0, IRQ_NO_BALANCING); + if (ret) + hif_err_rl("Set affinity %*pbl fails for CE IRQ %d", + qdf_cpumask_pr_args( + &pci_sc->ce_irq_cpu_mask[ce_id]), + pci_sc->ce_msi_irq_num[ce_id]); + else + hif_debug_rl("Set affinity %*pbl for CE IRQ: %d", + qdf_cpumask_pr_args( + &pci_sc->ce_irq_cpu_mask[ce_id]), + pci_sc->ce_msi_irq_num[ce_id]); + } +} #endif /* #ifdef HIF_CPU_PERF_AFFINE_MASK */ void hif_pci_config_irq_affinity(struct hif_softc *scn) @@ -3624,10 +3747,13 @@ void hif_pci_config_irq_affinity(struct hif_softc *scn) struct hif_exec_context *hif_ext_group; hif_core_ctl_set_boost(true); + /* Set IRQ affinity for WLAN DP interrupts*/ for (i = 0; i < hif_state->hif_num_extgroup; i++) { hif_ext_group = hif_state->hif_ext_group[i]; hif_pci_irq_set_affinity_hint(hif_ext_group); } + /* Set IRQ affinity for CE interrupts*/ + hif_pci_ce_irq_set_affinity_hint(scn); } int hif_pci_configure_grp_irq(struct hif_softc *scn, @@ -3642,8 +3768,7 @@ int hif_pci_configure_grp_irq(struct hif_softc *scn, hif_ext_group->irq_name = &hif_pci_get_irq_name; hif_ext_group->work_complete = &hif_dummy_grp_done; - for (j = 0; j < hif_ext_group->numirq; j++) - { + for (j = 0; j < hif_ext_group->numirq; j++) { irq = hif_ext_group->irq[j]; hif_debug("request_irq = %d for grp %d", @@ -3827,14 +3952,18 @@ static void hif_pci_get_soc_info_nopld(struct hif_pci_softc *sc, struct device *dev) {} -static bool hif_is_pld_based_target(int device_id) +static bool hif_is_pld_based_target(struct hif_pci_softc *sc, + int device_id) { + if (!pld_have_platform_driver_support(sc->dev)) + return false; + switch (device_id) { case QCA6290_DEVICE_ID: + case QCN9000_DEVICE_ID: case QCA6290_EMULATION_DEVICE_ID: -#ifdef QCA_WIFI_QCA6390 case QCA6390_DEVICE_ID: -#endif + case QCA6490_DEVICE_ID: case AR6320_DEVICE_ID: case QCN7605_DEVICE_ID: return true; @@ -3845,7 +3974,7 @@ static bool hif_is_pld_based_target(int device_id) static void hif_pci_init_deinit_ops_attach(struct hif_pci_softc *sc, int device_id) { - if (hif_is_pld_based_target(device_id)) { + if (hif_is_pld_based_target(sc, device_id)) { sc->hif_enable_pci = hif_enable_pci_pld; sc->hif_pci_deinit = hif_pci_deinit_pld; sc->hif_pci_get_soc_info = hif_pci_get_soc_info_pld; @@ -3896,7 +4025,8 @@ QDF_STATUS hif_pci_enable_bus(struct hif_softc *ol_sc, enum hif_enable_type type) { int ret = 0; - uint32_t hif_type, target_type; + uint32_t hif_type; + uint32_t target_type = TARGET_TYPE_UNKNOWN; struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(ol_sc); struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(ol_sc); uint16_t revision_id = 0; @@ -4869,6 +4999,19 @@ qdf_time_t hif_pm_runtime_get_dp_rx_busy_mark(struct hif_opaque_softc *hif_ctx) return sc->dp_last_busy_timestamp; } +void hif_pm_set_link_state(struct hif_opaque_softc *hif_handle, uint8_t val) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_handle); + + qdf_atomic_set(&scn->pm_link_state, val); +} + +uint8_t hif_pm_get_link_state(struct hif_opaque_softc *hif_handle) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_handle); + + return qdf_atomic_read(&scn->pm_link_state); +} #endif /* FEATURE_RUNTIME_PM */ int hif_pci_legacy_map_ce_to_irq(struct hif_softc *scn, int ce_id) @@ -4888,6 +5031,7 @@ int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset) if (tgt_info->target_type == TARGET_TYPE_QCA6290 || tgt_info->target_type == TARGET_TYPE_QCA6390 || + tgt_info->target_type == TARGET_TYPE_QCA6490 || tgt_info->target_type == TARGET_TYPE_QCA8074) { /* * Need to consider offset's memtype for QCA6290/QCA8074, @@ -4920,6 +5064,171 @@ bool hif_pci_needs_bmi(struct hif_softc *scn) return !ce_srng_based(scn); } +#ifdef FORCE_WAKE +#ifdef DEVICE_FORCE_WAKE_ENABLE +int hif_force_wake_request(struct hif_opaque_softc *hif_handle) +{ + uint32_t timeout, value; + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_pci_softc *pci_scn = HIF_GET_PCI_SOFTC(scn); + + HIF_STATS_INC(pci_scn, mhi_force_wake_request_vote, 1); + + if (qdf_in_interrupt()) + timeout = FORCE_WAKE_DELAY_TIMEOUT_MS * 1000; + else + timeout = 0; + + if (pld_force_wake_request_sync(scn->qdf_dev->dev, timeout)) { + hif_err("force wake request send failed"); + HIF_STATS_INC(pci_scn, mhi_force_wake_failure, 1); + return -EINVAL; + } + + /* If device's M1 state-change event races here, it can be ignored, + * as the device is expected to immediately move from M2 to M0 + * without entering low power state. + */ + if (!pld_is_device_awake(scn->qdf_dev->dev)) + HIF_INFO("%s: state-change event races, ignore", __func__); + + HIF_STATS_INC(pci_scn, mhi_force_wake_success, 1); + hif_write32_mb(scn, + scn->mem + + PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG, + 0); + hif_write32_mb(scn, + scn->mem + + PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG, + 1); + + HIF_STATS_INC(pci_scn, soc_force_wake_register_write_success, 1); + /* + * do not reset the timeout + * total_wake_time = MHI_WAKE_TIME + PCI_WAKE_TIME < 50 ms + */ + timeout = 0; + do { + value = + hif_read32_mb(scn, + scn->mem + + PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG); + if (value) + break; + qdf_mdelay(FORCE_WAKE_DELAY_MS); + timeout += FORCE_WAKE_DELAY_MS; + } while (timeout <= FORCE_WAKE_DELAY_TIMEOUT_MS); + + if (!value) { + hif_err("failed handshake mechanism"); + HIF_STATS_INC(pci_scn, soc_force_wake_failure, 1); + return -ETIMEDOUT; + } + + HIF_STATS_INC(pci_scn, soc_force_wake_success, 1); + return 0; +} + +int hif_force_wake_release(struct hif_opaque_softc *hif_handle) +{ + int ret; + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_pci_softc *pci_scn = HIF_GET_PCI_SOFTC(scn); + + ret = pld_force_wake_release(scn->qdf_dev->dev); + if (ret) { + hif_err("force wake release failure"); + HIF_STATS_INC(pci_scn, mhi_force_wake_release_failure, 1); + return ret; + } + + HIF_STATS_INC(pci_scn, mhi_force_wake_release_success, 1); + hif_write32_mb(scn, + scn->mem + + PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG, + 0); + HIF_STATS_INC(pci_scn, soc_force_wake_release_success, 1); + return 0; +} + +#else /* DEVICE_FORCE_WAKE_ENABLE */ +/** hif_force_wake_request() - Disable the PCIE scratch register + * write/read + * + * Return: 0 + */ +int hif_force_wake_request(struct hif_opaque_softc *hif_handle) +{ + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_pci_softc *pci_scn = HIF_GET_PCI_SOFTC(scn); + uint32_t timeout; + + HIF_STATS_INC(pci_scn, mhi_force_wake_request_vote, 1); + + if (qdf_in_interrupt()) + timeout = FORCE_WAKE_DELAY_TIMEOUT_MS * 1000; + else + timeout = 0; + + if (pld_force_wake_request_sync(scn->qdf_dev->dev, timeout)) { + hif_err("force wake request send failed"); + HIF_STATS_INC(pci_scn, mhi_force_wake_failure, 1); + return -EINVAL; + } + + /* If device's M1 state-change event races here, it can be ignored, + * as the device is expected to immediately move from M2 to M0 + * without entering low power state. + */ + if (!pld_is_device_awake(scn->qdf_dev->dev)) + HIF_INFO("%s: state-change event races, ignore", __func__); + + HIF_STATS_INC(pci_scn, mhi_force_wake_success, 1); + + return 0; +} + +int hif_force_wake_release(struct hif_opaque_softc *hif_handle) +{ + int ret; + struct hif_softc *scn = (struct hif_softc *)hif_handle; + struct hif_pci_softc *pci_scn = HIF_GET_PCI_SOFTC(scn); + + ret = pld_force_wake_release(scn->qdf_dev->dev); + if (ret) { + hif_err("force wake release failure"); + HIF_STATS_INC(pci_scn, mhi_force_wake_release_failure, 1); + return ret; + } + + HIF_STATS_INC(pci_scn, mhi_force_wake_release_success, 1); + return 0; +} +#endif /* DEVICE_FORCE_WAKE_ENABLE */ + +void hif_print_pci_stats(struct hif_pci_softc *pci_handle) +{ + hif_debug("mhi_force_wake_request_vote: %d", + pci_handle->stats.mhi_force_wake_request_vote); + hif_debug("mhi_force_wake_failure: %d", + pci_handle->stats.mhi_force_wake_failure); + hif_debug("mhi_force_wake_success: %d", + pci_handle->stats.mhi_force_wake_success); + hif_debug("soc_force_wake_register_write_success: %d", + pci_handle->stats.soc_force_wake_register_write_success); + hif_debug("soc_force_wake_failure: %d", + pci_handle->stats.soc_force_wake_failure); + hif_debug("soc_force_wake_success: %d", + pci_handle->stats.soc_force_wake_success); + hif_debug("mhi_force_wake_release_failure: %d", + pci_handle->stats.mhi_force_wake_release_failure); + hif_debug("mhi_force_wake_release_success: %d", + pci_handle->stats.mhi_force_wake_release_success); + hif_debug("oc_force_wake_release_success: %d", + pci_handle->stats.soc_force_wake_release_success); +} +#endif /* FORCE_WAKE */ + #ifdef FEATURE_HAL_DELAYED_REG_WRITE int hif_prevent_link_low_power_states(struct hif_opaque_softc *hif) { diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.h b/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.h index f3858ef4057125e9d589ff6b54ae9fc134f5cc5c..cdcb558eea1c29d22f6d3dabc00a4573a5eb06c9 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/pcie/if_pci.h @@ -28,7 +28,21 @@ #include "hif.h" #include "cepci.h" #include "ce_main.h" -#include + +#ifdef FORCE_WAKE +/* Register to wake the UMAC from power collapse */ +#define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40) +/* Register used for handshake mechanism to validate UMAC is awake */ +#define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG (0x01E00000 + 0x3004) +/* Timeout duration to validate UMAC wake status */ +#ifdef HAL_CONFIG_SLUB_DEBUG_ON +#define FORCE_WAKE_DELAY_TIMEOUT_MS 500 +#else +#define FORCE_WAKE_DELAY_TIMEOUT_MS 50 +#endif /* HAL_CONFIG_SLUB_DEBUG_ON */ +/* Validate UMAC status every 5ms */ +#define FORCE_WAKE_DELAY_MS 5 +#endif /* FORCE_WAKE */ #ifdef QCA_HIF_HIA_EXTND extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk; @@ -42,6 +56,11 @@ struct hif_tasklet_entry { void *hif_handler; /* struct hif_pci_softc */ }; +struct hang_event_bus_info { + uint16_t tlv_header; + uint16_t dev_id; +} qdf_packed; + /** * enum hif_pm_runtime_state - Driver States for Runtime Power Management * HIF_PM_RUNTIME_STATE_NONE: runtime pm is off @@ -111,6 +130,29 @@ struct hif_msi_info { OS_DMA_MEM_CONTEXT(dmacontext); }; +/** + * struct hif_pci_stats - Account for hif pci based statistics + * @mhi_force_wake_request_vote: vote for mhi + * @mhi_force_wake_failure: mhi force wake failure + * @mhi_force_wake_success: mhi force wake success + * @soc_force_wake_register_write_success: write to soc wake + * @soc_force_wake_failure: soc force wake failure + * @soc_force_wake_success: soc force wake success + * @mhi_force_wake_release_success: mhi force wake release success + * @soc_force_wake_release_success: soc force wake release + */ +struct hif_pci_stats { + uint32_t mhi_force_wake_request_vote; + uint32_t mhi_force_wake_failure; + uint32_t mhi_force_wake_success; + uint32_t soc_force_wake_register_write_success; + uint32_t soc_force_wake_failure; + uint32_t soc_force_wake_success; + uint32_t mhi_force_wake_release_failure; + uint32_t mhi_force_wake_release_success; + uint32_t soc_force_wake_release_success; +}; + struct hif_pci_softc { struct HIF_CE_state ce_sc; void __iomem *mem; /* PCI address. */ @@ -157,6 +199,11 @@ struct hif_pci_softc { void (*hif_pci_deinit)(struct hif_pci_softc *sc); void (*hif_pci_get_soc_info)(struct hif_pci_softc *sc, struct device *dev); + struct hif_pci_stats stats; +#ifdef HIF_CPU_PERF_AFFINE_MASK + /* Stores the affinity hint mask for each CE IRQ */ + qdf_cpu_mask ce_irq_cpu_mask[CE_COUNT_MAX]; +#endif }; bool hif_pci_targ_is_present(struct hif_softc *scn, void *__iomem *mem); @@ -201,6 +248,21 @@ int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset); #define OL_ATH_TX_DRAIN_WAIT_CNT 60 #endif +#ifdef FORCE_WAKE +/** + * hif_print_pci_stats() - Display HIF PCI stats + * @hif_ctx - HIF pci handle + * + * Return: None + */ +void hif_print_pci_stats(struct hif_pci_softc *pci_scn); +#else +static inline +void hif_print_pci_stats(struct hif_pci_softc *pci_scn) +{ +} +#endif /* FORCE_WAKE */ + #ifdef FEATURE_RUNTIME_PM #include @@ -220,4 +282,16 @@ static inline int hif_pm_runtime_put_auto(struct device *dev) } #endif /* FEATURE_RUNTIME_PM */ + +#ifdef HIF_BUS_LOG_INFO +bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset); +#else +static inline +bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data, + unsigned int *offset) +{ + return false; +} +#endif #endif /* __ATH_PCI_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6290def.c b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6290def.c index e755ced1297ad2994a5e69ab345516dc8e301ff2..4070b10ad4ce3a3bd64d3b430cdf01be96233900 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6290def.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6290def.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -152,15 +152,8 @@ #define CE_DDR_ADDRESS_FOR_RRI_LOW MISSING #define CE_DDR_ADDRESS_FOR_RRI_HIGH MISSING -#if defined(WCSS_VERSION) && \ - ((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \ - (defined(CONFIG_MCL) && (WCSS_VERSION >= 72))) #define HOST_IE_ADDRESS UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_0 #define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_1 -#else /* WCSS_VERSION < 72 */ -#define HOST_IE_ADDRESS UMAC_CE_COMMON_CE_HOST_IE_0 -#define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_CE_HOST_IE_1 -#endif /* WCSS_VERSION */ #define HOST_IE_COPY_COMPLETE_MASK MISSING #define SR_BA_ADDRESS MISSING diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6390def.c b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6390def.c index ffdcb17f08c04ef8180de405762474e5be6522c5..59fc7d56290a755db3d0a5de8b1d949c0c20391e 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6390def.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6390def.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -152,15 +152,8 @@ #define CE_DDR_ADDRESS_FOR_RRI_LOW MISSING #define CE_DDR_ADDRESS_FOR_RRI_HIGH MISSING -#if defined(WCSS_VERSION) && \ - ((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \ - (defined(CONFIG_MCL) && (WCSS_VERSION >= 72))) #define HOST_IE_ADDRESS UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_0 #define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_1 -#else /* WCSS_VERSION < 72 */ -#define HOST_IE_ADDRESS UMAC_CE_COMMON_CE_HOST_IE_0 -#define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_CE_HOST_IE_1 -#endif /* WCSS_VERSION */ #define HOST_IE_COPY_COMPLETE_MASK MISSING #define SR_BA_ADDRESS MISSING diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6490def.c b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6490def.c new file mode 100644 index 0000000000000000000000000000000000000000..1dc1ec2a99475ea431e54acd504be7af5d5ae29a --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6490def.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#if defined(QCA6490_HEADERS_DEF) + +#undef UMAC +#define WLAN_HEADERS 1 + +#include "lithium_top_reg.h" +#include "wcss_version.h" + +#define MISSING 0 + +#define SOC_RESET_CONTROL_OFFSET MISSING +#define GPIO_PIN0_OFFSET MISSING +#define GPIO_PIN1_OFFSET MISSING +#define GPIO_PIN0_CONFIG_MASK MISSING +#define GPIO_PIN1_CONFIG_MASK MISSING +#define LOCAL_SCRATCH_OFFSET 0x18 +#define GPIO_PIN10_OFFSET MISSING +#define GPIO_PIN11_OFFSET MISSING +#define GPIO_PIN12_OFFSET MISSING +#define GPIO_PIN13_OFFSET MISSING +#define MBOX_BASE_ADDRESS MISSING +#define INT_STATUS_ENABLE_ERROR_LSB MISSING +#define INT_STATUS_ENABLE_ERROR_MASK MISSING +#define INT_STATUS_ENABLE_CPU_LSB MISSING +#define INT_STATUS_ENABLE_CPU_MASK MISSING +#define INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define INT_STATUS_ENABLE_ADDRESS MISSING +#define CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define HOST_INT_STATUS_ADDRESS MISSING +#define CPU_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define COUNT_DEC_ADDRESS MISSING +#define HOST_INT_STATUS_CPU_MASK MISSING +#define HOST_INT_STATUS_CPU_LSB MISSING +#define HOST_INT_STATUS_ERROR_MASK MISSING +#define HOST_INT_STATUS_ERROR_LSB MISSING +#define HOST_INT_STATUS_COUNTER_MASK MISSING +#define HOST_INT_STATUS_COUNTER_LSB MISSING +#define RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define WINDOW_DATA_ADDRESS MISSING +#define WINDOW_READ_ADDR_ADDRESS MISSING +#define WINDOW_WRITE_ADDR_ADDRESS MISSING +/* GPIO Register */ +#define GPIO_ENABLE_W1TS_LOW_ADDRESS MISSING +#define GPIO_PIN0_CONFIG_LSB MISSING +#define GPIO_PIN0_PAD_PULL_LSB MISSING +#define GPIO_PIN0_PAD_PULL_MASK MISSING +/* SI reg */ +#define SI_CONFIG_ERR_INT_MASK MISSING +#define SI_CONFIG_ERR_INT_LSB MISSING + +#define RTC_SOC_BASE_ADDRESS MISSING +#define RTC_WMAC_BASE_ADDRESS MISSING +#define SOC_CORE_BASE_ADDRESS MISSING +#define WLAN_MAC_BASE_ADDRESS MISSING +#define GPIO_BASE_ADDRESS MISSING +#define ANALOG_INTF_BASE_ADDRESS MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define CE_COUNT 12 +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define SI_BASE_ADDRESS MISSING +#define DRAM_BASE_ADDRESS MISSING + +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB MISSING +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK MISSING +#define CLOCK_CONTROL_OFFSET MISSING +#define CLOCK_CONTROL_SI0_CLK_MASK MISSING +#define RESET_CONTROL_SI0_RST_MASK MISSING +#define WLAN_RESET_CONTROL_OFFSET MISSING +#define WLAN_RESET_CONTROL_COLD_RST_MASK MISSING +#define WLAN_RESET_CONTROL_WARM_RST_MASK MISSING +#define CPU_CLOCK_OFFSET MISSING + +#define CPU_CLOCK_STANDARD_LSB MISSING +#define CPU_CLOCK_STANDARD_MASK MISSING +#define LPO_CAL_ENABLE_LSB MISSING +#define LPO_CAL_ENABLE_MASK MISSING +#define WLAN_SYSTEM_SLEEP_OFFSET MISSING + +#define SOC_CHIP_ID_ADDRESS MISSING +#define SOC_CHIP_ID_REVISION_MASK MISSING +#define SOC_CHIP_ID_REVISION_LSB MISSING +#define SOC_CHIP_ID_REVISION_MSB MISSING + +#define FW_IND_EVENT_PENDING MISSING +#define FW_IND_INITIALIZED MISSING + +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_LSB MISSING + +#define SR_WR_INDEX_ADDRESS MISSING +#define DST_WATERMARK_ADDRESS MISSING + +#define DST_WR_INDEX_ADDRESS MISSING +#define SRC_WATERMARK_ADDRESS MISSING +#define SRC_WATERMARK_LOW_MASK MISSING +#define SRC_WATERMARK_HIGH_MASK MISSING +#define DST_WATERMARK_LOW_MASK MISSING +#define DST_WATERMARK_HIGH_MASK MISSING +#define CURRENT_SRRI_ADDRESS MISSING +#define CURRENT_DRRI_ADDRESS MISSING +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_ADDRESS MISSING +#define MISC_IS_ADDRESS MISSING +#define HOST_IS_COPY_COMPLETE_MASK MISSING +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS MISSING +#define CE_DDR_ADDRESS_FOR_RRI_LOW MISSING +#define CE_DDR_ADDRESS_FOR_RRI_HIGH MISSING + +#if (defined(WCSS_VERSION) && (WCSS_VERSION >= 72)) +#define HOST_IE_ADDRESS UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_0 +#define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_1 +#else /* WCSS_VERSION < 72 */ +#define HOST_IE_ADDRESS UMAC_CE_COMMON_CE_HOST_IE_0 +#define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_CE_HOST_IE_1 +#endif /* WCSS_VERSION */ + +#define HOST_IE_COPY_COMPLETE_MASK MISSING +#define SR_BA_ADDRESS MISSING +#define SR_BA_ADDRESS_HIGH MISSING +#define SR_SIZE_ADDRESS MISSING +#define CE_CTRL1_ADDRESS MISSING +#define CE_CTRL1_DMAX_LENGTH_MASK MISSING +#define DR_BA_ADDRESS MISSING +#define DR_BA_ADDRESS_HIGH MISSING +#define DR_SIZE_ADDRESS MISSING +#define CE_CMD_REGISTER MISSING +#define CE_MSI_ADDRESS MISSING +#define CE_MSI_ADDRESS_HIGH MISSING +#define CE_MSI_DATA MISSING +#define CE_MSI_ENABLE_BIT MISSING +#define MISC_IE_ADDRESS MISSING +#define MISC_IS_AXI_ERR_MASK MISSING +#define MISC_IS_DST_ADDR_ERR_MASK MISSING +#define MISC_IS_SRC_LEN_ERR_MASK MISSING +#define MISC_IS_DST_MAX_LEN_VIO_MASK MISSING +#define MISC_IS_DST_RING_OVERFLOW_MASK MISSING +#define MISC_IS_SRC_RING_OVERFLOW_MASK MISSING +#define SRC_WATERMARK_LOW_LSB MISSING +#define SRC_WATERMARK_HIGH_LSB MISSING +#define DST_WATERMARK_LOW_LSB MISSING +#define DST_WATERMARK_HIGH_LSB MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB MISSING +#define CE_CTRL1_DMAX_LENGTH_LSB MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_IDX_UPD_EN_MASK MISSING +#define CE_WRAPPER_DEBUG_OFFSET MISSING +#define CE_WRAPPER_DEBUG_SEL_MSB MISSING +#define CE_WRAPPER_DEBUG_SEL_LSB MISSING +#define CE_WRAPPER_DEBUG_SEL_MASK MISSING +#define CE_DEBUG_OFFSET MISSING +#define CE_DEBUG_SEL_MSB MISSING +#define CE_DEBUG_SEL_LSB MISSING +#define CE_DEBUG_SEL_MASK MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_ENABLES MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_STATUS MISSING + +#define QCA6490_BOARD_DATA_SZ MISSING +#define QCA6490_BOARD_EXT_DATA_SZ MISSING + +#define MY_TARGET_DEF QCA6490_TARGETdef +#define MY_HOST_DEF QCA6490_HOSTdef +#define MY_CEREG_DEF QCA6490_CE_TARGETdef +#define MY_TARGET_BOARD_DATA_SZ QCA6490_BOARD_DATA_SZ +#define MY_TARGET_BOARD_EXT_DATA_SZ QCA6490_BOARD_EXT_DATA_SZ +#include "targetdef.h" +#include "hostdef.h" +#else +#include "common_drv.h" +#include "targetdef.h" +#include "hostdef.h" +struct targetdef_s *QCA6490_TARGETdef; +struct hostdef_s *QCA6490_HOSTdef; +#endif /*QCA6490_HEADERS_DEF */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/qca6750def.c b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6750def.c new file mode 100644 index 0000000000000000000000000000000000000000..6ec562ff6c28bfc54e69d328c479c7b2025e4a81 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/qca6750def.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#if defined(QCA6750_HEADERS_DEF) + +#undef UMAC +#define WLAN_HEADERS 1 +#include "lithium_top_reg.h" +#include "wfss_ce_reg_seq_hwioreg.h" +#include "wcss_version.h" + +#define MISSING 0 + +#define SOC_RESET_CONTROL_OFFSET MISSING +#define GPIO_PIN0_OFFSET MISSING +#define GPIO_PIN1_OFFSET MISSING +#define GPIO_PIN0_CONFIG_MASK MISSING +#define GPIO_PIN1_CONFIG_MASK MISSING +#define LOCAL_SCRATCH_OFFSET 0x18 +#define GPIO_PIN10_OFFSET MISSING +#define GPIO_PIN11_OFFSET MISSING +#define GPIO_PIN12_OFFSET MISSING +#define GPIO_PIN13_OFFSET MISSING +#define MBOX_BASE_ADDRESS MISSING +#define INT_STATUS_ENABLE_ERROR_LSB MISSING +#define INT_STATUS_ENABLE_ERROR_MASK MISSING +#define INT_STATUS_ENABLE_CPU_LSB MISSING +#define INT_STATUS_ENABLE_CPU_MASK MISSING +#define INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define INT_STATUS_ENABLE_ADDRESS MISSING +#define CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define HOST_INT_STATUS_ADDRESS MISSING +#define CPU_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define COUNT_DEC_ADDRESS MISSING +#define HOST_INT_STATUS_CPU_MASK MISSING +#define HOST_INT_STATUS_CPU_LSB MISSING +#define HOST_INT_STATUS_ERROR_MASK MISSING +#define HOST_INT_STATUS_ERROR_LSB MISSING +#define HOST_INT_STATUS_COUNTER_MASK MISSING +#define HOST_INT_STATUS_COUNTER_LSB MISSING +#define RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define WINDOW_DATA_ADDRESS MISSING +#define WINDOW_READ_ADDR_ADDRESS MISSING +#define WINDOW_WRITE_ADDR_ADDRESS MISSING +/* GPIO Register */ +#define GPIO_ENABLE_W1TS_LOW_ADDRESS MISSING +#define GPIO_PIN0_CONFIG_LSB MISSING +#define GPIO_PIN0_PAD_PULL_LSB MISSING +#define GPIO_PIN0_PAD_PULL_MASK MISSING +/* SI reg */ +#define SI_CONFIG_ERR_INT_MASK MISSING +#define SI_CONFIG_ERR_INT_LSB MISSING + +#define RTC_SOC_BASE_ADDRESS MISSING +#define RTC_WMAC_BASE_ADDRESS MISSING +#define SOC_CORE_BASE_ADDRESS MISSING +#define WLAN_MAC_BASE_ADDRESS MISSING +#define GPIO_BASE_ADDRESS MISSING +#define ANALOG_INTF_BASE_ADDRESS MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define CE_COUNT 12 +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define SI_BASE_ADDRESS MISSING +#define DRAM_BASE_ADDRESS MISSING + +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB MISSING +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK MISSING +#define CLOCK_CONTROL_OFFSET MISSING +#define CLOCK_CONTROL_SI0_CLK_MASK MISSING +#define RESET_CONTROL_SI0_RST_MASK MISSING +#define WLAN_RESET_CONTROL_OFFSET MISSING +#define WLAN_RESET_CONTROL_COLD_RST_MASK MISSING +#define WLAN_RESET_CONTROL_WARM_RST_MASK MISSING +#define CPU_CLOCK_OFFSET MISSING + +#define CPU_CLOCK_STANDARD_LSB MISSING +#define CPU_CLOCK_STANDARD_MASK MISSING +#define LPO_CAL_ENABLE_LSB MISSING +#define LPO_CAL_ENABLE_MASK MISSING +#define WLAN_SYSTEM_SLEEP_OFFSET MISSING + +#define SOC_CHIP_ID_ADDRESS MISSING +#define SOC_CHIP_ID_REVISION_MASK MISSING +#define SOC_CHIP_ID_REVISION_LSB MISSING +#define SOC_CHIP_ID_REVISION_MSB MISSING + +#define FW_IND_EVENT_PENDING MISSING +#define FW_IND_INITIALIZED MISSING + +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_LSB MISSING + +#define SR_WR_INDEX_ADDRESS MISSING +#define DST_WATERMARK_ADDRESS MISSING + +#define DST_WR_INDEX_ADDRESS MISSING +#define SRC_WATERMARK_ADDRESS MISSING +#define SRC_WATERMARK_LOW_MASK MISSING +#define SRC_WATERMARK_HIGH_MASK MISSING +#define DST_WATERMARK_LOW_MASK MISSING +#define DST_WATERMARK_HIGH_MASK MISSING +#define CURRENT_SRRI_ADDRESS MISSING +#define CURRENT_DRRI_ADDRESS MISSING +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_ADDRESS MISSING +#define MISC_IS_ADDRESS MISSING +#define HOST_IS_COPY_COMPLETE_MASK MISSING +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS MISSING +#define CE_DDR_ADDRESS_FOR_RRI_LOW MISSING +#define CE_DDR_ADDRESS_FOR_RRI_HIGH MISSING + +#define HOST_IE_ADDRESS HWIO_SOC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_0_ADDR +#define HOST_IE_ADDRESS_2 HWIO_SOC_CE_COMMON_WFSS_CE_COMMON_R0_CE_HOST_IE_1_ADDR + +#define HOST_IE_COPY_COMPLETE_MASK MISSING +#define SR_BA_ADDRESS MISSING +#define SR_BA_ADDRESS_HIGH MISSING +#define SR_SIZE_ADDRESS MISSING +#define CE_CTRL1_ADDRESS MISSING +#define CE_CTRL1_DMAX_LENGTH_MASK MISSING +#define DR_BA_ADDRESS MISSING +#define DR_BA_ADDRESS_HIGH MISSING +#define DR_SIZE_ADDRESS MISSING +#define CE_CMD_REGISTER MISSING +#define CE_MSI_ADDRESS MISSING +#define CE_MSI_ADDRESS_HIGH MISSING +#define CE_MSI_DATA MISSING +#define CE_MSI_ENABLE_BIT MISSING +#define MISC_IE_ADDRESS MISSING +#define MISC_IS_AXI_ERR_MASK MISSING +#define MISC_IS_DST_ADDR_ERR_MASK MISSING +#define MISC_IS_SRC_LEN_ERR_MASK MISSING +#define MISC_IS_DST_MAX_LEN_VIO_MASK MISSING +#define MISC_IS_DST_RING_OVERFLOW_MASK MISSING +#define MISC_IS_SRC_RING_OVERFLOW_MASK MISSING +#define SRC_WATERMARK_LOW_LSB MISSING +#define SRC_WATERMARK_HIGH_LSB MISSING +#define DST_WATERMARK_LOW_LSB MISSING +#define DST_WATERMARK_HIGH_LSB MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB MISSING +#define CE_CTRL1_DMAX_LENGTH_LSB MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_IDX_UPD_EN_MASK MISSING +#define CE_WRAPPER_DEBUG_OFFSET MISSING +#define CE_WRAPPER_DEBUG_SEL_MSB MISSING +#define CE_WRAPPER_DEBUG_SEL_LSB MISSING +#define CE_WRAPPER_DEBUG_SEL_MASK MISSING +#define CE_DEBUG_OFFSET MISSING +#define CE_DEBUG_SEL_MSB MISSING +#define CE_DEBUG_SEL_LSB MISSING +#define CE_DEBUG_SEL_MASK MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_ENABLES MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_STATUS MISSING + +#define QCA6750_BOARD_DATA_SZ MISSING +#define QCA6750_BOARD_EXT_DATA_SZ MISSING + +#define MY_TARGET_DEF QCA6750_TARGETdef +#define MY_HOST_DEF QCA6750_HOSTdef +#define MY_CEREG_DEF QCA6750_CE_TARGETdef +#define MY_TARGET_BOARD_DATA_SZ QCA6750_BOARD_DATA_SZ +#define MY_TARGET_BOARD_EXT_DATA_SZ QCA6750_BOARD_EXT_DATA_SZ +#include "targetdef.h" +#include "hostdef.h" +#else +#include "common_drv.h" +#include "targetdef.h" +#include "hostdef.h" +struct targetdef_s *QCA6750_TARGETdef; +struct hostdef_s *QCA6750_HOSTdef; +#endif /*QCA6750_HEADERS_DEF */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/qcn9000def.c b/drivers/staging/qca-wifi-host-cmn/hif/src/qcn9000def.c new file mode 100644 index 0000000000000000000000000000000000000000..8a9527c49441398cd2049c999f00fb49a73ffed4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/qcn9000def.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "qdf_module.h" + +#if defined(QCN9000_HEADERS_DEF) + +#undef UMAC +#define WLAN_HEADERS 1 + +#include "wcss_version.h" +#include "wcss_seq_hwiobase.h" +#include "wfss_ce_reg_seq_hwioreg.h" + +#define MISSING 0 + +#define SOC_RESET_CONTROL_OFFSET MISSING +#define GPIO_PIN0_OFFSET MISSING +#define GPIO_PIN1_OFFSET MISSING +#define GPIO_PIN0_CONFIG_MASK MISSING +#define GPIO_PIN1_CONFIG_MASK MISSING +#define LOCAL_SCRATCH_OFFSET 0x18 +#define GPIO_PIN10_OFFSET MISSING +#define GPIO_PIN11_OFFSET MISSING +#define GPIO_PIN12_OFFSET MISSING +#define GPIO_PIN13_OFFSET MISSING +#define MBOX_BASE_ADDRESS MISSING +#define INT_STATUS_ENABLE_ERROR_LSB MISSING +#define INT_STATUS_ENABLE_ERROR_MASK MISSING +#define INT_STATUS_ENABLE_CPU_LSB MISSING +#define INT_STATUS_ENABLE_CPU_MASK MISSING +#define INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define INT_STATUS_ENABLE_ADDRESS MISSING +#define CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define HOST_INT_STATUS_ADDRESS MISSING +#define CPU_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_ADDRESS MISSING +#define ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define COUNT_DEC_ADDRESS MISSING +#define HOST_INT_STATUS_CPU_MASK MISSING +#define HOST_INT_STATUS_CPU_LSB MISSING +#define HOST_INT_STATUS_ERROR_MASK MISSING +#define HOST_INT_STATUS_ERROR_LSB MISSING +#define HOST_INT_STATUS_COUNTER_MASK MISSING +#define HOST_INT_STATUS_COUNTER_LSB MISSING +#define RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define WINDOW_DATA_ADDRESS MISSING +#define WINDOW_READ_ADDR_ADDRESS MISSING +#define WINDOW_WRITE_ADDR_ADDRESS MISSING +/* GPIO Register */ +#define GPIO_ENABLE_W1TS_LOW_ADDRESS MISSING +#define GPIO_PIN0_CONFIG_LSB MISSING +#define GPIO_PIN0_PAD_PULL_LSB MISSING +#define GPIO_PIN0_PAD_PULL_MASK MISSING +/* SI reg */ +#define SI_CONFIG_ERR_INT_MASK MISSING +#define SI_CONFIG_ERR_INT_LSB MISSING + +#define RTC_SOC_BASE_ADDRESS MISSING +#define RTC_WMAC_BASE_ADDRESS MISSING +#define SOC_CORE_BASE_ADDRESS MISSING +#define WLAN_MAC_BASE_ADDRESS MISSING +#define GPIO_BASE_ADDRESS MISSING +#define ANALOG_INTF_BASE_ADDRESS MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define CE_COUNT 12 +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define SI_BASE_ADDRESS MISSING +#define DRAM_BASE_ADDRESS MISSING + +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB MISSING +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK MISSING +#define CLOCK_CONTROL_OFFSET MISSING +#define CLOCK_CONTROL_SI0_CLK_MASK MISSING +#define RESET_CONTROL_SI0_RST_MASK MISSING +#define WLAN_RESET_CONTROL_OFFSET MISSING +#define WLAN_RESET_CONTROL_COLD_RST_MASK MISSING +#define WLAN_RESET_CONTROL_WARM_RST_MASK MISSING +#define CPU_CLOCK_OFFSET MISSING + +#define CPU_CLOCK_STANDARD_LSB MISSING +#define CPU_CLOCK_STANDARD_MASK MISSING +#define LPO_CAL_ENABLE_LSB MISSING +#define LPO_CAL_ENABLE_MASK MISSING +#define WLAN_SYSTEM_SLEEP_OFFSET MISSING + +#define SOC_CHIP_ID_ADDRESS MISSING +#define SOC_CHIP_ID_REVISION_MASK MISSING +#define SOC_CHIP_ID_REVISION_LSB MISSING +#define SOC_CHIP_ID_REVISION_MSB MISSING + +#define FW_IND_EVENT_PENDING MISSING +#define FW_IND_INITIALIZED MISSING + +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_MASK MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_TCP_OVER_IPV6_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV4_CHECKSUM_EN_LSB MISSING +#define MSDU_LINK_EXT_3_UDP_OVER_IPV6_CHECKSUM_EN_LSB MISSING + +#define SR_WR_INDEX_ADDRESS MISSING +#define DST_WATERMARK_ADDRESS MISSING + +#define DST_WR_INDEX_ADDRESS MISSING +#define SRC_WATERMARK_ADDRESS MISSING +#define SRC_WATERMARK_LOW_MASK MISSING +#define SRC_WATERMARK_HIGH_MASK MISSING +#define DST_WATERMARK_LOW_MASK MISSING +#define DST_WATERMARK_HIGH_MASK MISSING +#define CURRENT_SRRI_ADDRESS MISSING +#define CURRENT_DRRI_ADDRESS MISSING +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK MISSING +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK MISSING +#define HOST_IS_ADDRESS MISSING +#define MISC_IS_ADDRESS MISSING +#define HOST_IS_COPY_COMPLETE_MASK MISSING +#define CE_WRAPPER_BASE_ADDRESS MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS MISSING +#define CE_DDR_ADDRESS_FOR_RRI_LOW MISSING +#define CE_DDR_ADDRESS_FOR_RRI_HIGH MISSING + +#define HOST_IE_ADDRESS \ + HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_ADDR(\ + WFSS_CE_COMMON_REG_REG_BASE) +#define HOST_IE_REG1_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_SRC_RING_IE_SHFT +#define HOST_IE_ADDRESS_2 \ + HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_1_ADDR(\ + WFSS_CE_COMMON_REG_REG_BASE) +#define HOST_IE_REG2_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_1_STS_RING_IE_SHFT +#define HOST_IE_ADDRESS_3 \ + HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_ADDR(\ + WFSS_CE_COMMON_REG_REG_BASE) +#define HOST_IE_REG3_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_DST_RING_IE_SHFT + +#define HOST_IE_COPY_COMPLETE_MASK MISSING +#define SR_BA_ADDRESS MISSING +#define SR_BA_ADDRESS_HIGH MISSING +#define SR_SIZE_ADDRESS MISSING +#define CE_CTRL1_ADDRESS MISSING +#define CE_CTRL1_DMAX_LENGTH_MASK MISSING +#define DR_BA_ADDRESS MISSING +#define DR_BA_ADDRESS_HIGH MISSING +#define DR_SIZE_ADDRESS MISSING +#define CE_CMD_REGISTER MISSING +#define CE_MSI_ADDRESS MISSING +#define CE_MSI_ADDRESS_HIGH MISSING +#define CE_MSI_DATA MISSING +#define CE_MSI_ENABLE_BIT MISSING +#define MISC_IE_ADDRESS MISSING +#define MISC_IS_AXI_ERR_MASK MISSING +#define MISC_IS_DST_ADDR_ERR_MASK MISSING +#define MISC_IS_SRC_LEN_ERR_MASK MISSING +#define MISC_IS_DST_MAX_LEN_VIO_MASK MISSING +#define MISC_IS_DST_RING_OVERFLOW_MASK MISSING +#define MISC_IS_SRC_RING_OVERFLOW_MASK MISSING +#define SRC_WATERMARK_LOW_LSB MISSING +#define SRC_WATERMARK_HIGH_LSB MISSING +#define DST_WATERMARK_LOW_LSB MISSING +#define DST_WATERMARK_HIGH_LSB MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK MISSING +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB MISSING +#define CE_CTRL1_DMAX_LENGTH_LSB MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK MISSING +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB MISSING +#define CE_CTRL1_IDX_UPD_EN_MASK MISSING +#define CE_WRAPPER_DEBUG_OFFSET MISSING +#define CE_WRAPPER_DEBUG_SEL_MSB MISSING +#define CE_WRAPPER_DEBUG_SEL_LSB MISSING +#define CE_WRAPPER_DEBUG_SEL_MASK MISSING +#define CE_DEBUG_OFFSET MISSING +#define CE_DEBUG_SEL_MSB MISSING +#define CE_DEBUG_SEL_LSB MISSING +#define CE_DEBUG_SEL_MASK MISSING +#define CE0_BASE_ADDRESS MISSING +#define CE1_BASE_ADDRESS MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_ENABLES MISSING +#define A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_STATUS MISSING + +#define QCN9000_BOARD_DATA_SZ MISSING +#define QCN9000_BOARD_EXT_DATA_SZ MISSING + +#define MY_TARGET_DEF QCN9000_TARGETDEF +#define MY_HOST_DEF QCN9000_HOSTDEF +#define MY_CEREG_DEF QCN9000_CE_TARGETDEF +#define MY_TARGET_BOARD_DATA_SZ QCN9000_BOARD_DATA_SZ +#define MY_TARGET_BOARD_EXT_DATA_SZ QCN9000_BOARD_EXT_DATA_SZ +#include "targetdef.h" +#include "hostdef.h" +qdf_export_symbol(QCN9000_CE_TARGETDEF); +#else +#include "common_drv.h" +#include "targetdef.h" +#include "hostdef.h" +struct targetdef_s *QCN9000_TARGETDEF; +struct hostdef_s *QCN9000_HOSTDEF; +#endif /*QCN9000_HEADERS_DEF */ +qdf_export_symbol(QCN9000_TARGETDEF); +qdf_export_symbol(QCN9000_HOSTDEF); diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/regtable.c b/drivers/staging/qca-wifi-host-cmn/hif/src/regtable.c index 82d2feae11c288151856c07e2072d987bf99ff73..a6496b1cab0c0870314b303d5cb772b17e5b5d12 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/regtable.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/regtable.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -126,6 +126,14 @@ void hif_target_register_tbl_attach(struct hif_softc *scn, u32 target_type) break; #endif +#if defined(QCN9000_HEADERS_DEF) + case TARGET_TYPE_QCN9000: + scn->targetdef = QCN9000_TARGETDEF; + scn->target_ce_def = QCN9000_CE_TARGETDEF; + HIF_TRACE("%s: TARGET_TYPE_QCN9000", __func__); + break; +#endif + #if defined(QCA6390_HEADERS_DEF) case TARGET_TYPE_QCA6390: scn->targetdef = QCA6390_TARGETdef; @@ -134,6 +142,21 @@ void hif_target_register_tbl_attach(struct hif_softc *scn, u32 target_type) break; #endif /* QCA6390_HEADERS_DEF */ +#if defined(QCA6490_HEADERS_DEF) + case TARGET_TYPE_QCA6490: + scn->targetdef = QCA6490_TARGETdef; + scn->target_ce_def = QCA6490_CE_TARGETdef; + HIF_TRACE("%s: TARGET_TYPE_QCA6490", __func__); + break; +#endif /* QCA6490_HEADERS_DEF */ + +#if defined(QCA6750_HEADERS_DEF) + case TARGET_TYPE_QCA6750: + scn->targetdef = QCA6750_TARGETdef; + scn->target_ce_def = QCA6750_CE_TARGETdef; + HIF_TRACE("%s: TARGET_TYPE_QCA6750", __func__); + break; +#endif /* QCA6750_HEADERS_DEF */ default: break; } @@ -222,6 +245,11 @@ void hif_register_tbl_attach(struct hif_softc *scn, u32 hif_type) scn->hostdef = QCA6290_HOSTdef; break; #endif +#if defined(QCN9000_HEADERS_DEF) + case HIF_TYPE_QCN9000: + scn->hostdef = QCN9000_HOSTDEF; + break; +#endif #if defined(QCA6390_HEADERS_DEF) case HIF_TYPE_QCA6390: @@ -230,6 +258,19 @@ void hif_register_tbl_attach(struct hif_softc *scn, u32 hif_type) break; #endif /* QCA6390_HEADERS_DEF */ +#if defined(QCA6490_HEADERS_DEF) + case HIF_TYPE_QCA6490: + scn->hostdef = QCA6490_HOSTdef; + HIF_TRACE("%s: HIF_TYPE_QCA6490", __func__); + break; +#endif /* QCA6490_HEADERS_DEF */ + +#if defined(QCA6750_HEADERS_DEF) + case TARGET_TYPE_QCA6750: + scn->hostdef = QCA6750_HOSTdef; + HIF_TRACE("%s: TARGET_TYPE_QCA6750", __func__); + break; +#endif /* QCA6750_HEADERS_DEF */ default: break; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_bmi_reg_access.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_bmi_reg_access.c index d274d841588afe6bcd9ea2df1e094a8a30c42ad2..ada36b00f665b5f05ab6e3ef9964e6b8ae61d073 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_bmi_reg_access.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_bmi_reg_access.c @@ -25,6 +25,7 @@ #include "htc_api.h" #include "if_sdio.h" #include "regtable_sdio.h" +#include "hif_sdio_dev.h" #define BMI_COMMUNICATION_TIMEOUT 100000 diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_diag_reg_access.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_diag_reg_access.c index 0f4d50c83abb402efc57e908694f638b684dfd86..30e363552fd5d6556f2dd014f527f3eccc68acce 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_diag_reg_access.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_diag_reg_access.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,7 +26,7 @@ #include "hif.h" #include "if_sdio.h" #include "regtable_sdio.h" - +#include "hif_sdio_dev.h" #include "qdf_module.h" #define CPU_DBG_SEL_ADDRESS 0x00000483 diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio.c index 39aaf8e7399c41c92c4448284c619c252dead8dc..5636c4702af864cf5df96d49414740ec84520179 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio.c @@ -37,6 +37,7 @@ #include "hif_sdio_dev.h" #include "if_sdio.h" #include "regtable_sdio.h" +#include #define ATH_MODULE_NAME hif_sdio @@ -53,8 +54,16 @@ uint32_t hif_start(struct hif_opaque_softc *hif_ctx) struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); struct hif_sdio_dev *hif_device = scn->hif_handle; struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); + struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); + int ret = 0; HIF_ENTER(); + ret = hif_sdio_bus_configure(hif_sc); + if (ret) { + HIF_ERROR("%s: hif_sdio_bus_configure failed", __func__); + return QDF_STATUS_E_FAILURE; + } + hif_dev_enable_interrupts(htc_sdio_device); HIF_EXIT(); return QDF_STATUS_SUCCESS; diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_common.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_common.h index dc0900da898803f1220a4fbfc0732a145898c93d..21977f2a7045be40c0ef5dd5bd237d32100079f0 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_common.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,11 +26,13 @@ #define MANUFACTURER_ID_AR6320_BASE 0x500 #define MANUFACTURER_ID_QCA9377_BASE 0x700 #define MANUFACTURER_ID_QCA9379_BASE 0x800 -#define MANUFACTURER_ID_QCN7605_BASE 0x0000 /*TODO - GenoaSDIO */ +#define MANUFACTURER_ID_QCN7605 0x400B +#define MANUFACTURER_ID_QCN7605_BASE 0x4000 #define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00 #define MANUFACTURER_ID_AR6K_REV_MASK 0x00FF #define FUNCTION_CLASS 0x0 -#define MANUFACTURER_CODE 0x271 +#define MANUFACTURER_CODE 0x271 /* Atheros Manufacturer ID */ +#define MANUFACTURER_QC_CODE 0x70 /* QC Manufacturer ID */ #endif /* _HIF_SDIO_COMMON_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.c index 253cf2768080813a013132557b82e8b21ffb0754..ba2277a3bb866b4d3ca351a4bde53c64ae79794e 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.c @@ -208,127 +208,6 @@ QDF_STATUS hif_dev_enable_interrupts(struct hif_sdio_device *pdev) return status; } -#define DEV_CHECK_RECV_YIELD(pdev) \ - ((pdev)->CurrentDSRRecvCount >= \ - (pdev)->HifIRQYieldParams.recv_packet_yield_count) - -/** - * hif_dev_dsr_handler() - Synchronous interrupt handler - * - * @context: hif send context - * - * Return: 0 for success and non-zero for failure - */ -QDF_STATUS hif_dev_dsr_handler(void *context) -{ - struct hif_sdio_device *pdev = (struct hif_sdio_device *)context; - QDF_STATUS status = QDF_STATUS_SUCCESS; - bool done = false; - bool async_proc = false; - - HIF_ENTER(); - - /* reset the recv counter that tracks when we need - * to yield from the DSR - */ - pdev->CurrentDSRRecvCount = 0; - /* reset counter used to flag a re-scan of IRQ - * status registers on the target - */ - pdev->RecheckIRQStatusCnt = 0; - - while (!done) { - status = hif_dev_process_pending_irqs(pdev, &done, &async_proc); - if (QDF_IS_STATUS_ERROR(status)) - break; - - if (pdev->HifIRQProcessingMode == HIF_DEVICE_IRQ_SYNC_ONLY) { - /* the HIF layer does not allow async IRQ processing, - * override the asyncProc flag - */ - async_proc = false; - /* this will cause us to re-enter ProcessPendingIRQ() - * and re-read interrupt status registers. - * This has a nice side effect of blocking us until all - * async read requests are completed. This behavior is - * required as we do not allow ASYNC processing - * in interrupt handlers (like Windows CE) - */ - - if (pdev->DSRCanYield && DEV_CHECK_RECV_YIELD(pdev)) - /* ProcessPendingIRQs() pulled enough recv - * messages to satisfy the yield count, stop - * checking for more messages and return - */ - break; - } - - if (async_proc) { - /* the function does some async I/O for performance, - * we need to exit the ISR immediately, the check below - * will prevent the interrupt from being - * Ack'd while we handle it asynchronously - */ - break; - } - } - - if (QDF_IS_STATUS_SUCCESS(status) && !async_proc) { - /* Ack the interrupt only if : - * 1. we did not get any errors in processing interrupts - * 2. there are no outstanding async processing requests - */ - if (pdev->DSRCanYield) { - /* if the DSR can yield do not ACK the interrupt, there - * could be more pending messages. The HIF layer - * must ACK the interrupt on behalf of HTC - */ - HIF_INFO("%s: Yield (RX count: %d)", - __func__, pdev->CurrentDSRRecvCount); - } else { - HIF_INFO("%s: Ack interrupt", __func__); - hif_ack_interrupt(pdev->HIFDevice); - } - } - - HIF_EXIT(); - return status; -} - -/** hif_dev_set_mailbox_swap() - Set the mailbox swap from firmware - * @pdev : The HIF layer object - * - * Return: none - */ -void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev) -{ - struct hif_sdio_device *hif_device = hif_dev_from_hif(pdev); - - HIF_ENTER(); - - hif_device->swap_mailbox = true; - - HIF_EXIT(); -} - -/** hif_dev_get_mailbox_swap() - Get the mailbox swap setting - * @pdev : The HIF layer object - * - * Return: none - */ -bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev) -{ - struct hif_sdio_device *hif_device; - - HIF_ENTER(); - - hif_device = hif_dev_from_hif(pdev); - - HIF_EXIT(); - - return hif_device->swap_mailbox; -} - /** * hif_dev_setup() - set up sdio device. * @pDev: sdio device context @@ -346,7 +225,6 @@ QDF_STATUS hif_dev_setup(struct hif_sdio_device *pdev) status = hif_dev_setup_device(pdev); - if (status != QDF_STATUS_SUCCESS) { HIF_ERROR("%s: device specific setup failed", __func__); return QDF_STATUS_E_INVAL; diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.h index 5dbe6820c9d39787b61f6c85bec3c2dc3f9dad3c..7ee6582e6aa80beb29bae570c427c80cb6059f19 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_dev.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,7 @@ #include #include "athstartpack.h" #include "hif_internal.h" +#include "if_sdio.h" struct hif_sdio_device *hif_dev_from_hif(struct hif_sdio_dev *hif_device); @@ -47,7 +48,7 @@ QDF_STATUS hif_dev_send_buffer(struct hif_sdio_device *htc_sdio_device, QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev, bool *done, - bool *async_processing); + bool *async_processing); void hif_dev_mask_interrupts(struct hif_sdio_device *pdev); @@ -60,9 +61,9 @@ void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev); int hif_dev_setup_device(struct hif_sdio_device *pdev); -QDF_STATUS hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, - struct hif_device_mbox_info *config, - uint32_t config_len); +int hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, + void *config, + uint32_t config_len); void hif_dev_get_block_size(void *config); @@ -70,8 +71,93 @@ void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev); bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev); -int hif_sdio_set_drvdata(struct sdio_func *func, - struct hif_sdio_dev *hifdevice); - -struct hif_sdio_dev *get_hif_device(struct sdio_func *func); +QDF_STATUS hif_read_write(struct hif_sdio_dev *device, unsigned long address, + char *buffer, uint32_t length, uint32_t request, + void *context); + +#ifdef CONFIG_SDIO_TRANSFER_MAILBOX +static inline struct hif_sdio_dev *get_hif_device(struct hif_softc *hif_ctx, + struct sdio_func *func) +{ + qdf_assert(func); + return (struct hif_sdio_dev *)sdio_get_drvdata(func); +} + +/** + * hif_sdio_set_drvdata() - set wlan driver data into upper layer private + * @hif_ctx: HIF object + * @func: pointer to sdio function + * @hifdevice: pointer to hif device + * + * Return: zero for success. + */ +static inline int hif_sdio_set_drvdata(struct hif_softc *hif_ctx, + struct sdio_func *func, + struct hif_sdio_dev *hifdevice) +{ + sdio_set_drvdata(func, hifdevice); + return 0; +} + +static inline int hif_dev_configure_pipes(struct hif_sdio_dev *pdev, + struct sdio_func *func) +{ + return 0; +} + +static inline int hif_dev_register_channels(struct hif_sdio_dev *dev, + struct sdio_func *func) +{ + return 0; +} + +static inline void hif_dev_unregister_channels(struct hif_sdio_dev *dev, + struct sdio_func *func) +{ +} +#else +static inline struct hif_sdio_dev *get_hif_device(struct hif_softc *hif_ctx, + struct sdio_func *func) +{ + struct hif_sdio_softc *scn = (struct hif_sdio_softc *)hif_ctx; + + return (struct hif_sdio_dev *)scn->hif_handle; +} + +/** + * hif_sdio_set_drvdata() - set wlan driver data into upper layer private + * @hif_ctx: HIF object + * @func: pointer to sdio function + * @hifdevice: pointer to hif device + * + * Return: zero for success. + */ +static inline int hif_sdio_set_drvdata(struct hif_softc *hif_ctx, + struct sdio_func *func, + struct hif_sdio_dev *hifdevice) +{ + struct hif_sdio_softc *sc = (struct hif_sdio_softc *)hif_ctx; + + sc->hif_handle = hifdevice; + + return 0; +} + +int hif_dev_configure_pipes(struct hif_sdio_dev *pdev, + struct sdio_func *func); + +int hif_dev_register_channels(struct hif_sdio_dev *dev, + struct sdio_func *func); + +void hif_dev_unregister_channels(struct hif_sdio_dev *dev, + struct sdio_func *func); +#endif /* SDIO_TRANSFER */ +QDF_STATUS hif_enable_func(struct hif_softc *ol_sc, struct hif_sdio_dev *device, + struct sdio_func *func, bool resume); +QDF_STATUS hif_disable_func(struct hif_sdio_dev *device, + struct sdio_func *func, + bool reset); +A_STATUS hif_sdio_probe(struct hif_softc *ol_sc, + struct sdio_func *func, + struct hif_sdio_dev *device); #endif /* HIF_SDIO_DEV_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_internal.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_internal.h index 67c8ebfab7f189077cccd61a39965deb31623b0e..b378575d085489bdb07b65752ba077cbba309036 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/hif_sdio_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,7 +28,7 @@ #if defined(CONFIG_SDIO_TRANSFER_MAILBOX) #include #elif defined(CONFIG_SDIO_TRANSFER_ADMA) -#error "Error - Not implemented yet" +#include #else #error "Error - Invalid transfer method" #endif @@ -54,7 +54,6 @@ struct hif_sdio_device { qdf_spinlock_t TxLock; qdf_spinlock_t RxLock; struct hif_msg_callbacks hif_callbacks; - struct hif_device_mbox_info MailBoxInfo; uint32_t BlockSize; uint32_t BlockMask; enum hif_device_irq_mode HifIRQProcessingMode; @@ -65,8 +64,11 @@ struct hif_sdio_device { int RecheckIRQStatusCnt; uint32_t RecvStateFlags; void *pTarget; - bool swap_mailbox; struct devRegisters devRegisters; +#ifdef CONFIG_SDIO_TRANSFER_MAILBOX + bool swap_mailbox; + struct hif_device_mbox_info MailBoxInfo; +#endif }; #define LOCK_HIF_DEV(device) qdf_spin_lock(&(device)->Lock) diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.c index 0b98d0baf5d8b08b88a4b5fcd67dacbc0400b9a2..102b84d09fff387d8e53f46ada087622e5493c32 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -181,7 +181,7 @@ void hif_sdio_disable_bus(struct hif_softc *hif_sc) { struct sdio_func *func = dev_to_sdio_func(hif_sc->qdf_dev->dev); - hif_sdio_device_removed(func); + hif_sdio_device_removed(hif_sc, func); } /** diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.h index 1891c8b3e939ded30c7f8b66070ee82be81cc71b..191ea615ec237863b037d0798c4476bea9709904 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/if_sdio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -83,7 +83,7 @@ int hif_sdio_device_inserted(struct hif_softc *ol_sc, const struct sdio_device_id *id); void hif_sdio_stop(struct hif_softc *hif_ctx); void hif_sdio_shutdown(struct hif_softc *hif_ctx); -void hif_sdio_device_removed(struct sdio_func *func); +void hif_sdio_device_removed(struct hif_softc *hif_ctx, struct sdio_func *func); int hif_device_suspend(struct hif_softc *ol_sc, struct device *dev); int hif_device_resume(struct hif_softc *ol_sc, struct device *dev); void hif_register_tbl_attach(struct hif_softc *scn, diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/include/hif_internal.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/include/hif_internal.h index 8f2719a22802615f5810b96dd5ce2e8739fe75d7..41001c848ae984d2183361516ade24ef4ece9e96 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/include/hif_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/include/hif_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +35,7 @@ #include #include #include +#include #include "hif.h" #include "hif_debug.h" #include "hif_sdio_common.h" @@ -167,7 +168,7 @@ struct bus_request { struct bus_request *next; /* link list of available requests */ struct bus_request *inusenext; /* link list of in use requests */ struct semaphore sem_req; - uint32_t address; /* request data */ + unsigned long address; /* request data */ char *buffer; uint32_t length; uint32_t request; @@ -176,6 +177,14 @@ struct bus_request { struct HIF_SCATTER_REQ_PRIV *scatter_req; }; +#define HIF_ADMA_MAX_CHANS 2 +#ifdef CONFIG_SDIO_TRANSFER_ADMA +struct rx_q_entry { + qdf_list_node_t entry; + qdf_nbuf_t nbuf; +}; +#endif + struct hif_sdio_dev { struct sdio_func *func; qdf_spinlock_t asynclock; @@ -201,6 +210,15 @@ struct hif_sdio_dev { const struct sdio_device_id *id; struct mmc_host *host; void *htc_context; +#ifdef CONFIG_SDIO_TRANSFER_ADMA + struct sdio_al_client_handle *al_client; + struct sdio_al_channel_handle *al_chan[HIF_ADMA_MAX_CHANS]; + uint8_t adma_chans_used; + qdf_list_t rx_q; + qdf_spinlock_t rx_q_lock; + qdf_work_t rx_q_alloc_work; + bool rx_q_alloc_work_scheduled; +#endif }; struct HIF_DEVICE_OS_DEVICE_INFO { @@ -270,18 +288,13 @@ QDF_STATUS hif_configure_device(struct hif_softc *ol_sc, QDF_STATUS hif_attach_htc(struct hif_sdio_dev *device, struct htc_callbacks *callbacks); -QDF_STATUS hif_read_write(struct hif_sdio_dev *device, - uint32_t address, - char *buffer, - uint32_t length, uint32_t request, void *context); - void hif_ack_interrupt(struct hif_sdio_dev *device); void hif_mask_interrupt(struct hif_sdio_dev *device); void hif_un_mask_interrupt(struct hif_sdio_dev *device); -void hif_sdio_configure_pipes(struct hif_sdio_dev *dev, struct sdio_func *func); +int hif_sdio_configure_pipes(struct hif_sdio_dev *dev, struct sdio_func *func); struct _HIF_SCATTER_ITEM { u_int8_t *buffer; /* CPU accessible address of buffer */ @@ -400,14 +413,14 @@ static inline QDF_STATUS do_hif_read_write_scatter(struct hif_sdio_dev *device, #define SDIO_SET_CMD52_WRITE_ARG(arg, func, address, value) \ SDIO_SET_CMD52_ARG(arg, 1, (func), 0, address, value) -void hif_sdio_quirk_force_drive_strength(struct sdio_func *func); -void hif_sdio_quirk_write_cccr(struct sdio_func *func); -int hif_sdio_quirk_mod_strength(struct sdio_func *func); -int hif_sdio_quirk_async_intr(struct sdio_func *func); -int hif_sdio_set_bus_speed(struct sdio_func *func); -int hif_sdio_set_bus_width(struct sdio_func *func); -int hif_sdio_func_enable(struct hif_sdio_dev *device, - struct sdio_func *func); +void hif_sdio_quirk_force_drive_strength(struct hif_softc *ol_sc, + struct sdio_func *func); +void hif_sdio_quirk_write_cccr(struct hif_softc *ol_sc, struct sdio_func *func); +int hif_sdio_quirk_mod_strength(struct hif_softc *ol_sc, + struct sdio_func *func); +int hif_sdio_quirk_async_intr(struct hif_softc *ol_sc, struct sdio_func *func); +int hif_sdio_set_bus_speed(struct hif_softc *ol_sc, struct sdio_func *func); +int hif_sdio_set_bus_width(struct hif_softc *ol_sc, struct sdio_func *func); QDF_STATUS hif_sdio_func_disable(struct hif_sdio_dev *device, struct sdio_func *func, bool reset); diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/dev_quirks.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/dev_quirks.c index b84f1ab8b7e0ef3da87c8d3c5efe17a37ff01b7b..7c7e63ba01185d2c75f436bba67bbaaec01d425e 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/dev_quirks.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/dev_quirks.c @@ -1,8 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. - * - * - * + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -91,8 +88,10 @@ module_param(brokenirq, uint, 0644); MODULE_PARM_DESC(brokenirq, "Set as 1 to use polling method instead of interrupt mode"); +#ifdef CONFIG_SDIO_TRANSFER_MAILBOX /** * hif_sdio_force_drive_strength() - Set SDIO drive strength + * @ol_sc: softc instance * @func: pointer to sdio_func * * This function forces the driver strength of the SDIO @@ -100,61 +99,156 @@ MODULE_PARM_DESC(brokenirq, * * Return: none. */ -void hif_sdio_quirk_force_drive_strength(struct sdio_func *func) +void hif_sdio_quirk_force_drive_strength(struct hif_softc *ol_sc, + struct sdio_func *func) { int err = 0; unsigned char value = 0; uint32_t mask = 0, addr = SDIO_CCCR_DRIVE_STRENGTH; - struct hif_sdio_dev *device = sdio_get_drvdata(func); - uint16_t manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; + err = func0_cmd52_read_byte(func->card, addr, &value); + if (err) { + HIF_ERROR("%s: read driver strength 0x%02X fail %d\n", + __func__, addr, err); + return; + } + + mask = (SDIO_DRIVE_DTSx_MASK << SDIO_DRIVE_DTSx_SHIFT); + value = (value & ~mask) | SDIO_DTSx_SET_TYPE_D; + err = func0_cmd52_write_byte(func->card, addr, value); + if (err) { + HIF_ERROR("%s: write driver strength failed", __func__); + HIF_ERROR("%s: 0x%02X to 0x%02X failed: %d\n", __func__, + (uint32_t)value, addr, err); + return; + } + + value = 0; + addr = CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR; + err = func0_cmd52_read_byte(func->card, addr, &value); + if (err) { + HIF_ERROR("%s Read CCCR 0x%02X failed: %d\n", + __func__, addr, err); + return; + } + + mask = CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK; + value = (value & ~mask) | CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A | + CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C | + CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D; + err = func0_cmd52_write_byte(func->card, addr, value); + if (err) + HIF_ERROR("%s Write CCCR 0x%02X to 0x%02X failed: %d\n", + __func__, addr, value, err); +} + +/** + * hif_sdio_quirk_async_intr() - Set asynchronous interrupt settings + * @ol_sc: softc instance + * @func: pointer to sdio_func + * + * The values are taken from the module parameter asyncintdelay + * Call this with the sdhci host claimed + * + * Return: none. + */ +int hif_sdio_quirk_async_intr(struct hif_softc *ol_sc, struct sdio_func *func) +{ + uint8_t data; + uint16_t manfid; + int set_async_irq = 0, ret = 0; + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); + + manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; switch (manfid) { - case MANUFACTURER_ID_QCN7605_BASE: + case MANUFACTURER_ID_AR6003_BASE: + set_async_irq = 1; + ret = + func0_cmd52_write_byte(func->card, + CCCR_SDIO_IRQ_MODE_REG_AR6003, + SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003); + if (ret) + return ret; break; - default: - err = func0_cmd52_read_byte(func->card, addr, &value); - if (err) { - HIF_ERROR("%s: read driver strength 0x%02X fail %d\n", - __func__, addr, err); - break; - } + case MANUFACTURER_ID_AR6320_BASE: + case MANUFACTURER_ID_QCA9377_BASE: + case MANUFACTURER_ID_QCA9379_BASE: + set_async_irq = 1; + ret = func0_cmd52_read_byte(func->card, + CCCR_SDIO_IRQ_MODE_REG_AR6320, + &data); + if (ret) + return ret; - mask = (SDIO_DRIVE_DTSx_MASK << SDIO_DRIVE_DTSx_SHIFT); - value = (value & ~mask) | SDIO_DTSx_SET_TYPE_D; - err = func0_cmd52_write_byte(func->card, addr, value); - if (err) { - HIF_ERROR("%s: write driver strength failed", __func__); - HIF_ERROR("%s: 0x%02X to 0x%02X failed: %d\n", __func__, - (uint32_t)value, addr, err); - break; - } + data |= SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320; + ret = func0_cmd52_write_byte(func->card, + CCCR_SDIO_IRQ_MODE_REG_AR6320, + data); + if (ret) + return ret; + break; + } - value = 0; - addr = CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR; - err = func0_cmd52_read_byte(func->card, addr, &value); - if (err) { - HIF_ERROR("%s Read CCCR 0x%02X failed: %d\n", - __func__, addr, err); - break; - } + if (asyncintdelay) { + /* Set CCCR 0xF0[7:6] to increase async interrupt delay clock + * to fix interrupt missing issue on dell 8460p + */ - mask = CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK; - value = (value & ~mask) | - CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A | - CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C | - CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D; - err = func0_cmd52_write_byte(func->card, addr, value); - if (err) - HIF_ERROR("%s Write CCCR 0x%02X to 0x%02X failed: %d\n", - __func__, addr, value, err); + ret = func0_cmd52_read_byte(func->card, + CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, + &data); + if (ret) + return ret; - break; + data = (data & ~CCCR_SDIO_ASYNC_INT_DELAY_MASK) | + ((asyncintdelay << CCCR_SDIO_ASYNC_INT_DELAY_LSB) & + CCCR_SDIO_ASYNC_INT_DELAY_MASK); + + ret = func0_cmd52_write_byte(func->card, + CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, + data); + if (ret) + return ret; } + + return ret; +} +#else +/** + * hif_sdio_force_drive_strength() - Set SDIO drive strength + * @ol_sc: softc instance + * @func: pointer to sdio_func + * + * This function forces the driver strength of the SDIO + * Call this with the sdhci host claimed + * + * Return: none. + */ +void hif_sdio_quirk_force_drive_strength(struct hif_softc *ol_sc, + struct sdio_func *func) +{ } +/** + * hif_sdio_quirk_async_intr() - Set asynchronous interrupt settings + * @ol_sc: softc instance + * @func: pointer to sdio_func + * + * The values are taken from the module parameter asyncintdelay + * Call this with the sdhci host claimed + * + * Return: none. + */ +int hif_sdio_quirk_async_intr(struct hif_softc *ol_sc, struct sdio_func *func) +{ + return 0; +} +#endif + /** * hif_sdio_quirk_write_cccr() - write a desired CCCR register + * @ol_sc: softc instance * @func: pointer to sdio_func * * The values are taken from the module parameter writecccr @@ -162,7 +256,7 @@ void hif_sdio_quirk_force_drive_strength(struct sdio_func *func) * * Return: none. */ -void hif_sdio_quirk_write_cccr(struct sdio_func *func) +void hif_sdio_quirk_write_cccr(struct hif_softc *ol_sc, struct sdio_func *func) { int32_t err; @@ -231,6 +325,7 @@ void hif_sdio_quirk_write_cccr(struct sdio_func *func) /** * hif_sdio_quirk_mod_strength() - write a desired CCCR register + * @ol_sc: softc instance * @func: pointer to sdio_func * * The values are taken from the module parameter writecccr @@ -238,11 +333,11 @@ void hif_sdio_quirk_write_cccr(struct sdio_func *func) * * Return: none. */ -int hif_sdio_quirk_mod_strength(struct sdio_func *func) +int hif_sdio_quirk_mod_strength(struct hif_softc *ol_sc, struct sdio_func *func) { int ret = 0; uint32_t addr, value; - struct hif_sdio_dev *device = sdio_get_drvdata(func); + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); uint16_t manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; if (!modstrength) /* TODO: Dont set this : scn is not popolated yet */ @@ -287,82 +382,6 @@ int hif_sdio_quirk_mod_strength(struct sdio_func *func) return ret; } -/** - * hif_sdio_quirk_async_intr() - Set asynchronous interrupt settings - * @func: pointer to sdio_func - * - * The values are taken from the module parameter asyncintdelay - * Call this with the sdhci host claimed - * - * Return: none. - */ -int hif_sdio_quirk_async_intr(struct sdio_func *func) -{ - uint8_t data; - uint16_t manfid; - int set_async_irq = 0, ret = 0; - struct hif_sdio_dev *device = sdio_get_drvdata(func); - - manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; - - switch (manfid) { - case MANUFACTURER_ID_AR6003_BASE: - set_async_irq = 1; - ret = - func0_cmd52_write_byte(func->card, - CCCR_SDIO_IRQ_MODE_REG_AR6003, - SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003); - if (ret) - return ret; - break; - case MANUFACTURER_ID_AR6320_BASE: - case MANUFACTURER_ID_QCA9377_BASE: - case MANUFACTURER_ID_QCA9379_BASE: - set_async_irq = 1; - ret = func0_cmd52_read_byte(func->card, - CCCR_SDIO_IRQ_MODE_REG_AR6320, - &data); - if (ret) - return ret; - - data |= SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320; - ret = func0_cmd52_write_byte(func->card, - CCCR_SDIO_IRQ_MODE_REG_AR6320, - data); - if (ret) - return ret; - break; - case MANUFACTURER_ID_QCN7605_BASE: - /* No async intr delay settings */ - asyncintdelay = 0; - return ret; - } - - if (asyncintdelay) { - /* Set CCCR 0xF0[7:6] to increase async interrupt delay clock - * to fix interrupt missing issue on dell 8460p - */ - - ret = func0_cmd52_read_byte(func->card, - CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, - &data); - if (ret) - return ret; - - data = (data & ~CCCR_SDIO_ASYNC_INT_DELAY_MASK) | - ((asyncintdelay << CCCR_SDIO_ASYNC_INT_DELAY_LSB) & - CCCR_SDIO_ASYNC_INT_DELAY_MASK); - - ret = func0_cmd52_write_byte(func->card, - CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, - data); - if (ret) - return ret; - } - - return ret; -} - #if KERNEL_VERSION(3, 4, 0) <= LINUX_VERSION_CODE #ifdef SDIO_BUS_WIDTH_8BIT static int hif_cmd52_write_byte_8bit(struct sdio_func *func) @@ -381,14 +400,15 @@ static int hif_cmd52_write_byte_8bit(struct sdio_func *func) /** * hif_sdio_set_bus_speed() - Set the sdio bus speed + * @ol_sc: softc instance * @func: pointer to sdio_func * * Return: 0 on success, error number otherwise. */ -int hif_sdio_set_bus_speed(struct sdio_func *func) +int hif_sdio_set_bus_speed(struct hif_softc *ol_sc, struct sdio_func *func) { uint32_t clock, clock_set = 12500000; - struct hif_sdio_dev *device = get_hif_device(func); + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); uint16_t manfid; manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; @@ -427,16 +447,17 @@ int hif_sdio_set_bus_speed(struct sdio_func *func) /** * hif_set_bus_width() - Set the sdio bus width + * @ol_sc: softc instance * @func: pointer to sdio_func * * Return: 0 on success, error number otherwise. */ -int hif_sdio_set_bus_width(struct sdio_func *func) +int hif_sdio_set_bus_width(struct hif_softc *ol_sc, struct sdio_func *func) { int ret = 0; uint16_t manfid; uint8_t data = 0; - struct hif_sdio_dev *device = get_hif_device(func); + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; @@ -491,66 +512,6 @@ int hif_sdio_set_bus_width(struct sdio_func *func) return ret; } -/** - * hif_sdio_func_enable() - Handle device enabling as per device - * @device: HIF device object - * @func: function pointer - * - * Return success or failure - */ -int hif_sdio_func_enable(struct hif_sdio_dev *device, - struct sdio_func *func) -{ - uint16_t manfid; - - manfid = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; - - if (manfid == MANUFACTURER_ID_QCN7605_BASE) - return 0; - - if (device->is_disabled) { - int ret = 0; - - sdio_claim_host(func); - - ret = hif_sdio_quirk_async_intr(func); - if (ret) { - HIF_ERROR("%s: Error setting async intr:%d", - __func__, ret); - sdio_release_host(func); - return QDF_STATUS_E_FAILURE; - } - - func->enable_timeout = 100; - ret = sdio_enable_func(func); - if (ret) { - HIF_ERROR("%s: Unable to enable function: %d", - __func__, ret); - sdio_release_host(func); - return QDF_STATUS_E_FAILURE; - } - - ret = sdio_set_block_size(func, HIF_BLOCK_SIZE); - if (ret) { - HIF_ERROR("%s: Unable to set block size 0x%X : %d\n", - __func__, HIF_BLOCK_SIZE, ret); - sdio_release_host(func); - return QDF_STATUS_E_FAILURE; - } - - ret = hif_sdio_quirk_mod_strength(func); - if (ret) { - HIF_ERROR("%s: Error setting mod strength : %d\n", - __func__, ret); - sdio_release_host(func); - return QDF_STATUS_E_FAILURE; - } - - sdio_release_host(func); - } - - return 0; -} /** * hif_mask_interrupt() - Disable hif device irq @@ -594,11 +555,7 @@ void hif_mask_interrupt(struct hif_sdio_dev *device) */ static void hif_irq_handler(struct sdio_func *func) { - struct hif_sdio_dev *device; - - HIF_ENTER(); - - device = get_hif_device(func); + struct hif_sdio_dev *device = get_hif_device(NULL, func); atomic_set(&device->irq_handling, 1); /* release the host during intr so we can use * it when we process cmds @@ -607,8 +564,6 @@ static void hif_irq_handler(struct sdio_func *func) device->htc_callbacks.dsr_handler(device->htc_callbacks.context); sdio_claim_host(device->func); atomic_set(&device->irq_handling, 0); - - HIF_EXIT(); } /** diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/hif.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/hif.c index 926067c3ca27deb7ce1a6af3add0d91067b7c7af..7100baf1d616e981760ec4352f21f586195d91db 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/hif.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/native_sdio/src/hif.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -38,26 +37,10 @@ #include "hif_internal.h" #include -/* by default setup a bounce buffer for the data packets, - * if the underlying host controller driver - * does not use DMA you may be able to skip this step - * and save the memory allocation and transfer time - */ #define HIF_USE_DMA_BOUNCE_BUFFER 1 #define ATH_MODULE_NAME hif #include "a_debug.h" -#if HIF_USE_DMA_BOUNCE_BUFFER -/* macro to check if DMA buffer is WORD-aligned and DMA-able. - * Most host controllers assume the - * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack). - * virt_addr_valid check fails on stack memory. - */ -#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || \ - !virt_addr_valid((buffer))) -#else -#define BUFFER_NEEDS_BOUNCE(buffer) (false) -#endif #define MAX_HIF_DEVICES 2 #ifdef HIF_MBOX_SLEEP_WAR #define HIF_MIN_SLEEP_INACTIVITY_TIME_MS 50 @@ -83,7 +66,8 @@ MODULE_PARM_DESC(debugcccr, "Output this cccr values"); #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) -static struct hif_sdio_dev *add_hif_device(struct sdio_func *func); +static struct hif_sdio_dev *add_hif_device(struct hif_softc *hif_ctx, + struct sdio_func *func); static void del_hif_device(struct hif_sdio_dev *device); int reset_sdio_on_unload; @@ -171,186 +155,6 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, ATH_DEBUG_MASK_DEFAULTS, 0, NULL); #endif -/** - * __hif_read_write() - sdio read/write wrapper - * @device: pointer to hif device structure - * @address: address to read - * @buffer: buffer to hold read/write data - * @length: length to read/write - * @request: read/write/sync/async request - * @context: pointer to hold calling context - * - * Return: 0 on success, error number otherwise. - */ -static QDF_STATUS -__hif_read_write(struct hif_sdio_dev *device, - uint32_t address, char *buffer, - uint32_t length, uint32_t request, void *context) -{ - uint8_t opcode; - QDF_STATUS status = QDF_STATUS_SUCCESS; - int ret = A_OK; - uint8_t *tbuffer; - bool bounced = false; - - if (!device) { - HIF_ERROR("%s: device null!", __func__); - return QDF_STATUS_E_INVAL; - } - - if (!device->func) { - HIF_ERROR("%s: func null!", __func__); - return QDF_STATUS_E_INVAL; - } - - HIF_INFO_HI("%s: addr:0X%06X, len:%08d, %s, %s", __func__, - address, length, - request & HIF_SDIO_READ ? "Read " : "Write", - request & HIF_ASYNCHRONOUS ? "Async" : "Sync "); - - do { - if (request & HIF_EXTENDED_IO) { - HIF_INFO_HI("%s: Command type: CMD53\n", __func__); - } else { - HIF_ERROR("%s: Invalid command type: 0x%08x\n", - __func__, request); - status = QDF_STATUS_E_INVAL; - break; - } - - if (request & HIF_BLOCK_BASIS) { - /* round to whole block length size */ - length = - (length / HIF_BLOCK_SIZE) * - HIF_BLOCK_SIZE; - HIF_INFO_HI("%s: Block mode (BlockLen: %d)\n", - __func__, length); - } else if (request & HIF_BYTE_BASIS) { - HIF_INFO_HI("%s: Byte mode (BlockLen: %d)\n", - __func__, length); - } else { - HIF_ERROR("%s: Invalid data mode: 0x%08x\n", - __func__, request); - status = QDF_STATUS_E_INVAL; - break; - } - if (request & HIF_SDIO_WRITE) { - hif_fixup_write_param(device, request, - &length, &address); - - HIF_INFO_HI("addr:%08X, len:0x%08X, dummy:0x%04X\n", - address, length, - (request & HIF_DUMMY_SPACE_MASK) >> 16); - } - - if (request & HIF_FIXED_ADDRESS) { - opcode = CMD53_FIXED_ADDRESS; - HIF_INFO_HI("%s: Addr mode: fixed 0x%X\n", - __func__, address); - } else if (request & HIF_INCREMENTAL_ADDRESS) { - opcode = CMD53_INCR_ADDRESS; - HIF_INFO_HI("%s: Address mode: Incremental 0x%X\n", - __func__, address); - } else { - HIF_ERROR("%s: Invalid address mode: 0x%08x\n", - __func__, request); - status = QDF_STATUS_E_INVAL; - break; - } - - if (request & HIF_SDIO_WRITE) { -#if HIF_USE_DMA_BOUNCE_BUFFER - if (BUFFER_NEEDS_BOUNCE(buffer)) { - AR_DEBUG_ASSERT(device->dma_buffer); - tbuffer = device->dma_buffer; - /* copy the write data to the dma buffer */ - AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); - if (length > HIF_DMA_BUFFER_SIZE) { - HIF_ERROR("%s: Invalid write len: %d\n", - __func__, length); - status = QDF_STATUS_E_INVAL; - break; - } - memcpy(tbuffer, buffer, length); - bounced = true; - } else { - tbuffer = buffer; - } -#else - tbuffer = buffer; -#endif - if (opcode == CMD53_FIXED_ADDRESS && tbuffer) { - ret = sdio_writesb(device->func, address, - tbuffer, length); - HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer); - } else if (tbuffer) { - ret = sdio_memcpy_toio(device->func, address, - tbuffer, length); - HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer); - } - } else if (request & HIF_SDIO_READ) { -#if HIF_USE_DMA_BOUNCE_BUFFER - if (BUFFER_NEEDS_BOUNCE(buffer)) { - AR_DEBUG_ASSERT(device->dma_buffer); - AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); - if (length > HIF_DMA_BUFFER_SIZE) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid read length: %d\n", - __func__, length)); - status = QDF_STATUS_E_INVAL; - break; - } - tbuffer = device->dma_buffer; - bounced = true; - } else { - tbuffer = buffer; - } -#else - tbuffer = buffer; -#endif - if (opcode == CMD53_FIXED_ADDRESS && tbuffer) { - ret = sdio_readsb(device->func, tbuffer, - address, length); - HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer); - } else if (tbuffer) { - ret = sdio_memcpy_fromio(device->func, - tbuffer, address, - length); - HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer); - } -#if HIF_USE_DMA_BOUNCE_BUFFER - if (bounced && tbuffer) - memcpy(buffer, tbuffer, length); -#endif - } else { - HIF_ERROR("%s: Invalid dir: 0x%08x", __func__, request); - status = QDF_STATUS_E_INVAL; - return status; - } - - if (ret) { - HIF_ERROR("%s: SDIO bus operation failed!", __func__); - HIF_ERROR("%s: MMC stack returned : %d", __func__, ret); - HIF_ERROR("%s: addr:0X%06X, len:%08d, %s, %s", - __func__, address, length, - request & HIF_SDIO_READ ? "Read " : "Write", - request & HIF_ASYNCHRONOUS ? - "Async" : "Sync"); - status = QDF_STATUS_E_FAILURE; - } - } while (false); - - return status; -} - /** * add_to_async_list() - add bus reqest to async task list * @device: pointer to hif device @@ -380,222 +184,6 @@ void add_to_async_list(struct hif_sdio_dev *device, qdf_spin_unlock_irqrestore(&device->asynclock); } -/** - * hif_read_write() - queue a read/write request - * @device: pointer to hif device structure - * @address: address to read - * @buffer: buffer to hold read/write data - * @length: length to read/write - * @request: read/write/sync/async request - * @context: pointer to hold calling context - * - * Return: 0 on success, error number otherwise. - */ -QDF_STATUS -hif_read_write(struct hif_sdio_dev *device, - uint32_t address, - char *buffer, uint32_t length, - uint32_t request, void *context) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct bus_request *busrequest; - - AR_DEBUG_ASSERT(device); - AR_DEBUG_ASSERT(device->func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: device 0x%pK addr 0x%X buffer 0x%pK len %d req 0x%X context 0x%pK", - __func__, device, address, buffer, - length, request, context)); - - /*sdio r/w action is not needed when suspend, so just return */ - if ((device->is_suspend == true) - && (device->power_config == HIF_DEVICE_POWER_CUT)) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("skip io when suspending\n")); - return QDF_STATUS_SUCCESS; - } - do { - if ((request & HIF_ASYNCHRONOUS) || - (request & HIF_SYNCHRONOUS)) { - /* serialize all requests through the async thread */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Execution mode: %s\n", __func__, - (request & HIF_ASYNCHRONOUS) ? "Async" - : "Synch")); - busrequest = hif_allocate_bus_request(device); - if (!busrequest) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("no async bus requests available (%s, addr:0x%X, len:%d)\n", - request & HIF_SDIO_READ ? "READ" : - "WRITE", address, length)); - return QDF_STATUS_E_FAILURE; - } - busrequest->address = address; - busrequest->buffer = buffer; - busrequest->length = length; - busrequest->request = request; - busrequest->context = context; - - add_to_async_list(device, busrequest); - - if (request & HIF_SYNCHRONOUS) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: queued sync req: 0x%lX\n", - __func__, (unsigned long)busrequest)); - - /* wait for completion */ - up(&device->sem_async); - if (down_interruptible(&busrequest->sem_req) != - 0) { - /* interrupted, exit */ - return QDF_STATUS_E_FAILURE; - } else { - QDF_STATUS status = busrequest->status; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: sync return freeing 0x%lX: 0x%X\n", - __func__, - (unsigned long) - busrequest, - busrequest->status)); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: freeing req: 0x%X\n", - __func__, - (unsigned int) - request)); - hif_free_bus_request(device, - busrequest); - return status; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: queued async req: 0x%lX\n", - __func__, - (unsigned long)busrequest)); - up(&device->sem_async); - return QDF_STATUS_E_PENDING; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid execution mode: 0x%08x\n", - __func__, - (unsigned int)request)); - status = QDF_STATUS_E_INVAL; - break; - } - } while (0); - - return status; -} - -/** - * async_task() - thread function to serialize all bus requests - * @param: pointer to hif device - * - * thread function to serialize all requests, both sync and async - * Return: 0 on success, error number otherwise. - */ -static int async_task(void *param) -{ - struct hif_sdio_dev *device; - struct bus_request *request; - QDF_STATUS status; - bool claimed = false; - - device = (struct hif_sdio_dev *) param; - set_current_state(TASK_INTERRUPTIBLE); - while (!device->async_shutdown) { - /* wait for work */ - if (down_interruptible(&device->sem_async) != 0) { - /* interrupted, exit */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: async task interrupted\n", - __func__)); - break; - } - if (device->async_shutdown) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: async task stopping\n", - __func__)); - break; - } - /* we want to hold the host over multiple cmds - * if possible, but holding the host blocks - * card interrupts - */ - qdf_spin_lock_irqsave(&device->asynclock); - /* pull the request to work on */ - while (device->asyncreq) { - request = device->asyncreq; - if (request->inusenext) - device->asyncreq = request->inusenext; - else - device->asyncreq = NULL; - qdf_spin_unlock_irqrestore(&device->asynclock); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: async_task processing req: 0x%lX\n", - __func__, (unsigned long)request)); - - if (!claimed) { - sdio_claim_host(device->func); - claimed = true; - } - if (request->scatter_req) { - A_ASSERT(device->scatter_enabled); - /* pass the request to scatter routine which - * executes it synchronously, note, no need - * to free the request since scatter requests - * are maintained on a separate list - */ - status = do_hif_read_write_scatter(device, - request); - } else { - /* call hif_read_write in sync mode */ - status = - __hif_read_write(device, - request->address, - request->buffer, - request->length, - request-> - request & - ~HIF_SYNCHRONOUS, - NULL); - if (request->request & HIF_ASYNCHRONOUS) { - void *context = request->context; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: freeing req: 0x%lX\n", - __func__, (unsigned long) - request)); - hif_free_bus_request(device, request); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: async_task completion req 0x%lX\n", - __func__, (unsigned long) - request)); - device->htc_callbacks. - rw_compl_handler(context, status); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: async_task upping req: 0x%lX\n", - __func__, (unsigned long) - request)); - request->status = status; - up(&request->sem_req); - } - } - qdf_spin_lock_irqsave(&device->asynclock); - } - qdf_spin_unlock_irqrestore(&device->asynclock); - if (claimed) { - sdio_release_host(device->func); - claimed = false; - } - } - - complete_and_exit(&device->async_completion, 0); - - return 0; -} - /* * Setup IRQ mode for deep sleep and WoW * Switch back to 1 bits mode when we suspend for @@ -603,6 +191,7 @@ static int async_task(void *param) * Re-enable async 4-bit irq mode for some host controllers * after resume. */ +#ifdef CONFIG_SDIO_TRANSFER_MAILBOX static int sdio_enable4bits(struct hif_sdio_dev *device, int enable) { int ret = 0; @@ -675,34 +264,12 @@ static int sdio_enable4bits(struct hif_sdio_dev *device, int enable) return ret; } - -static QDF_STATUS hif_disable_func(struct hif_sdio_dev *device, - struct sdio_func *func, - bool reset) +#else +static int sdio_enable4bits(struct hif_sdio_dev *device, int enable) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - - HIF_ENTER(); - device = get_hif_device(func); - if (!IS_ERR(device->async_task)) { - init_completion(&device->async_completion); - device->async_shutdown = 1; - up(&device->sem_async); - wait_for_completion(&device->async_completion); - device->async_task = NULL; - sema_init(&device->sem_async, 0); - } - - status = hif_sdio_func_disable(device, func, reset); - if (status == QDF_STATUS_SUCCESS) - device->is_disabled = true; - - cleanup_hif_scatter_resources(device); - - HIF_EXIT(); - - return status; + return 0; } +#endif /** * hif_sdio_probe() - configure sdio device @@ -712,9 +279,9 @@ static QDF_STATUS hif_disable_func(struct hif_sdio_dev *device, * * Return: 0 for success and non-zero for failure */ -static A_STATUS hif_sdio_probe(struct hif_softc *ol_sc, - struct sdio_func *func, - struct hif_sdio_dev *device) +A_STATUS hif_sdio_probe(struct hif_softc *ol_sc, + struct sdio_func *func, + struct hif_sdio_dev *device) { int ret = 0; const struct sdio_device_id *id; @@ -794,7 +361,9 @@ static A_STATUS hif_sdio_probe(struct hif_softc *ol_sc, goto err_attach1; } - return 0; + ret = hif_dev_register_channels(device, func); + + return ret; err_attach1: if (scn->ramdump_base) @@ -803,48 +372,9 @@ static A_STATUS hif_sdio_probe(struct hif_softc *ol_sc, return ret; } -static QDF_STATUS hif_enable_func(struct hif_softc *ol_sc, - struct hif_sdio_dev *device, - struct sdio_func *func, - bool resume) -{ - int ret = QDF_STATUS_SUCCESS; - - HIF_ENTER(); - - if (!device) { - HIF_ERROR("%s: HIF device is NULL", __func__); - return QDF_STATUS_E_INVAL; - } - - if (hif_sdio_func_enable(device, func)) - return QDF_STATUS_E_FAILURE; - - /* create async I/O thread */ - if (!device->async_task && device->is_disabled) { - device->async_shutdown = 0; - device->async_task = kthread_create(async_task, - (void *)device, - "AR6K Async"); - if (IS_ERR(device->async_task)) { - HIF_ERROR("%s: Error creating async task", - __func__); - return QDF_STATUS_E_FAILURE; - } - device->is_disabled = false; - wake_up_process(device->async_task); - } - - if (resume == false) - ret = hif_sdio_probe(ol_sc, func, device); - - HIF_EXIT(); - - return ret; -} - /** * power_state_change_notify() - SDIO bus power notification handler + * @ol_sc: HIF device context * @config: hif device power change type * * Return: 0 on success, error number otherwise. @@ -910,6 +440,7 @@ power_state_change_notify(struct hif_softc *ol_sc, /** * hif_configure_device() - configure sdio device + * @ol_sc: HIF device context * @device: pointer to hif device structure * @opcode: configuration type * @config: configuration value to set @@ -1032,6 +563,7 @@ void hif_sdio_shutdown(struct hif_softc *hif_ctx) /** * hif_device_inserted() - hif-sdio driver probe handler + * @ol_sc: HIF device context * @func: pointer to sdio_func * @id: pointer to sdio_device_id * @@ -1057,10 +589,10 @@ static int hif_device_inserted(struct hif_softc *ol_sc, if (hifdevice && hifdevice->power_config == HIF_DEVICE_POWER_CUT && hifdevice->host == func->card->host) { - device = get_hif_device(func); + device = get_hif_device(ol_sc, func); hifdevice->func = func; hifdevice->power_config = HIF_DEVICE_POWER_UP; - hif_sdio_set_drvdata(func, hifdevice); + hif_sdio_set_drvdata(ol_sc, func, hifdevice); if (device->is_suspend) { HIF_INFO("%s: Resume from suspend", __func__); @@ -1072,9 +604,10 @@ static int hif_device_inserted(struct hif_softc *ol_sc, /* If device not found, then it is a new insertion, alloc and add it */ if (!device) { - if (add_hif_device(func) == NULL) + if (!add_hif_device(ol_sc, func)) return QDF_STATUS_E_FAILURE; - device = get_hif_device(func); + + device = get_hif_device(ol_sc, func); for (i = 0; i < MAX_HIF_DEVICES; ++i) { if (!hif_devices[i]) { @@ -1095,13 +628,13 @@ static int hif_device_inserted(struct hif_softc *ol_sc, */ sdio_claim_host(func); - hif_sdio_quirk_force_drive_strength(func); + hif_sdio_quirk_force_drive_strength(ol_sc, func); - hif_sdio_quirk_write_cccr(func); + hif_sdio_quirk_write_cccr(ol_sc, func); - ret = hif_sdio_set_bus_speed(func); + ret = hif_sdio_set_bus_speed(ol_sc, func); - ret = hif_sdio_set_bus_width(func); + ret = hif_sdio_set_bus_width(ol_sc, func); if (debugcccr) hif_dump_cccr(device); @@ -1174,11 +707,11 @@ void hif_ack_interrupt(struct hif_sdio_dev *device) * @pdev - HIF layer object * @func - SDIO bus function object * - * Return - NONE + * Return - error in case of failure to configure, else success */ -void hif_sdio_configure_pipes(struct hif_sdio_dev *dev, struct sdio_func *func) +int hif_sdio_configure_pipes(struct hif_sdio_dev *dev, struct sdio_func *func) { - /* ADMA-TODO */ + return hif_dev_configure_pipes(dev, func); } /** @@ -1233,7 +766,7 @@ void hif_free_bus_request(struct hif_sdio_dev *device, int hif_device_suspend(struct hif_softc *ol_sc, struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); - struct hif_sdio_dev *device = get_hif_device(func); + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); mmc_pm_flag_t pm_flag = 0; enum HIF_DEVICE_POWER_CHANGE_TYPE config; struct mmc_host *host = func->card->host; @@ -1314,7 +847,7 @@ int hif_device_resume(struct hif_softc *ol_sc, struct device *dev) enum HIF_DEVICE_POWER_CHANGE_TYPE config; struct hif_sdio_dev *device; - device = get_hif_device(func); + device = get_hif_device(ol_sc, func); if (!device) { HIF_ERROR("%s: hif object is null", __func__); return -EINVAL; @@ -1367,7 +900,8 @@ static A_STATUS hif_sdio_remove(void *context, void *hif_handle) return 0; } -static void hif_device_removed(struct sdio_func *func) + +static void hif_device_removed(struct hif_softc *ol_sc, struct sdio_func *func) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct hif_sdio_dev *device; @@ -1375,7 +909,7 @@ static void hif_device_removed(struct sdio_func *func) AR_DEBUG_ASSERT(func); HIF_ENTER(); - device = get_hif_device(func); + device = get_hif_device(ol_sc, func); if (device->power_config == HIF_DEVICE_POWER_CUT) { device->func = NULL; /* func will be free by mmc stack */ @@ -1406,7 +940,8 @@ static void hif_device_removed(struct sdio_func *func) HIF_EXIT(); } -static struct hif_sdio_dev *add_hif_device(struct sdio_func *func) +static struct hif_sdio_dev *add_hif_device(struct hif_softc *ol_sc, + struct sdio_func *func) { struct hif_sdio_dev *hifdevice = NULL; int ret = 0; @@ -1430,8 +965,8 @@ static struct hif_sdio_dev *add_hif_device(struct sdio_func *func) hifdevice->func = func; hifdevice->power_config = HIF_DEVICE_POWER_UP; hifdevice->device_state = HIF_DEVICE_STATE_ON; - ret = hif_sdio_set_drvdata(func, hifdevice); - hif_info("status %d", ret); + ret = hif_sdio_set_drvdata(ol_sc, func, hifdevice); + HIF_INFO("status %d", ret); return hifdevice; } @@ -1552,12 +1087,12 @@ int hif_sdio_device_inserted(struct hif_softc *ol_sc, HIF_ERROR("%s: Enter", __func__); status = hif_device_inserted(ol_sc, func, id); - HIF_ERROR("%s: Exit", __func__); + HIF_ERROR("%s: Exit: status:%d", __func__, status); return status; } -void hif_sdio_device_removed(struct sdio_func *func) +void hif_sdio_device_removed(struct hif_softc *ol_sc, struct sdio_func *func) { - hif_device_removed(func); + hif_device_removed(ol_sc, func); } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.c new file mode 100644 index 0000000000000000000000000000000000000000..bce8c52bdff4f18cda9bb7dff247b6f1acef07ce --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.c @@ -0,0 +1,862 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include "adma.h" +#include "hif_sdio_internal.h" +#include "pld_sdio.h" +#include "if_sdio.h" + +/** + * hif_dev_get_fifo_address() - get the fifo addresses for dma + * @pdev: SDIO HIF object + * @c : FIFO address config pointer + * + * Return : 0 for success, non-zero for error + */ +int hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, + void *c, + uint32_t config_len) +{ + /* SDIO AL handles DMA Addresses */ + return 0; +} + +/** + * hif_dev_get_block_size() - get the adma block size for dma + * @config : block size config pointer + * + * Return : NONE + */ +void hif_dev_get_block_size(void *config) +{ + /* TODO Get block size used by AL Layer in Mission ROM Mode */ + *((uint32_t *)config) = HIF_BLOCK_SIZE; /* QCN_SDIO_MROM_BLK_SZ TODO */ +} + +/** + * hif_dev_configure_pipes() - configure pipes + * @pdev: SDIO HIF object + * @func: sdio function object + * + * Return : 0 for success, non-zero for error + */ +int hif_dev_configure_pipes(struct hif_sdio_dev *pdev, struct sdio_func *func) +{ + /* SDIO AL Configures SDIO Channels */ + return 0; +} + +/** hif_dev_set_mailbox_swap() - Set the mailbox swap + * @pdev : The HIF layer object + * + * Return: none + */ +void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev) +{ + /* SDIO AL doesn't use mailbox architecture */ +} + +/** hif_dev_get_mailbox_swap() - Get the mailbox swap setting + * @pdev : The HIF layer object + * + * Return: true or false + */ +bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev) +{ + /* SDIO AL doesn't use mailbox architecture */ + return false; +} + +/** + * hif_dev_dsr_handler() - Synchronous interrupt handler + * + * @context: hif send context + * + * Return: 0 for success and non-zero for failure + */ +QDF_STATUS hif_dev_dsr_handler(void *context) +{ + /* SDIO AL handles interrupts */ + return QDF_STATUS_SUCCESS; +} + +/** + * hif_dev_map_service_to_pipe() - maps ul/dl pipe to service id. + * @pDev: SDIO HIF object + * @ServiceId: sevice index + * @ULPipe: uplink pipe id + * @DLPipe: down-linklink pipe id + * + * Return: 0 on success, error value on invalid map + */ +QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, uint16_t svc, + uint8_t *ul_pipe, uint8_t *dl_pipe) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + switch (svc) { + case HTT_DATA_MSG_SVC: + *dl_pipe = 2; + *ul_pipe = 3; + break; + + case HTC_CTRL_RSVD_SVC: + case HTC_RAW_STREAMS_SVC: + *dl_pipe = 0; + *ul_pipe = 1; + break; + + case WMI_DATA_BE_SVC: + case WMI_DATA_BK_SVC: + case WMI_DATA_VI_SVC: + case WMI_DATA_VO_SVC: + *dl_pipe = 2; + *ul_pipe = 3; + break; + + case WMI_CONTROL_SVC: + *dl_pipe = 0; + *ul_pipe = 1; + break; + + default: + HIF_ERROR("%s: Err : Invalid service (%d)", + __func__, svc); + status = QDF_STATUS_E_INVAL; + break; + } + return status; +} + +/** + * hif_bus_configure() - configure the bus + * @hif_sc: pointer to the hif context. + * + * return: 0 for success. nonzero for failure. + */ +int hif_sdio_bus_configure(struct hif_softc *hif_sc) +{ + struct pld_wlan_enable_cfg cfg; + enum pld_driver_mode mode; + uint32_t con_mode = hif_get_conparam(hif_sc); + + if (con_mode == QDF_GLOBAL_FTM_MODE) + mode = PLD_FTM; + else if (con_mode == QDF_GLOBAL_COLDBOOT_CALIB_MODE) + mode = PLD_COLDBOOT_CALIBRATION; + else if (QDF_IS_EPPING_ENABLED(con_mode)) + mode = PLD_EPPING; + else + mode = PLD_MISSION; + + return pld_wlan_enable(hif_sc->qdf_dev->dev, &cfg, mode); +} + +/** hif_dev_setup_device() - Setup device specific stuff here required for hif + * @pdev : HIF layer object + * + * return 0 on success, error otherwise + */ +int hif_dev_setup_device(struct hif_sdio_device *pdev) +{ + hif_dev_get_block_size(&pdev->BlockSize); + + return 0; +} + +/** hif_dev_mask_interrupts() - Disable the interrupts in the device + * @pdev SDIO HIF Object + * + * Return: NONE + */ +void hif_dev_mask_interrupts(struct hif_sdio_device *pdev) +{ + /* SDIO AL Handles Interrupts */ +} + +/** hif_dev_unmask_interrupts() - Enable the interrupts in the device + * @pdev SDIO HIF Object + * + * Return: NONE + */ +void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev) +{ + /* SDIO AL Handles Interrupts */ +} + +/** + * hif_dev_map_pipe_to_adma_chan() - maps pipe id to adma chan + * @pdev: The pointer to the hif device object + * @pipeid: pipe index + * + * Return: adma channel handle + */ +struct sdio_al_channel_handle *hif_dev_map_pipe_to_adma_chan +( +struct hif_sdio_device *dev, +uint8_t pipeid +) +{ + struct hif_sdio_dev *pdev = dev->HIFDevice; + + HIF_ENTER(); + + if ((pipeid == 0) || (pipeid == 1)) + return pdev->al_chan[0]; + else if ((pipeid == 2) || (pipeid == 3)) + return pdev->al_chan[1]; + else + return NULL; +} + +/** + * hif_dev_map_adma_chan_to_pipe() - map adma chan to htc pipe + * @pdev: The pointer to the hif device object + * @chan: channel number + * @upload: boolean to decide upload or download + * + * Return: Invalid pipe index + */ +uint8_t hif_dev_map_adma_chan_to_pipe(struct hif_sdio_device *pdev, + uint8_t chan, bool upload) +{ + HIF_INFO("%s: chan: %u, %s", __func__, chan, + upload ? "Upload" : "Download"); + + if (chan == 0) /* chan 0 is mapped to HTT */ + return upload ? 1 : 0; + else if (chan == 1) /* chan 1 is mapped to WMI */ + return upload ? 3 : 2; + + return (uint8_t)-1; /* invalid channel id */ +} + +/** + * hif_get_send_address() - Get the transfer pipe address + * @pdev: The pointer to the hif device object + * @pipe: The pipe identifier + * + * Return 0 for success and non-zero for failure to map + */ +int hif_get_send_address(struct hif_sdio_device *pdev, + uint8_t pipe, unsigned long *addr) +{ + struct sdio_al_channel_handle *chan = NULL; + + if (!addr) + return -EINVAL; + + *addr = 0; + chan = hif_dev_map_pipe_to_adma_chan(pdev, pipe); + + if (!chan) + return -EINVAL; + + *addr = (unsigned long)chan; + + return 0; +} + +/** + * hif_fixup_write_param() - Tweak the address and length parameters + * @pdev: The pointer to the hif device object + * @length: The length pointer + * @addr: The addr pointer + * + * Return: None + */ +void hif_fixup_write_param(struct hif_sdio_dev *pdev, uint32_t req, + uint32_t *length, uint32_t *addr) +{ + HIF_ENTER(); + HIF_EXIT(); +} + +#define HIF_MAX_RX_Q_ALLOC 0 /* TODO */ +#define HIF_RX_Q_ALLOC_THRESHOLD 100 +QDF_STATUS hif_disable_func(struct hif_sdio_dev *device, + struct sdio_func *func, + bool reset) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; +#if HIF_MAX_RX_Q_ALLOC + qdf_list_node_t *node; + struct rx_q_entry *rx_q_elem; +#endif + HIF_ENTER(); + +#if HIF_MAX_RX_Q_ALLOC + qdf_spin_lock_irqsave(&device->rx_q_lock); + + for (; device->rx_q.count; ) { + qdf_list_remove_back(&device->rx_q, &node); + rx_q_elem = container_of(node, struct rx_q_entry, entry); + if (rx_q_elem) { + if (rx_q_elem->nbuf) + qdf_nbuf_free(rx_q_elem->nbuf); + qdf_mem_free(rx_q_elem); + } + } + qdf_destroy_work(0, &device->rx_q_alloc_work); + + qdf_spin_unlock_irqrestore(&device->rx_q_lock); + + qdf_spinlock_destroy(&device->rx_q_lock); +#endif + + status = hif_sdio_func_disable(device, func, reset); + if (status == QDF_STATUS_SUCCESS) + device->is_disabled = true; + + cleanup_hif_scatter_resources(device); + + HIF_EXIT(); + + return status; +} + +/** + * hif_enable_func() - Enable SDIO function + * + * @ol_sc: HIF object pointer + * @device: HIF device pointer + * @sdio_func: SDIO function pointer + * @resume: If this is called from resume or probe + * + * Return: 0 in case of success, else error value + */ +QDF_STATUS hif_enable_func(struct hif_softc *ol_sc, struct hif_sdio_dev *device, + struct sdio_func *func, bool resume) +{ + int ret = QDF_STATUS_SUCCESS; + + if (!device) { + HIF_ERROR("%s: HIF device is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + + if (!resume) + ret = hif_sdio_probe(ol_sc, func, device); + +#if HIF_MAX_RX_Q_ALLOC + if (!ret) { + qdf_list_create(&device->rx_q, HIF_MAX_RX_Q_ALLOC); + qdf_spinlock_create(&device->rx_q_lock); + qdf_create_work(0, &device->rx_q_alloc_work, + hif_sdio_rx_q_alloc, (void *)device); + device->rx_q_alloc_work_scheduled = true; + qdf_sched_work(0, &device->rx_q_alloc_work); + } +#endif + return ret; +} + +/** + * hif_sdio_get_net_buf() - Get a network buffer from the rx q + * @dev - HIF device object + * + * Return - NULL if out of buffers, else qdf_nbuf_t + */ +#if HIF_MAX_RX_Q_ALLOC +static qdf_nbuf_t hif_sdio_get_nbuf(struct hif_sdio_dev *dev, uint16_t buf_len) +{ + qdf_list_node_t *node; + qdf_nbuf_t nbuf = NULL; + qdf_list_t *q = &dev->rx_q; + struct rx_q_entry *elem = NULL; + + /* TODO - Alloc nbuf based on buf_len */ + qdf_spin_lock_irqsave(&dev->rx_q_lock); + + if (q->count) { + qdf_list_remove_front(q, &node); + elem = qdf_container_of(node, struct rx_q_entry, entry); + nbuf = elem->nbuf; + } else { + HIF_ERROR("%s: no rx q elements", __func__); + } + + if (q->count <= HIF_RX_Q_ALLOC_THRESHOLD && + !dev->rx_q_alloc_work_scheduled) { + dev->rx_q_alloc_work_scheduled = true; + qdf_sched_work(0, &dev->rx_q_alloc_work); + } + + qdf_spin_unlock_irqrestore(&dev->rx_q_lock); + + qdf_mem_free(elem); + + return nbuf; +} +#else +static qdf_nbuf_t hif_sdio_get_nbuf(struct hif_sdio_dev *dev, uint16_t buf_len) +{ + qdf_nbuf_t nbuf; + + if (!buf_len) + buf_len = HIF_SDIO_RX_BUFFER_SIZE; + + nbuf = qdf_nbuf_alloc(NULL, buf_len, 0, 4, false); + + return nbuf; +} +#endif +/** + * hif_sdio_rx_q_alloc() - Deferred work for pre-alloc rx q + * @ctx - Pointer to context object + * + * Return NONE + */ +#if HIF_MAX_RX_Q_ALLOC +void hif_sdio_rx_q_alloc(void *ctx) +{ + struct rx_q_entry *rx_q_elem; + struct hif_sdio_dev *dev = (struct hif_sdio_dev *)ctx; + unsigned int rx_q_count = dev->rx_q.count; + + HIF_ENTER(); + qdf_spin_lock_irqsave(&dev->rx_q_lock); + + for (; rx_q_count < dev->rx_q.max_size; rx_q_count++) { + rx_q_elem = qdf_mem_malloc(sizeof(struct rx_q_entry)); + if (!rx_q_elem) { + HIF_ERROR("%s: failed to alloc rx q elem", __func__); + break; + } + + /* TODO - Alloc nbuf based on payload_len in HTC Header */ + rx_q_elem->nbuf = qdf_nbuf_alloc(NULL, HIF_SDIO_RX_BUFFER_SIZE, + 0, 4, false); + if (!rx_q_elem->nbuf) { + HIF_ERROR("%s: failed to alloc nbuf for rx", __func__); + qdf_mem_free(rx_q_elem); + break; + } + + qdf_list_insert_back(&dev->rx_q, &rx_q_elem->entry); + } + dev->rx_q_alloc_work_scheduled = false; + + qdf_spin_unlock_irqrestore(&dev->rx_q_lock); + HIF_EXIT(); +} +#else +void hif_sdio_rx_q_alloc(void *ctx) +{ +} +#endif + +#include + +struct sdio_al_channel_data qcn7605_chan[HIF_SDIO_MAX_AL_CHANNELS] = { + { + .name = "SDIO_AL_WLAN_CH0", /* HTT */ + .client_data = NULL, /* populate from client handle */ + .ul_xfer_cb = ul_xfer_cb, + .dl_xfer_cb = dl_xfer_cb, + .dl_data_avail_cb = dl_data_avail_cb, + .dl_meta_data_cb = NULL + }, + { + .name = "SDIO_AL_WLAN_CH1", /* WMI */ + .client_data = NULL, /* populate from client handle */ + .ul_xfer_cb = ul_xfer_cb, + .dl_xfer_cb = dl_xfer_cb, + .dl_data_avail_cb = dl_data_avail_cb, + .dl_meta_data_cb = NULL + } +}; + +/** + * hif_dev_register_channels()- Register transport layer channels + * @dev : HIF device object + * @func : SDIO function pointer + * + * Return : success on configuration, else failure + */ +int hif_dev_register_channels(struct hif_sdio_dev *dev, struct sdio_func *func) +{ + int ret = 0; + unsigned int chan; + struct sdio_al_channel_data *chan_data[HIF_ADMA_MAX_CHANS]; + + HIF_ENTER(); + + dev->al_client = pld_sdio_get_sdio_al_client_handle(func); + if (ret || !dev->al_client) { + HIF_ERROR("%s: Failed to get get sdio al handle", __func__); + return ret; + } + + if ((func->device & MANUFACTURER_ID_AR6K_BASE_MASK) == + MANUFACTURER_ID_QCN7605_BASE) { + dev->adma_chans_used = 2; + qcn7605_chan[0].client_data = dev->al_client->client_data; + qcn7605_chan[1].client_data = dev->al_client->client_data; + chan_data[0] = &qcn7605_chan[0]; + chan_data[1] = &qcn7605_chan[1]; + } else { + dev->adma_chans_used = 0; + } + + for (chan = 0; chan < dev->adma_chans_used; chan++) { + dev->al_chan[chan] = + pld_sdio_register_sdio_al_channel(dev->al_client, + chan_data[chan]); + if (!dev->al_chan[chan] || IS_ERR(dev->al_chan[chan])) { + ret = -EINVAL; + HIF_ERROR("%s: Channel registration failed", __func__); + } else { + dev->al_chan[chan]->priv = (void *)dev; + HIF_INFO("%s: chan %s : id : %u", __func__, + chan_data[chan]->name, + dev->al_chan[chan]->channel_id); + } + } + + HIF_EXIT(); + + return ret; +} + +/** + * hif_dev_unregister_channels()- Register transport layer channels + * @dev : HIF device object + * @func : SDIO Function pointer + * + * Return : None + */ +void hif_dev_unregister_channels(struct hif_sdio_dev *dev, + struct sdio_func *func) +{ + unsigned int chan; + + if (!dev) { + HIF_ERROR("%s: hif_sdio_dev is null", __func__); + return; + } + + for (chan = 0; chan < dev->adma_chans_used; chan++) { + dev->al_chan[chan]->priv = NULL; + pld_sdio_unregister_sdio_al_channel(dev->al_chan[chan]); + } +} + +/** + * hif_read_write() - queue a read/write request + * @dev: pointer to hif device structure + * @address: address to read, actually channel pointer + * @buffer: buffer to hold read/write data + * @length: length to read/write + * @request: read/write/sync/async request + * @context: pointer to hold calling context + * + * Return: 0, pending on success, error number otherwise. + */ +QDF_STATUS +hif_read_write(struct hif_sdio_dev *dev, + unsigned long sdio_al_ch_handle, + char *cbuffer, uint32_t length, + uint32_t request, void *context) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct sdio_al_channel_handle *ch; + struct bus_request *bus_req; + enum sdio_al_dma_direction dir; + struct hif_sdio_device *device; + QDF_STATUS (*rx_comp)(void *, qdf_nbuf_t, uint8_t); + qdf_nbuf_t nbuf; + int ret = 0, payload_len = 0; + unsigned char *buffer = (unsigned char *)cbuffer; + + if (!dev || !sdio_al_ch_handle) { + HIF_ERROR("%s: device = %pK, addr = %lu", __func__, + dev, sdio_al_ch_handle); + return QDF_STATUS_E_INVAL; + } + + if (!(request & HIF_ASYNCHRONOUS) && + !(request & HIF_SYNCHRONOUS)) { + HIF_ERROR("%s: Invalid request mode", __func__); + return QDF_STATUS_E_INVAL; + } + + /*sdio r/w action is not needed when suspend, so just return */ + if ((dev->is_suspend) && + (dev->power_config == HIF_DEVICE_POWER_CUT)) { + HIF_INFO("%s: skip in suspend", __func__); + return QDF_STATUS_SUCCESS; + } + + ch = (struct sdio_al_channel_handle *)sdio_al_ch_handle; + + bus_req = hif_allocate_bus_request(dev); + if (!bus_req) { + HIF_ERROR("%s: Bus alloc failed", __func__); + return QDF_STATUS_E_FAILURE; + } + + bus_req->address = sdio_al_ch_handle; + bus_req->length = length; + bus_req->request = request; + bus_req->context = context; + bus_req->buffer = buffer; + + /* Request SDIO AL to do transfer */ + dir = (request & HIF_SDIO_WRITE) ? SDIO_AL_TX : SDIO_AL_RX; + + if (request & HIF_SYNCHRONOUS) { + ret = sdio_al_queue_transfer(ch, + dir, + bus_req->buffer, + bus_req->length, + 1); /* higher priority */ + if (ret) { + status = QDF_STATUS_E_FAILURE; + HIF_ERROR("%s: SYNC REQ failed ret=%d", __func__, ret); + } else { + status = QDF_STATUS_SUCCESS; + } + + hif_free_bus_request(dev, bus_req); + + if ((status == QDF_STATUS_SUCCESS) && (dir == SDIO_AL_RX)) { + nbuf = (qdf_nbuf_t)context; + payload_len = HTC_GET_FIELD(bus_req->buffer, + HTC_FRAME_HDR, + PAYLOADLEN); + qdf_nbuf_set_pktlen(nbuf, payload_len + HTC_HDR_LENGTH); + device = (struct hif_sdio_device *)dev->htc_context; + rx_comp = device->hif_callbacks.rxCompletionHandler; + rx_comp(device->hif_callbacks.Context, nbuf, 0); + } + } else { + ret = sdio_al_queue_transfer_async(ch, + dir, + bus_req->buffer, + bus_req->length, + 1, /* higher priority */ + (void *)bus_req); + if (ret) { + status = QDF_STATUS_E_FAILURE; + HIF_ERROR("%s: ASYNC REQ fail ret=%d for len=%d ch=%d", + __func__, ret, length, ch->channel_id); + hif_free_bus_request(dev, bus_req); + } else { + status = QDF_STATUS_E_PENDING; + } + } + return status; +} + +/** + * ul_xfer_cb() - Completion call back for asynchronous transfer + * @ch_handle: The sdio al channel handle + * @result: The result of the operation + * @context: pointer to request context + * + * Return: None + */ +void ul_xfer_cb(struct sdio_al_channel_handle *ch_handle, + struct sdio_al_xfer_result *result, + void *ctx) +{ + struct bus_request *req = (struct bus_request *)ctx; + struct hif_sdio_dev *dev; + + if (!ch_handle || !result) { + HIF_ERROR("%s: Invalid args", __func__); + qdf_assert_always(0); + return; + } + + dev = (struct hif_sdio_dev *)ch_handle->priv; + + if (result->xfer_status) { + req->status = QDF_STATUS_E_FAILURE; + HIF_ERROR("%s: ASYNC Tx failed status=%d", __func__, + result->xfer_status); + } else { + req->status = QDF_STATUS_SUCCESS; + } + + dev->htc_callbacks.rw_compl_handler(req->context, req->status); + + hif_free_bus_request(dev, req); +} + +/** + * dl_data_avail_cb() - Called when data is available on a channel + * @ch_handle: The sdio al channel handle + * @len: The len of data available to download + * + * Return: None + */ +/* Use the asynchronous method of transfer. This will help in + * completing READ in the transfer done callback later which + * runs in sdio al thread context. If we do the syncronous + * transfer here, the thread context won't be available and + * perhaps a new thread may be required here. + */ +void dl_data_avail_cb(struct sdio_al_channel_handle *ch_handle, + unsigned int len) +{ + struct hif_sdio_dev *dev; + unsigned int chan; + qdf_nbuf_t nbuf; + + if (!ch_handle || !len) { + HIF_ERROR("%s: Invalid args %u", __func__, len); + qdf_assert_always(0); + return; + } + + dev = (struct hif_sdio_dev *)ch_handle->priv; + chan = ch_handle->channel_id; + + if (chan > HIF_SDIO_MAX_AL_CHANNELS) { + HIF_ERROR("%s: Invalid Ch ID %d", __func__, chan); + return; + } + + /* allocate a buffer for reading the data from the chip. + * Note that this is raw, unparsed buffer and will be + * processed in the transfer done callback. + */ + /* TODO, use global buffer instead of runtime allocations */ + nbuf = qdf_nbuf_alloc(NULL, len, 0, 4, false); + + if (!nbuf) { + HIF_ERROR("%s: Unable to alloc netbuf %u bytes", __func__, len); + return; + } + + hif_read_write(dev, (unsigned long)ch_handle, nbuf->data, len, + HIF_RD_ASYNC_BLOCK_FIX, nbuf); +} + +#define is_pad_block(buf) (*((uint32_t *)buf) == 0xbabababa) +uint16_t g_dbg_payload_len; + +/** + * dl_xfer_cb() - Call from lower layer after transfer is completed + * @ch_handle: The sdio al channel handle + * @result: The xfer result + * @ctx: Context passed in the transfer queuing + * + * Return: None + */ +void dl_xfer_cb(struct sdio_al_channel_handle *ch_handle, + struct sdio_al_xfer_result *result, + void *ctx) +{ + unsigned char *buf; + qdf_nbuf_t nbuf; + uint32_t len; + uint16_t payload_len = 0; + struct hif_sdio_dev *dev; + struct hif_sdio_device *device; + struct bus_request *bus_req = (struct bus_request *)ctx; + QDF_STATUS (*rx_completion)(void *, qdf_nbuf_t, uint8_t); + + if (!bus_req) { + HIF_ERROR("%s: Bus Req NULL!!!", __func__); + qdf_assert_always(0); + return; + } + + if (!ch_handle || !result) { + HIF_ERROR("%s: Invalid args %pK %pK", __func__, + ch_handle, result); + qdf_assert_always(0); + return; + } + + dev = (struct hif_sdio_dev *)ch_handle->priv; + if (result->xfer_status) { + HIF_ERROR("%s: ASYNC Rx failed %d", __func__, + result->xfer_status); + qdf_nbuf_free((qdf_nbuf_t)bus_req->context); + hif_free_bus_request(dev, bus_req); + return; + } + + device = (struct hif_sdio_device *)dev->htc_context; + rx_completion = device->hif_callbacks.rxCompletionHandler; + + buf = (unsigned char *)result->buf_addr; + len = (unsigned int)result->xfer_len; + + while (len >= sizeof(HTC_FRAME_HDR)) { + if (is_pad_block(buf)) { + /* End of Rx Buffer */ + break; + } + + if (HTC_GET_FIELD(buf, HTC_FRAME_HDR, ENDPOINTID) >= + ENDPOINT_MAX) { + HIF_ERROR("%s: invalid endpoint id: %u", __func__, + HTC_GET_FIELD(buf, HTC_FRAME_HDR, + ENDPOINTID)); + break; + } + + /* Copy the HTC frame to the alloc'd packet buffer */ + payload_len = HTC_GET_FIELD(buf, HTC_FRAME_HDR, PAYLOADLEN); + payload_len = qdf_le16_to_cpu(payload_len); + if (!payload_len) { + HIF_ERROR("%s:Invalid Payload len %d bytes", __func__, + payload_len); + break; + } + if (payload_len > g_dbg_payload_len) { + g_dbg_payload_len = payload_len; + HIF_ERROR("Max Rx HTC Payload = %d", g_dbg_payload_len); + } + + nbuf = hif_sdio_get_nbuf(dev, payload_len + HTC_HEADER_LEN); + if (!nbuf) { + HIF_ERROR("%s: failed to alloc rx buffer", __func__); + break; + } + + /* Check if payload fits in skb */ + if (qdf_nbuf_tailroom(nbuf) < payload_len + HTC_HEADER_LEN) { + HIF_ERROR("%s: Payload + HTC_HDR %d > skb tailroom %d", + __func__, (payload_len + 8), + qdf_nbuf_tailroom(nbuf)); + qdf_nbuf_free(nbuf); + break; + } + + qdf_mem_copy((uint8_t *)qdf_nbuf_data(nbuf), buf, + payload_len + HTC_HEADER_LEN); + + qdf_nbuf_put_tail(nbuf, payload_len + HTC_HDR_LENGTH); + + rx_completion(device->hif_callbacks.Context, nbuf, + 0); /* don't care, not used */ + + len -= payload_len + HTC_HDR_LENGTH; + buf += payload_len + HTC_HDR_LENGTH; + } + + qdf_nbuf_free((qdf_nbuf_t)bus_req->context); + hif_free_bus_request(dev, bus_req); +} diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.h new file mode 100644 index 0000000000000000000000000000000000000000..cfda66db25deb143a2bb73cb0738da06f8943010 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/adma.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * + * 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. + */ + +#ifndef _ADMA_H_ +#define _ADMA_H_ + +#include "hif_sdio_dev.h" +#include "htc_packet.h" +#include "htc_api.h" +#include "hif_internal.h" + +/* This should align with the underlying transport layer */ +#define HIF_DEFAULT_IO_BLOCK_SIZE 512 +#define HIF_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE +#define HIF_DUMMY_SPACE_MASK 0x0FFFFFFF + +#define HIF_SDIO_MAX_AL_CHANNELS 2 + +struct devRegisters { + uint32_t dummy; +}; + +#include "transfer.h" +#define DEV_REGISTERS_SIZE sizeof(struct devRegisters) + +uint8_t hif_dev_map_adma_chan_to_pipe(struct hif_sdio_device *pdev, + uint8_t chan, bool upload); + +struct sdio_al_channel_handle *hif_dev_map_pipe_to_adma_chan +( +struct hif_sdio_device *pdev, +uint8_t pipeid +); + +void dl_xfer_cb(struct sdio_al_channel_handle *ch_handle, + struct sdio_al_xfer_result *result, + void *ctx); +void ul_xfer_cb(struct sdio_al_channel_handle *ch_handle, + struct sdio_al_xfer_result *result, + void *ctx); + +void dl_data_avail_cb(struct sdio_al_channel_handle *ch_handle, + unsigned int len); + +void hif_sdio_rx_q_alloc(void *ctx); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.c index 84a0a690eeab42bd391c87b92153a9223b041484..91ad93f4cd1de610ae305433475c85c752503494 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.c @@ -1,7 +1,6 @@ /* * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * - * * 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 @@ -19,6 +18,7 @@ #ifdef CONFIG_SDIO_TRANSFER_MAILBOX #define ATH_MODULE_NAME hif +#include #include #include #include @@ -44,6 +44,24 @@ #include "regtable.h" #include "transfer.h" +/* by default setup a bounce buffer for the data packets, + * if the underlying host controller driver + * does not use DMA you may be able to skip this step + * and save the memory allocation and transfer time + */ +#define HIF_USE_DMA_BOUNCE_BUFFER 1 +#if HIF_USE_DMA_BOUNCE_BUFFER +/* macro to check if DMA buffer is WORD-aligned and DMA-able. + * Most host controllers assume the + * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack). + * virt_addr_valid check fails on stack memory. + */ +#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || \ + !virt_addr_valid((buffer))) +#else +#define BUFFER_NEEDS_BOUNCE(buffer) (false) +#endif + #ifdef SDIO_3_0 /** * set_extended_mbox_size() - set extended MBOX size @@ -170,6 +188,40 @@ static void set_extended_mbox_window_info(uint16_t manf_id, } } +/** hif_dev_set_mailbox_swap() - Set the mailbox swap from firmware + * @pdev : The HIF layer object + * + * Return: none + */ +void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev) +{ + struct hif_sdio_device *hif_device = hif_dev_from_hif(pdev); + + HIF_ENTER(); + + hif_device->swap_mailbox = true; + + HIF_EXIT(); +} + +/** hif_dev_get_mailbox_swap() - Get the mailbox swap setting + * @pdev : The HIF layer object + * + * Return: true or false + */ +bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev) +{ + struct hif_sdio_device *hif_device; + + HIF_ENTER(); + + hif_device = hif_dev_from_hif(pdev); + + HIF_EXIT(); + + return hif_device->swap_mailbox; +} + /** * hif_dev_get_fifo_address() - get the fifo addresses for dma * @pdev: SDIO HIF object @@ -177,22 +229,24 @@ static void set_extended_mbox_window_info(uint16_t manf_id, * * Return : 0 for success, non-zero for error */ -QDF_STATUS hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, - struct hif_device_mbox_info *config, - uint32_t config_len) +int hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, + void *config, + uint32_t config_len) { uint32_t count; + struct hif_device_mbox_info *cfg = + (struct hif_device_mbox_info *)config; for (count = 0; count < 4; count++) - config->mbox_addresses[count] = HIF_MBOX_START_ADDR(count); + cfg->mbox_addresses[count] = HIF_MBOX_START_ADDR(count); if (config_len >= sizeof(struct hif_device_mbox_info)) { set_extended_mbox_window_info((uint16_t)pdev->func->device, - config); - return QDF_STATUS_SUCCESS; + cfg); + return 0; } - return QDF_STATUS_E_INVAL; + return -EINVAL; } /** @@ -259,8 +313,8 @@ QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, uint16_t svc, break; default: - HIF_ERROR("%s: Err : Invalid service (%d)", - __func__, svc); + hif_err("%s: Err : Invalid service (%d)", + __func__, svc); status = QDF_STATUS_E_INVAL; break; } @@ -283,13 +337,13 @@ int hif_dev_setup_device(struct hif_sdio_device *pdev) sizeof(pdev->MailBoxInfo)); if (status != QDF_STATUS_SUCCESS) - HIF_ERROR("%s: HIF_DEVICE_GET_MBOX_ADDR failed", __func__); + hif_err("%s: HIF_DEVICE_GET_MBOX_ADDR failed", __func__); status = hif_configure_device(NULL, pdev->HIFDevice, HIF_DEVICE_GET_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); if (status != QDF_STATUS_SUCCESS) - HIF_ERROR("%s: HIF_DEVICE_GET_MBOX_BLOCK_SIZE fail", __func__); + hif_err("%s: HIF_DEVICE_GET_MBOX_BLOCK_SIZE fail", __func__); pdev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; @@ -322,7 +376,7 @@ void hif_dev_mask_interrupts(struct hif_sdio_device *pdev) HIF_WR_SYNC_BYTE_INC, NULL); if (status != QDF_STATUS_SUCCESS) - HIF_ERROR("%s: Err updating intr reg: %d", __func__, status); + hif_err("%s: Err updating intr reg: %d", __func__, status); } /** hif_dev_unmask_interrupts() - Enable the interrupts in the device @@ -378,7 +432,7 @@ void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev) NULL); if (status != QDF_STATUS_SUCCESS) - HIF_ERROR("%s: Err updating intr reg: %d", __func__, status); + hif_err("%s: Err updating intr reg: %d", __func__, status); } void hif_dev_dump_registers(struct hif_sdio_device *pdev, @@ -388,37 +442,38 @@ void hif_dev_dump_registers(struct hif_sdio_device *pdev, { int i = 0; - HIF_DBG("%s: Mailbox registers:", __func__); + hif_debug("%s: Mailbox registers:", __func__); if (irq_proc) { - HIF_DBG("HostIntStatus: 0x%x ", irq_proc->host_int_status); - HIF_DBG("CPUIntStatus: 0x%x ", irq_proc->cpu_int_status); - HIF_DBG("ErrorIntStatus: 0x%x ", irq_proc->error_int_status); - HIF_DBG("CounterIntStat: 0x%x ", irq_proc->counter_int_status); - HIF_DBG("MboxFrame: 0x%x ", irq_proc->mbox_frame); - HIF_DBG("RxLKAValid: 0x%x ", irq_proc->rx_lookahead_valid); - HIF_DBG("RxLKA0: 0x%x", irq_proc->rx_lookahead[0]); - HIF_DBG("RxLKA1: 0x%x ", irq_proc->rx_lookahead[1]); - HIF_DBG("RxLKA2: 0x%x ", irq_proc->rx_lookahead[2]); - HIF_DBG("RxLKA3: 0x%x", irq_proc->rx_lookahead[3]); + hif_debug("HostIntStatus: 0x%x ", irq_proc->host_int_status); + hif_debug("CPUIntStatus: 0x%x ", irq_proc->cpu_int_status); + hif_debug("ErrorIntStatus: 0x%x ", irq_proc->error_int_status); + hif_debug("CounterIntStat: 0x%x ", + irq_proc->counter_int_status); + hif_debug("MboxFrame: 0x%x ", irq_proc->mbox_frame); + hif_debug("RxLKAValid: 0x%x ", irq_proc->rx_lookahead_valid); + hif_debug("RxLKA0: 0x%x", irq_proc->rx_lookahead[0]); + hif_debug("RxLKA1: 0x%x ", irq_proc->rx_lookahead[1]); + hif_debug("RxLKA2: 0x%x ", irq_proc->rx_lookahead[2]); + hif_debug("RxLKA3: 0x%x", irq_proc->rx_lookahead[3]); if (pdev->MailBoxInfo.gmbox_address != 0) { - HIF_DBG("GMBOX-HostIntStatus2: 0x%x ", - irq_proc->host_int_status2); - HIF_DBG("GMBOX-RX-Avail: 0x%x ", - irq_proc->gmbox_rx_avail); + hif_debug("GMBOX-HostIntStatus2: 0x%x ", + irq_proc->host_int_status2); + hif_debug("GMBOX-RX-Avail: 0x%x ", + irq_proc->gmbox_rx_avail); } } if (irq_en) { - HIF_DBG("IntStatusEnable: 0x%x\n", - irq_en->int_status_enable); - HIF_DBG("CounterIntStatus: 0x%x\n", - irq_en->counter_int_status_enable); + hif_debug("IntStatusEnable: 0x%x\n", + irq_en->int_status_enable); + hif_debug("CounterIntStatus: 0x%x\n", + irq_en->counter_int_status_enable); } for (i = 0; mbox_regs && i < 4; i++) - HIF_DBG("Counter[%d]: 0x%x\n", i, mbox_regs->counter[i]); + hif_debug("Counter[%d]: 0x%x\n", i, mbox_regs->counter[i]); } /* under HL SDIO, with Interface Memory support, we have @@ -449,7 +504,7 @@ static uint8_t hif_dev_map_pipe_to_mail_box(struct hif_sdio_device *pdev, else if (0 == pipeid || 1 == pipeid) return 0; - HIF_ERROR("%s: pipeid=%d invalid", __func__, pipeid); + hif_err("%s: pipeid=%d invalid", __func__, pipeid); qdf_assert(0); @@ -472,8 +527,8 @@ static uint8_t hif_dev_map_mail_box_to_pipe(struct hif_sdio_device *pdev, else if (mbox_index == 1) return upload ? 3 : 2; - HIF_ERROR("%s: mbox_index=%d, upload=%d invalid", - __func__, mbox_index, upload); + hif_err("%s: mbox_index=%d, upload=%d invalid", + __func__, mbox_index, upload); qdf_assert(0); @@ -488,7 +543,7 @@ static uint8_t hif_dev_map_mail_box_to_pipe(struct hif_sdio_device *pdev, * Return 0 for success and non-zero for failure to map */ int hif_get_send_address(struct hif_sdio_device *pdev, - uint8_t pipe, uint32_t *addr) + uint8_t pipe, unsigned long *addr) { uint8_t mbox_index = INVALID_MAILBOX_NUMBER; @@ -535,14 +590,14 @@ void hif_fixup_write_param(struct hif_sdio_dev *pdev, uint32_t req, } else if (taddr == mboxinfo.mbox_prop[1].extended_address) { mboxlen = mboxinfo.mbox_prop[1].extended_size; } else { - HIF_ERROR("%s: Invalid write addr: 0x%08x\n", __func__, taddr); + hif_err("%s: Invalid write addr: 0x%08x\n", __func__, taddr); return; } if (mboxlen != 0) { if (*length > mboxlen) { - HIF_ERROR("%s: Error (%u > %u)", - __func__, *length, mboxlen); + hif_err("%s: Error (%u > %u)", + __func__, *length, mboxlen); return; } @@ -575,9 +630,9 @@ static QDF_STATUS hif_dev_recv_packet(struct hif_sdio_device *pdev, padded_length = DEV_CALC_RECV_PADDED_LEN(pdev, recv_length); if (padded_length > packet->BufferLength) { - HIF_ERROR("%s: No space for padlen:%d recvlen:%d bufferlen:%d", - __func__, padded_length, - recv_length, packet->BufferLength); + hif_err("%s: No space for padlen:%d recvlen:%d bufferlen:%d", + __func__, padded_length, + recv_length, packet->BufferLength); if (packet->Completion) { COMPLETE_HTC_PACKET(packet, QDF_STATUS_E_INVAL); return QDF_STATUS_SUCCESS; @@ -586,9 +641,9 @@ static QDF_STATUS hif_dev_recv_packet(struct hif_sdio_device *pdev, } /* mailbox index is saved in Endpoint member */ - HIF_INFO("%s : hdr:0x%x, len:%d, padded length: %d Mbox:0x%x", - __func__, packet->PktInfo.AsRx.ExpectedHdr, recv_length, - padded_length, mbox_index); + hif_debug("%s : hdr:0x%x, len:%d, padded length: %d Mbox:0x%x", + __func__, packet->PktInfo.AsRx.ExpectedHdr, recv_length, + padded_length, mbox_index); status = hif_read_write(pdev->HIFDevice, pdev->MailBoxInfo.mbox_addresses[mbox_index], @@ -597,18 +652,18 @@ static QDF_STATUS hif_dev_recv_packet(struct hif_sdio_device *pdev, req, sync ? NULL : packet); if (status != QDF_STATUS_SUCCESS && status != QDF_STATUS_E_PENDING) - HIF_ERROR("%s : Failed %d", __func__, status); + hif_err("%s : Failed %d", __func__, status); if (sync) { packet->Status = status; if (status == QDF_STATUS_SUCCESS) { HTC_FRAME_HDR *hdr = (HTC_FRAME_HDR *) packet->pBuffer; - HIF_INFO("%s: EP:%d,Len:%d,Flag:%d,CB:0x%02X,0x%02X\n", - __func__, - hdr->EndpointID, hdr->PayloadLen, - hdr->Flags, hdr->ControlBytes0, - hdr->ControlBytes1); + hif_debug("%s:EP:%d,Len:%d,Flg:%d,CB:0x%02X,0x%02X\n", + __func__, + hdr->EndpointID, hdr->PayloadLen, + hdr->Flags, hdr->ControlBytes0, + hdr->ControlBytes1); } } @@ -638,7 +693,7 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle if ((HTC_PACKET_QUEUE_DEPTH(recv_pkt_queue) - HTC_MAX_MSG_PER_BUNDLE_RX) > 0) { partial_bundle = true; - HIF_WARN("%s, partial bundle detected num: %d, %d\n", + hif_warn("%s, partial bundle detected num: %d, %d\n", __func__, HTC_PACKET_QUEUE_DEPTH(recv_pkt_queue), HTC_MAX_MSG_PER_BUNDLE_RX); @@ -648,7 +703,7 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle HTC_MAX_MSG_PER_BUNDLE_RX * target->TargetCreditSize; packet_rx_bundle = allocate_htc_bundle_packet(target); if (!packet_rx_bundle) { - HIF_ERROR("%s: packet_rx_bundle is NULL\n", __func__); + hif_err("%s: packet_rx_bundle is NULL\n", __func__); qdf_sleep(NBUF_ALLOC_FAIL_WAIT_TIME); /* 100 msec sleep */ return QDF_STATUS_E_NOMEM; } @@ -699,8 +754,8 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle HIF_RD_SYNC_BLOCK_FIX, NULL); if (status != QDF_STATUS_SUCCESS) { - HIF_ERROR("%s, hif_send Failed status:%d\n", - __func__, status); + hif_err("%s, hif_send Failed status:%d\n", + __func__, status); } else { unsigned char *buffer = bundle_buffer; *num_packets_fetched = i; @@ -745,7 +800,7 @@ QDF_STATUS hif_dev_recv_message_pending_handler(struct hif_sdio_device *pdev, HTC_PACKET_QUEUE recv_q, sync_comp_q; QDF_STATUS (*rxCompletion)(void *, qdf_nbuf_t, uint8_t); - HIF_INFO("%s: NumLookAheads: %d\n", __func__, num_look_aheads); + hif_debug("%s: NumLookAheads: %d\n", __func__, num_look_aheads); if (num_pkts_fetched) *num_pkts_fetched = 0; @@ -787,8 +842,8 @@ QDF_STATUS hif_dev_recv_message_pending_handler(struct hif_sdio_device *pdev, id = ((HTC_FRAME_HDR *)&look_aheads[0])->EndpointID; if (id >= ENDPOINT_MAX) { - HIF_ERROR("%s: Invalid Endpoint in lookahead: %d\n", - __func__, id); + hif_err("%s: Invalid Endpoint in lookahead: %d\n", + __func__, id); status = QDF_STATUS_E_PROTO; break; } @@ -974,7 +1029,7 @@ static QDF_STATUS hif_dev_service_cpu_interrupt(struct hif_sdio_device *pdev) cpu_int_status = mboxProcRegs(pdev).cpu_int_status & mboxEnaRegs(pdev).cpu_int_status_enable; - HIF_ERROR("%s: 0x%x", __func__, (uint32_t)cpu_int_status); + hif_err("%s: 0x%x", __func__, (uint32_t)cpu_int_status); /* Clear the interrupt */ mboxProcRegs(pdev).cpu_int_status &= ~cpu_int_status; @@ -1010,7 +1065,7 @@ static QDF_STATUS hif_dev_service_cpu_interrupt(struct hif_sdio_device *pdev) pdev->hif_callbacks.Context, QDF_STATUS_E_FAILURE); } else { - HIF_ERROR("%s: Unrecognized CPU event", __func__); + hif_err("%s: Unrecognized CPU event", __func__); } return status; @@ -1031,16 +1086,16 @@ static QDF_STATUS hif_dev_service_error_interrupt(struct hif_sdio_device *pdev) uint8_t error_int_status = 0; error_int_status = mboxProcRegs(pdev).error_int_status & 0x0F; - HIF_ERROR("%s: 0x%x", __func__, error_int_status); + hif_err("%s: 0x%x", __func__, error_int_status); if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) - HIF_ERROR("%s: Error : Wakeup", __func__); + hif_err("%s: Error : Wakeup", __func__); if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) - HIF_ERROR("%s: Error : Rx Underflow", __func__); + hif_err("%s: Error : Rx Underflow", __func__); if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) - HIF_ERROR("%s: Error : Tx Overflow", __func__); + hif_err("%s: Error : Tx Overflow", __func__); /* Clear the interrupt */ mboxProcRegs(pdev).error_int_status &= ~error_int_status; @@ -1080,7 +1135,7 @@ static QDF_STATUS hif_dev_service_debug_interrupt(struct hif_sdio_device *pdev) QDF_STATUS status; /* Send a target failure event to the application */ - HIF_ERROR("%s: Target debug interrupt", __func__); + hif_err("%s: Target debug interrupt", __func__); /* clear the interrupt , the debug error interrupt is counter 0 * read counter to clear interrupt @@ -1321,33 +1376,603 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev, return status; } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)) && \ - !defined(WITH_BACKPORTS) +#define DEV_CHECK_RECV_YIELD(pdev) \ + ((pdev)->CurrentDSRRecvCount >= \ + (pdev)->HifIRQYieldParams.recv_packet_yield_count) /** - * hif_sdio_set_drvdata() - set wlan driver data into upper layer private - * @func: pointer to sdio function - * @hifdevice: pointer to hif device + * hif_dev_dsr_handler() - Synchronous interrupt handler + * + * @context: hif send context * - * Return: non zero for success. + * Return: 0 for success and non-zero for failure */ -int hif_sdio_set_drvdata(struct sdio_func *func, - struct hif_sdio_dev *hifdevice) +QDF_STATUS hif_dev_dsr_handler(void *context) { - return sdio_set_drvdata(func, hifdevice); + struct hif_sdio_device *pdev = (struct hif_sdio_device *)context; + QDF_STATUS status = QDF_STATUS_SUCCESS; + bool done = false; + bool async_proc = false; + + /* reset the recv counter that tracks when we need + * to yield from the DSR + */ + pdev->CurrentDSRRecvCount = 0; + /* reset counter used to flag a re-scan of IRQ + * status registers on the target + */ + pdev->RecheckIRQStatusCnt = 0; + + while (!done) { + status = hif_dev_process_pending_irqs(pdev, &done, &async_proc); + if (QDF_IS_STATUS_ERROR(status)) + break; + + if (pdev->HifIRQProcessingMode == HIF_DEVICE_IRQ_SYNC_ONLY) { + /* the HIF layer does not allow async IRQ processing, + * override the asyncProc flag + */ + async_proc = false; + /* this will cause us to re-enter ProcessPendingIRQ() + * and re-read interrupt status registers. + * This has a nice side effect of blocking us until all + * async read requests are completed. This behavior is + * required as we do not allow ASYNC processing + * in interrupt handlers (like Windows CE) + */ + + if (pdev->DSRCanYield && DEV_CHECK_RECV_YIELD(pdev)) + /* ProcessPendingIRQs() pulled enough recv + * messages to satisfy the yield count, stop + * checking for more messages and return + */ + break; + } + + if (async_proc) { + /* the function does some async I/O for performance, + * we need to exit the ISR immediately, the check below + * will prevent the interrupt from being + * Ack'd while we handle it asynchronously + */ + break; + } + } + + if (QDF_IS_STATUS_SUCCESS(status) && !async_proc) { + /* Ack the interrupt only if : + * 1. we did not get any errors in processing interrupts + * 2. there are no outstanding async processing requests + */ + if (pdev->DSRCanYield) { + /* if the DSR can yield do not ACK the interrupt, there + * could be more pending messages. The HIF layer + * must ACK the interrupt on behalf of HTC + */ + hif_info("%s: Yield (RX count: %d)", + __func__, pdev->CurrentDSRRecvCount); + } else { + hif_ack_interrupt(pdev->HIFDevice); + } + } + + return status; +} + +/** + * hif_read_write() - queue a read/write request + * @device: pointer to hif device structure + * @address: address to read + * @buffer: buffer to hold read/write data + * @length: length to read/write + * @request: read/write/sync/async request + * @context: pointer to hold calling context + * + * Return: 0 on success, error number otherwise. + */ +QDF_STATUS +hif_read_write(struct hif_sdio_dev *device, + unsigned long address, + char *buffer, uint32_t length, + uint32_t request, void *context) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct bus_request *busrequest; + + AR_DEBUG_ASSERT(device); + AR_DEBUG_ASSERT(device->func); + hif_debug("%s: device 0x%pK addr 0x%lX buffer 0x%pK", + __func__, device, address, buffer); + hif_debug("%s: len %d req 0x%X context 0x%pK", + __func__, length, request, context); + + /*sdio r/w action is not needed when suspend, so just return */ + if ((device->is_suspend) && + (device->power_config == HIF_DEVICE_POWER_CUT)) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("skip io when suspending\n")); + return QDF_STATUS_SUCCESS; + } + do { + if ((request & HIF_ASYNCHRONOUS) || + (request & HIF_SYNCHRONOUS)) { + /* serialize all requests through the async thread */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("%s: Execution mode: %s\n", __func__, + (request & HIF_ASYNCHRONOUS) ? "Async" + : "Synch")); + busrequest = hif_allocate_bus_request(device); + if (!busrequest) { + hif_err("%s:bus requests unavail", __func__); + hif_err("%s, addr:0x%lX, len:%d", + request & HIF_SDIO_READ ? "READ" : + "WRITE", address, length); + return QDF_STATUS_E_FAILURE; + } + busrequest->address = address; + busrequest->buffer = buffer; + busrequest->length = length; + busrequest->request = request; + busrequest->context = context; + + add_to_async_list(device, busrequest); + + if (request & HIF_SYNCHRONOUS) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("%s: queued sync req: 0x%lX\n", + __func__, + (unsigned long)busrequest)); + + /* wait for completion */ + up(&device->sem_async); + if (down_interruptible(&busrequest->sem_req) == + 0) { + QDF_STATUS status = busrequest->status; + + hif_debug("%s: sync freeing 0x%lX:0x%X", + __func__, + (unsigned long)busrequest, + busrequest->status); + hif_debug("%s: freeing req: 0x%X", + __func__, + (unsigned int)request); + hif_free_bus_request(device, + busrequest); + return status; + } else { + /* interrupted, exit */ + return QDF_STATUS_E_FAILURE; + } + } else { + hif_debug("%s: queued async req: 0x%lX", + __func__, (unsigned long)busrequest); + up(&device->sem_async); + return QDF_STATUS_E_PENDING; + } + } else { + hif_err("%s: Invalid execution mode: 0x%08x", + __func__, (unsigned int)request); + status = QDF_STATUS_E_INVAL; + break; + } + } while (0); + + return status; +} + +/** + * hif_sdio_func_enable() - Handle device enabling as per device + * @device: HIF device object + * @func: function pointer + * + * Return success or failure + */ +static int hif_sdio_func_enable(struct hif_softc *ol_sc, + struct sdio_func *func) +{ + struct hif_sdio_dev *device = get_hif_device(ol_sc, func); + + if (device->is_disabled) { + int ret = 0; + + sdio_claim_host(func); + + ret = hif_sdio_quirk_async_intr(ol_sc, func); + if (ret) { + hif_err("%s: Error setting async intr:%d", + __func__, ret); + sdio_release_host(func); + return QDF_STATUS_E_FAILURE; + } + + func->enable_timeout = 100; + ret = sdio_enable_func(func); + if (ret) { + hif_err("%s: Unable to enable function: %d", + __func__, ret); + sdio_release_host(func); + return QDF_STATUS_E_FAILURE; + } + + ret = sdio_set_block_size(func, HIF_BLOCK_SIZE); + if (ret) { + hif_err("%s: Unable to set block size 0x%X : %d\n", + __func__, HIF_BLOCK_SIZE, ret); + sdio_release_host(func); + return QDF_STATUS_E_FAILURE; + } + + ret = hif_sdio_quirk_mod_strength(ol_sc, func); + if (ret) { + hif_err("%s: Error setting mod strength : %d\n", + __func__, ret); + sdio_release_host(func); + return QDF_STATUS_E_FAILURE; + } + + sdio_release_host(func); + } + + return 0; } + +/** + * __hif_read_write() - sdio read/write wrapper + * @device: pointer to hif device structure + * @address: address to read + * @buffer: buffer to hold read/write data + * @length: length to read/write + * @request: read/write/sync/async request + * @context: pointer to hold calling context + * + * Return: 0 on success, error number otherwise. + */ +static QDF_STATUS +__hif_read_write(struct hif_sdio_dev *device, + uint32_t address, char *buffer, + uint32_t length, uint32_t request, void *context) +{ + uint8_t opcode; + QDF_STATUS status = QDF_STATUS_SUCCESS; + int ret = A_OK; + uint8_t *tbuffer; + bool bounced = false; + + if (!device) { + hif_err("%s: device null!", __func__); + return QDF_STATUS_E_INVAL; + } + + if (!device->func) { + hif_err("%s: func null!", __func__); + return QDF_STATUS_E_INVAL; + } + + hif_debug("%s: addr:0X%06X, len:%08d, %s, %s", __func__, + address, length, + request & HIF_SDIO_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? "Async" : "Sync "); + + do { + if (request & HIF_EXTENDED_IO) { + //HIF_INFO_HI("%s: Command type: CMD53\n", __func__); + } else { + hif_err("%s: Invalid command type: 0x%08x\n", + __func__, request); + status = QDF_STATUS_E_INVAL; + break; + } + + if (request & HIF_BLOCK_BASIS) { + /* round to whole block length size */ + length = + (length / HIF_BLOCK_SIZE) * + HIF_BLOCK_SIZE; + hif_debug("%s: Block mode (BlockLen: %d)\n", + __func__, length); + } else if (request & HIF_BYTE_BASIS) { + hif_debug("%s: Byte mode (BlockLen: %d)\n", + __func__, length); + } else { + hif_err("%s: Invalid data mode: 0x%08x\n", + __func__, request); + status = QDF_STATUS_E_INVAL; + break; + } + if (request & HIF_SDIO_WRITE) { + hif_fixup_write_param(device, request, + &length, &address); + + hif_debug("addr:%08X, len:0x%08X, dummy:0x%04X\n", + address, length, + (request & HIF_DUMMY_SPACE_MASK) >> 16); + } + + if (request & HIF_FIXED_ADDRESS) { + opcode = CMD53_FIXED_ADDRESS; + hif_debug("%s: Addr mode: fixed 0x%X\n", + __func__, address); + } else if (request & HIF_INCREMENTAL_ADDRESS) { + opcode = CMD53_INCR_ADDRESS; + hif_debug("%s: Address mode: Incremental 0x%X\n", + __func__, address); + } else { + hif_err("%s: Invalid address mode: 0x%08x\n", + __func__, request); + status = QDF_STATUS_E_INVAL; + break; + } + + if (request & HIF_SDIO_WRITE) { +#if HIF_USE_DMA_BOUNCE_BUFFER + if (BUFFER_NEEDS_BOUNCE(buffer)) { + AR_DEBUG_ASSERT(device->dma_buffer); + tbuffer = device->dma_buffer; + /* copy the write data to the dma buffer */ + AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); + if (length > HIF_DMA_BUFFER_SIZE) { + hif_err("%s: Invalid write len: %d\n", + __func__, length); + status = QDF_STATUS_E_INVAL; + break; + } + memcpy(tbuffer, buffer, length); + bounced = true; + } else { + tbuffer = buffer; + } +#else + tbuffer = buffer; +#endif + if (opcode == CMD53_FIXED_ADDRESS && tbuffer) { + ret = sdio_writesb(device->func, address, + tbuffer, length); + hif_debug("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); + } else if (tbuffer) { + ret = sdio_memcpy_toio(device->func, address, + tbuffer, length); + hif_debug("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); + } + } else if (request & HIF_SDIO_READ) { +#if HIF_USE_DMA_BOUNCE_BUFFER + if (BUFFER_NEEDS_BOUNCE(buffer)) { + AR_DEBUG_ASSERT(device->dma_buffer); + AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); + if (length > HIF_DMA_BUFFER_SIZE) { + hif_err("%s: Invalid read len: %d\n", + __func__, length); + status = QDF_STATUS_E_INVAL; + break; + } + tbuffer = device->dma_buffer; + bounced = true; + } else { + tbuffer = buffer; + } #else -int hif_sdio_set_drvdata(struct sdio_func *func, - struct hif_sdio_dev *hifdevice) + tbuffer = buffer; +#endif + if (opcode == CMD53_FIXED_ADDRESS && tbuffer) { + ret = sdio_readsb(device->func, tbuffer, + address, length); + hif_debug("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); + } else if (tbuffer) { + ret = sdio_memcpy_fromio(device->func, + tbuffer, address, + length); + hif_debug("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); + } +#if HIF_USE_DMA_BOUNCE_BUFFER + if (bounced && tbuffer) + memcpy(buffer, tbuffer, length); +#endif + } else { + hif_err("%s: Invalid dir: 0x%08x", __func__, request); + status = QDF_STATUS_E_INVAL; + return status; + } + + if (ret) { + hif_err("%s: SDIO bus operation failed!", __func__); + hif_err("%s: MMC stack returned : %d", __func__, ret); + hif_err("%s: addr:0X%06X, len:%08d, %s, %s", + __func__, address, length, + request & HIF_SDIO_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? + "Async" : "Sync"); + status = QDF_STATUS_E_FAILURE; + } + } while (false); + + return status; +} + +/** + * async_task() - thread function to serialize all bus requests + * @param: pointer to hif device + * + * thread function to serialize all requests, both sync and async + * Return: 0 on success, error number otherwise. + */ +static int async_task(void *param) { - sdio_set_drvdata(func, hifdevice); + struct hif_sdio_dev *device; + struct bus_request *request; + QDF_STATUS status; + bool claimed = false; + + device = (struct hif_sdio_dev *)param; + set_current_state(TASK_INTERRUPTIBLE); + while (!device->async_shutdown) { + /* wait for work */ + if (down_interruptible(&device->sem_async) != 0) { + /* interrupted, exit */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("%s: async task interrupted\n", + __func__)); + break; + } + if (device->async_shutdown) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("%s: async task stopping\n", + __func__)); + break; + } + /* we want to hold the host over multiple cmds + * if possible, but holding the host blocks + * card interrupts + */ + qdf_spin_lock_irqsave(&device->asynclock); + /* pull the request to work on */ + while (device->asyncreq) { + request = device->asyncreq; + if (request->inusenext) + device->asyncreq = request->inusenext; + else + device->asyncreq = NULL; + qdf_spin_unlock_irqrestore(&device->asynclock); + hif_debug("%s: processing req: 0x%lX", + __func__, (unsigned long)request); + + if (!claimed) { + sdio_claim_host(device->func); + claimed = true; + } + if (request->scatter_req) { + A_ASSERT(device->scatter_enabled); + /* pass the request to scatter routine which + * executes it synchronously, note, no need + * to free the request since scatter requests + * are maintained on a separate list + */ + status = do_hif_read_write_scatter(device, + request); + } else { + /* call hif_read_write in sync mode */ + status = + __hif_read_write(device, + request->address, + request->buffer, + request->length, + request-> + request & + ~HIF_SYNCHRONOUS, + NULL); + if (request->request & HIF_ASYNCHRONOUS) { + void *context = request->context; + + hif_free_bus_request(device, request); + device->htc_callbacks. + rw_compl_handler(context, status); + } else { + hif_debug("%s: upping req: 0x%lX", + __func__, + (unsigned long)request); + request->status = status; + up(&request->sem_req); + } + } + qdf_spin_lock_irqsave(&device->asynclock); + } + qdf_spin_unlock_irqrestore(&device->asynclock); + if (claimed) { + sdio_release_host(device->func); + claimed = false; + } + } + + complete_and_exit(&device->async_completion, 0); + return 0; } -#endif /* LINUX VERSION */ -struct hif_sdio_dev *get_hif_device(struct sdio_func *func) +/** + * hif_disable_func() - Disable SDIO function + * + * @device: HIF device pointer + * @func: SDIO function pointer + * @reset: If this is called from resume or probe + * + * Return: 0 in case of success, else error value + */ +QDF_STATUS hif_disable_func(struct hif_sdio_dev *device, + struct sdio_func *func, + bool reset) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + HIF_ENTER(); + if (!IS_ERR(device->async_task)) { + init_completion(&device->async_completion); + device->async_shutdown = 1; + up(&device->sem_async); + wait_for_completion(&device->async_completion); + device->async_task = NULL; + sema_init(&device->sem_async, 0); + } + + status = hif_sdio_func_disable(device, func, reset); + if (status == QDF_STATUS_SUCCESS) + device->is_disabled = true; + + cleanup_hif_scatter_resources(device); + + HIF_EXIT(); + + return status; +} + +/** + * hif_enable_func() - Enable SDIO function + * + * @ol_sc: HIF object pointer + * @device: HIF device pointer + * @sdio_func: SDIO function pointer + * @resume: If this is called from resume or probe + * + * Return: 0 in case of success, else error value + */ +QDF_STATUS hif_enable_func(struct hif_softc *ol_sc, struct hif_sdio_dev *device, + struct sdio_func *func, bool resume) { - qdf_assert(func); + int ret = QDF_STATUS_SUCCESS; + + HIF_ENTER(); + + if (!device) { + hif_err("%s: HIF device is NULL", __func__); + return QDF_STATUS_E_INVAL; + } + + if (hif_sdio_func_enable(ol_sc, func)) + return QDF_STATUS_E_FAILURE; + + /* create async I/O thread */ + if (!device->async_task && device->is_disabled) { + device->async_shutdown = 0; + device->async_task = kthread_create(async_task, + (void *)device, + "AR6K Async"); + if (IS_ERR(device->async_task)) { + hif_err("%s: Error creating async task", + __func__); + return QDF_STATUS_E_FAILURE; + } + device->is_disabled = false; + wake_up_process(device->async_task); + } + + if (!resume) + ret = hif_sdio_probe(ol_sc, func, device); + + HIF_EXIT(); - return (struct hif_sdio_dev *)sdio_get_drvdata(func); + return ret; } #endif /* CONFIG_SDIO_TRANSFER_MAILBOX */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.h index 9123d872e76d74ffbb816da9917041d8ad6e7b94..3e5913215241fec47eda0b056a0960562efd20d0 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/mailbox.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. * * * @@ -146,11 +146,6 @@ */ #define HIF_DUMMY_SPACE_MASK 0xFFFF0000 -/* - * data written into the dummy space will not put into the final mbox FIFO - */ -#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 - PREPACK struct MBOX_IRQ_PROC_REGISTERS { uint8_t host_int_status; uint8_t cpu_int_status; @@ -190,4 +185,9 @@ struct devRegisters { #define DEV_REGISTERS_SIZE (sizeof(struct MBOX_IRQ_PROC_REGISTERS) + \ sizeof(struct MBOX_IRQ_ENABLE_REGISTERS) + \ sizeof(struct MBOX_COUNTER_REGISTERS)) + +void hif_dev_dump_registers(struct hif_sdio_device *pdev, + struct MBOX_IRQ_PROC_REGISTERS *irq_proc, + struct MBOX_IRQ_ENABLE_REGISTERS *irq_en, + struct MBOX_COUNTER_REGISTERS *mbox_regs); #endif /* _MAILBOX_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.c b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.c index 07ebf52b9509d6bade4f1c70e91578aa6d69e9b0..f75680ce06a8ddc5d852e39b539db5667dfe2f53 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.c @@ -91,12 +91,13 @@ QDF_STATUS hif_dev_send_buffer(struct hif_sdio_device *pdev, uint32_t xfer_id, unsigned char *pData; struct hif_sendContext *sctx; uint32_t request = hif_get_send_buffer_flags(pdev); - uint32_t padded_length, addr = 0; + uint32_t padded_length; + unsigned long addr = 0; int frag_count = 0, i, count, head_len; if (hif_get_send_address(pdev, pipe, &addr)) { - HIF_ERROR("%s: Invalid address map for pipe 0x%x", - __func__, pipe); + hif_err("%s: Invalid address map for pipe 0x%x", + __func__, pipe); return QDF_STATUS_E_INVAL; } @@ -216,17 +217,17 @@ QDF_STATUS hif_dev_alloc_and_prepare_rx_packets(struct hif_sdio_device *pdev, for (i = 0; i < messages; i++) { hdr = (HTC_FRAME_HDR *)&look_aheads[i]; if (hdr->EndpointID >= ENDPOINT_MAX) { - HIF_ERROR("%s: Invalid Endpoint:%d\n", - __func__, hdr->EndpointID); + hif_err("%s: Invalid Endpoint:%d\n", + __func__, hdr->EndpointID); status = QDF_STATUS_E_INVAL; break; } if (hdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) { - HIF_ERROR("%s: Payload length %d exceeds max HTC : %u", - __func__, - hdr->PayloadLen, - (uint32_t)HTC_MAX_PAYLOAD_LENGTH); + hif_err("%s: Payload length %d exceeds max HTC : %u", + __func__, + hdr->PayloadLen, + (uint32_t)HTC_MAX_PAYLOAD_LENGTH); status = QDF_STATUS_E_INVAL; break; } @@ -245,7 +246,7 @@ QDF_STATUS hif_dev_alloc_and_prepare_rx_packets(struct hif_sdio_device *pdev, */ num_messages++; - HIF_INFO("%s: HTC header : %u messages in bundle", + hif_info("%s: HTC header : %u messages in bundle", __func__, num_messages); } @@ -299,12 +300,12 @@ QDF_STATUS hif_dev_alloc_and_prepare_rx_packets(struct hif_sdio_device *pdev, /* make sure message can fit in the endpoint buffer */ if (full_length > packet->BufferLength) { - HIF_ERROR("%s: Payload Length Error", __func__); - HIF_ERROR("%s: header reports payload: %u(%u)", - __func__, hdr->PayloadLen, - full_length); - HIF_ERROR("%s: endpoint buffer size: %d\n", - __func__, packet->BufferLength); + hif_err("%s: Payload Length Error", __func__); + hif_err("%s: header reports payload: %u(%u)", + __func__, hdr->PayloadLen, + full_length); + hif_err("%s: endpoint buffer size: %d\n", + __func__, packet->BufferLength); status = QDF_STATUS_E_INVAL; break; } @@ -381,7 +382,7 @@ QDF_STATUS hif_dev_process_trailer(struct hif_sdio_device *pdev, HTC_RECORD_HDR *record; HTC_LOOKAHEAD_REPORT *look_ahead; - HIF_INFO("%s: length:%d", __func__, length); + hif_debug("%s: length:%d", __func__, length); orig_buffer = buffer; orig_length = length; @@ -399,11 +400,11 @@ QDF_STATUS hif_dev_process_trailer(struct hif_sdio_device *pdev, if (record->Length > length) { /* no room left in buffer for record */ - HIF_ERROR("%s: invalid record len: (%u, %u)", - __func__, record->Length, - record->RecordID); - HIF_ERROR("%s: buffer has %d bytes left", - __func__, length); + hif_err("%s: invalid record len: (%u, %u)", + __func__, record->Length, + record->RecordID); + hif_err("%s: buffer has %d bytes left", + __func__, length); status = QDF_STATUS_E_PROTO; break; } @@ -420,13 +421,13 @@ QDF_STATUS hif_dev_process_trailer(struct hif_sdio_device *pdev, if ((look_ahead->PreValid == ((~look_ahead->PostValid) & 0xFF)) && next_look_aheads) { - HIF_INFO_HI("%s: look_ahead Report", __func__); - HIF_INFO_HI("%s:prevalid:0x%x, postvalid:0x%x", - __func__, look_ahead->PreValid, - look_ahead->PostValid); - HIF_INFO_HI("%s:from endpoint %d : %u", - __func__, from_endpoint, - look_ahead->LookAhead0); + hif_debug("%s: look_ahead Report", __func__); + hif_debug("%s:prevalid:0x%x, postvalid:0x%x", + __func__, look_ahead->PreValid, + look_ahead->PostValid); + hif_debug("%s:from endpoint %d : %u", + __func__, from_endpoint, + look_ahead->LookAhead0); /* look ahead bytes are valid, copy them over */ ((uint8_t *)(&next_look_aheads[0]))[0] = look_ahead->LookAhead0; @@ -498,8 +499,8 @@ QDF_STATUS hif_dev_process_trailer(struct hif_sdio_device *pdev, } break; default: - HIF_ERROR("%s: HIF unhandled record: id:%u length:%u", - __func__, record->RecordID, record->Length); + hif_err("%s: HIF unhandled record: id:%u length:%u", + __func__, record->RecordID, record->Length); break; } @@ -515,7 +516,7 @@ QDF_STATUS hif_dev_process_trailer(struct hif_sdio_device *pdev, debug_dump_bytes(orig_buffer, orig_length, "BAD Recv Trailer"); - HIF_INFO("%s: status = %d", __func__, status); + hif_debug("%s: status = %d", __func__, status); return status; } @@ -572,10 +573,10 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev, /* validate the actual header that was refreshed */ if (packet->ActualLength > packet->BufferLength) { - HIF_ERROR("%s: Bundled RECV Look ahead: 0x%X", - __func__, look_ahead); - HIF_ERROR("%s: Invalid HDR payload length(%d)", - __func__, payloadLen); + hif_err("%s: Bundled RECV Look ahead: 0x%X", + __func__, look_ahead); + hif_err("%s: Invalid HDR payload length(%d)", + __func__, payloadLen); /* limit this to max buffer just to print out * some of the buffer */ @@ -588,12 +589,12 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev, if (packet->Endpoint != HTC_GET_FIELD(buf, HTC_FRAME_HDR, ENDPOINTID)) { - HIF_ERROR("%s: Refreshed HDR EP (%d)", - __func__, - HTC_GET_FIELD(buf, HTC_FRAME_HDR, - ENDPOINTID)); - HIF_ERROR("%s: doesn't match expected EP (%d)", - __func__, packet->Endpoint); + hif_err("%s: Refreshed HDR EP (%d)", + __func__, + HTC_GET_FIELD(buf, HTC_FRAME_HDR, + ENDPOINTID)); + hif_err("%s: doesn't match expected EP (%d)", + __func__, packet->Endpoint); status = QDF_STATUS_E_PROTO; break; } @@ -604,13 +605,13 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev, * length did not reflect the actual header * in the pending message */ - HIF_ERROR("%s: lookahead mismatch!", __func__); - HIF_ERROR("%s: pPkt:0x%lX flags:0x%X", - __func__, (unsigned long)packet, - packet->PktInfo.AsRx.HTCRxFlags); - HIF_ERROR("%s: look_ahead 0x%08X != 0x%08X", - __func__, look_ahead, - packet->PktInfo.AsRx.ExpectedHdr); + hif_err("%s: lookahead mismatch!", __func__); + hif_err("%s: pPkt:0x%lX flags:0x%X", + __func__, (unsigned long)packet, + packet->PktInfo.AsRx.HTCRxFlags); + hif_err("%s: look_ahead 0x%08X != 0x%08X", + __func__, look_ahead, + packet->PktInfo.AsRx.ExpectedHdr); #ifdef ATH_DEBUG_MODULE debug_dump_bytes((uint8_t *)&packet->PktInfo.AsRx. ExpectedHdr, 4, @@ -642,12 +643,12 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev, if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { - HIF_ERROR("%s: invalid header", - __func__); - HIF_ERROR("%s: payloadlength should be :%d", - __func__, payloadLen); - HIF_ERROR("%s: But control bytes is :%d)", - __func__, temp); + hif_err("%s: invalid header", + __func__); + hif_err("%s: payloadlength should be :%d", + __func__, payloadLen); + hif_err("%s: But control bytes is :%d)", + __func__, temp); status = QDF_STATUS_E_PROTO; break; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.h b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.h index 4a728385134a1abb8182eb77f10e02f48456a173..31950bfeb1a2158eb5fb133cf1d05b4315241308 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/sdio/transfer/transfer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * * @@ -65,13 +65,8 @@ struct hif_sendContext { unsigned int head_data_len; }; -void hif_dev_dump_registers(struct hif_sdio_device *pdev, - struct MBOX_IRQ_PROC_REGISTERS *irq_proc, - struct MBOX_IRQ_ENABLE_REGISTERS *irq_en, - struct MBOX_COUNTER_REGISTERS *mbox_regs); - int hif_get_send_address(struct hif_sdio_device *pdev, - uint8_t pipe, uint32_t *addr); + uint8_t pipe, unsigned long *addr); QDF_STATUS hif_dev_alloc_and_prepare_rx_packets(struct hif_sdio_device *pdev, uint32_t look_aheads[], @@ -103,8 +98,20 @@ static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev) return 0; } + +static inline int hif_sdio_bus_configure(struct hif_softc *hif_sc) +{ + return 0; +} + #elif defined(CONFIG_SDIO_TRANSFER_ADMA) -#error "Error - Not implemented yet" +static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev) +{ + /* ADAM-TODO */ + return (uint32_t)HIF_WR_ASYNC_BLOCK_FIX; +} + +int hif_sdio_bus_configure(struct hif_softc *hif_sc); #endif #endif /* __TRANSFER_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_ahb.c b/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_ahb.c index 1abc3ac733667ef7df5889ed8d4cf56ba24c2470..49672a5b8a9997fa35da169265a3507706c50b05 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_ahb.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_ahb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -233,14 +233,14 @@ int hif_ahb_configure_legacy_irq(struct hif_pci_softc *sc) qal_vbus_get_irq((struct qdf_pfm_hndl *)pdev, "legacy", &irq); if (irq < 0) { dev_err(&pdev->dev, "Unable to get irq\n"); - ret = -1; + ret = -EFAULT; goto end; } ret = request_irq(irq, hif_pci_legacy_ce_interrupt_handler, IRQF_DISABLED, "wlan_ahb", sc); if (ret) { dev_err(&pdev->dev, "ath_request_irq failed\n"); - ret = -1; + ret = -EFAULT; goto end; } sc->irq = irq; @@ -271,16 +271,24 @@ int hif_ahb_configure_irq(struct hif_pci_softc *sc) for (i = 0; i < scn->ce_count; i++) { if (host_ce_conf[i].flags & CE_ATTR_DISABLE_INTR) continue; - qal_vbus_get_irq((struct qdf_pfm_hndl *)pdev, - ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i], &irq); + ret = pfrm_get_irq(&pdev->dev, (struct qdf_pfm_hndl *)pdev, + ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i], + HIF_IC_CE0_IRQ_OFFSET + i, &irq); + if (ret) { + dev_err(&pdev->dev, "get irq failed\n"); + ret = -EFAULT; + goto end; + } + ic_irqnum[HIF_IC_CE0_IRQ_OFFSET + i] = irq; - ret = request_irq(irq , - hif_ahb_interrupt_handler, - IRQF_TRIGGER_RISING, ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i], - &hif_state->tasklets[i]); + ret = pfrm_request_irq(&pdev->dev, irq, + hif_ahb_interrupt_handler, + IRQF_TRIGGER_RISING, + ic_irqname[HIF_IC_CE0_IRQ_OFFSET + i], + &hif_state->tasklets[i]); if (ret) { dev_err(&pdev->dev, "ath_request_irq failed\n"); - ret = -1; + ret = -EFAULT; goto end; } hif_ahb_irq_enable(scn, i); @@ -305,25 +313,34 @@ int hif_ahb_configure_grp_irq(struct hif_softc *scn, hif_ext_group->irq_name = &hif_ahb_get_irq_name; hif_ext_group->work_complete = &hif_dummy_grp_done; + for (j = 0; j < hif_ext_group->numirq; j++) { + ret = pfrm_get_irq(&pdev->dev, (struct qdf_pfm_hndl *)pdev, + ic_irqname[hif_ext_group->irq[j]], + hif_ext_group->irq[j], &irq); + if (ret) { + dev_err(&pdev->dev, "get irq failed\n"); + ret = -EFAULT; + goto end; + } + ic_irqnum[hif_ext_group->irq[j]] = irq; + hif_ext_group->os_irq[j] = irq; + } + qdf_spin_lock_irqsave(&hif_ext_group->irq_lock); for (j = 0; j < hif_ext_group->numirq; j++) { - qal_vbus_get_irq((struct qdf_pfm_hndl *)pdev, - ic_irqname[hif_ext_group->irq[j]], &irq); - - ic_irqnum[hif_ext_group->irq[j]] = irq; + irq = hif_ext_group->os_irq[j]; irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); - ret = request_irq(irq, hif_ext_group_interrupt_handler, - IRQF_TRIGGER_RISING, - ic_irqname[hif_ext_group->irq[j]], - hif_ext_group); + ret = pfrm_request_irq(scn->qdf_dev->dev, + irq, hif_ext_group_interrupt_handler, + IRQF_TRIGGER_RISING, + ic_irqname[hif_ext_group->irq[j]], + hif_ext_group); if (ret) { - dev_err(&pdev->dev, - "ath_request_irq failed\n"); - ret = -1; + dev_err(&pdev->dev, "ath_request_irq failed\n"); + ret = -EFAULT; goto end; } - hif_ext_group->os_irq[j] = irq; } qdf_spin_unlock_irqrestore(&hif_ext_group->irq_lock); @@ -350,11 +367,22 @@ void hif_ahb_deconfigure_grp_irq(struct hif_softc *scn) hif_ext_group->irq_requested = false; for (j = 0; j < hif_ext_group->numirq; j++) { irq = hif_ext_group->os_irq[j]; + hif_ext_group->irq_enabled = false; irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY); - free_irq(irq, hif_ext_group); } qdf_spin_unlock_irqrestore(&hif_ext_group->irq_lock); + + /* Avoid holding the irq_lock while freeing the irq + * as the same lock is being held by the irq handler + * while disabling the irq. This causes a deadlock + * between free_irq and irq_handler. + */ + for (j = 0; j < hif_ext_group->numirq; j++) { + irq = hif_ext_group->os_irq[j]; + pfrm_free_irq(scn->qdf_dev->dev, + irq, hif_ext_group); + } } } } @@ -440,19 +468,23 @@ void hif_ahb_disable_bus(struct hif_softc *scn) int mem_pa_size = 0; struct hif_target_info *tgt_info = NULL; struct qdf_vbus_resource *vmres = NULL; + QDF_STATUS status; tgt_info = &scn->target_info; /*Disable WIFI clock input*/ if (sc->mem) { - qal_vbus_get_resource((struct qdf_pfm_hndl *)pdev, &vmres, - IORESOURCE_MEM, 0); - memres = (struct resource *)vmres; - if (!memres) { + status = pfrm_platform_get_resource( + scn->qdf_dev->dev, + (struct qdf_pfm_hndl *)pdev, &vmres, + IORESOURCE_MEM, 0); + if (QDF_IS_STATUS_ERROR(status)) { HIF_INFO("%s: Failed to get IORESOURCE_MEM\n", - __func__); + __func__); return; } - mem_pa_size = memres->end - memres->start + 1; + memres = (struct resource *)vmres; + if (memres) + mem_pa_size = memres->end - memres->start + 1; /* Should not be executed on 8074 platform */ if ((tgt_info->target_type != TARGET_TYPE_QCA8074) && @@ -464,9 +496,9 @@ void hif_ahb_disable_bus(struct hif_softc *scn) } mem = (void __iomem *)sc->mem; if (mem) { - devm_iounmap(&pdev->dev, mem); - devm_release_mem_region(&pdev->dev, scn->mem_pa, - mem_pa_size); + pfrm_devm_iounmap(&pdev->dev, mem); + pfrm_devm_release_mem_region(&pdev->dev, scn->mem_pa, + mem_pa_size); sc->mem = NULL; } } @@ -500,6 +532,8 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc, void __iomem *mem = NULL; uint32_t revision_id = 0; struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(ol_sc); + QDF_STATUS status; + struct qdf_vbus_resource *vmres = NULL; sc->pdev = (struct pci_dev *)pdev; sc->dev = &pdev->dev; @@ -513,22 +547,30 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc, return QDF_STATUS_E_FAILURE; } - memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + status = pfrm_platform_get_resource(&pdev->dev, + (struct qdf_pfm_hndl *)pdev, + &vmres, + IORESOURCE_MEM, 0); + if (QDF_IS_STATUS_ERROR(status)) { + HIF_INFO("%s: Failed to get IORESOURCE_MEM\n", __func__); + return -EIO; + } + memres = (struct resource *)vmres; if (!memres) { HIF_INFO("%s: Failed to get IORESOURCE_MEM\n", __func__); return -EIO; } - ret = dma_set_mask(dev, DMA_BIT_MASK(32)); + ret = pfrm_dma_set_mask(dev, 32); if (ret) { HIF_INFO("ath: 32-bit DMA not available\n"); goto err_cleanup1; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + ret = pfrm_dma_set_mask_and_coherent(dev, 32); #else - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + ret = pfrm_dma_set_coherent_mask(dev, 32); #endif if (ret) { HIF_ERROR("%s: failed to set dma mask error = %d", @@ -538,11 +580,16 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc, /* Arrange for access to Target SoC registers. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) - mem = devm_ioremap_resource(&pdev->dev, memres); + status = pfrm_devm_ioremap_resource(dev, + (struct qdf_vbus_resource *)memres, + &mem); #else - mem = devm_request_and_ioremap(&pdev->dev, memres); + status = pfrm_devm_request_and_ioremap( + dev, + (struct qdf_vbus_resource *)memres, + &mem); #endif - if (IS_ERR(mem)) { + if (QDF_IS_STATUS_ERROR(status)) { HIF_INFO("ath: ioremap error\n"); ret = PTR_ERR(mem); goto err_cleanup1; @@ -558,7 +605,6 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc, hif_register_tbl_attach(ol_sc, hif_type); hif_target_register_tbl_attach(ol_sc, target_type); - /* QCA_WIFI_QCA8074_VP:Should not be executed on 8074 VP platform */ if ((tgt_info->target_type != TARGET_TYPE_QCA8074) && (tgt_info->target_type != TARGET_TYPE_QCA8074V2) && (tgt_info->target_type != TARGET_TYPE_QCA6018)) { @@ -577,7 +623,6 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc, return QDF_STATUS_SUCCESS; err_target_sync: - /* QCA_WIFI_QCA8074_VP:Should not be executed on 8074 VP platform */ if ((tgt_info->target_type != TARGET_TYPE_QCA8074) && (tgt_info->target_type != TARGET_TYPE_QCA8074V2) && (tgt_info->target_type != TARGET_TYPE_QCA6018)) { @@ -630,20 +675,22 @@ void hif_ahb_nointrs(struct hif_softc *scn) if (sc->num_msi_intrs > 0) { /* MSI interrupt(s) */ for (i = 0; i < sc->num_msi_intrs; i++) { - free_irq(sc->irq + i, sc); + pfrm_free_irq(scn->qdf_dev->dev, sc->irq + i, sc); } sc->num_msi_intrs = 0; } else { if (!scn->per_ce_irq) { - free_irq(sc->irq, sc); + pfrm_free_irq(scn->qdf_dev->dev, sc->irq, sc); } else { for (i = 0; i < scn->ce_count; i++) { if (host_ce_conf[i].flags & CE_ATTR_DISABLE_INTR) continue; - free_irq(ic_irqnum[HIF_IC_CE0_IRQ_OFFSET + i], - &hif_state->tasklets[i]); + pfrm_free_irq( + scn->qdf_dev->dev, + ic_irqnum[HIF_IC_CE0_IRQ_OFFSET + i], + &hif_state->tasklets[i]); } hif_ahb_deconfigure_grp_irq(scn); } @@ -771,7 +818,7 @@ void hif_ahb_exec_grp_irq_enable(struct hif_exec_context *hif_ext_group) int i; qdf_spin_lock_irqsave(&hif_ext_group->irq_lock); - if (!hif_ext_group->irq_enabled) { + if (hif_ext_group->irq_requested && !hif_ext_group->irq_enabled) { for (i = 0; i < hif_ext_group->numirq; i++) { enable_irq(hif_ext_group->os_irq[i]); } @@ -790,3 +837,23 @@ bool hif_ahb_needs_bmi(struct hif_softc *scn) { return !ce_srng_based(scn); } + +void hif_ahb_display_stats(struct hif_softc *scn) +{ + if (!scn) { + HIF_ERROR("%s, hif_scn null", __func__); + return; + } + hif_display_ce_stats(scn); +} + +void hif_ahb_clear_stats(struct hif_softc *scn) +{ + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + + if (!hif_state) { + HIF_ERROR("%s, hif_state null", __func__); + return; + } + hif_clear_ce_stats(hif_state); +} diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_snoc.c b/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_snoc.c index 119db8af3b395ba6971097b60d35954e8627b8f6..51350887fecceb656e97ebc012902ea4d98a5f44 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_snoc.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/snoc/if_snoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -78,13 +78,11 @@ int hif_snoc_dump_registers(struct hif_softc *hif_ctx) void hif_snoc_display_stats(struct hif_softc *hif_ctx) { - struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx); - - if (!hif_state) { + if (!hif_ctx) { HIF_ERROR("%s, hif_ctx null", __func__); return; } - hif_display_ce_stats(hif_state); + hif_display_ce_stats(hif_ctx); } void hif_snoc_clear_stats(struct hif_softc *hif_ctx) diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb.c b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb.c index 4a129e3c5c75483cc13e43d4492c234d7a0548fc..8ed33841763e4952619265d7b8bbca6e1f532267 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb.c @@ -298,8 +298,14 @@ uint16_t hif_get_free_queue_number(struct hif_opaque_softc *scn, uint8_t pipe_id) { struct HIF_DEVICE_USB *device = HIF_GET_USB_DEVICE(scn); + struct HIF_USB_PIPE *pipe = &device->pipes[pipe_id]; + u16 urb_cnt; + + qdf_spin_lock_irqsave(&pipe->device->cs_lock); + urb_cnt = pipe->urb_cnt; + qdf_spin_unlock_irqrestore(&pipe->device->cs_lock); - return device->pipes[pipe_id].urb_cnt; + return urb_cnt; } /** @@ -378,6 +384,7 @@ QDF_STATUS hif_usb_device_init(struct hif_usb_softc *sc) qdf_spinlock_create(&(device->cs_lock)); qdf_spinlock_create(&(device->rx_lock)); qdf_spinlock_create(&(device->tx_lock)); + qdf_spinlock_create(&device->rx_prestart_lock); device->udev = dev; device->interface = interface; diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb_internal.h b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb_internal.h index ddf8cc22546be5c1dd025864d495f1a56c984e87..3f3a91eafe952481595b8c1ac6f3bcd5b23aea21 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/hif_usb_internal.h @@ -51,7 +51,8 @@ #define HIF_USB_FLUSH_WORK(pipe) flush_work(&pipe->io_complete_work) #else -#define HIF_USB_SCHEDULE_WORK(pipe) schedule_work(&pipe->io_complete_work) +#define HIF_USB_SCHEDULE_WORK(pipe) queue_work(system_highpri_wq,\ + &(pipe)->io_complete_work) #define HIF_USB_INIT_WORK(pipe)\ INIT_WORK(&pipe->io_complete_work,\ usb_hif_io_comp_work) diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.c b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.c index fd6da656f951c0712bd38e612e765f1731cbd4df..7917380e060b6a7ffabdebb9027f56bd5349c4d1 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.c @@ -26,7 +26,6 @@ #include "hif_debug.h" #include "epping_main.h" #include "hif_main.h" -#include "qwlan_version.h" #include "usb_api.h" #define DELAY_FOR_TARGET_READY 200 /* 200ms */ @@ -195,8 +194,6 @@ QDF_STATUS hif_usb_enable_bus(struct hif_softc *scn, u32 hif_type; u32 target_type; - usb_get_dev(usbdev); - if (!scn) { HIF_ERROR("%s: hif_ctx is NULL", __func__); goto err_usb; @@ -230,6 +227,7 @@ QDF_STATUS hif_usb_enable_bus(struct hif_softc *scn, * by CNSS driver. */ if (target_type != TARGET_TYPE_QCN7605) { + usb_get_dev(usbdev); if ((usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0, HZ)) < 0) { @@ -272,7 +270,8 @@ QDF_STATUS hif_usb_enable_bus(struct hif_softc *scn, unregister_reboot_notifier(&sc->reboot_notifier); err_usb: ret = QDF_STATUS_E_FAILURE; - usb_put_dev(usbdev); + if (target_type != TARGET_TYPE_QCN7605) + usb_put_dev(usbdev); return ret; } @@ -306,7 +305,8 @@ void hif_usb_disable_bus(struct hif_softc *hif_ctx) /* disable lpm to avoid following cold reset will * cause xHCI U1/U2 timeout */ - usb_disable_lpm(udev); + if (tgt_info->target_type != TARGET_TYPE_QCN7605) + usb_disable_lpm(udev); /* wait for disable lpm */ set_current_state(TASK_INTERRUPTIBLE); @@ -319,10 +319,10 @@ void hif_usb_disable_bus(struct hif_softc *hif_ctx) if (g_usb_sc->suspend_state) hif_bus_resume(GET_HIF_OPAQUE_HDL(hif_ctx)); - if (tgt_info->target_type != TARGET_TYPE_QCN7605) + if (tgt_info->target_type != TARGET_TYPE_QCN7605) { unregister_reboot_notifier(&sc->reboot_notifier); - - usb_put_dev(interface_to_usbdev(interface)); + usb_put_dev(udev); + } hif_usb_device_deinit(sc); @@ -532,8 +532,7 @@ int hif_usb_bus_configure(struct hif_softc *scn) else mode = PLD_MISSION; - return pld_wlan_enable(scn->qdf_dev->dev, &cfg, - mode, QWLAN_VERSIONSTR); + return pld_wlan_enable(scn->qdf_dev->dev, &cfg, mode); } #else /** @@ -706,7 +705,6 @@ void hif_usb_ramdump_handler(struct hif_opaque_softc *scn) if (pattern == FW_ASSERT_PATTERN) { HIF_ERROR("Firmware crash detected...\n"); - HIF_ERROR("Host SW version: %s\n", QWLAN_VERSIONSTR); HIF_ERROR("target_type: %d.target_version %d. target_revision%d.", tgt_info->target_type, tgt_info->target_version, @@ -722,7 +720,7 @@ void hif_usb_ramdump_handler(struct hif_opaque_softc *scn) reg = (uint32_t *) (data + 4); start_addr = *reg++; if (sc->fw_ram_dumping == 0) { - pr_err("Firmware stack dump:"); + qdf_nofl_err("Firmware stack dump:"); sc->fw_ram_dumping = 1; fw_stack_addr = start_addr; } @@ -731,13 +729,13 @@ void hif_usb_ramdump_handler(struct hif_opaque_softc *scn) for (i = 0; i < (len - 8); i += 16) { if ((*reg == FW_REG_END_PATTERN) && (i == len - 12)) { sc->fw_ram_dumping = 0; - pr_err("Stack start address = %#08x\n", - fw_stack_addr); + qdf_nofl_err("Stack start address = %#08x", + fw_stack_addr); break; } hex_dump_to_buffer(reg, remaining, 16, 4, str_buf, sizeof(str_buf), false); - pr_err("%#08x: %s\n", start_addr + i, str_buf); + qdf_nofl_err("%#08x: %s", start_addr + i, str_buf); remaining -= 16; reg += 4; } diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.h b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.h index 35d83af601d7f49ec3fd360a863e6fd9353fba7b..1dd3840559446f3ceb10c02ab6f45c973cca0b59 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.h +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/if_usb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -117,6 +117,7 @@ struct HIF_DEVICE_USB { qdf_spinlock_t cs_lock; qdf_spinlock_t tx_lock; qdf_spinlock_t rx_lock; + qdf_spinlock_t rx_prestart_lock; struct hif_msg_callbacks htc_callbacks; struct usb_device *udev; struct usb_interface *interface; diff --git a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/usbdrv.c b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/usbdrv.c index 13ccace19b53f0e3aa73cf0b577d06aeb0491df2..c56aa3152825ec261910f4872cc79ce76705e46c 100644 --- a/drivers/staging/qca-wifi-host-cmn/hif/src/usb/usbdrv.c +++ b/drivers/staging/qca-wifi-host-cmn/hif/src/usb/usbdrv.c @@ -546,6 +546,7 @@ static void usb_hif_usb_recv_prestart_complete QDF_STATUS status = QDF_STATUS_SUCCESS; qdf_nbuf_t buf = NULL; struct HIF_USB_PIPE *pipe = urb_context->pipe; + struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device); HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", __func__, @@ -601,8 +602,10 @@ static void usb_hif_usb_recv_prestart_complete usb_hif_cleanup_recv_urb(urb_context); /* Prestart URBs runs out and now start working receive pipe. */ - if (--pipe->urb_prestart_cnt == 0) + qdf_spin_lock_irqsave(&pipe->device->rx_prestart_lock); + if ((--pipe->urb_prestart_cnt == 0) && !sc->suspend_state) usb_hif_start_recv_pipes(pipe->device); + qdf_spin_unlock_irqrestore(&pipe->device->rx_prestart_lock); HIF_DBG("-%s", __func__); } @@ -676,6 +679,11 @@ static void usb_hif_usb_recv_complete(struct urb *urb) } /* note: queue implements a lock */ skb_queue_tail(&pipe->io_comp_queue, buf); + + if (pipe->device->htc_callbacks.update_bundle_stats) + pipe->device->htc_callbacks.update_bundle_stats + (pipe->device->htc_callbacks.Context, 1); + HIF_USB_SCHEDULE_WORK(pipe); } while (false); @@ -719,6 +727,7 @@ static void usb_hif_usb_recv_bundle_complete(struct urb *urb) HTC_FRAME_HDR *HtcHdr; uint16_t payloadLen; qdf_nbuf_t new_skb = NULL; + uint8_t no_of_pkt_in_bundle; HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%pK", __func__, @@ -766,6 +775,7 @@ static void usb_hif_usb_recv_bundle_complete(struct urb *urb) qdf_nbuf_peek_header(buf, &netdata, &netlen); netlen = urb->actual_length; + no_of_pkt_in_bundle = 0; do { uint16_t frame_len; @@ -815,7 +825,14 @@ static void usb_hif_usb_recv_bundle_complete(struct urb *urb) new_skb = NULL; netdata += frame_len; netlen -= frame_len; + no_of_pkt_in_bundle++; } while (netlen); + + if (pipe->device->htc_callbacks.update_bundle_stats) + pipe->device->htc_callbacks.update_bundle_stats + (pipe->device->htc_callbacks.Context, + no_of_pkt_in_bundle); + HIF_USB_SCHEDULE_WORK(pipe); } while (false); @@ -854,6 +871,7 @@ static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, HIF_TRACE("+%s", __func__); + qdf_spin_lock_irqsave(&recv_pipe->device->rx_prestart_lock); for (i = 0; i < prestart_urb; i++) { urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); if (!urb_context) @@ -885,7 +903,6 @@ static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, urb_context->buf); usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); - usb_status = usb_submit_urb(urb, GFP_ATOMIC); if (usb_status) { @@ -897,6 +914,7 @@ static void usb_hif_post_recv_prestart_transfers(struct HIF_USB_PIPE *recv_pipe, } recv_pipe->urb_prestart_cnt++; } + qdf_spin_unlock_irqrestore(&recv_pipe->device->rx_prestart_lock); HIF_TRACE("-%s", __func__); } @@ -1070,8 +1088,9 @@ void usb_hif_start_recv_pipes(struct HIF_DEVICE_USB *device) pipe = &device->pipes[HIF_RX_DATA_PIPE]; pipe->urb_cnt_thresh = pipe->urb_alloc / 2; - HIF_TRACE("Post URBs to RX_DATA_PIPE: %d", - device->pipes[HIF_RX_DATA_PIPE].urb_cnt); + HIF_TRACE("Post URBs to RX_DATA_PIPE: %d is_bundle %d", + device->pipes[HIF_RX_DATA_PIPE].urb_cnt, + device->is_bundle_enabled); if (device->is_bundle_enabled) { usb_hif_post_recv_bundle_transfers(pipe, pipe->device->rx_bundle_buf_len); diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc.c b/drivers/staging/qca-wifi-host-cmn/htc/htc.c index c7b7d927cd333020dd2731a9d06752771959de08..f2d420cdc72e321b6014d47b5a8c3f6274b3a72a 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc.c +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,6 +19,7 @@ #include "htc_debug.h" #include "htc_internal.h" #include "htc_credit_history.h" +#include "htc_hang_event.h" #include #include /* qdf_nbuf_t */ #include /* qdf_print */ @@ -45,7 +46,7 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, #endif -#if (defined(CONFIG_MCL) || defined(QCA_WIFI_QCA8074) || \ +#if (defined(WMI_MULTI_MAC_SVC) || defined(QCA_WIFI_QCA8074) || \ defined(QCA_WIFI_QCA6018)) static const uint32_t svc_id[] = {WMI_CONTROL_SVC, WMI_CONTROL_SVC_WMAC1, WMI_CONTROL_SVC_WMAC2}; @@ -134,6 +135,16 @@ void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start) hif_dump(target->hif_dev, CmdId, start); } +void htc_ce_tasklet_debug_dump(HTC_HANDLE htc_handle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); + + if (!target->hif_dev) + return; + + hif_display_stats(target->hif_dev); +} + /* cleanup the HTC instance */ static void htc_cleanup(HTC_TARGET *target) { @@ -143,6 +154,9 @@ static void htc_cleanup(HTC_TARGET *target) HTC_PACKET_QUEUE *pkt_queue; qdf_nbuf_t netbuf; + while (htc_dec_return_runtime_cnt((void *)target) >= 0) + hif_pm_runtime_put(target->hif_dev, RTPM_ID_HTC); + if (target->hif_dev) { hif_detach_htc(target->hif_dev); hif_mask_interrupt_call(target->hif_dev); @@ -260,9 +274,49 @@ static void htc_runtime_pm_deinit(HTC_TARGET *target) qdf_destroy_work(0, &target->queue_kicker); } +int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc); + + return qdf_atomic_dec_return(&target->htc_runtime_cnt); +} + +/** + * htc_init_runtime_cnt: Initialize htc runtime count + * @htc: HTC handle + * + * Return: None + */ +static inline +void htc_init_runtime_cnt(HTC_TARGET *target) +{ + qdf_atomic_init(&target->htc_runtime_cnt); +} #else static inline void htc_runtime_pm_init(HTC_TARGET *target) { } static inline void htc_runtime_pm_deinit(HTC_TARGET *target) { } + +static inline +void htc_init_runtime_cnt(HTC_TARGET *target) +{ +} +#endif + +#if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT) +static +void htc_update_rx_bundle_stats(void *ctx, uint8_t no_of_pkt_in_bundle) +{ + HTC_TARGET *target = (HTC_TARGET *)ctx; + + no_of_pkt_in_bundle--; + if (target && (no_of_pkt_in_bundle < HTC_MAX_MSG_PER_BUNDLE_RX)) + target->rx_bundle_stats[no_of_pkt_in_bundle]++; +} +#else +static +void htc_update_rx_bundle_stats(void *ctx, uint8_t no_of_pkt_in_bundle) +{ +} #endif /* registered target arrival callback from the HIF layer */ @@ -334,6 +388,7 @@ HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo, htcCallbacks.txResourceAvailHandler = htc_tx_resource_avail_handler; htcCallbacks.fwEventHandler = htc_fw_event_handler; + htcCallbacks.update_bundle_stats = htc_update_rx_bundle_stats; target->hif_dev = ol_sc; /* Get HIF default pipe for HTC message exchange */ @@ -349,9 +404,12 @@ HTC_HANDLE htc_create(void *ol_sc, struct htc_init_info *pInfo, } while (false); htc_recv_init(target); + htc_init_runtime_cnt(target); HTC_TRACE("-htc_create: (0x%pK)", target); + htc_hang_event_notifier_register(target); + return (HTC_HANDLE) target; } @@ -361,6 +419,7 @@ void htc_destroy(HTC_HANDLE HTCHandle) AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_destroy .. Destroying :0x%pK\n", target)); + htc_hang_event_notifier_unregister(); hif_stop(htc_get_hif_device(HTCHandle)); if (target) htc_cleanup(target); diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_api.h b/drivers/staging/qca-wifi-host-cmn/htc/htc_api.h index b4eeb33a8c8f6c5657696716662fd80fc0c58477..5ed879821a3045097152af611568df28d1afa67d 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_api.h +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,7 +38,13 @@ extern "C" { #define HTC_HTT_TRANSFER_HDRSIZE 24 -typedef void *HTC_HANDLE; +/* + * NOTE WELL: struct opaque_htc_handle is not defined anywhere. This + * reference is used to help ensure that a HTC_HANDLE is never used + * where a different handle type is expected + */ +struct opaque_htc_handle; +typedef struct opaque_htc_handle *HTC_HANDLE; typedef uint16_t HTC_SERVICE_ID; @@ -63,6 +69,8 @@ struct ol_ath_htc_stats { /* To resume HTT Tx queue during runtime resume */ typedef void (*HTC_EP_RESUME_TX_QUEUE)(void *); +typedef int (*HTC_EP_PADDING_CREDIT_UPDATE) (void *, int); + /* per service connection send completion */ typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *, HTC_PACKET *); /* per service connection callback when a plurality of packets have been sent @@ -169,6 +177,8 @@ struct htc_ep_callbacks { HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; HTC_EP_RESUME_TX_QUEUE ep_resume_tx_queue; + + HTC_EP_PADDING_CREDIT_UPDATE ep_padding_credit_update; /* if EpRecvAllocThresh is non-NULL, HTC will compare the * threshold value to the current recv packet length and invoke * the EpRecvAllocThresh callback to acquire a packet buffer @@ -471,6 +481,15 @@ QDF_STATUS htc_connect_service(HTC_HANDLE HTCHandle, */ void htc_dump(HTC_HANDLE HTCHandle, uint8_t CmdId, bool start); +/** + * htc_ce_taklet_debug_dump - Dump ce tasklet rings debug data + * @HTCHandle - HTC handle + * + * Debug logs will be printed. + * Return: None + */ +void htc_ce_tasklet_debug_dump(HTC_HANDLE htc_handle); + /** * htc_send_pkt - Send an HTC packet * @HTCHandle - HTC handle @@ -697,7 +716,7 @@ struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE * * Return: htc_handle tx queue depth */ -int htc_get_tx_queue_depth(HTC_HANDLE *htc_handle, HTC_ENDPOINT_ID endpoint_id); +int htc_get_tx_queue_depth(HTC_HANDLE htc_handle, HTC_ENDPOINT_ID endpoint_id); #ifdef WLAN_FEATURE_FASTPATH void htc_ctrl_msg_cmpl(HTC_HANDLE htc_pdev, HTC_ENDPOINT_ID htc_ep_id); @@ -762,9 +781,23 @@ void htc_clear_bundle_stats(HTC_HANDLE HTCHandle); #ifdef FEATURE_RUNTIME_PM int htc_pm_runtime_get(HTC_HANDLE htc_handle); int htc_pm_runtime_put(HTC_HANDLE htc_handle); + +/** + * htc_dec_return_runtime_cnt: Decrement htc runtime count + * @htc: HTC handle + * + * Return: value of runtime count after decrement + */ +int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc); #else static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; } static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; } + +static inline +int32_t htc_dec_return_runtime_cnt(HTC_HANDLE htc) +{ + return -1; +} #endif /** @@ -818,4 +851,19 @@ void htc_print_credit_history(HTC_HANDLE htc, uint32_t count, print(print_priv, "HTC Credit History Feature is disabled"); } #endif + +#ifdef SYSTEM_PM_CHECK +/** + * htc_system_resume() - Send out any pending WMI/HTT + * messages pending in htc queues on system resume. + * @htc: HTC handle + * + * Return: None + */ +void htc_system_resume(HTC_HANDLE htc); +#else +static inline void htc_system_resume(HTC_HANDLE htc) +{ +} +#endif #endif /* _HTC_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.c b/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.c index 4e067201232714b2a4cba15a102a91d3d0afb0c5..becfd4e3ced3cc5765c349d75b0091b1e7b6e1eb 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.c +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -20,6 +20,8 @@ #include "htc_internal.h" #include "htc_credit_history.h" #include +#include +#include struct HTC_CREDIT_HISTORY { enum htc_credit_exchange_type type; @@ -28,6 +30,11 @@ struct HTC_CREDIT_HISTORY { uint32_t htc_tx_queue_depth; }; +struct htc_hang_data_fixed_param { + uint16_t tlv_header; + struct HTC_CREDIT_HISTORY credit_hist; +} qdf_packed; + static qdf_spinlock_t g_htc_credit_lock; static uint32_t g_htc_credit_history_idx; static uint32_t g_htc_credit_history_length; @@ -135,3 +142,57 @@ void htc_print_credit_history(HTC_HANDLE htc, uint32_t count, qdf_spin_unlock_bh(&g_htc_credit_lock); } + +#ifdef WLAN_HANG_EVENT +void htc_log_hang_credit_history(struct notifier_block *block, void *data) +{ + qdf_notif_block *notif_block = qdf_container_of(block, qdf_notif_block, + notif_block); + struct qdf_notifer_data *htc_hang_data = data; + uint32_t count = 1, idx, total_len; + HTC_HANDLE htc; + struct htc_hang_data_fixed_param *cmd; + uint8_t *htc_buf_ptr; + + htc = notif_block->priv_data; + + if (!htc) + return; + + if (!htc_hang_data) + return; + + total_len = sizeof(struct htc_hang_data_fixed_param); + qdf_spin_lock_bh(&g_htc_credit_lock); + + if (count > HTC_CREDIT_HISTORY_MAX) + count = HTC_CREDIT_HISTORY_MAX; + if (count > g_htc_credit_history_length) + count = g_htc_credit_history_length; + + idx = HTC_CREDIT_HISTORY_MAX + g_htc_credit_history_idx - count; + idx %= HTC_CREDIT_HISTORY_MAX; + + qdf_spin_unlock_bh(&g_htc_credit_lock); + + while (count) { + struct HTC_CREDIT_HISTORY *hist = + &htc_credit_history_buffer[idx]; + htc_buf_ptr = htc_hang_data->hang_data + htc_hang_data->offset; + cmd = (struct htc_hang_data_fixed_param *)htc_buf_ptr; + + if (htc_hang_data->offset + total_len > QDF_WLAN_HANG_FW_OFFSET) + return; + + QDF_HANG_EVT_SET_HDR(&cmd->tlv_header, + HANG_EVT_TAG_HTC_CREDIT_HIST, + QDF_HANG_GET_STRUCT_TLVLEN(struct htc_hang_data_fixed_param)); + qdf_mem_copy(&cmd->credit_hist, hist, sizeof(*hist)); + --count; + ++idx; + if (idx >= HTC_CREDIT_HISTORY_MAX) + idx = 0; + htc_hang_data->offset += total_len; + } +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.h b/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.h index 78b284eaac3e470611045c390a3f3395fc096a31..bd02c998a154b588d62577c5df91f1a05a0da5f5 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.h +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_credit_history.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,7 +32,24 @@ void htc_credit_history_init(void); void htc_credit_record(enum htc_credit_exchange_type type, uint32_t tx_credit, uint32_t htc_tx_queue_depth); - +#ifdef WLAN_HANG_EVENT +/** + * htc_log_hang_credit_history: Log the credit history into a buffer + * @block: Notifier block + * @data: Private data of the block. + * + * HTC hang event notifier callback inovked when the recovery is triggered + * to log the credit information to understand the reason for recovery. + * + * Return: none + */ +void htc_log_hang_credit_history(struct notifier_block *block, void *data); +#else +static inline +void htc_log_hang_credit_history(struct notifier_block *block, void *data) +{ +} +#endif #else /* FEATURE_HTC_CREDIT_HISTORY */ static inline diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.c b/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.c new file mode 100644 index 0000000000000000000000000000000000000000..b6b75760dce7f684484dbab407515bb93b2b47d0 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ +#include +#include +#include "htc_hang_event.h" +#include "htc_internal.h" +#include "htc_credit_history.h" + +static int htc_recovery_notifier_call(struct notifier_block *block, + unsigned long state, + void *data) +{ + htc_log_hang_credit_history(block, data); + + return NOTIFY_OK; +} + +static qdf_notif_block htc_recovery_notifier = { + .notif_block.notifier_call = htc_recovery_notifier_call, +}; + +QDF_STATUS htc_hang_event_notifier_register(HTC_TARGET *target) +{ + htc_recovery_notifier.priv_data = target; + return qdf_hang_event_register_notifier(&htc_recovery_notifier); +} + +QDF_STATUS htc_hang_event_notifier_unregister(void) +{ + return qdf_hang_event_unregister_notifier(&htc_recovery_notifier); +} diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.h b/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.h new file mode 100644 index 0000000000000000000000000000000000000000..3304541bca93d02d60296af08cf7e23441daaf90 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_hang_event.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ +#ifndef HTC_HANG_EVENT_H +#define HTC_HANG_EVENT_H + +#include "htc_internal.h" + +#ifdef WLAN_HANG_EVENT +/** + * htc_hang_event_notifier_register() - HTC hang event notifier register + * @target: Target specific htc hangle + * + * This function registers htc layer notifier for the hang event notifier chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS htc_hang_event_notifier_register(HTC_TARGET *target); + +/** + * htc_hang_event_notifier_unregister() - htc hang event notifier unregister + * + * This function unregisters htc layer notifier for the hang event notifier + * chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS htc_hang_event_notifier_unregister(void); +#else +static inline QDF_STATUS htc_hang_event_notifier_register(HTC_TARGET *target) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS htc_hang_event_notifier_unregister(void) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_internal.h b/drivers/staging/qca-wifi-host-cmn/htc/htc_internal.h index 32b527821fee14eb88eb498d1e4bc70902e7f5b0..a51e910a59460bc13de664844124ece2f7b6c9f0 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -39,9 +39,15 @@ extern "C" { #define HTC_TARGET_DEBUG_INTR_MASK 0x01 #define HTC_TARGET_CREDIT_INTR_MASK 0xF0 #define HTC_MIN_MSG_PER_BUNDLE 2 + #if defined(HIF_USB) + #define HTC_MAX_MSG_PER_BUNDLE_RX 11 -#define HTC_MAX_MSG_PER_BUNDLE_TX 8 +#if defined(CFG_HTC_MAX_MSG_PER_BUNDLE_TX) +#define HTC_MAX_MSG_PER_BUNDLE_TX CFG_HTC_MAX_MSG_PER_BUNDLE_TX +#else +#define HTC_MAX_MSG_PER_BUNDLE_TX 8 +#endif /* CFG_HTC_MAX_MSG_PER_BUNDLE_TX */ #else #define HTC_MAX_MSG_PER_BUNDLE_RX 64 #define HTC_MAX_MSG_PER_BUNDLE 16 @@ -242,6 +248,11 @@ typedef struct _HTC_TARGET { uint8_t wmi_ep_count; /* Flag to indicate whether htc header length check is required */ bool htc_hdr_length_check; + +#ifdef FEATURE_RUNTIME_PM + /* Runtime count for H2T msg with response */ + qdf_atomic_t htc_runtime_cnt; +#endif } HTC_TARGET; diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_packet.h b/drivers/staging/qca-wifi-host-cmn/htc/htc_packet.h index 8ac7db432caf99693cf57cb71120a8c73ce27836..78e0a3b95bb6bfe0b87b9ff7f4f281f9d907a070 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_packet.h +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_packet.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2017, 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2017, 2019-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -76,8 +76,14 @@ struct htc_tx_packet_info { /* Tag packet for runtime put after sending */ #define HTC_TX_PACKET_TAG_RUNTIME_PUT (HTC_TX_PACKET_TAG_USER_DEFINED + 3) +/*Tag packet for runtime put in response or cleanup */ +#define HTC_TX_PACKET_TAG_RTPM_PUT_RC (HTC_TX_PACKET_TAG_USER_DEFINED + 4) + +#define HTC_TX_PACKET_SYSTEM_SUSPEND (HTC_TX_PACKET_TAG_USER_DEFINED + 5) +#define HTC_TX_PACKET_SYSTEM_RESUME (HTC_TX_PACKET_TAG_USER_DEFINED + 6) #define HTC_TX_PACKET_FLAG_FIXUP_NETBUF (1 << 0) +#define HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA (1 << 1) /** * struct htc_rx_packet_info - HTC RX Packet information diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_recv.c b/drivers/staging/qca-wifi-host-cmn/htc/htc_recv.c index ce09ee0296eaec82603bb752362522f1f07b363e..2d6047da83efd86b91630b43a39cb5e91052ef45 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_recv.c +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_recv.c @@ -229,10 +229,6 @@ qdf_nbuf_t rx_sg_to_single_netbuf(HTC_TARGET *target) } #endif -#ifdef CONFIG_WIN -#define HTC_MSG_NACK_SUSPEND 7 -#endif - QDF_STATUS htc_rx_completion_handler(void *Context, qdf_nbuf_t netbuf, uint8_t pipeID) { diff --git a/drivers/staging/qca-wifi-host-cmn/htc/htc_send.c b/drivers/staging/qca-wifi-host-cmn/htc/htc_send.c index b86c7c478b9bb858e26318fe440c67a3ae550db1..89170c47df806162344fb0ba861cd7b863bf2e84 100644 --- a/drivers/staging/qca-wifi-host-cmn/htc/htc_send.c +++ b/drivers/staging/qca-wifi-host-cmn/htc/htc_send.c @@ -71,7 +71,7 @@ void htc_dump_counter_info(HTC_HANDLE HTCHandle) __func__, target->ce_send_cnt, target->TX_comp_cnt)); } -int htc_get_tx_queue_depth(HTC_HANDLE *htc_handle, HTC_ENDPOINT_ID endpoint_id) +int htc_get_tx_queue_depth(HTC_HANDLE htc_handle, HTC_ENDPOINT_ID endpoint_id) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); HTC_ENDPOINT *endpoint = &target->endpoint[endpoint_id]; @@ -112,8 +112,10 @@ static inline void restore_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket) qdf_nbuf_unmap(target->osdev, netbuf, QDF_DMA_TO_DEVICE); pPacket->PktInfo.AsTx.Flags &= ~HTC_TX_PACKET_FLAG_FIXUP_NETBUF; } - - qdf_nbuf_pull_head(netbuf, sizeof(HTC_FRAME_HDR)); + if (pPacket->PktInfo.AsTx.Flags & + HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA) { + qdf_nbuf_pull_head(netbuf, sizeof(HTC_FRAME_HDR)); + } } static void send_packet_completion(HTC_TARGET *target, HTC_PACKET *pPacket) @@ -168,10 +170,27 @@ static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket) qdf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR)); } } + +/** + * htc_inc_runtime_cnt: Increment htc runtime count + * @target: handle of HTC context + * + * Return: None + */ +static inline +void htc_inc_runtime_cnt(HTC_TARGET *target) +{ + qdf_atomic_inc(&target->htc_runtime_cnt); +} #else static void log_packet_info(HTC_TARGET *target, HTC_PACKET *pPacket) { } + +static inline +void htc_inc_runtime_cnt(HTC_TARGET *target) +{ +} #endif void htc_send_complete_check_cleanup(void *context) @@ -302,8 +321,10 @@ htc_send_update_tx_bundle_stats(HTC_TARGET *target, qdf_size_t data_len, int TxCreditSize) { - if ((data_len / TxCreditSize) <= HTC_MAX_MSG_PER_BUNDLE_TX) - target->tx_bundle_stats[(data_len / TxCreditSize) - 1]++; + int index = ((data_len + TxCreditSize - 1) / TxCreditSize) - 1; + + if (index < HTC_MAX_MSG_PER_BUNDLE_TX) + target->tx_bundle_stats[index]++; } /** @@ -371,13 +392,137 @@ static QDF_STATUS htc_send_bundled_netbuf(HTC_TARGET *target, pEndpoint->UL_PipeID, pEndpoint->Id, data_len, bundleBuf, data_attr); - if (status != QDF_STATUS_SUCCESS) { - qdf_print("%s:hif_send_head failed(len=%zu).", __func__, - data_len); + if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) { + HTC_PACKET_QUEUE requeue; + + qdf_print("hif_send_head failed(len=%zu).", data_len); + INIT_HTC_PACKET_QUEUE(&requeue); + LOCK_HTC_TX(target); + pEndpoint->ul_outstanding_cnt--; + HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue, pPacketTx); + + if (pPacketTx->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED) { + HTC_PACKET *temp_packet; + HTC_PACKET_QUEUE *packet_queue = + (HTC_PACKET_QUEUE *)pPacketTx->pContext; + + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(packet_queue, + temp_packet) { + HTC_PACKET_ENQUEUE(&requeue, temp_packet); + } HTC_PACKET_QUEUE_ITERATE_END; + + UNLOCK_HTC_TX(target); + free_htc_bundle_packet(target, pPacketTx); + LOCK_HTC_TX(target); + + } else { + HTC_PACKET_ENQUEUE(&requeue, pPacketTx); + } + + HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue, + &requeue); + UNLOCK_HTC_TX(target); } return status; } +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT +#define SDIO_BLOCK_SIZE 512 +static int htc_tx_pad_credit_avail(HTC_ENDPOINT *ep) +{ + int ret = 0; + + if (!ep || !ep->EpCallBacks.pContext || + !ep->EpCallBacks.ep_padding_credit_update) + return 1; + + ret = ep->EpCallBacks.ep_padding_credit_update(ep->EpCallBacks.pContext, + 0); + + if (ret < 2) + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s ret %d\n", __func__, ret)); + + return ret; +} + +static bool htc_handle_extra_tx_credit(HTC_ENDPOINT *ep, + HTC_PACKET *p_last_htc_pkt, + unsigned char *p_last_pkt_bundle_buffer, + unsigned char **p_bundle_buffer, + int tot_data_len) +{ + bool extra_tx_credit = FALSE; + HTC_FRAME_HDR *p_htc_hdr; + int first_buf_bundled_len = 0, last_buf_len = 0; + int sdio_pad = 0, free_space = 0; + int (*update_ep_padding_credit)(void *, int); + + update_ep_padding_credit = ep->EpCallBacks.ep_padding_credit_update; + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + ("%s Tot data_len = %d\n", __func__, tot_data_len)); + + if (!p_last_htc_pkt) + return extra_tx_credit; + + last_buf_len = (p_last_htc_pkt->ActualLength + HTC_HDR_LENGTH); + if (tot_data_len != last_buf_len) { + first_buf_bundled_len = tot_data_len - ep->TxCreditSize; + free_space = tot_data_len - + (first_buf_bundled_len + last_buf_len); + } else { + free_space = ep->TxCreditSize - tot_data_len; + } + + sdio_pad = SDIO_BLOCK_SIZE - ((first_buf_bundled_len + last_buf_len) % + SDIO_BLOCK_SIZE); + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + ("%s first_buf_bundled_len = %d last_buf_len = %d\n", + __func__, first_buf_bundled_len, last_buf_len)); + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + ("%s sdio_pad = %d free_space = %d\n", __func__, + sdio_pad, free_space)); + + if (sdio_pad <= free_space) { + if (p_bundle_buffer && *p_bundle_buffer) { + /* Align Tx bundled buf to avoid a extra Padding buf */ + *p_bundle_buffer -= (free_space - sdio_pad); + } + } else { + /* Extra Padding Buffer needed, consume extra tx credit */ + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + ("%s Used a Tx credit for Padding Buffer\n", + __func__)); + p_htc_hdr = (HTC_FRAME_HDR *)(p_last_pkt_bundle_buffer); + p_htc_hdr->Flags |= HTC_FLAGS_PADDING_CHECK; + extra_tx_credit = TRUE; + if (ep->EpCallBacks.ep_padding_credit_update) { + /* Decrement 1 credit at host, + * due to extra tx credit consumed by padding buffer + */ + update_ep_padding_credit(ep->EpCallBacks.pContext, -1); + } + } + return extra_tx_credit; +} +#else +static int htc_tx_pad_credit_avail(HTC_ENDPOINT *ep) +{ + return 1; +} + +static bool htc_handle_extra_tx_credit(HTC_ENDPOINT *ep, + HTC_PACKET *p_last_htc_pkt, + unsigned char *p_last_pkt_bundle_buffer, + unsigned char **p_bundle_buffer, + int tot_data_len) +{ + return FALSE; +} +#endif + /** * htc_issue_packets_bundle() - HTC function to send bundle packets from a queue * @target: HTC target on which packets need to be sent @@ -399,6 +544,8 @@ static void htc_issue_packets_bundle(HTC_TARGET *target, int creditPad, creditRemainder, transferLength, bundlesSpaceRemaining = 0; HTC_PACKET_QUEUE *pQueueSave = NULL; + HTC_PACKET *p_last_htc_pkt = NULL; + unsigned char *p_last_pkt_bundle_buffer = NULL; bundlesSpaceRemaining = target->MaxMsgsPerHTCBundle * pEndpoint->TxCreditSize; @@ -414,6 +561,10 @@ static void htc_issue_packets_bundle(HTC_TARGET *target, pBundleBuffer = qdf_nbuf_data(bundleBuf); pQueueSave = (HTC_PACKET_QUEUE *) pPacketTx->pContext; while (1) { + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (htc_tx_pad_credit_avail(pEndpoint) < 1) + break; + } pPacket = htc_packet_dequeue(pPktQueue); if (!pPacket) break; @@ -431,6 +582,12 @@ static void htc_issue_packets_bundle(HTC_TARGET *target, } if (bundlesSpaceRemaining < transferLength) { + htc_handle_extra_tx_credit(pEndpoint, p_last_htc_pkt, + p_last_pkt_bundle_buffer, + &pBundleBuffer, + pBundleBuffer - + qdf_nbuf_data(bundleBuf)); + /* send out previous buffer */ htc_send_bundled_netbuf(target, pEndpoint, pBundleBuffer - last_credit_pad, @@ -460,6 +617,9 @@ static void htc_issue_packets_bundle(HTC_TARGET *target, pQueueSave = (HTC_PACKET_QUEUE *) pPacketTx->pContext; } + p_last_htc_pkt = pPacket; + p_last_pkt_bundle_buffer = pBundleBuffer; + bundlesSpaceRemaining -= transferLength; netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); @@ -500,15 +660,41 @@ static void htc_issue_packets_bundle(HTC_TARGET *target, last_credit_pad = creditPad; } /* send out remaining buffer */ - if (pBundleBuffer != qdf_nbuf_data(bundleBuf)) + if (pBundleBuffer != qdf_nbuf_data(bundleBuf)) { + htc_handle_extra_tx_credit(pEndpoint, p_last_htc_pkt, + p_last_pkt_bundle_buffer, + &pBundleBuffer, + pBundleBuffer - + qdf_nbuf_data(bundleBuf)); + htc_send_bundled_netbuf(target, pEndpoint, pBundleBuffer - last_credit_pad, pPacketTx); - else + } else { free_htc_bundle_packet(target, pPacketTx); + } } #endif /* ENABLE_BUNDLE_TX */ #else +static int htc_tx_pad_credit_avail(HTC_ENDPOINT *ep) +{ + return 1; +} + +bool htc_handle_extra_tx_credit(HTC_ENDPOINT *ep, + HTC_PACKET *p_last_htc_pkt, + unsigned char *p_last_pkt_bundle_buffer, + unsigned char **p_bundle_buffer, + int tot_data_len); +bool htc_handle_extra_tx_credit(HTC_ENDPOINT *ep, + HTC_PACKET *p_last_htc_pkt, + unsigned char *p_last_pkt_bundle_buffer, + unsigned char **p_bundle_buffer, + int tot_data_len) +{ + return FALSE; +} + static void htc_issue_packets_bundle(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pPktQueue) @@ -537,6 +723,15 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, enum qdf_bus_type bus_type; QDF_STATUS ret; bool rt_put = false; + bool used_extra_tx_credit = false; + uint8_t *buf = NULL; + int (*update_ep_padding_credit)(void *, int); + void *ctx = NULL; + bool rt_put_in_resp; + int32_t sys_state = HIF_SYSTEM_PM_STATE_ON; + + update_ep_padding_credit = + pEndpoint->EpCallBacks.ep_padding_credit_update; bus_type = hif_get_bus_type(target->hif_dev); @@ -544,6 +739,7 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, ("+htc_issue_packets: Queue: %pK, Pkts %d\n", pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue))); while (true) { + rt_put_in_resp = false; if (HTC_TX_BUNDLE_ENABLED(target) && HTC_PACKET_QUEUE_DEPTH(pPktQueue) >= HTC_MIN_MSG_PER_BUNDLE) { @@ -551,6 +747,11 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, case QDF_BUS_TYPE_SDIO: if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) break; + if (update_ep_padding_credit) { + if (htc_tx_pad_credit_avail + (pEndpoint) < 1) + break; + } case QDF_BUS_TYPE_USB: htc_issue_packets_bundle(target, pEndpoint, @@ -563,6 +764,13 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, /* if not bundling or there was a packet that could not be * placed in a bundle, and send it by normal way */ + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (htc_tx_pad_credit_avail(pEndpoint) < 1) { + status = QDF_STATUS_E_FAILURE; + break; + } + } + pPacket = htc_packet_dequeue(pPktQueue); if (!pPacket) { /* local queue is fully drained */ @@ -635,6 +843,11 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, pEndpoint->UL_PipeID, false); } + if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_SYSTEM_SUSPEND) { + sys_state = hif_system_pm_get_state(target->hif_dev); + hif_system_pm_set_state_suspending(target->hif_dev); + } + htc_packet_set_magic_cookie(pPacket, HTC_PACKET_MAGIC_COOKIE); /* * For HTT messages without a response from fw, @@ -643,17 +856,46 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target, */ if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_RUNTIME_PUT) rt_put = true; + else if (pPacket->PktInfo.AsTx.Tag == + HTC_TX_PACKET_TAG_RTPM_PUT_RC) { + rt_put_in_resp = true; + htc_inc_runtime_cnt(target); + } + #if DEBUG_BUNDLE qdf_print(" Send single EP%d buffer size:0x%x, total:0x%x.", pEndpoint->Id, pEndpoint->TxCreditSize, HTC_HDR_LENGTH + pPacket->ActualLength); #endif + buf = (uint8_t *)qdf_nbuf_get_frag_vaddr(netbuf, 0); + used_extra_tx_credit = + htc_handle_extra_tx_credit(pEndpoint, pPacket, buf, + NULL, pPacket->ActualLength + + HTC_HDR_LENGTH); + status = hif_send_head(target->hif_dev, pEndpoint->UL_PipeID, pEndpoint->Id, HTC_HDR_LENGTH + pPacket->ActualLength, netbuf, data_attr); + if (status != QDF_STATUS_SUCCESS) { + if (rt_put_in_resp) + htc_dec_return_runtime_cnt((void *)target); + + if (pPacket->PktInfo.AsTx.Tag == + HTC_TX_PACKET_SYSTEM_SUSPEND) + __hif_system_pm_set_state(target->hif_dev, + sys_state); + + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (used_extra_tx_credit) { + ctx = pEndpoint->EpCallBacks.pContext; + update_ep_padding_credit(ctx, 1); + } + } + } + htc_issue_tx_bundle_stats_inc(target); target->ce_send_cnt++; @@ -803,6 +1045,41 @@ htc_send_pkts_rtpm_dbgid_get(HTC_SERVICE_ID service_id) return rtpm_dbgid; } +#ifdef SYSTEM_PM_CHECK +/** + * extract_htc_system_resume_pkts(): Move system pm resume packets from endpoint + * into queue + * @endpoint: which enpoint to extract packets from + * @queue: a queue to store extracted packets in. + * + * Remove pm packets from the endpoint's tx queue and enqueue + * them into a queue + */ +static void extract_htc_system_resume_pkts(HTC_ENDPOINT *endpoint, + HTC_PACKET_QUEUE *queue) +{ + HTC_PACKET *packet; + + /* only WMI endpoint has power management packets */ + if (endpoint->service_id != WMI_CONTROL_SVC) + return; + + ITERATE_OVER_LIST_ALLOW_REMOVE(&endpoint->TxQueue.QueueHead, packet, + HTC_PACKET, ListLink) { + if (packet->PktInfo.AsTx.Tag == HTC_TX_PACKET_SYSTEM_RESUME) { + HTC_PACKET_REMOVE(&endpoint->TxQueue, packet); + HTC_PACKET_ENQUEUE(queue, packet); + } + } ITERATE_END +} +#else +static inline +void extract_htc_system_resume_pkts(HTC_ENDPOINT *endpoint, + HTC_PACKET_QUEUE *queue) +{ +} +#endif + /** * get_htc_send_packets_credit_based() - get packets based on available credits * @target: HTC target on which packets need to be sent @@ -828,6 +1105,8 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, bool do_pm_get = false; wlan_rtpm_dbgid rtpm_dbgid = 0; int ret; + HTC_PACKET_QUEUE sys_pm_queue; + bool sys_pm_check = false; /*** NOTE : the TX lock is held when this function is called ***/ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, @@ -836,8 +1115,16 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, INIT_HTC_PACKET_QUEUE(&pm_queue); extract_htc_pm_packets(pEndpoint, &pm_queue); if (HTC_QUEUE_EMPTY(&pm_queue)) { - tx_queue = &pEndpoint->TxQueue; do_pm_get = true; + + INIT_HTC_PACKET_QUEUE(&sys_pm_queue); + extract_htc_system_resume_pkts(pEndpoint, &sys_pm_queue); + if (HTC_QUEUE_EMPTY(&sys_pm_queue)) { + tx_queue = &pEndpoint->TxQueue; + sys_pm_check = true; + } else { + tx_queue = &sys_pm_queue; + } } else { tx_queue = &pm_queue; } @@ -873,6 +1160,13 @@ static void get_htc_send_packets_credit_based(HTC_TARGET *target, break; } + if (sys_pm_check && + hif_system_pm_state_check(target->hif_dev)) { + if (do_pm_get) + hif_pm_runtime_put(target->hif_dev, rtpm_dbgid); + break; + } + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Got head packet:%pK , Queue Depth: %d\n", pPacket, @@ -1012,12 +1306,20 @@ static void get_htc_send_packets(HTC_TARGET *target, } } + ret = hif_system_pm_state_check(target->hif_dev); + if (ret) { + if (do_pm_get) + hif_pm_runtime_put(target->hif_dev, rtpm_dbgid); + break; + } + pPacket = htc_packet_dequeue(tx_queue); if (!pPacket) { if (do_pm_get) hif_pm_runtime_put(target->hif_dev, rtpm_dbgid); break; } + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Got packet:%pK , New Queue Depth: %d\n", pPacket, @@ -1215,14 +1517,6 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target, return result; } - if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { - tx_resources = - hif_get_free_queue_number(target->hif_dev, - pEndpoint->UL_PipeID); - } else { - tx_resources = 0; - } - LOCK_HTC_TX(target); if (!HTC_QUEUE_EMPTY(&sendQueue)) { @@ -1261,6 +1555,14 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target, /* now drain the endpoint TX queue for transmission as long as we have * enough transmit resources */ + if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { + tx_resources = + hif_get_free_queue_number(target->hif_dev, + pEndpoint->UL_PipeID); + } else { + tx_resources = 0; + } + while (true) { if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) @@ -1518,6 +1820,8 @@ static inline QDF_STATUS __htc_send_pkt(HTC_HANDLE HTCHandle, return QDF_STATUS_E_INVAL; qdf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR)); + pPacket->PktInfo.AsTx.Flags |= + HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA; /* setup HTC frame header */ htc_hdr = (HTC_FRAME_HDR *)qdf_nbuf_get_frag_vaddr(netbuf, 0); AR_DEBUG_ASSERT(htc_hdr); @@ -1715,6 +2019,7 @@ QDF_STATUS htc_send_data_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket, int tx_resources; QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t data_attr = 0; + bool used_extra_tx_credit = false; if (pPacket) { if ((pPacket->Endpoint >= ENDPOINT_MAX) || @@ -1859,12 +2164,41 @@ QDF_STATUS htc_send_data_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket, HTC_MIN_MSG_PER_BUNDLE) && (hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_SDIO || hif_get_bus_type(target->hif_dev) == QDF_BUS_TYPE_USB)) { + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (htc_tx_pad_credit_avail(pEndpoint) < 1) { + status = QDF_STATUS_E_RESOURCES; + /* put the sendQueue back at the front + * of pEndpoint->TxQueue + */ + LOCK_HTC_TX(target); + HTC_PACKET_QUEUE_TRANSFER_TO_HEAD( + &pEndpoint->TxQueue, + &sendQueue); + UNLOCK_HTC_TX(target); + break; + } + } htc_issue_packets_bundle(target, pEndpoint, &sendQueue); } + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (htc_tx_pad_credit_avail(pEndpoint) < 1) { + status = QDF_STATUS_E_RESOURCES; + /* put the sendQueue back at the front + * of pEndpoint->TxQueue + */ + LOCK_HTC_TX(target); + HTC_PACKET_QUEUE_TRANSFER_TO_HEAD( + &pEndpoint->TxQueue, + &sendQueue); + UNLOCK_HTC_TX(target); + break; + } + } pPacket = htc_packet_dequeue(&sendQueue); if (!pPacket) break; netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + pHtcHdr = (HTC_FRAME_HDR *)qdf_nbuf_get_frag_vaddr(netbuf, 0); LOCK_HTC_TX(target); /* store in look up queue to match completions */ @@ -1873,11 +2207,27 @@ QDF_STATUS htc_send_data_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket, pEndpoint->ul_outstanding_cnt++; UNLOCK_HTC_TX(target); + used_extra_tx_credit = + htc_handle_extra_tx_credit(pEndpoint, pPacket, + (uint8_t *)pHtcHdr, + NULL, + pPacket->ActualLength + + HTC_HDR_LENGTH); + status = hif_send_head(target->hif_dev, pEndpoint->UL_PipeID, pEndpoint->Id, HTC_HDR_LENGTH + pPacket->ActualLength, netbuf, data_attr); + if (status != QDF_STATUS_SUCCESS) { + if (pEndpoint->EpCallBacks.ep_padding_credit_update) { + if (used_extra_tx_credit) { + pEndpoint->EpCallBacks. + ep_padding_credit_update + (pEndpoint->EpCallBacks.pContext, 1); + } + } + } #if DEBUG_BUNDLE qdf_print(" Send single EP%d buffer size:0x%x, total:0x%x.", pEndpoint->Id, @@ -2349,7 +2699,7 @@ void htc_process_credit_rpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, htc_try_send(target, pEndpoint, NULL); #else if (pEndpoint->service_id == HTT_DATA_MSG_SVC) - htc_send_data_pkt(target, NULL, 0); + htc_send_data_pkt((HTC_HANDLE)target, NULL, 0); else htc_try_send(target, pEndpoint, NULL); #endif @@ -2374,3 +2724,24 @@ struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE HTCHandle) return &(target->htc_pkt_stats); } + +#ifdef SYSTEM_PM_CHECK +void htc_system_resume(HTC_HANDLE htc) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc); + HTC_ENDPOINT *endpoint = NULL; + int i; + + if (!target) + return; + + for (i = 0; i < ENDPOINT_MAX; i++) { + endpoint = &target->endpoint[i]; + + if (endpoint->service_id == 0) + continue; + + htc_try_send(target, endpoint, NULL); + } +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/init_deinit/dispatcher/src/dispatcher_init_deinit.c b/drivers/staging/qca-wifi-host-cmn/init_deinit/dispatcher/src/dispatcher_init_deinit.c index 2c7f972c92612f9ca6d7124427b4633a2e1fbdf0..b06da00f509a49930e2aef3a572f357faf4a1f12 100644 --- a/drivers/staging/qca-wifi-host-cmn/init_deinit/dispatcher/src/dispatcher_init_deinit.c +++ b/drivers/staging/qca-wifi-host-cmn/init_deinit/dispatcher/src/dispatcher_init_deinit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -72,6 +72,12 @@ #include #endif +#ifdef FEATURE_COEX +#include +#endif + +#include + /** * DOC: This file provides various init/deinit trigger point for new * components. @@ -252,12 +258,6 @@ static QDF_STATUS dispatcher_regulatory_psoc_close(struct wlan_objmgr_psoc return regulatory_psoc_close(psoc); } -static QDF_STATUS dispatcher_regulatory_pdev_open(struct wlan_objmgr_pdev - *pdev) -{ - return regulatory_pdev_open(pdev); -} - #if defined(WLAN_CONV_SPECTRAL_ENABLE) && defined(SPECTRAL_MODULIZED_ENABLE) QDF_STATUS dispatcher_register_spectral_pdev_open_handler( spectral_pdev_open_handler handler) @@ -291,6 +291,12 @@ static QDF_STATUS dispatcher_spectral_pdev_close(struct wlan_objmgr_pdev *pdev) } #endif +static QDF_STATUS dispatcher_regulatory_pdev_open(struct wlan_objmgr_pdev + *pdev) +{ + return regulatory_pdev_open(pdev); +} + static QDF_STATUS dispatcher_regulatory_pdev_close(struct wlan_objmgr_pdev *pdev) { @@ -412,6 +418,16 @@ static QDF_STATUS dispatcher_deinit_crypto(void) { return wlan_crypto_deinit(); } + +static QDF_STATUS dispatcher_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_crypto_psoc_enable(psoc); +} + +static QDF_STATUS dispatcher_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_crypto_psoc_disable(psoc); +} #else static QDF_STATUS dispatcher_init_crypto(void) { @@ -422,6 +438,16 @@ static QDF_STATUS dispatcher_deinit_crypto(void) { return QDF_STATUS_SUCCESS; } + +static QDF_STATUS dispatcher_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dispatcher_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} #endif /* END of WLAN_CONV_CRYPTO_SUPPORTED */ #ifdef WIFI_POS_CONVERGED @@ -707,6 +733,50 @@ static QDF_STATUS fd_psoc_disable(struct wlan_objmgr_psoc *psoc) } #endif /* WLAN_SUPPORT_FILS */ +#ifdef FEATURE_COEX +static QDF_STATUS dispatcher_coex_init(void) +{ + return wlan_coex_init(); +} + +static QDF_STATUS dispatcher_coex_deinit(void) +{ + return wlan_coex_deinit(); +} + +static QDF_STATUS dispatcher_coex_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + return wlan_coex_psoc_open(psoc); +} + +static QDF_STATUS dispatcher_coex_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + return wlan_coex_psoc_close(psoc); +} +#else +static inline QDF_STATUS dispatcher_coex_init(void) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS dispatcher_coex_deinit(void) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +dispatcher_coex_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +dispatcher_coex_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* FEATURE_COEX */ + QDF_STATUS dispatcher_init(void) { if (QDF_STATUS_SUCCESS != wlan_objmgr_global_obj_init()) @@ -772,6 +842,12 @@ QDF_STATUS dispatcher_init(void) if (QDF_STATUS_SUCCESS != dispatcher_init_cfr()) goto cfr_init_fail; + if (QDF_STATUS_SUCCESS != dispatcher_coex_init()) + goto coex_init_fail; + + if (QDF_STATUS_SUCCESS != wlan_gpio_init()) + goto gpio_init_fail; + /* * scheduler INIT has to be the last as each component's * initialization has to happen first and then at the end @@ -783,6 +859,10 @@ QDF_STATUS dispatcher_init(void) return QDF_STATUS_SUCCESS; scheduler_init_fail: + wlan_gpio_deinit(); +gpio_init_fail: + dispatcher_coex_deinit(); +coex_init_fail: dispatcher_deinit_cfr(); cfr_init_fail: wlan_cmn_mlme_deinit(); @@ -836,6 +916,10 @@ QDF_STATUS dispatcher_deinit(void) QDF_BUG(QDF_STATUS_SUCCESS == scheduler_deinit()); + QDF_BUG(QDF_STATUS_SUCCESS == wlan_gpio_deinit()); + + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_coex_deinit()); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_deinit_cfr()); QDF_BUG(QDF_STATUS_SUCCESS == wlan_cmn_mlme_deinit()); @@ -924,8 +1008,13 @@ QDF_STATUS dispatcher_psoc_open(struct wlan_objmgr_psoc *psoc) if (QDF_STATUS_SUCCESS != dispatcher_ftm_psoc_open(psoc)) goto ftm_psoc_open_fail; + if (QDF_STATUS_SUCCESS != dispatcher_coex_psoc_open(psoc)) + goto coex_psoc_open_fail; + return QDF_STATUS_SUCCESS; +coex_psoc_open_fail: + dispatcher_ftm_psoc_close(psoc); ftm_psoc_open_fail: son_psoc_close(psoc); psoc_son_fail: @@ -946,6 +1035,8 @@ qdf_export_symbol(dispatcher_psoc_open); QDF_STATUS dispatcher_psoc_close(struct wlan_objmgr_psoc *psoc) { + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_coex_psoc_close(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_ftm_psoc_close(psoc)); QDF_BUG(QDF_STATUS_SUCCESS == son_psoc_close(psoc)); @@ -993,12 +1084,17 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc) if (QDF_STATUS_SUCCESS != dispatcher_dbr_psoc_enable(psoc)) goto dbr_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != dispatcher_crypto_psoc_enable(psoc)) + goto crypto_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != wlan_mlme_psoc_enable(psoc)) goto mlme_psoc_enable_fail; return QDF_STATUS_SUCCESS; mlme_psoc_enable_fail: + dispatcher_crypto_psoc_disable(psoc); +crypto_psoc_enable_fail: dispatcher_dbr_psoc_disable(psoc); dbr_psoc_enable_fail: fd_psoc_disable(psoc); @@ -1025,6 +1121,8 @@ QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc) { QDF_BUG(QDF_STATUS_SUCCESS == wlan_mlme_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_crypto_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_dbr_psoc_disable(psoc)); QDF_BUG(QDF_STATUS_SUCCESS == fd_psoc_disable(psoc)); @@ -1078,6 +1176,7 @@ QDF_STATUS dispatcher_pdev_open(struct wlan_objmgr_pdev *pdev) spectral_pdev_open_fail: dispatcher_regulatory_pdev_close(pdev); regulatory_pdev_open_fail: + return QDF_STATUS_E_FAILURE; } qdf_export_symbol(dispatcher_pdev_open); diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/inc/wlan_cfg80211_coex.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/inc/wlan_cfg80211_coex.h new file mode 100644 index 0000000000000000000000000000000000000000..cd3e6bd43240249608e994fdd3dda8edcc310701 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/inc/wlan_cfg80211_coex.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: declares driver functions interfacing with linux kernel + */ + +#ifndef _WLAN_CFG80211_COEX_H_ +#define _WLAN_CFG80211_COEX_H_ +#include +#include + +#ifdef FEATURE_COEX +int wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev, + const void *data, int data_len); +#else +static inline int +wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev, + const void *data, int data_len) +{ + return -ENOTSUPP; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/src/wlan_cfg80211_coex.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/src/wlan_cfg80211_coex.c new file mode 100644 index 0000000000000000000000000000000000000000..754b16796e48947850d595d64e169ab0042b783e --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/coex/src/wlan_cfg80211_coex.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: defines driver functions interfacing with linux kernel + */ +#include +#include +#include +#include +#include +#include +#include + +static const struct nla_policy +btc_chain_mode_policy[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX + 1] = { + [QCA_VENDOR_ATTR_BTC_CHAIN_MODE] = {.type = NLA_U32}, + [QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART] = {.type = NLA_FLAG}, +}; + +static int +__wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev, + uint8_t mode, bool do_restart) +{ + QDF_STATUS status; + uint8_t cur_mode; + int err; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev_tmp; + int vdev_id; + struct coex_psoc_obj *coex_obj; + + if (!vdev) { + coex_err("Null vdev"); + return -EINVAL; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + coex_err("NULL psoc"); + return -EINVAL; + } + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return -EINVAL; + + status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &cur_mode); + if (QDF_IS_STATUS_ERROR(status)) { + coex_err("failed to get cur BTC chain mode, status %d", status); + return -EFAULT; + } + + if (cur_mode == mode) + return -EALREADY; + + status = ucfg_coex_psoc_set_btc_chain_mode(psoc, mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + coex_err("unable to set BTC chain mode to %d", mode); + return -EFAULT; + } + + wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev_tmp) { + status = ucfg_coex_send_btc_chain_mode(vdev, mode); + err = qdf_status_to_os_return(status); + if (err) { + coex_err("Failed to set btc chain mode to %d for vdev %d", + mode, vdev_id); + return err; + } + coex_debug("Set btc chain mode to %d for vdev %d", + mode, vdev_id); + + if (!do_restart) + continue; + + wlan_coex_config_updated(vdev, COEX_CONFIG_BTC_CHAIN_MODE); + } + + return 0; +} + +/** + * wlan_hdd_cfg80211_set_btc_chain_mode() - set btc chain mode + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to btc chain mode command parameters. + * @data_len: the length in byte of btc chain mode command parameters. + * + * Return: An error code or 0 on success. + */ +int wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev, + const void *data, int data_len) +{ + struct nlattr *tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX + 1]; + uint32_t mode; + bool restart; + + if (wlan_cfg80211_nla_parse(tb, QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX, + data, data_len, btc_chain_mode_policy)) { + coex_err("Invalid btc chain mode ATTR"); + return -EINVAL; + } + + if (!tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE]) { + coex_err("btc chain mode - no attr mode"); + return -EINVAL; + } + + mode = nla_get_u32(tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE]); + if (mode < QCA_BTC_CHAIN_SHARED || mode > QCA_BTC_CHAIN_SEPARATED) { + coex_err("Invalid btc chain mode %d", mode); + return -EINVAL; + } + + restart = nla_get_flag(tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART]); + + coex_debug("vdev_id %u mode %u restart %u", + wlan_vdev_get_id(vdev), mode, restart); + + return __wlan_cfg80211_coex_set_btc_chain_mode(vdev, mode, restart); +} diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h index 23d370d023095d31318251e04e67be675ca61e61..9b44112c80e4a76799c1e3762da25420f2519508 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -52,6 +52,21 @@ int wlan_cfg80211_mc_cp_stats_get_wakelock_stats(struct wlan_objmgr_psoc *psoc, */ int wlan_cfg80211_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, int *dbm); +#ifdef WLAN_FEATURE_MIB_STATS +/** + * wlan_cfg80211_mc_cp_stats_get_mib_stats() - API to get mib stats + * statistics from firmware + * @vdev: Pointer to vdev + * @errno: error type in case of failure + * + * Callers of this API must call wlan_cfg80211_mc_cp_stats_free_stats_event + * API. + * Return: stats buffer on success, Null on failure + */ +struct stats_event * +wlan_cfg80211_mc_cp_stats_get_mib_stats(struct wlan_objmgr_vdev *vdev, + int *errno); +#endif /** * wlan_cfg80211_mc_cp_stats_get_station_stats() - API to get station diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_ic_cp_stats.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_ic_cp_stats.c index 4dcc0d5c8cdcb65189691e5617dc3c2959e27f92..df38bb1ad8f7b90b1cb689e6ab482a2acee4e704 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_ic_cp_stats.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_ic_cp_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,19 +32,19 @@ int wlan_cfg80211_get_peer_cp_stats(struct wlan_objmgr_peer *peer_obj, QDF_STATUS status; if (!peer_obj) { - cfg80211_err("Invalid input, peer obj NULL"); + osif_err("Invalid input, peer obj NULL"); return -EINVAL; } if (!peer_cp_stats) { - cfg80211_err("Invalid input, peer cp obj is NULL"); + osif_err("Invalid input, peer cp obj is NULL"); return -EINVAL; } status = wlan_ucfg_get_peer_cp_stats(peer_obj, peer_cp_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_peer_cp_stats status: %d", - status); + osif_err("wlan_cfg80211_get_peer_cp_stats status: %d", + status); } return qdf_status_to_os_return(status); @@ -56,19 +56,19 @@ int wlan_cfg80211_get_vdev_cp_stats(struct wlan_objmgr_vdev *vdev_obj, QDF_STATUS status; if (!vdev_obj) { - cfg80211_err("Invalid input, vdev obj is NULL"); + osif_err("Invalid input, vdev obj is NULL"); return -EINVAL; } if (!vdev_cp_stats) { - cfg80211_err("Invalid input, vdev cp obj is NULL"); + osif_err("Invalid input, vdev cp obj is NULL"); return -EINVAL; } status = wlan_ucfg_get_vdev_cp_stats(vdev_obj, vdev_cp_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_vdev_cp_stats status: %d", - status); + osif_err("wlan_cfg80211_get_vdev_cp_stats status: %d", + status); } return qdf_status_to_os_return(status); @@ -80,19 +80,19 @@ int wlan_cfg80211_get_pdev_cp_stats(struct wlan_objmgr_pdev *pdev_obj, QDF_STATUS status; if (!pdev_obj) { - cfg80211_err("Invalid input, pdev obj is NULL"); + osif_err("Invalid input, pdev obj is NULL"); return -EINVAL; } if (!pdev_cp_stats) { - cfg80211_err("Invalid input, pdev cp obj is NULL"); + osif_err("Invalid input, pdev cp obj is NULL"); return -EINVAL; } status = wlan_ucfg_get_pdev_cp_stats(pdev_obj, pdev_cp_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_pdev_cp_stats status: %d", - status); + osif_err("wlan_cfg80211_get_pdev_cp_stats status: %d", + status); } return qdf_status_to_os_return(status); @@ -108,19 +108,19 @@ wlan_cfg80211_get_atf_peer_cp_stats(struct wlan_objmgr_peer *peer_obj, QDF_STATUS status; if (!peer_obj) { - cfg80211_err("Invalid input, peer obj is NULL"); + osif_err("Invalid input, peer obj is NULL"); return -EINVAL; } if (!atf_cp_stats) { - cfg80211_err("Invalid input, ATF peer cp obj is NULL!"); + osif_err("Invalid input, ATF peer cp obj is NULL!"); return -EINVAL; } status = wlan_ucfg_get_atf_peer_cp_stats(peer_obj, atf_cp_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_atf_peer_cp_stats status: %d", - status); + osif_err("wlan_cfg80211_get_atf_peer_cp_stats status: %d", + status); } return qdf_status_to_os_return(status); @@ -134,25 +134,25 @@ int wlan_cfg80211_get_atf_peer_cp_stats_from_mac( QDF_STATUS status; if (!vdev_obj) { - cfg80211_err("Invalid input, vdev obj is NULL"); + osif_err("Invalid input, vdev obj is NULL"); return -EINVAL; } if (!mac) { - cfg80211_err("Invalid input, peer mac is NULL"); + osif_err("Invalid input, peer mac is NULL"); return -EINVAL; } if (!atf_cp_stats) { - cfg80211_err("Invalid input, ATF peer cp stats obj is NULL"); + osif_err("Invalid input, ATF peer cp stats obj is NULL"); return -EINVAL; } status = wlan_ucfg_get_atf_peer_cp_stats_from_mac(vdev_obj, mac, atf_cp_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_cp_stats_from_mac status: %d", - status); + osif_err("wlan_cfg80211_get_cp_stats_from_mac status: %d", + status); } return qdf_status_to_os_return(status); @@ -166,19 +166,19 @@ wlan_cfg80211_get_dcs_pdev_cp_stats(struct wlan_objmgr_pdev *pdev_obj, QDF_STATUS status; if (!pdev_obj) { - cfg80211_err("Invalid input, pdev obj is NULL"); + osif_err("Invalid input, pdev obj is NULL"); return -EINVAL; } if (!dcs_chan_stats) { - cfg80211_err("Invalid input, dcs chan stats is NULL"); + osif_err("Invalid input, dcs chan stats is NULL"); return -EINVAL; } status = wlan_ucfg_get_dcs_chan_stats(pdev_obj, dcs_chan_stats); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_cfg80211_get_dcs_pdev_cp_stats status: %d", - status); + osif_err("wlan_cfg80211_get_dcs_pdev_cp_stats status: %d", + status); } return qdf_status_to_os_return(status); diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c index 4d94947b1eca8f2623315d137f828389f4f60ea7..81eb1efd6aa97bcef47ebd0b5621f4e3824e348c 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,6 +32,24 @@ /* max time in ms, caller may wait for stats request get serviced */ #define CP_STATS_WAIT_TIME_STAT 800 +#ifdef WLAN_FEATURE_MIB_STATS +/** + * wlan_free_mib_stats() - free allocations for mib stats + * @stats: Pointer to stats event statucture + * + * Return: None + */ +static void wlan_free_mib_stats(struct stats_event *stats) +{ + qdf_mem_free(stats->mib_stats); + stats->mib_stats = NULL; +} +#else +static void wlan_free_mib_stats(struct stats_event *stats) +{ +} +#endif + /** * wlan_cfg80211_mc_cp_stats_dealloc() - callback to free priv * allocations for stats @@ -44,7 +62,7 @@ static void wlan_cfg80211_mc_cp_stats_dealloc(void *priv) struct stats_event *stats = priv; if (!stats) { - cfg80211_err("stats is NULL"); + osif_err("stats is NULL"); return; } @@ -54,6 +72,7 @@ static void wlan_cfg80211_mc_cp_stats_dealloc(void *priv) qdf_mem_free(stats->vdev_summary_stats); qdf_mem_free(stats->vdev_chain_rssi); qdf_mem_free(stats->peer_adv_stats); + wlan_free_mib_stats(stats); } /** @@ -76,41 +95,41 @@ static int wlan_cfg80211_mc_cp_stats_send_wake_lock_stats(struct wiphy *wiphy, nl_buf_len += QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX * (NLMSG_HDRLEN + sizeof(uint32_t)); - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len); + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len); if (!skb) { - cfg80211_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); + osif_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); return -ENOMEM; } - cfg80211_debug("wow_ucast_wake_up_count %d", - stats->ucast_wake_up_count); - cfg80211_debug("wow_bcast_wake_up_count %d", - stats->bcast_wake_up_count); - cfg80211_debug("wow_ipv4_mcast_wake_up_count %d", - stats->ipv4_mcast_wake_up_count); - cfg80211_debug("wow_ipv6_mcast_wake_up_count %d", - stats->ipv6_mcast_wake_up_count); - cfg80211_debug("wow_ipv6_mcast_ra_stats %d", - stats->ipv6_mcast_ra_stats); - cfg80211_debug("wow_ipv6_mcast_ns_stats %d", - stats->ipv6_mcast_ns_stats); - cfg80211_debug("wow_ipv6_mcast_na_stats %d", - stats->ipv6_mcast_na_stats); - cfg80211_debug("wow_icmpv4_count %d", - stats->icmpv4_count); - cfg80211_debug("wow_icmpv6_count %d", - stats->icmpv6_count); - cfg80211_debug("wow_rssi_breach_wake_up_count %d", - stats->rssi_breach_wake_up_count); - cfg80211_debug("wow_low_rssi_wake_up_count %d", - stats->low_rssi_wake_up_count); - cfg80211_debug("wow_gscan_wake_up_count %d", - stats->gscan_wake_up_count); - cfg80211_debug("wow_pno_complete_wake_up_count %d", - stats->pno_complete_wake_up_count); - cfg80211_debug("wow_pno_match_wake_up_count %d", - stats->pno_match_wake_up_count); + osif_debug("wow_ucast_wake_up_count %d", + stats->ucast_wake_up_count); + osif_debug("wow_bcast_wake_up_count %d", + stats->bcast_wake_up_count); + osif_debug("wow_ipv4_mcast_wake_up_count %d", + stats->ipv4_mcast_wake_up_count); + osif_debug("wow_ipv6_mcast_wake_up_count %d", + stats->ipv6_mcast_wake_up_count); + osif_debug("wow_ipv6_mcast_ra_stats %d", + stats->ipv6_mcast_ra_stats); + osif_debug("wow_ipv6_mcast_ns_stats %d", + stats->ipv6_mcast_ns_stats); + osif_debug("wow_ipv6_mcast_na_stats %d", + stats->ipv6_mcast_na_stats); + osif_debug("wow_icmpv4_count %d", + stats->icmpv4_count); + osif_debug("wow_icmpv6_count %d", + stats->icmpv6_count); + osif_debug("wow_rssi_breach_wake_up_count %d", + stats->rssi_breach_wake_up_count); + osif_debug("wow_low_rssi_wake_up_count %d", + stats->low_rssi_wake_up_count); + osif_debug("wow_gscan_wake_up_count %d", + stats->gscan_wake_up_count); + osif_debug("wow_pno_complete_wake_up_count %d", + stats->pno_complete_wake_up_count); + osif_debug("wow_pno_match_wake_up_count %d", + stats->pno_match_wake_up_count); ipv6_rx_multicast_addr_cnt = stats->ipv6_mcast_wake_up_count; icmpv6_cnt = stats->icmpv6_count; @@ -176,15 +195,15 @@ static int wlan_cfg80211_mc_cp_stats_send_wake_lock_stats(struct wiphy *wiphy, nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_PNO_MATCH_CNT, stats->pno_match_wake_up_count)) { - cfg80211_err("nla put fail"); + osif_err("nla put fail"); goto nla_put_failure; } - cfg80211_vendor_cmd_reply(skb); + wlan_cfg80211_vendor_cmd_reply(skb); return 0; nla_put_failure: - kfree_skb(skb); + wlan_cfg80211_vendor_free_skb(skb); return -EINVAL; } @@ -220,7 +239,7 @@ static void get_tx_power_cb(int tx_power, void *cookie) request = osif_request_get(cookie); if (!request) { - cfg80211_err("Obsolete request"); + osif_err("Obsolete request"); return; } @@ -247,7 +266,7 @@ int wlan_cfg80211_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, request = osif_request_alloc(¶ms); if (!request) { - cfg80211_err("Request allocation failure, return cached value"); + osif_err("Request allocation failure, return cached value"); goto fetch_tx_power; } @@ -269,13 +288,13 @@ int wlan_cfg80211_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, TYPE_CONNECTION_TX_POWER, &info); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("wlan_mc_cp_stats_request_tx_power status: %d", - status); + osif_err("wlan_mc_cp_stats_request_tx_power status: %d", + status); ret = qdf_status_to_os_return(status); } else { ret = osif_request_wait_for_response(request); if (ret) - cfg80211_err("wait failed or timed out ret: %d", ret); + osif_err("wait failed or timed out ret: %d", ret); else priv = osif_request_priv(request); } @@ -286,8 +305,8 @@ int wlan_cfg80211_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, } else { status = ucfg_mc_cp_stats_get_tx_power(vdev, dbm); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_mc_cp_stats_get_tx_power status: %d", - status); + osif_err("ucfg_mc_cp_stats_get_tx_power status: %d", + status); ret = qdf_status_to_os_return(status); } } @@ -319,14 +338,14 @@ static void get_peer_rssi_cb(struct stats_event *ev, void *cookie) request = osif_request_get(cookie); if (!request) { - cfg80211_err("Obsolete request"); + osif_err("Obsolete request"); return; } priv = osif_request_priv(request); rssi_size = sizeof(*ev->peer_stats) * ev->num_peer_stats; if (rssi_size == 0) { - cfg80211_err("Invalid rssi stats"); + osif_err("Invalid rssi stats"); goto get_peer_rssi_cb_fail; } @@ -366,7 +385,7 @@ wlan_cfg80211_mc_cp_stats_get_peer_rssi(struct wlan_objmgr_vdev *vdev, request = osif_request_alloc(¶ms); if (!request) { - cfg80211_err("Request allocation failure, return cached value"); + osif_err("Request allocation failure, return cached value"); *errno = -ENOMEM; qdf_mem_free(out); return NULL; @@ -382,20 +401,20 @@ wlan_cfg80211_mc_cp_stats_get_peer_rssi(struct wlan_objmgr_vdev *vdev, status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_PEER_STATS, &info); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("stats req failed: %d", status); + osif_err("stats req failed: %d", status); *errno = qdf_status_to_os_return(status); goto get_peer_rssi_fail; } *errno = osif_request_wait_for_response(request); if (*errno) { - cfg80211_err("wait failed or timed out ret: %d", *errno); + osif_err("wait failed or timed out ret: %d", *errno); goto get_peer_rssi_fail; } if (!priv->peer_stats || priv->num_peer_stats == 0) { - cfg80211_err("Invalid peer stats, count %d, data %pK", - priv->num_peer_stats, priv->peer_stats); + osif_err("Invalid peer stats, count %d, data %pK", + priv->num_peer_stats, priv->peer_stats); *errno = -EINVAL; goto get_peer_rssi_fail; } @@ -428,7 +447,7 @@ static void get_station_stats_cb(struct stats_event *ev, void *cookie) request = osif_request_get(cookie); if (!request) { - cfg80211_err("Obsolete request"); + osif_err("Obsolete request"); return; } @@ -438,8 +457,14 @@ static void get_station_stats_cb(struct stats_event *ev, void *cookie) peer_adv_size = sizeof(*ev->peer_adv_stats) * ev->num_peer_adv_stats; if (summary_size == 0 || rssi_size == 0) { - cfg80211_err("Invalid stats, summary %d rssi %d", - summary_size, rssi_size); + osif_err("Invalid stats, summary %d rssi %d", + summary_size, rssi_size); + goto station_stats_cb_fail; + } + if (priv->vdev_summary_stats || priv->vdev_chain_rssi || + priv->peer_adv_stats) { + osif_err("invalid context cookie %pK request %pK", + cookie, request); goto station_stats_cb_fail; } @@ -491,7 +516,7 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev, .dealloc = wlan_cfg80211_mc_cp_stats_dealloc, }; - cfg80211_debug("Enter"); + osif_debug("Enter"); out = qdf_mem_malloc(sizeof(*out)); if (!out) { @@ -514,7 +539,7 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev, info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)); peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_CP_STATS_ID); if (!peer) { - cfg80211_err("peer is null"); + osif_err("peer is null"); *errno = -EINVAL; goto get_station_stats_fail; } @@ -525,23 +550,23 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev, status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_STATION_STATS, &info); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Failed to send stats request status: %d", status); + osif_err("Failed to send stats request status: %d", status); *errno = qdf_status_to_os_return(status); goto get_station_stats_fail; } *errno = osif_request_wait_for_response(request); if (*errno) { - cfg80211_err("wait failed or timed out ret: %d", *errno); + osif_err("wait failed or timed out ret: %d", *errno); goto get_station_stats_fail; } if (!priv->vdev_summary_stats || !priv->vdev_chain_rssi || priv->num_summary_stats == 0 || priv->num_chain_rssi_stats == 0) { - cfg80211_err("Invalid stats"); - cfg80211_err("summary %d:%pK, rssi %d:%pK", - priv->num_summary_stats, priv->vdev_summary_stats, - priv->num_chain_rssi_stats, priv->vdev_chain_rssi); + osif_err("Invalid stats"); + osif_err("summary %d:%pK, rssi %d:%pK", + priv->num_summary_stats, priv->vdev_summary_stats, + priv->num_chain_rssi_stats, priv->vdev_chain_rssi); *errno = -EINVAL; goto get_station_stats_fail; } @@ -561,7 +586,7 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev, priv->peer_adv_stats = NULL; osif_request_put(request); - cfg80211_debug("Exit"); + osif_debug("Exit"); return out; @@ -569,10 +594,129 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev, osif_request_put(request); wlan_cfg80211_mc_cp_stats_free_stats_event(out); - cfg80211_debug("Exit"); + osif_debug("Exit"); + + return NULL; +} + +#ifdef WLAN_FEATURE_MIB_STATS +/** + * get_mib_stats_cb() - get mib stats from fw callback function + * @ev: mib stats buffer + * @cookie: a cookie for the request context + * + * Return: None + */ +static void get_mib_stats_cb(struct stats_event *ev, void *cookie) +{ + struct stats_event *priv; + struct osif_request *request; + + request = osif_request_get(cookie); + if (!request) { + osif_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + + priv->mib_stats = qdf_mem_malloc(sizeof(*ev->mib_stats)); + if (!priv->mib_stats) + goto get_mib_stats_cb_fail; + + priv->num_mib_stats = ev->num_mib_stats; + qdf_mem_copy(priv->mib_stats, ev->mib_stats, sizeof(*ev->mib_stats)); + +get_mib_stats_cb_fail: + osif_request_complete(request); + osif_request_put(request); +} + +struct stats_event * +wlan_cfg80211_mc_cp_stats_get_mib_stats(struct wlan_objmgr_vdev *vdev, + int *errno) +{ + void *cookie; + QDF_STATUS status; + struct stats_event *priv, *out; + struct wlan_objmgr_peer *peer; + struct osif_request *request; + struct request_info info = {0}; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = 2 * CP_STATS_WAIT_TIME_STAT, + .dealloc = wlan_cfg80211_mc_cp_stats_dealloc, + }; + + out = qdf_mem_malloc(sizeof(*out)); + if (!out) { + *errno = -ENOMEM; + return NULL; + } + + request = osif_request_alloc(¶ms); + if (!request) { + qdf_mem_free(out); + *errno = -ENOMEM; + return NULL; + } + + cookie = osif_request_cookie(request); + priv = osif_request_priv(request); + info.cookie = cookie; + info.u.get_mib_stats_cb = get_mib_stats_cb; + info.vdev_id = wlan_vdev_get_id(vdev); + info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)); + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_CP_STATS_ID); + if (!peer) { + osif_err("peer is null"); + *errno = -EINVAL; + goto get_mib_stats_fail; + } + qdf_mem_copy(info.peer_mac_addr, peer->macaddr, QDF_MAC_ADDR_SIZE); + + osif_debug("vdev id %d, pdev id %d, peer " QDF_MAC_ADDR_FMT, + info.vdev_id, info.pdev_id, + QDF_MAC_ADDR_REF(info.peer_mac_addr)); + + wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); + + status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_MIB_STATS, + &info); + if (QDF_IS_STATUS_ERROR(status)) { + osif_err("Failed to send stats request status: %d", status); + *errno = qdf_status_to_os_return(status); + goto get_mib_stats_fail; + } + + *errno = osif_request_wait_for_response(request); + if (*errno) { + osif_err("wait failed or timed out ret: %d", *errno); + goto get_mib_stats_fail; + } + + if (!priv->mib_stats || priv->num_mib_stats == 0 ) { + osif_err("Invalid mib stats %d:%pK", + priv->num_mib_stats, priv->mib_stats); + *errno = -EINVAL; + goto get_mib_stats_fail; + } + + out->num_mib_stats = priv->num_mib_stats; + out->mib_stats = priv->mib_stats; + priv->mib_stats = NULL; + + osif_request_put(request); + + return out; + +get_mib_stats_fail: + osif_request_put(request); + wlan_cfg80211_mc_cp_stats_free_stats_event(out); return NULL; } +#endif void wlan_cfg80211_mc_cp_stats_free_stats_event(struct stats_event *stats) { @@ -585,5 +729,6 @@ void wlan_cfg80211_mc_cp_stats_free_stats_event(struct stats_event *stats) qdf_mem_free(stats->vdev_summary_stats); qdf_mem_free(stats->vdev_chain_rssi); qdf_mem_free(stats->peer_adv_stats); + wlan_free_mib_stats(stats); qdf_mem_free(stats); } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h index 1f4e8df2a253f3eedb2f119dcf2231fc5d636a4f..18ad13aa8e7fec52d0b77a7f1f7249edd27f3542 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_cfg80211_crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019,2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -65,10 +65,12 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, * @vdev: vdev object * @key_type: denotes if the add key request is for pairwise or group key * @key_index: Index of the key that needs to be added + * @sync: flag to indicate whether or not to add key synchronously. + * DO NOT set to true if it's in scheduler context. * * Return: Zero on Success, negative value on failure */ int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, enum wlan_crypto_key_type key_type, - uint8_t key_index); + uint8_t key_index, bool sync); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_nl_to_crypto_params.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_nl_to_crypto_params.h index 58e44c21f44aa748ddeb7bfd78b6fd046d653591..c557394256311ce81471fc7f0a13319ed7de5796 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_nl_to_crypto_params.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/inc/wlan_nl_to_crypto_params.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,9 +30,10 @@ * set the crypto auth type for corresponding auth type received * from NL * - * Return: crypto auth type, negative value for failure + * Return: crypto auth type */ -int osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type); +wlan_crypto_auth_mode +osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type); /** * osif_nl_to_crypto_akm_type() - populate akm type for crypto @@ -41,9 +42,9 @@ int osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type); * set the crypto akm type for corresponding akm type received * from NL * - * Return: crypto akm type, negative value for failure + * Return: crypto akm type */ -int osif_nl_to_crypto_akm_type(u32 key_mgmt); +wlan_crypto_key_mgmt osif_nl_to_crypto_akm_type(u32 key_mgmt); /** * osif_nl_to_crypto_cipher_type() - populate cipher type for crypto diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_cfg80211_crypto.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_cfg80211_crypto.c index c059cf146e93334df593b57dec5e077dd684a357..02085d287726e647ce30e614ea86bbdb7604c07a 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_cfg80211_crypto.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_cfg80211_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,10 +23,15 @@ #include #include #include +#include +#include +#include +#include #include #include #include "wlan_cfg80211_crypto.h" #include +#include static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, uint8_t key_index, @@ -38,9 +43,9 @@ static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, qdf_mem_zero(crypto_key, sizeof(*crypto_key)); crypto_key->keylen = params->key_len; crypto_key->keyix = key_index; - cfg80211_debug("key_type %d, opmode %d, key_len %d, seq_len %d", - key_type, vdev->vdev_mlme.vdev_opmode, - params->key_len, params->seq_len); + osif_debug("key_type %d, opmode %d, key_len %d, seq_len %d", + key_type, vdev->vdev_mlme.vdev_opmode, + params->key_len, params->seq_len); qdf_mem_copy(&crypto_key->keyval[0], params->key, params->key_len); qdf_mem_copy(&crypto_key->keyrsc[0], params->seq, params->seq_len); @@ -52,7 +57,7 @@ static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, * but since we did not connect yet, so we do not know the peer * address yet. */ - cfg80211_debug("No Mac Address to copy"); + osif_debug("No Mac Address to copy"); return; } if (key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) { @@ -67,7 +72,8 @@ static void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev, vdev->vdev_mlme.macaddr, QDF_MAC_ADDR_SIZE); } - cfg80211_debug("mac %pM", crypto_key->macaddr); + osif_debug("mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(crypto_key->macaddr)); } int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, @@ -81,24 +87,24 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev) { - cfg80211_err("vdev is NULL"); + osif_err("vdev is NULL"); return -EINVAL; } if (!params) { - cfg80211_err("Key params is NULL"); + osif_err("Key params is NULL"); return -EINVAL; } cipher_len = osif_nl_to_crypto_cipher_len(params->cipher); if (cipher_len < 0 || params->key_len < cipher_len) { - cfg80211_err("cipher length %d less than reqd len %d", - params->key_len, cipher_len); + osif_err("cipher length %d less than reqd len %d", + params->key_len, cipher_len); return -EINVAL; } cipher = osif_nl_to_crypto_cipher_type(params->cipher); if (!IS_WEP_CIPHER(cipher)) { if ((key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) && !mac_addr) { - cfg80211_err("mac_addr is NULL for pairwise Key"); + osif_err("mac_addr is NULL for pairwise Key"); return -EINVAL; } } @@ -106,7 +112,7 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, params->key_len, params->seq_len); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Invalid key params"); + osif_err("Invalid key params"); return -EINVAL; } @@ -119,33 +125,97 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev, crypto_key = qdf_mem_malloc(sizeof(*crypto_key)); if (!crypto_key) return -EINVAL; - status = wlan_crypto_save_key(vdev, key_index, crypto_key); - if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Failed to save key"); - qdf_mem_free(crypto_key); - return -EINVAL; - } } wlan_cfg80211_translate_key(vdev, key_index, key_type, mac_addr, params, crypto_key); + status = wlan_crypto_save_key(vdev, key_index, crypto_key); + if (QDF_IS_STATUS_ERROR(status)) { + osif_err("Failed to save key"); + qdf_mem_free(crypto_key); + return -EINVAL; + } return 0; } +#define WLAN_WAIT_TIME_ADD_KEY 100 + +static void +wlan_cfg80211_crypto_add_key_cb(void *context, + struct crypto_add_key_result *result) +{ + struct osif_request *request; + struct crypto_add_key_result *priv; + + request = osif_request_get(context); + if (!request) { + osif_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + qdf_mem_copy(priv, result, sizeof(*priv)); + osif_request_complete(request); + osif_request_put(request); +} + int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, enum wlan_crypto_key_type key_type, - uint8_t key_index) + uint8_t key_index, bool sync) { struct wlan_crypto_key *crypto_key; QDF_STATUS status; + struct osif_request *request; + struct crypto_add_key_result *result; + struct wlan_crypto_comp_priv *priv; + int ret; + static const struct osif_request_params params = { + .priv_size = sizeof(*result), + .timeout_ms = WLAN_WAIT_TIME_ADD_KEY, + }; crypto_key = wlan_crypto_get_key(vdev, key_index); if (!crypto_key) { - cfg80211_err("Crypto KEY is NULL"); + osif_err("Crypto KEY is NULL"); return -EINVAL; } - status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + + if (sync) { + priv = wlan_get_vdev_crypto_obj(vdev); + if (!priv) { + osif_err("Invalid crypto_priv"); + return -EINVAL; + } + + request = osif_request_alloc(¶ms); + if (!request) { + osif_err("Request allocation failure"); + return -ENOMEM; + } + + priv->add_key_ctx = osif_request_cookie(request);; + priv->add_key_cb = wlan_cfg80211_crypto_add_key_cb; + + status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + if (QDF_IS_STATUS_SUCCESS(status)) { + ret = osif_request_wait_for_response(request); + if (ret) { + osif_err("Target response timed out"); + } else { + result = osif_request_priv(request); + osif_debug("complete, vdev_id %u, ix: %u, flags: %u, status: %u", + result->vdev_id, result->key_ix, + result->key_flags, result->status); + } + } + + priv->add_key_ctx = NULL; + priv->add_key_cb = NULL; + osif_request_put(request); + } else { + status = ucfg_crypto_set_key_req(vdev, crypto_key, key_type); + } return qdf_status_to_os_return(status); } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_nl_to_crypto_params.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_nl_to_crypto_params.c index 2ecf276048a9a2132af68cb3bacb6e193d4440a6..3e8430d5e884b03d5c588dc1fdde31831ae585f2 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_nl_to_crypto_params.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/crypto/src/wlan_nl_to_crypto_params.c @@ -276,7 +276,8 @@ static const struct osif_cipher_crypto_mapping #endif }; -int osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type) +wlan_crypto_auth_mode +osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type) { wlan_crypto_auth_mode crypto_auth_type = WLAN_CRYPTO_AUTH_NONE; @@ -284,15 +285,17 @@ int osif_nl_to_crypto_auth_type(enum nl80211_auth_type auth_type) auth_type >= QDF_ARRAY_SIZE(osif_auth_type_crypto_mapping)) { QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", auth_type); - return -EINVAL; + return crypto_auth_type; } + + crypto_auth_type = osif_auth_type_crypto_mapping[auth_type]; QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Auth type, NL: %d, crypto: %d", - auth_type, osif_auth_type_crypto_mapping[auth_type]); + auth_type, crypto_auth_type); return crypto_auth_type; } -int osif_nl_to_crypto_akm_type(u32 key_mgmt) +wlan_crypto_key_mgmt osif_nl_to_crypto_akm_type(u32 key_mgmt) { uint8_t index; wlan_crypto_key_mgmt crypto_akm_type = WLAN_CRYPTO_KEY_MGMT_NONE; @@ -307,13 +310,12 @@ int osif_nl_to_crypto_akm_type(u32 key_mgmt) break; } } - if (!akm_type_crypto_exist) { + if (!akm_type_crypto_exist) QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", key_mgmt); - return -EINVAL; - } - QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Akm suite, NL: %d, crypto: %d", - key_mgmt, crypto_akm_type); + else + QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Akm suite, NL: %d, crypto: %d", + key_mgmt, crypto_akm_type); return crypto_akm_type; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/inc/wlan_cfg80211_gpio.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/inc/wlan_cfg80211_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..924c290eec615ddab706ea312060fbbcf229f3fd --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/inc/wlan_cfg80211_gpio.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_cfg80211_gpio.h + * + * This Header file provide declaration for cfg80211 command handler API + */ + +#ifndef __WLAN_CFG80211_GPIO_CFG_H__ +#define __WLAN_CFG80211_GPIO_CFG_H__ + +#include +#include +#include +#include + +#ifdef WLAN_FEATURE_GPIO_CFG + +extern const struct nla_policy + wlan_cfg80211_gpio_config_policy + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1]; + +/** + * wlan_cfg80211_start_gpio_config() - set GPIO config + * @psoc: pointer to psoc common object + * @data: Pointer to the data to be passed via vendor interface + * @data_len: Length of the data to be passed + * + * Return: Return the Success or Failure code + */ +int wlan_cfg80211_start_gpio_config(struct wiphy *wiphy, + struct wlan_objmgr_psoc *psoc, + const void *data, int data_len); +#else +static inline +int wlan_cfg80211_start_gpio_config(struct wiphy *wiphy, + struct wlan_objmgr_psoc *psoc, + const void *data, int data_len) +{ + return 0; +} +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /* __WLAN_CFG80211_GPIO_CFG_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/src/wlan_cfg80211_gpio.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/src/wlan_cfg80211_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..b99898353a70e18408a42fc26420b08e7323af8a --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/gpio/src/wlan_cfg80211_gpio.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: defines driver functions interfacing with linux kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdf_module.h" + +const struct nla_policy +wlan_cfg80211_gpio_config_policy[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, + [QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG] = { + .type = NLA_U32, + .len = sizeof(uint32_t) }, +}; + +/** + * convert_vendor_gpio_direction() - Function to convert vendor gpio direction + * @dir: pointer to enum qca_gpio_direction + * + * Convert the vendor gpio direction to wmi unified gpio direction + * + * Return: wmi unified gpio direction + */ +static enum gpio_direction +convert_vendor_gpio_direction(enum qca_gpio_direction dir) +{ + switch (dir) { + case QCA_WLAN_GPIO_INPUT: + return WMI_HOST_GPIO_INPUT; + case QCA_WLAN_GPIO_OUTPUT: + return WMI_HOST_GPIO_OUTPUT; + default: + return WMI_HOST_GPIO_INPUT; + } +} + +/** + * convert_vendor_gpio_pull_type() - Function to convert vendor pull type + * @pull_type: pointer to enum qca_gpio_pull_type + * + * Convert the vendor pull type to wmi unified pull type + * + * Return: wmi unified gpio pull type + */ +static enum gpio_pull_type +convert_vendor_gpio_pull_type(enum qca_gpio_pull_type pull_type) +{ + switch (pull_type) { + case QCA_WLAN_GPIO_PULL_NONE: + return WMI_HOST_GPIO_PULL_NONE; + case QCA_WLAN_GPIO_PULL_UP: + return WMI_HOST_GPIO_PULL_UP; + case QCA_WLAN_GPIO_PULL_DOWN: + return WMI_HOST_GPIO_PULL_DOWN; + default: + return WMI_HOST_GPIO_PULL_NONE; + } +} + +/** + * convert_vendor_gpio_interrupt_mode() - Function to convert + * vendor interrupt mode + * @intr_mode: pointer to enum qca_gpio_interrupt_mode + * + * Convert the vendor interrupt mode to wmi unified interrupt mode + * + * Return: wmi unified gpio interrupt mode + */ +static enum gpio_interrupt_mode +convert_vendor_gpio_interrupt_mode(enum qca_gpio_interrupt_mode intr_mode) +{ + switch (intr_mode) { + case QCA_WLAN_GPIO_INTMODE_DISABLE: + return WMI_HOST_GPIO_INTMODE_DISABLE; + case QCA_WLAN_GPIO_INTMODE_RISING_EDGE: + return WMI_HOST_GPIO_INTMODE_RISING_EDGE; + case QCA_WLAN_GPIO_INTMODE_FALLING_EDGE: + return WMI_HOST_GPIO_INTMODE_FALLING_EDGE; + case QCA_WLAN_GPIO_INTMODE_BOTH_EDGE: + return WMI_HOST_GPIO_INTMODE_BOTH_EDGE; + case QCA_WLAN_GPIO_INTMODE_LEVEL_LOW: + return WMI_HOST_GPIO_INTMODE_LEVEL_LOW; + case QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH: + return WMI_HOST_GPIO_INTMODE_LEVEL_HIGH; + default: + return WMI_HOST_GPIO_INTMODE_DISABLE; + } +} + +/** + * convert_vendor_gpio_output_value() - Function to convert vendor + * gpio output value + * @value: pointer to enum qca_gpio_value + * + * Convert the vendor gpio value to wmi unified gpio output value + * + * Return: wmi unified gpio output value + */ +static enum gpio_value +convert_vendor_gpio_output_value(enum qca_gpio_value value) +{ + switch (value) { + case QCA_WLAN_GPIO_LEVEL_LOW: + return WMI_HOST_GPIO_LEVEL_LOW; + case QCA_WLAN_GPIO_LEVEL_HIGH: + return WMI_HOST_GPIO_LEVEL_HIGH; + default: + return WMI_HOST_GPIO_LEVEL_LOW; + } +} + +/** + * convert_vendor_gpio_drive() - Function to convert vendor + * gpio drive + * @drive: value of enum gpio_drive + * + * Convert the vendor gpio drive to wmi unified gpio output drive + * + * Return: wmi unified gpio output drive config + */ +static enum gpio_drive +convert_vendor_gpio_drive(enum qca_gpio_drive drive) +{ + switch (drive) { + case QCA_WLAN_GPIO_DRIVE_2MA: + return WMI_HOST_GPIO_DRIVE_2MA; + case QCA_WLAN_GPIO_DRIVE_4MA: + return WMI_HOST_GPIO_DRIVE_4MA; + case QCA_WLAN_GPIO_DRIVE_6MA: + return WMI_HOST_GPIO_DRIVE_6MA; + case QCA_WLAN_GPIO_DRIVE_8MA: + return WMI_HOST_GPIO_DRIVE_8MA; + case QCA_WLAN_GPIO_DRIVE_10MA: + return WMI_HOST_GPIO_DRIVE_10MA; + case QCA_WLAN_GPIO_DRIVE_12MA: + return WMI_HOST_GPIO_DRIVE_12MA; + case QCA_WLAN_GPIO_DRIVE_14MA: + return WMI_HOST_GPIO_DRIVE_14MA; + case QCA_WLAN_GPIO_DRIVE_16MA: + return WMI_HOST_GPIO_DRIVE_16MA; + default: + return WMI_HOST_GPIO_DRIVE_2MA; + } +} + +/** + * convert_vendor_gpio_init_enable() - Function to convert vendor + * gpio init_enable + * @internal_config: Param to decide whether to use internal config + * + * Convert the vendor internal_config to wmi unified gpio output init_enable + * + * Return: wmi unified gpio output init_enable config + */ +static enum gpio_init_enable +convert_vendor_gpio_init_enable(uint32_t internal_config) +{ + if(internal_config) + return WMI_HOST_GPIO_INIT_DISABLE; + else + return WMI_HOST_GPIO_INIT_ENABLE; +} + +/** + * wlan_set_gpio_config() - set the gpio configuration info + * @psoc: the pointer of wlan_objmgr_psoc + * @attr: list of attributes + * + * Return: 0 on success; errno on failure + */ +static int +wlan_set_gpio_config(struct wlan_objmgr_psoc *psoc, + struct nlattr **attr) +{ + struct gpio_config_params cfg_param; + struct nlattr *gpio_attr; + enum qca_gpio_direction pin_dir; + enum qca_gpio_pull_type pull_type; + enum qca_gpio_interrupt_mode intr_mode; + enum qca_gpio_drive drive; + uint32_t internal_config; + QDF_STATUS status; + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM]; + if (!gpio_attr) { + osif_err_rl("attr gpio number failed"); + return -EINVAL; + } + cfg_param.pin_num = nla_get_u32(gpio_attr); + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR]; + if (!gpio_attr) { + osif_err_rl("attr gpio dir failed"); + return -EINVAL; + } + pin_dir = nla_get_u32(gpio_attr); + if (pin_dir >= QCA_WLAN_GPIO_DIR_MAX) { + osif_err_rl("attr gpio direction invalid"); + return -EINVAL; + } + cfg_param.pin_dir = convert_vendor_gpio_direction(pin_dir); + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE]; + if (!gpio_attr) { + osif_err_rl("attr gpio pull failed"); + return -EINVAL; + } + pull_type = nla_get_u32(gpio_attr); + if (pull_type >= QCA_WLAN_GPIO_PULL_MAX) { + osif_err_rl("attr gpio pull type invalid"); + return -EINVAL; + } + cfg_param.pin_pull_type = convert_vendor_gpio_pull_type(pull_type); + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE]; + if (!gpio_attr) { + osif_err_rl("attr gpio interrupt mode failed"); + return -EINVAL; + } + intr_mode = nla_get_u32(gpio_attr); + if (intr_mode >= QCA_WLAN_GPIO_INTMODE_MAX) { + osif_err_rl("attr gpio interrupt mode invalid"); + return -EINVAL; + } + cfg_param.pin_intr_mode = convert_vendor_gpio_interrupt_mode(intr_mode); + + /* Below are optional parameters. Initialize to zero */ + cfg_param.mux_config_val = WMI_HOST_GPIO_MUX_DEFAULT; + cfg_param.drive = WMI_HOST_GPIO_DRIVE_2MA; + cfg_param.init_enable = WMI_HOST_GPIO_INIT_DISABLE; + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG]; + if (gpio_attr) { + cfg_param.mux_config_val = nla_get_u32(gpio_attr); + } + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE]; + if (gpio_attr) { + drive = nla_get_u32(gpio_attr); + if (drive >= QCA_WLAN_GPIO_DRIVE_MAX) { + osif_err_rl("attr gpio drive invalid"); + return -EINVAL; + } + cfg_param.drive = convert_vendor_gpio_drive(drive); + } + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG]; + if (gpio_attr) { + internal_config = nla_get_u32(gpio_attr); + cfg_param.init_enable = + convert_vendor_gpio_init_enable(internal_config); + } + + status = ucfg_set_gpio_config(psoc, &cfg_param); + return status; +} + +/** + * wlan_set_gpio_output() - set the gpio output info + * @psoc: the pointer of wlan_objmgr_psoc + * @attr: list of attributes + * + * Return: 0 on success; errno on failure + */ +static int +wlan_set_gpio_output(struct wlan_objmgr_psoc *psoc, + struct nlattr **attr) +{ + struct gpio_output_params out_param; + struct nlattr *gpio_attr; + enum qca_gpio_value pin_set; + QDF_STATUS status; + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM]; + if (!gpio_attr) { + osif_err_rl("attr gpio number failed"); + return -EINVAL; + } + out_param.pin_num = nla_get_u32(gpio_attr); + + gpio_attr = attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE]; + if (!gpio_attr) { + osif_err_rl("attr gpio value failed"); + return -EINVAL; + } + pin_set = nla_get_u32(gpio_attr); + if (pin_set >= QCA_WLAN_GPIO_LEVEL_MAX) { + osif_err_rl("attr gpio level invalid"); + return -EINVAL; + } + out_param.pin_set = convert_vendor_gpio_output_value(pin_set); + + status = ucfg_set_gpio_output(psoc, &out_param); + return status; +} + +/** + * wlan_cfg80211_start_gpio_config - Set the gpio configuration + * @wiphy: pointer to wiphy + * @psoc: the pointer of wlan_objmgr_psoc + * @data: pointer to data + * @data_len: data length + * + * __wlan_cfg80211_set_gpio_config will forward the GPIO setting to FW by + * WMI_GPIO_CONFIG/OUTPUT_CMDID + * + * Return: 0 on success; errno on failure + */ +int +wlan_cfg80211_start_gpio_config(struct wiphy *wiphy, + struct wlan_objmgr_psoc *psoc, + const void *data, + int data_len) +{ + uint32_t command; + struct nlattr *attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX + 1]; + int ret; + + if (wlan_cfg80211_nla_parse(attr, QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX, + data, data_len, + wlan_cfg80211_gpio_config_policy)) { + return -EINVAL; + } + + if (attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND]) { + command = nla_get_u32( + attr[QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND]); + + if (command == QCA_WLAN_VENDOR_GPIO_CONFIG) { + ret = wlan_set_gpio_config(psoc, attr); + } else if (command == QCA_WLAN_VENDOR_GPIO_OUTPUT) { + ret = wlan_set_gpio_output(psoc, attr); + } else { + osif_err_rl("Invalid command"); + return -EINVAL; + } + } else { + osif_err_rl("Invalid command"); + return -EINVAL; + } + + return ret; +} +qdf_export_symbol(wlan_cfg80211_start_gpio_config); + diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/mlme/src/wlan_cfg80211_vdev_mlme.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/mlme/src/wlan_cfg80211_vdev_mlme.c index 54eecf585527612c9931542f5bab0bea8133bae9..16a6a0cd8568d10eb5e988b612dc33addcaddc57 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/mlme/src/wlan_cfg80211_vdev_mlme.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/mlme/src/wlan_cfg80211_vdev_mlme.c @@ -31,7 +31,7 @@ wlan_cfg80211_vdev_mlme_get_param_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_len) { if (!vdev) { - cfg80211_err("VDEV is NULL!!!!"); + osif_err("VDEV is NULL!!!!"); return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); } @@ -44,7 +44,7 @@ wlan_cfg80211_vdev_mlme_get_trans_bssid(struct wlan_objmgr_vdev *vdev, uint8_t *addr) { if (!vdev) { - cfg80211_err("VDEV is NULL!!!!"); + osif_err("VDEV is NULL!!!!"); return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); } @@ -58,7 +58,7 @@ wlan_cfg80211_vdev_mlme_set_param(struct wlan_objmgr_vdev *vdev, struct wlan_vdev_mgr_cfg mlme_cfg) { if (!vdev) { - cfg80211_err("VDEV is NULL!!!!"); + osif_err("VDEV is NULL!!!!"); return; } @@ -71,7 +71,7 @@ wlan_cfg80211_vdev_mlme_get_param(struct wlan_objmgr_vdev *vdev, uint32_t *value) { if (!vdev) { - cfg80211_err("VDEV is NULL!!!!"); + osif_err("VDEV is NULL!!!!"); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/qca_vendor.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/qca_vendor.h index 8a81c4b731f27906002ff3f199c233c7b29bfa6e..16d1466222d79afbf141cfaa803d487ab1ba0188 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/qca_vendor.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/qca_vendor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,6 +34,10 @@ #define QCA_NL80211_VENDOR_ID 0x001374 +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + /** * enum qca_nl80211_vendor_subcmds: NL 80211 vendor sub command * @@ -98,7 +102,11 @@ * @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: After roaming, send the * roaming and auth information. * @QCA_NL80211_VENDOR_SUBCMD_OCB_SET_SCHED: Set OCB schedule - * @QCA_NL80211_VENDOR_SUBCMD_DO_ACS: ACS offload flag + * + * @QCA_NL80211_VENDOR_SUBCMD_DO_ACS: ACS command/event which is used to + * invoke the ACS function in device and pass selected channels to + * hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes. + * * @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Get the supported features by the * driver. * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Indicate that driver @@ -136,7 +144,20 @@ * @QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST: get preferred channel list * @QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL: channel hint - * @QCA_NL80211_VENDOR_SUBCMD_SETBAND: vendor setband command + * @QCA_NL80211_VENDOR_SUBCMD_SETBAND: Command to configure the band + * to the host driver. This command sets the band through either + * the attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE or + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE + * refers enum qca_set_band as unsigned integer values and + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK refers it as 32 bit unsigned BitMask + * values. Also, the acceptable values for + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE are only till QCA_SETBAND_2G. Further + * values/bitmask's are valid for QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. The + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE is deprecated and the + * recommendation is to use the QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. If the + * implementations configure using both the attributes, the configurations + * through QCA_WLAN_VENDOR_ATTR_SETBAND_MASK shall always take the + * precedence. * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete * @QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN: vendor abort scan @@ -276,6 +297,10 @@ * legacy blob encapsulated within an attribute and can be extended with * additional vendor attributes that can enhance the NAN command * interface. + * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to + * configure parameters per peer to capture Channel Frequency Response + * (CFR) and enable Periodic CFR capture. The attributes for this command + * are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. * @QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE: Sub command to get firmware state. * The returned firmware state is specified in the attribute * QCA_WLAN_VENDOR_ATTR_FW_STATE. @@ -352,6 +377,27 @@ * binary blobs from application/service to firmware. The attributes * defined in enum qca_wlan_vendor_attr_oem_data_params are used to * deliver the parameters. + * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT: This command/event is used + * to send/receive avoid frequency data using + * enum qca_wlan_vendor_attr_avoid_frequency_ext. + * This new command is alternative to existing command + * QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event + * is using stream of bytes instead of structured data using vendor + * attributes. + * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to + * add the STA node details in driver/firmware. Attributes for this event + * are specified in enum qca_wlan_vendor_attr_add_sta_node_params. + * @QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE: This command is used to set BT + * coex chain mode from application/service. + * The attributes defined in enum qca_vendor_attr_btc_chain_mode are used + * to deliver the parameters. + * @QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO: This vendor subcommand is used to + * get information of a station from driver to userspace. This command can + * be used in both STA and AP modes. For STA mode, it provides information + * of the current association when in connected state or the last + * association when in disconnected state. For AP mode, only information + * of the currently connected stations is available. This command uses + * attributes defined in enum qca_wlan_vendor_attr_get_sta_info. * @QCA_NL80211_VENDOR_SUBCMD_REQUEST_SAR_LIMITS_EVENT: This acts as an event. * Host drivers can request the user space entity to set the SAR power * limits with this event. Accordingly, the user space entity is expected @@ -375,6 +421,14 @@ * code immediately prior to triggering cfg80211_disconnected(). The * attributes used with this event are defined in enum * qca_wlan_vendor_attr_driver_disconnect_reason. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT. + * Uses attributes defined in enum qca_wlan_vendor_attr_config_twt. + * + * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the configured band from + * the host driver. The band configurations obtained are referred through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. + * */ enum qca_nl80211_vendor_subcmds { @@ -583,6 +637,7 @@ enum qca_nl80211_vendor_subcmds { /* Wi-Fi test configuration subcommand */ QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION = 169, QCA_NL80211_VENDOR_SUBCMD_NAN_EXT = 171, + QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG = 173, QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT = 174, QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG = 175, QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE = 177, @@ -591,9 +646,15 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING = 180, QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP = 181, QCA_NL80211_VENDOR_SUBCMD_OEM_DATA = 182, + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT = 183, + QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE = 184, + QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE = 185, + QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO = 186, QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS_EVENT = 187, QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO = 188, QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON = 189, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT = 191, + QCA_NL80211_VENDOR_SUBCMD_GETBAND = 192, }; enum qca_wlan_vendor_tos { @@ -647,6 +708,47 @@ enum qca_wlan_vendor_hang_reason { QCA_WLAN_HANG_DXE_FAILURE = 12, /* WMI pending commands exceed the maximum count */ QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS = 13, + /* Timeout for peer STA connection accept command's response from the + * FW in AP mode. This command is triggered when a STA (peer) connects + * to AP (DUT). + */ + QCA_WLAN_HANG_AP_STA_CONNECT_REQ_TIMEOUT = 14, + /* Timeout for the AP connection accept command's response from the FW + * in STA mode. This command is triggered when the STA (DUT) connects + * to an AP (peer). + */ + QCA_WLAN_HANG_STA_AP_CONNECT_REQ_TIMEOUT = 15, + /* Timeout waiting for the response to the MAC HW mode change command + * sent to FW as a part of MAC mode switch among DBS (Dual Band + * Simultaneous), SCC (Single Channel Concurrency), and MCC (Multi + * Channel Concurrency) mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CHANGE_TIMEOUT = 16, + /* Timeout waiting for the response from FW to configure the MAC HW's + * mode. This operation is to configure the single/two MACs in either + * SCC/MCC/DBS mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CONFIG_TIMEOUT = 17, + /* Timeout waiting for response of VDEV start command from the FW */ + QCA_WLAN_HANG_VDEV_START_RESPONSE_TIMED_OUT = 18, + /* Timeout waiting for response of VDEV restart command from the FW */ + QCA_WLAN_HANG_VDEV_RESTART_RESPONSE_TIMED_OUT = 19, + /* Timeout waiting for response of VDEV stop command from the FW */ + QCA_WLAN_HANG_VDEV_STOP_RESPONSE_TIMED_OUT = 20, + /* Timeout waiting for response of VDEV delete command from the FW */ + QCA_WLAN_HANG_VDEV_DELETE_RESPONSE_TIMED_OUT = 21, + /* Timeout waiting for response of peer all delete request command to + * the FW on a specific VDEV. + */ + QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22, + /* WMI sequence mismatch between WMI command and Tx completion */ + QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23, + /* Write to Device HAL register failed */ + QCA_WLAN_HANG_REG_WRITE_FAILURE = 24, + /* No credit left to send the wow_wakeup_from_sleep to firmware */ + QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25, + /* Bus failure */ + QCA_WLAN_HANG_BUS_FAILURE = 26, }; /** @@ -660,7 +762,12 @@ enum qca_wlan_vendor_attr_hang { * qca_wlan_vendor_hang_reason. */ QCA_WLAN_VENDOR_ATTR_HANG_REASON = 1, - + /* The binary blob data associated with the hang reason specified by + * QCA_WLAN_VENDOR_ATTR_HANG_REASON. This binary data is expected to + * contain the required dump to analyze the reason for the hang. + * NLA_BINARY attribute, the max size is 1024 bytes. + */ + QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA = 2, QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_HANG_MAX = QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST - 1, @@ -747,6 +854,7 @@ enum qca_wlan_vendor_attr_update_sta_info { * @QCA_WLAN_802_11_MODE_11N: mode N * @QCA_WLAN_802_11_MODE_11A: mode A * @QCA_WLAN_802_11_MODE_11AC: mode AC + * @QCA_WLAN_802_11_MODE_11AX: mode AX * @QCA_WLAN_802_11_MODE_INVALID: Invalid dot11 mode */ enum qca_wlan_802_11_mode { @@ -755,6 +863,7 @@ enum qca_wlan_802_11_mode { QCA_WLAN_802_11_MODE_11N, QCA_WLAN_802_11_MODE_11A, QCA_WLAN_802_11_MODE_11AC, + QCA_WLAN_802_11_MODE_11AX, QCA_WLAN_802_11_MODE_INVALID, }; @@ -831,8 +940,7 @@ enum qca_wlan_auth_type { * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE: * Max phy rate of remote station * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS: - * Unsigned 32 bit value. Represent the number of all frames from host to - * firmware. + * TX packets to remote station * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES: * TX bytes to remote station * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS: @@ -858,39 +966,6 @@ enum qca_wlan_auth_type { * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE: * Remote station short GI enable/disable * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD: Attribute type for padding - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT: - * Unsigned 32 bit value. Represents the number of retried frames received - * from remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT: - * Unsigned 32 bit value. Represents the number of broadcast and multicast - * frames received from remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_FAILURE: - * Unsigned 32 bit value. Represents the number of frames which is failed to - * be transmitted. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AVG_RSSI_PER_CHAIN: - * An array of CHAINS x signed 32 bit value. Represents the average value of - * RSSI per chain calculated for the remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_SUCCEED: - * Unsigned 32 bit value. Represents the number of frames retried but - * successfully transmitted to remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_LAST_PKT_RSSI: - * Signed 32 bit value. Represents the RSSI calculated by last packet received - * from remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY: - * Unsigned 32 bit value. Represent the number of retried frames from host - * to firmware. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST: - * Unsigned 32 bit value. Represent the number of frames retried but finally - * failed from host to firmware. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_TOTAL_FW: - * Unsigned 32 bit value. Represent the number of all frames from firmware - * to remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_FW: - * Unsigned 32 bit value. Represent the number of retried frames from - * firmware to remote station. - * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST_FW: - * Unsigned 32 bit value. Represent the number of frames retried but finally - * failed from firmware to remote station. * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES: Binary attribute * containing the raw information elements from Beacon frames. Represents * the Beacon frames of the current BSS in the connected state. When queried @@ -906,6 +981,8 @@ enum qca_wlan_auth_type { * mac address of peer station when it disconnects. Host driver sends * assoc request frame of the given station. Host driver doesn't provide * the IEs when the peer station is still in connected state. + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION: Attribute type for + * sending HE operation info. * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST: After last */ enum qca_wlan_vendor_attr_get_station_info { @@ -948,6 +1025,7 @@ enum qca_wlan_vendor_attr_get_station_info { QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION, /* keep last */ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST, @@ -1292,7 +1370,13 @@ enum qca_wlan_vendor_attr { QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND = 10, /* Unsigned 32-bit value */ QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND = 11, - /* Unsigned 32-bit value from enum qca_set_band. */ + /* Unsigned 32-bit value from enum qca_set_band. Also, the acceptable + * value for this attribute are only till QCA_SETBAND_2G. This attribute + * is deprecated. Recommendation is to use + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK instead. If the band is configured + * using both the attributes, the ones configured through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK take the precedence. + */ QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12, /* Dummy (NOP) attribute for 64 bit padding */ QCA_WLAN_VENDOR_ATTR_PAD = 13, @@ -1479,9 +1563,18 @@ enum qca_wlan_vendor_attr { */ QCA_WLAN_VENDOR_ATTR_FW_STATE = 42, + /* Unsigned 32-bitmask value from enum qca_set_band. Substitutes the + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE for which only the + * integer values of enum qca_set_band till QCA_SETBAND_2G are valid. + * This attribute shall consider the bitmask combinations to define + * the respective Band combinations and always takes precedence over + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE. + */ + QCA_WLAN_VENDOR_ATTR_SETBAND_MASK = 43, + /* keep last */ QCA_WLAN_VENDOR_ATTR_AFTER_LAST, - QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1 + QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1 }; enum qca_wlan_vendor_attr_extscan_config_params { @@ -2312,6 +2405,10 @@ enum qca_wlan_vendor_attr_ll_stats_results { QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT = 81, QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT = 82, + /* u8 value representing the time slicing duty cycle percentage. + * Possible values are 0-100. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87, /* keep last */ QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX = @@ -3618,27 +3715,29 @@ enum qca_wlan_vendor_attr_nd_offload { }; /** - * enum qca_wlan_vendor_features - vendor device/driver features + * enum qca_wlan_vendor_features - Vendor device/driver feature flags + * * @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key - * management offload, a mechanism where the station's firmware - * does the exchange with the AP to establish the temporal keys - * after roaming, rather than having the supplicant do it. + * management offload, a mechanism where the station's firmware + * does the exchange with the AP to establish the temporal keys + * after roaming, rather than having the user space wpa_supplicant do it. + * @QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY: Device supports automatic + * band selection based on channel selection results. * @QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS: Device supports - * simultaneous off-channel operations. - * @QQCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD: Device supports P2P - * Listen offload; a mechanism where the station's firmware - * takes care of responding to incoming Probe Request frames received - * from other P2P devices whilst in Listen state, rather than having the - * user space wpa_supplicant do it. Information from received P2P - * Requests are forwarded from firmware to host whenever the APPS - * processor exits power collapse state. + * simultaneous off-channel operations. + * @QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD: Device supports P2P + * Listen offload; a mechanism where the station's firmware takes care of + * responding to incoming Probe Request frames received from other P2P + * Devices whilst in Listen state, rather than having the user space + * wpa_supplicant do it. Information from received P2P requests are + * forwarded from firmware to host whenever the host processor wakes up. * @QCA_WLAN_VENDOR_FEATURE_OCE_STA: Device supports all OCE non-AP STA - * specific features + * specific features. * @QCA_WLAN_VENDOR_FEATURE_OCE_AP: Device supports all OCE AP specific * features. * @QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON: Device supports OCE STA-CFON * specific features only. If a Device sets this bit but not the - * QCA_WLAN_VENDOR_FEATURE_OCE_AP, the userspace shall assume that + * %QCA_WLAN_VENDOR_FEATURE_OCE_AP, the userspace shall assume that * this Device may not support all OCE AP functionalities but can support * only OCE STA-CFON functionalities. * @QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY: Device supports self @@ -3651,13 +3750,17 @@ enum qca_wlan_vendor_attr_nd_offload { * %QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and * %QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from * userspace. + * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports + * concurrent network sessions on different Wi-Fi Bands. This feature + * capability is attributed to the hardware's capability to support + * the same (e.g., DBS). * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits */ enum qca_wlan_vendor_features { QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0, QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1, QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS = 2, - QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD = 3, + QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD = 3, QCA_WLAN_VENDOR_FEATURE_OCE_STA = 4, QCA_WLAN_VENDOR_FEATURE_OCE_AP = 5, QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON = 6, @@ -3666,9 +3769,9 @@ enum qca_wlan_vendor_features { QCA_WLAN_VENDOR_FEATURE_11AX = 9, QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT = 10, QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG = 11, + QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13, - /* Additional features need to be added above this */ - NUM_QCA_WLAN_VENDOR_FEATURES + NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */ }; /** @@ -3716,41 +3819,155 @@ enum wifi_logger_supported_features { WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)) }; + /** - * enum qca_wlan_vendor_attr_acs_offload - * - * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL: ACS selected primary channel - * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL: ACS selected secondary channel - * @QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE: hw_mode for ACS - * @QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED: indicate if HT capability is enabled - * @QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED: indicate HT capability + * enum qca_wlan_vendor_attr_acs_offload - Defines attributes to be used with + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL: Required (u8). + * Used with event to notify the primary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY instead. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL: Required (u8). + * Used with event to notify the secondary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is still used if either of + * the driver or user space application doesn't support 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE: Required (u8). + * (a) Used with command to configure hw_mode from + * enum qca_wlan_vendor_acs_hw_mode for ACS operation. + * (b) Also used with event to notify the hw_mode of selected primary channel + * in ACS operation. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT mode. + * Disable (flag attribute not present) - HT disabled and + * Enable (flag attribute present) - HT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT40 mode. + * Disable (flag attribute not present) - HT40 disabled and + * Enable (flag attribute present) - HT40 enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for VHT mode. + * Disable (flag attribute not present) - VHT disabled and + * Enable (flag attribute present) - VHT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH: Optional (u16) with command and + * mandatory with event. + * If specified in command path, ACS operation is configured with the given + * channel width (in MHz). + * In event path, specifies the channel width of the primary channel selected. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure channel list using an array of + * channel numbers (u8). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver mandates use of QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST whereas + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is optional. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 0 center channel number selected in + * ACS operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 1 center channel number selected in + * ACS operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure the channel list using an array of channel + * center frequencies in MHz (u32). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver first parses the frequency list and if it fails to get a frequency + * list, parses the channel list specified using + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST (considers only 2 GHz and 5 GHz channels in + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST). + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY: Required (u32). + * Used with event to notify the primary channel center frequency (MHz) selected + * in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY: Required (u32). + * Used with event to notify the secondary channel center frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 0 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 1 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL. */ enum qca_wlan_vendor_attr_acs_offload { QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0, - QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL, - QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, - QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, - QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED, - QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED, - QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED, - QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH, - QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST, - QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, - QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, - QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL = 1, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL = 2, + QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE = 3, + QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED = 4, + QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED = 5, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED = 6, + QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH = 7, + QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST = 8, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL = 9, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL = 10, + QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST = 11, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY = 12, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY = 13, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY = 14, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15, + /* keep last */ QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_ACS_MAX = - QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1 + QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1 }; /** - * enum qca_wlan_vendor_acs_hw_mode + * enum qca_wlan_vendor_acs_hw_mode - Defines HW mode to be used with the + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. * - * @QCA_ACS_MODE_IEEE80211B: 11b mode - * @QCA_ACS_MODE_IEEE80211G: 11g mode - * @QCA_ACS_MODE_IEEE80211A: 11a mode - * @QCA_ACS_MODE_IEEE80211AD: 11ad mode + * @QCA_ACS_MODE_IEEE80211B: 802.11b mode + * @QCA_ACS_MODE_IEEE80211G: 802.11g mode + * @QCA_ACS_MODE_IEEE80211A: 802.11a mode + * @QCA_ACS_MODE_IEEE80211AD: 802.11ad mode + * @QCA_ACS_MODE_IEEE80211ANY: all modes + * @QCA_ACS_MODE_IEEE80211AX: 802.11ax mode */ enum qca_wlan_vendor_acs_hw_mode { QCA_ACS_MODE_IEEE80211B, @@ -3758,6 +3975,7 @@ enum qca_wlan_vendor_acs_hw_mode { QCA_ACS_MODE_IEEE80211A, QCA_ACS_MODE_IEEE80211AD, QCA_ACS_MODE_IEEE80211ANY, + QCA_ACS_MODE_IEEE80211AX, }; /** @@ -3797,6 +4015,12 @@ enum qca_ignore_assoc_disallowed { * QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION subcommands. */ +#define QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES\ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES +#define QCA_WLAN_VENDOR_ATTR_BEACON_REPORT_FAIL\ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL +#define QCA_WLAN_VENDOR_ATTR_ROAM_REASON\ + QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON enum qca_wlan_vendor_attr_config { QCA_WLAN_VENDOR_ATTR_CONFIG_INVALID = 0, /* @@ -3929,7 +4153,10 @@ enum qca_wlan_vendor_attr_config { * wiphy. */ QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX = 24, - /* 8-bit unsigned value to trigger QPower: 1-Enable, 0-Disable */ + /* + * 8-bit unsigned value to trigger QPower: + * 1-Enable, 0-Disable + */ QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER = 25, /* * 8-bit unsigned value to configure the driver and below layers to @@ -4111,13 +4338,96 @@ enum qca_wlan_vendor_attr_config { * take the union of IEs from both of these interfaces and send in * further disassoc/deauth frames. */ - QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES = 58, + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES = 58, /* 8-bit unsigned value for ELNA bypass. * 1-Enable, 0-Disable */ QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS = 59, + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL = 60, + + /* 8-bit unsigned value. This attribute enables/disables the host driver + * to send roam reason information in the reassociation request to the + * AP. 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON = 61, + + /* + * 8-bit unsigned value to trigger Optimized Power Management: + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT = 71, + + /* 8-bit unsigned value. This attribute takes the QOS/access category + * value represented by the enum qca_wlan_ac_type and expects the driver + * to upgrade the UDP frames to this QOS. The value of QCA_WLAN_AC_ALL + * is invalid for this attribute. This will override the DSCP value + * configured in the frame with the intention to only upgrade the QOS. + * That said, it is not intended to downgrade the QOS for the frames. + * Set the value to 0 ( corresponding to BE ) if the QOS upgrade needs + * to disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE = 72, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for transmitting data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_TX_CHAINS = 73, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for receiving data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS = 74, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for transmitting the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The TX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver + * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for receiving the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The RX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver + * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78, + /* keep last */ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = @@ -4422,6 +4732,10 @@ enum qca_wlan_ndp_sub_cmd { * antenna gain in dbm * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0: vht segment 0 * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1: vht segment 1 + * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0: vht + * segment 0 in center freq in MHz. + * @QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1: vht + * segment 1 in center freq in MHz. * */ enum qca_wlan_vendor_external_acs_event_chan_info_attr { @@ -4443,6 +4757,46 @@ enum qca_wlan_vendor_external_acs_event_chan_info_attr { */ QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2 = 11, + /* + * VHT segment 0 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * should be used. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 = 12, + + /* + * VHT segment 1 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * should be considered. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 = 13, + /* keep last */ QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX = @@ -4537,9 +4891,10 @@ enum qca_wlan_vendor_attr_pcl_config { }; enum qca_set_band { - QCA_SETBAND_AUTO, - QCA_SETBAND_5G, - QCA_SETBAND_2G, + QCA_SETBAND_AUTO = 0, + QCA_SETBAND_5G = BIT(0), + QCA_SETBAND_2G = BIT(1), + QCA_SETBAND_6G = BIT(2), }; /** @@ -5020,22 +5375,35 @@ enum dfs_mode { }; /** - * enum qca_wlan_vendor_attr_acs_config - Config params for ACS - * @QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID: Invalid - * @QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE: Dfs mode for ACS - * QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT: channel_hint for ACS - * QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST: after_last - * QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX: max attribute + * enum qca_wlan_vendor_attr_acs_config - Defines Configuration attributes + * used by the vendor command QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE: Required (u8) + * DFS mode for ACS operation from enum qca_acs_dfs_mode. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT: Required (u8) + * channel number hint for ACS operation, if valid channel is specified then + * ACS operation gives priority to this channel. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT: Required (u32). + * Channel center frequency (MHz) hint for ACS operation, if a valid center + * frequency is specified, ACS operation gives priority to this channel. */ enum qca_wlan_vendor_attr_acs_config { QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID = 0, - QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE, - QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE = 1, + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT = 2, + QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT = 3, QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX = QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST - 1, - }; /** @@ -5152,22 +5520,34 @@ enum qca_wlan_vendor_attr_loc_capa_flags { }; /** - * enum qca_wlan_vendor_attr_sap_config - config params for sap configuration - * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID: invalid - * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL: Channel on which SAP should start - * @QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST: List of frequencies on - * which AP is expected to operate. This is irrespective of ACS configuration. - * This list is a priority based one and is looked for before the AP is created - * to ensure the best concurrency sessions (avoid MCC and use DBS/SCC) co-exist - * in the system. - * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST: after last - * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX: max attribute + * enum qca_wlan_vendor_attr_sap_config - Parameters for AP configuration + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL: Optional (u8) + * Channel number on which Access Point should restart. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST: Required + * Nested attribute to hold list of center frequencies on which AP is + * expected to operate. This is irrespective of ACS configuration. + * This list is a priority based one and is looked for before the AP is + * created to ensure the best concurrency sessions (avoid MCC and use DBS/SCC) + * co-exist in the system. + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY: Optional (u32) + * Channel center frequency (MHz) on which the access point should restart. */ enum qca_wlan_vendor_attr_sap_config { QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID = 0, - QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL = 1, QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST = 2, - /* keep last */ + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY = 3, + + /* Keep last */ QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX = QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST - 1, @@ -6076,39 +6456,136 @@ enum qca_wlan_vendor_attr_ll_stats_ext { }; /** - * qca_wlan_vendor_attr_external_acs_channels: attribute to vendor subcmd - * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This carry a list of channels - * in priority order as decided after acs operation in userspace. - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON: One of reason code from - * qca_wlan_vendor_acs_select_reason. - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_COUNT: Number of channels in - * this list - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST: Array of nested values - * for each channel with following attributes: + * enum qca_wlan_vendor_attr_external_acs_channels: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This carries a list of channels + * in priority order as decided after ACS operation in userspace. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON: Required (u8). + * One of reason code from enum qca_wlan_vendor_acs_select_reason. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST: Required + * Array of nested values for each channel with following attributes: * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY: Primary channel (u8) - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY: Secondary channel (u8) - * required only for 160 / 80 + 80 - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0: VHT seg0 channel (u8) - * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1: VHT seg1 channel (u8) - * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH:channel width (u8) + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY: Required (u8). + * Primary channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY: Required (u8). + * Secondary channel number, required only for 160 and 80+80 MHz bandwidths. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0: Required (u8). + * VHT seg0 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1: Required (u8). + * VHT seg1 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH: Required (u8). + * Takes one of enum nl80211_chan_width values. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST: Required + * Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY: Required (u32) + * Primary channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY: Required (u32) + * Secondary channel frequency in MHz used for HT 40 MHz channels. + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0: Required (u32) + * VHT seg0 channel frequency in MHz + * Note: If user-space application has no support of the 6GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1: Required (u32) + * VHT seg1 channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. */ enum qca_wlan_vendor_attr_external_acs_channels { QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_INVALID = 0, + /* One of reason code (u8) from enum qca_wlan_vendor_acs_select_reason + */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON = 1, + + /* Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST = 2, + /* This (u8) will hold values of one of enum nl80211_bands */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND = 3, + /* Primary channel (u8) */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY = 4, + /* Secondary channel (u8) used for HT 40 MHz channels */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY = 5, + /* VHT seg0 channel (u8) */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 = 6, + /* VHT seg1 channel (u8) */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 = 7, + /* Channel width (u8). Takes one of enum nl80211_chan_width values. */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH = 8, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST = 9, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY = 10, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY = 11, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 = 12, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 = 13, + /* keep last */ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX = @@ -6117,37 +6594,140 @@ enum qca_wlan_vendor_attr_external_acs_channels { /** * qca_wlan_vendor_acs_select_reason: This represents the different reasons why - * the ACS has to be triggered. These parameters are used by + * the ACS has to be triggered. These values are used by * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON and - * QCA_NL80211_VENDOR_SUBCMD_ACS_SET_CHANNELS - * @QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT: Represents the reason that the - * ACS triggered during the AP start - * @QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: Represents the reason that - * DFS found with current channel - * @QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: Represents the reason that - * LTE CO-Exist in current band + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON */ enum qca_wlan_vendor_acs_select_reason { + /* Represents the reason that the ACS triggered during the AP start */ QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT, + /* Represents the reason that DFS found with the current channel */ QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS, + /* Represents the reason that LTE co-exist in the current band. */ QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX, + /* Represents the reason that generic, uncategorized interference has + * been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_GENERIC_INTERFERENCE, + /* Represents the reason that excessive 802.11 interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_80211_INTERFERENCE, + /* Represents the reason that generic Continuous Wave (CW) interference + * has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_CW_INTERFERENCE, + /* Represents the reason that Microwave Oven (MWO) interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_MWO_INTERFERENCE, + /* Represents the reason that generic Frequency-Hopping Spread Spectrum + * (FHSS) interference has been found in the current channel. This may + * include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_FHSS_INTERFERENCE, + /* Represents the reason that non-802.11 generic Frequency-Hopping + * Spread Spectrum (FHSS) interference has been found in the current + * channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_FHSS_INTERFERENCE, + /* Represents the reason that generic Wideband (WB) interference has + * been found in the current channel. This may include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_WB_INTERFERENCE, + /* Represents the reason that non-802.11 generic Wideband (WB) + * interference has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_WB_INTERFERENCE, + /* Represents the reason that Jammer interference has been found in the + * current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_JAMMER_INTERFERENCE, }; /** * enum qca_wlan_gpio_attr - Parameters for GPIO configuration + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND: Required (u32) + * value to specify the gpio command, please refer to enum qca_gpio_cmd_type + * to get the available value that this item can use. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM: Required (u32) + * value to specify the gpio number. + * Required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG or %.QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE: Required (u32) + * value to specify the gpio output level, please refer to enum qca_gpio_value + * to get the available value that this item can use. + * Required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32) + * value to specify the gpio pull type, please refer to enum qca_gpio_pull_type + * to get the available value that this item can use. + * Required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32) + * value to specify the gpio interrupt mode, please refer to enum + * qca_gpio_interrupt_mode to get the available value that this item can use. + * Required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32) + * value to specify the gpio direction, please refer to enum qca_gpio_direction + * to get the available value that this item can use. + * Required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32) + * Value to specify the mux config. Meaning of a given value is dependent + * on the target chipset and gpio pin. Must be of the range 0-15. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32) + * Value to specify the drive, Refer to enum qca_gpio_drive. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0). + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag) + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all + * other parameters for the given GPIO will be obtained from internal + * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be + * specified to indicate the GPIO pin being configured. */ enum qca_wlan_gpio_attr { QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0, /* Unsigned 32-bit attribute for GPIO command */ - QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND = 1, /* Unsigned 32-bit attribute for GPIO PIN number to configure */ - QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM = 2, /* Unsigned 32-bit attribute for GPIO value to configure */ - QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE = 3, /* Unsigned 32-bit attribute for GPIO pull type */ - QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE = 4, /* Unsigned 32-bit attribute for GPIO interrupt mode */ - QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5, + /* Unsigned 32-bit attribute for GPIO direction to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6, + /* Unsigned 32-bit attribute for GPIO mux config */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7, + /* Unsigned 32-bit attribute for GPIO drive */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8, + /* Flag attribute for using internal gpio configuration */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9, /* keep last */ QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST, @@ -6155,6 +6735,97 @@ enum qca_wlan_gpio_attr { QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST - 1, }; +/** + * enum gpio_cmd_type - GPIO configuration command type + * @QCA_WLAN_VENDOR_GPIO_CONFIG: set gpio configuration info + * @QCA_WLAN_VENDOR_GPIO_OUTPUT: set gpio output level + */ +enum qca_gpio_cmd_type { + QCA_WLAN_VENDOR_GPIO_CONFIG = 0, + QCA_WLAN_VENDOR_GPIO_OUTPUT = 1, +}; + +/** + * enum qca_gpio_pull_type - GPIO pull type + * @QCA_WLAN_GPIO_PULL_NONE: set gpio pull type to none + * @QCA_WLAN_GPIO_PULL_UP: set gpio pull up + * @QCA_WLAN_GPIO_PULL_DOWN: set gpio pull down + */ +enum qca_gpio_pull_type { + QCA_WLAN_GPIO_PULL_NONE = 0, + QCA_WLAN_GPIO_PULL_UP = 1, + QCA_WLAN_GPIO_PULL_DOWN = 2, + QCA_WLAN_GPIO_PULL_MAX, +}; + +/** + * enum qca_gpio_direction - GPIO direction + * @QCA_WLAN_GPIO_INPUT: set gpio as input mode + * @QCA_WLAN_GPIO_OUTPUT: set gpio as output mode + * @QCA_WLAN_GPIO_VALUE_MAX: invalid value + */ +enum qca_gpio_direction { + QCA_WLAN_GPIO_INPUT = 0, + QCA_WLAN_GPIO_OUTPUT = 1, + QCA_WLAN_GPIO_DIR_MAX, +}; + +/** + * enum qca_gpio_value - GPIO Value + * @QCA_WLAN_GPIO_LEVEL_LOW: set gpio output level to low + * @QCA_WLAN_GPIO_LEVEL_HIGH: set gpio output level to high + * @QCA_WLAN_GPIO_LEVEL_MAX: invalid value + */ +enum qca_gpio_value { + QCA_WLAN_GPIO_LEVEL_LOW = 0, + QCA_WLAN_GPIO_LEVEL_HIGH = 1, + QCA_WLAN_GPIO_LEVEL_MAX, +}; + +/** + * enum gpio_interrupt_mode - GPIO interrupt mode + * @QCA_WLAN_GPIO_INTMODE_DISABLE: disable interrupt trigger + * @QCA_WLAN_GPIO_INTMODE_RISING_EDGE: interrupt with gpio rising edge trigger + * @QCA_WLAN_GPIO_INTMODE_FALLING_EDGE: interrupt with gpio falling edge trigger + * @QCA_WLAN_GPIO_INTMODE_BOTH_EDGE: interrupt with gpio both edge trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_LOW: interrupt with gpio level low trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH: interrupt with gpio level high trigger + * @QCA_WLAN_GPIO_INTMODE_MAX: invalid value + */ +enum qca_gpio_interrupt_mode { + QCA_WLAN_GPIO_INTMODE_DISABLE = 0, + QCA_WLAN_GPIO_INTMODE_RISING_EDGE = 1, + QCA_WLAN_GPIO_INTMODE_FALLING_EDGE = 2, + QCA_WLAN_GPIO_INTMODE_BOTH_EDGE = 3, + QCA_WLAN_GPIO_INTMODE_LEVEL_LOW = 4, + QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH = 5, + QCA_WLAN_GPIO_INTMODE_MAX, +}; + +/** + * enum gpio_drive - GPIO drive + * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA + * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA + * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA + * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA + * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA + * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA + * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA + * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA + * @QCA_WLAN_GPIO_DRIVE_MAX: invalid gpio drive + */ +enum qca_gpio_drive { + QCA_WLAN_GPIO_DRIVE_2MA = 0, + QCA_WLAN_GPIO_DRIVE_4MA = 1, + QCA_WLAN_GPIO_DRIVE_6MA = 2, + QCA_WLAN_GPIO_DRIVE_8MA = 3, + QCA_WLAN_GPIO_DRIVE_10MA = 4, + QCA_WLAN_GPIO_DRIVE_12MA = 5, + QCA_WLAN_GPIO_DRIVE_14MA = 6, + QCA_WLAN_GPIO_DRIVE_16MA = 7, + QCA_WLAN_GPIO_DRIVE_MAX, +}; + /** * qca_wlan_set_qdepth_thresh_attr - Parameters for setting * MSDUQ depth threshold per peer per tid in the target @@ -6356,6 +7027,16 @@ enum qca_wlan_vendor_attr_spectral_scan { * This attribute is included only in failure scenarios. */ QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE = 26, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA ring. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG = 27, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA buffers. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG = 28, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX = @@ -6434,8 +7115,18 @@ enum qca_wlan_vendor_attr_spectral_cap { * u8 attribute. */ QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN = 10, - /* Flag attribute to indicate agile spectral scan capability */ + /* Flag attribute to indicate agile spectral scan capability + * for 20/40/80 MHz modes. + */ QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL = 11, + /* Flag attribute to indicate agile spectral scan capability + * for 160 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_160 = 12, + /* Flag attribute to indicate agile spectral scan capability + * for 80+80 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_80_80 = 13, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX = @@ -6644,12 +7335,22 @@ enum qca_wlan_vendor_attr_rrop_info { enum qca_wlan_vendor_attr_rtplinst { QCA_WLAN_VENDOR_ATTR_RTPLINST_INVALID = 0, - /* Primary channel number (u8) */ + /* Primary channel number (u8). + * Note: If both the driver and user space application support the + * 6 GHz band, this attribute is deprecated and + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY should be used. To + * maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY is still used if either the + * driver or user space application or both do not support the 6 GHz + * band. + */ QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY = 1, /* Representative Tx power in dBm (s32) with emphasis on throughput. */ QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_THROUGHPUT = 2, /* Representative Tx power in dBm (s32) with emphasis on range. */ QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_RANGE = 3, + /* Primary channel center frequency (u32) in MHz */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY = 4, QCA_WLAN_VENDOR_ATTR_RTPLINST_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_RTPLINST_MAX = @@ -7245,11 +7946,67 @@ enum qca_wlan_vendor_attr_wifi_test_config { QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST - 1, }; +/** + * enum qca_wlan_twt_operation - Operation of the config TWT request + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION. + * + * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured + * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. + * + * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. + * + * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Does not carry any + * parameters. Valid only after the TWT session is setup. + * + * @QCA_WLAN_TWT_SUSPEND: Terminate the TWT session. Does not carry any + * parameters. Valid only after the TWT session is setup. + * + * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are + * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_resume. + */ +enum qca_wlan_twt_operation { + QCA_WLAN_TWT_SET = 0, + QCA_WLAN_TWT_GET = 1, + QCA_WLAN_TWT_TERMINATE = 2, + QCA_WLAN_TWT_SUSPEND = 3, + QCA_WLAN_TWT_RESUME = 4, +}; + +/* enum qca_wlan_vendor_attr_config_twt: Defines attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION: + * u8 attribute. Specify the TWT operation of this request. Possible values + * are defined in enum qca_wlan_twt_operation. The parameters for the + * respective operation is specified through + * QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the + * parameters configured for TWT. These parameters are represented by + * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume + * based on the operation. + */ +enum qca_wlan_vendor_attr_config_twt { + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST - 1, +}; + /** * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for * TWT (Target Wake Time) setup request. These attributes are sent as part of * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and - * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. * * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST: Flag attribute. * Disable (flag attribute not present) - Individual TWT @@ -7328,7 +8085,8 @@ enum qca_wlan_vendor_attr_twt_setup { * enum qca_wlan_vendor_attr_twt_resume: Represents attributes for * TWT (Target Wake Time) resume request. These attributes are sent as part of * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME and - * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. * * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT: Optional (u8) * This attribute is used as the SP offset which is the offset from @@ -7484,6 +8242,238 @@ enum qca_wlan_vendor_attr_nan_params { QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_AFTER_LAST - 1 }; +/** + * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor + * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. + * @QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL: CFR method using QOS Null frame. + * @QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE: CFR method using QOS Null frame + * with phase + * @QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE: CFR method using probe response frame + */ +enum qca_wlan_vendor_cfr_method { + QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL = 0, + QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE = 1, + QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE = 2, +}; + +/** + * enum qca_wlan_vendor_cfr_capture_type - QCA vendor CFR capture type used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE. + * @QCA_WLAN_VENDOR_CFR_DIRECT_FTM: Filter directed FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK: Filter all FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP: Filter NDPA NDP directed frames. + * @QCA_WLAN_VENDOR_CFR_TA_RA: Filter frames based on TA/RA/Subtype which + * is provided by one or more of below attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * @QCA_WLAN_CFR_ALL_PACKET: Filter all packets. + * @QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL: Filter all NDPA NDP frames. + */ +enum qca_wlan_vendor_cfr_capture_type { + QCA_WLAN_VENDOR_CFR_DIRECT_FTM = 0, + QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK = 1, + QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP = 2, + QCA_WLAN_VENDOR_CFR_TA_RA = 3, + QCA_WLAN_VENDOR_CFR_ALL_PACKET = 4, + QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL = 5, +}; + +/** + * enum qca_wlan_vendor_peer_cfr_capture_attr - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG to configure peer + * Channel Frequency Response capture parameters and enable periodic CFR + * capture. + * + * @QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR: Optional (6-byte MAC address) + * MAC address of peer. This is for CFR version 1 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE: Required (flag) + * Enable peer CFR Capture. This attribute is mandatory to + * enable peer CFR capture. If this attribute is not present, + * peer CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH: Optional (u8) + * BW of measurement, attribute uses the values in enum nl80211_chan_width + * Supported values: 20, 40, 80, 80+80, 160. + * Note that all targets may not support all bandwidths. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY: Optional (u32) + * Periodicity of CFR measurement in msec. + * Periodicity should be a multiple of Base timer. + * Current Base timer value supported is 10 msecs (default). + * 0 for one shot capture. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD: Optional (u8) + * Method used to capture Channel Frequency Response. + * Attribute uses the values defined in enum qca_wlan_vendor_cfr_method. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE: Optional (flag) + * Enable periodic CFR capture. + * This attribute is mandatory for version 1 to enable Periodic CFR capture. + * If this attribute is not present, periodic CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_CFR_VERSION: Optional (u8) + * Value is 1 or 2 since there are two versions of CFR capture. Two versions + * can't be enabled at same time. This attribute is mandatory if target + * support both versions and use one of them. + * + * @QCA_WLAN_VENDOR_ATTR_CFR_ENABLE_GROUP_BITMAP: Optional (u32) + * This attribute is mandatory for version 2 if + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY is used. + * Bits 15:0 Bit fields indicating which group to be enabled. + * Bits 31:16 Reserved for future use. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION: Optional (u32) + * CFR capture duration in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL: Optional (u32) + * CFR capture interval in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE: Optional (u32) + * CFR capture type is defined in enum qca_wlan_vendor_cfr_capture_type. + * This attribute is mandatory for version 2. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK: Optional (u64) + * Bit fields indicating which user in the current UL MU + * transmissions are enabled for CFR capture. Bits 36 to 0 indicating + * user indexes for 37 users in a UL MU transmission. If bit 0 is set, + * then the CFR capture will happen for user index 0 in the current + * UL MU transmission. If bits 0,2 are set, then CFR capture for UL MU + * TX corresponds to user indices 0 and 2. Bits 63:37 Reserved for future use. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT: Optional (u32) + * Indicates the number of consecutive Rx packets to be skipped + * before CFR capture is enabled again. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE: Nested attribute containing + * one or more %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY attributes. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY: Nested attribute containing + * the following GROUP attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER: Optional (u32) + * Target support multiple groups for some configurations. Group number could be + * any value between 0 and 15. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA: Optional (6-byte MAC address) + * Transmitter address which is used to filter packets, this MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA: Optional (6-byte MAC address) + * Receiver address which is used to filter packets, this MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK: Optional (6-byte MAC address) + * Mask of transmitter address which is used to filter packets. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK: Optional (6-byte MAC address) + * Mask of receiver address which is used to filter packets. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS: Optional (u32) + * Indicates packets with a specific NSS will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 7:0, CFR capture will + * be done for packets matching the NSS specified within this bitmask. + * Bits 31:8 Reserved for future use. Bits 7:0 map to NSS: + * bit 0 : NSS 1 + * bit 1 : NSS 2 + * ... + * bit 7 : NSS 8 + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW: Optional (u32) + * Indicates packets with a specific BW will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 4:0, CFR capture + * will be done for packets matching the bandwidths specified within this + * bitmask. Bits 31:5 Reserved for future use. Bits 4:0 map to bandwidth + * numerated in enum nl80211_band (although not all bands may be supported + * by a given device). + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER: Optional (u32) + * Management packets matching the subtype filter categories will be + * filtered in by MAC for CFR capture. This is a bitmask, in which each bit + * represents the corresponding mgmt subtype value as per + * IEEE 802.11(2016) 9.2.4.1.3 Type and Subtype subfields. + * For example, beacon frame control type is 8, its value is 1<<8 = 0x100. + * This is for CFR version 2 only + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER: Optional (u32) + * Control packets matching the subtype filter categories will be + * filtered in by MAC for CFR capture. This is a bitmask, in which each bit + * represents the corresponding control subtype value as per + * IEEE 802.11(2016) 9.2.4.1.3 Type and Subtype subfields. + * This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER: Optional (u32) + * Data packets matching the subtype filter categories will be + * filtered in by MAC for CFR capture. This is a bitmask, in which each bit + * represents the corresponding data subtype value as per + * IEEE 802.11(2016) 9.2.4.1.3 Type and Subtype subfields. + * This is for CFR version 2 only. + * + */ +enum qca_wlan_vendor_peer_cfr_capture_attr { + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE = 2, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH = 3, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY = 4, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD = 5, + QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE = 6, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION = 7, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP = 8, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL = 10, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE = 11, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK = 12, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE = 14, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY = 15, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER = 16, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA = 17, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA = 18, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK = 19, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK = 20, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS = 21, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW = 22, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX = + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST - 1, +}; + /** * enum qca_coex_config_profiles - This enum defines different types of * traffic streams that can be prioritized one over the other during coex @@ -7958,14 +8948,23 @@ enum qca_wlan_vendor_attr_beacon_reporting_params { * enum qca_wlan_vendor_attr_oem_data_params - Used by the vendor command * QCA_NL80211_VENDOR_SUBCMD_OEM_DATA. * - * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA: The binary blob for the vendor - * command QCA_NL80211_VENDOR_SUBCMD_OEM_DATA are carried through this - * attribute. - * NLA_BINARY attribute, the max size is 1024 bytes. + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA: This NLA_BINARY attribute is + * used to set/query the data to/from the firmware. On query, the same + * attribute is used to carry the respective data in the reply sent by the + * driver to userspace. The request to set/query the data and the format of the + * respective data from the firmware are embedded in the attribute. The + * maximum size of the attribute payload is 1024 bytes. + * Userspace has to set the QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED + * attribute when the data is queried from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED: This NLA_FLAG attribute + * is set when the userspace queries data from the firmware. This attribute + * should not be set when userspace sets the OEM data to the firmware. */ enum qca_wlan_vendor_attr_oem_data_params { QCA_WLAN_VENDOR_ATTR_OEM_DATA_INVALID = 0, QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA = 1, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED = 3, /* keep last */ QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST, @@ -7973,6 +8972,394 @@ enum qca_wlan_vendor_attr_oem_data_params { QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST - 1 }; +/** + * enum qca_wlan_vendor_attr_avoid_frequency_ext - Defines attributes to be + * used with vendor command/event QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required + * Nested attribute containing multiple ranges with following attributes: + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32) + * Starting center frequency in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32) + * Ending center frequency in MHz. + */ +enum qca_wlan_vendor_attr_avoid_frequency_ext { + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3, + + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX = + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST - 1 +}; + +/* + * enum qca_wlan_vendor_attr_add_sta_node_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE. + */ +enum qca_wlan_vendor_attr_add_sta_node_params { + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_INVALID = 0, + /* 6 byte MAC address of STA */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_MAC_ADDR = 1, + /* Authentication algorithm used by the station of size u16; + * defined in enum nl80211_auth_type. + */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_AUTH_ALGO = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST - 1 +}; + +/** + * enum qca_btc_chain_mode - Specifies BT coex chain mode. + * This enum defines the valid set of values of BT coex chain mode. + * These values are used by attribute %QCA_VENDOR_ATTR_BTC_CHAIN_MODE of + * %QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_BTC_CHAIN_SHARED: chains of BT and WLAN 2.4G are shared. + * @QCA_BTC_CHAIN_SEPARATED: chains of BT and WLAN 2.4G are separated. + */ +enum qca_btc_chain_mode { + QCA_BTC_CHAIN_SHARED = 0, + QCA_BTC_CHAIN_SEPARATED = 1, +}; + +/** + * enum qca_vendor_attr_btc_chain_mode - Specifies attributes for BT coex + * chain mode. + * Attributes for data used by QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE: u32 attribute. + * Indicates the BT coex chain mode, are 32-bit values from + * enum qca_btc_chain_mode. This attribute is mandatory. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE_RESTART: flag attribute. + * If set, vdev should be restarted when BT coex chain mode is updated. + * This attribute is optional. + */ +enum qca_vendor_attr_btc_chain_mode { + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_INVALID = 0, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE = 1, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART = 2, + + /* Keep last */ + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX = + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST - 1, +}; + +/** + * enum qca_vendor_wlan_sta_flags - Station feature flags + * Bits will be set to 1 if the corresponding features are enabled. + * @QCA_VENDOR_WLAN_STA_FLAG_AMPDU: AMPDU is enabled for the station + * @QCA_VENDOR_WLAN_STA_FLAG_TX_STBC: TX Space-time block coding is enabled + for the station + * @QCA_VENDOR_WLAN_STA_FLAG_RX_STBC: RX Space-time block coding is enabled + for the station + */ +enum qca_vendor_wlan_sta_flags { + QCA_VENDOR_WLAN_STA_FLAG_AMPDU = BIT(0), + QCA_VENDOR_WLAN_STA_FLAG_TX_STBC = BIT(1), + QCA_VENDOR_WLAN_STA_FLAG_RX_STBC = BIT(2), +}; + +/** + * enum qca_vendor_wlan_sta_guard_interval - Station guard interval + * @QCA_VENDOR_WLAN_STA_GI_800_NS: Legacy normal guard interval + * @QCA_VENDOR_WLAN_STA_GI_400_NS: Legacy short guard interval + * @QCA_VENDOR_WLAN_STA_GI_1600_NS: Guard interval used by HE + * @QCA_VENDOR_WLAN_STA_GI_3200_NS: Guard interval used by HE + */ +enum qca_vendor_wlan_sta_guard_interval { + QCA_VENDOR_WLAN_STA_GI_800_NS = 0, + QCA_VENDOR_WLAN_STA_GI_400_NS = 1, + QCA_VENDOR_WLAN_STA_GI_1600_NS = 2, + QCA_VENDOR_WLAN_STA_GI_3200_NS = 3, +}; + +/** + * enum qca_wlan_vendor_attr_get_sta_info - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC: + * Required attribute in request for AP mode only, 6-byte MAC address, + * corresponding to the station's MAC address for which information is + * requested. For STA mode this is not required as the info always correspond + * to the self STA and the current/last association. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS: + * Optionally used in response, u32 attribute, contains a bitmap of different + * fields defined in enum qca_vendor_wlan_sta_flags, used in AP mode only. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL: + * Optionally used in response, u32 attribute, possible values are defined in + * enum qca_vendor_wlan_sta_guard_interval, used in AP mode only. + * Guard interval used by the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames received from station with retry + * bit set to 1 in FC. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter for number of data frames with broadcast or multicast address in + * the destination address received from the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED: + * Optionally used in response, u32 attribute, used in both STA and AP modes. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets and for which the TX status has been updated + * back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA and AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet and for which the TX status has been + * updated back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter in the target for the number of data frames successfully transmitted + * to the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA & AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT: u32, used in + * the STA mode only. Represent the number of probe requests sent by the STA + * while attempting to roam on missing certain number of beacons from the + * connected AP. If queried in the disconnected state, this represents the + * count for the last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT: u32, used in + * the STA mode. Represent the number of probe responses received by the station + * while attempting to roam on missing certain number of beacons from the + * connected AP. When queried in the disconnected state, this represents the + * count when in last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT: u32, used in the + * STA mode only. Represents the total number of frames sent out by STA + * including Data, ACK, RTS, CTS, Control Management. This data is maintained + * only for the connect session. Represents the count of last connected session, + * when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT: u32, used in the STA mode. + * Total number of RTS sent out by the STA. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT: u32, used in the + * STA mode.Represent the number of RTS transmission failure that reach retry + * limit. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT: u32, used in + * the STA mode. Represent the total number of non aggregated frames transmitted + * by the STA. This data is maintained per connect session. Represents the count + * of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT: u32, used in the + * STA mode. Represent the total number of aggregated frames transmitted by the + * STA. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT: u32, used in + * the STA mode. Represents the number of received frames with a good PLCP. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT: u32, + * used in the STA mode. Represents the number of occasions that no valid + * delimiter is detected by A-MPDU parser. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT: u32, used in the + * STA mode. Represents the number of frames for which CRC check failed in the + * MAC. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT: u32, used in the + * STA mode. Represents the number of unicast ACKs received with good FCS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT: u32, used in the STA + * mode. Represents the number of received Block Acks. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT: u32, used in the STA + * mode. Represents the number of beacons received from the connected BSS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT: u32, used in the + * STA mode. Represents the number of beacons received by the other BSS when in + * connected state (through the probes done by the STA). This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT: u64, used in + * the STA mode. Represents the number of received DATA frames with good FCS and + * matching Receiver Address when in connected state. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT: u32, used in the + * STA mode. Represents the number of RX Data multicast frames dropped by the HW + * when in the connected state. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS: u32, used in the + * STA mode. This represents the target power in dBm for the transmissions done + * to the AP in 2.4 GHz at 1 Mbps (DSSS) rate. This data is maintained per + * connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 5 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in + * the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for for transmissions done + * to the AP in 5 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT: u32, used + * in the STA mode. This represents the Nested attribute representing the + * overflow counts of each receive buffer allocated to the hardware during the + * STA's connection. The number of hw buffers might vary for each WLAN + * solution and hence this attribute represents the nested array of all such + * HW buffer count. This data is maintained per connect session. Represents + * the count of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER: u32, Max TX power (dBm) + * allowed as per the regulatory requirements for the current or last connected + * session. Used in the STA mode. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER: u32, Latest TX power + * (dBm) used by the station in its latest unicast frame while communicating + * to the AP in the connected state. When queried in the disconnected state, + * this represents the TX power used by the STA with last AP communication + * when in connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL: u32, Adaptive noise immunity + * level used to adjust the RX sensitivity. Represents the current ANI level + * when queried in the connected state. When queried in the disconnected + * state, this corresponds to the latest ANI level at the instance of + * disconnection. + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with an invalid MIC or a missing MME when PMF is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with the packet number less than or equal to the + * last received packet number when PMF is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT: u32, used in STA + * mode only. This represents the number of Beacon frames received from this + * station with an invalid MIC or a missing MME when beacon protection is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode + * only. This represents number of Beacon frames received from this station with + * the packet number less than or equal to the last received packet number when + * beacon protection is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in + * STA mode only. Driver uses this attribute to populate the connection failure + * reason codes and the values are defined in + * enum qca_sta_connect_fail_reason_codes. Userspace applications can send + * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving + * connection failure from driver. The driver shall not include this attribute + * in response to QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no + * connection failure observed in the last attempted connection. + */ +enum qca_wlan_vendor_attr_get_sta_info { + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC = 1, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS = 2, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL = 3, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT = 4, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED = 6, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED = 7, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL = 8, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY = 9, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED = 10, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT = 11, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT = 12, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT = 14, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT = 15, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT = 16, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT = 17, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT = 18, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT = 19, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT = 20, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT = 21, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT = 22, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT = 23, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT = 24, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT = 25, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT = 26, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS = 27, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS = 28, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0 = 29, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS = 30, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0 = 31, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT = 32, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER = 33, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER = 34, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL = 35, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT = 39, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST - 1, +}; + /** * enum qca_disconnect_reason_codes - Specifies driver disconnect reason codes. * Used when the driver triggers the STA to disconnect from the AP. @@ -8053,6 +9440,34 @@ enum qca_disconnect_reason_codes { QCA_DISCONNECT_REASON_USER_TRIGGERED = 16, }; +/** + * enum qca_sta_connect_fail_reason_codes - Defines values carried + * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor + * attribute. + * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No probe response frame received + * for unicast probe request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for + * ath request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not + * received from AP. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send assoc + * request. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for + * assoc request. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Assoc response is not + * received from AP. + */ +enum qca_sta_connect_fail_reason_codes { + QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1, + QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7, +}; + /** * enum qca_wlan_vendor_attr_driver_disconnect_reason - Defines attributes * used by %QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON vendor command. diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/inc/wlan_cfg80211_scan.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/inc/wlan_cfg80211_scan.h index aee2d3b5ef902344d1f58e7c9870051c335a6e41..7d7aecd2c93cb54aa9483a6ef085e9994927278c 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/inc/wlan_cfg80211_scan.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/inc/wlan_cfg80211_scan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -108,6 +108,7 @@ enum scan_source { * @scan_id: scan identifier used across host layers which is generated at WMI * @source: scan request originator (NL/Vendor scan) * @dev: net device (same as what is in scan_request) + * @scan_start_timestamp: scan start time * * Scan request linked list element */ @@ -117,6 +118,7 @@ struct scan_req { uint32_t scan_id; uint8_t source; struct net_device *dev; + qdf_time_t scan_start_timestamp; }; /** @@ -128,6 +130,14 @@ struct scan_req { * @half_rate: Half rate flag * @quarter_rate: Quarter rate flag * @strict_pscan: strict passive scan flag + * @dwell_time_active: Active dwell time. Ignored if zero or inapplicable. + * @dwell_time_active_2g: 2.4 GHz specific active dwell time. Ignored if zero or + * inapplicable. + * @dwell_time_passive: Passive dwell time. Ignored if zero or inapplicable. + * @dwell_time_active_6g: 6 GHz specific active dwell time. Ignored if zero or + * inapplicable. + * @dwell_time_passive_6g: 6 GHz specific passive dwell time. Ignored if zero or + * inapplicable. */ struct scan_params { uint8_t source; @@ -137,6 +147,11 @@ struct scan_params { bool half_rate; bool quarter_rate; bool strict_pscan; + uint32_t dwell_time_active; + uint32_t dwell_time_active_2g; + uint32_t dwell_time_passive; + uint32_t dwell_time_active_6g; + uint32_t dwell_time_passive_6g; }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/src/wlan_cfg80211_scan.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/src/wlan_cfg80211_scan.c index 855124cabc7a76e2103c5b16f3a47d35d5f48308..199feba31c5076357d7b84095f46d7f19696e5ff 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +22,7 @@ #include #include +#include #include #include #include @@ -86,8 +86,8 @@ static void wlan_fill_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, *randomize = true; memcpy(addr, mac_addr, QDF_MAC_ADDR_SIZE); memcpy(mask, mac_addr_mask, QDF_MAC_ADDR_SIZE); - cfg80211_debug("Random mac addr: %pM and Random mac mask: %pM", - addr, mask); + osif_debug("Random mac addr: "QDF_MAC_ADDR_FMT" and Random mac mask: "QDF_FULL_MAC_FMT, + QDF_MAC_ADDR_REF(addr), QDF_FULL_MAC_REF(mask)); } /** @@ -150,39 +150,42 @@ static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, * Return: None */ static void -wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req, +wlan_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc, + struct pno_scan_req_params *pno_req, struct cfg80211_sched_scan_request *request) { + if (!ucfg_scan_get_user_config_sched_scan_plan(psoc) || + request->n_scan_plans == 1) { + pno_req->fast_scan_period = + request->scan_plans[0].interval * MSEC_PER_SEC; + /* + * if only one scan plan is configured from framework + * then both fast and slow scan should be configured with the + * same value that is why fast scan cycles are hardcoded to one + */ + pno_req->fast_scan_max_cycles = 1; + pno_req->slow_scan_period = + request->scan_plans[0].interval * MSEC_PER_SEC; + } /* * As of now max 2 scan plans were supported by firmware * if number of scan plan supported by firmware increased below logic * must change. */ - if (request->n_scan_plans == SCAN_PNO_MAX_PLAN_REQUEST) { + else if (request->n_scan_plans == SCAN_PNO_MAX_PLAN_REQUEST) { pno_req->fast_scan_period = request->scan_plans[0].interval * MSEC_PER_SEC; pno_req->fast_scan_max_cycles = request->scan_plans[0].iterations; pno_req->slow_scan_period = request->scan_plans[1].interval * MSEC_PER_SEC; - } else if (request->n_scan_plans == 1) { - pno_req->fast_scan_period = - request->scan_plans[0].interval * MSEC_PER_SEC; - /* - * if only one scan plan is configured from framework - * then both fast and slow scan should be configured with the - * same value that is why fast scan cycles are hardcoded to one - */ - pno_req->fast_scan_max_cycles = 1; - pno_req->slow_scan_period = - request->scan_plans[0].interval * MSEC_PER_SEC; } else { - cfg80211_err("Invalid number of scan plans %d !!", - request->n_scan_plans); + osif_err("Invalid number of scan plans %d !!", + request->n_scan_plans); } } #else -#define wlan_config_sched_scan_plan(pno_req, request) \ +#define wlan_config_sched_scan_plan(psoc, pno_req, request) \ __wlan_config_sched_scan_plan(pno_req, request, psoc) static void @@ -235,17 +238,17 @@ static void wlan_cfg80211_pno_callback(struct wlan_objmgr_vdev *vdev, if (event->type != SCAN_EVENT_TYPE_NLO_COMPLETE) return; - cfg80211_debug("vdev id = %d", event->vdev_id); + osif_debug("vdev id = %d", event->vdev_id); pdev = wlan_vdev_get_pdev(vdev); if (!pdev) { - cfg80211_err("pdev is NULL"); + osif_err("pdev is NULL"); return; } pdev_ospriv = wlan_pdev_get_ospriv(pdev); if (!pdev_ospriv) { - cfg80211_err("pdev_ospriv is NULL"); + osif_err("pdev_ospriv is NULL"); return; } wlan_cfg80211_sched_scan_results(pdev_ospriv->wiphy, 0); @@ -264,12 +267,13 @@ static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc) static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs( struct wlan_objmgr_psoc *psoc, - u8 channel, bool *ok) + u16 chan_freq, bool *ok) { - QDF_STATUS status = policy_mgr_is_chan_ok_for_dnbs(psoc, channel, ok); + QDF_STATUS status = policy_mgr_is_chan_ok_for_dnbs( + psoc, chan_freq, ok); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("DNBS check failed"); + osif_err("DNBS check failed"); return status; } @@ -283,7 +287,7 @@ static bool wlan_cfg80211_is_ap_go_present(struct wlan_objmgr_psoc *psoc) static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs( struct wlan_objmgr_psoc *psoc, - u8 channel, + u16 chan_freq, bool *ok) { if (!ok) @@ -394,14 +398,15 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, struct pno_scan_req_params *req; int i, j, ret = 0; QDF_STATUS status; - uint8_t num_chan = 0, channel; + uint8_t num_chan = 0; + uint16_t chan_freq; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); struct wlan_objmgr_psoc *psoc; uint32_t valid_ch[SCAN_PNO_MAX_NETW_CHANNELS_EX] = {0}; bool enable_dfs_pno_chnl_scan; if (ucfg_scan_get_pno_in_progress(vdev)) { - cfg80211_debug("pno is already in progress"); + osif_debug("pno is already in progress"); return -EBUSY; } @@ -427,15 +432,15 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, if ((!req->networks_cnt) || (req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) { - cfg80211_err("Network input is not correct %d", - req->networks_cnt); + osif_err("Network input is not correct %d", + req->networks_cnt); ret = -EINVAL; goto error; } if (request->n_channels > SCAN_PNO_MAX_NETW_CHANNELS_EX) { - cfg80211_err("Incorrect number of channels %d", - request->n_channels); + osif_err("Incorrect number of channels %d", + request->n_channels); ret = -EINVAL; goto error; } @@ -454,14 +459,14 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, goto error; } for (i = 0; i < request->n_channels; i++) { - channel = request->channels[i]->hw_value; + chan_freq = request->channels[i]->center_freq; if ((!enable_dfs_pno_chnl_scan) && - (wlan_reg_is_dfs_ch(pdev, channel))) { - cfg80211_debug("Dropping DFS channel :%d", - channel); + (wlan_reg_is_dfs_for_freq(pdev, chan_freq))) { + osif_debug("Dropping DFS channel freq :%d", + chan_freq); continue; } - if (wlan_reg_is_dsrc_chan(pdev, channel)) + if (wlan_reg_is_dsrc_freq(chan_freq)) continue; if (ap_or_go_present) { @@ -469,10 +474,10 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, status = wlan_cfg80211_is_chan_ok_for_dnbs(psoc, - channel, + chan_freq, &ok); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("DNBS check failed"); + osif_err("DNBS check failed"); qdf_mem_free(chl); chl = NULL; ret = -EINVAL; @@ -481,17 +486,17 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, if (!ok) continue; } - len += qdf_scnprintf(chl + len, buff_len - len, " %d", channel); - valid_ch[num_chan++] = wlan_chan_to_freq(channel); + len += qdf_scnprintf(chl + len, buff_len - len, " %d", chan_freq); + valid_ch[num_chan++] = chan_freq; } - cfg80211_debug("Channel-List[%d]:%s", num_chan, chl); + osif_debug("Channel-List[%d]:%s", num_chan, chl); qdf_mem_free(chl); chl = NULL; /* If all channels are DFS and dropped, * then ignore the PNO request */ if (!num_chan) { - cfg80211_notice("Channel list empty due to filtering of DSRC"); + osif_notice("Channel list empty due to filtering of DSRC"); ret = -EINVAL; goto error; } @@ -504,8 +509,8 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, if ((!req->networks_list[i].ssid.length) || (req->networks_list[i].ssid.length > WLAN_SSID_MAX_LEN)) { - cfg80211_err(" SSID Len %d is not correct for network %d", - req->networks_list[i].ssid.length, i); + osif_err(" SSID Len %d is not correct for network %d", + req->networks_list[i].ssid.length, i); ret = -EINVAL; goto error; } @@ -564,9 +569,10 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, * switches slow_scan_period. This is less frequent scans and firmware * shall be in slow_scan_period mode until next PNO Start. */ - wlan_config_sched_scan_plan(req, request); + wlan_config_sched_scan_plan(psoc, req, request); req->delay_start_time = wlan_config_sched_scan_start_delay(request); req->scan_backoff_multiplier = scan_backoff_multiplier; + wlan_hdd_sched_scan_update_relative_rssi(req, request); psoc = wlan_pdev_get_psoc(pdev); @@ -580,22 +586,22 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, if (ucfg_ie_whitelist_enabled(psoc, vdev)) ucfg_copy_ie_whitelist_attrs(psoc, &req->ie_whitelist); - cfg80211_debug("Network count %d n_ssids %d fast_scan_period: %d msec slow_scan_period: %d msec, fast_scan_max_cycles: %d, relative_rssi %d band_pref %d, rssi_pref %d", - req->networks_cnt, request->n_ssids, - req->fast_scan_period, req->slow_scan_period, - req->fast_scan_max_cycles, req->relative_rssi, - req->band_rssi_pref.band, req->band_rssi_pref.rssi); + osif_debug("Network count %d n_ssids %d fast_scan_period: %d msec slow_scan_period: %d msec, fast_scan_max_cycles: %d, relative_rssi %d band_pref %d, rssi_pref %d", + req->networks_cnt, request->n_ssids, req->fast_scan_period, + req->slow_scan_period, req->fast_scan_max_cycles, + req->relative_rssi, req->band_rssi_pref.band, + req->band_rssi_pref.rssi); for (i = 0; i < req->networks_cnt; i++) - cfg80211_debug("[%d] ssid: %.*s, RSSI th %d bc NW type %u", - i, req->networks_list[i].ssid.length, - req->networks_list[i].ssid.ssid, - req->networks_list[i].rssi_thresh, - req->networks_list[i].bc_new_type); + osif_debug("[%d] ssid: %.*s, RSSI th %d bc NW type %u", + i, req->networks_list[i].ssid.length, + req->networks_list[i].ssid.ssid, + req->networks_list[i].rssi_thresh, + req->networks_list[i].bc_new_type); status = ucfg_scan_pno_start(vdev, req); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Failed to enable PNO"); + osif_err("Failed to enable PNO"); ret = -EINVAL; goto error; } @@ -611,7 +617,7 @@ int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev) status = ucfg_scan_pno_stop(vdev); if (QDF_IS_STATUS_ERROR(status)) - cfg80211_debug("Failed to disable PNO"); + osif_debug("Failed to disable PNO"); return 0; } @@ -681,6 +687,7 @@ wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev, scan_req->source = source; scan_req->scan_id = scan_start_req->scan_req.scan_id; scan_req->dev = req->wdev->netdev; + scan_req->scan_start_timestamp = qdf_get_time_of_the_day_ms(); qdf_mutex_acquire(&osif_scan->scan_req_q_lock); if (qdf_list_size(&osif_scan->scan_req_q) < WLAN_MAX_SCAN_COUNT) { @@ -689,9 +696,9 @@ wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev, qdf_list_insert_back(&osif_scan->scan_req_q, &scan_req->node); } else { - cfg80211_err("scan req failed with error %d", status); + osif_err("scan req failed with error %d", status); if (status == QDF_STATUS_E_RESOURCES) - cfg80211_err("HO is in progress.So defer the scan by informing busy"); + osif_err("HO is in progress.So defer the scan by informing busy"); } } else { ucfg_scm_scan_free_scan_request_mem(scan_start_req); @@ -700,8 +707,8 @@ wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev, qdf_mutex_release(&osif_scan->scan_req_q_lock); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_debug_rl("Failed to enqueue Scan Req as max scan %d already queued", - qdf_list_size(&osif_scan->scan_req_q)); + osif_rl_debug("Failed to enqueue Scan Req as max scan %d already queued", + qdf_list_size(&osif_scan->scan_req_q)); qdf_mem_free(scan_req); } @@ -721,7 +728,8 @@ wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev, static QDF_STATUS wlan_scan_request_dequeue( struct wlan_objmgr_pdev *pdev, uint32_t scan_id, struct cfg80211_scan_request **req, - uint8_t *source, struct net_device **dev) + uint8_t *source, struct net_device **dev, + qdf_time_t *scan_start_timestamp) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct scan_req *scan_req; @@ -730,21 +738,21 @@ static QDF_STATUS wlan_scan_request_dequeue( struct osif_scan_pdev *scan_priv; if ((!source) || (!req)) { - cfg80211_err("source or request is NULL"); + osif_err("source or request is NULL"); return QDF_STATUS_E_NULL_VALUE; } /* Get NL global context from objmgr*/ osif_ctx = wlan_pdev_get_ospriv(pdev); if (!osif_ctx) { - cfg80211_err("Failed to retrieve osif context"); + osif_err("Failed to retrieve osif context"); return status; } scan_priv = osif_ctx->osif_scan; qdf_mutex_acquire(&scan_priv->scan_req_q_lock); if (qdf_list_empty(&scan_priv->scan_req_q)) { - cfg80211_info("Scan List is empty"); + osif_info("Scan List is empty"); qdf_mutex_release(&scan_priv->scan_req_q_lock); return QDF_STATUS_E_FAILURE; } @@ -752,40 +760,40 @@ static QDF_STATUS wlan_scan_request_dequeue( if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&scan_priv->scan_req_q, &next_node)) { qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_err("Failed to remove Scan Req from queue"); + osif_err("Failed to remove Scan Req from queue"); return QDF_STATUS_E_FAILURE; } do { node = next_node; - scan_req = qdf_container_of(node, struct scan_req, - node); + scan_req = qdf_container_of(node, struct scan_req, node); if (scan_req->scan_id == scan_id) { status = qdf_list_remove_node(&scan_priv->scan_req_q, - node); + node); if (status == QDF_STATUS_SUCCESS) { *req = scan_req->scan_request; *source = scan_req->source; *dev = scan_req->dev; + *scan_start_timestamp = + scan_req->scan_start_timestamp; qdf_mem_free(scan_req); qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_debug("removed Scan id: %d, req = %pK, pending scans %d", - scan_id, req, - qdf_list_size(&scan_priv-> - scan_req_q)); + osif_debug("removed Scan id: %d, req = %pK, pending scans %d", + scan_id, req, + qdf_list_size(&scan_priv->scan_req_q)); return QDF_STATUS_SUCCESS; } else { qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_err("Failed to remove scan id %d, pending scans %d", - scan_id, - qdf_list_size(&scan_priv->scan_req_q)); + osif_err("Failed to remove scan id %d, pending scans %d", + scan_id, + qdf_list_size(&scan_priv->scan_req_q)); return status; } } } while (QDF_STATUS_SUCCESS == qdf_list_peek_next(&scan_priv->scan_req_q, node, &next_node)); qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_debug("Failed to find scan id %d", scan_id); + osif_debug("Failed to find scan id %d", scan_id); return status; } @@ -850,14 +858,16 @@ static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req, int i; uint8_t scan_status; uint64_t cookie; + int index = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX; - skb = cfg80211_vendor_event_alloc(req->wdev->wiphy, req->wdev, - SCAN_DONE_EVENT_BUF_SIZE + 4 + NLMSG_HDRLEN, - QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX, - GFP_ATOMIC); + skb = wlan_cfg80211_vendor_event_alloc(req->wdev->wiphy, req->wdev, + SCAN_DONE_EVENT_BUF_SIZE + 4 + + NLMSG_HDRLEN, + index, + GFP_ATOMIC); if (!skb) { - cfg80211_err("skb alloc failed"); + osif_err("skb alloc failed"); qdf_mem_free(req); return; } @@ -900,13 +910,13 @@ static void wlan_vendor_scan_callback(struct cfg80211_scan_request *req, if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_SCAN_STATUS, scan_status)) goto nla_put_failure; - cfg80211_vendor_event(skb, GFP_ATOMIC); + wlan_cfg80211_vendor_event(skb, GFP_ATOMIC); qdf_mem_free(req); return; nla_put_failure: - kfree_skb(skb); + wlan_cfg80211_vendor_free_skb(skb); qdf_mem_free(req); } @@ -963,6 +973,36 @@ void wlan_scan_release_wake_lock(struct wlan_objmgr_psoc *psoc, } #endif +static +uint32_t wlan_scan_get_bss_count_for_scan(struct wlan_objmgr_pdev *pdev, + qdf_time_t scan_start_ts) +{ + struct scan_filter *filter; + qdf_list_t *list = NULL; + uint32_t count = 0; + + if (!scan_start_ts) + return count; + + filter = qdf_mem_malloc(sizeof(*filter)); + if (!filter) + return count; + + filter->ignore_auth_enc_type = true; + filter->age_threshold = qdf_get_time_of_the_day_ms() - scan_start_ts; + + list = ucfg_scan_get_result(pdev, filter); + + qdf_mem_free(filter); + + if (list) { + count = qdf_list_size(list); + ucfg_scan_purge_results(list); + } + + return count; +} + /** * wlan_cfg80211_scan_done_callback() - scan done callback function called after * scan is finished @@ -979,44 +1019,49 @@ static void wlan_cfg80211_scan_done_callback( { struct cfg80211_scan_request *req = NULL; bool success = false; - uint32_t scan_id = event->scan_id; + uint32_t scan_id; uint8_t source = NL_SCAN; struct wlan_objmgr_pdev *pdev; struct pdev_osif_priv *osif_priv; struct net_device *netdev = NULL; QDF_STATUS status; + qdf_time_t scan_start_timestamp = 0; + uint32_t unique_bss_count = 0; + + if (!event) { + osif_nofl_err("Invalid scan event received"); + return; + } + + scan_id = event->scan_id; qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_OS_IF, event->type, - event->vdev_id, event->scan_id); + event->vdev_id, scan_id); + + if (event->type == SCAN_EVENT_TYPE_STARTED) + osif_nofl_info("scan start scan id %d", scan_id); if (!util_is_scan_completed(event, &success)) return; - cfg80211_debug("vdev %d, scan id %d type %s(%d) reason %s(%d)", - event->vdev_id, scan_id, - util_scan_get_ev_type_name(event->type), event->type, - util_scan_get_ev_reason_name(event->reason), - event->reason); - pdev = wlan_vdev_get_pdev(vdev); status = wlan_scan_request_dequeue( - pdev, scan_id, &req, &source, &netdev); + pdev, scan_id, &req, &source, &netdev, + &scan_start_timestamp); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Dequeue of scan request failed ID: %d", scan_id); + osif_err("Dequeue of scan request failed ID: %d", scan_id); goto allow_suspend; } if (!netdev) { - cfg80211_err("net dev is NULL,Drop scan event Id: %d", - scan_id); + osif_err("net dev is NULL,Drop scan event Id: %d", scan_id); goto allow_suspend; } /* Make sure vdev is active */ status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Failed to get vdev reference: scan Id: %d", - scan_id); + osif_err("Failed to get vdev reference: scan Id: %d", scan_id); goto allow_suspend; } @@ -1033,6 +1078,14 @@ static void wlan_cfg80211_scan_done_callback( wlan_vendor_scan_callback(req, !success); wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + + unique_bss_count = wlan_scan_get_bss_count_for_scan(pdev, + scan_start_timestamp); + osif_nofl_info("vdev %d, scan id %d type %s(%d) reason %s(%d) scan found %d bss", + event->vdev_id, scan_id, + util_scan_get_ev_type_name(event->type), event->type, + util_scan_get_ev_reason_name(event->reason), + event->reason, unique_bss_count); allow_suspend: osif_priv = wlan_pdev_get_ospriv(pdev); qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock); @@ -1059,6 +1112,7 @@ static void wlan_cfg80211_scan_done_callback( } else { qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); } + } QDF_STATUS wlan_scan_runtime_pm_init(struct wlan_objmgr_pdev *pdev) @@ -1189,7 +1243,7 @@ wlan_cfg80211_enqueue_for_cleanup(qdf_list_t *scan_cleanup_q, qdf_list_remove_node(&scan_priv->scan_req_q, node)) { qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_err("Failed to remove scan request"); + osif_err("Failed to remove scan request"); return; } qdf_mem_free(scan_req); @@ -1212,7 +1266,7 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev, qdf_list_node_t *node = NULL; if (!pdev) { - cfg80211_err("pdev is Null"); + osif_err("pdev is Null"); return; } @@ -1230,7 +1284,7 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev, while (!qdf_list_empty(&scan_cleanup_q)) { if (QDF_STATUS_SUCCESS != qdf_list_remove_front(&scan_cleanup_q, &node)) { - cfg80211_err("Failed to remove scan request"); + osif_err("Failed to remove scan request"); return; } scan_req = container_of(node, struct scan_req, node); @@ -1299,7 +1353,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, struct wlan_ssid *pssid; uint8_t i; int ret = 0; - uint8_t num_chan = 0, channel; + uint8_t num_chan = 0; uint32_t c_freq; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); wlan_scan_requester req_id; @@ -1314,18 +1368,18 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, psoc = wlan_pdev_get_psoc(pdev); if (!psoc) { - cfg80211_err("Invalid psoc object"); + osif_err("Invalid psoc object"); return -EINVAL; } opmode = wlan_vdev_mlme_get_opmode(vdev); - cfg80211_debug("%s(vdev%d): mode %d", request->wdev->netdev->name, - wlan_vdev_get_id(vdev), opmode); + osif_debug("%s(vdev%d): mode %d", request->wdev->netdev->name, + wlan_vdev_get_id(vdev), opmode); /* Get NL global context from objmgr*/ osif_priv = wlan_pdev_get_ospriv(pdev); if (!osif_priv) { - cfg80211_err("Invalid osif priv object"); + osif_err("Invalid osif priv object"); return -EINVAL; } @@ -1339,7 +1393,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, !qdf_list_empty(&osif_priv->osif_scan->scan_req_q) && opmode != QDF_SAP_MODE) { qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); - cfg80211_err("Simultaneous scan disabled, reject scan"); + osif_err("Simultaneous scan disabled, reject scan"); return -EBUSY; } qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock); @@ -1354,7 +1408,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, req_id = osif_priv->osif_scan->req_id; scan_id = ucfg_scan_get_scan_id(psoc); if (!scan_id) { - cfg80211_err("Invalid scan id"); + osif_err("Invalid scan id"); qdf_mem_free(req); return -EINVAL; } @@ -1383,9 +1437,9 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, req->scan_req.num_ssids = request->n_ssids; if (req->scan_req.num_ssids > WLAN_SCAN_MAX_NUM_SSID) { - cfg80211_info("number of ssid %d greater than MAX %d", - req->scan_req.num_ssids, - WLAN_SCAN_MAX_NUM_SSID); + osif_info("number of ssid %d greater than MAX %d", + req->scan_req.num_ssids, + WLAN_SCAN_MAX_NUM_SSID); req->scan_req.num_ssids = WLAN_SCAN_MAX_NUM_SSID; } /* copy all the ssid's and their length */ @@ -1419,6 +1473,24 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, if (is_p2p_scan && request->no_cck) req->scan_req.scan_type = SCAN_TYPE_P2P_SEARCH; + if (params->dwell_time_active) + req->scan_req.dwell_time_active = params->dwell_time_active; + + if (params->dwell_time_active_2g) + req->scan_req.dwell_time_active_2g = + params->dwell_time_active_2g; + + if (params->dwell_time_passive) + req->scan_req.dwell_time_passive = params->dwell_time_passive; + + if (params->dwell_time_active_6g) + req->scan_req.dwell_time_active_6g = + params->dwell_time_active_6g; + + if (params->dwell_time_passive_6g) + req->scan_req.dwell_time_passive_6g = + params->dwell_time_passive_6g; + /* Set dwell time mode according to scan policy type flags */ if (ucfg_scan_cfg_honour_nl_scan_policy_flags(psoc)) { if (req->scan_req.scan_policy_high_accuracy) @@ -1449,21 +1521,18 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, psoc, PM_P2P_GO_MODE, NULL); #endif for (i = 0; i < request->n_channels; i++) { - channel = request->channels[i]->hw_value; - c_freq = wlan_reg_chan_to_freq(pdev, channel); - if (wlan_reg_is_dsrc_chan(pdev, channel)) + c_freq = request->channels[i]->center_freq; + if (wlan_reg_is_dsrc_freq(c_freq)) continue; #ifdef WLAN_POLICY_MGR_ENABLE if (ap_or_go_present) { bool ok; - qdf_status = - policy_mgr_is_chan_ok_for_dnbs(psoc, - channel, - &ok); + qdf_status = policy_mgr_is_chan_ok_for_dnbs( + psoc, c_freq, &ok); if (QDF_IS_STATUS_ERROR(qdf_status)) { - cfg80211_err("DNBS check failed"); + osif_err("DNBS check failed"); ret = -EINVAL; goto err; } @@ -1480,12 +1549,12 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, req->scan_req.chan_list.chan[num_chan].phymode = SCAN_PHY_MODE_11A; num_chan++; - if (num_chan >= WLAN_SCAN_MAX_NUM_CHANNELS) + if (num_chan >= NUM_CHANNELS) break; } } if (!num_chan) { - cfg80211_err("Received zero non-dsrc channels"); + osif_err("Received zero non-dsrc channels"); ret = -EINVAL; goto err; } @@ -1607,14 +1676,14 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev, /* Get NL global context from objmgr*/ osif_ctx = wlan_pdev_get_ospriv(pdev); if (!osif_ctx) { - cfg80211_err("Failed to retrieve osif context"); + osif_err("Failed to retrieve osif context"); return ret; } scan_priv = osif_ctx->osif_scan; qdf_mutex_acquire(&scan_priv->scan_req_q_lock); if (qdf_list_empty(&scan_priv->scan_req_q)) { qdf_mutex_release(&scan_priv->scan_req_q_lock); - cfg80211_err("Failed to retrieve scan id"); + osif_err("Failed to retrieve scan id"); return ret; } @@ -1660,7 +1729,7 @@ QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev, /* Get NL global context from objmgr*/ osif_ctx = wlan_pdev_get_ospriv(pdev); if (!osif_ctx) { - cfg80211_err("Failed to retrieve osif context"); + osif_err("Failed to retrieve osif context"); qdf_mem_free(req); return QDF_STATUS_E_FAILURE; } @@ -1689,22 +1758,24 @@ QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev, else req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL; - cfg80211_debug("Type %d Vdev %d pdev %d scan id %d sync %d", - req->cancel_req.req_type, req->cancel_req.vdev_id, - req->cancel_req.pdev_id, req->cancel_req.scan_id, sync); + osif_debug("Type %d Vdev %d pdev %d scan id %d sync %d", + req->cancel_req.req_type, req->cancel_req.vdev_id, + req->cancel_req.pdev_id, req->cancel_req.scan_id, sync); if (sync) status = ucfg_scan_cancel_sync(req); else status = ucfg_scan_cancel(req); if (QDF_IS_STATUS_ERROR(status)) - cfg80211_err("Cancel scan request failed"); + osif_err("Cancel scan request failed"); wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return status; } +qdf_export_symbol(wlan_abort_scan); + int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev) { uint8_t pdev_id; @@ -1731,7 +1802,7 @@ int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev, pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, data, data_len, scan_policy)) { - cfg80211_err("Invalid ATTR"); + osif_err("Invalid ATTR"); return ret; } @@ -1752,16 +1823,13 @@ int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev, static inline struct ieee80211_channel * wlan_get_ieee80211_channel(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, - int chan_no) + int chan_freq) { - unsigned int freq; struct ieee80211_channel *chan; - freq = wlan_reg_chan_to_freq(pdev, chan_no); - chan = ieee80211_get_channel(wiphy, freq); + chan = ieee80211_get_channel(wiphy, chan_freq); if (!chan) - cfg80211_err("chan is NULL, chan_no: %d freq: %d", - chan_no, freq); + osif_err("chan is NULL, freq: %d", chan_freq); return chan; } @@ -1832,7 +1900,7 @@ static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data, uint32_t i; if (!bss || !data) { - cfg80211_err("Received bss is NULL"); + osif_err("Received bss is NULL"); return; } for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { @@ -1858,7 +1926,7 @@ wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy, struct cfg80211_inform_bss data = {0}; if (!bss) { - cfg80211_err("bss is null"); + osif_err("bss is null"); return NULL; } wlan_fill_per_chain_rssi(&data, bss); @@ -1904,7 +1972,7 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, struct wlan_cfg80211_inform_bss bss_data = {0}; if (!pdev_ospriv) { - cfg80211_err("os_priv is NULL"); + osif_err("os_priv is NULL"); return; } @@ -1913,8 +1981,8 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, bss_data.frame_len = wlan_get_frame_len(scan_params); bss_data.mgmt = qdf_mem_malloc_atomic(bss_data.frame_len); if (!bss_data.mgmt) { - cfg80211_err("mem alloc failed for bss %pM seq %d", - bss_data.mgmt->bssid, scan_params->seq_num); + osif_err("bss mem alloc failed for seq %d", + scan_params->seq_num); return; } qdf_mem_copy(bss_data.mgmt, @@ -1933,11 +2001,12 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, bss_data.rssi = scan_params->rssi_raw; bss_data.chan = wlan_get_ieee80211_channel(wiphy, pdev, - scan_params->channel.chan_idx); + scan_params->channel.chan_freq); if (!bss_data.chan) { - cfg80211_err("Channel not found for bss %pM seq %d chan %d", - bss_data.mgmt->bssid, scan_params->seq_num, - scan_params->channel.chan_idx); + osif_err("Channel not found for bss "QDF_MAC_ADDR_FMT" seq %d chan_freq %d", + QDF_MAC_ADDR_REF(bss_data.mgmt->bssid), + scan_params->seq_num, + scan_params->channel.chan_freq); qdf_mem_free(bss_data.mgmt); return; } @@ -1955,8 +2024,9 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, bss = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data); if (!bss) - cfg80211_err("failed to inform bss %pM seq %d", - bss_data.mgmt->bssid, scan_params->seq_num); + osif_err("failed to inform bss "QDF_MAC_ADDR_FMT" seq %d", + QDF_MAC_ADDR_REF(bss_data.mgmt->bssid), + scan_params->seq_num); else wlan_cfg80211_put_bss(wiphy, bss); @@ -1996,10 +2066,11 @@ void __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, uint8_t *bssid, bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, ssid, ssid_len); if (!bss) { - cfg80211_info("BSS %pM not found", bssid); + osif_info("BSS "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(bssid)); } else { - cfg80211_debug("unlink entry for ssid:%.*s and BSSID %pM", - ssid_len, ssid, bssid); + osif_debug("unlink entry for ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT, + ssid_len, ssid, QDF_MAC_ADDR_REF(bssid)); cfg80211_unlink_bss(wiphy, bss); wlan_cfg80211_put_bss(wiphy, bss); } @@ -2015,11 +2086,11 @@ void __wlan_cfg80211_unlink_bss_list(struct wiphy *wiphy, uint8_t *bssid, */ bss = wlan_cfg80211_get_bss(wiphy, NULL, bssid, NULL, 0); if (!bss) { - cfg80211_debug("Hidden bss not found for Ssid:%.*s BSSID: %pM sid_len %d", - ssid_len, ssid, bssid, ssid_len); + osif_debug("Hidden bss not found for Ssid:%.*s BSSID: "QDF_MAC_ADDR_FMT" sid_len %d", + ssid_len, ssid, QDF_MAC_ADDR_REF(bssid), ssid_len); } else { - cfg80211_debug("unlink entry for Hidden ssid:%.*s and BSSID %pM", - ssid_len, ssid, bssid); + osif_debug("unlink entry for Hidden ssid:%.*s and BSSID "QDF_MAC_ADDR_FMT, + ssid_len, ssid, QDF_MAC_ADDR_REF(bssid)); cfg80211_unlink_bss(wiphy, bss); /* cfg80211_get_bss get bss with ref count so release it */ @@ -2033,7 +2104,7 @@ void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev, struct wiphy *wiphy; if (!pdev_ospriv) { - cfg80211_err("os_priv is NULL"); + osif_err("os_priv is NULL"); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/os_if_spectral_netlink.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/os_if_spectral_netlink.h index 156eaac00bacc9e02036bf587c73c78600abb093..9028654621d5ec13da0239dc6de44451769b9325 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/os_if_spectral_netlink.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/os_if_spectral_netlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -36,7 +36,7 @@ void os_if_spectral_nl_data_ready(struct sk_buff *skb); #ifndef SPECTRAL_NETLINK #define SPECTRAL_NETLINK (NETLINK_GENERIC + 1) #endif -#define MAX_SPECTRAL_PAYLOAD 1500 +#define MAX_SPECTRAL_PAYLOAD (2004) /* Init's network namespace */ extern struct net init_net; diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h index 39bae6fae644ec20eec95e9dadb0929431bf23b0..ec5081c1ea50be9e9d4f03aa2dbba216a77bb983 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -135,4 +135,17 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, const void *data, int data_len); + +/** + * wlan_cfg80211_spectral_scan_dma_debug_config() - configure DMA debug + * @pdev: Pointer to pdev + * @tb: Pointer to Spectral Scan config attribute + * @sscan_mode: Spectral scan mode + * + * Return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure + */ +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/os_if_spectral_netlink.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/os_if_spectral_netlink.c index 9ec2d155f26698f6e993e902c0a142a5b649e274..748a078e4d81599982be83c431da9fc9de986097 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/os_if_spectral_netlink.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/os_if_spectral_netlink.c @@ -162,14 +162,14 @@ os_if_spectral_init_nl(struct wlan_objmgr_pdev *pdev) memset(&cfg, 0, sizeof(cfg)); if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } os_if_spectral_init_nl_cfg(&cfg); @@ -178,14 +178,14 @@ os_if_spectral_init_nl(struct wlan_objmgr_pdev *pdev) os_if_spectral_create_nl_sock(&cfg); if (!os_if_spectral_nl_sock) { - cfg80211_err("NETLINK_KERNEL_CREATE FAILED"); + osif_err("NETLINK_KERNEL_CREATE FAILED"); return -ENODEV; } } ps->spectral_sock = os_if_spectral_nl_sock; if (!ps->spectral_sock) { - cfg80211_err("ps->spectral_sock is NULL"); + osif_err("ps->spectral_sock is NULL"); return -ENODEV; } atomic_inc(&spectral_nl_users); @@ -206,14 +206,14 @@ os_if_spectral_destroy_netlink(struct wlan_objmgr_pdev *pdev) struct pdev_spectral *ps = NULL; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } ps->spectral_sock = NULL; @@ -248,17 +248,17 @@ os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, void *buf = NULL; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return NULL; } if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { - cfg80211_err("Invalid Spectral message type %u", smsg_type); + osif_err("Invalid Spectral message type %u", smsg_type); return NULL; } if (buf_type >= SPECTRAL_MSG_BUF_TYPE_MAX) { - cfg80211_err("Invalid Spectral message buffer type %u", + osif_err("Invalid Spectral message buffer type %u", buf_type); return NULL; } @@ -267,7 +267,7 @@ os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return NULL; } @@ -278,7 +278,7 @@ os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, 0, 0, false); if (!ps->skb[smsg_type]) { - cfg80211_err("alloc skb (len=%u, msg_type=%u) failed", + osif_err("alloc skb (len=%u, msg_type=%u) failed", MAX_SPECTRAL_PAYLOAD, smsg_type); return NULL; } @@ -307,7 +307,7 @@ os_if_spectral_prep_skb(struct wlan_objmgr_pdev *pdev, spectral_nlh = (struct nlmsghdr *)ps->skb[smsg_type]->data; buf = NLMSG_DATA(spectral_nlh); } else { - cfg80211_err("Failed to get spectral report buffer"); + osif_err("Failed to get spectral report buffer"); buf = NULL; } @@ -364,29 +364,29 @@ os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev, int status; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return -EINVAL; } if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { - cfg80211_err("Invalid Spectral message type %u", smsg_type); + osif_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } if (!ps->skb[smsg_type]) { - cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); + osif_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } if (!ps->spectral_sock) { - cfg80211_err("Spectral Socket is invalid, msg_type= %u", + osif_err("Spectral Socket is invalid, msg_type= %u", smsg_type); qdf_nbuf_free(ps->skb[smsg_type]); ps->skb[smsg_type] = NULL; @@ -421,24 +421,24 @@ os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev, int status; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return -EINVAL; } if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { - cfg80211_err("Invalid Spectral message type %u", smsg_type); + osif_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } ps = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } if (!ps->skb[smsg_type]) { - cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); + osif_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } @@ -449,7 +449,7 @@ os_if_spectral_nl_unicast_msg(struct wlan_objmgr_pdev *pdev, MSG_DONTWAIT, WLAN_NL_MSG_SPECTRAL_SCAN, CLD80211_MCGRP_OEM_MSGS); if (status < 0) - cfg80211_err("failed to send to spectral scan app"); + osif_err("failed to send to spectral scan app"); /* clear the local copy, free would be done by netlink layer */ ps->skb[smsg_type] = NULL; @@ -482,12 +482,12 @@ os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev, #endif if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return -EINVAL; } if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { - cfg80211_err("Invalid Spectral message type %u", smsg_type); + osif_err("Invalid Spectral message type %u", smsg_type); return -EINVAL; } @@ -495,12 +495,12 @@ os_if_spectral_nl_bcast_msg(struct wlan_objmgr_pdev *pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return -EINVAL; } if (!ps->skb[smsg_type]) { - cfg80211_err("Socket buffer is null, msg_type= %u", smsg_type); + osif_err("Socket buffer is null, msg_type= %u", smsg_type); return -EINVAL; } @@ -537,12 +537,12 @@ os_if_spectral_free_skb(struct wlan_objmgr_pdev *pdev, struct pdev_spectral *ps = NULL; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return; } if (smsg_type >= SPECTRAL_MSG_TYPE_MAX) { - cfg80211_err("Invalid Spectral message type %u", smsg_type); + osif_err("Invalid Spectral message type %u", smsg_type); return; } @@ -550,12 +550,12 @@ os_if_spectral_free_skb(struct wlan_objmgr_pdev *pdev, WLAN_UMAC_COMP_SPECTRAL); if (!ps) { - cfg80211_err("PDEV SPECTRAL object is NULL!"); + osif_err("PDEV SPECTRAL object is NULL!"); return; } if (!ps->skb[smsg_type]) { - cfg80211_info("Socket buffer is null, msg_type= %u", smsg_type); + osif_info("Socket buffer is null, msg_type= %u", smsg_type); return; } @@ -575,14 +575,14 @@ os_if_spectral_netlink_init(struct wlan_objmgr_pdev *pdev) struct spectral_context *sptrl_ctx; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return; } sptrl_ctx = spectral_get_spectral_ctx_from_pdev(pdev); if (!sptrl_ctx) { - cfg80211_err("Spectral context is NULL!"); + osif_err("Spectral context is NULL!"); return; } @@ -605,14 +605,14 @@ void os_if_spectral_netlink_deinit(struct wlan_objmgr_pdev *pdev) enum spectral_msg_type msg_type = SPECTRAL_MSG_NORMAL_MODE; if (!pdev) { - cfg80211_err("PDEV is NULL!"); + osif_err("PDEV is NULL!"); return; } sptrl_ctx = spectral_get_spectral_ctx_from_pdev(pdev); if (!sptrl_ctx) { - cfg80211_err("Spectral context is NULL!"); + osif_err("Spectral context is NULL!"); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/wlan_cfg80211_spectral.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/wlan_cfg80211_spectral.c index 1008d119512d281107fa058ba89cdb97d28d629c..b45efef147a7dde04d841918ecb8600762485026 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/wlan_cfg80211_spectral.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/spectral/src/wlan_cfg80211_spectral.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -31,7 +31,6 @@ #include #include #include -#include "qal_devcfg.h" static const struct nla_policy spectral_scan_policy[ QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1] = { @@ -84,7 +83,11 @@ static const struct nla_policy spectral_scan_policy[ [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY] = { .type = NLA_U32}, [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE] = { - .type = NLA_U32}, + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG] = { + .type = NLA_U8}, }; static void wlan_spectral_intit_config(struct spectral_config *config_req) @@ -134,13 +137,105 @@ convert_spectral_mode_nl_to_internal break; default: - cfg80211_err("Invalid spectral mode %u", nl_spectral_mode); + osif_err("Invalid spectral mode %u", nl_spectral_mode); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * convert_spectral_err_code_internal_to_nl() - Get Spectral error code + * @spectral_err_code: Spectral error code used internally + * @nl_err_code: Spectral error code for cfg80211 + * + * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE + */ +static QDF_STATUS +convert_spectral_err_code_internal_to_nl + (enum spectral_cp_error_code spectral_err_code, + enum qca_wlan_vendor_spectral_scan_error_code *nl_err_code) +{ + switch (spectral_err_code) { + case SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED; + break; + + case SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + break; + + case SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + break; + + case SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED; + break; + + default: + osif_err("Invalid spectral error code %u", spectral_err_code); return QDF_STATUS_E_FAILURE; } return QDF_STATUS_SUCCESS; } +#ifdef DIRECT_BUF_RX_DEBUG +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode) +{ + struct spectral_cp_request sscan_req; + uint8_t dma_debug_enable; + QDF_STATUS status; + + if (!tb || !pdev) + return QDF_STATUS_E_FAILURE; + + if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]) { + dma_debug_enable = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]); + sscan_req.ss_mode = sscan_mode; + sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable; + sscan_req.dma_debug_req.dma_debug_type = + SPECTRAL_DMA_RING_DEBUG; + sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG; + status = ucfg_spectral_control(pdev, &sscan_req); + if (status != QDF_STATUS_SUCCESS) { + osif_err("Could not configure dma ring debug"); + return QDF_STATUS_E_FAILURE; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]) { + dma_debug_enable = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]); + sscan_req.ss_mode = sscan_mode; + sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable; + sscan_req.dma_debug_req.dma_debug_type = + SPECTRAL_DMA_BUFFER_DEBUG; + sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG; + return ucfg_spectral_control(pdev, &sscan_req); + } + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* DIRECT_BUF_RX_DEBUG */ + int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, const void *data, @@ -155,6 +250,7 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, uint32_t scan_req_type = 0; struct spectral_cp_request sscan_req; enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL; + uint16_t skb_len; if (wlan_cfg80211_nla_parse( tb, @@ -162,7 +258,7 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, data, data_len, spectral_scan_policy)) { - cfg80211_err("Invalid Spectral Scan config ATTR"); + osif_err("Invalid Spectral Scan config ATTR"); return -EINVAL; } @@ -275,6 +371,25 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, scan_req_type = nla_get_u32(tb [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]); + skb_len = NLMSG_HDRLEN; + /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE */ + skb_len += NLA_HDRLEN + sizeof(u32); + /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE */ + skb_len += NLA_HDRLEN + sizeof(u64); + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len); + + if (!skb) { + osif_err(" reply skb alloc failed"); + return -ENOMEM; + } + + status = wlan_cfg80211_spectral_scan_dma_debug_config( + pdev, tb, sscan_mode); + if (QDF_IS_STATUS_ERROR(status)) { + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; + } + if (CONFIG_REQUESTED(scan_req_type)) { sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_SET_CONFIG; @@ -282,36 +397,77 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, qdf_min(sizeof(sscan_req.config_req.sscan_config), sizeof(config_req))); status = ucfg_spectral_control(pdev, &sscan_req); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; + if (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; + + /* No error reasons populated, just return error */ + if (sscan_req.config_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) + goto free_skb_return_os_status; + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.config_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) { + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; + } + } } if (SCAN_REQUESTED(scan_req_type)) { sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_ACTIVATE_SCAN; status = ucfg_spectral_control(pdev, &sscan_req); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; - } - - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) + - NLA_HDRLEN + NLMSG_HDRLEN); - if (!skb) { - cfg80211_err(" reply skb alloc failed"); - return -ENOMEM; + if (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; + + /* No error reasons populated, just return error */ + if (sscan_req.action_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) + goto free_skb_return_os_status; + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.action_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) { + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; + } + } } cookie = 0; if (wlan_cfg80211_nla_put_u64(skb, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE, cookie)) { - kfree_skb(skb); - return -EINVAL; + status = QDF_STATUS_E_INVAL; + goto free_skb_return_os_status; } - qal_devcfg_send_response((qdf_nbuf_t)skb); - + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); return 0; +free_skb_return_os_status: + wlan_cfg80211_vendor_free_skb(skb); + return qdf_status_to_os_return(status); } int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, @@ -323,6 +479,7 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, QDF_STATUS status; struct spectral_cp_request sscan_req; enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL; + struct sk_buff *skb; if (wlan_cfg80211_nla_parse( tb, @@ -330,7 +487,7 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, data, data_len, spectral_scan_policy)) { - cfg80211_err("Invalid Spectral Scan stop ATTR"); + osif_err("Invalid Spectral Scan stop ATTR"); return -EINVAL; } @@ -345,8 +502,38 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_STOP_SCAN; status = ucfg_spectral_control(pdev, &sscan_req); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; + if (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; + + /* No error reasons populated, just return error */ + if (sscan_req.action_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) + return qdf_status_to_os_return(status); + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.action_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) + return -EINVAL; + + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + NLMSG_HDRLEN + sizeof(u32) + NLA_HDRLEN); + + if (!skb) { + osif_err(" reply skb alloc failed"); + return -ENOMEM; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + wlan_cfg80211_vendor_free_skb(skb); + return -EINVAL; + } + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); + } return 0; } @@ -370,7 +557,7 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy, data, data_len, spectral_scan_policy)) { - cfg80211_err("Invalid Spectral Scan config ATTR"); + osif_err("Invalid Spectral Scan config ATTR"); return -EINVAL; } @@ -382,11 +569,12 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy, return -EINVAL; } - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (sizeof(u32) + + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + (sizeof(u32) + NLA_HDRLEN) * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + NLMSG_HDRLEN); if (!skb) { - cfg80211_err(" reply skb alloc failed"); + osif_err(" reply skb alloc failed"); return -ENOMEM; } @@ -457,10 +645,8 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy, sconfig->ss_short_report) || nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY, - sconfig->ss_frequency)) { - kfree_skb(skb); - return -EINVAL; - } + sconfig->ss_frequency)) + goto fail; sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_GET_DEBUG_LEVEL; @@ -468,13 +654,14 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy, spectral_dbg_level = sscan_req.debug_req.spectral_dbg_level; if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL, - spectral_dbg_level)) { - kfree_skb(skb); - return -EINVAL; - } - qal_devcfg_send_response((qdf_nbuf_t)skb); + spectral_dbg_level)) + goto fail; + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); return 0; +fail: + wlan_cfg80211_vendor_free_skb(skb); + return -EINVAL; } int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy, @@ -491,11 +678,12 @@ int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy, status = ucfg_spectral_control(pdev, &sscan_req); scaps = &sscan_req.caps_req.sscan_caps; - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (sizeof(u32) + + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + (sizeof(u32) + NLA_HDRLEN) * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX + NLMSG_HDRLEN); if (!skb) { - cfg80211_err(" reply skb alloc failed"); + osif_err(" reply skb alloc failed"); return -ENOMEM; } @@ -568,12 +756,31 @@ int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy, if (ret) goto fail; } - qal_devcfg_send_response((qdf_nbuf_t)skb); + + if (scaps->agile_spectral_cap_160) { + int ret; + + ret = nla_put_flag + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_160); + if (ret) + goto fail; + } + if (scaps->agile_spectral_cap_80p80) { + int ret; + + ret = nla_put_flag + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_80_80); + if (ret) + goto fail; + } + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); return 0; fail: - kfree_skb(skb); + wlan_cfg80211_vendor_free_skb(skb); return -EINVAL; } @@ -591,11 +798,12 @@ int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy, status = ucfg_spectral_control(pdev, &sscan_req); spetcral_diag = &sscan_req.diag_req.sscan_diag; - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (sizeof(u64) + - NLA_HDRLEN) * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_MAX + + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + (sizeof(u64) + NLA_HDRLEN) * + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_MAX + NLMSG_HDRLEN); if (!skb) { - cfg80211_err(" reply skb alloc failed"); + osif_err(" reply skb alloc failed"); return -ENOMEM; } @@ -619,10 +827,10 @@ int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy, skb, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH, spetcral_diag->spectral_vhtseg2id_mismatch)) { - kfree_skb(skb); + wlan_cfg80211_vendor_free_skb(skb); return -EINVAL; } - qal_devcfg_send_response((qdf_nbuf_t)skb); + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); return 0; } @@ -645,7 +853,7 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, data, data_len, NULL)) { - cfg80211_err("Invalid Spectral Scan config ATTR"); + osif_err("Invalid Spectral Scan config ATTR"); return -EINVAL; } @@ -668,10 +876,10 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, status = ucfg_spectral_control(pdev, &sscan_req); sscan_state.is_enabled = sscan_req.status_req.is_enabled; - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 2 * (sizeof(u32) + - NLA_HDRLEN) + NLMSG_HDRLEN); + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 2 * (sizeof(u32) + NLA_HDRLEN) + NLMSG_HDRLEN); if (!skb) { - cfg80211_err(" reply skb alloc failed"); + osif_err(" reply skb alloc failed"); return -ENOMEM; } @@ -686,10 +894,10 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, skb, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE)) goto fail; - qal_devcfg_send_response((qdf_nbuf_t)skb); + wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb); return 0; fail: - kfree_skb(skb); + wlan_cfg80211_vendor_free_skb(skb); return -EINVAL; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h index 26db59415482c9632697510652054b3ed809465e..cc6616d8cfbd05967496bdc295f6cae8c6b7dcec 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -105,4 +105,182 @@ static inline int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, } #endif +#ifdef CNSS_GENL +/** + * enum cld80211_vendor_sub_cmds + * @CLD80211_VENDOR_SUB_CMD_INVALID: invalid cmd type + * @CLD80211_VENDOR_SUB_CMD_REGISTRATION: app registration + * @CLD80211_VENDOR_SUB_CMD_SET_CAPS: set driver capabilities + * @CLD80211_VENDOR_SUB_CMD_GET_CAPS: get driver capabilities + * @CLD80211_VENDOR_SUB_CMD_GET_CH_INFO: get channel info + * @CLD80211_VENDOR_SUB_CMD_OEM_DATA: oem data req/rsp + * @CLD80211_VENDOR_SUB_CMD_OEM_ERROR: oem error rsp + * @CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND: peer status indication + * @CLD80211_VENDOR_SUB_CMD_MAX: Max cld80211 vendor sub cmds + */ +enum cld80211_vendor_sub_cmds { + CLD80211_VENDOR_SUB_CMD_INVALID = 0, + CLD80211_VENDOR_SUB_CMD_REGISTRATION = 1, + CLD80211_VENDOR_SUB_CMD_SET_CAPS = 2, + CLD80211_VENDOR_SUB_CMD_GET_CAPS = 3, + CLD80211_VENDOR_SUB_CMD_GET_CH_INFO = 4, + CLD80211_VENDOR_SUB_CMD_OEM_DATA = 5, + CLD80211_VENDOR_SUB_CMD_OEM_ERROR = 6, + CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND = 7, + /* keep last */ + CLD80211_VENDOR_SUB_CMD__AFTER_LAST, + CLD80211_VENDOR_SUB_CMD_MAX = + CLD80211_VENDOR_SUB_CMD__AFTER_LAST - 1 +}; + +/** + * enum cld80211_sub_attr_cap_rsp - Capability response sub attribute + * @CLD80211_SUB_ATTR_CAPS_INVALID: Invalid capability + * @CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE: OEM target signature + * @CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE: OEM target type + * @CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION: OEM firmware version + * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR: Driver version major + * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR: Driver version minor + * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH: Driver version patch + * @CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD: Driver version build + * @CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN: Allowed dwell time min + * @CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX: Allowed dwell time max + * @CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN: Current dwell time min + * @CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX: Current dwell time max + * @CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS: Supported bands + * @CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS: User defined capabilities + * @CLD80211_SUB_ATTR_CAPS_MAX: Max number for CAP sub attribute + * + */ +enum cld80211_sub_attr_cap_rsp { + CLD80211_SUB_ATTR_CAPS_INVALID = 0, + CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE = 1, + CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE = 2, + CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION = 3, + CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR = 4, + CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR = 5, + CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH = 6, + CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD = 7, + CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN = 8, + CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX = 9, + CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN = 10, + CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX = 11, + CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS = 12, + CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS = 13, + + /* keep last */ + CLD80211_SUB_ATTR_CAPS_AFTER_LAST, + CLD80211_SUB_ATTR_CAPS_MAX = + CLD80211_SUB_ATTR_CAPS_AFTER_LAST - 1 +}; + +/** + * enum cld80211_sub_attr_channel_rsp - Chan info response sub attribute + * @CLD80211_SUB_ATTR_CH_RESP_INVALID: Invalid channel resp + * @CLD80211_SUB_ATTR_CH_MORE_DATA: More date sub attr for frag response + * @CLD80211_SUB_ATTR_CHANNEL_NUM_CHAN: Number of channels in response + * @CLD80211_SUB_ATTR_CHANNEL_LIST: Channel list nesting + * @CLD80211_SUB_ATTR_CH_CHAN_ID: Channel number + * @CLD80211_SUB_ATTR_CH_MHZ: Channel frequency + * @CLD80211_SUB_ATTR_CH_BAND_CF_1: Center frequency 1 + * @CLD80211_SUB_ATTR_CH_BAND_CF_2: Center frequency 2 + * @CLD80211_SUB_ATTR_CH_INFO: channel info + * @CLD80211_SUB_ATTR_CH_REG_INFO_1: regulatory info field 1 + * @CLD80211_SUB_ATTR_CH_REG_INFO_2: regulatory info field 2 + * @CLD80211_SUB_ATTR_CAPS_MAX: Max number for CHAN Info sub attribute + * + */ +enum cld80211_sub_attr_channel_rsp { + CLD80211_SUB_ATTR_CH_RESP_INVALID = 0, + CLD80211_SUB_ATTR_CH_MORE_DATA = 1, + CLD80211_SUB_ATTR_CHANNEL_NUM_CHAN = 2, + CLD80211_SUB_ATTR_CH_LIST = 3, + /* CH_* belongs to CH_LIST */ + CLD80211_SUB_ATTR_CH_CHAN_ID = 4, + CLD80211_SUB_ATTR_CH_MHZ = 5, + CLD80211_SUB_ATTR_CH_BAND_CF_1 = 6, + CLD80211_SUB_ATTR_CH_BAND_CF_2 = 7, + CLD80211_SUB_ATTR_CH_INFO = 8, + CLD80211_SUB_ATTR_CH_REG_INFO_1 = 9, + CLD80211_SUB_ATTR_CH_REG_INFO_2 = 10, + + /* keep last */ + CLD80211_SUB_ATTR_CH_AFTER_LAST, + CLD80211_SUB_ATTR_CH_MAX = + CLD80211_SUB_ATTR_CH_AFTER_LAST - 1 + +}; + +/** + * enum cld80211_sub_attr_oem_data_req - OEM data req sub attribute + * @CLD80211_SUB_ATTR_MSG_OEM_DATA_INVALID: Invalid OEM data request + * @CLD80211_SUB_ATTR_MSG_OEM_DATA_FW: Data to Firmware + * @CLD80211_SUB_ATTR_MSG_OEM_DATA_DRIVER: Data to driver + * @CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_MAX: Max number for OEM data req sub + * attribute + * + * OEM data request sub attributes are NLA attributes in NLA type OEM data + * request. + * + */ +enum cld80211_sub_attr_oem_data_req { + CLD80211_SUB_ATTR_MSG_OEM_DATA_INVALID = 0, + CLD80211_SUB_ATTR_MSG_OEM_DATA_FW = 1, + CLD80211_SUB_ATTR_MSG_OEM_DATA_DRIVER = 2, + + /* keep last */ + CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_AFTER_LAST, + CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_MAX = + CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_AFTER_LAST - 1 +}; + +/** + * enum cld80211_sub_attr_oem_data_resp - OEM message sub attribute + * @CLD80211_SUB_ATTR_OEM_DATA_INVALID: Invalid oem data resp + * @CLD80211_SUB_ATTR_OEM_MORE_DATA: more date sub attribute + * @CLD80211_SUB_ATTR_BINARY_DATA: Binary data sub attribute + * @CLD80211_SUB_ATTR_OEM_DATA_RESP_MAX: Max number for OEM data resp + * sub attribute + * + * OEM message sub attributes are interface between apps and driver to + * process NLA type request and response messages. + * + */ +enum cld80211_sub_attr_oem_data_resp { + CLD80211_SUB_ATTR_OEM_DATA_INVALID = 0, + CLD80211_SUB_ATTR_OEM_MORE_DATA = 1, + CLD80211_SUB_ATTR_BINARY_DATA = 2, + + /* keep last */ + CLD80211_SUB_ATTR_OEM_DATA_RESP_AFTER_LAST, + CLD80211_SUB_ATTR_OEM_DATA_RESP_MAX = + CLD80211_SUB_ATTR_OEM_DATA_RESP_AFTER_LAST - 1 +}; + +/** + * enum cld80211_sub_attr_peer_info - peer info sub attribute + * @CLD80211_SUB_ATTR_PEER_INVALID: Invalid peer info + * @CLD80211_SUB_ATTR_PEER_MAC_ADDR: peer mac address + * @CLD80211_SUB_ATTR_PEER_STATUS: peer status + * @CLD80211_SUB_ATTR_PEER_VDEV_ID: peer vdevid + * @CLD80211_SUB_ATTR_PEER_CAPABILITY: peer capabilities + * @CLD80211_SUB_ATTR_PEER_RESERVED: reserved bytes + * @CLD80211_SUB_ATTR_PEER_CHAN_INFO: peer channel info + * + */ +enum cld80211_sub_attr_peer_info { + CLD80211_SUB_ATTR_PEER_INVALID = 0, + CLD80211_SUB_ATTR_PEER_MAC_ADDR = 1, + CLD80211_SUB_ATTR_PEER_STATUS = 2, + CLD80211_SUB_ATTR_PEER_VDEV_ID = 3, + CLD80211_SUB_ATTR_PEER_CAPABILITY = 4, + CLD80211_SUB_ATTR_PEER_RESERVED = 5, + CLD80211_SUB_ATTR_PEER_CHAN_INFO = 6, + + /* keep last */ + CLD80211_SUB_ATTR_PEER_AFTER_LAST, + CLD80211_SUB_ATTR_PEER_MAX = + CLD80211_SUB_ATTR_PEER_AFTER_LAST - 1 +}; +#endif #endif /* _OS_IF_WIFI_POS_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/src/os_if_wifi_pos.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/src/os_if_wifi_pos.c index 189b67bd555ad0fae38e09647d49cc13db36aec2..d85a23ce0ca9aa7b05109ec9b45511239b02a741 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/src/os_if_wifi_pos.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wifi_pos/src/os_if_wifi_pos.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +23,7 @@ */ #include "qdf_platform.h" +#include "qdf_module.h" #include "wlan_nlink_srv.h" #include "wlan_ptt_sock_svc.h" #include "wlan_nlink_common.h" @@ -32,6 +33,535 @@ #include "wlan_objmgr_psoc_obj.h" #ifdef CNSS_GENL #include +#include "linux/genetlink.h" +#include "wifi_pos_utils_pub.h" +#endif + +#ifdef CNSS_GENL +#define WLAN_CLD80211_MAX_SIZE SKB_WITH_OVERHEAD(8192UL) + +#define CLD80211_ATTR_CMD 4 +#define CLD80211_ATTR_CMD_TAG_DATA 5 +#define CLD80211_ATTR_MAX 5 + +static const uint32_t +cap_resp_sub_attr_len[CLD80211_SUB_ATTR_CAPS_MAX + 1] = { + [CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE] = + OEM_TARGET_SIGNATURE_LEN, + [CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN] = sizeof(uint16_t), + [CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX] = sizeof(uint16_t), + [CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN] = sizeof(uint16_t), + [CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX] = sizeof(uint16_t), + [CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS] = sizeof(uint16_t), + [CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS] = + sizeof(struct wifi_pos_user_defined_caps), +}; + +static const uint32_t +peer_status_sub_attr_len[CLD80211_SUB_ATTR_PEER_MAX + 1] = { + [CLD80211_SUB_ATTR_PEER_MAC_ADDR] = ETH_ALEN, + [CLD80211_SUB_ATTR_PEER_STATUS] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_PEER_VDEV_ID] = sizeof(uint8_t), + [CLD80211_SUB_ATTR_PEER_CAPABILITY] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_PEER_RESERVED] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_PEER_CHAN_INFO] = + sizeof(struct wifi_pos_ch_info_rsp), +}; + +static const uint32_t +ch_resp_sub_attr_len[CLD80211_SUB_ATTR_CH_MAX + 1] = { + [CLD80211_SUB_ATTR_CHANNEL_NUM_CHAN] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_LIST] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_CHAN_ID] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_MHZ] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_BAND_CF_1] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_BAND_CF_2] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_INFO] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_REG_INFO_1] = sizeof(uint32_t), + [CLD80211_SUB_ATTR_CH_REG_INFO_2] = sizeof(uint32_t), +}; +#endif + +static int map_wifi_pos_cmd_to_ani_msg_rsp( + enum wifi_pos_cmd_ids cmd) +{ + switch (cmd) { + case WIFI_POS_CMD_REGISTRATION: + return ANI_MSG_APP_REG_RSP; + case WIFI_POS_CMD_SET_CAPS: + return ANI_MSG_SET_OEM_CAP_RSP; + case WIFI_POS_CMD_GET_CAPS: + return ANI_MSG_GET_OEM_CAP_RSP; + case WIFI_POS_CMD_GET_CH_INFO: + return ANI_MSG_CHANNEL_INFO_RSP; + case WIFI_POS_CMD_OEM_DATA: + return ANI_MSG_OEM_DATA_RSP; + case WIFI_POS_CMD_ERROR: + return ANI_MSG_OEM_ERROR; + case WIFI_POS_PEER_STATUS_IND: + return ANI_MSG_PEER_STATUS_IND; + default: + osif_err("response message is invalid :%d", cmd); + return -EINVAL; + } +} + +static enum wifi_pos_cmd_ids +map_ani_msg_req_to_wifi_pos_cmd(uint32_t cmd) +{ + switch (cmd) { + case ANI_MSG_APP_REG_REQ: + return WIFI_POS_CMD_REGISTRATION; + case ANI_MSG_SET_OEM_CAP_REQ: + return WIFI_POS_CMD_SET_CAPS; + case ANI_MSG_GET_OEM_CAP_REQ: + return WIFI_POS_CMD_GET_CAPS; + case ANI_MSG_CHANNEL_INFO_REQ: + return WIFI_POS_CMD_GET_CH_INFO; + case ANI_MSG_OEM_DATA_REQ: + return WIFI_POS_CMD_OEM_DATA; + default: + osif_err("ani req is invalid :%d", cmd); + return WIFI_POS_CMD_INVALID; + } +} + +#ifdef CNSS_GENL +static enum wifi_pos_cmd_ids +map_cld_vendor_sub_cmd_to_wifi_pos_cmd( + enum cld80211_vendor_sub_cmds cmd) +{ + switch (cmd) { + case CLD80211_VENDOR_SUB_CMD_REGISTRATION: + return WIFI_POS_CMD_REGISTRATION; + case CLD80211_VENDOR_SUB_CMD_SET_CAPS: + return WIFI_POS_CMD_SET_CAPS; + case CLD80211_VENDOR_SUB_CMD_GET_CAPS: + return WIFI_POS_CMD_GET_CAPS; + case CLD80211_VENDOR_SUB_CMD_GET_CH_INFO: + return WIFI_POS_CMD_GET_CH_INFO; + case CLD80211_VENDOR_SUB_CMD_OEM_DATA: + return WIFI_POS_CMD_OEM_DATA; + default: + osif_err("cld vendor subcmd is invalid :%d", cmd); + return WIFI_POS_CMD_INVALID; + } +} + +static enum cld80211_vendor_sub_cmds +map_wifi_pos_cmd_to_cld_vendor_sub_cmd( + enum wifi_pos_cmd_ids cmd) +{ + switch (cmd) { + case WIFI_POS_CMD_REGISTRATION: + return CLD80211_VENDOR_SUB_CMD_REGISTRATION; + case WIFI_POS_CMD_SET_CAPS: + return CLD80211_VENDOR_SUB_CMD_SET_CAPS; + case WIFI_POS_CMD_GET_CAPS: + return CLD80211_VENDOR_SUB_CMD_GET_CAPS; + case WIFI_POS_CMD_GET_CH_INFO: + return CLD80211_VENDOR_SUB_CMD_GET_CH_INFO; + case WIFI_POS_CMD_OEM_DATA: + return CLD80211_VENDOR_SUB_CMD_OEM_DATA; + case WIFI_POS_CMD_ERROR: + return ANI_MSG_OEM_ERROR; + case WIFI_POS_PEER_STATUS_IND: + return ANI_MSG_PEER_STATUS_IND; + default: + osif_err("response message is invalid :%d", cmd); + return CLD80211_VENDOR_SUB_CMD_INVALID; + } +} + +static void os_if_wifi_pos_send_peer_nl_status(uint32_t pid, uint8_t *buf) +{ + void *hdr; + int flags = GFP_KERNEL; + struct sk_buff *msg = NULL; + struct nlattr *nest1, *nest2, *nest3; + struct wifi_pos_peer_status_info *peer_info; + struct wifi_pos_ch_info_rsp *chan_info; + + msg = cld80211_oem_rsp_alloc_skb(pid, &hdr, &nest1, &flags); + if (!msg) { + osif_err("alloc_skb failed"); + return; + } + + peer_info = (struct wifi_pos_peer_status_info *)buf; + chan_info = &peer_info->peer_chan_info; + + nla_put_u32(msg, CLD80211_ATTR_CMD, + CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND); + nest2 = nla_nest_start(msg, CLD80211_ATTR_CMD_TAG_DATA); + if (!nest2) { + osif_err("nla_nest_start failed"); + dev_kfree_skb(msg); + return; + } + + nla_put(msg, CLD80211_SUB_ATTR_PEER_MAC_ADDR, + ETH_ALEN, peer_info->peer_mac_addr); + nla_put_u8(msg, CLD80211_SUB_ATTR_PEER_STATUS, + peer_info->peer_status); + nla_put_u8(msg, CLD80211_SUB_ATTR_PEER_VDEV_ID, + peer_info->vdev_id); + nla_put_u32(msg, CLD80211_SUB_ATTR_PEER_CAPABILITY, + peer_info->peer_capability); + nla_put_u32(msg, CLD80211_SUB_ATTR_PEER_RESERVED, + peer_info->reserved0); + nest3 = nla_nest_start(msg, CLD80211_SUB_ATTR_PEER_CHAN_INFO); + if (!nest3) { + osif_err("nla_nest_start failed"); + dev_kfree_skb(msg); + return; + } + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_CHAN_ID, + chan_info->chan_id); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_MHZ, chan_info->mhz); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_BAND_CF_1, + chan_info->band_center_freq1); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_BAND_CF_2, + chan_info->band_center_freq2); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_INFO, chan_info->info); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_REG_INFO_1, + chan_info->reg_info_1); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_REG_INFO_2, + chan_info->reg_info_2); + + nla_nest_end(msg, nest3); + nla_nest_end(msg, nest2); + + osif_debug("sending oem rsp: type: %d to pid (%d)", + CLD80211_VENDOR_SUB_CMD_PEER_STATUS_IND, pid); + + cld80211_oem_send_reply(msg, hdr, nest1, flags); +} + +static void os_if_send_cap_nl_resp(uint32_t pid, uint8_t *buf) +{ + void *hdr; + int flags = GFP_KERNEL; + struct sk_buff *msg = NULL; + struct nlattr *nest1, *nest2; + struct wifi_pos_oem_get_cap_rsp *cap_rsp; + + msg = cld80211_oem_rsp_alloc_skb(pid, &hdr, &nest1, &flags); + if (!msg) { + osif_err("alloc_skb failed"); + return; + } + + nla_put_u32(msg, CLD80211_ATTR_CMD, + map_wifi_pos_cmd_to_cld_vendor_sub_cmd(WIFI_POS_CMD_GET_CAPS)); + + cap_rsp = (struct wifi_pos_oem_get_cap_rsp *)(buf); + nest2 = nla_nest_start(msg, CLD80211_ATTR_CMD_TAG_DATA); + + if (!nest2) { + osif_err("nla_nest_start failed"); + dev_kfree_skb(msg); + return; + } + + nla_put(msg, CLD80211_SUB_ATTR_CAPS_OEM_TARGET_SIGNATURE, + OEM_TARGET_SIGNATURE_LEN, OEM_TARGET_SIGNATURE); + nla_put_u32(msg, CLD80211_SUB_ATTR_CAPS_OEM_TARGET_TYPE, + cap_rsp->driver_cap.oem_target_type); + nla_put_u32(msg, CLD80211_SUB_ATTR_CAPS_OEM_FW_VERSION, + cap_rsp->driver_cap.oem_fw_version); + nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MAJOR, + cap_rsp->driver_cap.driver_version.major); + nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_MINOR, + cap_rsp->driver_cap.driver_version.minor); + nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_PATCH, + cap_rsp->driver_cap.driver_version.patch); + nla_put_u8(msg, CLD80211_SUB_ATTR_CAPS_DRIVER_VERSION_BUILD, + cap_rsp->driver_cap.driver_version.build); + nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MIN, + cap_rsp->driver_cap.allowed_dwell_time_min); + nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_ALLOWED_DWELL_TIME_MAX, + cap_rsp->driver_cap.allowed_dwell_time_max); + nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MIN, + cap_rsp->driver_cap.curr_dwell_time_min); + nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_CURRENT_DWELL_TIME_MAX, + cap_rsp->driver_cap.curr_dwell_time_max); + nla_put_u16(msg, CLD80211_SUB_ATTR_CAPS_SUPPORTED_BANDS, + cap_rsp->driver_cap.supported_bands); + nla_put(msg, CLD80211_SUB_ATTR_CAPS_USER_DEFINED_CAPS, + sizeof(struct wifi_pos_user_defined_caps), + &cap_rsp->user_defined_cap); + nla_nest_end(msg, nest2); + + osif_debug("sending oem rsp: type: %d to pid (%d)", + CLD80211_VENDOR_SUB_CMD_GET_CAPS, pid); + + cld80211_oem_send_reply(msg, hdr, nest1, flags); +} + +static void +os_if_get_chan_nl_resp_len(uint32_t *chan_info, uint32_t *attr_headers) +{ + uint32_t i; + struct nlattr more_data; + struct nlattr attr_tag_data; + struct nlattr cld80211_subattr_ch_list; + struct nlattr chan_iter; + + *attr_headers = NLA_ALIGN(sizeof(attr_tag_data)); + *attr_headers += NLA_ALIGN(sizeof(more_data)); + *attr_headers += nla_total_size( + ch_resp_sub_attr_len[CLD80211_SUB_ATTR_CHANNEL_NUM_CHAN]); + *attr_headers += sizeof(cld80211_subattr_ch_list); + + *chan_info = NLA_ALIGN(sizeof(chan_iter)); + i = CLD80211_SUB_ATTR_CH_LIST; + for (; i <= CLD80211_SUB_ATTR_CH_MAX; i++) + *chan_info += nla_total_size(ch_resp_sub_attr_len[i]); +} + +static uint8_t os_if_get_max_chan_nl_resp(uint8_t chan_num) +{ + struct nlattr vendor_data; + struct nlattr attr_cmd; + uint32_t chan_info = 0, attr_headers = 0; + uint32_t chan_info_msg_len, chan_allow = 0; + + os_if_get_chan_nl_resp_len(&chan_info, &attr_headers); + attr_headers += NLA_ALIGN(sizeof(vendor_data)); + attr_headers += NLA_ALIGN(sizeof(attr_cmd)); + + chan_info_msg_len = WLAN_CLD80211_MAX_SIZE; + chan_info_msg_len -= WIFIPOS_RESERVE_BYTES; + chan_info_msg_len -= attr_headers; + + chan_allow = chan_info_msg_len / chan_info; + + if (chan_num > chan_allow) + return chan_allow; + else + return chan_num; +} + +static int +os_if_create_ch_nl_resp(uint32_t pid, uint8_t *buf, uint16_t num_chan, + bool is_frag) +{ + void *hdr; + int i; + int flags = GFP_KERNEL; + struct sk_buff *msg = NULL; + struct nlattr *nest1, *nest2; + struct nlattr *nest3, *nest4; + struct wifi_pos_ch_info_rsp *channel_rsp; + + channel_rsp = (struct wifi_pos_ch_info_rsp *)buf; + + msg = cld80211_oem_rsp_alloc_skb(pid, &hdr, &nest1, &flags); + if (!msg) { + osif_err("alloc_skb failed"); + return -EPERM; + } + + nla_put_u32(msg, CLD80211_ATTR_CMD, + CLD80211_VENDOR_SUB_CMD_GET_CH_INFO); + + nest2 = nla_nest_start(msg, CLD80211_ATTR_CMD_TAG_DATA); + if (!nest2) + goto fail; + + if (is_frag) + nla_put_flag(msg, CLD80211_SUB_ATTR_CH_MORE_DATA); + + nla_put_u32(msg, CLD80211_SUB_ATTR_CHANNEL_NUM_CHAN, num_chan); + + nest3 = nla_nest_start(msg, CLD80211_SUB_ATTR_CH_LIST); + if (!nest3) + goto fail; + for (i = 0; i < num_chan; i++) { + nest4 = nla_nest_start(msg, i); + if (!nest4) + goto fail; + + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_CHAN_ID, + channel_rsp->chan_id); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_MHZ, channel_rsp->mhz); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_BAND_CF_1, + channel_rsp->band_center_freq1); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_BAND_CF_2, + channel_rsp->band_center_freq2); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_INFO, channel_rsp->info); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_REG_INFO_1, + channel_rsp->reg_info_1); + nla_put_u32(msg, CLD80211_SUB_ATTR_CH_REG_INFO_2, + channel_rsp->reg_info_2); + nla_nest_end(msg, nest4); + channel_rsp++; + } + + nla_nest_end(msg, nest3); + nla_nest_end(msg, nest2); + + osif_debug("sending oem rsp: type: %d to pid (%d)", + CLD80211_VENDOR_SUB_CMD_GET_CH_INFO, pid); + + cld80211_oem_send_reply(msg, hdr, nest1, flags); + return 0; + +fail: + osif_err("failed to fill CHAN_RESP attributes"); + dev_kfree_skb(msg); + return -EPERM; +} + +static void os_if_send_chan_nl_resp(uint32_t pid, uint8_t *buf) +{ + int err; + uint8_t check_chans = 0; + uint8_t *chnk_ptr, chan_allow = 0; + bool resp_frag = false; + + check_chans = buf[0]; + chnk_ptr = &buf[1]; + + do { + chan_allow = os_if_get_max_chan_nl_resp(check_chans); + + if (check_chans > chan_allow) + resp_frag = true; + else + resp_frag = false; + check_chans -= chan_allow; + + err = os_if_create_ch_nl_resp(pid, chnk_ptr, + chan_allow, resp_frag); + if (err) { + osif_err("failed to alloc memory for ch_nl_resp"); + return; + } + chnk_ptr += (sizeof(struct wifi_pos_ch_info_rsp) * + chan_allow); + } while (resp_frag); +} + +static int +os_if_create_oemdata_resp(uint32_t pid, uint8_t *buf, bool frag_resp, + uint32_t chnk_len) +{ + void *hdr; + int flags = GFP_KERNEL; + struct sk_buff *msg = NULL; + struct nlattr *nest1, *nest2; + + msg = cld80211_oem_rsp_alloc_skb(pid, &hdr, &nest1, &flags); + if (!msg) { + osif_err("alloc_skb failed"); + return -EPERM; + } + + nla_put_u32(msg, CLD80211_ATTR_CMD, CLD80211_VENDOR_SUB_CMD_OEM_DATA); + + nest2 = nla_nest_start(msg, CLD80211_ATTR_CMD_TAG_DATA); + if (!nest2) + goto fail; + + if (frag_resp) + nla_put_flag(msg, CLD80211_SUB_ATTR_OEM_MORE_DATA); + + nla_put(msg, CLD80211_SUB_ATTR_BINARY_DATA, chnk_len, buf); + + nla_nest_end(msg, nest2); + osif_debug("sending oem rsp: type: %d to pid (%d)", + CLD80211_VENDOR_SUB_CMD_OEM_DATA, pid); + cld80211_oem_send_reply(msg, hdr, nest1, flags); + return 0; + +fail: + osif_err("failed to fill CHAN_RESP attributes"); + dev_kfree_skb(msg); + return -EPERM; +} + +static void +os_if_send_oem_data_nl_resp(uint32_t pid, uint8_t *buf, + uint32_t buf_len) +{ + int err; + uint32_t attr_len; + uint32_t chnk_len, remain_len; + uint8_t *chnk_ptr; + bool frag_resp = false; + + struct nlattr vendor_data; + struct nlattr attr_cmd; + struct nlattr attr_tag_data; + struct nlattr cld80211_subattr_bindata; + struct nlattr more_data; + + attr_len = WIFIPOS_RESERVE_BYTES; + attr_len += NLMSG_ALIGN(sizeof(vendor_data)); + attr_len += NLMSG_ALIGN(sizeof(attr_cmd)); + attr_len += NLMSG_ALIGN(sizeof(attr_tag_data)); + attr_len += NLMSG_ALIGN(sizeof(more_data)); + + chnk_ptr = buf; + chnk_len = buf_len; + remain_len = buf_len; + do { + if (attr_len + nla_total_size(chnk_len) > + WLAN_CLD80211_MAX_SIZE) { + frag_resp = true; + + chnk_len = WLAN_CLD80211_MAX_SIZE - (attr_len + + sizeof(cld80211_subattr_bindata)); + } else { + frag_resp = false; + } + + remain_len -= chnk_len; + + err = os_if_create_oemdata_resp(pid, chnk_ptr, + frag_resp, chnk_len); + if (err) { + osif_err("failed to alloc memory for oem_nl_resp"); + return; + } + chnk_ptr += chnk_len; + chnk_len = remain_len; + } while (frag_resp); +} + +static void os_if_send_nl_resp(uint32_t pid, uint8_t *buf, + enum wifi_pos_cmd_ids cmd, uint32_t len) +{ + switch (cmd) { + case WIFI_POS_CMD_GET_CAPS: + os_if_send_cap_nl_resp(pid, buf); + break; + case WIFI_POS_CMD_GET_CH_INFO: + os_if_send_chan_nl_resp(pid, buf); + break; + case WIFI_POS_CMD_OEM_DATA: + os_if_send_oem_data_nl_resp(pid, buf, len); + break; + case WIFI_POS_PEER_STATUS_IND: + os_if_wifi_pos_send_peer_nl_status(pid, buf); + break; + default: + osif_err("response message is invalid :%d", cmd); + } +} +#else +static void os_if_send_nl_resp(uint32_t pid, uint8_t *buf, + enum wifi_pos_cmd_ids cmd, uint32_t len) +{ +} #endif /** @@ -41,74 +571,139 @@ * * Return: none */ -static void os_if_wifi_pos_send_rsp(uint32_t pid, uint32_t rsp_msg_type, +static void os_if_wifi_pos_send_rsp(uint32_t pid, enum wifi_pos_cmd_ids cmd, uint32_t buf_len, uint8_t *buf) { tAniMsgHdr *aniHdr; - struct sk_buff *skb; + struct sk_buff *skb = NULL; struct nlmsghdr *nlh; + struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); /* OEM msg is always to a specific process and cannot be a broadcast */ if (pid == 0) { - cfg80211_err("invalid dest pid"); + osif_err("invalid dest pid"); return; } - skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len), GFP_ATOMIC); - if (!skb) { - cfg80211_alert("alloc_skb failed"); - return; + if (ucfg_wifi_pos_is_nl_rsp(psoc)) { + os_if_send_nl_resp(pid, buf, cmd, buf_len); + } else { + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len), + GFP_ATOMIC); + if (!skb) { + osif_alert("alloc_skb failed"); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + buf_len); + + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = map_wifi_pos_cmd_to_ani_msg_rsp(cmd); + qdf_mem_copy(&aniHdr[1], buf, buf_len); + aniHdr->length = buf_len; + + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len)); + osif_debug("sending oem rsp: type: %d len(%d) to pid (%d)", + aniHdr->type, buf_len, pid); + nl_srv_ucast_oem(skb, pid, MSG_DONTWAIT); } - - nlh = (struct nlmsghdr *)skb->data; - nlh->nlmsg_pid = 0; /* from kernel */ - nlh->nlmsg_flags = 0; - nlh->nlmsg_seq = 0; - nlh->nlmsg_type = WLAN_NL_MSG_OEM; - nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + buf_len); - - aniHdr = NLMSG_DATA(nlh); - aniHdr->type = rsp_msg_type; - qdf_mem_copy(&aniHdr[1], buf, buf_len); - aniHdr->length = buf_len; - - skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + buf_len)); - cfg80211_debug("sending oem rsp: type: %d len(%d) to pid (%d)", - rsp_msg_type, buf_len, pid); - nl_srv_ucast_oem(skb, pid, MSG_DONTWAIT); } #ifdef CNSS_GENL -static int wifi_pos_parse_req(const void *data, int len, int pid, +static int +wifi_pos_parse_nla_oemdata_req(uint32_t len, uint8_t *buf, + struct wifi_pos_req_msg *req) +{ + struct nlattr *tb_oem_data[CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_MAX + 1]; + + if (wlan_cfg80211_nla_parse(tb_oem_data, + CLD80211_SUB_ATTR_MSG_OEM_DATA_REQ_MAX, + (struct nlattr *)buf, len, NULL)) { + osif_err("invalid data in request"); + return OEM_ERR_INVALID_MESSAGE_TYPE; + } + + if (!tb_oem_data[CLD80211_SUB_ATTR_MSG_OEM_DATA_FW]) { + osif_err("CLD80211_SUB_ATTR_MSG_OEM_DATA_FW not present"); + return OEM_ERR_INVALID_MESSAGE_TYPE; + } + req->buf_len = nla_len( + tb_oem_data[CLD80211_SUB_ATTR_MSG_OEM_DATA_FW]); + req->buf = nla_data( + tb_oem_data[CLD80211_SUB_ATTR_MSG_OEM_DATA_FW]); + + return 0; +} + +static int wifi_pos_parse_nla_req(const void *data, int len, int pid, struct wifi_pos_req_msg *req) { - tAniMsgHdr *msg_hdr; + uint8_t *msg; struct nlattr *tb[CLD80211_ATTR_MAX + 1]; - uint32_t msg_len, id, nl_field_info_size, expected_field_info_size; - struct wifi_pos_field_info *field_info; + uint32_t msg_len; if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) { - cfg80211_err("invalid data in request"); + osif_err("invalid data in request"); return OEM_ERR_INVALID_MESSAGE_TYPE; } - if (!tb[CLD80211_ATTR_DATA]) { - cfg80211_err("CLD80211_ATTR_DATA not present"); + req->pid = pid; + req->msg_type = map_cld_vendor_sub_cmd_to_wifi_pos_cmd( + nla_get_u32(tb[CLD80211_ATTR_CMD])); + req->rsp_version = WIFI_POS_RSP_V2_NL; + + if (tb[CLD80211_ATTR_CMD_TAG_DATA]) { + msg_len = nla_len(tb[CLD80211_ATTR_CMD_TAG_DATA]); + msg = nla_data(tb[CLD80211_ATTR_CMD_TAG_DATA]); + + if (req->msg_type == WIFI_POS_CMD_OEM_DATA) { + if (wifi_pos_parse_nla_oemdata_req(msg_len, msg, req)) { + osif_err("parsing oemdata req failed"); + return OEM_ERR_INVALID_MESSAGE_LENGTH; + } + } else { + req->buf_len = msg_len; + req->buf = msg; + } + } + if (tb[CLD80211_ATTR_META_DATA]) + osif_err("meta data dropped. Apps can use CLD80211_ATTR_CMD_TAG_DATA sub attrs"); + + return 0; +} + +static int wifi_pos_parse_ani_req(const void *data, int len, int pid, + struct wifi_pos_req_msg *req) +{ + tAniMsgHdr *msg_hdr; + struct nlattr *tb[CLD80211_ATTR_MAX + 1]; + uint32_t msg_len, id, nl_field_info_size, expected_field_info_size; + struct wifi_pos_field_info *field_info; + + if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) { + osif_err("invalid data in request"); return OEM_ERR_INVALID_MESSAGE_TYPE; } msg_len = nla_len(tb[CLD80211_ATTR_DATA]); if (msg_len < sizeof(*msg_hdr)) { - cfg80211_err("Insufficient length for msg_hdr: %u", msg_len); + osif_err("Insufficient length for msg_hdr: %u", msg_len); return OEM_ERR_INVALID_MESSAGE_LENGTH; } msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]); - req->msg_type = msg_hdr->type; + req->msg_type = map_ani_msg_req_to_wifi_pos_cmd( + (uint32_t)msg_hdr->type); + req->rsp_version = WIFI_POS_RSP_V1_FLAT_MEMORY; if (msg_len < sizeof(*msg_hdr) + msg_hdr->length) { - cfg80211_err("Insufficient length for msg_hdr buffer: %u", - msg_len); + osif_err("Insufficient length for msg_hdr buffer: %u", + msg_len); return OEM_ERR_INVALID_MESSAGE_LENGTH; } @@ -122,14 +717,14 @@ static int wifi_pos_parse_req(const void *data, int len, int pid, nl_field_info_size = nla_len(tb[id]); if (nl_field_info_size < sizeof(*field_info)) { - cfg80211_err("Insufficient length for field_info_buf: %u", - nl_field_info_size); + osif_err("Insufficient length for field_info_buf: %u", + nl_field_info_size); return OEM_ERR_INVALID_MESSAGE_LENGTH; } field_info = nla_data(tb[id]); if (!field_info->count) { - cfg80211_debug("field_info->count is zero, ignoring META_DATA"); + osif_debug("field_info->count is zero, ignoring META_DATA"); return 0; } @@ -137,8 +732,8 @@ static int wifi_pos_parse_req(const void *data, int len, int pid, (field_info->count - 1) * sizeof(struct wifi_pos_field); if (nl_field_info_size < expected_field_info_size) { - cfg80211_err("Insufficient len for total no.of %u fields", - field_info->count); + osif_err("Insufficient len for total no.of %u fields", + field_info->count); return OEM_ERR_INVALID_MESSAGE_LENGTH; } @@ -147,6 +742,29 @@ static int wifi_pos_parse_req(const void *data, int len, int pid, return 0; } + + +static int wifi_pos_parse_req(const void *data, int len, int pid, + struct wifi_pos_req_msg *req) +{ + int status = 0; + struct nlattr *tb[CLD80211_ATTR_MAX + 1]; + + if (wlan_cfg80211_nla_parse(tb, CLD80211_ATTR_MAX, data, len, NULL)) { + osif_err("invalid data in request"); + return OEM_ERR_INVALID_MESSAGE_TYPE; + } + + if (tb[CLD80211_ATTR_DATA]) { + status = wifi_pos_parse_ani_req(data, len, pid, req); + } else if (tb[CLD80211_ATTR_CMD]) { + status = wifi_pos_parse_nla_req(data, len, pid, req); + } else { + osif_err("Valid CLD80211 ATTR not present"); + return OEM_ERR_INVALID_MESSAGE_TYPE; + } + return status; +} #else static int wifi_pos_parse_req(struct sk_buff *skb, struct wifi_pos_req_msg *req) { @@ -154,35 +772,47 @@ static int wifi_pos_parse_req(struct sk_buff *skb, struct wifi_pos_req_msg *req) /* NLMSG_DATA(nlh) contains ANI msg */ struct nlmsghdr *nlh; tAniMsgHdr *msg_hdr; + size_t field_info_len; nlh = (struct nlmsghdr *)skb->data; if (!nlh) { - cfg80211_err("Netlink header null"); + osif_err("Netlink header null"); return OEM_ERR_NULL_MESSAGE_HEADER; } if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*msg_hdr))) { - cfg80211_err("nlmsg_len(%d) and msg_hdr_size(%zu) mis-match", - nlh->nlmsg_len, sizeof(*msg_hdr)); + osif_err("nlmsg_len(%d) and msg_hdr_size(%zu) mis-match", + nlh->nlmsg_len, sizeof(*msg_hdr)); return OEM_ERR_INVALID_MESSAGE_LENGTH; } msg_hdr = NLMSG_DATA(nlh); if (!msg_hdr) { - cfg80211_err("Message header null"); + osif_err("Message header null"); return OEM_ERR_NULL_MESSAGE_HEADER; } if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*msg_hdr) + msg_hdr->length)) { - cfg80211_err("nlmsg_len(%d) and animsg_len(%d) mis-match", - nlh->nlmsg_len, msg_hdr->length); + osif_err("nlmsg_len(%d) and animsg_len(%d) mis-match", + nlh->nlmsg_len, msg_hdr->length); return OEM_ERR_INVALID_MESSAGE_LENGTH; } - req->msg_type = msg_hdr->type; + req->msg_type = map_ani_msg_req_to_wifi_pos_cmd( + (uint32_t)msg_hdr->type); + req->rsp_version = WIFI_POS_RSP_V1_FLAT_MEMORY; req->buf_len = msg_hdr->length; req->buf = (uint8_t *)&msg_hdr[1]; req->pid = nlh->nlmsg_pid; + req->field_info_buf = NULL; + + field_info_len = nlh->nlmsg_len - + (NLMSG_LENGTH(sizeof(*msg_hdr) + msg_hdr->length)); + if (field_info_len) { + req->field_info_buf = (struct wifi_pos_field_info *) + (req->buf + req->buf_len); + req->field_info_buf_len = field_info_len; + } return 0; } @@ -204,9 +834,9 @@ static void __os_if_wifi_pos_callback(const void *data, int data_len, struct wifi_pos_req_msg req = {0}; struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); - cfg80211_debug("enter: pid %d", pid); + osif_debug("enter: pid %d", pid); if (!psoc) { - cfg80211_err("global psoc object not registered yet."); + osif_err("global psoc object not registered yet."); return; } @@ -214,15 +844,15 @@ static void __os_if_wifi_pos_callback(const void *data, int data_len, err = wifi_pos_parse_req(data, data_len, pid, &req); if (err) { os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc), - ANI_MSG_OEM_ERROR, sizeof(err), &err); + WIFI_POS_CMD_ERROR, sizeof(err), &err); status = QDF_STATUS_E_INVAL; goto release_psoc_ref; } status = ucfg_wifi_pos_process_req(psoc, &req, os_if_wifi_pos_send_rsp); if (QDF_IS_STATUS_ERROR(status)) - cfg80211_err("ucfg_wifi_pos_process_req failed. status: %d", - status); + osif_err("ucfg_wifi_pos_process_req failed. status: %d", + status); release_psoc_ref: wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID); @@ -247,9 +877,9 @@ static int __os_if_wifi_pos_callback(struct sk_buff *skb) struct wifi_pos_req_msg req = {0}; struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); - cfg80211_debug("enter"); + osif_debug("enter"); if (!psoc) { - cfg80211_err("global psoc object not registered yet."); + osif_err("global psoc object not registered yet."); return -EINVAL; } @@ -257,15 +887,15 @@ static int __os_if_wifi_pos_callback(struct sk_buff *skb) err = wifi_pos_parse_req(skb, &req); if (err) { os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc), - ANI_MSG_OEM_ERROR, sizeof(err), &err); + WIFI_POS_CMD_ERROR, sizeof(err), &err); status = QDF_STATUS_E_INVAL; goto release_psoc_ref; } status = ucfg_wifi_pos_process_req(psoc, &req, os_if_wifi_pos_send_rsp); if (QDF_IS_STATUS_ERROR(status)) - cfg80211_err("ucfg_wifi_pos_process_req failed. status: %d", - status); + osif_err("ucfg_wifi_pos_process_req failed. status: %d", + status); release_psoc_ref: wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID); @@ -294,7 +924,7 @@ int os_if_wifi_pos_register_nl(void) int ret = register_cld_cmd_cb(WLAN_NL_MSG_OEM, os_if_wifi_pos_callback, NULL); if (ret) - cfg80211_err("register_cld_cmd_cb failed"); + osif_err("register_cld_cmd_cb failed"); return ret; } @@ -304,13 +934,14 @@ int os_if_wifi_pos_register_nl(void) return nl_srv_register(WLAN_NL_MSG_OEM, os_if_wifi_pos_callback); } #endif /* CNSS_GENL */ +qdf_export_symbol(os_if_wifi_pos_register_nl); #ifdef CNSS_GENL int os_if_wifi_pos_deregister_nl(void) { int ret = deregister_cld_cmd_cb(WLAN_NL_MSG_OEM); if (ret) - cfg80211_err("deregister_cld_cmd_cb failed"); + osif_err("deregister_cld_cmd_cb failed"); return ret; } @@ -329,16 +960,16 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac, enum QDF_OPMODE dev_mode) { struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); - struct wmi_pos_peer_status_info *peer_info; + struct wifi_pos_peer_status_info *peer_info; if (!psoc) { - cfg80211_err("global wifi_pos psoc object not registered"); + osif_err("global wifi_pos psoc object not registered"); return; } if (!wifi_pos_is_app_registered(psoc) || wifi_pos_get_app_pid(psoc) == 0) { - cfg80211_debug("app is not registered or pid is invalid"); + osif_debug("app is not registered or pid is invalid"); return; } @@ -370,7 +1001,7 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac, } os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc), - ANI_MSG_PEER_STATUS_IND, + WIFI_POS_PEER_STATUS_IND, sizeof(*peer_info), (uint8_t *)peer_info); qdf_mem_free(peer_info); } @@ -379,7 +1010,7 @@ int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, struct wifi_pos_driver_caps *caps) { if (!psoc || !caps) { - cfg80211_err("psoc or caps buffer is null"); + osif_err("psoc or caps buffer is null"); return -EINVAL; } diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_cfg80211.h b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_cfg80211.h index 4debaa4613fec11f2655a856e16506b30826c3ca..52f21045018d8cf2962b4c8dc9a9adeb22da597f 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_cfg80211.h +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_cfg80211.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,37 +29,133 @@ #include #include #include +#include +#include "qal_devcfg.h" -#define cfg80211_alert(params...) \ +#define osif_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_err(params...) \ +#define osif_err(params...) \ QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_warn(params...) \ +#define osif_warn(params...) \ QDF_TRACE_WARN(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_notice(params...) \ +#define osif_notice(params...) \ QDF_TRACE_INFO(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_info(params...) \ +#define osif_info(params...) \ QDF_TRACE_INFO(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_debug(params...) \ +#define osif_debug(params...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, params) -#define cfg80211_debug_rl(params...) \ +#define osif_rl_debug(params...) \ QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_OS_IF, params) +#define osif_err_rl(params...) \ + QDF_TRACE_ERROR_RL(QDF_MODULE_ID_OS_IF, params) -#define COMMON_VENDOR_COMMANDS \ -{ \ - .info.vendor_id = OUI_QCA, \ - .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,\ - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ - WIPHY_VENDOR_CMD_NEED_NETDEV, \ - .doit = NULL \ -}, \ -{ \ - .info.vendor_id = OUI_QCA, \ - .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION,\ - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ - WIPHY_VENDOR_CMD_NEED_NETDEV, \ - .doit = NULL \ -}, +#define osif_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_OS_IF, params) +#define osif_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_OS_IF, params) +#define osif_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_OS_IF, params) +#define osif_nofl_info(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_OS_IF, params) +#define osif_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_OS_IF, params) + +/* For kernel version >= 5.2, driver needs to provide policy */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +#define vendor_command_policy(__policy, __maxattr) \ + .policy = __policy, \ + .maxattr = __maxattr +#else +#define vendor_command_policy(__policy, __maxattr) +#endif /*End of (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */ + +#if defined(NBUF_MEMORY_DEBUG) && defined(NETLINK_BUF_TRACK) +#define wlan_cfg80211_vendor_free_skb(skb) \ + qdf_nbuf_free(skb) + +#define wlan_cfg80211_vendor_event(skb, gfp) \ +{ \ + qdf_nbuf_count_dec(skb); \ + qdf_net_buf_debug_release_skb(skb); \ + cfg80211_vendor_event(skb, gfp); \ +} + +#define wlan_cfg80211_vendor_cmd_reply(skb) \ +{ \ + qdf_nbuf_count_dec(skb); \ + qdf_net_buf_debug_release_skb(skb); \ + cfg80211_vendor_cmd_reply(skb); \ +} + +static inline QDF_STATUS wlan_cfg80211_qal_devcfg_send_response(qdf_nbuf_t skb) +{ + qdf_nbuf_count_dec(skb); + qdf_net_buf_debug_release_skb(skb); + return qal_devcfg_send_response(skb); +} + +static inline struct sk_buff * +__cfg80211_vendor_cmd_alloc_reply_skb(struct wiphy *wiphy, int len, + const char *func, uint32_t line) +{ + struct sk_buff *skb; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); + if (skb) { + qdf_nbuf_count_inc(skb); + qdf_net_buf_debug_acquire_skb(skb, func, line); + } + return skb; +} +#define wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) \ + __cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len, __func__, __LINE__) + +static inline struct sk_buff * +__cfg80211_vendor_event_alloc(struct wiphy *wiphy, + struct wireless_dev *wdev, + int approxlen, + int event_idx, + gfp_t gfp, + const char *func, + uint32_t line) +{ + struct sk_buff *skb; + + skb = cfg80211_vendor_event_alloc(wiphy, wdev, + approxlen, + event_idx, + gfp); + if (skb) { + qdf_nbuf_count_inc(skb); + qdf_net_buf_debug_acquire_skb(skb, func, line); + } + return skb; +} +#define wlan_cfg80211_vendor_event_alloc(wiphy, wdev, len, idx, gfp) \ + __cfg80211_vendor_event_alloc(wiphy, wdev, len, \ + idx, gfp, \ + __func__, __LINE__) +#else /* NBUF_MEMORY_DEBUG && NETLINK_BUF_TRACK */ +#define wlan_cfg80211_vendor_free_skb(skb) \ + kfree_skb(skb) + +#define wlan_cfg80211_vendor_event(skb, gfp) \ + cfg80211_vendor_event(skb, gfp) + +#define wlan_cfg80211_vendor_cmd_reply(skb) \ + cfg80211_vendor_cmd_reply(skb) + +#define wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) \ + cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len) + +#define wlan_cfg80211_vendor_event_alloc(wiphy, wdev, len, idx, gfp) \ + cfg80211_vendor_event_alloc(wiphy, wdev, len, idx, gfp) + +static inline QDF_STATUS wlan_cfg80211_qal_devcfg_send_response( qdf_nbuf_t skb) +{ + return qal_devcfg_send_response(skb); +} +#endif /* NBUF_MEMORY_DEBUG && NETLINK_BUF_TRACK */ #undef nla_parse #undef nla_parse_nested @@ -116,5 +212,4 @@ wlan_cfg80211_nla_put_u64(struct sk_buff *skb, int attrtype, u64 value) return nla_put_u64_64bit(skb, attrtype, value, NL80211_ATTR_PAD); } #endif - #endif diff --git a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_osif_request_manager.c b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_osif_request_manager.c index 719200dca01145799e5d5f140358245d6dacdc1a..52cb1a54f1c614a95727dc4ea4aba6d5afa72e3b 100644 --- a/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_osif_request_manager.c +++ b/drivers/staging/qca-wifi-host-cmn/os_if/linux/wlan_osif_request_manager.c @@ -83,7 +83,7 @@ struct osif_request *osif_request_alloc(const struct osif_request_params *params struct osif_request *request; if (!is_initialized) { - cfg80211_err("invoked when not initialized"); + osif_err("invoked when not initialized"); return NULL; } @@ -119,7 +119,7 @@ struct osif_request *osif_request_get(void *cookie) struct osif_request *request; if (!is_initialized) { - cfg80211_err("invoked when not initialized"); + osif_err("invoked when not initialized"); return NULL; } qdf_spin_lock_bh(&spinlock); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/Kbuild b/drivers/staging/qca-wifi-host-cmn/qdf/Kbuild index 0d46466d82cc8d968df7bc8b03e09e27f9438a46..85f1b10faefacab7ec745935bbf14c1e5fee229a 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/Kbuild +++ b/drivers/staging/qca-wifi-host-cmn/qdf/Kbuild @@ -17,6 +17,7 @@ INCS += -Inbuf/linux -Inet/linux -Ios/linux INCS += -I$(WLAN_TOP)/../../include INCS += -I$(WLAN_TOP)/cmn_dev/qdf/inc INCS += -I$(WLAN_TOP)/cmn_dev/qal/inc +INCS += -I$(WLAN_TOP)/cmn_dev/utils/sys INCS += -I$(WLAN_TOP)/component_dev/qal/inc INCS += -I$(WLAN_TOP)/cmn_dev/qal/linux/src INCS += -I$(WLAN_TOP)/cmn_dev/qdf/linux/src diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_m.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_m.h index 150e40bb9b9c5ab4cb9c578099afada08073b8d4..da6cbd22693f2d223e042d9c41c670f3215730a3 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_m.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_m.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017,2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -58,20 +58,113 @@ static inline void qdf_nbuf_ipa_priv_set(qdf_nbuf_t buf, uint32_t priv) /** * qdf_nbuf_set_rx_protocol_tag() * @buf: Network buffer - * @val: Value to be set - * Return: void + * @val: Value to be set in the nbuf + * Return: None */ -static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint32_t val) +static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint16_t val) { } /** * qdf_nbuf_get_rx_protocol_tag() * @buf: Network buffer - * Return: void + * Return: Value of rx protocol tag, here 0 */ -static inline int qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) +static inline uint16_t qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) { return 0; } + +/** + * qdf_nbuf_set_rx_flow_tag() - set given value in flow tag field + * of buf(skb->cb) + * @buf: Network buffer + * @val: Rx Flow Tag to be set in the nbuf + * Return: None + */ +static inline void qdf_nbuf_set_rx_flow_tag(qdf_nbuf_t buf, uint16_t val) +{ +} + +/** + * qdf_nbuf_get_rx_flow_tag() - Get the value of flow_tag + * field of buf(skb->cb) + * @buf: Network buffer + * Return: Value of rx flow tag, here 0 + */ +static inline uint16_t qdf_nbuf_get_rx_flow_tag(qdf_nbuf_t buf) +{ + return 0; +} + +/** + * qdf_nbuf_set_exc_frame() - set exception frame flag + * @buf: Network buffer whose cb is to set exception frame flag + * @value: exception frame flag, value 0 or 1. + * + * Return: none + */ +static inline void qdf_nbuf_set_exc_frame(qdf_nbuf_t buf, uint8_t value) +{ + QDF_NBUF_CB_RX_PACKET_EXC_FRAME(buf) = value; +} + +/** + * qdf_nbuf_is_exc_frame() - check exception frame flag bit + * @buf: Network buffer to get exception flag + * + * Return: 0 or 1 + */ +static inline uint8_t qdf_nbuf_is_exc_frame(qdf_nbuf_t buf) +{ + return QDF_NBUF_CB_RX_PACKET_EXC_FRAME(buf); +} + +/** + * qdf_nbuf_set_rx_reo_dest_ind() - set reo destination indication + * @buf: Network buffer + * @value: reo destination indication value to set + * + * Return: none + */ +static inline void qdf_nbuf_set_rx_reo_dest_ind(qdf_nbuf_t buf, + uint8_t value) +{ + QDF_NBUF_CB_RX_PACKET_REO_DEST_IND(buf) = value; +} + +/** + * qdf_nbuf_get_rx_reo_dest_ind() - get reo destination indication + * @buf: Network buffer + * + * Return reo destination indication value (0 ~ 31) + */ +static inline uint8_t qdf_nbuf_get_rx_reo_dest_ind(qdf_nbuf_t buf) +{ + return QDF_NBUF_CB_RX_PACKET_REO_DEST_IND(buf); +} + +/** + * qdf_nbuf_set_rx_ipa_smmu_map() - set ipa smmu mapped flag + * @buf: Network buffer + * @value: 1 - ipa smmu mapped, 0 - ipa smmu unmapped + * + * Return: none + */ +static inline void qdf_nbuf_set_rx_ipa_smmu_map(qdf_nbuf_t buf, + uint8_t value) +{ + QDF_NBUF_CB_RX_PACKET_IPA_SMMU_MAP(buf) = value; +} + +/** + * qdf_nbuf_is_rx_ipa_smmu_map() - check ipa smmu map flag + * @buf: Network buffer + * + * Return 0 or 1 + */ +static inline uint8_t qdf_nbuf_is_rx_ipa_smmu_map(qdf_nbuf_t buf) +{ + return QDF_NBUF_CB_RX_PACKET_IPA_SMMU_MAP(buf); +} #endif /* _QDF_NBUF_M_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_w.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_w.h index b9ce5e005d7027503e06d9555cb52b11bd77dd04..04be21b63cd20072187132eea60b4b05ac6de586 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_w.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/i_qdf_nbuf_api_w.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017,2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,10 +68,10 @@ qdf_nbuf_set_ext_cb(qdf_nbuf_t buf, void *ref) * qdf_nbuf_set_rx_protocol_tag() - set given value in protocol_tag * field of buf(skb->cb) * @buf: Network buffer - * @val: Value to be set - * Return: void + * @val: Value to be set in the nbuf + * Return: None */ -static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint32_t val) +static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint16_t val) { __qdf_nbuf_set_rx_protocol_tag(buf, val); } @@ -80,10 +80,79 @@ static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint32_t val) * qdf_nbuf_get_rx_protocol_tag() - Get the value of protocol_tag * field of buf(skb->cb) * @buf: Network buffer - * Return: void + * Return: Value of Rx protocol tag in the nbuf */ -static inline int qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) +static inline uint16_t qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) { return __qdf_nbuf_get_rx_protocol_tag(buf); } + +/** + * qdf_nbuf_set_rx_flow_tag() - set given value in flow tag field + * of buf(skb->cb) + * @buf: Network buffer + * @val: Value of Rx flow tag to be set in the nbuf + * Return: None + */ +static inline void qdf_nbuf_set_rx_flow_tag(qdf_nbuf_t buf, uint16_t val) +{ + __qdf_nbuf_set_rx_flow_tag(buf, val); +} + +/** + * qdf_nbuf_get_rx_flow_tag() - Get the value of flow_tag + * field of buf(skb->cb) + * @buf: Network buffer + * Return: Value of the Rx flow tag in the nbuf + */ +static inline uint16_t qdf_nbuf_get_rx_flow_tag(qdf_nbuf_t buf) +{ + return __qdf_nbuf_get_rx_flow_tag(buf); +} + +/** + * qdf_nbuf_set_exc_frame() - set exception frame flag + * @buf: Network buffer whose cb is to set exception frame flag + * @value: exception frame flag, value 0 or 1. + * + * Return: none + */ +static inline void qdf_nbuf_set_exc_frame(qdf_nbuf_t buf, uint8_t value) +{ +} + +/** + * qdf_nbuf_set_rx_reo_dest_ind() - set reo destination indication + * @buf: Network buffer + * @value: reo destination indication value to set + * + * Return: none + */ +static inline void qdf_nbuf_set_rx_reo_dest_ind(qdf_nbuf_t buf, + uint8_t value) +{ +} + +/** +* qdf_nbuf_set_rx_ipa_smmu_map() - set ipa smmu mapped flag + * @buf: Network buffer + * @value: 1 - ipa smmu mapped, 0 - ipa smmu unmapped + * + * Return: none + */ +static inline void qdf_nbuf_set_rx_ipa_smmu_map(qdf_nbuf_t buf, + uint8_t value) +{ +} + +/** + * qdf_nbuf_is_rx_ipa_smmu_map() - check ipa smmu map flag + * @buf: Network buffer + * + * Return 0 or 1 + */ +static inline uint8_t qdf_nbuf_is_rx_ipa_smmu_map(qdf_nbuf_t buf) +{ + return 0; +} #endif /* _QDF_NBUF_W_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_atomic.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_atomic.h index 57f66d3ead37f1642f558f8f25a09cef6a95f4e3..3b888c388f32a9e1d130787c897cb49061e234ff 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_atomic.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -154,6 +154,17 @@ static inline int32_t qdf_atomic_dec_return(qdf_atomic_t *v) return __qdf_atomic_dec_return(v); } +/** + * qdf_atomic_inc_not_zero() - increment if not zero + * @v: A pointer to an opaque atomic variable + * + * Return: Returns non-zero on successful increment and zero otherwise + */ +static inline int32_t qdf_atomic_inc_not_zero(qdf_atomic_t *v) +{ + return __qdf_atomic_inc_not_zero(v); +} + /** * qdf_atomic_set_bit - Atomically set a bit in memory * @nr: bit to set diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_debugfs.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_debugfs.h index 62200b30fdaec8c6365c5a91d18ebf00c8981911..46dc3a945a5ae2cc89d24747966a4965c3fd4f59 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_debugfs.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_debugfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -240,6 +240,43 @@ void qdf_debugfs_remove_dir(qdf_dentry_t d); */ void qdf_debugfs_remove_file(qdf_dentry_t d); +/** + * qdf_debugfs_create_file_simplified() - Create a simple debugfs file + * where a single function call produces all the desired output + * @name: name of the file + * @mode: qdf file mode + * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' + * @fops: file operations { .show, .write , .priv... } + * + * Users just have to define the show() function and pass it via @fops.show() + * argument. When the output time comes, the show() will be called once. + * The show() function must do everything that is needed to write the data, + * all in one function call. + * This is useful either for writing small amounts of data to debugfs or + * for cases in which the output is not iterative. + * The private data can be passed via @fops.priv, which will be available + * inside the show() function as the 'private' filed of the qdf_debugfs_file_t. + * + * Return: dentry structure pointer in case of success, otherwise NULL. + * + */ + +qdf_dentry_t qdf_debugfs_create_file_simplified(const char *name, uint16_t mode, + qdf_dentry_t parent, + struct qdf_debugfs_fops *fops); + +/** + * qdf_debugfs_printer() - Print formated string into debugfs file + * @priv: The private data + * @fmt: Format string + * @...: arguments for the format string + * + * This function prints a new line character after printing the formatted + * string into the debugfs file. + * This function can be passed when the argument is of type qdf_abstract_print + */ +int qdf_debugfs_printer(void *priv, const char *fmt, ...); + #else /* WLAN_DEBUGFS */ static inline QDF_STATUS qdf_debugfs_init(void) @@ -333,5 +370,18 @@ static inline void qdf_debugfs_remove_dir_recursive(qdf_dentry_t d) {} static inline void qdf_debugfs_remove_dir(qdf_dentry_t d) {} static inline void qdf_debugfs_remove_file(qdf_dentry_t d) {} +static inline +qdf_dentry_t qdf_debugfs_create_file_simplified(const char *name, uint16_t mode, + qdf_dentry_t parent, + struct qdf_debugfs_fops *fops) +{ + return NULL; +} + +static inline +int qdf_debugfs_printer(void *priv, const char *fmt, ...) +{ + return 0; +} #endif /* WLAN_DEBUGFS */ #endif /* _QDF_DEBUGFS_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hang_event_notifier.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hang_event_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..532ea47ca0e2e20a0bb5df111b0871ba2dbdacea --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hang_event_notifier.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + + /** + * DOC: qdf_hang_event_notifier + * This file provides OS dependent QDF notifier call for hang event + */ + +#ifndef QDF_HANG_EVENT_NOTIFIER_H +#define QDF_HANG_EVENT_NOTIFIER_H + +#include + +#define QDF_HANG_EVENT_VERSION "1" +/* Max hang event buffer size */ +#define QDF_HANG_EVENT_DATA_SIZE 390 +/* Max offset which host can write */ +#define QDF_WLAN_MAX_HOST_OFFSET 194 +/* Start of the Firmware Data offset */ +#define QDF_WLAN_HANG_FW_OFFSET 195 + +/** + * hang_event_tag: Hang event tag for various modules + * @HANG_EVT_TAG_CDS: CDS module hang event tag + * @HANG_EVT_TAG_OS_IF: OS interface module hang event tag + * @HANG_EVT_TAG_OS_IF_SCAN: scan module hang event tag + * @HANG_EVT_TAG_LEGACY_MAC: Legacy mac module hang event tag + * @HANG_EVT_TAG_WMI_EVT_HIST: WMI event history hang event tag + * @HANG_EVT_TAG_WMI_CMD_HIST: WMI command history hang event tag + * @HANG_EVT_TAG_WMI_CMD_HIST: HTC event tag wmi command history hang event tag + * @HANG_EVT_TAG_DP_PEER_INFO: DP peer info hang event tag + * @HANG_EVT_TAG_CE_INFO: Copy Engine hang event tag + * @HANG_EVT_TAG_BUS_INFO: Bus hang event tag + */ +enum hang_event_tag { + HANG_EVT_TAG_CDS, + HANG_EVT_TAG_OS_IF, + HANG_EVT_TAG_OS_IF_SCAN, + HANG_EVT_TAG_LEGACY_MAC, + HANG_EVT_TAG_WMI_EVT_HIST, + HANG_EVT_TAG_WMI_CMD_HIST, + HANG_EVT_TAG_HTC_CREDIT_HIST, + HANG_EVT_TAG_DP_PEER_INFO, + HANG_EVT_TAG_CE_INFO, + HANG_EVT_TAG_BUS_INFO +}; + +#define QDF_HANG_EVENT_TLV_HDR_SIZE (sizeof(uint16_t)) + +#define QDF_HANG_EVT_SET_HDR(tlv_buf, tag, len) \ + (((uint16_t *)(tlv_buf))[0]) = (((tag) << 8) | ((len) & 0x000000FF)) + +#define QDF_HANG_GET_STRUCT_TLVLEN(tlv_struct) \ + ((uint16_t)(sizeof(tlv_struct) - QDF_HANG_EVENT_TLV_HDR_SIZE)) + +/** + * qdf_notifier_data - Private data for notifier data + * @hang_data: Data filled by notifier + * @offset: Current offset of the hang data buffer + */ +struct qdf_notifer_data { + uint8_t *hang_data; + unsigned int offset; +}; + +#ifdef WLAN_HANG_EVENT +/** + * qdf_hang_event_register_notifier() - Hang data notifier register + * @nb: Notifier block + * + * This function registers notifier block for the hang data notifier chain + * the registered function will be invoked when the hang data notifier call + * is invoked. + * + * Return: QDF_STATUS + */ +QDF_STATUS qdf_hang_event_register_notifier(qdf_notif_block *nb); + +/** + * qdf_hang_event_unregister_notifier() - Hang data notifier unregister + * @nb: Notifier block + * + * This function unregisters notifier block for the hang data notifier chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS qdf_hang_event_unregister_notifier(qdf_notif_block *nb); + +/** + * qdf_hang_event_notifier_call() - Hang data notifier register + * @v: state + * @data: Private data for this notifier chain + * + * This function when invoked will call the functions registered with this + * notifier chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS qdf_hang_event_notifier_call(unsigned long v, void *data); +#else +static inline +QDF_STATUS qdf_hang_event_register_notifier(qdf_notif_block *nb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS qdf_hang_event_unregister_notifier(qdf_notif_block *nb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS qdf_hang_event_notifier_call(unsigned long v, void *data) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hashtable.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hashtable.h index 098ee3961c9b1c1a3e36108b56698cf9c73f2959..7bb09b4fd8b15c9daf210afbb749f94c1d6a98ff 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hashtable.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_hashtable.h @@ -96,6 +96,18 @@ #define qdf_ht_for_each(table, i, cursor, entry_field) \ __qdf_ht_for_each(table, i, cursor, entry_field) +/** + * qdf_ht_for_each_safe() - iterate all entries in @table safe against removal + * of hash entry. + * @table: a non-pointer qdf_ht instance to iterate + * @i: int type cursor populated with the bucket index + * @tmp: a &struct used for temporary storage + * @cursor: container struct pointer populated with each iteration + * @entry_field: name of the entry field in the entry container struct + */ +#define qdf_ht_for_each_safe(table, i, tmp, cursor, entry_field) \ + __qdf_ht_for_each_safe(table, i, tmp, cursor, entry_field) + /** * qdf_ht_for_each_in_bucket() - iterate entries in the bucket for @key * @table: a non-pointer qdf_ht instance to iterate diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa.h index 75c0fa68c12e9f7b56b70e320cde8b97307368de..6d13de7d69a6497a2f6ca853ef49a7a51bbe636b 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -214,8 +214,24 @@ typedef __qdf_ipa_gsi_ep_config_t qdf_ipa_gsi_ep_config_t; typedef __qdf_ipa_dp_evt_type_t qdf_ipa_dp_evt_type_t; #ifdef WDI3_STATS_UPDATE +/** + * qdf_ipa_wdi_tx_info_t - WLAN embedded TX bytes information + * + * WLAN host fills this structure to update IPA driver about + * embedded TX information. + */ typedef __qdf_ipa_wdi_tx_info_t qdf_ipa_wdi_tx_info_t; + +/** + * qdf_ipa_wdi_bw_info_t - BW threshold levels to be monitored + * by IPA uC + */ typedef __qdf_ipa_wdi_bw_info_t qdf_ipa_wdi_bw_info_t; + +/** + * qdf_ipa_inform_wlan_bw_t - BW information given by IPA driver + * whenever uC detects threshold level reached + */ typedef __qdf_ipa_inform_wlan_bw_t qdf_ipa_inform_wlan_bw_t; #endif @@ -649,5 +665,22 @@ static inline bool qdf_get_ipa_smmu_enabled(void) } #endif +#ifdef IPA_LAN_RX_NAPI_SUPPORT +/** + * qdf_ipa_get_lan_rx_napi() - Check if NAPI is enabled in LAN + * RX DP + * + * Returns: true if enabled, false otherwise + */ +static inline bool qdf_ipa_get_lan_rx_napi(void) +{ + return __qdf_ipa_get_lan_rx_napi(); +} +#else +static inline bool qdf_ipa_get_lan_rx_napi(void) +{ + return false; +} +#endif /* IPA_LAN_RX_NAPI_SUPPORT */ #endif /* IPA_OFFLOAD */ #endif /* _QDF_IPA_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa_wdi3.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa_wdi3.h index 729e7d304e16f2df19d087ce719a9e5df2a4935f..cdb133e262985be5e50f74374878644bc09ef89f 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa_wdi3.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_ipa_wdi3.h @@ -400,9 +400,9 @@ static inline int qdf_ipa_wdi_release_smmu_mapping(uint32_t num_buffers, #ifdef WDI3_STATS_UPDATE /** - * qdf_ipa_wdi_wlan_stats() - send embedded Tx in bytes to IPA - * - * @tx_stats: tx stats in bytes on sta and sap interface + * qdf_ipa_wdi_wlan_stats() - Client should call this function to + * send Tx byte counts to IPA driver + * @tx_count: number of Tx bytes * * Returns: 0 on success, negative on failure */ @@ -412,7 +412,7 @@ static inline int qdf_ipa_wdi_wlan_stats(qdf_ipa_wdi_tx_info_t *tx_stats) } /** - * ipa_uc_bw_monitor() - start/stop uc bw monitoring + * qdf_ipa_uc_bw_monitor() - start/stop uc bw monitoring * @bw_info: set bw info levels to monitor * * Returns: 0 on success, negative on failure diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_lock.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_lock.h index 3950c564c3176b8ab2eee94ba2e6fe1dc01da29e..91f8948f723fded7f48ad9ced091eba5b8f7379f 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_lock.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_lock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -44,9 +44,14 @@ /* Max hold time in micro seconds, 0 to disable detection*/ #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ 10000 -#define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 1000000 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK 0 +#if QDF_LOCK_STATS +#define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 2000000 +#else +#define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 1000000 +#endif + #if !QDF_LOCK_STATS struct lock_stats {}; #define BEFORE_LOCK(x...) do {} while (0) @@ -85,13 +90,13 @@ do { \ uint64_t BEFORE_LOCK_time; \ uint64_t AFTER_LOCK_time; \ bool BEFORE_LOCK_is_locked = was_locked; \ - BEFORE_LOCK_time = qdf_get_log_timestamp(); \ + BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ do {} while (0) #define AFTER_LOCK(lock, func) \ lock->stats.acquired_by = func; \ - AFTER_LOCK_time = qdf_get_log_timestamp(); \ + AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ lock->stats.acquired++; \ lock->stats.last_acquired = AFTER_LOCK_time; \ if (BEFORE_LOCK_is_locked) { \ @@ -116,11 +121,11 @@ do { \ do { \ uint64_t BEFORE_LOCK_time; \ uint64_t AFTER_LOCK_time; \ - BEFORE_LOCK_time = qdf_get_log_timestamp(); \ + BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ do {} while (0) #define AFTER_TRYLOCK(lock, trylock_return, func) \ - AFTER_LOCK_time = qdf_get_log_timestamp(); \ + AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ if (trylock_return) { \ lock->stats.acquired++; \ lock->stats.last_acquired = AFTER_LOCK_time; \ @@ -133,8 +138,15 @@ do { \ /* max_hold_time in US */ #define BEFORE_UNLOCK(lock, max_hold_time) \ do {\ - uint64_t held_time = qdf_get_log_timestamp() - \ - lock->stats.last_acquired; \ + uint64_t BEFORE_UNLOCK_time; \ + uint64_t held_time; \ + BEFORE_UNLOCK_time = qdf_get_log_timestamp_lightweight(); \ +\ + if (unlikely(BEFORE_UNLOCK_time < lock->stats.last_acquired)) \ + held_time = 0; \ + else \ + held_time = BEFORE_UNLOCK_time - lock->stats.last_acquired; \ +\ lock->stats.held_time += held_time; \ \ if (held_time > lock->stats.max_held_time) \ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_mem.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_mem.h index 69ba990b38a87fa8a2fa6ae5cd3a79fa9a7a0ae0..56c3c498008caf1d1417ffd6c8be29782791c704 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_mem.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_mem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,6 +27,7 @@ /* Include Files */ #include #include +#include #define QDF_CACHE_LINE_SZ __qdf_cache_line_sz @@ -38,6 +39,7 @@ * Return: aligned value. */ #define qdf_align(a, align_size) __qdf_align(a, align_size) +#define qdf_page_size __page_size /** * struct qdf_mem_dma_page_t - Allocated dmaable page @@ -57,12 +59,17 @@ struct qdf_mem_dma_page_t { * @num_pages: Number of allocation needed pages * @dma_pages: page information storage in case of coherent memory * @cacheable_pages: page information storage in case of cacheable memory + * @is_mem_prealloc: flag for multiple pages pre-alloc or not */ struct qdf_mem_multi_page_t { uint16_t num_element_per_page; uint16_t num_pages; struct qdf_mem_dma_page_t *dma_pages; void **cacheable_pages; + qdf_size_t page_size; +#ifdef DP_MEM_PRE_ALLOC + uint8_t is_mem_prealloc; +#endif }; @@ -89,6 +96,13 @@ void qdf_mem_exit(void); #define QDF_MEM_FUNC_NAME_SIZE 48 #ifdef MEMORY_DEBUG +/** + * qdf_mem_debug_config_get() - Get the user configuration of mem_debug_disabled + * + * Return: value of mem_debug_disabled qdf module argument + */ +bool qdf_mem_debug_config_get(void); + /** * qdf_mem_malloc_debug() - debug version of QDF memory allocation API * @size: Number of bytes of memory to allocate. @@ -128,6 +142,28 @@ void qdf_mem_free_debug(void *ptr, const char *file, uint32_t line); #define qdf_mem_free(ptr) \ qdf_mem_free_debug(ptr, __func__, __LINE__) +void qdf_mem_multi_pages_alloc_debug(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + size_t element_size, uint16_t element_num, + qdf_dma_context_t memctxt, bool cacheable, + const char *func, uint32_t line, + void *caller); + +#define qdf_mem_multi_pages_alloc(osdev, pages, element_size, element_num,\ + memctxt, cacheable) \ + qdf_mem_multi_pages_alloc_debug(osdev, pages, element_size, \ + element_num, memctxt, cacheable, \ + __func__, __LINE__, QDF_RET_IP) + +void qdf_mem_multi_pages_free_debug(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, bool cacheable, + const char *func, uint32_t line); + +#define qdf_mem_multi_pages_free(osdev, pages, memctxt, cacheable) \ + qdf_mem_multi_pages_free_debug(osdev, pages, memctxt, cacheable, \ + __func__, __LINE__) + /** * qdf_mem_check_for_leaks() - Assert that the current memory domain is empty * @@ -203,6 +239,10 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, qdf_mem_free_consistent_debug(osdev, dev, size, vaddr, paddr, memctx, \ __func__, __LINE__) #else +static inline bool qdf_mem_debug_config_get(void) +{ + return false; +} /** * qdf_mem_malloc() - allocation QDF memory @@ -217,9 +257,10 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, * specified (for any reason) it returns NULL. */ #define qdf_mem_malloc(size) \ - qdf_mem_malloc_fl(size, __func__, __LINE__) + __qdf_mem_malloc(size, __func__, __LINE__) -void *qdf_mem_malloc_fl(qdf_size_t size, const char *func, uint32_t line); +#define qdf_mem_malloc_fl(size, func, line) \ + __qdf_mem_malloc(size, func, line) /** * qdf_mem_malloc_atomic() - allocation QDF memory atomically @@ -240,25 +281,40 @@ void *qdf_mem_malloc_atomic_fl(qdf_size_t size, const char *func, uint32_t line); -/** - * qdf_mem_free() - free QDF memory - * @ptr: Pointer to the starting address of the memory to be freed. - * - * Return: None - */ -void qdf_mem_free(void *ptr); +#define qdf_mem_free(ptr) \ + __qdf_mem_free(ptr) static inline void qdf_mem_check_for_leaks(void) { } -void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, - qdf_size_t size, qdf_dma_addr_t *paddr); +#define qdf_mem_alloc_consistent(osdev, dev, size, paddr) \ + __qdf_mem_alloc_consistent(osdev, dev, size, paddr, __func__, __LINE__) + +#define qdf_mem_free_consistent(osdev, dev, size, vaddr, paddr, memctx) \ + __qdf_mem_free_consistent(osdev, dev, size, vaddr, paddr, memctx) -void qdf_mem_free_consistent(qdf_device_t osdev, void *dev, - qdf_size_t size, void *vaddr, - qdf_dma_addr_t paddr, qdf_dma_context_t memctx); +void qdf_mem_multi_pages_alloc(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + size_t element_size, uint16_t element_num, + qdf_dma_context_t memctxt, bool cacheable); + +void qdf_mem_multi_pages_free(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, bool cacheable); #endif /* MEMORY_DEBUG */ +/** + * qdf_mem_multi_pages_zero() - zero out each page memory + * @pages: Multi page information storage + * @cacheable: Coherent memory or cacheable memory + * + * This function will zero out each page memory + * + * Return: None + */ +void qdf_mem_multi_pages_zero(struct qdf_mem_multi_page_t *pages, + bool cacheable); + /** * qdf_aligned_malloc() - allocates aligned QDF memory. * @size: Size to be allocated @@ -415,7 +471,7 @@ static inline uint32_t qdf_mem_map_nbytes_single(qdf_device_t osdev, void *buf, qdf_dma_dir_t dir, int nbytes, qdf_dma_addr_t *phy_addr) { -#if defined(HIF_PCI) +#if defined(HIF_PCI) || defined(HIF_IPCI) return __qdf_mem_map_nbytes_single(osdev, buf, dir, nbytes, phy_addr); #else return 0; @@ -444,7 +500,7 @@ static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev, qdf_dma_dir_t dir, int nbytes) { -#if defined(HIF_PCI) +#if defined(HIF_PCI) || defined(HIF_IPCI) __qdf_mem_unmap_nbytes_single(osdev, phy_addr, dir, nbytes); #endif } @@ -511,13 +567,6 @@ void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, qdf_size_t size, __dma_data_direction direction); -void qdf_mem_multi_pages_alloc(qdf_device_t osdev, - struct qdf_mem_multi_page_t *pages, - size_t element_size, uint16_t element_num, - qdf_dma_context_t memctxt, bool cacheable); -void qdf_mem_multi_pages_free(qdf_device_t osdev, - struct qdf_mem_multi_page_t *pages, - qdf_dma_context_t memctxt, bool cacheable); int qdf_mem_multi_page_link(qdf_device_t osdev, struct qdf_mem_multi_page_t *pages, uint32_t elem_size, uint32_t elem_count, uint8_t cacheable); @@ -597,7 +646,7 @@ static inline void qdf_update_mem_map_table(qdf_device_t osdev, uint32_t mem_size) { if (!mem_info) { - __qdf_print("%s: NULL mem_info\n", __func__); + qdf_nofl_err("%s: NULL mem_info", __func__); return; } @@ -794,8 +843,8 @@ static inline void qdf_mem_shared_mem_free(qdf_device_t osdev, qdf_shared_mem_t *shared_mem) { if (!shared_mem) { - __qdf_print("%s: NULL shared mem struct passed\n", - __func__); + qdf_nofl_err("%s: NULL shared mem struct passed", + __func__); return; } diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_nbuf.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_nbuf.h index b91f754c58e7a2934c868c4506df5017d6bd269e..e4aa99db54f8b0ba990ead38814726e9655e1690 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_nbuf.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_nbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -39,6 +39,7 @@ #define QDF_NBUF_PKT_TRAC_TYPE_ARP 0x10 #define QDF_NBUF_PKT_TRAC_TYPE_ICMP 0x20 #define QDF_NBUF_PKT_TRAC_TYPE_ICMPv6 0x40 +#define QDF_HL_CREDIT_TRACKING 0x80 #define QDF_NBUF_PKT_TRAC_MAX_STRING 12 #define QDF_NBUF_PKT_TRAC_PROTO_STRING 4 @@ -50,6 +51,8 @@ #define QDF_NBUF_TRAC_DHCP_SRV_PORT 67 #define QDF_NBUF_TRAC_DHCP_CLI_PORT 68 #define QDF_NBUF_TRAC_ETH_TYPE_OFFSET 12 +#define QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET 16 +#define QDF_NBUF_TRAC_DOUBLE_VLAN_ETH_TYPE_OFFSET 20 #define QDF_NBUF_TRAC_EAPOL_ETH_TYPE 0x888E #define QDF_NBUF_TRAC_WAPI_ETH_TYPE 0x88b4 #define QDF_NBUF_TRAC_ARP_ETH_TYPE 0x0806 @@ -83,7 +86,11 @@ #define QDF_NBUF_TRAC_DHCP6_SRV_PORT 547 #define QDF_NBUF_TRAC_DHCP6_CLI_PORT 546 #define QDF_NBUF_TRAC_MDNS_SRC_N_DST_PORT 5353 - +#define QDF_NBUF_TRAC_IP_OFFSET 14 +#define QDF_NBUF_TRAC_VLAN_IP_OFFSET 18 +#define QDF_NBUF_TRAC_DOUBLE_VLAN_IP_OFFSET 22 +/* One dword for IPv4 header size unit */ +#define QDF_NBUF_IPV4_HDR_SIZE_UNIT 4 /* EAPOL Related MASK */ #define EAPOL_PACKET_TYPE_OFFSET 15 @@ -166,6 +173,7 @@ #endif #define MAX_CHAIN 8 +#define QDF_MON_STATUS_MPDU_FCS_BMAP_NWORDS 8 /** * struct mon_rx_status - This will have monitor mode rx_status extracted from @@ -239,15 +247,13 @@ * @first_data_seq_ctrl: Sequence ctrl field of first data frame * @rxpcu_filter_pass: Flag which indicates whether RX packets are received in * BSS mode(not in promisc mode) - * @tx_status: packet tx status - * @tx_retry_cnt: tx retry count - * @tx_retry_cnt: tx retry count + * @rssi_chain: Rssi chain per nss per bw */ struct mon_rx_status { uint64_t tsft; uint32_t ppdu_timestamp; uint32_t preamble_type; - uint16_t chan_freq; + qdf_freq_t chan_freq; uint16_t chan_num; uint16_t chan_flags; uint16_t ht_flags; @@ -321,26 +327,71 @@ struct mon_rx_status { uint16_t first_data_seq_ctrl; uint8_t ltf_size; uint8_t rxpcu_filter_pass; - uint8_t tx_status; - uint8_t tx_retry_cnt; - bool add_rtap_ext; + int8_t rssi_chain[8][8]; + uint32_t rx_antenna; }; /** - * struct mon_rx_status - This will have monitor mode per user rx_status + * struct mon_rx_user_status - This will have monitor mode per user rx_status * extracted from hardware TLV. * @mcs: MCS index of Rx frame * @nss: Number of spatial streams - * @ofdma_info_valid: OFDMA info below is valid - * @dl_ofdma_ru_start_index: OFDMA RU start index - * @dl_ofdma_ru_width: OFDMA total RU width + * @mu_ul_info_valid: MU UL info below is valid + * @ofdma_ru_start_index: OFDMA RU start index + * @ofdma_ru_width: OFDMA total RU width + * @ofdma_ru_size: OFDMA RU size index + * @mu_ul_user_v0_word0: MU UL user info word 0 + * @mu_ul_user_v0_word1: MU UL user info word 1 + * @ast_index: AST table hash index + * @tid: QoS traffic tid number + * @tcp_msdu_count: tcp protocol msdu count + * @udp_msdu_count: udp protocol msdu count + * @other_msdu_count: other protocol msdu count + * @frame_control: frame control field + * @frame_control_info_valid: field indicates if fc value is valid + * @data_sequence_control_info_valid: field to indicate validity of seq control + * @first_data_seq_ctrl: Sequence ctrl field of first data frame + * @preamble_type: Preamble type in radio header + * @ht_flags: HT flags, only present for HT frames. + * @vht_flags: VHT flags, only present for VHT frames. + * @he_flags: HE (11ax) flags, only present in HE frames + * @rtap_flags: Bit map of available fields in the radiotap + * @rs_flags: Flags to indicate AMPDU or AMSDU aggregation + * @mpdu_cnt_fcs_ok: mpdu count received with fcs ok + * @mpdu_cnt_fcs_err: mpdu count received with fcs ok bitmap + * @mpdu_fcs_ok_bitmap: mpdu with fcs ok bitmap + * @mpdu_ok_byte_count: mpdu byte count with fcs ok + * @mpdu_err_byte_count: mpdu byte count with fcs err */ struct mon_rx_user_status { uint32_t mcs:4, nss:3, - ofdma_info_valid:1, - dl_ofdma_ru_start_index:7, - dl_ofdma_ru_width:7; + mu_ul_info_valid:1, + ofdma_ru_start_index:7, + ofdma_ru_width:7, + ofdma_ru_size:8; + uint32_t mu_ul_user_v0_word0; + uint32_t mu_ul_user_v0_word1; + uint32_t ast_index; + uint32_t tid; + uint16_t tcp_msdu_count; + uint16_t udp_msdu_count; + uint16_t other_msdu_count; + uint16_t frame_control; + uint8_t frame_control_info_valid; + uint8_t data_sequence_control_info_valid; + uint16_t first_data_seq_ctrl; + uint32_t preamble_type; + uint16_t ht_flags; + uint16_t vht_flags; + uint16_t he_flags; + uint8_t rtap_flags; + uint8_t rs_flags; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + uint32_t mpdu_fcs_ok_bitmap[QDF_MON_STATUS_MPDU_FCS_BMAP_NWORDS]; + uint32_t mpdu_ok_byte_count; + uint32_t mpdu_err_byte_count; }; /** @@ -1495,6 +1546,24 @@ qdf_nbuf_t qdf_nbuf_clone_debug(qdf_nbuf_t buf, const char *func, */ qdf_nbuf_t qdf_nbuf_copy_debug(qdf_nbuf_t buf, const char *func, uint32_t line); +#define qdf_nbuf_copy_expand(buf, headroom, tailroom) \ + qdf_nbuf_copy_expand_debug(buf, headroom, tailroom, __func__, __LINE__) + +/** + * qdf_nbuf_copy_expand_debug() - copy and expand nbuf + * @buf: Network buf instance + * @headroom: Additional headroom to be added + * @tailroom: Additional tailroom to be added + * @func: name of the calling function + * @line: line number of the callsite + * + * Return: New nbuf that is a copy of buf, with additional head and tailroom + * or NULL if there is no memory + */ +qdf_nbuf_t +qdf_nbuf_copy_expand_debug(qdf_nbuf_t buf, int headroom, int tailroom, + const char *func, uint32_t line); + #else /* NBUF_MEMORY_DEBUG */ static inline void qdf_net_buf_debug_init(void) {} @@ -1575,6 +1644,20 @@ static inline qdf_nbuf_t qdf_nbuf_copy(qdf_nbuf_t buf) return __qdf_nbuf_copy(buf); } +/** + * qdf_nbuf_copy_expand() - copy and expand nbuf + * @buf: Network buf instance + * @headroom: Additional headroom to be added + * @tailroom: Additional tailroom to be added + * + * Return: New nbuf that is a copy of buf, with additional head and tailroom + * or NULL if there is no memory + */ +static inline qdf_nbuf_t qdf_nbuf_copy_expand(qdf_nbuf_t buf, int headroom, + int tailroom) +{ + return __qdf_nbuf_copy_expand(buf, headroom, tailroom); +} #endif /* NBUF_MEMORY_DEBUG */ #ifdef WLAN_FEATURE_FASTPATH @@ -3116,6 +3199,17 @@ static inline void qdf_nbuf_unmap_tso_segment(qdf_device_t osdev, return __qdf_nbuf_unmap_tso_segment(osdev, tso_seg, is_last_seg); } +/** + * qdf_nbuf_get_tcp_payload_len() - function to return the tso payload len + * @nbuf: network buffer + * + * Return: size of the tso packet + */ +static inline size_t qdf_nbuf_get_tcp_payload_len(qdf_nbuf_t nbuf) +{ + return __qdf_nbuf_get_tcp_payload_len(nbuf); +} + /** * qdf_nbuf_get_tso_num_seg() - function to calculate the number * of TCP segments within the TSO jumbo packet @@ -3235,8 +3329,9 @@ qdf_nbuf_unshare_debug(qdf_nbuf_t buf, const char *func_name, uint32_t line_num) if (qdf_likely(buf != unshared_buf)) { qdf_net_buf_debug_delete_node(buf); - qdf_net_buf_debug_add_node(unshared_buf, 0, - func_name, line_num); + if (unshared_buf) + qdf_net_buf_debug_add_node(unshared_buf, 0, + func_name, line_num); } return unshared_buf; @@ -3530,7 +3625,7 @@ static inline void qdf_nbuf_orphan(qdf_nbuf_t buf) return __qdf_nbuf_orphan(buf); } -#ifdef CONFIG_WIN +#ifdef CONFIG_NBUF_AP_PLATFORM #include #else #include diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_net_types.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_net_types.h index 1772bdf0d8972e2aa0829b92daacbdf15b5808e2..c3a60736bbdac77cce89fced2bd2adbeebe207b9 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_net_types.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_net_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,6 +61,7 @@ typedef __in6_addr_t in6_addr_t; #define QDF_ETH_TYPE_IPV4 0x0800 /* IPV4 */ #define QDF_ETH_TYPE_IPV6 0x86dd /* IPV6 */ #define QDF_ETH_TYPE_8021Q 0x8100 /* 802.1Q vlan protocol */ +#define QDF_ETH_TYPE_8021AD 0x88a8 /* 802.1AD vlan protocol */ #define QDF_IEEE80211_4ADDR_HDR_LEN 30 #define QDF_IEEE80211_3ADDR_HDR_LEN 24 #define QDF_IEEE80211_FC0_SUBTYPE_QOS 0x80 @@ -74,6 +75,9 @@ typedef __in6_addr_t in6_addr_t; #define QDF_IEEE80211_FC0_SUBTYPE_DATA 0x00 #define QDF_IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define QDF_IEEE80211_FC0_SUBTYPE_QOS_NULL 0xC0 +#define QDF_IEEE80211_FC0_SUBTYPE_NODATA 0x40 + #define QDF_IEEE80211_FC0_TYPE_CTL 0x04 #define QDF_IEEE80211_FC0_SUBTYPE_BEAM_REPORT_POLL 0x40 #define QDF_IEEE80211_FC0_SUBTYPE_VHT_NDP_AN 0x50 diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_notifier.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..1d090e01766c1da4b67df75bde1c26da65a4e7b5 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_notifier.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * @file qdf_notifier.h + * This file abstracts notifier chain call operations. + */ + +#ifndef _QDF_NOTIFIER_H +#define _QDF_NOTIFIER_H + +#include +#include + +/* + * qdf_notif_block - qdf notifier block + * @__qdf_notifier_block: OS specific notifier block + * @priv_data: private data of the notifier block + */ +typedef struct { + __qdf_notifier_block notif_block; + void *priv_data; +} qdf_notif_block; + +typedef __qdf_blocking_notif_head qdf_blocking_notif_head; +typedef __qdf_atomic_notif_head qdf_atomic_notif_head; +typedef __qdf_notifier_block qdf_notifier_block; + +#ifdef WLAN_HANG_EVENT + +/** + * qdf_register_blocking_notifier_chain() - Register for blocking notifier chain + * @qdf_blocking_notif_head: Head of blocking notifier chain + * @qdf_notif_block: Notifier Block to be registered for this head chain + * + * This function is invoked to add a notifier block for the specific notifier + * head chain. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_register_blocking_notifier_chain(qdf_blocking_notif_head *head, + qdf_notif_block *qnb); +/** + * qdf_unregister_blocking_notifier_chain() - Unregister for blocking notifier + * chain + * @qdf_blocking_notif_head: Head of blocking notifier chain + * @qdf_notif_block: Notifier Block to be registered for this head chain + * + * This function is invoked to remove a notifier block for the specific notifier + * head chain. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_unregister_blocking_notifier_chain(qdf_blocking_notif_head *head, + qdf_notif_block *qnb); +/** + * qdf_blocking_notfier_call() - Invoke the function in the blocking chain + * @qdf_blocking_notif_head: Head of blocking notifier chain + * @state: state passed during the invoking of the notifier + * @data: Private data to be passed to all the notifier functions + * + * This function is called to invoke all the notifier blocks for the specific + * notifier chain with state and private data. + * when success the notifier reply with NOTIFY_OK. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_blocking_notfier_call(qdf_blocking_notif_head *head, + unsigned long state, void *data); + +/** + * qdf_register_atomic_notifier_chain() - Register for atomic notifier chain + * @qdf_blocking_notif_head: Head of atomic notifier chain + * @qdf_notif_block: Notifier Block to be registered for this head chain + * + * This function is invoked to add a notifier block for the specific atomic + * notifier head chain. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_register_atomic_notifier_chain(qdf_atomic_notif_head *head, + qdf_notif_block *qnb); +/** + * qdf_unregister_atmoic_notifier_chain() - Unregister for atomic notifier + * chain + * @qdf_blocking_notif_head: Head of blocking notifier chain + * @qdf_notif_block: Notifier Block to be registered for this head chain + * + * This function is invoked to remove a notifier block for the specific notifier + * head chain. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_unregister_atomic_notifier_chain(qdf_atomic_notif_head *head, + qdf_notif_block *qnb); +/** + * qdf_blocking_notfier_call() - Invoke the function in the blocking chain + * @qdf_blocking_notif_head: Head of blocking notifier chain + * @v: Generally state passed during the invoking of the notifier + * @data: Private data to be passed to all the notifier functions + * + * This function is invoke a notifier block for the specific notifier head chain + * with state and private data. when success the notifier reply with NOTIFY_OK. + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_atomic_notfier_call(qdf_atomic_notif_head *head, + unsigned long v, void *data); +#else + +static inline QDF_STATUS qdf_register_blocking_notifier_chain( + qdf_blocking_notif_head *head, + qdf_notif_block *qnb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS qdf_unregister_blocking_notifier_chain( + qdf_blocking_notif_head *head, + qdf_notif_block *qnb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS qdf_blocking_notfier_call( + qdf_blocking_notif_head *head, + unsigned long v, void *data) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS qdf_register_atomic_notifier_chain( + qdf_atomic_notif_head *head, + qdf_notif_block *qnb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS qdf_unregister_atomic_notifier_chain( + qdf_atomic_notif_head *head, + qdf_notif_block *qnb) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS qdf_atomic_notfier_call(qdf_atomic_notif_head *head, + unsigned long v, void *data) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_platform.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_platform.h index 9833002b372194a346f884a4c23a36ced2fa12ef..36e738eb004f4bc88706127e339d64378c6fc632 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_platform.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_platform.h @@ -28,13 +28,15 @@ /** * qdf_self_recovery_callback() - callback for self recovery + * @psoc: pointer to the posc object * @reason: the reason for the recovery request * @func: the caller's function name * @line: the line number of the callsite * * Return: none */ -typedef void (*qdf_self_recovery_callback)(enum qdf_hang_reason reason, +typedef void (*qdf_self_recovery_callback)(void *psoc, + enum qdf_hang_reason reason, const char *func, const uint32_t line); @@ -133,6 +135,7 @@ void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback); /** * qdf_trigger_self_recovery () - trigger self recovery + * @psoc: the psoc at which the recovery is being triggered * @reason: the reason for the recovery request * * Call API only in case of fatal error, @@ -141,9 +144,9 @@ void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback); * * Return: None */ -#define qdf_trigger_self_recovery(reason) \ - __qdf_trigger_self_recovery(reason, __func__, __LINE__) -void __qdf_trigger_self_recovery(enum qdf_hang_reason reason, +#define qdf_trigger_self_recovery(psoc, reason) \ + __qdf_trigger_self_recovery(psoc, reason, __func__, __LINE__) +void __qdf_trigger_self_recovery(void *psoc, enum qdf_hang_reason reason, const char *func, const uint32_t line); /** @@ -252,5 +255,81 @@ void qdf_register_drv_connected_callback(qdf_is_drv_connected_callback */ void qdf_check_state_before_panic(void); -#endif /*_QDF_PLATFORM_H*/ +/** + * qdf_is_drv_supported_callback() - callback to query if drv is supported + * + * Return: true if drv is supported else false + */ +typedef bool (*qdf_is_drv_supported_callback)(void); + +/** + * qdf_is_drv_supported_callback() - API to check if drv is supported or not + * + * DRV is dynamic request voting using which fw can do page fault and + * bring in page back without apps wake up + * + * Return: true: if drv is supported + * false: if drv is not supported + */ +bool qdf_is_drv_supported(void); + +/** + * qdf_register_drv_supported_callback() - API to register drv supported cb + * @is_drv_supported: callback to query if drv is supported or not + * + * Return: none + */ +void qdf_register_drv_supported_callback(qdf_is_drv_supported_callback + is_drv_supported); + +typedef void (*qdf_recovery_reason_update_callback)(enum qdf_hang_reason + reason); + +/** + * qdf_register_recovery_reason_update() - Register callback to update recovery + * reason + * @qdf_recovery_reason_update_callback: callback to update recovery reason + * + * Return: none + */ +void qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback + callback); + +/** + * qdf_recovery_reason_update() - update recovery reason + * @reason: recovery reason + * + * Return: none + */ +void qdf_recovery_reason_update(enum qdf_hang_reason reason); + +/** + * qdf_bus_reg_dump() - callback for getting bus specific register dump + * @dev: Bus specific device + * @buf: Hang event buffer in which the data will be populated + * @len: length of data to be populated in the hang event buffer + * + * Return: none + */ +typedef void (*qdf_bus_reg_dump)(struct device *dev, uint8_t *buf, + uint32_t len); +/** + * qdf_register_get_bus_reg_dump() - Register callback to update bus register + * dump + * @qdf_bus_reg_dump: callback to update bus register dump + * + * Return: none + */ +void qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback); + +/** + * qdf_get_bus_reg_dump() - Get the register dump for the bus + * @dev: device + * @buffer: buffer for hang data + * @len: len of hang data + * + * Return: none + */ +void qdf_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len); +#endif /*_QDF_PLATFORM_H*/ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_str.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_str.h index 7864a4412e3a6a73ffed019e6fb181d2d40cda9c..5c04baa5bd485902b36502c305194fbbcdba35b0 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_str.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_str.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -154,4 +154,20 @@ static inline qdf_size_t qdf_str_nlen(const char *str, qdf_size_t limit) return __qdf_str_nlen(str, limit); } +/** + * qdf_str_ncmp - Compare two strings + * @str1: First string + * @str2: Second string + * @limit: the maximum number of characters to check + * Return: + * 0 - strings are equal + * <0 - str1 sorts lexicographically before str2 + * >0 - str1 sorts lexicographically after str2 + */ +static inline int32_t +qdf_str_ncmp(const char *str1, const char *str2, qdf_size_t limit) +{ + return __qdf_str_ncmp(str1, str2, limit); +} + #endif /* __QDF_STR_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_streamfs.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_streamfs.h new file mode 100644 index 0000000000000000000000000000000000000000..f6449cbe4745c898ed4d8ede27d17c373ef1d5f2 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_streamfs.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: qdf_streamfs.h + * This file provides OS abstraction for stream filesystem APIs. + */ + +#ifndef _QDF_STREAMFS_H +#define _QDF_STREAMFS_H + +#include +#include +#include + +typedef __qdf_streamfs_chan_t qdf_streamfs_chan_t; +typedef __qdf_streamfs_chan_buf_t qdf_streamfs_chan_buf_t; + +#ifdef WLAN_STREAMFS +/** + * qdf_streamfs_create_dir() - wrapper to create a debugfs directory + * @name: name of the new directory + * @parent: parent node. If NULL, defaults to base qdf_debugfs_root + * + * Return: dentry structure pointer in case of success, otherwise NULL. + * + */ +static inline qdf_dentry_t qdf_streamfs_create_dir( + const char *name, qdf_dentry_t parent) +{ + return qdf_debugfs_create_dir(name, parent); +} + +/** + * qdf_streamfs_remove_file() - wrapper to remove streamfs file + * @d: streamfs node + * + */ +static inline void qdf_streamfs_remove_file(qdf_dentry_t d) +{ + qdf_debugfs_remove_file(d); +} + +/** + * qdf_debugfs_remove_dir_recursive() - wrapper to remove directory recursively + * @d: debugfs node + * + * This function will recursively remove a directory in streamfs that was + * previously created with a call to qdf_debugfs_create_file() or it's + * variant functions. + */ +static inline void qdf_streamfs_remove_dir_recursive(qdf_dentry_t d) +{ + qdf_debugfs_remove_dir_recursive(d); +} + +/** + * qdf_streamfs_create_file() - Create streamfs chan buffer file + * @name: base name of file to create + * @mode: filemode + * @parent: dentry of parent directory, NULL for root directory + * @buf: pointer to chan buffer + * + * Returns file dentry pointer if successful, NULL otherwise. + */ +qdf_dentry_t qdf_streamfs_create_file(const char *name, uint16_t mode, + qdf_dentry_t parent, + qdf_streamfs_chan_buf_t buf); + +/** + * qdf_streamfs_open() - Create streamfs channel for data trasfer + * @base_filename: base name of files to create, %NULL for buffering only + * @parent: dentry of parent directory, %NULL for root directory + * @subbuf_size: size of sub-buffers + * @n_subbufs: number of sub-buffers + * @private_data: user-defined data + * + * Returns channel pointer if successful, %NULL otherwise. + */ +qdf_streamfs_chan_t qdf_streamfs_open(const char *base_filename, + qdf_dentry_t parent, + size_t subbuf_size, size_t n_subbufs, + void *private_data); + +/** + * qdf_streamfs_close() - Closes all channel buffers and frees the channel. + * @chan: pointer to qdf_streamfs_chan. + * + * Returns NONE + */ +void qdf_streamfs_close(qdf_streamfs_chan_t chan); + +/** + * qdf_streamfs_flush() - Flushes all channel buffers. + * @chan: pointer to qdf_streamfs_chan. + * + * Returns NONE + */ +void qdf_streamfs_flush(qdf_streamfs_chan_t chan); + +/** + * qdf_streamfs_reset() - Reset streamfs channel + * @chan: pointer to qdf_streamfs_chan. + * + * This erases data from all channel buffers and restarting the channel + * in its initial state. The buffers are not freed, so any mappings are + * still in effect. + * + * Returns NONE + */ +void qdf_streamfs_reset(qdf_streamfs_chan_t chan); + +/** + * qdf_streamfs_subbufs_consumed() - update the buffer's sub-buffers-consumed + * count + * @chan: pointer to qdf_streamfs_chan. + * @cpu: the cpu associated with the channel buffer to update + * @subbufs_consumed: number of sub-buffers to add to current buf's count + * + * Returns NONE + */ +void qdf_streamfs_subbufs_consumed(qdf_streamfs_chan_t chan, + unsigned int cpu, + size_t consumed); + +/** + * qdf_streamfs_write() - write data into the channel + * @chan: relay channel + * @data: data to be written + * @length: number of bytes to write + * + * Writes data into the current cpu's channel buffer. + */ +void qdf_streamfs_write(qdf_streamfs_chan_t chan, const void *data, + size_t length); +#else +static inline qdf_dentry_t qdf_streamfs_create_dir( + const char *name, qdf_dentry_t parent) +{ + return NULL; +} + +static inline void qdf_streamfs_remove_file(qdf_dentry_t d) +{ +} + +static inline void qdf_streamfs_remove_dir_recursive(qdf_dentry_t d) +{ +} + +static inline +qdf_dentry_t qdf_streamfs_create_file(const char *name, uint16_t mode, + qdf_dentry_t parent, + qdf_streamfs_chan_buf_t buf) +{ + return NULL; +} + +static inline +qdf_streamfs_chan_t qdf_streamfs_open(const char *base_filename, + qdf_dentry_t parent, + size_t subbuf_size, size_t n_subbufs, + void *private_data) +{ + return NULL; +} + +static inline void qdf_streamfs_close(qdf_streamfs_chan_t chan) +{ +} + +static inline void qdf_streamfs_flush(qdf_streamfs_chan_t chan) +{ +} + +static inline void qdf_streamfs_reset(qdf_streamfs_chan_t chan) +{ +} + +static inline void +qdf_streamfs_subbufs_consumed(qdf_streamfs_chan_t chan, + unsigned int cpu, size_t consumed) +{ +} + +static inline void +qdf_streamfs_write(qdf_streamfs_chan_t chan, const void *data, + size_t length) +{ +} +#endif /* WLAN_STREAMFS */ +#endif /* _QDF_STREAMFS_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h index fcb28c8bea0a7fad5b0efa3121eb21bc5347a50e..17c8fe467462ff6c4f7ce512dce490d704be5b84 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_threads.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -168,4 +168,24 @@ void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp); * Return: None */ void qdf_cpumask_setall(qdf_cpu_mask *dstp); + +/** + * qdf_cpumask_empty - Check if cpu_mask is empty + * @srcp: cpumask pointer + * + * Return: true or false + * + */ +bool qdf_cpumask_empty(const struct cpumask *srcp); + +/** + * qdf_cpumask_copy - Copy srcp cpumask to dstp + * @srcp: source cpumask pointer + * @dstp: destination cpumask pointer + * + * Return: None + * + */ +void qdf_cpumask_copy(struct cpumask *dstp, + const struct cpumask *srcp); #endif /* __QDF_THREADS_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_time.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_time.h index 32cfeba0068e2ed67556c6ccb71b546d00ba13e5..575e851bd41061da2d2fcf004c036e061af0eb65 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_time.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_time.h @@ -270,6 +270,21 @@ static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time) return time; } + +/** + * qdf_get_log_timestamp_lightweight - get time stamp for logging + * For adrastea this API returns QTIMER tick which is needed to synchronize + * host and fw log timestamps + * For ROME and other discrete solution this API returns system boot time stamp + * + * Return: + * QTIMER ticks(19.2MHz) for adrastea + * System tick for rome and other 3rd party platform solutions + */ +static inline uint64_t qdf_get_log_timestamp_lightweight(void) +{ + return __qdf_get_log_timestamp(); +} #else #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10 @@ -279,6 +294,22 @@ static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time) /* timestamps are already in micro seconds */ return time; } + +static inline uint64_t qdf_get_log_timestamp_lightweight(void) +{ + uint64_t timestamp_us; + + /* explicitly change to uint64_t, otherwise it will assign + * uint32_t to timestamp_us, which lose high 32bits. + * on 64bit platform, it will only use low 32bits jiffies in + * jiffies_to_msecs. + * eg: HZ=250, it will overflow every (0xffff ffff<<2==0x3fff ffff) + * ticks. it is 1193 hours. + */ + timestamp_us = + (uint64_t)__qdf_system_ticks_to_msecs(qdf_system_ticks()) * 1000; + return timestamp_us; +} #endif /* end of MSM_PLATFORM */ static inline void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs, diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_trace.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_trace.h index 2ecbdb5fffaf03d686a21bad3ba21de151cf2ded..cfc389c12460fa04fc5e573cb9fef5eb905982d4 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_trace.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_trace.h @@ -54,10 +54,7 @@ */ #define QDF_WMI_MTRACE_CMD_ID(message_id) ((message_id) & 0x7F) -#ifdef CONFIG_MCL -#define QDF_DEFAULT_TRACE_LEVEL \ - ((1 << QDF_TRACE_LEVEL_FATAL) | (1 << QDF_TRACE_LEVEL_ERROR)) -#else +#ifdef QDF_TRACE_PRINT_ENABLE #define QDF_DEFAULT_TRACE_LEVEL (1 << QDF_TRACE_LEVEL_INFO) #endif @@ -207,6 +204,7 @@ typedef struct s_qdf_trace_data { * @QDF_DP_TRACE_ICMPv6_PACKET_RECORD - record ICMPv6 packet * @QDF_DP_TRACE_HDD_TX_TIMEOUT - HDD tx timeout * @QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT- SOFTAP HDD tx timeout + * @QDF_DP_TRACE_TX_CREDIT_RECORD - credit update record * @QDF_DP_TRACE_ULTRA_LOW_VERBOSITY - Below this is not logged for >4PPS * @QDF_DP_TRACE_TX_PACKET_RECORD - record 32 bytes of tx pkt at any layer * @QDF_DP_TRACE_RX_PACKET_RECORD - record 32 bytes of rx pkt at any layer @@ -253,6 +251,7 @@ enum QDF_DP_TRACE_ID { QDF_DP_TRACE_ICMPv6_PACKET_RECORD, QDF_DP_TRACE_HDD_TX_TIMEOUT, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT, + QDF_DP_TRACE_TX_CREDIT_RECORD, QDF_DP_TRACE_ULTRA_LOW_VERBOSITY, QDF_DP_TRACE_TX_PACKET_RECORD, QDF_DP_TRACE_RX_PACKET_RECORD, @@ -297,6 +296,36 @@ enum qdf_proto_dir { QDF_NA }; +/** + * QDF_CREDIT_UPDATE_SOURCE - source of credit record + * @QDF_TX_SCHED: Tx scheduler + * @QDF_TX_COMP: TX completion + * @QDF_TX_CREDIT_UPDATE: credit update indication + * @QDF_HTT_ATTACH: HTT attach + * @QDF_TX_HTT_MSG: HTT TX message + */ +enum QDF_CREDIT_UPDATE_SOURCE { + QDF_TX_SCHED, + QDF_TX_COMP, + QDF_TX_CREDIT_UPDATE, + QDF_HTT_ATTACH, + QDF_TX_HTT_MSG +}; + +/** + * QDF_CREDIT_OPERATION - operation on credit + * @QDF_CREDIT_INC: credit increment + * @QDF_CREDIT_DEC: credit decrement + * @QDF_CREDIT_ABS: Abosolute credit + * @QDF_OP_NA: Not applicable + */ +enum QDF_CREDIT_OPERATION { + QDF_CREDIT_INC, + QDF_CREDIT_DEC, + QDF_CREDIT_ABS, + QDF_OP_NA +}; + /** * struct qdf_dp_trace_ptr_buf - pointer record buffer * @cookie: cookie value @@ -339,6 +368,24 @@ struct qdf_dp_trace_mgmt_buf { uint8_t subtype; }; +/** + * struct qdf_dp_trace_credit_record - tx credit record + * @source: credit record source + * @operation: credit operation + * @delta: delta of credit + * @total_credits: total credit + * @g0_credit: group 0 credit + * @g1_credit: group 1 credit + */ +struct qdf_dp_trace_credit_record { + enum QDF_CREDIT_UPDATE_SOURCE source; + enum QDF_CREDIT_OPERATION operation; + int delta; + int total_credits; + int g0_credit; + int g1_credit; +}; + /** * struct qdf_dp_trace_event_buf - event buffer * @vdev_id : vdev id @@ -429,7 +476,7 @@ struct s_qdf_dp_trace_data { uint32_t head; uint32_t tail; uint32_t num; - uint8_t proto_bitmap; + uint32_t proto_bitmap; uint8_t no_of_record; uint16_t num_records_to_dump; uint16_t dump_counter; @@ -624,11 +671,11 @@ bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb, void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, uint16_t time_limit, uint8_t verbosity, - uint8_t proto_bitmap); + uint32_t proto_bitmap); void qdf_dp_trace_deinit(void); void qdf_dp_trace_spin_lock_init(void); -void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_records, - uint8_t verbosity); +void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_records, + uint8_t verbosity); void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir); void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id, uint8_t *data, uint8_t size, enum qdf_proto_dir dir); @@ -753,7 +800,7 @@ void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id, enum QDF_DP_TRACE_ID code, uint16_t msdu_id, enum qdf_proto_dir dir); -uint8_t qdf_dp_get_proto_bitmap(void); +uint32_t qdf_dp_get_proto_bitmap(void); uint8_t qdf_dp_get_verbosity(void); uint8_t qdf_dp_get_no_of_record(void); @@ -794,6 +841,20 @@ void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, uint8_t pdev_id, enum qdf_proto_type type, enum qdf_proto_subtype subtype); +/** + * qdf_dp_trace_credit_record() - record credit update + * @source: source of record + * @operation: credit operation + * @delta: credit delta + * @total_credits: total credit + * @g0_credit: group 0 credit + * @g1_credit: group 1 credit + */ +void qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source, + enum QDF_CREDIT_OPERATION operation, + int delta, int total_credits, + int g0_credit, int g1_credit); + /** * qdf_dp_display_mgmt_pkt() - display proto packet * @record: dptrace record @@ -806,6 +867,17 @@ void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, uint16_t index, uint8_t pdev_id, uint8_t info); +/** + * qdf_dp_display_credit_record() - display credit record + * @record: dptrace record + * @index: index + * @pdev_id: pdev id + * @info: metadeta info + */ +void qdf_dp_display_credit_record(struct qdf_dp_trace_record_s *record, + uint16_t index, uint8_t pdev_id, + uint8_t info); + /** * qdf_dp_display_event_record() - display event records * @record: dptrace record @@ -870,7 +942,7 @@ bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb, static inline void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, uint16_t time_limit, uint8_t verbosity, - uint8_t proto_bitmap) + uint32_t proto_bitmap) { } @@ -884,8 +956,8 @@ void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir) { } static inline -void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_records, - uint8_t verbosity) +void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_records, + uint8_t verbosity) { } @@ -1093,9 +1165,40 @@ qdf_tso_seg_dbg_zero(struct qdf_tso_seg_elem_t *tsoseg) #endif /* TSOSEG_DEBUG */ +/** + * qdf_trace_hex_dump() - externally called hex dump function + * @module: Module identifier a member of the QDF_MODULE_ID enumeration that + * identifies the module issuing the trace message. + * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration indicating + * the severity of the condition causing the trace message to be + * issued. More severe conditions are more likely to be logged. + * @data: The base address of the buffer to be logged. + * @buf_len: The size of the buffer to be logged. + * + * Checks the level of severity and accordingly prints the trace messages + * + * Return: None + */ void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, void *data, int buf_len); +/** + * qdf_trace_hex_ascii_dump() - externally called hex and ascii dump function + * @module: Module identifier a member of the QDF_MODULE_ID enumeration that + * identifies the module issuing the trace message. + * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration indicating + * the severity of the condition causing the trace message to be + * issued. More severe conditions are more likely to be logged. + * @data: The base address of the buffer to be logged. + * @buf_len: The size of the buffer to be logged. + * + * Checks the level of severity and accordingly prints the trace messages + * + * Return: None + */ +void qdf_trace_hex_ascii_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + void *data, int buf_len); + #define ERROR_CODE -1 #define QDF_MAX_NAME_SIZE 32 #define MAX_PRINT_CONFIG_SUPPORTED 32 @@ -1406,4 +1509,14 @@ void qdf_minidump_log(void *start_addr, size_t size, const char *name) __qdf_minidump_log(start_addr, size, name); } +/** + * qdf_minidump_remove() - Remove memory address from minidump + * @addr: Start address of the memory previously added + */ +static inline +void qdf_minidump_remove(void *addr) +{ + __qdf_minidump_remove(addr); +} + #endif /* __QDF_TRACE_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h index 5eebbdd1e7ffb58a99eeb9f0901f6fbce8829a8a..87cf7569553f57c77305fc115ffbc3b0d86682ab 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_types.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,12 +25,6 @@ #if !defined(__QDF_TYPES_H) #define __QDF_TYPES_H -#ifndef CONFIG_MCL -#if !defined(__printf) -#define __printf(a, b) -#endif -#endif - #define qdf_must_check __qdf_must_check /* Include Files */ @@ -113,6 +108,15 @@ typedef void *qdf_pm_t; */ typedef void *qdf_handle_t; +/** + * typedef qdf_freq_t - define frequency as a 16 bit/32 bit + * unsigned integer depending on the requirement + */ +#ifdef CONFIG_16_BIT_FREQ_TYPE +typedef uint16_t qdf_freq_t; +#else +typedef uint32_t qdf_freq_t; +#endif /** * typedef qdf_device_t - Platform/bus generic handle. * Used for bus specific functions. @@ -199,7 +203,7 @@ typedef struct qdf_shared_mem { qdf_dma_mem_context(memctx); } qdf_shared_mem_t; -#define qdf_iomem_t __qdf_iomem_t; +#define qdf_iomem_t __qdf_iomem_t /** * typedef enum QDF_TIMER_TYPE - QDF timer type @@ -375,7 +379,13 @@ typedef bool (*qdf_irqlocked_func_t)(void *); * @QDF_MODULE_ID_TX_CAPTURE: Tx capture enhancement feature ID * @QDF_MODULE_ID_INTEROP_ISSUES_AP: interop issues ap module ID * @QDF_MODULE_ID_BLACKLIST_MGR: Blacklist Manager module + * @QDF_MODULE_ID_QLD: QCA Live Debug module ID + * @QDF_MODULE_ID_DYNAMIC_MODE_CHG: Dynamic mode change module ID + * @QDF_MODULE_ID_COEX: Coex related config module ID + * @QDF_MODULE_ID_FTM_TIME_SYNC: FTM Time sync module ID * @QDF_MODULE_ID_PKT_CAPTURE: PACKET CAPTURE module ID + * @QDF_MODULE_ID_MON_FILTER: Monitor filter related config module ID + * @QDF_MODULE_ID_GPIO: GPIO configuration module ID * @QDF_MODULE_ID_ANY: anything * @QDF_MODULE_ID_MAX: Max place holder module ID */ @@ -492,7 +502,13 @@ typedef enum { QDF_MODULE_ID_TX_CAPTURE, QDF_MODULE_ID_INTEROP_ISSUES_AP, QDF_MODULE_ID_BLACKLIST_MGR, + QDF_MODULE_ID_QLD, + QDF_MODULE_ID_DYNAMIC_MODE_CHG, + QDF_MODULE_ID_COEX, + QDF_MODULE_ID_FTM_TIME_SYNC, QDF_MODULE_ID_PKT_CAPTURE, + QDF_MODULE_ID_MON_FILTER, + QDF_MODULE_ID_GPIO = 123, QDF_MODULE_ID_ANY, QDF_MODULE_ID_MAX, } QDF_MODULE_ID; @@ -596,11 +612,14 @@ const char *qdf_opmode_str(const enum QDF_OPMODE opmode); * enum QDF_GLOBAL_MODE - global mode when driver is loaded. * * @QDF_GLOBAL_MISSION_MODE: mission mode (STA, SAP...) + * @QDF_GLOBAL_WALTEST_MODE: WAL Test Mode * @QDF_GLOBAL_MONITOR_MODE: Monitor Mode * @QDF_GLOBAL_FTM_MODE: FTM mode * @QDF_GLOBAL_IBSS_MODE: IBSS mode + * @QDF_GLOBAL_COLDBOOT_CALIB_MODEL: Cold Boot Calibration Mode * @QDF_GLOBAL_EPPING_MODE: EPPING mode * @QDF_GLOBAL_QVIT_MODE: QVIT global mode + * @QDF_GLOBAL_FTM_COLDBOOT_CALIB_MODE: Cold Boot Calibration in FTM Mode * @QDF_GLOBAL_MAX_MODE: Max place holder */ enum QDF_GLOBAL_MODE { @@ -612,44 +631,12 @@ enum QDF_GLOBAL_MODE { QDF_GLOBAL_COLDBOOT_CALIB_MODE = 7, QDF_GLOBAL_EPPING_MODE = 8, QDF_GLOBAL_QVIT_MODE = 9, + QDF_GLOBAL_FTM_COLDBOOT_CALIB_MODE = 10, QDF_GLOBAL_MAX_MODE }; #define QDF_IS_EPPING_ENABLED(mode) (mode == QDF_GLOBAL_EPPING_MODE) -/** - * qdf_trace_msg()- logging API - * @module: Module identifier. A member of the QDF_MODULE_ID enumeration that - * identifies the module issuing the trace message. - * @level: Trace level. A member of the QDF_TRACE_LEVEL enumeration indicating - * the severity of the condition causing the trace message to be issued. - * More severe conditions are more likely to be logged. - * @str_format: Format string. The message to be logged. This format string - * contains printf-like replacement parameters, which follow this - * parameter in the variable argument list. - * - * Users wishing to add tracing information to their code should use - * QDF_TRACE. QDF_TRACE() will compile into a call to qdf_trace_msg() when - * tracing is enabled. - * - * Return: nothing - * - * implemented in qdf_trace.c - */ -void __printf(3, 4) qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, - const char *str_format, ...); -/** - * qdf_vtrace_msg() - the va_list version of qdf_trace_msg - * @module: the calling module's Id - * @level: the logging level to log using - * @str_format: the log format string - * @val: the va_list containing the values to format according to str_format - * - * Return: None - */ -void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, - const char *str_format, va_list val); - #ifdef QDF_TRACE_PRINT_ENABLE #define qdf_print(args...) QDF_TRACE_INFO(QDF_MODULE_ID_ANY, ## args) #define qdf_alert(args...) QDF_TRACE_FATAL(QDF_MODULE_ID_ANY, ## args) @@ -709,7 +696,6 @@ void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, #define qdf_rl_nofl_debug(params...) \ QDF_TRACE_DEBUG_RL_NO_FL(QDF_MODULE_ID_QDF, ## params) -#define qdf_vprint __qdf_vprint #define qdf_snprint __qdf_snprint #define qdf_kstrtoint __qdf_kstrtoint @@ -830,8 +816,43 @@ QDF_STATUS qdf_int64_parse(const char *int_str, int64_t *out_int); QDF_STATUS qdf_uint64_parse(const char *int_str, uint64_t *out_int); #define QDF_MAC_ADDR_SIZE 6 -#define QDF_MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" -#define QDF_MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] + +/** + * If the feature CONFIG_WLAN_TRACE_HIDE_MAC_ADDRESS is enabled, + * then the requirement is to hide 2nd, 3rd and 4th octet of the + * MAC address in the kernel logs and driver logs. + * But other management interfaces like ioctl, debugfs, sysfs, + * wext, unit test code or non-production simulator sw (iot_sim) + * should continue to log the full mac address. + * + * Developers must use QDF_FULL_MAC_FMT instead of "%pM", + * as this macro helps avoid accidentally breaking the feature + * CONFIG_WLAN_TRACE_HIDE_MAC_ADDRESS if enabled and code auditing + * becomes easy. + */ +#define QDF_FULL_MAC_FMT "%pM" +#define QDF_FULL_MAC_REF(a) (a) + +#if defined(WLAN_TRACE_HIDE_MAC_ADDRESS) +#define QDF_MAC_ADDR_FMT "%02x:**:**:**:%02x:%02x" + +/* + * The input data type for QDF_MAC_ADDR_REF can be pointer or an array. + * In case of array, compiler was throwing following warning + * 'address of array will always evaluate as ‘true’ + * and if the pointer is NULL, zero is passed to the format specifier + * which results in zero mac address (00:**:**:**:00:00) + * For this reason, input data type is typecasted to (uintptr_t). + */ +#define QDF_MAC_ADDR_REF(a) \ + (((uintptr_t)NULL != (uintptr_t)(a)) ? (a)[0] : 0), \ + (((uintptr_t)NULL != (uintptr_t)(a)) ? (a)[4] : 0), \ + (((uintptr_t)NULL != (uintptr_t)(a)) ? (a)[5] : 0) +#else +#define QDF_MAC_ADDR_FMT "%pM" +#define QDF_MAC_ADDR_REF(a) (a) +#endif /* WLAN_TRACE_HIDE_MAC_ADDRESS */ + #define QDF_MAC_ADDR_BCAST_INIT { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } #define QDF_MAC_ADDR_ZERO_INIT { { 0, 0, 0, 0, 0, 0 } } @@ -1018,6 +1039,22 @@ struct qdf_ipv6_addr { */ QDF_STATUS qdf_ipv6_parse(const char *ipv6_str, struct qdf_ipv6_addr *out_addr); +/** + * qdf_uint32_array_parse() - parse the given string as uint32 array + * @in_str: the input string to parse + * @out_array: the output uint32 array, populated on success + * @array_size: size of the array + * @out_size: size of the populated array + * + * This API is called to convert string (each value separated by + * a comma) into an uint32 array + * + * Return: QDF_STATUS + */ + +QDF_STATUS qdf_uint32_array_parse(const char *in_str, uint32_t *out_array, + qdf_size_t array_size, qdf_size_t *out_size); + /** * qdf_uint16_array_parse() - parse the given string as uint16 array * @in_str: the input string to parse @@ -1049,8 +1086,6 @@ QDF_STATUS qdf_uint16_array_parse(const char *in_str, uint16_t *out_array, QDF_STATUS qdf_uint8_array_parse(const char *in_str, uint8_t *out_array, qdf_size_t array_size, qdf_size_t *out_size); -#define QDF_MAX_NUM_CHAN (128) - #define QDF_BCAST_MAC_ADDR (0xFF) #define QDF_MCAST_IPV4_MAC_ADDR (0x01) #define QDF_MCAST_IPV6_MAC_ADDR (0x33) @@ -1286,19 +1321,45 @@ enum qdf_suspend_type { * @QDF_SUSPEND_TIMEOUT: Timeout for an ACK from FW for suspend request * @QDF_RESUME_TIMEOUT: Timeout for an ACK from FW for resume request * @QDF_WMI_EXCEED_MAX_PENDING_CMDS: wmi exceed max pending cmd + * @QDF_AP_STA_CONNECT_REQ_TIMEOUT: SAP peer assoc timeout from FW + * @QDF_STA_AP_CONNECT_REQ_TIMEOUT: STA peer assoc timeout from FW + * @QDF_MAC_HW_MODE_CHANGE_TIMEOUT: HW mode change timeout from FW + * @QDF_MAC_HW_MODE_CONFIG_TIMEOUT: HW dual mac cfg timeout from FW + * @QDF_VDEV_START_RESPONSE_TIMED_OUT: Start response timeout from FW + * @QDF_VDEV_RESTART_RESPONSE_TIMED_OUT: Restart response timeout from FW + * @QDF_VDEV_STOP_RESPONSE_TIMED_OUT: Stop response timeout from FW + * @QDF_VDEV_DELETE_RESPONSE_TIMED_OUT: Delete response timeout from FW + * @QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT: Peer delete all resp timeout + * @QDF_WMI_BUF_SEQUENCE_MISMATCH: WMI Tx completion buffer sequence mismatch + * @QDF_HAL_REG_WRITE_FAILURE: HAL register writing failures + * @QDF_SUSPEND_NO_CREDIT: host lack of credit after suspend + * @QCA_HANG_BUS_FAILURE: Bus failure */ enum qdf_hang_reason { - QDF_REASON_UNSPECIFIED = 0, - QDF_RX_HASH_NO_ENTRY_FOUND = 1, - QDF_PEER_DELETION_TIMEDOUT = 2, - QDF_PEER_UNMAP_TIMEDOUT = 3, - QDF_SCAN_REQ_EXPIRED = 4, - QDF_SCAN_ATTEMPT_FAILURES = 5, - QDF_GET_MSG_BUFF_FAILURE = 6, - QDF_ACTIVE_LIST_TIMEOUT = 7, - QDF_SUSPEND_TIMEOUT = 8, - QDF_RESUME_TIMEOUT = 9, - QDF_WMI_EXCEED_MAX_PENDING_CMDS = 10, + QDF_REASON_UNSPECIFIED, + QDF_RX_HASH_NO_ENTRY_FOUND, + QDF_PEER_DELETION_TIMEDOUT, + QDF_PEER_UNMAP_TIMEDOUT, + QDF_SCAN_REQ_EXPIRED, + QDF_SCAN_ATTEMPT_FAILURES, + QDF_GET_MSG_BUFF_FAILURE, + QDF_ACTIVE_LIST_TIMEOUT, + QDF_SUSPEND_TIMEOUT, + QDF_RESUME_TIMEOUT, + QDF_WMI_EXCEED_MAX_PENDING_CMDS, + QDF_AP_STA_CONNECT_REQ_TIMEOUT, + QDF_STA_AP_CONNECT_REQ_TIMEOUT, + QDF_MAC_HW_MODE_CHANGE_TIMEOUT, + QDF_MAC_HW_MODE_CONFIG_TIMEOUT, + QDF_VDEV_START_RESPONSE_TIMED_OUT, + QDF_VDEV_RESTART_RESPONSE_TIMED_OUT, + QDF_VDEV_STOP_RESPONSE_TIMED_OUT, + QDF_VDEV_DELETE_RESPONSE_TIMED_OUT, + QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT, + QDF_WMI_BUF_SEQUENCE_MISMATCH, + QDF_HAL_REG_WRITE_FAILURE, + QDF_SUSPEND_NO_CREDIT, + QCA_HANG_BUS_FAILURE, }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_util.h b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_util.h index d0e4077487bfd2d42060da3b71c9c031f7773226..2710afefcdf6004dff9e5c9878d7fee0460a8734 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_util.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/inc/qdf_util.h @@ -51,6 +51,11 @@ typedef __qdf_wait_queue_head_t qdf_wait_queue_head_t; */ #define qdf_wmb() __qdf_wmb() +/** + * qdf_rmb - read memory barrier. + */ +#define qdf_rmb() __qdf_rmb() + /** * qdf_mb - read + write memory barrier. */ @@ -766,4 +771,17 @@ int qdf_hex_str_to_binary(u8 *dst, const char *src, size_t count) return __qdf_hex_str_to_binary(dst, src, count); } +/** + * qdf_fls() - find last set bit in a given 32 bit input + * @x: 32 bit mask + * + * Return: zero if the input is zero, otherwise returns the bit + * position of the last set bit, where the LSB is 1 and MSB is 32. + */ +static inline +int qdf_fls(uint32_t x) +{ + return __qdf_fls(x); +} + #endif /*_QDF_UTIL_H*/ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_osdep.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_osdep.h index 9b80428defc5cbb4fa92a0eb54b2d67af27d5377..877f43f757f2fa848f11db957d7a83b610611ce1 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_osdep.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_osdep.h @@ -24,11 +24,7 @@ #ifndef _I_OSDEP_H #define _I_OSDEP_H -#ifdef CONFIG_MCL -#include -#else -#include -#endif +#include "queue.h" /* * Byte Order stuff @@ -54,8 +50,8 @@ do { \ if (!spin_is_locked(x)) { \ WARN_ON(1); \ - printk(KERN_EMERG " %s:%d unlock addr=%pK, %s \n", __func__, __LINE__, x, \ - !spin_is_locked(x) ? "Not locked" : ""); \ + qdf_info("unlock addr=%pK, %s", x, \ + !spin_is_locked(x) ? "Not locked" : ""); \ } \ spin_unlock_bh(x); \ } while (0) diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_atomic.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_atomic.h index 1af747d6aa86a728a47d319f961294220d523791..1d2cb2b30a879d72883684e065ff672f30c632ba 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_atomic.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -147,6 +147,17 @@ static inline int32_t __qdf_atomic_dec_return(__qdf_atomic_t *v) return atomic_dec_return(v); } +/** + * __qdf_atomic_inc_not_zero() - increment if not zero + * @v: A pointer to an opaque atomic variable + * + * Return: Returns non-zero on successful increment and zero otherwise + */ +static inline int32_t __qdf_atomic_inc_not_zero(__qdf_atomic_t *v) +{ + return atomic_inc_not_zero(v); +} + /** * __qdf_atomic_set_bit - Atomically set a bit in memory * @nr: bit to set diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hashtable.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hashtable.h index f1806cbf1d763d2bf0ba8b8d6f682649600820bb..f9ad3806e71b257d5853e515d5bddf6eebf4638e 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hashtable.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hashtable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -47,4 +47,7 @@ do { \ break; \ } while (false) +#define __qdf_ht_for_each_safe(table, i, tmp, cursor, entry_field) \ + hash_for_each_safe(table, i, tmp, cursor, entry_field) + #endif /* __I_QDF_HASHTABLE_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hrtimer.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hrtimer.h index d72db5700bb4de5b8abecf8ab178e29d4f5f23d3..00055036f9411949c5f2303c80dbb5e868441dc8 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hrtimer.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_hrtimer.h @@ -34,7 +34,9 @@ typedef struct { union { struct hrtimer hrtimer; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) struct tasklet_hrtimer tasklet_hrtimer; +#endif } u; enum qdf_context_mode ctx; } __qdf_hrtimer_data_t; @@ -63,6 +65,16 @@ enum hrtimer_mode __qdf_hrtimer_get_mode(enum qdf_hrtimer_mode mode) * * Return: void */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline +void __qdf_hrtimer_start(__qdf_hrtimer_data_t *timer, ktime_t interval, + enum qdf_hrtimer_mode mode) +{ + enum hrtimer_mode hrt_mode = __qdf_hrtimer_get_mode(mode); + + hrtimer_start(&timer->u.hrtimer, interval, hrt_mode); +} +#else static inline void __qdf_hrtimer_start(__qdf_hrtimer_data_t *timer, ktime_t interval, enum qdf_hrtimer_mode mode) @@ -75,6 +87,7 @@ void __qdf_hrtimer_start(__qdf_hrtimer_data_t *timer, ktime_t interval, tasklet_hrtimer_start(&timer->u.tasklet_hrtimer, interval, hrt_mode); } +#endif /** * __qdf_hrtimer_cancel() - cancels hrtimer in given context @@ -84,6 +97,16 @@ void __qdf_hrtimer_start(__qdf_hrtimer_data_t *timer, ktime_t interval, * * Return: int */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline +int __qdf_hrtimer_cancel(__qdf_hrtimer_data_t *timer) +{ + if (timer->ctx == QDF_CONTEXT_HARDWARE) + return hrtimer_cancel(&timer->u.hrtimer); + + return 0; +} +#else static inline int __qdf_hrtimer_cancel(__qdf_hrtimer_data_t *timer) { @@ -94,6 +117,7 @@ int __qdf_hrtimer_cancel(__qdf_hrtimer_data_t *timer) return 0; } +#endif /** * __qdf_hrtimer_init() - init hrtimer in a given context @@ -106,6 +130,26 @@ int __qdf_hrtimer_cancel(__qdf_hrtimer_data_t *timer) * * Return: void */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline void __qdf_hrtimer_init(__qdf_hrtimer_data_t *timer, + void *cback, + enum qdf_clock_id clock, + enum qdf_hrtimer_mode mode, + enum qdf_context_mode ctx) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + enum hrtimer_mode hrt_mode = __qdf_hrtimer_get_mode(mode); + + timer->ctx = ctx; + + if (timer->ctx == QDF_CONTEXT_HARDWARE) { + hrtimer_init(hrtimer, clock, hrt_mode); + hrtimer->function = cback; + } else if (timer->ctx == QDF_CONTEXT_TASKLET) { + QDF_BUG(0); + } +} +#else static inline void __qdf_hrtimer_init(__qdf_hrtimer_data_t *timer, void *cback, enum qdf_clock_id clock, @@ -125,6 +169,7 @@ static inline void __qdf_hrtimer_init(__qdf_hrtimer_data_t *timer, tasklet_hrtimer_init(tasklet_hrtimer, cback, clock, hrt_mode); } } +#endif /** * __qdf_hrtimer_kill() - kills hrtimer in given context @@ -134,6 +179,13 @@ static inline void __qdf_hrtimer_init(__qdf_hrtimer_data_t *timer, * * Return: void */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline +void __qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer) +{ + hrtimer_cancel(&timer->u.hrtimer); +} +#else static inline void __qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer) { @@ -142,6 +194,7 @@ void __qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer) else if (timer->ctx == QDF_CONTEXT_TASKLET) tasklet_hrtimer_cancel(&timer->u.tasklet_hrtimer); } +#endif /** * __qdf_hrtimer_get_remaining() - check remaining time in the timer @@ -151,6 +204,14 @@ void __qdf_hrtimer_kill(__qdf_hrtimer_data_t *timer) * * Return: remaining time as ktime object */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline ktime_t __qdf_hrtimer_get_remaining(__qdf_hrtimer_data_t *timer) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_get_remaining(hrtimer); +} +#else static inline ktime_t __qdf_hrtimer_get_remaining(__qdf_hrtimer_data_t *timer) { struct hrtimer *hrtimer = &timer->u.hrtimer; @@ -161,6 +222,7 @@ static inline ktime_t __qdf_hrtimer_get_remaining(__qdf_hrtimer_data_t *timer) else return hrtimer_get_remaining(&tasklet_hrtimer->timer); } +#endif /** * __qdf_hrtimer_is_queued() - check whether the timer is on one of the queues @@ -171,6 +233,14 @@ static inline ktime_t __qdf_hrtimer_get_remaining(__qdf_hrtimer_data_t *timer) * Return: false when the timer was not in queue * true when the timer was in queue */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline bool __qdf_hrtimer_is_queued(__qdf_hrtimer_data_t *timer) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_is_queued(hrtimer); +} +#else static inline bool __qdf_hrtimer_is_queued(__qdf_hrtimer_data_t *timer) { struct hrtimer *hrtimer = &timer->u.hrtimer; @@ -181,6 +251,7 @@ static inline bool __qdf_hrtimer_is_queued(__qdf_hrtimer_data_t *timer) else return hrtimer_is_queued(&tasklet_hrtimer->timer); } +#endif /** * __qdf_hrtimer_callback_running() - check if callback is running @@ -191,6 +262,14 @@ static inline bool __qdf_hrtimer_is_queued(__qdf_hrtimer_data_t *timer) * Return: false when callback is not running * true when callback is running */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline bool __qdf_hrtimer_callback_running(__qdf_hrtimer_data_t *timer) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_callback_running(hrtimer); +} +#else static inline bool __qdf_hrtimer_callback_running(__qdf_hrtimer_data_t *timer) { struct hrtimer *hrtimer = &timer->u.hrtimer; @@ -201,6 +280,7 @@ static inline bool __qdf_hrtimer_callback_running(__qdf_hrtimer_data_t *timer) else return hrtimer_callback_running(&tasklet_hrtimer->timer); } +#endif /** * __qdf_hrtimer_active() - check if timer is active @@ -212,6 +292,14 @@ static inline bool __qdf_hrtimer_callback_running(__qdf_hrtimer_data_t *timer) * Return: false if timer is not active * true if timer is active */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline bool __qdf_hrtimer_active(__qdf_hrtimer_data_t *timer) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_active(hrtimer); +} +#else static inline bool __qdf_hrtimer_active(__qdf_hrtimer_data_t *timer) { struct hrtimer *hrtimer = &timer->u.hrtimer; @@ -222,6 +310,7 @@ static inline bool __qdf_hrtimer_active(__qdf_hrtimer_data_t *timer) else return hrtimer_active(&tasklet_hrtimer->timer); } +#endif /** * __qdf_hrtimer_cb_get_time() - get remaining time in callback @@ -231,6 +320,14 @@ static inline bool __qdf_hrtimer_active(__qdf_hrtimer_data_t *timer) * * Return: time remaining as ktime object */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline ktime_t __qdf_hrtimer_cb_get_time(__qdf_hrtimer_data_t *timer) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_cb_get_time(hrtimer); +} +#else static inline ktime_t __qdf_hrtimer_cb_get_time(__qdf_hrtimer_data_t *timer) { struct hrtimer *hrtimer = &timer->u.hrtimer; @@ -241,6 +338,7 @@ static inline ktime_t __qdf_hrtimer_cb_get_time(__qdf_hrtimer_data_t *timer) else return hrtimer_cb_get_time(&tasklet_hrtimer->timer); } +#endif /** * __qdf_hrtimer_forward() - forward the hrtimer @@ -252,6 +350,16 @@ static inline ktime_t __qdf_hrtimer_cb_get_time(__qdf_hrtimer_data_t *timer) * * Return:the number of overruns */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline uint64_t __qdf_hrtimer_forward(__qdf_hrtimer_data_t *timer, + ktime_t now, + ktime_t interval) +{ + struct hrtimer *hrtimer = &timer->u.hrtimer; + + return hrtimer_forward(hrtimer, now, interval); +} +#else static inline uint64_t __qdf_hrtimer_forward(__qdf_hrtimer_data_t *timer, ktime_t now, ktime_t interval) @@ -264,5 +372,6 @@ static inline uint64_t __qdf_hrtimer_forward(__qdf_hrtimer_data_t *timer, else return hrtimer_forward(&tasklet_hrtimer->timer, now, interval); } +#endif #endif /* _I_QDF_HRTIMER_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_ipa.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_ipa.h index 0b3628896f6bbd0303d359bd4bd0f42b608312f4..273f5a3748ccfe92a874a80a2a06372b87601820 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_ipa.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,6 +20,7 @@ #ifdef IPA_OFFLOAD #include +#include /** * __qdf_ipa_wdi_meter_evt_type_t - type of event client callback is @@ -378,10 +379,40 @@ typedef struct ipa_wdi_buffer_info __qdf_ipa_wdi_buffer_info_t; typedef struct ipa_gsi_ep_config __qdf_ipa_gsi_ep_config_t; #ifdef WDI3_STATS_UPDATE +/** + * __qdf_ipa_wdi_tx_info_t - WLAN embedded TX information + */ typedef struct ipa_wdi_tx_info __qdf_ipa_wdi_tx_info_t; + +#define QDF_IPA_WDI_TX_INFO_STA_TX_BYTES(stats_info) \ + (((struct ipa_wdi_tx_info *)stats_info)->sta_tx) +#define QDF_IPA_WDI_TX_INFO_SAP_TX_BYTES(stats_info) \ + (((struct ipa_wdi_tx_info *)stats_info)->ap_tx) +/** + * __qdf_ipa_wdi_bw_info_t - BW levels to be monitored by uC + */ typedef struct ipa_wdi_bw_info __qdf_ipa_wdi_bw_info_t; + +#define QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_1(bw_info) \ + (((struct ipa_wdi_bw_info *)bw_info)->threshold[0]) +#define QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_2(bw_info) \ + (((struct ipa_wdi_bw_info *)bw_info)->threshold[1]) +#define QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_3(bw_info) \ + (((struct ipa_wdi_bw_info *)bw_info)->threshold[2]) +#define QDF_IPA_WDI_BW_INFO_START_STOP(bw_info) \ + (((struct ipa_wdi_bw_info *)bw_info)->stop) + +/** + * __qdf_ipa_inform_wlan_bw_t - BW information given by IPA driver + */ typedef struct ipa_inform_wlan_bw __qdf_ipa_inform_wlan_bw_t; -#endif + +#define QDF_IPA_INFORM_WLAN_BW_INDEX(bw_inform) \ + (((struct ipa_inform_wlan_bw*)bw_inform)->index) +#define QDF_IPA_INFORM_WLAN_BW_THROUGHPUT(bw_inform) \ + (((struct ipa_inform_wlan_bw*)bw_inform)->throughput) + +#endif /* WDI3_STATS_UPDATE */ /** * __qdf_ipa_dp_evt_type_t - type of event client callback is @@ -524,6 +555,10 @@ typedef struct ipa_wlan_hdr_attrib_val __qdf_ipa_wlan_hdr_attrib_val_t; #define __QDF_IPA_CLIENT_WLAN3_CONS IPA_CLIENT_WLAN3_CONS #define __QDF_IPA_CLIENT_WLAN4_CONS IPA_CLIENT_WLAN4_CONS +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#define IPA_LAN_RX_NAPI_SUPPORT +#endif + /* * Resume / Suspend */ @@ -937,5 +972,16 @@ static bool __qdf_get_ipa_smmu_enabled(void) } #endif +#ifdef IPA_LAN_RX_NAPI_SUPPORT +/** + * ipa_get_lan_rx_napi() - Check if NAPI is enabled in LAN RX DP + * + * Returns: true if enabled, false otherwise + */ +static inline bool __qdf_ipa_get_lan_rx_napi(void) +{ + return ipa_get_lan_rx_napi(); +} +#endif /* IPA_LAN_RX_NAPI_SUPPORT */ #endif /* IPA_OFFLOAD */ #endif /* _I_QDF_IPA_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_mem.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_mem.h index 95590d986c3df638d8fe271ba8d512c8db8c95cb..cdb5b3e8f870723adfd4ced1cc6390f6d1ad85d8 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_mem.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_mem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -39,11 +39,8 @@ #include /* L1_CACHE_BYTES */ #define __qdf_cache_line_sz L1_CACHE_BYTES -#if defined(CONFIG_MCL) -#include -#else -#include -#endif +#include "queue.h" + #else /* * Provide dummy defs for kernel data types, functions, and enums @@ -63,7 +60,9 @@ #if IS_ENABLED(CONFIG_ARM_SMMU) #include +#ifdef ENABLE_SMMU_S1_TRANSLATION #include +#endif #include #endif @@ -99,8 +98,19 @@ typedef struct __qdf_mempool_ctxt { #endif /* __KERNEL__ */ +#define __page_size ((size_t)PAGE_SIZE) #define __qdf_align(a, mask) ALIGN(a, mask) +#ifdef DISABLE_MEMDEBUG_PANIC +#define QDF_MEMDEBUG_PANIC(reason_fmt, args...) \ + do { \ + /* no-op */ \ + } while (false) +#else +#define QDF_MEMDEBUG_PANIC(reason_fmt, args...) \ + QDF_DEBUG_PANIC(reason_fmt, ## args) +#endif + /* typedef for dma_data_direction */ typedef enum dma_data_direction __dma_data_direction; @@ -210,7 +220,7 @@ static inline bool __qdf_mem_smmu_s1_enabled(qdf_device_t osdev) return osdev->smmu_s1_enabled; } -#if IS_ENABLED(CONFIG_ARM_SMMU) +#if IS_ENABLED(CONFIG_ARM_SMMU) && defined(ENABLE_SMMU_S1_TRANSLATION) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) /** * __qdf_dev_get_domain() - get iommu domain from osdev @@ -441,4 +451,61 @@ __qdf_mem_set_dma_pa(qdf_device_t osdev, { mem_info->pa = dma_pa; } + +/** + * __qdf_mem_alloc_consistent() - allocates consistent qdf memory + * @osdev: OS device handle + * @dev: Pointer to device handle + * @size: Size to be allocated + * @paddr: Physical address + * @func: Function name of the call site + * @line: line numbe rof the call site + * + * Return: pointer of allocated memory or null if memory alloc fails + */ +void *__qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, + qdf_size_t size, qdf_dma_addr_t *paddr, + const char *func, uint32_t line); + +/** + * __qdf_mem_malloc() - allocates QDF memory + * @size: Number of bytes of memory to allocate. + * + * @func: Function name of the call site + * @line: line numbe rof the call site + * + * This function will dynamicallly allocate the specified number of bytes of + * memory. + * + * Return: + * Upon successful allocate, returns a non-NULL pointer to the allocated + * memory. If this function is unable to allocate the amount of memory + * specified (for any reason) it returns NULL. + */ +void *__qdf_mem_malloc(qdf_size_t size, const char *func, uint32_t line); + +/** + * __qdf_mem_free() - free QDF memory + * @ptr: Pointer to the starting address of the memory to be freed. + * + * This function will free the memory pointed to by 'ptr'. + * Return: None + */ +void __qdf_mem_free(void *ptr); + +/** + * __qdf_mem_free_consistent() - free consistent qdf memory + * @osdev: OS device handle + * @dev: Pointer to device handle + * @size: Size to be allocated + * @vaddr: virtual address + * @paddr: Physical address + * @memctx: Pointer to DMA context + * + * Return: none + */ +void __qdf_mem_free_consistent(qdf_device_t osdev, void *dev, + qdf_size_t size, void *vaddr, + qdf_dma_addr_t paddr, qdf_dma_context_t memctx); + #endif /* __I_QDF_MEM_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf.h index d1a81b932f1a45ad9d09adeab0d0b22390f5022f..5d6dc425abb43756abc0dab2746fae215244978d 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -101,29 +101,31 @@ typedef union { * @rx.dev.priv_cb_w.fctx: ctx to handle special pkts defined by ftype * @rx.dev.priv_cb_w.msdu_len: length of RX packet * @rx.dev.priv_cb_w.peer_id: peer_id for RX packet - * @rx.dev.priv_cb_w.protocol_tag: protocol tag set by application for - * received packet type - * @rx.dev.priv_cb_w.reserved1: reserved for flow tag set by application - * for 5 tuples received - * + * @rx.dev.priv_cb_w.protocol_tag: protocol tag set by app for rcvd packet type + * @rx.dev.priv_cb_w.flow_tag: flow tag set by application for 5 tuples rcvd + * + * @rx.dev.priv_cb_m.peer_cached_buf_frm: peer cached buffer + * @rx.dev.priv_cb_m.flush_ind: flush indication + * @rx.dev.priv_cb_m.packet_buf_pool: packet buff bool + * @rx.dev.priv_cb_m.l3_hdr_pad: L3 header padding offset + * @rx.dev.priv_cb_m.exc_frm: exception frame + * @rx.dev.priv_cb_m.reo_dest_ind: reo destination indication + * @rx.dev.priv_cb_m.ipa_smmu_map: do IPA smmu map * @rx.dev.priv_cb_m.tcp_seq_num: TCP sequence number * @rx.dev.priv_cb_m.tcp_ack_num: TCP ACK number * @rx.dev.priv_cb_m.lro_ctx: LRO context * @rx.dev.priv_cb_m.dp.wifi3.msdu_len: length of RX packet * @rx.dev.priv_cb_m.dp.wifi3.peer_id: peer_id for RX packet * @rx.dev.priv_cb_m.dp.wifi2.map_index: - * @rx.dev.priv_cb_m.vdev_id: vdev_id for RX pkt * @rx.dev.priv_cb_m.ipa_owned: packet owned by IPA * * @rx.lro_eligible: flag to indicate whether the MSDU is LRO eligible - * @rx.peer_cached_buf_frm: peer cached buffer * @rx.tcp_proto: L4 protocol is TCP * @rx.tcp_pure_ack: A TCP ACK packet with no payload * @rx.ipv6_proto: L3 protocol is IPV6 * @rx.ip_offset: offset to IP header * @rx.tcp_offset: offset to TCP header * @rx_ctx_id: Rx context id - * @flush_ind: flush indication * @num_elements_in_list: number of elements in the nbuf list * * @rx.tcp_udp_chksum: L4 payload checksum @@ -134,7 +136,7 @@ typedef union { * @rx.flag_chfrag_start: first MSDU in an AMSDU * @rx.flag_chfrag_cont: middle or part of MSDU in an AMSDU * @rx.flag_chfrag_end: last MSDU in an AMSDU - * @rx.packet_buff_pool: indicate packet from pre-allocated pool for Rx ring + * @rx.flag_retry: flag to indicate MSDU is retried * @rx.flag_da_mcbc: flag to indicate mulicast or broadcast packets * @rx.flag_da_valid: flag to indicate DA is valid for RX packet * @rx.flag_sa_valid: flag to indicate SA is valid for RX packet @@ -148,12 +150,12 @@ typedef union { * @rx.trace.packet_track: RX_DATA packet * @rx.trace.rsrvd: enable packet logging * - * @rx.ftype: mcast2ucast, TSO, SG, MESH + * @rx.vdev_id: vdev_id for RX pkt * @rx.is_raw_frame: RAW frame * @rx.fcs_err: FCS error * @rx.tid_val: tid value - * @rx.flag_retry: flag to indicate MSDU is retried * @rx.reserved: reserved + * @rx.ftype: mcast2ucast, TSO, SG, MESH * * @tx.dev.priv_cb_w.fctx: ctx to handle special pkts defined by ftype * @tx.dev.priv_cb_w.ext_cb_ptr: extended cb pointer @@ -213,7 +215,7 @@ struct qdf_nbuf_cb { uint16_t msdu_len; uint16_t peer_id; uint16_t protocol_tag; - uint16_t reserved1; + uint16_t flow_tag; } priv_cb_w; struct { /* ipa_owned bit is common between rx @@ -221,9 +223,16 @@ struct qdf_nbuf_cb { * Do not change location of this bit. */ uint32_t ipa_owned:1, - reserved:15, - vdev_id:8, - reserved1:8; + peer_cached_buf_frm:1, + flush_ind:1, + packet_buf_pool:1, + reserved:4, + l3_hdr_pad:8, + /* exception frame flag */ + exc_frm:1, + reo_dest_ind:5, + ipa_smmu_map:1, + reserved1:9; uint32_t tcp_seq_num; uint32_t tcp_ack_num; union { @@ -239,14 +248,14 @@ struct qdf_nbuf_cb { } priv_cb_m; } dev; uint32_t lro_eligible:1, - peer_cached_buf_frm:1, tcp_proto:1, tcp_pure_ack:1, ipv6_proto:1, ip_offset:7, tcp_offset:7, rx_ctx_id:4, - flush_ind:1, + fcs_err:1, + is_raw_frame:1, num_elements_in_list:8; uint32_t tcp_udp_chksum:16, tcp_win:16; @@ -254,7 +263,7 @@ struct qdf_nbuf_cb { uint8_t flag_chfrag_start:1, flag_chfrag_cont:1, flag_chfrag_end:1, - packet_buff_pool:1, + flag_retry:1, flag_da_mcbc:1, flag_da_valid:1, flag_sa_valid:1, @@ -265,12 +274,9 @@ struct qdf_nbuf_cb { packet_track:4, rsrvd:3; } trace; - uint8_t ftype; - uint8_t is_raw_frame:1, - fcs_err:1, - tid_val:4, - flag_retry:1, - reserved:1; + uint16_t vdev_id:8, + tid_val:4, + ftype:4; } rx; /* Note: MAX: 40 bytes */ @@ -349,8 +355,6 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size, #define QDF_NBUF_CB_RX_LRO_ELIGIBLE(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.lro_eligible) -#define QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb) \ - (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.peer_cached_buf_frm) #define QDF_NBUF_CB_RX_TCP_PROTO(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_proto) #define QDF_NBUF_CB_RX_TCP_PURE_ACK(skb) \ @@ -363,8 +367,6 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size, (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_offset) #define QDF_NBUF_CB_RX_CTX_ID(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.rx_ctx_id) -#define QDF_NBUF_CB_RX_FLUSH_IND(skb) \ - (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.flush_ind) #define QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.num_elements_in_list) @@ -384,6 +386,9 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size, #define QDF_NBUF_CB_RX_FTYPE(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.ftype) +#define QDF_NBUF_CB_RX_VDEV_ID(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.vdev_id) + #define QDF_NBUF_CB_RX_CHFRAG_START(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.rx.flag_chfrag_start) @@ -393,9 +398,6 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size, #define QDF_NBUF_CB_RX_CHFRAG_END(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.rx.flag_chfrag_end) -#define QDF_NBUF_CB_RX_PACKET_BUFF_POOL(skb) \ - (((struct qdf_nbuf_cb *) \ - ((skb)->cb))->u.rx.packet_buff_pool) #define QDF_NBUF_CB_RX_DA_MCBC(skb) \ (((struct qdf_nbuf_cb *) \ @@ -1474,9 +1476,23 @@ void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev, bool is_last_seg); #ifdef FEATURE_TSO +/** + * __qdf_nbuf_get_tcp_payload_len() - function to return the tcp + * payload len + * @skb: buffer + * + * Return: size + */ +size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb); uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb); #else +static inline +size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb) +{ + return 0; +} + static inline uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) { return 0; @@ -1903,6 +1919,21 @@ __qdf_nbuf_expand(struct sk_buff *skb, uint32_t headroom, uint32_t tailroom) return NULL; } +/** + * __qdf_nbuf_copy_expand() - copy and expand nbuf + * @buf: Network buf instance + * @headroom: Additional headroom to be added + * @tailroom: Additional tailroom to be added + * + * Return: New nbuf that is a copy of buf, with additional head and tailroom + * or NULL if there is no memory + */ +static inline struct sk_buff * +__qdf_nbuf_copy_expand(struct sk_buff *buf, int headroom, int tailroom) +{ + return skb_copy_expand(buf, headroom, tailroom, GFP_ATOMIC); +} + /** * __qdf_nbuf_tx_cksum_info() - tx checksum info * @@ -2235,7 +2266,7 @@ void __qdf_nbuf_queue_head_unlock(struct sk_buff_head *skb_queue_head) spin_unlock_bh(&skb_queue_head->lock); } -#ifdef CONFIG_WIN +#ifdef CONFIG_NBUF_AP_PLATFORM #include #else #include diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_m.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_m.h index 296494c8aca95108fddc24a8df88573b1a979c15..69f594883c380d98deb3695f90c760aaf9167e48 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_m.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_m.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,9 +34,6 @@ #define QDF_NBUF_CB_RX_LRO_CTX(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m.lro_ctx) -#define QDF_NBUF_CB_RX_VDEV_ID(skb) \ - (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m.vdev_id) - #define QDF_NBUF_CB_TX_IPA_OWNED(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.priv_cb_m.ipa.owned) #define QDF_NBUF_CB_TX_IPA_PRIV(skb) \ @@ -61,6 +58,33 @@ (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m.dp. \ wifi2.map_index) +#define QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + peer_cached_buf_frm) + +#define QDF_NBUF_CB_RX_FLUSH_IND(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m.flush_ind) + +#define QDF_NBUF_CB_RX_PACKET_BUFF_POOL(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + packet_buf_pool) + +#define QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + l3_hdr_pad) + +#define QDF_NBUF_CB_RX_PACKET_EXC_FRAME(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + exc_frm) + +#define QDF_NBUF_CB_RX_PACKET_REO_DEST_IND(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + reo_dest_ind) + +#define QDF_NBUF_CB_RX_PACKET_IPA_SMMU_MAP(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.rx.dev.priv_cb_m. \ + ipa_smmu_map) + #define __qdf_nbuf_ipa_owned_get(skb) \ QDF_NBUF_CB_TX_IPA_OWNED(skb) diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_w.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_w.h index 893c86d2908f0e1650ca7525ad2fab176ea1413f..4657186c71584fd38c009931db63df97d23fe97e 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_w.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_nbuf_w.h @@ -82,6 +82,16 @@ #define __qdf_nbuf_get_rx_protocol_tag(skb) \ (QDF_NBUF_CB_RX_PROTOCOL_TAG((skb))) +#define QDF_NBUF_CB_RX_FLOW_TAG(skb) \ + (((struct qdf_nbuf_cb *) \ + ((skb)->cb))->u.rx.dev.priv_cb_w.flow_tag) + +#define __qdf_nbuf_set_rx_flow_tag(skb, val) \ + ((QDF_NBUF_CB_RX_FLOW_TAG((skb))) = val) + +#define __qdf_nbuf_get_rx_flow_tag(skb) \ + (QDF_NBUF_CB_RX_FLOW_TAG((skb))) + /** * qdf_nbuf_cb_update_vdev_id() - update vdev id in skb cb * @skb: skb pointer whose cb is updated with vdev id information diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_notifier.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..331bfffb485e9ab8413fab9d0cecacd3439cd3ce --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_notifier.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + + /** + * DOC: i_qdf_notifier.h + * + * Linux-specific definitions for use by QDF notifier APIs + */ + +#ifndef __I_QDF_NOTIFIER_H +#define __I_QDF_NOTIFIER_H + +#include + +typedef struct blocking_notifier_head __qdf_blocking_notif_head; +typedef struct atomic_notifier_head __qdf_atomic_notif_head; +typedef struct notifier_block __qdf_notifier_block; +#define qdf_blocking_notifier_init(p) BLOCKING_NOTIFIER_HEAD(p); +#define qdf_atomic_notifier_init(p) ATOMIC_NOTIFIER_HEAD(p); + +static inline int +__qdf_register_blocking_notifier_chain(__qdf_blocking_notif_head *head, + __qdf_notifier_block *qnb) +{ + return blocking_notifier_chain_register(head, qnb); +} + +static inline int +__qdf_unregister_blocking_notifier_chain(__qdf_blocking_notif_head *head, + __qdf_notifier_block *qnb) +{ + return blocking_notifier_chain_unregister(head, qnb); +} + +static inline int +__qdf_blocking_notfier_call(__qdf_blocking_notif_head *head, + unsigned long v, void *data) +{ + return blocking_notifier_call_chain(head, v, data); +} + +static inline int +__qdf_register_atomic_notifier_chain(__qdf_atomic_notif_head *head, + __qdf_notifier_block *qnb) +{ + return atomic_notifier_chain_register(head, qnb); +} + +static inline int +__qdf_unregister_atomic_notifier_chain(__qdf_atomic_notif_head *head, + __qdf_notifier_block *qnb) +{ + return atomic_notifier_chain_unregister(head, qnb); +} + +static inline int +__qdf_atomic_notifier_call(__qdf_atomic_notif_head *head, + unsigned long v, void *data) +{ + return atomic_notifier_call_chain(head, v, data); +} + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_str.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_str.h index 0f54196c36e5261244fbfa8b66f3edbbd1b30a87..53378e12ba0028e1053fb7f40bfc44fd25ae7527 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_str.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_str.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,5 +33,6 @@ #define __qdf_str_len(str) strlen(str) #define __qdf_str_trim(str) strim(str) #define __qdf_str_nlen(str, limit) strnlen(str, limit) +#define __qdf_str_ncmp(left, right, limit) strncmp(left, right, limit) #endif /* __I_QDF_STR_H */ diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_queue.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_streamfs.h similarity index 67% rename from drivers/staging/qcacld-3.0/core/cds/inc/cds_queue.h rename to drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_streamfs.h index 0487edb355da56503cc00ce12d5702dfc9feb5f4..d4b6e2edc1389ff922f245ca183e5559e7a10c34 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_queue.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_streamfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -16,9 +16,17 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _CDS_QUEUE_H -#define _CDS_QUEUE_H +/** + * DOC: i_qdf_streamfs.h + * Linux specific implementation for stream filesystem APIs. + */ + +#ifndef _I_QDF_STREAMFS_H +#define _I_QDF_STREAMFS_H + +#include -#include /* include BSD queue */ +typedef struct rchan *__qdf_streamfs_chan_t; +typedef struct rchan_buf *__qdf_streamfs_chan_buf_t; -#endif /* end of _CDS_QUEUE_H */ +#endif /* _I_QDF_STREAMFS_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_talloc.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_talloc.h index 7965d93ee22ee89d9d97eee4bcbce7c3099ae4bc..3bc402dcbd43092eba1c7f418cf6da6ae2a08223 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_talloc.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_talloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,16 +33,14 @@ #define __can_sleep() \ (!in_interrupt() && !irqs_disabled() && !in_atomic()) -#define __zalloc_sleeps(size) kmalloc(size, GFP_KERNEL) -#define __zalloc_atomic(size) kmalloc(size, GFP_ATOMIC) +#define __zalloc_sleeps(size) kzalloc(size, GFP_KERNEL) +#define __zalloc_atomic(size) kzalloc(size, GFP_ATOMIC) #define __zalloc_auto(size) \ - kmalloc(size, __can_sleep() ? GFP_KERNEL : GFP_ATOMIC) + kzalloc(size, __can_sleep() ? GFP_KERNEL : GFP_ATOMIC) #define __free(ptr) kfree(ptr) #define __alloc_size(ptr) ksize(ptr) -#define __page_size ((size_t)PAGE_SIZE) - #endif /* __I_QDF_TALLOC_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h index 539df213ba8973b8f66a06fd402c93efa031783f..30d98860a755c6874a6737bd0406209c5a313b60 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_time.h @@ -249,11 +249,7 @@ static inline bool __qdf_system_time_after_eq(__qdf_time_t a, __qdf_time_t b) */ static inline uint64_t __qdf_get_monotonic_boottime(void) { - struct timespec ts; - - get_monotonic_boottime(&ts); - - return ((uint64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); + return (uint64_t)ktime_to_us(ktime_get_boottime()); } #if defined (MSM_PLATFORM) @@ -266,7 +262,12 @@ static inline uint64_t __qdf_get_monotonic_boottime(void) * * Return: QTIMER(19.2 MHz) clock ticks */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +static inline uint64_t __qdf_get_log_timestamp(void) +{ + return __arch_counter_get_cntvct(); +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) static inline uint64_t __qdf_get_log_timestamp(void) { return arch_counter_get_cntvct(); @@ -305,7 +306,13 @@ static inline uint64_t __qdf_get_log_timestamp(void) * The time since system booted in nanoseconds */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) +static inline uint64_t __qdf_get_bootbased_boottime_ns(void) +{ + return ktime_get_boottime_ns(); +} + +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) static inline uint64_t __qdf_get_bootbased_boottime_ns(void) { return ktime_get_boot_ns(); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h index 3223905e10b240f3c19e953c5251f30c7b31132b..ea0b7fda1fbf1605c67538a5f8b4f929c3892e88 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -121,7 +121,8 @@ #define __QDF_TRACE_HEX_DUMP_RL(log_level, module_id, args...) \ __QDF_TRACE_HEX_DUMP_RATE_LIMITED(module_id, log_level, ## args) -static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { } +static inline void __qdf_trace_noop(QDF_MODULE_ID module, + const char *format, ...) { } static inline void __qdf_trace_dummy(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, const char *format, ...) { } @@ -132,6 +133,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, void *data, int buf_len) { } + #ifdef WLAN_LOG_FATAL #define QDF_TRACE_FATAL(params...) \ __QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params) @@ -141,6 +143,8 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, __QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params) #define QDF_TRACE_FATAL_RL_NO_FL(params...) \ __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params) +#define QDF_VTRACE_FATAL(module_id, fmt, args) \ + QDF_VTRACE(module_id, QDF_TRACE_LEVEL_FATAL, fmt, args) #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) \ __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_FATAL, ## params) #else @@ -148,6 +152,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params) #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params) #define QDF_TRACE_FATAL_RL_NO_FL(params...) __qdf_trace_noop(params) +#define QDF_VTRACE_FATAL(params...) __qdf_trace_noop(params) #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) __qdf_trace_noop(params) #endif @@ -160,6 +165,8 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, __QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params) #define QDF_TRACE_ERROR_RL_NO_FL(params...) \ __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params) +#define QDF_VTRACE_ERROR(module_id, fmt, args) \ + QDF_VTRACE(module_id, QDF_TRACE_LEVEL_ERROR, fmt, args) #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) \ __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_ERROR, ## params) #else @@ -167,6 +174,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params) #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params) #define QDF_TRACE_ERROR_RL_NO_FL(params...) __qdf_trace_noop(params) +#define QDF_VTRACE_ERROR(params...) __qdf_trace_noop(params) #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) __qdf_trace_noop(params) #endif @@ -179,6 +187,8 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, __QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params) #define QDF_TRACE_WARN_RL_NO_FL(params...) \ __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_WARN, ## params) +#define QDF_VTRACE_WARN(module_id, fmt, args) \ + QDF_VTRACE(module_id, QDF_TRACE_LEVEL_WARN, fmt, args) #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) \ __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_WARN, ## params) #else @@ -186,6 +196,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params) #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params) #define QDF_TRACE_WARN_RL_NO_FL(params...) __qdf_trace_noop(params) +#define QDF_VTRACE_WARN(params...) __qdf_trace_noop(params) #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) __qdf_trace_noop(params) #endif @@ -198,6 +209,8 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, __QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params) #define QDF_TRACE_INFO_RL_NO_FL(params...) \ __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_INFO, ## params) +#define QDF_VTRACE_INFO(module_id, fmt, args) \ + QDF_VTRACE(module_id, QDF_TRACE_LEVEL_INFO, fmt, args) #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) \ __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_INFO, ## params) #else @@ -205,6 +218,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params) #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params) #define QDF_TRACE_INFO_RL_NO_FL(params...) __qdf_trace_noop(params) +#define QDF_VTRACE_INFO(params...) __qdf_trace_noop(params) #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) __qdf_trace_noop(params) #endif @@ -217,6 +231,8 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, __QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params) #define QDF_TRACE_DEBUG_RL_NO_FL(params...) \ __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params) +#define QDF_VTRACE_DEBUG(module_id, fmt, args) \ + QDF_VTRACE(module_id, QDF_TRACE_LEVEL_DEBUG, fmt, args) #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) \ __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_DEBUG, ## params) #else @@ -224,6 +240,7 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params) #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params) #define QDF_TRACE_DEBUG_RL_NO_FL(params...) __qdf_trace_noop(params) +#define QDF_VTRACE_DEBUG(params...) __qdf_trace_noop(params) #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) __qdf_trace_noop(params) #endif @@ -263,6 +280,39 @@ static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, } \ } while (0) #endif /* WLAN_WARN_ON_ASSERT */ +/** + * qdf_trace_msg()- logging API + * @module: Module identifier. A member of the QDF_MODULE_ID enumeration that + * identifies the module issuing the trace message. + * @level: Trace level. A member of the QDF_TRACE_LEVEL enumeration indicating + * the severity of the condition causing the trace message to be issued. + * More severe conditions are more likely to be logged. + * @str_format: Format string. The message to be logged. This format string + * contains printf-like replacement parameters, which follow this + * parameter in the variable argument list. + * + * Users wishing to add tracing information to their code should use + * QDF_TRACE. QDF_TRACE() will compile into a call to qdf_trace_msg() when + * tracing is enabled. + * + * Return: nothing + * + * implemented in qdf_trace.c + */ +void __printf(3, 4) qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + const char *str_format, ...); + +/** + * qdf_vtrace_msg() - the va_list version of qdf_trace_msg + * @module: the calling module's Id + * @level: the logging level to log using + * @str_format: the log format string + * @val: the va_list containing the values to format according to str_format + * + * Return: None + */ +void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + const char *str_format, va_list val); #else @@ -277,6 +327,18 @@ static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, #endif +#ifdef QDF_TRACE_PRINT_ENABLE +static inline void qdf_vprint(const char *fmt, va_list args) +{ + QDF_VTRACE_INFO(QDF_MODULE_ID_ANY, fmt, args); +} +#else /* QDF_TRACE_PRINT_ENABLE */ +static inline void qdf_vprint(const char *fmt, va_list args) +{ + QDF_VTRACE_ERROR(QDF_MODULE_ID_QDF, fmt, args); +} +#endif + #ifdef PANIC_ON_BUG #ifdef CONFIG_SLUB_DEBUG /** @@ -389,8 +451,16 @@ __qdf_minidump_log(void *start_addr, size_t size, const char *name) "%s: failed to log %pK (%s)\n", __func__, start_addr, name); } + +static inline void +__qdf_minidump_remove(void *addr) +{ + remove_minidump_segments((uintptr_t)addr); +} #else static inline void __qdf_minidump_log(void *start_addr, size_t size, const char *name) {} +static inline void +__qdf_minidump_remove(void *addr) {} #endif #endif /* __I_QDF_TRACE_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h index 2c68abfa335cd655e6302303ca1099e5a1a9ae66..b43f6c0ccb42dc1dd91240d9343a5106763df0ed 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -98,11 +98,26 @@ typedef unsigned long dma_addr_t; typedef unsigned long phys_addr_t; typedef unsigned long __sgtable_t; +#ifndef SIOCGIWAP #define SIOCGIWAP 0 +#endif + +#ifndef IWEVCUSTOM #define IWEVCUSTOM 0 +#endif + +#ifndef IWEVREGISTERED #define IWEVREGISTERED 0 +#endif + +#ifndef IWEVEXPIRED #define IWEVEXPIRED 0 +#endif + +#ifndef SIOCGIWSCAN #define SIOCGIWSCAN 0 +#endif + #define DMA_TO_DEVICE 0 #define DMA_BIDIRECTIONAL 0 #define DMA_FROM_DEVICE 0 @@ -209,6 +224,7 @@ struct __qdf_mempool_ctxt; * @QDF_BUS_TYPE_SNOC: SNOC Bus * @QDF_BUS_TYPE_SIM: Simulator * @QDF_BUS_TYPE_USB: USB Bus + * @QDF_BUS_TYPE_IPCI: IPCI Bus */ enum qdf_bus_type { QDF_BUS_TYPE_NONE = -1, @@ -217,7 +233,8 @@ enum qdf_bus_type { QDF_BUS_TYPE_SNOC, QDF_BUS_TYPE_SIM, QDF_BUS_TYPE_SDIO, - QDF_BUS_TYPE_USB + QDF_BUS_TYPE_USB, + QDF_BUS_TYPE_IPCI }; /** @@ -250,14 +267,16 @@ struct __qdf_device { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) struct iommu_domain *domain; #else +#ifdef ENABLE_SMMU_S1_TRANSLATION struct dma_iommu_mapping *iommu_mapping; #endif +#endif }; typedef struct __qdf_device *__qdf_device_t; typedef size_t __qdf_size_t; typedef off_t __qdf_off_t; -typedef uint8_t __iomem *__qdf_iomem_t; +typedef void __iomem* __qdf_iomem_t; typedef uint32_t ath_dma_addr_t; @@ -312,8 +331,6 @@ enum __qdf_net_wireless_evcode { __QDF_CUSTOM_PUSH_BUTTON = IWEVCUSTOM, }; -#define __qdf_print printk -#define __qdf_vprint vprintk #define __qdf_snprint snprintf #define __qdf_vsnprint vsnprintf #define __qdf_toupper toupper diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_util.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_util.h index 469320e6e02c50d9849a8a9c6ab4db89e71fd100..67469c355e0917fedf5f9e6f73dccaae956f652a 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_util.h +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/i_qdf_util.h @@ -472,4 +472,17 @@ int __qdf_hex_str_to_binary(u8 *dst, const char *src, size_t count) return hex2bin(dst, src, count); } +/** + * __qdf_fls() - find last set bit in a given 32 bit input + * @x: 32 bit mask + * + * Return: zero if the input is zero, otherwise returns the bit + * position of the last set bit, where the LSB is 1 and MSB is 32. + */ +static inline +int __qdf_fls(uint32_t x) +{ + return fls(x); +} + #endif /*_I_QDF_UTIL_H*/ diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_crypto.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_crypto.c index a3bcf10e0526d9baf67834e5fa8727e453bad46d..766221a20a50d80c990f1fc763054db7faf2edcc 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_crypto.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_crypto.c @@ -95,6 +95,27 @@ void qdf_update_dbl(uint8_t *d) d[AES_BLOCK_SIZE - 1] ^= 0x87; } +/** + * set_desc_flags() - set flags variable in the shash_desc struct + * @desc: pointer to shash_desc struct + * @tfm: pointer to crypto_shash struct + * + * Set the flags variable in the shash_desc struct by getting the flag + * from the crypto_hash struct. The flag is not actually used, prompting + * its removal from kernel code in versions 5.2 and above. Thus, for + * versions 5.2 and above, do not set the flag variable of shash_desc. + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) +static void set_desc_flags(struct shash_desc *desc, struct crypto_shash *tfm) +{ + desc->flags = crypto_shash_get_flags(tfm); +} +#else +static void set_desc_flags(struct shash_desc *desc, struct crypto_shash *tfm) +{ +} +#endif + int qdf_get_keyed_hash(const char *alg, const uint8_t *key, unsigned int key_len, const uint8_t *src[], size_t *src_len, size_t num_elements, uint8_t *out) @@ -124,7 +145,7 @@ int qdf_get_keyed_hash(const char *alg, const uint8_t *key, do { SHASH_DESC_ON_STACK(desc, tfm); desc->tfm = tfm; - desc->flags = crypto_shash_get_flags(tfm); + set_desc_flags(desc, tfm); ret = crypto_shash_init(desc); if (ret) { diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_debugfs.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_debugfs.c index f590a87508b645044788d15218da836e0cb4de7d..da98bb0bbe889d919925b6c26df2ed7a099436ee 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_debugfs.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_debugfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -165,6 +165,8 @@ void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f, ...) va_end(args); } +qdf_export_symbol(qdf_debugfs_printf); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf, @@ -466,3 +468,70 @@ void qdf_debugfs_remove_file(qdf_dentry_t d) debugfs_remove(d); } qdf_export_symbol(qdf_debugfs_remove_file); + +static int qdf_debugfs_single_show(struct seq_file *seq, void *v) +{ + struct qdf_debugfs_fops *fops = seq->private; + + if (fops && fops->show) + fops->show(seq, fops->priv); + + return 0; +} + +/* .open() */ +static int qdf_debugfs_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, qdf_debugfs_single_show, + inode->i_private); +} + +/* File operations for the simplified version */ +static const struct file_operations qdf_debugfs_fops_simple = { + .owner = THIS_MODULE, + .open = qdf_debugfs_single_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek, +}; + +qdf_dentry_t qdf_debugfs_create_file_simplified( + const char *name, uint16_t mode, + qdf_dentry_t parent, struct qdf_debugfs_fops *fops) +{ + qdf_dentry_t file; + umode_t filemode; + + if (!name || !fops) + return NULL; + + if (!parent) + parent = qdf_debugfs_get_root(); + + filemode = qdf_debugfs_get_filemode(mode); + file = debugfs_create_file(name, filemode, parent, fops, + &qdf_debugfs_fops_simple); + + if (IS_ERR_OR_NULL(file)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s creation failed 0x%pK", name, file); + file = NULL; + } + + return file; +} +qdf_export_symbol(qdf_debugfs_create_file_simplified); + +int qdf_debugfs_printer(void *priv, const char *fmt, ...) +{ + struct seq_file *file = priv; + va_list args; + + va_start(args, fmt); + seq_vprintf(file, fmt, args); + seq_puts(file, "\n"); + va_end(args); + + return 0; +} +qdf_export_symbol(qdf_debugfs_printer); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.c new file mode 100644 index 0000000000000000000000000000000000000000..43fa3b44ee522c8262e0ac97ce7c7acfa1a4cf5d --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include + +#ifdef FUNC_CALL_MAP +char qdf_func_call_map_buf[QDF_FUNCTION_CALL_MAP_BUF_LEN] = {0}; + +void cc_func(unsigned int track) +{ + unsigned int index = 0; + unsigned int bit = 0; + + index = track / 8; + bit = track % 8; + qdf_func_call_map_buf[index] |= (char)(1 << bit); +} + +void qdf_get_func_call_map(char *data) +{ + qdf_mem_copy(data, qdf_func_call_map_buf, + QDF_FUNCTION_CALL_MAP_BUF_LEN); +} + +void qdf_clear_func_call_map(void) +{ + qdf_mem_zero(qdf_func_call_map_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.h b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..5f4fb25dedd73eef3f34a3cc554ca49096ba2716 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_func_tracker.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef QDF_FUNC_TRACKER_H +#define QDF_FUNC_TRACKER_H + +#ifdef FUNC_CALL_MAP + +#define QDF_FUNCTION_CALL_MAP_BUF_LEN 4096 + +/** + * cc_func() - Inserts the function Id into the global + * function map + * @track: Function Id which needs to be inserted into the + * Global function map. + * + * Return: None + */ +void cc_func(unsigned int track); + +/** + * qdf_get_func_call_map() - Copies the global function call + * map into the given buffer + * @data: Buffer in which the function call map needs to be + * copied + * + * Return: None + */ +void qdf_get_func_call_map(char *data); + +/** + * qdf_clear_func_call_map() - Clears the global function + * call map + * + * Return: None + */ +void qdf_clear_func_call_map(void); +#else +static inline void cc_func(unsigned int track) +{ +} + +static inline void qdf_get_func_call_map(char *data) +{ +} + +static inline void qdf_clear_func_call_map(void) +{ +} + +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_lock.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_lock.c index 710553e3be1471df5356f262541d6b86d8c916fa..48deb01e93ea15571f10669488d43f8a5320c9bf 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_lock.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_lock.c @@ -23,7 +23,7 @@ #include #include -#ifdef CONFIG_MCL +#ifdef FEATURE_RUNTIME_PM #include #include #endif @@ -582,10 +582,6 @@ qdf_export_symbol(__qdf_runtime_lock_init); void qdf_runtime_lock_deinit(qdf_runtime_lock_t *lock) { void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); - - if (!lock) - return; - hif_runtime_lock_deinit(hif_ctx, lock->lock); } qdf_export_symbol(qdf_runtime_lock_deinit); @@ -827,6 +823,7 @@ void qdf_lock_stats_deinit(void) __func__, lock_cookies[i].u.cookie.func, lock_cookies[i].u.cookie.line); } + lock_cookie_freelist = NULL; } /* allocated separate memory in case the lock memory is freed without diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mc_timer.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mc_timer.c index 163e7b1edd471fd5a202b21b386f87f515b6bfe8..b2591b32e957ddd9a3ec1e81552b8ac0d199a7d9 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mc_timer.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mc_timer.c @@ -30,6 +30,7 @@ #include "qdf_mem.h" #include #include "qdf_timer.h" +#include /* Preprocessor definitions and constants */ #define LINUX_TIMER_COOKIE 0x12341234 @@ -824,6 +825,17 @@ qdf_export_symbol(qdf_mc_timer_get_system_ticks); * Return: * The current system time in milliseconds */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +unsigned long qdf_mc_timer_get_system_time(void) +{ + struct timespec64 tv; + + ktime_get_real_ts64(&tv); + return tv.tv_sec * 1000 + tv.tv_nsec / 1000000; +} +qdf_export_symbol(qdf_mc_timer_get_system_time); + +#else unsigned long qdf_mc_timer_get_system_time(void) { struct timeval tv; @@ -832,17 +844,32 @@ unsigned long qdf_mc_timer_get_system_time(void) return tv.tv_sec * 1000 + tv.tv_usec / 1000; } qdf_export_symbol(qdf_mc_timer_get_system_time); +#endif s64 qdf_get_monotonic_boottime_ns(void) { - struct timespec ts; + return ktime_to_ns(ktime_get_boottime()); +} +qdf_export_symbol(qdf_get_monotonic_boottime_ns); - get_monotonic_boottime(&ts); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +qdf_time_t qdf_get_time_of_the_day_ms(void) +{ + struct timespec64 tv; + qdf_time_t local_time; + struct rtc_time tm; - return timespec_to_ns(&ts); + ktime_get_real_ts64(&tv); + local_time = (qdf_time_t)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + + return (tm.tm_hour * 60 * 60 * 1000) + + (tm.tm_min * 60 * 1000) + (tm.tm_sec * 1000) + + (tv.tv_nsec / 1000000); } -qdf_export_symbol(qdf_get_monotonic_boottime_ns); +qdf_export_symbol(qdf_get_time_of_the_day_ms); +#else qdf_time_t qdf_get_time_of_the_day_ms(void) { struct timeval tv; @@ -858,6 +885,7 @@ qdf_time_t qdf_get_time_of_the_day_ms(void) (tv.tv_usec / 1000); } qdf_export_symbol(qdf_get_time_of_the_day_ms); +#endif /** * qdf_timer_module_deinit() - Deinitializes a QDF timer module. @@ -873,6 +901,25 @@ void qdf_timer_module_deinit(void) } qdf_export_symbol(qdf_timer_module_deinit); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +void qdf_get_time_of_the_day_in_hr_min_sec_usec(char *tbuf, int len) +{ + struct timespec64 tv; + struct rtc_time tm; + unsigned long local_time; + + /* Format the Log time R#: [hr:min:sec.microsec] */ + ktime_get_real_ts64(&tv); + /* Convert rtc to local time */ + local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + scnprintf(tbuf, len, + "[%02d:%02d:%02d.%06lu]", + tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_nsec / 1000); +} +qdf_export_symbol(qdf_get_time_of_the_day_in_hr_min_sec_usec); + +#else void qdf_get_time_of_the_day_in_hr_min_sec_usec(char *tbuf, int len) { struct timeval tv; @@ -889,3 +936,4 @@ void qdf_get_time_of_the_day_in_hr_min_sec_usec(char *tbuf, int len) tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec); } qdf_export_symbol(qdf_get_time_of_the_day_in_hr_min_sec_usec); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mem.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mem.c index e967f212f4f4d53706d3f8d7d4b5588a0c3e4c19..21576d9878412a3acd3b8b511cd965a60d740cd5 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mem.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,19 +34,57 @@ #include #include #include -#include #if IS_ENABLED(CONFIG_WCNSS_MEM_PRE_ALLOC) #include #endif +#if defined(MEMORY_DEBUG) || defined(NBUF_MEMORY_DEBUG) +static bool mem_debug_disabled; +qdf_declare_param(mem_debug_disabled, bool); +qdf_export_symbol(mem_debug_disabled); +static bool is_initial_mem_debug_disabled; +#endif + /* Preprocessor Definitions and Constants */ #define QDF_MEM_MAX_MALLOC (4096 * 1024) /* 4 Mega Bytes */ #define QDF_MEM_WARN_THRESHOLD 300 /* ms */ #define QDF_DEBUG_STRING_SIZE 512 +/** + * struct __qdf_mem_stat - qdf memory statistics + * @kmalloc: total kmalloc allocations + * @dma: total dma allocations + * @skb: total skb allocations + */ +static struct __qdf_mem_stat { + qdf_atomic_t kmalloc; + qdf_atomic_t dma; + qdf_atomic_t skb; +} qdf_mem_stat; + #ifdef MEMORY_DEBUG #include "qdf_debug_domain.h" +#include + +enum list_type { + LIST_TYPE_MEM = 0, + LIST_TYPE_DMA = 1, + LIST_TYPE_MAX, +}; + +/** + * major_alloc_priv: private data registered to debugfs entry created to list + * the list major allocations + * @type: type of the list to be parsed + * @threshold: configured by user by overwriting the respective debugfs + * sys entry. This is to list the functions which requested + * memory/dma allocations more than threshold nubmer of times. + */ +struct major_alloc_priv { + enum list_type type; + uint32_t threshold; +}; static qdf_list_t qdf_mem_domains[QDF_DEBUG_DOMAIN_COUNT]; static qdf_spinlock_t qdf_mem_list_lock; @@ -237,13 +275,18 @@ qdf_mem_header_assert_valid(struct qdf_mem_header *header, qdf_debug_domain_name(header->domain), header->domain, qdf_debug_domain_name(current_domain), current_domain); - QDF_DEBUG_PANIC("Fatal memory error detected @ %s:%d", func, line); + QDF_MEMDEBUG_PANIC("Fatal memory error detected @ %s:%d", func, line); } -#endif /* MEMORY_DEBUG */ -u_int8_t prealloc_disabled = 1; -qdf_declare_param(prealloc_disabled, byte); -qdf_export_symbol(prealloc_disabled); +void qdf_mem_skb_inc(qdf_size_t size) +{ + qdf_atomic_add(size, &qdf_mem_stat.skb); +} + +void qdf_mem_skb_dec(qdf_size_t size) +{ + qdf_atomic_sub(size, &qdf_mem_stat.skb); +} /** * struct __qdf_mem_info - memory statistics @@ -263,80 +306,6 @@ struct __qdf_mem_info { uint64_t time; }; -static struct __qdf_mem_stat { - qdf_atomic_t kmalloc; - qdf_atomic_t dma; - qdf_atomic_t skb; -} qdf_mem_stat; - -void qdf_mem_skb_inc(qdf_size_t size) -{ - qdf_atomic_add(size, &qdf_mem_stat.skb); -} - -void qdf_mem_skb_dec(qdf_size_t size) -{ - qdf_atomic_sub(size, &qdf_mem_stat.skb); -} - -#if defined WLAN_DEBUGFS - -/* Debugfs root directory for qdf_mem */ -static struct dentry *qdf_mem_debugfs_root; - -/** - * struct __qdf_mem_stat - qdf memory statistics - * @kmalloc: total kmalloc allocations - * @dma: total dma allocations - * @skb: total skb allocations - */ - -void qdf_mem_kmalloc_inc(qdf_size_t size) -{ - qdf_atomic_add(size, &qdf_mem_stat.kmalloc); -} - -void qdf_mem_kmalloc_dec(qdf_size_t size) -{ - qdf_atomic_sub(size, &qdf_mem_stat.kmalloc); -} - -static void qdf_mem_dma_inc(qdf_size_t size) -{ - qdf_atomic_add(size, &qdf_mem_stat.dma); -} - -static inline void qdf_mem_dma_dec(qdf_size_t size) -{ - qdf_atomic_sub(size, &qdf_mem_stat.dma); -} - - -#ifdef MEMORY_DEBUG -static int qdf_err_printer(void *priv, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - QDF_VTRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, (char *)fmt, args); - va_end(args); - - return 0; -} - -static int seq_printf_printer(void *priv, const char *fmt, ...) -{ - struct seq_file *file = priv; - va_list args; - - va_start(args, fmt); - seq_vprintf(file, fmt, args); - seq_puts(file, "\n"); - va_end(args); - - return 0; -} - /* * The table depth defines the de-duplication proximity scope. * A deeper table takes more time, so choose any optimum value. @@ -344,15 +313,20 @@ static int seq_printf_printer(void *priv, const char *fmt, ...) #define QDF_MEM_STAT_TABLE_SIZE 8 /** - * qdf_mem_domain_print_header() - memory domain header print logic + * qdf_mem_debug_print_header() - memory debug header print logic * @print: the print adapter function * @print_priv: the private data to be consumed by @print + * @threshold: the threshold value set by user to list top allocations * * Return: None */ -static void qdf_mem_domain_print_header(qdf_abstract_print print, - void *print_priv) +static void qdf_mem_debug_print_header(qdf_abstract_print print, + void *print_priv, + uint32_t threshold) { + if (threshold) + print(print_priv, "APIs requested allocations >= %u no of time", + threshold); print(print_priv, "--------------------------------------------------------------"); print(print_priv, @@ -361,48 +335,6 @@ static void qdf_mem_domain_print_header(qdf_abstract_print print, "--------------------------------------------------------------"); } -/** - * qdf_mem_meta_table_print() - memory metadata table print logic - * @table: the memory metadata table to print - * @print: the print adapter function - * @print_priv: the private data to be consumed by @print - * - * Return: None - */ -static void qdf_mem_meta_table_print(struct __qdf_mem_info *table, - qdf_abstract_print print, - void *print_priv) -{ - int i; - char debug_str[QDF_DEBUG_STRING_SIZE]; - size_t len = 0; - char *debug_prefix = "WLAN_BUG_RCA: memory leak detected"; - - len += qdf_scnprintf(debug_str, sizeof(debug_str) - len, - "%s", debug_prefix); - - for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { - if (!table[i].count) - break; - - print(print_priv, - "%6u x %5u = %7uB @ %s:%u %pS %llu", - table[i].count, - table[i].size, - table[i].count * table[i].size, - table[i].func, - table[i].line, table[i].caller, - table[i].time); - len += qdf_scnprintf(debug_str + len, - sizeof(debug_str) - len, - " @ %s:%u %pS", - table[i].func, - table[i].line, - table[i].caller); - } - print(print_priv, "%s", debug_str); -} - /** * qdf_mem_meta_table_insert() - insert memory metadata into the given table * @table: the memory metadata table to insert into @@ -445,19 +377,25 @@ static bool qdf_mem_meta_table_insert(struct __qdf_mem_info *table, * @domain: the memory domain to print * @print: the print adapter function * @print_priv: the private data to be consumed by @print + * @threshold: the threshold value set by uset to list top allocations + * @mem_print: pointer to function which prints the memory allocation data * * Return: None */ static void qdf_mem_domain_print(qdf_list_t *domain, qdf_abstract_print print, - void *print_priv) + void *print_priv, + uint32_t threshold, + void (*mem_print)(struct __qdf_mem_info *, + qdf_abstract_print, + void *, uint32_t)) { QDF_STATUS status; struct __qdf_mem_info table[QDF_MEM_STAT_TABLE_SIZE]; qdf_list_node_t *node; qdf_mem_zero(table, sizeof(table)); - qdf_mem_domain_print_header(print, print_priv); + qdf_mem_debug_print_header(print, print_priv, threshold); /* hold lock while inserting to avoid use-after free of the metadata */ qdf_spin_lock(&qdf_mem_list_lock); @@ -469,7 +407,7 @@ static void qdf_mem_domain_print(qdf_list_t *domain, qdf_spin_unlock(&qdf_mem_list_lock); if (is_full) { - qdf_mem_meta_table_print(table, print, print_priv); + (*mem_print)(table, print, print_priv, threshold); qdf_mem_zero(table, sizeof(table)); } @@ -478,7 +416,128 @@ static void qdf_mem_domain_print(qdf_list_t *domain, } qdf_spin_unlock(&qdf_mem_list_lock); - qdf_mem_meta_table_print(table, print, print_priv); + (*mem_print)(table, print, print_priv, threshold); +} + +/** + * qdf_mem_meta_table_print() - memory metadata table print logic + * @table: the memory metadata table to print + * @print: the print adapter function + * @print_priv: the private data to be consumed by @print + * @threshold: the threshold value set by user to list top allocations + * + * Return: None + */ +static void qdf_mem_meta_table_print(struct __qdf_mem_info *table, + qdf_abstract_print print, + void *print_priv, + uint32_t threshold) +{ + int i; + char debug_str[QDF_DEBUG_STRING_SIZE]; + size_t len = 0; + char *debug_prefix = "WLAN_BUG_RCA: memory leak detected"; + + len += qdf_scnprintf(debug_str, sizeof(debug_str) - len, + "%s", debug_prefix); + + for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { + if (!table[i].count) + break; + + print(print_priv, + "%6u x %5u = %7uB @ %s:%u %pS %llu", + table[i].count, + table[i].size, + table[i].count * table[i].size, + table[i].func, + table[i].line, table[i].caller, + table[i].time); + len += qdf_scnprintf(debug_str + len, + sizeof(debug_str) - len, + " @ %s:%u %pS", + table[i].func, + table[i].line, + table[i].caller); + } + print(print_priv, "%s", debug_str); +} + +static int qdf_err_printer(void *priv, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + QDF_VTRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, (char *)fmt, args); + va_end(args); + + return 0; +} + +#endif /* MEMORY_DEBUG */ + +u_int8_t prealloc_disabled = 1; +qdf_declare_param(prealloc_disabled, byte); +qdf_export_symbol(prealloc_disabled); + +#if defined WLAN_DEBUGFS + +void qdf_mem_kmalloc_inc(qdf_size_t size) +{ + qdf_atomic_add(size, &qdf_mem_stat.kmalloc); +} + +void qdf_mem_kmalloc_dec(qdf_size_t size) +{ + qdf_atomic_sub(size, &qdf_mem_stat.kmalloc); +} + +/* Debugfs root directory for qdf_mem */ +static struct dentry *qdf_mem_debugfs_root; + +#ifdef MEMORY_DEBUG +static int seq_printf_printer(void *priv, const char *fmt, ...) +{ + struct seq_file *file = priv; + va_list args; + + va_start(args, fmt); + seq_vprintf(file, fmt, args); + seq_puts(file, "\n"); + va_end(args); + + return 0; +} + +/** + * qdf_print_major_alloc() - memory metadata table print logic + * @table: the memory metadata table to print + * @print: the print adapter function + * @print_priv: the private data to be consumed by @print + * @threshold: the threshold value set by uset to list top allocations + * + * Return: None + */ +static void qdf_print_major_alloc(struct __qdf_mem_info *table, + qdf_abstract_print print, + void *print_priv, + uint32_t threshold) +{ + int i; + + for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { + if (!table[i].count) + break; + if (table[i].count >= threshold) + print(print_priv, + "%6u x %5u = %7uB @ %s:%u %pS %llu", + table[i].count, + table[i].size, + table[i].count * table[i].size, + table[i].func, + table[i].line, table[i].caller, + table[i].time); + } } /** @@ -539,7 +598,10 @@ static int qdf_mem_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "\n%s Memory Domain (Id %d)\n", qdf_debug_domain_name(domain_id), domain_id); qdf_mem_domain_print(qdf_mem_list_get(domain_id), - seq_printf_printer, seq); + seq_printf_printer, + seq, + 0, + qdf_mem_meta_table_print); return 0; } @@ -558,6 +620,99 @@ static int qdf_mem_debugfs_open(struct inode *inode, struct file *file) return seq_open(file, &qdf_mem_seq_ops); } +/** + * qdf_major_alloc_show() - print sequential callback + * @seq: seq_file handle + * @v: current iterator + * + * Return: 0 - success + */ +static int qdf_major_alloc_show(struct seq_file *seq, void *v) +{ + enum qdf_debug_domain domain_id = *(enum qdf_debug_domain *)v; + struct major_alloc_priv *priv; + qdf_list_t *list; + + priv = (struct major_alloc_priv *)seq->private; + seq_printf(seq, "\n%s Memory Domain (Id %d)\n", + qdf_debug_domain_name(domain_id), domain_id); + + switch (priv->type) { + case LIST_TYPE_MEM: + list = qdf_mem_list_get(domain_id); + break; + case LIST_TYPE_DMA: + list = qdf_mem_dma_list(domain_id); + break; + default: + list = NULL; + break; + } + + if (list) + qdf_mem_domain_print(list, + seq_printf_printer, + seq, + priv->threshold, + qdf_print_major_alloc); + + return 0; +} + +/* sequential file operation table created to track major allocs */ +static const struct seq_operations qdf_major_allocs_seq_ops = { + .start = qdf_mem_seq_start, + .next = qdf_mem_seq_next, + .stop = qdf_mem_seq_stop, + .show = qdf_major_alloc_show, +}; + +static int qdf_major_allocs_open(struct inode *inode, struct file *file) +{ + void *private = inode->i_private; + struct seq_file *seq; + int rc; + + rc = seq_open(file, &qdf_major_allocs_seq_ops); + if (rc == 0) { + seq = file->private_data; + seq->private = private; + } + return rc; +} + +static ssize_t qdf_major_alloc_set_threshold(struct file *file, + const char __user *user_buf, + size_t count, + loff_t *pos) +{ + char buf[32]; + ssize_t buf_size; + uint32_t threshold; + struct seq_file *seq = file->private_data; + struct major_alloc_priv *priv = (struct major_alloc_priv *)seq->private; + + buf_size = min(count, (sizeof(buf) - 1)); + if (buf_size <= 0) + return 0; + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = '\0'; + if (!kstrtou32(buf, 10, &threshold)) + priv->threshold = threshold; + return buf_size; +} + +/* file operation table for listing major allocs */ +static const struct file_operations fops_qdf_major_allocs = { + .owner = THIS_MODULE, + .open = qdf_major_allocs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = qdf_major_alloc_set_threshold, +}; + /* debugfs file operation table */ static const struct file_operations fops_qdf_mem_debugfs = { .owner = THIS_MODULE, @@ -567,8 +722,25 @@ static const struct file_operations fops_qdf_mem_debugfs = { .release = seq_release, }; +static struct major_alloc_priv mem_priv = { + /* List type set to mem */ + LIST_TYPE_MEM, + /* initial threshold to list APIs which allocates mem >= 50 times */ + 50 +}; + +static struct major_alloc_priv dma_priv = { + /* List type set to DMA */ + LIST_TYPE_DMA, + /* initial threshold to list APIs which allocates dma >= 50 times */ + 50 +}; + static QDF_STATUS qdf_mem_debug_debugfs_init(void) { + if (is_initial_mem_debug_disabled) + return QDF_STATUS_SUCCESS; + if (!qdf_mem_debugfs_root) return QDF_STATUS_E_FAILURE; @@ -578,6 +750,18 @@ static QDF_STATUS qdf_mem_debug_debugfs_init(void) NULL, &fops_qdf_mem_debugfs); + debugfs_create_file("major_mem_allocs", + 0600, + qdf_mem_debugfs_root, + &mem_priv, + &fops_qdf_major_allocs); + + debugfs_create_file("major_dma_allocs", + 0600, + qdf_mem_debugfs_root, + &dma_priv, + &fops_qdf_major_allocs); + return QDF_STATUS_SUCCESS; } @@ -640,13 +824,6 @@ static QDF_STATUS qdf_mem_debugfs_init(void) #else /* WLAN_DEBUGFS */ -static inline void qdf_mem_dma_inc(qdf_size_t size) {} -static inline void qdf_mem_dma_dec(qdf_size_t size) {} -static -inline void qdf_mem_domain_print(qdf_list_t *domain, - qdf_abstract_print print, - void *print_priv) {} - static QDF_STATUS qdf_mem_debugfs_init(void) { return QDF_STATUS_E_NOSUPPORT; @@ -666,6 +843,16 @@ static QDF_STATUS qdf_mem_debug_debugfs_exit(void) #endif /* WLAN_DEBUGFS */ +static void qdf_mem_dma_inc(qdf_size_t size) +{ + qdf_atomic_add(size, &qdf_mem_stat.dma); +} + +static inline void qdf_mem_dma_dec(qdf_size_t size) +{ + qdf_atomic_sub(size, &qdf_mem_stat.dma); +} + /** * __qdf_mempool_init() - Create and initialize memory pool * @@ -895,6 +1082,23 @@ static int qdf_mem_malloc_flags(void) /* External Function implementation */ #ifdef MEMORY_DEBUG +/** + * qdf_mem_debug_config_get() - Get the user configuration of mem_debug_disabled + * + * Return: value of mem_debug_disabled qdf module argument + */ +#ifdef DISABLE_MEM_DBG_LOAD_CONFIG +bool qdf_mem_debug_config_get(void) +{ + /* Return false if DISABLE_LOAD_MEM_DBG_CONFIG flag is enabled */ + return false; +} +#else +bool qdf_mem_debug_config_get(void) +{ + return mem_debug_disabled; +} +#endif /* DISABLE_MEM_DBG_LOAD_CONFIG */ /** * qdf_mem_debug_init() - initialize qdf memory debug functionality @@ -905,6 +1109,11 @@ static void qdf_mem_debug_init(void) { int i; + is_initial_mem_debug_disabled = qdf_mem_debug_config_get(); + + if (is_initial_mem_debug_disabled) + return; + /* Initalizing the list with maximum size of 60000 */ for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) qdf_list_create(&qdf_mem_domains[i], 60000); @@ -920,12 +1129,19 @@ static uint32_t qdf_mem_domain_check_for_leaks(enum qdf_debug_domain domain, qdf_list_t *mem_list) { + if (is_initial_mem_debug_disabled) + return 0; + if (qdf_list_empty(mem_list)) return 0; qdf_err("Memory leaks detected in %s domain!", qdf_debug_domain_name(domain)); - qdf_mem_domain_print(mem_list, qdf_err_printer, NULL); + qdf_mem_domain_print(mem_list, + qdf_err_printer, + NULL, + 0, + qdf_mem_meta_table_print); return mem_list->count; } @@ -935,13 +1151,16 @@ static void qdf_mem_domain_set_check_for_leaks(qdf_list_t *domains) uint32_t leak_count = 0; int i; + if (is_initial_mem_debug_disabled) + return; + /* detect and print leaks */ for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) leak_count += qdf_mem_domain_check_for_leaks(i, domains + i); if (leak_count) - QDF_DEBUG_PANIC("%u fatal memory leaks detected!", - leak_count); + QDF_MEMDEBUG_PANIC("%u fatal memory leaks detected!", + leak_count); } /** @@ -953,6 +1172,9 @@ static void qdf_mem_debug_exit(void) { int i; + if (is_initial_mem_debug_disabled) + return; + /* mem */ qdf_mem_domain_set_check_for_leaks(qdf_mem_domains); for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) @@ -977,6 +1199,9 @@ void *qdf_mem_malloc_debug(size_t size, const char *func, uint32_t line, void *ptr; unsigned long start, duration; + if (is_initial_mem_debug_disabled) + return __qdf_mem_malloc(size, func, line); + if (!size || size > QDF_MEM_MAX_MALLOC) { qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line); return NULL; @@ -1024,6 +1249,11 @@ void qdf_mem_free_debug(void *ptr, const char *func, uint32_t line) struct qdf_mem_header *header; enum qdf_mem_validation_bitmap error_bitmap; + if (is_initial_mem_debug_disabled) { + __qdf_mem_free(ptr); + return; + } + /* freeing a null pointer is valid */ if (qdf_unlikely(!ptr)) return; @@ -1032,8 +1262,8 @@ void qdf_mem_free_debug(void *ptr, const char *func, uint32_t line) return; if (qdf_unlikely((qdf_size_t)ptr <= sizeof(*header))) - QDF_DEBUG_PANIC("Failed to free invalid memory location %pK", - ptr); + QDF_MEMDEBUG_PANIC("Failed to free invalid memory location %pK", + ptr); qdf_talloc_assert_no_children_fl(ptr, func, line); @@ -1064,45 +1294,184 @@ void qdf_mem_check_for_leaks(void) qdf_list_t *dma_list = qdf_mem_dma_list(current_domain); uint32_t leaks_count = 0; + if (is_initial_mem_debug_disabled) + return; + leaks_count += qdf_mem_domain_check_for_leaks(current_domain, mem_list); leaks_count += qdf_mem_domain_check_for_leaks(current_domain, dma_list); if (leaks_count) - QDF_DEBUG_PANIC("%u fatal memory leaks detected!", - leaks_count); + QDF_MEMDEBUG_PANIC("%u fatal memory leaks detected!", + leaks_count); } -#else -static void qdf_mem_debug_init(void) {} +/** + * qdf_mem_multi_pages_alloc_debug() - Debug version of + * qdf_mem_multi_pages_alloc + * @osdev: OS device handle pointer + * @pages: Multi page information storage + * @element_size: Each element size + * @element_num: Total number of elements should be allocated + * @memctxt: Memory context + * @cacheable: Coherent memory or cacheable memory + * @func: Caller of this allocator + * @line: Line number of the caller + * @caller: Return address of the caller + * + * This function will allocate large size of memory over multiple pages. + * Large size of contiguous memory allocation will fail frequently, then + * instead of allocate large memory by one shot, allocate through multiple, non + * contiguous memory and combine pages when actual usage + * + * Return: None + */ +void qdf_mem_multi_pages_alloc_debug(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + size_t element_size, uint16_t element_num, + qdf_dma_context_t memctxt, bool cacheable, + const char *func, uint32_t line, + void *caller) +{ + uint16_t page_idx; + struct qdf_mem_dma_page_t *dma_pages; + void **cacheable_pages = NULL; + uint16_t i; + + if (!pages->page_size) + pages->page_size = qdf_page_size; + + pages->num_element_per_page = pages->page_size / element_size; + if (!pages->num_element_per_page) { + qdf_print("Invalid page %d or element size %d", + (int)pages->page_size, (int)element_size); + goto out_fail; + } + + pages->num_pages = element_num / pages->num_element_per_page; + if (element_num % pages->num_element_per_page) + pages->num_pages++; + + if (cacheable) { + /* Pages information storage */ + pages->cacheable_pages = qdf_mem_malloc_debug( + pages->num_pages * sizeof(pages->cacheable_pages), + func, line, caller, 0); + if (!pages->cacheable_pages) + goto out_fail; + + cacheable_pages = pages->cacheable_pages; + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { + cacheable_pages[page_idx] = qdf_mem_malloc_debug( + pages->page_size, func, line, caller, 0); + if (!cacheable_pages[page_idx]) + goto page_alloc_fail; + } + pages->dma_pages = NULL; + } else { + pages->dma_pages = qdf_mem_malloc_debug( + pages->num_pages * sizeof(struct qdf_mem_dma_page_t), + func, line, caller, 0); + if (!pages->dma_pages) + goto out_fail; + + dma_pages = pages->dma_pages; + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { + dma_pages->page_v_addr_start = + qdf_mem_alloc_consistent_debug( + osdev, osdev->dev, pages->page_size, + &dma_pages->page_p_addr, + func, line, caller); + if (!dma_pages->page_v_addr_start) { + qdf_print("dmaable page alloc fail pi %d", + page_idx); + goto page_alloc_fail; + } + dma_pages->page_v_addr_end = + dma_pages->page_v_addr_start + pages->page_size; + dma_pages++; + } + pages->cacheable_pages = NULL; + } + return; + +page_alloc_fail: + if (cacheable) { + for (i = 0; i < page_idx; i++) + qdf_mem_free_debug(pages->cacheable_pages[i], + func, line); + qdf_mem_free_debug(pages->cacheable_pages, func, line); + } else { + dma_pages = pages->dma_pages; + for (i = 0; i < page_idx; i++) { + qdf_mem_free_consistent_debug( + osdev, osdev->dev, + pages->page_size, dma_pages->page_v_addr_start, + dma_pages->page_p_addr, memctxt, func, line); + dma_pages++; + } + qdf_mem_free_debug(pages->dma_pages, func, line); + } + +out_fail: + pages->cacheable_pages = NULL; + pages->dma_pages = NULL; + pages->num_pages = 0; +} -static void qdf_mem_debug_exit(void) {} +qdf_export_symbol(qdf_mem_multi_pages_alloc_debug); -void *qdf_mem_malloc_fl(size_t size, const char *func, uint32_t line) +/** + * qdf_mem_multi_pages_free_debug() - Debug version of qdf_mem_multi_pages_free + * @osdev: OS device handle pointer + * @pages: Multi page information storage + * @memctxt: Memory context + * @cacheable: Coherent memory or cacheable memory + * @func: Caller of this allocator + * @line: Line number of the caller + * + * This function will free large size of memory over multiple pages. + * + * Return: None + */ +void qdf_mem_multi_pages_free_debug(qdf_device_t osdev, + struct qdf_mem_multi_page_t *pages, + qdf_dma_context_t memctxt, bool cacheable, + const char *func, uint32_t line) { - void *ptr; + unsigned int page_idx; + struct qdf_mem_dma_page_t *dma_pages; - if (!size || size > QDF_MEM_MAX_MALLOC) { - qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, - line); - return NULL; + if (!pages->page_size) + pages->page_size = qdf_page_size; + + if (cacheable) { + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) + qdf_mem_free_debug(pages->cacheable_pages[page_idx], + func, line); + qdf_mem_free_debug(pages->cacheable_pages, func, line); + } else { + dma_pages = pages->dma_pages; + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { + qdf_mem_free_consistent_debug( + osdev, osdev->dev, pages->page_size, + dma_pages->page_v_addr_start, + dma_pages->page_p_addr, memctxt, func, line); + dma_pages++; + } + qdf_mem_free_debug(pages->dma_pages, func, line); } - ptr = qdf_mem_prealloc_get(size); - if (ptr) - return ptr; + pages->cacheable_pages = NULL; + pages->dma_pages = NULL; + pages->num_pages = 0; +} - ptr = kzalloc(size, qdf_mem_malloc_flags()); - if (!ptr) { - qdf_nofl_err("Failed to malloc %zuB @ %s:%d", - size, func, line); - return NULL; - } +qdf_export_symbol(qdf_mem_multi_pages_free_debug); - qdf_mem_kmalloc_inc(ksize(ptr)); +#else +static void qdf_mem_debug_init(void) {} - return ptr; -} -qdf_export_symbol(qdf_mem_malloc_fl); +static void qdf_mem_debug_exit(void) {} void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line) { @@ -1125,85 +1494,6 @@ void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line) } qdf_export_symbol(qdf_mem_malloc_atomic_fl); -/** - * qdf_mem_free() - free QDF memory - * @ptr: Pointer to the starting address of the memory to be free'd. - * - * This function will free the memory pointed to by 'ptr'. - * - * Return: None - */ -void qdf_mem_free(void *ptr) -{ - if (!ptr) - return; - - if (qdf_mem_prealloc_put(ptr)) - return; - - qdf_mem_kmalloc_dec(ksize(ptr)); - - kfree(ptr); -} - -qdf_export_symbol(qdf_mem_free); -#endif - -void *qdf_aligned_malloc_fl(uint32_t *size, - void **vaddr_unaligned, - qdf_dma_addr_t *paddr_unaligned, - qdf_dma_addr_t *paddr_aligned, - uint32_t align, - const char *func, uint32_t line) -{ - void *vaddr_aligned; - uint32_t align_alloc_size; - - *vaddr_unaligned = qdf_mem_malloc_fl((qdf_size_t)*size, func, - line); - if (!*vaddr_unaligned) { - qdf_warn("Failed to alloc %uB @ %s:%d", *size, func, line); - return NULL; - } - - *paddr_unaligned = qdf_mem_virt_to_phys(*vaddr_unaligned); - - /* Re-allocate additional bytes to align base address only if - * above allocation returns unaligned address. Reason for - * trying exact size allocation above is, OS tries to allocate - * blocks of size power-of-2 pages and then free extra pages. - * e.g., of a ring size of 1MB, the allocation below will - * request 1MB plus 7 bytes for alignment, which will cause a - * 2MB block allocation,and that is failing sometimes due to - * memory fragmentation. - */ - if ((unsigned long)(*paddr_unaligned) & (align - 1)) { - align_alloc_size = *size + align - 1; - - qdf_mem_free(*vaddr_unaligned); - *vaddr_unaligned = qdf_mem_malloc_fl( - (qdf_size_t)align_alloc_size, func, line); - if (!*vaddr_unaligned) { - qdf_warn("Failed to alloc %uB @ %s:%d", - align_alloc_size, func, line); - return NULL; - } - - *paddr_unaligned = qdf_mem_virt_to_phys( - *vaddr_unaligned); - *size = align_alloc_size; - } - - *paddr_aligned = (qdf_dma_addr_t)qdf_align - ((unsigned long)(*paddr_unaligned), align); - - vaddr_aligned = (void *)((unsigned long)(*vaddr_unaligned) + - ((unsigned long)(*paddr_aligned) - - (unsigned long)(*paddr_unaligned))); - - return vaddr_aligned; -} - /** * qdf_mem_multi_pages_alloc() - allocate large size of kernel memory * @osdev: OS device handle pointer @@ -1230,10 +1520,13 @@ void qdf_mem_multi_pages_alloc(qdf_device_t osdev, void **cacheable_pages = NULL; uint16_t i; - pages->num_element_per_page = PAGE_SIZE / element_size; + if (!pages->page_size) + pages->page_size = qdf_page_size; + + pages->num_element_per_page = pages->page_size / element_size; if (!pages->num_element_per_page) { qdf_print("Invalid page %d or element size %d", - (int)PAGE_SIZE, (int)element_size); + (int)pages->page_size, (int)element_size); goto out_fail; } @@ -1250,7 +1543,8 @@ void qdf_mem_multi_pages_alloc(qdf_device_t osdev, cacheable_pages = pages->cacheable_pages; for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { - cacheable_pages[page_idx] = qdf_mem_malloc(PAGE_SIZE); + cacheable_pages[page_idx] = + qdf_mem_malloc(pages->page_size); if (!cacheable_pages[page_idx]) goto page_alloc_fail; } @@ -1265,7 +1559,7 @@ void qdf_mem_multi_pages_alloc(qdf_device_t osdev, for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { dma_pages->page_v_addr_start = qdf_mem_alloc_consistent(osdev, osdev->dev, - PAGE_SIZE, + pages->page_size, &dma_pages->page_p_addr); if (!dma_pages->page_v_addr_start) { qdf_print("dmaable page alloc fail pi %d", @@ -1273,7 +1567,7 @@ void qdf_mem_multi_pages_alloc(qdf_device_t osdev, goto page_alloc_fail; } dma_pages->page_v_addr_end = - dma_pages->page_v_addr_start + PAGE_SIZE; + dma_pages->page_v_addr_start + pages->page_size; dma_pages++; } pages->cacheable_pages = NULL; @@ -1288,7 +1582,8 @@ void qdf_mem_multi_pages_alloc(qdf_device_t osdev, } else { dma_pages = pages->dma_pages; for (i = 0; i < page_idx; i++) { - qdf_mem_free_consistent(osdev, osdev->dev, PAGE_SIZE, + qdf_mem_free_consistent( + osdev, osdev->dev, pages->page_size, dma_pages->page_v_addr_start, dma_pages->page_p_addr, memctxt); dma_pages++; @@ -1322,6 +1617,9 @@ void qdf_mem_multi_pages_free(qdf_device_t osdev, unsigned int page_idx; struct qdf_mem_dma_page_t *dma_pages; + if (!pages->page_size) + pages->page_size = qdf_page_size; + if (cacheable) { for (page_idx = 0; page_idx < pages->num_pages; page_idx++) qdf_mem_free(pages->cacheable_pages[page_idx]); @@ -1329,7 +1627,8 @@ void qdf_mem_multi_pages_free(qdf_device_t osdev, } else { dma_pages = pages->dma_pages; for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { - qdf_mem_free_consistent(osdev, osdev->dev, PAGE_SIZE, + qdf_mem_free_consistent( + osdev, osdev->dev, pages->page_size, dma_pages->page_v_addr_start, dma_pages->page_p_addr, memctxt); dma_pages++; @@ -1343,6 +1642,129 @@ void qdf_mem_multi_pages_free(qdf_device_t osdev, return; } qdf_export_symbol(qdf_mem_multi_pages_free); +#endif + +void qdf_mem_multi_pages_zero(struct qdf_mem_multi_page_t *pages, + bool cacheable) +{ + unsigned int page_idx; + struct qdf_mem_dma_page_t *dma_pages; + + if (!pages->page_size) + pages->page_size = qdf_page_size; + + if (cacheable) { + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) + qdf_mem_zero(pages->cacheable_pages[page_idx], + pages->page_size); + } else { + dma_pages = pages->dma_pages; + for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { + qdf_mem_zero(dma_pages->page_v_addr_start, + pages->page_size); + dma_pages++; + } + } +} + +qdf_export_symbol(qdf_mem_multi_pages_zero); + +void __qdf_mem_free(void *ptr) +{ + if (!ptr) + return; + + if (qdf_mem_prealloc_put(ptr)) + return; + + qdf_mem_kmalloc_dec(ksize(ptr)); + + kfree(ptr); +} + +qdf_export_symbol(__qdf_mem_free); + +void *__qdf_mem_malloc(size_t size, const char *func, uint32_t line) +{ + void *ptr; + + if (!size || size > QDF_MEM_MAX_MALLOC) { + qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, + line); + return NULL; + } + + ptr = qdf_mem_prealloc_get(size); + if (ptr) + return ptr; + + ptr = kzalloc(size, qdf_mem_malloc_flags()); + if (!ptr) + return NULL; + + qdf_mem_kmalloc_inc(ksize(ptr)); + + return ptr; +} + +qdf_export_symbol(__qdf_mem_malloc); + +void *qdf_aligned_malloc_fl(uint32_t *size, + void **vaddr_unaligned, + qdf_dma_addr_t *paddr_unaligned, + qdf_dma_addr_t *paddr_aligned, + uint32_t align, + const char *func, uint32_t line) +{ + void *vaddr_aligned; + uint32_t align_alloc_size; + + *vaddr_unaligned = qdf_mem_malloc_fl((qdf_size_t)*size, func, + line); + if (!*vaddr_unaligned) { + qdf_warn("Failed to alloc %uB @ %s:%d", *size, func, line); + return NULL; + } + + *paddr_unaligned = qdf_mem_virt_to_phys(*vaddr_unaligned); + + /* Re-allocate additional bytes to align base address only if + * above allocation returns unaligned address. Reason for + * trying exact size allocation above is, OS tries to allocate + * blocks of size power-of-2 pages and then free extra pages. + * e.g., of a ring size of 1MB, the allocation below will + * request 1MB plus 7 bytes for alignment, which will cause a + * 2MB block allocation,and that is failing sometimes due to + * memory fragmentation. + */ + if ((unsigned long)(*paddr_unaligned) & (align - 1)) { + align_alloc_size = *size + align - 1; + + qdf_mem_free(*vaddr_unaligned); + *vaddr_unaligned = qdf_mem_malloc_fl( + (qdf_size_t)align_alloc_size, func, line); + if (!*vaddr_unaligned) { + qdf_warn("Failed to alloc %uB @ %s:%d", + align_alloc_size, func, line); + return NULL; + } + + *paddr_unaligned = qdf_mem_virt_to_phys( + *vaddr_unaligned); + *size = align_alloc_size; + } + + *paddr_aligned = (qdf_dma_addr_t)qdf_align + ((unsigned long)(*paddr_unaligned), align); + + vaddr_aligned = (void *)((unsigned long)(*vaddr_unaligned) + + ((unsigned long)(*paddr_aligned) - + (unsigned long)(*paddr_unaligned))); + + return vaddr_aligned; +} + +qdf_export_symbol(qdf_aligned_malloc_fl); /** * qdf_mem_multi_page_link() - Make links for multi page elements @@ -1574,7 +1996,9 @@ static inline void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, return vaddr; } -#elif defined(QCA_WIFI_QCA8074_VP) && defined(BUILD_X86) +#elif defined(CONFIG_WIFI_EMULATION_WIFI_3_0) && defined(BUILD_X86) && \ + !defined(QCA_WIFI_QCN9000) + #define QCA8074_RAM_BASE 0x50000000 #define QDF_MEM_ALLOC_X86_MAX_RETRIES 10 void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, qdf_size_t size, @@ -1638,6 +2062,11 @@ void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev, struct qdf_mem_header *header; void *vaddr; + if (is_initial_mem_debug_disabled) + return __qdf_mem_alloc_consistent(osdev, dev, + size, paddr, + func, line); + if (!size || size > QDF_MEM_MAX_MALLOC) { qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line); return NULL; @@ -1681,6 +2110,14 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, struct qdf_mem_header *header; enum qdf_mem_validation_bitmap error_bitmap; + if (is_initial_mem_debug_disabled) { + __qdf_mem_free_consistent( + osdev, dev, + size, vaddr, + paddr, memctx); + return; + } + /* freeing a null pointer is valid */ if (qdf_unlikely(!vaddr)) return; @@ -1708,31 +2145,39 @@ void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, qdf_mem_dma_free(dev, size + QDF_DMA_MEM_DEBUG_SIZE, vaddr, paddr); } qdf_export_symbol(qdf_mem_free_consistent_debug); +#endif /* MEMORY_DEBUG */ -#else +void __qdf_mem_free_consistent(qdf_device_t osdev, void *dev, + qdf_size_t size, void *vaddr, + qdf_dma_addr_t paddr, qdf_dma_context_t memctx) +{ + qdf_mem_dma_dec(size); + qdf_mem_dma_free(dev, size, vaddr, paddr); +} -void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, - qdf_size_t size, qdf_dma_addr_t *paddr) +qdf_export_symbol(__qdf_mem_free_consistent); + +void *__qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, + qdf_size_t size, qdf_dma_addr_t *paddr, + const char *func, uint32_t line) { - void *vaddr = qdf_mem_dma_alloc(osdev, dev, size, paddr); + void *vaddr; + + if (!size || size > QDF_MEM_MAX_MALLOC) { + qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", + size, func, line); + return NULL; + } + + vaddr = qdf_mem_dma_alloc(osdev, dev, size, paddr); if (vaddr) qdf_mem_dma_inc(size); return vaddr; } -qdf_export_symbol(qdf_mem_alloc_consistent); - -void qdf_mem_free_consistent(qdf_device_t osdev, void *dev, - qdf_size_t size, void *vaddr, - qdf_dma_addr_t paddr, qdf_dma_context_t memctx) -{ - qdf_mem_dma_dec(size); - qdf_mem_dma_free(dev, size, vaddr, paddr); -} -qdf_export_symbol(qdf_mem_free_consistent); -#endif /* MEMORY_DEBUG */ +qdf_export_symbol(__qdf_mem_alloc_consistent); void *qdf_aligned_mem_alloc_consistent_fl( qdf_device_t osdev, uint32_t *size, diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_module.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_module.c index 92dff158c343b3ab8e298f9cd879a6f0d3f78fef..9c1529206c050373d7d05a22b5d82abfa13fe9c6 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_module.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_module.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -42,8 +42,11 @@ MODULE_LICENSE("Dual BSD/GPL"); * * Return: int */ -static int __init -qdf_mod_init(void) +#ifndef QCA_SINGLE_WIFI_3_0 +static int __init qdf_mod_init(void) +#else +int qdf_mod_init(void) +#endif { qdf_shared_print_ctrl_init(); qdf_debugfs_init(); @@ -56,15 +59,20 @@ qdf_mod_init(void) return 0; } -module_init(qdf_mod_init); +#ifndef QCA_SINGLE_WIFI_3_0 +module_init(qdf_mod_init); +#endif /** * qdf_mod_exit() - module remove * * Return: int */ -static void __exit -qdf_mod_exit(void) +#ifndef QCA_SINGLE_WIFI_3_0 +static void __exit qdf_mod_exit(void) +#else +void qdf_mod_exit(void) +#endif { qdf_event_list_destroy(); qdf_nbuf_mod_exit(); @@ -75,5 +83,7 @@ qdf_mod_exit(void) qdf_debugfs_exit(); qdf_shared_print_ctrl_cleanup(); } -module_exit(qdf_mod_exit); +#ifndef QCA_SINGLE_WIFI_3_0 +module_exit(qdf_mod_exit); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_nbuf.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_nbuf.c index 6bddb719e314204d1491b921c0c77888529534f3..0ee852ee732791a22f4307ae751d2a82bcd313a6 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_nbuf.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_nbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -84,6 +84,7 @@ #define CHANNEL_FREQ_2512 2512 #define CHANNEL_FREQ_5000 5000 #define CHANNEL_FREQ_4000 4000 +#define CHANNEL_FREQ_5150 5150 #define FREQ_MULTIPLIER_CONST_5MHZ 5 #define FREQ_MULTIPLIER_CONST_20MHZ 20 #define RADIOTAP_5G_SPECTRUM_CHANNEL 0x0100 @@ -113,6 +114,65 @@ static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX]; static qdf_atomic_t nbuf_count; #endif +#if defined(NBUF_MEMORY_DEBUG) +static bool is_initial_mem_debug_disabled; +#endif + +/** + * __qdf_nbuf_get_ip_offset - Get IPV4/V6 header offset + * @data: Pointer to network data buffer + * + * Get the IP header offset in case of 8021Q and 8021AD + * tag is present in L2 header. + * + * Return: IP header offset + */ +static inline uint8_t __qdf_nbuf_get_ip_offset(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); + + if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) + return QDF_NBUF_TRAC_VLAN_IP_OFFSET; + else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD))) + return QDF_NBUF_TRAC_DOUBLE_VLAN_IP_OFFSET; + + return QDF_NBUF_TRAC_IP_OFFSET; +} + +qdf_export_symbol(__qdf_nbuf_get_ip_offset); + +/** + * __qdf_nbuf_get_ether_type - Get the ether type + * @data: Pointer to network data buffer + * + * Get the ether type in case of 8021Q and 8021AD tag + * is present in L2 header, e.g for the returned ether type + * value, if IPV4 data ether type 0x0800, return 0x0008. + * + * Return ether type. + */ +static inline uint16_t __qdf_nbuf_get_ether_type(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); + + if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); + else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD))) + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_DOUBLE_VLAN_ETH_TYPE_OFFSET); + + return ether_type; +} + +qdf_export_symbol(__qdf_nbuf_get_ether_type); + /** * qdf_nbuf_tx_desc_count_display() - Displays the packet counter * @@ -334,7 +394,16 @@ qdf_export_symbol(__qdf_nbuf_count_get); */ void __qdf_nbuf_count_inc(qdf_nbuf_t nbuf) { - qdf_atomic_inc(&nbuf_count); + int num_nbuf = 1; + qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(nbuf); + + /* Take care to account for frag_list */ + while (ext_list) { + ++num_nbuf; + ext_list = qdf_nbuf_queue_next(ext_list); + } + + qdf_atomic_add(num_nbuf, &nbuf_count); } qdf_export_symbol(__qdf_nbuf_count_inc); @@ -347,12 +416,29 @@ qdf_export_symbol(__qdf_nbuf_count_inc); */ void __qdf_nbuf_count_dec(__qdf_nbuf_t nbuf) { - qdf_atomic_dec(&nbuf_count); + qdf_nbuf_t ext_list; + int num_nbuf; + + if (qdf_nbuf_get_users(nbuf) > 1) + return; + + num_nbuf = 1; + + /* Take care to account for frag_list */ + ext_list = qdf_nbuf_get_ext_list(nbuf); + while (ext_list) { + if (qdf_nbuf_get_users(ext_list) == 1) + ++num_nbuf; + ext_list = qdf_nbuf_queue_next(ext_list); + } + + qdf_atomic_sub(num_nbuf, &nbuf_count); } qdf_export_symbol(__qdf_nbuf_count_dec); #endif -#if defined(QCA_WIFI_QCA8074_VP) && defined(BUILD_X86) +#if defined(CONFIG_WIFI_EMULATION_WIFI_3_0) && defined(BUILD_X86) && \ + !defined(QCA_WIFI_QCN9000) struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve, int align, int prio, const char *func, uint32_t line) @@ -529,6 +615,7 @@ enum qdf_nbuf_event_type { QDF_NBUF_FREE, QDF_NBUF_MAP, QDF_NBUF_UNMAP, + QDF_NBUF_ALLOC_COPY_EXPAND, }; struct qdf_nbuf_event { @@ -589,6 +676,9 @@ qdf_nbuf_track_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) { QDF_STATUS status; + if (is_initial_mem_debug_disabled) + return QDF_STATUS_SUCCESS; + status = qdf_tracker_track(&qdf_nbuf_map_tracker, nbuf, func, line); if (QDF_IS_STATUS_ERROR(status)) return status; @@ -601,6 +691,9 @@ qdf_nbuf_track_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) static void qdf_nbuf_untrack_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) { + if (is_initial_mem_debug_disabled) + return; + qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_UNMAP); qdf_tracker_untrack(&qdf_nbuf_map_tracker, nbuf, func, line); } @@ -769,8 +862,8 @@ static void qdf_nbuf_panic_on_free_if_mapped(qdf_nbuf_t nbuf, &map_func, &map_line)) return; - QDF_DEBUG_PANIC("Nbuf freed @ %s:%u while mapped from %s:%u", - func, line, map_func, map_line); + QDF_MEMDEBUG_PANIC("Nbuf freed @ %s:%u while mapped from %s:%u", + func, line, map_func, map_line); } #else static inline void qdf_nbuf_map_tracking_init(void) @@ -1284,12 +1377,21 @@ bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data) { uint16_t sport; uint16_t dport; + uint8_t ipv4_offset; + uint8_t ipv4_hdr_len; + struct iphdr *iphdr; + + if (__qdf_nbuf_get_ether_type(data) != + QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) + return false; + + ipv4_offset = __qdf_nbuf_get_ip_offset(data); + iphdr = (struct iphdr *)(data + ipv4_offset); + ipv4_hdr_len = iphdr->ihl * QDF_NBUF_IPV4_HDR_SIZE_UNIT; - sport = (uint16_t)(*(uint16_t *)(data + QDF_NBUF_TRAC_IPV4_OFFSET + - QDF_NBUF_TRAC_IPV4_HEADER_SIZE)); - dport = (uint16_t)(*(uint16_t *)(data + QDF_NBUF_TRAC_IPV4_OFFSET + - QDF_NBUF_TRAC_IPV4_HEADER_SIZE + - sizeof(uint16_t))); + sport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len); + dport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len + + sizeof(uint16_t)); if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_SRV_PORT)) && (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_CLI_PORT))) || @@ -1314,8 +1416,7 @@ bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data) { uint16_t ether_type; - ether_type = (uint16_t)(*(uint16_t *)(data + - QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); + ether_type = __qdf_nbuf_get_ether_type(data); if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_EAPOL_ETH_TYPE)) return true; @@ -1383,8 +1484,7 @@ bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data) { uint16_t ether_type; - ether_type = (uint16_t)(*(uint16_t *)(data + - QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); + ether_type = __qdf_nbuf_get_ether_type(data); if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_ARP_ETH_TYPE)) return true; @@ -1759,12 +1859,14 @@ bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data) { uint16_t sport; uint16_t dport; + uint8_t ipv6_offset; - sport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET + - QDF_NBUF_TRAC_IPV6_HEADER_SIZE); - dport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET + - QDF_NBUF_TRAC_IPV6_HEADER_SIZE + - sizeof(uint16_t)); + ipv6_offset = __qdf_nbuf_get_ip_offset(data); + sport = *(uint16_t *)(data + ipv6_offset + + QDF_NBUF_TRAC_IPV6_HEADER_SIZE); + dport = *(uint16_t *)(data + ipv6_offset + + QDF_NBUF_TRAC_IPV6_HEADER_SIZE + + sizeof(uint16_t)); if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT)) && (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT))) || @@ -1888,6 +1990,8 @@ bool __qdf_nbuf_data_is_icmp_pkt(uint8_t *data) return false; } +qdf_export_symbol(__qdf_nbuf_data_is_icmp_pkt); + /** * __qdf_nbuf_data_is_icmpv6_pkt() - check if it is IPV6 ICMPV6 packet. * @data: Pointer to IPV6 ICMPV6 packet data buffer @@ -2320,6 +2424,11 @@ void qdf_net_buf_debug_init(void) { uint32_t i; + is_initial_mem_debug_disabled = qdf_mem_debug_config_get(); + + if (is_initial_mem_debug_disabled) + return; + qdf_atomic_set(&qdf_nbuf_history_index, -1); qdf_nbuf_map_tracking_init(); @@ -2349,6 +2458,9 @@ void qdf_net_buf_debug_exit(void) QDF_NBUF_TRACK *p_node; QDF_NBUF_TRACK *p_prev; + if (is_initial_mem_debug_disabled) + return; + for (i = 0; i < QDF_NET_BUF_TRACK_MAX_SIZE; i++) { spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); p_node = gp_qdf_net_buf_track_tbl[i]; @@ -2435,6 +2547,9 @@ void qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf, size_t size, QDF_NBUF_TRACK *p_node; QDF_NBUF_TRACK *new_node; + if (is_initial_mem_debug_disabled) + return; + new_node = qdf_nbuf_track_alloc(); i = qdf_net_buf_debug_hash(net_buf); @@ -2475,6 +2590,9 @@ void qdf_net_buf_debug_update_node(qdf_nbuf_t net_buf, const char *func_name, unsigned long irq_flag; QDF_NBUF_TRACK *p_node; + if (is_initial_mem_debug_disabled) + return; + i = qdf_net_buf_debug_hash(net_buf); spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); @@ -2499,6 +2617,9 @@ void qdf_net_buf_debug_update_map_node(qdf_nbuf_t net_buf, unsigned long irq_flag; QDF_NBUF_TRACK *p_node; + if (is_initial_mem_debug_disabled) + return; + i = qdf_net_buf_debug_hash(net_buf); spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); @@ -2513,6 +2634,8 @@ void qdf_net_buf_debug_update_map_node(qdf_nbuf_t net_buf, spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); } +qdf_export_symbol(qdf_net_buf_debug_update_map_node); + void qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf, const char *func_name, uint32_t line_num) @@ -2521,6 +2644,9 @@ void qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf, unsigned long irq_flag; QDF_NBUF_TRACK *p_node; + if (is_initial_mem_debug_disabled) + return; + i = qdf_net_buf_debug_hash(net_buf); spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); @@ -2535,6 +2661,8 @@ void qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf, spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); } +qdf_export_symbol(qdf_net_buf_debug_update_unmap_node); + /** * qdf_net_buf_debug_delete_node() - remove skb from debug hash table * @@ -2548,6 +2676,9 @@ void qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf) unsigned long irq_flag; QDF_NBUF_TRACK *p_prev; + if (is_initial_mem_debug_disabled) + return; + i = qdf_net_buf_debug_hash(net_buf); spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); @@ -2593,6 +2724,9 @@ void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf, { qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf); + if (is_initial_mem_debug_disabled) + return; + while (ext_list) { /* * Take care to add if it is Jumbo packet connected using @@ -2622,6 +2756,9 @@ void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf) { qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf); + if (is_initial_mem_debug_disabled) + return; + while (ext_list) { /* * Take care to free if it is Jumbo packet connected using @@ -2653,6 +2790,11 @@ qdf_nbuf_t qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size, { qdf_nbuf_t nbuf; + if (is_initial_mem_debug_disabled) + return __qdf_nbuf_alloc(osdev, size, + reserve, align, + prio, func, line); + nbuf = __qdf_nbuf_alloc(osdev, size, reserve, align, prio, func, line); /* Store SKB in internal QDF tracking table */ @@ -2674,6 +2816,9 @@ void qdf_nbuf_free_debug(qdf_nbuf_t nbuf, const char *func, uint32_t line) if (qdf_unlikely(!nbuf)) return; + if (is_initial_mem_debug_disabled) + goto free_buf; + if (qdf_nbuf_get_users(nbuf) > 1) goto free_buf; @@ -2702,6 +2847,9 @@ qdf_nbuf_t qdf_nbuf_clone_debug(qdf_nbuf_t buf, const char *func, uint32_t line) { qdf_nbuf_t cloned_buf = __qdf_nbuf_clone(buf); + if (is_initial_mem_debug_disabled) + return cloned_buf; + if (qdf_unlikely(!cloned_buf)) return NULL; @@ -2717,6 +2865,9 @@ qdf_nbuf_t qdf_nbuf_copy_debug(qdf_nbuf_t buf, const char *func, uint32_t line) { qdf_nbuf_t copied_buf = __qdf_nbuf_copy(buf); + if (is_initial_mem_debug_disabled) + return copied_buf; + if (qdf_unlikely(!copied_buf)) return NULL; @@ -2728,6 +2879,28 @@ qdf_nbuf_t qdf_nbuf_copy_debug(qdf_nbuf_t buf, const char *func, uint32_t line) } qdf_export_symbol(qdf_nbuf_copy_debug); +qdf_nbuf_t +qdf_nbuf_copy_expand_debug(qdf_nbuf_t buf, int headroom, int tailroom, + const char *func, uint32_t line) +{ + qdf_nbuf_t copied_buf = __qdf_nbuf_copy_expand(buf, headroom, tailroom); + + if (qdf_unlikely(!copied_buf)) + return NULL; + + if (is_initial_mem_debug_disabled) + return copied_buf; + + /* Store SKB in internal QDF tracking table */ + qdf_net_buf_debug_add_node(copied_buf, 0, func, line); + qdf_nbuf_history_add(copied_buf, func, line, + QDF_NBUF_ALLOC_COPY_EXPAND); + + return copied_buf; +} + +qdf_export_symbol(qdf_nbuf_copy_expand_debug); + #endif /* NBUF_MEMORY_DEBUG */ #if defined(FEATURE_TSO) @@ -2766,6 +2939,51 @@ struct qdf_tso_cmn_seg_info_t { uint32_t tcp_seq_num; }; +/** + * qdf_nbuf_adj_tso_frag() - adjustment for buffer address of tso fragment + * + * @skb: network buffer + * + * Return: byte offset length of 8 bytes aligned. + */ +#ifdef FIX_TXDMA_LIMITATION +static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb) +{ + uint32_t eit_hdr_len; + uint8_t *eit_hdr; + uint8_t byte_8_align_offset; + + eit_hdr = skb->data; + eit_hdr_len = (skb_transport_header(skb) + - skb_mac_header(skb)) + tcp_hdrlen(skb); + byte_8_align_offset = ((unsigned long)(eit_hdr) + eit_hdr_len) & 0x7L; + if (qdf_unlikely(byte_8_align_offset)) { + TSO_DEBUG("%pK,Len %d %d", + eit_hdr, eit_hdr_len, byte_8_align_offset); + if (unlikely(skb_headroom(skb) < byte_8_align_offset)) { + TSO_DEBUG("[%d]Insufficient headroom,[%pK],[%pK],[%d]", + __LINE__, skb->head, skb->data, + byte_8_align_offset); + return 0; + } + qdf_nbuf_push_head(skb, byte_8_align_offset); + qdf_mem_move(skb->data, + skb->data + byte_8_align_offset, + eit_hdr_len); + skb->len -= byte_8_align_offset; + skb->mac_header -= byte_8_align_offset; + skb->network_header -= byte_8_align_offset; + skb->transport_header -= byte_8_align_offset; + } + return byte_8_align_offset; +} +#else +static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb) +{ + return 0; +} +#endif + /** * __qdf_nbuf_get_tso_cmn_seg_info() - get TSO common * information @@ -2930,18 +3148,21 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb, uint32_t num_seg = 0; struct qdf_tso_seg_elem_t *curr_seg; struct qdf_tso_num_seg_elem_t *total_num_seg; - struct skb_frag_struct *frag = NULL; + skb_frag_t *frag = NULL; uint32_t tso_frag_len = 0; /* tso segment's fragment length*/ uint32_t skb_frag_len = 0; /* skb's fragment length (contiguous memory)*/ uint32_t skb_proc = skb->len; /* bytes of skb pending processing */ uint32_t tso_seg_size = skb_shinfo(skb)->gso_size; int j = 0; /* skb fragment index */ + uint8_t byte_8_align_offset; memset(&tso_cmn_info, 0x0, sizeof(tso_cmn_info)); total_num_seg = tso_info->tso_num_seg_list; curr_seg = tso_info->tso_seg_list; total_num_seg->num_seg.tso_cmn_num_seg = 0; + byte_8_align_offset = qdf_nbuf_adj_tso_frag(skb); + if (qdf_unlikely(__qdf_nbuf_get_tso_cmn_seg_info(osdev, skb, &tso_cmn_info))) { qdf_warn("TSO: error getting common segment info"); @@ -2957,7 +3178,9 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb, skb_proc -= tso_cmn_info.eit_hdr_len; /* get the address to the next tso fragment */ - tso_frag_vaddr = skb->data + tso_cmn_info.eit_hdr_len; + tso_frag_vaddr = skb->data + + tso_cmn_info.eit_hdr_len + + byte_8_align_offset; /* get the length of the next tso fragment */ tso_frag_len = min(skb_frag_len, tso_seg_size); @@ -3185,6 +3408,19 @@ void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev, } qdf_export_symbol(__qdf_nbuf_unmap_tso_segment); +size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb) +{ + size_t packet_len; + + packet_len = skb->len - + ((skb_transport_header(skb) - skb_mac_header(skb)) + + tcp_hdrlen(skb)); + + return packet_len; +} + +qdf_export_symbol(__qdf_nbuf_get_tcp_payload_len); + /** * __qdf_nbuf_get_tso_num_seg() - function to divide a TSO nbuf * into segments @@ -3208,7 +3444,7 @@ uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) uint32_t skb_frag_len = 0; uint32_t eit_hdr_len = (skb_transport_header(skb) - skb_mac_header(skb)) + tcp_hdrlen(skb); - struct skb_frag_struct *frag = NULL; + skb_frag_t *frag = NULL; int j = 0; uint32_t temp_num_seg = 0; @@ -3290,11 +3526,11 @@ uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) return num_segs; } -#else +#elif !defined(QCA_WIFI_QCN9000) uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) { uint32_t i, gso_size, tmp_len, num_segs = 0; - struct skb_frag_struct *frag = NULL; + skb_frag_t *frag = NULL; /* * Check if the head SKB or any of frags are allocated in < 0x50000000 @@ -3319,6 +3555,42 @@ uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) } + gso_size = skb_shinfo(skb)->gso_size; + tmp_len = skb->len - ((skb_transport_header(skb) - skb_mac_header(skb)) + + tcp_hdrlen(skb)); + while (tmp_len) { + num_segs++; + if (tmp_len > gso_size) + tmp_len -= gso_size; + else + break; + } + + return num_segs; + + /* + * Do not free this frame, just do socket level accounting + * so that this is not reused. + */ +fail: + if (skb->sk) + atomic_sub(skb->truesize, &(skb->sk->sk_wmem_alloc)); + + return 0; +} +#else +uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) +{ + uint32_t i, gso_size, tmp_len, num_segs = 0; + skb_frag_t *frag = NULL; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + frag = &skb_shinfo(skb)->frags[i]; + + if (!frag) + goto fail; + } + gso_size = skb_shinfo(skb)->gso_size; tmp_len = skb->len - ((skb_transport_header(skb) - skb_mac_header(skb)) + tcp_hdrlen(skb)); @@ -3984,8 +4256,6 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, return rtap_len; } -#define IEEE80211_RADIOTAP_TX_STATUS 0 -#define IEEE80211_RADIOTAP_RETRY_COUNT 1 /** * This is the length for radiotap, combined length @@ -4004,11 +4274,6 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, #define RADIOTAP_AMPDU_STATUS_LEN (8 + 3) #define RADIOTAP_VENDOR_NS_LEN \ (sizeof(struct qdf_radiotap_vendor_ns_ath) + 1) -/* This is Radio Tap Header Extension Length. - * 4 Bytes for Extended it_present bit map + - * 4 bytes padding for alignment - */ -#define RADIOTAP_HEADER_EXT_LEN (2 * sizeof(uint32_t)) #define RADIOTAP_HEADER_LEN (sizeof(struct ieee80211_radiotap_header) + \ RADIOTAP_FIXED_HEADER_LEN + \ RADIOTAP_HT_FLAGS_LEN + \ @@ -4017,42 +4282,13 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, RADIOTAP_HE_FLAGS_LEN + \ RADIOTAP_HE_MU_FLAGS_LEN + \ RADIOTAP_HE_MU_OTHER_FLAGS_LEN + \ - RADIOTAP_VENDOR_NS_LEN + \ - RADIOTAP_HEADER_EXT_LEN) + RADIOTAP_VENDOR_NS_LEN) #define IEEE80211_RADIOTAP_HE 23 #define IEEE80211_RADIOTAP_HE_MU 24 #define IEEE80211_RADIOTAP_HE_MU_OTHER 25 uint8_t ATH_OUI[] = {0x00, 0x03, 0x7f}; /* Atheros OUI */ -/** - * radiotap_num_to_freq() - Get frequency from chan number - * @chan_num - Input channel number - * - * Return - Channel frequency in Mhz - */ -static uint16_t radiotap_num_to_freq (uint16_t chan_num) -{ - if (chan_num == CHANNEL_NUM_14) - return CHANNEL_FREQ_2484; - if (chan_num < CHANNEL_NUM_14) - return CHANNEL_FREQ_2407 + - (chan_num * FREQ_MULTIPLIER_CONST_5MHZ); - - if (chan_num < CHANNEL_NUM_27) - return CHANNEL_FREQ_2512 + - ((chan_num - CHANNEL_NUM_15) * - FREQ_MULTIPLIER_CONST_20MHZ); - - if (chan_num > CHANNEL_NUM_182 && - chan_num < CHANNEL_NUM_197) - return ((chan_num * FREQ_MULTIPLIER_CONST_5MHZ) + - CHANNEL_FREQ_4000); - - return CHANNEL_FREQ_5000 + - (chan_num * FREQ_MULTIPLIER_CONST_5MHZ); -} - /** * qdf_nbuf_update_radiotap_ampdu_flags() - Update radiotap header ampdu flags * @rx_status: Pointer to rx_status. @@ -4105,14 +4341,6 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, uint32_t rtap_len = rtap_hdr_len; uint8_t length = rtap_len; struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath; - uint32_t *rtap_ext = NULL; - - /* Adding Extended Header space */ - if (rx_status->add_rtap_ext) { - rtap_hdr_len += RADIOTAP_HEADER_EXT_LEN; - rtap_len = rtap_hdr_len; - } - length = rtap_len; /* IEEE80211_RADIOTAP_TSFT __le64 microseconds*/ rthdr->it_present = (1 << IEEE80211_RADIOTAP_TSFT); @@ -4139,11 +4367,10 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, /* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap */ rthdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL); - rx_status->chan_freq = radiotap_num_to_freq(rx_status->chan_num); put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]); rtap_len += 2; /* Channel flags. */ - if (rx_status->chan_num > CHANNEL_NUM_35) + if (rx_status->chan_freq > CHANNEL_FREQ_5150) rx_status->chan_flags = RADIOTAP_5G_SPECTRUM_CHANNEL; else rx_status->chan_flags = RADIOTAP_2G_SPECTRUM_CHANNEL; @@ -4297,20 +4524,6 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, cpu_to_le32(rx_status->ppdu_timestamp); rtap_len += sizeof(*radiotap_vendor_ns_ath); - /* Add Extension to Radiotap Header & corresponding data */ - if (rx_status->add_rtap_ext) { - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT); - rtap_ext = (uint32_t *)&rthdr->it_present; - rtap_ext++; - *rtap_ext = cpu_to_le32(1 << IEEE80211_RADIOTAP_TX_STATUS); - *rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RETRY_COUNT); - - rtap_buf[rtap_len] = rx_status->tx_status; - rtap_len += 1; - rtap_buf[rtap_len] = rx_status->tx_retry_cnt; - rtap_len += 1; - } - rthdr->it_len = cpu_to_le16(rtap_len); rthdr->it_present = cpu_to_le32(rthdr->it_present); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_periodic_work.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_periodic_work.c index 15aeb3435e1c7283b3cd591dd1b0d0210a212cbf..a845ed18ea3a4e892f3cad335738c71ca05c1406 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_periodic_work.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_periodic_work.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -97,7 +97,7 @@ QDF_STATUS __qdf_periodic_work_create(struct qdf_periodic_work *pwork, if (QDF_IS_STATUS_ERROR(status)) return status; - INIT_DELAYED_WORK(&pwork->dwork, __qdf_periodic_work_handler); + INIT_DEFERRABLE_WORK(&pwork->dwork, __qdf_periodic_work_handler); pwork->callback = callback; pwork->context = context; pwork->msec = 0; diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_streamfs.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_streamfs.c new file mode 100644 index 0000000000000000000000000000000000000000..25f58a33235aa60dad7fbc4dd9aae03a54da2a84 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_streamfs.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: qdf_streamfs + * This file provides QDF stream file system APIs + */ + +#include +#include +#include +#include + +/** + * qdf_create_buf_file_handler() - Create streamfs buffer file + * @filename: base name of files to create, NULL for buffering only + * @parent: dentry of parent directory, NULL for root directory + * @mode: filemode + * @buf: streamfs channel buf + * @is_global: pointer to set whether this buf file is global or not. + * + * Returns dentry if successful, NULL otherwise. + */ +static qdf_dentry_t +qdf_create_buf_file_handler(const char *filename, qdf_dentry_t parent, + uint16_t mode, qdf_streamfs_chan_buf_t buf, + int32_t *is_global) +{ + qdf_dentry_t buf_file; + *is_global = 1; + buf_file = qdf_streamfs_create_file(filename, mode, parent, buf); + + if (!buf_file) + return NULL; + + return buf_file; +} + +/** + * qdf_remove_buf_file_handler() - Remove streamfs buffer file + * @dentry:dentry + */ +static int qdf_remove_buf_file_handler(qdf_dentry_t dentry) +{ + qdf_streamfs_remove_file(dentry); + + return 0; +} + +static struct rchan_callbacks g_qdf_streamfs_cb = { + .create_buf_file = qdf_create_buf_file_handler, + .remove_buf_file = qdf_remove_buf_file_handler, +}; + +qdf_dentry_t +qdf_streamfs_create_file(const char *name, uint16_t mode, + qdf_dentry_t parent, + qdf_streamfs_chan_buf_t buf) +{ + qdf_dentry_t file = NULL; + + if (!name) + return NULL; + + file = debugfs_create_file(name, mode, + (struct dentry *)parent, + buf, &relay_file_operations); + + return file; +} + +qdf_export_symbol(qdf_streamfs_create_file); + +qdf_streamfs_chan_t +qdf_streamfs_open(const char *base_filename, qdf_dentry_t parent, + size_t subbuf_size, size_t n_subbufs, + void *private_data) +{ + qdf_streamfs_chan_t channel_ptr = NULL; + + channel_ptr = relay_open(base_filename, + (struct dentry *)parent, + subbuf_size, n_subbufs, + &g_qdf_streamfs_cb, + private_data); + + return channel_ptr; +} + +qdf_export_symbol(qdf_streamfs_open); + +void qdf_streamfs_close(qdf_streamfs_chan_t chan) +{ + if (chan) + relay_close(chan); +} + +qdf_export_symbol(qdf_streamfs_close); + +void qdf_streamfs_flush(qdf_streamfs_chan_t chan) +{ + if (chan) + relay_flush(chan); +} + +qdf_export_symbol(qdf_streamfs_flush); + +void qdf_streamfs_reset(qdf_streamfs_chan_t chan) +{ + if (chan) + relay_reset(chan); +} + +qdf_export_symbol(qdf_streamfs_reset); + +void qdf_streamfs_subbufs_consumed(qdf_streamfs_chan_t chan, + unsigned int cpu, + size_t consumed) +{ + if (chan) + relay_subbufs_consumed(chan, cpu, consumed); +} + +qdf_export_symbol(qdf_streamfs_subbufs_consumed); + +void qdf_streamfs_write(qdf_streamfs_chan_t chan, + const void *data, + size_t length) +{ + if (chan) + relay_write(chan, data, length); +} + +qdf_export_symbol(qdf_streamfs_write); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c index 8ec0963b0036057917b23d923667a30eb3fb2d5f..2e6463e737133db456387eba84e2d8d3789e1a14 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_threads.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -106,7 +106,7 @@ void qdf_busy_wait(uint32_t us_interval) } qdf_export_symbol(qdf_busy_wait); -#ifdef MSM_PLATFORM +#ifdef PF_WAKE_UP_IDLE void qdf_set_wake_up_idle(bool idle) { set_wake_up_idle(idle); @@ -115,7 +115,7 @@ void qdf_set_wake_up_idle(bool idle) void qdf_set_wake_up_idle(bool idle) { } -#endif /* MSM_PLATFORM */ +#endif /* PF_WAKE_UP_IDLE */ qdf_export_symbol(qdf_set_wake_up_idle); @@ -187,10 +187,29 @@ qdf_export_symbol(qdf_wake_up_process); * 2) arm architectures in kernel versions >=4.14 * 3) backported kernels defining BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK_ARM */ -#if (defined(WLAN_HOST_ARCH_ARM) && !WLAN_HOST_ARCH_ARM) || \ +#if ((defined(WLAN_HOST_ARCH_ARM) && !WLAN_HOST_ARCH_ARM) || \ LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || \ - defined(BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK_ARM) + defined(BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK_ARM)) && \ + defined(CONFIG_STACKTRACE) && !defined(CONFIG_ARCH_STACKWALK) #define QDF_PRINT_TRACE_COUNT 32 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)) +void qdf_print_thread_trace(qdf_thread_t *thread) +{ + const int spaces = 4; + struct task_struct *task = thread; + unsigned long entries[QDF_PRINT_TRACE_COUNT] = {0}; + struct stack_trace trace = { + .nr_entries = 0, + .skip = 0, + .entries = &entries[0], + .max_entries = QDF_PRINT_TRACE_COUNT, + }; + + save_stack_trace_tsk(task, &trace); + stack_trace_print(entries, trace.nr_entries, spaces); +} +#else void qdf_print_thread_trace(qdf_thread_t *thread) { const int spaces = 4; @@ -206,6 +225,8 @@ void qdf_print_thread_trace(qdf_thread_t *thread) save_stack_trace_tsk(task, &trace); print_stack_trace(&trace, spaces); } +#endif + #else void qdf_print_thread_trace(qdf_thread_t *thread) { } #endif /* KERNEL_VERSION(4, 14, 0) */ @@ -257,3 +278,18 @@ void qdf_cpumask_setall(qdf_cpu_mask *dstp) } qdf_export_symbol(qdf_cpumask_setall); + +bool qdf_cpumask_empty(const struct cpumask *srcp) +{ + return cpumask_empty(srcp); +} + +qdf_export_symbol(qdf_cpumask_empty); + +void qdf_cpumask_copy(struct cpumask *dstp, + const struct cpumask *srcp) +{ + return cpumask_copy(dstp, srcp); +} + +qdf_export_symbol(qdf_cpumask_copy); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c index e6f5323683624e9cca000e87adddd44182b523f6..681046ad804ac9e249605d85d3f99cf84512ea12 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -157,22 +157,8 @@ qdf_export_symbol(qdf_vtrace_msg); /* Buffer size = data bytes(2 hex chars plus space) + NULL */ #define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1) -/** - * qdf_trace_hex_dump() - externally called hex dump function - * @module: Module identifier a member of the QDF_MODULE_ID enumeration that - * identifies the module issuing the trace message. - * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration indicating - * the severity of the condition causing the trace message to be - * issued. More severe conditions are more likely to be logged. - * @data: The base address of the buffer to be logged. - * @buf_len: The size of the buffer to be logged. - * - * Checks the level of severity and accordingly prints the trace messages - * - * Return: None - */ -void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, - void *data, int buf_len) +static void __qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + void *data, int buf_len, bool print_ascii) { const u8 *ptr = data; int i = 0; @@ -187,15 +173,30 @@ void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, buf_len -= ROW_SIZE; hex_dump_to_buffer(ptr, linelen, ROW_SIZE, 1, - linebuf, sizeof(linebuf), false); + linebuf, sizeof(linebuf), print_ascii); qdf_trace_msg(module, level, "%.8x: %s", i, linebuf); ptr += ROW_SIZE; i += ROW_SIZE; } } + +void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + void *data, int buf_len) +{ + __qdf_trace_hex_dump(module, level, data, buf_len, false); +} + qdf_export_symbol(qdf_trace_hex_dump); +void qdf_trace_hex_ascii_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, + void *data, int buf_len) +{ + __qdf_trace_hex_dump(module, level, data, buf_len, true); +} + +qdf_export_symbol(qdf_trace_hex_ascii_dump); + #endif #ifdef TRACE_RECORD @@ -692,7 +693,7 @@ static void qdf_dp_unused(struct qdf_dp_trace_record_s *record, */ void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, uint16_t time_limit, uint8_t verbosity, - uint8_t proto_bitmap) + uint32_t proto_bitmap) { uint8_t i; @@ -739,6 +740,8 @@ void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, qdf_dp_display_proto_pkt; qdf_dp_trace_cb_table[QDF_DP_TRACE_MGMT_PACKET_RECORD] = qdf_dp_display_mgmt_pkt; + qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_CREDIT_RECORD] = + qdf_dp_display_credit_record; qdf_dp_trace_cb_table[QDF_DP_TRACE_EVENT_RECORD] = qdf_dp_display_event_record; @@ -765,7 +768,7 @@ void qdf_dp_trace_deinit(void) * * Return: None */ -void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_record, +void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_record, uint8_t verbosity) { g_qdf_dp_trace_data.proto_bitmap = proto_bitmap; @@ -891,7 +894,7 @@ static bool qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code) * * Return: proto bitmap */ -uint8_t qdf_dp_get_proto_bitmap(void) +uint32_t qdf_dp_get_proto_bitmap(void) { if (g_qdf_dp_trace_data.enable) return g_qdf_dp_trace_data.proto_bitmap; @@ -992,6 +995,8 @@ const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code) return "ICMPv6:"; case QDF_DP_TRACE_MGMT_PACKET_RECORD: return "MGMT:"; + case QDF_DP_TRACE_TX_CREDIT_RECORD: + return "CREDIT:"; case QDF_DP_TRACE_EVENT_RECORD: return "EVENT:"; case QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD: @@ -1068,6 +1073,39 @@ static const char *qdf_dp_dir_to_str(enum qdf_proto_dir dir) } } +static const char *qdf_dp_credit_source_to_str( + enum QDF_CREDIT_UPDATE_SOURCE source) +{ + switch (source) { + case QDF_TX_SCHED: + return "TX SCHED"; + case QDF_TX_COMP: + return "TX COMP"; + case QDF_TX_CREDIT_UPDATE: + return "CREDIT UP"; + case QDF_TX_HTT_MSG: + return "HTT TX MSG"; + case QDF_HTT_ATTACH: + return "HTT ATTACH"; + default: + return "invalid"; + } +} + +static const char *qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op) +{ + switch (op) { + case QDF_CREDIT_INC: + return "+"; + case QDF_CREDIT_DEC: + return "-"; + case QDF_CREDIT_ABS: + return "ABS"; + default: + return "invalid"; + } +} + /** * qdf_dp_type_to_str() - convert packet type to string * @type: type @@ -1519,13 +1557,15 @@ void qdf_dp_log_proto_pkt_info(uint8_t *sa, uint8_t *da, uint8_t type, last_ticks_rx[subtype] = curr_ticks; if (status == QDF_TX_RX_STATUS_INVALID) - qdf_nofl_info("%s %s: SA:%pM DA:%pM", + qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT, qdf_get_pkt_type_string(type, subtype), - dir ? "RX":"TX", sa, da); + dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa), + QDF_MAC_ADDR_REF(da)); else - qdf_nofl_info("%s %s: SA:%pM DA:%pM msdu_id:%d status: %s", + qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT " msdu_id:%d status: %s", qdf_get_pkt_type_string(type, subtype), - dir ? "RX":"TX", sa, da, msdu_id, + dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa), + QDF_MAC_ADDR_REF(da), msdu_id, qdf_get_pkt_status_string(status)); } @@ -1898,6 +1938,91 @@ void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, } qdf_export_symbol(qdf_dp_trace_mgmt_pkt); +static void +qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file, + struct qdf_dp_trace_record_s *record, + uint32_t index) +{ + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; + struct qdf_dp_trace_credit_record *buf = + (struct qdf_dp_trace_credit_record *)record->data; + + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); + if (buf->operation == QDF_OP_NA) + qdf_debugfs_printf(file, "%s [%s] [T: %d G0: %d G1: %d]\n", + prepend_str, + qdf_dp_credit_source_to_str(buf->source), + buf->total_credits, buf->g0_credit, + buf->g1_credit); + else + qdf_debugfs_printf(file, + "%s [%s] [T: %d G0: %d G1: %d] [%s %d]\n", + prepend_str, + qdf_dp_credit_source_to_str(buf->source), + buf->total_credits, buf->g0_credit, + buf->g1_credit, + qdf_dp_operation_to_str(buf->operation), + buf->delta); +} + +void qdf_dp_display_credit_record(struct qdf_dp_trace_record_s *record, + uint16_t index, uint8_t pdev_id, uint8_t info) +{ + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; + struct qdf_dp_trace_credit_record *buf = + (struct qdf_dp_trace_credit_record *)record->data; + + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); + if (buf->operation == QDF_OP_NA) + DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d]", + prepend_str, + qdf_dp_credit_source_to_str(buf->source), + buf->total_credits, buf->g0_credit, + buf->g1_credit); + else + DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d] [%s %d]", + prepend_str, + qdf_dp_credit_source_to_str(buf->source), + buf->total_credits, buf->g0_credit, + buf->g1_credit, + qdf_dp_operation_to_str(buf->operation), + buf->delta); +} + +void qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source, + enum QDF_CREDIT_OPERATION operation, + int delta, int total_credits, + int g0_credit, int g1_credit) +{ + struct qdf_dp_trace_credit_record buf; + int buf_size = sizeof(struct qdf_dp_trace_credit_record); + enum QDF_DP_TRACE_ID code = QDF_DP_TRACE_TX_CREDIT_RECORD; + + if (qdf_dp_enable_check(NULL, code, QDF_NA) == false) + return; + + if (!(qdf_dp_get_proto_bitmap() & QDF_HL_CREDIT_TRACKING)) + return; + + if (buf_size > QDF_DP_TRACE_RECORD_SIZE) + QDF_BUG(0); + + buf.source = source; + buf.operation = operation; + buf.delta = delta; + buf.total_credits = total_credits; + buf.g0_credit = g0_credit; + buf.g1_credit = g1_credit; + + qdf_dp_add_record(code, QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)&buf, + buf_size, NULL, 0, false); +} +qdf_export_symbol(qdf_dp_trace_credit_record); + void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, uint16_t index, uint8_t pdev_id, uint8_t info) { @@ -1961,14 +2086,14 @@ void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), index, info, record); DPTRACE_PRINT("%s [%d] [%s] SA: " - QDF_MAC_ADDR_STR " %s DA: " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT " %s DA: " + QDF_MAC_ADDR_FMT, prepend_str, buf->vdev_id, qdf_dp_subtype_to_str(buf->subtype), - QDF_MAC_ADDR_ARRAY(buf->sa.bytes), + QDF_MAC_ADDR_REF(buf->sa.bytes), qdf_dp_dir_to_str(buf->dir), - QDF_MAC_ADDR_ARRAY(buf->da.bytes)); + QDF_MAC_ADDR_REF(buf->da.bytes)); } qdf_export_symbol(qdf_dp_display_proto_pkt); @@ -2423,14 +2548,14 @@ static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file, loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), index, 0, record); qdf_debugfs_printf(file, "%s [%d] [%s] SA: " - QDF_MAC_ADDR_STR " %s DA: " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT " %s DA: " + QDF_MAC_ADDR_FMT, prepend_str, buf->vdev_id, qdf_dp_subtype_to_str(buf->subtype), - QDF_MAC_ADDR_ARRAY(buf->sa.bytes), + QDF_MAC_ADDR_REF(buf->sa.bytes), qdf_dp_dir_to_str(buf->dir), - QDF_MAC_ADDR_ARRAY(buf->da.bytes)); + QDF_MAC_ADDR_REF(buf->da.bytes)); qdf_debugfs_printf(file, "\n"); } @@ -2685,6 +2810,11 @@ QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file, qdf_dpt_display_proto_pkt_debugfs(file, &p_record, i); break; + case QDF_DP_TRACE_TX_CREDIT_RECORD: + qdf_dpt_display_credit_record_debugfs(file, &p_record, + i); + break; + case QDF_DP_TRACE_MGMT_PACKET_RECORD: qdf_dpt_display_mgmt_pkt_debugfs(file, &p_record, i); break; @@ -3026,8 +3156,13 @@ struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = { [QDF_MODULE_ID_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"}, [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"}, [QDF_MODULE_ID_BLACKLIST_MGR] = {"blm"}, - [QDF_MODULE_ID_PKT_CAPTURE] = {"pkt_capture"}, + [QDF_MODULE_ID_QLD] = {"QLD"}, + [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = {"Dynamic Mode Change"}, + [QDF_MODULE_ID_COEX] = {"COEX"}, + [QDF_MODULE_ID_MON_FILTER] = {"Monitor Filter"}, [QDF_MODULE_ID_ANY] = {"ANY"}, + [QDF_MODULE_ID_PKT_CAPTURE] = {"pkt_capture"}, + [QDF_MODULE_ID_GPIO] = {"GPIO_CFG"}, }; qdf_export_symbol(g_qdf_category_name); @@ -3265,8 +3400,6 @@ int qdf_print_ctrl_register(const struct category_info *cinfo, } } - pr_info("%s: Allocated print control object %d\n", - __func__, idx); return idx; } qdf_export_symbol(qdf_print_ctrl_register); @@ -3282,7 +3415,7 @@ qdf_export_symbol(qdf_shared_print_ctrl_cleanup); * Set this to invalid value to differentiate with user-provided * value. */ -int qdf_dbg_mask = 0; +int qdf_dbg_mask = QDF_TRACE_LEVEL_MAX; qdf_export_symbol(qdf_dbg_mask); qdf_declare_param(qdf_dbg_mask, int); @@ -3449,7 +3582,7 @@ static void set_default_trace_levels(struct category_info *cinfo) [QDF_MODULE_ID_SOC] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_OS_IF] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_TARGET_IF] = QDF_TRACE_LEVEL_INFO, - [QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_NONE, + [QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_FATAL, [QDF_MODULE_ID_MGMT_TXRX] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_SERIALIZATION] = QDF_TRACE_LEVEL_ERROR, [QDF_MODULE_ID_PMO] = QDF_TRACE_LEVEL_NONE, @@ -3485,8 +3618,13 @@ static void set_default_trace_levels(struct category_info *cinfo) [QDF_MODULE_ID_TX_CAPTURE] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_BLACKLIST_MGR] = QDF_TRACE_LEVEL_NONE, - [QDF_MODULE_ID_PKT_CAPTURE] = QDF_TRACE_LEVEL_NONE, + [QDF_MODULE_ID_QLD] = QDF_TRACE_LEVEL_ERROR, + [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = QDF_TRACE_LEVEL_INFO, + [QDF_MODULE_ID_COEX] = QDF_TRACE_LEVEL_ERROR, + [QDF_MODULE_ID_MON_FILTER] = QDF_TRACE_LEVEL_INFO, [QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO, + [QDF_MODULE_ID_PKT_CAPTURE] = QDF_TRACE_LEVEL_NONE, + [QDF_MODULE_ID_GPIO] = QDF_TRACE_LEVEL_NONE, }; for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { @@ -3505,14 +3643,14 @@ void qdf_shared_print_ctrl_init(void) /* * User specified across-module single debug level */ - if ((qdf_dbg_mask > 0) && (qdf_dbg_mask <= QDF_TRACE_LEVEL_MAX)) { + if ((qdf_dbg_mask >= 0) && (qdf_dbg_mask < QDF_TRACE_LEVEL_MAX)) { pr_info("User specified module debug level of %d\n", qdf_dbg_mask); for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { cinfo[i].category_verbose_mask = set_cumulative_verbose_mask(qdf_dbg_mask); } - } else { + } else if (qdf_dbg_mask != QDF_TRACE_LEVEL_MAX) { pr_info("qdf_dbg_mask value is invalid\n"); pr_info("Using the default module debug levels instead\n"); } @@ -3766,7 +3904,7 @@ qdf_export_symbol(QDF_PRINT_INFO); void qdf_logging_init(void) { wlan_logging_sock_init_svc(); - nl_srv_init(NULL); + nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY); wlan_logging_set_flush_timer(qdf_log_flush_timer_period); } @@ -3792,7 +3930,7 @@ void qdf_logging_flush_logs(void) #else void qdf_logging_init(void) { - nl_srv_init(NULL); + nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY); } void qdf_logging_exit(void) diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_hang_event_notifier.c b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_hang_event_notifier.c new file mode 100644 index 0000000000000000000000000000000000000000..09b1761b65179b47fc63bd3b27bfe2cd6011fb86 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_hang_event_notifier.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + + /** + * DOC: qdf_hang_event_notifier + * This file provides OS dependent QDF notifier call for hang event + */ + +#include +#include +#include + +static qdf_atomic_notifier_init(qdf_hang_event_notif_head) + +QDF_STATUS qdf_hang_event_register_notifier(qdf_notif_block *nb) +{ + return qdf_register_atomic_notifier_chain(&qdf_hang_event_notif_head, + nb); +} + +QDF_STATUS qdf_hang_event_unregister_notifier(qdf_notif_block *nb) +{ + return qdf_unregister_atomic_notifier_chain(&qdf_hang_event_notif_head, + nb); +} + +QDF_STATUS qdf_hang_event_notifier_call(unsigned long v, void *data) +{ + return qdf_atomic_notfier_call(&qdf_hang_event_notif_head, + v, data); +} diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_notifier.c b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_notifier.c new file mode 100644 index 0000000000000000000000000000000000000000..6351831e98ff24d8baa06679d4bbd2e6686797bd --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_notifier.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ +#include +#include +#include + +QDF_STATUS qdf_register_blocking_notifier_chain(qdf_blocking_notif_head *head, + qdf_notif_block *qnb) +{ + int ret; + + ret = __qdf_register_blocking_notifier_chain(head, &qnb->notif_block); + + return qdf_status_from_os_return(ret); +} + +QDF_STATUS qdf_unregister_blocking_notifier_chain(qdf_blocking_notif_head *head, + qdf_notif_block *qnb) +{ + int ret; + + ret = __qdf_unregister_blocking_notifier_chain(head, + &qnb->notif_block); + + return qdf_status_from_os_return(ret); +} + +QDF_STATUS qdf_blocking_notfier_call(qdf_blocking_notif_head *head, + unsigned long state, void *data) +{ + int ret; + + ret = __qdf_blocking_notfier_call(head, state, data); + + return qdf_status_from_os_return(ret); +} + +QDF_STATUS qdf_register_atomic_notifier_chain(qdf_atomic_notif_head *head, + qdf_notif_block *qnb) +{ + int ret; + + ret = __qdf_register_atomic_notifier_chain(head, &qnb->notif_block); + + return qdf_status_from_os_return(ret); +} + +QDF_STATUS qdf_unregister_atomic_notifier_chain(qdf_atomic_notif_head *head, + qdf_notif_block *qnb) +{ + int ret; + + ret = __qdf_unregister_atomic_notifier_chain(head, &qnb->notif_block); + + return qdf_status_from_os_return(ret); +} + +QDF_STATUS qdf_atomic_notfier_call(qdf_atomic_notif_head *head, + unsigned long v, void *data) +{ + int ret; + + ret = __qdf_atomic_notifier_call(head, v, data); + + return qdf_status_from_os_return(ret); +} diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_parse.c b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_parse.c index 577f8eedaea575d4fe17744554e201fe7359ef07..469d59a4fdf10ce4feedecd0e657fe51d9bd0a0c 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_parse.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_parse.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +30,7 @@ QDF_STATUS qdf_ini_parse(const char *ini_path, void *context, QDF_STATUS status; char *fbuf; char *cursor; + int ini_read_count = 0; status = qdf_file_read(ini_path, &fbuf); if (QDF_IS_STATUS_ERROR(status)) { @@ -99,6 +100,8 @@ QDF_STATUS qdf_ini_parse(const char *ini_path, void *context, status = item_cb(context, key, value); if (QDF_IS_STATUS_ERROR(status)) goto free_fbuf; + else + ini_read_count++; } else if (key[0] == '[') { qdf_size_t len = qdf_str_len(key); @@ -119,7 +122,11 @@ QDF_STATUS qdf_ini_parse(const char *ini_path, void *context, cursor++; } - status = QDF_STATUS_SUCCESS; + qdf_debug("INI values read: %d", ini_read_count); + if (ini_read_count != 0) + status = QDF_STATUS_SUCCESS; + else + status = QDF_STATUS_E_FAILURE; free_fbuf: qdf_file_buf_free(fbuf); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_platform.c b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_platform.c index 2a9bf2c769cd89b9fb1d209cbab063fe53327398..f1e486da74203a9c7e22fe70b9a22583eaed748b 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_platform.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_platform.c @@ -30,6 +30,11 @@ static qdf_is_driver_unloading_callback is_driver_unloading_cb; static qdf_is_recovering_callback is_recovering_cb; static qdf_is_drv_connected_callback is_drv_connected_cb; static qdf_wmi_send_over_qmi_callback _wmi_send_recv_qmi_cb; +static qdf_is_drv_supported_callback is_drv_supported_cb; +static qdf_recovery_reason_update_callback update_recovery_reason_cb; +static qdf_bus_reg_dump get_bus_reg_dump; + + void qdf_register_fw_down_callback(qdf_is_fw_down_callback is_fw_down) { @@ -87,11 +92,11 @@ void qdf_register_self_recovery_callback(qdf_self_recovery_callback callback) qdf_export_symbol(qdf_register_self_recovery_callback); -void __qdf_trigger_self_recovery(enum qdf_hang_reason reason, +void __qdf_trigger_self_recovery(void *psoc, enum qdf_hang_reason reason, const char *func, const uint32_t line) { if (self_recovery_cb) - self_recovery_cb(reason, func, line); + self_recovery_cb(psoc, reason, func, line); else QDF_DEBUG_PANIC_FL(func, line, ""); } @@ -175,3 +180,57 @@ void qdf_check_state_before_panic(void) qdf_export_symbol(qdf_check_state_before_panic); +void qdf_register_drv_supported_callback(qdf_is_drv_supported_callback + is_drv_supported) +{ + is_drv_supported_cb = is_drv_supported; +} + +qdf_export_symbol(qdf_register_drv_supported_callback); + +bool qdf_is_drv_supported(void) +{ + if (!is_drv_supported_cb) { + qdf_err("drv supported callback is not registered"); + return false; + } + + return is_drv_supported_cb(); +} + +qdf_export_symbol(qdf_is_drv_supported); + +void qdf_register_recovery_reason_update(qdf_recovery_reason_update_callback + callback) +{ + update_recovery_reason_cb = callback; +} + +qdf_export_symbol(qdf_register_recovery_reason_update); + +void qdf_recovery_reason_update(enum qdf_hang_reason reason) +{ + if (!update_recovery_reason_cb) + return; + + update_recovery_reason_cb(reason); +} + +qdf_export_symbol(qdf_recovery_reason_update); + +void qdf_register_get_bus_reg_dump(qdf_bus_reg_dump callback) +{ + get_bus_reg_dump = callback; +} + +qdf_export_symbol(qdf_register_get_bus_reg_dump); + +void qdf_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len) +{ + if (!get_bus_reg_dump) + return; + + get_bus_reg_dump(dev, buf, len); +} + +qdf_export_symbol(qdf_get_bus_reg_dump); diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_types.c b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_types.c index 8f645c74f347a3d926b55dadd7668fd5e99e48a7..86325250d25e8bd533676dfefd36316a358d7c30 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_types.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/src/qdf_types.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -616,6 +617,55 @@ QDF_STATUS qdf_ipv6_parse(const char *ipv6_str, struct qdf_ipv6_addr *out_addr) } qdf_export_symbol(qdf_ipv6_parse); +QDF_STATUS qdf_uint32_array_parse(const char *in_str, uint32_t *out_array, + qdf_size_t array_size, qdf_size_t *out_size) +{ + QDF_STATUS status; + bool negate; + qdf_size_t size = 0; + uint64_t value; + + QDF_BUG(in_str); + if (!in_str) + return QDF_STATUS_E_INVAL; + + QDF_BUG(out_array); + if (!out_array) + return QDF_STATUS_E_INVAL; + + QDF_BUG(out_size); + if (!out_size) + return QDF_STATUS_E_INVAL; + + while (size < array_size) { + status = __qdf_int_parse_lazy(&in_str, &value, &negate); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + if ((uint32_t)value != value || negate) + return QDF_STATUS_E_RANGE; + + in_str = qdf_str_left_trim(in_str); + + switch (in_str[0]) { + case ',': + out_array[size++] = value; + in_str++; + break; + case '\0': + out_array[size++] = value; + *out_size = size; + return QDF_STATUS_SUCCESS; + default: + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_E_FAILURE; +} + +qdf_export_symbol(qdf_uint32_array_parse); + QDF_STATUS qdf_uint16_array_parse(const char *in_str, uint16_t *out_array, qdf_size_t array_size, qdf_size_t *out_size) { diff --git a/drivers/staging/qca-wifi-host-cmn/qdf/test/qdf_types_test.c b/drivers/staging/qca-wifi-host-cmn/qdf/test/qdf_types_test.c index c19393ad318ab49a98fb010ca6a43b80d3a0b645..d833a76e6515128d9fdaedc71af7663ffb804387 100644 --- a/drivers/staging/qca-wifi-host-cmn/qdf/test/qdf_types_test.c +++ b/drivers/staging/qca-wifi-host-cmn/qdf/test/qdf_types_test.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -161,6 +162,153 @@ static uint32_t qdf_types_ut_int64_parse(void) return errors; } +#define ut_uint16_array_pass(str, max_size, exp_arr, exp_arr_size) \ +__ut_uint16_array(str, QDF_STATUS_SUCCESS, max_size, exp_arr, exp_arr_size) + +#define ut_uint16_array_fail(str, max_size, exp_status, exp_arr, exp_arr_size)\ +__ut_uint16_array(str, exp_status, max_size, exp_arr, exp_arr_size) + +static uint32_t +__ut_uint16_array(const char *str, QDF_STATUS exp_status, + uint8_t max_array_size, uint16_t *exp_array, + uint8_t exp_array_size) +{ + uint16_t parsed_array[10]; + qdf_size_t parsed_array_size; + QDF_STATUS status; + uint8_t i; + + status = qdf_uint16_array_parse(str, parsed_array, max_array_size, + &parsed_array_size); + + if (status != exp_status) { + qdf_nofl_alert("FAIL: qdf_uint16_array_parse(\"%s\") -> status %d; expected status %d", + str, status, exp_status); + return 1; + } + + if (QDF_IS_STATUS_ERROR(status)) + return 0; + + if (parsed_array_size != exp_array_size) { + qdf_nofl_alert("FAIL: qdf_uint16_array_parse(\"%s\") -> parsed_array_size %zu; exp_array_size %d", + str, parsed_array_size, exp_array_size); + return 1; + } + + for (i = 0; i < exp_array_size; i++) + if (parsed_array[i] != exp_array[i]) { + qdf_nofl_alert("FAIL: qdf_uint16_array_parse(\"%s\") -> parsed_array[%d] %d; exp_array[%d] %d", + str, i, parsed_array[i], i, + exp_array[i]); + return 1; + } + + return 0; +} + +static uint32_t qdf_types_ut_uint16_array_parse(void) +{ + uint32_t errors = 0; + uint16_t exp_array_value[10] = { + 1, 10, 2412, 2417, 100, 65535, 0, 5486, 5180, 9999}; + + errors += ut_uint16_array_pass( + "1, 10, 2412, 2417, 100, 65535, 0, 5486, 5180, 9999", + 10, exp_array_value, 10); + errors += ut_uint16_array_pass( + "+1, +10, +2412, +2417, +100, +65535, 0, +5486, +5180, +9999", + 10, exp_array_value, 10); + errors += ut_uint16_array_fail("1;", 10, QDF_STATUS_E_FAILURE, + exp_array_value, 0); + /* Out of range test where 65536 is out of range */ + errors += ut_uint16_array_fail( + "1, 10, 2412, 2417, 100, 65536, 0, 5486, 5180, 9999", + 10, QDF_STATUS_E_RANGE, exp_array_value, 0); + errors += ut_uint16_array_fail( + "-1, -10, -2412, -2417, -100, -65535, 0, -5486, -5180, -9999", + 10, QDF_STATUS_E_RANGE, exp_array_value, 0); + errors += ut_uint16_array_fail( + "1, 10, 2412, 2417, 100, 日本, 0, 5486, 5180, 9999", + 10, QDF_STATUS_E_FAILURE, exp_array_value, 0); + + return errors; +} + +#define ut_uint32_array_pass(str, max_size, exp_arr, exp_arr_size) \ +__ut_uint32_array(str, QDF_STATUS_SUCCESS, max_size, exp_arr, exp_arr_size) + +#define ut_uint32_array_fail(str, max_size, exp_status, exp_arr, exp_arr_size)\ +__ut_uint32_array(str, exp_status, max_size, exp_arr, exp_arr_size) + +static uint32_t +__ut_uint32_array(const char *str, QDF_STATUS exp_status, + uint8_t max_array_size, uint32_t *exp_array, + uint8_t exp_array_size) +{ + uint32_t parsed_array[10]; + qdf_size_t parsed_array_size; + QDF_STATUS status; + uint8_t i; + + status = qdf_uint32_array_parse(str, parsed_array, max_array_size, + &parsed_array_size); + + if (status != exp_status) { + qdf_nofl_alert("FAIL: qdf_uint32_array_parse(\"%s\") -> status %d; expected status %d", + str, status, exp_status); + return 1; + } + + if (QDF_IS_STATUS_ERROR(status)) + return 0; + + if (parsed_array_size != exp_array_size) { + qdf_nofl_alert("FAIL: qdf_uint32_array_parse(\"%s\") -> parsed_array_size %zu; exp_array_size %d", + str, parsed_array_size, exp_array_size); + return 1; + } + + for (i = 0; i < exp_array_size; i++) + if (parsed_array[i] != exp_array[i]) { + qdf_nofl_alert("FAIL: qdf_uint32_array_parse(\"%s\") -> parsed_array[%d] %d; exp_array[%d] %d", + str, i, parsed_array[i], i, + exp_array[i]); + return 1; + } + + return 0; +} + +static uint32_t qdf_types_ut_uint32_array_parse(void) +{ + uint32_t errors = 0; + uint32_t exp_array_value[10] = { 1, 100, 9997, 899965, 65536, 0, + 4294967295, 268435456, + 2164184149, 999999999}; + + errors += ut_uint32_array_pass( + "1, 100, 9997, 899965, 65536, 0, 4294967295, 268435456, 2164184149, 999999999", + 10, exp_array_value, 10); + errors += ut_uint32_array_pass( + "+1, +100, +9997, +899965, +65536, 0, +4294967295, +268435456, +2164184149, +999999999", + 10, exp_array_value, 10); + errors += ut_uint32_array_fail("1;", 10, QDF_STATUS_E_FAILURE, + exp_array_value, 0); + /* Out of range test where 4294967296 is out of range */ + errors += ut_uint32_array_fail( + "1, 100, 9997, 899965, 65536, 0, 4294967296, 268435456, 2164184149, 999999999", + 10, QDF_STATUS_E_RANGE, exp_array_value, 0); + errors += ut_uint32_array_fail( + "-1, -100, -9997, -899965, -65536, 0, -4294967295, -268435456, -2164184149, -999999999", + 10, QDF_STATUS_E_RANGE, exp_array_value, 0); + errors += ut_uint32_array_fail( + "1, 100, 9997, 899965, 65536, 日本, 0, 4294967295, 268435456, 999999999", + 10, QDF_STATUS_E_FAILURE, exp_array_value, 0); + + return errors; +} + #define ut_uint32_pass(str, exp) __ut_uint32(str, QDF_STATUS_SUCCESS, exp) #define ut_uint32_fail(str, exp_status) __ut_uint32(str, exp_status, 0) @@ -287,11 +435,11 @@ __ut_mac(const char *str, const char *display_str, QDF_STATUS exp_status, return 0; if (qdf_mem_cmp(&value, exp_value, sizeof(value))) { - qdf_nofl_alert("FAIL: qdf_mac_parse(%s) -> " QDF_MAC_ADDR_STR - "; expected " QDF_MAC_ADDR_STR, + qdf_nofl_alert("FAIL: qdf_mac_parse(%s) -> " QDF_FULL_MAC_FMT + "; expected " QDF_FULL_MAC_FMT, display_str, - QDF_MAC_ADDR_ARRAY(value.bytes), - QDF_MAC_ADDR_ARRAY(exp_value->bytes)); + QDF_FULL_MAC_REF(value.bytes), + QDF_FULL_MAC_REF(exp_value->bytes)); return 1; } @@ -507,6 +655,8 @@ uint32_t qdf_types_unit_test(void) errors += qdf_types_ut_mac_parse(); errors += qdf_types_ut_ipv4_parse(); errors += qdf_types_ut_ipv6_parse(); + errors += qdf_types_ut_uint16_array_parse(); + errors += qdf_types_ut_uint32_array_parse(); return errors; } diff --git a/drivers/staging/qca-wifi-host-cmn/scheduler/inc/scheduler_core.h b/drivers/staging/qca-wifi-host-cmn/scheduler/inc/scheduler_core.h index 680ac2094f05e0f7e1b3aa821f03175e4669d42e..0fe8d4867562d3cf0aed93d4b946eb35ef98fded 100644 --- a/drivers/staging/qca-wifi-host-cmn/scheduler/inc/scheduler_core.h +++ b/drivers/staging/qca-wifi-host-cmn/scheduler/inc/scheduler_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -95,11 +95,11 @@ struct scheduler_mq_ctx { * @resume_sch_event: scheduler resume wait event * @sch_thread_lock: scheduler thread lock * @sch_last_qidx: scheduler last qidx allocation + * @watchdog_msg_type: 'type' of the current msg being processed * @hdd_callback: os if suspend callback * @legacy_wma_handler: legacy wma message handler * @legacy_sys_handler: legacy sys message handler * @watchdog_timer: timer for triggering a scheduler watchdog bite - * @watchdog_msg_type: 'type' of the current msg being processed * @watchdog_callback: the callback of the current msg being processed */ struct scheduler_ctx { @@ -112,11 +112,11 @@ struct scheduler_ctx { qdf_event_t resume_sch_event; qdf_spinlock_t sch_thread_lock; uint8_t sch_last_qidx; + uint16_t watchdog_msg_type; hdd_suspend_callback hdd_callback; scheduler_msg_process_fn_t legacy_wma_handler; scheduler_msg_process_fn_t legacy_sys_handler; qdf_timer_t watchdog_timer; - uint16_t watchdog_msg_type; void *watchdog_callback; }; diff --git a/drivers/staging/qca-wifi-host-cmn/scheduler/src/scheduler_api.c b/drivers/staging/qca-wifi-host-cmn/scheduler/src/scheduler_api.c index 02e25ab2e504251eb0002df30dc85aa3daad452a..d50a88ac63aa597008a9ba84eec2428058eeb5ae 100644 --- a/drivers/staging/qca-wifi-host-cmn/scheduler/src/scheduler_api.c +++ b/drivers/staging/qca-wifi-host-cmn/scheduler/src/scheduler_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,6 +19,8 @@ #include #include #include +#include +#include QDF_STATUS scheduler_disable(void) { @@ -53,16 +55,21 @@ static inline void scheduler_watchdog_notify(struct scheduler_ctx *sched) if (sched->watchdog_callback) qdf_sprint_symbol(symbol, sched->watchdog_callback); - sched_err("WLAN_BUG_RCA: Callback %s (type 0x%x) exceeded its allotted time of %ds", - sched->watchdog_callback ? symbol : "", - sched->watchdog_msg_type, SCHEDULER_WATCHDOG_TIMEOUT / 1000); + sched_fatal("Callback %s (type 0x%x) exceeded its allotted time of %ds", + sched->watchdog_callback ? symbol : "", + sched->watchdog_msg_type, + SCHEDULER_WATCHDOG_TIMEOUT / 1000); } -#ifdef CONFIG_SLUB_DEBUG_ON static void scheduler_watchdog_timeout(void *arg) { struct scheduler_ctx *sched = arg; + if (qdf_is_recovering()) { + sched_debug("Recovery is in progress ignore timeout"); + return; + } + scheduler_watchdog_notify(sched); if (sched->sch_thread) qdf_print_thread_trace(sched->sch_thread); @@ -73,12 +80,6 @@ static void scheduler_watchdog_timeout(void *arg) QDF_DEBUG_PANIC("Going down for Scheduler Watchdog Bite!"); } -#else -static void scheduler_watchdog_timeout(void *arg) -{ - scheduler_watchdog_notify((struct scheduler_ctx *)arg); -} -#endif QDF_STATUS scheduler_enable(void) { @@ -100,7 +101,7 @@ QDF_STATUS scheduler_enable(void) sched_ctx->sch_thread = qdf_create_thread(scheduler_thread, sched_ctx, "scheduler_thread"); if (!sched_ctx->sch_thread) { - sched_err("Failed to create scheduler thread"); + sched_fatal("Failed to create scheduler thread"); return QDF_STATUS_E_RESOURCES; } @@ -124,7 +125,7 @@ QDF_STATUS scheduler_init(void) status = scheduler_create_ctx(); if (QDF_IS_STATUS_ERROR(status)) { - sched_err("Failed to create context; status:%d", status); + sched_fatal("Failed to create context; status:%d", status); return status; } @@ -137,25 +138,26 @@ QDF_STATUS scheduler_init(void) status = scheduler_queues_init(sched_ctx); if (QDF_IS_STATUS_ERROR(status)) { - sched_err("Failed to init queues; status:%d", status); + sched_fatal("Failed to init queues; status:%d", status); goto ctx_destroy; } status = qdf_event_create(&sched_ctx->sch_start_event); if (QDF_IS_STATUS_ERROR(status)) { - sched_err("Failed to create start event; status:%d", status); + sched_fatal("Failed to create start event; status:%d", status); goto queues_deinit; } status = qdf_event_create(&sched_ctx->sch_shutdown); if (QDF_IS_STATUS_ERROR(status)) { - sched_err("Failed to create shutdown event; status:%d", status); + sched_fatal("Failed to create shutdown event; status:%d", + status); goto start_event_destroy; } status = qdf_event_create(&sched_ctx->resume_sch_event); if (QDF_IS_STATUS_ERROR(status)) { - sched_err("Failed to create resume event; status:%d", status); + sched_fatal("Failed to create resume event; status:%d", status); goto shutdown_event_destroy; } @@ -698,3 +700,5 @@ QDF_STATUS scheduler_post_message_debug(QDF_MODULE_ID src_id, return status; } + +qdf_export_symbol(scheduler_post_message_debug); diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/Kbuild b/drivers/staging/qca-wifi-host-cmn/spectral/Kbuild index af0f7fd2a5d7caa1e98d82c01a8127015892f317..117fc4f4ce248aab09a9690db24fac14487a14ef 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/Kbuild +++ b/drivers/staging/qca-wifi-host-cmn/spectral/Kbuild @@ -189,7 +189,7 @@ endif ifeq ($(QCA_CFR_SUPPORT), 1) ccflags-y+= -DWLAN_CFR_ENABLE=1 -INCS += -I$(obj)/$(DEPTH)/component_dev/umac/cfr/dispatcher/inc +INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cfr/dispatcher/inc INCS += -I$(obj)/$(DEPTH)/component_dev/qal/inc endif diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_common.c b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_common.c index c955dca798b0e6ac77e2e842c46c273432e0dfd2..a460635da4d4883b80911085f4f1c8572a1c0d86 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_common.c +++ b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_common.c @@ -425,11 +425,16 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev, case SPECTRAL_ACTIVATE_SCAN: err = &sscan_req->action_req.sscan_err_code; - sc->sptrlc_start_spectral_scan(pdev, smode, err); + ret = sc->sptrlc_start_spectral_scan(pdev, smode, err); + if (QDF_IS_STATUS_ERROR(ret)) + goto bad; break; case SPECTRAL_STOP_SCAN: - sc->sptrlc_stop_spectral_scan(pdev, smode); + err = &sscan_req->action_req.sscan_err_code; + ret = sc->sptrlc_stop_spectral_scan(pdev, smode, err); + if (QDF_IS_STATUS_ERROR(ret)) + goto bad; break; case SPECTRAL_GET_CAPABILITY_INFO: @@ -466,6 +471,14 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev, } break; + case SPECTRAL_SET_DMA_DEBUG: + if (sc->sptrlc_set_dma_debug) + sc->sptrlc_set_dma_debug( + pdev, + sscan_req->dma_debug_req.dma_debug_type, + sscan_req->dma_debug_req.dma_debug_enable); + break; + default: goto bad; break; diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_defs_i.h b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_defs_i.h index 52abd90ff73bd471edd5c19838ef4ea4c623e91c..716807d5afac9d3468df25d08048f468b062fdfd 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_defs_i.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_defs_i.h @@ -118,6 +118,7 @@ struct wmi_spectral_cmd_ops; * @sptrlc_use_nl_bcast: Check whether to use Netlink broadcast/unicast * @sptrlc_deregister_netlink_cb: De-register Netlink callbacks * @sptrlc_process_spectral_report: Process spectral report + * @sptrlc_set_dma_debug: Set DMA debug */ struct spectral_context { struct wlan_objmgr_psoc *psoc_obj; @@ -143,8 +144,10 @@ struct spectral_context { (struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode, enum spectral_cp_error_code *err); - QDF_STATUS (*sptrlc_stop_spectral_scan)(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode); + QDF_STATUS (*sptrlc_stop_spectral_scan) + (struct wlan_objmgr_pdev *pdev, + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); bool (*sptrlc_is_spectral_active)(struct wlan_objmgr_pdev *pdev, enum spectral_scan_mode smode); bool (*sptrlc_is_spectral_enabled)(struct wlan_objmgr_pdev *pdev, @@ -161,13 +164,17 @@ struct spectral_context { struct wlan_objmgr_pdev *pdev, struct wmi_spectral_cmd_ops *cmd_ops); void (*sptrlc_register_netlink_cb)( - struct wlan_objmgr_pdev *pdev, - struct spectral_nl_cb *nl_cb); + struct wlan_objmgr_pdev *pdev, + struct spectral_nl_cb *nl_cb); bool (*sptrlc_use_nl_bcast)(struct wlan_objmgr_pdev *pdev); void (*sptrlc_deregister_netlink_cb)(struct wlan_objmgr_pdev *pdev); int (*sptrlc_process_spectral_report)( - struct wlan_objmgr_pdev *pdev, - void *payload); + struct wlan_objmgr_pdev *pdev, + void *payload); + QDF_STATUS (*sptrlc_set_dma_debug)( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); }; -#endif /* _SPECTRAL_DEFS_I_H_ */ +#endif /* _SPECTRAL_DEFS_I_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_module.c b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_module.c index 0f946e7e89c0b347a788a340fe1e75df584f5dc3..eabff65f6b36b536b584a551b050e1e1cdfe2a3c 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_module.c +++ b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_module.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -31,8 +31,12 @@ MODULE_LICENSE("Dual BSD/GPL"); * * Return: None */ -static int __init -spectral_init_module(void) + +#ifndef QCA_SINGLE_WIFI_3_0 +static int __init spectral_init_module(void) +#else +int spectral_init_module(void) +#endif { spectral_info("qca_spectral module loaded"); wlan_spectral_init(); @@ -51,12 +55,17 @@ spectral_init_module(void) * * Return: None */ -static void __exit -spectral_exit_module(void) +#ifndef QCA_SINGLE_WIFI_3_0 +static void __exit spectral_exit_module(void) +#else +void spectral_exit_module(void) +#endif { wlan_spectral_deinit(); spectral_info("qca_spectral module unloaded"); } +#ifndef QCA_SINGLE_WIFI_3_0 module_init(spectral_init_module); module_exit(spectral_exit_module); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_offload.c b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_offload.c index b07c7a7fc20f2dc9b87c18a44abcfc6328e4193e..7db9dd3861735521fed7fcf562c00bec2248ec4f 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_offload.c +++ b/drivers/staging/qca-wifi-host-cmn/spectral/core/spectral_offload.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -21,6 +21,23 @@ #include "spectral_ol_api_i.h" #include "../dispatcher/inc/wlan_spectral_tgt_api.h" +#ifdef DIRECT_BUF_RX_DEBUG +static void +spectral_ctx_init_ol_dma_debug(struct spectral_context *sc) +{ + if (!sc) { + spectral_err("spectral context is null!"); + return; + } + sc->sptrlc_set_dma_debug = tgt_set_spectral_dma_debug; +} +#else +static void +spectral_ctx_init_ol_dma_debug(struct spectral_context *sc) +{ +} +#endif + void spectral_ctx_init_ol(struct spectral_context *sc) { @@ -47,4 +64,5 @@ spectral_ctx_init_ol(struct spectral_context *sc) sc->sptrlc_use_nl_bcast = tgt_spectral_use_nl_bcast; sc->sptrlc_deregister_netlink_cb = tgt_spectral_deregister_nl_cb; sc->sptrlc_process_spectral_report = tgt_spectral_process_report; + spectral_ctx_init_ol_dma_debug(sc); } diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/cfg_spectral.h b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/cfg_spectral.h index b997cd9641bbaac1b17d33f9a7bf79656902c804..175d743b53a66fcc74eb05796b6fec6e13d1e3be 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/cfg_spectral.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/cfg_spectral.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,7 +43,29 @@ CFG_INI_BOOL("spectral_disable", false, \ "Spectral disable") +/* + * + * poison_spectral_bufs - enable poisoning of spectral buffers + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable the poisoning of spectral buffers. + * + * Related: None + * + * Supported Feature: Spectral + * + * Usage: Internal + * + * + */ +#define CFG_SPECTRAL_POISON_BUFS \ + CFG_INI_BOOL("poison_spectral_bufs", false, \ + "Enable spectral bufs poison at init") + #define CFG_SPECTRAL_ALL \ - CFG(CFG_SPECTRAL_DISABLE) + CFG(CFG_SPECTRAL_DISABLE) \ + CFG(CFG_SPECTRAL_POISON_BUFS) #endif diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/spectral_ioctl.h b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/spectral_ioctl.h index 2f24c6baf6c441daeb1a93e272af9febbaaea23d..4f99495f1ad5dd2c87e40f81fd0d3aca0c2e4bb4 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/spectral_ioctl.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/spectral_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -51,12 +51,13 @@ #define SPECTRAL_SET_ICM_ACTIVE (DFS_LAST_IOCTL + 21) #define SPECTRAL_GET_NOMINAL_NOISEFLOOR (DFS_LAST_IOCTL + 22) #define SPECTRAL_GET_DEBUG_LEVEL (DFS_LAST_IOCTL + 23) +#define SPECTRAL_SET_DMA_DEBUG (DFS_LAST_IOCTL + 24) /* * ioctl parameter types */ enum spectral_params { - SPECTRAL_PARAM_FFT_PERIOD = 1, + SPECTRAL_PARAM_FFT_PERIOD, SPECTRAL_PARAM_SCAN_PERIOD, SPECTRAL_PARAM_SCAN_COUNT, SPECTRAL_PARAM_SHORT_REPORT, @@ -80,8 +81,9 @@ enum spectral_params { SPECTRAL_PARAM_STOP, SPECTRAL_PARAM_ENABLE, SPECTRAL_PARAM_FREQUENCY, - SPECTRAL_PARAM_AFTER_LAST, - SPECTRAL_PARAM_MAX = SPECTRAL_PARAM_AFTER_LAST - 1, + SPECTRAL_PARAM_CHAN_FREQUENCY, + SPECTRAL_PARAM_CHAN_WIDTH, + SPECTRAL_PARAM_MAX, }; /** @@ -225,7 +227,9 @@ struct spectral_config { * @high_level_offset: high_level_offset * @rssi_thr: rssi_thr * @default_agc_max_gain: default_agc_max_gain - * @agile_spectral_cap: agile Spectral capability + * @agile_spectral_cap: agile Spectral capability for 20/40/80 + * @agile_spectral_cap_160: agile Spectral capability for 160 MHz + * @agile_spectral_cap_80p80: agile Spectral capability for 80p80 */ struct spectral_caps { uint8_t phydiag_cap; @@ -240,12 +244,16 @@ struct spectral_caps { int16_t rssi_thr; uint8_t default_agc_max_gain; bool agile_spectral_cap; + bool agile_spectral_cap_160; + bool agile_spectral_cap_80p80; }; #define SPECTRAL_IOCTL_PARAM_NOVAL (65535) -#define MAX_SPECTRAL_CHAINS 3 -#define MAX_NUM_BINS 520 +#define MAX_SPECTRAL_CHAINS (3) +#define MAX_NUM_BINS (1024) +#define MAX_NUM_BINS_PRI80 (1024) +#define MAX_NUM_BINS_SEC80 (520) /* 5 categories x (lower + upper) bands */ #define MAX_INTERF 10 @@ -343,6 +351,36 @@ struct spectral_classifier_params { * segment * @ch_width: Channel width 20/40/80/160 MHz * @spectral_mode: Spectral scan mode + * @spectral_pri80ind: Indication from hardware that the sample was + * received on the primary 80 MHz segment. If this + * is set when smode = SPECTRAL_SCAN_MODE_AGILE, it + * indicates that Spectral was carried out on pri80 + * instead of the Agile frequency due to a + * channel switch - Software may choose + * to ignore the sample in this case. + * @spectral_pri80ind_sec80: Indication from hardware that the sample was + * received on the primary 80 MHz segment instead of + * the secondary 80 MHz segment due to a channel + * switch - Software may choose to ignore the sample + * if this is set. Applicable only if smode = + * SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz + * Spectral operation. + * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of + * 160Mhz it will be primary 80 segment's timestamp + * as both primary & secondary segment's timestamp + * are expected to be almost equal. + * @timestamp_war_offset: Offset calculated based on reset_delay and + * last_raw_timestamp. It will be added to + * raw_timestamp to get spectral_tstamp. + * @raw_timestamp: Actual FFT timestamp reported by HW on primary + * segment. + * @raw_timestamp_sec80: Actual FFT timestamp reported by HW on sec80 MHz + * segment. + * @reset_delay: Time gap between the last spectral report before + * reset and the end of reset. It is provided by FW + * via direct DMA framework. + * @target_reset_count: Indicates the number of times target went through + * reset routine after spectral was enabled. */ struct spectral_samp_data { int16_t spectral_data_len; @@ -389,8 +427,8 @@ struct spectral_samp_data { uint8_t lb_edge_extrabins; uint8_t rb_edge_extrabins; uint16_t bin_pwr_count_sec80; - uint8_t bin_pwr[MAX_NUM_BINS]; - uint8_t bin_pwr_sec80[MAX_NUM_BINS]; + uint8_t bin_pwr[MAX_NUM_BINS_PRI80]; + uint8_t bin_pwr_sec80[MAX_NUM_BINS_SEC80]; struct interf_src_rsp interf_list; int16_t noise_floor; int16_t noise_floor_sec80; @@ -400,6 +438,15 @@ struct spectral_samp_data { uint8_t spectral_gainchange; uint8_t spectral_gainchange_sec80; enum spectral_scan_mode spectral_mode; + uint8_t spectral_pri80ind; + uint8_t spectral_pri80ind_sec80; + uint32_t last_raw_timestamp; + uint32_t timestamp_war_offset; + uint32_t raw_timestamp; + uint32_t raw_timestamp_sec80; + uint32_t reset_delay; + uint32_t target_reset_count; + uint32_t agile_ch_width; } __packed; /** @@ -408,6 +455,9 @@ struct spectral_samp_data { * @freq: Operating frequency in MHz * @vhtop_ch_freq_seg1: VHT Segment 1 centre frequency in MHz * @vhtop_ch_freq_seg2: VHT Segment 2 centre frequency in MHz + * @agile_freq: Center frequency in MHz of the entire span across which + * Agile Spectral is carried out. Applicable only for Agile + * Spectral samples. * @freq_loading: How busy was the channel * @dcs_enabled: Whether DCS is enabled * @int_type: Interference type indicated by DCS @@ -419,6 +469,7 @@ struct spectral_samp_msg { uint16_t freq; uint16_t vhtop_ch_freq_seg1; uint16_t vhtop_ch_freq_seg2; + uint16_t agile_freq; uint16_t freq_loading; uint16_t dcs_enabled; enum dcs_int_type int_type; diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_public_structs.h b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_public_structs.h index 4096eb4bea3ec6151be5e368f8d8de52fe7c5786..34cc4b1bc80ccee51a09bb5f5b61372af36ad28b 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_public_structs.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_public_structs.h @@ -218,18 +218,30 @@ enum spectral_capability_type { /** * enum spectral_cp_error_code - Spectral control path response code + * @SPECTRAL_SCAN_RESP_ERR_INVALID: Invalid error identifier * @SPECTRAL_SCAN_RESP_ERR_PARAM_UNSUPPORTED: parameter unsupported * @SPECTRAL_SCAN_RESP_ERR_MODE_UNSUPPORTED: mode unsupported * @SPECTRAL_SCAN_RESP_ERR_PARAM_INVALID_VALUE: invalid parameter value * @SPECTRAL_SCAN_RESP_ERR_PARAM_NOT_INITIALIZED: parameter uninitialized */ enum spectral_cp_error_code { + SPECTRAL_SCAN_ERR_INVALID, SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED, SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED, SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE, SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED, }; +/** + * enum spectral_dma_debug - Spectral DMA debug + * @SPECTRAL_DMA_RING_DEBUG: Spectral DMA ring debug + * @SPECTRAL_DMA_BUFFER_DEBUG: Spectral DMA buffer debug + */ +enum spectral_dma_debug { + SPECTRAL_DMA_RING_DEBUG, + SPECTRAL_DMA_BUFFER_DEBUG, +}; + /** * struct spectral_chan_stats - channel status info * @cycle_count: Cycle count @@ -376,12 +388,25 @@ struct spectral_scan_debug_request { enum spectral_cp_error_code sscan_err_code; }; +/** + * struct spectral_scan_dma_debug_request - DMA debug request + * @dma_debug_enable: Enable/disable @dma_debug_type + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @sscan_err_code: Spectral scan error code + */ +struct spectral_scan_dma_debug_request { + bool dma_debug_enable; + enum spectral_dma_debug dma_debug_type; + enum spectral_cp_error_code sscan_err_code; +}; + /** * struct spectral_cp_request - Spectral control path request * Creating request and extracting response has to * be atomic. * @ss_mode: Spectral scan mode * @req_id: Request identifier + * @dma_debug_req: Spectral DMA debug request */ struct spectral_cp_request { enum spectral_scan_mode ss_mode; @@ -394,6 +419,7 @@ struct spectral_cp_request { struct spectral_scan_get_chan_width_request chan_width_req; struct spectral_scan_get_status_request status_req; struct spectral_scan_debug_request debug_req; + struct spectral_scan_dma_debug_request dma_debug_req; }; }; diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_tgt_api.h index 4a1ee4dbbda6992f54af37dda2f6ea8cd948a66f..264ab28dc8617a31fb067f9babe3c78b1a2c4131 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_tgt_api.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_tgt_api.h @@ -102,7 +102,7 @@ QDF_STATUS tgt_get_spectral_config(struct wlan_objmgr_pdev *pdev, * tgt_start_spectral_scan() - Start spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode - * @res: Spectral control path error code + * @err: Spectral control path error code * * Implementation for starting spectral scan * @@ -116,13 +116,15 @@ QDF_STATUS tgt_start_spectral_scan(struct wlan_objmgr_pdev *pdev, * tgt_stop_spectral_scan() - Stop spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode + * @err: Spectral control path error code * * Implementation for stop spectral scan * * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE */ QDF_STATUS tgt_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode); + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); /** * tgt_is_spectral_active() - Get whether Spectral is active @@ -271,4 +273,16 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev); */ uint32_t tgt_spectral_get_target_type(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_set_spectral_dma_debug() - Set DMA debug for Spectral + * @pdev: Pointer to pdev object + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @dma_debug_enable: Value to be set for @dma_debug_type + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); #endif /* _WLAN_SPECTRAL_TGT_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_utils_api.h b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_utils_api.h index 9453dcc2f799d58c7eb76360fe748d68bbc04b30..3d1b159e82179aa0aae79f52d3fa1b623b6b2b93 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_utils_api.h +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/inc/wlan_spectral_utils_api.h @@ -88,11 +88,13 @@ wlan_register_wmi_spectral_cmd_ops(struct wlan_objmgr_pdev *pdev, /** * struct spectral_legacy_cbacks - Spectral legacy callbacks * @vdev_get_chan_freq: Get channel frequency + * @vdev_get_chan_freq_seg2: Get secondary 80 center frequency * @vdev_get_ch_width: Get channel width * @vdev_get_sec20chan_freq_mhz: Get seconadry 20 frequency */ struct spectral_legacy_cbacks { int16_t (*vdev_get_chan_freq)(struct wlan_objmgr_vdev *vdev); + int16_t (*vdev_get_chan_freq_seg2)(struct wlan_objmgr_vdev *vdev); enum phy_ch_width (*vdev_get_ch_width)(struct wlan_objmgr_vdev *vdev); int (*vdev_get_sec20chan_freq_mhz)(struct wlan_objmgr_vdev *vdev, uint16_t *sec20chan_freq); @@ -106,6 +108,14 @@ struct spectral_legacy_cbacks { */ int16_t spectral_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev); +/** + * spectral_vdev_get_chan_freq_seg2 - Get vdev's secondary 80 center frequency + * @vdev: vdev object + * + * Return: vdev secondary 80 center frequency + */ +int16_t spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev); + /** * spectral_vdev_get_sec20chan_freq_mhz - Get vdev secondary channel frequency * @vdev: vdev object diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_tgt_api.c index 0195ae2d0b47d382681dd9bcb9c085c375aff126..f416b47e9c325cc0ae53ef4a1fcc35ad22253fc5 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_tgt_api.c +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_tgt_api.c @@ -125,13 +125,14 @@ tgt_start_spectral_scan(struct wlan_objmgr_pdev *pdev, QDF_STATUS tgt_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode) + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) { - struct wlan_objmgr_psoc *psoc = NULL; + struct wlan_objmgr_psoc *psoc; psoc = wlan_pdev_get_psoc(pdev); return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_stop_spectral_scan( - pdev, smode); + pdev, smode, err); } bool @@ -297,23 +298,26 @@ tgt_spectral_register_to_dbr(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + struct wlan_lmac_if_sptrl_tx_ops *sptrl_tx_ops = NULL; struct dbr_module_config dbr_config = {0}; - uint32_t target_type; psoc = wlan_pdev_get_psoc(pdev); dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + sptrl_tx_ops = &psoc->soc_cb.tx_ops.sptrl_tx_ops; dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_SPECTRAL; dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_SPECTRAL; - target_type = tgt_spectral_get_target_type(psoc); - if ((target_type == TARGET_TYPE_QCA8074) || - (target_type == TARGET_TYPE_QCA8074V2) || - (target_type == TARGET_TYPE_QCA6018) || - (target_type == TARGET_TYPE_QCA6390)) + if ((sptrl_tx_ops->sptrlto_direct_dma_support) && + (sptrl_tx_ops->sptrlto_direct_dma_support(pdev))) { + if (sptrl_tx_ops->sptrlto_check_and_do_dbr_buff_debug) + sptrl_tx_ops->sptrlto_check_and_do_dbr_buff_debug(pdev); if (dbr_tx_ops->direct_buf_rx_module_register) - return dbr_tx_ops->direct_buf_rx_module_register + dbr_tx_ops->direct_buf_rx_module_register (pdev, 0, &dbr_config, spectral_dbr_event_handler); + if (sptrl_tx_ops->sptrlto_check_and_do_dbr_ring_debug) + sptrl_tx_ops->sptrlto_check_and_do_dbr_ring_debug(pdev); + } return QDF_STATUS_SUCCESS; } @@ -323,17 +327,29 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + struct wlan_lmac_if_sptrl_tx_ops *sptrl_tx_ops = NULL; psoc = wlan_pdev_get_psoc(pdev); dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + sptrl_tx_ops = &psoc->soc_cb.tx_ops.sptrl_tx_ops; + + if ((sptrl_tx_ops->sptrlto_direct_dma_support) && + (sptrl_tx_ops->sptrlto_direct_dma_support(pdev))) { + /* Stop DBR debug as the buffers itself are freed now */ + if (dbr_tx_ops->direct_buf_rx_stop_ring_debug) + dbr_tx_ops->direct_buf_rx_stop_ring_debug(pdev, 0); - if ((tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA8074) || - (tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA8074V2) || - (tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA6018)) + /*No need to zero-out as buffers are anyway getting freed*/ + if (dbr_tx_ops->direct_buf_rx_stop_buffer_poisoning) + dbr_tx_ops->direct_buf_rx_stop_buffer_poisoning + (pdev, 0); if (dbr_tx_ops->direct_buf_rx_module_unregister) - return dbr_tx_ops->direct_buf_rx_module_unregister + dbr_tx_ops->direct_buf_rx_module_unregister (pdev, 0); + return QDF_STATUS_SUCCESS; + } + return QDF_STATUS_E_FAILURE; } #else @@ -348,4 +364,32 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev) { return QDF_STATUS_SUCCESS; } +#endif /* DIRECT_BUF_RX_ENABLE */ + +#ifdef DIRECT_BUF_RX_DEBUG +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable) +{ + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + spectral_err("psoc is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_dma_debug( + pdev, + dma_debug_type, + dma_debug_enable); +} +#else +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable) +{ + return QDF_STATUS_SUCCESS; +} #endif diff --git a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c index 18b7c8201806d88f0fffd5a7f9295ecc1cf267ce..8a58ad65437880615b39860c6a5d5a0374cdc08b 100644 --- a/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c +++ b/drivers/staging/qca-wifi-host-cmn/spectral/dispatcher/src/wlan_spectral_utils_api.c @@ -119,6 +119,8 @@ spectral_register_legacy_cb(struct wlan_objmgr_psoc *psoc, sc->legacy_cbacks.vdev_get_chan_freq = legacy_cbacks->vdev_get_chan_freq; + sc->legacy_cbacks.vdev_get_chan_freq_seg2 = + legacy_cbacks->vdev_get_chan_freq_seg2; sc->legacy_cbacks.vdev_get_ch_width = legacy_cbacks->vdev_get_ch_width; sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz = legacy_cbacks->vdev_get_sec20chan_freq_mhz; @@ -138,9 +140,33 @@ spectral_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) return -EINVAL; } + if (!sc->legacy_cbacks.vdev_get_chan_freq) { + spectral_err("vdev_get_chan_freq is not supported"); + return -ENOTSUPP; + } + return sc->legacy_cbacks.vdev_get_chan_freq(vdev); } +int16_t +spectral_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev) +{ + struct spectral_context *sc; + + sc = spectral_get_spectral_ctx_from_vdev(vdev); + if (!sc) { + spectral_err("spectral context is null"); + return -EINVAL; + } + + if (!sc->legacy_cbacks.vdev_get_chan_freq_seg2) { + spectral_err("vdev_get_chan_freq_seg2 is not supported"); + return -ENOTSUPP; + } + + return sc->legacy_cbacks.vdev_get_chan_freq_seg2(vdev); +} + enum phy_ch_width spectral_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) { @@ -152,6 +178,11 @@ spectral_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) return CH_WIDTH_INVALID; } + if (!sc->legacy_cbacks.vdev_get_ch_width) { + spectral_err("vdev_get_ch_width is not supported"); + return -ENOTSUPP; + } + return sc->legacy_cbacks.vdev_get_ch_width(vdev); } @@ -167,6 +198,11 @@ spectral_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev, return -EINVAL; } + if (!sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz) { + spectral_err("vdev_get_sec20chan_freq_mhz is not supported"); + return -ENOTSUPP; + } + return sc->legacy_cbacks.vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); } @@ -179,6 +215,8 @@ wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) /* Spectral rx ops */ sptrl_rx_ops->sptrlro_get_target_handle = tgt_get_target_handle; sptrl_rx_ops->sptrlro_vdev_get_chan_freq = spectral_vdev_get_chan_freq; + sptrl_rx_ops->sptrlro_vdev_get_chan_freq_seg2 = + spectral_vdev_get_chan_freq_seg2; sptrl_rx_ops->sptrlro_vdev_get_ch_width = spectral_vdev_get_ch_width; sptrl_rx_ops->sptrlro_vdev_get_sec20chan_freq_mhz = spectral_vdev_get_sec20chan_freq_mhz; @@ -231,13 +269,19 @@ bool spectral_dbr_event_handler(struct wlan_objmgr_pdev *pdev, QDF_STATUS spectral_pdev_open(struct wlan_objmgr_pdev *pdev) { + struct wlan_objmgr_psoc *psoc; QDF_STATUS status; - if (wlan_spectral_is_feature_disabled(wlan_pdev_get_psoc(pdev))) { + psoc = wlan_pdev_get_psoc(pdev); + + if (wlan_spectral_is_feature_disabled(psoc)) { spectral_info("Spectral is disabled"); return QDF_STATUS_COMP_DISABLED; } + if (cfg_get(psoc, CFG_SPECTRAL_POISON_BUFS)) + tgt_set_spectral_dma_debug(pdev, SPECTRAL_DMA_BUFFER_DEBUG, 1); + status = tgt_spectral_register_to_dbr(pdev); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr.h b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr.h new file mode 100644 index 0000000000000000000000000000000000000000..77d3c69bee7de2f84fa35cb9d2920a4b5f481465 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _TARGET_IF_CFR_H_ +#define _TARGET_IF_CFR_H_ + +#include +#include +#include +#include +#include + +#include "wmi_unified_cfr_api.h" +#include "wmi_unified_param.h" +#include "wmi_unified_cfr_param.h" +#define PEER_CFR_CAPTURE_ENABLE 1 +#define PEER_CFR_CAPTURE_DISABLE 0 + +#define PEER_CFR_CAPTURE_EVT_STATUS_MASK 0x80000000 +#define PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK 0x40000000 +#define CFR_TX_EVT_STATUS_MASK 0x00000003 + +/* Status codes used by correlate and relay function */ +#define STATUS_STREAM_AND_RELEASE 0 +#define STATUS_HOLD 1 +#define STATUS_ERROR -1 + +/* Module IDs using corrlation function */ +#define CORRELATE_DBR_MODULE_ID 0 +/* + * HKV2 - Tx completion event for one-shot capture + * Cypress - Tx completion event for one-shot capture (or) RXTLV event for RCC + */ +#define CORRELATE_TX_EV_MODULE_ID 1 + +/** + * target_if_cfr_init_pdev() - Inits cfr pdev and registers necessary handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: Registration status for necessary handlers + */ +int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_deinit_pdev() - De-inits corresponding pdev and handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: De-registration status for necessary handlers + */ +int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_tx_ops_register() - Registers tx ops for cfr module + * @tx_ops - pointer to tx_ops structure. + */ +void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops); + +/** + * target_if_cfr_enable_cfr_timer() - Enables cfr timer + * @pdev: pointer to pdev object + * @cfr_timer: Amount of time this timer has to run + * + * Return: status of timer + */ +int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, + uint32_t cfr_timer); + +/** + * target_if_cfr_pdev_set_param() - Function to set params for cfr config + * @pdev: pointer to pdev object + * @param_id: param id which has to be set + * @param_value: value of param being set + * + * Return: success/failure of setting param + */ +int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev, + uint32_t param_id, uint32_t param_value); +/** + * target_if_cfr_start_capture() - Function to start cfr capture for a peer + * @pdev: pointer to pdev object + * @peer: pointer to peer object + * @cfr_params: capture parameters for this peer + * + * Return: success/failure status of start capture + */ +int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *cfr_params); +/** + * target_if_cfr_stop_capture() - Function to stop cfr capture for a peer + * @pdev: pointer to pdev object + * @peer: pointer to peer object + * + * Return: success/failure status of stop capture + */ +int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer); + +/** + * target_if_cfr_get_target_type() - Function to get target type + * @psoc: pointer to psoc object + * + * Return: target type of target + */ +int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc); + +/** + * target_if_cfr_set_cfr_support() - Function to set cfr support + * @psoc: pointer to psoc object + * @value: value to be set + */ +void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc, + uint8_t value); + +/** + * target_if_cfr_info_send() - Function to send cfr info to upper layers + * @pdev: pointer to pdev object + * @head: pointer to cfr info head + * @hlen: head len + * @data: pointer to cfr info data + * @dlen: data len + * @tail: pointer to cfr info tail + * @tlen: tail len + */ +void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, + size_t hlen, void *data, size_t dlen, void *tail, + size_t tlen); + +/** + * cfr_wifi2_0_init_pdev() - Function to init legacy pdev + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: success/failure status of init + */ +QDF_STATUS cfr_wifi2_0_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * cfr_wifi2_0_deinit_pdev() - Function to deinit legacy pdev + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: success/failure status of deinit + */ +QDF_STATUS cfr_wifi2_0_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6018.h b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6018.h new file mode 100644 index 0000000000000000000000000000000000000000..4255f85acac9e2a1fd03c5e2d6ba863d3dc58ce2 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6018.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _TARGET_IF_CFR_6018_H_ +#define _TARGET_IF_CFR_6018_H_ + +#ifdef WLAN_ENH_CFR_ENABLE +/* + * Memory requirements : + * + * 1. DMA header : + * + * Legacy DMA header(QCA8074V2) : 2 words (length = 8 bytes) + * Enhanced DMA header(QCA6018) : Upto 16 words depending on no. of MU users + * in UL-MU-PPDU (Max length = 64 bytes) + * + * Fixed 4 words for whal_cfir_enhanced_hdr + freeze TLV + * + uplink_user_info TLV (MAX 4) + * + * mu_rx_num_users -> No. of words in CFR DMA header + * 0 -> 12 = 4 + 7(freeze TLV) + 1(for 64-bit alignment) + * 1 -> 12 = 4 + 7(freeze TLV) + 1(user1) + * 2 -> 14 = 4 + 7(freeze TLV) + 2(users 1,2) + 1(for 64-bit alignment) + * 3 -> 14 = 4 + 7(freeze TLV) + 3(users 1,2,3) + * 4 -> 16 = 4 + 7(freeze TLV) + 4(users 1,2,3,4) + 1(for 64-bit alignment) + * + * + * 2. CFR data size for max BW/Nss/Nrx + * + * Cypress : Max BW = 80 MHz + * NSS = 2 + * Nrx = 2 + * Size of one tone = 4 bytes + * + * a. RTT-H - 2048 bytes + * + * b. Debug-H (MIMO CFR) - 16016 bytes + * + * c. RTT-H + CIR - 10240 bytes = 2048(RTT-H) + 8192(CIR) + */ + +/* Max 4 users in MU case */ +#define CYP_CFR_MU_USERS 4 + +#define CYP_MAX_HEADER_LENGTH_WORDS 16 + +/* payload_len = Max(2048, 16016, 10240) = 16064 (64-bit alignment) */ +#define CYP_MAX_DATA_LENGTH_BYTES 16064 + +/* in ms */ +#define LUT_AGE_TIMER 3000 +#define LUT_AGE_THRESHOLD 3000 +#define NUM_LUT_ENTRIES 136 + +/* Max size : + * 16173 = 93 bytes(csi header) + 64 bytes(cfr header) + 16016 bytes(cfr + * payload) + */ +#define STREAMFS_MAX_SUBBUF_CYP 16173 + +#define STREAMFS_NUM_SUBBUF_CYP 255 + +/* + * @tag: ucode fills this with 0xBA + * + * @length: length of CFR header in words (32-bit) + * + * @upload_done: ucode sets this to 1 to indicate DMA completion + * + * @capture_type: + * + * 0 - None + * 1 - RTT-H (Nss = 1, Nrx) + * 2 - Debug-H (Nss, Nrx) + * 3 - Reserved + * 5 - RTT-H + CIR(Nss, Nrx) + * + * @preamble_type: + * + * 0 - Legacy + * 1 - HT + * 2 - VHT + * 3 - HE + * + * @nss: + * + * 0 - 1-stream + * 1 - 2-stream + * .. .. + * 7 - 8-stream + * + *@num_chains: + * + * 0 - 1-chain + * 1 - 2-chain + * .. .. + * 7 - 8-chain + * + *@upload_bw_pkt: + * + * 0 - 20 MHz + * 1 - 40 MHz + * 2 - 80 MHz + * 3 - 160 MHz + * + * @sw_peer_id_valid: Indicates whether sw_peer_id field is valid or not, + * sent from MAC to PHY via the MACRX_FREEZE_CAPTURE_CHANNEL TLV + * + * @sw_peer_id: Indicates peer id based on AST search, sent from MAC to PHY + * via the MACRX_FREEZE_CAPTURE_CHANNEL TLV + * + * @phy_ppdu_id: sent from PHY to MAC, copied to MACRX_FREEZE_CAPTURE_CHANNEL + * TLV + * + * @total_bytes: Total size of CFR payload (FFT bins) + * + * @header_version: + * + * 1 - HKV2/Hastings + * 2 - Cypress + * + * @target_id: + * + * 1 - Hastings + * 2 - Cypress + * 3 - Hastings Prime + * 4 - Pine + * + * @cfr_fmt: + * + * 0 - raw (32-bit format) + * 1 - compressed (24-bit format) + * + * @mu_rx_data_incl: Indicates whether CFR header contains UL-MU-MIMO info + * + * @freeze_data_incl: Indicates whether CFR header contains + * MACRX_FREEZE_CAPTURE_CHANNEL TLV + * + * @decimation_factor: FFT bins decimation + * @mu_rx_num_users: Number of users in UL-MU-PPDU + */ +struct whal_cfir_enhanced_hdr { + uint16_t tag : 8, + length : 6, + rsvd1 : 2; + + uint16_t upload_done : 1, + capture_type : 3, + preamble_type : 2, + nss : 3, + num_chains : 3, + upload_pkt_bw : 3, + sw_peer_id_valid : 1; + + uint16_t sw_peer_id : 16; + + uint16_t phy_ppdu_id : 16; + + uint16_t total_bytes; + + uint16_t header_version :4, + target_id :4, + cfr_fmt :1, + rsvd2 :1, + mu_rx_data_incl :1, + freeze_data_incl:1, + rsvd3 :4; + + uint16_t mu_rx_num_users :8, + decimation_factor :4, + rsvd4 :4; + + uint16_t rsvd5; +}; + +struct macrx_freeze_capture_channel { + uint16_t freeze : 1, //[0] + capture_reason : 3, //[3:1] + packet_type : 2, //[5:4] + packet_sub_type : 4, //[9:6] + reserved : 5, //[14:10] + sw_peer_id_valid : 1; //[15] + uint16_t sw_peer_id : 16; //[15:0] + uint16_t phy_ppdu_id : 16; //[15:0] + uint16_t packet_ta_lower_16 : 16; //[15:0] + uint16_t packet_ta_mid_16 : 16; //[15:0] + uint16_t packet_ta_upper_16 : 16; //[15:0] + uint16_t packet_ra_lower_16 : 16; //[15:0] + uint16_t packet_ra_mid_16 : 16; //[15:0] + uint16_t packet_ra_upper_16 : 16; //[15:0] + uint16_t tsf_timestamp_15_0 : 16; //[15:0] + uint16_t tsf_timestamp_31_16 : 16; //[15:0] + uint16_t tsf_timestamp_47_32 : 16; //[15:0] + uint16_t tsf_timestamp_63_48 : 16; //[15:0] + uint16_t user_index : 6, //[5:0] + directed : 1, //[6] + reserved_13 : 9; //[15:7] +}; + +struct uplink_user_setup_info { + uint32_t bw_info_valid : 1, //[0] + uplink_receive_type : 2, //[2:1] + reserved_0a : 1, //[3] + uplink_11ax_mcs : 4, //[7:4] + ru_width : 7, //[14:8] + reserved_0b : 1, //[15] + nss : 3, //[18:16] + stream_offset : 3, //[21:19] + sta_dcm : 1, //[22] + sta_coding : 1, //[23] + ru_start_index : 7, //[30:24] + reserved_0c : 1; //[31] +}; + +/** + * cfr_6018_init_pdev() - Inits cfr pdev and registers necessary handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: Registration status for necessary handlers + */ +QDF_STATUS cfr_6018_init_pdev( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * cfr_6018_deinit_pdev() - De-inits corresponding pdev and handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: De-registration status for necessary handlers + */ +QDF_STATUS cfr_6018_deinit_pdev( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT + * entries + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT + * entries + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_dump_lut_enh() - Dump all valid LUT entries + * @pdev: objmgr PDEV + * + * Return: none + */ +void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev); + +/** + * target_if_cfr_config_rcc() - Start repetitive channel capture + * @pdev: pointer to pdev object + * @rcc_param: rcc configurations + * + * Return: Success/Failure status + */ +QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_param); + +/** + * target_if_cfr_default_ta_ra_config() - Configure default values to all + * params(BW/NSS/TA/RA) in TA_RA mode + * @rcc_param: rcc configurations + * @allvalid: Indicates whether all TA_RA params are valid or not. + * It could be either 0 or 1. + * 1: should be sent to FW during CFR initialization + * 0: should be set, after a successful commit session. + * @reset_cfg: This bitmap is being used to determine which groups' + * parameters are needed to be reset to its default state. + */ +void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_param, + bool allvalid, uint16_t reset_cfg); + +/** + * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in + * lookup table + * @pdev: PDEV object + * @nbuf: ppdu info + * + * Return: none + */ +void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf); + +/** + * target_if_cfr_update_global_cfg() - Update global config after a successful + * commit + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev); +#else +static QDF_STATUS cfr_6018_init_pdev( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS cfr_6018_deinit_pdev( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6490.h b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6490.h new file mode 100644 index 0000000000000000000000000000000000000000..94b149c84a7a6eee23bd6bf0e4cfac691d62ed6b --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/inc/target_if_cfr_6490.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC : target_if_cfr_6490.h + * + * Target interface of CFR for QCA6490 implementation + * + */ + +#ifndef _TARGET_IF_CFR_6490_H +#define _TARGET_IF_CFR_6490_H + +#ifdef QCA_WIFI_QCA6490 +#define CFR_MAC_ID_24G 1 +#define CFR_MAC_ID_5G 0 +#endif /* QCA_WIFI_QCA6490 */ + +/** + * target_if_cfr_subscribe_ppdu_desc() - subscribe ppdu description + * for CFR component + * + * @pdev: pointer to pdev object + * @is_subscribe: subscribe or unsubscribe + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe); + +/** + * cfr_6490_init_pdev() - Init pdev cfr for QCA6490 + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Registers to DBR component and init pdev cfr parameters + * + * Return: QDF status + */ +QDF_STATUS cfr_6490_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +/** + * cfr_6490_deinit_pdev() - De-inits pdev cfr for QCA6490 + * @pdev: pointer to pdev object + * + * Unregister to DBR and deinit pdev cfr parameters + * + * Return: QDF status + */ +QDF_STATUS cfr_6490_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev); + +#endif /* _TARGET_IF_CFR_6490_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr.c b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr.c new file mode 100644 index 0000000000000000000000000000000000000000..11e1c59062b43c3ba73900e550cd3423a5ce08b2 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr.c @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CFR_USE_FIXED_FOLDER +#include "target_if_cfr_6490.h" +#include "wlan_reg_services_api.h" +#else +#include +#endif + +int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer) +{ + struct peer_cfr *pe; + struct peer_cfr_params param = {0}; + struct wmi_unified *pdev_wmi_handle = NULL; + struct wlan_objmgr_vdev *vdev = {0}; + struct pdev_cfr *pdev_cfrobj; + int retv = 0; + + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + if (pe == NULL) + return -EINVAL; + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); + if (!pdev_wmi_handle) { + cfr_err("pdev wmi handle NULL"); + return -EINVAL; + } + vdev = wlan_peer_get_vdev(peer); + + qdf_mem_set(¶m, sizeof(param), 0); + + param.request = PEER_CFR_CAPTURE_DISABLE; + param.macaddr = wlan_peer_get_macaddr(peer); + param.vdev_id = wlan_vdev_get_id(vdev); + + param.periodicity = pe->period; + param.bandwidth = pe->bandwidth; + param.capture_method = pe->capture_method; + + retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m); + + pdev_cfrobj = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pdev_cfrobj) { + cfr_err("pdev object for CFR is null"); + return -EINVAL; + } + cfr_err("CFR capture stats for this capture:"); + cfr_err("DBR event count = %llu, Tx event count = %llu " + "Release count = %llu", + pdev_cfrobj->dbr_evt_cnt, pdev_cfrobj->tx_evt_cnt, + pdev_cfrobj->release_cnt); + + pdev_cfrobj->dbr_evt_cnt = 0; + pdev_cfrobj->tx_evt_cnt = 0; + pdev_cfrobj->release_cnt = 0; + + return retv; +} + +int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *cfr_params) +{ + struct peer_cfr_params param = {0}; + struct wmi_unified *pdev_wmi_handle = NULL; + struct wlan_objmgr_vdev *vdev; + int retv = 0; + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); + if (!pdev_wmi_handle) { + cfr_err("pdev wmi handle NULL"); + return -EINVAL; + } + vdev = wlan_peer_get_vdev(peer); + qdf_mem_set(¶m, sizeof(param), 0); + + param.request = PEER_CFR_CAPTURE_ENABLE; + param.macaddr = wlan_peer_get_macaddr(peer); + param.vdev_id = wlan_vdev_get_id(vdev); + + param.periodicity = cfr_params->period; + param.bandwidth = cfr_params->bandwidth; + param.capture_method = cfr_params->method; + + retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m); + return retv; +} + +int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev, + uint32_t param_id, uint32_t param_value) +{ + struct pdev_params pparam; + uint32_t pdev_id; + struct wmi_unified *pdev_wmi_handle = NULL; + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + if (pdev_id < 0) + return -EINVAL; + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); + if (!pdev_wmi_handle) { + cfr_err("pdev wmi handle NULL"); + return -EINVAL; + } + qdf_mem_set(&pparam, sizeof(pparam), 0); + pparam.param_id = param_id; + pparam.param_value = param_value; + + return wmi_unified_pdev_param_send(pdev_wmi_handle, + &pparam, pdev_id); +} + +int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, + uint32_t cfr_timer) +{ + struct pdev_cfr *pa; + int retval; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) + return QDF_STATUS_E_FAILURE; + + if (!cfr_timer) { + /* disable periodic cfr capture */ + retval = + target_if_cfr_pdev_set_param(pdev, + wmi_pdev_param_per_peer_prd_cfr_enable, + WMI_HOST_PEER_CFR_TIMER_DISABLE); + + if (retval == QDF_STATUS_SUCCESS) + pa->cfr_timer_enable = 0; + } else { + /* enable periodic cfr capture (default base timer is 10ms ) */ + retval = + target_if_cfr_pdev_set_param(pdev, + wmi_pdev_param_per_peer_prd_cfr_enable, + WMI_HOST_PEER_CFR_TIMER_ENABLE); + + if (retval == QDF_STATUS_SUCCESS) + pa->cfr_timer_enable = 1; + } + + return retval; +} + +int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc) +{ + uint32_t target_type = 0; + struct wlan_lmac_if_target_tx_ops *target_type_tx_ops; + + target_type_tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops; + + if (target_type_tx_ops->tgt_get_tgt_type) + target_type = target_type_tx_ops->tgt_get_tgt_type(psoc); + + return target_type; +} + +#ifdef CFR_USE_FIXED_FOLDER +int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + uint32_t target_type; + QDF_STATUS status; + + target_type = target_if_cfr_get_target_type(psoc); + + if (target_type == TARGET_TYPE_QCA6490) { + status = cfr_6490_init_pdev(psoc, pdev); + } else { + cfr_info("unsupport chip"); + status = QDF_STATUS_SUCCESS; + } + + return qdf_status_to_os_return(status); +} + +int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + uint32_t target_type; + QDF_STATUS status; + + target_type = target_if_cfr_get_target_type(psoc); + + if (target_type == TARGET_TYPE_QCA6490) { + status = cfr_6490_deinit_pdev(psoc, pdev); + } else { + cfr_info("unsupport chip"); + status = QDF_STATUS_SUCCESS; + } + + return qdf_status_to_os_return(status); +} +#else +int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + uint32_t target_type; + struct pdev_cfr *pa; + struct psoc_cfr *cfr_sc; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) + return QDF_STATUS_E_FAILURE; + + /* Reset unassociated entries for every init */ + qdf_mem_zero(&pa->unassoc_pool[0], MAX_CFR_ENABLED_CLIENTS * + sizeof(struct unassoc_pool_entry)); + + cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_CFR); + + if (cfr_sc == NULL) + return QDF_STATUS_E_FAILURE; + + target_type = target_if_cfr_get_target_type(psoc); + + if (target_type == TARGET_TYPE_QCA8074V2) { + pa->is_cfr_capable = cfr_sc->is_cfr_capable; + return cfr_8074v2_init_pdev(psoc, pdev); + } else if ((target_type == TARGET_TYPE_IPQ4019) || + (target_type == TARGET_TYPE_QCA9984) || + (target_type == TARGET_TYPE_QCA9888)) { + + pa->is_cfr_capable = cfr_sc->is_cfr_capable; + + return cfr_wifi2_0_init_pdev(psoc, pdev); + } else if (target_type == TARGET_TYPE_QCA6018) { + pa->is_cfr_capable = cfr_sc->is_cfr_capable; + return cfr_6018_init_pdev(psoc, pdev); + } else + return QDF_STATUS_E_NOSUPPORT; +} + +int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + uint32_t target_type; + + target_type = target_if_cfr_get_target_type(psoc); + + if (target_type == TARGET_TYPE_QCA8074V2) { + return cfr_8074v2_deinit_pdev(psoc, pdev); + } else if ((target_type == TARGET_TYPE_IPQ4019) || + (target_type == TARGET_TYPE_QCA9984) || + (target_type == TARGET_TYPE_QCA9888)) { + + return cfr_wifi2_0_deinit_pdev(psoc, pdev); + } else if (target_type == TARGET_TYPE_QCA6018) { + return cfr_6018_deinit_pdev(psoc, pdev); + } else + return QDF_STATUS_E_NOSUPPORT; +} +#endif + +#ifdef WLAN_ENH_CFR_ENABLE +#ifdef QCA_WIFI_QCA6490 +static uint8_t target_if_cfr_get_mac_id(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_channel *bss_chan; + struct pdev_cfr *pcfr; + uint8_t mac_id = 0; + + if (!pdev) { + cfr_err("null pdev"); + return mac_id; + } + + mac_id = wlan_objmgr_pdev_get_pdev_id(pdev); + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("null pcfr"); + return mac_id; + } + + if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID) + return mac_id; + + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, + pcfr->rcc_param.vdev_id, + WLAN_CFR_ID); + if (!vdev) { + cfr_err("null vdev"); + return mac_id; + } + + bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); + if (!bss_chan) { + cfr_info("null bss chan"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + return mac_id; + } + + cfr_debug("bss freq %d", bss_chan->ch_freq); + if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq)) + mac_id = CFR_MAC_ID_24G; + else + mac_id = CFR_MAC_ID_5G; + + pcfr->rcc_param.srng_id = mac_id; + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + + return mac_id; +} + +static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev) +{ + return target_if_cfr_get_mac_id(pdev); +} +#else +static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev) +{ + return wlan_objmgr_pdev_get_pdev_id(pdev); +} +#endif /* QCA_WIFI_QCA6490 */ + +QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_info) +{ + QDF_STATUS status; + struct wmi_unified *pdev_wmi_handle = NULL; + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); + if (!pdev_wmi_handle) { + cfr_err("pdev_wmi_handle is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + rcc_info->pdev_id = target_if_cfr_get_pdev_id(pdev); + rcc_info->num_grp_tlvs = + count_set_bits(rcc_info->modified_in_curr_session); + + status = wmi_unified_send_cfr_rcc_cmd(pdev_wmi_handle, rcc_info); + return status; +} + +void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_info, + bool allvalid, uint16_t reset_cfg) +{ + struct ta_ra_cfr_cfg *curr_cfg = NULL; + int grp_id; + unsigned long bitmap = reset_cfg; + uint8_t def_mac[QDF_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}; + uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0}; + + for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { + if (qdf_test_bit(grp_id, &bitmap)) { + curr_cfg = &rcc_info->curr[grp_id]; + qdf_mem_copy(curr_cfg->tx_addr, + def_mac, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->tx_addr_mask, + null_mac, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->rx_addr, + def_mac, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->rx_addr_mask, + null_mac, QDF_MAC_ADDR_SIZE); + curr_cfg->bw = 0xf; + curr_cfg->nss = 0xff; + curr_cfg->mgmt_subtype_filter = 0xffff; + curr_cfg->ctrl_subtype_filter = 0xffff; + curr_cfg->data_subtype_filter = 0xffff; + if (!allvalid) { + curr_cfg->valid_ta = 0; + curr_cfg->valid_ta_mask = 0; + curr_cfg->valid_ra = 0; + curr_cfg->valid_ra_mask = 0; + curr_cfg->valid_bw_mask = 0; + curr_cfg->valid_nss_mask = 0; + curr_cfg->valid_mgmt_subtype = 0; + curr_cfg->valid_ctrl_subtype = 0; + curr_cfg->valid_data_subtype = 0; + } else { + curr_cfg->valid_ta = 1; + curr_cfg->valid_ta_mask = 1; + curr_cfg->valid_ra = 1; + curr_cfg->valid_ra_mask = 1; + curr_cfg->valid_bw_mask = 1; + curr_cfg->valid_nss_mask = 1; + curr_cfg->valid_mgmt_subtype = 1; + curr_cfg->valid_ctrl_subtype = 1; + curr_cfg->valid_data_subtype = 1; + } + } + } +} +#endif + +#ifdef WLAN_ENH_CFR_ENABLE +#ifdef CFR_USE_FIXED_FOLDER +static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + tx_ops->cfr_tx_ops.cfr_subscribe_ppdu_desc = + target_if_cfr_subscribe_ppdu_desc; +} +#else +static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif /* CFR_USE_FIXED_FOLDER */ +static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + tx_ops->cfr_tx_ops.cfr_config_rcc = + target_if_cfr_config_rcc; + tx_ops->cfr_tx_ops.cfr_start_lut_timer = + target_if_cfr_start_lut_age_timer; + tx_ops->cfr_tx_ops.cfr_stop_lut_timer = + target_if_cfr_stop_lut_age_timer; + tx_ops->cfr_tx_ops.cfr_default_ta_ra_cfg = + target_if_cfr_default_ta_ra_config; + tx_ops->cfr_tx_ops.cfr_dump_lut_enh = + target_if_cfr_dump_lut_enh; + tx_ops->cfr_tx_ops.cfr_rx_tlv_process = + target_if_cfr_rx_tlv_process; + tx_ops->cfr_tx_ops.cfr_update_global_cfg = + target_if_cfr_update_global_cfg; + target_if_enh_cfr_add_ops(tx_ops); +} +#else +static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif + +void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + tx_ops->cfr_tx_ops.cfr_init_pdev = + target_if_cfr_init_pdev; + tx_ops->cfr_tx_ops.cfr_deinit_pdev = + target_if_cfr_deinit_pdev; + tx_ops->cfr_tx_ops.cfr_enable_cfr_timer = + target_if_cfr_enable_cfr_timer; + tx_ops->cfr_tx_ops.cfr_start_capture = + target_if_cfr_start_capture; + tx_ops->cfr_tx_ops.cfr_stop_capture = + target_if_cfr_stop_capture; + target_if_enh_cfr_tx_ops(tx_ops); +} + +void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + if (psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_support_set) + psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_support_set(psoc, value); +} + +void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, + size_t hlen, void *data, size_t dlen, void *tail, + size_t tlen) +{ + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + + if (psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_info_send) + psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_info_send(pdev, head, hlen, + data, dlen, tail, + tlen); +} diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6018.c b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6018.c new file mode 100644 index 0000000000000000000000000000000000000000..de491aa41e2ca1f8f3a97e5e999ec51eccd88787 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6018.c @@ -0,0 +1,1638 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DIRECT_BUF_RX_ENABLE +#include +#endif +#include +#include "cdp_txrx_ctrl.h" + +#define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1) + +static u_int32_t end_magic = 0xBEAFDEAD; +/** + * get_lut_entry() - Retrieve LUT entry using cookie number + * @pcfr: PDEV CFR object + * @offset: cookie number + * + * Return: look up table entry + */ +static struct look_up_table *get_lut_entry(struct pdev_cfr *pcfr, + int offset) +{ + if (offset >= pcfr->lut_num) { + cfr_err("Invalid offset %d, lut_num %d", + offset, pcfr->lut_num); + return NULL; + } + + return pcfr->lut[offset]; +} + +/** + * release_lut_entry_enh() - Clear all params in an LUT entry + * @pdev: objmgr PDEV + * @lut: pointer to LUT + * + * Return: status + */ +static int release_lut_entry_enh(struct wlan_objmgr_pdev *pdev, + struct look_up_table *lut) +{ + lut->dbr_recv = false; + lut->tx_recv = false; + lut->data = NULL; + lut->data_len = 0; + lut->dbr_ppdu_id = 0; + lut->tx_ppdu_id = 0; + lut->dbr_tstamp = 0; + lut->txrx_tstamp = 0; + lut->tx_address1 = 0; + lut->tx_address2 = 0; + lut->dbr_address = 0; + qdf_mem_zero(&lut->header, sizeof(struct csi_cfr_header)); + + return 0; +} + +/** + * target_if_cfr_dump_lut_enh() - dump all valid lut entries + * @pdev: objmgr pdev + * + * return: none + */ +void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pcfr; + struct look_up_table *lut = NULL; + int i = 0; + uint64_t diff; + QDF_STATUS retval = 0; + + retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); + if (retval != QDF_STATUS_SUCCESS) { + cfr_err("failed to get pdev reference"); + return; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pdev object for CFR is null"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return; + } + + for (i = 0; i < pcfr->lut_num; i++) { + lut = get_lut_entry(pcfr, i); + if (!lut) + continue; + if (lut->dbr_recv ^ lut->tx_recv) { + diff = (lut->dbr_tstamp > lut->txrx_tstamp) ? + (lut->dbr_tstamp - lut->txrx_tstamp) : + (lut->txrx_tstamp - lut->dbr_tstamp); + cfr_err("idx:%d dbrevnt: %d txrxevent: %d " + "dbrppdu:0x%x txrxppdu:0x%x dbr_tstamp: %llu " + "txrx_tstamp: %llu diff: %llu\n", + i, lut->dbr_recv, lut->tx_recv, + lut->dbr_ppdu_id, lut->tx_ppdu_id, + lut->dbr_tstamp, lut->txrx_tstamp, diff); + } + + } + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); +} + +/** + * cfr_free_pending_dbr_events() - Flush all pending DBR events. This is useful + * in cases where for RXTLV drops in host monitor status ring is huge. + * @pdev: objmgr pdev + * + * return: none + */ +static void cfr_free_pending_dbr_events(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pcfr; + struct look_up_table *lut = NULL; + int i = 0; + QDF_STATUS retval = 0; + + retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); + if (retval != QDF_STATUS_SUCCESS) { + cfr_err("failed to get pdev reference"); + return; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pdev object for CFR is null"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return; + } + + for (i = 0; i < pcfr->lut_num; i++) { + lut = get_lut_entry(pcfr, i); + if (!lut) + continue; + + if (lut->dbr_recv && !lut->tx_recv && + (lut->dbr_tstamp < pcfr->last_success_tstamp)) { + target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, + lut->dbr_address, + i, 0); + pcfr->flush_dbr_cnt++; + release_lut_entry_enh(pdev, lut); + } + } + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); +} + +/** + * dump_freeze_tlv() - Dump freeze TLV sent in enhanced DMA header + * @freeze_tlv: Freeze TLV sent from MAC to PHY + * @cookie: Index into lookup table + * + * Return: none + */ +static void dump_freeze_tlv(void *freeze_tlv, uint32_t cookie) +{ + struct macrx_freeze_capture_channel *freeze = + (struct macrx_freeze_capture_channel *)freeze_tlv; + + cfr_debug("<%u>\n" + "freeze: %d capture_reason: %d packet_type: 0x%x\n" + "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" + "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n" + "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n" + "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n" + "packet_ra_lower_16: 0x%04x tsf_timestamp_63_48: 0x%04x\n" + "tsf_timestamp_47_32: 0x%04x tsf_timestamp_31_16: 0x%04x\n" + "tsf_timestamp_15_0: 0x%04x user_index: %d directed: %d\n", + cookie, + freeze->freeze, + freeze->capture_reason, + freeze->packet_type, + freeze->packet_sub_type, + freeze->sw_peer_id_valid, + freeze->sw_peer_id, + freeze->phy_ppdu_id, + freeze->packet_ta_upper_16, + freeze->packet_ta_mid_16, + freeze->packet_ta_lower_16, + freeze->packet_ra_upper_16, + freeze->packet_ra_mid_16, + freeze->packet_ra_lower_16, + freeze->tsf_timestamp_63_48, + freeze->tsf_timestamp_47_32, + freeze->tsf_timestamp_31_16, + freeze->tsf_timestamp_15_0, + freeze->user_index, + freeze->directed); +} + +/** + * dump_mu_rx_info() - Dump MU info in enhanced DMA header + * @mu_rx_user_info: MU info sent by ucode + * @mu_rx_num_users: Number of MU users in UL-MU-PPDU + * @cookie: Index into lookup table + * + * Return: none + */ +static void dump_mu_rx_info(void *mu_rx_user_info, + uint8_t mu_rx_num_users, + uint32_t cookie) +{ + uint8_t i; + struct uplink_user_setup_info *ul_mu_user_info = + (struct uplink_user_setup_info *) mu_rx_user_info; + + for (i = 0 ; i < mu_rx_num_users; i++) { + cfr_debug("<%u>\n" + "\n" + "bw_info_valid = %d\n" + "uplink_receive_type = %d\n" + "uplink_11ax_mcs = %d\n" + "ru_width = %d\n" + "nss = %d\n" + "stream_offset = %d\n" + "sta_dcm = %d\n" + "sta_coding = %d\n" + "ru_start_index = %d\n", + cookie, + i, + ul_mu_user_info->bw_info_valid, + ul_mu_user_info->uplink_receive_type, + ul_mu_user_info->uplink_11ax_mcs, + ul_mu_user_info->ru_width, + ul_mu_user_info->nss, + ul_mu_user_info->stream_offset, + ul_mu_user_info->sta_dcm, + ul_mu_user_info->sta_coding, + ul_mu_user_info->ru_start_index); + ul_mu_user_info += sizeof(struct uplink_user_setup_info); + } +} + +static void dump_metadata(struct csi_cfr_header *header, uint32_t cookie) +{ + uint8_t user_id, chain_id; + struct cfr_metadata_version_3 *meta = &header->u.meta_v3; + uint8_t *usermac = NULL; + + cfr_debug("<%u>\n" + "start_magic_num = 0x%x\n" + "vendorid = 0x%x\n" + "cfr_metadata_version = %d\n" + "cfr_data_version = %d\n" + "chip_type = %d\n" + "platform_type = %d\n" + "status = %d\n" + "capture_bw = %d\n" + "channel_bw = %d\n" + "phy_mode = %d\n" + "prim20_chan = %d\n" + "center_freq1 = %d\n" + "center_freq2 = %d\n" + "ack_capture_mode = %d\n" + "cfr_capture_type = %d\n" + "sts_count = %d\n" + "num_rx_chain = %d\n" + "timestamp = %llu\n" + "length = %d\n" + "is_mu_ppdu = %d\n" + "num_users = %d\n", + cookie, + header->start_magic_num, + header->vendorid, + header->cfr_metadata_version, + header->cfr_data_version, + header->chip_type, + header->pltform_type, + meta->status, + meta->capture_bw, + meta->channel_bw, + meta->phy_mode, + meta->prim20_chan, + meta->center_freq1, + meta->center_freq2, + meta->capture_mode, + meta->capture_type, + meta->sts_count, + meta->num_rx_chain, + meta->timestamp, + meta->length, + meta->is_mu_ppdu, + meta->num_mu_users); + + if (meta->is_mu_ppdu) { + for (user_id = 0; user_id < meta->num_mu_users; user_id++) { + usermac = meta->peer_addr.mu_peer_addr[user_id]; + cfr_debug("peermac[%d]: " QDF_MAC_ADDR_FMT, + user_id, QDF_MAC_ADDR_REF(usermac)); + } + } else { + cfr_debug("peermac: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(meta->peer_addr.su_peer_addr)); + } + + for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { + cfr_debug("chain_rssi[%d] = %d\n", + chain_id, + meta->chain_rssi[chain_id]); + } + + for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { + cfr_debug("chain_phase[%d] = %d\n", + chain_id, + meta->chain_phase[chain_id]); + } +} +/** + * dump_enh_dma_hdr() - Dump enhanced DMA header populated by ucode + * @dma_hdr: pointer to enhanced DMA header + * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV + * @mu_rx_user_info: UPLINK_USER_SETUP_INFO TLV + * @header: pointer to metadata passed to userspace + * @error: Indicates whether it is an error + * @cookie: Index into lookup table + * + * Return: none + */ +static void dump_enh_dma_hdr(struct whal_cfir_enhanced_hdr *dma_hdr, + void *freeze_tlv, void *mu_rx_user_info, + struct csi_cfr_header *header, int error, + uint32_t cookie) +{ + if (!error) { + cfr_debug("<%u>\n" + "Tag: 0x%02x Length: %d udone: %d\n" + "ctype: %d preamble: %d Nss: %d\n" + "num_chains: %d bw: %d peervalid: %d\n" + "peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n" + "header_version: %d target_id: %d cfr_fmt: %d\n" + "mu_rx_data_incl: %d freeze_data_incl: %d\n" + "mu_rx_num_users: %d decimation_factor: %d\n", + cookie, + dma_hdr->tag, + dma_hdr->length, + dma_hdr->upload_done, + dma_hdr->capture_type, + dma_hdr->preamble_type, + dma_hdr->nss, + dma_hdr->num_chains, + dma_hdr->upload_pkt_bw, + dma_hdr->sw_peer_id_valid, + dma_hdr->sw_peer_id, + dma_hdr->phy_ppdu_id, + dma_hdr->total_bytes, + dma_hdr->header_version, + dma_hdr->target_id, + dma_hdr->cfr_fmt, + dma_hdr->mu_rx_data_incl, + dma_hdr->freeze_data_incl, + dma_hdr->mu_rx_num_users, + dma_hdr->decimation_factor); + + if (dma_hdr->freeze_data_incl) + dump_freeze_tlv(freeze_tlv, cookie); + + if (dma_hdr->mu_rx_data_incl) + dump_mu_rx_info(mu_rx_user_info, + dma_hdr->mu_rx_num_users, + cookie); + } else { + cfr_err("<%u>\n" + "Tag: 0x%02x Length: %d udone: %d\n" + "ctype: %d preamble: %d Nss: %d\n" + "num_chains: %d bw: %d peervalid: %d\n" + "peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n" + "header_version: %d target_id: %d cfr_fmt: %d\n" + "mu_rx_data_incl: %d freeze_data_incl: %d\n" + "mu_rx_num_users: %d decimation_factor: %d\n", + cookie, + dma_hdr->tag, + dma_hdr->length, + dma_hdr->upload_done, + dma_hdr->capture_type, + dma_hdr->preamble_type, + dma_hdr->nss, + dma_hdr->num_chains, + dma_hdr->upload_pkt_bw, + dma_hdr->sw_peer_id_valid, + dma_hdr->sw_peer_id, + dma_hdr->phy_ppdu_id, + dma_hdr->total_bytes, + dma_hdr->header_version, + dma_hdr->target_id, + dma_hdr->cfr_fmt, + dma_hdr->mu_rx_data_incl, + dma_hdr->freeze_data_incl, + dma_hdr->mu_rx_num_users, + dma_hdr->decimation_factor); + } +} + + +/** + * extract_peer_mac_from_freeze_tlv() - extract macaddr from freeze tlv + * @freeze_tlv: Freeze TLV sent from MAC to PHY + * @peermac: macaddr of the peer + * + * Return: none + */ +static void +extract_peer_mac_from_freeze_tlv(void *freeze_tlv, uint8_t *peermac) +{ + struct macrx_freeze_capture_channel *freeze = + (struct macrx_freeze_capture_channel *)freeze_tlv; + + peermac[0] = freeze->packet_ta_lower_16 & 0x00FF; + peermac[1] = (freeze->packet_ta_lower_16 & 0xFF00) >> 8; + peermac[2] = freeze->packet_ta_mid_16 & 0x00FF; + peermac[3] = (freeze->packet_ta_mid_16 & 0xFF00) >> 8; + peermac[4] = freeze->packet_ta_upper_16 & 0x00FF; + peermac[5] = (freeze->packet_ta_upper_16 & 0xFF00) >> 8; +} + +/** + * check_dma_length() - Sanity check DMA header and payload length + * @dma_hdr: pointer to enhanced DMA header + * + * Return: QDF_STATUS + */ +static QDF_STATUS check_dma_length(struct look_up_table *lut) +{ + if (lut->header_length <= CYP_MAX_HEADER_LENGTH_WORDS && + lut->payload_length <= CYP_MAX_DATA_LENGTH_BYTES) { + return QDF_STATUS_SUCCESS; + } else { + return QDF_STATUS_E_FAILURE; + } +} + +/** + * correlate_and_relay_enh() - Correlate TXRX and DBR events and stream CFR + * data to userspace + * @pdev: objmgr PDEV + * @cookie: Index into lookup table + * @lut: pointer to lookup table + * @module_id: ID of the event received + * 0 - DBR event + * 1 - TXRX event + * + * Return: + * - STATUS_ERROR + * - STATUS_HOLD + * - STATUS_STREAM_AND_RELEASE + */ +static int correlate_and_relay_enh(struct wlan_objmgr_pdev *pdev, + uint32_t cookie, + struct look_up_table *lut, + uint8_t module_id) +{ + struct pdev_cfr *pcfr; + uint64_t diff; + int status = STATUS_ERROR; + + if (module_id > 1) { + cfr_err("Received request with invalid mod id. Investigate!!"); + QDF_ASSERT(0); + status = STATUS_ERROR; + goto done; + } + + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + + if (module_id == CORRELATE_TX_EV_MODULE_ID) { + if (lut->tx_recv) + pcfr->cfr_dma_aborts++; + lut->tx_recv = true; + } else if (module_id == CORRELATE_DBR_MODULE_ID) { + pcfr->dbr_evt_cnt++; + lut->dbr_recv = true; + } + + if ((lut->dbr_recv == true) && (lut->tx_recv == true)) { + if (lut->dbr_ppdu_id == lut->tx_ppdu_id) { + + pcfr->last_success_tstamp = lut->dbr_tstamp; + if (lut->dbr_tstamp > lut->txrx_tstamp) { + diff = lut->dbr_tstamp - lut->txrx_tstamp; + cfr_debug("<%u>: " + "TXRX evt -> DBR evt" + "(delay = %llu ms)\n", cookie, diff); + } else if (lut->txrx_tstamp > lut->dbr_tstamp) { + diff = lut->txrx_tstamp - lut->dbr_tstamp; + cfr_debug("<%u>: " + "DBR evt -> TXRX evt" + "(delay = %llu ms)\n", cookie, diff); + } + + /* + * Flush pending dbr events, if newer PPDU TLV is + * received + */ + cfr_free_pending_dbr_events(pdev); + + if (check_dma_length(lut) == QDF_STATUS_SUCCESS) { + pcfr->release_cnt++; + cfr_debug("<%u>:Stream and release " + "CFR data for " + "ppdu_id:0x%04x\n", cookie, + lut->tx_ppdu_id); + status = STATUS_STREAM_AND_RELEASE; + goto done; + } else { + pcfr->invalid_dma_length_cnt++; + cfr_err("<%u>:CFR buffers " + "received with invalid length " + "header_length_words = %d " + "cfr_payload_length_bytes = %d " + "ppdu_id:0x%04x\n", + cookie, + lut->header_length, + lut->payload_length, + lut->tx_ppdu_id); + /* + * Assert here as length exceeding the allowed + * limit would anyway manifest as random crash + */ + QDF_ASSERT(0); + status = STATUS_ERROR; + goto done; + } + } else { + /* + * When there is a ppdu id mismatch, discard the TXRX + * event since multiple PPDUs are likely to have same + * dma addr, due to ucode aborts + */ + cfr_debug("Received new dbr event for same " + "cookie %u", + cookie); + lut->tx_recv = false; + lut->tx_ppdu_id = 0; + pcfr->clear_txrx_event++; + pcfr->cfr_dma_aborts++; + status = STATUS_HOLD; + } + } else { + status = STATUS_HOLD; + } +done: + return status; +} + +/** + * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in + * lookup table + * @pdev_obj: PDEV object + * @nbuf: ppdu info + * + * Return: none + */ +void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) +{ + struct cdp_rx_indication_ppdu *cdp_rx_ppdu; + struct cdp_rx_stats_ppdu_user *rx_stats_peruser; + struct cdp_rx_ppdu_cfr_info *cfr_info; + qdf_dma_addr_t buf_addr = 0, buf_addr_extn = 0; + struct pdev_cfr *pcfr; + struct look_up_table *lut = NULL; + struct csi_cfr_header *header = NULL; + uint32_t cookie; + struct wlan_objmgr_psoc *psoc; + struct wlan_channel *bss_chan; + enum wlan_phymode ch_phymode; + uint16_t ch_freq; + uint32_t ch_cfreq1; + uint32_t ch_cfreq2; + struct wlan_objmgr_vdev *vdev = NULL; + int i, status = 0; + QDF_STATUS retval = 0; + struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; + struct cfr_metadata_version_3 *meta = NULL; + uint8_t srng_id = 0; + + if (qdf_unlikely(!pdev)) { + cfr_err("pdev is null\n"); + qdf_nbuf_free(nbuf); + return; + } + + retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); + if (qdf_unlikely(retval != QDF_STATUS_SUCCESS)) { + cfr_err("failed to get pdev reference"); + qdf_nbuf_free(nbuf); + return; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (qdf_unlikely(!pcfr)) { + cfr_err("pdev object for CFR is NULL"); + goto done; + } + + cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(nbuf); + cfr_info = &cdp_rx_ppdu->cfr_info; + + if (!cfr_info->bb_captured_channel) + goto done; + + psoc = wlan_pdev_get_psoc(pdev); + if (qdf_unlikely(!psoc)) { + cfr_err("psoc is null\n"); + goto done; + } + + cfr_rx_ops = &psoc->soc_cb.rx_ops.cfr_rx_ops; + buf_addr_extn = cfr_info->rtt_che_buffer_pointer_high8 & 0xF; + buf_addr = (cfr_info->rtt_che_buffer_pointer_low32 | + ((uint64_t)buf_addr_extn << 32)); + + srng_id = pcfr->rcc_param.srng_id; + if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, + &cookie, srng_id)) { + cfr_debug("Cookie lookup failure for addr: 0x%pK", + (void *)((uintptr_t)buf_addr)); + goto done; + } + + cfr_debug("<%u>:buffer address: 0x%pK \n" + " ppdu_id: 0x%04x\n" + " BB_CAPTURED_CHANNEL = %d\n" + " RX_LOCATION_INFO_VALID = %d\n" + " RTT_CHE_BUFFER_POINTER_LOW32 = %x\n" + " RTT_CHE_BUFFER_POINTER_HIGH8 = %x\n" + " CHAN_CAPTURE_STATUS = %d\n", + cookie, + (void *)((uintptr_t)buf_addr), + cdp_rx_ppdu->ppdu_id, + cfr_info->bb_captured_channel, + cfr_info->rx_location_info_valid, + cfr_info->rtt_che_buffer_pointer_low32, + cfr_info->rtt_che_buffer_pointer_high8, + cfr_info->chan_capture_status); + + lut = get_lut_entry(pcfr, cookie); + if (qdf_unlikely(!lut)) { + cfr_err("lut is NULL"); + goto done; + } + + if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID) + vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID); + else + vdev = wlan_objmgr_get_vdev_by_id_from_pdev( + pdev, pcfr->rcc_param.vdev_id, WLAN_CFR_ID); + if (qdf_unlikely(!vdev)) { + cfr_debug("vdev is null\n"); + goto done; + } + + bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); + ch_freq = bss_chan->ch_freq; + ch_cfreq1 = bss_chan->ch_cfreq1; + ch_cfreq2 = bss_chan->ch_cfreq2; + ch_phymode = bss_chan->ch_phymode; + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + + pcfr->rx_tlv_evt_cnt++; + lut->tx_ppdu_id = cdp_rx_ppdu->ppdu_id; + lut->tx_address1 = cfr_info->rtt_che_buffer_pointer_low32; + lut->tx_address2 = cfr_info->rtt_che_buffer_pointer_high8; + lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); + header = &lut->header; + meta = &header->u.meta_v3; + + header->start_magic_num = 0xDEADBEAF; + header->vendorid = 0x8cfdf0; + header->cfr_metadata_version = CFR_META_VERSION_3; + header->cfr_data_version = CFR_DATA_VERSION_1; + header->chip_type = pcfr->chip_type; + header->pltform_type = CFR_PLATFORM_TYPE_ARM; + header->Reserved = 0; + + meta->status = 1; + meta->phy_mode = ch_phymode; + meta->prim20_chan = ch_freq; + meta->center_freq1 = ch_cfreq1; + meta->center_freq2 = ch_cfreq2; + meta->capture_mode = 0; + + meta->timestamp = cdp_rx_ppdu->timestamp; + meta->is_mu_ppdu = (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) ? 0 : 1; + meta->num_mu_users = (meta->is_mu_ppdu) ? (cdp_rx_ppdu->num_users) : 0; + + if (meta->num_mu_users > CYP_CFR_MU_USERS) + meta->num_mu_users = CYP_CFR_MU_USERS; + + for (i = 0; i < MAX_CHAIN; i++) + meta->chain_rssi[i] = cdp_rx_ppdu->per_chain_rssi[i]; + + if (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) { + qdf_mem_copy(meta->peer_addr.su_peer_addr, + cdp_rx_ppdu->mac_addr, + QDF_MAC_ADDR_SIZE); + } else { + for (i = 0 ; i < meta->num_mu_users; i++) { + rx_stats_peruser = &cdp_rx_ppdu->user[i]; + qdf_mem_copy(meta->peer_addr.mu_peer_addr[i], + rx_stats_peruser->mac_addr, + QDF_MAC_ADDR_SIZE); + } + } + status = correlate_and_relay_enh(pdev, cookie, lut, + CORRELATE_TX_EV_MODULE_ID); + if (status == STATUS_STREAM_AND_RELEASE) { + if (cfr_rx_ops->cfr_info_send) + status = cfr_rx_ops->cfr_info_send(pdev, + &lut->header, + sizeof(struct + csi_cfr_header), + lut->data, + lut->data_len, + &end_magic, 4); + dump_metadata(header, cookie); + release_lut_entry_enh(pdev, lut); + target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, + cookie, srng_id); + cfr_debug("Data sent to upper layers, release look up table"); + } else if (status == STATUS_HOLD) { + cfr_debug("HOLD for buffer address: 0x%pK cookie: %u", + (void *)((uintptr_t)buf_addr), cookie); + } else { + cfr_err("Correlation returned invalid status!!"); + } +done: + qdf_nbuf_free(nbuf); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); +} + +/** + * freeze_reason_to_capture_type() - Convert capture type enum in freeze tlv + * to the cfr type enum shared with userspace + * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV + * + * Return: cfr type enum + */ +static uint8_t freeze_reason_to_capture_type(void *freeze_tlv) +{ + struct macrx_freeze_capture_channel *freeze = + (struct macrx_freeze_capture_channel *)freeze_tlv; + + switch (freeze->capture_reason) { + case FREEZE_REASON_TM: + return CFR_TYPE_METHOD_TM; + case FREEZE_REASON_FTM: + return CFR_TYPE_METHOD_FTM; + case FREEZE_REASON_TA_RA_TYPE_FILTER: + return CFR_TYPE_METHOD_TA_RA_TYPE_FILTER; + case FREEZE_REASON_NDPA_NDP: + return CFR_TYPE_METHOD_NDPA_NDP; + case FREEZE_REASON_ALL_PACKET: + return CFR_TYPE_METHOD_ALL_PACKET; + case FREEZE_REASON_ACK_RESP_TO_TM_FTM: + return CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM; + default: + return CFR_TYPE_METHOD_AUTO; + } + return CFR_TYPE_METHOD_AUTO; +} + +#ifdef DIRECT_BUF_RX_ENABLE +/** + * enh_cfr_dbr_event_handler() - Process DBR event for CFR data DMA completion + * @pdev: PDEV object + * @payload: pointer to CFR data + * + * Return: status + */ +static bool enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev, + struct direct_buf_rx_data *payload) +{ + uint8_t *data = NULL; + uint32_t cookie = 0; + struct whal_cfir_enhanced_hdr dma_hdr = {0}; + int length, status = 0; + struct wlan_objmgr_psoc *psoc; + struct pdev_cfr *pcfr; + struct look_up_table *lut = NULL; + struct csi_cfr_header *header = NULL; + void *mu_rx_user_info = NULL, *freeze_tlv = NULL; + uint8_t capture_type = CFR_TYPE_METHOD_AUTO; + uint8_t *peer_macaddr = NULL; + struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; + struct cfr_metadata_version_3 *meta = NULL; + + if ((!pdev) || (!payload)) { + cfr_err("pdev or payload is null"); + return true; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + cfr_err("psoc is null"); + return true; + } + + cfr_rx_ops = &psoc->soc_cb.rx_ops.cfr_rx_ops; + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pdev object for CFR is null"); + return true; + } + + data = payload->vaddr; + cookie = payload->cookie; + + cfr_debug("<%u>:bufferaddr: 0x%pK cookie: %u\n", cookie, + (void *)((uintptr_t)payload->paddr), cookie); + + qdf_mem_copy(&dma_hdr, &data[0], + sizeof(struct whal_cfir_enhanced_hdr)); + + if (dma_hdr.freeze_data_incl) { + freeze_tlv = data + sizeof(struct whal_cfir_enhanced_hdr); + capture_type = freeze_reason_to_capture_type(freeze_tlv); + } + + if (dma_hdr.mu_rx_data_incl) { + mu_rx_user_info = data + + sizeof(struct whal_cfir_enhanced_hdr) + + (dma_hdr.freeze_data_incl ? + sizeof(struct macrx_freeze_capture_channel) : 0); + } + + + length = dma_hdr.length * 4; + length += dma_hdr.total_bytes; /* size of cfr data */ + + lut = get_lut_entry(pcfr, cookie); + if (!lut) { + cfr_err("lut is NULL"); + return true; + } + + lut->data = data; + lut->data_len = length; + lut->dbr_ppdu_id = dma_hdr.phy_ppdu_id; + lut->dbr_address = payload->paddr; + lut->dbr_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); + lut->header_length = dma_hdr.length; + lut->payload_length = dma_hdr.total_bytes; + qdf_mem_copy(&lut->dma_hdr, &dma_hdr, + sizeof(struct whal_cfir_dma_hdr)); + + header = &lut->header; + meta = &header->u.meta_v3; + meta->channel_bw = dma_hdr.upload_pkt_bw; + meta->num_rx_chain = NUM_CHAINS_FW_TO_HOST(dma_hdr.num_chains); + meta->length = length; + /* For Tx based captures, capture type is sent from FW */ + if (capture_type != CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM) { + meta->capture_type = capture_type; + meta->sts_count = (dma_hdr.nss + 1); + if (!dma_hdr.mu_rx_data_incl) { + /* extract peer addr from freeze tlv */ + peer_macaddr = meta->peer_addr.su_peer_addr; + if (dma_hdr.freeze_data_incl) { + extract_peer_mac_from_freeze_tlv(freeze_tlv, + peer_macaddr); + } + } + } + + if (dma_hdr.freeze_data_incl) { + dump_enh_dma_hdr(&dma_hdr, freeze_tlv, mu_rx_user_info, + header, 0, cookie); + } + + status = correlate_and_relay_enh(pdev, cookie, lut, + CORRELATE_DBR_MODULE_ID); + if (status == STATUS_STREAM_AND_RELEASE) { + /* + * Message format + * Meta data Header + actual payload + trailer + */ + if (cfr_rx_ops->cfr_info_send) + status = cfr_rx_ops->cfr_info_send(pdev, + &lut->header, + sizeof(struct + csi_cfr_header), + lut->data, + lut->data_len, + &end_magic, 4); + dump_metadata(header, cookie); + release_lut_entry_enh(pdev, lut); + cfr_debug("Data sent to upper layers, released look up table"); + status = true; + } else if (status == STATUS_HOLD) { + cfr_debug("TxRx event not received yet. " + "Buffer is not released"); + status = false; + } else { + cfr_err("Correlation returned invalid status!!"); + status = true; + } + + return status; +} + +/** + * target_if_register_to_dbr_enh() - Initialize DBR ring and register callback + * for DBR events + * @pdev: PDEV object + * + * Return: status + */ +static QDF_STATUS +target_if_register_to_dbr_enh(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + struct dbr_module_config dbr_config; + + psoc = wlan_pdev_get_psoc(pdev); + dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_CFR; + dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_CFR; + if (dbr_tx_ops->direct_buf_rx_module_register) { + return dbr_tx_ops->direct_buf_rx_module_register + (pdev, DBR_MODULE_CFR, &dbr_config, + enh_cfr_dbr_event_handler); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_unregister_to_dbr_enh() - Unregister callback for DBR events + * @pdev: PDEV object + * + * Return: status + */ +static QDF_STATUS +target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + + psoc = wlan_pdev_get_psoc(pdev); + dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + if (dbr_tx_ops->direct_buf_rx_module_unregister) { + return dbr_tx_ops->direct_buf_rx_module_unregister + (pdev, DBR_MODULE_CFR); + } + + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * dump_cfr_peer_tx_event_enh() - Dump TX completion event + * @event: ptr to WMI TX completion event for QOS frames sent during + * one-shot capture + * @cookie: Index into lookup table + * + * Return: none + */ +static void dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param *event, + uint32_t cookie) +{ + cfr_debug("<%u>CFR capture method: %d vdev_id: %d mac: " + QDF_MAC_ADDR_FMT, cookie, + event->capture_method, event->vdev_id, + QDF_MAC_ADDR_REF(event->peer_mac_addr.bytes)); + + cfr_debug("<%u>Chan: %d bw: %d phymode: %d cfreq1: %d cfrq2: %d " + "nss: %d\n", + cookie, + event->primary_20mhz_chan, event->bandwidth, + event->phy_mode, event->band_center_freq1, + event->band_center_freq2, event->spatial_streams); + + cfr_debug("<%u>Correlation_info1: 0x%08x " + "Correlation_info2: 0x%08x\n", + cookie, + event->correlation_info_1, event->correlation_info_2); + + cfr_debug("<%u>status: 0x%x ts: %d counter: %d rssi0: 0x%08x\n", + cookie, + event->status, event->timestamp_us, event->counter, + event->chain_rssi[0]); +} + +#ifdef DIRECT_BUF_RX_ENABLE +/** + * enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures + * @tx_evt_param: ptr to WMI TX completion event + * @header: pointer to metadata + * + * Return: none + */ +static void enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param + *tx_evt_param, + struct csi_cfr_header *header) +{ + header->start_magic_num = 0xDEADBEAF; + header->vendorid = 0x8cfdf0; + header->cfr_metadata_version = CFR_META_VERSION_3; + header->cfr_data_version = CFR_DATA_VERSION_1; + header->chip_type = CFR_CAPTURE_RADIO_CYP; + header->pltform_type = CFR_PLATFORM_TYPE_ARM; + header->Reserved = 0; + header->u.meta_v3.status = 0; /* failure */ + header->u.meta_v3.length = 0; + + qdf_mem_copy(&header->u.meta_v2.peer_addr[0], + &tx_evt_param->peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); + +} + +/** + * target_if_peer_capture_event() - WMI TX completion event for one-shot + * capture + * @sc: pointer to offload soc object + * @data: WMI TX completion event buffer + * @datalen: WMI Tx completion event buffer length + * + * Return: status + */ +static int +target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) +{ + QDF_STATUS retval = 0; + struct wmi_unified *wmi_handle; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_vdev *vdev; + uint32_t cookie; + struct pdev_cfr *pcfr; + struct look_up_table *lut = NULL; + struct csi_cfr_header *header = NULL; + struct csi_cfr_header header_error = {0}; + wmi_cfr_peer_tx_event_param tx_evt_param = {0}; + qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0; + int status; + struct wlan_channel *bss_chan; + struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; + + if (!sc || !data) { + cfr_err("sc or data is null"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(sc); + if (!psoc) { + cfr_err("psoc is null"); + return -EINVAL; + } + + cfr_rx_ops = &psoc->soc_cb.rx_ops.cfr_rx_ops; + + retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID); + if (QDF_IS_STATUS_ERROR(retval)) { + cfr_err("unable to get psoc reference"); + return -EINVAL; + } + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + cfr_err("wmi_handle is null"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + return -EINVAL; + } + + + retval = wmi_extract_cfr_peer_tx_event_param(wmi_handle, data, + &tx_evt_param); + + if (retval != QDF_STATUS_SUCCESS) { + cfr_err("Failed to extract cfr tx event param"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + return -EINVAL; + } + + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_evt_param.vdev_id, + WLAN_CFR_ID); + if (!vdev) { + cfr_err("vdev is null"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + return -EINVAL; + } + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + cfr_err("pdev is null"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + return -EINVAL; + } + + retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); + if (retval != QDF_STATUS_SUCCESS) { + cfr_err("failed to get pdev reference"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + return -EINVAL; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pdev object for CFR is NULL"); + retval = -EINVAL; + goto end; + } + + if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK) == 1) { + cfr_err("CFR capture failed as peer is in powersave: " + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); + + enh_prepare_cfr_header_txstatus(&tx_evt_param, &header_error); + if (cfr_rx_ops->cfr_info_send) + cfr_rx_ops->cfr_info_send(pdev, + &header_error, + sizeof(struct + csi_cfr_header), + NULL, 0, &end_magic, 4); + + retval = -EINVAL; + goto end; + } + + if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_STATUS_MASK) == 0) { + cfr_debug("CFR capture failed for peer: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); + retval = -EINVAL; + goto end; + } + + if (tx_evt_param.status & CFR_TX_EVT_STATUS_MASK) { + cfr_debug("TX packet returned status %d for peer: " + QDF_MAC_ADDR_FMT, + tx_evt_param.status & CFR_TX_EVT_STATUS_MASK, + QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); + retval = -EINVAL; + goto end; + } + + buf_addr_temp = (tx_evt_param.correlation_info_2 & 0x0f); + buf_addr = (tx_evt_param.correlation_info_1 | + ((uint64_t)buf_addr_temp << 32)); + + if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, + &cookie, 0)) { + cfr_debug("Cookie lookup failure for addr: 0x%pK status: 0x%x", + (void *)((uintptr_t)buf_addr), tx_evt_param.status); + retval = -EINVAL; + goto end; + } + + cfr_debug("buffer address: 0x%pK cookie: %u", + (void *)((uintptr_t)buf_addr), cookie); + + dump_cfr_peer_tx_event_enh(&tx_evt_param, cookie); + + lut = get_lut_entry(pcfr, cookie); + if (!lut) { + cfr_err("lut is NULL\n"); + retval = -EINVAL; + goto end; + } + + pcfr->tx_evt_cnt++; + pcfr->total_tx_evt_cnt++; + + lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16); + lut->tx_address1 = tx_evt_param.correlation_info_1; + lut->tx_address2 = tx_evt_param.correlation_info_2; + lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); + + header = &lut->header; + header->start_magic_num = 0xDEADBEAF; + header->vendorid = 0x8cfdf0; + header->cfr_metadata_version = CFR_META_VERSION_3; + header->cfr_data_version = CFR_DATA_VERSION_1; + header->chip_type = CFR_CAPTURE_RADIO_CYP; + header->pltform_type = CFR_PLATFORM_TYPE_ARM; + header->Reserved = 0; + header->u.meta_v3.status = (tx_evt_param.status & + PEER_CFR_CAPTURE_EVT_STATUS_MASK) ? + 1 : 0; + header->u.meta_v3.capture_bw = tx_evt_param.bandwidth; + + bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); + header->u.meta_v3.phy_mode = bss_chan->ch_phymode; + + header->u.meta_v3.prim20_chan = tx_evt_param.primary_20mhz_chan; + header->u.meta_v3.center_freq1 = tx_evt_param.band_center_freq1; + header->u.meta_v3.center_freq2 = tx_evt_param.band_center_freq2; + + /* Currently CFR data is captured on ACK of a Qos NULL frame. + * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy. + */ + header->u.meta_v3.capture_mode = tx_evt_param.bandwidth ? + CFR_DUP_LEGACY_ACK : CFR_LEGACY_ACK; + header->u.meta_v3.capture_type = tx_evt_param.capture_method; + header->u.meta_v3.num_rx_chain = wlan_vdev_mlme_get_rxchainmask(vdev); + header->u.meta_v3.sts_count = tx_evt_param.spatial_streams; + header->u.meta_v3.timestamp = tx_evt_param.timestamp_us; + + qdf_mem_copy(&header->u.meta_v3.peer_addr.su_peer_addr[0], + &tx_evt_param.peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); + qdf_mem_copy(&header->u.meta_v3.chain_rssi[0], + &tx_evt_param.chain_rssi[0], + HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_rssi[0])); + qdf_mem_copy(&header->u.meta_v3.chain_phase[0], + &tx_evt_param.chain_phase[0], + HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_phase[0])); + + status = correlate_and_relay_enh(pdev, cookie, lut, + CORRELATE_TX_EV_MODULE_ID); + if (status == STATUS_STREAM_AND_RELEASE) { + if (cfr_rx_ops->cfr_info_send) + status = cfr_rx_ops->cfr_info_send(pdev, + &lut->header, + sizeof( + struct + csi_cfr_header), + lut->data, + lut->data_len, + &end_magic, 4); + dump_metadata(header, cookie); + release_lut_entry_enh(pdev, lut); + target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, + cookie, 0); + cfr_debug("Data sent to upper layers, " + "releasing look up table"); + } else if (status == STATUS_HOLD) { + cfr_debug("HOLD for buffer address: 0x%pK cookie: %u", + (void *)((uintptr_t)buf_addr), cookie); + } else { + cfr_err("Correlation returned invalid status!!"); + retval = -EINVAL; + goto end; + } + +end: + + wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return retval; +} +#else +static int +target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) +{ + return 0; +} +#endif + +/** + * target_if_register_tx_completion_enh_event_handler() - Register callback for + * WMI TX completion event + * @psoc: PSOC object + * + * Return: Success/Failure status + */ +static int +target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc + *psoc) +{ + /* Register completion handler here */ + wmi_unified_t wmi_hdl; + int ret = 0; + + wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_hdl) { + cfr_err("Unable to get wmi handle"); + return -EINVAL; + } + + ret = wmi_unified_register_event_handler(wmi_hdl, + wmi_peer_cfr_capture_event_id, + target_if_peer_capture_event, + WMI_RX_UMAC_CTX); + /* + * Event registration is called per pdev + * Ignore erorr if event is alreday registred. + */ + if (ret == QDF_STATUS_E_FAILURE) + ret = QDF_STATUS_SUCCESS; + + return ret; +} + +/** + * target_if_unregister_tx_completion_enh_event_handler() - Unregister callback + * for WMI TX completion event + * @psoc: PSOC object + * + * Return: Success/Failure status + */ +static int +target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc + *psoc) +{ + /* Unregister completion handler here */ + wmi_unified_t wmi_hdl; + int status = 0; + + wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_hdl) { + cfr_err("Unable to get wmi handle"); + return -EINVAL; + } + + status = wmi_unified_unregister_event(wmi_hdl, + wmi_peer_cfr_capture_event_id); + return status; +} + +/** + * lut_ageout_timer_task() - Timer to flush pending TXRX/DBR events + * + * Return: none + */ +static os_timer_func(lut_ageout_timer_task) +{ + int i = 0; + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct look_up_table *lut = NULL; + uint64_t diff, cur_tstamp; + uint8_t srng_id = 0; + + OS_GET_TIMER_ARG(pcfr, struct pdev_cfr*); + + if (!pcfr) { + cfr_err("pdev object for CFR is null"); + return; + } + + pdev = pcfr->pdev_obj; + if (!pdev) { + cfr_err("pdev is null"); + return; + } + + srng_id = pcfr->rcc_param.srng_id; + if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID) + != QDF_STATUS_SUCCESS) { + cfr_err("failed to get pdev reference"); + return; + } + + cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); + + for (i = 0; i < pcfr->lut_num; i++) { + lut = get_lut_entry(pcfr, i); + if (!lut) + continue; + + if (lut->dbr_recv && !lut->tx_recv) { + diff = cur_tstamp - lut->dbr_tstamp; + if (diff > LUT_AGE_THRESHOLD) { + cfr_debug("<%d>TXRX event not received for " + "%llu ms, release lut entry : " + "dma_addr = 0x%pK\n", i, diff, + (void *)((uintptr_t)lut->dbr_address)); + target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, + lut->dbr_address, + i, srng_id); + pcfr->flush_timeout_dbr_cnt++; + release_lut_entry_enh(pdev, lut); + } + } + } + + if (pcfr->lut_timer_init) + qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); +} + +/** + * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT + * entries + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pcfr; + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (pcfr->lut_timer_init) + qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); +} + +/** + * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT + * entries + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pcfr; + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (pcfr->lut_timer_init) + qdf_timer_stop(&pcfr->lut_age_timer); +} + +/** + * target_if_cfr_update_global_cfg() - Update global config after a successful + * commit + * @pdev: pointer to pdev object + * + * Return: None + */ +void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev) +{ + int grp_id; + struct pdev_cfr *pcfr; + struct ta_ra_cfr_cfg *curr_cfg = NULL; + struct ta_ra_cfr_cfg *glbl_cfg = NULL; + unsigned long *modified_in_this_session; + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + modified_in_this_session = + (unsigned long *)&pcfr->rcc_param.modified_in_curr_session; + + for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { + if (qdf_test_bit(grp_id, modified_in_this_session)) { + /* Populating global config based on user's input */ + glbl_cfg = &pcfr->global[grp_id]; + curr_cfg = &pcfr->rcc_param.curr[grp_id]; + + if (curr_cfg->valid_ta) + qdf_mem_copy(glbl_cfg->tx_addr, + curr_cfg->tx_addr, + QDF_MAC_ADDR_SIZE); + + if (curr_cfg->valid_ra) + qdf_mem_copy(glbl_cfg->rx_addr, + curr_cfg->rx_addr, + QDF_MAC_ADDR_SIZE); + + if (curr_cfg->valid_ta_mask) + qdf_mem_copy(glbl_cfg->tx_addr_mask, + curr_cfg->tx_addr_mask, + QDF_MAC_ADDR_SIZE); + + if (curr_cfg->valid_ra_mask) + qdf_mem_copy(glbl_cfg->rx_addr_mask, + curr_cfg->rx_addr_mask, + QDF_MAC_ADDR_SIZE); + + if (curr_cfg->valid_bw_mask) + glbl_cfg->bw = curr_cfg->bw; + + if (curr_cfg->valid_nss_mask) + glbl_cfg->nss = curr_cfg->nss; + + if (curr_cfg->valid_mgmt_subtype) + glbl_cfg->mgmt_subtype_filter = + curr_cfg->mgmt_subtype_filter; + + if (curr_cfg->valid_ctrl_subtype) + glbl_cfg->ctrl_subtype_filter = + curr_cfg->ctrl_subtype_filter; + + if (curr_cfg->valid_data_subtype) + glbl_cfg->data_subtype_filter = + curr_cfg->data_subtype_filter; + } + } +} + +/** + * cfr_6018_init_pdev() - Inits cfr pdev and registers necessary handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: Registration status for necessary handlers + */ +QDF_STATUS cfr_6018_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct pdev_cfr *pcfr; + + if (!pdev) { + cfr_err("PDEV is NULL!"); + return QDF_STATUS_E_NULL_VALUE; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pcfr is NULL!"); + return QDF_STATUS_E_NULL_VALUE; + } + +#if DIRECT_BUF_RX_ENABLE + status = target_if_register_to_dbr_enh(pdev); + if (status != QDF_STATUS_SUCCESS) { + cfr_err("Failed to register with dbr"); + return status; + } +#endif + + status = target_if_register_tx_completion_enh_event_handler(psoc); + if (status != QDF_STATUS_SUCCESS) { + cfr_err("Failed to register with tx event handler"); + return status; + } + + pcfr->is_cfr_rcc_capable = 1; + pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY; + pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES; + pcfr->rcc_param.vdev_id = CFR_INVALID_VDEV_ID; + pcfr->rcc_param.srng_id = 0; + + target_if_cfr_default_ta_ra_config(&pcfr->rcc_param, + true, MAX_RESET_CFG_ENTRY); + + status = target_if_cfr_config_rcc(pdev, &pcfr->rcc_param); + if (status == QDF_STATUS_SUCCESS) { + /* Update global configuration */ + target_if_cfr_update_global_cfg(pdev); + } else { + cfr_err("Sending WMI to configure default has failed\n"); + return status; + } + + pcfr->rcc_param.modified_in_curr_session = 0; + + pcfr->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS; + pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_CYP; + pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_CYP; + pcfr->chip_type = CFR_CAPTURE_RADIO_CYP; + + if (!pcfr->lut_timer_init) { + qdf_timer_init(NULL, + &(pcfr->lut_age_timer), + lut_ageout_timer_task, (void *)pcfr, + QDF_TIMER_TYPE_WAKE_APPS); + pcfr->lut_timer_init = 1; + } + + return status; +} + +/** + * cfr_6018_deinit_pdev() - De-inits corresponding pdev and handlers. + * @psoc: pointer to psoc object + * @pdev: pointer to pdev object + * + * Return: De-registration status for necessary handlers + */ +QDF_STATUS cfr_6018_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + int status; + struct pdev_cfr *pcfr; + + pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pcfr is NULL"); + return -EINVAL; + } + + if (pcfr->lut_timer_init) { + qdf_timer_stop(&pcfr->lut_age_timer); + qdf_timer_free(&(pcfr->lut_age_timer)); + pcfr->lut_timer_init = 0; + } + + pcfr->tx_evt_cnt = 0; + pcfr->dbr_evt_cnt = 0; + pcfr->release_cnt = 0; + pcfr->total_tx_evt_cnt = 0; + pcfr->rx_tlv_evt_cnt = 0; + pcfr->flush_dbr_cnt = 0; + pcfr->flush_timeout_dbr_cnt = 0; + pcfr->invalid_dma_length_cnt = 0; + pcfr->clear_txrx_event = 0; + pcfr->cfr_dma_aborts = 0; + qdf_mem_zero(&pcfr->rcc_param, sizeof(struct cfr_rcc_param)); + qdf_mem_zero(&pcfr->global, (sizeof(struct ta_ra_cfr_cfg) * + MAX_TA_RA_ENTRIES)); + +#ifdef DIRECT_BUF_RX_ENABLE + status = target_if_unregister_to_dbr_enh(pdev); + if (status != QDF_STATUS_SUCCESS) + cfr_err("Failed to register with dbr"); +#endif + + status = target_if_unregister_tx_completion_enh_event_handler(psoc); + if (status != QDF_STATUS_SUCCESS) + cfr_err("Failed to register with dbr"); + + return status; +} diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6490.c b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6490.c new file mode 100644 index 0000000000000000000000000000000000000000..0e25aff300ecfcb829e0ed450e6f94779a0d49b4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6490.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC : target_if_cfr_6490.c + * + * Target interface of CFR for QCA6490 implementation + * + */ + +#include +#include "target_if_cfr.h" +#include +#include "wlan_cfr_utils_api.h" +#include "target_if_cfr_6490.h" +#include "target_if_cfr_6018.h" +#include "init_deinit_lmac.h" +#include "cfg_ucfg_api.h" +#include "cfr_cfg.h" + +static wdi_event_subscribe g_cfr_subscribe; + +static void target_cfr_callback(void *pdev_obj, enum WDI_EVENT event, + void *data, u_int16_t peer_id, + uint32_t status) +{ + struct wlan_objmgr_pdev *pdev; + qdf_nbuf_t nbuf = (qdf_nbuf_t)data; + qdf_nbuf_t data_clone; + + pdev = (struct wlan_objmgr_pdev *)pdev_obj; + if (qdf_unlikely((!pdev || !data))) { + cfr_err("Invalid pdev %pK or data %pK for event %d", + pdev, data, event); + qdf_nbuf_free(nbuf); + return; + } + + if (event != WDI_EVENT_RX_PPDU_DESC) { + cfr_debug("event is %d", event); + qdf_nbuf_free(nbuf); + return; + } + + data_clone = qdf_nbuf_clone(nbuf); + if (data_clone) + wlan_cfr_rx_tlv_process(pdev, (void *)data_clone); + + qdf_nbuf_free(nbuf); +} + +QDF_STATUS +target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe) +{ + ol_txrx_soc_handle soc; + struct wlan_objmgr_psoc *psoc; + struct pdev_cfr *pcfr; + + if (!pdev) { + cfr_err("Null pdev"); + return QDF_STATUS_E_INVAL; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("pcfr is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + cfr_err("Null psoc"); + return QDF_STATUS_E_INVAL; + } + + soc = wlan_psoc_get_dp_handle(psoc); + if (!soc) { + cfr_err("Null soc"); + return QDF_STATUS_E_INVAL; + } + + g_cfr_subscribe.callback = target_cfr_callback; + g_cfr_subscribe.context = pdev; + cdp_set_cfr_rcc(soc, 0, is_subscribe); + cdp_enable_mon_reap_timer(soc, 0, is_subscribe); + if (is_subscribe) { + if (cdp_wdi_event_sub(soc, 0, &g_cfr_subscribe, + WDI_EVENT_RX_PPDU_DESC)) { + cfr_err("wdi event sub fail"); + return QDF_STATUS_E_FAILURE; + } + } else { + if (cdp_wdi_event_unsub(soc, 0, &g_cfr_subscribe, + WDI_EVENT_RX_PPDU_DESC)) { + cfr_err("wdi event unsub fail"); + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS cfr_6490_init_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *cfr_pdev; + struct psoc_cfr *cfr_psoc; + struct wmi_unified *wmi_handle = NULL; + bool is_cfr_disabled; + bool cfr_capable; + QDF_STATUS status; + + if (!psoc || !pdev) { + cfr_err("null pdev or psoc"); + return QDF_STATUS_E_FAILURE; + } + + cfr_pdev = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_CFR); + if (!cfr_pdev) { + cfr_err("null pdev cfr"); + return QDF_STATUS_E_FAILURE; + } + + cfr_psoc = wlan_objmgr_psoc_get_comp_private_obj( + psoc, WLAN_UMAC_COMP_CFR); + + if (!cfr_psoc) { + cfr_err("null psoc cfr"); + return QDF_STATUS_E_FAILURE; + } + + wmi_handle = lmac_get_pdev_wmi_handle(pdev); + if (!wmi_handle) { + cfr_err("null wmi handle"); + return QDF_STATUS_E_FAILURE; + } + + is_cfr_disabled = cfg_get(psoc, CFG_CFR_DISABLE); + if (is_cfr_disabled) { + cfr_pdev->is_cfr_capable = 0; + cfr_psoc->is_cfr_capable = 0; + cfr_info("cfr disabled"); + return QDF_STATUS_SUCCESS; + } + + cfr_capable = wmi_service_enabled(wmi_handle, + wmi_service_cfr_capture_support); + cfr_pdev->is_cfr_capable = cfr_capable; + cfr_psoc->is_cfr_capable = cfr_capable; + if (!cfr_capable) { + cfr_err("FW doesn't support CFR"); + return QDF_STATUS_SUCCESS; + } + + status = cfr_6018_init_pdev(psoc, pdev); + cfr_pdev->chip_type = CFR_CAPTURE_RADIO_HSP; + + return status; +} + +QDF_STATUS cfr_6490_deinit_pdev(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pcfr; + + if (!psoc || !pdev) { + cfr_err("null pdev or psoc"); + return QDF_STATUS_E_FAILURE; + } + + pcfr = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_CFR); + if (!pcfr) { + cfr_err("null pdev cfr"); + return QDF_STATUS_E_FAILURE; + } + + if (!pcfr->is_cfr_capable) { + cfr_info("cfr disabled or FW not support"); + return QDF_STATUS_SUCCESS; + } + + return cfr_6018_deinit_pdev(psoc, pdev); +} diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/coex/inc/target_if_coex.h b/drivers/staging/qca-wifi-host-cmn/target_if/coex/inc/target_if_coex.h new file mode 100644 index 0000000000000000000000000000000000000000..d496efaa78ea7b371c5ad808ffec1f5839253b86 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/coex/inc/target_if_coex.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: contains coex target if declarations + */ +#ifndef __TARGET_IF_COEX_H__ +#define __TARGET_IF_COEX_H__ + +#include + +/** + * target_if_coex_register_tx_ops() - Register coex target_if tx ops + * @tx_ops: pointer to target if tx ops + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +target_if_coex_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/coex/src/target_if_coex.c b/drivers/staging/qca-wifi-host-cmn/target_if/coex/src/target_if_coex.c new file mode 100644 index 0000000000000000000000000000000000000000..6dd3c70b8092fc07d776aa9f57b540a597c56c5e --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/coex/src/target_if_coex.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: contains coex target if functions + */ +#include +#include + +static QDF_STATUS +target_if_coex_config_send(struct wlan_objmgr_pdev *pdev, + struct coex_config_params *param) +{ + wmi_unified_t pdev_wmi_handle; + + pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev); + if (!pdev_wmi_handle) { + coex_err("Invalid PDEV WMI handle"); + return QDF_STATUS_E_FAILURE; + } + + return wmi_unified_send_coex_config_cmd(pdev_wmi_handle, param); +} + +QDF_STATUS +target_if_coex_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + struct wlan_lmac_if_coex_tx_ops *coex_ops; + + if (!tx_ops) { + coex_err("target if tx ops is NULL!"); + return QDF_STATUS_E_INVAL; + } + + coex_ops = &tx_ops->coex_ops; + coex_ops->coex_config_send = target_if_coex_config_send; + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/core/inc/target_if.h b/drivers/staging/qca-wifi-host-cmn/target_if/core/inc/target_if.h index ea21539ef27e1c4e8b1951b31531d08244ff51f1..3f229597393c4e015a86a8b94aa40d12fe0155cb 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/core/inc/target_if.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/core/inc/target_if.h @@ -64,14 +64,6 @@ #define targetif_nofl_debug(params...) \ QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TARGET_IF, params) -#ifdef CONFIG_MCL -#define TARGET_TYPE_AR900B 9 /* Beeliner */ -#define TARGET_TYPE_QCA9984 15 /* cascade */ -#define TARGET_TYPE_IPQ4019 16 /* dakota */ -#define TARGET_TYPE_QCA9888 17 /* besra */ -#define TARGET_TYPE_AR9888 7 /* Peregrine */ -#endif - typedef struct wlan_objmgr_psoc *(*get_psoc_handle_callback)( void *scn_handle); @@ -118,9 +110,6 @@ struct host_fw_ver { }; struct common_dbglog_handle; -struct common_hif_handle; -struct common_htc_handle; -struct common_wmi_handle; struct common_accelerator_handle; /** @@ -133,9 +122,9 @@ struct common_accelerator_handle; * @dbglog_hdl: Debug log handle */ struct comp_hdls { - struct common_hif_handle *hif_hdl; - struct common_htc_handle *htc_hdl; - struct common_wmi_handle *wmi_hdl; + struct hif_opaque_softc *hif_hdl; + HTC_HANDLE htc_hdl; + struct wmi_unified *wmi_hdl; struct common_accelerator_handle *accelerator_hdl; struct common_dbglog_handle *dbglog_hdl; }; @@ -187,6 +176,7 @@ struct target_version_info { * @service_ext2_param: service ready ext2 event params * @service_ext_param: ext service params * @mac_phy_cap: phy caps array + * @dbr_ring_cap: dbr_ring capability info * @reg_cap: regulatory caps array * @scaling_params: Spectral bin scaling parameters * @num_mem_chunks: number of mem chunks allocated @@ -243,6 +233,7 @@ struct tgt_info { * @sw_version_check: Checks the SW version * @smart_log_enable: Enable Smart Logs feature * @cfr_support_enable: CFR support enable + * @set_pktlog_checksum: Set the pktlog checksum from FW ready event to pl_dev */ struct target_ops { QDF_STATUS (*ext_resource_config_enable) @@ -303,6 +294,8 @@ struct target_ops { void (*cfr_support_enable) (struct wlan_objmgr_psoc *psoc, struct target_psoc_info *tgt_info, uint8_t *event); + void (*set_pktlog_checksum) + (struct wlan_objmgr_pdev *pdev, uint32_t checksum); }; @@ -330,7 +323,7 @@ struct target_psoc_info { * @feature_ptr: stores legacy pointer or few driver specific structures */ struct target_pdev_info { - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; struct common_accelerator_handle *accelerator_hdl; int32_t pdev_idx; int32_t phy_idx; @@ -501,6 +494,14 @@ bool target_is_tgt_type_qca9984(uint32_t target_type); */ bool target_is_tgt_type_qca9888(uint32_t target_type); +/** + * target_is_tgt_type_adrastea() - Check if the target type is QCS40X + * @target_type: target type to be checked. + * + * Return: true if the target_type is QCS40X, else false. + */ +bool target_is_tgt_type_adrastea(uint32_t target_type); + /** * target_psoc_set_wlan_init_status() - set info wlan_init_status @@ -828,6 +829,35 @@ static inline uint8_t target_psoc_get_num_radios return psoc_info->info.num_radios; } +/** + * target_psoc_get_num_radios_for_mode() - get number of radios for a hw-mode + * @psoc_info: pointer to structure target_psoc_info + * + * API to get number_of_radios for a HW mode + * + * Return: number of radios + */ + +static inline uint8_t target_psoc_get_num_radios_for_mode + (struct target_psoc_info *psoc_info, uint8_t mode) +{ + uint8_t mac_phy_count; + uint8_t num_radios = 0; + struct tgt_info *info = &psoc_info->info; + + if (!psoc_info) + return 0; + + for (mac_phy_count = 0; + mac_phy_count < target_psoc_get_total_mac_phy_cnt(psoc_info); + mac_phy_count++) { + num_radios += + (info->mac_phy_cap[mac_phy_count].hw_mode_id == mode); + } + + return num_radios; +} + /** * target_psoc_set_service_bitmap() - set service_bitmap * @psoc_info: pointer to structure target_psoc_info @@ -902,7 +932,7 @@ static inline uint32_t target_psoc_get_num_mem_chunks */ static inline void target_psoc_set_hif_hdl (struct target_psoc_info *psoc_info, - struct common_hif_handle *hif_hdl) + struct hif_opaque_softc *hif_hdl) { if (!psoc_info) return; @@ -918,7 +948,7 @@ static inline void target_psoc_set_hif_hdl * * Return: hif_hdl */ -static inline struct common_hif_handle *target_psoc_get_hif_hdl +static inline struct hif_opaque_softc *target_psoc_get_hif_hdl (struct target_psoc_info *psoc_info) { if (!psoc_info) @@ -936,9 +966,9 @@ static inline struct common_hif_handle *target_psoc_get_hif_hdl * * Return: void */ -static inline void target_psoc_set_htc_hdl - (struct target_psoc_info *psoc_info, - struct common_htc_handle *htc_hdl) +static inline void target_psoc_set_htc_hdl( + struct target_psoc_info *psoc_info, + HTC_HANDLE htc_hdl) { if (!psoc_info) return; @@ -954,7 +984,7 @@ static inline void target_psoc_set_htc_hdl * * Return: htc_hdl */ -static inline struct common_htc_handle *target_psoc_get_htc_hdl +static inline HTC_HANDLE target_psoc_get_htc_hdl (struct target_psoc_info *psoc_info) { if (!psoc_info) @@ -973,7 +1003,7 @@ static inline struct common_htc_handle *target_psoc_get_htc_hdl */ static inline void target_psoc_set_wmi_hdl (struct target_psoc_info *psoc_info, - struct common_wmi_handle *wmi_hdl) + struct wmi_unified *wmi_hdl) { if (!psoc_info) return; @@ -989,7 +1019,7 @@ static inline void target_psoc_set_wmi_hdl * * Return: wmi_hdl */ -static inline struct common_wmi_handle *target_psoc_get_wmi_hdl +static inline struct wmi_unified *target_psoc_get_wmi_hdl (struct target_psoc_info *psoc_info) { if (!psoc_info) @@ -1270,6 +1300,56 @@ static inline struct wlan_psoc_host_service_ext_param return &psoc_info->info.service_ext_param; } +/** + * target_psoc_get_num_dbr_ring_caps() - get no of dbr_ring_caps + * @psoc_info: pointer to structure target_psoc_info + * + * API to get num_dbr_ring_caps + * + * Return: no of dbr_ring_caps + */ +static inline uint32_t target_psoc_get_num_dbr_ring_caps + (struct target_psoc_info *psoc_info) +{ + if (!psoc_info) + return 0; + + if (psoc_info->info.service_ext_param.num_dbr_ring_caps) + return psoc_info->info.service_ext_param.num_dbr_ring_caps; + + return psoc_info->info.service_ext2_param.num_dbr_ring_caps; +} + +/** + * target_psoc_get_mac_phy_cap_for_mode() - get mac_phy_cap for a hw-mode + * @psoc_info: pointer to structure target_psoc_info + * + * API to get mac_phy_cap for a specified hw-mode + * + * Return: structure pointer to wlan_psoc_host_mac_phy_caps + */ + +static inline struct wlan_psoc_host_mac_phy_caps + *target_psoc_get_mac_phy_cap_for_mode + (struct target_psoc_info *psoc_info, uint8_t mode) +{ + uint8_t mac_phy_idx; + struct tgt_info *info = &psoc_info->info; + + if (!psoc_info) + return NULL; + + for (mac_phy_idx = 0; + mac_phy_idx < PSOC_MAX_MAC_PHY_CAP; + mac_phy_idx++) + if (info->mac_phy_cap[mac_phy_idx].hw_mode_id == mode) + break; + + if (mac_phy_idx == PSOC_MAX_MAC_PHY_CAP) + return NULL; + + return &info->mac_phy_cap[mac_phy_idx]; +} /** * target_psoc_get_mac_phy_cap() - get mac_phy_cap @@ -1282,10 +1362,24 @@ static inline struct wlan_psoc_host_service_ext_param static inline struct wlan_psoc_host_mac_phy_caps *target_psoc_get_mac_phy_cap (struct target_psoc_info *psoc_info) { + uint32_t preferred_hw_mode; + struct wlan_psoc_host_mac_phy_caps *mac_phy_cap; + if (!psoc_info) return NULL; - return psoc_info->info.mac_phy_cap; + preferred_hw_mode = + target_psoc_get_preferred_hw_mode(psoc_info); + + if (preferred_hw_mode < WMI_HOST_HW_MODE_MAX) { + mac_phy_cap = + target_psoc_get_mac_phy_cap_for_mode + (psoc_info, preferred_hw_mode); + } else { + mac_phy_cap = psoc_info->info.mac_phy_cap; + } + + return mac_phy_cap; } /** @@ -1403,7 +1497,7 @@ static inline void *target_pdev_get_feature_ptr */ static inline void target_pdev_set_wmi_handle (struct target_pdev_info *pdev_info, - struct common_wmi_handle *wmi_handle) + struct wmi_unified *wmi_handle) { if (!pdev_info) return; @@ -1419,7 +1513,7 @@ static inline void target_pdev_set_wmi_handle * * Return: wmi_handle */ -static inline struct common_wmi_handle *target_pdev_get_wmi_handle +static inline struct wmi_unified *target_pdev_get_wmi_handle (struct target_pdev_info *pdev_info) { if (!pdev_info) @@ -1543,17 +1637,16 @@ static inline int32_t target_pdev_get_phy_idx * Return: wmi_handle on success * if tgt handle is not initialized, it returns NULL */ -static inline struct common_wmi_handle *GET_WMI_HDL_FROM_PSOC( +static inline struct wmi_unified *GET_WMI_HDL_FROM_PSOC( struct wlan_objmgr_psoc *psoc) { - void *tgt_if_handle; + struct target_psoc_info *tgt_if_handle; if (psoc) { tgt_if_handle = psoc->tgt_if_handle; if (tgt_if_handle) - return (target_psoc_get_wmi_hdl( - (struct target_psoc_info *)tgt_if_handle)); + return target_psoc_get_wmi_hdl(tgt_if_handle); else return NULL; } @@ -1570,10 +1663,10 @@ static inline struct common_wmi_handle *GET_WMI_HDL_FROM_PSOC( * Return: wmi_handle on success * if tgt handle is not initialized, it returns NULL */ -static inline struct common_wmi_handle *GET_WMI_HDL_FROM_PDEV( +static inline struct wmi_unified *GET_WMI_HDL_FROM_PDEV( struct wlan_objmgr_pdev *pdev) { - void *tgt_if_handle; + struct target_pdev_info *tgt_if_handle; if (pdev) { tgt_if_handle = pdev->tgt_if_handle; @@ -1726,6 +1819,24 @@ static inline void target_if_cfr_support_enable(struct wlan_objmgr_psoc *psoc, tgt_hdl->tif_ops->cfr_support_enable(psoc, tgt_hdl, evt_buf); } +/** + * target_if_set_pktlog_checksum - Set pktlog checksum + * @pdev: pdev object + * @tgt_hdl: target_psoc_info pointer + * @checksum: checksum received from FW + * + * API to set pktlog checksum + * + * Return: none + */ +static inline void target_if_set_pktlog_checksum(struct wlan_objmgr_pdev *pdev, + struct target_psoc_info *tgt_hdl, uint32_t checksum) +{ + if ((tgt_hdl->tif_ops) && + (tgt_hdl->tif_ops->set_pktlog_checksum)) + tgt_hdl->tif_ops->set_pktlog_checksum(pdev, checksum); +} + /** * target_if_atf_cfg_enable - Enable ATF config * @psoc: psoc object diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/core/src/target_if_main.c b/drivers/staging/qca-wifi-host-cmn/target_if/core/src/target_if_main.c index c29dc9679bbac0817c0fe972314351cb3f7bcae9..a565aab1d547719106fd24b8301812a4f9b9fee0 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/core/src/target_if_main.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/core/src/target_if_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -78,11 +78,14 @@ #ifdef CRYPTO_SET_KEY_CONVERGED #include #endif - -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include + +#ifdef FEATURE_COEX +#include #endif +#include + static struct target_if_ctx *g_target_if_ctx; struct target_if_ctx *target_if_get_ctx(void) @@ -341,6 +344,20 @@ static inline void target_if_crypto_tx_ops_register( } #endif +#ifdef FEATURE_COEX +static QDF_STATUS +target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + return target_if_coex_register_tx_ops(tx_ops); +} +#else +static inline QDF_STATUS +target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + return QDF_STATUS_SUCCESS; +} +#endif + static void target_if_target_tx_ops_register( struct wlan_lmac_if_tx_ops *tx_ops) { @@ -365,6 +382,9 @@ static void target_if_target_tx_ops_register( target_tx_ops->tgt_is_tgt_type_qca9888 = target_is_tgt_type_qca9888; + target_tx_ops->tgt_is_tgt_type_adrastea = + target_is_tgt_type_adrastea; + target_tx_ops->tgt_get_tgt_type = lmac_get_tgt_type; @@ -381,19 +401,11 @@ target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) return target_if_cp_stats_register_tx_ops(tx_ops); } -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE static QDF_STATUS target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) { return target_if_vdev_mgr_register_tx_ops(tx_ops); } -#else -static QDF_STATUS -target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) -{ - return QDF_STATUS_SUCCESS; -} -#endif #ifdef QCA_WIFI_FTM static @@ -407,6 +419,20 @@ void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) { } #endif + +#ifdef WLAN_FEATURE_GPIO_CFG +static +void target_if_gpio_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + target_if_gpio_register_tx_ops(tx_ops); +} +#else +static +void target_if_gpio_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif + static QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { @@ -449,6 +475,10 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_vdev_mgr_tx_ops_register(tx_ops); + target_if_coex_tx_ops_register(tx_ops); + + target_if_gpio_tx_ops_register(tx_ops); + /* Converged UMAC components to register their TX-ops here */ return QDF_STATUS_SUCCESS; } @@ -577,7 +607,6 @@ QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_INVAL; } init_deinit_chainmask_table_free(ext_param); - init_deinit_rf_characterization_entries_free(ext_param); init_deinit_dbr_ring_cap_free(tgt_psoc_info); init_deinit_spectral_scaling_params_free(tgt_psoc_info); @@ -609,3 +638,8 @@ bool target_is_tgt_type_qca9888(uint32_t target_type) { return target_type == TARGET_TYPE_QCA9888; } + +bool target_is_tgt_type_adrastea(uint32_t target_type) +{ + return target_type == TARGET_TYPE_ADRASTEA; +} diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/cp_stats/src/target_if_mc_cp_stats.c b/drivers/staging/qca-wifi-host-cmn/target_if/cp_stats/src/target_if_mc_cp_stats.c index 200a9320a2ffdaef945fbbb9708e81f3cddc4857..df77875133087d9ece2c6d1cfb2166629d3e6b84 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/cp_stats/src/target_if_mc_cp_stats.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/cp_stats/src/target_if_mc_cp_stats.c @@ -37,10 +37,20 @@ #include #include #include -#include #include #include +#ifdef WLAN_FEATURE_MIB_STATS +static void target_if_cp_stats_free_mib_stats(struct stats_event *ev) +{ + qdf_mem_free(ev->mib_stats); + ev->mib_stats = NULL; +} +#else +static void target_if_cp_stats_free_mib_stats(struct stats_event *ev) +{ +} +#endif static void target_if_cp_stats_free_stats_event(struct stats_event *ev) { qdf_mem_free(ev->pdev_stats); @@ -57,6 +67,7 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev) ev->vdev_summary_stats = NULL; qdf_mem_free(ev->vdev_chain_rssi); ev->vdev_chain_rssi = NULL; + target_if_cp_stats_free_mib_stats(ev); } static QDF_STATUS target_if_cp_stats_extract_pdev_stats( @@ -105,10 +116,7 @@ static void target_if_cp_stats_extract_peer_extd_stats( uint32_t i; wmi_host_peer_extd_stats peer_extd_stats; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); struct cdp_peer_stats *peer_stats; - struct cdp_peer *peer; - uint8_t peer_id; if (!stats_param->num_peer_extd_stats) return; @@ -134,17 +142,19 @@ static void target_if_cp_stats_extract_peer_extd_stats( ev->peer_extended_stats[i].rx_mc_bc_cnt = peer_extd_stats.rx_mc_bc_cnt; - peer = cdp_peer_find_by_addr(soc, txrx_pdev, - ev->peer_extended_stats[i].peer_macaddr, - &peer_id); - if (!peer) + peer_stats = qdf_mem_malloc(sizeof(*peer_stats)); + if (!peer_stats) continue; - peer_stats = cdp_host_get_peer_stats(soc, peer); - if (peer_stats) + status = cdp_host_get_peer_stats(soc, VDEV_ALL, + ev->peer_extended_stats[i].peer_macaddr, + peer_stats); + if (status == QDF_STATUS_SUCCESS) ev->peer_extended_stats[i].rx_mc_bc_cnt = peer_stats->rx.multicast.num + peer_stats->rx.bcast.num; + + qdf_mem_free(peer_stats); } } @@ -252,6 +262,50 @@ static QDF_STATUS target_if_cp_stats_extract_cca_stats( return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_MIB_STATS +static QDF_STATUS target_if_cp_stats_extract_mib_stats( + struct wmi_unified *wmi_hdl, + wmi_host_stats_event *stats_param, + struct stats_event *ev, uint8_t *data) +{ + QDF_STATUS status; + + if (!stats_param->num_mib_stats) + return QDF_STATUS_SUCCESS; + + if (stats_param->num_mib_stats != MAX_MIB_STATS || + (stats_param->num_mib_extd_stats && + stats_param->num_mib_extd_stats != MAX_MIB_STATS)) { + cp_stats_err("number of mib stats wrong, num_mib_stats %d, num_mib_extd_stats %d", + stats_param->num_mib_stats, + stats_param->num_mib_extd_stats); + return QDF_STATUS_E_INVAL; + } + + ev->num_mib_stats = stats_param->num_mib_stats; + + ev->mib_stats = qdf_mem_malloc(sizeof(*ev->mib_stats)); + if (!ev->mib_stats) + return QDF_STATUS_E_NOMEM; + + status = wmi_extract_mib_stats(wmi_hdl, data, ev->mib_stats); + if (QDF_IS_STATUS_ERROR(status)) { + cp_stats_err("wmi_extract_mib_stats failed"); + return status; + } + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS target_if_cp_stats_extract_mib_stats( + struct wmi_unified *wmi_hdl, + wmi_host_stats_event *stats_param, + struct stats_event *ev, uint8_t *data) +{ + return QDF_STATUS_SUCCESS; +} +#endif + static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats( struct wmi_unified *wmi_hdl, wmi_host_stats_event *stats_param, @@ -382,11 +436,23 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl, cp_stats_err("stats param extract failed: %d", status); return status; } - cp_stats_nofl_debug("num: pdev: %d, vdev: %d, peer: %d, rssi: %d", + cp_stats_nofl_debug("num: pdev: %d, pdev_extd: %d, vdev: %d, peer: %d," + "peer_extd: %d rssi: %d, mib %d, mib_extd %d, " + "bcnflt: %d, channel: %d, bcn: %d, peer_extd2: %d," + "last_event: %x", stats_param.num_pdev_stats, + stats_param.num_pdev_ext_stats, stats_param.num_vdev_stats, stats_param.num_peer_stats, - stats_param.num_rssi_stats); + stats_param.num_peer_extd_stats, + stats_param.num_rssi_stats, + stats_param.num_mib_stats, + stats_param.num_mib_extd_stats, + stats_param.num_bcnflt_stats, + stats_param.num_chan_stats, + stats_param.num_bcn_stats, + stats_param.num_peer_adv_stats, stats_param.last_event); + ev->last_event = stats_param.last_event; status = target_if_cp_stats_extract_pdev_stats(wmi_hdl, &stats_param, ev, data); @@ -415,6 +481,12 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl, if (QDF_IS_STATUS_ERROR(status)) return status; + status = target_if_cp_stats_extract_mib_stats(wmi_hdl, + &stats_param, + ev, data); + if (QDF_IS_STATUS_ERROR(status)) + return status; + return QDF_STATUS_SUCCESS; } @@ -616,6 +688,8 @@ static uint32_t get_stats_id(enum stats_req_type type) WMI_REQUEST_PDEV_STAT | WMI_REQUEST_PEER_EXTD2_STAT | WMI_REQUEST_RSSI_PER_CHAIN_STAT); + case TYPE_MIB_STATS: + return (WMI_REQUEST_MIB_STAT | WMI_REQUEST_MIB_EXTD_STAT); } return 0; diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/crypto/src/target_if_crypto.c b/drivers/staging/qca-wifi-host-cmn/target_if/crypto/src/target_if_crypto.c index c09d073533bc636fe1c8caeb1a0e495b619561b2..53fc94a5f2515e45da3ea7ecde531c4a599949a6 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/crypto/src/target_if_crypto.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/crypto/src/target_if_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,9 +34,56 @@ #include #include #include +#include #include +#include +#include +#include "wlan_crypto_def_i.h" +#include "wlan_crypto_obj_mgr_i.h" #ifdef FEATURE_WLAN_WAPI +#ifdef FEATURE_WAPI_BIG_ENDIAN +/* + * All lithium firmware expects WAPI in big endian + * format , whereas helium firmware's expect otherwise + */ + +static void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev, + bool pairwise, + enum wlan_crypto_cipher_type cipher_type, + struct set_key_params *params) +{ + static const unsigned char tx_iv[16] = {0x5c, 0x36, 0x5c, 0x36, 0x5c, + 0x36, 0x5c, 0x36, 0x5c, 0x36, + 0x5c, 0x36, 0x5c, 0x36, 0x5c, + 0x36}; + + static const unsigned char rx_iv[16] = {0x5c, 0x36, 0x5c, 0x36, 0x5c, + 0x36, 0x5c, 0x36, 0x5c, 0x36, + 0x5c, 0x36, 0x5c, 0x36, 0x5c, + 0x37}; + + if (cipher_type != WLAN_CRYPTO_CIPHER_WAPI_SMS4 && + cipher_type != WLAN_CRYPTO_CIPHER_WAPI_GCM4) + return; + + if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE || + vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) { + qdf_mem_copy(¶ms->rx_iv, &tx_iv, + WLAN_CRYPTO_WAPI_IV_SIZE); + qdf_mem_copy(params->tx_iv, &rx_iv, + WLAN_CRYPTO_WAPI_IV_SIZE); + } else { + qdf_mem_copy(params->rx_iv, &rx_iv, + WLAN_CRYPTO_WAPI_IV_SIZE); + qdf_mem_copy(params->tx_iv, &tx_iv, + WLAN_CRYPTO_WAPI_IV_SIZE); + } + + params->key_txmic_len = WLAN_CRYPTO_MIC_LEN; + params->key_rxmic_len = WLAN_CRYPTO_MIC_LEN; +} +#else static void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev, bool pairwise, enum wlan_crypto_cipher_type cipher_type, @@ -74,6 +121,7 @@ static void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev, params->key_txmic_len = WLAN_CRYPTO_MIC_LEN; params->key_rxmic_len = WLAN_CRYPTO_MIC_LEN; } +#endif /* FEATURE_WAPI_BIG_ENDIAN */ #else static inline void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev, bool pairwise, @@ -112,13 +160,10 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev; enum cdp_sec_type sec_type = cdp_sec_type_none; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_vdev *txrx_vdev; uint32_t pn[4] = {0, 0, 0, 0}; - struct cdp_peer *peer = NULL; - uint8_t peer_id; + bool peer_exist = false; uint8_t def_tx_idx; - void *pdev_wmi_handle; + wmi_unified_t pdev_wmi_handle; bool pairwise; QDF_STATUS status; @@ -157,21 +202,15 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, } qdf_mem_copy(¶ms.key_rsc_ctr, &req->keyrsc[0], sizeof(uint64_t)); - txrx_vdev = (struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)txrx_pdev, params.vdev_id); - peer = cdp_peer_find_by_addr(soc, txrx_pdev, req->macaddr, &peer_id); - - if (!txrx_vdev) { - target_if_err("Invalid txrx vdev"); - return QDF_STATUS_E_FAILURE; - } + peer_exist = cdp_find_peer_exist(soc, pdev->pdev_objmgr.wlan_pdev_id, + req->macaddr); target_if_debug("key_type %d, mac: %02x:%02x:%02x:%02x:%02x:%02x", key_type, req->macaddr[0], req->macaddr[1], req->macaddr[2], req->macaddr[3], req->macaddr[4], req->macaddr[5]); - if ((key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) && !peer) { + if ((key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) && !peer_exist) { target_if_err("Invalid peer"); return QDF_STATUS_E_FAILURE; } @@ -203,27 +242,152 @@ QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev, &req->keyval[0], req->keylen); params.key_len = req->keylen; - if (peer) { - /* Set PN check & security type in data path */ - qdf_mem_copy(&pn[0], ¶ms.key_rsc_ctr, sizeof(pn)); - cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn); - cdp_set_key_sec_type(soc, txrx_vdev, peer, sec_type, pairwise); - cdp_set_key(soc, peer, pairwise, (uint32_t *)(req->keyval + - WLAN_CRYPTO_IV_SIZE + WLAN_CRYPTO_MIC_LEN)); - } else { - target_if_info("peer not found"); - } + + /* Set PN check & security type in data path */ + qdf_mem_copy(&pn[0], ¶ms.key_rsc_ctr, sizeof(pn)); + cdp_set_pn_check(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, + sec_type, pn); + + cdp_set_key_sec_type(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, + sec_type, pairwise); + + cdp_set_key(soc, vdev->vdev_objmgr.vdev_id, req->macaddr, pairwise, + (uint32_t *)(req->keyval + WLAN_CRYPTO_IV_SIZE + + WLAN_CRYPTO_MIC_LEN)); target_if_debug("vdev_id:%d, key: idx:%d,len:%d", params.vdev_id, params.key_idx, params.key_len); - target_if_debug("peer mac %pM", params.peer_mac); + target_if_debug("peer mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(params.peer_mac)); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_DEBUG, ¶ms.key_rsc_ctr, sizeof(uint64_t)); status = wmi_unified_setup_install_key_cmd(pdev_wmi_handle, ¶ms); + /* Zero-out local key variables */ + qdf_mem_zero(¶ms, sizeof(struct set_key_params)); + return status; } +/** + * target_if_crypto_install_key_comp_evt_handler() - install key complete + * handler + * @handle: wma handle + * @event: event data + * @len: data length + * + * This event is sent by fw once WPA/WPA2 keys are installed in fw. + * + * Return: 0 for success or error code + */ +static int +target_if_crypto_install_key_comp_evt_handler(void *handle, uint8_t *event, + uint32_t len) +{ + struct wlan_crypto_comp_priv *priv_obj; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct wmi_install_key_comp_event params; + QDF_STATUS status; + wmi_unified_t wmi_handle; + struct crypto_add_key_result result; + + if (!event || !handle) { + target_if_err("invalid param"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(handle); + if (!psoc) { + target_if_err("psoc is null"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("invalid wmi handle"); + return -EINVAL; + } + + status = wmi_extract_install_key_comp_event(wmi_handle, event, + len, ¶ms); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("received invalid buf from target"); + return -EINVAL; + } + + target_if_debug("vdev %d mac " QDF_MAC_ADDR_FMT " ix %x flags %x status %d", + params.vdev_id, + QDF_MAC_ADDR_REF(params.peer_macaddr), + params.key_ix, params.key_flags, params.status); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, params.vdev_id, + WLAN_CRYPTO_ID); + if (!vdev) { + target_if_err("vdev %d is null", params.vdev_id); + return -EINVAL; + } + + priv_obj = wlan_get_vdev_crypto_obj(vdev); + if (!priv_obj) { + target_if_err("priv_obj is null"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID); + return -EINVAL; + } + + result.vdev_id = params.vdev_id; + result.key_ix = params.key_ix; + result.key_flags = params.key_flags; + result.status = params.status; + qdf_mem_copy(result.peer_macaddr, params.peer_macaddr, + QDF_MAC_ADDR_SIZE); + + if (priv_obj->add_key_cb) + priv_obj->add_key_cb(priv_obj->add_key_ctx, &result); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID); + + return 0; +} + +static QDF_STATUS +target_if_crypto_register_events(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + + if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { + target_if_err("psoc or psoc->tgt_if_handle is null"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event_handler( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_vdev_install_key_complete_event_id, + target_if_crypto_install_key_comp_evt_handler, + WMI_RX_WORK_CTX); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("register_event_handler failed: err %d", status); + return status; + } + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +target_if_crypto_deregister_events(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { + target_if_err("psoc or psoc->tgt_if_handle is null"); + return QDF_STATUS_E_INVAL; + } + + wmi_unified_unregister_event_handler( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_vdev_install_key_complete_event_id); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_crypto_tx_ops *crypto; @@ -235,6 +399,8 @@ QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) crypto = &tx_ops->crypto_tx_ops; crypto->set_key = target_if_crypto_set_key; + crypto->register_events = target_if_crypto_register_events; + crypto->deregister_events = target_if_crypto_deregister_events; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/inc/target_if_dfs_full_offload.h b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/inc/target_if_dfs_full_offload.h index 624aaf57b244ce157d6f2a3a5645ac716f9eda85..513b8413d9873c696d3a1a9fc244beb20daab493 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/inc/target_if_dfs_full_offload.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/inc/target_if_dfs_full_offload.h @@ -70,14 +70,16 @@ static QDF_STATUS target_process_bang_radar_cmd(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev); /** - * target_send_agile_ch_cfg_cmd() - Send agile channel to target for + * target_send_agile_ch_cfg_cmd() - Send agile channel parameters to target for * off channel precac. * @pdev: Pointer to DFS pdev object. + * @adfs_param: Agile-DFS CAC parameters. * * Return: QDF_STATUS */ -QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, - uint8_t *ch_freq); +QDF_STATUS +target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, + struct dfs_agile_cac_params *adfs_param); #else static inline QDF_STATUS target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev) @@ -87,7 +89,7 @@ target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev) static inline QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, - uint8_t *ch_freq) + struct dfs_agile_cac_params *adfs_param) { return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs.c b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs.c index f4be0611537fdb642b1bc16d10063e42fa2947b5..e040aea2bcecf8020ab724f3e0e2d1baa26091c0 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs.c @@ -213,6 +213,27 @@ static bool target_if_dfs_offload(struct wlan_objmgr_psoc *psoc) wmi_service_dfs_phyerr_offload); } +static QDF_STATUS target_if_dfs_get_target_type(struct wlan_objmgr_pdev *pdev, + uint32_t *target_type) +{ + struct wlan_objmgr_psoc *psoc; + struct target_psoc_info *tgt_psoc_info; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + target_if_err("null psoc"); + return QDF_STATUS_E_FAILURE; + } + + tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); + if (!tgt_psoc_info) { + target_if_err("null tgt_psoc_info"); + return QDF_STATUS_E_FAILURE; + } + *target_type = target_psoc_get_target_type(tgt_psoc_info); + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS target_if_dfs_register_event_handler( struct wlan_objmgr_psoc *psoc) { @@ -285,7 +306,7 @@ static QDF_STATUS target_if_dfs_set_phyerr_filter_offload( bool dfs_phyerr_filter_offload) { QDF_STATUS status; - void *wmi_handle; + wmi_unified_t wmi_handle; if (!pdev) { target_if_err("null pdev"); @@ -386,5 +407,6 @@ QDF_STATUS target_if_register_dfs_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) &target_send_usenol_pdev_param; dfs_tx_ops->dfs_send_subchan_marking_pdev_param = &target_send_subchan_marking_pdev_param; + dfs_tx_ops->dfs_get_target_type = &target_if_dfs_get_target_type; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs_full_offload.c b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs_full_offload.c index eab31e2d2f409e185bddd91788d2b9a3a48e31ea..9c29ce31cb02cd6f71deeb9a30e4d8ac5107d6ac 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs_full_offload.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dfs/src/target_if_dfs_full_offload.c @@ -344,7 +344,7 @@ QDF_STATUS target_send_ocac_abort_cmd(struct wlan_objmgr_pdev *pdev) } QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, - uint8_t *ch_freq) + struct dfs_agile_cac_params *adfs_param) { wmi_unified_t wmi_handle; struct vdev_adfs_ch_cfg_params param; @@ -373,11 +373,11 @@ QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, qdf_mem_set(¶m, sizeof(param), 0); param.vdev_id = wlan_vdev_get_id(vdev); param.ocac_mode = QUICK_OCAC_MODE; - param.min_duration_ms = 60000; - param.max_duration_ms = 0; - param.chan_freq = *ch_freq; - param.chan_width = wlan_vdev_get_ch_width(vdev); - param.center_freq = *ch_freq; + param.min_duration_ms = adfs_param->min_precac_timeout; + param.max_duration_ms = adfs_param->max_precac_timeout; + param.chan_freq = adfs_param->precac_chan; + param.chan_width = adfs_param->precac_chwidth; + param.center_freq = adfs_param->precac_chan; status = wmi_unified_send_vdev_adfs_ch_cfg_cmd(wmi_handle, ¶m); if (QDF_IS_STATUS_ERROR(status)) @@ -390,7 +390,7 @@ QDF_STATUS target_send_agile_ch_cfg_cmd(struct wlan_objmgr_pdev *pdev, } #endif -#if (defined(CONFIG_MCL) || defined(QCA_WIFI_QCA8074) || \ +#if (defined(WLAN_DFS_FULL_OFFLOAD) || defined(QCA_WIFI_QCA8074) || \ defined(QCA_WIFI_QCA6018)) QDF_STATUS target_process_bang_radar_cmd( struct wlan_objmgr_pdev *pdev, diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h index 6df48d23d5e4adf4de21d247dfc692c90982b248..10882f2f2c2c0e99384ccb923d9631a3858e07b7 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h @@ -23,6 +23,13 @@ #include "qdf_atomic.h" #include "wmi_unified_api.h" +#ifdef WLAN_DEBUGFS +#ifdef DIRECT_BUF_RX_DEBUG +/* Base debugfs entry for DBR module */ +extern qdf_dentry_t dbr_debugfs_entry; +#endif /* DIRECT_BUF_RX_DEBUG */ +#endif /* WLAN_DEBUGFS */ + #define direct_buf_rx_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_DIRECT_BUF_RX, params) #define direct_buf_rx_err(params...) \ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c index 0a882c617c40543a3526f035ce06f3c902866abf..cf9e7eabf233e643347292d11ad8cca6675aff51 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_api.c @@ -25,6 +25,39 @@ #include "target_if_direct_buf_rx_main.h" #include +#if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) +/* Base debugfs entry for DBR module */ +qdf_dentry_t dbr_debugfs_entry; + +static inline void +target_if_direct_buf_rx_debugfs_init(void) +{ + dbr_debugfs_entry = qdf_debugfs_create_dir("dbr_ring_debug", NULL); + + if (!dbr_debugfs_entry) + direct_buf_rx_err("error while creating direct_buf rx debugfs dir"); +} + +static inline void +target_if_direct_buf_rx_debugfs_deinit(void) +{ + if (dbr_debugfs_entry) { + qdf_debugfs_remove_dir_recursive(dbr_debugfs_entry); + dbr_debugfs_entry = NULL; + } +} +#else +static inline void +target_if_direct_buf_rx_debugfs_init(void) +{ +} + +static inline void +target_if_direct_buf_rx_debugfs_deinit(void) +{ +} +#endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ + QDF_STATUS direct_buf_rx_init(void) { QDF_STATUS status; @@ -69,6 +102,8 @@ QDF_STATUS direct_buf_rx_init(void) goto dbr_unreg_pdev_create; } + target_if_direct_buf_rx_debugfs_init(); + direct_buf_rx_info("Direct Buffer RX pdev,psoc create and destroy handlers registered"); return QDF_STATUS_SUCCESS; @@ -99,6 +134,8 @@ QDF_STATUS direct_buf_rx_deinit(void) { QDF_STATUS status; + target_if_direct_buf_rx_debugfs_deinit(); + status = wlan_objmgr_unregister_pdev_destroy_handler( WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, target_if_direct_buf_rx_pdev_destroy_handler, @@ -163,6 +200,28 @@ QDF_STATUS direct_buf_rx_target_attach(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#ifdef DIRECT_BUF_RX_DEBUG +static inline void +target_if_direct_buf_rx_debug_register_tx_ops( + struct wlan_lmac_if_tx_ops *tx_ops) +{ + tx_ops->dbr_tx_ops.direct_buf_rx_start_ring_debug = + target_if_dbr_start_ring_debug; + tx_ops->dbr_tx_ops.direct_buf_rx_stop_ring_debug = + target_if_dbr_stop_ring_debug; + tx_ops->dbr_tx_ops.direct_buf_rx_start_buffer_poisoning = + target_if_dbr_start_buffer_poisoning; + tx_ops->dbr_tx_ops.direct_buf_rx_stop_buffer_poisoning = + target_if_dbr_stop_buffer_poisoning; +} +#else +static inline void +target_if_direct_buf_rx_debug_register_tx_ops( + struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif /* DIRECT_BUF_RX_DEBUG */ + void target_if_direct_buf_rx_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { tx_ops->dbr_tx_ops.direct_buf_rx_module_register = @@ -177,5 +236,6 @@ void target_if_direct_buf_rx_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_direct_buf_rx_print_ring_stat; tx_ops->dbr_tx_ops.direct_buf_rx_get_ring_params = target_if_direct_buf_rx_get_ring_params; + target_if_direct_buf_rx_debug_register_tx_ops(tx_ops); } qdf_export_symbol(target_if_direct_buf_rx_register_tx_ops); diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c index c0b0f5da63edfc34353ad78a0d417ef27b1490b7..516f4b3002d2af1f5e961eb46d43d324538cf343 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,7 +43,6 @@ static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev) struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; uint8_t num_dbr_ring_caps, cap_idx, pdev_id, num_modules; struct target_psoc_info *tgt_psoc_info; - struct wlan_psoc_host_service_ext_param *ext_svc_param; psoc = wlan_pdev_get_psoc(pdev); @@ -57,8 +56,7 @@ static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev) direct_buf_rx_err("target_psoc_info is null"); return 0; } - ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info); - num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps; + num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); num_modules = 0; @@ -81,7 +79,6 @@ static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, enum DBR_MODULE mod_id = mod_param->mod_id; uint32_t num_dbr_ring_caps, pdev_id; struct target_psoc_info *tgt_psoc_info; - struct wlan_psoc_host_service_ext_param *ext_svc_param; psoc = wlan_pdev_get_psoc(pdev); @@ -96,8 +93,7 @@ static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } - ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info); - num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps; + num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); pdev_id = mod_param->pdev_id; @@ -123,11 +119,242 @@ static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +#ifdef DIRECT_BUF_RX_DEBUG +static inline struct direct_buf_rx_module_debug * +target_if_get_dbr_mod_debug_from_dbr_pdev_obj( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj, + uint8_t mod_id) +{ + if (!dbr_pdev_obj) { + direct_buf_rx_err("dir buf rx object is null"); + return NULL; + } + + if (mod_id >= DBR_MODULE_MAX) { + direct_buf_rx_err("Invalid module id"); + return NULL; + } + + if (!dbr_pdev_obj->dbr_mod_debug) { + direct_buf_rx_err("dbr_pdev_obj->dbr_mod_debug is NULL"); + return NULL; + } + + if (mod_id >= dbr_pdev_obj->num_modules) { + direct_buf_rx_err("Module %d not supported in target", mod_id); + return NULL; + } + return &dbr_pdev_obj->dbr_mod_debug[mod_id]; +} + +static inline struct direct_buf_rx_module_debug * +target_if_get_dbr_mod_debug_from_pdev( + struct wlan_objmgr_pdev *pdev, + uint8_t mod_id) +{ + struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + + if (!pdev) { + direct_buf_rx_err("pdev is null"); + return NULL; + } + + dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + return target_if_get_dbr_mod_debug_from_dbr_pdev_obj( + dbr_pdev_obj, mod_id); +} +#endif + +#ifdef DIRECT_BUF_RX_DEBUG +#define RING_DEBUG_EVENT_NAME_SIZE 12 +static const unsigned char +g_dbr_ring_debug_event[DBR_RING_DEBUG_EVENT_MAX][RING_DEBUG_EVENT_NAME_SIZE] = { + [DBR_RING_DEBUG_EVENT_RX] = "Rx", + [DBR_RING_DEBUG_EVENT_REPLENISH_RING] = "Replenish", +}; + +/** + * target_if_dbr_print_ring_debug_entries() - Print ring debug entries + * @print: The print adapter function + * @print_priv: The private data to be consumed by @print + * @dbr_pdev_obj: Pdev object of the DBR module + * @mod_id: Module ID + * + * Print ring debug entries of the ring identified by @dbr_pdev_obj and @mod_id + * using the given print adapter function + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS target_if_dbr_print_ring_debug_entries( + qdf_abstract_print print, void *print_priv, + struct direct_buf_rx_pdev_obj *dbr_pdev_obj, + uint8_t mod_id, uint8_t srng_id) +{ + struct direct_buf_rx_module_debug *mod_debug; + struct direct_buf_rx_ring_debug *ring_debug; + int idx; + + mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, + mod_id); + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + mod_debug = &dbr_pdev_obj->dbr_mod_debug[mod_id]; + ring_debug = &mod_debug->dbr_ring_debug[srng_id]; + + if (ring_debug->entries) { + print(print_priv, "Current debug entry is %d", + ring_debug->ring_debug_idx); + print(print_priv, "---------------------------------------------------------"); + print(print_priv, "| Number | Head Idx | Tail Idx | Timestamp | event |"); + print(print_priv, "---------------------------------------------------------"); + for (idx = 0; idx < ring_debug->num_ring_debug_entries; ++idx) { + print(print_priv, "|%8u|%10u|%10u|%11llu|%12s|", idx, + ring_debug->entries[idx].head_idx, + ring_debug->entries[idx].tail_idx, + ring_debug->entries[idx].timestamp, + g_dbr_ring_debug_event[ + ring_debug->entries[idx].event]); + } + print(print_priv, "---------------------------------------------------------"); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dbr_qdf_err_printer() - QDF error level printer for DBR module + * @print_priv: The private data + * @fmt: Format string + * + * This function should be passed in place of the 'print' argument to + * target_if_dbr_print_ring_debug_entries function for the logs that should be + * printed via QDF trace + * + * Return: QDF_STATUS of operation + */ +static int target_if_dbr_qdf_err_printer(void *priv, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + QDF_VTRACE(QDF_MODULE_ID_DIRECT_BUF_RX, QDF_TRACE_LEVEL_ERROR, + (char *)fmt, args); + va_end(args); + + return 0; +} + +static inline void target_if_direct_buf_rx_free_mod_debug( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ + if (!dbr_pdev_obj) { + direct_buf_rx_err("dir buf rx object is null"); + return; + } + /* Free the debug data structures of all modules */ + if (dbr_pdev_obj->dbr_mod_debug) { + qdf_mem_free(dbr_pdev_obj->dbr_mod_debug); + dbr_pdev_obj->dbr_mod_debug = NULL; + } +} + +static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ + if (!dbr_pdev_obj) { + direct_buf_rx_err("dir buf rx object is null"); + return QDF_STATUS_E_FAILURE; + } + /* Allocate the debug data structure for each module */ + dbr_pdev_obj->dbr_mod_debug = qdf_mem_malloc( + dbr_pdev_obj->num_modules * + sizeof(struct direct_buf_rx_module_debug)); + + if (!dbr_pdev_obj->dbr_mod_debug) + return QDF_STATUS_E_NOMEM; + + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void target_if_direct_buf_rx_free_mod_debug( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ +} +#endif + +#if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) +static inline void target_if_direct_buf_pdev_debugfs_init( + struct wlan_objmgr_pdev *pdev) +{ + char dir_name[32]; + struct wlan_objmgr_psoc *psoc; + struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + + if (!pdev) { + direct_buf_rx_err("pdev is null"); + return; + } + + psoc = wlan_pdev_get_psoc(pdev); + dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + if (!dbr_pdev_obj) { + direct_buf_rx_err("dir buf rx object is null"); + return; + } + + qdf_snprintf(dir_name, sizeof(dir_name), "SOC%u_PDEV%u", + wlan_psoc_get_id(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev)); + + /* Create debugfs entry for this radio */ + dbr_pdev_obj->debugfs_entry = qdf_debugfs_create_dir( + dir_name, dbr_debugfs_entry); + + if (!dbr_pdev_obj->debugfs_entry) + direct_buf_rx_err("error while creating direct_buf debugfs dir"); +} + +static inline void target_if_direct_buf_pdev_debugfs_deinit( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ + if (!dbr_pdev_obj) { + direct_buf_rx_err("dir buf rx object is null"); + return; + } + /* Remove the debugfs entry of the radio */ + if (dbr_pdev_obj->debugfs_entry) { + qdf_debugfs_remove_dir_recursive(dbr_pdev_obj->debugfs_entry); + dbr_pdev_obj->debugfs_entry = NULL; + } +} +#else +static inline void target_if_direct_buf_pdev_debugfs_init( + struct wlan_objmgr_pdev *pdev) +{ +} + +static inline void target_if_direct_buf_pdev_debugfs_deinit( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj) +{ +} +#endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( struct wlan_objmgr_pdev *pdev, void *data) { struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + struct direct_buf_rx_psoc_obj *dbr_psoc_obj; struct wlan_objmgr_psoc *psoc; uint8_t num_modules; QDF_STATUS status; @@ -146,13 +373,20 @@ QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( return QDF_STATUS_E_INVAL; } + dbr_psoc_obj = + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + if (!dbr_psoc_obj) { + direct_buf_rx_err("dir buf rx psoc object is null"); + return QDF_STATUS_E_FAILURE; + } + dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj)); if (!dbr_pdev_obj) return QDF_STATUS_E_NOMEM; - direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj); - status = wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_pdev_obj, QDF_STATUS_SUCCESS); @@ -164,6 +398,9 @@ QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( return status; } + dbr_psoc_obj->dbr_pdev_obj[wlan_objmgr_pdev_get_pdev_id(pdev)] = + dbr_pdev_obj; + num_modules = get_num_dbr_modules_per_pdev(pdev); direct_buf_rx_debug("Number of modules = %d pdev %d DBR pdev obj %pK", num_modules, wlan_objmgr_pdev_get_pdev_id(pdev), @@ -181,15 +418,28 @@ QDF_STATUS target_if_direct_buf_rx_pdev_create_handler( sizeof(struct direct_buf_rx_module_param)); if (!dbr_pdev_obj->dbr_mod_param) { - direct_buf_rx_err("alloc dbr mod param fail"); - wlan_objmgr_pdev_component_obj_detach(pdev, - WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, - dbr_pdev_obj); - qdf_mem_free(dbr_pdev_obj); - return QDF_STATUS_E_NOMEM; + direct_buf_rx_err("alloc dbr mod param fail"); + goto dbr_mod_param_fail; } + if (target_if_direct_buf_rx_alloc_mod_debug(dbr_pdev_obj) != + QDF_STATUS_SUCCESS) + goto dbr_mod_debug_fail; + + target_if_direct_buf_pdev_debugfs_init(pdev); + return QDF_STATUS_SUCCESS; + +dbr_mod_debug_fail: + qdf_mem_free(dbr_pdev_obj->dbr_mod_param); + +dbr_mod_param_fail: + wlan_objmgr_pdev_component_obj_detach( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, + dbr_pdev_obj); + qdf_mem_free(dbr_pdev_obj); + + return QDF_STATUS_E_NOMEM; } QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler( @@ -214,11 +464,19 @@ QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler( num_modules = dbr_pdev_obj->num_modules; for (mod_idx = 0; mod_idx < num_modules; mod_idx++) { + /* + * If the module didn't stop the ring debug by this time, + * it will result in memory leak of its ring debug entries. + * So, stop the ring debug + */ + target_if_dbr_stop_ring_debug(pdev, mod_idx); for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_idx, srng_id); } + target_if_direct_buf_pdev_debugfs_deinit(dbr_pdev_obj); + target_if_direct_buf_rx_free_mod_debug(dbr_pdev_obj); qdf_mem_free(dbr_pdev_obj->dbr_mod_param); dbr_pdev_obj->dbr_mod_param = NULL; @@ -304,6 +562,442 @@ QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler( return status; } +#if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG) +/** + * target_if_dbr_debugfs_show_ring_debug() - Function to display ring debug + * entries in debugfs + * @file: qdf debugfs file handler + * @arg: pointer to DBR debugfs private object + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS target_if_dbr_debugfs_show_ring_debug( + qdf_debugfs_file_t file, void *arg) +{ + struct dbr_debugfs_priv *priv = arg; + + return target_if_dbr_print_ring_debug_entries(qdf_debugfs_printer, + file, priv->dbr_pdev_obj, + priv->mod_id, + priv->srng_id); +} + +/** + * target_if_dbr_mod_debugfs_init() - Init debugfs for a given module + * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module + * @mod_id: Module ID corresponding to this ring + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS target_if_dbr_mod_debugfs_init( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj, + enum DBR_MODULE mod_id) +{ + struct direct_buf_rx_module_debug *mod_debug; + + mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, + mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + if (mod_debug->debugfs_entry) { + direct_buf_rx_err("debugfs mod entry was already created for %s module", + g_dbr_module_name[mod_id].module_name_str); + return QDF_STATUS_SUCCESS; + } + + mod_debug->debugfs_entry = + qdf_debugfs_create_dir(g_dbr_module_name[mod_id].module_name_str, + dbr_pdev_obj->debugfs_entry); + + if (!mod_debug->debugfs_entry) { + direct_buf_rx_err("error while creating direct_buf debugfs entry for %s module", + g_dbr_module_name[mod_id].module_name_str); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dbr_ring_debugfs_init() - Init debugfs for a given ring + * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module + * @mod_id: Module ID corresponding to this ring + * @srng_id: srng ID corresponding to this ring + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS target_if_dbr_ring_debugfs_init( + struct direct_buf_rx_pdev_obj *dbr_pdev_obj, + enum DBR_MODULE mod_id, uint8_t srng_id) +{ + struct direct_buf_rx_module_debug *mod_debug; + struct direct_buf_rx_ring_debug *ring_debug; + struct dbr_debugfs_priv *priv; + char debug_file_name[32]; + + mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj, + mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + ring_debug = &mod_debug->dbr_ring_debug[srng_id]; + + if (!mod_debug->debugfs_entry) { + direct_buf_rx_err("error mod_debug->debugfs_entry not created"); + return QDF_STATUS_E_FAILURE; + } + + if (ring_debug->debugfs_entry) { + direct_buf_rx_err("debugfs file for %d ring under %s module already created", + srng_id, + g_dbr_module_name[mod_id].module_name_str); + return QDF_STATUS_SUCCESS; + } + + qdf_snprintf(debug_file_name, sizeof(debug_file_name), + "ring_%d", srng_id); + + // Allocate debugfs ops + ring_debug->debugfs_fops = + qdf_mem_malloc(sizeof(*ring_debug->debugfs_fops)); + if (!ring_debug->debugfs_fops) { + direct_buf_rx_err("error in allocating debugfs ops"); + return QDF_STATUS_E_NOMEM; + } + + // Allocate private data + priv = qdf_mem_malloc(sizeof(*priv)); + if (!priv) { + direct_buf_rx_err("error in creating debugfs private data"); + goto priv_alloc_fail; + } + priv->dbr_pdev_obj = dbr_pdev_obj; + priv->mod_id = mod_id; + priv->srng_id = srng_id; + + /* Fill in the debugfs ops for this ring. + * When the output time comes, the 'show' function will be + * called with 'priv' as an argument. + */ + ring_debug->debugfs_fops->show = target_if_dbr_debugfs_show_ring_debug; + ring_debug->debugfs_fops->priv = priv; + + ring_debug->debugfs_entry = + qdf_debugfs_create_file_simplified( + debug_file_name, + (QDF_FILE_USR_READ | QDF_FILE_GRP_READ | + QDF_FILE_OTH_READ), + mod_debug->debugfs_entry, + ring_debug->debugfs_fops); + + if (!ring_debug->debugfs_entry) { + direct_buf_rx_err("error while creating direct_buf debugfs file for %d ring under %s module", + srng_id, + g_dbr_module_name[mod_id].module_name_str); + goto file_creation_fail; + } + + return QDF_STATUS_SUCCESS; + +file_creation_fail: + qdf_mem_free(ring_debug->debugfs_fops->priv); + +priv_alloc_fail: + qdf_mem_free(ring_debug->debugfs_fops); + ring_debug->debugfs_fops = NULL; + return QDF_STATUS_E_NOMEM; +} + +/** + * target_if_dbr_mod_debugfs_deinit() - De-init debugfs for a given module + * @mod_debug: Pointer to direct_buf_rx_module_debug structure + * + * Return: void + */ +static void target_if_dbr_mod_debugfs_deinit( + struct direct_buf_rx_module_debug *mod_debug) +{ + if (!mod_debug) { + direct_buf_rx_err("mod_debug is null"); + return; + } + + if (mod_debug->debugfs_entry) { + qdf_debugfs_remove_file(mod_debug->debugfs_entry); + mod_debug->debugfs_entry = NULL; + } +} + +/** + * target_if_dbr_ring_debugfs_deinit() - De-init debugfs for a given ring + * @ring_debug: Pointer to direct_buf_rx_ring_debug structure + * + * Return: void + */ +static void target_if_dbr_ring_debugfs_deinit( + struct direct_buf_rx_ring_debug *ring_debug) +{ + if (!ring_debug) { + direct_buf_rx_err("ring_debug is null"); + return; + } + + if (ring_debug->debugfs_entry) { + qdf_debugfs_remove_file(ring_debug->debugfs_entry); + ring_debug->debugfs_entry = NULL; + } + + // Free the private data and debugfs ops of this ring + if (ring_debug->debugfs_fops) { + qdf_mem_free(ring_debug->debugfs_fops->priv); + qdf_mem_free(ring_debug->debugfs_fops); + ring_debug->debugfs_fops = NULL; + } +} +#endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */ + +#ifdef DIRECT_BUF_RX_DEBUG +QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id) +{ + struct direct_buf_rx_module_debug *mod_debug; + struct direct_buf_rx_ring_debug *ring_debug; + uint8_t srng_id; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { + ring_debug = &mod_debug->dbr_ring_debug[srng_id]; + if (!ring_debug->entries) { + direct_buf_rx_debug("DBR ring debug for module %d srng %d was already disabled", + mod_id, srng_id); + continue; + } + /* De-init debugsfs for this ring */ + target_if_dbr_ring_debugfs_deinit(ring_debug); + qdf_mem_free(ring_debug->entries); + ring_debug->entries = NULL; + ring_debug->ring_debug_idx = 0; + ring_debug->num_ring_debug_entries = 0; + direct_buf_rx_info("DBR ring debug for module %d srng %d is now stopped", + mod_id, srng_id); + } + target_if_dbr_mod_debugfs_deinit(mod_debug); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, + uint32_t num_ring_debug_entries) +{ + struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + struct direct_buf_rx_module_debug *mod_debug; + struct direct_buf_rx_ring_debug *ring_debug; + uint8_t srng_id; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + if (num_ring_debug_entries > DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES) { + direct_buf_rx_err("Requested number of ring debug entries(%d) exceed the maximum entries allowed(%d)", + num_ring_debug_entries, + DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES); + + return QDF_STATUS_E_FAILURE; + } + + dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + target_if_dbr_mod_debugfs_init(dbr_pdev_obj, mod_id); + + for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) { + ring_debug = &mod_debug->dbr_ring_debug[srng_id]; + + if (ring_debug->entries) { + direct_buf_rx_err("DBR ring debug for module %d srng %d was already enabled", + mod_id, srng_id); + continue; + } + + ring_debug->entries = qdf_mem_malloc( + num_ring_debug_entries * + sizeof(*ring_debug->entries)); + + if (!ring_debug->entries) + return QDF_STATUS_E_NOMEM; + + ring_debug->ring_debug_idx = 0; + ring_debug->num_ring_debug_entries = num_ring_debug_entries; + /* Init debugsfs for this ring */ + target_if_dbr_ring_debugfs_init( + dbr_pdev_obj, + mod_id, srng_id); + direct_buf_rx_info("DBR ring debug for module %d srng %d is now started", + mod_id, srng_id); + } + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, uint32_t value) +{ + struct direct_buf_rx_module_debug *mod_debug; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + mod_debug->poisoning_enabled = true; + mod_debug->poison_value = value; /* Save the poison value */ + + direct_buf_rx_debug("DBR buffer poisoning for module %d is now started", + mod_id); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_stop_buffer_poisoning( + struct wlan_objmgr_pdev *pdev, + uint8_t mod_id) +{ + struct direct_buf_rx_module_debug *mod_debug; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + mod_debug->poisoning_enabled = false; + mod_debug->poison_value = 0; + + direct_buf_rx_debug("DBR buffer poisoning for module %d is now stopped", + mod_id); + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_dbr_fill_buffer_u32() - Fill buffer with an unsigned 32-bit value + * @buffer: pointer to the buffer + * @num_bytes: Size of the destination buffer in bytes + * @value: Unsigned 32-bit value to be copied + * + * Return : void + */ +static void +target_if_dbr_fill_buffer_u32(uint8_t *buffer, uint32_t num_bytes, + uint32_t value) +{ + uint32_t *bufp; + uint32_t idx; + uint32_t size = (num_bytes >> 2); + + if (!buffer) { + direct_buf_rx_err("buffer empty"); + return; + } + + bufp = (uint32_t *)buffer; + + for (idx = 0; idx < size; ++idx) { + *bufp = value; + ++bufp; + } +} + +/** + * target_if_dbr_debug_poison_buffer() - Poison a given DBR buffer + * @pdev: pointer to pdev object + * @mod_id: Module ID of the owner of the buffer + * @aligned_vaddr: Virtual address(aligned) of the buffer + * @size: Size of the buffer + * + * Value with which the buffers will be poisoned would have been saved + * while starting the buffer poisoning for the module, use that value. + * + * Return : QDF status of operation + */ +static QDF_STATUS target_if_dbr_debug_poison_buffer( + struct wlan_objmgr_pdev *pdev, + uint32_t mod_id, void *aligned_vaddr, uint32_t size) +{ + struct direct_buf_rx_module_debug *mod_debug; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + + if (!mod_debug) + return QDF_STATUS_E_INVAL; + + if (mod_debug->poisoning_enabled) { + target_if_dbr_fill_buffer_u32(aligned_vaddr, size, + mod_debug->poison_value); + } + + return QDF_STATUS_SUCCESS; +} + +static inline void target_if_dbr_qdf_show_ring_debug( + struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, uint8_t srng_id) +{ + struct direct_buf_rx_pdev_obj *dbr_pdev_obj = + wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + target_if_dbr_print_ring_debug_entries( + target_if_dbr_qdf_err_printer, + NULL, dbr_pdev_obj, + mod_id, srng_id); +} +#else +QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, + uint32_t num_ring_debug_entries) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, uint32_t value) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_dbr_stop_buffer_poisoning( + struct wlan_objmgr_pdev *pdev, + uint8_t mod_id) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS target_if_dbr_debug_poison_buffer( + struct wlan_objmgr_pdev *pdev, + uint32_t mod_id, void *aligned_vaddr, uint32_t size) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void target_if_dbr_qdf_show_ring_debug( + struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, uint8_t srng_id) +{ +} +#endif /* DIRECT_BUF_RX_DEBUG */ + static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, struct direct_buf_rx_module_param *mod_param, void *aligned_vaddr, uint32_t cookie) @@ -349,6 +1043,10 @@ static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } + target_if_dbr_debug_poison_buffer( + pdev, mod_param->mod_id, aligned_vaddr, + dbr_ring_cap->min_buf_size); + map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev, aligned_vaddr, QDF_DMA_FROM_DEVICE, @@ -364,7 +1062,13 @@ static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev, hal_srng_access_start(hal_soc, srng); ring_entry = hal_srng_src_get_next(hal_soc, srng); - QDF_ASSERT(ring_entry); + + if (!ring_entry) { + target_if_dbr_qdf_show_ring_debug(pdev, mod_param->mod_id, + mod_param->srng_id); + QDF_BUG(0); + } + dw_lo = (uint64_t)paddr & 0xFFFFFFFF; WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32); WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie); @@ -572,7 +1276,7 @@ static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, { QDF_STATUS status; struct wlan_objmgr_psoc *psoc; - void *wmi_hdl; + wmi_unified_t wmi_hdl; struct direct_buf_rx_cfg_req dbr_cfg_req = {0}; struct direct_buf_rx_ring_cfg *dbr_ring_cfg; struct direct_buf_rx_ring_cap *dbr_ring_cap; @@ -589,7 +1293,7 @@ static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, dbr_ring_cfg = mod_param->dbr_ring_cfg; dbr_ring_cap = mod_param->dbr_ring_cap; dbr_config = &mod_param->dbr_config; - wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); + wmi_hdl = lmac_get_pdev_wmi_handle(pdev); if (!wmi_hdl) { direct_buf_rx_err("WMI handle null. Can't send WMI CMD"); return QDF_STATUS_E_INVAL; @@ -599,18 +1303,18 @@ static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev, dbr_cfg_req.pdev_id = mod_param->pdev_id; /* Module ID numbering starts from 1 in FW. need to fix it */ dbr_cfg_req.mod_id = mod_param->mod_id; - dbr_cfg_req.base_paddr_lo = (uint64_t)dbr_ring_cfg->base_paddr_aligned - & 0xFFFFFFFF; - dbr_cfg_req.base_paddr_hi = (uint64_t)dbr_ring_cfg->base_paddr_aligned - & 0xFFFFFFFF00000000; - dbr_cfg_req.head_idx_paddr_lo = (uint64_t)dbr_ring_cfg->head_idx_addr - & 0xFFFFFFFF; - dbr_cfg_req.head_idx_paddr_hi = (uint64_t)dbr_ring_cfg->head_idx_addr - & 0xFFFFFFFF00000000; - dbr_cfg_req.tail_idx_paddr_lo = (uint64_t)dbr_ring_cfg->tail_idx_addr - & 0xFFFFFFFF; - dbr_cfg_req.tail_idx_paddr_hi = (uint64_t)dbr_ring_cfg->tail_idx_addr - & 0xFFFFFFFF00000000; + dbr_cfg_req.base_paddr_lo = + qdf_get_lower_32_bits(dbr_ring_cfg->base_paddr_aligned); + dbr_cfg_req.base_paddr_hi = + qdf_get_upper_32_bits(dbr_ring_cfg->base_paddr_aligned); + dbr_cfg_req.head_idx_paddr_lo = + qdf_get_lower_32_bits(dbr_ring_cfg->head_idx_addr); + dbr_cfg_req.head_idx_paddr_hi = + qdf_get_upper_32_bits(dbr_ring_cfg->head_idx_addr); + dbr_cfg_req.tail_idx_paddr_lo = + qdf_get_lower_32_bits(dbr_ring_cfg->tail_idx_addr); + dbr_cfg_req.tail_idx_paddr_hi = + qdf_get_upper_32_bits(dbr_ring_cfg->tail_idx_addr); dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min; dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size; dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event; @@ -662,6 +1366,7 @@ static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev, mod_param->mod_id = mod_id; mod_param->pdev_id = dbr_get_pdev_id( srng_id, wlan_objmgr_pdev_get_pdev_id(pdev)); + mod_param->srng_id = srng_id; /* Initialize DMA ring now */ status = target_if_dbr_init_srng(pdev, mod_param); @@ -813,8 +1518,10 @@ static void *target_if_dbr_vaddr_lookup( return dbr_buf_pool[cookie].vaddr + dbr_buf_pool[cookie].offset; } + direct_buf_rx_debug("Invalid paddr, cookie %d, pool paddr %pK, paddr %pK", + cookie, (void *)dbr_buf_pool[cookie].paddr, + (void *)paddr); - direct_buf_rx_debug("Incorrect paddr found on cookie slot"); return NULL; } @@ -925,6 +1632,14 @@ static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev, *cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET( dbr_rsp->dbr_entries[idx].paddr_hi); dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie); + + if (!dbr_data->vaddr) { + direct_buf_rx_debug("dbr vaddr lookup failed, cookie %d, hi %x, lo %x", + *cookie, dbr_rsp->dbr_entries[idx].paddr_hi, + dbr_rsp->dbr_entries[idx].paddr_lo); + return QDF_STATUS_E_FAILURE; + } + dbr_data->cookie = *cookie; dbr_data->paddr = paddr; direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK", @@ -981,6 +1696,90 @@ dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, } #endif +#ifdef DIRECT_BUF_RX_DEBUG +/** + * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry + * @pdev: pointer to pdev object + * @mod_id: Module ID + * @event: ring debug event + * + * Log the given event, head and tail pointers of DBR ring of the given module + * into its ring debug data structure. + * Also, log the timestamp at the time of logging. + */ +static void target_if_dbr_add_ring_debug_entry( + struct wlan_objmgr_pdev *pdev, + uint32_t mod_id, + enum DBR_RING_DEBUG_EVENT event, + uint8_t srng_id) +{ + struct wlan_objmgr_psoc *psoc; + void *hal_soc, *srng; + uint32_t hp = 0, tp = 0; + struct direct_buf_rx_psoc_obj *dbr_psoc_obj; + struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + struct direct_buf_rx_ring_cfg *dbr_ring_cfg; + struct direct_buf_rx_module_debug *mod_debug; + struct direct_buf_rx_module_param *mod_param; + struct direct_buf_rx_ring_debug *ring_debug; + struct direct_buf_rx_ring_debug_entry *entry; + + mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id); + + if (!mod_debug) + return; + + psoc = wlan_pdev_get_psoc(pdev); + + dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( + psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX); + + mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]; + if (!mod_param) { + direct_buf_rx_err("dir buf rx module param is null"); + return; + } + + hal_soc = dbr_psoc_obj->hal_soc; + dbr_ring_cfg = mod_param->dbr_ring_cfg; + srng = dbr_ring_cfg->srng; + ring_debug = &mod_debug->dbr_ring_debug[srng_id]; + + if (ring_debug->entries) { + if (hal_srng_access_start(hal_soc, srng)) { + direct_buf_rx_err("module %d - HAL srng access failed", + mod_id); + return; + } + hal_get_sw_hptp(hal_soc, srng, &tp, &hp); + hal_srng_access_end(hal_soc, srng); + entry = &ring_debug->entries[ring_debug->ring_debug_idx]; + + entry->head_idx = hp; + entry->tail_idx = tp; + entry->timestamp = qdf_get_log_timestamp(); + entry->event = event; + + ring_debug->ring_debug_idx++; + if (ring_debug->ring_debug_idx == + ring_debug->num_ring_debug_entries) + ring_debug->ring_debug_idx = 0; + } +} + +#else +static void target_if_dbr_add_ring_debug_entry( + struct wlan_objmgr_pdev *pdev, + uint32_t mod_id, + enum DBR_RING_DEBUG_EVENT event, + uint8_t srng_id) +{ +} +#endif /* DIRECT_BUF_RX_DEBUG */ + static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, uint8_t *data_buf, uint32_t data_len) @@ -996,7 +1795,7 @@ static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, struct direct_buf_rx_buf_info *dbr_buf_pool; struct direct_buf_rx_pdev_obj *dbr_pdev_obj; struct direct_buf_rx_module_param *mod_param; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID; uint8_t srng_id = 0; @@ -1095,10 +1894,20 @@ static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, &dbr_data.meta_data) == QDF_STATUS_SUCCESS) dbr_data.meta_data_valid = true; } + + target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, + DBR_RING_DEBUG_EVENT_RX, + srng_id); if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) { status = target_if_dbr_replenish_ring(pdev, mod_param, dbr_data.vaddr, cookie); + + target_if_dbr_add_ring_debug_entry( + pdev, dbr_rsp.mod_id, + DBR_RING_DEBUG_EVENT_REPLENISH_RING, + srng_id); + if (QDF_IS_STATUS_ERROR(status)) { direct_buf_rx_err("Ring replenish failed"); qdf_mem_free(dbr_rsp.dbr_entries); diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.h b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.h index 5e8e56637a380e2e0fb4db093db380e460a52d0f..a06375f9cc40fb9dbdca0aca2e5f13c686d04c82 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.h @@ -88,6 +88,84 @@ struct direct_buf_rx_ring_cap { uint32_t min_buf_align; }; +/** + * enum DBR_RING_DEBUG_EVENT - DMA ring debug event + * @DBR_RING_DEBUG_EVENT_NONE: Not a real value, just a place holder for + * no entry + * @DBR_RING_DEBUG_EVENT_RX: DBR Rx event + * @DBR_RING_DEBUG_EVENT_REPLENISH_RING: DBR replenish event + * @DBR_RING_DEBUG_EVENT_MAX: Not a real value, just a place holder for max + */ +enum DBR_RING_DEBUG_EVENT { + DBR_RING_DEBUG_EVENT_NONE = 0, + DBR_RING_DEBUG_EVENT_RX, + DBR_RING_DEBUG_EVENT_REPLENISH_RING, + DBR_RING_DEBUG_EVENT_MAX, +}; + +#define DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES (1024) +/** + * struct direct_buf_rx_ring_debug_entry - DBR ring debug entry + * @head_idx: Head index of the DMA ring + * @tail_idx: Tail index of the DMA ring + * @timestamp: Timestamp at the time of logging + * @event: Name of the event + */ +struct direct_buf_rx_ring_debug_entry { + uint32_t head_idx; + uint32_t tail_idx; + uint64_t timestamp; + enum DBR_RING_DEBUG_EVENT event; +}; + +#ifdef WLAN_DEBUGFS +/** + * struct dbr_debugfs_priv - Private data for DBR ring debugfs + * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module + * @mod_id: Pointer to the registered module ID + * @srng_id: srng ID + */ +struct dbr_debugfs_priv { + struct direct_buf_rx_pdev_obj *dbr_pdev_obj; + enum DBR_MODULE mod_id; + uint8_t srng_id; +}; +#endif + +/** + * struct direct_buf_rx_ring_debug - DMA ring debug of a module + * @entries: Pointer to the array of ring debug entries + * @ring_debug_idx: Current index in the array of ring debug entries + * @num_ring_debug_entries: Total ring debug entries + * @debugfs_entry: Debugfs entry for this ring + * @debugfs_priv: Debugfs ops for this ring + */ +struct direct_buf_rx_ring_debug { + struct direct_buf_rx_ring_debug_entry *entries; + uint32_t ring_debug_idx; + uint32_t num_ring_debug_entries; +#ifdef WLAN_DEBUGFS + qdf_dentry_t debugfs_entry; + struct qdf_debugfs_fops *debugfs_fops; +#endif +}; + +/** + * struct direct_buf_rx_module_debug - Debug of a module subscribed to DBR + * @dbr_ring_debug: Array of ring debug structers corresponding to each srng + * @poisoning_enabled: Whether buffer poisoning is enabled for this module + * @poison_value: Value with which buffers should be poisoned + * @debugfs_entry: Debugfs entry for this module + */ +struct direct_buf_rx_module_debug { + struct direct_buf_rx_ring_debug dbr_ring_debug[DBR_SRNG_NUM]; + bool poisoning_enabled; + uint32_t poison_value; +#ifdef WLAN_DEBUGFS + qdf_dentry_t debugfs_entry; +#endif +}; + /** * struct direct_buf_rx_module_param - DMA module param * @mod_id: Module ID @@ -101,6 +179,7 @@ struct direct_buf_rx_ring_cap { struct direct_buf_rx_module_param { enum DBR_MODULE mod_id; uint8_t pdev_id; + uint8_t srng_id; struct dbr_module_config dbr_config; struct direct_buf_rx_ring_cap *dbr_ring_cap; struct direct_buf_rx_ring_cfg *dbr_ring_cfg; @@ -113,20 +192,30 @@ struct direct_buf_rx_module_param { * struct direct_buf_rx_pdev_obj - Direct Buf RX pdev object struct * @num_modules: Number of modules registered to DBR for the pdev * @dbr_mod_param: Pointer to direct buf rx module param struct + * @dbr_mod_debug: Pointer to the array of DBR module debug structures + * @debugfs_entry: DBR debugfs entry of this radio */ struct direct_buf_rx_pdev_obj { uint32_t num_modules; struct direct_buf_rx_module_param (*dbr_mod_param)[DBR_SRNG_NUM]; +#ifdef DIRECT_BUF_RX_DEBUG + struct direct_buf_rx_module_debug *dbr_mod_debug; +#ifdef WLAN_DEBUGFS + qdf_dentry_t debugfs_entry; +#endif +#endif }; /** * struct direct_buf_rx_psoc_obj - Direct Buf RX psoc object struct * @hal_soc: Opaque HAL SOC handle * @osdev: QDF os device handle + * @dbr_pdev_objs: array of DBR pdev objects */ struct direct_buf_rx_psoc_obj { void *hal_soc; qdf_device_t osdev; + struct direct_buf_rx_pdev_obj *dbr_pdev_obj[WLAN_UMAC_MAX_PDEVS]; }; /** @@ -271,4 +360,44 @@ target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev, struct module_ring_params *param, uint8_t mod_id, uint8_t srng_id); +/** + * target_if_dbr_start_ring_debug() - Start DBR ring debug + * @pdev: pointer to pdev object + * @mod_id: module ID indicating the module using direct buffer rx framework + * @num_ring_debug_entries: Size of the ring debug entries + */ +QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, + uint32_t num_ring_debug_entries); + +/** + * target_if_dbr_stop_ring_debug() - Stop DBR ring debug + * @pdev: pointer to pdev object + * @mod_id: module ID indicating the module using direct buffer rx framework + */ +QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id); + +/** + * target_if_dbr_start_buffer_poisoning() - Start DBR buffer poisoning + * @pdev: pointer to pdev object + * @mod_id: module ID indicating the module using direct buffer rx framework + * @value: Value with which buffers should be poisoned + * + * Only those buffers which are going to be mapped to the device after this + * API call are guaranteed to be poisoned. If user wants all the buffers in + * the ring to be poisoned from their creation time then this API should be + * called before module's registration to the DBR. + * + */ +QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id, uint32_t value); + +/** + * target_if_dbr_stop_buffer_poisoning() - Stop DBR buffer poisoning + * @pdev: pointer to pdev object + * @mod_id: module ID indicating the module using direct buffer rx framework + */ +QDF_STATUS target_if_dbr_stop_buffer_poisoning(struct wlan_objmgr_pdev *pdev, + uint8_t mod_id); #endif /* _TARGET_IF_DIRECT_BUF_RX_MAIN_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dispatcher/inc/target_if_pub.h b/drivers/staging/qca-wifi-host-cmn/target_if/dispatcher/inc/target_if_pub.h new file mode 100644 index 0000000000000000000000000000000000000000..84a24b7c264dcb4d51f2116e59d3ef8143cbb7d8 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dispatcher/inc/target_if_pub.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * + * 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 contains the structure definitions of target interface + * used for the abstraction across various layers. + */ + +#ifndef _TARGET_IF_PUB_H_ +#define _TARGET_IF_PUB_H_ + +/** + * typedef target_pdev_info_t - Opaque definition of target pdev + * information structure + */ +struct target_pdev_info; +typedef struct target_pdev_info target_pdev_info_t; + +/** + * typedef target_psoc_info_t - Opaque definition of target psoc + * information structure + */ +struct target_psoc_info; +typedef struct target_psoc_info target_psoc_info_t; +#endif /* _TARGET_IF_PUB_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dp/inc/target_if_dp.h b/drivers/staging/qca-wifi-host-cmn/target_if/dp/inc/target_if_dp.h index 3bae0e202603e4a99627f9c2ef9c92b514cd3898..dcb6327b425b251375686edf030b12f23e4a2223 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/dp/inc/target_if_dp.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dp/inc/target_if_dp.h @@ -33,8 +33,9 @@ /** * struct reorder_q_setup - reorder queue setup params - * @pdev: pdev + * @psoc: psoc * @vdev_id: vdev id + * @pdev_id: pdev id * @peer_macaddr: peer mac address * @hw_qdesc: hw queue descriptor * @tid: tid number @@ -43,8 +44,9 @@ * @ba_window_size: BA window size */ struct reorder_q_setup { - struct cdp_ctrl_objmgr_pdev *pdev; + struct cdp_ctrl_objmgr_psoc *psoc; uint8_t vdev_id; + uint8_t pdev_id; uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; qdf_dma_addr_t hw_qdesc_paddr; uint8_t tid; @@ -55,7 +57,8 @@ struct reorder_q_setup { /** * target_if_peer_set_default_routing() - set peer default routing - * @pdev: pdev pointer + * @psoc: psoc pointer + * @pdev_id: pdev id * @peer_macaddr: peer mac address * @vdev_id: vdev id * @hash_based: hash based routing @@ -64,13 +67,14 @@ struct reorder_q_setup { * return: void */ void -target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t *peer_macaddr, uint8_t vdev_id, bool hash_based, uint8_t ring_num); - /** * target_if_peer_rx_reorder_queue_setup() - setup rx reorder queue * @pdev: pdev pointer + * @pdev_id: pdev id * @vdev_id: vdev id * @peer_macaddr: peer mac address * @hw_qdesc: hw queue descriptor @@ -82,7 +86,8 @@ target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_pdev *pdev, * return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS -target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, qdf_dma_addr_t hw_qdesc, int tid, uint16_t queue_no, @@ -91,7 +96,8 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, /** * target_if_peer_rx_reorder_queue_remove() - remove rx reorder queue - * @pdev: pdev pointer + * @psoc: psoc pointer + * @pdev_id: pdev id * @vdev_id: vdev id * @peer_macaddr: peer mac address * @peer_tid_bitmap: peer tid bitmap @@ -99,7 +105,8 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, * return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS -target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, uint32_t peer_tid_bitmap); @@ -111,7 +118,7 @@ target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_pdev *pdev, * return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS -target_if_lro_hash_config(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, struct cdp_lro_hash_config *lro_hash_cfg); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c b/drivers/staging/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c index fb7a25370c81274462aca88a2c0f804b98f7e2fb..e45352f887ec4b0e3274cfadebbccc303a6b4fc7 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/dp/src/target_if_dp.c @@ -25,17 +25,26 @@ #include void -target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_pdev *pdev, - uint8_t *peer_macaddr, uint8_t vdev_id, +target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t *peer_macaddr, + uint8_t vdev_id, bool hash_based, uint8_t ring_num) { uint32_t value; struct peer_set_params param; - struct common_wmi_handle *pdev_wmi_handle; + struct wmi_unified *pdev_wmi_handle; + struct wlan_objmgr_pdev *pdev = + wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, + pdev_id, WLAN_PDEV_TARGET_IF_ID); - pdev_wmi_handle = - lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev); + if (!pdev) { + target_if_err("pdev with id %d is NULL", pdev_id); + return; + } + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); if (!pdev_wmi_handle) { + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); target_if_err("pdev wmi handle NULL"); return; } @@ -53,9 +62,10 @@ target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_pdev *pdev, if (wmi_set_peer_param_send(pdev_wmi_handle, peer_macaddr, ¶m)) { target_if_err("Unable to set default routing for peer " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_macaddr)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_macaddr)); } + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); } #ifdef SERIALIZE_QUEUE_SETUP @@ -63,10 +73,11 @@ static QDF_STATUS target_if_rx_reorder_queue_setup(struct scheduler_msg *msg) { struct rx_reorder_queue_setup_params param; - struct common_wmi_handle *pdev_wmi_handle; + struct wmi_unified *pdev_wmi_handle; struct reorder_q_setup *q_params; - struct cdp_ctrl_objmgr_pdev *pdev; QDF_STATUS status; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; if (!(msg->bodyptr)) { target_if_err("rx_reorder: Invalid message body"); @@ -74,9 +85,17 @@ target_if_rx_reorder_queue_setup(struct scheduler_msg *msg) } q_params = msg->bodyptr; - pdev = q_params->pdev; - pdev_wmi_handle = - lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev); + psoc = (struct wlan_objmgr_psoc *)q_params->psoc; + + pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id, + WLAN_PDEV_TARGET_IF_ID); + + if (!pdev) { + target_if_err("pdev with id %d is NULL", q_params->pdev_id); + return QDF_STATUS_E_INVAL; + } + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); if (!pdev_wmi_handle) { target_if_err("pdev wmi handle NULL"); status = QDF_STATUS_E_FAILURE; @@ -95,13 +114,15 @@ target_if_rx_reorder_queue_setup(struct scheduler_msg *msg) status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle, ¶m); out: + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); qdf_mem_free(q_params); return status; } QDF_STATUS -target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, qdf_dma_addr_t hw_qdesc, int tid, uint16_t queue_no, @@ -116,8 +137,9 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, if (!q_params) return QDF_STATUS_E_NOMEM; - q_params->pdev = pdev; + q_params->psoc = psoc; q_params->vdev_id = vdev_id; + q_params->pdev_id = pdev_id; q_params->hw_qdesc_paddr = hw_qdesc; q_params->tid = tid; q_params->queue_no = queue_no; @@ -140,7 +162,8 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, #else QDF_STATUS -target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, qdf_dma_addr_t hw_qdesc, int tid, uint16_t queue_no, @@ -148,11 +171,20 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, uint16_t ba_window_size) { struct rx_reorder_queue_setup_params param; - struct common_wmi_handle *pdev_wmi_handle; + struct wmi_unified *pdev_wmi_handle; + QDF_STATUS status; + struct wlan_objmgr_pdev *pdev = + wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, + pdev_id, WLAN_PDEV_TARGET_IF_ID); - pdev_wmi_handle = - lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev); + if (!pdev) { + target_if_err("pdev with id %d is NULL", pdev_id); + return QDF_STATUS_E_INVAL; + } + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); if (!pdev_wmi_handle) { + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); target_if_err("pdev wmi handle NULL"); return QDF_STATUS_E_FAILURE; } @@ -165,42 +197,67 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_pdev *pdev, param.ba_window_size_valid = ba_window_size_valid; param.ba_window_size = ba_window_size; - return wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle, - ¶m); + status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle, + ¶m); + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); + + return status; } #endif QDF_STATUS -target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, uint8_t vdev_id, uint8_t *peer_macaddr, uint32_t peer_tid_bitmap) { struct rx_reorder_queue_remove_params param; - struct common_wmi_handle *pdev_wmi_handle; + struct wmi_unified *pdev_wmi_handle; + QDF_STATUS status; + struct wlan_objmgr_pdev *pdev = + wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, + pdev_id, WLAN_PDEV_TARGET_IF_ID); - pdev_wmi_handle = - lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev); + if (!pdev) { + target_if_err("pdev with id %d is NULL", pdev_id); + return QDF_STATUS_E_INVAL; + } + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); if (!pdev_wmi_handle) { + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); target_if_err("pdev wmi handle NULL"); return QDF_STATUS_E_FAILURE; } param.vdev_id = vdev_id; param.peer_macaddr = peer_macaddr; param.peer_tid_bitmap = peer_tid_bitmap; - return wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle, - ¶m); + status = wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle, + ¶m); + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); + + return status; } QDF_STATUS -target_if_lro_hash_config(struct cdp_ctrl_objmgr_pdev *pdev, +target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, struct cdp_lro_hash_config *lro_hash_cfg) { struct wmi_lro_config_cmd_t wmi_lro_cmd = {0}; - struct common_wmi_handle *pdev_wmi_handle; + struct wmi_unified *pdev_wmi_handle; + QDF_STATUS status; + struct wlan_objmgr_pdev *pdev = + wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, + pdev_id, WLAN_PDEV_TARGET_IF_ID); - pdev_wmi_handle = - lmac_get_pdev_wmi_handle((struct wlan_objmgr_pdev *)pdev); + if (!pdev) { + target_if_err("pdev with id %d is NULL", pdev_id); + return QDF_STATUS_E_INVAL; + } + + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); if (!lro_hash_cfg || !pdev_wmi_handle) { + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); target_if_err("wmi_handle: 0x%pK, lro_hash_cfg: 0x%pK", pdev_wmi_handle, lro_hash_cfg); return QDF_STATUS_E_FAILURE; @@ -209,8 +266,7 @@ target_if_lro_hash_config(struct cdp_ctrl_objmgr_pdev *pdev, wmi_lro_cmd.lro_enable = lro_hash_cfg->lro_enable; wmi_lro_cmd.tcp_flag = lro_hash_cfg->tcp_flag; wmi_lro_cmd.tcp_flag_mask = lro_hash_cfg->tcp_flag_mask; - wmi_lro_cmd.pdev_id = - lmac_get_pdev_idx((struct wlan_objmgr_pdev *)pdev); + wmi_lro_cmd.pdev_id = pdev_id; qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4, lro_hash_cfg->toeplitz_hash_ipv4, @@ -220,6 +276,9 @@ target_if_lro_hash_config(struct cdp_ctrl_objmgr_pdev *pdev, lro_hash_cfg->toeplitz_hash_ipv6, LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t)); - return wmi_unified_lro_config_cmd(pdev_wmi_handle, - &wmi_lro_cmd); + status = wmi_unified_lro_config_cmd(pdev_wmi_handle, + &wmi_lro_cmd); + wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); + + return status; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.c b/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..0b2cb5050645c2f8211bdfe2342626335b3d8578 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: target_if_gpio.c + * + * This file provide definition for APIs registered through lmac Tx Ops + */ + +#include +#include +#include +#include +#include + +/** + * target_if_set_gpio_config() - API to send gpio config request to wmi + * @psoc: pointer to psoc object + * @param: pointer to gpio info + * + * Return: status of operation. + */ +static QDF_STATUS +target_if_set_gpio_config(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null."); + return QDF_STATUS_E_NULL_VALUE; + } + + return wmi_unified_gpio_config_cmd_send(wmi_handle, param); +} + +/** + * target_if_set_gpio_output() - API to send gpio output request to wmi + * @psoc: pointer to psoc object + * @param: pointer to gpio info + * + * Return: status of operation. + */ +static QDF_STATUS +target_if_set_gpio_output(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null."); + return QDF_STATUS_E_NULL_VALUE; + } + + return wmi_unified_gpio_output_cmd_send(wmi_handle, param); +} + +QDF_STATUS +target_if_gpio_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + struct wlan_lmac_if_gpio_tx_ops *gpio_ops; + + if (!tx_ops) { + target_if_err("tx ops is NULL!"); + return QDF_STATUS_E_INVAL; + } + gpio_ops = &tx_ops->gpio_ops; + + gpio_ops->set_gpio_config = target_if_set_gpio_config; + gpio_ops->set_gpio_output = target_if_set_gpio_output; + + return QDF_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.h b/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..f0993511c645959beb6a3ca974b655295643ad28 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/gpio/target_if_gpio.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: offload lmac interface APIs for gpio cfg + */ +#ifndef __TARGET_IF_GPIO_CFG_H__ +#define __TARGET_IF_GPIO_CFG_H__ + +#ifdef WLAN_FEATURE_GPIO_CFG +#include +struct wlan_lmac_if_tx_ops; + +/** + * target_if_gpio_register_tx_ops() - register tx ops funcs + * @tx_ops: pointer to gpio tx ops + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +target_if_gpio_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); + +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /* __TARGET_IF_GPIO_CFG_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c b/drivers/staging/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c index 3ecf935c678c710f40dcc5d780d8f423b14edea8..56b70dbceeef4c20fa9dc70ae49782d5c03ec97d 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -140,7 +140,7 @@ QDF_STATUS target_if_green_ap_enable_egap( struct wlan_green_ap_egap_params *egap_params) { struct wlan_pdev_green_ap_ctx *green_ap_ctx; - void *wmi_hdl; + wmi_unified_t wmi_hdl; if (!pdev) { green_ap_err("pdev context passed is NULL"); @@ -175,7 +175,7 @@ QDF_STATUS target_if_green_ap_enable_egap( QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev, bool value, uint8_t pdev_id) { - void *wmi_hdl; + wmi_unified_t wmi_hdl; if (!pdev) { green_ap_err("pdev context passed is NULL"); diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_cmd_api.h b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_cmd_api.h index e96d3802c54b0c28a89a9be3ff81b08f3b46aa15..a7c9adf1efc640d8c6e40f80a625335db6bbb998 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_cmd_api.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_cmd_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,18 +33,6 @@ #define TXBF_CV_POOL2 4 #define HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED 0x8 -/** - * enum wlan_fw_mem_prio - defines FW Memory requirement type - * @FW_MEM_HIGH_PRIORITY: Memory requires contiguous memory allocation - * @FW_MEM_LOW_PRIORITY: Memory can be fragmented - * @FW_PRIORITY_MAX: Invalid type - */ -enum wlan_fw_mem_prio { - FW_MEM_HIGH_PRIORITY = 0, - FW_MEM_LOW_PRIORITY, - FW_PRIORITY_MAX -}; - /** * init_deinit_handle_host_mem_req() - handle host memory request * @psoc: PSOC object diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_deinit_lmac.h b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_deinit_lmac.h index bf1b43cb0b879ad28c2745414d03ee46639c915d..7d3b7104186255082dba560d5565a6914e45fb9f 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_deinit_lmac.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/init_deinit_lmac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -117,7 +117,7 @@ bool lmac_is_target_ar900b(struct wlan_objmgr_psoc *psoc); * * Return: wmi handler */ -struct common_wmi_handle *lmac_get_wmi_hdl(struct wlan_objmgr_psoc *psoc); +struct wmi_unified *lmac_get_wmi_hdl(struct wlan_objmgr_psoc *psoc); /** * lmac_get_wmi_unified_hdl() - get wmi handle @@ -137,7 +137,7 @@ wmi_unified_t lmac_get_wmi_unified_hdl(struct wlan_objmgr_psoc *psoc); * * Return: htc handler */ -struct common_htc_handle *lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc); +HTC_HANDLE lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc); /** * lmac_set_htc_hdl() - set htc handle @@ -149,7 +149,7 @@ struct common_htc_handle *lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc); * Return: void */ void lmac_set_htc_hdl(struct wlan_objmgr_psoc *psoc, - struct common_htc_handle *htc_hdl); + HTC_HANDLE htc_hdl); /** * lmac_get_hif_hdl() - get hif handle @@ -159,7 +159,7 @@ void lmac_set_htc_hdl(struct wlan_objmgr_psoc *psoc, * * Return: hif handler */ -struct common_hif_handle *lmac_get_hif_hdl(struct wlan_objmgr_psoc *psoc); +struct hif_opaque_softc *lmac_get_hif_hdl(struct wlan_objmgr_psoc *psoc); /** * lmac_get_ol_hif_hdl() - get hif handle @@ -179,7 +179,7 @@ struct hif_opaque_softc *lmac_get_ol_hif_hdl(struct wlan_objmgr_psoc *psoc); * * Return: wmi handle */ -struct common_wmi_handle *lmac_get_pdev_wmi_handle( +struct wmi_unified *lmac_get_pdev_wmi_handle( struct wlan_objmgr_pdev *pdev); /** diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_param.h b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_param.h index 4073156b1a265a54c77fad958dd6f51542bf0169..3a0f9986aebecd78fcd0d3a499feff67893994eb 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_param.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_param.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -109,6 +109,23 @@ struct wlan_psoc_host_ppe_threshold { uint32_t ppet16_ppet8_ru3_ru0[PSOC_HOST_MAX_NUM_SS]; }; +/** + * struct wlan_psoc_host_hal_reg_cap_ext - extended regulatory capabilities + * recvd in EXT service + * @wireless_modes: REGDMN MODE + * @low_2ghz_chan: lower 2.4GHz channels + * @high_2ghz_chan: higher 2.4 GHz channels + * @low_5ghz_chan: lower 5 GHz channels + * @high_5ghz_chan: higher 5 GHz channels + */ +struct wlan_psoc_host_hal_reg_cap_ext { + uint32_t wireless_modes; + uint32_t low_2ghz_chan; + uint32_t high_2ghz_chan; + uint32_t low_5ghz_chan; + uint32_t high_5ghz_chan; +}; + /** * struct wlan_psoc_host_mac_phy_caps - Phy caps recvd in EXT service * @hw_mode_id: identify a particular set of HW characteristics, @@ -161,6 +178,11 @@ struct wlan_psoc_host_ppe_threshold { * @he_ppet5G: 5G HE PPET info * @chainmask_table_id: chain mask table id * @lmac_id: hw mac id + * @reg_cap_ext: extended regulatory capabilities + * @tgt_pdev_id: target pdev id assigned and used by firmware + * @nss_ratio_enabled: This flag is set if nss ratio is received from FW as part + * of service ready ext event. + * @nss_ratio: nss ratio is used to calculate the NSS value for 160MHz. */ struct wlan_psoc_host_mac_phy_caps { uint32_t hw_mode_id; @@ -198,6 +220,10 @@ struct wlan_psoc_host_mac_phy_caps { struct wlan_psoc_host_ppe_threshold he_ppet5G; uint32_t chainmask_table_id; uint32_t lmac_id; + struct wlan_psoc_host_hal_reg_cap_ext reg_cap_ext; + uint32_t tgt_pdev_id; + bool nss_ratio_enabled; + uint8_t nss_ratio_info; }; /** @@ -255,6 +281,9 @@ struct wlan_psoc_host_spectral_scaling_params { * @supports_chan_width_80: channel width 80 support for this chain mask. * @supports_chan_width_160: channel width 160 support for this chain mask. * @supports_chan_width_80P80: channel width 80P80 support for this chain mask. + * @supports_aSpectral: Agile Spectral support for this chain mask. + * @supports_aSpectral_160: Agile Spectral support in 160 MHz. + * @supports_aDFS_160: Agile DFS support in 160 MHz for this chain mask. * @chain_mask_2G: 2G support for this chain mask. * @chain_mask_5G: 5G support for this chain mask. * @chain_mask_tx: Tx support for this chain mask. @@ -268,7 +297,10 @@ struct wlan_psoc_host_chainmask_capabilities { supports_chan_width_80:1, supports_chan_width_160:1, supports_chan_width_80P80:1, - reserved:22, + supports_aSpectral:1, + supports_aSpectral_160:1, + supports_aDFS_160:1, + reserved:19, chain_mask_2G:1, chain_mask_5G:1, chain_mask_tx:1, @@ -289,20 +321,6 @@ struct wlan_psoc_host_chainmask_table { struct wlan_psoc_host_chainmask_capabilities *cap_list; }; -#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION -/** - * struct wlan_psoc_host_rf_characterization_entry - rf characterization table - * @freq: center frequency of primary channel - * @bw: bandwidth of primary channel - * @chan_metric: primary channel-specific metric - */ -struct wlan_psoc_host_rf_characterization_entry { - uint16_t freq; - wmi_host_channel_width bw; - uint8_t chan_metric; -}; -#endif - /** * struct wlan_psoc_host_service_ext_param - EXT service base params in event * @default_conc_scan_config_bits: Default concurrenct scan config @@ -322,8 +340,6 @@ struct wlan_psoc_host_rf_characterization_entry { * @max_bssid_indicator: Maximum number of VAPs in MBSS IE * @num_bin_scaling_params: Number of Spectral bin scaling parameters * @chainmask_table: Available chain mask tables. - * @num_rf_characterization_entries: Number of RF characterization info entries - * @rf_characterization_entries: Channel RF characterization information entries * @sar_version: SAR version info */ struct wlan_psoc_host_service_ext_param { @@ -342,11 +358,6 @@ struct wlan_psoc_host_service_ext_param { uint32_t num_bin_scaling_params; struct wlan_psoc_host_chainmask_table chainmask_table[PSOC_MAX_CHAINMASK_TABLES]; -#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION - uint32_t num_rf_characterization_entries; - struct wlan_psoc_host_rf_characterization_entry - *rf_characterization_entries; -#endif uint32_t sar_version; }; @@ -356,13 +367,16 @@ struct wlan_psoc_host_service_ext_param { * reg_db_version_minor: REG DB version minor number * bdf_reg_db_version_major: BDF REG DB version major number * bdf_reg_db_version_minor: BDF REG DB version minor number + * @num_dbr_ring_caps: Number of direct buf rx ring capabilities + * @max_ndp_sessions: Max number of ndp session fw supports */ struct wlan_psoc_host_service_ext2_param { uint8_t reg_db_version_major; uint8_t reg_db_version_minor; uint8_t bdf_reg_db_version_major; uint8_t bdf_reg_db_version_minor; - + uint32_t num_dbr_ring_caps; + uint32_t max_ndp_sessions; }; #endif /* _SERVICE_READY_PARAM_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_util.h b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_util.h index dd32a5b217cb7e243ee962a6f9ec23e0ca1ba3af..e78fa79ff6a130c9f756b7e1910551bae4b4b05c 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_util.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/inc/service_ready_util.h @@ -27,50 +27,6 @@ #include "service_ready_param.h" #include "target_if.h" -#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION -/** - * init_deinit_populate_rf_characterization_entries() - * - allocates space for and populates the RF characterization information - * @handle: WMI handle pointer - * @evt: event buffer received from FW - * @service_ext_param: pointer to server ext param - * - * Allocates space for and populates the RF characterization information - * - * Return: QDF Status - */ -QDF_STATUS init_deinit_populate_rf_characterization_entries(void *handle, - uint8_t *evt, - struct wlan_psoc_host_service_ext_param *service_ext_par); - -/** - * init_deinit_rf_characterization_entries_free() - * - free RF characterization information - * @service_ext_param: pointer to server ext param - * - * Frees RF characterization information - * - * Return: QDF Status - */ -QDF_STATUS init_deinit_rf_characterization_entries_free( - struct wlan_psoc_host_service_ext_param *service_ext_par); -#else -static inline -QDF_STATUS init_deinit_populate_rf_characterization_entries(void *handle, - uint8_t *evt, - struct wlan_psoc_host_service_ext_param *ser_ext_par) -{ - return QDF_STATUS_SUCCESS; -} - -static inline -QDF_STATUS init_deinit_rf_characterization_entries_free( - struct wlan_psoc_host_service_ext_param *ser_ext_par) -{ - return QDF_STATUS_SUCCESS; -} -#endif - /** * init_deinit_chainmask_table_alloc() * - allocate chainmask table capability list. @@ -105,8 +61,9 @@ QDF_STATUS init_deinit_chainmask_table_free( * * Return: zero on successful population of service bitmap or failure flag */ -int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event, - uint32_t *service_bitmap); +int init_deinit_populate_service_bitmap( + wmi_unified_t wmi_handle, uint8_t *event, + uint32_t *service_bitmap); /** * init_deinit_populate_fw_version_cmd() - populate FW version @@ -117,7 +74,8 @@ int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event, * * Return: zero on successful population of fw_version command or failure flag */ -int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event); +int +init_deinit_populate_fw_version_cmd(wmi_unified_t wmi_handle, uint8_t *event); /** * init_deinit_populate_target_cap() - populate target cap @@ -129,8 +87,9 @@ int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event); * * Return: zero on successful population of target cap or failure flag */ -int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event, - struct wlan_psoc_target_capability_info *cap); +int init_deinit_populate_target_cap( + wmi_unified_t wmi_handle, uint8_t *event, + struct wlan_psoc_target_capability_info *cap); /** * init_deinit_populate_service_ready_ext_param() - populate service ready ext @@ -143,8 +102,9 @@ int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event, * * Return: zero on successful parsing of service ready ext parameter or failure */ -int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt, - struct wlan_psoc_host_service_ext_param *param); +int init_deinit_populate_service_ready_ext_param( + wmi_unified_t handle, uint8_t *evt, + struct wlan_psoc_host_service_ext_param *param); /** * init_deinit_populate_service_ready_ext2_param() - populate service ready ext2 @@ -158,7 +118,7 @@ int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt, * Return: zero on successful parsing of service ready ext parameter or failure */ int init_deinit_populate_service_ready_ext2_param( - void *handle, uint8_t *evt, + wmi_unified_t handle, uint8_t *evt, struct tgt_info *info); /** @@ -171,7 +131,8 @@ int init_deinit_populate_service_ready_ext2_param( * * Return: zero on successful parsing of chainmaks tables or failure flag */ -int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt, +int init_deinit_populate_chainmask_tables( + wmi_unified_t handle, uint8_t *evt, struct wlan_psoc_host_chainmask_table *param); /** @@ -185,7 +146,8 @@ int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt, * * Return: zero on successful population of mac physical capability or failure */ -int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt, +int init_deinit_populate_mac_phy_capability( + wmi_unified_t handle, uint8_t *evt, struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info); /** @@ -198,7 +160,8 @@ int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt, * * Return: zero on successful parsing of hw mode capability or failure */ -int init_deinit_populate_hw_mode_capability(void *wmi_handle, +int init_deinit_populate_hw_mode_capability( + wmi_unified_t wmi_handle, uint8_t *event, struct target_psoc_info *tgt_hdl); /** @@ -213,8 +176,24 @@ int init_deinit_populate_hw_mode_capability(void *wmi_handle, * Return: zero on successful parsing of dbr ring capability or failure */ int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, - void *handle, uint8_t *event, - struct tgt_info *info); + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info); + +/** + * init_deinit_populate_dbr_ring_cap_ext2() - populate dbr ring capability + * from ext2 event + * @psoc: PSOC object + * @handle: WMI handle pointer + * @event: event buffer received from FW + * @info: tgt_info object + * + * API to populate dbr ring capability + * + * Return: zero on successful parsing of dbr ring capability or failure + */ +int init_deinit_populate_dbr_ring_cap_ext2(struct wlan_objmgr_psoc *psoc, + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info); /** * init_deinit_populate_spectral_bin_scale_params() - populate Spectral scaling @@ -229,7 +208,7 @@ int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, */ int init_deinit_populate_spectral_bin_scale_params( struct wlan_objmgr_psoc *psoc, - void *handle, uint8_t *event, + wmi_unified_t handle, uint8_t *event, struct tgt_info *info); /** @@ -267,8 +246,9 @@ QDF_STATUS init_deinit_spectral_scaling_params_free( * Return: zero on successful parsing of physical reg capability or failure flag */ int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc, - void *wmi_handle, uint8_t *event, - struct tgt_info *info, bool service_ready); + wmi_unified_t wmi_handle, uint8_t *event, + struct tgt_info *info, + bool service_ready); /** * init_deinit_validate_160_80p80_fw_caps() - validate 160 80p80 fw caps diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_cmd_api.c b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_cmd_api.c index ee7db77e2fd46a37a24d31a45b303af594c62da4..ebc0b3b7c8ab2739e8ce0dffb25085908bfd1d45 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_cmd_api.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_cmd_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -182,98 +181,6 @@ static QDF_STATUS init_deinit_alloc_host_mem(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -/** - * init_deinit_alloc_num_units() - allocates num units requested by FW. - * @psoc: PSOC object - * @tgt_hdl: Target PSOC info - * @mem_reqs: pointer to mem req - * @num_units: Number - * @i: FW priority - * @idx: Index - * - * API to allocate num units of host memory requested by FW - * - * Return: QDF_STATUS_SUCCESS on successful allocation - * QDF_STATUS_E_FAILURE on failure - */ -static QDF_STATUS init_deinit_alloc_num_units(struct wlan_objmgr_psoc *psoc, - struct target_psoc_info *tgt_hdl, - host_mem_req *mem_reqs, uint16_t fw_prio, - uint16_t idx) -{ - struct tgt_info *info; - uint32_t num_units; - QDF_STATUS status; - - if (!tgt_hdl || !mem_reqs) { - target_if_err("Invalid parameters, tgt_hdl: %pK, mem_reqs: %pK", - tgt_hdl, mem_reqs); - return QDF_STATUS_E_INVAL; - } - - info = (&tgt_hdl->info); - - if (((fw_prio == FW_MEM_HIGH_PRIORITY) && - (mem_reqs[idx].num_unit_info & - HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)) || - ((fw_prio == FW_MEM_LOW_PRIORITY) && - (!(mem_reqs[idx].num_unit_info & - HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)))) { - /* First allocate the memory that requires contiguous memory */ - num_units = mem_reqs[idx].num_units; - if (mem_reqs[idx].num_unit_info) { - if (mem_reqs[idx].num_unit_info & - NUM_UNITS_IS_NUM_PEERS) { - /* - * number of units allocated is equal to number - * of peers, 1 extra for self peer on target. - * this needs to be fixed, host and target can - * get out of sync - */ - num_units = info->wlan_res_cfg.num_peers + 1; - } - if (mem_reqs[idx].num_unit_info & - NUM_UNITS_IS_NUM_ACTIVE_PEERS) { - /* - * Requesting allocation of memory using - * num_active_peers in qcache. if qcache is - * disabled in host, then it should allocate - * memory for num_peers instead of - * num_active_peers. - */ - if (info->wlan_res_cfg.num_active_peers) - num_units = - info->wlan_res_cfg.num_active_peers + 1; - else - num_units = - info->wlan_res_cfg.num_peers + 1; - } - } - - target_if_debug("idx %d req %d num_units %d num_unit_info %d unit size %d actual units %d", - idx, mem_reqs[idx].req_id, - mem_reqs[idx].num_units, - mem_reqs[idx].num_unit_info, - mem_reqs[idx].unit_size, num_units); - - status = init_deinit_alloc_host_mem(psoc, tgt_hdl, - mem_reqs[idx].req_id, num_units, - mem_reqs[idx].unit_size, - mem_reqs[idx].num_unit_info); - if (status == QDF_STATUS_E_FAILURE) { - target_if_err( - "psoc:(%pK) num_mem_chunk exceeds supp number", - psoc); - return QDF_STATUS_E_FAILURE; - } else if (status == QDF_STATUS_E_NOMEM) { - target_if_err("soc:(%pK) mem alloc failure", psoc); - return QDF_STATUS_E_NOMEM; - } - } - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, struct target_psoc_info *tgt_hdl) { @@ -300,12 +207,12 @@ QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, info = (&tgt_hdl->info); for (idx = 0; idx < info->num_mem_chunks; idx++) { qdf_mem_free_consistent( - qdf_dev, qdf_dev->dev, - info->mem_chunks[idx].len, - info->mem_chunks[idx].vaddr, - info->mem_chunks[idx].paddr, - qdf_get_dma_mem_context( - (&(info->mem_chunks[idx])), memctx)); + qdf_dev, qdf_dev->dev, + info->mem_chunks[idx].len, + info->mem_chunks[idx].vaddr, + info->mem_chunks[idx].paddr, + qdf_get_dma_mem_context( + (&info->mem_chunks[idx]), memctx)); info->mem_chunks[idx].vaddr = NULL; info->mem_chunks[idx].paddr = 0; @@ -319,15 +226,15 @@ QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, } QDF_STATUS init_deinit_handle_host_mem_req( - struct wlan_objmgr_psoc *psoc, - struct target_psoc_info *tgt_hdl, uint8_t *event) + struct wlan_objmgr_psoc *psoc, + struct target_psoc_info *tgt_hdl, uint8_t *event) { - uint8_t num_mem_reqs; - host_mem_req *mem_reqs; + uint32_t num_mem_reqs; + host_mem_req mem_reqs; uint32_t i; uint32_t idx; QDF_STATUS status = QDF_STATUS_SUCCESS; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; struct tgt_info *info; if (!tgt_hdl) { @@ -338,21 +245,38 @@ QDF_STATUS init_deinit_handle_host_mem_req( wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); info = (&tgt_hdl->info); - mem_reqs = wmi_extract_host_mem_req_from_service_ready( - wmi_handle, event, &num_mem_reqs); + num_mem_reqs = wmi_extract_num_mem_reqs_from_service_ready( + wmi_handle, event); if (!num_mem_reqs) return QDF_STATUS_SUCCESS; if (num_mem_reqs > MAX_MEM_CHUNKS) { target_if_err_rl("num_mem_reqs:%u is out of bounds", - num_mem_reqs); + num_mem_reqs); return QDF_STATUS_E_FAILURE; } - for (i = 0; i < FW_PRIORITY_MAX; i++) { + for (i = 0; i < WMI_FW_PRIORITY_MAX; i++) { for (idx = 0; idx < num_mem_reqs; idx++) { - status = init_deinit_alloc_num_units(psoc, tgt_hdl, - mem_reqs, i, idx); + status = wmi_extract_host_mem_req_from_service_ready( + wmi_handle, event, &mem_reqs, + info->wlan_res_cfg.num_active_peers, + info->wlan_res_cfg.num_peers, i, idx); + if (mem_reqs.tgt_num_units) { + status = init_deinit_alloc_host_mem( + psoc, + tgt_hdl, + mem_reqs.req_id, + mem_reqs.tgt_num_units, + mem_reqs.unit_size, + mem_reqs.num_unit_info); + if (status == QDF_STATUS_E_FAILURE) { + target_if_err("num_mem_chunk exceeds supp number"); + } else if (status == QDF_STATUS_E_NOMEM) { + target_if_err("mem alloc failure"); + } + } + if (status != QDF_STATUS_SUCCESS) return status; } @@ -384,8 +308,12 @@ void init_deinit_derive_band_to_mac_param( return; } + mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + if (!mac_phy_cap) { + target_if_err("mac_phy_cap is NULL"); + return; + } for (i = 0; i < target_psoc_get_num_radios(tgt_hdl); i++) { - mac_phy_cap = &info->mac_phy_cap[i]; if (mac_phy_cap->supported_bands == (WMI_HOST_WLAN_5G_CAPABILITY | WMI_HOST_WLAN_2G_CAPABILITY)) { @@ -409,9 +337,9 @@ void init_deinit_derive_band_to_mac_param( reg_cap[mac_phy_cap->phy_id].high_5ghz_chan = 0; target_if_debug("2G radio - pdev_id = %d start_freq = %d end_freq= %d", - band_to_mac[i].pdev_id, - band_to_mac[i].start_freq, - band_to_mac[i].end_freq); + band_to_mac[i].pdev_id, + band_to_mac[i].start_freq, + band_to_mac[i].end_freq); } else if (mac_phy_cap->supported_bands == WMI_HOST_WLAN_5G_CAPABILITY) { @@ -425,10 +353,11 @@ void init_deinit_derive_band_to_mac_param( reg_cap[mac_phy_cap->phy_id].high_2ghz_chan = 0; target_if_debug("5G radio -pdev_id = %d start_freq = %d end_freq =%d\n", - band_to_mac[i].pdev_id, - band_to_mac[i].start_freq, - band_to_mac[i].end_freq); + band_to_mac[i].pdev_id, + band_to_mac[i].start_freq, + band_to_mac[i].end_freq); } + mac_phy_cap++; } } @@ -438,7 +367,7 @@ void init_deinit_prepare_send_init_cmd( { struct wmi_init_cmd_param init_param = {0}; struct tgt_info *info; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; QDF_STATUS ret_val; if (!tgt_hdl) { @@ -483,6 +412,10 @@ void init_deinit_prepare_send_init_cmd( if (ret_val != QDF_STATUS_SUCCESS) return; + info->wlan_res_cfg.max_ndp_sessions = + QDF_MIN(info->wlan_res_cfg.max_ndp_sessions, + info->service_ext2_param.max_ndp_sessions); + target_if_debug("FW version 0x%x ", info->target_caps.fw_version); if (init_deinit_is_service_ext_msg(psoc, tgt_hdl) == QDF_STATUS_SUCCESS) target_if_debug("0x%x\n", diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_deinit_lmac.c b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_deinit_lmac.c index 282934ac231c6ed3e38a9f79b73a6516f46a8c5d..4da2a989350f1d144f35412dd972ae4d466ef9b3 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_deinit_lmac.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_deinit_lmac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,20 +68,12 @@ target_resource_config *lmac_get_tgt_res_cfg(struct wlan_objmgr_psoc *psoc) int32_t lmac_get_pdev_idx(struct wlan_objmgr_pdev *pdev) { - struct target_pdev_info *tgt_hdl; - if (!pdev) { target_if_err("pdev is null"); return 0xffffffff; } - tgt_hdl = wlan_pdev_get_tgt_if_handle(pdev); - if (!tgt_hdl) { - target_if_err("target_pdev_info is null"); - return 0xffffffff; - } - - return target_pdev_get_pdev_idx(tgt_hdl); + return wlan_objmgr_pdev_get_pdev_id(pdev); } uint32_t lmac_get_tgt_type(struct wlan_objmgr_psoc *psoc) @@ -187,7 +179,7 @@ bool lmac_is_target_ar900b(struct wlan_objmgr_psoc *psoc) } qdf_export_symbol(lmac_is_target_ar900b); -struct common_wmi_handle *lmac_get_wmi_hdl(struct wlan_objmgr_psoc *psoc) +struct wmi_unified *lmac_get_wmi_hdl(struct wlan_objmgr_psoc *psoc) { struct target_psoc_info *tgt_hdl; @@ -212,7 +204,7 @@ wmi_unified_t lmac_get_wmi_unified_hdl(struct wlan_objmgr_psoc *psoc) } qdf_export_symbol(lmac_get_wmi_unified_hdl); -struct common_htc_handle *lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc) +HTC_HANDLE lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc) { struct target_psoc_info *tgt_hdl; @@ -232,7 +224,7 @@ struct common_htc_handle *lmac_get_htc_hdl(struct wlan_objmgr_psoc *psoc) qdf_export_symbol(lmac_get_htc_hdl); void lmac_set_htc_hdl(struct wlan_objmgr_psoc *psoc, - struct common_htc_handle *htc_hdl) + HTC_HANDLE htc_hdl) { struct target_psoc_info *tgt_hdl; @@ -240,7 +232,7 @@ void lmac_set_htc_hdl(struct wlan_objmgr_psoc *psoc, target_if_err("psoc is null"); return; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info is null"); return; @@ -249,7 +241,7 @@ void lmac_set_htc_hdl(struct wlan_objmgr_psoc *psoc, target_psoc_set_htc_hdl(tgt_hdl, htc_hdl); } -struct common_hif_handle *lmac_get_hif_hdl(struct wlan_objmgr_psoc *psoc) +struct hif_opaque_softc *lmac_get_hif_hdl(struct wlan_objmgr_psoc *psoc) { struct target_psoc_info *tgt_hdl; @@ -274,7 +266,7 @@ struct hif_opaque_softc *lmac_get_ol_hif_hdl(struct wlan_objmgr_psoc *psoc) } qdf_export_symbol(lmac_get_ol_hif_hdl); -struct common_wmi_handle *lmac_get_pdev_wmi_handle( +struct wmi_unified *lmac_get_pdev_wmi_handle( struct wlan_objmgr_pdev *pdev) { struct target_pdev_info *tgt_hdl; diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_event_handler.c b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_event_handler.c index cad714de81a9358023f89fca4c1419da130ea804..5868c1a84d05a1e137cacffc3a6f92242a45deae 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_event_handler.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/init_event_handler.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,7 +49,7 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, struct wlan_objmgr_psoc *psoc; struct target_psoc_info *tgt_hdl; wmi_legacy_service_ready_callback legacy_callback; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; QDF_STATUS ret_val; if (!scn_handle) { @@ -63,8 +63,7 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, return -EINVAL; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( - psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info is null in service ready ev"); return -EINVAL; @@ -124,6 +123,18 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, if (wmi_service_enabled(wmi_handle, wmi_service_infra_mbssid)) wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_MBSS_IE); + if (wmi_service_enabled(wmi_handle, wmi_service_dynamic_hw_mode)) + wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_DYNAMIC_HW_MODE); + + if (wmi_service_enabled(wmi_handle, wmi_service_bw_165mhz_support)) + wlan_psoc_nif_fw_ext_cap_set(psoc, + WLAN_SOC_RESTRICTED_80P80_SUPPORT); + + if (wmi_service_enabled(wmi_handle, + wmi_service_nss_ratio_to_host_support)) + wlan_psoc_nif_fw_ext_cap_set( + psoc, WLAN_SOC_NSS_RATIO_TO_HOST_SUPPORT); + target_if_debug(" TT support %d, Wide BW Scan %d, SW cal %d", wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_TT_SUPPORT), wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_WIDEBAND_SCAN), @@ -146,6 +157,10 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, target_if_lteu_cfg_enable(psoc, tgt_hdl, event); + if (wmi_service_enabled(wmi_handle, wmi_service_rx_fse_support)) + wlan_psoc_nif_fw_ext_cap_set(psoc, + WLAN_SOC_CEXT_RX_FSE_SUPPORT); + /* override derived value, if it exceeds max peer count */ if ((wlan_psoc_get_max_peer_count(psoc) > tgt_hdl->info.wlan_res_cfg.num_active_peers) && @@ -201,7 +216,7 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle, int err_code = 0; struct wlan_objmgr_psoc *psoc; struct target_psoc_info *tgt_hdl; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; struct tgt_info *info; if (!scn_handle) { @@ -229,6 +244,15 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle, if (err_code) goto exit; + /* dbr_ring_caps could have already come as part of EXT event */ + if (info->service_ext2_param.num_dbr_ring_caps) { + err_code = init_deinit_populate_dbr_ring_cap_ext2(psoc, + wmi_handle, + event, info); + if (err_code) + goto exit; + } + /* send init command */ init_deinit_set_send_init_cmd(psoc, tgt_hdl); @@ -241,9 +265,10 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, uint32_t data_len) { int err_code; + uint8_t num_radios; struct wlan_objmgr_psoc *psoc; struct target_psoc_info *tgt_hdl; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; struct tgt_info *info; wmi_legacy_service_ready_callback legacy_callback; @@ -258,8 +283,7 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, return -EINVAL; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( - psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info is null in service ready ev"); return -EINVAL; @@ -286,20 +310,11 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, return -EINVAL; } - if (info->preferred_hw_mode != WMI_HOST_HW_MODE_MAX) { - struct wlan_psoc_host_hw_mode_caps *hw_cap = &info->hw_mode_cap; - /* prune info mac_phy cap to preferred/selected mode caps */ - info->total_mac_phy_cnt = 0; - err_code = init_deinit_populate_mac_phy_capability(wmi_handle, - event, - hw_cap, - info); - if (err_code) - goto exit; + num_radios = target_psoc_get_num_radios_for_mode(tgt_hdl, + info->preferred_hw_mode); - info->num_radios = info->total_mac_phy_cnt; - target_if_debug("num radios is %d\n", info->num_radios); - } + /* set number of radios based on current mode */ + target_psoc_set_num_radios(tgt_hdl, num_radios); target_if_print_service_ready_ext_param(psoc, tgt_hdl); @@ -320,17 +335,13 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, goto exit; } - err_code = init_deinit_populate_rf_characterization_entries( - wmi_handle, - event, - &info->service_ext_param); - if (err_code) - goto exit; - - err_code = init_deinit_populate_dbr_ring_cap(psoc, wmi_handle, - event, info); - if (err_code) - goto exit; + /* dbr_ring_caps can be absent if enough space is not available */ + if (info->service_ext_param.num_dbr_ring_caps) { + err_code = init_deinit_populate_dbr_ring_cap(psoc, wmi_handle, + event, info); + if (err_code) + goto exit; + } err_code = init_deinit_populate_spectral_bin_scale_params(psoc, wmi_handle, @@ -347,11 +358,6 @@ static int init_deinit_service_ext_ready_event_handler(ol_scn_t scn_handle, target_if_set_twt_ap_pdev_count(info, tgt_hdl); - info->wlan_res_cfg.num_vdevs = (target_psoc_get_num_radios(tgt_hdl) * - info->wlan_res_cfg.num_vdevs); - info->wlan_res_cfg.beacon_tx_offload_max_vdev = - (target_psoc_get_num_radios(tgt_hdl) * - info->wlan_res_cfg.beacon_tx_offload_max_vdev); info->wlan_res_cfg.max_bssid_indicator = info->service_ext_param.max_bssid_indicator; @@ -372,7 +378,7 @@ static int init_deinit_service_available_handler(ol_scn_t scn_handle, { struct wlan_objmgr_psoc *psoc; struct target_psoc_info *tgt_hdl; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; if (!scn_handle) { target_if_err("scn handle NULL"); @@ -385,8 +391,7 @@ static int init_deinit_service_available_handler(ol_scn_t scn_handle, return -EINVAL; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( - psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info is null"); return -EINVAL; @@ -413,7 +418,7 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle, struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_pdev *pdev; struct target_psoc_info *tgt_hdl; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; struct wmi_host_fw_abi_ver fw_ver; uint8_t myaddr[QDF_MAC_ADDR_SIZE]; struct tgt_info *info; @@ -435,8 +440,7 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle, return -EINVAL; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( - psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info is null"); return -EINVAL; @@ -467,8 +471,26 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle, else info->wlan_res_cfg.agile_capability = ready_ev.agile_capability; + /* Indicate to the waiting thread that the ready + * event was received + */ + info->wlan_init_status = wmi_ready_extract_init_status( + wmi_handle, event); + + legacy_callback = target_if_get_psoc_legacy_service_ready_cb(); + if (legacy_callback) + if (legacy_callback(wmi_ready_event_id, + scn_handle, event, data_len)) { + target_if_err("Legacy callback returned error!"); + tgt_hdl->info.wmi_ready = FALSE; + goto exit; + } + + num_radios = target_psoc_get_num_radios(tgt_hdl); + if ((ready_ev.num_total_peer != 0) && (info->wlan_res_cfg.num_peers != ready_ev.num_total_peer)) { + uint16_t num_peers = 0; /* FW allocated number of peers is different than host * requested. Update host max with FW reported value. */ @@ -476,6 +498,22 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle, info->wlan_res_cfg.num_peers, ready_ev.num_total_peer); info->wlan_res_cfg.num_peers = ready_ev.num_total_peer; + num_peers = info->wlan_res_cfg.num_peers / num_radios; + + for (i = 0; i < num_radios; i++) { + pdev = wlan_objmgr_get_pdev_by_id(psoc, i, + WLAN_INIT_DEINIT_ID); + if (!pdev) { + target_if_err(" PDEV %d is NULL", i); + return -EINVAL; + } + + wlan_pdev_set_max_peer_count(pdev, num_peers); + wlan_objmgr_pdev_release_ref(pdev, WLAN_INIT_DEINIT_ID); + } + + wlan_psoc_set_max_peer_count(psoc, + info->wlan_res_cfg.num_peers); } /* for non legacy num_total_peer will be non zero @@ -495,22 +533,22 @@ static int init_deinit_ready_event_handler(ol_scn_t scn_handle, } } - /* Indicate to the waiting thread that the ready - * event was received - */ - info->wlan_init_status = wmi_ready_extract_init_status( - wmi_handle, event); - legacy_callback = target_if_get_psoc_legacy_service_ready_cb(); - if (legacy_callback) - if (legacy_callback(wmi_ready_event_id, - scn_handle, event, data_len)) { - target_if_err("Legacy callback returned error!"); - tgt_hdl->info.wmi_ready = FALSE; - goto exit; + if (ready_ev.pktlog_defs_checksum) { + for (i = 0; i < num_radios; i++) { + pdev = wlan_objmgr_get_pdev_by_id(psoc, i, + WLAN_INIT_DEINIT_ID); + if (!pdev) { + target_if_err(" PDEV %d is NULL", i); + return -EINVAL; + } + target_if_set_pktlog_checksum(pdev, tgt_hdl, + ready_ev. + pktlog_defs_checksum); + wlan_objmgr_pdev_release_ref(pdev, WLAN_INIT_DEINIT_ID); } + } - num_radios = target_psoc_get_num_radios(tgt_hdl); /* * For non-legacy HW, MAC addr list is extracted. */ @@ -587,8 +625,7 @@ QDF_STATUS init_deinit_register_tgt_psoc_ev_handlers( return QDF_STATUS_E_FAILURE; } - tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( - psoc); + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); if (!tgt_hdl) { target_if_err("target_psoc_info null in register wmi hadler"); return QDF_STATUS_E_FAILURE; diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c index 0a6b4534b4859715c7e1e372cc476a7ab78047d8..21bc668947b8dbfaf7f43256c2715f28236aa2a8 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c @@ -26,51 +26,6 @@ #include #include -#ifdef WLAN_SUPPORT_RF_CHARACTERIZATION -QDF_STATUS init_deinit_populate_rf_characterization_entries(void *handle, - uint8_t *evt, - struct wlan_psoc_host_service_ext_param *ser_ext_par) -{ - uint32_t alloc_size; - QDF_STATUS status = QDF_STATUS_SUCCESS; - - if (ser_ext_par->num_rf_characterization_entries == 0) - return QDF_STATUS_SUCCESS; - - alloc_size = (sizeof(struct wlan_psoc_host_rf_characterization_entry) * - ser_ext_par->num_rf_characterization_entries); - - ser_ext_par->rf_characterization_entries = qdf_mem_malloc(alloc_size); - if (!ser_ext_par->rf_characterization_entries) { - init_deinit_rf_characterization_entries_free(ser_ext_par); - return QDF_STATUS_E_NOMEM; - } - - status = wmi_extract_rf_characterization_entries(handle, evt, - ser_ext_par->rf_characterization_entries); - if (QDF_IS_STATUS_ERROR(status)) { - target_if_err("failed to parse wmi service ready ext param"); - init_deinit_rf_characterization_entries_free(ser_ext_par); - } - - return status; -} - -qdf_export_symbol(init_deinit_populate_rf_characterization_entries); - -QDF_STATUS init_deinit_rf_characterization_entries_free( - struct wlan_psoc_host_service_ext_param *ser_ext_par) -{ - qdf_mem_free(ser_ext_par->rf_characterization_entries); - ser_ext_par->rf_characterization_entries = NULL; - ser_ext_par->num_rf_characterization_entries = 0; - - return QDF_STATUS_SUCCESS; -} - -qdf_export_symbol(init_deinit_rf_characterization_entries_free); -#endif - QDF_STATUS init_deinit_chainmask_table_alloc( struct wlan_psoc_host_service_ext_param *ser_ext_par) { @@ -128,8 +83,9 @@ QDF_STATUS init_deinit_chainmask_table_free( qdf_export_symbol(init_deinit_chainmask_table_free); -int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event, - uint32_t *service_bitmap) +int init_deinit_populate_service_bitmap( + wmi_unified_t wmi_handle, uint8_t *event, + uint32_t *service_bitmap) { QDF_STATUS status; @@ -142,7 +98,8 @@ int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event, return 0; } -int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event) +int init_deinit_populate_fw_version_cmd(wmi_unified_t wmi_handle, + uint8_t *event) { QDF_STATUS status; @@ -153,8 +110,9 @@ int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event) return 0; } -int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event, - struct wlan_psoc_target_capability_info *cap) +int init_deinit_populate_target_cap( + wmi_unified_t wmi_handle, uint8_t *event, + struct wlan_psoc_target_capability_info *cap) { QDF_STATUS status; @@ -167,8 +125,9 @@ int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event, return 0; } -int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt, - struct wlan_psoc_host_service_ext_param *param) +int init_deinit_populate_service_ready_ext_param( + wmi_unified_t handle, uint8_t *evt, + struct wlan_psoc_host_service_ext_param *param) { QDF_STATUS status; @@ -182,7 +141,7 @@ int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt, } int init_deinit_populate_service_ready_ext2_param( - void *handle, uint8_t *evt, + wmi_unified_t handle, uint8_t *evt, struct tgt_info *info) { QDF_STATUS status; @@ -197,7 +156,8 @@ int init_deinit_populate_service_ready_ext2_param( return 0; } -int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt, +int init_deinit_populate_chainmask_tables( + wmi_unified_t handle, uint8_t *evt, struct wlan_psoc_host_chainmask_table *param) { QDF_STATUS status; @@ -211,7 +171,8 @@ int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt, return 0; } -int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt, +int init_deinit_populate_mac_phy_capability( + wmi_unified_t handle, uint8_t *evt, struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info) { QDF_STATUS status; @@ -250,8 +211,8 @@ int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt, return 0; } -static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx, - struct wlan_psoc_host_hw_mode_caps *cap) +static int get_hw_mode(wmi_unified_t handle, uint8_t *evt, uint8_t hw_idx, + struct wlan_psoc_host_hw_mode_caps *cap) { QDF_STATUS status; @@ -265,7 +226,7 @@ static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx, return 0; } -static int get_sar_version(void *handle, uint8_t *evt, +static int get_sar_version(wmi_unified_t handle, uint8_t *evt, struct wlan_psoc_host_service_ext_param *ext_param) { QDF_STATUS status; @@ -349,8 +310,9 @@ select_preferred_hw_mode(struct target_psoc_info *tgt_hdl, return selected_mode; } -int init_deinit_populate_hw_mode_capability(void *wmi_handle, - uint8_t *event, struct target_psoc_info *tgt_hdl) +int init_deinit_populate_hw_mode_capability( + wmi_unified_t wmi_handle, uint8_t *event, + struct target_psoc_info *tgt_hdl) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t hw_idx; @@ -408,7 +370,8 @@ int init_deinit_populate_hw_mode_capability(void *wmi_handle, } int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, - void *handle, uint8_t *event, struct tgt_info *info) + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info) { uint8_t cap_idx; @@ -416,7 +379,6 @@ int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, QDF_STATUS status = QDF_STATUS_SUCCESS; num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps; - target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps); if (!num_dbr_ring_caps) @@ -448,8 +410,62 @@ int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc, return qdf_status_to_os_return(status); } +int init_deinit_populate_dbr_ring_cap_ext2(struct wlan_objmgr_psoc *psoc, + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info) + +{ + uint8_t cap_idx; + uint32_t num_dbr_ring_caps; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_psoc_host_dbr_ring_caps *param; + + /* + * If FW had already sent this info as part of EXT event, + * we need to discard the same and use the info from EXT2. + */ + if (info->service_ext_param.num_dbr_ring_caps) { + target_if_debug("dbr_ring_caps already populated"); + info->service_ext_param.num_dbr_ring_caps = 0; + qdf_mem_free(info->dbr_ring_cap); + info->dbr_ring_cap = NULL; + } + + num_dbr_ring_caps = info->service_ext2_param.num_dbr_ring_caps; + target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps); + + if (!num_dbr_ring_caps) + return 0; + + info->dbr_ring_cap = qdf_mem_malloc( + sizeof(struct wlan_psoc_host_dbr_ring_caps) * + num_dbr_ring_caps); + + if (!info->dbr_ring_cap) + return -EINVAL; + + for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { + param = &info->dbr_ring_cap[cap_idx]; + status = wmi_extract_dbr_ring_cap_service_ready_ext2(handle, + event, + cap_idx, + param); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("Extraction of DMA cap failed"); + goto free_and_return; + } + } + + return 0; + +free_and_return: + qdf_mem_free(info->dbr_ring_cap); + info->dbr_ring_cap = NULL; + + return qdf_status_to_os_return(status); +} int init_deinit_populate_spectral_bin_scale_params( - struct wlan_objmgr_psoc *psoc, void *handle, + struct wlan_objmgr_psoc *psoc, wmi_unified_t handle, uint8_t *event, struct tgt_info *info) { @@ -521,9 +537,70 @@ QDF_STATUS init_deinit_spectral_scaling_params_free( qdf_export_symbol(init_deinit_spectral_scaling_params_free); +#ifdef DBS_SBS_BAND_LIMITATION_WAR +#define phy0 0 +#define phy2 2 +#define NUM_RF_MODES 2 /* (DBS + DBS_SBS) */ +/** + * init_deinit_update_phy_reg_cap() - Update the low/high frequency for phy0. + * @psoc: PSOC common object + * @info: FW or lower layer related info + * @wlan_psoc_host_hal_reg_capabilities_ext: Reg caps per PHY + * + * For the DBS_SBS capable board, update the low or high frequency + * for phy0 by leveraging the frequency populated for phy2 + * depending on whether it is mapped to upper or lower 5G band by + * FW/HAL-PHY. + */ +static void init_deinit_update_phy_reg_cap(struct wlan_objmgr_psoc *psoc, + struct tgt_info *info, + struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap) +{ + struct target_psoc_info *tgt_hdl; + enum wmi_host_hw_mode_config_type mode; + uint32_t num_hw_modes; + uint8_t idx; + + tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle( + psoc); + if (!tgt_hdl) { + target_if_err("target_psoc_info is null in service ready ev"); + return; + } + + mode = target_psoc_get_preferred_hw_mode(tgt_hdl); + + num_hw_modes = info->hw_modes.num_modes; + + if ((mode != WMI_HOST_HW_MODE_DBS) || (num_hw_modes < NUM_RF_MODES)) + return; + + for (idx = 0; idx < num_hw_modes; idx++) + if (info->hw_modes.hw_mode_ids[idx] == + WMI_HOST_HW_MODE_DBS_SBS) { + if (reg_cap[phy0].low_5ghz_chan > + reg_cap[phy2].low_5ghz_chan) + reg_cap[phy0].low_5ghz_chan = + reg_cap[phy2].low_5ghz_chan; + else if (reg_cap[phy0].high_5ghz_chan < + reg_cap[phy2].high_5ghz_chan) + reg_cap[phy0].high_5ghz_chan = + reg_cap[phy2].high_5ghz_chan; + break; + } +} +#else +static void init_deinit_update_phy_reg_cap(struct wlan_objmgr_psoc *psoc, + struct tgt_info *info, + struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap) +{ +} +#endif + int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc, - void *handle, uint8_t *event, - struct tgt_info *info, bool service_ready) + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info, + bool service_ready) { uint8_t reg_idx; uint32_t num_phy_reg_cap; @@ -564,6 +641,7 @@ int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc, } } + init_deinit_update_phy_reg_cap(psoc, info, reg_cap); status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap); return qdf_status_to_os_return(status); @@ -609,7 +687,7 @@ QDF_STATUS init_deinit_validate_160_80p80_fw_caps( bool vhtcap_160mhz_sgi = false; bool valid = false; struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; if (!tgt_hdl) { target_if_err( @@ -724,7 +802,7 @@ QDF_STATUS init_deinit_is_service_ext_msg( struct wlan_objmgr_psoc *psoc, struct target_psoc_info *tgt_hdl) { - struct common_wmi_handle *wmi_handle; + struct wmi_unified *wmi_handle; if (!tgt_hdl) { target_if_err( @@ -758,6 +836,15 @@ bool init_deinit_is_preferred_hw_mode_supported( if (info->preferred_hw_mode == WMI_HOST_HW_MODE_MAX) return TRUE; + if (wlan_psoc_nif_feat_cap_get(psoc, WLAN_SOC_F_DYNAMIC_HW_MODE)) { + if (!wlan_psoc_nif_fw_ext_cap_get(psoc, + WLAN_SOC_CEXT_DYNAMIC_HW_MODE)) { + target_if_err( + "WMI service bit for DYNAMIC HW mode is not set!"); + return FALSE; + } + } + for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) { if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode) return TRUE; diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_timer_tx_ops.h b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_timer_tx_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..ad781db7fb60fd90a152db1f52ce527df8a7cb30 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_timer_tx_ops.h @@ -0,0 +1,94 @@ + +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: target_if_psoc_timer_tx_ops.h + * + * This file provide declaration for APIs registered through lmac Tx Ops + */ + +#ifndef __TARGET_IF_PSOC_TIMER_TX_OPS_H__ +#define __TARGET_IF_PSOC_TIMER_TX_OPS_H__ + +/** + * target_if_psoc_vdev_rsp_timer_inuse() - API to check if the response timer + * for vdev is inuse + * @psoc: Psoc object + * @vdev_id: Vdev object id + * + * Return: QDF_STATUS_E_ALREADY in case the timer is inuse or QDF_STATUS_SUCCESS + */ +QDF_STATUS target_if_psoc_vdev_rsp_timer_inuse(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + +/** + * target_if_flush_psoc_vdev_timers() - API to flush target_if response timers + * for vdev + * @psoc: pointer to psoc object + * + * This API is used to flush target_if response timer. This API used while + * wlan driver shutdown. + * + * Return: none + */ +void target_if_flush_psoc_vdev_timers(struct wlan_objmgr_psoc *psoc); + +/** + * target_if_psoc_vdev_rsp_timer_init() - API to initialize response timers for + * vdev from psoc + * @psoc: pointer to psoc object + * @vdev_id: vdev id for which response timer to be retrieved + * + * This API is used to initialize vdev response timer for vdev-id. + * + * Return: QDF_STATUS + */ +QDF_STATUS target_if_psoc_vdev_rsp_timer_init(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + +/** + * target_if_psoc_vdev_rsp_timer_deinit() - API to de-initialize response timers + * for vdev from psoc + * @psoc: pointer to psoc object + * @vdev_id: vdev id for which response timer to be retrieved + * + * This API is used to de-initialize vdev response timer from vdev-id. + * + * Return: none + */ +void target_if_psoc_vdev_rsp_timer_deinit(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + +/** + * target_if_vdev_mgr_rsp_timer_mod() - API to modify time of response timers + * for vdev from psoc + * @psoc: pointer to psoc object + * @vdev_id: vdev id for which response timer to be retrieved + * @mseconds: milli seconds + * + * This API is used to modify vdev response timer for vdev-id. + * + * Return: none + */ +QDF_STATUS target_if_vdev_mgr_rsp_timer_mod( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + int mseconds); + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h new file mode 100644 index 0000000000000000000000000000000000000000..7451dd5cb5646a0d686b3296c493141151d7e9d2 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/inc/target_if_psoc_wake_lock.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: target_if_psoc_wake_lock.h + * + * This file provides declaration for wakelock APIs + */ + +#ifndef __TARGET_IF_PSOC_WAKE_LOCK_H__ +#define __TARGET_IF_PSOC_WAKE_LOCK_H__ + +#include +#include + +#ifdef FEATURE_VDEV_RSP_WAKELOCK +/** + * struct wlan_vdev_wakelock - vdev wake lock sub structure + * @start_wakelock: wakelock for vdev start + * @stop_wakelock: wakelock for vdev stop + * @delete_wakelock: wakelock for vdev delete + * @wmi_cmd_rsp_runtime_lock: run time lock + */ +struct psoc_mlme_wakelock { + qdf_wake_lock_t start_wakelock; + qdf_wake_lock_t stop_wakelock; + qdf_wake_lock_t delete_wakelock; + qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock; +}; +#endif + +enum wakelock_mode { + START_WAKELOCK, + STOP_WAKELOCK, + DELETE_WAKELOCK +}; + +#ifdef FEATURE_VDEV_RSP_WAKELOCK + +/** + * target_if_wake_lock_init() - API to initialize + wakelocks:start, + stop and delete. + * @psoc: pointer to psoc + * + * This also initialize the runtime lock + * + * Return: None + */ +void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc); + +/** + * target_if_wake_lock_deinit() - API to destroy + wakelocks:start, stop and delete. + * @psoc: pointer to psoc + * + * This also destroy the runtime lock + * + * Return: None + */ +void target_if_wake_lock_deinit(struct wlan_objmgr_psoc *psoc); + +/** + * target_if_start_wake_lock_timeout_acquire() - acquire the + vdev start wakelock + * @psoc: pointer to psoc + * + * This also acquires the target_if runtime pm lock. + * + * Return: Success/Failure + */ +QDF_STATUS target_if_wake_lock_timeout_acquire(struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode); +/** + * target_if_start_wake_lock_timeout_release() - release the + start wakelock + * @psoc: pointer to psoc + * + * This also release the target_if runtime pm lock. + * + * Return: Success/Failure + */ +QDF_STATUS target_if_wake_lock_timeout_release(struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode); +#else +static inline void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc) +{ +} + +static inline void target_if_wake_lock_deinit(struct wlan_objmgr_psoc *psoc) +{ +} + +static inline QDF_STATUS target_if_wake_lock_timeout_acquire( + struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS target_if_wake_lock_timeout_release( + struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_timer_tx_ops.c b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_timer_tx_ops.c new file mode 100644 index 0000000000000000000000000000000000000000..7936e1f83415b3c5cb28905ce8a1cee00dab1dac --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_timer_tx_ops.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: target_if_psoc_timer_tx_ops.c + * + * This file provide definition for APIs registered through lmac Tx Ops + */ + +#include +#include +#include +#include +#include +#include + +QDF_STATUS target_if_psoc_vdev_rsp_timer_inuse(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + struct vdev_response_timer *vdev_rsp; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + mlme_err("Invalid vdev id passed VDEV_%d", vdev_id); + return QDF_STATUS_E_INVAL; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response is NULL for VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + if (qdf_atomic_read(&vdev_rsp->rsp_timer_inuse)) { + mlme_err("vdev response timer still inuse VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_ALREADY; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_psoc_vdev_rsp_timer_init(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + struct vdev_response_timer *vdev_rsp; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + mlme_err("Invalid vdev id passed VDEV_%d PSOC_%d", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response is NULL for VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + vdev_rsp->psoc = psoc; + vdev_rsp->vdev_id = vdev_id; + qdf_timer_init(NULL, &vdev_rsp->rsp_timer, + target_if_vdev_mgr_rsp_timer_mgmt_cb, + vdev_rsp, QDF_TIMER_TYPE_WAKE_APPS); + qdf_atomic_init(&vdev_rsp->rsp_timer_inuse); + + return QDF_STATUS_SUCCESS; +} + +void target_if_psoc_vdev_rsp_timer_deinit(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + struct vdev_response_timer *vdev_rsp; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + mlme_err("Invalid vdev id passed VDEV_%d PSOC_%d", vdev_id, + wlan_psoc_get_id(psoc)); + return; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); + return; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response is NULL for VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return; + } + + qdf_timer_free(&vdev_rsp->rsp_timer); + qdf_atomic_set(&vdev_rsp->rsp_timer_inuse, 0); + vdev_rsp->psoc = NULL; +} + +void target_if_flush_psoc_vdev_timers(struct wlan_objmgr_psoc *psoc) +{ + struct vdev_response_timer *vdev_rsp; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + int i; + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("PSOC_%d No Rx Ops", wlan_psoc_get_id(psoc)); + return; + } + + for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++) { + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, + i); + if (vdev_rsp && qdf_timer_sync_cancel(&vdev_rsp->rsp_timer)) + target_if_vdev_mgr_rsp_timer_cb(vdev_rsp); + } +} + +QDF_STATUS target_if_vdev_mgr_rsp_timer_mod( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + int mseconds) +{ + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + struct vdev_response_timer *vdev_rsp; + + if (!psoc) { + mlme_err("Invalid input"); + return QDF_STATUS_E_FAILURE; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_FAILURE; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + qdf_timer_mod(&vdev_rsp->rsp_timer, mseconds); + return QDF_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c new file mode 100644 index 0000000000000000000000000000000000000000..6028911d5a2e38bd7077247fb7ac254c2ff01e1c --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/psoc/src/target_if_psoc_wake_lock.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: target_if_psoc_wake_lock.c + * + * This file provide definition for APIs related to wake lock + */ + +#include "qdf_lock.h" +#include +#include +#include +#include +#include +#include + +void target_if_wake_lock_init(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", wlan_psoc_get_id(psoc)); + return; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + + qdf_wake_lock_create(&psoc_wakelock->start_wakelock, "vdev_start"); + qdf_wake_lock_create(&psoc_wakelock->stop_wakelock, "vdev_stop"); + qdf_wake_lock_create(&psoc_wakelock->delete_wakelock, "vdev_delete"); + + qdf_runtime_lock_init(&psoc_wakelock->wmi_cmd_rsp_runtime_lock); +} + +void target_if_wake_lock_deinit(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", wlan_psoc_get_id(psoc)); + return; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + + qdf_wake_lock_destroy(&psoc_wakelock->start_wakelock); + qdf_wake_lock_destroy(&psoc_wakelock->stop_wakelock); + qdf_wake_lock_destroy(&psoc_wakelock->delete_wakelock); + + qdf_runtime_lock_deinit(&psoc_wakelock->wmi_cmd_rsp_runtime_lock); +} + +QDF_STATUS target_if_wake_lock_timeout_acquire( + struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode) +{ + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops && !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + switch (mode) { + case START_WAKELOCK: + qdf_wake_lock_timeout_acquire(&psoc_wakelock->start_wakelock, + START_RESPONSE_TIMER); + break; + case STOP_WAKELOCK: + qdf_wake_lock_timeout_acquire(&psoc_wakelock->stop_wakelock, + STOP_RESPONSE_TIMER); + break; + case DELETE_WAKELOCK: + qdf_wake_lock_timeout_acquire(&psoc_wakelock->delete_wakelock, + DELETE_RESPONSE_TIMER); + break; + default: + target_if_err("operation mode is invalid"); + return QDF_STATUS_E_FAILURE; + } + + qdf_runtime_pm_prevent_suspend( + &psoc_wakelock->wmi_cmd_rsp_runtime_lock); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_wake_lock_timeout_release( + struct wlan_objmgr_psoc *psoc, + enum wakelock_mode mode) +{ + struct psoc_mlme_wakelock *psoc_wakelock; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_wakelock_info) { + mlme_err("psoc_id:%d No Rx Ops", wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + psoc_wakelock = rx_ops->psoc_get_wakelock_info(psoc); + switch (mode) { + case START_WAKELOCK: + qdf_wake_lock_release(&psoc_wakelock->start_wakelock, + WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP); + break; + case STOP_WAKELOCK: + qdf_wake_lock_release(&psoc_wakelock->stop_wakelock, + WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP); + break; + case DELETE_WAKELOCK: + qdf_wake_lock_release(&psoc_wakelock->delete_wakelock, + WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP); + break; + default: + target_if_err("operation mode is invalid"); + return QDF_STATUS_E_FAILURE; + } + + qdf_runtime_pm_allow_suspend(&psoc_wakelock->wmi_cmd_rsp_runtime_lock); + + return QDF_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_rx_ops.h b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_rx_ops.h index fbfd8f45e0c29bc1040b1276e87c218e3b3886fd..7cda52628d90b9b29e743b9b043e7fea7633adc7 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_rx_ops.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_rx_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,16 +28,68 @@ #include #include #include +#include /** - * target_if_vdev_mgr_is_driver_unloading: API to driver unload status + * target_if_vdev_mgr_is_panic_allowed: API to get if panic is allowed on + * timeout * - * Return: TRUE or FALSE + * Return: TRUE or FALSE when VDEV_ASSERT_MANAGEMENT is disabled else FALSE */ -static inline bool target_if_vdev_mgr_is_driver_unloading(void) +#ifdef VDEV_ASSERT_MANAGEMENT +static inline bool target_if_vdev_mgr_is_panic_allowed(void) { return false; } +#else +static inline bool target_if_vdev_mgr_is_panic_allowed(void) +{ + if (qdf_is_recovering() || qdf_is_fw_down()) + return false; + + return true; +} +#endif + + +/** + * target_if_vdev_mgr_offload_bcn_tx_status_handler() - API to handle beacon + * tx status event + * @scn: pointer to scan object + * @data: pointer to data + * @datalen: length of data + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +int target_if_vdev_mgr_offload_bcn_tx_status_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen); + +/** + * target_if_vdev_mgr_tbttoffset_update_handler() - API to handle tbtt offset + * update event + * @scn: pointer to scan object + * @data: pointer to data + * @datalen: length of data + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +int target_if_vdev_mgr_tbttoffset_update_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen); + +/** + * target_if_vdev_mgr_ext_tbttoffset_update_handler() - API to handle ext tbtt + * offset update event + * @scn: pointer to scan object + * @data: pointer to data + * @datalen: length of data + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +int target_if_vdev_mgr_ext_tbttoffset_update_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen); /** * target_if_vdev_mgr_is_panic_on_bug: API to get panic on bug @@ -96,4 +148,13 @@ QDF_STATUS target_if_vdev_mgr_wmi_event_register( QDF_STATUS target_if_vdev_mgr_wmi_event_unregister( struct wlan_objmgr_psoc *psoc); +/** + * target_if_vdev_mgr_rsp_timer_cb() - function to handle vdev related timeouts + * @vdev_rsp: pointer to vdev response timer + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on error + */ +QDF_STATUS +target_if_vdev_mgr_rsp_timer_cb(struct vdev_response_timer *vdev_rsp); + #endif /* __TARGET_IF_VDEV_MGR_RX_OPS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_tx_ops.h b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_tx_ops.h index e3caf0a23fbb5650cc18e1284695db0abd6cd596..14fd51c639d044e071c008c790a023c86b4f1e58 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_tx_ops.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/inc/target_if_vdev_mgr_tx_ops.h @@ -25,7 +25,6 @@ #ifndef __TARGET_IF_VDEV_MGR_TX_OPS_H__ #define __TARGET_IF_VDEV_MGR_TX_OPS_H__ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include #include #include @@ -62,13 +61,41 @@ target_if_vdev_mgr_get_tx_ops(struct wlan_objmgr_psoc *psoc) QDF_STATUS target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +/** + * target_if_vdev_mgr_assert_mgmt() - vdev assert mgmt api + * @PSOC: pointer to objmgr psoc + * @vdev_id: vdev id + * + * Return: NA + */ +#ifdef VDEV_ASSERT_MANAGEMENT +static inline void target_if_vdev_mgr_assert_mgmt( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ +} #else +static inline void target_if_vdev_mgr_assert_mgmt( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) -static inline QDF_STATUS -target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { - return QDF_STATUS_SUCCESS; + QDF_ASSERT(0); } +#endif + +/** + * target_if_vdev_mgr_rsp_timer_stop() - API to stop response timer for + * vdev manager operations + * @psoc: pointer to psoc object + * @vdev_rsp: vdev response timer + * @clear_bit: enum of wlan_vdev_mgr_tgt_if_rsp_bit + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS target_if_vdev_mgr_rsp_timer_stop( + struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit); -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ #endif /* __TARGET_IF_VDEV_MGR_TX_OPS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c index 8bead4d58f6ccf933f4403d8e80805e1ac97db29..2edff715a23e5dfdd193b18dacb147db7cca3b1b 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,113 +29,225 @@ #include #include #include -#include #include +#include +#include + +static inline +void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum qdf_hang_reason recovery_reason, + uint16_t rsp_pos) +{ + mlme_nofl_err("PSOC_%d VDEV_%d: %s rsp timeout", wlan_psoc_get_id(psoc), + vdev_id, string_from_rsp_bit(rsp_pos)); + if (target_if_vdev_mgr_is_panic_allowed()) + qdf_trigger_self_recovery(psoc, recovery_reason); + else + mlme_nofl_debug("PSOC_%d VDEV_%d: Panic not allowed", + wlan_psoc_get_id(psoc), vdev_id); +} -void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) +QDF_STATUS target_if_vdev_mgr_rsp_timer_cb(struct vdev_response_timer *vdev_rsp) { - struct wlan_objmgr_vdev *vdev = arg; struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_mlme_rx_ops *rx_ops; - struct vdev_response_timer *vdev_rsp; - struct crash_inject param; - struct wmi_unified *wmi_handle; struct vdev_start_response start_rsp = {0}; struct vdev_stop_response stop_rsp = {0}; struct vdev_delete_response del_rsp = {0}; + struct peer_delete_all_response peer_del_all_rsp = {0}; + enum qdf_hang_reason recovery_reason; uint8_t vdev_id; + uint16_t rsp_pos = RESPONSE_BIT_MAX; - vdev_id = wlan_vdev_get_id(vdev); - mlme_debug("Response timer expired for VDEV %d", vdev_id); + if (!vdev_rsp) { + mlme_err("Vdev response timer is NULL"); + return QDF_STATUS_E_FAILURE; + } - psoc = wlan_vdev_get_psoc(vdev); + psoc = vdev_rsp->psoc; if (!psoc) { mlme_err("PSOC is NULL"); - return; + return QDF_STATUS_E_FAILURE; } rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops || !rx_ops->vdev_mgr_get_response_timer_info) { + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { mlme_err("No Rx Ops"); - return; + return QDF_STATUS_E_FAILURE; } - vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) && !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) && !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) && - !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status)) { - mlme_debug("No response bit is set, ignoring actions"); - return; - } - - if (target_if_vdev_mgr_is_driver_unloading() || qdf_is_recovering() || - qdf_is_fw_down()) { - /* this ensures stop timer will not be done in target_if */ - vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT; + !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) && + !qdf_atomic_test_bit( + PEER_DELETE_ALL_RESPONSE_BIT, + &vdev_rsp->rsp_status)) { + mlme_debug("No response bit is set, ignoring actions :%d", + vdev_rsp->vdev_id); + return QDF_STATUS_E_FAILURE; + } + + vdev_id = vdev_rsp->vdev_id; + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_FAILURE; + } + + vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT; + if (qdf_atomic_test_bit(START_RESPONSE_BIT, + &vdev_rsp->rsp_status) || + qdf_atomic_test_bit(RESTART_RESPONSE_BIT, + &vdev_rsp->rsp_status)) { + start_rsp.vdev_id = vdev_id; + start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT; if (qdf_atomic_test_bit(START_RESPONSE_BIT, - &vdev_rsp->rsp_status) || - qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status)) { - start_rsp.vdev_id = wlan_vdev_get_id(vdev); - start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT; - if (qdf_atomic_test_bit(START_RESPONSE_BIT, - &vdev_rsp->rsp_status)) - start_rsp.resp_type = - WMI_HOST_VDEV_START_RESP_EVENT; - else - start_rsp.resp_type = - WMI_HOST_VDEV_RESTART_RESP_EVENT; - - rx_ops->vdev_mgr_start_response(psoc, &start_rsp); + start_rsp.resp_type = + WMI_HOST_VDEV_START_RESP_EVENT; + rsp_pos = START_RESPONSE_BIT; + recovery_reason = QDF_VDEV_START_RESPONSE_TIMED_OUT; + } else { + start_rsp.resp_type = + WMI_HOST_VDEV_RESTART_RESP_EVENT; + rsp_pos = RESTART_RESPONSE_BIT; + recovery_reason = QDF_VDEV_RESTART_RESPONSE_TIMED_OUT; } - if (qdf_atomic_test_bit(STOP_RESPONSE_BIT, - &vdev_rsp->rsp_status)) { - stop_rsp.vdev_id = wlan_vdev_get_id(vdev); - rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp); - } + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); + target_if_vdev_mgr_handle_recovery(psoc, vdev_id, + recovery_reason, rsp_pos); + rx_ops->vdev_mgr_start_response(psoc, &start_rsp); + } else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT, + &vdev_rsp->rsp_status)) { + rsp_pos = STOP_RESPONSE_BIT; + stop_rsp.vdev_id = vdev_id; + recovery_reason = QDF_VDEV_STOP_RESPONSE_TIMED_OUT; + + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); + target_if_vdev_mgr_handle_recovery(psoc, vdev_id, + recovery_reason, rsp_pos); + rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp); + } else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT, + &vdev_rsp->rsp_status)) { + del_rsp.vdev_id = vdev_id; + rsp_pos = DELETE_RESPONSE_BIT; + recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT; + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); + target_if_vdev_mgr_handle_recovery(psoc, vdev_id, + recovery_reason, rsp_pos); + rx_ops->vdev_mgr_delete_response(psoc, &del_rsp); + } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, + &vdev_rsp->rsp_status)) { + peer_del_all_rsp.vdev_id = vdev_id; + rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; + recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); + target_if_vdev_mgr_handle_recovery(psoc, vdev_id, + recovery_reason, rsp_pos); + rx_ops->vdev_mgr_peer_delete_all_response(psoc, + &peer_del_all_rsp); + } else { + mlme_err("PSOC_%d VDEV_%d: Unknown error", + wlan_psoc_get_id(psoc), vdev_id); + return QDF_STATUS_E_FAILURE; + } - if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT, - &vdev_rsp->rsp_status)) { - del_rsp.vdev_id = wlan_vdev_get_id(vdev); - rx_ops->vdev_mgr_delete_response(psoc, &del_rsp); - } + return QDF_STATUS_SUCCESS; +} - return; +#ifdef SERIALIZE_VDEV_RESP +static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg) +{ + struct vdev_response_timer *vdev_rsp; + struct wlan_objmgr_psoc *psoc; + + if (!msg->bodyptr) { + mlme_err("Message bodyptr is NULL"); + return QDF_STATUS_E_INVAL; } - if (target_if_vdev_mgr_is_panic_on_bug()) { - QDF_DEBUG_PANIC("PSOC_%d VDEV_%d: Panic on bug, rsp status:%d", - wlan_psoc_get_id(psoc), - vdev_id, vdev_rsp->rsp_status); - } else { - mlme_err("PSOC_%d VDEV_%d: Trigger Self recovery, rsp status%d", - wlan_psoc_get_id(psoc), - vdev_id, vdev_rsp->rsp_status); - wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); + vdev_rsp = msg->bodyptr; + if (!vdev_rsp) { + mlme_err("vdev response timer is NULL"); + return QDF_STATUS_E_INVAL; + } - qdf_mem_set(¶m, sizeof(param), 0); - /* RECOVERY_SIM_SELF_RECOVERY*/ - param.type = 0x08; - wmi_crash_inject(wmi_handle, ¶m); + psoc = vdev_rsp->psoc; + if (!psoc) { + mlme_err("PSOC is NULL"); + return QDF_STATUS_E_INVAL; } + + if (vdev_rsp->rsp_status) + wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); + + return QDF_STATUS_SUCCESS; } -static int target_if_vdev_mgr_start_response_handler( - ol_scn_t scn, - uint8_t *data, - uint32_t datalen) +static void +target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg) { - QDF_STATUS status; + struct scheduler_msg msg = {0}; + struct vdev_response_timer *vdev_rsp = arg; + struct wlan_objmgr_psoc *psoc; + + psoc = vdev_rsp->psoc; + if (!psoc) { + mlme_err("PSOC is NULL"); + return; + } + + msg.type = SYS_MSG_ID_MC_TIMER; + msg.reserved = SYS_MSG_COOKIE; + msg.callback = target_if_vdev_mgr_rsp_timer_cb; + msg.bodyptr = vdev_rsp; + msg.bodyval = 0; + msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb; + + if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF, + QDF_MODULE_ID_TARGET_IF, + QDF_MODULE_ID_SYS, &msg) == + QDF_STATUS_SUCCESS) + return; + + mlme_err("Could not enqueue timer to timer queue"); + if (psoc) + wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); +} + +void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) +{ + target_if_vdev_mgr_rsp_cb_mc_ctx(arg); +} + +#define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX +#else +void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) +{ + target_if_vdev_mgr_rsp_timer_cb(arg); +} + +#define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX +#endif + +static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen) +{ + QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_psoc *psoc; struct wmi_unified *wmi_handle; struct wlan_lmac_if_mlme_rx_ops *rx_ops; struct vdev_start_response rsp = {0}; wmi_host_vdev_start_resp vdev_start_resp; + uint8_t vdev_id; + struct vdev_response_timer *vdev_rsp; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } @@ -162,6 +274,28 @@ static int target_if_vdev_mgr_start_response_handler( return -EINVAL; } + vdev_id = vdev_start_resp.vdev_id; + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response timer is null VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return -EINVAL; + } + + if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT) + status = target_if_vdev_mgr_rsp_timer_stop( + psoc, vdev_rsp, + RESTART_RESPONSE_BIT); + else + status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, + START_RESPONSE_BIT); + + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", + psoc->soc_objmgr.psoc_id, vdev_id); + goto err; + } + rsp.vdev_id = vdev_start_resp.vdev_id; rsp.requestor_id = vdev_start_resp.requestor_id; rsp.status = vdev_start_resp.status; @@ -171,26 +305,28 @@ static int target_if_vdev_mgr_start_response_handler( rsp.mac_id = vdev_start_resp.mac_id; rsp.cfgd_tx_streams = vdev_start_resp.cfgd_tx_streams; rsp.cfgd_rx_streams = vdev_start_resp.cfgd_rx_streams; + rsp.max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power; status = rx_ops->vdev_mgr_start_response(psoc, &rsp); +err: return qdf_status_to_os_return(status); } -static int target_if_vdev_mgr_stop_response_handler( - ol_scn_t scn, - uint8_t *data, - uint32_t datalen) +static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_psoc *psoc; struct wmi_unified *wmi_handle; struct wlan_lmac_if_mlme_rx_ops *rx_ops; struct vdev_stop_response rsp = {0}; uint32_t vdev_id; + struct vdev_response_timer *vdev_rsp; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } @@ -217,26 +353,43 @@ static int target_if_vdev_mgr_stop_response_handler( return -EINVAL; } + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response timer is null VDEV_%d PSOC_%d", + vdev_id, wlan_psoc_get_id(psoc)); + return -EINVAL; + } + + status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, + STOP_RESPONSE_BIT); + + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", + psoc->soc_objmgr.psoc_id, vdev_id); + goto err; + } + rsp.vdev_id = vdev_id; status = rx_ops->vdev_mgr_stop_response(psoc, &rsp); +err: return qdf_status_to_os_return(status); } -static int target_if_vdev_mgr_delete_response_handler( - ol_scn_t scn, - uint8_t *data, - uint32_t datalen) +static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_psoc *psoc; struct wmi_unified *wmi_handle; struct wlan_lmac_if_mlme_rx_ops *rx_ops; struct vdev_delete_response rsp = {0}; struct wmi_host_vdev_delete_resp vdev_del_resp; + struct vdev_response_timer *vdev_rsp; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } @@ -247,8 +400,7 @@ static int target_if_vdev_mgr_delete_response_handler( } rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops || !rx_ops->vdev_mgr_stop_response || - !rx_ops->vdev_mgr_get_response_timer_info) { + if (!rx_ops || !rx_ops->vdev_mgr_delete_response) { mlme_err("No Rx Ops"); return -EINVAL; } @@ -264,16 +416,108 @@ static int target_if_vdev_mgr_delete_response_handler( return -EINVAL; } + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, + vdev_del_resp.vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response timer is null VDEV_%d PSOC_%d", + vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc)); + return -EINVAL; + } + + status = target_if_vdev_mgr_rsp_timer_stop( + psoc, vdev_rsp, + DELETE_RESPONSE_BIT); + + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", + wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id); + goto err; + } + rsp.vdev_id = vdev_del_resp.vdev_id; status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); - + target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK); +err: return qdf_status_to_os_return(status); } -static int target_if_vdev_mgr_offload_bcn_tx_status_handler( +static int target_if_vdev_mgr_peer_delete_all_response_handler( ol_scn_t scn, uint8_t *data, uint32_t datalen) +{ + QDF_STATUS status = QDF_STATUS_E_INVAL; + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + struct peer_delete_all_response rsp = {0}; + struct wmi_host_vdev_peer_delete_all_response_event + vdev_peer_del_all_resp; + struct vdev_response_timer *vdev_rsp; + + if (!scn || !data) { + mlme_err("Invalid input"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + mlme_err("PSOC is NULL"); + return -EINVAL; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) { + mlme_err("No Rx Ops"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + mlme_err("wmi_handle is null"); + return -EINVAL; + } + + if (wmi_extract_vdev_peer_delete_all_response_event( + wmi_handle, data, + &vdev_peer_del_all_resp)) { + mlme_err("WMI extract failed"); + return -EINVAL; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, + vdev_peer_del_all_resp.vdev_id); + if (!vdev_rsp) { + mlme_err("vdev response timer is null VDEV_%d PSOC_%d", + vdev_peer_del_all_resp.vdev_id, + wlan_psoc_get_id(psoc)); + return -EINVAL; + } + + status = target_if_vdev_mgr_rsp_timer_stop( + psoc, + vdev_rsp, + PEER_DELETE_ALL_RESPONSE_BIT); + + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", + psoc->soc_objmgr.psoc_id, + vdev_peer_del_all_resp.vdev_id); + goto err; + } + + rsp.vdev_id = vdev_peer_del_all_resp.vdev_id; + rsp.status = vdev_peer_del_all_resp.status; + status = rx_ops->vdev_mgr_peer_delete_all_response(psoc, &rsp); + +err: + return qdf_status_to_os_return(status); +} + +int target_if_vdev_mgr_offload_bcn_tx_status_handler( + ol_scn_t scn, + uint8_t *data, + uint32_t datalen) { QDF_STATUS status; struct wlan_objmgr_psoc *psoc; @@ -282,7 +526,7 @@ static int target_if_vdev_mgr_offload_bcn_tx_status_handler( uint32_t vdev_id, tx_status; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } psoc = target_if_get_psoc_from_scn_hdl(scn); @@ -316,9 +560,8 @@ static int target_if_vdev_mgr_offload_bcn_tx_status_handler( return qdf_status_to_os_return(status); } -static int target_if_vdev_mgr_tbttoffset_update_handler( - ol_scn_t scn, - uint8_t *data, +int target_if_vdev_mgr_tbttoffset_update_handler( + ol_scn_t scn, uint8_t *data, uint32_t datalen) { QDF_STATUS status; @@ -328,7 +571,7 @@ static int target_if_vdev_mgr_tbttoffset_update_handler( uint32_t num_vdevs = 0; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } psoc = target_if_get_psoc_from_scn_hdl(scn); @@ -354,12 +597,13 @@ static int target_if_vdev_mgr_tbttoffset_update_handler( return -EINVAL; } - status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, false); + status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, + false); return qdf_status_to_os_return(status); } -static int target_if_vdev_mgr_ext_tbttoffset_update_handler( +int target_if_vdev_mgr_ext_tbttoffset_update_handler( ol_scn_t scn, uint8_t *data, uint32_t datalen) @@ -371,7 +615,7 @@ static int target_if_vdev_mgr_ext_tbttoffset_update_handler( uint32_t num_vdevs = 0; if (!scn || !data) { - mlme_err("scn: 0x%pK, data: 0x%pK", scn, data); + mlme_err("Invalid input"); return -EINVAL; } psoc = target_if_get_psoc_from_scn_hdl(scn); @@ -398,7 +642,79 @@ static int target_if_vdev_mgr_ext_tbttoffset_update_handler( return -EINVAL; } - status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, true); + status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, + true); + + return qdf_status_to_os_return(status); +} + +static int target_if_vdev_mgr_multi_vdev_restart_resp_handler( + ol_scn_t scn, + uint8_t *data, + uint32_t datalen) +{ + QDF_STATUS status = QDF_STATUS_E_INVAL; + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + struct multi_vdev_restart_resp restart_resp; + struct vdev_response_timer *vdev_rsp; + uint8_t max_vdevs, vdev_idx; + + if (!scn || !data) { + mlme_err("Invalid input"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + mlme_err("PSOC is NULL"); + return -EINVAL; + } + + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp || + !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("No Rx Ops"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + mlme_err("wmi_handle is null"); + return -EINVAL; + } + + qdf_mem_zero(&restart_resp, sizeof(restart_resp)); + if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data, + &restart_resp)) { + mlme_err("WMI extract failed"); + return -EINVAL; + } + + max_vdevs = wlan_psoc_get_max_vdev_count(psoc); + for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) { + if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap)) + continue; + + mlme_debug("PSOC_%d VDEV_%d: Restart resp received", + wlan_psoc_get_id(psoc), vdev_idx); + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, + vdev_idx); + if (!vdev_rsp) { + mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", + wlan_psoc_get_id(psoc), vdev_idx); + continue; + } + + status = target_if_vdev_mgr_rsp_timer_stop( + psoc, vdev_rsp, RESTART_RESPONSE_BIT); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", + wlan_psoc_get_id(psoc), vdev_idx); + } + + status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp); return qdf_status_to_os_return(status); } @@ -424,7 +740,7 @@ QDF_STATUS target_if_vdev_mgr_wmi_event_register( wmi_handle, wmi_vdev_stopped_event_id, target_if_vdev_mgr_stop_response_handler, - WMI_RX_UMAC_CTX); + VDEV_RSP_RX_CTX); if (retval) mlme_err("failed to register for stop response"); @@ -432,7 +748,7 @@ QDF_STATUS target_if_vdev_mgr_wmi_event_register( wmi_handle, wmi_vdev_delete_resp_event_id, target_if_vdev_mgr_delete_response_handler, - WMI_RX_UMAC_CTX); + VDEV_RSP_RX_CTX); if (retval) mlme_err("failed to register for delete response"); @@ -440,10 +756,26 @@ QDF_STATUS target_if_vdev_mgr_wmi_event_register( wmi_handle, wmi_vdev_start_resp_event_id, target_if_vdev_mgr_start_response_handler, - WMI_RX_UMAC_CTX); + VDEV_RSP_RX_CTX); if (retval) mlme_err("failed to register for start response"); + retval = wmi_unified_register_event_handler( + wmi_handle, + wmi_peer_delete_all_response_event_id, + target_if_vdev_mgr_peer_delete_all_response_handler, + VDEV_RSP_RX_CTX); + if (retval) + mlme_err("failed to register for peer delete all response"); + + retval = wmi_unified_register_event_handler( + wmi_handle, + wmi_pdev_multi_vdev_restart_response_event_id, + target_if_vdev_mgr_multi_vdev_restart_resp_handler, + VDEV_RSP_RX_CTX); + if (retval) + mlme_err("failed to register for multivdev restart response"); + return qdf_status_from_os_return(retval); } @@ -463,14 +795,22 @@ QDF_STATUS target_if_vdev_mgr_wmi_event_unregister( return QDF_STATUS_E_INVAL; } + wmi_unified_unregister_event_handler( + wmi_handle, + wmi_pdev_multi_vdev_restart_response_event_id); + + wmi_unified_unregister_event_handler( + wmi_handle, + wmi_peer_delete_all_response_event_id); + wmi_unified_unregister_event_handler(wmi_handle, - wmi_vdev_stopped_event_id); + wmi_vdev_start_resp_event_id); wmi_unified_unregister_event_handler(wmi_handle, wmi_vdev_delete_resp_event_id); wmi_unified_unregister_event_handler(wmi_handle, - wmi_vdev_start_resp_event_id); + wmi_vdev_stopped_event_id); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c index ee271bc880481cc593ea053e5f77a9e29abcd92f..83cc320070e44d13d2386c7371aae1db1fcddb34 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,6 +34,10 @@ #include #include #include +#include +#include +#include +#include static QDF_STATUS target_if_vdev_mgr_register_event_handler( struct wlan_objmgr_psoc *psoc) @@ -47,25 +51,20 @@ static QDF_STATUS target_if_vdev_mgr_unregister_event_handler( return target_if_vdev_mgr_wmi_event_unregister(psoc); } -static QDF_STATUS target_if_vdev_mgr_rsp_timer_mod( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - int mseconds) +QDF_STATUS +target_if_vdev_mgr_rsp_timer_stop(struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit) { - if (!vdev || !vdev_rsp) { - mlme_err("Invalid input"); + struct wlan_lmac_if_mlme_tx_ops *txops; + + txops = target_if_vdev_mgr_get_tx_ops(psoc); + if (!txops || !txops->psoc_vdev_rsp_timer_deinit) { + mlme_err("Failed to get mlme txrx_ops VDEV_%d PSOC_%d", + vdev_rsp->vdev_id, wlan_psoc_get_id(psoc)); return QDF_STATUS_E_FAILURE; } - qdf_timer_mod(&vdev_rsp->rsp_timer, mseconds); - return QDF_STATUS_SUCCESS; -} - -static QDF_STATUS target_if_vdev_mgr_rsp_timer_stop( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - uint8_t clear_bit) -{ if (qdf_atomic_test_and_clear_bit(clear_bit, &vdev_rsp->rsp_status)) { /* * This is triggered from timer expiry case only for @@ -75,99 +74,67 @@ static QDF_STATUS target_if_vdev_mgr_rsp_timer_stop( qdf_timer_stop(&vdev_rsp->rsp_timer); vdev_rsp->timer_status = QDF_STATUS_SUCCESS; + if (clear_bit == DELETE_RESPONSE_BIT) + txops->psoc_vdev_rsp_timer_deinit(psoc, + vdev_rsp->vdev_id); + /* * Releasing reference taken at the time of * starting response timer */ - wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); + wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); return QDF_STATUS_SUCCESS; } - return QDF_STATUS_E_FAILURE; } -#ifdef VDEV_ASSERT_MANAGEMENT -static void target_if_vdev_mgr_assert_mgmt( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - uint8_t set_bit) -{ - target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, - set_bit); -} -#else -static void target_if_vdev_mgr_assert_mgmt( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - uint8_t set_bit) -{ - QDF_ASSERT(0); -} -#endif - static QDF_STATUS target_if_vdev_mgr_rsp_timer_start( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - uint8_t set_bit) + struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit set_bit) { - uint8_t vdev_id; uint8_t rsp_pos; - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - mlme_err("PSOC is NULL"); - return QDF_STATUS_E_INVAL; - } + uint8_t vdev_id; - vdev_id = wlan_vdev_get_id(vdev); /* it is expected to be only one command with FW at a time */ for (rsp_pos = START_RESPONSE_BIT; rsp_pos <= RESPONSE_BIT_MAX; rsp_pos++) { if (rsp_pos != set_bit) { if (qdf_atomic_test_bit(rsp_pos, &vdev_rsp->rsp_status)) { - mlme_err("PSOC_%d VDEV_%d: Response bit is set %d", + vdev_id = vdev_rsp->vdev_id; + mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response", wlan_psoc_get_id(psoc), - vdev_id, vdev_rsp->rsp_status); - target_if_vdev_mgr_assert_mgmt(vdev, vdev_rsp, - rsp_pos); + vdev_id, + string_from_rsp_bit(set_bit), + string_from_rsp_bit(rsp_pos)); + target_if_vdev_mgr_assert_mgmt(psoc, + vdev_id); + target_if_vdev_mgr_rsp_timer_stop(psoc, + vdev_rsp, + rsp_pos); } } } if (qdf_atomic_test_and_set_bit(set_bit, &vdev_rsp->rsp_status)) { - mlme_err("PSOC_%d VDEV_%d: Response bit is set %d", + mlme_err("PSOC_%d VDEV_%d: %s requested, waiting for %s response", wlan_psoc_get_id(psoc), - vdev_id, vdev_rsp->rsp_status); - target_if_vdev_mgr_assert_mgmt(vdev, vdev_rsp, - set_bit); + vdev_rsp->vdev_id, string_from_rsp_bit(set_bit), + string_from_rsp_bit(set_bit)); + target_if_vdev_mgr_assert_mgmt(psoc, vdev_rsp->vdev_id); + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, set_bit); + + qdf_atomic_set_bit(set_bit, &vdev_rsp->rsp_status); } /* reference taken for timer start, will be released with stop */ - wlan_objmgr_vdev_get_ref(vdev, WLAN_VDEV_TARGET_IF_ID); + wlan_objmgr_psoc_get_ref(psoc, WLAN_PSOC_TARGET_IF_ID); qdf_timer_start(&vdev_rsp->rsp_timer, vdev_rsp->expire_time); return QDF_STATUS_SUCCESS; } -static QDF_STATUS target_if_vdev_mgr_rsp_timer_init( - struct wlan_objmgr_vdev *vdev, - qdf_timer_t *rsp_timer) -{ - if (!vdev || !rsp_timer) { - mlme_err("Invalid input"); - return QDF_STATUS_E_INVAL; - } - - qdf_timer_init(NULL, rsp_timer, - target_if_vdev_mgr_rsp_timer_mgmt_cb, - (void *)vdev, QDF_TIMER_TYPE_WAKE_APPS); - mlme_debug("VDEV_%d: Response timer initialized", - wlan_vdev_get_id(vdev)); - - return QDF_STATUS_SUCCESS; -} struct wmi_unified *target_if_vdev_mgr_wmi_handle_get(struct wlan_objmgr_vdev *vdev) @@ -315,6 +282,18 @@ target_if_vdev_mlme_id_2_wmi(uint32_t cfg_id) case WLAN_MLME_CFG_LISTEN_INTERVAL: wmi_id = wmi_vdev_param_listen_interval; break; + case WLAN_MLME_CFG_ENABLE_MULTI_GROUP_KEY: + wmi_id = wmi_vdev_param_enable_multi_group_key; + break; + case WLAN_MLME_CFG_MAX_GROUP_KEYS: + wmi_id = wmi_vdev_param_max_group_keys; + break; + case WLAN_MLME_CFG_TX_ENCAP_TYPE: + wmi_id = wmi_vdev_param_tx_encap_type; + break; + case WLAN_MLME_CFG_RX_DECAP_TYPE: + wmi_id = wmi_vdev_param_rx_decap_type; + break; default: wmi_id = cfg_id; break; @@ -323,6 +302,37 @@ target_if_vdev_mlme_id_2_wmi(uint32_t cfg_id) return wmi_id; } +static +QDF_STATUS target_if_vdev_set_tx_rx_decap_type(struct wlan_objmgr_vdev *vdev, + enum wlan_mlme_cfg_id param_id, + uint32_t value) +{ + ol_txrx_soc_handle soc_txrx_handle; + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + cdp_config_param_type val = {0}; + + psoc = wlan_vdev_get_psoc(vdev); + soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); + + if (!soc_txrx_handle) + return QDF_STATUS_E_INVAL; + + if (param_id == WLAN_MLME_CFG_TX_ENCAP_TYPE) { + val.cdp_vdev_param_tx_encap = value; + return cdp_txrx_set_vdev_param(soc_txrx_handle, + vdev_id, CDP_TX_ENCAP_TYPE, + val); + } else if (param_id == WLAN_MLME_CFG_RX_DECAP_TYPE) { + val.cdp_vdev_param_rx_decap = value; + return cdp_txrx_set_vdev_param(soc_txrx_handle, + vdev_id, CDP_RX_DECAP_TYPE, + val); + } + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS target_if_vdev_mgr_set_param_send( struct wlan_objmgr_vdev *vdev, struct vdev_set_params *param) @@ -358,12 +368,29 @@ static QDF_STATUS target_if_vdev_mgr_create_send( QDF_STATUS status; struct wmi_unified *wmi_handle; uint8_t vap_addr[QDF_MAC_ADDR_SIZE] = {0}; + struct wlan_lmac_if_mlme_tx_ops *txops; + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; if (!vdev || !param) { mlme_err("Invalid input"); return QDF_STATUS_E_INVAL; } + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + mlme_err("Failed to get psoc for VDEV_%d", + wlan_vdev_get_id(vdev)); + return QDF_STATUS_E_INVAL; + } + + txops = wlan_mlme_get_lmac_tx_ops(psoc); + if (!txops || !txops->psoc_vdev_rsp_timer_init) { + mlme_err("Failed to get mlme txrx_ops for VDEV_%d PSOC_%d", + wlan_vdev_get_id(vdev), wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); if (!wmi_handle) { mlme_err("Failed to get WMI handle!"); @@ -374,6 +401,10 @@ static QDF_STATUS target_if_vdev_mgr_create_send( status = wmi_unified_vdev_create_send(wmi_handle, vap_addr, param); + vdev_id = wlan_vdev_get_id(vdev); + if (QDF_IS_STATUS_SUCCESS(status)) + status = txops->psoc_vdev_rsp_timer_init(psoc, vdev_id); + return status; } @@ -385,8 +416,8 @@ static QDF_STATUS target_if_vdev_mgr_start_send( struct wmi_unified *wmi_handle; struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_mlme_rx_ops *rx_ops; - struct vdev_response_timer *vdev_rsp; uint8_t vdev_id; + struct vdev_response_timer *vdev_rsp; if (!vdev || !param) { mlme_err("Invalid input"); @@ -402,37 +433,41 @@ static QDF_STATUS target_if_vdev_mgr_start_send( vdev_id = wlan_vdev_get_id(vdev); psoc = wlan_vdev_get_psoc(vdev); rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { - mlme_err("VDEV_%d: No Rx Ops", vdev_id); + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VEV_%d: PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); return QDF_STATUS_E_INVAL; } - vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response structure", vdev_id); - return QDF_STATUS_E_FAILURE; + mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; } vdev_rsp->expire_time = START_RESPONSE_TIMER; + target_if_wake_lock_timeout_acquire(psoc, START_WAKELOCK); + if (param->is_restart) - target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, RESTART_RESPONSE_BIT); else - target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, START_RESPONSE_BIT); status = wmi_unified_vdev_start_send(wmi_handle, param); if (QDF_IS_STATUS_ERROR(status)) { vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; vdev_rsp->expire_time = 0; + target_if_wake_lock_timeout_release(psoc, START_WAKELOCK); if (param->is_restart) - target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, RESTART_RESPONSE_BIT); else - target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, START_RESPONSE_BIT); } - return status; } @@ -446,6 +481,7 @@ static QDF_STATUS target_if_vdev_mgr_delete_response_send( rsp.vdev_id = wlan_vdev_get_id(vdev); status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); + target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK); return status; } @@ -457,9 +493,9 @@ static QDF_STATUS target_if_vdev_mgr_delete_send( QDF_STATUS status; struct wlan_objmgr_psoc *psoc; struct wmi_unified *wmi_handle; - struct vdev_response_timer *vdev_rsp; struct wlan_lmac_if_mlme_rx_ops *rx_ops; uint8_t vdev_id; + struct vdev_response_timer *vdev_rsp; if (!vdev || !param) { mlme_err("Invalid input"); @@ -475,20 +511,23 @@ static QDF_STATUS target_if_vdev_mgr_delete_send( vdev_id = wlan_vdev_get_id(vdev); psoc = wlan_vdev_get_psoc(vdev); rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { - mlme_err("VDEV_%d: No Rx Ops", vdev_id); + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); return QDF_STATUS_E_INVAL; } - vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response structure", vdev_id); - return QDF_STATUS_E_FAILURE; + mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; } vdev_rsp->expire_time = DELETE_RESPONSE_TIMER; - target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, DELETE_RESPONSE_BIT); + target_if_wake_lock_timeout_acquire(psoc, DELETE_WAKELOCK); status = wmi_unified_vdev_delete_send(wmi_handle, param->vdev_id); if (QDF_IS_STATUS_SUCCESS(status)) { @@ -498,15 +537,18 @@ static QDF_STATUS target_if_vdev_mgr_delete_send( if (!wmi_service_enabled(wmi_handle, wmi_service_sync_delete_cmds) || wlan_psoc_nif_feat_cap_get(psoc, - WLAN_SOC_F_TESTMODE_ENABLE)) + WLAN_SOC_F_TESTMODE_ENABLE)) { + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, + DELETE_RESPONSE_BIT); target_if_vdev_mgr_delete_response_send(vdev, rx_ops); + } } else { vdev_rsp->expire_time = 0; vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; - target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, DELETE_RESPONSE_BIT); + target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK); } - return status; } @@ -518,8 +560,9 @@ static QDF_STATUS target_if_vdev_mgr_stop_send( struct wmi_unified *wmi_handle; struct wlan_lmac_if_mlme_rx_ops *rx_ops; struct wlan_objmgr_psoc *psoc; - struct vdev_response_timer *vdev_rsp; uint8_t vdev_id; + struct vdev_response_timer *vdev_rsp; + if (!vdev || !param) { mlme_err("Invalid input"); @@ -535,29 +578,39 @@ static QDF_STATUS target_if_vdev_mgr_stop_send( vdev_id = wlan_vdev_get_id(vdev); psoc = wlan_vdev_get_psoc(vdev); rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - - if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { - mlme_err("VDEV_%d: No Rx Ops", vdev_id); + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); return QDF_STATUS_E_INVAL; } - vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response structure", vdev_id); - return QDF_STATUS_E_FAILURE; + mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; } vdev_rsp->expire_time = STOP_RESPONSE_TIMER; - target_if_vdev_mgr_rsp_timer_start(vdev, vdev_rsp, STOP_RESPONSE_BIT); + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, STOP_RESPONSE_BIT); + /* + * START wakelock is acquired before sending the start command and + * released after sending up command to fw. This is to prevent the + * system to go into suspend state during the connection. + * In auth/assoc failure scenario UP command is not sent + * so release the START wakelock here. + */ + target_if_wake_lock_timeout_release(psoc, START_WAKELOCK); + target_if_wake_lock_timeout_acquire(psoc, STOP_WAKELOCK); status = wmi_unified_vdev_stop_send(wmi_handle, param->vdev_id); if (QDF_IS_STATUS_ERROR(status)) { vdev_rsp->expire_time = 0; vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; - target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, STOP_RESPONSE_BIT); + target_if_wake_lock_timeout_release(psoc, STOP_WAKELOCK); } - return status; } @@ -567,6 +620,7 @@ static QDF_STATUS target_if_vdev_mgr_down_send( { QDF_STATUS status; struct wmi_unified *wmi_handle; + struct wlan_objmgr_psoc *psoc; if (!vdev || !param) { mlme_err("Invalid input"); @@ -579,7 +633,14 @@ static QDF_STATUS target_if_vdev_mgr_down_send( return QDF_STATUS_E_INVAL; } + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + mlme_err("Failed to get PSOC Object"); + return QDF_STATUS_E_INVAL; + } + status = wmi_unified_vdev_down_send(wmi_handle, param->vdev_id); + target_if_wake_lock_timeout_release(psoc, STOP_WAKELOCK); return status; } @@ -590,9 +651,8 @@ static QDF_STATUS target_if_vdev_mgr_up_send( { QDF_STATUS status; struct wmi_unified *wmi_handle; - struct vdev_set_params sparam = {0}; uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint8_t vdev_id; + struct wlan_objmgr_psoc *psoc; if (!vdev || !param) { mlme_err("Invalid input"); @@ -605,19 +665,15 @@ static QDF_STATUS target_if_vdev_mgr_up_send( return QDF_STATUS_E_INVAL; } - vdev_id = wlan_vdev_get_id(vdev); - sparam.vdev_id = vdev_id; - - sparam.param_id = WLAN_MLME_CFG_BEACON_INTERVAL; - wlan_util_vdev_get_param(vdev, WLAN_MLME_CFG_BEACON_INTERVAL, - &sparam.param_value); - status = target_if_vdev_mgr_set_param_send(vdev, &sparam); - if (QDF_IS_STATUS_ERROR(status)) - mlme_err("VDEV_%d: Failed to set beacon interval!", vdev_id); - + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + mlme_err("Failed to get PSOC Object"); + return QDF_STATUS_E_INVAL; + } ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid); status = wmi_unified_vdev_up_send(wmi_handle, bssid, param); + target_if_wake_lock_timeout_release(psoc, START_WAKELOCK); return status; } @@ -759,7 +815,6 @@ static QDF_STATUS target_if_vdev_mgr_config_ratemask_cmd_send( status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle, param); - return status; } @@ -795,14 +850,15 @@ static int32_t target_if_vdev_mgr_multi_vdev_restart_get_ref( { struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_vdev *tvdev; - struct vdev_response_timer *vdev_rsp = NULL; struct wlan_lmac_if_mlme_rx_ops *rx_ops; - uint32_t vdev_idx; + int32_t vdev_idx = -1; int32_t last_vdev_idx = -1; + struct vdev_response_timer *vdev_rsp; psoc = wlan_pdev_get_psoc(pdev); rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); - if (!rx_ops && !rx_ops->vdev_mgr_get_response_timer_info) { + + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { mlme_err("VDEV_%d: No Rx Ops", vdev_idx); return last_vdev_idx; } @@ -818,15 +874,17 @@ static int32_t target_if_vdev_mgr_multi_vdev_restart_get_ref( return last_vdev_idx; } - last_vdev_idx = vdev_idx; - vdev_rsp = - rx_ops->vdev_mgr_get_response_timer_info(tvdev); + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info( + psoc, + wlan_vdev_get_id(tvdev)); if (!vdev_rsp) { - mlme_err("VDEV_%d: No Rx Ops", vdev_idx); + mlme_err("VDEV_%d PSOC_%d No vdev rsp timer", + vdev_idx, wlan_psoc_get_id(psoc)); return last_vdev_idx; } - target_if_vdev_mgr_rsp_timer_start(tvdev, vdev_rsp, + last_vdev_idx = vdev_idx; + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, RESTART_RESPONSE_BIT); vdev_timer_started[vdev_idx] = true; } @@ -844,19 +902,30 @@ static void target_if_vdev_mgr_multi_vdev_restart_rel_ref( struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_vdev *tvdev; struct wlan_lmac_if_mlme_rx_ops *rx_ops; - struct vdev_response_timer *vdev_rsp = NULL; uint32_t vdev_idx; + struct vdev_response_timer *vdev_rsp; psoc = wlan_pdev_get_psoc(pdev); rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d: No Rx Ops", last_vdev_idx); + return; + } + for (vdev_idx = 0; vdev_idx <= last_vdev_idx; vdev_idx++) { tvdev = vdev_list[vdev_idx]; + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, + vdev_idx); + if (!vdev_rsp) { + mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", + vdev_idx, wlan_psoc_get_id(psoc)); + return; + } + if (QDF_IS_STATUS_ERROR(status)) { - vdev_rsp = - rx_ops->vdev_mgr_get_response_timer_info(tvdev); - if (vdev_rsp && vdev_timer_started[vdev_idx]) { + if (vdev_timer_started[vdev_idx]) { target_if_vdev_mgr_rsp_timer_stop( - tvdev, vdev_rsp, + psoc, vdev_rsp, RESTART_RESPONSE_BIT); vdev_timer_started[vdev_idx] = false; } @@ -968,6 +1037,96 @@ static QDF_STATUS target_if_vdev_mgr_sta_ps_param_send( return status; } +static QDF_STATUS target_if_vdev_mgr_peer_delete_all_send( + struct wlan_objmgr_vdev *vdev, + struct peer_delete_all_params *param) +{ + QDF_STATUS status; + struct wmi_unified *wmi_handle; + struct wlan_lmac_if_mlme_rx_ops *rx_ops; + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; + struct vdev_response_timer *vdev_rsp; + + if (!vdev || !param) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); + if (!wmi_handle) { + mlme_err("Failed to get WMI handle!"); + return QDF_STATUS_E_INVAL; + } + + vdev_id = wlan_vdev_get_id(vdev); + psoc = wlan_vdev_get_psoc(vdev); + rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); + + if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { + mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); + if (!vdev_rsp) { + mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id, + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_INVAL; + } + + vdev_rsp->expire_time = PEER_DELETE_ALL_RESPONSE_TIMER; + target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp, + PEER_DELETE_ALL_RESPONSE_BIT); + + status = wmi_unified_peer_delete_all_send(wmi_handle, param); + if (QDF_IS_STATUS_ERROR(status)) { + vdev_rsp->expire_time = 0; + vdev_rsp->timer_status = QDF_STATUS_E_CANCELED; + target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, + PEER_DELETE_ALL_RESPONSE_BIT); + } + return status; +} + +#if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) +static QDF_STATUS target_if_vdev_mgr_fils_enable_send( + struct wlan_objmgr_vdev *vdev, + struct config_fils_params *param) +{ + QDF_STATUS status; + struct wmi_unified *wmi_handle; + + if (!vdev || !param) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); + if (!wmi_handle) { + mlme_err("Failed to get WMI handle!"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_vdev_fils_enable_cmd_send(wmi_handle, param); + + return status; +} + +static void target_if_vdev_register_tx_fils( + struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops) +{ + mlme_tx_ops->vdev_fils_enable_send = + target_if_vdev_mgr_fils_enable_send; +} +#else +static void target_if_vdev_register_tx_fils( + struct wlan_lmac_if_mlme_tx_ops *mlme_tx_ops) +{ +} +#endif + QDF_STATUS target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { @@ -1012,14 +1171,27 @@ target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) mlme_tx_ops->beacon_tmpl_send = target_if_vdev_mgr_beacon_tmpl_send; mlme_tx_ops->vdev_set_param_send = target_if_vdev_mgr_set_param_send; + mlme_tx_ops->vdev_set_tx_rx_decap_type = + target_if_vdev_set_tx_rx_decap_type; mlme_tx_ops->vdev_sta_ps_param_send = target_if_vdev_mgr_sta_ps_param_send; - mlme_tx_ops->vdev_mgr_rsp_timer_init = - target_if_vdev_mgr_rsp_timer_init; - mlme_tx_ops->vdev_mgr_rsp_timer_mod = + mlme_tx_ops->psoc_vdev_rsp_timer_mod = target_if_vdev_mgr_rsp_timer_mod; + mlme_tx_ops->peer_delete_all_send = + target_if_vdev_mgr_peer_delete_all_send; + target_if_vdev_register_tx_fils(mlme_tx_ops); + + mlme_tx_ops->psoc_vdev_rsp_timer_init = + target_if_psoc_vdev_rsp_timer_init; + mlme_tx_ops->psoc_vdev_rsp_timer_deinit = + target_if_psoc_vdev_rsp_timer_deinit; + mlme_tx_ops->psoc_vdev_rsp_timer_inuse = + target_if_psoc_vdev_rsp_timer_inuse; + mlme_tx_ops->psoc_wake_lock_init = + target_if_wake_lock_init; + mlme_tx_ops->psoc_wake_lock_deinit = + target_if_wake_lock_deinit; mlme_tx_ops->vdev_mgr_rsp_timer_stop = target_if_vdev_mgr_rsp_timer_stop; - return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg_11d.c b/drivers/staging/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg_11d.c index 2e2bca8e89ae20ec1f783b9d96b789d7bdf3b6ed..c857868d380b38572ea4ddbbb820fa27d52b95e1 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg_11d.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/regulatory/src/target_if_reg_11d.c @@ -36,7 +36,7 @@ bool tgt_if_regulatory_is_11d_offloaded(struct wlan_objmgr_psoc *psoc) return false; if (reg_rx_ops->reg_ignore_fw_reg_offload_ind && - reg_rx_ops->reg_ignore_fw_reg_offload_ind(psoc)) { + reg_rx_ops->reg_ignore_fw_reg_offload_ind(psoc)) { target_if_debug("Ignore fw reg 11d offload indication"); return 0; } diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/scan/src/target_if_scan.c b/drivers/staging/qca-wifi-host-cmn/target_if/scan/src/target_if_scan.c index b63b38b2595f338e977d81cbec14e870cea0f8e7..a3b825bfac3e2e1d81218a26d51ff167be98f616 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/scan/src/target_if_scan.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/scan/src/target_if_scan.c @@ -29,7 +29,6 @@ #include #include - static inline struct wlan_lmac_if_scan_rx_ops * target_if_scan_get_rx_ops(struct wlan_objmgr_psoc *psoc) { @@ -93,12 +92,10 @@ target_if_scan_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data, uint32_t len) { - wmi_nlo_event *nlo_event; struct scan_event_info *event_info; struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; struct wlan_lmac_if_scan_rx_ops *scan_rx_ops; - WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = - (WMI_NLO_MATCH_EVENTID_param_tlvs *) data; QDF_STATUS status; if (!scn || !data) { @@ -112,16 +109,25 @@ int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data, return -EINVAL; } + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is NULL"); + return -EINVAL; + } + event_info = qdf_mem_malloc(sizeof(*event_info)); if (!event_info) return -ENOMEM; - nlo_event = param_buf->fixed_param; - target_if_debug("PNO complete event received for vdev %d", - nlo_event->vdev_id); + if (wmi_extract_nlo_complete_ev_param(wmi_handle, data, + &event_info->event)) { + target_if_err("Failed to extract WMI PNO complete event"); + qdf_mem_free(event_info); + return -EINVAL; + } - event_info->event.type = SCAN_EVENT_TYPE_NLO_COMPLETE; - event_info->event.vdev_id = nlo_event->vdev_id; + target_if_debug("PNO complete event received for vdev %d", + event_info->event.vdev_id); scan_rx_ops = target_if_scan_get_rx_ops(psoc); if (scan_rx_ops->scan_ev_handler) { @@ -141,12 +147,10 @@ int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data, int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data, uint32_t len) { - wmi_nlo_event *nlo_event; struct scan_event_info *event_info; struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; struct wlan_lmac_if_scan_rx_ops *scan_rx_ops; - WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = - (WMI_NLO_MATCH_EVENTID_param_tlvs *) data; QDF_STATUS status; if (!scn || !data) { @@ -160,16 +164,25 @@ int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data, return -EINVAL; } + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is NULL"); + return -EINVAL; + } + event_info = qdf_mem_malloc(sizeof(*event_info)); if (!event_info) return -ENOMEM; - nlo_event = param_buf->fixed_param; - target_if_debug("PNO match event received for vdev %d", - nlo_event->vdev_id); + if (wmi_extract_nlo_match_ev_param(wmi_handle, data, + &event_info->event)) { + target_if_err("Failed to extract WMI PNO match event"); + qdf_mem_free(event_info); + return -EINVAL; + } - event_info->event.type = SCAN_EVENT_TYPE_NLO_MATCH; - event_info->event.vdev_id = nlo_event->vdev_id; + target_if_debug("PNO match event received for vdev %d", + event_info->event.vdev_id); scan_rx_ops = target_if_scan_get_rx_ops(psoc); if (scan_rx_ops->scan_ev_handler) { @@ -378,7 +391,7 @@ QDF_STATUS target_if_scan_start(struct wlan_objmgr_pdev *pdev, struct scan_start_request *req) { - void *pdev_wmi_handle; + wmi_unified_t pdev_wmi_handle; pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev); if (!pdev_wmi_handle) { @@ -392,7 +405,7 @@ QDF_STATUS target_if_scan_cancel(struct wlan_objmgr_pdev *pdev, struct scan_cancel_param *req) { - void *pdev_wmi_handle; + wmi_unified_t pdev_wmi_handle; pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev); if (!pdev_wmi_handle) { diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.c b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.c index e14eab404b9fedc482316e4ba47951477749406e..6dc413934eca84cf7157083f176d792d05e533de 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -27,10 +27,11 @@ #include #include #include -#include #include #include #include +#include +#include /** * @spectral_ops - Spectral function table, holds the Spectral functions that @@ -88,12 +89,14 @@ target_if_spectral_get_vdev(struct target_if_spectral *spectral) * target_if_send_vdev_spectral_configure_cmd() - Send WMI command to configure * spectral parameters * @spectral: Pointer to Spectral target_if internal private data + * @smode: Spectral scan mode * @param: Pointer to spectral_config giving the Spectral configuration * * Return: QDF_STATUS_SUCCESS on success, negative error code on failure */ static int target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral, + enum spectral_scan_mode smode, struct spectral_config *param) { struct vdev_spectral_configure_params sparam; @@ -133,6 +136,8 @@ target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral, sparam.bin_scale = param->ss_bin_scale; sparam.dbm_adj = param->ss_dbm_adj; sparam.chn_mask = param->ss_chn_mask; + sparam.mode = smode; + sparam.center_freq = param->ss_frequency; return spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send( GET_WMI_HDL_FROM_PDEV(pdev), &sparam); @@ -142,6 +147,7 @@ target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral, * target_if_send_vdev_spectral_enable_cmd() - Send WMI command to * enable/disable Spectral * @spectral: Pointer to Spectral target_if internal private data + * @smode: Spectral scan mode * @is_spectral_active_valid: Flag to indicate if spectral activate (trigger) is * valid * @is_spectral_active: Value of spectral activate @@ -152,6 +158,7 @@ target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral, */ static int target_if_send_vdev_spectral_enable_cmd(struct target_if_spectral *spectral, + enum spectral_scan_mode smode, uint8_t is_spectral_active_valid, uint8_t is_spectral_active, uint8_t is_spectral_enabled_valid, @@ -180,6 +187,7 @@ target_if_send_vdev_spectral_enable_cmd(struct target_if_spectral *spectral, param.enabled_valid = is_spectral_enabled_valid; param.active = is_spectral_active; param.enabled = is_spectral_enabled; + param.mode = smode; return spectral->param_wmi_cmd_ops.wmi_spectral_enable_cmd_send( GET_WMI_HDL_FROM_PDEV(pdev), ¶m); @@ -345,7 +353,7 @@ target_if_log_read_spectral_params( const char *function_name, struct spectral_config *pparam) { - spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Returning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\n", + spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Returning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency=%u\n", function_name, pparam->ss_count, pparam->ss_period, @@ -364,7 +372,8 @@ target_if_log_read_spectral_params( pparam->ss_rpt_mode, pparam->ss_bin_scale, pparam->ss_dbm_adj, - pparam->ss_chn_mask); + pparam->ss_chn_mask, + pparam->ss_frequency); } /** @@ -666,7 +675,7 @@ target_if_log_write_spectral_params( const char *function_name, int ret) { - spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nstatus = %d", + spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency=%u\nstatus = %d", function_name, param->ss_count, param->ss_period, @@ -684,7 +693,10 @@ target_if_log_write_spectral_params( param->ss_pwr_format, param->ss_rpt_mode, param->ss_bin_scale, - param->ss_dbm_adj, param->ss_chn_mask, ret); + param->ss_dbm_adj, + param->ss_chn_mask, + param->ss_frequency, + ret); } /** @@ -731,7 +743,7 @@ target_if_spectral_info_write( pval = (uint8_t *)input; qdf_spin_lock(&info->osps_lock); - ret = target_if_send_vdev_spectral_enable_cmd(spectral, + ret = target_if_send_vdev_spectral_enable_cmd(spectral, smode, 1, *pval, 0, 0); target_if_log_write_spectral_active( @@ -761,7 +773,7 @@ target_if_spectral_info_write( pval = (uint8_t *)input; qdf_spin_lock(&info->osps_lock); - ret = target_if_send_vdev_spectral_enable_cmd(spectral, + ret = target_if_send_vdev_spectral_enable_cmd(spectral, smode, 0, 0, 1, *pval); target_if_log_write_spectral_enabled( @@ -792,7 +804,7 @@ target_if_spectral_info_write( qdf_spin_lock(&info->osps_lock); ret = target_if_send_vdev_spectral_configure_cmd(spectral, - param); + smode, param); target_if_log_write_spectral_params( param, @@ -1324,6 +1336,114 @@ target_if_spectral_get_macaddr(void *arg, char *addr) return 0; } +/** + * target_if_init_spectral_param_min_max() - Initialize Spectral parameter + * min and max values + * + * @param_min_max: Pointer to Spectral parameter min and max structure + * @gen: Spectral HW generation + * @target_type: Target type + * + * Initialize Spectral parameter min and max values + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_init_spectral_param_min_max( + struct spectral_param_min_max *param_min_max, + enum spectral_gen gen, uint32_t target_type) +{ + switch (gen) { + case SPECTRAL_GEN3: + param_min_max->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3; + param_min_max->fft_size_max[CH_WIDTH_20MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + if (target_type == TARGET_TYPE_QCN9000) { + param_min_max->fft_size_max[CH_WIDTH_40MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000; + param_min_max->fft_size_max[CH_WIDTH_80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000; + param_min_max->fft_size_max[CH_WIDTH_160MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000; + param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000; + } else { + param_min_max->fft_size_max[CH_WIDTH_40MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + param_min_max->fft_size_max[CH_WIDTH_80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + param_min_max->fft_size_max[CH_WIDTH_160MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + } + break; + + case SPECTRAL_GEN2: + param_min_max->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2; + param_min_max->fft_size_max[CH_WIDTH_20MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; + param_min_max->fft_size_max[CH_WIDTH_40MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; + param_min_max->fft_size_max[CH_WIDTH_80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; + param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; + param_min_max->fft_size_max[CH_WIDTH_160MHZ] = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; + break; + + default: + spectral_err("Invalid spectral generation %d", gen); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_init_spectral_param_properties() - Initialize Spectral parameter + * properties + * @spectral: Pointer to Spectral target_if internal private data + * + * Initialize Spectral parameter properties + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_init_spectral_param_properties(struct target_if_spectral *spectral) +{ + enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL; + int param; + + /* Initialize default values for properties. + * Default values are supported for all the parameters for all modes + * and allows different values for each mode for all the parameters . + */ + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) { + for (param = 0; param < SPECTRAL_PARAM_MAX; param++) { + spectral->properties[smode][param].supported = true; + spectral->properties[smode][param].common_all_modes = + false; + } + } + + /* Once FW advertisement is in place remove this hard coding */ + smode = SPECTRAL_SCAN_MODE_NORMAL; + spectral->properties[SPECTRAL_SCAN_MODE_NORMAL] + [SPECTRAL_PARAM_FREQUENCY].supported = false; + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) { + spectral->properties[smode] + [SPECTRAL_PARAM_SPECT_PRI].common_all_modes = true; + spectral->properties[smode] + [SPECTRAL_PARAM_SCAN_PERIOD].common_all_modes = true; + spectral->properties[smode] + [SPECTRAL_PARAM_INIT_DELAY].common_all_modes = true; + } + + return QDF_STATUS_SUCCESS; +} + /** * target_if_init_spectral_capability() - Initialize Spectral capability * @spectral: Pointer to Spectral target_if internal private data @@ -1342,6 +1462,11 @@ target_if_init_spectral_capability(struct target_if_spectral *spectral) struct target_psoc_info *tgt_psoc_info; struct wlan_psoc_host_service_ext_param *ext_svc_param; struct spectral_caps *pcap = &spectral->capability; + struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr = NULL; + struct wlan_psoc_host_mac_phy_caps *mac_phy_cap = NULL; + struct wlan_psoc_host_chainmask_table *table; + int j; + uint32_t table_id; pdev = spectral->pdev_obj; psoc = wlan_pdev_get_psoc(pdev); @@ -1368,19 +1493,56 @@ target_if_init_spectral_capability(struct target_if_spectral *spectral) pcap->spectral_cap = 1; pcap->advncd_spectral_cap = 1; pcap->hw_gen = spectral->spectral_gen; + if (spectral->spectral_gen >= SPECTRAL_GEN3) { + mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_psoc_info); + if (!mac_phy_cap_arr) { + spectral_err("mac phy cap array is null"); + return QDF_STATUS_E_FAILURE; + } - for (param_idx = 0; param_idx < num_bin_scaling_params; param_idx++) { - if (scaling_params[param_idx].pdev_id == pdev_id) { - pcap->is_scaling_params_populated = true; - pcap->formula_id = scaling_params[param_idx].formula_id; - pcap->low_level_offset = - scaling_params[param_idx].low_level_offset; - pcap->high_level_offset = - scaling_params[param_idx].high_level_offset; - pcap->rssi_thr = scaling_params[param_idx].rssi_thr; - pcap->default_agc_max_gain = - scaling_params[param_idx].default_agc_max_gain; - break; + mac_phy_cap = &mac_phy_cap_arr[pdev_id]; + if (!mac_phy_cap) { + spectral_err("mac phy cap is null"); + return QDF_STATUS_E_FAILURE; + } + + table_id = mac_phy_cap->chainmask_table_id; + table = &ext_svc_param->chainmask_table[table_id]; + if (!table) { + spectral_err("chainmask table not found"); + return QDF_STATUS_E_FAILURE; + } + + for (j = 0; j < table->num_valid_chainmasks; j++) { + pcap->agile_spectral_cap |= + table->cap_list[j].supports_aSpectral; + pcap->agile_spectral_cap_160 |= + table->cap_list[j].supports_aSpectral_160; + } + pcap->agile_spectral_cap_80p80 = pcap->agile_spectral_cap_160; + } else { + pcap->agile_spectral_cap = false; + pcap->agile_spectral_cap_160 = false; + pcap->agile_spectral_cap_80p80 = false; + } + + if (scaling_params) { + for (param_idx = 0; param_idx < num_bin_scaling_params; + param_idx++) { + if (scaling_params[param_idx].pdev_id == pdev_id) { + pcap->is_scaling_params_populated = true; + pcap->formula_id = + scaling_params[param_idx].formula_id; + pcap->low_level_offset = + scaling_params[param_idx].low_level_offset; + pcap->high_level_offset = + scaling_params[param_idx].high_level_offset; + pcap->rssi_thr = + scaling_params[param_idx].rssi_thr; + pcap->default_agc_max_gain = + scaling_params[param_idx].default_agc_max_gain; + break; + } } } @@ -1916,6 +2078,114 @@ target_if_spectral_attach_simulation(struct target_if_spectral *spectral) } #endif +/** + * target_if_spectral_len_adj_swar_init() - Initialize FFT bin length adjustment + * related info + * @swar: Pointer to Spectral FFT bin length adjustment SWAR params + * @target_type: Target type + * + * Function to Initialize parameters related to Spectral FFT bin + * length adjustment SWARs. + * + * Return: void + */ +static void +target_if_spectral_len_adj_swar_init(struct spectral_fft_bin_len_adj_swar *swar, + uint32_t target_type) +{ + if (target_type == TARGET_TYPE_QCA8074V2 || + target_type == TARGET_TYPE_QCN9000) + swar->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE; + else if (target_type == TARGET_TYPE_QCA8074 || + target_type == TARGET_TYPE_QCA6018 || + target_type == TARGET_TYPE_QCA6390) + swar->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE; + else + swar->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_NO_WAR; + + if (target_type == TARGET_TYPE_QCA8074 || + target_type == TARGET_TYPE_QCA8074V2 || + target_type == TARGET_TYPE_QCA6018 || + target_type == TARGET_TYPE_QCN9000) { + swar->inband_fftbin_size_adj = 1; + swar->null_fftbin_adj = 1; + } else { + swar->inband_fftbin_size_adj = 0; + swar->null_fftbin_adj = 0; + } + + if (target_type == TARGET_TYPE_QCA8074V2) + swar->packmode_fftbin_size_adj = 1; + else + swar->packmode_fftbin_size_adj = 0; +} + +/** + * target_if_spectral_report_params_init() - Initialize parameters which + * describes the structure of Spectral reports + * + * @rparams: Pointer to Spectral report parameter object + * @target_type: target type + * + * Function to Initialize parameters related to the structure of Spectral + * reports. + * + * Return: void + */ +static void +target_if_spectral_report_params_init( + struct spectral_report_params *rparams, + uint32_t target_type) +{ + /* This entries are currently used by gen3 chipsets only. Hence + * initialization is done for gen3 alone. In future if other generations + * needs to use them they have to add proper initial values. + */ + if (target_type == TARGET_TYPE_QCN9000) + rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_2; + else + rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1; + + switch (rparams->version) { + case SPECTRAL_REPORT_FORMAT_VERSION_1: + rparams->ssumaary_padding_bytes = + NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1; + rparams->fft_report_hdr_len = + FFT_REPORT_HEADER_LENGTH_GEN3_V1; + break; + case SPECTRAL_REPORT_FORMAT_VERSION_2: + rparams->ssumaary_padding_bytes = + NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2; + rparams->fft_report_hdr_len = + FFT_REPORT_HEADER_LENGTH_GEN3_V2; + break; + default: + qdf_assert_always(0); + } +} + +/** + * target_if_spectral_timestamp_war_init() - Initialize Spectral timestamp WAR + * related info + * @twar: Pointer to Spectral timstamp WAR related info + * + * Function to Initialize parameters related to Spectral timestamp WAR + * + * Return: void + */ +static void +target_if_spectral_timestamp_war_init(struct spectral_timestamp_war *twar) +{ + enum spectral_scan_mode smode; + + smode = SPECTRAL_SCAN_MODE_NORMAL; + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) { + twar->last_fft_timestamp[smode] = 0; + twar->timestamp_war_offset[smode] = 0; + } + twar->target_reset_count = 0; +} + /** * target_if_pdev_spectral_init() - Initialize target_if Spectral * functionality for the given pdev @@ -1936,6 +2206,7 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_target_tx_ops *tx_ops; enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL; + QDF_STATUS status; if (!pdev) { spectral_err("SPECTRAL: pdev is NULL!"); @@ -1990,32 +2261,21 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) qdf_spinlock_create(&spectral->noise_pwr_reports_lock); target_if_spectral_clear_stats(spectral); - if (target_type == TARGET_TYPE_QCA8074V2 || - target_type == TARGET_TYPE_QCA6018) - spectral->fftbin_size_war = - SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE; - else if (target_type == TARGET_TYPE_QCA8074 || - target_type == TARGET_TYPE_QCA6390) - spectral->fftbin_size_war = - SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE; - else - spectral->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_NO_WAR; - if (target_type == TARGET_TYPE_QCA8074 || target_type == TARGET_TYPE_QCA8074V2 || - target_type == TARGET_TYPE_QCA6018) { - spectral->inband_fftbin_size_adj = 1; - spectral->null_fftbin_adj = 1; - } else { - spectral->inband_fftbin_size_adj = 0; - spectral->null_fftbin_adj = 0; - } - spectral->last_fft_timestamp = 0; - spectral->timestamp_war_offset = 0; + target_type == TARGET_TYPE_QCA6018 || + target_type == TARGET_TYPE_QCA6390 || + target_type == TARGET_TYPE_QCN9000) + spectral->direct_dma_support = true; + + target_if_spectral_len_adj_swar_init(&spectral->len_adj_swar, + target_type); + target_if_spectral_report_params_init(&spectral->rparams, target_type); if ((target_type == TARGET_TYPE_QCA8074) || (target_type == TARGET_TYPE_QCA8074V2) || (target_type == TARGET_TYPE_QCA6018) || + (target_type == TARGET_TYPE_QCN9000) || (target_type == TARGET_TYPE_QCA6290) || (target_type == TARGET_TYPE_QCA6390)) { spectral->spectral_gen = SPECTRAL_GEN3; @@ -2024,8 +2284,6 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3; spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN3; spectral->tlvhdr_size = SPECTRAL_PHYERR_TLVSIZE_GEN3; - spectral->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3; - spectral->fft_size_max = SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3; } else { spectral->spectral_gen = SPECTRAL_GEN2; spectral->hdr_sig_exp = SPECTRAL_PHYERR_SIGNATURE_GEN2; @@ -2033,10 +2291,17 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2; spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN2; spectral->tlvhdr_size = sizeof(struct spectral_phyerr_tlv_gen2); - spectral->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2; - spectral->fft_size_max = SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2; } + status = target_if_init_spectral_param_min_max( + &spectral->param_min_max, + spectral->spectral_gen, target_type); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to initialize parameter min max values"); + goto fail; + } + + target_if_init_spectral_param_properties(spectral); /* Init spectral capability */ if (target_if_init_spectral_capability(spectral) != QDF_STATUS_SUCCESS) { @@ -2047,6 +2312,7 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) return NULL; target_if_init_spectral_ops(spectral); + target_if_spectral_timestamp_war_init(&spectral->timestamp_war); /* Spectral mode specific init */ for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) { @@ -2058,8 +2324,7 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) target_if_spectral_register_funcs(spectral, &spectral_ops); if (target_if_spectral_check_hw_capability(spectral) == false) { - target_if_spectral_detach(spectral); - spectral = NULL; + goto fail; } else { /* * TODO: Once the driver architecture transitions to chipset @@ -2090,6 +2355,10 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) } return spectral; + +fail: + target_if_spectral_detach(spectral); + return NULL; } /** @@ -2116,153 +2385,634 @@ target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev) return; } +/* target_if_spectral_find_agile_width() - Given a channel width enum, find the + * corresponding translation for Agile channel width. + * Translation schema of different operating modes: + * 20 -> 20, 40 -> 40, (80 & 160 & 80_80) -> 80. + * @chwidth: Channel width enum. + * + * Return: The translated channel width enum. + */ +static enum phy_ch_width +target_if_spectral_find_agile_width(enum phy_ch_width chwidth) +{ + switch (chwidth) { + case CH_WIDTH_20MHZ: + return CH_WIDTH_20MHZ; + case CH_WIDTH_40MHZ: + return CH_WIDTH_40MHZ; + case CH_WIDTH_80MHZ: + case CH_WIDTH_80P80MHZ: + case CH_WIDTH_160MHZ: + return CH_WIDTH_80MHZ; + default: + spectral_err("Invalid chwidth enum %d", chwidth); + return CH_WIDTH_INVALID; + } +} + /** - * target_if_set_spectral_config() - Set spectral config - * @pdev: Pointer to pdev object - * @threshtype: config type - * @value: config value - * @smode: Spectral scan mode - * @err: Spectral error code + * target_if_calculate_center_freq() - Helper routine to + * check whether given frequency is center frequency of a + * WLAN channel * - * API to set spectral configurations + * @spectral: Pointer to Spectral object + * @chan_freq: Center frequency of a WLAN channel + * @is_valid: Indicates whether given frequency is valid * - * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure + * Return: QDF_STATUS */ -QDF_STATUS -target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, - const uint32_t threshtype, const uint32_t value, - const enum spectral_scan_mode smode, - enum spectral_cp_error_code *err) +static QDF_STATUS +target_if_is_center_freq_of_any_chan(struct wlan_objmgr_pdev *pdev, + uint32_t chan_freq, + bool *is_valid) { - struct spectral_config params; - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; - struct spectral_config *sparams; + struct regulatory_channel *cur_chan_list; + int i; - spectral = get_target_if_spectral_handle_from_pdev(pdev); - p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); - if (!spectral) { - spectral_err("spectral object is NULL"); + if (!pdev) { + spectral_err("pdev object is null"); return QDF_STATUS_E_FAILURE; } - if (smode >= SPECTRAL_SCAN_MODE_MAX) { - spectral_err("Invalid Spectral mode %u", smode); + if (!is_valid) { + spectral_err("is valid argument is null"); return QDF_STATUS_E_FAILURE; } - sparams = &spectral->params[smode]; - if (!spectral->params_valid[smode]) { - target_if_spectral_info_read(spectral, - smode, - TARGET_IF_SPECTRAL_INFO_PARAMS, - &spectral->params[smode], - sizeof(spectral->params[smode])); - spectral->params_valid[smode] = true; + cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list)); + if (!cur_chan_list) + return QDF_STATUS_E_FAILURE; + + if (wlan_reg_get_current_chan_list( + pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { + spectral_err("Failed to get cur_chan list"); + qdf_mem_free(cur_chan_list); + return QDF_STATUS_E_FAILURE; } - switch (threshtype) { - case SPECTRAL_PARAM_FFT_PERIOD: - sparams->ss_fft_period = value; - break; - case SPECTRAL_PARAM_SCAN_PERIOD: - sparams->ss_period = value; - break; - case SPECTRAL_PARAM_SCAN_COUNT: - sparams->ss_count = value; - break; - case SPECTRAL_PARAM_SHORT_REPORT: - sparams->ss_short_report = (!!value) ? true : false; - break; - case SPECTRAL_PARAM_SPECT_PRI: - sparams->ss_spectral_pri = (!!value) ? true : false; - break; - case SPECTRAL_PARAM_FFT_SIZE: - if ((value < spectral->fft_size_min) || - (value > spectral->fft_size_max)) - return QDF_STATUS_E_FAILURE; - sparams->ss_fft_size = value; - break; - case SPECTRAL_PARAM_GC_ENA: - sparams->ss_gc_ena = !!value; - break; - case SPECTRAL_PARAM_RESTART_ENA: - sparams->ss_restart_ena = !!value; - break; - case SPECTRAL_PARAM_NOISE_FLOOR_REF: - sparams->ss_noise_floor_ref = value; - break; - case SPECTRAL_PARAM_INIT_DELAY: - sparams->ss_init_delay = value; - break; - case SPECTRAL_PARAM_NB_TONE_THR: - sparams->ss_nb_tone_thr = value; - break; - case SPECTRAL_PARAM_STR_BIN_THR: - sparams->ss_str_bin_thr = value; - break; - case SPECTRAL_PARAM_WB_RPT_MODE: - sparams->ss_wb_rpt_mode = !!value; - break; - case SPECTRAL_PARAM_RSSI_RPT_MODE: - sparams->ss_rssi_rpt_mode = !!value; - break; - case SPECTRAL_PARAM_RSSI_THR: - sparams->ss_rssi_thr = value; - break; - case SPECTRAL_PARAM_PWR_FORMAT: - sparams->ss_pwr_format = !!value; - break; - case SPECTRAL_PARAM_RPT_MODE: - if ((value < SPECTRAL_PARAM_RPT_MODE_MIN) || - (value > SPECTRAL_PARAM_RPT_MODE_MAX)) - return QDF_STATUS_E_FAILURE; - sparams->ss_rpt_mode = value; - break; - case SPECTRAL_PARAM_BIN_SCALE: - sparams->ss_bin_scale = value; - break; - case SPECTRAL_PARAM_DBM_ADJ: - sparams->ss_dbm_adj = !!value; - break; - case SPECTRAL_PARAM_CHN_MASK: - sparams->ss_chn_mask = value; - break; - case SPECTRAL_PARAM_FREQUENCY: - sparams->ss_frequency = value; - break; + *is_valid = false; + for (i = 0; i < NUM_CHANNELS; i++) { + uint32_t flags; + uint32_t center_freq; + + flags = cur_chan_list[i].chan_flags; + center_freq = cur_chan_list[i].center_freq; + + if (!(flags & REGULATORY_CHAN_DISABLED) && + (center_freq == chan_freq)) { + *is_valid = true; + break; + } } - p_sops->configure_spectral(spectral, sparams, smode); - /* only to validate the writes */ - p_sops->get_spectral_config(spectral, ¶ms, smode); + qdf_mem_free(cur_chan_list); + return QDF_STATUS_SUCCESS; } /** - * target_if_get_fft_bin_count() - Get fft bin count for a given fft length - * @fft_len: FFT length - * @pdev: Pointer to pdev object + * target_if_calculate_center_freq() - Helper routine to + * find the center frequency of the agile span from a + * WLAN channel center frequency * - * API to get fft bin count for a given fft length + * @spectral: Pointer to Spectral object + * @chan_freq: Center frequency of a WLAN channel + * @center_freq: Pointer to center frequency * - * Return: FFt bin count + * Return: QDF_STATUS */ -static int -target_if_get_fft_bin_count(int fft_len) +static QDF_STATUS +target_if_calculate_center_freq(struct target_if_spectral *spectral, + uint16_t chan_freq, + uint16_t *center_freq) { - int bin_count = 0; + struct wlan_objmgr_vdev *vdev; + enum phy_ch_width ch_width; + enum phy_ch_width agile_ch_width; - switch (fft_len) { - case 5: - bin_count = 16; - break; - case 6: - bin_count = 32; - break; - case 7: - bin_count = 64; - break; + if (!spectral) { + spectral_err("spectral target if object is null"); + return QDF_STATUS_E_FAILURE; + } + + if (!center_freq) { + spectral_err("center_freq argument is null"); + return QDF_STATUS_E_FAILURE; + } + + vdev = target_if_spectral_get_vdev(spectral); + if (!vdev) { + spectral_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + ch_width = target_if_vdev_get_ch_width(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + agile_ch_width = target_if_spectral_find_agile_width(ch_width); + + if (agile_ch_width == CH_WIDTH_20MHZ) { + *center_freq = chan_freq; + } else { + uint16_t start_freq; + uint16_t end_freq; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + + wlan_reg_get_5g_bonded_channel_and_state_for_freq + (spectral->pdev_obj, chan_freq, agile_ch_width, + &bonded_chan_ptr); + if (!bonded_chan_ptr) { + spectral_err("Bonded channel is not found"); + return QDF_STATUS_E_FAILURE; + } + start_freq = bonded_chan_ptr->start_freq; + end_freq = bonded_chan_ptr->end_freq; + *center_freq = (start_freq + end_freq) >> 1; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_validate_center_freq() - Helper routine to + * validate user provided agile center frequency + * + * @spectral: Pointer to Spectral object + * @center_freq: User provided agile span center frequency + * @is_valid: Indicates whether agile span center frequency is valid + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_validate_center_freq(struct target_if_spectral *spectral, + uint16_t center_freq, + bool *is_valid) +{ + struct wlan_objmgr_vdev *vdev; + enum phy_ch_width ch_width; + enum phy_ch_width agile_ch_width; + struct wlan_objmgr_pdev *pdev; + QDF_STATUS status; + + if (!spectral) { + spectral_err("spectral target if object is null"); + return QDF_STATUS_E_FAILURE; + } + + if (!is_valid) { + spectral_err("is_valid argument is null"); + return QDF_STATUS_E_FAILURE; + } + + pdev = spectral->pdev_obj; + vdev = target_if_spectral_get_vdev(spectral); + if (!vdev) { + spectral_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + ch_width = target_if_vdev_get_ch_width(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + agile_ch_width = target_if_spectral_find_agile_width(ch_width); + + if (agile_ch_width == CH_WIDTH_20MHZ) { + status = target_if_is_center_freq_of_any_chan + (pdev, center_freq, is_valid); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + } else { + uint16_t start_freq; + uint16_t end_freq; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + bool is_chan; + + status = target_if_is_center_freq_of_any_chan + (pdev, center_freq + FREQ_OFFSET_10MHZ, + &is_chan); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + + if (is_chan) { + uint32_t calulated_center_freq; + + wlan_reg_get_5g_bonded_channel_and_state_for_freq + (pdev, center_freq + FREQ_OFFSET_10MHZ, + agile_ch_width, + &bonded_chan_ptr); + if (!bonded_chan_ptr) { + spectral_err("Bonded channel is not found"); + return QDF_STATUS_E_FAILURE; + } + start_freq = bonded_chan_ptr->start_freq; + end_freq = bonded_chan_ptr->end_freq; + calulated_center_freq = (start_freq + end_freq) >> 1; + *is_valid = (center_freq == calulated_center_freq); + } else { + *is_valid = false; + } + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_is_agile_span_overlap_with_operating_span() - Helper routine to + * check whether agile span overlaps with current operating band. + * + * @spectral: Pointer to Spectral object + * @ss_frequency: Agile span center frequency + * @is_overlapping: Indicates whether Agile span overlaps with operating span + * + * Helper routine to check whether agile span overlaps with current + * operating band. + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_is_agile_span_overlap_with_operating_span + (struct target_if_spectral *spectral, + uint32_t ss_frequency, + bool *is_overlapping) +{ + enum phy_ch_width ch_width; + enum phy_ch_width agile_ch_width; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_pdev *pdev; + int16_t chan_freq; + uint32_t op_start_freq; + uint32_t op_end_freq; + uint32_t agile_start_freq; + uint32_t agile_end_freq; + uint32_t cfreq2; + + if (!spectral) { + spectral_err("Spectral object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + pdev = spectral->pdev_obj; + if (!pdev) { + spectral_err("pdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (!is_overlapping) { + spectral_err("Argument(is_overlapping) is NULL"); + return QDF_STATUS_E_FAILURE; + } + + vdev = target_if_spectral_get_vdev(spectral); + if (!vdev) { + spectral_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + ch_width = target_if_vdev_get_ch_width(vdev); + chan_freq = target_if_vdev_get_chan_freq(vdev); + cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + if (cfreq2 < 0) + return QDF_STATUS_E_FAILURE; + + if (ch_width == CH_WIDTH_20MHZ) { + op_start_freq = chan_freq - FREQ_OFFSET_10MHZ; + op_end_freq = chan_freq + FREQ_OFFSET_10MHZ; + } else { + wlan_reg_get_5g_bonded_channel_and_state_for_freq + (pdev, chan_freq, ch_width, &bonded_chan_ptr); + if (!bonded_chan_ptr) { + spectral_err("Bonded channel is not found"); + return QDF_STATUS_E_FAILURE; + } + op_start_freq = bonded_chan_ptr->start_freq - FREQ_OFFSET_10MHZ; + op_end_freq = bonded_chan_ptr->end_freq - FREQ_OFFSET_10MHZ; + } + + agile_ch_width = target_if_spectral_find_agile_width(ch_width); + if (agile_ch_width == CH_WIDTH_INVALID) + return QDF_STATUS_E_FAILURE; + agile_start_freq = ss_frequency - + (wlan_reg_get_bw_value(agile_ch_width) >> 1); + agile_end_freq = ss_frequency + + (wlan_reg_get_bw_value(agile_ch_width) >> 1); + if (agile_end_freq <= op_start_freq || op_end_freq <= agile_start_freq) + *is_overlapping = false; + else + *is_overlapping = true; + + /* Use non zero cfreq2 to identify 80p80 */ + if (cfreq2) { + uint32_t sec80_start_feq; + uint32_t sec80_end_freq; + + sec80_start_feq = cfreq2 - 40; + sec80_end_freq = cfreq2 + 40; + + if ((agile_end_freq > sec80_start_feq) && + (sec80_end_freq > agile_start_freq)) + *is_overlapping = true; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_spectral_populate_chwidth() - Helper routine to + * populate channel width for different Spectral modes + * + * @spectral: Pointer to Spectral object + * + * Helper routine to populate channel width for different Spectral modes + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) { + struct wlan_objmgr_vdev *vdev; + enum phy_ch_width vdev_ch_with; + + vdev = target_if_spectral_get_vdev(spectral); + if (!vdev) { + spectral_err("vdev is null"); + return QDF_STATUS_E_FAILURE; + } + + vdev_ch_with = target_if_vdev_get_ch_width(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + if (vdev_ch_with == CH_WIDTH_INVALID) { + spectral_err("Invalid channel width %d", vdev_ch_with); + return QDF_STATUS_E_FAILURE; + } + spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] = vdev_ch_with; + spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE] = + target_if_spectral_find_agile_width(vdev_ch_with); + + return QDF_STATUS_SUCCESS; +} + +/** + * _target_if_set_spectral_config() - Set spectral config + * @spectral: Pointer to spectral object + * @threshtype: config type + * @value: config value + * @smode: Spectral scan mode + * @err: Spectral error code + * + * API to set spectral configurations + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure + */ +static QDF_STATUS +_target_if_set_spectral_config(struct target_if_spectral *spectral, + const uint32_t threshtype, const uint32_t value, + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) +{ + struct spectral_config params; + struct target_if_spectral_ops *p_sops; + struct spectral_config *sparams; + QDF_STATUS status; + bool is_overlapping; + uint16_t agile_cfreq; + bool is_valid_chan; + struct spectral_param_min_max *param_min_max; + + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (!spectral) { + spectral_err("spectral object is NULL"); + return QDF_STATUS_E_FAILURE; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + param_min_max = &spectral->param_min_max; + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err("Invalid Spectral mode %u", smode); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + sparams = &spectral->params[smode]; + + if (!spectral->params_valid[smode]) { + target_if_spectral_info_read(spectral, + smode, + TARGET_IF_SPECTRAL_INFO_PARAMS, + &spectral->params[smode], + sizeof(spectral->params[smode])); + spectral->params_valid[smode] = true; + } + + switch (threshtype) { + case SPECTRAL_PARAM_FFT_PERIOD: + sparams->ss_fft_period = value; + break; + case SPECTRAL_PARAM_SCAN_PERIOD: + sparams->ss_period = value; + break; + case SPECTRAL_PARAM_SCAN_COUNT: + sparams->ss_count = value; + break; + case SPECTRAL_PARAM_SHORT_REPORT: + sparams->ss_short_report = (!!value) ? true : false; + break; + case SPECTRAL_PARAM_SPECT_PRI: + sparams->ss_spectral_pri = (!!value) ? true : false; + break; + case SPECTRAL_PARAM_FFT_SIZE: + status = target_if_spectral_populate_chwidth(spectral); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + if ((value < param_min_max->fft_size_min) || + (value > param_min_max->fft_size_max + [spectral->ch_width[smode]])) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + return QDF_STATUS_E_FAILURE; + } + sparams->ss_fft_size = value; + break; + case SPECTRAL_PARAM_GC_ENA: + sparams->ss_gc_ena = !!value; + break; + case SPECTRAL_PARAM_RESTART_ENA: + sparams->ss_restart_ena = !!value; + break; + case SPECTRAL_PARAM_NOISE_FLOOR_REF: + sparams->ss_noise_floor_ref = value; + break; + case SPECTRAL_PARAM_INIT_DELAY: + sparams->ss_init_delay = value; + break; + case SPECTRAL_PARAM_NB_TONE_THR: + sparams->ss_nb_tone_thr = value; + break; + case SPECTRAL_PARAM_STR_BIN_THR: + sparams->ss_str_bin_thr = value; + break; + case SPECTRAL_PARAM_WB_RPT_MODE: + sparams->ss_wb_rpt_mode = !!value; + break; + case SPECTRAL_PARAM_RSSI_RPT_MODE: + sparams->ss_rssi_rpt_mode = !!value; + break; + case SPECTRAL_PARAM_RSSI_THR: + sparams->ss_rssi_thr = value; + break; + case SPECTRAL_PARAM_PWR_FORMAT: + sparams->ss_pwr_format = !!value; + break; + case SPECTRAL_PARAM_RPT_MODE: + if ((value < SPECTRAL_PARAM_RPT_MODE_MIN) || + (value > SPECTRAL_PARAM_RPT_MODE_MAX)) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + return QDF_STATUS_E_FAILURE; + } + sparams->ss_rpt_mode = value; + break; + case SPECTRAL_PARAM_BIN_SCALE: + sparams->ss_bin_scale = value; + break; + case SPECTRAL_PARAM_DBM_ADJ: + sparams->ss_dbm_adj = !!value; + break; + case SPECTRAL_PARAM_CHN_MASK: + sparams->ss_chn_mask = value; + break; + case SPECTRAL_PARAM_FREQUENCY: + status = target_if_is_center_freq_of_any_chan + (spectral->pdev_obj, value, &is_valid_chan); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + + if (is_valid_chan) { + status = target_if_calculate_center_freq(spectral, + value, + &agile_cfreq); + if (QDF_IS_STATUS_ERROR(status)) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + return QDF_STATUS_E_FAILURE; + } + } else { + bool is_valid_agile_cfreq; + + status = target_if_validate_center_freq + (spectral, value, &is_valid_agile_cfreq); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + + if (!is_valid_agile_cfreq) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + spectral_err("Invalid agile center frequency"); + return QDF_STATUS_E_FAILURE; + } + + agile_cfreq = value; + } + + status = target_if_is_agile_span_overlap_with_operating_span + (spectral, agile_cfreq, &is_overlapping); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + + if (is_overlapping) { + spectral_err("Agile span overlapping with current BW"); + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + return QDF_STATUS_E_FAILURE; + } + sparams->ss_frequency = agile_cfreq; + break; + } + + p_sops->configure_spectral(spectral, sparams, smode); + /* only to validate the writes */ + p_sops->get_spectral_config(spectral, ¶ms, smode); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, + const uint32_t threshtype, const uint32_t value, + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) +{ + enum spectral_scan_mode mode = SPECTRAL_SCAN_MODE_NORMAL; + struct target_if_spectral *spectral; + QDF_STATUS status; + + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (!pdev) { + spectral_err("pdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("spectral object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err("Invalid Spectral mode %u", smode); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + if (!spectral->properties[smode][threshtype].supported) { + spectral_err("Spectral parameter(%u) unsupported for mode %u", + threshtype, smode); + *err = SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + if (spectral->properties[smode][threshtype].common_all_modes) { + spectral_warn("Setting Spectral parameter %u for all modes", + threshtype); + for (; mode < SPECTRAL_SCAN_MODE_MAX; mode++) { + status = _target_if_set_spectral_config + (spectral, threshtype, value, + mode, err); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; + } + + return _target_if_set_spectral_config(spectral, threshtype, + value, smode, err); +} + +/** + * target_if_get_fft_bin_count() - Get fft bin count for a given fft length + * @fft_len: FFT length + * @pdev: Pointer to pdev object + * + * API to get fft bin count for a given fft length + * + * Return: FFt bin count + */ +static int +target_if_get_fft_bin_count(int fft_len) +{ + int bin_count = 0; + + switch (fft_len) { + case 5: + bin_count = 16; + break; + case 6: + bin_count = 32; + break; + case 7: + bin_count = 64; + break; case 8: bin_count = 128; break; @@ -2343,8 +3093,19 @@ target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return QDF_STATUS_E_FAILURE; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return QDF_STATUS_E_FAILURE; + } + if (smode >= SPECTRAL_SCAN_MODE_MAX) { spectral_err("Invalid Spectral mode %u", smode); return QDF_STATUS_E_FAILURE; @@ -2378,7 +3139,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, int extension_channel = 0; int current_channel = 0; struct target_if_spectral_ops *p_sops = NULL; - struct wlan_objmgr_vdev *vdev = NULL; + QDF_STATUS status; if (!spectral) { spectral_err("Spectral LMAC object is NULL"); @@ -2404,15 +3165,11 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, extension_channel = p_sops->get_extension_channel(spectral); current_channel = p_sops->get_current_channel(spectral); - vdev = target_if_spectral_get_vdev(spectral); - if (!vdev) - return 1; - - spectral->ch_width = target_if_vdev_get_ch_width(vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); - - if (spectral->ch_width == CH_WIDTH_INVALID) + status = target_if_spectral_populate_chwidth(spectral); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to get channel widths"); return 1; + } if (spectral->capability.advncd_spectral_cap) { spectral->lb_edge_extrabins = 0; @@ -2428,7 +3185,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, spectral->rb_edge_extrabins = 4; } - if (spectral->ch_width == CH_WIDTH_20MHZ) { + if (spectral->ch_width[smode] == CH_WIDTH_20MHZ) { spectral->sc_spectral_20_40_mode = 0; spectral->spectral_numbins = @@ -2448,7 +3205,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, current_channel; spectral->classifier_params.upper_chan_in_mhz = 0; - } else if (spectral->ch_width == CH_WIDTH_40MHZ) { + } else if (spectral->ch_width[smode] == CH_WIDTH_40MHZ) { /* TODO : Remove this variable */ spectral->sc_spectral_20_40_mode = 1; spectral->spectral_numbins = @@ -2477,7 +3234,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, extension_channel; } - } else if (spectral->ch_width == CH_WIDTH_80MHZ) { + } else if (spectral->ch_width[smode] == CH_WIDTH_80MHZ) { /* Set the FFT Size */ /* TODO : Remove this variable */ spectral->sc_spectral_20_40_mode = 0; @@ -2515,7 +3272,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, extension_channel; } - } else if (spectral->ch_width == CH_WIDTH_160MHZ) { + } else if (spectral->ch_width[smode] == CH_WIDTH_160MHZ) { /* Set the FFT Size */ /* The below applies to both 160 and 80+80 cases */ @@ -2652,9 +3409,8 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, if (!p_sops->is_spectral_active(spectral, smode)) { p_sops->configure_spectral(spectral, spectral_params, smode); p_sops->start_spectral_scan(spectral, smode, err); - spectral->timestamp_war_offset = 0; - spectral->last_fft_timestamp = 0; - } else { + spectral->timestamp_war.timestamp_war_offset[smode] = 0; + spectral->timestamp_war.last_fft_timestamp[smode] = 0; } /* get current spectral configuration */ @@ -2665,13 +3421,284 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, return 0; } +/** + * target_if_is_aspectral_prohibited_by_adfs() - Is Agile Spectral prohibited by + * Agile DFS + * @psoc: Pointer to psoc + * @object: Pointer to pdev + * @arg: Pointer to flag which indicates whether Agile Spectral is prohibited + * + * This API checks whether Agile DFS is running on any of the pdevs. If so, it + * indicates that Agile Spectral scan is prohibited by Agile DFS. + * + * Return: void + */ +static void +target_if_is_aspectral_prohibited_by_adfs(struct wlan_objmgr_psoc *psoc, + void *object, void *arg) +{ + bool *is_aspectral_prohibited = arg; + struct wlan_objmgr_pdev *cur_pdev = object; + bool is_agile_dfs_enabled_cur_pdev = false; + QDF_STATUS status; + + qdf_assert_always(is_aspectral_prohibited); + if (*is_aspectral_prohibited) + return; + + qdf_assert_always(psoc); + qdf_assert_always(cur_pdev); + + status = ucfg_dfs_get_agile_precac_enable + (cur_pdev, + &is_agile_dfs_enabled_cur_pdev); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Get agile precac failed, prohibiting aSpectral"); + *is_aspectral_prohibited = true; + return; + } + + if (is_agile_dfs_enabled_cur_pdev) { + spectral_err("aDFS is in progress on one of the pdevs"); + *is_aspectral_prohibited = true; + } +} + +/** + * target_if_get_curr_band() - Get current operating band of pdev + * + * @spectral: pointer to spectral object + * + * API to get current operating band of a given pdev. + * + * Return: if success enum reg_wifi_band, REG_BAND_UNKNOWN in case of failure + */ +static enum reg_wifi_band +target_if_get_curr_band(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_vdev *vdev; + int16_t chan_freq; + enum reg_wifi_band cur_band; + + if (!pdev) { + spectral_err("pdev is NULL"); + return REG_BAND_UNKNOWN; + } + + vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_SPECTRAL_ID); + if (!vdev) { + spectral_debug("vdev is NULL"); + return REG_BAND_UNKNOWN; + } + chan_freq = target_if_vdev_get_chan_freq(vdev); + cur_band = wlan_reg_freq_to_band(chan_freq); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + + return cur_band; +} + +/** + * target_if_is_agile_scan_active_in_5g() - Is Agile Spectral scan active on + * any of the 5G pdevs + * @psoc: Pointer to psoc + * @object: Pointer to pdev + * @arg: Pointer to flag which indicates whether Agile Spectral scan is in + * progress in any 5G pdevs + * + * Return: void + */ +static void +target_if_is_agile_scan_active_in_5g(struct wlan_objmgr_psoc *psoc, + void *object, void *arg) +{ + enum reg_wifi_band band; + bool *is_agile_scan_inprog_5g_pdev = arg; + struct target_if_spectral *spectral; + struct wlan_objmgr_pdev *cur_pdev = object; + struct target_if_spectral_ops *p_sops; + + if (*is_agile_scan_inprog_5g_pdev) + return; + + spectral = get_target_if_spectral_handle_from_pdev(cur_pdev); + if (!spectral) { + spectral_err("target if spectral handle is NULL"); + return; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + + band = target_if_get_curr_band(cur_pdev); + if (band == REG_BAND_UNKNOWN) { + spectral_debug("Failed to get current band"); + return; + } + + if (band == REG_BAND_5G && + p_sops->is_spectral_active(spectral, SPECTRAL_SCAN_MODE_AGILE)) + *is_agile_scan_inprog_5g_pdev = true; +} + +/** + * target_if_is_agile_supported_cur_chmask() - Is Agile Spectral scan supported + * for current vdev rx chainmask. + * + * @spectral: Pointer to Spectral object + * @is_supported: Pointer to is_supported + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure + */ +static QDF_STATUS +target_if_is_agile_supported_cur_chmask(struct target_if_spectral *spectral, + bool *is_supported) +{ + struct wlan_objmgr_vdev *vdev; + uint8_t vdev_rxchainmask; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + struct target_psoc_info *tgt_psoc_info; + struct wlan_psoc_host_service_ext_param *ext_svc_param; + struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr = NULL; + struct wlan_psoc_host_mac_phy_caps *mac_phy_cap = NULL; + struct wlan_psoc_host_chainmask_table *table; + int j; + uint32_t table_id; + enum phy_ch_width ch_width; + uint8_t pdev_id; + + if (!spectral) { + spectral_err("spectral target if object is null"); + return QDF_STATUS_E_FAILURE; + } + + if (!is_supported) { + spectral_err("is supported argument is null"); + return QDF_STATUS_E_FAILURE; + } + + if (spectral->spectral_gen <= SPECTRAL_GEN2) { + spectral_err("HW Agile mode is not supported up to gen 2"); + return QDF_STATUS_E_FAILURE; + } + + pdev = spectral->pdev_obj; + if (!pdev) { + spectral_err("pdev is null"); + return QDF_STATUS_E_FAILURE; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_FAILURE; + } + + vdev = target_if_spectral_get_vdev(spectral); + if (!vdev) { + spectral_err("First vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + + vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev); + if (!vdev_rxchainmask) { + spectral_err("vdev rx chainmask is zero"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + return QDF_STATUS_E_FAILURE; + } + + ch_width = target_if_vdev_get_ch_width(vdev); + if (ch_width == CH_WIDTH_INVALID) { + spectral_err("Invalid channel width"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + return QDF_STATUS_E_FAILURE; + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); + + tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); + if (!tgt_psoc_info) { + spectral_err("target_psoc_info is null"); + return QDF_STATUS_E_FAILURE; + } + + ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info); + if (!ext_svc_param) { + spectral_err("Extended service ready param null"); + return QDF_STATUS_E_FAILURE; + } + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + + mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_psoc_info); + if (!mac_phy_cap_arr) { + spectral_err("mac phy cap array is null"); + return QDF_STATUS_E_FAILURE; + } + + mac_phy_cap = &mac_phy_cap_arr[pdev_id]; + if (!mac_phy_cap) { + spectral_err("mac phy cap is null"); + return QDF_STATUS_E_FAILURE; + } + + table_id = mac_phy_cap->chainmask_table_id; + table = &ext_svc_param->chainmask_table[table_id]; + if (!table) { + spectral_err("chainmask table not found"); + return QDF_STATUS_E_FAILURE; + } + + for (j = 0; j < table->num_valid_chainmasks; j++) { + if (table->cap_list[j].chainmask == vdev_rxchainmask) { + if (ch_width <= CH_WIDTH_80MHZ) + *is_supported = + table->cap_list[j].supports_aSpectral; + else + *is_supported = + table->cap_list[j].supports_aSpectral_160; + break; + } + } + + if (j == table->num_valid_chainmasks) { + spectral_err("vdev rx chainmask %u not found in table id = %u", + vdev_rxchainmask, table_id); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode, enum spectral_cp_error_code *err) { - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; + struct target_if_spectral_ops *p_sops; + struct target_if_spectral *spectral; + struct wlan_objmgr_psoc *psoc; + enum reg_wifi_band band; + + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (!pdev) { + spectral_err("pdev object is NUll"); + return QDF_STATUS_E_FAILURE; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_FAILURE; + } + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + spectral_err("Invalid Spectral mode %u", smode); + return QDF_STATUS_E_FAILURE; + } spectral = get_target_if_spectral_handle_from_pdev(pdev); if (!spectral) { @@ -2679,12 +3706,97 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_FAILURE; } - if (smode >= SPECTRAL_SCAN_MODE_MAX) { - spectral_err("Invalid Spectral mode %u", smode); - return QDF_STATUS_E_FAILURE; + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return QDF_STATUS_E_FAILURE; + } + + if (smode == SPECTRAL_SCAN_MODE_AGILE) { + QDF_STATUS status; + bool is_supported = false; + + status = target_if_is_agile_supported_cur_chmask(spectral, + &is_supported); + if (QDF_IS_STATUS_ERROR(status)) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + if (!is_supported) { + spectral_err("aSpectral unsupported for cur chainmask"); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + } + + band = target_if_get_curr_band(spectral->pdev_obj); + if (band == REG_BAND_UNKNOWN) { + spectral_err("Failed to get current band"); + return QDF_STATUS_E_FAILURE; + } + if ((band == REG_BAND_5G) && (smode == SPECTRAL_SCAN_MODE_AGILE)) { + struct target_psoc_info *tgt_hdl; + enum wmi_host_hw_mode_config_type mode; + bool is_agile_scan_inprog_5g_pdev; + + if (p_sops->is_spectral_active(spectral, + SPECTRAL_SCAN_MODE_AGILE)) { + spectral_err("Agile Scan in progress in current pdev"); + return QDF_STATUS_E_FAILURE; + } + + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); + if (!tgt_hdl) { + target_if_err("target_psoc_info is null"); + return QDF_STATUS_E_FAILURE; + } + + mode = target_psoc_get_preferred_hw_mode(tgt_hdl); + switch (mode) { + case WMI_HOST_HW_MODE_SBS_PASSIVE: + case WMI_HOST_HW_MODE_SBS: + case WMI_HOST_HW_MODE_DBS_SBS: + case WMI_HOST_HW_MODE_DBS_OR_SBS: + is_agile_scan_inprog_5g_pdev = false; + wlan_objmgr_iterate_obj_list + (psoc, WLAN_PDEV_OP, + target_if_is_agile_scan_active_in_5g, + &is_agile_scan_inprog_5g_pdev, 0, + WLAN_SPECTRAL_ID); + break; + default: + is_agile_scan_inprog_5g_pdev = false; + break; + } + + if (is_agile_scan_inprog_5g_pdev) { + spectral_err("Agile Scan in progress in one of the SBS 5G pdev"); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } } - p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (smode == SPECTRAL_SCAN_MODE_AGILE) { + bool is_aspectral_prohibited = false; + QDF_STATUS status; + + status = wlan_objmgr_iterate_obj_list + (psoc, WLAN_PDEV_OP, + target_if_is_aspectral_prohibited_by_adfs, + &is_aspectral_prohibited, 0, + WLAN_SPECTRAL_ID); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to iterate over pdevs"); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + if (is_aspectral_prohibited) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + } if (!spectral->params_valid[smode]) { target_if_spectral_info_read(spectral, @@ -2696,6 +3808,33 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, } qdf_spin_lock(&spectral->spectral_lock); + if (smode == SPECTRAL_SCAN_MODE_AGILE && + !spectral->params[smode].ss_frequency) { + *err = SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED; + qdf_spin_unlock(&spectral->spectral_lock); + return QDF_STATUS_E_FAILURE; + } + + if (smode == SPECTRAL_SCAN_MODE_AGILE) { + QDF_STATUS status; + bool is_overlapping; + + status = target_if_is_agile_span_overlap_with_operating_span + (spectral, + spectral->params[smode].ss_frequency, + &is_overlapping); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_spin_unlock(&spectral->spectral_lock); + return QDF_STATUS_E_FAILURE; + } + + if (is_overlapping) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + qdf_spin_unlock(&spectral->spectral_lock); + return QDF_STATUS_E_FAILURE; + } + } + target_if_spectral_scan_enable_params(spectral, &spectral->params[smode], smode, err); @@ -2706,23 +3845,36 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode) + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) { - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; + struct target_if_spectral_ops *p_sops; + struct target_if_spectral *spectral; - spectral = get_target_if_spectral_handle_from_pdev(pdev); - if (!spectral) { - spectral_err("Spectral LMAC object is NUll "); + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); return QDF_STATUS_E_FAILURE; } - p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + *err = SPECTRAL_SCAN_ERR_INVALID; if (smode >= SPECTRAL_SCAN_MODE_MAX) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; spectral_err("Invalid Spectral mode %u", smode); return QDF_STATUS_E_FAILURE; } + if (!pdev) { + spectral_err("pdev object is NUll "); + return QDF_STATUS_E_FAILURE; + } + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral LMAC object is NUll "); + return QDF_STATUS_E_FAILURE; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + qdf_spin_lock(&spectral->spectral_lock); p_sops->stop_spectral_scan(spectral, smode); if (spectral->classify_scan) { @@ -2759,8 +3911,19 @@ target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev, struct target_if_spectral_ops *p_sops = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return QDF_STATUS_E_FAILURE; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return QDF_STATUS_E_FAILURE; + } + if (smode >= SPECTRAL_SCAN_MODE_MAX) { spectral_err("Invalid Spectral mode %u", smode); return QDF_STATUS_E_FAILURE; @@ -2786,8 +3949,19 @@ target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, struct target_if_spectral_ops *p_sops = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return QDF_STATUS_E_FAILURE; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return QDF_STATUS_E_FAILURE; + } + if (smode >= SPECTRAL_SCAN_MODE_MAX) { spectral_err("Invalid Spectral mode %u", smode); return QDF_STATUS_E_FAILURE; @@ -2796,6 +3970,251 @@ target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, return p_sops->is_spectral_enabled(spectral, smode); } +#ifdef DIRECT_BUF_RX_DEBUG +/** + * target_if_spectral_do_dbr_ring_debug() - Start/Stop Spectral DMA ring debug + * @pdev: Pointer to pdev object + * @enable: Enable/Disable Spectral DMA ring debug + * + * Start/stop Spectral DMA ring debug based on @enable. + * Also save the state for future use. + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_do_dbr_ring_debug(struct wlan_objmgr_pdev *pdev, bool enable) +{ + struct target_if_spectral *spectral; + struct wlan_lmac_if_tx_ops *tx_ops; + struct wlan_objmgr_psoc *psoc; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* Save the state */ + spectral->dbr_ring_debug = enable; + + if (enable) + return tx_ops->dbr_tx_ops.direct_buf_rx_start_ring_debug( + pdev, 0, SPECTRAL_DBR_RING_DEBUG_SIZE); + else + return tx_ops->dbr_tx_ops.direct_buf_rx_stop_ring_debug( + pdev, 0); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_spectral_do_dbr_buff_debug() - Start/Stop Spectral DMA buffer debug + * @pdev: Pointer to pdev object + * @enable: Enable/Disable Spectral DMA buffer debug + * + * Start/stop Spectral DMA buffer debug based on @enable. + * Also save the state for future use. + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_do_dbr_buff_debug(struct wlan_objmgr_pdev *pdev, bool enable) +{ + struct target_if_spectral *spectral; + struct wlan_lmac_if_tx_ops *tx_ops; + struct wlan_objmgr_psoc *psoc; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* Save the state */ + spectral->dbr_buff_debug = enable; + + if (enable) + return tx_ops->dbr_tx_ops.direct_buf_rx_start_buffer_poisoning( + pdev, 0, MEM_POISON_SIGNATURE); + else + return tx_ops->dbr_tx_ops.direct_buf_rx_stop_buffer_poisoning( + pdev, 0); +} + +/** + * target_if_spectral_check_and_do_dbr_buff_debug() - Start/Stop Spectral buffer + * debug based on the previous state + * @pdev: Pointer to pdev object + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_check_and_do_dbr_buff_debug(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->dbr_buff_debug) + return target_if_spectral_do_dbr_buff_debug(pdev, true); + else + return target_if_spectral_do_dbr_buff_debug(pdev, false); +} + +/** + * target_if_spectral_check_and_do_dbr_ring_debug() - Start/Stop Spectral ring + * debug based on the previous state + * @pdev: Pointer to pdev object + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_check_and_do_dbr_ring_debug(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->dbr_ring_debug) + return target_if_spectral_do_dbr_ring_debug(pdev, true); + else + return target_if_spectral_do_dbr_ring_debug(pdev, false); +} + +/** + * target_if_spectral_set_dma_debug() - Set DMA debug for Spectral + * @pdev: Pointer to pdev object + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @debug_value: Value to be set for @dma_debug_type + * + * Set DMA debug for Spectral and start/stop Spectral DMA debug function + * based on @debug_value + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_set_dma_debug( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool debug_value) +{ + struct target_if_spectral_ops *p_sops; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_tx_ops *tx_ops; + struct target_if_spectral *spectral; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + if (!tx_ops->target_tx_ops.tgt_get_tgt_type) { + spectral_err("Unable to fetch target type"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->direct_dma_support) { + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (p_sops->is_spectral_active(spectral, + SPECTRAL_SCAN_MODE_NORMAL) || + p_sops->is_spectral_active(spectral, + SPECTRAL_SCAN_MODE_AGILE)) { + spectral_err("Altering DBR debug config isn't allowed during an ongoing scan"); + return QDF_STATUS_E_FAILURE; + } + + switch (dma_debug_type) { + case SPECTRAL_DMA_RING_DEBUG: + target_if_spectral_do_dbr_ring_debug(pdev, debug_value); + break; + + case SPECTRAL_DMA_BUFFER_DEBUG: + target_if_spectral_do_dbr_buff_debug(pdev, debug_value); + break; + + default: + spectral_err("Unsupported DMA debug type : %d", + dma_debug_type); + return QDF_STATUS_E_FAILURE; + } + } + return QDF_STATUS_SUCCESS; +} +#endif /* DIRECT_BUF_RX_DEBUG */ + +/** + * target_if_spectral_direct_dma_support() - Get Direct-DMA support + * @pdev: Pointer to pdev object + * + * Return: Whether Direct-DMA is supported on this radio + */ +static bool +target_if_spectral_direct_dma_support(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return false; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral LMAC object is NULL"); + return false; + } + return spectral->direct_dma_support; +} + /** * target_if_set_debug_level() - Set debug level for Spectral * @pdev: Pointer to pdev object @@ -2843,6 +4262,11 @@ target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev, struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(scaps, &spectral->capability, sizeof(struct spectral_caps)); @@ -2865,6 +4289,11 @@ target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(stats, &spectral->diag_stats, sizeof(struct spectral_diag_stats)); @@ -2884,13 +4313,14 @@ void target_if_register_wmi_spectral_cmd_ops(struct wlan_objmgr_pdev *pdev, struct wmi_spectral_cmd_ops *cmd_ops) { - struct target_if_spectral *spectral = NULL; + struct target_if_spectral *spectral = + get_target_if_spectral_handle_from_pdev(pdev); - spectral = get_target_if_spectral_handle_from_pdev(pdev); - spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send = - cmd_ops->wmi_spectral_configure_cmd_send; - spectral->param_wmi_cmd_ops.wmi_spectral_enable_cmd_send = - cmd_ops->wmi_spectral_enable_cmd_send; + if (!spectral) { + spectral_err("Spectral LMAC object is null"); + return; + } + spectral->param_wmi_cmd_ops = *cmd_ops; } /** @@ -2908,6 +4338,12 @@ target_if_register_netlink_cb( struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return; + } + qdf_mem_copy(&spectral->nl_cb, nl_cb, sizeof(struct spectral_nl_cb)); if (spectral->use_nl_bcast) @@ -2929,6 +4365,12 @@ target_if_use_nl_bcast(struct wlan_objmgr_pdev *pdev) struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return false; + } + return spectral->use_nl_bcast; } @@ -2960,11 +4402,42 @@ target_if_process_spectral_report(struct wlan_objmgr_pdev *pdev, struct target_if_spectral_ops *p_sops = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return -EPERM; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return -EPERM; + } + return p_sops->process_spectral_report(pdev, payload); } +#ifdef DIRECT_BUF_RX_DEBUG +static inline void +target_if_sptrl_debug_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + if (!tx_ops) + return; + + tx_ops->sptrl_tx_ops.sptrlto_set_dma_debug = + target_if_spectral_set_dma_debug; + tx_ops->sptrl_tx_ops.sptrlto_check_and_do_dbr_ring_debug = + target_if_spectral_check_and_do_dbr_ring_debug; + tx_ops->sptrl_tx_ops.sptrlto_check_and_do_dbr_buff_debug = + target_if_spectral_check_and_do_dbr_buff_debug; +} +#else +static inline void +target_if_sptrl_debug_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif + void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { @@ -3001,7 +4474,10 @@ target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) tx_ops->sptrl_tx_ops.sptrlto_deregister_netlink_cb = target_if_deregister_netlink_cb; tx_ops->sptrl_tx_ops.sptrlto_process_spectral_report = - target_if_process_spectral_report; + target_if_process_spectral_report; + tx_ops->sptrl_tx_ops.sptrlto_direct_dma_support = + target_if_spectral_direct_dma_support; + target_if_sptrl_debug_register_tx_ops(tx_ops); } qdf_export_symbol(target_if_sptrl_register_tx_ops); @@ -3014,6 +4490,18 @@ target_if_spectral_send_intf_found_msg(struct wlan_objmgr_pdev *pdev, struct target_if_spectral *spectral = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + + if (!spectral) { + spectral_err("SPECTRAL : Module doesn't exist"); + return; + } + + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (!p_sops) { + spectral_err("p_sops is null"); + return; + } + msg = (struct spectral_samp_msg *)spectral->nl_cb.get_sbuff( spectral->pdev_obj, SPECTRAL_MSG_INTERFERENCE_NOTIFICATION, @@ -3024,7 +4512,6 @@ target_if_spectral_send_intf_found_msg(struct wlan_objmgr_pdev *pdev, SPECTRAL_DCS_INT_CW : SPECTRAL_DCS_INT_WIFI; msg->dcs_enabled = dcs_enabled; msg->signature = SPECTRAL_SIGNATURE; - p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); p_sops->get_mac_address(spectral, msg->macaddr); if (spectral->send_phy_data (pdev, diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.h b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.h index 9ec90a10f89182ff42ed3a180492ef8e747f3ac5..7d651c883f78fcb3b2faf2934a0e5dca397294fd 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -41,6 +41,7 @@ #include +#define FREQ_OFFSET_10MHZ 10 #ifndef SPECTRAL_USE_NL_BCAST #define SPECTRAL_USE_NL_BCAST (0) #endif @@ -80,12 +81,16 @@ #define OFFSET_CH_WIDTH_160 50 /* Min and max for relevant Spectral params */ -#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) -#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) -#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) -#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3 (9) -#define SPECTRAL_PARAM_RPT_MODE_MIN (0) -#define SPECTRAL_PARAM_RPT_MODE_MAX (3) +#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) +#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT (9) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000 (10) +#define SPECTRAL_PARAM_RPT_MODE_MIN (0) +#define SPECTRAL_PARAM_RPT_MODE_MAX (3) + +/* DBR ring debug size for Spectral */ +#define SPECTRAL_DBR_RING_DEBUG_SIZE 512 #ifdef BIG_ENDIAN_HOST #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ @@ -109,6 +114,8 @@ /* Mask for time stamp from descriptor */ #define SPECTRAL_TSMASK 0xFFFFFFFF #define SPECTRAL_SIGNATURE 0xdeadbeef +/* Signature to write onto spectral buffer and then later validate */ +#define MEM_POISON_SIGNATURE (htobe32(0xdeadbeef)) /* START of spectral GEN II HW specific details */ #define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb @@ -238,12 +245,28 @@ struct spectral_phyerr_fft_gen2 { (((value) >= (1 << ((width) - 1))) ? \ (value - (1 << (width))) : (value)) -#define SSCAN_REPORT_DETECTOR_ID_POS_GEN3 (29) -#define SSCAN_REPORT_DETECTOR_ID_SIZE_GEN3 (2) -#define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) -#define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) -#define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) -#define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) +#define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_POS_GEN3 (29) +#define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3 (2) +#define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_POS_GEN3 (0) +#define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_SIZE_GEN3 (8) +#define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_POS_GEN3 (18) +#define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3 (10) +#define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3 (31) +#define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3 (1) +#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1 (30) +#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1 (1) +#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2 (16) +#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2 (1) + +#define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) +#define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) +#define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) +#define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) + +#define FFT_REPORT_HEADER_LENGTH_GEN3_V2 (24) +#define FFT_REPORT_HEADER_LENGTH_GEN3_V1 (16) +#define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1 (0) +#define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2 (16) #define PHYERR_HDR_SIG_POS \ (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig)) @@ -337,15 +360,21 @@ struct spectral_phyerr_fft_report_gen3 { * @sscan_gainchange: This bit is set to 1 if a gainchange occurred during * the spectral scan FFT. Software may choose to * disregard the results. + * @sscan_pri80: This is set to 1 to indicate that the Spectral scan was + * performed on the pri80 segment. Software may choose to + * disregard the FFT sample if this is set to 1 but detector ID + * does not correspond to the ID for the pri80 segment. */ struct sscan_report_fields_gen3 { uint8_t sscan_agc_total_gain; int16_t inband_pwr_db; uint8_t sscan_gainchange; + uint8_t sscan_pri80; }; /** - * struct spectral_sscan_report_gen3 - spectral report in phyerr event + * struct spectral_sscan_summary_report_gen3 - Spectral summary report + * event * @sscan_timestamp: Timestamp at which fft report was generated * @sscan_hdr_sig: signature * @sscan_hdr_tag: tag @@ -353,9 +382,9 @@ struct sscan_report_fields_gen3 { * @hdr_a: Header[0:31] * @resv: Header[32:63] * @hdr_b: Header[64:95] - * @resv: Header[96:127] + * @hdr_c: Header[96:127] */ -struct spectral_sscan_report_gen3 { +struct spectral_sscan_summary_report_gen3 { u_int32_t sscan_timestamp; #ifdef BIG_ENDIAN_HOST u_int8_t sscan_hdr_sig; @@ -369,7 +398,7 @@ struct spectral_sscan_report_gen3 { u_int32_t hdr_a; u_int32_t res1; u_int32_t hdr_b; - u_int32_t res2; + u_int32_t hdr_c; } __ATTRIB_PACK; #ifdef DIRECT_BUF_RX_ENABLE @@ -417,6 +446,89 @@ enum spectral_fftbin_size_war { SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2, }; +/** + * enum spectral_report_format_version - This represents the report format + * version number within each Spectral generation. + * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1 + * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2 + */ +enum spectral_report_format_version { + SPECTRAL_REPORT_FORMAT_VERSION_1, + SPECTRAL_REPORT_FORMAT_VERSION_2, +}; + +/** + * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for + * Spectral FFT bin length adjusting software WARS. + * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for + * in-band report format. This would be required on some chipsets under the + * following circumstances: In report mode 2 only the in-band bins are DMA'ed. + * Scatter/gather is used. However, the HW generates all bins, not just in-band, + * and reports the number of bins accordingly. The subsystem arranging for the + * DMA cannot change this value. On such chipsets the adjustment required at the + * host driver is to check if report format is 2, and if so halve the number of + * bins reported to get the number actually DMA'ed. + * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in + * which only summary of metrics for each completed FFT + spectral scan summary + * report are to be provided. This would be required on some chipsets under the + * following circumstances: In report mode 1, HW reports a length corresponding + * to all bins, and provides bins with value 0. This is because the subsystem + * arranging for the FFT information does not arrange for DMA of FFT bin values + * (as expected), but cannot arrange for a smaller length to be reported by HW. + * In these circumstances, the driver would have to disregard the NULL bins and + * report a bin count of 0 to higher layers. + * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral + * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length + * when packmode is enabled. This SWAR compensates this bug by dividing the + * length with 2. + * @fftbin_size_war: Type of FFT bin size SWAR + */ +struct spectral_fft_bin_len_adj_swar { + u_int8_t inband_fftbin_size_adj; + u_int8_t null_fftbin_adj; + uint8_t packmode_fftbin_size_adj; + enum spectral_fftbin_size_war fftbin_size_war; +}; + +/** + * struct spectral_report_params - Parameters related to format of Spectral + * report. + * @version: This represents the report format version number within each + * Spectral generation. + * @ssumaary_padding_bytes: Number of bytes of padding after Spectral summary + * report + * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This + * has to be subtracted from the length field of FFT report to find the length + * of FFT bins. + */ +struct spectral_report_params { + enum spectral_report_format_version version; + uint8_t ssumaary_padding_bytes; + uint8_t fft_report_hdr_len; +}; + +/** + * struct spectral_param_min_max - Spectral parameter minimum and maximum values + * @fft_size_min: Minimum value of fft_size + * @fft_size_max: Maximum value of fft_size for each BW + */ +struct spectral_param_min_max { + uint16_t fft_size_min; + uint16_t fft_size_max[CH_WIDTH_MAX]; +}; + +/** + * struct spectral_timestamp_swar - Spectral time stamp WAR related parameters + * @timestamp_war_offset: Offset to be added to correct timestamp + * @target_reset_count: Number of times target exercised the reset routine + * @last_fft_timestamp: last fft report timestamp + */ +struct spectral_timestamp_war { + uint32_t timestamp_war_offset[SPECTRAL_SCAN_MODE_MAX]; + uint64_t target_reset_count; + uint32_t last_fft_timestamp[SPECTRAL_SCAN_MODE_MAX]; +}; + #if ATH_PERF_PWR_OFFLOAD /** * enum target_if_spectral_info - Enumerations for specifying which spectral @@ -688,16 +800,30 @@ struct vdev_spectral_enable_params; /** * struct wmi_spectral_cmd_ops - structure used holding the operations * related to wmi commands on spectral parameters. - * @wmi_spectral_configure_cmd_send: - * @wmi_spectral_enable_cmd_send: + * @wmi_spectral_configure_cmd_send: Configure Spectral parameters + * @wmi_spectral_enable_cmd_send: Enable/Disable Spectral + * @wmi_spectral_crash_inject: Inject FW crash */ struct wmi_spectral_cmd_ops { QDF_STATUS (*wmi_spectral_configure_cmd_send)( - void *wmi_hdl, - struct vdev_spectral_configure_params *param); + wmi_unified_t wmi_hdl, + struct vdev_spectral_configure_params *param); QDF_STATUS (*wmi_spectral_enable_cmd_send)( - void *wmi_hdl, - struct vdev_spectral_enable_params *param); + wmi_unified_t wmi_hdl, + struct vdev_spectral_enable_params *param); + QDF_STATUS(*wmi_spectral_crash_inject)( + wmi_unified_t wmi_handle, struct crash_inject *param); +}; + +/** + * struct spectral_param_properties - structure holding Spectral + * parameter properties + * @supported: Parameter is supported or not + * @common_all_modes: Parameter should be common for all modes or not + */ +struct spectral_param_properties { + bool supported; + bool common_all_modes; }; /** @@ -705,6 +831,7 @@ struct wmi_spectral_cmd_ops { * @pdev: Pointer to pdev * @spectral_ops: Target if internal Spectral low level operations table * @capability: Spectral capabilities structure + * @properties: Spectral parameter properties per mode * @spectral_lock: Lock used for internal Spectral operations * @spectral_curchan_radindex: Current channel spectral index * @spectral_extchan_radindex: Extension channel spectral index @@ -760,8 +887,7 @@ struct wmi_spectral_cmd_ops { * @chaninfo: Channel statistics * @tsf64: Latest TSF Value * @param_info: Offload architecture Spectral parameter cache information - * @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3 - * respectively + * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode * @diag_stats: Diagnostic statistics * @is_160_format: Indicates whether information provided by HW is in altered * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) @@ -784,30 +910,22 @@ struct wmi_spectral_cmd_ops { * @nl_cb: Netlink callbacks * @use_nl_bcast: Whether to use Netlink broadcast/unicast * @send_phy_data: Send data to the application layer for a particular msg type - * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for - * in-band report format. This would be required on some chipsets under the - * following circumstances: In report mode 2 only the in-band bins are DMA'ed. - * Scatter/gather is used. However, the HW generates all bins, not just in-band, - * and reports the number of bins accordingly. The subsystem arranging for the - * DMA cannot change this value. On such chipsets the adjustment required at the - * host driver is to check if report format is 2, and if so halve the number of - * bins reported to get the number actually DMA'ed. - * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in - * which only summary of metrics for each completed FFT + spectral scan summary - * report are to be provided. This would be required on some chipsets under the - * following circumstances: In report mode 1, HW reports a length corresponding - * to all bins, and provides bins with value 0. This is because the subsystem - * arranging for the FFT information does not arrange for DMA of FFT bin values - * (as expected), but cannot arrange for a smaller length to be reported by HW. - * In these circumstances, the driver would have to disregard the NULL bins and - * report a bin count of 0 to higher layers. - * @last_fft_timestamp: last fft report timestamp - * @timestamp_war_offset: Offset to be added to correct timestamp + * @len_adj_swar: Spectral fft bin length adjustment SWAR related info + * @timestamp_war: Spectral time stamp WAR related info + * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled + * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled + * @direct_dma_support: Whether Direct-DMA is supported on the current radio + * @prev_tstamp: Timestamp of the previously received sample, which has to be + * compared with the current tstamp to check descrepancy + * @rparams: Parameters related to Spectral report structure + * @param_min_max: Spectral parameter's minimum and maximum values */ struct target_if_spectral { struct wlan_objmgr_pdev *pdev_obj; struct target_if_spectral_ops spectral_ops; struct spectral_caps capability; + struct spectral_param_properties + properties[SPECTRAL_SCAN_MODE_MAX][SPECTRAL_PARAM_MAX]; qdf_spinlock_t spectral_lock; int16_t spectral_curchan_radindex; int16_t spectral_extchan_radindex; @@ -887,7 +1005,7 @@ struct target_if_spectral { struct target_if_spectral_param_state_info param_info[SPECTRAL_SCAN_MODE_MAX]; #endif - uint32_t ch_width; + enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX]; struct spectral_diag_stats diag_stats; bool is_160_format; bool is_lb_edge_extrabins_format; @@ -906,15 +1024,15 @@ struct target_if_spectral { bool use_nl_bcast; int (*send_phy_data)(struct wlan_objmgr_pdev *pdev, enum spectral_msg_type smsg_type); - enum spectral_fftbin_size_war fftbin_size_war; - u_int8_t inband_fftbin_size_adj; - u_int8_t null_fftbin_adj; + struct spectral_fft_bin_len_adj_swar len_adj_swar; + struct spectral_timestamp_war timestamp_war; enum spectral_160mhz_report_delivery_state state_160mhz_delivery; - void *spectral_report_cache; - uint32_t last_fft_timestamp; - uint32_t timestamp_war_offset; - uint16_t fft_size_min; - uint16_t fft_size_max; + bool dbr_ring_debug; + bool dbr_buff_debug; + bool direct_dma_support; + uint32_t prev_tstamp; + struct spectral_report_params rparams; + struct spectral_param_min_max param_min_max; }; /** @@ -948,12 +1066,35 @@ struct target_if_spectral { * @freq: Center frequency of primary 20MHz channel in MHz * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz + * @agile_freq: Center frequency in MHz of the entire span across which Agile + * Spectral is carried out. Applicable only for Agile Spectral samples. * @freq_loading: spectral control duty cycles * @noise_floor: current noise floor (except for secondary 80 segment) * @noise_floor_sec80: current noise floor for secondary 80 segment * @interf_list: List of interfernce sources * @classifier_params: classifier parameters * @sc: classifier parameters + * @pri80ind: Indication from hardware that the sample was received on the + * primary 80 MHz segment. If this is set when smode = + * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried out on + * pri80 instead of the Agile frequency due to a channel switch - Software may + * choose to ignore the sample in this case. + * @pri80ind_sec80: Indication from hardware that the sample was received on the + * primary 80 MHz segment instead of the secondary 80 MHz segment due to a + * channel switch - Software may choose to ignore the sample if this is set. + * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz + * Spectral operation. + * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz + * it will be primary 80 segment's timestamp as both primary & secondary + * segment's timestamps are expected to be almost equal + * @timestamp_war_offset: Offset calculated based on reset_delay and + * last_raw_stamp. It will be added to raw_timestamp to get tstamp. + * @raw_timestamp: FFT timestamp reported by HW on primary segment. + * @raw_timestamp_sec80: FFT timestamp reported by HW on secondary 80 segment. + * @reset_delay: Time gap between the last spectral report before reset and the + * end of reset. + * @target_reset_count: Indicates the the number of times the target went + * through reset routine after spectral was enabled. */ struct target_if_samp_msg_params { int8_t rssi; @@ -984,6 +1125,7 @@ struct target_if_samp_msg_params { uint16_t freq; uint16_t vhtop_ch_freq_seg1; uint16_t vhtop_ch_freq_seg2; + uint16_t agile_freq; uint16_t freq_loading; int16_t noise_floor; int16_t noise_floor_sec80; @@ -995,6 +1137,14 @@ struct target_if_samp_msg_params { uint8_t gainchange; uint8_t gainchange_sec80; enum spectral_scan_mode smode; + uint8_t pri80ind; + uint8_t pri80ind_sec80; + uint32_t last_raw_timestamp; + uint32_t timestamp_war_offset; + uint32_t raw_timestamp; + uint32_t raw_timestamp_sec80; + uint32_t reset_delay; + uint32_t target_reset_count; }; #ifdef WLAN_CONV_SPECTRAL_ENABLE @@ -1100,13 +1250,15 @@ void target_if_spectral_send_intf_found_msg( * target_if_stop_spectral_scan() - Stop spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode + * @err: Pointer to error code * * API to stop the current on-going spectral scan * * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE */ QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode); + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); /** * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral @@ -1177,22 +1329,6 @@ int target_if_spectral_dump_phyerr_data_gen2( uint32_t datalen, bool is_160_format); -/** - * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 - * @spectral: Pointer to Spectral object - * @smode: Spectral scan mode - * @p_fft_report: Pointer to fft report - * @p_sfft: Pointer to search fft report - * - * Dump FFT Report for gen3 - * - * Return: Success/Failure - */ -int target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, - enum spectral_scan_mode smode, - struct spectral_phyerr_fft_report_gen3 *p_fft_report, - struct spectral_search_fft_info_gen3 *p_sfft); - /** * target_if_dbg_print_samp_msg() - Print contents of SAMP Message * @p: Pointer to SAMP message @@ -1203,19 +1339,6 @@ int target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, */ void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); -/** - * target_if_process_sfft_report_gen3() - Process Search FFT Report for gen3 - * @p_fft_report: Pointer to fft report - * @p_sfft: Pointer to search fft report - * - * Process Search FFT Report for gen3 - * - * Return: Success/Failure - */ -int target_if_process_sfft_report_gen3( - struct spectral_phyerr_fft_report_gen3 *p_fft_report, - struct spectral_search_fft_info_gen3 *p_fft_info); - /** * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal * Spectral data @@ -1228,10 +1351,19 @@ static inline struct target_if_spectral *get_target_if_spectral_handle_from_pdev( struct wlan_objmgr_pdev *pdev) { - struct target_if_spectral *spectral = NULL; - struct wlan_objmgr_psoc *psoc = NULL; + struct target_if_spectral *spectral; + struct wlan_objmgr_psoc *psoc; + + if (!pdev) { + spectral_err("pdev is null"); + return NULL; + } psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return NULL; + } spectral = (struct target_if_spectral *) psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_get_target_handle( @@ -1263,6 +1395,30 @@ int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) vdev); } +/** + * target_if_vdev_get_chan_freq_seg2() - Get center frequency of secondary 80 of + * given vdev + * @vdev: Pointer to vdev + * + * Get the center frequency of secondary 80 of given vdev + * + * Return: center frequency of secondary 80 + */ +static inline +int16_t target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc = NULL; + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + spectral_err("psoc is NULL"); + return -EINVAL; + } + + return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_chan_freq_seg2( + vdev); +} + /** * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a * given vdev @@ -1346,6 +1502,11 @@ void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, } spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral target if object is null"); + return; + } + /* set chainmask for all the modes */ for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) spectral->params[smode].ss_chn_mask = spectral_rx_chainmask; @@ -1379,6 +1540,11 @@ void target_if_spectral_process_phyerr( struct target_if_spectral_ops *p_sops = NULL; spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral target if object is null"); + return; + } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); if (!p_sops->spectral_process_phyerr) { spectral_err("null spectral_process_phyerr"); @@ -1441,7 +1607,7 @@ reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, enum spectral_msg_type smsg_type; QDF_STATUS ret; - if (spectral->ch_width == CH_WIDTH_160MHZ) { + if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) { spectral->state_160mhz_delivery = SPECTRAL_REPORT_WAIT_PRIMARY80; @@ -1468,7 +1634,7 @@ static inline bool is_secondaryseg_expected(struct target_if_spectral *spectral) { return - ((spectral->ch_width == CH_WIDTH_160MHZ) && + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && (spectral->state_160mhz_delivery == SPECTRAL_REPORT_WAIT_SECONDARY80)); } @@ -1485,8 +1651,8 @@ static inline bool is_primaryseg_expected(struct target_if_spectral *spectral) { return - ((spectral->ch_width != CH_WIDTH_160MHZ) || - ((spectral->ch_width == CH_WIDTH_160MHZ) && + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) || + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && (spectral->state_160mhz_delivery == SPECTRAL_REPORT_WAIT_PRIMARY80))); } @@ -1502,8 +1668,8 @@ static inline bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral) { return - ((spectral->ch_width != CH_WIDTH_160MHZ) || - ((spectral->ch_width == CH_WIDTH_160MHZ) && + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) || + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && ((spectral->spectral_gen == SPECTRAL_GEN2) || ((spectral->spectral_gen == SPECTRAL_GEN3) && (spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_PRIMARY80))))); @@ -1521,7 +1687,7 @@ static inline bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral) { return - ((spectral->ch_width == CH_WIDTH_160MHZ) && + ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && ((spectral->spectral_gen == SPECTRAL_GEN2) || ((spectral->spectral_gen == SPECTRAL_GEN3) && (spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_SECONDARY80)))); @@ -1898,6 +2064,14 @@ target_if_consume_spectral_report_gen3( struct spectral_report *report); #endif +/** + * target_if_spectral_fw_hang() - Crash the FW from Spectral module + * @spectral: Pointer to Spectral LMAC object + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral); + #ifdef WIN32 #pragma pack(pop, target_if_spectral) #endif diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_netlink.c b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_netlink.c index a57746ac73e4e1bf481003c7bd7a572e10c45686..a2be35823b39648447730db5eebeed8946ecfc95 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_netlink.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_netlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -51,6 +51,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, size_t pwr_count_sec80 = 0; enum spectral_msg_type msg_type; QDF_STATUS ret; + struct spectral_fft_bin_len_adj_swar *swar = &spectral->len_adj_swar; ret = target_if_get_spectral_msg_type(params->smode, &msg_type); if (QDF_IS_STATUS_ERROR(ret)) @@ -72,13 +73,24 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, spec_samp_msg->signature = SPECTRAL_SIGNATURE; spec_samp_msg->freq = params->freq; + if (params->smode == SPECTRAL_SCAN_MODE_AGILE) + spec_samp_msg->agile_freq = params->agile_freq; spec_samp_msg->freq_loading = params->freq_loading; samp_data->spectral_mode = params->smode; samp_data->spectral_data_len = params->datalen; samp_data->spectral_rssi = params->rssi; - samp_data->ch_width = spectral->ch_width; + samp_data->ch_width = + spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL]; + samp_data->agile_ch_width = + spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE]; samp_data->spectral_agc_total_gain = params->agc_total_gain; samp_data->spectral_gainchange = params->gainchange; + samp_data->spectral_pri80ind = params->pri80ind; + samp_data->last_raw_timestamp = params->last_raw_timestamp; + samp_data->timestamp_war_offset = params->timestamp_war_offset; + samp_data->raw_timestamp = params->raw_timestamp; + samp_data->reset_delay = params->reset_delay; + samp_data->target_reset_count = params->target_reset_count; samp_data->spectral_combined_rssi = (uint8_t)params->rssi; @@ -138,12 +150,12 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, qdf_mem_copy(cp, pcp, sizeof(struct spectral_classifier_params)); - if (spectral->fftbin_size_war == + if (swar->fftbin_size_war == SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { binptr_32 = (uint32_t *)bin_pwr_data; for (idx = 0; idx < pwr_count; idx++) samp_data->bin_pwr[idx] = *(binptr_32++); - } else if (spectral->fftbin_size_war == + } else if (swar->fftbin_size_war == SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { binptr_16 = (uint16_t *)bin_pwr_data; for (idx = 0; idx < pwr_count; idx++) @@ -179,6 +191,8 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, params->agc_total_gain_sec80; spec_samp_msg->samp_data.spectral_gainchange_sec80 = params->gainchange_sec80; + spec_samp_msg->samp_data.spectral_pri80ind_sec80 = + params->pri80ind_sec80; samp_data->spectral_data_len_sec80 = params->datalen_sec80; @@ -187,6 +201,8 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, samp_data->spectral_max_mag_sec80 = params->max_mag_sec80; + samp_data->raw_timestamp_sec80 = params->raw_timestamp_sec80; + /* * Currently, we compute pwr_count_sec80 considering the size of * the samp_data->bin_pwr_sec80 array rather than the number of @@ -205,12 +221,12 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, samp_data->bin_pwr_count_sec80 = pwr_count_sec80; bin_pwr_data = params->bin_pwr_data_sec80; - if (spectral->fftbin_size_war == + if (swar->fftbin_size_war == SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { binptr_32 = (uint32_t *)bin_pwr_data; for (idx = 0; idx < pwr_count_sec80; idx++) samp_data->bin_pwr_sec80[idx] = *(binptr_32++); - } else if (spectral->fftbin_size_war == + } else if (swar->fftbin_size_war == SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { binptr_16 = (uint16_t *)bin_pwr_data; for (idx = 0; idx < pwr_count_sec80; idx++) @@ -223,7 +239,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, } } - if ((spectral->ch_width != CH_WIDTH_160MHZ) || + if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ || (params->smode == SPECTRAL_SCAN_MODE_AGILE) || is_secondaryseg_rx_inprog(spectral)) { if (spectral->send_phy_data(spectral->pdev_obj, diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_phyerr.c b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_phyerr.c index 95e79df82f84c96a46dbe453e0fb442a9eb6e594..e235149110cbf8252134aedbf155322cdfdc7cf4 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_phyerr.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/spectral/target_if_spectral_phyerr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef DIRECT_BUF_RX_ENABLE #include #endif @@ -35,30 +36,87 @@ extern int spectral_debug_level; #ifdef WLAN_CONV_SPECTRAL_ENABLE +#define SPECTRAL_HEXDUMP_OCTET_PRINT_SIZE (3) +#define SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE (16) +#define SPECTRAL_HEXDUMP_EXTRA_BUFFER_PER_LINE (16) + +/* + * Provision for the expected hexdump line size as follows: + * + * Size per octet multiplied by number of octets per line + * + + * ASCII representation which is equivalent in print size to number of octets + * per line + * + + * Some extra buffer + */ +#define SPECTRAL_HEXDUMP_LINESIZE \ + ((SPECTRAL_HEXDUMP_OCTET_PRINT_SIZE * \ + SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE) + \ + SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE + \ + SPECTRAL_HEXDUMP_EXTRA_BUFFER_PER_LINE) + +/** + * target_if_spectral_hexdump() - Print hexdump of the given buffer + * @_buf: Pointer to buffer + * @_len: Length of the buffer + * + * Print the hexdump of buffer upto given length. Print upto + * SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE per line, followed by the ASCII + * representation of these octets. + */ static inline void target_if_spectral_hexdump(unsigned char *_buf, int _len) { int i, mod; - unsigned char ascii[17]; + unsigned char ascii[SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE + 1]; unsigned char *pc = (_buf); + char hexdump_line[SPECTRAL_HEXDUMP_LINESIZE + 1]; + int loc = 0; + + qdf_mem_zero(hexdump_line, sizeof(hexdump_line)); + + if (_len <= 0) { + spectral_err("buffer len is %d, too short", _len); + return; + } for (i = 0; i < _len; i++) { - mod = i % 16; + mod = i % SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE; + if (!mod) { - if (i) - spectral_debug(" %s\n", ascii); + if (i) { + qdf_assert_always(loc < sizeof(hexdump_line)); + loc += snprintf(&hexdump_line[loc], + sizeof(hexdump_line) - loc, + " %s", ascii); + spectral_debug("%s", hexdump_line); + qdf_mem_zero(hexdump_line, + sizeof(hexdump_line)); + loc = 0; + } } - spectral_debug(" %02x", pc[i]); + + qdf_assert_always(loc < sizeof(hexdump_line)); + loc += snprintf(&hexdump_line[loc], sizeof(hexdump_line) - loc, + " %02x", pc[i]); + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) ascii[mod] = '.'; else ascii[mod] = pc[i]; ascii[(mod) + 1] = '\0'; } - while ((i % 16) != 0) { - spectral_debug(" "); + + while ((i % SPECTRAL_HEXDUMP_NUM_OCTETS_PER_LINE) != 0) { + qdf_assert_always(loc < sizeof(hexdump_line)); + loc += snprintf(&hexdump_line[loc], sizeof(hexdump_line) - loc, + " "); i++; } - spectral_debug(" %s\n", ascii); + + qdf_assert_always(loc < sizeof(hexdump_line)); + snprintf(&hexdump_line[loc], sizeof(hexdump_line) - loc, " %s", ascii); + spectral_debug("%s", hexdump_line); } /** @@ -100,6 +158,21 @@ target_if_spectral_dump_fft(uint8_t *pfft, int fftlen) return 0; } +QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral) +{ + struct crash_inject param; + + if (!spectral) { + spectral_err("Spectral LMAC object is null"); + return QDF_STATUS_E_INVAL; + } + qdf_mem_set(¶m, sizeof(param), 0); + param.type = 1; //RECOVERY_SIM_ASSERT + + return spectral->param_wmi_cmd_ops.wmi_spectral_crash_inject( + GET_WMI_HDL_FROM_PDEV(spectral->pdev_obj), ¶m); +} + void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p) { @@ -899,8 +972,8 @@ target_if_process_phyerr_gen2(struct target_if_spectral *spectral, acs_stats->nfc_ctl_rssi = control_rssi; acs_stats->nfc_ext_rssi = extension_rssi; - if (spectral->is_160_format && - spectral->ch_width == CH_WIDTH_160MHZ) { + if (spectral->is_160_format && spectral->ch_width + [SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) { /* * We expect to see one more Search FFT report, and it * should be equal in size to the current one. @@ -1028,7 +1101,8 @@ target_if_get_combrssi_sec80_seg_gen2( total_gain_db = p_sfft_sec80->total_gain_info; /* Calculate offset */ - offset = target_if_get_offset_swar_sec80(spectral->ch_width); + offset = target_if_get_offset_swar_sec80( + spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL]); /* Calculate RSSI */ comb_rssi = ((avgpwr_db - total_gain_db) + offset); @@ -1126,7 +1200,74 @@ target_if_spectral_dump_phyerr_data_gen2(uint8_t *data, uint32_t datalen, return 0; } -int +#ifdef DIRECT_BUF_RX_ENABLE +/** + * target_if_spectral_get_bin_count_after_len_adj() - Get number of FFT bins in + * Spectral FFT report + * @fft_bin_len: FFT bin length reported by target + * @rpt_mode: Spectral report mode + * @swar: Spectral FFT bin length adjustments SWAR parameters + * + * Get actual number of FFT bins in the FFT report after adjusting the length + * by applying the SWARs for getting correct length. + * + * Return: FFT bin count + */ +static size_t +target_if_spectral_get_bin_count_after_len_adj( + size_t fft_bin_len, uint8_t rpt_mode, + struct spectral_fft_bin_len_adj_swar *swar) +{ + size_t fft_bin_count = fft_bin_len; + + if (rpt_mode == 1 && swar->null_fftbin_adj) { + /* + * No FFT bins are expected. Explicitly set FFT bin + * count to 0. + */ + fft_bin_count = 0; + } else { + /* + * Divide fft bin length by appropriate factor depending + * on the value of fftbin_size_war. + */ + switch (swar->fftbin_size_war) { + case SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE: + fft_bin_count >>= 2; + break; + case SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE: + fft_bin_count >>= 1; + /* Ideally we should be dividing fft bin length + * by 2. Due to a HW bug, actual length is two + * times the expected length. + */ + if (swar->packmode_fftbin_size_adj) + fft_bin_count >>= 1; + break; + case SPECTRAL_FFTBIN_SIZE_NO_WAR: + /* No length adjustment */ + break; + default: + qdf_assert_always(0); + } + + if (rpt_mode == 2 && swar->inband_fftbin_size_adj) + fft_bin_count >>= 1; + } + + return fft_bin_count; +} + +/** + * target_if_process_sfft_report_gen3() - Process Search FFT Report for gen3 + * @p_fft_report: Pointer to fft report + * @p_sfft: Pointer to search fft report + * + * Process Search FFT Report for gen3 + * + * Return: Success/Failure + */ +static int target_if_process_sfft_report_gen3( struct spectral_phyerr_fft_report_gen3 *p_fft_report, struct spectral_search_fft_info_gen3 *p_sfft) @@ -1174,113 +1315,122 @@ target_if_process_sfft_report_gen3( return 0; } -int +/** + * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 + * @spectral: Pointer to Spectral object + * @smode: Spectral scan mode + * @p_fft_report: Pointer to fft report + * @p_sfft: Pointer to search fft report + * + * Dump FFT Report for gen3 + * + * Return: void + */ +static void target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, enum spectral_scan_mode smode, struct spectral_phyerr_fft_report_gen3 *p_fft_report, struct spectral_search_fft_info_gen3 *p_sfft) { - int i = 0; - int fft_mag = 0; - int fft_hdr_length = (p_fft_report->fft_hdr_length * 4); - int report_len = (fft_hdr_length + 8); - int fft_bin_len = (fft_hdr_length - 16); - int fft_bin_len_to_dump = fft_bin_len; - int fft_bin_len_adj = 0; - int fft_bin_len_inband_tfer = 0; - - if ((spectral->params[smode].ss_rpt_mode == 1) && - spectral->null_fftbin_adj) { - /* fft_bin_len_adj is intentionally left at 0. */ - fft_bin_len_to_dump = 0; - } else { - /* - * Divide fft bin length by appropriate factor depending - * on the value of fftbin_size_war. - */ - if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) - fft_bin_len_adj = fft_bin_len >> 2; - else if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { - /* Ideally we should be dividing fft bin length by 2. - * Due to a HW bug, actual length is two times the - * expected length. - */ - fft_bin_len_adj = fft_bin_len >> 2; - } else - fft_bin_len_adj = fft_bin_len; - - if ((spectral->params[smode].ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len_adj >>= 1; - fft_bin_len_inband_tfer = fft_bin_len >> 1; - fft_bin_len_to_dump = fft_bin_len_inband_tfer; - } - } - - spectral_debug("#############################################################"); - spectral_debug("Spectral search fft_report"); - spectral_debug("fft_timestamp = 0x%x\nfft_hdr_length = %d(32 bit words)\nfft_hdr_tag = 0x%x\nfft_hdr_sig = 0x%x", - p_fft_report->fft_timestamp, - p_fft_report->fft_hdr_length, - p_fft_report->fft_hdr_tag, p_fft_report->fft_hdr_sig); - - spectral_debug("Length field in search fft report is %d(0x%x) bytes", + size_t fft_hdr_length = (p_fft_report->fft_hdr_length * 4); + size_t report_len = (fft_hdr_length + 8); + size_t fft_bin_len; + size_t fft_bin_count; + size_t fft_bin_len_inband_tfer = 0; + uint8_t *fft_bin_buf = NULL; + + fft_bin_len = fft_hdr_length - spectral->rparams.fft_report_hdr_len; + fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( + fft_bin_len, + spectral->params[smode].ss_rpt_mode, + &spectral->len_adj_swar); + + if ((spectral->params[smode].ss_rpt_mode == 2) && + spectral->len_adj_swar.inband_fftbin_size_adj) + fft_bin_len_inband_tfer = fft_bin_len >> 1; + + spectral_debug("Spectral FFT Report"); + spectral_debug("fft_timestamp = 0x%x", p_fft_report->fft_timestamp); + spectral_debug("fft_hdr_length = %u(32 bit words)", + p_fft_report->fft_hdr_length); + spectral_debug("fft_hdr_tag = 0x%x", p_fft_report->fft_hdr_tag); + spectral_debug("fft_hdr_sig = 0x%x", p_fft_report->fft_hdr_sig); + + spectral_debug("Length field in search fft report is %zu(0x%zx) bytes", fft_hdr_length, fft_hdr_length); - spectral_debug("Total length of search fft report is %d(0x%x) bytes", + spectral_debug("Total length of search fft report is %zu(0x%zx) bytes", report_len, report_len); - spectral_debug("Target reported fftbins in report is %d(0x%x)", - fft_bin_len, - fft_bin_len); + spectral_debug("Target reported fftbins in report is %zu(0x%zx)", + fft_bin_len, fft_bin_len); if ((spectral->params[smode].ss_rpt_mode == 1) && - spectral->null_fftbin_adj) + spectral->len_adj_swar.null_fftbin_adj) spectral_debug("WAR: Considering number of FFT bins as 0"); else if ((spectral->params[smode].ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - spectral_debug("FW fftbins actually transferred (in-band report mode) " - "%d(0x%x)", - fft_bin_len_inband_tfer, fft_bin_len_inband_tfer); + spectral->len_adj_swar.inband_fftbin_size_adj) { + spectral_debug("FW fftbins actually transferred (in-band report mode) %zu(0x%zx)", + fft_bin_len_inband_tfer, + fft_bin_len_inband_tfer); } - spectral_debug("Actual number of fftbins in report is %d(0x%x)\n", - fft_bin_len_adj, fft_bin_len_adj); - - spectral_debug("fft_detector_id = %u\nfft_num = %u\nfft_radar_check = %u\nfft_peak_sidx = %d\nfft_chn_idx = %u\nfft_base_pwr_db = %u\nfft_total_gain_db = %u\nfft_num_str_bins_ib = %u\nfft_peak_mag = %d\nfft_avgpwr_db = %u\nfft_relpwr_db = %u", - p_sfft->fft_detector_id, - p_sfft->fft_num, - p_sfft->fft_radar_check, - p_sfft->fft_peak_sidx, - p_sfft->fft_chn_idx, - p_sfft->fft_base_pwr_db, - p_sfft->fft_total_gain_db, - p_sfft->fft_num_str_bins_ib, - p_sfft->fft_peak_mag, - p_sfft->fft_avgpwr_db, p_sfft->fft_relpwr_db); - - if (fft_bin_len_to_dump > 0) { + spectral_debug("Actual number of fftbins in report is %zu(0x%zx)", + fft_bin_count, fft_bin_count); + + spectral_debug("fft_detector_id = %u", p_sfft->fft_detector_id); + spectral_debug("fft_num = %u", p_sfft->fft_num); + spectral_debug("fft_radar_check = %u", p_sfft->fft_radar_check); + spectral_debug("fft_peak_sidx = %d", p_sfft->fft_peak_sidx); + spectral_debug("fft_chn_idx = %u", p_sfft->fft_chn_idx); + spectral_debug("fft_base_pwr_db = %u", p_sfft->fft_base_pwr_db); + spectral_debug("fft_total_gain_db = %u", p_sfft->fft_total_gain_db); + spectral_debug("fft_num_str_bins_ib = %u", p_sfft->fft_num_str_bins_ib); + spectral_debug("fft_peak_mag = %d", p_sfft->fft_peak_mag); + spectral_debug("fft_avgpwr_db = %u", p_sfft->fft_avgpwr_db); + spectral_debug("fft_relpwr_db = %u", p_sfft->fft_relpwr_db); + + if (fft_bin_count > 0) { + int idx; + spectral_debug("FFT bins:"); - for (i = 0; i < fft_bin_len_to_dump; i++) { - if (i % 16 == 0) - spectral_debug("\n%d :", i); - fft_mag = - ((uint8_t *)p_fft_report)[SPECTRAL_FFT_BINS_POS + i]; - spectral_debug("%d ", fft_mag); + if (spectral->len_adj_swar.fftbin_size_war == + SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) { + uint32_t *binptr_32 = (uint32_t *)&p_fft_report->buf; + + fft_bin_buf = (uint8_t *)qdf_mem_malloc(MAX_NUM_BINS); + if (!fft_bin_buf) { + spectral_err("Failed to allocate memory"); + return; + } + for (idx = 0; idx < fft_bin_count; idx++) + fft_bin_buf[idx] = *(binptr_32++); + } else if (spectral->len_adj_swar.fftbin_size_war == + SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { + uint16_t *binptr_16 = (uint16_t *)&p_fft_report->buf; + + fft_bin_buf = (uint8_t *)qdf_mem_malloc(MAX_NUM_BINS); + if (!fft_bin_buf) { + spectral_err("Failed to allocate memory"); + return; + } + for (idx = 0; idx < fft_bin_count; idx++) + fft_bin_buf[idx] = *(binptr_16++); + } else { + fft_bin_buf = (uint8_t *)&p_fft_report->buf; } + target_if_spectral_hexdump(fft_bin_buf, fft_bin_count); + if ((spectral->len_adj_swar.fftbin_size_war != + SPECTRAL_FFTBIN_SIZE_NO_WAR) && fft_bin_buf) + qdf_mem_free(fft_bin_buf); } - spectral_debug("\n"); - spectral_debug("#############################################################"); - - return 0; } +#endif QDF_STATUS target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, uint8_t detector_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; - if (spectral->ch_width != CH_WIDTH_160MHZ) + if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) return QDF_STATUS_E_FAILURE; /* agile reports should not be coupled with 160 MHz state machine @@ -1333,47 +1483,84 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, #ifdef DIRECT_BUF_RX_ENABLE /** - * target_if_get_detector_id_sscan_report_gen3() - Get Spectral detector id - * @data: Pointer to Spectral summary report / Spectral - * search FFT report - * - * Get Spectral detector id from Spectral summary report / Spectral - * search FFT report + * target_if_get_detector_id_sscan_summary_report_gen3() - Get Spectral detector + * ID from Spectral summary report + * @data: Pointer to Spectral summary report * - * Return: detector id + * Return: Detector ID */ static uint8_t -target_if_get_detector_id_sscan_report_gen3(uint8_t *data) { - struct spectral_sscan_report_gen3 *psscan_report; +target_if_get_detector_id_sscan_summary_report_gen3(uint8_t *data) { + struct spectral_sscan_summary_report_gen3 *psscan_summary_report; uint8_t detector_id; - psscan_report = (struct spectral_sscan_report_gen3 *)data; - detector_id = get_bitfield(psscan_report->hdr_a, - SSCAN_REPORT_DETECTOR_ID_SIZE_GEN3, - SSCAN_REPORT_DETECTOR_ID_POS_GEN3); + qdf_assert_always(data); + + psscan_summary_report = + (struct spectral_sscan_summary_report_gen3 *)data; + + detector_id = get_bitfield( + psscan_summary_report->hdr_a, + SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3, + SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_POS_GEN3); return detector_id; } /** - * target_if_consume_sscan_report_gen3() - Consume spectral summary report - * @spectral: Pointer to spectral object - * @data: Pointer to spectral summary + * target_if_consume_sscan_summary_report_gen3() - Consume Spectral summary + * report + * @data: Pointer to Spectral summary report + * @fields: Pointer to structure to be populated with extracted fields + * @rparams: Pointer to structure with Spectral report params * - * Consume spectral summary report for gen3 + * Consume Spectral summary report for gen3 * * Return: void */ static void -target_if_consume_sscan_report_gen3(struct target_if_spectral *spectral, - uint8_t *data, - struct sscan_report_fields_gen3 *fields) { - struct spectral_sscan_report_gen3 *psscan_report; - - psscan_report = (struct spectral_sscan_report_gen3 *)data; - fields->sscan_agc_total_gain = get_bitfield(psscan_report->hdr_a, 8, 0); - fields->inband_pwr_db = get_bitfield(psscan_report->hdr_a, 10, 18); - fields->sscan_gainchange = get_bitfield(psscan_report->hdr_b, 1, 30); +target_if_consume_sscan_summary_report_gen3( + uint8_t *data, + struct sscan_report_fields_gen3 *fields, + struct spectral_report_params *rparams) { + struct spectral_sscan_summary_report_gen3 *psscan_summary_report; + + qdf_assert_always(data); + qdf_assert_always(fields); + qdf_assert_always(rparams); + + psscan_summary_report = + (struct spectral_sscan_summary_report_gen3 *)data; + + fields->sscan_agc_total_gain = get_bitfield( + psscan_summary_report->hdr_a, + SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_SIZE_GEN3, + SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_POS_GEN3); + fields->inband_pwr_db = get_bitfield( + psscan_summary_report->hdr_a, + SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3, + SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_POS_GEN3); + fields->sscan_pri80 = get_bitfield( + psscan_summary_report->hdr_a, + SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3, + SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3); + + switch (rparams->version) { + case SPECTRAL_REPORT_FORMAT_VERSION_1: + fields->sscan_gainchange = get_bitfield( + psscan_summary_report->hdr_b, + SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1, + SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1); + break; + case SPECTRAL_REPORT_FORMAT_VERSION_2: + fields->sscan_gainchange = get_bitfield( + psscan_summary_report->hdr_c, + SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2, + SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2); + break; + default: + qdf_assert_always(0); + } } /** @@ -1448,6 +1635,142 @@ target_if_get_spectral_mode(enum spectral_detector_id detector_id, return QDF_STATUS_SUCCESS; } +#ifdef DIRECT_BUF_RX_DEBUG +static void target_if_spectral_check_buffer_poisoning( + struct target_if_spectral *spectral, + struct spectral_report *report, + int num_fft_bins, enum spectral_scan_mode smode) +{ + uint32_t *data; + size_t len; + size_t words_to_check = + sizeof(struct spectral_sscan_summary_report_gen3) >> 2; + bool poisoned_words_found = false; + + if (!spectral) { + spectral_err_rl("Spectral LMAC object is null"); + return; + } + + if (!spectral->dbr_buff_debug) + return; + + if (!report) { + spectral_err_rl("Spectral report is null"); + return; + } + + /* Add search FFT report */ + if (spectral->params[smode].ss_rpt_mode > 0) + words_to_check += + sizeof(struct spectral_phyerr_fft_report_gen3) >> 2; + + /* Now add the number of FFT bins */ + if (spectral->params[smode].ss_rpt_mode > 1) { + /* Caller should take care to pass correct number of FFT bins */ + if (spectral->len_adj_swar.fftbin_size_war == + SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) + words_to_check += num_fft_bins; + else if (spectral->len_adj_swar.fftbin_size_war == + SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) + words_to_check += (num_fft_bins >> 1); + } + + data = (uint32_t *)report->data; + for (len = 0; len < words_to_check; ++len) { + if (*data == MEM_POISON_SIGNATURE) { + spectral_err("Pattern(%x) found in Spectral search FFT report at position %zu in the buffer %pK", + MEM_POISON_SIGNATURE, + (len << 2), report->data); + poisoned_words_found = true; + break; + } + ++data; + } + + /* Crash the FW even if one word is poisoned */ + if (poisoned_words_found) { + spectral_err("Pattern(%x) found in Spectral report, Hex dump of the sfft follows", + MEM_POISON_SIGNATURE); + target_if_spectral_hexdump((unsigned char *)report->data, + words_to_check << 2); + spectral_err("Asserting the FW"); + target_if_spectral_fw_hang(spectral); + } +} + +static void target_if_spectral_verify_ts(struct target_if_spectral *spectral, + uint8_t *buf, uint32_t current_ts) +{ + if (!spectral) { + spectral_err_rl("Spectral LMAC object is null"); + return; + } + + if (!spectral->dbr_buff_debug) + return; + + if (spectral->prev_tstamp) { + if (current_ts == spectral->prev_tstamp) { + spectral_err("Spectral timestamp(%u) in the current buffer(%pK) is equal to the previous timestamp, same report DMAed twice? Asserting the FW", + current_ts, buf); + target_if_spectral_fw_hang(spectral); + } + } + spectral->prev_tstamp = current_ts; +} +#else +static void target_if_spectral_check_buffer_poisoning( + struct target_if_spectral *spectral, + struct spectral_report *report, + int num_fft_bins, enum spectral_scan_mode smode) +{ +} + +static void target_if_spectral_verify_ts(struct target_if_spectral *spectral, + uint8_t *buf, uint32_t current_ts) +{ +} +#endif + +/** + * target_if_spectral_get_adjusted_timestamp() - Adjust Spectral time + * stamp to account for reset in time stamp due to target reset + * @twar: Spectral time stamp WAR related information + * @raw_timestamp: Spectral time stamp reported by target + * @reset_delay: Reset delay at target + * @smode: Spectral scan mode + * + * Correct time stamp to account for reset in time stamp due to target reset + * + * Return: Adjusted time stamp + */ +static uint32_t +target_if_spectral_get_adjusted_timestamp(struct spectral_timestamp_war *twar, + uint32_t raw_timestamp, + uint32_t reset_delay, + enum spectral_scan_mode smode) { + qdf_assert_always(smode < SPECTRAL_SCAN_MODE_MAX); + + if (reset_delay) { + enum spectral_scan_mode m = + SPECTRAL_SCAN_MODE_NORMAL; + + /* Adjust the offset for all the Spectral modes. + * Target will be sending the non zero reset delay for + * the first Spectral report after reset. This delay is + * common for all the Spectral modes. + */ + for (; m < SPECTRAL_SCAN_MODE_MAX; m++) + twar->timestamp_war_offset[m] += (reset_delay + + twar->last_fft_timestamp[m]); + twar->target_reset_count++; + } + twar->last_fft_timestamp[smode] = raw_timestamp; + + return raw_timestamp + twar->timestamp_war_offset[smode]; +} + int target_if_consume_spectral_report_gen3( struct target_if_spectral *spectral, @@ -1478,14 +1801,13 @@ target_if_consume_spectral_report_gen3( * 1. Order of FFT bin values * */ - uint64_t tsf64 = 0; struct target_if_samp_msg_params params = {0}; struct spectral_search_fft_info_gen3 search_fft_info; struct spectral_search_fft_info_gen3 *p_sfft = &search_fft_info; int8_t chn_idx_lowest_enabled = 0; int fft_hdr_length = 0; int report_len = 0; - int fft_bin_len = 0; + size_t fft_bin_count; struct target_if_spectral_ops *p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); struct spectral_phyerr_fft_report_gen3 *p_fft_report; @@ -1493,7 +1815,7 @@ target_if_consume_spectral_report_gen3( uint8_t *data = report->data; struct wlan_objmgr_vdev *vdev; uint8_t vdev_rxchainmask; - struct sscan_report_fields_gen3 sscan_report_fields; + struct sscan_report_fields_gen3 sscan_report_fields = {0}; enum spectral_detector_id detector_id; QDF_STATUS ret; @@ -1507,17 +1829,18 @@ target_if_consume_spectral_report_gen3( goto fail; } - detector_id = target_if_get_detector_id_sscan_report_gen3(data); + detector_id = target_if_get_detector_id_sscan_summary_report_gen3(data); if (detector_id > SPECTRAL_DETECTOR_AGILE) { spectral->diag_stats.spectral_invalid_detector_id++; spectral_err("Invalid detector id %u, expected is 0/1/2", detector_id); goto fail; } - target_if_consume_sscan_report_gen3(spectral, data, - &sscan_report_fields); + target_if_consume_sscan_summary_report_gen3(data, &sscan_report_fields, + &spectral->rparams); /* Advance buf pointer to the search fft report */ - data += sizeof(struct spectral_sscan_report_gen3); + data += sizeof(struct spectral_sscan_summary_report_gen3); + data += spectral->rparams.ssumaary_padding_bytes; if ((detector_id == SPECTRAL_DETECTOR_AGILE) || is_primaryseg_expected(spectral)) { @@ -1526,6 +1849,7 @@ target_if_consume_spectral_report_gen3( params.agc_total_gain = sscan_report_fields.sscan_agc_total_gain; params.gainchange = sscan_report_fields.sscan_gainchange; + params.pri80ind = sscan_report_fields.sscan_pri80; /* Process Spectral search FFT report */ if (target_if_verify_sig_and_tag_gen3( @@ -1570,47 +1894,27 @@ target_if_consume_spectral_report_gen3( goto fail; } - if ((spectral->params[params.smode].ss_rpt_mode == 1) && - spectral->null_fftbin_adj) { - /* - * No FFT bins are expected. Explicitly set FFT bin - * length to 0. - */ - fft_bin_len = 0; - } else { - fft_bin_len = (fft_hdr_length - 16); - - /* - * Divide fft bin length by appropriate factor depending - * on the value of fftbin_size_war. - */ - if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) - fft_bin_len >>= 2; - else if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { - /* Ideally we should be dividing fft bin length - * by 2. Due to a HW bug, actual length is two - * times the expected length. - */ - fft_bin_len >>= 2; - } - if ((spectral->params[params.smode].ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len >>= 1; - } - } - - if (report->reset_delay) { - spectral->timestamp_war_offset += (report->reset_delay + - spectral->last_fft_timestamp); - } - tsf64 = p_sfft->timestamp; - spectral->last_fft_timestamp = p_sfft->timestamp; - tsf64 += spectral->timestamp_war_offset; + fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( + fft_hdr_length - spectral->rparams.fft_report_hdr_len, + spectral->params[params.smode].ss_rpt_mode, + &spectral->len_adj_swar); + + params.last_raw_timestamp = spectral->timestamp_war. + last_fft_timestamp[params.smode]; + params.reset_delay = report->reset_delay; + params.raw_timestamp = p_sfft->timestamp; + params.tstamp = target_if_spectral_get_adjusted_timestamp( + &spectral->timestamp_war, + p_sfft->timestamp, report->reset_delay, + params.smode); + params.timestamp_war_offset = spectral->timestamp_war. + timestamp_war_offset[params.smode]; + params.target_reset_count = spectral->timestamp_war. + target_reset_count; /* Take care of state transitions for 160 MHz and 80p80 */ - if (spectral->ch_width == CH_WIDTH_160MHZ) { + if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == + CH_WIDTH_160MHZ) { ret = target_if_160mhz_delivery_state_change( spectral, detector_id); @@ -1650,6 +1954,10 @@ target_if_consume_spectral_report_gen3( SPECTRAL_FFT_BINS_POS); params.freq = p_sops->get_current_channel(spectral); + if (params.smode == SPECTRAL_SCAN_MODE_AGILE) + params.agile_freq = + spectral->params[params.smode].ss_frequency; + /* * For modes upto VHT80, the noise floor is populated with * the one corresponding @@ -1659,14 +1967,17 @@ target_if_consume_spectral_report_gen3( params.noise_floor = report->noisefloor[chn_idx_lowest_enabled]; params.datalen = (fft_hdr_length * 4); - params.pwr_count = fft_bin_len; - params.tstamp = (tsf64 & SPECTRAL_TSMASK); + params.pwr_count = fft_bin_count; + + target_if_spectral_verify_ts(spectral, report->data, + params.tstamp); } else if (is_secondaryseg_expected(spectral)) { /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ rssi = (sscan_report_fields.inband_pwr_db) >> 1; params.agc_total_gain_sec80 = sscan_report_fields.sscan_agc_total_gain; params.gainchange_sec80 = sscan_report_fields.sscan_gainchange; + params.pri80ind_sec80 = sscan_report_fields.sscan_pri80; /* Process Spectral search FFT report */ if (target_if_verify_sig_and_tag_gen3( @@ -1711,40 +2022,15 @@ target_if_consume_spectral_report_gen3( goto fail; } - if ((spectral->params[params.smode].ss_rpt_mode == 1) && - spectral->null_fftbin_adj) { - /* - * No FFT bins are expected. Explicitly set FFT bin - * length to 0. - */ - fft_bin_len = 0; - } else { - fft_bin_len = (fft_hdr_length - 16); - - /* - * Divide fft bin length by appropriate factor depending - * on the value of fftbin_size_war. - */ - if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE) - fft_bin_len >>= 2; - else if (spectral->fftbin_size_war == - SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE) { - /* Ideally we should be dividing fft bin length - * by 2. Due to a HW bug, actual length is two - * times the expected length. - */ - fft_bin_len >>= 2; - } - - if ((spectral->params[params.smode].ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len >>= 1; - } - } + fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( + fft_hdr_length - spectral->rparams.fft_report_hdr_len, + spectral->params[params.smode].ss_rpt_mode, + &spectral->len_adj_swar); + params.raw_timestamp_sec80 = p_sfft->timestamp; /* Take care of state transitions for 160 MHz and 80p80 */ - if (spectral->ch_width == CH_WIDTH_160MHZ) { + if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == + CH_WIDTH_160MHZ) { ret = target_if_160mhz_delivery_state_change( spectral, detector_id); @@ -1788,7 +2074,7 @@ target_if_consume_spectral_report_gen3( /* params.max_index_sec80 = p_sfft->peak_inx; */ /* XXX Does this definition of datalen *still hold? */ params.datalen_sec80 = fft_hdr_length * 4; - params.pwr_count_sec80 = fft_bin_len; + params.pwr_count_sec80 = fft_bin_count; params.bin_pwr_data_sec80 = (uint8_t *)((uint8_t *)p_fft_report + SPECTRAL_FFT_BINS_POS); @@ -1797,6 +2083,8 @@ target_if_consume_spectral_report_gen3( goto fail; } + target_if_spectral_check_buffer_poisoning(spectral, report, + fft_bin_count, params.smode); qdf_mem_copy(¶ms.classifier_params, &spectral->classifier_params, sizeof(struct spectral_classifier_params)); @@ -1805,7 +2093,6 @@ target_if_consume_spectral_report_gen3( target_if_spectral_create_samp_msg(spectral, ¶ms); return 0; - fail: spectral_err_rl("Error while processing Spectral report"); reset_160mhz_delivery_state_machine(spectral, diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/inc/target_if_wifi_pos.h b/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/inc/target_if_wifi_pos.h index b1a6b3fd856dceffd3ef2501f0d7de9ba44ba4d5..e136e099611e4595bf00990e5f1df0f5e4159faa 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/inc/target_if_wifi_pos.h +++ b/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/inc/target_if_wifi_pos.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +26,7 @@ #include "qdf_types.h" #include "qdf_status.h" +#include "wlan_cmn.h" struct oem_data_req; struct oem_data_rsp; struct wlan_objmgr_psoc; @@ -35,15 +36,6 @@ struct wlan_lmac_if_rx_ops; #ifdef WIFI_POS_CONVERGED -/** - * target_if_wifi_pos_get_txops: api to get tx ops - * @psoc: pointer to psoc object - * - * Return: tx ops - */ -struct wlan_lmac_if_wifi_pos_tx_ops *target_if_wifi_pos_get_txops( - struct wlan_objmgr_psoc *psoc); - /** * target_if_wifi_pos_get_rxops: api to get rx ops * @psoc: pointer to psoc object @@ -71,28 +63,24 @@ QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc); /** - * target_if_wifi_pos_register_tx_ops: function to register with lmac tx ops - * @tx_ops: lmac tx ops struct object + * target_if_wifi_pos_get_vht_ch_width: function to get vht channel width + * @psoc: pointer to psoc object + * @ch_width: pointer to the variable in which output value needs to be filled * - * Return: none + * Return: status of operation */ -void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +QDF_STATUS target_if_wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width *ch_width); /** - * target_if_wifi_pos_register_rx_ops: function to register with lmac rx ops - * @rx_ops: lmac rx ops struct object + * target_if_wifi_pos_register_tx_ops: function to register with lmac tx ops + * @tx_ops: lmac tx ops struct object * * Return: none */ -void target_if_wifi_pos_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops); +void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); #else -static inline struct wlan_lmac_if_wifi_pos_tx_ops *target_if_wifi_pos_get_txops( - struct wlan_objmgr_psoc *psoc) -{ - return NULL; -} - static inline struct wlan_lmac_if_wifi_pos_rx_ops *target_if_wifi_pos_get_rxops( struct wlan_objmgr_psoc *psoc) { @@ -104,10 +92,6 @@ static inline void target_if_wifi_pos_register_tx_ops( { } -static inline void target_if_wifi_pos_register_rx_ops( - struct wlan_lmac_if_rx_ops *rx_ops) -{ -} #endif #if defined(WLAN_FEATURE_CIF_CFR) && defined(WIFI_POS_CONVERGED) diff --git a/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/src/target_if_wifi_pos.c b/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/src/target_if_wifi_pos.c index d5bf4ae4d7df17b3306879aeaf0aa485e6d14553..6f9b00f4b8069c25853af801a6072599dbcc2fd3 100644 --- a/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/src/target_if_wifi_pos.c +++ b/drivers/staging/qca-wifi-host-cmn/target_if/wifi_pos/src/target_if_wifi_pos.c @@ -22,6 +22,8 @@ * target if layer. */ #include "../../../../umac/wifi_pos/src/wifi_pos_utils_i.h" +#include "wifi_pos_utils_pub.h" + #include "wmi_unified_api.h" #include "wlan_lmac_if_def.h" #include "target_if_wifi_pos.h" @@ -84,7 +86,7 @@ static QDF_STATUS target_if_wifi_pos_replenish_ring( static QDF_STATUS target_if_wifi_pos_get_indirect_data( struct wifi_pos_psoc_priv_obj *priv_obj, - wmi_oem_indirect_data *indirect, + struct wmi_host_oem_indirect_data *indirect, struct oem_data_rsp *rsp, uint32_t *cookie) { void *paddr = NULL; @@ -138,7 +140,7 @@ static QDF_STATUS target_if_wifi_pos_replenish_ring( static QDF_STATUS target_if_wifi_pos_get_indirect_data( struct wifi_pos_psoc_priv_obj *priv_obj, - wmi_oem_indirect_data *indirect, + struct wmi_host_oem_indirect_data *indirect, struct oem_data_rsp *rsp, uint32_t *cookie) { return QDF_STATUS_SUCCESS; @@ -162,14 +164,15 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, uint8_t ring_idx = 0; QDF_STATUS status; uint32_t cookie = 0; - wmi_oem_indirect_data *indirect; + struct wmi_host_oem_indirect_data *indirect; struct oem_data_rsp oem_rsp = {0}; struct wifi_pos_psoc_priv_obj *priv_obj; - struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); - struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops = NULL; - WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf = - (WMI_OEM_RESPONSE_EVENTID_param_tlvs *)data_buf; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops; + struct wmi_oem_response_param oem_resp_param = {0}; + wmi_unified_t wmi_handle; + psoc = target_if_get_psoc_from_scn_hdl(scn); if (!psoc) { target_if_err("psoc is null"); return QDF_STATUS_NOT_INITIALIZED; @@ -177,6 +180,13 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null"); + wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID); + return QDF_STATUS_NOT_INITIALIZED; + } + priv_obj = wifi_pos_get_psoc_priv_obj(psoc); if (!priv_obj) { target_if_err("priv_obj is null"); @@ -191,15 +201,19 @@ static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn, return QDF_STATUS_NOT_INITIALIZED; } - oem_rsp.rsp_len_1 = param_buf->num_data; - oem_rsp.data_1 = param_buf->data; + ret = wmi_extract_oem_response_param(wmi_handle, + data_buf, + &oem_resp_param); + + oem_rsp.rsp_len_1 = oem_resp_param.num_data1; + oem_rsp.data_1 = oem_resp_param.data_1; - if (param_buf->num_data2) { - oem_rsp.rsp_len_2 = param_buf->num_data2; - oem_rsp.data_2 = param_buf->data2; + if (oem_resp_param.num_data2) { + oem_rsp.rsp_len_2 = oem_resp_param.num_data2; + oem_rsp.data_2 = oem_resp_param.data_2; } - indirect = (wmi_oem_indirect_data *)param_buf->indirect_data; + indirect = &oem_resp_param.indirect_data; status = target_if_wifi_pos_get_indirect_data(priv_obj, indirect, &oem_rsp, &cookie); if (QDF_IS_STATUS_ERROR(status)) { @@ -270,17 +284,18 @@ static int wifi_pos_oem_err_rpt_ev_handler(ol_scn_t scn, uint8_t *buf, } /** - * wifi_pos_oem_data_req() - start OEM data request to target - * @psoc: the pointer to psoc object manager + * target_if_wifi_pos_oem_data_req() - start OEM data request to target + * @psoc: pointer to psoc object mgr * @req: start request params * * Return: QDF_STATUS */ -static QDF_STATUS wifi_pos_oem_data_req(struct wlan_objmgr_psoc *psoc, - struct oem_data_req *req) +static QDF_STATUS +target_if_wifi_pos_oem_data_req(struct wlan_objmgr_pdev *pdev, + struct oem_data_req *req) { QDF_STATUS status; - void *wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_unified_t wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev); target_if_debug("Send oem data req to target"); @@ -307,25 +322,14 @@ void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_wifi_pos_tx_ops *wifi_pos_tx_ops; wifi_pos_tx_ops = &tx_ops->wifi_pos_tx_ops; - wifi_pos_tx_ops->data_req_tx = wifi_pos_oem_data_req; -} - -void target_if_wifi_pos_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) -{ - struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops; - wifi_pos_rx_ops = &rx_ops->wifi_pos_rx_ops; - wifi_pos_rx_ops->oem_rsp_event_rx = wifi_pos_oem_rsp_handler; -} - -inline struct wlan_lmac_if_wifi_pos_tx_ops *target_if_wifi_pos_get_txops( - struct wlan_objmgr_psoc *psoc) -{ - if (!psoc) { - target_if_err("passed psoc is NULL"); - return NULL; - } + wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req; + wifi_pos_tx_ops->wifi_pos_register_events = + target_if_wifi_pos_register_events; + wifi_pos_tx_ops->wifi_pos_deregister_events = + target_if_wifi_pos_deregister_events; + wifi_pos_tx_ops->wifi_pos_get_vht_ch_width = + target_if_wifi_pos_get_vht_ch_width; - return &psoc->soc_cb.tx_ops.wifi_pos_tx_ops; } inline struct wlan_lmac_if_wifi_pos_rx_ops *target_if_wifi_pos_get_rxops( @@ -348,15 +352,14 @@ QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_INVAL; } - ret = wmi_unified_register_event_handler( + /* wmi_oem_response_event_id is not defined for legacy targets. + * So do not check for error for this event. + */ + wmi_unified_register_event_handler( get_wmi_unified_hdl_from_psoc(psoc), wmi_oem_response_event_id, target_if_wifi_pos_oem_rsp_ev_handler, WMI_RX_WORK_CTX); - if (ret) { - target_if_err("register_event_handler failed: err %d", ret); - return QDF_STATUS_E_INVAL; - } ret = wmi_unified_register_event_handler( get_wmi_unified_hdl_from_psoc(psoc), @@ -414,6 +417,33 @@ QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +QDF_STATUS target_if_wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width *ch_width) +{ + struct target_psoc_info *tgt_hdl; + int vht_cap_info; + + *ch_width = CH_WIDTH_INVALID; + + if (!psoc) + return QDF_STATUS_E_INVAL; + + tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); + if (!tgt_hdl) + return QDF_STATUS_E_INVAL; + + *ch_width = CH_WIDTH_80MHZ; + + vht_cap_info = target_if_get_vht_cap_info(tgt_hdl); + + if (vht_cap_info & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) + *ch_width = CH_WIDTH_80P80MHZ; + else if (vht_cap_info & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) + *ch_width = CH_WIDTH_160MHZ; + + return QDF_STATUS_SUCCESS; +} + #ifdef WLAN_FEATURE_CIF_CFR static QDF_STATUS target_if_wifi_pos_fill_ring(uint8_t ring_idx, struct hal_srng *srng, @@ -575,7 +605,7 @@ static QDF_STATUS target_if_wifi_pos_cfg_fw(struct wlan_objmgr_psoc *psoc, { uint8_t i; QDF_STATUS status; - void *wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_unified_t wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc); wmi_oem_dma_ring_cfg_req_fixed_param cfg = {0}; if (!wmi_hdl) { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/inc/cfr_defs_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/inc/cfr_defs_i.h new file mode 100644 index 0000000000000000000000000000000000000000..196071670a69c74dfc4b9648b1eec6c57d92fae4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/inc/cfr_defs_i.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _CFR_DEFS_I_H_ +#define _CFR_DEFS_I_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CFR_STOP_STR "CFR-CAPTURE-STOPPED" + +/** + * wlan_cfr_psoc_obj_create_handler() - psoc object create handler for cfr + * @psoc - pointer to psoc object + * @args - void pointer in case it needs arguments + * + * Return: status of object creation + */ +QDF_STATUS +wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * wlan_cfr_psoc_obj_destroy_handler() - psoc object destroy handler for cfr + * @psoc - pointer to psoc object + * @args - void pointer in case it needs arguments + * + * Return: status of destroy object + */ +QDF_STATUS +wlan_cfr_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * wlan_cfr_pdev_obj_create_handler() - pdev object create handler for cfr + * @pdev - pointer to pdev object + * @args - void pointer in case it needs arguments + * + * Return: status of object creation + */ +QDF_STATUS +wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg); + +/** + * wlan_cfr_pdev_obj_destroy_handler() - pdev object destroy handler for cfr + * @pdev - pointer to pdev object + * @args - void pointer in case it needs arguments + * + * Return: status of destroy object + */ +QDF_STATUS +wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg); + +/** + * wlan_cfr_peer_obj_create_handler() - peer object create handler for cfr + * @peer - pointer to peer object + * @args - void pointer in case it needs arguments + * + * Return: status of object creation + */ +QDF_STATUS +wlan_cfr_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg); + +/** + * wlan_cfr_peer_obj_destroy_handler() - peer object destroy handler for cfr + * @peer - pointer to peer object + * @args - void pointer in case it needs arguments + * + * Return: status ofi destry object + */ +QDF_STATUS +wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg); + +/** + * cfr_streamfs_init() - stream filesystem init + * @pdev - pointer to pdev object + * + * Return: status of fs init + */ +QDF_STATUS +cfr_streamfs_init(struct wlan_objmgr_pdev *pdev); + +/** + * cfr_streamfs_remove() - stream filesystem remove + * @pdev - pointer to pdev object + * + * Return: status of fs remove + */ +QDF_STATUS +cfr_streamfs_remove(struct wlan_objmgr_pdev *pdev); + +/** + * cfr_streamfs_write() - write to stream filesystem + * @pa - pointer to pdev_cfr object + * @write_data - Pointer to data + * @write_len - data len + * + * Return: status of fs write + */ +QDF_STATUS +cfr_streamfs_write(struct pdev_cfr *pa, const void *write_data, + size_t write_len); + +/** + * cfr_streamfs_flush() - flush the write to streamfs + * @pa - pointer to pdev_cfr object + * + * Return: status of fs flush + */ +QDF_STATUS +cfr_streamfs_flush(struct pdev_cfr *pa); + +/** + * cfr_stop_indication() - write cfr stop string + * @vdev - pointer to vdev object + * + * Write stop string and indicate to up layer. + * + * Return: status of write CFR stop string + */ +QDF_STATUS cfr_stop_indication(struct wlan_objmgr_vdev *vdev); + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/src/cfr_common.c b/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/src/cfr_common.c new file mode 100644 index 0000000000000000000000000000000000000000..58a614b0a06f8c33a72f14f17d4e0e0aeef29530 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/core/src/cfr_common.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CFR_USE_FIXED_FOLDER +#include +#endif + +/** + * wlan_cfr_get_dbr_num_entries() - Get entry number of DBR ring + * @pdev - the physical device object. + * + * Return : Entry number of DBR ring. + */ +static uint32_t +wlan_cfr_get_dbr_num_entries(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap; + uint8_t num_dbr_ring_caps, cap_idx, pdev_id; + struct target_psoc_info *tgt_psoc_info; + uint32_t num_entries = MAX_LUT_ENTRIES; + + if (!pdev) { + cfr_err("Invalid pdev"); + return num_entries; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + cfr_err("psoc is null"); + return num_entries; + } + + tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); + if (!tgt_psoc_info) { + cfr_err("target_psoc_info is null"); + return num_entries; + } + + num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info); + dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info); + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + + for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) { + if (dbr_ring_cap[cap_idx].pdev_id == pdev_id && + dbr_ring_cap[cap_idx].mod_id == DBR_MODULE_CFR) + num_entries = dbr_ring_cap[cap_idx].ring_elems_min; + } + + num_entries = QDF_MIN(num_entries, MAX_LUT_ENTRIES); + cfr_debug("pdev id %d, num_entries %d", pdev_id, num_entries); + + return num_entries; +} + +QDF_STATUS +wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + struct psoc_cfr *cfr_sc = NULL; + + cfr_sc = (struct psoc_cfr *)qdf_mem_malloc(sizeof(struct psoc_cfr)); + if (!cfr_sc) { + cfr_err("Failed to allocate cfr_ctx object\n"); + return QDF_STATUS_E_NOMEM; + } + + cfr_sc->psoc_obj = psoc; + + wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_CFR, + (void *)cfr_sc, + QDF_STATUS_SUCCESS); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cfr_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + struct psoc_cfr *cfr_sc = NULL; + + cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_CFR); + if (cfr_sc) { + wlan_objmgr_psoc_component_obj_detach(psoc, WLAN_UMAC_COMP_CFR, + (void *)cfr_sc); + qdf_mem_free(cfr_sc); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg) +{ + struct pdev_cfr *pa = NULL; + uint32_t idx; + + if (!pdev) { + cfr_err("PDEV is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + pa = (struct pdev_cfr *)qdf_mem_malloc(sizeof(struct pdev_cfr)); + if (!pa) { + cfr_err("Failed to allocate pdev_cfr object\n"); + return QDF_STATUS_E_NOMEM; + } + pa->pdev_obj = pdev; + pa->lut_num = wlan_cfr_get_dbr_num_entries(pdev); + if (!pa->lut_num) { + cfr_err("lut num is 0"); + return QDF_STATUS_E_INVAL; + } + pa->lut = (struct look_up_table **)qdf_mem_malloc(pa->lut_num * + sizeof(struct look_up_table *)); + if (!pa->lut) { + cfr_err("Failed to allocate lut, lut num %d", pa->lut_num); + qdf_mem_free(pa); + return QDF_STATUS_E_NOMEM; + } + for (idx = 0; idx < pa->lut_num; idx++) + pa->lut[idx] = (struct look_up_table *)qdf_mem_malloc( + sizeof(struct look_up_table)); + + wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_CFR, + (void *)pa, QDF_STATUS_SUCCESS); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg) +{ + struct pdev_cfr *pa = NULL; + uint32_t idx; + + if (!pdev) { + cfr_err("PDEV is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa) { + wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CFR, + (void *)pa); + if (pa->lut) { + for (idx = 0; idx < pa->lut_num; idx++) + qdf_mem_free(pa->lut[idx]); + qdf_mem_free(pa->lut); + } + qdf_mem_free(pa); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cfr_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg) +{ + struct peer_cfr *pe = NULL; + + if (!peer) { + cfr_err("PEER is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + pe = (struct peer_cfr *)qdf_mem_malloc(sizeof(struct peer_cfr)); + if (!pe) { + cfr_err("Failed to allocate peer_cfr object\n"); + return QDF_STATUS_E_FAILURE; + } + + pe->peer_obj = peer; + + /* Remaining will be populated when we give CFR capture command */ + wlan_objmgr_peer_component_obj_attach(peer, WLAN_UMAC_COMP_CFR, + (void *)pe, QDF_STATUS_SUCCESS); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg) +{ + struct peer_cfr *pe = NULL; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_pdev *pdev = NULL; + struct pdev_cfr *pa = NULL; + + if (!peer) { + cfr_err("PEER is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + vdev = wlan_peer_get_vdev(peer); + if (vdev) + pdev = wlan_vdev_get_pdev(vdev); + + if (pdev) + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + + if (pa && pe) { + if (pe->period && pe->request) + pa->cfr_current_sta_count--; + } + + if (pe) { + wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CFR, + (void *)pe); + qdf_mem_free(pe); + } + + return QDF_STATUS_SUCCESS; +} + +#ifdef CFR_USE_FIXED_FOLDER +static const char *cfr_get_dev_name(struct wlan_objmgr_pdev *pdev) +{ + const char *default_name = "wlan"; + + return default_name; +} +#else +static const char *cfr_get_dev_name(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pa = NULL; + char folder[32]; + struct net_device *pdev_netdev; + struct ol_ath_softc_net80211 *scn; + struct target_pdev_info *tgt_hdl; + const char *default_name = "wlan"; + + if (!pdev) { + cfr_err("PDEV is NULL\n"); + return default_name; + } + + tgt_hdl = wlan_pdev_get_tgt_if_handle(pdev); + + if (!tgt_hdl) { + cfr_err("target_pdev_info is NULL\n"); + return default_name; + } + + scn = target_pdev_get_feature_ptr(tgt_hdl); + pdev_netdev = scn->netdev; + + return pdev_netdev->name; +} +#endif + +QDF_STATUS cfr_streamfs_init(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pa = NULL; + char folder[32]; + + if (!pdev) { + cfr_err("PDEV is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + + if (pa == NULL) { + cfr_err("pdev_cfr is NULL\n"); + return QDF_STATUS_E_FAILURE; + } + + if (!pa->is_cfr_capable) { + cfr_err("CFR IS NOT SUPPORTED\n"); + return QDF_STATUS_E_FAILURE; + } + + snprintf(folder, sizeof(folder), "cfr%s", cfr_get_dev_name(pdev)); + + pa->dir_ptr = qdf_streamfs_create_dir((const char *)folder, NULL); + + if (!pa->dir_ptr) { + cfr_err("Directory create failed"); + return QDF_STATUS_E_FAILURE; + } + + pa->chan_ptr = qdf_streamfs_open("cfr_dump", pa->dir_ptr, + pa->subbuf_size, + pa->num_subbufs, NULL); + + if (!pa->chan_ptr) { + cfr_err("Chan create failed"); + qdf_streamfs_remove_dir_recursive(pa->dir_ptr); + pa->dir_ptr = NULL; + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS cfr_streamfs_remove(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pa = NULL; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa) { + if (pa->chan_ptr) { + qdf_streamfs_close(pa->chan_ptr); + pa->chan_ptr = NULL; + } + + if (pa->dir_ptr) { + qdf_streamfs_remove_dir_recursive(pa->dir_ptr); + pa->dir_ptr = NULL; + } + + } else + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS cfr_streamfs_write(struct pdev_cfr *pa, const void *write_data, + size_t write_len) +{ + if (pa->chan_ptr) { + + /* write to channel buffer */ + qdf_streamfs_write(pa->chan_ptr, (const void *)write_data, + write_len); + } else + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS cfr_streamfs_flush(struct pdev_cfr *pa) +{ + if (pa->chan_ptr) { + + /* Flush the data write to channel buffer */ + qdf_streamfs_flush(pa->chan_ptr); + } else + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS cfr_stop_indication(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pa; + uint32_t status; + struct wlan_objmgr_pdev *pdev; + + pdev = wlan_vdev_get_pdev(vdev); + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pa) { + cfr_err("pdev_cfr is NULL\n"); + return QDF_STATUS_E_INVAL; + } + + status = cfr_streamfs_write(pa, (const void *)CFR_STOP_STR, + sizeof(CFR_STOP_STR)); + + status = cfr_streamfs_flush(pa); + cfr_debug("stop indication done"); + + return status; +} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/cfr_cfg.h similarity index 54% rename from drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.h rename to drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/cfr_cfg.h index 17ef9628e687f24b3dfe7876b3ece6b89720a686..f7e3417a0a4a7c6160a3aa168e39121bf18ef2d5 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/cfr_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012, 2014, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -16,26 +16,34 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/** + * DOC: This file contains centralized cfg definitions of CFR component + */ +#ifndef __CFR_CONFIG_H +#define __CFR_CONFIG_H + /* + * + * cfr_disable - disable channel frequence response(CFR) feature + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to disable cfr feature. * - * This file lim_sta_hash_api.h contains the - * function prototypes for accessing station hash entry fields. + * Related: None * - * Author: Sunit Bhatia - * Date: 09/19/2006 - * History:- - * Date Modified by Modification Information - * -------------------------------------------------------------------- + * Supported Feature: cfr * + * Usage: External + * + * */ +#define CFG_CFR_DISABLE \ + CFG_INI_BOOL("cfr_disable", false, \ + "CFR disable") -#ifndef __LIM_STA_HASH_API_H__ -#define __LIM_STA_HASH_API_H__ - -#include "ani_global.h" -#include "lim_types.h" - -QDF_STATUS lim_get_sta_hash_bssidx(struct mac_context *mac, uint16_t assocId, - uint8_t *bssidx, struct pe_session *pe_session); +#define CFG_CFR_ALL \ + CFG(CFG_CFR_DISABLE) -#endif +#endif /* __CFR_CONFIG_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_public_structs.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_public_structs.h new file mode 100644 index 0000000000000000000000000000000000000000..60803097a4ccfc1677240b34e20ddb9c25f21e9e --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_public_structs.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: declare the data structure to hold CFR specific configurations + */ +#ifndef _WLAN_CFR_PUBLIC_STRUCTS_H_ +#define _WLAN_CFR_PUBLIC_STRUCTS_H_ + +#ifdef WLAN_CFR_ENABLE +#include "qdf_types.h" + +/** + * cfr_cwm_width : Capture bandwidth + * 0 : 20MHz, 1 : 40MHz, 2 : 80MHz, 3 : 160MHz, 4 : 80+80MHz + */ +enum cfr_cwm_width { + CFR_CWM_WIDTH20, + CFR_CWM_WIDTH40, + CFR_CWM_WIDTH80, + CFR_CWM_WIDTH160, + CFR_CWM_WIDTH80_80, + + CFR_CWM_WIDTH_MAX, + CFR_CWM_WIDTHINVALID = 0xff +}; + +/** + * cfr_capture_method : Tx based CFR capture method + * @CFR_CAPTURE_METHOD_QOS_NULL : Send QOS Null frame and capture CFR on ACK + * @CFR_CAPTURE_METHOD_QOS_NULL_WITH_PHASE: Send QoS Null frame with phase + * @CFR_CAPTURE_METHOD_PROBE_RESPONSE : Capture is enabled on probe response + * If node is not found, trigger unassociated capture. + */ +enum cfr_capture_method { + CFR_CAPTURE_METHOD_QOS_NULL = 0, + CFR_CAPTURE_METHOD_QOS_NULL_WITH_PHASE = 1, + CFR_CAPTURE_METHOD_PROBE_RESPONSE = 2, + CFR_CAPTURE_METHOD_LAST_VALID, + CFR_CAPTURE_METHOD_AUTO = 0xff, + CFR_CAPTURE_METHOD_MAX, +}; + +/** + * cfr_wlanconfig_param : CFR params used to store user provided inputs + * @bandwidth : CFR capture bandwidth + * @periodicity : CFR capture periodicity in milli seconds + * @capture_method : CFR capture method + * @mac : peer mac address + * @ta : Tx address + * @ra : Rx Address + * @ta_mask: Tx address mask + * @ra_mask; Rx address mask + * *** Controls for different capture modes in RCC *** + * @en_directed_ftm: Enable capture for directed RTT FTM Packet + * @en_directed_ndpa_ndp: Enable NDPA filter followed by directed NDP capture + * @en_ta_ra_filter: Enable MAC TA/RA/type filtering channel capture + * @en_all_ftm_ack: Enable all FTM and ACK capture + * @en_ndpa_ndp_all: Enable NDPA filter followed by NDP capture, + * capture includes both directed and non-directed packets. + * @en_all_pkt: Enable capture mode to filter in all packets + * @dis_directed_ftm: Drop directed RTT FTM packets + * @dis_directed_ndpa_ndp: Drop directed NDPA and NDP packets + * @dis_ta_ra_filter: Disable MAC TA/RA/type filtering channel capture + * @dis_all_ftm_ack: Drop all FTM and ACK capture + * @dis_ndpa_ndp_all: Drop all NDPA and NDP packets + * @dis_all_pkt: Do not filter in any packet + * + * **** Fixed parameters **** + * @cap_dur: Capture duration + * @cap_intvl: Capture interval + * FW may limit the interval and duration during which HW may attempt + * to capture by programming the user provided values. + * These values(cap_dur, cap_intvl) range from 1 us to roughly 16.8 in 1 us + * units. Max value is 0xFFFFFF, i.e., 16.777215 s + * @bw: Bandwidth: 20, 40, 80, 160, 320MHz + * @nss: 8 bits are allotted for NSS mask. Specifies which numbers of + * spatial streams (MIMO factor) are permitted + * @grp_id: Group id could of any value between 0 and 15 + * @expected_mgmt_subtype/ expected_ctrl_subtype / expected_data_subtype: + * corresponds to mgmt/ ctrl/ data, all are bitmasks, in which each bit + * represents the corresponding type/ subtype value as per IEEE80211. + * + * @en_cfg and reset_cfg: This bitmap of 16 bits, indicates 16 groups. + * Valid entry should be in between 0 to 0xFFFF. + * Turning on a bit in en_cfg will enable MAC TA_RA filter + * for corresponding group; whereas turning on a bit in reset_cfg + * will reset all 9 params in the corresponding group to default values. + * + * @ul_mu_user_mask_lower, ul_mu_user_mask_upper : + * Since Cypress supports max bandwidth of 80Mhz, maximum number + * of users in a UL MU-MIMO transmission would be 37. + * mask_lower_32: Bits from 31 to 0 indicate user indices for 32 users. + * mask_upper_32: Bits from 0 to 4 indicate user indices from 33 to 37. + * + * @ freeze_tlv_delay_cnt_en, freeze_tlv_delay_cnt_thr : + * freeze_tlv_delay_cnt_thr will decide the threshold for MAC to drop the + * freeze TLV. freeze_tlv_delay_cnt_thr will only be applicable if + * freeze_tlv_delay_cnt_en is enabled. + */ +struct cfr_wlanconfig_param { + enum cfr_cwm_width bandwidth; + uint32_t periodicity; + enum cfr_capture_method capture_method; + uint8_t mac[QDF_MAC_ADDR_SIZE]; +#ifdef WLAN_ENH_CFR_ENABLE + uint8_t ta[QDF_MAC_ADDR_SIZE]; + uint8_t ra[QDF_MAC_ADDR_SIZE]; + uint8_t ta_mask[QDF_MAC_ADDR_SIZE]; + uint8_t ra_mask[QDF_MAC_ADDR_SIZE]; + uint16_t en_directed_ftm :1, + en_directed_ndpa_ndp :1, + en_ta_ra_filter :1, + en_all_ftm_ack :1, + en_ndpa_ndp_all :1, + en_all_pkt :1, + dis_directed_ftm :1, + dis_directed_ndpa_ndp :1, + dis_ta_ra_filter :1, + dis_all_ftm_ack :1, + dis_ndpa_ndp_all :1, + dis_all_pkt :1, + rsvd0 :4; + + uint32_t cap_dur :24, + rsvd1 :8; + uint32_t cap_intvl :24, + rsvd2 :8; + uint32_t bw :5, + nss :8, + grp_id :4, + rsvd3 :15; + + uint32_t expected_mgmt_subtype :16, + expected_ctrl_subtype :16; + + uint32_t expected_data_subtype :16, + rsvd5 :16; + + uint32_t en_cfg :16, + reset_cfg :16; + + uint32_t ul_mu_user_mask_lower; + uint32_t ul_mu_user_mask_upper; + + uint32_t freeze_tlv_delay_cnt_en :1, + freeze_tlv_delay_cnt_thr :8, + rsvd6 :23; +#endif +}; + +#endif /* WLAN_CFR_ENABLE */ +#endif /* _WLAN_CFR_PUBLIC_STRUCTS_H_ */ + diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h new file mode 100644 index 0000000000000000000000000000000000000000..907524ba49b79b8a4f58eac66f72ea495072866a --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _WLAN_CFR_TGT_API_H_ +#define _WLAN_CFR_TGT_API_H_ + +#include +#include +#include +#include + +/* tgt layer has APIs in application, to access functions in target + * through tx_ops. + */ + +/** + * tgt_cfr_init_pdev() - API that registers CFR to handlers. + * @pdev: pointer to pdev_object + * + * Return: success/failure of init + */ +int tgt_cfr_init_pdev(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_deinit_pdev() - API that de-registers CFR to handlers. + * @pdev: pointer to pdev_object + * + * Return: success/failure of de-init + */ +int tgt_cfr_deinit_pdev(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_get_target_type() - API to determine target type. + * @psoc: pointer to psoc_object + * + * Return: enum value of target type + */ +int tgt_cfr_get_target_type(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_cfr_start_capture() - API to start cfr capture on a peer. + * @pdev: pointer to pdev_object + * @peer: pointer to peer_object + * @cfr_params: pointer to config cfr_params + * + * Return: success/failure of start capture + */ +int tgt_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *cfr_params); + +/** + * tgt_cfr_stop_capture() - API to stop cfr capture on a peer. + * @pdev: pointer to pdev_object + * @peer: pointer to peer_object + * + * Return: success/failure of stop capture + */ +int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer); + +/** + * tgt_cfr_enable_cfr_timer() - API to enable cfr timer + * @pdev: pointer to pdev_object + * @cfr_timer: Amount of time this timer has to run. If 0, it disables timer. + * + * Return: success/failure of timer enable + */ +int +tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer); + +/** + * tgt_cfr_support_set() - API to set cfr support + * @psoc: pointer to psoc_object + * @value: value to be set + */ +void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value); + +/** + * tgt_cfr_info_send() - API to send cfr info + * @pdev: pointer to pdev_object + * @head: pointer to cfr info head + * @hlen: head len + * @data: pointer to cfr info data + * @dlen: data len + * @tail: pointer to cfr info tail + * @tlen: tail len + * + * Return: success/failure of cfr info send + */ +uint32_t tgt_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, + size_t hlen, void *data, size_t dlen, void *tail, + size_t tlen); + +#ifdef WLAN_ENH_CFR_ENABLE +/** + * tgt_cfr_config_rcc() - API to set RCC + * @pdev: pointer to pdev_object + * @rcc_param: rcc configurations + * + * Return: succcess / failure + */ +QDF_STATUS tgt_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_param); + +/** + * tgt_cfr_start_lut_age_timer() - API to start timer to flush aged out LUT + * entries + * @pdev: pointer to pdev_object + * + * Return: None + */ +void tgt_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_stop_lut_age_timer() - API to stop timer to flush aged out LUT + * entries + * @pdev: pointer to pdev_object + * + * Return: None + */ +void tgt_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_default_ta_ra_cfg() - API to configure default values in TA_RA mode + * entries + * @pdev: pointer to pdev_object + * + * Return: none + */ +void tgt_cfr_default_ta_ra_cfg(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_param, + bool allvalid, uint16_t reset_cfg); + +/** + * tgt_cfr_dump_lut_enh() - Print all LUT entries + * @pdev: pointer to pdev_object + */ +void tgt_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_rx_tlv_process() - Process PPDU status TLVs + * @pdev_obj: pointer to pdev_object + * @nbuf: pointer to cdp_rx_indication_ppdu + */ +void tgt_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf); + +/** + * tgt_cfr_update_global_cfg() - Update global config after successful commit + * @pdev: pointer to pdev_object + */ +void tgt_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_cfr_subscribe_ppdu_desc() - Target interface to + * subscribe/unsubscribe WDI PPDU desc event + * @pdev: pointer to pdev_object + * @is_subscribe: subscribe or unsubscribei + * + * return QDF status + */ +QDF_STATUS tgt_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe); +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h new file mode 100644 index 0000000000000000000000000000000000000000..50f2889da0d50e0efe8cfaaea511dc35999c6010 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _WLAN_CFR_UCFG_API_H_ +#define _WLAN_CFR_UCFG_API_H_ + +#include +#include +#include + +#define MAX_CFR_PRD (10*60*1000) /* 10 minutes */ + +/** + * ucfg_cfr_start_capture() - function to start cfr capture for connected client + * @pdev: pointer to pdev object + * @peer: pointer to peer object + * @cfr_params: config params to cfr capture + * + * Return: status of start capture. + */ +int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *cfr_params); + +/** + * ucfg_cfr_stop_capture() - function to stop cfr capture for connected client + * @pdev: pointer to pdev object + * @peer: pointer to peer object + * + * Return: status of stop capture. + */ +int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer); + +/** + * ucfg_cfr_start_capture_probe_req() - function to start cfr capture for + * unassociated clients + * @pdev: pointer to pdev object + * @unassoc_mac: mac address of un-associated client + * @cfr_params: config params to cfr capture + * + * Return: status of start capture. + */ +int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac, + struct cfr_capture_params *params); + +/** + * ucfg_cfr_stop_capture_probe_req() - function to stop cfr capture for + * unassociated cleints + * @pdev: pointer to pdev object + * @unassoc_mac: mac address of un-associated client + * + * Return: status of stop capture. + */ +int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac); + +/** + * ucfg_cfr_list_peers() - Lists total number of peers with cfr capture enabled + * @pdev: pointer to pdev object + * + * Return: number of peers with cfr capture enabled + */ +int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_cfr_set_timer() - function to enable cfr timer + * @pdev: pointer to pdev object + * @value: value to be set + * + * Return: status of timer enable + */ +int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value); + +/** + * ucfg_cfr_get_timer() - function to get cfr_timer_enable + * @pdev: pointer to pdev object + * + * Return: value of cfr_timer_enable + */ +int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_cfr_stop_indication() - User space API to write cfr stop string + * @vdev - pointer to vdev object + * + * Write stop string and indicate to up layer. + * + * Return: status of write CFR stop string + */ +QDF_STATUS ucfg_cfr_stop_indication(struct wlan_objmgr_vdev *vdev); + +#ifdef WLAN_ENH_CFR_ENABLE +/* Channel capture recipe filters */ +enum capture_type { + RCC_DIRECTED_FTM_FILTER, + RCC_ALL_FTM_ACK_FILTER, + RCC_DIRECTED_NDPA_NDP_FILTER, + RCC_NDPA_NDP_ALL_FILTER, + RCC_TA_RA_FILTER, + RCC_ALL_PACKET_FILTER, + RCC_DIS_ALL_MODE, +}; + +/** + * ucfg_cfr_set_rcc_mode() - function to set RCC mode + * @vdev: pointer to vdev object + * @mode: capture type passed by user + * @value: Enable/Disable capture mode + * + * Return: status if the mode is set or not + */ +QDF_STATUS ucfg_cfr_set_rcc_mode(struct wlan_objmgr_vdev *vdev, + enum capture_type mode, uint8_t value); + +/** + * ucfg_cfr_get_rcc_enabled() - function to get RCC mode + * @vdev: pointer to vdev object + * + * Return: if the rcc is enabled or not + */ +bool ucfg_cfr_get_rcc_enabled(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_set_tara_config() - function to configure TA/RA address and mask + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS ucfg_cfr_set_tara_config(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_bw_nss() - function to configure nss and bandwidth + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS ucfg_cfr_set_bw_nss(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_frame_type_subtype() - function to configure frame type/subtype + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS +ucfg_cfr_set_frame_type_subtype(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_capture_duration() - function to configure capture duration + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS +ucfg_cfr_set_capture_duration(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_capture_interval() - function to configure capture interval + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS +ucfg_cfr_set_capture_interval(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_en_bitmap() - function to configure 16-bit bitmap in TA_RA mode + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS ucfg_cfr_set_en_bitmap(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_reset_bitmap() - function to clear all 9 params for all 16 + * groups in TA_RA mode + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS ucfg_cfr_set_reset_bitmap(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_ul_mu_user_mask() - function to configure UL MU user mask + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS +ucfg_cfr_set_ul_mu_user_mask(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_set_freeze_tlv_delay_cnt() - function to configure freeze TLV delay + * count threshold + * @vdev: pointer to vdev object + * @params: user config + * + * Return: status + */ +QDF_STATUS +ucfg_cfr_set_freeze_tlv_delay_cnt(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params); + +/** + * ucfg_cfr_committed_rcc_config() - function to commit user config + * @vdev: pointer to vdev object + * + * Return: status + */ +QDF_STATUS ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_get_cfg() - function to display user config + * @vdev: pointer to vdev object + * + * Return: status + */ +QDF_STATUS ucfg_cfr_get_cfg(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_rcc_dump_dbg_counters() - function to display PPDU counters + * @vdev: pointer to vdev object + * + * Return: status + */ +QDF_STATUS ucfg_cfr_rcc_dump_dbg_counters(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_rcc_clr_dbg_counters() - function to clear CFR PPDU counters + * @vdev: pointer to vdev object + * + * Return: status + */ +QDF_STATUS ucfg_cfr_rcc_clr_dbg_counters(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_rcc_dump_lut() - function to display lookup table + * @vdev: pointer to vdev object + * + * Return: status + */ +QDF_STATUS ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_cfr_subscribe_ppdu_desc() - User space interface to + * subscribe/unsubscribe WDI PPDU desc event + * @pdev: pointer to pdev_object + * @is_subscribe: subscribe or unsubscribei + * + * return QDF status + */ +QDF_STATUS ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe); +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h new file mode 100644 index 0000000000000000000000000000000000000000..24eaf26f710e5e76ee18053b052adb6cf67edf78 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _WLAN_CFR_UTILS_API_H_ +#define _WLAN_CFR_UTILS_API_H_ + +#include +#include +#ifdef WLAN_ENH_CFR_ENABLE +#include +#endif + +#define cfr_alert(format, args...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_CFR, format, ## args) + +#define cfr_err(format, args...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_CFR, format, ## args) + +#define cfr_warn(format, args...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_CFR, format, ## args) + +#define cfr_info(format, args...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_CFR, format, ## args) + +#define cfr_debug(format, args...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_CFR, format, ## args) + +#define DBR_EVENT_TIMEOUT_IN_MS_CFR 1 +#define DBR_NUM_RESP_PER_EVENT_CFR 1 +#define MAX_CFR_ENABLED_CLIENTS 10 +#ifdef WLAN_ENH_CFR_ENABLE +#define MAX_CFR_MU_USERS 4 +#define NUM_CHAN_CAPTURE_STATUS 4 +#define NUM_CHAN_CAPTURE_REASON 6 +#define MAX_TA_RA_ENTRIES 16 +#define MAX_RESET_CFG_ENTRY 0xFFFF +#define CFR_INVALID_VDEV_ID 0xff +#endif + +enum cfrmetaversion { + CFR_META_VERSION_NONE, + CFR_META_VERSION_1, + CFR_META_VERSION_2, + CFR_META_VERSION_3, + CFR_META_VERSION_MAX = 0xFF, +}; + +enum cfrdataversion { + CFR_DATA_VERSION_NONE, + CFR_DATA_VERSION_1, + CFR_DATA_VERSION_MAX = 0xFF, +}; + +enum cfrplatformtype { + CFR_PLATFORM_TYPE_NONE, + CFR_PLATFORM_TYPE_MIPS, + CFR_PLATFORM_TYPE_ARM, + CFR_PLATFFORM_TYPE_MAX = 0xFF, +}; + +enum cfrradiotype { + CFR_CAPTURE_RADIO_NONE, + CFR_CAPTURE_RADIO_OSPREY, + CFR_CAPTURE_RADIO_PEAKCOCK, + CFR_CAPTURE_RADIO_SCORPION, + CFR_CAPTURE_RADIO_HONEYBEE, + CFR_CAPTURE_RADIO_DRAGONFLY, + CFR_CAPTURE_RADIO_JET, + CFR_CAPTURE_RADIO_PEREGRINE = 17, + CFR_CAPTURE_RADIO_SWIFT, + CFR_CAPTURE_RADIO_BEELINER, + CFR_CAPTURE_RADIO_CASCADE, + CFR_CAPTURE_RADIO_DAKOTA, + CFR_CAPTURE_RADIO_BESRA, + CFR_CAPTURE_RADIO_HKV2, + CFR_CAPTURE_RADIO_CYP, + CFR_CAPTURE_RADIO_HSP, + CFR_CAPTURE_RADIO_MAX = 0xFF, +}; + +enum ack_capture_mode { + CFR_LEGACY_ACK = 0, + CFR_DUP_LEGACY_ACK = 1, + CFR_HT_ACK = 2, + CFR_VHT_ACK = 3, + CFR_INVALID_ACK, /*Always keep this at last*/ +}; + +/* Similar to WMI_PEER_CFR_CAPTURE_METHOD used in one-shot capture */ +enum cfr_capture_type { + CFR_TYPE_METHOD_NULL_FRAME = 0, + CFR_TYPE_METHOD_NULL_FRAME_WITH_PHASE = 1, + CFR_TYPE_METHOD_PROBE_RESP = 2, + CFR_TYPE_METHOD_TM = 3, + CFR_TYPE_METHOD_FTM = 4, + CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM = 5, + CFR_TYPE_METHOD_TA_RA_TYPE_FILTER = 6, + CFR_TYPE_METHOD_NDPA_NDP = 7, + CFR_TYPE_METHOD_ALL_PACKET = 8, + /* Add new capture methods before this line */ + CFR_TYPE_METHOD_LAST_VALID, + CFR_TYPE_METHOD_AUTO = 0xff, + CFR_TYPE_METHOD_MAX, +}; + +struct cfr_metadata_version_1 { + u_int8_t peer_addr[QDF_MAC_ADDR_SIZE]; + u_int8_t status; + u_int8_t capture_bw; + u_int8_t channel_bw; + u_int8_t phy_mode; + u_int16_t prim20_chan; + u_int16_t center_freq1; + u_int16_t center_freq2; + u_int8_t capture_mode; + u_int8_t capture_type; + u_int8_t sts_count; + u_int8_t num_rx_chain; + u_int32_t timestamp; + u_int32_t length; +} __attribute__ ((__packed__)); + +#define HOST_MAX_CHAINS 8 + +struct cfr_metadata_version_2 { + u_int8_t peer_addr[QDF_MAC_ADDR_SIZE]; + u_int8_t status; + u_int8_t capture_bw; + u_int8_t channel_bw; + u_int8_t phy_mode; + u_int16_t prim20_chan; + u_int16_t center_freq1; + u_int16_t center_freq2; + u_int8_t capture_mode; + u_int8_t capture_type; + u_int8_t sts_count; + u_int8_t num_rx_chain; + u_int32_t timestamp; + u_int32_t length; + u_int32_t chain_rssi[HOST_MAX_CHAINS]; + u_int16_t chain_phase[HOST_MAX_CHAINS]; +} __attribute__ ((__packed__)); + +#ifdef WLAN_ENH_CFR_ENABLE +struct cfr_metadata_version_3 { + u_int8_t status; + u_int8_t capture_bw; + u_int8_t channel_bw; + u_int8_t phy_mode; + u_int16_t prim20_chan; + u_int16_t center_freq1; + u_int16_t center_freq2; + u_int8_t capture_mode; /* ack_capture_mode */ + u_int8_t capture_type; /* cfr_capture_type */ + u_int8_t sts_count; + u_int8_t num_rx_chain; + u_int64_t timestamp; + u_int32_t length; + u_int8_t is_mu_ppdu; + u_int8_t num_mu_users; + union { + u_int8_t su_peer_addr[QDF_MAC_ADDR_SIZE]; + u_int8_t mu_peer_addr[MAX_CFR_MU_USERS][QDF_MAC_ADDR_SIZE]; + } peer_addr; + u_int32_t chain_rssi[HOST_MAX_CHAINS]; + u_int16_t chain_phase[HOST_MAX_CHAINS]; +} __attribute__ ((__packed__)); +#endif + +struct csi_cfr_header { + u_int32_t start_magic_num; + u_int32_t vendorid; + u_int8_t cfr_metadata_version; + u_int8_t cfr_data_version; + u_int8_t chip_type; + u_int8_t pltform_type; + u_int32_t Reserved; + + union { + struct cfr_metadata_version_1 meta_v1; + struct cfr_metadata_version_2 meta_v2; +#ifdef WLAN_ENH_CFR_ENABLE + struct cfr_metadata_version_3 meta_v3; +#endif + } u; +} __attribute__ ((__packed__)); + +/** + * struct cfr_capture_params - structure to store cfr config param + * bandwidth: bandwitdh of capture + * period: period of capture + * method: enum of method being followed to capture cfr data. 0-QoS null data + */ +struct cfr_capture_params { + u_int8_t bandwidth; + u_int32_t period; + u_int8_t method; +}; + +/** + * struct psoc_cfr - private psoc object for cfr + * psoc_obj: pointer to psoc object + * is_cfr_capable: flag to determine if cfr is enabled or not + */ +struct psoc_cfr { + struct wlan_objmgr_psoc *psoc_obj; + uint8_t is_cfr_capable; +}; + +/** + * struct cfr_wmi_host_mem_chunk - wmi mem chunk related + * vaddr: pointer to virtual address + * paddr: physical address + * len: len of the mem chunk allocated + * req_id: reqid related to the mem chunk + */ +struct cfr_wmi_host_mem_chunk { + uint32_t *vaddr; + uint32_t paddr; + uint32_t len; + uint32_t req_id; +}; + +struct whal_cfir_dma_hdr { + uint16_t + // 'BA' + tag : 8, + // '02', length of header in 4 octet units + length : 6, + // 00 + reserved : 2; + uint16_t + // [16] + upload_done : 1, + // [17:18], 0: invalid, 1: CFR, 2: CIR, 3: DebugH + capture_type : 3, + // [19:20], 0: Legacy, 1: HT, 2: VHT, 3: HE + preamble_type : 2, + // [21:23], 0: 1-stream, 1: 2-stream, ..., 7: 8-stream + nss : 3, + // [24:27], 0: invalid, 1: 1-chain, 2: 2-chain, etc. + num_chains : 3, + // [28:30], 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160 MHz + upload_pkt_bw : 3, // [31] + sw_peer_id_valid : 1; + uint16_t + sw_peer_id : 16; // [15:0] + uint16_t + phy_ppdu_id : 16; // [15:0] +}; + +#define MAX_LUT_ENTRIES 140 /* For HKv2 136 is max */ + +/** + * struct look_up_table - Placeholder for 2 asynchronous events (DBR and + * TXRX event) + * dbr_recv: Indicates whether WMI for DBR completion is received or not + * tx_recv: Indicates whether WMI for TX completion (or) WDI event for RX + * status is received or not + * data: pointer to CFR data that ucode DMAs to host memory + * data_len: length of CFR data DMAed by ucode + * dbr_ppdu_id: PPDU id retrieved from DBR completion WMI event + * tx_ppdu_id: PPDU id retrieved from WMI TX completion event (or) PPDU status + * TLV + * dbr_address: Physical address of the CFR data dump retrieved from DBR + * completion WMI event + * tx_address1: Physical address of the CFR data from TX/RX event + * tx_address2: Physical address of the CFR data from TX/RX event + * csi_cfr_header: CFR header constructed by host + * whal_cfir_enhanced_hdr: CFR header constructed by ucode + * tx_tstamp: Timestamp when TX/RX event was received + * dbr_tstamp: Timestamp when DBR completion event was received + * header_length: Length of header DMAed by ucode in words + * payload_length: Length of CFR payload + */ +struct look_up_table { + bool dbr_recv; + bool tx_recv; + uint8_t *data; /* capture payload */ + uint32_t data_len; /* capture len */ + uint16_t dbr_ppdu_id; /* ppdu id from dbr */ + uint16_t tx_ppdu_id; /* ppdu id from TX event */ + qdf_dma_addr_t dbr_address; /* capture len */ + uint32_t tx_address1; /* capture len */ + uint32_t tx_address2; /* capture len */ + struct csi_cfr_header header; + struct whal_cfir_dma_hdr dma_hdr; + uint64_t txrx_tstamp; + uint64_t dbr_tstamp; + uint32_t header_length; + uint32_t payload_length; +}; + +struct unassoc_pool_entry { + struct qdf_mac_addr mac; + struct cfr_capture_params cfr_params; + bool is_valid; +}; + +#ifdef WLAN_ENH_CFR_ENABLE +/** + * struct ta_ra_cfr_cfg - structure to store configuration of 16 groups in + * M_TA_RA mode + * filter_group_id: Filter group number for which the below filters needs to be + * applied + * bw: CFR capture will be done for packets matching the bandwidths specified + * within this bitmask + * nss: CFR capture will be done for packets matching the Nss specified within + * this bitmask + * valid_ta: Ta_addr is valid if set + * valid_ta_mask: Ta_addr_mask is valid if set + * valid_ra: Ra_addr is valid if set + * valid_ra_mask: Ra_addr_mask is valid if set + * valid_bw_mask: Bandwidth is valid if set + * valid_nss_mask: NSS is valid if set + * valid_mgmt_subtype: Mgmt_subtype is valid if set + * valid_ctrl_subtype: Ctrl_subtype is valid if set + * valid_data_subtype: Data_subtype is valid if set + * mgmt_subtype_filter: Managments Packets matching the subtype filter + * categories will be filtered in by MAC for CFR capture. + * ctrl_subtype_filter: Control Packets matching the subtype filter + * categories will be filtered in by MAC for CFR capture. + * data_subtype_filter: Data Packets matching the subtype filter + * categories will be filtered in by MAC for CFR capture. + * tx_addr: Packets whose transmitter address matches (tx_addr & tx_addr_mask) + * will be filtered in by MAC + * tx_addr_mask: Packets whose transmitter address matches (tx_addr & + * tx_addr_mask) will be filtered in by MAC + * rx_addr: Packets whose receiver address matches (rx_addr & rx_addr_mask) + * will be filtered in by MAC + * rx_addr_mask: Packets whose receiver address matches (rx_addr & + * rx_addr_mask) will be filtered in by MAC + */ +struct ta_ra_cfr_cfg { + uint8_t filter_group_id; + uint16_t bw :5, + nss :8, + rsvd0 :3; + uint16_t valid_ta :1, + valid_ta_mask :1, + valid_ra :1, + valid_ra_mask :1, + valid_bw_mask :1, + valid_nss_mask :1, + valid_mgmt_subtype :1, + valid_ctrl_subtype :1, + valid_data_subtype :1, + rsvd1 :7; + uint16_t mgmt_subtype_filter; + uint16_t ctrl_subtype_filter; + uint16_t data_subtype_filter; + uint8_t tx_addr[QDF_MAC_ADDR_SIZE]; + uint8_t rx_addr[QDF_MAC_ADDR_SIZE]; + uint8_t tx_addr_mask[QDF_MAC_ADDR_SIZE]; + uint8_t rx_addr_mask[QDF_MAC_ADDR_SIZE]; + +} qdf_packed; + +/** + * struct cfr_rcc_param - structure to store cfr config param + * pdev_id: pdev_id for identifying the MAC + * vdev_id: vdev_id of current rcc configures + * srng_id: srng id of current rcc configures + * capture_duration: Capture Duration field for which CFR capture has to happen, + * in microsecond units + * capture_interval: Capture interval field which is time in between + * consecutive CFR capture, in microsecond units + * ul_mu_user_mask_lower: Bitfields indicates which of the users in the current + * UL MU tranmission are enabled for CFR capture. + * ul_mu_user_mask_upper: This is contiuation of the above lower mask. + * freeze_tlv_delay_cnt_en: Enable Freeze TLV delay counter in MAC + * freeze_tlv_delay_cnt_thr: Indicates the number of consecutive Rx packets to + * be skipped before CFR capture is enabled again. + * filter_group_bitmap: Bitfields set indicates which of the CFR group config is + * enabled + * m_directed_ftm: Filter Directed FTM ACK frames for CFR capture + * m_all_ftm_ack: Filter All FTM ACK frames for CFR capture + * m_ndpa_ndp_directed: Filter NDPA NDP Directed Frames for CFR capture + * m_ndpa_ndp_all: Filter all NDPA NDP for CFR capture + * m_ta_ra_filter: Filter Frames based on TA/RA/Subtype as provided in CFR Group + * config + * m_all_packet: Filter in All packets for CFR Capture + * num_grp_tlvs: Indicates the number of groups in M_TA_RA mode, that have + * changes in the current commit session, use to construct WMI group TLV(s) + * curr: Placeholder for M_TA_RA group config in current commit session + * modified_in_curr_session: Bitmap indicating number of groups in M_TA_RA mode + * that have changed in current commit session. + */ +struct cfr_rcc_param { + uint8_t pdev_id; + uint8_t vdev_id; + uint8_t srng_id; + uint32_t capture_duration; + uint32_t capture_interval; + uint32_t ul_mu_user_mask_lower; + uint32_t ul_mu_user_mask_upper; + uint16_t freeze_tlv_delay_cnt_en :1, + freeze_tlv_delay_cnt_thr :8, + rsvd0 :7; + uint16_t filter_group_bitmap; + uint8_t m_directed_ftm : 1, + m_all_ftm_ack : 1, + m_ndpa_ndp_directed : 1, + m_ndpa_ndp_all : 1, + m_ta_ra_filter : 1, + m_all_packet : 1, + rsvd1 : 2; + uint8_t num_grp_tlvs; + + struct ta_ra_cfr_cfg curr[MAX_TA_RA_ENTRIES]; + uint16_t modified_in_curr_session; +}; +#endif /* WLAN_ENH_CFR_ENABLE */ + +/** + * struct pdev_cfr - private pdev object for cfr + * pdev_obj: pointer to pdev object + * is_cfr_capable: flag to determine if cfr is enabled or not + * cfr_timer_enable: flag to enable/disable timer + * chip_type: chip type which is defined in enum cfrradiotype + * cfr_mem_chunk: Region of memory used for storing cfr data + * cfr_max_sta_count: Maximum stations supported in one-shot capture mode + * num_subbufs: No. of sub-buffers used in relayfs + * subbuf_size: Size of sub-buffer used in relayfs + * chan_ptr: Channel in relayfs + * dir_ptr: Parent directory of relayfs file + * lut: lookup table used to store asynchronous DBR and TX/RX events for + * correlation + * lut_num: Number of lut + * dbr_buf_size: Size of DBR completion buffer + * dbr_num_bufs: No. of DBR completions + * tx_evt_cnt: No. of TX completion events till CFR stop was issued + * total_tx_evt_cnt: No. of Tx completion events since wifi was up + * dbr_evt_cnt: No. of WMI DBR completion events + * release_cnt: No. of CFR data buffers relayed to userspace + * rcc_param: Structure to store CFR config for the current commit session + * global: Structure to store accumulated CFR config + * rx_tlv_evt_cnt: Number of CFR WDI events from datapath + * lut_age_timer: Timer to flush pending TXRX/DBR events in lookup table + * lut_timer_init: flag to determine if lut_age_timer is initialized or not + * is_cfr_rcc_capable: Flag to determine if RCC is enabled or not. + * flush_dbr_cnt: No. of un-correlated DBR completions flushed when a newer PPDU + * is correlated successfully with newer DBR completion + * invalid_dma_length_cnt: No. of buffers for which CFR DMA header length (or) + * data length was invalid + * flush_timeout_dbr_cnt: No. of DBR completion flushed out in ageout logic + * clear_txrx_event: No. of PPDU status TLVs over-written in LUT + * unassoc_pool: Pool of un-associated clients used when capture method is + * CFR_CAPTURE_METHOD_PROBE_RESPONSE + * last_success_tstamp: DBR timestamp which indicates that both DBR and TX/RX + * events have been received successfully. + * cfr_dma_aborts: No. of CFR DMA aborts in ucode + */ +/* + * To be extended if we get more capbality info + * from FW's extended service ready event. + */ +struct pdev_cfr { + struct wlan_objmgr_pdev *pdev_obj; + uint8_t is_cfr_capable; + uint8_t cfr_timer_enable; + uint8_t chip_type; + struct cfr_wmi_host_mem_chunk cfr_mem_chunk; + uint16_t cfr_max_sta_count; + uint16_t cfr_current_sta_count; + uint32_t num_subbufs; + uint32_t subbuf_size; + qdf_streamfs_chan_t chan_ptr; + qdf_dentry_t dir_ptr; + struct look_up_table **lut; + uint32_t lut_num; + uint32_t dbr_buf_size; + uint32_t dbr_num_bufs; + uint64_t tx_evt_cnt; + uint64_t total_tx_evt_cnt; + uint64_t dbr_evt_cnt; + uint64_t release_cnt; +#ifdef WLAN_ENH_CFR_ENABLE + struct cfr_rcc_param rcc_param; + struct ta_ra_cfr_cfg global[MAX_TA_RA_ENTRIES]; + uint64_t rx_tlv_evt_cnt; + qdf_timer_t lut_age_timer; + uint8_t lut_timer_init; + uint8_t is_cfr_rcc_capable; + uint64_t flush_dbr_cnt; + uint64_t invalid_dma_length_cnt; + uint64_t flush_timeout_dbr_cnt; + uint64_t clear_txrx_event; + uint64_t last_success_tstamp; + uint64_t cfr_dma_aborts; +#endif + struct unassoc_pool_entry unassoc_pool[MAX_CFR_ENABLED_CLIENTS]; +}; + +#define PEER_CFR_CAPTURE_ENABLE 1 +#define PEER_CFR_CAPTURE_DISABLE 0 +/** + * struct peer_cfr - private peer object for cfr + * peer_obj: pointer to peer_obj + * request: Type of request (start/stop) + * bandwidth: bandwitdth of capture for this peer + * capture_method: enum determining type of cfr data capture. + * 0-Qos null data + */ +struct peer_cfr { + struct wlan_objmgr_peer *peer_obj; + u_int8_t request; /* start/stop */ + u_int8_t bandwidth; + u_int32_t period; + u_int8_t capture_method; +}; + +/** + * cfr_initialize_pdev() - cfr initialize pdev + * @pdev: Pointer to pdev_obj + * + * Return: status of cfr pdev init + */ +QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev); + +/** + * cfr_deinitialize_pdev() - cfr deinitialize pdev + * @pdev: Pointer to pdev_obj + * + * Return: status of cfr pdev deinit + */ +QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_cfr_init() - Global init for cfr. + * + * Return: status of global init pass/fail + */ +QDF_STATUS wlan_cfr_init(void); + +/** + * wlan_cfr_deinit() - Global de-init for cfr. + * + * Return: status of global de-init pass/fail + */ +QDF_STATUS wlan_cfr_deinit(void); + +/** + * wlan_cfr_pdev_open() - pdev_open function for cfr. + * @pdev: pointer to pdev object + * + * Return: status of pdev_open pass/fail + */ +QDF_STATUS wlan_cfr_pdev_open(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_cfr_pdev_close() - pdev_close function for cfr. + * @pdev: pointer to pdev object + * + * Return: status of pdev_close pass/fail + */ +QDF_STATUS wlan_cfr_pdev_close(struct wlan_objmgr_pdev *pdev); + +/** + * count_set_bits() - function to count set bits in a bitmap + * @value: input bitmap + * + * Return: No. of set bits + */ +uint8_t count_set_bits(uint32_t value); + +#ifdef WLAN_ENH_CFR_ENABLE +/** + * wlan_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in + * lookup table + * @pdev_obj: PDEV object + * @nbuf: ppdu info + * + * Return: none + */ +void wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf); +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c new file mode 100644 index 0000000000000000000000000000000000000000..3504ee5abd95af7f0377dc14dd5c36c4c78c0719 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * Layer b/w umac and target_if (ol) txops + * It contains wrapers for txops + */ + +#include +#include +#include +#include + +uint32_t tgt_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, + size_t hlen, void *data, size_t dlen, void *tail, + size_t tlen) +{ + struct pdev_cfr *pa; + uint32_t status; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + + if (pa == NULL) { + cfr_err("pdev_cfr is NULL\n"); + return -1; + } + + if (head) + status = cfr_streamfs_write(pa, (const void *)head, hlen); + + if (data) + status = cfr_streamfs_write(pa, (const void *)data, dlen); + + if (tail) + status = cfr_streamfs_write(pa, (const void *)tail, tlen); + + + /* finalise the write */ + status = cfr_streamfs_flush(pa); + + return status; +} + +void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value) +{ + struct psoc_cfr *cfr_sc; + + if (psoc == NULL) + return; + + cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_CFR); + if (cfr_sc == NULL) + return; + + cfr_sc->is_cfr_capable = !!value; + cfr_debug("CFR:%s FW support advert=%d\n", __func__, + cfr_sc->is_cfr_capable); +} + +static inline struct wlan_lmac_if_cfr_tx_ops * + wlan_psoc_get_cfr_txops(struct wlan_objmgr_psoc *psoc) +{ + return &((psoc->soc_cb.tx_ops.cfr_tx_ops)); +} + +int tgt_cfr_get_target_type(struct wlan_objmgr_psoc *psoc) +{ + uint32_t target_type = 0; + struct wlan_lmac_if_target_tx_ops *target_type_tx_ops; + + target_type_tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops; + + if (target_type_tx_ops->tgt_get_tgt_type) + target_type = target_type_tx_ops->tgt_get_tgt_type(psoc); + + return target_type; +} + +int tgt_cfr_init_pdev(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + int status = 0; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_init_pdev) + status = cfr_tx_ops->cfr_init_pdev(psoc, pdev); + + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +int tgt_cfr_deinit_pdev(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + int status = 0; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_deinit_pdev) + status = cfr_tx_ops->cfr_deinit_pdev(psoc, pdev); + + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +int tgt_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *cfr_params) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + int status = 0; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_start_capture) + status = cfr_tx_ops->cfr_start_capture(pdev, peer, cfr_params); + + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + int status = 0; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_stop_capture) + status = cfr_tx_ops->cfr_stop_capture(pdev, peer); + + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +int +tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer) +{ + int status = 0; + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_enable_cfr_timer) + status = cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer); + + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +#ifdef WLAN_ENH_CFR_ENABLE +QDF_STATUS +tgt_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_param) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_config_rcc) + status = cfr_tx_ops->cfr_config_rcc(pdev, rcc_param); + + if (status != QDF_STATUS_SUCCESS) + cfr_err("Error occurred with exit code %d\n", status); + + return status; +} + +void tgt_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + cfr_err("Invalid PSOC: Flush LUT Timer cannot be started\n"); + return; + } + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_start_lut_timer) + cfr_tx_ops->cfr_start_lut_timer(pdev); +} + +void tgt_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + cfr_err("Invalid PSOC: Flush LUT Timer cannot be stopped\n"); + return; + } + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_stop_lut_timer) + cfr_tx_ops->cfr_stop_lut_timer(pdev); +} + +void tgt_cfr_default_ta_ra_cfg(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *rcc_param, + bool allvalid, uint16_t reset_cfg) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_default_ta_ra_cfg) + cfr_tx_ops->cfr_default_ta_ra_cfg(rcc_param, + allvalid, reset_cfg); +} + +void tgt_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_dump_lut_enh) + cfr_tx_ops->cfr_dump_lut_enh(pdev); +} + +void tgt_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_rx_tlv_process) + cfr_tx_ops->cfr_rx_tlv_process(pdev, nbuf); +} + +void tgt_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + cfr_err("Invalid PSOC:Cannot update global config.\n"); + return; + } + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_update_global_cfg) + cfr_tx_ops->cfr_update_global_cfg(pdev); +} + +QDF_STATUS tgt_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe) +{ + struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + cfr_err("Invalid psoc\n"); + return QDF_STATUS_E_INVAL; + } + + cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); + + if (cfr_tx_ops->cfr_subscribe_ppdu_desc) + return cfr_tx_ops->cfr_subscribe_ppdu_desc(pdev, + is_subscribe); + + return QDF_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c new file mode 100644 index 0000000000000000000000000000000000000000..7ae271105e2d8928627b19cc65aa5ae51cd9db24 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c @@ -0,0 +1,1124 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include "cfr_defs_i.h" +#include +#include +#include +#include +#include +#ifdef WLAN_ENH_CFR_ENABLE +#include "cdp_txrx_ctrl.h" +#endif + +int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer, + struct cfr_capture_params *params) +{ + int status; + struct pdev_cfr *pa; + struct peer_cfr *pe; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (NULL == pa) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + /* Get peer private object */ + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + if (NULL == pe) { + cfr_err("PEER cfr object is NULL!\n"); + return -EINVAL; + } + + if ((params->period < 0) || (params->period > MAX_CFR_PRD) || + (params->period % 10)) { + cfr_err("Invalid period value: %d\n", params->period); + return -EINVAL; + } + + if (!(params->period) && (pa->cfr_timer_enable)) { + cfr_err("Single shot capture is not allowed during periodic capture\n"); + return -EINVAL; + } + + if ((params->period) && !(pa->cfr_timer_enable)) { + cfr_err("Global periodic timer is not enabled, configure global cfr timer\n"); + } + + if (params->period) { + if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) { + qdf_info("max periodic cfr clients reached\n"); + return -EINVAL; + } + if (!(pe->request)) + pa->cfr_current_sta_count++; + } + + status = tgt_cfr_start_capture(pdev, peer, params); + + if (status == 0) { + pe->bandwidth = params->bandwidth; + pe->period = params->period; + pe->capture_method = params->method; + pe->request = PEER_CFR_CAPTURE_ENABLE; + } else + pa->cfr_current_sta_count--; + + return status; +} + +int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac, + struct cfr_capture_params *params) +{ + int idx, idx_to_insert = -1; + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pa) { + cfr_err("Pdev cfr object is null!"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + cfr_err("CFR is not supported on this chip"); + return -EINVAL; + } + + if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) { + cfr_err("max cfr cleint reached"); + return -EINVAL; + } + + for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) { + /* Store first invalid entry's index, to add mac entry if not + * already present. + */ + if (idx_to_insert < 0) { + if (pa->unassoc_pool[idx].is_valid != true) + idx_to_insert = idx; + } + + /* Add new mac entry only if it is not present. If already + * present, update the capture parameters + */ + if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac, + sizeof(struct qdf_mac_addr)) == 0) { + cfr_info("Node already present. Updating params"); + qdf_mem_copy(&pa->unassoc_pool[idx].cfr_params, + params, + sizeof(struct cfr_capture_params)); + pa->unassoc_pool[idx].is_valid = true; + return 0; + } + } + + if (idx_to_insert < 0) { + /* All the entries in the table are valid. So we have reached + * max client capacity. To add a new client, capture on one of + * the clients in table has to be stopped. + */ + cfr_err("Maximum client capacity reached"); + return -EINVAL; + } + + /* If control reaches here, we did not find mac in the table + * and we have atleast one free entry in table. + * Add the entry at index = idx_to_insert + */ + qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].mac, + unassoc_mac, sizeof(struct qdf_mac_addr)); + qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].cfr_params, + params, sizeof(struct cfr_capture_params)); + pa->unassoc_pool[idx_to_insert].is_valid = true; + pa->cfr_current_sta_count++; + + return 0; +} + +int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac) +{ + struct pdev_cfr *pa; + int idx; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pa) { + cfr_err("Pdev cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + cfr_err("CFR is not supported on this chip\n"); + return -EINVAL; + } + + for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) { + /* Remove mac only if it is present */ + if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac, + sizeof(struct qdf_mac_addr)) == 0) { + qdf_mem_zero(&pa->unassoc_pool[idx], + sizeof(struct unassoc_pool_entry)); + pa->cfr_current_sta_count--; + return 0; + } + } + + /* If mac was present in pool it would have been deleted in the + * above loop and returned from there. + * If control reached here, mac was not found. So, ignore the request. + */ + cfr_err("Trying to delete mac not present in pool. Ignoring request."); + return 0; +} + +int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value) +{ + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + return tgt_cfr_enable_cfr_timer(pdev, value); +} +qdf_export_symbol(ucfg_cfr_set_timer); + +int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + return pa->cfr_timer_enable; +} +qdf_export_symbol(ucfg_cfr_get_timer); + +int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_peer *peer) +{ + int status; + struct peer_cfr *pe; + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + if (pe == NULL) { + cfr_err("PEER cfr object is NULL!\n"); + return -EINVAL; + } + + if ((pe->period) && (pe->request)) + status = tgt_cfr_stop_capture(pdev, peer); + else { + qdf_info("periodic cfr not started for the client\n"); + return -EINVAL; + } + + if (status == 0) { + pe->request = PEER_CFR_CAPTURE_DISABLE; + pa->cfr_current_sta_count--; + } + + return status; +} + +int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev) +{ + return 0; +} + +QDF_STATUS ucfg_cfr_stop_indication(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + cfr_err("null vdev"); + return QDF_STATUS_E_INVAL; + } + + return cfr_stop_indication(vdev); +} + +#ifdef WLAN_ENH_CFR_ENABLE + +static inline +QDF_STATUS dev_sanity_check(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_pdev **ppdev, + struct pdev_cfr **ppcfr) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!vdev) { + cfr_err("vdev is NULL\n"); + return QDF_STATUS_E_NULL_VALUE; + } + + *ppdev = wlan_vdev_get_pdev(vdev); + + if (!*ppdev) { + cfr_err("pdev is NULL\n"); + return QDF_STATUS_E_NULL_VALUE; + } + + status = wlan_objmgr_pdev_try_get_ref(*ppdev, WLAN_CFR_ID); + if (status != QDF_STATUS_SUCCESS) { + cfr_err("Failed to get pdev reference\n"); + return status; + } + + *ppcfr = wlan_objmgr_pdev_get_comp_private_obj(*ppdev, + WLAN_UMAC_COMP_CFR); + + if (!(*ppcfr)) { + cfr_err("pdev object for CFR is null"); + wlan_objmgr_pdev_release_ref(*ppdev, WLAN_CFR_ID); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!(*ppcfr)->is_cfr_rcc_capable) { + cfr_err("cfr is not supported on this chip\n"); + wlan_objmgr_pdev_release_ref(*ppdev, WLAN_CFR_ID); + return QDF_STATUS_E_NOSUPPORT; + } + + return status; +} + +/* + * This is needed only in case of m_ta_ra_filter mode. + * If user wants to reset the group configurations to default values, + * then this handler will come into action. + * + * If user wants to reset the configurations of 0th, 1st and 3rd group, + * then the input should be : + * + * wlanconfig ath0 cfr reset_cfg 0xb + * + */ + +QDF_STATUS ucfg_cfr_set_reset_bitmap(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.modified_in_curr_session |= params->reset_cfg; + tgt_cfr_default_ta_ra_cfg(pdev, &pcfr->rcc_param, + true, params->reset_cfg); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * This is needed only in case of m_ta_ra_filter mode. + * After providing all the group configurations, user should provide + * the information about which groups need to be enabled. + * Based on that FW will enable the configurations for CFR groups. + * If user has to enable only 0th group, then input should be : + * + * wlanconfig ath0 cfr en_cfg 0x1 + * + * Enable the bitmap from user provided configuration into cfr_rcc_param. + */ + +QDF_STATUS ucfg_cfr_set_en_bitmap(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.filter_group_bitmap = params->en_cfg; + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Copy user provided input for ul_mu_user_mask into cfr_rcc_param. + */ + +QDF_STATUS +ucfg_cfr_set_ul_mu_user_mask(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.ul_mu_user_mask_lower = params->ul_mu_user_mask_lower; + pcfr->rcc_param.ul_mu_user_mask_upper = params->ul_mu_user_mask_upper; + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * FREEZE_TLV_DELAY_CNT_* registers are used for FREEZE TLV timeout mechanism + * in MAC side. In case MAC send FREEZE TLV to PHY too late due to + * long AST delay, PHY ucode may not handle it well or it will impact + * next frame’s normal processing, then MAC needs to drop FREEZE TLV + * sending process after reaching the threshold. + * + * This handler will copy user provided input for freeze_tlv_delay_cnt + * into cfr_rcc_param. + */ + +QDF_STATUS +ucfg_cfr_set_freeze_tlv_delay_cnt(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.freeze_tlv_delay_cnt_en = + params->freeze_tlv_delay_cnt_en; + + pcfr->rcc_param.freeze_tlv_delay_cnt_thr = + params->freeze_tlv_delay_cnt_thr; + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Set capture interval from the provided configuration into cfr_rcc_param. + * All fixed parameters are needed to be stored into cfr_rcc_param. + */ + +QDF_STATUS +ucfg_cfr_set_capture_interval(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.capture_interval = params->cap_intvl; + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Set capture duration from the provided configuration into cfr_rcc_param. + * All fixed parameters are needed to be stored into cfr_rcc_param. + */ + +QDF_STATUS +ucfg_cfr_set_capture_duration(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + pcfr->rcc_param.capture_duration = params->cap_dur; + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Copy user provided group parameters( type/ subtype of mgmt, ctrl, data ) + * into curr_cfg instance of ta_ra_cfr_cfg. + * Set valid mask for the provided configuration. + * Set modified_in_this_session for the particular group. + */ + +QDF_STATUS +ucfg_cfr_set_frame_type_subtype(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct ta_ra_cfr_cfg *curr_cfg = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + /* Populating current config based on user's input */ + curr_cfg = &pcfr->rcc_param.curr[params->grp_id]; + curr_cfg->mgmt_subtype_filter = params->expected_mgmt_subtype; + curr_cfg->ctrl_subtype_filter = params->expected_ctrl_subtype; + curr_cfg->data_subtype_filter = params->expected_data_subtype; + + curr_cfg->valid_mgmt_subtype = 1; + curr_cfg->valid_ctrl_subtype = 1; + curr_cfg->valid_data_subtype = 1; + + qdf_set_bit(params->grp_id, + (unsigned long *) + &pcfr->rcc_param.modified_in_curr_session); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Copy user provided group parameters( BW and NSS ) + * into curr_cfg instance of ta_ra_cfr_cfg. + * Set valid mask for the provided configuration. + * Set modified_in_this_session for the particular group. + */ + +QDF_STATUS ucfg_cfr_set_bw_nss(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct ta_ra_cfr_cfg *curr_cfg = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + /* Populating current config based on user's input */ + curr_cfg = &pcfr->rcc_param.curr[params->grp_id]; + curr_cfg->bw = params->bw; + curr_cfg->nss = params->nss; + + curr_cfg->valid_bw_mask = 1; + curr_cfg->valid_nss_mask = 1; + + qdf_set_bit(params->grp_id, + (unsigned long *)&pcfr->rcc_param.modified_in_curr_session); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * Copy user provided group parameters( TA, RA, TA_MASK, RA_MASK ) + * into curr_cfg instance of ta_ra_cfr_cfg. + * Set valid mask for the provided configuration. + * Set modified_in_this_session for the particular group. + */ + +QDF_STATUS ucfg_cfr_set_tara_config(struct wlan_objmgr_vdev *vdev, + struct cfr_wlanconfig_param *params) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct ta_ra_cfr_cfg *curr_cfg = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + curr_cfg = &pcfr->rcc_param.curr[params->grp_id]; + qdf_mem_copy(curr_cfg->tx_addr, params->ta, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->rx_addr, params->ra, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->tx_addr_mask, + params->ta_mask, QDF_MAC_ADDR_SIZE); + qdf_mem_copy(curr_cfg->rx_addr_mask, + params->ra_mask, QDF_MAC_ADDR_SIZE); + + curr_cfg->valid_ta = 1; + curr_cfg->valid_ta_mask = 1; + curr_cfg->valid_ra = 1; + curr_cfg->valid_ra_mask = 1; + + qdf_set_bit(params->grp_id, + (unsigned long *) + &pcfr->rcc_param.modified_in_curr_session); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +static bool cfr_is_filter_enabled(struct cfr_rcc_param *rcc_param) +{ + if (rcc_param->m_directed_ftm || + rcc_param->m_all_ftm_ack || + rcc_param->m_ndpa_ndp_directed || + rcc_param->m_ndpa_ndp_all || + rcc_param->m_ta_ra_filter || + rcc_param->m_all_packet) + return true; + else + return false; +} + +QDF_STATUS ucfg_cfr_get_cfg(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct ta_ra_cfr_cfg *glbl_cfg = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t grp_id; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + if (!cfr_is_filter_enabled(&pcfr->rcc_param)) { + cfr_err(" All RCC modes are disabled.\n"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return status; + } + + cfr_err("CAPTURE MODE:\n"); + + cfr_err("m_directed_ftm is : %s\n", + pcfr->rcc_param.m_directed_ftm ? + "enabled" : "disabled"); + cfr_err("m_all_ftm_ack is : %s\n", + pcfr->rcc_param.m_all_ftm_ack ? + "enabled" : "disabled"); + cfr_err("m_ndpa_ndp_directed is: %s\n", + pcfr->rcc_param.m_ndpa_ndp_directed ? + "enabled" : "disabled"); + cfr_err("m_ndpa_ndp_all is : %s\n", + pcfr->rcc_param.m_ndpa_ndp_all ? + "enabled" : "disabled"); + cfr_err("m_ta_ra_filter is : %s\n", + pcfr->rcc_param.m_ta_ra_filter ? + "enabled" : "disabled"); + cfr_err("m_all_packet is : %s\n", + pcfr->rcc_param.m_all_packet ? + "enabled" : "disabled"); + + cfr_err("capture duration : %u usec\n", + pcfr->rcc_param.capture_duration); + cfr_err("capture interval : %u usec\n", + pcfr->rcc_param.capture_interval); + cfr_err("UL MU User mask lower : %u\n", + pcfr->rcc_param.ul_mu_user_mask_lower); + cfr_err("UL MU User mask upper : %u\n", + pcfr->rcc_param.ul_mu_user_mask_upper); + cfr_err("Freeze TLV delay count is : %s\n", + pcfr->rcc_param.freeze_tlv_delay_cnt_en ? + "enabled" : "disabled"); + cfr_err("Freeze TLV delay count threshold : %u\n", + pcfr->rcc_param.freeze_tlv_delay_cnt_thr); + cfr_err("Enabled CFG id bitmap : 0x%x\n", + pcfr->rcc_param.filter_group_bitmap); + cfr_err(" Modified cfg id bitmap : 0x%x\n", + pcfr->rcc_param.modified_in_curr_session); + + cfr_err("TARA_CONFIG details:\n"); + + for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { + glbl_cfg = &pcfr->global[grp_id]; + + cfr_err("Config ID: %d\n", grp_id); + cfr_err("Bandwidth :0x%x\n", glbl_cfg->bw); + cfr_err("NSS : 0x%x\n", glbl_cfg->nss); + cfr_err("valid_ta: %d\n", glbl_cfg->valid_ta); + cfr_err("valid_ta_mask: %d\n", glbl_cfg->valid_ta_mask); + cfr_err("valid_ra: %d\n", glbl_cfg->valid_ra); + cfr_err("valid_ra_mask: %d\n", glbl_cfg->valid_ra_mask); + cfr_err("valid_bw_mask: %d\n", glbl_cfg->valid_bw_mask); + cfr_err("valid_nss_mask: %d\n", glbl_cfg->valid_nss_mask); + cfr_err("valid_mgmt_subtype: %d\n", + glbl_cfg->valid_mgmt_subtype); + cfr_err("valid_ctrl_subtype: %d\n", + glbl_cfg->valid_ctrl_subtype); + cfr_err("valid_data_subtype: %d\n", + glbl_cfg->valid_data_subtype); + cfr_err("Mgmt subtype : 0x%x\n", + glbl_cfg->mgmt_subtype_filter); + cfr_err("CTRL subtype : 0x%x\n", + glbl_cfg->ctrl_subtype_filter); + cfr_err("Data subtype : 0x%x\n", + glbl_cfg->data_subtype_filter); + cfr_err("TX Addr: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(glbl_cfg->tx_addr)); + cfr_err("TX Addr Mask: " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(glbl_cfg->tx_addr_mask)); + cfr_err("RX Addr: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(glbl_cfg->rx_addr)); + cfr_err("RX Addr Mask: " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(glbl_cfg->rx_addr_mask)); + } + + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +static const char *chan_capture_status_to_str(enum chan_capture_status type) +{ + switch (type) { + case CAPTURE_IDLE: + return "CAPTURE_IDLE"; + case CAPTURE_BUSY: + return "CAPTURE_BUSY"; + case CAPTURE_ACTIVE: + return "CAPTURE_ACTIVE"; + case CAPTURE_NO_BUFFER: + return "CAPTURE_NO_BUFFER"; + default: + return "INVALID"; + } +} + +static const +char *mac_freeze_reason_to_str(enum mac_freeze_capture_reason type) +{ + switch (type) { + case FREEZE_REASON_TM: + return "FREEZE_REASON_TM"; + case FREEZE_REASON_FTM: + return "FREEZE_REASON_FTM"; + case FREEZE_REASON_ACK_RESP_TO_TM_FTM: + return "FREEZE_REASON_ACK_RESP_TO_TM_FTM"; + case FREEZE_REASON_TA_RA_TYPE_FILTER: + return "FREEZE_REASON_TA_RA_TYPE_FILTER"; + case FREEZE_REASON_NDPA_NDP: + return "FREEZE_REASON_NDPA_NDP"; + case FREEZE_REASON_ALL_PACKET: + return "FREEZE_REASON_ALL_PACKET"; + default: + return "INVALID"; + } +} + +QDF_STATUS ucfg_cfr_rcc_dump_dbg_counters(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct wlan_objmgr_psoc *psoc = NULL; + struct cdp_cfr_rcc_stats *cfr_rcc_stats = NULL; + uint8_t stats_cnt; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + cfr_err("psoc is null!"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return QDF_STATUS_E_NULL_VALUE; + } + + cfr_err("total_tx_evt_cnt = %llu\n", + pcfr->total_tx_evt_cnt); + cfr_err("dbr_evt_cnt = %llu\n", + pcfr->dbr_evt_cnt); + cfr_err("rx_tlv_evt_cnt = %llu\n", + pcfr->rx_tlv_evt_cnt); + cfr_err("release_cnt = %llu\n", + pcfr->release_cnt); + cfr_err("Error cnt:\n"); + cfr_err("flush_dbr_cnt = %llu\n", + pcfr->flush_dbr_cnt); + cfr_err("invalid_dma_length_cnt = %llu\n", + pcfr->invalid_dma_length_cnt); + cfr_err("flush_timeout_dbr_cnt = %llu\n", + pcfr->flush_timeout_dbr_cnt); + cfr_err("PPDU id mismatch for same cookie:\n"); + cfr_err("clear_txrx_event = %llu\n", + pcfr->clear_txrx_event); + cfr_err("cfr_dma_aborts = %llu\n", + pcfr->cfr_dma_aborts); + + cfr_rcc_stats = qdf_mem_malloc(sizeof(struct cdp_cfr_rcc_stats)); + if (!cfr_rcc_stats) { + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return QDF_STATUS_E_NOMEM; + } + + cdp_get_cfr_dbg_stats(wlan_psoc_get_dp_handle(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev), + cfr_rcc_stats); + + cfr_err("bb_captured_channel_cnt: %llu\n", + cfr_rcc_stats->bb_captured_channel_cnt); + cfr_err("bb_captured_timeout_cnt: %llu\n", + cfr_rcc_stats->bb_captured_timeout_cnt); + cfr_err("rx_loc_info_valid_cnt: %llu\n", + cfr_rcc_stats->rx_loc_info_valid_cnt); + + cfr_err("Channel capture status:\n"); + for (stats_cnt = 0; stats_cnt < CAPTURE_MAX; stats_cnt++) { + cfr_err("%s = %llu\n", + chan_capture_status_to_str(stats_cnt), + cfr_rcc_stats->chan_capture_status[stats_cnt]); + } + + cfr_err("Freeze reason:\n"); + for (stats_cnt = 0; stats_cnt < FREEZE_REASON_MAX; stats_cnt++) { + cfr_err("%s = %llu\n", + mac_freeze_reason_to_str(stats_cnt), + cfr_rcc_stats->reason_cnt[stats_cnt]); + } + + qdf_mem_free(cfr_rcc_stats); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +QDF_STATUS ucfg_cfr_rcc_clr_dbg_counters(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct wlan_objmgr_psoc *psoc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + cfr_err("psoc is null!"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + return QDF_STATUS_E_NULL_VALUE; + } + cdp_cfr_clr_dbg_stats(wlan_psoc_get_dp_handle(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev)); + + pcfr->dbr_evt_cnt = 0; + pcfr->release_cnt = 0; + pcfr->total_tx_evt_cnt = 0; + pcfr->rx_tlv_evt_cnt = 0; + pcfr->flush_dbr_cnt = 0; + pcfr->flush_timeout_dbr_cnt = 0; + pcfr->invalid_dma_length_cnt = 0; + pcfr->clear_txrx_event = 0; + pcfr->cfr_dma_aborts = 0; + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +QDF_STATUS ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!vdev) { + cfr_err("vdev is NULL\n"); + return QDF_STATUS_E_INVAL; + } + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + cfr_err("pdev is NULL\n"); + return QDF_STATUS_E_INVAL; + } + + if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID) != + QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_INVAL; + } + + cfr_err("LUT table:\n"); + tgt_cfr_dump_lut_enh(pdev); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +static void cfr_set_filter(struct wlan_objmgr_pdev *pdev, bool enable, + struct cdp_monitor_filter *filter_val) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + cfr_info("pdev_id=%d\n", wlan_objmgr_pdev_get_pdev_id(pdev)); + + cdp_cfr_filter(wlan_psoc_get_dp_handle(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev), + enable, + filter_val); +} + +/* + * With the initiation of commit command, this handler will be triggered. + * + * Starts the procedure of forming the TLVs. + * If Host succeeds to send WMI command to FW, after TLV processing, then it + * will save the previous CFR configurations into one instance ta_ra_cfr_cfg, + * called glbl_cfg and update the current config to default state for the + * next commit session. + * + * Finally, reset the counter (modified_in_this_session) to 0 before moving to + * next commit session. + * + */ + +QDF_STATUS ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + struct wlan_objmgr_psoc *psoc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct cdp_monitor_filter filter_val = {0}; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + cfr_err("psoc is null!"); + return QDF_STATUS_E_NULL_VALUE; + } + + pcfr->rcc_param.vdev_id = wlan_vdev_get_id(vdev); + + /* + * If capture mode is valid, then Host: + * Subscribes for PPDU status TLVs in monitor status ring. + * Sets filter type to either FP or MO, based on the capture mode. + * Starts the LUT_AGE_TIMER of 1sec. + * + * If capture mode is disabled, then Host: + * unsubscribes for PPDU status TLVs in monitor status ring. + * Sets filter type to 0. + * Stops the LUT_AGE_TIMER. + * + */ + + if (cfr_is_filter_enabled(&pcfr->rcc_param)) { + if (pcfr->rcc_param.m_all_ftm_ack) { + filter_val.mode |= MON_FILTER_PASS | + MON_FILTER_OTHER; + filter_val.fp_mgmt |= FILTER_MGMT_ACTION; + filter_val.mo_mgmt |= FILTER_MGMT_ACTION; + } + + if (pcfr->rcc_param.m_ndpa_ndp_all) { + filter_val.mode |= MON_FILTER_PASS | + MON_FILTER_OTHER; + filter_val.fp_ctrl |= FILTER_CTRL_VHT_NDP; + filter_val.mo_ctrl |= FILTER_CTRL_VHT_NDP; + } + + if (pcfr->rcc_param.m_all_packet) { + filter_val.mode |= MON_FILTER_PASS | + MON_FILTER_OTHER; + filter_val.fp_mgmt |= FILTER_MGMT_ALL; + filter_val.mo_mgmt |= FILTER_MGMT_ALL; + filter_val.fp_ctrl |= FILTER_CTRL_ALL; + filter_val.mo_ctrl |= FILTER_CTRL_ALL; + filter_val.fp_data |= FILTER_DATA_ALL; + filter_val.mo_data |= FILTER_DATA_ALL; + } + + /* + * M_TA_RA in monitor other is as intensive as M_ALL pkt + * Support only FP in M_TA_RA mode + */ + if (pcfr->rcc_param.m_ta_ra_filter) { + filter_val.mode |= MON_FILTER_PASS | + MON_FILTER_OTHER; + filter_val.fp_mgmt |= FILTER_MGMT_ALL; + filter_val.mo_mgmt |= FILTER_MGMT_ALL; + filter_val.fp_ctrl |= FILTER_CTRL_ALL; + filter_val.mo_ctrl |= FILTER_CTRL_ALL; + filter_val.fp_data |= FILTER_DATA_ALL; + filter_val.mo_data |= FILTER_DATA_ALL; + } + + if (pcfr->rcc_param.m_directed_ftm) { + filter_val.mode |= MON_FILTER_PASS; + filter_val.fp_mgmt |= FILTER_MGMT_ACTION; + } + + if (pcfr->rcc_param.m_ndpa_ndp_directed) { + filter_val.mode |= MON_FILTER_PASS; + filter_val.fp_ctrl |= FILTER_CTRL_VHT_NDP; + } + + if (!cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev))) + tgt_cfr_start_lut_age_timer(pdev); + cfr_set_filter(pdev, 1, &filter_val); + } else { + if (cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc), + wlan_objmgr_pdev_get_pdev_id(pdev))) + tgt_cfr_stop_lut_age_timer(pdev); + cfr_set_filter(pdev, 0, &filter_val); + } + + /* Trigger wmi to start the TLV processing. */ + status = tgt_cfr_config_rcc(pdev, &pcfr->rcc_param); + if (status == QDF_STATUS_SUCCESS) { + cfr_info("CFR commit done\n"); + /* Update global config */ + tgt_cfr_update_global_cfg(pdev); + + /* Bring curr_cfg to default state for next commit session */ + tgt_cfr_default_ta_ra_cfg(pdev, &pcfr->rcc_param, + false, MAX_RESET_CFG_ENTRY); + } else { + cfr_err("CFR commit failed\n"); + } + + pcfr->rcc_param.num_grp_tlvs = 0; + pcfr->rcc_param.modified_in_curr_session = 0; + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +/* + * This handler is used to enable / disable the capture mode. + * + */ +QDF_STATUS ucfg_cfr_set_rcc_mode(struct wlan_objmgr_vdev *vdev, + enum capture_type mode, uint8_t value) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return status; + + switch (mode) { + case RCC_DIRECTED_FTM_FILTER: + pcfr->rcc_param.m_directed_ftm = value; + break; + case RCC_ALL_FTM_ACK_FILTER: + pcfr->rcc_param.m_all_ftm_ack = value; + break; + case RCC_DIRECTED_NDPA_NDP_FILTER: + pcfr->rcc_param.m_ndpa_ndp_directed = value; + break; + case RCC_NDPA_NDP_ALL_FILTER: + pcfr->rcc_param.m_ndpa_ndp_all = value; + break; + case RCC_TA_RA_FILTER: + pcfr->rcc_param.m_ta_ra_filter = value; + break; + case RCC_ALL_PACKET_FILTER: + pcfr->rcc_param.m_all_packet = value; + break; + case RCC_DIS_ALL_MODE: + pcfr->rcc_param.m_directed_ftm = value; + pcfr->rcc_param.m_all_ftm_ack = value; + pcfr->rcc_param.m_ndpa_ndp_directed = value; + pcfr->rcc_param.m_ndpa_ndp_all = value; + pcfr->rcc_param.m_ta_ra_filter = value; + pcfr->rcc_param.m_all_packet = value; + break; + + default: + break; + } + + cfr_debug(" Capture mode set by user: 0x%x\n", value); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return status; +} + +bool ucfg_cfr_get_rcc_enabled(struct wlan_objmgr_vdev *vdev) +{ + struct pdev_cfr *pcfr = NULL; + struct wlan_objmgr_pdev *pdev = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + bool rcc_enabled = false; + + status = dev_sanity_check(vdev, &pdev, &pcfr); + if (status != QDF_STATUS_SUCCESS) + return false; + + rcc_enabled = cfr_is_filter_enabled(&pcfr->rcc_param); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); + + return rcc_enabled; +} + +QDF_STATUS ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, + bool is_subscribe) +{ + return tgt_cfr_subscribe_ppdu_desc(pdev, is_subscribe); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c new file mode 100644 index 0000000000000000000000000000000000000000..4cb8ea2298e2710d78df20ba9bd0f71524ff0863 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#include "../../core/inc/cfr_defs_i.h" +#include +#include + +QDF_STATUS wlan_cfr_init(void) +{ + if (wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_psoc_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_psoc_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_pdev_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_pdev_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_register_peer_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_peer_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_register_peer_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_peer_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cfr_deinit(void) +{ + if (wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_psoc_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_psoc_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_pdev_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_pdev_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_peer_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CFR, + wlan_cfr_peer_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cfr_pdev_open(struct wlan_objmgr_pdev *pdev) +{ + int status; + + /* chip specific init */ + status = tgt_cfr_init_pdev(pdev); + + if (status != QDF_STATUS_SUCCESS) { + cfr_err("tgt_cfr_init_pdev failed with %d\n", status); + return QDF_STATUS_SUCCESS; + } + + /* RealyFS init */ + status = cfr_streamfs_init(pdev); + + if (status != QDF_STATUS_SUCCESS) { + cfr_err("cfr_streamfs_init failed with %d\n", status); + return QDF_STATUS_SUCCESS; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_cfr_pdev_close(struct wlan_objmgr_pdev *pdev) +{ + int status = QDF_STATUS_SUCCESS; + /* + * DBR does not have close as of now; + * but this is getting added as part for new gerrit + * Once we have that support we will add it. + */ + status = cfr_streamfs_remove(pdev); + + return status; +} + +QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev) +{ + int status = QDF_STATUS_SUCCESS; + + /* chip specific init */ + + status = tgt_cfr_init_pdev(pdev); + + if (status != QDF_STATUS_SUCCESS) + cfr_err("cfr_initialize_pdev status=%d\n", status); + + return status; +} +qdf_export_symbol(cfr_initialize_pdev); + +QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev) +{ + int status = QDF_STATUS_SUCCESS; + + /* chip specific deinit */ + + status = tgt_cfr_deinit_pdev(pdev); + + if (status != QDF_STATUS_SUCCESS) + cfr_err("cfr_deinitialize_pdev status=%d\n", status); + + return status; +} +qdf_export_symbol(cfr_deinitialize_pdev); + +uint8_t count_set_bits(uint32_t value) +{ + uint8_t count = 0; + + while (value) { + value &= (value - 1); + count++; + } + + return count; +} + +qdf_export_symbol(count_set_bits); + +#ifdef WLAN_ENH_CFR_ENABLE +void wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) +{ + tgt_cfr_rx_tlv_process(pdev, nbuf); +} + +qdf_export_symbol(wlan_cfr_rx_tlv_process); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index 7f055208569dd94bae9f029165223f572822851d..bd8814cda7ce3a5ea5020b7f8d2abaac1251b8e7 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -134,6 +135,7 @@ #define WLAN_IBSS_IE_MAX_LEN 2 #define WLAN_REQUEST_IE_MAX_LEN 255 #define WLAN_RM_CAPABILITY_IE_MAX_LEN 5 +#define WLAN_RNR_IE_MIN_LEN 5 /* Wide band channel switch IE length */ #define WLAN_WIDE_BW_CHAN_SWITCH_IE_LEN 3 @@ -189,6 +191,19 @@ /* 80 + 80 MHz Operating Channel (revised signalling) */ #define WLAN_VHTOP_CHWIDTH_REVSIG_80_80 1 +#define WLAN_HEOP_FIXED_PARAM_LENGTH 7 +#define WLAN_HEOP_VHTOP_LENGTH 3 +#define WLAN_HEOP_CO_LOCATED_BSS_LENGTH 1 + +#define WLAN_HEOP_VHTOP_PRESENT_MASK 0x00004000 /* B14 */ +#define WLAN_HEOP_CO_LOCATED_BSS_MASK 0x00008000 /* B15 */ +#define WLAN_HEOP_6GHZ_INFO_PRESENT_MASK 0X00020000 /* B17 */ + +#define WLAN_HE_6GHZ_CHWIDTH_20 0 /* 20MHz Oper Ch width */ +#define WLAN_HE_6GHZ_CHWIDTH_40 1 /* 40MHz Oper Ch width */ +#define WLAN_HE_6GHZ_CHWIDTH_80 2 /* 80MHz Oper Ch width */ +#define WLAN_HE_6GHZ_CHWIDTH_160_80_80 3 /* 160/80+80 MHz Oper Ch width */ + #define WLAN_RATE_VAL 0x7f #define WLAN_BASIC_RATE_MASK 0x80 @@ -201,6 +216,9 @@ #define WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123 #define WLAN_BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 +#define WLAN_MIN_HECAP_IE_LEN 22 +#define WLAN_MAX_HECAP_IE_LEN 55 + #define WLAN_CHAN_IS_5GHZ(chanidx) \ ((chanidx > 30) ? true : false) #define WLAN_CHAN_IS_2GHZ(chanidx) \ @@ -218,6 +236,20 @@ ((vhtop)->vht_op_ch_freq_seg2 != 0) && \ (abs((vhtop)->vht_op_ch_freq_seg2 - (vhtop)->vht_op_ch_freq_seg1) > 8)) +/* Check if channel width is HE160 in HE 6ghz params */ +#define WLAN_IS_HE160(he_6g_param) (((he_6g_param)->width == \ + WLAN_HE_6GHZ_CHWIDTH_160_80_80) && \ + ((he_6g_param)->chan_freq_seg1 != 0) && \ + (abs((he_6g_param)->chan_freq_seg1 - \ + (he_6g_param)->chan_freq_seg0) == 8)) + +/* Check if channel width is HE80p80 in HE 6ghz params */ +#define WLAN_IS_HE80_80(he_6g_param) (((he_6g_param)->width == \ + WLAN_HE_6GHZ_CHWIDTH_160_80_80) && \ + ((he_6g_param)->chan_freq_seg1 != 0) && \ + (abs((he_6g_param)->chan_freq_seg1 - \ + (he_6g_param)->chan_freq_seg0) > 8)) + #define LE_READ_2(p) \ ((uint16_t)\ ((((const uint8_t *)(p))[0]) |\ @@ -397,6 +429,7 @@ enum element_ie { WLAN_ELEMID_AID = 197, WLAN_ELEMID_QUIET_CHANNEL = 198, WLAN_ELEMID_OP_MODE_NOTIFY = 199, + WLAN_ELEMID_REDUCED_NEIGHBOR_REPORT = 201, WLAN_ELEMID_VENDOR = 221, WLAN_ELEMID_FILS_INDICATION = 240, WLAN_ELEMID_RSNXE = 244, @@ -409,6 +442,7 @@ enum element_ie { * @WLAN_EXTN_ELEMID_HECAP: HE capabilities IE * @WLAN_EXTN_ELEMID_HEOP: HE Operation IE * @WLAN_EXTN_ELEMID_MUEDCA: MU-EDCA IE + * @WLAN_EXTN_ELEMID_HE_6G_CAP: HE 6GHz Band Capabilities IE * @WLAN_EXTN_ELEMID_SRP: spatial reuse parameter IE */ enum extn_element_ie { @@ -417,6 +451,7 @@ enum extn_element_ie { WLAN_EXTN_ELEMID_HEOP = 36, WLAN_EXTN_ELEMID_MUEDCA = 38, WLAN_EXTN_ELEMID_SRP = 39, + WLAN_EXTN_ELEMID_HE_6G_CAP = 59, WLAN_EXTN_ELEMID_ESP = 11, }; @@ -504,6 +539,19 @@ enum extn_element_ie { * listen interval is too large. * @STATUS_INVALID_FT_ACTION_FRAME_COUNT: Invalid FT Action frame count. * @STATUS_INVALID_PMKID: Invalid pairwise master key identifier (PMKID). + * + * Internal status codes: Add any internal status code just after + * STATUS_PROP_START and decrease the value of STATUS_PROP_START + * accordingly. + * + * @STATUS_PROP_START: Start of prop status codes. + * @STATUS_NO_NETWORK_FOUND: No network found + * @STATUS_AUTH_TX_FAIL: Failed to sent AUTH on air + * @STATUS_AUTH_NO_ACK_RECEIVED: No ack received for Auth tx + * @STATUS_AUTH_NO_RESP_RECEIVED: No Auth response for Auth tx + * @STATUS_ASSOC_TX_FAIL: Failed to sent Assoc on air + * @STATUS_ASSOC_NO_ACK_RECEIVED: No ack received for Assoc tx + * @STATUS_ASSOC_NO_RESP_RECEIVED: No Assoc response for Assoc tx */ enum wlan_status_code { STATUS_SUCCESS = 0, @@ -552,6 +600,16 @@ enum wlan_status_code { STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51, STATUS_INVALID_FT_ACTION_FRAME_COUNT = 52, STATUS_INVALID_PMKID = 53, + + /* Error STATUS code for intenal usage*/ + STATUS_PROP_START = 65528, + STATUS_NO_NETWORK_FOUND = 65528, + STATUS_AUTH_TX_FAIL = 65529, + STATUS_AUTH_NO_ACK_RECEIVED = 65530, + STATUS_AUTH_NO_RESP_RECEIVED = 65531, + STATUS_ASSOC_TX_FAIL = 65532, + STATUS_ASSOC_NO_ACK_RECEIVED = 65533, + STATUS_ASSOC_NO_RESP_RECEIVED = 65534, }; #define WLAN_OUI_SIZE 4 @@ -1113,6 +1171,26 @@ struct wlan_ie_vhtop { uint16_t vhtop_basic_mcs_set; } qdf_packed; +/** + * struct he_oper_6g_param: 6 Ghz params for HE + * @primary_channel: HE 6GHz Primary channel number + * @width: HE 6GHz BSS Channel Width + * @duplicate_beacon: HE 6GHz Duplicate beacon field + * @reserved: Reserved bits + * @chan_freq_seg0: HE 6GHz Channel Centre Frequency Segment 0 + * @chan_freq_seg1: HE 6GHz Channel Centre Frequency Segment 1 + * @minimum_rate: HE 6GHz Minimum Rate + */ +struct he_oper_6g_param { + uint8_t primary_channel; + uint8_t width:2, + duplicate_beacon:1, + reserved:5; + uint8_t chan_freq_seg0; + uint8_t chan_freq_seg1; + uint8_t minimum_rate; +} qdf_packed; + /** * struct wlan_country_ie: country IE * @ie: country IE diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index f2d5ef1adfa2c0b0d530b6d85fb2e5af67ae3095..161fd0158c55b249e2a8b700c0d0e93f778412cc 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -244,6 +244,20 @@ bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev); bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_peer *peer); +/** + * wlan_crypto_is_key_valid - called by mgmt txrx to check if key is valid + * @vdev: vdev + * @peer: peer + * @keyidx : key index + * + * This function gets called by mgmt txrx to check if key is valid + * + * Return: true or false + */ +bool wlan_crypto_is_key_valid(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_peer *peer, + uint16_t keyidx); + /** * wlan_crypto_add_mmie - called by mgmt txrx to add mmie in frame * @vdev: vdev @@ -306,6 +320,21 @@ QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *, uint8_t *frm); */ uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev, uint8_t *iebuf); + +/** + * wlan_crypto_build_rsnie_with_pmksa() - called by mlme to build rsnie + * @vdev: vdev + * @iebuf: ie buffer + * @pmksa: pmksa struct + * + * This function gets called by mlme to build rsnie from given vdev + * + * Return: end of buffer + */ +uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct wlan_crypto_pmksa *pmksa); + /** * wlan_crypto_build_rsnie - called by mlme to build rsnie * @vdev: vdev @@ -682,6 +711,16 @@ bool wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc *psoc, uint16_t ie_len, struct wlan_crypto_params * peer_crypto_params); +/** + * wlan_crypto_parse_rsnxe_ie() - parse RSNXE IE + * @rsnxe_ie: RSNXE IE pointer + * @cap_len: pointer to hold len of ext capability + * + * Return: pointer to RSNXE capability or NULL + */ +uint8_t * +wlan_crypto_parse_rsnxe_ie(uint8_t *rsnxe_ie, uint8_t *cap_len); + /** * wlan_set_vdev_crypto_prarams_from_ie - Sets vdev crypto params from IE info * @vdev: vdev pointer @@ -812,6 +851,26 @@ struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev, QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *req, enum wlan_crypto_key_type key_type); + +/** + * wlan_crypto_free_vdev_key - Free keys for vdev + * @vdev: vdev object + * + * This function frees keys stored in vdev crypto object. + * + * Return: None + */ +void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev); + +/** + * wlan_crypto_reset_vdev_params - Reset params for vdev + * @vdev: vdev object + * + * This function reset params stored in vdev crypto object. + * + * Return: None + */ +void wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev *vdev); #else static inline void wlan_crypto_update_set_key_peer( struct wlan_objmgr_vdev *vdev, @@ -841,7 +900,29 @@ QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_SUCCESS; } + +static inline void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev) +{ +} + +static inline void wlan_crypto_reset_vdev_prarams(struct wlan_objmgr_vdev *vdev) +{ +} #endif /* CRYPTO_SET_KEY_CONVERGED */ + +/** + * wlan_crypto_get_peer_pmksa() - called to get pmksa based on pmksa parameter + * @vdev: vdev + * @pmksa: bssid + * + * This function is to get pmksa based on pmksa parameter + * + * Return: wlan_crypto_pmksa when match found else NULL. + */ +struct wlan_crypto_pmksa * +wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *pmksa); + /** * wlan_crypto_get_pmksa - called to get pmksa of bssid passed. * @vdev: vdev @@ -855,6 +936,21 @@ struct wlan_crypto_pmksa * wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid); +/** + * wlan_crypto_get_fils_pmksa - Get the PMKSA for FILS + * SSID, if the SSID and cache id matches + * @vdev: Pointer with VDEV object + * @cache_id: Cache id + * @ssid: Pointer to ssid + * @ssid_len: SSID length + * + * Return: PMKSA entry if the cache id and SSID matches + */ +struct wlan_crypto_pmksa * +wlan_crypto_get_fils_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *cache_id, uint8_t *ssid, + uint8_t ssid_len); + /** * wlan_crypto_pmksa_flush - called to flush saved pmksa * @crypto_params: crypto_params @@ -880,4 +976,42 @@ QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_pmksa *pmksa, bool set); +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * wlan_crypto_selective_clear_sae_single_pmk_entries - Clear the PMK entries + * for BSS which have the single PMK flag set other than the current connected + * AP + * @vdev: Vdev + * @conn_bssid: Connected bssid + */ +void +wlan_crypto_selective_clear_sae_single_pmk_entries( + struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *conn_bssid); + +/** + * wlan_crypto_set_sae_single_pmk_bss_cap - Set the peer SAE sinlge pmk + * feature supported status + * @vdev: Vdev + * @bssid: BSSID for which the flag is to be set + * @single_pmk_capable_bss: Flag to indicate Sae single pmk supported BSSID or + * not + */ +void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *bssid, + bool single_pmk_capable_bss); +#else +static inline void +wlan_crypto_selective_clear_sae_single_pmk_entries( + struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *conn_bssid) +{ +} + +static inline +void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *bssid, + bool single_pmk_capable_bss) +{ +} +#endif + #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h index 164140bad809d648db31ce8d9c13e1b26a76ea37..a5f489b530a6ec9087123e131761919ad35a3d7e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,6 +49,9 @@ #define WLAN_CRYPTO_KEYIX_NONE ((uint16_t)-1) #define WLAN_CRYPTO_MAXKEYIDX (4) #define WLAN_CRYPTO_MAXIGTKKEYIDX (2) +#ifndef WLAN_CRYPTO_MAX_VLANKEYIX +#define WLAN_CRYPTO_MAX_VLANKEYIX WLAN_CRYPTO_MAXKEYIDX +#endif #define WLAN_CRYPTO_MAX_PMKID (16) /* 40 bit wep key len */ @@ -91,6 +94,8 @@ #define WLAN_CRYPTO_KEY_SWDECRYPT (0x100) /* host-based demic */ #define WLAN_CRYPTO_KEY_SWDEMIC (0x200) +/* get pn from fw for key */ +#define WLAN_CRYPTO_KEY_GET_PN (0x400) #define WLAN_CRYPTO_KEY_SWCRYPT (WLAN_CRYPTO_KEY_SWENCRYPT \ | WLAN_CRYPTO_KEY_SWDECRYPT) @@ -173,6 +178,12 @@ typedef enum wlan_crypto_rsn_cap { WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED = 0x40, } wlan_crypto_rsn_cap; +enum wlan_crypto_rsnx_cap { + WLAN_CRYPTO_RSNX_CAP_PROTECTED_TWT = 0x10, + WLAN_CRYPTO_RSNX_CAP_SAE_H2E = 0x20, + WLAN_CRYPTO_RSNX_CAP_SAE_PK = 0x40, +}; + typedef enum wlan_crypto_key_mgmt { WLAN_CRYPTO_KEY_MGMT_IEEE8021X = 0, WLAN_CRYPTO_KEY_MGMT_PSK = 1, @@ -198,8 +209,9 @@ typedef enum wlan_crypto_key_mgmt { WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384 = 21, WLAN_CRYPTO_KEY_MGMT_OWE = 22, WLAN_CRYPTO_KEY_MGMT_DPP = 23, + WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384 = 24, /** Keep WLAN_CRYPTO_KEY_MGMT_MAX at the end. */ - WLAN_CRYPTO_KEY_MGMT_MAX = WLAN_CRYPTO_KEY_MGMT_DPP, + WLAN_CRYPTO_KEY_MGMT_MAX = WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384, } wlan_crypto_key_mgmt; enum wlan_crypto_key_type { @@ -216,13 +228,19 @@ enum wlan_crypto_key_type { * @pmkid: pmkid info * @pmk: pmk info * @pmk_len: pmk len + * @single_pmk_supported: SAE single pmk supported BSS */ - struct wlan_crypto_pmksa { struct qdf_mac_addr bssid; uint8_t pmkid[PMKID_LEN]; uint8_t pmk[MAX_PMK_LEN]; uint8_t pmk_len; + uint8_t ssid_len; + uint8_t ssid[WLAN_SSID_MAX_LEN]; + uint8_t cache_id[WLAN_CACHE_ID_LEN]; +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) + bool single_pmk_supported; +#endif }; /** @@ -348,6 +366,9 @@ struct wlan_crypto_req_key { * @delkey: function pointer to delkey in hw * @defaultkey: function pointer to set default key * @set_key: converged function pointer to set key in hw + * @getpn: function pointer to get current pn value of peer + * @register_events: function pointer to register wmi event handler + * @deregister_events: function pointer to deregister wmi event handler */ struct wlan_lmac_if_crypto_tx_ops { @@ -365,6 +386,10 @@ struct wlan_lmac_if_crypto_tx_ops { QDF_STATUS (*set_key)(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *key, enum wlan_crypto_key_type key_type); + QDF_STATUS(*getpn)(struct wlan_objmgr_vdev *vdev, + uint8_t *macaddr, uint32_t key_type); + QDF_STATUS (*register_events)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*deregister_events)(struct wlan_objmgr_psoc *psoc); }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_main.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_main.h index 7f4e59f9591cb0b18870d747676f698e0ba1d963..20c1be62ab92b9fd2f9ffda9592625ae62b0a45f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_main.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/inc/wlan_crypto_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -21,6 +21,7 @@ */ #ifndef _WLAN_CRYPTO_MAIN_H_ #define _WLAN_CRYPTO_MAIN_H_ +#include "wlan_crypto_global_def.h" /** * wlan_crypto_init - Init the crypto service with object manager @@ -38,5 +39,32 @@ QDF_STATUS wlan_crypto_init(void); */ QDF_STATUS wlan_crypto_deinit(void); +#ifdef CRYPTO_SET_KEY_CONVERGED +/** + * wlan_crypto_psoc_enable: psoc enable API for wlan crypto component + * @psoc: pointer to PSOC + * + * Return: status of operation + */ +QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_crypto_psoc_disable: psoc disable API for wlan crypto component + * @psoc: pointer to PSOC + * + * Return: status of operation + */ +QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* end of _WLAN_CRYPTO_MAIN_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_def_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_def_i.h index d25e8ff46002e0d068ac8cd452663f2dea4460c0..b82e848ff9c0433c4bf5ee21e05b49e0a05cc576 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_def_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_def_i.h @@ -171,6 +171,12 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val) (psoc->soc_cb.tx_ops.crypto_tx_ops.defaultkey) #define WLAN_CRYPTO_TX_OPS_SET_KEY(psoc) \ ((psoc)->soc_cb.tx_ops.crypto_tx_ops.set_key) +#define WLAN_CRYPTO_TX_OPS_GETPN(psoc) \ + ((psoc)->soc_cb.tx_ops.crypto_tx_ops.getpn) +#define WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(psoc) \ + ((psoc)->soc_cb.tx_ops.crypto_tx_ops.register_events) +#define WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(psoc) \ + ((psoc)->soc_cb.tx_ops.crypto_tx_ops.deregister_events) /* unalligned little endian access */ #ifndef LE_READ_2 @@ -255,7 +261,7 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val) WLAN_RSN_SEL(11) #define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192\ WLAN_RSN_SEL(12) -#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192\ +#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384\ WLAN_RSN_SEL(13) #define RSN_AUTH_KEY_MGMT_FILS_SHA256 WLAN_RSN_SEL(14) #define RSN_AUTH_KEY_MGMT_FILS_SHA384 WLAN_RSN_SEL(15) @@ -420,6 +426,33 @@ struct wlan_crypto_mmie { uint8_t mic[16]; } __packed; +/** + * struct crypto_add_key_result - add key result structure + * @vdev_id: unique id identifying the VDEV + * @key_ix: key index + * @key_flags: key flags + * @status: status of add key + * @peer_macaddr: MAC address of the peer + * + * Structure used for add key result. + */ +struct crypto_add_key_result { + uint32_t vdev_id; + uint32_t key_ix; + uint32_t key_flags; + uint32_t status; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; +}; + +/** + * typedef crypto_add_key_callback - add key callback + * @context: opaque context that the client can use to associate the + * callback with the request + * @result: result of add key + */ +typedef void (*crypto_add_key_callback)(void *context, + struct crypto_add_key_result *result); + /** * struct wlan_crypto_comp_priv - crypto component private structure * @crypto_params: crypto params for the peer @@ -429,16 +462,21 @@ struct wlan_crypto_mmie { * @def_tx_keyid: default key used for this peer * @def_igtk_tx_keyid default igtk key used for this peer * @fils_aead_set fils params for this peer + * @add_key_ctx: Opaque context to be used by the caller to associate the + * add key request with the response + * @add_key_cb: Callback function to be called with the add key result * */ struct wlan_crypto_comp_priv { struct wlan_crypto_params crypto_params; - struct wlan_crypto_key *key[WLAN_CRYPTO_MAXKEYIDX]; + struct wlan_crypto_key *key[WLAN_CRYPTO_MAX_VLANKEYIX]; struct wlan_crypto_key *igtk_key[WLAN_CRYPTO_MAXIGTKKEYIDX]; - uint32_t igtk_key_type; + enum wlan_crypto_cipher_type igtk_key_type; uint8_t def_tx_keyid; uint8_t def_igtk_tx_keyid; uint8_t fils_aead_set; + void *add_key_ctx; + crypto_add_key_callback add_key_cb; }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index 012501a4da91a09a9bf59bc9b0b1f9c6d526b567..15874754c0cd3e796b76e46ee8964cd810a1eb1d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -35,6 +35,7 @@ #include "wlan_crypto_def_i.h" #include "wlan_crypto_param_handling_i.h" #include "wlan_crypto_obj_mgr_i.h" +#include "wlan_crypto_main.h" #include const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; @@ -359,6 +360,14 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, if (qdf_is_macaddr_equal(&pmksa->bssid, &crypto_params->pmksa[i]->bssid)) { match_found = true; + } else if (pmksa->ssid_len && + !qdf_mem_cmp(pmksa->ssid, + crypto_params->pmksa[i]->ssid, + pmksa->ssid_len) && + !qdf_mem_cmp(pmksa->cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN)) { + match_found = true; } if (match_found) { @@ -376,8 +385,8 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, continue; if (crypto_params->pmksa[j]->pmk_len && (!qdf_mem_cmp(crypto_params->pmksa[j]->pmk, - del_pmk, - crypto_params->pmksa[j]->pmk_len))) { + del_pmk, + crypto_params->pmksa[j]->pmk_len))) { qdf_mem_zero(crypto_params->pmksa[j], sizeof(struct wlan_crypto_pmksa)); qdf_mem_free(crypto_params->pmksa[j]); @@ -394,7 +403,7 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, if (i == WLAN_CRYPTO_MAX_PMKID && !match_found) crypto_debug("No such pmksa entry exists"); - return QDF_STATUS_E_INVAL; + return QDF_STATUS_SUCCESS; } QDF_STATUS wlan_crypto_pmksa_flush(struct wlan_crypto_params *crypto_params) @@ -454,6 +463,48 @@ QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev, return status; } +struct wlan_crypto_pmksa * +wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *pmksa) +{ + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *crypto_params; + uint8_t i; + + if (!pmksa) { + crypto_err("pmksa is NULL"); + return NULL; + } + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return NULL; + } + + crypto_params = &crypto_priv->crypto_params; + + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + if (qdf_is_macaddr_equal(&pmksa->bssid, + &crypto_params->pmksa[i]->bssid)) { + return crypto_params->pmksa[i]; + } else if (pmksa->ssid_len && + !qdf_mem_cmp(pmksa->ssid, + crypto_params->pmksa[i]->ssid, + pmksa->ssid_len) && + !qdf_mem_cmp(pmksa->cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN)){ + return crypto_params->pmksa[i]; + } + } + + return NULL; +} + struct wlan_crypto_pmksa * wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid) { @@ -486,6 +537,41 @@ wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid) return NULL; } + +struct wlan_crypto_pmksa * +wlan_crypto_get_fils_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *cache_id, uint8_t *ssid, + uint8_t ssid_len) +{ + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *crypto_params; + uint8_t i; + + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return NULL; + } + + crypto_params = &crypto_priv->crypto_params; + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + + if (!qdf_mem_cmp(cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN) && + !qdf_mem_cmp(ssid, crypto_params->pmksa[i]->ssid, + ssid_len) && + ssid_len == crypto_params->pmksa[i]->ssid_len) + return crypto_params->pmksa[i]; + } + + return NULL; +} + /** * wlan_crypto_is_htallowed - called to check is HT allowed for cipher * @vdev: vdev @@ -597,7 +683,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev, | WLAN_CRYPTO_KEY_RECV); } } else { - if ((req_key->keyix >= WLAN_CRYPTO_MAXKEYIDX) + if ((req_key->keyix >= WLAN_CRYPTO_MAX_VLANKEYIX) && (!IS_MGMT_CIPHER(req_key->type))) { return QDF_STATUS_E_INVAL; } @@ -737,7 +823,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev, uint16_t kid = req_key->keyix; if (kid == WLAN_CRYPTO_KEYIX_NONE) kid = 0; - if (kid >= WLAN_CRYPTO_MAXKEYIDX) { + if (kid >= WLAN_CRYPTO_MAX_VLANKEYIX) { crypto_err("invalid keyid %d", kid); return QDF_STATUS_E_INVAL; } @@ -994,6 +1080,10 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NOENT; } key = wlan_crypto_peer_getkey(peer, req_key->keyix); + if (WLAN_CRYPTO_TX_OPS_GETPN(psoc) && + (req_key->flags & WLAN_CRYPTO_KEY_GET_PN)) + WLAN_CRYPTO_TX_OPS_GETPN(psoc)(vdev, mac_addr, + req_key->type); wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID); if (!key) return QDF_STATUS_E_INVAL; @@ -1121,11 +1211,18 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev, cipher_table = (struct wlan_crypto_cipher *)key->cipher_table; qdf_mem_zero(key->keyval, sizeof(key->keyval)); - if (WLAN_CRYPTO_TX_OPS_DELKEY(psoc)) { + if (!IS_FILS_CIPHER(cipher_table->cipher) && + WLAN_CRYPTO_TX_OPS_DELKEY(psoc)) { WLAN_CRYPTO_TX_OPS_DELKEY(psoc)(vdev, key, macaddr, cipher_table->cipher); + } else if (IS_FILS_CIPHER(cipher_table->cipher)) { + if (key->private) + qdf_mem_free(key->private); } } + + /* Zero-out local key variables */ + qdf_mem_zero(key, sizeof(struct wlan_crypto_key)); qdf_mem_free(key); return QDF_STATUS_SUCCESS; @@ -1750,6 +1847,36 @@ bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev, return false; } +/** + * wlan_crypto_is_key_valid - called by mgmt txrx to check if key is valid + * @vdev: vdev + * @peer: peer + * @keyidx : key index + * + * This function gets called by mgmt txrx to check if key is valid + * + * Return: true or false + */ +bool wlan_crypto_is_key_valid(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_peer *peer, + uint16_t keyidx) +{ + struct wlan_crypto_key *key = NULL; + + if (!vdev && !peer) + return false; + + if (peer) + key = wlan_crypto_peer_getkey(peer, keyidx); + else if (vdev) + key = wlan_crypto_vdev_getkey(vdev, keyidx); + + if ((key) && key->valid) + return true; + + return false; +} + static void wlan_crypto_gmac_pn_swap(uint8_t *a, uint8_t *b) { a[0] = b[5]; @@ -2285,6 +2412,8 @@ static int32_t wlan_crypto_rsn_suite_to_keymgmt(uint8_t *sel) return WLAN_CRYPTO_KEY_MGMT_OWE; case RSN_AUTH_KEY_MGMT_DPP: return WLAN_CRYPTO_KEY_MGMT_DPP; + case RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384: + return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384; } return status; @@ -2311,7 +2440,6 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params, * version, mcast cipher, and 2 selector counts. * Other, variable-length data, must be checked separately. */ - RESET_AUTHMODE(crypto_params); SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WPA); if (len < 14) @@ -2326,7 +2454,6 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params, frm += 2, len -= 2; /* multicast/group cipher */ - RESET_MCAST_CIPHERS(crypto_params); w = wlan_crypto_wpa_suite_to_cipher(frm); if (w < 0) return QDF_STATUS_E_INVAL; @@ -2339,7 +2466,6 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params, if (len < n*4+2) return QDF_STATUS_E_INVAL; - RESET_UCAST_CIPHERS(crypto_params); for (; n > 0; n--) { w = wlan_crypto_wpa_suite_to_cipher(frm); if (w < 0) @@ -2358,7 +2484,6 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params, return QDF_STATUS_E_INVAL; w = 0; - RESET_KEY_MGMT(crypto_params); for (; n > 0; n--) { w = wlan_crypto_wpa_suite_to_keymgmt(frm); if (w < 0) @@ -2373,7 +2498,7 @@ QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *crypto_params, frm += 2, len -= 2; } - return 0; + return QDF_STATUS_SUCCESS; } /** @@ -2615,19 +2740,9 @@ uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev, return frm; } -/** - * wlan_crypto_build_rsnie - called by mlme to build rsnie - * @vdev: vdev - * @iebuf: ie buffer - * @bssid: bssid mac address to add pmkid in rsnie - * - * This function gets called by mlme to build rsnie from given vdev - * - * Return: end of buffer - */ -uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, - uint8_t *iebuf, - struct qdf_mac_addr *bssid) +uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct wlan_crypto_pmksa *pmksa) { uint8_t *frm = iebuf; uint8_t *selcnt; @@ -2779,20 +2894,13 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, /* optional capabilities */ if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) { /* PMK list */ - if (bssid) { - struct wlan_crypto_pmksa *pmksa; - - pmksa = wlan_crypto_get_pmksa(vdev, bssid); - - if (pmksa) { - WLAN_CRYPTO_ADDSHORT(frm, 1); - qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); - frm += PMKID_LEN; - } else { - WLAN_CRYPTO_ADDSHORT(frm, 0); - } - } else + if (pmksa) { + WLAN_CRYPTO_ADDSHORT(frm, 1); + qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); + frm += PMKID_LEN; + } else { WLAN_CRYPTO_ADDSHORT(frm, 0); + } if (HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC)) { @@ -2819,17 +2927,10 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, } } else { /* PMK list */ - if (bssid) { - struct wlan_crypto_pmksa *pmksa; - - pmksa = wlan_crypto_get_pmksa(vdev, bssid); - if (pmksa) { - WLAN_CRYPTO_ADDSHORT(frm, 1); - qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); - frm += PMKID_LEN; - } else { - WLAN_CRYPTO_ADDSHORT(frm, 0); - } + if (pmksa) { + WLAN_CRYPTO_ADDSHORT(frm, 1); + qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); + frm += PMKID_LEN; } } @@ -2839,6 +2940,18 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, return frm; } +uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct qdf_mac_addr *bssid) +{ + struct wlan_crypto_pmksa *pmksa = NULL; + + if (bssid) + pmksa = wlan_crypto_get_pmksa(vdev, bssid); + + return wlan_crypto_build_rsnie_with_pmksa(vdev, iebuf, pmksa); +} + bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_params *crypto_params){ struct wlan_crypto_params *my_crypto_params; @@ -2940,7 +3053,6 @@ QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params, * version, mcast cipher, and 2 selector counts. * Other, variable-length data, must be checked separately. */ - RESET_AUTHMODE(crypto_params); SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WAPI); if (len < WLAN_CRYPTO_WAPI_IE_LEN) @@ -2959,7 +3071,6 @@ QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params, if (len < n*4+2) return QDF_STATUS_E_INVAL; - RESET_KEY_MGMT(crypto_params); for (; n > 0; n--) { w = wlan_crypto_wapi_keymgmt(frm); if (w < 0) @@ -2975,7 +3086,6 @@ QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params, if (len < n*4+2) return QDF_STATUS_E_INVAL; - RESET_UCAST_CIPHERS(crypto_params); for (; n > 0; n--) { w = wlan_crypto_wapi_suite_to_cipher(frm); if (w < 0) @@ -2988,7 +3098,6 @@ QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params, return QDF_STATUS_E_INVAL; /* multicast/group cipher */ - RESET_MCAST_CIPHERS(crypto_params); w = wlan_crypto_wapi_suite_to_cipher(frm); if (w < 0) @@ -3799,7 +3908,7 @@ wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params, qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params)); rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSN, ie_ptr, ie_len); if (!rsn_ie) { - crypto_err("RSN IE NULL"); + crypto_debug("RSN IE not present"); return QDF_STATUS_E_INVAL; } @@ -3826,7 +3935,7 @@ wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params, wpa_ie = wlan_get_vendor_ie_ptr_from_oui((uint8_t *)&wpa_oui, WLAN_OUI_SIZE, ie_ptr, ie_len); if (!wpa_ie) { - crypto_err("WPA IE NULL"); + crypto_debug("WPA IE not present"); return QDF_STATUS_E_INVAL; } @@ -3951,11 +4060,31 @@ wlan_crypto_reset_prarams(struct wlan_crypto_params *params) params->ucastcipherset = 0; params->mcastcipherset = 0; params->mgmtcipherset = 0; - params->cipher_caps = 0; params->key_mgmt = 0; params->rsn_caps = 0; } +uint8_t * +wlan_crypto_parse_rsnxe_ie(uint8_t *rsnxe_ie, uint8_t *cap_len) +{ + uint8_t len; + uint8_t *ie; + + if (!rsnxe_ie) + return NULL; + + ie = rsnxe_ie; + len = ie[1]; + ie += 2; + + if (!len) + return NULL; + + *cap_len = ie[0] & 0xf; + + return ie; +} + QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, uint8_t *ie_ptr, uint16_t ie_len) @@ -3989,20 +4118,16 @@ QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, wlan_crypto_reset_prarams(vdev_crypto_params); status = wlan_get_crypto_params_from_rsn_ie(&crypto_params, ie_ptr, ie_len); - if (QDF_STATUS_SUCCESS == status) { + if (QDF_IS_STATUS_SUCCESS(status)) wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params); - } else { - crypto_err("get crypto prarams from RSN IE failed"); + else send_fail = true; - } status = wlan_get_crypto_params_from_wpa_ie(&crypto_params, ie_ptr, ie_len); - if (QDF_STATUS_SUCCESS == status) { + if (QDF_IS_STATUS_SUCCESS(status)) { wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params); send_fail = false; - } else { - crypto_debug("get crypto prarams from WPA IE failed"); } return send_fail ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS; @@ -4091,11 +4216,15 @@ QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev, crypto_err("Invalid Key index %d", key_index); return QDF_STATUS_E_FAILURE; } - if (key_index < WLAN_CRYPTO_MAXKEYIDX) + if (key_index < WLAN_CRYPTO_MAXKEYIDX) { crypto_priv->key[key_index] = crypto_key; - else + } else { crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX] = crypto_key; + crypto_priv->def_igtk_tx_keyid = + key_index - WLAN_CRYPTO_MAXKEYIDX; + crypto_priv->igtk_key_type = crypto_key->cipher_type; + } return QDF_STATUS_SUCCESS; } @@ -4149,4 +4278,100 @@ void wlan_crypto_update_set_key_peer(struct wlan_objmgr_vdev *vdev, qdf_mem_copy(crypto_key->macaddr, peer_mac, QDF_MAC_ADDR_SIZE); } + +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +void wlan_crypto_selective_clear_sae_single_pmk_entries( + struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *conn_bssid) +{ + struct wlan_crypto_params *crypto_params; + struct wlan_crypto_comp_priv *crypto_priv; + int i; + + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return; + } + + crypto_params = &crypto_priv->crypto_params; + + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + + if (crypto_params->pmksa[i]->single_pmk_supported && + !qdf_is_macaddr_equal(conn_bssid, + &crypto_params->pmksa[i]->bssid)) { + qdf_mem_zero(crypto_params->pmksa[i], + sizeof(struct wlan_crypto_pmksa)); + qdf_mem_free(crypto_params->pmksa[i]); + crypto_params->pmksa[i] = NULL; + } + } +} + +void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *bssid, + bool single_pmk_capable_bss) +{ + struct wlan_crypto_params *crypto_params; + struct wlan_crypto_comp_priv *crypto_priv; + int i; + + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return; + } + + crypto_params = &crypto_priv->crypto_params; + + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + + if (qdf_is_macaddr_equal(bssid, + &crypto_params->pmksa[i]->bssid)) + crypto_params->pmksa[i]->single_pmk_supported = + single_pmk_capable_bss; + } +} +#endif + +void wlan_crypto_reset_vdev_params(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_crypto_comp_priv *crypto_priv; + + crypto_debug("reset params for vdev %d", wlan_vdev_get_id(vdev)); + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return; + } + + wlan_crypto_reset_prarams(&crypto_priv->crypto_params); +} + +QDF_STATUS wlan_crypto_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + if (psoc && WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(psoc)) + return WLAN_CRYPTO_TX_OPS_REGISTER_EVENTS(psoc)(psoc); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS wlan_crypto_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + if (psoc && WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(psoc)) + return WLAN_CRYPTO_TX_OPS_DEREGISTER_EVENTS(psoc)(psoc); + + return QDF_STATUS_E_FAILURE; +} #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c index 401ca5c7d09b8d0bca559a9415b88be9446a9115..91d163b7ff44c5ffd0e0531d2674fbfddaddf281 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c @@ -197,6 +197,22 @@ static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv) } +#ifdef CRYPTO_SET_KEY_CONVERGED +void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_crypto_comp_priv *crypto_priv; + + crypto_debug("free key for vdev %d", wlan_vdev_get_id(vdev)); + crypto_priv = wlan_get_vdev_crypto_obj(vdev); + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return; + } + + wlan_crypto_free_key(crypto_priv); +} +#endif + static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler( struct wlan_objmgr_vdev *vdev, void *arg){ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/inc/wlan_cmn.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/inc/wlan_cmn.h index 99bf306da96182dfd623580c29ea036203466860..1a346c79c10a9fc19fe414ff00386a6d65cc6122 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/inc/wlan_cmn.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/inc/wlan_cmn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,6 +61,8 @@ /* Max length of a SSID */ #define WLAN_SSID_MAX_LEN 32 +#define WLAN_CACHE_ID_LEN 2 + /* Max sequence number */ #define WLAN_MAX_SEQ_NUM 4096 @@ -272,7 +274,10 @@ * @WLAN_UMAC_COMP_FWOL FW Offload * @WLAN_UMAC_COMP_INTEROP_ISSUES_AP interop issues ap component * @WLAN_UMAC_COMP_BLACKLIST_MGR: Blacklist mgr component + * @WLAN_UMAC_COMP_COEX: Coex config component + * @WLAN_UMAC_COMP_FTM_TIME_SYNC: WLAN FTM TIMESYNC * @WLAN_UMAC_COMP_PKT_CAPTURE: Packet capture component + * @WLAN_UMAC_COMP_GPIO: GPIO Configuration * @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC * * This id is static. @@ -312,7 +317,10 @@ enum wlan_umac_comp_id { WLAN_UMAC_COMP_CFR = 30, WLAN_UMAC_COMP_INTEROP_ISSUES_AP = 31, WLAN_UMAC_COMP_BLACKLIST_MGR = 32, - WLAN_UMAC_COMP_PKT_CAPTURE = 33, + WLAN_UMAC_COMP_COEX = 33, + WLAN_UMAC_COMP_FTM_TIME_SYNC = 34, + WLAN_UMAC_COMP_PKT_CAPTURE = 35, + WLAN_UMAC_COMP_GPIO = 39, WLAN_UMAC_COMP_ID_MAX, }; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index 5aeab067fdec74a5129b922752917ccd943bce66..1044b04a7233f769e2f5e5a4559ee9ebdf94dfc2 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -30,12 +30,6 @@ #include "wlan_objmgr_cmn.h" #include "qdf_nbuf.h" -#ifdef CONFIG_MCL -#define MGMT_DESC_POOL_MAX 64 -#else -#define MGMT_DESC_POOL_MAX 512 -#endif - #define mgmt_txrx_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_MGMT_TXRX, params) #define mgmt_txrx_err(params...) \ @@ -246,6 +240,20 @@ enum rrm_actioncode { RRM_NEIGHBOR_RPT, }; +/** + * enum ft_actioncode - ft action frames + * @FT_FAST_BSS_TRNST_REQ: ft request frame + * @FT_FAST_BSS_TRNST_RES: ft response frame + * @FT_FAST_BSS_TRNST_CONFIRM: ft confirm frame + * @FT_FAST_BSS_TRNST_ACK: ft ACK frame + */ +enum ft_actioncode { + FT_FAST_BSS_TRNST_REQ = 1, + FT_FAST_BSS_TRNST_RES, + FT_FAST_BSS_TRNST_CONFIRM, + FT_FAST_BSS_TRNST_ACK, +}; + /** * enum ht_actioncode - ht action frames * @HT_ACTION_NOTIFY_CHANWIDTH: ht notify bw action frame @@ -608,6 +616,10 @@ enum mgmt_frame_type { MGMT_ACTION_RRM_LINK_MEASUREMENT_RPT, MGMT_ACTION_RRM_NEIGHBOR_REQ, MGMT_ACTION_RRM_NEIGHBOR_RPT, + MGMT_ACTION_FT_REQUEST, + MGMT_ACTION_FT_RESPONSE, + MGMT_ACTION_FT_CONFIRM, + MGMT_ACTION_FT_ACK, MGMT_ACTION_HT_NOTIFY_CHANWIDTH, MGMT_ACTION_HT_SMPS, MGMT_ACTION_HT_PSMP, @@ -689,6 +701,7 @@ enum mgmt_frame_type { #define WLAN_NOISE_FLOOR_DBM_DEFAULT -96 /** * struct mgmt_rx_event_params - host mgmt header params + * @chan_freq: channel frequency on which this frame is received * @channel: channel on which this frame is received * @snr: snr information used to call rssi * @rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]: RSSI of PRI 20MHz for each chain @@ -705,6 +718,7 @@ enum mgmt_frame_type { * (win specific, will be removed in phase 4) */ struct mgmt_rx_event_params { + uint32_t chan_freq; uint32_t channel; uint32_t snr; uint8_t rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c index 93c5aee68a55b3f7bd706750808e887fd59b82d9..3aadfd8cc5097270e569ff3858716a9c3c724e19 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c @@ -258,6 +258,32 @@ mgmt_get_rrm_action_subtype(uint8_t action_code) return frm_type; } +static enum mgmt_frame_type +mgmt_get_ft_action_subtype(uint8_t action_code) +{ + enum mgmt_frame_type frm_type; + + switch (action_code) { + case FT_FAST_BSS_TRNST_REQ: + frm_type = MGMT_ACTION_FT_REQUEST; + break; + case FT_FAST_BSS_TRNST_RES: + frm_type = MGMT_ACTION_FT_RESPONSE; + break; + case FT_FAST_BSS_TRNST_CONFIRM: + frm_type = MGMT_ACTION_FT_CONFIRM; + break; + case FT_FAST_BSS_TRNST_ACK: + frm_type = MGMT_ACTION_FT_ACK; + break; + default: + frm_type = MGMT_FRM_UNSPECIFIED; + break; + } + + return frm_type; +} + /** * mgmt_get_ht_action_subtype() - gets ht action subtype * @action_code: action code @@ -710,6 +736,9 @@ mgmt_txrx_get_action_frm_subtype(uint8_t *mpdu_data_ptr) frm_type = mgmt_get_spec_mgmt_action_subtype( action_hdr->action_code); break; + case ACTION_FAST_BSS_TRNST: + frm_type = mgmt_get_ft_action_subtype(action_hdr->action_code); + break; case ACTION_CATEGORY_QOS: frm_type = mgmt_get_qos_action_subtype(action_hdr->action_code); break; @@ -942,8 +971,9 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler( wh->i_addr3); if (!is_from_addr_valid && !is_bssid_valid) { - mgmt_txrx_debug_rl("from addr %pM bssid addr %pM both not valid, dropping them", - wh->i_addr2, wh->i_addr3); + mgmt_txrx_debug_rl("from addr "QDF_MAC_ADDR_FMT" bssid addr "QDF_MAC_ADDR_FMT" both not valid, dropping them", + QDF_MAC_ADDR_REF(wh->i_addr2), + QDF_MAC_ADDR_REF(wh->i_addr3)); qdf_nbuf_free(buf); return QDF_STATUS_E_FAILURE; } @@ -951,8 +981,9 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler( if ((mgmt_subtype == MGMT_SUBTYPE_BEACON || mgmt_subtype == MGMT_SUBTYPE_PROBE_RESP) && !(is_from_addr_valid && is_bssid_valid)) { - mgmt_txrx_debug_rl("from addr %pM bssid addr %pM not valid, modifying them", - wh->i_addr2, wh->i_addr3); + mgmt_txrx_debug_rl("from addr "QDF_MAC_ADDR_FMT" bssid addr "QDF_MAC_ADDR_FMT" not valid, modifying them", + QDF_MAC_ADDR_REF(wh->i_addr2), + QDF_MAC_ADDR_REF(wh->i_addr3)); if (!is_from_addr_valid) qdf_mem_copy(wh->i_addr2, wh->i_addr3, QDF_MAC_ADDR_SIZE); @@ -1004,8 +1035,9 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler( if (!(mgmt_subtype == MGMT_SUBTYPE_BEACON || mgmt_subtype == MGMT_SUBTYPE_PROBE_RESP || mgmt_subtype == MGMT_SUBTYPE_PROBE_REQ)) - mgmt_txrx_debug("Rcvd mgmt frame subtype %x (frame type %u) from %pM, seq_num = %d, rssi = %d tsf_delta: %u", - mgmt_subtype, frm_type, wh->i_addr2, + mgmt_txrx_debug("Rcvd mgmt frame subtype %x (frame type %u) from "QDF_MAC_ADDR_FMT", seq_num = %d, rssi = %d tsf_delta: %u", + mgmt_subtype, frm_type, + QDF_MAC_ADDR_REF(wh->i_addr2), (le16toh(*(uint16_t *)wh->i_seq) >> WLAN_SEQ_SEQ_SHIFT), mgmt_rx_params->rssi, mgmt_rx_params->tsf_delta); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c index 587a058c086228294655b17db196adad422273ac..5889f146fa7d655995aa3b067ef63a80d37505bd 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c @@ -128,7 +128,7 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_destroy_notification( qdf_spinlock_destroy(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock); qdf_mem_free(mgmt_txrx_psoc_ctx); - mgmt_txrx_debug("mgmt txrx deletion successful, psoc: %pK", psoc); + mgmt_txrx_debug("mgmt txrx deletion successful"); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index e1a23a0e94187ea817d3ee08d3daba160fb3705a..fd758ccd079795d1f8da565ccdc9d59f6da29ce4 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -174,6 +174,9 @@ typedef QDF_STATUS (*wlan_objmgr_vdev_destroy_handler)( typedef void (*wlan_objmgr_vdev_status_handler)( struct wlan_objmgr_vdev *vdev, void *arg, QDF_STATUS status); +typedef void (*wlan_objmgr_vdev_peer_free_notify_handler)( + struct wlan_objmgr_vdev *vdev); + typedef QDF_STATUS (*wlan_objmgr_peer_create_handler)( struct wlan_objmgr_peer *peer, void *arg); @@ -229,7 +232,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_MLME_OBJ_DEL_ID: Object delete req/resp tracking with FW * @WLAN_ACTION_OUI_ID: action oui operations * @WLAN_LEGACY_SAP_ID: legacy sap fsm - * @WLAN_TGT_IF_DP_PEER_REF_ID: cp peer reference in dp (Target IF) + * @WLAN_PDEV_TARGET_IF_ID: Target interface layer for pdev APIs * @WLAN_MLME_SER_IF_ID: mlme serialization interface layer * @WLAN_SCHEDULER_ID: mlme scheduler * @WLAN_CFR_ID: CFG Capture method @@ -256,6 +259,8 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_MISC_ID: power manager, PAPI, rate set, etc. * @WLAN_FWOL_NB_ID: fw offload northbound operations * @WLAN_FWOL_SB_ID: fw offload southbound operations + * @WLAN_PSOC_TARGET_IF_ID PSOC related target_if operations + * @FTM_TIME_SYNC_ID: ftm time sync operations * @WLAN_PKT_CAPTURE_ID Packet capture operations * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ @@ -308,13 +313,13 @@ typedef enum { WLAN_MLME_OBJ_DEL_ID = 42, WLAN_ACTION_OUI_ID = 43, WLAN_LEGACY_SAP_ID = 44, - WLAN_TGT_IF_DP_PEER_REF_ID = 45, + WLAN_PDEV_TARGET_IF_ID = 45, WLAN_MLME_SER_IF_ID = 46, WLAN_SCHEDULER_ID = 47, WLAN_CFR_ID = 48, WLAN_VDEV_TARGET_IF_ID = 49, WLAN_RX_PKT_TAG_ID = 50, - WLAN_INTEROP_ISSUES_AP_ID = 51, + WLAN_INTEROP_ISSUES_AP_ID = 51, WLAN_WDS_ID = 52, WLAN_PROXY_ARP_ID = 53, WLAN_WNM_ID = 54, @@ -335,7 +340,9 @@ typedef enum { WLAN_MISC_ID = 69, WLAN_FWOL_NB_ID = 70, WLAN_FWOL_SB_ID = 71, - WLAN_PKT_CAPTURE_ID = 72, + WLAN_PSOC_TARGET_IF_ID = 72, + FTM_TIME_SYNC_ID = 73, + WLAN_PKT_CAPTURE_ID = 74, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; @@ -394,7 +401,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_MLME_OBJ_DEL_ID", "WLAN_ACTION_OUI_ID", "WLAN_LEGACY_SAP_ID", - "WLAN_TGT_IF_DP_PEER_REF_ID", + "WLAN_PDEV_TARGET_IF_ID", "WLAN_MLME_SER_IF_ID", "WLAN_SCHEDULER_ID", "WLAN_CFR_ID", @@ -421,6 +428,9 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_MISC_ID", "WLAN_FWOL_NB_ID", "WLAN_FWOL_SB_ID", + "WLAN_PSOC_TARGET_IF_ID", + "FTM_TIME_SYNC_ID", + "WLAN_PKT_CAPTURE_ID", "WLAN_REF_ID_MAX"}; return (char *)strings[id]; @@ -432,4 +442,62 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) #define WLAN_OBJMGR_BUG(val) #endif #define WLAN_OBJMGR_RATELIMIT_THRESH 2 + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +#define WLAN_OBJMGR_TRACE_FUNC_SIZE 30 +/** + * struct wlan_objmgr_line_ref - line reference data + * @line: line number + * @cnt: line reference count + */ +struct wlan_objmgr_line_ref { + uint32_t line; + qdf_atomic_t cnt; +}; + +/** + * struct wlan_objmgr_line_ref_node - line reference node + * @line_ref: line reference data + * @next: pointer to next line reference + */ +struct wlan_objmgr_line_ref_node { + struct wlan_objmgr_line_ref line_ref; + struct wlan_objmgr_line_ref_node *next; +}; + +/** + * struct wlan_objmgr_trace_func - trace function data + * @func: function pointer + * @line_head: pointer to head line trace reference + * @next: pointer to next function reference + */ +struct wlan_objmgr_trace_func { + char func[WLAN_OBJMGR_TRACE_FUNC_SIZE]; + struct wlan_objmgr_line_ref_node *line_head; + struct wlan_objmgr_trace_func *next; +}; + +/** + * struct wlan_objmgr_trace_id - trace reference data + * @num_func: num of functions + * @head: head pointer to function reference + */ +struct wlan_objmgr_trace_id { + uint32_t num_func; + struct wlan_objmgr_trace_func *head; +}; + +/** + * struct wlan_objmgr_trace - trace reference data + * @references: reference data + * @dereferences: dereference data + * @trace_lock: lock + */ +struct wlan_objmgr_trace { + struct wlan_objmgr_trace_id references[WLAN_REF_ID_MAX]; + struct wlan_objmgr_trace_id dereferences[WLAN_REF_ID_MAX]; + qdf_spinlock_t trace_lock; +}; +#endif /*WLAN_OBJMGR_REF_ID_TRACE*/ + #endif /* _WLAN_OBJMGR_CMN_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_debug.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_debug.h index 2df21f0d6d2b3f546a5af044c462c39a91f8fd76..ee5c5430a6472a532a45e3732271061d1ff77e53 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_debug.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -93,4 +93,53 @@ wlan_objmgr_debug_info_deinit(void) #endif /*WLAN_OBJMGR_DEBUG*/ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +/** + * wlan_objmgr_trace_ref() - Save trace info to list + * @func_head: head object of function list + * @trace: trace object + * @func: function name + * @line: line number + * + * API to trace func and line information for reference + * and dereference + * + * Return: void + */ +void +wlan_objmgr_trace_ref(struct wlan_objmgr_trace_func **func_head, + struct wlan_objmgr_trace *trace, + const char *func, int line); + +/** + * wlan_objmgr_trace_init_lock() - Initialize trace spinlock + * @trace: trace object + * + * API to initialize trace spin lock + * + * Return: void + */ +void wlan_objmgr_trace_init_lock(struct wlan_objmgr_trace *trace); + +/** + * wlan_objmgr_trace_deinit_lock() - Deinitialize trace spinlock + * @trace: trace object + * + * API to deinitialize trace spin lock + * + * Return: void + */ +void wlan_objmgr_trace_deinit_lock(struct wlan_objmgr_trace *trace); + +/** + * wlan_objmgr_trace_del_ref_list() - Delete reference trace list + * @trace: trace object + * + * API to delete trace list + * + * Return: void + */ +void wlan_objmgr_trace_del_ref_list(struct wlan_objmgr_trace *trace); +#endif /*WLAN_OBJMGR_REF_ID_TRACE*/ + #endif /*_WLAN_OBJMGR_DEBUG_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h index 6899ea9c453144d0273b079a6ab0a14f781d82cc..64b1daead5a80a145f6c0460fe88fb0a122f53ab 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h @@ -374,6 +374,39 @@ QDF_STATUS wlan_objmgr_unregister_vdev_status_handler( wlan_objmgr_vdev_status_handler handler, void *args); +/** + * wlan_objmgr_register_vdev_peer_free_notify_handler() - register vdev peer + * free handler + * @id: component id + * @handler: function pointer of the component + * + * API, allows other UMAC components to register handler + * The registered handler would be invoked on VDEV Peer gets freed + * + * Return: SUCCESS, + * Failure (if registration fails, each failure has different error + * code) + */ +QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler( + enum wlan_umac_comp_id id, + wlan_objmgr_vdev_peer_free_notify_handler handler); + +/** + * wlan_objmgr_unregister_vdev_peer_free_notify_handler() - unregister vdev + * peer free handler + * @id: component id + * @handler: function pointer of the component + * + * API, allows other UMAC components to unregister handler + * + * Return: SUCCESS, + * Failure (if handler is not present, each failure has different error + * code) + */ +QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler( + enum wlan_umac_comp_id id, + wlan_objmgr_vdev_peer_free_notify_handler handler); + /** * wlan_objmgr_register_peer_create_handler() - register peer create handler * @id: component id diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h index 82bc47d0647b2463c2b752195e2cff099be52712..a8c532a963f7fe754ce4e2a0d4897832239fb043 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,6 +24,7 @@ #include #include "wlan_objmgr_psoc_obj.h" +#include /* STATUS: scanning */ #define WLAN_PDEV_F_SCAN 0x00000001 @@ -86,6 +87,8 @@ #define WLAN_PDEV_F_MULTIVDEV_RESTART 0x10000000 /* MBSS IE enable */ #define WLAN_PDEV_F_MBSS_IE_ENABLE 0x20000000 +/* VDEV Peer delete all */ +#define WLAN_PDEV_F_DELETE_ALL_PEER 0x40000000 /* PDEV op flags */ /* Enable htrate for wep and tkip */ @@ -162,6 +165,7 @@ struct wlan_objmgr_pdev_mlme { * @wlan_peer_count: Peer count * @max_peer_count: Max Peer count * @temp_peer_count: Temporary peer count + * @max_monitor_vdev_count: Max monitor vdev count * @wlan_psoc: back pointer to PSOC, its attached to * @ref_cnt: Ref count * @ref_id_dbg: Array to track Ref count @@ -175,6 +179,7 @@ struct wlan_objmgr_pdev_objmgr { uint16_t wlan_peer_count; uint16_t max_peer_count; uint16_t temp_peer_count; + uint8_t max_monitor_vdev_count; struct wlan_objmgr_psoc *wlan_psoc; qdf_atomic_t ref_cnt; qdf_atomic_t ref_id_dbg[WLAN_REF_ID_MAX]; @@ -190,7 +195,6 @@ struct wlan_objmgr_pdev_objmgr { * @obj_status[]: object status of each component object * @obj_state: object state * @tgt_if_handle: Target interface handle - * @dp_handle: DP module handle * @pdev_lock: lock to protect object */ struct wlan_objmgr_pdev { @@ -201,8 +205,7 @@ struct wlan_objmgr_pdev { void *pdev_comp_priv_obj[WLAN_UMAC_MAX_COMPONENTS]; QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS]; WLAN_OBJ_STATE obj_state; - void *tgt_if_handle; - void *dp_handle; + target_pdev_info_t *tgt_if_handle; qdf_spinlock_t pdev_lock; }; @@ -351,13 +354,24 @@ QDF_STATUS wlan_objmgr_trigger_pdev_comp_priv_object_deletion( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_debug( + struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, dbgid) \ + wlan_objmgr_get_vdev_by_id_from_pdev_debug(pdev, \ + vdev_id, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id); +#endif /** - * wlan_objmgr_get_vdev_by_id_from_pdev_no_state() - find vdev using id from - * pdev + * wlan_objmgr_get_vdev_by_id_from_pdev_no_state() - find vdev using id + * from pdev * @pdev: PDEV object * @vdev_id: vdev id * @dbg_id: id of the caller @@ -371,9 +385,21 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug( + struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_id_from_pdev_no_state(pdev, \ + vdev_id, dbgid) \ + wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug(pdev, \ + vdev_id, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_macaddr_from_pdev() - find vdev using macaddr @@ -390,9 +416,20 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *fnc, int ln); + +#define wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, macaddr, dbgid) \ + wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(pdev, macaddr, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state() - find vdev using @@ -410,9 +447,46 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev + *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(pdev, macaddr, \ + dbgid) \ + wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(pdev, \ + macaddr, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state( struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_objmgr_pdev_get_first_vdev() - Get first vdev of pdev + * @pdev: PDEV object + * @dbg_id: Object Manager ref debug id + * + * API to get reference to first vdev of pdev. + * + * Return: reference to first vdev + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev_debug( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_pdev_get_first_vdev(pdev, dbgid) \ + wlan_objmgr_pdev_get_first_vdev_debug(pdev, dbgid, \ + __func__, __LINE__) +#else +struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_pdev_get_comp_private_obj() - get pdev component private object @@ -792,19 +866,6 @@ QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev, void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev, wlan_objmgr_ref_dbgid id); -/** - * wlan_objmgr_pdev_get_first_vdev() - Get first vdev of pdev - * @pdev: PDEV object - * @dbg_id: Object Manager ref debug id - * - * API to get reference to first vdev of pdev. - * - * Return: reference to first vdev - */ -struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev( - struct wlan_objmgr_pdev *pdev, - wlan_objmgr_ref_dbgid dbg_id); - /** * wlan_objmgr_pdev_get_pdev_id() - get pdev id * @pdev: PDEV object @@ -830,8 +891,9 @@ uint8_t wlan_objmgr_pdev_get_pdev_id(struct wlan_objmgr_pdev *pdev) * * Return: None */ -static inline void wlan_pdev_set_tgt_if_handle(struct wlan_objmgr_pdev *pdev, - void *tgt_if_handle) +static inline +void wlan_pdev_set_tgt_if_handle(struct wlan_objmgr_pdev *pdev, + target_pdev_info_t *tgt_if_handle) { /* This API is invoked with lock acquired, do not add log prints */ if (!pdev) @@ -848,7 +910,8 @@ static inline void wlan_pdev_set_tgt_if_handle(struct wlan_objmgr_pdev *pdev, * * Return: target interface handle */ -static inline void *wlan_pdev_get_tgt_if_handle(struct wlan_objmgr_pdev *pdev) +static inline +target_pdev_info_t *wlan_pdev_get_tgt_if_handle(struct wlan_objmgr_pdev *pdev) { if (!pdev) return NULL; @@ -885,6 +948,36 @@ static inline uint16_t wlan_pdev_get_max_peer_count( return pdev->pdev_objmgr.max_peer_count; } +/** + * wlan_pdev_set_max_monitor_vdev_count() - set max monitor vdev count + * @pdev: PDEV object + * @count: Max monitor vdev count + * + * API to set max monitor vdev count of PDEV + * + * Return: void + */ +static inline void wlan_pdev_set_max_monitor_vdev_count( + struct wlan_objmgr_pdev *pdev, + uint16_t count) +{ + pdev->pdev_objmgr.max_monitor_vdev_count = count; +} + +/** + * wlan_pdev_get_max_monitor_vdev_count() - get max monitor vdev count + * @pdev: PDEV object + * + * API to get max monitor vdev count of PDEV + * + * Return: max monitor vdev count + */ +static inline uint16_t wlan_pdev_get_max_monitor_vdev_count( + struct wlan_objmgr_pdev *pdev) +{ + return pdev->pdev_objmgr.max_monitor_vdev_count; +} + /** * wlan_pdev_get_peer_count() - get pdev peer count * @pdev: PDEV object @@ -978,37 +1071,15 @@ static inline uint8_t wlan_pdev_get_vdev_count(struct wlan_objmgr_pdev *pdev) } /** - * wlan_pdev_set_dp_handle() - set dp handle + * wlan_print_pdev_info() - print pdev members * @pdev: pdev object pointer - * @dp_handle: Data path module handle * * Return: void */ -static inline void wlan_pdev_set_dp_handle(struct wlan_objmgr_pdev *pdev, - void *dp_handle) -{ - if (qdf_unlikely(!pdev)) { - QDF_BUG(0); - return; - } - - pdev->dp_handle = dp_handle; -} - -/** - * wlan_pdev_get_dp_handle() - get dp handle - * @pdev: pdev object pointer - * - * Return: dp handle - */ -static inline void *wlan_pdev_get_dp_handle(struct wlan_objmgr_pdev *pdev) -{ - if (qdf_unlikely(!pdev)) { - QDF_BUG(0); - return NULL; - } - - return pdev->dp_handle; -} +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_pdev_info(struct wlan_objmgr_pdev *pdev); +#else +static inline void wlan_print_pdev_info(struct wlan_objmgr_pdev *pdev) {} +#endif #endif /* _WLAN_OBJMGR_PDEV_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h index 4e86aa34dfb4cec762a39875d5343a2624cf0c33..2324b37667faff0914995efbe240f3f7c9cdddfc 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -143,6 +143,7 @@ struct wlan_objmgr_peer_mlme { * @ref_cnt: Ref count * @ref_id_dbg: Array to track Ref count * @print_cnt: Count to throttle Logical delete prints + * @wlan_objmgr_trace: Trace ref and deref */ struct wlan_objmgr_peer_objmgr { struct wlan_objmgr_vdev *vdev; @@ -151,14 +152,9 @@ struct wlan_objmgr_peer_objmgr { qdf_atomic_t ref_id_dbg[WLAN_REF_ID_MAX]; #endif uint8_t print_cnt; -}; - -/** - * struct wlan_peer_activity -- peer inactivity info - * - */ -struct wlan_peer_activity { /*TODO */ - +#ifdef WLAN_OBJMGR_REF_ID_TRACE + struct wlan_objmgr_trace trace; +#endif }; /** @@ -167,12 +163,10 @@ struct wlan_peer_activity { /*TODO */ * @vdev_peer: peer list node for vdev's qdf list * @macaddr[]: Peer MAC address * @peer_mlme: Peer MLME common structure - * @peer_activity: peer activity * @peer_objmgr: Peer Object manager common structure * @peer_comp_priv_obj[]: Component's private object pointers * @obj_status[]: status of each component object * @obj_state: Status of Peer object - * @dp_handle: DP module handle * @pdev_id: Pdev ID * @peer_lock: Lock for access/update peer contents */ @@ -182,12 +176,10 @@ struct wlan_objmgr_peer { uint8_t macaddr[QDF_MAC_ADDR_SIZE]; uint8_t pdev_id; struct wlan_objmgr_peer_mlme peer_mlme; - struct wlan_peer_activity peer_activity; struct wlan_objmgr_peer_objmgr peer_objmgr; void *peer_comp_priv_obj[WLAN_UMAC_MAX_COMPONENTS]; QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS]; WLAN_OBJ_STATE obj_state; - void *dp_handle; qdf_spinlock_t peer_lock; }; @@ -381,8 +373,17 @@ static inline void wlan_peer_obj_unlock(struct wlan_objmgr_peer *peer) * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_peer_get_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_peer_get_ref(peer, dbgid) \ + wlan_objmgr_peer_get_ref_debug(peer, dbgid, __func__, __LINE__) +#else void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, wlan_objmgr_ref_dbgid id); +#endif /** * wlan_objmgr_peer_try_get_ref() - increment ref count, if allowed @@ -393,8 +394,18 @@ void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +QDF_STATUS wlan_objmgr_peer_try_get_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_peer_try_get_ref(peer, dbgid) \ + wlan_objmgr_peer_try_get_ref_debug(peer, dbgid, \ + __func__, __LINE__) +#else QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, wlan_objmgr_ref_dbgid id); +#endif /** * wlan_objmgr_peer_release_ref() - decrement ref count @@ -406,36 +417,147 @@ QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_peer_release_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_peer_release_ref(peer, dbgid) \ + wlan_objmgr_peer_release_ref_debug(peer, dbgid, \ + __func__, __LINE__) +#else void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, wlan_objmgr_ref_dbgid id); +#endif /** - * wlan_psoc_peer_list_peek_head() - get head of psoc peer list - * @peer_list: qdf_list_t + * wlan_peer_get_next_peer_of_psoc_ref() - get next peer to psoc peer list + * with lock and ref taken + * @peer_list: Peer list + * @hash_index: peer list hash index + * @peer: PEER object + * @dbg_id: Ref count debug module id * - * API to get the head peer of given peer (of psoc's peer list) + * API to get the next peer of given peer (of psoc's peer list) * - * Caller need to acquire lock with wlan_peer_obj_lock() + * Return: + * @next_peer: PEER object + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_peer_get_next_peer_of_psoc_ref(peer_list, hash_index, peer, \ + dbgid) \ + wlan_peer_get_next_peer_of_psoc_ref_debug(peer_list, \ + hash_index, peer, dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_peer_get_next_active_peer_of_psoc() - get next active peer to psoc peer + * list + * @peer_list: Peer list + * @hash_index: peer list hash index + * @peer: PEER object + * @dbg_id: Ref count debug module id + * + * API to get the next peer of given peer (of psoc's peer list) * * Return: - * @peer: head peer + * @next_peer: PEER object */ -static inline struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head( - qdf_list_t *peer_list) -{ - struct wlan_objmgr_peer *peer; - qdf_list_node_t *psoc_node = NULL; +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_peer_get_next_active_peer_of_psoc(peer_list, hash_index, \ + peer, dbgid) \ + wlan_peer_get_next_active_peer_of_psoc_debug(peer_list, \ + hash_index, peer, dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); +#endif - /* This API is invoked with lock acquired, do not add log prints */ - if (qdf_list_peek_front(peer_list, &psoc_node) != QDF_STATUS_SUCCESS) - return NULL; +/** + * wlan_peer_get_next_active_peer_of_vdev() - get next active_peer of vdev list + * @vdev: VDEV object + * @peer_list: Peer object list + * @peer: PEER object + * @dbg_id: Ref count debug module id + * + * API to get the next active peer of given peer (of vdev's peer list) + * + * Return: + * @next_peer: PEER object + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev_debug( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); - peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, psoc_peer); - return peer; -} +#define wlan_peer_get_next_active_peer_of_vdev(vdev, peer_list, peer, dbgid) \ + wlan_peer_get_next_active_peer_of_vdev_debug(vdev, peer_list, \ + peer, dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id); +#endif /** - * wlan_psoc_peer_list_peek_active_head() - get active head of psoc peer list + * wlan_vdev_peer_list_peek_active_head() - get active head of vdev peer list + * @vdev: VDEV object + * @peer_list: qdf_list_t + * @dbg_id: Ref count debug module id + * + * API to get the active head peer of given peer (of vdev's peer list) + * + * Return: + * @peer: active head peer + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head_debug( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_vdev_peer_list_peek_active_head(vdev, peer_list, dbgid) \ + wlan_vdev_peer_list_peek_active_head_debug(vdev, peer_list, \ + dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_psoc_peer_list_peek_head_ref() - get head of psoc peer list + * with ref and lock protected * @peer_list: wlan_peer_list * @hash_index: peer list hash index * @dbg_id: Ref count debug module id @@ -445,14 +567,25 @@ static inline struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head( * Return: * @peer: head peer */ -struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_psoc_peer_list_peek_head_ref(peer_list, hash_index, dbgid) \ + wlan_psoc_peer_list_peek_head_ref_debug(peer_list, hash_index, \ + dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( struct wlan_peer_list *peer_list, uint8_t hash_index, wlan_objmgr_ref_dbgid dbg_id); +#endif /** - * wlan_psoc_peer_list_peek_head_lock_ref() - get head of psoc peer list - * with ref and lock protected + * wlan_psoc_peer_list_peek_active_head() - get active head of psoc peer list * @peer_list: wlan_peer_list * @hash_index: peer list hash index * @dbg_id: Ref count debug module id @@ -462,51 +595,72 @@ struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( * Return: * @peer: head peer */ -struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_psoc_peer_list_peek_active_head(peer_list, hash_index, dbgid) \ + wlan_psoc_peer_list_peek_active_head_debug(peer_list, \ + hash_index, dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( struct wlan_peer_list *peer_list, uint8_t hash_index, wlan_objmgr_ref_dbgid dbg_id); +#endif /** - * wlan_vdev_peer_list_peek_head() - get head of vdev peer list + * wlan_psoc_peer_list_peek_head() - get head of psoc peer list * @peer_list: qdf_list_t * - * API to get the head peer of given peer (of vdev's peer list) + * API to get the head peer of given peer (of psoc's peer list) * * Caller need to acquire lock with wlan_peer_obj_lock() * * Return: * @peer: head peer */ -static inline struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_head( +static inline struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head( qdf_list_t *peer_list) { struct wlan_objmgr_peer *peer; - qdf_list_node_t *vdev_node = NULL; + qdf_list_node_t *psoc_node = NULL; /* This API is invoked with lock acquired, do not add log prints */ - if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) + if (qdf_list_peek_front(peer_list, &psoc_node) != QDF_STATUS_SUCCESS) return NULL; - peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, vdev_peer); + peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, psoc_peer); return peer; } /** - * wlan_vdev_peer_list_peek_active_head() - get active head of vdev peer list - * @vdev: VDEV object + * wlan_vdev_peer_list_peek_head() - get head of vdev peer list * @peer_list: qdf_list_t - * @dbg_id: Ref count debug module id * - * API to get the active head peer of given peer (of vdev's peer list) + * API to get the head peer of given peer (of vdev's peer list) + * + * Caller need to acquire lock with wlan_peer_obj_lock() * * Return: - * @peer: active head peer + * @peer: head peer */ -struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( - struct wlan_objmgr_vdev *vdev, - qdf_list_t *peer_list, - wlan_objmgr_ref_dbgid dbg_id); +static inline struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_head( + qdf_list_t *peer_list) +{ + struct wlan_objmgr_peer *peer; + qdf_list_node_t *vdev_node = NULL; + + /* This API is invoked with lock acquired, do not add log prints */ + if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) + return NULL; + + peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, vdev_peer); + return peer; +} /** * wlan_peer_get_next_peer_of_vdev() - get next peer of vdev list @@ -540,24 +694,6 @@ static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_vdev( return peer_next; } -/** - * wlan_peer_get_next_active_peer_of_vdev() - get next active_peer of vdev list - * @vdev: VDEV object - * @peer_list: Peer object list - * @peer: PEER object - * @dbg_id: Ref count debug module id - * - * API to get the next active peer of given peer (of vdev's peer list) - * - * Return: - * @next_peer: PEER object - */ -struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( - struct wlan_objmgr_vdev *vdev, - qdf_list_t *peer_list, - struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid dbg_id); - /** * wlan_peer_set_next_peer_of_vdev() - add peer to vdev peer list * @peer: PEER object @@ -611,45 +747,6 @@ static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc( return peer_next; } -/** - * wlan_peer_get_next_active_peer_of_psoc() - get next active peer to psoc peer - * list - * @peer_list: Peer list - * @hash_index: peer list hash index - * @peer: PEER object - * @dbg_id: Ref count debug module id - * - * API to get the next peer of given peer (of psoc's peer list) - * - * Return: - * @next_peer: PEER object - */ -struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( - struct wlan_peer_list *peer_list, - uint8_t hash_index, - struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid dbg_id); - - -/** - * wlan_peer_get_next_peer_of_psoc_ref() - get next peer to psoc peer list - * with lock and ref taken - * @peer_list: Peer list - * @hash_index: peer list hash index - * @peer: PEER object - * @dbg_id: Ref count debug module id - * - * API to get the next peer of given peer (of psoc's peer list) - * - * Return: - * @next_peer: PEER object - */ -struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( - struct wlan_peer_list *peer_list, - uint8_t hash_index, - struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid dbg_id); - /** * wlan_peer_set_next_peer_of_psoc() - add peer to psoc peer list * @peer: PEER object @@ -806,7 +903,7 @@ static inline void wlan_peer_set_vdev(struct wlan_objmgr_peer *peer, * Return: void */ static inline void wlan_peer_mlme_flag_set(struct wlan_objmgr_peer *peer, - uint32_t flag) + uint32_t flag) { peer->peer_mlme.peer_flags |= flag; } @@ -957,40 +1054,6 @@ static inline void wlan_peer_mlme_reset_seq_num( peer->peer_mlme.seq_num = 0; } -/** - * wlan_peer_set_dp_handle() - set dp handle - * @peer: peer object pointer - * @dp_handle: Data path module handle - * - * Return: void - */ -static inline void wlan_peer_set_dp_handle(struct wlan_objmgr_peer *peer, - void *dp_handle) -{ - if (qdf_unlikely(!peer)) { - QDF_BUG(0); - return; - } - - peer->dp_handle = dp_handle; -} - -/** - * wlan_peer_get_dp_handle() - get dp handle - * @peer: peer object pointer - * - * Return: dp handle - */ -static inline void *wlan_peer_get_dp_handle(struct wlan_objmgr_peer *peer) -{ - if (qdf_unlikely(!peer)) { - QDF_BUG(0); - return NULL; - } - - return peer->dp_handle; -} - /** * wlan_peer_get_psoc() - get psoc * @peer: PEER object @@ -1059,4 +1122,61 @@ uint32_t wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, enum wlan_umac_comp_id id); +/** + * wlan_objmgr_peer_trace_init_lock() - Initialize peer trace lock + * @peer: peer object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_TRACE +static inline void +wlan_objmgr_peer_trace_init_lock(struct wlan_objmgr_peer *peer) +{ + wlan_objmgr_trace_init_lock(&peer->peer_objmgr.trace); +} +#else +static inline void +wlan_objmgr_peer_trace_init_lock(struct wlan_objmgr_peer *peer) +{ +} +#endif + +/** + * wlan_objmgr_peer_trace_deinit_lock() - Deinitialize peer trace lock + * @peer: peer object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_TRACE +static inline void +wlan_objmgr_peer_trace_deinit_lock(struct wlan_objmgr_peer *peer) +{ + wlan_objmgr_trace_deinit_lock(&peer->peer_objmgr.trace); +} +#else +static inline void +wlan_objmgr_peer_trace_deinit_lock(struct wlan_objmgr_peer *peer) +{ +} +#endif + +/** + * wlan_objmgr_peer_trace_del_ref_list() - Delete peer trace reference list + * @peer: peer object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static inline void +wlan_objmgr_peer_trace_del_ref_list(struct wlan_objmgr_peer *peer) +{ + wlan_objmgr_trace_del_ref_list(&peer->peer_objmgr.trace); +} +#else +static inline void +wlan_objmgr_peer_trace_del_ref_list(struct wlan_objmgr_peer *peer) +{ +} +#endif + #endif /* _WLAN_OBJMGR_PEER_OBJ_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index f7eea2d6a4955201ab5c30c2cb62dc2bd8b16b31..c2c60313d699404ea2b2fc91171978820f84aaba 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,7 @@ #include "wlan_objmgr_cmn.h" #include "wlan_objmgr_debug.h" #include "wlan_lmac_if_def.h" +#include #define REG_DMN_CH144 0x0001 #define REG_DMN_ENTREPRISE 0x0002 @@ -131,6 +132,14 @@ #define WLAN_SOC_CEXT_OBSS_NBW_RU 0x00010000 /* MBSS IE support */ #define WLAN_SOC_CEXT_MBSS_IE 0x00020000 + /* RXOLE Flow Search Support */ +#define WLAN_SOC_CEXT_RX_FSE_SUPPORT 0x00040000 + /* Dynamic HW Mode Switch Support */ +#define WLAN_SOC_CEXT_DYNAMIC_HW_MODE 0x00080000 + /* Restricted 80+80 MHz support */ +#define WLAN_SOC_RESTRICTED_80P80_SUPPORT 0x00100000 + /* Indicates Firmware supports sending NSS ratio info to host */ +#define WLAN_SOC_NSS_RATIO_TO_HOST_SUPPORT 0x00200000 /* feature_flags */ /* CONF: ATH FF enabled */ @@ -187,11 +196,33 @@ #define WLAN_SOC_F_SPECTRAL_DISABLE 0x00800000 /* FTM testmode enable */ #define WLAN_SOC_F_TESTMODE_ENABLE 0x01000000 + /* Dynamic HW mode swithch enable */ +#define WLAN_SOC_F_DYNAMIC_HW_MODE 0x02000000 /* PSOC op flags */ /* Invalid VHT cap */ #define WLAN_SOC_OP_VHT_INVALID_CAP 0x00000001 + +/* enum wlan_nss_ratio - NSS ratio received from FW during service ready ext + * event. + * WLAN_NSS_RATIO_1BY2_NSS : Max nss of 160MHz is equals to half of the max nss + * of 80MHz + * WLAN_NSS_RATIO_3BY4_NSS : Max nss of 160MHz is equals to 3/4 of the max nss + * of 80MHz + * WLAN_NSS_RATIO_1_NSS : Max nss of 160MHz is equals to the max nss of 80MHz + * WLAN_NSS_RATIO_2_NSS : Max nss of 160MHz is equals to two times the max + * nss of 80MHz + * Values of this enum should be in sync with WMI_NSS_RATIO_INFO value provided + * in wmi_unified.h. + */ +enum wlan_nss_ratio { + WLAN_NSS_RATIO_1BY2_NSS = 0x0, + WLAN_NSS_RATIO_3BY4_NSS = 0x1, + WLAN_NSS_RATIO_1_NSS = 0x2, + WLAN_NSS_RATIO_2_NSS = 0x3, +}; + /** * struct wlan_objmgr_psoc_regulatory - Regulatory sub structure of PSOC * @country_code: Country code @@ -332,7 +363,7 @@ struct wlan_objmgr_psoc { void *soc_comp_priv_obj[WLAN_UMAC_MAX_COMPONENTS]; QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS]; WLAN_OBJ_STATE obj_state; - void *tgt_if_handle; + target_psoc_info_t *tgt_if_handle; void *dp_handle; qdf_spinlock_t psoc_lock; }; @@ -543,9 +574,19 @@ QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_debug( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, const char *func, int line); + +#define wlan_objmgr_get_peer_by_mac(psoc, macaddr, dbgid) \ + wlan_objmgr_get_peer_by_mac_debug(psoc, macaddr, dbgid, \ + __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer() - find peer from psoc's peer list @@ -563,9 +604,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer(psoc, pdev_id, macaddr, dbgid) \ + wlan_objmgr_get_peer_debug(psoc, pdev_id, macaddr, dbgid, \ + __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer_nolock() - find peer from psoc's peer list (lock free) @@ -583,9 +635,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer_nolock(psoc, pdev_id, macaddr, dbgid) \ + wlan_objmgr_get_peer_nolock_debug(psoc, pdev_id, macaddr, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer_logically_deleted() - find peer @@ -603,9 +666,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted_debug( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer_logically_deleted(psoc, macaddr, dbgid) \ + wlan_objmgr_get_peer_logically_deleted_debug(psoc, macaddr, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer_no_state() - find peer from psoc's peer list @@ -624,9 +698,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer_no_state(psoc, pdev_id, macaddr, dbgid) \ + wlan_objmgr_get_peer_no_state_debug(psoc, pdev_id, macaddr, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from @@ -649,10 +734,23 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( * Return: List of peer pointers * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( \ + psoc, pdev_id, bssid, macaddr, dbgid) \ + wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug( \ + psoc, pdev_id, bssid, macaddr, dbgid, __func__, __LINE__) +#else qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *bssid, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer_by_mac_n_vdev() - find peer from psoc's peer list @@ -673,10 +771,23 @@ qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer_by_mac_n_vdev(psoc, pdevid, bssid, macaddr, \ + dbgid) \ + wlan_objmgr_get_peer_by_mac_n_vdev_debug(psoc, pdevid, \ + bssid, macaddr, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *bssid, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_peer_by_mac_n_vdev_no_state() - find peer from psoc's peer @@ -697,10 +808,23 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( * Return: peer pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_peer_by_mac_n_vdev_no_state(psoc, pdevid, bssid, \ + macaddr, dbgid) \ + wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug(psoc, \ + pdevid, bssid, macaddr, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *bssid, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_pdev_by_id() - retrieve pdev by id @@ -793,10 +917,22 @@ struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_macaddr_no_state( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE opmode, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, opmode, dbgid) \ + wlan_objmgr_get_vdev_by_opmode_from_psoc_debug(psoc, opmode, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE opmode, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_id_from_psoc() - retrieve vdev by id @@ -813,9 +949,20 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, dbgid) \ + wlan_objmgr_get_vdev_by_id_from_psoc_debug(psoc, vdev_id, \ + dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_id_from_psoc_no_state() - retrieve vdev by id @@ -833,9 +980,20 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_id_from_psoc_no_state(psoc, vdev_id, dbgid) \ + wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug(psoc, \ + vdev_id, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_macaddr_from_psoc() - retrieve vdev by macaddr @@ -853,9 +1011,21 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_macaddr_from_psoc(psoc, pdev_id, macaddr, \ + dbgid) \ + wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug(psoc, pdev_id, \ + macaddr, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state() - retrieve vdev by @@ -875,9 +1045,22 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( * Return: vdev pointer * NULL on FAILURE */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev + *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state(psoc, pdev_id, \ + macaddr, dbgid) \ + wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug(psoc, \ + pdev_id, macaddr, dbgid, __func__, __LINE__) +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id); +#endif /** * wlan_psoc_obj_lock() - Acquire PSOC spinlock @@ -1224,8 +1407,9 @@ static inline uint8_t wlan_psoc_get_pdev_count(struct wlan_objmgr_psoc *psoc) * * Return: None */ -static inline void wlan_psoc_set_tgt_if_handle(struct wlan_objmgr_psoc *psoc, - void *tgt_if_handle) +static inline +void wlan_psoc_set_tgt_if_handle(struct wlan_objmgr_psoc *psoc, + target_psoc_info_t *tgt_if_handle) { if (!psoc) return; @@ -1241,7 +1425,8 @@ static inline void wlan_psoc_set_tgt_if_handle(struct wlan_objmgr_psoc *psoc, * * Return: target interface handle */ -static inline void *wlan_psoc_get_tgt_if_handle(struct wlan_objmgr_psoc *psoc) +static inline +target_psoc_info_t *wlan_psoc_get_tgt_if_handle(struct wlan_objmgr_psoc *psoc) { if (!psoc) return NULL; @@ -1446,25 +1631,33 @@ QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, * wlan_objmgr_psoc_check_for_pdev_leaks() - Assert no pdevs attached to @psoc * @psoc: The psoc to check * - * Return: None + * Return: No. of psoc leaks */ -void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc); +uint32_t wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc); /** * wlan_objmgr_psoc_check_for_vdev_leaks() - Assert no vdevs attached to @psoc * @psoc: The psoc to check * - * Return: None + * Return: No. of vdev leaks */ -void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc); +uint32_t wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc); /** * wlan_objmgr_psoc_check_for_peer_leaks() - Assert no peers attached to @psoc * @psoc: The psoc to check * + * Return: No. of peer leaks + */ +uint32_t wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_objmgr_psoc_check_for_leaks() - Assert on leak + * @psoc: The psoc to check + * * Return: None */ -void wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc); +void wlan_objmgr_psoc_check_for_leaks(struct wlan_objmgr_psoc *psoc); /** * wlan_objmgr_psoc_get_band_capability () - get user config @@ -1549,4 +1742,17 @@ static inline uint8_t wlan_psoc_get_id( return psoc->soc_objmgr.psoc_id; } + +/** + * wlan_print_psoc_info() - print psoc members + * @psoc: psoc object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc); +#else +static inline void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc) {} +#endif + #endif /* _WLAN_OBJMGR_PSOC_OBJ_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index a3cd24b47515647b6b61a9e961b1a96aa8fd2ee2..ce4637ef16e8f6c33c13ddf7cbce45881875eb8f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,11 +32,9 @@ #include "wlan_objmgr_pdev_obj.h" #include "wlan_objmgr_psoc_obj.h" #include "wlan_vdev_mlme_main.h" -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include "include/wlan_vdev_mlme.h" #include "wlan_vdev_mlme_api.h" #include "wlan_mlme_dbg.h" -#endif /* CONF: privacy enabled */ #define WLAN_VDEV_F_PRIVACY 0x00000001 @@ -168,6 +166,8 @@ #define WLAN_VDEV_FEXT_MAT 0x20000000 /* VDEV is wired PSTA*/ #define WLAN_VDEV_FEXT_WIRED_PSTA 0x40000000 + /* Fils discovery on 6G SAP*/ +#define WLAN_VDEV_FEXT_FILS_DISC_6G_SAP 0x80000000 /* VDEV OP flags */ /* if the vap destroyed by user */ @@ -234,7 +234,6 @@ /* Invalid VDEV identifier */ #define WLAN_INVALID_VDEV_ID 255 - /** * struct wlan_vdev_create_params - Create params, HDD/OSIF passes this * structure While creating VDEV @@ -258,11 +257,11 @@ struct wlan_vdev_create_params { * struct wlan_channel - channel structure * @ch_freq: Channel in Mhz. * @ch_ieee: IEEE channel number. - * @ch_flags: Channel flags. - * @ch_flagext: Channel extension flags. - * @ch_maxpower: Maximum tx power in dBm. * @ch_freq_seg1: Channel Center frequeny for VHT80/160 and HE80/160. * @ch_freq_seg2: Second channel Center frequency applicable for 80+80MHz mode. + * @ch_maxpower: Maximum tx power in dBm. + * @ch_flagext: Channel extension flags. + * @ch_flags: Channel flags. * @ch_cfreq1: channel center frequency for primary * @ch_cfreq2: channel center frequency for secondary * @ch_width: Channel width. @@ -271,11 +270,11 @@ struct wlan_vdev_create_params { struct wlan_channel { uint16_t ch_freq; uint8_t ch_ieee; - uint64_t ch_flags; - uint16_t ch_flagext; - int8_t ch_maxpower; uint8_t ch_freq_seg1; uint8_t ch_freq_seg2; + int8_t ch_maxpower; + uint16_t ch_flagext; + uint64_t ch_flags; uint32_t ch_cfreq1; uint32_t ch_cfreq2; enum phy_ch_width ch_width; @@ -317,17 +316,6 @@ struct wlan_objmgr_vdev_mlme { uint32_t vdev_op_flags; uint8_t mataddr[QDF_MAC_ADDR_SIZE]; uint8_t macaddr[QDF_MAC_ADDR_SIZE]; -#ifndef CMN_VDEV_MGR_TGT_IF_ENABLE - char ssid[WLAN_SSID_MAX_LEN + 1]; - uint8_t ssid_len; - uint8_t nss; - uint8_t tx_chainmask; - uint8_t rx_chainmask; - uint8_t tx_power; - uint32_t max_rate; - uint32_t tx_mgmt_rate; - uint32_t per_band_mgmt_rate[WLAN_BAND_NUM_MAX]; -#endif }; /** @@ -351,6 +339,7 @@ struct wlan_objmgr_vdev_nif { * @c_flags: creation specific flags * @ref_cnt: Ref count * @ref_id_dbg: Array to track Ref count + * @wlan_objmgr_trace: Trace ref and deref */ struct wlan_objmgr_vdev_objmgr { uint8_t vdev_id; @@ -364,6 +353,9 @@ struct wlan_objmgr_vdev_objmgr { uint32_t c_flags; qdf_atomic_t ref_cnt; qdf_atomic_t ref_id_dbg[WLAN_REF_ID_MAX]; +#ifdef WLAN_OBJMGR_REF_ID_TRACE + struct wlan_objmgr_trace trace; +#endif }; /** @@ -375,7 +367,6 @@ struct wlan_objmgr_vdev_objmgr { * @vdev_comp_priv_obj[]:Component's private objects list * @obj_status[]: Component object status * @obj_state: VDEV object state - * @dp_handle: DP module handle * @vdev_lock: VDEV lock */ struct wlan_objmgr_vdev { @@ -386,7 +377,6 @@ struct wlan_objmgr_vdev { void *vdev_comp_priv_obj[WLAN_UMAC_MAX_COMPONENTS]; QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS]; WLAN_OBJ_STATE obj_state; - void *dp_handle; qdf_spinlock_t vdev_lock; }; @@ -591,34 +581,6 @@ static inline struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_head( return vdev; } -/** - * wlan_pdev_peek_active_first_vdev() - get first active vdev from pdev list - * @pdev: PDEV object - * @dbg_id: id of the caller - * - * API to get the head active vdev of given pdev (of pdev's vdev list) - * - * Return: - */ -struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev( - struct wlan_objmgr_pdev *pdev, - wlan_objmgr_ref_dbgid dbg_id); - -/** - * wlan_pdev_vdev_list_peek_active_head() - get first active vdev from pdev list - * @vdev: VDEV object - * @vdev_list: qdf_list_t - * @dbg_id: id of the caller - * - * API to get the head active vdev of given vdev (of pdev's vdev list) - * - * Return: - * @peer: head peer - */ -struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( - struct wlan_objmgr_pdev *pdev, - qdf_list_t *vdev_list, - wlan_objmgr_ref_dbgid dbg_id); /** * wlan_vdev_get_next_vdev_of_pdev() - get next vdev @@ -652,23 +614,6 @@ static inline struct wlan_objmgr_vdev *wlan_vdev_get_next_vdev_of_pdev( return vdev_next; } -/** - * wlan_vdev_get_next_active_vdev_of_pdev() - get next active vdev - * @pdev: PDEV object - * @vdev_list: qdf_list_t - * @vdev: VDEV object - * @dbg_id: id of the caller - * - * API to get next active vdev object pointer of vdev - * - * Return: - * @vdev_next: VDEV object - */ -struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( - struct wlan_objmgr_pdev *pdev, - qdf_list_t *vdev_list, - struct wlan_objmgr_vdev *vdev, - wlan_objmgr_ref_dbgid dbg_id); /** @@ -939,252 +884,6 @@ static inline struct wlan_channel *wlan_vdev_mlme_get_des_chan( return vdev->vdev_mlme.des_chan; } -#ifndef CMN_VDEV_MGR_TGT_IF_ENABLE - -/** - * wlan_vdev_mlme_set_ssid() - set ssid - * @vdev: VDEV object - * @ssid: SSID (input) - * @ssid_len: Length of SSID - * - * API to set the SSID of VDEV - * - * Caller need to acquire lock with wlan_vdev_obj_lock() - * - * Return: SUCCESS, if update is done - * FAILURE, if ssid length is > max ssid len - */ -static inline QDF_STATUS wlan_vdev_mlme_set_ssid( - struct wlan_objmgr_vdev *vdev, - const uint8_t *ssid, uint8_t ssid_len) -{ - /* This API is invoked with lock acquired, do not add log prints */ - if (ssid_len <= WLAN_SSID_MAX_LEN) { - qdf_mem_copy(vdev->vdev_mlme.ssid, ssid, ssid_len); - vdev->vdev_mlme.ssid_len = ssid_len; - } else { - vdev->vdev_mlme.ssid_len = 0; - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -/** - * wlan_vdev_mlme_get_ssid() - get ssid - * @vdev: VDEV object - * @ssid: SSID - * @ssid_len: Length of SSID - * - * API to get the SSID of VDEV, it updates the SSID and its length - * in @ssid, @ssid_len respectively - * - * Caller need to acquire lock with wlan_vdev_obj_lock() - * - * Return: SUCCESS, if update is done - * FAILURE, if ssid length is > max ssid len - */ -static inline QDF_STATUS wlan_vdev_mlme_get_ssid( - struct wlan_objmgr_vdev *vdev, - uint8_t *ssid, uint8_t *ssid_len) -{ - /* This API is invoked with lock acquired, do not add log prints */ - if (vdev->vdev_mlme.ssid_len > 0) { - *ssid_len = vdev->vdev_mlme.ssid_len; - qdf_mem_copy(ssid, vdev->vdev_mlme.ssid, *ssid_len); - } else { - *ssid_len = 0; - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -/** - * wlan_vdev_mlme_set_nss() - set NSS - * @vdev: VDEV object - * @nss: nss configured by user - * - * API to set the Number of Spatial streams - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_nss(struct wlan_objmgr_vdev *vdev, - uint8_t nss) -{ - vdev->vdev_mlme.nss = nss; -} - -/** - * wlan_vdev_mlme_get_nss() - get NSS - * @vdev: VDEV object - * - * API to get the Number of Spatial Streams - * - * Return: - * @nss: nss value - */ -static inline uint8_t wlan_vdev_mlme_get_nss( - struct wlan_objmgr_vdev *vdev) -{ - return vdev->vdev_mlme.nss; -} - -/** - * wlan_vdev_mlme_set_txchainmask() - set Tx chainmask - * @vdev: VDEV object - * @chainmask : chainmask either configured by user or max supported - * - * API to set the Tx chainmask - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_txchainmask( - struct wlan_objmgr_vdev *vdev, - uint8_t chainmask) -{ - vdev->vdev_mlme.tx_chainmask = chainmask; -} - -/** - * wlan_vdev_mlme_get_txchainmask() - get Tx chainmask - * @vdev: VDEV object - * - * API to get the Tx chainmask - * - * Return: - * @chainmask : Tx chainmask either configured by user or max supported - */ -static inline uint8_t wlan_vdev_mlme_get_txchainmask( - struct wlan_objmgr_vdev *vdev) -{ - return vdev->vdev_mlme.tx_chainmask; -} - -/** - * wlan_vdev_mlme_set_rxchainmask() - set Rx chainmask - * @vdev: VDEV object - * @chainmask : Rx chainmask either configured by user or max supported - * - * API to set the Rx chainmask - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_rxchainmask( - struct wlan_objmgr_vdev *vdev, - uint8_t chainmask) -{ - vdev->vdev_mlme.rx_chainmask = chainmask; -} - -/** - * wlan_vdev_mlme_get_rxchainmask() - get Rx chainmask - * @vdev: VDEV object - * - * API to get the Rx chainmask - * - * Return: - * @chainmask : Rx chainmask either configured by user or max supported - */ -static inline uint8_t wlan_vdev_mlme_get_rxchainmask( - struct wlan_objmgr_vdev *vdev) -{ - /* This API is invoked with lock acquired, do not add log prints */ - return vdev->vdev_mlme.rx_chainmask; -} - -/** - * wlan_vdev_mlme_set_txpower() - set tx power - * @vdev: VDEV object - * @txpow: tx power either configured by used or max allowed - * - * API to set the tx power - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_txpower( - struct wlan_objmgr_vdev *vdev, - uint8_t txpow) -{ - vdev->vdev_mlme.tx_power = txpow; -} - -/** - * wlan_vdev_mlme_get_txpower() - get tx power - * @vdev: VDEV object - * - * API to get the tx power - * - * Return: - * @txpow: tx power either configured by used or max allowed - */ -static inline uint8_t wlan_vdev_mlme_get_txpower( - struct wlan_objmgr_vdev *vdev) -{ - return vdev->vdev_mlme.tx_power; -} - -/** - * wlan_vdev_mlme_set_maxrate() - set max rate - * @vdev: VDEV object - * @maxrate: configured by used or based on configured mode - * - * API to set the max rate the vdev supports - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_maxrate( - struct wlan_objmgr_vdev *vdev, - uint32_t maxrate) -{ - vdev->vdev_mlme.max_rate = maxrate; -} - -/** - * wlan_vdev_mlme_get_maxrate() - get max rate - * @vdev: VDEV object - * - * API to get the max rate the vdev supports - * - * Return: - * @maxrate: configured by used or based on configured mode - */ -static inline uint32_t wlan_vdev_mlme_get_maxrate( - struct wlan_objmgr_vdev *vdev) -{ - return vdev->vdev_mlme.max_rate; -} - -/** - * wlan_vdev_mlme_set_txmgmtrate() - set txmgmtrate - * @vdev: VDEV object - * @txmgmtrate: Tx Mgmt rate - * - * API to set Mgmt Tx rate - * - * Return: void - */ -static inline void wlan_vdev_mlme_set_txmgmtrate( - struct wlan_objmgr_vdev *vdev, - uint32_t txmgmtrate) -{ - vdev->vdev_mlme.tx_mgmt_rate = txmgmtrate; -} - -/** - * wlan_vdev_mlme_get_txmgmtrate() - get txmgmtrate - * @vdev: VDEV object - * - * API to get Mgmt Tx rate - * - * Return: - * @txmgmtrate: Tx Mgmt rate - */ -static inline uint32_t wlan_vdev_mlme_get_txmgmtrate( - struct wlan_objmgr_vdev *vdev) -{ - return vdev->vdev_mlme.tx_mgmt_rate; -} -#endif - /** * wlan_vdev_mlme_feat_cap_set() - set feature caps * @vdev: VDEV object @@ -1416,6 +1115,22 @@ static inline struct wlan_objmgr_peer *wlan_vdev_get_bsspeer( return vdev->vdev_objmgr.bss_peer; } +/** + * wlan_objmgr_vdev_find_peer_by_mac() - get a peer with given mac from vdev + * @vdev: VDEV object + * @peer_mac: mac address of the peer to be found + * @dbg_id: dbg_id of the module + * + * API to get and increment ref count of BSS peer of VDEV + * + * Return: + * @peer: peer pointer to the peer of the mac address + */ +struct wlan_objmgr_peer * +wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + wlan_objmgr_ref_dbgid dbg_id); + /** * wlan_objmgr_vdev_try_get_bsspeer() - get and increment ref count of BSS peer * of VDEV @@ -1510,8 +1225,17 @@ static inline uint16_t wlan_vdev_get_peer_count(struct wlan_objmgr_vdev *vdev) * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_vdev_get_ref(vdev, dbgid) \ + wlan_objmgr_vdev_get_ref_debug(vdev, dbgid, __func__, __LINE__) +#else void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, wlan_objmgr_ref_dbgid id); +#endif /** * wlan_objmgr_vdev_try_get_ref() - increment ref count, if allowed @@ -1522,8 +1246,18 @@ void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +QDF_STATUS wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_vdev_try_get_ref(vdev, dbgid) \ + wlan_objmgr_vdev_try_get_ref_debug(vdev, dbgid, \ + __func__, __LINE__) +#else QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, wlan_objmgr_ref_dbgid id); +#endif /** * wlan_objmgr_vdev_release_ref() - decrement ref count @@ -1535,8 +1269,111 @@ QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, * * Return: void */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line); + +#define wlan_objmgr_vdev_release_ref(vdev, dbgid)\ + wlan_objmgr_vdev_release_ref_debug(vdev, dbgid, \ + __func__, __LINE__) +#else void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev, wlan_objmgr_ref_dbgid id); +#endif + +/** + * wlan_vdev_get_next_active_vdev_of_pdev() - get next active vdev + * @pdev: PDEV object + * @vdev_list: qdf_list_t + * @vdev: VDEV object + * @dbg_id: id of the caller + * + * API to get next active vdev object pointer of vdev + * + * Return: + * @vdev_next: VDEV object + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev_debug( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_vdev_get_next_active_vdev_of_pdev(pdev, vdev_list, vdev, dbgid) \ + wlan_vdev_get_next_active_vdev_of_pdev_debug(pdev, vdev_list, \ + vdev, dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_pdev_peek_active_first_vdev() - get first active vdev from pdev list + * @pdev: PDEV object + * @dbg_id: id of the caller + * + * API to get the head active vdev of given pdev (of pdev's vdev list) + * + * Return: + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev_debug( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_pdev_peek_active_first_vdev(pdev, dbgid) \ + wlan_pdev_peek_active_first_vdev_debug(pdev, dbgid, \ + __func__, __LINE__) +#else +struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_pdev_vdev_list_peek_active_head() - get first active vdev from pdev list + * @vdev: VDEV object + * @vdev_list: qdf_list_t + * @dbg_id: id of the caller + * + * API to get the head active vdev of given vdev (of pdev's vdev list) + * + * Return: + * @peer: head peer + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head_debug( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line); + +#define wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list, dbgid) \ + wlan_pdev_vdev_list_peek_active_head_debug(pdev, vdev_list, \ + dbgid, __func__, __LINE__) +#else +struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + wlan_objmgr_ref_dbgid dbg_id); +#endif + +/** + * wlan_objmgr_vdev_peer_freed_notify() - Notifies modules about peer freed + * @vdev: VDEV object + * + * API to invokes registered callbacks to notify about peer freed + * + * Return: void + */ +void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev); /** * wlan_vdev_set_max_peer_count() - set max peer count @@ -1568,37 +1405,72 @@ static inline uint16_t wlan_vdev_get_max_peer_count( } /** - * wlan_vdev_set_dp_handle() - set dp handle + * wlan_print_vdev_info() - print vdev members * @vdev: vdev object pointer - * @dp_handle: Data path module handle * * Return: void */ -static inline void wlan_vdev_set_dp_handle(struct wlan_objmgr_vdev *vdev, - void *dp_handle) -{ - if (qdf_unlikely(!vdev)) { - QDF_BUG(0); - return; - } +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev); +#else +static inline void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev) {} +#endif - vdev->dp_handle = dp_handle; +/** + * wlan_objmgr_vdev_trace_init_lock() - Initialize trace lock + * @vdev: vdev object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_TRACE +static inline void +wlan_objmgr_vdev_trace_init_lock(struct wlan_objmgr_vdev *vdev) +{ + wlan_objmgr_trace_init_lock(&vdev->vdev_objmgr.trace); +} +#else +static inline void +wlan_objmgr_vdev_trace_init_lock(struct wlan_objmgr_vdev *vdev) +{ } +#endif /** - * wlan_vdev_get_dp_handle() - get dp handle + * wlan_objmgr_vdev_trace_deinit_lock() - Deinitialize trace lock * @vdev: vdev object pointer * - * Return: dp handle + * Return: void */ -static inline void *wlan_vdev_get_dp_handle(struct wlan_objmgr_vdev *vdev) +#ifdef WLAN_OBJMGR_TRACE +static inline void +wlan_objmgr_vdev_trace_deinit_lock(struct wlan_objmgr_vdev *vdev) { - if (qdf_unlikely(!vdev)) { - QDF_BUG(0); - return NULL; - } + wlan_objmgr_trace_deinit_lock(&vdev->vdev_objmgr.trace); +} +#else +static inline void +wlan_objmgr_vdev_trace_deinit_lock(struct wlan_objmgr_vdev *vdev) +{ +} +#endif - return vdev->dp_handle; +/** + * wlan_objmgr_vdev_trace_del_ref_list() - Delete trace ref list + * @vdev: vdev object pointer + * + * Return: void + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static inline void +wlan_objmgr_vdev_trace_del_ref_list(struct wlan_objmgr_vdev *vdev) +{ + wlan_objmgr_trace_del_ref_list(&vdev->vdev_objmgr.trace); +} +#else +static inline void +wlan_objmgr_vdev_trace_del_ref_list(struct wlan_objmgr_vdev *vdev) +{ } +#endif #endif /* _WLAN_OBJMGR_VDEV_OBJ_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_debug.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_debug.c index ea9efebcee8edc093ebf2a8effcbe51440b6e587..a6d9b242b374073b43cb1b0c9b883a9801d50e46 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_debug.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_debug.c @@ -27,9 +27,14 @@ #include "wlan_objmgr_global_obj_i.h" #include #include +#include -#define LOG_DEL_OBJ_TIMEOUT_VALUE_MSEC 5000 -#define LOG_DEL_OBJ_DESTROY_DURATION_SEC 5 +/* + * Default TTL (of FW) for mgmt frames is 5 sec, by considering all the other + * delays, arrived with this value + */ +#define LOG_DEL_OBJ_TIMEOUT_VALUE_MSEC 8000 +#define LOG_DEL_OBJ_DESTROY_DURATION_SEC 8 /* * The max duration for which a obj can be allowed to remain in L-state * The duration should be higher than the psoc idle timeout. @@ -37,6 +42,13 @@ #define LOG_DEL_OBJ_DESTROY_ASSERT_DURATION_SEC 32 #define LOG_DEL_OBJ_LIST_MAX_COUNT (3 + 5 + 48 + 4096) +union wlan_objmgr_del_obj { + struct wlan_objmgr_psoc *obj_psoc; + struct wlan_objmgr_pdev *obj_pdev; + struct wlan_objmgr_vdev *obj_vdev; + struct wlan_objmgr_peer *obj_peer; +}; + /** * struct log_del_obj - Logically deleted Object * @obj: Represents peer/vdev/pdev/psoc @@ -46,7 +58,7 @@ * deleted state */ struct log_del_obj { - void *obj; + union wlan_objmgr_del_obj obj; qdf_list_node_t node; enum wlan_objmgr_obj_type obj_type; qdf_time_t tstamp; @@ -89,18 +101,18 @@ wlan_obj_type_get_obj_name(enum wlan_objmgr_obj_type obj_type) } static uint8_t* -wlan_objmgr_debug_get_macaddr(void *obj, +wlan_objmgr_debug_get_macaddr(union wlan_objmgr_del_obj *obj, enum wlan_objmgr_obj_type obj_type) { switch (obj_type) { case WLAN_PSOC_OP: - return wlan_psoc_get_hw_macaddr(obj); + return wlan_psoc_get_hw_macaddr(obj->obj_psoc); case WLAN_PDEV_OP: - return wlan_pdev_get_hw_macaddr(obj); + return wlan_pdev_get_hw_macaddr(obj->obj_pdev); case WLAN_VDEV_OP: - return wlan_vdev_mlme_get_macaddr(obj); + return wlan_vdev_mlme_get_macaddr(obj->obj_vdev); case WLAN_PEER_OP: - return wlan_peer_get_macaddr(obj); + return wlan_peer_get_macaddr(obj->obj_peer); default: obj_mgr_err("invalid obj_type"); return NULL; @@ -123,6 +135,29 @@ wlan_objmgr_insert_ld_obj_to_list(struct wlan_objmgr_debug_info *debug_info, qdf_spin_unlock_bh(&debug_info->list_lock); } +static void wlan_obj_type_get_obj(union wlan_objmgr_del_obj *obj, + union wlan_objmgr_del_obj *del_obj, + enum wlan_objmgr_obj_type obj_type) +{ + switch (obj_type) { + case WLAN_PSOC_OP: + del_obj->obj_psoc = obj->obj_psoc; + return; + case WLAN_PDEV_OP: + del_obj->obj_pdev = obj->obj_pdev; + return; + case WLAN_VDEV_OP: + del_obj->obj_vdev = obj->obj_vdev; + return; + case WLAN_PEER_OP: + del_obj->obj_peer = obj->obj_peer; + return; + default: + obj_mgr_err("invalid obj_type"); + return; + } +} + void wlan_objmgr_notify_log_delete(void *obj, enum wlan_objmgr_obj_type obj_type) { @@ -131,6 +166,7 @@ void wlan_objmgr_notify_log_delete(void *obj, uint8_t *macaddr; qdf_time_t tstamp; struct log_del_obj *node; + union wlan_objmgr_del_obj *del_obj = (union wlan_objmgr_del_obj *)&obj; if (!obj) { obj_mgr_err("object is null"); @@ -146,7 +182,7 @@ void wlan_objmgr_notify_log_delete(void *obj, return; } - macaddr = wlan_objmgr_debug_get_macaddr(obj, obj_type); + macaddr = wlan_objmgr_debug_get_macaddr(del_obj, obj_type); if (!macaddr) { obj_mgr_err("macaddr is null"); return; @@ -163,16 +199,38 @@ void wlan_objmgr_notify_log_delete(void *obj, if (!node) return; - node->obj = obj; + wlan_obj_type_get_obj(del_obj, &node->obj, obj_type); node->obj_type = obj_type; node->tstamp = tstamp; - obj_mgr_debug("#%s : mac_addr :" QDF_MAC_ADDR_STR" entered L-state", - obj_name, QDF_MAC_ADDR_ARRAY(macaddr)); + obj_mgr_debug("#%s : mac_addr: "QDF_MAC_ADDR_FMT" entered L-state", + obj_name, QDF_MAC_ADDR_REF(macaddr)); wlan_objmgr_insert_ld_obj_to_list(debug_info, &node->node); } +static bool wlan_objmgr_del_obj_match(union wlan_objmgr_del_obj *obj, + union wlan_objmgr_del_obj *del_obj, + enum wlan_objmgr_obj_type obj_type) +{ + switch (obj_type) { + case WLAN_PSOC_OP: + if (del_obj->obj_psoc == obj->obj_psoc) + return true; + case WLAN_PDEV_OP: + if (del_obj->obj_pdev == obj->obj_pdev) + return true; + case WLAN_VDEV_OP: + if (del_obj->obj_vdev == obj->obj_vdev) + return true; + case WLAN_PEER_OP: + if (del_obj->obj_peer == obj->obj_peer) + return true; + default: + return false; + } +} + static void -wlan_objmgr_rem_ld_obj_from_list(void *obj, +wlan_objmgr_rem_ld_obj_from_list(union wlan_objmgr_del_obj *obj, struct wlan_objmgr_debug_info *debug_info, enum wlan_objmgr_obj_type obj_type) { @@ -188,7 +246,8 @@ wlan_objmgr_rem_ld_obj_from_list(void *obj, while (QDF_IS_STATUS_SUCCESS(status)) { obj_to_remove = qdf_container_of(node, struct log_del_obj, node); - if (obj_to_remove->obj == obj && + if (wlan_objmgr_del_obj_match(obj, &obj_to_remove->obj, + obj_type) && obj_to_remove->obj_type == obj_type) { status = qdf_list_remove_node(list, &obj_to_remove->node); @@ -211,6 +270,7 @@ void wlan_objmgr_notify_destroy(void *obj, struct wlan_objmgr_debug_info *debug_info; uint8_t *macaddr; const char *obj_name; + union wlan_objmgr_del_obj *del_obj = (union wlan_objmgr_del_obj *)&obj; qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); debug_info = g_umac_glb_obj->debug_info; @@ -220,7 +280,7 @@ void wlan_objmgr_notify_destroy(void *obj, obj_mgr_err("debug_info is null"); return; } - macaddr = wlan_objmgr_debug_get_macaddr(obj, obj_type); + macaddr = wlan_objmgr_debug_get_macaddr(del_obj, obj_type); if (!macaddr) { obj_mgr_err("macaddr is null"); return; @@ -230,10 +290,11 @@ void wlan_objmgr_notify_destroy(void *obj, obj_mgr_err("obj_name is null"); return; } - obj_mgr_debug("#%s, macaddr: " QDF_MAC_ADDR_STR" exited L-state", - obj_name, QDF_MAC_ADDR_ARRAY(macaddr)); + obj_mgr_debug("#%s : macaddr: "QDF_MAC_ADDR_FMT" exited L-state", + obj_name, QDF_MAC_ADDR_REF(macaddr)); - wlan_objmgr_rem_ld_obj_from_list(obj, debug_info, obj_type); + wlan_objmgr_rem_ld_obj_from_list(del_obj, + debug_info, obj_type); } /** @@ -266,28 +327,24 @@ static inline void wlan_objmgr_debug_obj_destroyed_panic(const char *obj_name) * * Return: None */ -static void wlan_objmgr_print_pending_refs(void *obj, +static void wlan_objmgr_print_pending_refs(union wlan_objmgr_del_obj *obj, enum wlan_objmgr_obj_type obj_type) { switch (obj_type) { case WLAN_PSOC_OP: - wlan_objmgr_print_ref_ids(((struct wlan_objmgr_psoc *) - obj)->soc_objmgr.ref_id_dbg, + wlan_objmgr_print_ref_ids(obj->obj_psoc->soc_objmgr.ref_id_dbg, QDF_TRACE_LEVEL_DEBUG); break; case WLAN_PDEV_OP: - wlan_objmgr_print_ref_ids(((struct wlan_objmgr_pdev *) - obj)->pdev_objmgr.ref_id_dbg, + wlan_objmgr_print_ref_ids(obj->obj_pdev->pdev_objmgr.ref_id_dbg, QDF_TRACE_LEVEL_DEBUG); break; case WLAN_VDEV_OP: - wlan_objmgr_print_ref_ids(((struct wlan_objmgr_vdev *) - obj)->vdev_objmgr.ref_id_dbg, + wlan_objmgr_print_ref_ids(obj->obj_vdev->vdev_objmgr.ref_id_dbg, QDF_TRACE_LEVEL_DEBUG); break; case WLAN_PEER_OP: - wlan_objmgr_print_ref_ids(((struct wlan_objmgr_peer *) - obj)->peer_objmgr.ref_id_dbg, + wlan_objmgr_print_ref_ids(obj->obj_peer->peer_objmgr.ref_id_dbg, QDF_TRACE_LEVEL_DEBUG); break; default: @@ -295,6 +352,84 @@ static void wlan_objmgr_print_pending_refs(void *obj, } } +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static void +wlan_objmgr_print_ref_func_line(struct wlan_objmgr_trace_func *func_head, + uint32_t id) +{ + uint32_t ref_cnt; + struct wlan_objmgr_line_ref_node *tmp_ln_node; + + obj_mgr_debug("ID: %s", string_from_dbgid(id)); + while (func_head) { + obj_mgr_debug("Func: %s", func_head->func); + tmp_ln_node = func_head->line_head; + while (tmp_ln_node) { + ref_cnt = qdf_atomic_read(&tmp_ln_node->line_ref.cnt); + obj_mgr_debug("line: %d cnt: %d", + tmp_ln_node->line_ref.line, + ref_cnt); + tmp_ln_node = tmp_ln_node->next; + } + func_head = func_head->next; + } +} + +static void +wlan_objmgr_trace_print_ref(union wlan_objmgr_del_obj *obj, + enum wlan_objmgr_obj_type obj_type) +{ + uint32_t id; + struct wlan_objmgr_trace_func *func_head; + struct wlan_objmgr_trace *trace; + struct wlan_objmgr_vdev_objmgr *vdev_obj; + struct wlan_objmgr_peer_objmgr *peer_obj; + + switch (obj_type) { + case WLAN_VDEV_OP: + vdev_obj = &obj->obj_vdev->vdev_objmgr; + trace = &vdev_obj->trace; + for (id = 0; id < WLAN_REF_ID_MAX; id++) { + if (qdf_atomic_read(&vdev_obj->ref_id_dbg[id])) { + obj_mgr_debug("Reference:"); + + func_head = trace->references[id].head; + wlan_objmgr_print_ref_func_line(func_head, id); + + obj_mgr_debug("Dereference:"); + func_head = trace->dereferences[id].head; + wlan_objmgr_print_ref_func_line(func_head, id); + } + } + break; + case WLAN_PEER_OP: + peer_obj = &obj->obj_peer->peer_objmgr; + trace = &peer_obj->trace; + for (id = 0; id < WLAN_REF_ID_MAX; id++) { + if (qdf_atomic_read(&vdev_obj->ref_id_dbg[id])) { + obj_mgr_debug("Reference:"); + + func_head = trace->references[id].head; + wlan_objmgr_print_ref_func_line(func_head, id); + + obj_mgr_debug("Dereference:"); + func_head = trace->dereferences[id].head; + wlan_objmgr_print_ref_func_line(func_head, id); + } + } + break; + default: + break; + } +} +#else +static void +wlan_objmgr_trace_print_ref(union wlan_objmgr_del_obj *obj, + enum wlan_objmgr_obj_type obj_type) +{ +} +#endif + /* timeout handler for iterating logically deleted object */ static void wlan_objmgr_iterate_log_del_obj_handler(void *timer_arg) @@ -335,7 +470,8 @@ static void wlan_objmgr_iterate_log_del_obj_handler(void *timer_arg) do { del_obj = qdf_container_of(node, struct log_del_obj, node); obj_type = del_obj->obj_type; - macaddr = wlan_objmgr_debug_get_macaddr(del_obj->obj, obj_type); + macaddr = wlan_objmgr_debug_get_macaddr(&del_obj->obj, + obj_type); obj_name = wlan_obj_type_get_obj_name(obj_type); /* If object is in logically deleted state for time more than @@ -356,10 +492,11 @@ static void wlan_objmgr_iterate_log_del_obj_handler(void *timer_arg) break; } - obj_mgr_alert("#%s in L-state,MAC: " QDF_MAC_ADDR_STR, - obj_name, QDF_MAC_ADDR_ARRAY(macaddr)); - wlan_objmgr_print_pending_refs(del_obj->obj, obj_type); + obj_mgr_alert("#%s in L-state,MAC: " QDF_MAC_ADDR_FMT, + obj_name, QDF_MAC_ADDR_REF(macaddr)); + wlan_objmgr_print_pending_refs(&del_obj->obj, obj_type); + wlan_objmgr_trace_print_ref(&del_obj->obj, obj_type); if (cur_tstamp > del_obj->tstamp + LOG_DEL_OBJ_DESTROY_ASSERT_DURATION_SEC) { if (!qdf_is_recovering() && !qdf_is_fw_down()) @@ -455,3 +592,163 @@ void wlan_objmgr_debug_info_init(void) g_umac_glb_obj->debug_info = debug_info; qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); } + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void +wlan_objmgr_trace_init_lock(struct wlan_objmgr_trace *trace) +{ + qdf_spinlock_create(&trace->trace_lock); +} + +void +wlan_objmgr_trace_deinit_lock(struct wlan_objmgr_trace *trace) +{ + qdf_spinlock_destroy(&trace->trace_lock); +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static inline struct wlan_objmgr_line_ref_node* +wlan_objmgr_trace_line_node_alloc(int line) +{ + struct wlan_objmgr_line_ref_node *line_node; + + line_node = qdf_mem_malloc_atomic(sizeof(*line_node)); + if (!line_node) + return NULL; + + line_node->line_ref.line = line; + qdf_atomic_set(&line_node->line_ref.cnt, 1); + line_node->next = NULL; + + return line_node; +} + +static inline struct wlan_objmgr_trace_func* +wlan_objmgr_trace_ref_node_alloc(const char *func, int line) +{ + struct wlan_objmgr_trace_func *func_node; + struct wlan_objmgr_line_ref_node *line_node; + + func_node = qdf_mem_malloc_atomic(sizeof(*func_node)); + if (!func_node) + return NULL; + + line_node = wlan_objmgr_trace_line_node_alloc(line); + if (!line_node) { + qdf_mem_free(func_node); + return NULL; + } + + func_node->line_head = line_node; + qdf_str_lcopy(func_node->func, func, WLAN_OBJMGR_TRACE_FUNC_SIZE); + func_node->next = NULL; + + return func_node; +} + +static inline void +wlan_objmgr_trace_check_line(struct wlan_objmgr_trace_func *tmp_func_node, + struct wlan_objmgr_trace *trace, int line) +{ + struct wlan_objmgr_line_ref_node *line_node; + struct wlan_objmgr_line_ref_node *tmp_ln_node; + + tmp_ln_node = tmp_func_node->line_head; + while (tmp_ln_node) { + line_node = tmp_ln_node; + if (tmp_ln_node->line_ref.line == line) { + qdf_atomic_inc(&tmp_ln_node->line_ref.cnt); + break; + } + tmp_ln_node = tmp_ln_node->next; + } + if (!tmp_ln_node) { + tmp_ln_node = wlan_objmgr_trace_line_node_alloc(line); + if (tmp_ln_node) + line_node->next = tmp_ln_node; + } +} + +void +wlan_objmgr_trace_ref(struct wlan_objmgr_trace_func **func_head, + struct wlan_objmgr_trace *trace, + const char *func, int line) +{ + struct wlan_objmgr_trace_func *tmp_func_node; + struct wlan_objmgr_trace_func *func_node; + + qdf_spin_lock_bh(&trace->trace_lock); + if (!*func_head) { + tmp_func_node = wlan_objmgr_trace_ref_node_alloc(func, line); + if (tmp_func_node) + *func_head = tmp_func_node; + } else { + tmp_func_node = *func_head; + while (tmp_func_node) { + func_node = tmp_func_node; + if (!qdf_str_ncmp(tmp_func_node->func, func, + WLAN_OBJMGR_TRACE_FUNC_SIZE - 1)) { + wlan_objmgr_trace_check_line(tmp_func_node, + trace, line); + break; + } + tmp_func_node = tmp_func_node->next; + } + + if (!tmp_func_node) { + tmp_func_node = wlan_objmgr_trace_ref_node_alloc(func, + line); + if (tmp_func_node) + func_node->next = tmp_func_node; + } + } + qdf_spin_unlock_bh(&trace->trace_lock); +} + +void +wlan_objmgr_trace_del_line(struct wlan_objmgr_line_ref_node **line_head) +{ + struct wlan_objmgr_line_ref_node *del_tmp_node; + struct wlan_objmgr_line_ref_node *line_node; + + line_node = *line_head; + while (line_node) { + del_tmp_node = line_node; + line_node = line_node->next; + qdf_mem_free(del_tmp_node); + } + *line_head = NULL; +} + +void +wlan_objmgr_trace_del_ref_list(struct wlan_objmgr_trace *trace) +{ + struct wlan_objmgr_trace_func *func_node; + struct wlan_objmgr_trace_func *del_tmp_node; + uint32_t id; + + qdf_spin_lock_bh(&trace->trace_lock); + for (id = 0; id < WLAN_REF_ID_MAX; id++) { + func_node = trace->references[id].head; + while (func_node) { + del_tmp_node = func_node; + wlan_objmgr_trace_del_line(&del_tmp_node->line_head); + func_node = func_node->next; + qdf_mem_free(del_tmp_node); + } + trace->references[id].head = NULL; + } + for (id = 0; id < WLAN_REF_ID_MAX; id++) { + func_node = trace->dereferences[id].head; + while (func_node) { + del_tmp_node = func_node; + wlan_objmgr_trace_del_line(&del_tmp_node->line_head); + func_node = func_node->next; + qdf_mem_free(del_tmp_node); + } + trace->dereferences[id].head = NULL; + } + qdf_spin_unlock_bh(&trace->trace_lock); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c index 19748d8587b1f3ca8c7f2f596e48047b3872aea1..f307d213bba6238c33f510250917d6398d953c3a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c @@ -556,6 +556,55 @@ QDF_STATUS wlan_objmgr_unregister_vdev_status_handler( return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler( + enum wlan_umac_comp_id id, + wlan_objmgr_vdev_peer_free_notify_handler handler) +{ + /* If id is not within valid range, return */ + if (id >= WLAN_UMAC_MAX_COMPONENTS) { + obj_mgr_err("Component %d is out of range", id); + WLAN_OBJMGR_BUG(0); + return QDF_STATUS_MAXCOMP_FAIL; + } + qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); + /* If there is a valid entry, return failure */ + if (g_umac_glb_obj->vdev_peer_free_notify_handler[id]) { + qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); + obj_mgr_err("Callback for comp %d is already registered", id); + return QDF_STATUS_E_FAILURE; + } + /* Store handler in Global object table */ + g_umac_glb_obj->vdev_peer_free_notify_handler[id] = handler; + + qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler( + enum wlan_umac_comp_id id, + wlan_objmgr_vdev_peer_free_notify_handler handler) +{ + /* If id is not within valid range, return */ + if (id >= WLAN_UMAC_MAX_COMPONENTS) { + obj_mgr_err("Component %d is out of range", id); + WLAN_OBJMGR_BUG(0); + return QDF_STATUS_MAXCOMP_FAIL; + } + qdf_spin_lock_bh(&g_umac_glb_obj->global_lock); + /* If there is an invalid entry, return failure */ + if (g_umac_glb_obj->vdev_peer_free_notify_handler[id] != handler) { + qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); + obj_mgr_err("Callback for Component %d is not registered", id); + return QDF_STATUS_E_FAILURE; + } + /* Reset handlers to NULL */ + g_umac_glb_obj->vdev_peer_free_notify_handler[id] = NULL; + + qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock); + + return QDF_STATUS_SUCCESS; +} QDF_STATUS wlan_objmgr_register_peer_create_handler( enum wlan_umac_comp_id id, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h index c42ca6ca911907052444b6ac8d0dc6a4bc12bc70..b9e24673a6878a757c0eb4f836e1bf38a4ce072b 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -44,6 +44,7 @@ struct wlan_objmgr_debug_info; * @vdev_create_handler_arg[]: VDEV create handler args array * @vdev_destroy_handler[]: VDEV destroy handler array * @vdev_destroy_handler_arg[]: VDEV destroy handler args array + * @vdev_peer_free_notify_handler[]: VDEV peer free notify handler array * @vdev_status_handler[]: VDEV status handler array * @vdev_status_handler_arg[]: VDEV status handler args array * @peer_create_handler[]: PEER create handler array @@ -81,6 +82,8 @@ struct wlan_objmgr_global { wlan_objmgr_vdev_destroy_handler vdev_destroy_handler[WLAN_UMAC_MAX_COMPONENTS]; void *vdev_destroy_handler_arg[WLAN_UMAC_MAX_COMPONENTS]; + wlan_objmgr_vdev_peer_free_notify_handler + vdev_peer_free_notify_handler[WLAN_UMAC_MAX_COMPONENTS]; wlan_objmgr_vdev_status_handler vdev_status_handler[WLAN_UMAC_MAX_COMPONENTS]; void *vdev_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS]; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c index d3494b0a6ef0f63fcbfdfb063c8dd77c88346fae..06311d9c1127f5ac6d3c62c19bf57d15312a309e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -172,7 +172,7 @@ struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create( return NULL; } - obj_mgr_info("Created pdev %d", pdev->pdev_objmgr.wlan_pdev_id); + obj_mgr_debug("Created pdev %d", pdev->pdev_objmgr.wlan_pdev_id); return pdev; } @@ -194,7 +194,8 @@ static QDF_STATUS wlan_objmgr_pdev_obj_destroy(struct wlan_objmgr_pdev *pdev) pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); - obj_mgr_info("Physically deleting pdev %d", pdev_id); + wlan_print_pdev_info(pdev); + obj_mgr_debug("Physically deleting pdev %d", pdev_id); if (pdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { obj_mgr_err("PDEV object delete is not invoked pdevid:%d objstate:%d", @@ -243,8 +244,8 @@ QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev) return QDF_STATUS_E_FAILURE; } - obj_mgr_info("Logically deleting pdev %d", - pdev->pdev_objmgr.wlan_pdev_id); + obj_mgr_debug("Logically deleting pdev %d", + pdev->pdev_objmgr.wlan_pdev_id); print_idx = qdf_get_pidx(); wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg, @@ -622,9 +623,198 @@ QDF_STATUS wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } -struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( +void *wlan_objmgr_pdev_get_comp_private_obj( + struct wlan_objmgr_pdev *pdev, + enum wlan_umac_comp_id id) +{ + void *comp_priv_obj; + + /* component id is invalid */ + if (id >= WLAN_UMAC_MAX_COMPONENTS) { + QDF_BUG(0); + return NULL; + } + + if (!pdev) { + QDF_BUG(0); + return NULL; + } + + comp_priv_obj = pdev->pdev_comp_priv_obj[id]; + + return comp_priv_obj; +} + +qdf_export_symbol(wlan_objmgr_pdev_get_comp_private_obj); + +void wlan_objmgr_pdev_get_ref(struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid id) +{ + if (!pdev) { + obj_mgr_err("pdev obj is NULL"); + QDF_ASSERT(0); + return; + } + qdf_atomic_inc(&pdev->pdev_objmgr.ref_cnt); + qdf_atomic_inc(&pdev->pdev_objmgr.ref_id_dbg[id]); +} + +qdf_export_symbol(wlan_objmgr_pdev_get_ref); + +QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid id) +{ + uint8_t pdev_id; + + if (!pdev) { + obj_mgr_err("pdev obj is NULL"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + + wlan_pdev_obj_lock(pdev); + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + if (pdev->obj_state != WLAN_OBJ_STATE_CREATED) { + wlan_pdev_obj_unlock(pdev); + if (pdev->pdev_objmgr.print_cnt++ <= + WLAN_OBJMGR_RATELIMIT_THRESH) + obj_mgr_err( + "[Ref id: %d] pdev [%d] is not in Created(st:%d)", + id, pdev_id, pdev->obj_state); + return QDF_STATUS_E_RESOURCES; + } + + wlan_objmgr_pdev_get_ref(pdev, id); + wlan_pdev_obj_unlock(pdev); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(wlan_objmgr_pdev_try_get_ref); + +void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid id) +{ + uint8_t pdev_id; + + if (!pdev) { + obj_mgr_err("pdev obj is NULL"); + QDF_ASSERT(0); + return; + } + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + + if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_id_dbg[id])) { + obj_mgr_err("pdev (id:%d)ref cnt was not taken by %d", + pdev_id, id); + wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg, + QDF_TRACE_LEVEL_FATAL); + WLAN_OBJMGR_BUG(0); + return; + } + + if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_cnt)) { + obj_mgr_err("pdev ref cnt is 0: pdev-id:%d", pdev_id); + WLAN_OBJMGR_BUG(0); + return; + } + + qdf_atomic_dec(&pdev->pdev_objmgr.ref_id_dbg[id]); + /* Decrement ref count, free pdev, if ref count == 0 */ + if (qdf_atomic_dec_and_test(&pdev->pdev_objmgr.ref_cnt)) + wlan_objmgr_pdev_obj_destroy(pdev); +} + +qdf_export_symbol(wlan_objmgr_pdev_release_ref); + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev_debug( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; + qdf_list_t *vdev_list = NULL; + struct wlan_objmgr_vdev *vdev; + qdf_list_node_t *node = NULL; + qdf_list_node_t *prev_node = NULL; + + wlan_pdev_obj_lock(pdev); + + /* VDEV list */ + vdev_list = &objmgr->wlan_vdev_list; + if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return NULL; + } + + do { + vdev = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref_debug(vdev, + dbg_id, func, line) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + + prev_node = node; + } while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS); + + wlan_pdev_obj_unlock(pdev); + + return NULL; +} + +qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev_debug); +#else +struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; + qdf_list_t *vdev_list = NULL; + struct wlan_objmgr_vdev *vdev; + qdf_list_node_t *node = NULL; + qdf_list_node_t *prev_node = NULL; + + wlan_pdev_obj_lock(pdev); + + /* VDEV list */ + vdev_list = &objmgr->wlan_vdev_list; + if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return NULL; + } + + do { + vdev = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + + prev_node = node; + } while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS); + + wlan_pdev_obj_unlock(pdev); + + return NULL; +} + +qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_debug( struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, - wlan_objmgr_ref_dbgid dbg_id) + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev_next; @@ -637,12 +827,15 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( vdev_list = &objmgr->wlan_vdev_list; /* Get first vdev */ vdev = wlan_pdev_vdev_list_peek_head(vdev_list); - /* Iterate through pdev's vdev list, till vdev id matches with - entry of vdev list */ + /** + * Iterate through pdev's vdev list, till vdev id matches with + * entry of vdev list + */ while (vdev) { if (wlan_vdev_get_id(vdev) == vdev_id) { - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != - QDF_STATUS_SUCCESS) + if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, + func, line) != + QDF_STATUS_SUCCESS) vdev = NULL; wlan_pdev_obj_unlock(pdev); @@ -655,9 +848,10 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( wlan_pdev_obj_unlock(pdev); return NULL; } -qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev); -struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_debug); +#else +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev( struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id) { @@ -678,9 +872,11 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( */ while (vdev) { if (wlan_vdev_get_id(vdev) == vdev_id) { - wlan_objmgr_vdev_get_ref(vdev, dbg_id); - wlan_pdev_obj_unlock(pdev); + if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != + QDF_STATUS_SUCCESS) + vdev = NULL; + wlan_pdev_obj_unlock(pdev); return vdev; } /* get next vdev */ @@ -688,14 +884,17 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( vdev = vdev_next; } wlan_pdev_obj_unlock(pdev); - return NULL; } -qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state); -struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( - struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug( + struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev_next; @@ -703,20 +902,21 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( qdf_list_t *vdev_list; wlan_pdev_obj_lock(pdev); + objmgr = &pdev->pdev_objmgr; vdev_list = &objmgr->wlan_vdev_list; /* Get first vdev */ vdev = wlan_pdev_vdev_list_peek_head(vdev_list); - /* Iterate through pdev's vdev list, till vdev macaddr matches with - entry of vdev list */ + /** + * Iterate through pdev's vdev list, till vdev id matches with + * entry of vdev list + */ while (vdev) { - if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) - == QDF_STATUS_SUCCESS) { - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != - QDF_STATUS_SUCCESS) - vdev = NULL; - + if (wlan_vdev_get_id(vdev) == vdev_id) { + wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id, + func, line); wlan_pdev_obj_unlock(pdev); + return vdev; } /* get next vdev */ @@ -728,9 +928,11 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( return NULL; } -struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state( - struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug); +#else +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state( + struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev_next; @@ -738,15 +940,17 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state( qdf_list_t *vdev_list; wlan_pdev_obj_lock(pdev); + objmgr = &pdev->pdev_objmgr; vdev_list = &objmgr->wlan_vdev_list; /* Get first vdev */ vdev = wlan_pdev_vdev_list_peek_head(vdev_list); - /* Iterate through pdev's vdev list, till vdev macaddr matches with - entry of vdev list */ + /** + * Iterate through pdev's vdev list, till vdev id matches with + * entry of vdev list + */ while (vdev) { - if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) - == QDF_STATUS_SUCCESS) { + if (wlan_vdev_get_id(vdev) == vdev_id) { wlan_objmgr_vdev_get_ref(vdev, dbg_id); wlan_pdev_obj_unlock(pdev); @@ -761,146 +965,196 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state( return NULL; } -void *wlan_objmgr_pdev_get_comp_private_obj( - struct wlan_objmgr_pdev *pdev, - enum wlan_umac_comp_id id) -{ - void *comp_priv_obj; - - /* component id is invalid */ - if (id >= WLAN_UMAC_MAX_COMPONENTS) { - QDF_BUG(0); - return NULL; - } - - if (!pdev) { - QDF_BUG(0); - return NULL; - } - - comp_priv_obj = pdev->pdev_comp_priv_obj[id]; - - return comp_priv_obj; -} -qdf_export_symbol(wlan_objmgr_pdev_get_comp_private_obj); +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state); +#endif -void wlan_objmgr_pdev_get_ref(struct wlan_objmgr_pdev *pdev, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *fnc, int ln) { - if (!pdev) { - obj_mgr_err("pdev obj is NULL"); - QDF_ASSERT(0); - return; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_vdev *vdev_next; + struct wlan_objmgr_pdev_objmgr *objmgr; + qdf_list_t *vdev_list; + + wlan_pdev_obj_lock(pdev); + objmgr = &pdev->pdev_objmgr; + vdev_list = &objmgr->wlan_vdev_list; + /* Get first vdev */ + vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + /** + * Iterate through pdev's vdev list, till vdev macaddr matches with + * entry of vdev list + */ + while (vdev) { + if (QDF_IS_STATUS_SUCCESS( + WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) { + if (QDF_IS_STATUS_SUCCESS( + wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, + fnc, ln))) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + } + /* get next vdev */ + vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev); + vdev = vdev_next; } - qdf_atomic_inc(&pdev->pdev_objmgr.ref_cnt); - qdf_atomic_inc(&pdev->pdev_objmgr.ref_id_dbg[id]); + wlan_pdev_obj_unlock(pdev); - return; + return NULL; } -qdf_export_symbol(wlan_objmgr_pdev_get_ref); - -QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev, - wlan_objmgr_ref_dbgid id) +#else +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id) { - uint8_t pdev_id; - - if (!pdev) { - obj_mgr_err("pdev obj is NULL"); - QDF_ASSERT(0); - return QDF_STATUS_E_FAILURE; - } + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_vdev *vdev_next; + struct wlan_objmgr_pdev_objmgr *objmgr; + qdf_list_t *vdev_list; wlan_pdev_obj_lock(pdev); - pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); - if (pdev->obj_state != WLAN_OBJ_STATE_CREATED) { - wlan_pdev_obj_unlock(pdev); - if (pdev->pdev_objmgr.print_cnt++ <= - WLAN_OBJMGR_RATELIMIT_THRESH) - obj_mgr_err( - "[Ref id: %d] pdev [%d] is not in Created(st:%d)", - id, pdev_id, pdev->obj_state); - return QDF_STATUS_E_RESOURCES; + objmgr = &pdev->pdev_objmgr; + vdev_list = &objmgr->wlan_vdev_list; + /* Get first vdev */ + vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + /** + * Iterate through pdev's vdev list, till vdev macaddr matches with + * entry of vdev list + */ + while (vdev) { + if (QDF_IS_STATUS_SUCCESS( + WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) { + if (QDF_IS_STATUS_SUCCESS( + wlan_objmgr_vdev_try_get_ref(vdev, dbg_id))) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + } + /* get next vdev */ + vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev); + vdev = vdev_next; } - - wlan_objmgr_pdev_get_ref(pdev, id); wlan_pdev_obj_unlock(pdev); - return QDF_STATUS_SUCCESS; + return NULL; } -qdf_export_symbol(wlan_objmgr_pdev_try_get_ref); +#endif -void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev + *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { - uint8_t pdev_id; - - if (!pdev) { - obj_mgr_err("pdev obj is NULL"); - QDF_ASSERT(0); - return; - } - - pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_vdev *vdev_next; + struct wlan_objmgr_pdev_objmgr *objmgr; + qdf_list_t *vdev_list; - if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_id_dbg[id])) { - obj_mgr_err("pdev (id:%d)ref cnt was not taken by %d", - pdev_id, id); - wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg, - QDF_TRACE_LEVEL_FATAL); - WLAN_OBJMGR_BUG(0); - return; - } + wlan_pdev_obj_lock(pdev); + objmgr = &pdev->pdev_objmgr; + vdev_list = &objmgr->wlan_vdev_list; + /* Get first vdev */ + vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + /** + * Iterate through pdev's vdev list, till vdev macaddr matches with + * entry of vdev list + */ + while (vdev) { + if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) + == QDF_STATUS_SUCCESS) { + wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id, + func, line); + wlan_pdev_obj_unlock(pdev); - if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_cnt)) { - obj_mgr_err("pdev ref cnt is 0: pdev-id:%d", pdev_id); - WLAN_OBJMGR_BUG(0); - return; + return vdev; + } + /* get next vdev */ + vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev); + vdev = vdev_next; } + wlan_pdev_obj_unlock(pdev); - qdf_atomic_dec(&pdev->pdev_objmgr.ref_id_dbg[id]); - /* Decrement ref count, free pdev, if ref count == 0 */ - if (qdf_atomic_dec_and_test(&pdev->pdev_objmgr.ref_cnt)) - wlan_objmgr_pdev_obj_destroy(pdev); - - return; + return NULL; } -qdf_export_symbol(wlan_objmgr_pdev_release_ref); - -struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev( - struct wlan_objmgr_pdev *pdev, +#else +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state( + struct wlan_objmgr_pdev *pdev, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) { - struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; - qdf_list_t *vdev_list = NULL; struct wlan_objmgr_vdev *vdev; - qdf_list_node_t *node = NULL; - qdf_list_node_t *prev_node = NULL; + struct wlan_objmgr_vdev *vdev_next; + struct wlan_objmgr_pdev_objmgr *objmgr; + qdf_list_t *vdev_list; wlan_pdev_obj_lock(pdev); - - /* VDEV list */ + objmgr = &pdev->pdev_objmgr; vdev_list = &objmgr->wlan_vdev_list; - if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { - wlan_pdev_obj_unlock(pdev); - return NULL; - } - - do { - vdev = qdf_container_of(node, struct wlan_objmgr_vdev, - vdev_node); - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == - QDF_STATUS_SUCCESS) { + /* Get first vdev */ + vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + /** + * Iterate through pdev's vdev list, till vdev macaddr matches with + * entry of vdev list + */ + while (vdev) { + if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) + == QDF_STATUS_SUCCESS) { + wlan_objmgr_vdev_get_ref(vdev, dbg_id); wlan_pdev_obj_unlock(pdev); + return vdev; } - - prev_node = node; - } while (qdf_list_peek_next(vdev_list, prev_node, &node) == - QDF_STATUS_SUCCESS); - + /* get next vdev */ + vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev); + vdev = vdev_next; + } wlan_pdev_obj_unlock(pdev); return NULL; } +#endif -qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev); +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_pdev_info(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_pdev_objmgr *pdev_objmgr; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_vdev *vdev_next; + qdf_list_t *vdev_list; + uint16_t index = 0; + + pdev_objmgr = &pdev->pdev_objmgr; + + obj_mgr_debug("pdev: %pK", pdev); + obj_mgr_debug("wlan_pdev_id: %d", pdev_objmgr->wlan_pdev_id); + obj_mgr_debug("wlan_vdev_count: %d", pdev_objmgr->wlan_vdev_count); + obj_mgr_debug("max_vdev_count: %d", pdev_objmgr->max_vdev_count); + obj_mgr_debug("wlan_peer_count: %d", pdev_objmgr->wlan_peer_count); + obj_mgr_debug("max_peer_count: %d", pdev_objmgr->max_peer_count); + obj_mgr_debug("temp_peer_count: %d", pdev_objmgr->temp_peer_count); + obj_mgr_debug("wlan_psoc: %pK", pdev_objmgr->wlan_psoc); + obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&pdev_objmgr->ref_cnt)); + + wlan_pdev_obj_lock(pdev); + vdev_list = &pdev_objmgr->wlan_vdev_list; + /* Get first vdev */ + vdev = wlan_pdev_vdev_list_peek_head(vdev_list); + + while (vdev) { + obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev); + wlan_print_vdev_info(vdev); + index++; + /* get next vdev */ + vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev); + vdev = vdev_next; + } + wlan_pdev_obj_unlock(pdev); +} + +qdf_export_symbol(wlan_print_pdev_info); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c index 33e3baa93de45a78d76cac1a1f6f4e7cc8e5415a..c99f3ac372f32d97219c1ce649f9477a722a08ee 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c @@ -84,9 +84,8 @@ static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) vdev = wlan_peer_get_vdev(peer); if (!vdev) { obj_mgr_err( - "VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "VDEV is NULL for peer("QDF_MAC_ADDR_FMT")", + QDF_MAC_ADDR_REF(macaddr)); return QDF_STATUS_E_FAILURE; } @@ -96,9 +95,8 @@ static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { obj_mgr_err( - "PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "PSOC is NULL for peer("QDF_MAC_ADDR_FMT")", + QDF_MAC_ADDR_REF(macaddr)); return QDF_STATUS_E_FAILURE; } @@ -109,25 +107,32 @@ static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev), WLAN_OBJMGR_ID); + wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); + /* Detach peer from VDEV's peer list */ if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) { obj_mgr_err( - "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5], vdev_id); + "Peer("QDF_MAC_ADDR_FMT") VDEV detach fail, vdev id: %d", + QDF_MAC_ADDR_REF(macaddr), vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); return QDF_STATUS_E_FAILURE; } /* Detach peer from PSOC's peer list */ if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) { obj_mgr_err( - "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "Peer("QDF_MAC_ADDR_FMT") PSOC detach failure", + QDF_MAC_ADDR_REF(macaddr)); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); return QDF_STATUS_E_FAILURE; } + wlan_objmgr_peer_trace_del_ref_list(peer); + wlan_objmgr_peer_trace_deinit_lock(peer); qdf_spinlock_destroy(&peer->peer_lock); qdf_mem_free(peer); + wlan_objmgr_vdev_peer_freed_notify(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); + return QDF_STATUS_SUCCESS; } @@ -161,18 +166,16 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( if (!vdev) { obj_mgr_err( - "VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "VDEV is NULL for peer ("QDF_MAC_ADDR_FMT")", + QDF_MAC_ADDR_REF(macaddr)); return NULL; } /* Get psoc, if psoc is NULL, return */ psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { obj_mgr_err( - "PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "PSOC is NULL for peer ("QDF_MAC_ADDR_FMT")", + QDF_MAC_ADDR_REF(macaddr)); return NULL; } /* Allocate memory for peer object */ @@ -196,14 +199,15 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( peer->peer_objmgr.print_cnt = 0; qdf_spinlock_create(&peer->peer_lock); + wlan_objmgr_peer_trace_init_lock(peer); /* Attach peer to psoc, psoc maintains the node table for the device */ if (wlan_objmgr_psoc_peer_attach(psoc, peer) != QDF_STATUS_SUCCESS) { obj_mgr_warn( - "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "Peer("QDF_MAC_ADDR_FMT") PSOC attach failure", + QDF_MAC_ADDR_REF(macaddr)); qdf_spinlock_destroy(&peer->peer_lock); + wlan_objmgr_peer_trace_deinit_lock(peer); qdf_mem_free(peer); return NULL; } @@ -211,12 +215,12 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( if (wlan_objmgr_vdev_peer_attach(vdev, peer) != QDF_STATUS_SUCCESS) { obj_mgr_warn( - "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "Peer("QDF_MAC_ADDR_FMT") VDEV attach failure", + QDF_MAC_ADDR_REF(macaddr)); /* if attach fails, detach from psoc table before free */ wlan_objmgr_psoc_peer_detach(psoc, peer); qdf_spinlock_destroy(&peer->peer_lock); + wlan_objmgr_peer_trace_deinit_lock(peer); qdf_mem_free(peer); return NULL; } @@ -256,15 +260,14 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( } else if (obj_status == QDF_STATUS_E_FAILURE) { /* Clean up the peer */ obj_mgr_err( - "Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + "Peer("QDF_MAC_ADDR_FMT") comp object alloc fail", + QDF_MAC_ADDR_REF(macaddr)); wlan_objmgr_peer_obj_delete(peer); return NULL; } - obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR " type %d", - QDF_MAC_ADDR_ARRAY(macaddr), type); + obj_mgr_debug("Created peer " QDF_MAC_ADDR_FMT " type %d", + QDF_MAC_ADDR_REF(macaddr), type); return peer; } @@ -285,13 +288,13 @@ static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer) macaddr = wlan_peer_get_macaddr(peer); - obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(macaddr)); + obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(macaddr)); if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { obj_mgr_err("PEER object del is not invoked obj_state:%d peer " - QDF_MAC_ADDR_STR, peer->obj_state, - QDF_MAC_ADDR_ARRAY(macaddr)); + QDF_MAC_ADDR_FMT, peer->obj_state, + QDF_MAC_ADDR_REF(macaddr)); WLAN_OBJMGR_BUG(0); } @@ -337,8 +340,8 @@ QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer) macaddr = wlan_peer_get_macaddr(peer); wlan_peer_obj_unlock(peer); - obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(macaddr)); + obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(macaddr)); print_idx = qdf_get_pidx(); wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_DEBUG); @@ -597,8 +600,69 @@ wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer, wlan_objmgr_ref_dbgid id) {} #endif -void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_DEBUG +static QDF_STATUS +wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id) +{ + if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) { + uint8_t *macaddr; + + macaddr = wlan_peer_get_macaddr(peer); + obj_mgr_err( + "peer("QDF_MAC_ADDR_FMT") ref was not taken by %d", + QDF_MAC_ADDR_REF(macaddr), id); + wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, + QDF_TRACE_LEVEL_FATAL); + WLAN_OBJMGR_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]); + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS +wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static inline void +wlan_objmgr_peer_ref_trace(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + struct wlan_objmgr_trace *trace; + + trace = &peer->peer_objmgr.trace; + + if (func) + wlan_objmgr_trace_ref(&trace->references[id].head, + trace, func, line); +} + +static inline void +wlan_objmgr_peer_deref_trace(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + struct wlan_objmgr_trace *trace; + + trace = &peer->peer_objmgr.trace; + if (func) + wlan_objmgr_trace_ref(&trace->dereferences[id].head, + trace, func, line); +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_peer_get_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line) { if (!peer) { obj_mgr_err("peer obj is NULL for %d", id); @@ -609,12 +673,65 @@ void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, qdf_atomic_inc(&peer->peer_objmgr.ref_cnt); wlan_objmgr_peer_get_debug_id_ref(peer, id); + wlan_objmgr_peer_ref_trace(peer, id, func, line); return; } + +qdf_export_symbol(wlan_objmgr_peer_get_ref_debug); +#else +void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id) +{ + if (!peer) { + obj_mgr_err("peer obj is NULL for %d", id); + QDF_ASSERT(0); + return; + } + /* Increment ref count */ + qdf_atomic_inc(&peer->peer_objmgr.ref_cnt); + wlan_objmgr_peer_get_debug_id_ref(peer, id); +} + qdf_export_symbol(wlan_objmgr_peer_get_ref); +#endif +#ifdef WLAN_OBJMGR_REF_ID_TRACE +QDF_STATUS wlan_objmgr_peer_try_get_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + if (!peer) { + obj_mgr_err("peer obj is NULL for %d", id); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + + wlan_peer_obj_lock(peer); + if (peer->obj_state != WLAN_OBJ_STATE_CREATED) { + wlan_peer_obj_unlock(peer); + if (peer->peer_objmgr.print_cnt++ <= + WLAN_OBJMGR_RATELIMIT_THRESH) { + uint8_t *macaddr; + + macaddr = wlan_peer_get_macaddr(peer); + obj_mgr_debug( + "peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)", + QDF_MAC_ADDR_REF(macaddr), + peer->obj_state); + } + return QDF_STATUS_E_RESOURCES; + } + + wlan_objmgr_peer_get_ref_debug(peer, id, func, line); + wlan_peer_obj_unlock(peer); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(wlan_objmgr_peer_try_get_ref_debug); +#else QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid id) + wlan_objmgr_ref_dbgid id) { if (!peer) { obj_mgr_err("peer obj is NULL for %d", id); @@ -631,8 +748,8 @@ QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, macaddr = wlan_peer_get_macaddr(peer); obj_mgr_debug( - "peer(" QDF_MAC_ADDR_STR ") not in Created st(%d)", - QDF_MAC_ADDR_ARRAY(macaddr), + "peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)", + QDF_MAC_ADDR_REF(macaddr), peer->obj_state); } return QDF_STATUS_E_RESOURCES; @@ -643,81 +760,120 @@ QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, return QDF_STATUS_SUCCESS; } + qdf_export_symbol(wlan_objmgr_peer_try_get_ref); +#endif -#ifdef WLAN_OBJMGR_REF_ID_DEBUG -static QDF_STATUS -wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { - if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) { - uint8_t *macaddr; + struct wlan_objmgr_peer *peer_next = NULL; + qdf_list_node_t *psoc_node = NULL; + qdf_list_node_t *prev_psoc_node = NULL; + qdf_list_t *obj_list; - macaddr = wlan_peer_get_macaddr(peer); - obj_mgr_err( - "peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5], id); - wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, - QDF_TRACE_LEVEL_FATAL); - WLAN_OBJMGR_BUG(0); - return QDF_STATUS_E_FAILURE; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + prev_psoc_node = &peer->psoc_peer; + while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == + QDF_STATUS_SUCCESS) { + peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, + psoc_peer); + + if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return peer_next; + } + + prev_psoc_node = psoc_node; } - qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]); - return QDF_STATUS_SUCCESS; + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return NULL; } #else -static QDF_STATUS -wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid id) +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id) { - return QDF_STATUS_SUCCESS; + struct wlan_objmgr_peer *peer_next = NULL; + qdf_list_node_t *psoc_node = NULL; + qdf_list_node_t *prev_psoc_node = NULL; + qdf_list_t *obj_list; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + prev_psoc_node = &peer->psoc_peer; + while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == + QDF_STATUS_SUCCESS) { + peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, + psoc_peer); + + if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == + QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return peer_next; + } + + prev_psoc_node = psoc_node; + } + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return NULL; } #endif -void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head_debug( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { - QDF_STATUS status; + struct wlan_objmgr_peer *peer; + qdf_list_node_t *vdev_node = NULL; + qdf_list_node_t *prev_vdev_node = NULL; - if (!peer) { - obj_mgr_err("peer obj is NULL for %d", id); - QDF_ASSERT(0); - return; + wlan_vdev_obj_lock(vdev); + + if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return NULL; } - if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { - uint8_t *macaddr; + do { + peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, + vdev_peer); - macaddr = wlan_peer_get_macaddr(peer); - obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); - WLAN_OBJMGR_BUG(0); - return; - } + if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return peer; + } - status = wlan_objmgr_peer_release_debug_id_ref(peer, id); - if (QDF_IS_STATUS_ERROR(status)) - return; + prev_vdev_node = vdev_node; + } while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == + QDF_STATUS_SUCCESS); - /* Provide synchronization from the access to add peer - * to logically deleted peer list. - */ - wlan_peer_obj_lock(peer); - /* Decrement ref count, free peer object, if ref count == 0 */ - if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { - wlan_peer_obj_unlock(peer); - wlan_objmgr_peer_obj_destroy(peer); - } else { - wlan_peer_obj_unlock(peer); - } + wlan_vdev_obj_unlock(vdev); - return; + return NULL; } -qdf_export_symbol(wlan_objmgr_peer_release_ref); - +#else struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( struct wlan_objmgr_vdev *vdev, qdf_list_t *peer_list, @@ -752,7 +908,46 @@ struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( return NULL; } +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev_debug( + struct wlan_objmgr_vdev *vdev, + qdf_list_t *peer_list, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer_next; + qdf_list_node_t *vdev_node = NULL; + qdf_list_node_t *prev_vdev_node = NULL; + + if (!peer) + return NULL; + wlan_vdev_obj_lock(vdev); + + prev_vdev_node = &peer->vdev_peer; + while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == + QDF_STATUS_SUCCESS) { + peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer, + vdev_peer); + + if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { + wlan_vdev_obj_unlock(vdev); + return peer_next; + } + + prev_vdev_node = vdev_node; + } + + wlan_vdev_obj_unlock(vdev); + + return NULL; +} +#else struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( struct wlan_objmgr_vdev *vdev, qdf_list_t *peer_list, @@ -787,14 +982,16 @@ struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( return NULL; } +#endif -struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head_debug( struct wlan_peer_list *peer_list, uint8_t hash_index, - struct wlan_objmgr_peer *peer, - wlan_objmgr_ref_dbgid dbg_id) + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { - struct wlan_objmgr_peer *peer_next = NULL; + struct wlan_objmgr_peer *peer; qdf_list_node_t *psoc_node = NULL; qdf_list_node_t *prev_psoc_node = NULL; qdf_list_t *obj_list; @@ -802,26 +999,29 @@ struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( qdf_spin_lock_bh(&peer_list->peer_list_lock); obj_list = &peer_list->peer_hash[hash_index]; - prev_psoc_node = &peer->psoc_peer; - while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == - QDF_STATUS_SUCCESS) { - peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, - psoc_peer); + if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + return NULL; + } - if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == + do { + peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, + psoc_peer); + if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, + func, line) == QDF_STATUS_SUCCESS) { qdf_spin_unlock_bh(&peer_list->peer_list_lock); - return peer_next; + return peer; } prev_psoc_node = psoc_node; - } + } while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == + QDF_STATUS_SUCCESS); qdf_spin_unlock_bh(&peer_list->peer_list_lock); - return NULL; } - +#else struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( struct wlan_peer_list *peer_list, uint8_t hash_index, @@ -856,7 +1056,35 @@ struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( qdf_spin_unlock_bh(&peer_list->peer_list_lock); return NULL; } +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref_debug( + struct wlan_peer_list *peer_list, + uint8_t hash_index, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer; + qdf_list_t *obj_list; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + peer = wlan_psoc_peer_list_peek_head(obj_list); + /* This API is invoked by caller, only when caller need to access the + * peer object, though object is not in active state, this API should be + * used carefully, where multiple object frees are not triggered + */ + if (peer) + wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, line); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return peer; +} +#else struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( struct wlan_peer_list *peer_list, uint8_t hash_index, @@ -870,8 +1098,7 @@ struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( peer = wlan_psoc_peer_list_peek_head(obj_list); - /** - * This API is invoked by caller, only when caller need to access the + /* This API is invoked by caller, only when caller need to access the * peer object, though object is not in active state, this API should be * used carefully, where multiple object frees are not triggered */ @@ -882,7 +1109,34 @@ struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( return peer; } +#endif +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref_debug( + struct wlan_peer_list *peer_list, uint8_t hash_index, + struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + qdf_list_t *obj_list; + struct wlan_objmgr_peer *peer_next; + + qdf_spin_lock_bh(&peer_list->peer_list_lock); + obj_list = &peer_list->peer_hash[hash_index]; + + peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer); + /* This API is invoked by caller, only when caller need to access the + * peer object, though object is not in active state, this API should be + * used carefully, where multiple free on object are not triggered + */ + if (peer_next) + wlan_objmgr_peer_get_ref_debug(peer_next, dbg_id, func, line); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + + return peer_next; +} +#else struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( struct wlan_peer_list *peer_list, uint8_t hash_index, struct wlan_objmgr_peer *peer, @@ -895,8 +1149,7 @@ struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( obj_list = &peer_list->peer_hash[hash_index]; peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer); - /** - * This API is invoked by caller, only when caller need to access the + /* This API is invoked by caller, only when caller need to access the * peer object, though object is not in active state, this API should be * used carefully, where multiple free on object are not triggered */ @@ -907,6 +1160,93 @@ struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( return peer_next; } +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_peer_release_ref_debug(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + QDF_STATUS status; + + if (!peer) { + obj_mgr_err("peer obj is NULL for %d", id); + QDF_ASSERT(0); + return; + } + + if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { + uint8_t *macaddr; + + macaddr = wlan_peer_get_macaddr(peer); + obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0", + QDF_MAC_ADDR_REF(macaddr)); + WLAN_OBJMGR_BUG(0); + return; + } + + status = wlan_objmgr_peer_release_debug_id_ref(peer, id); + if (QDF_IS_STATUS_ERROR(status)) + return; + + wlan_objmgr_peer_deref_trace(peer, id, func, line); + /* Provide synchronization from the access to add peer + * to logically deleted peer list. + */ + wlan_peer_obj_lock(peer); + /* Decrement ref count, free peer object, if ref count == 0 */ + if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_obj_destroy(peer); + } else { + wlan_peer_obj_unlock(peer); + } + + return; +} + +qdf_export_symbol(wlan_objmgr_peer_release_ref_debug); +#else +void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, + wlan_objmgr_ref_dbgid id) +{ + QDF_STATUS status; + + if (!peer) { + obj_mgr_err("peer obj is NULL for %d", id); + QDF_ASSERT(0); + return; + } + + if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { + uint8_t *macaddr; + + macaddr = wlan_peer_get_macaddr(peer); + obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0", + QDF_MAC_ADDR_REF(macaddr)); + WLAN_OBJMGR_BUG(0); + return; + } + + status = wlan_objmgr_peer_release_debug_id_ref(peer, id); + if (QDF_IS_STATUS_ERROR(status)) + return; + + /* Provide synchronization from the access to add peer + * to logically deleted peer list. + */ + wlan_peer_obj_lock(peer); + /* Decrement ref count, free peer object, if ref count == 0 */ + if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_obj_destroy(peer); + } else { + wlan_peer_obj_unlock(peer); + } +} + +qdf_export_symbol(wlan_objmgr_peer_release_ref); +#endif #ifdef WLAN_OBJMGR_REF_ID_DEBUG void diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c index 4a5e2593f6c08c38f8cfe6bb47cbaaea9fb5f397..d5d2ce5d12fd39325122af4e181fc267f4683a5e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -202,6 +202,7 @@ static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc) } wlan_objmgr_notify_destroy(psoc, WLAN_PSOC_OP); + wlan_print_psoc_info(psoc); obj_mgr_info("Physically deleting psoc %d", psoc->soc_objmgr.psoc_id); if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { @@ -941,45 +942,37 @@ QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( - struct wlan_objmgr_psoc *psoc, - enum QDF_OPMODE opmode, - wlan_objmgr_ref_dbgid dbg_id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { - struct wlan_objmgr_vdev *vdev = NULL; - int vdev_cnt = 0; - uint16_t max_vdev_cnt; + struct wlan_objmgr_vdev *vdev; /* if PSOC is NULL, return */ if (!psoc) return NULL; + /* vdev id is invalid */ + if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) + return NULL; wlan_psoc_obj_lock(psoc); - - max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); /* retrieve vdev pointer from vdev list */ - while (vdev_cnt < max_vdev_cnt) { - vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; - vdev_cnt++; - if (!vdev) - continue; - wlan_vdev_obj_lock(vdev); - if (vdev->vdev_mlme.vdev_opmode == opmode) { - wlan_vdev_obj_unlock(vdev); - if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != - QDF_STATUS_SUCCESS) { - vdev = NULL; - continue; - } - break; - } - wlan_vdev_obj_unlock(vdev); + vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; + if (vdev) { + if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, + func, line) != + QDF_STATUS_SUCCESS) + vdev = NULL; } wlan_psoc_obj_unlock(psoc); return vdev; } +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_debug); +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id) @@ -1005,8 +998,38 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( return vdev; } + qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev; + + /* if PSOC is NULL, return */ + if (!psoc) + return NULL; + /* vdev id is invalid */ + if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) + return NULL; + + wlan_psoc_obj_lock(psoc); + /* retrieve vdev pointer from vdev list */ + vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; + if (vdev) + wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id, func, line); + + wlan_psoc_obj_unlock(psoc); + + return vdev; +} +qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug); +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, wlan_objmgr_ref_dbgid dbg_id) @@ -1030,8 +1053,123 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( return vdev; } + qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE opmode, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev = NULL; + int vdev_cnt = 0; + uint16_t max_vdev_cnt; + + /* if PSOC is NULL, return */ + if (!psoc) + return NULL; + + wlan_psoc_obj_lock(psoc); + + max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); + /* retrieve vdev pointer from vdev list */ + while (vdev_cnt < max_vdev_cnt) { + vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; + vdev_cnt++; + if (!vdev) + continue; + wlan_vdev_obj_lock(vdev); + if (vdev->vdev_mlme.vdev_opmode == opmode) { + wlan_vdev_obj_unlock(vdev); + if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, + func, line) != + QDF_STATUS_SUCCESS) { + vdev = NULL; + continue; + } + break; + } + wlan_vdev_obj_unlock(vdev); + } + wlan_psoc_obj_unlock(psoc); + + return vdev; +} +#else +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( + struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE opmode, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_vdev *vdev = NULL; + int vdev_cnt = 0; + uint16_t max_vdev_cnt; + + /* if PSOC is NULL, return */ + if (!psoc) + return NULL; + + wlan_psoc_obj_lock(psoc); + + max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); + /* retrieve vdev pointer from vdev list */ + while (vdev_cnt < max_vdev_cnt) { + vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; + vdev_cnt++; + if (!vdev) + continue; + wlan_vdev_obj_lock(vdev); + if (vdev->vdev_mlme.vdev_opmode == opmode) { + wlan_vdev_obj_unlock(vdev); + if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != + QDF_STATUS_SUCCESS) { + vdev = NULL; + continue; + } + break; + } + wlan_vdev_obj_unlock(vdev); + } + wlan_psoc_obj_unlock(psoc); + + return vdev; +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_pdev *pdev; + + /* if PSOC is NULL, return */ + if (!psoc) + return NULL; + + if (!macaddr) + return NULL; + + pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); + if (!pdev) { + obj_mgr_err("pdev is null"); + return NULL; + } + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(pdev, macaddr, + dbg_id, + func, line); + wlan_objmgr_pdev_release_ref(pdev, dbg_id); + + return vdev; +} +qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug); +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) @@ -1056,8 +1194,44 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( return vdev; } + qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev + *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_pdev *pdev; + + /* if PSOC is NULL, return */ + if (!psoc) + return NULL; + + if (!macaddr) + return NULL; + + pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); + if (!pdev) { + obj_mgr_err("pdev is null"); + return NULL; + } + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(pdev, + macaddr, + dbg_id, + func, + line); + wlan_objmgr_pdev_release_ref(pdev, dbg_id); + return vdev; +} + +qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug); +#else struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) @@ -1082,7 +1256,9 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( return vdev; } + qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state); +#endif static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list, struct wlan_objmgr_peer *obj) @@ -1120,20 +1296,23 @@ static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer, } /** - * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer - * from psoc peer list + * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from + * psoc peer list * @psoc: PSOC object * @macaddr: MAC address + * #pdev_id: Pdev id * - * API to finds peer object pointer of logically deleted peer + * API to finds peer object pointer by MAC addr and pdev id from hash list * * Return: peer pointer * NULL on FAILURE */ -static struct wlan_objmgr_peer * - wlan_obj_psoc_peerlist_get_peer_logically_deleted( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer + *wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( qdf_list_t *obj_list, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) + uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; @@ -1142,16 +1321,14 @@ static struct wlan_objmgr_peer * peer = wlan_psoc_peer_list_peek_head(obj_list); while (peer) { /* For peer, macaddr is key */ - if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) - == QDF_STATUS_SUCCESS) { - /* Return peer in logically deleted state */ - if (peer->obj_state == - WLAN_OBJ_STATE_LOGICALLY_DELETED) { - wlan_objmgr_peer_get_ref(peer, dbg_id); - + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { return peer; } - } /* Move to next peer */ peer_temp = peer; @@ -1161,20 +1338,10 @@ static struct wlan_objmgr_peer * /* Not found, return NULL */ return NULL; } - -/** - * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list - * @psoc: PSOC object - * @macaddr: MAC address - * - * API to finds peer object pointer by MAC addr from hash list - * - * Return: peer pointer - * NULL on FAILURE - */ -static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( - qdf_list_t *obj_list, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) +#else +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; @@ -1183,10 +1350,11 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( peer = wlan_psoc_peer_list_peek_head(obj_list); while (peer) { /* For peer, macaddr is key */ - if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) - == QDF_STATUS_SUCCESS) { + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == - QDF_STATUS_SUCCESS) { + QDF_STATUS_SUCCESS) { return peer; } } @@ -1198,21 +1366,23 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( /* Not found, return NULL */ return NULL; } +#endif /** - * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from psoc peer list + * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list * @psoc: PSOC object * @macaddr: MAC address - * #pdev_id: Pdev id * - * API to finds peer object pointer by MAC addr and pdev id from hash list + * API to finds peer object pointer by MAC addr from hash list * * Return: peer pointer * NULL on FAILURE */ -static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( - qdf_list_t *obj_list, uint8_t *macaddr, - uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_debug( + qdf_list_t *obj_list, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; @@ -1221,11 +1391,11 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( peer = wlan_psoc_peer_list_peek_head(obj_list); while (peer) { /* For peer, macaddr is key */ - if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) - == QDF_STATUS_SUCCESS) && - (wlan_peer_get_pdev_id(peer) == pdev_id)) { - if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == - QDF_STATUS_SUCCESS) { + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { + if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { return peer; } } @@ -1237,10 +1407,10 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( /* Not found, return NULL */ return NULL; } - -static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( - qdf_list_t *obj_list, uint8_t *macaddr, - uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) +#else +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( + qdf_list_t *obj_list, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; @@ -1248,13 +1418,13 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( /* Iterate through hash list to get the peer */ peer = wlan_psoc_peer_list_peek_head(obj_list); while (peer) { - /* For peer, macaddr and pdev_id is key */ - if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) - == QDF_STATUS_SUCCESS) && - (wlan_peer_get_pdev_id(peer) == pdev_id)) { - wlan_objmgr_peer_get_ref(peer, dbg_id); - - return peer; + /* For peer, macaddr is key */ + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { + if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == + QDF_STATUS_SUCCESS) { + return peer; + } } /* Move to next peer */ peer_temp = peer; @@ -1264,110 +1434,169 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( /* Not found, return NULL */ return NULL; } +#endif /** - * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - get peer - * from psoc peer list using - * mac and vdev self mac - * @obj_list: peer object list + * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer + * from psoc peer list + * @psoc: PSOC object * @macaddr: MAC address - * @bssid: BSSID address - * @dbg_id: id of the caller - * - * API to finds peer object pointer by MAC addr and BSSID from - * peer hash list for a node which is in logically deleted state, - * bssid check is done on matching peer * - * Caller to free the list allocated in this function + * API to finds peer object pointer of logically deleted peer * - * Return: list of peer pointers + * Return: peer pointer * NULL on FAILURE */ -static qdf_list_t - *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer * + wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( + qdf_list_t *obj_list, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; + + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + /* For peer, macaddr is key */ + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { + /* Return peer in logically deleted state */ + if (peer->obj_state == + WLAN_OBJ_STATE_LOGICALLY_DELETED) { + wlan_objmgr_peer_get_ref_debug(peer, dbg_id, + func, line); + + return peer; + } + + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } + + /* Not found, return NULL */ + return NULL; +} +#else +static struct wlan_objmgr_peer * + wlan_obj_psoc_peerlist_get_peer_logically_deleted( qdf_list_t *obj_list, uint8_t *macaddr, - uint8_t *bssid, uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; - struct wlan_logically_del_peer *peer_list = NULL; - qdf_list_t *logical_del_peer_list = NULL; - bool lock_released = false; - logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); - if (!logical_del_peer_list) - return NULL; + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + /* For peer, macaddr is key */ + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { + /* Return peer in logically deleted state */ + if (peer->obj_state == + WLAN_OBJ_STATE_LOGICALLY_DELETED) { + wlan_objmgr_peer_get_ref(peer, dbg_id); - qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); + return peer; + } + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } + + /* Not found, return NULL */ + return NULL; +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer + *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t *bssid, + uint8_t pdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; /* Iterate through hash list to get the peer */ peer = wlan_psoc_peer_list_peek_head(obj_list); while (peer) { - wlan_peer_obj_lock(peer); - /* For peer, macaddr and pdev id are keys */ - if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) - == QDF_STATUS_SUCCESS) && - (wlan_peer_get_pdev_id(peer) == pdev_id)) { + /* For peer, macaddr is key */ + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { /* - * if BSSID not NULL, - * then match is requested by caller, check BSSID + * BSSID match is requested by caller, check BSSID * (vdev mac == bssid) -- return peer * (vdev mac != bssid) -- perform next iteration */ - if ((!bssid) || - (wlan_peer_bssid_match(peer, bssid) == - QDF_STATUS_SUCCESS)) { - /* Return peer in logically deleted state */ - if ((peer->obj_state == - WLAN_OBJ_STATE_LOGICALLY_DELETED) && - qdf_atomic_read( - &peer->peer_objmgr.ref_cnt)) { + if ((wlan_peer_bssid_match(peer, bssid) == + QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + wlan_objmgr_peer_get_ref_debug(peer, dbg_id, + func, line); - wlan_objmgr_peer_get_ref(peer, dbg_id); - wlan_peer_obj_unlock(peer); - lock_released = true; + return peer; + } + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } - peer_list = - qdf_mem_malloc( - sizeof(struct wlan_logically_del_peer)); - if (!peer_list) { - wlan_objmgr_peer_release_ref(peer, dbg_id); - /* Lock is already released */ - WLAN_OBJMGR_BUG(0); - break; - } + /* Not found, return NULL */ + return NULL; +} +#else +static struct wlan_objmgr_peer + *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t *bssid, + uint8_t pdev_id, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; - peer_list->peer = peer; + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + /* For peer, macaddr is key */ + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) { + /* + * BSSID match is requested by caller, check BSSID + * (vdev mac == bssid) -- return peer + * (vdev mac != bssid) -- perform next iteration + */ + if ((wlan_peer_bssid_match(peer, bssid) == + QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + wlan_objmgr_peer_get_ref(peer, dbg_id); - qdf_list_insert_front( - logical_del_peer_list, - &peer_list->list); - } + return peer; } } - - if (!lock_released) - wlan_peer_obj_unlock(peer); - /* Move to next peer */ peer_temp = peer; peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); - lock_released = false; } /* Not found, return NULL */ - if (qdf_list_empty(logical_del_peer_list)) { - qdf_mem_free(logical_del_peer_list); - return NULL; - } else { - return logical_del_peer_list; - } - + return NULL; } +#endif /** - * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer from psoc peer + * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer + * from psoc peer * list using mac and vdev * self mac * @psoc: PSOC object @@ -1380,10 +1609,13 @@ static qdf_list_t * Return: peer pointer * NULL on FAILURE */ -static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer + *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( qdf_list_t *obj_list, uint8_t *macaddr, uint8_t *bssid, uint8_t pdev_id, - wlan_objmgr_ref_dbgid dbg_id) + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_peer *peer; struct wlan_objmgr_peer *peer_temp; @@ -1402,7 +1634,10 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( if ((wlan_peer_bssid_match(peer, bssid) == QDF_STATUS_SUCCESS) && (wlan_peer_get_pdev_id(peer) == pdev_id)) { - if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) + if (wlan_objmgr_peer_try_get_ref_debug(peer, + dbg_id, + func, + line) == QDF_STATUS_SUCCESS) { return peer; } @@ -1415,12 +1650,10 @@ static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( /* Not found, return NULL */ return NULL; } - -static struct wlan_objmgr_peer - *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( +#else +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( qdf_list_t *obj_list, uint8_t *macaddr, - uint8_t *bssid, - uint8_t pdev_id, + uint8_t *bssid, uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_peer *peer; @@ -1440,107 +1673,610 @@ static struct wlan_objmgr_peer if ((wlan_peer_bssid_match(peer, bssid) == QDF_STATUS_SUCCESS) && (wlan_peer_get_pdev_id(peer) == pdev_id)) { - wlan_objmgr_peer_get_ref(peer, dbg_id); + if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) + == QDF_STATUS_SUCCESS) { + return peer; + } + } + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } + /* Not found, return NULL */ + return NULL; +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state_debug( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; + + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + /* For peer, macaddr and pdev_id is key */ + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, + line); + + return peer; + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } + + /* Not found, return NULL */ + return NULL; +} +#else +static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; + + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + /* For peer, macaddr and pdev_id is key */ + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + wlan_objmgr_peer_get_ref(peer, dbg_id); + + return peer; + } + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + } + + /* Not found, return NULL */ + return NULL; +} +#endif + +/** + * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - + * get peer + * from psoc peer list using + * mac and vdev self mac + * @obj_list: peer object list + * @macaddr: MAC address + * @bssid: BSSID address + * @dbg_id: id of the caller + * @func: function name + * @line: line number + * + * API to finds peer object pointer by MAC addr and BSSID from + * peer hash list for a node which is in logically deleted state, + * bssid check is done on matching peer + * + * Caller to free the list allocated in this function + * + * Return: list of peer pointers + * NULL on FAILURE + */ +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static qdf_list_t + *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t *bssid, uint8_t pdev_id, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; + struct wlan_logically_del_peer *peer_list = NULL; + qdf_list_t *logical_del_peer_list = NULL; + bool lock_released = false; + + logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); + if (!logical_del_peer_list) + return NULL; + + qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); + + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + wlan_peer_obj_lock(peer); + /* For peer, macaddr and pdev id are keys */ + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + /* + * if BSSID not NULL, + * then match is requested by caller, check BSSID + * (vdev mac == bssid) -- return peer + * (vdev mac != bssid) -- perform next iteration + */ + if ((!bssid) || + (wlan_peer_bssid_match(peer, bssid) == + QDF_STATUS_SUCCESS)) { + /* Return peer in logically deleted state */ + if ((peer->obj_state == + WLAN_OBJ_STATE_LOGICALLY_DELETED) && + qdf_atomic_read( + &peer->peer_objmgr.ref_cnt)) { + wlan_objmgr_peer_get_ref_debug(peer, + dbg_id, + func, + line); + wlan_peer_obj_unlock(peer); + lock_released = true; + + peer_list = + qdf_mem_malloc( + sizeof(struct wlan_logically_del_peer)); + if (!peer_list) { + wlan_objmgr_peer_release_ref(peer, dbg_id); + /* Lock is already released */ + WLAN_OBJMGR_BUG(0); + break; + } + + peer_list->peer = peer; + + qdf_list_insert_front( + logical_del_peer_list, + &peer_list->list); + } + } + } + + if (!lock_released) + wlan_peer_obj_unlock(peer); + + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + lock_released = false; + } + + /* Not found, return NULL */ + if (qdf_list_empty(logical_del_peer_list)) { + qdf_mem_free(logical_del_peer_list); + return NULL; + } else { + return logical_del_peer_list; + } +} +#else +static qdf_list_t + *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( + qdf_list_t *obj_list, uint8_t *macaddr, + uint8_t *bssid, uint8_t pdev_id, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_peer *peer_temp; + struct wlan_logically_del_peer *peer_list = NULL; + qdf_list_t *logical_del_peer_list = NULL; + bool lock_released = false; + + logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); + if (!logical_del_peer_list) + return NULL; + + qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); + + /* Iterate through hash list to get the peer */ + peer = wlan_psoc_peer_list_peek_head(obj_list); + while (peer) { + wlan_peer_obj_lock(peer); + /* For peer, macaddr and pdev id are keys */ + if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) + == QDF_STATUS_SUCCESS) && + (wlan_peer_get_pdev_id(peer) == pdev_id)) { + /* + * if BSSID not NULL, + * then match is requested by caller, check BSSID + * (vdev mac == bssid) -- return peer + * (vdev mac != bssid) -- perform next iteration + */ + if ((!bssid) || + (wlan_peer_bssid_match(peer, bssid) == + QDF_STATUS_SUCCESS)) { + /* Return peer in logically deleted state */ + if ((peer->obj_state == + WLAN_OBJ_STATE_LOGICALLY_DELETED) && + qdf_atomic_read( + &peer->peer_objmgr.ref_cnt)) { + wlan_objmgr_peer_get_ref(peer, dbg_id); + wlan_peer_obj_unlock(peer); + lock_released = true; + + peer_list = + qdf_mem_malloc( + sizeof(struct wlan_logically_del_peer)); + if (!peer_list) { + wlan_objmgr_peer_release_ref(peer, dbg_id); + /* Lock is already released */ + WLAN_OBJMGR_BUG(0); + break; + } + + peer_list->peer = peer; + + qdf_list_insert_front( + logical_del_peer_list, + &peer_list->list); + } + } + } + + if (!lock_released) + wlan_peer_obj_unlock(peer); + + /* Move to next peer */ + peer_temp = peer; + peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + lock_released = false; + } + + /* Not found, return NULL */ + if (qdf_list_empty(logical_del_peer_list)) { + qdf_mem_free(logical_del_peer_list); + return NULL; + } else { + return logical_del_peer_list; + } +} +#endif + +QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_peer_list *peer_list; + + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* Max temporary peer limit is reached, return failure */ + if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) { + if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) { + wlan_psoc_obj_unlock(psoc); + return QDF_STATUS_E_FAILURE; + } + } else { + /* Max peer limit is reached, return failure */ + if (objmgr->wlan_peer_count + >= wlan_psoc_get_max_peer_count(psoc)) { + wlan_psoc_obj_unlock(psoc); + return QDF_STATUS_E_FAILURE; + } + } + + /* Derive hash index from mac address */ + hash_index = WLAN_PEER_HASH(peer->macaddr); + peer_list = &objmgr->peer_list; + /* psoc lock should be taken before list lock */ + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* add peer to hash peer list */ + wlan_obj_psoc_peerlist_add_tail( + &peer_list->peer_hash[hash_index], + peer); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + /* Increment peer count */ + if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) + objmgr->temp_peer_count++; + else + objmgr->wlan_peer_count++; + + wlan_psoc_obj_unlock(psoc); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_peer_list *peer_list; + + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* if list is empty, return */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return QDF_STATUS_E_FAILURE; + } + /* Get hash index, to locate the actual peer list */ + hash_index = WLAN_PEER_HASH(peer->macaddr); + peer_list = &objmgr->peer_list; + /* psoc lock should be taken before list lock */ + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* removes the peer from peer_list */ + if (wlan_obj_psoc_peerlist_remove_peer( + &peer_list->peer_hash[hash_index], + peer) == + QDF_STATUS_E_FAILURE) { + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); + obj_mgr_err("Failed to detach peer"); + return QDF_STATUS_E_FAILURE; + } + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + /* Decrement peer count */ + if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) + objmgr->temp_peer_count--; + else + objmgr->wlan_peer_count--; + wlan_psoc_obj_unlock(psoc); + + return QDF_STATUS_SUCCESS; +} + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; + + if (pdev_id >= WLAN_UMAC_MAX_PDEVS) + QDF_ASSERT(0); + + if (!macaddr) + return NULL; + + /* psoc lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; + } + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( + &peer_list->peer_hash[hash_index], macaddr, + pdev_id, dbg_id, func, line); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); + + return peer; +} + +qdf_export_symbol(wlan_objmgr_get_peer_debug); +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; + + if (pdev_id >= WLAN_UMAC_MAX_PDEVS) + QDF_ASSERT(0); + + if (!macaddr) + return NULL; + + /* psoc lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; + } + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( + &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); + + return peer; +} + +qdf_export_symbol(wlan_objmgr_get_peer); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_debug( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; + + if (!macaddr) + return NULL; + + /* psoc lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; + } + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_debug( + &peer_list->peer_hash[hash_index], + macaddr, dbg_id, func, line); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); + + return peer; +} + +qdf_export_symbol(wlan_objmgr_get_peer_by_mac_debug); +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; + + if (!macaddr) + return NULL; + + /* psoc lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; + } + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer( + &peer_list->peer_hash[hash_index], macaddr, dbg_id); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); + + return peer; +} + +qdf_export_symbol(wlan_objmgr_get_peer_by_mac); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted_debug( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; - return peer; - } - } - /* Move to next peer */ - peer_temp = peer; - peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); + /* psoc lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc); + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; } + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( + &peer_list->peer_hash[hash_index], macaddr, dbg_id, + func, line); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc); - /* Not found, return NULL */ - return NULL; + return peer; } - -QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_peer *peer) +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( + struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; struct wlan_peer_list *peer_list; + /* psoc lock should be taken before peer list lock */ wlan_psoc_obj_lock(psoc); objmgr = &psoc->soc_objmgr; - /* Max temporary peer limit is reached, return failure */ - if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) { - if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) { - wlan_psoc_obj_unlock(psoc); - return QDF_STATUS_E_FAILURE; - } - } else { - /* Max peer limit is reached, return failure */ - if (objmgr->wlan_peer_count - >= wlan_psoc_get_max_peer_count(psoc)) { - wlan_psoc_obj_unlock(psoc); - return QDF_STATUS_E_FAILURE; - } + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) { + wlan_psoc_obj_unlock(psoc); + return NULL; } - - /* Derive hash index from mac address */ - hash_index = WLAN_PEER_HASH(peer->macaddr); + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); peer_list = &objmgr->peer_list; - /* psoc lock should be taken before list lock */ qdf_spin_lock_bh(&peer_list->peer_list_lock); - /* add peer to hash peer list */ - wlan_obj_psoc_peerlist_add_tail( - &peer_list->peer_hash[hash_index], - peer); + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted( + &peer_list->peer_hash[hash_index], macaddr, dbg_id); qdf_spin_unlock_bh(&peer_list->peer_list_lock); - /* Increment peer count */ - if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) - objmgr->temp_peer_count++; - else - objmgr->wlan_peer_count++; - wlan_psoc_obj_unlock(psoc); - return QDF_STATUS_SUCCESS; + return peer; } +#endif -QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_peer *peer) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; struct wlan_peer_list *peer_list; + /* psoc lock should be taken before peer list lock */ wlan_psoc_obj_lock(psoc); objmgr = &psoc->soc_objmgr; - /* if list is empty, return */ + /* List is empty, return NULL */ if (objmgr->wlan_peer_count == 0) { wlan_psoc_obj_unlock(psoc); - return QDF_STATUS_E_FAILURE; + return NULL; } - /* Get hash index, to locate the actual peer list */ - hash_index = WLAN_PEER_HASH(peer->macaddr); + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); peer_list = &objmgr->peer_list; - /* psoc lock should be taken before list lock */ qdf_spin_lock_bh(&peer_list->peer_list_lock); - /* removes the peer from peer_list */ - if (wlan_obj_psoc_peerlist_remove_peer( - &peer_list->peer_hash[hash_index], - peer) == - QDF_STATUS_E_FAILURE) { - qdf_spin_unlock_bh(&peer_list->peer_list_lock); - wlan_psoc_obj_unlock(psoc); - obj_mgr_err("Failed to detach peer"); - return QDF_STATUS_E_FAILURE; - } + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( + &peer_list->peer_hash[hash_index], macaddr, bssid, + pdev_id, dbg_id, func, line); qdf_spin_unlock_bh(&peer_list->peer_list_lock); - /* Decrement peer count */ - if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) - objmgr->temp_peer_count--; - else - objmgr->wlan_peer_count--; wlan_psoc_obj_unlock(psoc); - return QDF_STATUS_SUCCESS; + return peer; } -struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( - struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, +qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug); +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_psoc_objmgr *objmgr; @@ -1561,26 +2297,30 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted( - &peer_list->peer_hash[hash_index], macaddr, dbg_id); + peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( + &peer_list->peer_hash[hash_index], macaddr, bssid, + pdev_id, dbg_id); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return peer; } -struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( - struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) +qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; struct wlan_objmgr_peer *peer = NULL; struct wlan_peer_list *peer_list; - if (!macaddr) - return NULL; - /* psoc lock should be taken before peer list lock */ wlan_psoc_obj_lock(psoc); objmgr = &psoc->soc_objmgr; @@ -1594,30 +2334,27 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer( - &peer_list->peer_hash[hash_index], macaddr, dbg_id); + peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( + &peer_list->peer_hash[hash_index], macaddr, bssid, + pdev_id, dbg_id, func, line); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return peer; } -qdf_export_symbol(wlan_objmgr_get_peer_by_mac); -struct wlan_objmgr_peer *wlan_objmgr_get_peer( +qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_debug); +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, - uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) + uint8_t *bssid, uint8_t *macaddr, + wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; struct wlan_objmgr_peer *peer = NULL; struct wlan_peer_list *peer_list; - if (pdev_id >= WLAN_UMAC_MAX_PDEVS) - QDF_ASSERT(0); - - if (!macaddr) - return NULL; - /* psoc lock should be taken before peer list lock */ wlan_psoc_obj_lock(psoc); objmgr = &psoc->soc_objmgr; @@ -1631,15 +2368,48 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer( peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( - &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); + peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( + &peer_list->peer_hash[hash_index], macaddr, bssid, + pdev_id, dbg_id); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return peer; } -qdf_export_symbol(wlan_objmgr_get_peer); +qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock_debug( + struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_psoc_objmgr *objmgr; + uint8_t hash_index; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_peer_list *peer_list; + + /* psoc lock should be taken before peer list lock */ + objmgr = &psoc->soc_objmgr; + /* List is empty, return NULL */ + if (objmgr->wlan_peer_count == 0) + return NULL; + + /* reduce the search window, with hash key */ + hash_index = WLAN_PEER_HASH(macaddr); + peer_list = &objmgr->peer_list; + /* Iterate through peer list, get peer */ + peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( + &peer_list->peer_hash[hash_index], macaddr, + pdev_id, dbg_id, func, line); + + return peer; +} + +qdf_export_symbol(wlan_objmgr_get_peer_nolock_debug); +#else struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) @@ -1664,12 +2434,15 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( return peer; } -qdf_export_symbol(wlan_objmgr_get_peer_nolock); +qdf_export_symbol(wlan_objmgr_get_peer_nolock); +#endif -struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state_debug( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, - uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; @@ -1689,19 +2462,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer_no_state( - &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); + peer = wlan_obj_psoc_peerlist_get_peer_no_state_debug( + &peer_list->peer_hash[hash_index], macaddr, + pdev_id, dbg_id, func, line); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return peer; } -qdf_export_symbol(wlan_objmgr_get_peer_no_state); -struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( +qdf_export_symbol(wlan_objmgr_get_peer_no_state_debug); +#else +struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, - uint8_t *bssid, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) + uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; @@ -1721,19 +2495,20 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( - &peer_list->peer_hash[hash_index], macaddr, bssid, - pdev_id, dbg_id); + peer = wlan_obj_psoc_peerlist_get_peer_no_state( + &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return peer; } -qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); +qdf_export_symbol(wlan_objmgr_get_peer_no_state); +#endif /** - * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from psoc + * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - + * get peer from psoc * peer list using * mac and vdev * self mac @@ -1742,6 +2517,8 @@ qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); * @macaddr: MAC address * @bssid: BSSID address. NULL mac means search all. * @dbg_id: id of the caller + * @func: function name + * @line: line number * * API to finds peer object pointer by MAC addr and BSSID from * peer hash list, bssid check is done on matching peer @@ -1750,10 +2527,12 @@ qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); * NULL on FAILURE */ -qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( +#ifdef WLAN_OBJMGR_REF_ID_TRACE +qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *bssid, uint8_t *macaddr, - wlan_objmgr_ref_dbgid dbg_id) + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; @@ -1775,26 +2554,27 @@ qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( /* Iterate through peer list, get peer */ logical_del_peer_list = - wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( + wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( &peer_list->peer_hash[hash_index], macaddr, - bssid, pdev_id, dbg_id); + bssid, pdev_id, dbg_id, func, line); qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); return logical_del_peer_list; } -qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev); -struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( +qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug); +#else +qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *bssid, uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) { struct wlan_objmgr_psoc_objmgr *objmgr; uint8_t hash_index; - struct wlan_objmgr_peer *peer = NULL; - struct wlan_peer_list *peer_list; + struct wlan_peer_list *peer_list = NULL; + qdf_list_t *logical_del_peer_list = NULL; /* psoc lock should be taken before peer list lock */ wlan_psoc_obj_lock(psoc); @@ -1808,16 +2588,21 @@ struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( hash_index = WLAN_PEER_HASH(macaddr); peer_list = &objmgr->peer_list; qdf_spin_lock_bh(&peer_list->peer_list_lock); + /* Iterate through peer list, get peer */ - peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( - &peer_list->peer_hash[hash_index], macaddr, bssid, - pdev_id, dbg_id); + logical_del_peer_list = + wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( + &peer_list->peer_hash[hash_index], macaddr, + bssid, pdev_id, dbg_id); + qdf_spin_unlock_bh(&peer_list->peer_list_lock); wlan_psoc_obj_unlock(psoc); - return peer; + return logical_del_peer_list; } -qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state); + +qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev); +#endif void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc, enum wlan_umac_comp_id id) @@ -2005,7 +2790,7 @@ QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) +uint32_t wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) { struct wlan_objmgr_psoc_objmgr *_psoc; struct wlan_objmgr_pdev *pdev; @@ -2014,13 +2799,13 @@ void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) QDF_BUG(psoc); if (!psoc) - return; + return leaks; wlan_psoc_obj_lock(psoc); _psoc = &psoc->soc_objmgr; if (!_psoc->wlan_pdev_count) { wlan_psoc_obj_unlock(psoc); - return; + return leaks; } obj_mgr_alert("objmgr pdev leaks detected for psoc %u!", @@ -2045,14 +2830,12 @@ void wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) wlan_pdev_obj_unlock(pdev); } - QDF_DEBUG_PANIC("%u objmgr pdev leaks detected for psoc %u!", - leaks, _psoc->psoc_id); - wlan_psoc_obj_unlock(psoc); + return leaks; } qdf_export_symbol(wlan_objmgr_psoc_check_for_pdev_leaks); -void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) +uint32_t wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) { struct wlan_objmgr_psoc_objmgr *_psoc; struct wlan_objmgr_vdev *vdev; @@ -2061,13 +2844,13 @@ void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) QDF_BUG(psoc); if (!psoc) - return; + return leaks; wlan_psoc_obj_lock(psoc); _psoc = &psoc->soc_objmgr; if (!_psoc->wlan_vdev_count) { wlan_psoc_obj_unlock(psoc); - return; + return leaks; } obj_mgr_alert("objmgr vdev leaks detected for psoc %u!", @@ -2091,10 +2874,8 @@ void wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) wlan_vdev_obj_unlock(vdev); } - QDF_DEBUG_PANIC("%u objmgr vdev leaks detected for psoc %u!", - leaks, _psoc->psoc_id); - wlan_psoc_obj_unlock(psoc); + return leaks; } qdf_export_symbol(wlan_objmgr_psoc_check_for_vdev_leaks); @@ -2108,8 +2889,8 @@ wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) ref_id_dbg = peer->peer_objmgr.ref_id_dbg; wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { - obj_mgr_alert(QDF_MAC_ADDR_STR " %7u %4u %s", - QDF_MAC_ADDR_ARRAY(peer->macaddr), + obj_mgr_alert(QDF_MAC_ADDR_FMT " %7u %4u %s", + QDF_MAC_ADDR_REF(peer->macaddr), vdev_id, refs, string_from_dbgid(ref_id)); @@ -2119,15 +2900,15 @@ wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) static inline void wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) { - obj_mgr_alert(QDF_MAC_ADDR_STR " %7u %4u %s", - QDF_MAC_ADDR_ARRAY(peer->macaddr), + obj_mgr_alert(QDF_MAC_ADDR_FMT " %7u %4u %s", + QDF_MAC_ADDR_REF(peer->macaddr), vdev_id, qdf_atomic_read(&peer->peer_objmgr.ref_cnt), "TOTAL_REF_COUNT"); } #endif -void wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) +uint32_t wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) { struct wlan_objmgr_psoc_objmgr *_psoc; struct wlan_objmgr_vdev *vdev; @@ -2136,13 +2917,13 @@ void wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) QDF_BUG(psoc); if (!psoc) - return; + return leaks; wlan_psoc_obj_lock(psoc); _psoc = &psoc->soc_objmgr; if (!_psoc->temp_peer_count && !_psoc->wlan_peer_count) { wlan_psoc_obj_unlock(psoc); - return; + return leaks; } obj_mgr_alert("objmgr peer leaks detected for psoc %u!", @@ -2164,9 +2945,72 @@ void wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) wlan_vdev_obj_unlock(vdev); } - QDF_DEBUG_PANIC("%u objmgr peer leaks detected for psoc %u!", - leaks, _psoc->psoc_id); - wlan_psoc_obj_unlock(psoc); + return leaks; } qdf_export_symbol(wlan_objmgr_psoc_check_for_peer_leaks); + +void wlan_objmgr_psoc_check_for_leaks(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_objmgr_psoc_objmgr *_psoc; + uint32_t peer_leaks = 0; + uint32_t vdev_leaks = 0; + uint32_t pdev_leaks = 0; + + _psoc = &psoc->soc_objmgr; + + peer_leaks = wlan_objmgr_psoc_check_for_peer_leaks(psoc); + vdev_leaks = wlan_objmgr_psoc_check_for_vdev_leaks(psoc); + pdev_leaks = wlan_objmgr_psoc_check_for_pdev_leaks(psoc); + + if (peer_leaks || vdev_leaks || pdev_leaks) { + QDF_DEBUG_PANIC("%u objmgr peer leaks %u objmgr vdev leaks" + "%u objmgr pdev leaks detected for psoc %u!", + peer_leaks, vdev_leaks, pdev_leaks, + _psoc->psoc_id); + } +} + +qdf_export_symbol(wlan_objmgr_psoc_check_for_leaks); + +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_objmgr_psoc_objmgr *psoc_objmgr; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_vdev *vdev; + uint16_t index = 0; + + psoc_objmgr = &psoc->soc_objmgr; + + obj_mgr_debug("psoc: %pK", psoc); + obj_mgr_debug("psoc_id: %d", psoc_objmgr->psoc_id); + obj_mgr_debug("wlan_pdev_count: %d", psoc_objmgr->wlan_pdev_count); + obj_mgr_debug("wlan_pdev_id_map: 0x%x", psoc_objmgr->wlan_pdev_id_map); + obj_mgr_debug("wlan_vdev_count: %d", psoc_objmgr->wlan_vdev_count); + obj_mgr_debug("max_vdev_count: %d", psoc_objmgr->max_vdev_count); + obj_mgr_debug("wlan_peer_count: %d", psoc_objmgr->wlan_peer_count); + obj_mgr_debug("max_peer_count: %d", psoc_objmgr->max_peer_count); + obj_mgr_debug("temp_peer_count: %d", psoc_objmgr->temp_peer_count); + obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&psoc_objmgr->ref_cnt)); + obj_mgr_debug("qdf_dev: %pK", psoc_objmgr->qdf_dev); + + obj_mgr_debug("wlan_vdev_id_map[%d]: 0x%x", + index, psoc_objmgr->wlan_vdev_id_map[index]); + index++; + obj_mgr_debug("wlan_vdev_id_map[%d]: 0x%x", + index, psoc_objmgr->wlan_vdev_id_map[index]); + + wlan_objmgr_for_each_psoc_pdev(psoc, index, pdev) { + obj_mgr_debug("wlan_pdev_list[%d]: %pK", index, pdev); + wlan_print_pdev_info(pdev); + } + + wlan_objmgr_for_each_psoc_vdev(psoc, index, vdev) { + obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev); + wlan_print_vdev_info(vdev); + } +} + +qdf_export_symbol(wlan_print_psoc_info); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index b7c1eb137e12476b03e71c996957b5999fb9619f..7646a2a7a28a57eeb404e7cff72c8c14b006c7af 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -104,6 +104,8 @@ static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev) QDF_STATUS_E_FAILURE) return QDF_STATUS_E_FAILURE; + wlan_objmgr_vdev_trace_del_ref_list(vdev); + wlan_objmgr_vdev_trace_deinit_lock(vdev); qdf_spinlock_destroy(&vdev->vdev_lock); qdf_mem_free(vdev->vdev_mlme.bss_chan); @@ -168,6 +170,7 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( return NULL; } + wlan_objmgr_vdev_trace_init_lock(vdev); /* Initialize spinlock */ qdf_spinlock_create(&vdev->vdev_lock); /* Attach VDEV to PSOC VDEV's list */ @@ -178,6 +181,7 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( qdf_mem_free(vdev->vdev_mlme.bss_chan); qdf_mem_free(vdev->vdev_mlme.des_chan); qdf_spinlock_destroy(&vdev->vdev_lock); + wlan_objmgr_vdev_trace_deinit_lock(vdev); qdf_mem_free(vdev); return NULL; } @@ -192,6 +196,7 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( qdf_mem_free(vdev->vdev_mlme.bss_chan); qdf_mem_free(vdev->vdev_mlme.des_chan); qdf_spinlock_destroy(&vdev->vdev_lock); + wlan_objmgr_vdev_trace_deinit_lock(vdev); qdf_mem_free(vdev); return NULL; } @@ -260,13 +265,13 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( /* Component object failed to be created, clean up the object */ } else if (obj_status == QDF_STATUS_E_FAILURE) { /* Clean up the psoc */ - wlan_objmgr_vdev_obj_delete(vdev); obj_mgr_err("VDEV comp objects creation failed for vdev-id:%d", vdev->vdev_objmgr.vdev_id); + wlan_objmgr_vdev_obj_delete(vdev); return NULL; } - obj_mgr_info("Created vdev %d", vdev->vdev_objmgr.vdev_id); + obj_mgr_debug("Created vdev %d", vdev->vdev_objmgr.vdev_id); return vdev; } @@ -338,7 +343,7 @@ QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_FAILURE; } - obj_mgr_info("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id); + obj_mgr_debug("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id); print_idx = qdf_get_pidx(); wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, @@ -512,8 +517,8 @@ QDF_STATUS wlan_objmgr_iterate_peerobj_list( if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { wlan_vdev_obj_unlock(vdev); - obj_mgr_err("VDEV is not in create state(:%d): vdev-id:%d", - vdev_id, vdev->obj_state); + obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d", + vdev->obj_state, vdev_id); return QDF_STATUS_E_FAILURE; } wlan_objmgr_vdev_get_ref(vdev, dbg_id); @@ -538,6 +543,59 @@ QDF_STATUS wlan_objmgr_iterate_peerobj_list( return QDF_STATUS_SUCCESS; } +/** + ** APIs to get a peer with given mac in a vdev + */ +struct wlan_objmgr_peer * +wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + wlan_objmgr_ref_dbgid dbg_id) +{ + qdf_list_t *peer_list; + struct wlan_objmgr_peer *peer = NULL; + struct wlan_objmgr_peer *peer_next = NULL; + uint8_t vdev_id; + + if (!vdev) { + obj_mgr_err("VDEV is NULL"); + return NULL; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + + if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { + wlan_vdev_obj_unlock(vdev); + obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d", + vdev->obj_state, vdev_id); + return NULL; + } + wlan_objmgr_vdev_get_ref(vdev, dbg_id); + peer_list = &vdev->vdev_objmgr.wlan_peer_list; + /* Iterate through VDEV's peer list */ + peer = wlan_vdev_peer_list_peek_head(peer_list); + while (peer) { + peer_next = wlan_peer_get_next_peer_of_vdev(peer_list, + peer); + if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == + QDF_STATUS_SUCCESS) { + if (!WLAN_ADDR_EQ(peer_mac, + wlan_peer_get_macaddr(peer))) { + wlan_objmgr_vdev_release_ref(vdev, + dbg_id); + wlan_vdev_obj_unlock(vdev); + return peer; + } + wlan_objmgr_peer_release_ref(peer, dbg_id); + } + peer = peer_next; + } + wlan_objmgr_vdev_release_ref(vdev, dbg_id); + wlan_vdev_obj_unlock(vdev); + return NULL; +} + +qdf_export_symbol(wlan_objmgr_vdev_find_peer_by_mac); + /** * wlan_obj_vdev_populate_logically_del_peerlist() - get peer * from vdev peer list @@ -803,7 +861,9 @@ QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev, wlan_vdev_set_selfpeer(vdev, peer); opmode = wlan_vdev_mlme_get_opmode(vdev); /* For AP mode, self peer and BSS peer are same */ - if ((opmode == QDF_SAP_MODE) || (opmode == QDF_P2P_GO_MODE)) + if ((opmode == QDF_SAP_MODE) || + (opmode == QDF_P2P_GO_MODE) || + (opmode == QDF_NDI_MODE)) wlan_vdev_set_bsspeer(vdev, peer); } /* set BSS peer for sta */ @@ -923,8 +983,40 @@ void *wlan_objmgr_vdev_get_comp_private_obj( } qdf_export_symbol(wlan_objmgr_vdev_get_comp_private_obj); -void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +static inline void +wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + struct wlan_objmgr_trace *trace; + + trace = &vdev->vdev_objmgr.trace; + + if (func) + wlan_objmgr_trace_ref(&trace->references[id].head, + trace, func, line); +} + +static inline void +wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line) +{ + struct wlan_objmgr_trace *trace; + + trace = &vdev->vdev_objmgr.trace; + + if (func) + wlan_objmgr_trace_ref(&trace->dereferences[id].head, + trace, func, line); +} +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line) { if (!vdev) { obj_mgr_err("vdev obj is NULL for id:%d", id); @@ -935,12 +1027,32 @@ void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt); qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]); + wlan_objmgr_vdev_ref_trace(vdev, id, func, line); return; } + +qdf_export_symbol(wlan_objmgr_vdev_get_ref_debug); +#else +void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id) +{ + if (!vdev) { + obj_mgr_err("vdev obj is NULL for id:%d", id); + QDF_ASSERT(0); + return; + } + /* Increment ref count */ + qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt); + qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]); +} + qdf_export_symbol(wlan_objmgr_vdev_get_ref); +#endif -QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, - wlan_objmgr_ref_dbgid id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +QDF_STATUS wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line) { uint8_t vdev_id; @@ -964,50 +1076,152 @@ QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, } /* Increment ref count */ - wlan_objmgr_vdev_get_ref(vdev, id); + wlan_objmgr_vdev_get_ref_debug(vdev, id, func, line); wlan_vdev_obj_unlock(vdev); return QDF_STATUS_SUCCESS; } -qdf_export_symbol(wlan_objmgr_vdev_try_get_ref); -void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev, - wlan_objmgr_ref_dbgid id) +qdf_export_symbol(wlan_objmgr_vdev_try_get_ref_debug); +#else +QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id) { uint8_t vdev_id; if (!vdev) { obj_mgr_err("vdev obj is NULL for id:%d", id); QDF_ASSERT(0); - return; + return QDF_STATUS_E_FAILURE; } + wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); + if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { + wlan_vdev_obj_unlock(vdev); + if (vdev->vdev_objmgr.print_cnt++ <= + WLAN_OBJMGR_RATELIMIT_THRESH) + obj_mgr_err( + "[Ref id: %d] vdev(%d) is not in Created state(%d)", + id, vdev_id, vdev->obj_state); - if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) { - obj_mgr_err("vdev (id:%d)ref cnt was not taken by %d", - vdev_id, id); - wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, - QDF_TRACE_LEVEL_FATAL); - WLAN_OBJMGR_BUG(0); - return; + return QDF_STATUS_E_RESOURCES; } - if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) { - obj_mgr_err("vdev ref cnt is 0"); - WLAN_OBJMGR_BUG(0); - return; + /* Increment ref count */ + wlan_objmgr_vdev_get_ref(vdev, id); + wlan_vdev_obj_unlock(vdev); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(wlan_objmgr_vdev_try_get_ref); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev_debug( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev_next; + qdf_list_node_t *node = &vdev->vdev_node; + qdf_list_node_t *prev_node = NULL; + + if (!node) + return NULL; + + wlan_pdev_obj_lock(pdev); + prev_node = node; + while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS) { + vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref_debug(vdev_next, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev_next; + } + + prev_node = node; } - qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]); + wlan_pdev_obj_unlock(pdev); - /* Decrement ref count, free vdev, if ref count == 0 */ - if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt)) - wlan_objmgr_vdev_obj_destroy(vdev); + return NULL; +} +#else +struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, + struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid dbg_id) +{ + struct wlan_objmgr_vdev *vdev_next; + qdf_list_node_t *node = &vdev->vdev_node; + qdf_list_node_t *prev_node = NULL; - return; + if (!node) + return NULL; + + wlan_pdev_obj_lock(pdev); + prev_node = node; + while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS) { + vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev_next; + } + + prev_node = node; + } + wlan_pdev_obj_unlock(pdev); + + return NULL; } -qdf_export_symbol(wlan_objmgr_vdev_release_ref); +#endif + +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head_debug( + struct wlan_objmgr_pdev *pdev, + qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_vdev *vdev; + qdf_list_node_t *node = NULL; + qdf_list_node_t *prev_node = NULL; + wlan_pdev_obj_lock(pdev); + + if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return NULL; + } + + do { + vdev = qdf_container_of(node, struct wlan_objmgr_vdev, + vdev_node); + if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, + func, line) == + QDF_STATUS_SUCCESS) { + wlan_pdev_obj_unlock(pdev); + return vdev; + } + + prev_node = node; + } while (qdf_list_peek_next(vdev_list, prev_node, &node) == + QDF_STATUS_SUCCESS); + + wlan_pdev_obj_unlock(pdev); + + return NULL; +} +#else struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( struct wlan_objmgr_pdev *pdev, qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id) @@ -1040,7 +1254,24 @@ struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( return NULL; } +#endif +#ifdef WLAN_OBJMGR_REF_ID_TRACE +struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev_debug( + struct wlan_objmgr_pdev *pdev, + wlan_objmgr_ref_dbgid dbg_id, + const char *func, int line) +{ + struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; + qdf_list_t *vdev_list; + + /* VDEV list */ + vdev_list = &objmgr->wlan_vdev_list; + + return wlan_pdev_vdev_list_peek_active_head_debug(pdev, vdev_list, + dbg_id, func, line); +} +#else struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev( struct wlan_objmgr_pdev *pdev, wlan_objmgr_ref_dbgid dbg_id) @@ -1054,36 +1285,112 @@ struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev( return wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list, dbg_id); } +#endif -struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( - struct wlan_objmgr_pdev *pdev, - qdf_list_t *vdev_list, - struct wlan_objmgr_vdev *vdev, - wlan_objmgr_ref_dbgid dbg_id) +#ifdef WLAN_OBJMGR_REF_ID_TRACE +void wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id, + const char *func, int line) { - struct wlan_objmgr_vdev *vdev_next; - qdf_list_node_t *node = &vdev->vdev_node; - qdf_list_node_t *prev_node = NULL; + uint8_t vdev_id; - if (!node) - return NULL; + if (!vdev) { + obj_mgr_err("vdev obj is NULL for id:%d", id); + QDF_ASSERT(0); + return; + } - wlan_pdev_obj_lock(pdev); - prev_node = node; - while (qdf_list_peek_next(vdev_list, prev_node, &node) == - QDF_STATUS_SUCCESS) { - vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, - vdev_node); - if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) == - QDF_STATUS_SUCCESS) { - wlan_pdev_obj_unlock(pdev); - return vdev_next; - } + vdev_id = wlan_vdev_get_id(vdev); - prev_node = node; + if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) { + obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d", + vdev_id, id); + wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, + QDF_TRACE_LEVEL_FATAL); + WLAN_OBJMGR_BUG(0); + return; } - wlan_pdev_obj_unlock(pdev); - return NULL; + if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) { + obj_mgr_alert("vdev ref cnt is 0"); + WLAN_OBJMGR_BUG(0); + return; + } + qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]); + wlan_objmgr_vdev_deref_trace(vdev, id, func, line); + + /* Decrement ref count, free vdev, if ref count == 0 */ + if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt)) + wlan_objmgr_vdev_obj_destroy(vdev); } +qdf_export_symbol(wlan_objmgr_vdev_release_ref_debug); +#else +void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev, + wlan_objmgr_ref_dbgid id) +{ + uint8_t vdev_id; + + if (!vdev) { + obj_mgr_err("vdev obj is NULL for id:%d", id); + QDF_ASSERT(0); + return; + } + + vdev_id = wlan_vdev_get_id(vdev); + + if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) { + obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d", + vdev_id, id); + wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, + QDF_TRACE_LEVEL_FATAL); + WLAN_OBJMGR_BUG(0); + return; + } + + if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) { + obj_mgr_alert("vdev ref cnt is 0"); + WLAN_OBJMGR_BUG(0); + return; + } + qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]); + + /* Decrement ref count, free vdev, if ref count == 0 */ + if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt)) + wlan_objmgr_vdev_obj_destroy(vdev); +} + +qdf_export_symbol(wlan_objmgr_vdev_release_ref); +#endif + +#ifdef WLAN_OBJMGR_DEBUG +void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_vdev_objmgr *vdev_objmgr; + uint32_t ref_cnt; + + vdev_objmgr = &vdev->vdev_objmgr; + + ref_cnt = qdf_atomic_read(&vdev_objmgr->ref_cnt); + + obj_mgr_debug("vdev: %pK", vdev); + obj_mgr_debug("vdev_id: %d", vdev_objmgr->vdev_id); + obj_mgr_debug("print_cnt: %d", vdev_objmgr->print_cnt); + obj_mgr_debug("wlan_pdev: %pK", vdev_objmgr->wlan_pdev); + obj_mgr_debug("ref_cnt: %d", ref_cnt); +} + +qdf_export_symbol(wlan_print_vdev_info); +#endif + +void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev) +{ + wlan_objmgr_vdev_peer_free_notify_handler stat_handler; + uint8_t i; + + for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { + stat_handler = g_umac_glb_obj->vdev_peer_free_notify_handler[i]; + if (stat_handler) + stat_handler(vdev); + } +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_api.h index bbc81bacec88a84f49d68b76c87714cbe131d943..2d33bd0beb015427ae1ac696c8f988bdc554b029 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -160,7 +159,40 @@ typedef QDF_STATUS (*wlan_ser_umac_cmd_cb)(void *umac_cmd); /** * enum wlan_umac_cmd_id - Command Type - * @WLAN_SER_CMD_SCAN: Scan command + * @WLAN_SER_CMD_SCAN: Scan command + * @WLAN_SER_CMD_NONSCAN: Non-scan command + * @WLAN_SER_CMD_HDD_ISSUE_REASSOC_SAME_AP: HDD Reassoc cmd + * @WLAN_SER_CMD_SME_ISSUE_REASSOC_SAME_AP: SME Reassoc cmd + * @WLAN_SER_CMD_SME_ISSUE_DISASSOC_FOR_HANDOFF: SME Disassoc cmd + * @WLAN_SER_CMD_SME_ISSUE_ASSOC_TO_SIMILAR_AP: SME Assoc cmd + * @WLAN_SER_CMD_FORCE_IBSS_LEAVE: IBSS leave AP cmd + * @WLAN_SER_CMD_SME_ISSUE_FT_REASSOC: SME reassoc cmd + * @WLAN_SER_CMD_FORCE_DISASSOC_STA: Force diassoc for STA vap + * @WLAN_SER_CMD_FORCE_DEAUTH_STA: Force deauth for STA vap + * @WLAN_SER_CMD_PERFORM_PRE_AUTH: Pre auth ops cmd + * @WLAN_SER_CMD_WM_STATUS_CHANGE: WM status modification cmd + * @WLAN_SER_CMD_NDP_INIT_REQ: NDP init request cmd + * @WLAN_SER_CMD_NDP_RESP_REQ: NDP response to request cmd + * @WLAN_SER_CMD_NDP_DATA_END_INIT_REQ: NDP data end init request + * @WLAN_SER_CMD_NDP_END_ALL_REQ: NDP close all request + * @WLAN_SER_CMD_ADDTS: ADD Ts cmd + * @WLAN_SER_CMD_DELTS: Del Ts cmd + * @WLAN_SER_CMD_TDLS_SEND_MGMT: TDLS mgmt send cmd + * @WLAN_SER_CMD_TDLS_ADD_PEER: TDLS cmd to add peer + * @WLAN_SER_CMD_TDLS_DEL_PEER: TDLS cmd to del peer + * @WLAN_SER_CMD_SET_HW_MODE: Cmd to set hardware mode change + * @WLAN_SER_CMD_NSS_UPDATE: Cmd to update NSS config + * @WLAN_SER_CMD_SET_DUAL_MAC_CONFIG: Cmd to set dual mac + * @WLAN_SER_CMD_SET_ANTENNA_MODE: Set antenna mode + * @WLAN_SER_CMD_VDEV_DELETE: Cmd to del vdev + * @WLAN_SER_CMD_VDEV_START_BSS: Cmd to start a AP VDEV + * @WLAN_SER_CMD_VDEV_STOP_BSS: Cmd to stop a AP VDEV + * @WLAN_SER_CMD_VDEV_CONNECT: Cmd to start a STA VDEV + * @WLAN_SER_CMD_VDEV_DISCONNECT: Cmd to stop a STA VDEV + * @WLAN_SER_CMD_VDEV_RESTART: Cmd to restart a VDEV + * @WLAN_SER_CMD_PDEV_RESTART: Cmd to restart all VDEVs of a PDEV + * @WLAN_SER_CMD_PDEV_CSA_RESTART: Cmd to CSA restart all AP VDEVs of a PDEV + * @WLAN_SER_CMD_GET_DISCONNECT_STATS: Cmd to get peer stats on disconnection */ enum wlan_serialization_cmd_type { /* all scan command before non-scan */ @@ -190,12 +222,15 @@ enum wlan_serialization_cmd_type { WLAN_SER_CMD_NSS_UPDATE, WLAN_SER_CMD_SET_DUAL_MAC_CONFIG, WLAN_SER_CMD_SET_ANTENNA_MODE, - WLAN_SER_CMD_DEL_STA_SESSION, + WLAN_SER_CMD_VDEV_DELETE, WLAN_SER_CMD_VDEV_START_BSS, WLAN_SER_CMD_VDEV_STOP_BSS, WLAN_SER_CMD_VDEV_CONNECT, WLAN_SER_CMD_VDEV_DISCONNECT, WLAN_SER_CMD_VDEV_RESTART, + WLAN_SER_CMD_PDEV_RESTART, + WLAN_SER_CMD_PDEV_CSA_RESTART, + WLAN_SER_CMD_GET_DISCONNECT_STATS, WLAN_SER_CMD_MAX }; @@ -209,6 +244,8 @@ enum wlan_serialization_cmd_type { * @WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD: Cancel all non scans on a given vdev * @WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE: Cancel all non scans on a given vdev * and matching cmd type + * @WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD: Cancel all non-blocking, + * non-scan commands of a given vdev * @WLAN_SER_CANCEL_NON_SCAN_CMD: Cancel the given non scan command */ enum wlan_serialization_cancel_type { @@ -219,6 +256,7 @@ enum wlan_serialization_cancel_type { WLAN_SER_CANCEL_PDEV_NON_SCAN_CMD, WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD, WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE, + WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD, WLAN_SER_CANCEL_NON_SCAN_CMD, WLAN_SER_CANCEL_MAX, }; @@ -259,6 +297,18 @@ enum wlan_serialization_cmd_status { WLAN_SER_CMD_NOT_FOUND, }; +/** + * enum wlan_ser_cmd_attr - Serialization cmd attribute + * @WLAN_SER_CMD_ATTR_NONE - No attribuate associated + * @WLAN_SER_CMD_ATTR_BLOCK - Blocking attribute + * @WLAN_SER_CMD_ATTR_NONBLOCK - Non-blocking attribute + */ +enum wlan_ser_cmd_attr { + WLAN_SER_CMD_ATTR_NONE, + WLAN_SER_CMD_ATTR_BLOCK, + WLAN_SER_CMD_ATTR_NONBLOCK, +}; + /** * struct wlan_serialization_command - Command to be serialized * @wlan_serialization_cmd_type: Type of command @@ -575,6 +625,16 @@ wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev); QDF_STATUS wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev); +/** + * wlan_ser_is_vdev_queue_enabled() - Return vdev queue status + * @vdev: vdev object + * + * This API return vdev queue enable status + * + * Return: true if vdev queue is enabled + */ +bool wlan_ser_is_vdev_queue_enabled(struct wlan_objmgr_vdev *vdev); + /** * wlan_ser_validate_umac_cmd() - validate umac cmd data * @vdev: objmgr vdev pointer @@ -631,4 +691,14 @@ void wlan_serialization_purge_all_pending_cmd_by_vdev_id( void wlan_serialization_purge_all_scan_cmd_by_vdev_id( struct wlan_objmgr_pdev *pdev, uint8_t vdev_id); + +/** + * wlan_ser_vdev_queue_disable -Disable vdev specific serialization queue + * @vdev: Vdev Object + * + * This function disables the serialization for the vdev queue + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_ser_vdev_queue_disable(struct wlan_objmgr_vdev *vdev); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_legacy_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_legacy_api.h index 56cff30dec03cfc6eca777e6676853c78b40fcfe..0c48da459aed79ec45969339b4ef357b667165ee 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_legacy_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/inc/wlan_serialization_legacy_api.h @@ -79,19 +79,6 @@ wlan_serialization_get_pending_list_next_node_using_psoc( struct wlan_objmgr_psoc *psoc, struct wlan_serialization_command *prev_cmd, uint8_t is_cmd_for_pending_scan_queue); -/** - * wlan_serialization_get_active_list_count() - Return Active list count - * @psoc: pointer to soc - * @is_cmd_from_active_scan_queue: flag to determine whether command needed - * from scan or non-scan active queue - * - * Get the number of nodes present in active list - * - * Return: count number of active commands in queue - */ - -uint32_t wlan_serialization_get_active_list_count(struct wlan_objmgr_psoc *psoc, - uint8_t is_cmd_from_active_scan_queue); /** * wlan_serialization_get_pending_list_count() - Return pending list count * @psoc: pointer to soc diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_api.c index 7c22472a76ce5a0521bced4c5db6941acb7b1bf0..6cf61b7cf3cbcf9389e39c8aea52154b844b5d6e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -643,6 +643,25 @@ wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev) return cmd_type; } +bool wlan_ser_is_vdev_queue_enabled(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_ser_vdev_obj *ser_vdev_obj; + struct wlan_serialization_vdev_queue *vdev_queue; + + ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); + if (!ser_vdev_obj) { + ser_err("invalid ser_vdev_obj"); + return false; + } + + vdev_queue = wlan_serialization_get_vdev_queue_obj( + ser_vdev_obj, WLAN_SER_CMD_NONSCAN); + if (vdev_queue->queue_disable) + return false; + else + return true; +} + QDF_STATUS wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev) { @@ -766,9 +785,11 @@ void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev) wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, WLAN_SER_CMD_SCAN, true); wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, - WLAN_SER_CMD_NONSCAN, false); + WLAN_SER_CMD_NONSCAN, false, + WLAN_SER_CMD_ATTR_NONE); wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, - WLAN_SER_CMD_NONSCAN, true); + WLAN_SER_CMD_NONSCAN, true, + WLAN_SER_CMD_ATTR_NONE); } static inline @@ -815,7 +836,8 @@ void wlan_serialization_purge_all_pending_cmd_by_vdev_id( wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, WLAN_SER_CMD_SCAN, false); wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL, - WLAN_SER_CMD_NONSCAN, false); + WLAN_SER_CMD_NONSCAN, false, + WLAN_SER_CMD_ATTR_NONE); wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); } @@ -852,3 +874,47 @@ void wlan_serialization_purge_all_scan_cmd_by_vdev_id( wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); } + +QDF_STATUS wlan_ser_vdev_queue_disable(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_pdev *pdev; + struct wlan_ser_vdev_obj *ser_vdev_obj; + struct wlan_serialization_vdev_queue *vdev_queue; + struct wlan_ser_pdev_obj *ser_pdev_obj; + struct wlan_serialization_pdev_queue *pdev_q; + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + ser_err("invalid PDEV object"); + return QDF_STATUS_E_INVAL; + } + + ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); + if (!ser_pdev_obj) { + ser_err("invalid ser_pdev_obj"); + return QDF_STATUS_E_INVAL; + } + + ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); + if (!ser_vdev_obj) { + ser_err("invalid ser_vdev_obj"); + return QDF_STATUS_E_INVAL; + } + + pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; + + vdev_queue = wlan_serialization_get_vdev_queue_obj( + ser_vdev_obj, WLAN_SER_CMD_NONSCAN); + if (!vdev_queue) { + ser_err("invalid vdev_queue object"); + return QDF_STATUS_E_INVAL; + } + + wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); + vdev_queue->queue_disable = true; + wlan_serialization_release_lock(&pdev_q->pdev_queue_lock); + ser_debug("Disabling the serialization for vdev:%d", + wlan_vdev_get_id(vdev)); + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal.c index dc9443a1b8c75f3186fbecc67a0f2a46b0d1952c..88dfc763614710aff9711adf174244183b703f6e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -364,7 +363,8 @@ QDF_STATUS wlan_serialization_activate_cmd( wlan_serialization_cmd_cancel_handler( ser_pdev_obj, &cmd_list->cmd, NULL, NULL, cmd_list->cmd.cmd_type, - WLAN_SERIALIZATION_ACTIVE_QUEUE); + WLAN_SERIALIZATION_ACTIVE_QUEUE, + WLAN_SER_CMD_ATTR_NONE); error: return status; } @@ -543,6 +543,7 @@ QDF_STATUS wlan_serialization_generic_timer_cb(void *arg) struct wlan_serialization_timer *timer = arg; struct wlan_serialization_command *cmd = timer->cmd; struct wlan_objmgr_vdev *vdev = NULL; + enum wlan_serialization_cmd_status status; if (!cmd) { @@ -566,10 +567,11 @@ QDF_STATUS wlan_serialization_generic_timer_cb(void *arg) * dequeue cmd API will cleanup and destroy the timer. If it fails to * dequeue command then we have to destroy the timer. */ - wlan_serialization_dequeue_cmd(cmd, SER_TIMEOUT, true); + status = wlan_serialization_dequeue_cmd(cmd, SER_TIMEOUT, true); /* Release the ref taken before the timer was started */ - wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); + if (status == WLAN_SER_CMD_IN_ACTIVE_LIST) + wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID); return QDF_STATUS_SUCCESS; } @@ -815,7 +817,8 @@ wlan_serialization_cmd_cancel_handler( struct wlan_ser_pdev_obj *ser_obj, struct wlan_serialization_command *cmd, struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, - enum wlan_serialization_cmd_type cmd_type, uint8_t queue_type) + enum wlan_serialization_cmd_type cmd_type, uint8_t queue_type, + enum wlan_ser_cmd_attr cmd_attr) { enum wlan_serialization_cmd_status active_status = WLAN_SER_CMD_NOT_FOUND; @@ -837,7 +840,7 @@ wlan_serialization_cmd_cancel_handler( else active_status = wlan_ser_cancel_non_scan_cmd( ser_obj, pdev, vdev, cmd, - cmd_type, true); + cmd_type, true, cmd_attr); } if (queue_type & WLAN_SERIALIZATION_PENDING_QUEUE) { @@ -848,7 +851,7 @@ wlan_serialization_cmd_cancel_handler( else pending_status = wlan_ser_cancel_non_scan_cmd( ser_obj, pdev, vdev, cmd, - cmd_type, false); + cmd_type, false, cmd_attr); } if (active_status == WLAN_SER_CMD_IN_ACTIVE_LIST && @@ -894,38 +897,44 @@ wlan_serialization_find_and_cancel_cmd( /* remove scan cmd which matches the given cmd struct */ status = wlan_serialization_cmd_cancel_handler( ser_obj, cmd, NULL, NULL, - WLAN_SER_CMD_SCAN, queue_type); + WLAN_SER_CMD_SCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_PDEV_SCANS: /* remove all scan cmds which matches the pdev object */ status = wlan_serialization_cmd_cancel_handler( ser_obj, NULL, pdev, NULL, - WLAN_SER_CMD_SCAN, queue_type); + WLAN_SER_CMD_SCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_VDEV_SCANS: case WLAN_SER_CANCEL_VDEV_HOST_SCANS: /* remove all scan cmds which matches the vdev object */ status = wlan_serialization_cmd_cancel_handler( ser_obj, NULL, NULL, cmd->vdev, - WLAN_SER_CMD_SCAN, queue_type); + WLAN_SER_CMD_SCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_NON_SCAN_CMD: /* remove nonscan cmd which matches the given cmd */ status = wlan_serialization_cmd_cancel_handler( ser_obj, cmd, NULL, NULL, - WLAN_SER_CMD_NONSCAN, queue_type); + WLAN_SER_CMD_NONSCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_PDEV_NON_SCAN_CMD: /* remove all non scan cmds which matches the pdev object */ status = wlan_serialization_cmd_cancel_handler( ser_obj, NULL, pdev, NULL, - WLAN_SER_CMD_NONSCAN, queue_type); + WLAN_SER_CMD_NONSCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD: /* remove all non scan cmds which matches the vdev object */ status = wlan_serialization_cmd_cancel_handler( ser_obj, NULL, NULL, cmd->vdev, - WLAN_SER_CMD_NONSCAN, queue_type); + WLAN_SER_CMD_NONSCAN, queue_type, + WLAN_SER_CMD_ATTR_NONE); break; case WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE: /* @@ -934,7 +943,18 @@ wlan_serialization_find_and_cancel_cmd( */ status = wlan_serialization_cmd_cancel_handler( ser_obj, NULL, NULL, cmd->vdev, - cmd->cmd_type, queue_type); + cmd->cmd_type, queue_type, + WLAN_SER_CMD_ATTR_NONE); + break; + case WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD: + /* + * remove all non-blocking non-scan cmds which matches the given + * vdev + */ + status = wlan_serialization_cmd_cancel_handler( + ser_obj, NULL, NULL, cmd->vdev, + WLAN_SER_CMD_NONSCAN, queue_type, + WLAN_SER_CMD_ATTR_NONBLOCK); break; default: ser_err("Invalid request"); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h index 44b6b9b1fb53b4f2c91cbea76292721fbfff6fa3..a1cb902fad3b1afd5089769c86e0e54d8732747d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_internal_i.h @@ -205,6 +205,7 @@ wlan_serialization_find_and_cancel_cmd( * @vdev: pointer to vdev * @cmd_type: pointer to cmd_type * @queue_type: If active queue or pending queue + * @cmd_attr: Attrbute to indicate a blocking or a non-blocking command * * This API will decide from which queue, command needs to be cancelled * and pass that queue and other parameter required to cancel the command @@ -219,5 +220,6 @@ wlan_serialization_cmd_cancel_handler( struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, enum wlan_serialization_cmd_type cmd_type, - uint8_t queue_type); + uint8_t queue_type, + enum wlan_ser_cmd_attr cmd_attr); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_legacy_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_legacy_api.c index 7e237225a86f8287ce5c09a44ba2e8238f3eaaed..1469630d49231fb0a834311bde839de37f4dcfd6 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_legacy_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_legacy_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -77,35 +77,6 @@ wlan_serialization_get_pdev_priv_obj_using_psoc(struct wlan_objmgr_psoc *psoc) return ser_pdev_obj; } -uint32_t wlan_serialization_get_active_list_count( - struct wlan_objmgr_psoc *psoc, - uint8_t is_cmd_from_active_scan_queue) -{ - struct wlan_ser_pdev_obj *ser_pdev_obj; - qdf_list_t *queue; - struct wlan_serialization_pdev_queue *pdev_queue; - uint32_t count; - - ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); - if (!ser_pdev_obj) { - ser_err("invalid ser_pdev_obj"); - return 0; - } - - if (is_cmd_from_active_scan_queue) - pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; - else - pdev_queue = - &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; - - wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); - queue = &pdev_queue->active_list; - count = qdf_list_size(queue); - wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); - - return count; -} - uint32_t wlan_serialization_get_pending_list_count( struct wlan_objmgr_psoc *psoc, uint8_t is_cmd_from_pending_scan_queue) @@ -200,10 +171,8 @@ wlan_serialization_peek_head_pending_cmd_using_psoc( pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; queue = &pdev_queue->pending_list; - if (wlan_serialization_list_empty(queue)) { - ser_err("Empty Queue"); + if (wlan_serialization_list_empty(queue)) goto end; - } wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue( diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_main.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_main.c index 1ae48be7107203924a16e7f37d3ae7e3f428ce66..683d00074434a9219ce7647e25aa18dec536e3b7 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_main.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -52,11 +52,12 @@ QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc) if (status != QDF_STATUS_SUCCESS) ser_err("ser cleanning up all timer failed"); + /* Use lock to free to avoid any race where timer is still in use */ + wlan_serialization_acquire_lock(&ser_soc_obj->timer_lock); qdf_mem_free(ser_soc_obj->timers); ser_soc_obj->timers = NULL; ser_soc_obj->max_active_cmds = 0; - - wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); + wlan_serialization_release_lock(&ser_soc_obj->timer_lock); error: return status; } @@ -87,7 +88,6 @@ QDF_STATUS wlan_serialization_psoc_enable(struct wlan_objmgr_psoc *psoc) goto error; } - wlan_serialization_create_lock(&ser_soc_obj->timer_lock); status = QDF_STATUS_SUCCESS; error: @@ -127,6 +127,7 @@ static QDF_STATUS wlan_serialization_psoc_create_handler( ser_err("Obj attach failed"); goto error; } + wlan_serialization_create_lock(&soc_ser_obj->timer_lock); ser_debug("ser psoc obj created"); status = QDF_STATUS_SUCCESS; @@ -144,7 +145,6 @@ static void wlan_serialization_destroy_cmd_pool( struct wlan_serialization_pdev_queue *pdev_queue) { qdf_list_node_t *node = NULL; - struct wlan_serialization_command_list *cmd_list; ser_debug("Destroy cmd pool list %pK, size %d", &pdev_queue->cmd_pool_list, @@ -152,8 +152,7 @@ static void wlan_serialization_destroy_cmd_pool( while (!qdf_list_empty(&pdev_queue->cmd_pool_list)) { qdf_list_remove_front(&pdev_queue->cmd_pool_list, &node); - cmd_list = (struct wlan_serialization_command_list *)node; - qdf_mem_free(cmd_list); + qdf_mem_free(node); } qdf_list_destroy(&pdev_queue->cmd_pool_list); @@ -329,6 +328,7 @@ wlan_serialization_psoc_destroy_handler(struct wlan_objmgr_psoc *psoc, if (status != QDF_STATUS_SUCCESS) ser_err("ser psoc private obj detach failed"); + wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); ser_debug("ser psoc obj deleted with status %d", status); qdf_mem_free(ser_soc_obj); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c index 96f587f0e08c1c73125c4110b5bb911b76bcc99d..cd41cb7a6a395201557562705cdbc0285eeb6827 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c @@ -360,6 +360,9 @@ wlan_ser_move_non_scan_pending_to_active( qdf_atomic_set_bit(CMD_MARKED_FOR_ACTIVATION, &active_cmd_list->cmd_in_use); + if (active_cmd_list->cmd.is_blocking) + pdev_queue->blocking_cmd_waiting--; + wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); wlan_serialization_activate_cmd(active_cmd_list, ser_pdev_obj, @@ -367,15 +370,11 @@ wlan_ser_move_non_scan_pending_to_active( wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); - if (vdev_queue_lookup) + if (vdev_queue_lookup || pdev_queue->blocking_cmd_active) break; pending_node = NULL; - if (active_cmd_list->cmd.is_blocking) { - pdev_queue->blocking_cmd_waiting--; - break; - } } wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); @@ -455,7 +454,7 @@ wlan_ser_cancel_non_scan_cmd( struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, struct wlan_serialization_command *cmd, enum wlan_serialization_cmd_type cmd_type, - uint8_t is_active_queue) + uint8_t is_active_queue, enum wlan_ser_cmd_attr cmd_attr) { qdf_list_t *pdev_queue; qdf_list_t *vdev_queue; @@ -532,6 +531,18 @@ wlan_ser_cancel_non_scan_cmd( continue; } + /* + * If a non-blocking cmd is required to be cancelled, but + * the nnode cmd is a blocking cmd then continue with the + * next command in the list else proceed with cmd cancel. + */ + if ((cmd_attr == WLAN_SER_CMD_ATTR_NONBLOCK) && + wlan_serialization_match_cmd_blocking(nnode, + WLAN_SER_PDEV_NODE)) { + pnode = nnode; + continue; + } + /* * active queue can't be removed directly, requester needs to * wait for active command response and send remove request for diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h index 5426ae4c5ee17e803ac52c26ef37a2063f6afcc5..d52402bf8efb1b2b723ddc98be46798fcebf9dbb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -115,6 +115,8 @@ wlan_ser_remove_non_scan_cmd(struct wlan_ser_pdev_obj *ser_pdev_obj, * @cmd_type: Serialization command type to be cancelled * @is_active_queue: If the cmd has to be removed from active queue or pending * queue + * @cmd_attr: Indicate the attribute of the cmd to be cancelled + * i.e blocking/non-blocking * * Return: Status specifying the cancel of a command from the given queue */ @@ -124,5 +126,6 @@ wlan_ser_cancel_non_scan_cmd(struct wlan_ser_pdev_obj *ser_obj, struct wlan_objmgr_vdev *vdev, struct wlan_serialization_command *cmd, enum wlan_serialization_cmd_type cmd_type, - uint8_t is_active_queue); + uint8_t is_active_queue, + enum wlan_ser_cmd_attr cmd_attr); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c index b7c626aa0c516e0002968e9266b5592abfb4de71..4ec739408f03b2c70a2a02ee8a11c0b9f19309fb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c @@ -157,9 +157,26 @@ QDF_STATUS wlan_serialization_cleanup_vdev_timers( struct wlan_serialization_timer *ser_timer; QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t i = 0; + struct wlan_objmgr_pdev *pdev = NULL; + struct wlan_objmgr_psoc *psoc = NULL; + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + QDF_BUG(0); + ser_err("pdev is null"); + status = QDF_STATUS_E_FAILURE; + goto error; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + QDF_BUG(0); + ser_err("psoc is null"); + status = QDF_STATUS_E_FAILURE; + goto error; + } - psoc_ser_obj = wlan_serialization_get_psoc_obj( - wlan_vdev_get_psoc(vdev)); + psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc); if (!psoc_ser_obj) { ser_err("Invalid psoc_ser_obj"); @@ -462,7 +479,7 @@ wlan_serialization_remove_cmd_from_queue( goto error; if (!queue || wlan_serialization_list_empty(queue)) { - ser_err("Empty queue"); + ser_debug("Empty queue"); goto error; } @@ -757,6 +774,30 @@ bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode, return match_found; } +bool wlan_serialization_match_cmd_blocking( + qdf_list_node_t *nnode, + enum wlan_serialization_node node_type) +{ + struct wlan_serialization_command_list *cmd_list = NULL; + bool match_found = false; + + if (node_type == WLAN_SER_PDEV_NODE) + cmd_list = + qdf_container_of(nnode, + struct wlan_serialization_command_list, + pdev_node); + else + cmd_list = + qdf_container_of(nnode, + struct wlan_serialization_command_list, + vdev_node); + + if (cmd_list->cmd.is_blocking) + match_found = true; + + return match_found; +} + qdf_list_node_t * wlan_serialization_find_cmd(qdf_list_t *queue, enum wlan_serialization_match_type match_type, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h index 61e5348dfc975a48f24098a87e8f5024a6ffc0e9..a7bc208aad7daa94e6158b9401fa970dbe0d1e74 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -546,6 +546,19 @@ bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode, struct wlan_objmgr_pdev *pdev, enum wlan_serialization_node node_type); +/** + * wlan_serialization_match_cmd_blocking() - Check for a blocking cmd + * @nnode: The node on which the matching has to be done + * @node_type: Pdev node or vdev node + * + * This API will check if the give command of nnode is a blocking command. + * + * Return: True if blocking command, false otherwise. + */ +bool wlan_serialization_match_cmd_blocking( + qdf_list_node_t *nnode, + enum wlan_serialization_node node_type); + /** * wlan_serialization_find_cmd() - Find the cmd matching the given criterias * @cmd: Serialization command information diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/inc/wlan_sm_engine_dbg.h b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/inc/wlan_sm_engine_dbg.h index 512b860532c206fbb9f1737e42fcc4ca99106f2e..9edb7eb03a9fc033feacc4974daabc8be170e6fa 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/inc/wlan_sm_engine_dbg.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/inc/wlan_sm_engine_dbg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -137,6 +137,18 @@ void wlan_sm_history_delete(struct wlan_sm *sm); */ void wlan_sm_print_history(struct wlan_sm *sm); +#if SM_HIST_DEBUGFS_SUPPORT +/** + * wlan_sm_print_fs_history() - API to print SM history in proc + * @sm: state machine handle + * @m: debug fs file handle + * + * Prints SM history through proc + * + * Return: void + */ +void wlan_sm_print_fs_history(struct wlan_sm *sm, qdf_debugfs_file_t m); +#endif #else /* SM_ENG_HIST_ENABLE */ /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/src/wlan_sm_engine_dbg.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/src/wlan_sm_engine_dbg.c index 3676d0c706500b6a84fc1a2eb8a5de12aa7c8a90..b21ee4cc6cbf8de1710e671341e59d7b3ff23fdb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/src/wlan_sm_engine_dbg.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/sm_engine/src/wlan_sm_engine_dbg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -116,3 +116,63 @@ void wlan_sm_print_history(struct wlan_sm *sm) qdf_spin_unlock_bh(&p_sm_history->sm_history_lock); } + +#if SM_HIST_DEBUGFS_SUPPORT +static void wlan_sm_print_fs_history_entry(struct wlan_sm *sm, + struct wlan_sm_history_info *ent, + uint16_t i, qdf_debugfs_file_t m) +{ + const char *event_name = NULL; + + if (sm->event_names) { + if (ent->event_type < sm->num_event_names) + event_name = sm->event_names[ent->event_type]; + + if (!ent->trace_type) + return; + + qdf_debugfs_printf(m, + "|%6d |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |\n", + i, ent->trace_type, + event_name ? event_name : "UNKNOWN_EVENT", + ent->event_type, + sm->state_info[ent->initial_state].name, + ent->initial_state, + sm->state_info[ent->final_state].name, + ent->final_state); + } else { + qdf_debugfs_printf(m, + "|%6d |%11d |%28d |%19s[%2d] |%19s[%2d] |\n", + i, ent->trace_type, + ent->event_type, + sm->state_info[ent->initial_state].name, + ent->initial_state, + sm->state_info[ent->final_state].name, + ent->final_state); + } +} + +void wlan_sm_print_fs_history(struct wlan_sm *sm, qdf_debugfs_file_t m) +{ + struct wlan_sm_history *p_sm_history = &sm->history; + uint8_t i; + uint8_t idx; + + /* + * History saved in circular buffer. + * Save a pointer to next write location and increment pointer. + */ + qdf_spin_lock_bh(&p_sm_history->sm_history_lock); + qdf_debugfs_printf(m, "|%6s |%11s |%28s |%23s |%23s |\n", "Index", + "Trace Type", "Event", + "Initial State", "Final State"); + + for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) { + idx = (p_sm_history->index + i) % WLAN_SM_ENGINE_HISTORY_SIZE; + wlan_sm_print_fs_history_entry(sm, &p_sm_history->data[idx], + idx, m); + } + + qdf_spin_unlock_bh(&p_sm_history->sm_history_lock); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/utils/src/wlan_utility.c b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/utils/src/wlan_utility.c index 5bab3e124d4da9d382d540a5276b62fc057b451b..c82001afd5944381360e248d33b32627d2b061f4 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/utils/src/wlan_utility.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cmn_services/utils/src/wlan_utility.c @@ -28,7 +28,9 @@ uint32_t wlan_chan_to_freq(uint8_t chan) { - /* ch 0 - ch 13 */ + if (chan == 0 ) + return 0; + if (chan < WLAN_24_GHZ_CHANNEL_14) return WLAN_24_GHZ_BASE_FREQ + chan * WLAN_CHAN_SPACING_5MHZ; else if (chan == WLAN_24_GHZ_CHANNEL_14) @@ -47,6 +49,9 @@ uint8_t wlan_freq_to_chan(uint32_t freq) { uint8_t chan; + if (freq == 0) + return 0; + if (freq > WLAN_24_GHZ_BASE_FREQ && freq < WLAN_CHAN_14_FREQ) chan = ((freq - WLAN_24_GHZ_BASE_FREQ) / WLAN_CHAN_SPACING_5MHZ); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/core/inc/wlan_coex_main.h b/drivers/staging/qca-wifi-host-cmn/umac/coex/core/inc/wlan_coex_main.h new file mode 100644 index 0000000000000000000000000000000000000000..22cde21af03fe1fd2f10c639307a7b3fb3b9324b --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/core/inc/wlan_coex_main.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains declarations for coex core functions + */ + +#ifndef _WLAN_COEX_MAIN_API_H_ +#define _WLAN_COEX_MAIN_API_H_ + +#ifdef FEATURE_COEX +#include "wlan_coex_ucfg_api.h" +#include "wmi_unified_param.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_vdev_obj.h" + +#define coex_err(params...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_COEX, params) +#define coex_info(params...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_COEX, params) +#define coex_debug(params...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_COEX, params) + +/** + * struct coex_psoc_obj - coex object definition + * @btc_chain_mode: BT Coex chain mode. + * @coex_config_updated: callback functions for each config type, which will + * be called when config is updated. + */ +struct coex_psoc_obj { + uint8_t btc_chain_mode; + update_coex_cb coex_config_updated[COEX_CONFIG_TYPE_MAX]; +}; + +/** + * wlan_psoc_get_coex_obj() - private API to get coex object from psoc + * @psoc: psoc object + * + * Return: coex object + */ +#define wlan_psoc_get_coex_obj(psoc) \ + wlan_psoc_get_coex_obj_fl(psoc, __func__, __LINE__) + +static inline struct coex_psoc_obj * +wlan_psoc_get_coex_obj_fl(struct wlan_objmgr_psoc *psoc, + const char *func, uint32_t line) +{ + struct coex_psoc_obj *psoc_obj; + + psoc_obj = (struct coex_psoc_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_COEX); + if (!psoc_obj) { + coex_err("%s:%u, Failed to get coex psoc object", func, line); + return NULL; + } + return psoc_obj; +} + +/** + * wlan_coex_psoc_init() - API to initialize coex component + * @psoc: soc context + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_coex_psoc_init(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_coex_psoc_deinit() - API to deinitialize coex component + * @psoc: soc context + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_coex_psoc_deinit(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_coex_config_send() - private API to send coex config + * @vdev: pointer to vdev object + * @param: parameters of coex config + * + * Return: status of operation + */ +QDF_STATUS wlan_coex_config_send(struct wlan_objmgr_vdev *vdev, + struct coex_config_params *param); + +/** + * wlan_coex_config_updated() - private API to notify that coex config + * is updated. + * @vdev: pointer to vdev object + * @type: type of coex config + * + * Return: status of operation + */ +QDF_STATUS +wlan_coex_config_updated(struct wlan_objmgr_vdev *vdev, uint8_t type); + +/** + * wlan_coex_psoc_created_notification() - PSOC obj create callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is created. + * + * Return: Success or Failure + */ +QDF_STATUS wlan_coex_psoc_created_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * wlan_coex_psoc_destroyed_notification() - PSOC obj delete callback + * @psoc: PSOC object + * @arg_list: Variable argument list + * + * This callback is registered with object manager during initialization to + * get notified when the object is deleted. + * + * Return: Success or Failure + */ +QDF_STATUS wlan_coex_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * wlan_coex_psoc_set_btc_chain_mode() - private API to set BT coex chain mode + * for psoc + * @psoc: pointer to psoc object + * @val: BT coex chain mode + * + * Return : status of operation + */ +QDF_STATUS +wlan_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t val); + +/** + * wlan_coex_psoc_get_btc_chain_mode() - private API to get BT coex chain mode + * from psoc + * @psoc: pointer to psoc object + * @val: pointer to BT coex chain mode + * + * Return : status of operation + */ +QDF_STATUS +wlan_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t *val); +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/core/src/wlan_coex_main.c b/drivers/staging/qca-wifi-host-cmn/umac/coex/core/src/wlan_coex_main.c new file mode 100644 index 0000000000000000000000000000000000000000..d48b6e54eba229245d28acd55d5e4af61288b75e --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/core/src/wlan_coex_main.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains definitions for coex core functions + */ + +#include +#include +#include + +QDF_STATUS wlan_coex_psoc_created_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + struct coex_psoc_obj *psoc_obj; + QDF_STATUS status; + + psoc_obj = qdf_mem_malloc(sizeof(*psoc_obj)); + if (!psoc_obj) + return QDF_STATUS_E_NOMEM; + + /* Attach scan private date to psoc */ + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_COEX, + psoc_obj, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + coex_err("Failed to attach psoc coex component"); + qdf_mem_free(psoc_obj); + } else { + coex_debug("Coex object attach to psoc successful"); + } + + return status; +} + +QDF_STATUS wlan_coex_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + void *psoc_obj; + QDF_STATUS status; + + psoc_obj = wlan_psoc_get_coex_obj(psoc); + if (!psoc_obj) + return QDF_STATUS_E_FAILURE; + + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_COEX, + psoc_obj); + if (QDF_IS_STATUS_ERROR(status)) + coex_err("Failed to detach psoc coex component"); + + qdf_mem_free(psoc_obj); + + return status; +} + +QDF_STATUS +wlan_coex_psoc_init(struct wlan_objmgr_psoc *psoc) +{ + struct coex_psoc_obj *coex_obj; + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return QDF_STATUS_E_INVAL; + + coex_obj->btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_coex_psoc_deinit(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_coex_config_send(struct wlan_objmgr_vdev *vdev, + struct coex_config_params *param) +{ + QDF_STATUS status; + + status = tgt_send_coex_config(vdev, param); + if (QDF_IS_STATUS_ERROR(status)) + coex_err("failed to send coex config"); + + return status; +} + +QDF_STATUS +wlan_coex_config_updated(struct wlan_objmgr_vdev *vdev, uint8_t type) +{ + struct wlan_objmgr_psoc *psoc; + struct coex_psoc_obj *coex_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!vdev) { + coex_err("NULL vdev"); + return QDF_STATUS_E_INVAL; + } + + if (type >= COEX_CONFIG_TYPE_MAX) { + coex_err("config type out of range: %d", type); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + coex_err("NULL psoc"); + return QDF_STATUS_E_INVAL; + } + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return QDF_STATUS_E_INVAL; + + if (coex_obj->coex_config_updated[type]) + status = coex_obj->coex_config_updated[type](vdev); + + return status; +} + +QDF_STATUS +wlan_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t val) +{ + struct coex_psoc_obj *coex_obj; + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return QDF_STATUS_E_INVAL; + + coex_obj->btc_chain_mode = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t *val) +{ + struct coex_psoc_obj *coex_obj; + + if (!val) { + coex_err("invalid param for getting btc chain mode"); + return QDF_STATUS_E_INVAL; + } + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return QDF_STATUS_E_INVAL; + + *val = coex_obj->btc_chain_mode; + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_tgt_api.h new file mode 100644 index 0000000000000000000000000000000000000000..452ce1bc6c1d31d081a4ad295bb9c69a1042eb7c --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_tgt_api.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains coex south bound interface definitions + */ + +#ifndef _WLAN_COEX_TGT_API_H_ +#define _WLAN_COEX_TGT_API_H_ + +#ifdef FEATURE_COEX +struct coex_config_params; + +/** + * tgt_send_coex_config() - invoke target_if send coex config + * @vdev: vdev object + * @param: coex config parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS +tgt_send_coex_config(struct wlan_objmgr_vdev *vdev, + struct coex_config_params *param); +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_ucfg_api.h new file mode 100644 index 0000000000000000000000000000000000000000..2fd5a24230bfe0dca64907426e0ba087b63cecf4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_ucfg_api.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains coex north bound interface declarations + */ + +#ifndef _WLAN_COEX_UCFG_API_H_ +#define _WLAN_COEX_UCFG_API_H_ + +#include "qdf_status.h" +#include +#include +#include "qca_vendor.h" + +#define WLAN_COEX_BTC_CHAIN_MODE_SHARED QCA_BTC_CHAIN_SHARED +#define WLAN_COEX_BTC_CHAIN_MODE_SEPARATED QCA_BTC_CHAIN_SEPARATED +#define WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED 0xFF + +/** + * enum coex_config_type - coex config type definitions + * @COEX_CONFIG_BTC_CHAIN_MODE: config BT coex chain mode + * @COEX_CONFIG_TYPE_MAX: max value + */ +enum coex_config_type { + COEX_CONFIG_BTC_CHAIN_MODE, + /* keep last */ + COEX_CONFIG_TYPE_MAX, +}; + +/** + * typedef update_coex_cb() - cb to inform coex config + * @vdev: vdev pointer + * + * Return: void + */ +typedef QDF_STATUS (*update_coex_cb)(struct wlan_objmgr_vdev *vdev); + +#ifdef FEATURE_COEX +/** + * ucfg_coex_register_cfg_updated_handler() - API to register coex config + * updated handler. + * @psoc: pointer to psoc object + * @type: type of coex config + * @handler: handler to be registered + * + * Return: status of operation + */ +QDF_STATUS +ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc, + enum coex_config_type type, + update_coex_cb handler); + +/** + * ucfg_coex_psoc_set_btc_chain_mode() - API to set BT coex chain mode for psoc + * @psoc: pointer to psoc object + * @val: BT coex chain mode + * + * Return : status of operation + */ +QDF_STATUS +ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t val); + +/** + * ucfg_coex_psoc_get_btc_chain_mode() - API to get BT coex chain mode from psoc + * @psoc: pointer to psoc object + * @val: pointer to BT coex chain mode + * + * Return : status of operation + */ +QDF_STATUS +ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t *val); + +/** + * ucfg_coex_send_btc_chain_mode() - API to send BT coex config to target if + * @vdev: pointer to vdev object + * @mode: BT coex chain mode + * + * Return: status of operation + */ +QDF_STATUS +ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev, uint8_t mode); +#else +static inline QDF_STATUS +ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc, + enum coex_config_type type, + update_coex_cb handler) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t *val) +{ + if (val) + *val = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev, uint8_t mode) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_utils_api.h similarity index 50% rename from drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_tgt_api.h rename to drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_utils_api.h index 0f516ae8f4c507bccb27b7411389c4db97e8c2c6..76bb68d495848aaa973ddd5688d759574006b677 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_tgt_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/inc/wlan_coex_utils_api.h @@ -15,41 +15,49 @@ */ /** - * DOC: packet capture south bound interface declaration + * DOC: wlan_coex_utils_api.h + * + * This header file provides declaration of public APIs exposed to other UMAC + * components. */ -#ifndef _WLAN_PKT_CAPTURE_TGT_API_H -#define _WLAN_PKT_CAPTURE_TGT_API_H -#include "wlan_pkt_capture_objmgr.h" -#include "wlan_pkt_capture_main.h" -#include "wlan_pkt_capture_public_structs.h" +#ifndef _WLAN_COEX_UTILS_API_H_ +#define _WLAN_COEX_UTILS_API_H_ +#include -/** - * tgt_pkt_capture_register_ev_handler() - register pkt capture ev handler - * @vdev: pointer to vdev object +/* + * wlan_coex_init() - Coex module initialization API * * Return: QDF_STATUS */ -QDF_STATUS -tgt_pkt_capture_register_ev_handler(struct wlan_objmgr_vdev *vdev); +QDF_STATUS wlan_coex_init(void); -/** - * tgt_pkt_capture_unregister_ev_handler() - unregister pkt capture ev handler - * @vdev: pointer to vdev object +/* + * wlan_coex_deinit() - Coex module deinitialization API * * Return: QDF_STATUS */ +QDF_STATUS wlan_coex_deinit(void); + +/** + * wlan_coex_psoc_open() - Open coex component + * @psoc: soc context + * + * This function gets called when dispatcher opening. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ QDF_STATUS -tgt_pkt_capture_unregister_ev_handler(struct wlan_objmgr_vdev *vdev); +wlan_coex_psoc_open(struct wlan_objmgr_psoc *psoc); /** - * tgt_pkt_capture_send_mode() - send packet capture mode to firmware - * @vdev: pointer to vdev object - * @mode: packet capture mode + * wlan_coex_psoc_close() - Close coex component + * @psoc: soc context * - * Return: QDF_STATUS + * This function gets called when dispatcher closing. + * + * Return: QDF_STATUS_SUCCESS - in case of success */ QDF_STATUS -tgt_pkt_capture_send_mode(struct wlan_objmgr_vdev *vdev, - enum pkt_capture_mode mode); -#endif /* _WLAN_PKT_CAPTURE_TGT_API_H */ +wlan_coex_psoc_close(struct wlan_objmgr_psoc *psoc); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_tgt_api.c new file mode 100644 index 0000000000000000000000000000000000000000..4022a7c13eb5a9f2be0e75b7d0bbdc47da6dd42e --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_tgt_api.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains coex south bound interface definitions + */ + +#include +#include +#include +#include "wlan_objmgr_pdev_obj.h" + +static inline struct wlan_lmac_if_coex_tx_ops * +wlan_psoc_get_coex_txops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.tx_ops.coex_ops; +} + +static inline struct wlan_lmac_if_coex_tx_ops * +wlan_vdev_get_coex_txops(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + coex_err("NULL psoc"); + return NULL; + } + + return wlan_psoc_get_coex_txops(psoc); +} + +QDF_STATUS +tgt_send_coex_config(struct wlan_objmgr_vdev *vdev, + struct coex_config_params *param) +{ + struct wlan_lmac_if_coex_tx_ops *coex_ops; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + + if (!vdev) { + coex_err("NULL vdev"); + return QDF_STATUS_E_NULL_VALUE; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + coex_err("NULL psoc"); + return QDF_STATUS_E_NULL_VALUE; + } + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) { + coex_err("NULL pdev"); + return QDF_STATUS_E_NULL_VALUE; + } + + coex_ops = wlan_psoc_get_coex_txops(psoc); + QDF_ASSERT(coex_ops->coex_config_send); + if (coex_ops->coex_config_send) + return coex_ops->coex_config_send(pdev, param); + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_ucfg_api.c new file mode 100644 index 0000000000000000000000000000000000000000..68321ee4c1f557245235a74f28d5e9514c1884f1 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_ucfg_api.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* + * DOC: contains coex north bound interface definitions + */ + +#include +#include +#include "wmi_unified.h" + +QDF_STATUS +ucfg_coex_register_cfg_updated_handler(struct wlan_objmgr_psoc *psoc, + enum coex_config_type type, + update_coex_cb handler) +{ + struct coex_psoc_obj *coex_obj; + + if (type >= COEX_CONFIG_TYPE_MAX) { + coex_err("invalid coex type: %d", type); + return QDF_STATUS_E_INVAL; + } + + coex_obj = wlan_psoc_get_coex_obj(psoc); + if (!coex_obj) + return QDF_STATUS_E_INVAL; + + coex_obj->coex_config_updated[type] = handler; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_coex_psoc_set_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t val) +{ + return wlan_coex_psoc_set_btc_chain_mode(psoc, val); +} + +QDF_STATUS +ucfg_coex_psoc_get_btc_chain_mode(struct wlan_objmgr_psoc *psoc, uint8_t *val) +{ + return wlan_coex_psoc_get_btc_chain_mode(psoc, val); +} + +QDF_STATUS +ucfg_coex_send_btc_chain_mode(struct wlan_objmgr_vdev *vdev, uint8_t mode) +{ + struct coex_config_params param = {0}; + + if (mode != WLAN_COEX_BTC_CHAIN_MODE_SHARED && + mode != WLAN_COEX_BTC_CHAIN_MODE_SEPARATED) + return QDF_STATUS_E_INVAL; + + param.vdev_id = wlan_vdev_get_id(vdev); + param.config_type = WMI_COEX_CONFIG_BTCOEX_SEPARATE_CHAIN_MODE; + param.config_arg1 = mode; + + coex_debug("send btc chain mode %d for vdev %d", mode, param.vdev_id); + + return wlan_coex_config_send(vdev, ¶m); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_utils_api.c new file mode 100644 index 0000000000000000000000000000000000000000..32178781bac0b16a280e74efc99d5bda0706f8cb --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/coex/dispatcher/src/wlan_coex_utils_api.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_coex_utils_api.c + * + * This file provides definitions of public APIs exposed to other UMAC + * components. + */ + +#include +#include +#include + +QDF_STATUS wlan_coex_init(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_COEX, + wlan_coex_psoc_created_notification, NULL); + if (QDF_IS_STATUS_ERROR(status)) { + coex_err("Failed to register psoc create handler"); + goto fail_create_psoc; + } + + status = wlan_objmgr_register_psoc_destroy_handler( + WLAN_UMAC_COMP_COEX, + wlan_coex_psoc_destroyed_notification, NULL); + if (QDF_IS_STATUS_ERROR(status)) { + coex_err("Failed to create psoc delete handler"); + goto fail_psoc_destroy; + } + + coex_debug("coex psoc create and delete handler registered"); + return status; + +fail_psoc_destroy: + wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_COEX, + wlan_coex_psoc_created_notification, NULL); +fail_create_psoc: + return status; +} + +QDF_STATUS wlan_coex_deinit(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_unregister_psoc_destroy_handler( + WLAN_UMAC_COMP_COEX, + wlan_coex_psoc_destroyed_notification, NULL); + if (status != QDF_STATUS_SUCCESS) + coex_err("Failed to unregister psoc delete handler"); + + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_COEX, + wlan_coex_psoc_created_notification, NULL); + if (status != QDF_STATUS_SUCCESS) + coex_err("Failed to unregister psoc create handler"); + + return status; +} + +QDF_STATUS +wlan_coex_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + return wlan_coex_psoc_init(psoc); +} + +QDF_STATUS +wlan_coex_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + return wlan_coex_psoc_deinit(psoc); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_defs.h b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_defs.h index 9d0dd0e8dc11172b616094615dbe8e3faa7aad41..762cdfe70b34ea6096ac7e0d6399e9db4d2cf72c 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_defs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_defs.h @@ -35,6 +35,7 @@ #include #include "wlan_cp_stats_cmn_defs.h" #include +#include /* noise floor */ #define CP_STATS_TGT_NOISE_FLOOR_DBM (-96) @@ -54,7 +55,7 @@ struct psoc_cp_stats { void *psoc_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t psoc_cp_stats_lock; struct psoc_cmn_cp_stats *cmn_stats; - void *obj_stats; + psoc_ext_cp_stats_t *obj_stats; void (*legacy_stats_cb)(void *stats); }; @@ -67,7 +68,7 @@ struct psoc_cp_stats { */ struct pdev_cp_stats { struct wlan_objmgr_pdev *pdev_obj; - void *pdev_stats; + pdev_ext_cp_stats_t *pdev_stats; void *pdev_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t pdev_cp_stats_lock; }; @@ -80,8 +81,8 @@ struct pdev_cp_stats { * @vdev_cp_stats_lock: lock to protect object */ struct vdev_cp_stats { - struct wlan_objmgr_vdev *vdev_obj; - void *vdev_stats; + struct wlan_objmgr_vdev *vdev_obj; + vdev_ext_cp_stats_t *vdev_stats; void *vdev_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t vdev_cp_stats_lock; }; @@ -90,14 +91,12 @@ struct vdev_cp_stats { * struct peer_cp_stats - defines cp stats at peer object * @peer_obj: pointer to peer * @peer_stats: pointer to ic/mc specific stats - * @peer_adv_stats: pointer to peer adv stats * @peer_comp_priv_obj[]: component's private object pointers * @peer_cp_stats_lock: lock to protect object */ struct peer_cp_stats { - struct wlan_objmgr_peer *peer_obj; - void *peer_stats; - void *peer_adv_stats; + struct wlan_objmgr_peer *peer_obj; + peer_ext_cp_stats_t *peer_stats; void *peer_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t peer_cp_stats_lock; }; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h index ade2073f00a9f614ae42ab6f058813b73deebfa3..d06ad955d4f2734ea8efca5852acc8445c7276ab 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h @@ -33,6 +33,8 @@ #define MAX_NUM_CHAINS 2 +#define MAX_MIB_STATS 1 + #define IS_MSB_SET(__num) ((__num) & BIT(31)) #define IS_LSB_SET(__num) ((__num) & BIT(0)) @@ -44,11 +46,13 @@ * @TYPE_CONNECTION_TX_POWER: tx power was requested * @TYPE_STATION_STATS: station stats was requested * @TYPE_PEER_STATS: peer stats was requested + * @TYPE_MIB_STATS: MIB stats was requested */ enum stats_req_type { TYPE_CONNECTION_TX_POWER = 0, TYPE_STATION_STATS, TYPE_PEER_STATS, + TYPE_MIB_STATS, TYPE_MAX, }; @@ -65,6 +69,8 @@ enum stats_req_type { * @TX_RATE_HE20: HE 20 rates * @TX_RATE_HE40: HE 40 rates * @TX_RATE_HE80: HE 80 rates + * @TX_RATE_HE160: HE 160 rates + * @TX_RATE_VHT160: VHT 160 rates */ enum tx_rate_info { TX_RATE_LEGACY = 0x1, @@ -78,6 +84,8 @@ enum tx_rate_info { TX_RATE_HE20 = 0x100, TX_RATE_HE40 = 0x200, TX_RATE_HE80 = 0x400, + TX_RATE_HE160 = 0x800, + TX_RATE_VHT160 = 0x1000, }; /** @@ -155,7 +163,8 @@ struct stats_event; /** * struct request_info: details of each request * @cookie: identifier for os_if request - * @callback: callback to process os_if request when response comes. + * @u: unified data type for callback to process tx power/peer rssi/ + * station stats/mib stats request when response comes. * @vdev_id: vdev_id of request * @pdev_id: pdev_id of request * @peer_mac_addr: peer mac address @@ -167,6 +176,8 @@ struct request_info { void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie); void (*get_station_stats_cb)(struct stats_event *ev, void *cookie); + void (*get_mib_stats_cb)(struct stats_event *ev, + void *cookie); } u; uint32_t vdev_id; uint32_t pdev_id; @@ -289,7 +300,8 @@ struct peer_extd_stats { * @rx_rate: rx rate * @peer_rssi: rssi * @peer_macaddr: mac address - * @peer_extd_stats: Pointer to peer extended stats + * @extd_stats: Pointer to peer extended stats + * @adv_stats: Pointer to peer adv (extd2) stats */ struct peer_mc_cp_stats { uint32_t tx_rate; @@ -297,6 +309,7 @@ struct peer_mc_cp_stats { int8_t peer_rssi; uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; struct peer_extd_stats *extd_stats; + struct peer_adv_mc_cp_stats *adv_stats; }; /** @@ -313,6 +326,137 @@ struct peer_adv_mc_cp_stats { uint64_t rx_bytes; }; +#ifdef WLAN_FEATURE_MIB_STATS +/** + * struct dot11_counters - mib group containing attributes that are MAC counters + * @tx_frags: successfully transmitted fragments + * @group_tx_frames: transmitted group addressed frames + * @failed_cnt: MSDUs not transmitted successfully + * @rx_frags: fragments successfully received + * @group_rx_frames: group addressed frames received + * @fcs_error_cnt: FCS errors detected + * @tx_frames: frames successfully transmitted + */ +struct dot11_counters { + uint32_t tx_frags; + uint32_t group_tx_frames; + uint32_t failed_cnt; + uint32_t rx_frags; + uint32_t group_rx_frames; + uint32_t fcs_error_cnt; + uint32_t tx_frames; +}; + +/** + * struct dot11_mac_statistics - mib stats information on the operation of MAC + * @retry_cnt: retries done by mac for successful transmition + * @multi_retry_cnt: multiple retries done before successful transmition + * @frame_dup_cnt: duplicate no of frames + * @rts_success_cnt: number of CTS received (in response to RTS) + * @rts_fail_cnt: number of CTS not received (in response to RTS) + * @tx_ack_fail_cnt: number of ACK not received + */ +struct dot11_mac_statistics { + uint32_t retry_cnt; + uint32_t multi_retry_cnt; + uint32_t frame_dup_cnt; + uint32_t rts_success_cnt; + uint32_t rts_fail_cnt; + uint32_t tx_ack_fail_cnt; +}; + +/** + * dot11_qos_counters - qos mac counters + * @qos_tx_frag_cnt: transmitted QoS fragments + * @qos_failed_cnt: failed Qos fragments + * @qos_retry_cnt: Qos frames transmitted after retransmissions + * @qos_multi_retry_cnt: Qos frames transmitted after more than + * one retransmissions + * @qos_frame_dup_cnt: duplicate frames + * @qos_rts_success_cnt: number of CTS received (in response to RTS) + * @qos_rts_fail_cnt: number of CTS not received (in response to RTS) + * @tx_qos_ack_fail_cnt_up: number of ACK not received + * (in response to Qos frame) + * @qos_rx_frag_cnt: number of received MPDU of type Data + * @qos_tx_frame_cnt: number of transmitted MPDU of type Data + * @qos_discarded_frame_cnt: total Discarded MSDUs + * @qos_mpdu_rx_cnt: total received MPDU + * @qos_retries_rx_cnt: received MPDU with retry bit equal to 1 + */ +struct dot11_qos_counters { + uint32_t qos_tx_frag_cnt; + uint32_t qos_failed_cnt; + uint32_t qos_retry_cnt; + uint32_t qos_multi_retry_cnt; + uint32_t qos_frame_dup_cnt; + uint32_t qos_rts_success_cnt; + uint32_t qos_rts_fail_cnt; + uint32_t tx_qos_ack_fail_cnt_up; + uint32_t qos_rx_frag_cnt; + uint32_t qos_tx_frame_cnt; + uint32_t qos_discarded_frame_cnt; + uint32_t qos_mpdu_rx_cnt; + uint32_t qos_retries_rx_cnt; +}; + +/** + * dot11_rsna_stats - mib rsn stats + * @rm_ccmp_replays: received robust management CCMP MPDUs discarded + * by the replay mechanism + * @tkip_icv_err: TKIP ICV errors encountered + * @tkip_replays: TKIP replay errors detected + * @ccmp_decrypt_err: MPDUs discarded by the CCMP decryption algorithm + * @ccmp_replays: received CCMP MPDUs discarded by the replay mechanism + * @cmac_icv_err: MPDUs discarded by the CMAC integrity check algorithm + * @cmac_replays: MPDUs discarded by the CMAC replay errors + */ +struct dot11_rsna_stats { + uint32_t rm_ccmp_replays; + uint32_t tkip_icv_err; + uint32_t tkip_replays; + uint32_t ccmp_decrypt_err; + uint32_t ccmp_replays; + uint32_t cmac_icv_err; + uint32_t cmac_replays; +}; + +/** + * dot11_counters_group3 - dot11 group3 stats + * @tx_ampdu_cnt: transmitted AMPDUs + * @tx_mpdus_in_ampdu_cnt: number of MPDUs in the A-MPDU in transmitted AMPDUs + * @tx_octets_in_ampdu_cnt: octets in the transmitted A-MPDUs + * @ampdu_rx_cnt: received A-MPDU + * @mpdu_in_rx_ampdu_cnt: MPDUs received in the A-MPDU + * @rx_octets_in_ampdu_cnt: octets in the received A-MPDU + * @rx_ampdu_deli_crc_err_cnt: number of MPDUs delimiter with CRC error + */ +struct dot11_counters_group3 { + uint32_t tx_ampdu_cnt; + uint32_t tx_mpdus_in_ampdu_cnt; + uint64_t tx_octets_in_ampdu_cnt; + uint32_t ampdu_rx_cnt; + uint32_t mpdu_in_rx_ampdu_cnt; + uint64_t rx_octets_in_ampdu_cnt; + uint32_t rx_ampdu_deli_crc_err_cnt; +}; + +/** + * mib_stats_metrics - mib stats counters + * @mib_counters: dot11Counters group + * @mib_mac_statistics: dot11MACStatistics group + * @mib_qos_counters: dot11QoSCounters group + * @mib_rsna_stats: dot11RSNAStats group + * @mib_counters_group3: dot11CountersGroup3 group + */ +struct mib_stats_metrics { + struct dot11_counters mib_counters; + struct dot11_mac_statistics mib_mac_statistics; + struct dot11_qos_counters mib_qos_counters; + struct dot11_rsna_stats mib_rsna_stats; + struct dot11_counters_group3 mib_counters_group3; +}; +#endif + /** * struct congestion_stats_event: congestion stats event param * @vdev_id: vdev_id of the event @@ -356,6 +500,8 @@ struct chain_rssi_event { * @cca_stats: if populated indicates congestion stats * @num_summary_stats: number of summary stats * @vdev_summary_stats: if populated indicates array of summary stats per vdev + * @num_mib_stats: number of mib stats + * @mib_stats: if populated indicates array of mib stats per vdev * @num_chain_rssi_stats: number of chain rssi stats * @vdev_chain_rssi: if populated indicates array of chain rssi per vdev * @tx_rate: tx rate (kbps) @@ -375,6 +521,10 @@ struct stats_event { struct congestion_stats_event *cca_stats; uint32_t num_summary_stats; struct summary_stats_event *vdev_summary_stats; +#ifdef WLAN_FEATURE_MIB_STATS + uint32_t num_mib_stats; + struct mib_stats_metrics *mib_stats; +#endif uint32_t num_chain_rssi_stats; struct chain_rssi_event *vdev_chain_rssi; uint32_t tx_rate; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h index efbd21e7a6d55947cc6176ee88c860c4436cb89c..3a9247a113f771c570d4c8dd7b70acfc0a5b7163 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h @@ -158,11 +158,17 @@ QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc, * ucfg_mc_cp_stats_reset_pending_req() - API to reset pending request * @psoc: pointer to psoc object * @type: request to update + * @last_req: last request + * @pending: pending request present + * + * The function is an atomic operation of "reset" and "get" last request. * * Return: status of operation */ QDF_STATUS ucfg_mc_cp_stats_reset_pending_req(struct wlan_objmgr_psoc *psoc, - enum stats_req_type type); + enum stats_req_type type, + struct request_info *last_req, + bool *pending); /** * ucfg_mc_cp_stats_get_pending_req() - API to get pending request diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c index dfa70901c7a94ca3642c3ca76b65d3cf92add1b3..8c9d4726ea90019ac8d70d4eba60fa569042536f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -69,6 +69,7 @@ static void tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev = NULL; struct pdev_mc_cp_stats *pdev_mc_stats; struct pdev_cp_stats *pdev_cp_stats_priv; + bool pending = false; if (!ev->pdev_stats) return; @@ -119,8 +120,10 @@ static void tgt_mc_cp_stats_extract_tx_power(struct wlan_objmgr_psoc *psoc, if (tgt_mc_cp_stats_is_last_event(ev, TYPE_CONNECTION_TX_POWER)) { ucfg_mc_cp_stats_reset_pending_req(psoc, - TYPE_CONNECTION_TX_POWER); - if (last_req.u.get_tx_power_cb) + TYPE_CONNECTION_TX_POWER, + &last_req, + &pending); + if (last_req.u.get_tx_power_cb && pending) last_req.u.get_tx_power_cb(max_pwr, last_req.cookie); } end: @@ -137,8 +140,8 @@ static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev, struct peer_extd_stats *peer_extd_mc_stats; if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) { - cp_stats_debug("ignore self peer: %pM", - wlan_peer_get_macaddr(peer)); + cp_stats_debug("ignore self peer: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer))); return; } @@ -210,7 +213,8 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc, peer = wlan_objmgr_get_peer(psoc, last_req->pdev_id, mac_addr, WLAN_CP_STATS_ID); if (!peer) { - cp_stats_err("peer[%pM] is null", mac_addr); + cp_stats_err("peer["QDF_MAC_ADDR_FMT"] is null", + QDF_MAC_ADDR_REF(mac_addr)); goto end; } @@ -261,6 +265,7 @@ tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc *psoc, { uint8_t *peer_mac_addr; struct wlan_objmgr_peer *peer; + struct peer_mc_cp_stats *peer_mc_stats; struct peer_adv_mc_cp_stats *peer_adv_mc_stats; QDF_STATUS status = QDF_STATUS_SUCCESS; struct peer_cp_stats *peer_cp_stats_priv; @@ -282,7 +287,8 @@ tgt_mc_cp_stats_update_peer_adv_stats(struct wlan_objmgr_psoc *psoc, goto end; } wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); - peer_adv_mc_stats = peer_cp_stats_priv->peer_adv_stats; + peer_mc_stats = peer_cp_stats_priv->peer_stats; + peer_adv_mc_stats = peer_mc_stats->adv_stats; qdf_mem_copy(peer_adv_mc_stats->peer_macaddr, peer_adv_stats->peer_macaddr, @@ -341,8 +347,9 @@ tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc, peer_mc_stats->rx_rate = peer_stats->rx_rate; if (peer_stats->peer_rssi) peer_mc_stats->peer_rssi = peer_stats->peer_rssi; - cp_stats_nofl_debug("PEER STATS: peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%d", - peer_mc_stats->peer_macaddr, peer_mc_stats->tx_rate, + cp_stats_nofl_debug("PEER STATS: peer_mac="QDF_MAC_ADDR_FMT", tx_rate=%u, rx_rate=%u, peer_rssi=%d", + QDF_MAC_ADDR_REF(peer_mc_stats->peer_macaddr), + peer_mc_stats->tx_rate, peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi); wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); @@ -400,8 +407,8 @@ tgt_mc_cp_stats_update_peer_extd_stats( peer_extended_stats->rx_mc_bc_cnt; wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); - cp_stats_debug("peer_mac=%pM, rx_mc_bc_cnt=%u", - peer_extended_stats->peer_macaddr, + cp_stats_debug("peer_mac="QDF_MAC_ADDR_FMT", rx_mc_bc_cnt=%u", + QDF_MAC_ADDR_REF(peer_extended_stats->peer_macaddr), peer_extended_stats->rx_mc_bc_cnt); end: @@ -460,9 +467,9 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc, uint32_t i; QDF_STATUS status; struct request_info last_req = {0}; + bool pending = false; uint32_t selected; - if (is_station_stats) status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS, @@ -537,11 +544,48 @@ static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc, tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev); if (tgt_mc_cp_stats_is_last_event(ev, TYPE_PEER_STATS)) { - ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS); - tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req); + ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS, + &last_req, &pending); + if (pending && last_req.u.get_peer_rssi_cb) + tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req); } } +#ifdef WLAN_FEATURE_MIB_STATS +static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc, + struct stats_event *ev) +{ + QDF_STATUS status; + struct request_info last_req = {0}; + bool pending = false; + + if (!ev->mib_stats) { + cp_stats_debug("no mib stats"); + return; + } + + status = ucfg_mc_cp_stats_get_pending_req(psoc, + TYPE_MIB_STATS, &last_req); + + if (QDF_IS_STATUS_ERROR(status)) { + cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed"); + return; + } + + if (tgt_mc_cp_stats_is_last_event(ev, TYPE_MIB_STATS)) { + ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_MIB_STATS, + &last_req, &pending); + if (last_req.u.get_mib_stats_cb && pending) + last_req.u.get_mib_stats_cb(ev, last_req.cookie); + } +} +#else +static void tgt_mc_cp_stats_extract_mib_stats(struct wlan_objmgr_psoc *psoc, + struct stats_event *ev) +{ +} +#endif + static void tgt_mc_cp_stats_extract_cca_stats(struct wlan_objmgr_psoc *psoc, struct stats_event *ev) { @@ -633,7 +677,8 @@ static void tgt_mc_cp_stats_extract_vdev_summary_stats( peer = wlan_objmgr_get_peer(psoc, last_req.pdev_id, last_req.peer_mac_addr, WLAN_CP_STATS_ID); if (!peer) { - cp_stats_debug("peer is null %pM", last_req.peer_mac_addr); + cp_stats_debug("peer is null "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(last_req.peer_mac_addr)); goto end; } @@ -792,11 +837,11 @@ tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc, info.tx_rate = peer_mc_stats->tx_rate / 100; info.rx_rate = peer_mc_stats->rx_rate / 100; - if (peer_cp_stats_priv->peer_adv_stats) { + if (peer_mc_stats->adv_stats) { info.num_peer_adv_stats = 1; qdf_mem_copy(info.peer_adv_stats, - peer_cp_stats_priv->peer_adv_stats, - sizeof(peer_cp_stats_priv->peer_adv_stats)); + peer_mc_stats->adv_stats, + sizeof(peer_mc_stats->adv_stats)); } wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); @@ -819,6 +864,7 @@ static void tgt_mc_cp_stats_extract_station_stats( { QDF_STATUS status; struct request_info last_req = {0}; + bool pending = false; status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS, @@ -838,9 +884,12 @@ static void tgt_mc_cp_stats_extract_station_stats( * reset type_map bit for station stats . */ if (tgt_mc_cp_stats_is_last_event(ev, TYPE_STATION_STATS)) { - ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS); - tgt_mc_cp_stats_prepare_n_send_raw_station_stats(psoc, - &last_req); + ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS, + &last_req, + &pending); + if (pending && last_req.u.get_station_stats_cb) + tgt_mc_cp_stats_prepare_n_send_raw_station_stats( + psoc, &last_req); } } @@ -866,6 +915,9 @@ QDF_STATUS tgt_mc_cp_stats_process_stats_event(struct wlan_objmgr_psoc *psoc, if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_STATION_STATS)) tgt_mc_cp_stats_extract_station_stats(psoc, ev); + if (ucfg_mc_cp_stats_is_req_pending(psoc, TYPE_MIB_STATS)) + tgt_mc_cp_stats_extract_mib_stats(psoc, ev); + tgt_mc_cp_stats_extract_cca_stats(psoc, ev); tgt_mc_cp_send_lost_link_stats(psoc, ev); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index f527e6ba07649adcb5f11be927dec07dedbc3eb4..44c517de4c300fc777adea8f1454706b6599011d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -90,18 +90,21 @@ QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs) if (!peer_mc_stats) return QDF_STATUS_E_NOMEM; - peer_cs->peer_adv_stats = qdf_mem_malloc(sizeof - (struct peer_adv_mc_cp_stats)); - if (!peer_cs->peer_adv_stats) { + peer_mc_stats->adv_stats = + qdf_mem_malloc(sizeof(struct peer_adv_mc_cp_stats)); + + if (!peer_mc_stats->adv_stats) { qdf_mem_free(peer_mc_stats); + peer_mc_stats = NULL; return QDF_STATUS_E_NOMEM; } peer_mc_stats->extd_stats = qdf_mem_malloc(sizeof(struct peer_extd_stats)); + if (!peer_mc_stats->extd_stats) { - qdf_mem_free(peer_cs->peer_adv_stats); - peer_cs->peer_adv_stats = NULL; + qdf_mem_free(peer_mc_stats->adv_stats); + peer_mc_stats->adv_stats = NULL; qdf_mem_free(peer_mc_stats); peer_mc_stats = NULL; return QDF_STATUS_E_NOMEM; @@ -115,8 +118,8 @@ QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs) { struct peer_mc_cp_stats *peer_mc_stats = peer_cs->peer_stats; - qdf_mem_free(peer_cs->peer_adv_stats); - peer_cs->peer_adv_stats = NULL; + qdf_mem_free(peer_mc_stats->adv_stats); + peer_mc_stats->adv_stats = NULL; qdf_mem_free(peer_mc_stats->extd_stats); peer_mc_stats->extd_stats = NULL; qdf_mem_free(peer_cs->peer_stats); @@ -529,7 +532,9 @@ QDF_STATUS ucfg_mc_cp_stats_set_pending_req(struct wlan_objmgr_psoc *psoc, } QDF_STATUS ucfg_mc_cp_stats_reset_pending_req(struct wlan_objmgr_psoc *psoc, - enum stats_req_type type) + enum stats_req_type type, + struct request_info *last_req, + bool *pending) { struct psoc_mc_cp_stats *psoc_mc_stats; struct psoc_cp_stats *psoc_cp_stats_priv; @@ -547,6 +552,12 @@ QDF_STATUS ucfg_mc_cp_stats_reset_pending_req(struct wlan_objmgr_psoc *psoc, wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv); psoc_mc_stats = psoc_cp_stats_priv->obj_stats; + if (psoc_mc_stats->pending.type_map & (1 << type)) { + *last_req = psoc_mc_stats->pending.req[type]; + *pending = true; + } else { + *pending = false; + } psoc_mc_stats->pending.type_map &= ~(1 << type); qdf_mem_zero(&psoc_mc_stats->pending.req[type], sizeof(psoc_mc_stats->pending.req[type])); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs.h index d617adaee23939a2b1025670eb9f1343d8345d2b..24f5a84c959095c4ba0f6b1ea2e2b23d872448fd 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2005-2006 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -29,16 +29,18 @@ #include /* qdf_spinlock */ #include #include +#include /* qdf_str_lcopy */ #include #include "dfs_structs.h" #include "dfs_channel.h" #include "dfs_ioctl_private.h" #include /* For qdf_packed*/ -#include /* For STAILQ_ENTRY */ +#include "queue.h" /* For STAILQ_ENTRY */ #include #include #include +#include /* File Line and Submodule String */ #define FLSM(x, str) #str " : " FL(x) @@ -195,6 +197,12 @@ #define WLAN_DFS_DATA_STRUCT_LOCK_DESTROY(_dfs) \ qdf_spinlock_destroy(&(_dfs)->dfs_data_struct_lock) +/* Wrappers to call MLME radar during mode switch lock. */ +#define DFS_RADAR_MODE_SWITCH_LOCK(_dfs) \ + dfs_mlme_acquire_radar_mode_switch_lock((_dfs)->dfs_pdev_obj) +#define DFS_RADAR_MODE_SWITCH_UNLOCK(_dfs) \ + dfs_mlme_release_radar_mode_switch_lock((_dfs)->dfs_pdev_obj) + /* Mask for time stamp from descriptor */ #define DFS_TSMASK 0xFFFFFFFF /* Shift for time stamp from descriptor */ @@ -319,14 +327,8 @@ #define NUM_BINS 128 #define THOUSAND 1000 -/* ETSI11_WORLD regdmn pair id */ -#define ETSI11_WORLD_REGDMN_PAIR_ID 0x26 -#define ETSI12_WORLD_REGDMN_PAIR_ID 0x28 -#define ETSI13_WORLD_REGDMN_PAIR_ID 0x27 -#define ETSI14_WORLD_REGDMN_PAIR_ID 0x29 - /* Array offset to ETSI legacy pulse */ -#define ETSI_LEGACY_PULSE_ARR_OFFSET 2 +#define ETSI_LEGACY_PULSE_ARR_OFFSET 4 #define ETSI_RADAR_EN302_502_FREQ_LOWER 5725 #define ETSI_RADAR_EN302_502_FREQ_UPPER 5865 @@ -400,6 +402,11 @@ * in host. NOL timer can be configured by user. NOL in FW (for FO) is disabled. */ #define USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW 2 + +/* Non Agile detector IDs */ +#define DETECTOR_ID_0 0 +#define DETECTOR_ID_1 1 +/* Agile detector ID */ #define AGILE_DETECTOR_ID 2 /** @@ -688,9 +695,14 @@ struct dfs_filtertype { * @dfs_ch_flags: Channel flags. * @dfs_ch_flagext: Extended channel flags. * @dfs_ch_ieee: IEEE channel number. - * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency. - * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency applicable for 80+80MHz - * mode of operation. + * @dfs_ch_vhtop_ch_freq_seg1: IEEE Channel Center of primary segment + * @dfs_ch_vhtop_ch_freq_seg2: IEEE Channel Center applicable for 80+80MHz + * mode of operation. + * @dfs_ch_mhz_freq_seg1: Channel center frequency of primary segment in + * MHZ. + * @dfs_ch_mhz_freq_seg2: Channel center frequency of secondary segment + * in MHZ applicable only for 80+80MHZ mode of + * operation. */ struct dfs_channel { uint16_t dfs_ch_freq; @@ -699,6 +711,8 @@ struct dfs_channel { uint8_t dfs_ch_ieee; uint8_t dfs_ch_vhtop_ch_freq_seg1; uint8_t dfs_ch_vhtop_ch_freq_seg2; + uint16_t dfs_ch_mhz_freq_seg1; + uint16_t dfs_ch_mhz_freq_seg2; }; /** @@ -724,7 +738,7 @@ struct dfs_state { * @nol_dfs Back pointer to dfs object. * @nol_freq: Centre frequency. * @nol_chwidth: Event width (MHz). - * @nol_start_us: NOL start time in us. + * @nol_start_ticks: NOL start time in OS ticks. * @nol_timeout_ms: NOL timeout value in msec. * @nol_timer: Per element NOL timer. * @nol_next: Next element pointer. @@ -734,7 +748,7 @@ struct dfs_nolelem { struct wlan_dfs *nol_dfs; uint32_t nol_freq; uint32_t nol_chwidth; - uint64_t nol_start_us; + unsigned long nol_start_ticks; uint32_t nol_timeout_ms; qdf_timer_t nol_timer; struct dfs_nolelem *nol_next; @@ -889,6 +903,20 @@ struct dfs_event_log { #define FREQ_OFFSET_BOUNDARY_FOR_80MHZ 40 +/** + * struct dfs_mode_switch_defer_params - Parameters storing DFS information + * before defer, as part of HW mode switch. + * + * @radar_params: Deferred radar parameters. + * @is_cac_completed: Boolean representing CAC completion event. + * @is_radar_detected: Boolean representing radar event. + */ +struct dfs_mode_switch_defer_params { + struct radar_found_info *radar_params; + bool is_cac_completed; + bool is_radar_detected; +}; + /** * struct wlan_dfs - The main dfs structure. * @dfs_debug_mask: Current debug bitmask. @@ -931,14 +959,23 @@ struct dfs_event_log { * received. * @is_radar_during_precac: Radar found during precac. * @dfs_precac_lock: Lock to protect precac lists. - * @dfs_precac_enable: Enable the precac. * @dfs_precac_secondary_freq: Second segment freq for precac. - * @dfs_precac_primary_freq: Primary freq. + * Applicable to only legacy chips. + * @dfs_precac_secondary_freq_mhz: Second segment freq in MHZ for precac. + * Applicable to only legacy chips. + * @dfs_precac_primary_freq: PreCAC Primary freq applicable only to + * legacy chips. + * @dfs_precac_primary_freq_mhz: PreCAC Primary freq in MHZ applicable only + * to legacy chips. * @dfs_defer_precac_channel_change: Defer precac channel change. * @dfs_precac_inter_chan: Intermediate non-DFS channel used while * doing precac. + * @dfs_precac_inter_chan_freq: Intermediate non-DFS freq used while + * doing precac. * @dfs_autoswitch_des_chan: Desired channel which has to be used * after precac. + * @dfs_autoswitch_des_chan_freq: Desired freq which has to be used + * after precac. * @dfs_autoswitch_des_mode: Desired PHY mode which has to be used * after precac. * @dfs_pre_cac_timeout_channel_change: Channel change due to precac timeout. @@ -979,13 +1016,14 @@ struct dfs_event_log { * not be re-done. * @dfs_precac_timeout_override: Overridden precac timeout. * @dfs_num_precac_freqs: Number of PreCAC VHT80 frequencies. - * @dfs_precac_required_list: PreCAC required list. - * @dfs_precac_done_list: PreCAC done list. - * @dfs_precac_nol_list: PreCAC NOL List. + * @dfs_precac_list: PreCAC list (contains individual trees). + * @dfs_precac_chwidth: PreCAC channel width enum. * @dfs_curchan: DFS current channel. + * @dfs_prevchan: DFS previous channel. * @dfs_cac_started_chan: CAC started channel. * @dfs_pdev_obj: DFS pdev object. * @dfs_is_offload_enabled: Set if DFS offload enabled. + * @dfs_agile_precac_freq_mhz: Freq in MHZ configured on Agile DFS engine. * @dfs_use_nol: Use the NOL when radar found(default: TRUE) * @dfs_nol_lock: Lock to protect nol list. * @tx_leakage_threshold: Tx leakage threshold for dfs. @@ -1031,8 +1069,21 @@ struct dfs_event_log { * @dfs_nol_ie_bitmap: The bitmap of radar affected subchannels * in the current channel list * to be sent in NOL IE with RCSA. - * @dfs_is_rcsa_ie_sent To send or to not send RCSA IE. - * @dfs_is_nol_ie_sent To send or to not send NOL IE. + * @dfs_is_rcsa_ie_sent: To send or to not send RCSA IE. + * @dfs_is_nol_ie_sent: To send or to not send NOL IE. + * @dfs_legacy_precac_ucfg: User configuration for legacy preCAC in + * partial offload chipsets. + * @dfs_agile_precac_ucfg: User configuration for agile preCAC. + * @dfs_fw_adfs_support_non_160: Target Agile DFS support for non-160 BWs. + * @dfs_fw_adfs_support_160: Target Agile DFS support for 160 BW. + * @dfs_allow_hw_pulses: Allow/Block HW pulses. When synthetic + * pulses are injected, the HW pulses should + * be blocked and this variable should be + * false so that HW pulses and synthetic + * pulses do not get mixed up. + * defer timer running. + * @dfs_defer_params: DFS deferred event parameters (allocated + * only for the duration of defer alone). */ struct wlan_dfs { uint32_t dfs_debug_mask; @@ -1079,13 +1130,27 @@ struct wlan_dfs { bool is_radar_during_precac; qdf_spinlock_t dfs_precac_lock; bool dfs_precac_enable; +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_precac_secondary_freq; uint8_t dfs_precac_primary_freq; +#endif +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_precac_secondary_freq_mhz; + uint16_t dfs_precac_primary_freq_mhz; +#endif uint8_t dfs_defer_precac_channel_change; #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_precac_inter_chan; uint8_t dfs_autoswitch_des_chan; +#endif enum wlan_phymode dfs_autoswitch_des_mode; +#endif +#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_precac_inter_chan_freq; + uint16_t dfs_autoswitch_des_chan_freq; +#endif #endif uint8_t dfs_pre_cac_timeout_channel_change:1; qdf_timer_t wlan_dfs_task_timer; @@ -1126,22 +1191,22 @@ struct wlan_dfs { #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) uint8_t dfs_disable_radar_marking; #endif - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list; - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list; - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list; - -#ifdef QCA_SUPPORT_ETSI_PRECAC_DFS - TAILQ_HEAD(, dfs_etsi_precac_entry) dfs_etsiprecac_required_list; - TAILQ_HEAD(, dfs_etsi_precac_entry) dfs_etsiprecac_done_list; -#endif + TAILQ_HEAD(, dfs_precac_entry) dfs_precac_list; + enum phy_ch_width dfs_precac_chwidth; struct dfs_channel *dfs_curchan; + struct dfs_channel *dfs_prevchan; struct dfs_channel dfs_cac_started_chan; struct wlan_objmgr_pdev *dfs_pdev_obj; struct dfs_soc_priv_obj *dfs_soc_obj; #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) uint8_t dfs_psoc_idx; +#endif +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_agile_precac_freq; +#endif +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_agile_precac_freq_mhz; #endif bool dfs_is_offload_enabled; int dfs_use_nol; @@ -1175,7 +1240,14 @@ struct wlan_dfs { uint8_t dfs_nol_ie_bitmap; bool dfs_is_rcsa_ie_sent; bool dfs_is_nol_ie_sent; - bool dfs_agile_precac_enable; + uint8_t dfs_legacy_precac_ucfg:1, + dfs_agile_precac_ucfg:1, + dfs_fw_adfs_support_non_160:1, + dfs_fw_adfs_support_160:1; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) + bool dfs_allow_hw_pulses; +#endif + struct dfs_mode_switch_defer_params dfs_defer_params; }; #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) @@ -1206,6 +1278,7 @@ struct wlan_dfs_priv { * @dfs_precac_timer: agile precac timer * @dfs_precac_timer_running: precac timer running flag * @ocac_status: Off channel CAC complete status + * @dfs_nol_ctx: dfs NOL data for all radios. */ struct dfs_soc_priv_obj { struct wlan_objmgr_psoc *psoc; @@ -1220,6 +1293,7 @@ struct dfs_soc_priv_obj { bool precac_state_started; bool ocac_status; #endif + struct dfsreq_nolinfo *dfs_psoc_nolinfo; }; /** @@ -1951,9 +2025,23 @@ void dfs_detach(struct wlan_dfs *dfs); * @prevchan_ieee: Prevchan number. * @prevchan_flags: Prevchan flags. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_cac_valid_reset(struct wlan_dfs *dfs, uint8_t prevchan_ieee, uint32_t prevchan_flags); +#endif + +/** + * dfs_cac_valid_reset_for_freq() - Cancels the dfs_cac_valid_timer timer. + * @dfs: Pointer to wlan_dfs structure. + * @prevchan_chan: Prevchan frequency + * @prevchan_flags: Prevchan flags. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_cac_valid_reset_for_freq(struct wlan_dfs *dfs, + uint16_t prevchan_freq, + uint32_t prevchan_flags); +#endif /** * dfs_cac_stop() - Clear the AP CAC timer. @@ -1973,39 +2061,6 @@ void dfs_cancel_cac_timer(struct wlan_dfs *dfs); */ void dfs_start_cac_timer(struct wlan_dfs *dfs); -/** - * dfs_is_subset_channel() - Check if the new_chan is subset of the old_chan. - * @dfs: Pointer to wlan_dfs structure. - * @old_chan: Pointer to old channel. - * @new_chan: Pointer to new channel. - * - * Return: true if the new channel is subset of or same as the old channel, - * else false. - */ -bool dfs_is_subset_channel(struct wlan_dfs *dfs, - struct dfs_channel *old_chan, - struct dfs_channel *new_chan); - -/** - * dfs_is_curchan_subset_of_cac_started_chan() - Check if the dfs current - * channel is subset of cac started channel. - * @dfs: Pointer to wlan_dfs structure. - * - * If the current channel and the cac_started_chan is same or - * if the current channel is subset of the cac_started_chan then - * this function returns true. - * - * Return: true if current channel is same or subset of cac started channel, - * else false. - */ -bool dfs_is_curchan_subset_of_cac_started_chan(struct wlan_dfs *dfs); - -/** - * dfs_clear_cac_started_chan() - Clear dfs cac started channel. - * @dfs: Pointer to wlan_dfs structure. - */ -void dfs_clear_cac_started_chan(struct wlan_dfs *dfs); - /** * dfs_set_update_nol_flag() - Sets update_nol flag. * @dfs: Pointer to wlan_dfs structure. @@ -2160,16 +2215,10 @@ int dfs_get_debug_info(struct wlan_dfs *dfs, void *data); /** - * dfs_cac_timer_init() - Initialize cac timers. + * dfs_cac_timer_attach() - Initialize cac timers. * @dfs: Pointer to wlan_dfs structure. */ -void dfs_cac_timer_init(struct wlan_dfs *dfs); - -/** - * dfs_cac_attach() - Initialize dfs cac variables. - * @dfs: Pointer to wlan_dfs structure. - */ -void dfs_cac_attach(struct wlan_dfs *dfs); +void dfs_cac_timer_attach(struct wlan_dfs *dfs); /** * dfs_cac_timer_reset() - Cancel dfs cac timers. @@ -2345,6 +2394,7 @@ static inline bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency1. * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency2. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_set_current_channel(struct wlan_dfs *dfs, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -2352,7 +2402,33 @@ void dfs_set_current_channel(struct wlan_dfs *dfs, uint8_t dfs_ch_ieee, uint8_t dfs_ch_vhtop_ch_freq_seg1, uint8_t dfs_ch_vhtop_ch_freq_seg2); +#endif +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_set_current_channel_for_freq() - Set DFS current channel. + * @dfs: Pointer to wlan_dfs structure. + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_flags: Channel flags. + * @dfs_chan_flagext: Extended channel flags. + * @dfs_chan_ieee: IEEE channel number. + * @dfs_chan_vhtop_freq_seg1: Channel Center frequency1. + * @dfs_chan_vhtop_freq_seg2: Channel Center frequency2. + * @dfs_chan_mhz_freq_seg1: Channel center frequency of primary segment in MHZ. + * @dfs_chan_mhz_freq_seg2: Channel center frequency of secondary segment in MHZ + * applicable only for 80+80MHZ mode of operation. + */ +void dfs_set_current_channel_for_freq(struct wlan_dfs *dfs, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2); + +#endif /** * dfs_get_nol_chfreq_and_chwidth() - Get channel freq and width from NOL list. * @dfs_nol: Pointer to NOL channel entry. @@ -2587,16 +2663,20 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, uint8_t nol_ie_bitmap); /** - * dfs_check_for_cac_start() - Check for DFS CAC start conditions. + * dfs_is_cac_required() - Check if DFS CAC is required for the current channel. * @dfs: Pointer to wlan_dfs structure. + * @cur_chan: Pointer to current channel of dfs_channel structure. + * @prev_chan: Pointer to previous channel of dfs_channel structure. * @continue_current_cac: If AP can start CAC then this variable indicates * whether to continue with the current CAC or restart the CAC. This variable * is valid only if this function returns true. * - * Return: true if AP can start or continue the current CAC, else false. + * Return: true if AP requires CAC or can continue current CAC, else false. */ -bool dfs_check_for_cac_start(struct wlan_dfs *dfs, - bool *continue_current_cac); +bool dfs_is_cac_required(struct wlan_dfs *dfs, + struct dfs_channel *cur_chan, + struct dfs_channel *prev_chan, + bool *continue_current_cac); /** * dfs_task_testtimer_reset() - stop dfs test timer. @@ -2649,4 +2729,103 @@ static inline int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs, #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs); #endif + +/** + * dfs_reset_agile_config() - Reset the ADFS config variables. + * @dfs: Pointer to dfs_soc_priv_obj. + */ +#ifdef QCA_SUPPORT_AGILE_DFS +void dfs_reset_agile_config(struct dfs_soc_priv_obj *dfs_soc); +#endif + +/** + * dfs_reinit_timers() - Reinit timers in DFS. + * @dfs: Pointer to wlan_dfs. + */ +int dfs_reinit_timers(struct wlan_dfs *dfs); + +/** + * dfs_reset_dfs_prevchan() - Reset DFS previous channel structure. + * @dfs: Pointer to wlan_dfs object. + * + * Return: None. + */ +void dfs_reset_dfs_prevchan(struct wlan_dfs *dfs); + +/** + * dfs_init_tmp_psoc_nol() - Init temporary psoc NOL structure. + * @dfs: Pointer to wlan_dfs object. + * @num_radios: Num of radios in the PSOC. + * + * Return: void. + */ +void dfs_init_tmp_psoc_nol(struct wlan_dfs *dfs, uint8_t num_radios); + +/** + * dfs_deinit_tmp_psoc_nol() - De-init temporary psoc NOL structure. + * @dfs: Pointer to wlan_dfs object. + * + * Return: void. + */ +void dfs_deinit_tmp_psoc_nol(struct wlan_dfs *dfs); + +/** + * dfs_save_dfs_nol_in_psoc() - Save NOL data of given pdev. + * @dfs: Pointer to wlan_dfs object. + * @pdev_id: The pdev ID which will have the NOL data. + * @low_5ghz_freq: The low 5GHz frequency value of the target pdev id. + * @high_5ghz_freq: The high 5GHz frequency value of the target pdev id. + * + * Based on the frequency of the NOL channel, copy it to the target pdev_id + * structure in psoc. + * + * Return: void. + */ +void dfs_save_dfs_nol_in_psoc(struct wlan_dfs *dfs, + uint8_t pdev_id, + uint16_t low_5ghz_freq, + uint16_t high_5ghz_freq); + +/** + * dfs_reinit_nol_from_psoc_copy() - Reinit saved NOL data to corresponding + * DFS object. + * @dfs: Pointer to wlan_dfs object. + * @pdev_id: pdev_id of the given dfs object. + * + * Return: void. + */ +void dfs_reinit_nol_from_psoc_copy(struct wlan_dfs *dfs, uint8_t pdev_id); + +/** + * dfs_is_hw_mode_switch_in_progress() - Check if HW mode switch in progress. + * @dfs: Pointer to wlan_dfs object. + * + * Return: True if mode switch is in progress, else false. + */ +bool dfs_is_hw_mode_switch_in_progress(struct wlan_dfs *dfs); + +/** + * dfs_start_mode_switch_defer_timer() - start mode switch defer timer. + * @dfs: Pointer to wlan_dfs object. + * + * Return: void. + */ +void dfs_start_mode_switch_defer_timer(struct wlan_dfs *dfs); + +/** + * dfs_complete_deferred_tasks() - Process mode switch completion event and + * handle deffered tasks. + * @dfs: Pointer to wlan_dfs object. + * + * Return: void. + */ +void dfs_complete_deferred_tasks(struct wlan_dfs *dfs); + +/** + * dfs_process_cac_completion() - Process DFS CAC completion event. + * @dfs: Pointer to wlan_dfs object. + * + * Return: void. + */ +void dfs_process_cac_completion(struct wlan_dfs *dfs); #endif /* _DFS_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_etsi_precac.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_etsi_precac.h deleted file mode 100644 index 59c449b9bd7d1dc2b4e3d1142f2b5245cb23be20..0000000000000000000000000000000000000000 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_etsi_precac.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * DOC: This file has ETSI Pre-CAC DFS APIs. - */ - -#ifndef _DFS_ETSI_PRECAC_H_ -#define _DFS_ETSI_PRECAC_H_ - -#include "dfs.h" - -#define VHT160_IEEE_FREQ_DIFF 16 - -/** - * struct dfs_etsi_precac_entry - PreCAC entry for ETSI domain - * @pe_list: ETSI PreCAC entry. - * @ieee: channel number - * @etsi_caclst_ticks start tick, OS speicfic. - * @dfs: Pointer to wlan_dfs structure. - */ -struct dfs_etsi_precac_entry { - TAILQ_ENTRY(dfs_etsi_precac_entry) pe_list; - uint16_t ieee; - unsigned long etsi_caclst_ticks; - struct wlan_dfs *dfs; -}; - -/** - * dfs_print_etsi_precaclists() - Print etsi precac list. - * @dfs: Pointer to wlan_dfs structure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_print_etsi_precaclists(struct wlan_dfs *dfs); -#else -static inline void dfs_print_etsi_precaclists(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_reset_etsi_precac_lists() - Resets the ETSI precac lists. - * @dfs: Pointer to wlan_dfs structure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_reset_etsi_precac_lists(struct wlan_dfs *dfs); -#else -static inline void dfs_reset_etsi_precac_lists(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_reset_etsiprecaclists()- Clears and initializes etsi_precac_required_list - * etsi_precac_done_list. - * - * @dfs: Pointer to wlan_dfs structure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_reset_etsiprecaclists(struct wlan_dfs *dfs); -#else -static inline void dfs_reset_etsiprecaclists(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_add_to_etsi_precac_required_list()- Add channel to ETSI PreCAC Required - * list. - * - * @dfs: Pointer to wlan_dfs structure. - * @chan: Pointer to channel to be added to ETSI PreCAC Required List. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_add_to_etsi_precac_required_list(struct wlan_dfs *dfs, uint8_t *chan); -#else -static inline void dfs_add_to_etsi_precac_required_list(struct wlan_dfs *dfs, - uint8_t *chan) -{ -} -#endif - -/** - * dfs_deinit_etsi_precac_list() - Clears the etsi precac list. - * @dfs: Pointer to wlan_dfs dtructure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_deinit_etsi_precac_list(struct wlan_dfs *dfs); -#else -static inline void dfs_deinit_etsi_precac_list(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_etsi_precac_attach() - Initialize ETSI precac variables. - * @dfs: Pointer to DFS structure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_etsi_precac_attach(struct wlan_dfs *dfs); -#else -static inline void dfs_etsi_precac_attach(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_etsi_precac_detach() - Free etsi_precac memory. - * @dfs: Pointer to wlan_dfs dtructure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_etsi_precac_detach(struct wlan_dfs *dfs); -#else -static inline void dfs_etsi_precac_detach(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_init_etsiprecac_list() - Init ETSI precac list. - * @dfs: Pointer to wlan_dfs dtructure. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_init_etsi_precac_list(struct wlan_dfs *dfs); -#else -static inline void dfs_init_etsi_precac_list(struct wlan_dfs *dfs) -{ -} -#endif - -/** - * dfs_is_subchan_in_etsi_precac_done_list() - Is HT20 sub channel - * in etsi precac done list. - * @dfs: Pointer to wlan_dfs structure. - * @channel: HT20 sub channel - * - * Return: If subchannel present in precac done list return 1. - * Otherwise return 0 - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -int dfs_is_subchan_in_etsi_precac_done_list(struct wlan_dfs *dfs, - uint8_t channel); -#else -static inline int dfs_is_subchan_in_etsi_precac_done_list(struct wlan_dfs *dfs) -{ - return 0; -} -#endif -/** - * dfs_is_etsi_precac_done() - Is precac done. - * @dfs: Pointer to wlan_dfs structure. - * - * Return: If precac already done in channel, return 1. Otherwise return 0. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -bool dfs_is_etsi_precac_done(struct wlan_dfs *dfs); -#else -static inline bool dfs_is_etsi_precac_done(struct wlan_dfs *dfs) -{ - return false; -} -#endif - -/** - * dfs_mark_etsi_precac_dfs() - Mark the precac channel as radar for ETSI. - * @dfs: Pointer to wlan_dfs structure. - * @channels: List of HT20 primary channels - * @num_channels: Number of HT20 primary channels - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_mark_etsi_precac_dfs(struct wlan_dfs *dfs, - uint8_t *channels, uint8_t num_channels); -#else -static inline void dfs_mark_etsi_precac_dfs(struct wlan_dfs *dfs, - uint8_t *channels, - uint8_t num_channels) -{ -} -#endif - -/** - * dfs_add_chan_to_etsi_done_list() - Add subchannel to ETSI CAC done list, - * if present in ETSI CAC required list - * @dfs: Pointer to wlan_dfs structure. - * @channel: HT20 primary channel - * - * Return: If channel added to ETSI CAC done list, return 1. Otherwise return 0. - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -int dfs_add_chan_to_etsi_done_list(struct wlan_dfs *dfs, uint8_t channel); -#else -static inline int dfs_add_chan_to_etsi_done_list(struct wlan_dfs *dfs, - uint8_t channel) -{ - return 0; -} -#endif - -/** - * dfs_add_to_etsi_precac_done_list() - Add channel to ETSI CAC done list - * @curchan: Pointer to dfs_channel structure. - * - */ -#if defined(QCA_SUPPORT_ETSI_PRECAC_DFS) -void dfs_add_to_etsi_precac_done_list(struct wlan_dfs *dfs); -#else -static inline void dfs_add_to_etsi_precac_done_list(struct wlan_dfs *dfs) -{ -} -#endif - -#endif /* _DFS_ETSI_PRECAC_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_filter_init.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_filter_init.h index 10ac388975707fed640abf1b4a62a9620e5d530f..5b86d7a104fb77e5fc2e84fe471abe94a5c2c6b1 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_filter_init.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_filter_init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -88,26 +88,12 @@ static inline void dfs_main_timer_detach(struct wlan_dfs *dfs) } #endif -#ifdef CONFIG_WIN -#if DA_SUPPORT -#if defined(WLAN_DFS_DIRECT_ATTACH) +#if defined(DA_SUPPORT) && defined(WLAN_DFS_DIRECT_ATTACH) void dfs_get_da_radars(struct wlan_dfs *dfs); #else static inline void dfs_get_da_radars(struct wlan_dfs *dfs) { } #endif -#else -#define dfs_get_da_radars(dfs) /**/ -#endif /* _DA_SUPPORT_ */ -#else -#if defined(WLAN_DFS_DIRECT_ATTACH) -void dfs_get_da_radars(struct wlan_dfs *dfs); -#else -static inline void dfs_get_da_radars(struct wlan_dfs *dfs) -{ -} -#endif -#endif /* _CONFIG_WIN_ */ #endif /* _DFS_FILTER_INIT_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_internal.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_internal.h index 07ff4b1670e43a84a7d1e91e6ff5c017b8d868bf..33bcb7514375d089b92992edda3f2a0a6d404f3f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for @@ -36,6 +36,7 @@ * @DFS_MKK4_DOMAIN: MKK domain * @DFS_CN_DOMAIN: China domain * @DFS_KR_DOMAIN: Korea domain + * @DFS_MKKN_DOMAIN: MKKN domain * @DFS_UNDEF_DOMAIN: Undefined domain */ enum DFS_DOMAIN { @@ -45,6 +46,7 @@ enum DFS_DOMAIN { DFS_MKK4_DOMAIN = 3, DFS_CN_DOMAIN = 4, DFS_KR_DOMAIN = 5, + DFS_MKKN_DOMAIN = 6, DFS_UNDEF_DOMAIN }; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_partial_offload_radar.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_partial_offload_radar.h index 40b94f6a8b6769767ceac6c14cc17c3ea2bd2293..4fb8f7ec0dfbb54c6894bead3ccdba70c2a338a5 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_partial_offload_radar.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_partial_offload_radar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -197,4 +197,56 @@ static inline void dfs_false_radarfound_reset_vars(struct wlan_dfs *dfs) { } #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * dfs_allow_hw_pulses() - Set or unset dfs_allow_hw_pulses + * which allow or disallow HW pulses. + * @dfs: Pointer to DFS pdev object. + * @allow_hw_pulses: allow/disallow synthetic pulse detection true/false. + * + * Return: void + */ +void dfs_allow_hw_pulses(struct wlan_dfs *dfs, bool allow_hw_pulses); +#else +static inline void dfs_allow_hw_pulses(struct wlan_dfs *dfs, + bool allow_hw_pulses) +{ +} +#endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * dfs_is_hw_pulses_allowed() - Check if HW pulses are allowed or not. + * @pdev: Pointer to DFS pdev object. + * + * Return: bool + */ +bool dfs_is_hw_pulses_allowed(struct wlan_dfs *dfs); +#else +static inline bool dfs_is_hw_pulses_allowed(struct wlan_dfs *dfs) +{ + return true; +} +#endif + +/** + * dfs_inject_synthetic_pulse_sequence() - Inject the synthetic pulse to the + * phyerror processing algorithm. + * @dfs: Pointer to wlan_dfs structure. + * @buf: Pointer to buffer of pulses. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +QDF_STATUS dfs_inject_synthetic_pulse_sequence(struct wlan_dfs *dfs, + unsigned char *buf); +#else +static inline +QDF_STATUS dfs_inject_synthetic_pulse_sequence(struct wlan_dfs *dfs, + unsigned char *buf) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_DFS_PARTIAL_OFFLOAD && WLAN_DFS_SYNTHETIC_RADAR */ #endif /* _DFS_PARTIAL_OFFLOAD_RADAR_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_phyerr_tlv.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_phyerr_tlv.h index 08500d023da12691c60d769e9dde72dc4b20276b..0fad819bde94ff3131e571b958b5c0b46cae461a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_phyerr_tlv.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_phyerr_tlv.h @@ -81,11 +81,6 @@ #define RADAR_REPORT_PULSE_SUBCHAN_MASK 0x00FF0000 #define RADAR_REPORT_PULSE_SUBCHAN_MASK_S 16 -#define RADAR_REPORT_PULSE_REG_4 0x03 - -#define RADAR_REPORT_PULSE_RSSI 0x3FFC0000 -#define RADAR_REPORT_PULSE_RSSI_S 18 - #define RADAR_REPORT_PULSE_TSF_OFFSET 0x0000FF00 #define RADAR_REPORT_PULSE_TSF_OFFSET_S 8 diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_process_radar_found_ind.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_process_radar_found_ind.h index 2017742340e26edfb4dea4316867876067ef7542..d41cc034a9eb3f48ca37f06978b0305148389582 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_process_radar_found_ind.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_process_radar_found_ind.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -69,18 +69,29 @@ #define DFS_CHIRP_OFFSET 10 /* second segment freq offset */ #define DFS_160MHZ_SECOND_SEG_OFFSET 40 +/*Primary segment id is 0 */ +#define PRIMARY_SEG 0 /* Frequency offset indices */ #define CENTER_CH 0 #define LEFT_CH 1 #define RIGHT_CH 2 +#ifdef CONFIG_CHAN_NUM_API /* Next channel number offset's from center channel number */ #define DFS_5GHZ_NEXT_CHAN_OFFSET 2 #define DFS_5GHZ_2ND_CHAN_OFFSET 6 #define DFS_5GHZ_3RD_CHAN_OFFSET 10 #define DFS_5GHZ_4TH_CHAN_OFFSET 14 - +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/* Next channel frequency offsets from center channel frequency */ +#define DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET 10 +#define DFS_5GHZ_2ND_CHAN_FREQ_OFFSET 30 +#define DFS_5GHZ_3RD_CHAN_FREQ_OFFSET 50 +#define DFS_5GHZ_4TH_CHAN_FREQ_OFFSET 70 +#endif /* Max number of bonding channels in 160 MHz segment */ #define NUM_CHANNELS_160MHZ 8 @@ -138,17 +149,41 @@ void dfs_radarfound_action_generic(struct wlan_dfs *dfs, uint8_t seg_id); /** * dfs_get_bonding_channels() - Get bonding channels. - * @dfs: Pointer to wlan_dfs structure. - * @curchan: Pointer to dfs_channels to know width and primary channel. - * @segment_id: Segment id, useful for 80+80/160 MHz operating band. - * @channels: Pointer to save radar affected channels. + * @dfs: Pointer to wlan_dfs structure. + * @curchan: Pointer to dfs_channels to know width and primary channel. + * @segment_id: Segment id, useful for 80+80/160 MHz operating band. + * @detector_id: Detector id, used to find if radar is detected on + * Agile detector. + * @channels: Pointer to save radar affected channels. * * Return: Number of channels. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, struct dfs_channel *curchan, uint32_t segment_id, + uint8_t detector_id, uint8_t *channels); +#endif + +/** + * dfs_get_bonding_channels_for_freq() - Get bonding channels. + * @dfs: Pointer to wlan_dfs structure. + * @curchan: Pointer to dfs_channels to know width and primary channel. + * @segment_id: Segment id, useful for 80+80/160 MHz operating band. + * @detector_id: Detector id, used to find if radar is detected on + * Agile detector. + * @freq_list: Pointer to save radar affected channel's frequency. + * + * Return: Number of channels. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t dfs_get_bonding_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t detector_id, + uint16_t *freq_list); +#endif /** * dfs_get_bonding_channels_without_seg_info() - Get bonding channels in chan @@ -157,8 +192,24 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, * * Return: number of sub channels in the input channel. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, uint8_t *channels); +#endif + +/** + * dfs_get_bonding_channel_without_seg_info_for_freq() - Get bonding channels + * in chan. + * @chan: Pointer to dfs_channel structure. + * @freq_list: channel array holding list of bonded channel's frequency. + * + * Return: number of sub channels in the input channel. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t +dfs_get_bonding_channel_without_seg_info_for_freq(struct dfs_channel *chan, + uint16_t *freq_list); +#endif /** * dfs_set_nol_subchannel_marking() - Set or unset NOL subchannel marking. diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_random_chan_sel.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_random_chan_sel.h index 88d8cbbd079ee2f1a3273acd73e5266d66997d37..bf03f79856fed011045ad761676f03fe36d6408c 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_random_chan_sel.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_random_chan_sel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -69,20 +69,29 @@ /* Next 5GHz channel number */ #define DFS_80_NUM_SUB_CHANNEL 4 +/* Next 5GHz channel freq offset */ +#define DFS_80_NUM_SUB_CHANNEL_FREQ 20 + /* Next 5GHz channel number */ #define DFS_NEXT_5GHZ_CHANNEL 4 +/* Next 5GHz channel number */ +#define DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET 20 + /* Number of 20MHz channels in bitmap */ #define DFS_MAX_20M_SUB_CH 8 +/* Frequency difference between 80+80 MHz */ +#define DFS_80P80M_FREQ_DIFF 40 + /* Number of 80MHz channels in 5GHz band */ #define DFS_MAX_80MHZ_BANDS 6 /* Start channel and center channel diff in 80Mhz */ #define DFS_80MHZ_START_CENTER_CH_DIFF 6 -/* Max number of channels */ -#define DFS_MAX_NUM_CHAN 128 +/* Start channel and center channel freq diff in 80Mhz */ +#define DFS_80MHZ_START_CENTER_CH_FREQ_DIFF 30 /* Bitmap mask for 80MHz */ #define DFS_80MHZ_MASK 0x0F @@ -102,6 +111,11 @@ /* Max 2.4 GHz channel number */ #define DFS_MAX_24GHZ_CHANNEL 14 +/* Max 2.4 GHz channel frequency */ +#define DFS_MAX_24GHZ_CHANNEL_FREQ 2484 + +/* Adjacent weather radar channel frequency */ +#define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ 5580 /* Max valid channel number */ #define MAX_CHANNEL_NUM 184 @@ -121,20 +135,30 @@ #endif #define DFS_IS_CHANNEL_WEATHER_RADAR(_f) (((_f) >= 5600) && ((_f) <= 5650)) +#ifdef CONFIG_CHAN_NUM_API #define DFS_IS_CHAN_JAPAN_INDOOR(_ch) (((_ch) >= 36) && ((_ch) <= 64)) #define DFS_IS_CHAN_JAPAN_W53(_ch) (((_ch) >= 52) && ((_ch) <= 64)) #define DFS_IS_CHAN_JAPAN_OUTDOOR(_ch) (((_ch) >= 100) && ((_ch) <= 140)) +#endif + +#ifdef CONFIG_CHAN_FREQ_API +#define DFS_IS_CHAN_JAPAN_INDOOR_FREQ(_ch)(((_ch) >= 5180) && ((_ch) <= 5320)) +#define DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(_ch)(((_ch) >= 5500) && ((_ch) <= 5700)) +#define DFS_IS_CHAN_JAPAN_W53_FREQ(_ch) (((_ch) >= 5260) && ((_ch) <= 5320)) +#endif /** * struct chan_bonding_info - for holding channel bonding bitmap * @chan_map: channel map * @rsvd: reserved * @start_chan: start channel + * @start_chan_freq: start channel frequency in MHZ. */ struct chan_bonding_info { uint8_t chan_map:4; uint8_t rsvd:4; uint8_t start_chan; + uint16_t start_chan_freq; }; /** @@ -154,6 +178,7 @@ struct chan_bonding_bitmap { */ struct dfs_tx_leak_info { uint8_t leak_chan; + uint16_t leak_chan_freq; uint32_t leak_lvl; }; @@ -164,7 +189,9 @@ struct dfs_tx_leak_info { */ struct dfs_matrix_tx_leak_info { uint8_t channel; - struct dfs_tx_leak_info chan_matrix[CHAN_ENUM_144 - CHAN_ENUM_36 + 1]; + uint16_t channel_freq; + struct dfs_tx_leak_info chan_matrix[CHAN_ENUM_5720 - + CHAN_ENUM_5180 + 1]; }; #endif @@ -181,10 +208,32 @@ struct dfs_matrix_tx_leak_info { * * Return: QDF_STATUS */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, uint8_t temp_ch_lst_sz, uint8_t *temp_ch_lst); +#endif + +/** + * dfs_mark_leaking_chan_for_freq() - to mark channel leaking in to nol + * @dfs: dfs handler. + * @ch_width: channel width + * @temp_chan_lst_sz: the target channel list size. + * @temp_freq_lst: the target frequency channel list + * + * This function removes the channels from temp channel list that + * (if selected as target channel) will cause leakage in one of + * the NOL channels + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst); +#endif /** * dfs_prepare_random_channel() - This function picks a random channel from @@ -205,6 +254,7 @@ QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, * * Return: channel number, else zero. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *ch_list, uint32_t ch_count, @@ -213,3 +263,34 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, uint8_t dfs_region, struct dfs_acs_info *acs_info); +#endif + +/** + * dfs_prepare_random_channel() - This function picks a random channel from + * the list of available channels. + * @dfs: dfs handler. + * @chan_list: channel list. + * @ch_count: Number of channels in given list. + * @flags: DFS_RANDOM_CH_FLAG_* + * @chan_wd: input channel width, used same variable to return new ch width. + * @cur_chan: current channel. + * @dfs_region: DFS region. + * @acs_info: acs channel range information. + * + * Function used to find random channel selection from a given list. + * First this function removes channels based on flags and then uses final + * list to find channel based on requested bandwidth, if requested bandwidth + * not available, it chooses next lower bandwidth and try. + * + * Return: channel frequency, else zero. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *ch_list, + uint32_t chan_count, + uint32_t flags, + uint8_t *chan_wd, + struct dfs_channel *cur_chan, + uint8_t dfs_region, + struct dfs_acs_info *acs_info); +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h index cfeddc3a323bf2386c682c703fcc27478c57c8de..dd718e97f4b8be504a7473d863fa88f756dd6970 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/dfs_zero_cac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting * All rights reserved. * @@ -34,23 +34,64 @@ #include "dfs.h" #include +#ifdef CONFIG_CHAN_NUM_API #define VHT160_IEEE_FREQ_DIFF 16 +#endif + #define OCAC_SUCCESS 0 #define OCAC_RESET 1 #define OCAC_CANCEL 2 +#define TREE_DEPTH 3 +#define N_SUBCHANS_FOR_80BW 4 + +#define INITIAL_20_CHAN_OFFSET -6 +#define INITIAL_40_CHAN_OFFSET -4 +#define INITIAL_80_CHAN_OFFSET 0 + +#define NEXT_20_CHAN_OFFSET 4 +#define NEXT_40_CHAN_OFFSET 8 +#define NEXT_80_CHAN_OFFSET 16 + +#define DFS_CHWIDTH_20_VAL 20 +#define DFS_CHWIDTH_40_VAL 40 +#define DFS_CHWIDTH_80_VAL 80 +#define DFS_CHWIDTH_160_VAL 160 + +#define WEATHER_CHAN_START 120 +#define WEATHER_CHAN_END 128 + +/* PreCAC timeout durations in ms. */ +#define MIN_PRECAC_DURATION (6 * 60 * 1000) /* 6 mins */ +#define MIN_WEATHER_PRECAC_DURATION (60 * 60 * 1000) /* 1 hour */ +#define MAX_PRECAC_DURATION (4 * 60 * 60 * 1000) /* 4 hours */ +#define MAX_WEATHER_PRECAC_DURATION (24 * 60 * 60 * 1000) /* 24 hours */ + +#define PCAC_DFS_INDEX_ZERO 0 +#define PCAC_TIMER_NOT_RUNNING 0 +#define PRECAC_NOT_STARTED 0 /** - * struct dfs_precac_entry - PreCAC entry. - * @pe_list: PreCAC entry. - * @vht80_freq: VHT80 freq. - * @precac_nol_timer: Per element precac NOL timer. - * @dfs: Pointer to wlan_dfs structure. + * struct precac_tree_node - Individual tree node structure for every node in + * the precac forest maintained. + * @left_child: Pointer to the left child of the node. + * @right_child: Pointer to the right child of the node. + * @ch_ieee: Center channel ieee value. + * @ch_freq: Center channel frequency value (BSTree node key value). + * @n_caced_subchs: Number of CACed subchannels of the ch_ieee. + * @n_nol_subchs: Number of subchannels of the ch_ieee in NOL. + * @n_valid_subchs: Number of subchannels of the ch_ieee available (as per + * the country's channel list). + * @bandwidth: Bandwidth of the ch_ieee (in the current node). */ -struct dfs_precac_entry { - TAILQ_ENTRY(dfs_precac_entry) pe_list; - uint8_t vht80_freq; - qdf_timer_t precac_nol_timer; - struct wlan_dfs *dfs; +struct precac_tree_node { + struct precac_tree_node *left_child; + struct precac_tree_node *right_child; + uint8_t ch_ieee; + uint16_t ch_freq; + uint8_t n_caced_subchs; + uint8_t n_nol_subchs; + uint8_t n_valid_subchs; + uint8_t bandwidth; }; /** @@ -69,6 +110,22 @@ enum precac_chan_state { PRECAC_NOL, }; +/** + * struct dfs_precac_entry - PreCAC entry. + * @pe_list: PreCAC entry. + * @vht80_ch_ieee: VHT80 centre channel IEEE value. + * @vht80_ch_freq: VHT80 centre channel frequency value. + * @dfs: Pointer to wlan_dfs structure. + * @tree_root: Tree root node with 80MHz channel key. + */ +struct dfs_precac_entry { + TAILQ_ENTRY(dfs_precac_entry) pe_list; + uint8_t vht80_ch_ieee; + uint16_t vht80_ch_freq; + struct wlan_dfs *dfs; + struct precac_tree_node *tree_root; +}; + /** * dfs_zero_cac_timer_init() - Initialize zero-cac timers * @dfs_soc_obj: Pointer to DFS SOC object structure. @@ -106,9 +163,7 @@ static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs) #endif /** - * dfs_reset_precaclists() - Clears and initiakizes precac_required_list, - * precac_done_list and precac_nol_list. - * + * dfs_reset_precaclists() - Clears and initializes precac_list. * @dfs: Pointer to wlan_dfs structure. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) @@ -149,14 +204,35 @@ void dfs_init_precac_list(struct wlan_dfs *dfs); * @precac_chan: Start thr precac timer in this channel. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) +#ifdef CONFIG_CHAN_NUM_API void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan); +#endif + +/** + * dfs_start_precac_timer() - Start precac timer. + * @dfs: Pointer to wlan_dfs structure. + * @precac_chan_freq: Frequency to start precac timer. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan) { } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline +void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq) +{ +} +#endif +#endif /** * dfs_cancel_precac_timer() - Cancel the precac timer. @@ -239,27 +315,79 @@ static inline bool dfs_is_precac_done(struct wlan_dfs *dfs, * * Return: True if intermediate channel needs to configure. False otherwise. */ +#ifdef CONFIG_CHAN_NUM_API bool dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, uint8_t *pref_chan, enum wlan_phymode mode); +#endif + +/** + * dfs_decide_precac_preferred_chan_for_freq() - Choose operating channel among + * configured DFS channel and + * intermediate channel based on + * precac status of configured + * DFS channel. + * @dfs: Pointer to wlan_dfs structure. + * @pref_chan: Configured DFS channel frequency + * @mode: Configured PHY mode. + * + * Return: True if intermediate channel needs to configure. False otherwise. + */ + +#ifdef CONFIG_CHAN_FREQ_API +bool +dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs, + uint16_t *pref_chan_freq, + enum wlan_phymode mode); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, uint8_t *pref_chan, enum wlan_phymode mode) { } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs, + uint8_t *pref_chan, + enum wlan_phymode mode) +{ +} +#endif +#endif /** - * dfs_get_freq_from_precac_required_list() - Get VHT80 freq from - * precac_required_list. - * @dfs: Pointer to wlan_dfs structure. - * @exclude_ieee_freq: Find a VHT80 freqency that is not equal to - * exclude_ieee_freq. + * dfs_get_ieeechan_for_precac() - Get chan of required bandwidth from + * precac_list. + * @dfs: Pointer to wlan_dfs structure. + * @exclude_pri_ch_ieee: Primary channel IEEE to be excluded for preCAC. + * @exclude_sec_ch_ieee: Secondary channel IEEE to be excluded for preCAC. + * @bandwidth: Bandwidth of requested channel. + */ +#ifdef CONFIG_CHAN_NUM_API +uint8_t dfs_get_ieeechan_for_precac(struct wlan_dfs *dfs, + uint8_t exclude_pri_ch_ieee, + uint8_t exclude_sec_ch_ieee, + uint8_t bandwidth); +#endif + +/** + * dfs_get_ieeechan_for_precac_for_freq() - Get chan of required bandwidth from + * precac_list. + * @dfs: Pointer to wlan_dfs structure. + * @exclude_pri_chan_freq: Primary channel freq to be excluded for preCAC. + * @exclude_sec_chan_freq: Secondary channel freq to be excluded for preCAC. + * @bandwidth: Bandwidth of requested channel. */ -uint8_t dfs_get_freq_from_precac_required_list(struct wlan_dfs *dfs, - uint8_t exclude_ieee_freq); +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_get_ieeechan_for_precac_for_freq(struct wlan_dfs *dfs, + uint16_t exclude_pri_chan_freq, + uint16_t exclude_sec_chan_freq, + uint8_t bandwidth); +#endif /** * dfs_override_precac_timeout() - Override the default precac timeout. @@ -329,6 +457,7 @@ static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs, * exhausted the VHT80_80/VHT160 comes back to VHT80 mode. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) +#ifdef CONFIG_CHAN_NUM_API void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -337,7 +466,32 @@ void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t *phy_mode, bool *dfs_set_cfreq2, bool *set_agile); +#endif + +/* + * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac. + * @dfs: Pointer to wlan_dfs structure. + * @chan_mode: Channel mode. + * @ch_freq_seg1: Segment1 channel freq in mhz. + * @cfreq1: cfreq1. + * @cfreq2: cfreq2. + * @phy_mode: Precac phymode. + * @dfs_set_cfreq2: Precac cfreq2 + * @set_agile: Agile mode flag. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs, + uint32_t chan_mode, + uint16_t ch_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile); +#endif + #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -350,6 +504,21 @@ static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline +void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs, + uint32_t chan_mode, + uint16_t ch_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile) +{ +} +#endif +#endif + #if defined(QCA_SUPPORT_AGILE_DFS) /** * dfs_find_pdev_for_agile_precac() - Find pdev to select channel for precac. @@ -376,16 +545,39 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, uint32_t center_freq); /** - * dfs_find_vht80_chan_for_agile_precac() - . - * @pdev :Pointer to wlan_objmgr_pdev structure. - * @*ch_freq: Pointer to channel number for agile set request. - * @ch_freq_seg1 : Current primary beaconing channel number. - * @ch_freq_seg2 : Current secondary segment channel number. + * dfs_get_ieeechan_for_agilecac() - Find an IEEE channel for agile CAC. + * @dfs: Pointer to wlan_dfs structure. + * @ch_ieee: Pointer to channel number for agile set request. + * @pri_ch_ieee: Current primary IEEE channel. + * @sec_ch_ieee: Current secondary IEEE channel (in HT80_80 mode). + * + * Find an IEEE channel for agileCAC which is not the current operating + * channels (indicated by pri_ch_ieee, sec_ch_ieee). + */ +#ifdef CONFIG_CHAN_NUM_API +void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs, + uint8_t *ch_ieee, + uint8_t pri_ch_ieee, + uint8_t sec_ch_ieee); +#endif + +/** + * dfs_get_ieeechan_for_agilecac_for_freq() - Find chan freq for agile CAC. + * @dfs: Pointer to wlan_dfs structure. + * @chan_freq: Pointer to channel freq for agile set request. + * @pri_chan_freq: Current primary IEEE channel freq. + * @sec_chan_freq: Current secondary IEEE channel freq (in HT80_80 mode). + * + * Find an IEEE channel freq for agileCAC which is not the current operating + * channels (indicated by pri_chan_freq, sec_chan_freq). */ -void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs, - uint8_t *ch_freq, - uint8_t ch_freq_seg1, - uint8_t ch_freq_seg2); +#ifdef CONFIG_CHAN_FREQ_API +void dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs, + uint16_t *chan_freq, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq); +#endif + /** * dfs_agile_precac_start() - Start agile precac. * @dfs: Pointer to wlan_dfs structure. @@ -393,14 +585,31 @@ void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs, void dfs_agile_precac_start(struct wlan_dfs *dfs); /** - * dfs_start_agile_precac_timer() - Start precac timer. - * @dfs: Pointer to wlan_dfs structure. - * @precac_chan: Start thr precac timer in this channel. + * dfs_start_agile_precac_timer() - Start precac timer for the given channel. + * @dfs: Pointer to wlan_dfs structure. * @ocac_status: Status of the off channel CAC. + * @adfs_param: Agile DFS CAC parameters. + * + * Start the precac timer with proper timeout values based on the channel to + * be preCACed. The preCAC channel number and chwidth information is present + * in the adfs_param argument. Once the timer is started, update the timeout + * fields in adfs_param. */ void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, - uint8_t precac_chan, - uint8_t ocac_status); + uint8_t ocac_status, + struct dfs_agile_cac_params *adfs_param); + +/** + * dfs_set_fw_adfs_support() - Set FW aDFS support in dfs object. + * @dfs: Pointer to wlan_dfs structure. + * @fw_adfs_support_160: aDFS enabled when pdev is on 160/80P80MHz. + * @fw_adfs_support_non_160: aDFS enabled when pdev is on 20/40/80MHz. + * + * Return: void. + */ +void dfs_set_fw_adfs_support(struct wlan_dfs *dfs, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160); #else static inline void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev, uint8_t *cur_precac_dfs_index) @@ -418,20 +627,40 @@ dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, { } -static inline void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs, - uint8_t *ch_freq, - uint8_t ch_freq_seg1, - uint8_t ch_freq_seg2) +#ifdef CONFIG_CHAN_NUM_API +static inline void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs, + uint8_t *ch_ieee, + uint8_t pri_ch_ieee, + uint8_t sec_ch_ieee) { } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs, + uint16_t *chan_freq, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq) +{ +} +#endif static inline void dfs_agile_precac_start(struct wlan_dfs *dfs) { } -static inline void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, - uint8_t precac_chan, - uint8_t ocac_status) +static inline void +dfs_start_agile_precac_timer(struct wlan_dfs *dfs, + uint8_t ocac_status, + struct dfs_agile_cac_params *adfs_param) +{ +} + +static inline void +dfs_set_fw_adfs_support(struct wlan_dfs *dfs, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160) { } #endif @@ -455,7 +684,7 @@ static inline void dfs_agile_soc_obj_init(struct wlan_dfs *dfs, /** * dfs_set_precac_enable() - Set precac enable flag. * @dfs: Pointer to wlan_dfs structure. - * @value: input value for dfs_precac_enable flag. + * @value: input value for dfs_legacy_precac_ucfg flag. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) void dfs_set_precac_enable(struct wlan_dfs *dfs, @@ -468,24 +697,46 @@ static inline void dfs_set_precac_enable(struct wlan_dfs *dfs, #endif /** - * dfs_get_precac_enable() - Get precac enable flag. - * @dfs: Pointer to wlan_dfs structure. + * dfs_is_legacy_precac_enabled() - Check if legacy preCAC is enabled for the + * DFS onject. + * @dfs: Pointer to the wlan_dfs object. + * + * Return: True if legacy preCAC is enabled, else false. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) -uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs); +bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs); #else -static inline uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs) +static inline bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs) { return 0; } #endif +/** + * dfs_is_agile_precac_enabled() - Check if agile preCAC is enabled for the DFS. + * @dfs: Pointer to the wlan_dfs object. + * + * Return: True if agile DFS is enabled, else false. + * + * For agile preCAC to be enabled, + * 1. User configuration should be set. + * 2. Target should support aDFS. + */ +#ifdef QCA_SUPPORT_AGILE_DFS +bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs); +#else +static inline bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs) +{ + return false; +} +#endif + #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT /** * dfs_set_precac_intermediate_chan() - Set intermediate chan to be used while * doing precac. * @dfs: Pointer to wlan_dfs structure. - * @value: input value for dfs_precac_enable flag. + * @value: input value for dfs_legacy_precac_ucfg flag. * * Return: * * 0 - Successfully set intermediate channel. @@ -526,13 +777,28 @@ static inline uint32_t dfs_get_intermediate_chan(struct wlan_dfs *dfs) * Return: * * PRECAC_REQUIRED: Precac has not done on precac_chan. * * PRECAC_NOW : Precac is running on precac_chan. - * * PRECAC_DONE : precac_chan is in precac done list. - * * PRECAC_NOL : precac_chan is in precac NOL list. + * * PRECAC_DONE : precac_chan is in CAC done state in precac list. + * * PRECAC_NOL : precac_chan is in NOL state in precac list. * * PRECAC_ERR : Invalid precac state. */ enum precac_chan_state dfs_get_precac_chan_state(struct wlan_dfs *dfs, uint8_t precac_chan); + +/** + * dfs_get_precac_chan_state_for_freq() - Get precac status of a given channel. + * @dfs: Pointer to wlan_dfs structure. + * @precac_chan: Channel freq for which precac state need to be checked. + */ + +#ifdef CONFIG_CHAN_FREQ_API +enum precac_chan_state +dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq); +#endif + #else + +#ifdef CONFIG_CHAN_NUM_API static inline enum precac_chan_state dfs_get_precac_chan_state(struct wlan_dfs *dfs, uint8_t precac_chan) @@ -541,6 +807,16 @@ dfs_get_precac_chan_state(struct wlan_dfs *dfs, } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline enum precac_chan_state +dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq) +{ + return PRECAC_REQUIRED; +} +#endif +#endif + /** * dfs_zero_cac_reset() - Reset Zero cac DFS variables. * @dfs: Pointer to wlan_dfs structure. @@ -548,50 +824,261 @@ dfs_get_precac_chan_state(struct wlan_dfs *dfs, void dfs_zero_cac_reset(struct wlan_dfs *dfs); /** - * dfs_is_ht20_40_80_chan_in_precac_done_list() - Is precac done on a - * VHT20/40/80 channel. + * dfs_reinit_precac_lists() - Reinit DFS preCAC lists. + * @src_dfs: Source DFS from which the preCAC list is copied. + * @dest_dfs: Destination DFS to which the preCAC list is copied. + * @low_5g_freq: Low 5G frequency value of the destination DFS. + * @high_5g_freq: High 5G frequency value of the destination DFS. + * + * Copy all the preCAC list entries from the source DFS to the destination DFS + * which fall within the frequency range of low_5g_freq and high_5g_freq. + * + * Return: None (void). + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) +void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, + struct wlan_dfs *dest_dfs, + uint16_t low_5g_freq, + uint16_t high_5g_freq); +#else +static inline void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, + struct wlan_dfs *dest_dfs, + uint16_t low_5g_freq, + uint16_t high_5g_freq) +{ +} +#endif + +/** + * dfs_is_precac_done_on_ht20_40_80_chan() - Is precac done on a + * VHT20/40/80 channel. *@dfs: Pointer to wlan_dfs structure. - *@chan: Pointer to dfs_channel for which preCAC done is checked. + *@chan: Channel IEEE value. * * Return: - * * True: If channel is present in precac-done list. - * * False: If channel is not present in precac-done list. + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. */ -bool dfs_is_ht20_40_80_chan_in_precac_done_list(struct wlan_dfs *dfs, - struct dfs_channel *chan); +#ifdef CONFIG_CHAN_NUM_API +bool dfs_is_precac_done_on_ht20_40_80_chan(struct wlan_dfs *dfs, + uint8_t chan); +#endif /** - * dfs_is_ht8080_ht160_chan_in_precac_done_list() - Is precac done on - * VHT80+80 or VHT160 - * channel. - * @dfs: Pointer to wlan_dfs structure. - * @chan: Pointer to dfs_channel for which preCAC done is checked. + * dfs_is_precac_done_on_ht20_40_80_chan_for_freq() - Is precac done on a + * VHT20/40/80 channel. + *@dfs: Pointer to wlan_dfs structure. + *@chan: Channel frequency * * Return: - * * True: If channel is present in precac-done list. - * * False: If channel is not present in precac-done list. + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. */ -bool dfs_is_ht8080_ht160_chan_in_precac_done_list(struct wlan_dfs *dfs, - struct dfs_channel *chan); +#ifdef CONFIG_CHAN_FREQ_API +bool dfs_is_precac_done_on_ht20_40_80_chan_for_freq(struct wlan_dfs *dfs, + uint16_t chan_freq); +#endif /** - * dfs_mark_precac_dfs() - Mark the precac channel as radar. + * dfs_is_precac_done_on_ht8080_ht160_chan() - Is precac done on + * VHT80+80 or VHT160 + * channel. * @dfs: Pointer to wlan_dfs structure. - * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. - * @detector_id: detector id which found RADAR in HW. + * @chan: Pointer to dfs_channel for which preCAC done is checked. + * + * Return: + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. */ +bool dfs_is_precac_done_on_ht8080_ht160_chan(struct wlan_dfs *dfs, + struct dfs_channel *chan); + #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) -void dfs_mark_precac_dfs(struct wlan_dfs *dfs, - uint8_t is_radar_found_on_secondary_seg, - uint8_t detector_id); +/** + * dfs_find_chwidth_and_center_chan() - Find the channel width enum and + * primary and secondary center channel + * value of the current channel. + * @dfs: Pointer to wlan_dfs structure. + * @chwidth: Channel width enum of current channel. + * @primary_chan_ieee: Primary IEEE channel. + * @secondary_chan_ieee: Secondary IEEE channel (in HT80_80 mode). + */ +#ifdef CONFIG_CHAN_NUM_API +void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint8_t *primary_chan_ieee, + uint8_t *secondary_chan_ieee); + +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_find_chwidth_and_center_chan_for_freq() - Find the channel width enum and + * primary and secondary center channel + * value of the current channel. + * @dfs: Pointer to wlan_dfs structure. + * @chwidth: Channel width enum of current channel. + * @primary_chan_freq: Primary IEEE channel freq. + * @secondary_chan_freq: Secondary IEEE channel freq (in HT80_80 mode). + */ +void dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint16_t *primary_chan_freq, + uint16_t *secondary_chan_freq); +#endif + +/** + * dfs_mark_precac_done() - Mark the channel as preCAC done. + * @dfs: Pointer to wlan_dfs structure. + * @pri_ch_ieee: Primary channel IEEE. + * @sec_ch_ieee: Secondary channel IEEE (only in HT80_80 mode). + * @ch_width: Channel width enum. + */ +#ifdef CONFIG_CHAN_NUM_API +void dfs_mark_precac_done(struct wlan_dfs *dfs, + uint8_t pri_ch_ieee, + uint8_t sec_ch_ieee, + enum phy_ch_width ch_width); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_mark_precac_done_for_freq() - Mark the channel as preCAC done. + * @dfs: Pointer to wlan_dfs structure. + * @pri_chan_freq: Primary channel IEEE freq. + * @sec_chan_freq: Secondary channel IEEE freq(only in HT80_80 mode). + * @chan_width: Channel width enum. + */ +void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq, + enum phy_ch_width chan_width); +#endif + +/** + * dfs_mark_precac_nol() - Mark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. + * @detector_id: detector id which found RADAR in HW. + * @channels: Array of radar found subchannels. + * @num_channels: Number of radar found subchannels. + */ +#ifdef CONFIG_CHAN_NUM_API +void dfs_mark_precac_nol(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint8_t *channels, + uint8_t num_channels); +#endif + +/** + * dfs_mark_precac_nol_for_freq() - Mark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. + * @detector_id: detector id which found RADAR in HW. + * @freq_list: Array of radar found frequencies. + * @num_channels: Number of radar found subchannels. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint16_t *freq_list, + uint8_t num_channels); +#endif + +/** + * dfs_unmark_precac_nol() - Unmark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @channel: channel marked as radar. + */ +#ifdef CONFIG_CHAN_NUM_API +void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel); +#endif + +/** + * dfs_unmark_precac_nol_for_freq() - Unmark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @channel: channel freq marked as radar. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, uint16_t chan_freq); +#endif + #else -static inline void dfs_mark_precac_dfs(struct wlan_dfs *dfs, - uint8_t is_radar_found_on_secondary_seg, - uint8_t detector_id) +#ifdef CONFIG_CHAN_NUM_API +static inline void +dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint8_t *primary_chan_ieee, + uint8_t *secondary_chan_ieee) +{ +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint16_t *primary_chan_freq, + uint16_t *secondary_chan_freq) { } #endif +#ifdef CONFIG_CHAN_NUM_API +static inline void dfs_mark_precac_done(struct wlan_dfs *dfs, + uint8_t pri_ch_ieee, + uint8_t sec_ch_ieee, + enum phy_ch_width ch_width) +{ +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq, + enum phy_ch_width chan_width) +{ +} +#endif + +#ifdef CONFIG_CHAN_NUM_API +static inline void dfs_mark_precac_nol(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint8_t *channels, + uint8_t num_channels) +{ +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint16_t *freq, + uint8_t num_channels) +{ +} +#endif + +#ifdef CONFIG_CHAN_NUM_API +static inline void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel) +{ +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint16_t chan_freq) +{ +} +#endif +#endif + /** * dfs_is_precac_timer_running() - Check whether precac timer is running. * @dfs: Pointer to wlan_dfs structure. @@ -604,4 +1091,21 @@ static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs) return false; } #endif + +#ifdef CONFIG_CHAN_FREQ_API +#define VHT160_FREQ_DIFF 80 + +#define INITIAL_20_CHAN_FREQ_OFFSET -30 +#define INITIAL_40_CHAN_FREQ_OFFSET -20 +#define INITIAL_80_CHAN_FREQ_OFFSET 0 + +#define NEXT_20_CHAN_FREQ_OFFSET 20 +#define NEXT_40_CHAN_FREQ_OFFSET 40 +#define NEXT_80_CHAN_FREQ_OFFSET 80 + +#define WEATHER_CHAN_START_FREQ 5600 +#define WEATHER_CHAN_END_FREQ 5640 + +#endif + #endif /* _DFS_ZERO_CAC_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_bindetects.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_bindetects.c index 67548ad0a121335060690a2b3fdd139b3d4d0c34..81db766c57bb30e3dc54e86a655fa5c6469c39eb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_bindetects.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_bindetects.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2002-2010, Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -322,6 +322,7 @@ void dfs_add_pulse( dl->dl_numelems = n+1; } } + dfs_debug(dfs, WLAN_DEBUG_DFS2, "dl firstElem = %d lastElem = %d", dl->dl_firstelem, dl->dl_lastelem); } @@ -544,6 +545,55 @@ static inline int dfs_bin_basic_sanity( return 1; } +/** + * dfs_pick_lowpri() - Pick lowpri as refpri + * @dfs: Pointer to wlan_dfs structure. + * @dl: Pointer to dfs delayline. + * @rf: Pointer to dfs_filter structure. + * @lowpriindex: Low PRI index. + * @scoreindex: score index. + * @primargin: PRI margin. + */ +#ifdef DFS_PRI_MULTIPLIER +static inline void dfs_pick_lowpri(struct wlan_dfs *dfs, + struct dfs_delayline *dl, + struct dfs_filter *rf, + uint32_t lowpriindex, + uint32_t *scoreindex, + uint32_t primargin) +{ + uint32_t candidate_refpri, deltapri, lowpri; + uint32_t dindex_candidate, dindex_lowpri; + uint32_t i; + + dindex_candidate = (dl->dl_firstelem + *scoreindex) & DFS_MAX_DL_MASK; + dindex_lowpri = (dl->dl_firstelem + lowpriindex) & DFS_MAX_DL_MASK; + + candidate_refpri = dl->dl_elems[dindex_candidate].de_time; + lowpri = dl->dl_elems[dindex_lowpri].de_time; + + if (rf->rf_ignore_pri_window == 0 && + candidate_refpri != lowpri) { + for (i = 1; i <= dfs->dfs_pri_multiplier; i++) { + deltapri = DFS_DIFF(candidate_refpri, i * lowpri); + if (deltapri < primargin) { + *scoreindex = lowpriindex; + break; + } + } + } +} +#else +static inline void dfs_pick_lowpri(struct wlan_dfs *dfs, + struct dfs_delayline *dl, + struct dfs_filter *rf, + uint32_t lowpriindex, + uint32_t *scoreindex, + uint32_t primargin) +{ +} +#endif + /** * dfs_find_scoreindex() - Find score index * @rf: Pointer to dfs_filter structure. @@ -667,6 +717,18 @@ int dfs_bin_check( dfs_find_scoreindex(rf, highscore, lowpriindex, highscoreindex, &scoreindex); + /* + * Observed ETSI type2 while channel loading 31% with pulse pri: + * 1489, 2978, 2978, 2978, 1489, 2978, 1489 us. With above logic, + * the highscore will be 4 (2978), scoreindex is 5. In this case, + * index 0, 4, 6 pulses will be not matched later in + * dfs_count_the_other_delay_elements(), which leads to the radar was + * not detected. The fix is: compare the highscore pri with lowpri, + * if they have relationship, within primargin of + * [1, dfs_pri_multiplier] times of lowpri, choose lowpri as refpri. + */ + dfs_pick_lowpri(dfs, dl, rf, lowpriindex, &scoreindex, primargin); + /* We got the possible pri, save its parameters as reference. */ dfs_find_refs(dl, rf, scoreindex, &refdur, &refpri); @@ -802,8 +864,8 @@ static void dfs_count_the_other_delay_elements( int fundamentalpri) { int delayindex; - uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2; - uint32_t j = 0, delta_time_stamps, deltapri; + uint32_t searchpri, searchdur, deltadur; + uint32_t j = 0, delta_time_stamps, deltapri, k; int dindex, primatch, numpulsetochk = 2; int32_t sidx_min = DFS_BIG_SIDX; int32_t sidx_max = -DFS_BIG_SIDX; @@ -819,23 +881,30 @@ static void dfs_count_the_other_delay_elements( dl->dl_elems[dindex].de_time -= refpri; searchpri = refpri; } + searchdur = dl->dl_elems[delayindex].de_dur; deltadur = DFS_DIFF(searchdur, refdur); deltapri = DFS_DIFF(searchpri, refpri); - deltapri1 = DFS_DIFF(searchpri, refpri); - deltapri2 = DFS_DIFF(searchpri, 2 * refpri); primatch = 0; if ((rf->rf_ignore_pri_window > 0) && (rf->rf_patterntype != 2)) { for (j = 0; j < rf->rf_numpulses; j++) { - deltapri1 = DFS_DIFF(searchpri, (j + 1) * refpri); - if (deltapri1 < (2 * primargin)) { + deltapri = DFS_DIFF(searchpri, (j + 1) * refpri); + if (deltapri < (2 * primargin)) { primatch = 1; break; } } - } else if ((deltapri1 < primargin) || (deltapri2 < primargin)) { + } else if (rf->rf_patterntype == 2) { primatch = 1; + } else { + for (k = 1; k <= dfs->dfs_pri_multiplier; k++) { + deltapri = DFS_DIFF(searchpri, k * refpri); + if (deltapri < primargin) { + primatch = 1; + break; + } + } } if (primatch && (deltadur < durmargin)) { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_init.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_init.c index 716d0d3852bed213a500c793e5360272c1104914..b5eaa3f40c142e96e0f31e6bae87a35d7e33c21d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_init.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_init.c @@ -431,12 +431,61 @@ int dfs_check_etsi_overlap(int center_freq, int chan_width, chan_freq_high)); } +#ifdef CONFIG_CHAN_FREQ_API +bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) +{ + int chan_freq; + int chan_width; + int overlap = 0; + struct wlan_objmgr_vdev *vdev = NULL; + struct wlan_channel *bss_chan = NULL; + + /* Get centre frequency */ + chan_freq = dfs->dfs_curchan->dfs_ch_mhz_freq_seg1; + vdev = wlan_objmgr_pdev_get_first_vdev(dfs->dfs_pdev_obj, WLAN_DFS_ID); + if (!vdev) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL"); + return false; + } + + bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); + /* Grab width */ + chan_width = wlan_reg_get_bw_value(bss_chan->ch_width); + + if (WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) { + /* HT80_80 mode has 2 segments and each segment must + * be checked for control channel first. + */ + overlap = dfs_check_etsi_overlap( + chan_freq, chan_width / 2, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + + /* check for extension channel */ + chan_freq = dfs->dfs_curchan->dfs_ch_mhz_freq_seg2; + + overlap += dfs_check_etsi_overlap( + chan_freq, chan_width / 2, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + } else { + overlap = dfs_check_etsi_overlap( + chan_freq, chan_width, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + } + + return(wlan_reg_is_regdmn_en302502_applicable(dfs->dfs_pdev_obj) && + overlap); +} +#else +#ifdef CONFIG_CHAN_NUM_API bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) { int chan_freq; int chan_width; int overlap = 0; - uint16_t regdmn; struct wlan_objmgr_vdev *vdev = NULL; struct wlan_channel *bss_chan = NULL; @@ -478,11 +527,8 @@ bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) ETSI_RADAR_EN302_502_FREQ_UPPER); } - regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj); - - return(((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) || - (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) || - (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) || - (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) && + return(wlan_reg_is_regdmn_en302502_applicable(dfs->dfs_pdev_obj) && overlap); } +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c index 4595f3db2b269436fbaf3f002ef222fd8fda9723..80f508aa80c81228151ecdce124a789df3adf9e7 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2011, Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -96,6 +96,16 @@ static struct dfs_pulse dfs_mkk4_radars[] = { {16, 15, 2000, 5000, 0, 4, 7, 11, 23, 22, 0, 3, 0, 5, 0, 11}, }; +/** + * struct dfs_pulse dfs_mkkn_radars - MKKN radar table for Offload chipsets. + */ +static struct dfs_pulse dfs_mkkn_radars[] = { + /** Since the table is empty no new radar type shall be detected. + * New filters shall be added to this tables after proper testing + * and verification. + */ +}; + /** * struct dfs_bin5pulse dfs_fcc_bin5pulses - FCC BIN5 pulses for Offload * chipsets. @@ -168,6 +178,14 @@ static struct dfs_pulse dfs_etsi_radars[] = { /* PRF 4500, 20us duration, 9 pulses per burst */ {9, 20, 4500, 4500, 1, 4, 5, 19, 21, 18, 0, 0, 1, 1000, 0, 41}, + /* Type 3 */ + /* 10 15us, 200-1000 PRF, 15 pulses */ + {15, 15, 200, 1000, 0, 4, 5, 8, 18, 22, 0, 0, 0, 5, 0, 42}, + + /* Type 4 */ + /* 1-15us, 1200-1600 PRF, 15 pulses */ + {15, 15, 1200, 1600, 0, 4, 5, 0, 18, 22, 0, 0, 0, 5, 0, 43}, + /* TYPE staggered pulse */ /* Type 5*/ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ @@ -206,34 +224,34 @@ static struct dfs_pulse dfs_china_radars[] = { /* TYPE staggered pulse */ /* Type 5*/ /* 0.8-2us, 2-3 bursts,300-400 PRF, 12 pulses each */ - {36, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 51}, + {36, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 0, 0, 51}, /* Type 6 */ /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 16 pulses each */ - {48, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 52}, + {48, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 0, 0, 52}, /* constant PRF based */ /* Type 1 */ /* 0.5-5us, 200 1000 PRF, 12 pulses */ - {12, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 53}, - {12, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 57}, - {12, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 58}, - {12, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 59}, + {12, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 53}, + {12, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 57}, + {12, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 58}, + {12, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 59}, /* Type 2 */ /* 0.5-15us, 200-1600 PRF, 16 pulses */ - {16, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 54}, + {16, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 0, 0, 54}, /* Type 3 */ /* 0.5-30us, 2300-4000 PRF, 24 pulses*/ - {24, 15, 2300, 4000, 0, 24, 10, 0, 33, 24, 0, 0, 0, 55}, + {24, 15, 2300, 4000, 0, 24, 10, 0, 33, 24, 0, 0, 0, 0, 0, 55}, /* Type 4 */ /* 20-30us, 2000-4000 PRF, 20 pulses*/ - {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 56}, + {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 0, 0, 56}, /* 1us, 1000 PRF, 20 pulses */ /* 1000 us PRI */ - {20, 1, 1000, 1000, 0, 6, 6, 0, 1, 18, 0, 3, 0, 50}, + {20, 1, 1000, 1000, 0, 6, 6, 0, 1, 18, 0, 3, 0, 0, 0, 50}, }; /** @@ -247,13 +265,14 @@ static struct dfs_pulse dfs_korea_radars[] = { {10, 1, 1800, 1800, 0, 4, 4, 0, 1, 18, 0, 3, 1, 5, 0, 41}, /* Korea Type 3 */ - {70, 1, 330, 330, 0, 4, 20, 0, 2, 18, 0, 3, 1, 5, 0, 42}, + {70, 1, 330, 330, 0, 4, 20, 0, 3, 18, 0, 3, 1, 5, 0, 42}, /* Korea Type 4 */ {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 1000, 0, 43}, }; #define RSSI_THERSH_AR900B 15 +#define RSSI_THERSH_ADRASTEA 18 /** * dfs_assign_fcc_pulse_table() - Assign FCC pulse table @@ -284,6 +303,37 @@ static inline void dfs_assign_fcc_pulse_table( } } +#ifdef DFS_OVERRIDE_RF_THRESHOLD +static void dfs_set_adrastea_rf_thrshold( + struct wlan_objmgr_psoc *psoc, + int dfsdomain, + uint32_t target_type, + struct wlan_dfs_radar_tab_info *rinfo) +{ + int i; + struct wlan_lmac_if_target_tx_ops *tx_ops; + + tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops; + + if (tx_ops->tgt_is_tgt_type_adrastea(target_type) && + dfsdomain == DFS_ETSI_DOMAIN) { + for (i = 0; i < rinfo->numradars; i++) { + rinfo->dfs_radars[i].rp_rssithresh = + DFS_MIN(rinfo->dfs_radars[i].rp_rssithresh, + RSSI_THERSH_ADRASTEA); + } + } +} +#else +static inline void dfs_set_adrastea_rf_thrshold( + struct wlan_objmgr_psoc *psoc, + int dfsdomain, + uint32_t target_type, + struct wlan_dfs_radar_tab_info *rinfo) +{ +} +#endif + void dfs_get_po_radars(struct wlan_dfs *dfs) { struct wlan_dfs_radar_tab_info rinfo; @@ -366,6 +416,14 @@ void dfs_get_po_radars(struct wlan_dfs *dfs) rinfo.b5pulses = NULL; rinfo.numb5radars = 0; break; + case DFS_MKKN_DOMAIN: + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKKN domain"); + rinfo.dfsdomain = DFS_MKKN_DOMAIN; + rinfo.dfs_radars = dfs_mkkn_radars; + rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkkn_radars); + rinfo.b5pulses = NULL; + rinfo.numb5radars = 0; + break; case DFS_MKK4_DOMAIN: dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "MKK4 domain"); rinfo.dfsdomain = DFS_MKK4_DOMAIN; @@ -418,6 +476,8 @@ void dfs_get_po_radars(struct wlan_dfs *dfs) rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B; } + dfs_set_adrastea_rf_thrshold(psoc, dfsdomain, target_type, &rinfo); + WLAN_DFS_DATA_STRUCT_LOCK(dfs); dfs_init_radar_filters(dfs, &rinfo); WLAN_DFS_DATA_STRUCT_UNLOCK(dfs); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c index 90f395900fe0e2374387ae9c0e6a748cf018fa1e..d67ea476962c940ea2aab293fecbe965a1a48531 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c @@ -162,7 +162,6 @@ static void dfs_radar_summary_parse(struct wlan_dfs *dfs, MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_AGC_TOTAL_GAIN); rsu->agc_mb_gain = MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_AGC_MB_GAIN); - rsu->rssi = MS(rs[RADAR_REPORT_PULSE_REG_4], RADAR_REPORT_PULSE_RSSI); } /** @@ -446,6 +445,60 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs, * * Return: Returns the channel center. */ +#ifdef CONFIG_CHAN_FREQ_API +static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, + struct rx_radar_status *rs) +{ + uint32_t chan_centre; + uint32_t chan_width; + int chan_offset; + + /* For now, just handle up to VHT80 correctly. */ + if (!dfs->dfs_curchan) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_curchan is null"); + return 0; + /* + * For now, the only 11ac channel with freq1/freq2 setup is + * VHT80. Should have a flag macro to check this! + */ + } else if (WLAN_IS_CHAN_11AC_VHT80(dfs->dfs_curchan)) { + /* + * 11AC, so cfreq1/cfreq2 are setup. + * If it's 80+80 this won't work - need to use seg + * appropriately! + */ + chan_centre = dfs->dfs_curchan->dfs_ch_mhz_freq_seg1; + } else { + /* + * HT20/HT40. + * This is hard-coded - it should be 5 or 10 for half/quarter + * appropriately. + */ + chan_width = 20; + + /* Grab default channel centre. */ + chan_centre = dfs->dfs_curchan->dfs_ch_freq; + + /* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D. */ + if (WLAN_IS_CHAN_11N_HT40PLUS(dfs->dfs_curchan) || + (dfs->dfs_curchan->dfs_ch_flags & WLAN_CHAN_VHT40PLUS)) + chan_offset = chan_width; + else if (WLAN_IS_CHAN_11N_HT40MINUS(dfs->dfs_curchan) || + (dfs->dfs_curchan->dfs_ch_flags & + WLAN_CHAN_VHT40MINUS)) + chan_offset = -chan_width; + else + chan_offset = 0; + + /* Calculate new _real_ channel centre. */ + chan_centre += (chan_offset / 2); + } + + /* Return ev_chan_centre in MHz. */ + return chan_centre; +} +#else +#ifdef CONFIG_CHAN_NUM_API static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, struct rx_radar_status *rs) { @@ -500,6 +553,9 @@ static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, /* Return ev_chan_centre in MHz. */ return chan_centre; } +#endif +#endif + /** * dfs_tlv_calc_event_freq_pulse() - Calculate the centre frequency and diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_process_radarevent.c index 350e9c68379fa242213076055a95dcd0a5063ce9..8e287bc4d22e1b0705fe293f847c30e2f2d53754 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2002-2010, Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -31,6 +31,16 @@ #include "wlan_dfs_lmac_api.h" #include "../dfs_partial_offload_radar.h" +#ifdef DFS_FCC_TYPE4_DURATION_CHECK +#define DFS_WAR_30_MHZ_SEPARATION 30 +#define DFS_WAR_PEAK_INDEX_ZERO 0 +#define DFS_TYPE4_WAR_PULSE_DURATION_LOWER_LIMIT 11 +#define DFS_TYPE4_WAR_PULSE_DURATION_UPPER_LIMIT 33 +#define DFS_TYPE4_WAR_PRI_LOWER_LIMIT 200 +#define DFS_TYPE4_WAR_PRI_UPPER_LIMIT 500 +#define DFS_TYPE4_WAR_VALID_PULSE_DURATION 12 +#endif + #define FREQ_5500_MHZ 5500 #define FREQ_5500_MHZ 5500 @@ -92,6 +102,58 @@ static inline uint8_t dfs_process_pulse_dur(struct wlan_dfs *dfs, return (uint8_t)dfs_round((int32_t)((dfs->dur_multiplier)*re_dur)); } +#ifdef DFS_FCC_TYPE4_DURATION_CHECK +/* + * dfs_dur_check() - Modify the pulse duration for FCC Type 4 and JAPAN W56 + * Type 8 radar pulses when the conditions mentioned in the + * function body are reported in the radar summary report. + * @dfs: Pointer to wlan_dfs structure. + * @chan: Current channel. + * @re: Pointer to dfs_event. + * @diff_ts: timestamp of current pulse - timestamp of last pulse. + * + * return: Void + */ +static inline void dfs_dur_check( + struct wlan_dfs *dfs, + struct dfs_channel *chan, + struct dfs_event *re, + uint32_t diff_ts) +{ + if ((dfs->dfsdomain == DFS_FCC_DOMAIN || + dfs->dfsdomain == DFS_MKK4_DOMAIN) && + ((chan->dfs_ch_flags & WLAN_CHAN_VHT80) == WLAN_CHAN_VHT80) && + (DFS_DIFF(chan->dfs_ch_freq, chan->dfs_ch_mhz_freq_seg1) == + DFS_WAR_30_MHZ_SEPARATION) && + re->re_sidx == DFS_WAR_PEAK_INDEX_ZERO && + (re->re_dur > DFS_TYPE4_WAR_PULSE_DURATION_LOWER_LIMIT && + re->re_dur < DFS_TYPE4_WAR_PULSE_DURATION_UPPER_LIMIT) && + (diff_ts > DFS_TYPE4_WAR_PRI_LOWER_LIMIT && + diff_ts < DFS_TYPE4_WAR_PRI_UPPER_LIMIT)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "chan flags=%llu, Pri Chan %d MHz center %d MHZ", + chan->dfs_ch_flags, + chan->dfs_ch_freq, chan->dfs_ch_mhz_freq_seg1); + + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Report Peak Index = %d,re.re_dur = %d,diff_ts = %d", + re->re_sidx, re->re_dur, diff_ts); + + re->re_dur = DFS_TYPE4_WAR_VALID_PULSE_DURATION; + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Modifying the pulse duration to %d", re->re_dur); + } +} +#else +static inline void dfs_dur_check( + struct wlan_dfs *dfs, + struct dfs_channel *chan, + struct dfs_event *re, + uint32_t diff_ts) +{ +} +#endif + /* * dfs_print_radar_events() - Prints the Radar events. * @dfs: Pointer to wlan_dfs structure. @@ -427,7 +489,9 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs, (uint32_t) deltaT, re->re_dur, ext_chan_event_flag); - if (*found) { + if (*found && + (utils_get_dfsdomain(dfs->dfs_pdev_obj) != + DFS_CN_DOMAIN)) { ori_rf_check_delta_peak = rf->rf_check_delta_peak; /* @@ -574,6 +638,28 @@ static inline void dfs_radarfound_reset_vars( } } +/* + * dfs_print_radar_found_freq() - Print radar found frequency. + * @dfs: Pointer to wlan_dfs. + */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_print_radar_found_freq(struct wlan_dfs *dfs) +{ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "bangradar on 2nd segment cfreq = %u", + dfs->dfs_precac_secondary_freq_mhz); +} +#else +#ifdef CONFIG_CHAN_NUM_API +static void dfs_print_radar_found_freq(struct wlan_dfs *dfs) +{ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "bangradar on 2nd segment cfreq = %u", + dfs->dfs_precac_secondary_freq); +} +#endif +#endif + /** * dfs_handle_bangradar - Handle the case of bangradar * @dfs: Pointer to wlan_dfs structure. @@ -606,9 +692,7 @@ static inline int dfs_handle_bangradar( WLAN_IS_CHAN_11AC_VHT160(chan) || WLAN_IS_CHAN_11AC_VHT80_80(chan)) { dfs->is_radar_found_on_secondary_seg = 1; - dfs_debug(dfs, WLAN_DEBUG_DFS, - "bangradar on 2nd segment cfreq = %u", - dfs->dfs_precac_secondary_freq); + dfs_print_radar_found_freq(dfs); } else { dfs_debug(dfs, WLAN_DEBUG_DFS, "No second segment"); @@ -1239,6 +1323,8 @@ static inline int dfs_process_each_radarevent( dfs_add_to_pulseline(dfs, &re, &this_ts, &test_ts, &diff_ts, &index); + dfs_dur_check(dfs, chan, &re, diff_ts); + dfs_log_event(dfs, &re, this_ts, diff_ts, index); dfs_conditional_clear_delaylines(dfs, diff_ts, this_ts, re); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_radar.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_radar.c index 922a33a16213fed59f8b44f03c020bfd0ae8b53d..fae38b0cd719f39e51b6a50f74ee34e6462494c7 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_radar.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/filtering/dfs_radar.c @@ -61,6 +61,80 @@ void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst, qdf_mem_copy(dst, src, sizeof(*dst)); } +#ifdef CONFIG_CHAN_FREQ_API +struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, + int ext_chan_flag) +{ + struct dfs_state *rs = NULL; + struct dfs_channel *ch, cmp_ch1; + int i; + QDF_STATUS err; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return NULL; + } + ch = &cmp_ch1; + if (ext_chan_flag) { + err = dfs_mlme_get_extchan_for_freq( + dfs->dfs_pdev_obj, + &ch->dfs_ch_freq, + &ch->dfs_ch_flags, + &ch->dfs_ch_flagext, + &ch->dfs_ch_ieee, + &ch->dfs_ch_vhtop_ch_freq_seg1, + &ch->dfs_ch_vhtop_ch_freq_seg2, + &ch->dfs_ch_mhz_freq_seg1, + &ch->dfs_ch_mhz_freq_seg2); + + if (err == QDF_STATUS_SUCCESS) { + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "Extension channel freq = %u flags=0x%x", + ch->dfs_ch_freq, + ch->dfs_ch_flagext); + } else { + return NULL; + } + } else { + ch = dfs->dfs_curchan; + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "Primary channel freq = %u flags=0x%x", + ch->dfs_ch_freq, ch->dfs_ch_flagext); + } + + for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { + if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq == + ch->dfs_ch_freq) && + (dfs->dfs_radar[i].rs_chan.dfs_ch_flags == + ch->dfs_ch_flags)) { + if (index) + *index = (uint8_t)i; + return &dfs->dfs_radar[i]; + } + } + /* No existing channel found, look for first free channel state entry.*/ + for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { + if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) { + rs = &dfs->dfs_radar[i]; + /* Found one, set channel info and default thresholds.*/ + rs->rs_chan = *ch; + + /* Copy the parameters from the default set. */ + dfs_phyerr_param_copy(&rs->rs_param, + &dfs->dfs_defaultparams); + + if (index) + *index = (uint8_t)i; + + return rs; + } + } + dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left."); + + return NULL; +} +#else +#ifdef CONFIG_CHAN_NUM_API struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, int ext_chan_flag) { @@ -129,7 +203,103 @@ struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, return NULL; } +#endif +#endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) +{ + int is_ext_ch; + int is_fastclk = 0; + struct dfs_channel *exch, extchan; + QDF_STATUS err = QDF_STATUS_E_FAILURE; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan); + lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac); + /* + * In all modes, if the primary is DFS then we have to + * enable radar detection. In HT80_80, we can have + * primary non-DFS 80MHz with extension 80MHz DFS. + */ + if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) || + ((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) || + WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) && + WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) || + (dfs_is_precac_timer_running(dfs))) { + struct dfs_state *rs_pri = NULL, *rs_ext = NULL; + uint8_t index_pri, index_ext; + + dfs->dfs_proc_phyerr |= DFS_AR_EN; + dfs->dfs_proc_phyerr |= DFS_RADAR_EN; + dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN; + + exch = &extchan; + if (is_ext_ch) { + err = dfs_mlme_get_extchan_for_freq + ( + dfs->dfs_pdev_obj, + &exch->dfs_ch_freq, + &exch->dfs_ch_flags, + &exch->dfs_ch_flagext, + &exch->dfs_ch_ieee, + &exch->dfs_ch_vhtop_ch_freq_seg1, + &exch->dfs_ch_vhtop_ch_freq_seg2, + &exch->dfs_ch_mhz_freq_seg1, + &exch->dfs_ch_mhz_freq_seg2); + } + dfs_reset_alldelaylines(dfs); + + rs_pri = dfs_getchanstate(dfs, &index_pri, 0); + if (err == QDF_STATUS_SUCCESS) + rs_ext = dfs_getchanstate(dfs, &index_ext, 1); + + if (rs_pri && ((err == QDF_STATUS_E_FAILURE) || (rs_ext))) { + struct wlan_dfs_phyerr_param pe; + + qdf_mem_set(&pe, sizeof(pe), '\0'); + + if (index_pri != dfs->dfs_curchan_radindex) + dfs_reset_alldelaylines(dfs); + + dfs->dfs_curchan_radindex = (int16_t)index_pri; + + if (rs_ext) + dfs->dfs_extchan_radindex = (int16_t)index_ext; + + dfs_phyerr_param_copy(&pe, &rs_pri->rs_param); + dfs_debug(dfs, WLAN_DEBUG_DFS3, + "firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d", + pe.pe_firpwr, + pe.pe_rrssi, pe.pe_height, + pe.pe_prssi, pe.pe_inband, + pe.pe_relpwr, pe.pe_relstep, + pe.pe_maxlen); + + lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk, + &pe, dfs->dfsdomain); + dfs_debug(dfs, WLAN_DEBUG_DFS, + "Enabled radar detection on channel %d", + dfs->dfs_curchan->dfs_ch_freq); + + dfs->dur_multiplier = is_fastclk ? + DFS_FAST_CLOCK_MULTIPLIER : + DFS_NO_FAST_CLOCK_MULTIPLIER; + + dfs_debug(dfs, WLAN_DEBUG_DFS3, + "duration multiplier is %d", + dfs->dur_multiplier); + } else + dfs_debug(dfs, WLAN_DEBUG_DFS, + "No more radar states left"); + } +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) { int is_ext_ch; @@ -220,6 +390,8 @@ void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) "No more radar states left"); } } +#endif +#endif int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype, const uint32_t value) diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs.c index d69592f7beda953b12311a00633fed49e00d7bdd..e05d6be2c5fbe4713e0db6c5ea38afd474acf012 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2002-2006, Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -31,7 +31,7 @@ #include "../dfs_full_offload.h" #include #include "wlan_dfs_utils_api.h" -#include "../dfs_etsi_precac.h" +#include "../dfs_process_radar_found_ind.h" #include "../dfs_partial_offload_radar.h" /* Disable NOL in FW. */ @@ -69,15 +69,20 @@ static inline struct dfs_channel *dfs_alloc_dfs_curchan(void) return qdf_mem_malloc(sizeof(struct dfs_channel)); } +static inline struct dfs_channel *dfs_alloc_dfs_prevchan(void) +{ + return qdf_mem_malloc(sizeof(struct dfs_channel)); +} + /* - * dfs_free_dfs_curchan() - Free dfs_channel buffer - * @dfs_curchan: dfs_channel buffer pointer + * dfs_free_dfs_chan() - Free dfs_channel buffer + * @dfs_chan: dfs_channel buffer pointer * * Return: None */ -static inline void dfs_free_dfs_curchan(struct dfs_channel *dfs_curchan) +static inline void dfs_free_dfs_chan(struct dfs_channel *dfs_chan) { - qdf_mem_free(dfs_curchan); + qdf_mem_free(dfs_chan); } #else @@ -85,6 +90,7 @@ static inline void dfs_free_dfs_curchan(struct dfs_channel *dfs_curchan) /* Static buffers for DFS objects */ static struct wlan_dfs global_dfs; static struct dfs_channel global_dfs_curchan; +static struct dfs_channel global_dfs_prevchan; static inline struct wlan_dfs *dfs_alloc_wlan_dfs(void) { @@ -100,7 +106,12 @@ static inline struct dfs_channel *dfs_alloc_dfs_curchan(void) return &global_dfs_curchan; } -static inline void dfs_free_dfs_curchan(struct dfs_channel *dfs_curchan) +static inline struct dfs_channel *dfs_alloc_dfs_prevchan(void) +{ + return &global_dfs_prevchan; +} + +static inline void dfs_free_dfs_chan(struct dfs_channel *dfs_chan) { } #endif @@ -112,6 +123,28 @@ static inline void dfs_free_dfs_curchan(struct dfs_channel *dfs_curchan) * channel as RADAR and does not add the channel to NOL. It sends the CSA in * the current channel. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_testtimer_task) +{ + struct wlan_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + dfs->wlan_dfstest = 0; + + /* + * Flip the channel back to the original channel. + * Make sure this is done properly with a CSA. + */ + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "go back to channel %d", + dfs->wlan_dfstest_ieeechan); + dfs_mlme_start_csa_for_freq(dfs->dfs_pdev_obj, + dfs->wlan_dfstest_ieeechan, + dfs->dfs_curchan->dfs_ch_freq, + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs->dfs_curchan->dfs_ch_flags); +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_testtimer_task) { struct wlan_dfs *dfs = NULL; @@ -131,6 +164,8 @@ static os_timer_func(dfs_testtimer_task) dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2, dfs->dfs_curchan->dfs_ch_flags); } +#endif +#endif int dfs_get_debug_info(struct wlan_dfs *dfs, void *data) { @@ -162,6 +197,12 @@ int dfs_create_object(struct wlan_dfs **dfs) return 1; } + (*dfs)->dfs_prevchan = dfs_alloc_dfs_prevchan(); + if (!((*dfs)->dfs_prevchan)) { + dfs_free_wlan_dfs(*dfs); + return 1; + } + qdf_mem_zero((*dfs)->dfs_prevchan, sizeof(struct dfs_channel)); return 0; } @@ -185,9 +226,8 @@ int dfs_attach(struct wlan_dfs *dfs) return ret; } } - dfs_cac_attach(dfs); + dfs_cac_timer_attach(dfs); dfs_zero_cac_attach(dfs); - dfs_etsi_precac_attach(dfs); dfs_nol_attach(dfs); /* @@ -257,13 +297,13 @@ void dfs_detach(struct wlan_dfs *dfs) dfs_main_detach(dfs); dfs_zero_cac_detach(dfs); dfs_nol_detach(dfs); - dfs_etsi_precac_detach(dfs); } #ifndef WLAN_DFS_STATIC_MEM_ALLOC void dfs_destroy_object(struct wlan_dfs *dfs) { - dfs_free_dfs_curchan(dfs->dfs_curchan); + dfs_free_dfs_chan(dfs->dfs_prevchan); + dfs_free_dfs_chan(dfs->dfs_curchan); dfs_free_wlan_dfs(dfs); } #else @@ -700,11 +740,29 @@ int dfs_control(struct wlan_dfs *dfs, break; case DFS_SHOW_PRECAC_LISTS: dfs_print_precaclists(dfs); - dfs_print_etsi_precaclists(dfs); break; case DFS_RESET_PRECAC_LISTS: dfs_reset_precac_lists(dfs); - dfs_reset_etsi_precac_lists(dfs); + break; + case DFS_INJECT_SEQUENCE: + error = dfs_inject_synthetic_pulse_sequence(dfs, indata); + if (error) + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Not injected Synthetic pulse"); + break; + + case DFS_ALLOW_HW_PULSES: + if (insize < sizeof(u_int8_t) || !indata) { + error = -EINVAL; + break; + } + dfs_allow_hw_pulses(dfs, !!(*(u_int8_t *)indata)); + break; + case DFS_SET_PRI_MULTIPILER: + dfs->dfs_pri_multiplier = *(int *)indata; + dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Set dfs pri multiplier to %d, dfsdomain %d", + dfs->dfs_pri_multiplier, dfs->dfsdomain); break; default: error = -EINVAL; @@ -714,6 +772,40 @@ int dfs_control(struct wlan_dfs *dfs, return error; } +/** + * dfs_is_curchan_same_as_given_chan() - Find if dfs_curchan has the same + * channel parameters provided. + * @dfs_curchan: Pointer to DFS current channel structure. + * @dfs_ch_freq: New curchan's primary frequency. + * @dfs_ch_flags: New curchan's channel flags. + * @dfs_ch_flagext: New curchan's channel flags extension. + * @dfs_ch_vhtop_ch_freq_seg1: New curchan's primary centre IEEE. + * @dfs_ch_vhtop_ch_freq_seg2: New curchan's secondary centre IEEE. + * + * Return: True if curchan has the same channel parameters of the given channel, + * else false. + */ +static bool +dfs_is_curchan_same_as_given_chan(struct dfs_channel *dfs_curchan, + uint16_t dfs_ch_freq, + uint64_t dfs_ch_flags, + uint16_t dfs_ch_flagext, + uint8_t dfs_ch_vhtop_ch_freq_seg1, + uint8_t dfs_ch_vhtop_ch_freq_seg2) +{ + if ((dfs_curchan->dfs_ch_freq == dfs_ch_freq) && + (dfs_curchan->dfs_ch_flags == dfs_ch_flags) && + (dfs_curchan->dfs_ch_flagext == dfs_ch_flagext) && + (dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 == + dfs_ch_vhtop_ch_freq_seg1) && + (dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 == + dfs_ch_vhtop_ch_freq_seg2)) + return true; + + return false; +} + +#ifdef CONFIG_CHAN_NUM_API void dfs_set_current_channel(struct wlan_dfs *dfs, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -727,6 +819,29 @@ void dfs_set_current_channel(struct wlan_dfs *dfs, return; } + if (!dfs->dfs_curchan) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_curchan is NULL"); + return; + } + + /* Check if the input parameters are the same as that of dfs_curchan */ + if (dfs_is_curchan_same_as_given_chan(dfs->dfs_curchan, + dfs_ch_freq, + dfs_ch_flags, + dfs_ch_flagext, + dfs_ch_vhtop_ch_freq_seg1, + dfs_ch_vhtop_ch_freq_seg2)) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "dfs_curchan already updated"); + return; + } + + /* Update dfs previous channel with the old dfs_curchan, if it exists */ + if (dfs->dfs_curchan->dfs_ch_freq) + qdf_mem_copy(dfs->dfs_prevchan, + dfs->dfs_curchan, + sizeof(struct dfs_channel)); + dfs->dfs_curchan->dfs_ch_freq = dfs_ch_freq; dfs->dfs_curchan->dfs_ch_flags = dfs_ch_flags; dfs->dfs_curchan->dfs_ch_flagext = dfs_ch_flagext; @@ -734,6 +849,53 @@ void dfs_set_current_channel(struct wlan_dfs *dfs, dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 = dfs_ch_vhtop_ch_freq_seg1; dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_ch_vhtop_ch_freq_seg2; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void dfs_set_current_channel_for_freq(struct wlan_dfs *dfs, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2) + +{ + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + /* Check if the input parameters are the same as that of dfs_curchan */ + if (dfs_is_curchan_same_as_given_chan(dfs->dfs_curchan, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_vhtop_freq_seg1, + dfs_chan_vhtop_freq_seg2)) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "dfs_curchan already updated"); + return; + } + + /* Update dfs previous channel with the old dfs_curchan, if it exists */ + if (dfs->dfs_curchan->dfs_ch_freq) + qdf_mem_copy(dfs->dfs_prevchan, + dfs->dfs_curchan, + sizeof(struct dfs_channel)); + + dfs->dfs_curchan->dfs_ch_freq = dfs_chan_freq; + dfs->dfs_curchan->dfs_ch_flags = dfs_chan_flags; + dfs->dfs_curchan->dfs_ch_flagext = dfs_chan_flagext; + dfs->dfs_curchan->dfs_ch_ieee = dfs_chan_ieee; + dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 = dfs_chan_vhtop_freq_seg1; + dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_chan_vhtop_freq_seg2; + dfs->dfs_curchan->dfs_ch_mhz_freq_seg1 = dfs_chan_mhz_freq_seg1; + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2 = dfs_chan_mhz_freq_seg2; +} +#endif void dfs_update_cur_chan_flags(struct wlan_dfs *dfs, uint64_t flags, @@ -742,3 +904,40 @@ void dfs_update_cur_chan_flags(struct wlan_dfs *dfs, dfs->dfs_curchan->dfs_ch_flags = flags; dfs->dfs_curchan->dfs_ch_flagext = flagext; } + +int dfs_reinit_timers(struct wlan_dfs *dfs) +{ + dfs_cac_timer_attach(dfs); + dfs_zero_cac_timer_init(dfs->dfs_soc_obj); + dfs_nol_timer_init(dfs); + dfs_main_task_testtimer_init(dfs); + return 0; +} + +void dfs_reset_dfs_prevchan(struct wlan_dfs *dfs) +{ + qdf_mem_zero(dfs->dfs_prevchan, sizeof(struct dfs_channel)); +} + +bool dfs_is_hw_mode_switch_in_progress(struct wlan_dfs *dfs) +{ + return lmac_dfs_is_hw_mode_switch_in_progress(dfs->dfs_pdev_obj); +} + +void dfs_complete_deferred_tasks(struct wlan_dfs *dfs) +{ + if (dfs->dfs_defer_params.is_radar_detected) { + /* Handle radar event that was deferred and free the temporary + * storage of the radar event parameters. + */ + dfs_process_radar_ind(dfs, dfs->dfs_defer_params.radar_params); + qdf_mem_free(dfs->dfs_defer_params.radar_params); + dfs->dfs_defer_params.is_radar_detected = false; + } else if (dfs->dfs_defer_params.is_cac_completed) { + /* Handle CAC completion event that was deferred for HW mode + * switch. + */ + dfs_process_cac_completion(dfs); + dfs->dfs_defer_params.is_cac_completed = false; + } +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_cac.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_cac.c index f5dc99db66f644adae74ff9f4dbfc30c01680ac5..0bbeb00858ce23851bcbb15b03edee2c889696bd 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_cac.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_cac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting * All rights reserved. * @@ -30,7 +30,6 @@ #include "../dfs_channel.h" #include "../dfs_zero_cac.h" -#include "../dfs_etsi_precac.h" #include #include "wlan_dfs_utils_api.h" #include "wlan_dfs_mlme_api.h" @@ -65,6 +64,7 @@ int dfs_get_override_cac_timeout(struct wlan_dfs *dfs, int *cac_timeout) return 0; } +#ifdef CONFIG_CHAN_NUM_API void dfs_cac_valid_reset(struct wlan_dfs *dfs, uint8_t prevchan_ieee, uint32_t prevchan_flags) @@ -80,6 +80,24 @@ void dfs_cac_valid_reset(struct wlan_dfs *dfs, } } } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void dfs_cac_valid_reset_for_freq(struct wlan_dfs *dfs, + uint16_t prevchan_freq, + uint32_t prevchan_flags) +{ + if (dfs->dfs_cac_valid_time) { + if ((prevchan_freq != dfs->dfs_curchan->dfs_ch_freq) || + (prevchan_flags != dfs->dfs_curchan->dfs_ch_flags)) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Cancelling timer & clearing cac_valid"); + qdf_timer_stop(&dfs->dfs_cac_valid_timer); + dfs->dfs_cac_valid = 0; + } + } +} +#endif /** * dfs_cac_valid_timeout() - Timeout function for dfs_cac_valid_timer @@ -94,14 +112,107 @@ static os_timer_func(dfs_cac_valid_timeout) dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, ": Timed out!!"); } +/** + * dfs_clear_cac_started_chan() - Clear dfs cac started channel. + * @dfs: Pointer to wlan_dfs structure. + */ +static void dfs_clear_cac_started_chan(struct wlan_dfs *dfs) +{ + qdf_mem_zero(&dfs->dfs_cac_started_chan, + sizeof(dfs->dfs_cac_started_chan)); +} + +void dfs_process_cac_completion(struct wlan_dfs *dfs) +{ + enum phy_ch_width ch_width = CH_WIDTH_INVALID; + uint16_t primary_chan_freq = 0, secondary_chan_freq = 0; + struct dfs_channel *dfs_curchan; + + dfs->dfs_cac_timer_running = 0; + dfs_curchan = dfs->dfs_curchan; + + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "cac expired, chan %d cur time %d", + dfs->dfs_curchan->dfs_ch_freq, + (qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000)); + + /* + * When radar is detected during a CAC we are woken up prematurely to + * switch to a new channel. Check the channel to decide how to act. + */ + if (WLAN_IS_CHAN_RADAR(dfs->dfs_curchan)) { + dfs_mlme_mark_dfs_for_freq(dfs->dfs_pdev_obj, + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq, + dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs_curchan->dfs_ch_flags); + dfs_debug(dfs, WLAN_DEBUG_DFS, + "CAC timer on chan %u (%u MHz) stopped due to radar", + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); + } else { + dfs_debug(dfs, WLAN_DEBUG_DFS, + "CAC timer on channel %u (%u MHz) expired;" + "no radar detected", + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); + + /* On CAC completion, set the bit 'cac_valid'. + * CAC will not be re-done if this bit is reset. + * The flag will be reset when dfs_cac_valid_timer + * timesout. + */ + if (dfs->dfs_cac_valid_time) { + dfs->dfs_cac_valid = 1; + qdf_timer_mod(&dfs->dfs_cac_valid_timer, + dfs->dfs_cac_valid_time * 1000); + } + + dfs_find_chwidth_and_center_chan_for_freq(dfs, + &ch_width, + &primary_chan_freq, + &secondary_chan_freq); + /* Mark the current channel as preCAC done */ + dfs_mark_precac_done_for_freq(dfs, primary_chan_freq, + secondary_chan_freq, ch_width); + } + + dfs_clear_cac_started_chan(dfs); + /* Iterate over the nodes, processing the CAC completion event. */ + dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0); + + /* Send a CAC timeout, VAP up event to user space */ + dfs_mlme_deliver_event_up_after_cac(dfs->dfs_pdev_obj); + + if (dfs->dfs_defer_precac_channel_change == 1) { + dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj); + dfs->dfs_defer_precac_channel_change = 0; + } +} + /** * dfs_cac_timeout() - DFS cactimeout function. * * Sets dfs_cac_timer_running to 0 and dfs_cac_valid_timer. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_cac_timeout) +{ + struct wlan_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + + if (dfs_is_hw_mode_switch_in_progress(dfs)) + dfs->dfs_defer_params.is_cac_completed = true; + else + dfs_process_cac_completion(dfs); +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_cac_timeout) { struct wlan_dfs *dfs = NULL; + enum phy_ch_width ch_width = CH_WIDTH_INVALID; + uint8_t primary_chan_ieee = 0, secondary_chan_ieee = 0; OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); dfs->dfs_cac_timer_running = 0; @@ -110,10 +221,6 @@ static os_timer_func(dfs_cac_timeout) dfs->dfs_curchan->dfs_ch_freq, (qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000)); - /* Once CAC is done, add channel to ETSI precacdone list*/ - if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN) - dfs_add_to_etsi_precac_done_list(dfs); - /* * When radar is detected during a CAC we are woken up prematurely to * switch to a new channel. Check the channel to decide how to act. @@ -144,8 +251,17 @@ static os_timer_func(dfs_cac_timeout) qdf_timer_mod(&dfs->dfs_cac_valid_timer, dfs->dfs_cac_valid_time * 1000); } + + dfs_find_chwidth_and_center_chan(dfs, + &ch_width, + &primary_chan_ieee, + &secondary_chan_ieee); + /* Mark the current channel as preCAC done */ + dfs_mark_precac_done(dfs, primary_chan_ieee, + secondary_chan_ieee, ch_width); } + dfs_clear_cac_started_chan(dfs); /* Iterate over the nodes, processing the CAC completion event. */ dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0); @@ -157,9 +273,13 @@ static os_timer_func(dfs_cac_timeout) dfs->dfs_defer_precac_channel_change = 0; } } +#endif +#endif -void dfs_cac_timer_init(struct wlan_dfs *dfs) +void dfs_cac_timer_attach(struct wlan_dfs *dfs) { + dfs->dfs_cac_timeout_override = -1; + dfs->wlan_dfs_cac_time = WLAN_DFS_WAIT_MS; qdf_timer_init(NULL, &(dfs->dfs_cac_timer), dfs_cac_timeout, @@ -173,21 +293,12 @@ void dfs_cac_timer_init(struct wlan_dfs *dfs) QDF_TIMER_TYPE_WAKE_APPS); } -void dfs_cac_attach(struct wlan_dfs *dfs) -{ - dfs->dfs_cac_timeout_override = -1; - dfs->wlan_dfs_cac_time = WLAN_DFS_WAIT_MS; - dfs_cac_timer_init(dfs); -} - void dfs_cac_timer_reset(struct wlan_dfs *dfs) { qdf_timer_stop(&dfs->dfs_cac_timer); dfs_get_override_cac_timeout(dfs, &(dfs->dfs_cac_timeout_override)); - qdf_mem_zero(&dfs->dfs_cac_started_chan, - sizeof(dfs->dfs_cac_started_chan)); - + dfs_clear_cac_started_chan(dfs); } void dfs_cac_timer_detach(struct wlan_dfs *dfs) @@ -203,6 +314,31 @@ int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs) return dfs->dfs_cac_timer_running; } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_start_cac_timer(struct wlan_dfs *dfs) +{ + int cac_timeout = 0; + struct dfs_channel *chan = dfs->dfs_curchan; + + cac_timeout = + dfs_mlme_get_cac_timeout_for_freq(dfs->dfs_pdev_obj, + chan->dfs_ch_freq, + chan->dfs_ch_mhz_freq_seg2, + chan->dfs_ch_flags); + + dfs->dfs_cac_started_chan = *chan; + + dfs_debug(dfs, WLAN_DEBUG_DFS, + "chan = %d cfreq2 = %d timeout = %d sec, curr_time = %d sec", + chan->dfs_ch_ieee, chan->dfs_ch_vhtop_ch_freq_seg2, + cac_timeout, + qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000); + + qdf_timer_mod(&dfs->dfs_cac_timer, cac_timeout * 1000); + dfs->dfs_cac_aborted = 0; +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_start_cac_timer(struct wlan_dfs *dfs) { int cac_timeout = 0; @@ -224,10 +360,13 @@ void dfs_start_cac_timer(struct wlan_dfs *dfs) qdf_timer_mod(&dfs->dfs_cac_timer, cac_timeout * 1000); dfs->dfs_cac_aborted = 0; } +#endif +#endif void dfs_cancel_cac_timer(struct wlan_dfs *dfs) { qdf_timer_stop(&dfs->dfs_cac_timer); + dfs_clear_cac_started_chan(dfs); } void dfs_cac_stop(struct wlan_dfs *dfs) @@ -241,6 +380,7 @@ void dfs_cac_stop(struct wlan_dfs *dfs) qdf_timer_stop(&dfs->dfs_cac_timer); if (dfs->dfs_cac_timer_running) dfs->dfs_cac_aborted = 1; + dfs_clear_cac_started_chan(dfs); dfs->dfs_cac_timer_running = 0; } @@ -252,49 +392,29 @@ void dfs_stacac_stop(struct wlan_dfs *dfs) dfs_debug(dfs, WLAN_DEBUG_DFS, "Stopping STA CAC Timer %d procphyerr 0x%08x", dfs->dfs_curchan->dfs_ch_freq, phyerr); + dfs_clear_cac_started_chan(dfs); } -bool dfs_is_subset_channel(struct wlan_dfs *dfs, - struct dfs_channel *old_chan, - struct dfs_channel *new_chan) +/* + * dfs_is_subset_channel_for_freq() - Find out if prev channel and current + * channel are subsets of each other. + * @old_subchans_freq: Pointer to previous sub-channels freq. + * @old_n_chans: Number of previous sub-channels. + * @new_subchans_freq: Pointer to new sub-channels freq. + * @new_n_chans: Number of new sub-channels + */ +#ifdef CONFIG_CHAN_FREQ_API +static bool +dfs_is_subset_channel_for_freq(uint16_t *old_subchans_freq, + uint8_t old_n_chans, + uint16_t *new_subchans_freq, + uint8_t new_n_chans) { - uint8_t old_subchans[NUM_CHANNELS_160MHZ]; - uint8_t new_subchans[NUM_CHANNELS_160MHZ]; - uint8_t old_n_chans; - uint8_t new_n_chans; - int i = 0, j = 0; - bool is_found = false; - - if (WLAN_IS_CHAN_11AC_VHT160(old_chan) || - WLAN_IS_CHAN_11AC_VHT80_80(old_chan)) { - /* If primary segment is NON-DFS */ - if (!WLAN_IS_CHAN_DFS(old_chan)) - old_n_chans = dfs_get_bonding_channels(dfs, - old_chan, - SEG_ID_SECONDARY, - old_subchans); - else - old_n_chans = dfs_get_bonding_channels_without_seg_info( - old_chan, old_subchans); - } else { - old_n_chans = dfs_get_bonding_channels_without_seg_info( - old_chan, old_subchans); - } + bool is_found; + int i, j; - if (WLAN_IS_CHAN_11AC_VHT160(new_chan) || - WLAN_IS_CHAN_11AC_VHT80_80(new_chan)) { - /* If primary segment is NON-DFS */ - if (WLAN_IS_CHAN_DFS(new_chan)) - new_n_chans = dfs_get_bonding_channels( - dfs, new_chan, SEG_ID_SECONDARY, - new_subchans); - else - new_n_chans = dfs_get_bonding_channels_without_seg_info( - new_chan, new_subchans); - } else { - new_n_chans = dfs_get_bonding_channels_without_seg_info( - new_chan, new_subchans); - } + if (!new_n_chans) + return true; if (new_n_chans > old_n_chans) return false; @@ -302,7 +422,7 @@ bool dfs_is_subset_channel(struct wlan_dfs *dfs, for (i = 0; i < new_n_chans; i++) { is_found = false; for (j = 0; j < old_n_chans; j++) { - if (new_subchans[i] == old_subchans[j]) { + if (new_subchans_freq[i] == old_subchans_freq[j]) { is_found = true; break; } @@ -317,22 +437,83 @@ bool dfs_is_subset_channel(struct wlan_dfs *dfs, return is_found; } +#endif -bool dfs_is_curchan_subset_of_cac_started_chan(struct wlan_dfs *dfs) +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_find_dfs_sub_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *chan, + uint16_t *subchan_arr) { - return dfs_is_subset_channel(dfs, &dfs->dfs_cac_started_chan, - dfs->dfs_curchan); + if (WLAN_IS_CHAN_MODE_160(chan) || WLAN_IS_CHAN_MODE_80_80(chan)) { + if (WLAN_IS_CHAN_DFS(chan) && WLAN_IS_CHAN_DFS_CFREQ2(chan)) + return dfs_get_bonding_channel_without_seg_info_for_freq + (chan, subchan_arr); + if (WLAN_IS_CHAN_DFS(chan)) + return dfs_get_bonding_channels_for_freq(dfs, + chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + subchan_arr); + if (WLAN_IS_CHAN_DFS_CFREQ2(chan)) + return dfs_get_bonding_channels_for_freq + (dfs, chan, SEG_ID_SECONDARY, + DETECTOR_ID_0, subchan_arr); + /* All channels in 160/80_80 BW are non DFS, return 0 + * as number of subchannels + */ + return 0; + } else if (WLAN_IS_CHAN_DFS(chan)) { + return dfs_get_bonding_channel_without_seg_info_for_freq + (chan, subchan_arr); + } + /* All channels are non DFS, return 0 as number of subchannels*/ + return 0; } +#endif -void dfs_clear_cac_started_chan(struct wlan_dfs *dfs) +/* dfs_is_new_chan_subset_of_old_chan() - Find if new channel is subset of + * old channel. + * @dfs: Pointer to wlan_dfs structure. + * @new_chan: Pointer to new channel of dfs_channel structure. + * @old_chan: Pointer to old channel of dfs_channel structure. + * + * Return: True if new channel is subset of old channel, else false. + */ +#ifdef CONFIG_CHAN_FREQ_API +static bool +dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs, + struct dfs_channel *new_chan, + struct dfs_channel *old_chan) { - qdf_mem_zero(&dfs->dfs_cac_started_chan, - sizeof(dfs->dfs_cac_started_chan)); + uint16_t new_subchans[NUM_CHANNELS_160MHZ]; + uint16_t old_subchans[NUM_CHANNELS_160MHZ]; + uint8_t n_new_subchans = 0; + uint8_t n_old_subchans = 0; + + /* Given channel is the old channel. i.e. The channel which + * should have the new channel as subset. + */ + n_old_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, old_chan, + old_subchans); + /* cur_chan is the new channel to be check if subset of old channel */ + n_new_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, new_chan, + new_subchans); + + return dfs_is_subset_channel_for_freq(old_subchans, + n_old_subchans, + new_subchans, + n_new_subchans); } +#endif -bool dfs_check_for_cac_start(struct wlan_dfs *dfs, - bool *continue_current_cac) +bool dfs_is_cac_required(struct wlan_dfs *dfs, + struct dfs_channel *cur_chan, + struct dfs_channel *prev_chan, + bool *continue_current_cac) { + struct dfs_channel *cac_started_chan = &dfs->dfs_cac_started_chan; + if (dfs->dfs_ignore_dfs || dfs->dfs_cac_valid || dfs->dfs_ignore_cac) { dfs_debug(dfs, WLAN_DEBUG_DFS, "Skip CAC, ignore_dfs = %d cac_valid = %d ignore_cac = %d", @@ -341,18 +522,11 @@ bool dfs_check_for_cac_start(struct wlan_dfs *dfs, return false; } - if (dfs_is_etsi_precac_done(dfs)) { - dfs_debug(dfs, WLAN_DEBUG_DFS, - "ETSI PRE-CAC alreay done on this channel %d", - dfs->dfs_curchan->dfs_ch_ieee); - return false; - } - /* If the channel has completed PRE-CAC then CAC can be skipped here. */ - if (dfs_is_precac_done(dfs, dfs->dfs_curchan)) { + if (dfs_is_precac_done(dfs, cur_chan)) { dfs_debug(dfs, WLAN_DEBUG_DFS, "PRE-CAC alreay done on this channel %d", - dfs->dfs_curchan->dfs_ch_ieee); + cur_chan->dfs_ch_ieee); return false; } @@ -365,7 +539,9 @@ bool dfs_check_for_cac_start(struct wlan_dfs *dfs, * VAP(1) comes up in the same channel then instead of * cancelling the CAC we can let the CAC continue. */ - if (dfs_is_curchan_subset_of_cac_started_chan(dfs)) { + if (dfs_is_new_chan_subset_of_old_chan(dfs, + cur_chan, + cac_started_chan)) { *continue_current_cac = true; } else { /* New CAC is needed, cancel the running CAC @@ -385,7 +561,9 @@ bool dfs_check_for_cac_start(struct wlan_dfs *dfs, dfs_cancel_cac_timer(dfs); } } else { /* CAC timer is not running. */ - if (dfs_is_curchan_subset_of_cac_started_chan(dfs)) { + if (dfs_is_new_chan_subset_of_old_chan(dfs, + cur_chan, + prev_chan)) { /* AP bandwidth reduce case: * When AP detects the RADAR in in-service monitoring * mode in channel A, it cancels the running CAC and diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_filter_init.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_filter_init.c index 7a7ba255831183628f85334ffb0b5e06d7db5e72..01f3b821d370a5806aa0e53dd5b0b8095e1b7f8b 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_filter_init.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_filter_init.c @@ -218,6 +218,7 @@ int dfs_main_attach(struct wlan_dfs *dfs) /*Verify : Passing NULL to qdf_timer_init().*/ dfs_main_task_timer_init(dfs); + dfs_allow_hw_pulses(dfs, true); dfs_host_wait_timer_init(dfs); WLAN_DFSQ_LOCK_CREATE(dfs); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_nol.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_nol.c index 45a0ffdee782751a191dd234cde39298422b43f4..eda749ad4c1b5c9a68d82e0393ce6d5eac1fbfac 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_nol.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_nol.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2002-2010, Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -55,6 +55,64 @@ bool dfs_get_update_nol_flag(struct wlan_dfs *dfs) * * Clears the WLAN_CHAN_DFS_RADAR_FOUND flag for the NOL timeout channel. */ +/* Unused function */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_nol_timeout) +{ + struct dfs_channel *c = NULL, lc; + unsigned long oldest, now; + struct wlan_dfs *dfs = NULL; + int i; + int nchans = 0; + + c = &lc; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans); + + now = oldest = qdf_system_ticks(); + for (i = 0; i < nchans; i++) { + dfs_mlme_get_dfs_channels_for_freq + (dfs->dfs_pdev_obj, + &c->dfs_ch_freq, + &c->dfs_ch_flags, + &c->dfs_ch_flagext, + &c->dfs_ch_ieee, + &c->dfs_ch_vhtop_ch_freq_seg1, + &c->dfs_ch_vhtop_ch_freq_seg2, + &c->dfs_ch_mhz_freq_seg1, + &c->dfs_ch_mhz_freq_seg2, + i); + if (WLAN_IS_CHAN_RADAR(c)) { + if (qdf_system_time_after_eq(now, + dfs->dfs_nol_event[i] + + dfs_get_nol_timeout(dfs))) { + c->dfs_ch_flagext &= ~WLAN_CHAN_DFS_RADAR_FOUND; + if (c->dfs_ch_flags & WLAN_CHAN_DFS_RADAR) { + /* + * NB: do this here so we get only one + * msg instead of one for every channel + * table entry. + */ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "radar on channel %u (%u MHz) cleared after timeout", + c->dfs_ch_ieee, + c->dfs_ch_freq); + } + } else if (dfs->dfs_nol_event[i] < oldest) { + oldest = dfs->dfs_nol_event[i]; + } + } + } + if (oldest != now) { + /* Arrange to process next channel up for a status change. */ + qdf_timer_mod(&dfs->dfs_nol_timer, + dfs_get_nol_timeout(dfs) - + qdf_system_ticks_to_msecs(qdf_system_ticks())); + } +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_nol_timeout) { struct dfs_channel *c = NULL, lc; @@ -108,6 +166,8 @@ static os_timer_func(dfs_nol_timeout) qdf_system_ticks_to_msecs(qdf_system_ticks())); } } +#endif +#endif /** * dfs_nol_elem_free_work_cb - Free NOL element @@ -227,6 +287,40 @@ static void dfs_nol_delete(struct wlan_dfs *dfs, * * When NOL times out, this function removes the channel from NOL list. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_remove_from_nol) +{ + struct dfs_nolelem *nol_arg; + struct wlan_dfs *dfs; + uint16_t delfreq; + uint16_t delchwidth; + uint8_t chan; + + OS_GET_TIMER_ARG(nol_arg, struct dfs_nolelem *); + + dfs = nol_arg->nol_dfs; + delfreq = nol_arg->nol_freq; + delchwidth = nol_arg->nol_chwidth; + + /* Delete the given NOL entry. */ + DFS_NOL_DELETE_CHAN_LOCKED(dfs, delfreq, delchwidth); + + /* Update the wireless stack with the new NOL. */ + dfs_nol_update(dfs); + + dfs_mlme_nol_timeout_notification(dfs->dfs_pdev_obj); + chan = utils_dfs_freq_to_chan(delfreq); + utils_dfs_deliver_event(dfs->dfs_pdev_obj, delfreq, + WLAN_EV_NOL_FINISHED); + dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, + "remove channel %d from nol", chan); + utils_dfs_unmark_precac_nol_for_freq(dfs->dfs_pdev_obj, delfreq); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + &delfreq, 1, DFS_NOL_RESET); + utils_dfs_save_nol(dfs->dfs_pdev_obj); +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_remove_from_nol) { struct dfs_nolelem *nol_arg; @@ -253,12 +347,13 @@ static os_timer_func(dfs_remove_from_nol) WLAN_EV_NOL_FINISHED); dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, "remove channel %d from nol", chan); - utils_dfs_add_to_etsi_precac_required_list(dfs->dfs_pdev_obj, - &chan); + utils_dfs_unmark_precac_nol(dfs->dfs_pdev_obj, chan); utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, &chan, 1, DFS_NOL_RESET); utils_dfs_save_nol(dfs->dfs_pdev_obj); } +#endif +#endif void dfs_print_nol(struct wlan_dfs *dfs) { @@ -274,16 +369,16 @@ void dfs_print_nol(struct wlan_dfs *dfs) nol = dfs->dfs_nol; dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, "NOL"); while (nol) { - diff_ms = qdf_do_div(qdf_get_monotonic_boottime() - - nol->nol_start_us, 1000); + diff_ms = qdf_system_ticks_to_msecs(qdf_system_ticks() - + nol->nol_start_ticks); diff_ms = (nol->nol_timeout_ms - diff_ms); remaining_sec = diff_ms / 1000; /* Convert to seconds */ dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, - "nol:%d channel=%d MHz width=%d MHz time left=%u seconds nol start_us=%llu", + "nol:%d channel=%d MHz width=%d MHz time left=%u seconds nol starttick=%llu", i++, nol->nol_freq, nol->nol_chwidth, remaining_sec, - nol->nol_start_us); + (uint64_t)nol->nol_start_ticks); nol = nol->nol_next; } } @@ -338,13 +433,52 @@ void dfs_get_nol(struct wlan_dfs *dfs, while (nol) { dfs_nol[*nchan].nol_freq = nol->nol_freq; dfs_nol[*nchan].nol_chwidth = nol->nol_chwidth; - dfs_nol[*nchan].nol_start_us = nol->nol_start_us; + dfs_nol[*nchan].nol_start_ticks = nol->nol_start_ticks; dfs_nol[*nchan].nol_timeout_ms = nol->nol_timeout_ms; ++(*nchan); nol = nol->nol_next; } } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_set_nol(struct wlan_dfs *dfs, + struct dfsreq_nolelem *dfs_nol, + int nchan) +{ +#define TIME_IN_MS 1000 + uint32_t nol_time_lft_ms; + struct dfs_channel chan; + int i; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + for (i = 0; i < nchan; i++) { + nol_time_lft_ms = + qdf_system_ticks_to_msecs(qdf_system_ticks() - + dfs_nol[i].nol_start_ticks); + + if (nol_time_lft_ms < dfs_nol[i].nol_timeout_ms) { + chan.dfs_ch_freq = dfs_nol[i].nol_freq; + chan.dfs_ch_flags = 0; + chan.dfs_ch_flagext = 0; + nol_time_lft_ms = + (dfs_nol[i].nol_timeout_ms - nol_time_lft_ms); + + DFS_NOL_ADD_CHAN_LOCKED(dfs, chan.dfs_ch_freq, + (nol_time_lft_ms / TIME_IN_MS)); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + &chan.dfs_ch_freq, + 1, DFS_NOL_SET); + } + } +#undef TIME_IN_MS + dfs_nol_update(dfs); +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_set_nol(struct wlan_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan) @@ -361,8 +495,9 @@ void dfs_set_nol(struct wlan_dfs *dfs, } for (i = 0; i < nchan; i++) { - nol_time_left_ms = qdf_do_div(qdf_get_monotonic_boottime() - - dfs_nol[i].nol_start_us, 1000); + nol_time_left_ms = + qdf_system_ticks_to_msecs(qdf_system_ticks() - + dfs_nol[i].nol_start_ticks); if (nol_time_left_ms < dfs_nol[i].nol_timeout_ms) { chan.dfs_ch_freq = dfs_nol[i].nol_freq; @@ -381,6 +516,8 @@ void dfs_set_nol(struct wlan_dfs *dfs, #undef TIME_IN_MS dfs_nol_update(dfs); } +#endif +#endif void dfs_nol_addchan(struct wlan_dfs *dfs, uint16_t freq, @@ -402,7 +539,7 @@ void dfs_nol_addchan(struct wlan_dfs *dfs, while (nol) { if ((nol->nol_freq == freq) && (nol->nol_chwidth == ch_width)) { - nol->nol_start_us = qdf_get_monotonic_boottime(); + nol->nol_start_ticks = qdf_system_ticks(); nol->nol_timeout_ms = dfs_nol_timeout * TIME_IN_MS; dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, @@ -427,7 +564,7 @@ void dfs_nol_addchan(struct wlan_dfs *dfs, elem->nol_dfs = dfs; elem->nol_freq = freq; elem->nol_chwidth = ch_width; - elem->nol_start_us = qdf_get_monotonic_boottime(); + elem->nol_start_ticks = qdf_system_ticks(); elem->nol_timeout_ms = dfs_nol_timeout*TIME_IN_MS; elem->nol_next = NULL; if (prev) { @@ -438,8 +575,9 @@ void dfs_nol_addchan(struct wlan_dfs *dfs, } qdf_timer_init(NULL, - &elem->nol_timer, dfs_remove_from_nol, - elem, QDF_TIMER_TYPE_WAKE_APPS); + &elem->nol_timer, dfs_remove_from_nol, + elem, QDF_TIMER_TYPE_WAKE_APPS); + qdf_timer_mod(&elem->nol_timer, dfs_nol_timeout * TIME_IN_MS); /* Update the NOL counter. */ @@ -542,9 +680,41 @@ void dfs_nol_free_list(struct wlan_dfs *dfs) dfs->dfs_nol = NULL; } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_nol_timer_cleanup(struct wlan_dfs *dfs) +{ + struct dfs_nolelem *nol; + uint16_t nol_freq; + + while (true) { + WLAN_DFSNOL_LOCK(dfs); + + nol = dfs->dfs_nol; + if (nol) { + dfs->dfs_nol = nol->nol_next; + dfs->dfs_nol_count--; + nol_freq = nol->nol_freq; + WLAN_DFSNOL_UNLOCK(dfs); + utils_dfs_reg_update_nol_chan_for_freq( + dfs->dfs_pdev_obj, + &nol_freq, + 1, + DFS_NOL_RESET); + + qdf_timer_free(&nol->nol_timer); + qdf_mem_free(nol); + } else { + WLAN_DFSNOL_UNLOCK(dfs); + break; + } + } +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_nol_timer_cleanup(struct wlan_dfs *dfs) { struct dfs_nolelem *nol; + uint8_t nol_chan; while (true) { WLAN_DFSNOL_LOCK(dfs); @@ -553,7 +723,12 @@ void dfs_nol_timer_cleanup(struct wlan_dfs *dfs) if (nol) { dfs->dfs_nol = nol->nol_next; dfs->dfs_nol_count--; + nol_chan = utils_dfs_freq_to_chan(nol->nol_freq); WLAN_DFSNOL_UNLOCK(dfs); + utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, + &nol_chan, + 1, + DFS_NOL_RESET); qdf_timer_free(&nol->nol_timer); qdf_mem_free(nol); @@ -563,6 +738,8 @@ void dfs_nol_timer_cleanup(struct wlan_dfs *dfs) } } } +#endif +#endif void dfs_nol_workqueue_cleanup(struct wlan_dfs *dfs) { @@ -586,6 +763,42 @@ void dfs_getnol(struct wlan_dfs *dfs, void *dfs_nolinfo) DFS_GET_NOL_LOCKED(dfs, nolinfo->dfs_nol, &(nolinfo->dfs_ch_nchans)); } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_clear_nolhistory(struct wlan_dfs *dfs) +{ + struct dfs_channel *chan_list; + int nchans = 0; + bool sta_opmode; + + if (!dfs->dfs_is_stadfs_enabled) + return; + + sta_opmode = dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj); + if (!sta_opmode) + return; + + nchans = dfs_get_num_chans(); + + chan_list = qdf_mem_malloc(nchans * sizeof(*chan_list)); + if (!chan_list) + return; + + utils_dfs_get_nol_history_chan_list(dfs->dfs_pdev_obj, + (void *)chan_list, &nchans); + if (!nchans) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero chans"); + qdf_mem_free(chan_list); + return; + } + + utils_dfs_reg_update_nol_history_chan_for_freq(dfs->dfs_pdev_obj, + (void *)chan_list, nchans, + DFS_NOL_HISTORY_RESET); + + qdf_mem_free(chan_list); +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_clear_nolhistory(struct wlan_dfs *dfs) { struct dfs_channel *chan_list; @@ -619,15 +832,52 @@ void dfs_clear_nolhistory(struct wlan_dfs *dfs) qdf_mem_free(chan_list); } +#endif +#endif -#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \ + defined(CONFIG_CHAN_FREQ_API) +void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) +{ + struct dfs_nolelem *nol; + uint16_t freq_list[NUM_CHANNELS_160MHZ]; + int i, nchans = 0; + + nchans = dfs_get_bonding_channels_for_freq(dfs, + &dfs->dfs_radar_found_chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + freq_list); + + WLAN_DFSNOL_LOCK(dfs); + for (i = 0; i < nchans && i < NUM_CHANNELS_160MHZ; i++) { + nol = dfs->dfs_nol; + while (nol) { + if (nol->nol_freq == freq_list[i]) { + OS_SET_TIMER(&nol->nol_timer, 0); + break; + } + nol = nol->nol_next; + } + } + WLAN_DFSNOL_UNLOCK(dfs); + + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + freq_list, nchans, DFS_NOL_RESET); +} +#else +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \ + defined(CONFIG_CHAN_NUM_API) void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) { struct dfs_nolelem *nol; uint8_t channels[NUM_CHANNELS_160MHZ]; int i, nchans = 0; - nchans = dfs_get_bonding_channels(dfs, &dfs->dfs_radar_found_chan, 0, + nchans = dfs_get_bonding_channels(dfs, + &dfs->dfs_radar_found_chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, channels); WLAN_DFSNOL_LOCK(dfs); @@ -648,3 +898,102 @@ void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) channels, nchans, DFS_NOL_RESET); } #endif +#endif + +void dfs_init_tmp_psoc_nol(struct wlan_dfs *dfs, uint8_t num_radios) +{ + struct dfs_soc_priv_obj *dfs_soc_obj = dfs->dfs_soc_obj; + + if (WLAN_UMAC_MAX_PDEVS < num_radios) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, + "num_radios (%u) exceeds limit", num_radios); + return; + } + + /* Allocate the temporary psoc NOL copy structure for the number + * of radios provided. + */ + dfs_soc_obj->dfs_psoc_nolinfo = + qdf_mem_malloc(sizeof(struct dfsreq_nolinfo) * num_radios); +} + +void dfs_deinit_tmp_psoc_nol(struct wlan_dfs *dfs) +{ + struct dfs_soc_priv_obj *dfs_soc_obj = dfs->dfs_soc_obj; + + if (!dfs_soc_obj->dfs_psoc_nolinfo) + return; + + qdf_mem_free(dfs_soc_obj->dfs_psoc_nolinfo); + dfs_soc_obj->dfs_psoc_nolinfo = NULL; +} + +void dfs_save_dfs_nol_in_psoc(struct wlan_dfs *dfs, + uint8_t pdev_id, + uint16_t low_5ghz_freq, + uint16_t high_5ghz_freq) +{ + struct dfs_soc_priv_obj *dfs_soc_obj = dfs->dfs_soc_obj; + struct dfsreq_nolinfo tmp_nolinfo, *nolinfo; + uint32_t i, num_chans = 0; + uint16_t tmp_freq; + + if (!dfs->dfs_nol_count) + return; + + if (!dfs_soc_obj->dfs_psoc_nolinfo) + return; + + nolinfo = &dfs_soc_obj->dfs_psoc_nolinfo[pdev_id]; + /* Fetch the NOL entries for the DFS object. */ + dfs_getnol(dfs, &tmp_nolinfo); + + /* nolinfo might already have some data. Do not overwrite it */ + num_chans = nolinfo->dfs_ch_nchans; + for (i = 0; i < tmp_nolinfo.dfs_ch_nchans; i++) { + tmp_freq = tmp_nolinfo.dfs_nol[i].nol_freq; + + /* Add to nolinfo only if within the pdev's frequency range. */ + if ((low_5ghz_freq < tmp_freq) && (high_5ghz_freq > tmp_freq)) { + /* Figure out the completed duration of each NOL. */ + uint32_t nol_completed_ms = + qdf_system_ticks_to_msecs(qdf_system_ticks() - + tmp_nolinfo.dfs_nol[i].nol_start_ticks); + + nolinfo->dfs_nol[num_chans] = tmp_nolinfo.dfs_nol[i]; + /* Remember the remaining NOL time in the timeout + * variable. + */ + nolinfo->dfs_nol[num_chans++].nol_timeout_ms -= + nol_completed_ms; + } + } + + nolinfo->dfs_ch_nchans = num_chans; +} + +void dfs_reinit_nol_from_psoc_copy(struct wlan_dfs *dfs, uint8_t pdev_id) +{ + struct dfs_soc_priv_obj *dfs_soc_obj = dfs->dfs_soc_obj; + struct dfsreq_nolinfo *nol; + uint8_t i; + + if (!dfs_soc_obj->dfs_psoc_nolinfo) + return; + + if (!dfs_soc_obj->dfs_psoc_nolinfo[pdev_id].dfs_ch_nchans) + return; + + nol = &dfs_soc_obj->dfs_psoc_nolinfo[pdev_id]; + + /* The NOL timeout value in each entry points to the remaining time + * of the NOL. This is to indicate that the NOL entries are paused + * and are not left to continue. + * While adding these NOL, update the start ticks to current time + * to avoid losing entries which might have timed out during + * the pause and resume mechanism. + */ + for (i = 0; i < nol->dfs_ch_nchans; i++) + nol->dfs_nol[i].nol_start_ticks = qdf_system_ticks(); + dfs_set_nol(dfs, nol->dfs_nol, nol->dfs_ch_nchans); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c index 2ef7188e067516297b8b10f960cf95e791bd027b..6c02b7036bc7818d17e76c582bc9ad214966ad92 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,7 +23,6 @@ #include "../dfs.h" #include "../dfs_zero_cac.h" -#include "../dfs_etsi_precac.h" #include "../dfs_process_radar_found_ind.h" #include #include @@ -151,22 +150,24 @@ int dfs_get_nol_subchannel_marking(struct wlan_dfs *dfs, } /** - * dfs_radar_add_channel_list_to_nol()- Add given channels to nol + * dfs_radar_add_channel_list_to_nol_for_freq()- Add given channels to nol * @dfs: Pointer to wlan_dfs structure. - * @channels: Pointer to the channel list. + * @freq_list: Pointer to list of frequency. * @num_channels: Number of channels in the list. * * Add list of channels to nol, only if the channel is dfs. * * Return: QDF_STATUS */ -static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, - uint8_t *channels, - uint8_t num_channels) +#ifdef CONFIG_CHAN_FREQ_API +static QDF_STATUS +dfs_radar_add_channel_list_to_nol_for_freq(struct wlan_dfs *dfs, + uint16_t *freq_list, + uint8_t num_channels) { int i; - uint8_t last_chan = 0; - uint8_t nollist[NUM_CHANNELS_160MHZ]; + uint16_t last_chan_freq = 0; + uint16_t nol_freq_list[NUM_CHANNELS_160MHZ]; uint8_t num_ch = 0; if (num_channels > NUM_CHANNELS_160MHZ) { @@ -176,25 +177,25 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, } for (i = 0; i < num_channels; i++) { - if (channels[i] == 0 || - channels[i] == last_chan) + if (freq_list[i] == 0 || + freq_list[i] == last_chan_freq) continue; - if (!utils_is_dfs_ch(dfs->dfs_pdev_obj, channels[i])) { + if (!utils_is_dfs_chan_for_freq(dfs->dfs_pdev_obj, + freq_list[i])) { dfs_info(dfs, WLAN_DEBUG_DFS, "ch=%d is not dfs, skip", - channels[i]); + freq_list[i]); continue; } - last_chan = channels[i]; + last_chan_freq = freq_list[i]; DFS_NOL_ADD_CHAN_LOCKED(dfs, - (uint16_t)utils_dfs_chan_to_freq(channels[i]), - dfs->wlan_dfs_nol_timeout); - nollist[num_ch++] = last_chan; + freq_list[i], + dfs->wlan_dfs_nol_timeout); + nol_freq_list[num_ch++] = last_chan_freq; utils_dfs_deliver_event(dfs->dfs_pdev_obj, - (uint16_t) - utils_dfs_chan_to_freq(channels[i]), + freq_list[i], WLAN_EV_NOL_STARTED); dfs_info(dfs, WLAN_DEBUG_DFS_NOL, "ch=%d Added to NOL", - last_chan); + last_chan_freq); } if (!num_ch) { @@ -203,21 +204,22 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, return QDF_STATUS_E_FAILURE; } - utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, - nollist, num_ch, DFS_NOL_SET); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + nol_freq_list, num_ch, + DFS_NOL_SET); if (dfs->dfs_is_stadfs_enabled) if (dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj)) - utils_dfs_reg_update_nol_history_ch( - dfs->dfs_pdev_obj, nollist, num_ch, - DFS_NOL_HISTORY_SET); + utils_dfs_reg_update_nol_history_chan_for_freq( + dfs->dfs_pdev_obj, nol_freq_list, + num_ch, DFS_NOL_HISTORY_SET); dfs_nol_update(dfs); utils_dfs_save_nol(dfs->dfs_pdev_obj); return QDF_STATUS_SUCCESS; } - +#endif /** * dfs_radar_chan_for_80()- Find frequency offsets for 80MHz * @freq_offset: freq offset @@ -323,6 +325,56 @@ static void dfs_radar_chan_for_20(struct freqs_offsets *freq_offset, * @radar_found: Pointer to radar_found_info. * @freq_center: Pointer to retrieve the value of radar found cfreq. */ +#ifdef CONFIG_CHAN_FREQ_API +static void +dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint32_t *freq_center) +{ + struct dfs_channel *curchan = dfs->dfs_curchan; + + /* Radar found on agile detector ID. + * Applicable to chips that have a separate agile radar detector + * engine. + */ + if (radar_found->detector_id == AGILE_DETECTOR_ID) { + *freq_center = dfs->dfs_agile_precac_freq_mhz; + } else if (!radar_found->segment_id) { + *freq_center = curchan->dfs_ch_mhz_freq_seg1; + } else { + /* Radar found on secondary segment by the HW when + * preCAC was running. It (dfs_precac_enable) is specific to + * legacy chips. + */ + if (dfs_is_precac_timer_running(dfs) && + dfs_is_legacy_precac_enabled(dfs)) { + *freq_center = dfs->dfs_precac_secondary_freq_mhz; + } else { + /* Radar found on secondary segment by the HW, when preCAC + * was not running in legacy chips or preCAC was running + * in Lithium chips. + */ + *freq_center = curchan->dfs_ch_mhz_freq_seg2; + if (WLAN_IS_CHAN_MODE_160(curchan)) { + /* If center frequency of entire 160 band + * is less than center frequency of primary + * segment, then the center frequency of + * secondary segment is -40 of center + * frequency of entire 160 segment. + */ + if (curchan->dfs_ch_mhz_freq_seg2 < + curchan->dfs_ch_mhz_freq_seg1) + *freq_center -= + DFS_160MHZ_SECOND_SEG_OFFSET; + else + *freq_center += + DFS_160MHZ_SECOND_SEG_OFFSET; + } + } + } +} +#else +#ifdef CONFIG_CHAN_NUM_API static void dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, struct radar_found_info @@ -330,47 +382,76 @@ dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, uint32_t *freq_center) { struct dfs_channel *curchan = dfs->dfs_curchan; - uint64_t flag; - - flag = curchan->dfs_ch_flags; - if (!radar_found->segment_id) { + /* Radar found on agile detector ID. + * Applicable to chips that have a separate agile radar detector + * engine. + */ + if (radar_found->detector_id == AGILE_DETECTOR_ID) { + *freq_center = utils_dfs_chan_to_freq( + dfs->dfs_agile_precac_freq); + /* Radar found on primary segment by the HW. */ + } else if (radar_found->segment_id == PRIMARY_SEG) { *freq_center = utils_dfs_chan_to_freq( curchan->dfs_ch_vhtop_ch_freq_seg1); } else { - if (dfs_is_precac_timer_running(dfs)) { + /* Radar found on secondary segment by the HW when + * preCAC was running. It (dfs_precac_enable) is specific to + * legacy chips. + */ + if (dfs_is_precac_timer_running(dfs) && + dfs_is_legacy_precac_enabled(dfs)) { *freq_center = utils_dfs_chan_to_freq( dfs->dfs_precac_secondary_freq); } else { - *freq_center = utils_dfs_chan_to_freq( - curchan->dfs_ch_vhtop_ch_freq_seg2); - if ((flag & WLAN_CHAN_VHT160) || - (flag & WLAN_CHAN_HE160)) - *freq_center += DFS_160MHZ_SECOND_SEG_OFFSET; + /* Radar found on secondary segment by the HW, when preCAC + * was not running in legacy chips or preCAC was running + * in Lithium chips. + */ + *freq_center = utils_dfs_chan_to_freq( + curchan->dfs_ch_vhtop_ch_freq_seg2); + if (WLAN_IS_CHAN_MODE_160(curchan)) { + /* If center frequency of entire 160 band + * is less than center frequency of primary + * segment, then the center frequency of + * secondary segment is -40 of center + * frequency of entire 160 segment. + */ + if (curchan->dfs_ch_vhtop_ch_freq_seg2 < + curchan->dfs_ch_vhtop_ch_freq_seg1) + *freq_center -= + DFS_160MHZ_SECOND_SEG_OFFSET; + else + *freq_center += + DFS_160MHZ_SECOND_SEG_OFFSET; + } } } } +#endif +#endif /** - * dfs_find_radar_affected_subchans() - Finds radar affected sub channels. + * dfs_find_radar_affected_subchans_for_freq() - Find radar affected sub chans. * @dfs: Pointer to wlan_dfs structure. * @radar_found: Pointer to radar_found structure. - * @channels: Pointer to save radar affected channels. + * @freq_list: Pointer to save radar affected channels. * @freq_center: Freq_center of the radar affected chan. * * Return: Number of channels. */ -static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, - struct radar_found_info - *radar_found, - uint8_t *channels, - uint32_t freq_center) +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_find_radar_affected_subchans_for_freq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint16_t *freq_list, + uint32_t freq_center) { int i, j; uint8_t num_radar_subchans; uint32_t flag; int32_t sidx; - uint8_t candidate_subchan; - uint8_t cur_subchans[NUM_CHANNELS_160MHZ]; + uint16_t candidate_subchan_freq; + uint16_t cur_subchans[NUM_CHANNELS_160MHZ]; uint8_t n_cur_subchans; struct dfs_channel *curchan = dfs->dfs_curchan; struct freqs_offsets freq_offset; @@ -384,8 +465,8 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, sidx = DFS_FREQ_OFFSET_TO_SIDX(radar_found->freq_offset); dfs_info(dfs, WLAN_DEBUG_DFS, - "seg=%d, sidx=%d, offset=%d, chirp=%d, flag=%d, f=%d", - radar_found->segment_id, sidx, + "seg=%d, det=%d, sidx=%d, offset=%d, chirp=%d, flag=%d, f=%d", + radar_found->segment_id, radar_found->detector_id, sidx, radar_found->freq_offset, radar_found->is_chirp, flag, freq_center); @@ -417,27 +498,31 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, return 0; } - n_cur_subchans = dfs_get_bonding_channels(dfs, curchan, - radar_found->segment_id, - cur_subchans); + n_cur_subchans = + dfs_get_bonding_channels_for_freq(dfs, curchan, + radar_found->segment_id, + radar_found->detector_id, + cur_subchans); for (i = 0, num_radar_subchans = 0; i < DFS_NUM_FREQ_OFFSET; i++) { - candidate_subchan = utils_dfs_freq_to_chan(freq_offset.freq[i]); + candidate_subchan_freq = freq_offset.freq[i]; for (j = 0; j < n_cur_subchans; j++) { - if (cur_subchans[j] == candidate_subchan) { - channels[num_radar_subchans++] = - candidate_subchan; + if (cur_subchans[j] == candidate_subchan_freq) { + freq_list[num_radar_subchans++] = + candidate_subchan_freq; dfs_info(dfs, WLAN_DEBUG_DFS, "offset=%d, channel=%d", num_radar_subchans, - channels[num_radar_subchans - 1]); + freq_list[num_radar_subchans - 1]); break; } } } return num_radar_subchans; } +#endif +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, uint8_t *channels) { @@ -485,23 +570,166 @@ uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, return nchannels; } +#endif + +/* + * dfs_get_bonding_channel_without_seg_info_for_freq() - Get bonding frequency + * list. + * @chan: Pointer to dfs_channel. + * @freq_list: Pointer to frequency list. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t +dfs_get_bonding_channel_without_seg_info_for_freq(struct dfs_channel *chan, + uint16_t *freq_list) +{ + uint16_t center_freq; + uint8_t nchannels = 0; + + center_freq = chan->dfs_ch_mhz_freq_seg1; + + if (WLAN_IS_CHAN_MODE_20(chan)) { + nchannels = 1; + freq_list[0] = center_freq; + } else if (WLAN_IS_CHAN_MODE_40(chan)) { + nchannels = 2; + freq_list[0] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_80(chan)) { + nchannels = 4; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_80_80(chan)) { + nchannels = 8; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + center_freq = chan->dfs_ch_mhz_freq_seg2; + freq_list[4] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_160(chan)) { + nchannels = 8; + center_freq = chan->dfs_ch_mhz_freq_seg2; + freq_list[0] = center_freq - DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[4] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + } + + return nchannels; +} +#endif + +/* + * dfs_get_bonding_channels_for_freq() - Get bonding channel frequency. + * @dfs: Pointer to wlan_dfs. + * @curchan: Pointer to dfs_channel. + * @segment_id: Segment ID. + * @detector_id: Detector ID. + * @freq_list: Pointer to frequency list. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t dfs_get_bonding_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t detector_id, + uint16_t *freq_list) +{ + uint16_t center_freq; + uint8_t nchannels = 0; + if (detector_id == AGILE_DETECTOR_ID) + center_freq = dfs->dfs_agile_precac_freq_mhz; + else if (!segment_id) + center_freq = curchan->dfs_ch_mhz_freq_seg1; + else { + /* When precac is running "dfs_ch_vhtop_ch_freq_seg2" is + * zero and "dfs_precac_secondary_freq" holds the secondary + * frequency. + */ + if (dfs_is_precac_timer_running(dfs)) + center_freq = dfs->dfs_precac_secondary_freq_mhz; + else + center_freq = curchan->dfs_ch_mhz_freq_seg2; + } + + if (WLAN_IS_CHAN_MODE_20(curchan)) { + nchannels = 1; + freq_list[0] = center_freq; + } else if (WLAN_IS_CHAN_MODE_40(curchan)) { + nchannels = 2; + freq_list[0] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_80(curchan) || + WLAN_IS_CHAN_MODE_80_80(curchan) || + detector_id == AGILE_DETECTOR_ID) { + /* If the current channel's bandwidth is 80/80+80/160Mhz, + * the corresponding agile Detector's bandwidth will be 80Mhz. + * Therefore, if radar is found on the agile detector find + * subchannels for 80Mhz bandwidth. + */ + nchannels = 4; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_160(curchan)) { + nchannels = 8; + center_freq = curchan->dfs_ch_mhz_freq_seg2; + freq_list[0] = center_freq - DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[4] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + } + + return nchannels; +} +#endif + +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, struct dfs_channel *curchan, uint32_t segment_id, + uint8_t detector_id, uint8_t *channels) { uint8_t center_chan; uint8_t nchannels = 0; - if (!segment_id) + if (detector_id == AGILE_DETECTOR_ID) + center_chan = dfs->dfs_agile_precac_freq; + else if (!segment_id) center_chan = curchan->dfs_ch_vhtop_ch_freq_seg1; else { /* When precac is running "dfs_ch_vhtop_ch_freq_seg2" is * zero and "dfs_precac_secondary_freq" holds the secondary - * frequency. + * frequency in case of legacy chips. + * For chips that support a separate agile detector engine, + * "dfs_agile_precac_freq" holds the frequency that agile + * engine operates on. + * + * In case of radar detected by the HW in the secondary 80 + * channel,"dfs_ch_vhtop_ch_freq_seg2" holds the secondary + * segment center frequency in the below cases: + * 1. preCAC timer is running in chips that support separate + * agile engines. + * 2. preCAC timer is not running. */ - if (dfs_is_precac_timer_running(dfs)) + if (dfs_is_precac_timer_running(dfs) && + dfs_is_legacy_precac_enabled(dfs)) center_chan = dfs->dfs_precac_secondary_freq; else center_chan = curchan->dfs_ch_vhtop_ch_freq_seg2; @@ -515,7 +743,13 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, channels[0] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET; channels[1] = center_chan + DFS_5GHZ_NEXT_CHAN_OFFSET; } else if (WLAN_IS_CHAN_MODE_80(curchan) || - WLAN_IS_CHAN_MODE_80_80(curchan)) { + WLAN_IS_CHAN_MODE_80_80(curchan) || + detector_id == AGILE_DETECTOR_ID) { + /* If the current channel's bandwidth is 80/80+80/160Mhz, + * the corresponding agile Detector's bandwidth will be 80Mhz. + * Therefore, if radar is found on the agile detector find + * subchannels for 80Mhz bandwidth. + */ nchannels = 4; channels[0] = center_chan - DFS_5GHZ_2ND_CHAN_OFFSET; channels[1] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET; @@ -536,6 +770,7 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, return nchannels; } +#endif static inline void dfs_reset_bangradar(struct wlan_dfs *dfs) { @@ -586,33 +821,31 @@ int dfs_second_segment_radar_disable(struct wlan_dfs *dfs) /* dfs_prepare_nol_ie_bitmap: Create a Bitmap from the radar found subchannels * to be sent along with RCSA. - * - * Get the subchannels affected by radar and all the channels in current - * channel. - * start from the first bit pointing to first subchannel in the current - * channel, set as 1 if radar affected, 0 if unaffected. - * If the number of subchannels increases (future cases), the bitmap should - * be an array of required size. - * - * Please change macro "MIN_DFS_SUBCHAN_BW" when NOL logic changes. + * @dfs: Pointer to wlan_dfs. + * @radar_found: Pointer to radar_found_info. + * @in_sub_channels: Pointer to Sub-channels. + * @n_in_sub_channels: Number of sub-channels. */ -static void dfs_prepare_nol_ie_bitmap(struct wlan_dfs *dfs, - struct radar_found_info *radar_found, - uint8_t *in_sub_channels, - uint8_t n_in_sub_channels) +#ifdef CONFIG_CHAN_FREQ_API +static void +dfs_prepare_nol_ie_bitmap_for_freq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint16_t *in_sub_channels, + uint8_t n_in_sub_channels) { - uint8_t cur_subchans[NUM_CHANNELS_160MHZ]; + uint16_t cur_subchans[NUM_CHANNELS_160MHZ]; uint8_t n_cur_subchans; uint8_t i; uint8_t j; uint8_t bits = 0x01; - n_cur_subchans = dfs_get_bonding_channels(dfs, dfs->dfs_curchan, - radar_found->segment_id, - cur_subchans); + n_cur_subchans = + dfs_get_bonding_channels_for_freq(dfs, dfs->dfs_curchan, + radar_found->segment_id, + radar_found->detector_id, + cur_subchans); dfs->dfs_nol_ie_bandwidth = MIN_DFS_SUBCHAN_BW; - dfs->dfs_nol_ie_startfreq = - (uint16_t)utils_dfs_chan_to_freq(cur_subchans[0]); + dfs->dfs_nol_ie_startfreq = cur_subchans[0]; /* Search through the array list of radar affected subchannels * to find if the subchannel in our current channel has radar hit. @@ -628,6 +861,7 @@ static void dfs_prepare_nol_ie_bitmap(struct wlan_dfs *dfs, bits <<= 1; } } +#endif void dfs_fetch_nol_ie_info(struct wlan_dfs *dfs, uint8_t *nol_ie_bandwidth, @@ -663,12 +897,13 @@ static void dfs_reset_nol_ie_bitmap(struct wlan_dfs *dfs) dfs->dfs_nol_ie_bitmap = 0; } +#ifdef CONFIG_CHAN_FREQ_API bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, uint16_t nol_ie_startfreq, uint8_t nol_ie_bitmap) { uint8_t num_subchans; uint8_t bits = 0x01; - uint8_t radar_subchans[NUM_CHANNELS_160MHZ]; + uint16_t radar_subchans[NUM_CHANNELS_160MHZ]; bool should_nol_ie_be_sent = true; qdf_mem_zero(radar_subchans, sizeof(radar_subchans)); @@ -678,10 +913,11 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, * can't be sent to uplink. */ num_subchans = - dfs_get_bonding_channels(dfs, - dfs->dfs_curchan, - dfs->dfs_curchan->dfs_ch_freq, - radar_subchans); + dfs_get_bonding_channels_for_freq(dfs, + dfs->dfs_curchan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + radar_subchans); should_nol_ie_be_sent = false; } else { /* Add the NOL IE information in DFS structure so that RCSA @@ -695,38 +931,91 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, for (num_subchans = 0; num_subchans < NUM_CHANNELS_160MHZ; num_subchans++) { if (nol_ie_bitmap & bits) { - radar_subchans[num_subchans] = - utils_dfs_freq_to_chan(frequency); + radar_subchans[num_subchans] = frequency; } bits <<= 1; frequency += nol_ie_bandwidth; } } - dfs_radar_add_channel_list_to_nol(dfs, radar_subchans, num_subchans); + dfs_radar_add_channel_list_to_nol_for_freq(dfs, radar_subchans, + num_subchans); return should_nol_ie_be_sent; } +#endif +#ifdef CONFIG_CHAN_FREQ_API QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, struct radar_found_info *radar_found) { bool wait_for_csa = false; - uint8_t channels[NUM_CHANNELS_160MHZ]; + uint16_t freq_list[NUM_CHANNELS_160MHZ]; uint8_t num_channels; - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t freq_center; uint32_t radarfound_freq; + struct dfs_channel *dfs_curchan; + + /* Acquire a lock to avoid initiating mode switch till radar + * processing is completed. + */ + DFS_RADAR_MODE_SWITCH_LOCK(dfs); - if (!dfs->dfs_curchan) { + /* Before processing radar, check if HW mode switch is in progress. + * If in progress, defer the processing of radar event received till + * the mode switch is completed. + */ + if (dfs_is_hw_mode_switch_in_progress(dfs)) { + struct radar_found_info *radar_params = NULL; + + radar_params = qdf_mem_malloc(sizeof(*radar_params)); + if (!radar_params) + goto exit; + + /* If CAC timer is running, cancel it here rather than + * after processing to avoid handling unnecessary CAC timeouts. + */ + if (dfs->dfs_cac_timer_running) + dfs_cac_stop(dfs); + + /* If CAC timer is to be handled after mode switch and then + * we receive radar, no point in handling CAC completion. + */ + if (dfs->dfs_defer_params.is_cac_completed) + dfs->dfs_defer_params.is_cac_completed = false; + qdf_mem_copy(radar_params, radar_found, sizeof(*radar_params)); + dfs->dfs_defer_params.radar_params = radar_params; + dfs->dfs_defer_params.is_radar_detected = true; + status = QDF_STATUS_SUCCESS; + goto exit; + } + + dfs_curchan = dfs->dfs_curchan; + + if (!dfs_curchan) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs->dfs_curchan is NULL"); - return QDF_STATUS_E_FAILURE; + goto exit; } - /* Check if the current channel is a non DFS channel */ - if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan)) { + /* Check if the current channel is a non DFS channel + * If the current channel is non-DFS and the radar is from Agile + * Detector we need to process it since Agile Detector has a + * different channel. + */ + if (!dfs_radarevent_basic_sanity(dfs, dfs_curchan) && + !(radar_found->detector_id == AGILE_DETECTOR_ID)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event on a non-DFS channel"); - return QDF_STATUS_E_FAILURE; + goto exit; + } + + /* Sanity checks for radar on Agile detector */ + if (radar_found->detector_id == AGILE_DETECTOR_ID && + (!dfs_is_agile_precac_enabled(dfs) || !dfs->dfs_agile_precac_freq_mhz)) + { + dfs_err(dfs, WLAN_DEBUG_DFS, + "radar on Agile detector when ADFS is not running"); + goto exit; } /* For Full Offload, FW sends segment id,freq_offset and chirp @@ -743,7 +1032,11 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_compute_radar_found_cfreq(dfs, radar_found, &freq_center); radarfound_freq = freq_center + radar_found->freq_offset; - if (radar_found->segment_id == SEG_ID_SECONDARY) + if (radar_found->detector_id == AGILE_DETECTOR_ID) + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Radar found on Agile detector freq=%d radar freq=%d", + freq_center, radarfound_freq); + else if (radar_found->segment_id == SEG_ID_SECONDARY) dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Radar found on second segment.Radarfound Freq=%d MHz.Secondary Chan cfreq=%d MHz.", radarfound_freq, freq_center); @@ -751,63 +1044,58 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "Radar found on channel=%d, freq=%d MHz. Primary beaconning chan:%d, freq=%d MHz.", utils_dfs_freq_to_chan(radarfound_freq), - radarfound_freq, dfs->dfs_curchan->dfs_ch_ieee, - dfs->dfs_curchan->dfs_ch_freq); + radarfound_freq, dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); - utils_dfs_deliver_event(dfs->dfs_pdev_obj, - radarfound_freq, + utils_dfs_deliver_event(dfs->dfs_pdev_obj, radarfound_freq, WLAN_EV_RADAR_DETECTED); if (!dfs->dfs_use_nol) { dfs_reset_bangradar(dfs); dfs_send_csa_to_current_chan(dfs); - return QDF_STATUS_SUCCESS; + status = QDF_STATUS_SUCCESS; + goto exit; } if (dfs->dfs_bangradar_type == DFS_BANGRADAR_FOR_ALL_SUBCHANS) - num_channels = dfs_get_bonding_channels_without_seg_info( - dfs->dfs_curchan, channels); + num_channels = + dfs_get_bonding_channel_without_seg_info_for_freq + (dfs_curchan, freq_list); /* BW reduction is dependent on subchannel marking */ else if ((dfs->dfs_use_nol_subchannel_marking) && (!(dfs->dfs_bangradar_type) || - (dfs->dfs_bangradar_type == - DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS))) - num_channels = dfs_find_radar_affected_subchans(dfs, - radar_found, - channels, - freq_center); + (dfs->dfs_bangradar_type == + DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS))) + num_channels = + dfs_find_radar_affected_subchans_for_freq(dfs, + radar_found, + freq_list, + freq_center); else - num_channels = dfs_get_bonding_channels(dfs, - dfs->dfs_curchan, - radar_found->segment_id, - channels); + num_channels = dfs_get_bonding_channels_for_freq + (dfs, dfs_curchan, radar_found->segment_id, + radar_found->detector_id, freq_list); dfs_reset_bangradar(dfs); - if (dfs->dfs_agile_precac_enable && radar_found->detector_id == - AGILE_DETECTOR_ID) { - dfs_debug(dfs, WLAN_DEBUG_DFS, - "%s: %d Radar found on agile detector:%d , STAY in Same operating Channel", - __func__, __LINE__, radar_found->detector_id); - dfs_mark_precac_dfs(dfs, dfs->is_radar_found_on_secondary_seg, - radar_found->detector_id); - return QDF_STATUS_SUCCESS; - } - - status = dfs_radar_add_channel_list_to_nol(dfs, channels, num_channels); + status = dfs_radar_add_channel_list_to_nol_for_freq(dfs, + freq_list, + num_channels); if (QDF_IS_STATUS_ERROR(status)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event received on invalid channel"); - return status; + goto exit; } + dfs->dfs_is_nol_ie_sent = false; - (dfs->is_radar_during_precac) ? + (dfs->is_radar_during_precac || + radar_found->detector_id == AGILE_DETECTOR_ID) ? (dfs->dfs_is_rcsa_ie_sent = false) : (dfs->dfs_is_rcsa_ie_sent = true); if (dfs->dfs_use_nol_subchannel_marking) { dfs_reset_nol_ie_bitmap(dfs); - dfs_prepare_nol_ie_bitmap(dfs, radar_found, channels, - num_channels); + dfs_prepare_nol_ie_bitmap_for_freq(dfs, radar_found, freq_list, + num_channels); dfs->dfs_is_nol_ie_sent = true; } @@ -822,27 +1110,20 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs->is_radar_found_on_secondary_seg, dfs_is_precac_timer_running(dfs)); /* - * Even if radar found on primary, we need to move the channel - * from precac-required-list and precac-done-list to - * precac-nol-list. + * Even if radar found on primary, we need to mark the channel as NOL + * in preCAC list. The preCAC list also maintains the current CAC + * channels as part of pre-cleared DFS. Hence call the API + * to mark channels as NOL irrespective of preCAC being enabled or not. */ - if (dfs->dfs_precac_enable || dfs->dfs_agile_precac_enable) { - dfs_debug(dfs, WLAN_DEBUG_DFS, - "%s: %d Radar found on dfs detector:%d", - __func__, __LINE__, radar_found->detector_id); - dfs_mark_precac_dfs(dfs, - dfs->is_radar_found_on_secondary_seg, - radar_found->detector_id); - } - - if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN) { - /* Remove chan from ETSI Pre-CAC Cleared List*/ - dfs_info(dfs, WLAN_DEBUG_DFS_NOL, - "%s : %d remove channel from ETSI PreCAC List\n", - __func__, __LINE__); - dfs_mark_etsi_precac_dfs(dfs, channels, num_channels); - } + dfs_debug(dfs, WLAN_DEBUG_DFS, + "%s: %d Radar found on dfs detector:%d", + __func__, __LINE__, radar_found->detector_id); + dfs_mark_precac_nol_for_freq(dfs, + dfs->is_radar_found_on_secondary_seg, + radar_found->detector_id, + freq_list, + num_channels); /* * This calls into the umac DFS code, which sets the umac * related radar flags and begins the channel change @@ -855,6 +1136,11 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_mlme_start_rcsa(dfs->dfs_pdev_obj, &wait_for_csa); + /* If radar is found on preCAC or Agile CAC, return here since + * channel change is not required. + */ + if (radar_found->detector_id == AGILE_DETECTOR_ID) + goto exit; if (!dfs->dfs_is_offload_enabled && dfs->is_radar_found_on_secondary_seg) { dfs_second_segment_radar_disable(dfs); @@ -862,7 +1148,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, if (dfs->is_radar_during_precac) { dfs->is_radar_during_precac = 0; - return QDF_STATUS_SUCCESS; + goto exit; } } @@ -873,7 +1159,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, * needs to be fixed. See EV 105776. */ if (wait_for_csa) - return QDF_STATUS_SUCCESS; + goto exit; /* * EV 129487 : We have detected radar in the channel, @@ -887,11 +1173,14 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_second_segment_radar_disable(dfs); } - dfs_mlme_mark_dfs(dfs->dfs_pdev_obj, - dfs->dfs_curchan->dfs_ch_ieee, - dfs->dfs_curchan->dfs_ch_freq, - dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2, - dfs->dfs_curchan->dfs_ch_flags); + dfs_mlme_mark_dfs_for_freq(dfs->dfs_pdev_obj, + dfs->dfs_curchan->dfs_ch_ieee, + dfs->dfs_curchan->dfs_ch_freq, + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs->dfs_curchan->dfs_ch_flags); - return QDF_STATUS_SUCCESS; +exit: + DFS_RADAR_MODE_SWITCH_UNLOCK(dfs); + return status; } +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c index 1ac50a0e5f2569830512bb86edacb219f164a421..774006c2002e7a4e05934f2906d412fb0da876bd 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c @@ -20,6 +20,7 @@ #include "../dfs_random_chan_sel.h" #include #include +#include "../dfs_process_radar_found_ind.h" #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION /* @@ -35,681 +36,681 @@ /* channel tx leakage table - ht80 */ struct dfs_matrix_tx_leak_info ht80_chan[] = { - {52, - {{36, 148}, {40, 199}, - {44, 193}, {48, 197}, - {52, DFS_TX_LEAKAGE_MIN}, {56, 153}, - {60, 137}, {64, 134}, - {100, 358}, {104, 350}, - {108, 404}, {112, 344}, - {116, 424}, {120, 429}, - {124, 437}, {128, 435}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180, 148}, {40, 5200, 199}, + {44, 5520, 193}, {48, 5240, 197}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153}, + {60, 5300, 137}, {64, 5320, 134}, + {100, 5500, 358}, {104, 5520, 350}, + {108, 5540, 404}, {112, 5560, 344}, + {116, 5580, 424}, {120, 5600, 429}, + {124, 5620, 437}, {128, 5640, 435}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, 171}, {40, 178}, - {44, 171}, {48, 178}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, 280}, - {100, 351}, {104, 376}, - {108, 362}, {112, 362}, - {116, 403}, {120, 397}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, 171}, {40, 5200, 178}, + {44, 5220, 171}, {48, 5240, 178}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280}, + {100, 5500, 351}, {104, 5520, 376}, + {108, 5540, 362}, {112, 5560, 362}, + {116, 5580, 403}, {120, 5600, 397}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, 156}, {40, 146}, - {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 180}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 376}, {104, 360}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, 395}, {120, 399}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60,5300, + {{36, 5180, 156}, {40, 5200, 146}, + {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 376}, {104, 5520, 360}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, 395}, {120, 5600, 399}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, 217}, {40, 221}, - {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 176}, {56, 176}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 384}, {104, 390}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, 375}, {120, 374}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320, + {{36, 5180, 217}, {40, 5200, 221}, + {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 176}, {56, 5280, 176}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 384}, {104, 5520, 390}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, 375}, {120, 5600, 374}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 357}, {40, 326}, - {44, 321}, {48, 326}, - {52, 378}, {56, 396}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, 196}, {112, 116}, - {116, 166}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {100, 5500, + {{36, 5180, 357}, {40, 5200, 326}, + {44, 5220, 321}, {48, 5240, 326}, + {52, 5260, 378}, {56, 5280, 396}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, 196}, {112, 5560, 116}, + {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {104, - {{36, 325}, {40, 325}, - {44, 305}, {48, 352}, - {52, 411}, {56, 411}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, 460}, - {116, 198}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {104, 5520, + {{36, 5180, 325}, {40, 5200, 325}, + {44, 5220, 305}, {48, 5240, 352}, + {52, 5260, 411}, {56, 5280, 411}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460}, + {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {108, - {{36, 304}, {40, 332}, - {44, 310}, {48, 335}, - {52, 431}, {56, 391}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 280}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 185}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {108, 5540, + {{36,5180, 304}, {40, 5200, 332}, + {44, 5220, 310}, {48, 5240, 335}, + {52, 5260, 431}, {56, 5280, 391}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {112, - {{36, 327}, {40, 335}, - {44, 331}, {48, 345}, - {52, 367}, {56, 401}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 131}, {104, 132}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 189}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {112,5560, + {{36, 5180, 327}, {40, 5200, 335}, + {44, 5220, 331}, {48, 5240, 345}, + {52, 5260, 367}, {56, 5280, 401}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 131}, {104, 5520, 132}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {116, - {{36, 384}, {40, 372}, - {44, 389}, {48, 396}, - {52, 348}, {56, 336}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 172}, {104, 169}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {116, 5580, + {{36, 5180, 384}, {40, 5200, 372}, + {44, 5220, 389}, {48, 5240, 396}, + {52, 5260, 348}, {56, 5280, 336}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 172}, {104, 5520, 169}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {120, - {{36, 395}, {40, 419}, - {44, 439}, {48, 407}, - {52, 321}, {56, 334}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 134}, {104, 186}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 159}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {120, 5600, + {{36, 5180, 395}, {40, 5200, 419}, + {44, 5220, 439}, {48, 5240, 407}, + {52, 5260, 321}, {56, 5280, 334}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 134}, {104, 5520, 186}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {124, - {{36, 469}, {40, 433}, - {44, 434}, {48, 435}, - {52, 332}, {56, 345}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 146}, {104, 177}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 350}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 138}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 469}, {40, 5200, 433}, + {44, 5220, 434}, {48, 5240, 435}, + {52, 5260, 332}, {56, 5280, 345}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 146}, {104, 5520, 177}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 408}, {40, 434}, - {44, 449}, {48, 444}, - {52, 341}, {56, 374}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 205}, {104, 208}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 142}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 408}, {40, 5200, 434}, + {44, 5220, 449}, {48, 5240, 444}, + {52, 5260, 341}, {56, 5280, 374}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 205}, {104, 5520, 208}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136, 5680, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140, 5700, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144, 5720, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; /* channel tx leakage table - ht40 */ struct dfs_matrix_tx_leak_info ht40_chan[] = { - {52, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, 230}, {48, 230}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_AUTO_MIN}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, - {100, 625}, {104, 323}, - {108, 646}, {112, 646}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, 230}, {48, 5240, 230}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, + {100, 5500, 625}, {104, 5520, 323}, + {108, 5540, 646}, {112, 5560, 646}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 611}, {104, 611}, - {108, 617}, {112, 617}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 611}, {104, 5520, 611}, + {108, 5540, 617}, {112, 5560, 617}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 190}, {56, 190}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 608}, {104, 608}, - {108, 623}, {112, 623}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60, 5300, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 190}, {56, 5280, 190}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 608}, {104, 5520, 608}, + {108, 5540, 623}, {112, 5560, 623}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 295}, {56, 295}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 594}, {104, 594}, - {108, 625}, {112, 625}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 295}, {56, 5280, 295}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 594}, {104, 5520, 594}, + {108, 5540, 625}, {112, 5560, 625}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 618}, {40, 618}, - {44, 604}, {48, 604}, - {52, 596}, {56, 596}, - {60, 584}, {64, 584}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, 299}, {112, 299}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 538}, {136, 538}, - {140, 598}, - {144, DFS_TX_LEAKAGE_MIN} + {100, 5500, + {{36, 5180, 618}, {40, 5200, 618}, + {44, 5220, 604}, {48, 5240, 604}, + {52, 5260, 596}, {56, 5280, 596}, + {60, 5300, 584}, {64, 5320, 584}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, 299}, {112, 5560, 299}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 538}, {136,5680, 538}, + {140, 5700, 598}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {104, - {{36, 636}, {40, 636}, - {44, 601}, {48, 601}, - {52, 616}, {56, 616}, - {60, 584}, {64, 584}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 553}, {136, 553}, - {140, 568}, - {144, DFS_TX_LEAKAGE_MIN} + {104, 5520, + {{36, 5180, 636}, {40, 5200, 636}, + {44, 5220, 601}, {48, 5240, 601}, + {52, 5260, 616}, {56, 5280, 616}, + {60, 5300, 584}, {64, 5320, 584}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 553}, {136, 5680, 553}, + {140, 5700, 568}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {108, - {{36, 600}, {40, 600}, - {44, 627}, {48, 627}, - {52, 611}, {56, 611}, - {60, 611}, {64, 611}, - {100, 214}, {104, 214}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, 534}, - {144, DFS_TX_LEAKAGE_MIN} + {108, 5540, + {{36, 5180, 600}, {40, 5200, 600}, + {44, 5220, 627}, {48, 5240, 627}, + {52, 5260, 611}, {56, 5280, 611}, + {60, 5300, 611}, {64, 5320, 611}, + {100, 5500, 214}, {104, 5520, 214}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, 534}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {112, - {{36, 645}, {40, 645}, - {44, 641}, {48, 641}, - {52, 618}, {56, 618}, - {60, 612}, {64, 612}, - {100, 293}, {104, 293}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, 521}, - {144, DFS_TX_LEAKAGE_MIN} + {112, 5560, + {{36, 5180, 645}, {40, 5200, 645}, + {44, 5220, 641}, {48, 5240, 641}, + {52, 5260, 618}, {56, 5280, 618}, + {60, 5300, 612}, {64, 5320, 612}, + {100, 5500, 293}, {104, 5520, 293}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, 521}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {116, - {{36, 661}, {40, 661}, - {44, 624}, {48, 624}, - {52, 634}, {56, 634}, - {60, 611}, {64, 611}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, 217}, {112, 217}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {116, 5580, + {{36, 5180, 661}, {40, 5200, 661}, + {44, 5220, 624}, {48, 5240, 624}, + {52, 5260, 634}, {56, 5280, 634}, + {60, 5300, 611}, {64, 5320, 611}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, 217}, {112, 5560, 217}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {120, - {{36, 667}, {40, 667}, - {44, 645}, {48, 645}, - {52, 633}, {56, 633}, - {60, 619}, {64, 619}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, 291}, {112, 291}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {120, 5600, + {{36, 5180, 667}, {40, 5200, 667}, + {44, 5220, 645}, {48, 5240, 645}, + {52, 5260, 633}, {56, 5280, 633}, + {60, 5300, 619}, {64, 5320, 619}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, 291}, {112, 5560, 291}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {124, - {{36, 676}, {40, 676}, - {44, 668}, {48, 668}, - {52, 595}, {56, 595}, - {60, 622}, {64, 622}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, 225}, {120, 225}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 676}, {40, 5200, 676}, + {44, 5220, 668}, {48, 5240, 668}, + {52, 5260, 595}, {56, 5280, 595}, + {60, 5300, 622}, {64, 5320, 622}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, 225}, {120, 5600, 225}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 678}, {40, 678}, - {44, 664}, {48, 664}, - {52, 651}, {56, 651}, - {60, 643}, {64, 643}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, 293}, {120, 293}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 678}, {40, 5200, 678}, + {44, 5220, 664}, {48, 5240, 664}, + {52, 5260, 651}, {56, 5280, 651}, + {60, 5300, 643}, {64, 5320, 643}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, 293}, {120, 5600, 293}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, 689}, {40, 689}, - {44, 669}, {48, 669}, - {52, 662}, {56, 662}, - {60, 609}, {64, 609}, - {100, 538}, {104, 538}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, 247}, {128, 247}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, 689}, {40, 5200, 689}, + {44, 5220, 669}, {48, 5240, 669}, + {52, 5260, 662}, {56, 5280, 662}, + {60, 5300, 609}, {64, 5320, 609}, + {100, 5500, 538}, {104, 5520, 538}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, 247}, {128, 5640, 247}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, 703}, {40, 703}, - {44, 688}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 671}, {56, 671}, - {60, 658}, {64, 658}, - {100, 504}, {104, 504}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, 289}, {128, 289}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136, 5680, + {{36, 5180, 703}, {40, 5200, 703}, + {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 671}, {56, 5280, 671}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 504}, {104, 5520, 504}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, 289}, {128, 5640, 289}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, 695}, {40, 695}, - {44, 684}, {48, 684}, - {52, 664}, {56, 664}, - {60, 658}, {64, 658}, - {100, 601}, {104, 601}, - {108, 545}, {112, 545}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 262}, {136, 262}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140, 5700, + {{36, 5180, 695}, {40, 5200, 695}, + {44, 5220, 684}, {48, 5240, 684}, + {52, 5260, 664}, {56, 5280, 664}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 601}, {104, 5520, 601}, + {108, 5540, 545}, {112, 5560, 545}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 262}, {136, 5680, 262}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, 695}, {40, 695}, - {44, 684}, {48, 684}, - {52, 664}, {56, 664}, - {60, 658}, {64, 658}, - {100, 601}, {104, 601}, - {108, 545}, {112, 545}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 262}, {136, 262}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144, 5720, + {{36, 5180, 695}, {40, 5200, 695}, + {44, 5220, 684}, {48, 5240, 684}, + {52, 5260, 664}, {56, 5280, 664}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 601}, {104, 5520, 601}, + {108, 5540, 545}, {112, 5560, 545}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 262}, {136, 5680, 262}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; /* channel tx leakage table - ht20 */ struct dfs_matrix_tx_leak_info ht20_chan[] = { - {52, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 286}, - {44, 225}, {48, 121}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, 300}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, - {100, 637}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286}, + {44, 5220, 225}, {48,5240, 121}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, + {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, 468}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 206}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, 507}, {40, 440}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 313}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60, 5300, + {{36, 5180, 507}, {40, 5200, 440}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, 516}, {40, 520}, - {44, 506}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 301}, {56, 258}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 620}, {104, 617}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320 , + {{36, 5180, 516}, {40, 5200, 520}, + {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 301}, {56, 5280, 258}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 620}, {104, 5520, 617}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 616}, {40, 601}, - {44, 604}, {48, 589}, - {52, 612}, {56, 592}, - {60, 590}, {64, 582}, - {100, DFS_TX_LEAKAGE_MIN}, {104, 131}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 522}, - {124, 571}, {128, 589}, - {132, 593}, {136, 598}, - {140, 594}, - {144, DFS_TX_LEAKAGE_MIN}, + {100, 5500, + {{36, 5180, 616}, {40, 5200, 601}, + {44, 5220, 604}, {48, 5240, 589}, + {52, 5260, 612}, {56, 5280, 592}, + {60, 5300, 590}, {64, 5320, 582}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522}, + {124, 5620, 571}, {128, 5640, 589}, + {132, 5660, 593}, {136, 5680, 598}, + {140, 5700, 594}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {104, - {{36, 622}, {40, 624}, - {44, 618}, {48, 610}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, 463}, - {116, 483}, {120, 503}, - {124, 523}, {128, 565}, - {132, 570}, {136, 588}, - {140, 585}, - {144, DFS_TX_LEAKAGE_MIN}, + {104, 5520, + {{36, 5180, 622}, {40, 5200, 624}, + {44, 5220, 618}, {48, 5240, 610}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463}, + {116, 5580, 483}, {120, 5600, 503}, + {124, 5620, 523}, {128, 5640, 565}, + {132, 5660, 570}, {136, 5680, 588}, + {140, 5700, 585}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {108, - {{36, 620}, {40, 638}, - {44, 611}, {48, 614}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 477}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 477}, {120, 497}, - {124, 517}, {128, 537}, - {132, 557}, {136, 577}, - {140, 603}, - {144, DFS_TX_LEAKAGE_MIN}, + {108, 5540, + {{36, 5180, 620}, {40, 5200, 638}, + {44, 5220, 611}, {48, 5240, 614}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 477}, {120, 5600, 497}, + {124, 5620, 517}, {128, 5640, 537}, + {132, 5660, 557}, {136, 5680, 577}, + {140, 5700, 603}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {112, - {{36, 636}, {40, 623}, - {44, 638}, {48, 628}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, 606}, - {100, 501}, {104, 481}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, 481}, - {124, 501}, {128, 421}, - {132, 541}, {136, 561}, - {140, 583}, - {144, DFS_TX_LEAKAGE_MIN}, + {112, 5560, + {{36, 5180, 636}, {40, 5200, 623}, + {44, 5220, 638}, {48, 5240, 628}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606}, + {100, 5500, 501}, {104, 5520, 481}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481}, + {124, 5620, 501}, {128, 5640, 421}, + {132, 5660, 541}, {136, 5680, 561}, + {140, 5700, 583}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {116, - {{36, 646}, {40, 648}, - {44, 633}, {48, 634}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, 615}, {64, 594}, - {100, 575}, {104, 554}, - {108, 534}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, 534}, {136, 554}, - {140, 574}, - {144, DFS_TX_LEAKAGE_MIN}, + {116, 5580, + {{36, 5180, 646}, {40, 5200, 648}, + {44, 5220, 633}, {48, 5240, 634}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, 615}, {64, 5320, 594}, + {100, 5500, 575}, {104, 5520, 554}, + {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, 534}, {136, 5680, 554}, + {140, 5700, 574}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {120, - {{36, 643}, {40, 649}, - {44, 654}, {48, 629}, - {52, DFS_TX_LEAKAGE_MAX}, {56, 621}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 565}, {104, 545}, - {108, 525}, {112, 505}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 505}, - {132, 525}, {136, 545}, - {140, 565}, - {144, DFS_TX_LEAKAGE_MIN}, + {120, 5600, + {{36, 5180, 643}, {40, 5200, 649}, + {44, 5220, 654}, {48, 5240, 629}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 565}, {104, 5520, 545}, + {108, 5540, 525}, {112, 5560, 505}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505}, + {132, 5660, 525}, {136, 5680, 545}, + {140, 5700, 565}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {124, - {{36, 638}, {40, 657}, - {44, 663}, {48, 649}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 581}, {104, 561}, - {108, 541}, {112, 521}, - {116, 499}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, 499}, {136, 519}, - {140, 539}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 638}, {40, 5200, 657}, + {44, 5220, 663}, {48, 5240, 649}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 581}, {104, 5520, 561}, + {108, 5540, 541}, {112, 5560, 521}, + {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, 499}, {136, 5680, 519}, + {140, 5700, 539}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 651}, {40, 651}, - {44, 674}, {48, 640}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 603}, {104, 560}, - {108, 540}, {112, 520}, - {116, 499}, {120, 479}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, 479}, - {140, 499}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 651}, {40, 5200, 651}, + {44, 5220, 674}, {48, 5240, 640}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 603}, {104, 5520, 560}, + {108, 5540, 540}, {112, 5560, 520}, + {116, 5580, 499}, {120, 5600, 479}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479}, + {140, 5700, 499}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, 643}, {40, 668}, - {44, 651}, {48, 657}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MAX}, {104, 602}, - {108, 578}, {112, 570}, - {116, 550}, {120, 530}, - {124, 510}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, 490}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, 643}, {40, 5200, 668}, + {44, 5220, 651}, {48, 5240, 657}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602}, + {108, 5540, 578}, {112,5560, 570}, + {116, 5580, 550}, {120, 5600, 530}, + {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, 490}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, 654}, {40, 667}, - {44, 666}, {48, 642}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 596}, - {116, 555}, {120, 535}, - {124, 515}, {128, 495}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136,5680, + {{36, 5180, 654}, {40, 5200, 667}, + {44, 5220, 666}, {48, 5240, 642}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596}, + {116, 5580, 555}, {120, 5600, 535}, + {124, 5620, 515}, {128, 5640, 495}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, 679}, {40, 673}, - {44, 667}, {48, 656}, - {52, 634}, {56, 663}, - {60, 662}, {64, 660}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, - {116, 573}, {120, 553}, - {124, 533}, {128, 513}, - {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140,5700, + {{36, 5180, 679}, {40, 5200, 673}, + {44, 5220, 667}, {48, 5240, 656}, + {52, 5260, 634}, {56, 5280, 663}, + {60, 5300, 662}, {64, 5320, 660}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, + {116, 5580, 573}, {120, 5600, 553}, + {124, 5620, 533}, {128, 5640, 513}, + {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, 679}, {40, 673}, - {44, 667}, {48, 656}, - {52, 634}, {56, 663}, - {60, 662}, {64, 660}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, - {116, 573}, {120, 553}, - {124, 533}, {128, 513}, - {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144,5720, + {{36, 5180, 679}, {40, 5200, 673}, + {44, 5220, 667}, {48, 5240, 656}, + {52, 5260, 634}, {56, 5280, 663}, + {60, 5300, 662}, {64, 5320, 660}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, + {116, 5580, 573}, {120, 5600, 553}, + {124, 5620, 533}, {128, 5640, 513}, + {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; @@ -723,6 +724,7 @@ struct dfs_matrix_tx_leak_info ht20_chan[] = { * * Return: TRUE or FALSE */ +#ifdef CONFIG_CHAN_NUM_API static bool dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, uint8_t NOL_channel, @@ -771,7 +773,72 @@ dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, return true; } } +#endif + +/* + * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage + * matrix. + * @chan_width: target channel width + * @nol_channel: the NOL channel frequency whose leakage matrix is required + * @pTarget_chnl_mtrx: pointer to target channel matrix returned. + * + * This function gives the leakage matrix for given NOL channel and ch_width + * + * Return: TRUE or FALSE + */ +#ifdef CONFIG_CHAN_FREQ_API +static bool +dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width, + uint16_t nol_freq, + struct dfs_tx_leak_info + **pTarget_chnl_mtrx) +{ + struct dfs_tx_leak_info *target_chan_matrix = NULL; + struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; + uint32_t nchan_matrix; + int i = 0; + switch (chan_width) { + case CH_WIDTH_20MHZ: + /* HT20 */ + pchan_matrix = ht20_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); + break; + case CH_WIDTH_40MHZ: + /* HT40 */ + pchan_matrix = ht40_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); + break; + case CH_WIDTH_80MHZ: + /* HT80 */ + pchan_matrix = ht80_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); + break; + default: + /* handle exception and fall back to HT20 table */ + pchan_matrix = ht20_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); + break; + } + + for (i = 0; i < nchan_matrix; i++) { + /* find the SAP channel to map the leakage matrix */ + if (nol_freq == pchan_matrix[i].channel_freq) { + target_chan_matrix = pchan_matrix[i].chan_matrix; + break; + } + } + + if (!target_chan_matrix) { + return false; + } else { + *pTarget_chnl_mtrx = target_chan_matrix; + return true; + } +} +#endif + +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, @@ -779,7 +846,7 @@ dfs_mark_leaking_ch(struct wlan_dfs *dfs, uint8_t *temp_ch_lst) { struct dfs_tx_leak_info *target_chan_matrix = NULL; - uint32_t num_channel = (CHAN_ENUM_144 - CHAN_ENUM_36) + 1; + uint32_t num_channel = (CHAN_ENUM_5720 - CHAN_ENUM_5180) + 1; uint32_t j = 0; uint32_t k = 0; uint8_t dfs_nol_channel; @@ -838,7 +905,79 @@ dfs_mark_leaking_ch(struct wlan_dfs *dfs, return QDF_STATUS_SUCCESS; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +#define END_CHAN_INDEX CHAN_ENUM_5720 +#define START_CHAN_INDEX CHAN_ENUM_5180 +QDF_STATUS +dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + struct dfs_tx_leak_info *target_chan_matrix = NULL; + uint32_t num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1; + uint32_t j = 0; + uint32_t k = 0; + struct dfs_nolelem *nol; + + nol = dfs->dfs_nol; + while (nol) { + if (false == dfs_find_target_channel_in_channel_matrix_for_freq( + ch_width, nol->nol_freq, + &target_chan_matrix)) { + /* + * should never happen, we should always find a table + * here, if we don't, need a fix here! + */ + dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Couldn't find target channel matrix!"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + /* + * following is based on assumption that both temp_freq_lst + * and target channel matrix are in increasing order of + * ch_id + */ + for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) { + if (temp_freq_lst[j] == 0) { + j++; + continue; + } + if (target_chan_matrix[k].leak_chan_freq != + temp_freq_lst[j]) { + k++; + continue; + } + /* + * check leakage from candidate channel + * to NOL channel + */ + if (target_chan_matrix[k].leak_lvl <= + dfs->tx_leakage_threshold) { + /* + * candidate channel will have + * bad leakage in NOL channel, + * remove from temp list + */ + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "dfs: channel: %d will have bad leakage due to channel: %d\n", + nol->nol_freq, temp_freq_lst[j]); + temp_freq_lst[j] = 0; + } + j++; + k++; + } + nol = nol->nol_next; + } /* end of loop that selects each NOL */ + + return QDF_STATUS_SUCCESS; +} +#endif #else +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, @@ -848,18 +987,30 @@ dfs_mark_leaking_ch(struct wlan_dfs *dfs, return QDF_STATUS_SUCCESS; } #endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif /** * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using * bitmap * @dfs: Pointer to DFS structure. * @bitmap: bitmap - * @avail_chnl: prepared channel list + * @avail_freq_list: prepared channel list * * Prepare 80MHz channels from the bitmap. * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_80mhz_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -889,6 +1040,46 @@ static uint8_t dfs_populate_80mhz_available_channels( return chnl_count; } +#endif + +/* + * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels + * available for selection. + * @dfs: Pointer to wlan_dfs. + * @bitmap: Pointer to bonding channel bitmap. + * @avail_freq_list: Pointer to frequency list of available channels. + */ +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t dfs_populate_80mhz_available_channel_for_freq( + struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint16_t *avail_freq_list) +{ + uint8_t i = 0; + uint8_t chnl_count = 0; + uint16_t start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; + if (bitmap->chan_bonding_set[i].chan_map == + DFS_80MHZ_MASK) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); + } + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel count %d", chnl_count); + + return chnl_count; +} +#endif /** * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using @@ -901,6 +1092,7 @@ static uint8_t dfs_populate_80mhz_available_channels( * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_40mhz_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -933,6 +1125,42 @@ static uint8_t dfs_populate_40mhz_available_channels( return chnl_count; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bmap, + uint16_t *avail_freq_list) +{ + uint8_t i = 0; + uint8_t chnl_count = 0; + uint16_t start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq; + if ((bmap->chan_bonding_set[i].chan_map & + DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); + } + if ((bmap->chan_bonding_set[i].chan_map & + DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); + } + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel count %d", chnl_count); + + return chnl_count; +} +#endif /** * dfs_populate_available_channels()- Populate channels based on width and @@ -946,6 +1174,7 @@ static uint8_t dfs_populate_40mhz_available_channels( * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -969,6 +1198,47 @@ static uint8_t dfs_populate_available_channels( return 0; } +#endif + +/** + * dfs_populate_available_channel_for_freq()- Populate channels based on width + * and bitmap. + * @dfs: Pointer to DFS structure. + * @bitmap: bitmap + * @chan_width: channel width + * @avail_freq_list: prepared channel list + * + * Prepare channel list based on width and channel bitmap. + * + * Return: channel count + */ +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint8_t chan_width, + uint16_t *freq_list) +{ + switch (chan_width) { + case DFS_CH_WIDTH_160MHZ: + case DFS_CH_WIDTH_80P80MHZ: + case DFS_CH_WIDTH_80MHZ: + return dfs_populate_80mhz_available_channel_for_freq(dfs, + bitmap, + freq_list); + case DFS_CH_WIDTH_40MHZ: + return dfs_populate_40mhz_available_channel_for_freq(dfs, + bitmap, + freq_list); + default: + dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid chan_width %d", chan_width); + break; + } + + return 0; +} +#endif /** * dfs_get_rand_from_lst()- Get random channel from a given channel list @@ -980,6 +1250,7 @@ static uint8_t dfs_populate_available_channels( * * Return: channel number */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_get_rand_from_lst( struct wlan_dfs *dfs, uint8_t *ch_lst, @@ -1003,6 +1274,44 @@ static uint8_t dfs_get_rand_from_lst( return ch_lst[i]; } +#endif + +/** + * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel + * list. + * @dfs: Pointer to DFS structure. + * @freq_lst: Frequency list + * @num_chan: number of channels + * + * Get random channel from given channel list. + * + * Return: channel frequency. + */ + +#ifdef CONFIG_CHAN_FREQ_API +static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs, + uint16_t *freq_lst, + uint8_t num_chan) +{ + uint8_t i; + uint32_t rand_byte = 0; + + if (!num_chan || !freq_lst) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, + "invalid param freq_lst %pK, num_chan = %d", + freq_lst, num_chan); + return 0; + } + + get_random_bytes((uint8_t *)&rand_byte, 1); + i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan; + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "random channel %d", freq_lst[i]); + + return freq_lst[i]; +} +#endif /** * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based @@ -1015,6 +1324,7 @@ static uint8_t dfs_get_rand_from_lst( * * Return: None */ +#ifdef CONFIG_CHAN_NUM_API static void dfs_random_channel_sel_set_bitmap( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -1036,6 +1346,45 @@ static void dfs_random_channel_sel_set_bitmap( dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "Channel=%d is not in the bitmap", channel); } +#endif + +/** + * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based + * on given channel number + * @dfs: Pointer to DFS structure. + * @bitmap: bitmap + * @chan_freq: channel frequency + * + * Set channel bit in bitmap based on given channel frequency. + * + * Return: None + */ +#ifdef CONFIG_CHAN_FREQ_API +#define FREQUENCY_BAND_LIMIT 60 +static void +dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint16_t chan_freq) +{ + int i = 0; + int start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; + if (chan_freq >= start_chan_freq && + chan_freq <= start_chan_freq + + FREQUENCY_BAND_LIMIT) { + bitmap->chan_bonding_set[i].chan_map |= + (1 << ((chan_freq - start_chan_freq) / + DFS_80_NUM_SUB_CHANNEL_FREQ)); + return; + } + } + + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Frequency=%d is not in the bitmap", chan_freq); +} +#endif /** * dfs_find_ch_with_fallback()- find random channel @@ -1050,6 +1399,7 @@ static void dfs_random_channel_sel_set_bitmap( * * Return: channel number */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_find_ch_with_fallback( struct wlan_dfs *dfs, uint8_t *ch_wd, @@ -1062,7 +1412,7 @@ static uint8_t dfs_find_ch_with_fallback( struct chan_bonding_bitmap ch_map = { { {0} } }; uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; - uint8_t final_lst[DFS_MAX_NUM_CHAN] = {0}; + uint8_t final_lst[NUM_CHANNELS] = {0}; /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ ch_map.chan_bonding_set[0].start_chan = 36; @@ -1184,27 +1534,159 @@ static uint8_t dfs_find_ch_with_fallback( return target_channel; } +#endif /** - * dfs_remove_cur_ch_from_list()- remove current operating channels - * @ch_list: list of avilable channel list - * @ch_cnt: number of channels. - * @ch_wd: channel width. - * @cur_chan: current channel. + * dfs_find_ch_with_fallback_for_freq()- find random channel + * @dfs: Pointer to DFS structure. + * @chan_wd: channel width + * @center_freq_seg1: center frequency of secondary segment. + * @freq_lst: list of available frequency. + * @num_chan: number of channels in the list. * - * Remove current channels from list of available channels. + * Find random channel based on given channel width and channel list, + * fallback to lower width if requested channel width not available. * - * Return: channel number + * Return: channel frequency. */ -static void dfs_remove_cur_ch_from_list( - struct dfs_channel *ch_list, - uint32_t *ch_cnt, - uint8_t *ch_wd, - struct dfs_channel *cur_chan) +#ifdef CONFIG_CHAN_FREQ_API +static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs, + uint8_t *chan_wd, + uint16_t *center_freq_seg1, + uint16_t *freq_lst, + uint32_t num_chan) { - /* TODO */ - return; + bool flag = false; + uint32_t rand_byte = 0; + struct chan_bonding_bitmap ch_map = { { {0} } }; + uint8_t count = 0, i, index = 0, final_cnt = 0; + uint16_t target_channel = 0; + uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; + uint16_t final_lst[NUM_CHANNELS] = {0}; + + /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ + ch_map.chan_bonding_set[0].start_chan_freq = 5180; + ch_map.chan_bonding_set[1].start_chan_freq = 5260; + ch_map.chan_bonding_set[2].start_chan_freq = 5500; + ch_map.chan_bonding_set[3].start_chan_freq = 5580; + ch_map.chan_bonding_set[4].start_chan_freq = 5660; + ch_map.chan_bonding_set[5].start_chan_freq = 5745; + + for (i = 0; i < num_chan; i++) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel = %d added to bitmap", freq_lst[i]); + dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map, + freq_lst[i]); + } + + /* populate available channel list from bitmap */ + final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map, + *chan_wd, final_lst); + + /* If no valid ch bonding found, fallback */ + if (final_cnt == 0) { + if ((*chan_wd == DFS_CH_WIDTH_160MHZ) || + (*chan_wd == DFS_CH_WIDTH_80P80MHZ) || + (*chan_wd == DFS_CH_WIDTH_80MHZ)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 40Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_40MHZ; + } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from 40Mhz to 20MHz"); + *chan_wd = DFS_CH_WIDTH_20MHZ; + } + return 0; + } + + /* ch count should be > 8 to switch new channel in 160Mhz band */ + if (((*chan_wd == DFS_CH_WIDTH_160MHZ) || + (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) && + (final_cnt < DFS_MAX_20M_SUB_CH)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 80Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_80MHZ; + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_160MHZ) { + /* + * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 + * and all the channels in these blocks are continuous + * and separated by 4Mhz. + */ + for (i = 1; ((i < final_cnt)); i++) { + if ((final_lst[i] - final_lst[i - 1]) == + DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET) + count++; + else + count = 0; + if (count == DFS_MAX_20M_SUB_CH - 1) { + flag = true; + new_160_start_ch = final_lst[i - count]; + break; + } + } + } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { + flag = true; + } + + if ((flag == false) && (*chan_wd > DFS_CH_WIDTH_80MHZ)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 80Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_80MHZ; + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_160MHZ) { + get_random_bytes((uint8_t *)&rand_byte, 1); + rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) + % DFS_MAX_20M_SUB_CH; + target_channel = new_160_start_ch + (rand_byte * + DFS_80_NUM_SUB_CHANNEL_FREQ); + } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { + get_random_bytes((uint8_t *)&rand_byte, 1); + index = (rand_byte + qdf_mc_timer_get_system_ticks()) % + final_cnt; + target_channel = final_lst[index]; + index -= (index % DFS_80_NUM_SUB_CHANNEL); + primary_seg_start_ch = final_lst[index]; + + /* reset channels associate with primary 80Mhz */ + for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) + final_lst[i + index] = 0; + /* select and calculate center freq for secondary segment */ + for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { + if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] && + (abs(primary_seg_start_ch - + final_lst[i * DFS_80_NUM_SUB_CHANNEL]) > + (DFS_80P80M_FREQ_DIFF * 2))) { + sec_seg_ch = final_lst[i * + DFS_80_NUM_SUB_CHANNEL] + + DFS_80MHZ_START_CENTER_CH_FREQ_DIFF; + break; + } + } + + if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH)) + *chan_wd = DFS_CH_WIDTH_160MHZ; + else if (!sec_seg_ch) + *chan_wd = DFS_CH_WIDTH_80MHZ; + + *center_freq_seg1 = sec_seg_ch; + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Center frequency seg1 = %d", sec_seg_ch); + } else { + target_channel = dfs_get_rand_from_lst_for_freq(dfs, + final_lst, + final_cnt); + } + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "target channel = %d", target_channel); + + return target_channel; } +#endif bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) { @@ -1241,8 +1723,9 @@ bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) * * prepare channel list based on flags * - * Return: None + * return: none */ +#ifdef CONFIG_CHAN_NUM_API static void dfs_apply_rules(struct wlan_dfs *dfs, uint32_t flags, uint8_t *random_chan_list, @@ -1301,8 +1784,8 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, if (acs_info && acs_info->acs_mode) { for (j = 0; j < acs_info->num_of_channel; j++) { - if (acs_info->channel_list[j] == - chan->dfs_ch_ieee) { + if (acs_info->chan_freq_list[j] == + wlan_chan_to_freq(chan->dfs_ch_ieee)) { found = true; break; } @@ -1379,7 +1862,178 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, *random_chan_cnt += 1; } } +#endif + +/** + * dfs_apply_rules_for_freq()- prepare channel list based on flags + * @dfs: dfs handler + * @flags: channel flags + * @random_chan_freq_list: output channel list + * @random_chan_cnt: output channel count + * @chan_list: input channel list + * @chan_cnt: input channel count + * @dfs_region: dfs region + * @acs_info: acs channel range information + * + * prepare channel list based on flags + * + * return: none + */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs, + uint32_t flags, + uint16_t *random_chan_freq_list, + uint32_t *random_chan_cnt, + struct dfs_channel *chan_list, + uint32_t chan_cnt, + uint8_t dfs_region, + struct dfs_acs_info *acs_info) +{ + struct dfs_channel *chan; + bool flag_no_weather = 0; + bool flag_no_lower_5g = 0; + bool flag_no_upper_5g = 0; + bool flag_no_dfs_chan = 0; + bool flag_no_2g_chan = 0; + bool flag_no_5g_chan = 0; + bool flag_no_japan_w53 = 0; + int i; + bool found = false; + uint16_t j; + uint16_t freq_list[NUM_CHANNELS_160MHZ]; + uint8_t num_channels = 0; + + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; + + if (dfs_region == DFS_MKK_REGION_VAL) { + flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; + flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; + flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; + } + + flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; + flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; + flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; + + if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { + num_channels = + dfs_get_bonding_channel_without_seg_info_for_freq + (dfs->dfs_curchan, freq_list); + } + + for (i = 0; i < chan_cnt; i++) { + chan = &chan_list[i]; + found = false; + + if ((chan->dfs_ch_ieee == 0) || + (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "invalid channel %d", chan->dfs_ch_ieee); + continue; + } + + if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { + for (j = 0; j < num_channels; j++) { + if (chan->dfs_ch_freq == freq_list[j]) { + dfs_debug(dfs, + WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip %d current operating channel", + chan->dfs_ch_freq); + found = true; + break; + } + } + + if (found) + continue; + } + + if (acs_info && acs_info->acs_mode) { + for (j = 0; j < acs_info->num_of_channel; j++) { + if (acs_info->chan_freq_list[j] == + chan->dfs_ch_freq) { + found = true; + break; + } + } + + if (!found) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip ch freq %d not in acs range", + chan->dfs_ch_freq); + continue; + } + found = false; + } + + if (flag_no_2g_chan && + chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_5g_chan && chan->dfs_ch_freq > + DFS_MAX_24GHZ_CHANNEL_FREQ) + { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip 5 GHz channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_weather) { + if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip weather channel=%d", + chan->dfs_ch_ieee); + continue; + } + } + + if (flag_no_lower_5g && + DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip indoor channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_upper_5g && + DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip outdoor channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_dfs_chan && + (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip dfs channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_japan_w53 && + DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip japan W53 channel=%d", + chan->dfs_ch_ieee); + continue; + } + + if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip nol channel=%d", chan->dfs_ch_ieee); + continue; + } + + random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq; + *random_chan_cnt += 1; + } +} +#endif +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *ch_list, uint32_t ch_cnt, @@ -1415,9 +2069,6 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, if (!random_chan_list) return 0; - if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) - dfs_remove_cur_ch_from_list(ch_list, &ch_cnt, ch_wd, cur_chan); - dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt, ch_list, ch_cnt, dfs_region, acs_info); @@ -1491,3 +2142,139 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, return target_ch; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *chan_list, + uint32_t chan_cnt, + uint32_t flags, + uint8_t *chan_wd, + struct dfs_channel *cur_chan, + uint8_t dfs_region, + struct dfs_acs_info *acs_info) +{ + int i = 0; + uint8_t final_cnt = 0; + uint16_t target_freq = 0; + uint16_t *random_chan_freq_list = NULL; + uint32_t random_chan_cnt = 0; + uint16_t flag_no_weather = 0; + uint16_t *leakage_adjusted_lst; + uint16_t final_lst[NUM_CHANNELS] = {0}; + uint16_t *dfs_cfreq_seg2 = NULL; + + if (!chan_list || !chan_cnt) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid params %pK, chan_cnt=%d", + chan_list, chan_cnt); + return 0; + } + + if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_80P80MHZ) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid chan_wd %d", *chan_wd); + return 0; + } + + random_chan_freq_list = + qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list)); + if (!random_chan_freq_list) + return 0; + + dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list, + &random_chan_cnt, chan_list, chan_cnt, + dfs_region, acs_info); + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; + + /* list adjusted after leakage has been marked */ + leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt * + sizeof(*leakage_adjusted_lst)); + if (!leakage_adjusted_lst) { + qdf_mem_free(random_chan_freq_list); + return 0; + } + + do { + int ret; + + qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list, + random_chan_cnt * sizeof(*leakage_adjusted_lst)); + ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd, + random_chan_cnt, + leakage_adjusted_lst); + if (QDF_IS_STATUS_ERROR(ret)) { + qdf_mem_free(random_chan_freq_list); + qdf_mem_free(leakage_adjusted_lst); + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_20MHZ) { + /* + * PASS: 3 - from leakage_adjusted_lst, prepare valid + * ch list and use random number from that + */ + for (i = 0; i < random_chan_cnt; i++) { + if (leakage_adjusted_lst[i] == 0) + continue; + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Channel=%d added to available list", + leakage_adjusted_lst[i]); + final_lst[final_cnt] = leakage_adjusted_lst[i]; + final_cnt++; + } + target_freq = dfs_get_rand_from_lst_for_freq(dfs, + final_lst, + final_cnt); + break; + } + dfs_cfreq_seg2 = &cur_chan->dfs_ch_mhz_freq_seg2; + target_freq = + dfs_find_ch_with_fallback_for_freq(dfs, chan_wd, + dfs_cfreq_seg2, + leakage_adjusted_lst, + random_chan_cnt); + + /* Since notion of 80+80 is not present in the regulatory + * channel the function may return invalid 80+80 channels for + * some devices (e.g. Pine). Therefore, check if we need to + * correct it by checking the following condition. + */ + if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) && + (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) && + !(CHAN_WITHIN_RESTRICTED_80P80(target_freq, + *dfs_cfreq_seg2))) { + *chan_wd = DFS_CH_WIDTH_160MHZ; + target_freq = dfs_find_ch_with_fallback_for_freq( + dfs, chan_wd, dfs_cfreq_seg2, + leakage_adjusted_lst, random_chan_cnt); + } + + /* + * When flag_no_weather is set, avoid usage of Adjacent + * weather radar channel in HT40 mode as extension channel + * will be on 5600. + */ + if (flag_no_weather && + (target_freq == + DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) && + (*chan_wd == DFS_CH_WIDTH_40MHZ)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip weather adjacent ch=%d\n", + target_freq); + continue; + } + + if (target_freq) + break; + } while (true); + + qdf_mem_free(random_chan_freq_list); + qdf_mem_free(leakage_adjusted_lst); + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d", + target_freq); + + return target_freq; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h index aa339a023875b4e615d14e10377abde988a72329..a17d29b32d64fe77c0f075b8286324da0dec56ce 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2010, Atheros Communications Inc. * All Rights Reserved. * @@ -53,29 +53,45 @@ #define DFS_SET_DISABLE_RADAR_MARKING 25 #define DFS_GET_DISABLE_RADAR_MARKING 26 +#define DFS_INJECT_SEQUENCE 27 +#define DFS_ALLOW_HW_PULSES 28 +#define DFS_SET_PRI_MULTIPILER 29 + +#define RESTRICTED_80P80_START_CHAN 132 +#define RESTRICTED_80P80_END_CHAN 161 + +/* Check if the given channels are within restricted 80P80 start chan(132) and + * end chan (161). + */ +#define CHAN_WITHIN_RESTRICTED_80P80(chan, cfreq_seg2) \ + ((((chan) >= RESTRICTED_80P80_START_CHAN) && \ + ((chan) <= RESTRICTED_80P80_END_CHAN) && \ + ((cfreq_seg2) >= RESTRICTED_80P80_START_CHAN) && \ + ((cfreq_seg2) <= RESTRICTED_80P80_END_CHAN)) ? true : false) + /* * Spectral IOCTLs use DFS_LAST_IOCTL as the base. * This must always be the last IOCTL in DFS and have * the highest value. */ -#define DFS_LAST_IOCTL 27 +#define DFS_LAST_IOCTL 29 #ifndef DFS_CHAN_MAX -#define DFS_CHAN_MAX 1023 +#define DFS_CHAN_MAX 25 #endif /** * struct dfsreq_nolelem - NOL elements. * @nol_freq: NOL channel frequency. * @nol_chwidth: NOL channel width. - * @nol_start_us: OS microseconds when the NOL timer started. + * @nol_start_ticks: OS ticks when the NOL timer started. * @nol_timeout_ms: Nol timeout value in msec. */ struct dfsreq_nolelem { uint16_t nol_freq; uint16_t nol_chwidth; - uint64_t nol_start_us; + unsigned long nol_start_ticks; uint32_t nol_timeout_ms; }; @@ -189,6 +205,10 @@ struct dfs_bangradar_params { /* Flag to exclude Japan W53 channnels */ #define DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH 0x0100 /* 0000 0001 0000 0000 */ +/* Restricted 80P80 MHz is enabled */ +#define DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED 0x0200 + /* 0000 0010 0000 0000 */ + /** * struct wlan_dfs_caps - DFS capability structure. * @wlan_dfs_ext_chan_ok: Can radar be detected on the extension chan? @@ -271,4 +291,69 @@ enum WLAN_DFS_EVENTS { WLAN_EV_NOL_FINISHED, }; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * Structure of Pulse to be injected into the DFS Module + * ****************************************************** + * Header + * ====== + * ----------|--------------| + * num_pulses| total_len_seq| + * ----------|--------------| + * Buffer Contents per pulse: + * ========================== + * ------|----------|-----------|----------|-----------|---------------|-------- + * r_rssi|r_ext_rssi|r_rs_tstamp|r_fulltsf |fft_datalen|total_len_pulse|FFT + * | | | | | |Buffer.. + * ------|----------|-----------|----------|-----------|---------------|-------- + */ + +/** + * struct synthetic_pulse - Radar Pulse Structure to be filled on reading the + * user file. + * @r_rssi: RSSI of the pulse. + * @r_ext_rssi: Extension Channel RSSI. + * @r_rs_tstamp: Timestamp. + * @r_fulltsf: TSF64. + * @fft_datalen: Total len of FFT. + * @total_len_pulse: Total len of the pulse. + * @fft_buf: Pointer to fft data. + */ + +struct synthetic_pulse { + uint8_t r_rssi; + uint8_t r_ext_rssi; + uint32_t r_rs_tstamp; + uint64_t r_fulltsf; + uint16_t fft_datalen; + uint16_t total_len_pulse; + unsigned char *fft_buf; +} qdf_packed; + +/** + * struct synthetic_seq - Structure to hold an array of pointers to the + * pulse structure. + * @num_pulses: Total num of pulses in the sequence. + * @total_len_seq: Total len of the sequence. + * @pulse: Array of pointers to synthetic_pulse structure. + */ + +struct synthetic_seq { + uint8_t num_pulses; + uint32_t total_len_seq; + struct synthetic_pulse *pulse[0]; +}; + +/** + * struct seq_store - Structure to hold an array of pointers to the synthetic + * sequence structure. + * @num_sequence: Total number of "sequence of pulses" in the file. + * @seq_arr: Array of pointers to synthetic_seq structure. + */ + +struct seq_store { + uint8_t num_sequence; + struct synthetic_seq *seq_arr[0]; +}; +#endif /* WLAN_DFS_PARTIAL_OFFLOAD && WLAN_DFS_SYNTHETIC_RADAR */ #endif /* _DFS_IOCTL_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h index 99b671e9159680a37b3a94712aa0dad03d681262..5ed030da216a6b55681281a4e62cd0183d263c43 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -118,4 +118,13 @@ static inline bool lmac_is_host_dfs_check_support_enabled( return false; } #endif + +/** + * lmac_dfs_is_hw_mode_switch_in_progress() - Check if HW mode switch is in + * progress. + * @pdev: Pointer to PDEV structure. + * + * Return: true if HW mode switch is in progress, else false. + */ +bool lmac_dfs_is_hw_mode_switch_in_progress(struct wlan_objmgr_pdev *pdev); #endif /* _WLAN_DFS_LMAC_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h index 3719595f858694e5d8febac5a90b4a597ce89251..3593f06d0f0a7620562363225b96ee3100fc1268 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -44,12 +44,29 @@ void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev, * @vhtop_ch_freq_seg2: VHT80 Cfreq2. * @flags: channel flags. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint16_t freq, uint8_t vhtop_ch_freq_seg2, uint64_t flags); +#endif +/** + * dfs_mlme_mark_dfs_for_freq() - Mark the channel in the channel list. + * @pdev: Pointer to DFS pdev object. + * @ieee: Channel number. + * @freq: Channel frequency. + * @vhtop_ch_freq_seg2_mhz: VHT80 Cfreq2 in Mhz. + * @flags: channel flags. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_mark_dfs_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee, + uint16_t freq, + uint16_t vhtop_ch_freq_mhz_seg2, + uint64_t flags); +#endif /** * dfs_mlme_start_csa() - Sends CSA in ieeeChan * @pdev: Pointer to DFS pdev object. @@ -58,12 +75,29 @@ void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, * @cfreq2: HT80 cfreq2. * @flags: channel flags. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieee_chan, uint16_t freq, uint8_t cfreq2, uint64_t flags); +#endif +/** + * dfs_mlme_start_csa_for_freq() - Sends CSA in ieeeChan + * @pdev: Pointer to DFS pdev object. + * @ieee_chan: Channel number. + * @freq: Channel frequency. + * @cfreq2: HT80 cfreq2 in Mhz. + * @flags: channel flags. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee_chan, + uint16_t freq, + uint16_t cfreq2_mhz, + uint64_t flags); +#endif /** * dfs_mlme_proc_cac() - Process the CAC completion event. * @pdev: Pointer to DFS pdev object. @@ -96,6 +130,7 @@ void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev, int *nchans); * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency applicable for 80+80MHz * mode of operation. */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -103,6 +138,34 @@ QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, uint8_t *dfs_ch_ieee, uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2); +#endif + +/** + * dfs_mlme_get_extchan() - Get extension channel. + * @pdev: Pointer to DFS pdev object. + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_flags: Channel flags. + * @dfs_chan_flagext: Extended channel flags. + * @dfs_chan_ieee: IEEE channel number. + * @dfs_chan_vhtop_ch_freq_seg1: Channel Center IEEE. + * @dfs_chan_vhtop_ch_freq_seg2: Channel Center IEEE applicable for 80+80MHz + * mode of operation. + * @dfs_chan_mhz_freq_seg1: Primary channel center freq. + * @dfs_chan_mhz_freq_seg2: Secondary channel center freq applicable for + * 80+80 MHZ. + */ + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_ch_freq_seg1, + uint8_t *dfs_chan_vhtop_ch_freq_seg2, + uint16_t *dfs_chan_mhz_freq_seg1, + uint16_t *dfs_chan_mhz_freq_seg2); +#endif /** * dfs_mlme_set_no_chans_available() - Set no_chans_available flag. @@ -140,6 +203,7 @@ int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, * * QDF_STATUS_SUCCESS : Channel found. * * QDF_STATUS_E_FAILURE: Channel not found. */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, uint8_t ieee, @@ -151,6 +215,46 @@ dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, uint8_t *dfs_ch_ieee, uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2); +#endif + +/** + * dfs_mlme_find_dot11_chan_for_freq() - Find a channel pointer given the mode, + * frequency and channel flags. + * @pdev: Pointer to DFS pdev object. + * @ch_freq: Channel frequency. + * @des_cfreq2_mhz: cfreq2 in MHZ. + * @mode: Phymode + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_flags: Channel flags. + * @dfs_chan_flagext: Extended channel flags. + * @dfs_chan_ieee: IEEE channel number. + * @dfs_chan_vhtop_ch_freq_seg1: Channel Center IEEE for primary 80 segment. + * @dfs_chan_vhtop_ch_freq_seg2: Channel Center frequency applicable for + * 80+80MHz mode of operation. + * @dfs_chan_mhz_freq_seg1: Channel center frequency of primary 80 segment. + * @dfs_chan_mhz_freq_seg2: Channel center frequency for secondary 80 + * segment applicable only for 80+80MHZ mode of + * operation. + * + * Return: + * * QDF_STATUS_SUCCESS : Channel found. + * * QDF_STATUS_E_FAILURE: Channel not found. + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t chan_freq, + uint16_t des_cfreq2_mhz, + int mode, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_ch_freq_seg1, + uint8_t *dfs_chan_vhtop_ch_freq_seg2, + uint16_t *dfs_chan_mhz_freq_seg1, + uint16_t *dfs_chan_mhz_freq_seg2); +#endif /** * dfs_mlme_get_dfs_ch_channels() - Get channel from channel list. @@ -164,6 +268,7 @@ dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, * mode of operation. * @index: Index into channel list. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -172,6 +277,36 @@ void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2, int index); +#endif + +/** + * dfs_mlme_get_dfs_channels_for_freq() - Get DFS channel from channel list. + * @pdev: Pointer to DFS pdev object. + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_flags: Channel flags. + * @dfs_chan_flagext: Extended channel flags. + * @dfs_chan_ieee: IEEE channel number. + * @dfs_chan_vhtop_ch_freq_seg1: Channel Center IEEE number. + * @dfs_chan_vhtop_ch_freq_seg2: Channel Center IEEE applicable for 80+80MHz + * mode of operation. + * @dfs_chan_mhz_freq_seg1 : Primary 80 Channel Center frequency. + * @dfs_chan_mhz_freq_seg2 : Channel center frequency applicable only for + * 80+80 mode of operation. + * @index: Index into channel list. + */ +#ifdef CONFIG_CHAN_FREQ_API +void +dfs_mlme_get_dfs_channels_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_ch_freq_seg1, + uint8_t *dfs_chan_vhtop_ch_freq_seg2, + uint16_t *dfs_chan_mhz_freq_seg1, + uint16_t *dfs_chan_mhz_freq_seg2, + int index); +#endif /** * dfs_mlme_dfs_ch_flags_ext() - Get extension channel flags. @@ -209,11 +344,27 @@ void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, * mode of operation. * @dfs_ch_flags: Channel flags. */ +#ifdef CONFIG_CHAN_NUM_API int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint8_t dfs_ch_vhtop_ch_freq_seg2, uint64_t dfs_ch_flags); +#endif +/** + * dfs_mlme_get_cac_timeout_for_freq() - Get cac_timeout. + * @pdev: Pointer to DFS pdev object. + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_vhtop_freq_seg2: Channel Center frequency applicable for 80+80MHz + * mode of operation. + * @dfs_chan_flags: Channel flags. + */ +#ifdef CONFIG_CHAN_FREQ_API +int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_chan_freq, + uint16_t dfs_chan_vhtop_freq_seg2_mhz, + uint64_t dfs_chan_flags); +#endif /** * dfs_mlme_rebuild_chan_list_with_non_dfs_channels() - Rebuild the channel list * with only non DFS channels. @@ -257,12 +408,12 @@ void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, */ #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num); + uint32_t chan_freq); #else static inline bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) + uint32_t chan_freq) { return true; } @@ -289,4 +440,22 @@ void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) * Return: true if pdev opmode is STA, else false. */ bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev); + +/** + * dfs_mlme_acquire_radar_mode_switch_lock() - Acquire lock for radar processing + * over mode switch handling. + * @pdev: Pointer to DFS pdev object. + * + * Return: void. + */ +void dfs_mlme_acquire_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev); + +/** + * dfs_mlme_release_radar_mode_switch_lock() - Release lock taken for radar + * processing over mode switch handling. + * @pdev: Pointer to DFS pdev object. + * + * Return: void. + */ +void dfs_mlme_release_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev); #endif /* _WLAN_DFS_MLME_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h index 5ee103a4ac9e165ed70781bf54e69ac42c71ad9e..dfa407daeff1a7e2235c48b2d4479a8bd549b05e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h @@ -56,12 +56,12 @@ struct radar_found_info { /** * struct dfs_acs_info - acs info, ch range * @acs_mode: to enable/disable acs 1/0. - * @channel_list: channel list in acs config + * @chan_freq_list: channel frequency list * @num_of_channel: number of channel in ACS channel list */ struct dfs_acs_info { uint8_t acs_mode; - uint8_t *channel_list; + uint32_t *chan_freq_list; uint8_t num_of_channel; }; @@ -124,4 +124,20 @@ struct dfs_radar_found_params { u_int32_t sidx_min; u_int32_t sidx_max; }; + +/** + * struct dfs_agile_cac_params - Agile DFS-CAC parameters. + * @precac_chan: Agile preCAC channel. + * @precac_chan_freq: Agile preCAC channel frequency in MHZ. + * @precac_chwidth: Agile preCAC channel width. + * @min_precac_timeout: Minimum agile preCAC timeout. + * @max_precac_timeout: Maximum agile preCAC timeout. + */ +struct dfs_agile_cac_params { + uint8_t precac_chan; + uint16_t precac_chan_freq; + enum phy_ch_width precac_chwidth; + uint32_t min_precac_timeout; + uint32_t max_precac_timeout; +}; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index c2b4ed4d85dba03d6728aeda75e6b814d563a0d5..c49a497ae22ddbdb2aab46ea90cf47e8684ea6e3 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -97,7 +97,7 @@ struct dfs_emulate_bang_radar_test_cmd { * @vdev_id: Physical device identifier * @chan_freq: Channel number * @chan_width: Channel Width - * @center_freq: Center Frequency channel number + * @center_freq: Center channel number * @ocac_status: off channel cac status */ struct vdev_adfs_complete_status { @@ -122,6 +122,7 @@ extern struct dfs_to_mlme global_dfs_to_mlme; * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency2. */ #ifdef DFS_COMPONENT_ENABLE +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -129,6 +130,34 @@ QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, uint8_t dfs_ch_ieee, uint8_t dfs_ch_vhtop_ch_freq_seg1, uint8_t dfs_ch_vhtop_ch_freq_seg2); +#endif + +/** + * tgt_dfs_set_current_channel_for_freq() - Fill dfs channel structure from + * dfs_channel structure. + * @pdev: Pointer to DFS pdev object. + * @dfs_ch_freq: Frequency in Mhz. + * @dfs_ch_flags: Channel flags. + * @dfs_ch_flagext: Extended channel flags. + * @dfs_ch_ieee: IEEE channel number. + * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency1. + * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency2. + * @dfs_ch_mhz_freq_seg1: Channel center frequency of primary segment in MHZ. + * @dfs_ch_mhz_freq_seg2: Channel center frequency of secondary segment in MHZ + * applicable only for 80+80MHZ mode of operation. + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_ch_freq, + uint64_t dfs_ch_flags, + uint16_t dfs_ch_flagext, + uint8_t dfs_ch_ieee, + uint8_t dfs_ch_vhtop_ch_freq_seg1, + uint8_t dfs_ch_vhtop_ch_freq_seg2, + uint16_t dfs_ch_mhz_freq_seg1, + uint16_t dfs_ch_mhz_freq_seg2); +#endif /** * tgt_dfs_radar_enable() - Enables the radar. @@ -350,6 +379,7 @@ QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev, * wrapper function for dfs_find_vht80_chan_for_precacdfs_cancel_cac_timer(). * This function called from outside of dfs component. */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -358,6 +388,32 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, uint32_t *phy_mode, bool *dfs_set_cfreq2, bool *set_agile); +#endif + +/** + * tgt_dfs_find_vht80_precac_chan_freq() - Find VHT80 channel for precac + * @pdev: Pointer to DFS pdev object. + * @chan_mode: Channel mode. + * @ch_freq_seg1_mhz: Segment1 channel freq in MHZ. + * @cfreq1: cfreq1. + * @cfreq2: cfreq2. + * @phy_mode: Precac phymode. + * @dfs_set_cfreq2: Precac cfreq2 + * @set_agile: Agile mode flag. + * + * wrapper function for dfs_find_vht80_chan_for_precac_for_freq(). + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_find_vht80_precac_chan_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_mode, + uint16_t ch_freq_mhz_seg1, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile); +#endif /** * tgt_dfs_cac_complete() - Process cac complete indication. @@ -528,4 +584,97 @@ tgt_dfs_send_subchan_marking(struct wlan_objmgr_pdev *pdev, bool subchanmark) return QDF_STATUS_SUCCESS; } #endif +#ifdef QCA_SUPPORT_AGILE_DFS +/** + * tgt_dfs_set_fw_adfs_support() - Set FW aDFS support in dfs object. + * @pdev: Pointer to pdev object. + * @fw_adfs_support_160: aDFS enabled when pdev is on 160/80P80MHz. + * @fw_adfs_support_non_160: aDFS enabled when pdev is on 20/40/80MHz. + * + * Return: void. + */ +void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160); +#else +static inline +void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160) +{ +} +#endif + +/** + * tgt_dfs_init_tmp_psoc_nol() - Init temporary psoc NOL structure. + * @pdev: Pointer to pdev object. + * @num_radios: Number of radios in the psoc. + * + * Return: void. + */ +void tgt_dfs_init_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev, + uint8_t num_radios); + +/** + * tgt_dfs_deinit_tmp_psoc_nol() - De-init temporary psoc NOL structure. + * @pdev: Pointer to pdev object. + * + * Return: void. + */ +void tgt_dfs_deinit_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev); + +/** + * tgt_dfs_save_dfs_nol_in_psoc() - Save NOL data of given pdev. + * @pdev: Pointer to pdev object. + * @pdev_id: The pdev ID which will have the NOL data. + * @low_5ghz_freq: The low 5GHz frequency value of the target pdev id. + * @high_5ghz_freq: The high 5GHz frequency value of the target pdev id. + * + * Based on the frequency of the NOL channel, copy it to the target pdev_id + * structure in psoc. + * + * Return: void. + */ +void tgt_dfs_save_dfs_nol_in_psoc(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id, + uint16_t low_5ghz_freq, + uint16_t high_5ghz_freq); + +/** + * tgt_dfs_reinit_nol_from_psoc_copy() - Reinit saved NOL data to corresponding + * pdevs. + * @pdev: Pointer to pdev object. + * @pdev_id: pdev_id of the given pdev. + * + * Return: void. + */ +void tgt_dfs_reinit_nol_from_psoc_copy(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id); + +/** + * tgt_dfs_reinit_precac_lists() - Reinit preCAC lists. + * @src_pdev: Source pdev object from which the preCAC list is copied. + * @dest_pdev: Destination pdev object to which the preCAC list is copied. + * @low_5g_freq: Low 5G frequency value of the destination DFS. + * @high_5g_freq: High 5G frequency value of the destination DFS. + * + * Copy all the preCAC list entries from the source pdev object to the + * destination pdev object which fall within the frequency range of + * low_5g_freq and high_5g_freq. + * + * Return: None (void). + */ +void tgt_dfs_reinit_precac_lists(struct wlan_objmgr_pdev *src_pdev, + struct wlan_objmgr_pdev *dest_pdev, + uint16_t low_5g_freq, + uint16_t high_5g_freq); + +/** + * tgt_dfs_complete_deferred_tasks() - Process HW mode switch completion and + * handle deferred tasks. + * @pdev: Pointer to primary pdev object. + * + * Return: void. + */ +void tgt_dfs_complete_deferred_tasks(struct wlan_objmgr_pdev *pdev); #endif /* _WLAN_DFS_TGT_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index 9c409ccbfab2f2fb3d1bcc7b626c49e204018117..2d7d7fb8252beee3ae5b8cb376288c418c7fd3e2 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -64,6 +64,19 @@ * @mlme_update_scan_channel_list: Update the scan channel list sent to FW. * @mlme_bringdown_vaps: Bringdown vaps if no chans is present. * @mlme_dfs_deliver_event: Deliver DFS events to user space + * @mlme_precac_chan_change_csa_for_freq:Channel change triggered by PrCAC using + * Channel Switch Announcement. + * @mlme_mark_dfs_for_freq: Mark DFS channel frequency as radar. + * @mlme_get_extchan_for_freq: Get the extension channel. + * @mlme_find_dot11_chan_for_freq: Find a channel pointer. + * @mlme_get_dfs_channels_for_freq: Get DFS channels from current channel + * list. + * @mlme_get_cac_timeout_for_freq: Get CAC timeout for a given channel + * frequency. + * @mlme_acquire_radar_mode_switch_lock: Acquire lock for radar processing over + * mode switch. + * @mlme_release_radar_mode_switch_lock: Release lock taken for radar processing + * over mode switch. */ struct dfs_to_mlme { QDF_STATUS (*pdev_component_obj_attach)(struct wlan_objmgr_pdev *pdev, @@ -75,19 +88,37 @@ struct dfs_to_mlme { void *comp_priv_obj); QDF_STATUS (*dfs_start_rcsa)(struct wlan_objmgr_pdev *pdev, bool *wait_for_csa); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_mark_dfs)(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint16_t freq, uint8_t vhtop_ch_freq_seg2, uint64_t flags); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS (*mlme_mark_dfs_for_freq)(struct wlan_objmgr_pdev *pdev, + uint8_t ieee, + uint16_t freq, + uint16_t ic_mhz_freq_seg2, + uint64_t flags); +#endif +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_start_csa)(struct wlan_objmgr_pdev *pdev, uint8_t ieee_chan, uint16_t freq, uint8_t cfreq2, uint64_t flags); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS (*mlme_start_csa_for_freq)(struct wlan_objmgr_pdev *pdev, + uint8_t ieee_chan, uint16_t freq, + uint16_t cfreq2, uint64_t flags); +#endif + QDF_STATUS (*mlme_proc_cac)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*mlme_deliver_event_up_after_cac)( struct wlan_objmgr_pdev *pdev); QDF_STATUS (*mlme_get_dfs_ch_nchans)(struct wlan_objmgr_pdev *pdev, int *nchans); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_get_extchan)(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -95,12 +126,25 @@ struct dfs_to_mlme { uint8_t *dfs_ch_ieee, uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS (*mlme_get_extchan_for_freq)(struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_ch_freq, + uint64_t *dfs_ch_flags, + uint16_t *dfs_ch_flagext, + uint8_t *dfs_ch_ieee, + uint8_t *dfs_vhtop_ch_freq_seg1, + uint8_t *dfs_vhtop_ch_freq_seg2, + uint16_t *dfs_ch_mhz_freq_seg1, + uint16_t *dfs_ch_mhz_freq_seg2); +#endif QDF_STATUS (*mlme_set_no_chans_available)(struct wlan_objmgr_pdev *pdev, int val); QDF_STATUS (*mlme_ieee2mhz)(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag, int *freq); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_find_dot11_channel)(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint8_t des_cfreq2, @@ -111,7 +155,22 @@ struct dfs_to_mlme { uint8_t *dfs_ch_ieee, uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2); - +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS (*mlme_find_dot11_chan_for_freq)(struct wlan_objmgr_pdev *, + uint16_t freq, + uint16_t des_cfreq2_mhz, + int mode, + uint16_t *dfs_ch_freq, + uint64_t *dfs_ch_flags, + uint16_t *dfs_ch_flagext, + uint8_t *dfs_ch_ieee, + uint8_t *dfs_ch_freq_seg1, + uint8_t *dfs_ch_freq_seg2, + uint16_t *dfs_cfreq1_mhz, + uint16_t *dfs_cfreq2_mhz); +#endif +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_get_dfs_ch_channels)(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -120,14 +179,37 @@ struct dfs_to_mlme { uint8_t *dfs_ch_vhtop_ch_freq_seg1, uint8_t *dfs_ch_vhtop_ch_freq_seg2, int index); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS (*mlme_get_dfs_channels_for_freq)( + struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_ch_freq_seg1, + uint8_t *dfs_chan_vhtop_ch_freq_seg2, + uint16_t *dfs_chan_mhz_freq_seg1, + uint16_t *dfs_chan_mhz_freq_seg2, + int index); +#endif QDF_STATUS (*mlme_dfs_ch_flags_ext)(struct wlan_objmgr_pdev *pdev, uint16_t *flag_ext); QDF_STATUS (*mlme_channel_change_by_precac)( struct wlan_objmgr_pdev *pdev); #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT - QDF_STATUS (*mlme_precac_chan_change_csa)(struct wlan_objmgr_pdev *pdev, - uint8_t des_chan, - enum wlan_phymode des_mode); +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS + (*mlme_precac_chan_change_csa_for_freq)(struct wlan_objmgr_pdev *, + uint16_t des_chan_freq, + enum wlan_phymode des_mode); +#endif +#ifdef CONFIG_CHAN_NUM_API + QDF_STATUS + (*mlme_precac_chan_change_csa)(struct wlan_objmgr_pdev *, + uint8_t des_chan, + enum wlan_phymode des_mode); +#endif #endif QDF_STATUS (*mlme_nol_timeout_notification)( struct wlan_objmgr_pdev *pdev); @@ -135,17 +217,27 @@ struct dfs_to_mlme { void *nollist, int nentries); bool (*mlme_is_opmode_sta)(struct wlan_objmgr_pdev *pdev); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*mlme_get_cac_timeout)(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint8_t c_vhtop_ch_freq_seg2, uint64_t dfs_ch_flags, int *cac_timeout); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS + (*mlme_get_cac_timeout_for_freq)(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_ch_freq, + uint16_t c_vhtop_ch_freq_seg2, + uint64_t dfs_ch_flags, + int *cac_timeout); +#endif QDF_STATUS (*mlme_rebuild_chan_list_with_non_dfs_channels) (struct wlan_objmgr_pdev *pdev); QDF_STATUS (*mlme_restart_vaps_with_non_dfs_chan) (struct wlan_objmgr_pdev *pdev, int no_chans_avail); bool (*mlme_check_allowed_prim_chanlist) - (struct wlan_objmgr_pdev *pdev, uint32_t chan_num); + (struct wlan_objmgr_pdev *pdev, uint32_t chan); QDF_STATUS (*mlme_update_scan_channel_list) (struct wlan_objmgr_pdev *pdev); QDF_STATUS (*mlme_bringdown_vaps) @@ -154,6 +246,10 @@ struct dfs_to_mlme { (struct wlan_objmgr_pdev *pdev, uint16_t freq, enum WLAN_DFS_EVENTS event); + void (*mlme_acquire_radar_mode_switch_lock) + (struct wlan_objmgr_pdev *pdev); + void (*mlme_release_radar_mode_switch_lock) + (struct wlan_objmgr_pdev *pdev); }; extern struct dfs_to_mlme global_dfs_to_mlme; @@ -240,7 +336,7 @@ QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev, /** * ucfg_dfs_set_precac_enable() - Set precac enable flag. * @pdev: Pointer to DFS pdev object. - * @value: input value for dfs_precac_enable flag. + * @value: input value for dfs_legacy_precac_ucfg flag. * * Wrapper function for dfs_set_precac_enable(). * This function called from outside of dfs component. @@ -249,14 +345,31 @@ QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev, uint32_t value); /** - * ucfg_dfs_get_precac_enable() - Get precac enable flag. + * ucfg_dfs_get_legacy_precac_enable() - Get the legacy precac enable flag. * @pdev: Pointer to DFS pdev object. * @buff: Pointer to save precac_enable value. * - * Wrapper function for dfs_get_precac_enable(). + * Wrapper function for dfs_is_legacy_precac_enabled() and returns the + * legacy precac enable flag for partial offload chipsets. + * This function called from outside of dfs component. + */ +QDF_STATUS ucfg_dfs_get_legacy_precac_enable(struct wlan_objmgr_pdev *pdev, + bool *buff); + +/** + * ucfg_dfs_get_agile_precac_enable() - Get agile precac enable flag. + * @pdev: Pointer to DFS pdev object. + * @buff: Pointer to save dfs_agile_precac_ucfg value. + * + * Wrapper function for dfs_is_legacy_precac_enabled(). * This function called from outside of dfs component. + * + * Return: + * * QDF_STATUS_SUCCESS: Successfully able to get agile precac flag. + * * QDF_STATUS_E_FAILURE: Failed to get agile precac flag. */ -QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, int *buff); +QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev, + bool *buff); #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT /** @@ -299,11 +412,32 @@ QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev, * * Return: Precac state of the given channel. */ +#ifdef CONFIG_CHAN_NUM_API enum precac_chan_state ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev, uint8_t precac_chan); #endif +/** + * ucfg_dfs_get_precac_chan_state_for_freq() - Get precac status for the + * given channel. + * @pdev: Pointer to DFS pdev object. + * @precac_chan: Channel frequency for which precac state needs to be + * determined. + * + * Wrapper function for dfs_get_precac_chan_state(). + * This function called from outside of dfs component. + * + * Return: Precac state of the given channel. + */ +#ifdef CONFIG_CHAN_FREQ_API +enum precac_chan_state +ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t precac_freq); +#endif + +#endif + #ifdef QCA_MCL_DFS_SUPPORT /** * ucfg_dfs_update_config() - Update DFS user config. @@ -345,6 +479,46 @@ QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, } #endif +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +/** + * ucfg_dfs_allow_hw_pulses() - Set or unset dfs-allow_hw_pulses + * which isolates synthetic radar pulse detection from actual radar detection. + * @pdev: Pointer to DFS pdev object. + * @allow_hw_pulses: Allow synthetic pulse detection true/false. + * + * Wrapper function for dfs_set_allow_hw_pulses(). + * This function called from outside of dfs component. + * + * Return: void + */ +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses); + +/** + * ucfg_dfs_is_hw_pulses_allowed() - Check if actual radar detection is allowed + * or synthetic pulse detection is enabled. + * @pdev: Pointer to DFS pdev object. + * + * Wrapper function for dfs_is_hw_pulses_allowed(). + * This function called from outside of dfs component. + * + * Return: bool + */ +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev); +#else +static inline +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses) +{ +} + +static inline +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev) +{ + return true; +} +#endif + /** * ucfg_dfs_get_override_status_timeout() - Get the value of host dfs status * wait timeout. @@ -394,4 +568,32 @@ QDF_STATUS ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev, bool *nol_subchannel_marking); +/** + * ucfg_dfs_reinit_timers() - Init DFS timers. + * @pdev: Pointer to wlan_objmgr_pdev structure. + * + * Wrapper function to reset CAC, NOL, DFS Test Timer and ZeroCAC Timer. + * This is invoked per pdev to reinitialize timers after HW Mode Switch is + * triggered. + */ +QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_dfs_reset_agile_config() - Reset ADFS config. + * @pdev: Pointer to wlan_objmgr_pdev structure. + * + * Wrapper function to reset Agile DFS config such as the variables which hold + * information about the state of the preCAC timer, active precac + * dfs index and OCAC status. It is invoked before HW Mode switch is triggered + * to ensure ADFS config is in a well known consistent state. + */ +#ifdef QCA_SUPPORT_AGILE_DFS +QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc + *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_UCFG_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index f1950749ae47ff8b815f7e48c9a2d598bae3c661..d074bb68831643515833053428db234841fe4033 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -93,10 +93,26 @@ extern struct dfs_to_mlme global_dfs_to_mlme; * Wrapper function for dfs_cac_valid_reset(). This function called from * outside of DFS component. */ - +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, uint8_t prevchan_ieee, uint32_t prevchan_flags); +#endif + +/** + * utils_dfs_cac_valid_reset_for_freq() - Cancels the dfs_cac_valid_timer timer. + * @pdev: Pointer to DFS pdev object. + * @prevchan_freq: Prevchan frequency. + * @prevchan_flags: Prevchan flags. + * + * Wrapper function for dfs_cac_valid_reset_for_freq(). This function called + * from outside of DFS component. + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t prevchan_freq, + uint32_t prevchan_flags); +#endif /** * utils_dfs_reset() - Reset DFS members. @@ -116,8 +132,7 @@ QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev); bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq); /** - * utils_dfs_reset_precaclists() - Clears and initiakizes precac_required_list, - * precac_done_list and precac_nol_list. + * utils_dfs_reset_precaclists() - Clears and initializes precac_list. * @pdev: Pointer to DFS pdev object. * * Wrapper function for dfs_reset_precaclists(). This function called from @@ -126,42 +141,28 @@ bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq); QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev); /** - * utils_dfs_reset_etsi_precaclists() - Clears and initializes etsi - * precac_required_list, - * etsi precac_done_list and - * etsi precac_nol_list. + * utils_dfs_unmark_precac_nol() - Clears precac channel marked as NOL. * @pdev: Pointer to DFS pdev object. + * @chan: channel to be unmarked as NOL. * - * Wrapper function for dfs_reset_etsiprecaclists(). This function called from - * outside of DFS component. + * Return void. */ -#ifdef QCA_SUPPORT_ETSI_PRECAC_DFS -QDF_STATUS utils_dfs_reset_etsi_precaclists(struct wlan_objmgr_pdev *pdev); -#else -static inline QDF_STATUS utils_dfs_reset_etsi_precaclists( - struct wlan_objmgr_pdev *pdev) -{ - return QDF_STATUS_SUCCESS; -} +#ifdef CONFIG_CHAN_NUM_API +void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan); #endif -/** utils_dfs_add_to_etsi_precac_required_list() - Add channel to ETSI PreCAC - * Required list. +/** + * utils_dfs_unmark_precac_nol_for_freq() - Clears precac channel marked as NOL. * @pdev: Pointer to DFS pdev object. - * @chan: Pointer to channel to be added to ETSI PreCAC Required List. + * @chan_freq: channel freq to be unmarked as NOL. * - * Return: void + * Return void. */ -#ifdef QCA_SUPPORT_ETSI_PRECAC_DFS -void utils_dfs_add_to_etsi_precac_required_list(struct wlan_objmgr_pdev *pdev, - uint8_t *chan); -#else -static inline void -utils_dfs_add_to_etsi_precac_required_list(struct wlan_objmgr_pdev *pdev, - uint8_t *chan) -{ -} +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t chan_freq); #endif + /** * utils_dfs_cancel_precac_timer() - Cancel the precac timer. * @pdev: Pointer to DFS pdev object. @@ -196,12 +197,32 @@ QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev); * * Return: True if intermediate channel needs to configure. False otherwise. */ +#ifdef CONFIG_CHAN_NUM_API bool utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, uint8_t *ch_ieee, enum wlan_phymode mode); #endif +/** + * utils_dfs_precac_decide_pref_chan() - Choose preferred channel + * @pdev: Pointer to DFS pdev object. + * @ch_freq: Pointer to channel frequency. + * @mode: Configured PHY mode. + * + * Wrapper function for dfs_decide_precac_preferred_chan(). This + * function called from outside of dfs component. + * + * Return: True if intermediate channel needs to configure. False otherwise. + */ +#ifdef CONFIG_CHAN_FREQ_API +bool +utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *ch_freq, + enum wlan_phymode mode); +#endif +#endif + /** * utils_dfs_cancel_cac_timer() - Cancels the CAC timer. * @pdev: Pointer to DFS pdev object. @@ -443,10 +464,80 @@ QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev, * * Return: QDF_STATUS */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_get_random_channel(struct wlan_objmgr_pdev *pdev, uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode, uint8_t *target_chan, struct dfs_acs_info *acs_info); +#endif + +/** + * utils_dfs_get_random_channel_for_freq() - Get random channel. + * @pdev: Pointer to DFS pdev object. + * @flags: random channel selection flags. + * @ch_params: current channel params. + * @hw_mode: current operating mode. + * @target_chan: Pointer to target_chan freq. + * @acs_info: acs range info. + * + * wrapper function for get_random_chan(). this + * function called from outside of dfs component. + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +utils_dfs_get_random_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t flags, + struct ch_params *ch_params, + uint32_t *hw_mode, uint16_t *target_chan, + struct dfs_acs_info *acs_info); +#endif + +/** + * utils_dfs_get_vdev_random_channel() - Get random channel for vdev + * @pdev: Pointer to DFS pdev object. + * @vdev: vdev of the request + * @flags: random channel selection flags. + * @ch_params: current channel params. + * @hw_mode: current operating mode. + * @target_chan: Pointer to target_chan. + * @acs_info: acs range info. + * + * Get random channel based on vdev interface type. If the vdev is null, + * the function will get random channel by SAP interface type. + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_NUM_API +QDF_STATUS utils_dfs_get_vdev_random_channel( + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode, + uint8_t *target_chan, struct dfs_acs_info *acs_info); +#endif + +/** + * utils_dfs_get_vdev_random_channel() - Get random channel for vdev + * @pdev: Pointer to DFS pdev object. + * @vdev: vdev of the request + * @flags: random channel selection flags. + * @ch_params: current channel params. + * @hw_mode: current operating mode. + * @target_chan: Pointer to target_chan_freq. + * @acs_info: acs range info. + * + * Get random channel based on vdev interface type. If the vdev is null, + * the function will get random channel by SAP interface type. + * + * Return: QDF_STATUS + */ + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq( + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode, + uint16_t *target_chan_freq, struct dfs_acs_info *acs_info); +#endif /** * utils_dfs_bw_reduced_channel() - Get BW reduced channel. @@ -460,10 +551,32 @@ QDF_STATUS utils_dfs_get_random_channel(struct wlan_objmgr_pdev *pdev, * * Return: QDF_STATUS */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_bw_reduced_channel(struct wlan_objmgr_pdev *pdev, struct ch_params *ch_params, uint32_t *hw_mode, uint8_t *target_chan); +#endif + +/** + * utils_dfs_bw_reduced_channel_for_freq() - Get BW reduced channel. + * @pdev: Pointer to DFS pdev object. + * @ch_params: current channel params. + * @hw_mode: current operating mode. + * @target_chan: Pointer to target_chan freq. + * + * wrapper function for get bw_reduced_channel. this + * function called from outside of dfs component. + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_bw_reduced_channel_for_freq(struct wlan_objmgr_pdev *pdev, + struct ch_params *ch_params, + uint32_t *hw_mode, + uint16_t *target_chan_freq); +#endif + /** * utils_dfs_init_nol() - Initialize nol from platform driver. * @pdev: pdev handler. @@ -516,17 +629,21 @@ static inline void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev) void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev); /** - * utils_is_dfs_ch() - is channel dfs. + * utils_is_dfs_chan_for_freq() - is channel dfs. * @pdev: pdev handler. + * @chan_freq: Channel frequency in MHZ. * * is channel dfs. * * Return: True if channel dfs, else false. */ -static inline bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) +#ifdef CONFIG_CHAN_FREQ_API +static inline bool utils_is_dfs_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_freq) { - return wlan_reg_is_dfs_ch(pdev, chan); + return wlan_reg_is_dfs_for_freq(pdev, chan_freq); } +#endif /** * utils_is_dfs_cfreq2_ch() - is channel dfs cfreq2. @@ -536,15 +653,7 @@ static inline bool utils_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) * * Return: True if channel dfs cfreq2, else false. */ -#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev); -#else -static inline -bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) -{ - return false; -} -#endif /** * utils_dfs_reg_update_nol_ch() - set nol channel @@ -556,11 +665,29 @@ bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) * * Return: void */ +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, bool nol_ch); +#endif +/** + * utils_dfs_reg_update_nol_chan_for_freq() - set nol channel + * + * @pdev: pdev ptr + * @ch_list: freq channel list to be returned + * @num_ch: number of channels + * @nol_ch: nol flag + * + * Return: void + */ +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *ch_list, + uint8_t num_ch, + bool nol_ch); +#endif /** * utils_dfs_freq_to_chan () - convert channel freq to channel number * @freq: frequency @@ -609,11 +736,33 @@ QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev, * * Return: QDF_STATUS */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, enum phy_ch_width ch_width, uint8_t temp_ch_lst_sz, uint8_t *temp_ch_lst); +#endif +/** + * utils_dfs_mark_leaking_chan_for_freq() - to mark channel leaking in to nol + * @pdev: Pointer to pdev structure. + * @ch_width: channel width + * @temp_ch_lst_sz: the target channel list + * @temp_ch_lst: the target frequency list + * + * This function removes the channels from temp channel list that + * (if selected as target channel) will cause leakage in one of + * the NOL channels + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev, + enum phy_ch_width ch_width, + uint8_t temp_ch_lst_sz, + uint16_t *temp_ch_lst); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline QDF_STATUS utils_dfs_mark_leaking_ch (struct wlan_objmgr_pdev *pdev, enum phy_ch_width ch_width, @@ -623,6 +772,17 @@ static inline QDF_STATUS utils_dfs_mark_leaking_ch return QDF_STATUS_SUCCESS; } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline QDF_STATUS utils_dfs_mark_leaking_chan_for_freq + (struct wlan_objmgr_pdev *pdev, + enum phy_ch_width ch_width, + uint8_t temp_ch_lst_sz, + uint16_t *temp_ch_lst) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif /** * utils_get_dfsdomain() - Get DFS domain. * @pdev: Pointer to PDEV structure. @@ -695,22 +855,63 @@ void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, * * Return: void */ +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, bool nol_history_ch); +#endif /** - * utils_dfs_check_for_cac_start() - Check for DFS CAC start conditions. + * utils_dfs_reg_update_nol_history_chan_for_freq() - set nol history channel + * + * @pdev: pdev ptr + * @ch_list: freq channel list to be returned + * @num_ch: number of channels + * @nol_history_ch: nol history flag + * + * Return: void + */ +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *, + uint16_t *freq_list, + uint8_t num_ch, + bool nol_history_ch); +#endif + +/** + * utils_dfs_is_cac_required() - Check if CAC is required on the cur_chan. + * @pdev: pdev ptr + * @cur_chan: Pointer to current channel of wlan_channel structure. + * @prev_chan: Pointer to previous channel of wlan_channel structure. + * @continue_current_cac: If AP can start CAC then this variable indicates + * whether to continue with the current CAC or restart the CAC. This variable + * is valid only if this function returns true. + * + * Return: true if AP requires CAC or can continue current CAC, else false. + */ +bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, + struct wlan_channel *cur_chan, + struct wlan_channel *prev_chan, + bool *continue_current_cac); + +/** + * utils_dfs_is_cac_required_on_dfs_curchan() - Check if CAC is required on the + * dfs_curchan. * @pdev: pdev ptr * @continue_current_cac: If AP can start CAC then this variable indicates * whether to continue with the current CAC or restart the CAC. This variable * is valid only if this function returns true. * - * Return: true if AP can start or continue the current CAC, else false. + * This API checks if the dfs_curchan is a subset of the dfs_prevchan. + * dfs_curchan and dfs_prevchan are updated after start response by + * dfs_set_current_channel(). + * + * Return: true if AP requires CAC or can continue current CAC, else false. */ -bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev, - bool *continue_current_cac); +bool +utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, + bool *continue_current_cac); /** utils_dfs_is_precac_done() - Check if precac has been done in chosen channel * @pdev: Pointer to DFS pdev object. @@ -753,8 +954,10 @@ void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq, enum WLAN_DFS_EVENTS event); /** - * utils_dfs_clear_cac_started_chan() - Clear dfs cac started channel. - * @pdev: pdev ptr + * utils_dfs_reset_dfs_prevchan() - Reset DFS previous channel structure. + * @pdev: Pointer to DFS pdev object. + * + * Return: None. */ -void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev); +void utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev *pdev); #endif /* _WLAN_DFS_UTILS_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index 90dfed33d36876f688dd1fb44f3a6a1cec74d824..db9cc0c7ab3045ab442b150e442b9caa81accb74 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -50,24 +50,57 @@ struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev) return dfs; } +/* + * register_dfs_precac_auto_chan_callbacks_freq() - Register auto chan switch + * frequency based APIs callback. + * @mlme_callback: Pointer to dfs_to_mlme. + */ #ifndef QCA_MCL_DFS_SUPPORT -#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API) static inline void -register_dfs_precac_auto_chan_callbacks(struct dfs_to_mlme *mlme_callback) +register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback) { if (!mlme_callback) return; - mlme_callback->mlme_precac_chan_change_csa = - mlme_dfs_precac_chan_change_csa; + mlme_callback->mlme_precac_chan_change_csa_for_freq = + mlme_dfs_precac_chan_change_csa_for_freq; } #else static inline void -register_dfs_precac_auto_chan_callbacks(struct dfs_to_mlme *mlme_callback) +register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback) +{ +} +#endif +#endif + +/* + * register_dfs_callbacks_for_freq() - Register dfs callbacks. + * @mlme_callback: Pointer to dfs_to_mlme. + */ +#ifndef QCA_MCL_DFS_SUPPORT +#ifdef CONFIG_CHAN_FREQ_API +static inline void +register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback) { + if (!mlme_callback) + return; + + mlme_callback->mlme_mark_dfs_for_freq = mlme_dfs_mark_dfs_for_freq; + mlme_callback->mlme_find_dot11_chan_for_freq = + mlme_dfs_find_dot11_chan_for_freq; + mlme_callback->mlme_get_dfs_channels_for_freq = + mlme_dfs_get_dfs_channels_for_freq; + mlme_callback->mlme_get_cac_timeout_for_freq = + mlme_dfs_get_cac_timeout_for_freq; + mlme_callback->mlme_get_extchan_for_freq = + mlme_dfs_get_extchan_for_freq; + mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq; } #endif +#endif +#ifndef QCA_MCL_DFS_SUPPORT void register_dfs_callbacks(void) { struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme; @@ -78,26 +111,19 @@ void register_dfs_callbacks(void) wlan_objmgr_pdev_component_obj_detach; tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa; - tmp_dfs_to_mlme->mlme_mark_dfs = mlme_dfs_mark_dfs; - tmp_dfs_to_mlme->mlme_start_csa = mlme_dfs_start_csa; tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac; tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac = mlme_dfs_deliver_event_up_after_cac; tmp_dfs_to_mlme->mlme_get_dfs_ch_nchans = mlme_dfs_get_dfs_ch_nchans; - tmp_dfs_to_mlme->mlme_get_extchan = mlme_dfs_get_extchan; tmp_dfs_to_mlme->mlme_set_no_chans_available = mlme_dfs_set_no_chans_available; tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz; - tmp_dfs_to_mlme->mlme_find_dot11_channel = mlme_dfs_find_dot11_channel; - tmp_dfs_to_mlme->mlme_get_dfs_ch_channels = - mlme_dfs_get_dfs_ch_channels; tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext; tmp_dfs_to_mlme->mlme_channel_change_by_precac = mlme_dfs_channel_change_by_precac; tmp_dfs_to_mlme->mlme_nol_timeout_notification = mlme_dfs_nol_timeout_notification; tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update; - tmp_dfs_to_mlme->mlme_get_cac_timeout = mlme_dfs_get_cac_timeout; tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels = mlme_dfs_rebuild_chan_list_with_non_dfs_channels; tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan = @@ -113,10 +139,16 @@ void register_dfs_callbacks(void) tmp_dfs_to_mlme->mlme_dfs_deliver_event = mlme_dfs_deliver_event; + tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock = + mlme_acquire_radar_mode_switch_lock; + tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock = + mlme_release_radar_mode_switch_lock; /* * Register precac auto channel switch feature related callbacks */ - register_dfs_precac_auto_chan_callbacks(tmp_dfs_to_mlme); + register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme); + /* Register freq based callbacks */ + register_dfs_callbacks_for_freq(tmp_dfs_to_mlme); } #else void register_dfs_callbacks(void) diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c index bfa0b4ee4ae961cd4b910ad681e8eb1dbb13717b..48c0bb454d06edf3d65df63f170d765ab9a44edb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -197,3 +197,20 @@ bool lmac_is_host_dfs_check_support_enabled(struct wlan_objmgr_pdev *pdev) return enabled; } #endif + +bool lmac_dfs_is_hw_mode_switch_in_progress(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; + bool is_hw_mode_switch_in_progress = false; + + psoc = wlan_pdev_get_psoc(pdev); + dfs_tx_ops = &psoc->soc_cb.tx_ops.dfs_tx_ops; + + if (dfs_tx_ops->dfs_check_mode_switch_state) + dfs_tx_ops->dfs_check_mode_switch_state( + pdev, + &is_hw_mode_switch_in_progress); + + return is_hw_mode_switch_in_progress; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c index dac0e47a06c74ee983bf48e9de35b9a2f03a5be8..54e68c6af7f254026dc8e1848b5f72a47583d8bf 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -39,6 +39,7 @@ void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev, } #ifndef QCA_MCL_DFS_SUPPORT +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint16_t freq, @@ -52,7 +53,24 @@ void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, vhtop_ch_freq_seg2, flags); } -#else +#endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_mark_dfs_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee, + uint16_t freq, + uint16_t vhtop_ch_freq_seg2, + uint64_t flags) +{ + if (global_dfs_to_mlme.mlme_mark_dfs_for_freq) + global_dfs_to_mlme.mlme_mark_dfs_for_freq(pdev, + ieee, + freq, + vhtop_ch_freq_seg2, + flags); +} +#endif +#else /* Else of ndef MCL_DFS_SUPPORT */ +#ifdef CONFIG_CHAN_NUM_API static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, void *object, void *arg) @@ -69,7 +87,33 @@ static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", vdev_id); } +#endif +/* dfs_send_radar_ind_for_freq() - Send radar found indication. + * @pdev: Pointer to wlan_objmgr_pdev. + * @object: Pointer to wlan_objmgr_vdev. + * @arg : void pointer to args. + */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_send_radar_ind_for_freq(struct wlan_objmgr_pdev *pdev, + void *object, + void *arg) +{ + struct scheduler_msg sme_msg = {0}; + uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); + + sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; + sme_msg.bodyptr = NULL; + sme_msg.bodyval = vdev_id; + scheduler_post_message(QDF_MODULE_ID_DFS, + QDF_MODULE_ID_SME, + QDF_MODULE_ID_SME, &sme_msg); + dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted", + vdev_id); +} +#endif + +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint16_t freq, @@ -92,7 +136,32 @@ void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_mark_dfs_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee, + uint16_t freq, + uint16_t vhtop_ch_freq_seg2, + uint64_t flags) +{ + struct wlan_objmgr_vdev *vdev; + + if (!pdev) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); + return; + } + + vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); + + if (vdev) { + dfs_send_radar_ind_for_freq(pdev, vdev, NULL); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); + } +} +#endif +#endif + #ifndef QCA_MCL_DFS_SUPPORT +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieee_chan, uint16_t freq, uint8_t cfreq2, uint64_t flags) @@ -101,7 +170,19 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, global_dfs_to_mlme.mlme_start_csa(pdev, ieee_chan, freq, cfreq2, flags); } +#endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee_chan, uint16_t freq, + uint16_t cfreq2, uint64_t flags) +{ + if (global_dfs_to_mlme.mlme_start_csa_for_freq) + global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan, + freq, cfreq2, flags); +} +#endif #else +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieee_chan, uint16_t freq, uint8_t cfreq2, uint64_t flags) @@ -121,6 +202,27 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, } } #endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev, + uint8_t ieee_chan, uint16_t freq, + uint16_t cfreq2, uint64_t flags) +{ + struct wlan_objmgr_vdev *vdev; + + if (!pdev) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev"); + return; + } + + vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID); + + if (vdev) { + dfs_send_radar_ind(pdev, vdev, NULL); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); + } +} +#endif +#endif #ifndef QCA_MCL_DFS_SUPPORT void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) @@ -159,6 +261,7 @@ void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev, nchans); } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -178,6 +281,33 @@ QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_FAILURE; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_ch_freq_seg1, + uint8_t *dfs_chan_vhtop_ch_freq_seg2, + uint16_t *dfs_chan_mhz_freq_seg1, + uint16_t *dfs_chan_mhz_freq_seg2) +{ + if (global_dfs_to_mlme.mlme_get_extchan_for_freq) + return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_ieee, + dfs_chan_vhtop_ch_freq_seg1, + dfs_chan_vhtop_ch_freq_seg2, + dfs_chan_mhz_freq_seg1, + dfs_chan_mhz_freq_seg2); + + return QDF_STATUS_E_FAILURE; +} +#endif void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev, int val) @@ -201,6 +331,7 @@ int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag) return freq; } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, uint8_t ieee, @@ -226,7 +357,41 @@ dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev, dfs_ch_vhtop_ch_freq_seg2); return QDF_STATUS_E_FAILURE; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + uint16_t des_cfreq2, + int mode, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flag, + uint16_t *dfs_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_cfreq1, + uint8_t *dfs_cfreq2, + uint16_t *cfreq1_mhz, + uint16_t *cfreq2_mhz) +{ + if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq) + return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev, + freq, + des_cfreq2, + mode, + dfs_chan_freq, + dfs_chan_flag, + dfs_flagext, + dfs_chan_ieee, + dfs_cfreq1, + dfs_cfreq2, + cfreq1_mhz, + cfreq2_mhz); + return QDF_STATUS_E_FAILURE; +} +#endif +#ifdef CONFIG_CHAN_NUM_API void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, uint16_t *dfs_ch_freq, uint64_t *dfs_ch_flags, @@ -246,6 +411,33 @@ void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev, dfs_ch_vhtop_ch_freq_seg2, index); } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mlme_get_dfs_channels_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *dfs_chan_freq, + uint64_t *dfs_chan_flags, + uint16_t *dfs_chan_flagext, + uint8_t *dfs_chan_ieee, + uint8_t *dfs_chan_vhtop_freq_seg1, + uint8_t *dfs_chan_vhtop_freq_seg2, + uint16_t *dfs_ch_mhz_freq_seg1, + uint16_t *dfs_ch_mhz_freq_seg2, + int index) +{ + if (global_dfs_to_mlme.mlme_get_dfs_channels_for_freq) + global_dfs_to_mlme.mlme_get_dfs_channels_for_freq(pdev, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_ieee, + dfs_chan_vhtop_freq_seg1, + dfs_chan_vhtop_freq_seg2, + dfs_ch_mhz_freq_seg1, + dfs_ch_mhz_freq_seg2, + index); +} +#endif uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev) { @@ -282,6 +474,7 @@ void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev, nentries); } +#ifdef CONFIG_CHAN_NUM_API int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint8_t dfs_ch_vhtop_ch_freq_seg2, @@ -298,6 +491,26 @@ int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, return cac_timeout; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_chan_freq, + uint16_t dfs_cfreq2, + uint64_t dfs_ch_flags) +{ + int cac_timeout = 0; + + if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq) + global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev, + dfs_chan_freq, + dfs_cfreq2, + dfs_ch_flags, + &cac_timeout); + + return cac_timeout; +} +#endif #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( @@ -323,13 +536,13 @@ void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN) bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) + uint32_t chan_freq) { if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist) return true; return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev, - chan_num); + chan_freq); } #endif @@ -354,3 +567,19 @@ bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); } + +void dfs_mlme_acquire_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) +{ + if (!global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock) + return; + + global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock(pdev); +} + +void dfs_mlme_release_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev) +{ + if (!global_dfs_to_mlme.mlme_release_radar_mode_switch_lock) + return; + + global_dfs_to_mlme.mlme_release_radar_mode_switch_lock(pdev); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index 40339b536a9fc119f5581abc8bd782a46d853e13..577976dad0eaa7359e30a4b91281fbb23cf539e9 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -71,6 +71,7 @@ bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev) return is_5ghz; } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -101,6 +102,46 @@ QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(tgt_dfs_set_current_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_set_current_channel_for_freq(dfs, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_ieee, + dfs_chan_vhtop_freq_seg1, + dfs_chan_vhtop_freq_seg2, + dfs_chan_mhz_freq_seg1, + dfs_chan_mhz_freq_seg2); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_set_current_channel_for_freq); +#endif QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev, int no_cac, uint32_t opmode, bool enable) @@ -385,26 +426,98 @@ QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev) qdf_export_symbol(tgt_dfs_agile_precac_start); #ifdef QCA_SUPPORT_AGILE_DFS +#ifdef CONFIG_CHAN_FREQ_API QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, int agile_precac_state) { struct wlan_dfs *dfs; + struct dfs_soc_priv_obj *dfs_soc; + bool is_precac_running_on_given_pdev = false; int i; + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + dfs = wlan_pdev_get_dfs_obj(pdev); if (!dfs) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); return QDF_STATUS_E_FAILURE; } - dfs->dfs_soc_obj->precac_state_started = agile_precac_state; - if (!dfs->dfs_soc_obj->precac_state_started) { - for (i = 0; i < dfs->dfs_soc_obj->num_dfs_privs; i++) - dfs->dfs_soc_obj->dfs_priv[i].agile_precac_active = 0; + dfs_soc = dfs->dfs_soc_obj; + for (i = 0; i < dfs_soc->num_dfs_privs; i++) { + if (dfs_soc->dfs_priv[i].dfs == dfs) { + /* Set the pdev state to given value. */ + dfs_soc->dfs_priv[i].agile_precac_active = + agile_precac_state; + /* If the pdev state is changed to inactive, + * reset the agile channel. + */ + if (!agile_precac_state) + dfs->dfs_agile_precac_freq_mhz = 0; + if (dfs_soc->cur_precac_dfs_index == i) + is_precac_running_on_given_pdev = true; + } } + /* If preCAC is running on this pdev and the agile_precac_state + * is set to false, set the global state in dfs_soc_obj to false. + * If this global state is not set to false, then preCAC will not be + * started the next time this pdev becomes active. + */ + if (is_precac_running_on_given_pdev && !agile_precac_state) + dfs_soc->precac_state_started = PRECAC_NOT_STARTED; + return QDF_STATUS_SUCCESS; } +#else +#ifdef CONFIG_CHAN_NUM_API +QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, + int agile_precac_state) +{ + struct wlan_dfs *dfs; + struct dfs_soc_priv_obj *dfs_soc; + bool is_precac_running_on_given_pdev = false; + int i; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_soc = dfs->dfs_soc_obj; + for (i = 0; i < dfs_soc->num_dfs_privs; i++) { + if (dfs_soc->dfs_priv[i].dfs == dfs) { + /* Set the pdev state to given value. */ + dfs_soc->dfs_priv[i].agile_precac_active = + agile_precac_state; + /* If the pdev state is changed to inactive, + * reset the agile channel. + */ + if (!agile_precac_state) + dfs->dfs_agile_precac_freq = 0; + if (dfs_soc->cur_precac_dfs_index == i) + is_precac_running_on_given_pdev = true; + } + } + + /* If preCAC is running on this pdev and the agile_precac_state + * is set to false, set the global state in dfs_soc_obj to false. + * If this global state is not set to false, then preCAC will not be + * started the next time this pdev becomes active. + */ + if (is_precac_running_on_given_pdev && !agile_precac_state) + dfs_soc->precac_state_started = PRECAC_NOT_STARTED; + + return QDF_STATUS_SUCCESS; +} +#endif +#endif + #else QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, int agile_precac_state) @@ -446,6 +559,7 @@ QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev, #endif qdf_export_symbol(tgt_dfs_ocac_complete); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -475,6 +589,41 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(tgt_dfs_find_vht80_chan_for_precac); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_find_vht80_precac_chan_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_mode, + uint16_t chan_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_find_vht80_chan_for_precac_for_freq(dfs, + chan_mode, + chan_freq_seg1_mhz, + cfreq1, + cfreq2, + phy_mode, + dfs_set_cfreq2, + set_agile); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_find_vht80_precac_chan_freq); +#endif QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev, struct radar_found_info *radar_found) @@ -774,3 +923,123 @@ bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev) return dfs->dfs_is_stadfs_enabled; } + +#ifdef QCA_SUPPORT_AGILE_DFS +void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_set_fw_adfs_support(dfs, + fw_adfs_support_160, + fw_adfs_support_non_160); +} + +qdf_export_symbol(tgt_dfs_set_fw_adfs_support); +#endif + +void tgt_dfs_init_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev, + uint8_t num_radios) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_init_tmp_psoc_nol(dfs, num_radios); +} + +qdf_export_symbol(tgt_dfs_init_tmp_psoc_nol); + +void tgt_dfs_deinit_tmp_psoc_nol(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_deinit_tmp_psoc_nol(dfs); +} + +qdf_export_symbol(tgt_dfs_deinit_tmp_psoc_nol); + +void tgt_dfs_save_dfs_nol_in_psoc(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id, + uint16_t low_5ghz_freq, + uint16_t high_5ghz_freq) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_save_dfs_nol_in_psoc(dfs, pdev_id, low_5ghz_freq, high_5ghz_freq); +} + +qdf_export_symbol(tgt_dfs_save_dfs_nol_in_psoc); + +void tgt_dfs_reinit_nol_from_psoc_copy(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_reinit_nol_from_psoc_copy(dfs, pdev_id); +} + +qdf_export_symbol(tgt_dfs_reinit_nol_from_psoc_copy); + +void tgt_dfs_reinit_precac_lists(struct wlan_objmgr_pdev *src_pdev, + struct wlan_objmgr_pdev *dest_pdev, + uint16_t low_5g_freq, + uint16_t high_5g_freq) +{ + struct wlan_dfs *src_dfs, *dest_dfs; + + src_dfs = wlan_pdev_get_dfs_obj(src_pdev); + if (!src_dfs) { + dfs_err(src_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + dest_dfs = wlan_pdev_get_dfs_obj(dest_pdev); + if (!dest_dfs) { + dfs_err(dest_dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_reinit_precac_lists(src_dfs, dest_dfs, low_5g_freq, high_5g_freq); +} + +void tgt_dfs_complete_deferred_tasks(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_complete_deferred_tasks(dfs); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c index 1709fe17e23f8dbbb402818ce08c873c217b3a6d..556e304dda4138423f62e224cffdc23b3642f8ad 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -139,8 +139,8 @@ QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev, } qdf_export_symbol(ucfg_dfs_set_precac_enable); -QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, - int *buff) +QDF_STATUS ucfg_dfs_get_legacy_precac_enable(struct wlan_objmgr_pdev *pdev, + bool *buff) { struct wlan_dfs *dfs; @@ -153,11 +153,38 @@ QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_FAILURE; } - *buff = dfs_get_precac_enable(dfs); + *buff = dfs_is_legacy_precac_enabled(dfs); return QDF_STATUS_SUCCESS; } -qdf_export_symbol(ucfg_dfs_get_precac_enable); + +qdf_export_symbol(ucfg_dfs_get_legacy_precac_enable); + +QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev, + bool *buff) +{ + struct wlan_dfs *dfs; + + if (!pdev || !buff) + return QDF_STATUS_E_FAILURE; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) { + *buff = false; + return QDF_STATUS_SUCCESS; + } + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + *buff = dfs_is_agile_precac_enabled(dfs); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(ucfg_dfs_get_agile_precac_enable); QDF_STATUS ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev, @@ -222,6 +249,7 @@ QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +#ifdef CONFIG_CHAN_NUM_API enum precac_chan_state ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev, uint8_t precac_chan) @@ -236,7 +264,31 @@ ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev, } retval = dfs_get_precac_chan_state(dfs, precac_chan); - if (PRECAC_ERR == retval) { + if (retval == PRECAC_ERR) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Could not find precac channel state"); + } + + return retval; +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +enum precac_chan_state +ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t precac_chan_freq) +{ + struct wlan_dfs *dfs; + enum precac_chan_state retval = PRECAC_ERR; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return PRECAC_ERR; + } + + retval = dfs_get_precac_chan_state_for_freq(dfs, precac_chan_freq); + if (retval == PRECAC_ERR) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Could not find precac channel state"); } @@ -244,6 +296,7 @@ ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev, return retval; } #endif +#endif #ifdef QCA_MCL_DFS_SUPPORT QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc, @@ -310,3 +363,88 @@ QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, qdf_export_symbol(ucfg_dfs_get_override_status_timeout); #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR) +void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_allow_hw_pulses(dfs, allow_hw_pulses); +} + +qdf_export_symbol(ucfg_dfs_allow_hw_pulses); + +bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return false; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + return dfs_is_hw_pulses_allowed(dfs); +} + +qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed); +#endif + +#ifdef QCA_SUPPORT_AGILE_DFS +QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc) +{ + struct dfs_soc_priv_obj *soc_obj; + + if (!psoc) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); + return QDF_STATUS_E_FAILURE; + } + + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_DFS); + if (!soc_obj) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, + "Failed to get dfs psoc component"); + return QDF_STATUS_E_FAILURE; + } + + dfs_reset_agile_config(soc_obj); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(ucfg_dfs_reset_agile_config); +#endif + +QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_reinit_timers(dfs); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(ucfg_dfs_reinit_timers); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 0ba8a971afc79e9887c3ad847f80c57399956c30..c47703619671fb08488b9820739641623d7cdad6 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -27,7 +27,6 @@ #include "wlan_dfs_mlme_api.h" #include "../../core/src/dfs.h" #include "../../core/src/dfs_zero_cac.h" -#include "../../core/src/dfs_etsi_precac.h" #include #include "../../core/src/dfs_random_chan_sel.h" #ifdef QCA_DFS_USE_POLICY_MANAGER @@ -54,7 +53,6 @@ QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev) dfs_reset(dfs); dfs_nol_update(dfs); dfs_reset_precaclists(dfs); - dfs_reset_etsiprecaclists(dfs); return QDF_STATUS_SUCCESS; } @@ -70,6 +68,7 @@ bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq) return dfs_is_freq_in_nol(dfs, freq); } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, uint8_t prevchan_ieee, uint32_t prevchan_flags) @@ -85,8 +84,12 @@ QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(utils_dfs_cac_valid_reset); +#endif -QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t prevchan_freq, + uint32_t prevchan_flags) { struct wlan_dfs *dfs; @@ -94,14 +97,15 @@ QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) if (!dfs) return QDF_STATUS_E_FAILURE; - dfs_reset_precaclists(dfs); + dfs_cac_valid_reset_for_freq(dfs, prevchan_freq, prevchan_flags); return QDF_STATUS_SUCCESS; } -qdf_export_symbol(utils_dfs_reset_precaclists); -#ifdef QCA_SUPPORT_ETSI_PRECAC_DFS -QDF_STATUS utils_dfs_reset_etsi_precaclists(struct wlan_objmgr_pdev *pdev) +qdf_export_symbol(utils_dfs_cac_valid_reset_for_freq); +#endif + +QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) { struct wlan_dfs *dfs; @@ -109,15 +113,30 @@ QDF_STATUS utils_dfs_reset_etsi_precaclists(struct wlan_objmgr_pdev *pdev) if (!dfs) return QDF_STATUS_E_FAILURE; - dfs_reset_etsiprecaclists(dfs); + dfs_reset_precaclists(dfs); return QDF_STATUS_SUCCESS; } +qdf_export_symbol(utils_dfs_reset_precaclists); + +#ifdef CONFIG_CHAN_NUM_API +void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) + return; + + dfs_unmark_precac_nol(dfs, chan); +} -qdf_export_symbol(utils_dfs_reset_etsi_precaclists); +qdf_export_symbol(utils_dfs_unmark_precac_nol); +#endif -void utils_dfs_add_to_etsi_precac_required_list(struct wlan_objmgr_pdev *pdev, - uint8_t *chan) +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t chan_freq) { struct wlan_dfs *dfs; @@ -125,10 +144,10 @@ void utils_dfs_add_to_etsi_precac_required_list(struct wlan_objmgr_pdev *pdev, if (!dfs) return; - dfs_add_to_etsi_precac_required_list(dfs, chan); + dfs_unmark_precac_nol_for_freq(dfs, chan_freq); } -qdf_export_symbol(utils_dfs_add_to_etsi_precac_required_list); +qdf_export_symbol(utils_dfs_unmark_precac_nol_for_freq); #endif QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) @@ -145,6 +164,26 @@ QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_cancel_precac_timer); +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); + return QDF_STATUS_E_FAILURE; + } + + if (!dfs->dfs_precac_secondary_freq_mhz) + return QDF_STATUS_E_FAILURE; + + dfs_start_precac_timer_for_freq(dfs, + dfs->dfs_precac_secondary_freq_mhz); + return QDF_STATUS_SUCCESS; +} +#else +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) { struct wlan_dfs *dfs; @@ -161,8 +200,11 @@ QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) dfs->dfs_precac_secondary_freq); return QDF_STATUS_SUCCESS; } +#endif +#endif #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_NUM_API bool utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, uint8_t *ch_ieee, @@ -179,6 +221,23 @@ utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef CONFIG_CHAN_FREQ_API +bool +utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq, + enum wlan_phymode mode) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); + return false; + } + return dfs_decide_precac_preferred_chan_for_freq(dfs, chan_freq, mode); +} +#endif +#endif QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev) { struct wlan_dfs *dfs; @@ -220,17 +279,6 @@ QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_cac_stop); -void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev) -{ - struct wlan_dfs *dfs; - - dfs = wlan_pdev_get_dfs_obj(pdev); - if (!dfs) - return; - - dfs_clear_cac_started_chan(dfs); -} - /** dfs_fill_chan_info() - Fill the dfs channel structure with wlan * channel. * @chan: Pointer to DFS channel structure. @@ -238,6 +286,21 @@ void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev) * * Return: void */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_fill_chan_info(struct dfs_channel *chan, + struct wlan_channel *wlan_chan) +{ + chan->dfs_ch_freq = wlan_chan->ch_freq; + chan->dfs_ch_flags = wlan_chan->ch_flags; + chan->dfs_ch_flagext = wlan_chan->ch_flagext; + chan->dfs_ch_ieee = wlan_chan->ch_ieee; + chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; + chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; + chan->dfs_ch_mhz_freq_seg1 = wlan_chan->ch_cfreq1; + chan->dfs_ch_mhz_freq_seg2 = wlan_chan->ch_cfreq2; +} +#else +#ifdef CONFIG_CHAN_NUM_API static void dfs_fill_chan_info(struct dfs_channel *chan, struct wlan_channel *wlan_chan) { @@ -248,6 +311,8 @@ static void dfs_fill_chan_info(struct dfs_channel *chan, chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; } +#endif +#endif bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, struct wlan_channel *wlan_chan) @@ -264,8 +329,31 @@ bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, return dfs_is_precac_done(dfs, &chan); } -bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev, - bool *continue_current_cac) +bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, + struct wlan_channel *cur_chan, + struct wlan_channel *prev_chan, + bool *continue_current_cac) +{ + struct wlan_dfs *dfs; + struct dfs_channel cur_channel; + struct dfs_channel prev_channel; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) + return false; + + dfs_fill_chan_info(&cur_channel, cur_chan); + dfs_fill_chan_info(&prev_channel, prev_chan); + + return dfs_is_cac_required(dfs, + &cur_channel, + &prev_channel, + continue_current_cac); +} + +bool +utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, + bool *continue_current_cac) { struct wlan_dfs *dfs; @@ -273,7 +361,10 @@ bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev, if (!dfs) return false; - return dfs_check_for_cac_start(dfs, continue_current_cac); + return dfs_is_cac_required(dfs, + dfs->dfs_curchan, + dfs->dfs_prevchan, + continue_current_cac); } QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev) @@ -663,6 +754,7 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, * utils_dfs_get_channel_list() - Get channel list from regdb component, based * on current channel list. * @pdev: Pointer to pdev structure. + * @vdev: vdev of request * @chan: Pointer to channel list. * @num_chan: number of channels. * @@ -671,7 +763,74 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, * so that the random channel function does not select either 2.4GHz or 4.9GHz * channel. */ +#ifdef CONFIG_CHAN_FREQ_API static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, + struct dfs_channel *chan_list, + uint32_t *num_chan) +{ + struct dfs_channel *tmp_chan_list = NULL; + struct wlan_dfs *dfs; + bool is_curchan_5g; + bool is_curchan_24g; + bool is_curchan_49g; + uint32_t chan_num; + uint32_t center_freq; + uint16_t flagext; + int i, j = 0; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return; + } + + tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list)); + if (!tmp_chan_list) + return; + + utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan); + + chan_num = dfs->dfs_curchan->dfs_ch_ieee; + center_freq = dfs->dfs_curchan->dfs_ch_freq; + is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq); + is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq); + is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq); + + for (i = 0; i < *num_chan; i++) { + chan_num = tmp_chan_list[i].dfs_ch_ieee; + center_freq = tmp_chan_list[i].dfs_ch_freq; + flagext = tmp_chan_list[i].dfs_ch_flagext; + /* No change in prototype needed. Hence retaining same func */ + if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq)) + continue; + + if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH_FREQ(center_freq)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + chan_list[j].dfs_ch_flagext = flagext; + j++; + } else if ((is_curchan_24g) && + WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + j++; + } else if ((is_curchan_49g) && + WLAN_REG_IS_49GHZ_FREQ(center_freq)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + j++; + } + } + + *num_chan = j; + + qdf_mem_free(tmp_chan_list); +} +#else /* NUM_API */ +#ifdef CONFIG_CHAN_NUM_API +static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, struct dfs_channel *chan_list, uint32_t *num_chan) { @@ -733,6 +892,8 @@ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, qdf_mem_free(tmp_chan_list); } +#endif +#endif #else @@ -742,17 +903,19 @@ void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, utils_dfs_get_chan_list(pdev, clist, num_chan); } -void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, - void *clist, uint32_t *num_chan) +static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, + struct dfs_channel *chan_list, + uint32_t *num_chan) { - uint8_t pcl_ch[QDF_MAX_NUM_CHAN] = {0}; - uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t pcl_ch[NUM_CHANNELS] = {0}; + uint8_t weight_list[NUM_CHANNELS] = {0}; uint32_t len; uint32_t weight_len; int i; struct wlan_objmgr_psoc *psoc; uint32_t conn_count = 0; - struct dfs_channel *chan_list = (struct dfs_channel *)clist; + enum policy_mgr_con_mode mode; psoc = wlan_pdev_get_psoc(pdev); if (!psoc) { @@ -763,14 +926,21 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, len = QDF_ARRAY_SIZE(pcl_ch); weight_len = QDF_ARRAY_SIZE(weight_list); + + if (vdev) + mode = policy_mgr_convert_device_mode_to_qdf_type( + wlan_vdev_mlme_get_opmode(vdev)); + else + mode = PM_SAP_MODE; conn_count = policy_mgr_mode_specific_connection_count( - psoc, PM_SAP_MODE, NULL); + psoc, mode, NULL); if (0 == conn_count) - policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl_ch, - &len, weight_list, weight_len); + policy_mgr_get_pcl(psoc, mode, pcl_ch, + &len, weight_list, weight_len); else - policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl_ch, - &len, weight_list, weight_len, true); + policy_mgr_get_pcl_for_existing_conn( + psoc, mode, pcl_ch, &len, weight_list, + weight_len, true); if (*num_chan < len) { dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, @@ -781,29 +951,27 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, } for (i = 0; i < len; i++) { - chan_list[i].dfs_ch_ieee = pcl_ch[i]; - chan_list[i].dfs_ch_freq = - wlan_reg_chan_to_freq(pdev, pcl_ch[i]); + chan_list[i].dfs_ch_ieee = + wlan_reg_freq_to_chan(pdev, pcl_ch[i]); + chan_list[i].dfs_ch_freq = pcl_ch[i]; } *num_chan = i; dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); } -static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, - struct dfs_channel *chan_list, - uint32_t *num_chan) +void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, + void *clist, uint32_t *num_chan) { - utils_dfs_get_chan_list(pdev, (void *)chan_list, num_chan); + utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist, + num_chan); } #endif -QDF_STATUS utils_dfs_get_random_channel( - struct wlan_objmgr_pdev *pdev, - uint16_t flags, - struct ch_params *ch_params, - uint32_t *hw_mode, - uint8_t *target_chan, - struct dfs_acs_info *acs_info) +#ifdef CONFIG_CHAN_NUM_API +QDF_STATUS utils_dfs_get_vdev_random_channel( + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode, + uint8_t *target_chan, struct dfs_acs_info *acs_info) { uint32_t dfs_reg; uint32_t num_chan = NUM_CHANNELS; @@ -831,7 +999,7 @@ QDF_STATUS utils_dfs_get_random_channel( if (!chan_list) goto random_chan_error; - utils_dfs_get_channel_list(pdev, chan_list, &num_chan); + utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan); if (!num_chan) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); goto random_chan_error; @@ -870,8 +1038,125 @@ QDF_STATUS utils_dfs_get_random_channel( return status; } + +qdf_export_symbol(utils_dfs_get_vdev_random_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq( + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode, + uint16_t *target_chan_freq, struct dfs_acs_info *acs_info) +{ + uint32_t dfs_reg; + uint32_t num_chan = NUM_CHANNELS; + struct wlan_dfs *dfs = NULL; + struct wlan_objmgr_psoc *psoc; + struct dfs_channel *chan_list = NULL; + struct dfs_channel cur_chan; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + *target_chan_freq = 0; + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); + goto random_chan_error; + } + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + goto random_chan_error; + } + + wlan_reg_get_dfs_region(pdev, &dfs_reg); + chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); + if (!chan_list) + goto random_chan_error; + + utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan); + if (!num_chan) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); + goto random_chan_error; + } + + cur_chan.dfs_ch_vhtop_ch_freq_seg1 = chan_params->center_freq_seg0; + cur_chan.dfs_ch_vhtop_ch_freq_seg2 = chan_params->center_freq_seg1; + cur_chan.dfs_ch_mhz_freq_seg1 = chan_params->mhz_freq_seg0; + cur_chan.dfs_ch_mhz_freq_seg2 = chan_params->mhz_freq_seg1; + + if (!chan_params->ch_width) + utils_dfs_get_max_sup_width(pdev, + (uint8_t *)&chan_params->ch_width); + + *target_chan_freq = dfs_prepare_random_channel_for_freq(dfs, chan_list, + num_chan, flags, (uint8_t *)&chan_params->ch_width, + &cur_chan, (uint8_t)dfs_reg, acs_info); + + chan_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1; + chan_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2; + chan_params->mhz_freq_seg0 = cur_chan.dfs_ch_mhz_freq_seg1; + chan_params->mhz_freq_seg1 = cur_chan.dfs_ch_mhz_freq_seg2; + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "input width=%d", chan_params->ch_width); + + if (*target_chan_freq) { + wlan_reg_set_channel_params_for_freq(pdev, *target_chan_freq, 0, + chan_params); + utils_dfs_get_max_phy_mode(pdev, hw_mode); + status = QDF_STATUS_SUCCESS; + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "ch=%d, seg0=%d, seg1=%d, width=%d", + *target_chan_freq, chan_params->center_freq_seg0, + chan_params->center_freq_seg1, chan_params->ch_width); + +random_chan_error: + qdf_mem_free(chan_list); + + return status; +} + +qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API +QDF_STATUS utils_dfs_get_random_channel( + struct wlan_objmgr_pdev *pdev, + uint16_t flags, + struct ch_params *ch_params, + uint32_t *hw_mode, + uint8_t *target_chan, + struct dfs_acs_info *acs_info) +{ + return utils_dfs_get_vdev_random_channel( + pdev, NULL, flags, ch_params, hw_mode, target_chan, + acs_info); +} qdf_export_symbol(utils_dfs_get_random_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_get_random_channel_for_freq( + struct wlan_objmgr_pdev *pdev, + uint16_t flags, + struct ch_params *ch_params, + uint32_t *hw_mode, + uint16_t *target_chan_freq, + struct dfs_acs_info *acs_info) +{ + return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags, + ch_params, hw_mode, + target_chan_freq, + acs_info); +} +qdf_export_symbol(utils_dfs_get_random_channel_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_bw_reduced_channel( struct wlan_objmgr_pdev *pdev, struct ch_params *ch_params, @@ -919,6 +1204,60 @@ QDF_STATUS utils_dfs_bw_reduced_channel( } qdf_export_symbol(utils_dfs_bw_reduced_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_bw_reduced_channel_for_freq( + struct wlan_objmgr_pdev *pdev, + struct ch_params *chan_params, + uint32_t *hw_mode, + uint16_t *target_chan_freq) +{ + struct wlan_dfs *dfs = NULL; + struct wlan_objmgr_psoc *psoc; + enum channel_state ch_state; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct dfs_channel *dfs_curchan; + + *target_chan_freq = 0; + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); + return status; + } + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return status; + } + dfs_curchan = dfs->dfs_curchan; + ch_state = + wlan_reg_get_channel_state_for_freq(pdev, + dfs_curchan->dfs_ch_freq); + + if (ch_state == CHANNEL_STATE_DFS || + ch_state == CHANNEL_STATE_ENABLE) { + chan_params->mhz_freq_seg0 = + dfs_curchan->dfs_ch_mhz_freq_seg1; + chan_params->mhz_freq_seg1 = + dfs_curchan->dfs_ch_mhz_freq_seg2; + wlan_reg_set_channel_params_for_freq(pdev, + dfs_curchan->dfs_ch_freq, + 0, chan_params); + + *target_chan_freq = dfs_curchan->dfs_ch_freq; + utils_dfs_get_max_phy_mode(pdev, hw_mode); + + return QDF_STATUS_SUCCESS; + } + + return status; +} + +qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq); +#endif + #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev) @@ -1053,6 +1392,7 @@ void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_clear_nol_channels); +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, @@ -1062,7 +1402,21 @@ void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch); } qdf_export_symbol(utils_dfs_reg_update_nol_ch); +#endif +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *freq_list, + uint8_t num_chan, + bool nol_chan) +{ + wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan); +} + +qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, @@ -1070,6 +1424,19 @@ void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, { wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch); } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void +utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *freq_list, + uint8_t num_chan, + bool nol_history_chan) +{ + wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan, + nol_history_chan); +} +#endif uint8_t utils_dfs_freq_to_chan(uint32_t freq) { @@ -1112,6 +1479,7 @@ uint32_t utils_dfs_chan_to_freq(uint8_t chan) qdf_export_symbol(utils_dfs_chan_to_freq); #ifdef QCA_MCL_DFS_SUPPORT +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, enum phy_ch_width ch_width, uint8_t temp_ch_lst_sz, @@ -1130,6 +1498,27 @@ QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, qdf_export_symbol(utils_dfs_mark_leaking_ch); #endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + struct wlan_dfs *dfs = NULL; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz, + temp_freq_lst); +} +qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq); +#endif +#endif + int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev) { enum dfs_reg dfsdomain; @@ -1197,6 +1586,7 @@ QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev, } qdf_export_symbol(utils_dfs_get_disable_radar_marking); +#endif bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) { @@ -1210,7 +1600,6 @@ bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_is_dfs_cfreq2_ch); -#endif void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq, enum WLAN_DFS_EVENTS event) @@ -1218,3 +1607,19 @@ void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq, if (global_dfs_to_mlme.mlme_dfs_deliver_event) global_dfs_to_mlme.mlme_dfs_deliver_event(pdev, freq, event); } + +void utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null"); + return; + } + + dfs_reset_dfs_prevchan(dfs); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index bb83c9f385f3df48ba489b3c7139983736ec2d51..2f2b0150505d022e57086255191fa19efe64ff58 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -20,7 +20,6 @@ #ifndef _WLAN_LMAC_IF_DEF_H_ #define _WLAN_LMAC_IF_DEF_H_ -#include #include "qdf_status.h" #include "wlan_objmgr_cmn.h" #ifdef DFS_COMPONENT_ENABLE @@ -80,10 +79,8 @@ struct dbr_module_config; #include #endif /* QCA_SUPPORT_CP_STATS */ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include #include -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ #ifdef QCA_SUPPORT_CP_STATS /** @@ -182,18 +179,12 @@ struct wlan_lmac_if_ftm_tx_ops { uint8_t *buf, uint32_t len, uint8_t mac_id); }; - +enum wlan_mlme_cfg_id; /** * struct wlan_lmac_if_mlme_tx_ops - south bound tx function pointers for mlme - * @scan_sta_power_events: function to handle STA power events - * @scan_connection_lost: function to get scan connection lost - * @scan_end: function to end scan * @get_wifi_iface_id: function to get wifi interface id * @vdev_mlme_attach: function to register events * @vdev_mlme_detach: function to unregister events - * @vdev_mgr_rsp_timer_init: function to initialize vdev response timer - * @vdev_mgr_rsp_timer_mod: function to timer_mod vdev response timer - * @vdev_mgr_rsp_timer_stop: function to stop vdev response timer * @vdev_create_send: function to send vdev create * @vdev_start_send: function to send vdev start * @vdev_up_send: function to send vdev up @@ -201,6 +192,7 @@ struct wlan_lmac_if_ftm_tx_ops { * @vdev_stop_send: function to send vdev stop * @vdev_down_send: function to send vdev down * @vdev_set_param_send: function to send vdev parameter + * @vdev_set_tx_rx_decap_type: function to send vdev tx rx cap/decap type * @vdev_set_nac_rssi_send: function to send nac rssi * @vdev_set_neighbour_rx_cmd_send: function to send vdev neighbour rx cmd * @vdev_sifs_trigger_send: function to send vdev sifs trigger @@ -212,28 +204,19 @@ struct wlan_lmac_if_ftm_tx_ops { * @beacon_tmpl_send: function to send beacon template * @vdev_bcn_miss_offload_send: function to send beacon miss offload * @vdev_sta_ps_param_send: function to sent STA power save config - * @target_is_pre_lithium: function to get target type status + * @peer_delete_all_send: function to send vdev delete all peer request + * @psoc_vdev_rsp_timer_init: function to initialize psoc vdev response timer + * @psoc_vdev_rsp_timer_deinit: function to deinitialize psoc vdev rsp timer + * @psoc_vdev_rsp_timer_inuse: function to determine whether the vdev rsp + * timer is inuse or not + * @psoc_vdev_rsp_timer_mod: function to modify the time of vdev rsp timer + * @psoc_wake_lock_init: Initialize psoc wake lock for vdev response timer + * @psoc_wake_lock_deinit: De-Initialize psoc wake lock for vdev response timer */ struct wlan_lmac_if_mlme_tx_ops { - void (*scan_sta_power_events)(struct wlan_objmgr_pdev *pdev, - int event_type, int event_status); - void (*scan_connection_lost)(struct wlan_objmgr_pdev *pdev); - void (*scan_end)(struct wlan_objmgr_pdev *pdev); uint32_t (*get_wifi_iface_id) (struct wlan_objmgr_pdev *pdev); QDF_STATUS (*vdev_mlme_attach)(struct wlan_objmgr_psoc *psoc); QDF_STATUS (*vdev_mlme_detach)(struct wlan_objmgr_psoc *psoc); -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE - QDF_STATUS (*vdev_mgr_rsp_timer_init)( - struct wlan_objmgr_vdev *vdev, - qdf_timer_t *rsp_timer); - QDF_STATUS (*vdev_mgr_rsp_timer_mod)( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - int mseconds); - QDF_STATUS (*vdev_mgr_rsp_timer_stop)( - struct wlan_objmgr_vdev *vdev, - struct vdev_response_timer *vdev_rsp, - uint8_t clear_bit); QDF_STATUS (*vdev_create_send)(struct wlan_objmgr_vdev *vdev, struct vdev_create_params *param); QDF_STATUS (*vdev_start_send)(struct wlan_objmgr_vdev *vdev, @@ -248,6 +231,9 @@ struct wlan_lmac_if_mlme_tx_ops { struct vdev_down_params *param); QDF_STATUS (*vdev_set_param_send)(struct wlan_objmgr_vdev *vdev, struct vdev_set_params *param); + QDF_STATUS (*vdev_set_tx_rx_decap_type)(struct wlan_objmgr_vdev *vdev, + enum wlan_mlme_cfg_id param_id, + uint32_t value); QDF_STATUS (*vdev_set_nac_rssi_send)( struct wlan_objmgr_vdev *vdev, struct vdev_scan_nac_rssi_params *param); @@ -274,10 +260,37 @@ struct wlan_lmac_if_mlme_tx_ops { struct beacon_params *param); QDF_STATUS (*beacon_tmpl_send)(struct wlan_objmgr_vdev *vdev, struct beacon_tmpl_params *param); +#if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) + QDF_STATUS (*vdev_fils_enable_send)(struct wlan_objmgr_vdev *vdev, + struct config_fils_params *param); +#endif QDF_STATUS (*vdev_bcn_miss_offload_send)(struct wlan_objmgr_vdev *vdev); QDF_STATUS (*vdev_sta_ps_param_send)(struct wlan_objmgr_vdev *vdev, struct sta_ps_params *param); -#endif + QDF_STATUS (*peer_delete_all_send)( + struct wlan_objmgr_vdev *vdev, + struct peer_delete_all_params *param); + QDF_STATUS (*psoc_vdev_rsp_timer_init)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + void (*psoc_vdev_rsp_timer_deinit)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + QDF_STATUS (*psoc_vdev_rsp_timer_inuse)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + QDF_STATUS (*psoc_vdev_rsp_timer_mod)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + int mseconds); + void (*psoc_wake_lock_init)( + struct wlan_objmgr_psoc *psoc); + void (*psoc_wake_lock_deinit)( + struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*vdev_mgr_rsp_timer_stop)( + struct wlan_objmgr_psoc *psoc, + struct vdev_response_timer *vdev_rsp, + enum wlan_vdev_mgr_tgt_if_rsp_bit clear_bit); }; /** @@ -427,12 +440,15 @@ struct wlan_lmac_if_atf_tx_ops { * @fd_vdev_config_fils: Enable and configure FILS Discovery * @fd_register_event_handler: Register swfda WMI event handler * @fd_unregister_event_handler: Un-register swfda WMI event handler + * @fd_offload_tmpl_send: Send FD template to FW */ struct wlan_lmac_if_fd_tx_ops { QDF_STATUS (*fd_vdev_config_fils)(struct wlan_objmgr_vdev *vdev, uint32_t fd_period); void (*fd_register_event_handler)(struct wlan_objmgr_psoc *psoc); void (*fd_unregister_event_handler)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*fd_offload_tmpl_send)(struct wlan_objmgr_pdev *pdev, + struct fils_discovery_tmpl_params *fd_tmpl_param); }; #endif @@ -475,6 +491,14 @@ struct wlan_lmac_if_sa_api_tx_ops { * @cfr_enable_cfr_timer: Function to enable CFR timer * @cfr_start_capture: Function to start CFR capture * @cfr_stop_capture: Function to stop CFR capture + * @cfr_config_rcc: Function to set the Repetitive channel capture params + * @cfr_start_lut_timer: Function to start timer to flush aged-out LUT entries + * @cfr_stop_lut_timer: Function to stop timer to flush aged-out LUT entries + * @cfr_default_ta_ra_cfg: Function to configure default values for TA_RA mode + * @cfr_dump_lut_enh: Function to dump LUT entries + * @cfr_rx_tlv_process: Function to process PPDU status TLVs + * @cfr_update_global_cfg: Function to update the global config for + * a successful commit session. */ struct wlan_lmac_if_cfr_tx_ops { int (*cfr_init_pdev)(struct wlan_objmgr_psoc *psoc, @@ -488,6 +512,19 @@ struct wlan_lmac_if_cfr_tx_ops { struct cfr_capture_params *params); int (*cfr_stop_capture)(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer); +#ifdef WLAN_ENH_CFR_ENABLE + QDF_STATUS (*cfr_config_rcc)(struct wlan_objmgr_pdev *pdev, + struct cfr_rcc_param *params); + void (*cfr_start_lut_timer)(struct wlan_objmgr_pdev *pdev); + void (*cfr_stop_lut_timer)(struct wlan_objmgr_pdev *pdev); + void (*cfr_default_ta_ra_cfg)(struct cfr_rcc_param *params, + bool allvalid, uint16_t reset_cfg); + void (*cfr_dump_lut_enh)(struct wlan_objmgr_pdev *pdev); + void (*cfr_rx_tlv_process)(struct wlan_objmgr_pdev *pdev, void *nbuf); + void (*cfr_update_global_cfg)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*cfr_subscribe_ppdu_desc)(struct wlan_objmgr_pdev *pdev, + bool is_subscribe); +#endif }; #endif /* WLAN_CFR_ENABLE */ @@ -517,6 +554,12 @@ struct wmi_spectral_cmd_ops; * @sptrlto_use_nl_bcast: Get whether to use Netlink broadcast/unicast * @sptrlto_deregister_netlink_cb: De-register Spectral Netlink callbacks * @sptrlto_process_spectral_report: Process spectral report + * @sptrlto_set_dma_debug: Set DMA debug for Spectral + * @sptrlto_direct_dma_support: Whether Direct-DMA is supported on this radio + * @sptrlto_check_and_do_dbr_ring_debug: Start/Stop Spectral ring debug based + * on the previous state + * @sptrlto_check_and_do_dbr_buff_debug: Start/Stop Spectral buffer debug based + * on the previous state **/ struct wlan_lmac_if_sptrl_tx_ops { void *(*sptrlto_pdev_spectral_init)(struct wlan_objmgr_pdev *pdev); @@ -537,7 +580,8 @@ struct wlan_lmac_if_sptrl_tx_ops { enum spectral_cp_error_code *err); QDF_STATUS (*sptrlto_stop_spectral_scan) (struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode); + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); bool (*sptrlto_is_spectral_active)(struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode); bool (*sptrlto_is_spectral_enabled)(struct wlan_objmgr_pdev *pdev, @@ -562,6 +606,16 @@ struct wlan_lmac_if_sptrl_tx_ops { int (*sptrlto_process_spectral_report)( struct wlan_objmgr_pdev *pdev, void *payload); + QDF_STATUS (*sptrlto_set_dma_debug)( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); + bool (*sptrlto_direct_dma_support)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*sptrlto_check_and_do_dbr_ring_debug)( + struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*sptrlto_check_and_do_dbr_buff_debug)( + struct wlan_objmgr_pdev *pdev); + }; #endif /* WLAN_CONV_SPECTRAL_ENABLE */ @@ -570,10 +624,17 @@ struct wlan_lmac_if_sptrl_tx_ops { * struct wlan_lmac_if_wifi_pos_tx_ops - structure of firmware tx function * pointers for wifi_pos component * @data_req_tx: function pointer to send wifi_pos req to firmware + * @wifi_pos_register_events: function pointer to register wifi_pos events + * @wifi_pos_deregister_events: function pointer to deregister wifi_pos events + * @wifi_pos_get_vht_ch_width: Function pointer to get max supported bw by FW */ struct wlan_lmac_if_wifi_pos_tx_ops { - QDF_STATUS (*data_req_tx)(struct wlan_objmgr_psoc *psoc, + QDF_STATUS (*data_req_tx)(struct wlan_objmgr_pdev *pdev, struct oem_data_req *req); + QDF_STATUS (*wifi_pos_register_events)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*wifi_pos_deregister_events)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*wifi_pos_get_vht_ch_width)(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width *ch_width); }; #endif @@ -591,6 +652,10 @@ struct wlan_lmac_if_wifi_pos_tx_ops { * @direct_buf_rx_print_ring_stat: Print ring status per module per pdev * * @direct_buf_rx_get_ring_params: Get ring parameters for module_id + * @direct_buf_rx_start_ring_debug: Start DBR ring debug + * @direct_buf_rx_stop_ring_debug: Stop DBR ring debug + * @direct_buf_rx_start_buffer_poisoning: Start DBR buffer poisoning + * @direct_buf_rx_stop_buffer_poisoning: Stop DBR buffer poisoning */ struct wlan_lmac_if_direct_buf_rx_tx_ops { QDF_STATUS (*direct_buf_rx_module_register)( @@ -611,8 +676,17 @@ struct wlan_lmac_if_direct_buf_rx_tx_ops { (struct wlan_objmgr_pdev *pdev, struct module_ring_params *param, uint8_t module_id, uint8_t srng_id); + QDF_STATUS (*direct_buf_rx_start_ring_debug)( + struct wlan_objmgr_pdev *pdev, uint8_t mod_id, + uint32_t num_ring_debug_entries); + QDF_STATUS (*direct_buf_rx_stop_ring_debug)( + struct wlan_objmgr_pdev *pdev, uint8_t mod_id); + QDF_STATUS (*direct_buf_rx_start_buffer_poisoning)( + struct wlan_objmgr_pdev *pdev, uint8_t mod_id, uint32_t value); + QDF_STATUS (*direct_buf_rx_stop_buffer_poisoning)( + struct wlan_objmgr_pdev *pdev, uint8_t mod_id); }; -#endif +#endif /* DIRECT_BUF_RX_ENABLE */ #ifdef FEATURE_WLAN_TDLS /* fwd declarations for tdls tx ops */ @@ -736,6 +810,7 @@ struct wlan_lmac_if_reg_tx_ops { * @dfs_send_avg_radar_params_to_fw: Send average radar parameters to FW. * @dfs_send_usenol_pdev_param: Send usenol pdev param to FW. * @dfs_send_subchan_marking_pdev_param: Send subchan marking pdev param to FW. + * @dfs_check_mode_switch_state: Find if HW mode switch is in progress. */ struct wlan_lmac_if_dfs_tx_ops { @@ -766,8 +841,9 @@ struct wlan_lmac_if_dfs_tx_ops { QDF_STATUS (*dfs_process_emulate_bang_radar_cmd)( struct wlan_objmgr_pdev *pdev, struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test); - QDF_STATUS (*dfs_agile_ch_cfg_cmd)(struct wlan_objmgr_pdev *pdev, - uint8_t *ch_freq); + QDF_STATUS (*dfs_agile_ch_cfg_cmd)( + struct wlan_objmgr_pdev *pdev, + struct dfs_agile_cac_params *adfs_params); QDF_STATUS (*dfs_ocac_abort_cmd)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_is_pdev_5ghz)(struct wlan_objmgr_pdev *pdev, bool *is_5ghz); @@ -788,6 +864,9 @@ struct wlan_lmac_if_dfs_tx_ops { QDF_STATUS (*dfs_send_subchan_marking_pdev_param)( struct wlan_objmgr_pdev *pdev, bool subchanmark); + QDF_STATUS (*dfs_check_mode_switch_state)( + struct wlan_objmgr_pdev *pdev, + bool *is_hw_mode_switch_in_progress); }; /** @@ -797,6 +876,7 @@ struct wlan_lmac_if_dfs_tx_ops { * @tgt_is_tgt_type_ipq4019: To check IPQ4019 target type. * @tgt_is_tgt_type_qca9984: To check QCA9984 target type. * @tgt_is_tgt_type_qca9888: To check QCA9888 target type. + * @tgt_is_tgt_type_adrastea: To check QCS40X target type. * @tgt_get_tgt_type: Get target type * @tgt_get_tgt_version: Get target version * @tgt_get_tgt_revision: Get target revision @@ -806,6 +886,7 @@ struct wlan_lmac_if_target_tx_ops { bool (*tgt_is_tgt_type_ipq4019)(uint32_t); bool (*tgt_is_tgt_type_qca9984)(uint32_t); bool (*tgt_is_tgt_type_qca9888)(uint32_t); + bool (*tgt_is_tgt_type_adrastea)(uint32_t); uint32_t (*tgt_get_tgt_type)(struct wlan_objmgr_psoc *psoc); uint32_t (*tgt_get_tgt_version)(struct wlan_objmgr_psoc *psoc); uint32_t (*tgt_get_tgt_revision)(struct wlan_objmgr_psoc *psoc); @@ -843,6 +924,36 @@ struct wlan_lmac_if_green_ap_tx_ops { }; #endif +#ifdef FEATURE_COEX +struct coex_config_params; + +/** + * struct wlan_lmac_if_coex_tx_ops - south bound tx function pointers for coex + * @coex_config_send: function pointer to send coex config to fw + */ +struct wlan_lmac_if_coex_tx_ops { + QDF_STATUS (*coex_config_send)(struct wlan_objmgr_pdev *pdev, + struct coex_config_params *param); +}; +#endif + +#ifdef WLAN_FEATURE_GPIO_CFG +struct gpio_config_params; +struct gpio_output_params; + +/** + * struct wlan_lmac_if_gpio_tx_ops - south bound tx function pointers for gpio + * @set_gpio_config: function pointert to send gpio config to fw + * @set_gpio_output: function pointert to send gpio output to fw + */ +struct wlan_lmac_if_gpio_tx_ops { + QDF_STATUS (*set_gpio_config)(struct wlan_objmgr_psoc *psoc, + struct gpio_config_params *param); + QDF_STATUS (*set_gpio_output)(struct wlan_objmgr_psoc *psoc, + struct gpio_output_params *param); +}; +#endif + /** * struct wlan_lmac_if_tx_ops - south bound tx function pointers * @mgmt_txrx_tx_ops: mgmt txrx tx ops @@ -850,9 +961,11 @@ struct wlan_lmac_if_green_ap_tx_ops { * @dfs_tx_ops: dfs tx ops. * @green_ap_tx_ops: green_ap tx_ops * @cp_stats_tx_ops: cp stats tx_ops + * @coex_ops: coex tx_ops + * @gpio_ops: gpio tx_ops * * Callback function tabled to be registered with umac. - * umac will use the functional table to send events/frames to lmac/wmi + * umac will use the functional table to send events/frames to wmi */ struct wlan_lmac_if_tx_ops { @@ -921,6 +1034,14 @@ struct wlan_lmac_if_tx_ops { #endif struct wlan_lmac_if_ftm_tx_ops ftm_tx_ops; + +#ifdef FEATURE_COEX + struct wlan_lmac_if_coex_tx_ops coex_ops; +#endif + +#ifdef WLAN_FEATURE_GPIO_CFG + struct wlan_lmac_if_gpio_tx_ops gpio_ops; +#endif }; /** @@ -970,8 +1091,8 @@ struct wlan_lmac_if_reg_rx_ops { enum dfs_reg *dfs_reg); QDF_STATUS (*reg_ch_avoid_event_handler)(struct wlan_objmgr_psoc *psoc, struct ch_avoid_ind_type *ch_avoid_ind); - uint32_t (*reg_freq_to_chan)(struct wlan_objmgr_pdev *pdev, - uint32_t freq); + uint8_t (*reg_freq_to_chan)(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); QDF_STATUS (*reg_set_chan_144)(struct wlan_objmgr_pdev *pdev, bool enable_ch_144); bool (*reg_get_chan_144)(struct wlan_objmgr_pdev *pdev); @@ -981,7 +1102,13 @@ struct wlan_lmac_if_reg_rx_ops { struct cur_regdmn_info *cur_regdmn); QDF_STATUS (*reg_enable_dfs_channels)(struct wlan_objmgr_pdev *pdev, bool dfs_enable); + QDF_STATUS (*reg_modify_pdev_chan_range)(struct + wlan_objmgr_pdev *pdev); + QDF_STATUS (*reg_disable_chan_coex)(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); bool (*reg_ignore_fw_reg_offload_ind)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*reg_get_unii_5g_bitmap)(struct wlan_objmgr_pdev *pdev, + uint8_t *bitmap); }; #ifdef CONVERGED_P2P_ENABLE @@ -1133,6 +1260,7 @@ struct wlan_lmac_if_atf_rx_ops { * @fd_free: Free FD frame buffer * @fd_get_valid_fd_period: Get valid FD period * @fd_swfda_handler: SWFDA event handler + * @fd_offload: Offload FD frame */ struct wlan_lmac_if_fd_rx_ops { uint8_t (*fd_is_fils_enable)(struct wlan_objmgr_vdev *vdev); @@ -1142,6 +1270,8 @@ struct wlan_lmac_if_fd_rx_ops { uint32_t (*fd_get_valid_fd_period)(struct wlan_objmgr_vdev *vdev, uint8_t *is_modified); QDF_STATUS (*fd_swfda_handler)(struct wlan_objmgr_vdev *vdev); + QDF_STATUS (*fd_offload)(struct wlan_objmgr_vdev *vdev, + uint32_t vdev_id); }; #endif @@ -1199,11 +1329,14 @@ struct wlan_lmac_if_cfr_rx_ops { * struct wlan_lmac_if_sptrl_rx_ops - Spectral south bound Rx operations * * @sptrlro_get_target_handle: Get Spectral handle for target/LMAC private data + * @sptrlro_vdev_get_chan_freq_seg2: Get secondary 80 center frequency * @sptrlro_spectral_is_feature_disabled: Check if spectral feature is disabled */ struct wlan_lmac_if_sptrl_rx_ops { void * (*sptrlro_get_target_handle)(struct wlan_objmgr_pdev *pdev); int16_t (*sptrlro_vdev_get_chan_freq)(struct wlan_objmgr_vdev *vdev); + int16_t (*sptrlro_vdev_get_chan_freq_seg2) + (struct wlan_objmgr_vdev *vdev); enum phy_ch_width (*sptrlro_vdev_get_ch_width)( struct wlan_objmgr_vdev *vdev); int (*sptrlro_vdev_get_sec20chan_freq_mhz)( @@ -1240,7 +1373,8 @@ struct wlan_lmac_if_wifi_pos_rx_ops { * @dfs_cancel_precac_timer: Cancel the precac timer. * @dfs_override_precac_timeout: Override the default precac timeout. * @dfs_set_precac_enable: Set precac enable flag. - * @dfs_get_precac_enable: Get precac enable flag. + * @dfs_get_legacy_precac_enable: Get the precac enable flag for + * partial offload (legacy) chipsets. * @dfs_set_precac_intermediate_chan: Set intermediate channel for precac. * @dfs_get_precac_intermediate_chan: Get intermediate channel for precac. * @dfs_precac_preferred_chan: Configure preferred channel during @@ -1253,8 +1387,10 @@ struct wlan_lmac_if_wifi_pos_rx_ops { * @dfs_dfs_cac_complete_ind: Process cac complete indication. * @dfs_agile_precac_start: Initiate Agile PreCAC run. * @dfs_set_agile_precac_state: Set agile precac state. + * @dfs_reset_adfs_config: Reset agile dfs variables. * @dfs_dfs_ocac_complete_ind: Process offchan cac complete indication. * @dfs_stop: Clear dfs timers. + * @dfs_reinit_timers: Reinitialize DFS timers. * @dfs_enable_stadfs: Enable/Disable STADFS capability. * @dfs_is_stadfs_enabled: Get STADFS capability value. * @dfs_process_phyerr_filter_offload:Process radar event. @@ -1267,6 +1403,17 @@ struct wlan_lmac_if_wifi_pos_rx_ops { * timeout. * @dfs_reset_spoof_test: Checks if radar detection is enabled. * @dfs_is_disable_radar_marking_set: Check if dis_radar_marking param is set. + * @dfs_allow_hw_pulses: Set or unset dfs_allow_hw_pulses which + * allow or disallow HW pulses. + * @dfs_is_hw_pulses_allowed: Check if HW pulses are allowed or not. + * @dfs_set_fw_adfs_support: Set the agile DFS FW support in DFS. + * @dfs_reset_dfs_prevchan: Reset DFS previous channel structure. + * @dfs_init_tmp_psoc_nol: Init temporary PSOC NOL structure. + * @dfs_deinit_tmp_psoc_nol: Deinit temporary PSOC NOL structure. + * @dfs_save_dfs_nol_in_psoc: Copy DFS NOL data to the PSOC copy. + * @dfs_reinit_nol_from_psoc_copy: Reinit DFS NOL from the PSOC NOL copy. + * @dfs_reinit_precac_lists: Reinit precac lists from other pdev. + * @dfs_complete_deferred_tasks: Process mode switch completion in DFS. */ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_get_radars)(struct wlan_objmgr_pdev *pdev); @@ -1295,6 +1442,7 @@ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_is_precac_timer_running)(struct wlan_objmgr_pdev *pdev, bool *is_precac_timer_running ); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*dfs_find_vht80_chan_for_precac)(struct wlan_objmgr_pdev *pdev, uint32_t chan_mode, @@ -1304,9 +1452,23 @@ struct wlan_lmac_if_dfs_rx_ops { uint32_t *phy_mode, bool *dfs_set_cfreq2, bool *set_agile); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS + (*dfs_find_vht80_chan_for_precac_for_freq)(struct wlan_objmgr_pdev + *pdev, + uint32_t chan_mode, + uint16_t ch_freq_seg1, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile); +#endif QDF_STATUS (*dfs_agile_precac_start)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_set_agile_precac_state)(struct wlan_objmgr_pdev *pdev, int agile_precac_state); + QDF_STATUS (*dfs_reset_adfs_config)(struct wlan_objmgr_psoc *psoc); QDF_STATUS (*dfs_dfs_ocac_complete_ind)(struct wlan_objmgr_pdev *pdev, struct vdev_adfs_complete_status *ocac_st); @@ -1317,22 +1479,43 @@ struct wlan_lmac_if_dfs_rx_ops { int precac_timeout); QDF_STATUS (*dfs_set_precac_enable)(struct wlan_objmgr_pdev *pdev, uint32_t value); - QDF_STATUS (*dfs_get_precac_enable)(struct wlan_objmgr_pdev *pdev, - int *buff); + QDF_STATUS + (*dfs_get_legacy_precac_enable)(struct wlan_objmgr_pdev *pdev, + bool *buff); + QDF_STATUS (*dfs_get_agile_precac_enable)(struct wlan_objmgr_pdev *pdev, + bool *buff); #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT QDF_STATUS (*dfs_set_precac_intermediate_chan)(struct wlan_objmgr_pdev *pdev, uint32_t value); QDF_STATUS (*dfs_get_precac_intermediate_chan)(struct wlan_objmgr_pdev *pdev, int *buff); +#ifdef CONFIG_CHAN_NUM_API bool (*dfs_decide_precac_preferred_chan)(struct wlan_objmgr_pdev *pdev, uint8_t *pref_chan, enum wlan_phymode mode); +#endif +#ifdef CONFIG_CHAN_FREQ_API + bool (*dfs_decide_precac_preferred_chan_for_freq)(struct + wlan_objmgr_pdev *pdev, + uint16_t *pref_chan_freq, + enum wlan_phymode mode); +#endif + +#ifdef CONFIG_CHAN_NUM_API enum precac_chan_state (*dfs_get_precac_chan_state)(struct wlan_objmgr_pdev *pdev, uint8_t precac_chan); +#endif + +#ifdef CONFIG_CHAN_FREQ_API + enum precac_chan_state (*dfs_get_precac_chan_state_for_freq)(struct + wlan_objmgr_pdev *pdev, + uint16_t pcac_freq); +#endif #endif QDF_STATUS (*dfs_get_override_precac_timeout)( struct wlan_objmgr_pdev *pdev, int *precac_timeout); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS (*dfs_set_current_channel)(struct wlan_objmgr_pdev *pdev, uint16_t ic_freq, uint64_t ic_flags, @@ -1340,6 +1523,19 @@ struct wlan_lmac_if_dfs_rx_ops { uint8_t ic_ieee, uint8_t ic_vhtop_ch_freq_seg1, uint8_t ic_vhtop_ch_freq_seg2); +#endif +#ifdef CONFIG_CHAN_FREQ_API + QDF_STATUS + (*dfs_set_current_channel_for_freq)(struct wlan_objmgr_pdev *pdev, + uint16_t ic_freq, + uint64_t ic_flags, + uint16_t ic_flagext, + uint8_t ic_ieee, + uint8_t ic_vhtop_ch_freq_seg1, + uint8_t ic_vhtop_ch_freq_seg2, + uint16_t dfs_ch_mhz_freq_seg1, + uint16_t dfs_ch_mhz_freq_seg2); +#endif #ifdef DFS_COMPONENT_ENABLE QDF_STATUS (*dfs_process_radar_ind)(struct wlan_objmgr_pdev *pdev, struct radar_found_info *radar_found); @@ -1347,6 +1543,7 @@ struct wlan_lmac_if_dfs_rx_ops { uint32_t vdev_id); #endif QDF_STATUS (*dfs_stop)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*dfs_reinit_timers)(struct wlan_objmgr_pdev *pdev); void (*dfs_enable_stadfs)(struct wlan_objmgr_pdev *pdev, bool val); bool (*dfs_is_stadfs_enabled)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_process_phyerr_filter_offload)( @@ -1377,105 +1574,45 @@ struct wlan_lmac_if_dfs_rx_ops { bool value); QDF_STATUS (*dfs_is_bw_reduction_needed)(struct wlan_objmgr_pdev *pdev, bool *bw_reduce); + void (*dfs_allow_hw_pulses)(struct wlan_objmgr_pdev *pdev, + bool allow_hw_pulses); + bool (*dfs_is_hw_pulses_allowed)(struct wlan_objmgr_pdev *pdev); + void (*dfs_set_fw_adfs_support)(struct wlan_objmgr_pdev *pdev, + bool fw_adfs_support_160, + bool fw_adfs_support_non_160); + void (*dfs_reset_dfs_prevchan)(struct wlan_objmgr_pdev *pdev); + void (*dfs_init_tmp_psoc_nol)(struct wlan_objmgr_pdev *pdev, + uint8_t num_radios); + void (*dfs_deinit_tmp_psoc_nol)(struct wlan_objmgr_pdev *pdev); + void (*dfs_save_dfs_nol_in_psoc)(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id, + uint16_t low_5ghz_freq, + uint16_t high_5ghz_freq); + void (*dfs_reinit_nol_from_psoc_copy)(struct wlan_objmgr_pdev *pdev, + uint8_t pdev_id); + void (*dfs_reinit_precac_lists)(struct wlan_objmgr_pdev *src_pdev, + struct wlan_objmgr_pdev *dest_pdev, + uint16_t low_5g_freq, + uint16_t high_5g_freq); + void (*dfs_complete_deferred_tasks)(struct wlan_objmgr_pdev *pdev); }; /** * struct wlan_lmac_if_mlme_rx_ops: Function pointer to call MLME functions - * @wlan_mlme_scan_start: function to start scan - * @wlan_mlme_register_pm_event_handler: function to register pm event - * @wlan_mlme_unregister_pm_event_handler: function unregister for pm event - * @wlan_mlme_register_vdev_event_handler: function to register for vdev event - * @wlan_mlme_unregister_vdev_event_handler: functiont o unregister for vdev + * @vdev_mgr_start_response: function to handle start response + * @vdev_mgr_stop_response: function to handle stop response + * @vdev_mgr_delete_response: function to handle delete response + * @vdev_mgr_offload_bcn_tx_status_event_handle: function to handle offload + * beacon tx + * @vdev_mgr_tbttoffset_update_handle: function to handle tbtt offset event + * @vdev_mgr_peer_delete_all_response: function to handle vdev delete all peer * event - * @wlan_mlme_send_probe_request: function to send probe - * @wlan_mlme_resmgr_request_bsschan: function to request bsschan - * @wlan_mlme_resmgr_request_offchan: function to request offchan - * @wlan_mlme_resmgr_active: function to check resmgr status - * @wlan_mlme_get_cw_inter_found: function to get cw interference - * @wlan_mlme_set_home_channel: function to set home channel - * @wlan_mlme_set_channel: function to set channel - * @wlan_mlme_start_record_stats: functiont to start record stats - * @wlan_mlme_end_record_stats: function to end recording of stats - * @wlan_mlme_get_enh_rpt_ind: function to get enhanced repeater index - * @wlan_mlme_pause: function to pause mlme - * @wlan_mlme_unpause: function to unpause mlme - * @wlan_mlme_vdev_pause_control: function to set vdev pause control - * @wlan_mlme_sta_power_pause: function to set sta power pause - * @wlan_mlme_sta_power_unpause: function to set sta power pause - * @wlan_mlme_set_vdev_sleep: function to sleep vdev sleep - * @wlan_mlme_set_vdev_wakeup: function to set vdev wakeup - * @wlan_mlme_get_traffic_indication_timestamp: function to get tid timestamp - * @wlan_mlme_get_acs_in_progress: function to get ACS progress - * @wlan_mlme_end_scan: function to end scan - * @mlme_get_rsp_timer: function to get vdev mgr response timer - * @mlme_response_timeout_cb: function to trigger on response time expiry - * @mlme_start_response: function to handle vdev start response - * @mlme_stop_response: function to handle vdev stop response - * @mlme_offload_bcn_tx_status_event_handle: function to get offload beacon tx - * status - * @mlme_tbttoffset_update_handle: function to handle tbttoffset event + * @psoc_get_wakelock_info: function to get wakelock info + * @psoc_get_vdev_response_timer_info: function to get vdev response timer + * structure for a specific vdev id + * @vdev_mgr_multi_vdev_restart_resp: function to handle mvr response */ struct wlan_lmac_if_mlme_rx_ops { - - void (*wlan_mlme_scan_start)(struct wlan_objmgr_pdev *pdev); - void (*wlan_mlme_register_pm_event_handler)( - struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - void (*wlan_mlme_unregister_pm_event_handler)( - struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - QDF_STATUS (*wlan_mlme_register_vdev_event_handler)( - struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - QDF_STATUS (*wlan_mlme_unregister_vdev_event_handler)( - struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - int (*wlan_mlme_send_probe_request)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id, - u_int8_t *destination, - u_int8_t *bssid, - u_int8_t *ssid, - u_int32_t ssidlen, - u_int8_t *ie, - size_t len); - int (*wlan_mlme_resmgr_request_bsschan)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_resmgr_request_offchan)(struct wlan_objmgr_pdev *pdev, - u_int32_t freq, - u_int32_t flags, - u_int32_t estimated_offchannel_time); - int (*wlan_mlme_resmgr_active)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_get_cw_inter_found)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_set_home_channel)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - int (*wlan_mlme_set_channel)(struct wlan_objmgr_pdev *pdev, - u_int32_t freq, - u_int32_t flags); - void (*wlan_mlme_start_record_stats)(struct wlan_objmgr_pdev *pdev); - void (*wlan_mlme_end_record_stats)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_get_enh_rpt_ind)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_pause)(struct wlan_objmgr_pdev *pdev); - void (*wlan_mlme_unpause)(struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_vdev_pause_control)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - int (*wlan_mlme_sta_power_pause)( - struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id, - u_int32_t timeout); - int (*wlan_mlme_sta_power_unpause)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - int (*wlan_mlme_set_vdev_sleep)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - int (*wlan_mlme_set_vdev_wakeup)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - qdf_time_t (*wlan_mlme_get_traffic_indication_timestamp)( - struct wlan_objmgr_pdev *pdev); - int (*wlan_mlme_get_acs_in_progress)(struct wlan_objmgr_pdev *pdev, - uint8_t vdev_id); - void (*wlan_mlme_end_scan)(struct wlan_objmgr_pdev *pdev); - -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE - struct vdev_response_timer *(*vdev_mgr_get_response_timer_info)( - struct wlan_objmgr_vdev *vdev); QDF_STATUS (*vdev_mgr_start_response)( struct wlan_objmgr_psoc *psoc, struct vdev_start_response *rsp); @@ -1491,7 +1628,19 @@ struct wlan_lmac_if_mlme_rx_ops { QDF_STATUS (*vdev_mgr_tbttoffset_update_handle)( uint32_t num_vdevs, bool is_ext); + QDF_STATUS (*vdev_mgr_peer_delete_all_response)( + struct wlan_objmgr_psoc *psoc, + struct peer_delete_all_response *rsp); + QDF_STATUS (*vdev_mgr_multi_vdev_restart_resp)( + struct wlan_objmgr_psoc *psoc, + struct multi_vdev_restart_resp *rsp); +#ifdef FEATURE_VDEV_RSP_WAKELOCK + struct psoc_mlme_wakelock *(*psoc_get_wakelock_info)( + struct wlan_objmgr_psoc *psoc); #endif + struct vdev_response_timer *(*psoc_get_vdev_response_timer_info)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); }; #ifdef WLAN_SUPPORT_GREEN_AP diff --git a/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index f0ce9d6864ef63b3a651468cea70f9f123d3defd..cd8fdf12a2c70aadf4bd790cea35e480a44f1c34 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -64,15 +64,16 @@ #ifdef QCA_SUPPORT_CP_STATS #include #endif /* QCA_SUPPORT_CP_STATS */ - -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include -#endif #ifdef WLAN_CFR_ENABLE #include "wlan_cfr_tgt_api.h" #endif +#ifdef WIFI_POS_CONVERGED +#include "wifi_pos_api.h" +#endif + /* Function pointer for OL/WMA specific UMAC tx_ops * registration. */ @@ -80,18 +81,11 @@ QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register) (struct wlan_lmac_if_tx_ops *tx_ops); qdf_export_symbol(wlan_lmac_if_umac_tx_ops_register); -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE static void tgt_vdev_mgr_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) { tgt_vdev_mgr_register_rx_ops(rx_ops); } -#else -static void -tgt_vdev_mgr_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) -{ -} -#endif #ifdef QCA_SUPPORT_CP_STATS /** @@ -188,6 +182,7 @@ wlan_lmac_if_fd_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) fd_rx_ops->fd_free = tgt_fd_free; fd_rx_ops->fd_get_valid_fd_period = tgt_fd_get_valid_fd_period; fd_rx_ops->fd_swfda_handler = tgt_fd_swfda_handler; + fd_rx_ops->fd_offload = tgt_fd_offload; } #else static void @@ -272,7 +267,7 @@ wlan_lmac_if_crypto_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) static void wlan_lmac_if_umac_rx_ops_register_wifi_pos( struct wlan_lmac_if_rx_ops *rx_ops) { - target_if_wifi_pos_register_rx_ops(rx_ops); + wifi_pos_register_rx_ops(rx_ops); } #else static void wlan_lmac_if_umac_rx_ops_register_wifi_pos( @@ -323,8 +318,17 @@ static void wlan_lmac_if_umac_reg_rx_ops_register( rx_ops->reg_rx_ops.reg_enable_dfs_channels = ucfg_reg_enable_dfs_channels; + rx_ops->reg_rx_ops.reg_modify_pdev_chan_range = + wlan_reg_modify_pdev_chan_range; + rx_ops->reg_rx_ops.reg_ignore_fw_reg_offload_ind = tgt_reg_ignore_fw_reg_offload_ind; + + rx_ops->reg_rx_ops.reg_disable_chan_coex = + wlan_reg_disable_chan_coex; + + rx_ops->reg_rx_ops.reg_get_unii_5g_bitmap = + ucfg_reg_get_unii_5g_bitmap; } #ifdef CONVERGED_P2P_ENABLE @@ -353,6 +357,51 @@ static void wlan_lmac_if_umac_rx_ops_register_p2p( } #endif +/* + * register_precac_auto_chan_rx_ops_ieee() - Register auto chan switch rx ops + * for IEEE channel based APIs. + * rx_ops: Pointer to wlan_lmac_if_dfs_rx_ops + */ +#ifdef DFS_COMPONENT_ENABLE +#if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_NUM_API) +static inline void +register_precac_auto_chan_rx_ops_ieee(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ + if (!rx_ops) + return; + rx_ops->dfs_get_precac_chan_state = ucfg_dfs_get_precac_chan_state; +} +#else +static inline void +register_precac_auto_chan_rx_ops_ieee(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ +} +#endif +#endif + +/* + * register_precac_auto_chan_rx_ops_freq() - Register auto chan switch rx ops + * for frequency based channel APIs. + * rx_ops: Pointer to wlan_lmac_if_dfs_rx_ops + */ +#ifdef DFS_COMPONENT_ENABLE +#if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API) +static inline void +register_precac_auto_chan_rx_ops_freq(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ + if (!rx_ops) + return; + rx_ops->dfs_get_precac_chan_state_for_freq = + ucfg_dfs_get_precac_chan_state_for_freq; +} +#else +static inline void +register_precac_auto_chan_rx_ops_freq(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ +} +#endif +#endif + #ifdef DFS_COMPONENT_ENABLE #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT static inline void @@ -364,7 +413,6 @@ register_precac_auto_chan_rx_ops(struct wlan_lmac_if_dfs_rx_ops *rx_ops) ucfg_dfs_set_precac_intermediate_chan; rx_ops->dfs_get_precac_intermediate_chan = ucfg_dfs_get_precac_intermediate_chan; - rx_ops->dfs_get_precac_chan_state = ucfg_dfs_get_precac_chan_state; } #else static inline void @@ -373,6 +421,41 @@ register_precac_auto_chan_rx_ops(struct wlan_lmac_if_dfs_rx_ops *rx_ops) } #endif +/* + * register_dfs_rx_ops_for_freq() - Register DFS rx ops for frequency based + * channel APIs. + * rx_ops: Pointer to wlan_lmac_if_dfs_rx_ops. + */ +#ifdef CONFIG_CHAN_FREQ_API +static void register_dfs_rx_ops_for_freq(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ + if (!rx_ops) + return; + rx_ops->dfs_find_vht80_chan_for_precac_for_freq = + tgt_dfs_find_vht80_precac_chan_freq; + rx_ops->dfs_set_current_channel_for_freq = + tgt_dfs_set_current_channel_for_freq; +} +#endif + +/* + * register_dfs_rx_ops_for_ieee() - Register DFS rx ops for IEEE channel based + * APIs + * rx_ops: Pointer to wlan_lmac_if_dfs_rx_ops. + */ + +#ifdef CONFIG_CHAN_NUM_API +static void register_dfs_rx_ops_for_ieee(struct wlan_lmac_if_dfs_rx_ops *rx_ops) +{ + if (!rx_ops) + return; + rx_ops->dfs_find_vht80_chan_for_precac = + tgt_dfs_find_vht80_chan_for_precac; + rx_ops->dfs_set_current_channel = + tgt_dfs_set_current_channel; +} +#endif + static QDF_STATUS wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) { @@ -388,25 +471,27 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) dfs_rx_ops->dfs_control = tgt_dfs_control; dfs_rx_ops->dfs_is_precac_timer_running = tgt_dfs_is_precac_timer_running; - dfs_rx_ops->dfs_find_vht80_chan_for_precac = - tgt_dfs_find_vht80_chan_for_precac; dfs_rx_ops->dfs_agile_precac_start = tgt_dfs_agile_precac_start; dfs_rx_ops->dfs_set_agile_precac_state = tgt_dfs_set_agile_precac_state; dfs_rx_ops->dfs_start_precac_timer = utils_dfs_start_precac_timer; dfs_rx_ops->dfs_cancel_precac_timer = utils_dfs_cancel_precac_timer; + dfs_rx_ops->dfs_reset_adfs_config = ucfg_dfs_reset_agile_config; dfs_rx_ops->dfs_override_precac_timeout = ucfg_dfs_override_precac_timeout; dfs_rx_ops->dfs_set_precac_enable = ucfg_dfs_set_precac_enable; - dfs_rx_ops->dfs_get_precac_enable = ucfg_dfs_get_precac_enable; + dfs_rx_ops->dfs_get_legacy_precac_enable = + ucfg_dfs_get_legacy_precac_enable; + dfs_rx_ops->dfs_get_agile_precac_enable = + ucfg_dfs_get_agile_precac_enable; dfs_rx_ops->dfs_get_override_precac_timeout = ucfg_dfs_get_override_precac_timeout; - dfs_rx_ops->dfs_set_current_channel = tgt_dfs_set_current_channel; dfs_rx_ops->dfs_process_radar_ind = tgt_dfs_process_radar_ind; dfs_rx_ops->dfs_dfs_cac_complete_ind = tgt_dfs_cac_complete; dfs_rx_ops->dfs_dfs_ocac_complete_ind = tgt_dfs_ocac_complete; dfs_rx_ops->dfs_stop = tgt_dfs_stop; + dfs_rx_ops->dfs_reinit_timers = ucfg_dfs_reinit_timers; dfs_rx_ops->dfs_enable_stadfs = tgt_dfs_enable_stadfs; dfs_rx_ops->dfs_is_stadfs_enabled = tgt_dfs_is_stadfs_enabled; dfs_rx_ops->dfs_process_phyerr_filter_offload = @@ -430,8 +515,31 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) utils_dfs_bw_reduce; dfs_rx_ops->dfs_is_bw_reduction_needed = utils_dfs_is_bw_reduce; - + dfs_rx_ops->dfs_allow_hw_pulses = + ucfg_dfs_allow_hw_pulses; + dfs_rx_ops->dfs_is_hw_pulses_allowed = + ucfg_dfs_is_hw_pulses_allowed; + dfs_rx_ops->dfs_set_fw_adfs_support = + tgt_dfs_set_fw_adfs_support; + dfs_rx_ops->dfs_reset_dfs_prevchan = + utils_dfs_reset_dfs_prevchan; + dfs_rx_ops->dfs_init_tmp_psoc_nol = + tgt_dfs_init_tmp_psoc_nol; + dfs_rx_ops->dfs_deinit_tmp_psoc_nol = + tgt_dfs_deinit_tmp_psoc_nol; + dfs_rx_ops->dfs_save_dfs_nol_in_psoc = + tgt_dfs_save_dfs_nol_in_psoc; + dfs_rx_ops->dfs_reinit_nol_from_psoc_copy = + tgt_dfs_reinit_nol_from_psoc_copy; + dfs_rx_ops->dfs_reinit_precac_lists = + tgt_dfs_reinit_precac_lists; + dfs_rx_ops->dfs_complete_deferred_tasks = + tgt_dfs_complete_deferred_tasks; register_precac_auto_chan_rx_ops(dfs_rx_ops); + register_precac_auto_chan_rx_ops_ieee(dfs_rx_ops); + register_precac_auto_chan_rx_ops_freq(dfs_rx_ops); + register_dfs_rx_ops_for_freq(dfs_rx_ops); + register_dfs_rx_ops_for_ieee(dfs_rx_ops); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/inc/cfg_green_ap_params.h b/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/inc/cfg_green_ap_params.h index 4cbb2491668307b9153609f695e70d75e3221093..410dfb5d4786b4da5347d6225f6116f2c431b874 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/inc/cfg_green_ap_params.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/inc/cfg_green_ap_params.h @@ -43,7 +43,7 @@ #define CFG_ENABLE_GREEN_AP_FEATURE CFG_INI_BOOL( \ "gEnableGreenAp", \ - MCL_OR_WIN_VALUE(1, 0), \ + PLATFORM_VALUE(1, 0), \ "enable green ap") /* @@ -66,7 +66,7 @@ #define CFG_ENABLE_EGAP_FEATURE CFG_INI_BOOL( \ "gEnableEGAP", \ - MCL_OR_WIN_VALUE(1,0), \ + PLATFORM_VALUE(1, 0), \ "enable e-gap") /* * diff --git a/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/src/wlan_green_ap_api.c b/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/src/wlan_green_ap_api.c index 70cd45b0b1d728c39628f86849bf65e17cc70555..7fa69dceb56d280913a824c993d1feda89216155 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/src/wlan_green_ap_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/green_ap/dispatcher/src/wlan_green_ap_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -156,7 +156,7 @@ static QDF_STATUS wlan_green_ap_pdev_obj_destroy_notification( qdf_spinlock_destroy(&green_ap_ctx->lock); qdf_mem_free(green_ap_ctx); - green_ap_info("green ap deletion successful, pdev: %pK", pdev); + green_ap_info("green ap deletion successful"); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_mlme_cmn.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_mlme_cmn.h index eee5f244862aeb107a8399a3e89fd048fbce02ac..3991f6aee8275130b7ae7234e0fd50f7362e47b9 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_mlme_cmn.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_mlme_cmn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,11 +20,16 @@ #ifndef _WLAN_MLME_CMN_H_ #define _WLAN_MLME_CMN_H_ +#include #include #include /** * struct vdev_mlme_ext_ops - VDEV MLME legacy callbacks structure + * @mlme_psoc_ext_hdl_create: callback to invoke creation of legacy + * psoc object + * @mlme_psoc_ext_hdl_destroy: callback to invoke destroy of legacy + * psoc object * @mlme_pdev_ext_hdl_create: callback to invoke creation of legacy * pdev object * @mlme_pdev_ext_hdl_destroy: callback to invoke destroy of legacy @@ -42,8 +47,14 @@ * command * @mlme_vdev_enqueue_exp_cmd: callback to enqueue exception command * required by serialization + * @mlme_multi_vdev_restart_resp: callback to process multivdev restart + * response */ struct mlme_ext_ops { + QDF_STATUS (*mlme_psoc_ext_hdl_create)( + struct psoc_mlme_obj *psoc_mlme); + QDF_STATUS (*mlme_psoc_ext_hdl_destroy)( + struct psoc_mlme_obj *pdev_mlme); QDF_STATUS (*mlme_pdev_ext_hdl_create)( struct pdev_mlme_obj *pdev_mlme); QDF_STATUS (*mlme_pdev_ext_hdl_destroy)( @@ -63,8 +74,36 @@ struct mlme_ext_ops { QDF_STATUS (*mlme_vdev_enqueue_exp_cmd)( struct vdev_mlme_obj *vdev_mlme, uint8_t cmd_type); + QDF_STATUS (*mlme_vdev_ext_delete_rsp)( + struct wlan_objmgr_psoc *psoc, + struct vdev_delete_response *rsp); + QDF_STATUS (*mlme_multi_vdev_restart_resp)( + struct wlan_objmgr_psoc *psoc, + struct multi_vdev_restart_resp *resp); }; +/** + * mlme_psoc_ops_ext_hdl_create() - Alloc PSOC mlme ext handle + * @psoc_mlme: PSOC MLME comp object + * + * API to allocate PSOC MLME ext handle + * + * Return: SUCCESS on successful allocation + * Else FAILURE + */ +QDF_STATUS mlme_psoc_ops_ext_hdl_create(struct psoc_mlme_obj *psoc_mlme); + +/** + * mlme_psoc_ops_ext_hdl_destroy() - Destroy PSOC mlme ext handle + * @psoc_mlme: PSOC MLME comp object + * + * API to free psoc MLME ext handle + * + * Return: SUCCESS on successful free + * Else FAILURE + */ +QDF_STATUS mlme_psoc_ops_ext_hdl_destroy(struct psoc_mlme_obj *psoc_mlme); + /** * mlme_pdev_ops_ext_hdl_create - Alloc PDEV mlme ext handle * @pdev_mlme_obj: PDEV MLME comp object @@ -182,6 +221,19 @@ QDF_STATUS mlme_vdev_ops_stop_fw_send(struct wlan_objmgr_vdev *vdev); */ QDF_STATUS mlme_vdev_ops_down_fw_send(struct wlan_objmgr_vdev *vdev); +/* + * mlme_vdev_ops_ext_hdl_multivdev_restart_resp() - Handler multivdev restart + * response event + * @psoc: PSOC object manager handle + * @resp: Restart response event + * + * Return: Success on successful handling of the response event, + * Else failure + */ +QDF_STATUS mlme_vdev_ops_ext_hdl_multivdev_restart_resp( + struct wlan_objmgr_psoc *psoc, + struct multi_vdev_restart_resp *resp); + /** * mlme_set_ops_register_cb - Sets ops registration callback * @ops_cb: Function pointer @@ -212,4 +264,17 @@ QDF_STATUS wlan_cmn_mlme_init(void); * FAILURE, if registration fails */ QDF_STATUS wlan_cmn_mlme_deinit(void); + +/** + * mlme_vdev_ops_ext_hdl_delete_rsp - Vdev Delete response ext handler + * @psoc: PSOC object + * @rsp: Vdev delete response received from the firmware + * + * API to invoke the legacy delete response handler for legacy cleanup + * + * Return: SUCCESS on successful deletion + * FAILURE, if deletion fails + */ +QDF_STATUS mlme_vdev_ops_ext_hdl_delete_rsp(struct wlan_objmgr_psoc *psoc, + struct vdev_delete_response *rsp); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_pdev_mlme.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_pdev_mlme.h index 96e8786eee804f4d058fd01fdfb50137a4d08823..6f3c68ffeb1fc027834e50cb0a8b56f86e312ef0 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_pdev_mlme.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_pdev_mlme.h @@ -22,6 +22,18 @@ #include #include +#include + +/* + * struct pdev_restart_attr - Pdev restart attributes + * @vdev: vdev on which the pdev restart cmd was enqueued + * @restart_bmap: Bitmap for vdev requesting multivdev restart + */ +struct pdev_restart_attr { + struct wlan_objmgr_vdev *vdev; + unsigned long restart_bmap[2]; +}; + /** * struct pdev_mlme_obj - PDEV MLME component object * @pdev: PDEV object @@ -35,13 +47,14 @@ */ struct pdev_mlme_obj { struct wlan_objmgr_pdev *pdev; - void *ext_pdev_ptr; + mlme_pdev_ext_t *ext_pdev_ptr; QDF_STATUS (*mlme_register_ops)(struct vdev_mlme_obj *vdev_mlme); qdf_spinlock_t vdev_restart_lock; qdf_timer_t restart_req_timer; unsigned long restart_pend_vdev_bmap[2]; unsigned long restart_send_vdev_bmap[2]; unsigned long start_send_vdev_arr[2]; + struct pdev_restart_attr pdev_restart; }; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_psoc_mlme.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_psoc_mlme.h new file mode 100644 index 0000000000000000000000000000000000000000..c7ca931ca5d5a1ee125c92904b5728e59ba170c1 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_psoc_mlme.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Define PSOC MLME structure + */ +#ifndef _WLAN_PSOC_MLME_H_ +#define _WLAN_PSOC_MLME_H_ + +#include +#include +#include +#ifdef FEATURE_VDEV_RSP_WAKELOCK +#include +#endif + +/* Max RNR size given max vaps are 16 */ +#define MAX_RNR_SIZE 256 + +/** + * struct wlan_rnr_global_cache - RNR cache buffer per soc + * @rnr_buf: RNR cache buffer + * @rnr_cnt: Count of APs in cache + * @rnr_size: Size of RNR cache (RNR IE) + */ +struct wlan_6ghz_rnr_global_cache { + char rnr_buf[MAX_RNR_SIZE]; + int rnr_cnt; + uint16_t rnr_size; +}; + +/** + * struct psoc_mlme_obj - PSoC MLME component object + * @psoc: PSoC object + * @ext_psoc_ptr: PSoC legacy pointer + * @psoc_vdev_rt: PSoC Vdev response timer + * @psoc_mlme_wakelock: Wakelock to prevent system going to suspend + * @rnr_6ghz_cache: Cache of 6Ghz vap in RNR ie format + */ +struct psoc_mlme_obj { + struct wlan_objmgr_psoc *psoc; + mlme_psoc_ext_t *ext_psoc_ptr; + struct vdev_response_timer psoc_vdev_rt[WLAN_UMAC_PSOC_MAX_VDEVS]; +#ifdef FEATURE_VDEV_RSP_WAKELOCK + struct psoc_mlme_wakelock psoc_mlme_wakelock; +#endif + struct wlan_6ghz_rnr_global_cache rnr_6ghz_cache; +}; + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_vdev_mlme.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_vdev_mlme.h index d12fc27e8e44beac3e144f6b666ed966dfe88b1d..5bf922d9c99e89effa2467245e40be1db5d8e08c 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_vdev_mlme.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/include/wlan_vdev_mlme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,7 @@ #include #include #include +#include struct vdev_mlme_obj; @@ -30,17 +31,24 @@ struct vdev_mlme_obj; #define MULTIPLE_VDEV_RESTART_REQ_ID 0x1234 /* values for vdev_type */ +#define WLAN_VDEV_MLME_TYPE_UNKNOWN 0x0 #define WLAN_VDEV_MLME_TYPE_AP 0x1 #define WLAN_VDEV_MLME_TYPE_STA 0x2 #define WLAN_VDEV_MLME_TYPE_IBSS 0x3 #define WLAN_VDEV_MLME_TYPE_MONITOR 0x4 +#define WLAN_VDEV_MLME_TYPE_NAN 0x5 +#define WLAN_VDEV_MLME_TYPE_OCB 0x6 +#define WLAN_VDEV_MLME_TYPE_NDI 0x7 /* values for vdev_subtype */ +#define WLAN_VDEV_MLME_SUBTYPE_UNKNOWN 0x0 #define WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE 0x1 #define WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT 0x2 #define WLAN_VDEV_MLME_SUBTYPE_P2P_GO 0x3 #define WLAN_VDEV_MLME_SUBTYPE_PROXY_STA 0x4 #define WLAN_VDEV_MLME_SUBTYPE_MESH 0x5 +#define WLAN_VDEV_MLME_SUBTYPE_MESH_11S 0x6 +#define WLAN_VDEV_MLME_SUBTYPE_SMART_MONITOR 0x7 /* vdev control flags (per bits) */ #define WLAN_VDEV_MLME_FLAGS_NON_MBSSID_AP 0x00000001 @@ -192,7 +200,7 @@ struct vdev_mlme_proto { * @type: vdev type * @sub_type: vdev subtype * @rx_decap_type: rx decap type - * @tx_decap_type: tx decap type + * @tx_encap_type: tx encap type * @disable_hw_ack: disable ha ack flag * @bssid: bssid * @phy_mode: phy mode @@ -217,7 +225,7 @@ struct vdev_mlme_mgmt_generic { uint8_t type; uint8_t subtype; uint8_t rx_decap_type; - uint8_t tx_decap_type; + uint8_t tx_encap_type; bool disable_hw_ack; uint8_t bssid[QDF_MAC_ADDR_SIZE]; uint32_t phy_mode; @@ -225,9 +233,12 @@ struct vdev_mlme_mgmt_generic { /** * struct vdev_mlme_mgmt_ap - ap specific vdev mlme mgmt cfg - * @. + * @hidden_ssid: flag to indicate whether it is hidden ssid + * @cac_duration_ms: cac duration in millseconds */ struct vdev_mlme_mgmt_ap { + bool hidden_ssid; + uint32_t cac_duration_ms; }; /** @@ -262,6 +273,7 @@ struct vdev_mlme_inactivity_params { * @max_rate: max bandwidth rate * @tx_mgmt_rate: Tx Mgmt rate * @bcn_tx_rate: beacon Tx rate + * @bcn_tx_rate_code: beacon Tx rate code * @type: Type of ratemask configuration * @lower32: Lower 32 bits in the 1st 64-bit value * @higher32: Higher 32 bits in the 1st 64-bit value @@ -275,6 +287,9 @@ struct vdev_mlme_rate_info { uint32_t max_rate; uint32_t tx_mgmt_rate; uint32_t bcn_tx_rate; +#ifdef WLAN_BCN_RATECODE_ENABLE + uint32_t bcn_tx_rate_code; +#endif uint8_t type; uint32_t lower32; uint32_t higher32; @@ -438,6 +453,8 @@ enum vdev_start_resp_type { * @mlme_vdev_notify_start_state_exit: callback to notify on vdev start * start state exit * @mlme_vdev_is_newchan_no_cac: callback to check CAC is required + * @mlme_vdev_ext_peer_delete_all_rsp: callback to initiate actions for + * vdev mlme peer delete all response */ struct vdev_mlme_ops { QDF_STATUS (*mlme_vdev_validate_basic_params)( @@ -496,9 +513,6 @@ struct vdev_mlme_ops { QDF_STATUS (*mlme_vdev_notify_down_complete)( struct vdev_mlme_obj *vdev_mlme, uint16_t event_data_len, void *event_data); - QDF_STATUS (*mlme_vdev_ext_delete_rsp)( - struct vdev_mlme_obj *vdev_mlme, - struct vdev_delete_response *rsp); QDF_STATUS (*mlme_vdev_ext_stop_rsp)( struct vdev_mlme_obj *vdev_mlme, struct vdev_stop_response *rsp); @@ -509,6 +523,9 @@ struct vdev_mlme_ops { struct vdev_mlme_obj *vdev_mlme); QDF_STATUS (*mlme_vdev_is_newchan_no_cac)( struct vdev_mlme_obj *vdev_mlme); + QDF_STATUS (*mlme_vdev_ext_peer_delete_all_rsp)( + struct vdev_mlme_obj *vdev_mlme, + struct peer_delete_all_response *rsp); }; /** @@ -522,6 +539,7 @@ struct vdev_mlme_ops { * @ops: VDEV MLME callback table * @ext_vdev_ptr: VDEV MLME legacy pointer * @vdev_rt: VDEV response timer + * @vdev_wakelock: vdev wakelock sub structure */ struct vdev_mlme_obj { struct vdev_mlme_proto proto; @@ -533,494 +551,9 @@ struct vdev_mlme_obj { struct wlan_sm *sm_hdl; struct wlan_objmgr_vdev *vdev; struct vdev_mlme_ops *ops; - void *ext_vdev_ptr; - struct vdev_response_timer vdev_rt; + mlme_vdev_ext_t *ext_vdev_ptr; }; -/** - * mlme_vdev_validate_basic_params - Validate basic params - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API validate MLME VDEV basic parameters - * - * Return: SUCCESS on successful validation - * FAILURE, if any parameter is not initialized - */ -static inline QDF_STATUS mlme_vdev_validate_basic_params( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_validate_basic_params) - ret = vdev_mlme->ops->mlme_vdev_validate_basic_params( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_reset_proto_params - Reset VDEV protocol params - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API resets the protocol params fo vdev - * - * Return: SUCCESS on successful reset - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_reset_proto_params( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_reset_proto_params) - ret = vdev_mlme->ops->mlme_vdev_reset_proto_params( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_start_send - Invokes VDEV start operation - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV start operation - * - * Return: SUCCESS on successful completion of start operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_start_send( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_send) - ret = vdev_mlme->ops->mlme_vdev_start_send( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_restart_send - Invokes VDEV restart operation - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV restart operation - * - * Return: SUCCESS on successful completion of restart operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_restart_send( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_restart_send) - ret = vdev_mlme->ops->mlme_vdev_restart_send( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_stop_start_send - Invoke block VDEV restart operation - * @vdev_mlme_obj: VDEV MLME comp object - * @restart: restart req/start req - * @event_data_len: data size - * @event_data: event data - * - * API invokes stops pending VDEV restart operation - * - * Return: SUCCESS alsways - */ -static inline QDF_STATUS mlme_vdev_stop_start_send( - struct vdev_mlme_obj *vdev_mlme, - uint8_t restart, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_start_send) - ret = vdev_mlme->ops->mlme_vdev_stop_start_send( - vdev_mlme, restart, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_start_continue - VDEV start response handling - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV start response actions - * - * Return: SUCCESS on successful completion of start response operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_start_continue( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_continue) - ret = vdev_mlme->ops->mlme_vdev_start_continue( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_start_req_failed - Invoke Station VDEV connection, if it pause - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes on START fail response - * - * Return: SUCCESS on successful invocation of callback - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_start_req_failed( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_req_failed) - ret = vdev_mlme->ops->mlme_vdev_start_req_failed( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_sta_conn_start - Invoke Station VDEV connection, if it pause - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes connection SM to start station connection - * - * Return: SUCCESS on successful invocation of connection sm - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_sta_conn_start( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_sta_conn_start) - ret = vdev_mlme->ops->mlme_vdev_sta_conn_start( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_up_send - VDEV up operation - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV up operations - * - * Return: SUCCESS on successful completion of up operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_up_send( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_up_send) - ret = vdev_mlme->ops->mlme_vdev_up_send( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_notify_up_complete - VDEV up state transition notification - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API notifies MLME on moving to UP state - * - * Return: SUCCESS on successful completion of up notification - * FAILURE, if it fails due to any - */ -static inline -QDF_STATUS mlme_vdev_notify_up_complete(struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, - void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_notify_up_complete) - ret = vdev_mlme->ops->mlme_vdev_notify_up_complete( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_notify_roam_start - VDEV Roaming notification - * @vdev_mlme_obj: VDEV MLME comp object - * @event_len: data size - * @event_data: event data - * - * API notifies MLME on roaming - * - * Return: SUCCESS on successful completion of up notification - * FAILURE, if it fails due to any - */ -static inline -QDF_STATUS mlme_vdev_notify_roam_start(struct vdev_mlme_obj *vdev_mlme, - uint16_t event_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_notify_roam_start) - ret = vdev_mlme->ops->mlme_vdev_notify_roam_start(vdev_mlme, - event_len, - event_data); - - return ret; -} - -/** - * mlme_vdev_update_beacon - Updates beacon - * @vdev_mlme_obj: VDEV MLME comp object - * @op: beacon update type - * @event_data_len: data size - * @event_data: event data - * - * API updates/allocates/frees the beacon - * - * Return: SUCCESS on successful update of beacon - * FAILURE, if it fails due to any - */ -static inline -QDF_STATUS mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme, - enum beacon_update_op op, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_update_beacon) - ret = vdev_mlme->ops->mlme_vdev_update_beacon(vdev_mlme, op, - event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_disconnect_peers - Disconnect peers - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API trigger stations disconnection with AP VDEV or AP disconnection with STA - * VDEV - * - * Return: SUCCESS on successful invocation of station disconnection - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_disconnect_peers( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_disconnect_peers) - ret = vdev_mlme->ops->mlme_vdev_disconnect_peers( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_dfs_cac_timer_stop - Stop CAC timer - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API stops the CAC timer through DFS API - * - * Return: SUCCESS on successful CAC timer stop - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_dfs_cac_timer_stop( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_dfs_cac_timer_stop) - ret = vdev_mlme->ops->mlme_vdev_dfs_cac_timer_stop( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_stop_send - Invokes VDEV stop operation - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV stop operation - * - * Return: SUCCESS on successful completion of stop operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_stop_send( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_send) - ret = vdev_mlme->ops->mlme_vdev_stop_send( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_stop_continue - VDEV stop response handling - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV stop response actions - * - * Return: SUCCESS on successful completion of stop response operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_stop_continue( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_continue) - ret = vdev_mlme->ops->mlme_vdev_stop_continue(vdev_mlme, - event_data_len, - event_data); - - return ret; -} - -/** - * mlme_vdev_down_send - VDEV down operation - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API invokes VDEV down operation - * - * Return: SUCCESS on successful completion of VDEV down operation - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_down_send( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_down_send) - ret = vdev_mlme->ops->mlme_vdev_down_send( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_notify_down_complete - VDEV init state transition notification - * @vdev_mlme_obj: VDEV MLME comp object - * @event_data_len: data size - * @event_data: event data - * - * API notifies MLME on moving to INIT state - * - * Return: SUCCESS on successful completion of down notification - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_notify_down_complete( - struct vdev_mlme_obj *vdev_mlme, - uint16_t event_data_len, void *event_data) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_notify_down_complete) - ret = vdev_mlme->ops->mlme_vdev_notify_down_complete( - vdev_mlme, event_data_len, event_data); - - return ret; -} - -/** - * mlme_vdev_notify_start_state_exit - VDEV SM start state exit notification - * @vdev_mlme_obj: VDEV MLME comp object - * - * API notifies on start state exit - * - * Return: SUCCESS on successful completion of notification - * FAILURE, if it fails due to any - */ -static inline QDF_STATUS mlme_vdev_notify_start_state_exit( - struct vdev_mlme_obj *vdev_mlme) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && - vdev_mlme->ops->mlme_vdev_notify_start_state_exit) - ret = vdev_mlme->ops->mlme_vdev_notify_start_state_exit( - vdev_mlme); - - return ret; -} - -/** - * mlme_vdev_is_newchan_no_cac - Checks new channel requires CAC - * @vdev_mlme_obj: VDEV MLME comp object - * - * API checks whether Channel needs CAC period, - * if yes, it moves to SUSPEND_RESTART to disconnect stations before - * sending RESTART to FW, otherwise, it moves to RESTART_PROGRESS substate - * - * Return: SUCCESS to move to RESTART_PROGRESS substate - * FAILURE, move to SUSPEND_RESTART state - */ -static inline QDF_STATUS mlme_vdev_is_newchan_no_cac( - struct vdev_mlme_obj *vdev_mlme) -{ - QDF_STATUS ret = QDF_STATUS_SUCCESS; - - if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_is_newchan_no_cac) - ret = vdev_mlme->ops->mlme_vdev_is_newchan_no_cac(vdev_mlme); - - return ret; -} - -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE /** * wlan_vdev_mlme_set_ssid() - set ssid * @vdev: VDEV object @@ -1349,5 +882,4 @@ static inline uint32_t wlan_vdev_mlme_get_txmgmtrate( return vdev_mlme->mgmt.rate_info.tx_mgmt_rate; } -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_psoc_mlme_main.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_psoc_mlme_main.h new file mode 100644 index 0000000000000000000000000000000000000000..36026b7ae1a8d35e1366813d0cd2ad331893ef1b --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_psoc_mlme_main.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Define PSOC MLME structure + */ +#ifndef _WLAN_PSOC_MLME_MAIN_H_ +#define _WLAN_PSOC_MLME_MAIN_H_ + +/** + * wlan_psoc_mlme_init() - Initializes PSOC MLME component + * + * Registers callbacks with object manager for create/destroy + * + * Return: SUCCESS on successful initialization + * FAILURE, if initialization fails + */ +QDF_STATUS wlan_psoc_mlme_init(void); + +/** + * wlan_psoc_mlme_deinit() - Uninitializes PSOC MLME component + * + * Unregisters callbacks with object manager for create/destroy + * + * Return: SUCCESS on successful de-initialization + * FAILURE, if de-initialization fails + */ +QDF_STATUS wlan_psoc_mlme_deinit(void); + +/** + * mlme_psoc_get_priv: get MLME priv object from psoc object + * @psoc: pointer to psoc object + * + * Return: pointer to MLME psoc private object + */ +struct psoc_mlme_obj *mlme_psoc_get_priv(struct wlan_objmgr_psoc *psoc); + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h index 8a89344b2bda51748ca04b71ab423c2c3aa84a38..e13bcddf009b8e42a22eec02d2cea4558e5ccd3f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/inc/wlan_vdev_mlme_main.h @@ -116,6 +116,8 @@ enum wlan_vdev_state { * @WLAN_VDEV_SM_EV_DOWN_COMPLETE: Notification of DOWN complete * @WLAN_VDEV_SM_EV_ROAM: Notifiction on ROAMING * @WLAN_VDEV_SM_EV_STOP_REQ: Invoke API to initiate STOP handshake + * @WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED:Test only, CSA completes without + * change in channel */ enum wlan_vdev_sm_evt { WLAN_VDEV_SM_EV_START = 0, @@ -148,6 +150,7 @@ enum wlan_vdev_sm_evt { WLAN_VDEV_SM_EV_DOWN_COMPLETE = 27, WLAN_VDEV_SM_EV_ROAM = 28, WLAN_VDEV_SM_EV_STOP_REQ = 29, + WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED = 30, }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c index 5054286c2d74e1ca34244a08c63a72b0e0cdd64d..0f03758b28f0de019a655b2cc3c11566ad8faba2 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,13 +18,14 @@ * DOC: Implements MLME global APIs */ -#include "wlan_objmgr_cmn.h" -#include "include/wlan_mlme_cmn.h" -#include "include/wlan_pdev_mlme.h" -#include "include/wlan_vdev_mlme.h" -#include "include/wlan_mlme_cmn.h" -#include "wlan_pdev_mlme_main.h" -#include "wlan_vdev_mlme_main.h" +#include +#include +#include +#include +#include +#include +#include +#include struct mlme_ext_ops *glbl_ops; mlme_get_global_ops_cb glbl_ops_cb; @@ -33,6 +34,10 @@ QDF_STATUS wlan_cmn_mlme_init(void) { QDF_STATUS status; + status = wlan_psoc_mlme_init(); + if (status != QDF_STATUS_SUCCESS) + return status; + status = wlan_pdev_mlme_init(); if (status != QDF_STATUS_SUCCESS) return status; @@ -59,14 +64,38 @@ QDF_STATUS wlan_cmn_mlme_deinit(void) if (status != QDF_STATUS_SUCCESS) return status; + status = wlan_psoc_mlme_deinit(); + if (status != QDF_STATUS_SUCCESS) + return status; + return QDF_STATUS_SUCCESS; } +QDF_STATUS mlme_psoc_ops_ext_hdl_create(struct psoc_mlme_obj *psoc_mlme) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (glbl_ops && glbl_ops->mlme_psoc_ext_hdl_create) + ret = glbl_ops->mlme_psoc_ext_hdl_create(psoc_mlme); + + return ret; +} + +QDF_STATUS mlme_psoc_ops_ext_hdl_destroy(struct psoc_mlme_obj *psoc_mlme) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (glbl_ops && glbl_ops->mlme_psoc_ext_hdl_destroy) + ret = glbl_ops->mlme_psoc_ext_hdl_destroy(psoc_mlme); + + return ret; +} + QDF_STATUS mlme_pdev_ops_ext_hdl_create(struct pdev_mlme_obj *pdev_mlme) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_pdev_ext_hdl_create) + if (glbl_ops && glbl_ops->mlme_pdev_ext_hdl_create) ret = glbl_ops->mlme_pdev_ext_hdl_create(pdev_mlme); return ret; @@ -76,7 +105,7 @@ QDF_STATUS mlme_pdev_ops_ext_hdl_destroy(struct pdev_mlme_obj *pdev_mlme) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_pdev_ext_hdl_destroy) + if (glbl_ops && glbl_ops->mlme_pdev_ext_hdl_destroy) ret = glbl_ops->mlme_pdev_ext_hdl_destroy(pdev_mlme); return ret; @@ -86,7 +115,7 @@ QDF_STATUS mlme_vdev_ops_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_vdev_ext_hdl_create) + if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_create) ret = glbl_ops->mlme_vdev_ext_hdl_create(vdev_mlme); return ret; @@ -96,7 +125,7 @@ QDF_STATUS mlme_vdev_ops_ext_hdl_post_create(struct vdev_mlme_obj *vdev_mlme) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_vdev_ext_hdl_post_create) + if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_post_create) ret = glbl_ops->mlme_vdev_ext_hdl_post_create(vdev_mlme); return ret; @@ -106,7 +135,7 @@ QDF_STATUS mlme_vdev_ops_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_vdev_ext_hdl_destroy) + if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_destroy) ret = glbl_ops->mlme_vdev_ext_hdl_destroy(vdev_mlme); return ret; @@ -128,7 +157,7 @@ QDF_STATUS mlme_vdev_ops_multivdev_restart_fw_cmd_send( { QDF_STATUS ret = QDF_STATUS_SUCCESS; - if ((glbl_ops) && glbl_ops->mlme_multivdev_restart_fw_send) + if (glbl_ops && glbl_ops->mlme_multivdev_restart_fw_send) glbl_ops->mlme_multivdev_restart_fw_send(pdev); return ret; @@ -165,6 +194,29 @@ QDF_STATUS mlme_vdev_enqueue_exp_ser_cmd(struct vdev_mlme_obj *vdev_mlme, return ret; } +QDF_STATUS mlme_vdev_ops_ext_hdl_delete_rsp(struct wlan_objmgr_psoc *psoc, + struct vdev_delete_response *rsp) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((glbl_ops) && glbl_ops->mlme_vdev_ext_delete_rsp) + ret = glbl_ops->mlme_vdev_ext_delete_rsp(psoc, rsp); + + return ret; +} + +QDF_STATUS mlme_vdev_ops_ext_hdl_multivdev_restart_resp( + struct wlan_objmgr_psoc *psoc, + struct multi_vdev_restart_resp *resp) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((glbl_ops) && glbl_ops->mlme_multi_vdev_restart_resp) + ret = glbl_ops->mlme_multi_vdev_restart_resp(psoc, resp); + + return ret; +} + void mlme_set_ops_register_cb(mlme_get_global_ops_cb ops_cb) { glbl_ops_cb = ops_cb; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_psoc_mlme_main.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_psoc_mlme_main.c new file mode 100644 index 0000000000000000000000000000000000000000..cf409c99e3474c4bc7873110fdc61813c274880d --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_psoc_mlme_main.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Implements PSOC MLME APIs + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct psoc_mlme_obj *mlme_psoc_get_priv(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *psoc_mlme; + + psoc_mlme = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_MLME); + if (!psoc_mlme) { + mlme_err("PSOC MLME component object is NULL"); + return NULL; + } + + return psoc_mlme; +} + +qdf_export_symbol(mlme_psoc_get_priv); + +static QDF_STATUS mlme_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + struct psoc_mlme_obj *psoc_mlme; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + psoc_mlme = qdf_mem_malloc(sizeof(struct psoc_mlme_obj)); + if (!psoc_mlme) { + mlme_err("Failed to allocate PSOS mlme Object"); + return QDF_STATUS_E_NOMEM; + } + + psoc_mlme->psoc = psoc; + + status = mlme_psoc_ops_ext_hdl_create(psoc_mlme); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Failed to allocate psoc ext handle"); + goto init_failed; + } + + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_MLME, + psoc_mlme, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Failed to attach psoc_ctx with psoc"); + goto init_failed; + } + + return QDF_STATUS_SUCCESS; +init_failed: + qdf_mem_free(psoc_mlme); + + return status; +} + +static QDF_STATUS mlme_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + struct psoc_mlme_obj *psoc_mlme; + + psoc_mlme = mlme_psoc_get_priv(psoc); + if (!psoc_mlme) { + mlme_err("PSOC MLME component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + wlan_objmgr_psoc_component_obj_detach(psoc, WLAN_UMAC_COMP_MLME, + psoc_mlme); + + mlme_psoc_ops_ext_hdl_destroy(psoc_mlme); + + qdf_mem_free(psoc_mlme); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_psoc_mlme_init(void) +{ + if (wlan_objmgr_register_psoc_create_handler + (WLAN_UMAC_COMP_MLME, + mlme_psoc_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_FAILURE; + + if (wlan_objmgr_register_psoc_destroy_handler + (WLAN_UMAC_COMP_MLME, + mlme_psoc_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) { + if (wlan_objmgr_unregister_psoc_create_handler + (WLAN_UMAC_COMP_MLME, + mlme_psoc_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_psoc_mlme_deinit(void) +{ + if (wlan_objmgr_unregister_psoc_create_handler + (WLAN_UMAC_COMP_MLME, + mlme_psoc_obj_create_handler, NULL) + != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_FAILURE; + + if (wlan_objmgr_unregister_psoc_destroy_handler + (WLAN_UMAC_COMP_MLME, + mlme_psoc_obj_destroy_handler, NULL) + != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c index ddd41b2744093081d4d5ca118603baa991f6e7d2..7ef6dfb1285f8671d526208c26c428d45552a55a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,22 +22,27 @@ #include #include #include -#include "include/wlan_mlme_cmn.h" -#include "include/wlan_vdev_mlme.h" -#include "include/wlan_pdev_mlme.h" -#include "vdev_mgr/core/src/vdev_mlme_sm.h" -#include "wlan_pdev_mlme_api.h" -#include "wlan_vdev_mlme_api.h" -#include "wlan_serialization_api.h" -#include "wlan_utility.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg) { struct vdev_mlme_obj *vdev_mlme; struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; struct pdev_mlme_obj *pdev_mlme; + struct wlan_lmac_if_mlme_tx_ops *txops; + QDF_STATUS status; if (!vdev) { mlme_err(" VDEV is NULL"); @@ -50,9 +55,33 @@ static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_FAILURE; } + /** + * 1st check whether for this vdev any vdev commands are pending for + * response. + */ + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + mlme_err("PSOC is NULL"); + return QDF_STATUS_E_FAILURE; + } + + txops = wlan_mlme_get_lmac_tx_ops(psoc); + if (!txops || !txops->psoc_vdev_rsp_timer_inuse) { + mlme_err("Failed to get mlme txrx_ops PSOC_%d", + wlan_psoc_get_id(psoc)); + return QDF_STATUS_E_FAILURE; + } + + status = txops->psoc_vdev_rsp_timer_inuse(psoc, wlan_vdev_get_id(vdev)); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("The vdev response is pending for VDEV_%d status:%d", + wlan_vdev_get_id(vdev), status); + return QDF_STATUS_E_FAILURE; + } + pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); if (!pdev_mlme) { - mlme_err(" PDEV MLME is NULL"); + mlme_err("PDEV MLME is NULL"); return QDF_STATUS_E_FAILURE; } @@ -103,28 +132,10 @@ static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_FAILURE; } -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE -static void mlme_vdev_obj_timer_deinit( - struct vdev_mlme_obj *vdev_mlme) -{ - struct vdev_response_timer *vdev_rsp; - - vdev_rsp = &vdev_mlme->vdev_rt; - qdf_timer_free(&vdev_rsp->rsp_timer); -} -#else -static void mlme_vdev_obj_timer_deinit( - struct vdev_mlme_obj *vdev_mlme) -{ -} -#endif static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg) { struct vdev_mlme_obj *vdev_mlme; - struct wlan_objmgr_psoc *psoc; - struct cdp_soc_t *soc_txrx_handle; - struct cdp_vdev *vdev_txrx_handle; if (!vdev) { mlme_err(" VDEV is NULL"); @@ -137,17 +148,6 @@ static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } - psoc = wlan_vdev_get_psoc(vdev); - soc_txrx_handle = (struct cdp_soc_t *)wlan_psoc_get_dp_handle(psoc); - vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); - if (soc_txrx_handle && vdev_txrx_handle) { - wlan_vdev_set_dp_handle(vdev, NULL); - cdp_vdev_detach(soc_txrx_handle, vdev_txrx_handle, - NULL, NULL); - } - - mlme_vdev_obj_timer_deinit(vdev_mlme); - mlme_vdev_sm_destroy(vdev_mlme); mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c index 3e9a4435114b75c1cec7f5ac2bddf1d7a1aac897..80ea23bc43155dffce5b964fcc6cb3f47b27aa1a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -41,6 +41,8 @@ wlan_vdev_mlme_ser_start_bss(struct wlan_serialization_command *cmd) return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; /* * Serialization command filtering logic * a. Cancel any existing start bss cmd in the pending queue @@ -77,6 +79,9 @@ wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd) mlme_err("Null input"); return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; /* * Serialization command filtering logic * a. Cancel any existing start/stop/restart command in the pending @@ -90,7 +95,7 @@ wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd) wlan_serialization_is_cmd_present_in_pending_queue(NULL, cmd); wlan_vdev_mlme_ser_cancel_request(cmd->vdev, WLAN_SER_CMD_NONSCAN, - WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD); + WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD); if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { mlme_debug("Cmd already exist in the active queue"); @@ -106,21 +111,94 @@ wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd) } enum wlan_serialization_status -wlan_vdev_mlme_ser_restart_bss(struct wlan_serialization_command *cmd) +wlan_vdev_mlme_ser_vdev_restart(struct wlan_serialization_command *cmd) { if (!cmd || !cmd->vdev) { mlme_err("Null input"); return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; + /* + * Serialization command filtering logic + * a. If there exists START or PDEV/VDEV restart command in the pending + * queue then ignore this new vdev restart request. + * b. Else enqueue the new VDEV RESTART cmd + */ + cmd->cmd_type = WLAN_SER_CMD_VDEV_START_BSS; + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, cmd)) { + mlme_debug("Start cmd already in the pending queue"); + return WLAN_SER_CMD_ALREADY_EXISTS; + } + + cmd->cmd_type = WLAN_SER_CMD_PDEV_RESTART; + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, cmd)) { + mlme_debug("Pdev restart already in the pending queue"); + return WLAN_SER_CMD_ALREADY_EXISTS; + } + + cmd->cmd_type = WLAN_SER_CMD_VDEV_RESTART; + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, cmd)) { + mlme_debug("Vdev restart already in the pending queue"); + return WLAN_SER_CMD_ALREADY_EXISTS; + } + + return wlan_serialization_request(cmd); +} + +void wlan_mlme_restart_pdev_iter_cb(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + uint8_t *pdev_restart_pending = (uint8_t *)arg; + struct wlan_serialization_command cmd = {0}; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + + cmd.vdev = vdev; + cmd.cmd_id = vdev_id; + cmd.cmd_type = WLAN_SER_CMD_PDEV_RESTART; /* * Serialization command filtering logic - * a. Cancel any existing RESTART cmd in the pending queue - * b. Enqueue the new RESTART cmd + * a. Cancel any existing VDEV restart cmd in the pending queue + * b. If Pdev restart already exist in pending queue then return else + * enqueue the new PDEV RESTART cmd */ wlan_vdev_mlme_ser_cancel_request( - cmd->vdev, + vdev, WLAN_SER_CMD_VDEV_RESTART, WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); + + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &cmd)) { + mlme_debug("Cmd already exist in the pending queue vdev:%u", + vdev_id); + *pdev_restart_pending = 1; + } +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_restart(struct wlan_serialization_command *cmd) +{ + struct wlan_objmgr_pdev *pdev; + uint8_t pdev_restart_in_pending = 0; + + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; + + pdev = wlan_vdev_get_pdev(cmd->vdev); + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_restart_pdev_iter_cb, + &pdev_restart_in_pending, 0, + WLAN_MLME_SER_IF_ID); + + if (pdev_restart_in_pending) + return WLAN_SER_CMD_ALREADY_EXISTS; + return wlan_serialization_request(cmd); } @@ -133,6 +211,9 @@ wlan_vdev_mlme_ser_connect(struct wlan_serialization_command *cmd) mlme_err("Null input"); return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; /* * Serialization command filtering logic * a. Cancel any existing CONNECT cmd in the pending queue @@ -165,16 +246,19 @@ wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd) mlme_err("Null input"); return WLAN_SER_CMD_DENIED_UNSPECIFIED; } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; /* * Serialization command filtering logic - * a.Cancel any existing CONNECT/DISCONNECT/RESTART command in the + * a.Cancel any existing non-blocking non-scan command in the * pending queue * b.If there is a DISCONNECT cmd in active queue then return * c.Else enqueue the DISCONNECT cmd */ wlan_vdev_mlme_ser_cancel_request(cmd->vdev, WLAN_SER_CMD_NONSCAN, - WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD); + WLAN_SER_CANCEL_VDEV_NON_SCAN_NB_CMD); if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) { mlme_debug("Cmd already exist in the active queue"); @@ -184,6 +268,96 @@ wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd) return wlan_serialization_request(cmd); } +static void +wlan_mlme_cancel_pending_csa_restart(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = object; + bool *csa_restart_pending = arg; + struct wlan_serialization_command cmd = {0}; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + + cmd.vdev = vdev; + cmd.cmd_id = vdev_id; + cmd.cmd_type = WLAN_SER_CMD_PDEV_CSA_RESTART; + if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &cmd)) { + mlme_debug("Cmd already exist in the pending queue vdev:%u", + vdev_id); + *csa_restart_pending = true; + } + + wlan_vdev_mlme_ser_cancel_request( + vdev, + WLAN_SER_CMD_PDEV_CSA_RESTART, + WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE); +} + +static void +wlan_mlme_check_pdev_restart(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = object; + bool *pdev_restart_pending = arg; + struct wlan_serialization_command cmd = {0}; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + + cmd.vdev = vdev; + cmd.cmd_id = vdev_id; + cmd.cmd_type = WLAN_SER_CMD_PDEV_RESTART; + if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) { + mlme_debug("Pdev restart already in the active queue vdev:%u", + vdev_id); + *pdev_restart_pending = true; + } +} + +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_csa_restart(struct wlan_serialization_command *cmd) +{ + struct wlan_objmgr_pdev *pdev; + bool csa_restart_pending = false; + bool pdev_restart_pending = false; + enum wlan_serialization_status ret; + + if (!cmd || !cmd->vdev) { + mlme_err("Null input"); + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + } + + if (!wlan_ser_is_vdev_queue_enabled(cmd->vdev)) + return WLAN_SER_CMD_QUEUE_DISABLED; + + /* + * Serialization command filtering logic + * a. Cancel any existing PDEV CSA restart cmd in the pending queue + * b. If there exists PDEV RESTART command in the active queue + * then deny this request + * c. If PDEV CSA RESTART cmd already existed in pending queue + * then enqueue and return already exists + * d. Else enqueue this PDEV CSA RESTART cmd + */ + pdev = wlan_vdev_get_pdev(cmd->vdev); + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_cancel_pending_csa_restart, + &csa_restart_pending, 0, + WLAN_MLME_SER_IF_ID); + + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + wlan_mlme_check_pdev_restart, + &pdev_restart_pending, 0, + WLAN_MLME_SER_IF_ID); + + if (pdev_restart_pending) + return WLAN_SER_CMD_DENIED_UNSPECIFIED; + + ret = wlan_serialization_request(cmd); + + if (csa_restart_pending && ret == WLAN_SER_CMD_PENDING) + return WLAN_SER_CMD_ALREADY_EXISTS; + + return ret; +} + void wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev, uint32_t cmd_id, @@ -191,7 +365,7 @@ wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev, { struct wlan_serialization_queued_cmd_info cmd = {0}; - mlme_debug("Remove the cmd type:%d", cmd_type); + mlme_debug("Vdev:%d remove cmd:%d", wlan_vdev_get_id(vdev), cmd_type); cmd.vdev = vdev; cmd.cmd_id = cmd_id; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h index ba4cb3461fd084a676343ad7a6e9bfa252707c35..4f90e3080690a10a20f942a6b2d79b4b62be7795 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,13 +49,22 @@ enum wlan_serialization_status wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd); /** - * wlan_vdev_mlme_ser_restart_bss() - Add restart bss cmd to serialization + * wlan_vdev_mlme_ser_vdev_restart() - Add vdev restart cmd to serialization * @cmd: Serialization command * * Return: Status of enqueue in the serialization module */ enum wlan_serialization_status -wlan_vdev_mlme_ser_restart_bss(struct wlan_serialization_command *cmd); +wlan_vdev_mlme_ser_vdev_restart(struct wlan_serialization_command *cmd); + +/** + * wlan_vdev_mlme_ser_pdev_restart() - Add pdev restart cmd to serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_restart(struct wlan_serialization_command *cmd); /** * wlan_vdev_mlme_ser_connect() - Add connect cmd to serialization @@ -110,4 +119,14 @@ wlan_vdev_mlme_ser_cancel_request(struct wlan_objmgr_vdev *vdev, */ void mlme_ser_inc_act_cmd_timeout(struct wlan_serialization_command *cmd); +/** + * wlan_vdev_mlme_ser_pdev_csa_restart - Add pdev CSA restart cmd to + * serialization + * @cmd: Serialization command + * + * Return: Status of enqueue in the serialization module + */ +enum wlan_serialization_status +wlan_vdev_mlme_ser_pdev_csa_restart(struct wlan_serialization_command *cmd); + #endif /* _WLAN_VDEV_MLME_SER_IF_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/inc/wlan_pdev_mlme_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/inc/wlan_pdev_mlme_api.h index 739832a4b10e3d39b811af8048dc03810b4761ee..4b99fd081274276c5716917bb57e1e7a25a7041a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/inc/wlan_pdev_mlme_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/inc/wlan_pdev_mlme_api.h @@ -23,6 +23,7 @@ /** * wlan_pdev_mlme_get_cmpt_obj - Returns MLME component object + * @pdev: PDEV object * * Retrieves MLME component object from PDEV object * @@ -33,12 +34,13 @@ struct pdev_mlme_obj *wlan_pdev_mlme_get_cmpt_obj( struct wlan_objmgr_pdev *pdev); /** * wlan_pdev_mlme_get_ext_hdl - Returns legacy handle + * @pdev: PDEV object * * Retrieves legacy handle from pdev mlme component object * * Return: legacy handle on SUCCESS * NULL, if it fails to retrieve */ -void *wlan_pdev_mlme_get_ext_hdl(struct wlan_objmgr_pdev *pdev); +mlme_pdev_ext_t *wlan_pdev_mlme_get_ext_hdl(struct wlan_objmgr_pdev *pdev); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/src/wlan_pdev_mlme_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/src/wlan_pdev_mlme_api.c index 03b04ac61efaf6bb93a8d863433cb1c6e54109c8..87973069bef9aa7329526b64947c269bc7b90458 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/src/wlan_pdev_mlme_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/pdev_mgr/dispatcher/src/wlan_pdev_mlme_api.c @@ -43,7 +43,7 @@ struct pdev_mlme_obj *wlan_pdev_mlme_get_cmpt_obj(struct wlan_objmgr_pdev *pdev) return pdev_mlme; } -void *wlan_pdev_mlme_get_ext_hdl(struct wlan_objmgr_pdev *pdev) +mlme_pdev_ext_t *wlan_pdev_mlme_get_ext_hdl(struct wlan_objmgr_pdev *pdev) { struct pdev_mlme_obj *pdev_mlme; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/inc/wlan_psoc_mlme_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/inc/wlan_psoc_mlme_api.h new file mode 100644 index 0000000000000000000000000000000000000000..f9911ab14c77d3704a5bb090e52ebe0a723fb0cc --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/inc/wlan_psoc_mlme_api.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Define PSOC MLME public APIs + */ + +#ifndef _WLAN_PSOC_MLME_API_H_ +#define _WLAN_PSOC_MLME_API_H_ + +/** + * wlan_psoc_mlme_get_cmpt_obj() - Returns PSOC MLME component object + * @psoc: PSOC object + * + * Retrieves MLME component object from PSOC object + * + * Return: comp handle on SUCCESS + * NULL, if it fails to retrieve + */ +struct psoc_mlme_obj *wlan_psoc_mlme_get_cmpt_obj( + struct wlan_objmgr_psoc *psoc); + +/** + * wlan_psoc_mlme_get_ext_hdl() - Returns legacy handle + * @psoc: PSOC object + * + * Retrieves legacy handle from psoc mlme component object + * + * Return: legacy handle on SUCCESS + * NULL, if it fails to retrieve + */ +mlme_psoc_ext_t *wlan_psoc_mlme_get_ext_hdl(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_psoc_mlme_set_ext_hdl() - Set legacy handle + * @psoc_mlme: psoc_mlme object + * psoc_ext_hdl: PSOC level legacy handle + * + * Sets legacy handle in psoc mlme component object + * + * Return: Void + */ +void wlan_psoc_mlme_set_ext_hdl(struct psoc_mlme_obj *psoc_mlme, + mlme_psoc_ext_t *psoc_ext_hdl); + +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c new file mode 100644 index 0000000000000000000000000000000000000000..508d017531b519711c16e1b95ad4555efe6c3942 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/psoc_mgr/dispatcher/src/wlan_psoc_mlme_api.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Implements PSOC MLME public APIs + */ + +#include +#include +#include +#include +#include + +struct psoc_mlme_obj *wlan_psoc_mlme_get_cmpt_obj(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *psoc_mlme; + + psoc_mlme = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_MLME); + if (!psoc_mlme) { + mlme_err("PSOC MLME component object is NULL"); + return NULL; + } + + return psoc_mlme; +} + +qdf_export_symbol(wlan_psoc_mlme_get_cmpt_obj); + +mlme_psoc_ext_t *wlan_psoc_mlme_get_ext_hdl(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *psoc_mlme; + + psoc_mlme = wlan_psoc_mlme_get_cmpt_obj(psoc); + if (psoc_mlme) + return psoc_mlme->ext_psoc_ptr; + + return NULL; +} + +qdf_export_symbol(wlan_psoc_mlme_get_ext_hdl); + +void wlan_psoc_mlme_set_ext_hdl(struct psoc_mlme_obj *psoc_mlme, + mlme_psoc_ext_t *psoc_ext_hdl) +{ + psoc_mlme->ext_psoc_ptr = psoc_ext_hdl; +} + +qdf_export_symbol(wlan_psoc_mlme_set_ext_hdl); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c index fa3002c7689af8d6a9ad3752304b430d8bc8f5e8..7d3bc3c9350ec46f4156e62353bf82ddf0f92c3c 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,6 +34,7 @@ #include #include #include +#include static QDF_STATUS vdev_mgr_create_param_update( struct vdev_mlme_obj *mlme_obj, @@ -98,6 +99,7 @@ static QDF_STATUS vdev_mgr_start_param_update( bool set_agile = false, dfs_set_cfreq2 = false; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_pdev *pdev; + enum QDF_OPMODE op_mode; vdev = mlme_obj->vdev; if (!vdev) { @@ -120,13 +122,23 @@ static QDF_STATUS vdev_mgr_start_param_update( des_chan = wlan_vdev_mlme_get_des_chan(vdev); param->vdev_id = wlan_vdev_get_id(vdev); - tgt_dfs_set_current_channel(pdev, des_chan->ch_freq, - des_chan->ch_flags, - des_chan->ch_flagext, - des_chan->ch_ieee, - des_chan->ch_freq_seg1, - des_chan->ch_freq_seg2); - + op_mode = wlan_vdev_mlme_get_opmode(vdev); + if ((op_mode == QDF_SAP_MODE || op_mode == QDF_P2P_GO_MODE) && + (WLAN_REG_IS_5GHZ_CH_FREQ(des_chan->ch_freq) || + WLAN_REG_IS_49GHZ_FREQ(des_chan->ch_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(des_chan->ch_freq))) { + tgt_dfs_set_current_channel_for_freq(pdev, des_chan->ch_freq, + des_chan->ch_flags, + des_chan->ch_flagext, + des_chan->ch_ieee, + des_chan->ch_freq_seg1, + des_chan->ch_freq_seg2, + des_chan->ch_cfreq1, + des_chan->ch_cfreq2); + if (des_chan->ch_cfreq2) + param->channel.dfs_set_cfreq2 = + utils_is_dfs_cfreq2_ch(pdev); + } param->beacon_interval = mlme_obj->proto.generic.beacon_interval; param->dtim_period = mlme_obj->proto.generic.dtim_period; param->disable_hw_ack = mlme_obj->mgmt.generic.disable_hw_ack; @@ -144,10 +156,14 @@ static QDF_STATUS vdev_mgr_start_param_update( param->channel.mhz = des_chan->ch_freq; param->channel.half_rate = mlme_obj->mgmt.rate_info.half_rate; param->channel.quarter_rate = mlme_obj->mgmt.rate_info.quarter_rate; - param->channel.dfs_set = utils_is_dfs_ch(pdev, param->channel.chan_id); - param->channel.dfs_set_cfreq2 = utils_is_dfs_cfreq2_ch(pdev); + + if (op_mode == QDF_SAP_MODE || op_mode == QDF_P2P_GO_MODE) + param->channel.dfs_set = wlan_reg_is_dfs_for_freq( + pdev, + des_chan->ch_freq); + param->channel.is_chan_passive = - utils_is_dfs_ch(pdev, param->channel.chan_id); + utils_is_dfs_chan_for_freq(pdev, param->channel.mhz); param->channel.allow_ht = mlme_obj->proto.ht_info.allow_ht; param->channel.allow_vht = mlme_obj->proto.vht_info.allow_vht; param->channel.phy_mode = mlme_obj->mgmt.generic.phy_mode; @@ -158,22 +174,25 @@ static QDF_STATUS vdev_mgr_start_param_update( param->channel.maxregpower = mlme_obj->mgmt.generic.maxregpower; param->channel.antennamax = mlme_obj->mgmt.generic.antennamax; param->channel.reg_class_id = mlme_obj->mgmt.generic.reg_class_id; - param->bcn_tx_rate_code = mlme_obj->mgmt.rate_info.bcn_tx_rate; + param->bcn_tx_rate_code = vdev_mgr_fetch_ratecode(mlme_obj); param->ldpc_rx_enabled = mlme_obj->proto.generic.ldpc; + if (mlme_obj->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_AP) { + param->hidden_ssid = mlme_obj->mgmt.ap.hidden_ssid; + param->cac_duration_ms = mlme_obj->mgmt.ap.cac_duration_ms; + } wlan_vdev_mlme_get_ssid(vdev, param->ssid.mac_ssid, ¶m->ssid.length); if (des_chan->ch_phymode == WLAN_PHYMODE_11AC_VHT80 || des_chan->ch_phymode == WLAN_PHYMODE_11AXA_HE80) { - tgt_dfs_find_vht80_chan_for_precac(pdev, - des_chan->ch_phymode, - des_chan->ch_freq_seg1, - ¶m->channel.cfreq1, - ¶m->channel.cfreq2, - ¶m->channel.phy_mode, - &dfs_set_cfreq2, - &set_agile); - + tgt_dfs_find_vht80_precac_chan_freq(pdev, + des_chan->ch_phymode, + des_chan->ch_freq_seg1, + ¶m->channel.cfreq1, + ¶m->channel.cfreq2, + ¶m->channel.phy_mode, + &dfs_set_cfreq2, + &set_agile); param->channel.dfs_set_cfreq2 = dfs_set_cfreq2; param->channel.set_agile = set_agile; } @@ -330,6 +349,8 @@ QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj) struct beacon_tmpl_params bcn_tmpl_param = {0}; enum QDF_OPMODE opmode; struct wlan_objmgr_vdev *vdev; + struct config_fils_params fils_param = {0}; + uint8_t is_6g_sap_fd_enabled; if (!mlme_obj) { mlme_err("VDEV_MLME is NULL"); @@ -357,6 +378,25 @@ QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj) return status; status = tgt_vdev_mgr_up_send(mlme_obj, ¶m); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + is_6g_sap_fd_enabled = wlan_vdev_mlme_feat_ext_cap_get(vdev, + WLAN_VDEV_FEXT_FILS_DISC_6G_SAP); + mlme_debug("SAP FD enabled %d", is_6g_sap_fd_enabled); + if (opmode == QDF_SAP_MODE && mlme_obj->vdev->vdev_mlme.des_chan && + WLAN_REG_IS_6GHZ_CHAN_FREQ( + mlme_obj->vdev->vdev_mlme.des_chan->ch_freq)) { + fils_param.vdev_id = wlan_vdev_get_id(mlme_obj->vdev); + if (is_6g_sap_fd_enabled) { + fils_param.fd_period = DEFAULT_FILS_DISCOVERY_PERIOD; + } else { + fils_param.send_prb_rsp_frame = true; + fils_param.fd_period = DEFAULT_PROBE_RESP_PERIOD; + } + status = tgt_vdev_mgr_fils_enable_send(mlme_obj, + &fils_param); + } return status; } @@ -449,6 +489,7 @@ static QDF_STATUS vdev_mgr_multiple_restart_param_update( uint32_t disable_hw_ack, uint32_t *vdev_ids, uint32_t num_vdevs, + struct vdev_mlme_mvr_param *mvr_param, struct multiple_vdev_restart_params *param) { param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); @@ -461,6 +502,8 @@ static QDF_STATUS vdev_mgr_multiple_restart_param_update( sizeof(uint32_t) * (param->num_vdevs)); qdf_mem_copy(¶m->ch_param, chan, sizeof(struct mlme_channel_param)); + qdf_mem_copy(param->mvr_param, mvr_param, + sizeof(*mvr_param) * (param->num_vdevs)); return QDF_STATUS_SUCCESS; } @@ -469,14 +512,15 @@ QDF_STATUS vdev_mgr_multiple_restart_send(struct wlan_objmgr_pdev *pdev, struct mlme_channel_param *chan, uint32_t disable_hw_ack, uint32_t *vdev_ids, - uint32_t num_vdevs) + uint32_t num_vdevs, + struct vdev_mlme_mvr_param *mvr_param) { struct multiple_vdev_restart_params param = {0}; vdev_mgr_multiple_restart_param_update(pdev, chan, disable_hw_ack, vdev_ids, num_vdevs, - ¶m); + mvr_param, ¶m); return tgt_vdev_mgr_multiple_vdev_restart_send(pdev, ¶m); } @@ -526,3 +570,41 @@ QDF_STATUS vdev_mgr_set_custom_aggr_size_send( return tgt_vdev_mgr_set_custom_aggr_size_send(vdev_mlme, ¶m); } + +static QDF_STATUS vdev_mgr_peer_delete_all_param_update( + struct vdev_mlme_obj *mlme_obj, + struct peer_delete_all_params *param) +{ + struct wlan_objmgr_vdev *vdev; + + vdev = mlme_obj->vdev; + if (!vdev) { + mlme_err("VDEV is NULL"); + return QDF_STATUS_E_INVAL; + } + + param->vdev_id = wlan_vdev_get_id(vdev); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS vdev_mgr_peer_delete_all_send(struct vdev_mlme_obj *mlme_obj) +{ + QDF_STATUS status; + struct peer_delete_all_params param = {0}; + + if (!mlme_obj) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + status = vdev_mgr_peer_delete_all_param_update(mlme_obj, ¶m); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Param Update Error: %d", status); + return status; + } + + status = tgt_vdev_mgr_peer_delete_all_send(mlme_obj, ¶m); + + return status; +} + diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h index 9ce437d87cbd03f34a2b0ad331b480d3c17e7125..f6461213aba55da257b950650f2142d79700f24e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,7 +26,6 @@ #ifndef __VDEV_MGR_OPS_H__ #define __VDEV_MGR_OPS_H__ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include #include #include @@ -220,14 +219,35 @@ QDF_STATUS vdev_mgr_bcn_miss_offload_send(struct vdev_mlme_obj *mlme_obj); * @disable_hw_ack: ddisable hw ack value * @vdev_ids: pointer to list of vdev ids which require restart * @num_vdevs: number of vdevs in list + * @mvr_param: multiple vdev restart param * * Return: QDF_STATUS - Success or Failure */ -QDF_STATUS vdev_mlme_multiple_restart_send(struct wlan_objmgr_pdev *pdev, - struct mlme_channel_param *chan, - uint32_t disable_hw_ack, - uint32_t *vdev_ids, - uint32_t num_vdevs); +QDF_STATUS vdev_mgr_multiple_restart_send( + struct wlan_objmgr_pdev *pdev, + struct mlme_channel_param *chan, + uint32_t disable_hw_ack, + uint32_t *vdev_ids, + uint32_t num_vdevs, + struct vdev_mlme_mvr_param *mvr_param); -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ +/** + * vdev_mgr_peer_delete_all_send() – MLME API to send peer delete all request + * @mlme_obj: pointer to vdev_mlme_obj + * + * Return: QDF_STATUS - Success or Failure + */ +QDF_STATUS vdev_mgr_peer_delete_all_send(struct vdev_mlme_obj *mlme_obj); + +#ifdef WLAN_BCN_RATECODE_ENABLE +static inline uint32_t vdev_mgr_fetch_ratecode(struct vdev_mlme_obj *mlme_obj) +{ + return mlme_obj->mgmt.rate_info.bcn_tx_rate_code; +} +#else +static inline uint32_t vdev_mgr_fetch_ratecode(struct vdev_mlme_obj *mlme_obj) +{ + return mlme_obj->mgmt.rate_info.bcn_tx_rate; +} +#endif #endif /* __VDEV_MGR_OPS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c index b512e6e6d665a8270c5f342ebf69d43f2c345f43..47d178eb3af52f870a9fe4b72e650ba887a15e3e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.c @@ -920,7 +920,12 @@ static bool mlme_vdev_subst_start_conn_progress_event(void *ctx, case WLAN_VDEV_SM_EV_CONN_PROGRESS: /* This API decides to move to DFS CAC WAIT or UP state, * for station notify connection state machine */ - mlme_vdev_start_continue(vdev_mlme, event_data_len, event_data); + if (mlme_vdev_start_continue(vdev_mlme, event_data_len, + event_data) != QDF_STATUS_SUCCESS) + mlme_vdev_sm_deliver_event( + vdev_mlme, + WLAN_VDEV_SM_EV_CONNECTION_FAIL, + event_data_len, event_data); status = true; break; @@ -1369,6 +1374,19 @@ static bool mlme_vdev_subst_suspend_csa_restart_event(void *ctx, bool status; switch (event) { + case WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED: + /** + * This event is sent when CSA count becomes 0 without + * change in channel i.e. only Beacon Probe response template + * is updated (CSA / ECSA IE is removed). + */ + + mlme_vdev_sm_transition_to(vdev_mlme, WLAN_VDEV_S_UP); + mlme_vdev_sm_deliver_event(vdev_mlme, + WLAN_VDEV_SM_EV_UP_HOST_RESTART, + event_data_len, event_data); + status = true; + break; case WLAN_VDEV_SM_EV_CSA_RESTART: mlme_vdev_update_beacon(vdev_mlme, BEACON_CSA, event_data_len, event_data); @@ -1635,6 +1653,7 @@ static const char *vdev_sm_event_names[] = { "EV_DOWN_COMPLETE", "EV_ROAM", "EV_STOP_REQ", + "EV_CHAN_SWITCH_DISABLED", }; struct wlan_sm_state_info sm_info[] = { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h index 22ecfcd71f2ddc1891e154582e2c3d98eee5ff74..deb784b49a122b3d5a1808cf5b89eed77049fb68 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -97,6 +97,489 @@ QDF_STATUS mlme_vdev_sm_create(struct vdev_mlme_obj *vdev_mlme); */ QDF_STATUS mlme_vdev_sm_destroy(struct vdev_mlme_obj *vdev_mlme); +/** + * mlme_vdev_validate_basic_params - Validate basic params + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API validate MLME VDEV basic parameters + * + * Return: SUCCESS on successful validation + * FAILURE, if any parameter is not initialized + */ +static inline QDF_STATUS mlme_vdev_validate_basic_params( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_validate_basic_params) + ret = vdev_mlme->ops->mlme_vdev_validate_basic_params( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_reset_proto_params - Reset VDEV protocol params + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API resets the protocol params fo vdev + * + * Return: SUCCESS on successful reset + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_reset_proto_params( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_reset_proto_params) + ret = vdev_mlme->ops->mlme_vdev_reset_proto_params( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_start_send - Invokes VDEV start operation + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV start operation + * + * Return: SUCCESS on successful completion of start operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_start_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_send) + ret = vdev_mlme->ops->mlme_vdev_start_send( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_restart_send - Invokes VDEV restart operation + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV restart operation + * + * Return: SUCCESS on successful completion of restart operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_restart_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_restart_send) + ret = vdev_mlme->ops->mlme_vdev_restart_send( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_stop_start_send - Invoke block VDEV restart operation + * @vdev_mlme_obj: VDEV MLME comp object + * @restart: restart req/start req + * @event_data_len: data size + * @event_data: event data + * + * API invokes stops pending VDEV restart operation + * + * Return: SUCCESS alsways + */ +static inline QDF_STATUS mlme_vdev_stop_start_send( + struct vdev_mlme_obj *vdev_mlme, + uint8_t restart, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_start_send) + ret = vdev_mlme->ops->mlme_vdev_stop_start_send( + vdev_mlme, restart, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_start_continue - VDEV start response handling + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV start response actions + * + * Return: SUCCESS on successful completion of start response operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_start_continue( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_continue) + ret = vdev_mlme->ops->mlme_vdev_start_continue( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_start_req_failed - Invoke Station VDEV connection, if it pause + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes on START fail response + * + * Return: SUCCESS on successful invocation of callback + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_start_req_failed( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_start_req_failed) + ret = vdev_mlme->ops->mlme_vdev_start_req_failed( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_sta_conn_start - Invoke Station VDEV connection, if it pause + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes connection SM to start station connection + * + * Return: SUCCESS on successful invocation of connection sm + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_sta_conn_start( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_sta_conn_start) + ret = vdev_mlme->ops->mlme_vdev_sta_conn_start( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_up_send - VDEV up operation + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV up operations + * + * Return: SUCCESS on successful completion of up operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_up_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_up_send) + ret = vdev_mlme->ops->mlme_vdev_up_send( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_notify_up_complete - VDEV up state transition notification + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API notifies MLME on moving to UP state + * + * Return: SUCCESS on successful completion of up notification + * FAILURE, if it fails due to any + */ +static inline +QDF_STATUS mlme_vdev_notify_up_complete(struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, + void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_notify_up_complete) + ret = vdev_mlme->ops->mlme_vdev_notify_up_complete( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_notify_roam_start - VDEV Roaming notification + * @vdev_mlme_obj: VDEV MLME comp object + * @event_len: data size + * @event_data: event data + * + * API notifies MLME on roaming + * + * Return: SUCCESS on successful completion of up notification + * FAILURE, if it fails due to any + */ +static inline +QDF_STATUS mlme_vdev_notify_roam_start(struct vdev_mlme_obj *vdev_mlme, + uint16_t event_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_notify_roam_start) + ret = vdev_mlme->ops->mlme_vdev_notify_roam_start(vdev_mlme, + event_len, + event_data); + + return ret; +} + +/** + * mlme_vdev_update_beacon - Updates beacon + * @vdev_mlme_obj: VDEV MLME comp object + * @op: beacon update type + * @event_data_len: data size + * @event_data: event data + * + * API updates/allocates/frees the beacon + * + * Return: SUCCESS on successful update of beacon + * FAILURE, if it fails due to any + */ +static inline +QDF_STATUS mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme, + enum beacon_update_op op, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if (vdev_mlme->ops && vdev_mlme->ops->mlme_vdev_update_beacon) + ret = vdev_mlme->ops->mlme_vdev_update_beacon(vdev_mlme, op, + event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_disconnect_peers - Disconnect peers + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API trigger stations disconnection with AP VDEV or AP disconnection with STA + * VDEV + * + * Return: SUCCESS on successful invocation of station disconnection + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_disconnect_peers( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_disconnect_peers) + ret = vdev_mlme->ops->mlme_vdev_disconnect_peers( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_dfs_cac_timer_stop - Stop CAC timer + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API stops the CAC timer through DFS API + * + * Return: SUCCESS on successful CAC timer stop + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_dfs_cac_timer_stop( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_dfs_cac_timer_stop) + ret = vdev_mlme->ops->mlme_vdev_dfs_cac_timer_stop( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_stop_send - Invokes VDEV stop operation + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV stop operation + * + * Return: SUCCESS on successful completion of stop operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_stop_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_send) + ret = vdev_mlme->ops->mlme_vdev_stop_send( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_stop_continue - VDEV stop response handling + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV stop response actions + * + * Return: SUCCESS on successful completion of stop response operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_stop_continue( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_stop_continue) + ret = vdev_mlme->ops->mlme_vdev_stop_continue(vdev_mlme, + event_data_len, + event_data); + + return ret; +} + +/** + * mlme_vdev_down_send - VDEV down operation + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API invokes VDEV down operation + * + * Return: SUCCESS on successful completion of VDEV down operation + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_down_send( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_down_send) + ret = vdev_mlme->ops->mlme_vdev_down_send( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_notify_down_complete - VDEV init state transition notification + * @vdev_mlme_obj: VDEV MLME comp object + * @event_data_len: data size + * @event_data: event data + * + * API notifies MLME on moving to INIT state + * + * Return: SUCCESS on successful completion of down notification + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_notify_down_complete( + struct vdev_mlme_obj *vdev_mlme, + uint16_t event_data_len, void *event_data) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_notify_down_complete) + ret = vdev_mlme->ops->mlme_vdev_notify_down_complete( + vdev_mlme, event_data_len, event_data); + + return ret; +} + +/** + * mlme_vdev_notify_start_state_exit - VDEV SM start state exit notification + * @vdev_mlme_obj: VDEV MLME comp object + * + * API notifies on start state exit + * + * Return: SUCCESS on successful completion of notification + * FAILURE, if it fails due to any + */ +static inline QDF_STATUS mlme_vdev_notify_start_state_exit( + struct vdev_mlme_obj *vdev_mlme) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && + vdev_mlme->ops->mlme_vdev_notify_start_state_exit) + ret = vdev_mlme->ops->mlme_vdev_notify_start_state_exit( + vdev_mlme); + + return ret; +} + +/** + * mlme_vdev_is_newchan_no_cac - Checks new channel requires CAC + * @vdev_mlme_obj: VDEV MLME comp object + * + * API checks whether Channel needs CAC period, + * if yes, it moves to SUSPEND_RESTART to disconnect stations before + * sending RESTART to FW, otherwise, it moves to RESTART_PROGRESS substate + * + * Return: SUCCESS to move to RESTART_PROGRESS substate + * FAILURE, move to SUSPEND_RESTART state + */ +static inline QDF_STATUS mlme_vdev_is_newchan_no_cac( + struct vdev_mlme_obj *vdev_mlme) +{ + QDF_STATUS ret = QDF_STATUS_SUCCESS; + + if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_is_newchan_no_cac) + ret = vdev_mlme->ops->mlme_vdev_is_newchan_no_cac(vdev_mlme); + + return ret; +} + #ifdef VDEV_SM_LOCK_SUPPORT /** * mlme_vdev_sm_spinlock_create - Create VDEV MLME spinlock @@ -208,13 +691,13 @@ static inline void mlme_vdev_cmd_mutex_release(struct vdev_mlme_obj *vdev_mlme) #else static inline void mlme_vdev_sm_spinlock_create(struct vdev_mlme_obj *vdev_mlme) { - mlme_info("VDEV SM lock is disabled!!!"); + mlme_debug("VDEV SM lock is disabled!!!"); } static inline void mlme_vdev_sm_spinlock_destroy( struct vdev_mlme_obj *vdev_mlme) { - mlme_info("VDEV SM lock is disabled!!!"); + mlme_debug("VDEV SM lock is disabled!!!"); } static inline void mlme_vdev_sm_spin_lock(struct vdev_mlme_obj *vdev_mlme) @@ -228,13 +711,13 @@ static inline void mlme_vdev_sm_spin_unlock(struct vdev_mlme_obj *vdev_mlme) static inline void mlme_vdev_cmd_mutex_create(struct vdev_mlme_obj *vdev_mlme) { - mlme_info("VDEV CMD lock is disabled!!!"); + mlme_debug("VDEV CMD lock is disabled!!!"); } static inline void mlme_vdev_cmd_mutex_destroy(struct vdev_mlme_obj *vdev_mlme) { - mlme_info("VDEV CMD lock is disabled!!!"); + mlme_debug("VDEV CMD lock is disabled!!!"); } static inline void mlme_vdev_cmd_mutex_acquire(struct vdev_mlme_obj *vdev_mlme) diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_api.h index b8b650566f50d4082eb30614bd3d7a6e064bbf72..893b76185aed147cb4714d75ac126ddbbfebed37 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_api.h @@ -25,26 +25,37 @@ #ifndef __WLAN_VDEV_MGR_RX_OPS_H__ #define __WLAN_VDEV_MGR_RX_OPS_H__ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include #include /** - * tgt_vdev_mgr_register_rx_ops(): API to register rx ops with lmac + * tgt_vdev_mgr_register_rx_ops() - API to register rx ops with lmac * @rx_ops: rx ops struct * * Return: none */ void tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops); -#else + /** - * tgt_vdev_mgr_register_rx_ops(): API to register rx ops with lmac - * @rx_ops: rx ops struct + * tgt_vdev_mgr_ext_tbttoffset_update_handle() - API to handle ext tbtt offset + * update event + * @num_vdevs: number of vdevs + * @is_ext: ext is set/reset * - * Return: none + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +tgt_vdev_mgr_ext_tbttoffset_update_handle(uint32_t num_vdevs, bool is_ext); + +/** + * tgt_vdev_mgr_get_response_timer_info() - API to get vdev_mgr timer info + * @psoc: objmgr psoc object + * @vdev_id: vdev id + * + * Return: struct vdev_response_timer on success else NULL */ -static inline void -tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) {} -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ +struct vdev_response_timer * +tgt_vdev_mgr_get_response_timer_info(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif /* __WLAN_VDEV_MGR_RX_OPS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h index 2dce8e791034e545eca83933507c0a2af06215be..4495ae8c3bad852c47ab27678615f2646e289166 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,30 +27,77 @@ #define __WLAN_VDEV_MGR_TGT_IF_RX_DEFS_H__ #include +#include +#ifdef FEATURE_RUNTIME_PM +#include +#endif -#define START_RESPONSE_BIT 0x1 -#define RESTART_RESPONSE_BIT 0x2 -#define STOP_RESPONSE_BIT 0x3 -#define DELETE_RESPONSE_BIT 0x4 -#define RESPONSE_BIT_MAX (START_RESPONSE_BIT | RESTART_RESPONSE_BIT |\ - STOP_RESPONSE_BIT | DELETE_RESPONSE_BIT) +/** + * enum wlan_vdev_mgr_tgt_if_rsp_bit - response status bit + * START_RESPONSE_BIT: vdev start response bit + * RESTART_RESPONSE_BIT: vdev restart response bit + * STOP_RESPONSE_BIT: vdev stop response bit + * DELETE_RESPONSE_BIT: vdev delete response bit + * PEER_DELETE_ALL_RESPONSE_BIT: vdev peer delete all response bit + */ +enum wlan_vdev_mgr_tgt_if_rsp_bit { + START_RESPONSE_BIT = 0, + RESTART_RESPONSE_BIT = 1, + STOP_RESPONSE_BIT = 2, + DELETE_RESPONSE_BIT = 3, + PEER_DELETE_ALL_RESPONSE_BIT = 4, + RESPONSE_BIT_MAX, +}; -#define START_RESPONSE_TIMER 6000 /* 6 seconds */ -#define STOP_RESPONSE_TIMER 3000 /* 3 seconds */ -#define DELETE_RESPONSE_TIMER 3000 /* 3 seconds */ +/** + * string_from_rsp_bit() - Convert response bit to string + * @bit - response bit as in wlan_vdev_mgr_tgt_if_rsp_bit + * + * Please note to add new string in the array at index equal to + * its enum value in wlan_vdev_mgr_tgt_if_rsp_bit. + */ +static inline char *string_from_rsp_bit(enum wlan_vdev_mgr_tgt_if_rsp_bit bit) +{ + static const char *strings[] = { "START", + "RESTART", + "STOP", + "DELETE", + "PEER DELETE ALL", + "RESPONE MAX"}; + return (char *)strings[bit]; +} + +#ifdef FEATURE_RUNTIME_PM +/* Add extra PMO_RESUME_TIMEOUT for runtime PM resume timeout */ +#define START_RESPONSE_TIMER (6000 + PMO_RESUME_TIMEOUT) +#define STOP_RESPONSE_TIMER (4000 + PMO_RESUME_TIMEOUT) +#define DELETE_RESPONSE_TIMER (4000 + PMO_RESUME_TIMEOUT) +#define PEER_DELETE_ALL_RESPONSE_TIMER (6000 + PMO_RESUME_TIMEOUT) +#else +#define START_RESPONSE_TIMER 6000 +#define STOP_RESPONSE_TIMER 4000 +#define DELETE_RESPONSE_TIMER 4000 +#define PEER_DELETE_ALL_RESPONSE_TIMER 6000 +#endif /** * struct vdev_response_timer - vdev mgmt response ops timer + * @psoc: Object manager psoc * @rsp_timer: VDEV MLME mgmt response timer * @rsp_status: variable to check response status * @expire_time: time to expire timer * @timer_status: status of timer + * @rsp_timer_inuse: Status bit to inform whether the rsp timer is inuse + * @vdev_id: vdev object id */ struct vdev_response_timer { + struct wlan_objmgr_psoc *psoc; qdf_timer_t rsp_timer; unsigned long rsp_status; uint32_t expire_time; QDF_STATUS timer_status; + qdf_atomic_t rsp_timer_inuse; + uint8_t vdev_id; }; /** @@ -64,6 +111,7 @@ struct vdev_response_timer { * @mac_id: mac id * @cfgd_tx_streams: configured tx streams * @cfgd_rx_streams: configured rx streams + * @max_allowed_tx_power: max tx power allowed */ struct vdev_start_response { uint8_t vdev_id; @@ -75,6 +123,7 @@ struct vdev_start_response { uint32_t mac_id; uint32_t cfgd_tx_streams; uint32_t cfgd_rx_streams; + uint32_t max_allowed_tx_power; }; /** @@ -93,4 +142,27 @@ struct vdev_delete_response { uint8_t vdev_id; }; +/** + * struct peer_delete_all_response - peer delete all response structure + * @vdev_id: vdev id + * @status: FW status for vdev delete all peer request + */ +struct peer_delete_all_response { + uint8_t vdev_id; + uint8_t status; +}; + +#define VDEV_ID_BMAP_SIZE 2 +/** + * struct multi_vdev_restart_resp - multi-vdev restart response structure + * @pdev_id: pdev id + * @status: FW status for multi vdev restart request + * @vdev_id_bmap: Bitmap of vdev_ids + */ +struct multi_vdev_restart_resp { + uint8_t pdev_id; + uint8_t status; + unsigned long vdev_id_bmap[VDEV_ID_BMAP_SIZE]; +}; + #endif /* __WLAN_VDEV_MGR_TGT_IF_RX_DEFS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h index bb50fefbcaaee0f1565c038a71bb6cebd4803b71..ddca045633c64707a9b01e9b4fca1eb948c793c2 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h @@ -27,7 +27,6 @@ #ifndef __WLAN_VDEV_MGR_TX_OPS_API_H__ #define __WLAN_VDEV_MGR_TX_OPS_API_H__ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include #include #include @@ -222,6 +221,33 @@ QDF_STATUS tgt_vdev_mgr_beacon_tmpl_send( struct vdev_mlme_obj *mlme_obj, struct beacon_tmpl_params *param); +#if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) +/** + * tgt_vdev_mgr_fils_enable_send()- API to send fils enable command + * @mlme_obj: pointer to vdev_mlme_obj + * @param: pointer to config_fils_params struct + * + * Return: QDF_STATUS - Success or Failure + */ +QDF_STATUS tgt_vdev_mgr_fils_enable_send( + struct vdev_mlme_obj *mlme_obj, + struct config_fils_params *param); +#else +/** + * tgt_vdev_mgr_fils_enable_send()- API to send fils enable command + * @mlme_obj: pointer to vdev_mlme_obj + * @param: pointer to config_fils_params struct + * + * Return: QDF_STATUS - Success or Failure + */ +static inline QDF_STATUS tgt_vdev_mgr_fils_enable_send( + struct vdev_mlme_obj *mlme_obj, + struct config_fils_params *param) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * tgt_vdev_mgr_multiple_vdev_restart_send() – API to send multiple vdev * restart @@ -234,6 +260,18 @@ QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( struct wlan_objmgr_pdev *pdev, struct multiple_vdev_restart_params *param); +/** + * tgt_vdev_mgr_set_tx_rx_decap_type() – API to send tx rx decap type + * @mlme_obj: pointer to vdev mlme obj + * @param_id: param id + * value: value to set for param id + * + * Return: QDF_STATUS - Success or Failure + */ +QDF_STATUS tgt_vdev_mgr_set_tx_rx_decap_type(struct vdev_mlme_obj *mlme_obj, + enum wlan_mlme_cfg_id param_id, + uint32_t value); + /** * tgt_vdev_mgr_set_param_send() – API to send parameter cfg * @mlme_obj: pointer to vdev_mlme_obj @@ -253,5 +291,15 @@ QDF_STATUS tgt_vdev_mgr_set_param_send( */ QDF_STATUS tgt_vdev_mgr_bcn_miss_offload_send(struct vdev_mlme_obj *mlme_obj); -#endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */ +/** + * tgt_vdev_mgr_peer_delete_all_send() – API to send peer delete all request + * @mlme_obj: pointer to vdev_mlme_obj + * @param: pointer to peer_delete_all_params + * + * Return: QDF_STATUS - Success or Failure + */ +QDF_STATUS tgt_vdev_mgr_peer_delete_all_send( + struct vdev_mlme_obj *mlme_obj, + struct peer_delete_all_params *param); + #endif /* __WLAN_VDEV_MGR_TX_OPS_API_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h index 71e1b9f51575e43167f45ba7c8d34dbaea98ca93..51283ab146fd62956b0335efa2f0ab93b4855ff1 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,7 +25,6 @@ #ifndef __WLAN_VDEV_MGR_TX_OPS_DEFS_H__ #define __WLAN_VDEV_MGR_TX_OPS_DEFS_H__ -#ifdef CMN_VDEV_MGR_TGT_IF_ENABLE #include /** @@ -83,9 +82,38 @@ enum wlan_mlme_host_vdev_start_status { WLAN_MLME_HOST_VDEV_START_CHAN_INVALID, WLAN_MLME_HOST_VDEV_START_CHAN_BLOCKED, WLAN_MLME_HOST_VDEV_START_CHAN_DFS_VIOLATION, + WLAN_MLME_HOST_VDEV_START_CHAN_INVALID_REGDOMAIN, + WLAN_MLME_HOST_VDEV_START_CHAN_INVALID_BAND, WLAN_MLME_HOST_VDEV_START_TIMEOUT, + /* Add new response status code from here */ + WLAN_MLME_HOST_VDEV_START_MAX_REASON, }; +/** + * string_from_start_rsp_status() - Convert start response status to string + * @start_rsp - start response status + * + * Please note to add new string in the array at index equal to + * its enum value in wlan_mlme_host_vdev_start_status. + */ +static inline char *string_from_start_rsp_status( + enum wlan_mlme_host_vdev_start_status start_rsp) +{ + static const char *strings[] = { "START_OK", + "CHAN_INVALID", + "CHAN_BLOCKED", + "CHAN_DFS_VIOLATION", + "CHAN_INVALID_REGDOMAIN", + "CHAN_INVALID_BAND", + "START_RESPONSE_TIMEOUT", + "START_RESPONSE_UNKNOWN"}; + + if (start_rsp >= WLAN_MLME_HOST_VDEV_START_MAX_REASON) + start_rsp = WLAN_MLME_HOST_VDEV_START_MAX_REASON; + + return (char *)strings[start_rsp]; +} + /** * enum wlan_mlme_host_start_event_param - start/restart resp event */ @@ -122,10 +150,14 @@ struct sta_ps_params { * struct tbttoffset_params - Tbttoffset event params * @vdev_id: Virtual AP device identifier * @tbttoffset : Tbttoffset for the virtual AP device + * @vdev_tbtt_qtime_lo: Tbtt qtime low value + * @vdev_tbtt_qtime_hi: Tbtt qtime high value */ struct tbttoffset_params { uint32_t vdev_id; uint32_t tbttoffset; + uint32_t vdev_tbtt_qtime_lo; + uint32_t vdev_tbtt_qtime_hi; }; /** @@ -138,6 +170,7 @@ struct tbttoffset_params { * @csa_switch_count_offset: CSA swith count offset in beacon frame * @ext_csa_switch_count_offset: ECSA switch count offset in beacon frame * @esp_ie_offset: ESP IE offset in beacon frame + * @mu_edca_ie_offset: Mu EDCA IE offset in beacon frame * @frm: beacon template parameter */ struct beacon_tmpl_params { @@ -149,6 +182,7 @@ struct beacon_tmpl_params { uint32_t csa_switch_count_offset; uint32_t ext_csa_switch_count_offset; uint32_t esp_ie_offset; + uint32_t mu_edca_ie_offset; uint8_t *frm; }; @@ -174,6 +208,19 @@ struct beacon_params { bool is_high_latency; }; +/* struct fils_discovery_tmpl_params - FILS Discovery template cmd parameter + * @vdev_id: vdev ID + * @tmpl_len: FILS Discovery template length + * @tmpl_aligned: FILS Discovery template alignment + * @frm: FILS Discovery template parameter + */ +struct fils_discovery_tmpl_params { + uint8_t vdev_id; + uint32_t tmpl_len; + uint32_t tmpl_len_aligned; + uint8_t *frm; +}; + /** * struct mlme_channel_param - Channel parameters with all * info required by target. @@ -219,6 +266,14 @@ struct mlme_channel_param { uint8_t reg_class_id; }; +/** + * struct vdev_mlme_mvr_param - Multiple vdev restart params + * @phymode: phymode information + */ +struct vdev_mlme_mvr_param { + uint32_t phymode; +}; + /** * struct multiple_vdev_restart_params - Multiple vdev restart cmd parameter * @pdev_id: Pdev identifier @@ -228,6 +283,7 @@ struct mlme_channel_param { * @num_vdevs: No. of vdevs that need to be restarted * @ch_param: Pointer to channel_param * @vdev_ids: Pointer to array of vdev_ids + * @mvr_param: array holding multi vdev restart param */ struct multiple_vdev_restart_params { uint32_t pdev_id; @@ -237,6 +293,7 @@ struct multiple_vdev_restart_params { uint32_t num_vdevs; struct mlme_channel_param ch_param; uint32_t vdev_ids[WLAN_UMAC_PDEV_MAX_VDEVS]; + struct vdev_mlme_mvr_param mvr_param[WLAN_UMAC_PDEV_MAX_VDEVS]; }; /** @@ -251,6 +308,22 @@ struct peer_flush_params { uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; }; +/* Default FILS DISCOVERY/probe response sent in period of 20TU */ +#define DEFAULT_FILS_DISCOVERY_PERIOD 20 +#define DEFAULT_PROBE_RESP_PERIOD 20 + +/** + * struct config_fils_params - FILS config params + * @vdev_id: vdev id + * @fd_period: 0 - Disabled, non-zero - Period in ms (mili seconds) + * @send_prb_rsp_frame: send broadcast prb resp frame + */ +struct config_fils_params { + uint8_t vdev_id; + uint32_t fd_period; + uint32_t send_prb_rsp_frame: 1; +}; + /** * struct config_ratemask_params - ratemask config parameters * @vdev_id: vdev id @@ -258,6 +331,7 @@ struct peer_flush_params { * @lower32: Lower 32 bits in the 1st 64-bit value * @higher32: Higher 32 bits in the 1st 64-bit value * @lower32_2: Lower 32 bits in the 2nd 64-bit value + * @higher32_2: Higher 32 bits in the 2nd 64-bit value */ struct config_ratemask_params { uint8_t vdev_id; @@ -265,6 +339,7 @@ struct config_ratemask_params { uint32_t lower32; uint32_t higher32; uint32_t lower32_2; + uint32_t higher32_2; }; /** @@ -442,5 +517,12 @@ struct vdev_down_params { uint8_t vdev_id; }; -#endif +/** + * struct peer_delete_all_params - peer delete all request parameter + * @vdev_id: vdev id + */ +struct peer_delete_all_params { + uint8_t vdev_id; +}; + #endif /* __WLAN_VDEV_MGR_TX_OPS_DEFS_H__ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_ucfg_api.h index 3b6bab0b96487ca97d187b6e8e592680215f3c72..484175b71b8ad0d1fe6279e2d73f946829ec7a20 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_ucfg_api.h @@ -92,7 +92,7 @@ enum wlan_mlme_cfg_id { WLAN_MLME_CFG_TYPE, WLAN_MLME_CFG_SUBTYPE, WLAN_MLME_CFG_UAPSD, - WLAN_MLME_CFG_TX_DECAP_TYPE, + WLAN_MLME_CFG_TX_ENCAP_TYPE, WLAN_MLME_CFG_RX_DECAP_TYPE, WLAN_MLME_CFG_RATEMASK_TYPE, WLAN_MLME_CFG_RATEMASK_LOWER32, @@ -101,6 +101,8 @@ enum wlan_mlme_cfg_id { WLAN_MLME_CFG_BCN_TX_RATE, WLAN_MLME_CFG_BCN_TX_RATE_CODE, WLAN_MLME_CFG_RATEMASK_CAPS, + WLAN_MLME_CFG_ENABLE_MULTI_GROUP_KEY, + WLAN_MLME_CFG_MAX_GROUP_KEYS, WLAN_MLME_CFG_MAX }; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mlme_api.h b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mlme_api.h index 278da74f597ce03372573da4c2e3c76ea8a3531d..11945cc8c4caee6086229db56af35c946fb784da 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mlme_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mlme_api.h @@ -21,6 +21,7 @@ #ifndef _WLAN_VDEV_MLME_API_H_ #define _WLAN_VDEV_MLME_API_H_ +#include /** * wlan_vdev_mlme_get_cmpt_obj - Retrieves MLME component object * from VDEV object @@ -42,7 +43,8 @@ struct vdev_mlme_obj *wlan_vdev_mlme_get_cmpt_obj( * * Return: */ -void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, void *ext_hdl); +void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, + mlme_vdev_ext_t *ext_hdl); /** * wlan_vdev_mlme_get_ext_hdl - Returns legacy handle @@ -53,7 +55,7 @@ void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, void *ext_hdl); * Return: legacy handle on SUCCESS * NULL, if it fails to retrieve */ -void *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev); +mlme_vdev_ext_t *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev); /** * wlan_vdev_mlme_sm_deliver_evt() - Delivers event to VDEV MLME SM diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c index b7584b9d3ca02c51775f1638ccda2df250d2d866..2979d716a30b7d983b9f3142962b139f1e63b3ed 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,27 +22,40 @@ * This file provide definition for APIs registered for LMAC MLME Rx Ops */ #include +#include #include #include #include #include #include #include +#include +#include +#include -static struct vdev_response_timer * -tgt_vdev_mgr_get_response_timer_info(struct wlan_objmgr_vdev *vdev) +struct vdev_response_timer * +tgt_vdev_mgr_get_response_timer_info(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { - struct vdev_mlme_obj *vdev_mlme; + struct psoc_mlme_obj *psoc_mlme; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_err("VDEV_%d: VDEV_MLME is NULL", wlan_vdev_get_id(vdev)); + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + mlme_err("Incorrect vdev_id: %d", vdev_id); return NULL; } - return &vdev_mlme->vdev_rt; + psoc_mlme = mlme_psoc_get_priv(psoc); + if (!psoc_mlme) { + mlme_err("VDEV_%d PSOC_%d PSOC_MLME is NULL", vdev_id, + wlan_psoc_get_id(psoc)); + return NULL; + } + + return &psoc_mlme->psoc_vdev_rt[vdev_id]; } +qdf_export_symbol(tgt_vdev_mgr_get_response_timer_info); + static QDF_STATUS tgt_vdev_mgr_start_response_handler( struct wlan_objmgr_psoc *psoc, struct vdev_start_response *rsp) @@ -50,8 +63,6 @@ static QDF_STATUS tgt_vdev_mgr_start_response_handler( QDF_STATUS status = QDF_STATUS_E_FAILURE; struct vdev_mlme_obj *vdev_mlme; struct wlan_objmgr_vdev *vdev; - struct vdev_response_timer *vdev_rsp; - struct wlan_lmac_if_mlme_tx_ops *tx_ops; if (!rsp || !psoc) { mlme_err("Invalid input"); @@ -67,25 +78,8 @@ static QDF_STATUS tgt_vdev_mgr_start_response_handler( vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); if (!vdev_mlme) { - mlme_err("VDEV_%d: VDEV_MLME is NULL", rsp->vdev_id); - goto tgt_vdev_mgr_start_response_handler_end; - } - - vdev_rsp = &vdev_mlme->vdev_rt; - if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response", rsp->vdev_id); - goto tgt_vdev_mgr_start_response_handler_end; - } - - tx_ops = target_if_vdev_mgr_get_tx_ops(psoc); - if (rsp->resp_type == RESTART_RESPONSE) - status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, - RESTART_RESPONSE_BIT); - else - status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, - START_RESPONSE_BIT); - if (QDF_IS_STATUS_ERROR(status)) { - mlme_err("VDEV_%d: Unexpected response", rsp->vdev_id); + mlme_err("VDEV_%d PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, + wlan_psoc_get_id(psoc)); goto tgt_vdev_mgr_start_response_handler_end; } @@ -93,6 +87,7 @@ static QDF_STATUS tgt_vdev_mgr_start_response_handler( status = vdev_mlme->ops->mlme_vdev_ext_start_rsp( vdev_mlme, rsp); + tgt_vdev_mgr_start_response_handler_end: wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); return status; @@ -105,8 +100,6 @@ static QDF_STATUS tgt_vdev_mgr_stop_response_handler( QDF_STATUS status = QDF_STATUS_E_FAILURE; struct vdev_mlme_obj *vdev_mlme; struct wlan_objmgr_vdev *vdev; - struct vdev_response_timer *vdev_rsp; - struct wlan_lmac_if_mlme_tx_ops *tx_ops; if (!rsp || !psoc) { mlme_err("Invalid input"); @@ -122,21 +115,8 @@ static QDF_STATUS tgt_vdev_mgr_stop_response_handler( vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); if (!vdev_mlme) { - mlme_err("VDEV_%d: VDEV_MLME is NULL", rsp->vdev_id); - goto tgt_vdev_mgr_stop_response_handler_end; - } - - vdev_rsp = &vdev_mlme->vdev_rt; - if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response", rsp->vdev_id); - goto tgt_vdev_mgr_stop_response_handler_end; - } - - tx_ops = target_if_vdev_mgr_get_tx_ops(psoc); - status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, - STOP_RESPONSE_BIT); - if (QDF_IS_STATUS_ERROR(status)) { - mlme_err("VDEV_%d: Unexpected response", rsp->vdev_id); + mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, + wlan_psoc_get_id(psoc)); goto tgt_vdev_mgr_stop_response_handler_end; } @@ -144,20 +124,29 @@ static QDF_STATUS tgt_vdev_mgr_stop_response_handler( status = vdev_mlme->ops->mlme_vdev_ext_stop_rsp( vdev_mlme, rsp); + tgt_vdev_mgr_stop_response_handler_end: wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); return status; } -QDF_STATUS tgt_vdev_mgr_delete_response_handler( +static QDF_STATUS tgt_vdev_mgr_delete_response_handler( struct wlan_objmgr_psoc *psoc, struct vdev_delete_response *rsp) { QDF_STATUS status = QDF_STATUS_E_FAILURE; + + status = mlme_vdev_ops_ext_hdl_delete_rsp(psoc, rsp); + return status; +} + +static QDF_STATUS tgt_vdev_mgr_peer_delete_all_response_handler( + struct wlan_objmgr_psoc *psoc, + struct peer_delete_all_response *rsp) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; struct vdev_mlme_obj *vdev_mlme; struct wlan_objmgr_vdev *vdev; - struct vdev_response_timer *vdev_rsp; - struct wlan_lmac_if_mlme_tx_ops *tx_ops; if (!rsp || !psoc) { mlme_err("Invalid input"); @@ -174,31 +163,18 @@ QDF_STATUS tgt_vdev_mgr_delete_response_handler( vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); if (!vdev_mlme) { - mlme_err("VDEV_%d: VDEV_MLME is NULL", rsp->vdev_id); - goto tgt_vdev_mgr_delete_response_handler_end; - } - - vdev_rsp = &vdev_mlme->vdev_rt; - if (!vdev_rsp) { - mlme_err("VDEV_%d: Invalid response", rsp->vdev_id); - goto tgt_vdev_mgr_delete_response_handler_end; - } - - tx_ops = target_if_vdev_mgr_get_tx_ops(psoc); - status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, - DELETE_RESPONSE_BIT); - if (QDF_IS_STATUS_ERROR(status)) { - mlme_err("VDEV_%d: Unexpected response", rsp->vdev_id); - goto tgt_vdev_mgr_delete_response_handler_end; + mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, + wlan_psoc_get_id(psoc)); + goto tgt_vdev_mgr_peer_delete_all_response_handler_end; } if ((vdev_mlme->ops) && - vdev_mlme->ops->mlme_vdev_ext_delete_rsp) - status = vdev_mlme->ops->mlme_vdev_ext_delete_rsp( + vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp) + status = vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp( vdev_mlme, rsp); -tgt_vdev_mgr_delete_response_handler_end: +tgt_vdev_mgr_peer_delete_all_response_handler_end: wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); return status; } @@ -220,7 +196,7 @@ tgt_vdev_mgr_tbttoffset_update_handler(uint32_t num_vdevs, bool is_ext) return status; } -static QDF_STATUS +QDF_STATUS tgt_vdev_mgr_ext_tbttoffset_update_handle(uint32_t num_vdevs, bool is_ext) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -228,6 +204,42 @@ tgt_vdev_mgr_ext_tbttoffset_update_handle(uint32_t num_vdevs, bool is_ext) return status; } +static QDF_STATUS tgt_vdev_mgr_multi_vdev_restart_resp_handler( + struct wlan_objmgr_psoc *psoc, + struct multi_vdev_restart_resp *resp) +{ + return mlme_vdev_ops_ext_hdl_multivdev_restart_resp(psoc, resp); +} + +#ifdef FEATURE_VDEV_RSP_WAKELOCK +static struct psoc_mlme_wakelock * +tgt_psoc_get_wakelock_info(struct wlan_objmgr_psoc *psoc) +{ + struct psoc_mlme_obj *psoc_mlme; + + psoc_mlme = mlme_psoc_get_priv(psoc); + if (!psoc_mlme) { + mlme_err("PSOC_MLME is NULL"); + return NULL; + } + + return &psoc_mlme->psoc_mlme_wakelock; +} + +static inline void +tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops + *mlme_rx_ops) +{ + mlme_rx_ops->psoc_get_wakelock_info = tgt_psoc_get_wakelock_info; +} +#else +static inline void +tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops + *mlme_rx_ops) +{ +} +#endif + void tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) { struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops = &rx_ops->mops; @@ -242,6 +254,11 @@ void tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) tgt_vdev_mgr_stop_response_handler; mlme_rx_ops->vdev_mgr_delete_response = tgt_vdev_mgr_delete_response_handler; - mlme_rx_ops->vdev_mgr_get_response_timer_info = + mlme_rx_ops->vdev_mgr_peer_delete_all_response = + tgt_vdev_mgr_peer_delete_all_response_handler; + mlme_rx_ops->psoc_get_vdev_response_timer_info = tgt_vdev_mgr_get_response_timer_info; + mlme_rx_ops->vdev_mgr_multi_vdev_restart_resp = + tgt_vdev_mgr_multi_vdev_restart_resp_handler; + tgt_psoc_reg_wakelock_info_rx_op(&rx_ops->mops); } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c index 286b0b6cfcd960ea8deb2838c2b4af103dd9ad05..d7cdc2aab189740162967a06f49d50b6a565a3fa 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -57,13 +57,10 @@ QDF_STATUS tgt_vdev_mgr_create_send( struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_vdev *vdev; ol_txrx_soc_handle soc_txrx_handle; - struct cdp_pdev *pdev_txrx_handle; - struct cdp_vdev *vdev_txrx_handle; enum wlan_op_mode cdp_txrx_opmode; enum wlan_op_subtype cdp_txrx_subtype; uint32_t vdev_id; uint8_t *vdev_addr; - struct vdev_response_timer *vdev_rsp; if (!param) { mlme_err("Invalid input"); @@ -73,42 +70,37 @@ QDF_STATUS tgt_vdev_mgr_create_send( vdev = mlme_obj->vdev; vdev_id = wlan_vdev_get_id(vdev); txops = wlan_vdev_mlme_get_lmac_txops(vdev); - if (!txops || !txops->vdev_create_send || - !txops->vdev_mgr_rsp_timer_init) { - mlme_err("VDEV_%d: No Tx Ops", vdev_id); + if (!txops || !txops->vdev_create_send) { + mlme_err("VDEV_%d No Tx Ops", vdev_id); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + mlme_err("psoc object is NULL"); return QDF_STATUS_E_INVAL; } status = txops->vdev_create_send(vdev, param); - if (QDF_IS_STATUS_SUCCESS(status)) { - vdev_rsp = &mlme_obj->vdev_rt; - txops->vdev_mgr_rsp_timer_init(vdev, &vdev_rsp->rsp_timer); - } else { - mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("VDEV_%d PSOC_%d Tx Ops Error : %d", vdev_id, + wlan_psoc_get_id(psoc), status); return status; } cdp_txrx_opmode = wlan_util_vdev_get_cdp_txrx_opmode(vdev); cdp_txrx_subtype = wlan_util_vdev_get_cdp_txrx_subtype(vdev); vdev_addr = wlan_vdev_mlme_get_macaddr(vdev); - psoc = wlan_vdev_get_psoc(vdev); pdev = wlan_vdev_get_pdev(vdev); soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); - pdev_txrx_handle = wlan_pdev_get_dp_handle(pdev); - if (!soc_txrx_handle || !pdev_txrx_handle) - return QDF_STATUS_E_FAILURE; - - vdev_txrx_handle = cdp_vdev_attach(soc_txrx_handle, - pdev_txrx_handle, - vdev_addr, vdev_id, - cdp_txrx_opmode, - cdp_txrx_subtype); - if (!vdev_txrx_handle) + if (!soc_txrx_handle) return QDF_STATUS_E_FAILURE; - wlan_vdev_set_dp_handle(vdev, vdev_txrx_handle); - - return status; + return cdp_vdev_attach(soc_txrx_handle, + wlan_objmgr_pdev_get_pdev_id(pdev), + vdev_addr, vdev_id, + cdp_txrx_opmode, + cdp_txrx_subtype); } QDF_STATUS tgt_vdev_mgr_create_complete(struct vdev_mlme_obj *vdev_mlme) @@ -195,6 +187,8 @@ QDF_STATUS tgt_vdev_mgr_delete_send( QDF_STATUS status; struct wlan_lmac_if_mlme_tx_ops *txops; struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + ol_txrx_soc_handle soc_txrx_handle; uint8_t vdev_id; if (!param) { @@ -210,6 +204,12 @@ QDF_STATUS tgt_vdev_mgr_delete_send( return QDF_STATUS_E_INVAL; } + psoc = wlan_vdev_get_psoc(vdev); + soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); + if (soc_txrx_handle) + cdp_vdev_detach(soc_txrx_handle, wlan_vdev_get_id(vdev), + NULL, NULL); + status = txops->vdev_delete_send(vdev, param); if (QDF_IS_STATUS_ERROR(status)) mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); @@ -292,7 +292,6 @@ QDF_STATUS tgt_vdev_mgr_up_send( QDF_STATUS status; struct wlan_lmac_if_mlme_tx_ops *txops; ol_txrx_soc_handle soc_txrx_handle; - struct cdp_vdev *vdev_txrx_handle; struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_vdev *vdev; uint8_t vdev_id; @@ -313,17 +312,9 @@ QDF_STATUS tgt_vdev_mgr_up_send( /* cdp set rx and tx decap type */ psoc = wlan_vdev_get_psoc(vdev); soc_txrx_handle = wlan_psoc_get_dp_handle(psoc); - vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); - if (!soc_txrx_handle || !vdev_txrx_handle) + if (!soc_txrx_handle || vdev_id == WLAN_INVALID_VDEV_ID) return QDF_STATUS_E_INVAL; - cdp_set_vdev_rx_decap_type(soc_txrx_handle, - (struct cdp_vdev *)vdev_txrx_handle, - mlme_obj->mgmt.generic.rx_decap_type); - cdp_set_tx_encap_type(soc_txrx_handle, - (struct cdp_vdev *)vdev_txrx_handle, - mlme_obj->mgmt.generic.tx_decap_type); - status = txops->vdev_up_send(vdev, param); if (QDF_IS_STATUS_ERROR(status)) mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); @@ -486,6 +477,33 @@ QDF_STATUS tgt_vdev_mgr_beacon_tmpl_send( return QDF_STATUS_SUCCESS; } +#if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) +QDF_STATUS tgt_vdev_mgr_fils_enable_send( + struct vdev_mlme_obj *mlme_obj, + struct config_fils_params *param) +{ + QDF_STATUS status; + struct wlan_lmac_if_mlme_tx_ops *txops; + struct wlan_objmgr_vdev *vdev; + uint8_t vdev_id; + + vdev = mlme_obj->vdev; + vdev_id = wlan_vdev_get_id(vdev); + txops = wlan_vdev_mlme_get_lmac_txops(vdev); + if (!txops || !txops->vdev_fils_enable_send) { + mlme_err("VDEV_%d: No Tx Ops fils Enable", vdev_id); + return QDF_STATUS_E_INVAL; + } + + status = txops->vdev_fils_enable_send(vdev, param); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("VDEV_%d: Tx Ops fils Enable Error : %d", + vdev_id, status); + + return status; +} +#endif + QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( struct wlan_objmgr_pdev *pdev, struct multiple_vdev_restart_params *param) @@ -521,6 +539,35 @@ QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( return status; } +QDF_STATUS tgt_vdev_mgr_set_tx_rx_decap_type(struct vdev_mlme_obj *mlme_obj, + enum wlan_mlme_cfg_id param_id, + uint32_t value) +{ + QDF_STATUS status; + struct wlan_lmac_if_mlme_tx_ops *txops; + struct wlan_objmgr_vdev *vdev; + uint8_t vdev_id; + + if (!mlme_obj) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + vdev = mlme_obj->vdev; + vdev_id = wlan_vdev_get_id(vdev); + txops = wlan_vdev_mlme_get_lmac_txops(vdev); + if (!txops || !txops->vdev_set_tx_rx_decap_type) { + mlme_err("VDEV_%d: No Tx Ops", vdev_id); + return QDF_STATUS_E_INVAL; + } + + status = txops->vdev_set_tx_rx_decap_type(vdev, param_id, value); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); + + return status; +} + QDF_STATUS tgt_vdev_mgr_set_param_send( struct vdev_mlme_obj *mlme_obj, struct vdev_set_params *param) @@ -578,3 +625,32 @@ QDF_STATUS tgt_vdev_mgr_sta_ps_param_send( return status; } + +QDF_STATUS tgt_vdev_mgr_peer_delete_all_send( + struct vdev_mlme_obj *mlme_obj, + struct peer_delete_all_params *param) +{ + QDF_STATUS status; + struct wlan_lmac_if_mlme_tx_ops *txops; + struct wlan_objmgr_vdev *vdev; + uint8_t vdev_id; + + if (!param) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + vdev = mlme_obj->vdev; + vdev_id = wlan_vdev_get_id(vdev); + txops = wlan_vdev_mlme_get_lmac_txops(vdev); + if (!txops || !txops->peer_delete_all_send) { + mlme_err("VDEV_%d: No Tx Ops", vdev_id); + return QDF_STATUS_E_INVAL; + } + + status = txops->peer_delete_all_send(vdev, param); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status); + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_ucfg_api.c index 779755df8178392b401c1ddea31f896e60aca5d7..6582f3cc7e702cf77903c9d0575f8128f6ef7509 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_ucfg_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_ucfg_api.c @@ -28,6 +28,7 @@ #include #include #include +#include void ucfg_wlan_vdev_mgr_get_param_bssid( struct wlan_objmgr_vdev *vdev, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c index fd329da926722ef249513477aee17cbcab7e3bb8..b631396ce720a101d07662f71732c45c94bf0ea3 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include static QDF_STATUS vdev_mgr_config_ratemask_update( struct vdev_mlme_obj *mlme_obj, @@ -84,6 +86,24 @@ wlan_util_vdev_get_cdp_txrx_opmode(struct wlan_objmgr_vdev *vdev) case QDF_MONITOR_MODE: cdp_txrx_opmode = wlan_op_mode_monitor; break; + case QDF_P2P_DEVICE_MODE: + cdp_txrx_opmode = wlan_op_mode_ap; + break; + case QDF_P2P_CLIENT_MODE: + cdp_txrx_opmode = wlan_op_mode_sta; + break; + case QDF_P2P_GO_MODE: + cdp_txrx_opmode = wlan_op_mode_ap; + break; + case QDF_OCB_MODE: + cdp_txrx_opmode = wlan_op_mode_ocb; + break; + case QDF_IBSS_MODE: + cdp_txrx_opmode = wlan_op_mode_ibss; + break; + case QDF_NDI_MODE: + cdp_txrx_opmode = wlan_op_mode_ndi; + break; default: cdp_txrx_opmode = wlan_op_mode_unknown; }; @@ -117,7 +137,7 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, struct vdev_mlme_proto *mlme_proto; struct vdev_mlme_mgmt *mlme_mgmt; struct vdev_mlme_inactivity_params *inactivity_params; - int is_wmi_cmd = 0; + bool is_wmi_cmd = false; int ret = QDF_STATUS_SUCCESS; struct vdev_set_params param = {0}; @@ -133,27 +153,27 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, switch (param_id) { case WLAN_MLME_CFG_DTIM_PERIOD: mlme_proto->generic.dtim_period = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_SLOT_TIME: mlme_proto->generic.slot_time = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_PROTECTION_MODE: mlme_proto->generic.protection_mode = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_BEACON_INTERVAL: mlme_proto->generic.beacon_interval = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_LDPC: mlme_proto->generic.ldpc = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_NSS: mlme_proto->generic.nss = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_TSF_ADJUST: mlme_proto->generic.tsfadjust = mlme_cfg.tsf; @@ -186,22 +206,22 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, mlme_proto->vht_info.bfee_sts_cap = mlme_cfg.value; break; case WLAN_MLME_CFG_TXBF_CAPS: - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_HT_CAPS: mlme_proto->ht_info.ht_caps = mlme_cfg.value; break; case WLAN_MLME_CFG_HE_OPS: mlme_proto->he_ops_info.he_ops = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_RTS_THRESHOLD: mlme_mgmt->generic.rts_threshold = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_FRAG_THRESHOLD: mlme_mgmt->generic.frag_threshold = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_PROBE_DELAY: mlme_mgmt->generic.probe_delay = mlme_cfg.value; @@ -211,19 +231,19 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, break; case WLAN_MLME_CFG_DROP_UNENCRY: mlme_mgmt->generic.drop_unencry = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_TX_PWR_LIMIT: mlme_mgmt->generic.tx_pwrlimit = mlme_cfg.value; break; case WLAN_MLME_CFG_TX_POWER: mlme_mgmt->generic.tx_power = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_AMPDU: mlme_mgmt->generic.ampdu = mlme_cfg.value; mlme_cfg.value = (mlme_cfg.value << 8) + 0xFF; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_AMPDU_SIZE: mlme_mgmt->generic.ampdu = mlme_cfg.value; @@ -231,7 +251,7 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, case WLAN_MLME_CFG_AMSDU: mlme_mgmt->generic.amsdu = mlme_cfg.value; mlme_cfg.value = (mlme_cfg.value << 8) + 0xFF; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_AMSDU_SIZE: mlme_mgmt->generic.amsdu = mlme_cfg.value; @@ -245,17 +265,17 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, case WLAN_MLME_CFG_MIN_IDLE_INACTIVE_TIME: inactivity_params->keepalive_min_idle_inactive_time_secs = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_MAX_IDLE_INACTIVE_TIME: inactivity_params->keepalive_max_idle_inactive_time_secs = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_MAX_UNRESPONSIVE_INACTIVE_TIME: inactivity_params->keepalive_max_unresponsive_time_secs = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_RATE_FLAGS: mlme_mgmt->rate_info.rate_flags = mlme_cfg.value; @@ -286,7 +306,7 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, break; case WLAN_MLME_CFG_LISTEN_INTERVAL: mlme_mgmt->powersave_info.listen_interval = mlme_cfg.value; - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_MODDTIM_CNT: mlme_mgmt->powersave_info.moddtim_cnt = mlme_cfg.value; @@ -328,11 +348,19 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, case WLAN_MLME_CFG_UAPSD: mlme_proto->sta.uapsd_cfg = mlme_cfg.value; break; - case WLAN_MLME_CFG_TX_DECAP_TYPE: - mlme_mgmt->generic.tx_decap_type = mlme_cfg.value; + case WLAN_MLME_CFG_TX_ENCAP_TYPE: + is_wmi_cmd = true; + mlme_mgmt->generic.tx_encap_type = mlme_cfg.value; + tgt_vdev_mgr_set_tx_rx_decap_type(vdev_mlme, + WLAN_MLME_CFG_TX_ENCAP_TYPE, + mlme_cfg.value); break; case WLAN_MLME_CFG_RX_DECAP_TYPE: + is_wmi_cmd = true; mlme_mgmt->generic.rx_decap_type = mlme_cfg.value; + tgt_vdev_mgr_set_tx_rx_decap_type(vdev_mlme, + WLAN_MLME_CFG_RX_DECAP_TYPE, + mlme_cfg.value); break; case WLAN_MLME_CFG_RATEMASK_TYPE: mlme_mgmt->rate_info.type = mlme_cfg.value; @@ -350,10 +378,16 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, mlme_mgmt->rate_info.bcn_tx_rate = mlme_cfg.value; break; case WLAN_MLME_CFG_BCN_TX_RATE_CODE: - is_wmi_cmd = 1; + is_wmi_cmd = true; break; case WLAN_MLME_CFG_TX_MGMT_RATE_CODE: - is_wmi_cmd = 1; + is_wmi_cmd = true; + break; + case WLAN_MLME_CFG_ENABLE_MULTI_GROUP_KEY: + is_wmi_cmd = true; + break; + case WLAN_MLME_CFG_MAX_GROUP_KEYS: + is_wmi_cmd = true; break; default: break; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c index 1d0629976cff5b08db46e6900b83bc844d865390..fafc0bed56c3e9bd0c38d41e8f6d7f26abbf45df 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c @@ -46,7 +46,8 @@ struct vdev_mlme_obj *wlan_vdev_mlme_get_cmpt_obj(struct wlan_objmgr_vdev *vdev) qdf_export_symbol(wlan_vdev_mlme_get_cmpt_obj); -void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, void *ext_hdl) +void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, + mlme_vdev_ext_t *ext_hdl) { struct vdev_mlme_obj *vdev_mlme; @@ -62,7 +63,7 @@ void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev, void *ext_hdl) qdf_export_symbol(wlan_vdev_mlme_set_ext_hdl); -void *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev) +mlme_vdev_ext_t *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev) { struct vdev_mlme_obj *vdev_mlme; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c index 065efcf4463c564e51b99e4272c518b34a243146..d783f8158316141ea1f35927ff25ab2995931dab 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_build_chan_list.c @@ -183,12 +183,10 @@ static void reg_do_auto_bw_correction(uint32_t num_reg_rules, uint16_t new_bw; for (count = 0; count < num_reg_rules - 1; count++) { - if ((reg_rule_ptr[count].end_freq == - reg_rule_ptr[count + 1].start_freq) && - ((reg_rule_ptr[count].max_bw + - reg_rule_ptr[count + 1].max_bw) <= max_bw)) { - new_bw = reg_rule_ptr[count].max_bw + - reg_rule_ptr[count + 1].max_bw; + if (reg_rule_ptr[count].end_freq == + reg_rule_ptr[count + 1].start_freq) { + new_bw = QDF_MIN(max_bw, reg_rule_ptr[count].max_bw + + reg_rule_ptr[count + 1].max_bw); reg_rule_ptr[count].max_bw = new_bw; reg_rule_ptr[count + 1].max_bw = new_bw; } @@ -255,18 +253,43 @@ static void reg_modify_chan_list_for_indoor_channels( } } +#ifdef CONFIG_BAND_6GHZ +static void reg_modify_chan_list_for_band_6G( + struct regulatory_channel *chan_list) +{ + enum channel_enum chan_enum; + + reg_debug("disabling 6G"); + for (chan_enum = MIN_6GHZ_CHANNEL; + chan_enum <= MAX_6GHZ_CHANNEL; chan_enum++) { + chan_list[chan_enum].chan_flags |= + REGULATORY_CHAN_DISABLED; + chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; + } +} +#else +static inline void reg_modify_chan_list_for_band_6G( + struct regulatory_channel *chan_list) +{ +} +#endif + /** - * reg_modify_chan_list_for_band() - Based on the input band value, either - * disable 2GHz or 5GHz channels. + * reg_modify_chan_list_for_band() - Based on the input band bitmap, either + * disable 2GHz, 5GHz, or 6GHz channels. * @chan_list: Pointer to regulatory channel list. - * @band_val: Input band value. + * @band_bitmap: Input bitmap of reg_wifi_band values. */ static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, - enum band_info band_val) + uint32_t band_bitmap) { enum channel_enum chan_enum; - if (band_val == BAND_2G) { + if (!band_bitmap) + return; + + if (!(band_bitmap & BIT(REG_BAND_5G))) { + reg_debug("disabling 5G"); for (chan_enum = MIN_5GHZ_CHANNEL; chan_enum <= MAX_5GHZ_CHANNEL; chan_enum++) { chan_list[chan_enum].chan_flags |= @@ -275,7 +298,8 @@ static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, } } - if (band_val == BAND_5G) { + if (!(band_bitmap & BIT(REG_BAND_2G))) { + reg_debug("disabling 2G"); for (chan_enum = MIN_24GHZ_CHANNEL; chan_enum <= MAX_24GHZ_CHANNEL; chan_enum++) { chan_list[chan_enum].chan_flags |= @@ -283,6 +307,10 @@ static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; } } + + if (!(band_bitmap & BIT(REG_BAND_6G))) + reg_modify_chan_list_for_band_6G(chan_list); + } /** @@ -360,13 +388,13 @@ static void reg_modify_chan_list_for_nol_list( * Return: None */ static void reg_find_low_limit_chan_enum( - struct regulatory_channel *chan_list, uint32_t low_freq, + struct regulatory_channel *chan_list, qdf_freq_t low_freq, uint32_t *low_limit) { enum channel_enum chan_enum; uint16_t min_bw; uint16_t max_bw; - uint32_t center_freq; + qdf_freq_t center_freq; for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { min_bw = chan_list[chan_enum].min_bw; @@ -396,13 +424,13 @@ static void reg_find_low_limit_chan_enum( * Return: None */ static void reg_find_high_limit_chan_enum( - struct regulatory_channel *chan_list, uint32_t high_freq, + struct regulatory_channel *chan_list, qdf_freq_t high_freq, uint32_t *high_limit) { enum channel_enum chan_enum; uint16_t min_bw; uint16_t max_bw; - uint32_t center_freq; + qdf_freq_t center_freq; for (chan_enum = NUM_CHANNELS - 1; chan_enum >= 0; chan_enum--) { min_bw = chan_list[chan_enum].min_bw; @@ -427,6 +455,37 @@ static void reg_find_high_limit_chan_enum( } } +#ifdef REG_DISABLE_JP_CH144 +/** + * reg_modify_chan_list_for_japan() - Disable channel 144 for MKK17_MKKC + * regdomain by default. + * @pdev: Pointer to pdev + * + * Return: None + */ +static void +reg_modify_chan_list_for_japan(struct wlan_objmgr_pdev *pdev) +{ +#define MKK17_MKKC 0xE1 + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return; + } + + if (pdev_priv_obj->reg_dmn_pair == MKK17_MKKC) + pdev_priv_obj->en_chan_144 = false; + +#undef MKK17_MKKC +} +#else +static inline void +reg_modify_chan_list_for_japan(struct wlan_objmgr_pdev *pdev) +{ +} +#endif /** * reg_modify_chan_list_for_freq_range() - Modify channel list for the given low * and high frequency range. @@ -440,10 +499,10 @@ static void reg_find_high_limit_chan_enum( */ static void reg_modify_chan_list_for_freq_range(struct regulatory_channel *chan_list, - uint32_t low_freq_2g, - uint32_t high_freq_2g, - uint32_t low_freq_5g, - uint32_t high_freq_5g) + qdf_freq_t low_freq_2g, + qdf_freq_t high_freq_2g, + qdf_freq_t low_freq_5g, + qdf_freq_t high_freq_5g) { uint32_t low_limit_2g = NUM_CHANNELS; uint32_t high_limit_2g = NUM_CHANNELS; @@ -584,6 +643,134 @@ reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_is_reg_unii_band_1_set() - Check UNII bitmap + * @unii_bitmap: 5G UNII band bitmap + * + * This function checks the input bitmap to disable UNII-1 band channels. + * + * Return: Return true if UNII-1 channels need to be disabled, + * else return false. + */ +static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) +{ + return !!(unii_bitmap & BIT(REG_UNII_BAND_1)); +} + +/** + * reg_is_reg_unii_band_2a_set() - Check UNII bitmap + * @unii_bitmap: 5G UNII band bitmap + * + * This function checks the input bitmap to disable UNII-2A band channels. + * + * Return: Return true if UNII-2A channels need to be disabled, + * else return false. + */ +static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) +{ + return !!(unii_bitmap & BIT(REG_UNII_BAND_2A)); +} + +/** + * reg_is_5g_enum() - Check if channel enum is a 5G channel enum + * @chan_enum: channel enum + * + * Return: Return true if the input channel enum is 5G, else return false. + */ +static bool reg_is_5g_enum(enum channel_enum chan_enum) +{ + return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL); +} + +/** + * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels + * @chan_list: Pointer to current channel list + * @start_enum: starting enum value + * @end_enum: ending enum value + * + * Remove channels in a unii band based in on the input start_enum and end_enum. + * Disable the state and flags. Set disable_coex flag to true. + * + * return: void. + */ +static void +reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, + enum channel_enum start_enum, + enum channel_enum end_enum) +{ + enum channel_enum chan_enum; + + if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) { + reg_err_rl("start_enum or end_enum is invalid"); + return; + } + + for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) { + chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; + chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED; + } +} + +/** + * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and + * UNII2A band + * @pdev_priv_obj: Pointer to pdev private object + * + * This function disables the UNII-1 and UNII-2A band channels + * based on input unii_5g_bitmap. + * + * Return: void. + */ +static void +reg_modify_disable_chan_list_for_unii1_and_unii2a( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap; + struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; + + if (reg_is_reg_unii_band_1_set(unii_bitmap)) { + reg_remove_unii_chan_from_chan_list(chan_list, + MIN_UNII_1_BAND_CHANNEL, + MAX_UNII_1_BAND_CHANNEL); + } + + if (reg_is_reg_unii_band_2a_set(unii_bitmap)) { + reg_remove_unii_chan_from_chan_list(chan_list, + MIN_UNII_2A_BAND_CHANNEL, + MAX_UNII_2A_BAND_CHANNEL); + } +} +#else +static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) +{ + return false; +} + +static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) +{ + return false; +} + +static inline bool reg_is_5g_enum(enum channel_enum chan_enum) +{ + return false; +} + +static inline void +reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, + enum channel_enum start_enum, + enum channel_enum end_enum) +{ +} + +static inline void +reg_modify_disable_chan_list_for_unii1_and_unii2a( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) { @@ -599,6 +786,8 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list, pdev_priv_obj->band_capability); + reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj); + reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list, pdev_priv_obj->dfs_enabled); @@ -687,6 +876,9 @@ void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc, &psoc_priv_obj->mas_chan_params[pdev_id]); psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules; reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj); + reg_modify_chan_list_for_japan(pdev); + pdev_priv_obj->chan_list_recvd = + psoc_priv_obj->chan_list_recvd[pdev_id]; reg_compute_pdev_current_chan_list(pdev_priv_obj); reg_tx_ops = reg_get_psoc_tx_ops(psoc); @@ -701,6 +893,40 @@ void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc, } } +/** + * reg_populate_6g_band_channels() - For all the valid 6GHz regdb channels + * in the master channel list, find the regulatory rules and call + * reg_fill_channel_info() to populate master channel list with txpower, + * antennagain, BW info, etc. + * @reg_rule_5g: Pointer to regulatory rule. + * @num_5g_reg_rules: Number of regulatory rules. + * @min_bw_5g: Minimum regulatory bandwidth. + * @mas_chan_list: Pointer to the master channel list. + */ +#ifdef CONFIG_BAND_6GHZ +static void +reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g, + uint32_t num_5g_reg_rules, + uint16_t min_bw_5g, + struct regulatory_channel *mas_chan_list) +{ + reg_populate_band_channels(MIN_6GHZ_CHANNEL, + MAX_6GHZ_CHANNEL, + reg_rule_5g, + num_5g_reg_rules, + min_bw_5g, + mas_chan_list); +} +#else +static void +reg_populate_6g_band_channels(struct cur_reg_rule *reg_rule_5g, + uint32_t num_5g_reg_rules, + uint16_t min_bw_5g, + struct regulatory_channel *mas_chan_list) +{ +} +#endif /* CONFIG_BAND_6GHZ */ + #ifdef CONFIG_REG_CLIENT /** * reg_send_ctl_info() - Send CTL info to firmware when regdb is not offloaded @@ -857,7 +1083,8 @@ QDF_STATUS reg_process_master_chan_list( REGULATORY_CHAN_DISABLED; mas_chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; - mas_chan_list[chan_enum].nol_chan = false; + if (!soc_reg->retain_nol_across_regdmn_update) + mas_chan_list[chan_enum].nol_chan = false; } soc_reg->num_phy = regulat_info->num_phy; @@ -921,17 +1148,21 @@ QDF_STATUS reg_process_master_chan_list( reg_rule_2g, num_2g_reg_rules, min_bw_2g, mas_chan_list); - if (num_5g_reg_rules != 0) + if (num_5g_reg_rules != 0) { reg_populate_band_channels(MIN_5GHZ_CHANNEL, MAX_5GHZ_CHANNEL, reg_rule_5g, num_5g_reg_rules, min_bw_5g, mas_chan_list); - - if (num_5g_reg_rules != 0) reg_populate_band_channels(MIN_49GHZ_CHANNEL, MAX_49GHZ_CHANNEL, - reg_rule_5g, num_5g_reg_rules, - min_bw_5g, mas_chan_list); + reg_rule_5g, num_5g_reg_rules, + min_bw_5g, mas_chan_list); + reg_populate_6g_band_channels(reg_rule_5g, + num_5g_reg_rules, + min_bw_5g, + mas_chan_list); + } + soc_reg->chan_list_recvd[phy_id] = true; status = reg_send_ctl_info(soc_reg, regulat_info, tx_ops); if (!QDF_IS_STATUS_SUCCESS(status)) return status; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_callbacks.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_callbacks.c index 709b35302c63133fc0b76d0bb8c95dd09fb35d11..ed253021d0778bbfaacc6f346c8dac017c89ca3f 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_callbacks.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -211,6 +211,11 @@ QDF_STATUS reg_send_scheduler_msg_sb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + if (!pdev_priv_obj->chan_list_recvd) { + reg_err("Empty channel list"); + return QDF_STATUS_E_FAILURE; + } + status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); if (QDF_IS_STATUS_ERROR(status)) { reg_err("error taking psoc ref cnt"); @@ -267,6 +272,11 @@ QDF_STATUS reg_send_scheduler_msg_nb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + if (!pdev_priv_obj->chan_list_recvd) { + reg_err("Empty channel list"); + return QDF_STATUS_E_FAILURE; + } + status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { reg_err("error taking psoc ref cnt"); @@ -336,7 +346,6 @@ QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; pdev_priv_obj->sap_state = sap_state; - set_disable_channel_state(pdev_priv_obj); reg_compute_pdev_current_chan_list(pdev_priv_obj); status = reg_send_scheduler_msg_sb(psoc, pdev); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.c index 39e9f3b03d1a1b4d20d309bfa92cc9e8c073330a..8b47d2f8fcf16d8a80c24260e8fb27547626ebed 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -20,7 +20,7 @@ /** * DOC: reg_db.c * This file implements QCA regulatory database. - * Current implementation conforms to database version 30. + * Current implementation conforms to database version 31. */ #include @@ -118,6 +118,8 @@ enum country_code { CTRY_ISRAEL = 376, CTRY_ITALY = 380, CTRY_JAMAICA = 388, + CTRY_JAPAN = 392, + CTRY_JAPAN15 = 4015, CTRY_JERSEY = 832, CTRY_JORDAN = 400, CTRY_KAZAKHSTAN = 398, @@ -223,11 +225,9 @@ enum country_code { CTRY_VIRGIN_ISLANDS = 850, CTRY_VIRGIN_ISLANDS_BRITISH = 92, CTRY_WALLIS_AND_FUTUNA = 876, + CTRY_XA = 4100, /* Used by Linux Client for legacy MKK domain */ CTRY_YEMEN = 887, CTRY_ZIMBABWE = 716, - CTRY_JAPAN = 392, - CTRY_JAPAN15 = 4015, - CTRY_XA = 4100, }; enum reg_domain { @@ -246,12 +246,17 @@ enum reg_domain { FCC6_WORLD = 0x23, FCC6_FCCA = 0x14, FCC8_FCCA = 0x16, + FCC8_WORLD = 0x09, FCC9_FCCA = 0x17, FCC10_FCCA = 0x18, FCC11_WORLD = 0x19, FCC13_WORLD = 0xE4, FCC14_FCCB = 0xE6, - +#ifdef CONFIG_BAND_6GHZ + FCC15_FCCA = 0xEA, + FCC16_FCCA = 0xE8, + FCC17_FCCA = 0xE9, +#endif ETSI1_WORLD = 0x37, ETSI3_WORLD = 0x36, ETSI4_WORLD = 0x30, @@ -319,17 +324,17 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ALBANIA, ETSI1_WORLD, "AL", 40, 160, 0}, {CTRY_ALGERIA, APL13_WORLD, "DZ", 40, 160, 0}, {CTRY_AMERICAN_SAMOA, FCC3_FCCA, "AS", 40, 160, 0}, - {CTRY_ANDORRA, ETSI3_WORLD, "AD", 40, 160, 0}, + {CTRY_ANDORRA, ETSI1_WORLD, "AD", 40, 160, 0}, {CTRY_ANGUILLA, ETSI1_WORLD, "AI", 40, 160, 0}, {CTRY_ANTIGUA_AND_BARBUDA, ETSI1_WORLD, "AG", 40, 160, 0}, {CTRY_ARGENTINA, APL16_ETSIC, "AR", 40, 160, 0}, - {CTRY_ARMENIA, ETSI4_WORLD, "AM", 40, 20, 0}, + {CTRY_ARMENIA, APL4_WORLD, "AM", 40, 160, 0}, {CTRY_ARUBA, ETSI1_WORLD, "AW", 40, 160, 0}, {CTRY_AUSTRALIA, FCC6_WORLD, "AU", 40, 160, 0}, {CTRY_AUSTRIA, ETSI1_WORLD, "AT", 40, 160, 0}, {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", 40, 160, 0}, {CTRY_BAHAMAS, FCC3_WORLD, "BS", 40, 160, 0}, - {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 20, 0}, + {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 160, 0}, {CTRY_BANGLADESH, APL1_WORLD, "BD", 40, 160, 0}, {CTRY_BARBADOS, FCC2_WORLD, "BB", 40, 160, 0}, {CTRY_BELARUS, ETSI1_WORLD, "BY", 40, 160, 0}, @@ -337,10 +342,10 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_BELIZE, ETSI8_WORLD, "BZ", 40, 160, 0}, {CTRY_BERMUDA, FCC3_FCCA, "BM", 40, 160, 0}, {CTRY_BHUTAN, ETSI1_WORLD, "BT", 40, 160, 0}, - {CTRY_BOLIVIA, APL8_WORLD, "BO", 40, 160, 0}, + {CTRY_BOLIVIA, FCC8_WORLD, "BO", 40, 160, 0}, {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", 40, 160, 0}, {CTRY_BRAZIL, FCC3_ETSIC, "BR", 40, 160, 0}, - {CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN", 40, 160, 0}, + {CTRY_BRUNEI_DARUSSALAM, FCC8_WORLD, "BN", 40, 160, 0}, {CTRY_BULGARIA, ETSI1_WORLD, "BG", 40, 160, 0}, {CTRY_BURKINA_FASO, FCC3_WORLD, "BF", 40, 160, 0}, {CTRY_CAMBODIA, ETSI1_WORLD, "KH", 40, 160, 0}, @@ -362,9 +367,9 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_DENMARK, ETSI1_WORLD, "DK", 40, 160, 0}, {CTRY_DOMINICA, FCC1_FCCA, "DM", 40, 160, 0}, {CTRY_DOMINICAN_REPUBLIC, FCC3_FCCA, "DO", 40, 160, 0}, - {CTRY_ECUADOR, FCC3_WORLD, "EC", 40, 20, 0}, + {CTRY_ECUADOR, FCC3_FCCA, "EC", 40, 160, 0}, {CTRY_EGYPT, ETSI3_WORLD, "EG", 40, 160, 0}, - {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", 40, 20, 0}, + {CTRY_EL_SALVADOR, FCC3_WORLD, "SV", 40, 160, 0}, {CTRY_ESTONIA, ETSI1_WORLD, "EE", 40, 160, 0}, {CTRY_ETHIOPIA, ETSI1_WORLD, "ET", 40, 160, 0}, {CTRY_FALKLAND_ISLANDS, ETSI1_WORLD, "FK", 40, 160, 0}, @@ -401,12 +406,14 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ISRAEL, ETSI3_WORLD, "IL", 40, 160, 0}, {CTRY_ITALY, ETSI1_WORLD, "IT", 40, 160, 0}, {CTRY_JAMAICA, FCC13_WORLD, "JM", 40, 160, 0}, + {CTRY_JAPAN, MKK17_MKKC, "JP", 40, 160, 0}, + {CTRY_JAPAN15, MKK17_MKKC, "JP", 40, 160, 0}, {CTRY_JERSEY, ETSI1_WORLD, "JE", 40, 160, 0}, {CTRY_JORDAN, APL4_WORLD, "JO", 40, 160, 0}, {CTRY_KAZAKHSTAN, MKK5_MKKC, "KZ", 40, 160, 0}, {CTRY_KENYA, ETSI13_WORLD, "KE", 40, 160, 0}, {CTRY_KOREA_ROC, APL9_MKKC, "KR", 40, 160, 0}, - {CTRY_KUWAIT, ETSI3_WORLD, "KW", 40, 160, 0}, + {CTRY_KUWAIT, ETSI1_WORLD, "KW", 40, 160, 0}, {CTRY_LATVIA, ETSI1_WORLD, "LV", 40, 160, 0}, {CTRY_LEBANON, FCC3_WORLD, "LB", 40, 160, 0}, {CTRY_LESOTHO, ETSI1_WORLD, "LS", 40, 160, 0}, @@ -439,7 +446,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN", 40, 160, 0}, {CTRY_NEW_CALEDONIA, ETSI1_WORLD, "NC", 40, 160, 0}, {CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ", 40, 160, 0}, - {CTRY_NIGERIA, APL8_WORLD, "NG", 40, 160, 0}, + {CTRY_NIGERIA, APL6_WORLD, "NG", 40, 160, 0}, {CTRY_NORTHERN_MARIANA_ISLANDS, FCC3_FCCA, "MP", 40, 160, 0}, {CTRY_NICARAGUA, FCC3_FCCA, "NI", 40, 160, 0}, {CTRY_NIUE, ETSI1_WORLD, "NU", 40, 160, 0}, @@ -483,7 +490,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", 40, 160, 0}, {CTRY_SPAIN, ETSI1_WORLD, "ES", 40, 160, 0}, {CTRY_SURINAME, ETSI1_WORLD, "SR", 40, 160, 0}, - {CTRY_SRI_LANKA, FCC3_WORLD, "LK", 40, 20, 0}, + {CTRY_SRI_LANKA, FCC3_ETSIC, "LK", 40, 160, 0}, {CTRY_SVALBARD_AND_JAN_MAYEN, FCC6_WORLD, "SJ", 40, 160, 0}, {CTRY_SWEDEN, ETSI1_WORLD, "SE", 40, 160, 0}, {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", 40, 160, 0}, @@ -510,10 +517,8 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_VIRGIN_ISLANDS, FCC3_FCCA, "VI", 40, 160, 0}, {CTRY_VIRGIN_ISLANDS_BRITISH, ETSI1_WORLD, "VG", 40, 160, 0}, {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF", 40, 160, 0}, - {CTRY_YEMEN, NULL1_WORLD, "YE", 40, 0, 0}, + {CTRY_YEMEN, ETSI1_WORLD, "YE", 40, 160, 0}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", 40, 160, 0}, - {CTRY_JAPAN, MKK5_MKKC, "JP", 40, 160, 0}, - {CTRY_JAPAN15, MKK5_MKKC, "JP", 40, 160, 0}, }; #else #ifdef WLAN_FEATURE_DSRC @@ -523,17 +528,17 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ALBANIA, ETSI13_WORLD, "AL", 40, 160, 0}, {CTRY_ALGERIA, APL13_WORLD, "DZ", 40, 160, 0}, {CTRY_AMERICAN_SAMOA, FCC3_FCCA, "AS", 40, 160, 0}, - {CTRY_ANDORRA, ETSI3_WORLD, "AD", 40, 160, 0}, + {CTRY_ANDORRA, ETSI1_WORLD, "AD", 40, 160, 0}, {CTRY_ANGUILLA, ETSI1_WORLD, "AI", 40, 160, 0}, {CTRY_ANTIGUA_AND_BARBUDA, ETSI10_WORLD, "AG", 40, 160, 0}, {CTRY_ARGENTINA, APL17_ETSIC, "AR", 40, 160, 0}, - {CTRY_ARMENIA, ETSI4_WORLD, "AM", 40, 20, 0}, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", 40, 160, 0}, {CTRY_ARUBA, ETSI1_WORLD, "AW", 40, 160, 0}, {CTRY_AUSTRALIA, FCC6_WORLD, "AU", 40, 160, 0}, {CTRY_AUSTRIA, ETSI10_WORLD, "AT", 40, 160, 0}, {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", 40, 160, 0}, {CTRY_BAHAMAS, FCC3_WORLD, "BS", 40, 160, 0}, - {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 20, 0}, + {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 160, 0}, {CTRY_BANGLADESH, APL1_WORLD, "BD", 40, 160, 0}, {CTRY_BARBADOS, FCC2_WORLD, "BB", 40, 160, 0}, {CTRY_BELARUS, ETSI1_WORLD, "BY", 40, 160, 0}, @@ -541,10 +546,10 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_BELIZE, ETSI8_WORLD, "BZ", 40, 160, 0}, {CTRY_BERMUDA, FCC3_FCCA, "BM", 40, 160, 0}, {CTRY_BHUTAN, ETSI1_WORLD, "BT", 40, 160, 0}, - {CTRY_BOLIVIA, APL8_WORLD, "BO", 40, 160, 0}, + {CTRY_BOLIVIA, FCC3_WORLD, "BO", 40, 160, 0}, {CTRY_BOSNIA_HERZ, ETSI13_WORLD, "BA", 40, 160, 0}, {CTRY_BRAZIL, FCC3_ETSIC, "BR", 40, 160, 0}, - {CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN", 40, 160, 0}, + {CTRY_BRUNEI_DARUSSALAM, FCC3_WORLD, "BN", 40, 160, 0}, {CTRY_BULGARIA, ETSI10_WORLD, "BG", 40, 160, 0}, {CTRY_BURKINA_FASO, FCC3_WORLD, "BF", 40, 160, 0}, {CTRY_CAMBODIA, ETSI1_WORLD, "KH", 40, 160, 0}, @@ -566,9 +571,9 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_DENMARK, ETSI10_WORLD, "DK", 40, 160, 0}, {CTRY_DOMINICA, FCC2_FCCA, "DM", 40, 160, 0}, {CTRY_DOMINICAN_REPUBLIC, FCC3_FCCA, "DO", 40, 160, 0}, - {CTRY_ECUADOR, FCC3_WORLD, "EC", 40, 20, 0}, + {CTRY_ECUADOR, FCC3_FCCA, "EC", 40, 160, 0}, {CTRY_EGYPT, ETSI3_WORLD, "EG", 40, 160, 0}, - {CTRY_EL_SALVADOR, FCC2_WORLD, "SV", 40, 20, 0}, + {CTRY_EL_SALVADOR, FCC3_WORLD, "SV", 40, 160, 0}, {CTRY_ESTONIA, ETSI10_WORLD, "EE", 40, 160, 0}, {CTRY_ETHIOPIA, ETSI1_WORLD, "ET", 40, 160, 0}, {CTRY_FALKLAND_ISLANDS, ETSI10_WORLD, "FK", 40, 160, 0}, @@ -605,12 +610,15 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ISRAEL, ETSI3_WORLD, "IL", 40, 160, 0}, {CTRY_ITALY, ETSI10_WORLD, "IT", 40, 160, 0}, {CTRY_JAMAICA, FCC13_WORLD, "JM", 40, 160, 0}, + {CTRY_JAPAN, MKK17_MKKC, "JP", 40, 160, 0}, + {CTRY_JAPAN15, MKK5_MKKC, "JP", 40, 160, 0}, + {CTRY_XA, MKK5_MKKA, "XA", 40, 160, 0}, {CTRY_JERSEY, ETSI10_WORLD, "JE", 40, 160, 0}, {CTRY_JORDAN, APL4_WORLD, "JO", 40, 160, 0}, {CTRY_KAZAKHSTAN, MKK5_MKKC, "KZ", 40, 160, 0}, {CTRY_KENYA, ETSI13_WORLD, "KE", 40, 160, 0}, {CTRY_KOREA_ROC, APL9_MKKC, "KR", 40, 160, 0}, - {CTRY_KUWAIT, ETSI3_WORLD, "KW", 40, 160, 0}, + {CTRY_KUWAIT, ETSI13_WORLD, "KW", 40, 160, 0}, {CTRY_LATVIA, ETSI10_WORLD, "LV", 40, 160, 0}, {CTRY_LEBANON, FCC3_WORLD, "LB", 40, 160, 0}, {CTRY_LESOTHO, ETSI1_WORLD, "LS", 40, 160, 0}, @@ -643,7 +651,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_NETHERLANDS_ANTILLES, ETSI10_WORLD, "AN", 40, 160, 0}, {CTRY_NEW_CALEDONIA, ETSI10_WORLD, "NC", 40, 160, 0}, {CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ", 40, 160, 0}, - {CTRY_NIGERIA, APL8_WORLD, "NG", 40, 160, 0}, + {CTRY_NIGERIA, APL6_WORLD, "NG", 40, 160, 0}, {CTRY_NORTHERN_MARIANA_ISLANDS, FCC10_FCCA, "MP", 40, 160, 0}, {CTRY_NICARAGUA, FCC3_FCCA, "NI", 40, 160, 0}, {CTRY_NIUE, ETSI10_WORLD, "NU", 40, 160, 0}, @@ -687,7 +695,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", 40, 160, 0}, {CTRY_SPAIN, ETSI10_WORLD, "ES", 40, 160, 0}, {CTRY_SURINAME, ETSI1_WORLD, "SR", 40, 160, 0}, - {CTRY_SRI_LANKA, FCC3_WORLD, "LK", 40, 20, 0}, + {CTRY_SRI_LANKA, FCC3_ETSIC, "LK", 40, 160, 0}, {CTRY_SVALBARD_AND_JAN_MAYEN, FCC6_WORLD, "SJ", 40, 160, 0}, {CTRY_SWEDEN, ETSI10_WORLD, "SE", 40, 160, 0}, {CTRY_SWITZERLAND, ETSI10_WORLD, "CH", 40, 160, 0}, @@ -714,10 +722,8 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_VIRGIN_ISLANDS, FCC10_FCCA, "VI", 40, 160, 0}, {CTRY_VIRGIN_ISLANDS_BRITISH, ETSI10_WORLD, "VG", 40, 160, 0}, {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF", 40, 160, 0}, - {CTRY_YEMEN, NULL1_WORLD, "YE", 40, 0, 0}, + {CTRY_YEMEN, ETSI1_WORLD, "YE", 40, 160, 0}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", 40, 160, 0}, - {CTRY_JAPAN, MKK5_MKKC, "JP", 40, 160, 0}, - {CTRY_XA, MKK5_MKKA, "XA", 40, 160, 0}, }; #else const struct country_code_to_reg_domain g_all_countries[] = { @@ -726,17 +732,17 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ALBANIA, ETSI13_WORLD, "AL", 40, 160, 0}, {CTRY_ALGERIA, APL13_WORLD, "DZ", 40, 160, 0}, {CTRY_AMERICAN_SAMOA, FCC3_FCCA, "AS", 40, 160, 0}, - {CTRY_ANDORRA, ETSI3_WORLD, "AD", 40, 160, 0}, + {CTRY_ANDORRA, ETSI13_WORLD, "AD", 40, 160, 0}, {CTRY_ANGUILLA, ETSI1_WORLD, "AI", 40, 160, 0}, {CTRY_ANTIGUA_AND_BARBUDA, ETSI13_WORLD, "AG", 40, 160, 0}, {CTRY_ARGENTINA, APL17_ETSIC, "AR", 40, 160, 0}, - {CTRY_ARMENIA, ETSI4_WORLD, "AM", 40, 20, 0}, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", 40, 160, 0}, {CTRY_ARUBA, ETSI1_WORLD, "AW", 40, 160, 0}, {CTRY_AUSTRALIA, FCC6_WORLD, "AU", 40, 160, 0}, {CTRY_AUSTRIA, ETSI13_WORLD, "AT", 40, 160, 0}, {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", 40, 160, 0}, {CTRY_BAHAMAS, FCC3_WORLD, "BS", 40, 160, 0}, - {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 20, 0}, + {CTRY_BAHRAIN, APL15_WORLD, "BH", 40, 160, 0}, {CTRY_BANGLADESH, APL1_WORLD, "BD", 40, 160, 0}, {CTRY_BARBADOS, FCC2_WORLD, "BB", 40, 160, 0}, {CTRY_BELARUS, ETSI1_WORLD, "BY", 40, 160, 0}, @@ -744,10 +750,10 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_BELIZE, ETSI8_WORLD, "BZ", 40, 160, 0}, {CTRY_BERMUDA, FCC3_FCCA, "BM", 40, 160, 0}, {CTRY_BHUTAN, ETSI1_WORLD, "BT", 40, 160, 0}, - {CTRY_BOLIVIA, APL8_WORLD, "BO", 40, 160, 0}, + {CTRY_BOLIVIA, FCC3_WORLD, "BO", 40, 160, 0}, {CTRY_BOSNIA_HERZ, ETSI13_WORLD, "BA", 40, 160, 0}, {CTRY_BRAZIL, FCC3_ETSIC, "BR", 40, 160, 0}, - {CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN", 40, 160, 0}, + {CTRY_BRUNEI_DARUSSALAM, FCC3_WORLD, "BN", 40, 160, 0}, {CTRY_BULGARIA, ETSI13_WORLD, "BG", 40, 160, 0}, {CTRY_BURKINA_FASO, FCC3_WORLD, "BF", 40, 160, 0}, {CTRY_CAMBODIA, ETSI1_WORLD, "KH", 40, 160, 0}, @@ -769,9 +775,9 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_DENMARK, ETSI13_WORLD, "DK", 40, 160, 0}, {CTRY_DOMINICA, FCC2_FCCA, "DM", 40, 160, 0}, {CTRY_DOMINICAN_REPUBLIC, FCC3_FCCA, "DO", 40, 160, 0}, - {CTRY_ECUADOR, FCC3_WORLD, "EC", 40, 20, 0}, + {CTRY_ECUADOR, FCC3_FCCA, "EC", 40, 160, 0}, {CTRY_EGYPT, ETSI3_WORLD, "EG", 40, 160, 0}, - {CTRY_EL_SALVADOR, FCC2_WORLD, "SV", 40, 20, 0}, + {CTRY_EL_SALVADOR, FCC3_WORLD, "SV", 40, 160, 0}, {CTRY_ESTONIA, ETSI13_WORLD, "EE", 40, 160, 0}, {CTRY_ETHIOPIA, ETSI1_WORLD, "ET", 40, 160, 0}, {CTRY_FALKLAND_ISLANDS, ETSI13_WORLD, "FK", 40, 160, 0}, @@ -808,12 +814,15 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_ISRAEL, ETSI3_WORLD, "IL", 40, 160, 0}, {CTRY_ITALY, ETSI13_WORLD, "IT", 40, 160, 0}, {CTRY_JAMAICA, FCC13_WORLD, "JM", 40, 160, 0}, + {CTRY_JAPAN, MKK17_MKKC, "JP", 40, 160, 0}, + {CTRY_JAPAN15, MKK5_MKKC, "JP", 40, 160, 0}, + {CTRY_XA, MKK5_MKKA, "XA", 40, 160, 0}, {CTRY_JERSEY, ETSI13_WORLD, "JE", 40, 160, 0}, {CTRY_JORDAN, APL4_WORLD, "JO", 40, 160, 0}, {CTRY_KAZAKHSTAN, MKK5_MKKC, "KZ", 40, 160, 0}, {CTRY_KENYA, ETSI13_WORLD, "KE", 40, 160, 0}, {CTRY_KOREA_ROC, APL9_MKKC, "KR", 40, 160, 0}, - {CTRY_KUWAIT, ETSI3_WORLD, "KW", 40, 160, 0}, + {CTRY_KUWAIT, ETSI13_WORLD, "KW", 40, 160, 0}, {CTRY_LATVIA, ETSI13_WORLD, "LV", 40, 160, 0}, {CTRY_LEBANON, FCC3_WORLD, "LB", 40, 160, 0}, {CTRY_LESOTHO, ETSI1_WORLD, "LS", 40, 160, 0}, @@ -846,7 +855,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_NETHERLANDS_ANTILLES, ETSI13_WORLD, "AN", 40, 160, 0}, {CTRY_NEW_CALEDONIA, ETSI13_WORLD, "NC", 40, 160, 0}, {CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ", 40, 160, 0}, - {CTRY_NIGERIA, APL8_WORLD, "NG", 40, 160, 0}, + {CTRY_NIGERIA, APL6_WORLD, "NG", 40, 160, 0}, {CTRY_NORTHERN_MARIANA_ISLANDS, FCC3_FCCA, "MP", 40, 160, 0}, {CTRY_NICARAGUA, FCC3_FCCA, "NI", 40, 160, 0}, {CTRY_NIUE, ETSI13_WORLD, "NU", 40, 160, 0}, @@ -890,7 +899,7 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", 40, 160, 0}, {CTRY_SPAIN, ETSI13_WORLD, "ES", 40, 160, 0}, {CTRY_SURINAME, ETSI1_WORLD, "SR", 40, 160, 0}, - {CTRY_SRI_LANKA, FCC3_WORLD, "LK", 40, 20, 0}, + {CTRY_SRI_LANKA, FCC3_ETSIC, "LK", 40, 160, 0}, {CTRY_SVALBARD_AND_JAN_MAYEN, FCC6_WORLD, "SJ", 40, 160, 0}, {CTRY_SWEDEN, ETSI13_WORLD, "SE", 40, 160, 0}, {CTRY_SWITZERLAND, ETSI13_WORLD, "CH", 40, 160, 0}, @@ -917,10 +926,8 @@ const struct country_code_to_reg_domain g_all_countries[] = { {CTRY_VIRGIN_ISLANDS, FCC3_FCCA, "VI", 40, 160, 0}, {CTRY_VIRGIN_ISLANDS_BRITISH, ETSI13_WORLD, "VG", 40, 160, 0}, {CTRY_WALLIS_AND_FUTUNA, ETSI1_WORLD, "WF", 40, 160, 0}, - {CTRY_YEMEN, NULL1_WORLD, "YE", 40, 0, 0}, + {CTRY_YEMEN, ETSI1_WORLD, "YE", 40, 160, 0}, {CTRY_ZIMBABWE, ETSI1_WORLD, "ZW", 40, 160, 0}, - {CTRY_JAPAN, MKK5_MKKC, "JP", 40, 160, 0}, - {CTRY_XA, MKK5_MKKA, "XA", 40, 160, 0}, }; #endif #endif @@ -954,6 +961,11 @@ enum reg_domains_5g { FCC11, FCC13, FCC14, +#ifdef CONFIG_BAND_6GHZ + FCC15, + FCC16, + FCC17, +#endif ETSI1, ETSI3, ETSI4, @@ -1013,10 +1025,16 @@ const struct reg_domain_pair g_reg_dmn_pairs[] = { {FCC6_WORLD, FCC6, WORLD}, {FCC6_FCCA, FCC6, FCCA}, {FCC8_FCCA, FCC8, FCCA}, + {FCC8_WORLD, FCC8, WORLD}, + {FCC10_FCCA, FCC10, FCCA}, {FCC11_WORLD, FCC11, WORLD}, {FCC13_WORLD, FCC13, WORLD}, {FCC14_FCCB, FCC14, FCCB}, - +#ifdef CONFIG_BAND_6GHZ + {FCC15_FCCA, FCC15, FCCA}, + {FCC16_FCCA, FCC16, FCCA}, + {FCC17_FCCA, FCC17, FCCA}, +#endif {ETSI1_WORLD, ETSI1, WORLD}, {ETSI3_WORLD, ETSI3, WORLD}, {ETSI4_WORLD, ETSI4, WORLD}, @@ -1144,6 +1162,7 @@ enum reg_rules_5g { CHAN_5170_5250_7, CHAN_5170_5250_8, CHAN_5170_5250_9, + CHAN_5170_5250_10, CHAN_5170_5330_1, CHAN_5170_5330_2, CHAN_5250_5330_1, @@ -1160,6 +1179,8 @@ enum reg_rules_5g { CHAN_5250_5330_12, CHAN_5250_5330_13, CHAN_5250_5330_14, + CHAN_5250_5330_15, + CHAN_5250_5330_16, CHAN_5490_5730_1, CHAN_5490_5730_2, CHAN_5490_5730_3, @@ -1174,6 +1195,7 @@ enum reg_rules_5g { CHAN_5490_5710_5, CHAN_5490_5710_6, CHAN_5490_5710_7, + CHAN_5490_5710_8, CHAN_5490_5590_1, CHAN_5490_5590_2, CHAN_5490_5590_3, @@ -1208,6 +1230,16 @@ enum reg_rules_5g { CHAN_5855_5875_1, CHAN_5850_5925_1, CHAN_5850_5925_2, +#ifdef CONFIG_BAND_6GHZ + CHAN_5935_6435_1, + CHAN_5935_6435_2, + CHAN_6435_6535_1, + CHAN_6435_6535_2, + CHAN_6535_6875_1, + CHAN_6535_6875_2, + CHAN_6875_7115_1, + CHAN_6875_7115_2, +#endif }; const struct regulatory_rule reg_rules_5g[] = { @@ -1224,6 +1256,7 @@ const struct regulatory_rule reg_rules_5g[] = { [CHAN_5170_5250_7] = {5170, 5250, 80, 20, REGULATORY_CHAN_INDOOR_ONLY}, [CHAN_5170_5250_8] = {5170, 5250, 80, 23, REGULATORY_CHAN_INDOOR_ONLY}, [CHAN_5170_5250_9] = {5170, 5250, 40, 30, 0}, + [CHAN_5170_5250_10] = {5170, 5250, 20, 20, REGULATORY_CHAN_INDOOR_ONLY}, [CHAN_5170_5330_1] = {5170, 5330, 160, 20, REGULATORY_CHAN_NO_IR}, [CHAN_5170_5330_2] = {5170, 5330, 160, 24, 0}, [CHAN_5250_5330_1] = {5250, 5330, 80, 23, REGULATORY_CHAN_RADAR}, @@ -1242,6 +1275,9 @@ const struct regulatory_rule reg_rules_5g[] = { [CHAN_5250_5330_13] = {5250, 5330, 40, 30, REGULATORY_CHAN_RADAR}, [CHAN_5250_5330_14] = {5250, 5330, 80, 20, REGULATORY_CHAN_RADAR | REGULATORY_CHAN_INDOOR_ONLY}, + [CHAN_5250_5330_15] = {5250, 5330, 20, 20, REGULATORY_CHAN_RADAR | + REGULATORY_CHAN_INDOOR_ONLY}, + [CHAN_5250_5330_16] = {5250, 5330, 80, 23, REGULATORY_CHAN_INDOOR_ONLY}, [CHAN_5490_5730_1] = {5490, 5730, 160, 24, REGULATORY_CHAN_RADAR}, [CHAN_5490_5730_2] = {5490, 5730, 160, 20, REGULATORY_CHAN_NO_IR}, [CHAN_5490_5730_3] = {5490, 5730, 160, 30, 0}, @@ -1256,6 +1292,7 @@ const struct regulatory_rule reg_rules_5g[] = { [CHAN_5490_5710_5] = {5490, 5710, 160, 24, REGULATORY_CHAN_RADAR}, [CHAN_5490_5710_6] = {5490, 5710, 160, 26, REGULATORY_CHAN_RADAR}, [CHAN_5490_5710_7] = {5490, 5710, 160, 23, REGULATORY_CHAN_RADAR}, + [CHAN_5490_5710_8] = {5490, 5710, 20, 27, REGULATORY_CHAN_RADAR}, [CHAN_5490_5590_1] = {5490, 5590, 80, 24, REGULATORY_CHAN_RADAR}, [CHAN_5490_5590_2] = {5490, 5590, 80, 30, 0}, [CHAN_5490_5590_3] = {5490, 5590, 80, 36, 0}, @@ -1290,6 +1327,16 @@ const struct regulatory_rule reg_rules_5g[] = { [CHAN_5855_5875_1] = {5855, 5875, 20, 30, 0}, [CHAN_5850_5925_1] = {5850, 5925, 20, 24, 0}, [CHAN_5850_5925_2] = {5850, 5925, 20, 30, 0}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_5935_6435_1] = {5935, 6435, 160, 18, REGULATORY_CHAN_AFC}, + [CHAN_5935_6435_2] = {5935, 6435, 160, 30, REGULATORY_CHAN_AFC}, + [CHAN_6435_6535_1] = {6435, 6535, 100, 18, REGULATORY_CHAN_INDOOR_ONLY}, + [CHAN_6435_6535_2] = {6435, 6535, 100, 24, REGULATORY_CHAN_INDOOR_ONLY}, + [CHAN_6535_6875_1] = {6535, 6875, 160, 18, REGULATORY_CHAN_AFC}, + [CHAN_6535_6875_2] = {6535, 6875, 160, 30, REGULATORY_CHAN_AFC}, + [CHAN_6875_7115_1] = {6875, 7115, 160, 18, REGULATORY_CHAN_INDOOR_ONLY}, + [CHAN_6875_7115_2] = {6875, 7115, 160, 24, REGULATORY_CHAN_INDOOR_ONLY}, +#endif }; @@ -1345,6 +1392,33 @@ const struct regdomain regdomains_5g[] = { CHAN_5490_5730_4, CHAN_5735_5835_2} }, +#ifdef CONFIG_BAND_6GHZ + [FCC15] = {CTL_FCC, DFS_FCC_REGION, 2, 0, 8, {CHAN_5170_5250_5, + CHAN_5250_5330_7, + CHAN_5490_5730_1, + CHAN_5735_5835_2, + CHAN_5935_6435_1, + CHAN_6435_6535_1, + CHAN_6535_6875_1, + CHAN_6875_7115_1} }, + + [FCC16] = {CTL_FCC, DFS_FCC_REGION, 2, 0, 8, {CHAN_5170_5250_4, + CHAN_5250_5330_7, + CHAN_5490_5730_1, + CHAN_5735_5835_2, + CHAN_5935_6435_2, + CHAN_6435_6535_2, + CHAN_6535_6875_2, + CHAN_6875_7115_2} }, + + [FCC17] = {CTL_FCC, DFS_FCC_REGION, 2, 0, 6, {CHAN_5170_5250_4, + CHAN_5250_5330_7, + CHAN_5490_5730_1, + CHAN_5735_5835_2, + CHAN_5935_6435_2, + CHAN_6535_6875_2} }, +#endif + [ETSI1] = {CTL_ETSI, DFS_ETSI_REGION, 2, 0, 3, {CHAN_5170_5250_8, CHAN_5250_5330_12, CHAN_5490_5710_1} }, @@ -1370,9 +1444,9 @@ const struct regdomain regdomains_5g[] = { CHAN_5490_5710_3, CHAN_5850_5925_2} }, - [ETSI11] = {CTL_ETSI, DFS_ETSI_REGION, 10, 0, 4, {CHAN_5170_5250_7, - CHAN_5250_5330_14, - CHAN_5490_5710_3, + [ETSI11] = {CTL_ETSI, DFS_ETSI_REGION, 10, 0, 4, {CHAN_5170_5250_10, + CHAN_5250_5330_15, + CHAN_5490_5710_8, CHAN_5735_5875_1} }, [ETSI12] = {CTL_ETSI, DFS_ETSI_REGION, 2, 0, 4, {CHAN_5170_5250_7, @@ -1436,8 +1510,8 @@ const struct regdomain regdomains_5g[] = { CHAN_5250_5330_1, CHAN_5735_5835_4} }, - [APL15] = {CTL_FCC, DFS_UNINIT_REGION, 2, 0, 3, {CHAN_5170_5250_2, - CHAN_5250_5330_5, + [APL15] = {CTL_FCC, DFS_UNINIT_REGION, 2, 0, 3, {CHAN_5170_5250_8, + CHAN_5250_5330_16, CHAN_5735_5835_4} }, [APL16] = {CTL_FCC, DFS_UNINIT_REGION, 2, 0, 5, {CHAN_5170_5250_1, @@ -1484,9 +1558,9 @@ const struct regdomain regdomains_5g[] = { [MKK16] = {CTL_MKK, DFS_MKK_REGION, 2, 0, 1, {CHAN_5490_5710_6} }, - [MKK17] = {CTL_MKK, DFS_MKK_REGION, 2, 0, 3, {CHAN_5170_5250_8, + [MKK17] = {CTL_MKK, DFS_MKKN_REGION, 2, 0, 3, {CHAN_5170_5250_8, CHAN_5250_5330_12, - CHAN_5490_5710_7} }, + CHAN_5490_5730_6} }, [WORLD_5G_1] = {CTL_NONE, DFS_UNINIT_REGION, 2, 0, 2, {CHAN_5170_5330_1, @@ -1584,3 +1658,11 @@ bool reg_etsi13_regdmn(uint8_t reg_dmn) { return reg_dmn == ETSI13; } + +bool reg_en302_502_regdmn(uint16_t regdmn) +{ + return ((regdmn == ETSI11_WORLD) || + (regdmn == ETSI12_WORLD) || + (regdmn == ETSI14_WORLD) || + (regdmn == ETSI15_WORLD)); +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.h index 8183a27a70dd9fd7d11549e7978adc9a8bd4db27..b07c14339a647fc1a577e1e3162ad752c3d992a4 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_db.h @@ -104,4 +104,12 @@ QDF_STATUS reg_get_default_country(uint16_t *default_country); * Return: true or false */ bool reg_etsi13_regdmn(uint8_t reg_dmn); + +/** + * reg_en302_502_regdmn() - Check if the reg domain is en302_502 applicable. + * @reg_dmn: Regulatory domain pair ID. + * + * Return: True if EN302_502 applicable, else false. + */ +bool reg_en302_502_regdmn(uint16_t reg_dmn); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_lte.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_lte.c index 2a31e23c447fdbd85ac6abbb4f504025ac3e0f11..2687c314ffe6104212c6c6fca912a46fc79220cd 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_lte.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_lte.c @@ -48,8 +48,8 @@ static QDF_STATUS reg_process_ch_avoid_freq(struct wlan_objmgr_psoc *psoc, enum channel_enum ch_loop; enum channel_enum start_ch_idx; enum channel_enum end_ch_idx; - uint16_t start_channel; - uint16_t end_channel; + uint8_t start_channel; + uint8_t end_channel; uint32_t i; struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; struct ch_avoid_freq_type *range; @@ -62,7 +62,7 @@ static QDF_STATUS reg_process_ch_avoid_freq(struct wlan_objmgr_psoc *psoc, for (i = 0; i < psoc_priv_obj->avoid_freq_list.ch_avoid_range_cnt; i++) { - if (psoc_priv_obj->unsafe_chan_list.ch_cnt >= NUM_CHANNELS) { + if (psoc_priv_obj->unsafe_chan_list.chan_cnt >= NUM_CHANNELS) { reg_warn("LTE Coex unsafe channel list full"); break; } @@ -106,10 +106,10 @@ static QDF_STATUS reg_process_ch_avoid_freq(struct wlan_objmgr_psoc *psoc, for (ch_loop = start_ch_idx; ch_loop <= end_ch_idx; ch_loop++) { - psoc_priv_obj->unsafe_chan_list.ch_list[ - psoc_priv_obj->unsafe_chan_list.ch_cnt++] = - REG_CH_NUM(ch_loop); - if (psoc_priv_obj->unsafe_chan_list.ch_cnt >= + psoc_priv_obj->unsafe_chan_list.chan_freq_list[ + psoc_priv_obj->unsafe_chan_list.chan_cnt++] = + REG_CH_TO_FREQ(ch_loop); + if (psoc_priv_obj->unsafe_chan_list.chan_cnt >= NUM_CHANNELS) { reg_warn("LTECoex unsafe ch list full"); break; @@ -117,16 +117,15 @@ static QDF_STATUS reg_process_ch_avoid_freq(struct wlan_objmgr_psoc *psoc, } } - - if (!psoc_priv_obj->unsafe_chan_list.ch_cnt) + if (!psoc_priv_obj->unsafe_chan_list.chan_cnt) return QDF_STATUS_SUCCESS; - for (ch_loop = 0; ch_loop < psoc_priv_obj->unsafe_chan_list.ch_cnt; + for (ch_loop = 0; ch_loop < psoc_priv_obj->unsafe_chan_list.chan_cnt; ch_loop++) { if (ch_loop >= NUM_CHANNELS) break; reg_debug("Unsafe freq %d", - psoc_priv_obj->unsafe_chan_list.ch_list[ch_loop]); + psoc_priv_obj->unsafe_chan_list.chan_freq_list[ch_loop]); } return QDF_STATUS_SUCCESS; @@ -186,6 +185,11 @@ QDF_STATUS reg_process_ch_avoid_event(struct wlan_objmgr_psoc *psoc, reg_err("reg psoc private obj is NULL"); return QDF_STATUS_E_FAILURE; } + if (CH_AVOID_RULE_DO_NOT_RESTART == + psoc_priv_obj->restart_beaconing) { + reg_debug("skipping all LTE Coex unsafe channel range"); + return QDF_STATUS_SUCCESS; + } /* Make unsafe channel list */ reg_debug("band count %d", ch_avoid_event->ch_avoid_range_cnt); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_offload_11d_scan.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_offload_11d_scan.c index 9c67ef618ac5c21bbc177c1f8df69c6ebd46f387..2099d3847ad8d4a3d55749bcc2001a35ce95bb29 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_offload_11d_scan.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_offload_11d_scan.c @@ -406,7 +406,7 @@ QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc, if (tx_ops->set_country_code) { tx_ops->set_country_code(psoc, &country_code); } else { - reg_err("country set handler is not present"); + reg_err("NULL country set handler"); for (ctr = 0; ctr < psoc_priv_obj->num_phy; ctr++) psoc_priv_obj->new_11d_ctry_pending[ctr] = false; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.c index c6eb0ce191f0fe78892fe528cfd2940236d48479..d661630d032f68d82843ee4da50787b9c5f16031 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,94 +33,225 @@ #include #include "reg_build_chan_list.h" #include "reg_opclass.h" +#include "reg_services_common.h" #ifdef HOST_OPCLASS static struct reg_dmn_supp_op_classes reg_dmn_curr_supp_opp_classes = { 0 }; #endif static const struct reg_dmn_op_class_map_t global_op_class[] = { - {81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, - {82, 25, BW20, {14} }, - {83, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} }, - {84, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} }, - {115, 20, BW20, {36, 40, 44, 48} }, - {116, 40, BW40_LOW_PRIMARY, {36, 44} }, - {117, 40, BW40_HIGH_PRIMARY, {40, 48} }, - {118, 20, BW20, {52, 56, 60, 64} }, - {119, 40, BW40_LOW_PRIMARY, {52, 60} }, - {120, 40, BW40_HIGH_PRIMARY, {56, 64} }, - {121, 20, BW20, - {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, - {122, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, - {123, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, - {125, 20, BW20, {149, 153, 157, 161, 165, 169} }, - {126, 40, BW40_LOW_PRIMARY, {149, 157} }, - {127, 40, BW40_HIGH_PRIMARY, {153, 161} }, - {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, - 112, 116, 120, 124, 128, 132, 136, 140, 144, - 149, 153, 157, 161} }, - {0, 0, 0, {0} }, + {81, 25, BW20, BIT(BEHAV_NONE), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {82, 25, BW20, BIT(BEHAV_NONE), 2414, + {14} }, + {83, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9} }, + {84, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 2407, + {5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {115, 20, BW20, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48} }, + {116, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {36, 44} }, + {117, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {40, 48} }, + {118, 20, BW20, BIT(BEHAV_NONE), 5000, + {52, 56, 60, 64} }, + {119, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {52, 60} }, + {120, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {56, 64} }, + {121, 20, BW20, BIT(BEHAV_NONE), 5000, + {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144} }, + {122, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {100, 108, 116, 124, 132, 140} }, + {123, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {104, 112, 120, 128, 136, 144} }, + {125, 20, BW20, BIT(BEHAV_NONE), 5000, + {149, 153, 157, 161, 165, 169} }, + {126, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {149, 157} }, + {127, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {153, 161} }, + {128, 80, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, + 128, 132, 136, 140, 144, + 149, 153, 157, 161} }, + {129, 160, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, 128} }, + {130, 80, BW80, BIT(BEHAV_BW80_PLUS), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, 128, + 132, 136, 140, 144, 149, 153, 157, 161} }, + +#ifdef CONFIG_BAND_6GHZ + {131, 20, BW20, BIT(BEHAV_NONE), 5940, + {1, 5, 9, 13, 17, 21, 25, 29, 33, + 37, 41, 45, 49, 53, 57, 61, 65, 69, + 73, 77, 81, 85, 89, 93, 97, + 101, 105, 109, 113, 117, 121, 125, + 129, 133, 137, 141, 145, 149, 153, + 157, 161, 165, 169, 173, 177, 181, + 185, 189, 193, 197, 201, 205, 209, + 213, 217, 221, 225, 229, 233} }, + + {132, 40, BW40_LOW_PRIMARY, BIT(BEHAV_NONE), 5940, + {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, + 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, + 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, + 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, + 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, + 221, 225, 229, 233} }, + + {133, 80, BW80, BIT(BEHAV_NONE), 5940, + {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, + 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, + 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, + 141, 145, 149, 153, 157, 161, 165, 169, 173, + 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, + 217, 221, 225, 229, 233} }, + + {134, 160, BW80, BIT(BEHAV_NONE), 5940, + {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, + 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, + 93, 97, 101, 105, 109, 113, 117, 121, 125, + 129, 133, 137, 141, 145, 149, 153, 157, 161, + 165, 169, 173, 177, 181, 185, 189, 193, 197, + 201, 205, 209, 213, 217, 221, 225, 229, 233} }, + + {135, 80, BW80, BIT(BEHAV_BW80_PLUS), 5940, + {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, + 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, + 85, 89, 93, 97, 101, 105, 109, 113, 117, + 121, 125, 129, 133, 137, 141, 145, 149, + 153, 157, 161, 165, 169, 173, 177, 181, + 185, 189, 193, 197, 201, 205, 209, 213, + 217, 221, 225, 229, 233} }, +#endif + {0, 0, 0, 0, 0, {0} }, }; static const struct reg_dmn_op_class_map_t us_op_class[] = { - {1, 20, BW20, {36, 40, 44, 48} }, - {2, 20, BW20, {52, 56, 60, 64} }, - {4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, - 144} }, - {5, 20, BW20, {149, 153, 157, 161, 165} }, - {12, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} }, - {22, 40, BW40_LOW_PRIMARY, {36, 44} }, - {23, 40, BW40_LOW_PRIMARY, {52, 60} }, - {24, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, - {26, 40, BW40_LOW_PRIMARY, {149, 157} }, - {27, 40, BW40_HIGH_PRIMARY, {40, 48} }, - {28, 40, BW40_HIGH_PRIMARY, {56, 64} }, - {29, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, - {30, 40, BW40_HIGH_PRIMARY, {153, 161} }, - {31, 40, BW40_HIGH_PRIMARY, {153, 161} }, - {32, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7} }, - {33, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11} }, - {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, - 112, 116, 120, 124, 128, 132, 136, 140, 144, - 149, 153, 157, 161} }, - {0, 0, 0, {0} }, + {1, 20, BW20, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48} }, + {2, 20, BW20, BIT(BEHAV_NONE), 5000, + {52, 56, 60, 64} }, + {4, 20, BW20, BIT(BEHAV_NONE), 5000, + {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144} }, + {5, 20, BW20, BIT(BEHAV_NONE), 5000, + {149, 153, 157, 161, 165} }, + {12, 25, BW20, BIT(BEHAV_NONE), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} }, + {22, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {36, 44} }, + {23, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {52, 60} }, + {24, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {100, 108, 116, 124, 132} }, + {26, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {149, 157} }, + {27, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {40, 48} }, + {28, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {56, 64} }, + {29, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {104, 112, 120, 128, 136} }, + {30, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {153, 161} }, + {31, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {153, 161} }, + {32, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 2407, + {1, 2, 3, 4, 5, 6, 7} }, + {33, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 2407, + {5, 6, 7, 8, 9, 10, 11} }, + {128, 80, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, + 104, 108, 112, 116, 120, 124, 128, 132, + 136, 140, 144, 149, 153, 157, 161} }, + {129, 160, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, + 104, 108, 112, 116, 120, 124, 128} }, + {130, 80, BW80, BIT(BEHAV_BW80_PLUS), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, + 104, 108, 112, 116, 120, 124, 128, 132, + 136, 140, 144, 149, 153, 157, 161} }, + {0, 0, 0, 0, 0, {0} }, }; static const struct reg_dmn_op_class_map_t euro_op_class[] = { - {1, 20, BW20, {36, 40, 44, 48} }, - {2, 20, BW20, {52, 56, 60, 64} }, - {3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, - {4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, - {5, 40, BW40_LOW_PRIMARY, {36, 44} }, - {6, 40, BW40_LOW_PRIMARY, {52, 60} }, - {7, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, - {8, 40, BW40_HIGH_PRIMARY, {40, 48} }, - {9, 40, BW40_HIGH_PRIMARY, {56, 64} }, - {10, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, - {11, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} }, - {12, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} }, - {17, 20, BW20, {149, 153, 157, 161, 165, 169} }, - {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, - 116, 120, 124, 128} }, - {0, 0, 0, {0} }, + {1, 20, BW20, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48} }, + {2, 20, BW20, BIT(BEHAV_NONE), 5000, + {52, 56, 60, 64} }, + {3, 20, BW20, BIT(BEHAV_NONE), 5000, + {100, 104, 108, 112, 116, 120, + 124, 128, 132, 136, 140} }, + {4, 25, BW20, BIT(BEHAV_NONE), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {5, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {36, 44} }, + {6, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {52, 60} }, + {7, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {100, 108, 116, 124, 132} }, + {8, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {40, 48} }, + {9, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {56, 64} }, + {10, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {104, 112, 120, 128, 136} }, + {11, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9} }, + {12, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 2407, + {5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {17, 20, BW20, BIT(BEHAV_NONE), 5000, + {149, 153, 157, 161, 165, 169} }, + {128, 80, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, + 124, 128} }, + {129, 160, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, + 104, 108, 112, 116, 120, 124, 128} }, + {130, 80, BW80, BIT(BEHAV_BW80_PLUS), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, + 124, 128} }, + {0, 0, 0, 0, 0, {0} }, }; static const struct reg_dmn_op_class_map_t japan_op_class[] = { - {1, 20, BW20, {36, 40, 44, 48} }, - {30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, - {31, 25, BW20, {14} }, - {32, 20, BW20, {52, 56, 60, 64} }, - {34, 20, BW20, - {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, - {36, 40, BW40_LOW_PRIMARY, {36, 44} }, - {37, 40, BW40_LOW_PRIMARY, {52, 60} }, - {39, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, - {41, 40, BW40_HIGH_PRIMARY, {40, 48} }, - {42, 40, BW40_HIGH_PRIMARY, {56, 64} }, - {44, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, - {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, - 116, 120, 124, 128} }, - {0, 0, 0, {0} }, + {1, 20, BW20, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48} }, + {30, 25, BW20, BIT(BEHAV_NONE), 2407, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {31, 25, BW20, BIT(BEHAV_NONE), 2407, + {14} }, + {32, 20, BW20, BIT(BEHAV_NONE), 5000, + {52, 56, 60, 64} }, + {34, 20, BW20, BIT(BEHAV_NONE), 5000, + {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, + {36, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {36, 44} }, + {37, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {52, 60} }, + {39, 40, BW40_LOW_PRIMARY, BIT(BEHAV_BW40_LOW_PRIMARY), 5000, + {100, 108, 116, 124, 132} }, + {41, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {40, 48} }, + {42, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {56, 64} }, + {44, 40, BW40_HIGH_PRIMARY, BIT(BEHAV_BW40_HIGH_PRIMARY), 5000, + {104, 112, 120, 128, 136} }, + {128, 80, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, + 124, 128} }, + {129, 160, BW80, BIT(BEHAV_NONE), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, + 104, 108, 112, 116, 120, 124, 128} }, + {130, 80, BW80, BIT(BEHAV_BW80_PLUS), 5000, + {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, + 124, 128} }, + {0, 0, 0, 0, 0, {0} }, }; #ifdef HOST_OPCLASS @@ -130,9 +261,8 @@ static const struct reg_dmn_op_class_map_t japan_op_class[] = { * * Return: class. */ -static -const struct reg_dmn_op_class_map_t *reg_get_class_from_country(uint8_t - *country) +static const +struct reg_dmn_op_class_map_t *reg_get_class_from_country(uint8_t *country) { const struct reg_dmn_op_class_map_t *class = NULL; @@ -181,7 +311,7 @@ uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel, for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && class->channels[i]); i++) { if (channel == class->channels[i]) - return class->ch_spacing; + return class->chan_spacing; } } class++; @@ -211,6 +341,34 @@ uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel, return 0; } +uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country, + qdf_freq_t freq, + uint8_t ch_width, + uint16_t behav_limit) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl = NULL; + uint16_t i = 0; + + op_class_tbl = reg_get_class_from_country(country); + + while (op_class_tbl && op_class_tbl->op_class) { + if (op_class_tbl->chan_spacing == ch_width) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if ((op_class_tbl->start_freq + + (FREQ_TO_CHAN_SCALE * + op_class_tbl->channels[i]) == freq) && + (behav_limit & op_class_tbl->behav_limit)) { + return op_class_tbl->op_class; + } + } + } + op_class_tbl++; + } + + return 0; +} + void reg_dmn_print_channels_in_opclass(uint8_t *country, uint8_t op_class) { const struct reg_dmn_op_class_map_t *class = NULL; @@ -273,4 +431,452 @@ uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class) return 0; } + +#ifdef CONFIG_CHAN_FREQ_API +void reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + if (reg_freq_to_band(freq) == REG_BAND_6G) { + global_tbl_lookup = true; + if (chan_width == BW_40_MHZ) + behav_limit = BIT(BEHAV_NONE); + } else { + global_tbl_lookup = false; + } + + reg_freq_width_to_chan_op_class(pdev, freq, + chan_width, + global_tbl_lookup, + behav_limit, + op_class, + chan_num); +} + +void reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl; + enum channel_enum chan_enum; + uint16_t i; + + chan_enum = reg_get_chan_enum_for_freq(freq); + + if (chan_enum == INVALID_CHANNEL) { + reg_err_rl("Invalid chan enum %d", chan_enum); + return; + } + + if (global_tbl_lookup) { + op_class_tbl = global_op_class; + } else { + if (channel_map == channel_map_us) + op_class_tbl = us_op_class; + else if (channel_map == channel_map_eu) + op_class_tbl = euro_op_class; + else if (channel_map == channel_map_china) + op_class_tbl = us_op_class; + else if (channel_map == channel_map_jp) + op_class_tbl = japan_op_class; + else + op_class_tbl = global_op_class; + } + + while (op_class_tbl->op_class) { + if (op_class_tbl->chan_spacing >= chan_width) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if ((op_class_tbl->start_freq + + FREQ_TO_CHAN_SCALE * + op_class_tbl->channels[i] == freq) && + (behav_limit & op_class_tbl->behav_limit || + behav_limit == BIT(BEHAV_NONE))) { + *chan_num = op_class_tbl->channels[i]; + *op_class = op_class_tbl->op_class; + return; + } + } + } + op_class_tbl++; + } + + reg_err_rl("no op class for frequency %d", freq); +} + +void reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + enum channel_enum chan_enum; + struct regulatory_channel *cur_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct ch_params chan_params; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("NULL pdev reg obj"); + return; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + chan_enum = reg_get_chan_enum_for_freq(freq); + + if (chan_enum == INVALID_CHANNEL) { + reg_err_rl("Invalid chan enum %d", chan_enum); + return; + } + + chan_params.ch_width = CH_WIDTH_MAX; + reg_set_channel_params_for_freq(pdev, freq, 0, &chan_params); + + reg_freq_width_to_chan_op_class(pdev, freq, + reg_get_bw_value(chan_params.ch_width), + global_tbl_lookup, + behav_limit, + op_class, + chan_num); +} + +bool reg_country_opclass_freq_check(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t op_class, + qdf_freq_t chan_freq) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl; + uint8_t i; + + op_class_tbl = reg_get_class_from_country((uint8_t *)country); + + while (op_class_tbl && op_class_tbl->op_class) { + if (op_class_tbl->op_class == op_class) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if (op_class_tbl->channels[i] * + FREQ_TO_CHAN_SCALE + + op_class_tbl->start_freq == chan_freq) + return true; + } + } + op_class_tbl++; + } + return false; +} + +#endif + +uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, + uint8_t op_class, + bool global_tbl_lookup) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl; + + if (global_tbl_lookup) { + op_class_tbl = global_op_class; + } else { + if (channel_map == channel_map_us) + op_class_tbl = us_op_class; + else if (channel_map == channel_map_eu) + op_class_tbl = euro_op_class; + else if (channel_map == channel_map_china) + op_class_tbl = us_op_class; + else if (channel_map == channel_map_jp) + op_class_tbl = japan_op_class; + else + op_class_tbl = global_op_class; + } + + while (op_class_tbl->op_class) { + if (op_class_tbl->op_class == op_class) + return op_class_tbl->chan_spacing; + op_class_tbl++; + } + + return 0; +} + +uint16_t reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl = NULL; + uint8_t i = 0; + + if (global_tbl_lookup) { + op_class_tbl = global_op_class; + } else { + if (channel_map == channel_map_global) { + op_class_tbl = global_op_class; + } else if (channel_map == channel_map_us) { + op_class_tbl = us_op_class; + } else if (channel_map == channel_map_eu) { + op_class_tbl = euro_op_class; + } else if (channel_map == channel_map_china) { + op_class_tbl = us_op_class; + } else if (channel_map == channel_map_jp) { + op_class_tbl = japan_op_class; + } else { + reg_err_rl("Invalid channel map"); + return 0; + } + } + + while (op_class_tbl->op_class) { + if (op_class_tbl->op_class == op_class) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if (op_class_tbl->channels[i] == chan) { + chan = op_class_tbl->channels[i]; + return op_class_tbl->start_freq + + (chan * FREQ_TO_CHAN_SCALE); + } + } + reg_err_rl("Channel not found"); + return 0; + } + op_class_tbl++; + } + reg_err_rl("Invalid opclass"); + return 0; +} + +#ifdef HOST_OPCLASS_EXT +qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t chan, uint8_t op_class, + bool strict) +{ + const struct reg_dmn_op_class_map_t *op_class_tbl, *op_class_tbl_org; + uint16_t i; + + if (reg_is_6ghz_op_class(pdev, op_class)) + op_class_tbl_org = global_op_class; + else + op_class_tbl_org = + reg_get_class_from_country((uint8_t *)country); + op_class_tbl = op_class_tbl_org; + while (op_class_tbl && op_class_tbl->op_class) { + if (op_class_tbl->op_class == op_class) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if (op_class_tbl->channels[i] == chan) + return op_class_tbl->start_freq + + (chan * FREQ_TO_CHAN_SCALE); + } + } + op_class_tbl++; + } + reg_debug_rl("Not found ch %d in op class %d ch list, strict %d", + chan, op_class, strict); + if (strict) + return 0; + + op_class_tbl = op_class_tbl_org; + while (op_class_tbl && op_class_tbl->op_class) { + for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + op_class_tbl->channels[i]); i++) { + if (op_class_tbl->channels[i] == chan) + return op_class_tbl->start_freq + + (chan * FREQ_TO_CHAN_SCALE); + } + op_class_tbl++; + } + reg_debug_rl("Got invalid freq 0 for ch %d", chan); + + return 0; +} +#endif + +static void +reg_get_op_class_tbl_by_chan_map(const struct + reg_dmn_op_class_map_t **op_class_tbl) +{ + if (channel_map == channel_map_us) + *op_class_tbl = us_op_class; + else if (channel_map == channel_map_eu) + *op_class_tbl = euro_op_class; + else if (channel_map == channel_map_china) + *op_class_tbl = us_op_class; + else if (channel_map == channel_map_jp) + *op_class_tbl = japan_op_class; + else + *op_class_tbl = global_op_class; +} + +/** + * reg_get_channel_cen - Calculate central channel in the channel set. + * + * @op_class_tbl - Pointer to op_class_tbl. + * @idx - Pointer to channel index. + * @num_channels - Number of channels. + * @center_chan - Pointer to center channel number + * + * Return : void + */ +static void reg_get_channel_cen(const struct + reg_dmn_op_class_map_t *op_class_tbl, + uint8_t *idx, + uint8_t num_channels, + uint8_t *center_chan) +{ + uint8_t i; + uint16_t new_chan = 0; + + for (i = *idx; i < (*idx + num_channels); i++) + new_chan += op_class_tbl->channels[i]; + + new_chan = new_chan / num_channels; + *center_chan = new_chan; + *idx = *idx + num_channels; +} + +/** + * reg_get_chan_or_chan_center - Calculate central channel in the channel set. + * + * @op_class_tbl - Pointer to op_class_tbl. + * @idx - Pointer to channel index. + * + * Return : Center channel number + */ +static uint8_t reg_get_chan_or_chan_center(const struct + reg_dmn_op_class_map_t *op_class_tbl, + uint8_t *idx) +{ + uint8_t center_chan; + + if (((op_class_tbl->chan_spacing == BW_80_MHZ) && + (op_class_tbl->behav_limit == BIT(BEHAV_NONE))) || + ((op_class_tbl->chan_spacing == BW_80_MHZ) && + (op_class_tbl->behav_limit == BIT(BEHAV_BW80_PLUS)))) { + reg_get_channel_cen(op_class_tbl, + idx, + NUM_20_MHZ_CHAN_IN_80_MHZ_CHAN, + ¢er_chan); + } else if (op_class_tbl->chan_spacing == BW_160_MHZ) { + reg_get_channel_cen(op_class_tbl, + idx, + NUM_20_MHZ_CHAN_IN_160_MHZ_CHAN, + ¢er_chan); + } else { + center_chan = op_class_tbl->channels[*idx]; + *idx = *idx + 1; + } + + return center_chan; +} + +/** + * reg_get_channels_from_opclassmap()- Get channels from the opclass map + * @pdev: Pointer to pdev + * @reg_ap_cap: Pointer to reg_ap_cap + * @index: Pointer to index of reg_ap_cap + * @op_class_tbl: Pointer to op_class_tbl + * @is_opclass_operable: Set true if opclass is operable, else set false + * + * Populate channels from opclass map to reg_ap_cap as supported and + * non-supported channels. + * + * Return: void. + */ +static void +reg_get_channels_from_opclassmap( + struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t index, + const struct reg_dmn_op_class_map_t *op_class_tbl, + bool *is_opclass_operable) +{ + uint8_t op_cls_chan; + qdf_freq_t search_freq; + bool is_freq_present; + uint8_t chan_idx = 0, n_sup_chans = 0, n_unsup_chans = 0; + + while (op_class_tbl->channels[chan_idx]) { + op_cls_chan = op_class_tbl->channels[chan_idx]; + search_freq = op_class_tbl->start_freq + + (FREQ_TO_CHAN_SCALE * op_cls_chan); + is_freq_present = + reg_is_freq_present_in_cur_chan_list(pdev, search_freq); + + if (!is_freq_present) { + reg_ap_cap[index].non_sup_chan_list[n_unsup_chans++] = + reg_get_chan_or_chan_center(op_class_tbl, + &chan_idx); + reg_ap_cap[index].num_non_supported_chan++; + } else { + reg_ap_cap[index].sup_chan_list[n_sup_chans++] = + reg_get_chan_or_chan_center(op_class_tbl, + &chan_idx); + reg_ap_cap[index].num_supported_chan++; + } + } + + if (reg_ap_cap[index].num_supported_chan >= 1) + *is_opclass_operable = true; +} + +QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t *n_opclasses, + uint8_t max_supp_op_class, + bool global_tbl_lookup) +{ + uint8_t max_reg_power = 0; + const struct reg_dmn_op_class_map_t *op_class_tbl; + uint8_t index = 0; + + if (global_tbl_lookup) + op_class_tbl = global_op_class; + else + reg_get_op_class_tbl_by_chan_map(&op_class_tbl); + + max_reg_power = reg_get_max_tx_power(pdev); + + while (op_class_tbl->op_class && (index < max_supp_op_class)) { + bool is_opclass_operable = false; + + qdf_mem_zero(reg_ap_cap[index].sup_chan_list, + REG_MAX_CHANNELS_PER_OPERATING_CLASS); + reg_ap_cap[index].num_supported_chan = 0; + qdf_mem_zero(reg_ap_cap[index].non_sup_chan_list, + REG_MAX_CHANNELS_PER_OPERATING_CLASS); + reg_ap_cap[index].num_non_supported_chan = 0; + reg_get_channels_from_opclassmap(pdev, + reg_ap_cap, + index, + op_class_tbl, + &is_opclass_operable); + if (is_opclass_operable) { + reg_ap_cap[index].op_class = op_class_tbl->op_class; + reg_ap_cap[index].ch_width = + op_class_tbl->chan_spacing; + reg_ap_cap[index].start_freq = + op_class_tbl->start_freq; + reg_ap_cap[index].max_tx_pwr_dbm = max_reg_power; + reg_ap_cap[index].behav_limit = + op_class_tbl->behav_limit; + index++; + } + + op_class_tbl++; + } + + *n_opclasses = index; + + return QDF_STATUS_SUCCESS; +} + #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.h index 8b2ffd969a68e529fef15b78d8b7b348e9fe7344..0cd260c0cdf8859da78d158c23e6fd83995fbb16 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_opclass.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -47,6 +47,21 @@ uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel, */ uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel, uint8_t offset); + +/** + * reg_dmn_get_opclass_from_freq_width() - Get operating class from frequency + * @country: Country code. + * @freq: Channel center frequency. + * @ch_width: Channel width. + * @behav_limit: Behaviour limit. + * + * Return: Error code. + */ +uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country, + qdf_freq_t freq, + uint8_t ch_width, + uint16_t behav_limit); + /** * reg_dmn_get_opclass_from_channe() - Print channels in op class. * @country: Country code. @@ -74,6 +89,147 @@ uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class); */ uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class); +/** + * reg_get_opclass_details() - Get details about the current opclass table. + * @pdev: Pointer to pdev. + * @reg_ap_cap: Pointer to reg_ap_cap. + * @n_opclasses: Pointer to number of opclasses. + * @max_supp_op_class: Maximum number of operating classes supported. + * @global_tbl_lookup: Whether to lookup global op class table. + * + * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE. + */ +QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t *n_opclasses, + uint8_t max_supp_op_class, + bool global_tbl_lookup); +#ifdef CONFIG_CHAN_FREQ_API + +/** + * reg_freq_width_to_chan_op_class() - convert frequency to oper class, + * channel + * @pdev: pdev pointer + * @freq: channel frequency in mhz + * @chan_width: channel width + * @global_tbl_lookup: whether to lookup global op class tbl + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: Void. + */ +void reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * reg_freq_width_to_chan_op_class_auto() - convert frequency to operating + * class,channel after fixing up the global_tbl_lookup and behav_limit + * for 6G frequencies. + * @pdev: pdev pointer + * @freq: channel frequency in mhz + * @chan_width: channel width + * @global_tbl_lookup: whether to lookup global op class tbl + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: Void. + */ +void reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * reg_freq_to_chan_op_class() - convert frequency to oper class, + * channel + * @pdev: pdev pointer + * @freq: channel frequency in mhz + * @global_tbl_lookup: whether to lookup global op class tbl + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: Void. + */ +void reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * reg_country_opclass_freq_check() - check for frequency in (tbl, oper class) + * + * @pdev: pdev pointer + * @country: country from country IE + * @op_class: operating class + * @chan_freq: channel frequency in mhz + * + * Return: bool + */ +bool reg_country_opclass_freq_check(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t op_class, + qdf_freq_t chan_freq); +#endif + +/** + * reg_get_op_class_width() - get oper class width + * + * @pdev: pdev pointer + * @global_tbl_lookup: whether to lookup global op class tbl + * @op_class: operating class + * Return: uint16 + */ +uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, + uint8_t op_class, + bool global_tbl_lookup); + +#ifdef HOST_OPCLASS_EXT +/** + * reg_country_chan_opclass_to_freq() - Convert channel number to frequency + * based on country code and op class + * @pdev: pdev object. + * @country: country code. + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @strict: flag to find channel from matched operating class code. + * + * Look up (channel, operating class) pair in country operating class tables + * and return the channel frequency. + * If not found and "strict" flag is false, try to get frequency (Mhz) by + * channel number only. + * + * Return: Channel center frequency else return 0. + */ +qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t chan, uint8_t op_class, + bool strict); +#endif + +/** + * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @global_tbl_lookup: Global table lookup. + * + * Return: Channel center frequency else return 0. + */ +uint16_t reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup); #else static inline uint16_t reg_dmn_get_chanwidth_from_opclass( @@ -100,10 +256,99 @@ static inline uint16_t reg_dmn_get_opclass_from_channel( return 0; } +static inline +uint8_t reg_dmn_get_opclass_from_freq_width(uint8_t *country, + qdf_freq_t freq, + uint8_t ch_width, + uint16_t behav_limit) +{ + return 0; +} + static inline void reg_dmn_print_channels_in_opclass(uint8_t *country, uint8_t op_class) { } +static inline +QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t *n_opclasses, + uint8_t max_supp_op_class, + bool global_tbl_lookup) +{ + return QDF_STATUS_E_FAILURE; +} + +#ifdef CONFIG_CHAN_FREQ_API + +static inline void +reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ +} + +static inline void +reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ +} + +static inline void +reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ +} + +static inline bool +reg_country_opclass_freq_check(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t op_class, + uint16_t chan_freq) +{ +} + +#endif + +static inline uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, + uint8_t op_class, + bool global_tbl_lookup) +{ + return 0; +} + +#ifdef HOST_OPCLASS_EXT +static inline +qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t chan, uint8_t op_class, + bool strict) +{ + return 0; +} +#endif + +static inline uint16_t +reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + return 0; +} + #endif #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.c index 3da6ecf696bc047b71776a32bf66a5be21101b3b..8f31c6a3a3f9c6aa8b99000a31b199984b386bb6 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.c @@ -32,6 +32,7 @@ #include "reg_services_common.h" #include "reg_build_chan_list.h" #include "reg_host_11d.h" +#include "reg_callbacks.h" struct wlan_regulatory_psoc_priv_obj *reg_get_psoc_obj( struct wlan_objmgr_psoc *psoc) @@ -81,7 +82,8 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification( soc_reg_obj->offload_enabled = false; soc_reg_obj->psoc_ptr = psoc; soc_reg_obj->dfs_enabled = true; - soc_reg_obj->band_capability = BAND_ALL; + soc_reg_obj->band_capability = (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) | + BIT(REG_BAND_6G)); soc_reg_obj->enable_11d_supp = false; soc_reg_obj->indoor_chan_enabled = true; soc_reg_obj->force_ssc_disable_indoor_channel = false; @@ -89,8 +91,9 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification( soc_reg_obj->vdev_cnt_11d = 0; soc_reg_obj->vdev_id_for_11d_scan = INVALID_VDEV_ID; soc_reg_obj->restart_beaconing = CH_AVOID_RULE_RESTART; - soc_reg_obj->enable_srd_chan_in_master_mode = true; + soc_reg_obj->enable_srd_chan_in_master_mode = 0xFF; soc_reg_obj->enable_11d_in_world_mode = false; + soc_reg_obj->retain_nol_across_regdmn_update = false; for (i = 0; i < MAX_STA_VDEV_CNT; i++) soc_reg_obj->vdev_ids_11d[i] = INVALID_VDEV_ID; @@ -100,6 +103,7 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification( for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) { mas_chan_list = soc_reg_obj->mas_chan_params[pdev_cnt].mas_chan_list; + soc_reg_obj->chan_list_recvd[pdev_cnt] = false; for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { mas_chan_list[chan_enum].chan_flags |= @@ -152,6 +156,25 @@ QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification( return status; } +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_reset_unii_5g_bitmap() - Reset the value of unii_5g_bitmap. + * @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj. + * + * Return : void + */ +static void +reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + pdev_priv_obj->unii_5g_bitmap = 0x0; +} +#else +static void inline +reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + QDF_STATUS wlan_regulatory_pdev_obj_created_notification( struct wlan_objmgr_pdev *pdev, void *arg_list) { @@ -183,10 +206,11 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( pdev_priv_obj->pdev_ptr = pdev; pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; pdev_priv_obj->set_fcc_channel = false; - pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; + pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; pdev_priv_obj->en_chan_144 = true; + reg_reset_unii_5g_bitmap(pdev_priv_obj); qdf_spinlock_create(&pdev_priv_obj->reg_rules_lock); @@ -228,6 +252,8 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules; reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj); + pdev_priv_obj->chan_list_recvd = + psoc_priv_obj->chan_list_recvd[pdev_id]; status = wlan_objmgr_pdev_component_obj_attach( pdev, WLAN_UMAC_COMP_REGULATORY, pdev_priv_obj, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.h index c5f6cd301baa52c560e4d7f868f0721ebb43cd22..dc0c8bce08cde8209c591b53b91f2922c0aa8582 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_priv_objs.h @@ -80,6 +80,7 @@ struct chan_change_cbk_entry { /** * struct wlan_regulatory_psoc_priv_obj - wlan regulatory psoc private object + * @chan_list_recvd: whether channel list has been received * @new_user_ctry_pending: In this array, element[phy_id] is true if any user * country update is pending for pdev (phy_id), used in case of MCL. * @new_init_ctry_pending: In this array, element[phy_id] is true if any user @@ -88,9 +89,16 @@ struct chan_change_cbk_entry { * country update is pending for pdev (phy_id). * @world_country_pending: In this array, element[phy_id] is true if any world * country update is pending for pdev (phy_id). + * @band_capability: bitmap of bands enabled, using enum reg_wifi_band as the + * bit position value + * @ignore_fw_reg_offload_ind: Ignore FW reg offload indication + * @six_ghz_supported: whether 6ghz is supported + * @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain + * changes. */ struct wlan_regulatory_psoc_priv_obj { struct mas_chan_params mas_chan_params[PSOC_MAX_PHY_REG_CAP]; + bool chan_list_recvd[PSOC_MAX_PHY_REG_CAP]; bool offload_enabled; bool six_ghz_supported; uint8_t num_phy; @@ -105,7 +113,7 @@ struct wlan_regulatory_psoc_priv_obj { bool new_11d_ctry_pending[PSOC_MAX_PHY_REG_CAP]; bool world_country_pending[PSOC_MAX_PHY_REG_CAP]; bool dfs_enabled; - enum band_info band_capability; + uint32_t band_capability; bool indoor_chan_enabled; bool ignore_fw_reg_offload_ind; bool enable_11d_supp_original; @@ -133,14 +141,17 @@ struct wlan_regulatory_psoc_priv_obj { struct wlan_psoc_host_hal_reg_capabilities_ext reg_cap[PSOC_MAX_PHY_REG_CAP]; bool force_ssc_disable_indoor_channel; - bool enable_srd_chan_in_master_mode; + uint8_t enable_srd_chan_in_master_mode; bool enable_11d_in_world_mode; qdf_spinlock_t cbk_list_lock; + bool retain_nol_across_regdmn_update; }; /** * struct wlan_regulatory_pdev_priv_obj - wlan regulatory pdev private object * @pdev_opened: whether pdev has been opened by application + * @band_capability: bitmap of bands enabled, using enum reg_wifi_band as the + * bit position value */ struct wlan_regulatory_pdev_priv_obj { struct regulatory_channel cur_chan_list[NUM_CHANNELS]; @@ -156,16 +167,19 @@ struct wlan_regulatory_pdev_priv_obj { char current_country[REG_ALPHA2_LEN + 1]; uint16_t reg_dmn_pair; uint16_t ctry_code; +#ifdef DISABLE_UNII_SHARED_BANDS + uint8_t unii_5g_bitmap; +#endif enum dfs_reg dfs_region; uint32_t phybitmap; struct wlan_objmgr_pdev *pdev_ptr; - uint32_t range_2g_low; - uint32_t range_2g_high; - uint32_t range_5g_low; - uint32_t range_5g_high; + qdf_freq_t range_2g_low; + qdf_freq_t range_2g_high; + qdf_freq_t range_5g_low; + qdf_freq_t range_5g_high; bool dfs_enabled; bool set_fcc_channel; - enum band_info band_capability; + uint32_t band_capability; bool indoor_chan_enabled; bool en_chan_144; uint32_t wireless_modes; @@ -174,6 +188,7 @@ struct wlan_regulatory_pdev_priv_obj { bool sap_state; struct reg_rule_info reg_rules; qdf_spinlock_t reg_rules_lock; + bool chan_list_recvd; bool pdev_opened; }; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c index 809619220b8207b357b54ab73892a4b85461f000..be27444d70a67faea1b843b658dca11899a8aa20 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,9 +34,10 @@ #include "reg_db_parser.h" #include "reg_build_chan_list.h" #include +#include const struct chan_map *channel_map; - +#ifdef CONFIG_CHAN_NUM_API static const struct bonded_channel bonded_chan_40mhz_list[] = { {36, 40}, {44, 48}, @@ -66,6 +67,98 @@ static const struct bonded_channel bonded_chan_160mhz_list[] = { {36, 64}, {100, 128} }; +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +/* bonded_chan_40mhz_list_freq - List of 40MHz bonnded channel frequencies */ +static const struct bonded_channel_freq bonded_chan_40mhz_list_freq[] = { + {5180, 5200}, + {5220, 5240}, + {5260, 5280}, + {5300, 5320}, + {5500, 5520}, + {5540, 5560}, + {5580, 5600}, + {5620, 5640}, + {5660, 5680}, + {5700, 5720}, + {5745, 5765}, + {5785, 5805}, + {5825, 5845}, +#ifdef CONFIG_BAND_6GHZ + {5945, 5965}, + {5985, 6005}, + {6025, 6045}, + {6065, 6085}, + {6105, 6125}, + {6145, 6165}, + {6185, 6205}, + {6225, 6245}, + {6265, 6285}, + {6305, 6325}, + {6345, 6365}, + {6385, 6405}, + {6425, 6445}, + {6465, 6485}, + {6505, 6525}, + {6545, 6565}, + {6585, 6605}, + {6625, 6645}, + {6665, 6685}, + {6705, 6725}, + {6745, 6765}, + {6785, 6805}, + {6825, 6845}, + {6865, 6885}, + {6905, 6925}, + {6945, 6965}, + {6985, 7005}, + {7025, 7045}, + {7065, 7085} +#endif /*CONFIG_BAND_6GHZ*/ +}; + +/* bonded_chan_80mhz_list_freq - List of 80MHz bonnded channel frequencies */ +static const struct bonded_channel_freq bonded_chan_80mhz_list_freq[] = { + {5180, 5240}, + {5260, 5320}, + {5500, 5560}, + {5580, 5640}, + {5660, 5720}, + {5745, 5805}, +#ifdef CONFIG_BAND_6GHZ + {5945, 6005}, + {6025, 6085}, + {6105, 6165}, + {6185, 6245}, + {6265, 6325}, + {6345, 6405}, + {6425, 6485}, + {6505, 6565}, + {6585, 6645}, + {6665, 6725}, + {6745, 6805}, + {6825, 6885}, + {6905, 6965}, + {6985, 7045} +#endif /*CONFIG_BAND_6GHZ*/ +}; + +/* bonded_chan_160mhz_list_freq - List of 160MHz bonnded channel frequencies */ +static const struct bonded_channel_freq bonded_chan_160mhz_list_freq[] = { + {5180, 5320}, + {5500, 5640}, +#ifdef CONFIG_BAND_6GHZ + {5945, 6085}, + {6105, 6245}, + {6265, 6405}, + {6425, 6565}, + {6585, 6725}, + {6745, 6885}, + {6905, 7045} +#endif /*CONFIG_BAND_6GHZ*/ +}; +#endif /*CONFIG_CHAN_FREQ_API*/ static const enum phy_ch_width get_next_lower_bw[] = { [CH_WIDTH_80P80MHZ] = CH_WIDTH_160MHZ, @@ -77,74 +170,7 @@ static const enum phy_ch_width get_next_lower_bw[] = { [CH_WIDTH_5MHZ] = CH_WIDTH_INVALID }; -#ifdef CONFIG_LEGACY_CHAN_ENUM -static const struct chan_map channel_map_old[NUM_CHANNELS] = { - [CHAN_ENUM_1] = {2412, 1, 2, 40}, - [CHAN_ENUM_2] = {2417, 2, 2, 40}, - [CHAN_ENUM_3] = {2422, 3, 2, 40}, - [CHAN_ENUM_4] = {2427, 4, 2, 40}, - [CHAN_ENUM_5] = {2432, 5, 2, 40}, - [CHAN_ENUM_6] = {2437, 6, 2, 40}, - [CHAN_ENUM_7] = {2442, 7, 2, 40}, - [CHAN_ENUM_8] = {2447, 8, 2, 40}, - [CHAN_ENUM_9] = {2452, 9, 2, 40}, - [CHAN_ENUM_10] = {2457, 10, 2, 40}, - [CHAN_ENUM_11] = {2462, 11, 2, 40}, - [CHAN_ENUM_12] = {2467, 12, 2, 40}, - [CHAN_ENUM_13] = {2472, 13, 2, 40}, - [CHAN_ENUM_14] = {2484, 14, 2, 40}, - - [CHAN_ENUM_36] = {5180, 36, 2, 160}, - [CHAN_ENUM_40] = {5200, 40, 2, 160}, - [CHAN_ENUM_44] = {5220, 44, 2, 160}, - [CHAN_ENUM_48] = {5240, 48, 2, 160}, - [CHAN_ENUM_52] = {5260, 52, 2, 160}, - [CHAN_ENUM_56] = {5280, 56, 2, 160}, - [CHAN_ENUM_60] = {5300, 60, 2, 160}, - [CHAN_ENUM_64] = {5320, 64, 2, 160}, - - [CHAN_ENUM_100] = {5500, 100, 2, 160}, - [CHAN_ENUM_104] = {5520, 104, 2, 160}, - [CHAN_ENUM_108] = {5540, 108, 2, 160}, - [CHAN_ENUM_112] = {5560, 112, 2, 160}, - [CHAN_ENUM_116] = {5580, 116, 2, 160}, - [CHAN_ENUM_120] = {5600, 120, 2, 160}, - [CHAN_ENUM_124] = {5620, 124, 2, 160}, - [CHAN_ENUM_128] = {5640, 128, 2, 160}, - [CHAN_ENUM_132] = {5660, 132, 2, 160}, - [CHAN_ENUM_136] = {5680, 136, 2, 160}, - [CHAN_ENUM_140] = {5700, 140, 2, 160}, - [CHAN_ENUM_144] = {5720, 144, 2, 160}, - - [CHAN_ENUM_149] = {5745, 149, 2, 160}, - [CHAN_ENUM_153] = {5765, 153, 2, 160}, - [CHAN_ENUM_157] = {5785, 157, 2, 160}, - [CHAN_ENUM_161] = {5805, 161, 2, 160}, - [CHAN_ENUM_165] = {5825, 165, 2, 160}, -#ifndef WLAN_FEATURE_DSRC - [CHAN_ENUM_169] = {5845, 169, 2, 40}, - [CHAN_ENUM_173] = {5865, 173, 2, 20}, -#else - [CHAN_ENUM_170] = {5852, 170, 2, 20}, - [CHAN_ENUM_171] = {5855, 171, 2, 20}, - [CHAN_ENUM_172] = {5860, 172, 2, 20}, - [CHAN_ENUM_173] = {5865, 173, 2, 20}, - [CHAN_ENUM_174] = {5870, 174, 2, 20}, - [CHAN_ENUM_175] = {5875, 175, 2, 20}, - [CHAN_ENUM_176] = {5880, 176, 2, 20}, - [CHAN_ENUM_177] = {5885, 177, 2, 20}, - [CHAN_ENUM_178] = {5890, 178, 2, 20}, - [CHAN_ENUM_179] = {5895, 179, 2, 20}, - [CHAN_ENUM_180] = {5900, 180, 2, 20}, - [CHAN_ENUM_181] = {5905, 181, 2, 20}, - [CHAN_ENUM_182] = {5910, 182, 2, 20}, - [CHAN_ENUM_183] = {5915, 183, 2, 20}, - [CHAN_ENUM_184] = {5920, 184, 2, 20}, -#endif -}; - -#else -static const struct chan_map channel_map_us[NUM_CHANNELS] = { +const struct chan_map channel_map_us[NUM_CHANNELS] = { [CHAN_ENUM_2412] = {2412, 1, 20, 40}, [CHAN_ENUM_2417] = {2417, 2, 20, 40}, [CHAN_ENUM_2422] = {2422, 3, 20, 40}, @@ -229,11 +255,21 @@ static const struct chan_map channel_map_us[NUM_CHANNELS] = { [CHAN_ENUM_5805] = {5805, 161, 2, 160}, [CHAN_ENUM_5825] = {5825, 165, 2, 160}, [CHAN_ENUM_5845] = {5845, 169, 2, 160}, +#ifdef WLAN_FEATURE_DSRC [CHAN_ENUM_5850] = {5850, 170, 2, 160}, [CHAN_ENUM_5855] = {5855, 171, 2, 160}, [CHAN_ENUM_5860] = {5860, 172, 2, 160}, +#else + [CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160}, + [CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160}, + [CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160}, +#endif [CHAN_ENUM_5865] = {5865, 173, 2, 160}, +#ifdef WLAN_FEATURE_DSRC [CHAN_ENUM_5870] = {5870, 174, 2, 160}, +#else + [CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160}, +#endif [CHAN_ENUM_5875] = {5875, 175, 2, 160}, [CHAN_ENUM_5880] = {5880, 176, 2, 160}, [CHAN_ENUM_5885] = {5885, 177, 2, 160}, @@ -244,9 +280,70 @@ static const struct chan_map channel_map_us[NUM_CHANNELS] = { [CHAN_ENUM_5910] = {5910, 182, 2, 160}, [CHAN_ENUM_5915] = {5915, 183, 2, 160}, [CHAN_ENUM_5920] = {5920, 184, 2, 160}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_ENUM_5945] = {5945, 1, 2, 160}, + [CHAN_ENUM_5965] = {5965, 5, 2, 160}, + [CHAN_ENUM_5985] = {5985, 9, 2, 160}, + [CHAN_ENUM_6005] = {6005, 13, 2, 160}, + [CHAN_ENUM_6025] = {6025, 17, 2, 160}, + [CHAN_ENUM_6045] = {6045, 21, 2, 160}, + [CHAN_ENUM_6065] = {6065, 25, 2, 160}, + [CHAN_ENUM_6085] = {6085, 29, 2, 160}, + [CHAN_ENUM_6105] = {6105, 33, 2, 160}, + [CHAN_ENUM_6125] = {6125, 37, 2, 160}, + [CHAN_ENUM_6145] = {6145, 41, 2, 160}, + [CHAN_ENUM_6165] = {6165, 45, 2, 160}, + [CHAN_ENUM_6185] = {6185, 49, 2, 160}, + [CHAN_ENUM_6205] = {6205, 53, 2, 160}, + [CHAN_ENUM_6225] = {6225, 57, 2, 160}, + [CHAN_ENUM_6245] = {6245, 61, 2, 160}, + [CHAN_ENUM_6265] = {6265, 65, 2, 160}, + [CHAN_ENUM_6285] = {6285, 69, 2, 160}, + [CHAN_ENUM_6305] = {6305, 73, 2, 160}, + [CHAN_ENUM_6325] = {6325, 77, 2, 160}, + [CHAN_ENUM_6345] = {6345, 81, 2, 160}, + [CHAN_ENUM_6365] = {6365, 85, 2, 160}, + [CHAN_ENUM_6385] = {6385, 89, 2, 160}, + [CHAN_ENUM_6405] = {6405, 93, 2, 160}, + [CHAN_ENUM_6425] = {6425, 97, 2, 160}, + [CHAN_ENUM_6445] = {6445, 101, 2, 160}, + [CHAN_ENUM_6465] = {6465, 105, 2, 160}, + [CHAN_ENUM_6485] = {6485, 109, 2, 160}, + [CHAN_ENUM_6505] = {6505, 113, 2, 160}, + [CHAN_ENUM_6525] = {6525, 117, 2, 160}, + [CHAN_ENUM_6545] = {6545, 121, 2, 160}, + [CHAN_ENUM_6565] = {6565, 125, 2, 160}, + [CHAN_ENUM_6585] = {6585, 129, 2, 160}, + [CHAN_ENUM_6605] = {6605, 133, 2, 160}, + [CHAN_ENUM_6625] = {6625, 137, 2, 160}, + [CHAN_ENUM_6645] = {6645, 141, 2, 160}, + [CHAN_ENUM_6665] = {6665, 145, 2, 160}, + [CHAN_ENUM_6685] = {6685, 149, 2, 160}, + [CHAN_ENUM_6705] = {6705, 153, 2, 160}, + [CHAN_ENUM_6725] = {6725, 157, 2, 160}, + [CHAN_ENUM_6745] = {6745, 161, 2, 160}, + [CHAN_ENUM_6765] = {6765, 165, 2, 160}, + [CHAN_ENUM_6785] = {6785, 169, 2, 160}, + [CHAN_ENUM_6805] = {6805, 173, 2, 160}, + [CHAN_ENUM_6825] = {6825, 177, 2, 160}, + [CHAN_ENUM_6845] = {6845, 181, 2, 160}, + [CHAN_ENUM_6865] = {6865, 185, 2, 160}, + [CHAN_ENUM_6885] = {6885, 189, 2, 160}, + [CHAN_ENUM_6905] = {6905, 193, 2, 160}, + [CHAN_ENUM_6925] = {6925, 197, 2, 160}, + [CHAN_ENUM_6945] = {6945, 201, 2, 160}, + [CHAN_ENUM_6965] = {6965, 205, 2, 160}, + [CHAN_ENUM_6985] = {6985, 209, 2, 160}, + [CHAN_ENUM_7005] = {7005, 213, 2, 160}, + [CHAN_ENUM_7025] = {7025, 217, 2, 160}, + [CHAN_ENUM_7045] = {7045, 221, 2, 160}, + [CHAN_ENUM_7065] = {7065, 225, 2, 160}, + [CHAN_ENUM_7085] = {7085, 229, 2, 160}, + [CHAN_ENUM_7105] = {7105, 233, 2, 160} +#endif /* CONFIG_BAND_6GHZ */ }; -static const struct chan_map channel_map_eu[NUM_CHANNELS] = { +const struct chan_map channel_map_eu[NUM_CHANNELS] = { [CHAN_ENUM_2412] = {2412, 1, 20, 40}, [CHAN_ENUM_2417] = {2417, 2, 20, 40}, [CHAN_ENUM_2422] = {2422, 3, 20, 40}, @@ -346,9 +443,70 @@ static const struct chan_map channel_map_eu[NUM_CHANNELS] = { [CHAN_ENUM_5910] = {5910, 182, 2, 160}, [CHAN_ENUM_5915] = {5915, 183, 2, 160}, [CHAN_ENUM_5920] = {5920, 184, 2, 160}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_ENUM_5945] = {5945, 1, 2, 160}, + [CHAN_ENUM_5965] = {5965, 5, 2, 160}, + [CHAN_ENUM_5985] = {5985, 9, 2, 160}, + [CHAN_ENUM_6005] = {6005, 13, 2, 160}, + [CHAN_ENUM_6025] = {6025, 17, 2, 160}, + [CHAN_ENUM_6045] = {6045, 21, 2, 160}, + [CHAN_ENUM_6065] = {6065, 25, 2, 160}, + [CHAN_ENUM_6085] = {6085, 29, 2, 160}, + [CHAN_ENUM_6105] = {6105, 33, 2, 160}, + [CHAN_ENUM_6125] = {6125, 37, 2, 160}, + [CHAN_ENUM_6145] = {6145, 41, 2, 160}, + [CHAN_ENUM_6165] = {6165, 45, 2, 160}, + [CHAN_ENUM_6185] = {6185, 49, 2, 160}, + [CHAN_ENUM_6205] = {6205, 53, 2, 160}, + [CHAN_ENUM_6225] = {6225, 57, 2, 160}, + [CHAN_ENUM_6245] = {6245, 61, 2, 160}, + [CHAN_ENUM_6265] = {6265, 65, 2, 160}, + [CHAN_ENUM_6285] = {6285, 69, 2, 160}, + [CHAN_ENUM_6305] = {6305, 73, 2, 160}, + [CHAN_ENUM_6325] = {6325, 77, 2, 160}, + [CHAN_ENUM_6345] = {6345, 81, 2, 160}, + [CHAN_ENUM_6365] = {6365, 85, 2, 160}, + [CHAN_ENUM_6385] = {6385, 89, 2, 160}, + [CHAN_ENUM_6405] = {6405, 93, 2, 160}, + [CHAN_ENUM_6425] = {6425, 97, 2, 160}, + [CHAN_ENUM_6445] = {6445, 101, 2, 160}, + [CHAN_ENUM_6465] = {6465, 105, 2, 160}, + [CHAN_ENUM_6485] = {6485, 109, 2, 160}, + [CHAN_ENUM_6505] = {6505, 113, 2, 160}, + [CHAN_ENUM_6525] = {6525, 117, 2, 160}, + [CHAN_ENUM_6545] = {6545, 121, 2, 160}, + [CHAN_ENUM_6565] = {6565, 125, 2, 160}, + [CHAN_ENUM_6585] = {6585, 129, 2, 160}, + [CHAN_ENUM_6605] = {6605, 133, 2, 160}, + [CHAN_ENUM_6625] = {6625, 137, 2, 160}, + [CHAN_ENUM_6645] = {6645, 141, 2, 160}, + [CHAN_ENUM_6665] = {6665, 145, 2, 160}, + [CHAN_ENUM_6685] = {6685, 149, 2, 160}, + [CHAN_ENUM_6705] = {6705, 153, 2, 160}, + [CHAN_ENUM_6725] = {6725, 157, 2, 160}, + [CHAN_ENUM_6745] = {6745, 161, 2, 160}, + [CHAN_ENUM_6765] = {6765, 165, 2, 160}, + [CHAN_ENUM_6785] = {6785, 169, 2, 160}, + [CHAN_ENUM_6805] = {6805, 173, 2, 160}, + [CHAN_ENUM_6825] = {6825, 177, 2, 160}, + [CHAN_ENUM_6845] = {6845, 181, 2, 160}, + [CHAN_ENUM_6865] = {6865, 185, 2, 160}, + [CHAN_ENUM_6885] = {6885, 189, 2, 160}, + [CHAN_ENUM_6905] = {6905, 193, 2, 160}, + [CHAN_ENUM_6925] = {6925, 197, 2, 160}, + [CHAN_ENUM_6945] = {6945, 201, 2, 160}, + [CHAN_ENUM_6965] = {6965, 205, 2, 160}, + [CHAN_ENUM_6985] = {6985, 209, 2, 160}, + [CHAN_ENUM_7005] = {7005, 213, 2, 160}, + [CHAN_ENUM_7025] = {7025, 217, 2, 160}, + [CHAN_ENUM_7045] = {7045, 221, 2, 160}, + [CHAN_ENUM_7065] = {7065, 225, 2, 160}, + [CHAN_ENUM_7085] = {7085, 229, 2, 160}, + [CHAN_ENUM_7105] = {7105, 233, 2, 160} +#endif /* CONFIG_BAND_6GHZ */ }; -static const struct chan_map channel_map_jp[NUM_CHANNELS] = { +const struct chan_map channel_map_jp[NUM_CHANNELS] = { [CHAN_ENUM_2412] = {2412, 1, 20, 40}, [CHAN_ENUM_2417] = {2417, 2, 20, 40}, [CHAN_ENUM_2422] = {2422, 3, 20, 40}, @@ -448,9 +606,70 @@ static const struct chan_map channel_map_jp[NUM_CHANNELS] = { [CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_ENUM_5945] = {5945, 1, 2, 160}, + [CHAN_ENUM_5965] = {5965, 5, 2, 160}, + [CHAN_ENUM_5985] = {5985, 9, 2, 160}, + [CHAN_ENUM_6005] = {6005, 13, 2, 160}, + [CHAN_ENUM_6025] = {6025, 17, 2, 160}, + [CHAN_ENUM_6045] = {6045, 21, 2, 160}, + [CHAN_ENUM_6065] = {6065, 25, 2, 160}, + [CHAN_ENUM_6085] = {6085, 29, 2, 160}, + [CHAN_ENUM_6105] = {6105, 33, 2, 160}, + [CHAN_ENUM_6125] = {6125, 37, 2, 160}, + [CHAN_ENUM_6145] = {6145, 41, 2, 160}, + [CHAN_ENUM_6165] = {6165, 45, 2, 160}, + [CHAN_ENUM_6185] = {6185, 49, 2, 160}, + [CHAN_ENUM_6205] = {6205, 53, 2, 160}, + [CHAN_ENUM_6225] = {6225, 57, 2, 160}, + [CHAN_ENUM_6245] = {6245, 61, 2, 160}, + [CHAN_ENUM_6265] = {6265, 65, 2, 160}, + [CHAN_ENUM_6285] = {6285, 69, 2, 160}, + [CHAN_ENUM_6305] = {6305, 73, 2, 160}, + [CHAN_ENUM_6325] = {6325, 77, 2, 160}, + [CHAN_ENUM_6345] = {6345, 81, 2, 160}, + [CHAN_ENUM_6365] = {6365, 85, 2, 160}, + [CHAN_ENUM_6385] = {6385, 89, 2, 160}, + [CHAN_ENUM_6405] = {6405, 93, 2, 160}, + [CHAN_ENUM_6425] = {6425, 97, 2, 160}, + [CHAN_ENUM_6445] = {6445, 101, 2, 160}, + [CHAN_ENUM_6465] = {6465, 105, 2, 160}, + [CHAN_ENUM_6485] = {6485, 109, 2, 160}, + [CHAN_ENUM_6505] = {6505, 113, 2, 160}, + [CHAN_ENUM_6525] = {6525, 117, 2, 160}, + [CHAN_ENUM_6545] = {6545, 121, 2, 160}, + [CHAN_ENUM_6565] = {6565, 125, 2, 160}, + [CHAN_ENUM_6585] = {6585, 129, 2, 160}, + [CHAN_ENUM_6605] = {6605, 133, 2, 160}, + [CHAN_ENUM_6625] = {6625, 137, 2, 160}, + [CHAN_ENUM_6645] = {6645, 141, 2, 160}, + [CHAN_ENUM_6665] = {6665, 145, 2, 160}, + [CHAN_ENUM_6685] = {6685, 149, 2, 160}, + [CHAN_ENUM_6705] = {6705, 153, 2, 160}, + [CHAN_ENUM_6725] = {6725, 157, 2, 160}, + [CHAN_ENUM_6745] = {6745, 161, 2, 160}, + [CHAN_ENUM_6765] = {6765, 165, 2, 160}, + [CHAN_ENUM_6785] = {6785, 169, 2, 160}, + [CHAN_ENUM_6805] = {6805, 173, 2, 160}, + [CHAN_ENUM_6825] = {6825, 177, 2, 160}, + [CHAN_ENUM_6845] = {6845, 181, 2, 160}, + [CHAN_ENUM_6865] = {6865, 185, 2, 160}, + [CHAN_ENUM_6885] = {6885, 189, 2, 160}, + [CHAN_ENUM_6905] = {6905, 193, 2, 160}, + [CHAN_ENUM_6925] = {6925, 197, 2, 160}, + [CHAN_ENUM_6945] = {6945, 201, 2, 160}, + [CHAN_ENUM_6965] = {6965, 205, 2, 160}, + [CHAN_ENUM_6985] = {6985, 209, 2, 160}, + [CHAN_ENUM_7005] = {7005, 213, 2, 160}, + [CHAN_ENUM_7025] = {7025, 217, 2, 160}, + [CHAN_ENUM_7045] = {7045, 221, 2, 160}, + [CHAN_ENUM_7065] = {7065, 225, 2, 160}, + [CHAN_ENUM_7085] = {7085, 229, 2, 160}, + [CHAN_ENUM_7105] = {7105, 233, 2, 160} +#endif /* CONFIG_BAND_6GHZ */ }; -static const struct chan_map channel_map_global[NUM_CHANNELS] = { +const struct chan_map channel_map_global[NUM_CHANNELS] = { [CHAN_ENUM_2412] = {2412, 1, 20, 40}, [CHAN_ENUM_2417] = {2417, 2, 20, 40}, [CHAN_ENUM_2422] = {2422, 3, 20, 40}, @@ -550,9 +769,70 @@ static const struct chan_map channel_map_global[NUM_CHANNELS] = { [CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_ENUM_5945] = {5945, 1, 2, 160}, + [CHAN_ENUM_5965] = {5965, 5, 2, 160}, + [CHAN_ENUM_5985] = {5985, 9, 2, 160}, + [CHAN_ENUM_6005] = {6005, 13, 2, 160}, + [CHAN_ENUM_6025] = {6025, 17, 2, 160}, + [CHAN_ENUM_6045] = {6045, 21, 2, 160}, + [CHAN_ENUM_6065] = {6065, 25, 2, 160}, + [CHAN_ENUM_6085] = {6085, 29, 2, 160}, + [CHAN_ENUM_6105] = {6105, 33, 2, 160}, + [CHAN_ENUM_6125] = {6125, 37, 2, 160}, + [CHAN_ENUM_6145] = {6145, 41, 2, 160}, + [CHAN_ENUM_6165] = {6165, 45, 2, 160}, + [CHAN_ENUM_6185] = {6185, 49, 2, 160}, + [CHAN_ENUM_6205] = {6205, 53, 2, 160}, + [CHAN_ENUM_6225] = {6225, 57, 2, 160}, + [CHAN_ENUM_6245] = {6245, 61, 2, 160}, + [CHAN_ENUM_6265] = {6265, 65, 2, 160}, + [CHAN_ENUM_6285] = {6285, 69, 2, 160}, + [CHAN_ENUM_6305] = {6305, 73, 2, 160}, + [CHAN_ENUM_6325] = {6325, 77, 2, 160}, + [CHAN_ENUM_6345] = {6345, 81, 2, 160}, + [CHAN_ENUM_6365] = {6365, 85, 2, 160}, + [CHAN_ENUM_6385] = {6385, 89, 2, 160}, + [CHAN_ENUM_6405] = {6405, 93, 2, 160}, + [CHAN_ENUM_6425] = {6425, 97, 2, 160}, + [CHAN_ENUM_6445] = {6445, 101, 2, 160}, + [CHAN_ENUM_6465] = {6465, 105, 2, 160}, + [CHAN_ENUM_6485] = {6485, 109, 2, 160}, + [CHAN_ENUM_6505] = {6505, 113, 2, 160}, + [CHAN_ENUM_6525] = {6525, 117, 2, 160}, + [CHAN_ENUM_6545] = {6545, 121, 2, 160}, + [CHAN_ENUM_6565] = {6565, 125, 2, 160}, + [CHAN_ENUM_6585] = {6585, 129, 2, 160}, + [CHAN_ENUM_6605] = {6605, 133, 2, 160}, + [CHAN_ENUM_6625] = {6625, 137, 2, 160}, + [CHAN_ENUM_6645] = {6645, 141, 2, 160}, + [CHAN_ENUM_6665] = {6665, 145, 2, 160}, + [CHAN_ENUM_6685] = {6685, 149, 2, 160}, + [CHAN_ENUM_6705] = {6705, 153, 2, 160}, + [CHAN_ENUM_6725] = {6725, 157, 2, 160}, + [CHAN_ENUM_6745] = {6745, 161, 2, 160}, + [CHAN_ENUM_6765] = {6765, 165, 2, 160}, + [CHAN_ENUM_6785] = {6785, 169, 2, 160}, + [CHAN_ENUM_6805] = {6805, 173, 2, 160}, + [CHAN_ENUM_6825] = {6825, 177, 2, 160}, + [CHAN_ENUM_6845] = {6845, 181, 2, 160}, + [CHAN_ENUM_6865] = {6865, 185, 2, 160}, + [CHAN_ENUM_6885] = {6885, 189, 2, 160}, + [CHAN_ENUM_6905] = {6905, 193, 2, 160}, + [CHAN_ENUM_6925] = {6925, 197, 2, 160}, + [CHAN_ENUM_6945] = {6945, 201, 2, 160}, + [CHAN_ENUM_6965] = {6965, 205, 2, 160}, + [CHAN_ENUM_6985] = {6985, 209, 2, 160}, + [CHAN_ENUM_7005] = {7005, 213, 2, 160}, + [CHAN_ENUM_7025] = {7025, 217, 2, 160}, + [CHAN_ENUM_7045] = {7045, 221, 2, 160}, + [CHAN_ENUM_7065] = {7065, 225, 2, 160}, + [CHAN_ENUM_7085] = {7085, 229, 2, 160}, + [CHAN_ENUM_7105] = {7105, 233, 2, 160} +#endif /* CONFIG_BAND_6GHZ */ }; -static const struct chan_map channel_map_china[NUM_CHANNELS] = { +const struct chan_map channel_map_china[NUM_CHANNELS] = { [CHAN_ENUM_2412] = {2412, 1, 20, 40}, [CHAN_ENUM_2417] = {2417, 2, 20, 40}, [CHAN_ENUM_2422] = {2422, 3, 20, 40}, @@ -652,15 +932,69 @@ static const struct chan_map channel_map_china[NUM_CHANNELS] = { [CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160}, [CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160}, +#ifdef CONFIG_BAND_6GHZ + [CHAN_ENUM_5945] = {5945, 1, 2, 160}, + [CHAN_ENUM_5965] = {5965, 5, 2, 160}, + [CHAN_ENUM_5985] = {5985, 9, 2, 160}, + [CHAN_ENUM_6005] = {6005, 13, 2, 160}, + [CHAN_ENUM_6025] = {6025, 17, 2, 160}, + [CHAN_ENUM_6045] = {6045, 21, 2, 160}, + [CHAN_ENUM_6065] = {6065, 25, 2, 160}, + [CHAN_ENUM_6085] = {6085, 29, 2, 160}, + [CHAN_ENUM_6105] = {6105, 33, 2, 160}, + [CHAN_ENUM_6125] = {6125, 37, 2, 160}, + [CHAN_ENUM_6145] = {6145, 41, 2, 160}, + [CHAN_ENUM_6165] = {6165, 45, 2, 160}, + [CHAN_ENUM_6185] = {6185, 49, 2, 160}, + [CHAN_ENUM_6205] = {6205, 53, 2, 160}, + [CHAN_ENUM_6225] = {6225, 57, 2, 160}, + [CHAN_ENUM_6245] = {6245, 61, 2, 160}, + [CHAN_ENUM_6265] = {6265, 65, 2, 160}, + [CHAN_ENUM_6285] = {6285, 69, 2, 160}, + [CHAN_ENUM_6305] = {6305, 73, 2, 160}, + [CHAN_ENUM_6325] = {6325, 77, 2, 160}, + [CHAN_ENUM_6345] = {6345, 81, 2, 160}, + [CHAN_ENUM_6365] = {6365, 85, 2, 160}, + [CHAN_ENUM_6385] = {6385, 89, 2, 160}, + [CHAN_ENUM_6405] = {6405, 93, 2, 160}, + [CHAN_ENUM_6425] = {6425, 97, 2, 160}, + [CHAN_ENUM_6445] = {6445, 101, 2, 160}, + [CHAN_ENUM_6465] = {6465, 105, 2, 160}, + [CHAN_ENUM_6485] = {6485, 109, 2, 160}, + [CHAN_ENUM_6505] = {6505, 113, 2, 160}, + [CHAN_ENUM_6525] = {6525, 117, 2, 160}, + [CHAN_ENUM_6545] = {6545, 121, 2, 160}, + [CHAN_ENUM_6565] = {6565, 125, 2, 160}, + [CHAN_ENUM_6585] = {6585, 129, 2, 160}, + [CHAN_ENUM_6605] = {6605, 133, 2, 160}, + [CHAN_ENUM_6625] = {6625, 137, 2, 160}, + [CHAN_ENUM_6645] = {6645, 141, 2, 160}, + [CHAN_ENUM_6665] = {6665, 145, 2, 160}, + [CHAN_ENUM_6685] = {6685, 149, 2, 160}, + [CHAN_ENUM_6705] = {6705, 153, 2, 160}, + [CHAN_ENUM_6725] = {6725, 157, 2, 160}, + [CHAN_ENUM_6745] = {6745, 161, 2, 160}, + [CHAN_ENUM_6765] = {6765, 165, 2, 160}, + [CHAN_ENUM_6785] = {6785, 169, 2, 160}, + [CHAN_ENUM_6805] = {6805, 173, 2, 160}, + [CHAN_ENUM_6825] = {6825, 177, 2, 160}, + [CHAN_ENUM_6845] = {6845, 181, 2, 160}, + [CHAN_ENUM_6865] = {6865, 185, 2, 160}, + [CHAN_ENUM_6885] = {6885, 189, 2, 160}, + [CHAN_ENUM_6905] = {6905, 193, 2, 160}, + [CHAN_ENUM_6925] = {6925, 197, 2, 160}, + [CHAN_ENUM_6945] = {6945, 201, 2, 160}, + [CHAN_ENUM_6965] = {6965, 205, 2, 160}, + [CHAN_ENUM_6985] = {6985, 209, 2, 160}, + [CHAN_ENUM_7005] = {7005, 213, 2, 160}, + [CHAN_ENUM_7025] = {7025, 217, 2, 160}, + [CHAN_ENUM_7045] = {7045, 221, 2, 160}, + [CHAN_ENUM_7065] = {7065, 225, 2, 160}, + [CHAN_ENUM_7085] = {7085, 229, 2, 160}, + [CHAN_ENUM_7105] = {7105, 233, 2, 160} +#endif /* CONFIG_BAND_6GHZ */ }; -#endif -#ifdef CONFIG_LEGACY_CHAN_ENUM -void reg_init_channel_map(enum dfs_reg dfs_region) -{ - channel_map = channel_map_old; -} -#else void reg_init_channel_map(enum dfs_reg dfs_region) { switch (dfs_region) { @@ -675,6 +1009,7 @@ void reg_init_channel_map(enum dfs_reg dfs_region) channel_map = channel_map_eu; break; case DFS_MKK_REGION: + case DFS_MKKN_REGION: channel_map = channel_map_jp; break; case DFS_CN_REGION: @@ -685,7 +1020,6 @@ void reg_init_channel_map(enum dfs_reg dfs_region) break; } } -#endif uint16_t reg_get_bw_value(enum phy_ch_width bw) { @@ -719,6 +1053,7 @@ struct wlan_lmac_if_reg_tx_ops *reg_get_psoc_tx_ops( return &((psoc->soc_cb.tx_ops.reg_ops)); } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan) @@ -747,6 +1082,8 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, reg_channels[i].chan_flags != REGULATORY_CHAN_DISABLED) { ch_list[count].chan_num = reg_channels[i].chan_num; + ch_list[count].center_freq = + reg_channels[i].center_freq; ch_list[count++].tx_power = reg_channels[i].tx_power; } @@ -757,7 +1094,7 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } -enum channel_enum reg_get_chan_enum(uint32_t chan_num) +enum channel_enum reg_get_chan_enum(uint8_t chan_num) { uint32_t count; @@ -765,13 +1102,13 @@ enum channel_enum reg_get_chan_enum(uint32_t chan_num) if (channel_map[count].chan_num == chan_num) return count; - reg_err("invalid channel number %d", chan_num); + reg_err_rl("invalid channel number %d", chan_num); return INVALID_CHANNEL; } enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev, - uint32_t ch) + uint8_t ch) { enum channel_enum ch_idx; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -791,32 +1128,6 @@ enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev, return pdev_priv_obj->cur_chan_list[ch_idx].state; } - -static uint32_t reg_get_channel_flags(struct wlan_objmgr_pdev *pdev, - uint32_t chan) -{ - enum channel_enum chan_enum; - struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - - chan_enum = reg_get_chan_enum(chan); - - if (chan_enum == INVALID_CHANNEL) { - reg_err("chan is not valid"); - return REGULATORY_CHAN_INVALID; - } - - pdev_priv_obj = reg_get_pdev_obj(pdev); - - if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { - reg_err("pdev reg obj is NULL"); - return REGULATORY_CHAN_INVALID; - } - - return pdev_priv_obj->cur_chan_list[chan_enum].chan_flags; -} - - - /** * reg_get_5g_bonded_chan_array() - get ptr to bonded channel * @pdev: Pointer to pdev structure @@ -829,7 +1140,7 @@ static uint32_t reg_get_channel_flags(struct wlan_objmgr_pdev *pdev, */ static enum channel_state reg_get_5g_bonded_chan_array( struct wlan_objmgr_pdev *pdev, - uint32_t oper_chan, + uint8_t oper_chan, const struct bonded_channel bonded_chan_ar[], uint16_t array_size, const struct bonded_channel **bonded_chan_ptr_ptr) @@ -863,17 +1174,8 @@ static enum channel_state reg_get_5g_bonded_chan_array( return chan_state; } -/** - * reg_get_5g_bonded_channel() - get the 5G bonded channel state - * @pdev: Pointer to pdev structure - * @chan_num: channel number - * @ch_width: channel width - * @bonded_chan_ptr_ptr: bonded channel ptr ptr - * - * Return: channel state - */ -static enum channel_state reg_get_5g_bonded_channel( - struct wlan_objmgr_pdev *pdev, uint32_t chan_num, +enum channel_state reg_get_5g_bonded_channel( + struct wlan_objmgr_pdev *pdev, uint8_t chan_num, enum phy_ch_width ch_width, const struct bonded_channel **bonded_chan_ptr_ptr) { @@ -1024,6 +1326,7 @@ enum channel_state reg_get_2g_bonded_channel_state( return CHANNEL_STATE_ENABLE; } +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_combine_channel_states() - Get minimum of channel state1 and state2 @@ -1043,6 +1346,7 @@ static enum channel_state reg_combine_channel_states( return min(chan_state1, chan_state2); } +#ifdef CONFIG_CHAN_NUM_API /** * reg_set_5g_channel_params () - Sets channel parameteres for given bandwidth * @ch: channel number. @@ -1203,22 +1507,7 @@ void reg_set_channel_params(struct wlan_objmgr_pdev *pdev, else if (REG_IS_24GHZ_CH(ch)) reg_set_2g_channel_params(pdev, ch, ch_params, sec_ch_2g); } - -QDF_STATUS reg_get_curr_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band) -{ - struct wlan_regulatory_pdev_priv_obj *pdev_reg; - - pdev_reg = reg_get_pdev_obj(pdev); - if (!IS_VALID_PDEV_REG_OBJ(pdev_reg)) { - reg_err("pdev reg component is NULL"); - return QDF_STATUS_E_INVAL; - } - - *band = pdev_reg->band_capability; - - return QDF_STATUS_SUCCESS; -} +#endif /* CONFIG_CHAN_NUM_API */ QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country_code) @@ -1272,8 +1561,9 @@ void reg_set_dfs_region(struct wlan_objmgr_pdev *pdev, reg_init_channel_map(dfs_reg); } +#ifdef CONFIG_CHAN_NUM_API uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) + uint8_t chan_num) { enum channel_enum chan_enum; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -1298,8 +1588,8 @@ uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, return reg_channels[chan_enum].tx_power; } -uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) +qdf_freq_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) { enum channel_enum chan_enum; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -1323,27 +1613,33 @@ uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, } bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { - uint32_t chan_flags; + enum channel_state ch_state; - chan_flags = reg_get_channel_flags(pdev, chan); + ch_state = reg_get_channel_state(pdev, chan); - return chan_flags & REGULATORY_CHAN_RADAR; + return ch_state == CHANNEL_STATE_DFS; } +#endif /* CONFIG_CHAN_NUM_API */ -uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, - uint32_t freq) +uint8_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) { uint32_t count; struct regulatory_channel *chan_list; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + if (freq == 0) { + reg_err_rl("Invalid freq %d", freq); + return 0; + } + pdev_priv_obj = reg_get_pdev_obj(pdev); if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { reg_err("reg pdev priv obj is NULL"); - return QDF_STATUS_E_FAILURE; + return 0; } chan_list = pdev_priv_obj->mas_chan_list; @@ -1371,7 +1667,7 @@ uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, (freq - chan_list[count - 1].center_freq) / 5); end: - reg_err("invalid frequency %d", freq); + reg_err_rl("invalid frequency %d", freq); return 0; } @@ -1394,7 +1690,7 @@ static uint16_t reg_compute_chan_to_freq(struct wlan_objmgr_pdev *pdev, chan_list = pdev_priv_obj->mas_chan_list; for (count = min_chan_range; count <= max_chan_range; count++) { - if (reg_chan_is_49ghz(pdev, chan_list[count].chan_num)) { + if (REG_IS_49GHZ_FREQ(chan_list[count].center_freq)) { if (chan_list[count].chan_num == chan_num) break; continue; @@ -1417,7 +1713,7 @@ static uint16_t reg_compute_chan_to_freq(struct wlan_objmgr_pdev *pdev, goto end; if ((chan_list[count - 1].chan_num == INVALID_CHANNEL_NUM) || - reg_chan_is_49ghz(pdev, chan_list[count - 1].chan_num) || + REG_IS_49GHZ_FREQ(chan_list[count - 1].center_freq) || (chan_list[count].chan_num == INVALID_CHANNEL_NUM)) { reg_err("Channel %d invalid in current reg domain", chan_num); @@ -1439,23 +1735,34 @@ uint16_t reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint16_t min_chan_range = MIN_24GHZ_CHANNEL; uint16_t max_chan_range = MAX_5GHZ_CHANNEL; + if (chan_num == 0) { + reg_err_rl("Invalid channel %d", chan_num); + return 0; + } + return reg_compute_chan_to_freq(pdev, chan_num, min_chan_range, max_chan_range); } -uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) +#ifdef CONFIG_CHAN_NUM_API +qdf_freq_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) { uint32_t count; struct regulatory_channel *chan_list; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + if (chan_num == 0) { + reg_err_rl("Invalid channel %d", chan_num); + return 0; + } + pdev_priv_obj = reg_get_pdev_obj(pdev); if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { reg_err("reg pdev priv obj is NULL"); - return QDF_STATUS_E_FAILURE; + return 0; } chan_list = pdev_priv_obj->cur_chan_list; @@ -1475,23 +1782,16 @@ uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, return 0; } -#ifndef CONFIG_LEGACY_CHAN_ENUM bool reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num) { - uint32_t freq = 0; + qdf_freq_t freq = 0; freq = reg_chan_to_freq(pdev, chan_num); return REG_IS_49GHZ_FREQ(freq) ? true : false; } -#else -bool reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num) -{ - return false; -} -#endif -enum band_info reg_chan_to_band(uint32_t chan_num) +enum band_info reg_chan_to_band(uint8_t chan_num) { if (chan_num <= 14) return BAND_2G; @@ -1533,6 +1833,7 @@ void reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, reg_compute_pdev_current_chan_list(pdev_priv_obj); } +#endif /* CONFIG_CHAN_NUM_API */ QDF_STATUS reg_program_default_cc(struct wlan_objmgr_pdev *pdev, uint16_t regdmn) @@ -1765,7 +2066,7 @@ QDF_STATUS reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev, } if (index == num_reg_dmn) { - reg_err("invalid regdomain"); + reg_debug_rl("invalid regdomain"); return QDF_STATUS_E_FAILURE; } @@ -1883,8 +2184,8 @@ QDF_STATUS reg_set_hal_reg_cap( } bool reg_chan_in_range(struct regulatory_channel *chan_list, - uint32_t low_freq_2g, uint32_t high_freq_2g, - uint32_t low_freq_5g, uint32_t high_freq_5g, + qdf_freq_t low_freq_2g, qdf_freq_t high_freq_2g, + qdf_freq_t low_freq_5g, qdf_freq_t high_freq_5g, enum channel_enum ch_enum) { uint32_t low_limit_2g = NUM_CHANNELS; @@ -1894,7 +2195,7 @@ bool reg_chan_in_range(struct regulatory_channel *chan_list, bool chan_in_range; enum channel_enum chan_enum; uint16_t min_bw; - uint32_t center_freq; + qdf_freq_t center_freq; for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { min_bw = chan_list[chan_enum].min_bw; @@ -1958,6 +2259,7 @@ bool reg_chan_in_range(struct regulatory_channel *chan_list, return false; } +#ifdef CONFIG_CHAN_NUM_API void reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, uint8_t *chan_list, uint8_t num_chan, bool nol_history_chan) @@ -2005,6 +2307,7 @@ bool reg_is_5ghz_ch(uint32_t chan) { return REG_IS_5GHZ_CH(chan); } +#endif /* CONFIG_CHAN_NUM_API */ bool reg_is_24ghz_ch_freq(uint32_t freq) { @@ -2016,53 +2319,285 @@ bool reg_is_5ghz_ch_freq(uint32_t freq) return REG_IS_5GHZ_FREQ(freq); } -#ifndef CONFIG_LEGACY_CHAN_ENUM -bool reg_is_49ghz_freq(uint32_t freq) +/** + * BAND_2G_PRESENT() - Check if REG_BAND_2G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_2G is set in the band_mask, else false + */ +static inline bool BAND_2G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_2G))); +} + +/** + * BAND_5G_PRESENT() - Check if REG_BAND_5G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_5G is set in the band_mask, else false + */ +static inline bool BAND_5G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_5G))); +} + +bool reg_is_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + struct regulatory_channel *cur_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + enum channel_enum chan_enum; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return false; + } + + chan_enum = reg_get_chan_enum_for_freq(freq); + + if (chan_enum == INVALID_CHANNEL) { + reg_err_rl("Invalid chan enum %d", chan_enum); + return false; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + return (cur_chan_list[chan_enum].chan_flags & + REGULATORY_CHAN_INDOOR_ONLY); +} + +#ifdef CONFIG_BAND_6GHZ +bool reg_is_6ghz_chan_freq(uint16_t freq) +{ + return REG_IS_6GHZ_FREQ(freq); +} + +uint16_t reg_min_6ghz_chan_freq(void) +{ + return REG_MIN_6GHZ_CHAN_FREQ; +} + +uint16_t reg_max_6ghz_chan_freq(void) +{ + return REG_MAX_6GHZ_CHAN_FREQ; +} + +bool reg_is_6ghz_psc_chan_freq(uint16_t freq) +{ + if (!REG_IS_6GHZ_FREQ(freq)) { + reg_debug(" Channel frequency is not a 6GHz frequency"); + return false; + } + + if (!(((freq - SIXG_STARTING_FREQ) + (FREQ_LEFT_SHIFT)) % + (FREQ_TO_CHAN_SCALE * NUM_80MHZ_BAND_IN_6G))) { + return true; + } + + reg_debug_rl("Channel freq %d MHz is not a 6GHz PSC frequency", freq); + + return false; +} + +/** + * BAND_6G_PRESENT() - Check if REG_BAND_6G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_6G is set in the band_mask, else false + */ +static inline bool BAND_6G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_6G))); +} +#else +static inline bool BAND_6G_PRESENT(uint8_t band_mask) +{ + return false; +} +#endif /* CONFIG_BAND_6GHZ */ + +uint16_t +reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *cur_chan_list; + uint16_t i, num_channels = 0; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return 0; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + if (BAND_2G_PRESENT(band_mask)) { + for (i = MIN_24GHZ_CHANNEL; i <= MAX_24GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + if (BAND_5G_PRESENT(band_mask)) { + for (i = MIN_49GHZ_CHANNEL; i <= MAX_5GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + if (BAND_6G_PRESENT(band_mask)) { + for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + + if (!num_channels) { + reg_err("Failed to retrieve the channel list"); + return 0; + } + + return num_channels; +} + +qdf_freq_t reg_chan_band_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num, + uint8_t band_mask) +{ + enum channel_enum min_chan, max_chan; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + uint16_t freq; + + if (chan_num == 0) { + reg_err_rl("Invalid channel %d", chan_num); + return 0; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return 0; + } + + if (BAND_6G_PRESENT(band_mask)) { + if (BAND_2G_PRESENT(band_mask) || + BAND_5G_PRESENT(band_mask)) { + reg_err_rl("Incorrect band_mask %x", band_mask); + return 0; + } + + min_chan = MIN_6GHZ_CHANNEL; + max_chan = MAX_6GHZ_CHANNEL; + return reg_compute_chan_to_freq(pdev, chan_num, + min_chan, + max_chan); + } else { + if (BAND_2G_PRESENT(band_mask)) { + min_chan = MIN_24GHZ_CHANNEL; + max_chan = MAX_24GHZ_CHANNEL; + freq = reg_compute_chan_to_freq(pdev, chan_num, + min_chan, + max_chan); + if (freq != 0) + return freq; + } + + if (BAND_5G_PRESENT(band_mask)) { + min_chan = MIN_49GHZ_CHANNEL; + max_chan = MAX_5GHZ_CHANNEL; + + return reg_compute_chan_to_freq(pdev, chan_num, + min_chan, + max_chan); + } + + reg_err_rl("Incorrect band_mask %x", band_mask); + return 0; + } +} + +bool reg_is_49ghz_freq(qdf_freq_t freq) { return REG_IS_49GHZ_FREQ(freq); } -#endif -uint32_t reg_ch_num(uint32_t ch_enum) +qdf_freq_t reg_ch_num(uint32_t ch_enum) { return REG_CH_NUM(ch_enum); } -uint32_t reg_ch_to_freq(uint32_t ch_enum) +qdf_freq_t reg_ch_to_freq(uint32_t ch_enum) { return REG_CH_TO_FREQ(ch_enum); } -bool reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2) +#ifdef CONFIG_CHAN_NUM_API +bool reg_is_same_band_channels(uint8_t chan_num1, uint8_t chan_num2) { return (chan_num1 && chan_num2 && (REG_IS_5GHZ_CH(chan_num1) == REG_IS_5GHZ_CH(chan_num2))); } -bool reg_is_channel_valid_5g_sbs(uint32_t curchan, uint32_t newchan) +bool reg_is_channel_valid_5g_sbs(uint8_t curchan, uint8_t newchan) { return REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan); } -uint32_t reg_min_24ghz_ch_num(void) +uint8_t reg_min_24ghz_ch_num(void) { return REG_MIN_24GHZ_CH_NUM; } -uint32_t reg_max_24ghz_ch_num(void) +uint8_t reg_max_24ghz_ch_num(void) { return REG_MAX_24GHZ_CH_NUM; } -uint32_t reg_min_5ghz_ch_num(void) +uint8_t reg_min_5ghz_ch_num(void) { return REG_MIN_5GHZ_CH_NUM; } -uint32_t reg_max_5ghz_ch_num(void) +uint8_t reg_max_5ghz_ch_num(void) { return REG_MAX_5GHZ_CH_NUM; } +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +qdf_freq_t reg_min_24ghz_chan_freq(void) +{ + return REG_MIN_24GHZ_CH_FREQ; +} + +qdf_freq_t reg_max_24ghz_chan_freq(void) +{ + return REG_MAX_24GHZ_CH_FREQ; +} + +qdf_freq_t reg_min_5ghz_chan_freq(void) +{ + return REG_MIN_5GHZ_CH_FREQ; +} + +qdf_freq_t reg_max_5ghz_chan_freq(void) +{ + return REG_MAX_5GHZ_CH_FREQ; +} +#endif /* CONFIG_CHAN_FREQ_API */ QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable) @@ -2116,65 +2651,1022 @@ QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, return status; } -QDF_STATUS reg_set_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc) -{ - struct wlan_regulatory_psoc_priv_obj *psoc_reg; - - psoc_reg = reg_get_psoc_obj(psoc); - if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { - reg_err("psoc reg component is NULL"); - return QDF_STATUS_E_INVAL; - } - - psoc_reg->ignore_fw_reg_offload_ind = true; - return QDF_STATUS_SUCCESS; -} - -bool reg_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc) +bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) { - struct wlan_regulatory_psoc_priv_obj *psoc_reg; + struct cur_regdmn_info cur_reg_dmn; + QDF_STATUS status; - psoc_reg = reg_get_psoc_obj(psoc); - if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) + status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); + if (status != QDF_STATUS_SUCCESS) { + reg_err("Failed to get reg domain"); return false; + } - return psoc_reg->ignore_fw_reg_offload_ind; + return reg_en302_502_regdmn(cur_reg_dmn.regdmn_pair_id); } -QDF_STATUS reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc, bool val) +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) { + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr; + uint32_t cnt; + uint32_t phy_id; + enum direction dir; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct target_pdev_info *tgt_pdev; + + tgt_pdev = wlan_pdev_get_tgt_if_handle(pdev); + phy_id = (uint32_t)target_pdev_get_phy_idx(tgt_pdev); + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } - psoc_priv_obj = reg_get_psoc_obj(psoc); + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + psoc_priv_obj = reg_get_psoc_obj(psoc); if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { reg_err("psoc reg component is NULL"); - return QDF_STATUS_E_FAILURE; + return QDF_STATUS_E_INVAL; } - psoc_priv_obj->six_ghz_supported = val; + reg_cap_ptr = psoc_priv_obj->reg_cap; - return QDF_STATUS_SUCCESS; -} + for (cnt = 0; cnt < PSOC_MAX_PHY_REG_CAP; cnt++) { + if (!reg_cap_ptr) { + qdf_mem_free(pdev_priv_obj); + reg_err("reg cap ptr is NULL"); + return QDF_STATUS_E_FAULT; + } -bool reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, uint8_t op_class) -{ - return ((op_class >= MIN_6GHZ_OPER_CLASS) && - (op_class <= MAX_6GHZ_OPER_CLASS)); + if (reg_cap_ptr->phy_id == phy_id) + break; + reg_cap_ptr++; + } + + if (cnt == PSOC_MAX_PHY_REG_CAP) { + qdf_mem_free(pdev_priv_obj); + reg_err("extended capabilities not found for pdev"); + return QDF_STATUS_E_FAULT; + } + + if (psoc_priv_obj->offload_enabled) { + dir = NORTHBOUND; + } else { + dir = SOUTHBOUND; + } + + pdev_priv_obj->range_2g_low = reg_cap_ptr->low_2ghz_chan; + pdev_priv_obj->range_2g_high = reg_cap_ptr->high_2ghz_chan; + pdev_priv_obj->range_5g_low = reg_cap_ptr->low_5ghz_chan; + pdev_priv_obj->range_5g_high = reg_cap_ptr->high_5ghz_chan; + pdev_priv_obj->wireless_modes = reg_cap_ptr->wireless_modes; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + + /* Fill the ic channel list with the updated current channel + * chan list. + */ + if (reg_tx_ops->fill_umac_legacy_chanlist) { + reg_tx_ops->fill_umac_legacy_chanlist(pdev, + pdev_priv_obj->cur_chan_list); + + } else { + if (dir == NORTHBOUND) + status = reg_send_scheduler_msg_nb(psoc, pdev); + else + status = reg_send_scheduler_msg_sb(psoc, pdev); + } + + return status; +} + +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_is_reg_unii_band_1_or_reg_unii_band_2a() - Check the input bitmap + * @unii_5g_bitmap: 5G UNII band bitmap + * + * This function checks if either REG_UNII_BAND_1 or REG_UNII_BAND_2A, + * are present in the 5G UNII band bitmap. + * + * Return: Return true if REG_UNII_BAND_1 or REG_UNII_BAND_2A, are present in + * the UNII 5g bitmap else return false. + */ +static bool +reg_is_reg_unii_band_1_or_reg_unii_band_2a(uint8_t unii_5g_bitmap) +{ + if (!unii_5g_bitmap) + return false; + + return ((unii_5g_bitmap & (BIT(REG_UNII_BAND_1) | + BIT(REG_UNII_BAND_2A))) == unii_5g_bitmap); +} + +QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("reg pdev priv obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (unii_5g_bitmap && + !reg_is_reg_unii_band_1_or_reg_unii_band_2a(unii_5g_bitmap)) { + reg_err_rl("Invalid unii_5g_bitmap = %d", unii_5g_bitmap); + return QDF_STATUS_E_FAILURE; + } + + if (pdev_priv_obj->unii_5g_bitmap == unii_5g_bitmap) { + reg_debug_rl("UNII bitmask for 5G channels is already set %d", + unii_5g_bitmap); + return QDF_STATUS_SUCCESS; + } + + reg_debug_rl("Setting UNII bitmask for 5G: %d", unii_5g_bitmap); + pdev_priv_obj->unii_5g_bitmap = unii_5g_bitmap; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + + if (reg_tx_ops->fill_umac_legacy_chanlist) { + reg_tx_ops->fill_umac_legacy_chanlist(pdev, + pdev_priv_obj->cur_chan_list); + } + + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev + *pdev, + struct channel_power + *ch_list, + uint8_t *num_chan) +{ + int i, count; + struct regulatory_channel *reg_channels; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + if (!num_chan || !ch_list) { + reg_err("chan_list or num_ch is NULL"); + return QDF_STATUS_E_FAILURE; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + /* set the current channel list */ + reg_channels = pdev_priv_obj->cur_chan_list; + + for (i = 0, count = 0; i < NUM_CHANNELS; i++) { + if (reg_channels[i].state && + !(reg_channels[i].chan_flags & REGULATORY_CHAN_DISABLED)) { + ch_list[count].center_freq = + reg_channels[i].center_freq; + ch_list[count++].tx_power = + reg_channels[i].tx_power; + } + } + + *num_chan = count; + + return QDF_STATUS_SUCCESS; +} + +enum channel_enum reg_get_chan_enum_for_freq(qdf_freq_t freq) +{ + uint32_t count; + + for (count = 0; count < NUM_CHANNELS; count++) + if (channel_map[count].center_freq == freq) + return count; + + reg_err("invalid channel center frequency %d", freq); + + return INVALID_CHANNEL; +} + +bool +reg_is_freq_present_in_cur_chan_list(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_enum chan_enum; + struct regulatory_channel *cur_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("pdev reg obj is NULL"); + return false; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) + if (cur_chan_list[chan_enum].center_freq == freq) + if ((cur_chan_list[chan_enum].state != + CHANNEL_STATE_DISABLE) && + !(cur_chan_list[chan_enum].chan_flags & + REGULATORY_CHAN_DISABLED)) + return true; + + reg_debug_rl("Channel center frequency %d not found", freq); + + return false; +} + +enum channel_state reg_get_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_enum ch_idx; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + ch_idx = reg_get_chan_enum_for_freq(freq); + + if (ch_idx == INVALID_CHANNEL) + return CHANNEL_STATE_INVALID; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg obj is NULL"); + return CHANNEL_STATE_INVALID; + } + + return pdev_priv_obj->cur_chan_list[ch_idx].state; +} + +static uint32_t reg_get_channel_flags_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_enum chan_enum; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + chan_enum = reg_get_chan_enum_for_freq(freq); + + if (chan_enum == INVALID_CHANNEL) { + reg_err("chan freq is not valid"); + return REGULATORY_CHAN_INVALID; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg obj is NULL"); + return REGULATORY_CHAN_INVALID; + } + + return pdev_priv_obj->cur_chan_list[chan_enum].chan_flags; +} + +/** + * reg_get_5g_bonded_chan_array_for_freq()- Return the channel state for a + * 5G or 6G channel frequency based on the bonded channel. + * @pdev: Pointer to pdev. + * @freq: Channel center frequency. + * @bonded_chan_ar: Array of bonded channel frequencies. + * @array_size: Array size. + * @bonded_chan_ptr_ptr: Pointer to bonded_channel_freq. + * + * Return: Channel State + */ +static enum channel_state +reg_get_5g_bonded_chan_array_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + const struct bonded_channel_freq + bonded_chan_ar[], + uint16_t array_size, + const struct bonded_channel_freq + **bonded_chan_ptr_ptr) +{ + int i; + uint16_t chan_cfreq; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + enum channel_state chan_state = CHANNEL_STATE_INVALID; + enum channel_state temp_chan_state; + + for (i = 0; i < array_size; i++) { + if ((freq >= bonded_chan_ar[i].start_freq) && + (freq <= bonded_chan_ar[i].end_freq)) { + bonded_chan_ptr = &bonded_chan_ar[i]; + break; + } + } + + if (!bonded_chan_ptr) + return chan_state; + + *bonded_chan_ptr_ptr = bonded_chan_ptr; + chan_cfreq = bonded_chan_ptr->start_freq; + while (chan_cfreq <= bonded_chan_ptr->end_freq) { + temp_chan_state = reg_get_channel_state_for_freq(pdev, + chan_cfreq); + if (temp_chan_state < chan_state) + chan_state = temp_chan_state; + chan_cfreq = chan_cfreq + 20; + } + + return chan_state; +} + +/** + * reg_get_5g_bonded_channel_for_freq()- Return the channel state for a + * 5G or 6G channel frequency based on the channel width and bonded channel + * @pdev: Pointer to pdev. + * @freq: Channel center frequency. + * @ch_width: Channel Width. + * @bonded_chan_ptr_ptr: Pointer to bonded_channel_freq. + * + * Return: Channel State + */ +enum channel_state +reg_get_5g_bonded_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + enum phy_ch_width ch_width, + const struct bonded_channel_freq + **bonded_chan_ptr_ptr) + +{ + if (ch_width == CH_WIDTH_80P80MHZ) + return reg_get_5g_bonded_chan_array_for_freq(pdev, freq, + bonded_chan_80mhz_list_freq, + QDF_ARRAY_SIZE(bonded_chan_80mhz_list_freq), + bonded_chan_ptr_ptr); + else if (ch_width == CH_WIDTH_160MHZ) + return reg_get_5g_bonded_chan_array_for_freq(pdev, freq, + bonded_chan_160mhz_list_freq, + QDF_ARRAY_SIZE(bonded_chan_160mhz_list_freq), + bonded_chan_ptr_ptr); + else if (ch_width == CH_WIDTH_80MHZ) + return reg_get_5g_bonded_chan_array_for_freq(pdev, freq, + bonded_chan_80mhz_list_freq, + QDF_ARRAY_SIZE(bonded_chan_80mhz_list_freq), + bonded_chan_ptr_ptr); + else if (ch_width == CH_WIDTH_40MHZ) + return reg_get_5g_bonded_chan_array_for_freq(pdev, freq, + bonded_chan_40mhz_list_freq, + QDF_ARRAY_SIZE(bonded_chan_40mhz_list_freq), + bonded_chan_ptr_ptr); + else + return reg_get_channel_state_for_freq(pdev, freq); +} + +enum channel_state +reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw) +{ + enum channel_enum ch_indx; + enum channel_state chan_state; + struct regulatory_channel *reg_channels; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + bool bw_enabled = false; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + + if (bw > CH_WIDTH_80P80MHZ) { + reg_err("bw passed is not good"); + return CHANNEL_STATE_INVALID; + } + + chan_state = reg_get_5g_bonded_channel_for_freq(pdev, freq, bw, + &bonded_chan_ptr); + + if ((chan_state == CHANNEL_STATE_INVALID) || + (chan_state == CHANNEL_STATE_DISABLE)) + return chan_state; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg obj is NULL"); + return CHANNEL_STATE_INVALID; + } + reg_channels = pdev_priv_obj->cur_chan_list; + + ch_indx = reg_get_chan_enum_for_freq(freq); + if (ch_indx == INVALID_CHANNEL) + return CHANNEL_STATE_INVALID; + if (bw == CH_WIDTH_5MHZ) + bw_enabled = true; + else if (bw == CH_WIDTH_10MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 10) && + (reg_channels[ch_indx].max_bw >= 10); + else if (bw == CH_WIDTH_20MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 20) && + (reg_channels[ch_indx].max_bw >= 20); + else if (bw == CH_WIDTH_40MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 40) && + (reg_channels[ch_indx].max_bw >= 40); + else if (bw == CH_WIDTH_80MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 80) && + (reg_channels[ch_indx].max_bw >= 80); + else if (bw == CH_WIDTH_160MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 160) && + (reg_channels[ch_indx].max_bw >= 160); + else if (bw == CH_WIDTH_80P80MHZ) + bw_enabled = (reg_channels[ch_indx].min_bw <= 80) && + (reg_channels[ch_indx].max_bw >= 80); + + if (bw_enabled) + return chan_state; + else + return CHANNEL_STATE_DISABLE; +} + +enum channel_state +reg_get_2g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t oper_ch_freq, + qdf_freq_t sec_ch_freq, + enum phy_ch_width bw) +{ + enum channel_enum chan_idx; + enum channel_state chan_state; + struct regulatory_channel *reg_channels; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + bool bw_enabled = false; + enum channel_state chan_state2 = CHANNEL_STATE_INVALID; + + if (bw > CH_WIDTH_40MHZ) + return CHANNEL_STATE_INVALID; + + if (bw == CH_WIDTH_40MHZ) { + if ((sec_ch_freq + 20 != oper_ch_freq) && + (oper_ch_freq + 20 != sec_ch_freq)) + return CHANNEL_STATE_INVALID; + chan_state2 = reg_get_channel_state_for_freq(pdev, sec_ch_freq); + if (chan_state2 == CHANNEL_STATE_INVALID) + return chan_state2; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return CHANNEL_STATE_INVALID; + } + + reg_channels = pdev_priv_obj->cur_chan_list; + + chan_state = reg_get_channel_state_for_freq(pdev, oper_ch_freq); + if (chan_state2 < chan_state) + chan_state = chan_state2; + + if ((chan_state == CHANNEL_STATE_INVALID) || + (chan_state == CHANNEL_STATE_DISABLE)) + return chan_state; + + chan_idx = reg_get_chan_enum_for_freq(oper_ch_freq); + if (chan_idx == INVALID_CHANNEL) + return CHANNEL_STATE_INVALID; + if (bw == CH_WIDTH_5MHZ) + bw_enabled = true; + else if (bw == CH_WIDTH_10MHZ) + bw_enabled = (reg_channels[chan_idx].min_bw <= 10) && + (reg_channels[chan_idx].max_bw >= 10); + else if (bw == CH_WIDTH_20MHZ) + bw_enabled = (reg_channels[chan_idx].min_bw <= 20) && + (reg_channels[chan_idx].max_bw >= 20); + else if (bw == CH_WIDTH_40MHZ) + bw_enabled = (reg_channels[chan_idx].min_bw <= 40) && + (reg_channels[chan_idx].max_bw >= 40); + + if (bw_enabled) + return chan_state; + else + return CHANNEL_STATE_DISABLE; + + return CHANNEL_STATE_ENABLE; +} + +/** + * reg_set_5g_channel_params_for_freq()- Set channel parameters like center + * frequency for a bonded channel state. Also return the maximum bandwidth + * supported by the channel. + * @pdev: Pointer to pdev. + * @freq: Channel center frequency. + * ch_params: Pointer to ch_params. + * + * Return: void + */ +static void reg_set_5g_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + struct ch_params *ch_params) +{ + /* + * Set channel parameters like center frequency for a bonded channel + * state. Also return the maximum bandwidth supported by the channel. + */ + + enum channel_state chan_state = CHANNEL_STATE_ENABLE; + enum channel_state chan_state2 = CHANNEL_STATE_ENABLE; + const struct bonded_channel_freq *bonded_chan_ptr = NULL; + const struct bonded_channel_freq *bonded_chan_ptr2 = NULL; + + if (!ch_params) { + reg_err("ch_params is NULL"); + return; + } + + if (ch_params->ch_width >= CH_WIDTH_MAX) { + if (ch_params->mhz_freq_seg1 != 0) + ch_params->ch_width = CH_WIDTH_80P80MHZ; + else + ch_params->ch_width = CH_WIDTH_160MHZ; + } + + while (ch_params->ch_width != CH_WIDTH_INVALID) { + bonded_chan_ptr = NULL; + bonded_chan_ptr2 = NULL; + chan_state = reg_get_5g_bonded_channel_for_freq( + pdev, freq, ch_params->ch_width, + &bonded_chan_ptr); + + chan_state = reg_get_5g_bonded_channel_state_for_freq( + pdev, freq, ch_params->ch_width); + + if (ch_params->ch_width == CH_WIDTH_80P80MHZ) { + chan_state2 = reg_get_5g_bonded_channel_state_for_freq( + pdev, ch_params->mhz_freq_seg1 - + NEAREST_20MHZ_CHAN_FREQ_OFFSET, + CH_WIDTH_80MHZ); + + chan_state = reg_combine_channel_states( + chan_state, chan_state2); + } + + if ((chan_state != CHANNEL_STATE_ENABLE) && + (chan_state != CHANNEL_STATE_DFS)) + goto update_bw; + if (ch_params->ch_width <= CH_WIDTH_20MHZ) { + ch_params->sec_ch_offset = NO_SEC_CH; + ch_params->mhz_freq_seg0 = freq; + if (reg_is_6ghz_chan_freq(ch_params->mhz_freq_seg0)) + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + SIXG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + else + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + FIVEG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + break; + } else if (ch_params->ch_width >= CH_WIDTH_40MHZ) { + reg_get_5g_bonded_chan_array_for_freq( + pdev, freq, bonded_chan_40mhz_list_freq, + QDF_ARRAY_SIZE(bonded_chan_40mhz_list_freq), + &bonded_chan_ptr2); + if (!bonded_chan_ptr || !bonded_chan_ptr2) + goto update_bw; + if (freq == bonded_chan_ptr2->start_freq) + ch_params->sec_ch_offset = LOW_PRIMARY_CH; + else + ch_params->sec_ch_offset = HIGH_PRIMARY_CH; + + ch_params->mhz_freq_seg0 = + (bonded_chan_ptr->start_freq + + bonded_chan_ptr->end_freq) / 2; + if (reg_is_6ghz_chan_freq(ch_params->mhz_freq_seg0)) + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + SIXG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + else + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + FIVEG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + break; + } +update_bw: + ch_params->ch_width = get_next_lower_bw[ch_params->ch_width]; + } + + if (ch_params->ch_width == CH_WIDTH_160MHZ) { + ch_params->mhz_freq_seg1 = ch_params->mhz_freq_seg0; + if (reg_is_6ghz_chan_freq(ch_params->mhz_freq_seg1)) + ch_params->center_freq_seg1 = + (ch_params->mhz_freq_seg1 - SIXG_STARTING_FREQ) / + FREQ_TO_CHAN_SCALE; + else + ch_params->center_freq_seg1 = + (ch_params->mhz_freq_seg1 - FIVEG_STARTING_FREQ) / + FREQ_TO_CHAN_SCALE; + chan_state = reg_get_5g_bonded_channel_for_freq( + pdev, freq, CH_WIDTH_80MHZ, &bonded_chan_ptr); + if (bonded_chan_ptr) { + ch_params->mhz_freq_seg0 = + (bonded_chan_ptr->start_freq + + bonded_chan_ptr->end_freq) / 2; + if (reg_is_6ghz_chan_freq(ch_params->mhz_freq_seg0)) + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + SIXG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + else + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + FIVEG_STARTING_FREQ) / FREQ_TO_CHAN_SCALE; + } + } + /* Overwrite mhz_freq_seg1 to 0 for non 160 and 80+80 width */ + if (!(ch_params->ch_width == CH_WIDTH_160MHZ || + ch_params->ch_width == CH_WIDTH_80P80MHZ)) { + ch_params->mhz_freq_seg1 = 0; + ch_params->center_freq_seg1 = 0; + } } -bool reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev) +/** + * reg_set_2g_channel_params_for_freq() - set the 2.4G bonded channel parameters + * @oper_freq: operating channel + * @ch_params: channel parameters + * @sec_ch_2g_freq: 2.4G secondary channel + * + * Return: void + */ +static void reg_set_2g_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t oper_freq, + struct ch_params *ch_params, + uint16_t sec_ch_2g_freq) { - struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + enum channel_state chan_state = CHANNEL_STATE_ENABLE; + + if (ch_params->ch_width >= CH_WIDTH_MAX) + ch_params->ch_width = CH_WIDTH_40MHZ; + if ((reg_get_bw_value(ch_params->ch_width) > 20) && !sec_ch_2g_freq) { + if (oper_freq >= TWOG_CHAN_1_IN_MHZ && oper_freq <= + TWOG_CHAN_5_IN_MHZ) + sec_ch_2g_freq = oper_freq + 20; + else if (oper_freq >= TWOG_CHAN_6_IN_MHZ && oper_freq <= + TWOG_CHAN_13_IN_MHZ) + sec_ch_2g_freq = oper_freq - 20; + } + + while (ch_params->ch_width != CH_WIDTH_INVALID) { + chan_state = + reg_get_2g_bonded_channel_state_for_freq(pdev, oper_freq, + sec_ch_2g_freq, + ch_params->ch_width); + if ((chan_state == CHANNEL_STATE_ENABLE) || + (chan_state == CHANNEL_STATE_DFS)) { + if (ch_params->ch_width == CH_WIDTH_40MHZ) { + if (oper_freq < sec_ch_2g_freq) + ch_params->sec_ch_offset = + LOW_PRIMARY_CH; + else + ch_params->sec_ch_offset = + HIGH_PRIMARY_CH; + ch_params->mhz_freq_seg0 = + (oper_freq + sec_ch_2g_freq) / 2; + if (ch_params->mhz_freq_seg0 == + TWOG_CHAN_14_IN_MHZ) + ch_params->center_freq_seg0 = 14; + else + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + TWOG_STARTING_FREQ) / + FREQ_TO_CHAN_SCALE; + } else { + ch_params->sec_ch_offset = NO_SEC_CH; + ch_params->mhz_freq_seg0 = oper_freq; + if (ch_params->mhz_freq_seg0 == + TWOG_CHAN_14_IN_MHZ) + ch_params->center_freq_seg0 = 14; + else + ch_params->center_freq_seg0 = + (ch_params->mhz_freq_seg0 - + TWOG_STARTING_FREQ) / + FREQ_TO_CHAN_SCALE; + } + break; + } + + ch_params->ch_width = get_next_lower_bw[ch_params->ch_width]; + } + /* Overwrite mhz_freq_seg1 and center_freq_seg1 to 0 for 2.4 Ghz */ + ch_params->mhz_freq_seg1 = 0; + ch_params->center_freq_seg1 = 0; +} + +void reg_set_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_2g_freq, + struct ch_params *ch_params) +{ + if (reg_is_5ghz_ch_freq(freq) || reg_is_6ghz_chan_freq(freq)) + reg_set_5g_channel_params_for_freq(pdev, freq, ch_params); + else if (reg_is_24ghz_ch_freq(freq)) + reg_set_2g_channel_params_for_freq(pdev, freq, ch_params, + sec_ch_2g_freq); +} + +uint8_t reg_get_channel_reg_power_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_enum chan_enum; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *reg_channels; + + chan_enum = reg_get_chan_enum_for_freq(freq); + + if (chan_enum == INVALID_CHANNEL) { + reg_err("channel is invalid"); + return REG_INVALID_TXPOWER; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return REG_INVALID_TXPOWER; + } + + reg_channels = pdev_priv_obj->cur_chan_list; + + return reg_channels[chan_enum].tx_power; +} + +bool reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + uint32_t chan_flags; + + chan_flags = reg_get_channel_flags_for_freq(pdev, freq); + + return chan_flags & REGULATORY_CHAN_RADAR; +} + +#ifdef CONFIG_REG_CLIENT +/** + * reg_get_psoc_mas_chan_list () - Get psoc master channel list + * @pdev: pointer to pdev object + * @psoc: pointer to psoc object + * + * Return: psoc master chanel list + */ +static struct regulatory_channel *reg_get_psoc_mas_chan_list( + struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + uint8_t pdev_id; + + soc_reg = reg_get_psoc_obj(psoc); + if (!soc_reg) { + reg_err("reg psoc private obj is NULL"); + return NULL; + } + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + + return soc_reg->mas_chan_params[pdev_id].mas_chan_list; +} +#else +static inline struct regulatory_channel *reg_get_psoc_mas_chan_list( + struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_psoc *psoc) +{ + return NULL; +} +#endif + +void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq_list, + uint8_t num_chan, + bool nol_chan) +{ + enum channel_enum chan_enum; + struct regulatory_channel *mas_chan_list, *psoc_mas_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; struct wlan_objmgr_psoc *psoc; + uint16_t i; + + if (!num_chan || !chan_freq_list) { + reg_err("chan_freq_list or num_ch is NULL"); + return; + } psoc = wlan_pdev_get_psoc(pdev); - if (!psoc) { - reg_err_rl("psoc is NULL"); + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!pdev_priv_obj) { + reg_err("reg pdev private obj is NULL"); + return; + } + + psoc_mas_chan_list = reg_get_psoc_mas_chan_list(pdev, psoc); + + mas_chan_list = pdev_priv_obj->mas_chan_list; + for (i = 0; i < num_chan; i++) { + chan_enum = reg_get_chan_enum_for_freq(chan_freq_list[i]); + if (chan_enum == INVALID_CHANNEL) { + reg_err("Invalid freq in nol list, freq %d", + chan_freq_list[i]); + continue; + } + mas_chan_list[chan_enum].nol_chan = nol_chan; + if (psoc_mas_chan_list) + psoc_mas_chan_list[chan_enum].nol_chan = nol_chan; + } + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_send_scheduler_msg_sb(psoc, pdev); +} + +void reg_update_nol_history_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_list, + uint8_t num_chan, + bool nol_history_chan) +{ + enum channel_enum chan_enum; + struct regulatory_channel *mas_chan_list; + struct regulatory_channel *cur_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + uint16_t i; + + if (!num_chan || !chan_list) { + reg_err("chan_list or num_ch is NULL"); + return; + } + + pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj( + pdev, WLAN_UMAC_COMP_REGULATORY); + + if (!pdev_priv_obj) { + reg_err("reg psoc private obj is NULL"); + return; + } + + mas_chan_list = pdev_priv_obj->mas_chan_list; + cur_chan_list = pdev_priv_obj->cur_chan_list; + + for (i = 0; i < num_chan; i++) { + chan_enum = reg_get_chan_enum_for_freq(chan_list[i]); + if (chan_enum == INVALID_CHANNEL) { + reg_err("Invalid ch in nol list, chan %d", + chan_list[i]); + continue; + } + mas_chan_list[chan_enum].nol_history = nol_history_chan; + cur_chan_list[chan_enum].nol_history = nol_history_chan; + } +} + +static inline bool REG_IS_FREQUENCY_VALID_5G_SBS(qdf_freq_t curfreq, + qdf_freq_t newfreq) +{ + return ((curfreq) > (newfreq) ? + REG_CH_TO_FREQ(reg_get_chan_enum_for_freq(curfreq)) + - REG_CH_TO_FREQ(reg_get_chan_enum_for_freq(newfreq)) + > REG_SBS_SEPARATION_THRESHOLD : + REG_CH_TO_FREQ(reg_get_chan_enum_for_freq(newfreq)) + - REG_CH_TO_FREQ(reg_get_chan_enum_for_freq(curfreq)) + > REG_SBS_SEPARATION_THRESHOLD); +} + +bool reg_is_frequency_valid_5g_sbs(qdf_freq_t curfreq, qdf_freq_t newfreq) +{ + return REG_IS_FREQUENCY_VALID_5G_SBS(curfreq, newfreq); +} + +qdf_freq_t reg_min_chan_freq(void) +{ + return channel_map[MIN_24GHZ_CHANNEL].center_freq; +} + +qdf_freq_t reg_max_chan_freq(void) +{ + return channel_map[NUM_CHANNELS - 1].center_freq; +} + +bool reg_is_same_band_freqs(qdf_freq_t freq1, qdf_freq_t freq2) +{ + return (freq1 && freq2 && ((REG_IS_6GHZ_FREQ(freq1) && + REG_IS_6GHZ_FREQ(freq2)) || + (REG_IS_5GHZ_FREQ(freq1) && + REG_IS_5GHZ_FREQ(freq2)) || + (REG_IS_24GHZ_CH_FREQ(freq1) && + REG_IS_24GHZ_CH_FREQ(freq2)))); +} + +enum reg_wifi_band reg_freq_to_band(qdf_freq_t freq) +{ + if (REG_IS_24GHZ_CH_FREQ(freq)) + return REG_BAND_2G; + else if (REG_IS_5GHZ_FREQ(freq) || REG_IS_49GHZ_FREQ(freq)) + return REG_BAND_5G; + else if (REG_IS_6GHZ_FREQ(freq)) + return REG_BAND_6G; + return REG_BAND_UNKNOWN; +} + +#endif /* CONFIG_CHAN_FREQ_API */ + +uint8_t reg_get_max_tx_power(struct wlan_objmgr_pdev *pdev) +{ + struct regulatory_channel *cur_chan_list; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + uint8_t i, max_tx_power = 0; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev private obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + for (i = 0; i < NUM_CHANNELS; i++) { + if (cur_chan_list[i].state != CHANNEL_STATE_DISABLE && + cur_chan_list[i].chan_flags != REGULATORY_CHAN_DISABLED) { + if (cur_chan_list[i].tx_power > max_tx_power) + max_tx_power = cur_chan_list[i].tx_power; + } + } + + if (!max_tx_power) + reg_err_rl("max_tx_power is zero"); + + return max_tx_power; +} + +QDF_STATUS reg_set_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_reg; + + psoc_reg = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc_reg->ignore_fw_reg_offload_ind = true; + return QDF_STATUS_SUCCESS; +} + +bool reg_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_reg; + + psoc_reg = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) return false; + + return psoc_reg->ignore_fw_reg_offload_ind; +} + +QDF_STATUS reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc, bool val) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + + psoc_priv_obj = reg_get_psoc_obj(psoc); + + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_FAILURE; } + psoc_priv_obj->six_ghz_supported = val; + + return QDF_STATUS_SUCCESS; +} + +bool reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, uint8_t op_class) +{ + return ((op_class >= MIN_6GHZ_OPER_CLASS) && + (op_class <= MAX_6GHZ_OPER_CLASS)); +} + +bool reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + psoc_priv_obj = reg_get_psoc_obj(psoc); if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { @@ -2184,3 +3676,47 @@ bool reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev) return psoc_priv_obj->six_ghz_supported; } + +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS +reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("pdev reg component is NULL"); + return QDF_STATUS_E_FAILURE; + } + *bitmap = pdev_priv_obj->unii_5g_bitmap; + + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef CONFIG_REG_CLIENT +enum band_info reg_band_bitmap_to_band_info(uint32_t band_bitmap) +{ + if ((band_bitmap & BIT(REG_BAND_2G)) && + (band_bitmap & BIT(REG_BAND_5G)) && + (band_bitmap & BIT(REG_BAND_6G))) + return BAND_ALL; + else if ((band_bitmap & BIT(REG_BAND_5G)) && + (band_bitmap & BIT(REG_BAND_6G))) + return BAND_5G; + else if ((band_bitmap & BIT(REG_BAND_2G)) && + (band_bitmap & BIT(REG_BAND_6G))) + return BAND_2G; + else if ((band_bitmap & BIT(REG_BAND_2G)) && + (band_bitmap & BIT(REG_BAND_5G))) + return BAND_ALL; + else if (band_bitmap & BIT(REG_BAND_2G)) + return BAND_2G; + else if (band_bitmap & BIT(REG_BAND_5G)) + return BAND_5G; + else if (band_bitmap & BIT(REG_BAND_6G)) + return BAND_2G; + else + return BAND_UNKNOWN; +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.h index 47b581132e4848a4dd573d42c1f6c2c5e52acac7..d18e01827905df5265e992b8d42bf93fa0e53f50 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_services_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -28,7 +28,13 @@ #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) +#define FREQ_TO_CHAN_SCALE 5 +/* The distance between the 80Mhz center and the nearest 20Mhz channel */ +#define NEAREST_20MHZ_CHAN_FREQ_OFFSET 10 +#define NUM_20_MHZ_CHAN_IN_80_MHZ_CHAN 4 +#define NUM_20_MHZ_CHAN_IN_160_MHZ_CHAN 8 +#ifdef CONFIG_CHAN_NUM_API #define REG_MIN_24GHZ_CH_NUM channel_map[MIN_24GHZ_CHANNEL].chan_num #define REG_MAX_24GHZ_CH_NUM channel_map[MAX_24GHZ_CHANNEL].chan_num #define REG_MIN_5GHZ_CH_NUM channel_map[MIN_5GHZ_CHANNEL].chan_num @@ -37,6 +43,7 @@ #define REG_IS_24GHZ_CH(chan_num) \ (((chan_num) >= REG_MIN_24GHZ_CH_NUM) && \ ((chan_num) <= REG_MAX_24GHZ_CH_NUM)) +#endif /* CONFIG_CHAN_NUM_API */ #define REG_MIN_24GHZ_CH_FREQ channel_map[MIN_24GHZ_CHANNEL].center_freq #define REG_MAX_24GHZ_CH_FREQ channel_map[MAX_24GHZ_CHANNEL].center_freq @@ -45,23 +52,46 @@ (((freq) >= REG_MIN_24GHZ_CH_FREQ) && \ ((freq) <= REG_MAX_24GHZ_CH_FREQ)) -#ifndef CONFIG_LEGACY_CHAN_ENUM +#ifdef CONFIG_CHAN_FREQ_API +#define REG_MIN_5GHZ_CH_FREQ channel_map[MIN_5GHZ_CHANNEL].center_freq +#define REG_MAX_5GHZ_CH_FREQ channel_map[MAX_5GHZ_CHANNEL].center_freq +#endif /* CONFIG_CHAN_FREQ_API */ + #define REG_MIN_49GHZ_CH_FREQ channel_map[MIN_49GHZ_CHANNEL].center_freq #define REG_MAX_49GHZ_CH_FREQ channel_map[MAX_49GHZ_CHANNEL].center_freq #define REG_IS_49GHZ_FREQ(freq) \ (((freq) >= REG_MIN_49GHZ_CH_FREQ) && \ ((freq) <= REG_MAX_49GHZ_CH_FREQ)) -#endif +#ifdef CONFIG_CHAN_NUM_API #define REG_IS_5GHZ_CH(chan_num) \ (((chan_num) >= REG_MIN_5GHZ_CH_NUM) && \ ((chan_num) <= REG_MAX_5GHZ_CH_NUM)) +#endif /* CONFIG_CHAN_NUM_API */ #define REG_IS_5GHZ_FREQ(freq) \ (((freq) >= channel_map[MIN_5GHZ_CHANNEL].center_freq) && \ ((freq) <= channel_map[MAX_5GHZ_CHANNEL].center_freq)) +#ifdef CONFIG_BAND_6GHZ +#define FREQ_LEFT_SHIFT 55 +#define SIXG_STARTING_FREQ 5940 +#define NUM_80MHZ_BAND_IN_6G 16 +#define NUM_PSC_FREQ 15 +#define PSC_BAND_MHZ (FREQ_TO_CHAN_SCALE * NUM_80MHZ_BAND_IN_6G) +#define REG_MIN_6GHZ_CHAN_FREQ channel_map[MIN_6GHZ_CHANNEL].center_freq +#define REG_MAX_6GHZ_CHAN_FREQ channel_map[MAX_6GHZ_CHANNEL].center_freq +#else +#define FREQ_LEFT_SHIFT 0 +#define SIXG_STARTING_FREQ 0 +#define NUM_80MHZ_BAND_IN_6G 0 +#define NUM_PSC_FREQ 0 +#define PSC_BAND_MHZ (FREQ_TO_CHAN_SCALE * NUM_80MHZ_BAND_IN_6G) +#define REG_MIN_6GHZ_CHAN_FREQ 0 +#define REG_MAX_6GHZ_CHAN_FREQ 0 +#endif /*CONFIG_BAND_6GHZ*/ + #define REG_CH_NUM(ch_enum) channel_map[ch_enum].chan_num #define REG_CH_TO_FREQ(ch_enum) channel_map[ch_enum].center_freq @@ -71,14 +101,20 @@ #define MAX_6GHZ_OPER_CLASS 135 extern const struct chan_map *channel_map; +extern const struct chan_map channel_map_us[]; +extern const struct chan_map channel_map_eu[]; +extern const struct chan_map channel_map_jp[]; +extern const struct chan_map channel_map_china[]; +extern const struct chan_map channel_map_global[]; +#ifdef CONFIG_CHAN_NUM_API /** * reg_get_chan_enum() - Get channel enum for given channel number * @chan_num: Channel number * * Return: Channel enum */ -enum channel_enum reg_get_chan_enum(uint32_t chan_num); +enum channel_enum reg_get_chan_enum(uint8_t chan_num); /** * reg_get_channel_list_with_power() - Provides the channel list with power @@ -100,7 +136,21 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, * Return: channel state */ enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev, - uint32_t ch); + uint8_t ch); + +/** + * reg_get_5g_bonded_channel() - get the 5G bonded channel state + * @pdev: Pointer to pdev structure + * @chan_num: channel number + * @ch_width: channel width + * @bonded_chan_ptr_ptr: bonded channel ptr ptr + * + * Return: channel state + */ +enum channel_state reg_get_5g_bonded_channel( + struct wlan_objmgr_pdev *pdev, uint8_t chan_num, + enum phy_ch_width ch_width, + const struct bonded_channel **bonded_chan_ptr_ptr); /** * reg_get_5g_bonded_channel_state() - Get channel state for 5G bonded channel @@ -140,6 +190,7 @@ enum channel_state reg_get_2g_bonded_channel_state( void reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, uint8_t sec_ch_2g, struct ch_params *ch_params); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_read_default_country() - Get the default regulatory country @@ -161,6 +212,7 @@ QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc, void reg_get_current_dfs_region(struct wlan_objmgr_pdev *pdev, enum dfs_reg *dfs_reg); +#ifdef CONFIG_CHAN_NUM_API /** * reg_get_channel_reg_power() - Get the txpower for the given channel * @pdev: Pointer to pdev @@ -169,7 +221,7 @@ void reg_get_current_dfs_region(struct wlan_objmgr_pdev *pdev, * Return: txpower */ uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num); + uint8_t chan_num); /** * reg_get_channel_freq() - Get the channel frequency @@ -178,8 +230,9 @@ uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, * * Return: frequency */ -uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num); +qdf_freq_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_get_bw_value() - give bandwidth value @@ -199,13 +252,15 @@ uint16_t reg_get_bw_value(enum phy_ch_width bw); void reg_set_dfs_region(struct wlan_objmgr_pdev *pdev, enum dfs_reg dfs_reg); +#ifdef CONFIG_CHAN_NUM_API /** * reg_chan_to_band() - Get band from channel number * @chan_num: channel number * * Return: band info */ -enum band_info reg_chan_to_band(uint32_t chan_num); +enum band_info reg_chan_to_band(uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_program_chan_list() - Set user country code and populate the channel list @@ -217,6 +272,7 @@ enum band_info reg_chan_to_band(uint32_t chan_num); QDF_STATUS reg_program_chan_list(struct wlan_objmgr_pdev *pdev, struct cc_regdmn_s *rd); +#ifdef CONFIG_CHAN_NUM_API /** * reg_update_nol_ch () - Updates NOL channels in current channel list * @pdev: pointer to pdev object @@ -236,25 +292,27 @@ void reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *chan_list, * * Return: true or false */ -bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); +bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_freq_to_chan() - Get channel number from frequency. * @pdev: Pointer to pdev * @freq: Channel frequency * - * Return: Channel number + * Return: Channel number if success, otherwise 0 */ -uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, uint32_t freq); +uint8_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); +#ifdef CONFIG_CHAN_NUM_API /** * reg_chan_to_freq() - Get frequency from channel number * @pdev: Pointer to pdev * @chan_num: Channel number * - * Return: Channel frequency + * Return: Channel frequency if success, otherwise 0 */ -uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint32_t chan_num); +qdf_freq_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); /** * reg_legacy_chan_to_freq() - Get freq from chan noumber, for 2G and 5G @@ -274,6 +332,7 @@ uint16_t reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, * Return: true if the channel is 4.9GHz else false. */ bool reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_program_default_cc() - Program default country code @@ -295,16 +354,6 @@ QDF_STATUS reg_program_default_cc(struct wlan_objmgr_pdev *pdev, QDF_STATUS reg_get_current_cc(struct wlan_objmgr_pdev *pdev, struct cc_regdmn_s *rd); -/** - * reg_get_curr_band() - Get current band - * @pdev: Pdev pointer - * @band: Pointer to save the current band - * - * Return: QDF_STATUS - */ -QDF_STATUS reg_get_curr_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band); - /** * reg_set_regdb_offloaded() - set/clear regulatory offloaded flag * @@ -374,8 +423,8 @@ QDF_STATUS reg_set_hal_reg_cap( * Return: true if ch_enum is with in pdev's channel range, else false. */ bool reg_chan_in_range(struct regulatory_channel *chan_list, - uint32_t low_freq_2g, uint32_t high_freq_2g, - uint32_t low_freq_5g, uint32_t high_freq_5g, + qdf_freq_t low_freq_2g, qdf_freq_t high_freq_2g, + qdf_freq_t low_freq_5g, qdf_freq_t high_freq_5g, enum channel_enum ch_enum); /** @@ -391,6 +440,7 @@ void reg_init_channel_map(enum dfs_reg dfs_region); struct wlan_lmac_if_reg_tx_ops *reg_get_psoc_tx_ops( struct wlan_objmgr_psoc *psoc); +#ifdef CONFIG_CHAN_NUM_API /** * reg_update_nol_history_ch() - Set nol-history flag for the channels in the * list. @@ -421,6 +471,7 @@ bool reg_is_24ghz_ch(uint32_t chan); * Return: true if channel number is 5GHz, else false */ bool reg_is_5ghz_ch(uint32_t chan); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_is_24ghz_ch_freq() - Check if the given channel frequency is 2.4GHz @@ -436,17 +487,126 @@ bool reg_is_24ghz_ch_freq(uint32_t freq); * * Return: true if channel frequency is 5GHz, else false */ -bool reg_is_5ghz_ch_freq(uint32_t chan); +bool reg_is_5ghz_ch_freq(uint32_t freq); + +/** + * reg_is_freq_indoor() - Check if the input frequency is an indoor frequency. + * @pdev: Pointer to pdev. + * @freq: Channel frequency. + * + * Return: Return true if the input frequency is indoor, else false. + */ +bool reg_is_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +#ifdef CONFIG_BAND_6GHZ +/** + * reg_is_6ghz_chan_freq() - Check if the given channel frequency is 6GHz + * @freq: Channel frequency + * + * Return: true if channel frequency is 6GHz, else false + */ +bool reg_is_6ghz_chan_freq(uint16_t freq); + +/** + * REG_IS_6GHZ_FREQ() - Check if the given channel frequency is 6GHz + * @freq: Channel frequency + * + * Return: true if channel frequency is 6GHz, else false + */ +static inline bool REG_IS_6GHZ_FREQ(uint16_t freq) +{ + return ((freq >= REG_MIN_6GHZ_CHAN_FREQ) && + (freq <= REG_MAX_6GHZ_CHAN_FREQ)); +} + +/** + * reg_is_6ghz_psc_chan_freq() - Check if the given 6GHz channel frequency is + * preferred scanning channel frequency. + * @freq: Channel frequency + * + * Return: true if given 6GHz channel frequency is preferred scanning channel + * frequency, else false + */ +bool reg_is_6ghz_psc_chan_freq(uint16_t freq); + +/** + * reg_min_6ghz_chan_freq() - Get minimum 6GHz channel center frequency + * + * Return: Minimum 6GHz channel center frequency + */ +uint16_t reg_min_6ghz_chan_freq(void); + +/** + * reg_max_6ghz_chan_freq() - Get maximum 6GHz channel center frequency + * + * Return: Maximum 6GHz channel center frequency + */ +uint16_t reg_max_6ghz_chan_freq(void); +#else +static inline bool reg_is_6ghz_chan_freq(uint16_t freq) +{ + return false; +} + +static inline bool REG_IS_6GHZ_FREQ(uint16_t freq) +{ + return false; +} + +static inline bool reg_is_6ghz_psc_chan_freq(uint16_t freq) +{ + return false; +} + +static inline uint16_t reg_min_6ghz_chan_freq(void) +{ + return 0; +} + +static inline uint16_t reg_max_6ghz_chan_freq(void) +{ + return 0; +} +#endif /* CONFIG_BAND_6GHZ */ + +/** + * reg_get_band_channel_list() - Get the channel list and number of channels + * @pdev: pdev ptr + * @band_mask: Input bitmap with band set + * @channel_list: Pointer to Channel List + * + * Get the given channel list and number of channels from the current channel + * list based on input band bitmap. + * + * Return: Number of channels, else 0 to indicate error + */ +uint16_t reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list); + +/** + * reg_chan_band_to_freq - Return channel frequency based on the channel number + * and band. + * @pdev: pdev ptr + * @chan: Channel Number + * @band_mask: Bitmap for bands + * + * Return: Return channel frequency or return 0, if the channel is disabled or + * if the input channel number or band_mask is invalid. Composite bands are + * supported only for 2.4Ghz and 5Ghz bands. For other bands the following + * priority is given: 1) 6Ghz 2) 5Ghz 3) 2.4Ghz. + */ +qdf_freq_t reg_chan_band_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan, + uint8_t band_mask); -#ifndef CONFIG_LEGACY_CHAN_ENUM /** * reg_is_49ghz_freq() - Check if the given channel frequency is 4.9GHz * @freq: Channel frequency * * Return: true if channel frequency is 4.9GHz, else false */ -bool reg_is_49ghz_freq(uint32_t freq); -#endif +bool reg_is_49ghz_freq(qdf_freq_t freq); /** * reg_ch_num() - Get channel number from channel enum @@ -454,7 +614,7 @@ bool reg_is_49ghz_freq(uint32_t freq); * * Return: channel number */ -uint32_t reg_ch_num(uint32_t ch_enum); +qdf_freq_t reg_ch_num(uint32_t ch_enum); /** * reg_ch_to_freq() - Get channel frequency from channel enum @@ -462,8 +622,9 @@ uint32_t reg_ch_num(uint32_t ch_enum); * * Return: channel frequency */ -uint32_t reg_ch_to_freq(uint32_t ch_enum); +qdf_freq_t reg_ch_to_freq(uint32_t ch_enum); +#ifdef CONFIG_CHAN_NUM_API /** * reg_is_same_band_channels() - Check if given channel numbers have same band * @chan_num1: Channel number1 @@ -471,7 +632,7 @@ uint32_t reg_ch_to_freq(uint32_t ch_enum); * * Return: true if both the channels has the same band. */ -bool reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2); +bool reg_is_same_band_channels(uint8_t chan_num1, uint8_t chan_num2); /** * reg_is_channel_valid_5g_sbs() Check if the given channel is 5G SBS. @@ -480,35 +641,66 @@ bool reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2); * * Return: true if the given channel is a valid 5G SBS */ -bool reg_is_channel_valid_5g_sbs(uint32_t curchan, uint32_t newchan); +bool reg_is_channel_valid_5g_sbs(uint8_t curchan, uint8_t newchan); /** * reg_min_24ghz_ch_num() - Get minimum 2.4GHz channel number * * Return: Minimum 2.4GHz channel number */ -uint32_t reg_min_24ghz_ch_num(void); +uint8_t reg_min_24ghz_ch_num(void); /** * reg_max_24ghz_ch_num() - Get maximum 2.4GHz channel number * * Return: Maximum 2.4GHz channel number */ -uint32_t reg_max_24ghz_ch_num(void); +uint8_t reg_max_24ghz_ch_num(void); /** * reg_min_5ghz_ch_num() - Get minimum 5GHz channel number * * Return: Minimum 5GHz channel number */ -uint32_t reg_min_5ghz_ch_num(void); +uint8_t reg_min_5ghz_ch_num(void); /** * reg_max_5ghz_ch_num() - Get maximum 5GHz channel number * * Return: Maximum 5GHz channel number */ -uint32_t reg_max_5ghz_ch_num(void); +uint8_t reg_max_5ghz_ch_num(void); +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +/** + * reg_min_24ghz_chan_freq() - Get minimum 2.4GHz channel frequency + * + * Return: Minimum 2.4GHz channel frequency + */ +qdf_freq_t reg_min_24ghz_chan_freq(void); + +/** + * reg_max_24ghz_chan_freq() - Get maximum 2.4GHz channel frequency + * + * Return: Maximum 2.4GHz channel frequency + */ +qdf_freq_t reg_max_24ghz_chan_freq(void); + +/** + * reg_min_5ghz_chan_freq() - Get minimum 5GHz channel frequency + * + * Return: Minimum 5GHz channel frequency + */ +qdf_freq_t reg_min_5ghz_chan_freq(void); + +/** + * reg_max_5ghz_chan_freq() - Get maximum 5GHz channel frequency + * + * Return: Maximum 5GHz channel frequency + */ +qdf_freq_t reg_max_5ghz_chan_freq(void); +#endif /* CONFIG_CHAN_FREQ_API */ /** * reg_enable_dfs_channels() - Enable the use of DFS channels @@ -518,6 +710,256 @@ uint32_t reg_max_5ghz_ch_num(void); */ QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable); +/** + * reg_is_regdmn_en302502_applicable() - Find if ETSI EN302_502 radar pattern + * is applicable in current regulatory domain. + * @pdev: Pdev object pointer. + * + * Return: True if en302_502 is applicable, else false. + */ +bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * reg_modify_pdev_chan_range() - Compute current channel list + * in accordance with the modified reg caps. + * @pdev: The physical dev for which channel list must be built. + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); + +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_disable_chan_coex() - Disable Coexisting channels based on the input + * bitmask. + * @pdev: pointer to wlan_objmgr_pdev. + * unii_5g_bitmap: UNII 5G bitmap. + * + * Return : QDF_STATUS + */ +QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * reg_is_freq_present_in_cur_chan_list() - Check the input frequency + * @pdev: Pointer to pdev + * @freq: Channel center frequency in MHz + * + * Check if the input channel center frequency is present in the current + * channel list + * + * Return: Return true if channel center frequency is present in the current + * channel list, else return false. + */ +bool +reg_is_freq_present_in_cur_chan_list(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * reg_get_chan_enum_for_freq() - Get channel enum for given channel frequency + * @freq: Channel Frequency + * + * Return: Channel enum + */ +enum channel_enum reg_get_chan_enum_for_freq(qdf_freq_t freq); + +/** + * reg_get_channel_list_with_power_for_freq() - Provides the channel list with + * power + * @pdev: Pointer to pdev + * @ch_list: Pointer to the channel list. + * @num_chan: Pointer to save number of channels + * + * Return: QDF_STATUS + */ +QDF_STATUS +reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev *pdev, + struct channel_power *ch_list, + uint8_t *num_chan); + +/** + * reg_get_channel_state_for_freq() - Get channel state from regulatory + * @pdev: Pointer to pdev + * @freq: channel center frequency. + * + * Return: channel state + */ +enum channel_state reg_get_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * reg_get_5g_bonded_channel_state_for_freq() - Get channel state for + * 5G bonded channel using the channel frequency + * @pdev: Pointer to pdev + * @freq: channel center frequency. + * @bw: channel band width + * + * Return: channel state + */ +enum channel_state +reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw); + +/** + * reg_get_2g_bonded_channel_state_for_freq() - Get channel state for 2G + * bonded channel + * @freq: channel center frequency. + * @pdev: Pointer to pdev + * @oper_ch_freq: Primary channel center frequency + * @sec_ch_freq: Secondary channel center frequency + * @bw: channel band width + * + * Return: channel state + */ +enum channel_state +reg_get_2g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t oper_ch_freq, + qdf_freq_t sec_ch_freq, + enum phy_ch_width bw); + +/** + * reg_set_channel_params_for_freq () - Sets channel parameteres for given + * bandwidth + * @pdev: Pointer to pdev + * @freq: Channel center frequency. + * @sec_ch_2g_freq: Secondary 2G channel frequency + * @ch_params: pointer to the channel parameters. + * + * Return: None + */ +void reg_set_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_2g_freq, + struct ch_params *ch_params); + +/** + * reg_get_channel_reg_power_for_freq() - Get the txpower for the given channel + * @pdev: Pointer to pdev + * @freq: Channel frequency + * + * Return: txpower + */ +uint8_t reg_get_channel_reg_power_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * reg_update_nol_ch_for_freq () - Updates NOL channels in current channel list + * @pdev: pointer to pdev object + * @chan_freq_list: pointer to NOL channel list + * @num_ch: No.of channels in list + * @update_nol: set/reset the NOL status + * + * Return: None + */ +void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq_list, + uint8_t num_chan, + bool nol_chan); +/** + * reg_is_dfs_for_freq () - Checks the channel state for DFS + * @pdev: pdev ptr + * @freq: Channel center frequency + * + * Return: true or false + */ +bool reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +/** + * reg_chan_freq_is_49ghz() - Check if the input channel center frequency is + * 4.9GHz + * @pdev: Pdev pointer + * @chan_num: Input channel center frequency + * + * Return: true if the frequency is 4.9GHz else false. + */ +bool reg_chan_freq_is_49ghz(qdf_freq_t freq); + +/** + * reg_update_nol_history_ch_for_freq() - Set nol-history flag for the channels + * in the list. + * @pdev: Pdev ptr. + * @chan_list: Input channel freqeuncy list. + * @num_ch: Number of channels. + * @nol_history_ch: NOL-History flag. + * + * Return: void + */ +void reg_update_nol_history_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_list, + uint8_t num_chan, + bool nol_history_chan); + +/** + * reg_is_same_5g_band_freqs() - Check if given channel center + * frequencies have same band + * @freq1: Channel Center Frequency 1 + * @freq2: Channel Center Frequency 2 + * + * Return: true if both the frequencies has the same band. + */ +bool reg_is_same_band_freqs(qdf_freq_t freq1, qdf_freq_t freq2); + +/** + * reg_is_frequency_valid_5g_sbs() Check if the given frequency is 5G SBS. + * @curfreq: current channel frequency + * @newfreq: new channel center frequency + * + * Return: true if the given center frequency is a valid 5G SBS + */ +bool reg_is_frequency_valid_5g_sbs(qdf_freq_t curfreq, qdf_freq_t newfreq); + +/** + * reg_freq_to_band() - Get band from channel frequency + * @chan_num: channel frequency + * + * Return: wifi band + */ +enum reg_wifi_band reg_freq_to_band(qdf_freq_t freq); + +/** + * reg_min_chan_freq() - minimum channel frequency supported + * + * Return: channel frequency + */ +qdf_freq_t reg_min_chan_freq(void); + +/** + * reg_max_chan_freq() - maximum channel frequency supported + * + * Return: channel frequency + */ +qdf_freq_t reg_max_chan_freq(void); + +/** + * reg_get_5g_bonded_channel_for_freq()- Return the channel state for a + * 5G or 6G channel frequency based on the channel width and bonded channel + * @pdev: Pointer to pdev. + * @freq: Channel center frequency. + * @ch_width: Channel Width. + * @bonded_chan_ptr_ptr: Pointer to bonded_channel_freq. + * + * Return: Channel State + */ +enum channel_state +reg_get_5g_bonded_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + enum phy_ch_width ch_width, + const struct bonded_channel_freq + **bonded_chan_ptr_ptr); +#endif /* CONFIG_CHAN_FREQ_API */ + +/** + * reg_get_max_tx_power() - Get maximum tx power from the current channel list + * @pdev: Pointer to pdev + * + * Return: return the value of the maximum tx power in the current channel list + * + */ +uint8_t reg_get_max_tx_power(struct wlan_objmgr_pdev *pdev); + /** * reg_set_ignore_fw_reg_offload_ind() - Set if regdb offload indication * needs to be ignored @@ -556,8 +998,33 @@ bool reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, /** * reg_is_6ghz_supported() - Whether 6ghz is supported * - * @pdev: pointer to pdev + * @psoc: pointer to psoc + */ +bool reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc); + +/** + * reg_get_unii_5g_bitmap() - get unii_5g_bitmap value + * @pdev: pdev pointer + * @bitmap: Pointer to retrieve the unii_5g_bitmap of enum reg_unii_band + * + * Return: QDF_STATUS */ -bool reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev); +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS +reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap); +#endif +#ifdef CONFIG_REG_CLIENT +/** + * reg_band_bitmap_to_band_info() - Convert the band_bitmap to a band_info enum. + * Since band_info enum only has combinations for 2G and 5G, 6G is not + * considered in this function. + * @band_bitmap: bitmap on top of reg_wifi_band of bands enabled + * + * Return: BAND_ALL if both 2G and 5G band is enabled + * BAND_2G if 2G is enabled but 5G isn't + * BAND_5G if 5G is enabled but 2G isn't + */ +enum band_info reg_band_bitmap_to_band_info(uint32_t band_bitmap); +#endif #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c index ef956a5a64d95c237f7e3ee8449febd6597f7a47..44800675e8a318755516ecadaa3e64505ae05dfc 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.c @@ -42,7 +42,8 @@ #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) -bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch) +#ifdef CONFIG_CHAN_NUM_API +bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch) { enum channel_enum ch_idx; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -65,6 +66,34 @@ bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch) return false; } +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_enum ch_idx; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + + ch_idx = reg_get_chan_enum_for_freq(freq); + + if (ch_idx == INVALID_CHANNEL) + return false; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg obj is NULL"); + return false; + } + + if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags & + REGULATORY_CHAN_RADAR) + return true; + + return false; +} +#endif /* CONFIG_CHAN_FREQ_API */ bool reg_is_world_ctry_code(uint16_t ctry_code) { @@ -276,8 +305,9 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, return QDF_STATUS_SUCCESS; } +#ifdef CONFIG_CHAN_NUM_API bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { enum channel_state ch_state; @@ -286,12 +316,40 @@ bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, return (ch_state == CHANNEL_STATE_DFS) || (ch_state == CHANNEL_STATE_DISABLE); } +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + enum channel_state chan_state; + + chan_state = reg_get_channel_state_for_freq(pdev, freq); + + return (chan_state == CHANNEL_STATE_DFS) || + (chan_state == CHANNEL_STATE_DISABLE); +} +#endif /* CONFIG_CHAN_FREQ_API */ #ifdef WLAN_FEATURE_DSRC -bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_dsrc_freq(qdf_freq_t freq) +{ + if (!REG_IS_5GHZ_FREQ(freq)) + return false; + + if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) + return false; + + return true; +} +#endif /*CONFIG_CHAN_FREQ_API*/ + +#ifdef CONFIG_CHAN_NUM_API +bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) { struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - uint32_t freq = 0; + qdf_freq_t freq = 0; pdev_priv_obj = reg_get_pdev_obj(pdev); @@ -310,6 +368,7 @@ bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) return true; } +#endif /* CONFIG_CHAN_NUM_API */ #else @@ -320,17 +379,33 @@ bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); if (status != QDF_STATUS_SUCCESS) { - reg_err("Failed to get reg domain"); + reg_debug_rl("Failed to get reg domain"); return false; } return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g); } -bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq) +{ + if (!REG_IS_5GHZ_FREQ(freq)) + return false; + + if (!(freq >= REG_ETSI13_SRD_START_FREQ && + freq <= REG_ETSI13_SRD_END_FREQ)) + return false; + + return reg_is_etsi13_regdmn(pdev); +} +#endif /* CONFIG_CHAN_FREQ_API */ + +#ifdef CONFIG_CHAN_NUM_API +bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) { struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - uint32_t freq = 0; + qdf_freq_t freq = 0; pdev_priv_obj = reg_get_pdev_obj(pdev); @@ -350,6 +425,7 @@ bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) return reg_is_etsi13_regdmn(pdev); } +#endif /* CONFIG_CHAN_NUM_API */ bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) { @@ -373,8 +449,7 @@ bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) } #endif -QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, - enum band_info band) +QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap) { struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -388,8 +463,8 @@ QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } - if (pdev_priv_obj->band_capability == band) { - reg_info("same band %d", band); + if (pdev_priv_obj->band_capability == band_bitmap) { + reg_info("same band %d", band_bitmap); return QDF_STATUS_SUCCESS; } @@ -405,8 +480,8 @@ QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } - reg_info("set band_info: %d", band); - pdev_priv_obj->band_capability = band; + reg_info("set band bitmap: %d", band_bitmap); + pdev_priv_obj->band_capability = band_bitmap; reg_compute_pdev_current_chan_list(pdev_priv_obj); @@ -416,11 +491,9 @@ QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, } QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band) + uint32_t *band_bitmap) { - struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - struct wlan_objmgr_psoc *psoc; pdev_priv_obj = reg_get_pdev_obj(pdev); @@ -429,33 +502,73 @@ QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } + reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability); + *band_bitmap = pdev_priv_obj->band_capability; + + return QDF_STATUS_SUCCESS; +} + +#ifdef DISABLE_CHANNEL_LIST +QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + psoc = wlan_pdev_get_psoc(pdev); if (!psoc) { reg_err("psoc is NULL"); return QDF_STATUS_E_INVAL; } - psoc_priv_obj = reg_get_psoc_obj(psoc); - if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { - reg_err("psoc reg component is NULL"); + pdev_priv_obj->disable_cached_channels = false; + reg_compute_pdev_current_chan_list(pdev_priv_obj); + status = reg_send_scheduler_msg_sb(psoc, pdev); + return status; +} + +QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); return QDF_STATUS_E_INVAL; } - reg_debug("get band_info: %d", pdev_priv_obj->band_capability); - *band = pdev_priv_obj->band_capability; + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } - return QDF_STATUS_SUCCESS; + pdev_priv_obj->disable_cached_channels = true; + reg_compute_pdev_current_chan_list(pdev_priv_obj); + status = reg_send_scheduler_msg_sb(psoc, pdev); + return status; } -#ifdef DISABLE_CHANNEL_LIST -QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) { struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; struct wlan_objmgr_psoc *psoc; - QDF_STATUS status; + uint16_t i, j; pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { reg_err("pdev reg component is NULL"); return QDF_STATUS_E_INVAL; @@ -472,13 +585,36 @@ QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) reg_err("psoc reg component is NULL"); return QDF_STATUS_E_INVAL; } + if (pdev_priv_obj->num_cache_channels > 0) { + pdev_priv_obj->num_cache_channels = 0; + qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, + sizeof(pdev_priv_obj->cache_disable_chan_list)); + } - pdev_priv_obj->disable_cached_channels = false; - reg_compute_pdev_current_chan_list(pdev_priv_obj); - status = reg_send_scheduler_msg_sb(psoc, pdev); - return status; + for (i = 0; i < num_channels; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + if (channel_list[i] == pdev_priv_obj-> + cur_chan_list[j].center_freq) { + pdev_priv_obj-> + cache_disable_chan_list[i].center_freq = + channel_list[i]; + pdev_priv_obj-> + cache_disable_chan_list[i].state = + pdev_priv_obj->cur_chan_list[j].state; + pdev_priv_obj-> + cache_disable_chan_list[i].chan_flags = + pdev_priv_obj-> + cur_chan_list[j].chan_flags; + } + } + } + pdev_priv_obj->num_cache_channels = num_channels; + + return QDF_STATUS_SUCCESS; } +#endif /* CONFIG_CHAN_FREQ_API */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t *channel_list, uint32_t num_channels) @@ -533,12 +669,7 @@ QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } - -void set_disable_channel_state( - struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) -{ - pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; -} +#endif /* CONFIG_CHAN_NUM_API */ #endif #ifdef CONFIG_REG_CLIENT @@ -668,6 +799,8 @@ QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, config_vars.enable_srd_chan_in_master_mode; psoc_priv_obj->enable_11d_in_world_mode = config_vars.enable_11d_in_world_mode; + psoc_priv_obj->retain_nol_across_regdmn_update = + config_vars.retain_nol_across_regdmn_update; status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); if (QDF_IS_STATUS_ERROR(status)) { @@ -682,7 +815,19 @@ QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, return status; } -bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + enum channel_state ch_state; + + ch_state = reg_get_channel_state_for_freq(pdev, freq); + + return ch_state == CHANNEL_STATE_DISABLE; +} +#endif /* CONFIG_CHAN_FREQ_API */ + +#ifdef CONFIG_CHAN_NUM_API +bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan) { enum channel_state ch_state; @@ -690,6 +835,7 @@ bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) return ch_state == CHANNEL_STATE_DISABLE; } +#endif /* CONFIG_CHAN_NUM_API */ bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) { diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.h index 1ab8b947103693e4492ae8187c30e64bce15307e..91bd0cbaaab440cb419917a61e68bd25fdabc965 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/core/src/reg_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -33,6 +33,7 @@ #define REG_ETSI13_SRD_START_FREQ 5745 #define REG_ETSI13_SRD_END_FREQ 5865 +#ifdef CONFIG_CHAN_NUM_API #define REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ ((curchan) > (newchan) ? \ REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ @@ -41,6 +42,7 @@ REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \ - REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ > REG_SBS_SEPARATION_THRESHOLD) +#endif /* CONFIG_LEGACY_REG_API */ /** * reg_is_world_ctry_code() - Check if the given country code is WORLD regdomain @@ -50,7 +52,7 @@ */ bool reg_is_world_ctry_code(uint16_t ctry_code); -#ifdef CONFIG_REG_CLIENT +#if defined(CONFIG_REG_CLIENT) && defined(CONFIG_CHAN_NUM_API) /** * reg_chan_has_dfs_attribute() - check channel has dfs attribue or not * @ch: channel number. @@ -59,50 +61,158 @@ bool reg_is_world_ctry_code(uint16_t ctry_code); * * Return: true if chan is dfs, otherwise false */ -bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch); +bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch); /** - * reg_set_band() - Sets the band information for the PDEV - * @pdev: The physical dev to set the band for - * @band: The set band parameters to configure for the physical device + * reg_is_passive_or_disable_ch() - Check if the given channel is passive or + * disabled. + * @pdev: Pointer to physical dev + * @chan: Channel number * - * Return: QDF_STATUS + * Return: true if channel is passive or disabled, else false. */ -QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, enum band_info band); +bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan); /** - * reg_get_band() - Get the band information for the PDEV - * @pdev: The physical dev to get the band for - * @band: The band parameters of the physical device + * reg_is_disable_ch() - Check if the given channel in disable state + * @pdev: Pointer to pdev + * @chan: channel number * - * Return: QDF_STATUS + * Return: True if channel state is disabled, else false + */ +bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan); +#else +static inline bool +reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch) +{ + return false; +} + +static inline bool +reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan) +{ + return false; +} + +static inline bool +reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan) +{ + return false; +} +#endif /* defined(CONFIG_REG_CLIENT) && defined(CONFIG_CHAN_NUM_API) */ + +#if defined(CONFIG_REG_CLIENT) && defined(CONFIG_CHAN_FREQ_API) +/** + * reg_chan_has_dfs_attribute_for_freq() - check channel frequency has dfs + * attribue or not + * @freq: channel frequency. + * + * This API gets initial dfs attribute flag of the channel frequency from + * regdomain + * + * Return: true if channel frequency is dfs, otherwise false + */ +bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); +/** + * reg_is_passive_or_disable_for_freq() - Check if the given channel is + * passive or disabled. + * @pdev: Pointer to physical dev + * @chan: Channel frequency + * + * Return: true if channel frequency is passive or disabled, else false. + */ +bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); +/** + * reg_is_disable_for_freq() - Check if the given channel frequency in + * disable state + * @pdev: Pointer to pdev + * @freq: Channel frequency + * + * Return: True if channel state is disabled, else false */ -QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, enum band_info *band); +bool reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); +#else +static inline bool +reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return false; +} + +static inline bool +reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return false; +} + +static inline bool +reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + return false; +} +#endif /* defined(CONFIG_REG_CLIENT) && defined(CONFIG_CHAN_FREQ_API) */ #ifdef DISABLE_CHANNEL_LIST /** - * reg_restore_cached_channels() - Cache the current state of the channels + * reg_disable_cached_channels() - Disable cached channels + * @pdev: The physical dev to cache the channels for + */ +QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev); +/** + * reg_restore_cached_channels() - Restore disabled cached channels * @pdev: The physical dev to cache the channels for */ QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev); +#else +static inline +QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +static inline +QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* DISABLE_CHANNEL_LIST */ +#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_FREQ_API) /** - * reg_cache_channel_state() - Cache the current state of the channels + * reg_cache_channel_freq_state() - Cache the current state of the channels + * based on the channel center frequency * @pdev: The physical dev to cache the channels for * @channel_list: List of the channels for which states needs to be cached * @num_channels: Number of channels in the list * */ -QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, - uint32_t *channel_list, - uint32_t num_channels); +QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels); #else static inline -QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) { return QDF_STATUS_SUCCESS; } +#endif /* defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_FREQ_API) */ +#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_NUM_API) +/** + * reg_cache_channel_state() - Cache the current state of the channels + * @pdev: The physical dev to cache the channels for + * @channel_list: List of the channels for which states needs to be cached + * @num_channels: Number of channels in the list + * + */ +QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels); +#else static inline QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t *channel_list, @@ -110,7 +220,26 @@ QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, { return QDF_STATUS_SUCCESS; } -#endif +#endif /* defined (DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_NUM_API) */ + +#ifdef CONFIG_REG_CLIENT +/** + * reg_set_band() - Sets the band information for the PDEV + * @pdev: The physical dev to set the band for + * @band_bitmap: The set band parameters to configure for the physical device + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap); + +/** + * reg_get_band() - Get the band information for the PDEV + * @pdev: The physical dev to get the band for + * @band_bitmap: The band parameters of the physical device + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, uint32_t *band_bitmap); /** * reg_set_fcc_constraint() - Apply fcc constraints on channels 12/13 @@ -199,25 +328,6 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, const uint8_t *country_alpha2, enum country_src source); -/** - * reg_is_passive_or_disable_ch() - Check if the given channel is passive or - * disabled. - * @pdev: Pointer to physical dev - * @chan: Channel number - * - * Return: true if channel is passive or disabled, else false. - */ -bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); - -/** - * reg_is_disable_ch() - Check if the given channel in disable state - * @pdev: Pointer to pdev - * @chan: channel number - * - * Return: True if channel state is disabled, else false - */ -bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); - /** * reg_set_config_vars () - set configration variables * @psoc: psoc ptr @@ -308,13 +418,6 @@ bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, struct cur_regulatory_info *regulat_info); #else - -static inline bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, - uint32_t ch) -{ - return false; -} - static inline QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc, uint8_t *country_code) { @@ -349,18 +452,6 @@ static inline QDF_STATUS reg_get_domain_from_country_code( return QDF_STATUS_SUCCESS; } -static inline bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) -{ - return false; -} - -static inline bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) -{ - return false; -} - static inline QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, struct reg_config_vars config_vars) { @@ -427,6 +518,18 @@ bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) #endif #if defined(WLAN_FEATURE_DSRC) && defined(CONFIG_REG_CLIENT) +/** + * reg_is_dsrc_freq () - Checks the channel frequency is DSRC or not + * @freq: Channel center frequency + * @pdev: pdev ptr + * + * Return: true or false + */ +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_dsrc_freq(qdf_freq_t freq); +#endif /* CONFIG_CHAN_FREQ_API*/ + +#ifdef CONFIG_CHAN_NUM_API /** * reg_is_dsrc_chan () - Checks the channel for DSRC or not * @chan: channel @@ -434,10 +537,11 @@ bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) * * Return: true or false */ -bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan); +bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan); +#endif /* CONFIG_CHAN_NUM_API */ static inline bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { return false; } @@ -447,6 +551,20 @@ static inline bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) return false; } +/** + * reg_is_etsi13_srd_chan_for_freq() - Checks the channel for ETSI13 srd ch + * frequency or not + * @freq: Channel center frequency + * @pdev: pdev ptr + * + * Return: true or false + */ +static inline bool +reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, uint16_t freq) +{ + return false; +} + static inline bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) { @@ -454,11 +572,21 @@ reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) } #elif defined(CONFIG_REG_CLIENT) static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) +{ + return false; +} + +static inline bool reg_is_dsrc_freq(qdf_freq_t freq) { return false; } +#ifdef CONFIG_CHAN_FREQ_API +bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev + *pdev, uint16_t freq); +#endif /*CONFIG_CHAN_FREQ_API */ + /** * reg_is_etsi13_regdmn () - Checks if the current reg domain is ETSI13 or not * @pdev: pdev ptr @@ -467,6 +595,7 @@ static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, */ bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev); +#ifdef CONFIG_CHAN_NUM_API /** * reg_is_etsi13_srd_chan () - Checks the channel for ETSI13 srd ch or not * @chan: channel @@ -474,7 +603,8 @@ bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev); * * Return: true or false */ -bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan); +bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan); +#endif /* CONFIG_CHAN_NUM_API */ /** * reg_is_etsi13_srd_chan_allowed_master_mode() - Checks if regdmn is ETSI13 @@ -487,7 +617,19 @@ bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan); bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev); #else static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) +{ + return false; +} + +static inline bool reg_is_dsrc_freq(qdf_freq_t freq) +{ + return false; +} + +static inline +bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq) { return false; } @@ -504,23 +646,10 @@ reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) } static inline bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { return false; } #endif -#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_REG_CLIENT) -/** - * set_disable_channel_state() - Set disable channel state flag - * @pdev_priv_obj: Pointer to pdev object - */ -void set_disable_channel_state( - struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj); -#else -static inline void set_disable_channel_state( - struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) -{ -} -#endif #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index 6dd2eea3ee6db6e997dd1b41096a8b06aaca82ce..2e3f55ee1b592bd5e644a93933b76f45f28f95f2 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,12 +25,19 @@ #define __REG_SERVICES_PUBLIC_STRUCT_H_ #define REG_SBS_SEPARATION_THRESHOLD 100 + +#ifdef CONFIG_BAND_6GHZ +#define REG_MAX_CHANNELS_PER_OPERATING_CLASS 70 +#else #define REG_MAX_CHANNELS_PER_OPERATING_CLASS 25 +#endif + #define REG_MAX_SUPP_OPER_CLASSES 32 #define REG_MAX_CHAN_CHANGE_CBKS 30 +#define REG_INVALID_TXPOWER 255 #define MAX_STA_VDEV_CNT 4 #define INVALID_VDEV_ID 0xFF -#define INVALID_CHANNEL_NUM 0xBAD +#define INVALID_CHANNEL_NUM 0x0 #define CH_AVOID_MAX_RANGE 4 #define REG_ALPHA2_LEN 2 #define MAX_REG_RULES 10 @@ -40,6 +47,7 @@ #define REGULATORY_CHAN_RADAR BIT(3) #define REGULATORY_CHAN_NO_OFDM BIT(6) #define REGULATORY_CHAN_INDOOR_ONLY BIT(9) +#define REGULATORY_CHAN_AFC BIT(13) #define REGULATORY_CHAN_NO_HT40 BIT(4) #define REGULATORY_CHAN_NO_80MHZ BIT(7) @@ -55,6 +63,10 @@ #define REGULATORY_PHYMODE_NO11AC BIT(4) #define REGULATORY_PHYMODE_NO11AX BIT(5) +#define BW_80_MHZ 80 +#define BW_160_MHZ 160 +#define BW_40_MHZ 40 + /** * enum dfs_reg - DFS region * @DFS_UNINIT_REGION: un-initialized region @@ -63,8 +75,12 @@ * @DFS_MKK_REGION: MKK region * @DFS_CN_REGION: China region * @DFS_KR_REGION: Korea region + * @DFS_MKK_REGION: MKKN region + * that supports updated W53 RADAR pattern + * detection. * @DFS_UNDEF_REGION: Undefined region */ + enum dfs_reg { DFS_UNINIT_REGION = 0, DFS_FCC_REGION = 1, @@ -72,6 +88,7 @@ enum dfs_reg { DFS_MKK_REGION = 3, DFS_CN_REGION = 4, DFS_KR_REGION = 5, + DFS_MKKN_REGION = 6, DFS_UNDEF_REGION = 0xFFFF, }; @@ -87,224 +104,7 @@ enum op_class_table_num { OP_CLASS_JAPAN, OP_CLASS_GLOBAL }; -#ifdef CONFIG_LEGACY_CHAN_ENUM -/** - * enum channel_enum - channel enumeration - * @CHAN_ENUM_1: channel number 1 - * @CHAN_ENUM_2: channel number 2 - * @CHAN_ENUM_3: channel number 3 - * @CHAN_ENUM_4: channel number 4 - * @CHAN_ENUM_5: channel number 5 - * @CHAN_ENUM_6: channel number 6 - * @CHAN_ENUM_7: channel number 7 - * @CHAN_ENUM_8: channel number 8 - * @CHAN_ENUM_9: channel number 9 - * @CHAN_ENUM_10: channel number 10 - * @CHAN_ENUM_11: channel number 11 - * @CHAN_ENUM_12: channel number 12 - * @CHAN_ENUM_13: channel number 13 - * @CHAN_ENUM_14: channel number 14 - * @CHAN_ENUM_183: channel number 183 - * @CHAN_ENUM_184: channel number 184 - * @CHAN_ENUM_185: channel number 185 - * @CHAN_ENUM_187: channel number 187 - * @CHAN_ENUM_188: channel number 188 - * @CHAN_ENUM_189: channel number 189 - * @CHAN_ENUM_192: channel number 192 - * @CHAN_ENUM_196: channel number 196 - * @CHAN_ENUM_36: channel number 36 - * @CHAN_ENUM_40: channel number 40 - * @CHAN_ENUM_44: channel number 44 - * @CHAN_ENUM_48: channel number 48 - * @CHAN_ENUM_52: channel number 52 - * @CHAN_ENUM_56: channel number 56 - * @CHAN_ENUM_60: channel number 60 - * @CHAN_ENUM_64: channel number 64 - * @CHAN_ENUM_100: channel number 100 - * @CHAN_ENUM_104: channel number 104 - * @CHAN_ENUM_108: channel number 108 - * @CHAN_ENUM_112: channel number 112 - * @CHAN_ENUM_116: channel number 116 - * @CHAN_ENUM_120: channel number 120 - * @CHAN_ENUM_124: channel number 124 - * @CHAN_ENUM_128: channel number 128 - * @CHAN_ENUM_132: channel number 132 - * @CHAN_ENUM_136: channel number 136 - * @CHAN_ENUM_140: channel number 140 - * @CHAN_ENUM_144: channel number 144 - * @CHAN_ENUM_149: channel number 149 - * @CHAN_ENUM_153: channel number 153 - * @CHAN_ENUM_157: channel number 157 - * @CHAN_ENUM_161: channel number 161 - * @CHAN_ENUM_165: channel number 165 - * @CHAN_ENUM_169: channel number 169 - * @CHAN_ENUM_170: channel number 170 - * @CHAN_ENUM_171: channel number 171 - * @CHAN_ENUM_172: channel number 172 - * @CHAN_ENUM_173: channel number 173 - * @CHAN_ENUM_174: channel number 174 - * @CHAN_ENUM_175: channel number 175 - * @CHAN_ENUM_176: channel number 176 - * @CHAN_ENUM_177: channel number 177 - * @CHAN_ENUM_178: channel number 178 - * @CHAN_ENUM_179: channel number 179 - * @CHAN_ENUM_180: channel number 180 - * @CHAN_ENUM_181: channel number 181 - * @CHAN_ENUM_182: channel number 182 - * @CHAN_ENUM_183: channel number 183 - * @CHAN_ENUM_184: channel number 184 - */ - -#ifdef WLAN_FEATURE_DSRC -enum channel_enum { - CHAN_ENUM_1, - CHAN_ENUM_2, - CHAN_ENUM_3, - CHAN_ENUM_4, - CHAN_ENUM_5, - CHAN_ENUM_6, - CHAN_ENUM_7, - CHAN_ENUM_8, - CHAN_ENUM_9, - CHAN_ENUM_10, - CHAN_ENUM_11, - CHAN_ENUM_12, - CHAN_ENUM_13, - CHAN_ENUM_14, - - CHAN_ENUM_36, - CHAN_ENUM_40, - CHAN_ENUM_44, - CHAN_ENUM_48, - CHAN_ENUM_52, - CHAN_ENUM_56, - CHAN_ENUM_60, - CHAN_ENUM_64, - - CHAN_ENUM_100, - CHAN_ENUM_104, - CHAN_ENUM_108, - CHAN_ENUM_112, - CHAN_ENUM_116, - CHAN_ENUM_120, - CHAN_ENUM_124, - CHAN_ENUM_128, - CHAN_ENUM_132, - CHAN_ENUM_136, - CHAN_ENUM_140, - CHAN_ENUM_144, - - CHAN_ENUM_149, - CHAN_ENUM_153, - CHAN_ENUM_157, - CHAN_ENUM_161, - CHAN_ENUM_165, - - CHAN_ENUM_170, - CHAN_ENUM_171, - CHAN_ENUM_172, - CHAN_ENUM_173, - CHAN_ENUM_174, - CHAN_ENUM_175, - CHAN_ENUM_176, - CHAN_ENUM_177, - CHAN_ENUM_178, - CHAN_ENUM_179, - CHAN_ENUM_180, - CHAN_ENUM_181, - CHAN_ENUM_182, - CHAN_ENUM_183, - CHAN_ENUM_184, - - NUM_CHANNELS, - - MIN_24GHZ_CHANNEL = CHAN_ENUM_1, - MAX_24GHZ_CHANNEL = CHAN_ENUM_14, - NUM_24GHZ_CHANNELS = (MAX_24GHZ_CHANNEL - MIN_24GHZ_CHANNEL + 1), - - MIN_49GHZ_CHANNEL = INVALID_CHANNEL_NUM, - MAX_49GHZ_CHANNEL = INVALID_CHANNEL_NUM - 1, - NUM_49GHZ_CHANNELS = MAX_49GHZ_CHANNEL - MIN_49GHZ_CHANNEL + 1, - - MIN_5GHZ_CHANNEL = CHAN_ENUM_36, - MAX_5GHZ_CHANNEL = CHAN_ENUM_184, - NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1), - - MIN_DSRC_CHANNEL = CHAN_ENUM_170, - MAX_DSRC_CHANNEL = CHAN_ENUM_184, - NUM_DSRC_CHANNELS = (MAX_DSRC_CHANNEL - MIN_DSRC_CHANNEL + 1), - - INVALID_CHANNEL = 0xBAD, -}; - -#else -enum channel_enum { - CHAN_ENUM_1, - CHAN_ENUM_2, - CHAN_ENUM_3, - CHAN_ENUM_4, - CHAN_ENUM_5, - CHAN_ENUM_6, - CHAN_ENUM_7, - CHAN_ENUM_8, - CHAN_ENUM_9, - CHAN_ENUM_10, - CHAN_ENUM_11, - CHAN_ENUM_12, - CHAN_ENUM_13, - CHAN_ENUM_14, - - CHAN_ENUM_36, - CHAN_ENUM_40, - CHAN_ENUM_44, - CHAN_ENUM_48, - CHAN_ENUM_52, - CHAN_ENUM_56, - CHAN_ENUM_60, - CHAN_ENUM_64, - - CHAN_ENUM_100, - CHAN_ENUM_104, - CHAN_ENUM_108, - CHAN_ENUM_112, - CHAN_ENUM_116, - CHAN_ENUM_120, - CHAN_ENUM_124, - CHAN_ENUM_128, - CHAN_ENUM_132, - CHAN_ENUM_136, - CHAN_ENUM_140, - CHAN_ENUM_144, - - CHAN_ENUM_149, - CHAN_ENUM_153, - CHAN_ENUM_157, - CHAN_ENUM_161, - CHAN_ENUM_165, - CHAN_ENUM_169, - CHAN_ENUM_173, - - NUM_CHANNELS, - - MIN_24GHZ_CHANNEL = CHAN_ENUM_1, - MAX_24GHZ_CHANNEL = CHAN_ENUM_14, - NUM_24GHZ_CHANNELS = (MAX_24GHZ_CHANNEL - MIN_24GHZ_CHANNEL + 1), - - MIN_49GHZ_CHANNEL = INVALID_CHANNEL_NUM, - MAX_49GHZ_CHANNEL = INVALID_CHANNEL_NUM - 1, - NUM_49GHZ_CHANNELS = MAX_49GHZ_CHANNEL - MIN_49GHZ_CHANNEL + 1, - - MIN_5GHZ_CHANNEL = CHAN_ENUM_36, - - MAX_5GHZ_CHANNEL = CHAN_ENUM_173, - - NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1), - INVALID_CHANNEL = 0xBAD, -}; -#endif /* WLAN_FEATURE_DSRC */ - -#else /* CONFIG_LEGACY_CHAN_ENUM */ /** * enum channel_enum - channel enumeration * @CHAN_ENUM_2412: channel with freq 2412 @@ -404,6 +204,65 @@ enum channel_enum { * @CHAN_ENUM_5910: channel with freq 5910 * @CHAN_ENUM_5915: channel with freq 5915 * @CHAN_ENUM_5920: channel with freq 5920 + * @CHAN_ENUM_5945: channel with freq 5945 + * @CHAN_ENUM_5965: channel with freq 5965 + * @CHAN_ENUM_5985: channel with freq 5985 + * @CHAN_ENUM_6005: channel with freq 6005 + * @CHAN_ENUM_6025: channel with freq 6025 + * @CHAN_ENUM_6045: channel with freq 6045 + * @CHAN_ENUM_6065: channel with freq 6065 + * @CHAN_ENUM_6085: channel with freq 6085 + * @CHAN_ENUM_6105: channel with freq 6105 + * @CHAN_ENUM_6125: channel with freq 6125 + * @CHAN_ENUM_6145: channel with freq 6145 + * @CHAN_ENUM_6165: channel with freq 6165 + * @CHAN_ENUM_6185: channel with freq 6185 + * @CHAN_ENUM_6205: channel with freq 6205 + * @CHAN_ENUM_6225: channel with freq 6225 + * @CHAN_ENUM_6245: channel with freq 6245 + * @CHAN_ENUM_6265: channel with freq 6265 + * @CHAN_ENUM_6285: channel with freq 6285 + * @CHAN_ENUM_6305: channel with freq 6305 + * @CHAN_ENUM_6325: channel with freq 6325 + * @CHAN_ENUM_6345: channel with freq 6345 + * @CHAN_ENUM_6365: channel with freq 6365 + * @CHAN_ENUM_6385: channel with freq 6385 + * @CHAN_ENUM_6405: channel with freq 6405 + * @CHAN_ENUM_6425: channel with freq 6425 + * @CHAN_ENUM_6445: channel with freq 6445 + * @CHAN_ENUM_6465: channel with freq 6465 + * @CHAN_ENUM_6485: channel with freq 6485 + * @CHAN_ENUM_6505: channel with freq 6505 + * @CHAN_ENUM_6525: channel with freq 6525 + * @CHAN_ENUM_6545: channel with freq 6545 + * @CHAN_ENUM_6565: channel with freq 6565 + * @CHAN_ENUM_6585: channel with freq 6585 + * @CHAN_ENUM_6605: channel with freq 6605 + * @CHAN_ENUM_6625: channel with freq 6625 + * @CHAN_ENUM_6645: channel with freq 6645 + * @CHAN_ENUM_6665: channel with freq 6665 + * @CHAN_ENUM_6685: channel with freq 6685 + * @CHAN_ENUM_6705: channel with freq 6705 + * @CHAN_ENUM_6725: channel with freq 6725 + * @CHAN_ENUM_6745: channel with freq 6745 + * @CHAN_ENUM_6765: channel with freq 6765 + * @CHAN_ENUM_6785: channel with freq 6785 + * @CHAN_ENUM_6805: channel with freq 6805 + * @CHAN_ENUM_6825: channel with freq 6825 + * @CHAN_ENUM_6845: channel with freq 6845 + * @CHAN_ENUM_6865: channel with freq 6865 + * @CHAN_ENUM_6885: channel with freq 6885 + * @CHAN_ENUM_6905: channel with freq 6905 + * @CHAN_ENUM_6925: channel with freq 6925 + * @CHAN_ENUM_6945: channel with freq 6945 + * @CHAN_ENUM_6965: channel with freq 6965 + * @CHAN_ENUM_6985: channel with freq 6985 + * @CHAN_ENUM_7005: channel with freq 7005 + * @CHAN_ENUM_7025: channel with freq 7025 + * @CHAN_ENUM_7045: channel with freq 7045 + * @CHAN_ENUM_7065: channel with freq 7065 + * @CHAN_ENUM_7085: channel with freq 7085 + * @CHAN_ENUM_7105: channel with freq 7105 */ enum channel_enum { CHAN_ENUM_2412, @@ -506,6 +365,67 @@ enum channel_enum { CHAN_ENUM_5910, CHAN_ENUM_5915, CHAN_ENUM_5920, +#ifdef CONFIG_BAND_6GHZ + CHAN_ENUM_5945, + CHAN_ENUM_5965, + CHAN_ENUM_5985, + CHAN_ENUM_6005, + CHAN_ENUM_6025, + CHAN_ENUM_6045, + CHAN_ENUM_6065, + CHAN_ENUM_6085, + CHAN_ENUM_6105, + CHAN_ENUM_6125, + CHAN_ENUM_6145, + CHAN_ENUM_6165, + CHAN_ENUM_6185, + CHAN_ENUM_6205, + CHAN_ENUM_6225, + CHAN_ENUM_6245, + CHAN_ENUM_6265, + CHAN_ENUM_6285, + CHAN_ENUM_6305, + CHAN_ENUM_6325, + CHAN_ENUM_6345, + CHAN_ENUM_6365, + CHAN_ENUM_6385, + CHAN_ENUM_6405, + CHAN_ENUM_6425, + CHAN_ENUM_6445, + CHAN_ENUM_6465, + CHAN_ENUM_6485, + CHAN_ENUM_6505, + CHAN_ENUM_6525, + CHAN_ENUM_6545, + CHAN_ENUM_6565, + CHAN_ENUM_6585, + CHAN_ENUM_6605, + CHAN_ENUM_6625, + CHAN_ENUM_6645, + CHAN_ENUM_6665, + CHAN_ENUM_6685, + CHAN_ENUM_6705, + CHAN_ENUM_6725, + CHAN_ENUM_6745, + CHAN_ENUM_6765, + CHAN_ENUM_6785, + CHAN_ENUM_6805, + CHAN_ENUM_6825, + CHAN_ENUM_6845, + CHAN_ENUM_6865, + CHAN_ENUM_6885, + CHAN_ENUM_6905, + CHAN_ENUM_6925, + CHAN_ENUM_6945, + CHAN_ENUM_6965, + CHAN_ENUM_6985, + CHAN_ENUM_7005, + CHAN_ENUM_7025, + CHAN_ENUM_7045, + CHAN_ENUM_7065, + CHAN_ENUM_7085, + CHAN_ENUM_7105, +#endif /* CONFIG_BAND_6GHZ */ NUM_CHANNELS, @@ -526,9 +446,30 @@ enum channel_enum { NUM_DSRC_CHANNELS = (MAX_DSRC_CHANNEL - MIN_DSRC_CHANNEL + 1), INVALID_CHANNEL = 0xBAD, -}; + +#ifdef DISABLE_UNII_SHARED_BANDS + MIN_UNII_1_BAND_CHANNEL = CHAN_ENUM_5180, + MAX_UNII_1_BAND_CHANNEL = CHAN_ENUM_5240, + NUM_UNII_1_BAND_CHANNELS = (MAX_UNII_1_BAND_CHANNEL - + MIN_UNII_1_BAND_CHANNEL + 1), + + MIN_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5260, + MAX_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5320, + NUM_UNII_2A_BAND_CHANNELS = (MAX_UNII_2A_BAND_CHANNEL - + MIN_UNII_2A_BAND_CHANNEL + 1), #endif +#ifdef CONFIG_BAND_6GHZ + MIN_6GHZ_CHANNEL = CHAN_ENUM_5945, + MAX_6GHZ_CHANNEL = CHAN_ENUM_7105, + NUM_6GHZ_CHANNELS = (MAX_6GHZ_CHANNEL - MIN_6GHZ_CHANNEL + 1), +#else + MIN_6GHZ_CHANNEL = INVALID_CHANNEL, + MAX_6GHZ_CHANNEL = INVALID_CHANNEL, + NUM_6GHZ_CHANNELS = 0, +#endif /* CONFIG_BAND_6GHZ */ +}; + /** * enum channel_state - channel state * @CHANNEL_STATE_DISABLE: disabled state @@ -585,23 +526,29 @@ enum ctl_value { * struct ch_params * @ch_width: channel width * @sec_ch_offset: secondary channel offset - * @center_freq_seg0: center freq for segment 0 - * @center_freq_seg1: center freq for segment 1 + * @center_freq_seg0: channel number for segment 0 + * @center_freq_seg1: channel number segment 1 + * @mhz_freq_seg0: Center frequency for segment 0 + * @mhz_freq_seg1: Center frequency for segment 1 */ struct ch_params { enum phy_ch_width ch_width; uint8_t sec_ch_offset; uint8_t center_freq_seg0; uint8_t center_freq_seg1; + qdf_freq_t mhz_freq_seg0; + qdf_freq_t mhz_freq_seg1; }; /** * struct channel_power + * @center_freq: Channel Center Frequency * @chan_num: channel number * @tx_power: TX power */ struct channel_power { - uint32_t chan_num; + qdf_freq_t center_freq; + uint8_t chan_num; uint32_t tx_power; }; @@ -622,20 +569,64 @@ enum offset_t { BW_INVALID = 0xFF }; +/** + * enum behav_limit - behavior limit + * @BEHAV_NONE: none + * @BEHAV_BW40_LOW_PRIMARY: BW40 low primary + * @BEHAV_BW40_HIGH_PRIMARY: BW40 high primary + * @BEHAV_BW80_PLUS: BW 80 plus + * @BEHAV_INVALID: invalid behavior + */ +enum behav_limit { + BEHAV_NONE, + BEHAV_BW40_LOW_PRIMARY, + BEHAV_BW40_HIGH_PRIMARY, + BEHAV_BW80_PLUS, + BEHAV_INVALID = 0xFF +}; + /** * struct reg_dmn_op_class_map_t: operating class * @op_class: operating class number - * @ch_spacing: channel spacing + * @chan_spacing: channel spacing * @offset: offset + * @behav_limit: OR of bitmaps of enum behav_limit + * @start_freq: starting frequency * @channels: channel set */ struct reg_dmn_op_class_map_t { uint8_t op_class; - uint8_t ch_spacing; + uint8_t chan_spacing; enum offset_t offset; + uint16_t behav_limit; + qdf_freq_t start_freq; uint8_t channels[REG_MAX_CHANNELS_PER_OPERATING_CLASS]; }; +/** + * struct regdmn_ap_cap_opclass_t: AP Cap operation class table + * @op_class: operating class number + * @ch_width: channel width in MHz + * @start_freq: Starting Frequency in MHz + * @behav_limit: OR of bitmaps of enum behav_limit + * @max_tx_pwr_dbm: Maximum tx power in dbm + * @num_supported_chan: Number of supported channels + * @num_non_supported_chan: Number of non-supported channels + * @sup_chan_list: Array of supported channel numbers + * @non_sup_chan_list: Array of non supported channel numbers + */ +struct regdmn_ap_cap_opclass_t { + uint8_t op_class; + uint8_t ch_width; + qdf_freq_t start_freq; + uint16_t behav_limit; + uint8_t max_tx_pwr_dbm; + uint8_t num_supported_chan; + uint8_t num_non_supported_chan; + uint8_t sup_chan_list[REG_MAX_CHANNELS_PER_OPERATING_CLASS]; + uint8_t non_sup_chan_list[REG_MAX_CHANNELS_PER_OPERATING_CLASS]; +}; + /** * struct reg_dmn_supp_op_classes: operating classes * @num_classes: number of classes @@ -713,8 +704,8 @@ enum country_src { * @nol_history: Set NOL-History when STA vap detects RADAR. */ struct regulatory_channel { - uint32_t center_freq; - uint32_t chan_num; + qdf_freq_t center_freq; + uint8_t chan_num; enum channel_state state; uint32_t chan_flags; uint32_t tx_power; @@ -725,7 +716,6 @@ struct regulatory_channel { bool nol_history; }; - /** * struct regulatory: regulatory information * @reg_domain: regulatory domain pair @@ -760,8 +750,8 @@ struct regulatory { * @max_bw: max bw */ struct chan_map { - uint32_t center_freq; - uint32_t chan_num; + qdf_freq_t center_freq; + uint8_t chan_num; uint16_t min_bw; uint16_t max_bw; }; @@ -772,8 +762,18 @@ struct chan_map { * @end_ch: end channel */ struct bonded_channel { - uint16_t start_ch; - uint16_t end_ch; + uint8_t start_ch; + uint8_t end_ch; +}; + +/** + * struct bonded_channel_freq + * @start_freq: start channel frequency + * @end_freq: end channel frequency + */ +struct bonded_channel_freq { + uint16_t start_freq; + uint16_t end_freq; }; struct set_country { @@ -836,7 +836,7 @@ struct cur_reg_rule { * @min_bw_5g: minimum 5G bw * @max_bw_5g: maximum 5G bw * @num_2g_reg_rules: number 2G reg rules - * @num_5g_reg_rules: number 5G reg rules + * @num_5g_reg_rules: number 5G and 6G reg rules * @reg_rules_2g_ptr: ptr to 2G reg rules * @reg_rules_5g_ptr: ptr to 5G reg rules */ @@ -875,6 +875,38 @@ struct reg_rule_info { struct cur_reg_rule reg_rules[MAX_REG_RULES]; }; +/** + * enum reg_reg_wifi_band + * @REG_BAND_2G: 2G band + * @REG_BAND_5G: 5G band + * @REG_BAND_6G: 6G band + * @REG_BAND_UNKNOWN: Unsupported band + */ +enum reg_wifi_band { + REG_BAND_2G, + REG_BAND_5G, + REG_BAND_6G, + REG_BAND_UNKNOWN +}; + +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * enum reg_unii_band + * @REG_UNII_BAND_1: Disable UNII-1 band channels + * @REG_UNII_BAND_2A: Disable UNII-2A band channels + */ +enum reg_unii_band { + REG_UNII_BAND_1 = 0x0, + REG_UNII_BAND_2A = 0x1, +}; +#endif + +#define REG_BAND_MASK_ALL (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) \ + | BIT(REG_BAND_6G)) + +/* Avoid the use of band_info as it does not support 6GHz band. Use + * reg_wifi_band, as it supports the 6GHz band + */ /** * enum band_info * @BAND_ALL:all bands @@ -917,18 +949,20 @@ enum restart_beaconing_on_ch_avoid_rule { * away from active LTE channels * @enable_srd_chan_in_master_mode: SRD channel support in master mode * @enable_11d_in_world_mode: enable 11d in world mode + * @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain. */ struct reg_config_vars { uint32_t enable_11d_support; uint32_t scan_11d_interval; uint32_t userspace_ctry_priority; - enum band_info band_capability; + uint32_t band_capability; uint32_t dfs_enabled; uint32_t indoor_chan_enabled; uint32_t force_ssc_disable_indoor_channel; enum restart_beaconing_on_ch_avoid_rule restart_beaconing; - bool enable_srd_chan_in_master_mode; + uint8_t enable_srd_chan_in_master_mode; bool enable_11d_in_world_mode; + bool retain_nol_across_regdmn_update; }; /** @@ -1041,8 +1075,8 @@ struct cur_regdmn_info { * @end_freq: end freq */ struct ch_avoid_freq_type { - uint32_t start_freq; - uint32_t end_freq; + qdf_freq_t start_freq; + qdf_freq_t end_freq; }; /** @@ -1057,12 +1091,12 @@ struct ch_avoid_ind_type { /** * struct unsafe_ch_list - * @ch_cnt: no.of channels - * @ch_list: channel list + * @chan_cnt: no.of channels + * @chan_freq_list: channel frequency list */ struct unsafe_ch_list { - uint16_t ch_cnt; - uint16_t ch_list[NUM_CHANNELS]; + uint16_t chan_cnt; + uint16_t chan_freq_list[NUM_CHANNELS]; }; /** @@ -1075,6 +1109,14 @@ struct avoid_freq_ind_data { struct unsafe_ch_list chan_list; }; +#define FIVEG_STARTING_FREQ 5000 +#define TWOG_STARTING_FREQ 2407 +#define TWOG_CHAN_14_IN_MHZ 2484 +#define TWOG_CHAN_1_IN_MHZ 2412 +#define TWOG_CHAN_5_IN_MHZ 2432 +#define TWOG_CHAN_6_IN_MHZ 2437 +#define TWOG_CHAN_13_IN_MHZ 2472 + /** * struct reg_ctl_params - reg ctl and regd info * @regd: regdomain pair diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index a15aa155d545bd9b7eb45e9f34a40aaa15dc9757..0c8f420ee0cebe21a7dab14df08307b1276b0bbc 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,13 +26,14 @@ #ifndef __WLAN_REG_SERVICES_API_H #define __WLAN_REG_SERVICES_API_H +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_min_24ghz_ch_num() - Get minimum 2.4GHz channel number * * Return: Minimum 2.4GHz channel number */ #define WLAN_REG_MIN_24GHZ_CH_NUM wlan_reg_min_24ghz_ch_num() -uint32_t wlan_reg_min_24ghz_ch_num(void); +uint8_t wlan_reg_min_24ghz_ch_num(void); /** * wlan_reg_max_24ghz_ch_num() - Get maximum 2.4GHz channel number @@ -40,7 +41,7 @@ uint32_t wlan_reg_min_24ghz_ch_num(void); * Return: Maximum 2.4GHz channel number */ #define WLAN_REG_MAX_24GHZ_CH_NUM wlan_reg_max_24ghz_ch_num() -uint32_t wlan_reg_max_24ghz_ch_num(void); +uint8_t wlan_reg_max_24ghz_ch_num(void); /** * wlan_reg_min_5ghz_ch_num() - Get minimum 5GHz channel number @@ -48,7 +49,7 @@ uint32_t wlan_reg_max_24ghz_ch_num(void); * Return: Minimum 5GHz channel number */ #define WLAN_REG_MIN_5GHZ_CH_NUM wlan_reg_min_5ghz_ch_num() -uint32_t wlan_reg_min_5ghz_ch_num(void); +uint8_t wlan_reg_min_5ghz_ch_num(void); /** * wlan_reg_max_5ghz_ch_num() - Get maximum 5GHz channel number @@ -56,8 +57,44 @@ uint32_t wlan_reg_min_5ghz_ch_num(void); * Return: Maximum 5GHz channel number */ #define WLAN_REG_MAX_5GHZ_CH_NUM wlan_reg_max_5ghz_ch_num() -uint32_t wlan_reg_max_5ghz_ch_num(void); +uint8_t wlan_reg_max_5ghz_ch_num(void); +#endif /* CONFIG_CHAN_NUM_API */ +#ifdef CONFIG_CHAN_FREQ_API +/** + * wlan_reg_min_24ghz_chan_freq() - Get minimum 2.4GHz channel frequency + * + * Return: Minimum 2.4GHz channel frequency + */ +#define WLAN_REG_MIN_24GHZ_CHAN_FREQ wlan_reg_min_24ghz_chan_freq() +qdf_freq_t wlan_reg_min_24ghz_chan_freq(void); + +/** + * wlan_reg_max_24ghz_chan_freq() - Get maximum 2.4GHz channel frequency + * + * Return: Maximum 2.4GHz channel frequency + */ +#define WLAN_REG_MAX_24GHZ_CHAN_FREQ wlan_reg_max_24ghz_chan_freq() +qdf_freq_t wlan_reg_max_24ghz_chan_freq(void); + +/** + * wlan_reg_min_5ghz_chan_freq() - Get minimum 5GHz channel frequency + * + * Return: Minimum 5GHz channel frequency + */ +#define WLAN_REG_MIN_5GHZ_CHAN_FREQ wlan_reg_min_5ghz_chan_freq() +qdf_freq_t wlan_reg_min_5ghz_chan_freq(void); + +/** + * wlan_reg_max_5ghz_chan_freq() - Get maximum 5GHz channel frequency + * + * Return: Maximum 5GHz channel frequency + */ +#define WLAN_REG_MAX_5GHZ_CHAN_FREQ wlan_reg_max_5ghz_chan_freq() +qdf_freq_t wlan_reg_max_5ghz_chan_freq(void); +#endif /* CONFIG_CHAN_FREQ_API */ + +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_is_24ghz_ch() - Check if the given channel number is 2.4GHz * @chan: Channel number @@ -65,7 +102,7 @@ uint32_t wlan_reg_max_5ghz_ch_num(void); * Return: true if channel number is 2.4GHz, else false */ #define WLAN_REG_IS_24GHZ_CH(chan) wlan_reg_is_24ghz_ch(chan) -bool wlan_reg_is_24ghz_ch(uint32_t chan); +bool wlan_reg_is_24ghz_ch(uint8_t chan); /** * wlan_reg_is_5ghz_ch() - Check if the given channel number is 5GHz @@ -74,7 +111,8 @@ bool wlan_reg_is_24ghz_ch(uint32_t chan); * Return: true if channel number is 5GHz, else false */ #define WLAN_REG_IS_5GHZ_CH(chan) wlan_reg_is_5ghz_ch(chan) -bool wlan_reg_is_5ghz_ch(uint32_t chan); +bool wlan_reg_is_5ghz_ch(uint8_t chan); +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_is_24ghz_ch_freq() - Check if the given channel frequency is 2.4GHz @@ -83,7 +121,7 @@ bool wlan_reg_is_5ghz_ch(uint32_t chan); * Return: true if channel frequency is 2.4GHz, else false */ #define WLAN_REG_IS_24GHZ_CH_FREQ(freq) wlan_reg_is_24ghz_ch_freq(freq) -bool wlan_reg_is_24ghz_ch_freq(uint32_t freq); +bool wlan_reg_is_24ghz_ch_freq(qdf_freq_t freq); /** * wlan_reg_is_5ghz_ch_freq() - Check if the given channel frequency is 5GHz @@ -92,9 +130,114 @@ bool wlan_reg_is_24ghz_ch_freq(uint32_t freq); * Return: true if channel frequency is 5GHz, else false */ #define WLAN_REG_IS_5GHZ_CH_FREQ(freq) wlan_reg_is_5ghz_ch_freq(freq) -bool wlan_reg_is_5ghz_ch_freq(uint32_t freq); +bool wlan_reg_is_5ghz_ch_freq(qdf_freq_t freq); + +/** + * wlan_reg_is_freq_indoor() - Check if a frequency is indoor. + * @pdev: Pointer to pdev. + * @freq: Channel frequency. + * + * Return: Return true if a frequency is indoor, else false. + */ +bool wlan_reg_is_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +#ifdef CONFIG_BAND_6GHZ +/** + * wlan_reg_is_6ghz_chan_freq() - Check if the given channel frequency is 6GHz + * @freq: Channel frequency + * + * Return: true if channel frequency is 6GHz, else false + */ +#define WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) wlan_reg_is_6ghz_chan_freq(freq) +bool wlan_reg_is_6ghz_chan_freq(uint16_t freq); + +/** + * wlan_reg_is_6ghz_psc_chan_freq() - Check if the given 6GHz channel frequency + * is preferred scanning channel frequency. + * @freq: Channel frequency + * + * Return: true if given 6GHz channel frequency is preferred scanning channel + * frequency, else false + */ +#define WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq) \ + wlan_reg_is_6ghz_psc_chan_freq(freq) +bool wlan_reg_is_6ghz_psc_chan_freq(uint16_t freq); + +/** + * wlan_reg_min_6ghz_chan_freq() - Get minimum 6GHz channel center frequency + * + * Return: Minimum 6GHz channel center frequency + */ +#define WLAN_REG_MIN_6GHZ_CHAN_FREQ wlan_reg_min_6ghz_chan_freq() +uint16_t wlan_reg_min_6ghz_chan_freq(void); + +/** + * wlan_reg_max_6ghz_chan_freq() - Get maximum 6GHz channel center frequency + * + * Return: Maximum 6GHz channel center frequency + */ +#define WLAN_REG_MAX_6GHZ_CHAN_FREQ wlan_reg_max_6ghz_chan_freq() +uint16_t wlan_reg_max_6ghz_chan_freq(void); + +#else + +#define WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) (false) +static inline bool wlan_reg_is_6ghz_chan_freq(uint16_t freq) +{ + return false; +} + +#define WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq) (false) +static inline bool wlan_reg_is_6ghz_psc_chan_freq(uint16_t freq) +{ + return false; +} + +#define WLAN_REG_MIN_6GHZ_CHAN_FREQ (false) +static inline uint16_t wlan_reg_min_6ghz_chan_freq(void) +{ + return 0; +} + +#define WLAN_REG_MAX_6GHZ_CHAN_FREQ (false) +static inline uint16_t wlan_reg_max_6ghz_chan_freq(void) +{ + return 0; +} +#endif /* CONFIG_BAND_6GHZ */ + +/** + * wlan_reg_get_band_channel_list() - Get channel list based on the band_mask + * @pdev: pdev ptr + * @band_mask: Input bitmap with band set + * @channel_list: Pointer to Channel List + * + * Get the given channel list and number of channels from the current channel + * list based on input band bitmap. + * + * Return: Number of channels, else 0 to indicate error + */ +uint16_t +wlan_reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list); + +/** + * wlan_reg_chan_band_to_freq - Return channel frequency based on the channel + * number and band. + * @pdev: pdev ptr + * @chan: Channel Number + * @band_mask: Bitmap for bands + * + * Return: Return channel frequency or return 0, if the channel is disabled or + * if the input channel number or band_mask is invalid. Composite bands are + * supported only for 2.4Ghz and 5Ghz bands. For other bands the following + * priority is given: 1) 6Ghz 2) 5Ghz 3) 2.4Ghz. + */ +qdf_freq_t wlan_reg_chan_band_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan, + uint8_t band_mask); -#ifndef CONFIG_LEGACY_CHAN_ENUM /** * wlan_reg_is_49ghz_freq() - Check if the given channel frequency is 4.9GHz * @freq: Channel frequency @@ -102,8 +245,7 @@ bool wlan_reg_is_5ghz_ch_freq(uint32_t freq); * Return: true if channel frequency is 4.9GHz, else false */ #define WLAN_REG_IS_49GHZ_FREQ(freq) wlan_reg_is_49ghz_freq(freq) -bool wlan_reg_is_49ghz_freq(uint32_t freq); -#endif +bool wlan_reg_is_49ghz_freq(qdf_freq_t freq); /** * wlan_reg_ch_num() - Get channel number from channel enum @@ -112,7 +254,7 @@ bool wlan_reg_is_49ghz_freq(uint32_t freq); * Return: channel number */ #define WLAN_REG_CH_NUM(ch_enum) wlan_reg_ch_num(ch_enum) -uint32_t wlan_reg_ch_num(uint32_t ch_enum); +uint8_t wlan_reg_ch_num(uint32_t ch_enum); /** * wlan_reg_ch_to_freq() - Get channel frequency from channel enum @@ -121,8 +263,9 @@ uint32_t wlan_reg_ch_num(uint32_t ch_enum); * Return: channel frequency */ #define WLAN_REG_CH_TO_FREQ(ch_enum) wlan_reg_ch_to_freq(ch_enum) -uint32_t wlan_reg_ch_to_freq(uint32_t ch_enum); +qdf_freq_t wlan_reg_ch_to_freq(uint32_t ch_enum); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_is_same_band_channels() - Check if given channel numbers have same * band @@ -133,7 +276,7 @@ uint32_t wlan_reg_ch_to_freq(uint32_t ch_enum); */ #define WLAN_REG_IS_SAME_BAND_CHANNELS(chan_num1, chan_num2) \ wlan_reg_is_same_band_channels(chan_num1, chan_num2) -bool wlan_reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2); +bool wlan_reg_is_same_band_channels(uint8_t chan_num1, uint8_t chan_num2); /** * wlan_reg_is_channel_valid_5g_sbs() Check if the given channel is 5G SBS. @@ -144,11 +287,11 @@ bool wlan_reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2); */ #define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ wlan_reg_is_channel_valid_5g_sbs(curchan, newchan) -bool wlan_reg_is_channel_valid_5g_sbs(uint32_t curchan, uint32_t newchan); +bool wlan_reg_is_channel_valid_5g_sbs(uint8_t curchan, uint8_t newchan); +#endif /* CONFIG_CHAN_NUM_API */ -#define WLAN_REG_INVALID_CHANNEL_ID -#define WLAN_REG_GET_24_END_CHAN_NUM 14 +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_chan_to_band() - Get band from channel number * @chan_num: channel number @@ -156,7 +299,7 @@ bool wlan_reg_is_channel_valid_5g_sbs(uint32_t curchan, uint32_t newchan); * Return: band info */ #define WLAN_REG_CHAN_TO_BAND(chan_num) wlan_reg_chan_to_band(chan_num) -enum band_info wlan_reg_chan_to_band(uint32_t chan_num); +enum band_info wlan_reg_chan_to_band(uint8_t chan_num); /** * wlan_reg_get_channel_list_with_power() - Provide the channel list with power @@ -167,7 +310,7 @@ enum band_info wlan_reg_chan_to_band(uint32_t chan_num); QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan); - +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_read_default_country() - Read the default country for the regdomain * @country: pointer to the country code. @@ -197,6 +340,7 @@ bool wlan_reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq); QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, uint8_t *country); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_chan_has_dfs_attribute() - check channel has dfs attribute flag * @ch: channel number. @@ -206,7 +350,7 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, * Return: true if chan is dfs, otherwise false */ bool -wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch); +wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch); /** * wlan_reg_is_etsi13_srd_chan () - Checks if the ch is ETSI13 srd ch or not @@ -217,6 +361,20 @@ wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch); */ bool wlan_reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +/** + * wlan_reg_is_etsi13_srd_chan_for_freq () - Checks if the ch is ETSI13 srd ch + * or not + * @pdev: pdev ptr + * @freq: channel center frequency + * + * Return: true or false + */ +bool wlan_reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); +#endif /*CONFIG_CHAN_FREQ_API*/ /** * wlan_reg_is_etsi13_regdmn() - Checks if current reg domain is ETSI13 or not @@ -246,13 +404,14 @@ bool wlan_reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev */ bool wlan_reg_is_world(uint8_t *country); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_chan_enum() - Get channel enum for given channel number * @chan_num: Channel number * * Return: Channel enum */ -enum channel_enum wlan_reg_get_chan_enum(uint32_t chan_num); +enum channel_enum wlan_reg_get_chan_enum(uint8_t chan_num); /** * wlan_reg_get_channel_state() - Get channel state from regulatory @@ -261,7 +420,7 @@ enum channel_enum wlan_reg_get_chan_enum(uint32_t chan_num); * Return: channel state */ enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev, - uint32_t ch); + uint8_t ch); /** * wlan_reg_get_5g_bonded_channel_state() - Get 5G bonded channel state @@ -300,7 +459,7 @@ enum channel_state wlan_reg_get_2g_bonded_channel_state( void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, uint8_t sec_ch_2g, struct ch_params *ch_params); - +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_get_dfs_region () - Get the current dfs region * @dfs_reg: pointer to dfs region @@ -310,23 +469,25 @@ void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, QDF_STATUS wlan_reg_get_dfs_region(struct wlan_objmgr_pdev *pdev, enum dfs_reg *dfs_reg); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_channel_reg_power() - Provide the channel regulatory power - * @chan_num: chennal number + * @chan_num: channel number * * Return: int */ uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num); + uint8_t chan_num); /** * wlan_reg_get_channel_freq() - provide the channel center freq - * @chan_num: chennal number + * @chan_num: channel number * * Return: int */ -uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num); +qdf_freq_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_get_current_chan_list() - provide the pdev current channel list @@ -337,6 +498,8 @@ uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, struct regulatory_channel *chan_list); + +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_bonded_channel_state() - get bonded channel state * @pdev: pdev ptr @@ -349,6 +512,7 @@ QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, enum channel_state wlan_reg_get_bonded_channel_state( struct wlan_objmgr_pdev *pdev, uint8_t ch, enum phy_ch_width bw, uint8_t sec_ch); +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_set_dfs_region() - set the dfs region @@ -391,6 +555,21 @@ QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel, uint8_t offset); + +/** + * wlan_reg_get_opclass_from_freq_width() - Get operating class from frequency + * @country: Country code. + * @freq: Channel center frequency. + * @ch_width: Channel width. + * @behav_limit: Behaviour limit. + * + * Return: Error code. + */ +uint8_t wlan_reg_get_opclass_from_freq_width(uint8_t *country, + qdf_freq_t freq, + uint8_t ch_width, + uint16_t behav_limit); + /** * wlan_reg_dmn_print_channels_in_opclass() - Print channels in op-class * @country: country alpha2 @@ -435,6 +614,23 @@ uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class); +/** + * wlan_reg_get_opclass_details() - Get details about the current opclass table. + * @pdev: Pointer to pdev. + * @reg_ap_cap: Pointer to reg_ap_cap. + * @n_opclasses: Pointer to number of opclasses. + * @max_supp_op_class: Maximum number of operating classes supported. + * @global_tbl_lookup: Whether to lookup global op class tbl. + * + * Return: QDF_STATUS_SUCCESS if success, else return QDF_STATUS_FAILURE. + */ +QDF_STATUS +wlan_reg_get_opclass_details(struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t *n_opclasses, + uint8_t max_supp_op_class, + bool global_tbl_lookup); + /** * wlan_regulatory_init() - init regulatory component * @@ -466,7 +662,7 @@ QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc); /** * regulatory_pdev_open() - Open regulatory component - * @pdev: Pointer to pdev structure. + * @pdev: Pointer to pdev structure * * Return: Success or Failure */ @@ -480,6 +676,7 @@ QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev); */ QDF_STATUS regulatory_pdev_close(struct wlan_objmgr_pdev *pdev); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_update_nol_ch () - set nol channel * @pdev: pdev ptr @@ -494,15 +691,6 @@ void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t num_ch, bool nol_ch); -/** - * wlan_reg_is_dfs_ch () - Checks the channel state for DFS - * @pdev: pdev ptr - * @chan: channel - * - * Return: true or false - */ -bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); - /** * wlan_reg_is_dsrc_chan () - Checks if the channel is dsrc channel or not * @pdev: pdev ptr @@ -521,7 +709,7 @@ bool wlan_reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); * Return: true or false */ bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan); + uint8_t chan); /** * wlan_reg_is_disable_ch () - Checks chan state for disabled @@ -530,7 +718,8 @@ bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, * * Return: true or false */ -bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); +bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint8_t chan); +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_freq_to_chan () - convert channel freq to channel number @@ -539,8 +728,8 @@ bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan); * * Return: true or false */ -uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, - uint32_t freq); +uint8_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); /** * wlan_reg_chan_to_freq () - convert channel number to frequency @@ -548,8 +737,8 @@ uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, * * Return: true or false */ -uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan); +qdf_freq_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan); /** * wlan_reg_legacy_chan_to_freq () - convert chan to freq, for 2G and 5G @@ -557,8 +746,8 @@ uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, * * Return: frequency */ -uint16_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, - uint8_t chan); +qdf_freq_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan); /** * wlan_reg_is_us() - reg is us country @@ -568,6 +757,7 @@ uint16_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, */ bool wlan_reg_is_us(uint8_t *country); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_chan_is_49ghz() - Check if the input channel number is 4.9GHz * @pdev: Pdev pointer @@ -575,9 +765,9 @@ bool wlan_reg_is_us(uint8_t *country); * * Return: true if the channel is 4.9GHz else false. */ - bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_set_country() - Set the current regulatory country @@ -664,10 +854,10 @@ bool wlan_reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc); * Return: QDF status */ QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev, - uint32_t *low_2g, - uint32_t *high_2g, - uint32_t *low_5g, - uint32_t *high_5g); + qdf_freq_t *low_2g, + qdf_freq_t *high_2g, + qdf_freq_t *low_5g, + qdf_freq_t *high_5g); /** * wlan_reg_get_tx_ops () - get regulatory tx ops * @psoc: psoc ptr @@ -686,6 +876,7 @@ wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc); QDF_STATUS wlan_reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev, struct cur_regdmn_info *cur_regdmn); +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_update_nol_history_ch() - Set nol-history flag for the channels in * the list. @@ -701,6 +892,364 @@ void wlan_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, bool nol_history_ch); +#endif /* CONFIG_CHAN_NUM_API */ +/** + * wlan_reg_is_regdmn_en302502_applicable() - Find if ETSI EN302_502 radar + * pattern is applicable in the current regulatory domain. + * @pdev: Pdev ptr. + * + * Return: Boolean. + * True: If EN302_502 is applicable. + * False: otherwise. + */ +bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified channel range in the regcap. + * @pdev: pointer to wlan_objmgr_pdev. + * + * Return : QDF_STATUS + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_reg_disable_chan_coex() - Disable Coexisting channels based on the input + * bitmask + * @pdev: pointer to wlan_objmgr_pdev. + * unii_5g_bitmap: UNII 5G bitmap. + * + * Return : QDF_STATUS + */ +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); +#else +static inline QDF_STATUS +wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * wlan_reg_is_same_band_freqs() - Check if two channel frequencies + * have same band + * @freq1: Frequency 1 + * @freq2: Frequency 2 + * + * Return: true if both the channel frequency has the same band. + */ +#define WLAN_REG_IS_SAME_BAND_FREQS(freq1, freq2) \ + wlan_reg_is_same_band_freqs(freq1, freq2) +bool wlan_reg_is_same_band_freqs(qdf_freq_t freq1, qdf_freq_t freq2); + +/** + * wlan_reg_get_chan_enum_for_freq() - Get channel enum for given channel center + * frequency + * @freq: Channel center frequency + * + * Return: Channel enum + */ +enum channel_enum wlan_reg_get_chan_enum_for_freq(qdf_freq_t freq); + +/** + * wlan_reg_update_nol_history_ch_for_freq() - Set nol-history flag for the + * channels in the list. + * + * @pdev: Pdev ptr + * @ch_list: Input channel list. + * @num_ch: Number of channels. + * @nol_history_ch: Nol history value. + * + * Return: void + */ +void wlan_reg_update_nol_history_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *ch_list, + uint8_t num_ch, + bool nol_history_ch); +/** + * wlan_reg_is_frequency_valid_5g_sbs() Check if the given frequency is 5G SBS. + * @curfreq: current channel center frequency + * @newfreq:new channel center frequency + * + * Return: true if the given frequency is a valid 5G SBS + */ +#define WLAN_REG_IS_FREQUENCY_VALID_5G_SBS(curfreq, newfreq) \ + wlan_reg_is_frequency_valid_5g_sbs(curfreq, newfreq) +bool wlan_reg_is_frequency_valid_5g_sbs(qdf_freq_t curfreq, qdf_freq_t newfreq); + +/** + * wlan_reg_chan_has_dfs_attribute_for_freq() - check channel has dfs + * attribute flag + * @freq: channel center frequency. + * + * This API get chan initial dfs attribute from regdomain + * + * Return: true if chan is dfs, otherwise false + */ +bool +wlan_reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * wlan_reg_get_channel_list_with_power_for_freq() - Provide the channel list + * with power + * @ch_list: pointer to the channel list. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev *pdev, + struct channel_power *ch_list, + uint8_t *num_chan); + +/** + * wlan_reg_get_5g_bonded_channel_state_for_freq() - Get 5G bonded channel state + * @pdev: The physical dev to program country code or regdomain + * @freq: channel frequency. + * @bw: channel band width + * + * Return: channel state + */ +enum channel_state +wlan_reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw); +/** + * wlan_reg_get_2g_bonded_channel_state_for_freq() - Get 2G bonded channel state + * @pdev: The physical dev to program country code or regdomain + * @freq: channel center frequency. + * @sec_ch_freq: Secondary channel center frequency. + * @bw: channel band width + * + * Return: channel state + */ +enum channel_state +wlan_reg_get_2g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_freq, + enum phy_ch_width bw); + +/** + * wlan_reg_get_channel_state_for_freq() - Get channel state from regulatory + * @pdev: Pointer to pdev + * @freq: channel center frequency. + * + * Return: channel state + */ +enum channel_state +wlan_reg_get_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * wlan_reg_set_channel_params_for_freq() - Sets channel parameteres for + * given bandwidth + * @pdev: The physical dev to program country code or regdomain + * @freq: channel center frequency. + * @sec_ch_2g_freq: Secondary channel center frequency. + * @ch_params: pointer to the channel parameters. + * + * Return: None + */ +void wlan_reg_set_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_2g_freq, + struct ch_params *ch_params); + +/** + * wlan_reg_get_channel_cfreq_reg_power_for_freq() - Provide the channel + * regulatory power + * @freq: channel center frequency + * + * Return: int + */ +uint8_t wlan_reg_get_channel_reg_power_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * wlan_reg_update_nol_ch_for_freq () - set nol channel + * @pdev: pdev ptr + * @chan_freq_list: channel list to be returned + * @num_ch: number of channels + * @nol_ch: nol flag + * + * Return: void + */ +void wlan_reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq_list, + uint8_t num_ch, + bool nol_ch); + +/** + * wlan_reg_is_dfs_freq() - Checks the channel state for DFS + * @freq: Channel center frequency + * + * Return: true or false + */ +bool wlan_reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); + +/** + * wlan_reg_is_dsrc_freq() - Checks if the channel is dsrc channel or not + * @freq: Channel center frequency + * + * Return: true or false + */ +bool wlan_reg_is_dsrc_freq(qdf_freq_t freq); + +/** + * wlan_reg_is_passive_or_disable_for_freq() - Checks chan state for passive + * and disabled + * @pdev: pdev ptr + * @freq: Channel center frequency + * + * Return: true or false + */ +bool wlan_reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * wlan_reg_is_disable_for_freq() - Checks chan state for disabled + * @pdev: pdev ptr + * @freq: Channel center frequency + * + * Return: true or false + */ +bool wlan_reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq); + +/** + * wlan_reg_chan_to_band() - Get band from channel number + * @chan_num: channel number + * + * Return: wifi band + */ +enum reg_wifi_band wlan_reg_freq_to_band(qdf_freq_t freq); + +/** + * wlan_reg_min_chan_freq() - Minimum channel frequency supported + * + * Return: frequency + */ +qdf_freq_t wlan_reg_min_chan_freq(void); + +/** + * wlan_reg_max_chan_freq() - Return max. frequency + * + * Return: frequency + */ +qdf_freq_t wlan_reg_max_chan_freq(void); + +/** + * wlan_reg_freq_width_to_chan_op_class() -Get op class from freq + * @pdev: pdev ptr + * @freq: channel frequency + * @chan_width: channel width + * @global_tbl_lookup: whether to look up global table + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: void + */ +void wlan_reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * wlan_reg_freq_width_to_chan_op_class_auto() - convert frequency to + * operating class,channel + * @pdev: pdev pointer + * @freq: channel frequency in mhz + * @chan_width: channel width + * @global_tbl_lookup: whether to lookup global op class tbl + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: Void. + */ +void wlan_reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * wlan_reg_freq_to_chan_and_op_class() - Converts freq to oper class + * @pdev: pdev ptr + * @freq: channel frequency + * @global_tbl_lookup: whether to look up global table + * @behav_limit: behavior limit + * @op_class: operating class + * @chan_num: channel number + * + * Return: void + */ +void wlan_reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num); + +/** + * wlan_reg_country_opclass_freq_check() - checks frequency in (ctry, op class) + * pair + * @pdev: pdev ptr + * @country: country information + * @op_class: operating class + * @chan_freq: channel frequency + * + * Return: bool + */ +bool wlan_reg_country_opclass_freq_check(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t op_class, + qdf_freq_t chan_freq); + +/** + * wlan_reg_get_5g_bonded_channel_and_state_for_freq()- Return the channel + * state for a 5G or 6G channel frequency based on the channel width and + * bonded channel. + * @pdev: Pointer to pdev. + * @freq: Channel center frequency. + * @bw Channel Width. + * @bonded_chan_ptr_ptr: Pointer to bonded_channel_freq. + * + * Return: Channel State + */ +enum channel_state +wlan_reg_get_5g_bonded_channel_and_state_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + enum phy_ch_width bw, + const + struct bonded_channel_freq + **bonded_chan_ptr_ptr); +#endif /*CONFIG_CHAN_FREQ_API */ + +/** + * wlan_reg_get_op_class_width() - Get operating class chan width + * @pdev: pdev ptr + * @freq: channel frequency + * @global_tbl_lookup: whether to look up global table + * @op_class: operating class + * @chan_num: channel number + * + * Return: channel width of op class + */ +uint16_t wlan_reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, + uint8_t op_class, + bool global_tbl_lookup); + /** * wlan_reg_is_6ghz_op_class() - Whether 6ghz oper class * @pdev: pdev ptr @@ -713,10 +1262,57 @@ bool wlan_reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, /** * wlan_reg_is_6ghz_supported() - Whether 6ghz is supported - * @pdev: pdev ptr + * @psoc: psoc ptr * * Return: bool */ -bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev); +bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc); + +#ifdef HOST_OPCLASS_EXT +/** + * wlan_reg_country_chan_opclass_to_freq() - Convert channel number to + * frequency based on country code and op class + * @pdev: pdev object. + * @country: country code. + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @strict: flag to find channel from matched operating class code. + * + * Look up (channel, operating class) pair in country operating class tables + * and return the channel frequency. + * If not found and "strict" flag is false, try to get frequency (Mhz) by + * channel number only. + * + * Return: Channel center frequency else return 0. + */ +qdf_freq_t +wlan_reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t chan, uint8_t op_class, + bool strict); +#endif +/** + * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency + * @chan: IEEE Channel Number. + * @op_class: Opclass. + * @global_tbl_lookup: Global table lookup. + * + * Return: Channel center frequency else return 0. + */ +uint16_t wlan_reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup); +#ifdef CONFIG_REG_CLIENT +/** + * wlan_reg_band_bitmap_to_band_info() - Convert the band_bitmap to a + * band_info enum + * @band_bitmap: bitmap on top of reg_wifi_band of bands enabled + * + * Return: BAND_ALL if both 2G and 5G band is enabled + * BAND_2G if 2G is enabled but 5G isn't + * BAND_5G if 5G is enabled but 2G isn't + */ +enum band_info wlan_reg_band_bitmap_to_band_info(uint32_t band_bitmap); +#endif #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h index 2fae138fdea7a719cd5216efab160b111e94e0e3..1014c325e75bf146ab804312b0dfff22e39b88ae 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h @@ -69,7 +69,6 @@ QDF_STATUS tgt_reg_process_ch_avoid_event(struct wlan_objmgr_psoc *psoc, /** * tgt_reg_ignore_fw_reg_offload_ind() - Check whether regdb offload indication * from FW needs to be ignored. - * * @psoc: Pointer to psoc */ bool tgt_reg_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h index e6fc9674b2618b0e71e3e56b3ce6db550fabe821..657bce376bd664df5e319783693abf558501a634 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -31,22 +31,23 @@ typedef QDF_STATUS (*reg_event_cb)(void *status_struct); /** * ucfg_reg_set_band() - Sets the band information for the PDEV * @pdev: The physical pdev to set the band for - * @band: The set band parameter to configure for the physical device + * @band_bitmap: The band bitmap parameter (over reg_wifi_band) to configure + * for the physical device * * Return: QDF_STATUS */ QDF_STATUS ucfg_reg_set_band(struct wlan_objmgr_pdev *pdev, - enum band_info band); + uint32_t band_bitmap); /** * ucfg_reg_get_band() - Gets the band information for the PDEV * @pdev: The physical pdev to get the band for - * @band: The band parameter of the physical device + * @band_bitmap: The band parameter of the physical device * * Return: QDF_STATUS */ QDF_STATUS ucfg_reg_get_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band); + uint32_t *band_bitmap); /** * ucfg_reg_notify_sap_event() - Notify regulatory domain for sap event @@ -66,7 +67,7 @@ QDF_STATUS ucfg_reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, * * Return: QDF_STATUS */ -#ifdef DISABLE_CHANNEL_LIST +#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_NUM_API) void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t *channel_list, uint32_t num_channels); @@ -77,18 +78,53 @@ void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t num_channels) { } -#endif +#endif /* CONFIG_CHAN_NUM_API */ /** - * ucfg_reg_restore_cached_channels() - Cache the current state of the channles - * @pdev: The physical dev to cache the channels for + * ucfg_reg_cache_channel_freq_state() - Cache the current state of the + * channels based on the channel center frequency. + * @pdev: Pointer to pdev. + * @channel_list: List of the channels for which states need to be cached. + * @num_channels: Number of channels in the list. * * Return: QDF_STATUS */ +#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_CHAN_FREQ_API) +void ucfg_reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels); +#else +static inline +void ucfg_reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) +{ +} +#endif /* CONFIG_CHAN_FREQ_API */ + + #ifdef DISABLE_CHANNEL_LIST +/** + * ucfg_reg_disable_cached_channels() - Disable cached channels + * @pdev: The physical dev to cache the channels for + * + * Return: None + */ +void ucfg_reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_reg_restore_cached_channels() - Restore disabled cached channels + * @pdev: The physical dev to cache the channels for + * + * Return: None + */ void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev); #else static inline +void ucfg_reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) +{ +} +static inline void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) { } @@ -153,15 +189,6 @@ QDF_STATUS ucfg_reg_set_country(struct wlan_objmgr_pdev *dev, */ QDF_STATUS ucfg_reg_reset_country(struct wlan_objmgr_psoc *psoc); -/** - * ucfg_reg_get_curr_band() - Get the current band capability - * @pdev: The physical dev to get default country from - * @band: buffer to populate the band into - * - * Return: QDF_STATUS - */ -QDF_STATUS ucfg_reg_get_curr_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band); /** * ucfg_reg_enable_dfs_channels() - Enable the use of DFS channels * @pdev: The physical dev to enable DFS channels for @@ -358,4 +385,23 @@ QDF_STATUS ucfg_reg_set_hal_reg_cap(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS ucfg_set_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_reg_get_unii_5g_bitmap() - get unii_5g_bitmap value + * @pdev: pdev pointer + * @bitmap: Pointer to retrieve unii_5g_bitmap of enum reg_unii_band. + * + * Return: QDF_STATUS + */ +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS +ucfg_reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap); +#else +static inline QDF_STATUS +ucfg_reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap) +{ + *bitmap = 0; + return QDF_STATUS_SUCCESS; +} +#endif + #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 281d33996bbbe9314d4154af0c351afe0700de9f..baa186a724ae204d8bca7b9f461ea5c978546af4 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include <../../core/src/reg_offload_11d_scan.h> #include +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_channel_list_with_power() - Provide the channel list with power * @ch_list: pointer to the channel list. @@ -56,6 +58,7 @@ QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, */ return reg_get_channel_list_with_power(pdev, ch_list, num_chan); } +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_read_default_country() - Read the default country for the regdomain @@ -81,6 +84,7 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, return reg_read_current_country(psoc, country); } +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_channel_state() - Get channel state from regulatory * @ch: channel number. @@ -88,7 +92,7 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, * Return: channel state */ enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev, - uint32_t ch) + uint8_t ch) { /* * Get channel state from regulatory @@ -97,7 +101,7 @@ enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev, } bool -wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch) +wlan_reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint8_t ch) { return reg_chan_has_dfs_attribute(pdev, ch); } @@ -153,6 +157,7 @@ void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, */ reg_set_channel_params(pdev, ch, sec_ch_2g, ch_params); } +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_get_dfs_region () - Get the current dfs region @@ -171,8 +176,9 @@ QDF_STATUS wlan_reg_get_dfs_region(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +#ifdef CONFIG_CHAN_NUM_API uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) + uint8_t chan_num) { return reg_get_channel_reg_power(pdev, chan_num); } @@ -183,11 +189,12 @@ uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, * * Return: int */ -uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) +qdf_freq_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) { return reg_get_channel_freq(pdev, chan_num); } +#endif /* CONFIG_CHAN_NUM_API */ QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, struct regulatory_channel *chan_list) @@ -195,6 +202,8 @@ QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, return reg_get_current_chan_list(pdev, chan_list); } +qdf_export_symbol(wlan_reg_get_current_chan_list); + /** * wlan_reg_get_bw_value() - give bandwidth value * bw: bandwidth enum @@ -206,6 +215,9 @@ uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw) return reg_get_bw_value(bw); } +qdf_export_symbol(wlan_reg_get_bw_value); + +#ifdef CONFIG_CHAN_NUM_API /** * wlan_reg_get_bonded_channel_state() - Get 2G bonded channel state * @ch: channel number. @@ -224,6 +236,7 @@ enum channel_state wlan_reg_get_bonded_channel_state( return reg_get_5g_bonded_channel_state(pdev, ch, bw); } +#endif /* CONFIG_CHAN_NUM_API */ /** * wlan_reg_set_dfs_region () - Get the current dfs region @@ -254,6 +267,15 @@ uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country, offset); } +uint8_t wlan_reg_get_opclass_from_freq_width(uint8_t *country, + qdf_freq_t freq, + uint8_t ch_width, + uint16_t behav_limit) +{ + return reg_dmn_get_opclass_from_freq_width(country, freq, ch_width, + behav_limit); +} + void wlan_reg_dmn_print_channels_in_opclass(uint8_t *country, uint8_t opclass) { @@ -280,6 +302,18 @@ uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes, return reg_dmn_get_curr_opclasses(num_classes, class); } +QDF_STATUS +wlan_reg_get_opclass_details(struct wlan_objmgr_pdev *pdev, + struct regdmn_ap_cap_opclass_t *reg_ap_cap, + uint8_t *n_opclasses, + uint8_t max_supp_op_class, + bool global_tbl_lookup) +{ + return reg_get_opclass_details(pdev, reg_ap_cap, n_opclasses, + max_supp_op_class, + global_tbl_lookup); +} + QDF_STATUS wlan_regulatory_init(void) { QDF_STATUS status; @@ -315,7 +349,7 @@ QDF_STATUS wlan_regulatory_init(void) reg_err("failed to register reg psoc obj create handler"); goto unreg_pdev_create; } - + channel_map = channel_map_global; reg_debug("regulatory handlers registered with obj mgr"); return status; @@ -415,7 +449,6 @@ QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc) QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *parent_psoc; - QDF_STATUS status; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; pdev_priv_obj = reg_get_pdev_obj(pdev); @@ -429,12 +462,9 @@ QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev) parent_psoc = wlan_pdev_get_psoc(pdev); - status = reg_send_scheduler_msg_sb(parent_psoc, pdev); - - if (QDF_IS_STATUS_ERROR(status)) - reg_err("scheduler send msg failed"); + reg_send_scheduler_msg_nb(parent_psoc, pdev); - return status; + return QDF_STATUS_SUCCESS; } QDF_STATUS regulatory_pdev_close(struct wlan_objmgr_pdev *pdev) @@ -463,6 +493,7 @@ QDF_STATUS regulatory_pdev_close(struct wlan_objmgr_pdev *pdev) return QDF_STATUS_SUCCESS; } +#ifdef CONFIG_CHAN_NUM_API void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, bool nol_ch) { @@ -476,47 +507,48 @@ void wlan_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch); } -bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) -{ - return reg_is_dfs_ch(pdev, chan); -} - bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { return reg_is_passive_or_disable_ch(pdev, chan); } bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, - uint32_t chan) + uint8_t chan) { return reg_is_disable_ch(pdev, chan); } +#endif /* CONFIG_CHAN_NUM_API */ -uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, - uint32_t freq) +uint8_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) { return reg_freq_to_chan(pdev, freq); } -uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num) +qdf_export_symbol(wlan_reg_freq_to_chan); + +#ifdef CONFIG_CHAN_NUM_API +qdf_freq_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) { return reg_chan_to_freq(pdev, chan_num); } -uint16_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, - uint8_t chan_num) +qdf_export_symbol(wlan_reg_chan_to_freq); + +qdf_freq_t wlan_reg_legacy_chan_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan_num) { return reg_legacy_chan_to_freq(pdev, chan_num); } bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, - uint8_t chan_num) + uint8_t chan_num) { return reg_chan_is_49ghz(pdev, chan_num); } +#endif /* CONFIG_CHAN_NUM_API */ QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev, uint8_t *country) @@ -565,6 +597,7 @@ bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc) return reg_11d_enabled_on_host(psoc); } +#ifdef CONFIG_CHAN_NUM_API bool wlan_reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan_num) { return reg_is_dsrc_chan(pdev, chan_num); @@ -575,6 +608,7 @@ bool wlan_reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, { return reg_is_etsi13_srd_chan(pdev, chan_num); } +#endif /* CONFIG_CHAN_NUM_API */ bool wlan_reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) { @@ -616,10 +650,10 @@ bool wlan_reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc) } QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev, - uint32_t *low_2g, - uint32_t *high_2g, - uint32_t *low_5g, - uint32_t *high_5g) + qdf_freq_t *low_2g, + qdf_freq_t *high_2g, + qdf_freq_t *low_5g, + qdf_freq_t *high_5g) { struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; @@ -651,88 +685,404 @@ QDF_STATUS wlan_reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev, return reg_get_curr_regdomain(pdev, cur_regdmn); } -uint32_t wlan_reg_min_24ghz_ch_num(void) +#ifdef CONFIG_CHAN_NUM_API +uint8_t wlan_reg_min_24ghz_ch_num(void) { return reg_min_24ghz_ch_num(); } -uint32_t wlan_reg_max_24ghz_ch_num(void) +uint8_t wlan_reg_max_24ghz_ch_num(void) { return reg_max_24ghz_ch_num(); } -uint32_t wlan_reg_min_5ghz_ch_num(void) +uint8_t wlan_reg_min_5ghz_ch_num(void) { return reg_min_5ghz_ch_num(); } -uint32_t wlan_reg_max_5ghz_ch_num(void) +uint8_t wlan_reg_max_5ghz_ch_num(void) { return reg_max_5ghz_ch_num(); } +#endif /* CONFIG_CHAN_NUM_API */ + +#ifdef CONFIG_CHAN_FREQ_API +qdf_freq_t wlan_reg_min_24ghz_chan_freq(void) +{ + return reg_min_24ghz_chan_freq(); +} + +qdf_freq_t wlan_reg_max_24ghz_chan_freq(void) +{ + return reg_max_24ghz_chan_freq(); +} -bool wlan_reg_is_24ghz_ch(uint32_t chan) +qdf_freq_t wlan_reg_min_5ghz_chan_freq(void) +{ + return reg_min_5ghz_chan_freq(); +} + +qdf_freq_t wlan_reg_max_5ghz_chan_freq(void) +{ + return reg_max_5ghz_chan_freq(); +} +#endif /* CONFIG_CHAN_FREQ_API */ + +#ifdef CONFIG_CHAN_NUM_API +bool wlan_reg_is_24ghz_ch(uint8_t chan) { return reg_is_24ghz_ch(chan); } -bool wlan_reg_is_5ghz_ch(uint32_t chan) +bool wlan_reg_is_5ghz_ch(uint8_t chan) { return reg_is_5ghz_ch(chan); } +#endif /* CONFIG_CHAN_NUM_API */ -bool wlan_reg_is_24ghz_ch_freq(uint32_t freq) +bool wlan_reg_is_24ghz_ch_freq(qdf_freq_t freq) { return reg_is_24ghz_ch_freq(freq); } -bool wlan_reg_is_5ghz_ch_freq(uint32_t freq) +bool wlan_reg_is_5ghz_ch_freq(qdf_freq_t freq) { return reg_is_5ghz_ch_freq(freq); } -#ifndef CONFIG_LEGACY_CHAN_ENUM -bool wlan_reg_is_49ghz_freq(uint32_t freq) +bool wlan_reg_is_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + return reg_is_freq_indoor(pdev, freq); +} + +#ifdef CONFIG_BAND_6GHZ +bool wlan_reg_is_6ghz_chan_freq(uint16_t freq) +{ + return reg_is_6ghz_chan_freq(freq); +} + +uint16_t wlan_reg_min_6ghz_chan_freq(void) +{ + return reg_min_6ghz_chan_freq(); +} + +uint16_t wlan_reg_max_6ghz_chan_freq(void) +{ + return reg_max_6ghz_chan_freq(); +} + +bool wlan_reg_is_6ghz_psc_chan_freq(uint16_t freq) +{ + return reg_is_6ghz_psc_chan_freq(freq); +} + +#endif /* CONFIG_BAND_6GHZ */ + +uint16_t +wlan_reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list) +{ + if (!pdev) { + reg_err("pdev object is NULL"); + return 0; + } + + return reg_get_band_channel_list(pdev, band_mask, channel_list); +} + +qdf_freq_t wlan_reg_chan_band_to_freq(struct wlan_objmgr_pdev *pdev, + uint8_t chan, uint8_t band_mask) +{ + return reg_chan_band_to_freq(pdev, chan, band_mask); +} + +bool wlan_reg_is_49ghz_freq(qdf_freq_t freq) { return reg_is_49ghz_freq(freq); } -#endif -uint32_t wlan_reg_ch_num(uint32_t ch_enum) +uint8_t wlan_reg_ch_num(uint32_t ch_enum) { return reg_ch_num(ch_enum); } -uint32_t wlan_reg_ch_to_freq(uint32_t ch_enum) +qdf_freq_t wlan_reg_ch_to_freq(uint32_t ch_enum) { return reg_ch_to_freq(ch_enum); } -bool wlan_reg_is_same_band_channels(uint32_t chan_num1, uint32_t chan_num2) +#ifdef CONFIG_CHAN_NUM_API +bool wlan_reg_is_same_band_channels(uint8_t chan_num1, uint8_t chan_num2) { return reg_is_same_band_channels(chan_num1, chan_num2); } -bool wlan_reg_is_channel_valid_5g_sbs(uint32_t curchan, uint32_t newchan) +bool wlan_reg_is_channel_valid_5g_sbs(uint8_t curchan, uint8_t newchan) { return reg_is_channel_valid_5g_sbs(curchan, newchan); } -enum band_info wlan_reg_chan_to_band(uint32_t chan_num) +enum band_info wlan_reg_chan_to_band(uint8_t chan_num) { return reg_chan_to_band(chan_num); } +qdf_export_symbol(wlan_reg_chan_to_band); + /** * wlan_reg_get_chan_enum() - Get channel enum for given channel number * @chan_num: Channel number * * Return: Channel enum */ -enum channel_enum wlan_reg_get_chan_enum(uint32_t chan_num) +enum channel_enum wlan_reg_get_chan_enum(uint8_t chan_num) { return reg_get_chan_enum(chan_num); } +#endif /* CONFIG_CHAN_NUM_API */ + +bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) +{ + return reg_is_regdmn_en302502_applicable(pdev); +} + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified regcap. + * @pdev: pointer to struct wlan_objmgr_pdev + * + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) +{ + return reg_modify_pdev_chan_range(pdev); +} + +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + return reg_disable_chan_coex(pdev, unii_5g_bitmap); +} +#endif + +#ifdef CONFIG_CHAN_FREQ_API +bool wlan_reg_is_same_band_freqs(qdf_freq_t freq1, qdf_freq_t freq2) +{ + return reg_is_same_band_freqs(freq1, freq2); +} + +bool wlan_reg_is_frequency_valid_5g_sbs(qdf_freq_t curfreq, qdf_freq_t newfreq) +{ + return reg_is_frequency_valid_5g_sbs(curfreq, newfreq); +} + +enum channel_enum wlan_reg_get_chan_enum_for_freq(qdf_freq_t freq) +{ + return reg_get_chan_enum_for_freq(freq); +} + +bool wlan_reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_is_etsi13_srd_chan_for_freq(pdev, freq); +} + +bool wlan_reg_is_dsrc_freq(qdf_freq_t freq) +{ + return reg_is_dsrc_freq(freq); +} + +void wlan_reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq_list, + uint8_t num_ch, + bool nol_ch) +{ + reg_update_nol_ch_for_freq(pdev, chan_freq_list, num_ch, nol_ch); +} + +void wlan_reg_update_nol_history_ch_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *ch_list, + uint8_t num_ch, + bool nol_history_ch) +{ + reg_update_nol_history_ch_for_freq(pdev, + ch_list, + num_ch, + nol_history_ch); +} + +bool wlan_reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) +{ + return reg_is_dfs_for_freq(pdev, freq); +} + +bool wlan_reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_is_passive_or_disable_for_freq(pdev, freq); +} + +bool wlan_reg_is_disable_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_is_disable_for_freq(pdev, freq); +} + +QDF_STATUS +wlan_reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev *pdev, + struct channel_power *ch_list, + uint8_t *num_chan) +{ + return reg_get_channel_list_with_power_for_freq(pdev, + ch_list, + num_chan); +} + +bool +wlan_reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_chan_has_dfs_attribute_for_freq(pdev, freq); +} + +enum channel_state +wlan_reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + enum phy_ch_width bw) +{ + return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, bw); +} + +enum channel_state +wlan_reg_get_2g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_freq, + enum phy_ch_width bw) +{ + return reg_get_2g_bonded_channel_state_for_freq(pdev, + freq, + sec_ch_freq, + bw); +} + +void wlan_reg_set_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + qdf_freq_t sec_ch_2g_freq, + struct ch_params *ch_params) +{ + reg_set_channel_params_for_freq(pdev, freq, sec_ch_2g_freq, ch_params); +} + +enum channel_state +wlan_reg_get_channel_state_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_get_channel_state_for_freq(pdev, freq); +} + +uint8_t wlan_reg_get_channel_reg_power_for_freq(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq) +{ + return reg_get_channel_reg_power_for_freq(pdev, freq); +} + +enum reg_wifi_band wlan_reg_freq_to_band(qdf_freq_t freq) +{ + return reg_freq_to_band(freq); +} +qdf_export_symbol(wlan_reg_freq_to_band); + +qdf_freq_t wlan_reg_min_chan_freq(void) +{ + return reg_min_chan_freq(); +} + +qdf_freq_t wlan_reg_max_chan_freq(void) +{ + return reg_max_chan_freq(); +} + +void wlan_reg_freq_width_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + return reg_freq_width_to_chan_op_class(pdev, freq, chan_width, + global_tbl_lookup, + behav_limit, + op_class, + chan_num); +} + +void wlan_reg_freq_width_to_chan_op_class_auto(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t chan_width, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + reg_freq_width_to_chan_op_class_auto(pdev, freq, chan_width, + global_tbl_lookup, + behav_limit, + op_class, + chan_num); +} + +void wlan_reg_freq_to_chan_op_class(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + bool global_tbl_lookup, + uint16_t behav_limit, + uint8_t *op_class, + uint8_t *chan_num) +{ + return reg_freq_to_chan_op_class(pdev, freq, + global_tbl_lookup, + behav_limit, + op_class, + chan_num); +} + +bool wlan_reg_country_opclass_freq_check(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t op_class, + qdf_freq_t chan_freq) +{ + return reg_country_opclass_freq_check(pdev, country, + op_class, chan_freq); +} + +enum channel_state +wlan_reg_get_5g_bonded_channel_and_state_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t freq, + enum phy_ch_width bw, + const + struct bonded_channel_freq + **bonded_chan_ptr_ptr) +{ + /* + * Get channel frequencies and state from regulatory + */ + return reg_get_5g_bonded_channel_for_freq(pdev, freq, bw, + bonded_chan_ptr_ptr); +} + +qdf_export_symbol(wlan_reg_get_5g_bonded_channel_and_state_for_freq); + +#endif /* CONFIG CHAN FREQ API */ + +uint16_t wlan_reg_get_op_class_width(struct wlan_objmgr_pdev *pdev, + uint8_t op_class, + bool global_tbl_lookup) +{ + return reg_get_op_class_width(pdev, op_class, + global_tbl_lookup); +} bool wlan_reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, uint8_t op_class) @@ -740,7 +1090,36 @@ bool wlan_reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, return reg_is_6ghz_op_class(pdev, op_class); } -bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev) +bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc) +{ + return reg_is_6ghz_supported(psoc); +} + +#ifdef HOST_OPCLASS_EXT +qdf_freq_t +wlan_reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev, + const uint8_t country[3], + uint8_t chan, uint8_t op_class, + bool strict) +{ + return reg_country_chan_opclass_to_freq(pdev, country, chan, op_class, + strict); +} +#endif + +uint16_t wlan_reg_chan_opclass_to_freq(uint8_t chan, + uint8_t op_class, + bool global_tbl_lookup) +{ + if (!chan || !op_class) + return 0; + + return reg_chan_opclass_to_freq(chan, op_class, global_tbl_lookup); +} + +#ifdef CONFIG_REG_CLIENT +enum band_info wlan_reg_band_bitmap_to_band_info(uint32_t band_bitmap) { - return reg_is_6ghz_supported(pdev); + return reg_band_bitmap_to_band_info(band_bitmap); } +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c index b42f6ec4523fd00a312a9ccf71d7a33d3f7ce526..7cc643217795d819c5e56eb882ea0bc860ee4b51 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -119,15 +119,15 @@ QDF_STATUS ucfg_reg_get_current_cc(struct wlan_objmgr_pdev *pdev, #ifdef CONFIG_REG_CLIENT QDF_STATUS ucfg_reg_set_band(struct wlan_objmgr_pdev *pdev, - enum band_info band) + uint32_t band_bitmap) { - return reg_set_band(pdev, band); + return reg_set_band(pdev, band_bitmap); } QDF_STATUS ucfg_reg_get_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band) + uint32_t *band_bitmap) { - return reg_get_band(pdev, band); + return reg_get_band(pdev, band_bitmap); } /** @@ -227,13 +227,6 @@ QDF_STATUS ucfg_reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, return reg_enable_dfs_channels(pdev, dfs_enable); } -QDF_STATUS ucfg_reg_get_curr_band(struct wlan_objmgr_pdev *pdev, - enum band_info *band) -{ - return reg_get_curr_band(pdev, band); - -} - void ucfg_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc, void *cbk, void *arg) { @@ -287,6 +280,24 @@ QDF_STATUS ucfg_reg_set_hal_reg_cap(struct wlan_objmgr_psoc *psoc, qdf_export_symbol(ucfg_reg_set_hal_reg_cap); #ifdef DISABLE_CHANNEL_LIST +#ifdef CONFIG_CHAN_FREQ_API +/** + * ucfg_reg_cache_channel_freq_state() - Cache the current state of the channels + * based of the channel center frequency. + * @pdev: The physical dev to cache the channels for + * @channel_list: List of the channels for which states needs to be cached + * @num_channels: Number of channels in the list + * + */ +void ucfg_reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) +{ + reg_cache_channel_freq_state(pdev, channel_list, num_channels); +} +#endif /* CONFIG_CHAN_FREQ_API */ + +#ifdef CONFIG_CHAN_NUM_API /** * ucfg_reg_cache_channel_state() - Cache the current state of the channles * @pdev: The physical dev to cache the channels for @@ -299,18 +310,29 @@ void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, { reg_cache_channel_state(pdev, channel_list, num_channels); } +#endif /* CONFIG_CHAN_NUM_API */ -/** - * ucfg_reg_restore_cached_channels() - Cache the current state of the channles - * @pdev: The physical dev to cache the channels for - */ void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) { reg_restore_cached_channels(pdev); } + +void ucfg_reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + reg_disable_cached_channels(pdev); +} + #endif QDF_STATUS ucfg_set_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc) { return reg_set_ignore_fw_reg_offload_ind(psoc); } + +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS +ucfg_reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap) +{ + return reg_get_unii_5g_bitmap(pdev, bitmap); +} +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_bss_score.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_bss_score.c index dce2b85f6980491e94296cee96c59a476d7589ce..22802dca3b45e1dd899b88f700ef2f359b99aabe 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_bss_score.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_bss_score.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,6 +27,7 @@ #include "wlan_policy_mgr_api.h" #endif #include "wlan_reg_services_api.h" +#include "wlan_crypto_global_api.h" #define SCM_20MHZ_BW_INDEX 0 #define SCM_40MHZ_BW_INDEX 1 @@ -116,10 +118,10 @@ void scm_validate_scoring_config(struct scoring_config *score_cfg) score_cfg->weight_cfg.channel_congestion_weightage + score_cfg->weight_cfg.oce_wan_weightage; - if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) { + if (total_weight > MAX_BSS_SCORE) { scm_err("total weight is greater than %d fallback to default values", - BEST_CANDIDATE_MAX_WEIGHT); + MAX_BSS_SCORE); score_cfg->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE; score_cfg->weight_cfg.ht_caps_weightage = @@ -387,7 +389,7 @@ static int32_t scm_calculate_bandwidth_score( bw_weight_per_idx = score_config->bandwidth_weight_per_index; - if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq)) { cbmode = score_config->cb_mode_24G; if (score_config->vht_24G_cap) is_vht = true; @@ -477,17 +479,13 @@ static int32_t scm_get_congestion_pct(struct scan_cache_entry *entry) */ congestion = SCM_MAX_CHANNEL_UTILIZATION - est_air_time_percentage; - if (!congestion) - congestion = 1; - } else if (util_scan_entry_qbssload(entry)) { + } else if (entry->qbss_chan_load) { ap_load = (entry->qbss_chan_load * BEST_CANDIDATE_MAX_WEIGHT); /* * Calculate ap_load in % from qbss channel load from * 0-255 range */ congestion = qdf_do_div(ap_load, MAX_AP_LOAD); - if (!congestion) - congestion = 1; } return congestion; @@ -653,7 +651,8 @@ static uint32_t scm_get_sta_nss(struct wlan_objmgr_psoc *psoc, * NSS as 2*2. */ - if (policy_mgr_is_chnl_in_diff_band(psoc, bss_channel) && + if (policy_mgr_is_chnl_in_diff_band( + psoc, wlan_chan_to_freq(bss_channel)) && policy_mgr_is_hw_dbs_capable(psoc) && !(policy_mgr_is_hw_dbs_2x2_capable(psoc))) return 1; @@ -674,6 +673,36 @@ static uint32_t scm_get_sta_nss(struct wlan_objmgr_psoc *psoc, } #endif +/** + * scm_calculate_sae_pk_ap_weightage() - Calculate SAE-PK AP weightage + * @entry: bss entry + * @score_params: bss score params + * @sae_pk_cap_present: sae_pk cap presetn in RSNXE capability field + * + * Return: SAE-PK AP weightage score + */ +static uint32_t +scm_calculate_sae_pk_ap_weightage(struct scan_cache_entry *entry, + struct scoring_config *score_params, + bool *sae_pk_cap_present) +{ + uint8_t *rsnxe_ie, *rsnxe_cap, cap_len; + + rsnxe_ie = util_scan_entry_rsnxe(entry); + + rsnxe_cap = wlan_crypto_parse_rsnxe_ie(rsnxe_ie, &cap_len); + + if (!rsnxe_cap) + return 0; + + *sae_pk_cap_present = *rsnxe_cap & WLAN_CRYPTO_RSNX_CAP_SAE_PK; + if (*sae_pk_cap_present) + return score_params->weight_cfg.sae_pk_ap_weightage * + MAX_INDEX_SCORE; + + return 0; +} + int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, struct scan_default_params *params, struct scan_cache_entry *entry, @@ -698,11 +727,14 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, int8_t rssi_pref_5g_rssi_thresh; bool same_bucket = false; bool ap_su_beam_former = false; + uint32_t sae_pk_score = 0; + bool sae_pk_cap_present = 0; struct wlan_ie_vhtcaps *vht_cap; struct scoring_config *score_config; struct weight_config *weight_config; struct wlan_scan_obj *scan_obj; uint32_t sta_nss; + struct wlan_objmgr_pdev *pdev = NULL; scan_obj = wlan_psoc_get_scan_obj(psoc); if (!scan_obj) { @@ -730,7 +762,7 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, weight_config->ht_caps_weightage; score += ht_score; - if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(entry->channel.chan_freq)) { if (score_config->vht_24G_cap) is_vht = true; } else if (score_config->vht_cap) { @@ -787,13 +819,14 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, */ if ((entry->rssi_raw > rssi_pref_5g_rssi_thresh) && !same_bucket) { - if (WLAN_CHAN_IS_5GHZ(entry->channel.chan_idx)) + if (WLAN_REG_IS_5GHZ_CH_FREQ(entry->channel.chan_freq)) band_score = weight_config->chan_band_weightage * WLAN_GET_SCORE_PERCENTAGE( score_config->band_weight_per_index, SCM_BAND_5G_INDEX); - } else if (WLAN_CHAN_IS_2GHZ(entry->channel.chan_idx)) { + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + entry->channel.chan_freq)) { band_score = weight_config->chan_band_weightage * WLAN_GET_SCORE_PERCENTAGE( score_config->band_weight_per_index, @@ -806,10 +839,24 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, score += oce_wan_score; } - sta_nss = scm_get_sta_nss(psoc, entry->channel.chan_idx, + sae_pk_score = scm_calculate_sae_pk_ap_weightage(entry, score_config, + &sae_pk_cap_present); + score += sae_pk_score; + + pdev = wlan_objmgr_get_pdev_by_id(psoc, entry->pdev_id, WLAN_SCAN_ID); + if (!pdev) { + scm_err("pdev is NULL"); + return 0; + } + + sta_nss = scm_get_sta_nss(psoc, + wlan_reg_freq_to_chan( + pdev, + entry->channel.chan_freq), score_config->vdev_nss_24g, score_config->vdev_nss_5g); + wlan_objmgr_pdev_release_ref(pdev, WLAN_SCAN_ID); /* * If station support nss as 2*2 but AP support NSS as 1*1, * this AP will be given half weight compare to AP which are having @@ -825,28 +872,30 @@ int scm_calculate_bss_score(struct wlan_objmgr_psoc *psoc, score_config->beamformee_cap, score_config->cb_mode_24G, score_config->cb_mode_5G, sta_nss); - scm_nofl_debug("Candidate(%pM chan %d): rssi %d HT %d VHT %d HE %d su bfer %d phy %d air time frac %d qbss %d cong_pct %d NSS %d", - entry->bssid.bytes, entry->channel.chan_idx, + scm_nofl_debug("Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d HT %d VHT %d HE %d su bfer %d phy %d air time frac %d qbss %d cong_pct %d NSS %d sae_pk_cap_present %d", + QDF_MAC_ADDR_REF(entry->bssid.bytes), + entry->channel.chan_freq, entry->rssi_raw, util_scan_entry_htcap(entry) ? 1 : 0, util_scan_entry_vhtcap(entry) ? 1 : 0, util_scan_entry_hecap(entry) ? 1 : 0, ap_su_beam_former, entry->phy_mode, entry->air_time_fraction, - entry->qbss_chan_load, congestion_pct, entry->nss); + entry->qbss_chan_load, congestion_pct, entry->nss, + sae_pk_cap_present); - scm_nofl_debug("Scores: prorated_pcnt %d rssi %d pcl %d ht %d vht %d he %d bfee %d bw %d band %d congestion %d nss %d oce wan %d TOTAL %d", + scm_nofl_debug("Scores: prorated_pcnt %d rssi %d pcl %d ht %d vht %d he %d bfee %d bw %d band %d congestion %d nss %d oce wan %d sae_pk %d TOTAL %d", prorated_pcnt, rssi_score, pcl_score, ht_score, vht_score, he_score, beamformee_score, bandwidth_score, band_score, congestion_score, nss_score, oce_wan_score, - score); + sae_pk_score, score); entry->bss_score = score; return score; } -bool scm_get_pcl_weight_of_channel(int channel_id, - struct scan_filter *filter, - int *pcl_chan_weight, - uint8_t *weight_list) +bool scm_get_pcl_weight_of_channel(uint32_t chan_freq, + struct scan_filter *filter, + int *pcl_chan_weight, + uint8_t *weight_list) { int i; bool found = false; @@ -855,7 +904,7 @@ bool scm_get_pcl_weight_of_channel(int channel_id, return found; for (i = 0; i < filter->num_of_pcl_channels; i++) { - if (filter->pcl_channel_list[i] == channel_id) { + if (filter->pcl_freq_list[i] == chan_freq) { *pcl_chan_weight = filter->pcl_weight_list[i]; found = true; break; diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.c index 7e4ea15c8a054a06a877d699446eed8d7530e554..2c6b2a4ffc59366f886ef26a8e0e29307129138e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -53,6 +53,114 @@ #include #include +#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO + +struct channel_list_db *scm_get_rnr_channel_db(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_scan_obj *scan_obj = NULL; + + scan_obj = wlan_psoc_get_scan_obj(psoc); + + if (!scan_obj) + return NULL; + + return &scan_obj->rnr_channel_db; +} + +struct meta_rnr_channel *scm_get_chan_meta(struct wlan_objmgr_psoc *psoc, + uint32_t chan_freq) +{ + int i; + struct channel_list_db *rnr_channel_db; + + if (!psoc || !chan_freq || !wlan_reg_is_6ghz_chan_freq(chan_freq)) + return NULL; + + rnr_channel_db = scm_get_rnr_channel_db(psoc); + if (!rnr_channel_db) + return NULL; + + for (i = 0; i < QDF_ARRAY_SIZE(rnr_channel_db->channel); i++) + if (rnr_channel_db->channel[i].chan_freq == chan_freq) + return &rnr_channel_db->channel[i]; + + return NULL; +} + +static void scm_add_rnr_channel_db(struct wlan_objmgr_psoc *psoc, + struct scan_cache_entry *entry) +{ + uint32_t chan_freq; + uint8_t is_6g_bss, i; + struct meta_rnr_channel *channel; + struct rnr_bss_info *rnr_bss; + struct scan_rnr_node *rnr_node; + + chan_freq = entry->channel.chan_freq; + is_6g_bss = wlan_reg_is_6ghz_chan_freq(chan_freq); + + /* Return if the BSS is not 6G and RNR IE is not present */ + if (!(is_6g_bss || entry->ie_list.rnrie)) + return; + + scm_debug("BSS freq %d BSSID: "QDF_MAC_ADDR_FMT, chan_freq, + QDF_MAC_ADDR_REF(entry->bssid.bytes)); + if (is_6g_bss) { + channel = scm_get_chan_meta(psoc, chan_freq); + if (!channel) { + scm_debug("Failed to get chan Meta freq %d", chan_freq); + return; + } + channel->bss_beacon_probe_count++; + channel->beacon_probe_last_time_found = entry->scan_entry_time; + } + + /* + * If scan entry got RNR IE then loop through all + * entries and increase the BSS count in respective channels + */ + if (!entry->ie_list.rnrie) + return; + + for (i = 0; i < MAX_RNR_BSS; i++) { + rnr_bss = &entry->rnr.bss_info[i]; + /* Skip if entry is not valid */ + if (!rnr_bss->channel_number) + continue; + chan_freq = wlan_reg_chan_opclass_to_freq(rnr_bss->channel_number, + rnr_bss->operating_class, + false); + channel = scm_get_chan_meta(psoc, chan_freq); + if (!channel) { + scm_debug("Failed to get chan Meta freq %d", chan_freq); + continue; + } + channel->bss_beacon_probe_count++; + /* Don't add RNR entry if list is full */ + if (qdf_list_size(&channel->rnr_list) >= WLAN_MAX_RNR_COUNT) { + scm_debug("List is full"); + return; + } + + rnr_node = qdf_mem_malloc(sizeof(struct scan_rnr_node)); + if (!rnr_node) + return; + rnr_node->entry.timestamp = entry->scan_entry_time; + if (!qdf_is_macaddr_zero(&rnr_bss->bssid)) + qdf_mem_copy(&rnr_node->entry.bssid, + &rnr_bss->bssid, + QDF_MAC_ADDR_SIZE); + if (rnr_bss->short_ssid) + rnr_node->entry.short_ssid = rnr_bss->short_ssid; + scm_debug("Add freq %d: "QDF_MAC_ADDR_FMT" short ssid %x", chan_freq, + QDF_MAC_ADDR_REF(rnr_bss->bssid.bytes), + rnr_bss->short_ssid); + qdf_list_insert_back(&channel->rnr_list, + &rnr_node->node); + } +} +#endif + /** * scm_del_scan_node() - API to remove scan node from the list * @list: hash list @@ -183,7 +291,6 @@ static void scm_scan_entry_del(struct scan_dbs *scan_db, return; } scan_node->cookie = 0; - scm_scan_entry_put_ref(scan_db, scan_node, false); } @@ -316,8 +423,8 @@ static void scm_check_and_age_out(struct scan_dbs *scan_db, { if (util_scan_entry_age(node->entry) >= scan_aging_time) { - scm_debug("Aging out BSSID: %pM with age %lu ms", - node->entry->bssid.bytes, + scm_debug("Aging out BSSID: "QDF_MAC_ADDR_FMT" with age %lu ms", + QDF_MAC_ADDR_REF(node->entry->bssid.bytes), util_scan_entry_age(node->entry)); qdf_spin_lock_bh(&scan_db->scan_db_lock); scm_scan_entry_del(scan_db, node); @@ -401,9 +508,9 @@ static QDF_STATUS scm_flush_oldest_entry(struct scan_dbs *scan_db) } if (oldest_node) { - scm_debug("Flush oldest BSSID: %pM with age %lu ms", - oldest_node->entry->bssid.bytes, - util_scan_entry_age(oldest_node->entry)); + scm_debug("Flush oldest BSSID: "QDF_MAC_ADDR_FMT" with age %lu ms", + QDF_MAC_ADDR_REF(oldest_node->entry->bssid.bytes), + util_scan_entry_age(oldest_node->entry)); /* Release ref_cnt taken for oldest_node and delete it */ qdf_spin_lock_bh(&scan_db->scan_db_lock); scm_scan_entry_del(scan_db, oldest_node); @@ -512,8 +619,8 @@ scm_copy_info_from_dup_entry(struct wlan_objmgr_pdev *pdev, scan_params->frm_subtype == MGMT_SUBTYPE_BEACON && !util_scan_is_null_ssid(&scan_params->ssid)) { if (scan_obj->cb.unlink_bss) { - scm_debug("Hidden AP %pM switch to non-hidden SSID, So unlink the entry", - scan_entry->bssid.bytes); + scm_debug("Hidden AP "QDF_MAC_ADDR_FMT" switch to non-hidden SSID, So unlink the entry", + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes)); scan_obj->cb.unlink_bss(pdev, scan_entry); } } @@ -559,37 +666,45 @@ scm_copy_info_from_dup_entry(struct wlan_objmgr_pdev *pdev, if ((scan_params->frm_subtype == MGMT_SUBTYPE_BEACON) && !util_scan_entry_htinfo(scan_params) && !util_scan_entry_ds_param(scan_params) && - (scan_params->channel.chan_idx != scan_entry->channel.chan_idx) && + (scan_params->channel.chan_freq != scan_entry->channel.chan_freq) && (scan_params->rssi_raw < ADJACENT_CHANNEL_RSSI_THRESHOLD)) { - scan_params->channel.chan_idx = scan_entry->channel.chan_idx; + scan_params->channel.chan_freq = scan_entry->channel.chan_freq; scan_params->channel_mismatch = true; } /* Use old value for rssi if beacon was heard on adjacent channel. */ if (scan_params->channel_mismatch) { + scan_params->snr = scan_entry->snr; + scan_params->avg_snr = scan_entry->avg_snr; scan_params->rssi_raw = scan_entry->rssi_raw; scan_params->avg_rssi = scan_entry->avg_rssi; scan_params->rssi_timestamp = scan_entry->rssi_timestamp; } else { - /* If elapsed time since last rssi update for this + /* If elapsed time since last rssi and snr update for this * entry is smaller than a thresold, calculate a - * running average of the RSSI values. - * Otherwise new frames RSSI is more representive + * running average of the RSSI and SNR values. + * Otherwise new frames RSSI and SNR are more representive * of the signal strength. */ time_gap = scan_params->scan_entry_time - scan_entry->rssi_timestamp; - if (time_gap > WLAN_RSSI_AVERAGING_TIME) + if (time_gap > WLAN_RSSI_AVERAGING_TIME) { scan_params->avg_rssi = WLAN_RSSI_IN(scan_params->rssi_raw); + scan_params->avg_snr = + WLAN_SNR_IN(scan_params->snr); + } else { - /* Copy previous average rssi to new entry */ + /* Copy previous average rssi and snr to new entry */ + scan_params->avg_snr = scan_entry->avg_snr; scan_params->avg_rssi = scan_entry->avg_rssi; /* Average with previous samples */ WLAN_RSSI_LPF(scan_params->avg_rssi, - scan_params->rssi_raw); + scan_params->rssi_raw); + WLAN_SNR_LPF(scan_params->avg_snr, + scan_params->snr); } scan_params->rssi_timestamp = scan_params->scan_entry_time; @@ -691,20 +806,22 @@ static QDF_STATUS scm_add_update_entry(struct wlan_objmgr_psoc *psoc, if (scan_params->ie_list.csa || scan_params->ie_list.xcsa || scan_params->ie_list.cswrp) - scm_debug("CSA IE present for BSSID: %pM", - scan_params->bssid.bytes); + scm_debug("CSA IE present for BSSID: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(scan_params->bssid.bytes)); is_dup_found = scm_find_duplicate(pdev, scan_obj, scan_db, scan_params, &dup_node); security_type = scan_params->security_type; - scm_nofl_debug("Received %s: %pM \"%.*s\" chan %d rssi %d tsf_delta %u seq %d phy %d hidden %d mismatch %d %s%s%s%s pdev %d boot_time %llu ns", + scm_nofl_debug("Received %s: "QDF_MAC_ADDR_FMT" \"%.*s\" freq %d rssi %d tsf_delta %u seq %d snr %d phy %d hidden %d mismatch %d %s%s%s%s pdev %d boot_time %llu ns", (scan_params->frm_subtype == MGMT_SUBTYPE_PROBE_RESP) ? - "prb rsp" : "bcn", scan_params->bssid.bytes, + "prb rsp" : "bcn", + QDF_MAC_ADDR_REF(scan_params->bssid.bytes), scan_params->ssid.length, scan_params->ssid.ssid, - scan_params->channel.chan_idx, scan_params->rssi_raw, + scan_params->channel.chan_freq, scan_params->rssi_raw, scan_params->tsf_delta, scan_params->seq_num, - scan_params->phy_mode, scan_params->is_hidden_ssid, + scan_params->snr, scan_params->phy_mode, + scan_params->is_hidden_ssid, scan_params->channel_mismatch, security_type & SCAN_SECURITY_TYPE_WPA ? "[WPA]" : "", security_type & SCAN_SECURITY_TYPE_RSN ? "[RSN]" : "", @@ -801,7 +918,7 @@ QDF_STATUS __scm_handle_bcn_probe(struct scan_bcn_probe_event *bcn) } if (bcn->frm_type == MGMT_SUBTYPE_BEACON && - utils_is_dfs_ch(pdev, bcn->rx_data->channel)) { + wlan_reg_is_dfs_for_freq(pdev, bcn->rx_data->chan_freq)) { util_scan_add_hidden_ssid(pdev, bcn->buf); } @@ -810,8 +927,8 @@ QDF_STATUS __scm_handle_bcn_probe(struct scan_bcn_probe_event *bcn) qdf_nbuf_len(bcn->buf), bcn->frm_type, bcn->rx_data); if (!scan_list || qdf_list_empty(scan_list)) { - scm_debug("failed to unpack %d frame BSSID: %pM", - bcn->frm_type, hdr->i_addr3); + scm_debug("failed to unpack %d frame BSSID: "QDF_MAC_ADDR_FMT, + bcn->frm_type, QDF_MAC_ADDR_REF(hdr->i_addr3)); status = QDF_STATUS_E_INVAL; goto free_nbuf; } @@ -820,8 +937,8 @@ QDF_STATUS __scm_handle_bcn_probe(struct scan_bcn_probe_event *bcn) for (i = 0; i < list_count; i++) { status = qdf_list_remove_front(scan_list, &next_node); if (QDF_IS_STATUS_ERROR(status) || !next_node) { - scm_debug("list remove failure i:%d, lsize:%d, BSSID: %pM", - i, list_count, hdr->i_addr3); + scm_debug("list remove failure i:%d, lsize:%d, BSSID: "QDF_MAC_ADDR_FMT, + i, list_count, QDF_MAC_ADDR_REF(hdr->i_addr3)); status = QDF_STATUS_E_INVAL; goto free_nbuf; } @@ -833,16 +950,28 @@ QDF_STATUS __scm_handle_bcn_probe(struct scan_bcn_probe_event *bcn) if (scan_obj->drop_bcn_on_chan_mismatch && scan_entry->channel_mismatch) { - scm_nofl_debug("Drop frame for chan mismatch %pM Seq Num: %d chan %d RSSI %d", - scan_entry->bssid.bytes, + scm_nofl_debug("Drop frame for chan mismatch "QDF_MAC_ADDR_FMT" Seq Num: %d freq %d RSSI %d", + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes), + scan_entry->seq_num, + scan_entry->channel.chan_freq, + scan_entry->rssi_raw); + util_scan_free_cache_entry(scan_entry); + qdf_mem_free(scan_node); + continue; + } + /* Do not add invalid channel entry as kernel will reject it */ + if (scan_obj->drop_bcn_on_invalid_freq && + wlan_reg_is_disable_for_freq(pdev, + scan_entry->channel.chan_freq)) { + scm_nofl_debug("Drop frame for invalid freq %d: "QDF_MAC_ADDR_FMT" Seq Num: %d RSSI %d", + scan_entry->channel.chan_freq, + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes), scan_entry->seq_num, - scan_entry->channel.chan_idx, scan_entry->rssi_raw); util_scan_free_cache_entry(scan_entry); qdf_mem_free(scan_node); continue; } - if (scan_obj->cb.update_beacon) scan_obj->cb.update_beacon(pdev, scan_entry); @@ -851,8 +980,8 @@ QDF_STATUS __scm_handle_bcn_probe(struct scan_bcn_probe_event *bcn) status = scm_add_update_entry(psoc, pdev, scan_entry); if (QDF_IS_STATUS_ERROR(status)) { - scm_debug("failed to add entry for BSSID: %pM Seq Num: %d", - scan_entry->bssid.bytes, + scm_debug("failed to add entry for BSSID: "QDF_MAC_ADDR_FMT" Seq Num: %d", + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes), scan_entry->seq_num); util_scan_free_cache_entry(scan_entry); qdf_mem_free(scan_node); @@ -916,16 +1045,15 @@ static void scm_list_insert_sorted(struct wlan_objmgr_psoc *psoc, scm_err("wlan_scan_psoc_get_def_params failed"); return; } - if (filter->num_of_pcl_channels > 0 && (scan_node->entry->rssi_raw > SCM_PCL_RSSI_THRESHOLD)) { if (scm_get_pcl_weight_of_channel( - scan_node->entry->channel.chan_idx, + scan_node->entry->channel.chan_freq, filter, &pcl_chan_weight, filter->pcl_weight_list)) { - scm_debug("pcl channel %d pcl_chan_weight %d", - scan_node->entry->channel.chan_idx, - pcl_chan_weight); + scm_debug("pcl freq %d pcl_chan_weight %d", + scan_node->entry->channel.chan_freq, + pcl_chan_weight); } } if (params->is_bssid_hint_priority && @@ -963,7 +1091,6 @@ static void scm_list_insert_sorted(struct wlan_objmgr_psoc *psoc, if (!cur_lst) qdf_list_insert_back(scan_list, &scan_node->node); - } /** @@ -1294,21 +1421,22 @@ QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev, * scm_filter_channels() - Remove entries not belonging to channel list * @scan_db: scan db * @db_node: node on which filters are applied - * @chan_list: valid channel list + * @chan_freq_list: valid channel frequency (in MHz) list * @num_chan: number of channels * * Return: QDF_STATUS */ -static void scm_filter_channels(struct scan_dbs *scan_db, - struct scan_cache_node *db_node, - uint8_t *chan_list, uint32_t num_chan) +static void scm_filter_channels(struct wlan_objmgr_pdev *pdev, + struct scan_dbs *scan_db, + struct scan_cache_node *db_node, + uint32_t *chan_freq_list, uint32_t num_chan) { int i; bool match = false; for (i = 0; i < num_chan; i++) { - if (chan_list[i] == - util_scan_entry_channel_num(db_node->entry)) { + if (chan_freq_list[i] == util_scan_entry_channel_frequency( + db_node->entry)) { match = true; break; } @@ -1322,7 +1450,7 @@ static void scm_filter_channels(struct scan_dbs *scan_db, } void scm_filter_valid_channel(struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, uint32_t num_chan) + uint32_t *chan_freq_list, uint32_t num_chan) { int i; struct wlan_objmgr_psoc *psoc; @@ -1353,8 +1481,8 @@ void scm_filter_valid_channel(struct wlan_objmgr_pdev *pdev, cur_node = scm_get_next_node(scan_db, &scan_db->scan_hash_tbl[i], NULL); while (cur_node) { - scm_filter_channels(scan_db, - cur_node, chan_list, num_chan); + scm_filter_channels(pdev, scan_db, + cur_node, chan_freq_list, num_chan); next_node = scm_get_next_node(scan_db, &scan_db->scan_hash_tbl[i], cur_node); cur_node = next_node; @@ -1412,7 +1540,6 @@ QDF_STATUS scm_db_init(struct wlan_objmgr_psoc *psoc) qdf_list_create(&scan_db->scan_hash_tbl[j], MAX_SCAN_CACHE_SIZE); } - return QDF_STATUS_SUCCESS; } @@ -1443,6 +1570,146 @@ QDF_STATUS scm_db_deinit(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO +QDF_STATUS scm_channel_list_db_init(struct wlan_objmgr_psoc *psoc) +{ + uint32_t i, j; + uint32_t min_freq, max_freq; + struct channel_list_db *rnr_channel_db; + + min_freq = wlan_reg_min_6ghz_chan_freq(); + max_freq = wlan_reg_max_6ghz_chan_freq(); + + scm_info("min_freq %d max_freq %d", min_freq, max_freq); + i = min_freq; + rnr_channel_db = scm_get_rnr_channel_db(psoc); + if (!rnr_channel_db) + return QDF_STATUS_E_INVAL; + + for (j = 0; j < QDF_ARRAY_SIZE(rnr_channel_db->channel); j++) { + if (i >= min_freq && i <= max_freq) + rnr_channel_db->channel[j].chan_freq = i; + i += 20; + /* init list for all to avoid uninitialized list */ + qdf_list_create(&rnr_channel_db->channel[j].rnr_list, + WLAN_MAX_RNR_COUNT); + } + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS scm_channel_list_db_deinit(struct wlan_objmgr_psoc *psoc) +{ + int i; + qdf_list_node_t *cur_node, *next_node; + struct meta_rnr_channel *channel; + struct scan_rnr_node *rnr_node; + struct channel_list_db *rnr_channel_db; + + rnr_channel_db = scm_get_rnr_channel_db(psoc); + if (!rnr_channel_db) + return QDF_STATUS_E_INVAL; + + for (i = 0; i < QDF_ARRAY_SIZE(rnr_channel_db->channel); i++) { + channel = &rnr_channel_db->channel[i]; + channel->chan_freq = 0; + channel->beacon_probe_last_time_found = 0; + channel->bss_beacon_probe_count = 0; + channel->saved_profile_count = 0; + cur_node = NULL; + qdf_list_peek_front(&channel->rnr_list, &cur_node); + while (cur_node) { + next_node = NULL; + qdf_list_peek_next(&channel->rnr_list, cur_node, + &next_node); + rnr_node = qdf_container_of(cur_node, + struct scan_rnr_node, + node); + qdf_list_remove_node(&channel->rnr_list, + &rnr_node->node); + qdf_mem_free(rnr_node); + cur_node = next_node; + next_node = NULL; + } + qdf_list_destroy(&channel->rnr_list); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS scm_rnr_db_flush(struct wlan_objmgr_psoc *psoc) +{ + int i; + qdf_list_node_t *cur_node, *next_node; + struct meta_rnr_channel *channel; + struct scan_rnr_node *rnr_node; + struct channel_list_db *rnr_channel_db; + + rnr_channel_db = scm_get_rnr_channel_db(psoc); + if (!rnr_channel_db) + return QDF_STATUS_E_INVAL; + + for (i = 0; i < QDF_ARRAY_SIZE(rnr_channel_db->channel); i++) { + channel = &rnr_channel_db->channel[i]; + cur_node = NULL; + qdf_list_peek_front(&channel->rnr_list, &cur_node); + while (cur_node) { + next_node = NULL; + qdf_list_peek_next(&channel->rnr_list, cur_node, + &next_node); + rnr_node = qdf_container_of(cur_node, + struct scan_rnr_node, + node); + qdf_list_remove_node(&channel->rnr_list, + &rnr_node->node); + qdf_mem_free(rnr_node); + cur_node = next_node; + next_node = NULL; + } + /* Reset beacon info */ + channel->beacon_probe_last_time_found = 0; + channel->bss_beacon_probe_count = 0; + } + + return QDF_STATUS_SUCCESS; +} + +void scm_update_rnr_from_scan_cache(struct wlan_objmgr_pdev *pdev) +{ + uint8_t i; + struct scan_dbs *scan_db; + struct scan_cache_node *cur_node; + struct scan_cache_node *next_node = NULL; + struct wlan_objmgr_psoc *psoc; + struct scan_cache_entry *entry; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + scm_err("psoc is NULL"); + return; + } + scan_db = wlan_pdev_get_scan_db(psoc, pdev); + if (!scan_db) { + scm_err("scan_db is NULL"); + return; + } + + for (i = 0 ; i < SCAN_HASH_SIZE; i++) { + cur_node = scm_get_next_node(scan_db, + &scan_db->scan_hash_tbl[i], NULL); + while (cur_node) { + entry = cur_node->entry; + scm_add_rnr_channel_db(psoc, entry); + next_node = + scm_get_next_node(scan_db, + &scan_db->scan_hash_tbl[i], + cur_node); + cur_node = next_node; + next_node = NULL; + } + } +} +#endif + QDF_STATUS scm_update_scan_mlme_info(struct wlan_objmgr_pdev *pdev, struct scan_cache_entry *entry) { @@ -1515,7 +1782,7 @@ QDF_STATUS scm_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev, entry = cur_node->entry; if (qdf_is_macaddr_equal(&bss_info->bssid, &entry->bssid) && (util_is_ssid_match(&bss_info->ssid, &entry->ssid)) && - (bss_info->chan == entry->channel.chan_idx)) { + (bss_info->freq == entry->channel.chan_freq)) { /* Acquire db lock to prevent simultaneous update */ qdf_spin_lock_bh(&scan_db->scan_db_lock); qdf_mem_copy(&entry->mlme_info, mlme, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.h index 7d4e658217136c318edbb0517a2624a9191c1ab4..54140085ee014699ed22f940735a63e76504dce0 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,8 +35,6 @@ (((const uint8_t *)(addr))[QDF_MAC_ADDR_SIZE - 1] % SCAN_HASH_SIZE) #define SCM_PCL_RSSI_THRESHOLD -75 -#define BEST_CANDIDATE_MAX_BSS_SCORE 10000 - #define ADJACENT_CHANNEL_RSSI_THRESHOLD -80 /** @@ -145,7 +144,7 @@ QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev, * scm_filter_valid_channel() - The Public API to filter scan result * based on valid channel list * @pdev: pdev object - * @chan_list: valid channel list + * @chan_freq_list: valid channel frequency (in MHz) list * @num_chan: number of valid channels * * The Public API to to filter scan result @@ -154,7 +153,7 @@ QDF_STATUS scm_flush_results(struct wlan_objmgr_pdev *pdev, * Return: void. */ void scm_filter_valid_channel(struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, uint32_t num_chan); + uint32_t *chan_freq_list, uint32_t num_chan); /** * scm_iterate_scan_db() - function to iterate scan table @@ -199,6 +198,71 @@ QDF_STATUS scm_db_init(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS scm_db_deinit(struct wlan_objmgr_psoc *psoc); +#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO + +/** + * scm_get_rnr_channel_db() - API to get rnr db + * @psoc: psoc + * + * Return: rnr db + */ +struct channel_list_db *scm_get_rnr_channel_db(struct wlan_objmgr_psoc *psoc); + +/** + * scm_get_chan_meta() - API to return channel meta + * @psoc: psoc + * @freq: channel frequency + * + * Return: channel meta information + */ +struct meta_rnr_channel *scm_get_chan_meta(struct wlan_objmgr_psoc *psoc, + uint32_t chan_freq); + +/** + * scm_channel_list_db_init() - API to init scan list priority list db + * @psoc: psoc + * + * Return: QDF_STATUS + */ +QDF_STATUS scm_channel_list_db_init(struct wlan_objmgr_psoc *psoc); + +/** + * scm_channel_list_db_deinit() - API to deinit scan list priority list db + * @psoc: psoc + * + * Return: QDF_STATUS + */ +QDF_STATUS scm_channel_list_db_deinit(struct wlan_objmgr_psoc *psoc); + +/** + * scm_rnr_db_flush() - API to flush rnr entries + * @psoc: psoc + * + * Return: QDF_STATUS + */ +QDF_STATUS scm_rnr_db_flush(struct wlan_objmgr_psoc *psoc); + +/** + * scm_update_rnr_from_scan_cache() - API to update rnr info from scan cache + * @pdev: pdev + * + * Return: void + */ +void scm_update_rnr_from_scan_cache(struct wlan_objmgr_pdev *pdev); + +#else +static inline QDF_STATUS scm_channel_list_db_init(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS scm_channel_list_db_deinit(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * scm_validate_scoring_config() - validate score config * @score_cfg: config to be validated diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db_i.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db_i.h index d0c91c4e2e1594bd4cd660a42fa474a2d814f899..690dad03d531167fcb95c3de61742fbd66d2820b 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_cache_db_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -117,7 +117,7 @@ wlan_pdev_get_scan_db(struct wlan_objmgr_psoc *psoc, /** * scm_get_pcl_weight_of_channel() - Get PCL weight if channel is present in pcl - * @channel_id: channel of bss + * @chan_freq: channel frequency of bss, unit: MHz * @filter: filter * @pcl_chan_weight: Get PCL weight for corresponding channel * @weight_list: Weight list for all the pcl channels. @@ -126,8 +126,8 @@ wlan_pdev_get_scan_db(struct wlan_objmgr_psoc *psoc, * * Return: true or false */ -bool scm_get_pcl_weight_of_channel(int channel_id, - struct scan_filter *filter, - int *pcl_chan_weight, - uint8_t *weight_list); +bool scm_get_pcl_weight_of_channel(uint32_t chan_freq, + struct scan_filter *filter, + int *pcl_chan_weight, + uint8_t *weight_list); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c index 4581289d75c2b8f77ce8f2355e69e0d1a50af5c6..bbde9124c273ac2920a6b1b5c6d113d8ec97faa5 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -295,8 +295,9 @@ scm_check_pmf_match(struct scan_filter *filter, match = false; if (!match) - scm_debug("%pM : PMF cap didn't match (filter %d AP %d)", - db_entry->bssid.bytes, filter->pmf_cap, + scm_debug(QDF_MAC_ADDR_FMT" : PMF cap didn't match (filter %d AP %d)", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes), + filter->pmf_cap, ap_pmf_cap); return match; @@ -398,7 +399,8 @@ static bool scm_is_rsn_security(struct scan_filter *filter, if (!security) return false; if (!util_scan_entry_rsn(db_entry)) { - scm_debug("%pM : doesn't have RSN IE", db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : doesn't have RSN IE", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } status = wlan_parse_rsn_ie(util_scan_entry_rsn(db_entry), &rsn); @@ -415,15 +417,15 @@ static bool scm_is_rsn_security(struct scan_filter *filter, match = scm_is_cipher_match(rsn.pwise_cipher_suites, rsn.pwise_cipher_count, WLAN_RSN_SEL(cipher_type)); if (!match) { - scm_debug("%pM : pairwise cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : pairwise cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } match = scm_is_rsn_mcast_cipher_match(&rsn, filter, &neg_mccipher); if (!match) { - scm_debug("%pM : mcast cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : mcast cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -673,8 +675,8 @@ static bool scm_is_rsn_security(struct scan_filter *filter, } if (!match) { - scm_debug("%pM : akm suites didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : akm suites didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -768,8 +770,8 @@ static bool scm_is_wpa_security(struct scan_filter *filter, if (!security) return false; if (!util_scan_entry_wpa(db_entry)) { - scm_debug("%pM : AP doesn't have WPA IE", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : AP doesn't have WPA IE", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -787,15 +789,15 @@ static bool scm_is_wpa_security(struct scan_filter *filter, match = scm_is_cipher_match(wpa.uc_ciphers, wpa.uc_cipher_count, WLAN_WPA_SEL(cipher_type)); if (!match) { - scm_debug("%pM : unicase cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : unicase cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } match = scm_is_wpa_mcast_cipher_match(&wpa, filter, &neg_mccipher); if (!match) { - scm_debug("%pM : mcast cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : mcast cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -845,7 +847,8 @@ static bool scm_is_wpa_security(struct scan_filter *filter, } if (!match) - scm_debug("%pM : akm didn't match", db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : akm didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); if (match) { security->auth_type = neg_auth; @@ -877,8 +880,8 @@ static bool scm_is_wapi_security(struct scan_filter *filter, if (!security) return false; if (!util_scan_entry_wapi(db_entry)) { - scm_debug("%pM : mcast cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : mcast cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -890,8 +893,8 @@ static bool scm_is_wapi_security(struct scan_filter *filter, match = scm_is_cipher_match(wapi.uc_cipher_suites, wapi.uc_cipher_count, WLAN_WAPI_SEL(cipher_type)); if (!match) { - scm_debug("%pM : unicast cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : unicast cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -905,8 +908,8 @@ static bool scm_is_wapi_security(struct scan_filter *filter, break; } if (!match) { - scm_debug("%pM : mcast cipher didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : mcast cipher didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } neg_mccipher = filter->mc_enc_type[i]; @@ -920,8 +923,8 @@ static bool scm_is_wapi_security(struct scan_filter *filter, wapi.akm_suite_count, WLAN_WAPI_SEL(WLAN_WAI_PSK))) { neg_auth = WLAN_AUTH_TYPE_WAPI_WAI_PSK; } else { - scm_debug("%pM : akm is not supported", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : akm is not supported", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } @@ -934,8 +937,8 @@ static bool scm_is_wapi_security(struct scan_filter *filter, } if (!match) - scm_debug("%pM : akm suite didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : akm suite didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); if (match) { security->auth_type = neg_auth; security->mc_enc = neg_mccipher; @@ -1034,6 +1037,7 @@ static bool scm_is_fils_config_match(struct scan_filter *filter, int i; struct fils_indication_ie *indication_ie; uint8_t *data; + uint8_t *end_ptr; if (!filter->fils_scan_filter.realm_check) return true; @@ -1045,14 +1049,19 @@ static bool scm_is_fils_config_match(struct scan_filter *filter, indication_ie = (struct fils_indication_ie *) db_entry->ie_list.fils_indication; + end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2; + data = indication_ie->variable_data; - if (indication_ie->is_cache_id_present) + if (indication_ie->is_cache_id_present && + (data + CACHE_IDENTIFIER_LEN) <= end_ptr) data += CACHE_IDENTIFIER_LEN; - if (indication_ie->is_hessid_present) + if (indication_ie->is_hessid_present && + (data + HESSID_LEN) <= end_ptr) data += HESSID_LEN; - for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) { + for (i = 1; i <= indication_ie->realm_identifiers_cnt && + (data + REAM_HASH_LEN) <= end_ptr; i++) { if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm, data, REAM_HASH_LEN)) return true; @@ -1170,7 +1179,9 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc, */ if (!match && util_scan_entry_is_hidden_ap(db_entry)) { for (i = 0; i < filter->num_of_auth; i++) { - if (filter->auth_type[i] == WLAN_AUTH_TYPE_OWE) { + if (filter->auth_type[i] == WLAN_AUTH_TYPE_OWE && + util_is_bssid_match(&filter->bssid_hint, + &db_entry->bssid)) { match = true; break; } @@ -1194,9 +1205,9 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc, match = false; for (i = 0; i < filter->num_of_channels; i++) { - if (!filter->channel_list[i] || ( - (filter->channel_list[i] == - db_entry->channel.chan_idx))) { + if (!filter->chan_freq_list[i] || + filter->chan_freq_list[i] == + db_entry->channel.chan_freq) { match = true; break; } @@ -1212,14 +1223,15 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc, if (!filter->ignore_auth_enc_type && !scm_is_security_match(filter, db_entry, security)) { - scm_debug("%pM : Ignore as security profile didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : Ignore as security profile didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } if (!util_is_bss_type_match(filter->bss_type, db_entry->cap_info)) { - scm_debug("%pM : Ignore as bss type didn't match cap_info %x bss_type %d", - db_entry->bssid.bytes, db_entry->cap_info.value, + scm_debug(QDF_MAC_ADDR_FMT" : Ignore as bss type didn't match cap_info %x bss_type %d", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes), + db_entry->cap_info.value, filter->bss_type); return false; } @@ -1229,31 +1241,31 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc, if (filter->only_wmm_ap && !db_entry->ie_list.wmeinfo && !db_entry->ie_list.wmeparam) { - scm_debug("%pM : Ignore as required wmeinfo and wme params not present", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : Ignore as required wmeinfo and wme params not present", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } /* Match realm */ if (!scm_is_fils_config_match(filter, db_entry)) { - scm_debug("%pM :Ignore as fils config didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" :Ignore as fils config didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } cc_ie = util_scan_entry_country(db_entry); if (!util_country_code_match(filter->country, cc_ie)) { - scm_debug("%pM : Ignore as country %.*s didn't match", - db_entry->bssid.bytes, 2, filter->country); + scm_debug(QDF_MAC_ADDR_FMT" : Ignore as country %.*s didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes), + 2, filter->country); return false; } if (!util_mdie_match(filter->mobility_domain, (struct rsn_mdie *)db_entry->ie_list.mdie)) { - scm_debug("%pM : Ignore as mdie didn't match", - db_entry->bssid.bytes); + scm_debug(QDF_MAC_ADDR_FMT" : Ignore as mdie didn't match", + QDF_MAC_ADDR_REF(db_entry->bssid.bytes)); return false; } - return true; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_main.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_main.h index 33b55a4e8c894914e002e8573a7eeec7612b1d3c..26ea25e967bd94f55cac45bb0a3852819e054bad 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_main.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +30,7 @@ #include #include "wlan_scan_cache_db.h" #include "wlan_scan_11d.h" +#include "wlan_scan_cfg.h" #define scm_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_SCAN, params) @@ -89,6 +90,9 @@ #define SCAN_P2P_SCAN_MAX_BURST_DURATION (240) #define SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS (6) +/* MAX RNR entries per channel*/ +#define WLAN_MAX_RNR_COUNT 15 + /** * struct probe_time_dwell_time - probe time, dwell time map * @dwell_time: dwell time @@ -112,19 +116,6 @@ struct probe_time_dwell_time { #define SCM_NUM_RSSI_CAT 15 #define SCAN_STA_MIRACAST_MCC_REST_TIME 400 -#ifndef CONFIG_MCL -#define MAX_SCAN_CACHE_SIZE 1024 -#define SCAN_MAX_REST_TIME 0 -#define SCAN_MIN_REST_TIME 50 -#define SCAN_BURST_DURATION 0 -#define SCAN_PROBE_SPACING_TIME 0 -#define SCAN_PROBE_DELAY 0 -#define SCAN_MAX_SCAN_TIME 50000 -#define SCAN_NETWORK_IDLE_TIMEOUT 200 -#define HIDDEN_SSID_TIME (0xFFFFFFFF) -#define SCAN_CHAN_STATS_EVENT_ENAB (true) -#endif - #define SCAN_TIMEOUT_GRACE_PERIOD 10 #define SCAN_MAX_BSS_PDEV 100 #define SCAN_PRIORITY SCAN_PRIORITY_LOW @@ -143,6 +134,21 @@ struct probe_time_dwell_time { */ #define SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME 0x4 +/* Indicate to scan all PSC channel */ +#define SCAN_FLAG_EXT_6GHZ_SCAN_ALL_PSC_CH 0x8 + +/* Indicate to scan all NON-PSC channel */ +#define SCAN_FLAG_EXT_6GHZ_SCAN_ALL_NON_PSC_CH 0x10 + +/* Indicate to save scan result matching hint from scan client */ +#define SCAN_FLAG_EXT_6GHZ_MATCH_HINT 0x20 + +/* Skip any channel on which RNR information is not received */ +#define SCAN_FLAG_EXT_6GHZ_SKIP_NON_RNR_CH 0x40 + +/* Indicate client hint req is high priority than FW rnr or FILS discovery */ +#define SCAN_FLAG_EXT_6GHZ_CLIENT_HIGH_PRIORITY 0x80 + /* Passive dwell time if bt_a2dp is enabled. Time in msecs*/ #define PASSIVE_DWELL_TIME_BT_A2DP_ENABLED 28 @@ -238,6 +244,7 @@ struct scan_vdev_obj { * @pno_wake_lock: pno wake lock * @pno_cb: callback to call on PNO completion * @mawc_params: Configuration parameters for NLO MAWC. + * @user_config_sched_scan_plan: if enabled set user confing sched scan plan */ struct pno_def_config { bool pno_offload_enabled; @@ -256,9 +263,11 @@ struct pno_def_config { qdf_wake_lock_t pno_wake_lock; struct cb_handler pno_cb; struct nlo_mawc_params mawc_params; + bool user_config_sched_scan_plan; }; #endif +#ifdef FEATURE_WLAN_EXTSCAN /** * struct extscan_def_config - def configuration for EXTSCAN * @extscan_enabled: enable extscan @@ -274,6 +283,7 @@ struct extscan_def_config { uint32_t extscan_active_max_chn_time; uint32_t extscan_active_min_chn_time; }; +#endif /** * struct scan_default_params - default scan parameters to be used @@ -283,6 +293,8 @@ struct extscan_def_config { * @skip_dfs_chan_in_p2p_search: Skip DFS channels in p2p search. * @use_wake_lock_in_user_scan: if wake lock will be acquired during user scan * @active_dwell_2g: default active dwell time for 2G channels, if it's not zero + * @active_dwell_6g: default active dwell time for 6G channels + * @passive_dwell_6g: default passive dwell time for 6G channels * @passive_dwell:default passive dwell time * @max_rest_time: default max rest time * @sta_miracast_mcc_rest_time: max rest time for miracast and mcc @@ -308,6 +320,7 @@ struct extscan_def_config { * @max_bss_per_pdev: maximum number of bss entries to be maintained per pdev * @max_active_scans_allowed: maximum number of active parallel scan allowed * per psoc + * @scan_mode_6g: scan mode in 6Ghz * @enable_connected_scan: enable scans after connection * @scan_priority: default scan priority * @adaptive_dwell_time_mode: adaptive dwell mode with connection @@ -365,6 +378,8 @@ struct scan_default_params { bool skip_dfs_chan_in_p2p_search; bool use_wake_lock_in_user_scan; uint32_t active_dwell_2g; + uint32_t active_dwell_6g; + uint32_t passive_dwell_6g; uint32_t passive_dwell; uint32_t max_rest_time; uint32_t sta_miracast_mcc_rest_time; @@ -393,6 +408,7 @@ struct scan_default_params { uint8_t p2p_scan_burst_duration; uint8_t go_scan_burst_duration; uint8_t ap_scan_burst_duration; + enum scan_mode_6ghz scan_mode_6g; bool enable_connected_scan; enum scan_priority scan_priority; enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode; @@ -482,8 +498,12 @@ struct scan_cb { * @miracast_enabled: miracast enabled * @disable_timeout: command timeout disabled * @drop_bcn_on_chan_mismatch: drop bcn if channel mismatch + * @drop_bcn_on_invalid_freq: drop bcn if freq is invalid in IEs (DS/HT/HE) * @scan_start_request_buff: buffer used to pass * scan config to event handlers + * @rnr_channel_db: RNR channel list database + * @allow_bss_with_incomplete_ie: Continue scan entry even if any corrupted IES + * are present. */ struct wlan_scan_obj { uint32_t scan_disabled; @@ -507,7 +527,12 @@ struct wlan_scan_obj { bool miracast_enabled; bool disable_timeout; bool drop_bcn_on_chan_mismatch; + bool drop_bcn_on_invalid_freq; struct scan_start_request scan_start_request_buff; +#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO + struct channel_list_db rnr_channel_db; +#endif + bool allow_bss_with_incomplete_ie; }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c index 9f2293c07054ae62475abb1bd847907de754fd3c..f39ee60c17e7d7e0ae3e06f695beb7cbcedacf04 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +34,19 @@ #include #endif #include +#include + +/* Beacon/probe weightage multiplier */ +#define BCN_PROBE_WEIGHTAGE 5 + +/* Saved profile weightage multiplier */ +#define SAVED_PROFILE_WEIGHTAGE 10 + +/* maximum number of 6ghz hints can be sent per scan request */ +#define MAX_HINTS_PER_SCAN_REQ 15 + +/* maximum number of hints can be sent per 6ghz channel */ +#define MAX_HINTS_PER_CHANNEL 4 QDF_STATUS scm_scan_free_scan_request_mem(struct scan_start_request *req) @@ -548,7 +560,7 @@ int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) return burst_duration; } -#define SCM_ACTIVE_DWELL_TIME_NAN 40 +#define SCM_ACTIVE_DWELL_TIME_NAN 60 #define SCM_ACTIVE_DWELL_TIME_SAP 40 /** @@ -614,16 +626,39 @@ static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, req->scan_req.adaptive_dwell_time_mode = scan_obj->scan_def.adaptive_dwell_time_mode_nc; /* - * If AP/GO is active and has connected clients set min rest time - * same as max rest time, so that firmware spends more time on home - * channel which will increase the probability of sending beacon at TBTT + * If AP/GO is active and has connected clients : + * 1.set min rest time same as max rest time, so that + * firmware spends more time on home channel which will + * increase the probability of sending beacon at TBTT + * 2.if DBS is supported and SAP is not on 2g, + * do not reset active dwell time for 2g. + */ + + /* + * For SAP, the dwell time cannot exceed 32 ms as it can't go + * offchannel more than 32 ms. For Go, since we + * advertise NOA, GO can have regular dwell time which is 40 ms. */ if ((ap_present && sap_peer_count) || (go_present && go_peer_count)) { - req->scan_req.dwell_time_active_2g = 0; + if ((policy_mgr_is_hw_dbs_capable(psoc) && + policy_mgr_is_sap_go_on_2g(psoc)) || + !policy_mgr_is_hw_dbs_capable(psoc)) { + if (ap_present) + req->scan_req.dwell_time_active_2g = + QDF_MIN(req->scan_req.dwell_time_active, + (SCAN_CTS_DURATION_MS_MAX - + SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); + else + req->scan_req.dwell_time_active_2g = 0; + } req->scan_req.min_rest_time = req->scan_req.max_rest_time; } + if (policy_mgr_current_concurrency_is_mcc(psoc)) + req->scan_req.min_rest_time = + scan_obj->scan_def.conc_max_rest_time; + /* * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell * time for 2g channels instead of dwell_time_active_2g @@ -683,11 +718,14 @@ static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, break; } - if (ndi_present) { + if (go_present && sta_active) { req->scan_req.burst_duration = - scm_scan_get_burst_duration( - req->scan_req.dwell_time_active, - scan_obj->miracast_enabled); + req->scan_req.dwell_time_active; + break; + } + + if (ndi_present || (p2p_cli_present && sta_active)) { + req->scan_req.burst_duration = 0; break; } } while (0); @@ -710,34 +748,42 @@ static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, } if (ap_present) { - uint8_t ap_chan; + uint16_t ap_chan_freq; struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); - ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); + ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); /* * P2P/STA scan while SoftAP is sending beacons. * Max duration of CTS2self is 32 ms, which limits the - * dwell time. If DBS is supported and if SAP is on 2G channel - * then keep passive dwell time default. + * dwell time. + * If DBS is supported and: + * 1.if SAP is on 2G channel then keep passive + * dwell time default. + * 2.if SAP is on 5G/6G channel then update dwell time active. */ if (sap_peer_count) { - req->scan_req.dwell_time_active = - QDF_MIN(req->scan_req.dwell_time_active, - (SCAN_CTS_DURATION_MS_MAX - + if (policy_mgr_is_hw_dbs_capable(psoc) && + (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) { + req->scan_req.dwell_time_active = + QDF_MIN(req->scan_req.dwell_time_active, + (SCAN_CTS_DURATION_MS_MAX - SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); + } if (!policy_mgr_is_hw_dbs_capable(psoc) || (policy_mgr_is_hw_dbs_capable(psoc) && - WLAN_CHAN_IS_5GHZ(ap_chan))) { + WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) { req->scan_req.dwell_time_passive = req->scan_req.dwell_time_active; } } + if (scan_obj->scan_def.ap_scan_burst_duration) { req->scan_req.burst_duration = scan_obj->scan_def.ap_scan_burst_duration; } else { req->scan_req.burst_duration = 0; - if (utils_is_dfs_ch(pdev, ap_chan)) + if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq)) req->scan_req.burst_duration = SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * req->scan_req.dwell_time_active; @@ -746,8 +792,7 @@ static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, if (ndi_present) { req->scan_req.dwell_time_active = - QDF_MIN(req->scan_req.dwell_time_active, - SCM_ACTIVE_DWELL_TIME_NAN); + SCM_ACTIVE_DWELL_TIME_NAN; req->scan_req.dwell_time_active_2g = QDF_MIN(req->scan_req.dwell_time_active_2g, SCM_ACTIVE_DWELL_TIME_NAN); @@ -815,6 +860,262 @@ static inline void scm_scan_chlist_concurrency_modify( } #endif +#ifdef CONFIG_BAND_6GHZ +static void +scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, + struct chan_list *chan_list, + struct wlan_scan_obj *scan_obj) +{ + uint8_t i; + struct regulatory_channel *chan_list_6g; + bool psc_channel_found = false; + bool channel_6g_found = false; + uint8_t num_scan_channels = 0, channel_count; + struct wlan_objmgr_pdev *pdev; + uint32_t freq; + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) + return; + + scm_debug("6g scan mode %d", scan_obj->scan_def.scan_mode_6g); + for (i = 0; i < chan_list->num_chan; i++) { + freq = chan_list->chan[i].freq; + if ((scan_obj->scan_def.scan_mode_6g == + SCAN_MODE_6G_NO_CHANNEL) && + (wlan_reg_is_6ghz_chan_freq(freq))) { + /* Drop the 6Ghz channels */ + continue; + } else if ((scan_obj->scan_def.scan_mode_6g == + SCAN_MODE_6G_PSC_CHANNEL) && + (wlan_reg_is_6ghz_chan_freq(freq))) { + /* Allow only PSC channels */ + if (wlan_reg_is_6ghz_psc_chan_freq(freq)) + psc_channel_found = true; + else + continue; + } else if ((scan_obj->scan_def.scan_mode_6g == + SCAN_MODE_6G_ALL_CHANNEL) && + (wlan_reg_is_6ghz_chan_freq(freq))) { + /* Allow any 6ghz channel */ + channel_6g_found = true; + } + chan_list->chan[num_scan_channels++] = + chan_list->chan[i]; + } + + scm_debug("psc_channel_found %d channel_6g_found%d", + psc_channel_found, channel_6g_found); + if ((scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_PSC_CHANNEL && + !psc_channel_found) || + (scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_ALL_CHANNEL && + !channel_6g_found)) { + chan_list_6g = qdf_mem_malloc(NUM_6GHZ_CHANNELS * + sizeof(struct regulatory_channel)); + if (!chan_list_6g) + goto end; + + /* Add the 6Ghz channels based on config*/ + channel_count = wlan_reg_get_band_channel_list(pdev, + BIT(REG_BAND_6G), + chan_list_6g); + scm_debug("Number of 6G channels %d", channel_count); + for (i = 0; i < channel_count; i++) { + if ((scan_obj->scan_def.scan_mode_6g == + SCAN_MODE_6G_PSC_CHANNEL) && + (!psc_channel_found) && + wlan_reg_is_6ghz_psc_chan_freq(chan_list_6g[i]. + center_freq)) { + chan_list->chan[num_scan_channels++].freq = + chan_list_6g[i].center_freq; + } else if ((scan_obj->scan_def.scan_mode_6g == + SCAN_MODE_6G_ALL_CHANNEL) && + (!channel_6g_found)) { + chan_list->chan[num_scan_channels++].freq = + chan_list_6g[i].center_freq; + } + } + qdf_mem_free(chan_list_6g); + } +end: + chan_list->num_chan = num_scan_channels; +} +#else +static void +scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, + struct chan_list *chan_list, + struct wlan_scan_obj *scan_obj) +{ +} +#endif + +#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO +static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, + struct chan_list *chan_list) +{ + uint8_t i, j = 0, max, tmp_list_count; + struct meta_rnr_channel *channel; + struct chan_info temp_list[MAX_6GHZ_CHANNEL]; + struct rnr_chan_weight *rnr_chan_info, temp; + uint32_t weight; + struct wlan_objmgr_psoc *psoc; + + rnr_chan_info = qdf_mem_malloc(sizeof(rnr_chan_info) * MAX_6GHZ_CHANNEL); + if (!rnr_chan_info) + return; + + for (i = 0; i < chan_list->num_chan; i++) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_list->chan[i].freq)) + temp_list[j++].freq = chan_list->chan[i].freq; + } + tmp_list_count = j; + scm_debug("Total 6ghz channels %d", tmp_list_count); + + /* No Need to sort if the 6ghz channels are less than one */ + if (tmp_list_count < 1) { + qdf_mem_free(rnr_chan_info); + return; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + scm_err("Psoc is NULL"); + return; + } + + /* compute the weightage */ + for (i = 0, j = 0; i < tmp_list_count; i++) { + channel = scm_get_chan_meta(psoc, temp_list[i].freq); + if (!channel) + continue; + weight = channel->bss_beacon_probe_count * BCN_PROBE_WEIGHTAGE + + channel->saved_profile_count * SAVED_PROFILE_WEIGHTAGE; + rnr_chan_info[j].weight = weight; + rnr_chan_info[j].chan_freq = temp_list[i].freq; + j++; + scm_debug("Freq %d weight %d bcn_cnt %d", temp_list[i].freq, + weight, channel->bss_beacon_probe_count); + } + + /* Sort the channel using selection sort - descending order */ + for (i = 0; i < tmp_list_count - 1; i++) { + max = i; + for (j = i + 1; j < tmp_list_count; j++) { + if (rnr_chan_info[j].weight > + rnr_chan_info[max].weight) + max = j; + } + if (max != i) { + qdf_mem_copy(&temp, &rnr_chan_info[max], + sizeof(*rnr_chan_info)); + qdf_mem_copy(&rnr_chan_info[max], &rnr_chan_info[i], + sizeof(*rnr_chan_info)); + qdf_mem_copy(&rnr_chan_info[i], &temp, + sizeof(*rnr_chan_info)); + } + } + + /* update the 6g list based on the weightage */ + for (i = 0, j = 0; (i < NUM_CHANNELS && j < tmp_list_count); i++) { + if (wlan_reg_is_6ghz_chan_freq(chan_list->chan[i].freq)) + chan_list->chan[i].freq = rnr_chan_info[j++].chan_freq; + } + qdf_mem_free(rnr_chan_info); +} + +static void scm_update_rnr_info(struct wlan_objmgr_psoc *psoc, + struct scan_start_request *req) +{ + uint8_t i, num_bssid = 0, num_ssid = 0; + uint8_t total_count = MAX_HINTS_PER_SCAN_REQ; + uint32_t freq; + struct meta_rnr_channel *chan; + qdf_list_node_t *cur_node, *next_node = NULL; + struct scan_rnr_node *rnr_node; + struct chan_list *chan_list; + QDF_STATUS status; + + if (!req) + return; + + chan_list = &req->scan_req.chan_list; + for (i = 0; i < chan_list->num_chan; i++) { + freq = chan_list->chan[i].freq; + + chan = scm_get_chan_meta(psoc, freq); + if (!chan) { + scm_debug("Failed to get meta, freq %d", freq); + continue; + } + if (qdf_list_empty(&chan->rnr_list)) + continue; + + qdf_list_peek_front(&chan->rnr_list, &cur_node); + while (cur_node && total_count) { + rnr_node = qdf_container_of(cur_node, + struct scan_rnr_node, + node); + if (!qdf_is_macaddr_zero(&rnr_node->entry.bssid) && + req->scan_req.num_hint_bssid < + WLAN_SCAN_MAX_HINT_BSSID) { + qdf_mem_copy(&req->scan_req.hint_bssid[num_bssid++].bssid, + &rnr_node->entry.bssid, + QDF_MAC_ADDR_SIZE); + req->scan_req.num_hint_bssid++; + total_count--; + } else if (rnr_node->entry.short_ssid && + req->scan_req.num_hint_s_ssid < + WLAN_SCAN_MAX_HINT_S_SSID) { + req->scan_req.hint_s_ssid[num_ssid++].short_ssid = + rnr_node->entry.short_ssid; + req->scan_req.num_hint_s_ssid++; + total_count--; + } + status = qdf_list_peek_next(&chan->rnr_list, cur_node, + &next_node); + if (QDF_IS_STATUS_ERROR(status)) + break; + cur_node = next_node; + next_node = NULL; + } + } +} + +static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev, + struct scan_start_request *req) +{ + struct wlan_objmgr_psoc *psoc; + struct channel_list_db *rnr_db; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return; + rnr_db = scm_get_rnr_channel_db(psoc); + if (!rnr_db) + return; + + rnr_db->scan_count++; + if (rnr_db->scan_count >= RNR_UPDATE_SCAN_CNT_THRESHOLD) { + rnr_db->scan_count = 0; + scm_rnr_db_flush(psoc); + scm_update_rnr_from_scan_cache(pdev); + } + + scm_update_rnr_info(psoc, req); +} + +#else +static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev, + struct chan_list *chan_list) +{ +} + +static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev, + struct scan_start_request *req) +{ +} +#endif + /** * scm_update_channel_list() - update scan req params depending on dfs inis * and initial scan request. @@ -834,6 +1135,7 @@ scm_update_channel_list(struct scan_start_request *req, bool first_scan_done = true; bool p2p_search = false; bool skip_dfs_ch = true; + uint32_t first_freq; pdev = wlan_vdev_get_pdev(req->vdev); @@ -854,10 +1156,11 @@ scm_update_channel_list(struct scan_start_request *req, * No need to update channels if req is single channel* ie ROC, * Preauth or a single channel scan etc. * If the single chan in the scan channel list is an NOL channel,it is - * not removed as it would reduce the number of scan channels to 0 - * and FW would scan all chans which is unexpected in this scenerio. + * removed and it would reduce the number of scan channels to 0. */ - if (req->scan_req.chan_list.num_chan == 1) + first_freq = req->scan_req.chan_list.chan[0].freq; + if ((req->scan_req.chan_list.num_chan == 1) && + (!utils_dfs_is_freq_in_nol(pdev, first_freq))) return; /* do this only for STA and P2P-CLI mode */ @@ -878,9 +1181,7 @@ scm_update_channel_list(struct scan_start_request *req, freq = req->scan_req.chan_list.chan[i].freq; if (skip_dfs_ch && - wlan_reg_chan_has_dfs_attribute(pdev, - wlan_reg_freq_to_chan( - pdev, freq))) { + wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) { scm_nofl_debug("Skip DFS freq %d", freq); continue; } @@ -892,7 +1193,15 @@ scm_update_channel_list(struct scan_start_request *req, req->scan_req.chan_list.chan[num_scan_channels++] = req->scan_req.chan_list.chan[i]; } + req->scan_req.chan_list.num_chan = num_scan_channels; + /* Dont upadte the channel list for SAP mode */ + if (wlan_vdev_mlme_get_opmode(req->vdev) != QDF_SAP_MODE) { + scm_update_6ghz_channel_list(req->vdev, + &req->scan_req.chan_list, + scan_obj); + scm_sort_6ghz_channel_list(req->vdev, &req->scan_req.chan_list); + } scm_scan_chlist_concurrency_modify(req->vdev, req); } @@ -1022,6 +1331,8 @@ scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, else if (!req->scan_req.chan_list.num_chan) ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); + if (scan_obj->scan_def.scan_mode_6g != SCAN_MODE_6G_NO_CHANNEL) + scm_add_rnr_info(pdev, req); scm_update_channel_list(req, scan_obj); } @@ -1034,9 +1345,10 @@ static inline void scm_print_scan_req_info(struct scan_req_params *req) struct chan_list *chan_lst; #define MAX_SCAN_FREQ_TO_PRINT 60 - scm_nofl_debug("Scan start: scan id %d vdev %d Dwell time: act %d pass %d act_2G %d, probe time %d n_probes %d flags %x ext_flag %x events %x policy %d wide_bw %d pri %d", + scm_nofl_debug("Scan start: scan id %d vdev %d Dwell time: act %d pass %d act_2G %d act_6G %d pass_6G %d, probe time %d n_probes %d flags %x ext_flag %x events %x policy %d wide_bw %d pri %d", req->scan_id, req->vdev_id, req->dwell_time_active, req->dwell_time_passive, req->dwell_time_active_2g, + req->dwell_time_active_6g, req->dwell_time_passive_6g, req->repeat_probe_time, req->n_probes, req->scan_flags, req->scan_ctrl_flags_ext, req->scan_events, req->scan_policy_type, req->scan_f_wide_band, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_cfg.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_cfg.h index 49a3d09e42cb48a0cc7891638bddce6806bec49f..175a3beccbb1121496cc9c6abfe9501641fc7eca 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_cfg.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,6 +24,19 @@ #include "cfg_define.h" +/** + * enum scan_mode_6ghz - scan mode for 6GHz + * @SCAN_MODE_6G_NO_CHANNEL: Remove 6GHz channels in the scan request + * @SCAN_MODE_6G_PSC_CHANNEL: Allow/Add 6Ghz PSC channels to scan request + * @SCAN_MODE_6G_ALL_CHANNEL: Allow all the 6Ghz channels + */ +enum scan_mode_6ghz { + SCAN_MODE_6G_NO_CHANNEL, + SCAN_MODE_6G_PSC_CHANNEL, + SCAN_MODE_6G_ALL_CHANNEL, + SCAN_MODE_6G_MAX = SCAN_MODE_6G_ALL_CHANNEL, +}; + /* * * drop_bcn_on_chan_mismatch - drop the beacon for chan mismatch @@ -45,6 +58,27 @@ true,\ "drop bcn on channel mismatch") +/* + * + * drop_bcn_on_invalid_freq - drop the beacon or probe resp with invalid freq + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to decide whether to drop the beacon/probe resp or not + * if channel received in DS param, HT info and HE IE is invalid. + * + * Related: None + * + * Usage: External + * + * + */ +#define CFG_DROP_BCN_ON_INVALID_FREQ CFG_INI_BOOL(\ + "drop_bcn_on_invalid_freq",\ + true,\ + "drop bcn on invalid freq in HT, DS, HE IE") + /* * * gActiveMaxChannelTime - Set max channel time for active scan @@ -63,7 +97,7 @@ */ #define CFG_ACTIVE_MAX_CHANNEL_TIME CFG_INI_UINT(\ "gActiveMaxChannelTime",\ - 0, 10000, MCL_OR_WIN_VALUE(40, 105),\ + 0, 10000, PLATFORM_VALUE(40, 105),\ CFG_VALUE_OR_DEFAULT, "active dwell time") /* @@ -125,9 +159,51 @@ */ #define CFG_ACTIVE_MAX_2G_CHANNEL_TIME CFG_INI_UINT(\ "active_max_channel_time_2g",\ - 0, 10000, MCL_OR_WIN_VALUE(80, 0),\ + 0, 10000, PLATFORM_VALUE(80, 0),\ CFG_VALUE_OR_DEFAULT, "active dwell time for 2G channels") +/* + * + * active_max_channel_time_6g - Set max time for active 6G channel scan + * @Min: 0 + * @Max: 10000 + * @Default: 40 + * + * This ini is used to set maximum time in msecs spent in active 6G channel scan + * + * + * Related: None + * + * Usage: External + * + * + */ +#define CFG_ACTIVE_MAX_6G_CHANNEL_TIME CFG_INI_UINT(\ + "active_max_channel_time_6g",\ + 0, 10000, 40,\ + CFG_VALUE_OR_DEFAULT, "active dwell time for 6G channels") + +/* + * + * passive_max_channel_time_6g - Set max time for passive 6G channel scan + * @Min: 0 + * @Max: 10000 + * @Default: 30 + * + * This ini is used to set maximum time in msecs spent in passive 6G chan scan + * + * + * Related: None + * + * Usage: External + * + * + */ +#define CFG_PASSIVE_MAX_6G_CHANNEL_TIME CFG_INI_UINT(\ + "passive_max_channel_time_6g",\ + 0, 10000, 30,\ + CFG_VALUE_OR_DEFAULT, "passive dwell time for 6G channels") + /* * * gPassiveMaxChannelTime - Set max channel time for passive scan @@ -146,7 +222,7 @@ */ #define CFG_PASSIVE_MAX_CHANNEL_TIME CFG_INI_UINT(\ "gPassiveMaxChannelTime",\ - 0, 10000, MCL_OR_WIN_VALUE(110, 300),\ + 0, 10000, PLATFORM_VALUE(110, 300),\ CFG_VALUE_OR_DEFAULT, "passive dwell time") /* @@ -161,7 +237,7 @@ */ #define CFG_SCAN_NUM_PROBES CFG_INI_UINT(\ "gScanNumProbes",\ - 0, 20, MCL_OR_WIN_VALUE(0, 2),\ + 0, 20, PLATFORM_VALUE(0, 2),\ CFG_VALUE_OR_DEFAULT,\ "number of probes on each channel") @@ -185,7 +261,7 @@ */ #define CFG_SCAN_PROBE_REPEAT_TIME CFG_INI_UINT(\ "gScanProbeRepeatTime",\ - 0, 30, MCL_OR_WIN_VALUE(20, 50),\ + 0, 50, PLATFORM_VALUE(20, 50),\ CFG_VALUE_OR_DEFAULT,\ "probe repeat time on each channel") @@ -217,7 +293,7 @@ */ #define CFG_ADAPTIVE_SCAN_DWELL_MODE CFG_INI_UINT(\ "hostscan_adaptive_dwell_mode",\ - 0, 4, MCL_OR_WIN_VALUE(2, 0),\ + 0, 4, PLATFORM_VALUE(2, 0),\ CFG_VALUE_OR_DEFAULT,\ "Enable adaptive dwell mode") @@ -249,7 +325,7 @@ */ #define CFG_ADAPTIVE_SCAN_DWELL_MODE_NC CFG_INI_UINT(\ "hostscan_adaptive_dwell_mode_no_conn",\ - 0, 4, MCL_OR_WIN_VALUE(4, 0),\ + 0, 4, PLATFORM_VALUE(4, 0),\ CFG_VALUE_OR_DEFAULT,\ "Enable adaptive dwell mode without connection") @@ -307,6 +383,30 @@ "Set priority for connection with bssid_hint") #ifdef FEATURE_WLAN_SCAN_PNO +/* + * + * g_user_config_sched_scan_plan - set user config sched scan plans. + * @Min: 0 + * @Max:1 + * @Default: 1 + * + * This ini is used to decide if user config number of sched scan plan needs to + * be configured or only one sched scan plan needs to be configured. + * If this ini is enabled then user config number of sched scan plans will be + * configured else only one sched scan plan will be configured. + * + * Supported Feature: PNO scan + * + * Usage: External + * + * + */ + +#define CFG_USER_CONFIG_SCHED_SCAN_PLAN CFG_INI_BOOL(\ + "g_user_config_sched_scan_plan",\ + true, \ + "set user config sched scan plans") + /* * * g_max_sched_scan_plan_iterations - pno sched max scan plan iterations. @@ -632,7 +732,7 @@ * mawc_nlo_enabled - For NLO/PNO, enable MAWC based scan * @Min: 0 * @Max: 1 - * @Default: 1 + * @Default: 0 * * Enable/Disable the Motion Aided Wireless Connectivity * based NLO using this parameter @@ -645,7 +745,7 @@ */ #define CFG_MAWC_NLO_ENABLED CFG_INI_BOOL( \ "mawc_nlo_enabled", \ - 1, \ + 0, \ "Enable MAWC based scan") /* @@ -737,7 +837,8 @@ CFG(CFG_MAWC_NLO_ENABLED) \ CFG(CFG_MAWC_NLO_EXP_BACKOFF_RATIO) \ CFG(CFG_MAWC_NLO_INIT_SCAN_INTERVAL) \ - CFG(CFG_MAWC_NLO_MAX_SCAN_INTERVAL) + CFG(CFG_MAWC_NLO_MAX_SCAN_INTERVAL) \ + CFG(CFG_USER_CONFIG_SCHED_SCAN_PLAN) #else #define CFG_SCAN_PNO @@ -763,7 +864,7 @@ */ #define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC CFG_INI_UINT(\ "gActiveMaxChannelTimeConc",\ - 0, 10000, MCL_OR_WIN_VALUE(40, 0),\ + 0, 10000, PLATFORM_VALUE(40, 0),\ CFG_VALUE_OR_DEFAULT, \ "active scan time in STA+SAP concurrent") @@ -787,7 +888,7 @@ */ #define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC CFG_INI_UINT(\ "gPassiveMaxChannelTimeConc",\ - 0, 10000, MCL_OR_WIN_VALUE(110, 0),\ + 0, 10000, PLATFORM_VALUE(110, 0),\ CFG_VALUE_OR_DEFAULT, \ "Set priority for connection with bssid_hint") @@ -810,7 +911,7 @@ */ #define CFG_MAX_REST_TIME_CONC CFG_INI_UINT(\ "nRestTimeConc",\ - 0, 10000, MCL_OR_WIN_VALUE(100, 0),\ + 0, 10000, PLATFORM_VALUE(100, 0),\ CFG_VALUE_OR_DEFAULT, \ "Rest time before moving to a new channel") @@ -835,7 +936,7 @@ */ #define CFG_MIN_REST_TIME_CONC CFG_INI_UINT(\ "min_rest_time_conc",\ - 0, 50, MCL_OR_WIN_VALUE(50, 0),\ + 0, 50, PLATFORM_VALUE(50, 0),\ CFG_VALUE_OR_DEFAULT, \ "minimum time spent on home channel") @@ -890,7 +991,7 @@ */ #define CFG_IDLE_TIME_CONC CFG_INI_UINT(\ "gIdleTimeConc",\ - 0, 25, MCL_OR_WIN_VALUE(25, 0),\ + 0, 25, PLATFORM_VALUE(25, 0),\ CFG_VALUE_OR_DEFAULT, \ "data inactivity time on bss channel") @@ -1147,8 +1248,60 @@ false,\ "Enable/Disable SNR Monitoring") +/* + * + * scan_mode_6ghz - 6ghz Scan mode + * @Min: 0 + * @Max: 2 + * @Default: 2 + * + * Configure the 6Ghz scan mode + * 0 - Remove 6GHz channels in the scan request + * 1 - Allow/Add 6Ghz PSC channels to scan request + * 2 - Allow all the 6Ghz channels + * + * Related: SCAN + * + * Usage: Internal/External + * + * + */ +#define CFG_6GHZ_SCAN_MODE CFG_INI_UINT( \ + "scan_mode_6ghz", \ + SCAN_MODE_6G_NO_CHANNEL, \ + SCAN_MODE_6G_MAX, \ + PLATFORM_VALUE(SCAN_MODE_6G_PSC_CHANNEL, \ + SCAN_MODE_6G_ALL_CHANNEL), \ + CFG_VALUE_OR_DEFAULT, \ + "6ghz scan mode") + +/* + * + * scan_allow_bss_with_corrupted_ie - Continue scan even if corrupted IEs are + * present. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to continue scan even if corrupted IEs are present. If this + * ini is enable, the scan module skips the IEs following corrupted IEs(IE's + * with invalid len) and adds the scan entry without completely dropping the + * frame. + * + * Related: scan + * + * Usage: External + * + * + */ +#define CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE CFG_INI_BOOL( \ + "scan_allow_bss_with_corrupted_ie", \ + false, \ + "scan allow bss with corrupted ie") + #define CFG_SCAN_ALL \ CFG(CFG_DROP_BCN_ON_CHANNEL_MISMATCH) \ + CFG(CFG_DROP_BCN_ON_INVALID_FREQ) \ CFG(CFG_ENABLE_WAKE_LOCK_IN_SCAN) \ CFG(CFG_ACTIVE_MAX_CHANNEL_TIME) \ CFG(CFG_ENABLE_DFS_SCAN) \ @@ -1156,6 +1309,8 @@ CFG(CFG_INITIAL_NO_DFS_SCAN) \ CFG(CFG_ACTIVE_MAX_2G_CHANNEL_TIME) \ CFG(CFG_PASSIVE_MAX_CHANNEL_TIME) \ + CFG(CFG_ACTIVE_MAX_6G_CHANNEL_TIME) \ + CFG(CFG_PASSIVE_MAX_6G_CHANNEL_TIME) \ CFG(CFG_SCAN_NUM_PROBES) \ CFG(CFG_SCAN_PROBE_REPEAT_TIME) \ CFG(CFG_ADAPTIVE_SCAN_DWELL_MODE) \ @@ -1176,6 +1331,8 @@ CFG(CFG_ENABLE_SNR_MONITORING) \ CFG(CFG_AP_SCAN_BURST_DURATION) \ CFG(CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH) \ + CFG(CFG_6GHZ_SCAN_MODE) \ + CFG(CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE) \ CFG_SCAN_PNO #endif /* __CONFIG_SCAN_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 10f5feebcc04cbf75b85400ae1d7385f782b9068..bba10550cf9205b1c6e2bcfe26c15bf0e5ed3afb 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,13 +29,16 @@ #include #include #include +#include typedef uint16_t wlan_scan_requester; typedef uint32_t wlan_scan_id; +#define WLAN_SCAN_MAX_HINT_S_SSID 10 +#define WLAN_SCAN_MAX_HINT_BSSID 10 +#define MAX_RNR_BSS 5 #define WLAN_SCAN_MAX_NUM_SSID 16 #define WLAN_SCAN_MAX_NUM_BSSID 4 -#define WLAN_SCAN_MAX_NUM_CHANNELS 68 #define SCM_CANCEL_SCAN_WAIT_TIME 50 #define SCM_CANCEL_SCAN_WAIT_ITERATION 600 @@ -68,14 +71,12 @@ typedef uint32_t wlan_scan_id; #define CHANNEL_CONGESTION_WEIGHTAGE 5 #define OCE_WAN_WEIGHTAGE 0 #define BEST_CANDIDATE_MAX_WEIGHT 100 +#define MAX_BSS_SCORE 200 #define MAX_INDEX_SCORE 100 #define MAX_INDEX_PER_INI 4 +#define SAE_PK_AP_WEIGHTAGE 3 -#ifdef CONFIG_MCL -#define MAX_BCN_PROBE_IN_SCAN_QUEUE 150 -#else -#define MAX_BCN_PROBE_IN_SCAN_QUEUE 2000 -#endif +#define BEST_CANDIDATE_MAX_BSS_SCORE (MAX_BSS_SCORE * 100) #define WLAN_GET_BITS(_val, _index, _num_bits) \ (((_val) >> (_index)) & ((1 << (_num_bits)) - 1)) @@ -89,6 +90,7 @@ typedef uint32_t wlan_scan_id; WLAN_GET_BITS(value32, (8 * (bw_index)), 8) #define WLAN_SET_SCORE_PERCENTAGE(value32, score_pcnt, bw_index) \ WLAN_SET_BITS(value32, (8 * (bw_index)), 8, score_pcnt) +#define TBTT_INFO_COUNT 16 /* forward declaration */ struct wlan_objmgr_vdev; @@ -97,15 +99,15 @@ struct wlan_objmgr_psoc; /** * struct channel_info - BSS channel information - * @chan_idx: current operating channel index + * @chan_freq: channel frequency * @cfreq0: channel frequency index0 * @cfreq1: channel frequency index1 * @priv: channel private information */ struct channel_info { - uint8_t chan_idx; - uint8_t cfreq0; - uint8_t cfreq1; + uint32_t chan_freq; + uint32_t cfreq0; + uint32_t cfreq1; void *priv; }; @@ -156,12 +158,16 @@ struct element_info { * @cswrp: pointer to channel switch announcement wrapper ie * @widebw: pointer to wide band channel switch sub ie * @txpwrenvlp: pointer to tx power envelop sub ie + * @hecap: pointer to hecap ie + * @hecap_6g: pointer to he 6ghz cap ie * @srp: pointer to spatial reuse parameter sub extended ie * @fils_indication: pointer to FILS indication ie * @esp: pointer to ESP indication ie * @mbo_oce: pointer to mbo/oce indication ie + * @rnrie: reduced neighbor report IE * @adaptive_11r: pointer to adaptive 11r IE * @single_pmk: Pointer to sae single pmk IE + * @rsnxe: Pointer to rsnxe IE */ struct ie_list { uint8_t *tim; @@ -203,15 +209,18 @@ struct ie_list { uint8_t *secchanoff; uint8_t *mdie; uint8_t *hecap; + uint8_t *hecap_6g; uint8_t *heop; uint8_t *srp; uint8_t *fils_indication; uint8_t *esp; uint8_t *mbo_oce; uint8_t *muedca; + uint8_t *rnrie; uint8_t *extender; uint8_t *adaptive_11r; uint8_t *single_pmk; + uint8_t *rsnxe; }; enum scan_entry_connection_state { @@ -242,12 +251,12 @@ struct mlme_info { /** * struct bss_info - information required to uniquely define a bss - * @chan: bss operating primary channel index + * @freq: freq of operating primary channel * @ssid: ssid of bss * @bssid: bssid of bss */ struct bss_info { - uint8_t chan; + uint32_t freq; struct wlan_ssid ssid; struct qdf_mac_addr bssid; }; @@ -285,6 +294,82 @@ struct scan_mbssid_info { uint8_t trans_bssid[QDF_MAC_ADDR_SIZE]; }; +/** + * struct rnr_bss_info - Reduced Neighbor Report BSS information + * @neighbor_ap_tbtt_offset: Neighbor AP TBTT offset + * @channel_number: channel number + * @operating_class: operting class + * @bssid: BSS MAC address + * @short_ssid: short ssid + * @bss_params: BSS parameters + */ +struct rnr_bss_info { + uint8_t neighbor_ap_tbtt_offset; + uint32_t channel_number; + uint32_t operating_class; + struct qdf_mac_addr bssid; + uint32_t short_ssid; + uint8_t bss_params; +}; + +/** + * struct tbtt_information_header - TBTT information header + * @tbbt_info_fieldtype: TBTT information field type + * @filter_neighbor_ap: filtered neighbor ap + * @tbbt_info_count: TBTT information count + * @tbtt_info_length: TBTT informaiton length + */ +struct tbtt_information_header { + uint16_t tbbt_info_fieldtype:2; + uint16_t filtered_neighbor_ap:1; + uint16_t reserved:1; + uint16_t tbtt_info_count:4; + uint16_t tbtt_info_length:8; +}; + +/** + * struct neighbor_ap_info_field - Neighbor information field + * @tbtt_info_header: TBTT information header + * @operting_class: operating class + * @channel_number: channel number + */ +struct neighbor_ap_info_field { + struct tbtt_information_header tbtt_header; + uint8_t operting_class; + uint8_t channel_number; +}; + +/** + * enum tbtt_information_field - TBTT information field + * @TBTT_NEIGHBOR_AP_OFFSET_ONLY: TBTT information field type + * @TBTT_NEIGHBOR_AP_BSS_PARAM: neighbor AP and bss param + * @TBTT_NEIGHBOR_AP_SHORTSSID: neighbor AP and Short ssid + * @TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM: neighbor AP, short ssid and bss param + * @TBTT_NEIGHBOR_AP_BSSID: neighbor AP and bssid + * @TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM: neighbor AP, bssid and bss param + * @TBTT_NEIGHBOR_AP_BSSSID_S_SSID: neighbor AP, bssid and short ssid + * @TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM: neighbor AP, bssid, short ssid + * and bss params + */ +enum tbtt_information_field { + TBTT_NEIGHBOR_AP_OFFSET_ONLY = 1, + TBTT_NEIGHBOR_AP_BSS_PARAM = 2, + TBTT_NEIGHBOR_AP_SHORTSSID = 5, + TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM = 6, + TBTT_NEIGHBOR_AP_BSSID = 7, + TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM = 8, + TBTT_NEIGHBOR_AP_BSSSID_S_SSID = 11, + TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM = 12 +}; + +/** + * struct reduced_neighbor_report - Reduced Neighbor Report + * @bss_info: RNR BSS Information + */ +struct reduced_neighbor_report { + struct rnr_bss_info bss_info[MAX_RNR_BSS]; +}; + #define SCAN_SECURITY_TYPE_WEP 0x01 #define SCAN_SECURITY_TYPE_WPA 0x02 #define SCAN_SECURITY_TYPE_WAPI 0x04 @@ -300,8 +385,10 @@ struct scan_mbssid_info { * @security_type: security supported * @seq_num: sequence number * @phy_mode: Phy mode of the AP - * @avg_rssi: Average RSSI fof the AP + * @avg_rssi: Average RSSI of the AP * @rssi_raw: The rssi of the last beacon/probe received + * @snr: The snr of the last beacon/probe received + * @avg_snr: Average SNR of the AP * @bcn_int: Beacon interval of the AP * @cap_info: Capability of the AP * @tsf_info: TSF info @@ -317,6 +404,7 @@ struct scan_mbssid_info { * @hidden_ssid_timestamp: boottime in microsec when hidden * ssid was received * @mbssid_info: Multi bssid information + * @rnr: Reduced neighbor report information * @channel: channel info on which AP is present * @channel_mismatch: if channel received in metadata * doesnot match the one in beacon @@ -330,6 +418,7 @@ struct scan_mbssid_info { * @alt_wcn_ie: alternate WCN IE * @ie_list: IE list pointers * @raw_frame: contain raw frame and the length of the raw frame + * @pdev_id: pdev id */ struct scan_cache_entry { uint8_t frm_subtype; @@ -342,6 +431,8 @@ struct scan_cache_entry { enum wlan_phymode phy_mode; int32_t avg_rssi; int8_t rssi_raw; + uint8_t snr; + uint32_t avg_snr; uint16_t bcn_int; union wlan_capability cap_info; union { @@ -359,6 +450,7 @@ struct scan_cache_entry { qdf_time_t rssi_timestamp; qdf_time_t hidden_ssid_timestamp; struct scan_mbssid_info mbssid_info; + struct reduced_neighbor_report rnr; struct channel_info channel; bool channel_mismatch; struct mlme_info mlme_info; @@ -371,6 +463,12 @@ struct scan_cache_entry { struct element_info alt_wcn_ie; struct ie_list ie_list; struct element_info raw_frame; + /* + * This is added temporarily for 6GHz channel to freq conversion + * to get pdev wherever it requores to convert frequency to + * channel as regulatory apis requires pdev as argument + */ + uint8_t pdev_id; }; #define MAX_FAVORED_BSSID 16 @@ -389,6 +487,7 @@ struct scan_cache_entry { * @pcl_weightage: PCL weightage * @channel_congestion_weightage: channel congestion weightage * @oce_wan_weightage: OCE WAN metrics weightage + * @sae_pk_ap_weightage: SAE-PK AP weigtage */ struct weight_config { uint8_t rssi_weightage; @@ -402,6 +501,7 @@ struct weight_config { uint8_t pcl_weightage; uint8_t channel_congestion_weightage; uint8_t oce_wan_weightage; + uint8_t sae_pk_ap_weightage; }; /** @@ -547,11 +647,11 @@ struct fils_filter_info { * @country[3]: Ap with specific country code * @bssid_list: bssid list * @ssid_list: ssid list - * @channel_list: channel list + * @chan_freq_list: channel frequency list, frequency unit: MHz * @auth_type: auth type list * @enc_type: unicast enc type list * @mc_enc_type: multicast cast enc type list - * @pcl_channel_list: PCL channel list + * @pcl_freq_list: PCL channel frequency list, frequency unit: MHz * @fils_scan_filter: FILS info * @pcl_weight_list: PCL Weight list * @bssid_hint: Mac address of bssid_hint @@ -582,13 +682,13 @@ struct scan_filter { uint8_t country[3]; struct qdf_mac_addr bssid_list[WLAN_SCAN_FILTER_NUM_BSSID]; struct wlan_ssid ssid_list[WLAN_SCAN_FILTER_NUM_SSID]; - uint8_t channel_list[QDF_MAX_NUM_CHAN]; + uint32_t chan_freq_list[NUM_CHANNELS]; enum wlan_auth_type auth_type[WLAN_NUM_OF_SUPPORT_AUTH_TYPE]; enum wlan_enc_type enc_type[WLAN_NUM_OF_ENCRYPT_TYPE]; enum wlan_enc_type mc_enc_type[WLAN_NUM_OF_ENCRYPT_TYPE]; - uint8_t pcl_channel_list[QDF_MAX_NUM_CHAN]; + uint32_t pcl_freq_list[NUM_CHANNELS]; struct fils_filter_info fils_scan_filter; - uint8_t pcl_weight_list[QDF_MAX_NUM_CHAN]; + uint8_t pcl_weight_list[NUM_CHANNELS]; struct qdf_mac_addr bssid_hint; }; @@ -624,27 +724,6 @@ enum scan_priority { SCAN_PRIORITY_COUNT, }; - -/** - * enum scan_type - type of scan - * @SCAN_TYPE_BACKGROUND: background scan - * @SCAN_TYPE_FOREGROUND: foregrounc scan - * @SCAN_TYPE_SPECTRAL: spectral scan - * @SCAN_TYPE_REPEATER_BACKGROUND: background scan in repeater - * @SCAN_TYPE_REPEATER_EXT_BACKGROUND: background scan in extended repeater - * @SCAN_TYPE_RADIO_MEASUREMENTS: redio measurement - * @SCAN_TYPE_COUNT: number of scan types supported - */ -enum scan_type { - SCAN_TYPE_BACKGROUND, - SCAN_TYPE_FOREGROUND, - SCAN_TYPE_SPECTRAL, - SCAN_TYPE_REPEATER_BACKGROUND, - SCAN_TYPE_REPEATER_EXT_BACKGROUND, - SCAN_TYPE_RADIO_MEASUREMENTS, - SCAN_TYPE_COUNT, -}; - /** * enum scan_phy_mode - phymode used for scan * @SCAN_PHY_MODE_11A: 11a mode @@ -703,21 +782,6 @@ enum scan_phy_mode { SCAN_PHY_MODE_MAX = 24 }; -/** - * struct scan_extra_params_legacy - * extra parameters required for legacy DA scan module - * @scan_type: type of scan - * @min_dwell_active: min active dwell time - * @min_dwell_passive: min passive dwell time - * @init_rest_time: init rest time for enhanced independent repeater - */ -struct scan_extra_params_legacy { - enum scan_type scan_type; - uint32_t min_dwell_active; - uint32_t min_dwell_passive; - uint32_t init_rest_time; -}; - /** * enum scan_dwelltime_adaptive_mode: dwelltime_mode * @SCAN_DWELL_MODE_DEFAULT: Use firmware default mode @@ -766,7 +830,7 @@ struct probe_req_whitelist_attr { * @phymode: phymode in which @frequency should be scanned */ struct chan_info { - uint32_t freq; + qdf_freq_t freq; uint32_t phymode; }; @@ -777,8 +841,32 @@ struct chan_info { * @chan: channel parameters used for this scan */ struct chan_list { - uint32_t num_chan; - struct chan_info chan[WLAN_SCAN_MAX_NUM_CHANNELS]; + uint8_t num_chan; + struct chan_info chan[NUM_CHANNELS]; +}; + +/** + * struct hint_short_ssid - short SSID hint + * and their phymode + * @freq_flags: freq unit: MHz (upper 16bits) + * flags (lower 16bits) + * @short_ssid: short SSID + */ +struct hint_short_ssid { + uint32_t freq_flags; + uint32_t short_ssid; +}; + +/** + * struct hint_bssid - BSSID hint + * and their phymode + * @freq_flags: freq unit: MHz (upper 16bits) + * flags (lower 16bits) + * @bssid: BSSID + */ +struct hint_bssid { + uint32_t freq_flags; + struct qdf_mac_addr bssid; }; /** @@ -820,6 +908,8 @@ enum scan_request_type { * @dwell_time_active: active dwell time * @dwell_time_active_2g: active dwell time for 2G channels, if it's not zero * @dwell_time_passive: passive dwell time + * @dwell_time_active_6g: 6Ghz active dwell time + * @dwell_time_passive_6g: 6Ghz passive dwell time * @min_rest_time: min rest time * @max_rest_time: max rest time * @repeat_probe_time: repeat probe time @@ -869,6 +959,10 @@ enum scan_request_type { * @htcap: htcap ie * @vhtcap: vhtcap ie * @scan_ctrl_flags_ext: scan control flag extended + * @num_hint_s_ssid: number of short SSID hints + * @num_hint_bssid: number of BSSID hints + * @hint_s_ssid: short SSID hints + * @hint_bssid: BSSID hints */ struct scan_req_params { @@ -899,6 +993,8 @@ struct scan_req_params { uint32_t dwell_time_active; uint32_t dwell_time_active_2g; uint32_t dwell_time_passive; + uint32_t dwell_time_active_6g; + uint32_t dwell_time_passive_6g; uint32_t min_rest_time; uint32_t max_rest_time; uint32_t repeat_probe_time; @@ -960,17 +1056,19 @@ struct scan_req_params { struct element_info htcap; struct element_info vhtcap; uint32_t scan_ctrl_flags_ext; + uint32_t num_hint_s_ssid; + uint32_t num_hint_bssid; + struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID]; + struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID]; }; /** * struct scan_start_request - scan request config * @vdev: vdev - * @legacy_params: extra parameters required for legacy DA arch * @scan_req: common scan start request parameters */ struct scan_start_request { struct wlan_objmgr_vdev *vdev; - struct scan_extra_params_legacy legacy_params; struct scan_req_params scan_req; }; @@ -1171,7 +1269,7 @@ enum scan_cb_type { /* Set PNO */ #define SCAN_PNO_MAX_PLAN_REQUEST 2 -#define SCAN_PNO_MAX_NETW_CHANNELS_EX 60 +#define SCAN_PNO_MAX_NETW_CHANNELS_EX (NUM_CHANNELS) #define SCAN_PNO_MAX_SUPP_NETWORKS 16 #define SCAN_PNO_DEF_SLOW_SCAN_MULTIPLIER 6 #define SCAN_PNO_DEF_SCAN_TIMER_REPEAT 20 @@ -1357,4 +1455,62 @@ enum ext_cap_bit_field { OBSS_NARROW_BW_RU_IN_ULOFDMA_TOLERENT_SUPPORT = 79, }; +/** + * scan_rnr_info - RNR information + * @timestamp: time stamp of beacon/probe + * @short_ssid: Short SSID + * @bssid: BSSID + */ +struct scan_rnr_info { + qdf_time_t timestamp; + uint32_t short_ssid; + struct qdf_mac_addr bssid; +}; + +/** + * struct scan_rnr_node - Scan RNR entry node + * @node: node pointers + * @entry: scan RNR entry pointer + */ +struct scan_rnr_node { + qdf_list_node_t node; + struct scan_rnr_info entry; +}; + +/** + * meta_rnr_channel - Channel information for scan priority algorithm + * @chan_freq: channel frequency + * @bss_beacon_probe_count: Beacon and probe request count + * @saved_profile_count: Saved profile count + * @beacon_probe_last_time_found: Timestamp of beacon/probe observed + * @rnr_list: RNR list to store RNR IE information + */ +struct meta_rnr_channel { + uint32_t chan_freq; + uint32_t bss_beacon_probe_count; + uint32_t saved_profile_count; + qdf_time_t beacon_probe_last_time_found; + qdf_list_t rnr_list; +}; + +#define RNR_UPDATE_SCAN_CNT_THRESHOLD 2 +/** + * channel_list_db - Database for channel information + * @channel: channel meta information + * @scan_count: scan count since the db was updated + */ +struct channel_list_db { + struct meta_rnr_channel channel[NUM_6GHZ_CHANNELS]; + uint8_t scan_count; +}; + +/** + * rnr_chan_weight - RNR channel weightage + * @chan_freq: channel frequency + * @weight: weightage of the channel + */ +struct rnr_chan_weight { + uint32_t chan_freq; + uint32_t weight; +}; #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h index dbc4f90ee54402f8773a548e2466022dac6e5d7f..4f2f5a66b267163edee4fe2aeb629a6160bf50c4 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -371,7 +371,7 @@ QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev, * ucfg_scan_filter_valid_channel() - The Public API to filter scan result * based on valid channel list * @pdev: pdev object - * @chan_list: valid channel list + * @chan_freq_list: valid channel frequency (in MHz) list * @num_chan: number of valid channels * * The Public API to to filter scan result @@ -380,7 +380,7 @@ QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev, * Return: void. */ void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, uint32_t num_chan); + uint32_t *chan_freq_list, uint32_t num_chan); /** * ucfg_scan_db_iterate() - function to iterate scan table @@ -954,6 +954,16 @@ ucfg_scan_get_max_sched_scan_plan_interval(struct wlan_objmgr_psoc *psoc); uint32_t ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_scan_get_user_config_sched_scan_plan() - API to get user config sched + * scan plan configuration value + * @psoc: pointer to psoc object + * + * Return: value. + */ +bool +ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc); + #else static inline bool ucfg_scan_is_pno_offload_enabled(struct wlan_objmgr_psoc *psoc) @@ -1008,6 +1018,12 @@ ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) return 0; } +static inline bool +ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc) +{ + return true; +} + #endif /* FEATURE_WLAN_SCAN_PNO */ /** diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_utils_api.h b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_utils_api.h index 6fb5f54d3f653dd8408939864584d24e8c98f6bb..f40242324a1d32bf0976f18bc2d0d29360ff39ad 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_utils_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/inc/wlan_scan_utils_api.h @@ -30,6 +30,7 @@ #include #include #include +#include #define ASCII_SPACE_CHARACTER 32 @@ -207,7 +208,7 @@ util_scan_entry_reset_timestamp(struct scan_cache_entry *scan_entry) #define WLAN_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ -#define WLAN_RSSI_LPF_LEN 10 +#define WLAN_RSSI_LPF_LEN 0 #define WLAN_RSSI_DUMMY_MARKER 0x127 #define WLAN_EP_MUL(x, mul) ((x) * (mul)) @@ -230,7 +231,7 @@ util_scan_entry_reset_timestamp(struct scan_cache_entry *scan_entry) ((x != WLAN_RSSI_DUMMY_MARKER) ? ((((x) << 3) + (y) - (x)) >> 3) : (y)) #define WLAN_RSSI_LPF(x, y) do { \ - if ((y) >= RSSI_LPF_THRESHOLD) \ + if ((y) < RSSI_LPF_THRESHOLD) \ x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \ } while (0) @@ -239,6 +240,24 @@ util_scan_entry_reset_timestamp(struct scan_cache_entry *scan_entry) x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \ } while (0) +#define WLAN_SNR_EP_MULTIPLIER BIT(7) /* pow2 to optimize out * and / */ +#define WLAN_SNR_DUMMY_MARKER 0x127 +#define SNR_LPF_THRESHOLD 0 +#define WLAN_SNR_LPF_LEN 10 + +#define WLAN_SNR_OUT(x) (((x) != WLAN_SNR_DUMMY_MARKER) ? \ + (WLAN_EP_RND((x), WLAN_SNR_EP_MULTIPLIER)) : WLAN_SNR_DUMMY_MARKER) + +#define WLAN_SNR_IN(x) (WLAN_EP_MUL((x), WLAN_SNR_EP_MULTIPLIER)) + +#define WLAN_LPF_SNR(x, y, len) \ + ((x != WLAN_SNR_DUMMY_MARKER) ? ((((x) << 3) + (y) - (x)) >> 3) : (y)) + +#define WLAN_SNR_LPF(x, y) do { \ + if ((y) > SNR_LPF_THRESHOLD) \ + x = WLAN_LPF_SNR((x), WLAN_SNR_IN((y)), WLAN_SNR_LPF_LEN); \ + } while (0) + /** * util_scan_entry_rssi() - function to read rssi of scan entry * @scan_entry: scan entry @@ -247,20 +266,33 @@ util_scan_entry_reset_timestamp(struct scan_cache_entry *scan_entry) * * Return: rssi */ -static inline uint8_t +static inline int32_t util_scan_entry_rssi(struct scan_cache_entry *scan_entry) { - uint32_t rssi = WLAN_RSSI_OUT(scan_entry->avg_rssi); + return WLAN_RSSI_OUT(scan_entry->avg_rssi); +} + +/** + * util_scan_entry_snr() - function to read snr of scan entry + * @scan_entry: scan entry + * + * API, function to read snr value of scan entry + * + * Return: snr + */ +static inline uint8_t +util_scan_entry_snr(struct scan_cache_entry *scan_entry) +{ + uint32_t snr = WLAN_SNR_OUT(scan_entry->avg_snr); /* * An entry is in the BSS list means we've received at least one beacon - * from the corresponding AP, so the rssi must be initialized. + * from the corresponding AP, so the snr must be initialized. * - * If the RSSI is not initialized, return 0 (i.e. RSSI == Noise Floor). - * Once se_avgrssi field has been initialized, ATH_RSSI_OUT always - * returns values that fit in an 8-bit variable - * (RSSI values are typically 0-90). + * If the SNR is not initialized, return 0 (i.e. SNR == Noise Floor). + * Once se_avgsnr field has been initialized, ATH_SNR_OUT always + * returns values that fit in an 8-bit variable. */ - return (rssi >= WLAN_RSSI_DUMMY_MARKER) ? 0 : (uint8_t) rssi; + return (snr >= WLAN_SNR_DUMMY_MARKER) ? 0 : (uint8_t)snr; } /** @@ -672,9 +704,12 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry, old_ptr, new_ptr); ie_lst->esp = conv_ptr(ie_lst->esp, old_ptr, new_ptr); ie_lst->mbo_oce = conv_ptr(ie_lst->mbo_oce, old_ptr, new_ptr); + ie_lst->muedca = conv_ptr(ie_lst->muedca, old_ptr, new_ptr); + ie_lst->rnrie = conv_ptr(ie_lst->rnrie, old_ptr, new_ptr); ie_lst->extender = conv_ptr(ie_lst->extender, old_ptr, new_ptr); ie_lst->adaptive_11r = conv_ptr(ie_lst->adaptive_11r, old_ptr, new_ptr); ie_lst->single_pmk = conv_ptr(ie_lst->single_pmk, old_ptr, new_ptr); + ie_lst->rsnxe = conv_ptr(ie_lst->rsnxe, old_ptr, new_ptr); return QDF_STATUS_SUCCESS; } @@ -742,17 +777,17 @@ util_scan_entry_channel(struct scan_cache_entry *scan_entry) } /** - * util_scan_entry_channel_num() - function to read channel number + * util_scan_entry_channel_frequency() - function to read channel number * @scan_entry: scan entry * * API, function to read channel number * * Return: channel number */ -static inline uint8_t -util_scan_entry_channel_num(struct scan_cache_entry *scan_entry) +static inline uint32_t +util_scan_entry_channel_frequency(struct scan_cache_entry *scan_entry) { - return scan_entry->channel.chan_idx; + return scan_entry->channel.chan_freq; } /** @@ -1418,6 +1453,19 @@ util_scan_entry_hecap(struct scan_cache_entry *scan_entry) return scan_entry->ie_list.hecap; } +/** + * util_scan_entry_he_6g_cap() - function to read he 6GHz caps vendor ie + * @scan_entry: scan entry + * + * API, function to read he 6GHz caps vendor ie + * + * Return: he caps vendorie or NULL if ie is not present + */ +static inline uint8_t* +util_scan_entry_he_6g_cap(struct scan_cache_entry *scan_entry) +{ + return scan_entry->ie_list.hecap_6g; +} /** * util_scan_entry_heop() - function to read heop vendor ie @@ -1553,6 +1601,20 @@ util_scan_entry_mbo_oce(struct scan_cache_entry *scan_entry) return scan_entry->ie_list.mbo_oce; } +/** + * util_scan_entry_rsnxe() - function to read RSNXE ie + * @scan_entry: scan entry + * + * API, function to read RSNXE ie + * + * Return: RSNXE ie + */ +static inline uint8_t * +util_scan_entry_rsnxe(struct scan_cache_entry *scan_entry) +{ + return scan_entry->ie_list.rsnxe; +} + /** * util_scan_scm_chan_to_band() - function to tell band for channel number * @chan: Channel number diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index ca8be76518e88e52fd7944330cc0a3c2e42fb114..b77e7fc3939e59f80e01fcc020babe1ad20f3e2a 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -72,9 +71,9 @@ QDF_STATUS ucfg_scan_flush_results(struct wlan_objmgr_pdev *pdev, } void ucfg_scan_filter_valid_channel(struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, uint32_t num_chan) + uint32_t *chan_freq_list, uint32_t num_chan) { - scm_filter_valid_channel(pdev, chan_list, num_chan); + scm_filter_valid_channel(pdev, chan_freq_list, num_chan); } QDF_STATUS ucfg_scan_init(void) @@ -261,6 +260,8 @@ wlan_pno_global_init(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_INTERVAL); pno_def->max_sched_scan_plan_iterations = cfg_get(psoc, CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); + pno_def->user_config_sched_scan_plan = + cfg_get(psoc, CFG_USER_CONFIG_SCHED_SCAN_PLAN); mawc_cfg->enable = cfg_get(psoc, CFG_MAWC_NLO_ENABLED); mawc_cfg->exp_backoff_ratio = @@ -625,8 +626,8 @@ ucfg_scan_config_hidden_ssid_for_bssid(struct wlan_objmgr_pdev *pdev, if (!scan_obj) return QDF_STATUS_E_FAILURE; - scm_debug("Configure bsssid:%pM ssid:%.*s", - bssid, ssid->length, ssid->ssid); + scm_debug("Configure bsssid:"QDF_MAC_ADDR_FMT" ssid:%.*s", + QDF_MAC_ADDR_REF(bssid), ssid->length, ssid->ssid); qdf_mem_copy(scan_obj->pdev_info[pdev_id].conf_bssid, bssid, QDF_MAC_ADDR_SIZE); scan_obj->pdev_info[pdev_id].conf_ssid.length = ssid->length; @@ -956,6 +957,8 @@ wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, scan_obj->scan_disabled = 0; scan_obj->drop_bcn_on_chan_mismatch = cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH); + scan_obj->drop_bcn_on_invalid_freq = + cfg_get(psoc, CFG_DROP_BCN_ON_INVALID_FREQ); scan_obj->disable_timeout = false; scan_obj->scan_def.active_dwell = cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME); @@ -970,6 +973,10 @@ wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_ENABLE_WAKE_LOCK_IN_SCAN); scan_obj->scan_def.active_dwell_2g = cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME); + scan_obj->scan_def.active_dwell_6g = + cfg_get(psoc, CFG_ACTIVE_MAX_6G_CHANNEL_TIME); + scan_obj->scan_def.passive_dwell_6g = + cfg_get(psoc, CFG_PASSIVE_MAX_6G_CHANNEL_TIME); scan_obj->scan_def.passive_dwell = cfg_get(psoc, CFG_PASSIVE_MAX_CHANNEL_TIME); scan_obj->scan_def.max_rest_time = SCAN_MAX_REST_TIME; @@ -1039,6 +1046,9 @@ wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, scan_obj->scan_def.scan_ev_restarted = true; scan_obj->scan_def.enable_connected_scan = cfg_get(psoc, CFG_ENABLE_CONNECTED_SCAN); + scan_obj->scan_def.scan_mode_6g = cfg_get(psoc, CFG_6GHZ_SCAN_MODE); + scan_obj->allow_bss_with_incomplete_ie = + cfg_get(psoc, CFG_SCAN_ALLOW_BSS_WITH_CORRUPTED_IE); /* init scan id seed */ qdf_atomic_init(&scan_obj->scan_ids); @@ -1160,6 +1170,8 @@ ucfg_scan_init_default_params(struct wlan_objmgr_vdev *vdev, req->scan_req.scan_priority = def->scan_priority; req->scan_req.dwell_time_active = def->active_dwell; req->scan_req.dwell_time_active_2g = def->active_dwell_2g; + req->scan_req.dwell_time_active_6g = def->active_dwell_6g; + req->scan_req.dwell_time_passive_6g = def->passive_dwell_6g; req->scan_req.dwell_time_passive = def->passive_dwell; req->scan_req.min_rest_time = def->min_rest_time; req->scan_req.max_rest_time = def->max_rest_time; @@ -1270,8 +1282,8 @@ ucfg_scan_init_bssid_params(struct scan_start_request *req, */ static bool is_chan_enabled_for_scan(struct regulatory_channel *reg_chan, - uint32_t low_2g, uint32_t high_2g, uint32_t low_5g, - uint32_t high_5g) + qdf_freq_t low_2g, qdf_freq_t high_2g, qdf_freq_t low_5g, + qdf_freq_t high_5g) { if (reg_chan->state == CHANNEL_STATE_DISABLE) return false; @@ -1299,7 +1311,7 @@ ucfg_scan_init_chanlist_params(struct scan_start_request *req, uint32_t idx; QDF_STATUS status; struct regulatory_channel *reg_chan_list = NULL; - uint32_t low_2g, high_2g, low_5g, high_5g; + qdf_freq_t low_2g, high_2g, low_5g, high_5g; struct wlan_objmgr_pdev *pdev = NULL; uint32_t *scan_freqs = NULL; uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / @@ -1626,6 +1638,7 @@ ucfg_scan_psoc_open(struct wlan_objmgr_psoc *psoc) qdf_spinlock_create(&scan_obj->lock); ucfg_scan_register_pmo_handler(); scm_db_init(psoc); + scm_channel_list_db_init(psoc); return QDF_STATUS_SUCCESS; } @@ -1649,6 +1662,7 @@ ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc) ucfg_scan_unregister_pmo_handler(); qdf_spinlock_destroy(&scan_obj->lock); wlan_scan_global_deinit(psoc); + scm_channel_list_db_deinit(psoc); return QDF_STATUS_SUCCESS; } @@ -2040,4 +2054,17 @@ ucfg_scan_get_max_sched_scan_plan_iterations(struct wlan_objmgr_psoc *psoc) return scan_obj->pno_cfg.max_sched_scan_plan_iterations; } +bool +ucfg_scan_get_user_config_sched_scan_plan(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_scan_obj *scan_obj; + + scan_obj = wlan_psoc_get_scan_obj(psoc); + if (!scan_obj) { + scm_err("Failed to get scan object"); + return cfg_default(CFG_MAX_SCHED_SCAN_PLAN_ITERATIONS); + } + + return scan_obj->pno_cfg.user_config_sched_scan_plan; +} #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c index d589d0dd71163537b3afe5a116c46462fccb2c8c..02ab28c5bc979aa3b8998b79f560e5a37772941c 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,6 +29,9 @@ #include #define MAX_IE_LEN 1024 +#define SHORT_SSID_LEN 4 +#define NEIGHBOR_AP_LEN 1 +#define BSS_PARAMS_LEN 1 const char* util_scan_get_ev_type_name(enum scan_event_type type) @@ -142,8 +145,8 @@ bool util_is_scan_entry_match( util_scan_is_null_ssid(&entry2->ssid)) return true; } else if (entry1->cap_info.wlan_caps.ibss && - (entry1->channel.chan_idx == - entry2->channel.chan_idx)) { + (entry1->channel.chan_freq == + entry2->channel.chan_freq)) { /* * Same channel cannot have same SSID for * different IBSS, so no need to check BSSID @@ -182,14 +185,194 @@ static bool util_is_pureg_rate(uint8_t *rates, uint8_t nrates) return pureg; } +#ifdef CONFIG_BAND_6GHZ +static struct he_oper_6g_param *util_scan_get_he_6g_params(uint8_t *he_ops) +{ + uint8_t len; + uint32_t he_oper_params; + + if (!he_ops) + return NULL; + + len = he_ops[1]; + he_ops += sizeof(struct ie_header); + + if (len < WLAN_HEOP_FIXED_PARAM_LENGTH) + return NULL; + + /* element id extension */ + he_ops++; + len--; + + he_oper_params = LE_READ_4(he_ops); + if (!(he_oper_params & WLAN_HEOP_6GHZ_INFO_PRESENT_MASK)) + return NULL; + + /* fixed params - element id extension */ + he_ops += WLAN_HEOP_FIXED_PARAM_LENGTH - 1; + len -= WLAN_HEOP_FIXED_PARAM_LENGTH - 1; + + if (!len) + return NULL; + + /* vht oper params */ + if (he_oper_params & WLAN_HEOP_VHTOP_PRESENT_MASK) { + if (len < WLAN_HEOP_VHTOP_LENGTH) + return NULL; + he_ops += WLAN_HEOP_VHTOP_LENGTH; + len -= WLAN_HEOP_VHTOP_LENGTH; + } + + if (!len) + return NULL; + + if (he_oper_params & WLAN_HEOP_CO_LOCATED_BSS_MASK) { + he_ops += WLAN_HEOP_CO_LOCATED_BSS_LENGTH; + len -= WLAN_HEOP_CO_LOCATED_BSS_LENGTH; + } + + if (len < sizeof(struct he_oper_6g_param)) + return NULL; + + return (struct he_oper_6g_param *)he_ops; +} + +static QDF_STATUS +util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params, + qdf_freq_t *chan_freq, uint8_t band_mask) +{ + struct he_oper_6g_param *he_6g_params; + uint8_t *he_ops; + struct wlan_scan_obj *scan_obj; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + scm_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + scan_obj = wlan_psoc_get_scan_obj(psoc); + if (!scan_obj) { + scm_err("scan_obj is NULL"); + return QDF_STATUS_E_INVAL; + } + + he_ops = util_scan_entry_heop(scan_params); + if (!util_scan_entry_hecap(scan_params) || !he_ops) + return QDF_STATUS_SUCCESS; + + he_6g_params = util_scan_get_he_6g_params(he_ops); + if (!he_6g_params) + return QDF_STATUS_SUCCESS; + + *chan_freq = wlan_reg_chan_band_to_freq(pdev, + he_6g_params->primary_channel, + band_mask); + if (scan_obj->drop_bcn_on_invalid_freq && + wlan_reg_is_disable_for_freq(pdev, *chan_freq)) { + scm_debug_rl(QDF_MAC_ADDR_FMT": Drop as invalid channel %d freq %d in HE 6Ghz params", + scan_params->bssid.bytes, + he_6g_params->primary_channel, *chan_freq); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + static enum wlan_phymode -util_scan_get_phymode_5g(struct scan_cache_entry *scan_params) +util_scan_get_phymode_6g(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params) +{ + struct he_oper_6g_param *he_6g_params; + enum wlan_phymode phymode = WLAN_PHYMODE_11AXA_HE20; + uint8_t *he_ops; + uint8_t band_mask = BIT(REG_BAND_6G); + + he_ops = util_scan_entry_heop(scan_params); + if (!util_scan_entry_hecap(scan_params) || !he_ops) + return phymode; + + he_6g_params = util_scan_get_he_6g_params(he_ops); + if (!he_6g_params) + return phymode; + + switch (he_6g_params->width) { + case WLAN_HE_6GHZ_CHWIDTH_20: + phymode = WLAN_PHYMODE_11AXA_HE20; + break; + case WLAN_HE_6GHZ_CHWIDTH_40: + phymode = WLAN_PHYMODE_11AXA_HE40; + break; + case WLAN_HE_6GHZ_CHWIDTH_80: + phymode = WLAN_PHYMODE_11AXA_HE80; + break; + case WLAN_HE_6GHZ_CHWIDTH_160_80_80: + if (WLAN_IS_HE80_80(he_6g_params)) + phymode = WLAN_PHYMODE_11AXA_HE80_80; + else if (WLAN_IS_HE160(he_6g_params)) + phymode = WLAN_PHYMODE_11AXA_HE160; + else + phymode = WLAN_PHYMODE_11AXA_HE80; + break; + default: + scm_err("Invalid he_6g_params width: %d", he_6g_params->width); + phymode = WLAN_PHYMODE_11AXA_HE20; + break; + } + + if (he_6g_params->chan_freq_seg0) + scan_params->channel.cfreq0 = + wlan_reg_chan_band_to_freq(pdev, + he_6g_params->chan_freq_seg0, + band_mask); + if (he_6g_params->chan_freq_seg1) + scan_params->channel.cfreq1 = + wlan_reg_chan_band_to_freq(pdev, + he_6g_params->chan_freq_seg1, + band_mask); + + return phymode; +} +#else +static QDF_STATUS +util_scan_get_chan_from_he_6g_params(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params, + qdf_freq_t *chan_freq, uint8_t band_mask) +{ + return QDF_STATUS_SUCCESS; +} +static inline enum wlan_phymode +util_scan_get_phymode_6g(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params) +{ + return WLAN_PHYMODE_AUTO; +} +#endif + +static inline +uint32_t util_scan_sec_chan_freq_from_htinfo(struct wlan_ie_htinfo_cmn *htinfo, + uint32_t primary_chan_freq) +{ + if (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_ABOVE) + return primary_chan_freq + WLAN_CHAN_SPACING_20MHZ; + else if (htinfo->hi_extchoff == WLAN_HTINFO_EXTOFFSET_BELOW) + return primary_chan_freq - WLAN_CHAN_SPACING_20MHZ; + + return 0; +} + +static enum wlan_phymode +util_scan_get_phymode_5g(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params) { enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; uint16_t ht_cap = 0; struct htcap_cmn_ie *htcap; struct wlan_ie_htinfo_cmn *htinfo; struct wlan_ie_vhtop *vhtop; + uint8_t band_mask = BIT(REG_BAND_5G); htcap = (struct htcap_cmn_ie *) util_scan_entry_htcap(scan_params); @@ -209,6 +392,10 @@ util_scan_get_phymode_5g(struct scan_cache_entry *scan_params) else phymode = WLAN_PHYMODE_11NA_HT20; + scan_params->channel.cfreq0 = + util_scan_sec_chan_freq_from_htinfo(htinfo, + scan_params->channel.chan_freq); + if (util_scan_entry_vhtcap(scan_params) && vhtop) { switch (vhtop->vht_op_chwidth) { case WLAN_VHTOP_CHWIDTH_2040: @@ -237,6 +424,16 @@ util_scan_get_phymode_5g(struct scan_cache_entry *scan_params) phymode = WLAN_PHYMODE_11AC_VHT20; break; } + if (vhtop->vht_op_ch_freq_seg1) + scan_params->channel.cfreq0 = + wlan_reg_chan_band_to_freq(pdev, + vhtop->vht_op_ch_freq_seg1, + band_mask); + if (vhtop->vht_op_ch_freq_seg2) + scan_params->channel.cfreq1 = + wlan_reg_chan_band_to_freq(pdev, + vhtop->vht_op_ch_freq_seg2, + band_mask); } if (!util_scan_entry_hecap(scan_params)) @@ -318,6 +515,10 @@ util_scan_get_phymode_2g(struct scan_cache_entry *scan_params) if (!IS_WLAN_PHYMODE_HT(phymode)) return phymode; + scan_params->channel.cfreq0 = + util_scan_sec_chan_freq_from_htinfo(htinfo, + scan_params->channel.chan_freq); + if (util_scan_entry_vhtcap(scan_params) && vhtop) { switch (vhtop->vht_op_chwidth) { case WLAN_VHTOP_CHWIDTH_2040: @@ -352,6 +553,18 @@ util_scan_get_phymode_2g(struct scan_cache_entry *scan_params) return phymode; } +static enum wlan_phymode +util_scan_get_phymode(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params) +{ + if (WLAN_REG_IS_24GHZ_CH_FREQ(scan_params->channel.chan_freq)) + return util_scan_get_phymode_2g(scan_params); + else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(scan_params->channel.chan_freq)) + return util_scan_get_phymode_6g(pdev, scan_params); + else + return util_scan_get_phymode_5g(pdev, scan_params); +} + static QDF_STATUS util_scan_parse_chan_switch_wrapper_ie(struct scan_cache_entry *scan_params, struct ie_header *sub_ie, qdf_size_t sub_ie_len) @@ -418,6 +631,115 @@ util_scan_is_hidden_ssid(struct ie_ssid *ssid) return true; } +static QDF_STATUS +util_scan_update_rnr(struct rnr_bss_info *rnr, + struct neighbor_ap_info_field *ap_info, + uint8_t *data) +{ + uint8_t tbtt_info_length; + + tbtt_info_length = ap_info->tbtt_header.tbtt_info_length; + + switch (tbtt_info_length) { + case TBTT_NEIGHBOR_AP_OFFSET_ONLY: + /* Dont store it skip*/ + break; + + case TBTT_NEIGHBOR_AP_BSS_PARAM: + /* Dont store it skip*/ + break; + + case TBTT_NEIGHBOR_AP_SHORTSSID: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->short_ssid, &data[1], SHORT_SSID_LEN); + break; + + case TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->short_ssid, &data[1], SHORT_SSID_LEN); + rnr->bss_params = data[5]; + break; + + case TBTT_NEIGHBOR_AP_BSSID: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); + break; + + case TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); + rnr->bss_params = data[7]; + break; + + case TBTT_NEIGHBOR_AP_BSSSID_S_SSID: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); + qdf_mem_copy(&rnr->short_ssid, &data[7], SHORT_SSID_LEN); + break; + + case TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM: + rnr->channel_number = ap_info->channel_number; + rnr->operating_class = ap_info->operting_class; + qdf_mem_copy(&rnr->bssid, &data[1], QDF_MAC_ADDR_SIZE); + qdf_mem_copy(&rnr->short_ssid, &data[7], SHORT_SSID_LEN); + rnr->bss_params = data[11]; + break; + + default: + scm_debug("Wrong fieldtype"); + } + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +util_scan_parse_rnr_ie(struct scan_cache_entry *scan_entry, + struct ie_header *ie) +{ + uint32_t rnr_ie_len; + uint16_t tbtt_count, tbtt_length, i, fieldtype; + uint8_t *data; + struct neighbor_ap_info_field *neighbor_ap_info; + + rnr_ie_len = ie->ie_len; + data = (uint8_t *)ie + sizeof(struct ie_header); + + while ((data + sizeof(struct neighbor_ap_info_field)) <= + ((uint8_t *)ie + rnr_ie_len + 2)) { + neighbor_ap_info = (struct neighbor_ap_info_field *)data; + tbtt_count = neighbor_ap_info->tbtt_header.tbtt_info_count; + tbtt_length = neighbor_ap_info->tbtt_header.tbtt_info_length; + fieldtype = neighbor_ap_info->tbtt_header.tbbt_info_fieldtype; + scm_debug("channel number %d, op class %d", + neighbor_ap_info->channel_number, + neighbor_ap_info->operting_class); + scm_debug("tbtt_count %d, tbtt_length %d, fieldtype %d", + tbtt_count, tbtt_length, fieldtype); + data += sizeof(struct neighbor_ap_info_field); + + if (tbtt_count > TBTT_INFO_COUNT) + break; + + for (i = 0; i < (tbtt_count + 1) && + (data + tbtt_length) <= + ((uint8_t *)ie + rnr_ie_len + 2); i++) { + if (i < MAX_RNR_BSS) + util_scan_update_rnr( + &scan_entry->rnr.bss_info[i], + neighbor_ap_info, + data); + data += tbtt_length; + } + } + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS util_scan_parse_extn_ie(struct scan_cache_entry *scan_params, struct ie_header *ie) @@ -434,6 +756,9 @@ util_scan_parse_extn_ie(struct scan_cache_entry *scan_params, scan_params->ie_list.srp = (uint8_t *)ie; break; case WLAN_EXTN_ELEMID_HECAP: + if ((extn_ie->ie_len < WLAN_MIN_HECAP_IE_LEN) || + (extn_ie->ie_len > WLAN_MAX_HECAP_IE_LEN)) + return QDF_STATUS_E_INVAL; scan_params->ie_list.hecap = (uint8_t *)ie; break; case WLAN_EXTN_ELEMID_HEOP: @@ -445,6 +770,9 @@ util_scan_parse_extn_ie(struct scan_cache_entry *scan_params, case WLAN_EXTN_ELEMID_MUEDCA: scan_params->ie_list.muedca = (uint8_t *)ie; break; + case WLAN_EXTN_ELEMID_HE_6G_CAP: + scan_params->ie_list.hecap_6g = (uint8_t *)ie; + break; default: break; } @@ -560,11 +888,28 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params, } static QDF_STATUS -util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) +util_scan_populate_bcn_ie_list(struct wlan_objmgr_pdev *pdev, + struct scan_cache_entry *scan_params, + qdf_freq_t *chan_freq, uint8_t band_mask) { struct ie_header *ie, *sub_ie; uint32_t ie_len, sub_ie_len; QDF_STATUS status; + uint8_t chan_idx; + struct wlan_scan_obj *scan_obj; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + scm_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + scan_obj = wlan_psoc_get_scan_obj(psoc); + if (!scan_obj) { + scm_err("scan_obj is NULL"); + return QDF_STATUS_E_INVAL; + } ie_len = util_scan_entry_ie_len(scan_params); ie = (struct ie_header *) @@ -579,8 +924,15 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) } if (ie_len < ie->ie_len) { - scm_debug("Incomplete corrupted IE:%x", - ie->ie_id); + if (scan_obj->allow_bss_with_incomplete_ie) { + scm_debug(QDF_MAC_ADDR_FMT": Scan allowed with incomplete corrupted IE:%x, ie_len: %d, ie->ie_len: %d, stop processing further", + QDF_MAC_ADDR_REF(scan_params->bssid.bytes), + ie->ie_id, ie_len, ie->ie_len); + break; + } + scm_debug(QDF_MAC_ADDR_FMT": Scan not allowed with incomplete corrupted IE:%x, ie_len: %d, ie->ie_len: %d, stop processing further", + QDF_MAC_ADDR_REF(scan_params->bssid.bytes), + ie->ie_id, ie_len, ie->ie_len); return QDF_STATUS_E_INVAL; } @@ -600,8 +952,18 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) if (ie->ie_len != WLAN_DS_PARAM_IE_MAX_LEN) return QDF_STATUS_E_INVAL; scan_params->ie_list.ds_param = (uint8_t *)ie; - scan_params->channel.chan_idx = + chan_idx = ((struct ds_ie *)ie)->cur_chan; + *chan_freq = wlan_reg_chan_band_to_freq(pdev, chan_idx, + band_mask); + /* Drop if invalid freq */ + if (scan_obj->drop_bcn_on_invalid_freq && + wlan_reg_is_disable_for_freq(pdev, *chan_freq)) { + scm_debug_rl(QDF_MAC_ADDR_FMT": Drop as invalid channel %d freq %d in DS IE", + scan_params->bssid.bytes, + chan_idx, *chan_freq); + return QDF_STATUS_E_INVAL; + } break; case WLAN_ELEMID_TIM: if (ie->ie_len < WLAN_TIM_IE_MIN_LENGTH) @@ -656,9 +1018,16 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) (uint8_t *)&(((struct htcap_ie *)ie)->ie); break; case WLAN_ELEMID_RSN: - if (ie->ie_len < WLAN_RSN_IE_MIN_LEN) - goto err; - scan_params->ie_list.rsn = (uint8_t *)ie; + /* + * For security cert TC, RSNIE length can be 1 but if + * beacon is dropped, old entry will remain in scan + * cache and cause cert TC failure as connection with + * old entry with valid RSN IE will pass. + * So instead of dropping the frame, do not store the + * RSN pointer so that old entry is overwritten. + */ + if (ie->ie_len >= WLAN_RSN_IE_MIN_LEN) + scan_params->ie_list.rsn = (uint8_t *)ie; break; case WLAN_ELEMID_XRATES: scan_params->ie_list.xrates = (uint8_t *)ie; @@ -678,9 +1047,18 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) goto err; scan_params->ie_list.htinfo = (uint8_t *)&(((struct wlan_ie_htinfo *) ie)->hi_ie); - scan_params->channel.chan_idx = - ((struct wlan_ie_htinfo_cmn *) - (scan_params->ie_list.htinfo))->hi_ctrlchannel; + chan_idx = ((struct wlan_ie_htinfo_cmn *) + (scan_params->ie_list.htinfo))->hi_ctrlchannel; + *chan_freq = wlan_reg_chan_band_to_freq(pdev, chan_idx, + band_mask); + /* Drop if invalid freq */ + if (scan_obj->drop_bcn_on_invalid_freq && + wlan_reg_is_disable_for_freq(pdev, *chan_freq)) { + scm_debug_rl(QDF_MAC_ADDR_FMT": Drop as invalid channel %d freq %d in HT_INFO IE", + scan_params->bssid.bytes, + chan_idx, *chan_freq); + return QDF_STATUS_E_INVAL; + } break; case WLAN_ELEMID_WAPI: if (ie->ie_len < WLAN_WAPI_IE_MIN_LEN) @@ -738,11 +1116,24 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params) goto err; scan_params->ie_list.fils_indication = (uint8_t *)ie; break; + case WLAN_ELEMID_RSNXE: + if (!ie->ie_len) + goto err; + scan_params->ie_list.rsnxe = (uint8_t *)ie; + break; case WLAN_ELEMID_EXTN_ELEM: status = util_scan_parse_extn_ie(scan_params, ie); if (QDF_IS_STATUS_ERROR(status)) goto err_status; break; + case WLAN_ELEMID_REDUCED_NEIGHBOR_REPORT: + if (ie->ie_len < WLAN_RNR_IE_MIN_LEN) + goto err; + scan_params->ie_list.rnrie = (uint8_t *)ie; + status = util_scan_parse_rnr_ie(scan_params, ie); + if (QDF_IS_STATUS_ERROR(status)) + goto err_status; + break; default: break; } @@ -1131,6 +1522,8 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, struct qbss_load_ie *qbss_load; struct scan_cache_node *scan_node; uint8_t i; + qdf_freq_t chan_freq = 0; + uint8_t band_mask; scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry)); if (!scan_entry) { @@ -1161,13 +1554,17 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, scan_entry->seq_num = (le16toh(*(uint16_t *)hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT); + scan_entry->snr = rx_param->snr; + scan_entry->avg_snr = WLAN_SNR_IN(scan_entry->snr); scan_entry->rssi_raw = rx_param->rssi; scan_entry->avg_rssi = WLAN_RSSI_IN(scan_entry->rssi_raw); scan_entry->tsf_delta = rx_param->tsf_delta; + scan_entry->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); /* Copy per chain rssi to scan entry */ qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl, WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); + band_mask = BIT(wlan_reg_freq_to_band(rx_param->chan_freq)); if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev), WLAN_SOC_CEXT_HW_DB2DBM)) { @@ -1204,9 +1601,11 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, scan_entry->raw_frame.len = frame_len; qdf_mem_copy(scan_entry->raw_frame.ptr, frame, frame_len); - status = util_scan_populate_bcn_ie_list(scan_entry); + status = util_scan_populate_bcn_ie_list(pdev, scan_entry, &chan_freq, + band_mask); if (QDF_IS_STATUS_ERROR(status)) { - scm_debug("failed to parse beacon IE"); + scm_debug(QDF_MAC_ADDR_FMT": failed to parse beacon IE", + scan_entry->bssid.bytes); qdf_mem_free(scan_entry->raw_frame.ptr); qdf_mem_free(scan_entry); return QDF_STATUS_E_FAILURE; @@ -1224,13 +1623,26 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, if (scan_entry->ie_list.p2p) scan_entry->is_p2p = true; + if (!chan_freq && util_scan_entry_hecap(scan_entry)) { + status = util_scan_get_chan_from_he_6g_params(pdev, scan_entry, + &chan_freq, + band_mask); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(scan_entry->raw_frame.ptr); + qdf_mem_free(scan_entry); + return QDF_STATUS_E_FAILURE; + } + } + + if (chan_freq) + scan_entry->channel.chan_freq = chan_freq; + /* If no channel info is present in beacon use meta channel */ - if (!scan_entry->channel.chan_idx) { - scan_entry->channel.chan_idx = - rx_param->channel; - } else if (rx_param->channel != - scan_entry->channel.chan_idx) { - if (!wlan_reg_chan_is_49ghz(pdev, scan_entry->channel.chan_idx)) + if (!scan_entry->channel.chan_freq) { + scan_entry->channel.chan_freq = rx_param->chan_freq; + } else if (rx_param->chan_freq != + scan_entry->channel.chan_freq) { + if (!wlan_reg_is_49ghz_freq(scan_entry->channel.chan_freq)) scan_entry->channel_mismatch = true; } @@ -1246,10 +1658,8 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, } qdf_mem_copy(&scan_entry->mbssid_info, mbssid_info, sizeof(scan_entry->mbssid_info)); - if (WLAN_CHAN_IS_5GHZ(scan_entry->channel.chan_idx)) - scan_entry->phy_mode = util_scan_get_phymode_5g(scan_entry); - else - scan_entry->phy_mode = util_scan_get_phymode_2g(scan_entry); + + scan_entry->phy_mode = util_scan_get_phymode(pdev, scan_entry); scan_entry->nss = util_scan_scm_calc_nss_supported_by_ap(scan_entry); scm_fill_adaptive_11r_cap(scan_entry); @@ -1321,6 +1731,7 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, uint8_t *pos, *tmp; const uint8_t *tmp_old, *tmp_new; uint8_t *sub_copy; + size_t tmp_rem_len; /* copy subelement as we need to change its content to * mark an ie after it is processed. @@ -1335,8 +1746,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, /* new ssid */ tmp_new = util_scan_find_ie(WLAN_ELEMID_SSID, sub_copy, subie_len); if (tmp_new) { - qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); - pos += (tmp_new[1] + 2); + if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) { + qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); + pos += (tmp_new[1] + 2); + } } /* go through IEs in ie (skip SSID) and subelement, @@ -1356,8 +1769,12 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, if (!tmp) { /* ie in old ie but not in subelement */ if (tmp_old[0] != WLAN_ELEMID_MULTIPLE_BSSID) { - qdf_mem_copy(pos, tmp_old, tmp_old[1] + 2); - pos += tmp_old[1] + 2; + if ((pos + tmp_old[1] + 2) <= + (new_ie + ielen)) { + qdf_mem_copy(pos, tmp_old, + tmp_old[1] + 2); + pos += tmp_old[1] + 2; + } } } else { /* ie in transmitting ie also in subelement, @@ -1366,24 +1783,35 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, * vendor ie, compare OUI + type + subType to * determine if they are the same ie. */ - if (tmp_old[0] == WLAN_ELEMID_VENDOR) { + tmp_rem_len = subie_len - (tmp - sub_copy); + if (tmp_old[0] == WLAN_ELEMID_VENDOR && + tmp_rem_len >= 7) { if (!qdf_mem_cmp(tmp_old + 2, tmp + 2, 5)) { /* same vendor ie, copy from * subelement */ - qdf_mem_copy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = 0xff; + if ((pos + tmp[1] + 2) <= + (new_ie + ielen)) { + qdf_mem_copy(pos, tmp, + tmp[1] + 2); + pos += tmp[1] + 2; + tmp[0] = 0xff; + } } else { - qdf_mem_copy(pos, tmp_old, - tmp_old[1] + 2); - pos += tmp_old[1] + 2; + if ((pos + tmp_old[1] + 2) <= + (new_ie + ielen)) { + qdf_mem_copy(pos, tmp_old, + tmp_old[1] + 2); + pos += tmp_old[1] + 2; + } } } else { /* copy ie from subelement into new ie */ - qdf_mem_copy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = 0xff; + if ((pos + tmp[1] + 2) <= (new_ie + ielen)) { + qdf_mem_copy(pos, tmp, tmp[1] + 2); + pos += tmp[1] + 2; + tmp[0] = 0xff; + } } } @@ -1402,8 +1830,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen, tmp_new[0] == WLAN_ELEMID_SSID || tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX || tmp_new[0] == 0xff)) { - qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); - pos += tmp_new[1] + 2; + if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) { + qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2); + pos += tmp_new[1] + 2; + } } if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) break; @@ -1445,7 +1875,7 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, pos = ie; - new_ie = qdf_mem_malloc(MAX_IE_LEN); + new_ie = qdf_mem_malloc(ielen); if (!new_ie) return QDF_STATUS_E_NOMEM; @@ -1563,9 +1993,9 @@ util_scan_parse_beacon_frame(struct wlan_objmgr_pdev *pdev, { struct wlan_bcn_frame *bcn; struct wlan_frame_hdr *hdr; - uint8_t *mbssid_ie = NULL; + uint8_t *mbssid_ie = NULL, *extcap_ie; uint32_t ie_len = 0; - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; struct scan_mbssid_info mbssid_info = { 0 }; hdr = (struct wlan_frame_hdr *)frame; @@ -1575,12 +2005,24 @@ util_scan_parse_beacon_frame(struct wlan_objmgr_pdev *pdev, sizeof(struct wlan_frame_hdr) - offsetof(struct wlan_bcn_frame, ie)); - mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, + extcap_ie = util_scan_find_ie(WLAN_ELEMID_XCAPS, (uint8_t *)&bcn->ie, ie_len); - if (mbssid_ie) { - qdf_mem_copy(&mbssid_info.trans_bssid, - hdr->i_addr3, QDF_MAC_ADDR_SIZE); - mbssid_info.profile_count = 1 << mbssid_ie[2]; + /* Process MBSSID when Multiple BSSID (Bit 22) is set in Ext Caps */ + if (extcap_ie && + extcap_ie[1] >= 3 && extcap_ie[1] <= WLAN_EXTCAP_IE_MAX_LEN && + (extcap_ie[4] & 0x40)) { + mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, + (uint8_t *)&bcn->ie, ie_len); + if (mbssid_ie) { + if (mbssid_ie[1] < 4) { + scm_debug("MBSSID IE length is wrong %d", + mbssid_ie[1]); + return status; + } + qdf_mem_copy(&mbssid_info.trans_bssid, + hdr->i_addr3, QDF_MAC_ADDR_SIZE); + mbssid_info.profile_count = 1 << mbssid_ie[2]; + } } status = util_scan_gen_scan_entry(pdev, frame, frame_len, diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_api.h b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_api.h index 022f0c8d32681887d2c2550f81027a3ce120f1d7..7b835438b9c0551ff6786efc69c1ed13a87c497b 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_api.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,9 +24,8 @@ #define _WIFI_POS_API_H_ /* Include files */ -#include "qdf_types.h" -#include "qdf_status.h" -#include "qdf_trace.h" +#include "wifi_pos_utils_pub.h" +#include "../src/wifi_pos_utils_i.h" /* forward reference */ struct wlan_objmgr_psoc; @@ -113,7 +112,7 @@ struct qdf_packed wifi_pos_ch_info_rsp { }; /** - * struct wmi_pos_peer_status_info - Status information for a given peer + * struct wifi_pos_peer_status_info - Status information for a given peer * @peer_mac_addr: peer mac address * @peer_status: peer status: 1: CONNECTED, 2: DISCONNECTED * @vdev_id: vdev_id for the peer mac @@ -121,7 +120,7 @@ struct qdf_packed wifi_pos_ch_info_rsp { * @reserved0: reserved0 * @peer_chan_info: channel info on which peer is connected */ -struct qdf_packed wmi_pos_peer_status_info { +struct qdf_packed wifi_pos_peer_status_info { uint8_t peer_mac_addr[ETH_ALEN]; uint8_t peer_status; uint8_t vdev_id; @@ -138,15 +137,17 @@ struct qdf_packed wmi_pos_peer_status_info { * @buf_len: request buffer length * @field_info_buf: buffer containing field info * @field_info_buf_len: length of field info buffer + * @rsp_version: nl type or ani type * */ struct wifi_pos_req_msg { - uint32_t msg_type; + enum wifi_pos_cmd_ids msg_type; uint32_t pid; uint8_t *buf; uint32_t buf_len; struct wifi_pos_field_info *field_info_buf; uint32_t field_info_buf_len; + uint32_t rsp_version; }; /** @@ -159,8 +160,8 @@ struct wifi_pos_req_msg { * Return: status of operation */ QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, - struct wifi_pos_req_msg *req, - void (*send_rsp_cb)(uint32_t, uint32_t, uint32_t, uint8_t *)); + struct wifi_pos_req_msg *req, + wifi_pos_send_rsp_handler send_rsp_cb); /** * wifi_pos_init: initializes WIFI POS component, called by dispatcher init @@ -304,6 +305,15 @@ void wifi_pos_set_current_dwell_time_max(struct wlan_objmgr_psoc *psoc, QDF_STATUS wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, struct wifi_pos_driver_caps *caps); +struct wlan_lmac_if_rx_ops; +/** + * wifi_pos_register_rx_ops: function to register with lmac rx ops + * @rx_ops: lmac rx ops struct object + * + * Return: None + */ +void wifi_pos_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops); + /** * ucfg_wifi_pos_get_ftm_cap: API to get fine timing measurement caps * @psoc: psoc object @@ -321,6 +331,24 @@ uint32_t ucfg_wifi_pos_get_ftm_cap(struct wlan_objmgr_psoc *psoc); */ void ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc *psoc, uint32_t val); +/** + * ucfg_wifi_pos_set_oem_6g_supported: API to set oem target 6g enabled/disabled + * @psoc: psoc object + * @val: value to set + * + * Return: None + */ +void ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * ucfg_wifi_pos_is_nl_rsp: API to check if response is nl or ani type + * @psoc: psoc object + * + * Return: true if response is nl type + */ +bool ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc *psoc); + /** * wifi_pos_get_app_pid: returns oem app pid. * @psoc: pointer to psoc object @@ -390,6 +418,19 @@ static inline QDF_STATUS wifi_pos_init_cir_cfr_rings( } #endif +/** + * wifi_pos_register_get_fw_phy_mode_for_freq_cb: API to register callback + * to get current PHY mode + * @psoc: pointer to psoc object + * @handler: callback to be registered + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_register_get_fw_phy_mode_for_freq_cb( + struct wlan_objmgr_psoc *psoc, + void (*handler)(uint32_t, uint32_t, uint32_t *)); + /** * wifi_pos_register_get_phy_mode_cb: API to register callback to get * current PHY mode @@ -403,4 +444,33 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( struct wlan_objmgr_psoc *psoc, void (*handler)(uint8_t, uint32_t, uint32_t *)); +/** + * wifi_pos_register_send_action: API to register callback to send + * action frames + * @psoc: pointer to psoc object + * @handler: callback to be registered + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)); + +/** + * wifi_pos_send_report_resp: Send report to osif + * @psoc: pointer to psoc object + * @req_id: Request id + * @dest_mac: destination mac address + * @err_code: Error code to be sent + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_utils_pub.h b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_utils_pub.h new file mode 100644 index 0000000000000000000000000000000000000000..9b1c66b1d7558e5358b9b9e4cbc6591fc5612917 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/inc/wifi_pos_utils_pub.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wifi_pos_utils_pub.h + * This file declares public utils of wifi positioning component + */ +#ifndef _WIFI_POS_UTILS_PUB_H_ +#define _WIFI_POS_UTILS_PUB_H_ + +/* Include files */ +#include "qdf_types.h" +#include "qdf_status.h" +#include "qdf_trace.h" + +#define WIFIPOS_RESERVE_BYTES 100 +#define OEM_TARGET_SIGNATURE_LEN 8 +#define OEM_TARGET_SIGNATURE "QUALCOMM" + +#define MAX_CHANNELS 255 +#define OEM_CAP_MAX_NUM_CHANNELS 128 + +#define WIFI_POS_RSP_V1_FLAT_MEMORY 0x00000001 +#define WIFI_POS_RSP_V2_NL 0x00000002 + +/** + * enum wifi_pos_cmd_ids + * @WIFI_POS_CMD_REGISTRATION: app registration + * @WIFI_POS_CMD_GET_CAPS: get driver capabilities + * @WIFI_POS_CMD_GET_CH_INFO: get channel info + * @WIFI_POS_CMD_OEM_DATA: oem data req/rsp + * @WIFI_POS_CMD_MAX: Max cld80211 vendor sub cmds + */ + +enum wifi_pos_cmd_ids { + WIFI_POS_CMD_INVALID = 0, + WIFI_POS_CMD_REGISTRATION = 1, + WIFI_POS_CMD_SET_CAPS = 2, + WIFI_POS_CMD_GET_CAPS = 3, + WIFI_POS_CMD_GET_CH_INFO = 4, + WIFI_POS_CMD_OEM_DATA = 5, + WIFI_POS_CMD_ERROR = 6, + WIFI_POS_PEER_STATUS_IND = 7, + /* keep last */ + WIFI_POS_CMD__AFTER_LAST, + WIFI_POS_CMD_MAX = + WIFI_POS_CMD__AFTER_LAST - 1 +}; + + +/** + * struct wifi_pos_driver_version - Driver version identifier (w.x.y.z) + * @major: Version ID major number + * @minor: Version ID minor number + * @patch: Version ID patch number + * @build: Version ID build number + */ +struct qdf_packed wifi_pos_driver_version { + uint8_t major; + uint8_t minor; + uint8_t patch; + uint8_t build; +}; + +/** + * struct wifi_pos_channel_power + * @center_freq: Channel Center Frequency + * @chan_num: channel number + * @tx_power: TX power + */ +struct wifi_pos_channel_power { + uint32_t center_freq; + uint32_t chan_num; + uint32_t tx_power; +}; + +/** + * struct wifi_pos_channel_list + * @valid_channels: no of valid channels + * @chan_info: channel info + */ +struct qdf_packed wifi_pos_channel_list { + uint16_t num_channels; + struct wifi_pos_channel_power chan_info[MAX_CHANNELS]; +}; + +/** + * struct wifi_pos_driver_caps - OEM Data Capabilities + * @oem_target_signature: Signature of chipset vendor + * @oem_target_type: Chip type + * @oem_fw_version: Firmware version + * @driver_version: Host software version + * @allowed_dwell_time_min: Channel dwell time - allowed minimum + * @allowed_dwell_time_max: Channel dwell time - allowed maximum + * @curr_dwell_time_min: Channel dwell time - current minimim + * @curr_dwell_time_max: Channel dwell time - current maximum + * @supported_bands: Supported bands, 2.4G or 5G Hz + * @num_channels: Num of channels IDs to follow + * @channel_list: List of channel IDs + */ +struct qdf_packed wifi_pos_driver_caps { + uint8_t oem_target_signature[OEM_TARGET_SIGNATURE_LEN]; + uint32_t oem_target_type; + uint32_t oem_fw_version; + struct wifi_pos_driver_version driver_version; + uint16_t allowed_dwell_time_min; + uint16_t allowed_dwell_time_max; + uint16_t curr_dwell_time_min; + uint16_t curr_dwell_time_max; + uint16_t supported_bands; + uint16_t num_channels; + uint8_t channel_list[OEM_CAP_MAX_NUM_CHANNELS]; +}; + +/** + * struct wifi_pos_user_defined_caps - OEM capability to be exchanged between + * host and userspace + * @ftm_rr: FTM range report capability bit + * @lci_capability: LCI capability bit + * @reserved1: reserved + * @reserved2: reserved + */ +struct wifi_pos_user_defined_caps { + uint32_t ftm_rr:1; + uint32_t lci_capability:1; + uint32_t reserved1:30; + uint32_t reserved2; +}; + +/** + * struct wifi_pos_oem_get_cap_rsp - capabilities set by userspace and target. + * @driver_cap: target capabilities + * @user_defined_cap: capabilities set by userspace via set request + */ +struct qdf_packed wifi_pos_oem_get_cap_rsp { + struct wifi_pos_driver_caps driver_cap; + struct wifi_pos_user_defined_caps user_defined_cap; +}; +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_api.c b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_api.c index b465b2a1fccd6a5fe3c16ed1379ba0d7058f1aef..60e714cfa6a4927236d759ddc6333889d6d29e41 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_api.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -91,7 +91,16 @@ QDF_STATUS wifi_pos_deinit(void) QDF_STATUS wifi_pos_psoc_enable(struct wlan_objmgr_psoc *psoc) { - QDF_STATUS status = target_if_wifi_pos_register_events(psoc); + QDF_STATUS status; + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + + tx_ops = wifi_pos_get_tx_ops(psoc); + if (!tx_ops) { + wifi_pos_err("tx_ops is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tx_ops->wifi_pos_register_events(psoc); if (QDF_IS_STATUS_ERROR(status)) wifi_pos_err("target_if_wifi_pos_register_events failed"); @@ -101,7 +110,16 @@ QDF_STATUS wifi_pos_psoc_enable(struct wlan_objmgr_psoc *psoc) QDF_STATUS wifi_pos_psoc_disable(struct wlan_objmgr_psoc *psoc) { - QDF_STATUS status = target_if_wifi_pos_deregister_events(psoc); + QDF_STATUS status; + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + + tx_ops = wifi_pos_get_tx_ops(psoc); + if (!tx_ops) { + wifi_pos_err("tx_ops is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tx_ops->wifi_pos_deregister_events(psoc); if (QDF_IS_STATUS_ERROR(status)) wifi_pos_err("target_if_wifi_pos_deregister_events failed"); @@ -332,3 +350,57 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_register_get_fw_phy_mode_for_freq_cb( + struct wlan_objmgr_psoc *psoc, + void (*handler)(uint32_t, uint32_t, uint32_t *)) +{ + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; + + if (!psoc) { + wifi_pos_err("psoc is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!handler) { + wifi_pos_err("Null callback"); + return QDF_STATUS_E_NULL_VALUE; + } + wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); + if (!wifi_pos_psoc) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wifi_pos_psoc->wifi_pos_get_fw_phy_mode_for_freq = handler; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)) +{ + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; + + if (!psoc) { + wifi_pos_err("psoc is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!handler) { + wifi_pos_err("Null callback"); + return QDF_STATUS_E_NULL_VALUE; + } + wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); + if (!wifi_pos_psoc) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wifi_pos_psoc->wifi_pos_send_action = handler; + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c index f371bdc1f3ce72aa8fe48d571731f9001b461c86..871b38cdd04e43cb470be71cf503e23e16097975 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -77,16 +77,88 @@ static bool wifi_pos_get_tlv_support(struct wlan_objmgr_psoc *psoc) return true; } +struct wlan_lmac_if_wifi_pos_tx_ops * + wifi_pos_get_tx_ops(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc) { + wifi_pos_err("psoc is null"); + return NULL; + } + + return &psoc->soc_cb.tx_ops.wifi_pos_tx_ops; +} + +#ifdef CNSS_GENL +static uint8_t * +wifi_pos_prepare_reg_resp(uint32_t *rsp_len, + struct app_reg_rsp_vdev_info *vdevs_info) +{ + uint32_t *nl_sign; + uint8_t *resp_buf; + struct wifi_app_reg_rsp *app_reg_rsp; + + /* + * allocate ENHNC_FLAGS_LEN i.e. 4bytes extra memory in app_reg_resp + * to indicate NLA type response is supported for OEM request + * commands. + */ + *rsp_len = (sizeof(struct app_reg_rsp_vdev_info) * vdev_idx) + + sizeof(uint8_t) + ENHNC_FLAGS_LEN; + resp_buf = qdf_mem_malloc(*rsp_len); + if (!resp_buf) + return NULL; + + app_reg_rsp = (struct wifi_app_reg_rsp *)resp_buf; + app_reg_rsp->num_inf = vdev_idx; + qdf_mem_copy(&app_reg_rsp->vdevs, vdevs_info, + sizeof(struct app_reg_rsp_vdev_info) * vdev_idx); + + nl_sign = (uint32_t *)&app_reg_rsp->vdevs[vdev_idx]; + *nl_sign |= NL_ENABLE_OEM_REQ_RSP; + + return resp_buf; +} +#else +static uint8_t * +wifi_pos_prepare_reg_resp(uint32_t *rsp_len, + struct app_reg_rsp_vdev_info *vdevs_info) +{ + uint8_t *resp_buf; + struct wifi_app_reg_rsp *app_reg_rsp; + + *rsp_len = (sizeof(struct app_reg_rsp_vdev_info) * vdev_idx) + + sizeof(uint8_t); + resp_buf = qdf_mem_malloc(*rsp_len); + if (!resp_buf) + return NULL; + + app_reg_rsp = (struct wifi_app_reg_rsp *)resp_buf; + app_reg_rsp->num_inf = vdev_idx; + qdf_mem_copy(&app_reg_rsp->vdevs, vdevs_info, + sizeof(struct app_reg_rsp_vdev_info) * vdev_idx); + + return resp_buf; +} +#endif + static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, struct wifi_pos_req_msg *req) { uint8_t idx; uint32_t sub_type = 0; uint32_t channel_mhz = 0; - void *pdev_id = NULL; + uint32_t pdev_id = 0; uint32_t offset; struct oem_data_req data_req; struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + struct wlan_objmgr_pdev *pdev; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } wifi_pos_debug("Received data req pid(%d), len(%d)", req->pid, req->buf_len); @@ -113,7 +185,14 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, if (req->field_info_buf->fields[idx].id == WMIRTT_FIELD_ID_pdev) { - pdev_id = &req->buf[offset]; + pdev_id = *((uint32_t *)&req->buf[offset]); + /* pdev_id in FW starts from 1. So convert it to + * host id by decrementing it. + * zero has special meaning due to backward + * compatibility. Dont change it. + */ + if (pdev_id) + pdev_id -= 1; continue; } } @@ -132,25 +211,39 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, /* TBD */ break; case TARGET_OEM_CONFIGURE_FTMRR: - /* TBD */ + wifi_pos_debug("FTMRR request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; case TARGET_OEM_CONFIGURE_WRU: - /* TBD */ + wifi_pos_debug("WRU request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; default: wifi_pos_debug("invalid sub type or not passed"); - /* - * this is legacy MCL operation. pass whole msg to firmware as - * it is. - */ - tx_ops = target_if_wifi_pos_get_txops(psoc); + + tx_ops = wifi_pos_get_tx_ops(psoc); if (!tx_ops) { wifi_pos_err("tx ops null"); return QDF_STATUS_E_INVAL; } + + pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, + WLAN_WIFI_POS_CORE_ID); + if (!pdev) { + wifi_pos_err("pdev null"); + return QDF_STATUS_E_INVAL; + } data_req.data_len = req->buf_len; data_req.data = req->buf; - tx_ops->data_req_tx(psoc, &data_req); + tx_ops->data_req_tx(pdev, &data_req); + wlan_objmgr_pdev_release_ref(pdev, + WLAN_WIFI_POS_CORE_ID); break; } @@ -178,7 +271,7 @@ static QDF_STATUS wifi_pos_process_set_cap_req(struct wlan_objmgr_psoc *psoc, wifi_pos_obj->lci_capability = caps->lci_capability; error_code = qdf_status_to_os_return(QDF_STATUS_SUCCESS); wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, - ANI_MSG_SET_OEM_CAP_RSP, + WIFI_POS_CMD_SET_CAPS, sizeof(error_code), (uint8_t *)&error_code); @@ -198,22 +291,77 @@ static QDF_STATUS wifi_pos_process_get_cap_req(struct wlan_objmgr_psoc *psoc, } wifi_pos_debug("Received get cap req pid(%d), len(%d)", - req->pid, req->buf_len); + req->pid, req->buf_len); wifi_pos_populate_caps(psoc, &cap_rsp.driver_cap); cap_rsp.user_defined_cap.ftm_rr = wifi_pos_obj->ftm_rr; cap_rsp.user_defined_cap.lci_capability = wifi_pos_obj->lci_capability; + wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, - ANI_MSG_GET_OEM_CAP_RSP, + WIFI_POS_CMD_GET_CAPS, sizeof(cap_rsp), (uint8_t *)&cap_rsp); return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code) +{ + struct wifi_pos_err_msg_report err_report = {0}; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } + + err_report.msg_tag_len = OEM_MSG_RSP_HEAD_TAG_ID << 16; + err_report.msg_tag_len |= (sizeof(err_report) - + sizeof(err_report.err_rpt)) & 0x0000FFFF; + err_report.msg_subtype = TARGET_OEM_ERROR_REPORT_RSP; + err_report.req_id = req_id & 0xFFFF; + err_report.req_id |= ((err_code & 0xFF) << 16); + err_report.req_id |= (0x1 << 24); + err_report.time_left = 0xFFFFFFFF; + err_report.err_rpt.tag_len = OEM_MEAS_RSP_HEAD_TAG_ID << 16; + err_report.err_rpt.tag_len |= + (sizeof(struct wifi_pos_err_rpt)) & 0x0000FFFF; + memcpy(&err_report.err_rpt.dest_mac, dest_mac, QDF_MAC_ADDR_SIZE); + + wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, + WIFI_POS_CMD_OEM_DATA, + sizeof(err_report), + (uint8_t *)&err_report); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width *ch_width) +{ + struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; + + tx_ops = wifi_pos_get_tx_ops(psoc); + if (!tx_ops) { + qdf_print("tx ops null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!tx_ops->wifi_pos_get_vht_ch_width) { + wifi_pos_err("wifi pos get vht ch width is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + return tx_ops->wifi_pos_get_vht_ch_width( + psoc, ch_width); +} + static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev, - uint16_t chan, + uint16_t freq, struct wifi_pos_ch_info_rsp *chan_info) { struct ch_params ch_params = {0}; @@ -221,33 +369,35 @@ static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc, struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); uint32_t phy_mode; + QDF_STATUS status; if (!wifi_pos_psoc) { wifi_pos_err("wifi_pos priv obj is null"); return; } - /* Passing CH_WIDTH_MAX will give the max bandwidth supported */ - ch_params.ch_width = CH_WIDTH_MAX; + status = wifi_pos_get_vht_ch_width(psoc, &ch_params.ch_width); - wlan_reg_set_channel_params(pdev, chan, sec_ch_2g, &ch_params); - if (ch_params.center_freq_seg0) - chan_info->band_center_freq1 = - wlan_reg_legacy_chan_to_freq( - pdev, - ch_params.center_freq_seg0); - - wifi_pos_psoc->wifi_pos_get_phy_mode(chan, ch_params.ch_width, - &phy_mode); + if (QDF_IS_STATUS_ERROR(status)) { + wifi_pos_err("can not get vht ch width"); + return; + } + wlan_reg_set_channel_params_for_freq(pdev, freq, + sec_ch_2g, &ch_params); + chan_info->band_center_freq1 = ch_params.mhz_freq_seg0; + wifi_pos_psoc->wifi_pos_get_fw_phy_mode_for_freq(freq, + ch_params.ch_width, + &phy_mode); REG_SET_CHANNEL_MODE(chan_info, phy_mode); } static void wifi_pos_get_reg_info(struct wlan_objmgr_pdev *pdev, - uint32_t chan_num, uint32_t *reg_info_1, + uint16_t freq, uint32_t *reg_info_1, uint32_t *reg_info_2) { - uint32_t reg_power = wlan_reg_get_channel_reg_power(pdev, chan_num); + uint32_t reg_power = wlan_reg_get_channel_reg_power_for_freq(pdev, + freq); *reg_info_1 = 0; *reg_info_2 = 0; @@ -278,20 +428,55 @@ static uint32_t wifi_pos_get_valid_channels(uint8_t *channels, uint32_t num_ch, return num_valid_channels; } +static void wifi_pos_pdev_iterator(struct wlan_objmgr_psoc *psoc, + void *obj, void *arg) +{ + QDF_STATUS status; + uint8_t num_channels; + struct wlan_objmgr_pdev *pdev = obj; + struct wifi_pos_channel_list *chan_list = arg; + struct channel_power *ch_info = NULL; + + if (!chan_list) { + wifi_pos_err("wifi_pos priv arg is null"); + return; + } + ch_info = (struct channel_power *)chan_list->chan_info; + status = wlan_reg_get_channel_list_with_power(pdev, ch_info, + &num_channels); + + if (QDF_IS_STATUS_ERROR(status)) { + wifi_pos_err("Failed to get valid channel list"); + return; + } + chan_list->num_channels = num_channels; +} + +static void wifi_pos_get_ch_info(struct wlan_objmgr_psoc *psoc, + struct wifi_pos_channel_list *chan_list) +{ + wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, + wifi_pos_pdev_iterator, + chan_list, true, WLAN_WIFI_POS_CORE_ID); + wifi_pos_notice("num channels: %d", chan_list->num_channels); +} + static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, struct wifi_pos_req_msg *req) { - uint8_t idx; + uint8_t idx, band_mask; uint8_t *buf; - uint32_t len; + uint32_t len, i, freq; uint32_t reg_info_1; uint32_t reg_info_2; + bool oem_6g_support_disable; uint8_t *channels = req->buf; struct wlan_objmgr_pdev *pdev; uint32_t num_ch = req->buf_len; uint8_t valid_channel_list[NUM_CHANNELS]; - uint32_t num_valid_channels; + uint32_t num_valid_channels = 0; struct wifi_pos_ch_info_rsp *ch_info; + struct wifi_pos_channel_list *ch_list; struct wifi_pos_psoc_priv_obj *wifi_pos_obj = wifi_pos_get_psoc_priv_obj(psoc); @@ -313,38 +498,68 @@ static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, wifi_pos_err("Invalid number of channels"); return QDF_STATUS_E_INVAL; } - num_valid_channels = wifi_pos_get_valid_channels(channels, num_ch, + + ch_list = qdf_mem_malloc(sizeof(*ch_list)); + if (!ch_list) + return QDF_STATUS_E_NOMEM; + + if (num_ch == 0 && req->rsp_version == WIFI_POS_RSP_V2_NL) { + wifi_pos_get_ch_info(psoc, ch_list); + qdf_spin_lock_bh(&wifi_pos_obj->wifi_pos_lock); + oem_6g_support_disable = wifi_pos_obj->oem_6g_support_disable; + qdf_spin_unlock_bh(&wifi_pos_obj->wifi_pos_lock); + + /* ch_list has the frequencies in order of 2.4g, 5g & 6g */ + for (i = 0; i < ch_list->num_channels; i++) { + freq = ch_list->chan_info[i].center_freq; + if (oem_6g_support_disable && + WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) + continue; + num_valid_channels++; + } + } else { + /* v1 has ch_list with frequencies in order of 2.4g, 5g only */ + num_valid_channels = wifi_pos_get_valid_channels( + channels, num_ch, valid_channel_list); + band_mask = BIT(REG_BAND_5G) | BIT(REG_BAND_2G); + for (i = 0; i < num_valid_channels; i++) { + ch_list->chan_info[i].chan_num = valid_channel_list[i]; + ch_list->chan_info[i].center_freq = + wlan_reg_chan_band_to_freq( + pdev, + ch_list->chan_info[i].chan_num, + band_mask); + } + } len = sizeof(uint8_t) + sizeof(struct wifi_pos_ch_info_rsp) * num_valid_channels; buf = qdf_mem_malloc(len); if (!buf) { wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID); + qdf_mem_free(ch_list); return QDF_STATUS_E_NOMEM; } - qdf_mem_zero(buf, len); - /* First byte of message body will have num of channels */ buf[0] = num_valid_channels; ch_info = (struct wifi_pos_ch_info_rsp *)&buf[1]; for (idx = 0; idx < num_valid_channels; idx++) { - ch_info[idx].chan_id = valid_channel_list[idx]; - wifi_pos_get_reg_info(pdev, ch_info[idx].chan_id, - ®_info_1, ®_info_2); ch_info[idx].reserved0 = 0; - ch_info[idx].mhz = wlan_reg_get_channel_freq( - pdev, - valid_channel_list[idx]); + ch_info[idx].chan_id = ch_list->chan_info[idx].chan_num; + ch_info[idx].mhz = ch_list->chan_info[idx].center_freq; ch_info[idx].band_center_freq1 = ch_info[idx].mhz; ch_info[idx].band_center_freq2 = 0; ch_info[idx].info = 0; - if (wlan_reg_is_dfs_ch(pdev, valid_channel_list[idx])) + wifi_pos_get_reg_info(pdev, ch_info[idx].mhz, + ®_info_1, ®_info_2); + + if (wlan_reg_is_dfs_for_freq(pdev, ch_info[idx].mhz)) WIFI_POS_SET_DFS(ch_info[idx].info); wifi_update_channel_bw_info(psoc, pdev, - ch_info[idx].chan_id, + ch_info[idx].mhz, &ch_info[idx]); ch_info[idx].reg_info_1 = reg_info_1; @@ -352,9 +567,11 @@ static QDF_STATUS wifi_pos_process_ch_info_req(struct wlan_objmgr_psoc *psoc, } wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, - ANI_MSG_CHANNEL_INFO_RSP, + WIFI_POS_CMD_GET_CH_INFO, len, buf); + qdf_mem_free(buf); + qdf_mem_free(ch_list); wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID); return QDF_STATUS_SUCCESS; @@ -374,10 +591,9 @@ static QDF_STATUS wifi_pos_process_app_reg_req(struct wlan_objmgr_psoc *psoc, struct wifi_pos_req_msg *req) { QDF_STATUS ret = QDF_STATUS_SUCCESS; - uint8_t err = 0; + uint8_t err = 0, *app_reg_rsp; uint32_t rsp_len; char *sign_str = NULL; - struct wifi_app_reg_rsp *app_reg_rsp; struct app_reg_rsp_vdev_info vdevs_info[WLAN_UMAC_PSOC_MAX_VDEVS] = { { 0 } }; struct wifi_pos_psoc_priv_obj *wifi_pos_obj = @@ -412,23 +628,19 @@ static QDF_STATUS wifi_pos_process_app_reg_req(struct wlan_objmgr_psoc *psoc, wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, wifi_pos_vdev_iterator, vdevs_info, true, WLAN_WIFI_POS_CORE_ID); - rsp_len = (sizeof(struct app_reg_rsp_vdev_info) * vdev_idx) - + sizeof(uint8_t); - app_reg_rsp = qdf_mem_malloc(rsp_len); + + app_reg_rsp = wifi_pos_prepare_reg_resp(&rsp_len, vdevs_info); if (!app_reg_rsp) { ret = QDF_STATUS_E_NOMEM; err = OEM_ERR_NULL_CONTEXT; goto app_reg_failed; } - app_reg_rsp->num_inf = vdev_idx; - qdf_mem_copy(&app_reg_rsp->vdevs, vdevs_info, - sizeof(struct app_reg_rsp_vdev_info) * vdev_idx); if (!vdev_idx) wifi_pos_debug("no active vdev"); vdev_idx = 0; - wifi_pos_obj->wifi_pos_send_rsp(req->pid, ANI_MSG_APP_REG_RSP, + wifi_pos_obj->wifi_pos_send_rsp(req->pid, WIFI_POS_CMD_REGISTRATION, rsp_len, (uint8_t *)app_reg_rsp); qdf_mem_free(app_reg_rsp); @@ -436,7 +648,7 @@ static QDF_STATUS wifi_pos_process_app_reg_req(struct wlan_objmgr_psoc *psoc, app_reg_failed: - wifi_pos_obj->wifi_pos_send_rsp(req->pid, ANI_MSG_OEM_ERROR, + wifi_pos_obj->wifi_pos_send_rsp(req->pid, WIFI_POS_CMD_ERROR, sizeof(err), &err); return ret; } @@ -452,15 +664,15 @@ static QDF_STATUS wifi_pos_tlv_callback(struct wlan_objmgr_psoc *psoc, { wifi_pos_debug("enter: msg_type: %d", req->msg_type); switch (req->msg_type) { - case ANI_MSG_APP_REG_REQ: + case WIFI_POS_CMD_REGISTRATION: return wifi_pos_process_app_reg_req(psoc, req); - case ANI_MSG_OEM_DATA_REQ: + case WIFI_POS_CMD_OEM_DATA: return wifi_pos_process_data_req(psoc, req); - case ANI_MSG_CHANNEL_INFO_REQ: + case WIFI_POS_CMD_GET_CH_INFO: return wifi_pos_process_ch_info_req(psoc, req); - case ANI_MSG_SET_OEM_CAP_REQ: + case WIFI_POS_CMD_SET_CAPS: return wifi_pos_process_set_cap_req(psoc, req); - case ANI_MSG_GET_OEM_CAP_REQ: + case WIFI_POS_CMD_GET_CAPS: return wifi_pos_process_get_cap_req(psoc, req); default: wifi_pos_err("invalid request type"); @@ -582,7 +794,7 @@ int wifi_pos_oem_rsp_handler(struct wlan_objmgr_psoc *psoc, uint32_t app_pid; struct wifi_pos_psoc_priv_obj *priv = wifi_pos_get_psoc_priv_obj(psoc); - void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *); + wifi_pos_send_rsp_handler wifi_pos_send_rsp; if (!priv) { wifi_pos_err("private object is NULL"); @@ -620,51 +832,32 @@ int wifi_pos_oem_rsp_handler(struct wlan_objmgr_psoc *psoc, qdf_mem_copy(&data[oem_rsp->rsp_len_1 + oem_rsp->dma_len], oem_rsp->data_2, oem_rsp->rsp_len_2); - wifi_pos_send_rsp(app_pid, ANI_MSG_OEM_DATA_RSP, len, data); + wifi_pos_send_rsp(app_pid, WIFI_POS_CMD_OEM_DATA, len, data); qdf_mem_free(data); } else { - wifi_pos_send_rsp(app_pid, ANI_MSG_OEM_DATA_RSP, + wifi_pos_send_rsp(app_pid, WIFI_POS_CMD_OEM_DATA, oem_rsp->rsp_len_1, oem_rsp->data_1); } return 0; } -static void wifi_pos_pdev_iterator(struct wlan_objmgr_psoc *psoc, - void *obj, void *arg) +void wifi_pos_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) { - QDF_STATUS status; - uint8_t i, num_channels; - struct wlan_objmgr_pdev *pdev = obj; - struct wifi_pos_driver_caps *caps = arg; - struct channel_power ch_list[NUM_CHANNELS]; + struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops; - status = wlan_reg_get_channel_list_with_power(pdev, ch_list, - &num_channels); - - if (QDF_IS_STATUS_ERROR(status)) { - wifi_pos_err("Failed to get valid channel list"); - return; - } - for (i = 0; i < num_channels; i++) - caps->channel_list[i] = ch_list[i].chan_num; - caps->num_channels = num_channels; -} - -static void wifi_pos_get_ch_info(struct wlan_objmgr_psoc *psoc, - struct wifi_pos_driver_caps *caps) -{ - wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, - wifi_pos_pdev_iterator, - caps, true, WLAN_WIFI_POS_CORE_ID); - wifi_pos_err("num channels: %d", caps->num_channels); + wifi_pos_rx_ops = &rx_ops->wifi_pos_rx_ops; + wifi_pos_rx_ops->oem_rsp_event_rx = wifi_pos_oem_rsp_handler; } QDF_STATUS wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, struct wifi_pos_driver_caps *caps) { + uint16_t i, count = 0; + uint32_t freq; struct wifi_pos_psoc_priv_obj *wifi_pos_obj = wifi_pos_get_psoc_priv_obj(psoc); + struct wifi_pos_channel_list *ch_list = NULL; wifi_pos_debug("Enter"); if (!wifi_pos_obj) { @@ -672,6 +865,10 @@ QDF_STATUS wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_NULL_VALUE; } + ch_list = qdf_mem_malloc(sizeof(*ch_list)); + if (!ch_list) + return QDF_STATUS_E_NOMEM; + strlcpy(caps->oem_target_signature, OEM_TARGET_SIGNATURE, OEM_TARGET_SIGNATURE_LEN); @@ -686,6 +883,16 @@ QDF_STATUS wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, caps->curr_dwell_time_min = wifi_pos_obj->current_dwell_time_min; caps->curr_dwell_time_max = wifi_pos_obj->current_dwell_time_max; caps->supported_bands = wlan_objmgr_psoc_get_band_capability(psoc); - wifi_pos_get_ch_info(psoc, caps); + wifi_pos_get_ch_info(psoc, ch_list); + + /* copy valid channels list to caps */ + for (i = 0; i < ch_list->num_channels; i++) { + freq = ch_list->chan_info[i].center_freq; + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq)) + continue; + caps->channel_list[count++] = ch_list->chan_info[i].chan_num; + } + caps->num_channels = count; + qdf_mem_free(ch_list); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main_i.h b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main_i.h index 1d423103d5f3dbd22fb20453c40d3a7714d5a427..227c2ceb1d4829c945fb31afc5c431f05b8b4c10 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_main_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,11 @@ #ifndef _WIFI_POS_MAIN_H_ #define _WIFI_POS_MAIN_H_ +#ifdef CNSS_GENL +#define ENHNC_FLAGS_LEN 4 +#define NL_ENABLE_OEM_REQ_RSP 0x00000001 +#endif + /* forward reference */ struct wlan_objmgr_psoc; @@ -65,4 +70,12 @@ QDF_STATUS wifi_pos_psoc_obj_destroyed_notification( int wifi_pos_oem_rsp_handler(struct wlan_objmgr_psoc *psoc, struct oem_data_rsp *oem_rsp); +/** + * wifi_pos_get_tx_ops: api to get tx ops + * @psoc: pointer to psoc object + * + * Return: tx ops + */ +struct wlan_lmac_if_wifi_pos_tx_ops * + wifi_pos_get_tx_ops(struct wlan_objmgr_psoc *psoc); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg.c b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg.c index ba6fa8441de616d727d71e0171106ccef5f8e15e..00f82358380acf4027ab3a41dec122a38807a89e 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,8 +26,8 @@ #include "wlan_ptt_sock_svc.h" QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, - struct wifi_pos_req_msg *req, - void (*send_rsp_cb)(uint32_t, uint32_t, uint32_t, uint8_t *)) + struct wifi_pos_req_msg *req, + wifi_pos_send_rsp_handler send_rsp_cb) { uint8_t err; uint32_t app_pid; @@ -46,21 +46,22 @@ QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, wifi_pos_psoc_obj->wifi_pos_send_rsp = send_rsp_cb; is_app_registered = wifi_pos_psoc_obj->is_app_registered; app_pid = wifi_pos_psoc_obj->app_pid; + wifi_pos_psoc_obj->rsp_version = req->rsp_version; qdf_spin_unlock_bh(&wifi_pos_psoc_obj->wifi_pos_lock); if (!wifi_pos_psoc_obj->wifi_pos_req_handler) { wifi_pos_err("wifi_pos_psoc_obj->wifi_pos_req_handler is null"); err = OEM_ERR_NULL_CONTEXT; - send_rsp_cb(app_pid, ANI_MSG_OEM_ERROR, sizeof(err), &err); + send_rsp_cb(app_pid, WIFI_POS_CMD_ERROR, sizeof(err), &err); return QDF_STATUS_E_NULL_VALUE; } - if (req->msg_type != ANI_MSG_APP_REG_REQ && + if (req->msg_type != WIFI_POS_CMD_REGISTRATION && (!is_app_registered || app_pid != req->pid)) { wifi_pos_err("requesting app is not registered, app_registered: %d, requesting pid: %d, stored pid: %d", is_app_registered, req->pid, app_pid); err = OEM_ERR_APP_NOT_REGISTERED; - send_rsp_cb(app_pid, ANI_MSG_OEM_ERROR, sizeof(err), &err); + send_rsp_cb(app_pid, WIFI_POS_CMD_ERROR, sizeof(err), &err); return QDF_STATUS_E_INVAL; } @@ -101,3 +102,40 @@ void ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc *psoc, uint32_t val) qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); } +void ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = + wifi_pos_get_psoc_priv_obj(psoc); + if (!wifi_pos_psoc) { + wifi_pos_alert("unable to get wifi_pos psoc obj"); + return; + } + + qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); + wifi_pos_psoc->oem_6g_support_disable = val; + qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); +} + +bool ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc *psoc) +{ + uint32_t val = 0; + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_psoc) { + wifi_pos_alert("unable to get wifi_pos psoc obj"); + return false; + } + + qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); + val = wifi_pos_psoc->rsp_version; + qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); + + if (val == WIFI_POS_RSP_V2_NL) + return true; + else + return false; + +} + diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg_i.h b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg_i.h index a5dd1f4f878f389e04b965ec339e01ff9676507e..730be472f4104de06386f5f2912042099dc6d668 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_ucfg_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -41,7 +41,7 @@ struct wifi_pos_req_msg; * Return: status of operation */ QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, - struct wifi_pos_req_msg *req, - void (*send_rsp_cb)(uint32_t, uint32_t, uint32_t, uint8_t *)); + struct wifi_pos_req_msg *req, + wifi_pos_send_rsp_handler send_rsp_cb); #endif /* _WIFI_POS_UCFG_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils.c b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils.c index ce7a9adac411e4015067abcf30a371894ab5767f..d4144d01048e1eeb43fbd61f9882ae1ed6be762d 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils.c +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -59,6 +59,8 @@ struct wlan_objmgr_psoc *wifi_pos_get_psoc(void) return tmp; } +qdf_export_symbol(wifi_pos_get_psoc); + void wifi_pos_set_psoc(struct wlan_objmgr_psoc *psoc) { struct wlan_objmgr_psoc *tmp; @@ -103,3 +105,5 @@ struct wifi_pos_psoc_priv_obj *wifi_pos_get_psoc_priv_obj( return obj; } + +qdf_export_symbol(wifi_pos_get_psoc_priv_obj); diff --git a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils_i.h b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils_i.h index 0b1c5cdc0c4238bb3d10eb85b2f21f81f8e80957..465de82a8ef766aaa8de07e352b8f66f03e34df0 100644 --- a/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils_i.h +++ b/drivers/staging/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_utils_i.h @@ -30,6 +30,8 @@ #include "qdf_status.h" #include "ol_defines.h" #include "qdf_trace.h" +#include "qdf_module.h" +#include "wifi_pos_utils_pub.h" struct wlan_objmgr_psoc; struct wifi_pos_req_msg; @@ -59,11 +61,6 @@ struct wifi_pos_req_msg; #define OEM_APP_SIGNATURE_LEN 16 #define OEM_APP_SIGNATURE_STR "QUALCOMM-OEM-APP" -#define OEM_TARGET_SIGNATURE_LEN 8 -#define OEM_TARGET_SIGNATURE "QUALCOMM" - -#define OEM_CAP_MAX_NUM_CHANNELS 128 - #ifndef OEM_DATA_RSP_SIZE #define OEM_DATA_RSP_SIZE 1724 /* Header + VHT80 CIR * 2 chains */ @@ -123,70 +120,39 @@ struct oem_data_rsp { }; /** - * struct wifi_pos_driver_version - Driver version identifier (w.x.y.z) - * @major: Version ID major number - * @minor: Version ID minor number - * @patch: Version ID patch number - * @build: Version ID build number + * struct wifi_pos_err_rpt - Error report response for userspace. + * @tag_len: tlv header of the message. + * @info: Report info. Reserved for error report. + * @dest_mac: Mac address of the sta in the request. + * @reserved: Reserved in error report. */ -struct qdf_packed wifi_pos_driver_version { - uint8_t major; - uint8_t minor; - uint8_t patch; - uint8_t build; +struct qdf_packed wifi_pos_err_rpt { + uint32_t tag_len; + uint32_t info; + uint8_t dest_mac[QDF_MAC_ADDR_SIZE + 2]; + uint32_t reserved; }; +#define OEM_MSG_RSP_HEAD_TAG_ID 33 +#define OEM_MEAS_RSP_HEAD_TAG_ID 41 /** - * struct wifi_pos_driver_caps - OEM Data Capabilities - * @oem_target_signature: Signature of chipset vendor, e.g. QUALCOMM - * @oem_target_type: Chip type - * @oem_fw_version: Firmware version - * @driver_version: Host software version - * @allowed_dwell_time_min: Channel dwell time - allowed minimum - * @allowed_dwell_time_max: Channel dwell time - allowed maximum - * @curr_dwell_time_min: Channel dwell time - current minimim - * @curr_dwell_time_max: Channel dwell time - current maximum - * @supported_bands: Supported bands, 2.4G or 5G Hz - * @num_channels: Num of channels IDs to follow - * @channel_list: List of channel IDs + * struct wifi_pos_err_msg_report - Error report message + * @msg_tag_len: Message tlv header + * @msg_subtype: Message subtype + * @req_id: id corresponding to the request. + * @fragment_info: Valid only for fragments. + * @pdev_id: pdev_id of radion. + * @time_left: time left in the measurment req. + * @err_rpt: Error report data. */ -struct qdf_packed wifi_pos_driver_caps { - uint8_t oem_target_signature[OEM_TARGET_SIGNATURE_LEN]; - uint32_t oem_target_type; - uint32_t oem_fw_version; - struct wifi_pos_driver_version driver_version; - uint16_t allowed_dwell_time_min; - uint16_t allowed_dwell_time_max; - uint16_t curr_dwell_time_min; - uint16_t curr_dwell_time_max; - uint16_t supported_bands; - uint16_t num_channels; - uint8_t channel_list[OEM_CAP_MAX_NUM_CHANNELS]; -}; - -/** - * struct wifi_pos_user_defined_caps - OEM capability to be exchanged between - * host and userspace - * @ftm_rr: FTM range report capability bit - * @lci_capability: LCI capability bit - * @reserved1: reserved - * @reserved2: reserved - */ -struct wifi_pos_user_defined_caps { - uint32_t ftm_rr:1; - uint32_t lci_capability:1; - uint32_t reserved1:30; - uint32_t reserved2; -}; - -/** - * struct wifi_pos_oem_get_cap_rsp - capabilities set by userspace and target. - * @driver_cap: target capabilities - * @user_defined_cap: capabilities set by userspace via set request - */ -struct qdf_packed wifi_pos_oem_get_cap_rsp { - struct wifi_pos_driver_caps driver_cap; - struct wifi_pos_user_defined_caps user_defined_cap; +struct qdf_packed wifi_pos_err_msg_report { + uint32_t msg_tag_len; + uint32_t msg_subtype; + uint32_t req_id; + uint32_t fragment_info; + uint32_t pdev_id; + uint32_t time_left; + struct wifi_pos_err_rpt err_rpt; }; /** @@ -243,6 +209,9 @@ struct wifi_pos_dma_rings_cfg { void *srng; }; +typedef void (*wifi_pos_send_rsp_handler)(uint32_t, enum wifi_pos_cmd_ids, + uint32_t, uint8_t *); + /** * struct wifi_pos_psoc_priv_obj - psoc obj data for wifi_pos * @app_pid: pid of app registered to host driver @@ -266,8 +235,16 @@ struct wifi_pos_dma_rings_cfg { * @dma_buf_pool: DMA buffer pools maintained at host: this will be 2-D array * where with num_rows = number of rings num_elements in each row = ring depth * @wifi_pos_lock: lock to access wifi pos priv object + * @oem_6g_support_disable: oem target 6ghz support is disabled if set * @wifi_pos_req_handler: function pointer to handle TLV or non-TLV * @wifi_pos_send_rsp: function pointer to send msg to userspace APP + * @wifi_pos_get_phy_mode: function pointer to get wlan phymode for given + * channel, channel width + * @wifi_pos_get_fw_phy_mode_for_freq: function pointer to get fw phymode + * for given freq and channel width + * @wifi_pos_send_action: function pointer to send registered action frames + * to userspace APP + * @rsp_version: rsp version * * wifi pos request messages * <----- fine_time_meas_cap (in bits) -----> @@ -303,10 +280,17 @@ struct wifi_pos_psoc_priv_obj { struct wifi_pos_dma_buf_info **dma_buf_pool; qdf_spinlock_t wifi_pos_lock; + bool oem_6g_support_disable; QDF_STATUS (*wifi_pos_req_handler)(struct wlan_objmgr_psoc *psoc, struct wifi_pos_req_msg *req); - void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *); + wifi_pos_send_rsp_handler wifi_pos_send_rsp; void (*wifi_pos_get_phy_mode)(uint8_t, uint32_t, uint32_t *); + void (*wifi_pos_get_fw_phy_mode_for_freq)(uint32_t, uint32_t, + uint32_t *); + void (*wifi_pos_send_action)(struct wlan_objmgr_psoc *psoc, + uint32_t oem_subtype, uint8_t *buf, + uint32_t len); + uint32_t rsp_version; }; /** diff --git a/drivers/staging/qca-wifi-host-cmn/utils/epping/inc/epping_internal.h b/drivers/staging/qca-wifi-host-cmn/utils/epping/inc/epping_internal.h index 7b1e6e89dea644f895ec82b01533634820a7ecf7..ff1960e9423f28a6099f4528fa83d72953e9c16c 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/epping/inc/epping_internal.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/epping/inc/epping_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -60,6 +60,10 @@ #define EPPING_MAX_ADAPTERS 1 #define EPPING_LOG(level, args ...) QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args) +#define EPPING_HEX_DUMP(level, data, len) qdf_trace_hex_dump( \ + QDF_MODULE_ID_HDD, \ + level, \ + data, buf_len) struct epping_cookie { HTC_PACKET HtcPkt; /* HTC packet wrapper */ @@ -79,7 +83,7 @@ typedef enum { #define MAX_COOKIE_SLOT_SIZE 512 #define MAX_TX_PKT_DUP_NUM 4 -#ifdef HIF_PCI +#if defined(HIF_PCI) || defined(HIF_IPCI) #define WLAN_EPPING_DELAY_TIMEOUT_US 10 #define EPPING_MAX_CE_NUMS 8 #define EPPING_MAX_WATER_MARK 8 @@ -110,7 +114,7 @@ typedef struct epping_context { unsigned int kperf_num_tx_acks[EPPING_MAX_NUM_EPIDS]; unsigned int total_rx_recv; unsigned int total_tx_acks; -#ifdef HIF_PCI +#if defined(HIF_PCI) || defined(HIF_IPCI) epping_poll_t epping_poll[EPPING_MAX_NUM_EPIDS]; #endif struct epping_cookie *cookie_list; @@ -181,12 +185,12 @@ epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx, bool rtnl_held); void epping_destroy_adapter(epping_adapter_t *adapter); int epping_connect_service(epping_context_t *pEpping_ctx); -#ifdef HIF_PCI +#if defined(HIF_PCI) || defined(HIF_IPCI) void epping_register_tx_copier(HTC_ENDPOINT_ID eid, epping_context_t *pEpping_ctx); void epping_unregister_tx_copier(HTC_ENDPOINT_ID eid, epping_context_t *pEpping_ctx); void epping_tx_copier_schedule(epping_context_t *pEpping_ctx, HTC_ENDPOINT_ID eid, qdf_nbuf_t skb); -#endif /* HIF_PCI */ +#endif /* HIF_PCI || HIF_IPCI */ #endif /* end #ifndef EPPING_INTERNAL_H */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_helper.c b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_helper.c index fe17d8241cc06d9a683e7de648f98d8a6921e801..a75878af451fc13554419669ed6e1b46dcdd9686 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_helper.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_helper.c @@ -127,24 +127,11 @@ void epping_get_dummy_mac_addr(tSirMacAddr macAddr) void epping_hex_dump(void *data, int buf_len, const char *str) { - char *buf = (char *)data; - int i; + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "%s: E, %s", __func__, str); - printk("%s: E, %s\n", __func__, str); - for (i = 0; (i + 7) < buf_len; i += 8) { - printk("%02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[i], - buf[i + 1], - buf[i + 2], - buf[i + 3], - buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); - } + EPPING_HEX_DUMP(QDF_TRACE_LEVEL_INFO, data, buf_len); - /* Dump the bytes in the last line */ - for (; i < buf_len; i++) { - printk("%02x ", buf[i]); - } - printk("\n%s: X %s\n", __func__, str); + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "%s: X %s", __func__, str); } void *epping_get_qdf_ctx(void) diff --git a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_rx.c b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_rx.c index 0a5ae0b2654b258054c58c6ef2b97386bcb9f13e..a273146fbdaf28a14eeeac3cbe84002294e85493 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_rx.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_rx.c @@ -114,7 +114,8 @@ void epping_rx(void *ctx, HTC_PACKET *pPacket) if (status != QDF_STATUS_SUCCESS) { if (status != QDF_STATUS_E_CANCELED) { - printk("%s: RX ERR (%d)\n", __func__, status); + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: RX ERR (%d)", + __func__, status); } qdf_nbuf_free(pktSkb); return; diff --git a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_tx.c b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_tx.c index b1969382eb8d434c9d21d5dd9444480d6fb7f19a..202e02e56758ff062ddf02a0acd82983f83cdb58 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_tx.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_tx.c @@ -366,8 +366,9 @@ void epping_tx_complete(void *ctx, HTC_PACKET *htc_pkt) flushing = true; } if (status != QDF_STATUS_E_RESOURCES) { - printk("%s() -TX ERROR, status: 0x%x\n", - __func__, status); + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s() -TX ERROR, status: 0x%x", + __func__, status); } } else { EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__); diff --git a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_txrx.c b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_txrx.c index 5332f4a6ba138f1efd8211cbb788ecc550acbc3d..0200fd6f43105b1a7e547f1534bdef1c42a675c5 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_txrx.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/epping/src/epping_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -419,7 +419,8 @@ int epping_connect_service(epping_context_t *pEpping_ctx) connect.EpCallbacks.EpRecvRefill = epping_refill; connect.EpCallbacks.EpSendFull = epping_tx_queue_full /* ar6000_tx_queue_full */; -#elif defined(HIF_USB) || defined(HIF_PCI) || defined(HIF_SNOC) +#elif defined(HIF_USB) || defined(HIF_PCI) || defined(HIF_SNOC) || \ + defined(HIF_IPCI) connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */; connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */; /* disable flow control for hw flow control */ @@ -440,7 +441,8 @@ int epping_connect_service(epping_context_t *pEpping_ctx) } pEpping_ctx->EppingEndpoint[0] = response.Endpoint; -#if defined(HIF_PCI) || defined(HIF_USB) || defined(HIF_SNOC) +#if defined(HIF_PCI) || defined(HIF_USB) || defined(HIF_SNOC) || \ + defined(HIF_IPCI) connect.service_id = WMI_DATA_BK_SVC; status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); if (QDF_IS_STATUS_ERROR(status)) { diff --git a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c index cc98cdcf939af57a91c751a4e74e0720bcd64e09..c0889fd83db5af83c4bd40123c7ef8ec160f45f8 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1328,6 +1328,16 @@ int dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_log_lvl) return 0; } +int dbglog_set_mod_wow_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_log_lvl) +{ + /* set the global module level to log_lvl */ + wma_config_debug_module_cmd(wmi_handle, + WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP, + mod_log_lvl, NULL, 0); + + return 0; +} + void dbglog_set_vap_enable_bitmap(wmi_unified_t wmi_handle, uint32_t vap_enable_bitmap) @@ -3590,8 +3600,9 @@ A_BOOL dbglog_coex_print_handler(uint32_t mod_id, dbglog_printf_no_line_break(timestamp, vap_id, "%s: %u", dbg_id_str, args[0]); for (i = 1; i < numargs; i++) - printk("%u", args[i]); - printk("\n"); + dbglog_printf_no_line_break(timestamp, vap_id, + "%u", args[i]); + dbglog_printf_no_line_break(timestamp, vap_id, "\n"); } else { return false; } diff --git a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.h b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.h index ea613def20f32e1f4896a092bbc4a3d3808d6472..93b21efea03a7a42c01d51dcf02a14d24ced32f4 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/fwlog/dbglog_host.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -102,7 +102,7 @@ int dbglog_set_timestamp_resolution(wmi_unified_t wmi_handle, uint16_t tsr); -/** Enable reporting. If it is set to false then Traget wont deliver +/** Enable reporting. If it is set to false then Target wont deliver * any debug information */ int @@ -129,6 +129,19 @@ dbglog_set_log_lvl(wmi_unified_t wmi_handle, DBGLOG_LOG_LVL log_lvl); int dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_id_lvl); +/* + * set the debug log level for wow module + * mod_id_lvl : the format is more user friendly. + * module_id = mod_id_lvl/10; + * log_level = mod_id_lvl%10; + * example : mod_id_lvl is 153. then module id is 15 and log level is 3. + * this format allows user to pass a sinlge value + * (which is the most convenient way for most of the OSs) + * to be passed from user to the driver. + */ +int +dbglog_set_mod_wow_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_id_lvl); + /** Enable/Disable the logging for VAP */ int dbglog_vap_log_enable(wmi_unified_t wmi_handle, uint16_t vap_id, @@ -237,6 +250,12 @@ dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_id_lvl) { return A_OK; } + +static inline int +dbglog_set_mod_wow_log_lvl(wmi_unified_t wmi_handle, uint32_t mod_id_lvl) +{ + return A_OK; +} #endif /* FEATURE_FW_LOG_PARSING */ #ifdef __cplusplus diff --git a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_event.h b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_event.h index b07365dfd3b9e4b2b9b708915b64c563b7681d81..6a4ea97c72939fd6fe5d4786a058136b3929ed3e 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_event.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_event.h @@ -316,6 +316,7 @@ typedef struct { * @est_link_speed: link speed of connection, units in Mbps * @result_code: result code of connection success or failure * @reason_code: if failed then what is the reason + * @op_freq: channel frequency in MHz on which AP is connected */ struct host_event_wlan_connection_stats { int8_t rssi; @@ -333,6 +334,7 @@ struct host_event_wlan_connection_stats { uint32_t est_link_speed; uint16_t result_code; uint16_t reason_code; + uint32_t op_freq; } qdf_packed; /*------------------------------------------------------------------------- @@ -896,6 +898,7 @@ enum wifi_connectivity_events { * @WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER: iface change timer running * @WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE: Montitor mode wakelock * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART: Wakelock for Idle Restart + * @WIFI_POWER_EVENT_WAKELOCK_TDLS: Wakelock for TDLS * * Indicates the reason for which the wakelock was taken/released */ @@ -923,6 +926,7 @@ enum wake_lock_reason { WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER, WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE, WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART, + WIFI_POWER_EVENT_WAKELOCK_TDLS, }; /* The length of interface name should >= IFNAMSIZ */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_log.h b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_log.h index 70690efa870f436cc019f1fa3189f3fb5a14853f..a83a21446dd9b58fa0e0e68c34e2303dc39234a5 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_log.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/host_diag_core_log.h @@ -100,6 +100,7 @@ typedef struct { uint8_t operatingChannel; uint8_t beaconInterval; uint8_t status; + uint32_t op_freq; } host_log_ibss_pkt_type; /*--------------------------------------------------------------------------- @@ -284,6 +285,271 @@ struct host_log_cold_boot_cal_data_type { uint8_t cb_cal_data[HOST_LOG_MAX_COLD_BOOT_CAL_DATA_SIZE]; }; +#define WLAN_MAX_ROAM_CANDIDATE_AP 9 +#define WLAN_MAX_ROAM_SCAN_CHAN 38 +#define WLAN_MAX_SSID_SIZE 32 + +/** + * host_log_wlan_mgmt_tx_rx_info: To capture TX/RX mgmt frames' payload + * @hdr: Log header + * @version: Version number of the payload + * @vdev_id: Vdev id + * @is_tx: 1 - TX frame, 0 - RX frame + * @mgmt_type: type of frames, value: enum wifi_frm_type + * @mgmt_subtype: subtype of mgmt frame, value: enum mgmt_frm_subtype + * @mgmt_frame_seq_num: Frame sequence number in 802.11 header + * @operating_freq: operating frequency of AP + * @ssid_len: length of SSID, max 32 bytes long as per standard + * @ssid: SSID of connected AP + * @self_mac_addr: mac address of self interface + * @bssid: BSSID for which frame is received + * @mac_failure_reason: Internal driver failure reason + * @mgmt_status_code: 802.11 management frame response status code from + * section 9.4.1.9 IEEE 802.11 - 2016 + * @auth_algo: Authentication algorithm number + * @auth_transaction_num: Authentication transaction sequence number + * @is_retry: Is retry frame + * @rssi: RSSI for the received frame + * @origin: 1- Sent by host. 2- sent by firmware + */ +struct host_log_wlan_mgmt_tx_rx_info { + log_hdr_type hdr; + uint8_t version; + uint8_t vdev_id; + bool is_tx; + uint8_t mgmt_type; + uint8_t mgmt_subtype; + uint16_t mgmt_frame_seq_num; + uint8_t operating_freq; + uint8_t ssid_len; + char ssid[WLAN_MAX_SSID_SIZE]; + uint8_t self_mac_addr[QDF_MAC_ADDR_SIZE]; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; + uint16_t mac_failure_reason; + uint16_t mgmt_status_code; + uint8_t auth_algo; + uint8_t auth_transaction_num; + uint8_t is_retry; + uint32_t rssi; + uint8_t origin; +} qdf_packed; + +/** + * struct wlan_roam_btm_trigger_data - BTM roam trigger related information + * @btm_request_mode: BTM request mode - solicited/unsolicited + * @disassoc_timer: Number of TBTT before AP disassociates the STA in ms + * @validity_interval: Preferred candidate list validity interval in ms + * @candidate_list_count: Number of candidates in BTM request. + * @btm_resp_status: Status code of the BTM response. + */ +struct wlan_roam_btm_trigger_data { + uint8_t btm_request_mode; + uint32_t disassoc_timer; + uint32_t validity_interval; + uint16_t candidate_list_count; + uint16_t btm_resp_status; +} qdf_packed; + +/** + * struct wlan_roam_cu_trigger_data - BSS Load roam trigger parameters + * @cu_load: Connected AP CU load percentage + */ +struct wlan_roam_cu_trigger_data { + uint16_t cu_load; +} qdf_packed; + +/** + * Struct wlan_roam_rssi_trigger_data - RSSI roam trigger related + * parameters + * @threshold: RSSI threshold value in dBm for LOW rssi roam trigger + */ +struct wlan_roam_rssi_trigger_data { + uint32_t threshold; +} qdf_packed; + +/** + * struct wlan_roam_deauth_trigger_data - Deauth roaming trigger related + * parameters + * @type: 1- Deauthentication 2- Disassociation + * @reason: Status code of the Deauth/Disassoc received + */ +struct wlan_roam_deauth_trigger_data { + uint8_t type; + uint32_t reason; +} qdf_packed; + +/** + * struct host_log_wlan_roam_trigger_info - Roam trigger + * related info + * @hdr: Log header + * @version: Version number of the payload + * @vdev_id: Vdev id + * @trigger_reason: Roaming trigger reason + * @trigger_sub_reason: Roaming trigger sub reason + * @current_rssi: Current connected AP RSSI + * @timestamp: Host driver timestamp in msecs + * @btm_trig_data: BTM trigger related data + * @cu_load_data: CU load trigger related data + * @rssi_trig_data: RSSI roam trigger related data + * @deauth_trig_data: Deauth Roam trigger related data + */ +struct host_log_wlan_roam_trigger_info { + log_hdr_type hdr; + uint8_t version; + uint8_t vdev_id; + uint32_t trigger_reason; + uint32_t trigger_sub_reason; + uint32_t current_rssi; + uint32_t timestamp; + union { + struct wlan_roam_btm_trigger_data btm_trig_data; + struct wlan_roam_cu_trigger_data cu_load_data; + struct wlan_roam_rssi_trigger_data rssi_trig_data; + struct wlan_roam_deauth_trigger_data deauth_trig_data; + }; +} qdf_packed; + +/** + * struct host_log_wlan_roam_candidate_info - Roam scan candidate APs related + * info + * @version: Payload structure version + * @timestamp: Host timestamp in millisecs + * @type: 0 - Candidate AP; 1 - Current connected AP. + * @bssid: AP bssid. + * @freq: Channel frquency + * @cu_load: Channel utilization load of the AP. + * @cu_score: Channel Utilization score. + * @rssi: Candidate AP rssi + * @rssi_score: AP RSSI score + * @total_score: Total score of the candidate AP. + * @etp: Estimated throughput value of the AP in Mbps + */ +struct host_log_wlan_roam_candidate_info { + uint8_t version; + uint32_t timestamp; + uint8_t type; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; + uint16_t freq; + uint32_t cu_load; + uint32_t cu_score; + uint32_t rssi; + uint32_t rssi_score; + uint32_t total_score; + uint32_t etp; +} qdf_packed; + +/** + * struct host_log_wlan_roam_scan_data - Roam scan event details + * @hdr: Log header + * @version: Version number of the diag log payload + * @vdev_id: Vdev ID + * @type: 0 - Partial roam scan; 1 - Full roam scan + * @num_ap: Number of candidate APs. + * @num_chan: Number of channels. + * @timestamp: Time of day in milliseconds at which scan was triggered + * @trigger_reason: Roam scan trigger reason + * @next_rssi_threshold: Next roam can trigger rssi threshold + * @chan_freq: List of frequencies scanned as part of roam scan + * @ap: List of candidate AP info + */ +struct host_log_wlan_roam_scan_data { + log_hdr_type hdr; + uint8_t version; + uint8_t vdev_id; + uint16_t type; + uint8_t num_ap; + uint8_t num_chan; + uint32_t timestamp; + uint32_t trigger_reason; + uint32_t next_rssi_threshold; + uint16_t chan_freq[WLAN_MAX_ROAM_SCAN_CHAN]; + struct host_log_wlan_roam_candidate_info ap[WLAN_MAX_ROAM_CANDIDATE_AP]; +} qdf_packed; + +/** + * struct host_log_wlan_roam_result_info - Roam result related info. + * @hdr: Log header + * @version: Payload strcuture version + * @vdev_id: Vdev Id + * @status: 0 - Roaming is success ; 1 - Roaming failed + * @timestamp: Host timestamp in millisecs + * @fail_reason: One of WMI_ROAM_FAIL_REASON_ID + */ +struct host_log_wlan_roam_result_info { + log_hdr_type hdr; + uint8_t version; + uint8_t vdev_id; + bool status; + uint32_t timestamp; + uint32_t fail_reason; +} qdf_packed; + +/** + * struct wlan_rrm_beacon_report - RRM beacon report related + * parameters + * @req_bssid: beacon report requestor BSSID + * @req_ssid: Requested SSID for beacon report + * @is_wildcard_bssid: Is the BSSID FF:FF:FF:FF:FF:FF + * @req_reg_class: Regulatory class mentioned in the request + * @req_measurement_mode: Measurement mode. Active/Passive/Beacon report Table + * @req_measurement_duration: Measurement duration requested. + * @num_reports_in_frame: Number of BSS scanned + * @is_last_frame_in_req: True if this frame is the last frame sent for the + * request + */ +struct wlan_rrm_beacon_report { + uint8_t req_bssid[QDF_MAC_ADDR_SIZE]; + uint8_t req_ssid[WLAN_MAX_SSID_SIZE]; + bool is_wildcard_bssid; + uint8_t req_reg_class; + uint16_t req_measurement_mode; + uint16_t req_measurement_duration; + uint8_t num_reports_in_frame; + bool is_last_frame_in_req; +} qdf_packed; + +/** + * struct host_log_wlan_rrm_tx_rx_info - RRM frame related details + * @hdr: Log header + * @version: Version of the payload struture + * @vdev_id: Vdev id + * @orgin: Sent by host or firmware + * @is_tx: Is Tx frame or RX frame + * @roam_result: Roaming result + * @timestamp: Time of the day in milliseconds + * @mgmt_frame_seq_num: Frame sequence number + * @received_chan_freq: Frame received channel frequency + * @action_category: Action frame category + * @rrm_action_code: Radio measurement/Noise measurement + * @radio_measurement_type: Neighbor report/Beacon report + * @bssid: BSSID field in frame + * @req_num_freq: Number of frequencies provided in request + * @req_freq: Frequencies requested + * @fail_reason_code: response TX failure status code + * @rssi: Rx frame rssi + * @bcn_rpt: Beacon report related parameters + */ +struct host_log_wlan_rrm_tx_rx_info { + log_hdr_type hdr; + uint8_t version; + uint8_t vdev_id; + uint8_t origin; + bool is_tx; + bool roam_result; + uint32_t timestamp; + uint16_t mgmt_frame_seq_num; + uint16_t received_chan_freq; + uint8_t action_category; + uint8_t rrm_action_code; + uint8_t radio_measurement_type; + uint8_t bssid[QDF_MAC_ADDR_SIZE]; + uint8_t req_num_freq; + uint16_t req_freq[WLAN_MAX_ROAM_SCAN_CHAN]; + uint8_t fail_reason_code; + uint32_t rssi; + struct wlan_rrm_beacon_report bcn_rpt; +} qdf_packed; + /** * struct host_event_proto_pkt_info - DP protocol pkt info * @hdr: Log header diff --git a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/log_codes.h b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/log_codes.h index 10f9f100852311854ca0f22bfd7580802208ac9a..ddc8301f8976b9d66feda905fed89564a098c92e 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/log_codes.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/inc/log_codes.h @@ -2003,6 +2003,12 @@ #define LOG_WLAN_COLD_BOOT_CAL_DATA_C ((0xA18) + LOG_1X_BASE_C) +#define LOG_WLAN_AUTH_ASSOC_TX_RX_INFO_C ((0xA19) + LOG_1X_BASE_C) +#define LOG_WLAN_ROAM_TRIGGER_INFO_C ((0xA1A) + LOG_1X_BASE_C) +#define LOG_WLAN_ROAM_SCAN_INFO_C ((0xA1B) + LOG_1X_BASE_C) +#define LOG_WLAN_ROAM_RESULT_INFO_C ((0xA1C) + LOG_1X_BASE_C) +#define LOG_WLAN_RRM_TX_RX_INFO_C ((0xA1D) + LOG_1X_BASE_C) + #define LOG_WLAN_DP_PROTO_PKT_INFO_C ((0xA1E) + LOG_1X_BASE_C) /* This is only here for old (pre equipment ID update) logging code */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/src/host_diag_log.c b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/src/host_diag_log.c index 97e51f6542b8de2e4095b5d387d0700a64b4a9df..f42743e9c8ac4fab5459113da3bf0d656e1b1414 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/src/host_diag_log.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/host_diag_log/src/host_diag_log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -109,12 +109,8 @@ void host_diag_log_submit(void *plog_hdr_ptr) uint16_t data_len; uint16_t total_len; - if (cds_is_load_or_unload_in_progress()) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, - "%s: Unloading/Loading in Progress. Ignore!!!", - __func__); + if (cds_is_load_or_unload_in_progress()) return; - } if (nl_srv_is_initialized() != 0) return; @@ -201,12 +197,8 @@ void host_diag_event_report_payload(uint16_t event_Id, uint16_t length, event_report_t *pEvent_report; uint16_t total_len; - if (cds_is_load_or_unload_in_progress()) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, - "%s: Unloading/Loading in Progress. Ignore!!!", - __func__); + if (cds_is_load_or_unload_in_progress()) return; - } if (nl_srv_is_initialized() != 0) return; diff --git a/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_logging_sock_svc.h b/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_logging_sock_svc.h index 941fbe5ddae28280ecc603bdff3a8a6e1114ee7d..7db67a26664318c06a090d54d532d9f4e52d7775 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_logging_sock_svc.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_logging_sock_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -60,12 +60,36 @@ static inline void wlan_logging_set_active(bool active) {} static inline void wlan_logging_set_log_to_console(bool log_to_console) {} #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ -#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && !defined(REMOVE_PKT_LOG) -void wlan_deregister_txrx_packetdump(void); -void wlan_register_txrx_packetdump(void); +#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ + defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) +/** + * wlan_deregister_txrx_packetdump() - tx/rx packet dump + * deregistration + * @pdev_id: id of the datapath pdev handle + * + * This function is used to deregister tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_deregister_txrx_packetdump(uint8_t pdev_id); + +/** + * wlan_register_txrx_packetdump() - tx/rx packet dump + * registration + * @pdev_id: id of the datapath pdev handle + * + * This function is used to register tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_register_txrx_packetdump(uint8_t pdev_id); #else -static inline void wlan_deregister_txrx_packetdump(void) {} -static inline void wlan_register_txrx_packetdump(void) {} +static inline void wlan_deregister_txrx_packetdump(uint8_t pdev_id) {} +static inline void wlan_register_txrx_packetdump(uint8_t pdev_id) {} #endif #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && defined(FEATURE_WLAN_DIAG_SUPPORT) @@ -84,7 +108,8 @@ static inline void wlan_report_log_completion(uint32_t is_fatal, #endif /* FEATURE_WLAN_DIAG_SUPPORT */ -#if defined(CONFIG_MCL) && !defined(REMOVE_PKT_LOG) +#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ + defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data); #else static inline diff --git a/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_roam_debug.h b/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_roam_debug.h index 09425b18be73b0e0761f5a5bd7a96393059323b3..9b66b843d7a31ad47e4f92c598987a0c3b217805 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_roam_debug.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/logging/inc/wlan_roam_debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the diff --git a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c index d8e851662d1b939446b45f18a5b93d9d129b22ac..8eb9af23faeda44bd887c5b544feffc44c42d4c3 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_logging_sock_svc.c @@ -23,16 +23,6 @@ #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE #include -#ifdef CONFIG_MCL -#include -#include -#include "cds_utils.h" -#include "csr_api.h" -#include "wma.h" -#include "ol_txrx_api.h" -#include "pktlog_ac.h" -#include -#endif #include #include #include @@ -43,11 +33,26 @@ #include #include #include "host_diag_core_log.h" +#include #ifdef CNSS_GENL #include #endif +#if defined(FEATURE_FW_LOG_PARSING) || defined(FEATURE_WLAN_DIAG_SUPPORT) || \ + defined(FEATURE_PKTLOG) +#include +#include "ani_global.h" +#endif + +#ifdef FEATURE_PKTLOG +#ifndef REMOVE_PKT_LOG +#include "wma.h" +#include "pktlog_ac.h" +#include +#endif +#endif + #define MAX_NUM_PKT_LOG 32 #define LOGGING_TRACE(level, args ...) \ @@ -63,6 +68,8 @@ #define MAX_LOGMSG_LENGTH 2048 #define MAX_SKBMSG_LENGTH 4096 +#define WLAN_LOG_BUFFER_SIZE 2048 +#if defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) /** * Buffer to accommodate - * pktlog buffer (2048 bytes) @@ -74,7 +81,6 @@ * HTT_T2H_MAX_MSG_SIZE. Adjust WLAN_LOG_BUFFER_SIZE * based on the above mentioned macros. */ -#define WLAN_LOG_BUFFER_SIZE 2048 #define ATH_PKTLOG_HDR_SIZE (sizeof(struct ath_pktlog_hdr)) #define PKT_DUMP_HDR_SIZE (sizeof(struct packet_dump)) #define EXTRA_PADDING 40 @@ -82,6 +88,9 @@ #define MAX_PKTSTATS_LENGTH \ ((WLAN_LOG_BUFFER_SIZE) + (ATH_PKTLOG_HDR_SIZE) + \ (PKT_DUMP_HDR_SIZE) + (EXTRA_PADDING)) +#else +#define MAX_PKTSTATS_LENGTH WLAN_LOG_BUFFER_SIZE +#endif /* FEATURE_PKTLOG */ #define MAX_PKTSTATS_BUFF 16 #define HOST_LOG_DRIVER_MSG 0x001 @@ -476,8 +485,9 @@ static int pkt_stats_fill_headers(struct sk_buff *skb) cds_pkt_size); if (unlikely(skb_headroom(skb) < cds_pkt_size)) { - pr_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", - __LINE__, skb->head, skb->data, sizeof(msg_header)); + qdf_nofl_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", + __LINE__, skb->head, skb->data, + sizeof(msg_header)); return -EIO; } @@ -485,8 +495,9 @@ static int pkt_stats_fill_headers(struct sk_buff *skb) &cds_pktlog, cds_pkt_size); if (unlikely(skb_headroom(skb) < sizeof(int))) { - pr_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", - __LINE__, skb->head, skb->data, sizeof(int)); + qdf_nofl_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", + __LINE__, skb->head, skb->data, + sizeof(int)); return -EIO; } @@ -507,8 +518,9 @@ static int pkt_stats_fill_headers(struct sk_buff *skb) msg_header.wmsg.length = cpu_to_be16(skb->len); if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { - pr_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", - __LINE__, skb->head, skb->data, sizeof(msg_header)); + qdf_nofl_err("VPKT [%d]: Insufficient headroom, head[%pK], data[%pK], req[%zu]", + __LINE__, skb->head, skb->data, + sizeof(msg_header)); return -EIO; } @@ -558,8 +570,8 @@ static int pktlog_send_per_pkt_stats_to_user(void) skb_new = dev_alloc_skb(MAX_SKBMSG_LENGTH); if (!skb_new) { if (!rate_limit) { - pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", - __func__, MAX_SKBMSG_LENGTH, + qdf_nofl_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u", + __func__, MAX_SKBMSG_LENGTH, gwlan_logging.drop_count); } rate_limit = 1; @@ -576,14 +588,15 @@ static int pktlog_send_per_pkt_stats_to_user(void) ret = pkt_stats_fill_headers(pstats_msg->skb); if (ret < 0) { - pr_err("%s failed to fill headers %d\n", __func__, ret); + qdf_nofl_err("%s failed to fill headers %d", + __func__, ret); free_old_skb = true; goto err; } ret = nl_srv_bcast_diag(pstats_msg->skb); if (ret < 0) { - pr_info("%s: Send Failed %d drop_count = %u\n", - __func__, ret, + qdf_nofl_info("%s: Send Failed %d drop_count = %u", + __func__, ret, ++gwlan_logging.pkt_stat_drop_cnt); } else { ret = 0; @@ -635,10 +648,9 @@ static int send_filled_buffers_to_user(void) skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); if (!skb) { if (!rate_limit) { - pr_err - ("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", - __func__, MAX_LOGMSG_LENGTH, - gwlan_logging.drop_count); + qdf_nofl_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); } rate_limit = 1; ret = -ENOMEM; @@ -664,10 +676,10 @@ static int send_filled_buffers_to_user(void) list_add_tail(&plog_msg->node, &gwlan_logging.free_list); spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); - pr_err("%s: drop_count = %u\n", __func__, - ++gwlan_logging.drop_count); - pr_err("%s: nlmsg_put() failed for msg size[%d]\n", - __func__, tot_msg_len); + qdf_nofl_err("%s: drop_count = %u", __func__, + ++gwlan_logging.drop_count); + qdf_nofl_err("%s: nlmsg_put() failed for msg size[%d]", + __func__, tot_msg_len); dev_kfree_skb(skb); skb = NULL; ret = -EINVAL; @@ -686,8 +698,8 @@ static int send_filled_buffers_to_user(void) ret = nl_srv_bcast_host_logs(skb); /* print every 64th drop count */ if (ret < 0 && (!(gwlan_logging.drop_count % 0x40))) { - pr_err("%s: Send Failed %d drop_count = %u\n", - __func__, ret, ++gwlan_logging.drop_count); + qdf_nofl_err("%s: Send Failed %d drop_count = %u", + __func__, ret, ++gwlan_logging.drop_count); } } @@ -795,9 +807,8 @@ static int wlan_logging_thread(void *Arg) || gwlan_logging.exit)); if (ret_wait_status == -ERESTARTSYS) { - pr_err - ("%s: wait_event_interruptible returned -ERESTARTSYS", - __func__); + qdf_nofl_err("%s: wait_event_interruptible returned -ERESTARTSYS", + __func__); break; } @@ -930,8 +941,8 @@ int wlan_logging_sock_init_svc(void) gwlan_logging.buffer_length = MAX_LOGMSG_LENGTH; if (allocate_log_msg_buffer() != QDF_STATUS_SUCCESS) { - pr_err("%s: Could not allocate memory for log_msg\n", - __func__); + qdf_nofl_err("%s: Could not allocate memory for log_msg", + __func__); return -ENOMEM; } @@ -952,8 +963,8 @@ int wlan_logging_sock_init_svc(void) pkt_stats_size = sizeof(struct pkt_stats_msg); gpkt_stats_buffers = vmalloc(MAX_PKTSTATS_BUFF * pkt_stats_size); if (!gpkt_stats_buffers) { - pr_err("%s: Could not allocate memory for Pkt stats\n", - __func__); + qdf_nofl_err("%s: Could not allocate memory for Pkt stats", + __func__); goto err1; } qdf_mem_zero(gpkt_stats_buffers, @@ -969,7 +980,8 @@ int wlan_logging_sock_init_svc(void) for (i = 0; i < MAX_PKTSTATS_BUFF; i++) { gpkt_stats_buffers[i].skb = dev_alloc_skb(MAX_PKTSTATS_LENGTH); if (!gpkt_stats_buffers[i].skb) { - pr_err("%s: Memory alloc failed for skb", __func__); + qdf_nofl_err("%s: Memory alloc failed for skb", + __func__); /* free previously allocated skb and return */ for (j = 0; j < i ; j++) dev_kfree_skb(gpkt_stats_buffers[j].skb); @@ -996,8 +1008,8 @@ int wlan_logging_sock_init_svc(void) gwlan_logging.thread = kthread_create(wlan_logging_thread, NULL, "wlan_logging_thread"); if (IS_ERR(gwlan_logging.thread)) { - pr_err("%s: Could not Create LogMsg Thread Controller", - __func__); + qdf_nofl_err("%s: Could not Create LogMsg Thread Controller", + __func__); goto err3; } wake_up_process(gwlan_logging.thread); @@ -1044,12 +1056,10 @@ int wlan_logging_sock_deinit_svc(void) if (!gwlan_logging.pcur_node) return 0; -#ifdef CONFIG_MCL INIT_COMPLETION(gwlan_logging.shutdown_comp); -#endif gwlan_logging.exit = true; gwlan_logging.is_active = false; -#ifdef CONFIG_MCL +#if defined(FEATURE_FW_LOG_PARSING) || defined(FEATURE_WLAN_DIAG_SUPPORT) cds_set_multicast_logging(0); #endif gwlan_logging.is_flush_complete = false; @@ -1110,11 +1120,7 @@ void wlan_logging_set_per_pkt_stats(void) */ void wlan_logging_set_fw_flush_complete(void) { - if (gwlan_logging.is_active == false -#ifdef CONFIG_MCL - || !cds_is_fatal_event_enabled() -#endif - ) + if (!gwlan_logging.is_active) return; set_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag); @@ -1133,23 +1139,17 @@ void wlan_flush_host_logs_for_fatal(void) { unsigned long flags; -#ifdef CONFIG_MCL - if (cds_is_log_report_in_progress()) { -#endif - if (gwlan_logging.flush_timer_period == 0) - 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); -#ifdef CONFIG_MCL - } -#endif + if (gwlan_logging.flush_timer_period == 0) + qdf_nofl_info("%s:flush all host logs Setting HOST_LOG_POST_MAS", + __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); } -#ifdef CONFIG_MCL +#ifdef FEATURE_PKTLOG #ifndef REMOVE_PKT_LOG static uint8_t gtx_count; @@ -1188,8 +1188,8 @@ static int wlan_get_pkt_stats_free_node(void) if ( cds_is_multicast_logging() && (!(gwlan_logging.pkt_stat_drop_cnt % 0x40))) { - pr_err("%s: drop_count = %u\n", - __func__, gwlan_logging.pkt_stat_drop_cnt); + qdf_nofl_err("%s: drop_count = %u", + __func__, gwlan_logging.pkt_stat_drop_cnt); } list_del_init(gwlan_logging.pkt_stat_filled_list.next); ret = 1; @@ -1224,7 +1224,7 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) pktlog_hdr = (struct ath_pktlog_hdr *)pl_hdr; if (!pktlog_hdr) { - pr_err("%s : Invalid pkt_stats_header\n", __func__); + qdf_nofl_err("%s : Invalid pkt_stats_header", __func__); return; } @@ -1315,7 +1315,7 @@ static void driver_hal_status_map(uint8_t *status) /* * send_packetdump() - send packet dump * @soc: soc handle - * @vdev: vdev handle + * @vdev_id: ID of the virtual device handle * @netbuf: netbuf * @status: status of tx packet * @type: type of packet @@ -1327,19 +1327,19 @@ static void driver_hal_status_map(uint8_t *status) * */ static void send_packetdump(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, qdf_nbuf_t netbuf, + uint8_t vdev_id, qdf_nbuf_t netbuf, uint8_t status, uint8_t type) { struct ath_pktlog_hdr pktlog_hdr = {0}; struct packet_dump pd_hdr = {0}; if (!netbuf) { - pr_err("%s: Invalid netbuf.\n", __func__); + qdf_nofl_err("%s: Invalid netbuf.", __func__); return; } /* Send packet dump only for STA interface */ - if (wlan_op_mode_sta != cdp_get_opmode(soc, vdev)) + if (wlan_op_mode_sta != cdp_get_opmode(soc, vdev_id)) return; #if defined(HELIUMPLUS) @@ -1392,17 +1392,7 @@ static void send_packetdump_monitor(uint8_t type) wlan_pkt_stats_to_logger_thread(&pktlog_hdr, &pd_hdr, NULL); } -/** - * wlan_deregister_txrx_packetdump() - tx/rx packet dump - * deregistration - * - * This function is used to deregister tx/rx packet dump callbacks - * with ol, pe and htt layers - * - * Return: None - * - */ -void wlan_deregister_txrx_packetdump(void) +void wlan_deregister_txrx_packetdump(uint8_t pdev_id) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -1410,7 +1400,7 @@ void wlan_deregister_txrx_packetdump(void) return; if (gtx_count || grx_count) { - cdp_deregister_packetdump_cb(soc); + cdp_deregister_packetdump_cb(soc, pdev_id); wma_deregister_packetdump_callback(); send_packetdump_monitor(STOP_MONITOR); csr_packetdump_timer_stop(); @@ -1425,6 +1415,7 @@ void wlan_deregister_txrx_packetdump(void) /* * check_txrx_packetdump_count() - function to check * tx/rx packet dump global counts + * @pdev_id: datapath pdev identifier * * This function is used to check global counts of tx/rx * packet dump functionality. @@ -1433,14 +1424,14 @@ void wlan_deregister_txrx_packetdump(void) * 0 otherwise * */ -static bool check_txrx_packetdump_count(void) +static bool check_txrx_packetdump_count(uint8_t pdev_id) { if (gtx_count == MAX_NUM_PKT_LOG || grx_count == MAX_NUM_PKT_LOG) { LOGGING_TRACE(QDF_TRACE_LEVEL_DEBUG, "%s gtx_count: %d grx_count: %d deregister packetdump", __func__, gtx_count, grx_count); - wlan_deregister_txrx_packetdump(); + wlan_deregister_txrx_packetdump(pdev_id); return 1; } return 0; @@ -1449,7 +1440,8 @@ static bool check_txrx_packetdump_count(void) /* * tx_packetdump_cb() - tx packet dump callback * @soc: soc handle - * @vdev: vdev handle + * @pdev_id: datapath pdev id + * @vdev_id: vdev id * @netbuf: netbuf * @status: status of tx packet * @type: packet type @@ -1461,27 +1453,29 @@ static bool check_txrx_packetdump_count(void) * */ static void tx_packetdump_cb(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, qdf_nbuf_t netbuf, + uint8_t pdev_id, uint8_t vdev_id, + qdf_nbuf_t netbuf, uint8_t status, uint8_t type) { bool temp; - if (!soc || !vdev) + if (!soc) return; - temp = check_txrx_packetdump_count(); + temp = check_txrx_packetdump_count(pdev_id); if (temp) return; driver_hal_status_map(&status); - send_packetdump(soc, vdev, netbuf, status, type); + send_packetdump(soc, vdev_id, netbuf, status, type); } /* * rx_packetdump_cb() - rx packet dump callback * @soc: soc handle - * @vdev: vdev handle + * @pdev_id: datapath pdev id + * @vdev_id: vdev id * @netbuf: netbuf * @status: status of rx packet * @type: packet type @@ -1493,47 +1487,40 @@ static void tx_packetdump_cb(ol_txrx_soc_handle soc, * */ static void rx_packetdump_cb(ol_txrx_soc_handle soc, - struct cdp_vdev *vdev, qdf_nbuf_t netbuf, + uint8_t pdev_id, uint8_t vdev_id, + qdf_nbuf_t netbuf, uint8_t status, uint8_t type) { bool temp; - if (!soc || !vdev) + if (!soc) return; - temp = check_txrx_packetdump_count(); + temp = check_txrx_packetdump_count(pdev_id); if (temp) return; - send_packetdump(soc, vdev, netbuf, status, type); + send_packetdump(soc, vdev_id, netbuf, status, type); } - -/** - * wlan_register_txrx_packetdump() - tx/rx packet dump - * registration - * - * This function is used to register tx/rx packet dump callbacks - * with ol, pe and htt layers - * - * Return: None - * - */ -void wlan_register_txrx_packetdump(void) +void wlan_register_txrx_packetdump(uint8_t pdev_id) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!soc) return; - cdp_register_packetdump_cb(soc, tx_packetdump_cb, rx_packetdump_cb); + cdp_register_packetdump_cb(soc, pdev_id, + tx_packetdump_cb, rx_packetdump_cb); wma_register_packetdump_callback(tx_packetdump_cb, rx_packetdump_cb); send_packetdump_monitor(START_MONITOR); gtx_count = 0; grx_count = 0; + + csr_packetdump_timer_start(); } #endif /* REMOVE_PKT_LOG */ -#endif /* CONFIG_MCL */ +#endif /* FEATURE_PKTLOG */ #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_roam_debug.c b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_roam_debug.c index 8988282853a4efebfd9e597ec3008f8e2f007ec6..c6ced135050f351f689425338093af6a3854abb8 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_roam_debug.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/logging/src/wlan_roam_debug.c @@ -247,9 +247,10 @@ void wlan_roam_debug_dump_table(void) roam_debug("index = %5d timestamp = 0x%016llx delta ms = %-12u", i, dbg_rec->time, delta); - roam_debug("info = %-24s vdev_id = %-3d mac addr = %pM", + roam_debug("info = %-24s vdev_id = %-3d mac addr = "QDF_MAC_ADDR_FMT, wlan_roam_debug_string(dbg_rec->operation), - (int8_t)dbg_rec->vdev_id, dbg_rec->mac_addr.bytes); + (int8_t)dbg_rec->vdev_id, + QDF_MAC_ADDR_REF(dbg_rec->mac_addr.bytes)); roam_debug("peer obj = 0x%pK peer_id = %-4d", dbg_rec->peer_obj, (int8_t)dbg_rec->peer_id); roam_debug("arg1 = 0x%-8x arg2 = 0x%-8x", dbg_rec->arg1, diff --git a/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_common.h b/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_common.h index 6b43052389f1b5c1e008b5c6010276da448fb9d7..2ca6f2b0fb9a39c830962357736e75a40e7a383d 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_common.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -94,7 +94,7 @@ typedef enum eAniNlModuleTypes { ANI_NL_MSG_PUMAC = ANI_NL_MSG_BASE + 0x01, /* PTT Socket App */ ANI_NL_MSG_PTT = ANI_NL_MSG_BASE + 0x07, /* Quarky GUI */ WLAN_NL_MSG_OEM = ANI_NL_MSG_BASE + 0x09, - WLAN_NL_MSG_SVC, + WLAN_NL_MSG_SVC = ANI_NL_MSG_BASE + 0x0a, WLAN_NL_MSG_CNSS_DIAG = ANI_NL_MSG_BASE + 0x0B, /* Value needs to be 27 */ ANI_NL_MSG_LOG, WLAN_NL_MSG_SPECTRAL_SCAN, diff --git a/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_srv.h b/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_srv.h index 53c2d6e283382b61d98f9460ee187fdd3ea1ed59..c66b06b534566a422c908e4b7a214a5150b945b1 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_srv.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/nlink/inc/wlan_nlink_srv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017, 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -40,7 +40,36 @@ typedef int (*nl_srv_msg_callback)(struct sk_buff *skb); -int nl_srv_init(void *wiphy); +/** + * cld80211_oem_send_reply() - API to send cld80211 msg + * @skb: Sk buffer + * @hdr: nl80211hdr pointer + * @nest: pointer of vendor nested attribute + * @flags: Flags + * + * API to send cld80211 msg to applications + * + * Return: None + */ +void cld80211_oem_send_reply(struct sk_buff *msg, void *hdr, + struct nlattr *nest, int flags); + +/** + * nl80211hdr_put() - API to allocate skb for cld80211 msg + * @hdr: nl80211hdr pointer + * @portid: Port ID + * @nest: pointer of vendor nested attribute + * @flags: Flags + * + * API to allocate skb for cld80211 msg + * + * Return: Pointer to skbuff + */ + +struct sk_buff * +cld80211_oem_rsp_alloc_skb(uint32_t portid, void **hdr, struct nlattr **nest, + int *flags); +int nl_srv_init(void *wiphy, int proto); void nl_srv_exit(void); int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); int nl_srv_unregister(tWlanNlModTypes msg_type, @@ -50,6 +79,21 @@ int nl_srv_unregister(tWlanNlModTypes msg_type, int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag, int app_id, int mcgroup_id); int nl_srv_bcast(struct sk_buff *skb, int mcgroup_id, int app_id); + +/** + * nl80211hdr_put() - API to fill genlmsg header + * @skb: Sk buffer + * @portid: Port ID + * @seq: Sequence number + * @flags: Flags + * @cmd: Command id + * + * API to fill genl message header for brodcast events to user space + * + * Return: Pointer to user specific header/payload + */ +void *nl80211hdr_put(struct sk_buff *skb, uint32_t portid, + uint32_t seq, int flags, uint8_t cmd); #else int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag); int nl_srv_bcast(struct sk_buff *skb); diff --git a/drivers/staging/qca-wifi-host-cmn/utils/nlink/src/wlan_nlink_srv.c b/drivers/staging/qca-wifi-host-cmn/utils/nlink/src/wlan_nlink_srv.c index 171d599e10f0867a9b629b403b7e6e1150ad03f2..d0b79feb060bba5320ff8c7efcb88018b4296ba0 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/nlink/src/wlan_nlink_srv.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/nlink/src/wlan_nlink_srv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -48,6 +48,7 @@ static bool logger_initialized; /** * nl_srv_init() - wrapper function to register to cnss_logger * @wiphy: the pointer to the wiphy structure + * @proto: the host log netlink protocol * * The netlink socket is no longer initialized in the driver itself, instead * will be initialized in the cnss_logger module, the driver should register @@ -60,7 +61,7 @@ static bool logger_initialized; * * Return: radio index for success and -EINVAL for failure */ -int nl_srv_init(void *wiphy) +int nl_srv_init(void *wiphy, int proto) { if (logger_initialized) goto initialized; @@ -266,8 +267,56 @@ qdf_export_symbol(nl_srv_is_initialized); #include #include +void cld80211_oem_send_reply(struct sk_buff *msg, void *hdr, + struct nlattr *nest, int flags) +{ + struct genl_family *cld80211_fam = cld80211_get_genl_family(); + + nla_nest_end(msg, nest); + genlmsg_end(msg, hdr); + + genlmsg_multicast_netns(cld80211_fam, &init_net, msg, 0, + CLD80211_MCGRP_OEM_MSGS, flags); +} + +struct sk_buff * +cld80211_oem_rsp_alloc_skb(uint32_t portid, void **hdr, struct nlattr **nest, + int *flags) +{ + struct sk_buff *msg; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + *flags = GFP_ATOMIC; + + msg = nlmsg_new(WLAN_CLD80211_MAX_SIZE, *flags); + if (!msg) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "nlmsg malloc fails"); + return NULL; + } + + *hdr = nl80211hdr_put(msg, portid, 0, *flags, WLAN_NL_MSG_OEM); + if (*hdr == NULL) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "nl80211 hdr put failed"); + goto nla_put_failure; + } + + *nest = nla_nest_start(msg, CLD80211_ATTR_VENDOR_DATA); + if (*nest == NULL) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "nla_nest_start failed"); + goto nla_put_failure; + } + return msg; +nla_put_failure: + genlmsg_cancel(msg, *hdr); + nlmsg_free(msg); + return NULL; +} + /* For CNSS_GENL netlink sockets will be initialized by CNSS Kernel Module */ -int nl_srv_init(void *wiphy) +int nl_srv_init(void *wiphy, int proto) { return 0; } @@ -292,21 +341,8 @@ int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) return 0; } - -/** - * nl80211hdr_put() - API to fill genlmsg header - * @skb: Sk buffer - * @portid: Port ID - * @seq: Sequence number - * @flags: Flags - * @cmd: Command id - * - * API to fill genl message header for brodcast events to user space - * - * Return: Pointer to user specific header/payload - */ -static inline void *nl80211hdr_put(struct sk_buff *skb, uint32_t portid, - uint32_t seq, int flags, uint8_t cmd) +void *nl80211hdr_put(struct sk_buff *skb, uint32_t portid, + uint32_t seq, int flags, uint8_t cmd) { struct genl_family *cld80211_fam = cld80211_get_genl_family(); @@ -481,7 +517,7 @@ int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag, return 0; } -#elif !defined(MULTI_IF_NAME) +#elif !defined(MULTI_IF_NAME) || defined(MULTI_IF_LOG) /* Global variables */ static DEFINE_MUTEX(nl_srv_sem); @@ -497,7 +533,7 @@ static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh); * Initialize the netlink service. * Netlink service is usable after this. */ -int nl_srv_init(void *wiphy) +int nl_srv_init(void *wiphy, int proto) { int retcode = 0; struct netlink_kernel_cfg cfg = { @@ -505,7 +541,7 @@ int nl_srv_init(void *wiphy) .input = nl_srv_rcv }; - nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, + nl_srv_sock = netlink_kernel_create(&init_net, proto, &cfg); if (nl_srv_sock) { @@ -552,6 +588,8 @@ int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) return retcode; } +qdf_export_symbol(nl_srv_register); + /* * Unregister the message handler for a specified module. */ @@ -736,7 +774,7 @@ qdf_export_symbol(nl_srv_is_initialized); #else -int nl_srv_init(void *wiphy) +int nl_srv_init(void *wiphy, int proto) { return 0; } @@ -797,4 +835,6 @@ void nl_srv_ucast_oem(struct sk_buff *skb, int dst_pid, int flag) { nl_srv_ucast(skb, dst_pid, flag); } + +qdf_export_symbol(nl_srv_ucast_oem); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac.h b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac.h index 7dc1eaffe959aa25903b18de64dd01abab17f828..a7d46b728aec7507602c72adb9b084736b0df442 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,7 +61,15 @@ extern void pktlog_release_buf(struct hif_opaque_softc *scn); ssize_t pktlog_read_proc_entry(char *buf, size_t nbytes, loff_t *ppos, struct ath_pktlog_info *pl_info, bool *read_complete); -A_STATUS wdi_pktlog_unsubscribe(struct cdp_pdev *txrx_pdev, uint32_t log_state); + +/** + * wdi_pktlog_unsubscribe() - Unsubscribe pktlog callbacks + * @pdev_id: pdev id + * @log_state: Pktlog registration + * + * Return: zero on success, non-zero on failure + */ +A_STATUS wdi_pktlog_unsubscribe(uint8_t pdev_id, uint32_t log_state); struct ol_pl_arch_dep_funcs { void (*pktlog_init)(struct hif_opaque_softc *scn); @@ -93,6 +101,7 @@ struct pktlog_dev_t { struct ol_pl_arch_dep_funcs *pl_funcs; struct ath_pktlog_info *pl_info; ol_ath_generic_softc_handle scn; + uint8_t pdev_id; char *name; bool tgt_pktlog_alloced; bool is_pktlog_cb_subscribed; @@ -141,7 +150,17 @@ int pktlog_disable(struct hif_opaque_softc *scn); int pktlogmod_init(void *context); void pktlogmod_exit(void *context); int pktlog_htc_attach(void); -void pktlog_process_fw_msg(uint32_t *msg_word, uint32_t msg_len); + +/** + * pktlog_process_fw_msg() - process packetlog message + * @pdev_id: physical device instance id + * @msg_word: message buffer + * @msg_len: message length + * + * Return: None + */ +void pktlog_process_fw_msg(uint8_t pdev_id, uint32_t *msg_word, + uint32_t msg_len); void lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data, u_int16_t peer_id, uint32_t status); @@ -204,7 +223,8 @@ static inline int pktlog_htc_attach(void) return 0; } -static inline void pktlog_process_fw_msg(uint32_t *msg_word, uint32_t msg_len) +static inline void pktlog_process_fw_msg(uint8_t pdev_id, uint32_t *msg_word, + uint32_t msg_len) { } #endif /* REMOVE_PKT_LOG */ #endif /* _PKTLOG_AC_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_api.h b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_api.h index 60226922fff6067302bbe8ebf0a056f0b9eb84eb..bc75425b93fbb2c2df8653c82fd8f2210c4f451c 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_api.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_api.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2014, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2016-2018, 2020 The Linux Foundation. + * All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,6 +55,7 @@ struct pktlog_dev_t; void pktlog_sethandle(struct pktlog_dev_t **pl_handle, hif_opaque_softc_handle scn); +void pktlog_set_pdev_id(struct pktlog_dev_t *pl_dev, uint8_t pdev_id); void *get_txrx_context(void); @@ -129,6 +131,12 @@ struct ath_pktlog_info { #endif /* _PKTLOG_INFO */ #else /* REMOVE_PKT_LOG */ typedef void *pktlog_dev_handle; +#define pktlog_set_pdev_id(pl_dev, pdev_id) \ + do { \ + (void)pl_dev; \ + (void)pdev_id; \ + } while (0) + #define pktlog_sethandle(pl_handle, scn) \ do { \ (void)pl_handle; \ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_i.h b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_i.h index 2ca00ddf260e2b992abb97af6f139ce3334d9684..5f7d9beba2ff32c6abc0b25d305f0ee4c0780334 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_i.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_ac_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,7 @@ #include +#define PKTLOG_TAG "ATH_PKTLOG" #define PKTLOG_DEFAULT_BUFSIZE (10 * 1024 * 1024) /* 10MB */ #define PKTLOG_DEFAULT_SACK_THR 3 #define PKTLOG_DEFAULT_TAIL_LENGTH 100 @@ -59,14 +60,72 @@ char *pktlog_getbuf(struct pktlog_dev_t *pl_dev, struct ath_pktlog_info *pl_info, size_t log_size, struct ath_pktlog_hdr *pl_hdr); -A_STATUS process_tx_info(struct cdp_pdev *pdev, void *data); -A_STATUS process_rx_info(void *pdev, void *data); -A_STATUS process_rx_info_remote(void *pdev, void *data); -A_STATUS process_rate_find(void *pdev, void *data); -A_STATUS process_rate_update(void *pdev, void *data); -A_STATUS process_sw_event(void *pdev, void *data); -int process_pktlog_lite(void *context, void *log_data, uint16_t log_type); -int process_rx_desc_remote(void *pdev, void *data); -A_STATUS process_offload_pktlog(struct cdp_pdev *pdev, void *data); +#ifdef PKTLOG_HAS_SPECIFIC_DATA +/** + * pktlog_hdr_set_specific_data() - set type specific data + * @log_hdr: pktlog header + * @type_specific_data: type specific data + * + * Return: None + */ +void +pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr, + uint32_t type_specific_data); + +/** + * pktlog_hdr_get_specific_data() - get type specific data + * @log_hdr: pktlog header + * @type_specific_data: type specific data + * + * Return: pktlog subtype + */ +uint32_t +pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr); + +/** + * pktlog_arg_set_specific_data() - set type specific data + * @log_hdr: pktlog arg + * @type_specific_data: type specific data + * + * Return: None + */ +void +pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg, + uint32_t type_specific_data); + +/** + * pktlog_arg_get_specific_data() - set type specific data + * @log_hdr: pktlog arg + * @type_specific_data: type specific data + * + * Return: pktlog subtype + */ +uint32_t +pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg); +#else +static inline void +pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr, + uint32_t type_specific_data) +{ +} + +static inline uint32_t +pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr) +{ + return 0; +} + +static inline void +pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg, + uint32_t type_specific_data) +{ +} + +static inline uint32_t +pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg) +{ + return 0; +} +#endif /* PKTLOG_HAS_SPECIFIC_DATA */ #endif /* REMOVE_PKT_LOG */ #endif diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi2.h b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi2.h new file mode 100644 index 0000000000000000000000000000000000000000..d24d52709539c0f2101361f1e72d3692a5911ad1 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi2.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "ol_txrx_types.h" +#include "ol_htt_tx_api.h" +#include "ol_tx_desc.h" +#include "qdf_mem.h" +#include "htt.h" +#include "htt_internal.h" +#include "pktlog_ac_i.h" +#include "wma_api.h" +#include "wlan_logging_sock_svc.h" + +#define TX_DESC_ID_LOW_MASK 0xffff +#define TX_DESC_ID_LOW_SHIFT 0 +#define TX_DESC_ID_HIGH_MASK 0xffff0000 +#define TX_DESC_ID_HIGH_SHIFT 16 + +#ifndef REMOVE_PKT_LOG +/** + * process_tx_info() - process tx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data); + +/** + * process_rx_info_remote() - process rx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_rx_info_remote(void *pdev, void *data); + +/** + * process_rx_info() - process rx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_rx_info(void *pdev, void *data); + +/** + * process_rate_find() - process rate event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_rate_find(void *pdev, void *data); + +/** + * process_rate_update() - process rate event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_rate_update(void *pdev, void *data); + +/** + * process_sw_event() - process sw event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +A_STATUS process_sw_event(void *pdev, void *data); +#else +static inline +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + return 0; +} + +static inline +A_STATUS process_rx_info_remote(void *pdev, void *data) +{ + return 0; +} + +static inline +A_STATUS process_rx_info(void *pdev, void *data) +{ + return 0; +} + +static inline +A_STATUS process_rate_find(void *pdev, void *data) +{ + return 0; +} + +static inline +A_STATUS process_rate_update(void *pdev, void *data) +{ + return 0; +} + +static inline +A_STATUS process_sw_event(void *pdev, void *data) +{ + return 0; +} +#endif /* REMOVE_PKT_LOG */ + +/** + * process_offload_pktlog_wifi3() - Process full pktlog events + * pdev: abstract pdev handle + * data: pktlog buffer + * + * Return: zero on success, non-zero on failure + */ +static inline A_STATUS +process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) +{ + return 0; +} + +/** + * process_rx_desc_remote_wifi3() - Process pktlog buffers received + * from monitor status ring + * @pdev: pdev handle + * @data: pktlog buffer pointer + * + * Return: 0 - success/non-zero - failure + */ +static inline int +process_rx_desc_remote_wifi3(void *pdev, void *data) +{ + return 0; +} + +/** + * process_pktlog_lite_wifi3() - Process pktlog buffers received + * from monitor status ring + * @pdev: pdev handle + * @data: pktlog buffer pointer + * + * Return: 0 - success/non-zero - failure + */ +static inline int +process_pktlog_lite_wifi3(void *context, void *log_data, + uint16_t log_type) +{ + return 0; +} diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi3.h b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi3.h new file mode 100644 index 0000000000000000000000000000000000000000..5ffe4f85f9c4e30f276ad3c4255a69c67556cb19 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/include/pktlog_wifi3.h @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "pktlog_ac_i.h" +#include "wlan_logging_sock_svc.h" + +#ifndef REMOVE_PKT_LOG +/** + * process_offload_pktlog_wifi3() - Process full pktlog events + * pdev: abstract pdev handle + * data: pktlog buffer + * + * Return: zero on success, non-zero on failure + */ +A_STATUS +process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data); + +/** + * process_rx_desc_remote_wifi3() - Process pktlog buffers received + * from monitor status ring + * @pdev: pdev handle + * @data: pktlog buffer pointer + * + * Return: 0 - success/non-zero - failure + */ +int process_rx_desc_remote_wifi3(void *pdev, void *data); + +/** + * process_pktlog_lite_wifi3() - Process pktlog buffers received + * from monitor status ring + * @pdev: pdev handle + * @data: pktlog buffer pointer + * + * Return: 0 - success/non-zero - failure + */ +int process_pktlog_lite_wifi3(void *context, void *log_data, + uint16_t log_type); +#else +static inline A_STATUS +process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) +{ + return 0; +} + +static inline +int process_rx_desc_remote_wifi3(void *pdev, void *data) +{ + return 0; +} + +static inline int +process_pktlog_lite_wifi3(void *context, void *log_data, + uint16_t log_type) +{ + return 0; +} +#endif /* REMOVE_PKT_LOG */ + +/** + * process_tx_info() - process tx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + return 0; +} + +/** + * process_rx_info_remote() - process rx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_rx_info_remote(void *pdev, void *data) +{ + return 0; +} + +/** + * process_rx_remote() - process rx pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_rx_info(void *pdev, void *data) +{ + return 0; +} + +/** + * process_rate_find() - process rate event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_rate_find(void *pdev, void *data) +{ + return 0; +} + +/** + * process_rate_update() - process rate event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_rate_update(void *pdev, void *data) +{ + return 0; +} + +/** + * process_sw_event() - process sw event pktlog buffers + * @txrx_pdev: ol pdev handle + * @data: pktlog buffer + * + * Return: 0 - success/non-zero - failure + */ +static inline +A_STATUS process_sw_event(void *pdev, void *data) +{ + return 0; +} diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c index 269bdaef34342d5fd1877758c17dbac560c59a77..5fe1391612753f13fb9e6eb4452d70cb38489087 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/linux_ac.c @@ -37,7 +37,6 @@ #include "host_diag_core_log.h" #include "ani_global.h" -#define PKTLOG_TAG "ATH_PKTLOG" #define PKTLOG_DEVNAME_SIZE 32 #define MAX_WLANDEV 1 @@ -55,7 +54,7 @@ #ifndef __MOD_INC_USE_COUNT #define PKTLOG_MOD_INC_USE_COUNT do { \ if (!try_module_get(THIS_MODULE)) { \ - printk(KERN_WARNING "try_module_get failed\n"); \ + qdf_nofl_info("try_module_get failed"); \ } } while (0) #define PKTLOG_MOD_DEC_USE_COUNT module_put(THIS_MODULE) @@ -102,9 +101,8 @@ int pktlog_alloc_buf(struct hif_opaque_softc *scn) pl_dev = get_pktlog_handle(); if (!pl_dev) { - printk(PKTLOG_TAG - "%s: Unable to allocate buffer pdev_txrx_handle or pdev_txrx_handle->pl_dev is null\n", - __func__); + qdf_nofl_info(PKTLOG_TAG + "%s: pdev_txrx_handle->pl_dev is null", __func__); return -EINVAL; } @@ -115,16 +113,13 @@ int pktlog_alloc_buf(struct hif_opaque_softc *scn) qdf_spin_lock_bh(&pl_info->log_lock); if (pl_info->buf) { qdf_spin_unlock_bh(&pl_info->log_lock); - printk(PKTLOG_TAG "Buffer is already in use\n"); + qdf_nofl_info(PKTLOG_TAG "Buffer is already in use"); return -EINVAL; } qdf_spin_unlock_bh(&pl_info->log_lock); buffer = vmalloc((page_cnt + 2) * PAGE_SIZE); if (!buffer) { - printk(PKTLOG_TAG - "%s: Unable to allocate buffer " - "(%d pages)\n", __func__, page_cnt); return -ENOMEM; } @@ -204,7 +199,7 @@ qdf_sysctl_decl(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, ppos) if (!scn) { mutex_unlock(&proc_mutex); - printk("%s: Invalid scn context\n", __func__); + qdf_nofl_info("%s: Invalid scn context", __func__); ASSERT(0); return -EINVAL; } @@ -213,7 +208,7 @@ qdf_sysctl_decl(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, ppos) if (!pl_dev) { mutex_unlock(&proc_mutex); - printk("%s: Invalid pktlog context\n", __func__); + qdf_nofl_info("%s: Invalid pktlog context", __func__); ASSERT(0); return -ENODEV; } @@ -267,7 +262,7 @@ qdf_sysctl_decl(ath_sysctl_pktlog_size, ctl, write, filp, buffer, lenp, ppos) if (!scn) { mutex_unlock(&proc_mutex); - printk("%s: Invalid scn context\n", __func__); + qdf_nofl_info("%s: Invalid scn context", __func__); ASSERT(0); return -EINVAL; } @@ -276,7 +271,7 @@ qdf_sysctl_decl(ath_sysctl_pktlog_size, ctl, write, filp, buffer, lenp, ppos) if (!pl_dev) { mutex_unlock(&proc_mutex); - printk("%s: Invalid pktlog handle\n", __func__); + qdf_nofl_info("%s: Invalid pktlog handle", __func__); ASSERT(0); return -ENODEV; } @@ -397,7 +392,7 @@ static int pktlog_sysctl_register(struct hif_opaque_softc *scn) register_sysctl_table(pl_info_lnx->sysctls); if (!pl_info_lnx->sysctl_header) { - printk("%s: failed to register sysctls!\n", proc_name); + qdf_nofl_info("%s: failed to register sysctls!", proc_name); return -EINVAL; } @@ -455,16 +450,16 @@ static int pktlog_attach(struct hif_opaque_softc *scn) &pl_info_lnx->info); if (!proc_entry) { - printk(PKTLOG_TAG "%s: create_proc_entry failed for %s\n", - __func__, proc_name); + qdf_nofl_info(PKTLOG_TAG "%s: create_proc_entry failed for %s", + __func__, proc_name); goto attach_fail1; } pl_info_lnx->proc_entry = proc_entry; if (pktlog_sysctl_register(scn)) { - printk(PKTLOG_TAG "%s: sysctl register failed for %s\n", - __func__, proc_name); + qdf_nofl_info(PKTLOG_TAG "%s: sysctl register failed for %s", + __func__, proc_name); goto attach_fail2; } @@ -485,7 +480,7 @@ static void pktlog_sysctl_unregister(struct pktlog_dev_t *pl_dev) struct ath_pktlog_info_lnx *pl_info_lnx; if (!pl_dev) { - printk("%s: Invalid pktlog context\n", __func__); + qdf_nofl_info("%s: Invalid pktlog context", __func__); ASSERT(0); return; } @@ -505,7 +500,7 @@ static void pktlog_detach(struct hif_opaque_softc *scn) struct pktlog_dev_t *pl_dev = get_pktlog_handle(); if (!pl_dev) { - printk("%s: Invalid pktlog context\n", __func__); + qdf_nofl_info("%s: Invalid pktlog context", __func__); ASSERT(0); return; } @@ -1042,7 +1037,7 @@ int pktlogmod_init(void *context) g_pktlog_pde = proc_mkdir(PKTLOG_PROC_DIR, NULL); if (!g_pktlog_pde) { - printk(PKTLOG_TAG "%s: proc_mkdir failed\n", __func__); + qdf_nofl_info(PKTLOG_TAG "%s: proc_mkdir failed", __func__); return -EPERM; } diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_ac.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_ac.c index c1537a265a6bb7e74df4e9f2834ae22387f5b640..a7a0583e2217e71271e7f7321de7f2f6384ba6be 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_ac.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_ac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -41,6 +41,11 @@ #include "htc.h" #include #include +#ifdef PKTLOG_LEGACY +#include "pktlog_wifi2.h" +#else +#include "pktlog_wifi3.h" +#endif /* PKTLOG_LEGACY */ wdi_event_subscribe PKTLOG_TX_SUBSCRIBER; wdi_event_subscribe PKTLOG_RX_SUBSCRIBER; @@ -70,6 +75,11 @@ void pktlog_sethandle(struct pktlog_dev_t **pl_handle, *pl_handle = &pl_dev; } +void pktlog_set_pdev_id(struct pktlog_dev_t *pl_dev, uint8_t pdev_id) +{ + pl_dev->pdev_id = pdev_id; +} + void pktlog_set_callback_regtype( enum pktlog_callback_regtype callback_type) { @@ -85,19 +95,10 @@ void pktlog_set_callback_regtype( struct pktlog_dev_t *get_pktlog_handle(void) { - struct cdp_pdev *pdev_txrx_handle = - cds_get_context(QDF_MODULE_ID_TXRX); + uint8_t pdev_id = WMI_PDEV_ID_SOC; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - return cdp_get_pldev(soc, pdev_txrx_handle); -} - -/* - * Get current txrx context - */ -void *get_txrx_context(void) -{ - return cds_get_context(QDF_MODULE_ID_TXRX); + return cdp_get_pldev(soc, pdev_id); } static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types, @@ -165,56 +166,56 @@ pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state, #ifdef PKTLOG_LEGACY /** * wdi_pktlog_subscribe() - Subscribe pktlog callbacks - * @cdp_pdev: abstract pdev handle + * @pdev_id: pdev id * @log_state: Pktlog registration * * Return: zero on success, non-zero on failure */ static inline A_STATUS -wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) +wdi_pktlog_subscribe(uint8_t pdev_id, int32_t log_state) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); - if (!cdp_pdev) { + if (pdev_id < 0) { qdf_print("Invalid pdev in %s", __func__); return A_ERROR; } if (log_state & ATH_PKTLOG_TX) { - if (cdp_wdi_event_sub(soc, cdp_pdev, &PKTLOG_TX_SUBSCRIBER, - WDI_EVENT_TX_STATUS)) { + if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_TX_SUBSCRIBER, + WDI_EVENT_TX_STATUS)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RX) { - if (cdp_wdi_event_sub(soc, cdp_pdev, &PKTLOG_RX_SUBSCRIBER, - WDI_EVENT_RX_DESC)) { + if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_RX_SUBSCRIBER, + WDI_EVENT_RX_DESC)) { return A_ERROR; } - if (cdp_wdi_event_sub(soc, cdp_pdev, - &PKTLOG_RX_REMOTE_SUBSCRIBER, - WDI_EVENT_RX_DESC_REMOTE)) { + if (cdp_wdi_event_sub(soc, pdev_id, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RCFIND) { - if (cdp_wdi_event_sub(soc, cdp_pdev, - &PKTLOG_RCFIND_SUBSCRIBER, - WDI_EVENT_RATE_FIND)) { + if (cdp_wdi_event_sub(soc, pdev_id, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RCUPDATE) { - if (cdp_wdi_event_sub(soc, cdp_pdev, - &PKTLOG_RCUPDATE_SUBSCRIBER, - WDI_EVENT_RATE_UPDATE)) { + if (cdp_wdi_event_sub(soc, pdev_id, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_SW_EVENT) { - if (cdp_wdi_event_sub(soc, cdp_pdev, - &PKTLOG_SW_EVENT_SUBSCRIBER, - WDI_EVENT_SW_EVENT)) { + if (cdp_wdi_event_sub(soc, pdev_id, + &PKTLOG_SW_EVENT_SUBSCRIBER, + WDI_EVENT_SW_EVENT)) { return A_ERROR; } } @@ -223,11 +224,11 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) } #else static inline A_STATUS -wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) +wdi_pktlog_subscribe(uint8_t pdev_id, int32_t log_state) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); - if (!cdp_pdev) { + if (pdev_id < 0) { qdf_print("Invalid pdev in %s", __func__); return A_ERROR; } @@ -237,7 +238,7 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) (log_state & ATH_PKTLOG_RCUPDATE) || (log_state & ATH_PKTLOG_SW_EVENT)) { if (cdp_wdi_event_sub(soc, - cdp_pdev, + pdev_id, &PKTLOG_OFFLOAD_SUBSCRIBER, WDI_EVENT_OFFLOAD_ALL)) { return A_ERROR; @@ -245,15 +246,15 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) } if (log_state & ATH_PKTLOG_RX) { - if (cdp_wdi_event_sub(soc, cdp_pdev, - &PKTLOG_RX_SUBSCRIBER, - WDI_EVENT_RX_DESC)) { + if (cdp_wdi_event_sub(soc, pdev_id, + &PKTLOG_RX_SUBSCRIBER, + WDI_EVENT_RX_DESC)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_SW_EVENT) { - if (cdp_wdi_event_sub(soc, cdp_pdev, + if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_SW_EVENT_SUBSCRIBER, WDI_EVENT_SW_EVENT)) { return A_ERROR; @@ -261,7 +262,7 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) } if (log_state & ATH_PKTLOG_LITE_T2H) { - if (cdp_wdi_event_sub(soc, cdp_pdev, + if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_LITE_T2H_SUBSCRIBER, WDI_EVENT_LITE_T2H)) { return A_ERROR; @@ -269,7 +270,7 @@ wdi_pktlog_subscribe(struct cdp_pdev *cdp_pdev, int32_t log_state) } if (log_state & ATH_PKTLOG_LITE_RX) { - if (cdp_wdi_event_sub(soc, cdp_pdev, + if (cdp_wdi_event_sub(soc, pdev_id, &PKTLOG_LITE_RX_SUBSCRIBER, WDI_EVENT_LITE_RX)) { return A_ERROR; @@ -286,7 +287,7 @@ void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data, switch (event) { case WDI_EVENT_OFFLOAD_ALL: { - if (process_offload_pktlog(pdev, log_data)) { + if (process_offload_pktlog_wifi3(pdev, log_data)) { qdf_print("Unable to process offload info"); return; } @@ -370,7 +371,7 @@ lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data, switch (event) { case WDI_EVENT_RX_DESC: { - if (process_rx_desc_remote(context, log_data)) { + if (process_rx_desc_remote_wifi3(context, log_data)) { qdf_print("Unable to process RX info"); return; } @@ -378,8 +379,8 @@ lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data, } case WDI_EVENT_LITE_T2H: { - if (process_pktlog_lite(context, log_data, - PKTLOG_TYPE_LITE_T2H)) { + if (process_pktlog_lite_wifi3(context, log_data, + PKTLOG_TYPE_LITE_T2H)) { qdf_print("Unable to process lite_t2h"); return; } @@ -387,8 +388,8 @@ lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data, } case WDI_EVENT_LITE_RX: { - if (process_pktlog_lite(context, log_data, - PKTLOG_TYPE_LITE_RX)) { + if (process_pktlog_lite_wifi3(context, log_data, + PKTLOG_TYPE_LITE_RX)) { qdf_print("Unable to process lite_rx"); return; } @@ -400,56 +401,50 @@ lit_pktlog_callback(void *context, enum WDI_EVENT event, void *log_data, } #ifdef PKTLOG_LEGACY -/** - * wdi_pktlog_unsubscribe() - Unsubscribe pktlog callbacks - * @cdp_pdev: abstract pdev handle - * @log_state: Pktlog registration - * - * Return: zero on success, non-zero on failure - */ A_STATUS -wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state) +wdi_pktlog_unsubscribe(uint8_t pdev_id, uint32_t log_state) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* TODO: WIN implementation to get soc */ if (log_state & ATH_PKTLOG_TX) { - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_TX_SUBSCRIBER, - WDI_EVENT_TX_STATUS)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_TX_SUBSCRIBER, + WDI_EVENT_TX_STATUS)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RX) { - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_RX_SUBSCRIBER, + WDI_EVENT_RX_DESC)) { return A_ERROR; } - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_RX_REMOTE_SUBSCRIBER, - WDI_EVENT_RX_DESC_REMOTE)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RCFIND) { - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_RCFIND_SUBSCRIBER, - WDI_EVENT_RATE_FIND)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RCUPDATE) { - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_RCUPDATE_SUBSCRIBER, - WDI_EVENT_RATE_UPDATE)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RCUPDATE) { - if (cdp_wdi_event_unsub(soc, pdev, - &PKTLOG_SW_EVENT_SUBSCRIBER, - WDI_EVENT_SW_EVENT)) { + if (cdp_wdi_event_unsub(soc, pdev_id, + &PKTLOG_SW_EVENT_SUBSCRIBER, + WDI_EVENT_SW_EVENT)) { return A_ERROR; } } @@ -458,7 +453,7 @@ wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state) } #else A_STATUS -wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state) +wdi_pktlog_unsubscribe(uint8_t pdev_id, uint32_t log_state) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -467,28 +462,28 @@ wdi_pktlog_unsubscribe(struct cdp_pdev *pdev, uint32_t log_state) (log_state & ATH_PKTLOG_RCUPDATE) || (log_state & ATH_PKTLOG_SW_EVENT)) { if (cdp_wdi_event_unsub(soc, - pdev, + pdev_id, &PKTLOG_OFFLOAD_SUBSCRIBER, WDI_EVENT_OFFLOAD_ALL)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_RX) { - if (cdp_wdi_event_unsub(soc, pdev, + if (cdp_wdi_event_unsub(soc, pdev_id, &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_LITE_T2H) { - if (cdp_wdi_event_unsub(soc, pdev, + if (cdp_wdi_event_unsub(soc, pdev_id, &PKTLOG_LITE_T2H_SUBSCRIBER, WDI_EVENT_LITE_T2H)) { return A_ERROR; } } if (log_state & ATH_PKTLOG_LITE_RX) { - if (cdp_wdi_event_unsub(soc, pdev, + if (cdp_wdi_event_unsub(soc, pdev_id, &PKTLOG_LITE_RX_SUBSCRIBER, WDI_EVENT_LITE_RX)) { return A_ERROR; @@ -504,7 +499,7 @@ int pktlog_disable(struct hif_opaque_softc *scn) struct pktlog_dev_t *pl_dev; struct ath_pktlog_info *pl_info; uint8_t save_pktlog_state; - struct cdp_pdev *txrx_pdev = get_txrx_context(); + uint8_t pdev_id = WMI_PDEV_ID_SOC; pl_dev = get_pktlog_handle(); @@ -520,8 +515,8 @@ int pktlog_disable(struct hif_opaque_softc *scn) return -EINVAL; } - if (!txrx_pdev) { - qdf_print("Invalid cdp_pdev"); + if (pdev_id < 0) { + qdf_print("Invalid pdev"); return -EINVAL; } @@ -543,7 +538,7 @@ int pktlog_disable(struct hif_opaque_softc *scn) } if (pl_dev->is_pktlog_cb_subscribed && - wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) { + wdi_pktlog_unsubscribe(pdev_id, pl_info->log_state)) { pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS; qdf_print("Cannot unsubscribe pktlog from the WDI"); return -EINVAL; @@ -637,7 +632,7 @@ int __pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, { struct pktlog_dev_t *pl_dev; struct ath_pktlog_info *pl_info; - struct cdp_pdev *cdp_pdev; + uint8_t pdev_id; int error; if (!scn) { @@ -653,8 +648,8 @@ int __pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, return -EINVAL; } - cdp_pdev = get_txrx_context(); - if (!cdp_pdev) { + pdev_id = WMI_PDEV_ID_SOC; + if (pdev_id < 0) { qdf_print("%s: Invalid txrx context", __func__); ASSERT(0); return -EINVAL; @@ -725,7 +720,7 @@ int __pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, if (log_state != 0) { /* WDI subscribe */ if (!pl_dev->is_pktlog_cb_subscribed) { - error = wdi_pktlog_subscribe(cdp_pdev, log_state); + error = wdi_pktlog_subscribe(pdev_id, log_state); if (error) { pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS; @@ -795,7 +790,7 @@ static int __pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) { struct pktlog_dev_t *pl_dev; struct ath_pktlog_info *pl_info; - struct cdp_pdev *pdev; + uint8_t pdev_id = WMI_PDEV_ID_SOC; void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint32_t buff_size; uint32_t max_allowed_buff_size; @@ -814,10 +809,8 @@ static int __pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) return -EINVAL; } - pdev = get_txrx_context(); - - if (!pdev) { - qdf_print("%s: invalid pdev handle", __func__); + if (pdev_id < 0) { + qdf_print("%s: invalid pdev", __func__); return -EINVAL; } @@ -857,7 +850,7 @@ static int __pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) qdf_spin_lock_bh(&pl_info->log_lock); if (pl_info->buf) { if (pl_dev->is_pktlog_cb_subscribed && - wdi_pktlog_unsubscribe(pdev, pl_info->log_state)) { + wdi_pktlog_unsubscribe(pdev_id, pl_info->log_state)) { pl_info->curr_pkt_state = PKTLOG_OPR_NOT_IN_PROGRESS; qdf_spin_unlock_bh(&pl_info->log_lock); @@ -972,21 +965,14 @@ int pktlog_clearbuff(struct hif_opaque_softc *scn, bool clear_buff) return 0; } -/** - * pktlog_process_fw_msg() - process packetlog message - * @buff: buffer - * - * Return: None - */ -void pktlog_process_fw_msg(uint32_t *buff, uint32_t len) +void pktlog_process_fw_msg(uint8_t pdev_id, uint32_t *buff, uint32_t len) { uint32_t *pl_hdr; uint32_t log_type; - struct cdp_pdev *pdev = get_txrx_context(); struct ol_fw_data pl_fw_data; - if (!pdev) { - qdf_print("%s: txrx_pdev is NULL", __func__); + if (pdev_id == OL_TXRX_INVALID_PDEV_ID) { + qdf_print("%s: txrx pdev_id is invalid", __func__); return; } pl_hdr = buff; @@ -1003,19 +989,19 @@ void pktlog_process_fw_msg(uint32_t *buff, uint32_t len) || (log_type == PKTLOG_TYPE_TX_FRM_HDR) || (log_type == PKTLOG_TYPE_TX_VIRT_ADDR)) wdi_event_handler(WDI_EVENT_TX_STATUS, - pdev, &pl_fw_data); + pdev_id, &pl_fw_data); else if (log_type == PKTLOG_TYPE_RC_FIND) wdi_event_handler(WDI_EVENT_RATE_FIND, - pdev, &pl_fw_data); + pdev_id, &pl_fw_data); else if (log_type == PKTLOG_TYPE_RC_UPDATE) wdi_event_handler(WDI_EVENT_RATE_UPDATE, - pdev, &pl_fw_data); + pdev_id, &pl_fw_data); else if (log_type == PKTLOG_TYPE_RX_STAT) wdi_event_handler(WDI_EVENT_RX_DESC, - pdev, &pl_fw_data); + pdev_id, &pl_fw_data); else if (log_type == PKTLOG_TYPE_SW_EVENT) wdi_event_handler(WDI_EVENT_SW_EVENT, - pdev, &pl_fw_data); + pdev_id, &pl_fw_data); } #if defined(QCA_WIFI_3_0_ADRASTEA) @@ -1066,7 +1052,7 @@ static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt) msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg); msg_len = qdf_nbuf_len(pktlog_t2h_msg); - pktlog_process_fw_msg(msg_word, msg_len); + pktlog_process_fw_msg(pdev->pdev_id, msg_word, msg_len); qdf_nbuf_free(pktlog_t2h_msg); } diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_internal.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_internal.c index dae0059a18265dd86eccfea46ef2302420a9f090..d028931f0145ff8b84f129c86ac864063a5b7096 100644 --- a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_internal.c +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_internal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -42,63 +42,33 @@ #include "wma_api.h" #include "wlan_logging_sock_svc.h" -#define TX_DESC_ID_LOW_MASK 0xffff -#define TX_DESC_ID_LOW_SHIFT 0 -#define TX_DESC_ID_HIGH_MASK 0xffff0000 -#define TX_DESC_ID_HIGH_SHIFT 16 - #ifdef PKTLOG_HAS_SPECIFIC_DATA -static inline void +void pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr, uint32_t type_specific_data) { log_hdr->type_specific_data = type_specific_data; } -static inline uint32_t +uint32_t pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr) { return log_hdr->type_specific_data; } -static inline void +void pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg, uint32_t type_specific_data) { plarg->type_specific_data = type_specific_data; } -static inline uint32_t +uint32_t pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg) { return plarg->type_specific_data; } - -#else -static inline void -pktlog_hdr_set_specific_data(struct ath_pktlog_hdr *log_hdr, - uint32_t type_specific_data) -{ -} - -static inline uint32_t -pktlog_hdr_get_specific_data(struct ath_pktlog_hdr *log_hdr) -{ - return 0; -} - -static inline void -pktlog_arg_set_specific_data(struct ath_pktlog_arg *plarg, - uint32_t type_specific_data) -{ -} - -static inline uint32_t -pktlog_arg_get_specific_data(struct ath_pktlog_arg *plarg) -{ - return 0; -} -#endif +#endif /* PKTLOG_HAS_SPECIFIC_DATA */ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg) { @@ -116,7 +86,7 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg) #endif if (!plarg) { - printk("Invalid parg in %s\n", __func__); + qdf_nofl_info("Invalid parg in %s", __func__); return; } @@ -132,7 +102,7 @@ void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg) flags = plarg->flags; if (!log_buf) { - printk("Invalid log_buf in %s\n", __func__); + qdf_nofl_info("Invalid log_buf in %s", __func__); return; } @@ -226,1340 +196,4 @@ char *pktlog_getbuf(struct pktlog_dev_t *pl_dev, return plarg.buf; } - -static struct txctl_frm_hdr frm_hdr; - -#ifndef HELIUMPLUS -static void process_ieee_hdr(void *data) -{ - uint8_t dir; - struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); - - frm_hdr.framectrl = *(uint16_t *) (wh->i_fc); - frm_hdr.seqctrl = *(uint16_t *) (wh->i_seq); - dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); - - if (dir == IEEE80211_FC1_DIR_TODS) { - frm_hdr.bssid_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - } else if (dir == IEEE80211_FC1_DIR_FROMDS) { - frm_hdr.bssid_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - } else { - frm_hdr.bssid_tail = - (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr3 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.sa_tail = - (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr2 - [QDF_MAC_ADDR_SIZE - - 1]); - frm_hdr.da_tail = - (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> - i_addr1 - [QDF_MAC_ADDR_SIZE - - 1]); - } -} - -/** - * fill_ieee80211_hdr_data() - fill ieee802.11 data header - * @txrx_pdev: txrx pdev - * @pl_msdu_info: msdu info - * @data: data received from event - * - * Return: none - */ -/* TODO: Platform specific function */ -static void -fill_ieee80211_hdr_data(struct cdp_pdev *pdev, - struct ath_pktlog_msdu_info *pl_msdu_info, void *data) -{ - uint32_t i; - uint32_t *htt_tx_desc; - struct ol_tx_desc_t *tx_desc; - uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; - uint16_t tx_desc_id; - uint32_t *msdu_id_info = (uint32_t *) - ((void *)data + sizeof(struct ath_pktlog_hdr)); - uint32_t *msdu_id = (uint32_t *) ((char *)msdu_id_info + - msdu_id_offset); - uint8_t *addr, *vap_addr; - uint8_t vdev_id; - qdf_nbuf_t netbuf; - uint32_t len; - struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev; - - - pl_msdu_info->num_msdu = *msdu_id_info; - pl_msdu_info->priv_size = sizeof(uint32_t) * - pl_msdu_info->num_msdu + sizeof(uint32_t); - - if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid num_msdu count", - __func__); - qdf_assert(0); - return; - } - for (i = 0; i < pl_msdu_info->num_msdu; i++) { - /* - * Handle big endianness - * Increment msdu_id once after retrieving - * lower 16 bits and uppper 16 bits - */ - if (!(i % 2)) { - tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) - >> TX_DESC_ID_LOW_SHIFT); - } else { - tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) - >> TX_DESC_ID_HIGH_SHIFT); - msdu_id += 1; - } - if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "%s: drop due to invalid msdu id = %x", - __func__, tx_desc_id); - return; - } - tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); - qdf_assert(tx_desc); - netbuf = tx_desc->netbuf; - htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc; - qdf_assert(htt_tx_desc); - - qdf_nbuf_peek_header(netbuf, &addr, &len); - - if (len < (2 * QDF_MAC_ADDR_SIZE)) { - qdf_print("TX frame does not have a valid address"); - return; - } - /* Adding header information for the TX data frames */ - vdev_id = (uint8_t) (*(htt_tx_desc + - HTT_TX_VDEV_ID_WORD) >> - HTT_TX_VDEV_ID_SHIFT) & - HTT_TX_VDEV_ID_MASK; - - vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); - - frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) | - (addr[QDF_MAC_ADDR_SIZE - 1]); - frm_hdr.sa_tail = - (addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) | - (addr[2 * QDF_MAC_ADDR_SIZE - 1]); - if (vap_addr) { - frm_hdr.bssid_tail = - (vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) | - (vap_addr[QDF_MAC_ADDR_SIZE - 1]); - } else { - frm_hdr.bssid_tail = 0x0000; - } - pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc + - HTT_TX_MSDU_LEN_DWORD) - & HTT_TX_MSDU_LEN_MASK; - /* - * Add more information per MSDU - * e.g., protocol information - */ - } - -} -#endif - -#ifdef HELIUMPLUS -A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) -{ - /* - * Must include to process different types - * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR - */ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!txrx_pdev) { - printk("Invalid pdev in %s\n", __func__); - return A_ERROR; - } - - if (!pl_dev) { - pr_err("Invalid pktlog handle in %s\n", __func__); - qdf_assert(pl_dev); - return A_ERROR; - } - - qdf_assert(data); - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - pl_hdr.type_specific_data = - *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); - pl_info = pl_dev->pl_info; - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { - size_t log_size = sizeof(frm_hdr) + pl_hdr.size; - void *txdesc_hdr_ctl = (void *) - pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); - qdf_assert(txdesc_hdr_ctl); - qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t))); - - qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr)); - qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr), - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - pl_hdr.size = log_size; - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txdesc_hdr_ctl); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { - struct ath_pktlog_tx_status txstat_log; - size_t log_size = pl_hdr.size; - - txstat_log.ds_status = (void *) - pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_assert(txstat_log.ds_status); - qdf_mem_copy(txstat_log.ds_status, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - /* TODO: MCL specific API */ - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txstat_log.ds_status); - } - return A_OK; -} -#else -A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) -{ - /* - * Must include to process different types - * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR - */ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!txrx_pdev) { - qdf_print("Invalid pdev in %s", __func__); - return A_ERROR; - } - - if (!pl_dev) { - pr_err("Invalid pktlog handle in %s\n", __func__); - qdf_assert(pl_dev); - return A_ERROR; - } - - qdf_assert(data); - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - - pktlog_hdr_set_specific_data(&pl_hdr, - *(pl_tgt_hdr + - ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); - - pl_info = pl_dev->pl_info; - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { - /* Valid only for the TX CTL */ - process_ieee_hdr(fw_data->data + sizeof(pl_hdr)); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { - uint32_t desc_id = (uint32_t) *((uint32_t *)(fw_data->data + - sizeof(pl_hdr))); - uint32_t vdev_id = desc_id; - - /* if the pkt log msg is for the bcn frame the vdev id - * is piggybacked in desc_id and the MSB of the desc ID - * would be set to FF - */ -#define BCN_DESC_ID 0xFF - if ((desc_id >> 24) == BCN_DESC_ID) { - void *data; - uint32_t buf_size; - - vdev_id &= 0x00FFFFFF; - /* TODO: MCL specific API */ - data = wma_get_beacon_buffer_by_vdev_id(vdev_id, - &buf_size); - if (data) { - /* TODO: platform specific API */ - process_ieee_hdr(data); - qdf_mem_free(data); - } - } else { - /* - * TODO: get the hdr content for mgmt frames from - * Tx mgmt desc pool - */ - } - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { - struct ath_pktlog_txctl txctl_log; - size_t log_size = sizeof(txctl_log.priv); - - txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, - pl_info, - log_size, - &pl_hdr); - - if (!txctl_log.txdesc_hdr_ctl) { - printk - ("failed to get buf for txctl_log.txdesc_hdr_ctl\n"); - return A_ERROR; - } - - /* - * frm hdr is currently Valid only for local frames - * Add capability to include the fmr hdr for remote frames - */ - txctl_log.priv.frm_hdr = frm_hdr; - qdf_assert(txctl_log.priv.txdesc_ctl); - qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl)); - pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl)) - ? sizeof(txctl_log.priv.txdesc_ctl) : - pl_hdr.size; - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - qdf_assert(txctl_log.txdesc_hdr_ctl); - qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, - sizeof(txctl_log.priv)); - pl_hdr.size = log_size; - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txctl_log.txdesc_hdr_ctl); - /* Add Protocol information and HT specific information */ - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { - struct ath_pktlog_tx_status txstat_log; - size_t log_size = pl_hdr.size; - - txstat_log.ds_status = (void *) - pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); - qdf_assert(txstat_log.ds_status); - qdf_mem_copy(txstat_log.ds_status, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - txstat_log.ds_status); - } - - if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { - struct ath_pktlog_msdu_info pl_msdu_info; - size_t log_size; - - qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info)); - log_size = sizeof(pl_msdu_info.priv); - - if (pl_dev->mt_pktlog_enabled == false) - fill_ieee80211_hdr_data(txrx_pdev, - &pl_msdu_info, fw_data->data); - - pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, - ((void *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - sizeof(pl_msdu_info.priv.msdu_id_info)); - qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, - sizeof(pl_msdu_info.priv)); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - pl_msdu_info.ath_msdu_info); - } - - return A_OK; -} -#endif - -/** - * process_offload_pktlog() - Process full pktlog events - * pdev: abstract pdev handle - * data: pktlog buffer - * - * Return: zero on success, non-zero on failure - */ -A_STATUS -process_offload_pktlog(struct cdp_pdev *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_info *pl_info; - struct ath_pktlog_hdr pl_hdr; - uint32_t *pl_tgt_hdr; - void *txdesc_hdr_ctl = NULL; - size_t log_size = 0; - size_t tmp_log_size = 0; - - if (!pl_dev) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Invalid context in %s\n", __func__); - return A_ERROR; - } - - if (!data) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Invalid data in %s\n", __func__); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)data; - - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - - pktlog_hdr_set_specific_data(&pl_hdr, - *(pl_tgt_hdr + - ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); - - if (pl_hdr.size > MAX_PKTLOG_RECV_BUF_SIZE) { - pl_dev->invalid_packets++; - return A_ERROR; - } - - /* - * Must include to process different types - * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR - */ - pl_info = pl_dev->pl_info; - tmp_log_size = sizeof(frm_hdr) + pl_hdr.size; - log_size = pl_hdr.size; - txdesc_hdr_ctl = - (void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); - if (!txdesc_hdr_ctl) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "Failed to allocate pktlog descriptor"); - return A_NO_MEMORY; - } - qdf_assert(txdesc_hdr_ctl); - qdf_assert(pl_hdr->size < PKTLOG_MAX_TX_WORDS * sizeof(u_int32_t)); - qdf_mem_copy(txdesc_hdr_ctl, - ((void *)data + sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, txdesc_hdr_ctl); - - return A_OK; -} - -/* TODO: hardware dependent function */ -A_STATUS process_rx_info_remote(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_info *pl_info; - struct htt_host_rx_desc_base *rx_desc; - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_rx_info rxstat_log; - size_t log_size; - struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data; - qdf_nbuf_t msdu; - - if (!pdev || !r_data || !pl_dev) { - qdf_print("%s: Invalid handle", __func__); - return A_ERROR; - } - - pl_info = pl_dev->pl_info; - msdu = r_data->msdu; - - while (msdu) { - rx_desc = - (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1; - log_size = - sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base); - - /* - * Construct the pktlog header pl_hdr - * Because desc is DMA'd to the host memory - */ - pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); - pl_hdr.missed_cnt = 0; -#if defined(HELIUMPLUS) - pl_hdr.macId = r_data->mac_id; - pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; -#else - pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; -#endif - pl_hdr.size = sizeof(*rx_desc) - - sizeof(struct htt_host_fw_desc_base); -#if defined(HELIUMPLUS) - pl_hdr.timestamp = - rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32; - pl_hdr.type_specific_data = 0xDEADAA; -#else - pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp; -#endif /* !defined(HELIUMPLUS) */ - - pktlog_hdr_set_specific_data(&pl_hdr, 0xDEADAA); - - rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc + - sizeof(struct htt_host_fw_desc_base), pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - rxstat_log.rx_desc); - msdu = qdf_nbuf_next(msdu); - } - return A_OK; -} - -#ifdef HELIUMPLUS -A_STATUS process_rx_info(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_info *pl_info; - struct ath_pktlog_rx_info rxstat_log; - struct ath_pktlog_hdr pl_hdr; - size_t log_size; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!pdev) { - printk("Invalid pdev in %s", __func__); - return A_ERROR; - } - - pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; - if (!pl_dev) { - printk("Invalid pl_dev in %s", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_info = pl_dev->pl_info; - pl_tgt_hdr = (uint32_t *)fw_data->data; - - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - - log_size = pl_hdr.size; - rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_mem_copy(rxstat_log.rx_desc, - (void *)fw_data->data + sizeof(struct ath_pktlog_hdr), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); - - return A_OK; -} - -#else -A_STATUS process_rx_info(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_info *pl_info; - struct ath_pktlog_rx_info rxstat_log; - struct ath_pktlog_hdr pl_hdr; - size_t log_size; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!pdev) { - printk("Invalid pdev in %s", __func__); - return A_ERROR; - } - - pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; - if (!pl_dev) { - printk("Invalid pl_dev in %s", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_info = pl_dev->pl_info; - pl_tgt_hdr = (uint32_t *)fw_data->data; - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - - log_size = pl_hdr.size; - rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - qdf_mem_copy(rxstat_log.rx_desc, - (void *)fw_data->data + sizeof(struct ath_pktlog_hdr), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); - - return A_OK; -} -#endif - -#ifdef HELIUMPLUS -A_STATUS process_rate_find(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - size_t log_size; - uint32_t len; - struct ol_fw_data *fw_data; - - /* - * Will be uncommented when the rate control find - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - struct ath_pktlog_rc_find rcf_log; - uint32_t *pl_tgt_hdr; - - if (!pdev || !data || !pl_dev) { - qdf_print("%s: Invalid handle", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - pl_info = pl_dev->pl_info; - log_size = pl_hdr.size; - rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(rcf_log.rcFind, - ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind); - - return A_OK; -} - -#else -A_STATUS process_rate_find(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - size_t log_size; - uint32_t len; - struct ol_fw_data *fw_data; - - /* - * Will be uncommented when the rate control find - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - struct ath_pktlog_rc_find rcf_log; - uint32_t *pl_tgt_hdr; - - if (!pdev || !data || !pl_dev) { - qdf_print("%s: Invalid handle", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - pl_info = pl_dev->pl_info; - log_size = pl_hdr.size; - rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(rcf_log.rcFind, - ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind); - - return A_OK; -} -#endif - -#ifdef HELIUMPLUS -A_STATUS process_sw_event(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - size_t log_size; - uint32_t len; - struct ol_fw_data *fw_data; - - /* - * Will be uncommented when the rate control find - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - struct ath_pktlog_sw_event sw_event; - uint32_t *pl_tgt_hdr; - - if (!pdev) { - qdf_print("Invalid pdev in %s", __func__); - return A_ERROR; - } - if (!data) { - qdf_print("Invalid data in %s", __func__); - return A_ERROR; - } - if (!pl_dev) { - qdf_print("Invalid pl_dev in %s", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - - pl_hdr.type_specific_data = - *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); - pl_info = pl_dev->pl_info; - log_size = pl_hdr.size; - sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(sw_event.sw_event, - ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event); - - return A_OK; -} - -#else -A_STATUS process_sw_event(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_info *pl_info; - size_t log_size; - uint32_t len; - struct ol_fw_data *fw_data; - - /* - * Will be uncommented when the rate control find - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - struct ath_pktlog_sw_event sw_event; - uint32_t *pl_tgt_hdr; - - if (!pdev) { - qdf_print("Invalid pdev in %s", __func__); - return A_ERROR; - } - if (!data) { - qdf_print("Invalid data in %s", __func__); - return A_ERROR; - } - if (!pl_dev) { - qdf_print("Invalid pl_dev in %s", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - - pktlog_hdr_set_specific_data(&pl_hdr, - *(pl_tgt_hdr + - ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); - - pl_info = pl_dev->pl_info; - log_size = pl_hdr.size; - sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(sw_event.sw_event, - ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event); - - return A_OK; -} -#endif - -#ifdef HELIUMPLUS -A_STATUS process_rate_update(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - size_t log_size; - struct ath_pktlog_info *pl_info; - struct ath_pktlog_rc_update rcu_log; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!pdev || !data || !pl_dev) { - qdf_print("%s: Invalid handle", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & - ATH_PKTLOG_HDR_MAC_ID_MASK) >> - ATH_PKTLOG_HDR_MAC_ID_SHIFT; - pl_hdr.flags |= PKTLOG_HDR_SIZE_16; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - log_size = pl_hdr.size; - pl_info = pl_dev->pl_info; - - /* - * Will be uncommented when the rate control update - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(rcu_log.txRateCtrl, - ((char *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl); - return A_OK; -} - -#else -A_STATUS process_rate_update(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - size_t log_size; - struct ath_pktlog_info *pl_info; - struct ath_pktlog_rc_update rcu_log; - uint32_t *pl_tgt_hdr; - struct ol_fw_data *fw_data; - uint32_t len; - - if (!pdev || !data || !pl_dev) { - qdf_print("%s: Invalid handle", __func__); - return A_ERROR; - } - - fw_data = (struct ol_fw_data *)data; - len = fw_data->len; - if (len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || - len < (sizeof(uint32_t) * - (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { - qdf_print("Invalid msdu len in %s", __func__); - qdf_assert(0); - return A_ERROR; - } - - pl_tgt_hdr = (uint32_t *)fw_data->data; - /* - * Makes the short words (16 bits) portable b/w little endian - * and big endian - */ - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & - ATH_PKTLOG_HDR_FLAGS_MASK) >> - ATH_PKTLOG_HDR_FLAGS_SHIFT; - pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & - ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> - ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; - pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & - ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> - ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; - pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & - ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; - pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); - log_size = pl_hdr.size; - pl_info = pl_dev->pl_info; - - /* - * Will be uncommented when the rate control update - * for pktlog is implemented in the firmware. - * Currently derived from the TX PPDU status - */ - rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { - qdf_assert(0); - return A_ERROR; - } - qdf_mem_copy(rcu_log.txRateCtrl, - ((char *)fw_data->data + - sizeof(struct ath_pktlog_hdr)), - pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl); - return A_OK; -} -#endif - -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) -int process_rx_desc_remote(void *pdev, void *data) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_rx_info rxstat_log; - size_t log_size; - struct ath_pktlog_info *pl_info; - qdf_nbuf_t log_nbuf = (qdf_nbuf_t)data; - - if (!pl_dev) { - qdf_err("Pktlog handle is NULL"); - return -EINVAL; - } - - pl_info = pl_dev->pl_info; - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); - pl_hdr.missed_cnt = 0; - pl_hdr.log_type = 22; /*PKTLOG_TYPE_RX_STATBUF*/ - pl_hdr.size = qdf_nbuf_len(log_nbuf); - pl_hdr.timestamp = 0; - log_size = pl_hdr.size; - rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - - if (!rxstat_log.rx_desc) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - "%s: Rx descriptor is NULL", __func__); - return -EINVAL; - } - - qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size); - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, - rxstat_log.rx_desc); - return 0; -} - -int -process_pktlog_lite(void *context, void *log_data, uint16_t log_type) -{ - struct pktlog_dev_t *pl_dev = get_pktlog_handle(); - struct ath_pktlog_info *pl_info; - struct ath_pktlog_hdr pl_hdr; - struct ath_pktlog_rx_info rxstat_log; - size_t log_size; - qdf_nbuf_t log_nbuf = (qdf_nbuf_t)log_data; - - if (!pl_dev) { - qdf_err("Pktlog handle is NULL"); - return -EINVAL; - } - - pl_info = pl_dev->pl_info; - qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); - pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); - pl_hdr.missed_cnt = 0; - pl_hdr.log_type = log_type; - pl_hdr.size = qdf_nbuf_len(log_nbuf); - pl_hdr.timestamp = 0; - log_size = pl_hdr.size; - rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, - log_size, &pl_hdr); - if (!rxstat_log.rx_desc) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - "%s: Rx descriptor is NULL", __func__); - return -EINVAL; - } - - qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size); - - cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); - return 0; -} -#else -int process_rx_desc_remote(void *pdev, void *data) -{ - return 0; -} -int -process_pktlog_lite(void *context, void *log_data, uint16_t log_type) -{ - return 0; -} -#endif #endif /*REMOVE_PKT_LOG */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi2.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi2.c new file mode 100644 index 0000000000000000000000000000000000000000..2cc8ae7866af19e12da69534be7cda7dffb48f3b --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi2.c @@ -0,0 +1,1196 @@ +/** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* WIFI2 - Refers to legacy platforms */ +#include "pktlog_wifi2.h" + +#ifndef REMOVE_PKT_LOG +static struct txctl_frm_hdr frm_hdr; + +#ifndef HELIUMPLUS +/** + * process_ieee_hdr(): Process ieee header from the pktlog buffer + * @data: pktlog buffer + * + * Return: None + */ +static void process_ieee_hdr(void *data) +{ + uint8_t dir; + struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); + + frm_hdr.framectrl = *(uint16_t *)(wh->i_fc); + frm_hdr.seqctrl = *(uint16_t *)(wh->i_seq); + dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); + + if (dir == IEEE80211_FC1_DIR_TODS) { + frm_hdr.bssid_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + } else if (dir == IEEE80211_FC1_DIR_FROMDS) { + frm_hdr.bssid_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + } else { + frm_hdr.bssid_tail = + (wh->i_addr3[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr3 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr2 + [QDF_MAC_ADDR_SIZE + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[QDF_MAC_ADDR_SIZE - 2] << 8) | (wh-> + i_addr1 + [QDF_MAC_ADDR_SIZE + - 1]); + } +} + +/** + * fill_ieee80211_hdr_data() - fill ieee802.11 data header + * @txrx_pdev: txrx pdev + * @pl_msdu_info: msdu info + * @data: data received from event + * + * Return: none + */ +/* TODO: Platform specific function */ +static void +fill_ieee80211_hdr_data(struct cdp_pdev *pdev, + struct ath_pktlog_msdu_info *pl_msdu_info, + void *data) +{ + uint32_t i; + uint32_t *htt_tx_desc; + struct ol_tx_desc_t *tx_desc; + uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; + uint16_t tx_desc_id; + uint32_t *msdu_id_info = (uint32_t *) + ((void *)data + sizeof(struct ath_pktlog_hdr)); + uint32_t *msdu_id = (uint32_t *)((char *)msdu_id_info + + msdu_id_offset); + uint8_t *addr, *vap_addr; + uint8_t vdev_id; + qdf_nbuf_t netbuf; + uint32_t len; + struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)pdev; + + pl_msdu_info->num_msdu = *msdu_id_info; + pl_msdu_info->priv_size = sizeof(uint32_t) * + pl_msdu_info->num_msdu + sizeof(uint32_t); + + if (pl_msdu_info->num_msdu > MAX_PKT_INFO_MSDU_ID) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: Invalid num_msdu count", + __func__); + qdf_assert(0); + return; + } + for (i = 0; i < pl_msdu_info->num_msdu; i++) { + /* + * Handle big endianness + * Increment msdu_id once after retrieving + * lower 16 bits and uppper 16 bits + */ + if (!(i % 2)) { + tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) + >> TX_DESC_ID_LOW_SHIFT); + } else { + tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) + >> TX_DESC_ID_HIGH_SHIFT); + msdu_id += 1; + } + if (tx_desc_id >= txrx_pdev->tx_desc.pool_size) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: drop due to invalid msdu id = %x", + __func__, tx_desc_id); + return; + } + tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); + qdf_assert(tx_desc); + netbuf = tx_desc->netbuf; + htt_tx_desc = (uint32_t *)tx_desc->htt_tx_desc; + qdf_assert(htt_tx_desc); + + qdf_nbuf_peek_header(netbuf, &addr, &len); + + if (len < (2 * QDF_MAC_ADDR_SIZE)) { + qdf_print("TX frame does not have a valid address"); + return; + } + /* Adding header information for the TX data frames */ + vdev_id = (uint8_t)(*(htt_tx_desc + + HTT_TX_VDEV_ID_WORD) >> + HTT_TX_VDEV_ID_SHIFT) & + HTT_TX_VDEV_ID_MASK; + + vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); + + frm_hdr.da_tail = (addr[QDF_MAC_ADDR_SIZE - 2] << 8) | + (addr[QDF_MAC_ADDR_SIZE - 1]); + frm_hdr.sa_tail = + (addr[2 * QDF_MAC_ADDR_SIZE - 2] << 8) | + (addr[2 * QDF_MAC_ADDR_SIZE - 1]); + if (vap_addr) { + frm_hdr.bssid_tail = + (vap_addr[QDF_MAC_ADDR_SIZE - 2] << 8) | + (vap_addr[QDF_MAC_ADDR_SIZE - 1]); + } else { + frm_hdr.bssid_tail = 0x0000; + } + pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc + + HTT_TX_MSDU_LEN_DWORD) + & HTT_TX_MSDU_LEN_MASK; + /* + * Add more information per MSDU + * e.g., protocol information + */ + } +} +#endif /* HELIUMPLUS */ + +#ifdef HELIUMPLUS +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!txrx_pdev) { + qdf_nofl_info("Invalid pdev in %s", __func__); + return A_ERROR; + } + + if (!pl_dev) { + qdf_nofl_err("Invalid pktlog handle in %s", __func__); + qdf_assert(pl_dev); + return A_ERROR; + } + + qdf_assert(data); + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_hdr.type_specific_data = + *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); + pl_info = pl_dev->pl_info; + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + size_t log_size = sizeof(frm_hdr) + pl_hdr.size; + void *txdesc_hdr_ctl = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + qdf_assert(txdesc_hdr_ctl); + qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t))); + + qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr)); + qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr), + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txdesc_hdr_ctl); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + /* TODO: MCL specific API */ + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + return A_OK; +} +#else +A_STATUS process_tx_info(struct cdp_pdev *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!txrx_pdev) { + qdf_print("Invalid pdev in %s", __func__); + return A_ERROR; + } + + if (!pl_dev) { + qdf_nofl_err("Invalid pktlog handle in %s", __func__); + qdf_assert(pl_dev); + return A_ERROR; + } + + qdf_assert(data); + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pktlog_hdr_set_specific_data(&pl_hdr, + *(pl_tgt_hdr + + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); + + pl_info = pl_dev->pl_info; + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { + /* Valid only for the TX CTL */ + process_ieee_hdr(fw_data->data + sizeof(pl_hdr)); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { + uint32_t desc_id = (uint32_t)*((uint32_t *)(fw_data->data + + sizeof(pl_hdr))); + uint32_t vdev_id = desc_id; + + /* if the pkt log msg is for the bcn frame the vdev id + * is piggybacked in desc_id and the MSB of the desc ID + * would be set to FF + */ +#define BCN_DESC_ID 0xFF + if ((desc_id >> 24) == BCN_DESC_ID) { + void *data; + uint32_t buf_size; + + vdev_id &= 0x00FFFFFF; + /* TODO: MCL specific API */ + data = wma_get_beacon_buffer_by_vdev_id(vdev_id, + &buf_size); + if (data) { + /* TODO: platform specific API */ + process_ieee_hdr(data); + qdf_mem_free(data); + } + } else { + /* + * TODO: get the hdr content for mgmt frames from + * Tx mgmt desc pool + */ + } + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + struct ath_pktlog_txctl txctl_log; + size_t log_size = sizeof(txctl_log.priv); + + txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, + pl_info, + log_size, + &pl_hdr); + + if (!txctl_log.txdesc_hdr_ctl) { + qdf_nofl_info + ("failed to get txctl_log.txdesc_hdr_ctl buf"); + return A_ERROR; + } + + /* + * frm hdr is currently Valid only for local frames + * Add capability to include the fmr hdr for remote frames + */ + txctl_log.priv.frm_hdr = frm_hdr; + qdf_assert(txctl_log.priv.txdesc_ctl); + qdf_assert(pl_hdr.size < sizeof(txctl_log.priv.txdesc_ctl)); + pl_hdr.size = (pl_hdr.size > sizeof(txctl_log.priv.txdesc_ctl)) + ? sizeof(txctl_log.priv.txdesc_ctl) : + pl_hdr.size; + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + qdf_assert(txctl_log.txdesc_hdr_ctl); + qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, + sizeof(txctl_log.priv)); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txctl_log.txdesc_hdr_ctl); + /* Add Protocol information and HT specific information */ + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { + struct ath_pktlog_msdu_info pl_msdu_info; + size_t log_size; + + qdf_mem_zero(&pl_msdu_info, sizeof(pl_msdu_info)); + log_size = sizeof(pl_msdu_info.priv); + + if (pl_dev->mt_pktlog_enabled == false) + fill_ieee80211_hdr_data(txrx_pdev, + &pl_msdu_info, fw_data->data); + + pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, + ((void *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + sizeof(pl_msdu_info.priv.msdu_id_info)); + qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, + sizeof(pl_msdu_info.priv)); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + pl_msdu_info.ath_msdu_info); + } + + return A_OK; +} +#endif /* HELIUMPLUS */ + +A_STATUS process_rx_info_remote(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_info *pl_info; + struct htt_host_rx_desc_base *rx_desc; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_rx_info rxstat_log; + size_t log_size; + struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data; + qdf_nbuf_t msdu; + + if (!pdev || !r_data || !pl_dev) { + qdf_print("%s: Invalid handle", __func__); + return A_ERROR; + } + + pl_info = pl_dev->pl_info; + msdu = r_data->msdu; + + while (msdu) { + rx_desc = + (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1; + log_size = + sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base); + + /* + * Construct the pktlog header pl_hdr + * Because desc is DMA'd to the host memory + */ + pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + pl_hdr.missed_cnt = 0; +#if defined(HELIUMPLUS) + pl_hdr.macId = r_data->mac_id; + pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; +#else + pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; +#endif + pl_hdr.size = sizeof(*rx_desc) - + sizeof(struct htt_host_fw_desc_base); +#if defined(HELIUMPLUS) + pl_hdr.timestamp = + rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32; + pl_hdr.type_specific_data = 0xDEADAA; +#else + pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp; +#endif /* !defined(HELIUMPLUS) */ + + pktlog_hdr_set_specific_data(&pl_hdr, 0xDEADAA); + + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc + + sizeof(struct htt_host_fw_desc_base), pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + rxstat_log.rx_desc); + msdu = qdf_nbuf_next(msdu); + } + return A_OK; +} + +#ifdef HELIUMPLUS +A_STATUS process_rx_info(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rx_info rxstat_log; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!pdev) { + qdf_nofl_info("Invalid pdev in %s", __func__); + return A_ERROR; + } + + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + if (!pl_dev) { + qdf_nofl_info("Invalid pl_dev in %s", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_info = pl_dev->pl_info; + pl_tgt_hdr = (uint32_t *)fw_data->data; + + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy(rxstat_log.rx_desc, + (void *)fw_data->data + sizeof(struct ath_pktlog_hdr), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); + + return A_OK; +} +#else +A_STATUS process_rx_info(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rx_info rxstat_log; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!pdev) { + qdf_nofl_info("Invalid pdev in %s", __func__); + return A_ERROR; + } + + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + if (!pl_dev) { + qdf_nofl_info("Invalid pl_dev in %s", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_info = pl_dev->pl_info; + pl_tgt_hdr = (uint32_t *)fw_data->data; + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy(rxstat_log.rx_desc, + (void *)fw_data->data + sizeof(struct ath_pktlog_hdr), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); + + return A_OK; +} +#endif /* HELIUMPLUS */ + +#ifdef HELIUMPLUS +A_STATUS process_rate_find(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + uint32_t len; + struct ol_fw_data *fw_data; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_rc_find rcf_log; + uint32_t *pl_tgt_hdr; + + if (!pdev || !data || !pl_dev) { + qdf_print("%s: Invalid handle", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(rcf_log.rcFind, + ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind); + + return A_OK; +} + +#else +A_STATUS process_rate_find(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + uint32_t len; + struct ol_fw_data *fw_data; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_rc_find rcf_log; + uint32_t *pl_tgt_hdr; + + if (!pdev || !data || !pl_dev) { + qdf_print("%s: Invalid handle", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(rcf_log.rcFind, + ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind); + + return A_OK; +} +#endif + +#ifdef HELIUMPLUS +A_STATUS process_rate_update(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rc_update rcu_log; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!pdev || !data || !pl_dev) { + qdf_print("%s: Invalid handle", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + log_size = pl_hdr.size; + pl_info = pl_dev->pl_info; + + /* + * Will be uncommented when the rate control update + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(rcu_log.txRateCtrl, + ((char *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl); + return A_OK; +} +#else +A_STATUS process_rate_update(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rc_update rcu_log; + uint32_t *pl_tgt_hdr; + struct ol_fw_data *fw_data; + uint32_t len; + + if (!pdev || !data || !pl_dev) { + qdf_print("%s: Invalid handle", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + log_size = pl_hdr.size; + pl_info = pl_dev->pl_info; + + /* + * Will be uncommented when the rate control update + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(rcu_log.txRateCtrl, + ((char *)fw_data->data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl); + return A_OK; +} +#endif /* HELIUMPLUS */ + +#ifdef HELIUMPLUS +A_STATUS process_sw_event(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + uint32_t len; + struct ol_fw_data *fw_data; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_sw_event sw_event; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + qdf_print("Invalid pdev in %s", __func__); + return A_ERROR; + } + if (!data) { + qdf_print("Invalid data in %s", __func__); + return A_ERROR; + } + if (!pl_dev) { + qdf_print("Invalid pl_dev in %s", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MAC_ID_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pl_hdr.type_specific_data = + *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(sw_event.sw_event, + ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event); + + return A_OK; +} +#else +A_STATUS process_sw_event(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + uint32_t len; + struct ol_fw_data *fw_data; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_sw_event sw_event; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + qdf_print("Invalid pdev in %s", __func__); + return A_ERROR; + } + if (!data) { + qdf_print("Invalid data in %s", __func__); + return A_ERROR; + } + if (!pl_dev) { + qdf_print("Invalid pl_dev in %s", __func__); + return A_ERROR; + } + + fw_data = (struct ol_fw_data *)data; + len = fw_data->len; + if (len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) || + len < (sizeof(uint32_t) * + (ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET + 1))) { + qdf_print("Invalid msdu len in %s", __func__); + qdf_assert(0); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)fw_data->data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pktlog_hdr_set_specific_data(&pl_hdr, + *(pl_tgt_hdr + + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET)); + + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) { + qdf_assert(0); + return A_ERROR; + } + qdf_mem_copy(sw_event.sw_event, + ((char *)fw_data->data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, sw_event.sw_event); + + return A_OK; +} +#endif /* HELIUMPLUS */ +#endif /* REMOVE_PKT_LOG */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi3.c b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi3.c new file mode 100644 index 0000000000000000000000000000000000000000..c74c7374aa6b85c9044cdd652c4b7535d7fd54be --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/pktlog/pktlog_wifi3.c @@ -0,0 +1,163 @@ +/** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/* WIFI3 - Refers to platforms - 6290/6390/6490 */ +#include "pktlog_wifi3.h" + +#ifndef REMOVE_PKT_LOG +A_STATUS +process_offload_pktlog_wifi3(struct cdp_pdev *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_info *pl_info; + struct ath_pktlog_hdr pl_hdr; + uint32_t *pl_tgt_hdr; + void *txdesc_hdr_ctl = NULL; + size_t log_size = 0; + + if (!pl_dev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid context in %s\n", __func__); + return A_ERROR; + } + + if (!data) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid data in %s\n", __func__); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)data; + + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pl_hdr.type_specific_data = *(pl_tgt_hdr + + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); + + if (pl_hdr.size > MAX_PKTLOG_RECV_BUF_SIZE) { + pl_dev->invalid_packets++; + return A_ERROR; + } + + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + txdesc_hdr_ctl = + (void *)pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); + if (!txdesc_hdr_ctl) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Failed to allocate pktlog descriptor"); + return A_NO_MEMORY; + } + qdf_assert(txdesc_hdr_ctl); + qdf_assert(pl_hdr->size < PKTLOG_MAX_TX_WORDS * sizeof(u_int32_t)); + qdf_mem_copy(txdesc_hdr_ctl, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, txdesc_hdr_ctl); + + return A_OK; +} + +int process_rx_desc_remote_wifi3(void *pdev, void *data) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_rx_info rxstat_log; + size_t log_size; + struct ath_pktlog_info *pl_info; + qdf_nbuf_t log_nbuf = (qdf_nbuf_t)data; + + if (!pl_dev) { + qdf_err("Pktlog handle is NULL"); + return -EINVAL; + } + + pl_info = pl_dev->pl_info; + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + pl_hdr.missed_cnt = 0; + pl_hdr.log_type = PKTLOG_TYPE_RX_STATBUF; + pl_hdr.size = qdf_nbuf_len(log_nbuf); + pl_hdr.timestamp = 0; + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + if (!rxstat_log.rx_desc) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, + "%s: Rx descriptor is NULL", __func__); + return -EINVAL; + } + + qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + rxstat_log.rx_desc); + return 0; +} + +int +process_pktlog_lite_wifi3(void *context, void *log_data, + uint16_t log_type) +{ + struct pktlog_dev_t *pl_dev = get_pktlog_handle(); + struct ath_pktlog_info *pl_info; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_rx_info rxstat_log; + size_t log_size; + qdf_nbuf_t log_nbuf = (qdf_nbuf_t)log_data; + + if (!pl_dev) { + qdf_err("Pktlog handle is NULL"); + return -EINVAL; + } + + pl_info = pl_dev->pl_info; + qdf_mem_zero(&pl_hdr, sizeof(pl_hdr)); + pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + pl_hdr.missed_cnt = 0; + pl_hdr.log_type = log_type; + pl_hdr.size = qdf_nbuf_len(log_nbuf); + pl_hdr.timestamp = 0; + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + if (!rxstat_log.rx_desc) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, + "%s: Rx descriptor is NULL", __func__); + return -EINVAL; + } + + qdf_mem_copy(rxstat_log.rx_desc, qdf_nbuf_data(log_nbuf), pl_hdr.size); + + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); + return 0; +} +#endif /* REMOVE_PKT_LOG */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_api.h b/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_api.h new file mode 100644 index 0000000000000000000000000000000000000000..9afdf28ebe274887c0c2625bfb5f92619ca7a3c4 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_api.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: qld_api.h + * QLD: This file provides public exposed functions + */ + +#ifndef _QLD_API_H_ +#define _QLD_API_H_ + +#define QLD_MAX_NAME 48 + +/** + * struct qld_entry - Individual entry in qld_event + * @addr: Start address of object to dump + * @size: Size of memory dump + * @name: Name of memory dump + */ +struct qld_entry { + uint64_t addr; + size_t size; + char name[QLD_MAX_NAME]; +}; + +/** + * typedef qld_iter_func - qld callback function + * @req: opaque pointer + * @qld_entry: qld_entry + * + * Return: 0 - OK -EINVAL - On failure + */ +typedef int (*qld_iter_func)(void *req, struct qld_entry *entry); + +/** + * qld_iterate_list() - qld list iteration routine + * @gen_table: callback function to genrate table + * @req: opaque request + * + * Return: 0 - OK -EINVAL - On failure + */ +int qld_iterate_list(qld_iter_func gen_table, void *req); + +/** + * qld_register() - Register qld for the given address + * @addr: starting address the dump + * @size: size of memory to dump + * @name: name identifier of dump + * + * Return: 0 - OK -EINVAL -ENOMEM - On failure + */ +int qld_register(void *addr, size_t size, char *name); + +/** + * qld_unregister() - Un-register qld for the given address + * @addr: starting address the dump + * + * Return: 0 - OK -EINVAL - On failure + */ +int qld_unregister(void *addr); + +/** + * qld_list_init() - Initialize qld list + * @max_list: maximum size list supports + * + * Return: 0 - OK -EINVAL -ENOMEM - On failure + */ +int qld_list_init(uint32_t max_list); + +/** + * qld_list_delete() - empty qld list + * + * Return: 0 - OK -EINVAL - On failure + */ +int qld_list_delete(void); + +/** + * qld_list_deinit() - De-initialize qld list + * + * Return: 0 - OK -EINVAL - On failure + */ +int qld_list_deinit(void); + +/** + * qld_get_list_count () - get size of qld list + * @list_count: list_count to set + * + * Return: 0 - OK -EINVAL - On failure + */ +int qld_get_list_count(uint32_t *list_count); + +/** + * is_qld_enable() - check if qld feature is set + * + * Return: true on success, false on failure + */ +bool is_qld_enable(void); + +#endif /* _QLD_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_priv.h b/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_priv.h new file mode 100644 index 0000000000000000000000000000000000000000..ebf7b56931a8157f1b268e0928998ff1c8204107 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/qld/inc/qld_priv.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: qld_priv.h + * QLD: This file provies Private functions for qld + */ + +#ifndef _QLD_PRIV_H_ +#define _QLD_PRIV_H_ + +#include +#include +#include + +#define qld_alert(format, args...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_QLD, format, ## args) + +#define qld_err(format, args...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_QLD, format, ## args) + +#define qld_warn(format, args...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_QLD, format, ## args) + +#define qld_info(format, args...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_QLD, format, ## args) + +#define qld_debug(format, args...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_QLD, format, ## args) + +/** + * struct qld_list_handle - Top level qld structure + * @qld_lock: Spinlock for structure + * @qld_list: linked list for linking + * @qld_max_list: maximum list size + */ +struct qld_list_handle { + qdf_spinlock_t qld_lock; + qdf_list_t qld_list; + uint32_t qld_max_list; +}; + +/** + * struct qld_node - qld node + * @node: single node of linked list + * @entry: single qld_entry in list + */ +struct qld_node { + qdf_list_node_t node; + struct qld_entry entry; +}; + +#endif /*_QLD_PRIV_H_*/ diff --git a/drivers/staging/qca-wifi-host-cmn/utils/qld/src/qld.c b/drivers/staging/qca-wifi-host-cmn/utils/qld/src/qld.c new file mode 100644 index 0000000000000000000000000000000000000000..d377d59a89dc00d2de518a58870efed46cb03e2a --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/utils/qld/src/qld.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: qld + * QLD: main file of QCA Live Dump (QLD) + */ + +#include "qld_priv.h" +#include "qld_api.h" +#include "qdf_module.h" + +/* Handle for qld structure */ +static struct qld_list_handle *qld_handle; + +bool is_qld_enable(void) +{ + if (!qld_handle) + return false; + + return true; +} + +qdf_export_symbol(is_qld_enable); + +int qld_list_init(uint32_t max_list) +{ + if (!max_list) + return -EINVAL; + + qld_handle = qdf_mem_malloc(sizeof(*qld_handle)); + + if (!qld_handle) + return -ENOMEM; + + qdf_spinlock_create(&qld_handle->qld_lock); + qld_handle->qld_max_list = max_list; + qdf_list_create(&qld_handle->qld_list, qld_handle->qld_max_list); + qld_debug("LIST init with max size of %u", qld_handle->qld_max_list); + return 0; +} + +qdf_export_symbol(qld_list_init); + +int qld_list_deinit(void) +{ + if (!qld_handle) { + qld_err("Handle NULL"); + return -EINVAL; + } + /* Delete the list */ + qld_list_delete(); + qdf_list_destroy(&qld_handle->qld_list); + qdf_spinlock_destroy(&qld_handle->qld_lock); + qdf_mem_free(qld_handle); + qld_handle = NULL; + qld_debug("LIST De-initialized"); + return 0; +} + +qdf_export_symbol(qld_list_deinit); + +int qld_list_delete(void) +{ + struct qld_node *qld; + qdf_list_node_t *node = NULL; + qdf_list_t *list; + + if (!qld_handle) { + qld_err("Handle NULL"); + return -EINVAL; + } + list = &qld_handle->qld_list; + qdf_spinlock_acquire(&qld_handle->qld_lock); + /* Check and remove the elements of list */ + while (qdf_list_remove_front(list, &node) == QDF_STATUS_SUCCESS) { + qld = qdf_container_of(node, struct qld_node, node); + qdf_mem_free(qld); + } + qdf_spinlock_release(&qld_handle->qld_lock); + qld_debug("LIST Emptied"); + return 0; +} + +qdf_export_symbol(qld_list_delete); + +int qld_register(void *addr, size_t size, char *name) +{ + struct qld_node *qld; + uint32_t list_count = 0; + + if (!qld_handle || !addr) { + qld_err("Handle or address is NULL"); + return -EINVAL; + } + + if ((qld_get_list_count(&list_count) != 0)) { + qdf_err("QLD: Invalid list count"); + return -EINVAL; + } + if (list_count >= qld_handle->qld_max_list) { + qld_err("List full,reg failed.Increase list size"); + return -EINVAL; + } + /* Check if data is already registered */ + qdf_spinlock_acquire(&qld_handle->qld_lock); + qdf_list_for_each(&qld_handle->qld_list, qld, node) { + if (qld->entry.addr == (uintptr_t)addr) { + qld_err("%s already registered", qld->entry.name); + qdf_spinlock_release(&qld_handle->qld_lock); + return -EINVAL; + } + } + qdf_spinlock_release(&qld_handle->qld_lock); + qld = qdf_mem_malloc(sizeof(*qld)); + if (!qld) + return -ENOMEM; + + qld_debug("Insert addr=%pK size=%zu name=%s", (void *)addr, size, name); + qdf_spinlock_acquire(&qld_handle->qld_lock); + qld->entry.addr = (uintptr_t)addr; + qld->entry.size = size; + qdf_snprintf(qld->entry.name, sizeof(qld->entry.name), "%s", name); + qdf_list_insert_front(&qld_handle->qld_list, &qld->node); + qdf_spinlock_release(&qld_handle->qld_lock); + return 0; +} + +qdf_export_symbol(qld_register); + +int qld_unregister(void *addr) +{ + struct qld_node *qld = NULL; + + if (!qld_handle || !addr) { + qld_err("Handle or address is NULL"); + return -EINVAL; + } + + qdf_spinlock_acquire(&qld_handle->qld_lock); + qdf_list_for_each(&qld_handle->qld_list, qld, node) { + if (qld->entry.addr == (uintptr_t)addr) + break; + } + qdf_list_remove_node(&qld_handle->qld_list, &qld->node); + qld_debug("Delete name=%s, size=%zu", qld->entry.name, qld->entry.size); + qdf_mem_free(qld); + qdf_spinlock_release(&qld_handle->qld_lock); + return 0; +} + +qdf_export_symbol(qld_unregister); + +int qld_iterate_list(qld_iter_func gen_table, void *qld_req) +{ + struct qld_node *qld = NULL; + + if (!qld_handle) + return -EINVAL; + + if (!qld_req || !gen_table) { + qld_err("req buffer or func is NULL %s", __func__); + return -EINVAL; + } + qdf_spinlock_acquire(&qld_handle->qld_lock); + qdf_list_for_each(&qld_handle->qld_list, qld, node) { + (gen_table)(qld_req, &qld->entry); + } + qdf_spinlock_release(&qld_handle->qld_lock); + return 0; +} + +qdf_export_symbol(qld_iterate_list); + +int qld_get_list_count(uint32_t *list_count) +{ + if (!qld_handle) { + qld_err("Handle NULL"); + return -EINVAL; + } + *list_count = qld_handle->qld_list.count; + return 0; +} + +qdf_export_symbol(qld_get_list_count); diff --git a/drivers/staging/qcacld-3.0/core/cds/src/queue.h b/drivers/staging/qca-wifi-host-cmn/utils/sys/queue.h similarity index 80% rename from drivers/staging/qcacld-3.0/core/cds/src/queue.h rename to drivers/staging/qca-wifi-host-cmn/utils/sys/queue.h index 73200429eaf77516184b1179a3533efede432dca..23b184385378d8be99dcf8a5291cec870fef10fd 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/queue.h +++ b/drivers/staging/qca-wifi-host-cmn/utils/sys/queue.h @@ -1,38 +1,37 @@ /* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $ - */ - -#if !defined(__NetBSD__) -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ +* Copyright (c) 1991, 1993 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* @(#)queue.h 8.5 (Berkeley) 8/20/94 +* $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $ +*/ + +#ifndef _QUEUE_H_ +#define _QUEUE_H_ /* * This file defines four types of data structures: singly-linked lists, @@ -101,7 +100,9 @@ */ #define QUEUE_MACRO_DEBUG 0 #if QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ +/* + * Store the last 2 places the queue element or head was altered + */ struct qm_trace { char *lastfile; int lastline; @@ -134,7 +135,9 @@ struct qm_trace { #endif /* QUEUE_MACRO_DEBUG */ #ifdef ATHR_RNWF -/* NDIS contains a defn for SLIST_ENTRY and SINGLE_LIST_ENTRY */ +/* + * NDIS contains a defn for SLIST_ENTRY and SINGLE_LIST_ENTRY + */ #endif /* @@ -200,12 +203,13 @@ struct qm_trace { while (SLIST_NEXT(curelm, field) != (elm)) \ curelm = SLIST_NEXT(curelm, field); \ SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field);\ } \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), \ + field); \ } while (0) /* @@ -213,8 +217,8 @@ struct qm_trace { */ #define STAILQ_HEAD(name, type) \ struct name { \ - struct type *stqh_first; /* first element */ \ - struct type **stqh_last; /* addr of last next element */ \ + struct type *stqh_first; \ + struct type **stqh_last; \ } #define STAILQ_HEAD_INITIALIZER(head) \ @@ -241,7 +245,7 @@ struct qm_trace { #define STAILQ_FIRST(head) ((head)->stqh_first) #define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ + for ((var) = STAILQ_FIRST((head)); \ (var); \ (var) = STAILQ_NEXT((var), field)) @@ -256,13 +260,15 @@ struct qm_trace { } while (0) #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), \ + field)) == NULL) \ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ STAILQ_NEXT((tqelm), field) = (elm); \ } while (0) #define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == \ + NULL) \ (head)->stqh_last = &STAILQ_NEXT((elm), field); \ STAILQ_FIRST((head)) = (elm); \ } while (0) @@ -290,27 +296,33 @@ struct qm_trace { while (STAILQ_NEXT(curelm, field) != (elm)) \ curelm = STAILQ_NEXT(curelm, field); \ if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((curelm), field); \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), \ + field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((curelm),\ + field); \ } \ } while (0) #define STAILQ_REMOVE_AFTER(head, elm, field) do { \ if (STAILQ_NEXT(elm, field)) { \ if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), \ + field)) == NULL) \ + (head)->stqh_last = \ + &STAILQ_NEXT((elm), field); \ } \ } while (0) #define STAILQ_REMOVE_HEAD(head, field) do { \ if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == \ + NULL)\ (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT((elm), field)) == NULL) \ (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) @@ -319,7 +331,7 @@ struct qm_trace { */ #define ATH_LIST_HEAD(name, type) \ struct name { \ - struct type *lh_first; /* first element */ \ + struct type *lh_first; \ } #ifndef LIST_HEAD @@ -331,8 +343,8 @@ struct qm_trace { #define LIST_ENTRY(type) \ struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ + struct type *le_next; \ + struct type **le_prev; \ } /* @@ -358,7 +370,8 @@ struct qm_trace { } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \ + if ((LIST_NEXT((elm), field) = \ + LIST_NEXT((listelm), field)) != NULL) \ LIST_NEXT((listelm), field)->field.le_prev = \ &LIST_NEXT((elm), field); \ LIST_NEXT((listelm), field) = (elm); \ @@ -374,7 +387,8 @@ struct qm_trace { #define LIST_INSERT_HEAD(head, elm, field) do { \ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \ + LIST_FIRST((head))->field.le_prev = \ + &LIST_NEXT((elm), field); \ LIST_FIRST((head)) = (elm); \ (elm)->field.le_prev = &LIST_FIRST((head)); \ } while (0) @@ -391,14 +405,23 @@ struct qm_trace { /* * Tail queue declarations. */ +#ifndef TRACE_TX_LEAK +#define TRACE_TX_LEAK 0 +#endif + +#if TRACE_TX_LEAK +#define HEADNAME char headname[64]; +#define COPY_HEADNAME(head) OS_MEMCPY((head)->headname, #head, sizeof(#head)) +#else #define HEADNAME #define COPY_HEADNAME(head) +#endif #define TAILQ_HEAD(name, type) \ struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - HEADNAME \ + struct type *tqh_first; \ + struct type **tqh_last; \ + HEADNAME \ TRACEBUF \ } @@ -407,8 +430,8 @@ struct qm_trace { #define TAILQ_ENTRY(type) \ struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ + struct type *tqe_next; \ + struct type **tqe_prev; \ TRACEBUF \ } @@ -448,7 +471,8 @@ struct qm_trace { } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), \ + field)) != NULL) \ TAILQ_NEXT((elm), field)->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ else { \ @@ -471,7 +495,7 @@ struct qm_trace { } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)\ TAILQ_FIRST((head))->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ else \ @@ -514,12 +538,12 @@ struct qm_trace { } while (0) #define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - } \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;\ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + } \ } while (0) #ifdef _KERNEL @@ -536,7 +560,7 @@ struct quehead { #if defined(__GNUC__) || defined(__INTEL_COMPILER) -static __inline void insque(void *a, void *b) +static inline void insque(void *a, void *b) { struct quehead *element = (struct quehead *)a, *head = (struct quehead *)b; @@ -547,7 +571,7 @@ static __inline void insque(void *a, void *b) element->qh_link->qh_rlink = element; } -static __inline void remque(void *a) +static inline void remque(void *a) { struct quehead *element = (struct quehead *)a; @@ -565,7 +589,4 @@ void remque(void *a); #endif /* _KERNEL */ -#endif /* !_SYS_QUEUE_H_ */ -#else /* !__NetBSD__ */ -#include_next -#endif /* __NetBSD__ */ +#endif /* _QUEUE_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/cfg_dp.h b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/cfg_dp.h index fa439f6d8c7e22033aea146d836a09c3e428db7c..f9f61732bc988cb84df14d0046bf490f6865b8a7 100644 --- a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/cfg_dp.h +++ b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/cfg_dp.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,30 +39,37 @@ #define WLAN_CFG_NUM_TCL_DATA_RINGS_MIN 3 #define WLAN_CFG_NUM_TCL_DATA_RINGS_MAX 3 -#ifdef CONFIG_MCL -#ifdef QCA_LL_TX_FLOW_CONTROL_V2 +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \ + defined(QCA_LL_PDEV_TX_FLOW_CONTROL) #define WLAN_CFG_TX_FLOW_START_QUEUE_OFFSET 10 #define WLAN_CFG_TX_FLOW_STOP_QUEUE_TH 15 #else #define WLAN_CFG_TX_FLOW_START_QUEUE_OFFSET 0 #define WLAN_CFG_TX_FLOW_STOP_QUEUE_TH 0 #endif -#else -#define WLAN_CFG_TX_FLOW_START_QUEUE_OFFSET 0 -#define WLAN_CFG_TX_FLOW_STOP_QUEUE_TH 0 -#endif #define WLAN_CFG_PER_PDEV_TX_RING_MIN 0 #define WLAN_CFG_PER_PDEV_TX_RING_MAX 1 -#ifdef CONFIG_MCL +#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) #define WLAN_CFG_PER_PDEV_RX_RING 0 #define WLAN_CFG_PER_PDEV_LMAC_RING 0 #define WLAN_LRO_ENABLE 0 #define WLAN_CFG_MAC_PER_TARGET 2 #ifdef IPA_OFFLOAD +/* Using TCL data ring 2 for IPA Tx And + * WBM2SW ring 2 for Tx completion + */ +#define WLAN_CFG_IPA_TX_N_TXCMPL_RING 2 /* Size of TCL TX Ring */ +#if defined(TX_TO_NPEERS_INC_TX_DESCS) +#define WLAN_CFG_TX_RING_SIZE 2048 +#else #define WLAN_CFG_TX_RING_SIZE 1024 +#endif +#define WLAN_CFG_IPA_TX_RING_SIZE 1024 +#define WLAN_CFG_IPA_TX_COMP_RING_SIZE 1024 + #define WLAN_CFG_PER_PDEV_TX_RING 0 #define WLAN_CFG_IPA_UC_TX_BUF_SIZE 2048 #define WLAN_CFG_IPA_UC_TX_PARTITION_BASE 3000 @@ -73,11 +81,20 @@ #define WLAN_CFG_IPA_UC_TX_PARTITION_BASE 0 #define WLAN_CFG_IPA_UC_RX_IND_RING_COUNT 0 #endif + +#if defined(TX_TO_NPEERS_INC_TX_DESCS) +#define WLAN_CFG_TX_COMP_RING_SIZE 4096 + +/* Tx Descriptor and Tx Extension Descriptor pool sizes */ +#define WLAN_CFG_NUM_TX_DESC 4096 +#define WLAN_CFG_NUM_TX_EXT_DESC 4096 +#else #define WLAN_CFG_TX_COMP_RING_SIZE 1024 /* Tx Descriptor and Tx Extension Descriptor pool sizes */ #define WLAN_CFG_NUM_TX_DESC 1024 #define WLAN_CFG_NUM_TX_EXT_DESC 1024 +#endif /* Interrupt Mitigation - Batch threshold in terms of number of frames */ #define WLAN_CFG_INT_BATCH_THRESHOLD_TX 1 @@ -88,48 +105,15 @@ #define WLAN_CFG_INT_TIMER_THRESHOLD_TX 8 #define WLAN_CFG_INT_TIMER_THRESHOLD_RX 8 #define WLAN_CFG_INT_TIMER_THRESHOLD_OTHER 8 -#else -#define WLAN_CFG_PER_PDEV_TX_RING 0 -#define WLAN_CFG_IPA_UC_TX_BUF_SIZE 0 -#define WLAN_CFG_IPA_UC_TX_PARTITION_BASE 0 -#define WLAN_CFG_IPA_UC_RX_IND_RING_COUNT 0 #endif -#ifdef CONFIG_WIN -#define WLAN_CFG_PER_PDEV_RX_RING 0 -#define WLAN_CFG_PER_PDEV_LMAC_RING 1 -#define WLAN_LRO_ENABLE 0 -#define WLAN_CFG_MAC_PER_TARGET 3 -/* Tx Descriptor and Tx Extension Descriptor pool sizes */ -#ifndef QCA_WIFI_QCA8074_VP -#define WLAN_CFG_NUM_TX_DESC 0x320000 -#else -#define WLAN_CFG_NUM_TX_DESC (8 << 10) -#endif -#define WLAN_CFG_NUM_TX_EXT_DESC 0x80000 - -/* Interrupt Mitigation - Batch threshold in terms of number of frames */ -#define WLAN_CFG_INT_BATCH_THRESHOLD_TX 256 -#define WLAN_CFG_INT_BATCH_THRESHOLD_RX 128 -#define WLAN_CFG_INT_BATCH_THRESHOLD_OTHER 1 - -/* Interrupt Mitigation - Timer threshold in us */ -#define WLAN_CFG_INT_TIMER_THRESHOLD_TX 1000 -#define WLAN_CFG_INT_TIMER_THRESHOLD_RX 500 -#define WLAN_CFG_INT_TIMER_THRESHOLD_OTHER 1000 - -#define WLAN_CFG_TX_RING_SIZE 512 +#define WLAN_CFG_RX_PENDING_HL_THRESHOLD 0x60000 +#define WLAN_CFG_RX_PENDING_HL_THRESHOLD_MIN 0 +#define WLAN_CFG_RX_PENDING_HL_THRESHOLD_MAX 0x80000 -/* Size the completion ring using following 2 parameters - * - NAPI schedule latency (assuming 1 netdev competing for CPU) - * = 20 ms (2 jiffies) - * - Worst case PPS requirement = 400K PPS - * - * Ring size = 20 * 400 = 8000 - * 8192 is nearest power of 2 - */ -#define WLAN_CFG_TX_COMP_RING_SIZE 0x80000 -#endif +#define WLAN_CFG_RX_PENDING_LO_THRESHOLD 0x60000 +#define WLAN_CFG_RX_PENDING_LO_THRESHOLD_MIN 100 +#define WLAN_CFG_RX_PENDING_LO_THRESHOLD_MAX 0x80000 #define WLAN_CFG_INT_TIMER_THRESHOLD_WBM_RELEASE_RING 256 #define WLAN_CFG_INT_TIMER_THRESHOLD_REO_RING 512 @@ -141,7 +125,7 @@ #define WLAN_CFG_PER_PDEV_LMAC_RING_MAX 1 #define WLAN_CFG_TX_RING_SIZE_MIN 512 -#define WLAN_CFG_TX_RING_SIZE_MAX 2048 +#define WLAN_CFG_TX_RING_SIZE_MAX 0x80000 #define WLAN_CFG_TX_COMP_RING_SIZE_MIN 512 #define WLAN_CFG_TX_COMP_RING_SIZE_MAX 0x80000 @@ -250,13 +234,14 @@ #define WLAN_CFG_REO_DST_RING_SIZE_MIN 1024 #define WLAN_CFG_REO_DST_RING_SIZE_MAX 2048 -#define WLAN_CFG_REO_REINJECT_RING_SIZE 32 +#define WLAN_CFG_REO_REINJECT_RING_SIZE 128 #define WLAN_CFG_REO_REINJECT_RING_SIZE_MIN 32 -#define WLAN_CFG_REO_REINJECT_RING_SIZE_MAX 32 +#define WLAN_CFG_REO_REINJECT_RING_SIZE_MAX 128 #define WLAN_CFG_RX_RELEASE_RING_SIZE 1024 #define WLAN_CFG_RX_RELEASE_RING_SIZE_MIN 8 -#if defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750) #define WLAN_CFG_RX_RELEASE_RING_SIZE_MAX 1024 #else #define WLAN_CFG_RX_RELEASE_RING_SIZE_MAX 8192 @@ -270,7 +255,7 @@ #define WLAN_CFG_REO_CMD_RING_SIZE_MIN 64 #define WLAN_CFG_REO_CMD_RING_SIZE_MAX 128 -#define WLAN_CFG_REO_STATUS_RING_SIZE 256 +#define WLAN_CFG_REO_STATUS_RING_SIZE 128 #define WLAN_CFG_REO_STATUS_RING_SIZE_MIN 128 #define WLAN_CFG_REO_STATUS_RING_SIZE_MAX 2048 @@ -282,6 +267,26 @@ #define WLAN_CFG_RXDMA_REFILL_RING_SIZE_MIN 16 #define WLAN_CFG_RXDMA_REFILL_RING_SIZE_MAX 4096 +#define WLAN_CFG_TX_DESC_LIMIT_0 0 +#define WLAN_CFG_TX_DESC_LIMIT_0_MIN 4096 +#define WLAN_CFG_TX_DESC_LIMIT_0_MAX 32768 + +#define WLAN_CFG_TX_DESC_LIMIT_1 0 +#define WLAN_CFG_TX_DESC_LIMIT_1_MIN 4096 +#define WLAN_CFG_TX_DESC_LIMIT_1_MAX 32768 + +#define WLAN_CFG_TX_DESC_LIMIT_2 0 +#define WLAN_CFG_TX_DESC_LIMIT_2_MIN 4096 +#define WLAN_CFG_TX_DESC_LIMIT_2_MAX 32768 + +#define WLAN_CFG_TX_DEVICE_LIMIT 65536 +#define WLAN_CFG_TX_DEVICE_LIMIT_MIN 16384 +#define WLAN_CFG_TX_DEVICE_LIMIT_MAX 65536 + +#define WLAN_CFG_TX_SW_INTERNODE_QUEUE 1024 +#define WLAN_CFG_TX_SW_INTERNODE_QUEUE_MIN 128 +#define WLAN_CFG_TX_SW_INTERNODE_QUEUE_MAX 1024 + #define WLAN_CFG_RXDMA_MONITOR_BUF_RING_SIZE 4096 #define WLAN_CFG_RXDMA_MONITOR_BUF_RING_SIZE_MIN 16 #define WLAN_CFG_RXDMA_MONITOR_BUF_RING_SIZE_MAX 8192 @@ -302,6 +307,44 @@ #define WLAN_CFG_RXDMA_ERR_DST_RING_SIZE_MIN 1024 #define WLAN_CFG_RXDMA_ERR_DST_RING_SIZE_MAX 8192 +#define WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE 32 +#define WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE_MIN 0 +#define WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE_MAX 256 + +/** + * Allocate as many RX descriptors as buffers in the SW2RXDMA + * ring. This value may need to be tuned later. + */ +#if defined(QCA_HOST2FW_RXBUF_RING) +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE 1 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MIN 1 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MAX 1 + +/** + * For low memory AP cases using 1 will reduce the rx descriptors memory req + */ +#elif defined(QCA_LOWMEM_CONFIG) || defined(QCA_512M_CONFIG) +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE 1 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MIN 1 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MAX 3 + +/** + * AP use cases need to allocate more RX Descriptors than the number of + * entries avaialable in the SW2RXDMA buffer replenish ring. This is to account + * for frames sitting in REO queues, HW-HW DMA rings etc. Hence using a + * multiplication factor of 3, to allocate three times as many RX descriptors + * as RX buffers. + */ +#else +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE 3 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MIN 1 +#define WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MAX 3 +#endif //QCA_HOST2FW_RXBUF_RING + +#define WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE 16384 +#define WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE_MIN 1 +#define WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE_MAX 16384 + #define WLAN_CFG_PKTLOG_BUFFER_SIZE 10 #define WLAN_CFG_PKTLOG_MIN_BUFFER_SIZE 1 #define WLAN_CFG_PKTLOG_MAX_BUFFER_SIZE 10 @@ -475,6 +518,49 @@ WLAN_CFG_PER_PDEV_LMAC_RING_MAX, \ WLAN_CFG_PER_PDEV_LMAC_RING, \ CFG_VALUE_OR_DEFAULT, "DP pdev LMAC ring") +/* + * + * dp_rx_pending_hl_threshold - High threshold of frame number to start + * frame dropping scheme + * @Min: 0 + * @Max: 524288 + * @Default: 393216 + * + * This ini entry is used to set a high limit threshold to start frame + * dropping scheme + * + * Usage: External + * + * + */ +#define CFG_DP_RX_PENDING_HL_THRESHOLD \ + CFG_INI_UINT("dp_rx_pending_hl_threshold", \ + WLAN_CFG_RX_PENDING_HL_THRESHOLD_MIN, \ + WLAN_CFG_RX_PENDING_HL_THRESHOLD_MAX, \ + WLAN_CFG_RX_PENDING_HL_THRESHOLD, \ + CFG_VALUE_OR_DEFAULT, "DP rx pending hl threshold") + +/* + * + * dp_rx_pending_lo_threshold - Low threshold of frame number to stop + * frame dropping scheme + * @Min: 100 + * @Max: 524288 + * @Default: 393216 + * + * This ini entry is used to set a low limit threshold to stop frame + * dropping scheme + * + * Usage: External + * + * + */ +#define CFG_DP_RX_PENDING_LO_THRESHOLD \ + CFG_INI_UINT("dp_rx_pending_lo_threshold", \ + WLAN_CFG_RX_PENDING_LO_THRESHOLD_MIN, \ + WLAN_CFG_RX_PENDING_LO_THRESHOLD_MAX, \ + WLAN_CFG_RX_PENDING_LO_THRESHOLD, \ + CFG_VALUE_OR_DEFAULT, "DP rx pending lo threshold") #define CFG_DP_BASE_HW_MAC_ID \ CFG_INI_UINT("dp_base_hw_macid", \ @@ -493,13 +579,66 @@ CFG_INI_BOOL("LROEnable", WLAN_LRO_ENABLE, \ "DP LRO Enable") +/* + * + * CFG_DP_SG - Enable the SG feature standalonely + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini entry is used to enable/disable SG feature standalonely. + * Also does Rome support SG on TX, lithium does not. + * For example the lithium does not support SG on UDP frames. + * Which is able to handle SG only for TSO frames(in case TSO is enabled). + * + * Usage: External + * + * + */ #define CFG_DP_SG \ CFG_INI_BOOL("dp_sg_support", false, \ "DP SG Enable") +#define WLAN_CFG_GRO_ENABLE_MIN 0 +#define WLAN_CFG_GRO_ENABLE_MAX 3 +#define WLAN_CFG_GRO_ENABLE_DEFAULT 0 +#define DP_GRO_ENABLE_BIT_SET BIT(0) +#define DP_TC_BASED_DYNAMIC_GRO BIT(1) + +/* + * + * CFG_DP_GRO - Enable the GRO feature standalonely + * @Min: 0 + * @Max: 3 + * @Default: 0 + * + * This ini entry is used to enable/disable GRO feature standalonely. + * Value 0: Disable GRO feature + * Value 1: Enable GRO feature always + * Value 3: Enable GRO dynamic feature where TC rule can control GRO + * behavior + * + * Usage: External + * + * + */ #define CFG_DP_GRO \ - CFG_INI_BOOL("GROEnable", false, \ - "DP GRO Enable") + CFG_INI_UINT("GROEnable", \ + WLAN_CFG_GRO_ENABLE_MIN, \ + WLAN_CFG_GRO_ENABLE_MAX, \ + WLAN_CFG_GRO_ENABLE_DEFAULT, \ + CFG_VALUE_OR_DEFAULT, "DP GRO Enable") + +#define WLAN_CFG_TC_INGRESS_PRIO_MIN 0 +#define WLAN_CFG_TC_INGRESS_PRIO_MAX 0xFFFF +#define WLAN_CFG_TC_INGRESS_PRIO_DEFAULT 0 + +#define CFG_DP_TC_INGRESS_PRIO \ + CFG_INI_UINT("tc_ingress_prio", \ + WLAN_CFG_TC_INGRESS_PRIO_MIN, \ + WLAN_CFG_TC_INGRESS_PRIO_MAX, \ + WLAN_CFG_TC_INGRESS_PRIO_DEFAULT, \ + CFG_VALUE_OR_DEFAULT, "DP tc ingress prio") #define CFG_DP_OL_TX_CSUM \ CFG_INI_BOOL("dp_offload_tx_csum_support", false, \ @@ -518,9 +657,55 @@ "DP peer flow ctrl Enable") #define CFG_DP_NAPI \ - CFG_INI_BOOL("dp_napi_enabled", MCL_OR_WIN_VALUE(true, false), \ + CFG_INI_BOOL("dp_napi_enabled", PLATFORM_VALUE(true, false), \ "DP Napi Enabled") +/* + * + * gEnableP2pIpTcpUdpChecksumOffload - Enable checksum offload for P2P mode + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini entry is used to enable/disable TX checksum(UDP/TCP) for P2P modes. + * This includes P2P device mode, P2P client mode and P2P GO mode. + * The feature is enabled by default. To disable TX checksum for P2P, add the + * following entry in ini file: + * gEnableP2pIpTcpUdpChecksumOffload=0 + * + * Usage: External + * + * + */ +#define CFG_DP_P2P_TCP_UDP_CKSUM_OFFLOAD \ + CFG_INI_BOOL("gEnableP2pIpTcpUdpChecksumOffload", true, \ + "DP TCP UDP Checksum Offload for P2P mode (device/cli/go)") +/* + * + * gEnableNanIpTcpUdpChecksumOffload - Enable NAN checksum offload + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * Usage: External + * + * + */ +#define CFG_DP_NAN_TCP_UDP_CKSUM_OFFLOAD \ + CFG_INI_BOOL("gEnableNanIpTcpUdpChecksumOffload", true, \ + "DP TCP UDP Checksum Offload for NAN mode") + +/* + * + * gEnableIpTcpUdpChecksumOffload - Enable checksum offload + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * Usage: External + * + * + */ #define CFG_DP_TCP_UDP_CKSUM_OFFLOAD \ CFG_INI_BOOL("gEnableIpTcpUdpChecksumOffload", true, \ "DP TCP UDP Checksum Offload") @@ -599,6 +784,41 @@ WLAN_CFG_RXDMA_REFILL_RING_SIZE, \ CFG_VALUE_OR_DEFAULT, "DP RXDMA refilll ring") +#define CFG_DP_TX_DESC_LIMIT_0 \ + CFG_INI_UINT("dp_tx_desc_limit_0", \ + WLAN_CFG_TX_DESC_LIMIT_0_MIN, \ + WLAN_CFG_TX_DESC_LIMIT_0_MAX, \ + WLAN_CFG_TX_DESC_LIMIT_0, \ + CFG_VALUE_OR_DEFAULT, "DP TX DESC limit 0") + +#define CFG_DP_TX_DESC_LIMIT_1 \ + CFG_INI_UINT("dp_tx_desc_limit_1", \ + WLAN_CFG_TX_DESC_LIMIT_1_MIN, \ + WLAN_CFG_TX_DESC_LIMIT_1_MAX, \ + WLAN_CFG_TX_DESC_LIMIT_1, \ + CFG_VALUE_OR_DEFAULT, "DP TX DESC limit 1") + +#define CFG_DP_TX_DESC_LIMIT_2 \ + CFG_INI_UINT("dp_tx_desc_limit_2", \ + WLAN_CFG_TX_DESC_LIMIT_2_MIN, \ + WLAN_CFG_TX_DESC_LIMIT_2_MAX, \ + WLAN_CFG_TX_DESC_LIMIT_2, \ + CFG_VALUE_OR_DEFAULT, "DP TX DESC limit 2") + +#define CFG_DP_TX_DEVICE_LIMIT \ + CFG_INI_UINT("dp_tx_device_limit", \ + WLAN_CFG_TX_DEVICE_LIMIT_MIN, \ + WLAN_CFG_TX_DEVICE_LIMIT_MAX, \ + WLAN_CFG_TX_DEVICE_LIMIT, \ + CFG_VALUE_OR_DEFAULT, "DP TX DEVICE limit") + +#define CFG_DP_TX_SW_INTERNODE_QUEUE \ + CFG_INI_UINT("dp_tx_sw_internode_queue", \ + WLAN_CFG_TX_SW_INTERNODE_QUEUE_MIN, \ + WLAN_CFG_TX_SW_INTERNODE_QUEUE_MAX, \ + WLAN_CFG_TX_SW_INTERNODE_QUEUE, \ + CFG_VALUE_OR_DEFAULT, "DP TX SW internode queue") + #define CFG_DP_RXDMA_MONITOR_BUF_RING \ CFG_INI_UINT("dp_rxdma_monitor_buf_ring", \ WLAN_CFG_RXDMA_MONITOR_BUF_RING_SIZE_MIN, \ @@ -677,6 +897,61 @@ CFG_INI_BOOL("gEnableDataStallDetection", \ true, "Enable/Disable Data stall detection") +#define CFG_DP_RX_SW_DESC_WEIGHT \ + CFG_INI_UINT("dp_rx_sw_desc_weight", \ + WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MIN, \ + WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE_MAX, \ + WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE, \ + CFG_VALUE_OR_DEFAULT, "DP RX SW DESC weight") + +#define CFG_DP_RX_FLOW_SEARCH_TABLE_SIZE \ + CFG_INI_UINT("dp_rx_flow_search_table_size", \ + WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE_MIN, \ + WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE_MAX, \ + WLAN_CFG_RX_FLOW_SEARCH_TABLE_SIZE, \ + CFG_VALUE_OR_DEFAULT, \ + "DP Rx Flow Search Table Size in number of entries") + +#define CFG_DP_RX_FLOW_TAG_ENABLE \ + CFG_INI_BOOL("dp_rx_flow_tag_enable", false, \ + "Enable/Disable DP Rx Flow Tag") + +#define CFG_DP_RX_FLOW_SEARCH_TABLE_PER_PDEV \ + CFG_INI_BOOL("dp_rx_per_pdev_flow_search", false, \ + "DP Rx Flow Search Table Is Per PDev") + +#define CFG_DP_RX_MON_PROTOCOL_FLOW_TAG_ENABLE \ + CFG_INI_BOOL("dp_rx_monitor_protocol_flow_tag_enable", true, \ + "Enable/Disable Rx Protocol & Flow tags in Monitor mode") + +/* + * + * dp_rx_fisa_enable - Control Rx datapath FISA + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable DP Rx FISA feature + * + * Related: dp_rx_flow_search_table_size + * + * Supported Feature: STA,P2P and SAP IPA disabled terminating + * + * Usage: Internal/External + * + * + */ +#define CFG_DP_RX_FISA_ENABLE \ + CFG_INI_BOOL("dp_rx_fisa_enable", false, \ + "Enable/Disable DP Rx FISA") + +#define CFG_DP_RXDMA_MONITOR_RX_DROP_THRESHOLD \ + CFG_INI_UINT("mon_drop_thresh", \ + WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE_MIN, \ + WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE_MAX, \ + WLAN_CFG_RXDMA_MONITOR_RX_DROP_THRESH_SIZE, \ + CFG_VALUE_OR_DEFAULT, "RXDMA monitor rx drop theshold") + #define CFG_DP_PKTLOG_BUFFER_SIZE \ CFG_INI_UINT("PktlogBufSize", \ WLAN_CFG_PKTLOG_MIN_BUFFER_SIZE, \ @@ -684,6 +959,64 @@ WLAN_CFG_PKTLOG_BUFFER_SIZE, \ CFG_VALUE_OR_DEFAULT, "Packet Log buffer size") +/* + * + * legacy_mode_csum_disable - Disable csum offload for legacy 802.11abg modes + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to disable HW checksum offload capability for legacy + * connections + * + * Related: gEnableIpTcpUdpChecksumOffload should be enabled + * + * Usage: Internal + * + * + */ + +#define CFG_DP_LEGACY_MODE_CSUM_DISABLE \ + CFG_INI_BOOL("legacy_mode_csum_disable", false, \ + "Enable/Disable legacy mode checksum") + +/* + * + * wow_check_rx_pending_enable - control to check RX frames pending in Wow + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to control DP Software to perform RX pending check + * before entering WoW mode + * + * Usage: Internal + * + * + */ +#define CFG_DP_WOW_CHECK_RX_PENDING \ + CFG_INI_BOOL("wow_check_rx_pending_enable", \ + false, \ + "enable rx frame pending check in WoW mode") + +/* + * + * gForceRX64BA - enable force 64 blockack mode for RX + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to control DP Software to use 64 blockack + * for RX direction forcibly + * + * Usage: Internal + * + * + */ +#define CFG_FORCE_RX_64_BA \ + CFG_INI_BOOL("gForceRX64BA", \ + false, "Enable/Disable force 64 blockack in RX side") + #define CFG_DP \ CFG(CFG_DP_HTT_PACKET_TYPE) \ CFG(CFG_DP_INT_BATCH_THRESHOLD_OTHER) \ @@ -713,12 +1046,15 @@ CFG(CFG_DP_LRO) \ CFG(CFG_DP_SG) \ CFG(CFG_DP_GRO) \ + CFG(CFG_DP_TC_INGRESS_PRIO) \ CFG(CFG_DP_OL_TX_CSUM) \ CFG(CFG_DP_OL_RX_CSUM) \ CFG(CFG_DP_RAWMODE) \ CFG(CFG_DP_PEER_FLOW_CTRL) \ CFG(CFG_DP_NAPI) \ CFG(CFG_DP_TCP_UDP_CKSUM_OFFLOAD) \ + CFG(CFG_DP_NAN_TCP_UDP_CKSUM_OFFLOAD) \ + CFG(CFG_DP_P2P_TCP_UDP_CKSUM_OFFLOAD) \ CFG(CFG_DP_DEFRAG_TIMEOUT_CHECK) \ CFG(CFG_DP_WBM_RELEASE_RING) \ CFG(CFG_DP_TCL_CMD_RING) \ @@ -730,6 +1066,11 @@ CFG(CFG_DP_REO_STATUS_RING) \ CFG(CFG_DP_RXDMA_BUF_RING) \ CFG(CFG_DP_RXDMA_REFILL_RING) \ + CFG(CFG_DP_TX_DESC_LIMIT_0) \ + CFG(CFG_DP_TX_DESC_LIMIT_1) \ + CFG(CFG_DP_TX_DESC_LIMIT_2) \ + CFG(CFG_DP_TX_DEVICE_LIMIT) \ + CFG(CFG_DP_TX_SW_INTERNODE_QUEUE) \ CFG(CFG_DP_RXDMA_MONITOR_BUF_RING) \ CFG(CFG_DP_RXDMA_MONITOR_DST_RING) \ CFG(CFG_DP_RXDMA_MONITOR_STATUS_RING) \ @@ -744,6 +1085,17 @@ CFG(CFG_DP_REORDER_OFFLOAD_SUPPORT) \ CFG(CFG_DP_AP_STA_SECURITY_SEPERATION) \ CFG(CFG_DP_ENABLE_DATA_STALL_DETECTION) \ - CFG(CFG_DP_PKTLOG_BUFFER_SIZE) - + CFG(CFG_DP_RX_SW_DESC_WEIGHT) \ + CFG(CFG_DP_RX_FLOW_SEARCH_TABLE_SIZE) \ + CFG(CFG_DP_RX_FLOW_TAG_ENABLE) \ + CFG(CFG_DP_RX_FLOW_SEARCH_TABLE_PER_PDEV) \ + CFG(CFG_DP_RX_MON_PROTOCOL_FLOW_TAG_ENABLE) \ + CFG(CFG_DP_RXDMA_MONITOR_RX_DROP_THRESHOLD) \ + CFG(CFG_DP_PKTLOG_BUFFER_SIZE) \ + CFG(CFG_DP_RX_FISA_ENABLE) \ + CFG(CFG_DP_LEGACY_MODE_CSUM_DISABLE) \ + CFG(CFG_DP_RX_PENDING_HL_THRESHOLD) \ + CFG(CFG_DP_RX_PENDING_LO_THRESHOLD) \ + CFG(CFG_DP_WOW_CHECK_RX_PENDING) \ + CFG(CFG_FORCE_RX_64_BA) #endif /* _CFG_DP_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.c b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.c index 238f3ccddf02707313835ef721c57322db3848ac..e760e8fe8938372610c39448bd3217bf86003fa8 100644 --- a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.c +++ b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,6 +29,7 @@ #include "wlan_cfg.h" #include "cfg_ucfg_api.h" #include "hal_api.h" +#include "dp_types.h" /* * FIX THIS - @@ -90,49 +92,130 @@ #define WLAN_CFG_HOST2RXDMA_RING_MASK_2 0x4 #define WLAN_CFG_HOST2RXDMA_RING_MASK_3 0x0 -#ifdef CONFIG_MCL -static const int tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) +static const int tx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_TX_RING_MASK_0, 0, 0, 0, 0, 0, 0}; #ifndef IPA_OFFLOAD -static const int rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, WLAN_CFG_RX_RING_MASK_0, WLAN_CFG_RX_RING_MASK_1, WLAN_CFG_RX_RING_MASK_2, WLAN_CFG_RX_RING_MASK_3, 0, 0}; #else -static const int rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, WLAN_CFG_RX_RING_MASK_0, WLAN_CFG_RX_RING_MASK_1, WLAN_CFG_RX_RING_MASK_2, 0, 0, 0}; #endif -static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, WLAN_CFG_RX_MON_RING_MASK_0, WLAN_CFG_RX_MON_RING_MASK_1, 0, 0, 0, 0}; -static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int host2rxdma_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, 0}; -static const int rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rxdma2host_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, WLAN_CFG_RXDMA2HOST_RING_MASK_0, WLAN_CFG_RXDMA2HOST_RING_MASK_1}; -static const int host2rxdma_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int host2rxdma_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, 0}; -static const int rxdma2host_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rxdma2host_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, 0}; -static const int rx_err_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_err_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, WLAN_CFG_RX_ERR_RING_MASK_0}; -static const int rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_wbm_rel_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, WLAN_CFG_RX_WBM_REL_RING_MASK_0}; -static const int reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int reo_status_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, 0, 0, 0, WLAN_CFG_REO_STATUS_RING_MASK_0}; + +static const int tx_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rx_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rx_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int host2rxdma_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rxdma2host_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int host2rxdma_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rxdma2host_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rx_err_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int rx_wbm_rel_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + +static const int reo_status_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0, 0, 0, 0}; + #else -static const int tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { + +static const int tx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_TX_RING_MASK_0, WLAN_CFG_TX_RING_MASK_1, WLAN_CFG_TX_RING_MASK_2, WLAN_CFG_TX_RING_MASK_3}; -static const int rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RX_RING_MASK_0, + WLAN_CFG_RX_RING_MASK_1, + WLAN_CFG_RX_RING_MASK_2, + WLAN_CFG_RX_RING_MASK_3}; + +static const int rx_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0}; + +static const int host2rxdma_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0}; + +static const int rxdma2host_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + 0, 0, 0, 0}; + +static const int host2rxdma_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_HOST2RXDMA_MON_RING_MASK_0, + WLAN_CFG_HOST2RXDMA_MON_RING_MASK_1, + WLAN_CFG_HOST2RXDMA_MON_RING_MASK_2}; + +static const int rxdma2host_mon_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RXDMA2HOST_MON_RING_MASK_0, + WLAN_CFG_RXDMA2HOST_MON_RING_MASK_1, + WLAN_CFG_RXDMA2HOST_MON_RING_MASK_2}; + +static const int rx_err_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RX_ERR_RING_MASK_0, + WLAN_CFG_RX_ERR_RING_MASK_1, + WLAN_CFG_RX_ERR_RING_MASK_2, + WLAN_CFG_RX_ERR_RING_MASK_3}; + +static const int rx_wbm_rel_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RX_WBM_REL_RING_MASK_0, + WLAN_CFG_RX_WBM_REL_RING_MASK_1, + WLAN_CFG_RX_WBM_REL_RING_MASK_2, + WLAN_CFG_RX_WBM_REL_RING_MASK_3}; + +static const int reo_status_ring_mask_msi[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_REO_STATUS_RING_MASK_0, + WLAN_CFG_REO_STATUS_RING_MASK_1, + WLAN_CFG_REO_STATUS_RING_MASK_2, + WLAN_CFG_REO_STATUS_RING_MASK_3}; + +static const int tx_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_TX_RING_MASK_0, + WLAN_CFG_TX_RING_MASK_1, + WLAN_CFG_TX_RING_MASK_2, + WLAN_CFG_TX_RING_MASK_3}; + +static const int rx_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, @@ -145,7 +228,7 @@ static const int rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RX_RING_MASK_2, WLAN_CFG_RX_RING_MASK_3}; -static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, @@ -154,19 +237,19 @@ static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RX_MON_RING_MASK_1, WLAN_CFG_RX_MON_RING_MASK_2}; -static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int host2rxdma_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_HOST2RXDMA_RING_MASK_0, WLAN_CFG_HOST2RXDMA_RING_MASK_1, WLAN_CFG_HOST2RXDMA_RING_MASK_2, WLAN_CFG_HOST2RXDMA_RING_MASK_3}; -static const int rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rxdma2host_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RXDMA2HOST_RING_MASK_0, WLAN_CFG_RXDMA2HOST_RING_MASK_1, WLAN_CFG_RXDMA2HOST_RING_MASK_2, WLAN_CFG_RXDMA2HOST_RING_MASK_3}; -static const int host2rxdma_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int host2rxdma_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, @@ -175,7 +258,7 @@ static const int host2rxdma_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_HOST2RXDMA_MON_RING_MASK_1, WLAN_CFG_HOST2RXDMA_MON_RING_MASK_2}; -static const int rxdma2host_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rxdma2host_mon_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { 0, 0, 0, @@ -184,24 +267,24 @@ static const int rxdma2host_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RXDMA2HOST_MON_RING_MASK_1, WLAN_CFG_RXDMA2HOST_MON_RING_MASK_2}; -static const int rx_err_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_err_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RX_ERR_RING_MASK_0, WLAN_CFG_RX_ERR_RING_MASK_1, WLAN_CFG_RX_ERR_RING_MASK_2, WLAN_CFG_RX_ERR_RING_MASK_3}; -static const int rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int rx_wbm_rel_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RX_WBM_REL_RING_MASK_0, WLAN_CFG_RX_WBM_REL_RING_MASK_1, WLAN_CFG_RX_WBM_REL_RING_MASK_2, WLAN_CFG_RX_WBM_REL_RING_MASK_3}; -static const int reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { +static const int reo_status_ring_mask_integrated[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_REO_STATUS_RING_MASK_0, WLAN_CFG_REO_STATUS_RING_MASK_1, WLAN_CFG_REO_STATUS_RING_MASK_2, WLAN_CFG_REO_STATUS_RING_MASK_3}; -#endif /*CONFIG_MCL*/ +#endif /* MAX_PDEV_CNT == 1 */ /** * g_wlan_srng_cfg[] - Per ring_type specific configuration @@ -279,17 +362,86 @@ void wlan_set_srng_cfg(struct wlan_srng_cfg **wlan_cfg) *wlan_cfg = g_wlan_srng_cfg; } +static const uint8_t rx_fst_toeplitz_key[WLAN_CFG_RX_FST_TOEPLITZ_KEYLEN] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa +}; + +void wlan_cfg_fill_interrupt_mask(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx, + int interrupt_mode, + bool is_monitor_mode) { + int i = 0; + + if (interrupt_mode == DP_INTR_INTEGRATED) { + for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) { + wlan_cfg_ctx->int_tx_ring_mask[i] = + tx_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rx_ring_mask[i] = + rx_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rx_mon_ring_mask[i] = + rx_mon_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rx_err_ring_mask[i] = + rx_err_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = + rx_wbm_rel_ring_mask_integrated[i]; + wlan_cfg_ctx->int_reo_status_ring_mask[i] = + reo_status_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = + rxdma2host_ring_mask_integrated[i]; + wlan_cfg_ctx->int_host2rxdma_ring_mask[i] = + host2rxdma_ring_mask_integrated[i]; + wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[i] = + host2rxdma_mon_ring_mask_integrated[i]; + wlan_cfg_ctx->int_rxdma2host_mon_ring_mask[i] = + rxdma2host_mon_ring_mask_integrated[i]; + } + } else if (interrupt_mode == DP_INTR_MSI || interrupt_mode == + DP_INTR_POLL) { + for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) { + wlan_cfg_ctx->int_tx_ring_mask[i] = tx_ring_mask_msi[i]; + wlan_cfg_ctx->int_rx_mon_ring_mask[i] = + rx_mon_ring_mask_msi[i]; + wlan_cfg_ctx->int_rx_err_ring_mask[i] = + rx_err_ring_mask_msi[i]; + wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = + rx_wbm_rel_ring_mask_msi[i]; + wlan_cfg_ctx->int_reo_status_ring_mask[i] = + reo_status_ring_mask_msi[i]; + if (is_monitor_mode) { + wlan_cfg_ctx->int_rx_ring_mask[i] = 0; + wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0; + } else { + wlan_cfg_ctx->int_rx_ring_mask[i] = + rx_ring_mask_msi[i]; + wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = + rxdma2host_ring_mask_msi[i]; + } + wlan_cfg_ctx->int_host2rxdma_ring_mask[i] = + host2rxdma_ring_mask_msi[i]; + wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[i] = + host2rxdma_mon_ring_mask_msi[i]; + wlan_cfg_ctx->int_rxdma2host_mon_ring_mask[i] = + rxdma2host_mon_ring_mask_msi[i]; + } + } else { + qdf_err("Interrupt mode %d", interrupt_mode); + } +} + /** * wlan_cfg_soc_attach() - Allocate and prepare SoC configuration * @psoc - Object manager psoc * Return: wlan_cfg_ctx - Handle to Configuration context */ -struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void *psoc) +struct wlan_cfg_dp_soc_ctxt * +wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc) { - int i = 0; - struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = qdf_mem_malloc(sizeof(struct wlan_cfg_dp_soc_ctxt)); + uint32_t gro_bit_set; if (!wlan_cfg_ctx) return NULL; @@ -334,32 +486,13 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void *psoc) wlan_cfg_ctx->pktlog_buffer_size = cfg_get(psoc, CFG_DP_PKTLOG_BUFFER_SIZE); - for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) { - wlan_cfg_ctx->int_tx_ring_mask[i] = tx_ring_mask[i]; - wlan_cfg_ctx->int_rx_ring_mask[i] = rx_ring_mask[i]; - wlan_cfg_ctx->int_rx_mon_ring_mask[i] = rx_mon_ring_mask[i]; - wlan_cfg_ctx->int_rx_err_ring_mask[i] = rx_err_ring_mask[i]; - wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = - rx_wbm_rel_ring_mask[i]; - wlan_cfg_ctx->int_reo_status_ring_mask[i] = - reo_status_ring_mask[i]; - wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = - rxdma2host_ring_mask[i]; - wlan_cfg_ctx->int_host2rxdma_ring_mask[i] = - host2rxdma_ring_mask[i]; - wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[i] = - host2rxdma_mon_ring_mask[i]; - wlan_cfg_ctx->int_rxdma2host_mon_ring_mask[i] = - rxdma2host_mon_ring_mask[i]; - } - /* This is default mapping and can be overridden by HW config * received from FW */ - wlan_cfg_set_hw_macid(wlan_cfg_ctx, 0, 1); + wlan_cfg_set_hw_mac_idx(wlan_cfg_ctx, 0, 0); if (MAX_PDEV_CNT > 1) - wlan_cfg_set_hw_macid(wlan_cfg_ctx, 1, 3); + wlan_cfg_set_hw_mac_idx(wlan_cfg_ctx, 1, 2); if (MAX_PDEV_CNT > 2) - wlan_cfg_set_hw_macid(wlan_cfg_ctx, 2, 2); + wlan_cfg_set_hw_mac_idx(wlan_cfg_ctx, 2, 1); wlan_cfg_ctx->base_hw_macid = cfg_get(psoc, CFG_DP_BASE_HW_MAC_ID); @@ -367,16 +500,27 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void *psoc) wlan_cfg_ctx->tso_enabled = cfg_get(psoc, CFG_DP_TSO); wlan_cfg_ctx->lro_enabled = cfg_get(psoc, CFG_DP_LRO); wlan_cfg_ctx->sg_enabled = cfg_get(psoc, CFG_DP_SG); - wlan_cfg_ctx->gro_enabled = cfg_get(psoc, CFG_DP_GRO); + gro_bit_set = cfg_get(psoc, CFG_DP_GRO); + if (gro_bit_set & DP_GRO_ENABLE_BIT_SET) { + wlan_cfg_ctx->gro_enabled = true; + if (gro_bit_set & DP_TC_BASED_DYNAMIC_GRO) + wlan_cfg_ctx->tc_based_dynamic_gro = true; + } + wlan_cfg_ctx->tc_ingress_prio = cfg_get(psoc, CFG_DP_TC_INGRESS_PRIO); wlan_cfg_ctx->ol_tx_csum_enabled = cfg_get(psoc, CFG_DP_OL_TX_CSUM); wlan_cfg_ctx->ol_rx_csum_enabled = cfg_get(psoc, CFG_DP_OL_RX_CSUM); wlan_cfg_ctx->rawmode_enabled = cfg_get(psoc, CFG_DP_RAWMODE); wlan_cfg_ctx->peer_flow_ctrl_enabled = cfg_get(psoc, CFG_DP_PEER_FLOW_CTRL); wlan_cfg_ctx->napi_enabled = cfg_get(psoc, CFG_DP_NAPI); - /*Enable checksum offload by default*/ + wlan_cfg_ctx->p2p_tcp_udp_checksumoffload = + cfg_get(psoc, CFG_DP_P2P_TCP_UDP_CKSUM_OFFLOAD); + wlan_cfg_ctx->nan_tcp_udp_checksumoffload = + cfg_get(psoc, CFG_DP_NAN_TCP_UDP_CKSUM_OFFLOAD); wlan_cfg_ctx->tcp_udp_checksumoffload = cfg_get(psoc, CFG_DP_TCP_UDP_CKSUM_OFFLOAD); + wlan_cfg_ctx->legacy_mode_checksumoffload_disable = + cfg_get(psoc, CFG_DP_LEGACY_MODE_CSUM_DISABLE); wlan_cfg_ctx->per_pkt_trace = cfg_get(psoc, CFG_DP_PER_PKT_LOGGING); wlan_cfg_ctx->defrag_timeout_check = cfg_get(psoc, CFG_DP_DEFRAG_TIMEOUT_CHECK); @@ -401,16 +545,49 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void *psoc) CFG_DP_REO_STATUS_RING); wlan_cfg_ctx->rxdma_refill_ring = cfg_get(psoc, CFG_DP_RXDMA_REFILL_RING); + wlan_cfg_ctx->tx_desc_limit_0 = cfg_get(psoc, + CFG_DP_TX_DESC_LIMIT_0); + wlan_cfg_ctx->tx_desc_limit_1 = cfg_get(psoc, + CFG_DP_TX_DESC_LIMIT_1); + wlan_cfg_ctx->tx_desc_limit_2 = cfg_get(psoc, + CFG_DP_TX_DESC_LIMIT_2); + wlan_cfg_ctx->tx_device_limit = cfg_get(psoc, + CFG_DP_TX_DEVICE_LIMIT); + wlan_cfg_ctx->tx_sw_internode_queue = cfg_get(psoc, + CFG_DP_TX_SW_INTERNODE_QUEUE); wlan_cfg_ctx->rxdma_err_dst_ring = cfg_get(psoc, CFG_DP_RXDMA_ERR_DST_RING); wlan_cfg_ctx->enable_data_stall_detection = cfg_get(psoc, CFG_DP_ENABLE_DATA_STALL_DETECTION); + wlan_cfg_ctx->enable_force_rx_64_ba = + cfg_get(psoc, CFG_FORCE_RX_64_BA); wlan_cfg_ctx->tx_flow_start_queue_offset = cfg_get(psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); wlan_cfg_ctx->tx_flow_stop_queue_threshold = cfg_get(psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); wlan_cfg_ctx->disable_intra_bss_fwd = cfg_get(psoc, CFG_DP_AP_STA_SECURITY_SEPERATION); + wlan_cfg_ctx->rx_sw_desc_weight = cfg_get(psoc, + CFG_DP_RX_SW_DESC_WEIGHT); + wlan_cfg_ctx->rx_toeplitz_hash_key = (uint8_t *)rx_fst_toeplitz_key; + wlan_cfg_ctx->rx_flow_max_search = WLAN_CFG_RX_FST_MAX_SEARCH; + wlan_cfg_ctx->is_rx_flow_tag_enabled = + cfg_get(psoc, CFG_DP_RX_FLOW_TAG_ENABLE); + wlan_cfg_ctx->is_rx_flow_search_table_per_pdev = + cfg_get(psoc, CFG_DP_RX_FLOW_SEARCH_TABLE_PER_PDEV); + wlan_cfg_ctx->rx_flow_search_table_size = + cfg_get(psoc, CFG_DP_RX_FLOW_SEARCH_TABLE_SIZE); + wlan_cfg_ctx->is_rx_mon_protocol_flow_tag_enabled = + cfg_get(psoc, CFG_DP_RX_MON_PROTOCOL_FLOW_TAG_ENABLE); + wlan_cfg_ctx->mon_drop_thresh = + cfg_get(psoc, CFG_DP_RXDMA_MONITOR_RX_DROP_THRESHOLD); + wlan_cfg_ctx->is_rx_fisa_enabled = cfg_get(psoc, CFG_DP_RX_FISA_ENABLE); + wlan_cfg_ctx->rx_pending_high_threshold = + cfg_get(psoc, CFG_DP_RX_PENDING_HL_THRESHOLD); + wlan_cfg_ctx->rx_pending_low_threshold = + cfg_get(psoc, CFG_DP_RX_PENDING_LO_THRESHOLD); + wlan_cfg_ctx->wow_check_rx_pending_enable = + cfg_get(psoc, CFG_DP_WOW_CHECK_RX_PENDING); return wlan_cfg_ctx; } @@ -420,7 +597,8 @@ void wlan_cfg_soc_detach(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx) qdf_mem_free(wlan_cfg_ctx); } -struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_pdev_attach(void *psoc) +struct wlan_cfg_dp_pdev_ctxt * +wlan_cfg_pdev_attach(struct cdp_ctrl_objmgr_psoc *psoc) { struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_ctx = qdf_mem_malloc(sizeof(struct wlan_cfg_dp_pdev_ctxt)); @@ -449,6 +627,11 @@ void wlan_cfg_pdev_detach(struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_ctx) qdf_mem_free(wlan_cfg_ctx); } +int wlan_cfg_get_mon_drop_thresh(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->mon_drop_thresh; +} + void wlan_cfg_set_num_contexts(struct wlan_cfg_dp_soc_ctxt *cfg, int num) { cfg->num_int_ctxts = num; @@ -535,23 +718,45 @@ int wlan_cfg_get_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, return cfg->int_host2rxdma_ring_mask[context]; } -void wlan_cfg_set_hw_macid(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, - int hw_macid) +void wlan_cfg_set_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, + int hw_macid) { qdf_assert_always(pdev_idx < MAX_PDEV_CNT); cfg->hw_macid[pdev_idx] = hw_macid; } -int wlan_cfg_get_hw_macid(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx) +int wlan_cfg_get_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx) { qdf_assert_always(pdev_idx < MAX_PDEV_CNT); return cfg->hw_macid[pdev_idx]; } -int wlan_cfg_get_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx) +int wlan_cfg_get_target_pdev_id(struct wlan_cfg_dp_soc_ctxt *cfg, + int hw_macid) +{ + int idx; + + for (idx = 0; idx < MAX_PDEV_CNT; idx++) { + if (cfg->hw_macid[idx] == hw_macid) + return (idx + 1); + } + qdf_assert_always(idx < MAX_PDEV_CNT); + return WLAN_INVALID_PDEV_ID; +} + +void wlan_cfg_set_pdev_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, + int hw_macid) { qdf_assert_always(pdev_idx < MAX_PDEV_CNT); - return cfg->hw_macid[pdev_idx] - cfg->base_hw_macid; + qdf_assert_always(hw_macid < MAX_NUM_LMAC_HW); + + cfg->hw_macid_pdev_id_map[hw_macid] = pdev_idx; +} + +int wlan_cfg_get_pdev_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int hw_macid) +{ + qdf_assert_always(hw_macid < MAX_NUM_LMAC_HW); + return cfg->hw_macid_pdev_id_map[hw_macid]; } void wlan_cfg_set_ce_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, @@ -642,6 +847,18 @@ int wlan_cfg_per_pdev_tx_ring(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->per_pdev_tx_ring; } +uint32_t +wlan_cfg_rx_pending_hl_threshold(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_pending_high_threshold; +} + +uint32_t +wlan_cfg_rx_pending_lo_threshold(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_pending_low_threshold; +} + int wlan_cfg_per_pdev_lmac_ring(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->per_pdev_lmac_ring; @@ -863,6 +1080,16 @@ int wlan_cfg_get_int_timer_threshold_mon(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->int_timer_threshold_mon; } +int wlan_cfg_get_p2p_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->p2p_tcp_udp_checksumoffload; +} + +int wlan_cfg_get_nan_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->nan_tcp_udp_checksumoffload; +} + int wlan_cfg_get_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->tcp_udp_checksumoffload; @@ -932,12 +1159,48 @@ wlan_cfg_get_dp_soc_rxdma_refill_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->rxdma_refill_ring; } +int +wlan_cfg_get_dp_soc_tx_desc_limit_0(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->tx_desc_limit_0; +} + +int +wlan_cfg_get_dp_soc_tx_desc_limit_1(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->tx_desc_limit_1; +} + +int +wlan_cfg_get_dp_soc_tx_desc_limit_2(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->tx_desc_limit_2; +} + +int +wlan_cfg_get_dp_soc_tx_device_limit(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->tx_device_limit; +} + +int +wlan_cfg_get_dp_soc_tx_sw_internode_queue(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->tx_sw_internode_queue; +} + int wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->rxdma_err_dst_ring; } +int +wlan_cfg_get_dp_soc_rx_sw_desc_weight(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_sw_desc_weight; +} + bool wlan_cfg_get_dp_caps(struct wlan_cfg_dp_soc_ctxt *cfg, enum cdp_capabilities dp_caps) @@ -988,3 +1251,78 @@ int wlan_cfg_get_tx_flow_start_queue_offset(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->tx_flow_start_queue_offset; } #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */ + +void wlan_cfg_set_rx_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val) +{ + cfg->is_rx_flow_tag_enabled = val; +} + +uint8_t *wlan_cfg_rx_fst_get_hash_key(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_toeplitz_hash_key; +} + +uint8_t wlan_cfg_rx_fst_get_max_search(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_flow_max_search; +} + +bool wlan_cfg_is_rx_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->is_rx_flow_tag_enabled; +} + +#ifdef WLAN_SUPPORT_RX_FISA +bool wlan_cfg_is_rx_fisa_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return (bool)(cfg->is_rx_fisa_enabled); +} +#else +bool wlan_cfg_is_rx_fisa_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return false; +} +#endif + +void +wlan_cfg_set_rx_flow_search_table_per_pdev(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val) +{ + cfg->is_rx_flow_search_table_per_pdev = val; +} + +bool wlan_cfg_is_rx_flow_search_table_per_pdev(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->is_rx_flow_search_table_per_pdev; +} + +void wlan_cfg_set_rx_flow_search_table_size(struct wlan_cfg_dp_soc_ctxt *cfg, + uint16_t val) +{ + cfg->rx_flow_search_table_size = val; +} + +uint16_t +wlan_cfg_get_rx_flow_search_table_size(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->rx_flow_search_table_size; +} + +void +wlan_cfg_set_rx_mon_protocol_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val) +{ + cfg->is_rx_mon_protocol_flow_tag_enabled = val; +} + +bool +wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->is_rx_mon_protocol_flow_tag_enabled; +} + +bool wlan_cfg_is_dp_force_rx_64_ba(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->enable_force_rx_64_ba; +} diff --git a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.h b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.h index f08823c8e6b48961433ea1ec514892b9da12d696..7fd657610af65d07597eca7acd4fe8169f86d686 100644 --- a/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.h +++ b/drivers/staging/qca-wifi-host-cmn/wlan_cfg/wlan_cfg.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,7 +24,7 @@ * Temporary place holders. These should come either from target config * or platform configuration */ -#if defined(CONFIG_MCL) +#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) #define WLAN_CFG_DST_RING_CACHED_DESC 0 #define MAX_PDEV_CNT 1 #define WLAN_CFG_INT_NUM_CONTEXTS 7 @@ -35,26 +36,23 @@ #define DP_TX_NAPI_BUDGET_DIV_MASK 0 /* PPDU Stats Configuration - Configure bitmask for enabling tx ppdu tlv's */ -#define DP_PPDU_TXLITE_STATS_BITMASK_CFG 0x1FFF +#define DP_PPDU_TXLITE_STATS_BITMASK_CFG 0x3FFF #define NUM_RXDMA_RINGS_PER_PDEV 2 + +/*Maximum Number of LMAC instances*/ +#define MAX_NUM_LMAC_HW 2 #else #define WLAN_CFG_DST_RING_CACHED_DESC 1 #define MAX_PDEV_CNT 3 #define WLAN_CFG_INT_NUM_CONTEXTS 11 -#define WLAN_CFG_RXDMA1_ENABLE 1 -/* - * This mask defines how many transmit frames account for 1 NAPI work unit - * 0xFFFF means each 64K tx frame completions account for 1 unit of NAPI budget - */ -#define DP_TX_NAPI_BUDGET_DIV_MASK 0xFFFF - -/* PPDU Stats Configuration - Configure bitmask for enabling tx ppdu tlv's */ -#define DP_PPDU_TXLITE_STATS_BITMASK_CFG 0xFFFF - #define NUM_RXDMA_RINGS_PER_PDEV 1 +#define MAX_NUM_LMAC_HW 3 + #endif +#define WLAN_CFG_INT_NUM_CONTEXTS_MAX 11 + /* Tx configuration */ #define MAX_LINK_DESC_BANKS 8 #define MAX_TXDESC_POOLS 4 @@ -66,7 +64,7 @@ #define MAX_RX_MAC_RINGS 2 /* DP process status */ -#ifdef CONFIG_MCL +#if defined(MAX_PDEV_CNT) && (MAX_PDEV_CNT == 1) #define CONFIG_PROCESS_RX_STATUS 1 #define CONFIG_PROCESS_TX_STATUS 1 #else @@ -81,6 +79,10 @@ #define MAX_NUM_PEER_ID_PER_PEER 8 #define DP_MAX_TIDS 17 #define DP_NON_QOS_TID 16 +#define DP_NULL_DATA_TID 17 + +#define WLAN_CFG_RX_FST_MAX_SEARCH 2 +#define WLAN_CFG_RX_FST_TOEPLITZ_KEYLEN 40 struct wlan_cfg_dp_pdev_ctxt; @@ -132,12 +134,16 @@ struct wlan_srng_cfg { * @lro_enabled: enable/disable LRO feature * @sg_enabled: enable disable scatter gather feature * @gro_enabled: enable disable GRO feature + * @tc_based_dynamic_gro: enable/disable tc based dynamic gro + * @tc_ingress_prio: ingress prio to be checked for dynamic gro * @ipa_enabled: Flag indicating if IPA is enabled * @ol_tx_csum_enabled: Flag indicating if TX csum is enabled * @ol_rx_csum_enabled: Flag indicating if Rx csum is enabled * @rawmode_enabled: Flag indicating if RAW mode is enabled * @peer_flow_ctrl_enabled: Flag indicating if peer flow control is enabled * @napi_enabled: enable/disable interrupt mode for reaping tx and rx packets + * @p2p_tcp_udp_checksumoffload: enable/disable checksum offload for P2P mode + * @nan_tcp_udp_checksumoffload: enable/disable checksum offload for NAN mode * @tcp_udp_checksumoffload: enable/disable checksum offload * @nss_cfg: nss configuration * @rx_defrag_min_timeout: rx defrag minimum timeout @@ -153,16 +159,37 @@ struct wlan_srng_cfg { * @rxdma_err_dst_ring: rxdma error detination ring size * @raw_mode_war: enable/disable raw mode war * @enable_data_stall_detection: flag to enable data stall detection + * @enable_force_rx_64_ba: flag to enable force 64 blockack in RX * @disable_intra_bss_fwd: flag to disable intra bss forwarding * @rxdma1_enable: flag to indicate if rxdma1 is enabled + * @tx_desc_limit_0: tx_desc limit for 5G H + * @tx_desc_limit_1: tx_desc limit for 2G + * @tx_desc_limit_2: tx_desc limit for 5G L + * @tx_device_limit: tx device limit + * @tx_sw_internode_queue: tx sw internode queue * @tx_comp_loop_pkt_limit: Max # of packets to be processed in 1 tx comp loop * @rx_reap_loop_pkt_limit: Max # of packets to be processed in 1 rx reap loop * @rx_hp_oos_update_limit: Max # of HP OOS (out of sync) updates * @rx_enable_eol_data_check: flag to enable check for more ring data at end of * dp_rx_process loop - * tx_comp_enable_eol_data_check: flag to enable/disable checking for more data + * @tx_comp_enable_eol_data_check: flag to enable/disable checking for more data * at end of tx_comp_handler loop. + * @rx_sw_desc_weight: rx sw descriptor weight configuration + * @is_rx_mon_protocol_flow_tag_enabled: flag to enable/disable RX protocol or + * flow tagging in monitor/mon-lite mode + * @is_rx_flow_tag_enabled: flag to enable/disable RX flow tagging using FSE + * @is_rx_flow_search_table_per_pdev: flag to indicate if a per-SOC or per-pdev + * table should be used + * @rx_flow_search_table_size: indicates the number of flows in the flow search + * table + * @rx_flow_max_search: max skid length for each hash entry + * @rx_toeplitz_hash_key: toeplitz key pointer used for hash computation over + * 5 tuple flow entry * @pktlog_buffer_size: packet log buffer size + * @is_rx_fisa_enabled: flag to enable/disable FISA Rx + * @rx_pending_high_threshold: threshold of starting pkt drop + * @rx_pending_low_threshold: threshold of stopping pkt drop + * @wow_check_rx_pending_enable: Enable RX frame pending check in WoW */ struct wlan_cfg_dp_soc_ctxt { int num_int_ctxts; @@ -202,19 +229,25 @@ struct wlan_cfg_dp_soc_ctxt { int int_rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; int int_host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; int hw_macid[MAX_PDEV_CNT]; + int hw_macid_pdev_id_map[MAX_NUM_LMAC_HW]; int base_hw_macid; bool rx_hash; bool tso_enabled; bool lro_enabled; bool sg_enabled; bool gro_enabled; + bool tc_based_dynamic_gro; + uint32_t tc_ingress_prio; bool ipa_enabled; bool ol_tx_csum_enabled; bool ol_rx_csum_enabled; bool rawmode_enabled; bool peer_flow_ctrl_enabled; bool napi_enabled; + bool p2p_tcp_udp_checksumoffload; + bool nan_tcp_udp_checksumoffload; bool tcp_udp_checksumoffload; + bool legacy_mode_checksumoffload_disable; bool defrag_timeout_check; int nss_cfg; uint32_t tx_flow_stop_queue_threshold; @@ -234,9 +267,16 @@ struct wlan_cfg_dp_soc_ctxt { uint32_t per_pkt_trace; bool raw_mode_war; bool enable_data_stall_detection; + bool enable_force_rx_64_ba; bool disable_intra_bss_fwd; bool rxdma1_enable; int max_ast_idx; + int tx_desc_limit_0; + int tx_desc_limit_1; + int tx_desc_limit_2; + int tx_device_limit; + int tx_sw_internode_queue; + int mon_drop_thresh; #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT uint32_t tx_comp_loop_pkt_limit; uint32_t rx_reap_loop_pkt_limit; @@ -244,7 +284,18 @@ struct wlan_cfg_dp_soc_ctxt { bool rx_enable_eol_data_check; bool tx_comp_enable_eol_data_check; #endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */ + int rx_sw_desc_weight; + bool is_rx_mon_protocol_flow_tag_enabled; + bool is_rx_flow_tag_enabled; + bool is_rx_flow_search_table_per_pdev; + uint16_t rx_flow_search_table_size; + uint16_t rx_flow_max_search; + uint8_t *rx_toeplitz_hash_key; uint8_t pktlog_buffer_size; + uint8_t is_rx_fisa_enabled; + uint32_t rx_pending_high_threshold; + uint32_t rx_pending_low_threshold; + bool wow_check_rx_pending_enable; }; /** @@ -275,7 +326,8 @@ struct wlan_cfg_dp_pdev_ctxt { * * Return: Handle to configuration context */ -struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void *ctrl_obj); +struct wlan_cfg_dp_soc_ctxt * +wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_obj); /** * wlan_cfg_soc_detach() - Detach soc configuration handle @@ -297,7 +349,8 @@ void wlan_cfg_soc_detach(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx); * * Return: Handle to configuration context */ -struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_pdev_attach(void *ctrl_obj); +struct wlan_cfg_dp_pdev_ctxt * +wlan_cfg_pdev_attach(struct cdp_ctrl_objmgr_psoc *ctrl_obj); /** * wlan_cfg_pdev_detach() Detach and free pdev configuration handle @@ -321,6 +374,7 @@ void wlan_cfg_set_rxbuf_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, void wlan_cfg_set_max_peer_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint32_t val); void wlan_cfg_set_max_ast_idx(struct wlan_cfg_dp_soc_ctxt *cfg, uint32_t val); int wlan_cfg_get_max_ast_idx(struct wlan_cfg_dp_soc_ctxt *cfg); +int wlan_cfg_get_mon_drop_thresh(struct wlan_cfg_dp_soc_ctxt *cfg); int wlan_cfg_set_rx_err_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask); int wlan_cfg_set_rx_wbm_rel_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, @@ -460,36 +514,61 @@ int wlan_cfg_get_rxdma2host_mon_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context); /** - * wlan_cfg_set_hw_macid() - Set HW MAC Id for the given PDEV index + * wlan_cfg_set_hw_macidx() - Set HW MAC Idx for the given PDEV index * * @wlan_cfg_ctx - Configuration Handle * @pdev_idx - Index of SW PDEV * @hw_macid - HW MAC Id * */ -void wlan_cfg_set_hw_macid(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, - int hw_macid); +void wlan_cfg_set_hw_mac_idx + (struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, int hw_macid); /** - * wlan_cfg_get_hw_macid() - Get HW MAC Id for the given PDEV index + * wlan_cfg_get_hw_mac_idx() - Get 0 based HW MAC index for the given + * PDEV index * * @wlan_cfg_ctx - Configuration Handle * @pdev_idx - Index of SW PDEV * - * Return: HW MAC Id + * Return: HW MAC index */ -int wlan_cfg_get_hw_macid(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx); +int wlan_cfg_get_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx); /** - * wlan_cfg_get_hw_mac_idx() - Get 0 based HW MAC index for the given - * PDEV index + * wlan_cfg_get_target_pdev_id() - Get target PDEV ID for HW MAC ID + * + * @wlan_cfg_ctx - Configuration Handle + * @hw_macid - Index of hw mac + * + * Return: PDEV ID + */ +int +wlan_cfg_get_target_pdev_id(struct wlan_cfg_dp_soc_ctxt *cfg, int hw_macid); + +/** + * wlan_cfg_set_pdev_idx() - Set 0 based host PDEV index for the given + * hw mac index * * @wlan_cfg_ctx - Configuration Handle * @pdev_idx - Index of SW PDEV + * @hw_macid - Index of hw mac * - * Return: HW MAC index + * Return: PDEV index */ -int wlan_cfg_get_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx); +void wlan_cfg_set_pdev_idx + (struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, int hw_macid); + +/** + * wlan_cfg_get_pdev_idx() - Get 0 based PDEV index for the given + * hw mac index + * + * @wlan_cfg_ctx - Configuration Handle + * @hw_macid - Index of hw mac + * + * Return: PDEV index + */ +int wlan_cfg_get_pdev_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int hw_macid); /** * wlan_cfg_get_rx_err_ring_mask() - Return Rx monitor ring interrupt mask @@ -770,6 +849,24 @@ wlan_cfg_get_dma_mon_desc_ring_size(struct wlan_cfg_dp_pdev_ctxt *cfg); int wlan_cfg_get_rx_dma_buf_ring_size( struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_pdev_ctx); +/* + * wlan_cfg_rx_pending_hl_threshold() - Return high threshold of rx pending + * @wlan_cfg_pdev_ctx + * + * Return: rx_pending_high_threshold + */ +uint32_t +wlan_cfg_rx_pending_hl_threshold(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_rx_pending_lo_threshold() - Return low threshold of rx pending + * @wlan_cfg_pdev_ctx + * + * Return: rx_pending_low_threshold + */ +uint32_t +wlan_cfg_rx_pending_lo_threshold(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_get_num_mac_rings() - Return the number of MAC RX DMA rings * per pdev @@ -911,6 +1008,22 @@ int wlan_cfg_get_int_timer_threshold_mon(struct wlan_cfg_dp_soc_ctxt *cfg); */ int wlan_cfg_get_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg); +/* + * wlan_cfg_get_nan_checksum_offload - Get checksum offload enable/disable val + * @wlan_cfg_soc_ctx + * + * Return: Checksum offload enable or disable value for NAN mode + */ +int wlan_cfg_get_nan_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_get_p2p_checksum_offload - Get checksum offload enable/disable val + * @wlan_cfg_soc_ctx + * + * Return: Checksum offload enable or disable value for P2P mode + */ +int wlan_cfg_get_p2p_checksum_offload(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_tx_ring_size - Get Tx DMA ring size (TCL Data Ring) * @wlan_cfg_soc_ctx @@ -999,6 +1112,51 @@ wlan_cfg_get_dp_soc_reo_cmd_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg); int wlan_cfg_get_dp_soc_reo_status_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg); +/* + * wlan_cfg_get_dp_soc_tx_desc_limit_0 - Get tx desc limit for 5G H + * @wlan_cfg_soc_ctx + * + * Return: tx desc limit for 5G H + */ +int +wlan_cfg_get_dp_soc_tx_desc_limit_0(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_get_dp_soc_tx_desc_limit_1 - Get tx desc limit for 2G + * @wlan_cfg_soc_ctx + * + * Return: tx desc limit for 2G + */ +int +wlan_cfg_get_dp_soc_tx_desc_limit_1(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_get_dp_soc_tx_desc_limit_2 - Get tx desc limit for 5G L + * @wlan_cfg_soc_ctx + * + * Return: tx desc limit for 5G L + */ +int +wlan_cfg_get_dp_soc_tx_desc_limit_2(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_get_dp_soc_tx_device_limit - Get tx device limit + * @wlan_cfg_soc_ctx + * + * Return: tx device limit + */ +int +wlan_cfg_get_dp_soc_tx_device_limit(struct wlan_cfg_dp_soc_ctxt *cfg); + +/* + * wlan_cfg_get_dp_soc_tx_sw_internode_queue - Get tx sw internode queue + * @wlan_cfg_soc_ctx + * + * Return: tx sw internode queue + */ +int +wlan_cfg_get_dp_soc_tx_sw_internode_queue(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_get_dp_soc_rxdma_refill_ring_size - Get rxdma refill ring size * @wlan_cfg_soc_ctx @@ -1017,6 +1175,15 @@ wlan_cfg_get_dp_soc_rxdma_refill_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg); int wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg); +/* + * wlan_cfg_get_dp_soc_rx_sw_desc_weight - Get rx sw desc weight + * @wlan_cfg_soc_ctx + * + * Return: rx_sw_desc_weight + */ +int +wlan_cfg_get_dp_soc_rx_sw_desc_weight(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_get_dp_caps - Get dp capablities * @wlan_cfg_soc_ctx @@ -1046,4 +1213,138 @@ int wlan_cfg_get_rx_defrag_min_timeout(struct wlan_cfg_dp_soc_ctxt *cfg); int wlan_cfg_get_defrag_timeout_check(struct wlan_cfg_dp_soc_ctxt *cfg); +/** + * wlan_cfg_get_rx_flow_search_table_size() - Return the size of Rx FST + * in number of entries + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: rx_fst_size + */ +uint16_t +wlan_cfg_get_rx_flow_search_table_size(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_rx_fst_get_max_search() - Return the max skid length for FST search + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: max_search + */ +uint8_t wlan_cfg_rx_fst_get_max_search(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_rx_fst_get_hash_key() - Return Toeplitz Hash Key used for FST + * search + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: 320-bit Hash Key + */ +uint8_t *wlan_cfg_rx_fst_get_hash_key(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_set_rx_flow_tag_enabled() - set rx flow tag enabled flag in + * DP soc context + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @val: Rx flow tag feature flag value + * + * Return: None + */ +void wlan_cfg_set_rx_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val); + +/** + * wlan_cfg_is_rx_flow_tag_enabled() - get rx flow tag enabled flag from + * DP soc context + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: true if feature is enabled, else false + */ +bool wlan_cfg_is_rx_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_set_rx_flow_search_table_per_pdev() - Set flag to indicate that + * Rx FST is per pdev + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @val: boolean flag indicating Rx FST per pdev or per SOC + * + * Return: None + */ +void +wlan_cfg_set_rx_flow_search_table_per_pdev(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val); + +/** + * wlan_cfg_is_rx_flow_search_table_per_pdev() - get RX FST flag for per pdev + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: true if Rx FST is per pdev, else false + */ +bool +wlan_cfg_is_rx_flow_search_table_per_pdev(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_set_rx_flow_search_table_size() - set RX FST size in DP SoC context + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @val: Rx FST size in number of entries + * + * Return: None + */ +void +wlan_cfg_set_rx_flow_search_table_size(struct wlan_cfg_dp_soc_ctxt *cfg, + uint16_t val); + +/** + * wlan_cfg_set_rx_mon_protocol_flow_tag_enabled() - set mon rx tag enabled flag + * in DP soc context + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @val: Rx protocol or flow tag feature flag value in monitor mode from INI + * + * Return: None + */ +void +wlan_cfg_set_rx_mon_protocol_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg, + bool val); + +/** + * wlan_cfg_is_rx_mon_protocol_flow_tag_enabled() - get mon rx tag enabled flag + * from DP soc context + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * + * Return: true if feature is enabled in monitor mode for protocol or flow + * tagging in INI, false otherwise + */ +bool +wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_fill_interrupt_mask() - set interrupt mask + * + * @wlan_cfg_dp_soc_ctxt: soc configuration context + * @interrupt_mode: interrupt_mode: MSI/LEGACY + * @is_monitor_mode: is monitor mode enabled + * + * Return: void + */ +void wlan_cfg_fill_interrupt_mask(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx, + int interrupt_mode, bool is_monitor_mode); + +/** + * wlan_cfg_is_rx_fisa_enabled() - Get Rx FISA enabled flag + * + * + * @cfg: soc configuration context + * + * Return: true if enabled, false otherwise. + */ +bool wlan_cfg_is_rx_fisa_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); + +/** + * wlan_cfg_is_dp_force_rx_64_ba() - Get force use 64 BA flag + * @cfg: config context + * + * Return: force use 64 BA flag + */ +bool wlan_cfg_is_dp_force_rx_64_ba(struct wlan_cfg_dp_soc_ctxt *cfg); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_filtered_logging.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_filtered_logging.h new file mode 100644 index 0000000000000000000000000000000000000000..08700275701235b94697193e0ab032de271fd7c7 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_filtered_logging.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef WMI_FILTERED_LOGGING_H +#define WMI_FILTERED_LOGGING_H + +#include +#include "wmi_unified_priv.h" + +#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING +/** + * wmi_specific_cmd_record() - Record user specified command + * @wmi_handle: handle to WMI + * @id: cmd id + * @buf: buf containing cmd details + * + * Check if the command id is in target list, + * if found, record it. + * + * Context: the function will not sleep, caller is expected to hold + * proper locking. + * + * Return: none + */ +void wmi_specific_cmd_record(wmi_unified_t wmi_handle, + uint32_t id, uint8_t *buf); + +/** + * wmi_specific_evt_record() - Record user specified event + * @wmi_handle: handle to WMI + * @id: cmd id + * @buf: buf containing event details + * + * Check if the event id is in target list, + * if found, record it. + * + * Context: the function will not sleep, caller is expected to hold + * proper locking. + * + * Return: none + */ +void wmi_specific_evt_record(wmi_unified_t wmi_handle, + uint32_t id, uint8_t *buf); + +/** + * wmi_filtered_logging_init() - initialize filtered logging + * @wmi_handle: handle to WMI + * + * Context: the function will not sleep, no lock needed + * + * Return: none + */ +void wmi_filtered_logging_init(wmi_unified_t wmi_handle); + +/** + * wmi_filtered_logging_free() - free the buffers for filtered logging + * @wmi_handle: handle to WMI + * + * Context: the function will not sleep, no lock needed + * + * Return: none + */ +void wmi_filtered_logging_free(wmi_unified_t wmi_handle); + +/* + * Debugfs read/write functions + */ +/** + * debug_filtered_wmi_cmds_show() - debugfs read function for filtered_wmi_cmds + * @m: seq_file handle + * @v: not used, offset of read + * Return: number of bytes read + */ +int debug_filtered_wmi_cmds_show(qdf_debugfs_file_t m, void *v); + +/** + * debug_filtered_wmi_evts_show() - debugfs read function for filtered_wmi_evts + * @m: seq_file handle + * @v: not used, offset of read + * Return: number of bytes read + */ +int debug_filtered_wmi_evts_show(qdf_debugfs_file_t m, void *v); + +/** + * debug_wmi_filtered_command_log_show() - debugfs read function for + * wmi_filtered_command_log + * @m: seq_file handle + * @v: not used, offset of read + * Return: number of bytes read + */ +int debug_wmi_filtered_command_log_show(qdf_debugfs_file_t m, void *v); + +/** + * debug_wmi_filtered_event_log_show() - debugfs read function for + * wmi_filtered_event_log + * @m: seq_file handle + * @v: not used, offset of read + * Return: number of bytes read + */ +int debug_wmi_filtered_event_log_show(qdf_debugfs_file_t m, void *v); + +/** + * debug_wmi_filtered_wmi_cmds_write() - debugfs write for filtered_wmi_cmds + * + * @file: file handler to access wmi_handle + * @buf: received data buffer + * @count: length of received buffer + * @ppos: Not used + * + * Return: count + */ +ssize_t debug_filtered_wmi_cmds_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos); + +/** + * debug_wmi_filtered_wmi_evts_write() - debugfs write for filtered_wmi_evts + * + * @file: file handler to access wmi_handle + * @buf: received data buffer + * @count: length of received buffer + * @ppos: Not used + * + * Return: count + */ +ssize_t debug_filtered_wmi_evts_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos); + +/** + * debug_wmi_filtered_command_log_write() - debugfs write for + * filtered_command_log + * + * @file: file handler to access wmi_handle + * @buf: received data buffer + * @count: length of received buffer + * @ppos: Not used + * + * Return: count + */ +ssize_t debug_wmi_filtered_command_log_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos); + +/** + * debug_wmi_filtered_event_log_write() - debugfs write for filtered_event_log + * + * @file: file handler to access wmi_handle + * @buf: received data buffer + * @count: length of received buffer + * @ppos: Not used + * + * Return: count + */ +ssize_t debug_wmi_filtered_event_log_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos); + +#else /* WMI_INTERFACE_FILTERED_EVENT_LOGGING */ + +static inline void wmi_specific_cmd_record(wmi_unified_t wmi_handle, + uint32_t id, uint8_t *buf) +{ + /* do nothing */ +} + +static inline void wmi_specific_evt_record(wmi_unified_t wmi_handle, + uint32_t id, uint8_t *buf) +{ + /* do nothing */ +} + +static inline void wmi_filtered_logging_init(wmi_unified_t wmi_handle) +{ + /* do nothing */ +} + +static inline void wmi_filtered_logging_free(wmi_unified_t wmi_handle) +{ + /* do nothing */ +} +#endif /* end of WMI_INTERFACE_FILTERED_EVENT_LOGGING */ + +#endif /*WMI_FILTERED_LOGGING_H*/ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_hang_event.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_hang_event.h new file mode 100644 index 0000000000000000000000000000000000000000..96127ea6f622c03e7716c7b1ee8900ed8b5754b7 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_hang_event.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ +#ifndef WMI_HANG_EVENT_H +#define WMI_HANG_EVENT_H + +#include +#ifdef WLAN_HANG_EVENT + +/** + * wmi_hang_event_notifier_register() - wmi hang event notifier register + * @wmi_hdl: WMI Handle + * + * This function registers wmi layer notifier for the hang event notifier chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS wmi_hang_event_notifier_register(struct wmi_unified *wmi_hdl); + +/** + * wmi_hang_event_notifier_unregister() - wmi hang event notifier unregister + * @wmi_hdl: WMI Handle + * + * This function unregisters wmi layer notifier for the hang event notifier + * chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS wmi_hang_event_notifier_unregister(void); +#else +static inline +QDF_STATUS wmi_hang_event_notifier_register(struct wmi_unified *wmi_hdl) +{ + return 0; +} + +static inline QDF_STATUS wmi_hang_event_notifier_unregister(void) +{ + return 0; +} +#endif +#endif diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_api.h index 45b51ec0832d617d4655ae759478e82930bc093c..7cbc50e104cdcc659009d1219b6df1857181872d 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_api.h @@ -25,9 +25,6 @@ #define _WMI_UNIFIED_API_H_ #include -#ifdef CONFIG_MCL -#include "wmi.h" -#endif #include "htc_api.h" #include "wmi_unified_param.h" #include "service_ready_param.h" @@ -37,9 +34,6 @@ #include "wmi_unified_pmo_api.h" #endif #include "wlan_scan_public_structs.h" -#ifdef WLAN_FEATURE_DISA -#include "wlan_disa_public_struct.h" -#endif #ifdef WLAN_FEATURE_ACTION_OUI #include "wlan_action_oui_public_struct.h" #endif @@ -106,10 +100,6 @@ #include "wmi_unified_fwol_api.h" #endif -#ifdef WLAN_FEATURE_PKT_CAPTURE -#include "wlan_pkt_capture_public_structs.h" -#endif - typedef qdf_nbuf_t wmi_buf_t; #define wmi_buf_data(_buf) qdf_nbuf_data(_buf) @@ -131,19 +121,6 @@ typedef qdf_nbuf_t wmi_buf_t; struct wmi_soc; struct policy_mgr_dual_mac_config; -/** - * struct wmi_rx_ops - handle to wmi rx ops - * @scn_handle: handle to scn - * @ev: event buffer - * @rx_ctx: rx execution context - * @wma_process_fw_event_handler_cbk: generic event handler callback - */ -struct wmi_rx_ops { - - int (*wma_process_fw_event_handler_cbk)(ol_scn_t scn_handle, - void *ev, - uint8_t rx_ctx); -}; /** * enum wmi_target_type - type of supported wmi command @@ -161,11 +138,26 @@ enum wmi_target_type { * enum wmi_rx_exec_ctx - wmi rx execution context * @WMI_RX_WORK_CTX: work queue context execution provided by WMI layer * @WMI_RX_UMAC_CTX: execution context provided by umac layer + * @WMI_RX_SERIALIZER_CTX: Execution context is serialized thread context * */ enum wmi_rx_exec_ctx { WMI_RX_WORK_CTX, - WMI_RX_UMAC_CTX + WMI_RX_UMAC_CTX, + WMI_RX_TASKLET_CTX = WMI_RX_UMAC_CTX, + WMI_RX_SERIALIZER_CTX = 2 +}; + +/** + * enum wmi_fw_mem_prio - defines FW Memory requirement type + * @WMI_FW_MEM_HIGH_PRIORITY: Memory requires contiguous memory allocation + * @WMI_FW_MEM_LOW_PRIORITY: Memory can be fragmented + * @WMI_FW_PRIORITY_MAX: Invalid type + */ +enum wmi_fw_mem_prio { + WMI_FW_MEM_HIGH_PRIORITY = 0, + WMI_FW_MEM_LOW_PRIORITY, + WMI_FW_PRIORITY_MAX }; /** @@ -184,7 +176,6 @@ struct wmi_unified_attach_params { enum wmi_target_type target_type; bool use_cookie; bool is_async_ep; - struct wmi_rx_ops *rx_ops; struct wlan_objmgr_psoc *psoc; uint16_t max_commands; uint32_t soc_id; @@ -227,10 +218,11 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle); /** * API to sync time between host and firmware * - * @param wmi_handle : handle to WMI. - * @return void. + * @wmi_handle: handle to WMI. + * + * Return: none */ -void wmi_send_time_stamp_sync_cmd_tlv(void *wmi_hdl); +void wmi_send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle); void wmi_unified_remove_work(struct wmi_unified *wmi_handle); @@ -383,14 +375,15 @@ wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle, wmi_conv_event_id event_id); /** - * request wmi to connet its htc service. - * @param wmi_handle : handle to WMI. - * @param htc_handle : handle to HTC. - * @return void + * wmi_unified_connect_htc_service() - WMI API to get connect to HTC service + * @wmi_handle: handle to WMI. + * @htc_handle: handle to HTC. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAULT for failure */ QDF_STATUS wmi_unified_connect_htc_service(struct wmi_unified *wmi_handle, - void *htc_handle); + HTC_HANDLE htc_handle); /* * WMI API to verify the host has enough credits to suspend @@ -430,6 +423,36 @@ void wmi_set_target_suspend(wmi_unified_t wmi_handle, bool val); */ bool wmi_is_target_suspended(struct wmi_unified *wmi_handle); +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI +/** + * wmi_set_qmi_stats() - WMI API to set qmi stats enabled/disabled + * @wmi_handle: handle to WMI. + * @val: suspend state boolean + */ +void wmi_set_qmi_stats(wmi_unified_t wmi_handle, bool val); + +/** + * wmi_is_qmi_stats_enabled() - WMI API to check if periodic stats + * over qmi is enableid + * @wmi_handle: handle to WMI. + * + * WMI API to check if periodic stats over qmi is enabled + * + * Return: true if qmi stats is enabled, else false. + */ +bool wmi_is_qmi_stats_enabled(struct wmi_unified *wmi_handle); +#else +static inline +void wmi_set_qmi_stats(wmi_unified_t wmi_handle, bool val) +{} + +static inline +bool wmi_is_qmi_stats_enabled(struct wmi_unified *wmi_handle) +{ + return false; +} +#endif /* end if of WLAN_FEATURE_WMI_SEND_RECV_QMI */ + /** * WMI API to set bus suspend state * @param wmi_handle: handle to WMI. @@ -461,6 +484,14 @@ void wmi_set_tgt_assert(wmi_unified_t wmi_handle, bool val); int wmi_stop(wmi_unified_t wmi_handle); +/** + * generic function to start unified WMI command + * @param wmi_handle : handle to WMI. + * @return 0 on success and -ve on failure. + */ +int +wmi_start(wmi_unified_t wmi_handle); + /** * API to flush all the previous packets associated with the wmi endpoint * @@ -470,13 +501,18 @@ void wmi_flush_endpoint(wmi_unified_t wmi_handle); /** - * wmi_pdev_id_conversion_enable() - API to enable pdev_id conversion in WMI - * By default pdev_id conversion is not done in WMI. + * wmi_pdev_id_conversion_enable() - API to enable pdev_id and phy_id + * conversion in WMI. By default pdev_id and + * phyid conversion is not done in WMI. * This API can be used enable conversion in WMI. * @param wmi_handle : handle to WMI + * @param *pdev_id_map : pdev conversion map + * @param size : size of pdev_id_map * Return none */ -void wmi_pdev_id_conversion_enable(wmi_unified_t wmi_handle); +void wmi_pdev_id_conversion_enable(wmi_unified_t wmi_handle, + uint32_t *pdev_id_map, + uint8_t size); /** * API to handle wmi rx event after UMAC has taken care of execution @@ -514,6 +550,32 @@ void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx); void wmi_process_fw_event(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf); uint16_t wmi_get_max_msg_len(wmi_unified_t wmi_handle); +/** + * wmi_unified_soc_set_hw_mode_cmd() - Send WMI_SOC_SET_HW_MODE_CMDID to FW + * @wmi_handle: wmi handle + * @hw_mode_index: The HW_Mode field is a enumerated type that is selected + * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID. + * + * Request HardWare (HW) Mode change to WLAN firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_soc_set_hw_mode_cmd(wmi_unified_t wmi_handle, + uint32_t hw_mode_index); + +/** + * wmi_extract_hw_mode_resp() - function to extract HW mode change response + * @wmi_hdl: WMI handle + * @evt_buf: Buffer holding event data + * @cmd_status: command status + * + * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. + */ +QDF_STATUS +wmi_unified_extract_hw_mode_resp(wmi_unified_t wmi, + void *evt_buf, + uint32_t *cmd_status); + /** * wmi_unified_extract_roam_trigger_stats() - Extract roam trigger related * stats @@ -545,6 +607,7 @@ QDF_STATUS wmi_unified_extract_roam_scan_stats(wmi_unified_t wmi, void *evt_buf, struct wmi_roam_scan_data *dst, uint8_t idx, uint8_t chan_idx, uint8_t ap_idx); + /** * wmi_unified_extract_roam_result_stats() - Extract roam result related stats * @wmi: wmi handle @@ -573,13 +636,40 @@ QDF_STATUS wmi_unified_extract_roam_11kv_stats(wmi_unified_t wmi, void *evt_buf, struct wmi_neighbor_report_data *dst, uint8_t idx, uint8_t rpt_idx); +/** + * wmi_unified_extract_roam_msg_info() - Extract Roam msg stats + * @wmi: wmi handle + * @evt_buf: Pointer to the event buffer + * @dst: Pointer to destination structure to fill data + * @idx: TLV id + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_unified_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf, + struct wmi_roam_msg_info *dst, uint8_t idx); -QDF_STATUS wmi_unified_vdev_create_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct vdev_create_params *param); +/** + * wmi_unified_vdev_create_send() - send VDEV create command to fw + * @wmi_handle: wmi handle + * @param: pointer to hold vdev create parameter + * @macaddr: vdev mac address + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_create_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct vdev_create_params *param); -QDF_STATUS wmi_unified_vdev_delete_send(void *wmi_hdl, - uint8_t if_id); +/** + * wmi_unified_vdev_delete_send() - send VDEV delete command to fw + * @wmi_handle: wmi handle + * @if_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_delete_send(wmi_unified_t wmi_handle, + uint8_t if_id); /** * wmi_unified_vdev_nss_chain_params_send() - send VDEV nss chain params to fw @@ -589,813 +679,2400 @@ QDF_STATUS wmi_unified_vdev_delete_send(void *wmi_hdl, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_vdev_nss_chain_params_send(void *wmi_hdl, - uint8_t vdev_id, - struct vdev_nss_chains *nss_chains_user_cfg); +QDF_STATUS +wmi_unified_vdev_nss_chain_params_send( + wmi_unified_t wmi_handle, + uint8_t vdev_id, + struct vdev_nss_chains *nss_chains_user_cfg); + +/** + * wmi_unified_vdev_stop_send() - send vdev stop command to fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_stop_send(wmi_unified_t wmi_handle, + uint8_t vdev_id); -QDF_STATUS wmi_unified_vdev_stop_send(void *wmi_hdl, - uint8_t vdev_id); +/** + * wmi_unified_vdev_up_send() - send vdev up command in fw + * @wmi_handle: wmi handle + * @bssid: bssid + * @params: pointer to hold vdev up parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_up_send(wmi_unified_t wmi_handle, + uint8_t bssid[QDF_MAC_ADDR_SIZE], + struct vdev_up_params *params); -QDF_STATUS wmi_unified_vdev_up_send(void *wmi_hdl, - uint8_t bssid[QDF_MAC_ADDR_SIZE], - struct vdev_up_params *params); +/** + * wmi_unified_vdev_down_send() - send vdev down command to fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_down_send(wmi_unified_t wmi_handle, + uint8_t vdev_id); -QDF_STATUS wmi_unified_vdev_down_send(void *wmi_hdl, - uint8_t vdev_id); +/** + * wmi_unified_vdev_start_send() - send vdev start command to fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_start_send(wmi_unified_t wmi_handle, + struct vdev_start_params *req); -QDF_STATUS wmi_unified_vdev_start_send(void *wmi_hdl, - struct vdev_start_params *req); /** * wmi_unified_vdev_set_nac_rssi_send() - send NAC_RSSI command to fw - * @param wmi_handle : handle to WMI - * @param req : pointer to hold nac rssi request data + * @wmi_handle: handle to WMI + * @req: pointer to hold nac rssi request data * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_vdev_set_nac_rssi_send(void *wmi_hdl, - struct vdev_scan_nac_rssi_params *req); - -QDF_STATUS wmi_unified_hidden_ssid_vdev_restart_send(void *wmi_hdl, - struct hidden_ssid_vdev_restart_params *restart_params); +QDF_STATUS +wmi_unified_vdev_set_nac_rssi_send(wmi_unified_t wmi_handle, + struct vdev_scan_nac_rssi_params *req); -QDF_STATUS wmi_unified_vdev_set_param_send(void *wmi_hdl, +/** + * wmi_unified_vdev_set_param_send() - WMI vdev set parameter function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold vdev set parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_vdev_set_param_send(wmi_unified_t wmi_handle, struct vdev_set_params *param); -QDF_STATUS wmi_unified_sifs_trigger_send(void *wmi_hdl, +/** + * wmi_unified_sifs_trigger_send() - WMI vdev sifs trigger parameter function + * @wmi_handle: handle to WMI. + * @param: pointer to hold sifs trigger parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_sifs_trigger_send(wmi_unified_t wmi_handle, struct sifs_trigger_param *param); -QDF_STATUS wmi_unified_peer_delete_send(void *wmi_hdl, - uint8_t - peer_addr[QDF_MAC_ADDR_SIZE], - uint8_t vdev_id); - -QDF_STATUS wmi_unified_peer_flush_tids_send(void *wmi_hdl, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - struct peer_flush_params *param); - -QDF_STATUS wmi_set_peer_param_send(void *wmi_hdl, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - struct peer_set_params *param); - -QDF_STATUS wmi_unified_peer_create_send(void *wmi_hdl, - struct peer_create_params *param); - -QDF_STATUS wmi_unified_stats_request_send(wmi_unified_t wmi_handle, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct stats_request_params *param); - -QDF_STATUS wmi_unified_green_ap_ps_send(void *wmi_hdl, - uint32_t value, uint8_t pdev_id); - -QDF_STATUS wmi_unified_wow_enable_send(void *wmi_hdl, - struct wow_cmd_params *param, - uint8_t mac_id); - -QDF_STATUS wmi_unified_wow_wakeup_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_wow_add_wakeup_event_send(void *wmi_hdl, - struct wow_add_wakeup_params *param); - -QDF_STATUS wmi_unified_wow_add_wakeup_pattern_send(void *wmi_hdl, - struct wow_add_wakeup_pattern_params *param); - -QDF_STATUS wmi_unified_wow_remove_wakeup_pattern_send(void *wmi_hdl, - struct wow_remove_wakeup_pattern_params *param); - -#ifndef CONFIG_MCL -QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id); - /** - * wmi_unified_peer_based_pktlog_send() - WMI request enable peer - * based filtering - * @wmi_handle: handle to WMI. - * @macaddr: PEER mac address to be filtered - * @mac_id: Mac id - * @enb_dsb: Enable or Disable peer based pktlog - * filtering + * wmi_unified_peer_delete_send() - send PEER delete command to fw + * @wmi_handle: wmi handle + * @peer_addr: peer mac addr + * @vdev_id: vdev id * - * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_peer_based_pktlog_send(void *wmi_hdl, - uint8_t *macaddr, - uint8_t mac_id, - uint8_t enb_dsb); -#else -QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct packet_enable_params *param); -#endif - -QDF_STATUS wmi_unified_packet_log_disable_send(void *wmi_hdl, uint8_t mac_id); - -QDF_STATUS wmi_unified_suspend_send(void *wmi_hdl, - struct suspend_params *param, - uint8_t mac_id); - -QDF_STATUS wmi_unified_resume_send(void *wmi_hdl, - uint8_t mac_id); - -QDF_STATUS -wmi_unified_pdev_param_send(void *wmi_hdl, - struct pdev_params *param, - uint8_t mac_id); - -QDF_STATUS wmi_unified_beacon_tmpl_send_cmd(void *wmi_hdl, - struct beacon_tmpl_params *param); - - -QDF_STATUS wmi_unified_peer_assoc_send(void *wmi_hdl, - struct peer_assoc_params *param); - -QDF_STATUS wmi_unified_sta_ps_cmd_send(void *wmi_hdl, - struct sta_ps_params *param); - -QDF_STATUS wmi_unified_ap_ps_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct ap_ps_params *param); - -QDF_STATUS wmi_unified_scan_start_cmd_send(void *wmi_hdl, - struct scan_req_params *param); - -QDF_STATUS wmi_unified_scan_stop_cmd_send(void *wmi_hdl, - struct scan_cancel_param *param); - -QDF_STATUS wmi_unified_scan_chan_list_cmd_send(void *wmi_hdl, - struct scan_chan_list_params *param); - - -QDF_STATUS wmi_crash_inject(void *wmi_hdl, - struct crash_inject *param); - -QDF_STATUS wmi_unified_pdev_utf_cmd_send(void *wmi_hdl, - struct pdev_utf_params *param, - uint8_t mac_id); - -#ifdef FEATURE_FW_LOG_PARSING -QDF_STATUS wmi_unified_dbglog_cmd_send(void *wmi_hdl, - struct dbglog_params *param); -#else -static inline QDF_STATUS -wmi_unified_dbglog_cmd_send(void *wmi_hdl, - struct dbglog_params *param) -{ - return QDF_STATUS_SUCCESS; -} -#endif - -QDF_STATUS wmi_mgmt_unified_cmd_send(void *wmi_hdl, - struct wmi_mgmt_params *param); - -QDF_STATUS wmi_offchan_data_tx_cmd_send(void *wmi_hdl, - struct wmi_offchan_data_tx_params *param); - -QDF_STATUS wmi_unified_modem_power_state(void *wmi_hdl, - uint32_t param_value); - -QDF_STATUS wmi_unified_set_sta_ps_mode(void *wmi_hdl, - uint32_t vdev_id, uint8_t val); QDF_STATUS -wmi_unified_set_sta_uapsd_auto_trig_cmd(void *wmi_hdl, - struct sta_uapsd_trig_params *param); - -QDF_STATUS wmi_unified_get_temperature(void *wmi_hdl); - -QDF_STATUS wmi_unified_set_smps_params(void *wmi_hdl, uint8_t vdev_id, - int value); - -QDF_STATUS wmi_unified_set_mimops(void *wmi_hdl, uint8_t vdev_id, int value); - -QDF_STATUS wmi_unified_lro_config_cmd(void *wmi_hdl, - struct wmi_lro_config_cmd_t *wmi_lro_cmd); - -QDF_STATUS wmi_unified_set_thermal_mgmt_cmd(void *wmi_hdl, - struct thermal_cmd_params *thermal_info); - -QDF_STATUS wmi_unified_peer_rate_report_cmd(void *wmi_hdl, - struct wmi_peer_rate_report_params *rate_report_params); - -QDF_STATUS wmi_unified_process_update_edca_param(void *wmi_hdl, - uint8_t vdev_id, bool mu_edca_param, - struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]); - -QDF_STATUS wmi_unified_probe_rsp_tmpl_send_cmd(void *wmi_hdl, - uint8_t vdev_id, - struct wmi_probe_resp_params *probe_rsp_info); - -QDF_STATUS wmi_unified_setup_install_key_cmd(void *wmi_hdl, - struct set_key_params *key_params); +wmi_unified_peer_delete_send(wmi_unified_t wmi_handle, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint8_t vdev_id); -QDF_STATUS wmi_unified_p2p_go_set_beacon_ie_cmd(void *wmi_hdl, - uint32_t vdev_id, uint8_t *p2p_ie); - -QDF_STATUS wmi_unified_scan_probe_setoui_cmd(void *wmi_hdl, - struct scan_mac_oui *psetoui); - -#ifdef IPA_OFFLOAD -QDF_STATUS wmi_unified_ipa_offload_control_cmd(void *wmi_hdl, - struct ipa_uc_offload_control_params *ipa_offload); -#endif - -QDF_STATUS wmi_unified_pno_stop_cmd(void *wmi_hdl, uint8_t vdev_id); - -#ifdef FEATURE_WLAN_SCAN_PNO -QDF_STATUS wmi_unified_pno_start_cmd(void *wmi_hdl, - struct pno_scan_req_params *pno); -#endif - -QDF_STATUS wmi_unified_nlo_mawc_cmd(void *wmi_hdl, - struct nlo_mawc_params *params); - -#ifdef WLAN_FEATURE_LINK_LAYER_STATS /** - * wmi_unified_process_ll_stats_clear_cmd() - clear link layer stats + * wmi_unified_peer_flush_tids_send() - flush peer tids packets in fw * @wmi_handle: wmi handle - * @clear_req: ll stats clear request command params + * @peer_addr: peer mac address + * @param: pointer to hold peer flush tid parameter * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_process_ll_stats_clear_cmd(wmi_unified_t wmi_handle, - const struct ll_stats_clear_params *clear_req); +QDF_STATUS +wmi_unified_peer_flush_tids_send(wmi_unified_t wmi_handle, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + struct peer_flush_params *param); /** - * wmi_unified_process_ll_stats_set_cmd() - link layer stats set request - * @wmi_handle: wmi handle - * @set_req: ll stats set request command params + * wmi_unified_peer_delete_all_send() - send PEER delete all command to fw + * @wmi_hdl: wmi handle + * @param: pointer to hold peer delete all parameters * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_process_ll_stats_set_cmd(wmi_unified_t wmi_handle, - const struct ll_stats_set_params *set_req); +QDF_STATUS wmi_unified_peer_delete_all_send( + wmi_unified_t wmi_hdl, + struct peer_delete_all_params *param); /** - * wmi_unified_process_ll_stats_get_cmd() - link layer stats get request + * wmi_set_peer_param() - set peer parameter in fw * @wmi_handle: wmi handle - * @get_req: ll stats get request command params + * @peer_addr: peer mac address + * @param: pointer to hold peer set parameter * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_process_ll_stats_get_cmd(wmi_unified_t wmi_handle, - const struct ll_stats_get_params *get_req); -#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +QDF_STATUS +wmi_set_peer_param_send(wmi_unified_t wmi_handle, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + struct peer_set_params *param); /** - * wmi_unified_congestion_request_cmd() - send request to fw to get CCA - * @wmi_hdl: wma handle + * wmi_unified_peer_create_send() - send peer create command to fw + * @wmi_handle: wmi handle + * @peer_addr: peer mac address + * @peer_type: peer type * @vdev_id: vdev id * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_congestion_request_cmd(void *wmi_hdl, - uint8_t vdev_id); - -QDF_STATUS wmi_unified_snr_request_cmd(void *wmi_hdl); +QDF_STATUS wmi_unified_peer_create_send(wmi_unified_t wmi_handle, + struct peer_create_params *param); -QDF_STATUS wmi_unified_snr_cmd(void *wmi_hdl, uint8_t vdev_id); +QDF_STATUS wmi_unified_stats_request_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct stats_request_params *param); /** - * wmi_unified_link_status_req_cmd() - process link status request from UMAC + * wmi_unified_green_ap_ps_send() - enable green ap powersave command * @wmi_handle: wmi handle - * @params: get link status params + * @value: value + * @pdev_id: pdev id to have radio context * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_link_status_req_cmd(wmi_unified_t wmi_handle, - struct link_status_params *params); - -#ifdef WLAN_SUPPORT_GREEN_AP -QDF_STATUS wmi_unified_egap_conf_params_cmd(void *wmi_hdl, - struct wlan_green_ap_egap_params *egap_params); -#endif - -QDF_STATUS wmi_unified_csa_offload_enable(void *wmi_hdl, uint8_t vdev_id); +QDF_STATUS wmi_unified_green_ap_ps_send(wmi_unified_t wmi_handle, + uint32_t value, uint8_t pdev_id); -#ifdef WLAN_FEATURE_CIF_CFR /** - * wmi_unified_oem_dma_ring_cfg() - configure OEM DMA rings - * @wmi_handle: wmi handle - * @data_len: len of dma cfg req - * @data: dma cfg req + * wmi_unified_wow_enable_send() - WMI wow enable function + * @wmi_handle: handle to WMI. + * @param: pointer to hold wow enable parameter + * @mac_id: radio context * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_oem_dma_ring_cfg(void *wmi_hdl, - wmi_oem_dma_ring_cfg_req_fixed_param *cfg); -#endif +QDF_STATUS wmi_unified_wow_enable_send(wmi_unified_t wmi_handle, + struct wow_cmd_params *param, + uint8_t mac_id); /** - * wmi_unified_start_oem_data_cmd() - start oem data request to target - * @wmi_handle: wmi handle - * @data_len: the length of @data - * @data: the pointer to data buf - * - * This is legacy api for oem data request, using wmi command - * WMI_OEM_REQ_CMDID. + * wmi_unified_wow_wakeup_send() - WMI wow wakeup function + * @wmi_handle: handle to WMI. * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_start_oem_data_cmd(wmi_unified_t wmi_handle, - uint32_t data_len, - uint8_t *data); +QDF_STATUS wmi_unified_wow_wakeup_send(wmi_unified_t wmi_handle); -QDF_STATUS wmi_unified_dfs_phyerr_filter_offload_en_cmd(void *wmi_hdl, - bool dfs_phyerr_filter_offload); - -#ifdef CONFIG_MCL -QDF_STATUS wmi_unified_pktlog_wmi_send_cmd(void *wmi_hdl, - WMI_PKTLOG_EVENT pktlog_event, - uint32_t cmd_id, - uint8_t user_triggered); -#endif - -QDF_STATUS wmi_unified_stats_ext_req_cmd(void *wmi_hdl, - struct stats_ext_params *preq); - -QDF_STATUS wmi_unified_process_dhcpserver_offload_cmd(void *wmi_hdl, - struct dhcp_offload_info_params *params); +/** + * wmi_unified_wow_add_wakeup_event_send() - WMI wow wakeup function + * @wmi_handle: handle to WMI. + * @param: pointer to wow wakeup event parameter structure + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_wow_add_wakeup_event_send(wmi_unified_t wmi_handle, + struct wow_add_wakeup_params *param); -QDF_STATUS wmi_unified_send_regdomain_info_to_fw_cmd(void *wmi_hdl, - uint32_t reg_dmn, uint16_t regdmn2G, - uint16_t regdmn5G, uint8_t ctl2G, - uint8_t ctl5G); +/** + * wmi_unified_wow_add_wakeup_pattern_send() - WMI wow wakeup pattern function + * @wmi_handle: handle to WMI. + * @param: pointer to wow wakeup pattern parameter structure + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_wow_add_wakeup_pattern_send( + wmi_unified_t wmi_handle, + struct wow_add_wakeup_pattern_params *param); -QDF_STATUS wmi_unified_process_fw_mem_dump_cmd(void *wmi_hdl, - struct fw_dump_req_param *mem_dump_req); +/** + * wmi_unified_wow_remove_wakeup_pattern_send() - wow wakeup pattern function + * @wmi_handle: handle to WMI. + * @param: pointer to wow wakeup pattern parameter structure + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_wow_remove_wakeup_pattern_send( + wmi_unified_t wmi_handle, + struct wow_remove_wakeup_pattern_params *param); -QDF_STATUS wmi_unified_cfg_action_frm_tb_ppdu_cmd(void *wmi_hdl, - struct cfg_action_frm_tb_ppdu_param *cfg_info); +/** + * wmi_unified_packet_log_enable_send() - WMI request stats function + * @wmi_handle : handle to WMI. + * @PKTLOG_EVENT : PKTLOG Event + * @mac_id : MAC id corresponds to pdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_packet_log_enable_send(wmi_unified_t wmi_handle, + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, + uint8_t mac_id); -QDF_STATUS wmi_unified_save_fw_version_cmd(void *wmi_hdl, - void *evt_buf); +/** + * wmi_unified_peer_based_pktlog_send() - WMI request enable peer + * based filtering + * @wmi_handle: handle to WMI. + * @macaddr: PEER mac address to be filtered + * @mac_id: Mac id + * @enb_dsb: Enable or Disable peer based pktlog + * filtering + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_peer_based_pktlog_send(wmi_unified_t wmi_handle, + uint8_t *macaddr, + uint8_t mac_id, + uint8_t enb_dsb); -QDF_STATUS wmi_unified_log_supported_evt_cmd(void *wmi_hdl, - uint8_t *event, - uint32_t len); +/** + * wmi_unified_packet_log_disable__send() - WMI pktlog disable function + * @wmi_handle: handle to WMI. + * @PKTLOG_EVENT: packet log event + * + * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_packet_log_disable_send(wmi_unified_t wmi_handle, + uint8_t mac_id); -QDF_STATUS wmi_unified_enable_specific_fw_logs_cmd(void *wmi_hdl, - struct wmi_wifi_start_log *start_log); +/** + * wmi_unified_suspend_send() - WMI suspend function + * @wmi_handle: handle to WMI. + * @param: pointer to hold suspend parameter + * @mac_id: radio context + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_suspend_send(wmi_unified_t wmi_handle, + struct suspend_params *param, + uint8_t mac_id); -QDF_STATUS wmi_unified_flush_logs_to_fw_cmd(void *wmi_hdl); +/** + * wmi_unified_resume_send - WMI resume function + * @wmi_handle : handle to WMI. + * @mac_id: radio context + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_resume_send(wmi_unified_t wmi_handle, + uint8_t mac_id); -QDF_STATUS wmi_unified_unit_test_cmd(void *wmi_hdl, - struct wmi_unit_test_cmd *wmi_utest); +/** + * wmi_unified_pdev_param_send() - set pdev parameters + * @wmi_handle: wmi handle + * @param: pointer to pdev parameter + * @mac_id: radio context + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures, + * errno on failure + */ +QDF_STATUS +wmi_unified_pdev_param_send(wmi_unified_t wmi_handle, + struct pdev_params *param, + uint8_t mac_id); -#ifdef FEATURE_WLAN_APF /** - * wmi_unified_set_active_apf_mode_cmd() - config active APF mode in FW - * @wmi: the WMI handle - * @vdev_id: the Id of the vdev to apply the configuration to - * @ucast_mode: the active APF mode to configure for unicast packets - * @mcast_bcast_mode: the active APF mode to configure for multicast/broadcast - * packets + * wmi_unified_fd_tmpl_send_cmd() - WMI FILS Discovery send function + * @wmi_handle: handle to WMI. + * @param: pointer to hold FILS Discovery send cmd parameter + * + * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_set_active_apf_mode_cmd(wmi_unified_t wmi, uint8_t vdev_id, - enum wmi_host_active_apf_mode ucast_mode, - enum wmi_host_active_apf_mode - mcast_bcast_mode); +wmi_unified_fd_tmpl_send_cmd(wmi_unified_t wmi_handle, + struct fils_discovery_tmpl_params *param); /** - * wmi_unified_send_apf_enable_cmd() - send apf enable/disable cmd - * @wmi: wmi handle - * @vdev_id: VDEV id - * @enable: true: enable, false: disable + * wmi_unified_beacon_tmpl_send_cmd() - WMI beacon send function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold beacon send cmd parameter * - * This function passes the apf enable command to fw + * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_beacon_tmpl_send_cmd(wmi_unified_t wmi_handle, + struct beacon_tmpl_params *param); + +/** + * wmi_unified_peer_assoc_send() - WMI peer assoc function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to peer assoc parameter * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_apf_enable_cmd(wmi_unified_t wmi, - uint32_t vdev_id, bool enable); +QDF_STATUS wmi_unified_peer_assoc_send(wmi_unified_t wmi_handle, + struct peer_assoc_params *param); /** - * wmi_unified_send_apf_write_work_memory_cmd() - send cmd to write into the APF - * work memory. - * @wmi: wmi handle - * @write_params: parameters and buffer pointer for the write - * - * This function passes the write apf work mem command to fw + * wmi_unified_sta_ps_cmd_send() - set sta powersave parameters + * @wmi_handle: wmi handle + * @peer_addr: peer mac address + * @param: pointer to sta_ps parameter structure * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_apf_write_work_memory_cmd(wmi_unified_t wmi, - struct wmi_apf_write_memory_params *write_params); +QDF_STATUS wmi_unified_sta_ps_cmd_send(wmi_unified_t wmi_handle, + struct sta_ps_params *param); /** - * wmi_unified_send_apf_read_work_memory_cmd() - send cmd to read part of APF - * work memory - * @wmi: wmi handle - * @read_params: contains relative address and length to read from - * - * This function passes the read apf work mem command to fw + * wmi_unified_ap_ps_cmd_send() - set ap powersave parameters + * @wmi_handle: wmi handle + * @peer_addr: peer mac address + * @param: pointer to ap_ps parameter structure * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_apf_read_work_memory_cmd(wmi_unified_t wmi, - struct wmi_apf_read_memory_params *read_params); +QDF_STATUS wmi_unified_ap_ps_cmd_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct ap_ps_params *param); /** - * wmi_extract_apf_read_memory_resp_event() - exctract read mem resp event - * @wmi: wmi handle - * @evt_buf: Pointer to the event buffer - * @resp: pointer to memory to extract event parameters into - * - * This function exctracts read mem response event into the given structure ptr + * wmi_unified_scan_start_cmd_send() - WMI scan start function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold scan start cmd parameter * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_extract_apf_read_memory_resp_event(wmi_unified_t wmi, void *evt_buf, - struct wmi_apf_read_memory_resp_event_params - *read_mem_evt); -#endif /* FEATURE_WLAN_APF */ - -QDF_STATUS wmi_send_get_user_position_cmd(void *wmi_hdl, uint32_t value); - -QDF_STATUS wmi_send_get_peer_mumimo_tx_count_cmd(void *wmi_hdl, uint32_t value); - -QDF_STATUS wmi_send_reset_peer_mumimo_tx_count_cmd(void *wmi_hdl, - uint32_t value); - -QDF_STATUS wmi_unified_send_btcoex_wlan_priority_cmd(void *wmi_hdl, - struct btcoex_cfg_params *param); - -QDF_STATUS wmi_unified_send_btcoex_duty_cycle_cmd(void *wmi_hdl, - struct btcoex_cfg_params *param); - -QDF_STATUS wmi_unified_send_coex_ver_cfg_cmd(void *wmi_hdl, - coex_ver_cfg_t *param); - -QDF_STATUS wmi_unified_send_coex_config_cmd(void *wmi_hdl, - struct coex_config_params *param); - -QDF_STATUS wmi_unified_pdev_fips_cmd_send(void *wmi_hdl, - struct fips_params *param); - -QDF_STATUS wmi_unified_wlan_profile_enable_cmd_send(void *wmi_hdl, - struct wlan_profile_params *param); - -QDF_STATUS wmi_unified_wlan_profile_trigger_cmd_send(void *wmi_hdl, - struct wlan_profile_params *param); - -QDF_STATUS wmi_unified_set_chan_cmd_send(void *wmi_hdl, - struct channel_param *param); - -QDF_STATUS wmi_unified_set_ratepwr_table_cmd_send(void *wmi_hdl, - struct ratepwr_table_params *param); - -QDF_STATUS wmi_unified_get_ratepwr_table_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_set_ratepwr_chainmsk_cmd_send(void *wmi_hdl, - struct ratepwr_chainmsk_params *param); - -QDF_STATUS wmi_unified_set_macaddr_cmd_send(void *wmi_hdl, - struct macaddr_params *param); - -QDF_STATUS wmi_unified_pdev_scan_start_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_pdev_scan_end_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_set_acparams_cmd_send(void *wmi_hdl, - struct acparams_params *param); - -QDF_STATUS wmi_unified_set_vap_dscp_tid_map_cmd_send(void *wmi_hdl, - struct vap_dscp_tid_map_params *param); - -QDF_STATUS wmi_unified_proxy_ast_reserve_cmd_send(void *wmi_hdl, - struct proxy_ast_reserve_params *param); +wmi_unified_scan_start_cmd_send(wmi_unified_t wmi_handle, + struct scan_req_params *param); /** - * wmi_unified_set_bridge_mac_addr_cmd_send() - WMI set bridge mac addr cmd function - * @param wmi_hdl : handle to WMI. - * @param param : pointer to hold bridge mac addr param + * wmi_unified_scan_stop_cmd_send() - WMI scan start function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold scan start cmd parameter * - * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_set_bridge_mac_addr_cmd_send(void *wmi_hdl, - struct set_bridge_mac_addr_params *param); - - -QDF_STATUS wmi_unified_phyerr_enable_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_phyerr_enable_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_phyerr_disable_cmd_send(void *wmi_hdl); - -QDF_STATUS wmi_unified_smart_ant_enable_tx_feedback_cmd_send(void *wmi_hdl, - struct smart_ant_enable_tx_feedback_params *param); - -QDF_STATUS wmi_unified_vdev_spectral_configure_cmd_send(void *wmi_hdl, - struct vdev_spectral_configure_params *param); - -QDF_STATUS wmi_unified_vdev_spectral_enable_cmd_send(void *wmi_hdl, - struct vdev_spectral_enable_params *param); - -QDF_STATUS wmi_unified_bss_chan_info_request_cmd_send(void *wmi_hdl, - struct bss_chan_info_request_params *param); +QDF_STATUS +wmi_unified_scan_stop_cmd_send(wmi_unified_t wmi_handle, + struct scan_cancel_param *param); -QDF_STATUS wmi_unified_thermal_mitigation_param_cmd_send(void *wmi_hdl, - struct thermal_mitigation_params *param); +/** + * wmi_unified_scan_chan_list_cmd_send() - WMI scan channel list function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold scan channel list parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_scan_chan_list_cmd_send(wmi_unified_t wmi_handle, + struct scan_chan_list_params *param); -QDF_STATUS wmi_unified_vdev_set_fwtest_param_cmd_send(void *wmi_hdl, - struct set_fwtest_params *param); /** - * wmi_unified_vdev_set_custom_aggr_size_cmd_send() - WMI set custom aggr - * size command - * @param wmi_hdl : handle to WMI. - * @param param : pointer to hold custom aggr size param + * wmi_crash_inject() - inject fw crash + * @wmi_handle: wmi handle + * @param: ponirt to crash inject parameter structure * - * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_vdev_set_custom_aggr_size_cmd_send(void *wmi_hdl, - struct set_custom_aggr_size_params *param); +QDF_STATUS wmi_crash_inject(wmi_unified_t wmi_handle, + struct crash_inject *param); /** - * wmi_unified_vdev_set_qdepth_thresh_cmd_send() - WMI set qdepth threshold - * @param wmi_hdl : handle to WMI. - * @param param : pointer to hold set qdepth thresh param + * wmi_unified_pdev_utf_cmd() - send utf command to fw + * @wmi_handle: wmi handle + * @param: pointer to pdev_utf_params + * @mac_id: mac id to have radio context * - * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_vdev_set_qdepth_thresh_cmd_send(void *wmi_hdl, - struct set_qdepth_thresh_params *param); - -QDF_STATUS wmi_unified_pdev_set_regdomain_cmd_send(void *wmi_hdl, - struct pdev_set_regdomain_params *param); - -QDF_STATUS wmi_unified_set_beacon_filter_cmd_send(void *wmi_hdl, - struct set_beacon_filter_params *param); - -QDF_STATUS wmi_unified_remove_beacon_filter_cmd_send(void *wmi_hdl, - struct remove_beacon_filter_params *param); +QDF_STATUS wmi_unified_pdev_utf_cmd_send(wmi_unified_t wmi_handle, + struct pdev_utf_params *param, + uint8_t mac_id); -QDF_STATUS wmi_unified_addba_clearresponse_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct addba_clearresponse_params *param); - -QDF_STATUS wmi_unified_addba_send_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct addba_send_params *param); - -QDF_STATUS wmi_unified_delba_send_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct delba_send_params *param); - -QDF_STATUS wmi_unified_addba_setresponse_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct addba_setresponse_params *param); - -QDF_STATUS wmi_unified_singleamsdu_cmd_send(void *wmi_hdl, - uint8_t macaddr[QDF_MAC_ADDR_SIZE], - struct singleamsdu_params *param); - -QDF_STATUS wmi_unified_mu_scan_cmd_send(void *wmi_hdl, - struct mu_scan_params *param); - -QDF_STATUS wmi_unified_lteu_config_cmd_send(void *wmi_hdl, - struct lteu_config_params *param); - -QDF_STATUS wmi_unified_set_psmode_cmd_send(void *wmi_hdl, - struct set_ps_mode_params *param); +#ifdef FEATURE_FW_LOG_PARSING +/** + * wmi_unified_dbglog_cmd_send() - set debug log level + * @wmi_handle: handle to WMI. + * @param: pointer to hold dbglog level parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_dbglog_cmd_send(wmi_unified_t wmi_handle, + struct dbglog_params *param); +#else +static inline QDF_STATUS +wmi_unified_dbglog_cmd_send(wmi_unified_t wmi_handle, + struct dbglog_params *param) +{ + return QDF_STATUS_SUCCESS; +} +#endif -QDF_STATUS wmi_unified_init_cmd_send(void *wmi_hdl, - struct wmi_init_cmd_param *param); +/** + * wmi_mgmt_unified_cmd_send() - management cmd over wmi layer + * @wmi_handle: handle to WMI. + * @param: pointer to hold mgmt cmd parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_mgmt_unified_cmd_send(wmi_unified_t wmi_handle, + struct wmi_mgmt_params *param); -bool wmi_service_enabled(void *wmi_hdl, uint32_t service_id); +/** + * wmi_offchan_data_tx_cmd_send() - Send offchan data tx cmd over wmi layer + * @wmi_handle: handle to WMI. + * @param: pointer to hold offchan data cmd parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_offchan_data_tx_cmd_send( + wmi_unified_t wmi_handle, + struct wmi_offchan_data_tx_params *param); /** - * wmi_save_service_bitmap() - save service bitmap + * wmi_unified_modem_power_state() - set modem power state to fw * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer + * @param_value: parameter value * - * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf, - void *bitmap_buf); +QDF_STATUS wmi_unified_modem_power_state(wmi_unified_t wmi_handle, + uint32_t param_value); /** - * wmi_save_ext_service_bitmap() - save extended service bitmap + * wmi_unified_set_sta_ps_mode() - set sta powersave params in fw * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer + * @vdev_id: vdev id + * @val: value * - * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. */ -QDF_STATUS wmi_save_ext_service_bitmap(void *wmi_hdl, void *evt_buf, - void *bitmap_buf); +QDF_STATUS wmi_unified_set_sta_ps_mode(wmi_unified_t wmi_handle, + uint32_t vdev_id, + uint8_t val); -QDF_STATUS wmi_save_fw_version(void *wmi_hdl, void *evt_buf); +/** + * wmi_unified_set_sta_uapsd_auto_trig_cmd() - set uapsd auto trigger command + * @wmi_handle: wmi handle + * @param: uapsd cmd parameter strcture + * + * This function sets the trigger + * uapsd params such as service interval, delay interval + * and suspend interval which will be used by the firmware + * to send trigger frames periodically when there is no + * traffic on the transmit side. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS +wmi_unified_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle, + struct sta_uapsd_trig_params *param); -QDF_STATUS wmi_get_target_cap_from_service_ready(void *wmi_hdl, - void *evt_buf, - struct wlan_psoc_target_capability_info *ev); +/** + * wmi_get_temperature() - get pdev temperature req + * @wmi_handle: wmi handle + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS wmi_unified_get_temperature(wmi_unified_t wmi_handle); -QDF_STATUS wmi_extract_hal_reg_cap(void *wmi_hdl, void *evt_buf, - struct wlan_psoc_hal_reg_capability *hal_reg_cap); +/** + * wmi_set_smps_params() - set smps params + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @value: value + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS wmi_unified_set_smps_params(wmi_unified_t wmi_handle, + uint8_t vdev_id, + int value); -host_mem_req *wmi_extract_host_mem_req_from_service_ready(void *wmi_hdl, - void *evt_buf, uint8_t *num_entries); +/** + * wmi_set_mimops() - set MIMO powersave + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @value: value + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS wmi_unified_set_mimops(wmi_unified_t wmi_handle, + uint8_t vdev_id, int value); -uint32_t wmi_ready_extract_init_status(void *wmi_hdl, void *ev); +/** + * wmi_unified_lro_config_cmd() - process the LRO config command + * @wmi_handle: Pointer to wmi handle + * @wmi_lro_cmd: Pointer to LRO configuration parameters + * + * This function sends down the LRO configuration parameters to + * the firmware to enable LRO, sets the TCP flags and sets the + * seed values for the toeplitz hash generation + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_lro_config_cmd(wmi_unified_t wmi_handle, + struct wmi_lro_config_cmd_t *wmi_lro_cmd); -QDF_STATUS wmi_ready_extract_mac_addr(void *wmi_hdl, - void *ev, uint8_t *macaddr); +/** + * wmi_unified_set_thermal_mgmt_cmd() - set thermal mgmt command to fw + * @wmi_handle: Pointer to wmi handle + * @thermal_info: Thermal command information + * + * This function sends the thermal management command + * to the firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_thermal_mgmt_cmd(wmi_unified_t wmi_handle, + struct thermal_cmd_params *thermal_info); -wmi_host_mac_addr *wmi_ready_extract_mac_addr_list(void *wmi_hdl, void *ev, - uint8_t *num_mac_addr); +/** + * wmi_unified_peer_rate_report_cmd() - process the peer rate report command + * @wmi_handle: Pointer to wmi handle + * @rate_report_params: Pointer to peer rate report parameters + * + * + * Return: QDF_STATUS_SUCCESS for success otherwise failure + */ +QDF_STATUS +wmi_unified_peer_rate_report_cmd( + wmi_unified_t wmi_handle, + struct wmi_peer_rate_report_params *rate_report_params); /** - * wmi_extract_ready_params() - Extract data from ready event apart from - * status, macaddr and version. - * @wmi_handle: Pointer to WMI handle. - * @evt_buf: Pointer to Ready event buffer. - * @ev_param: Pointer to host defined struct to copy the data from event. + * wmi_unified_process_update_edca_param() - update EDCA params + * @wmi_handle: wmi handle + * @vdev_id: vdev id. + * @mu_edca_param: mu_edca_param. + * @wmm_vparams: edca parameters * - * Return: QDF_STATUS_SUCCESS on success. + * This function updates EDCA parameters to the target + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_ready_event_params(void *wmi_hdl, - void *evt_buf, struct wmi_host_ready_ev_param *ev_param); +QDF_STATUS +wmi_unified_process_update_edca_param( + wmi_unified_t wmi_handle, + uint8_t vdev_id, + bool mu_edca_param, + struct wmi_host_wme_vparams wmm_vparams[WMI_MAX_NUM_AC]); -QDF_STATUS wmi_extract_fw_version(void *wmi_hdl, - void *ev, struct wmi_host_fw_ver *fw_ver); +/** + * wmi_unified_probe_rsp_tmpl_send_cmd() - send probe response template to fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @probe_rsp_info: probe response info + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_probe_rsp_tmpl_send_cmd( + wmi_unified_t wmi_handle, + uint8_t vdev_id, + struct wmi_probe_resp_params *probe_rsp_info); + +/** + * wmi_unified_setup_install_key_cmd - send key to install to fw + * @wmi_handle: wmi handle + * @key_params: key parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_setup_install_key_cmd(wmi_unified_t wmi_handle, + struct set_key_params *key_params); + +/** + * wmi_unified_get_pn_send_cmd() - send command to fw get PN for peer + * @wmi_handle: wmi handle + * @pn_params: PN parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_get_pn_send_cmd(wmi_unified_t wmi_hdl, + struct peer_request_pn_param *pn_params); + +/** + * wmi_unified_p2p_go_set_beacon_ie_cmd() - set beacon IE for p2p go + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @p2p_ie: p2p IE + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_p2p_go_set_beacon_ie_cmd(wmi_unified_t wmi_hdl, + uint32_t vdev_id, + uint8_t *p2p_ie); + +/** + * wmi_unified_scan_probe_setoui_cmd() - set scan probe OUI + * @wmi_handle: wmi handle + * @psetoui: OUI parameters + * + * set scan probe OUI parameters in firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_scan_probe_setoui_cmd(wmi_unified_t wmi_handle, + struct scan_mac_oui *psetoui); + +#ifdef IPA_OFFLOAD +/** wmi_unified_ipa_offload_control_cmd() - ipa offload control parameter + * @wmi_handle: wmi handle + * @ipa_offload: ipa offload control parameter + * + * Returns: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures, + * error number otherwise + */ +QDF_STATUS +wmi_unified_ipa_offload_control_cmd( + wmi_unified_t wmi_handle, + struct ipa_uc_offload_control_params *ipa_offload); +#endif + +/** + * wmi_unified_pno_stop_cmd() - PNO stop request + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * This function request FW to stop ongoing PNO operation. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pno_stop_cmd(wmi_unified_t wmi_handle, uint8_t vdev_id); + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + * wmi_unified_pno_start_cmd() - PNO start request + * @wmi_handle: wmi handle + * @pno: PNO request + * + * This function request FW to start PNO request. + * Request: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pno_start_cmd(wmi_unified_t wmi_handle, + struct pno_scan_req_params *pno); +#endif + +/** + * wmi_unified_nlo_mawc_cmd() - NLO MAWC cmd configuration + * @wmi_handle: wmi handle + * @params: Configuration parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_nlo_mawc_cmd(wmi_unified_t wmi_handle, + struct nlo_mawc_params *params); + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/** + * wmi_unified_process_ll_stats_clear_cmd() - clear link layer stats + * @wmi_handle: wmi handle + * @clear_req: ll stats clear request command params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_process_ll_stats_clear_cmd(wmi_unified_t wmi_handle, + const struct ll_stats_clear_params *clear_req); + +/** + * wmi_unified_process_ll_stats_set_cmd() - link layer stats set request + * @wmi_handle: wmi handle + * @set_req: ll stats set request command params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_process_ll_stats_set_cmd(wmi_unified_t wmi_handle, + const struct ll_stats_set_params *set_req); + +/** + * wmi_unified_process_ll_stats_get_cmd() - link layer stats get request + * @wmi_handle: wmi handle + * @get_req: ll stats get request command params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_process_ll_stats_get_cmd(wmi_unified_t wmi_handle, + const struct ll_stats_get_params *get_req); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/** + * wmi_unified_congestion_request_cmd() - send request to fw to get CCA + * @wmi_handle: wma handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_congestion_request_cmd(wmi_unified_t wmi_handle, + uint8_t vdev_id); + +/** + * wmi_unified_snr_request_cmd() - send request to fw to get RSSI stats + * @wmi_handle: wmi handle + * @rssi_req: get RSSI request + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_snr_request_cmd(wmi_unified_t wmi_handle); + +/** + * wmi_unified_snr_cmd() - get RSSI from fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_snr_cmd(wmi_unified_t wmi_handle, uint8_t vdev_id); + +/** + * wmi_unified_link_status_req_cmd() - process link status request from UMAC + * @wmi_handle: wmi handle + * @params: get link status params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_link_status_req_cmd(wmi_unified_t wmi_handle, + struct link_status_params *params); + +#ifdef WLAN_SUPPORT_GREEN_AP +/** + * wmi_unified_egap_conf_params_cmd() - send wmi cmd of egap config params + * @wmi_handle: wmi handler + * @egap_params: pointer to egap_params + * + * Return: 0 for success, otherwise appropriate error code + */ +QDF_STATUS +wmi_unified_egap_conf_params_cmd( + wmi_unified_t wmi_handle, + struct wlan_green_ap_egap_params *egap_params); +#endif + +/** + * wmi_unified_csa_offload_enable() - send CSA offload enable command + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_csa_offload_enable(wmi_unified_t wmi_handle, + uint8_t vdev_id); + +#ifdef WLAN_FEATURE_CIF_CFR +/** + * wmi_unified_oem_dma_ring_cfg() - configure OEM DMA rings + * @wmi_handle: wmi handle + * @data_len: len of dma cfg req + * @data: dma cfg req + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_oem_dma_ring_cfg(wmi_unified_t wmi_handle, + wmi_oem_dma_ring_cfg_req_fixed_param *cfg); +#endif + +/** + * wmi_unified_start_oem_data_cmd() - start oem data request to target + * @wmi_handle: wmi handle + * @data_len: the length of @data + * @data: the pointer to data buf + * + * This is legacy api for oem data request, using wmi command + * WMI_OEM_REQ_CMDID. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_start_oem_data_cmd(wmi_unified_t wmi_handle, + uint32_t data_len, + uint8_t *data); + +#ifdef FEATURE_OEM_DATA +/** + * wmi_unified_start_oemv2_data_cmd() - start oem data cmd to target + * @wmi_handle: wmi handle + * @params: oem data params + * + * This is common api for oem data, using wmi command WMI_OEM_DATA_CMDID. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_start_oemv2_data_cmd(wmi_unified_t wmi_handle, + struct oem_data *params); +#endif + +/** + * wmi_unified_dfs_phyerr_filter_offload_en_cmd() - enable dfs phyerr filter + * @wmi_handle: wmi handle + * @dfs_phyerr_filter_offload: is dfs phyerr filter offload + * + * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or + * WMI_DFS_PHYERR_FILTER_DIS_CMDID command + * to firmware based on phyerr filtering + * offload status. + * + * Return: 1 success, 0 failure + */ +QDF_STATUS +wmi_unified_dfs_phyerr_filter_offload_en_cmd(wmi_unified_t wmi_handle, + bool dfs_phyerr_filter_offload); + +#if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) +/** + * wmi_unified_pktlog_wmi_send_cmd() - send pktlog event command to target + * @wmi_handle: wmi handle + * @pktlog_event: pktlog event + * @cmd_id: pktlog cmd id + * @user_triggered: user triggered input for PKTLOG enable mode + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pktlog_wmi_send_cmd(wmi_unified_t wmi_handle, + WMI_PKTLOG_EVENT pktlog_event, + uint32_t cmd_id, + uint8_t user_triggered); +#endif + +/** + * wmi_unified_stats_ext_req_cmd() - request ext stats from fw + * @wmi_handle: wmi handle + * @preq: stats ext params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_stats_ext_req_cmd(wmi_unified_t wmi_handle, + struct stats_ext_params *preq); + +/** + * wmi_unified_process_dhcpserver_offload_cmd() - enable DHCP server offload + * @wmi_handle: wmi handle + * @pDhcpSrvOffloadInfo: DHCP server offload info + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_process_dhcpserver_offload_cmd( + wmi_unified_t wmi_handle, + struct dhcp_offload_info_params *params); + +/** + * wmi_unified_send_regdomain_info_to_fw_cmd() - send regdomain info to fw + * @wmi_handle: wmi handle + * @reg_dmn: reg domain + * @regdmn2G: 2G reg domain + * @regdmn5G: 5G reg domain + * @ctl2G: 2G test limit + * @ctl5G: 5G test limit + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_send_regdomain_info_to_fw_cmd(wmi_unified_t wmi_handle, + uint32_t reg_dmn, + uint16_t regdmn2G, + uint16_t regdmn5G, + uint8_t ctl2G, + uint8_t ctl5G); + +QDF_STATUS +wmi_unified_process_fw_mem_dump_cmd(wmi_unified_t wmi_hdl, + struct fw_dump_req_param *mem_dump_req); + +/** + * wmi_unified_cfg_action_frm_tb_ppdu_cmd()-send action frame TB PPDU cfg to FW + * @wmi_handle: Pointer to WMi handle + * @cfg_info: Pointer to cfg msg + * + * This function sends action frame TB PPDU cfg to firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * + */ +QDF_STATUS +wmi_unified_cfg_action_frm_tb_ppdu_cmd( + wmi_unified_t wmi_handle, + struct cfg_action_frm_tb_ppdu_param *cfg_info); + +/** + * wmi_unified_save_fw_version_cmd() - save fw version + * @wmi_handle: pointer to wmi handle + * @evt_buf: Event buffer + * + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + * + */ +QDF_STATUS wmi_unified_save_fw_version_cmd(wmi_unified_t wmi_handle, + void *evt_buf); + +/** + * wmi_unified_log_supported_evt_cmd() - Enable/Disable FW diag/log events + * @wmi_handle: wmi handle + * @event: Event received from FW + * @len: Length of the event + * + * Enables the low frequency events and disables the high frequency + * events. Bit 17 indicates if the event if low/high frequency. + * 1 - high frequency, 0 - low frequency + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures + */ +QDF_STATUS wmi_unified_log_supported_evt_cmd(wmi_unified_t wmi_handle, + uint8_t *event, + uint32_t len); + +/** + * wmi_unified_enable_specific_fw_logs_cmd() - Start/Stop logging of diag log id + * @wmi_handle: wmi handle + * @start_log: Start logging related parameters + * + * Send the command to the FW based on which specific logging of diag + * event/log id can be started/stopped + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_enable_specific_fw_logs_cmd(wmi_unified_t wmi_handle, + struct wmi_wifi_start_log *start_log); + +/** + * wmi_unified_flush_logs_to_fw_cmd() - Send log flush command to FW + * @wmi_handle: WMI handle + * + * This function is used to send the flush command to the FW, + * that will flush the fw logs that are residue in the FW + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_flush_logs_to_fw_cmd(wmi_unified_t wmi_handle); + +/** + * wmi_unified_unit_test_cmd() - send unit test command to fw. + * @wmi_handle: wmi handle + * @wmi_utest: unit test command + * + * This function send unit test command to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_unit_test_cmd(wmi_unified_t wmi_handle, + struct wmi_unit_test_cmd *wmi_utest); + +#ifdef FEATURE_WLAN_APF +/** + * wmi_unified_set_active_apf_mode_cmd() - config active APF mode in FW + * @wmi: the WMI handle + * @vdev_id: the Id of the vdev to apply the configuration to + * @ucast_mode: the active APF mode to configure for unicast packets + * @mcast_bcast_mode: the active APF mode to configure for multicast/broadcast + * packets + */ +QDF_STATUS +wmi_unified_set_active_apf_mode_cmd(wmi_unified_t wmi, uint8_t vdev_id, + enum wmi_host_active_apf_mode ucast_mode, + enum wmi_host_active_apf_mode + mcast_bcast_mode); + +/** + * wmi_unified_send_apf_enable_cmd() - send apf enable/disable cmd + * @wmi: wmi handle + * @vdev_id: VDEV id + * @enable: true: enable, false: disable + * + * This function passes the apf enable command to fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_send_apf_enable_cmd(wmi_unified_t wmi, + uint32_t vdev_id, bool enable); + +/** + * wmi_unified_send_apf_write_work_memory_cmd() - send cmd to write into the APF + * work memory. + * @wmi: wmi handle + * @write_params: parameters and buffer pointer for the write + * + * This function passes the write apf work mem command to fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_send_apf_write_work_memory_cmd(wmi_unified_t wmi, + struct wmi_apf_write_memory_params *write_params); + +/** + * wmi_unified_send_apf_read_work_memory_cmd() - send cmd to read part of APF + * work memory + * @wmi: wmi handle + * @read_params: contains relative address and length to read from + * + * This function passes the read apf work mem command to fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_send_apf_read_work_memory_cmd(wmi_unified_t wmi, + struct wmi_apf_read_memory_params *read_params); + +/** + * wmi_extract_apf_read_memory_resp_event() - exctract read mem resp event + * @wmi: wmi handle + * @evt_buf: Pointer to the event buffer + * @resp: pointer to memory to extract event parameters into + * + * This function exctracts read mem response event into the given structure ptr + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_apf_read_memory_resp_event(wmi_unified_t wmi, void *evt_buf, + struct wmi_apf_read_memory_resp_event_params + *read_mem_evt); +#endif /* FEATURE_WLAN_APF */ + +/** + * wmi_send_get_user_position_cmd() - send get user position command to fw + * @wmi_handle: wmi handle + * @value: user pos value + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_send_get_user_position_cmd(wmi_unified_t wmi_handle, uint32_t value); + +/** + * wmi_send_get_peer_mumimo_tx_count_cmd() - send get mumio tx count + * command to fw + * @wmi_handle: wmi handle + * @value: user pos value + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_send_get_peer_mumimo_tx_count_cmd(wmi_unified_t wmi_handle, + uint32_t value); + +/** + * wmi_send_reset_peer_mumimo_tx_count_cmd() - send reset peer mumimo + * tx count to fw + * @wmi_handle: wmi handle + * @value: reset tx count value + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_send_reset_peer_mumimo_tx_count_cmd(wmi_unified_t wmi_handle, + uint32_t value); + +/* + * wmi_unified_send_btcoex_wlan_priority_cmd() - send btcoex priority commands + * @wmi_handle: wmi handle + * @param: wmi btcoex cfg params + * + * Send WMI_BTCOEX_CFG_CMDID parameters to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_unified_send_btcoex_wlan_priority_cmd(wmi_unified_t wmi_handle, + struct btcoex_cfg_params *param); + +/** + * wmi_unified_send_btcoex_duty_cycle_cmd() - send btcoex duty cycle commands + * @wmi_handle: wmi handle + * @param: wmi btcoex cfg params + * + * Send WMI_BTCOEX_CFG_CMDID parameters to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_unified_send_btcoex_duty_cycle_cmd(wmi_unified_t wmi_handle, + struct btcoex_cfg_params *param); + +/** + * wmi_unified_send_coex_ver_cfg_cmd() - send coex ver cfg command + * @wmi_handle: wmi handle + * @param: wmi coex ver cfg params + * + * Send WMI_COEX_VERSION_CFG_CMID parameters to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_unified_send_coex_ver_cfg_cmd(wmi_unified_t wmi_handle, + coex_ver_cfg_t *param); + +/** + * wmi_unified_send_coex_config_cmd() - send coex ver cfg command + * @wmi_handle: wmi handle + * @param: wmi coex cfg cmd params + * + * Send WMI_COEX_CFG_CMD parameters to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_unified_send_coex_config_cmd(wmi_unified_t wmi_handle, + struct coex_config_params *param); + +/** + * wmi_unified_pdev_fips_cmd_send() - WMI pdev fips cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold pdev fips param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_pdev_fips_cmd_send(wmi_unified_t wmi_handle, + struct fips_params *param); + +#ifdef WLAN_FEATURE_DISA +/** + * wmi_unified_encrypt_decrypt_send_cmd() - send encryptdecrypt cmd to fw + * @wmi_handle: wmi handle + * @params: encrypt/decrypt params + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_encrypt_decrypt_send_cmd(void *wmi_hdl, + struct disa_encrypt_decrypt_req_params + *params); +#endif /* WLAN_FEATURE_DISA */ + +/** + * wmi_unified_wlan_profile_enable_cmd_send() - WMI wlan profile enable + * cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold wlan profile param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_wlan_profile_enable_cmd_send(wmi_unified_t wmi_handle, + struct wlan_profile_params *param); + +/** + * wmi_unified_wlan_profile_trigger_cmd_send() - WMI wlan profile trigger + * cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold wlan profile param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_wlan_profile_trigger_cmd_send(wmi_unified_t wmi_handle, + struct wlan_profile_params *param); + +/** + * wmi_unified_set_chan_cmd_send() - WMI set channel cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold channel param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_chan_cmd_send(wmi_unified_t wmi_handle, + struct channel_param *param); + +/** + * wmi_unified_set_ratepwr_table_cmd_send() - WMI ratepwr table cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold ratepwr table param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_ratepwr_table_cmd_send(wmi_unified_t wmi_handle, + struct ratepwr_table_params *param); + +/** + * wmi_unified_get_ratepwr_table_cmd_send() - WMI ratepwr table cmd function + * @wmi_handle: handle to WMI. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_get_ratepwr_table_cmd_send(wmi_unified_t wmi_handle); + +/** + * wmi_unified_set_ratepwr_chainmsk_cmd_send() - WMI ratepwr + * chainmsk cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold ratepwr chainmsk param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_ratepwr_chainmsk_cmd_send(wmi_unified_t wmi_handle, + struct ratepwr_chainmsk_params + *param); + +/** + * wmi_unified_set_macaddr_cmd_send() - WMI set macaddr cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold macaddr param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_set_macaddr_cmd_send(wmi_unified_t wmi_handle, + struct macaddr_params *param); + +/** + * wmi_unified_pdev_scan_start_cmd_send() - WMI pdev scan start cmd function + * @wmi_handle: handle to WMI. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pdev_scan_start_cmd_send(wmi_unified_t wmi_handle); + +/** + * wmi_unified_pdev_scan_end_cmd_send() - WMI pdev scan end cmd function + * @wmi_handle: handle to WMI. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pdev_scan_end_cmd_send(wmi_unified_t wmi_handle); + +/** + * wmi_unified_set_acparams_cmd_send() - WMI set acparams cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold acparams param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_acparams_cmd_send(wmi_unified_t wmi_handle, + struct acparams_params *param); + +/** + * wmi_unified_set_vap_dscp_tid_map_cmd_send() - WMI set vap dscp + * tid map cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold dscp param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_vap_dscp_tid_map_cmd_send( + wmi_unified_t wmi_handle, + struct vap_dscp_tid_map_params *param); + +/** + * wmi_unified_proxy_ast_reserve_cmd_send() - WMI proxy ast + * reserve cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold ast param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_proxy_ast_reserve_cmd_send(wmi_unified_t wmi_handle, + struct proxy_ast_reserve_params *param); + +/** + * wmi_unified_set_bridge_mac_addr_cmd_send() - WMI set bridge mac + * addr cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold bridge mac addr param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_set_bridge_mac_addr_cmd_send( + wmi_unified_t wmi_handle, + struct set_bridge_mac_addr_params *param); + +/** + * wmi_unified_phyerr_enable_cmd_send() - WMI phyerr enable cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold phyerr enable param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_phyerr_enable_cmd_send(wmi_unified_t wmi_handle); + +/** + * wmi_unified_phyerr_disable_cmd_send() - WMI phyerr disable cmd function + * @wmi_handle: handle to WMI. + * @param: pointer to hold phyerr disable param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_phyerr_disable_cmd_send(wmi_unified_t wmi_handle); + +/** + * wmi_unified_smart_ant_enable_tx_feedback_cmd_send() - + * WMI set tx antenna function + * @wmi_handle: handle to WMI. + * @param: pointer to hold antenna param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_smart_ant_enable_tx_feedback_cmd_send( + wmi_unified_t wmi_handle, + struct smart_ant_enable_tx_feedback_params *param); + +/** + * wmi_unified_vdev_spectral_configure_cmd_send() - + * WMI set spectral config function + * @wmi_handle: handle to WMI. + * @param: pointer to hold spectral config param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_spectral_configure_cmd_send( + wmi_unified_t wmi_handle, + struct vdev_spectral_configure_params *param); + +/** + * wmi_unified_vdev_spectral_enable_cmd_send() - WMI enable spectral function + * @wmi_handle: handle to WMI. + * @param: pointer to hold enable spectral param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_spectral_enable_cmd_send( + wmi_unified_t wmi_handle, + struct vdev_spectral_enable_params *param); + +#if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) +/** + * wmi_unified_vdev_fils_enable_cmd_send() - WMI send fils enable command + * @param wmi_handle: handle to WMI. + * @param config_fils_params: fils enable parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_vdev_fils_enable_cmd_send(struct wmi_unified *wmi_handle, + struct config_fils_params *param); +#endif + +/** + * wmi_unified_bss_chan_info_request_cmd_send() - WMI bss chan info + * request function + * @wmi_handle: handle to WMI. + * @param: pointer to hold chan info param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_bss_chan_info_request_cmd_send( + wmi_unified_t wmi_handle, + struct bss_chan_info_request_params *param); + +/** + * wmi_unified_thermal_mitigation_param_cmd_send() - + * WMI thermal mitigation function + * @wmi_handle: handle to WMI. + * @param: pointer to hold thermal mitigation param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_thermal_mitigation_param_cmd_send( + wmi_unified_t wmi_handle, + struct thermal_mitigation_params *param); + +/** + * wmi_unified_vdev_set_fwtest_param_cmd_send() - WMI set fwtest function + * @wmi_handle: handle to WMI. + * @param: pointer to hold fwtest param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_set_fwtest_param_cmd_send( + wmi_unified_t wmi_handle, + struct set_fwtest_params *param); + +/** + * wmi_unified_vdev_set_custom_aggr_size_cmd_send() - WMI set custom aggr + * size command + * @wmi_handle: handle to WMI. + * @param: pointer to hold custom aggr size param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_set_custom_aggr_size_cmd_send( + wmi_unified_t wmi_handle, + struct set_custom_aggr_size_params *param); + +/** + * wmi_unified_vdev_set_qdepth_thresh_cmd_send() - WMI set qdepth threshold + * @wmi_handle: handle to WMI. + * @param: pointer to hold set qdepth thresh param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_vdev_set_qdepth_thresh_cmd_send( + wmi_unified_t wmi_handle, + struct set_qdepth_thresh_params *param); + +/** + * wmi_unified_pdev_set_regdomain_params_cmd_send() - WMI set regdomain + * function + * @wmi_handle: handle to WMI. + * @param: pointer to hold regdomain param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_pdev_set_regdomain_cmd_send( + wmi_unified_t wmi_handle, + struct pdev_set_regdomain_params *param); + +/** + * wmi_unified_set_beacon_filter_cmd_send() - WMI set beacon filter function + * @wmi_handle: handle to WMI. + * @param: pointer to hold beacon filter param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_set_beacon_filter_cmd_send( + wmi_unified_t wmi_handle, + struct set_beacon_filter_params *param); + +/** + * wmi_unified_remove_beacon_filter_cmd_send() - WMI set beacon filter function + * @wmi_handle: handle to WMI. + * @param: pointer to hold beacon filter param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_remove_beacon_filter_cmd_send( + wmi_unified_t wmi_handle, + struct remove_beacon_filter_params *param); + +/** + * wmi_unified_addba_clearresponse_cmd_send() - WMI addba resp cmd function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold addba resp parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_addba_clearresponse_cmd_send( + wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct addba_clearresponse_params *param); + +/** + * wmi_unified_addba_send_cmd_send() - WMI addba send function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold addba parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_addba_send_cmd_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct addba_send_params *param); + +/** + * wmi_unified_delba_send_cmd_send() - WMI delba cmd function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold delba parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_delba_send_cmd_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct delba_send_params *param); + +/** + * wmi_unified_addba_setresponse_cmd_send() - WMI addba set resp cmd function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold addba set resp parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_addba_setresponse_cmd_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct addba_setresponse_params *param); + +/** + * wmi_unified_singleamsdu_cmd_send() - WMI singleamsdu function + * @wmi_handle: handle to WMI. + * @macaddr: MAC address + * @param: pointer to hold singleamsdu parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_singleamsdu_cmd_send(wmi_unified_t wmi_handle, + uint8_t macaddr[QDF_MAC_ADDR_SIZE], + struct singleamsdu_params *param); + +/** + * wmi_unified_mu_scan_cmd_send() - WMI set mu scan function + * @wmi_handle: handle to WMI. + * @param: pointer to hold mu scan param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_mu_scan_cmd_send(wmi_unified_t wmi_handle, + struct mu_scan_params *param); + +/** + * wmi_unified_lteu_config_cmd_send() - WMI set mu scan function + * @wmi_handle: handle to WMI. + * @param: pointer to hold mu scan param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_lteu_config_cmd_send(wmi_unified_t wmi_handle, + struct lteu_config_params *param); + +/** + * wmi_unified_set_psmode_cmd_send() - WMI set mu scan function + * @wmi_handle: handle to WMI. + * @param: pointer to hold mu scan param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_set_psmode_cmd_send(wmi_unified_t wmi_handle, + struct set_ps_mode_params *param); + +/** + * wmi_unified_init_cmd_send() - send initialization cmd to fw + * @wmi_handle: wmi handle + * @param: pointer to wmi init param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_init_cmd_send(wmi_unified_t wmi_handle, + struct wmi_init_cmd_param *param); + +/** + * wmi_service_enabled() - Check if service enabled + * @wmi_handle: wmi handle + * @service_id: service identifier + * + * Return: 1 enabled, 0 disabled + */ +bool wmi_service_enabled(wmi_unified_t wmi_handle, uint32_t service_id); + +/** + * wmi_save_service_bitmap() - save service bitmap + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @bitmap_buf: bitmap buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + */ +QDF_STATUS wmi_save_service_bitmap(wmi_unified_t wmi_handle, void *evt_buf, + void *bitmap_buf); + +/** + * wmi_save_ext_service_bitmap() - save extended service bitmap + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code + */ +QDF_STATUS wmi_save_ext_service_bitmap(wmi_unified_t wmi_handle, void *evt_buf, + void *bitmap_buf); + +/** + * wmi_save_fw_version() - Save fw version + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_save_fw_version(wmi_unified_t wmi_handle, void *evt_buf); + +/** + * wmi_get_target_cap_from_service_ready() - extract service ready event + * @wmi_handle: wmi handle + * @evt_buf: pointer to received event buffer + * @ev: pointer to hold target capability information extracted from even + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_get_target_cap_from_service_ready( + wmi_unified_t wmi_handle, void *evt_buf, + struct wlan_psoc_target_capability_info *ev); + +/** + * wmi_extract_hal_reg_cap() - extract HAL registered capabilities + * @wmi_handle: wmi handle + * @evt_buf: Pointer to event buffer + * @hal_reg_cap: pointer to hold HAL reg capabilities + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_hal_reg_cap(wmi_unified_t wmi_handle, void *evt_buf, + struct wlan_psoc_hal_reg_capability *hal_reg_cap); + +/** + * wmi_extract_num_mem_reqs_from_service_ready() - Extract number of memory + * entries requested + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * + * Return: Number of entries requested + */ +uint32_t wmi_extract_num_mem_reqs_from_service_ready( + wmi_unified_t wmi_handle, + void *evt_buf); + +/** + * wmi_extract_host_mem_req_from_service_ready() - Extract host memory + * request event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @mem_reqs: pointer to host memory request structure + * @num_active_peers: number of active peers for peer cache + * @num_peers: number of peers + * @fw_prio: FW priority + * @idx: Index for memory request + * + * Return: Host memory request parameters requested by target + */ +QDF_STATUS wmi_extract_host_mem_req_from_service_ready( + wmi_unified_t wmi_handle, void *evt_buf, host_mem_req *mem_reqs, + uint32_t num_active_peers, uint32_t num_peers, + enum wmi_fw_mem_prio fw_prio, uint16_t idx); + +/** + * wmi_ready_extract_init_status() - Extract init status from ready event + * @wmi_handle: wmi handle + * @ev: Pointer to event buffer + * + * Return: ready status + */ +uint32_t wmi_ready_extract_init_status(wmi_unified_t wmi_handle, void *ev); + +/** + * wmi_ready_extract_mac_addr() - extract mac address from ready event + * @wmi_handle: wmi handle + * @ev: pointer to event buffer + * @macaddr: Pointer to hold MAC address + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_ready_extract_mac_addr(wmi_unified_t wmi_handle, + void *ev, uint8_t *macaddr); + +/** + * wmi_ready_extract_mac_addr() - extract MAC address list from ready event + * @wmi_handle: wmi handle + * @ev: pointer to event buffer + * @num_mac_addr: Pointer to number of entries + * + * Return: address to start of mac addr list + */ +wmi_host_mac_addr +*wmi_ready_extract_mac_addr_list(wmi_unified_t wmi_handle, void *ev, + uint8_t *num_mac_addr); + +/** + * wmi_extract_ready_params() - Extract data from ready event apart from + * status, macaddr and version. + * @wmi_handle: Pointer to WMI handle. + * @evt_buf: Pointer to Ready event buffer. + * @ev_param: Pointer to host defined struct to copy the data from event. + * + * Return: QDF_STATUS_SUCCESS on success. + */ +QDF_STATUS wmi_extract_ready_event_params( + wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_host_ready_ev_param *ev_param); + +/** + * wmi_extract_fw_version() - extract fw version + * @wmi_handle: wmi handle + * @ev: pointer to event buffer + * @fw_ver: Pointer to hold fw version + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_fw_version(wmi_unified_t wmi_handle, void *ev, + struct wmi_host_fw_ver *fw_ver); + +/** + * wmi_extract_fw_abi_version() - extract fw abi version + * @wmi_handle: wmi handle + * @ev: Pointer to event buffer + * @fw_ver: Pointer to hold fw abi version + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_fw_abi_version(wmi_unified_t wmi_handle, void *ev, + struct wmi_host_fw_abi_ver *fw_ver); + +/** + * wmi_check_and_update_fw_version() - Ready and fw version check + * @wmi_handle: wmi handle + * @ev: pointer to event buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_check_and_update_fw_version(wmi_unified_t wmi_handle, void *ev); -QDF_STATUS wmi_extract_fw_abi_version(void *wmi_hdl, - void *ev, struct wmi_host_fw_abi_ver *fw_ver); +/** + * wmi_extract_dbglog_data_len() - extract debuglog data length + * @wmi_handle: wmi handle + * @evt_b: pointer to event buffer + * @len: length of buffer + * + * Return: length + */ +uint8_t *wmi_extract_dbglog_data_len(wmi_unified_t wmi_handle, + void *evt_b, uint32_t *len); + +/** + * wmi_send_ext_resource_config() - send extended resource configuration + * @wmi_handle: wmi handle + * @ext_cfg: pointer to extended resource configuration + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_send_ext_resource_config(wmi_unified_t wmi_handle, + wmi_host_ext_resource_config *ext_cfg); + +/** + * wmi_unified_rtt_meas_req_test_cmd_send() - WMI rtt meas req test function + * @wmi_handle: handle to WMI. + * @param: pointer to hold rtt meas req test param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_rtt_meas_req_test_cmd_send(wmi_unified_t wmi_handle, + struct rtt_meas_req_test_params *param); -QDF_STATUS wmi_check_and_update_fw_version(void *wmi_hdl, void *ev); +/** + * wmi_unified_rtt_meas_req_cmd_send() - WMI rtt meas req function + * @wmi_handle: handle to WMI. + * @param: pointer to hold rtt meas req param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_rtt_meas_req_cmd_send(wmi_unified_t wmi_handle, + struct rtt_meas_req_params *param); -uint8_t *wmi_extract_dbglog_data_len(void *wmi_hdl, - void *evt_b, uint32_t *len); +/** + * wmi_unified_rtt_keepalive_req_cmd_send() - WMI rtt meas req test function + * @wmi_handle: handle to WMI. + * @param: pointer to hold rtt meas req test param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_rtt_keepalive_req_cmd_send(wmi_unified_t wmi_handle, + struct rtt_keepalive_req_params *param); -QDF_STATUS wmi_send_ext_resource_config(void *wmi_hdl, - wmi_host_ext_resource_config *ext_cfg); +/** + * wmi_unified_lci_set_cmd_send() - WMI lci set function + * @wmi_handle: handle to WMI. + * @param: pointer to hold lci param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_lci_set_cmd_send(wmi_unified_t wmi_handle, + struct lci_set_params *param); -QDF_STATUS wmi_unified_rtt_meas_req_test_cmd_send(void *wmi_hdl, - struct rtt_meas_req_test_params *param); +/** + * wmi_unified_lcr_set_cmd_send() - WMI lcr set function + * @wmi_handle: handle to WMI. + * @param: pointer to hold lcr param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_lcr_set_cmd_send(wmi_unified_t wmi_handle, + struct lcr_set_params *param); -QDF_STATUS wmi_unified_rtt_meas_req_cmd_send(void *wmi_hdl, - struct rtt_meas_req_params *param); +/** + * wmi_unified_extract_pn() - extract pn event data + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: pointer to get pn event param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extract_pn(wmi_unified_t wmi_hdl, void *evt_buf, + struct wmi_host_get_pn_event *param); -QDF_STATUS wmi_unified_rtt_keepalive_req_cmd_send(void *wmi_hdl, - struct rtt_keepalive_req_params *param); +/** + * wmi_unified_send_periodic_chan_stats_config_cmd() - send periodic chan + * stats cmd to fw + * @wmi_handle: wmi handle + * @param: pointer to hold periodic chan stats param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_send_periodic_chan_stats_config_cmd( + wmi_unified_t wmi_handle, + struct periodic_chan_stats_params *param); -QDF_STATUS wmi_unified_lci_set_cmd_send(void *wmi_hdl, - struct lci_set_params *param); +/* Extract APIs */ -QDF_STATUS wmi_unified_lcr_set_cmd_send(void *wmi_hdl, - struct lcr_set_params *param); +/** + * wmi_extract_fips_event_data() - extract fips event data + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: pointer to FIPS event param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_fips_event_data(wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_host_fips_event_param *param); -QDF_STATUS wmi_unified_send_periodic_chan_stats_config_cmd(void *wmi_hdl, - struct periodic_chan_stats_params *param); +#ifdef WLAN_FEATURE_DISA +/** + * wmi_extract_encrypt_decrypt_resp_params() - + * extract encrypt decrypt resp params from event buffer + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @resp: encrypt decrypt resp params + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS +wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl, void *evt_buf, + struct disa_encrypt_decrypt_resp_params + *param); +#endif /* WLAN_FEATURE_DISA */ -/* Extract APIs */ +/** + * wmi_extract_mgmt_rx_params() - extract management rx params from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @hdr: Pointer to hold header + * @bufp: Pointer to hold pointer to rx param buffer + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_mgmt_rx_params(wmi_unified_t wmi_handle, void *evt_buf, + struct mgmt_rx_event_params *hdr, uint8_t **bufp); -QDF_STATUS wmi_extract_fips_event_data(void *wmi_hdl, void *evt_buf, - struct wmi_host_fips_event_param *param); +/** + * wmi_extract_vdev_roam_param() - extract vdev roam param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold roam param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_vdev_roam_param(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_roam_event *ev); -QDF_STATUS wmi_extract_mgmt_rx_params(void *wmi_hdl, void *evt_buf, - struct mgmt_rx_event_params *hdr, uint8_t **bufp); +/** + * wmi_extract_vdev_scan_ev_param() - extract vdev scan param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold vdev scan param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_vdev_scan_ev_param(wmi_unified_t wmi_handle, void *evt_buf, + struct scan_event *param); -QDF_STATUS wmi_extract_vdev_roam_param(void *wmi_hdl, void *evt_buf, - wmi_host_roam_event *ev); +#ifdef FEATURE_WLAN_SCAN_PNO +/** + * wmi_extract_nlo_match_ev_param() - extract NLO match param from event + * @wmi_handle: pointer to WMI handle + * @evt_buf: pointer to WMI event buffer + * @param: pointer to scan event param for NLO match + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS +wmi_extract_nlo_match_ev_param(wmi_unified_t wmi_handle, void *evt_buf, + struct scan_event *param); -QDF_STATUS wmi_extract_vdev_scan_ev_param(void *wmi_hdl, void *evt_buf, - struct scan_event *param); +/** + * wmi_extract_nlo_complete_ev_param() - extract NLO complete param from event + * @wmi_handle: pointer to WMI handle + * @evt_buf: pointer to WMI event buffer + * @param: pointer to scan event param for NLO complete + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS +wmi_extract_nlo_complete_ev_param(wmi_unified_t wmi_handle, void *evt_buf, + struct scan_event *param); +#endif -QDF_STATUS wmi_extract_mu_ev_param(void *wmi_hdl, void *evt_buf, - wmi_host_mu_report_event *param); +/** + * wmi_extract_mu_ev_param() - extract mu param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold mu report + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_mu_ev_param(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_mu_report_event *param); -QDF_STATUS wmi_extract_mu_db_entry(void *wmi_hdl, void *evt_buf, - uint8_t idx, wmi_host_mu_db_entry *param); +/** + * wmi_extract_mu_db_entry() - extract mu db entry from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @idx: index + * @param: Pointer to hold mu db entry + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_mu_db_entry(wmi_unified_t wmi_handle, void *evt_buf, + uint8_t idx, wmi_host_mu_db_entry *param); -QDF_STATUS wmi_extract_mumimo_tx_count_ev_param(void *wmi_hdl, void *evt_buf, - wmi_host_peer_txmu_cnt_event *param); +/** + * wmi_extract_mumimo_tx_count_ev_param() - extract mumimo tx count from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold mumimo tx count + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_mumimo_tx_count_ev_param(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_peer_txmu_cnt_event *param); -QDF_STATUS wmi_extract_peer_gid_userpos_list_ev_param(void *wmi_hdl, - void *evt_buf, wmi_host_peer_gid_userpos_list_event *param); +/** + * wmi_extract_peer_gid_userpos_list_ev_param() - extract peer userpos list + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold peer gid userposition list + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_peer_gid_userpos_list_ev_param( + wmi_unified_t wmi_handle, + void *evt_buf, + wmi_host_peer_gid_userpos_list_event *param); +/** + * wmi_extract_esp_estimate_ev_param() - extract air time from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold esp event + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ QDF_STATUS -wmi_extract_esp_estimate_ev_param(void *wmi_hdl, void *evt_buf, +wmi_extract_esp_estimate_ev_param(wmi_unified_t wmi_handle, void *evt_buf, struct esp_estimation_event *param); -QDF_STATUS wmi_extract_gpio_input_ev_param(void *wmi_hdl, - void *evt_buf, uint32_t *gpio_num); - -QDF_STATUS wmi_extract_pdev_reserve_ast_ev_param(void *wmi_hdl, - void *evt_buf, struct wmi_host_proxy_ast_reserve_param *param); +/** + * wmi_extract_gpio_input_ev_param() - extract gpio input param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @gpio_num: Pointer to hold gpio number + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_gpio_input_ev_param(wmi_unified_t wmi_handle, + void *evt_buf, uint32_t *gpio_num); -QDF_STATUS wmi_extract_pdev_generic_buffer_ev_param(void *wmi_hdl, - void *evt_buf, +/** + * wmi_extract_pdev_reserve_ast_ev_param() - extract reserve ast entry + * param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold reserve ast entry param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_pdev_reserve_ast_ev_param( + wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_host_proxy_ast_reserve_param *param); +/** + * wmi_extract_pdev_generic_buffer_ev_param() - extract pdev generic buffer + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to generic buffer param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_pdev_generic_buffer_ev_param( + wmi_unified_t wmi_handle, void *evt_buf, wmi_host_pdev_generic_buffer_event *param); -QDF_STATUS wmi_extract_peer_ratecode_list_ev(void *wmi_hdl, void *evt_buf, - uint8_t *peer_mac, wmi_sa_rate_cap *rate_cap); +/** + * wmi_extract_peer_ratecode_list_ev() - extract peer ratecode from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @peer_mac: Pointer to hold peer mac address + * @pdev_id: Pointer to hold pdev_id + * @rate_cap: Pointer to hold ratecode + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_peer_ratecode_list_ev( + wmi_unified_t wmi_handle, void *evt_buf, + uint8_t *peer_mac, uint32_t *pdev_id, + wmi_sa_rate_cap *rate_cap); -QDF_STATUS wmi_extract_bcnflt_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats); +/** + * wmi_extract_bcnflt_stats() - extract bcn fault stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into bcn fault stats + * @bcnflt_stats: Pointer to hold bcn fault stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_bcnflt_stats( + wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_bcnflt_stats *bcnflt_stats); -QDF_STATUS wmi_extract_rtt_hdr(void *wmi_hdl, void *evt_buf, - wmi_host_rtt_event_hdr *ev); +/** + * wmi_extract_rtt_hdr() - extract rtt header from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold rtt header + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_rtt_hdr(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_rtt_event_hdr *ev); -QDF_STATUS wmi_extract_rtt_ev(void *wmi_hdl, void *evt_buf, - wmi_host_rtt_meas_event *ev, uint8_t *hdump, - uint16_t hdump_len); +/** + * wmi_extract_rtt_ev() - extract rtt event + * @wmi_handle: wmi handle + * @evt_buf: Pointer to event buffer + * @ev: Pointer to hold rtt event + * @hdump: Pointer to hold hex dump + * @hdump_len: hex dump length + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_rtt_ev(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_rtt_meas_event *ev, + uint8_t *hdump, uint16_t hdump_len); -QDF_STATUS wmi_extract_rtt_error_report_ev(void *wmi_hdl, void *evt_buf, - wmi_host_rtt_error_report_event *ev); +/** + * wmi_extract_rtt_error_report_ev() - extract rtt error report from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold rtt error report + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_rtt_error_report_ev(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_rtt_error_report_event *ev); -QDF_STATUS wmi_extract_chan_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_chan_stats *chan_stats); +/** + * wmi_extract_chan_stats() - extract chan stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into chan stats + * @chan_stats: Pointer to hold chan stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_chan_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_chan_stats *chan_stats); -QDF_STATUS wmi_extract_thermal_stats(void *wmi_hdl, void *evt_buf, - uint32_t *temp, uint32_t *level, uint32_t *pdev_id); +/** + * wmi_extract_thermal_stats() - extract thermal stats from event + * @wmi_handle: wmi handle + * @evt_buf: Pointer to event buffer + * @temp: Pointer to hold extracted temperature + * @level: Pointer to hold extracted level + * @pdev_id: Pointer to hold extracted pdev_id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_thermal_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t *temp, uint32_t *level, + uint32_t *pdev_id); -QDF_STATUS wmi_extract_thermal_level_stats(void *wmi_hdl, void *evt_buf, - uint8_t idx, uint32_t *levelcount, uint32_t *dccount); +/** + * wmi_extract_thermal_level_stats() - extract thermal level stats from + * event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @idx: Index to level stats + * @levelcount: Pointer to hold levelcount + * @dccount: Pointer to hold dccount + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_thermal_level_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint8_t idx, uint32_t *levelcount, + uint32_t *dccount); -QDF_STATUS wmi_extract_comb_phyerr(void *wmi_hdl, void *evt_buf, +/** + * wmi_extract_comb_phyerr() - extract comb phy error from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @datalen: data length of event buffer + * @buf_offset: Pointer to hold value of current event buffer offset + * post extraction + * @phyerr: Pointer to hold phyerr + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_comb_phyerr(wmi_unified_t wmi_handle, void *evt_buf, uint16_t datalen, uint16_t *buf_offset, wmi_host_phyerr_t *phyerr); -QDF_STATUS wmi_extract_single_phyerr(void *wmi_hdl, void *evt_buf, - uint16_t datalen, uint16_t *buf_offset, - wmi_host_phyerr_t *phyerr); +/** + * wmi_extract_single_phyerr() - extract single phy error from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @datalen: data length of event buffer + * @buf_offset: Pointer to hold value of current event buffer offset + * post extraction + * @phyerr: Pointer to hold phyerr + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_single_phyerr(wmi_unified_t wmi_handle, void *evt_buf, + uint16_t datalen, uint16_t *buf_offset, + wmi_host_phyerr_t *phyerr); -QDF_STATUS wmi_extract_composite_phyerr(void *wmi_hdl, void *evt_buf, - uint16_t datalen, wmi_host_phyerr_t *phyerr); +/** + * wmi_extract_composite_phyerr() - extract composite phy error from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @datalen: Length of event buffer + * @phyerr: Pointer to hold phy error + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_composite_phyerr(wmi_unified_t wmi_handle, void *evt_buf, + uint16_t datalen, wmi_host_phyerr_t *phyerr); -QDF_STATUS wmi_extract_profile_ctx(void *wmi_hdl, void *evt_buf, +/** + * wmi_extract_profile_ctx() - extract profile context from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @profile_ctx: Pointer to hold profile context + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_profile_ctx(wmi_unified_t wmi_handle, void *evt_buf, wmi_host_wlan_profile_ctx_t *profile_ctx); -QDF_STATUS wmi_extract_profile_data(void *wmi_hdl, void *evt_buf, uint8_t idx, - wmi_host_wlan_profile_t *profile_data); - -QDF_STATUS wmi_extract_stats_param(void *wmi_hdl, void *evt_buf, - wmi_host_stats_event *stats_param); +/** + * wmi_extract_profile_data() - extract profile data from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @idx: index of profile data + * @profile_data: Pointer to hold profile data + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_profile_data(wmi_unified_t wmi_handle, void *evt_buf, uint8_t idx, + wmi_host_wlan_profile_t *profile_data); -QDF_STATUS wmi_extract_pdev_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, - wmi_host_pdev_stats *pdev_stats); +/** + * wmi_extract_stats_param() - extract all stats count from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @stats_param: Pointer to hold stats count + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_stats_param(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_stats_event *stats_param); -QDF_STATUS wmi_extract_unit_test(void *wmi_hdl, void *evt_buf, - wmi_unit_test_event *unit_test, uint32_t maxspace); +/** + * wmi_extract_pdev_stats() - extract pdev stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into pdev stats + * @pdev_stats: Pointer to hold pdev stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_pdev_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_pdev_stats *pdev_stats); -QDF_STATUS wmi_extract_pdev_ext_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, - wmi_host_pdev_ext_stats *pdev_ext_stats); +/** + * extract_unit_test() - extract unit test from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @unit_test: Pointer to hold unit-test header + * @maxspace: The amount of space in evt_buf + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_unit_test(wmi_unified_t wmi_handle, void *evt_buf, + wmi_unit_test_event *unit_test, uint32_t maxspace); -QDF_STATUS wmi_extract_peer_extd_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, - wmi_host_peer_extd_stats *peer_extd_stats); +/** + * wmi_extract_pdev_ext_stats() - extract extended pdev stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into extended pdev stats + * @pdev_ext_stats: Pointer to hold extended pdev stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_pdev_ext_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, + wmi_host_pdev_ext_stats *pdev_ext_stats); -QDF_STATUS wmi_extract_peer_adv_stats(wmi_unified_t wmi_handle, void *evt_buf, - struct wmi_host_peer_adv_stats - *peer_adv_stats); +/** + * wmi_extract_peer_extd_stats() - extract extended peer stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into extended peer stats + * @peer_extd_stats: Pointer to hold extended peer stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_peer_extd_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, + wmi_host_peer_extd_stats *peer_extd_stats); -QDF_STATUS wmi_extract_bss_chan_info_event(void *wmi_hdl, void *evt_buf, - wmi_host_pdev_bss_chan_info_event *bss_chan_info); +/** + * wmi_extract_peer_adv_stats() - extract advance (extd2) peer stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @peer_adv_stats: Pointer to hold extended peer stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_peer_adv_stats( + wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_host_peer_adv_stats *peer_adv_stats); -QDF_STATUS wmi_extract_peer_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_peer_stats *peer_stats); +/** + * wmi_extract_bss_chan_info_event() - extract bss channel information + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @bss_chan_info: Pointer to hold bss channel information + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_bss_chan_info_event( + wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_pdev_bss_chan_info_event *bss_chan_info); -QDF_STATUS wmi_extract_tx_data_traffic_ctrl_ev(void *wmi_hdl, void *evt_buf, - wmi_host_tx_data_traffic_ctrl_event *ev); +/** + * wmi_extract_peer_stats() - extract peer stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into peer stats + * @peer_stats: Pointer to hold peer stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_peer_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_peer_stats *peer_stats); -QDF_STATUS wmi_extract_vdev_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_vdev_stats *vdev_stats); +/** + * wmi_extract_tx_data_traffic_ctrl_ev() - extract tx data traffic control + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold data traffic control + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_tx_data_traffic_ctrl_ev(wmi_unified_t wmi_handle, void *evt_buf, + wmi_host_tx_data_traffic_ctrl_event *ev); -QDF_STATUS wmi_extract_per_chain_rssi_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, struct wmi_host_per_chain_rssi_stats *rssi_stats); +/** + * wmi_extract_vdev_stats() - extract vdev stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into vdev stats + * @vdev_stats: Pointer to hold vdev stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_vdev_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_vdev_stats *vdev_stats); -QDF_STATUS wmi_extract_vdev_extd_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_vdev_extd_stats *vdev_extd_stats); +/** + * wmi_extract_per_chain_rssi_stats() - extract rssi stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into rssi stats + * @rssi_stats: Pointer to hold rssi stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_per_chain_rssi_stats( + wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, + struct wmi_host_per_chain_rssi_stats *rssi_stats); -QDF_STATUS wmi_extract_bcn_stats(void *wmi_hdl, void *evt_buf, - uint32_t index, wmi_host_bcn_stats *vdev_bcn_stats); +#ifdef WLAN_FEATURE_MIB_STATS +/** + * wmi_extract_mib_stats() - extract mib stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @mib_stats: pointer to hold mib stats + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_mib_stats(wmi_unified_t wmi_handle, void *evt_buf, + struct mib_stats_metrics *mib_stats); +#endif -#ifdef FEATURE_OEM_DATA /** - * wmi_unified_start_oemv2_data_cmd() - start oem data cmd to target + * wmi_extract_vdev_extd_stats() - extract extended vdev stats from event * @wmi_handle: wmi handle - * @params: oem data params + * @evt_buf: pointer to event buffer + * @index: Index into extended vdev stats + * @vdev_extd_stats: Pointer to hold extended vdev stats * - * This is common api for oem data, using wmi command WMI_OEM_DATA_CMDID. + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_vdev_extd_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, + wmi_host_vdev_extd_stats *vdev_extd_stats); + +/** + * wmi_extract_bcn_stats() - extract beacon stats from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @index: Index into beacon stats + * @vdev_bcn_stats: Pointer to hold beacon stats * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_start_oemv2_data_cmd(wmi_unified_t wmi_handle, - struct oem_data *params); -#endif +QDF_STATUS +wmi_extract_bcn_stats(wmi_unified_t wmi_handle, void *evt_buf, + uint32_t index, wmi_host_bcn_stats *vdev_bcn_stats); /** * wmi_extract_vdev_nac_rssi_stats() - extract NAC_RSSI stats from event * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer - * @param vdev_extd_stats: Pointer to hold nac rssi stats + * @evt_buf: pointer to event buffer + * @vdev_extd_stats: Pointer to hold nac rssi stats * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_vdev_nac_rssi_stats(void *wmi_hdl, void *evt_buf, +QDF_STATUS wmi_extract_vdev_nac_rssi_stats( + wmi_unified_t wmi_handle, void *evt_buf, struct wmi_host_vdev_nac_rssi_event *vdev_nac_rssi_stats); /** @@ -1407,35 +3084,82 @@ QDF_STATUS wmi_extract_vdev_nac_rssi_stats(void *wmi_hdl, void *evt_buf, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_peer_retry_stats(void *wmi_hdl, void *evt_buf, +QDF_STATUS wmi_extract_peer_retry_stats( + wmi_unified_t wmi_handle, void *evt_buf, uint32_t index, struct wmi_host_peer_retry_stats *peer_retry_stats); -QDF_STATUS wmi_unified_send_power_dbg_cmd(void *wmi_hdl, - struct wmi_power_dbg_params *param); +/** + * wmi_unified_send_power_dbg_cmd() - send power debug commands + * @wmi_handle: wmi handle + * @param: wmi power debug parameter + * + * Send WMI_POWER_DEBUG_CMDID parameters to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wmi_unified_send_power_dbg_cmd(wmi_unified_t wmi_handle, + struct wmi_power_dbg_params *param); /** * wmi_extract_sar_cap_service_ready_ext() - extract SAR cap from * FW service ready event - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @evt_buf: event buffer received from firmware * @ext_param: extended target info * * Return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS wmi_extract_sar_cap_service_ready_ext( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct wlan_psoc_host_service_ext_param *ext_param); -QDF_STATUS wmi_unified_fw_test_cmd(void *wmi_hdl, +/** + * wmi_unified_fw_test_cmd() - send fw test command to fw. + * @wmi_handle: wmi handle + * @wmi_fwtest: fw test command + * + * This function sends fw test command to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_fw_test_cmd(wmi_unified_t wmi_handle, struct set_fwtest_params *wmi_fwtest); -QDF_STATUS wmi_unified_peer_rx_reorder_queue_setup_send(void *wmi_hdl, - struct rx_reorder_queue_setup_params *param); -QDF_STATUS wmi_unified_peer_rx_reorder_queue_remove_send(void *wmi_hdl, - struct rx_reorder_queue_remove_params *param); +/** + * wmi_unified_peer_rx_reorder_queue_setup_send() - send rx reorder queue + * setup command to fw + * @wmi_handle: wmi handle + * @param: Rx reorder queue setup parameters + * + * Return: QDF_STATUS for success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_peer_rx_reorder_queue_setup_send( + wmi_unified_t wmi_handle, + struct rx_reorder_queue_setup_params *param); + +/** + * wmi_unified_peer_rx_reorder_queue_remove_send() - send rx reorder queue + * remove command to fw + * @wmi_handle: wmi handle + * @param: Rx reorder queue remove parameters + * + * Return: QDF_STATUS for success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_peer_rx_reorder_queue_remove_send( + wmi_unified_t wmi_handle, + struct rx_reorder_queue_remove_params *param); -QDF_STATUS wmi_extract_service_ready_ext(void *wmi_hdl, uint8_t *evt_buf, +/* + * wmi_extract_service_ready_ext() - extract extended service ready + * @wmi_handle: wmi handle + * @param: wmi power debug parameter + * + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wmi_extract_service_ready_ext( + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct wlan_psoc_host_service_ext_param *param); /* @@ -1451,18 +3175,52 @@ QDF_STATUS wmi_extract_service_ready_ext2( struct wmi_unified *wmi_handle, uint8_t *evt_buf, struct wlan_psoc_host_service_ext2_param *param); +/** + * wmi_extract_hw_mode_cap_service_ready_ext() - + * extract HW mode cap from service ready event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @hw_mode_idx: hw mode idx should be less than num_mode + * @param: Pointer to hold evt buf + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ QDF_STATUS wmi_extract_hw_mode_cap_service_ready_ext( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t hw_mode_idx, struct wlan_psoc_host_hw_mode_caps *param); + +/** + * wmi_extract_mac_phy_cap_service_ready_ext() - + * extract MAC phy cap from service ready event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @hw_mode_id: hw mode id of hw_mode_caps + * @phy_id: phy_id within hw_mode_cap + * @param: pointer to mac phy caps structure to hold the values from event + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ QDF_STATUS wmi_extract_mac_phy_cap_service_ready_ext( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t hw_mode_id, uint8_t phy_id, struct wlan_psoc_host_mac_phy_caps *param); -QDF_STATUS wmi_extract_reg_cap_service_ready_ext( - void *wmi_hdl, + +/** + * wmi_extract_reg_cap_service_ready_ext() - + * extract REG cap from service ready event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @phy_idx: phy idx should be less than num_mode + * @param: Pointer to hold evt buf + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS +wmi_extract_reg_cap_service_ready_ext( + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t phy_idx, struct wlan_psoc_host_hal_reg_capabilities_ext *param); @@ -1470,7 +3228,7 @@ QDF_STATUS wmi_extract_reg_cap_service_ready_ext( * wmi_extract_dbr_ring_cap_service_ready_ext: Extract direct buffer rx * capability received through * extended service ready event - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @evt_buf: Event buffer * @idx: Index of the module for which capability is received * @param: Pointer to direct buffer rx ring cap struct @@ -1478,7 +3236,23 @@ QDF_STATUS wmi_extract_reg_cap_service_ready_ext( * Return: QDF status of operation */ QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext( - void *wmi_hdl, + wmi_unified_t wmi_handle, + uint8_t *evt_buf, uint8_t idx, + struct wlan_psoc_host_dbr_ring_caps *param); + +/** + * wmi_extract_dbr_ring_cap_service_ready_ext2: Extract direct buffer rx + * capability received through + * extended service ready2 event + * @wmi_handle: WMI handle + * @evt_buf: Event buffer + * @idx: Index of the module for which capability is received + * @param: Pointer to direct buffer rx ring cap struct + * + * Return: QDF status of operation + */ +QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext2( + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct wlan_psoc_host_dbr_ring_caps *param); @@ -1486,7 +3260,7 @@ QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext( * wmi_extract_spectral_scaling_params_service_ready_ext: Extract Spectral * scaling params received through * extended service ready event - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @evt_buf: Event buffer * @idx: Index * @param: Pointer to Spectral scaling params @@ -1494,35 +3268,79 @@ QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext( * Return: QDF status of operation */ QDF_STATUS wmi_extract_spectral_scaling_params_service_ready_ext( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct wlan_psoc_host_spectral_scaling_params *param); -QDF_STATUS wmi_extract_pdev_utf_event(void *wmi_hdl, +/** + * wmi_extract_pdev_utf_event() - + * extract UTF data from pdev utf event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold evt buf + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS wmi_extract_pdev_utf_event(wmi_unified_t wmi_handle, uint8_t *evt_buf, struct wmi_host_pdev_utf_event *param); -QDF_STATUS wmi_extract_pdev_qvit_event(void *wmi_hdl, - uint8_t *evt_buf, - struct wmi_host_pdev_qvit_event *param); +/** + * wmi_extract_pdev_qvit_event() - + * extract UTF data from pdev qvit event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold evt buf + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS wmi_extract_pdev_qvit_event(wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_host_pdev_qvit_event *param); #ifdef WLAN_SUPPORT_RF_CHARACTERIZATION +/** + * wmi_extract_num_rf_characterziation_entries - Extract number of RF + * characterization metrics received from the RF characterization event. + * @wmi_hdl: WMI handle + * @evt_buf: Event buffer + * @num_rf_characterization_entries: Number of RF characterization metrics + * + * Return: QDF status of operation + */ +QDF_STATUS wmi_extract_num_rf_characterization_entries(wmi_unified_t wmi_hdl, + uint8_t *evt_buf, + uint32_t *num_rf_characterization_entries); + /** * wmi_extract_rf_characterziation_entries - Extract RF characterization metrics - * received through extended service ready event. + * received from the RF characterization event. * @wmi_hdl: WMI handle * @evt_buf: Event buffer + * @num_rf_characterization_entries: Number of RF characterization metrics * @rf_characterization_entries: Pointer to RF characterization metrics * * Return: QDF status of operation */ QDF_STATUS wmi_extract_rf_characterization_entries(wmi_unified_t wmi_hdl, uint8_t *evt_buf, - struct wlan_psoc_host_rf_characterization_entry *rf_characterization_entries); + uint32_t num_rf_characterization_entries, + struct wmi_host_rf_characterization_event_param *rf_characterization_entries); #endif -QDF_STATUS wmi_extract_chainmask_tables(void *wmi_hdl, uint8_t *evt_buf, +/* + * wmi_extract_chainmask_tables_tlv() - extract chain mask tables + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer. + * @chainmask_table: pointer to struct wlan_psoc_host_chainmask_table + * + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wmi_extract_chainmask_tables( + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct wlan_psoc_host_chainmask_table *chainmask_table); + /** * wmi_unified_dfs_phyerr_offload_en_cmd() - enable dfs phyerr offload * @wmi_handle: wmi handle @@ -1530,8 +3348,8 @@ QDF_STATUS wmi_extract_chainmask_tables(void *wmi_hdl, uint8_t *evt_buf, * * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_dfs_phyerr_offload_en_cmd(void *wmi_hdl, - uint32_t pdev_id); +QDF_STATUS wmi_unified_dfs_phyerr_offload_en_cmd(wmi_unified_t wmi_handle, + uint32_t pdev_id); /** * wmi_unified_dfs_phyerr_offload_dis_cmd() - disable dfs phyerr offload @@ -1540,58 +3358,66 @@ QDF_STATUS wmi_unified_dfs_phyerr_offload_en_cmd(void *wmi_hdl, * * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_dfs_phyerr_offload_dis_cmd(void *wmi_hdl, - uint32_t pdev_id); +QDF_STATUS wmi_unified_dfs_phyerr_offload_dis_cmd(wmi_unified_t wmi_handle, + uint32_t pdev_id); #ifdef QCA_SUPPORT_AGILE_DFS /** * wmi_unified_send_vdev_adfs_ch_cfg_cmd() - send adfs channel config command * @wmi_handle: wmi handle - * @vdev_adfs_ch_cfg_params: adfs channel config params + * @param: adfs channel config params * * Return: QDF_STATUS */ QDF_STATUS -wmi_unified_send_vdev_adfs_ch_cfg_cmd(void *wmi_hdl, +wmi_unified_send_vdev_adfs_ch_cfg_cmd(wmi_unified_t wmi_handle, struct vdev_adfs_ch_cfg_params *param); /** * wmi_unified_send_vdev_adfs_ocac_abort_cmd() - send adfs o-cac abort command * @wmi_handle: wmi handle - * @vdev_adfs_abort_params: adfs channel o-cac abort params + * @param: adfs channel o-cac abort params * * Return: QDF_STATUS */ QDF_STATUS -wmi_unified_send_vdev_adfs_ocac_abort_cmd(void *wmi_hdl, +wmi_unified_send_vdev_adfs_ocac_abort_cmd(wmi_unified_t wmi_handle, struct vdev_adfs_abort_params *param); #endif -QDF_STATUS wmi_unified_set_country_cmd_send(void *wmi_hdl, - struct set_country *param); +/** + * wmi_unified_set_country_cmd_send() - WMI set country function + * @wmi_handle : handle to WMI. + * @param : pointer to hold set country cmd parameter + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_set_country_cmd_send(wmi_unified_t wmi_handle, + struct set_country *param); #ifdef WLAN_FEATURE_ACTION_OUI /** * wmi_unified_send_action_oui_cmd() - send action oui cmd to fw - * @wmi_hdl: wma handle + * @wmi_handle: wma handle * @req: wmi action oui message to be send * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_send_action_oui_cmd(void *wmi_hdl, +wmi_unified_send_action_oui_cmd(wmi_unified_t wmi_handle, struct action_oui_request *req); #endif /* WLAN_FEATURE_ACTION_OUI */ /** * wmi_unified_send_request_get_rcpi_cmd() - command to request rcpi value - * @wmi_hdl: wma handle + * @wmi_handle: wma handle * @get_rcpi_param: rcpi params * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_request_get_rcpi_cmd(void *wmi_hdl, - struct rcpi_req *get_rcpi_param); +QDF_STATUS +wmi_unified_send_request_get_rcpi_cmd(wmi_unified_t wmi_handle, + struct rcpi_req *get_rcpi_param); /** * wmi_extract_rcpi_response_event - api to extract RCPI event params @@ -1602,8 +3428,9 @@ QDF_STATUS wmi_unified_send_request_get_rcpi_cmd(void *wmi_hdl, * Return: QDF_STATUS_SUCCESS for successful event parse * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE */ -QDF_STATUS wmi_extract_rcpi_response_event(void *wmi_hdl, void *evt_buf, - struct rcpi_res *res); +QDF_STATUS +wmi_extract_rcpi_response_event(wmi_unified_t wmi_handle, void *evt_buf, + struct rcpi_res *res); #ifdef WMI_INTERFACE_EVENT_LOGGING void wmi_print_cmd_log(wmi_unified_t wmi, uint32_t count, @@ -1632,18 +3459,17 @@ void wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count, /** * wmi_unified_send_wds_entry_list_cmd() - WMI function to get list of * wds entries from FW - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * * Send WMI_PDEV_WDS_ENTRY_LIST_CMDID parameters to fw. * * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error */ - -QDF_STATUS wmi_unified_send_dump_wds_table_cmd(void *wmi_hdl); +QDF_STATUS wmi_unified_send_dump_wds_table_cmd(wmi_unified_t wmi_handle); /** * wmi_extract_wds_entry - api to extract wds entry - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @evt_buf: pointer to event buffer * @wds_entry: wds entry * @idx: index to point wds entry in event buffer @@ -1651,14 +3477,14 @@ QDF_STATUS wmi_unified_send_dump_wds_table_cmd(void *wmi_hdl); * Return: QDF_STATUS_SUCCESS for successful event parse * else QDF_STATUS_E_INVAL or QDF_STATUS_E_FAILURE */ - -QDF_STATUS wmi_extract_wds_entry(void *wmi_hdl, uint8_t *evt_buf, - struct wdsentry *wds_entry, u_int32_t idx); +QDF_STATUS +wmi_extract_wds_entry(wmi_unified_t wmi_handle, uint8_t *evt_buf, + struct wdsentry *wds_entry, u_int32_t idx); /** * wmi_unified_send_obss_detection_cfg_cmd() - WMI function to send obss * detection configuration to FW. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @cfg: obss detection configuration * * Send WMI_SAP_OBSS_DETECTION_CFG_CMDID parameters to fw. @@ -1666,13 +3492,14 @@ QDF_STATUS wmi_extract_wds_entry(void *wmi_hdl, uint8_t *evt_buf, * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_send_obss_detection_cfg_cmd(void *wmi_hdl, - struct wmi_obss_detection_cfg_param *cfg); +QDF_STATUS wmi_unified_send_obss_detection_cfg_cmd( + wmi_unified_t wmi_handle, + struct wmi_obss_detection_cfg_param *cfg); /** * wmi_unified_extract_obss_detection_info() - WMI function to extract obss * detection info from FW. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @data: event data from firmware * @info: Pointer to hold obss detection info * @@ -1681,20 +3508,20 @@ QDF_STATUS wmi_unified_send_obss_detection_cfg_cmd(void *wmi_hdl, * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_extract_obss_detection_info(void *wmi_hdl, - uint8_t *data, - struct wmi_obss_detect_info - *info); +QDF_STATUS wmi_unified_extract_obss_detection_info( + wmi_unified_t wmi_handle, + uint8_t *data, + struct wmi_obss_detect_info *info); #ifdef WLAN_SUPPORT_GREEN_AP QDF_STATUS wmi_extract_green_ap_egap_status_info( - void *wmi_hdl, uint8_t *evt_buf, - struct wlan_green_ap_egap_status_info *egap_status_info_params); + wmi_unified_t wmi_hdl, uint8_t *evt_buf, + struct wlan_green_ap_egap_status_info *egap_status_info_params); #endif /** * wmi_unified_send_roam_scan_stats_cmd() - Wrapper to request roam scan stats - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @params: request params * * This function is used to send the roam scan stats request command to @@ -1703,7 +3530,7 @@ QDF_STATUS wmi_extract_green_ap_egap_status_info( * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_send_roam_scan_stats_cmd(void *wmi_hdl, +wmi_unified_send_roam_scan_stats_cmd(wmi_unified_t wmi_handle, struct wmi_roam_scan_stats_req *params); /** @@ -1722,7 +3549,7 @@ wmi_extract_roam_scan_stats_res_evt(wmi_unified_t wmi, void *evt_buf, /** * wmi_extract_offload_bcn_tx_status_evt() - API to extract bcn tx status event - * @wmi: wmi handle + * @wmi_handle: wmi handle * @evt_buf: pointer to the event buffer * @vdev_id: output pointer to hold vdev id * @tx_status: output pointer to hold bcn tx status @@ -1730,17 +3557,17 @@ wmi_extract_roam_scan_stats_res_evt(wmi_unified_t wmi, void *evt_buf, * Return: QDF_STATUS */ QDF_STATUS -wmi_extract_offload_bcn_tx_status_evt(void *wmi_hdl, void *evt_buf, +wmi_extract_offload_bcn_tx_status_evt(wmi_unified_t wmi_handle, void *evt_buf, uint32_t *vdev_id, uint32_t *tx_status); /* wmi_get_ch_width_from_phy_mode() - convert phy mode to channel width - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @phymode: phy mode * * Return: wmi channel width */ -wmi_host_channel_width wmi_get_ch_width_from_phy_mode(void *wmi_hdl, - WMI_HOST_WLAN_PHY_MODE phymode); +wmi_host_channel_width wmi_get_ch_width_from_phy_mode( + wmi_unified_t wmi_handle, WMI_HOST_WLAN_PHY_MODE phymode); #ifdef QCA_SUPPORT_CP_STATS /** @@ -1759,7 +3586,7 @@ QDF_STATUS wmi_extract_cca_stats(wmi_unified_t wmi_handle, void *evt_buf, #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) /** * wmi_unified_dfs_send_avg_params_cmd() - send average radar parameters cmd. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @params: radar found params * * This function passes the average radar parameters to fw @@ -1767,12 +3594,12 @@ QDF_STATUS wmi_extract_cca_stats(wmi_unified_t wmi_handle, void *evt_buf, * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_dfs_send_avg_params_cmd(void *wmi_hdl, +wmi_unified_dfs_send_avg_params_cmd(wmi_unified_t wmi_handle, struct dfs_radar_found_params *params); /** * wmi_extract_dfs_status_from_fw() - extract host dfs status from fw. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @evt_buf: pointer to event buffer * @dfs_status_check: pointer to the host dfs status * @@ -1780,46 +3607,47 @@ wmi_unified_dfs_send_avg_params_cmd(void *wmi_hdl, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_dfs_status_from_fw(void *wmi_hdl, void *evt_buf, +QDF_STATUS wmi_extract_dfs_status_from_fw(wmi_unified_t wmi_handle, + void *evt_buf, uint32_t *dfs_status_check); #endif #ifdef OL_ATH_SMART_LOGGING /** * wmi_unified_send_smart_logging_enable_cmd() - send smart logging enable cmd - * @wmi_hdl: wmi handle - * @params: enable/disable + * @wmi_handle: wmi handle + * @param: enable/disable * * This function enables/disable the smart logging feature * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_smart_logging_enable_cmd(void *wmi_hdl, +QDF_STATUS wmi_unified_send_smart_logging_enable_cmd(wmi_unified_t wmi_handle, uint32_t param); /** * wmi_unified_send_smart_logging_fatal_cmd() - send smart logging fatal cmd - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @param: Fatal event * * This function sends the smart log fatal events to the FW * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_smart_logging_fatal_cmd - (void *wmi_hdl, - struct wmi_debug_fatal_events *param); +QDF_STATUS +wmi_unified_send_smart_logging_fatal_cmd(wmi_unified_t wmi_handle, + struct wmi_debug_fatal_events *param); /** * wmi_extract_smartlog_ev() - extract smartlog event info from event * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer - * @param ev: Pointer to hold fatal events + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold fatal events * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_smartlog_ev - (void *wmi_hdl, void *evt_buf, - struct wmi_debug_fatal_events *ev); +QDF_STATUS +wmi_extract_smartlog_ev(wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_debug_fatal_events *ev); #endif /* OL_ATH_SMART_LOGGING */ @@ -1841,16 +3669,15 @@ void wmi_process_fw_event_worker_thread_ctx(struct wmi_unified *wmi_handle, * wmi_extract_ctl_failsafe_check_ev_param() - extract ctl failsafe * status from event * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer - * @param ev: Pointer to hold ctl status + * @evt_buf: pointer to event buffer + * @ev: Pointer to hold ctl status * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS -wmi_extract_ctl_failsafe_check_ev_param(void *wmi_hdl, - void *evt_buf, - struct wmi_host_pdev_ctl_failsafe_event - *param); +QDF_STATUS wmi_extract_ctl_failsafe_check_ev_param( + wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_host_pdev_ctl_failsafe_event *param); #ifdef OBSS_PD /** @@ -1860,7 +3687,8 @@ wmi_extract_ctl_failsafe_check_ev_param(void *wmi_hdl, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_cmd(void *wmi_handle, +QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_cmd( + wmi_unified_t wmi_handle, struct wmi_host_obss_spatial_reuse_set_param *obss_spatial_reuse_param); /** @@ -1870,7 +3698,8 @@ QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_cmd(void *wmi_handle, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_def_thresh_cmd(void *wmi_hdl, +QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_def_thresh_cmd( + wmi_unified_t wmi_handle, struct wmi_host_obss_spatial_reuse_set_def_thresh *thresh); #endif /* OBSS_PD */ @@ -1879,20 +3708,20 @@ QDF_STATUS wmi_unified_send_obss_spatial_reuse_set_def_thresh_cmd(void *wmi_hdl, * wmi_convert_pdev_id_host_to_target() - Convert pdev_id from host to target * defines. For legacy there is not conversion required. Just return pdev_id as * it is. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @host_pdev_id: host pdev_id to be converted. * @target_pdev_id: Output target pdev id. * * Return: QDF_STATUS */ -QDF_STATUS wmi_convert_pdev_id_host_to_target(void *wmi_hdl, +QDF_STATUS wmi_convert_pdev_id_host_to_target(wmi_unified_t wmi_handle, uint32_t host_pdev_id, uint32_t *target_pdev_id); /** * wmi_unified_send_bss_color_change_enable_cmd() - WMI function to send bss * color change enable to FW. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @vdev_id: vdev ID * @enable: enable or disable color change handeling within firmware * @@ -1901,27 +3730,29 @@ QDF_STATUS wmi_convert_pdev_id_host_to_target(void *wmi_hdl, * * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_send_bss_color_change_enable_cmd(void *wmi_hdl, - uint32_t vdev_id, - bool enable); +QDF_STATUS +wmi_unified_send_bss_color_change_enable_cmd(wmi_unified_t wmi_handle, + uint32_t vdev_id, + bool enable); /** * wmi_unified_send_obss_color_collision_cfg_cmd() - WMI function to send bss * color collision detection configuration to FW. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @cfg: obss color collision detection configuration * * Send WMI_OBSS_COLOR_COLLISION_DET_CONFIG_CMDID parameters to fw. * * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_send_obss_color_collision_cfg_cmd(void *wmi_hdl, +QDF_STATUS wmi_unified_send_obss_color_collision_cfg_cmd( + wmi_unified_t wmi_handle, struct wmi_obss_color_collision_cfg_param *cfg); /** * wmi_unified_extract_obss_color_collision_info() - WMI function to extract * obss color collision info from FW. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @data: event data from firmware * @info: Pointer to hold bss color collision info * @@ -1929,7 +3760,8 @@ QDF_STATUS wmi_unified_send_obss_color_collision_cfg_cmd(void *wmi_hdl, * * Return: QDF_STATUS */ -QDF_STATUS wmi_unified_extract_obss_color_collision_info(void *wmi_hdl, +QDF_STATUS wmi_unified_extract_obss_color_collision_info( + wmi_unified_t wmi_handle, uint8_t *data, struct wmi_obss_color_collision_info *info); #ifdef CRYPTO_SET_KEY_CONVERGED @@ -1977,47 +3809,117 @@ QDF_STATUS wmi_unified_send_mws_coex_req_cmd(struct wmi_unified *wmi_handle, QDF_STATUS wmi_unified_send_idle_trigger_monitor(wmi_unified_t wmi_handle, uint8_t val); -#ifdef WLAN_CFR_ENABLE + +#ifdef WIFI_POS_CONVERGED /** - * wmi_unified_send_peer_cfr_capture_cmd() - WMI function to start CFR capture - * for a peer + * wmi_extract_oem_response_param() - WMI function to extract OEM response param * @wmi_hdl: WMI handle - * @param: configuration params for capture + * @resp_buf: Buffer holding response data + * @oem_resp_param: zero-filled structure pointer to hold oem response data * * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. */ QDF_STATUS -wmi_unified_send_peer_cfr_capture_cmd(void *wmi_hdl, - struct peer_cfr_params *param); +wmi_extract_oem_response_param(wmi_unified_t wmi_hdl, void *resp_buf, + struct wmi_oem_response_param *oem_resp_param); +#endif /* WIFI_POS_CONVERGED */ /** - * wmi_extract_cfr_peer_tx_event_param() - WMI function to extract cfr tx event - * for a peer + * wmi_critical_events_in_flight() - get the number of critical events in flight + * * @wmi_hdl: WMI handle - * @evt_buf: Buffer holding event data - * @peer_tx_event: pointer to hold tx event data + * + * Return: the number of critical events in flight. + */ +uint32_t wmi_critical_events_in_flight(struct wmi_unified *wmi); + + +#ifdef FEATURE_ANI_LEVEL_REQUEST +/** + * wmi_unified_ani_level_cmd_send() - WMI function to send get ani level cmd + * @wmi_hdl: WMI handle + * @freqs: pointer to list of freqs for which ANI levels are to be fetched + * @num_freqs: number of freqs in the above parameter + * + * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. + */ +QDF_STATUS wmi_unified_ani_level_cmd_send(wmi_unified_t wmi_handle, + uint32_t *freqs, + uint8_t num_freqs); + +/** + * wmi_unified_extract_ani_level() - WMI function to receive ani level cmd + * @wmi_hdl: WMI handle + * @info: pointer to ANI data received from the FW and stored in HOST + * @num_freqs: number of freqs in the above parameter * * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. */ +QDF_STATUS wmi_unified_extract_ani_level(wmi_unified_t wmi_handle, + uint8_t *data, + struct wmi_host_ani_level_event **info, + uint32_t *num_freqs); +#endif /* FEATURE_ANI_LEVEL_REQUEST */ + +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +/** + * wmi_unified_send_wlan_time_sync_ftm_trigger() - send ftm timesync trigger cmd + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @burst_mode: mode reg getting time sync relation from FW + * + * This function indicates the FW to trigger wlan time sync using FTM + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_send_wlan_time_sync_ftm_trigger(wmi_unified_t wmi_handle, + uint32_t vdev_id, + bool burst_mode); + +/** + * wmi_unified_send_wlan_time_sync_qtime() - send ftm time sync qtime cmd. + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @lpass_ts: audio qtime + * + * This function sends the wmi cmd to FW having audio qtime + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ QDF_STATUS -wmi_extract_cfr_peer_tx_event_param(void *wmi_hdl, void *evt_buf, - wmi_cfr_peer_tx_event_param *peer_tx_event); +wmi_unified_send_wlan_time_sync_qtime(wmi_unified_t wmi_handle, + uint32_t vdev_id, uint64_t lpass_ts); -#endif /* WLAN_CFR_ENABLE */ +/** + * wmi_unified_extract_time_sync_ftm_start_stop_params() - extract FTM time sync + * params + * @wmi_handle: wmi handle + * @evt_buf: event buffer + * @param: params received in start stop ftm timesync event + * + * This function extracts the params from ftm timesync start stop event + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_extract_time_sync_ftm_start_stop_params( + wmi_unified_t wmi_handle, void *evt_buf, + struct ftm_time_sync_start_stop_params *param); -#ifdef WLAN_FEATURE_PKT_CAPTURE /** - * wmi_unified_extract_vdev_mgmt_offload_event() - Extract mgmt offload params - * @wmi: WMI handle - * @evt_buf: Event buffer - * @params: Management offload event params + * wmi_unified_extract_time_sync_ftm_offset() - extract timesync FTM offset + * @wmi_handle: wmi handle + * @evt_buf: event buffer + * @param: params received in ftm timesync offset event * - * WMI function to extract management offload event params + * This function extracts the params from ftm timesync offset event * - * Return: QDF_STATUS + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_extract_vdev_mgmt_offload_event(wmi_unified_t wmi, void *evt_buf, - struct mgmt_offload_event_params *params); -#endif +wmi_unified_extract_time_sync_ftm_offset(wmi_unified_t wmi_handle, + void *evt_buf, + struct ftm_time_sync_offset *param); +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_bcn_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_bcn_api.h index 1b5e25e5d319f1f86bca1bc34769d9128c57fe73..52cc48722f5d06bc3ecb39f6d2470d02de917ed6 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_bcn_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_bcn_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,14 +30,14 @@ /** * wmi_unified_bcn_buf_ll_cmd() - prepare and send beacon buffer to fw for LL - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @param: bcn ll cmd parameter * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_unified_bcn_buf_ll_cmd(void *wmi_hdl, +wmi_unified_bcn_buf_ll_cmd(wmi_unified_t wmi_handle, wmi_bcn_send_from_host_cmd_fixed_param * param); #endif diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_api.h new file mode 100644 index 0000000000000000000000000000000000000000..aa457b905d47b8e81518a9fb7e9b6877a4ba180f --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_api.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _WMI_UNIFIED_CFR_API_H_ +#define _WMI_UNIFIED_CFR_API_H_ + +#include "wmi_unified_param.h" +#include "wmi_unified_cfr_param.h" + +#ifdef WLAN_CFR_ENABLE +/** + * wmi_unified_send_peer_cfr_capture_cmd() - WMI function to start CFR capture + * for a peer + * @wmi_handle: WMI handle + * @param: configuration params for capture + * + * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. + */ +QDF_STATUS +wmi_unified_send_peer_cfr_capture_cmd(wmi_unified_t wmi_handle, + struct peer_cfr_params *param); +/** + * wmi_extract_cfr_peer_tx_event_param() - WMI function to extract cfr tx event + * for a peer + * @wmi_handle: WMI handle + * @evt_buf: Buffer holding event data + * @peer_tx_event: pointer to hold tx event data + * + * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. + */ +QDF_STATUS +wmi_extract_cfr_peer_tx_event_param(wmi_unified_t wmi_handle, void *evt_buf, + wmi_cfr_peer_tx_event_param *peer_tx_event); + +#ifdef WLAN_ENH_CFR_ENABLE +/** + * wmi_unified_send_cfr_rcc_cmd() - WMI function to send CFR RCC param + * @wmi_handle: WMI handle + * @cfg: pointer to RCC param + * + * Return: QDF_STATUS_SUCCESS if success, else returns proper error code. + */ +QDF_STATUS wmi_unified_send_cfr_rcc_cmd(wmi_unified_t wmi_handle, + struct cfr_rcc_param *cfg); +#endif +#endif /* WLAN_CFR_ENABLE */ +#endif /* _WMI_UNIFIED_CFR_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_param.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_param.h new file mode 100644 index 0000000000000000000000000000000000000000..151d9f60b0e8a4ee9f4471269f93cff9c51c6087 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_cfr_param.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef _WMI_UNIFIED_CFR_PARAM_H_ +#define _WMI_UNIFIED_CFR_PARAM_H_ + +#ifdef WLAN_CFR_ENABLE + +#define WMI_HOST_PEER_CFR_TIMER_ENABLE 1 +#define WMI_HOST_PEER_CFR_TIMER_DISABLE 0 + + +/** + * struct peer_cfr_params - peer cfr capture cmd parameter + * @request: enable/disable cfr capture + * @macaddr: macaddr of the client + * @vdev_id: vdev id + * @periodicity: cfr capture period + * @bandwidth: bandwidth of cfr capture + * @capture_method: cfr capture method/type + */ +struct peer_cfr_params { + uint32_t request; + uint8_t *macaddr; + uint32_t vdev_id; + uint32_t periodicity; + uint32_t bandwidth; + uint32_t capture_method; +}; + + +#endif /* WLAN_CFR_ENABLE */ +#endif /* _WMI_UNIFIED_CFR_PARAM_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_concurrency_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_concurrency_api.h index 3e2d06d35695da96fffe94193b016b60cdfe4a60..2f2e968ed427bff5c086f2f2926b20afbdeb484a 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_concurrency_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_concurrency_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,22 +24,22 @@ /** * wmi_unified_set_mcc_channel_time_quota_cmd() - set MCC channel time quota - * @wmi: wmi handle - * @adapter_1_chan_number: adapter 1 channel number + * @wmi_handle: wmi handle + * @adapter_1_chan_freq: adapter 1 channel number * @adapter_1_quota: adapter 1 quota - * @adapter_2_chan_number: adapter 2 channel number + * @adapter_2_chan_freq: adapter 2 channel number * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_set_mcc_channel_time_quota_cmd - (void *wmi_hdl, +QDF_STATUS wmi_unified_set_mcc_channel_time_quota_cmd( + wmi_unified_t wmi_handle, uint32_t adapter_1_chan_freq, uint32_t adapter_1_quota, uint32_t adapter_2_chan_freq); /** * wmi_unified_set_mcc_channel_time_latency_cmd() - set MCC channel time latency - * @wmi: wmi handle - * @mcc_channel: mcc channel + * @wmi_handle: wmi handle + * @mcc_channel_freq: mcc channel freq * @mcc_channel_time_latency: MCC channel time latency. * * Currently used to set time latency for an MCC vdev/adapter using operating @@ -48,8 +48,8 @@ QDF_STATUS wmi_unified_set_mcc_channel_time_quota_cmd * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_set_mcc_channel_time_latency_cmd - (void *wmi_hdl, +QDF_STATUS wmi_unified_set_mcc_channel_time_latency_cmd( + wmi_unified_t wmi_handle, uint32_t mcc_channel_freq, uint32_t mcc_channel_time_latency); /** @@ -57,13 +57,14 @@ QDF_STATUS wmi_unified_set_mcc_channel_time_latency_cmd * scheduler * @wmi_handle: wmi handle * @mcc_adaptive_scheduler: enable/disable + * @pdev_id: pdev id * * This function enable/disable mcc adaptive scheduler in fw. * * Return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS wmi_unified_set_enable_disable_mcc_adaptive_scheduler_cmd( - void *wmi_hdl, uint32_t mcc_adaptive_scheduler, - uint32_t pdev_id); + wmi_unified_t wmi_handle, uint32_t mcc_adaptive_scheduler, + uint32_t pdev_id); #endif /* _WMI_UNIFIED_CONCURRENCY_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_crypto_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_crypto_api.h new file mode 100644 index 0000000000000000000000000000000000000000..3dce977c0bc2b38498e42ce030fd62d91e3ee7e1 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_crypto_api.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved. + * + * 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 contains the API definitions for the Unified Wireless Module + * Interface (WMI) specific to crypto component. + */ + +#ifndef _WMI_UNIFIED_CRYPTO_API_H_ +#define _WMI_UNIFIED_CRYPTO_API_H_ + +/* + * WMI_ADD_CIPHER_KEY_CMDID + */ +typedef enum { + PAIRWISE_USAGE = 0x00, + GROUP_USAGE = 0x01, + TX_USAGE = 0x02, /* default Tx Key - Static WEP only */ + PMK_USAGE = 0x04, /* PMK cache */ +} KEY_USAGE; + +/** + * wmi_extract_install_key_comp_event() - extract params of install key complete + * from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @len: length of the event buffer + * @params: Pointer to hold params of install key complete + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_extract_install_key_comp_event(wmi_unified_t wmi_handle, + void *evt_buf, uint32_t len, + struct wmi_install_key_comp_event *param); +#endif + diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_api.h index 8039749715ad637cbbb39ce681793b3d62b6cf3a..de378415c55378d99779542e4d491ba3d1da3898 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_api.h @@ -26,32 +26,32 @@ /** * wmi_unified_dbr_ring_cfg: Configure direct buffer rx rings - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @cfg: pointer to direct buffer rx config request * * Return: QDF status of operation */ -QDF_STATUS wmi_unified_dbr_ring_cfg(void *wmi_hdl, - struct direct_buf_rx_cfg_req *cfg); +QDF_STATUS wmi_unified_dbr_ring_cfg(wmi_unified_t wmi_handle, + struct direct_buf_rx_cfg_req *cfg); /** * wmi_extract_dbr_buf_release_fixed : Extract direct buffer rx fixed param * from buffer release event - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @evt_buf: Event buffer * @param: Pointer to direct buffer rx response struct * * Return: QDF status of operation */ QDF_STATUS wmi_extract_dbr_buf_release_fixed( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct direct_buf_rx_rsp *param); /** * wmi_extract_dbr_buf_release_entry: Extract direct buffer rx buffer tlv * - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @evt_buf: Event buffer * @idx: Index of the module for which capability is received * @param: Pointer to direct buffer rx entry @@ -59,14 +59,14 @@ QDF_STATUS wmi_extract_dbr_buf_release_fixed( * Return: QDF status of operation */ QDF_STATUS wmi_extract_dbr_buf_release_entry( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct direct_buf_rx_entry *param); /** * wmi_extract_dbr_buf_metadata: Extract direct buffer metadata * - * @wmi_hdl: WMI handle + * @wmi_handle: WMI handle * @evt_buf: Event buffer * @idx: Index of the module for which capability is received * @param: Pointer to direct buffer metadata @@ -74,7 +74,7 @@ QDF_STATUS wmi_extract_dbr_buf_release_entry( * Return: QDF status of operation */ QDF_STATUS wmi_extract_dbr_buf_metadata( - void *wmi_hdl, + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct direct_buf_rx_metadata *param); diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_param.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_param.h index f0f903287f8fd9fce516c6d32936f83c6d6be91d..ed7226b69801c02a1aa4092b2112de6e2a86abb4 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_param.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dbr_param.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -20,7 +20,9 @@ #define _WMI_UNIFIED_DBR_PARAM_H_ #define WMI_HOST_DBR_RING_ADDR_LO_S 0 -#define WMI_HOST_DBR_RING_ADDR_LO 0xffffffff +#define WMI_HOST_DBR_RING_ADDR_LO_M 0xffffffff +#define WMI_HOST_DBR_RING_ADDR_LO \ + (WMI_HOST_DBR_RING_ADDR_LO_M << WMI_HOST_DBR_RING_ADDR_LO_S) #define WMI_HOST_DBR_RING_ADDR_LO_GET(dword) \ WMI_HOST_F_MS(dword, WMI_HOST_DBR_RING_ADDR_LO) @@ -28,7 +30,9 @@ WMI_HOST_F_RMW(dword, val, WMI_HOST_DBR_RING_ADDR_LO) #define WMI_HOST_DBR_RING_ADDR_HI_S 0 -#define WMI_HOST_DBR_RING_ADDR_HI 0xf +#define WMI_HOST_DBR_RING_ADDR_HI_M 0xf +#define WMI_HOST_DBR_RING_ADDR_HI \ + (WMI_HOST_DBR_RING_ADDR_HI_M << WMI_HOST_DBR_RING_ADDR_HI_S) #define WMI_HOST_DBR_RING_ADDR_HI_GET(dword) \ WMI_HOST_F_MS(dword, WMI_HOST_DBR_RING_ADDR_HI) @@ -36,7 +40,9 @@ WMI_HOST_F_RMW(dword, val, WMI_HOST_DBR_RING_ADDR_HI) #define WMI_HOST_DBR_DATA_ADDR_LO_S 0 -#define WMI_HOST_DBR_DATA_ADDR_LO 0xffffffff +#define WMI_HOST_DBR_DATA_ADDR_LO_M 0xffffffff +#define WMI_HOST_DBR_DATA_ADDR_LO \ + (WMI_HOST_DBR_DATA_ADDR_LO_M << WMI_HOST_DBR_DATA_ADDR_LO_S) #define WMI_HOST_DBR_DATA_ADDR_LO_GET(dword) \ WMI_HOST_F_MS(dword, WMI_HOST_DBR_DATA_ADDR_LO) @@ -44,7 +50,9 @@ WMI_HOST_F_RMW(dword, val, WMI_HOST_DBR_DATA_ADDR_LO) #define WMI_HOST_DBR_DATA_ADDR_HI_S 0 -#define WMI_HOST_DBR_DATA_ADDR_HI 0xf +#define WMI_HOST_DBR_DATA_ADDR_HI_M 0xf +#define WMI_HOST_DBR_DATA_ADDR_HI \ + (WMI_HOST_DBR_DATA_ADDR_HI_M << WMI_HOST_DBR_DATA_ADDR_HI_S) #define WMI_HOST_DBR_DATA_ADDR_HI_GET(dword) \ WMI_HOST_F_MS(dword, WMI_HOST_DBR_DATA_ADDR_HI) @@ -52,7 +60,10 @@ WMI_HOST_F_RMW(dword, val, WMI_HOST_DBR_DATA_ADDR_HI) #define WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_S 12 -#define WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA 0x7fffff +#define WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_M 0x7ffff +#define WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA \ + (WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_M << \ + WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_S) #define WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET(dword) \ WMI_HOST_F_MS(dword, WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA) diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dfs_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dfs_api.h index 932da83cb720990ebfb17f48ff70c8d5a1814fdb..cf8ccca9eeb665cd1f1a9e0fd052e6d73f1a7bc3 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dfs_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_dfs_api.h @@ -28,14 +28,15 @@ /** * wmi_extract_dfs_cac_complete_event() - function to handle cac complete event - * @handle: wma handle + * @wmi_handle: wmi handle * @event_buf: event buffer * @vdev_id: vdev id * @len: length of buffer * * Return: 0 for success or error code */ -QDF_STATUS wmi_extract_dfs_cac_complete_event(void *wmi_hdl, +QDF_STATUS wmi_extract_dfs_cac_complete_event( + wmi_unified_t wmi_handle, uint8_t *evt_buf, uint32_t *vdev_id, uint32_t len); @@ -43,27 +44,27 @@ QDF_STATUS wmi_extract_dfs_cac_complete_event(void *wmi_hdl, /** * wmi_extract_dfs_ocac_complete_event() - function to handle off channel * CAC complete event - * @handle: wmi handle + * @wmi_handle: wmi handle * @event_buf: event buffer - * @vdev_adfs_complete_status: off channel cac complete params + * @param: off channel cac complete params * * Return: 0 for success or error code */ QDF_STATUS -wmi_extract_dfs_ocac_complete_event(void *wmi_hdl, uint8_t *evt_buf, +wmi_extract_dfs_ocac_complete_event(wmi_unified_t wmi_handle, uint8_t *evt_buf, struct vdev_adfs_complete_status *param); /** * wmi_extract_dfs_radar_detection_event() - function to handle radar event - * @handle: wma handle + * @wmi_handle: wmi handle * @event_buf: event buffer * @radar_found: radar found event info - * @vdev_id: vdev id * @len: length of buffer * * Return: 0 for success or error code */ -QDF_STATUS wmi_extract_dfs_radar_detection_event(void *wmi_hdl, +QDF_STATUS wmi_extract_dfs_radar_detection_event( + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct radar_found_info *radar_found, uint32_t len); @@ -71,14 +72,15 @@ QDF_STATUS wmi_extract_dfs_radar_detection_event(void *wmi_hdl, #ifdef QCA_MCL_DFS_SUPPORT /** * wmi_extract_wlan_radar_event_info() - function to handle radar pulse event. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @evt_buf: event buffer * @wlan_radar_event: pointer to radar event info structure * @len: length of buffer * * Return: QDF_STATUS */ -QDF_STATUS wmi_extract_wlan_radar_event_info(void *wmi_hdl, +QDF_STATUS wmi_extract_wlan_radar_event_info( + wmi_unified_t wmi_handle, uint8_t *evt_buf, struct radar_event_info *wlan_radar_event, uint32_t len); @@ -87,38 +89,38 @@ QDF_STATUS wmi_extract_wlan_radar_event_info(void *wmi_hdl, #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) /** * wmi_send_usenol_pdev_param() - function to send usenol pdev param. - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @usenol: value of usenol * @pdev: pointer to objmgr_pdev structure * * Return: QDF_STATUS */ -QDF_STATUS wmi_send_usenol_pdev_param(void *wmi_hdl, bool usenol, +QDF_STATUS wmi_send_usenol_pdev_param(wmi_unified_t wmi_handle, bool usenol, struct wlan_objmgr_pdev *pdev); /** * wmi_send_subchan_marking_pdev_param() - Function to send subchannel * marking pdev param. - * @wmi_hdl: WMI handle. + * @wmi_handle: WMI handle. * @subchanmark: Value of use subchannel marking. * @pdev: Pointer to objmgr_pdev structure. * * Return: QDF_STATUS */ QDF_STATUS -wmi_send_subchan_marking_pdev_param(void *wmi_hdl, +wmi_send_subchan_marking_pdev_param(wmi_unified_t wmi_handle, bool subchanmark, struct wlan_objmgr_pdev *pdev); #else static inline QDF_STATUS -wmi_send_usenol_pdev_param(void *wmi_hdl, bool usenol, +wmi_send_usenol_pdev_param(wmi_unified_t wmi_hdl, bool usenol, struct wlan_objmgr_pdev *pdev) { return QDF_STATUS_SUCCESS; } static inline QDF_STATUS -wmi_send_subchan_marking_pdev_param(void *wmi_hdl, +wmi_send_subchan_marking_pdev_param(wmi_unified_t wmi_handle, bool subchanmark, struct wlan_objmgr_pdev *pdev) { diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_extscan_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_extscan_api.h index 12e6e93ebd39f3a6ccc49cd06464b17cdf356517..102efbceb4573e8fd2f1c5f2b13d7fd64d072e17 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_extscan_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_extscan_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,47 +19,151 @@ #ifndef _WMI_UNIFIED_EXTSCAN_API_H_ #define _WMI_UNIFIED_EXTSCAN_API_H_ -QDF_STATUS wmi_unified_reset_passpoint_network_list_cmd(void *wmi_hdl, - struct wifi_passpoint_req_param *req); +/** + * wmi_unified_reset_passpoint_network_list_cmd() - reset passpoint network list + * @wmi_handle: wmi handle + * @req: passpoint network request structure + * + * This function sends down WMI command with network id set to wildcard id. + * firmware shall clear all the config entries + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_reset_passpoint_network_list_cmd( + wmi_unified_t wmi_handle, + struct wifi_passpoint_req_param *req); + +/** + * wmi_unified_set_passpoint_network_list_cmd() - set passpoint network list + * @wmi_handle: wmi handle + * @req: passpoint network request structure + * + * This function reads the incoming @req and fill in the destination + * WMI structure and send down the passpoint configs down to the firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ -QDF_STATUS wmi_unified_set_passpoint_network_list_cmd(void *wmi_hdl, - struct wifi_passpoint_req_param *req); +QDF_STATUS wmi_unified_set_passpoint_network_list_cmd( + wmi_unified_t wmi_handle, + struct wifi_passpoint_req_param *req); -QDF_STATUS wmi_unified_set_epno_network_list_cmd(void *wmi_hdl, +/** wmi_unified_set_epno_network_list_cmd() - set epno network list + * @wmi_handle: wmi handle + * @req: epno config params request structure + * + * This function reads the incoming epno config request structure + * and constructs the WMI message to the firmware. + * + * Returns: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failures, + * error number otherwise + */ +QDF_STATUS wmi_unified_set_epno_network_list_cmd( + wmi_unified_t wmi_handle, struct wifi_enhanced_pno_params *req); -QDF_STATUS wmi_unified_extscan_get_capabilities_cmd(void *wmi_hdl, - struct extscan_capabilities_params *pgetcapab); +/** + * wmi_unified_extscan_get_capabilities_cmd() - extscan get capabilities + * @wmi_handle: wmi handle + * @pgetcapab: get capabilities params + * + * This function send request to fw to get extscan capabilities. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extscan_get_capabilities_cmd( + wmi_unified_t wmi_handle, + struct extscan_capabilities_params *pgetcapab); -QDF_STATUS wmi_unified_extscan_get_cached_results_cmd(void *wmi_hdl, - struct extscan_cached_result_params *pcached_results); +/** + * wmi_unified_extscan_get_cached_results_cmd() - extscan get cached results + * @wmi_handle: wmi handle + * @pcached_results: cached results parameters + * + * This function send request to fw to get cached results. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extscan_get_cached_results_cmd( + wmi_unified_t wmi_handle, + struct extscan_cached_result_params *pcached_results); -QDF_STATUS wmi_unified_extscan_stop_change_monitor_cmd(void *wmi_hdl, - struct extscan_capabilities_reset_params *reset_req); +/** + * wmi_unified_extscan_stop_change_monitor_cmd() - send stop change monitor cmd + * @wmi_handle: wmi handle + * @reset_req: Reset change request params + * + * This function sends stop change monitor request to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extscan_stop_change_monitor_cmd( + wmi_unified_t wmi_handle, + struct extscan_capabilities_reset_params *reset_req); -QDF_STATUS wmi_unified_extscan_start_change_monitor_cmd(void *wmi_hdl, - struct extscan_set_sig_changereq_params * - psigchange); +/** + * wmi_unified_extscan_start_change_monitor_cmd() - start change monitor cmd + * @wmi_handle: wmi handle + * @psigchange: change monitor request params + * + * This function sends start change monitor request to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extscan_start_change_monitor_cmd( + wmi_unified_t wmi_handle, + struct extscan_set_sig_changereq_params *psigchange); -QDF_STATUS wmi_unified_extscan_stop_hotlist_monitor_cmd(void *wmi_hdl, - struct extscan_bssid_hotlist_reset_params *photlist_reset); +/** + * wmi_unified_extscan_stop_hotlist_monitor_cmd() - stop hotlist monitor + * @wmi_handle: wmi handle + * @photlist_reset: hotlist reset params + * + * This function configures hotlist monitor to stop in fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_extscan_stop_hotlist_monitor_cmd( + wmi_unified_t wmi_handle, + struct extscan_bssid_hotlist_reset_params *photlist_reset); /** * wmi_unified_extscan_start_hotlist_monitor_cmd() - start hotlist monitor - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @params: hotlist params * * This function configures hotlist monitor to start in fw. * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_extscan_start_hotlist_monitor_cmd(void *wmi_hdl, - struct extscan_bssid_hotlist_set_params *params); +QDF_STATUS wmi_unified_extscan_start_hotlist_monitor_cmd( + wmi_unified_t wmi_handle, + struct extscan_bssid_hotlist_set_params *params); -QDF_STATUS wmi_unified_stop_extscan_cmd(void *wmi_hdl, - struct extscan_stop_req_params *pstopcmd); +/** + * wmi_unified_stop_extscan_cmd() - stop extscan command to fw. + * @wmi_handle: wmi handle + * @pstopcmd: stop scan command request params + * + * This function sends stop extscan request to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS wmi_unified_stop_extscan_cmd( + wmi_unified_t wmi_handle, + struct extscan_stop_req_params *pstopcmd); -QDF_STATUS wmi_unified_start_extscan_cmd(void *wmi_hdl, - struct wifi_scan_cmd_req_params *pstart); +/** + * wmi_unified_start_extscan_cmd() - start extscan command to fw. + * @wmi_handle: wmi handle + * @pstart: scan command request params + * + * This function sends start extscan request to fw. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure. + */ +QDF_STATUS wmi_unified_start_extscan_cmd( + wmi_unified_t wmi_handle, + struct wifi_scan_cmd_req_params *pstart); #endif /* _WMI_UNIFIED_EXTSCAN_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_gpio_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_gpio_api.h new file mode 100644 index 0000000000000000000000000000000000000000..15f9bebf4cee0f3268a6be809e8a13a6b4b08477 --- /dev/null +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_gpio_api.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ +/** + * DOC: Implement API's specific to gpio component. + */ + +#ifndef _WMI_UNIFIED_GPIO_API_H_ +#define _WMI_UNIFIED_GPIO_API_H_ + +#include + +/** + * wmi_unified_gpio_config_cmd_send() - WMI gpio config function + * @wmi_handle: handle to WMI. + * @param: pointer to hold gpio config param + * + * Send WMI set gpio configuration to firmware. + * + * Return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_gpio_config_cmd_send(wmi_unified_t wmi_handle, + struct gpio_config_params *param); + +/** + * wmi_unified_gpio_output_cmd_send() - WMI gpio output function + * @wmi_handle: handle to WMI. + * @param: pointer to hold gpio output param + * + * Send WMI set gpio output value to firmware. + * + * Return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_gpio_output_cmd_send(wmi_unified_t wmi_handle, + struct gpio_output_params *param); + +#endif /* _WMI_UNIFIED_GPIO_API_H_ */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_nan_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_nan_api.h index e357dc3079a32a0da93ade2ad083aba38bdad2d4..ee0fafd9999e39bf068d42fbf862d0521632b52c 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_nan_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_nan_api.h @@ -47,34 +47,34 @@ QDF_STATUS wmi_unified_nan_disable_req_cmd(wmi_unified_t wmi_handle, /** * wmi_unified_ndp_initiator_req_cmd_send - api to send initiator request to FW - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @req: pointer to request buffer * * Return: status of operation */ QDF_STATUS -wmi_unified_ndp_initiator_req_cmd_send(void *wmi_hdl, +wmi_unified_ndp_initiator_req_cmd_send(wmi_unified_t wmi_handle, struct nan_datapath_initiator_req *req); /** * wmi_unified_ndp_responder_req_cmd_send - api to send responder request to FW - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @req: pointer to request buffer * * Return: status of operation */ QDF_STATUS -wmi_unified_ndp_responder_req_cmd_send(void *wmi_hdl, +wmi_unified_ndp_responder_req_cmd_send(wmi_unified_t wmi_handle, struct nan_datapath_responder_req *req); /** * wmi_unified_ndp_end_req_cmd_send - api to send end request to FW - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @req: pointer to request buffer * * Return: status of operation */ -QDF_STATUS wmi_unified_ndp_end_req_cmd_send(void *wmi_hdl, +QDF_STATUS wmi_unified_ndp_end_req_cmd_send(wmi_unified_t wmi_handle, struct nan_datapath_end_req *req); /** diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_p2p_api.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_p2p_api.h index 3a571582a190bb0e007c539ddc5749c937313778..e5a5db3f8695b8cab595518d2ab222eed7911fe8 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_p2p_api.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_p2p_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,22 +26,22 @@ /** * wmi_unified_set_p2pgo_oppps_req() - send p2p go opp power save request to fw - * @wmi_hdl: wmi handle - * @opps: p2p opp power save parameters + * @wmi_handle: wmi handle + * @oppps: p2p opp power save parameters * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_set_p2pgo_oppps_req(void *wmi_hdl, +QDF_STATUS wmi_unified_set_p2pgo_oppps_req(wmi_unified_t wmi_handle, struct p2p_ps_params *oppps); /** * wmi_unified_set_p2pgo_noa_req_cmd() - send p2p go noa request to fw - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @noa: p2p power save parameters * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(void *wmi_hdl, +QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(wmi_unified_t wmi_handle, struct p2p_ps_params *noa); /** @@ -52,52 +52,54 @@ QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(void *wmi_hdl, * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_p2p_noa_ev_param(void *wmi_hdl, +QDF_STATUS wmi_extract_p2p_noa_ev_param(wmi_unified_t wmi_handle, void *evt_buf, struct p2p_noa_info *param); /** * wmi_send_set_mac_addr_rx_filter_cmd() - set mac addr rx filter cmd - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @param: Pointer to set mac filter struct * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_send_set_mac_addr_rx_filter_cmd(void *wmi_hdl, +wmi_send_set_mac_addr_rx_filter_cmd(wmi_unified_t wmi_handle, struct p2p_set_mac_filter *param); /** * wmi_extract_mac_addr_rx_filter_evt_param() - extract mac addr rx filter evt - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @evt_buf: pointer to event buffer * @param: Pointer to extracted evt info * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS -wmi_extract_mac_addr_rx_filter_evt_param(void *wmi_hdl, void *evt_buf, +wmi_extract_mac_addr_rx_filter_evt_param(wmi_unified_t wmi_handle, + void *evt_buf, struct p2p_set_mac_filter_evt *param); #ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * wmi_unified_p2p_lo_start_cmd() - send p2p lo start request to fw - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @param: p2p listen offload start parameters * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_p2p_lo_start_cmd(void *wmi_hdl, +QDF_STATUS wmi_unified_p2p_lo_start_cmd(wmi_unified_t wmi_handle, struct p2p_lo_start *param); /** * wmi_unified_p2p_lo_stop_cmd() - send p2p lo stop request to fw - * @wmi_hdl: wmi handle + * @wmi_handle: wmi handle * @vdev_id: vdev id * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_p2p_lo_stop_cmd(void *wmi_hdl, uint8_t vdev_id); +QDF_STATUS wmi_unified_p2p_lo_stop_cmd(wmi_unified_t wmi_handle, + uint8_t vdev_id); /** * wmi_extract_p2p_lo_stop_ev_param() - extract p2p lo stop param from event @@ -107,7 +109,7 @@ QDF_STATUS wmi_unified_p2p_lo_stop_cmd(void *wmi_hdl, uint8_t vdev_id); * * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_extract_p2p_lo_stop_ev_param(void *wmi_hdl, +QDF_STATUS wmi_extract_p2p_lo_stop_ev_param(wmi_unified_t wmi_handle, void *evt_buf, struct p2p_lo_event *param); #endif /* FEATURE_P2P_LISTEN_OFFLOAD */ diff --git a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h index 8786fdb5faf9298174e0d928dd1c34f692f4be64..6384d3d58656d05a782bdce92266cdd64fafb170 100644 --- a/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h +++ b/drivers/staging/qca-wifi-host-cmn/wmi/inc/wmi_unified_param.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -374,6 +373,12 @@ #define WMI_HOST_TPC_REGINDEX_MAX 4 #define WMI_HOST_ARRAY_GAIN_NUM_STREAMS 2 +/* AST Index for flow override */ +#define WMI_CONFIG_MSDU_AST_INDEX_0 0x0 +#define WMI_CONFIG_MSDU_AST_INDEX_1 0x1 +#define WMI_CONFIG_MSDU_AST_INDEX_2 0x2 +#define WMI_CONFIG_MSDU_AST_INDEX_3 0x3 + #include "qdf_atomic.h" #ifdef BIG_ENDIAN_HOST @@ -462,16 +467,6 @@ typedef enum { WMI_HOST_MODE_MAX = 24 } WMI_HOST_WLAN_PHY_MODE; -#ifndef CMN_VDEV_MGR_TGT_IF_ENABLE -typedef enum { - WMI_HOST_VDEV_START_OK = 0, - WMI_HOST_VDEV_START_CHAN_INVALID, - WMI_HOST_VDEV_START_CHAN_BLOCKED, - WMI_HOST_VDEV_START_CHAN_DFS_VIOLATION, - WMI_HOST_VDEV_START_TIMEOUT, -} WMI_HOST_VDEV_START_STATUS; -#endif - /* * Needs to be removed and use channel_param based * on how it is processed @@ -583,6 +578,7 @@ typedef enum { * @WMI_HOST_CHAN_WIDTH_80P80: 80+80 MHz channel operating width * @WMI_HOST_CHAN_WIDTH_5: 5 MHz channel operating width * @WMI_HOST_CHAN_WIDTH_10: 10 MHz channel operating width + * @WMI_HOST_CHAN_WIDTH_165: 165 MHz channel operating width */ typedef enum { WMI_HOST_CHAN_WIDTH_20 = 0, @@ -592,6 +588,7 @@ typedef enum { WMI_HOST_CHAN_WIDTH_80P80 = 4, WMI_HOST_CHAN_WIDTH_5 = 5, WMI_HOST_CHAN_WIDTH_10 = 6, + WMI_HOST_CHAN_WIDTH_165 = 7, } wmi_host_channel_width; #define ATH_EXPONENT_TO_VALUE(v) ((1< */ diff --git a/drivers/staging/qcacld-3.0/components/blacklist_mgr/dispatcher/src/wlan_blm_ucfg_api.c b/drivers/staging/qcacld-3.0/components/blacklist_mgr/dispatcher/src/wlan_blm_ucfg_api.c index b53d5f3ddb46ebe8a87d696568031633a489e3ad..5ce6da9b0e89b779dd019a9d8566c88e1148e8fe 100644 --- a/drivers/staging/qcacld-3.0/components/blacklist_mgr/dispatcher/src/wlan_blm_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/blacklist_mgr/dispatcher/src/wlan_blm_ucfg_api.c @@ -22,6 +22,7 @@ #include #include #include +#include "wlan_pmo_obj_mgmt_api.h" QDF_STATUS ucfg_blm_init(void) { @@ -106,13 +107,83 @@ QDF_STATUS ucfg_blm_deinit(void) return status; } +QDF_STATUS ucfg_blm_psoc_set_suspended(struct wlan_objmgr_psoc *psoc, + bool state) +{ + struct blm_psoc_priv_obj *blm_psoc_obj; + + blm_psoc_obj = blm_get_psoc_obj(psoc); + + if (!blm_psoc_obj) { + blm_err("BLM psoc obj NULL"); + return QDF_STATUS_E_FAILURE; + } + + blm_psoc_obj->is_suspended = state; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_blm_psoc_get_suspended(struct wlan_objmgr_psoc *psoc, + bool *state) +{ + struct blm_psoc_priv_obj *blm_psoc_obj; + + blm_psoc_obj = blm_get_psoc_obj(psoc); + + if (!blm_psoc_obj) { + blm_err("BLM psoc obj NULL"); + *state = true; + return QDF_STATUS_E_FAILURE; + } + + *state = blm_psoc_obj->is_suspended; + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +ucfg_blm_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + ucfg_blm_psoc_set_suspended(psoc, true); + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +ucfg_blm_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + ucfg_blm_psoc_set_suspended(psoc, false); + blm_update_reject_ap_list_to_fw(psoc); + return QDF_STATUS_SUCCESS; +} + +static inline void +ucfg_blm_register_pmo_handler(void) +{ + pmo_register_suspend_handler(WLAN_UMAC_COMP_BLACKLIST_MGR, + ucfg_blm_suspend_handler, NULL); + pmo_register_resume_handler(WLAN_UMAC_COMP_BLACKLIST_MGR, + ucfg_blm_resume_handler, NULL); +} + +static inline void +ucfg_blm_unregister_pmo_handler(void) +{ + pmo_unregister_suspend_handler(WLAN_UMAC_COMP_BLACKLIST_MGR, + ucfg_blm_suspend_handler); + pmo_unregister_resume_handler(WLAN_UMAC_COMP_BLACKLIST_MGR, + ucfg_blm_resume_handler); +} + QDF_STATUS ucfg_blm_psoc_open(struct wlan_objmgr_psoc *psoc) { + ucfg_blm_register_pmo_handler(); return blm_cfg_psoc_open(psoc); } QDF_STATUS ucfg_blm_psoc_close(struct wlan_objmgr_psoc *psoc) { + ucfg_blm_unregister_pmo_handler(); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/components/cfg/cfg_all.h b/drivers/staging/qcacld-3.0/components/cfg/cfg_all.h index 3aa0d3fe91d145ac91654f4779257129128a2f94..cdc133b1a08db8a2a6f6491b453c340ae87d6114 100644 --- a/drivers/staging/qcacld-3.0/components/cfg/cfg_all.h +++ b/drivers/staging/qcacld-3.0/components/cfg/cfg_all.h @@ -41,6 +41,12 @@ #define CFG_NAN_ALL #endif +#ifdef WLAN_CFR_ENABLE +#include "cfr_cfg.h" +#else +#define CFG_CFR_ALL +#endif + #include "wlan_pmo_cfg.h" #include "hdd_config.h" #include "hdd_dp_cfg.h" @@ -63,4 +69,5 @@ CFG_P2P_ALL \ CFG_PMO_ALL \ CFG_TDLS_ALL \ - CFG_PKT_CAPTURE_MODE_ALL + CFG_PKT_CAPTURE_MODE_ALL \ + CFG_CFR_ALL diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 0c74f912454cbe1b294cc064cda70ba7f49ce0f1..46a6a4ff82c0944ef799c006fcd9064cfb6d6fbb 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +31,7 @@ #include "qdf_status.h" #include "wlan_objmgr_psoc_obj.h" #include "wlan_policy_mgr_public_struct.h" +#include "wlan_utility.h" struct target_psoc_info; @@ -86,7 +88,7 @@ enum sap_csa_reason_code { CSA_REASON_BAND_RESTRICTED }; -/* +/** * enum PM_AP_DFS_MASTER_MODE - AP dfs master mode * @PM_STA_SAP_ON_DFS_DEFAULT - Disallow STA+SAP SCC on DFS channel * @PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED - Allow STA+SAP SCC @@ -446,9 +448,9 @@ uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc); * Searches and gets the channel number from the scan results and checks if * concurrency is allowed for the given session ID * - * Non zero channel number if concurrency is allowed, zero otherwise + * Return: Non zero channel frequency value if concurrency is allowed else 0 */ -uint8_t policy_mgr_search_and_check_for_session_conc( +uint32_t policy_mgr_search_and_check_for_session_conc( struct wlan_objmgr_psoc *psoc, uint8_t session_id, void *roam_profile); @@ -456,7 +458,7 @@ uint8_t policy_mgr_search_and_check_for_session_conc( * policy_mgr_is_chnl_in_diff_band() - to check that given channel * is in diff band from existing channel or not * @psoc: pointer to psoc - * @channel: given channel + * @ch_freq: given channel frequency * * This API will check that if the passed channel is in diff band than the * already existing connections or not. @@ -464,26 +466,26 @@ uint8_t policy_mgr_search_and_check_for_session_conc( * Return: true if channel is in diff band */ bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, - uint8_t channel); + uint32_t ch_freq); /** * policy_mgr_check_for_session_conc() - Check if concurrency is * allowed for a session * @psoc: PSOC object information * @session_id: Session ID - * @channel: Channel number + * @ch_freq: Channel frequency * * Checks if connection is allowed for a given session_id * * True if the concurrency is allowed, false otherwise */ -bool policy_mgr_check_for_session_conc( - struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel); +bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint32_t ch_freq); /** * policy_mgr_handle_conc_multiport() - to handle multiport concurrency * @session_id: Session ID - * @channel: Channel number + * @ch_freq: Channel frequency * @reason: reason for connection update * * This routine will handle STA side concurrency when policy manager @@ -491,9 +493,10 @@ bool policy_mgr_check_for_session_conc( * * Return: QDF_STATUS */ -QDF_STATUS policy_mgr_handle_conc_multiport( - struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel, - enum policy_mgr_conn_update_reason reason); +QDF_STATUS +policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint32_t ch_freq, + enum policy_mgr_conn_update_reason reason); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH /** @@ -548,7 +551,7 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA * @psoc: PSOC object information * @vdev_id: Vdev id - * @channel: Channel to change + * @ch_freq: Channel frequency to change * @ch_width: channel width to change * @forced: Force to switch channel, ignore SCC/MCC check * @@ -556,17 +559,15 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( * * Return: None */ -void policy_mgr_change_sap_channel_with_csa( - struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, - uint32_t ch_width, - bool forced); +void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t ch_freq, + uint32_t ch_width, bool forced); + #else static inline void policy_mgr_change_sap_channel_with_csa( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, - uint32_t ch_width, - bool forced) + uint8_t vdev_id, uint32_t ch_freq, + uint32_t ch_width, bool forced) { } @@ -625,37 +626,28 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, uint8_t session_id); -/** - * policy_mgr_skip_dfs_ch() - skip dfs channel or not - * @psoc: pointer to soc - * @skip_dfs_channel: pointer to result - * - * Return: QDF_STATUS - */ -QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, - bool *skip_dfs_channel); - /** * policy_mgr_get_channel() - provide channel number of given mode and vdevid * @psoc: PSOC object information * @mode: given mode * @vdev_id: pointer to vdev_id * - * This API will provide channel number of matching mode and vdevid. + * This API will provide channel frequency value of matching mode and vdevid. * If vdev_id is NULL then it will match only mode * If vdev_id is not NULL the it will match both mode and vdev_id * - * Return: channel number + * Return: channel frequency value */ -uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, uint32_t *vdev_id); +uint32_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t *vdev_id); /** * policy_mgr_get_pcl() - provides the preferred channel list for * new connection * @psoc: PSOC object information - * @mode: Device mode - * @pcl_channels: PCL channels + * @mode: Device mode + * @pcl_channels: Preferred channel freq list * @len: length of the PCL * @pcl_weight: Weights of the PCL * @weight_len: Max length of the weights list @@ -668,27 +660,27 @@ uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t *pcl_channels, uint32_t *len, - uint8_t *pcl_weight, uint32_t weight_len); + enum policy_mgr_con_mode mode, + uint32_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len); /** * policy_mgr_init_chan_avoidance() - init channel avoidance in policy manager. * @psoc: PSOC object information - * @chan_list: channel list + * @chan_freq_list: channel frequency list * @chan_cnt: channel count * * Return: QDF_STATUS */ QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, - uint16_t *chan_list, + qdf_freq_t *chan_freq_list, uint16_t chan_cnt); /** * policy_mgr_update_with_safe_channel_list() - provides the safe * channel list * @psoc: PSOC object information - * @pcl_channels: channel list + * @pcl_channels: channel freq list * @len: length of the list * @weight_list: Weights of the PCL * @weight_len: Max length of the weights list @@ -699,8 +691,10 @@ QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, * Return: None */ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_channels, uint32_t *len, - uint8_t *weight_list, uint32_t weight_len); + uint32_t *pcl_channels, + uint32_t *len, + uint8_t *weight_list, + uint32_t weight_len); /** * policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel @@ -718,16 +712,18 @@ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, * to give preferred channel list. once we get preferred channel list, loop * through list to find first non-dfs channel from ascending order. * - * Return: uint8_t non-dfs channel + * Return: uint32_t non-dfs channel frequency */ -uint8_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, bool for_existing_conn); +uint32_t +policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + bool for_existing_conn); /** * policy_mgr_is_any_nondfs_chnl_present() - Find any non-dfs * channel from conc table * @psoc: PSOC object information - * @channel: pointer to channel which needs to be filled + * @ch_freq: pointer to channel frequency which needs to be filled * * In-case if any connection is already present whose channel is none dfs then * return that channel @@ -735,7 +731,7 @@ uint8_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, * Return: true up-on finding non-dfs channel else false */ bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, - uint8_t *channel); + uint32_t *ch_freq); /** * policy_mgr_get_dfs_beaconing_session_id() - to find the @@ -753,7 +749,7 @@ uint32_t policy_mgr_get_dfs_beaconing_session_id( * policy_mgr_is_any_dfs_beaconing_session_present() - to find * if any DFS session * @psoc: PSOC object information - * @channel: pointer to channel number that needs to filled + * @ch_freq: pointer to channel frequency that needs to filled * * If any beaconing session such as SAP or GO present and it is on DFS channel * then this function will return true @@ -761,46 +757,46 @@ uint32_t policy_mgr_get_dfs_beaconing_session_id( * Return: true if session is on DFS or false if session is on non-dfs channel */ bool policy_mgr_is_any_dfs_beaconing_session_present( - struct wlan_objmgr_psoc *psoc, uint8_t *channel); - + struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq); /** * policy_mgr_allow_concurrency() - Check for allowed concurrency * combination consulting the PCL * @psoc: PSOC object information * @mode: new connection mode - * @channel: channel on which new connection is coming up + * @ch_freq: channel frequency on which new connection is coming up * @bw: Bandwidth requested by the connection (optional) * * When a new connection is about to come up check if current * concurrency combination including the new connection is * allowed or not based on the HW capability * - * Return: True/False + * Return: True/False based on concurrency support */ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t channel, enum hw_mode_bandwidth bw); + enum policy_mgr_con_mode mode, + uint32_t ch_freq, + enum hw_mode_bandwidth bw); /** * policy_mgr_nan_sap_pre_enable_conc_check() - Check if NAN+SAP SCC is * allowed in given ch * @psoc: PSOC object information * @mode: Connection mode - * @ch: channel to check + * @ch_freq: channel frequency to check * * Return: True if allowed else false */ bool policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t ch); + uint32_t ch_freq); /** * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency * combination when channel switch * @psoc: PSOC object information * @mode: connection mode - * @channel: target channel to switch + * @ch_freq: target channel frequency to switch * @vdev_id: vdev id of channel switch interface * @forced: forced to chan switch. * @reason: request reason of CSA @@ -817,12 +813,11 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, * * Return: True/False */ -bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t channel, - uint32_t vdev_id, - bool forced, - enum sap_csa_reason_code reason); +bool +policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t ch_freq, uint32_t vdev_id, + bool forced, enum sap_csa_reason_code reason); /** * policy_mgr_get_first_connection_pcl_table_index() - provides the @@ -873,6 +868,25 @@ enum policy_mgr_two_connection_mode policy_mgr_get_third_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc); +#ifdef FEATURE_FOURTH_CONNECTION +/** + * policy_mgr_get_fourth_connection_pcl_table_index() - provides the + * row index to fourthConnectionPclTable to get to the correct + * pcl + * @psoc: PSOC object information + * + * This function provides the row index to + * fourthConnectionPclTable. The index is derived based on + * current connection, band on which it is on & chain mask it is + * using, as obtained from pm_conc_connection_list. + * + * Return: table index + */ +enum policy_mgr_three_connection_mode + policy_mgr_get_fourth_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc); +#endif + /** * policy_mgr_incr_connection_count() - adds the new connection to * the current connections list @@ -925,7 +939,7 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, * for the new connection * @psoc: PSOC object information * @session_id: Session id - * @channel: Channel on which new connection will be + * @ch_freq: Channel frequency on which new connection will be * @reason: Reason for which connection update is required * * This function initiates initiates actions @@ -934,9 +948,10 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, * * Return: QDF_STATUS enum */ -QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, - uint32_t session_id, uint8_t channel, - enum policy_mgr_conn_update_reason); +QDF_STATUS +policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, uint32_t ch_freq, + enum policy_mgr_conn_update_reason); /** * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current @@ -955,7 +970,7 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( * policy_mgr_get_preferred_dbs_action_table() - get dbs action table type * @psoc: Pointer to psoc * @vdev_id: vdev Id - * @channel: channel of vdev. + * @ch_freq: channel frequency of vdev. * @reason: reason of request * * 1. Based on band preferred and vdev priority setting to choose the preferred @@ -975,13 +990,13 @@ enum policy_mgr_conc_next_action policy_mgr_get_preferred_dbs_action_table( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason); /** * policy_mgr_is_ibss_conn_exist() - to check if IBSS connection already present * @psoc: PSOC object information - * @ibss_channel: pointer to ibss channel which needs to be filled + * @ibss_ch_freq: pointer to ibss channel which needs to be filled * * this routine will check if IBSS connection already exist or no. If it * exist then this routine will return true and fill the ibss_channel value. @@ -989,7 +1004,7 @@ policy_mgr_get_preferred_dbs_action_table( * Return: true if ibss connection exist else false */ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, - uint8_t *ibss_channel); + uint32_t *ibss_ch_freq); /** * policy_mgr_get_conn_info() - get the current connections list @@ -1013,7 +1028,7 @@ struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info( * @chain_mask: chain mask * @type: connection type * @sub_type: connection subtype - * @channelid: channel number + * @ch_freq: channel frequency value * @mac_id: mac id * * This function adds the new connection to the current @@ -1021,10 +1036,13 @@ struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info( * * Return: QDF_STATUS */ -QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, - uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id); +QDF_STATUS +policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t tx_streams, + uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, + uint32_t sub_type, + uint32_t ch_freq, uint32_t mac_id); /** * policy_mgr_update_connection_info_utfw() - updates the @@ -1036,7 +1054,7 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, * @chain_mask: chain mask * @type: connection type * @sub_type: connection subtype - * @channelid: channel number + * @ch_freq: channel frequency value * @mac_id: mac id * * This function updates the connection to the current @@ -1044,10 +1062,14 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, * * Return: QDF_STATUS */ -QDF_STATUS policy_mgr_update_connection_info_utfw(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, - uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id); +QDF_STATUS +policy_mgr_update_connection_info_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint32_t tx_streams, + uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, + uint32_t sub_type, + uint32_t ch_freq, uint32_t mac_id); /** * policy_mgr_decr_connection_count_utfw() - remove the old @@ -1114,7 +1136,7 @@ static inline QDF_STATUS policy_mgr_incr_connection_count_utfw( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id) + uint32_t ch_freq, uint32_t mac_id) { return QDF_STATUS_SUCCESS; } @@ -1122,7 +1144,7 @@ static inline QDF_STATUS policy_mgr_update_connection_info_utfw( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id) + uint32_t ch_freq, uint32_t mac_id) { return QDF_STATUS_SUCCESS; } @@ -1302,8 +1324,6 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW */ struct policy_mgr_sme_cbacks { - QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, - uint32_t *list_len); void (*sme_get_nss_for_vdev)(enum QDF_OPMODE, uint8_t *nss_2g, uint8_t *nss_5g); QDF_STATUS (*sme_soc_set_dual_mac_config)( @@ -1311,7 +1331,8 @@ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list *msg); QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id, - uint8_t new_nss, policy_mgr_nss_update_cback cback, + uint8_t new_nss, uint8_t ch_width, + policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason, uint32_t original_vdev_id); @@ -1319,7 +1340,7 @@ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_get_ap_channel_from_scan)( void *roam_profile, void **scan_cache, - uint8_t *channel); + uint32_t *ch_freq); QDF_STATUS (*sme_scan_result_purge)( void *scan_result); }; @@ -1333,31 +1354,30 @@ struct policy_mgr_sme_cbacks { * @get_mode_for_non_connected_vdev: Get the mode for a non * connected vdev * @hdd_get_device_mode: Get QDF_OPMODE type for session id (vdev id) - * @hdd_wapi_security_sta_exist: Get whether wapi encription station existing - * or not. Some hw doesn't support WAPI encryption concurrency with other - * encryption type. * @hdd_is_chan_switch_in_progress: Check if in any adater channel switch is in * progress * @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN. + * @hdd_get_ap_6ghz_capable: get ap vdev 6ghz capable info from hdd ap adapter. * @wlan_hdd_indicate_active_ndp_cnt: indicate active ndp cnt to hdd */ struct policy_mgr_hdd_cbacks { void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, + uint8_t vdev_id, uint32_t ch_freq, uint32_t channel_bw, bool forced); QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch); + uint8_t vdev_id, uint32_t *ch_freq); enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); enum QDF_OPMODE (*hdd_get_device_mode)(uint32_t session_id); - bool (*hdd_wapi_security_sta_exist)(void); bool (*hdd_is_chan_switch_in_progress)(void); + bool (*hdd_is_cac_in_progress)(void); void (*wlan_hdd_set_sap_csa_reason)(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t reason); + uint32_t (*hdd_get_ap_6ghz_capable)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); void (*wlan_hdd_indicate_active_ndp_cnt)(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t cnt); }; @@ -1538,16 +1558,17 @@ bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode, * policy_mgr_get_channel_from_scan_result() - to get channel from scan result * @psoc: PSOC object information * @roam_profile: pointer to roam profile - * @channel: channel to be filled + * @ch_freq: channel frequency to be filled * * This routine gets channel which most likely a candidate to which STA * will make connection. * * Return: QDF_STATUS */ -QDF_STATUS policy_mgr_get_channel_from_scan_result( - struct wlan_objmgr_psoc *psoc, - void *roam_profile, uint8_t *channel); +QDF_STATUS +policy_mgr_get_channel_from_scan_result(struct wlan_objmgr_psoc *psoc, + void *roam_profile, + uint32_t *ch_freq); /** * policy_mgr_mode_specific_num_open_sessions() - to get number of open sessions @@ -1743,7 +1764,7 @@ QDF_STATUS policy_mgr_restart_opportunistic_timer( * policy_mgr_modify_sap_pcl_based_on_mandatory_channel() - * Modify SAPs PCL based on mandatory channel list * @psoc: PSOC object information - * @pcl_list_org: Pointer to the preferred channel list to be trimmed + * @pcl_list_org: Pointer to the preferred channel freq list to be trimmed * @weight_list_org: Pointer to the weights of the preferred channel list * @pcl_len_org: Pointer to the length of the preferred chanel list * @@ -1752,7 +1773,7 @@ QDF_STATUS policy_mgr_restart_opportunistic_timer( * Return: QDF_STATUS */ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( - struct wlan_objmgr_psoc *psoc, uint8_t *pcl_list_org, + struct wlan_objmgr_psoc *psoc, uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org); /** @@ -1760,7 +1781,7 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( * connection update * @psoc: PSOC object information * @session_id: Session id - * @channel: Channel number + * @ch_freq: Channel frequency * @reason: Reason for connection update * * Update the connection to either single MAC or dual MAC and wait for the @@ -1770,7 +1791,7 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( */ QDF_STATUS policy_mgr_update_and_wait_for_connection_update( struct wlan_objmgr_psoc *psoc, uint8_t session_id, - uint8_t channel, enum policy_mgr_conn_update_reason reason); + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason); /** * policy_mgr_is_sap_mandatory_channel_set() - Checks if SAP @@ -1784,34 +1805,33 @@ bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_list_has_24GHz_channel() - Check if list contains 2.4GHz channels - * @channel_list: Channel list + * @channel_list: Channel frequency list * @list_len: Length of the channel list * * Checks if the channel list contains atleast one 2.4GHz channel * * Return: True if 2.4GHz channel is present, false otherwise */ -bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list, - uint32_t list_len); +bool policy_mgr_list_has_24GHz_channel(uint32_t *ch_freq_list, + uint32_t list_len); /** * policy_mgr_get_valid_chans_from_range() - get valid channel from given range * @psoc: PSOC object information - * @ch_list: Pointer to the channel list + * @ch_freq_list: Pointer to the channel frequency list * @ch_cnt: Pointer to the length of the channel list * @mode: Device mode * * Return: QDF_STATUS */ QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc, - uint8_t *ch_list, + uint32_t *ch_list, uint32_t *ch_cnt, enum policy_mgr_con_mode mode); - /** * policy_mgr_get_valid_chans() - Get the valid channel list * @psoc: PSOC object information - * @chan_list: Pointer to the valid channel list + * @ch_freq_list: Pointer to the valid channel frequency list * @list_len: Pointer to the length of the valid channel list * * Gets the valid channel list filtered by band @@ -1819,7 +1839,8 @@ QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, - uint8_t *chan_list, uint32_t *list_len); + uint32_t *ch_freq_list, + uint32_t *list_len); /** * policy_mgr_get_nss_for_vdev() - Get the allowed nss value for the @@ -1840,19 +1861,20 @@ QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_get_sap_mandatory_channel() - Get the mandatory channel for SAP * @psoc: PSOC object information - * @chan: Pointer to the SAP mandatory channel + * @ch_freq: Pointer to the SAP mandatory channel frequency * * Gets the mandatory channel for SAP operation * * Return: QDF_STATUS */ -QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, - uint16_t *chan); +QDF_STATUS +policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, + uint32_t *ch_freq); /** * policy_mgr_set_sap_mandatory_channels() - Set the mandatory channel for SAP * @psoc: PSOC object information - * @channels: Channel list to be set + * @ch_freq_list: Channel frequency list to be set * @len: Length of the channel list * * Sets the channels for the mandatory channel list along with the length of @@ -1861,7 +1883,8 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, - uint8_t *channels, uint32_t len); + uint32_t *ch_freq_list, + uint32_t len); /** * policy_mgr_is_any_mode_active_on_band_along_with_session() - @@ -1885,14 +1908,15 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( * policy_mgr_get_chan_by_session_id() - Get channel for a given session ID * @psoc: PSOC object information * @session_id: Session ID - * @chan: Pointer to the channel + * @ch_freq: Pointer to the channel frequency * * Gets the channel for a given session ID * * Return: QDF_STATUS */ QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, - uint8_t session_id, uint8_t *chan); + uint8_t session_id, + uint32_t *ch_freq); /** * policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID @@ -1929,10 +1953,10 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, * * Gets the MCC channel for a given session ID. * - * Return: '0' (INVALID_CHANNEL_ID) or valid channel number + * Return: '0' (INVALID_CHANNEL_ID) or valid channel frequency */ -uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, - uint8_t session_id); +uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, + uint8_t session_id); /** * policy_mgr_get_pcl_for_existing_conn() - Get PCL for existing connection @@ -1948,10 +1972,11 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, * * Return: None */ -QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_get_pcl_for_existing_conn( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t *pcl_ch, uint32_t *len, - uint8_t *weight_list, uint32_t weight_len, + uint32_t *pcl_ch, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len, bool all_matching_cxn_to_del); /** @@ -1989,45 +2014,20 @@ QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( * this is required if DBS mode is 2x2 * @psoc: PSOC object information * @vdev_id: vdev id on which channel switch is required - * @chan: New channel to which channel switch is requested + * @ch_freq: New channel frequency to which channel switch is requested * @reason: reason for hw mode change * * Return: QDF_STATUS, success if HW mode change is required else Failure */ QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( - struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t chan, - enum policy_mgr_conn_update_reason reason); - -/** - * policy_mgr_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change - * @psoc: PSOC object information - * @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 policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc, - bool flag); - -/** - * policy_mgr_is_hw_mode_change_after_vdev_up() - Check if hw - * mode change is needed - * @psoc: PSOC object information - * 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 policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc); + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason); /** * policy_mgr_checkn_update_hw_mode_single_mac_mode() - Set hw_mode to SMM * if required * @psoc: PSOC object information - * @channel: channel number for the new STA connection + * @ch_freq: channel frequency for the new STA connection * * After the STA disconnection, if the hw_mode is in DBS and the new STA * connection is coming in the band in which existing connections are @@ -2037,7 +2037,7 @@ bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc); * Return: None */ void policy_mgr_checkn_update_hw_mode_single_mac_mode( - struct wlan_objmgr_psoc *psoc, uint8_t channel); + struct wlan_objmgr_psoc *psoc, uint32_t ch_freq); /** * policy_mgr_dump_connection_status_info() - Dump the concurrency information @@ -2123,6 +2123,18 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, */ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_is_sap_p2pgo_on_dfs() - check if there is a P2PGO or SAP + * operating in a DFS channel + * @psoc: PSOC object information + * This routine is called to check if there is a P2PGO/SAP on DFS channel + * + * Return: True - P2PGO/SAP present on DFS Channel + * False - Otherwise + */ + +bool policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_register_sme_cb() - register SME callbacks * @psoc: PSOC object information @@ -2691,14 +2703,14 @@ void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, * policy_mgr_is_chan_ok_for_dnbs() - Function to check if a channel * is OK for "Do Not Break Stream" * @psoc: PSOC object information - * @channel: Channel to check. + * @ch_freq: Channel frequency to check. * @ok: Pointer to flag in which status will be stored * This function checks if a channel is OK for * "Do Not Break Stream" * Return: SUCCESS or FAILURE */ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, - uint8_t channel, bool *ok); + uint32_t ch_freq, bool *ok); /** * policy_mgr_get_hw_dbs_nss() - Computes DBS NSS @@ -2738,18 +2750,34 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini, uint32_t channel_select_logic_conc); +/** + * policy_mgr_is_sta_present_on_dfs_channel() - to find whether any DFS STA is + * present + * @psoc: PSOC object information + * @vdev_id: pointer to vdev_id. It will be filled with the vdev_id of DFS STA + * @ch_freq: pointer to channel frequency on which DFS STA is present + * @ch_width: pointer channel width on which DFS STA is connected + * If any STA is connected on DFS channel then this function will return true + * + * Return: true if session is on DFS or false if session is on non-dfs channel + */ +bool policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc, + uint8_t *vdev_id, + qdf_freq_t *ch_freq, + enum hw_mode_bandwidth *ch_width); + /** * policy_mgr_is_safe_channel - Check if the channel is in LTE * coex channel avoidance list * @psoc: PSOC object information - * @channel: channel to be checked + * @ch_freq: channel frequency to be checked * * Check if the channel is in LTE coex channel avoidance list. * * Return: true for success, else false */ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, - uint8_t channel); + uint32_t ch_freq); /** * policy_mgr_is_force_scc() - checks if SCC needs to be @@ -2773,11 +2801,11 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc); bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc); /** - * policy_mgr_valid_sap_conc_channel_check() - checks & updates - * the channel SAP to come up on in case of STA+SAP concurrency + * policy_mgr_valid_sap_conc_channel_check() - Check and update + * the SAP channel in case of STA+SAP concurrency * @psoc: PSOC object information - * @con_ch: pointer to the channel on which sap will come up - * @sap_ch: initial channel for SAP + * @con_ch_freq: pointer to the chan freq on which sap will come up + * @sap_ch_freq: initial channel frequency for SAP * @sap_vdev_id: sap vdev id. * * This function checks & updates the channel SAP to come up on in @@ -2785,28 +2813,28 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc); * Return: Success if SAP can come up on a channel */ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( - struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch, - uint8_t sap_vdev_id); + struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, + uint32_t sap_ch_freq, uint8_t sap_vdev_id); /** * policy_mgr_get_alternate_channel_for_sap() - Get an alternate * channel to move the SAP to * @psoc: PSOC object information * @sap_vdev_id: sap vdev id. - * @sap_channel: sap channel. + * @sap_ch_freq: sap channel frequency. * * This function returns an alternate channel for SAP to move to * Return: The new channel for SAP */ -uint8_t policy_mgr_get_alternate_channel_for_sap( +uint32_t policy_mgr_get_alternate_channel_for_sap( struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id, - uint8_t sap_channel); + uint32_t sap_ch_freq); /** * policy_mgr_disallow_mcc() - Check for mcc * * @psoc: PSOC object information - * @channel: channel on which new connection is coming up + * @ch_freq: channel frequency on which new connection is coming up * * When a new connection is about to come up check if current * concurrency combination including the new connection is @@ -2815,7 +2843,7 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( * Return: True if it is causing MCC */ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, - uint8_t channel); + uint32_t ch_freq); /** * policy_mgr_mode_specific_get_channel() - Get channel for a @@ -2823,25 +2851,25 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, * @psoc: PSOC object information * @chan_list: Connection type * - * Get channel for a connection type + * Get channel frequency for a connection type * - * Return: channel number + * Return: channel frequency */ -uint8_t policy_mgr_mode_specific_get_channel( - struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); +uint32_t policy_mgr_mode_specific_get_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode); /** * policy_mgr_add_sap_mandatory_chan() - Add chan to SAP mandatory channel * list * @psoc: Pointer to soc - * @chan: Channel to be added + * @ch_freq: Channel frequency to be added * * Add chan to SAP mandatory channel list * * Return: None */ void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, - uint8_t chan); + uint32_t ch_freq); /** * policy_mgr_get_sap_mandatory_chan_list_len() - Return the SAP mandatory @@ -2870,14 +2898,15 @@ void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc); * policy_mgr_remove_sap_mandatory_chan() - Remove channel from SAP mandatory * channel list * @psoc: Pointer to soc - * @chan: channel to be removed from mandatory channel list + * @ch_freq: channel frequency to be removed from mandatory list * * Remove channel from SAP mandatory channel list * * Return: None */ void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, - uint8_t chan); + uint32_t ch_freq); + /* * policy_set_cur_conc_system_pref - set current conc_system_pref * @psoc: soc pointer @@ -2916,7 +2945,7 @@ void policy_mgr_check_and_stop_opportunistic_timer( * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs * and passive channels to 0 * @psoc: pointer to soc - * @pcl_channels: preferred channel list + * @pcl: preferred channel freq list * @len: length of preferred channel list * @weight_list: preferred channel weight list * @weight_len: length of weight list @@ -2925,7 +2954,7 @@ void policy_mgr_check_and_stop_opportunistic_timer( * Return: None */ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( - struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, + struct wlan_objmgr_psoc *psoc, uint32_t *pcl, uint32_t *len, uint8_t *weight_list, uint32_t weight_len); /** @@ -2938,17 +2967,6 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( */ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( struct wlan_objmgr_psoc *psoc); - -/** - * policy_mgr_is_special_mode_active_5g() - check if given mode active in 5g - * @psoc: pointer to soc - * @mode: operating mode of interface to be checked - * - * Return: true if given mode is active in 5g - */ -bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode); - /** * policy_mgr_is_sta_connected_2g() - check if sta connected in 2g * @psoc: pointer to soc @@ -2958,18 +2976,14 @@ bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc); /** - * policy_mgr_trim_acs_channel_list() - Trims ACS channel list with - * intersection of PCL - * @pcl: preferred channel list - * @pcl_count: Preferred channel list count - * @org_ch_list: ACS channel list from user space - * @org_ch_list_count: ACS channel count from user space + * policy_mgr_is_connected_sta_5g() - check if sta connected in 5 GHz + * @psoc: pointer to soc + * @freq: Pointer to the frequency on which sta is connected * - * Return: None + * Return: true if sta is connected in 5 GHz else false */ -void policy_mgr_trim_acs_channel_list(uint8_t *pcl, uint8_t pcl_count, - uint8_t *org_ch_list, - uint8_t *org_ch_list_count); +bool policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc, + qdf_freq_t *freq); /** * policy_mgr_scan_trim_5g_chnls_for_dfs_ap() - check if sta scan should skip @@ -2985,7 +2999,7 @@ bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc); * policy_mgr_is_hwmode_set_for_given_chnl() - to check for given channel * if the hw mode is properly set. * @psoc: pointer to psoc - * @channel: given channel + * @ch_freq: given channel frequency * * If HW mode is properly set for given channel then it returns true else * it returns false. @@ -2997,8 +3011,9 @@ bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc); * Return: true if HW mode is set properly else false */ bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, - uint8_t channel); -/* + uint32_t ch_freq); + +/** * policy_mgr_get_connection_info() - Get info of all active connections * @info: Pointer to connection info * @@ -3029,7 +3044,7 @@ QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); * allowed. * @psoc: pointer to soc * @policy_mgr_con_mode: operating mode of interface to be checked - * @channel: new operating channel of the interface to be checked + * @ch_freq: new operating channel of the interface to be checked * @vdev_id: vdev id of the connection to be checked, 0xff for new connection * * Checks whether new channel SAP/GO can co-exist with the channel of existing @@ -3054,22 +3069,9 @@ QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); */ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel, + uint32_t ch_freq, uint32_t vdev_id); -/** - * policy_mgr_allow_multiple_sta_connections() - check whether multiple STA - * concurrency is allowed and F/W supported - * @psoc: Pointer to soc - * @second_sta_chan: 2nd STA channel - * @first_sta_chan: 1st STA channel - * - * Return: true if supports else false. - */ -bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, - uint8_t second_sta_chan, - uint8_t first_sta_chan); - /** * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that * whether support dual beacon on same channel on single MAC @@ -3104,24 +3106,24 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( * policy_mgr_valid_channel_for_channel_switch() - check for valid channel for * channel switch. * @psoc: poniter to psoc - * @channel: channel to be validated. + * @ch_freq: channel frequency to be validated. * This function validates whether the given channel is valid for channel * switch. * * Return: true or false */ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, - uint8_t channel); + uint32_t ch_freq); /** * policy_mgr_update_user_config_sap_chan() - Update user configured channel * @psoc: poniter to psoc - * @channel: channel to be upated + * @ch_freq: channel frequency to be upated * * Return: void **/ -void policy_mgr_update_user_config_sap_chan( - struct wlan_objmgr_psoc *psoc, uint32_t channel); +void policy_mgr_update_user_config_sap_chan(struct wlan_objmgr_psoc *psoc, + uint32_t ch_freq); /** * policy_mgr_nan_sap_post_enable_conc_check() - Do concurrency operations @@ -3146,7 +3148,8 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc); * required * after sta disconnection * @psoc: psoc object data - * @intf_ch: sap channel + * @sap_vdev_id: sap vdev id + * @intf_ch_freq: sap channel frequency * * Check if SAP should be moved to a non dfs channel after STA disconnection. * This API applicable only for STA+SAP SCC and ini 'sta_sap_scc_on_dfs_chan' @@ -3155,29 +3158,31 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc); * Return: true if sap restart is required, otherwise false */ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( - struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch); + struct wlan_objmgr_psoc *psoc, uint32_t sap_vdev_id, + uint32_t *intf_ch_freq); /** * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with * STA * @psoc: poniter to psoc - * @sap_ch: operating channel of SAP interface + * @sap_ch_freq: operating channel frequency of SAP interface * This function checks whether SAP is doing SCC with STA * * Return: true or false */ -bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch); +bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, + uint32_t sap_ch_freq); /** * policy_mgr_nan_sap_scc_on_unsafe_ch_chk() - check whether SAP is doing SCC * with NAN * @psoc: poniter to psoc - * @sap_ch: operating channel of SAP interface + * @sap_freq: operating channel frequency of SAP interface * * Return: true or false */ bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, - uint8_t sap_ch); + uint32_t sap_freq); /** * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index @@ -3194,6 +3199,98 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( uint32_t idx, struct policy_mgr_hw_mode_params *hw_mode); +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +/** + * policy_mgr_is_6ghz_conc_mode_supported() - Check connection mode supported + * on 6ghz or not + * @psoc: Pointer to soc + * @mode: new connection mode + * + * Current PORed 6ghz connection modes are STA, SAP. + * + * Return: true if supports else false. + */ +bool policy_mgr_is_6ghz_conc_mode_supported( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); + +/** + * policy_mgr_init_ap_6ghz_capable - Init 6Ghz capable flags + * @psoc: PSOC object information + * @vdev_id: vdev id + * @ap_6ghz_capable: vdev 6ghz capable flag + * + * Init 6Ghz capable flags for active connection in policy mgr conn table + * + * Return: void + */ +void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable); + +/** + * policy_mgr_set_ap_6ghz_capable - Set 6Ghz capable flags to connection list + * @psoc: PSOC object information + * @vdev_id: vdev id + * @set: set or clear + * @ap_6ghz_capable: vdev 6ghz capable flag + * + * Set/Clear 6Ghz capable flags for active connection in policy mgr conn table + * + * Return: void + */ +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable); + +/** + * policy_mgr_get_ap_6ghz_capable - Get 6Ghz capable info for a vdev + * @psoc: PSOC object information + * @vdev_id: vdev id + * @conn_flag: output conntion flags + * + * Get 6Ghz capable flag for ap vdev (SAP). When SAP on 5G, for same reason + * the AP needs to be moved to 6G and this API will be called to check whether + * AP is 6Ghz capable or not. + * AP is allowed on 6G band only when all of below statements are true: + * a. SAP config includes WPA3 security - SAE,OWE,SuiteB. + * b. SAP is configured by ACS range which includes any 6G channel or + configured by 6G Fixed channel. + * c. SAP has no legacy clients (client doesn't support 6G band). + * legacy client (non 6ghz capable): association request frame has no + * 6G band global operating Class. + * + * Return: true if AP is 6ghz capable + */ +bool policy_mgr_get_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag); +#else +static inline bool policy_mgr_is_6ghz_conc_mode_supported( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +{ + return false; +} + +static inline void policy_mgr_init_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable) +{} + +static inline +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable) +{} + +static inline bool policy_mgr_get_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag) +{ + return false; +} + +#endif + /** * policy_mgr_update_nan_vdev_mac_info() - Update the NAN vdev id and MAC id in * policy manager @@ -3213,7 +3310,7 @@ QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, * policy_mgr_get_mode_specific_conn_info() - Get active mode specific * channel and vdev id * @psoc: PSOC object information - * @channel: Mode specific channel (list) + * @ch_freq_list: Mode specific channel freq list * @vdev_id: Mode specific vdev id (list) * @mode: Connection Mode * @@ -3222,10 +3319,18 @@ QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, * Return: number of connection found as per given mode */ uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, - uint8_t *channel, + uint32_t *ch_freq_list, uint8_t *vdev_id, enum policy_mgr_con_mode mode); +/** + * policy_mgr_is_sap_go_on_2g() - check if sap/go is on 2g + * @psoc: PSOC object information + * + * Return: true or false + */ +bool policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_get_5g_scc_prefer() - Prefer 5G SCC * @psoc: psoc object @@ -3248,7 +3353,7 @@ bool policy_mgr_get_5g_scc_prefer( * Return: True or false */ bool policy_mgr_dump_channel_list(uint32_t len, - uint8_t *pcl_channels, + uint32_t *pcl_channels, uint8_t *pcl_weight); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h index 025c01bcf8ed66f1921ddf2ffe00baf6a83b9d5d..833a18b5ae0cf201591bc67835763938f81889ba 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h @@ -563,6 +563,33 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ CFG_INI_UINT("g_enable_go_force_scc", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ "Enable/Disable P2P GO force SCC") +/** + * + * g_pcl_band_priority - Set 5G/6G Channel order + * Options. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to set preference between 5G and 6G channels during + * PCL population. + * 0 - Prefer 5G channels, 5G channels will be placed before the 6G channels + * in PCL. + * 1 - Prefer 6G channels, 6G channels will be placed before the 5G channels + * in PCL. + * + * Supported Feature: STA, SAP + * + * + * Usage: Internal/External + * + * + */ + +#define CFG_PCL_BAND_PRIORITY \ +CFG_INI_UINT("g_pcl_band_priority", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ + "Set 5G and 6G Channel order") + /* * * g_prefer_5g_scc_to_dbs - prefer 5g scc to dbs @@ -605,6 +632,7 @@ CFG_INI_UINT("g_prefer_5g_scc_to_dbs", 0, 0xFFFFFFFF, 0, CFG_VALUE_OR_DEFAULT, \ CFG(CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN) \ CFG(CFG_MARK_INDOOR_AS_DISABLE_FEATURE)\ CFG(CFG_ALLOW_MCC_GO_DIFF_BI) \ - CFG(CFG_PREFER_5G_SCC_TO_DBS) \ - CFG(CFG_P2P_GO_ENABLE_FORCE_SCC) + CFG(CFG_P2P_GO_ENABLE_FORCE_SCC) \ + CFG(CFG_PCL_BAND_PRIORITY) \ + CFG(CFG_PREFER_5G_SCC_TO_DBS) #endif diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index 7736f111ed74fd7df915966b37a0bd996af5579a..4a44dca56e1fbb6eb9563f4df069c7f029ed4930 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -28,8 +28,6 @@ /* Include files */ #include -#define POLICY_MGR_MAX_CHANNEL_LIST 128 - /** * Some max value greater than the max length of the channel list */ @@ -59,7 +57,11 @@ #define MAX_MAC 2 +#ifdef FEATURE_FOURTH_CONNECTION +#define MAX_NUMBER_OF_CONC_CONNECTIONS 4 +#else #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 +#endif typedef int (*send_mode_change_event_cb)(void); @@ -175,6 +177,18 @@ enum policy_mgr_pcl_channel_order { POLICY_MGR_PCL_ORDER_5G_THEN_2G, }; +/** + * policy_mgr_pcl_band_priority - Band priority between 5G and 6G channel + * @POLICY_MGR_PCL_BAND_5G_THEN_6G: 5 Ghz channel followed by 6 Ghz channel + * @POLICY_MGR_PCL_BAND_6G_THEN_5G: 6 Ghz channel followed by 5 Ghz channel + * + * Band priority between 5G and 6G + */ +enum policy_mgr_pcl_band_priority { + POLICY_MGR_PCL_BAND_5G_THEN_6G = 0, + POLICY_MGR_PCL_BAND_6G_THEN_5G, +}; + /** * enum policy_mgr_max_rx_ss - Maximum number of receive spatial streams * @POLICY_MGR_RX_NSS_1: Receive Nss = 1 @@ -564,6 +578,16 @@ enum policy_mgr_one_connection_mode { * 1x1 * @PM_SAP_SAP_DBS_2x2: SAP & SAP connection on DBS using 2x2 * @PM_SAP_SAP_SBS_5_1x1: SAP & SAP connection on 5G SBS using 1x1 + * @PM_SAP_NAN_DISC_SCC_24_1x1: SAP & NAN connection on + * SCC using 1x1@2.4 Ghz + * @PM_SAP_NAN_DISC_SCC_24_2x2: SAP & NAN connection on + * SCC using 2x2@2.4 Ghz + * @PM_SAP_NAN_DISC_MCC_24_1x1: SAP & NAN connection on + * MCC using 1x1@2.4 Ghz + * @PM_SAP_NAN_DISC_MCC_24_2x2: SAP & NAN connection on + * SCC using 2x2@2.4 Ghz + * @PM_SAP_NAN_DISC_DBS_1x1: SAP & NAN connection on DBS using 1x1 + * @PM_SAP_NAN_DISC_DBS_2x2: SAP & NAN connection on DBS using 2x2 * @PM_STA_STA_SCC_24_1x1: STA & STA connection on * SCC using 1x1@2.4 Ghz * @PM_STA_STA_SCC_24_2x2: STA & STA connection on @@ -600,6 +624,21 @@ enum policy_mgr_one_connection_mode { * @PM_NAN_DISC_NDI_MCC_24_2x2: NAN & NDI connection on MCC using 2x2 on 2.4 GHz * @PM_NAN_DISC_NDI_DBS_1x1: NAN & NDI connection on DBS using 1x1 * @PM_NAN_DISC_NDI_DBS_2x2: NAN & NDI connection on DBS using 2x2 + * @PM_P2P_GO_P2P_GO_SCC_24_1x1: P2P GO & P2P GO SCC on 2.4G using 1x1 + * @PM_P2P_GO_P2P_GO_SCC_24_2x2: P2P GO & P2P GO SCC on 2.4G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_24_1x1: P2P GO & P2P GO MCC on 2.4G using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_24_2x2: P2P GO & P2P GO MCC on 2.4G using 2x2 + * @PM_P2P_GO_P2P_GO_SCC_5_1x1: P2P GO & P2P GO SCC on 5G using 1x1 + * @PM_P2P_GO_P2P_GO_SCC_5_2x2: P2P GO & P2P GO SCC on 5G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_5_1x1: P2P GO & P2P GO MCC on 5G using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_5_2x2: P2P GO & P2P GO MCC on 5G using 2x2 + * @PM_P2P_GO_P2P_GO_MCC_24_5_1x1: P2P GO 2.4G & P2P GO 5G dual band MCC + * using 1x1 + * @PM_P2P_GO_P2P_GO_MCC_24_5_2x2: P2P GO 2.4G & P2P GO 5G dual band MCC + * using 2x2 + * @PM_P2P_GO_P2P_GO_DBS_1x1: P2P GO & P2P GO on DBS using 1x1 + * @PM_P2P_GO_P2P_GO_DBS_2x2: P2P GO & P2P GO on DBS using 2x2 + * @PM_P2P_GO_P2P_GO_SBS_5_1x1: P2P GO & P2P GO on SBS using 1x1 * * These are generic IDs that identify the various roles in the * software system @@ -696,6 +735,12 @@ enum policy_mgr_two_connection_mode { PM_SAP_SAP_DBS_1x1, PM_SAP_SAP_DBS_2x2, PM_SAP_SAP_SBS_5_1x1, + PM_SAP_NAN_DISC_SCC_24_1x1, + PM_SAP_NAN_DISC_SCC_24_2x2, + PM_SAP_NAN_DISC_MCC_24_1x1, + PM_SAP_NAN_DISC_MCC_24_2x2, + PM_SAP_NAN_DISC_DBS_1x1, + PM_SAP_NAN_DISC_DBS_2x2, PM_STA_STA_SCC_24_1x1, PM_STA_STA_SCC_24_2x2, PM_STA_STA_MCC_24_1x1, @@ -721,10 +766,70 @@ enum policy_mgr_two_connection_mode { PM_NAN_DISC_NDI_MCC_24_2x2, PM_NAN_DISC_NDI_DBS_1x1, PM_NAN_DISC_NDI_DBS_2x2, - + PM_P2P_GO_P2P_GO_SCC_24_1x1, + PM_P2P_GO_P2P_GO_SCC_24_2x2, + PM_P2P_GO_P2P_GO_MCC_24_1x1, + PM_P2P_GO_P2P_GO_MCC_24_2x2, + PM_P2P_GO_P2P_GO_SCC_5_1x1, + PM_P2P_GO_P2P_GO_SCC_5_2x2, + PM_P2P_GO_P2P_GO_MCC_5_1x1, + PM_P2P_GO_P2P_GO_MCC_5_2x2, + PM_P2P_GO_P2P_GO_MCC_24_5_1x1, + PM_P2P_GO_P2P_GO_MCC_24_5_2x2, + PM_P2P_GO_P2P_GO_DBS_1x1, + PM_P2P_GO_P2P_GO_DBS_2x2, + PM_P2P_GO_P2P_GO_SBS_5_1x1, PM_MAX_TWO_CONNECTION_MODE }; +#ifdef FEATURE_FOURTH_CONNECTION +/** + * enum policy_mgr_three_connection_mode - Combination of first three + * connections type, concurrency state, band used. + * + * @PM_STA_SAP_SCC_24_SAP_5_DBS: STA & SAP connection on 2.4 Ghz SCC, another + * SAP on 5 G + * @PM_STA_SAP_SCC_5_SAP_24_DBS: STA & SAP connection on 5 Ghz SCC, another + * SAP on 2.4 G + * @PM_STA_SAP_SCC_24_STA_5_DBS: STA & SAP connection on 2.4 Ghz SCC, another + * STA on 5G + * @PM_STA_SAP_SCC_5_STA_24_DBS: STA & SAP connection on 5 Ghz SCC, another + * STA on 2.4 G + * @PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS: NAN_DISC & SAP connection on 2.4 Ghz SCC, + * NDI/NDP on 5 G + * @PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS: NAN_DISC & NDI/NDP connection on 2.4 Ghz + * SCC, SAP on 5 G + * @PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS: SAP & NDI/NDP connection on 5 Ghz, + * NAN_DISC on 24 Ghz + * @PM_NAN_DISC_STA_24_NDI_5_DBS: STA and NAN Disc on 2.4Ghz and NDI on 5ghz DBS + * @PM_NAN_DISC_NDI_24_STA_5_DBS: NDI and NAN Disc on 2.4Ghz and STA on 5ghz DBS + * @PM_STA_NDI_5_NAN_DISC_24_DBS: STA, NDI on 5ghz and NAN Disc on 2.4Ghz DBS + * @PM_STA_NDI_NAN_DISC_24_SMM: STA, NDI, NAN Disc all on 2.4ghz SMM + * @PM_NAN_DISC_NDI_24_NDI_5_DBS: NDI and NAN Disc on 2.4Ghz and second NDI in + * 5ghz DBS + * @PM_NDI_NDI_5_NAN_DISC_24_DBS: Both NDI on 5ghz and NAN Disc on 2.4Ghz DBS + * @PM_NDI_NDI_NAN_DISC_24_SMM: Both NDI, NAN Disc on 2.4ghz SMM + */ +enum policy_mgr_three_connection_mode { + PM_STA_SAP_SCC_24_SAP_5_DBS, + PM_STA_SAP_SCC_5_SAP_24_DBS, + PM_STA_SAP_SCC_24_STA_5_DBS, + PM_STA_SAP_SCC_5_STA_24_DBS, + PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS, + PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS, + PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS, + PM_NAN_DISC_STA_24_NDI_5_DBS, + PM_NAN_DISC_NDI_24_STA_5_DBS, + PM_STA_NDI_5_NAN_DISC_24_DBS, + PM_STA_NDI_NAN_DISC_24_SMM, + PM_NAN_DISC_NDI_24_NDI_5_DBS, + PM_NDI_NDI_5_NAN_DISC_24_DBS, + PM_NDI_NDI_NAN_DISC_24_SMM, + + PM_MAX_THREE_CONNECTION_MODE +}; +#endif + /** * enum policy_mgr_conc_next_action - actions to be taken on old * connections. @@ -925,28 +1030,57 @@ enum dbs_support { ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN, }; +/** + * enum conn_6ghz_flag - structure to define connection 6ghz capable info + * in policy mgr conn info struct + * + * @CONN_6GHZ_FLAG_VALID: The 6ghz flag is valid (has been initialized) + * @CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED: AP is configured in 6ghz band capable + * by user: + * a. ACS channel range includes 6ghz. + * b. SAP is started in 6ghz fix channel. + * @CONN_6GHZ_FLAG_SECURITY_ALLOWED: AP has security mode which is permitted in + * 6ghz band. + * @CONN_6GHZ_FLAG_NO_LEGACY_CLIENT: AP has no legacy client connected + */ +enum conn_6ghz_flag { + CONN_6GHZ_FLAG_VALID = 0x0001, + CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED = 0x0002, + CONN_6GHZ_FLAG_SECURITY_ALLOWED = 0x0004, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT = 0x0008, +}; + +#define CONN_6GHZ_CAPABLIE (CONN_6GHZ_FLAG_VALID | \ + CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED | \ + CONN_6GHZ_FLAG_SECURITY_ALLOWED | \ + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT) + /** * struct policy_mgr_conc_connection_info - information of all existing * connections in the wlan system * * @mode: connection type - * @chan: channel of the connection + * @freq: Channel frequency * @bw: channel bandwidth used for the connection * @mac: The HW mac it is running * @chain_mask: The original capability advertised by HW * @original_nss: nss negotiated at connection time * @vdev_id: vdev id of the connection * @in_use: if the table entry is active + * @ch_flagext: Channel extension flags. + * @conn_6ghz_flag: connection 6ghz capable flags */ struct policy_mgr_conc_connection_info { enum policy_mgr_con_mode mode; - uint8_t chan; + uint32_t freq; enum hw_mode_bandwidth bw; uint8_t mac; enum policy_mgr_chain_mode chain_mask; uint32_t original_nss; uint32_t vdev_id; bool in_use; + uint16_t ch_flagext; + enum conn_6ghz_flag conn_6ghz_flag; }; /** @@ -1026,8 +1160,8 @@ struct policy_mgr_hw_mode { * @pcl_len: Number of channels in the PCL */ struct policy_mgr_pcl_list { - uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST]; - uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; uint32_t pcl_len; }; @@ -1044,12 +1178,12 @@ struct policy_mgr_pcl_list { * @weight_list: Weights assigned by policy manager */ struct policy_mgr_pcl_chan_weights { - uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t pcl_list[NUM_CHANNELS]; uint32_t pcl_len; - uint8_t saved_chan_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t saved_chan_list[NUM_CHANNELS]; uint32_t saved_num_chan; - uint8_t weighed_valid_list[POLICY_MGR_MAX_CHANNEL_LIST]; - uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint8_t weighed_valid_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; }; /** @@ -1060,6 +1194,7 @@ struct policy_mgr_pcl_chan_weights { * @mhz: channel frequency in MHz * @chan_width: channel bandwidth * @mac_id: the mac on which vdev is on + * @ch_flagext: Channel extension flags. */ struct policy_mgr_vdev_entry_info { uint32_t type; @@ -1067,6 +1202,7 @@ struct policy_mgr_vdev_entry_info { uint32_t mhz; uint32_t chan_width; uint32_t mac_id; + uint16_t ch_flagext; }; /** @@ -1143,10 +1279,12 @@ struct dbs_nss { * @mac_id: The HW mac it is running * @vdev_id: vdev id * @channel: channel of the connection + * @ch_freq: channel freq in Mhz */ struct connection_info { uint8_t mac_id; uint8_t vdev_id; uint8_t channel; + uint32_t ch_freq; }; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h index 495542613cf6c4546e13aa74ac2b3b282b585d52..dd4682377539b28eef4a41e6e0a939f6d490e157 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h @@ -286,14 +286,14 @@ ucfg_policy_mgr_get_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc *psoc, * ucfg_policy_mgr_init_chan_avoidance() - init channel avoidance in policy * manager * @psoc: pointer to psoc - * @chan_list: channel list + * @chan_freq_list: channel frequency list * @chan_cnt: channel count * * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. */ QDF_STATUS ucfg_policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, - uint16_t *chan_list, + qdf_freq_t *chan_freq_list, uint16_t chan_cnt); /** diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 5fbc7acee7beae715262bec697c49a485bf82958..35660a0a1526cc7e8a6bdc1fcf4fc2b3800c154b 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +36,7 @@ #include "wlan_nan_api.h" #include "nan_ucfg_api.h" #include "sap_api.h" +#include "wlan_mlme_api.h" enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); @@ -165,6 +167,17 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + /* Don't send WMI_PDEV_SET_HW_MODE_CMDID to FW if existing SAP / GO is + * in CAC-in-progress state. Host is blocking this command as FW is + * having design limitation and FW don't expect this command when CAC + * is in progress state. + */ + if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && + pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { + policy_mgr_err("SAP CAC_IN_PROGRESS state, drop WMI_PDEV_SET_HW_MODE_CMDID"); + return QDF_STATUS_E_FAILURE; + } + msg.hw_mode_index = hw_mode_index; msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb; msg.reason = reason; @@ -226,7 +239,7 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( conn_index, pm_conc_connection_list[conn_index].mac, pm_conc_connection_list[conn_index].in_use, - pm_conc_connection_list[conn_index].chan, + pm_conc_connection_list[conn_index].freq, pm_conc_connection_list[conn_index].original_nss); if ((pm_conc_connection_list[conn_index].mac == 0) && pm_conc_connection_list[conn_index].in_use) { @@ -240,9 +253,8 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( mac |= POLICY_MGR_MAC1; if (policy_mgr_is_hw_dbs_required_for_band( psoc, HW_MODE_MAC_BAND_2G) && - WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[conn_index].chan) - ) { + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection"); goto done; @@ -297,13 +309,12 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - uint32_t conn_index = 0; + uint32_t conn_index = 0, ch_freq; bool found = false; struct policy_mgr_vdev_entry_info conn_table_entry; enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; uint8_t nss_2g, nss_5g; enum policy_mgr_con_mode mode; - uint8_t chan; uint32_t nss = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -322,8 +333,9 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, } conn_index++; } - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (!found) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* err msg */ policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", vdev_id); @@ -333,26 +345,28 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, status = pm_ctx->wma_cbacks.wma_get_connection_info( vdev_id, &conn_table_entry); if (QDF_STATUS_SUCCESS != status) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_err("can't find vdev_id %d in connection table", vdev_id); return status; } } else { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_err("wma_get_connection_info is NULL"); return QDF_STATUS_E_FAILURE; } mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); - chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz); + ch_freq = conn_table_entry.mhz; status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); if (QDF_IS_STATUS_SUCCESS(status)) { - if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || - (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1))) + if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) || + (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1)) chain_mask = POLICY_MGR_TWO_TWO; else chain_mask = POLICY_MGR_ONE_ONE; - nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g; + nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g; } else { policy_mgr_err("Error in getting nss"); } @@ -360,14 +374,12 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("update PM connection table for vdev:%d", vdev_id); /* add the entry */ - policy_mgr_update_conc_list(psoc, conn_index, - mode, - chan, + policy_mgr_update_conc_list( + psoc, conn_index, mode, ch_freq, policy_mgr_get_bw(conn_table_entry.chan_width), - conn_table_entry.mac_id, - chain_mask, - nss, vdev_id, true, true); - + conn_table_entry.mac_id, chain_mask, + nss, vdev_id, true, true, conn_table_entry.ch_flagext); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* do we need to change the HW mode */ policy_mgr_check_n_start_opportunistic_timer(psoc); @@ -377,20 +389,20 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_update_and_wait_for_connection_update( struct wlan_objmgr_psoc *psoc, uint8_t session_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) { QDF_STATUS status; - policy_mgr_debug("session:%d channel:%d reason:%d", - session_id, channel, reason); + policy_mgr_debug("session:%d ch_freq:%d reason:%d", + session_id, ch_freq, reason); status = policy_mgr_reset_connection_update(psoc); if (QDF_IS_STATUS_ERROR(status)) policy_mgr_err("clearing event failed"); - status = policy_mgr_current_connections_update(psoc, - session_id, channel, reason); + status = policy_mgr_current_connections_update( + psoc, session_id, ch_freq, reason); if (QDF_STATUS_E_FAILURE == status) { policy_mgr_err("connections update failed"); return QDF_STATUS_E_FAILURE; @@ -487,9 +499,9 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( } bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, - uint8_t channel) + uint32_t ch_freq) { - uint8_t i, pm_chnl; + uint8_t i; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -499,14 +511,14 @@ bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, } /* - * check given channel against already existing connections' - * channels. if they differ then channels are in different bands + * check given channel freq against already existing connections' + * channel freqs. if they differ then channels are in different bands */ qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { - pm_chnl = pm_conc_connection_list[i].chan; if (pm_conc_connection_list[i].in_use) - if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) { + if (!WLAN_REG_IS_SAME_BAND_FREQS( + ch_freq, pm_conc_connection_list[i].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("channel is in diff band"); return true; @@ -518,7 +530,7 @@ bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, } bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, - uint8_t channel) + uint32_t ch_freq) { enum policy_mgr_band band; bool is_hwmode_dbs, dbs_required_for_2g; @@ -526,7 +538,7 @@ bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, if (policy_mgr_is_hw_dbs_capable(psoc) == false) return true; - if (WLAN_REG_IS_24GHZ_CH(channel)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) band = POLICY_MGR_BAND_24; else band = POLICY_MGR_BAND_5; @@ -579,7 +591,7 @@ enum policy_mgr_conc_next_action policy_mgr_get_preferred_dbs_action_table( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -591,7 +603,7 @@ policy_mgr_get_preferred_dbs_action_table( bool dbs_2x2_5g_1x1_2g_supported; bool dbs_2x2_2g_1x1_5g_supported; uint32_t vdev_pri_list, vdev_pri_id; - uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; + uint32_t ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; uint32_t vdev_count = 0; uint32_t i; @@ -636,7 +648,7 @@ policy_mgr_get_preferred_dbs_action_table( if (!vdev_priority_enabled) goto DONE; - if (vdev_id != INVALID_VDEV_ID && channel) { + if (vdev_id != INVALID_VDEV_ID && ch_freq) { if (pm_ctx->hdd_cbacks.hdd_get_device_mode) new_conn_op_mode = pm_ctx->hdd_cbacks. hdd_get_device_mode(vdev_id); @@ -644,12 +656,12 @@ policy_mgr_get_preferred_dbs_action_table( new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type( new_conn_op_mode); if (new_conn_mode == PM_MAX_NUM_OF_MODE) - policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized", + policy_mgr_debug("new vdev %d op_mode %d freq %d reason %d: not prioritized", vdev_id, new_conn_op_mode, - channel, reason); + ch_freq, reason); else - policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d", - vdev_id, new_conn_op_mode, channel, + policy_mgr_debug("new vdev %d op_mode %d freq %d : reason %d", + vdev_id, new_conn_op_mode, ch_freq, reason); } vdev_pri_list = pm_ctx->cfg.vdev_priority_list; @@ -662,7 +674,7 @@ policy_mgr_get_preferred_dbs_action_table( goto NEXT; } vdev_count = policy_mgr_get_mode_specific_conn_info( - psoc, chan_list, vdev_list, pri_conn_mode); + psoc, ch_freq_list, vdev_list, pri_conn_mode); /** * Take care of duplication case, the vdev id may * exist in the conn list already with old chan. @@ -671,12 +683,12 @@ policy_mgr_get_preferred_dbs_action_table( found = false; for (i = 0; i < vdev_count; i++) { policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d", - i, vdev_list[i], chan_list[i], + i, vdev_list[i], ch_freq_list[i], pri_conn_mode); if (new_conn_mode == pri_conn_mode && vdev_list[i] == vdev_id) { - chan_list[i] = channel; + ch_freq_list[i] = ch_freq; found = true; } } @@ -685,7 +697,7 @@ policy_mgr_get_preferred_dbs_action_table( * make decision if it is prioritized. */ if (!found && new_conn_mode == pri_conn_mode) { - chan_list[vdev_count] = channel; + ch_freq_list[vdev_count] = ch_freq; vdev_list[vdev_count++] = vdev_id; } /** @@ -699,7 +711,8 @@ policy_mgr_get_preferred_dbs_action_table( * preferred band. */ if (vdev_count > 0) { - band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]); + band_pref_5g = + WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq_list[0]); break; } NEXT: @@ -717,7 +730,7 @@ policy_mgr_get_preferred_dbs_action_table( * policy_mgr_get_second_conn_action_table() - get second conn action table * @psoc: Pointer to psoc * @vdev_id: vdev Id - * @channel: channel of vdev. + * @ch_freq: channel frequency of vdev. * @reason: reason of request * * Get the action table based on current HW Caps and INI user preference. @@ -730,7 +743,7 @@ static policy_mgr_next_action_two_connection_table_type * policy_mgr_get_second_conn_action_table( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) { enum policy_mgr_conc_next_action preferred_action; @@ -739,7 +752,7 @@ policy_mgr_get_second_conn_action_table( return next_action_two_connection_table; preferred_action = policy_mgr_get_preferred_dbs_action_table( - psoc, vdev_id, channel, reason); + psoc, vdev_id, ch_freq, reason); switch (preferred_action) { case PM_DBS2: return next_action_two_connection_2x2_2g_1x1_5g_table; @@ -752,7 +765,7 @@ policy_mgr_get_second_conn_action_table( * policy_mgr_get_third_conn_action_table() - get third connection action table * @psoc: Pointer to psoc * @vdev_id: vdev Id - * @channel: channel of vdev. + * @ch_freq: channel frequency of vdev. * @reason: reason of request * * Get the action table based on current HW Caps and INI user preference. @@ -765,7 +778,7 @@ static policy_mgr_next_action_three_connection_table_type * policy_mgr_get_third_conn_action_table( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) { enum policy_mgr_conc_next_action preferred_action; @@ -774,7 +787,7 @@ policy_mgr_get_third_conn_action_table( return next_action_three_connection_table; preferred_action = policy_mgr_get_preferred_dbs_action_table( - psoc, vdev_id, channel, reason); + psoc, vdev_id, ch_freq, reason); switch (preferred_action) { case PM_DBS2: return next_action_three_connection_2x2_2g_1x1_5g_table; @@ -786,7 +799,7 @@ policy_mgr_get_third_conn_action_table( static QDF_STATUS policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, uint32_t session_id, - uint8_t channel, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason, enum policy_mgr_conc_next_action *next_action) { @@ -810,15 +823,15 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - if (WLAN_REG_IS_24GHZ_CH(channel)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) band = POLICY_MGR_BAND_24; else band = POLICY_MGR_BAND_5; num_connections = policy_mgr_get_connection_count(psoc); - policy_mgr_debug("num_connections=%d channel=%d", - num_connections, channel); + policy_mgr_debug("num_connections=%d freq=%d", + num_connections, ch_freq); switch (num_connections) { case 0: @@ -840,7 +853,7 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } second_conn_table = policy_mgr_get_second_conn_action_table( - psoc, session_id, channel, reason); + psoc, session_id, ch_freq, reason); *next_action = (*second_conn_table)[second_index][band]; break; case 2: @@ -852,7 +865,7 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } third_conn_table = policy_mgr_get_third_conn_action_table( - psoc, session_id, channel, reason); + psoc, session_id, ch_freq, reason); *next_action = (*third_conn_table)[third_index][band]; break; default: @@ -894,11 +907,11 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } - -QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, - uint32_t session_id, - uint8_t channel, - enum policy_mgr_conn_update_reason reason) +QDF_STATUS +policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, uint32_t ch_freq, + enum policy_mgr_conn_update_reason + reason) { enum policy_mgr_conc_next_action next_action = PM_NOP; QDF_STATUS status; @@ -908,7 +921,7 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_NOSUPPORT; } - status = policy_mgr_get_next_action(psoc, session_id, channel, reason, + status = policy_mgr_get_next_action(psoc, session_id, ch_freq, reason, &next_action); if (QDF_IS_STATUS_ERROR(status)) return status; @@ -1216,13 +1229,14 @@ QDF_STATUS policy_mgr_next_actions( return status; } -QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, - uint8_t session_id, uint8_t channel, - enum policy_mgr_conn_update_reason reason) +QDF_STATUS +policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint32_t ch_freq, + enum policy_mgr_conn_update_reason reason) { QDF_STATUS status; - if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) { + if (!policy_mgr_check_for_session_conc(psoc, session_id, ch_freq)) { policy_mgr_err("Conc not allowed for the session %d", session_id); return QDF_STATUS_E_FAILURE; @@ -1233,7 +1247,7 @@ QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, policy_mgr_err("clearing event failed"); status = policy_mgr_current_connections_update(psoc, session_id, - channel, reason); + ch_freq, reason); if (QDF_STATUS_E_FAILURE == status) { policy_mgr_err("connections update failed"); return status; @@ -1244,7 +1258,7 @@ QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH void policy_mgr_update_user_config_sap_chan( - struct wlan_objmgr_psoc *psoc, uint32_t channel) + struct wlan_objmgr_psoc *psoc, uint32_t ch_freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1253,7 +1267,7 @@ void policy_mgr_update_user_config_sap_chan( policy_mgr_err("Invalid pm context and failed to update the user config sap channel"); return; } - pm_ctx->user_config_sap_channel = channel; + pm_ctx->user_config_sap_ch_freq = ch_freq; } /** @@ -1282,7 +1296,7 @@ static bool policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc *psoc) } bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, - uint8_t channel) + uint32_t ch_freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; bool is_safe = true; @@ -1299,9 +1313,9 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, return is_safe; for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { - if (channel == pm_ctx->unsafe_channel_list[j]) { + if (ch_freq == pm_ctx->unsafe_channel_list[j]) { is_safe = false; - policy_mgr_warn("CH %d is not safe", channel); + policy_mgr_warn("Freq %d is not safe", ch_freq); break; } } @@ -1310,43 +1324,127 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, } bool policy_mgr_is_sap_restart_required_after_sta_disconnect( - struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch) + struct wlan_objmgr_psoc *psoc, + uint32_t sap_vdev_id, uint32_t *intf_ch_freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc, - PM_SAP_MODE); + uint32_t curr_sap_freq = 0, new_sap_freq = 0; bool sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + bool sta_sap_scc_on_lte_coex_chan = + policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc); uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0; + uint32_t cc_count, i, go_index_start, pcl_len = 0; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; + enum policy_mgr_con_mode mode; + uint32_t pcl_channels[NUM_CHANNELS + 1]; + uint8_t pcl_weight[NUM_CHANNELS + 1]; + struct policy_mgr_conc_connection_info info = {0}; + uint8_t num_cxn_del = 0; + QDF_STATUS status; - *intf_ch = 0; - + if (intf_ch_freq) + *intf_ch_freq = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid pm context"); return false; } + if (!pm_ctx->do_sap_unsafe_ch_check) + return false; + if (!sta_sap_scc_on_dfs_chan && !sta_sap_scc_on_lte_coex_chan) + return false; policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value); - policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, sap_chan %u", - sta_sap_scc_on_dfs_chan, - sta_sap_scc_on_dfs_chnl_config_value, - sap_chan); - - if ((!sta_sap_scc_on_dfs_chan || - (sta_sap_scc_on_dfs_chnl_config_value == 2) || - !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) && - (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) == - CHANNEL_STATE_DFS))) && - (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || - policy_mgr_is_safe_channel(psoc, sap_chan))) { + if (!policy_mgr_is_hw_dbs_capable(psoc)) + if (policy_mgr_get_connection_count(psoc) > 1) + return false; + + cc_count = policy_mgr_get_mode_specific_conn_info(psoc, + &op_ch_freq_list[0], + &vdev_id[0], + PM_SAP_MODE); + go_index_start = cc_count; + if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) + cc_count += policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_P2P_GO_MODE); + + for (i = 0 ; i < cc_count; i++) { + if (sap_vdev_id != INVALID_VDEV_ID && + sap_vdev_id != vdev_id[i]) + continue; + if (policy_mgr_is_any_mode_active_on_band_along_with_session( + psoc, vdev_id[i], + WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ? + POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5)) + continue; + if (sta_sap_scc_on_dfs_chan && + (sta_sap_scc_on_dfs_chnl_config_value != 2) && + wlan_reg_is_dfs_for_freq(pm_ctx->pdev, + op_ch_freq_list[i])) { + sap_vdev_id = vdev_id[i]; + curr_sap_freq = op_ch_freq_list[i]; + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u", + sta_sap_scc_on_dfs_chan, + sta_sap_scc_on_dfs_chnl_config_value, + curr_sap_freq); + break; + } + if (sta_sap_scc_on_lte_coex_chan && + !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i])) { + sap_vdev_id = vdev_id[i]; + curr_sap_freq = op_ch_freq_list[i]; + policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u", + sta_sap_scc_on_lte_coex_chan, + curr_sap_freq); + break; + } + } + + if (!curr_sap_freq) return false; + mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE; + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, + &info, &num_cxn_del); + /* Add the user config ch as first condidate */ + pcl_channels[0] = pm_ctx->user_config_sap_ch_freq; + pcl_weight[0] = 0; + status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len, + &pcl_weight[1], + QDF_ARRAY_SIZE(pcl_weight) - 1); + if (status == QDF_STATUS_SUCCESS) + pcl_len++; + else + pcl_len = 1; + for (i = 0; i < pcl_len; i++) { + if (pcl_channels[i] == curr_sap_freq) + continue; + if (!wlan_reg_is_same_band_freqs( + curr_sap_freq, pcl_channels[i])) + continue; + if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) || + wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i])) + continue; + new_sap_freq = pcl_channels[i]; + break; } + /* Restore the connection entry */ + if (num_cxn_del > 0) + policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - *intf_ch = pm_ctx->user_config_sap_channel; - policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u", - *intf_ch); + if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq) + return false; + if (!intf_ch_freq) + return true; + + *intf_ch_freq = new_sap_freq; + policy_mgr_debug("Standalone SAP(vdev_id %d) is not allowed on DFS/Unsafe channel, Move it to channel %u", + sap_vdev_id, *intf_ch_freq); return true; } @@ -1355,15 +1453,15 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is * allowed in LTE COEX unsafe ch * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context - * @ch: Channel to check + * @ch_freq: Channel frequency to check * * Return: True if allowed else false */ static bool policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj - *pm_ctx, uint8_t ch) + *pm_ctx, uint32_t ch_freq) { - if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch) || + if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) || pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl) return true; @@ -1384,9 +1482,9 @@ static void policy_mgr_nan_disable_work(void *data) } bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, - uint8_t sap_ch) + uint32_t sap_freq) { - uint8_t nan_ch_2g, nan_ch_5g; + uint32_t nan_2g_freq, nan_5g_freq; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -1395,25 +1493,25 @@ bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, return false; } - nan_ch_2g = policy_mgr_mode_specific_get_channel(psoc, - PM_NAN_DISC_MODE); - if (nan_ch_2g == 0) { + nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc, + PM_NAN_DISC_MODE); + if (nan_2g_freq == 0) { policy_mgr_debug("No NAN+SAP SCC"); return false; } - nan_ch_5g = wlan_nan_get_disc_5g_ch(psoc); + nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc); - policy_mgr_debug("SAP Ch: %d NAN Ch: %d %d", sap_ch, - nan_ch_2g, nan_ch_5g); - if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_2g, sap_ch)) { + policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq, + nan_2g_freq, nan_5g_freq); + if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) { if (policy_mgr_is_force_scc(pm_ctx->psoc) && policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, - nan_ch_2g)) + nan_2g_freq)) return true; - } else if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_5g, sap_ch)) { + } else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) { if (policy_mgr_is_force_scc(pm_ctx->psoc) && policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, - nan_ch_5g)) + nan_5g_freq)) return true; } else { /* @@ -1434,10 +1532,10 @@ bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, bool policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t ch) + uint32_t ch_freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t sap_ch, nan_ch_2g, nan_ch_5g; + uint32_t sap_freq, nan_2g_freq, nan_5g_freq; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1450,7 +1548,7 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, return true; } - if (!ch) { + if (!ch_freq) { policy_mgr_err("Invalid channel"); return false; } @@ -1463,11 +1561,11 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, ucfg_nan_disable_concurrency(pm_ctx->psoc); } if (mode == PM_NAN_DISC_MODE) { - sap_ch = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, - PM_SAP_MODE); - policy_mgr_debug("SAP CH: %d NAN Ch: %d", sap_ch, ch); - if (WLAN_REG_IS_SAME_BAND_CHANNELS(sap_ch, ch)) { - if (sap_ch == ch) { + sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, + PM_SAP_MODE); + policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq); + if (WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq)) { + if (sap_freq == ch_freq) { policy_mgr_debug("NAN+SAP SCC"); return true; } @@ -1476,22 +1574,22 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("SAP force SCC disabled"); return false; } - if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, - ch)) { + if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( + pm_ctx, ch_freq)) { policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); return false; } } } else if (mode == PM_SAP_MODE) { - nan_ch_2g = + nan_2g_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, PM_NAN_DISC_MODE); - nan_ch_5g = wlan_nan_get_disc_5g_ch(pm_ctx->psoc); - policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch, nan_ch_2g, - nan_ch_5g); - if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_2g, ch) || - WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_5g, ch)) { - if (ch == nan_ch_2g || ch == nan_ch_5g) { + nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc); + policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq, + nan_2g_freq, nan_5g_freq); + if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) || + WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) { + if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) { policy_mgr_debug("NAN+SAP SCC"); return true; } @@ -1500,12 +1598,12 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, ucfg_nan_disable_concurrency(pm_ctx->psoc); return false; } - if ((WLAN_REG_IS_5GHZ_CH(ch) && + if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( - pm_ctx, nan_ch_5g)) || - (WLAN_REG_IS_24GHZ_CH(ch) && + pm_ctx, nan_5g_freq)) || + (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( - pm_ctx, nan_ch_2g))) { + pm_ctx, nan_2g_freq))) { policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); ucfg_nan_disable_concurrency(pm_ctx->psoc); return false; @@ -1519,7 +1617,7 @@ void policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; struct policy_mgr_conc_connection_info *sap_info = NULL; - uint8_t sap_ch = 0, nan_ch_2g, nan_ch_5g, i; + uint8_t nan_freq_2g, nan_freq_5g, i; QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); @@ -1532,20 +1630,21 @@ void policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) if (pm_conc_connection_list[i].mode == PM_SAP_MODE && pm_conc_connection_list[i].in_use) { sap_info = &pm_conc_connection_list[i]; - sap_ch = sap_info->chan; break; } } - if (sap_ch == 0) + if (!sap_info) return; - nan_ch_2g = policy_mgr_mode_specific_get_channel(psoc, - PM_NAN_DISC_MODE); - nan_ch_5g = wlan_nan_get_disc_5g_ch(psoc); - if (sap_ch == nan_ch_2g || sap_ch == nan_ch_5g) { + if (sap_info->freq == 0) + return; + nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc, + PM_NAN_DISC_MODE); + nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc); + if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) { policy_mgr_debug("NAN and SAP already in SCC"); return; } - if (nan_ch_2g == 0) + if (nan_freq_2g == 0) return; if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && @@ -1558,22 +1657,23 @@ void policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) policy_mgr_err("wait for event failed, still continue with channel switch"); } - policy_mgr_debug("Force SCC for NAN+SAP Ch: %d", - WLAN_REG_IS_5GHZ_CH(sap_ch) ? nan_ch_5g : nan_ch_2g); + policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d", + WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq) ? + nan_freq_5g : nan_freq_2g); if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc, sap_info->vdev_id, CSA_REASON_CONCURRENT_NAN_EVENT); - if (WLAN_REG_IS_5GHZ_CH(sap_ch)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) { policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, - nan_ch_5g, + nan_freq_5g, policy_mgr_get_ch_width( sap_info->bw), true); } else { policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, - nan_ch_2g, + nan_freq_2g, policy_mgr_get_ch_width( sap_info->bw), true); @@ -1584,7 +1684,7 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; struct policy_mgr_conc_connection_info *sap_info = NULL; - uint8_t sap_ch = 0, i; + uint32_t sap_freq = 0, i; QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); @@ -1597,17 +1697,17 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) if (pm_conc_connection_list[i].mode == PM_SAP_MODE && pm_conc_connection_list[i].in_use) { sap_info = &pm_conc_connection_list[i]; - sap_ch = sap_info->chan; + sap_freq = sap_info->freq; break; } } - if (sap_ch == 0 || policy_mgr_is_safe_channel(psoc, sap_ch)) + if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq)) return; - sap_ch = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE, - false); - policy_mgr_debug("User/ACS orig ch: %d New SAP ch: %d", - pm_ctx->user_config_sap_channel, sap_ch); + sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE, + false); + policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d", + pm_ctx->user_config_sap_ch_freq, sap_freq); if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { policy_mgr_debug("wait as channel switch is already in progress"); @@ -1619,12 +1719,12 @@ void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) } if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) - pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc, - sap_info->vdev_id, - CSA_REASON_CONCURRENT_NAN_EVENT); + pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason( + psoc, sap_info->vdev_id, + CSA_REASON_CONCURRENT_NAN_EVENT); policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, - sap_ch, + sap_freq, policy_mgr_get_ch_width( sap_info->bw), true); } @@ -1636,27 +1736,28 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) struct sta_ap_intf_check_work_ctx *work_info = NULL; uint32_t mcc_to_scc_switch, cc_count = 0, i; QDF_STATUS status; - uint8_t channel, sec_ch; - uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t ch_freq; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; work_info = data; if (!work_info) { policy_mgr_err("Invalid work_info"); - goto end; + return; } psoc = work_info->psoc; if (!psoc) { policy_mgr_err("Invalid psoc"); - goto end; + return; } pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); - goto end; + return; } + mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc); @@ -1666,18 +1767,15 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) if (!policy_mgr_is_sap_go_existed(psoc)) goto end; - cc_count = policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], - PM_SAP_MODE); + cc_count = policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_SAP_MODE); policy_mgr_debug("Number of concurrent SAP: %d", cc_count); if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) cc_count = cc_count + - policy_mgr_get_mode_specific_conn_info - (psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], - PM_P2P_GO_MODE); + policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_P2P_GO_MODE); policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", cc_count); if (!cc_count) { @@ -1699,21 +1797,20 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_err("SAP restart get channel callback in NULL"); goto end; } - if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) + if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) for (i = 0; i < cc_count; i++) { status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart - (psoc, - vdev_id[i], &channel, &sec_ch); + (psoc, vdev_id[i], &ch_freq); if (status == QDF_STATUS_SUCCESS) { - policy_mgr_debug("SAP restarts due to MCC->SCC switch, old chan:%d new chan: %d", - operating_channel[i], channel); + policy_mgr_debug("SAP restarts due to MCC->SCC switch, old ch freq :%d new ch freq: %d", + op_ch_freq_list[i], ch_freq); break; } } end: - policy_mgr_debug("Check sta ap intf done"); + pm_ctx->do_sap_unsafe_ch_check = false; } void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) @@ -1729,7 +1826,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) } static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, - uint8_t sta_channel) + uint32_t sta_ch_freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; @@ -1742,16 +1839,17 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) && + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && sta_sap_scc_on_dfs_chan) { policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u", - sta_channel); + sta_ch_freq); return true; } - if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) && - !sta_sap_scc_on_dfs_chan) || - wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) || - !policy_mgr_is_safe_channel(psoc, sta_channel)) { + if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) && + !sta_sap_scc_on_dfs_chan) || + wlan_reg_is_passive_or_disable_for_freq( + pm_ctx->pdev, sta_ch_freq) || + !policy_mgr_is_safe_channel(psoc, sta_ch_freq)) { if (policy_mgr_is_hw_dbs_capable(psoc)) return true; else @@ -1761,14 +1859,108 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, return true; } +/** + * policy_mgr_select_2g_chan() - select 2G usable channel for SAP + * @psoc: psoc object + * + * Select active 2G home channel or select safe 2G channel. + * + * return: uint32 chan freq + */ +static uint32_t policy_mgr_select_2g_chan(struct wlan_objmgr_psoc *psoc) +{ + uint8_t count, i; + struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS]; + struct regulatory_channel band_2g_list[NUM_24GHZ_CHANNELS]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return 0; + } + + count = policy_mgr_get_connection_info(psoc, info); + for (i = 0; i < count; i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(info[i].ch_freq)) + return info[i].ch_freq; + } + + count = wlan_reg_get_band_channel_list(pm_ctx->pdev, BIT(REG_BAND_2G), + band_2g_list); + for (i = 0; i < count; i++) { + if (policy_mgr_is_safe_channel(psoc, + band_2g_list[i].center_freq)) + return band_2g_list[i].center_freq; + } + + return PM_24_GHZ_CH_FREQ_6; +} + +/** + * policy_mgr_check_6ghz_sap_conc() - check sap force scc to 6ghz + * @psoc: psoc object + * @con_ch_freq: concurrency channel + * @sap_ch_freq: SAP starting channel + * @sap_vdev_id: sap vdev id + * + * Validate whether SAP can be forced scc to 6ghz band or not. + * If not, select 2G band channel for DBS hw + * or keep SAP starting channel not changed for non-DBS hw. + * + * return: QDF_STATUS_SUCCESS + */ +static QDF_STATUS policy_mgr_check_6ghz_sap_conc( + struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, + uint32_t sap_ch_freq, uint8_t sap_vdev_id) +{ + uint32_t ch_freq = *con_ch_freq; + + if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && + !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) && + !policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL)) { + policy_mgr_debug("sap %d not support 6ghz freq %d", + sap_vdev_id, ch_freq); + if (policy_mgr_is_hw_dbs_capable(psoc)) { + ch_freq = policy_mgr_select_2g_chan(psoc); + policy_mgr_debug("select 2G ch %d to achieve DBS", + ch_freq); + } else { + /* Keep MCC 2G(or 5G) + 6G for non-DBS chip*/ + ch_freq = 0; + policy_mgr_debug("do not force SCC for non-dbs hw"); + } + } + if (ch_freq != sap_ch_freq) + *con_ch_freq = ch_freq; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_valid_sap_conc_channel_check( - struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch, - uint8_t sap_vdev_id) + struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, + uint32_t sap_ch_freq, uint8_t sap_vdev_id) { - uint8_t channel = *con_ch; - uint8_t temp_channel = 0; + uint32_t ch_freq = *con_ch_freq; + uint32_t temp_ch_freq = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; + struct wlan_objmgr_vdev *vdev; + enum QDF_OPMODE vdev_opmode; + bool enable_srd_channel; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, sap_vdev_id, + WLAN_POLICY_MGR_ID); + if (!vdev) { + policy_mgr_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + + wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode, + &enable_srd_channel); pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1790,63 +1982,66 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( * return from here. If SCC, check further if SAP can move to * STA's channel. */ - if (!channel && - (sap_ch != policy_mgr_mode_specific_get_channel( - psoc, PM_STA_MODE))) + if (!ch_freq && + sap_ch_freq != policy_mgr_mode_specific_get_channel(psoc, + PM_STA_MODE)) { return QDF_STATUS_SUCCESS; - else if (!channel) - channel = sap_ch; + } else if (!ch_freq) { + ch_freq = sap_ch_freq; + } else if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { + return policy_mgr_check_6ghz_sap_conc( + psoc, con_ch_freq, sap_ch_freq, sap_vdev_id); + } sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - if (policy_mgr_valid_sta_channel_check(psoc, channel)) { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || - wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, channel) || + if (policy_mgr_valid_sta_channel_check(psoc, ch_freq)) { + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) || + wlan_reg_is_passive_or_disable_for_freq(pm_ctx->pdev, + ch_freq) || !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || - policy_mgr_is_safe_channel(psoc, channel)) || - (!wlan_reg_is_etsi13_srd_chan_allowed_master_mode( - pm_ctx->pdev) && - wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, channel))) { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && + policy_mgr_is_safe_channel(psoc, ch_freq)) || + (!enable_srd_channel && + wlan_reg_is_etsi13_srd_chan_for_freq(pm_ctx->pdev, + ch_freq))) { + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) && sta_sap_scc_on_dfs_chan) { policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); goto update_chan; } if (policy_mgr_is_hw_dbs_capable(psoc)) { - temp_channel = - policy_mgr_get_alternate_channel_for_sap(psoc, - sap_vdev_id, - sap_ch); - policy_mgr_debug("temp_channel is %d", - temp_channel); - if (temp_channel) { - channel = temp_channel; + temp_ch_freq = + policy_mgr_get_alternate_channel_for_sap( + psoc, sap_vdev_id, sap_ch_freq); + policy_mgr_debug("temp ch freq is %d", + temp_ch_freq); + if (temp_ch_freq) { + ch_freq = temp_ch_freq; } else { - if (WLAN_REG_IS_5GHZ_CH(channel)) - channel = PM_24_GHZ_CHANNEL_6; + if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) + ch_freq = PM_24_GHZ_CH_FREQ_6; else - channel = PM_5_GHZ_CHANNEL_36; + ch_freq = PM_5_GHZ_CH_FREQ_36; } if (!policy_mgr_is_safe_channel( - psoc, channel)) { - policy_mgr_warn( - "Can't have concurrency on %d as it is not safe", - channel); + psoc, ch_freq)) { + policy_mgr_warn("Can't have concurrency on %d as it is not safe", + *con_ch_freq); return QDF_STATUS_E_FAILURE; } } else { policy_mgr_warn("Can't have concurrency on %d", - channel); + ch_freq); return QDF_STATUS_E_FAILURE; } } } update_chan: - if (channel != sap_ch) - *con_ch = channel; + if (ch_freq != sap_ch_freq) + *con_ch_freq = ch_freq; return QDF_STATUS_SUCCESS; } @@ -1867,11 +2062,11 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t mcc_to_scc_switch; - uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; uint32_t cc_count = 0; bool restart_sap = false; - uint8_t sap_ch; + uint32_t sap_freq; /* * if no sta, sap/p2p go may need switch channel for band * capability change. @@ -1893,41 +2088,38 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( "No action taken at check_concurrent_intf_and_restart_sap"); return; } - - if (policy_mgr_get_connection_count(psoc) == 1) { - /* - * If STA+SAP sessions are on DFS channel and STA+SAP SCC is - * enabled on DFS channel then move the SAP out of DFS channel - * as soon as STA gets disconnect. - * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is - * enabled on unsafe channel then move the SAP to safe channel - * as soon as STA disconnected. - */ - if (policy_mgr_is_sap_restart_required_after_sta_disconnect( - psoc, &sap_ch)) { - policy_mgr_debug("move the SAP to configured channel %u", - sap_ch); - restart_sap = true; - goto sap_restart; - } + /* + * If STA+SAP sessions are on DFS channel and STA+SAP SCC is + * enabled on DFS channel then move the SAP out of DFS channel + * as soon as STA gets disconnect. + * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is + * enabled on unsafe channel then move the SAP to safe channel + * as soon as STA disconnected. + */ + if (policy_mgr_is_sap_restart_required_after_sta_disconnect( + psoc, INVALID_VDEV_ID, &sap_freq)) { + policy_mgr_debug("move the SAP to configured channel %u", + sap_freq); + restart_sap = true; + goto sap_restart; } /* * force SCC with STA+STA+SAP will need some additional logic */ - cc_count = policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], PM_STA_MODE); + cc_count = policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_STA_MODE); if (!cc_count) { policy_mgr_debug("Could not get STA operating channel&vdevid"); } sta_check = !cc_count || - policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]); + policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]); cc_count = 0; cc_count = policy_mgr_get_mode_specific_conn_info( - psoc, &operating_channel[cc_count], + psoc, &op_ch_freq_list[cc_count], &vdev_id[cc_count], PM_P2P_CLIENT_MODE); if (!cc_count) policy_mgr_debug("Could not get GC operating channel&vdevid"); @@ -1938,7 +2130,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc); policy_mgr_debug("MCC to SCC switch: %d chan: %d", - mcc_to_scc_switch, operating_channel[0]); + mcc_to_scc_switch, op_ch_freq_list[0]); sap_restart: /* * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not @@ -1966,7 +2158,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA * @psoc: PSOC object information * @vdev_id: Vdev id - * @channel: Channel to change + * @ch_freq: Channel to change * @ch_width: channel width to change * @forced: Force to switch channel, ignore SCC/MCC check * @@ -1975,9 +2167,8 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( * Return: None */ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, - uint32_t ch_width, - bool forced) + uint8_t vdev_id, uint32_t ch_freq, + uint32_t ch_width, bool forced) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1990,7 +2181,7 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { policy_mgr_info("SAP change change without restart"); pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, - vdev_id, channel, ch_width, forced); + vdev_id, ch_freq, ch_width, forced); } } #endif @@ -2237,8 +2428,8 @@ QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( } QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( - struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t chan, - enum policy_mgr_conn_update_reason reason) + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + uint32_t ch_freq, enum policy_mgr_conn_update_reason reason) { QDF_STATUS status; struct policy_mgr_conc_connection_info info; @@ -2270,7 +2461,7 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( return QDF_STATUS_E_ALREADY; } - if (!WLAN_CHAN_IS_2GHZ(chan)) + if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G) return QDF_STATUS_E_NOSUPPORT; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); @@ -2283,7 +2474,7 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, &info, &num_cxn_del); - status = policy_mgr_get_next_action(psoc, vdev_id, chan, + status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq, reason, &next_action); /* Restore the connection entry */ if (num_cxn_del) @@ -2313,7 +2504,7 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch( } void policy_mgr_checkn_update_hw_mode_single_mac_mode( - struct wlan_objmgr_psoc *psoc, uint8_t channel) + struct wlan_objmgr_psoc *psoc, uint32_t ch_freq) { uint8_t i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -2328,7 +2519,7 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) && - (WLAN_REG_IS_24GHZ_CH(channel))) { + (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) { policy_mgr_debug("DBS required for new connection"); return; } @@ -2336,16 +2527,16 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if (pm_conc_connection_list[i].in_use) { - if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, - pm_conc_connection_list[i].chan)) { + if (!WLAN_REG_IS_SAME_BAND_FREQS( + ch_freq, pm_conc_connection_list[i].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("DBS required"); return; } if (policy_mgr_is_hw_dbs_required_for_band( psoc, HW_MODE_MAC_BAND_2G) && - WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[i].chan)) { + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[i].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("DBS required"); return; @@ -2478,11 +2669,12 @@ QDF_STATUS policy_mgr_update_connection_info_utfw( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id) + uint32_t ch_freq, uint32_t mac_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t conn_index = 0, found = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint16_t ch_flagext = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2508,23 +2700,30 @@ QDF_STATUS policy_mgr_update_connection_info_utfw( } policy_mgr_debug("--> updating entry at index[%d]", conn_index); + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) + ch_flagext |= IEEE80211_CHAN_DFS; + policy_mgr_update_conc_list(psoc, conn_index, policy_mgr_get_mode(type, sub_type), - channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true, true); + ch_freq, HW_MODE_20_MHZ, + mac_id, chain_mask, 0, vdev_id, true, true, + ch_flagext); return QDF_STATUS_SUCCESS; } -QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_incr_connection_count_utfw( + struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, uint32_t chain_mask, uint32_t type, uint32_t sub_type, - uint32_t channelid, uint32_t mac_id) + uint32_t ch_freq, uint32_t mac_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t conn_index = 0; bool update_conn = true; enum policy_mgr_con_mode mode; + uint16_t ch_flagext = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; conn_index = policy_mgr_get_connection_count(psoc); if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { @@ -2539,11 +2738,17 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE) update_conn = false; - policy_mgr_update_conc_list(psoc, conn_index, - mode, - channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true, - update_conn); + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid pm context"); + return false; + } + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) + ch_flagext |= IEEE80211_CHAN_DFS; + + policy_mgr_update_conc_list(psoc, conn_index, mode, ch_freq, + HW_MODE_20_MHZ, mac_id, chain_mask, + 0, vdev_id, true, update_conn, ch_flagext); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 7ca8cd74574dbeb3e7b67fa01034c53225d720f3..8b17d4c23069dd78b9fc8ea0630e2bf7aac36e13 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -566,34 +566,18 @@ QDF_STATUS policy_mgr_get_old_and_new_hw_index( return QDF_STATUS_SUCCESS; } -/** - * policy_mgr_update_conc_list() - Update the concurrent connection list - * @conn_index: Connection index - * @mode: Mode - * @chan: Channel - * @bw: Bandwidth - * @mac: Mac id - * @chain_mask: Chain mask - * @vdev_id: vdev id - * @in_use: Flag to indicate if the index is in use or not - * @update_conn: Flag to indicate if mode change event should - * be sent or not - * - * Updates the index value of the concurrent connection list - * - * Return: None - */ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, uint32_t conn_index, enum policy_mgr_con_mode mode, - uint8_t chan, + uint32_t ch_freq, enum hw_mode_bandwidth bw, uint8_t mac, enum policy_mgr_chain_mode chain_mask, uint32_t original_nss, uint32_t vdev_id, bool in_use, - bool update_conn) + bool update_conn, + uint16_t ch_flagext) { struct policy_mgr_psoc_priv_obj *pm_ctx; bool mcc_mode; @@ -612,13 +596,14 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); pm_conc_connection_list[conn_index].mode = mode; - pm_conc_connection_list[conn_index].chan = chan; + pm_conc_connection_list[conn_index].freq = ch_freq; pm_conc_connection_list[conn_index].bw = bw; pm_conc_connection_list[conn_index].mac = mac; pm_conc_connection_list[conn_index].chain_mask = chain_mask; pm_conc_connection_list[conn_index].original_nss = original_nss; pm_conc_connection_list[conn_index].vdev_id = vdev_id; pm_conc_connection_list[conn_index].in_use = in_use; + pm_conc_connection_list[conn_index].ch_flagext = ch_flagext; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* @@ -768,7 +753,7 @@ void policy_mgr_store_and_del_conn_info_by_vdev_id( void policy_mgr_store_and_del_conn_info_by_chan_and_mode( struct wlan_objmgr_psoc *psoc, - uint32_t chan, + uint32_t ch_freq, enum policy_mgr_con_mode mode, struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del) @@ -790,7 +775,7 @@ void policy_mgr_store_and_del_conn_info_by_chan_and_mode( } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (chan != pm_conc_connection_list[conn_index].chan || + if (ch_freq != pm_conc_connection_list[conn_index].freq || mode != pm_conc_connection_list[conn_index].mode) { conn_index++; continue; @@ -800,7 +785,7 @@ void policy_mgr_store_and_del_conn_info_by_chan_and_mode( info[found_index].vdev_id, info[found_index].mode, info[found_index].vdev_id, conn_index, - chan); + ch_freq); found_index++; conn_index++; } @@ -1216,8 +1201,8 @@ static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) strlcat(cc_mode, " with SCC for 1st two connections on mac ", length); @@ -1228,8 +1213,8 @@ static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc, mac = pm_conc_connection_list[0].mac; } if (pm_conc_connection_list[0].mac == pm_conc_connection_list[2].mac) { - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[2].chan) + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[2].freq) strlcat(cc_mode, " with SCC for 1st & 3rd connections on mac ", length); @@ -1240,8 +1225,8 @@ static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc, mac = pm_conc_connection_list[0].mac; } if (pm_conc_connection_list[1].mac == pm_conc_connection_list[2].mac) { - if (pm_conc_connection_list[1].chan == - pm_conc_connection_list[2].chan) + if (pm_conc_connection_list[1].freq == + pm_conc_connection_list[2].freq) strlcat(cc_mode, " with SCC for 2nd & 3rd connections on mac ", length); @@ -1289,8 +1274,8 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) count = policy_mgr_dump_current_concurrency_two_connection( cc_mode, sizeof(cc_mode)); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { strlcat(cc_mode, " SCC", sizeof(cc_mode)); } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { @@ -1304,10 +1289,10 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) count = policy_mgr_dump_current_concurrency_three_connection( cc_mode, sizeof(cc_mode)); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - if ((pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) && - (pm_conc_connection_list[0].chan == - pm_conc_connection_list[2].chan)){ + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq && + pm_conc_connection_list[0].freq == + pm_conc_connection_list[2].freq){ qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); strlcat(cc_mode, " SCC", sizeof(cc_mode)); @@ -1367,8 +1352,9 @@ QDF_STATUS policy_mgr_pdev_get_pcl(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("get pcl to set it to the FW"); status = policy_mgr_get_pcl(psoc, con_mode, - pcl->pcl_list, &pcl->pcl_len, - pcl->weight_list, QDF_ARRAY_SIZE(pcl->weight_list)); + pcl->pcl_list, &pcl->pcl_len, + pcl->weight_list, + QDF_ARRAY_SIZE(pcl->weight_list)); if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Unable to set PCL to FW, Get PCL failed"); @@ -1468,6 +1454,7 @@ void pm_dbs_opportunistic_timer_handler(void *data) uint32_t session_id; struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data; enum policy_mgr_conn_update_reason reason; + struct policy_mgr_psoc_priv_obj *pm_ctx = policy_mgr_get_context(psoc); if (!psoc) { policy_mgr_err("Invalid Context"); @@ -1477,8 +1464,14 @@ void pm_dbs_opportunistic_timer_handler(void *data) /* if we still need it */ action = policy_mgr_need_opportunistic_upgrade(psoc, &reason); policy_mgr_debug("action:%d", action); - if (!action) + if (!action) { + return; + } else if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress && + pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) { + policy_mgr_debug("SAP is in CAC_IN_PROGRESS state, restarting"); + policy_mgr_restart_opportunistic_timer(psoc, false); return; + } session_id = pm_get_vdev_id_of_first_conn_idx(psoc); policy_mgr_next_actions(psoc, session_id, action, reason); @@ -1667,21 +1660,22 @@ enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw) * Return: QDF_STATUS */ -static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, +static QDF_STATUS policy_mgr_get_sbs_channels( + uint32_t *ch_freq_list, uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len, uint32_t *index, enum policy_mgr_pcl_group_id group_id, - uint8_t *available_5g_channels, + uint32_t *available_5g_ch_freqs, uint32_t available_5g_channels_len, bool add_5g_channels) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t conn_index = 0, num_channels = 0; - uint32_t num_5g_channels = 0, cur_5g_channel = 0; - uint8_t remaining_5g_Channels[QDF_MAX_NUM_CHAN] = {}; + uint32_t num_5g_channels = 0, cur_5g_ch_freq = 0; + uint32_t remaining_5g_ch_freqs[NUM_CHANNELS] = {}; uint32_t remaining_channel_index = 0; uint32_t j = 0, i = 0, weight1, weight2; - if ((!channels) || (!len)) { + if (!ch_freq_list || !len) { policy_mgr_err("channels or len is NULL"); status = QDF_STATUS_E_FAILURE; return status; @@ -1702,12 +1696,12 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, weight1, weight2, *index); while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[conn_index].chan)) - && (pm_conc_connection_list[conn_index].in_use)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq) && + pm_conc_connection_list[conn_index].in_use) { num_5g_channels++; - cur_5g_channel = - pm_conc_connection_list[conn_index].chan; + cur_5g_ch_freq = + pm_conc_connection_list[conn_index].freq; } conn_index++; } @@ -1716,8 +1710,8 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, if (num_5g_channels > 1) { /* This case we are already in SBS so return the channels */ while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + ch_freq_list[num_channels++] = + pm_conc_connection_list[conn_index++].freq; if (*index < weight_len) pcl_weight[(*index)++] = weight1; } @@ -1725,22 +1719,22 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, /* fix duplicate issue later */ if (add_5g_channels) for (j = 0; j < available_5g_channels_len; j++) - remaining_5g_Channels[ + remaining_5g_ch_freqs[ remaining_channel_index++] = - available_5g_channels[j]; + available_5g_ch_freqs[j]; } else { /* Get list of valid sbs channels for the current * connected channel */ for (j = 0; j < available_5g_channels_len; j++) { - if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( - cur_5g_channel, available_5g_channels[j])) { - channels[num_channels++] = - available_5g_channels[j]; + if (WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( + cur_5g_ch_freq, available_5g_ch_freqs[j])) { + ch_freq_list[num_channels++] = + available_5g_ch_freqs[j]; } else { - remaining_5g_Channels[ - remaining_channel_index++] = - available_5g_channels[j]; + remaining_5g_ch_freqs[ + remaining_channel_index++] = + available_5g_ch_freqs[j]; continue; } if (*index < weight_len) @@ -1750,8 +1744,8 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, } if (add_5g_channels) { - qdf_mem_copy(channels+num_channels, remaining_5g_Channels, - remaining_channel_index); + qdf_mem_copy(ch_freq_list + num_channels, remaining_5g_ch_freqs, + remaining_channel_index * sizeof(*ch_freq_list)); *len += remaining_channel_index; for (i = 0; ((i < remaining_channel_index) && (i < weight_len)); i++) @@ -1761,11 +1755,12 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, return status; } - /** * policy_mgr_get_connection_channels() - provides the channel(s) * on which current connection(s) is - * @channels: the channel(s) on which current connection(s) is + * @psoc: psoc object + * @mode: conn mode + * @ch_freq_list: the channel(s) on which current connection(s) is * @len: Number of channels * @order: no order OR 2.4 Ghz channel followed by 5 Ghz * channel OR 5 Ghz channel followed by 2.4 Ghz channel @@ -1783,7 +1778,8 @@ static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, */ static QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, - uint8_t *channels, + enum policy_mgr_con_mode mode, + uint32_t *ch_freq_list, uint32_t *len, enum policy_mgr_pcl_channel_order order, bool skip_dfs_channel, uint8_t *pcl_weight, uint32_t weight_len, @@ -1793,6 +1789,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, uint32_t conn_index = 0, num_channels = 0; uint32_t weight1, weight2; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool add_6ghz = true; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1800,7 +1797,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, return status; } - if ((!channels) || (!len)) { + if (!ch_freq_list || !len) { policy_mgr_err("channels or len is NULL"); status = QDF_STATUS_E_FAILURE; return status; @@ -1819,27 +1816,37 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, * assignments. * * e.g., when order is POLICY_MGR_PCL_ORDER_24G_THEN_5G and group id is - * POLICY_MGR_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is - * assigned to 2.4GHz channels and the weight - * WEIGHT_OF_GROUP3_PCL_CHANNELS is assigned to the 5GHz channels. + * POLICY_MGR_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is + * assigned to 2.4GHz channels and the weight + * WEIGHT_OF_GROUP3_PCL_CHANNELS is assigned to the 5GHz channels. */ if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; - } else { + } else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) { weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS; weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } else { + weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS; } + if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) + add_6ghz = false; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (POLICY_MGR_PCL_ORDER_NONE == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[conn_index].chan)) { + bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( + pm_conc_connection_list[conn_index].freq); + if (skip_dfs_channel && wlan_reg_is_dfs_for_freq( + pm_ctx->pdev, + pm_conc_connection_list[conn_index].freq)) { conn_index++; - } else if (*index < weight_len) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + } else if ((*index < weight_len) && + (!is_6ghz_ch || add_6ghz)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; pcl_weight[(*index)++] = weight1; } else { conn_index++; @@ -1848,11 +1855,12 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, *len = num_channels; } else if (POLICY_MGR_PCL_ORDER_24G_THEN_5G == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[conn_index].chan) + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq) && (*index < weight_len)) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; pcl_weight[(*index)++] = weight1; } else { conn_index++; @@ -1860,14 +1868,31 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, } conn_index = 0; while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[conn_index].chan)) { + if (skip_dfs_channel && + wlan_reg_is_dfs_for_freq( + pm_ctx->pdev, + pm_conc_connection_list[conn_index].freq)) { conn_index++; - } else if (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[conn_index].chan) - && (*index < weight_len)) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq) && + (*index < weight_len)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; + pcl_weight[(*index)++] = weight2; + } else { + conn_index++; + } + } + conn_index = 0; + while (add_6ghz && + PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( + pm_conc_connection_list[conn_index].freq); + if (is_6ghz_ch && (*index < weight_len)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; pcl_weight[(*index)++] = weight2; } else { conn_index++; @@ -1876,14 +1901,17 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, *len = num_channels; } else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[conn_index].chan)) { + if (skip_dfs_channel && + wlan_reg_is_dfs_for_freq( + pm_ctx->pdev, + pm_conc_connection_list[conn_index].freq)) { conn_index++; - } else if (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[conn_index].chan) - && (*index < weight_len)) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq) && + (*index < weight_len)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; pcl_weight[(*index)++] = weight1; } else { conn_index++; @@ -1891,17 +1919,32 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, } conn_index = 0; while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[conn_index].chan) - && (*index < weight_len)) { - channels[num_channels++] = - pm_conc_connection_list[conn_index++].chan; + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[conn_index].freq) && + (*index < weight_len)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; pcl_weight[(*index)++] = weight2; } else { conn_index++; } } + conn_index = 0; + while (add_6ghz && + PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ( + pm_conc_connection_list[conn_index].freq); + if (is_6ghz_ch && (*index < weight_len)) { + ch_freq_list[num_channels++] = + pm_conc_connection_list[ + conn_index++].freq; + pcl_weight[(*index)++] = weight2; + } else { + conn_index++; + } + } *len = num_channels; } else { policy_mgr_err("unknown order %d", order); @@ -1925,7 +1968,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, * Return: None */ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( - struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, + struct wlan_objmgr_psoc *psoc, uint32_t *pcl_channels, uint32_t *len, uint8_t *weight_list, uint32_t weight_len) { uint8_t i; @@ -1952,7 +1995,7 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( return; if (len) - orig_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN); + orig_channel_count = QDF_MIN(*len, NUM_CHANNELS); else { policy_mgr_err("invalid number of channel length"); return; @@ -1961,8 +2004,8 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( policy_mgr_debug("Set weight of DFS/passive channels to 0"); for (i = 0; i < orig_channel_count; i++) { - channel_state = wlan_reg_get_channel_state(pm_ctx->pdev, - pcl_channels[i]); + channel_state = wlan_reg_get_channel_state_for_freq( + pm_ctx->pdev, pcl_channels[i]); if ((channel_state == CHANNEL_STATE_DISABLE) || (channel_state == CHANNEL_STATE_INVALID)) /* Set weight of inactive channels to 0 */ @@ -1975,6 +2018,77 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( return; } +static void policy_mgr_add_5g_to_pcl( + struct wlan_objmgr_psoc *psoc, + uint32_t *ch_freq_list, + uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len, + uint32_t *index, enum policy_mgr_pcl_group_id group_id, + const uint32_t *chlist_5g, uint8_t chlist_5g_len, + const uint32_t *chlist_6g, uint8_t chlist_6g_len) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t weight1, weight2; + const uint32_t *chlist1; + uint8_t chlist1_len; + const uint32_t *chlist2; + uint8_t chlist2_len; + uint32_t i; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { + weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + } else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) { + weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } else { + weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS; + } + if (pm_ctx->cfg.pcl_band_priority == POLICY_MGR_PCL_BAND_6G_THEN_5G) { + chlist1 = chlist_6g; + chlist1_len = chlist_6g_len; + chlist2 = chlist_5g; + chlist2_len = chlist_5g_len; + } else { + chlist1 = chlist_5g; + chlist1_len = chlist_5g_len; + chlist2 = chlist_6g; + chlist2_len = chlist_6g_len; + } + if ((chlist1_len + *index) > weight_len) { + policy_mgr_err("no enough weight len %d chlist1_len %d %d", + weight_len, chlist1_len, *index); + return; + } + qdf_mem_copy(ch_freq_list, chlist1, chlist1_len * sizeof(*chlist1)); + for (i = 0; i < chlist1_len; i++) + pcl_weight[(*index)++] = weight1; + + *len += chlist1_len; + + if ((chlist2_len + *index) > weight_len) { + policy_mgr_err("no enough weight len chlist2_len %d %d %d", + weight_len, chlist2_len, *index); + return; + } + qdf_mem_copy(&ch_freq_list[chlist1_len], chlist2, + chlist2_len * sizeof(*chlist2)); + for (i = 0; i < chlist2_len; i++) + pcl_weight[(*index)++] = weight2; + *len += chlist2_len; + + policy_mgr_debug("Add 5g chlist len %d 6g chlist len %d len %d index %d order %d", + chlist_5g_len, chlist_6g_len, *len, *index, + pm_ctx->cfg.pcl_band_priority); +} + /** * policy_mgr_get_channel_list() - provides the channel list * suggestion for new connection @@ -1993,22 +2107,20 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( */ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_pcl_type pcl, - uint8_t *pcl_channels, uint32_t *len, + uint32_t *pcl_channels, uint32_t *len, enum policy_mgr_con_mode mode, uint8_t *pcl_weights, uint32_t weight_len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_channels = 0; uint32_t sbs_num_channels = 0; - uint32_t chan_index = 0, chan_index_24 = 0, chan_index_5 = 0; - uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0}; - uint8_t channel_list_24[QDF_MAX_NUM_CHAN] = {0}; - uint8_t channel_list_5[QDF_MAX_NUM_CHAN] = {0}; - uint8_t sbs_channel_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t chan_index_24 = 0, chan_index_5 = 0, chan_index_6 = 0; bool skip_dfs_channel = false; - bool is_etsi13_srd_chan_allowed_in_mas_mode = true; uint32_t i = 0, j = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool sta_sap_scc_on_dfs_chan; + uint32_t *channel_list, *channel_list_24, *channel_list_5, + *sbs_channel_list, *channel_list_6; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2033,63 +2145,63 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("pcl is 0"); return QDF_STATUS_SUCCESS; } + + channel_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); + channel_list_24 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); + channel_list_5 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); + sbs_channel_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); + channel_list_6 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t)); + if (!channel_list || !channel_list_24 || !channel_list_5 || + !sbs_channel_list || !channel_list_6) { + status = QDF_STATUS_E_NOMEM; + goto end; + } + /* get the channel list for current domain */ - status = policy_mgr_get_valid_chans(psoc, channel_list, &num_channels); + status = policy_mgr_get_valid_chans(psoc, channel_list, + &num_channels); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Error in getting valid channels"); - return status; + goto end; } + /* + * if you have atleast one STA connection then don't fill DFS channels + * in the preferred channel list + */ + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) { - policy_mgr_skip_dfs_ch(psoc, - &skip_dfs_channel); - is_etsi13_srd_chan_allowed_in_mas_mode = - wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx-> - pdev); + if ((policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) > 0) && + (!sta_sap_scc_on_dfs_chan)) { + policy_mgr_debug("skip DFS ch from pcl for SAP/Go"); + skip_dfs_channel = true; + } } /* Let's divide the list in 2.4 & 5 Ghz lists */ - while ((chan_index < QDF_MAX_NUM_CHAN) && - (channel_list[chan_index] <= 11) && - (chan_index_24 < QDF_MAX_NUM_CHAN)) - channel_list_24[chan_index_24++] = channel_list[chan_index++]; - if ((chan_index < QDF_MAX_NUM_CHAN) && - (channel_list[chan_index] == 12) && - (chan_index_24 < QDF_MAX_NUM_CHAN)) { - channel_list_24[chan_index_24++] = channel_list[chan_index++]; - if ((chan_index < QDF_MAX_NUM_CHAN) && - (channel_list[chan_index] == 13) && - (chan_index_24 < QDF_MAX_NUM_CHAN)) { - channel_list_24[chan_index_24++] = - channel_list[chan_index++]; - if ((chan_index < QDF_MAX_NUM_CHAN) && - (channel_list[chan_index] == 14) && - (chan_index_24 < QDF_MAX_NUM_CHAN)) - channel_list_24[chan_index_24++] = - channel_list[chan_index++]; - } - } + for (i = 0; i < num_channels; i++) { + if (wlan_reg_is_24ghz_ch_freq(channel_list[i])) { + channel_list_24[chan_index_24++] = channel_list[i]; + } else if (wlan_reg_is_5ghz_ch_freq(channel_list[i])) { + if ((true == skip_dfs_channel) && + wlan_reg_is_dfs_for_freq(pm_ctx->pdev, + channel_list[i])) + continue; - while ((chan_index < num_channels) && - (chan_index < QDF_MAX_NUM_CHAN) && - (chan_index_5 < QDF_MAX_NUM_CHAN)) { - if ((true == skip_dfs_channel) && - wlan_reg_is_dfs_ch(pm_ctx->pdev, - channel_list[chan_index])) { - chan_index++; - continue; - } - if (!is_etsi13_srd_chan_allowed_in_mas_mode && - wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, - channel_list[chan_index])) { - chan_index++; - continue; + channel_list_5[chan_index_5++] = channel_list[i]; + } else if (wlan_reg_is_6ghz_chan_freq(channel_list[i])) { + /* Add to 5G list untill 6G conc support is enabled */ + channel_list_6[chan_index_6++] = channel_list[i]; } - channel_list_5[chan_index_5++] = channel_list[chan_index++]; } - + if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) + chan_index_6 = 0; num_channels = 0; sbs_num_channels = 0; + i = 0; /* In the below switch case, the channel list is populated based on the * pcl. e.g., if the pcl is PM_SCC_CH_24G, the SCC channel group is * populated first followed by the 2.4GHz channel group. Along with @@ -2107,20 +2219,20 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, * When the weight to be assigned to the group is known along with the * number of channels, the weights are directly assigned to the * pcl_weights list. But, the channel list is populated using - * policy_mgr_get_connection_channels(), the order of weights to be used - * is passed as an argument to the function - * policy_mgr_get_connection_channels() using - * 'enum policy_mgr_pcl_group_id' which indicates the next available - * weights to be used and policy_mgr_get_connection_channels() will take - * care of the weight assignments. + * policy_mgr_get_connection_channels(), the order of weights to be used + * is passed as an argument to the function + * policy_mgr_get_connection_channels() using + * 'enum policy_mgr_pcl_group_id' which indicates the next available + * weights to be used and policy_mgr_get_connection_channels() will take + * care of the weight assignments. * - * e.g., 'enum policy_mgr_pcl_group_id' value of - * POLICY_MGR_PCL_GROUP_ID2_ID3 indicates that the next available groups - * for weight assignment are WEIGHT_OF_GROUP2_PCL_CHANNELS and - * WEIGHT_OF_GROUP3_PCL_CHANNELS and that the - * weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated. - * So, in the same example, when order is - * POLICY_MGR_PCL_ORDER_24G_THEN_5G, + * e.g., 'enum policy_mgr_pcl_group_id' value of + * POLICY_MGR_PCL_GROUP_ID2_ID3 indicates that the next available groups + * for weight assignment are WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS and that the + * weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated. + * So, in the same example, when order is + * POLICY_MGR_PCL_ORDER_24G_THEN_5G, * policy_mgr_get_connection_channels() will assign the weight * WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the * weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels. @@ -2129,43 +2241,48 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, case PM_24G: chan_index_24 = QDF_MIN(chan_index_24, weight_len); qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24); + chan_index_24 * sizeof(*pcl_channels)); *len = chan_index_24; for (i = 0; i < *len; i++) pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case PM_5G: - chan_index_5 = QDF_MIN(chan_index_5, weight_len); - qdf_mem_copy(pcl_channels, channel_list_5, - chan_index_5); - *len = chan_index_5; - for (i = 0; i < *len; i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_add_5g_to_pcl( + psoc, pcl_channels, len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_SCC_CH: case PM_MCC_CH: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; status = QDF_STATUS_SUCCESS; break; case PM_SCC_CH_24G: case PM_MCC_CH_24G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; chan_index_24 = QDF_MIN((num_channels + chan_index_24), weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_24, chan_index_24); + qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, + chan_index_24 * sizeof(*pcl_channels)); *len += chan_index_24; for (j = 0; j < chan_index_24; i++, j++) pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; @@ -2174,157 +2291,174 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, break; case PM_SCC_CH_5G: case PM_MCC_CH_5G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, - num_channels); + num_channels * sizeof(*pcl_channels)); *len = num_channels; - chan_index_5 = QDF_MIN((num_channels + chan_index_5), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_5, chan_index_5); - *len += chan_index_5; - for (j = 0; j < chan_index_5; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; + policy_mgr_add_5g_to_pcl( + psoc, &pcl_channels[num_channels], len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID2_ID3, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH: case PM_24G_MCC_CH: chan_index_24 = QDF_MIN(chan_index_24, weight_len); qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24); + chan_index_24 * sizeof(*pcl_channels)); *len = chan_index_24; for (i = 0; i < chan_index_24; i++) pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], - channel_list, num_channels); + qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, + num_channels * sizeof(*pcl_channels)); *len += num_channels; status = QDF_STATUS_SUCCESS; break; case PM_5G_SCC_CH: case PM_5G_MCC_CH: - chan_index_5 = QDF_MIN(chan_index_5, weight_len); - qdf_mem_copy(pcl_channels, channel_list_5, - chan_index_5); - *len = chan_index_5; - for (i = 0; i < chan_index_5; i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels(psoc, + policy_mgr_add_5g_to_pcl( + psoc, pcl_channels, len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); + + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, - POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_5], - channel_list, num_channels); + POLICY_MGR_PCL_GROUP_ID3_ID4); + qdf_mem_copy(&pcl_channels[*len], channel_list, + num_channels * sizeof(*pcl_channels)); *len += num_channels; status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_24G_THEN_5G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, - num_channels); + num_channels * sizeof(*pcl_channels)); *len = num_channels; status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_5G_THEN_2G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5_24G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_24G_THEN_5G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; chan_index_24 = QDF_MIN((num_channels + chan_index_24), weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_24, chan_index_24); + qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, + chan_index_24 * sizeof(*pcl_channels)); *len += chan_index_24; for (j = 0; j < chan_index_24; i++, j++) pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_24_SCC_ON_5_5G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_24G_THEN_5G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; - chan_index_5 = QDF_MIN((num_channels + chan_index_5), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_5, chan_index_5); - *len += chan_index_5; - for (j = 0; j < chan_index_5; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + policy_mgr_add_5g_to_pcl( + psoc, &pcl_channels[num_channels], len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24_24G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_5G_THEN_2G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; chan_index_24 = QDF_MIN((num_channels + chan_index_24), weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_24, chan_index_24); + qdf_mem_copy(&pcl_channels[num_channels], channel_list_24, + chan_index_24 * sizeof(*pcl_channels)); *len += chan_index_24; for (j = 0; j < chan_index_24; i++, j++) pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case PM_SCC_ON_5_SCC_ON_24_5G: - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_5G_THEN_2G, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2); - qdf_mem_copy(pcl_channels, channel_list, num_channels); + qdf_mem_copy(pcl_channels, channel_list, + num_channels * sizeof(*pcl_channels)); *len = num_channels; - chan_index_5 = QDF_MIN((num_channels + chan_index_5), - weight_len) - num_channels; - qdf_mem_copy(&pcl_channels[num_channels], - channel_list_5, chan_index_5); - *len += chan_index_5; - for (j = 0; j < chan_index_5; i++, j++) - pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + policy_mgr_add_5g_to_pcl( + psoc, &pcl_channels[num_channels], len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH_SBS_CH: qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24); + chan_index_24 * sizeof(*pcl_channels)); *len = chan_index_24; for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], - channel_list, num_channels); + qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, + num_channels * sizeof(*pcl_channels)); *len += num_channels; if (policy_mgr_is_hw_sbs_capable(psoc)) { policy_mgr_get_sbs_channels( @@ -2333,23 +2467,25 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, channel_list_5, chan_index_5, false); qdf_mem_copy( &pcl_channels[chan_index_24 + num_channels], - sbs_channel_list, sbs_num_channels); + sbs_channel_list, + sbs_num_channels * sizeof(*pcl_channels)); *len += sbs_num_channels; } status = QDF_STATUS_SUCCESS; break; case PM_24G_SCC_CH_SBS_CH_5G: qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24); + chan_index_24 * sizeof(*pcl_channels)); *len = chan_index_24; for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], - channel_list, num_channels); + qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, + num_channels * sizeof(*pcl_channels)); *len += num_channels; if (policy_mgr_is_hw_sbs_capable(psoc)) { policy_mgr_get_sbs_channels( @@ -2358,22 +2494,25 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, channel_list_5, chan_index_5, true); qdf_mem_copy( &pcl_channels[chan_index_24 + num_channels], - sbs_channel_list, sbs_num_channels); + sbs_channel_list, + sbs_num_channels * sizeof(*pcl_channels)); *len += sbs_num_channels; } else { - qdf_mem_copy( + policy_mgr_add_5g_to_pcl( + psoc, &pcl_channels[chan_index_24 + num_channels], - channel_list_5, chan_index_5); - *len += chan_index_5; - for (i = chan_index_24 + num_channels; - ((i < *len) && (i < weight_len)); i++) - pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); } status = QDF_STATUS_SUCCESS; break; case PM_24G_SBS_CH_MCC_CH: qdf_mem_copy(pcl_channels, channel_list_24, - chan_index_24); + chan_index_24 * sizeof(*pcl_channels)); *len = chan_index_24; for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; @@ -2383,15 +2522,17 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3, channel_list_5, chan_index_5, false); qdf_mem_copy(&pcl_channels[num_channels], - sbs_channel_list, sbs_num_channels); + sbs_channel_list, + sbs_num_channels * sizeof(*pcl_channels)); *len += sbs_num_channels; } - policy_mgr_get_connection_channels(psoc, + policy_mgr_get_connection_channels( + psoc, mode, channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, skip_dfs_channel, pcl_weights, weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3); - qdf_mem_copy(&pcl_channels[chan_index_24], - channel_list, num_channels); + qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, + num_channels * sizeof(*pcl_channels)); *len += num_channels; status = QDF_STATUS_SUCCESS; break; @@ -2402,14 +2543,19 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2, channel_list_5, chan_index_5, true); qdf_mem_copy(&pcl_channels[num_channels], - sbs_channel_list, sbs_num_channels); + sbs_channel_list, + sbs_num_channels * sizeof(*pcl_channels)); *len += sbs_num_channels; } else { - qdf_mem_copy(pcl_channels, channel_list_5, - chan_index_5); - *len = chan_index_5; - for (i = 0; ((i < *len) && (i < weight_len)); i++) - pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_add_5g_to_pcl( + psoc, + pcl_channels, + len, + pcl_weights, weight_len, + &i, + POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, + channel_list_6, chan_index_6); } status = QDF_STATUS_SUCCESS; break; @@ -2420,7 +2566,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, if ((*len != 0) && (*len != i)) policy_mgr_debug("pcl len (%d) and weight list len mismatch (%d)", - *len, i); + *len, i); /* check the channel avoidance list for beaconing entities */ if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) @@ -2430,22 +2576,18 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, policy_mgr_set_weight_of_dfs_passive_channels_to_zero(psoc, pcl_channels, len, pcl_weights, weight_len); +end: + qdf_mem_free(channel_list); + qdf_mem_free(channel_list_24); + qdf_mem_free(channel_list_5); + qdf_mem_free(sbs_channel_list); + qdf_mem_free(channel_list_6); + return status; } -/** - * policy_mgr_disallow_mcc() - Check for mcc - * - * @channel: channel on which new connection is coming up - * - * When a new connection is about to come up check if current - * concurrency combination including the new connection is - * causing MCC - * - * Return: True/False - */ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, - uint8_t channel) + uint32_t ch_freq) { uint32_t index = 0; bool match = false; @@ -2459,14 +2601,13 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (PM_CONC_CONNECTION_LIST_VALID_INDEX(index)) { if (policy_mgr_is_hw_dbs_capable(psoc) == false) { - if (pm_conc_connection_list[index].chan != - channel) { + if (pm_conc_connection_list[index].freq != ch_freq) { match = true; break; } - } else if (WLAN_REG_IS_5GHZ_CH - (pm_conc_connection_list[index].chan)) { - if (pm_conc_connection_list[index].chan != channel) { + } else if (WLAN_REG_IS_5GHZ_CH_FREQ + (pm_conc_connection_list[index].freq)) { + if (pm_conc_connection_list[index].freq != ch_freq) { match = true; break; } @@ -2478,11 +2619,45 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, return match; } +/** + * policy_mgr_is_multi_ap_plus_sta_3vif_conc() - Check multiple AP plus STA + * concurrency + * @mode1: policy_mgr_con_mode of connection 1 + * @mode2: policy_mgr_con_mode of connection 2 + * @mode2: policy_mgr_con_mode of connection 3 + * + * Check the 3vif concurrency is SAP(GO)+SAP(GO)+STA or not based on + * connection mode. + * + * Return: True/False + */ +static bool policy_mgr_is_multi_ap_plus_sta_3vif_conc( + enum policy_mgr_con_mode mode1, enum policy_mgr_con_mode mode2, + enum policy_mgr_con_mode mode3) +{ + if (mode1 == PM_STA_MODE && + (mode2 == PM_SAP_MODE || mode2 == PM_P2P_GO_MODE) && + (mode3 == PM_SAP_MODE || mode3 == PM_P2P_GO_MODE)) + return true; + if (mode2 == PM_STA_MODE && + (mode1 == PM_SAP_MODE || mode1 == PM_P2P_GO_MODE) && + (mode3 == PM_SAP_MODE || mode3 == PM_P2P_GO_MODE)) + return true; + if (mode3 == PM_STA_MODE && + (mode1 == PM_SAP_MODE || mode1 == PM_P2P_GO_MODE) && + (mode2 == PM_SAP_MODE || mode2 == PM_P2P_GO_MODE)) + return true; + + return false; +} + /** * policy_mgr_allow_new_home_channel() - Check for allowed number of * home channels + * @mode: policy_mgr_con_mode of new connection, * @channel: channel on which new connection is coming up * @num_connections: number of current connections + * @is_dfs_ch: DFS channel or not * * When a new connection is about to come up check if current * concurrency combination including the new connection is @@ -2490,8 +2665,9 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, * * Return: True/False */ -bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, - uint8_t channel, uint32_t num_connections) +bool policy_mgr_allow_new_home_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t ch_freq, uint32_t num_connections, bool is_dfs_ch) { bool status = true; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -2509,27 +2685,26 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, if (num_connections == 2) { /* No SCC or MCC combination is allowed with / on DFS channel */ if ((mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) - && wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && - (wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[0].chan) || - wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[1].chan))) { - + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && + is_dfs_ch && + ((pm_conc_connection_list[0].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) || + (pm_conc_connection_list[1].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)))) { policy_mgr_rl_debug("Existing DFS connection, new 3-port DFS connection is not allowed"); status = false; - } else if (((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) + } else if (((pm_conc_connection_list[0].freq != + pm_conc_connection_list[1].freq) || (mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) ) && (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac)) { if (policy_mgr_is_hw_dbs_capable(psoc) == false) { - if ((channel != - pm_conc_connection_list[0].chan) && - (channel != - pm_conc_connection_list[1].chan)) { + if (ch_freq != + pm_conc_connection_list[0].freq && + ch_freq != + pm_conc_connection_list[1].freq) { policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); status = false; } @@ -2548,26 +2723,56 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, * same MAC is possible. */ status = true; - } else if (((WLAN_REG_IS_24GHZ_CH(channel)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[1].chan))) || - ((WLAN_REG_IS_5GHZ_CH(channel)) && - (WLAN_REG_IS_5GHZ_CH - (pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH - (pm_conc_connection_list[1].chan)))) { - policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); - status = false; + } else if (((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ + (pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ + (pm_conc_connection_list[1].freq))) || + ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ + (pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ + (pm_conc_connection_list[1].freq)))) { + policy_mgr_rl_debug("don't allow 3rd home channel on same MAC"); + status = false; + } + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + /* Existing two connections are SCC */ + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + /* keep legacy chip "allow" as it is */ + policy_mgr_rl_debug("allow 2 intf SCC + new intf ch %d for legacy hw", + ch_freq); + } else if ((pm_conc_connection_list[0].mode == + PM_NAN_DISC_MODE && + pm_conc_connection_list[1].mode == + PM_NDI_MODE) || + (pm_conc_connection_list[0].mode == + PM_NDI_MODE && + pm_conc_connection_list[1].mode == + PM_NAN_DISC_MODE)) { + /* + * NAN + NDI are managed in Firmware by dividing + * up slots. Connection on NDI is re-negotiable + * and therefore a 3rd connection with the + * same MAC is possible. + */ + } else if (wlan_reg_is_same_band_channels( + ch_freq, pm_conc_connection_list[0].freq) && + policy_mgr_is_multi_ap_plus_sta_3vif_conc( + pm_conc_connection_list[0].mode, + pm_conc_connection_list[1].mode, + mode)) { + policy_mgr_rl_debug("don't allow 3rd home channel on same MAC - sta existing"); + status = false; } } - } else if ((num_connections == 1) - && (mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) - && wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) - && wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[0].chan)) { + } else if ((num_connections == 1) && + (mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && + is_dfs_ch && + (pm_conc_connection_list[0].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2))) { policy_mgr_rl_debug("Existing DFS connection, new 2-port DFS connection is not allowed"); status = false; @@ -2577,22 +2782,8 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, return status; } -/** - * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed - * @channel: channel number which needs to be validated - * @list: list of existing connections. - * @mode: mode against which channel needs to be validated - * - * This API takes the channel as input and compares with existing - * connection channels. If existing connection's channel is DFS channel - * and provided channel is 5G channel then don't allow concurrency to - * happen as MCC with DFS channel is not yet supported - * - * Return: true if 5G channel is allowed, false if not allowed - * - */ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, - uint8_t channel, uint32_t *list, + uint32_t ch_freq, uint32_t *list, enum policy_mgr_con_mode mode) { uint32_t index = 0, count = 0; @@ -2607,11 +2798,10 @@ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, count = policy_mgr_mode_specific_connection_count(psoc, mode, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (index < count) { - if (wlan_reg_is_dfs_ch( - pm_ctx->pdev, - pm_conc_connection_list[list[index]].chan) && - WLAN_REG_IS_5GHZ_CH(channel) && - (channel != pm_conc_connection_list[list[index]].chan)) { + if ((pm_conc_connection_list[list[index]].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) && + WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && + (ch_freq != pm_conc_connection_list[list[index]].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel"); return false; @@ -2665,10 +2855,15 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("nss update successful for vdev:%d ori %d reason %d", vdev_id, original_vdev_id, reason); - if (PM_NOP != next_action) - policy_mgr_next_actions(psoc, original_vdev_id, next_action, - reason); - else { + if (PM_NOP != next_action) { + if (reason == POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH) + policy_mgr_next_actions(psoc, vdev_id, next_action, + reason); + else + policy_mgr_next_actions(psoc, original_vdev_id, + next_action, reason); + } else { + policy_mgr_debug("No action needed right now"); ret = policy_mgr_set_opportunistic_update(psoc); if (!QDF_IS_STATUS_SUCCESS(ret)) policy_mgr_err("ERROR: set opportunistic_update event failed"); @@ -2688,15 +2883,17 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint32_t conn_index = 0; uint32_t vdev_id; - uint32_t original_nss; + uint32_t original_nss, ch_freq; struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t chan; + enum phy_ch_width ch_width = CH_WIDTH_MAX; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return status; } + if (next_action == PM_DBS2 && band == POLICY_MGR_BAND_5) + ch_width = CH_WIDTH_40MHZ; count = policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, list); @@ -2705,7 +2902,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, vdev_id = pm_conc_connection_list[list[index]].vdev_id; original_nss = pm_conc_connection_list[list[index]].original_nss; - chan = pm_conc_connection_list[list[index]].chan; + ch_freq = pm_conc_connection_list[list[index]].freq; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); conn_index = policy_mgr_get_connection_for_vdev_id( psoc, vdev_id); @@ -2718,11 +2915,11 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, if (original_nss == 2 && (band == POLICY_MGR_ANY || (band == POLICY_MGR_BAND_24 && - WLAN_REG_IS_24GHZ_CH(chan)) || + WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) || (band == POLICY_MGR_BAND_5 && - WLAN_REG_IS_5GHZ_CH(chan)))) { + WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) { status = pm_ctx->sme_cbacks.sme_nss_update_request( - vdev_id, new_nss, + vdev_id, new_nss, ch_width, policy_mgr_nss_update_cb, next_action, psoc, reason, original_vdev_id); @@ -2740,7 +2937,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, vdev_id = pm_conc_connection_list[list[index]].vdev_id; original_nss = pm_conc_connection_list[list[index]].original_nss; - chan = pm_conc_connection_list[list[index]].chan; + ch_freq = pm_conc_connection_list[list[index]].freq; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); conn_index = policy_mgr_get_connection_for_vdev_id( psoc, vdev_id); @@ -2752,11 +2949,11 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, if (original_nss == 2 && (band == POLICY_MGR_ANY || (band == POLICY_MGR_BAND_24 && - WLAN_REG_IS_24GHZ_CH(chan)) || + WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) || (band == POLICY_MGR_BAND_5 && - WLAN_REG_IS_5GHZ_CH(chan)))) { + WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) { status = pm_ctx->sme_cbacks.sme_nss_update_request( - vdev_id, new_nss, + vdev_id, new_nss, ch_width, policy_mgr_nss_update_cb, next_action, psoc, reason, original_vdev_id); @@ -2898,9 +3095,9 @@ enum policy_mgr_conc_next_action num_connections = policy_mgr_get_connection_count(psoc); policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", - pm_conc_connection_list[0].chan, - pm_conc_connection_list[1].chan, - pm_conc_connection_list[2].chan, num_connections, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq, + pm_conc_connection_list[2].freq, num_connections, hw_mode.dbs_cap); /* If the band of operation of both the MACs is the same, @@ -2908,25 +3105,23 @@ enum policy_mgr_conc_next_action */ switch (num_connections) { case 1: - band1 = wlan_reg_chan_to_band(pm_conc_connection_list[0].chan); - if (band1 == BAND_2G) + band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq); + if (band1 == REG_BAND_2G) return PM_DBS; else return PM_NOP; case 2: - band1 = wlan_reg_chan_to_band(pm_conc_connection_list[0].chan); - band2 = wlan_reg_chan_to_band(pm_conc_connection_list[1].chan); - if ((band1 == BAND_2G) || - (band2 == BAND_2G)) { + band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq); + band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq); + if (band1 == REG_BAND_2G || band2 == REG_BAND_2G) { if (!hw_mode.dbs_cap) return PM_DBS; else return PM_NOP; - } else if ((band1 == BAND_5G) && - (band2 == BAND_5G)) { - if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( - pm_conc_connection_list[0].chan, - pm_conc_connection_list[1].chan)) { + } else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G) { + if (WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq)) { if (!hw_mode.sbs_cap) return PM_SBS; else @@ -2940,28 +3135,26 @@ enum policy_mgr_conc_next_action } else return PM_NOP; case 3: - band1 = wlan_reg_chan_to_band(pm_conc_connection_list[0].chan); - band2 = wlan_reg_chan_to_band(pm_conc_connection_list[1].chan); - band3 = wlan_reg_chan_to_band(pm_conc_connection_list[2].chan); - if ((band1 == BAND_2G) || - (band2 == BAND_2G) || - (band3 == BAND_2G)) { + band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq); + band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq); + band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq); + if (band1 == REG_BAND_2G || band2 == REG_BAND_2G || + band3 == REG_BAND_2G) { if (!hw_mode.dbs_cap) return PM_DBS; else return PM_NOP; - } else if ((band1 == BAND_5G) && - (band2 == BAND_5G) && - (band3 == BAND_5G)) { - if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( - pm_conc_connection_list[0].chan, - pm_conc_connection_list[2].chan) && - WLAN_REG_IS_CHANNEL_VALID_5G_SBS( - pm_conc_connection_list[1].chan, - pm_conc_connection_list[2].chan) && - WLAN_REG_IS_CHANNEL_VALID_5G_SBS( - pm_conc_connection_list[0].chan, - pm_conc_connection_list[1].chan)) { + } else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G && + band3 == REG_BAND_5G) { + if (WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( + pm_conc_connection_list[0].freq, + pm_conc_connection_list[2].freq) && + WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( + pm_conc_connection_list[1].freq, + pm_conc_connection_list[2].freq) && + WLAN_REG_IS_FREQUENCY_VALID_5G_SBS( + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq)) { if (!hw_mode.sbs_cap) return PM_SBS; else @@ -3017,9 +3210,9 @@ enum policy_mgr_conc_next_action qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", - pm_conc_connection_list[0].chan, - pm_conc_connection_list[1].chan, - pm_conc_connection_list[2].chan, num_connections, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq, + pm_conc_connection_list[2].freq, num_connections, hw_mode.dbs_cap); /* If the band of operation of both the MACs is the same, @@ -3031,8 +3224,8 @@ enum policy_mgr_conc_next_action next_action = PM_NOP; break; case 2: - band1 = wlan_reg_chan_to_band(pm_conc_connection_list[0].chan); - band2 = wlan_reg_chan_to_band(pm_conc_connection_list[1].chan); + band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq); + band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq); if ((band1 == band2) && (hw_mode.dbs_cap)) next_action = PM_SINGLE_MAC_UPGRADE; else if ((band1 != band2) && (!hw_mode.dbs_cap)) @@ -3043,9 +3236,9 @@ enum policy_mgr_conc_next_action break; case 3: - band1 = wlan_reg_chan_to_band(pm_conc_connection_list[0].chan); - band2 = wlan_reg_chan_to_band(pm_conc_connection_list[1].chan); - band3 = wlan_reg_chan_to_band(pm_conc_connection_list[2].chan); + band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq); + band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq); + band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq); if (((band1 == band2) && (band2 == band3)) && (hw_mode.dbs_cap)) { next_action = PM_SINGLE_MAC_UPGRADE; @@ -3114,13 +3307,14 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels( { pm_ctx->sap_mandatory_channels_len = 0; qdf_mem_zero(pm_ctx->sap_mandatory_channels, - QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels)); + QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) * + sizeof(*pm_ctx->sap_mandatory_channels)); return QDF_STATUS_SUCCESS; } void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, - uint8_t chan) + uint32_t ch_freq) { int i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -3132,13 +3326,13 @@ void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, } for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) { - if (chan == pm_ctx->sap_mandatory_channels[i]) + if (ch_freq == pm_ctx->sap_mandatory_channels[i]) return; } - policy_mgr_debug("chan %hu", chan); + policy_mgr_debug("Ch freq: %hu", ch_freq); pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++] - = chan; + = ch_freq; } uint32_t policy_mgr_get_sap_mandatory_chan_list_len( @@ -3157,7 +3351,7 @@ uint32_t policy_mgr_get_sap_mandatory_chan_list_len( void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc) { - uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t ch_freq_list[NUM_CHANNELS] = {0}; uint32_t len = 0; int i; QDF_STATUS status; @@ -3169,28 +3363,28 @@ void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc) return; } - status = policy_mgr_get_valid_chans(psoc, chan_list, &len); + status = policy_mgr_get_valid_chans(psoc, ch_freq_list, &len); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Error in getting valid channels"); return; } pm_ctx->sap_mandatory_channels_len = 0; - for (i = 0; (i < len) && (i < QDF_MAX_NUM_CHAN); i++) { - if (WLAN_REG_IS_24GHZ_CH(chan_list[i])) { + for (i = 0; (i < len) && (i < NUM_CHANNELS); i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i])) { policy_mgr_debug("Add chan %hu to mandatory list", - chan_list[i]); + ch_freq_list[i]); pm_ctx->sap_mandatory_channels[ pm_ctx->sap_mandatory_channels_len++] = - chan_list[i]; + ch_freq_list[i]; } } } void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, - uint8_t chan) + uint32_t ch_freq) { - uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t ch_freq_list[NUM_CHANNELS] = {0}; uint32_t num_chan = 0; int i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -3201,20 +3395,22 @@ void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, return; } - if (pm_ctx->sap_mandatory_channels_len >= QDF_MAX_NUM_CHAN) { + if (pm_ctx->sap_mandatory_channels_len >= NUM_CHANNELS) { policy_mgr_err("Invalid channel len %d ", pm_ctx->sap_mandatory_channels_len); return; } for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) { - if (chan == pm_ctx->sap_mandatory_channels[i]) + if (ch_freq == pm_ctx->sap_mandatory_channels[i]) continue; - chan_list[num_chan++] = pm_ctx->sap_mandatory_channels[i]; + ch_freq_list[num_chan++] = pm_ctx->sap_mandatory_channels[i]; } qdf_mem_zero(pm_ctx->sap_mandatory_channels, - pm_ctx->sap_mandatory_channels_len); - qdf_mem_copy(pm_ctx->sap_mandatory_channels, chan_list, num_chan); + pm_ctx->sap_mandatory_channels_len * + sizeof(*pm_ctx->sap_mandatory_channels)); + qdf_mem_copy(pm_ctx->sap_mandatory_channels, ch_freq_list, + num_chan * sizeof(*pm_ctx->sap_mandatory_channels)); pm_ctx->sap_mandatory_channels_len = num_chan; } diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index c1b9448888b68367027a716afe0acda41f6a9855..4fb7c1b01197967e6bbefa035fa9e5e7202a8f75 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,6 +36,7 @@ #include "wlan_nan_api.h" #include "nan_public_structs.h" #include "wlan_reg_services_api.h" +#include "wlan_mlme_vdev_mgr_interface.h" /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 @@ -71,27 +73,6 @@ policy_mgr_get_enable_overlap_chnl(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc) -{ - uint32_t mcc_to_scc_switch; - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return false; - } - mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc); - if (mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) - return true; - - if (pm_ctx->cfg.go_force_scc && policy_mgr_is_force_scc(psoc)) - return true; - - return false; -} - QDF_STATUS policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc *psoc, uint8_t dual_mac_feature) { @@ -189,7 +170,7 @@ policy_mgr_get_dfs_master_dynamic_enabled( (pm_conc_connection_list[i].mode == PM_STA_MODE || pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE))) continue; - if (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[i].chan)) + if (WLAN_REG_IS_5GHZ_CH_FREQ(pm_conc_connection_list[i].freq)) sta_on_5g = true; else sta_on_2g = true; @@ -1526,21 +1507,21 @@ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) case 1: break; case 2: - if ((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) && - (pm_conc_connection_list[0].mac == - pm_conc_connection_list[1].mac)) { + if (pm_conc_connection_list[0].freq != + pm_conc_connection_list[1].freq && + pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { is_mcc = true; } break; case 3: - if ((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) || - (pm_conc_connection_list[0].chan != - pm_conc_connection_list[2].chan) || - (pm_conc_connection_list[1].chan != - pm_conc_connection_list[2].chan)){ - is_mcc = true; + if (pm_conc_connection_list[0].freq != + pm_conc_connection_list[1].freq || + pm_conc_connection_list[0].freq != + pm_conc_connection_list[2].freq || + pm_conc_connection_list[1].freq != + pm_conc_connection_list[2].freq){ + is_mcc = true; } break; default: @@ -1552,6 +1533,49 @@ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) return is_mcc; } +bool policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc *psoc) +{ + int index, count; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; + + if (psoc) + pm_ctx = policy_mgr_get_context(psoc); + + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + index = 0; + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + count = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, + list); + while (index < count) { + if (pm_conc_connection_list[list[index]].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return true; + } + index++; + } + count = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, + list); + index = 0; + while (index < count) { + if (pm_conc_connection_list[list[index]].ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return true; + } + index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return false; +} + /** * policy_mgr_set_concurrency_mode() - To set concurrency mode * @psoc: PSOC object data @@ -1635,6 +1659,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_6ghz_flag = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1669,6 +1694,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, if (mode != QDF_NAN_DISC_MODE && pm_ctx->dp_cbacks.hdd_v2_flow_pool_map) pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id); + if (mode == QDF_SAP_MODE) + policy_mgr_get_ap_6ghz_capable(psoc, session_id, + &conn_6ghz_flag); policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); @@ -1709,6 +1737,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb) pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true); } + if (mode == QDF_SAP_MODE) + policy_mgr_init_ap_6ghz_capable(psoc, session_id, + conn_6ghz_flag); policy_mgr_dump_current_concurrency(psoc); @@ -1754,16 +1785,16 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, break; } + if (mode != QDF_NAN_DISC_MODE && + pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap) + pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id); + if (mode == QDF_NDI_MODE && pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt) pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt( psoc, session_id, pm_ctx->no_of_active_sessions[mode]); - if (mode != QDF_NAN_DISC_MODE && - pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap) - pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id); - policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); @@ -1817,6 +1848,16 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb) pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode); } + /* + * When STA disconnected, we need to move DFS SAP + * to Non-DFS if g_sta_sap_scc_on_dfs_chan enabled. + * The same if g_sta_sap_scc_on_lte_coex_chan enabled, + * need to move SAP on unsafe channel to safe channel. + * The flag will be checked by + * policy_mgr_is_sap_restart_required_after_sta_disconnect. + */ + if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) + pm_ctx->do_sap_unsafe_ch_check = true; return qdf_status; } @@ -1831,7 +1872,7 @@ QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc, enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; uint8_t nss_2g = 0, nss_5g = 0; enum policy_mgr_con_mode mode; - uint8_t chan; + uint32_t ch_freq; uint32_t nss = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; bool update_conn = true; @@ -1870,15 +1911,15 @@ QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc, mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); - chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz); + ch_freq = conn_table_entry.mhz; status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); if (QDF_IS_STATUS_SUCCESS(status)) { - if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || - (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1))) + if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) || + (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1)) chain_mask = POLICY_MGR_TWO_TWO; else chain_mask = POLICY_MGR_ONE_ONE; - nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g; + nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g; } else { policy_mgr_err("Error in getting nss"); } @@ -1889,11 +1930,12 @@ QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc, /* add the entry */ policy_mgr_update_conc_list(psoc, conn_index, mode, - chan, + ch_freq, policy_mgr_get_bw(conn_table_entry.chan_width), conn_table_entry.mac_id, chain_mask, - nss, vdev_id, true, update_conn); + nss, vdev_id, true, update_conn, + conn_table_entry.ch_flagext); policy_mgr_debug("Add at idx:%d vdev %d mac=%d", conn_index, vdev_id, conn_table_entry.mac_id); @@ -1938,8 +1980,8 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[next_conn_index].mode; pm_conc_connection_list[conn_index].mac = pm_conc_connection_list[next_conn_index].mac; - pm_conc_connection_list[conn_index].chan = - pm_conc_connection_list[next_conn_index].chan; + pm_conc_connection_list[conn_index].freq = + pm_conc_connection_list[next_conn_index].freq; pm_conc_connection_list[conn_index].bw = pm_conc_connection_list[next_conn_index].bw; pm_conc_connection_list[conn_index].chain_mask = @@ -1948,6 +1990,8 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[next_conn_index].original_nss; pm_conc_connection_list[conn_index].in_use = pm_conc_connection_list[next_conn_index].in_use; + pm_conc_connection_list[conn_index].ch_flagext = + pm_conc_connection_list[next_conn_index].ch_flagext; conn_index++; next_conn_index++; } @@ -1998,7 +2042,7 @@ bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode, } bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, - uint8_t *ibss_channel) + uint32_t *ibss_ch_freq) { uint32_t count = 0, index = 0; uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; @@ -2010,7 +2054,7 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return status; } - if (!ibss_channel) { + if (!ibss_ch_freq) { policy_mgr_err("Null pointer error"); return false; } @@ -2021,10 +2065,10 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, /* No IBSS connection */ status = false; } else if (count == 1) { - *ibss_channel = pm_conc_connection_list[list[index]].chan; + *ibss_ch_freq = pm_conc_connection_list[list[index]].freq; status = true; } else { - *ibss_channel = pm_conc_connection_list[list[index]].chan; + *ibss_ch_freq = pm_conc_connection_list[list[index]].freq; policy_mgr_debug("Multiple IBSS connections, picking first one"); status = true; } @@ -2033,9 +2077,10 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, return status; } -uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, - uint8_t *channel, uint8_t *vdev_id, - enum policy_mgr_con_mode mode) +uint32_t policy_mgr_get_mode_specific_conn_info( + struct wlan_objmgr_psoc *psoc, + uint32_t *ch_freq_list, uint8_t *vdev_id, + enum policy_mgr_con_mode mode) { uint32_t count = 0, index = 0; @@ -2047,7 +2092,7 @@ uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return count; } - if (!channel || !vdev_id) { + if (!vdev_id) { policy_mgr_err("Null pointer error"); return count; } @@ -2056,13 +2101,16 @@ uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, psoc, mode, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (count == 1) { - *channel = pm_conc_connection_list[list[index]].chan; + if (ch_freq_list) + *ch_freq_list = + pm_conc_connection_list[list[index]].freq; *vdev_id = pm_conc_connection_list[list[index]].vdev_id; } else { for (index = 0; index < count; index++) { - channel[index] = - pm_conc_connection_list[list[index]].chan; + if (ch_freq_list) + ch_freq_list[index] = + pm_conc_connection_list[list[index]].freq; vdev_id[index] = pm_conc_connection_list[list[index]].vdev_id; @@ -2116,19 +2164,179 @@ static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc) static bool policy_mgr_check_privacy_for_new_conn( struct policy_mgr_psoc_priv_obj *pm_ctx) { - if (!pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist) + struct wlan_objmgr_pdev *pdev = pm_ctx->pdev; + + if (!pdev) { + policy_mgr_debug("pdev is Null"); + return true; + } + + if (mlme_is_wapi_sta_active(pdev) && + policy_mgr_get_connection_count(pm_ctx->psoc) > 0) + return false; + + return true; + +} + +#ifdef FEATURE_FOURTH_CONNECTION +static bool policy_mgr_is_concurrency_allowed_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t ch_freq, + struct policy_mgr_pcl_list pcl) +{ + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t sap_cnt, go_cnt; + + /* new STA may just have ssid, no channel until bssid assigned */ + if (ch_freq == 0 && mode == PM_STA_MODE) return true; - if (pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist() && - (policy_mgr_get_connection_count(pm_ctx->psoc) > 0)) + sap_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, NULL); + + go_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, NULL); + if (sap_cnt || go_cnt) { + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return false; + } + + if (policy_mgr_get_mcc_to_scc_switch_mode(psoc) != + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) { + policy_mgr_err("couldn't start 4th port for bad force scc cfg"); + return false; + } + if (pm_ctx->cfg.dual_mac_feature || + !pm_ctx->cfg.sta_sap_scc_on_dfs_chnl || + !pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl) { + policy_mgr_err( + "Couldn't start 4th port for bad cfg of dual mac, dfs scc, lte coex scc"); + return false; + } + + for (i = 0; i < pcl.pcl_len; i++) + if (ch_freq == pcl.pcl_list[i]) + return true; + + policy_mgr_err("4th port failed on ch freq %d with mode %d", + ch_freq, mode); + return false; + } + + return true; +} +#else +static inline bool policy_mgr_is_concurrency_allowed_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t ch_freq, + struct policy_mgr_pcl_list pcl) +{return false; } +#endif + +/** + * policy_mgr_allow_multiple_sta_connections() - check whether multiple STA + * concurrency is allowed and F/W supported + * @psoc: Pointer to soc + * @second_sta_freq: 2nd STA channel frequency + * @first_sta_freq: 1st STA channel frequency + * + * Return: true if supports else false. + */ +static bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, + uint32_t second_sta_freq, + uint32_t first_sta_freq) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + if (!wmi_service_enabled(wmi_handle, + wmi_service_sta_plus_sta_support)) + return false; + + return true; +} + +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +bool policy_mgr_is_6ghz_conc_mode_supported( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +{ + if (mode == PM_STA_MODE || mode == PM_SAP_MODE) + return true; + else + return false; +} +#endif + +/** + * policy_mgr_is_6g_channel_allowed() - Check new 6Ghz connection + * allowed or not + * @psoc: Pointer to soc + * @mode: new connection mode + * @ch_freq: channel freq + * + * 1. Only STA/SAP are allowed on 6Ghz. + * 2. If there is DFS beacon entity existing on 5G band, 5G+6G MCC is not + * allowed. + * + * Return: true if supports else false. + */ +static bool policy_mgr_is_6g_channel_allowed( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t ch_freq) +{ + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_conc_connection_info *conn; + bool is_dfs; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) + return true; + + /* Only STA/SAP is supported on 6Ghz currently */ + if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) + return false; + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn = &pm_conc_connection_list[conn_index]; + if (!conn->in_use) + continue; + is_dfs = (conn->ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) && + WLAN_REG_IS_5GHZ_CH_FREQ(conn->freq); + if ((conn->mode == PM_SAP_MODE || + conn->mode == PM_P2P_GO_MODE) && + is_dfs && ch_freq != conn->freq) { + policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel"); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return false; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return true; } bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel, + uint32_t ch_freq, enum hw_mode_bandwidth bw) { uint32_t num_connections = 0, count = 0, index = 0; @@ -2136,7 +2344,10 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; - uint8_t chan; + bool go_force_scc; + uint32_t sta_freq; + enum channel_state chan_state; + bool is_dfs_ch = false; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2158,10 +2369,16 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, goto done; } - if (channel) { + if (ch_freq) { + chan_state = wlan_reg_get_5g_bonded_channel_state_for_freq( + pm_ctx->pdev, ch_freq, + policy_mgr_get_ch_width(bw)); + if (chan_state == CHANNEL_STATE_DFS) + is_dfs_ch = true; /* don't allow 3rd home channel on same MAC */ - if (!policy_mgr_allow_new_home_channel(psoc, - channel, num_connections)) + if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq, + num_connections, + is_dfs_ch)) goto done; /* @@ -2173,26 +2390,42 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, * DFS channel then allow concurrency but make sure it is * going to DBS and send PCL to firmware indicating that * don't allow STA to roam to 5G channels. + * 4) On a single MAC device, if a SAP/P2PGO is already on a DFS + * channel, don't allow a 2 channel as it will result + * in MCC which is not allowed. */ if (!policy_mgr_is_5g_channel_allowed(psoc, - channel, list, PM_P2P_GO_MODE)) + ch_freq, list, PM_P2P_GO_MODE)) goto done; if (!policy_mgr_is_5g_channel_allowed(psoc, - channel, list, PM_SAP_MODE)) + ch_freq, list, PM_SAP_MODE)) + goto done; + if (!policy_mgr_is_6g_channel_allowed(psoc, mode, + ch_freq)) goto done; sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - - if (!sta_sap_scc_on_dfs_chan && ((mode == PM_P2P_GO_MODE) || - (mode == PM_SAP_MODE))) { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) - match = policy_mgr_disallow_mcc(psoc, channel); + go_force_scc = policy_mgr_go_scc_enforced(psoc); + if ((!sta_sap_scc_on_dfs_chan && mode == PM_SAP_MODE) || + (!go_force_scc && mode == PM_P2P_GO_MODE)) { + if (is_dfs_ch) + match = policy_mgr_disallow_mcc(psoc, + ch_freq); } if (true == match) { policy_mgr_rl_debug("No MCC, SAP/GO about to come up on DFS channel"); goto done; } + if ((policy_mgr_is_hw_dbs_capable(psoc) != true) && + num_connections) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { + if (policy_mgr_is_sap_p2pgo_on_dfs(psoc)) { + policy_mgr_rl_debug("MCC not allowed: SAP/P2PGO on DFS"); + goto done; + } + } + } } /* Check for STA+STA concurrency */ @@ -2203,9 +2436,9 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, policy_mgr_rl_debug("3rd STA isn't permitted"); goto done; } - chan = pm_conc_connection_list[list[0]].chan; - if (!policy_mgr_allow_multiple_sta_connections(psoc, channel, - chan)) + sta_freq = pm_conc_connection_list[list[0]].freq; + if (!policy_mgr_allow_multiple_sta_connections(psoc, ch_freq, + sta_freq)) goto done; } @@ -2222,7 +2455,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, goto done; } if ((PM_IBSS_MODE == mode) && - (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) && count) { + (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) && count) { policy_mgr_rl_debug("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); goto done; } @@ -2243,10 +2476,10 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, * band. If requirement changes then this condition * needs to be removed */ - if (channel && - (pm_conc_connection_list[0].chan != channel) && - WLAN_REG_IS_SAME_BAND_CHANNELS( - pm_conc_connection_list[0].chan, channel)) { + if (ch_freq && + pm_conc_connection_list[0].freq != ch_freq && + WLAN_REG_IS_SAME_BAND_FREQS( + pm_conc_connection_list[0].freq, ch_freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_rl_debug("No IBSS + STA MCC"); goto done; @@ -2274,10 +2507,10 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, goto done; } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - if (channel && - (wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[0].chan)) - && (WLAN_REG_IS_5GHZ_CH(channel))) { + if (ch_freq && + (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq))) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_rl_debug("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); goto done; @@ -2287,9 +2520,9 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, * band. If requirement changes then this condition * needs to be removed */ - if ((pm_conc_connection_list[0].chan != channel) && - WLAN_REG_IS_SAME_BAND_CHANNELS( - pm_conc_connection_list[0].chan, channel)) { + if (pm_conc_connection_list[0].freq != ch_freq && + WLAN_REG_IS_SAME_BAND_FREQS( + pm_conc_connection_list[0].freq, ch_freq)) { policy_mgr_rl_debug("No IBSS + STA MCC"); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); goto done; @@ -2301,21 +2534,21 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } } - if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel, + if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq, WLAN_INVALID_VDEV_ID)) { policy_mgr_rl_debug("This concurrency combination is not allowed"); goto done; } - /* don't allow two P2P GO on same band */ - if (channel && (mode == PM_P2P_GO_MODE) && num_connections) { + if (ch_freq && mode == PM_P2P_GO_MODE && num_connections) { index = 0; - count = policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_GO_MODE, list); + count = policy_mgr_mode_specific_connection_count( + psoc, PM_P2P_GO_MODE, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (index < count) { - if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, - pm_conc_connection_list[list[index]].chan)) { + if (WLAN_REG_IS_SAME_BAND_FREQS( + ch_freq, + pm_conc_connection_list[list[index]].freq)) { policy_mgr_rl_debug("Don't allow P2P GO on same band"); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); goto done; @@ -2338,10 +2571,12 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel, enum hw_mode_bandwidth bw) + uint32_t ch_freq, + enum hw_mode_bandwidth bw) { QDF_STATUS status; struct policy_mgr_pcl_list pcl; + bool allowed; qdf_mem_zero(&pcl, sizeof(pcl)); status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, @@ -2352,22 +2587,30 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, return false; } - return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw); + allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq, bw); + + /* Fourth connection concurrency check */ + if (allowed && policy_mgr_get_connection_count(psoc) == 3) + allowed = policy_mgr_is_concurrency_allowed_4_port( + psoc, + mode, + ch_freq, + pcl); + return allowed; } -bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t channel, - uint32_t vdev_id, - bool forced, - enum sap_csa_reason_code reason) +bool +policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t ch_freq, uint32_t vdev_id, + bool forced, enum sap_csa_reason_code reason) { bool allow = false; struct policy_mgr_conc_connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t num_cxn_del = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t old_chan; + uint32_t old_ch_freq; QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); @@ -2376,9 +2619,10 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, return allow; } policy_mgr_debug("check concurrency_csa vdev:%d ch %d, forced %d, reason %d", - vdev_id, channel, forced, reason); + vdev_id, ch_freq, forced, reason); - status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &old_chan); + status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, + &old_ch_freq); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Failed to get channel for vdev:%d", vdev_id); @@ -2407,16 +2651,13 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, if (forced && reason == CSA_REASON_UNSAFE_CHANNEL) policy_mgr_store_and_del_conn_info_by_chan_and_mode( - psoc, old_chan, mode, info, &num_cxn_del); + psoc, old_ch_freq, mode, info, &num_cxn_del); else policy_mgr_store_and_del_conn_info_by_vdev_id( psoc, vdev_id, info, &num_cxn_del); - allow = policy_mgr_allow_concurrency( - psoc, - mode, - channel, - HW_MODE_20_MHZ); + allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq, + HW_MODE_20_MHZ); /* Restore the connection entry */ if (num_cxn_del > 0) policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); @@ -2465,7 +2706,7 @@ uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc) */ QDF_STATUS policy_mgr_get_channel_from_scan_result( struct wlan_objmgr_psoc *psoc, - void *roam_profile, uint8_t *channel) + void *roam_profile, uint32_t *ch_freq) { QDF_STATUS status = QDF_STATUS_E_FAILURE; void *scan_cache = NULL; @@ -2477,14 +2718,14 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( return QDF_STATUS_E_INVAL; } - if (!roam_profile || !channel) { + if (!roam_profile || !ch_freq) { policy_mgr_err("Invalid input parameters"); return QDF_STATUS_E_INVAL; } if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan) { status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan - (roam_profile, &scan_cache, channel); + (roam_profile, &scan_cache, ch_freq); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Get AP channel failed"); return status; @@ -2528,12 +2769,12 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -uint8_t policy_mgr_search_and_check_for_session_conc( +uint32_t policy_mgr_search_and_check_for_session_conc( struct wlan_objmgr_psoc *psoc, uint8_t session_id, void *roam_profile) { - uint8_t channel = 0; + uint32_t ch_freq = 0; QDF_STATUS status; enum policy_mgr_con_mode mode; bool ret; @@ -2542,7 +2783,7 @@ uint8_t policy_mgr_search_and_check_for_session_conc( pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - return channel; + return ch_freq; } if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) { @@ -2550,27 +2791,28 @@ uint8_t policy_mgr_search_and_check_for_session_conc( psoc, session_id); if (PM_MAX_NUM_OF_MODE == mode) { policy_mgr_err("Invalid mode"); - return channel; + return ch_freq; } } else - return channel; + return ch_freq; - status = policy_mgr_get_channel_from_scan_result(psoc, - roam_profile, &channel); - if ((QDF_STATUS_SUCCESS != status) || (channel == 0)) { + status = policy_mgr_get_channel_from_scan_result( + psoc, roam_profile, &ch_freq); + if (QDF_STATUS_SUCCESS != status || ch_freq == 0) { policy_mgr_err("%s error %d %d", - __func__, status, channel); + __func__, status, ch_freq); return 0; } /* Take care of 160MHz and 80+80Mhz later */ - ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ); + ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, + HW_MODE_20_MHZ); if (false == ret) { policy_mgr_err("Connection failed due to conc check fail"); return 0; } - return channel; + return ch_freq; } /** @@ -2583,14 +2825,14 @@ uint8_t policy_mgr_search_and_check_for_session_conc( */ static bool policy_mgr_is_two_connection_mcc(void) { - return ((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) && + return ((pm_conc_connection_list[0].freq != + pm_conc_connection_list[1].freq) && (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) && - (pm_conc_connection_list[0].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[1].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false; + (pm_conc_connection_list[0].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ) && + (pm_conc_connection_list[1].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false; } /** @@ -2603,18 +2845,18 @@ static bool policy_mgr_is_two_connection_mcc(void) */ static bool policy_mgr_is_three_connection_mcc(void) { - return (((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) || - (pm_conc_connection_list[0].chan != - pm_conc_connection_list[2].chan) || - (pm_conc_connection_list[1].chan != - pm_conc_connection_list[2].chan)) && - (pm_conc_connection_list[0].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[1].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[2].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false; + return (((pm_conc_connection_list[0].freq != + pm_conc_connection_list[1].freq) || + (pm_conc_connection_list[0].freq != + pm_conc_connection_list[2].freq) || + (pm_conc_connection_list[1].freq != + pm_conc_connection_list[2].freq)) && + (pm_conc_connection_list[0].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ) && + (pm_conc_connection_list[1].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ) && + (pm_conc_connection_list[2].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false; } bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) @@ -2645,7 +2887,7 @@ bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) } bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, - uint8_t session_id, uint8_t channel) + uint8_t session_id, uint32_t ch_freq) { enum policy_mgr_con_mode mode; bool ret; @@ -2667,13 +2909,13 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, } else return false; - if (channel == 0) { + if (ch_freq == 0) { policy_mgr_err("Invalid channel number 0"); return false; } /* Take care of 160MHz and 80+80Mhz later */ - ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ); + ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ); if (false == ret) { policy_mgr_err("Connection failed due to conc check fail"); return 0; @@ -2908,6 +3150,43 @@ bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc) psoc, PM_STA_MODE, NULL) > 1; } +bool policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc, + uint8_t *vdev_id, + qdf_freq_t *ch_freq, + enum hw_mode_bandwidth *ch_width) +{ + struct policy_mgr_conc_connection_info *conn_info; + bool status = false; + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && + (conn_info->mode == PM_STA_MODE || + conn_info->mode == PM_P2P_CLIENT_MODE) && + (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) || + (wlan_reg_is_5ghz_ch_freq(conn_info->freq) && + conn_info->bw == HW_MODE_160_MHZ))) { + *vdev_id = conn_info->vdev_id; + *ch_freq = pm_conc_connection_list[conn_index].freq; + *ch_width = conn_info->bw; + status = true; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; +} + /** * policy_mgr_is_sta_active_connection_exists() - Check if a STA * connection is active @@ -2925,7 +3204,7 @@ bool policy_mgr_is_sta_active_connection_exists( } bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, - uint8_t *channel) + uint32_t *ch_freq) { bool status = false; uint32_t conn_index = 0; @@ -2940,9 +3219,9 @@ bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (pm_conc_connection_list[conn_index].in_use && - !wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[conn_index].chan)) { - *channel = pm_conc_connection_list[conn_index].chan; + !wlan_reg_is_dfs_for_freq(pm_ctx->pdev, + pm_conc_connection_list[conn_index].freq)) { + *ch_freq = pm_conc_connection_list[conn_index].freq; status = true; } } @@ -2969,8 +3248,8 @@ uint32_t policy_mgr_get_dfs_beaconing_session_id( conn_index++) { conn_info = &pm_conc_connection_list[conn_index]; if (conn_info->in_use && - wlan_reg_chan_has_dfs_attribute(pm_ctx->pdev, - conn_info->chan) && + wlan_reg_chan_has_dfs_attribute_for_freq( + pm_ctx->pdev, conn_info->freq) && (conn_info->mode == PM_SAP_MODE || conn_info->mode == PM_P2P_GO_MODE)) { session_id = @@ -2984,7 +3263,7 @@ uint32_t policy_mgr_get_dfs_beaconing_session_id( } bool policy_mgr_is_any_dfs_beaconing_session_present( - struct wlan_objmgr_psoc *psoc, uint8_t *channel) + struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq) { struct policy_mgr_conc_connection_info *conn_info; bool status = false; @@ -3001,10 +3280,10 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( conn_index++) { conn_info = &pm_conc_connection_list[conn_index]; if (conn_info->in_use && - wlan_reg_is_dfs_ch(pm_ctx->pdev, conn_info->chan) && + wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) && (PM_SAP_MODE == conn_info->mode || PM_P2P_GO_MODE == conn_info->mode)) { - *channel = pm_conc_connection_list[conn_index].chan; + *ch_freq = pm_conc_connection_list[conn_index].freq; status = true; } } @@ -3016,7 +3295,7 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; - uint8_t ap_dfs_channel = 0; + uint32_t ap_dfs_ch_freq = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -3024,9 +3303,8 @@ bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc) return false; } - policy_mgr_is_any_dfs_beaconing_session_present( - psoc, &ap_dfs_channel); - if (!ap_dfs_channel) + policy_mgr_is_any_dfs_beaconing_session_present(psoc, &ap_dfs_ch_freq); + if (!ap_dfs_ch_freq) return false; /* * 1) if agile & DFS scans are supportet @@ -3042,7 +3320,7 @@ bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc) return false; policy_mgr_debug("scan skip 5g chan due to dfs ap(ch %d) present", - ap_dfs_channel); + ap_dfs_ch_freq); return true; } @@ -3088,15 +3366,16 @@ void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc) qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { - policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d", - i, pm_conc_connection_list[i].in_use, - pm_conc_connection_list[i].vdev_id, - pm_conc_connection_list[i].mode, - pm_conc_connection_list[i].mac, - pm_conc_connection_list[i].chan, - pm_conc_connection_list[i].chain_mask, - pm_conc_connection_list[i].original_nss, - pm_conc_connection_list[i].bw); + policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d freq:%d orig chainmask:%d orig nss:%d bw:%d, ch_flags %0X", + i, pm_conc_connection_list[i].in_use, + pm_conc_connection_list[i].vdev_id, + pm_conc_connection_list[i].mode, + pm_conc_connection_list[i].mac, + pm_conc_connection_list[i].freq, + pm_conc_connection_list[i].chain_mask, + pm_conc_connection_list[i].original_nss, + pm_conc_connection_list[i].bw, + pm_conc_connection_list[i].ch_flagext); } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } @@ -3123,8 +3402,8 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( case POLICY_MGR_BAND_24: if ((pm_conc_connection_list[i].vdev_id != session_id) && (pm_conc_connection_list[i].in_use) && - (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[i].chan))) { + (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[i].freq))) { status = true; goto release_mutex_and_send_status; } @@ -3132,8 +3411,8 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( case POLICY_MGR_BAND_5: if ((pm_conc_connection_list[i].vdev_id != session_id) && (pm_conc_connection_list[i].in_use) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[i].chan))) { + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[i].freq))) { status = true; goto release_mutex_and_send_status; } @@ -3151,7 +3430,8 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( } QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, - uint8_t session_id, uint8_t *chan) + uint8_t session_id, + uint32_t *ch_freq) { uint32_t i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -3166,7 +3446,7 @@ QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if ((pm_conc_connection_list[i].vdev_id == session_id) && (pm_conc_connection_list[i].in_use)) { - *chan = pm_conc_connection_list[i].chan; + *ch_freq = pm_conc_connection_list[i].freq; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; } @@ -3177,7 +3457,8 @@ QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, } QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, - uint8_t session_id, uint8_t *mac_id) + uint8_t session_id, + uint8_t *mac_id) { uint32_t i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -3206,9 +3487,8 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, uint8_t mac_id, uint8_t session_id, uint8_t *mcc_session_id) { - uint32_t i; + uint32_t i, ch_freq; QDF_STATUS status; - uint8_t chan; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -3217,7 +3497,7 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - status = policy_mgr_get_chan_by_session_id(psoc, session_id, &chan); + status = policy_mgr_get_chan_by_session_id(psoc, session_id, &ch_freq); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Failed to get channel for session id:%d", session_id); @@ -3231,8 +3511,8 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, if (pm_conc_connection_list[i].vdev_id == session_id) continue; /* Inter band or intra band MCC */ - if ((pm_conc_connection_list[i].chan != chan) && - (pm_conc_connection_list[i].in_use)) { + if (pm_conc_connection_list[i].freq != ch_freq && + pm_conc_connection_list[i].in_use) { *mcc_session_id = pm_conc_connection_list[i].vdev_id; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; @@ -3243,12 +3523,12 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } -uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, - uint8_t session_id) +uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, + uint8_t session_id) { uint8_t mac_id, mcc_session_id; QDF_STATUS status; - uint8_t chan; + uint32_t ch_freq; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -3271,50 +3551,14 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, } status = policy_mgr_get_chan_by_session_id(psoc, mcc_session_id, - &chan); + &ch_freq); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Failed to get channel for MCC session ID:%d", mcc_session_id); return INVALID_CHANNEL_ID; } - return chan; -} - -void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc, - bool flag) -{ - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return; - } - - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - pm_ctx->do_hw_mode_change = flag; - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - - policy_mgr_debug("hw_mode_change_channel:%d", flag); -} - -bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) -{ - bool flag; - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return INVALID_CHANNEL_ID; - } - - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - flag = pm_ctx->do_hw_mode_change; - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - - return flag; + return ch_freq; } bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) @@ -3335,10 +3579,10 @@ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) } QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, - uint8_t channel, bool *ok) + uint32_t ch_freq, bool *ok) { uint32_t cc_count = 0, i; - uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct wlan_objmgr_vdev *vdev; @@ -3347,23 +3591,22 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - cc_count = policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], - PM_SAP_MODE); + cc_count = policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_SAP_MODE); if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) - cc_count = cc_count + policy_mgr_get_mode_specific_conn_info( - psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], - PM_P2P_GO_MODE); + cc_count = cc_count + + policy_mgr_get_mode_specific_conn_info( + psoc, &op_ch_freq_list[cc_count], + &vdev_id[cc_count], PM_P2P_GO_MODE); + if (!cc_count) { *ok = true; return QDF_STATUS_SUCCESS; } - if (!channel) { + if (!ch_freq) { policy_mgr_err("channel is 0, cc count %d", cc_count); return QDF_STATUS_E_INVAL; } @@ -3371,9 +3614,7 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) { for (i = 0; i < cc_count; i++) { vdev = wlan_objmgr_get_vdev_by_id_from_psoc( - psoc, - vdev_id[i], - WLAN_POLICY_MGR_ID); + psoc, vdev_id[i], WLAN_POLICY_MGR_ID); if (!vdev) { policy_mgr_err("vdev for vdev_id:%d is NULL", vdev_id[i]); @@ -3395,14 +3636,14 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, */ /* TODO: To be enhanced for SBS */ if (policy_mgr_is_dnsc_set(vdev)) { - if (operating_channel[i] == channel) { + if (op_ch_freq_list[i] == ch_freq) { *ok = true; wlan_objmgr_vdev_release_ref( vdev, WLAN_POLICY_MGR_ID); break; - } else if (WLAN_REG_IS_SAME_BAND_CHANNELS( - operating_channel[i], channel)) { + } else if (WLAN_REG_IS_SAME_BAND_FREQS( + op_ch_freq_list[i], ch_freq)) { *ok = false; wlan_objmgr_vdev_release_ref( vdev, @@ -3632,8 +3873,7 @@ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( return status; } -bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode) +bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t conn_index; @@ -3647,8 +3887,9 @@ bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { - if (pm_conc_connection_list[conn_index].mode == mode && - pm_conc_connection_list[conn_index].chan >= 36 && + if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && + pm_conc_connection_list[conn_index].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ && pm_conc_connection_list[conn_index].in_use) ret = true; } @@ -3657,7 +3898,8 @@ bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc, return ret; } -bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) +bool +policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc, qdf_freq_t *freq) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t conn_index; @@ -3668,48 +3910,23 @@ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) policy_mgr_err("Invalid Context"); return ret; } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { + *freq = pm_conc_connection_list[conn_index].freq; if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && - pm_conc_connection_list[conn_index].chan <= 14 && - pm_conc_connection_list[conn_index].in_use) + WLAN_REG_IS_5GHZ_CH_FREQ(*freq) && + pm_conc_connection_list[conn_index].in_use) { ret = true; + break; + } } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return ret; } -void policy_mgr_trim_acs_channel_list(uint8_t *pcl, uint8_t pcl_count, - uint8_t *org_ch_list, - uint8_t *org_ch_list_count) -{ - uint16_t i, j, ch_list_count = 0; - - if (*org_ch_list_count >= QDF_MAX_NUM_CHAN) { - policy_mgr_err("org_ch_list_count too big %d", - *org_ch_list_count); - return; - } - - if (pcl_count >= QDF_MAX_NUM_CHAN) { - policy_mgr_err("pcl_count is too big %d", - pcl_count); - return; - } - - policy_mgr_debug("Update ACS channels with PCL"); - for (j = 0; j < *org_ch_list_count; j++) - for (i = 0; i < pcl_count; i++) - if (pcl[i] == org_ch_list[j]) { - org_ch_list[ch_list_count++] = pcl[i]; - break; - } - - *org_ch_list_count = ch_list_count; -} - uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, struct connection_info *info) { @@ -3721,7 +3938,7 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return count; } - + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { @@ -3729,24 +3946,27 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[conn_index].vdev_id; info[count].mac_id = pm_conc_connection_list[conn_index].mac; - info[count].channel = - pm_conc_connection_list[conn_index].chan; + info[count].channel = wlan_reg_freq_to_chan( + pm_ctx->pdev, + pm_conc_connection_list[conn_index].freq); + info[count].ch_freq = + pm_conc_connection_list[conn_index].freq; count++; } } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return count; } bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel, + uint32_t ch_freq, uint32_t vdev_id) { enum policy_mgr_con_mode con_mode; - uint8_t con_chan; int id; - uint32_t vdev; + uint32_t vdev, con_freq; bool dbs; if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE) @@ -3763,9 +3983,9 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, con_mode = pm_conc_connection_list[id].mode; if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE) continue; - con_chan = pm_conc_connection_list[id].chan; + con_freq = pm_conc_connection_list[id].freq; if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) && - (channel == con_chan)) { + (ch_freq == con_freq)) { policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP"); return true; } @@ -3773,7 +3993,7 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("DBS unsupported, mcc and scc unsupported too, don't allow 2nd AP"); return false; } - if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, con_chan)) { + if (WLAN_REG_IS_SAME_BAND_FREQS(ch_freq, con_freq)) { policy_mgr_debug("DBS supported, 2 SAP on same band, reject 2nd AP"); return false; } @@ -3783,24 +4003,6 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, return true; } -bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc, - uint8_t second_sta_chan, - uint8_t first_sta_chan) -{ - struct wmi_unified *wmi_handle; - - wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); - if (!wmi_handle) { - policy_mgr_debug("Invalid WMI handle"); - return false; - } - if (!wmi_service_enabled(wmi_handle, - wmi_service_sta_plus_sta_support)) - return false; - - return true; -} - bool policy_mgr_dual_beacon_on_single_mac_scc_capable( struct wlan_objmgr_psoc *psoc) { @@ -3859,8 +4061,127 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( return scc_lte_coex; } +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + conn_info->conn_6ghz_flag = ap_6ghz_capable; + conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("vdev %d init conn_6ghz_flag %x new %x", + vdev_id, ap_6ghz_capable, conn_6ghz_flag); +} + +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + if (set) + conn_info->conn_6ghz_flag |= ap_6ghz_capable; + else + conn_info->conn_6ghz_flag &= ~ap_6ghz_capable; + conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("vdev %d %s conn_6ghz_flag %x new %x", + vdev_id, set ? "set" : "clr", + ap_6ghz_capable, conn_6ghz_flag); +} + +bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint32_t *conn_flag) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + bool is_6g_allowed = false; + + if (conn_flag) + *conn_flag = 0; + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + /* If the vdev connection is not active, policy mgr will query legacy + * hdd to get sap acs and security information. + * The assumption is no legacy client connected for non active + * connection. + */ + if (!(conn_6ghz_flag & CONN_6GHZ_FLAG_VALID) && + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable) + conn_6ghz_flag = pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable( + psoc, vdev_id) | + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT; + + if ((conn_6ghz_flag & CONN_6GHZ_CAPABLIE) == CONN_6GHZ_CAPABLIE) + is_6g_allowed = true; + policy_mgr_debug("vdev %d conn_6ghz_flag %x 6ghz %s", vdev_id, + conn_6ghz_flag, is_6g_allowed ? "allowed" : "deny"); + if (conn_flag) + *conn_flag = conn_6ghz_flag; + + return is_6g_allowed; +} +#endif + bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, - uint8_t channel) + uint32_t ch_freq) { uint32_t sta_sap_scc_on_dfs_chan; uint32_t sap_count; @@ -3878,10 +4199,10 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, sap_count = policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL); - state = wlan_reg_get_channel_state(pm_ctx->pdev, channel); + state = wlan_reg_get_channel_state_for_freq(pm_ctx->pdev, ch_freq); - policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u", - sta_sap_scc_on_dfs_chan, sap_count, channel, state); + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, ch freq %u, state %u", + sta_sap_scc_on_dfs_chan, sap_count, ch_freq, state); if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) || ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan)) { @@ -3893,7 +4214,8 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, return false; } -bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch) +bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, + uint32_t sap_freq) { uint32_t conn_index; bool is_scc = false; @@ -3915,9 +4237,9 @@ bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch) for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (pm_conc_connection_list[conn_index].in_use && - (pm_conc_connection_list[conn_index].mode == - PM_STA_MODE) && - (sap_ch == pm_conc_connection_list[conn_index].chan)) { + (pm_conc_connection_list[conn_index].mode == + PM_STA_MODE) && (sap_freq == + pm_conc_connection_list[conn_index].freq)) { is_scc = true; break; } @@ -3927,6 +4249,27 @@ bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch) return is_scc; } +bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc) +{ + uint32_t mcc_to_scc_switch; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc); + if (mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) + return true; + + if (pm_ctx->cfg.go_force_scc && policy_mgr_is_force_scc(psoc)) + return true; + + return false; +} + QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, uint8_t nan_vdev_id, uint8_t mac_id) @@ -3947,6 +4290,33 @@ QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc, return status; } +bool policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_index; + bool ret = false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return ret; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == PM_SAP_MODE || + pm_conc_connection_list[conn_index].mode == PM_P2P_GO_MODE) && + pm_conc_connection_list[conn_index].freq <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ && + pm_conc_connection_list[conn_index].in_use) + ret = true; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return ret; +} + bool policy_mgr_get_5g_scc_prefer( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 469fa8fe7cb763e651671d9284534352481a6332..07f28f25cf00b750fe8ca3a7e6aec85d8d09ef89 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -25,6 +25,7 @@ #include "qdf_lock.h" #include "qdf_defer.h" #include "wlan_reg_services_api.h" +#include "cds_ieee80211_common_i.h" #define DBS_OPPORTUNISTIC_TIME 5 @@ -36,8 +37,8 @@ #define CONNECTION_UPDATE_TIMEOUT (POLICY_MGR_SER_CMD_TIMEOUT + 2000) #endif -#define PM_24_GHZ_CHANNEL_6 (6) -#define PM_5_GHZ_CHANNEL_36 (36) +#define PM_24_GHZ_CH_FREQ_6 (2437) +#define PM_5_GHZ_CH_FREQ_36 (5180) #define CHANNEL_SWITCH_COMPLETE_TIMEOUT (2000) /** @@ -202,6 +203,14 @@ extern policy_mgr_next_action_two_connection_table_type *next_action_two_connection_table; extern policy_mgr_next_action_three_connection_table_type *next_action_three_connection_table; + +#ifdef FEATURE_FOURTH_CONNECTION +extern const enum policy_mgr_pcl_type + fourth_connection_pcl_dbs_table + [PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE]; +#endif + extern policy_mgr_next_action_two_connection_table_type *next_action_two_connection_2x2_2g_1x1_5g_table; extern policy_mgr_next_action_three_connection_table_type @@ -241,8 +250,9 @@ struct sta_ap_intf_check_work_ctx { * @chnl_select_plcy: Channel selection policy * @enable_mcc_adaptive_sch: Enable/Disable MCC adaptive scheduler * @enable_sta_cxn_5g_band: Enable/Disable STA connection in 5G band - * @prefer_5g_scc_to_dbs: Prefer to work in 5G SCC mode. * @go_force_scc: Enable/Disable P2P GO force SCC + * @pcl_band_priority: PCL channel order between 5G and 6G. + * @prefer_5g_scc_to_dbs: Prefer to work in 5G SCC mode. */ struct policy_mgr_cfg { uint8_t mcc_to_scc_switch; @@ -264,8 +274,9 @@ struct policy_mgr_cfg { uint32_t dbs_selection_plcy; uint32_t vdev_priority_list; uint32_t chnl_select_plcy; - uint32_t prefer_5g_scc_to_dbs; uint8_t go_force_scc; + enum policy_mgr_pcl_band_priority pcl_band_priority; + uint32_t prefer_5g_scc_to_dbs; }; /** @@ -289,14 +300,11 @@ struct policy_mgr_cfg { * interaction with Policy Manager * @sap_mandatory_channels: The user preferred master list on * which SAP can be brought up. This - * mandatory channel list would be as per + * mandatory channel freq list would be as per * OEMs preference & conforming to the * regulatory/other considerations * @sap_mandatory_channels_len: Length of the SAP mandatory * channel list - * @do_hw_mode_change: Flag to check if HW mode change is needed - * after vdev is up. Especially used after - * channel switch related vdev restart * @concurrency_mode: active concurrency combination * @no_of_open_sessions: Number of active vdevs * @no_of_active_sessions: Number of active connections @@ -311,12 +319,16 @@ struct policy_mgr_cfg { * change is in progress * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler * value from INI - * @unsafe_channel_list: LTE coex channel avoidance list + * @unsafe_channel_list: LTE coex channel freq avoidance list * @unsafe_channel_count: LTE coex channel avoidance list count * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work * @nan_sap_conc_work: Info related to nan sap conc work * @opportunistic_update_done_evt: qdf event to synchronize host * & FW HW mode + * @channel_switch_complete_evt: qdf event for channel switch completion check + * @mode_change_cb: Mode change callback + * @user_config_sap_ch_freq: SAP channel freq configured by user application + * @cfg: Policy manager config data * @dynamic_mcc_adaptive_sched: disable/enable mcc adaptive scheduler feature */ struct policy_mgr_psoc_priv_obj { @@ -331,9 +343,9 @@ struct policy_mgr_psoc_priv_obj { struct policy_mgr_tdls_cbacks tdls_cbacks; struct policy_mgr_cdp_cbacks cdp_cbacks; struct policy_mgr_dp_cbacks dp_cbacks; - uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; + uint32_t sap_mandatory_channels[NUM_CHANNELS]; uint32_t sap_mandatory_channels_len; - bool do_hw_mode_change; + bool do_sap_unsafe_ch_check; uint32_t concurrency_mode; uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; @@ -346,15 +358,17 @@ struct policy_mgr_psoc_priv_obj { struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; struct policy_mgr_user_cfg user_cfg; - uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; + uint32_t unsafe_channel_list[NUM_CHANNELS]; uint16_t unsafe_channel_count; struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; uint8_t cur_conc_system_pref; qdf_event_t opportunistic_update_done_evt; qdf_event_t channel_switch_complete_evt; send_mode_change_event_cb mode_change_cb; - uint32_t user_config_sap_channel; + uint32_t user_config_sap_ch_freq; struct policy_mgr_cfg cfg; + uint32_t valid_ch_freq_list[NUM_CHANNELS]; + uint32_t valid_ch_freq_list_count; bool dynamic_mcc_adaptive_sched; }; @@ -439,17 +453,38 @@ QDF_STATUS policy_mgr_get_old_and_new_hw_index( struct wlan_objmgr_psoc *psoc, uint32_t *old_hw_mode_index, uint32_t *new_hw_mode_index); + +/** + * policy_mgr_update_conc_list() - Update the concurrent connection list + * @conn_index: Connection index + * @mode: Mode + * @ch_freq: channel frequency + * @bw: Bandwidth + * @mac: Mac id + * @chain_mask: Chain mask + * @vdev_id: vdev id + * @in_use: Flag to indicate if the index is in use or not + * @update_conn: Flag to indicate if mode change event should + * be sent or not + * @ch_flagext: channel state flags + * + * Updates the index value of the concurrent connection list + * + * Return: None + */ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, uint32_t conn_index, enum policy_mgr_con_mode mode, - uint8_t chan, + uint32_t freq, enum hw_mode_bandwidth bw, uint8_t mac, enum policy_mgr_chain_mode chain_mask, uint32_t original_nss, uint32_t vdev_id, bool in_use, - bool update_conn); + bool update_conn, + uint16_t ch_flagext); + void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del, @@ -480,7 +515,7 @@ void policy_mgr_store_and_del_conn_info_by_vdev_id( * policy_mgr_store_and_del_conn_info_by_chan_and_mode() - Store and del a * connection info by chan number and conn mode * @psoc: PSOC object information - * @chan: channel number + * @ch_freq: channel frequency value * @mode: conn mode * @info: structure array pointer where the connection info will be saved * @num_cxn_del: number of connection which are going to be deleted @@ -492,7 +527,7 @@ void policy_mgr_store_and_del_conn_info_by_vdev_id( */ void policy_mgr_store_and_del_conn_info_by_chan_and_mode( struct wlan_objmgr_psoc *psoc, - uint32_t chan, + uint32_t ch_freq, enum policy_mgr_con_mode mode, struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del); @@ -541,14 +576,47 @@ enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw); QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_pcl_type pcl, - uint8_t *pcl_channels, uint32_t *len, + uint32_t *pcl_channels, uint32_t *len, enum policy_mgr_con_mode mode, uint8_t *pcl_weights, uint32_t weight_len); -bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, - uint8_t channel, uint32_t num_connections); + +/** + * policy_mgr_allow_new_home_channel() - Check for allowed number of + * home channels + * @psoc: PSOC Pointer + * @mode: Connection mode + * @ch_freq: channel frequency on which new connection is coming up + * @num_connections: number of current connections + * @is_dfs_ch: DFS channel or not + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * allowed or not based on the HW capability + * + * Return: True/False + */ +bool policy_mgr_allow_new_home_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t ch_freq, uint32_t num_connections, bool is_dfs_ch); + +/** + * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed + * @ch_freq: channel frequency which needs to be validated + * @list: list of existing connections. + * @mode: mode against which channel needs to be validated + * + * This API takes the channel frequency as input and compares with existing + * connection channels. If existing connection's channel is DFS channel + * and provided channel is 5G channel then don't allow concurrency to + * happen as MCC with DFS channel is not yet supported + * + * Return: true if 5G channel is allowed, false if not allowed + * + */ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, - uint8_t channel, uint32_t *list, + uint32_t ch_freq, uint32_t *list, enum policy_mgr_con_mode mode); + QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, enum policy_mgr_conn_update_reason reason, @@ -625,7 +693,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, * concurrency combination * @psoc: PSOC object information * @mode: new connection mode - * @channel: channel on which new connection is coming up + * @ch_freq: channel frequency on which new connection is coming up * @bw: Bandwidth requested by the connection (optional) * * When a new connection is about to come up check if current @@ -637,6 +705,6 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, */ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel, + uint32_t ch_freq, enum hw_mode_bandwidth bw); #endif diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c index 06b168100bb70e929b0f79f23cdb0ae91b84db4a..585067da092cec1f5068e7d9f2707ebb9e2bd628 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -453,7 +454,6 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) } policy_mgr_get_mcc_adaptive_sch(psoc, &enable_mcc_adaptive_sch); policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable_mcc_adaptive_sch); - pm_ctx->do_hw_mode_change = false; pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; /* reset sap mandatory channels */ status = policy_mgr_reset_sap_mandatory_channels(pm_ctx); @@ -614,8 +614,6 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, pm_ctx->sme_cbacks.sme_get_nss_for_vdev = sme_cbacks->sme_get_nss_for_vdev; - pm_ctx->sme_cbacks.sme_get_valid_channels = - sme_cbacks->sme_get_valid_channels; pm_ctx->sme_cbacks.sme_nss_update_request = sme_cbacks->sme_nss_update_request; pm_ctx->sme_cbacks.sme_pdev_set_hw_mode = @@ -664,10 +662,12 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, hdd_cbacks->get_mode_for_non_connected_vdev; pm_ctx->hdd_cbacks.hdd_get_device_mode = hdd_cbacks->hdd_get_device_mode; - pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist = - hdd_cbacks->hdd_wapi_security_sta_exist; pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = hdd_cbacks->hdd_is_chan_switch_in_progress; + pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = + hdd_cbacks->hdd_is_cac_in_progress; + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = + hdd_cbacks->hdd_get_ap_6ghz_capable; pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = hdd_cbacks->wlan_hdd_indicate_active_ndp_cnt; @@ -688,6 +688,9 @@ QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL; pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL; pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL; + pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL; + pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL; + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL; return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index 41c1332a237f41d3b109bfacbcf59fc8d2f85116..b3f3e772cd392155c0df95266be33ed1b3d5721c 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,9 +65,10 @@ policy_mgr_next_action_two_connection_table_type policy_mgr_next_action_three_connection_table_type *next_action_three_connection_2x2_2g_1x1_5g_table; -QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_get_pcl_for_existing_conn( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t *pcl_ch, uint32_t *len, + uint32_t *pcl_ch, uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len, bool all_matching_cxn_to_del) { @@ -83,7 +85,7 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - + *len = 0; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ @@ -91,7 +93,7 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, all_matching_cxn_to_del, info, &num_cxn_del); /* Get the PCL */ status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, - pcl_weight, weight_len); + pcl_weight, weight_len); policy_mgr_debug("Get PCL to FW for mode:%d", mode); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); @@ -140,13 +142,46 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, return; } -void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_pdev *pdev, - struct regulatory_channel *chan_list, - struct avoid_freq_ind_data *avoid_freq_ind, - void *arg) +/** + * policy_mgr_update_valid_ch_freq_list() - Update policy manager valid ch list + * @pm_ctx: policy manager context data + * @ch_list: Regulatory channel list + * + * When regulatory component channel list is updated this internal function is + * called to update policy manager copy of valid channel list. + * + * Return: QDF_STATUS_SUCCESS on success other qdf error status code + */ +static void +policy_mgr_update_valid_ch_freq_list(struct policy_mgr_psoc_priv_obj *pm_ctx, + struct regulatory_channel *reg_ch_list) +{ + uint32_t i, j = 0, ch; + enum channel_state state; + + for (i = 0; i < NUM_CHANNELS; i++) { + ch = reg_ch_list[i].chan_num; + state = wlan_reg_get_channel_state(pm_ctx->pdev, ch); + + if (state != CHANNEL_STATE_DISABLE && + state != CHANNEL_STATE_INVALID) { + pm_ctx->valid_ch_freq_list[j] = + reg_ch_list[i].center_freq; + j++; + } + } + pm_ctx->valid_ch_freq_list_count = j; +} + +void +policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, + struct regulatory_channel *chan_list, + struct avoid_freq_ind_data *avoid_freq_ind, + void *arg) { struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t i; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -154,6 +189,8 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, return; } + policy_mgr_update_valid_ch_freq_list(pm_ctx, chan_list); + if (!avoid_freq_ind) { policy_mgr_debug("avoid_freq_ind NULL"); return; @@ -164,20 +201,20 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, * NUM_CHANNELS and hence the ch_cnt should also not * exceed NUM_CHANNELS. */ - pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >= + pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.chan_cnt >= NUM_CHANNELS ? - NUM_CHANNELS : avoid_freq_ind->chan_list.ch_cnt; - if (pm_ctx->unsafe_channel_count) - qdf_mem_copy(pm_ctx->unsafe_channel_list, - avoid_freq_ind->chan_list.ch_list, - pm_ctx->unsafe_channel_count * - sizeof(pm_ctx->unsafe_channel_list[0])); + NUM_CHANNELS : avoid_freq_ind->chan_list.chan_cnt; + + for (i = 0; i < pm_ctx->unsafe_channel_count; i++) + pm_ctx->unsafe_channel_list[i] = + avoid_freq_ind->chan_list.chan_freq_list[i]; + policy_mgr_debug("Channel list update, received %d avoided channels", - pm_ctx->unsafe_channel_count); + pm_ctx->unsafe_channel_count); } QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, - uint16_t *chan_list, + qdf_freq_t *chan_freq_list, uint16_t chan_cnt) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -193,7 +230,7 @@ QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, NUM_CHANNELS : chan_cnt; for (i = 0; i < pm_ctx->unsafe_channel_count; i++) - pm_ctx->unsafe_channel_list[i] = chan_list[i]; + pm_ctx->unsafe_channel_list[i] = chan_freq_list[i]; policy_mgr_debug("Channel list init, received %d avoided channels", pm_ctx->unsafe_channel_count); @@ -202,11 +239,13 @@ QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, } void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_channels, uint32_t *len, - uint8_t *weight_list, uint32_t weight_len) + uint32_t *pcl_channels, + uint32_t *len, + uint8_t *weight_list, + uint32_t weight_len) { - uint8_t current_channel_list[QDF_MAX_NUM_CHAN]; - uint8_t org_weight_list[QDF_MAX_NUM_CHAN]; + uint32_t current_channel_list[NUM_CHANNELS]; + uint8_t org_weight_list[NUM_CHANNELS]; uint8_t is_unsafe = 1; uint8_t i, j; uint32_t safe_channel_count = 0, current_channel_count = 0; @@ -220,7 +259,7 @@ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, } if (len) { - current_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN); + current_channel_count = QDF_MIN(*len, NUM_CHANNELS); } else { policy_mgr_err("invalid number of channel length"); return; @@ -232,10 +271,11 @@ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, } qdf_mem_copy(current_channel_list, pcl_channels, - current_channel_count); - qdf_mem_zero(pcl_channels, current_channel_count); + current_channel_count * sizeof(*current_channel_list)); + qdf_mem_zero(pcl_channels, + current_channel_count * sizeof(*pcl_channels)); - qdf_mem_copy(org_weight_list, weight_list, QDF_MAX_NUM_CHAN); + qdf_mem_copy(org_weight_list, weight_list, NUM_CHANNELS); qdf_mem_zero(weight_list, weight_len); policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_on_lte_coex); @@ -274,14 +314,14 @@ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( struct policy_mgr_psoc_priv_obj *pm_ctx, - uint8_t *pcl_list_org, + uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; for (i = 0; i < *pcl_len_org; i++) { - if (!wlan_reg_is_passive_or_disable_ch( + if (!wlan_reg_is_passive_or_disable_for_freq( pm_ctx->pdev, pcl_list_org[i])) { pcl_list_org[pcl_len] = pcl_list_org[i]; weight_list_org[pcl_len++] = weight_list_org[i]; @@ -294,17 +334,17 @@ static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_list_org, + uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; - uint8_t pcl_list[QDF_MAX_NUM_CHAN]; - uint8_t weight_list[QDF_MAX_NUM_CHAN]; + uint32_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; bool ok; QDF_STATUS status = QDF_STATUS_E_FAILURE; - if (*pcl_len_org > QDF_MAX_NUM_CHAN) { + if (*pcl_len_org > NUM_CHANNELS) { policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); return status; } @@ -322,20 +362,20 @@ static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs( } } - qdf_mem_zero(pcl_list_org, *pcl_len_org); + qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); qdf_mem_zero(weight_list_org, *pcl_len_org); - qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); qdf_mem_copy(weight_list_org, weight_list, pcl_len); *pcl_len_org = pcl_len; return QDF_STATUS_SUCCESS; } -uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, uint32_t *vdev_id) +uint32_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t *vdev_id) { uint32_t idx = 0; - uint8_t chan; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -355,9 +395,8 @@ uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, (!vdev_id || (*vdev_id == pm_conc_connection_list[idx].vdev_id)) && pm_conc_connection_list[idx].in_use) { - chan = pm_conc_connection_list[idx].chan; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - return chan; + return pm_conc_connection_list[idx].freq; } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } @@ -365,8 +404,15 @@ uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, return 0; } -QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, - bool *skip_dfs_channel) +/** + * policy_mgr_skip_dfs_ch() - skip dfs channel or not + * @psoc: pointer to soc + * @skip_dfs_channel: pointer to result + * + * Return: QDF_STATUS + */ +static QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, + bool *skip_dfs_channel) { bool sta_sap_scc_on_dfs_chan; bool dfs_master_capable; @@ -389,23 +435,11 @@ QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - - if (policy_mgr_is_hw_dbs_capable(psoc)) { - if ((policy_mgr_is_special_mode_active_5g(psoc, - PM_P2P_CLIENT_MODE) || - policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)) && - !sta_sap_scc_on_dfs_chan) { - policy_mgr_debug("skip DFS ch from pcl for DBS SAP/Go"); - *skip_dfs_channel = true; - } - } else { - if ((policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, - NULL) > 0) && - !sta_sap_scc_on_dfs_chan) { - policy_mgr_debug("skip DFS ch from pcl for non-DBS SAP/Go"); - *skip_dfs_channel = true; - } + if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + NULL) > 0) && + !sta_sap_scc_on_dfs_chan) { + policy_mgr_debug("SAP/Go skips DFS ch if sta connects"); + *skip_dfs_channel = true; } return QDF_STATUS_SUCCESS; @@ -422,7 +456,7 @@ QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc, */ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_list_org, + uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org) { @@ -436,7 +470,7 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs( policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - if (*pcl_len_org > QDF_MAX_NUM_CHAN) { + if (*pcl_len_org > NUM_CHANNELS) { policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); return QDF_STATUS_E_FAILURE; } @@ -453,7 +487,7 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs( } for (i = 0; i < *pcl_len_org; i++) { - if (!wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_list_org[i])) { + if (!wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_list_org[i])) { pcl_list_org[pcl_len] = pcl_list_org[i]; weight_list_org[pcl_len++] = weight_list_org[i]; } @@ -466,13 +500,13 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs( static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_list_org, + uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; - uint8_t pcl_list[QDF_MAX_NUM_CHAN]; - uint8_t weight_list[QDF_MAX_NUM_CHAN]; + uint32_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -480,21 +514,22 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - if (*pcl_len_org > QDF_MAX_NUM_CHAN) { + if (*pcl_len_org > NUM_CHANNELS) { policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); return QDF_STATUS_E_FAILURE; } for (i = 0; i < *pcl_len_org; i++) { - if (!wlan_reg_is_disable_ch(pm_ctx->pdev, pcl_list_org[i])) { + if (!wlan_reg_is_disable_for_freq( + pm_ctx->pdev, pcl_list_org[i])) { pcl_list[pcl_len] = pcl_list_org[i]; weight_list[pcl_len++] = weight_list_org[i]; } } - qdf_mem_zero(pcl_list_org, *pcl_len_org); + qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); qdf_mem_zero(weight_list_org, *pcl_len_org); - qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); qdf_mem_copy(weight_list_org, weight_list, pcl_len); *pcl_len_org = pcl_len; @@ -503,42 +538,36 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( static QDF_STATUS policy_mgr_modify_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_list_org, + uint32_t *pcl_list_org, uint8_t *weight_list_org, uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; - uint8_t pcl_list[QDF_MAX_NUM_CHAN]; - uint8_t weight_list[QDF_MAX_NUM_CHAN]; + uint32_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; struct policy_mgr_psoc_priv_obj *pm_ctx; - bool is_etsi13_srd_chan_allowed_in_mas_mode = true; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - is_etsi13_srd_chan_allowed_in_mas_mode = - wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev); - - if (is_etsi13_srd_chan_allowed_in_mas_mode) - return QDF_STATUS_SUCCESS; - if (*pcl_len_org > QDF_MAX_NUM_CHAN) { + if (*pcl_len_org > NUM_CHANNELS) { policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); return QDF_STATUS_E_FAILURE; } for (i = 0; i < *pcl_len_org; i++) { - if (wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, - pcl_list_org[i])) + if (wlan_reg_is_etsi13_srd_chan_for_freq( + pm_ctx->pdev, pcl_list_org[i])) continue; pcl_list[pcl_len] = pcl_list_org[i]; weight_list[pcl_len++] = weight_list_org[i]; } - qdf_mem_zero(pcl_list_org, *pcl_len_org); + qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); qdf_mem_zero(weight_list_org, *pcl_len_org); - qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); qdf_mem_copy(weight_list_org, weight_list, pcl_len); *pcl_len_org = pcl_len; @@ -547,7 +576,7 @@ policy_mgr_modify_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc, static QDF_STATUS policy_mgr_pcl_modification_for_sap( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *pcl_channels, uint8_t *pcl_weight, uint32_t *len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -555,6 +584,7 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap( bool nol_modified_pcl = false; bool dfs_modified_pcl = false; bool modified_final_pcl = false; + bool srd_chan_enabled; if (policy_mgr_is_sap_mandatory_channel_set(psoc)) { status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( @@ -583,12 +613,18 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap( } dfs_modified_pcl = true; - status = policy_mgr_modify_pcl_based_on_srd - (psoc, pcl_channels, pcl_weight, len); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get srd modified pcl for SAP"); - return status; + wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_SAP_MODE, + &srd_chan_enabled); + + if (!srd_chan_enabled) { + status = policy_mgr_modify_pcl_based_on_srd + (psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to modify SRD in pcl for SAP"); + return status; + } } + modified_final_pcl = true; policy_mgr_debug(" %d %d %d %d", mandatory_modified_pcl, @@ -601,11 +637,12 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap( static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *pcl_channels, uint8_t *pcl_weight, uint32_t *len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool srd_chan_enabled; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -620,12 +657,18 @@ static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go( return status; } - status = policy_mgr_modify_pcl_based_on_srd - (psoc, pcl_channels, pcl_weight, len); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get srd modified pcl for P2P-GO"); - return status; + wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_P2P_GO_MODE, + &srd_chan_enabled); + + if (!srd_chan_enabled) { + status = policy_mgr_modify_pcl_based_on_srd + (psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to modify SRD in pcl for GO"); + return status; + } } + policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); return QDF_STATUS_SUCCESS; @@ -633,7 +676,7 @@ static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go( static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *pcl_channels, uint8_t *pcl_weight, uint32_t *len, enum policy_mgr_con_mode mode) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -661,10 +704,58 @@ static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( return status; } +#ifdef FEATURE_FOURTH_CONNECTION +static enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + enum policy_mgr_conc_priority_mode pref) +{ + enum policy_mgr_three_connection_mode fourth_index = 0; + enum policy_mgr_pcl_type pcl; + + /* Will be enhanced for other types of 4 port conc (NaN etc.) + * in future. + */ + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + policy_mgr_err("Can't find index for 4th port pcl table for non dbs capable"); + return PM_MAX_PCL_TYPE; + } + + /* SAP and P2P Go have same result in 4th port pcl table */ + if (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) { + mode = PM_SAP_MODE; + } + + if (mode != PM_STA_MODE && mode != PM_SAP_MODE && + mode != PM_NDI_MODE) { + policy_mgr_err("Can't start 4th port if not STA, SAP, NDI"); + return PM_MAX_PCL_TYPE; + } + + fourth_index = + policy_mgr_get_fourth_connection_pcl_table_index(psoc); + if (PM_MAX_THREE_CONNECTION_MODE == fourth_index) { + policy_mgr_err("Can't find index for 4th port pcl table"); + return PM_MAX_PCL_TYPE; + } + policy_mgr_debug("Index for 4th port pcl table: %d", fourth_index); + + pcl = fourth_connection_pcl_dbs_table[fourth_index][mode][pref]; + + return pcl; +} +#else +static inline enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + enum policy_mgr_conc_priority_mode pref) +{return PM_MAX_PCL_TYPE; } +#endif + QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t *pcl_channels, uint32_t *len, - uint8_t *pcl_weight, uint32_t weight_len) + enum policy_mgr_con_mode mode, + uint32_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_connections = 0; @@ -751,6 +842,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, [third_index][mode][conc_system_pref]; } break; + case 3: + pcl = policy_mgr_get_pcl_4_port(psoc, mode, conc_system_pref); + break; default: policy_mgr_err("unexpected num_connections value %d", num_connections); @@ -815,7 +909,8 @@ enum policy_mgr_one_connection_mode qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (PM_STA_MODE == pm_conc_connection_list[0].mode) { - if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_24_1x1; @@ -829,7 +924,8 @@ enum policy_mgr_one_connection_mode index = PM_STA_5_2x2; } } else if (PM_SAP_MODE == pm_conc_connection_list[0].mode) { - if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_24_1x1; @@ -843,7 +939,8 @@ enum policy_mgr_one_connection_mode index = PM_SAP_5_2x2; } } else if (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) { - if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_24_1x1; @@ -857,7 +954,8 @@ enum policy_mgr_one_connection_mode index = PM_P2P_CLI_5_2x2; } } else if (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) { - if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_24_1x1; @@ -871,7 +969,8 @@ enum policy_mgr_one_connection_mode index = PM_P2P_GO_5_2x2; } } else if (PM_IBSS_MODE == pm_conc_connection_list[0].mode) { - if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_IBSS_24_1x1; @@ -891,10 +990,10 @@ enum policy_mgr_one_connection_mode index = PM_NAN_DISC_24_2x2; } - policy_mgr_debug("mode:%d chan:%d chain:%d index:%d", - pm_conc_connection_list[0].mode, - pm_conc_connection_list[0].chan, - pm_conc_connection_list[0].chain_mask, index); + policy_mgr_debug("mode:%d freq:%d chain:%d index:%d", + pm_conc_connection_list[0].mode, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[0].chain_mask, index); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -906,10 +1005,10 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_SAP_SCC_24_1x1; @@ -925,19 +1024,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_SAP_MCC_24_1x1; else index = PM_P2P_CLI_SAP_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_SAP_MCC_5_1x1; @@ -954,8 +1053,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_SAP_SBS_5_1x1; @@ -976,10 +1077,10 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_SAP_SCC_24_1x1; @@ -995,19 +1096,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_SAP_MCC_24_1x1; else index = PM_STA_SAP_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_SAP_MCC_5_1x1; @@ -1024,8 +1125,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_SAP_SBS_5_1x1; @@ -1046,10 +1149,10 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_SAP_SCC_24_1x1; @@ -1065,19 +1168,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_SAP_MCC_24_1x1; else index = PM_SAP_SAP_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_SAP_MCC_5_1x1; @@ -1094,8 +1197,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_SAP_SBS_5_1x1; @@ -1116,18 +1221,18 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_SCC_24_1x1; else index = PM_STA_P2P_GO_SCC_24_2x2; } else { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_SCC_5_1x1; else index = PM_STA_P2P_GO_SCC_5_2x2; @@ -1135,19 +1240,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_MCC_24_1x1; else index = PM_STA_P2P_GO_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_MCC_5_1x1; @@ -1164,8 +1269,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_SBS_5_1x1; @@ -1186,18 +1293,18 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_SCC_24_1x1; else index = PM_STA_P2P_CLI_SCC_24_2x2; } else { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_SCC_5_1x1; else index = PM_STA_P2P_CLI_SCC_5_2x2; @@ -1205,19 +1312,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[1].chan))) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_MCC_24_1x1; else index = PM_STA_P2P_CLI_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_MCC_5_1x1; @@ -1234,8 +1341,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_SBS_5_1x1; @@ -1256,10 +1365,10 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_P2P_CLI_SCC_24_1x1; @@ -1275,19 +1384,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_P2P_CLI_MCC_24_1x1; else index = PM_P2P_GO_P2P_CLI_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_P2P_CLI_MCC_5_1x1; @@ -1304,8 +1413,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_P2P_CLI_SBS_5_1x1; @@ -1326,10 +1437,10 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_SAP_SCC_24_1x1; @@ -1345,19 +1456,19 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_SAP_MCC_24_1x1; else index = PM_P2P_GO_SAP_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_SAP_MCC_5_1x1; @@ -1374,8 +1485,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_SAP_SBS_5_1x1; @@ -1396,38 +1509,38 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - if (WLAN_REG_IS_24GHZ_CH - (pm_conc_connection_list[0].chan)) { + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_SCC_24_1x1; else index = PM_STA_STA_SCC_24_2x2; } else { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_SCC_5_1x1; else index = PM_STA_STA_SCC_5_2x2; } /* MCC */ } else if (pm_conc_connection_list[0].mac == - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) + pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_MCC_24_1x1; else index = PM_STA_STA_MCC_24_2x2; - } else if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq)) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_MCC_5_1x1; @@ -1444,8 +1557,10 @@ static enum policy_mgr_two_connection_mode } else if (pm_conc_connection_list[0].mac != pm_conc_connection_list[1].mac) { /* SBS */ - if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_SBS_5_1x1; @@ -1461,14 +1576,86 @@ static enum policy_mgr_two_connection_mode return index; } +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_go_go(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_SCC_24_1x1; + else + index = PM_P2P_GO_P2P_GO_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_SCC_5_1x1; + else + index = PM_P2P_GO_P2P_GO_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_MCC_24_1x1; + else + index = PM_P2P_GO_P2P_GO_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_MCC_5_1x1; + else + index = PM_P2P_GO_P2P_GO_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_MCC_24_5_1x1; + else + index = PM_P2P_GO_P2P_GO_MCC_24_5_2x2; + } + /* SBS or DBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[0].freq)) && + (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[1].freq))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_GO_DBS_1x1; + else + index = PM_P2P_GO_P2P_GO_DBS_2x2; + } + } + return index; +} + static enum policy_mgr_two_connection_mode policy_mgr_get_third_connection_pcl_table_index_nan_ndi(void) { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - /* NAN Discovery can only be on 2.4GHz */ + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_NAN_DISC_NDI_SCC_24_1x1; else @@ -1476,7 +1663,7 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - /* NAN Discovery can only be on 2.4GHz */ + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_NAN_DISC_NDI_MCC_24_1x1; else @@ -1497,9 +1684,9 @@ static enum policy_mgr_two_connection_mode { enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; /* SCC */ - if (pm_conc_connection_list[0].chan == - pm_conc_connection_list[1].chan) { - /* NAN Discovery can only be on 2.4GHz */ + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_NAN_DISC_SCC_24_1x1; else @@ -1507,7 +1694,7 @@ static enum policy_mgr_two_connection_mode /* MCC */ } else if (pm_conc_connection_list[0].mac == pm_conc_connection_list[1].mac) { - /* NAN Discovery can only be on 2.4GHz */ + /* Policy mgr only considers NAN Disc ch in 2.4 GHz */ if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_NAN_DISC_MCC_24_1x1; else @@ -1523,6 +1710,37 @@ static enum policy_mgr_two_connection_mode return index; } +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sap_nan(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) { + /* Policy mgr only considers NAN Disc ch in 2.4 GHz */ + if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) + index = PM_SAP_NAN_DISC_SCC_24_1x1; + else + index = PM_SAP_NAN_DISC_SCC_24_2x2; + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ + if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) + index = PM_SAP_NAN_DISC_MCC_24_1x1; + else + index = PM_SAP_NAN_DISC_MCC_24_2x2; + /* DBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) + index = PM_SAP_NAN_DISC_DBS_1x1; + else + index = PM_SAP_NAN_DISC_DBS_2x2; + } + return index; +} + enum policy_mgr_two_connection_mode policy_mgr_get_third_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc) @@ -1595,26 +1813,235 @@ enum policy_mgr_two_connection_mode (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode))) index = policy_mgr_get_third_connection_pcl_table_index_nan_ndi(); + else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) && + (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)) || + ((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) && + (PM_SAP_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_sap_nan(); + else if ((pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) && + (pm_conc_connection_list[1].mode == PM_P2P_GO_MODE)) + index = + policy_mgr_get_third_connection_pcl_table_index_go_go(); + + policy_mgr_debug("mode0:%d mode1:%d freq0:%d freq1:%d chain:%d index:%d", + pm_conc_connection_list[0].mode, + pm_conc_connection_list[1].mode, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq, + pm_conc_connection_list[0].chain_mask, index); + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return index; +} + +#ifdef FEATURE_FOURTH_CONNECTION +enum policy_mgr_three_connection_mode + policy_mgr_get_fourth_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc) +{ + enum policy_mgr_three_connection_mode index = + PM_MAX_THREE_CONNECTION_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t count_sap = 0; + uint32_t count_sta = 0; + uint32_t count_ndi = 0; + uint32_t count_nan_disc = 0; + uint32_t list_sap[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t list_sta[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t list_ndi[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t list_nan_disc[MAX_NUMBER_OF_CONC_CONNECTIONS]; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return index; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + + /* For 4 port concurrency case, + * 1st step: (SAP+STA)(2.4G MAC SCC) + (SAP+STA)(5G MAC SCC) + * 2nd step: (AGO+STA)(2.4G MAC SCC) + (AGO+STA)(5G MAC SCC) + */ + count_sap += policy_mgr_mode_specific_connection_count( + psoc, PM_SAP_MODE, &list_sap[count_sap]); + count_sap += policy_mgr_mode_specific_connection_count( + psoc, PM_P2P_GO_MODE, &list_sap[count_sap]); + count_sta = policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, list_sta); + count_ndi = policy_mgr_mode_specific_connection_count( + psoc, PM_NDI_MODE, list_ndi); + count_nan_disc = policy_mgr_mode_specific_connection_count( + psoc, PM_NAN_DISC_MODE, list_nan_disc); + policy_mgr_debug("sap/ago %d, sta %d, ndi %d nan disc %d", + count_sap, count_sta, count_ndi, count_nan_disc); + if (count_sap == 2 && count_sta == 1) { + policy_mgr_debug( + "channel: sap0: %d, sap1: %d, sta0: %d", + pm_conc_connection_list[list_sap[0]].freq, + pm_conc_connection_list[list_sap[1]].freq, + pm_conc_connection_list[list_sta[0]].freq); + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[1]].freq)) { + index = PM_STA_SAP_SCC_24_SAP_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[1]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq)) { + index = PM_STA_SAP_SCC_24_SAP_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[1]].freq)) { + index = PM_STA_SAP_SCC_5_SAP_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[1]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq)) { + index = PM_STA_SAP_SCC_5_SAP_24_DBS; + } else { + index = PM_MAX_THREE_CONNECTION_MODE; + } + } else if (count_sap == 1 && count_sta == 2) { + policy_mgr_debug( + "channel: sap0: %d, sta0: %d, sta1: %d", + pm_conc_connection_list[list_sap[0]].freq, + pm_conc_connection_list[list_sta[0]].freq, + pm_conc_connection_list[list_sta[1]].freq); + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[1]].freq)) { + index = PM_STA_SAP_SCC_24_STA_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[1]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq)) { + index = PM_STA_SAP_SCC_24_STA_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[1]].freq)) { + index = PM_STA_SAP_SCC_5_STA_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[1]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq)) { + index = PM_STA_SAP_SCC_5_STA_24_DBS; + } else { + index = PM_MAX_THREE_CONNECTION_MODE; + } + } else if (count_nan_disc == 1 && count_ndi == 1 && count_sap == 1) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sap[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS; + } else { + index = PM_MAX_THREE_CONNECTION_MODE; + } + } else if (count_nan_disc == 1 && count_ndi == 1 && count_sta == 1) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NAN_DISC_STA_24_NDI_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NAN_DISC_NDI_24_STA_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_STA_NDI_5_NAN_DISC_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_sta[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_STA_NDI_NAN_DISC_24_SMM; + } + } else if (count_nan_disc == 1 && count_ndi == 2) { + /* Policy mgr only considers NAN Disc ch in 2.4GHz */ + if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[1]].freq)) { + index = PM_NAN_DISC_NDI_24_NDI_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NAN_DISC_NDI_24_NDI_5_DBS; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq) && + WLAN_REG_IS_5GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NDI_NDI_5_NAN_DISC_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq) && + WLAN_REG_IS_24GHZ_CH_FREQ( + pm_conc_connection_list[list_ndi[0]].freq)) { + index = PM_NDI_NDI_NAN_DISC_24_SMM; + } + } - policy_mgr_debug("mode0:%d mode1:%d chan0:%d chan1:%d chain:%d index:%d", + policy_mgr_debug( + "mode0:%d mode1:%d mode2:%d chan0:%d chan1:%d chan2:%d chain:%d index:%d", pm_conc_connection_list[0].mode, pm_conc_connection_list[1].mode, - pm_conc_connection_list[0].chan, - pm_conc_connection_list[1].chan, + pm_conc_connection_list[2].mode, + pm_conc_connection_list[0].freq, + pm_conc_connection_list[1].freq, + pm_conc_connection_list[2].freq, pm_conc_connection_list[0].chain_mask, index); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return index; } +#endif -uint8_t +uint32_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - bool for_existing_conn) + enum policy_mgr_con_mode mode, + bool for_existing_conn) { - uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; - uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; + uint32_t pcl_channels[NUM_CHANNELS]; + uint8_t pcl_weight[NUM_CHANNELS]; struct policy_mgr_psoc_priv_obj *pm_ctx; /* @@ -1622,15 +2049,15 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, * then return 2.4G channel, so atleast we won't fall * under 5G MCC scenario */ - uint8_t channel = PM_24_GHZ_CHANNEL_6; - uint32_t i, pcl_len = 0; + uint32_t i, pcl_len = 0, non_dfs_freq, freq; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - return channel; + return PM_24_GHZ_CH_FREQ_6; } + freq = PM_24_GHZ_CH_FREQ_6; if (true == for_existing_conn) { /* * First try to see if there is any non-dfs channel already @@ -1638,36 +2065,37 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, * that channel */ if (true == policy_mgr_is_any_nondfs_chnl_present( - psoc, &channel)) - return channel; + psoc, &non_dfs_freq)) + return non_dfs_freq; - if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl_for_existing_conn( + if (QDF_STATUS_SUCCESS != + policy_mgr_get_pcl_for_existing_conn( psoc, mode, - &pcl_channels[0], &pcl_len, + pcl_channels, &pcl_len, pcl_weight, QDF_ARRAY_SIZE(pcl_weight), false)) - return channel; + return freq; } else { - if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(psoc, mode, - &pcl_channels[0], &pcl_len, - pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) - return channel; + if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl( + psoc, mode, pcl_channels, &pcl_len, pcl_weight, + QDF_ARRAY_SIZE(pcl_weight))) + return freq; } for (i = 0; i < pcl_len; i++) { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i]) || + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]) || !policy_mgr_is_safe_channel(psoc, pcl_channels[i])) { continue; } else { - channel = pcl_channels[i]; + freq = pcl_channels[i]; break; } } - return channel; + return freq; } -static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list, +static void policy_mgr_remove_dsrc_channels(uint32_t *ch_freq_list, uint32_t *num_channels, struct wlan_objmgr_pdev *pdev) { @@ -1675,8 +2103,8 @@ static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list, int i; for (i = 0; i < *num_channels; i++) { - if (!wlan_reg_is_dsrc_chan(pdev, chan_list[i])) { - chan_list[num_chan_temp] = chan_list[i]; + if (!wlan_reg_is_dsrc_freq(ch_freq_list[i])) { + ch_freq_list[num_chan_temp] = ch_freq_list[i]; num_chan_temp++; } } @@ -1684,17 +2112,16 @@ static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list, *num_channels = num_chan_temp; } -QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc, - uint8_t *ch_list, - uint32_t *ch_cnt, - enum policy_mgr_con_mode mode) +QDF_STATUS policy_mgr_get_valid_chans_from_range( + struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq_list, + uint32_t *ch_cnt, enum policy_mgr_con_mode mode) { - uint8_t ch_weight_list[QDF_MAX_NUM_CHAN] = {0}; + uint8_t ch_weight_list[NUM_CHANNELS] = {0}; uint32_t ch_weight_len; QDF_STATUS status = QDF_STATUS_E_FAILURE; size_t chan_index = 0; - if (!ch_list || !ch_cnt) { + if (!ch_freq_list || !ch_cnt) { policy_mgr_err("NULL parameters"); return QDF_STATUS_E_FAILURE; } @@ -1706,19 +2133,19 @@ QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc, /* check the channel avoidance list for beaconing entities */ if (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) - policy_mgr_update_with_safe_channel_list(psoc, ch_list, - ch_cnt, ch_weight_list, - ch_weight_len); + policy_mgr_update_with_safe_channel_list( + psoc, ch_freq_list, ch_cnt, ch_weight_list, + ch_weight_len); status = policy_mgr_mode_specific_modification_on_pcl( - psoc, ch_list, ch_weight_list, ch_cnt, mode); + psoc, ch_freq_list, ch_weight_list, ch_cnt, mode); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("failed to get modified pcl for mode %d", mode); return status; } - status = policy_mgr_modify_pcl_based_on_dnbs(psoc, ch_list, + status = policy_mgr_modify_pcl_based_on_dnbs(psoc, ch_freq_list, ch_weight_list, ch_cnt); if (QDF_IS_STATUS_ERROR(status)) { @@ -1730,9 +2157,9 @@ QDF_STATUS policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc *psoc, } QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, - uint8_t *chan_list, uint32_t *list_len) + uint32_t *ch_freq_list, + uint32_t *list_len) { - QDF_STATUS status; struct policy_mgr_psoc_priv_obj *pm_ctx; *list_len = 0; @@ -1742,41 +2169,37 @@ QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - - if (!pm_ctx->sme_cbacks.sme_get_valid_channels) { - policy_mgr_err("sme_get_valid_chans callback is NULL"); - return QDF_STATUS_E_FAILURE; + if (!pm_ctx->valid_ch_freq_list_count) { + policy_mgr_err("Invalid PM valid channel list"); + return QDF_STATUS_E_INVAL; } - *list_len = QDF_MAX_NUM_CHAN; - status = pm_ctx->sme_cbacks.sme_get_valid_channels( - chan_list, list_len); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("Error in getting valid channels"); - *list_len = 0; - return status; - } + *list_len = pm_ctx->valid_ch_freq_list_count; + qdf_mem_copy(ch_freq_list, pm_ctx->valid_ch_freq_list, + pm_ctx->valid_ch_freq_list_count * + sizeof(pm_ctx->valid_ch_freq_list[0])); - policy_mgr_remove_dsrc_channels(chan_list, list_len, pm_ctx->pdev); + policy_mgr_remove_dsrc_channels(ch_freq_list, list_len, pm_ctx->pdev); return QDF_STATUS_SUCCESS; } -bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list, - uint32_t list_len) +bool policy_mgr_list_has_24GHz_channel(uint32_t *ch_freq_list, + uint32_t list_len) { uint32_t i; for (i = 0; i < list_len; i++) { - if (WLAN_REG_IS_24GHZ_CH(channel_list[i])) + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i])) return true; } return false; } -QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, - uint8_t *channels, uint32_t len) +QDF_STATUS +policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, + uint32_t *ch_freq_list, uint32_t len) { uint32_t i; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1792,7 +2215,7 @@ QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - if (!policy_mgr_list_has_24GHz_channel(channels, len)) { + if (!policy_mgr_list_has_24GHz_channel(ch_freq_list, len)) { policy_mgr_err("2.4GHz channels missing, this is not expected"); return QDF_STATUS_E_FAILURE; } @@ -1801,7 +2224,7 @@ QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, pm_ctx->sap_mandatory_channels_len); for (i = 0; i < len; i++) { - pm_ctx->sap_mandatory_channels[i] = channels[i]; + pm_ctx->sap_mandatory_channels[i] = ch_freq_list[i]; policy_mgr_debug("chan:%d", pm_ctx->sap_mandatory_channels[i]); } @@ -1827,14 +2250,17 @@ bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc) } QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( - struct wlan_objmgr_psoc *psoc, - uint8_t *pcl_list_org, - uint8_t *weight_list_org, - uint32_t *pcl_len_org) + struct wlan_objmgr_psoc *psoc, uint32_t *pcl_list_org, + uint8_t *weight_list_org, uint32_t *pcl_len_org) { uint32_t i, j, pcl_len = 0; bool found; struct policy_mgr_psoc_priv_obj *pm_ctx; + qdf_freq_t dfs_sta_freq = 0; + qdf_freq_t sta_5GHz_freq = 0; + enum hw_mode_bandwidth sta_ch_width; + uint8_t sta_vdev_id = 0, scc_on_dfs_channel = 0; + bool sta_sap_scc_on_5ghz_channel; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1853,14 +2279,39 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) policy_mgr_debug("fav chan:%d", - pm_ctx->sap_mandatory_channels[i]); + pm_ctx->sap_mandatory_channels[i]); + + policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &scc_on_dfs_channel); + if (scc_on_dfs_channel) + policy_mgr_is_sta_present_on_dfs_channel(psoc, + &sta_vdev_id, + &dfs_sta_freq, + &sta_ch_width); + sta_sap_scc_on_5ghz_channel = + policy_mgr_is_connected_sta_5g(psoc, &sta_5GHz_freq); for (i = 0; i < *pcl_len_org; i++) { found = false; - if (i >= QDF_MAX_NUM_CHAN) { - policy_mgr_debug("index is exceeding QDF_MAX_NUM_CHAN"); + if (i >= NUM_CHANNELS) { + policy_mgr_debug("index is exceeding NUM_CHANNELS"); break; } + + if (scc_on_dfs_channel && policy_mgr_is_force_scc(psoc) && + pcl_list_org[i] == dfs_sta_freq) { + policy_mgr_debug("dfs chan:%d", pcl_list_org[i]); + found = true; + goto update_pcl; + } + + if (sta_sap_scc_on_5ghz_channel && + policy_mgr_is_force_scc(psoc) && + pcl_list_org[i] == sta_5GHz_freq) { + policy_mgr_debug("scc chan:%d", pcl_list_org[i]); + found = true; + goto update_pcl; + } + for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) { if (pcl_list_org[i] == pm_ctx->sap_mandatory_channels[j]) { @@ -1868,7 +2319,9 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( break; } } - if (found && (pcl_len < QDF_MAX_NUM_CHAN)) { + +update_pcl: + if (found && (pcl_len < NUM_CHANNELS)) { pcl_list_org[pcl_len] = pcl_list_org[i]; weight_list_org[pcl_len++] = weight_list_org[i]; } @@ -1879,15 +2332,15 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( } QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, - uint16_t *chan) + uint32_t *ch_freq) { QDF_STATUS status; struct policy_mgr_pcl_list pcl; qdf_mem_zero(&pcl, sizeof(pcl)); - status = policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, - pcl.pcl_list, &pcl.pcl_len, + status = policy_mgr_get_pcl_for_existing_conn( + psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list), false); if (QDF_IS_STATUS_ERROR(status)) { @@ -1901,9 +2354,10 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, * channel between PCL & mandatory channel list as well */ if (!pcl.pcl_len && !policy_mgr_mode_specific_connection_count(psoc, - PM_SAP_MODE, NULL)) { + PM_SAP_MODE, NULL)) { policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl"); - status = policy_mgr_get_pcl(psoc, PM_SAP_MODE, + status = policy_mgr_get_pcl( + psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); @@ -1927,8 +2381,8 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - *chan = pcl.pcl_list[0]; - policy_mgr_debug("mandatory channel:%d", *chan); + *ch_freq = pcl.pcl_list[0]; + policy_mgr_debug("mandatory channel:%d", *ch_freq); return QDF_STATUS_SUCCESS; } @@ -1948,7 +2402,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN, + qdf_mem_set(weight->weighed_valid_list, NUM_CHANNELS, WEIGHT_OF_DISALLOWED_CHANNELS); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count( @@ -1992,40 +2446,40 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -uint8_t policy_mgr_mode_specific_get_channel( +uint32_t policy_mgr_mode_specific_get_channel( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { uint32_t conn_index; - uint8_t channel = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t freq = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - return channel; + return 0; } /* provides the channel for the first matching mode type */ qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if ((pm_conc_connection_list[conn_index].mode == mode) && - pm_conc_connection_list[conn_index].in_use) { - channel = pm_conc_connection_list[conn_index].chan; + pm_conc_connection_list[conn_index].in_use) { + freq = pm_conc_connection_list[conn_index].freq; break; } } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - return channel; + return freq; } -uint8_t policy_mgr_get_alternate_channel_for_sap( +uint32_t policy_mgr_get_alternate_channel_for_sap( struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id, - uint8_t sap_channel) + uint32_t sap_ch_freq) { - uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; - uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; - uint8_t channel = 0; + uint32_t pcl_channels[NUM_CHANNELS]; + uint8_t pcl_weight[NUM_CHANNELS]; + uint32_t ch_freq = 0; uint32_t pcl_len = 0; struct policy_mgr_conc_connection_info info; uint8_t num_cxn_del = 0; @@ -2048,13 +2502,13 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, &info, &num_cxn_del); - if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE, - pcl_channels, &pcl_len, - pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) { + if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl( + psoc, PM_SAP_MODE, pcl_channels, &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) { for (i = 0; i < pcl_len; i++) { - if (pcl_channels[i] == sap_channel) + if (pcl_channels[i] == sap_ch_freq) continue; - channel = pcl_channels[i]; + ch_freq = pcl_channels[i]; break; } } @@ -2063,7 +2517,7 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - return channel; + return ch_freq; } /* @@ -2073,10 +2527,10 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( #define CHAN_WEIGHT_CHAR_LEN 10 #define MAX_CHAN_TO_PRINT 39 -bool policy_mgr_dump_channel_list(uint32_t len, uint8_t *pcl_channels, +bool policy_mgr_dump_channel_list(uint32_t len, uint32_t *pcl_channels, uint8_t *pcl_weight) { - uint32_t idx, buff_len, num = 0, count = 0; + uint32_t idx, buff_len, num = 0, count = 0, count_6G = 0; char *chan_buff = NULL; buff_len = (QDF_MIN(len, MAX_CHAN_TO_PRINT) * CHAN_WEIGHT_CHAR_LEN) + 1; @@ -2085,21 +2539,52 @@ bool policy_mgr_dump_channel_list(uint32_t len, uint8_t *pcl_channels, return false; policymgr_nofl_debug("Total PCL Chan Freq %d", len); - for (idx = 0; idx < len; idx++) { - num += qdf_scnprintf(chan_buff + num, buff_len - num, " %d[%d]", - pcl_channels[idx], pcl_weight[idx]); - count++; - if (count >= MAX_CHAN_TO_PRINT) { - /* Print the MAX_CHAN_TO_PRINT channels */ - policymgr_nofl_debug("Chan[weight]:%s", chan_buff); - count = 0; - num = 0; + for (idx = 0; (idx < len) && (idx < NUM_CHANNELS); idx++) { + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_channels[idx])) { + num += qdf_scnprintf(chan_buff + num, buff_len - num, + " %d[%d]", pcl_channels[idx], + pcl_weight[idx]); + count++; + if (count >= MAX_CHAN_TO_PRINT) { + /* Print the MAX_CHAN_TO_PRINT channels */ + policymgr_nofl_debug("2G+5G Freq[weight]:%s", + chan_buff); + count = 0; + num = 0; + } + } else { + count_6G++; + } + } + /* Print any pending channels */ + if (num) + policymgr_nofl_debug("2G+5G Freq[weight]:%s", chan_buff); + + if (!count_6G) + goto free; + + count = 0; + num = 0; + for (idx = 0; (idx < len) && (idx < NUM_CHANNELS); idx++) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_channels[idx])) { + num += qdf_scnprintf(chan_buff + num, buff_len - num, + " %d[%d]", pcl_channels[idx], + pcl_weight[idx]); + count++; + if (count >= MAX_CHAN_TO_PRINT) { + /* Print the MAX_CHAN_TO_PRINT channels */ + policymgr_nofl_debug("6G Freq[weight]:%s", + chan_buff); + count = 0; + num = 0; + } } } /* Print any pending channels */ if (num) - policymgr_nofl_debug("Chan[weight]:%s", chan_buff); + policymgr_nofl_debug("6G Freq[weight]:%s", chan_buff); +free: qdf_mem_free(chan_buff); return true; diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h index 41326ef934fe6c617b890fbb48bf1e4fa258f403..7acc8292fa08faf3373d1c85889a9ab8cf40d0ab 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h @@ -1764,6 +1764,180 @@ pm_third_connection_pcl_dbs_1x1_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_P2P_GO_P2P_GO_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_DBS_2x2] = { + [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_STA_P2P_CLI_SCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h index 2a63c23c7ffd5b48cca9dd006040eba8b3cfee3d..dc4da9276e26056486e66d3bc87820729e1038f1 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -133,8 +133,7 @@ static enum policy_mgr_pcl_type [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, - PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -145,8 +144,7 @@ static enum policy_mgr_pcl_type [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, - PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -160,8 +158,7 @@ static enum policy_mgr_pcl_type PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, - PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -175,8 +172,7 @@ static enum policy_mgr_pcl_type PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, - PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -547,8 +543,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_NAN_DISC_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_SCC_5_2x2] = { @@ -560,8 +555,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_NAN_DISC_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_MCC_5_1x1] = { @@ -621,14 +615,13 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_SCC_ON_5_SCC_ON_24}, [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_NAN_DISC_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_DBS_2x2] = { @@ -636,14 +629,13 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_SCC_ON_5_SCC_ON_24}, [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_NAN_DISC_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_SBS_5_1x1] = { @@ -661,14 +653,71 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_SAP_NAN_DISC_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_NAN_DISC_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_NAN_DISC_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_NAN_DISC_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_NAN_DISC_DBS_1x1] = { + [PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, + [PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_NAN_DISC_DBS_2x2] = { + [PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, + [PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_STA_P2P_GO_SCC_24_1x1] = { [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -680,8 +729,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -693,8 +741,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -706,8 +753,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -722,8 +768,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_24G_SCC_CH_SBS_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -738,8 +783,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_24G_SCC_CH_SBS_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -753,8 +797,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -768,8 +811,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -783,8 +825,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -798,8 +839,7 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -814,7 +854,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -829,7 +870,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NAN_DISC_MODE] = { @@ -1031,7 +1073,166 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, - [PM_P2P_GO_SAP_SBS_5_1x1] = { + [PM_P2P_GO_P2P_GO_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_DBS_2x2] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NAN_DISC_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_NDI_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_GO_SBS_5_1x1] = { [PM_STA_MODE] = { PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, [PM_SAP_MODE] = { @@ -1695,7 +1896,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NAN_DISC_NDI_SCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -1703,7 +1904,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NAN_DISC_NDI_MCC_24_1x1] = { [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -1711,7 +1912,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NAN_DISC_NDI_MCC_24_2x2] = { [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -1720,7 +1921,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NAN_DISC_NDI_DBS_1x1] = { [PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -1729,13 +1931,71 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_NAN_DISC_NDI_DBS_2x2] = { [PM_STA_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_SCC_ON_24_SCC_ON_5_5G, PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_24_SCC_ON_5_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, }; +#ifdef FEATURE_FOURTH_CONNECTION +/** + * fourth_connection_pcl_dbs_table - table which provides PCL for + * the 4th connection, when we have 3 connections already in + * the system (with DBS supported by HW), this table is for auto products. + */ +#ifdef FOURTH_CONNECTION_AUTO +const enum policy_mgr_pcl_type +fourth_connection_pcl_dbs_table + [PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE] = { + [PM_STA_SAP_SCC_24_SAP_5_DBS] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_SAP_SCC_5_SAP_24_DBS] = { + [PM_STA_MODE] = { PM_24G, PM_24G, PM_24G } }, + [PM_STA_SAP_SCC_24_STA_5_DBS] = { + [PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_SAP_SCC_5_STA_24_DBS] = { + [PM_SAP_MODE] = { PM_24G, PM_24G, PM_24G } }, + [PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS] = { + [PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS] = { + [PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS] = { + [PM_SAP_MODE] = { PM_24G, PM_24G, PM_24G } } +}; +#else +/** + * fourth_connection_pcl_dbs_table - table which provides PCL for + * the 4th connection, when we have 3 connections already in + * the system (with DBS supported by HW), this table is for mobile products + * If you want to support any 4 port other than the below in MCL add below as + * other concurrencies supported by auto may not be PORed for mobile products + * and vice-versa. + */ +const enum policy_mgr_pcl_type +fourth_connection_pcl_dbs_table + [PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE] = { + [PM_NAN_DISC_STA_24_NDI_5_DBS] = { + [PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_NAN_DISC_NDI_24_STA_5_DBS] = { + [PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_NDI_5_NAN_DISC_24_DBS] = { + [PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_NDI_NAN_DISC_24_SMM] = { + [PM_NDI_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_NAN_DISC_NDI_24_NDI_5_DBS] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_NDI_NDI_5_NAN_DISC_24_DBS] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_NDI_NDI_NAN_DISC_24_SMM] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } } +}; +#endif +#endif + /** * next_action_two_connection_table - table which provides next * action while a new connection is coming up, with one @@ -1847,6 +2107,11 @@ static policy_mgr_next_action_three_connection_table_type [PM_SAP_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, [PM_SAP_SAP_SCC_5_2x2] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_P2P_GO_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_GO_P2P_GO_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_GO_P2P_GO_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_GO_P2P_GO_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_GO_P2P_GO_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, }; #endif diff --git a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c index f238c87eb50dc0871dd5b5d2ca70c0cf3fa35481..44fcb2d964afd7faefd6a41a687ae53ea00126b1 100644 --- a/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c +++ b/drivers/staging/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c @@ -37,6 +37,7 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) cfg->max_conc_cxns = cfg_get(psoc, CFG_MAX_CONC_CXNS); cfg->conc_rule1 = cfg_get(psoc, CFG_ENABLE_CONC_RULE1); cfg->conc_rule2 = cfg_get(psoc, CFG_ENABLE_CONC_RULE2); + cfg->pcl_band_priority = cfg_get(psoc, CFG_PCL_BAND_PRIORITY); cfg->dbs_selection_plcy = cfg_get(psoc, CFG_DBS_SELECTION_PLCY); cfg->vdev_priority_list = cfg_get(psoc, CFG_VDEV_CUSTOM_PRIORITY_LIST); cfg->chnl_select_plcy = cfg_get(psoc, CFG_CHNL_SELECT_LOGIC_CONC); @@ -65,8 +66,8 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) cfg_get(psoc, CFG_ENABLE_SAP_MANDATORY_CHAN_LIST); cfg->mark_indoor_chnl_disable = cfg_get(psoc, CFG_MARK_INDOOR_AS_DISABLE_FEATURE); - cfg->prefer_5g_scc_to_dbs = cfg_get(psoc, CFG_PREFER_5G_SCC_TO_DBS); cfg->go_force_scc = cfg_get(psoc, CFG_P2P_GO_ENABLE_FORCE_SCC); + cfg->prefer_5g_scc_to_dbs = cfg_get(psoc, CFG_PREFER_5G_SCC_TO_DBS); return QDF_STATUS_SUCCESS; } @@ -226,10 +227,10 @@ ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc, - uint16_t *chan_list, + qdf_freq_t *chan_freq_list, uint16_t chan_cnt) { - return policy_mgr_init_chan_avoidance(psoc, chan_list, chan_cnt); + return policy_mgr_init_chan_avoidance(psoc, chan_freq_list, chan_cnt); } QDF_STATUS ucfg_policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc, diff --git a/drivers/staging/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_ext_type.h b/drivers/staging/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_ext_type.h new file mode 100644 index 0000000000000000000000000000000000000000..a4f5ae1a19e02c52fff27a43107b63eda85bb87f --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/cp_stats/dispatcher/inc/wlan_cp_stats_ext_type.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_ext_cp_stats_types.h + * + * This header file is included by the converged control path statistics + * component to map legacy statistic structures to the external + * (ext)typedefs used by the converged code. This mechanism allows the + * legacy structs to be included as part of the global objmgr objects. + */ + +#ifndef __WLAN_EXT_CP_STATS_TYPE_H__ +#define __WLAN_EXT_CP_STATS_TYPE_H__ + +/** + * typedef psoc_ext_cp_stats_t - Definition of psoc cp stats pointer + * Define obj_stats from external umac/cp_stats component point to this type + */ +typedef struct psoc_mc_cp_stats psoc_ext_cp_stats_t; + +/** + * typedef pdev_ext_cp_stats_t - Definition of pdev cp stats pointer + * Define pdev_stats from external umac/cp_stats component point to this type + */ +typedef struct pdev_mc_cp_stats pdev_ext_cp_stats_t; + +/** + * typedef vdev_ext_cp_stats_t - Definition of vdev cp stats pointer + * Define vdev_stats from external umac/cp_stats component point to this type + */ +typedef struct vdev_mc_cp_stats vdev_ext_cp_stats_t; + +/** + * typedef peer_ext_cp_stats_t - Definition of peer cp stats pointer + * Define peer_stats from external umac/cp_stats component point to this type + */ +typedef struct peer_mc_cp_stats peer_ext_cp_stats_t; + +/** + * typedef peer_ext_adv_cp_stats_t - Definition of peer adv cp stats pointer + * Define peer_adv_stats from external umac/cp_stats component point to this + * type + */ +typedef struct peer_adv_mc_cp_stats peer_ext_adv_cp_stats_t; + +#endif /* __WLAN_EXT_CP_STATS_TYPE_H__ */ + diff --git a/drivers/staging/qcacld-3.0/components/dsc/src/__wlan_dsc.h b/drivers/staging/qcacld-3.0/components/dsc/src/__wlan_dsc.h index c6539a14715dbbb867ae7bae222db344b4049c97..bd9de768547b7cf3a5a20da408e37e510d9660ad 100644 --- a/drivers/staging/qcacld-3.0/components/dsc/src/__wlan_dsc.h +++ b/drivers/staging/qcacld-3.0/components/dsc/src/__wlan_dsc.h @@ -39,6 +39,13 @@ #define dsc_debug(params...) /* no-op */ #endif +#define dsc_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, params) +#define dsc_nofl_info(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_QDF, params) +#define dsc_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_QDF, params) + #define dsc_enter_exit dsc_debug #define dsc_enter() dsc_enter_exit("enter") #define dsc_enter_str(str) dsc_enter_exit("enter(\"%s\")", str) diff --git a/drivers/staging/qcacld-3.0/components/dsc/src/wlan_dsc_vdev.c b/drivers/staging/qcacld-3.0/components/dsc/src/wlan_dsc_vdev.c index ebbfbd77894d2e52734a8e34ae6e36b15879b796..b045ffd53334d22d24fd4e53dd3b7fcef23acd22 100644 --- a/drivers/staging/qcacld-3.0/components/dsc/src/wlan_dsc_vdev.c +++ b/drivers/staging/qcacld-3.0/components/dsc/src/wlan_dsc_vdev.c @@ -121,7 +121,7 @@ void dsc_vdev_destroy(struct dsc_vdev **out_vdev) * resumed after the current trans/op is completed. return QDF_STATUS_E_AGAIN * in this case. * - * If there is a psoc transition taking place because of psoc idle shutdown, + * If there is a psoc transition taking place becasue of psoc idle shutdown, * then the vdev trans/ops should be rejected and queued in the DSC queue so * that it may be resumed after the current trans/ops is completed. Return * QDF_STATUS_E_AGAIN in this case. diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_main.h b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_main.h new file mode 100644 index 0000000000000000000000000000000000000000..a7d5a8df29916e48ec40653be11910f34e1e6b3f --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_main.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Declare private API which shall be used internally only + * in ftm_time_sync component. This file shall include prototypes of + * various notification handlers and logging functions. + * + * Note: This API should be never accessed out of ftm_time_sync component. + */ + +#ifndef _FTM_TIME_SYNC_MAIN_H_ +#define _FTM_TIME_SYNC_MAIN_H_ + +#include +#include "ftm_time_sync_priv.h" +#include "ftm_time_sync_objmgr.h" + +#define ftm_time_sync_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_FTM_TIME_SYNC, level, ## args) + +#define ftm_time_sync_logfl(level, format, args...) \ + ftm_time_sync_log(level, FL(format), ## args) + +#define ftm_time_sync_fatal(format, args...) \ + ftm_time_sync_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define ftm_time_sync_err(format, args...) \ + ftm_time_sync_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define ftm_time_sync_warn(format, args...) \ + ftm_time_sync_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define ftm_time_sync_info(format, args...) \ + ftm_time_sync_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define ftm_time_sync_debug(format, args...) \ + ftm_time_sync_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) + +#define FTM_TIME_SYNC_ENTER() ftm_time_sync_debug("enter") +#define FTM_TIME_SYNC_EXIT() ftm_time_sync_debug("exit") + +/** + * ftm_time_sync_vdev_create_notification(): Handler for vdev create notify. + * @vdev: vdev which is going to be created by objmgr + * @arg: argument for notification handler. + * + * Allocate and attach vdev private object. + * + * Return: QDF_STATUS status in case of success else return error. + */ +QDF_STATUS ftm_timesync_vdev_create_notification(struct wlan_objmgr_vdev *vdev, + void *arg); + +/** + * ftm_time_sync_vdev_destroy_notification(): Handler for vdev destroy notify. + * @vdev: vdev which is going to be destroyed by objmgr + * @arg: argument for notification handler. + * + * Deallocate and detach vdev private object. + * + * Return QDF_STATUS status in case of success else return error + */ +QDF_STATUS +ftm_timesync_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, + void *arg); + +#endif /* end of _FTM_TIME_SYNC_MAIN_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_objmgr.h b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_objmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..59b6168e5d9bf72e56a5935c150bc7653c3ee917 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_objmgr.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: This file contains various object manager related wrappers and helpers + */ + +#ifndef _FTM_TIME_SYNC_OBJMGR_H +#define _FTM_TIME_SYNC_OBJMGR_H + +#include "wlan_cmn.h" +#include "wlan_objmgr_cmn.h" +#include "wlan_objmgr_vdev_obj.h" +#include "wlan_objmgr_global_obj.h" + +/** + * ftm_timesync_vdev_get_ref() - Wrapper to increment ftm_timesync ref count + * @vdev: vdev object + * + * Wrapper for ftm_timesync to increment ref count after checking valid + * object state. + * + * Return: SUCCESS/FAILURE + */ +static inline +QDF_STATUS ftm_timesync_vdev_get_ref(struct wlan_objmgr_vdev *vdev) +{ + return wlan_objmgr_vdev_try_get_ref(vdev, FTM_TIME_SYNC_ID); +} + +/** + * ftm_timesync_vdev_put_ref() - Wrapper to decrement ftm_timesync ref count + * @vdev: vdev object + * + * Wrapper for ftm_timesync to decrement ref count of vdev. + * + * Return: SUCCESS/FAILURE + */ +static inline +void ftm_timesync_vdev_put_ref(struct wlan_objmgr_vdev *vdev) +{ + return wlan_objmgr_vdev_release_ref(vdev, FTM_TIME_SYNC_ID); +} + +/** + * ftm_timesync_vdev_get_priv(): Wrapper to retrieve vdev priv obj + * @vdev: vdev pointer + * + * Wrapper for ftm_timesync to get vdev private object pointer. + * + * Return: Private object of vdev + */ +static inline struct ftm_timesync_vdev_priv * +ftm_timesync_vdev_get_priv(struct wlan_objmgr_vdev *vdev) +{ + struct ftm_timesync_vdev_priv *vdev_priv; + + vdev_priv = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_FTM_TIME_SYNC); + QDF_BUG(vdev_priv); + + return vdev_priv; +} + +#endif /* _FTM_TIME_SYNC_OBJMGR_H */ diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_priv.h b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_priv.h new file mode 100644 index 0000000000000000000000000000000000000000..9619cd28fc1b65ea9166b9ca4a3d6df944081f30 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/inc/ftm_time_sync_priv.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Declare private API which shall be used internally only + * in ftm_timesync component. This file shall include prototypes of + * ftm_timesync parsing and send logic. + * + * Note: This API should be never accessed out of ftm_timesync component. + */ + +#ifndef _FTM_TIME_SYNC_PRIV_STRUCT_H_ +#define _FTM_TIME_SYNC_PRIV_STRUCT_H_ + +#include +#include +#include "ftm_time_sync_objmgr.h" +#include "wlan_ftm_time_sync_public_struct.h" + +#define WLAN_FTM_TIME_SYNC_PAIR_MAX 32 + +/** + * struct wlan_time_sync_pair - wlan time sync pair + * @qtime_master: master qtime + * @qtime_slave: slave qtime + */ +struct wlan_time_sync_pair { + uint64_t qtime_master; + uint64_t qtime_slave; +}; + +/** + * struct ftm_timesync_vdev_priv - Private object to be stored in vdev + * @qtime_ref: qtime ref + * @mac_ref: mac time ref + * @time_pair: array of master/slave qtime pair + */ + +struct ftm_timesync_priv { + uint64_t qtime_ref; + uint64_t mac_ref; + struct wlan_time_sync_pair time_pair[WLAN_FTM_TIME_SYNC_PAIR_MAX]; +}; + +/** + * struct ftm_timesync_vdev_priv - Private object to be stored in vdev + * @vdev: pointer to vdev object + * @ftm_ts_priv: time sync private struct + * @rx_ops: rx operations for ftm time sync + * @tx_ops: tx operations for ftm time sync + */ +struct ftm_timesync_vdev_priv { + struct wlan_objmgr_vdev *vdev; + struct ftm_timesync_priv ftm_ts_priv; + struct wlan_ftm_timesync_rx_ops rx_ops; + struct wlan_ftm_timesync_tx_ops tx_ops; +}; + +#endif /* End of _FTM_TIME_SYNC_PRIV_STRUCT_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/src/ftm_time_sync_main.c b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/src/ftm_time_sync_main.c new file mode 100644 index 0000000000000000000000000000000000000000..e16139e655223134a53304783e756e6c238466da --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/core/src/ftm_time_sync_main.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Implement various notification handlers which are accessed + * internally in ftm_timesync component only. + */ + +#include "ftm_time_sync_main.h" + +QDF_STATUS +ftm_timesync_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg) +{ + struct ftm_timesync_vdev_priv *vdev_priv; + QDF_STATUS status; + + vdev_priv = qdf_mem_malloc(sizeof(*vdev_priv)); + if (!vdev_priv) { + status = QDF_STATUS_E_NOMEM; + goto exit; + } + + status = wlan_objmgr_vdev_component_obj_attach( + vdev, WLAN_UMAC_COMP_FTM_TIME_SYNC, + (void *)vdev_priv, QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + ftm_time_sync_err("Failed to attach priv with vdev"); + goto free_vdev_priv; + } + + vdev_priv->vdev = vdev; + goto exit; + +free_vdev_priv: + qdf_mem_free(vdev_priv); + status = QDF_STATUS_E_INVAL; +exit: + return status; +} + +QDF_STATUS +ftm_timesync_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) +{ + struct ftm_timesync_vdev_priv *vdev_priv = NULL; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + vdev_priv = ftm_timesync_vdev_get_priv(vdev); + if (!vdev_priv) { + ftm_time_sync_err("vdev priv is NULL"); + goto exit; + } + + status = wlan_objmgr_vdev_component_obj_detach( + vdev, WLAN_UMAC_COMP_FTM_TIME_SYNC, + (void *)vdev_priv); + if (QDF_IS_STATUS_ERROR(status)) + ftm_time_sync_err("Failed to detach priv with vdev"); + + qdf_mem_free(vdev_priv); + vdev_priv = NULL; + +exit: + return status; +} diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/ftm_time_sync_ucfg_api.h b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/ftm_time_sync_ucfg_api.h new file mode 100644 index 0000000000000000000000000000000000000000..8f7169de34e5e473a0b25099c563e0f4b6e17270 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/ftm_time_sync_ucfg_api.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Declare public API related to the ftm timesync called by north bound + * HDD/OSIF/LIM + */ + +#ifndef _FTM_TIME_SYNC_UCFG_API_H_ +#define _FTM_TIME_SYNC_UCFG_API_H_ + +#include +#include +//#include "ftm_time_sync_public_struct.h" +#include "ftm_time_sync_objmgr.h" + +#ifdef FEATURE_WLAN_TIME_SYNC_FTM + +/** + * ucfg_ftm_timesync_init() - FTM time sync component initialization. + * + * This function initializes the ftm time sync component and registers + * the handlers which are invoked on vdev creation. + * + * Return: For successful registration - QDF_STATUS_SUCCESS, + * else QDF_STATUS error codes. + */ +QDF_STATUS ucfg_ftm_timesync_init(void); + +/** + * ucfg_ftm_timesync_deinit() - FTM time sync component deinit. + * + * This function deinits ftm time sync component. + * + * Return: None + */ +void ucfg_ftm_timesync_deinit(void); + +#else + +static inline +QDF_STATUS ucfg_ftm_timesync_init(void) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +void ucfg_ftm_timesync_deinit(void) +{ +} + +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ +#endif /* _FTM_TIME_SYNC_UCFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/wlan_ftm_time_sync_public_struct.h b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/wlan_ftm_time_sync_public_struct.h new file mode 100644 index 0000000000000000000000000000000000000000..6b1b5ba22f6cd6b4bcb70d3ebb166a7fd9257799 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/inc/wlan_ftm_time_sync_public_struct.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Declare various struct, macros which are used for obj mgmt in ftm time + * sync. + * + * Note: This file shall not contain public API's prototype/declarations. + * + */ + +#ifndef _WLAN_TIME_SYNC_FTM_PUBLIC_STRUCT_H_ +#define _WLAN_TIME_SYNC_FTM_PUBLIC_STRUCT_H_ + +/** + * struct wlan_ftm_timesync_tx_ops - structure of tx operation function + * pointers for ftm timesync component + * @ftm_time_sync_send_qtime: send qtime wmi cmd to FW + * @ftm_time_sync_send_trigger: send ftm time sync trigger cmd + * + */ +struct wlan_ftm_timesync_tx_ops { + QDF_STATUS (*ftm_time_sync_send_qtime)(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint64_t lpass_ts); + QDF_STATUS (*ftm_time_sync_send_trigger)(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, bool mode); +}; + +/** + * struct wlan_ftm_timesync_rx_ops - structure of rx operation function + * pointers for ftm timesync component + * @ftm_timesync_register_start_stop: register ftm timesync start stop event + * @ftm_timesync_regiser_master_slave_offset: register master slave qtime + * offset event + */ +struct wlan_ftm_timesync_rx_ops { + QDF_STATUS (*ftm_timesync_register_start_stop) + (struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*ftm_timesync_regiser_master_slave_offset) + (struct wlan_objmgr_psoc *psoc); +}; +#endif /*_WLAN_TIME_SYNC_FTM_PUBLIC_STRUCT_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/src/ftm_time_sync_ucfg_api.c b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/src/ftm_time_sync_ucfg_api.c new file mode 100644 index 0000000000000000000000000000000000000000..cd4412ca2ad586d68e0ebae74537f2c10be0dcb6 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/ftm_time_sync/dispatcher/src/ftm_time_sync_ucfg_api.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Public API implementation of ftm timesync called by north bound iface. + */ + +#include "ftm_time_sync_ucfg_api.h" +#include "ftm_time_sync_main.h" +#include + +QDF_STATUS ucfg_ftm_timesync_init(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_register_vdev_create_handler( + WLAN_UMAC_COMP_FTM_TIME_SYNC, + ftm_timesync_vdev_create_notification, NULL); + if (!QDF_IS_STATUS_SUCCESS(status)) { + ftm_time_sync_err("Failed to register vdev create handler"); + goto exit; + } + + status = wlan_objmgr_register_vdev_destroy_handler( + WLAN_UMAC_COMP_FTM_TIME_SYNC, + ftm_timesync_vdev_destroy_notification, NULL); + if (QDF_IS_STATUS_SUCCESS(status)) { + ftm_time_sync_debug("vdev create/delete notif registered"); + goto exit; + } + + ftm_time_sync_err("Failed to register vdev delete handler"); + wlan_objmgr_unregister_vdev_create_handler( + WLAN_UMAC_COMP_FTM_TIME_SYNC, + ftm_timesync_vdev_create_notification, NULL); + +exit: + return status; +} + +void ucfg_ftm_timesync_deinit(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_unregister_vdev_create_handler( + WLAN_UMAC_COMP_FTM_TIME_SYNC, + ftm_timesync_vdev_create_notification, NULL); + if (!QDF_IS_STATUS_SUCCESS(status)) + ftm_time_sync_err("Failed to unregister vdev create handler"); + + status = wlan_objmgr_unregister_vdev_destroy_handler( + WLAN_UMAC_COMP_FTM_TIME_SYNC, + ftm_timesync_vdev_destroy_notification, + NULL); + if (!QDF_IS_STATUS_SUCCESS(status)) + ftm_time_sync_err("Failed to unregister vdev delete handler"); +} diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/core/inc/wlan_fw_offload_main.h b/drivers/staging/qcacld-3.0/components/fw_offload/core/inc/wlan_fw_offload_main.h index db1c9db0596957a01a5b7f4957763966979656fb..6fb325ccfddf4667314b1d02c9b4a13551b7921b 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/core/inc/wlan_fw_offload_main.h +++ b/drivers/staging/qcacld-3.0/components/fw_offload/core/inc/wlan_fw_offload_main.h @@ -37,6 +37,17 @@ #define fwol_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_FWOL, params) #define fwol_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_FWOL, params) +#define fwol_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_FWOL, params) +#define fwol_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_FWOL, params) +#define fwol_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_FWOL, params) +#define fwol_nofl_info(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_FWOL, params) +#define fwol_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_FWOL, params) + /** * enum wlan_fwol_southbound_event - fw offload south bound event type * @WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE: get eLNA bypass response @@ -62,6 +73,10 @@ enum wlan_fwol_southbound_event { * @bt_interference_high_ll: Lower limit of high level BT interference * @bt_interference_high_ul: Upper limit of high level BT interference * @btc_mpta_helper_enable: Enable/Disable tri-radio MPTA helper + * @bt_sco_allow_wlan_2g_scan: Enable/Disble wlan 2g scan when + * BT SCO connection is on + * @btc_three_way_coex_config_legacy_enable: Enable/Disable tri-radio coex + * config legacy feature */ struct wlan_fwol_coex_config { uint8_t btc_mode; @@ -77,6 +92,10 @@ struct wlan_fwol_coex_config { int16_t bt_interference_high_ul; #ifdef FEATURE_MPTA_HELPER bool btc_mpta_helper_enable; +#endif + bool bt_sco_allow_wlan_2g_scan; +#ifdef FEATURE_COEX_CONFIG + bool btc_three_way_coex_config_legacy_enable; #endif }; @@ -158,6 +177,7 @@ struct wlan_fwol_neighbor_report_cfg { * @neighbor_report_cfg: 11K neighbor report config * @ani_enabled: ANI enable/disable * @enable_rts_sifsbursting: Enable RTS SIFS Bursting + * @enable_sifs_burst: Enable SIFS burst * @max_mpdus_inampdu: Max number of MPDUS * @enable_phy_reg_retention: Enable PHY reg retention * @upper_brssi_thresh: Upper BRSSI threshold @@ -169,11 +189,14 @@ struct wlan_fwol_neighbor_report_cfg { * @enable_fw_log_level: Set the FW log level * @enable_fw_log_type: Set the FW log type * @enable_fw_module_log_level: enable fw module log level - * @enable_fw_module_log_level_num: enablefw module log level num + * @enable_fw_module_log_level_num: enable fw module log level num + * @enable_fw_mod_wow_log_level: enable fw wow module log level + * @enable_fw_mod_wow_log_level_num: enable fw wow module log level num * @sap_xlna_bypass: bypass SAP xLNA * @is_rate_limit_enabled: Enable/disable RA rate limited * @tsf_gpio_pin: TSF GPIO Pin config * @tsf_irq_host_gpio_pin: TSF GPIO Pin config + * @tsf_sync_host_gpio_pin: TSF Sync GPIO Pin config * @tsf_ptp_options: TSF Plus feature options config * @lprx_enable: LPRx feature enable config * @sae_enable: SAE feature enable config @@ -193,6 +216,7 @@ struct wlan_fwol_cfg { struct wlan_fwol_neighbor_report_cfg neighbor_report_cfg; bool ani_enabled; bool enable_rts_sifsbursting; + uint8_t enable_sifs_burst; uint8_t max_mpdus_inampdu; uint8_t enable_phy_reg_retention; uint16_t upper_brssi_thresh; @@ -205,6 +229,8 @@ struct wlan_fwol_cfg { uint16_t enable_fw_log_type; uint8_t enable_fw_module_log_level[FW_MODULE_LOG_LEVEL_STRING_LENGTH]; uint8_t enable_fw_module_log_level_num; + uint8_t enable_fw_mod_wow_log_level[FW_MODULE_LOG_LEVEL_STRING_LENGTH]; + uint8_t enable_fw_mod_wow_log_level_num; bool sap_xlna_bypass; #ifdef FEATURE_WLAN_RA_FILTERING bool is_rate_limit_enabled; @@ -216,6 +242,9 @@ struct wlan_fwol_cfg { #ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ uint32_t tsf_irq_host_gpio_pin; #endif +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC + uint32_t tsf_sync_host_gpio_pin; +#endif #endif #endif bool lprx_enable; diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/core/src/wlan_fw_offload_main.c b/drivers/staging/qcacld-3.0/components/fw_offload/core/src/wlan_fw_offload_main.c index ffca9378801409a22504d56e733f58842337d669..e114752ccb9376deed5f4bdc45bcbe604057a6bb 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/core/src/wlan_fw_offload_main.c +++ b/drivers/staging/qcacld-3.0/components/fw_offload/core/src/wlan_fw_offload_main.c @@ -53,6 +53,32 @@ fwol_mpta_helper_config_get(struct wlan_objmgr_psoc *psoc, } #endif +/** + * fwol_three_way_coex_config_legacy_config_get: Populate + * btc_three_way_coex_config_legacy_enable from cfg + * @psoc: The global psoc handler + * @coex_config: The cfg structure + * + * Return: none + */ +#ifdef FEATURE_COEX_CONFIG +static void +fwol_three_way_coex_config_legacy_config_get( + struct wlan_objmgr_psoc *psoc, + struct wlan_fwol_coex_config *coex_config) +{ + coex_config->btc_three_way_coex_config_legacy_enable = + cfg_get(psoc, CFG_THREE_WAY_COEX_CONFIG_LEGACY); +} +#else +static void +fwol_three_way_coex_config_legacy_config_get( + struct wlan_objmgr_psoc *psoc, + struct wlan_fwol_coex_config *coex_config) +{ +} +#endif + static void fwol_init_coex_config_in_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_fwol_coex_config *coex_config) @@ -78,6 +104,9 @@ fwol_init_coex_config_in_cfg(struct wlan_objmgr_psoc *psoc, coex_config->bt_interference_high_ul = cfg_get(psoc, CFG_BT_INTERFERENCE_HIGH_UL); fwol_mpta_helper_config_get(psoc, coex_config); + coex_config->bt_sco_allow_wlan_2g_scan = + cfg_get(psoc, CFG_BT_SCO_ALLOW_WLAN_2G_SCAN); + fwol_three_way_coex_config_legacy_config_get(psoc, coex_config); } static void @@ -389,6 +418,33 @@ ucfg_fwol_fetch_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc, { } #endif + +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +/** + * ucfg_fwol_fetch_tsf_sync_host_gpio_pin: Populate the + * tsf_sync_host_gpio_pin from cfg + * @psoc: The global psoc handler + * @fwol_cfg: The cfg structure + * + * This function is used to populate the cfg value of host platform + * gpio pin configured to drive tsf sync interrupt pin on wlan chip. + * + * Return: none + */ +static void +ucfg_fwol_fetch_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc, + struct wlan_fwol_cfg *fwol_cfg) +{ + fwol_cfg->tsf_sync_host_gpio_pin = + cfg_get(psoc, CFG_SET_TSF_SYNC_HOST_GPIO_PIN); +} +#else +static void +ucfg_fwol_fetch_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc, + struct wlan_fwol_cfg *fwol_cfg) +{ +} +#endif /** * ucfg_fwol_init_sae_cfg: Populate the sae control config from cfg * @psoc: The global psoc handler @@ -435,6 +491,7 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) struct wlan_fwol_psoc_obj *fwol_obj; struct wlan_fwol_cfg *fwol_cfg; qdf_size_t enable_fw_module_log_level_num; + qdf_size_t enable_fw_wow_mod_log_level_num; fwol_obj = fwol_get_psoc_obj(psoc); if (!fwol_obj) { @@ -451,6 +508,7 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) fwol_cfg->ani_enabled = cfg_get(psoc, CFG_ENABLE_ANI); fwol_cfg->enable_rts_sifsbursting = cfg_get(psoc, CFG_SET_RTS_FOR_SIFS_BURSTING); + fwol_cfg->enable_sifs_burst = cfg_get(psoc, CFG_SET_SIFS_BURST); fwol_cfg->max_mpdus_inampdu = cfg_get(psoc, CFG_MAX_MPDUS_IN_AMPDU); fwol_cfg->enable_phy_reg_retention = cfg_get(psoc, CFG_ENABLE_PHY_REG); fwol_cfg->upper_brssi_thresh = cfg_get(psoc, CFG_UPPER_BRSSI_THRESH); @@ -470,6 +528,12 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) &enable_fw_module_log_level_num); fwol_cfg->enable_fw_module_log_level_num = (uint8_t)enable_fw_module_log_level_num; + qdf_uint8_array_parse(cfg_get(psoc, CFG_ENABLE_FW_WOW_MODULE_LOG_LEVEL), + fwol_cfg->enable_fw_mod_wow_log_level, + FW_MODULE_LOG_LEVEL_STRING_LENGTH, + &enable_fw_wow_mod_log_level_num); + fwol_cfg->enable_fw_mod_wow_log_level_num = + (uint8_t)enable_fw_wow_mod_log_level_num; ucfg_fwol_init_tsf_ptp_options(psoc, fwol_cfg); ucfg_fwol_init_sae_cfg(psoc, fwol_cfg); fwol_cfg->lprx_enable = cfg_get(psoc, CFG_LPRX); @@ -481,6 +545,7 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) ucfg_fwol_fetch_ra_filter(psoc, fwol_cfg); ucfg_fwol_fetch_tsf_gpio_pin(psoc, fwol_cfg); ucfg_fwol_fetch_tsf_irq_host_gpio_pin(psoc, fwol_cfg); + ucfg_fwol_fetch_tsf_sync_host_gpio_pin(psoc, fwol_cfg); ucfg_fwol_fetch_dhcp_server_settings(psoc, fwol_cfg); fwol_cfg->sap_xlna_bypass = cfg_get(psoc, CFG_SET_SAP_XLNA_BYPASS); fwol_cfg->disable_hw_assist = cfg_get(psoc, CFG_DISABLE_HW_ASSIST); diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_coex.h b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_coex.h index dcac2bf3aefa27fea433ba13ae0889259ec11e5c..c3b665b3f06a0fbfacc9d3c4fbe7306d9f12c619 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_coex.h +++ b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_coex.h @@ -260,6 +260,59 @@ #define COEX_MPTA_HELPER_CFG #endif +/* + * + * gBtScoAllowWlan2GScan - Allow wlan 2g scan when BT SCO connection is on + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * 0 - Disable + * 1 - Enable + * + * This ini is used to enable or disable wlan 2g scan + * when BT SCO connection is on. + * + * Usage: External + * + * + */ +#define CFG_BT_SCO_ALLOW_WLAN_2G_SCAN CFG_INI_BOOL( \ + "gBtScoAllowWlan2GScan", \ + 1, \ + "Bt Sco Allow Wlan 2G Scan") + +#ifdef FEATURE_COEX_CONFIG +/* + * + * gThreeWayCoexConfigLegacyEnable - Enable coex config legacy feature + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable or disable three way coex config legacy feature. + * This feature is designed only for non-mobile solution. + * When the feature is disabled, Firmware use the default configuration to + * set the coex priority of three antenna(WLAN, BT, ZIGBEE). + * when enable this feature, customer can use the vendor command to set antenna + * coex priority dynamically. + * + * Supported Feature: three way coex config + * + * Usage: External + * + * + */ +#define CFG_THREE_WAY_COEX_CONFIG_LEGACY CFG_INI_BOOL( \ + "gThreeWayCoexConfigLegacyEnable", \ + 0, \ + "Enable/Disable COEX Config Legacy") + +#define THREE_WAY_COEX_CONFIG_LEGACY_CFG CFG(CFG_THREE_WAY_COEX_CONFIG_LEGACY) +#else +#define THREE_WAY_COEX_CONFIG_LEGACY_CFG +#endif + #define CFG_COEX_ALL \ CFG(CFG_BTC_MODE) \ CFG(CFG_ANTENNA_ISOLATION) \ @@ -272,5 +325,7 @@ CFG(CFG_BT_INTERFERENCE_MEDIUM_UL) \ CFG(CFG_BT_INTERFERENCE_HIGH_LL) \ CFG(CFG_BT_INTERFERENCE_HIGH_UL) \ - COEX_MPTA_HELPER_CFG + COEX_MPTA_HELPER_CFG \ + CFG(CFG_BT_SCO_ALLOW_WLAN_2G_SCAN) \ + THREE_WAY_COEX_CONFIG_LEGACY_CFG #endif diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h index 2a04a5e762a868f9401591562fa6a64d9c00f11f..b4dc29f33b7eec9235a2c2727c9611aab4091406 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h +++ b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/cfg_fwol_generic.h @@ -65,6 +65,38 @@ 0, \ "Set rts for sifs bursting") +/* + * + * sifs_burst_mask - Set sifs burst mask + * @Min: 0 + * @Max: 3 + * @Default: 1 + * + * This ini is used to set 11n and legacy(non 11n/wmm) + * sifs burst. Especially under running multi stream + * traffic test case, it can be useful to let the low + * priority AC, or legacy mode device, or the specified + * AC to aggressively contend air medium, then have a + * obvious improvement of throughput. Bit0 is the switch + * of sifs burst, it must be set if want to enable sifs + * burst, Bit1 is for legacy mode. + * Supported configuration: + * 0: disabled + * 1: enabled, but disabled for legacy mode + * 3: all enabled + * + * Usage: External + * + * + */ +#define CFG_SET_SIFS_BURST CFG_INI_UINT( \ + "sifs_burst_mask", \ + 0, \ + 3, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Set SIFS burst mask") + /* * * gMaxMPDUsInAMPDU - max mpdus in ampdu @@ -358,10 +390,48 @@ "gFwDebugModuleLoglevel", \ 0, \ FW_MODULE_LOG_LEVEL_STRING_LENGTH, \ - "2,1,3,1,5,1,9,1,13,1,14,1,18,1,19,1,26,1,28,1,29,1,31,1,36,1,38,1,"\ - "46,1,47,1,50,1,52,1,53,1,56,1,60,1,61,1,4,1", \ + "1,1,2,1,3,1,4,1,5,1,8,1,9,1,13,1,14,1,17,1,18,1,19,1,22,1,26,1,28,1," \ + "29,1,31,1,36,1,38,1,46,1,47,1,50,1,52,1,53,1,56,1,60,1,61,1", \ "Set modulized firmware debug log level") +/* + * + * gFwDebugWowModuleLoglevel - modulized firmware wow debug log level + * @Min: N/A + * @Max: N/A + * @Default: N/A + * + * This ini is used to set modulized firmware wow debug log level. + * FW module log level input string format looks like below: + * gFwDebugWowModuleLoglevel=",,..." + * For example: + * gFwDebugWowModuleLoglevel="1,0,2,1,3,2,4,3,5,4,6,5,7,6" + * The above input string means: + * For FW module ID 1 enable log level 0 + * For FW module ID 2 enable log level 1 + * For FW module ID 3 enable log level 2 + * For FW module ID 4 enable log level 3 + * For FW module ID 5 enable log level 4 + * For FW module ID 6 enable log level 5 + * For FW module ID 7 enable log level 6 + * For valid values of log levels check enum DBGLOG_LOG_LVL and + * for valid values of module ids check enum WLAN_MODULE_ID. + * + * Related: None + * + * Supported Feature: Debugging + * + * Usage: External + * + * + */ +#define CFG_ENABLE_FW_WOW_MODULE_LOG_LEVEL CFG_INI_STRING( \ + "gFwDebugWowModuleLoglevel", \ + 0, \ + FW_MODULE_LOG_LEVEL_STRING_LENGTH, \ + "5,3,18,3,31,3,36,3", \ + "Set modulized firmware wow debug log level") + #ifdef FEATURE_WLAN_RA_FILTERING /* * gRAFilterEnable @@ -433,6 +503,40 @@ #define __CFG_SET_TSF_IRQ_HOST_GPIO_PIN #endif +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +/* + * + * gtsf_sync_host_gpio_pin + * @Min: 0 + * @Max: 254 + * @Default: 255 + * + * TSF sync GPIO pin of host platform + * + * The driver will use this gpio on host platform + * to drive the TSF sync pin on wlan chip. + * Toggling this gpio will generate a strobe to fw + * for latching TSF. + * + * Related: None + * + * Usage: External + * + * + */ +#define CFG_SET_TSF_SYNC_HOST_GPIO_PIN CFG_INI_UINT( \ + "gtsf_sync_host_gpio_pin", \ + 0, \ + 254, \ + 255, \ + CFG_VALUE_OR_DEFAULT, \ + "TSF sync GPIO pin of host platform") + +#define __CFG_SET_TSF_SYNC_HOST_GPIO_PIN CFG(CFG_SET_TSF_SYNC_HOST_GPIO_PIN) +#else +#define __CFG_SET_TSF_SYNC_HOST_GPIO_PIN +#endif + #if defined(WLAN_FEATURE_TSF) && defined(WLAN_FEATURE_TSF_PLUS) /* * gtsf_ptp_options: TSF Plus feature options @@ -687,6 +791,7 @@ CFG_FWOL_DHCP \ CFG(CFG_ENABLE_ANI) \ CFG(CFG_SET_RTS_FOR_SIFS_BURSTING) \ + CFG(CFG_SET_SIFS_BURST) \ CFG(CFG_MAX_MPDUS_IN_AMPDU) \ CFG(CFG_ENABLE_PHY_REG) \ CFG(CFG_UPPER_BRSSI_THRESH) \ @@ -701,6 +806,7 @@ CFG(CFG_RA_FILTER_ENABLE) \ CFG(CFG_SET_TSF_GPIO_PIN) \ __CFG_SET_TSF_IRQ_HOST_GPIO_PIN \ + __CFG_SET_TSF_SYNC_HOST_GPIO_PIN \ __CFG_SET_TSF_PTP_OPT \ CFG(CFG_LPRX) \ __CFG_IS_SAE_ENABLED \ @@ -708,6 +814,7 @@ CFG(CFG_TX_SCH_DELAY) \ CFG(CFG_ENABLE_SECONDARY_RATE) \ CFG(CFG_SET_SAP_XLNA_BYPASS) \ + CFG(CFG_ENABLE_FW_WOW_MODULE_LOG_LEVEL) \ CFG(CFG_DISABLE_HW_ASSIST) #endif diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h index 1ec3b4ed2fc78bd51cb779868a22f03e7b8a0fb0..21f62083721482eff8b0d231cf7abbe9c5096e69 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h @@ -160,6 +160,16 @@ QDF_STATUS ucfg_fwol_get_ani_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc, bool *enable_rts_sifsbursting); +/** + * ucfg_get_enable_sifs_burst() - Get the enable_sifs_burst value + * @psoc: pointer to the psoc object + * @enable_sifs_burst: pointer to return enable_sifs_burst value + * + * Return: QDF Status + */ +QDF_STATUS ucfg_get_enable_sifs_burst(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sifs_burst); + /** * ucfg_get_max_mpdus_inampdu() - Assigns the max_mpdus_inampdu value * @psoc: pointer to the psoc object @@ -257,7 +267,7 @@ QDF_STATUS ucfg_fwol_get_enable_fw_log_type(struct wlan_objmgr_psoc *psoc, * @enable_fw_module_log_level: * pointer to enable_fw_module_log_level array * @enable_fw_module_log_level_num: - * pointer to enable_fw_module_log_leve array element num + * pointer to enable_fw_module_log_level array element num * * Return: QDF Status */ @@ -266,6 +276,23 @@ QDF_STATUS ucfg_fwol_get_enable_fw_module_log_level( uint8_t **enable_fw_module_log_level, uint8_t *enable_fw_module_log_level_num); +/** + * ucfg_fwol_wow_get_enable_fw_module_log_level() - Assigns + * enable_fw_module_log_level string + * + * @psoc: pointer to the psoc object + * @enable_fw_wow_module_log_level: + * pointer to enable_fw_wow_module_log_level array + * @enable_fw_wow_module_log_level_num: + * pointer to enable_fw_wow_module_log_level array element num + * + * Return: QDF Status + */ +QDF_STATUS ucfg_fwol_wow_get_enable_fw_module_log_level( + struct wlan_objmgr_psoc *psoc, + uint8_t **enable_fw_wow_module_log_level, + uint8_t *enable_fw_wow_module_log_level_num); + /** * ucfg_fwol_get_sap_xlna_bypass() - Assigns sap_xlna_bypass value * @psoc: pointer to the psoc object @@ -320,6 +347,19 @@ ucfg_fwol_get_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc, uint32_t *tsf_irq_host_gpio_pin); #endif +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +/** + * ucfg_fwol_get_tsf_sync_host_gpio_pin() - Assigns tsf_sync_host_gpio_pin value + * @psoc: pointer to the psoc object + * + * Return: QDF Status + */ + +QDF_STATUS +ucfg_fwol_get_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc, + uint32_t *tsf_irq_host_gpio_pin); +#endif + #ifdef DHCP_SERVER_OFFLOAD /** * ucfg_fwol_get_enable_dhcp_server_offload()-Assign enable_dhcp_server_offload diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c index 37b66645c15adad52e687a46c4ac6e65a29800f7..a8f88506b934321d8b2f4d215476c49c0d3c46c6 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c +++ b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c @@ -178,6 +178,9 @@ QDF_STATUS tgt_fwol_pdev_param_send(struct wlan_objmgr_pdev *pdev, { struct wmi_unified *wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); + if (!wmi_handle) + return QDF_STATUS_E_FAILURE; + return wmi_unified_pdev_param_send(wmi_handle, &pdev_param, FWOL_WILDCARD_PDEV_ID); } diff --git a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c index ab6ecaefc3a4e87cb6551641f5b79e6ac4281695..4c035117a08f7c0d76dfbb47a7230c0935df4024 100644 --- a/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c @@ -72,6 +72,7 @@ fwol_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, void *arg) if (QDF_IS_STATUS_ERROR(status)) { fwol_err("Failed to attach psoc_ctx with psoc"); qdf_mem_free(fwol_obj); + return status; } tgt_fwol_register_rx_ops(&fwol_obj->rx_ops); @@ -316,6 +317,21 @@ QDF_STATUS ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_get_enable_sifs_burst(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sifs_burst) +{ + struct wlan_fwol_psoc_obj *fwol_obj; + + fwol_obj = fwol_get_psoc_obj(psoc); + if (!fwol_obj) { + fwol_err("Failed to get FWOL obj"); + return QDF_STATUS_E_FAILURE; + } + + *enable_sifs_burst = fwol_obj->cfg.enable_sifs_burst; + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_get_max_mpdus_inampdu(struct wlan_objmgr_psoc *psoc, uint8_t *max_mpdus_inampdu) { @@ -504,6 +520,26 @@ QDF_STATUS ucfg_fwol_get_enable_fw_module_log_level( return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_fwol_wow_get_enable_fw_module_log_level( + struct wlan_objmgr_psoc *psoc, + uint8_t **enable_fw_wow_module_log_level, + uint8_t *enable_fw_wow_module_log_level_num) +{ + struct wlan_fwol_psoc_obj *fwol_obj; + + fwol_obj = fwol_get_psoc_obj(psoc); + if (!fwol_obj) { + fwol_err("Failed to get FWOL obj"); + return QDF_STATUS_E_FAILURE; + } + + *enable_fw_wow_module_log_level = + fwol_obj->cfg.enable_fw_mod_wow_log_level; + *enable_fw_wow_module_log_level_num = + fwol_obj->cfg.enable_fw_mod_wow_log_level_num; + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_fwol_get_sap_xlna_bypass(struct wlan_objmgr_psoc *psoc, bool *sap_xlna_bypass) { @@ -604,6 +640,27 @@ ucfg_fwol_get_tsf_irq_host_gpio_pin(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#endif + +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +QDF_STATUS +ucfg_fwol_get_tsf_sync_host_gpio_pin(struct wlan_objmgr_psoc *psoc, + uint32_t *tsf_sync_host_gpio_pin) +{ + struct wlan_fwol_psoc_obj *fwol_obj; + + fwol_obj = fwol_get_psoc_obj(psoc); + if (!fwol_obj) { + fwol_err("Failed to get FWOL obj"); + *tsf_sync_host_gpio_pin = + cfg_default(CFG_SET_TSF_SYNC_HOST_GPIO_PIN); + return QDF_STATUS_E_FAILURE; + } + + *tsf_sync_host_gpio_pin = fwol_obj->cfg.tsf_sync_host_gpio_pin; + return QDF_STATUS_SUCCESS; +} + #endif #endif #else diff --git a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h index 2afd61c0974b5c87cd05ab810b906e8f966a36f5..b4332c8f0a4ca0d382e1a067d4c0da54034d2dfe 100644 --- a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h +++ b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -31,10 +31,12 @@ /** * struct wlan_interop_issues_ap_info - interop issues ap info + * @detect_enable: the flag to enable detect issue ap * @count: the number of interop issues ap * @rap_items: interop issues ap items */ struct wlan_interop_issues_ap_info { + bool detect_enable; uint32_t count; struct qdf_mac_addr rap_items[MAX_INTEROP_ISSUES_AP_NUM]; }; diff --git a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h index 4d9508712e5ca6ba950b81b69b9c1b8dc0544c29..ce90efdf56f36d69c7be2423b4ed22fc5a9aa477 100644 --- a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -71,12 +71,12 @@ void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev, /** * ucfg_set_interop_issues_ap_config() - API to set interop issues ap - * @vdev: the pointer of vdev object + * @psoc: the pointer of psoc object * @rap: the pointer of interop issues ap info * * Return: none */ -QDF_STATUS ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev, +QDF_STATUS ucfg_set_interop_issues_ap_config(struct wlan_objmgr_psoc *psoc, struct wlan_interop_issues_ap_info *rap); #else static inline diff --git a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c index e53524cbcfbe6870b90470a0ae29f1ddb96001d3..d40611e49383bd2c92dca540e68c1c2f0b19568d 100644 --- a/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,10 +26,10 @@ #include QDF_STATUS -ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev, +ucfg_set_interop_issues_ap_config(struct wlan_objmgr_psoc *psoc, struct wlan_interop_issues_ap_info *rap) { - return tgt_set_interop_issues_ap_req(wlan_vdev_get_psoc(vdev), rap); + return tgt_set_interop_issues_ap_req(psoc, rap); } void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev, diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_core.h b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_core.h index f880811c9dbca18fda828baa42a6007ead54d972..8b88b6921d912d412a368d0810d742881f501020 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_core.h +++ b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -349,7 +349,7 @@ bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx) #ifdef FEATURE_METERING -#ifndef QCA_WIFI_QCA6390 +#ifndef WDI3_STATS_UPDATE /** * wlan_ipa_uc_op_metering() - IPA uC operation for stats and quota limit * @ipa_ctx: IPA context @@ -393,6 +393,8 @@ void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx); /** * wlan_ipa_update_tx_stats() - send embedded tx traffic in bytes to IPA * @ipa_ctx: IPA context + * @sta_tx: tx in bytes on sta interface + * @sap_tx: tx in bytes on sap interface * * Return: void */ @@ -552,6 +554,82 @@ void wlan_ipa_reg_send_to_nw_cb(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->send_to_nw = cb; } +#ifdef IPA_LAN_RX_NAPI_SUPPORT +/** + * wlan_ipa_reg_rps_enable_cb() - Register callback to enable RPS + * @ipa_ctx: IPA context + * @cb: callback + * + * Return: None + */ +static inline +void wlan_ipa_reg_rps_enable_cb(struct wlan_ipa_priv *ipa_ctx, + wlan_ipa_rps_enable cb) +{ + ipa_ctx->rps_enable = cb; +} + +/** + * ipa_set_rps_enable(): Enable/disable RPS for all interfaces of specific mode + * @ipa_ctx: IPA context + * @mode: mode of interface for which RPS needs to be enabled + * @enable: Set true to enable RPS + * + * Return: None + */ +void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode, + bool enable); + +/** + * ipa_set_rps_per_vdev(): Enable/disable RPS for a specific vdev + * @ipa_ctx: IPA context + * @vdev_id: vdev id for which RPS needs to be enabled + * @enable: Set true to enable RPS + * + * Return: None + */ +static inline +void ipa_set_rps_per_vdev(struct wlan_ipa_priv *ipa_ctx, uint8_t vdev_id, + bool enable) +{ + if (ipa_ctx->rps_enable) + ipa_ctx->rps_enable(vdev_id, enable); +} + +/** + * wlan_ipa_handle_multiple_sap_evt() - Handle multiple SAP connect/disconnect + * @ipa_ctx: IPA global context + * @type: IPA event type. + * + * This function is used to disable pipes when multiple SAP are connected and + * enable pipes back when only one SAP is connected. + * + * Return: None + */ +void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx, + qdf_ipa_wlan_event type); + +#else +static inline +void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode, + bool enable) +{ +} + +static inline +void ipa_set_rps_per_vdev(struct wlan_ipa_priv *ipa_ctx, uint8_t vdev_id, + bool enable) +{ +} + +static inline +void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx, + qdf_ipa_wlan_event type) +{ +} + +#endif + /** * wlan_ipa_set_mcc_mode() - Set MCC mode * @ipa_ctx: IPA context @@ -659,7 +737,6 @@ static inline void wlan_ipa_mcc_work_handler(void *data) * wlan_ipa_wlan_evt() - IPA event handler * @net_dev: Interface net device * @device_mode: Net interface device mode - * @sta_id: station id for the event * @session_id: session id for the event * @type: event enum of type ipa_wlan_event * @mac_address: MAC address associated with the event @@ -667,7 +744,7 @@ static inline void wlan_ipa_mcc_work_handler(void *data) * Return: QDF_STATUS */ QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr); diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_main.h b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_main.h index 5cd4a53064095c06c5c6943e6f7951a1c2c9cd0b..1e066f8f227e989666e985bc1bbd8fbf48d526b4 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_main.h +++ b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_main.h @@ -164,13 +164,13 @@ QDF_STATUS ipa_send_uc_offload_enable_disable(struct wlan_objmgr_pdev *pdev, void ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_soc); /** - * ipa_set_txrx_handle() - set dp txrx handle + * ipa_set_pdev_id() - set dp pdev id * @psoc: psoc handle - * @txrx_handle: dp txrx handle + * @pdev_id: dp txrx physical device id * * Return: None */ -void ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, void *txrx_handle); +void ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id); /** * ipa_rm_set_perf_level() - set ipa rm perf level @@ -256,6 +256,18 @@ void ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, wlan_ipa_send_to_nw cb); +#ifdef IPA_LAN_RX_NAPI_SUPPORT +/** + * ipa_reg_rps_enable_cb() - Register cb to enable RPS + * @pdev: pdev obj + * @cb: callback + * + * Return: None + */ +void ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb); +#endif + /** * ipa_set_mcc_mode() - Set MCC mode * @pdev: pdev obj @@ -356,7 +368,6 @@ QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, * @pdev: pdev obj * @net_dev: Interface net device * @device_mode: Net interface device mode - * @sta_id: station id for the event * @session_id: session id for the event * @type: event enum of type ipa_wlan_event * @mac_address: MAC address associated with the event @@ -364,7 +375,7 @@ QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, * Return: QDF_STATUS */ QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, - uint8_t device_mode, uint8_t sta_id, uint8_t session_id, + uint8_t device_mode, uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr); @@ -476,6 +487,7 @@ void ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev, #else /* Not IPA_OFFLOAD */ typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev); typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev); +typedef void (*wlan_ipa_rps_enable)(uint8_t vdev_id, bool enable); #endif /* IPA_OFFLOAD */ #endif /* end of _WLAN_IPA_MAIN_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_priv.h b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_priv.h index f9a83f6bb07ad7abde8bee47cb23170bc2816247..d3555b5e442bc4d51d6a29aa53a4000afe7d0aa6 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_priv.h +++ b/drivers/staging/qcacld-3.0/components/ipa/core/inc/wlan_ipa_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -52,7 +52,8 @@ #define WLAN_IPA_UC_RT_DEBUG_FILL_INTERVAL 10000 #define WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET 0 -#define WLAN_IPA_MAX_IFACE 3 +#define WLAN_IPA_MAX_IFACE MAX_IPA_IFACE +#define WLAN_IPA_CLIENT_MAX_IFACE 3 #define WLAN_IPA_MAX_SYSBAM_PIPE 4 #define WLAN_IPA_MAX_SESSION 5 #define WLAN_IPA_MAX_STA_COUNT 41 @@ -185,7 +186,8 @@ struct wlan_ipa_tx_hdr { * @reserved1: Reserved not used * @reserved2: Reserved not used */ -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) struct frag_header { uint8_t reserved[0]; }; @@ -210,7 +212,8 @@ struct frag_header { * @reserved: Reserved not used */ -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) struct ipa_header { uint8_t reserved[0]; }; @@ -307,14 +310,12 @@ struct wlan_ipa_priv; /** * struct wlan_ipa_iface_context - IPA interface context * @ipa_ctx: IPA private context - * @tl_context: TL context * @cons_client: IPA consumer pipe * @prod_client: IPA producer pipe * @prod_client: IPA producer pipe * @iface_id: IPA interface ID * @dev: Net device structure * @device_mode: Interface device mode - * @sta_id: Interface station ID * @session_id: Session ID * @interface_lock: Interface lock * @ifa_address: Interface address @@ -323,7 +324,6 @@ struct wlan_ipa_priv; */ struct wlan_ipa_iface_context { struct wlan_ipa_priv *ipa_ctx; - void *tl_context; qdf_ipa_client_type_t cons_client; qdf_ipa_client_type_t prod_client; @@ -331,7 +331,6 @@ struct wlan_ipa_iface_context { uint8_t iface_id; /* This iface ID */ qdf_netdev_t dev; enum QDF_OPMODE device_mode; - uint8_t sta_id; /* This iface station ID */ uint8_t session_id; qdf_spinlock_t interface_lock; uint32_t ifa_address; @@ -356,6 +355,7 @@ struct wlan_ipa_iface_context { * @num_tx_dequeued: Number of TX dequeued * @num_max_pm_queue: Number of packets in PM queue * @num_rx_excep: Number of RX IPA exception packets + * @num_rx_no_iface_eapol: No of EAPOL pkts before iface setup * @num_tx_fwd_ok: Number of TX forward packet success * @num_tx_fwd_err: Number of TX forward packet failures */ @@ -376,6 +376,7 @@ struct wlan_ipa_stats { uint64_t num_tx_dequeued; uint64_t num_max_pm_queue; uint64_t num_rx_excep; + uint64_t num_rx_no_iface_eapol; uint64_t num_tx_fwd_ok; uint64_t num_tx_fwd_err; }; @@ -383,12 +384,10 @@ struct wlan_ipa_stats { /** * struct ipa_uc_stas_map - IPA UC assoc station map * @is_reserved: STA reserved flag - * @sta_id: Station ID * @mac_addr: Station mac address */ struct ipa_uc_stas_map { bool is_reserved; - uint8_t sta_id; struct qdf_mac_addr mac_addr; }; @@ -464,7 +463,6 @@ struct ipa_uc_fw_stats { * @node: Pending event list node * @type: WLAN IPA event type * @device_mode: Device mode - * @sta_id: Station ID * @session_id: Session ID * @mac_addr: Mac address * @is_loading: Driver loading flag @@ -474,7 +472,6 @@ struct wlan_ipa_uc_pending_event { qdf_ipa_wlan_event type; qdf_netdev_t net_dev; uint8_t device_mode; - uint8_t sta_id; uint8_t session_id; uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; bool is_loading; @@ -587,6 +584,13 @@ struct wlan_ipa_tx_desc { typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev); typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev); +/** + * typedef wlan_ipa_rps_enable - Enable/disable RPS for adapter using vdev id + * @vdev_id: vdev_id of adapter + * @enable: Set true to enable RPS + */ +typedef void (*wlan_ipa_rps_enable)(uint8_t vdev_id, bool enable); + /* IPA private context structure definition */ struct wlan_ipa_priv { struct wlan_objmgr_pdev *pdev; @@ -594,7 +598,7 @@ struct wlan_ipa_priv { struct wlan_ipa_iface_context iface_context[WLAN_IPA_MAX_IFACE]; uint8_t num_iface; void *dp_soc; - void *dp_pdev; + uint8_t dp_pdev_id; struct wlan_ipa_config *config; enum wlan_ipa_rm_state rm_state; /* @@ -643,6 +647,7 @@ struct wlan_ipa_priv { uint32_t curr_cons_bw; uint8_t activated_fw_pipe; + uint8_t num_sap_connected; uint8_t sap_num_connected_sta; uint8_t sta_connected; uint32_t tx_pipe_handle; @@ -693,6 +698,11 @@ struct wlan_ipa_priv { wlan_ipa_send_to_nw send_to_nw; ipa_uc_offload_control_req ipa_tx_op; +#ifdef IPA_LAN_RX_NAPI_SUPPORT + /*Callback to enable RPS for STA in STA+SAP scenario*/ + wlan_ipa_rps_enable rps_enable; +#endif + qdf_event_t ipa_resource_comp; uint32_t wdi_version; @@ -723,9 +733,6 @@ struct wlan_ipa_priv { #define BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) -#define WLAN_IPA_DBG_DUMP_RX_LEN 84 -#define WLAN_IPA_DBG_DUMP_TX_LEN 48 - #define IPA_RESOURCE_COMP_WAIT_TIME 500 #ifdef FEATURE_METERING diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_core.c b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_core.c index e69461266ca419681fc1b0d4b7fb14a17c4b9aec..971f66f33f79a87d2dbcd4a9c9f1f9a71ead7762 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_core.c +++ b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -19,6 +19,7 @@ /* Include Files */ #include "wlan_ipa_core.h" #include "wlan_ipa_main.h" +#include "wlan_hdd_main.h" #include #include "cdp_txrx_ipa.h" #include "wal_rx_desc.h" @@ -36,7 +37,7 @@ static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx); static struct wlan_ipa_iface_2_client { qdf_ipa_client_type_t cons_client; qdf_ipa_client_type_t prod_client; -} wlan_ipa_iface_2_client[WLAN_IPA_MAX_IFACE] = { +} wlan_ipa_iface_2_client[WLAN_IPA_CLIENT_MAX_IFACE] = { { QDF_IPA_CLIENT_WLAN2_CONS, QDF_IPA_CLIENT_WLAN1_PROD }, { @@ -149,11 +150,11 @@ static void wlan_ipa_uc_loaded_uc_cb(void *priv_ctxt) } ipa_ctx = priv_ctxt; - ipa_ctx->uc_loaded = true; uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_UC_OPCODE_UC_READY]; if (!list_empty(&uc_op_work->work.work.entry)) { /* uc_op_work is not initialized yet */ + ipa_ctx->uc_loaded = true; return; } @@ -196,8 +197,19 @@ static void wlan_ipa_send_pkt_to_tl( qdf_ipa_rx_data_t *ipa_tx_desc) { struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; + qdf_device_t osdev; qdf_nbuf_t skb; struct wlan_ipa_tx_desc *tx_desc; + qdf_dma_addr_t paddr; + QDF_STATUS status; + + if (!ipa_ctx) + return; + pdev = ipa_ctx->pdev; + psoc = wlan_pdev_get_psoc(pdev); + osdev = wlan_psoc_get_qdf_dev(psoc); qdf_spin_lock_bh(&iface_context->interface_lock); /* @@ -214,6 +226,14 @@ static void wlan_ipa_send_pkt_to_tl( return; } } + + if (!osdev) { + ipa_free_skb(ipa_tx_desc); + iface_context->stats.num_tx_drop++; + qdf_spin_unlock_bh(&iface_context->interface_lock); + wlan_ipa_wdi_rm_try_release(ipa_ctx); + return; + } qdf_spin_unlock_bh(&iface_context->interface_lock); skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc); @@ -222,15 +242,33 @@ static void wlan_ipa_send_pkt_to_tl( /* Store IPA Tx buffer ownership into SKB CB */ qdf_nbuf_ipa_owned_set(skb); + + if (qdf_mem_smmu_s1_enabled(osdev)) { + status = qdf_nbuf_map(osdev, skb, QDF_DMA_TO_DEVICE); + if (QDF_IS_STATUS_SUCCESS(status)) { + paddr = qdf_nbuf_get_frag_paddr(skb, 0); + } else { + ipa_free_skb(ipa_tx_desc); + qdf_spin_lock_bh(&iface_context->interface_lock); + iface_context->stats.num_tx_drop++; + qdf_spin_unlock_bh(&iface_context->interface_lock); + wlan_ipa_wdi_rm_try_release(ipa_ctx); + return; + } + } else { + paddr = QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc); + } + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { qdf_nbuf_mapped_paddr_set(skb, - QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc) - + WLAN_IPA_WLAN_FRAG_HEADER - + WLAN_IPA_WLAN_IPA_HEADER); + paddr + + WLAN_IPA_WLAN_FRAG_HEADER + + WLAN_IPA_WLAN_IPA_HEADER); QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -= WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER; - } else - qdf_nbuf_mapped_paddr_set(skb, ipa_tx_desc->dma_addr); + } else { + qdf_nbuf_mapped_paddr_set(skb, paddr); + } qdf_spin_lock_bh(&ipa_ctx->q_lock); /* get free Tx desc and assign ipa_tx_desc pointer */ @@ -246,14 +284,22 @@ static void wlan_ipa_send_pkt_to_tl( } else { ipa_ctx->stats.num_tx_desc_error++; qdf_spin_unlock_bh(&ipa_ctx->q_lock); + + if (qdf_mem_smmu_s1_enabled(osdev)) { + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) + qdf_nbuf_mapped_paddr_set(skb, paddr); + + qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); + } + qdf_ipa_free_skb(ipa_tx_desc); wlan_ipa_wdi_rm_try_release(ipa_ctx); return; } skb = cdp_ipa_tx_send_data_frame(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_vdev *)iface_context->tl_context, - QDF_IPA_RX_DATA_SKB(ipa_tx_desc)); + iface_context->session_id, + QDF_IPA_RX_DATA_SKB(ipa_tx_desc)); if (skb) { qdf_nbuf_free(skb); iface_context->stats.num_tx_err++; @@ -339,15 +385,9 @@ static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward( { int ret = WLAN_IPA_FORWARD_PKT_NONE; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); if ((desc & FW_RX_DESC_FORWARD_M)) { - void *vdev = cdp_get_vdev_from_vdev_id(soc, pdev, - iface_ctx->session_id); - if (!vdev) - goto drop_pkt; - - if (cdp_tx_desc_thresh_reached(soc, vdev)) { + if (cdp_tx_desc_thresh_reached(soc, iface_ctx->session_id)) { /* Drop the packet*/ ipa_ctx->stats.num_tx_fwd_err++; goto drop_pkt; @@ -384,7 +424,8 @@ static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward( /* * TODO: Get WDI version through FW capabilities */ -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) { ipa_ctx->wdi_version = IPA_WDI_3; @@ -426,7 +467,7 @@ wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx, &ipa_ctx->sys_pipe[i].ipa_sys_params, sizeof(qdf_ipa_sys_connect_params_t)); - qdf_status = cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + qdf_status = cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, wlan_ipa_i2w_cb, wlan_ipa_w2i_cb, wlan_ipa_wdi_meter_notifier_cb, ipa_ctx->config->desc_size, @@ -688,7 +729,7 @@ wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx, goto exit; } - if (cdp_ipa_rx_intrabss_fwd(ipa_ctx->dp_soc, iface_ctx->tl_context, + if (cdp_ipa_rx_intrabss_fwd(ipa_ctx->dp_soc, iface_ctx->session_id, nbuf, &fwd_success)) { ipa_ctx->ipa_rx_internal_drop_count++; ipa_ctx->ipa_rx_discard++; @@ -722,7 +763,7 @@ static inline int wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx, static inline QDF_STATUS wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx, qdf_device_t osdev) { - return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, wlan_ipa_i2w_cb, wlan_ipa_w2i_cb, wlan_ipa_wdi_meter_notifier_cb, ipa_ctx->config->desc_size, @@ -855,6 +896,50 @@ wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx, #endif /* CONFIG_IPA_WDI_UNIFIED_API */ +/** + * wlan_ipa_send_sta_eapol_to_nw() - Send Rx EAPOL pkt for STA to Kernel + * @skb: network buffer + * + * Called when a EAPOL packet is received via IPA Exception path + * before wlan_ipa_setup_iface is done for STA. + * + * Return: 0 on success, err_code for failure. + */ +static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb) +{ + struct wlan_ipa_priv *ipa_ctx = gp_ipa; + struct hdd_context *hdd_ctx; + struct hdd_adapter *adapter; + struct ethhdr *eh; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + ipa_err_rl("Invalid hdd_context"); + return -EINVAL; + } + + eh = (struct ethhdr *)qdf_nbuf_data(skb); + adapter = hdd_get_adapter_by_macaddr(hdd_ctx, eh->h_dest); + if (hdd_validate_adapter(adapter)) { + ipa_err_rl("Invalid adapter"); + return -EINVAL; + } + if (adapter->device_mode != QDF_STA_MODE) { + ipa_err_rl("device_mode is not STA"); + return -EINVAL; + } + + skb->destructor = wlan_ipa_uc_rt_debug_destructor; + + if (ipa_ctx->send_to_nw) + ipa_ctx->send_to_nw(skb, adapter->dev); + + ipa_ctx->ipa_rx_net_send_count++; + ipa_ctx->stats.num_rx_no_iface_eapol++; + + return 0; +} + /** * wlan_ipa_send_skb_to_network() - Send skb to kernel * @skb: network buffer @@ -899,17 +984,9 @@ static bool wlan_ipa_eapol_intrabss_fwd_check(struct wlan_ipa_priv *ipa_ctx, uint8_t vdev_id, qdf_nbuf_t nbuf) { - struct cdp_vdev *vdev; uint8_t *vdev_mac_addr; - vdev = cdp_get_vdev_from_vdev_id(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, - vdev_id); - if (!vdev) { - ipa_err_rl("txrx vdev is NULL for vdev_id = %d", vdev_id); - return false; - } - - vdev_mac_addr = cdp_get_vdev_mac_addr(ipa_ctx->dp_soc, vdev); + vdev_mac_addr = cdp_get_vdev_mac_addr(ipa_ctx->dp_soc, vdev_id); if (!vdev_mac_addr) return false; @@ -938,10 +1015,8 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, uint8_t iface_id; uint8_t session_id = 0xff; struct wlan_ipa_iface_context *iface_context; - void *peer; bool is_eapol_wapi = false; struct qdf_mac_addr peer_mac_addr = QDF_MAC_ADDR_ZERO_INIT; - uint8_t sta_idx; ipa_ctx = (struct wlan_ipa_priv *)priv; if (!ipa_ctx) { @@ -958,33 +1033,37 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { session_id = (uint8_t)skb->cb[0]; iface_id = ipa_ctx->vdev_to_iface[session_id]; + ipa_ctx->stats.num_rx_excep++; + qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN); } else { iface_id = WLAN_IPA_GET_IFACE_ID(skb->data); + qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN); } + if (iface_id >= WLAN_IPA_MAX_IFACE) { - ipa_err_rl("Invalid iface_id: %u,session id: %x %x %x %x. Dropped!", + ipa_err_rl("Invalid iface_id %u,session_id %x %x %x %x", iface_id, session_id, (uint8_t)skb->cb[1], (uint8_t)skb->cb[2], (uint8_t)skb->cb[3]); + + if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) { + ipa_err_rl("EAPOL pkt. Sending to NW!"); + if (!wlan_ipa_send_sta_eapol_to_nw(skb)) + break; + } + ipa_err_rl("Pkt Dropped!"); ipa_ctx->ipa_rx_internal_drop_count++; dev_kfree_skb_any(skb); return; } iface_context = &ipa_ctx->iface_context[iface_id]; - if (!iface_context->tl_context) { - ipa_err_rl("TL context of iface_id %u is NULL", - iface_id); + if (iface_context->session_id == WLAN_IPA_MAX_SESSION) { + ipa_err_rl("session_id of iface_id %u is invalid:%d", + iface_id, iface_context->session_id); ipa_ctx->ipa_rx_internal_drop_count++; dev_kfree_skb_any(skb); return; } - - if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { - ipa_ctx->stats.num_rx_excep++; - qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN); - } else { - qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN); - } iface_context->stats.num_rx_ipa_excep++; if (iface_context->device_mode == QDF_STA_MODE) @@ -1000,9 +1079,9 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, if (iface_context->device_mode == QDF_SAP_MODE && !wlan_ipa_eapol_intrabss_fwd_check(ipa_ctx, iface_context->session_id, skb)) { - ipa_err_rl("EAPOL intrabss fwd drop DA: %pM", - qdf_nbuf_data(skb) + - QDF_NBUF_DEST_MAC_OFFSET); + ipa_err_rl("EAPOL intrabss fwd drop DA:"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(qdf_nbuf_data(skb) + + QDF_NBUF_DEST_MAC_OFFSET)); ipa_ctx->ipa_rx_internal_drop_count++; dev_kfree_skb_any(skb); return; @@ -1011,19 +1090,17 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, is_eapol_wapi = true; } - peer = cdp_peer_find_by_addr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, - peer_mac_addr.bytes, &sta_idx); - /* * Check for peer authorized state before allowing * non-EAPOL/WAPI frames to be intrabss forwarded * or submitted to stack. */ - - if (peer && cdp_peer_state_get(ipa_ctx->dp_soc, peer) != + if (cdp_peer_state_get(ipa_ctx->dp_soc, + iface_context->session_id, + &peer_mac_addr.bytes[0]) != OL_TXRX_PEER_STATE_AUTH && !is_eapol_wapi) { - ipa_err_rl("Non EAPOL/WAPI packet received when peer %pM is unauthorized", - peer_mac_addr.bytes); + ipa_err_rl("Non EAPOL/WAPI packet received when peer "QDF_MAC_ADDR_FMT" is unauthorized", + QDF_MAC_ADDR_REF(peer_mac_addr.bytes)); ipa_ctx->ipa_rx_internal_drop_count++; dev_kfree_skb_any(skb); return; @@ -1257,7 +1334,7 @@ QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx) if (qdf_atomic_read(&ipa_ctx->pipes_disabled)) { result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc, - ipa_ctx->dp_pdev); + ipa_ctx->dp_pdev_id); if (result) { ipa_err("Enable IPA WDI PIPE failed: ret=%d", result); qdf_status = QDF_STATUS_E_FAILURE; @@ -1270,7 +1347,7 @@ QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx) if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) { cdp_ipa_enable_autonomy(ipa_ctx->dp_soc, - ipa_ctx->dp_pdev); + ipa_ctx->dp_pdev_id); qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0); } end: @@ -1308,7 +1385,7 @@ wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable) if (!qdf_atomic_read(&ipa_ctx->autonomy_disabled)) { cdp_ipa_disable_autonomy(ipa_ctx->dp_soc, - ipa_ctx->dp_pdev); + ipa_ctx->dp_pdev_id); qdf_atomic_set(&ipa_ctx->autonomy_disabled, 1); } @@ -1317,7 +1394,7 @@ wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable) wlan_ipa_set_pending_tx_timer(ipa_ctx); } else { qdf_status = cdp_ipa_disable_pipes(ipa_ctx->dp_soc, - ipa_ctx->dp_pdev); + ipa_ctx->dp_pdev_id); if (QDF_IS_STATUS_ERROR(qdf_status)) { ipa_err("Disable IPA WDI PIPE failed: ret=%u", qdf_status); @@ -1349,12 +1426,12 @@ wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable) * wlan_ipa_uc_find_add_assoc_sta() - Find associated station * @ipa_ctx: Global IPA IPA context * @sta_add: Should station be added - * @sta_id: ID of the station being queried + * @mac_addr: mac address of station being queried * * Return: true if the station was found */ static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx, - bool sta_add, uint8_t sta_id, + bool sta_add, uint8_t *mac_addr) { bool sta_found = false; @@ -1362,20 +1439,22 @@ static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx, for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { if ((ipa_ctx->assoc_stas_map[idx].is_reserved) && - (ipa_ctx->assoc_stas_map[idx].sta_id == sta_id)) { + (qdf_is_macaddr_equal( + &ipa_ctx->assoc_stas_map[idx].mac_addr, + (struct qdf_mac_addr *)mac_addr))) { sta_found = true; break; } } if (sta_add && sta_found) { - ipa_err("STA ID %d already exist, cannot add", sta_id); + ipa_err("STA already exist, cannot add: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr)); return sta_found; } if (sta_add) { for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { if (!ipa_ctx->assoc_stas_map[idx].is_reserved) { ipa_ctx->assoc_stas_map[idx].is_reserved = true; - ipa_ctx->assoc_stas_map[idx].sta_id = sta_id; qdf_mem_copy(&ipa_ctx->assoc_stas_map[idx]. mac_addr, mac_addr, QDF_NET_ETH_LEN); @@ -1385,16 +1464,17 @@ static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx, } if (!sta_add && !sta_found) { ipa_info("STA does not exist, cannot delete: " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_addr)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); return sta_found; } if (!sta_add) { for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) { if ((ipa_ctx->assoc_stas_map[idx].is_reserved) && - (ipa_ctx->assoc_stas_map[idx].sta_id == sta_id)) { + (qdf_is_macaddr_equal( + &ipa_ctx->assoc_stas_map[idx].mac_addr, + (struct qdf_mac_addr *)mac_addr))) { ipa_ctx->assoc_stas_map[idx].is_reserved = false; - ipa_ctx->assoc_stas_map[idx].sta_id = 0xFF; qdf_mem_zero( &ipa_ctx->assoc_stas_map[idx].mac_addr, QDF_NET_ETH_LEN); @@ -1440,19 +1520,20 @@ static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context) ipa_debug("enter"); - if (!iface_context->tl_context) + if (iface_context->session_id == WLAN_IPA_MAX_SESSION) return; cdp_ipa_cleanup_iface(ipa_ctx->dp_soc, iface_context->dev->name, wlan_ipa_is_ipv6_enabled(ipa_ctx->config)); + if (iface_context->device_mode == QDF_SAP_MODE) + ipa_ctx->num_sap_connected--; + qdf_spin_lock_bh(&iface_context->interface_lock); - iface_context->tl_context = NULL; iface_context->dev = NULL; iface_context->device_mode = QDF_MAX_NO_OF_MODE; iface_context->session_id = WLAN_IPA_MAX_SESSION; - iface_context->sta_id = WLAN_IPA_MAX_STA_COUNT; qdf_spin_unlock_bh(&iface_context->interface_lock); iface_context->ifa_address = 0; qdf_zero_macaddr(&iface_context->bssid); @@ -1476,12 +1557,34 @@ static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb) qdf_ipa_rx_data_t *ipa_tx_desc; struct wlan_ipa_tx_desc *tx_desc; uint16_t id; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_psoc *psoc; + qdf_device_t osdev; if (!qdf_nbuf_ipa_owned_get(skb)) { dev_kfree_skb_any(skb); return; } + if (!ipa_ctx) + return; + pdev = ipa_ctx->pdev; + psoc = wlan_pdev_get_psoc(pdev); + osdev = wlan_psoc_get_qdf_dev(psoc); + + if (osdev && qdf_mem_smmu_s1_enabled(osdev)) { + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { + qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(skb); + + qdf_nbuf_mapped_paddr_set(skb, + paddr - + WLAN_IPA_WLAN_FRAG_HEADER - + WLAN_IPA_WLAN_IPA_HEADER); + } + + qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE); + } + /* Get Tx desc pointer from SKB CB */ id = QDF_NBUF_CB_TX_IPA_PRIV(skb); tx_desc = &ipa_ctx->tx_desc_pool[id]; @@ -1510,18 +1613,16 @@ static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb) * @net_dev: Interface net device * @device_mode: Net interface device mode * @adapter: Interface upon which IPA is being setup - * @sta_id: Station ID of the API instance * @session_id: Station ID of the API instance * * Return: QDF STATUS */ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, qdf_netdev_t net_dev, - uint8_t device_mode, uint8_t sta_id, + uint8_t device_mode, uint8_t session_id) { struct wlan_ipa_iface_context *iface_context = NULL; - void *tl_context = NULL; int i; QDF_STATUS status; @@ -1557,7 +1658,8 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, } for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { - if (!ipa_ctx->iface_context[i].tl_context) { + if (ipa_ctx->iface_context[i].session_id == + WLAN_IPA_MAX_SESSION) { iface_context = &(ipa_ctx->iface_context[i]); break; } @@ -1570,17 +1672,6 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, goto end; } - iface_context->sta_id = sta_id; - tl_context = (void *)cdp_peer_get_vdev_by_sta_id(ipa_ctx->dp_soc, - ipa_ctx->dp_pdev, - sta_id); - if (!tl_context) { - ipa_err("Not able to get TL context sta_id: %d", sta_id); - status = QDF_STATUS_E_INVAL; - goto end; - } - - iface_context->tl_context = tl_context; iface_context->dev = net_dev; iface_context->device_mode = device_mode; iface_context->session_id = session_id; @@ -1599,6 +1690,9 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->num_iface++; + if (device_mode == QDF_SAP_MODE) + ipa_ctx->num_sap_connected++; + ipa_debug("exit: num_iface=%d", ipa_ctx->num_iface); return status; @@ -1610,7 +1704,28 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx, return status; } -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) + +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode, + bool enable) +{ + struct wlan_ipa_iface_context *iface_ctx; + wlan_ipa_rps_enable cb = ipa_ctx->rps_enable; + int i; + + if (!cb) + return; + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + if (iface_ctx->device_mode == mode) + cb(iface_ctx->session_id, enable); + } +} +#endif + /** * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection * @ipa_ctx: IPA context @@ -1621,6 +1736,14 @@ static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx) { ipa_debug("enter"); + if (qdf_ipa_get_lan_rx_napi() && (ipa_ctx->num_sap_connected > 1)) { + ipa_debug("Multiple SAP connected. Not enabling pipes. Exit"); + return QDF_STATUS_E_PERM; + } + + if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected) + ipa_set_rps(ipa_ctx, QDF_STA_MODE, true); + if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) { ipa_err("IPA WDI Pipe activation failed"); return QDF_STATUS_E_BUSY; @@ -1639,6 +1762,9 @@ void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx, wlan_ipa_uc_disable_pipes(ipa_ctx, force_disable); + if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected) + ipa_set_rps(ipa_ctx, QDF_STA_MODE, false); + ipa_debug("exit: IPA WDI Pipes deactivated"); } @@ -1762,7 +1888,7 @@ void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->resource_unloading = true; qdf_event_reset(&ipa_ctx->ipa_resource_comp); ipa_info("Disable FW RX PIPE"); - cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, false, false); + cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, false, false); ipa_debug("exit: IPA WDI Pipes deactivated"); } @@ -1857,14 +1983,17 @@ static void wlan_ipa_uc_offload_enable_disable(struct wlan_ipa_priv *ipa_ctx, static void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop) { qdf_ipa_wdi_bw_info_t bw_info; + uint32_t bw_low = ipa_ctx->config->ipa_bw_low; + uint32_t bw_medium = ipa_ctx->config->ipa_bw_medium; + uint32_t bw_high = ipa_ctx->config->ipa_bw_high; int ret; bw_info.num = WLAN_IPA_UC_BW_MONITOR_LEVEL; /* IPA uc will mobitor three bw levels for wlan client */ - bw_info.threshold[0] = ipa_ctx->config->ipa_bw_low; - bw_info.threshold[1] = ipa_ctx->config->ipa_bw_medium; - bw_info.threshold[2] = ipa_ctx->config->ipa_bw_high; - bw_info.stop = stop; + QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_1(&bw_info) = bw_low; + QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_2(&bw_info) = bw_medium; + QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_3(&bw_info) = bw_high; + QDF_IPA_WDI_BW_INFO_START_STOP(&bw_info) = stop; ret = qdf_ipa_uc_bw_monitor(&bw_info); if (ret) @@ -1886,6 +2015,90 @@ void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop) } #endif +/** + * wlan_ipa_send_msg() - Allocate and send message to IPA + * @net_dev: Interface net device + * @type: event enum of type ipa_wlan_event + * @mac_address: MAC address associated with the event + * + * Return: QDF STATUS + */ +static QDF_STATUS wlan_ipa_send_msg(qdf_netdev_t net_dev, + qdf_ipa_wlan_event type, + uint8_t *mac_addr) +{ + qdf_ipa_msg_meta_t meta; + qdf_ipa_wlan_msg_t *msg; + QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t); + + msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); + + if (!msg) { + ipa_err("msg allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + QDF_IPA_SET_META_MSG_TYPE(&meta, type); + strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, IPA_RESOURCE_NAME_MAX); + qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); + + ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg), QDF_IPA_MSG_META_MSG_TYPE(&meta)); + + if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) { + ipa_err("%s: Evt: %d fail", + QDF_IPA_WLAN_MSG_NAME(msg), + QDF_IPA_MSG_META_MSG_TYPE(&meta)); + qdf_mem_free(msg); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx, + qdf_ipa_wlan_event type) +{ + struct wlan_ipa_iface_context *iface_ctx; + int i; + + if (type == QDF_IPA_AP_DISCONNECT) { + ipa_debug("Multiple SAP disconnecting. Enabling IPA"); + + if (ipa_ctx->sap_num_connected_sta > 0) + wlan_ipa_uc_handle_first_con(ipa_ctx); + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + + if (iface_ctx->device_mode == QDF_SAP_MODE) { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + iface_ctx->session_id, + true); + break; + } + } + } else if (type == QDF_IPA_AP_CONNECT) { + ipa_debug("Multiple SAP connected. Disabling IPA"); + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + + if (iface_ctx->device_mode == QDF_SAP_MODE) { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + iface_ctx->session_id, + false); + } + } + + if (!ipa_ctx->ipa_pipes_down) + wlan_ipa_uc_disable_pipes(ipa_ctx, true); + } +} +#endif + static inline void wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id, uint8_t *mac_addr) @@ -1898,7 +2111,6 @@ wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id, * __wlan_ipa_wlan_evt() - IPA event handler * @net_dev: Interface net device * @device_mode: Net interface device mode - * @sta_id: station id for the event * @session_id: session id for the event * @type: event enum of type ipa_wlan_event * @mac_address: MAC address associated with the event @@ -1908,7 +2120,7 @@ wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id, * Return: QDF STATUS */ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, qdf_ipa_wlan_event type, uint8_t *mac_addr) { @@ -1924,8 +2136,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_vdev *vdev; - ipa_debug("%s: EVT: %d, MAC: %pM, sta_id: %d session_id: %u", - net_dev->name, type, mac_addr, sta_id, session_id); + ipa_debug("%s: EVT: %d, MAC: "QDF_MAC_ADDR_FMT", session_id: %u", + net_dev->name, type, QDF_MAC_ADDR_REF(mac_addr), session_id); if (type >= QDF_IPA_WLAN_EVENT_MAX) return QDF_STATUS_E_INVAL; @@ -2023,7 +2235,6 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, pending_event->net_dev = net_dev; pending_event->device_mode = device_mode; - pending_event->sta_id = sta_id; pending_event->session_id = session_id; pending_event->type = type; pending_event->is_loading = ipa_ctx->resource_loading; @@ -2045,6 +2256,12 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, break; } } + + if (qdf_ipa_get_lan_rx_napi() && + ipa_ctx->num_sap_connected == 1) { + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, + type); + } } return QDF_STATUS_SUCCESS; @@ -2069,10 +2286,19 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, ipa_ctx, net_dev, QDF_STA_MODE); if (iface_ctx) wlan_ipa_cleanup_iface(iface_ctx); + status = wlan_ipa_send_msg(net_dev, + QDF_IPA_STA_DISCONNECT, + mac_addr); + if (status != QDF_STATUS_SUCCESS) { + ipa_err("QDF_IPA_STA_DISCONNECT send failed %u", + status); + qdf_mutex_release(&ipa_ctx->event_lock); + goto end; + } } status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode, - sta_id, session_id); + session_id); if (status != QDF_STATUS_SUCCESS) { ipa_err("wlan_ipa_setup_iface failed %u", status); qdf_mutex_release(&ipa_ctx->event_lock); @@ -2082,6 +2308,10 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, ipa_ctx->vdev_to_iface[session_id] = wlan_ipa_get_ifaceid(ipa_ctx, session_id); + wlan_ipa_save_bssid_iface_ctx(ipa_ctx, + ipa_ctx->vdev_to_iface[session_id], + mac_addr); + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) && (ipa_ctx->sap_num_connected_sta > 0 || wlan_ipa_is_sta_only_offload_enabled()) && @@ -2116,9 +2346,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, ipa_ctx->sta_connected++; - wlan_ipa_save_bssid_iface_ctx(ipa_ctx, - ipa_ctx->vdev_to_iface[session_id], - mac_addr); + if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta) + ipa_set_rps_per_vdev(ipa_ctx, session_id, true); qdf_mutex_release(&ipa_ctx->event_lock); @@ -2144,7 +2373,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode, - sta_id, session_id); + session_id); if (status != QDF_STATUS_SUCCESS) { qdf_mutex_release(&ipa_ctx->event_lock); ipa_err("%s: Evt: %d, Interface setup failed", @@ -2154,8 +2383,14 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { qdf_mutex_release(&ipa_ctx->event_lock); - wlan_ipa_uc_offload_enable_disable(ipa_ctx, - SIR_AP_RX_DATA_OFFLOAD, session_id, true); + if (qdf_ipa_get_lan_rx_napi() && + (ipa_ctx->num_sap_connected > 1)) { + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); + } else { + wlan_ipa_uc_offload_enable_disable(ipa_ctx, + SIR_AP_RX_DATA_OFFLOAD, + session_id, true); + } qdf_mutex_acquire(&ipa_ctx->event_lock); } @@ -2241,6 +2476,9 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, if (iface_ctx) wlan_ipa_cleanup_iface(iface_ctx); + if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta) + ipa_set_rps_per_vdev(ipa_ctx, session_id, false); + qdf_mutex_release(&ipa_ctx->event_lock); ipa_debug("sta_connected=%d", ipa_ctx->sta_connected); @@ -2292,6 +2530,10 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } } + if (qdf_ipa_get_lan_rx_napi() && + (ipa_ctx->num_sap_connected == 1)) + wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type); + qdf_mutex_release(&ipa_ctx->event_lock); break; @@ -2303,10 +2545,12 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, } qdf_mutex_acquire(&ipa_ctx->event_lock); - if (wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, true, sta_id, + if (wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, true, mac_addr)) { qdf_mutex_release(&ipa_ctx->event_lock); - ipa_err("%s: STA ID %d found", net_dev->name, sta_id); + ipa_err("%s: STA found, addr: " QDF_MAC_ADDR_FMT, + net_dev->name, + QDF_MAC_ADDR_REF(mac_addr)); return QDF_STATUS_SUCCESS; } @@ -2415,10 +2659,12 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, return QDF_STATUS_SUCCESS; } if (!wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, false, - sta_id, mac_addr)) { + mac_addr)) { qdf_mutex_release(&ipa_ctx->event_lock); - ipa_debug("%s: STA ID %d NOT found, not valid", - msg_ex->name, sta_id); + ipa_debug("%s: STA NOT found, not valid: " + QDF_MAC_ADDR_FMT, + msg_ex->name, QDF_MAC_ADDR_REF(mac_addr)); + return QDF_STATUS_SUCCESS; } ipa_ctx->sap_num_connected_sta--; @@ -2443,6 +2689,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, * unloading WLAN driver is in progress */ + wlan_ipa_uc_bw_monitor(ipa_ctx, true); wlan_ipa_uc_disable_pipes(ipa_ctx, true); } else { @@ -2558,7 +2805,6 @@ wlan_host_to_ipa_wlan_event(enum wlan_ipa_wlan_event wlan_ipa_event_type) * wlan_ipa_wlan_evt() - SSR wrapper for __wlan_ipa_wlan_evt * @net_dev: Interface net device * @device_mode: Net interface device mode - * @sta_id: station id for the event * @session_id: session id for the event * @ipa_event_type: event enum of type wlan_ipa_wlan_event * @mac_address: MAC address associated with the event @@ -2566,7 +2812,7 @@ wlan_host_to_ipa_wlan_event(enum wlan_ipa_wlan_event wlan_ipa_event_type) * Return: QDF_STATUS */ QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr) { @@ -2576,7 +2822,7 @@ QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode, /* Data path offload only support for STA and SAP mode */ if ((device_mode == QDF_STA_MODE) || (device_mode == QDF_SAP_MODE)) - status = __wlan_ipa_wlan_evt(net_dev, device_mode, sta_id, + status = __wlan_ipa_wlan_evt(net_dev, device_mode, session_id, type, mac_addr); return status; @@ -2614,7 +2860,6 @@ wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading) if (pending_event->is_loading == is_loading && vdev) { __wlan_ipa_wlan_evt(pending_event->net_dev, pending_event->device_mode, - pending_event->sta_id, pending_event->session_id, pending_event->type, pending_event->mac_addr); @@ -3049,7 +3294,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, iface_context->iface_id = i; iface_context->dev = NULL; iface_context->device_mode = QDF_MAX_NO_OF_MODE; - iface_context->tl_context = NULL; + iface_context->session_id = WLAN_IPA_MAX_SESSION; qdf_spinlock_create(&iface_context->interface_lock); } @@ -3081,6 +3326,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->ipa_p_rx_packets = 0; ipa_ctx->resource_loading = false; ipa_ctx->resource_unloading = false; + ipa_ctx->num_sap_connected = 0; ipa_ctx->sta_connected = 0; ipa_ctx->ipa_pipes_down = true; qdf_atomic_set(&ipa_ctx->pipes_disabled, 1); @@ -3182,7 +3428,8 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) /* Teardown IPA sys_pipe for MCC */ if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { wlan_ipa_teardown_sys_pipe(ipa_ctx); - qdf_cancel_work(&ipa_ctx->mcc_work); + if (ipa_ctx->uc_loaded) + qdf_cancel_work(&ipa_ctx->mcc_work); } wlan_ipa_wdi_destroy_rm(ipa_ctx); @@ -3274,15 +3521,11 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx) ipa_info("UC READY"); - if (!qdf_dev) { - ipa_err("qdf device is NULL!"); - return; - } - if (true == ipa_ctx->uc_loaded) { ipa_info("UC already loaded"); return; } + ipa_ctx->uc_loaded = true; if (!qdf_dev) { ipa_err("qdf_dev is null"); @@ -3308,7 +3551,11 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx) return; } - cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev); + cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); + wlan_ipa_init_metering(ipa_ctx); + + if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx))) + ipa_err("Failed to init perf level"); /* * Enable IPA/FW PIPEs if @@ -3378,7 +3625,7 @@ static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg, if (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND) { wlan_ipa_uc_disable_pipes(ipa_ctx, true); ipa_info("Disable FW TX PIPE"); - cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, false, true); } @@ -3522,12 +3769,18 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx, ipa_debug("enter"); + if (!osdev) { + ipa_err("osdev null"); + status = QDF_STATUS_E_FAILURE; + goto fail_return; + } + for (i = 0; i < WLAN_IPA_MAX_SESSION; i++) { ipa_ctx->vdev_to_iface[i] = WLAN_IPA_MAX_SESSION; ipa_ctx->vdev_offload_enabled[i] = false; } - if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev)) { + if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id)) { ipa_err("IPA UC resource alloc fail"); status = QDF_STATUS_E_FAILURE; goto fail_return; @@ -3542,14 +3795,15 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx, goto fail_return; } - cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev); + cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, + ipa_ctx->dp_pdev_id); wlan_ipa_init_metering(ipa_ctx); if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS) ipa_err("Failed to init perf level"); } - cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, wlan_ipa_uc_op_event_handler, (void *)ipa_ctx); for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { @@ -3594,6 +3848,7 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) if (true == ipa_ctx->uc_loaded) { status = cdp_ipa_cleanup(ipa_ctx->dp_soc, + ipa_ctx->dp_pdev_id, ipa_ctx->tx_pipe_handle, ipa_ctx->rx_pipe_handle); if (status) @@ -3670,7 +3925,7 @@ void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx, for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { iface_ctx = &ipa_ctx->iface_context[i]; if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE && - iface_ctx->dev == net_dev && iface_ctx->tl_context) { + iface_ctx->dev && iface_ctx->dev == net_dev) { wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT, net_dev->dev_addr); wlan_ipa_cleanup_iface(iface_ctx); diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_main.c b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_main.c index bd5563c09ff536bf03466f52d9f07eeddde8038c..5d33d4ec96e1b72b34770dc5a57bbf950caf0fc6 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_main.c +++ b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_main.c @@ -125,7 +125,7 @@ void ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_soc) wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID); } -void ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, void *txrx_handle) +void ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id) { struct wlan_objmgr_pdev *pdev; struct wlan_ipa_priv *ipa_obj; @@ -150,7 +150,7 @@ void ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, void *txrx_handle) return; } - ipa_obj->dp_pdev = txrx_handle; + ipa_obj->dp_pdev_id = pdev_id; wlan_objmgr_pdev_release_ref(pdev, WLAN_IPA_ID); } @@ -319,6 +319,30 @@ void ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, return wlan_ipa_reg_send_to_nw_cb(ipa_obj, cb); } +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb) +{ + struct wlan_ipa_priv *ipa_obj; + + if (!ipa_config_is_enabled()) { + ipa_debug("ipa is disabled"); + return; + } + + if (!ipa_is_ready()) + return; + + ipa_obj = ipa_pdev_get_priv_obj(pdev); + if (!ipa_obj) { + ipa_err("IPA object is NULL"); + return; + } + + return wlan_ipa_reg_rps_enable_cb(ipa_obj, cb); +} +#endif + void ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode) { struct wlan_ipa_priv *ipa_obj; @@ -521,7 +545,7 @@ QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, } QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, - uint8_t device_mode, uint8_t sta_id, uint8_t session_id, + uint8_t device_mode, uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr) { @@ -533,7 +557,7 @@ QDF_STATUS ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, return QDF_STATUS_E_FAILURE; } - return wlan_ipa_wlan_evt(net_dev, device_mode, sta_id, session_id, + return wlan_ipa_wlan_evt(net_dev, device_mode, session_id, ipa_event_type, mac_addr); } diff --git a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_stats.c b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_stats.c index 32afde0799f6df9aba233d16380b5156304e7035..ad125fdac321dc06fdc8514b19414f0f421143c6 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_stats.c +++ b/drivers/staging/qcacld-3.0/components/ipa/core/src/wlan_ipa_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -335,9 +335,10 @@ static void wlan_ipa_dump_ipa_ctx(struct wlan_ipa_priv *ipa_ctx) QDF_TRACE(QDF_MODULE_ID_IPA, QDF_TRACE_LEVEL_INFO, "\nassoc_stas_map ----"); for (i = 0; i < WLAN_IPA_MAX_STA_COUNT; i++) { - ipa_info("\n\t[%d]: is_reserved=%d, sta_id=%d", i, - ipa_ctx->assoc_stas_map[i].is_reserved, - ipa_ctx->assoc_stas_map[i].sta_id); + ipa_info("\n\t[%d]: is_reserved=%d mac: " QDF_MAC_ADDR_FMT, i, + ipa_ctx->assoc_stas_map[i].is_reserved, + QDF_MAC_ADDR_REF( + ipa_ctx->assoc_stas_map[i].mac_addr.bytes)); } } @@ -422,20 +423,18 @@ static void wlan_ipa_dump_iface_context(struct wlan_ipa_priv *ipa_ctx) ipa_info("\niface_context[%d]----\n" "\tipa_ctx: %pK\n" - "\ttl_context: %pK\n" + "\tsession_id: %d\n" "\tcons_client: %d\n" "\tprod_client: %d\n" "\tiface_id: %d\n" - "\tsta_id: %d\n" "\tinterface_lock: %pK\n" "\tifa_address: 0x%x\n", i, iface_context->ipa_ctx, - iface_context->tl_context, + iface_context->session_id, iface_context->cons_client, iface_context->prod_client, iface_context->iface_id, - iface_context->sta_id, &iface_context->interface_lock, iface_context->ifa_address); } @@ -469,7 +468,7 @@ void wlan_ipa_uc_stat_request(struct wlan_ipa_priv *ipa_ctx, uint8_t reason) if (wlan_ipa_is_fw_wdi_activated(ipa_ctx) && (false == ipa_ctx->resource_loading)) { ipa_ctx->stat_req_reason = reason; - cdp_ipa_get_stat(ipa_ctx->dp_soc, ipa_ctx->dp_pdev); + cdp_ipa_get_stat(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); qdf_mutex_release(&ipa_ctx->ipa_lock); } else { qdf_mutex_release(&ipa_ctx->ipa_lock); @@ -521,12 +520,11 @@ static void wlan_ipa_print_session_info(struct wlan_ipa_priv *ipa_ctx) for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { iface_context = &ipa_ctx->iface_context[i]; - if (!iface_context->tl_context) + if (iface_context->session_id == WLAN_IPA_MAX_SESSION) continue; - ipa_info("\nIFACE[%d]: sta_id:%d, mode:%d, offload:%d", - i, iface_context->sta_id, - iface_context->device_mode, + ipa_info("\nIFACE[%d]: mode:%d, offload:%d", + i, iface_context->device_mode, ipa_ctx->vdev_offload_enabled[iface_context-> session_id]); } @@ -539,9 +537,9 @@ static void wlan_ipa_print_session_info(struct wlan_ipa_priv *ipa_ctx) qdf_list_peek_front(&ipa_ctx->pending_event, (qdf_list_node_t **)&event); while (event) { - ipa_info("PENDING EVENT[%d]: EVT:%s, sta_id:%d, MAC:%pM", + ipa_info("PENDING EVENT[%d]: EVT:%s, MAC:"QDF_MAC_ADDR_FMT, i, wlan_ipa_wlan_event_to_str(event->type), - event->sta_id, event->mac_addr); + QDF_MAC_ADDR_REF(event->mac_addr)); qdf_list_peek_next(&ipa_ctx->pending_event, (qdf_list_node_t *)event, @@ -606,7 +604,7 @@ static void wlan_ipa_print_txrx_stats(struct wlan_ipa_priv *ipa_ctx) for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { iface_context = &ipa_ctx->iface_context[i]; - if (!iface_context->tl_context) + if (iface_context->session_id == WLAN_IPA_MAX_SESSION) continue; ipa_info("IFACE[%d]: TX:%llu, TX DROP:%llu, TX ERR:%llu," @@ -766,29 +764,32 @@ static void __wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt, void *data) { struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context(); - struct ipa_inform_wlan_bw *bw_info; + struct qdf_ipa_inform_wlan_bw *bw_info; + uint8_t bw_level_index; + uint64_t throughput; if (evt != IPA_INFORM_WLAN_BW) return; bw_info = data; - ipa_debug("bw_info idx:%d tp:%llu", bw_info->index, - bw_info->throughput); + bw_level_index = QDF_IPA_INFORM_WLAN_BW_INDEX(bw_info); + throughput = QDF_IPA_INFORM_WLAN_BW_THROUGHPUT(bw_info); + ipa_debug("bw_info idx:%d tp:%llu", bw_level_index, throughput); - if (bw_info->index == ipa_ctx->curr_bw_level) + if (bw_level_index == ipa_ctx->curr_bw_level) return; - if (bw_info->index == WLAN_IPA_BW_LEVEL_LOW) { + if (bw_level_index == WLAN_IPA_BW_LEVEL_LOW) { cdp_ipa_set_perf_level(ipa_ctx->dp_soc, QDF_IPA_CLIENT_WLAN2_CONS, ipa_ctx->config->ipa_bw_low); ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_LOW; - } else if (bw_info->index == WLAN_IPA_BW_LEVEL_MEDIUM) { + } else if (bw_level_index == WLAN_IPA_BW_LEVEL_MEDIUM) { cdp_ipa_set_perf_level(ipa_ctx->dp_soc, QDF_IPA_CLIENT_WLAN2_CONS, ipa_ctx->config->ipa_bw_medium); ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_MEDIUM; - } else if (bw_info->index == WLAN_IPA_BW_LEVEL_HIGH) { + } else if (bw_level_index == WLAN_IPA_BW_LEVEL_HIGH) { cdp_ipa_set_perf_level(ipa_ctx->dp_soc, QDF_IPA_CLIENT_WLAN2_CONS, ipa_ctx->config->ipa_bw_high); @@ -806,8 +807,9 @@ void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx, uint64_t sta_tx, if (!qdf_atomic_read(&ipa_ctx->stats_quota)) return; - tx_stats.sta_tx = sta_tx; - tx_stats.ap_tx = ap_tx; + QDF_IPA_WDI_TX_INFO_STA_TX_BYTES(&tx_stats) = sta_tx; + QDF_IPA_WDI_TX_INFO_SAP_TX_BYTES(&tx_stats) = ap_tx; + qdf_ipa_wdi_wlan_stats(&tx_stats); } @@ -826,7 +828,7 @@ static void wlan_ipa_uc_sharing_stats_request(struct wlan_ipa_priv *ipa_ctx, qdf_mutex_acquire(&ipa_ctx->ipa_lock); if (false == ipa_ctx->resource_loading) { qdf_mutex_release(&ipa_ctx->ipa_lock); - cdp_ipa_uc_get_share_stats(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + cdp_ipa_uc_get_share_stats(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, reset_stats); } else { qdf_mutex_release(&ipa_ctx->ipa_lock); @@ -851,9 +853,9 @@ static void wlan_ipa_uc_set_quota(struct wlan_ipa_priv *ipa_ctx, qdf_mutex_acquire(&ipa_ctx->ipa_lock); if (false == ipa_ctx->resource_loading) { qdf_mutex_release(&ipa_ctx->ipa_lock); - } else { - cdp_ipa_uc_set_quota(ipa_ctx->dp_soc, ipa_ctx->dp_pdev, + cdp_ipa_uc_set_quota(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, quota_bytes); + } else { qdf_mutex_release(&ipa_ctx->ipa_lock); } } @@ -963,7 +965,6 @@ QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx, struct ipa_uc_quota_rsp *uc_quota_rsp; struct ipa_uc_quota_ind *uc_quota_ind; struct wlan_ipa_iface_context *iface_ctx; - uint32_t ifindex; uint64_t quota_bytes; if (msg->op_code == WLAN_IPA_UC_OPCODE_SHARING_STATS) { @@ -994,11 +995,11 @@ QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx, /* send quota exceeded indication to IPA */ iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE); - ifindex = iface_ctx->dev->ifindex; quota_bytes = uc_quota_ind->quota_bytes; if (iface_ctx) - qdf_ipa_broadcast_wdi_quota_reach_ind(ifindex, - quota_bytes); + qdf_ipa_broadcast_wdi_quota_reach_ind( + iface_ctx->dev->ifindex, + quota_bytes); else ipa_err("Failed quota_reach_ind: NULL interface"); } else { diff --git a/drivers/staging/qcacld-3.0/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h b/drivers/staging/qcacld-3.0/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h index 8adbf39a60f239a12d8f02607a98df350836ba3e..57d41f5a2e7aedd3bbd6fe914fb95086e970de90 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h @@ -69,15 +69,14 @@ void ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_soc); /** - * ucfg_ipa_set_txrx_handle() - register pdev txrx handler + * ucfg_ipa_set_pdev_id() - register pdev id * @psoc: psoc handle - * @psoc: psoc obj - * @txrx_handle: data path pdev txrx handle + * @pdev_id: data path txrx pdev id * * Return: None */ -void ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle); +void ucfg_ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id); /** * ucfg_ipa_set_perf_level() - Set IPA perf level @@ -164,6 +163,24 @@ void ucfg_ipa_reg_sap_xmit_cb(struct wlan_objmgr_pdev *pdev, void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, wlan_ipa_send_to_nw cb); +/** + * ucfg_ipa_reg_rps_enable_cb() - Register cb to enable RPS + * @pdev: pdev obj + * @cb: callback + * + * Return: None + */ +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb); +#else +static inline +void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb) +{ +} +#endif + /** * ucfg_ipa_set_mcc_mode() - Set MCC mode * @pdev: pdev obj @@ -263,7 +280,6 @@ QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, * @pdev: pdev obj * @net_dev: Interface net device * @device_mode: Net interface device mode - * @sta_id: station id for the event * @session_id: session id for the event * @type: event enum of type ipa_wlan_event * @mac_address: MAC address associated with the event @@ -272,7 +288,7 @@ QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr); @@ -364,6 +380,14 @@ void ucfg_ipa_component_config_update(struct wlan_objmgr_psoc *psoc); */ uint32_t ucfg_ipa_get_tx_buf_count(void); +/** + * ucfg_ipa_update_tx_stats() - send embedded tx traffic in bytes to IPA + * @pdev: pdev obj + * @sta_tx: tx in bytes on sta vdev + * @ap_tx: tx in bytes on sap vdev + * + * Return: void + */ void ucfg_ipa_update_tx_stats(struct wlan_objmgr_pdev *pdev, uint64_t sta_tx, uint64_t ap_tx); /** @@ -404,8 +428,8 @@ QDF_STATUS ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, } static inline -QDF_STATUS ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle) +QDF_STATUS ucfg_ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id) { return QDF_STATUS_SUCCESS; } @@ -461,6 +485,12 @@ void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, { } +static inline +void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb) +{ +} + static inline void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode) { @@ -526,7 +556,7 @@ QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, static inline QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr) { diff --git a/drivers/staging/qcacld-3.0/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c b/drivers/staging/qcacld-3.0/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c index 6024c9a2f78450f627788884b77683968347160c..53ad2635086bba6d82a9178c2043fa71cfec0fb2 100644 --- a/drivers/staging/qcacld-3.0/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c @@ -39,10 +39,10 @@ bool ucfg_ipa_uc_is_enabled(void) return ipa_config_is_uc_enabled(); } -void ucfg_ipa_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle) +void ucfg_ipa_set_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id) { - return ipa_set_txrx_handle(psoc, txrx_handle); + return ipa_set_pdev_id(psoc, pdev_id); } void ucfg_ipa_set_dp_handle(struct wlan_objmgr_psoc *psoc, @@ -99,8 +99,15 @@ void ucfg_ipa_reg_send_to_nw_cb(struct wlan_objmgr_pdev *pdev, wlan_ipa_send_to_nw cb) { return ipa_reg_send_to_nw_cb(pdev, cb); +} +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void ucfg_ipa_reg_rps_enable_cb(struct wlan_objmgr_pdev *pdev, + wlan_ipa_rps_enable cb) +{ + return ipa_reg_rps_enable_cb(pdev, cb); } +#endif void ucfg_ipa_set_mcc_mode(struct wlan_objmgr_pdev *pdev, bool mcc_mode) { @@ -161,11 +168,11 @@ QDF_STATUS ucfg_ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev, QDF_STATUS ucfg_ipa_wlan_evt(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev, uint8_t device_mode, - uint8_t sta_id, uint8_t session_id, + uint8_t session_id, enum wlan_ipa_wlan_event ipa_event_type, uint8_t *mac_addr) { - return ipa_wlan_evt(pdev, net_dev, device_mode, sta_id, session_id, + return ipa_wlan_evt(pdev, net_dev, device_mode, session_id, ipa_event_type, mac_addr); } diff --git a/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_main.h b/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_main.h index e4425b35b8f9a33289007116a825baa8e8fcdfbe..e98e7a9223f00cc9ec52cde02325f1151afa80dd 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_main.h +++ b/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,23 +36,13 @@ #define mlme_legacy_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_MLME, params) /** - * struct wlan_mlme_psoc_obj -MLME psoc priv object + * struct wlan_mlme_psoc_ext_obj -MLME ext psoc priv object * @cfg: cfg items */ -struct wlan_mlme_psoc_obj { +struct wlan_mlme_psoc_ext_obj { struct wlan_mlme_cfg cfg; }; -/** - * struct wlan_ies - Generic WLAN Information Element(s) format - * @len: Total length of the IEs - * @data: IE data - */ -struct wlan_ies { - uint16_t len; - uint8_t *data; -}; - /** * struct wlan_disconnect_info - WLAN Disconnection Information * @self_discon_ies: Disconnect IEs to be sent in deauth/disassoc frames @@ -69,9 +59,18 @@ struct wlan_disconnect_info { bool from_ap; }; +/** + * struct sae_auth_retry - SAE auth retry Information + * @sae_auth_max_retry: Max number of sae auth retries + * @sae_auth: SAE auth frame information + */ +struct sae_auth_retry { + uint8_t sae_auth_max_retry; + struct wlan_ies sae_auth; +}; + /** * struct peer_mlme_priv_obj - peer MLME component object - * @ucast_key_cipher: unicast crypto type. * @last_pn_valid if last PN is valid * @last_pn: last pn received * @rmf_pn_replays: rmf pn replay count @@ -80,7 +79,6 @@ struct wlan_disconnect_info { * @last_disassoc_deauth_received_time: last disassoc/deauth received time */ struct peer_mlme_priv_obj { - uint32_t ucast_key_cipher; uint8_t last_pn_valid; uint64_t last_pn; uint32_t rmf_pn_replays; @@ -156,7 +154,9 @@ struct wlan_mlme_roam { * @sta_dynamic_oce_value: Dyanmic oce flags value for sta * @roam_invoke_params: Roam invoke params * @disconnect_info: Disconnection information + * @vdev_stop_type: vdev stop type request * @roam_off_state: Roam offload state + * @sae_auth_retry: SAE auth retry information */ struct mlme_legacy_priv { bool chan_switch_in_progress; @@ -172,52 +172,11 @@ struct mlme_legacy_priv { uint8_t sta_dynamic_oce_value; struct mlme_roam_after_data_stall roam_invoke_params; struct wlan_disconnect_info disconnect_info; + uint32_t vdev_stop_type; struct wlan_mlme_roam mlme_roam; + struct sae_auth_retry sae_retry; }; -#ifndef CRYPTO_SET_KEY_CONVERGED -/** - * wlan_peer_set_unicast_cipher() - set unicast cipher - * @peer: PEER object - * @value: value to be set - * - * Return: void - */ -static inline -void wlan_peer_set_unicast_cipher(struct wlan_objmgr_peer *peer, uint32_t value) -{ - struct peer_mlme_priv_obj *peer_priv; - - peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, - WLAN_UMAC_COMP_MLME); - if (!peer_priv) { - mlme_legacy_err(" peer mlme component object is NULL"); - return; - } - peer_priv->ucast_key_cipher = value; -} - -/** - * wlan_peer_get_unicast_cipher() - get unicast cipher - * @peer: PEER object - * - * Return: ucast_key_cipher value - */ -static inline -uint32_t wlan_peer_get_unicast_cipher(struct wlan_objmgr_peer *peer) -{ - struct peer_mlme_priv_obj *peer_priv; - - peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, - WLAN_UMAC_COMP_MLME); - if (!peer_priv) { - mlme_legacy_err("peer mlme component object is NULL"); - return 0; - } - - return peer_priv->ucast_key_cipher; -} -#endif /** * wma_get_peer_mic_len() - get mic hdr len and mic length for peer * @psoc: psoc @@ -296,32 +255,6 @@ struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config( struct mlme_roam_after_data_stall * mlme_get_roam_invoke_params(struct wlan_objmgr_vdev *vdev); -/** - * mlme_psoc_object_created_notification(): mlme psoc create handler - * @psoc: psoc which is going to created by objmgr - * @arg: argument for vdev create handler - * - * Register this api with objmgr to detect psoc is created - * - * Return: QDF_STATUS status in case of success else return error - */ -QDF_STATUS -mlme_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, - void *arg); - -/** - * mlme_psoc_object_destroyed_notification(): mlme psoc delete handler - * @psoc: psoc which is going to delete by objmgr - * @arg: argument for vdev delete handler - * - * Register this api with objmgr to detect psoc is deleted - * - * Return: QDF_STATUS status in case of success else return error - */ -QDF_STATUS -mlme_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc, - void *arg); - /** * mlme_cfg_on_psoc_enable() - Populate MLME structure from CFG and INI * @psoc: pointer to the psoc object @@ -333,17 +266,19 @@ mlme_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc, QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc); /** - * mlme_get_psoc_obj() - Get MLME object from psoc + * mlme_get_psoc_ext_obj() - Get MLME object from psoc * @psoc: pointer to the psoc object * * Get the MLME object pointer from the psoc * * Return: pointer to MLME object */ -#define mlme_get_psoc_obj(psoc) mlme_get_psoc_obj_fl(psoc, __func__, __LINE__) -struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc, - const char *func, - uint32_t line); +#define mlme_get_psoc_ext_obj(psoc) \ + mlme_get_psoc_ext_obj_fl(psoc, __func__, __LINE__) +struct wlan_mlme_psoc_ext_obj *mlme_get_psoc_ext_obj_fl(struct wlan_objmgr_psoc + *psoc, + const char *func, + uint32_t line); /** * mlme_init_ibss_cfg() - Init IBSS config data structure with default CFG value @@ -355,6 +290,22 @@ struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc, QDF_STATUS mlme_init_ibss_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_ibss_cfg *ibss_cfg); +/** + * mlme_get_sae_auth_retry() - Get sae_auth_retry pointer + * @vdev: vdev pointer + * + * Return: Pointer to struct sae_auth_retry or NULL + */ +struct sae_auth_retry *mlme_get_sae_auth_retry(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_free_sae_auth_retry() - Free the SAE auth info + * @vdev: vdev pointer + * + * Return: None + */ +void mlme_free_sae_auth_retry(struct wlan_objmgr_vdev *vdev); + /** * mlme_set_self_disconnect_ies() - Set diconnect IEs configured from userspace * @vdev: vdev pointer @@ -447,6 +398,25 @@ bool mlme_get_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, */ struct wlan_ies *mlme_get_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev); +/** + * mlme_set_peer_pmf_status() - set pmf status of peer + * @peer: PEER object + * @is_pmf_enabled: Carries if PMF is enabled or not + * + * is_pmf_enabled will be set to true if PMF is enabled by peer + * + * Return: void + */ +void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, + bool is_pmf_enabled); +/** + * mlme_get_peer_pmf_status() - get if peer is of pmf capable + * @peer: PEER object + * + * Return: Value of is_pmf_enabled; True if PMF is enabled by peer + */ +bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer); + /** * mlme_set_discon_reason_n_from_ap() - set disconnect reason and from ap flag * @psoc: PSOC pointer @@ -573,12 +543,43 @@ mlme_get_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); * @reqs: RSO stop requestor * @clear: clear bit if true else set bit * - * Return: bitmap value + * Return: None */ void mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum roam_control_requestor reqs, bool clear); +/** + * mlme_clear_operations_bitmap() - Clear mlme operations bitmap which + * indicates what mlme operations are in progress + * @psoc: PSOC pointer + * @vdev_id: vdev for which the mlme operation bitmap is requested + * + * Return: None + */ +void +mlme_clear_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); + +/** + * mlme_get_cfg_wlm_level() - Get the WLM level value + * @psoc: pointer to psoc object + * @level: level that needs to be filled. + * + * Return: QDF Status + */ +QDF_STATUS mlme_get_cfg_wlm_level(struct wlan_objmgr_psoc *psoc, + uint8_t *level); + +/** + * mlme_get_cfg_wlm_reset() - Get the WLM reset flag + * @psoc: pointer to psoc object + * @reset: reset that needs to be filled. + * + * Return: QDF Status + */ +QDF_STATUS mlme_get_cfg_wlm_reset(struct wlan_objmgr_psoc *psoc, + bool *reset); + #define MLME_IS_ROAM_STATE_RSO_STARTED(psoc, vdev_id) \ (mlme_get_roam_state(psoc, vdev_id) == ROAM_RSO_STARTED) @@ -595,25 +596,6 @@ mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, (mlme_get_roam_state(psoc, vdev_id) >= ROAM_INIT) #endif -/** - * mlme_set_peer_pmf_status() - set pmf status of peer - * @peer: PEER object - * @is_pmf_enabled: Carries if PMF is enabled or not - * - * is_pmf_enabled will be set to true if PMF is enabled by peer - * - * Return: void - */ -void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, - bool is_pmf_enabled); -/** - * mlme_get_peer_pmf_status() - get if peer is of pmf capable - * @peer: PEER object - * - * Return: Value of is_pmf_enabled; True if PMF is enabled by peer - */ -bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer); - /** * mlme_reinit_control_config_lfr_params() - Reinitialize roam control config * @psoc: PSOC pointer @@ -626,4 +608,13 @@ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer); */ void mlme_reinit_control_config_lfr_params(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_lfr_cfg *lfr); + +/** + * wlan_is_vdev_id_up() - check if vdev id is in UP state + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * + * Return: if vdev is up + */ +bool wlan_is_vdev_id_up(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id); #endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h b/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h index 45e65d3726560787997188a93c8d85cbac24d97e..3bd0ec7a0d92d24061c6e213ada9ba492bd7f398 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h +++ b/drivers/staging/qcacld-3.0/components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h @@ -110,6 +110,22 @@ mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val); */ bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev); +/** + * mlme_is_wapi_sta_active() - check sta with wapi security exists and is +active + * @pdev: pdev pointer + * + * Return: true if sta with wapi security exists + */ +#ifdef FEATURE_WLAN_WAPI +bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev); +#else +static inline bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev) +{ + return false; +} +#endif + /** * mlme_set_connection_fail() - set connection failure flag * @vdev: vdev pointer @@ -165,7 +181,44 @@ mlme_set_mbssid_info(struct wlan_objmgr_vdev *vdev, * Return: None */ void mlme_get_mbssid_info(struct wlan_objmgr_vdev *vdev, - struct vdev_mlme_mbss_11ax **mbss_11ax); + struct vdev_mlme_mbss_11ax *mbss_11ax); + +/** + * mlme_set_tx_power() - set tx power + * @vdev: vdev pointer + * @tx_power: tx power to be set + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_set_tx_power(struct wlan_objmgr_vdev *vdev, + int8_t tx_power); + +/** + * mlme_get_tx_power() - get tx power + * @vdev: vdev pointer + * @tx_power: tx power info + * + * Return: None + */ +int8_t mlme_get_tx_power(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_get_max_reg_power() - get max reg power + * @vdev: vdev pointer + * + * Return: max reg power + */ +int8_t mlme_get_max_reg_power(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_set_max_reg_power() - set max reg power + * @vdev: vdev pointer + * @max_tx_power: max tx power to be set + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_set_max_reg_power(struct wlan_objmgr_vdev *vdev, + int8_t max_reg_power); /** * mlme_is_vdev_in_beaconning_mode() - check if vdev is beaconing mode @@ -187,6 +240,43 @@ bool mlme_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode); QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev, enum vdev_assoc_type assoc_type); +/** + * mlme_get_vdev_bss_peer_mac_addr() - to get peer mac address + * @vdev: pointer to vdev + * @bss_peer_mac_address: pointer to bss_peer_mac_address + * + * This API is used to get mac address of peer. + * + * Return: QDF_STATUS based on overall success + */ +QDF_STATUS mlme_get_vdev_bss_peer_mac_addr( + struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *bss_peer_mac_address); + +/** + * mlme_get_vdev_stop_type() - to get vdev stop type + * @vdev: vdev pointer + * @vdev_stop_type: vdev stop type + * + * This API will get vdev stop type from mlme legacy priv. + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_get_vdev_stop_type(struct wlan_objmgr_vdev *vdev, + uint32_t *vdev_stop_type); + +/** + * mlme_set_vdev_stop_type() - to set vdev stop type + * @vdev: vdev pointer + * @vdev_stop_type: vdev stop type + * + * This API will set vdev stop type from mlme legacy priv. + * + * Return: QDF_STATUS + */ +QDF_STATUS mlme_set_vdev_stop_type(struct wlan_objmgr_vdev *vdev, + uint32_t vdev_stop_type); + /** * mlme_get_assoc_type() - get associate type * @vdev: vdev pointer @@ -194,4 +284,23 @@ QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev, * Return: associate type */ enum vdev_assoc_type mlme_get_assoc_type(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_vdev_create_send() - function to send the vdev create to firmware + * @vdev: vdev pointer + * + * Return: QDF_STATUS_SUCCESS when the command has been successfully sent + * to firmware or QDF_STATUS_E_** when there is a failure in sending the command + * to firmware. + */ +QDF_STATUS mlme_vdev_create_send(struct wlan_objmgr_vdev *vdev); + +/** + * mlme_vdev_self_peer_create() - function to send the vdev create self peer + * @vdev: vdev pointer + * + * Return: QDF_STATUS_SUCCESS when the self peer is successfully created + * to firmware or QDF_STATUS_E_** when there is a failure. + */ +QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev); #endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_main.c b/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_main.c index f04d36747ffe37d7b0a74d483ec73b8746a6405c..9035571d1a0c3820f09475453b1f0165a11f70ca 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_main.c +++ b/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_main.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,141 +25,76 @@ #include "cfg_ucfg_api.h" #include "wmi_unified.h" #include "wlan_scan_public_structs.h" +#include "wlan_psoc_mlme_api.h" #include "wlan_vdev_mlme_api.h" #include "wlan_mlme_api.h" #include #define NUM_OF_SOUNDING_DIMENSIONS 1 /*Nss - 1, (Nss = 2 for 2x2)*/ -struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc, - const char *func, uint32_t line) +struct wlan_mlme_psoc_ext_obj *mlme_get_psoc_ext_obj_fl( + struct wlan_objmgr_psoc *psoc, + const char *func, uint32_t line) { - struct wlan_mlme_psoc_obj *mlme_obj; - mlme_obj = (struct wlan_mlme_psoc_obj *) - wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_MLME); - if (!mlme_obj) - mlme_legacy_err("mlme obj is null, %s:%d", func, line); - - return mlme_obj; + return wlan_psoc_mlme_get_ext_hdl(psoc); } struct wlan_mlme_nss_chains *mlme_get_dynamic_vdev_config( struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - return &mlme_priv->dynamic_cfg; } struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config( struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - return &mlme_priv->ini_cfg; } struct mlme_roam_after_data_stall * mlme_get_roam_invoke_params(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; - - mlme_priv = vdev_mlme->ext_vdev_ptr; + } return &mlme_priv->roam_invoke_params; } uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - return &mlme_priv->sta_dynamic_oce_value; } -QDF_STATUS -mlme_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, - void *arg) -{ - QDF_STATUS status; - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = qdf_mem_malloc(sizeof(struct wlan_mlme_psoc_obj)); - if (!mlme_obj) { - mlme_legacy_err("Failed to allocate memory"); - return QDF_STATUS_E_NOMEM; - } - - status = wlan_objmgr_psoc_component_obj_attach(psoc, - WLAN_UMAC_COMP_MLME, - mlme_obj, - QDF_STATUS_SUCCESS); - if (status != QDF_STATUS_SUCCESS) { - mlme_legacy_err("Failed to attach psoc_ctx with psoc"); - qdf_mem_free(mlme_obj); - } - - return status; -} - -QDF_STATUS -mlme_psoc_object_destroyed_notification(struct wlan_objmgr_psoc *psoc, - void *arg) -{ - struct wlan_mlme_psoc_obj *mlme_obj = NULL; - QDF_STATUS status; - - mlme_obj = mlme_get_psoc_obj(psoc); - - status = wlan_objmgr_psoc_component_obj_detach(psoc, - WLAN_UMAC_COMP_MLME, - mlme_obj); - if (status != QDF_STATUS_SUCCESS) { - mlme_legacy_err("Failed to detach psoc_ctx from psoc"); - status = QDF_STATUS_E_FAILURE; - goto out; - } - - qdf_mem_free(mlme_obj); - -out: - return status; -} - -#ifdef CRYPTO_SET_KEY_CONVERGED QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *peer_mac, uint8_t *mic_len, uint8_t *mic_hdr_len) @@ -174,7 +110,8 @@ QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_mac, WLAN_LEGACY_MAC_ID); if (!peer) { - mlme_legacy_debug("Peer of peer_mac %pM not found", peer_mac); + mlme_legacy_debug("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); return QDF_STATUS_E_INVAL; } @@ -191,49 +128,13 @@ QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, *mic_hdr_len = IEEE80211_CCMP_HEADERLEN; *mic_len = IEEE80211_CCMP_MICLEN; } - mlme_legacy_debug("peer %pM hdr_len %d mic_len %d key_cipher 0x%x", - peer_mac, *mic_hdr_len, *mic_len, key_cipher); + mlme_legacy_debug("peer "QDF_MAC_ADDR_FMT" hdr_len %d mic_len %d key_cipher 0x%x", + QDF_MAC_ADDR_REF(peer_mac), + *mic_hdr_len, *mic_len, key_cipher); return QDF_STATUS_SUCCESS; } -#else - -QDF_STATUS mlme_get_peer_mic_len(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, - uint8_t *peer_mac, uint8_t *mic_len, - uint8_t *mic_hdr_len) -{ - struct wlan_objmgr_peer *peer; - uint32_t key_cipher; - - if (!psoc || !mic_len || !mic_hdr_len || !peer_mac) { - mlme_legacy_debug("psoc/mic_len/mic_hdr_len/peer_mac null"); - return QDF_STATUS_E_NULL_VALUE; - } - - peer = wlan_objmgr_get_peer(psoc, pdev_id, - peer_mac, WLAN_LEGACY_MAC_ID); - if (!peer) { - mlme_legacy_debug("Peer of peer_mac %pM not found", peer_mac); - return QDF_STATUS_E_INVAL; - } - key_cipher = wlan_peer_get_unicast_cipher(peer); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); - - if (key_cipher == WMI_CIPHER_AES_GCM) { - *mic_hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; - *mic_len = WLAN_IEEE80211_GCMP_MICLEN; - } else { - *mic_hdr_len = IEEE80211_CCMP_HEADERLEN; - *mic_len = IEEE80211_CCMP_MICLEN; - } - mlme_legacy_debug("peer %pM hdr_len %d mic_len %d key_cipher %d", - peer_mac, *mic_hdr_len, *mic_len, key_cipher); - - return QDF_STATUS_SUCCESS; -} -#endif - QDF_STATUS mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer, void *arg) @@ -333,6 +234,42 @@ static void mlme_init_chainmask_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_ENABLE_BT_CHAIN_SEPARATION); } +static void mlme_init_ratemask_cfg(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_ratemask *ratemask_cfg) +{ + uint32_t masks[CFG_MLME_RATE_MASK_LEN] = { 0 }; + qdf_size_t len = 0; + QDF_STATUS status; + + ratemask_cfg->type = cfg_get(psoc, CFG_RATEMASK_TYPE); + if ((ratemask_cfg->type <= WLAN_MLME_RATEMASK_TYPE_NO_MASK) || + (ratemask_cfg->type >= WLAN_MLME_RATEMASK_TYPE_MAX)) { + mlme_legacy_debug("Ratemask disabled"); + return; + } + + status = qdf_uint32_array_parse(cfg_get(psoc, CFG_RATEMASK_SET), + masks, + CFG_MLME_RATE_MASK_LEN, + &len); + + if (status != QDF_STATUS_SUCCESS || len != CFG_MLME_RATE_MASK_LEN) { + /* Do not enable ratemaks if config is invalid */ + ratemask_cfg->type = WLAN_MLME_RATEMASK_TYPE_NO_MASK; + mlme_legacy_err("Failed to parse ratemask"); + return; + } + + ratemask_cfg->lower32 = masks[0]; + ratemask_cfg->higher32 = masks[1]; + ratemask_cfg->lower32_2 = masks[2]; + ratemask_cfg->higher32_2 = masks[3]; + mlme_legacy_debug("Ratemask type: %d, masks:0x%x, 0x%x, 0x%x, 0x%x", + ratemask_cfg->type, ratemask_cfg->lower32, + ratemask_cfg->higher32, ratemask_cfg->lower32_2, + ratemask_cfg->higher32_2); +} + #ifdef WLAN_FEATURE_11W static void mlme_init_pmf_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_generic *gen) @@ -377,6 +314,8 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_ENABLE_RTT_MAC_RANDOMIZATION); gen->band_capability = cfg_get(psoc, CFG_BAND_CAPABILITY); + if (!gen->band_capability) + gen->band_capability = (BIT(REG_BAND_2G) | BIT(REG_BAND_5G)); gen->band = gen->band_capability; gen->select_5ghz_margin = cfg_get(psoc, CFG_SELECT_5GHZ_MARGIN); @@ -416,15 +355,15 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_ENABLE_BEACON_RECEPTION_STATS); gen->enable_remove_time_stamp_sync_cmd = cfg_get(psoc, CFG_REMOVE_TIME_STAMP_SYNC_CMD); + gen->disable_4way_hs_offload = + cfg_get(psoc, CFG_DISABLE_4WAY_HS_OFFLOAD); gen->mgmt_retry_max = cfg_get(psoc, CFG_MGMT_RETRY_MAX); gen->bmiss_skip_full_scan = cfg_get(psoc, CFG_BMISS_SKIP_FULL_SCAN); gen->enable_ring_buffer = cfg_get(psoc, CFG_ENABLE_RING_BUFFER); gen->enable_peer_unmap_conf_support = cfg_get(psoc, CFG_DP_ENABLE_PEER_UMAP_CONF_SUPPORT); - gen->disable_4way_hs_offload = - cfg_get(psoc, CFG_DISABLE_4WAY_HS_OFFLOAD); - gen->dfs_chan_ageout_time = - cfg_get(psoc, CFG_DFS_CHAN_AGEOUT_TIME); + gen->sae_connect_retries = + cfg_get(psoc, CFG_SAE_CONNECION_RETRIES); } static void mlme_init_edca_ani_cfg(struct wlan_mlme_edca_params *edca_params) @@ -955,6 +894,8 @@ static void mlme_init_dfs_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_DISABLE_DFS_JAPAN_W53); dfs_cfg->sap_tx_leakage_threshold = cfg_get(psoc, CFG_SAP_TX_LEAKAGE_THRESHOLD); + dfs_cfg->dfs_pri_multiplier = + cfg_get(psoc, CFG_DFS_RADAR_PRI_MULTIPLIER); } static void mlme_init_feature_flag_in_cfg( @@ -1154,13 +1095,13 @@ static void mlme_init_he_cap_in_cfg(struct wlan_objmgr_psoc *psoc, he_caps->dot11_he_cap.rx_full_bw_su_he_mu_non_cmpr_sigb = cfg_default(CFG_HE_RX_FULL_BW_MU_NON_CMPR_SIGB); he_caps->dot11_he_cap.rx_he_mcs_map_lt_80 = - cfg_default(CFG_HE_RX_MCS_MAP_LT_80); + cfg_get(psoc, CFG_HE_RX_MCS_MAP_LT_80); he_caps->dot11_he_cap.tx_he_mcs_map_lt_80 = - cfg_default(CFG_HE_TX_MCS_MAP_LT_80); - value = cfg_default(CFG_HE_RX_MCS_MAP_160); + cfg_get(psoc, CFG_HE_TX_MCS_MAP_LT_80); + value = cfg_get(psoc, CFG_HE_RX_MCS_MAP_160); qdf_mem_copy(he_caps->dot11_he_cap.rx_he_mcs_map_160, &value, sizeof(uint16_t)); - value = cfg_default(CFG_HE_TX_MCS_MAP_160); + value = cfg_get(psoc, CFG_HE_TX_MCS_MAP_160); qdf_mem_copy(he_caps->dot11_he_cap.tx_he_mcs_map_160, &value, sizeof(uint16_t)); value = cfg_default(CFG_HE_RX_MCS_MAP_80_80); @@ -1270,6 +1211,8 @@ static void mlme_init_sap_cfg(struct wlan_objmgr_psoc *psoc, sap_cfg->sap_sae_enabled = is_sae_sap_enabled(psoc); sap_cfg->is_sap_bcast_deauth_enabled = cfg_get(psoc, CFG_IS_SAP_BCAST_DEAUTH_ENABLED); + sap_cfg->is_6g_sap_fd_enabled = + cfg_get(psoc, CFG_6G_SAP_FILS_DISCOVERY_ENABLED); } static void mlme_init_obss_ht40_cfg(struct wlan_objmgr_psoc *psoc, @@ -1295,6 +1238,8 @@ static void mlme_init_obss_ht40_cfg(struct wlan_objmgr_psoc *psoc, (bool)cfg_default(CFG_OBSS_DETECTION_OFFLOAD); obss_ht40->obss_color_collision_offload_enabled = (bool)cfg_default(CFG_OBSS_COLOR_COLLISION_OFFLOAD); + obss_ht40->bss_color_collision_det_sta = + cfg_get(psoc, CFG_BSS_CLR_COLLISION_DETCN_STA); } static void mlme_init_threshold_cfg(struct wlan_objmgr_psoc *psoc, @@ -1304,14 +1249,99 @@ static void mlme_init_threshold_cfg(struct wlan_objmgr_psoc *psoc, threshold->frag_threshold = cfg_get(psoc, CFG_FRAG_THRESHOLD); } +static bool +mlme_is_freq_present_in_list(struct acs_weight *normalize_weight_chan_list, + uint8_t num_freq, uint32_t freq, uint8_t *index) +{ + uint8_t i; + + for (i = 0; i < num_freq && i < NUM_CHANNELS; i++) { + if (normalize_weight_chan_list[i].chan_freq == freq) { + *index = i; + return true; + } + } + + return false; +} + +static void +mlme_acs_parse_weight_list(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_acs *acs) +{ + char *acs_weight, *str1, *str2 = NULL, *acs_weight_temp, is_range = '-'; + int freq1, freq2, normalize_factor; + uint8_t num_acs_weight = 0, num_acs_weight_range = 0, index = 0; + struct acs_weight *weight_list = acs->normalize_weight_chan; + struct acs_weight_range *range_list = acs->normalize_weight_range; + + if (!qdf_str_len(cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT))) + return; + + acs_weight = qdf_mem_malloc(ACS_WEIGHT_MAX_STR_LEN); + + if (!acs_weight) + return; + + qdf_mem_copy(acs_weight, cfg_get(psoc, CFG_NORMALIZE_ACS_WEIGHT), + ACS_WEIGHT_MAX_STR_LEN); + acs_weight_temp = acs_weight; + + while(acs_weight_temp) { + str1 = strsep(&acs_weight_temp, ","); + if (!str1) + goto end; + freq1 = 0; + freq2 = 0; + if (strchr(str1, is_range)) { + str2 = strsep(&str1, "-"); + sscanf(str2, "%d", &freq1); + sscanf(str1, "%d", &freq2); + strsep(&str1, "="); + if (!str1) + goto end; + sscanf(str1, "%d", &normalize_factor); + + if (num_acs_weight_range == MAX_ACS_WEIGHT_RANGE) + continue; + range_list[num_acs_weight_range].normalize_weight = + normalize_factor; + range_list[num_acs_weight_range].start_freq = freq1; + range_list[num_acs_weight_range++].end_freq = freq2; + } else { + sscanf(str1, "%d", &freq1); + strsep(&str1, "="); + if (!str1 || !weight_list) + goto end; + sscanf(str1, "%d", &normalize_factor); + if (mlme_is_freq_present_in_list(weight_list, + num_acs_weight, freq1, + &index)) { + weight_list[index].normalize_weight = + normalize_factor; + } else { + if (num_acs_weight == NUM_CHANNELS) + continue; + + weight_list[num_acs_weight].chan_freq = freq1; + weight_list[num_acs_weight++].normalize_weight = + normalize_factor; + } + } + } + + acs->normalize_weight_num_chan = num_acs_weight; + acs->num_weight_range = num_acs_weight_range; + +end: + qdf_mem_free(acs_weight); +} + static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_acs *acs) { acs->is_acs_with_more_param = cfg_get(psoc, CFG_ACS_WITH_MORE_PARAM); - acs->force_sap_start = - cfg_get(psoc, CFG_ACS_FORCE_START_SAP); - acs->np_chan_weightage = cfg_get(psoc, CFG_ACS_NP_CHAN_WEIGHT); acs->auto_channel_select_weight = cfg_get(psoc, CFG_AUTO_CHANNEL_SELECT_WEIGHT); acs->is_vendor_acs_support = @@ -1320,6 +1350,10 @@ static void mlme_init_acs_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_USER_ACS_DFS_LTE); acs->is_external_acs_policy = cfg_get(psoc, CFG_EXTERNAL_ACS_POLICY); + acs->force_sap_start = + cfg_get(psoc, CFG_ACS_FORCE_START_SAP); + acs->np_chan_weightage = cfg_get(psoc, CFG_ACS_NP_CHAN_WEIGHT); + mlme_acs_parse_weight_list(psoc, acs); } QDF_STATUS mlme_init_ibss_cfg(struct wlan_objmgr_psoc *psoc, @@ -1397,8 +1431,7 @@ static void mlme_init_sta_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_QCN_IE_SUPPORT); sta->fils_max_chan_guard_time = cfg_get(psoc, CFG_FILS_MAX_CHAN_GUARD_TIME); - sta->force_rsne_override = - cfg_get(psoc, CFG_FORCE_RSNE_OVERRIDE); + sta->deauth_retry_cnt = cfg_get(psoc, CFG_DEAUTH_RETRY_CNT); sta->single_tid = cfg_get(psoc, CFG_SINGLE_TID_RC); sta->sta_miracast_mcc_rest_time = @@ -1482,6 +1515,8 @@ static void mlme_init_roam_offload_cfg(struct wlan_objmgr_psoc *psoc, lfr->lfr3_roaming_offload = cfg_get(psoc, CFG_LFR3_ROAMING_OFFLOAD); lfr->enable_self_bss_roam = cfg_get(psoc, CFG_LFR3_ENABLE_SELF_BSS_ROAM); + lfr->enable_roam_reason_vsie = + cfg_get(psoc, CFG_ENABLE_ROAM_REASON_VSIE); lfr->enable_disconnect_roam_offload = cfg_get(psoc, CFG_LFR_ENABLE_DISCONNECT_ROAM); lfr->enable_idle_roam = @@ -1608,6 +1643,12 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_LFR_ROAM_BG_SCAN_CLIENT_BITMAP); lfr->roam_bg_scan_bad_rssi_offset_2g = cfg_get(psoc, CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G); + lfr->roam_data_rssi_threshold_triggers = + cfg_get(psoc, CFG_ROAM_DATA_RSSI_THRESHOLD_TRIGGERS); + lfr->roam_data_rssi_threshold = + cfg_get(psoc, CFG_ROAM_DATA_RSSI_THRESHOLD); + lfr->rx_data_inactivity_time = + cfg_get(psoc, CFG_RX_DATA_INACTIVITY_TIME); lfr->adaptive_roamscan_dwell_mode = cfg_get(psoc, CFG_LFR_ADAPTIVE_ROAMSCAN_DWELL_MODE); lfr->per_roam_enable = @@ -1725,6 +1766,7 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc, lfr->roam_scan_period_after_inactivity = cfg_get(psoc, CFG_POST_INACTIVITY_ROAM_SCAN_PERIOD); lfr->fw_akm_bitmap = 0; + lfr->enable_ft_im_roaming = cfg_get(psoc, CFG_FT_IM_ROAMING); mlme_init_roam_offload_cfg(psoc, lfr); mlme_init_ese_cfg(psoc, lfr); @@ -1754,17 +1796,17 @@ static void mlme_init_power_cfg(struct wlan_objmgr_psoc *psoc, power->tx_power_2g = cfg_get(psoc, CFG_SET_TXPOWER_LIMIT2G); power->tx_power_5g = cfg_get(psoc, CFG_SET_TXPOWER_LIMIT5G); - power->max_tx_power_24.max_len = CFG_MAX_TX_POWER_2_4_LEN; + power->max_tx_power_24_chan.max_len = CFG_MAX_TX_POWER_2_4_LEN; qdf_uint8_array_parse(cfg_default(CFG_MAX_TX_POWER_2_4), - power->max_tx_power_24.data, - sizeof(power->max_tx_power_24.data), - &power->max_tx_power_24.len); + power->max_tx_power_24_chan.data, + sizeof(power->max_tx_power_24_chan.data), + &power->max_tx_power_24_chan.len); - power->max_tx_power_5.max_len = CFG_MAX_TX_POWER_5_LEN; + power->max_tx_power_5_chan.max_len = CFG_MAX_TX_POWER_5_LEN; qdf_uint8_array_parse(cfg_default(CFG_MAX_TX_POWER_5), - power->max_tx_power_5.data, - sizeof(power->max_tx_power_5.data), - &power->max_tx_power_5.len); + power->max_tx_power_5_chan.data, + sizeof(power->max_tx_power_5_chan.data), + &power->max_tx_power_5_chan.len); power->power_usage.max_len = CFG_POWER_USAGE_MAX_LEN; power->power_usage.len = CFG_POWER_USAGE_MAX_LEN; @@ -1808,6 +1850,8 @@ static void mlme_init_scoring_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_SCORING_CHAN_CONGESTION_WEIGHTAGE); scoring_cfg->weight_cfg.oce_wan_weightage = cfg_get(psoc, CFG_SCORING_OCE_WAN_WEIGHTAGE); + scoring_cfg->weight_cfg.sae_pk_ap_weightage = + cfg_get(psoc, CFG_SAE_PK_AP_WEIGHTAGE); total_weight = scoring_cfg->weight_cfg.rssi_weightage + scoring_cfg->weight_cfg.ht_caps_weightage + @@ -1819,15 +1863,16 @@ static void mlme_init_scoring_cfg(struct wlan_objmgr_psoc *psoc, scoring_cfg->weight_cfg.beamforming_cap_weightage + scoring_cfg->weight_cfg.pcl_weightage + scoring_cfg->weight_cfg.channel_congestion_weightage + - scoring_cfg->weight_cfg.oce_wan_weightage; + scoring_cfg->weight_cfg.oce_wan_weightage + + scoring_cfg->weight_cfg.sae_pk_ap_weightage; /* * If configured weights are greater than max weight, * fallback to default weights */ - if (total_weight > BEST_CANDIDATE_MAX_WEIGHT) { + if (total_weight > MAX_BSS_SCORE) { mlme_legacy_err("Total weight greater than %d, using default weights", - BEST_CANDIDATE_MAX_WEIGHT); + MAX_BSS_SCORE); scoring_cfg->weight_cfg.rssi_weightage = RSSI_WEIGHTAGE; scoring_cfg->weight_cfg.ht_caps_weightage = HT_CAPABILITY_WEIGHTAGE; @@ -1845,6 +1890,8 @@ static void mlme_init_scoring_cfg(struct wlan_objmgr_psoc *psoc, scoring_cfg->weight_cfg.channel_congestion_weightage = CHANNEL_CONGESTION_WEIGHTAGE; scoring_cfg->weight_cfg.oce_wan_weightage = OCE_WAN_WEIGHTAGE; + scoring_cfg->weight_cfg.sae_pk_ap_weightage = + SAE_PK_AP_WEIGHTAGE; } scoring_cfg->rssi_score.best_rssi_threshold = @@ -2037,6 +2084,8 @@ static void mlme_init_wifi_pos_cfg(struct wlan_objmgr_psoc *psoc, { wifi_pos_cfg->fine_time_meas_cap = cfg_get(psoc, CFG_FINE_TIME_MEAS_CAPABILITY); + wifi_pos_cfg->oem_6g_support_disable = + cfg_get(psoc, CFG_OEM_SIXG_SUPPORT_DISABLE); } #ifdef FEATURE_WLAN_ESE @@ -2213,6 +2262,12 @@ mlme_init_roam_score_config(struct wlan_objmgr_psoc *psoc, min_rssi_param->min_rssi = cfg_get(psoc, CFG_BMISS_ROAM_MIN_RSSI); min_rssi_param->trigger_reason = ROAM_TRIGGER_REASON_BMISS; + + min_rssi_param = &mlme_cfg->trig_min_rssi[MIN_RSSI_2G_TO_5G_ROAM]; + min_rssi_param->min_rssi = + cfg_get(psoc, CFG_2G_TO_5G_ROAM_MIN_RSSI); + min_rssi_param->trigger_reason = ROAM_TRIGGER_REASON_HIGH_RSSI; + } /** @@ -2226,6 +2281,7 @@ static void mlme_init_fe_wlm_in_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_fe_wlm *wlm_config) { wlm_config->latency_enable = cfg_get(psoc, CFG_LATENCY_ENABLE); + wlm_config->latency_reset = cfg_get(psoc, CFG_LATENCY_RESET); wlm_config->latency_level = cfg_get(psoc, CFG_LATENCY_LEVEL); wlm_config->latency_flags[0] = cfg_get(psoc, CFG_LATENCY_FLAGS_NORMAL); wlm_config->latency_flags[1] = cfg_get(psoc, CFG_LATENCY_FLAGS_MOD); @@ -2246,6 +2302,7 @@ static void mlme_init_fe_rrm_in_cfg(struct wlan_objmgr_psoc *psoc, qdf_size_t len; rrm_config->rrm_enabled = cfg_get(psoc, CFG_RRM_ENABLE); + rrm_config->sap_rrm_enabled = cfg_get(psoc, CFG_SAP_RRM_ENABLE); rrm_config->rrm_rand_interval = cfg_get(psoc, CFG_RRM_MEAS_RAND_INTVL); qdf_uint8_array_parse(cfg_get(psoc, CFG_RM_CAPABILITY), @@ -2320,10 +2377,13 @@ static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_reg *reg) { qdf_size_t valid_channel_list_num = 0; + uint8_t channel_list[CFG_VALID_CHANNEL_LIST_LEN]; + uint8_t i; + struct wlan_objmgr_pdev *pdev = NULL; reg->self_gen_frm_pwr = cfg_get(psoc, CFG_SELF_GEN_FRM_PWR); - reg->etsi13_srd_chan_in_master_mode = - cfg_get(psoc, CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE); + reg->etsi_srd_chan_in_master_mode = + cfg_get(psoc, CFG_ETSI_SRD_CHAN_IN_MASTER_MODE); reg->restart_beaconing_on_ch_avoid = cfg_get(psoc, CFG_RESTART_BEACONING_ON_CH_AVOID); reg->indoor_channel_support = cfg_get(psoc, CFG_INDOOR_CHANNEL_SUPPORT); @@ -2335,12 +2395,30 @@ static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, reg->ignore_fw_reg_offload_ind = cfg_get( psoc, CFG_IGNORE_FW_REG_OFFLOAD_IND); + reg->retain_nol_across_regdmn_update = + cfg_get(psoc, CFG_RETAIN_NOL_ACROSS_REG_DOMAIN); qdf_uint8_array_parse(cfg_default(CFG_VALID_CHANNEL_LIST), - reg->valid_channel_list, + channel_list, CFG_VALID_CHANNEL_LIST_LEN, &valid_channel_list_num); reg->valid_channel_list_num = (uint8_t)valid_channel_list_num; + + reg->enable_nan_on_indoor_channels = + cfg_get(psoc, CFG_INDOOR_CHANNEL_SUPPORT_FOR_NAN); + + pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_MLME_NB_ID); + if (!pdev) { + mlme_legacy_err("null pdev"); + return; + } + + for (i = 0; i < valid_channel_list_num; i++) + reg->valid_channel_freq_list[i] = + wlan_reg_chan_to_freq(pdev, channel_list[i]); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_NB_ID); + qdf_str_lcopy(reg->country_code, cfg_default(CFG_COUNTRY_CODE), sizeof(reg->country_code)); reg->country_code_len = (uint8_t)sizeof(reg->country_code); @@ -2348,18 +2426,20 @@ static void mlme_init_reg_cfg(struct wlan_objmgr_psoc *psoc, } static void -mlme_init_dot11_mode_cfg(struct wlan_mlme_dot11_mode *dot11_mode) +mlme_init_dot11_mode_cfg(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_dot11_mode *dot11_mode) { dot11_mode->dot11_mode = cfg_default(CFG_DOT11_MODE); + dot11_mode->vdev_type_dot11_mode = cfg_get(psoc, CFG_VDEV_DOT11_MODE); } QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; struct wlan_mlme_cfg *mlme_cfg; QDF_STATUS status = QDF_STATUS_SUCCESS; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { mlme_legacy_err("Failed to get MLME Obj"); return QDF_STATUS_E_FAILURE; @@ -2391,7 +2471,7 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) mlme_init_ibss_cfg(psoc, &mlme_cfg->ibss); mlme_init_feature_flag_in_cfg(psoc, &mlme_cfg->feature_flags); mlme_init_scoring_cfg(psoc, &mlme_cfg->scoring); - mlme_init_dot11_mode_cfg(&mlme_cfg->dot11_mode); + mlme_init_dot11_mode_cfg(psoc, &mlme_cfg->dot11_mode); mlme_init_threshold_cfg(psoc, &mlme_cfg->threshold); mlme_init_acs_cfg(psoc, &mlme_cfg->acs); mlme_init_power_cfg(psoc, &mlme_cfg->power); @@ -2405,14 +2485,44 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) mlme_init_reg_cfg(psoc, &mlme_cfg->reg); mlme_init_btm_cfg(psoc, &mlme_cfg->btm); mlme_init_roam_score_config(psoc, mlme_cfg); + mlme_init_ratemask_cfg(psoc, &mlme_cfg->ratemask_cfg); return status; } +struct sae_auth_retry *mlme_get_sae_auth_retry(struct wlan_objmgr_vdev *vdev) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return NULL; + } + + return &mlme_priv->sae_retry; +} + +void mlme_free_sae_auth_retry(struct wlan_objmgr_vdev *vdev) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return; + } + + mlme_priv->sae_retry.sae_auth_max_retry = 0; + if (mlme_priv->sae_retry.sae_auth.data) + qdf_mem_free(mlme_priv->sae_retry.sae_auth.data); + mlme_priv->sae_retry.sae_auth.data = NULL; + mlme_priv->sae_retry.sae_auth.len = 0; +} + void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev, struct wlan_ies *ie) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; if (!ie || !ie->len || !ie->data) { @@ -2420,14 +2530,12 @@ void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev, return; } - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - if (mlme_priv->disconnect_info.self_discon_ies.data) { qdf_mem_free(mlme_priv->disconnect_info.self_discon_ies.data); mlme_priv->disconnect_info.self_discon_ies.len = 0; @@ -2450,17 +2558,14 @@ void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev, void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - if (mlme_priv->disconnect_info.self_discon_ies.data) { qdf_mem_free(mlme_priv->disconnect_info.self_discon_ies.data); mlme_priv->disconnect_info.self_discon_ies.data = NULL; @@ -2470,15 +2575,13 @@ void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; } - mlme_priv = vdev_mlme->ext_vdev_ptr; return &mlme_priv->disconnect_info.self_discon_ies; } @@ -2486,7 +2589,6 @@ struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev) void mlme_set_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev, struct wlan_ies *ie) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; if (!ie || !ie->len || !ie->data) { @@ -2494,14 +2596,12 @@ void mlme_set_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev, return; } - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - if (mlme_priv->disconnect_info.peer_discon_ies.data) { qdf_mem_free(mlme_priv->disconnect_info.peer_discon_ies.data); mlme_priv->disconnect_info.peer_discon_ies.len = 0; @@ -2524,17 +2624,14 @@ void mlme_set_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev, void mlme_free_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - if (mlme_priv->disconnect_info.peer_discon_ies.data) { qdf_mem_free(mlme_priv->disconnect_info.peer_discon_ies.data); mlme_priv->disconnect_info.peer_discon_ies.data = NULL; @@ -2544,23 +2641,45 @@ void mlme_free_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev) struct wlan_ies *mlme_get_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return NULL; } - mlme_priv = vdev_mlme->ext_vdev_ptr; - return &mlme_priv->disconnect_info.peer_discon_ies; } -void mlme_set_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool from_ap, - uint32_t reason_code) +void mlme_set_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev, bool flag) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return; + } + + mlme_priv->follow_ap_edca = flag; +} + +bool mlme_get_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return false; + } + + return mlme_priv->follow_ap_edca; +} + +void mlme_set_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool flag) { struct wlan_objmgr_vdev *vdev; struct mlme_legacy_priv *mlme_priv; @@ -2579,41 +2698,68 @@ void mlme_set_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, return; } - mlme_priv->disconnect_info.from_ap = from_ap; - mlme_priv->disconnect_info.discon_reason = reason_code; + mlme_priv->reconn_after_assoc_timeout = flag; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); } -void mlme_get_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool *from_ap, - uint32_t *reason_code) +bool mlme_get_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { struct wlan_objmgr_vdev *vdev; struct mlme_legacy_priv *mlme_priv; + bool reconn_after_assoc_timeout; if (!psoc) - return; + return false; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_LEGACY_MAC_ID); if (!vdev) - return; + return false; mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); - return; + return false; } - *from_ap = mlme_priv->disconnect_info.from_ap; - *reason_code = mlme_priv->disconnect_info.discon_reason; - mlme_priv->disconnect_info.from_ap = false; - mlme_priv->disconnect_info.discon_reason = 0; + reconn_after_assoc_timeout = mlme_priv->reconn_after_assoc_timeout; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + return reconn_after_assoc_timeout; } -void mlme_set_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool flag) +void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, + bool is_pmf_enabled) +{ + struct peer_mlme_priv_obj *peer_priv; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + mlme_legacy_err(" peer mlme component object is NULL"); + return; + } + peer_priv->is_pmf_enabled = is_pmf_enabled; +} + +bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer) +{ + struct peer_mlme_priv_obj *peer_priv; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + mlme_legacy_err("peer mlme component object is NULL"); + return false; + } + + return peer_priv->is_pmf_enabled; +} + +void mlme_set_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool from_ap, + uint32_t reason_code) { struct wlan_objmgr_vdev *vdev; struct mlme_legacy_priv *mlme_priv; @@ -2632,35 +2778,37 @@ void mlme_set_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, return; } - mlme_priv->reconn_after_assoc_timeout = flag; + mlme_priv->disconnect_info.from_ap = from_ap; + mlme_priv->disconnect_info.discon_reason = reason_code; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); } -bool mlme_get_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id) +void mlme_get_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool *from_ap, + uint32_t *reason_code) { struct wlan_objmgr_vdev *vdev; struct mlme_legacy_priv *mlme_priv; - bool reconn_after_assoc_timeout; if (!psoc) - return false; + return; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_LEGACY_MAC_ID); if (!vdev) - return false; + return; mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); - return false; + return; } - reconn_after_assoc_timeout = mlme_priv->reconn_after_assoc_timeout; + *from_ap = mlme_priv->disconnect_info.from_ap; + *reason_code = mlme_priv->disconnect_info.discon_reason; + mlme_priv->disconnect_info.from_ap = false; + mlme_priv->disconnect_info.discon_reason = 0; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); - - return reconn_after_assoc_timeout; } #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -2685,9 +2833,10 @@ static void mlme_print_roaming_state(uint8_t vdev_id, enum roam_offload_state cur_state, enum roam_offload_state new_state) { - mlme_legacy_debug("ROAM: vdev %d: %s(%d) --> %s(%d)", - vdev_id, mlme_roam_state_to_string(cur_state), cur_state, - mlme_roam_state_to_string(new_state), new_state); + mlme_debug("ROAM: vdev %d: %s(%d) --> %s(%d)", + vdev_id, mlme_roam_state_to_string(cur_state), cur_state, + mlme_roam_state_to_string(new_state), new_state); + /* TODO: Try to print the state change requestor also */ } @@ -2700,7 +2849,7 @@ mlme_get_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc, bool value; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2710,12 +2859,12 @@ mlme_get_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc, mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return 0; } value = mlme_priv->mlme_roam.roam_cfg.supplicant_disabled_roaming; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return value; } @@ -2727,7 +2876,7 @@ void mlme_set_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc, struct mlme_legacy_priv *mlme_priv; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2737,12 +2886,12 @@ void mlme_set_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc, mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return; } mlme_priv->mlme_roam.roam_cfg.supplicant_disabled_roaming = val; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); } uint32_t @@ -2753,7 +2902,7 @@ mlme_get_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) uint32_t roam_bitmap; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2763,12 +2912,12 @@ mlme_get_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return 0; } roam_bitmap = mlme_priv->mlme_roam.roam_cfg.roam_trigger_bitmap; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return roam_bitmap; } @@ -2780,7 +2929,7 @@ void mlme_set_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, struct mlme_legacy_priv *mlme_priv; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); return; @@ -2789,12 +2938,12 @@ void mlme_set_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return; } mlme_priv->mlme_roam.roam_cfg.roam_trigger_bitmap = val; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); } uint8_t @@ -2805,7 +2954,7 @@ mlme_get_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) uint8_t bitmap; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2815,12 +2964,14 @@ mlme_get_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return 0xFF; } bitmap = mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + mlme_legacy_debug("vdev[%d] bitmap[0x%x]", vdev_id, + mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return bitmap; } @@ -2833,7 +2984,7 @@ mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct mlme_legacy_priv *mlme_priv; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); return; @@ -2842,7 +2993,7 @@ mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return; } @@ -2850,7 +3001,64 @@ mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap &= ~reqs; else mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap |= reqs; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + mlme_legacy_debug("vdev[%d] bitmap[0x%x], reqs: %d, clear: %d", vdev_id, + mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap, + reqs, clear); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); +} + +void +mlme_clear_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_OBJMGR_ID); + + if (!vdev) { + mlme_legacy_err("vdev object is NULL"); + return; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); + return; + } + + mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap = 0; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); +} + +QDF_STATUS mlme_get_cfg_wlm_level(struct wlan_objmgr_psoc *psoc, + uint8_t *level) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *level = mlme_obj->cfg.wlm_config.latency_level; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS mlme_get_cfg_wlm_reset(struct wlan_objmgr_psoc *psoc, + bool *reset) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *reset = mlme_obj->cfg.wlm_config.latency_reset; + + return QDF_STATUS_SUCCESS; } enum roam_offload_state @@ -2861,7 +3069,7 @@ mlme_get_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) enum roam_offload_state roam_state; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2871,12 +3079,12 @@ mlme_get_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return ROAM_DEINIT; } roam_state = mlme_priv->mlme_roam.roam_sm.state; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return roam_state; } @@ -2888,7 +3096,7 @@ void mlme_set_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct mlme_legacy_priv *mlme_priv; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, - WLAN_LEGACY_MAC_ID); + WLAN_MLME_OBJMGR_ID); if (!vdev) { mlme_legacy_err("vdev object is NULL"); @@ -2898,67 +3106,31 @@ void mlme_set_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { mlme_legacy_err("vdev legacy private object is NULL"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); return; } mlme_print_roaming_state(vdev_id, mlme_priv->mlme_roam.roam_sm.state, new_state); mlme_priv->mlme_roam.roam_sm.state = new_state; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); -} -#endif - -void mlme_set_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev, bool flag) -{ - struct mlme_legacy_priv *mlme_priv; - - mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); - if (!mlme_priv) { - mlme_legacy_err("vdev legacy private object is NULL"); - return; - } - - mlme_priv->follow_ap_edca = flag; -} - -bool mlme_get_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev) -{ - struct mlme_legacy_priv *mlme_priv; - - mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); - if (!mlme_priv) { - mlme_legacy_err("vdev legacy private object is NULL"); - return false; - } - - return mlme_priv->follow_ap_edca; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); } -void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, - bool is_pmf_enabled) +bool wlan_is_vdev_id_up(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) { - struct peer_mlme_priv_obj *peer_priv; + struct wlan_objmgr_vdev *vdev; + bool is_up = false; - peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, - WLAN_UMAC_COMP_MLME); - if (!peer_priv) { - mlme_legacy_err(" peer mlme component object is NULL"); - return; - } - peer_priv->is_pmf_enabled = is_pmf_enabled; -} + if (!pdev) + return is_up; -bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer) -{ - struct peer_mlme_priv_obj *peer_priv; - - peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, - WLAN_UMAC_COMP_MLME); - if (!peer_priv) { - mlme_legacy_err("peer mlme component object is NULL"); - return false; + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, + WLAN_LEGACY_MAC_ID); + if (vdev) { + is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev)); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); } - return peer_priv->is_pmf_enabled; + return is_up; } +#endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index 3d6b6af2c9eb48fcf4e5b53337200d09fceeb32e..a40ca88ffcc91a6fac329e1ee978a399acabb3c5 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/drivers/staging/qcacld-3.0/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,6 +24,9 @@ #include "wma_api.h" #include "lim_types.h" #include +#include <../../core/src/vdev_mgr_ops.h> +#include "wlan_psoc_mlme_api.h" +#include "wlan_crypto_global_api.h" static struct vdev_mlme_ops sta_mlme_ops; static struct vdev_mlme_ops ap_mlme_ops; @@ -569,17 +572,14 @@ static QDF_STATUS ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, bool val) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->chan_switch_in_progress = val; return QDF_STATUS_SUCCESS; @@ -587,17 +587,14 @@ QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, bool mlme_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->chan_switch_in_progress; } @@ -605,17 +602,14 @@ QDF_STATUS ap_mlme_set_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev, bool val) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->hidden_ssid_restart_in_progress = val; return QDF_STATUS_SUCCESS; @@ -623,33 +617,27 @@ ap_mlme_set_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev, bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->hidden_ssid_restart_in_progress; } QDF_STATUS mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->connection_fail = val; return QDF_STATUS_SUCCESS; @@ -657,69 +645,159 @@ QDF_STATUS mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val) bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->connection_fail; } +#ifdef FEATURE_WLAN_WAPI +static void mlme_is_sta_vdev_wapi(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + int32_t keymgmt; + bool *is_wapi_sta_exist = (bool *)arg; + QDF_STATUS status; + + if (*is_wapi_sta_exist) + return; + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) + return; + + status = wlan_vdev_is_up(vdev); + if (QDF_IS_STATUS_ERROR(status)) + return; + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + if (keymgmt < 0) + return; + + if (keymgmt & ((1 << WLAN_CRYPTO_KEY_MGMT_WAPI_PSK) | + (1 << WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))) { + *is_wapi_sta_exist = true; + mlme_debug("wapi exist for Vdev: %d", + wlan_vdev_get_id(vdev)); + } +} + +bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev) +{ + bool is_wapi_sta_exist = false; + + wlan_objmgr_pdev_iterate_obj_list(pdev, + WLAN_VDEV_OP, + mlme_is_sta_vdev_wapi, + &is_wapi_sta_exist, 0, + WLAN_MLME_OBJMGR_ID); + + return is_wapi_sta_exist; +} +#endif + QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev, enum vdev_assoc_type assoc_type) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->assoc_type = assoc_type; return QDF_STATUS_SUCCESS; } +QDF_STATUS mlme_get_vdev_bss_peer_mac_addr( + struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *bss_peer_mac_address) +{ + struct wlan_objmgr_peer *peer; + + if (!vdev) { + mlme_legacy_err("vdev is null"); + return QDF_STATUS_E_INVAL; + } + + peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID); + if (!peer) { + mlme_legacy_err("peer is null"); + return QDF_STATUS_E_INVAL; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer), + QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS mlme_get_vdev_stop_type(struct wlan_objmgr_vdev *vdev, + uint32_t *vdev_stop_type) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + *vdev_stop_type = mlme_priv->vdev_stop_type; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS mlme_set_vdev_stop_type(struct wlan_objmgr_vdev *vdev, + uint32_t vdev_stop_type) +{ + struct mlme_legacy_priv *mlme_priv; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv->vdev_stop_type = vdev_stop_type; + + return QDF_STATUS_SUCCESS; +} + enum vdev_assoc_type mlme_get_assoc_type(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->assoc_type; } QDF_STATUS mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->vdev_start_failed = val; return QDF_STATUS_SUCCESS; @@ -727,33 +805,27 @@ mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val) bool mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->vdev_start_failed; } QDF_STATUS mlme_set_cac_required(struct wlan_objmgr_vdev *vdev, bool val) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return QDF_STATUS_E_FAILURE; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - mlme_priv->cac_required_for_new_channel = val; return QDF_STATUS_SUCCESS; @@ -761,17 +833,14 @@ QDF_STATUS mlme_set_cac_required(struct wlan_objmgr_vdev *vdev, bool val) bool mlme_get_cac_required(struct wlan_objmgr_vdev *vdev) { - struct vdev_mlme_obj *vdev_mlme; struct mlme_legacy_priv *mlme_priv; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_legacy_err("vdev component object is NULL"); + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); return false; } - mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->ext_vdev_ptr; - return mlme_priv->cac_required_for_new_channel; } @@ -797,7 +866,7 @@ QDF_STATUS mlme_set_mbssid_info(struct wlan_objmgr_vdev *vdev, } void mlme_get_mbssid_info(struct wlan_objmgr_vdev *vdev, - struct vdev_mlme_mbss_11ax **mbss_11ax) + struct vdev_mlme_mbss_11ax *mbss_11ax) { struct vdev_mlme_obj *vdev_mlme; @@ -807,7 +876,135 @@ void mlme_get_mbssid_info(struct wlan_objmgr_vdev *vdev, return; } - *mbss_11ax = &vdev_mlme->mgmt.mbss_11ax; + mbss_11ax = &vdev_mlme->mgmt.mbss_11ax; +} + +QDF_STATUS mlme_set_tx_power(struct wlan_objmgr_vdev *vdev, + int8_t tx_power) +{ + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + + if (!vdev_mlme) { + mlme_legacy_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + vdev_mlme->mgmt.generic.tx_power = tx_power; + + return QDF_STATUS_SUCCESS; +} + +int8_t mlme_get_tx_power(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_legacy_err("vdev component object is NULL"); + return QDF_STATUS_E_INVAL; + } + + return vdev_mlme->mgmt.generic.tx_power; +} + +QDF_STATUS mlme_set_max_reg_power(struct wlan_objmgr_vdev *vdev, + int8_t max_reg_power) +{ + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + + if (!vdev_mlme) { + mlme_legacy_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + vdev_mlme->mgmt.generic.maxregpower = max_reg_power; + + return QDF_STATUS_SUCCESS; +} + +int8_t mlme_get_max_reg_power(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_legacy_err("vdev component object is NULL"); + return QDF_STATUS_E_INVAL; + } + + return vdev_mlme->mgmt.generic.maxregpower; +} + +/** + * mlme_get_vdev_types() - get vdev type and subtype from its operation mode + * @mode: operation mode of vdev + * @type: type of vdev + * @sub_type: sub_type of vdev + * + * This API is called to get vdev type and subtype from its operation mode. + * Vdev operation modes are defined in enum QDF_OPMODE. + * + * Type of vdev are WLAN_VDEV_MLME_TYPE_AP, WLAN_VDEV_MLME_TYPE_STA, + * WLAN_VDEV_MLME_TYPE_IBSS, ,WLAN_VDEV_MLME_TYPE_MONITOR, + * WLAN_VDEV_MLME_TYPE_NAN, WLAN_VDEV_MLME_TYPE_OCB, WLAN_VDEV_MLME_TYPE_NDI + * + * Sub_types of vdev are WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE, + * WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT, WLAN_VDEV_MLME_SUBTYPE_P2P_GO, + * WLAN_VDEV_MLME_SUBTYPE_PROXY_STA, WLAN_VDEV_MLME_SUBTYPE_MESH + * Return: QDF_STATUS + */ + +static QDF_STATUS mlme_get_vdev_types(enum QDF_OPMODE mode, uint8_t *type, + uint8_t *sub_type) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + *type = 0; + *sub_type = 0; + + switch (mode) { + case QDF_STA_MODE: + *type = WLAN_VDEV_MLME_TYPE_STA; + break; + case QDF_SAP_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + break; + case QDF_P2P_DEVICE_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE; + break; + case QDF_P2P_CLIENT_MODE: + *type = WLAN_VDEV_MLME_TYPE_STA; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT; + break; + case QDF_P2P_GO_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_GO; + break; + case QDF_OCB_MODE: + *type = WLAN_VDEV_MLME_TYPE_OCB; + break; + case QDF_IBSS_MODE: + *type = WLAN_VDEV_MLME_TYPE_IBSS; + break; + case QDF_MONITOR_MODE: + *type = WMI_HOST_VDEV_TYPE_MONITOR; + break; + case QDF_NDI_MODE: + *type = WLAN_VDEV_MLME_TYPE_NDI; + break; + case QDF_NAN_DISC_MODE: + *type = WLAN_VDEV_MLME_TYPE_NAN; + break; + default: + mlme_err("Invalid device mode %d", mode); + status = QDF_STATUS_E_INVAL; + break; + } + return status; } /** @@ -819,6 +1016,8 @@ void mlme_get_mbssid_info(struct wlan_objmgr_vdev *vdev, static QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) { + QDF_STATUS status; + mlme_legacy_debug("vdev id = %d ", vdev_mlme->vdev->vdev_objmgr.vdev_id); vdev_mlme->ext_vdev_ptr = @@ -828,7 +1027,28 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) return QDF_STATUS_E_NOMEM; } - return QDF_STATUS_SUCCESS; + sme_get_vdev_type_nss(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev), + &vdev_mlme->proto.generic.nss_2g, + &vdev_mlme->proto.generic.nss_5g); + + status = mlme_get_vdev_types(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev), + &vdev_mlme->mgmt.generic.type, + &vdev_mlme->mgmt.generic.subtype); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Get vdev type failed; status:%d", status); + qdf_mem_free(vdev_mlme->ext_vdev_ptr); + return status; + } + + status = vdev_mgr_create_send(vdev_mlme); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Failed to create vdev for vdev id %d", + wlan_vdev_get_id(vdev_mlme->vdev)); + qdf_mem_free(vdev_mlme->ext_vdev_ptr); + return status; + } + + return status; } /** @@ -848,6 +1068,7 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme) mlme_free_self_disconnect_ies(vdev_mlme->vdev); mlme_free_peer_disconnect_ies(vdev_mlme->vdev); + mlme_free_sae_auth_retry(vdev_mlme->vdev); qdf_mem_free(vdev_mlme->ext_vdev_ptr); vdev_mlme->ext_vdev_ptr = NULL; @@ -986,6 +1207,127 @@ static QDF_STATUS mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, return wma_mon_mlme_vdev_down_send(vdev_mlme, data_len, data); } +/** + * vdevmgr_vdev_delete_rsp_handle() - callback to handle vdev delete response + * @vdev_mlme: vdev mlme object + * @rsp: pointer to vdev delete response + * + * This function is called to handle vdev delete response and send result to + * upper layer + * + * Return: QDF_STATUS + */ +static QDF_STATUS +vdevmgr_vdev_delete_rsp_handle(struct wlan_objmgr_psoc *psoc, + struct vdev_delete_response *rsp) +{ + mlme_legacy_debug("vdev id = %d ", rsp->vdev_id); + return wma_vdev_detach_callback(rsp); +} + +/** + * vdevmgr_vdev_stop_rsp_handle() - callback to handle vdev stop response + * @vdev_mlme: vdev mlme object + * @rsp: pointer to vdev stop response + * + * This function is called to handle vdev stop response and send result to + * upper layer + * + * Return: QDF_STATUS + */ +static QDF_STATUS +vdevmgr_vdev_stop_rsp_handle(struct vdev_mlme_obj *vdev_mlme, + struct vdev_stop_response *rsp) +{ + mlme_legacy_debug("vdev id = %d ", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + return wma_vdev_stop_resp_handler(vdev_mlme, rsp); +} + +/** + * psoc_mlme_ext_hdl_create() - Create mlme legacy priv object + * @psoc_mlme: psoc mlme object + * + * Return: QDF_STATUS + */ +static +QDF_STATUS psoc_mlme_ext_hdl_create(struct psoc_mlme_obj *psoc_mlme) +{ + psoc_mlme->ext_psoc_ptr = + qdf_mem_malloc(sizeof(struct wlan_mlme_psoc_ext_obj)); + if (!psoc_mlme->ext_psoc_ptr) { + mlme_legacy_err("Failed to allocate memory"); + return QDF_STATUS_E_NOMEM; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * psoc_mlme_ext_hdl_destroy() - Destroy mlme legacy priv object + * @psoc_mlme: psoc mlme object + * + * Return: QDF_STATUS + */ +static +QDF_STATUS psoc_mlme_ext_hdl_destroy(struct psoc_mlme_obj *psoc_mlme) +{ + if (!psoc_mlme) { + mlme_err("PSOC MLME is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (psoc_mlme->ext_psoc_ptr) { + qdf_mem_free(psoc_mlme->ext_psoc_ptr); + psoc_mlme->ext_psoc_ptr = NULL; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * vdevmgr_vdev_delete_rsp_handle() - callback to handle vdev delete response + * @vdev_mlme: vdev mlme object + * @rsp: pointer to vdev delete response + * + * This function is called to handle vdev delete response and send result to + * upper layer + * + * Return: QDF_STATUS + */ +static QDF_STATUS +vdevmgr_vdev_start_rsp_handle(struct vdev_mlme_obj *vdev_mlme, + struct vdev_start_response *rsp) +{ + QDF_STATUS status; + + mlme_legacy_debug("vdev id = %d ", + vdev_mlme->vdev->vdev_objmgr.vdev_id); + status = wma_vdev_start_resp_handler(vdev_mlme, rsp); + + return status; +} + +QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + mlme_err("Failed to get vdev mlme obj for vdev id %d", + wlan_vdev_get_id(vdev)); + return QDF_STATUS_E_INVAL; + } + + return wma_vdev_self_peer_create(vdev_mlme); +} + +static +QDF_STATUS vdevmgr_mlme_ext_post_hdl_create(struct vdev_mlme_obj *vdev_mlme) +{ + return QDF_STATUS_SUCCESS; +} + /** * struct sta_mlme_ops - VDEV MLME operation callbacks strucutre for sta * @mlme_vdev_start_send: callback to initiate actions of VDEV @@ -1027,6 +1369,8 @@ static struct vdev_mlme_ops sta_mlme_ops = { .mlme_vdev_stop_continue = vdevmgr_mlme_stop_continue, .mlme_vdev_down_send = vdevmgr_mlme_vdev_down_send, .mlme_vdev_notify_down_complete = vdevmgr_notify_down_complete, + .mlme_vdev_ext_stop_rsp = vdevmgr_vdev_stop_rsp_handle, + .mlme_vdev_ext_start_rsp = vdevmgr_vdev_start_rsp_handle, }; /** @@ -1075,6 +1419,8 @@ static struct vdev_mlme_ops ap_mlme_ops = { .mlme_vdev_down_send = vdevmgr_mlme_vdev_down_send, .mlme_vdev_notify_down_complete = vdevmgr_notify_down_complete, .mlme_vdev_is_newchan_no_cac = ap_mlme_vdev_is_newchan_no_cac, + .mlme_vdev_ext_stop_rsp = vdevmgr_vdev_stop_rsp_handle, + .mlme_vdev_ext_start_rsp = vdevmgr_vdev_start_rsp_handle, }; static struct vdev_mlme_ops mon_mlme_ops = { @@ -1085,16 +1431,14 @@ static struct vdev_mlme_ops mon_mlme_ops = { .mlme_vdev_disconnect_peers = mon_mlme_vdev_disconnect_peers, .mlme_vdev_stop_send = mon_mlme_vdev_stop_send, .mlme_vdev_down_send = mon_mlme_vdev_down_send, + .mlme_vdev_ext_start_rsp = vdevmgr_vdev_start_rsp_handle, }; -/** - * struct mlme_ext_ops - VDEV MLME legacy global callbacks structure - * @mlme_vdev_ext_hdl_create: callback to invoke creation of legacy - * vdev object - * @mlme_vdev_ext_hdl_destroy: callback to invoke destroy of legacy - * vdev object - */ static struct mlme_ext_ops ext_ops = { + .mlme_psoc_ext_hdl_create = psoc_mlme_ext_hdl_create, + .mlme_psoc_ext_hdl_destroy = psoc_mlme_ext_hdl_destroy, .mlme_vdev_ext_hdl_create = vdevmgr_mlme_ext_hdl_create, .mlme_vdev_ext_hdl_destroy = vdevmgr_mlme_ext_hdl_destroy, + .mlme_vdev_ext_hdl_post_create = vdevmgr_mlme_ext_post_hdl_create, + .mlme_vdev_ext_delete_rsp = vdevmgr_vdev_delete_rsp_handle, }; diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_acs.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_acs.h index 45314720b065f6f218121e135b1e99851c27d867..3cb820e6efd6d7bdd129dfda82e9ac0d2af0750a 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_acs.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_acs.h @@ -125,44 +125,6 @@ 0, \ "Acs support for lte coex and dfs") -/* - * - * np_chan_weight - chan weightage for non preferred channels - * @Min: 0x00000000 - * @Max: 0x64646464 - * @Default: 0x00000000 - * - * This INI give percentage value of weights to be considered in the ACS algo - * for the non preferred channels. the distribution of the channel type is:- - * Example:- If the percentage of lets say DFS channels is set to 50%, and - * the weight comes out to be x, then we would increase the weight of DFS - * channels by 50% ( 100 - y% set in INI), so that it gets de-prioritized in - * the ACS sorted channel list, the lesser the weight, the better the channel. - * So the channel with more weight is less likely to be selected. So by default - * the np chan weightage for DFS is set to 0, that is it will be assigned max - * weightage, so no probality of getting selected, as for standlaone, DFS is not - * recommended (it takes 60 sec/10min to start depending upon channel type). - * - * Indexes are defined in this way. - * 0 Index (BITS 0-7): DFS - Def 0% - * 1 Index (BITS 8-15): Reserved - * 2 Index (BITS 16-23): Reserved - * 3 Index (BITS 24-31): Reserved - * These percentage values are stored in HEX. Max can be 0x64 - * Supported Feature: ACS - * - * Usage: External - * - * - */ -#define CFG_ACS_NP_CHAN_WEIGHT CFG_INI_UINT( \ - "np_chan_weight", \ - 0x00000000, \ - 0x64646464, \ - 0x00000000, \ - CFG_VALUE_OR_DEFAULT, \ - "np chan weight") - /* * * acs_policy - External ACS policy control @@ -193,6 +155,30 @@ 1, \ "External ACS Policy Control") +#define ACS_WEIGHT_MAX_STR_LEN 500 + +/* + * + * normalize_acs_weight - Used to control the ACS channel weightage. + * + * This ini is used to specify the weight percentage of the channel. Channel + * weights can be controlled by user to prioritize or de-prioritize channels. + * + * Related: ACS + * + * Supported Feature: ACS + * + * Usage: External + * + * + */ +#define CFG_NORMALIZE_ACS_WEIGHT CFG_INI_STRING( \ + "normalize_acs_weight", \ + 0, \ + ACS_WEIGHT_MAX_STR_LEN, \ + "5940-7105=0, 5965=100, 6045=100, 6125=100, 6205=100, 6285=100, 6365=100, 6605=100, 6685=100, 6765=100, 6845=100", \ + "Used to specify the channel weights") + /* * * force_start_sap- Enable the SAP even if no channel is suitable for SAP @@ -216,13 +202,52 @@ 0, \ "Force start SAP") +/* + * + * np_chan_weight - chan weightage for non preferred channels + * @Min: 0x00000000 + * @Max: 0x64646464 + * @Default: 0x00000000 + * + * This INI give percentage value of weights to be considered in the ACS algo + * for the non preferred channels. the distribution of the channel type is:- + * Example:- If the percentage of lets say DFS channels is set to 50%, and + * the weight comes out to be x, then we would increase the weight of DFS + * channels by 50% ( 100 - y% set in INI), so that it gets de-prioritized in + * the ACS sorted channel list, the lesser the weight, the better the channel. + * So the channel with more weight is less likely to be selected. So by default + * the np chan weightage for DFS is set to 0, that is it will be assigned max + * weightage, so no probality of getting selected, as for standlaone, DFS is not + * recommended (it takes 60 sec/10min to start depending upon channel type). + * + * Indexes are defined in this way. + * 0 Index (BITS 0-7): DFS - Def 0% + * 1 Index (BITS 8-15): Reserved + * 2 Index (BITS 16-23): Reserved + * 3 Index (BITS 24-31): Reserved + * These percentage values are stored in HEX. Max can be 0x64 + * Supported Feature: ACS + * + * Usage: External + * + * + */ +#define CFG_ACS_NP_CHAN_WEIGHT CFG_INI_UINT( \ + "np_chan_weight", \ + 0x00000000, \ + 0x64646464, \ + 0x00000000, \ + CFG_VALUE_OR_DEFAULT, \ + "np chan weight") + #define CFG_ACS_ALL \ CFG(CFG_ACS_WITH_MORE_PARAM) \ CFG(CFG_AUTO_CHANNEL_SELECT_WEIGHT) \ - CFG(CFG_ACS_NP_CHAN_WEIGHT) \ CFG(CFG_USER_AUTO_CHANNEL_SELECTION) \ CFG(CFG_USER_ACS_DFS_LTE) \ CFG(CFG_EXTERNAL_ACS_POLICY) \ - CFG(CFG_ACS_FORCE_START_SAP) + CFG(CFG_NORMALIZE_ACS_WEIGHT) \ + CFG(CFG_ACS_FORCE_START_SAP) \ + CFG(CFG_ACS_NP_CHAN_WEIGHT) #endif /* __CFG_MLME_ACS_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dfs.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dfs.h index bfc476382689c6b0534ed2ca2efc54e0e06173a3..e1a1eea334f2f4fad395ec37ad3c519c2ae2b45e 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dfs.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -47,6 +47,31 @@ CFG_VALUE_OR_DEFAULT, \ "sap tx leakage threshold") +/* + * + * gDFSradarMappingPriMultiplier - dfs pri multiplier + * @Min: 1 + * @Max: 10 + * @Default: 2 + * + * customer can set this value from 1 to 10 which means + * host could handle missing pulses while there is high + * channel loading, for example: 30% ETSI and 50% Japan W53 + * + * Related: none + * + * Usage: External + * + * + */ +#define CFG_DFS_RADAR_PRI_MULTIPLIER CFG_INI_UINT( \ + "gDFSradarMappingPriMultiplier", \ + 1, \ + 10, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "dfs pri multiplier") + /* * * gDfsBeaconTxEnhanced - beacon tx enhanced @@ -203,6 +228,7 @@ CFG(CFG_DISABLE_DFS_CH_SWITCH) \ CFG(CFG_DFS_BEACON_TX_ENHANCED) \ CFG(CFG_SAP_TX_LEAKAGE_THRESHOLD) \ + CFG(CFG_DFS_RADAR_PRI_MULTIPLIER) \ CFG(CFG_ENABLE_NON_DFS_CHAN_ON_RADAR) \ CFG(CFG_ENABLE_DFS_MASTER_CAPABILITY) \ CFG(CFG_DISABLE_DFS_JAPAN_W53) \ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dot11mode.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dot11mode.h index 0125a62402e083afb5004ee3da277c6504aa6af8..fad8e6357a8cda446fc03256b44ba84d63c86088 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dot11mode.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_dot11mode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -31,8 +31,58 @@ CFG_VALUE_OR_DEFAULT, \ "dot 11 mode") +/* + * + * vdev_dot11_mode- Bit mask to set the dot11 mode for different vdev types + * @Min: 0x0 + * @Max: 0x333333 + * @Default: 0 + * + * This ini is used to set the dot11mode different vdev types. + * dot11_mode ini value (CFG_DOT11_MODE) is the master configuration + * Min configuration of INI dot11_mode and vdev_dot11_mode is used for that + * vdev type. + * dot11_mode vdev_dot11_mode dot11_mode_used + * 11AX 11AC 11AC + * 11AC 11AX 11AC + * + * Dot11 mode value is 4 bit length for each vdev. Below is the bit definition + * for different vdev types dot11 mode value bit index. + * + * Bits used for dot11mode Vdev Type + * BIT[3:0] STA mode + * BIT[7:4] P2P_CLI/P2P_DEVICE mode + * BIT[11:8] NAN DISCOVERY + * BIT[15:12] OCB + * BIT[19:16] TDLS + * BIT[23:20] NDI mode + * + * Dot11 mode value to be set in the above bit definition: + * 0 - Auto, Uses CFG_DOT11_MODE setting + * 1 - HT mode(11N) + * 2 - VHT mode(11AC) + * 3 - HE mode(11AX) + * + * E.g: vdev_dot11_mode=0x013220 + * + * 0 1 3 2 2 0 + * NDI(auto) TDLS HT OCB_HE VHT NAN_DISC VHT P2P STA_AUTO + * + * Usage: Internal/External + * + * + */ +#define CFG_VDEV_DOT11_MODE CFG_INI_UINT( \ + "vdev_dot11_mode", \ + 0, \ + 0x333333, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "vdev dot 11 mode") + #define CFG_DOT11_MODE_ALL \ CFG(CFG_DOT11_MODE) \ + CFG(CFG_VDEV_DOT11_MODE) \ #endif /* __CFG_MLME_DOT11MODE_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_rrm.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_rrm.h index 9a81b7a743634a77b663e22cc37612655a07d38b..9ce59b4e9d9a31d858aa533ac80bdf59275a687d 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_rrm.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_rrm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,19 +25,19 @@ /* * - * gRrmEnable - Enable/Disable RRM + * gRrmEnable - Enable/Disable RRM on STA * @Min: 0 * @Max: 1 * @Default: 0 * * This ini is used to controls the capabilities (11 k) included - * in the capabilities field. + * in the capabilities field for STA. * * Related: None. * * Supported Feature: 11k * - * Usage: Internal/External + * Usage: Internal * * */ @@ -45,6 +45,28 @@ 0, \ "Enable/Disable RRM") +/* + * + * sap_rrm_enable - Enable/Disable RRM on SAP + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to control the capabilities (11 k) included + * in the capabilities field for SAP. + * + * Related: None. + * + * Supported Feature: 11k + * + * Usage: Internal + * + * + */ +#define CFG_SAP_RRM_ENABLE CFG_INI_BOOL("sap_rrm_enable", \ + 0, \ + "Enable/Disable RRM on SAP") + /* * * gRrmRandnIntvl - Randomization interval @@ -100,6 +122,7 @@ #define CFG_FE_RRM_ALL \ CFG(CFG_RRM_ENABLE) \ + CFG(CFG_SAP_RRM_ENABLE) \ CFG(CFG_RRM_MEAS_RAND_INTVL) \ CFG(CFG_RM_CAPABILITY) diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h index c9411b03c19878d72fb40ccb0152370072837aa4..c5dbb256da3652e3385eca89e3df6ce09644f4f4 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,7 +29,7 @@ * * @min: 0 * @max: 1 - * @default: 0 + * @default: 1 * * 0 - disable * 1 - enable @@ -40,6 +40,23 @@ 1, \ "WLM latency Enable") +/* + * + * wlm_latency_reset_on_disconnect - WLM latency level reset on disconnect + * + * @min: 0 + * @max: 1 + * @default: 0 + * + * 0 - disable + * 1 - enable + * + * + */ +#define CFG_LATENCY_RESET CFG_INI_BOOL("wlm_latency_reset_on_disconnect", \ + 0, \ + "WLM latency reset on disconnect") + /* * * wlm_latency_level - WLM latency level @@ -237,6 +254,7 @@ #define CFG_FE_WLM_ALL \ CFG(CFG_LATENCY_ENABLE) \ + CFG(CFG_LATENCY_RESET) \ CFG(CFG_LATENCY_LEVEL) \ CFG(CFG_LATENCY_FLAGS_NORMAL) \ CFG(CFG_LATENCY_FLAGS_MOD) \ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_generic.h index 349487e405e2c61aed78bba479a28b113644b97d..567ddca9514e8a5bfc5c8f294751ef1b4512d88f 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_generic.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_generic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -140,13 +140,21 @@ /* * - * BandCapability - Preferred band (0: Both, 1: 2.4G only, 2: 5G only) + * BandCapability - Preferred band (0: Both 2.4G and 5G, + * 1: 2.4G only, + * 2: 5G only, + * 3: Both 2.4G and 5G, + * 4: 6G only, + * 5: Both 2.4G and 6G, + * 6: Both 5G and 6G, + * 7: 2.4G, 5G, and 6G) * @Min: 0 - * @Max: 2 - * @Default: 0 + * @Max: 7 + * @Default: 7 * * This ini is used to set default band capability - * (0: Both, 1: 2.4G only, 2: 5G only) + * (0: Both 2.4G and 5G, 1: 2.4G only, 2: 5G only, 3: Both 2.4G and 5G, + * 4: 6G only, 5: Both 2.4G and 6G, 6: Both 5G and 6G, 7: 2.4G, 5G, and 6G) * * Related: None * @@ -159,8 +167,8 @@ #define CFG_BAND_CAPABILITY CFG_INI_UINT( \ "BandCapability", \ 0, \ - 2, \ - 0, \ + 7, \ + 7, \ CFG_VALUE_OR_DEFAULT, \ "Band Capability") @@ -595,6 +603,28 @@ 0, \ "Enable to remove time stamp sync cmd") +/* + * + * disable_4way_hs_offload - Enable/Disable 4 way handshake offload to firmware + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * 0 4-way HS to be handled in firmware + * 1 4-way HS to be handled in supplicant + * + * Related: None + * + * Supported Feature: STA Roaming + * + * Usage: External + * + * + */ +#define CFG_DISABLE_4WAY_HS_OFFLOAD CFG_INI_BOOL("disable_4way_hs_offload", \ + 0, \ + "Enable/disable 4 way handshake offload to firmware") + /* * * mgmt_retry_max - Maximum Retries for mgmt frames @@ -642,6 +672,7 @@ #define CFG_BMISS_SKIP_FULL_SCAN CFG_INI_BOOL("bmiss_skip_full_scan", \ 0, \ "To decide partial/partial scan followed by full scan") + /* * * gEnableRingBuffer - Enable Ring Buffer for Bug Report @@ -660,54 +691,52 @@ * */ #define CFG_ENABLE_RING_BUFFER CFG_INI_BOOL( \ - "gEnableRingBuffer", \ - 1, \ - "To Enable Ring Buffer") + "gEnableRingBuffer", \ + 1, \ + "To Enable Ring Buffer") /* * - * disable_4way_hs_offload - Enable/Disable 4 way handshake offload to firmware - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * 0 4-way HS to be handled in firmware - * 1 4-way HS to be handled in supplicant + * sae_connect_retries - Bit mask to retry Auth and full connection on assoc + * timeout to same AP and auth retries during roaming + * @Min: 0x0 + * @Max: 0x53 + * @Default: 0x49 + * + * This ini is used to set max auth retry in auth phase of roaming and initial + * connection and max connection retry in case of assoc timeout. MAX Auth + * retries are capped to 3, connection retries are capped to 2 and roam Auth + * retry is capped to 1. + * Default is 0x49 i.e. 1 retry each. + * + * Bits Retry Type + * BIT[0:2] AUTH retries + * BIT[3:5] Connection reties + * BIT[6:8] ROAM AUTH retries + * + * Some Possible values are as below + * 0 - NO auth/roam Auth retry and NO full connection retry after + * assoc timeout + * 0x49 - 1 auth/roam auth retry and 1 full connection retry + * 0x52 - 1 roam auth retry, 2 auth retry and 2 full connection retry + * 0x1 /0x2 - 0 roam auth retry, 1 or 2 auth retry respectively and NO full + * connection retry + * 0x8 /0x10 - 0 roam auth retry,NO auth retry and 1 or 2 full connection retry + * respectively. + * 0x4A - 1 roam auth retry,2 auth retry and 1 full connection retry + * 0x51 - 1 auth/roam auth retry and 2 full connection retry * * Related: None * - * Supported Feature: STA Roaming - * - * Usage: External - * - * - */ -#define CFG_DISABLE_4WAY_HS_OFFLOAD CFG_INI_BOOL("disable_4way_hs_offload", \ - 0, \ - "Enable/disable 4 way handshake offload to firmware") - -/* - * - * dfs_chan_ageout_time - Set DFS Channel ageout time(in seconds) - * @Min: 0 - * @Max: 8 - * Default: 0 - * - * Ageout time is the time upto which DFS channel information such as beacon - * found is remembered. So that Firmware performs Active scan instead of the - * Passive to reduce the Dwell time. - * This ini Parameter used to set ageout timer value from host to FW. - * If not set, Firmware will disable ageout time. - * - * Supported Feature: STA scan in DFS channels + * Supported Feature: STA SAE * * Usage: External * * */ -#define CFG_DFS_CHAN_AGEOUT_TIME CFG_INI_UINT("dfs_chan_ageout_time", \ - 0, 8, 0, CFG_VALUE_OR_DEFAULT, \ - "Set DFS Channel ageout time from host to firmware") +#define CFG_SAE_CONNECION_RETRIES CFG_INI_UINT("sae_connect_retries", \ + 0, 0x53, 0x49, CFG_VALUE_OR_DEFAULT, \ + "Bit mask to retry Auth and full connection on assoc timeout to same AP for SAE connection") #define CFG_GENERIC_ALL \ CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \ @@ -739,5 +768,5 @@ CFG(CFG_MGMT_RETRY_MAX) \ CFG(CFG_BMISS_SKIP_FULL_SCAN) \ CFG(CFG_ENABLE_RING_BUFFER) \ - CFG(CFG_DFS_CHAN_AGEOUT_TIME) + CFG(CFG_SAE_CONNECION_RETRIES) #endif /* __CFG_MLME_GENERIC_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h index 7fd251e041e7fc068cde936c82a5b5ee62a8e512..ecba16b1e8a4f9f350ad267969ad6ce463d459b3 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_he_caps.h @@ -507,35 +507,158 @@ 0, \ "He Rx Full Bw Mu Non Cmpr Sigb") -#define CFG_HE_RX_MCS_MAP_LT_80 CFG_UINT( \ +/* 11AX related INI configuration */ +/* + * + * he_rx_mcs_map_lt_80 - configure Rx HE-MCS Map for ≤ 80 MHz + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0xFFFA + * + * This ini is used to configure Rx HE-MCS Map for ≤ 80 MHz + * 0:1 Max HE-MCS For 1 SS + * 2:3 Max HE-MCS For 2 SS + * 4:5 Max HE-MCS For 3 SS + * 6:7 Max HE-MCS For 4 SS + * 8:9 Max HE-MCS For 5 SS + * 10:11 Max HE-MCS For 6 SS + * 12:13 Max HE-MCS For 7 SS + * 14:15 Max HE-MCS For 8 SS + * + * 0 indicates support for HE-MCS 0-7 for n spatial streams + * 1 indicates support for HE-MCS 0-9 for n spatial streams + * 2 indicates support for HE-MCS 0-11 for n spatial streams + * 3 indicates that n spatial streams is not supported for HE PPDUs + * + * Related: NA + * + * Supported Feature: 11AX + * + * Usage: External + * + * + */ +#define CFG_HE_RX_MCS_MAP_LT_80 CFG_INI_UINT( \ "he_rx_mcs_map_lt_80", \ 0, \ 0xFFFF, \ - 0xFFF0, \ + 0xFFFA, \ CFG_VALUE_OR_DEFAULT, \ "He Rx Mcs Map Lt 80") -#define CFG_HE_TX_MCS_MAP_LT_80 CFG_UINT( \ +/* 11AX related INI configuration */ +/* + * + * he_tx_mcs_map_lt_80 - configure Tx HE-MCS Map for ≤ 80 MHz + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0xFFFA + * + * This ini is used to configure Tx HE-MCS Map for ≤ 80 MHz + * 0:1 Max HE-MCS For 1 SS + * 2:3 Max HE-MCS For 2 SS + * 4:5 Max HE-MCS For 3 SS + * 6:7 Max HE-MCS For 4 SS + * 8:9 Max HE-MCS For 5 SS + * 10:11 Max HE-MCS For 6 SS + * 12:13 Max HE-MCS For 7 SS + * 14:15 Max HE-MCS For 8 SS + * + * 0 indicates support for HE-MCS 0-7 for n spatial streams + * 1 indicates support for HE-MCS 0-9 for n spatial streams + * 2 indicates support for HE-MCS 0-11 for n spatial streams + * 3 indicates that n spatial streams is not supported for HE PPDUs + * + * Related: NA + * + * Supported Feature: 11AX + * + * Usage: External + * + * + */ +#define CFG_HE_TX_MCS_MAP_LT_80 CFG_INI_UINT( \ "he_tx_mcs_map_lt_80", \ 0, \ 0xFFFF, \ - 0xFFF0, \ + 0xFFFA, \ CFG_VALUE_OR_DEFAULT, \ "He Tx Mcs Map Lt 80") - -#define CFG_HE_RX_MCS_MAP_160 CFG_UINT( \ +/* 11AX related INI configuration */ +/* + * + * he_rx_mcs_map_160 - configure Rx HE-MCS Map for 160 MHz + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0xFFFA + * + * This ini is used to configure Rx HE-MCS Map for 160 MHz + * 0:1 Max HE-MCS For 1 SS + * 2:3 Max HE-MCS For 2 SS + * 4:5 Max HE-MCS For 3 SS + * 6:7 Max HE-MCS For 4 SS + * 8:9 Max HE-MCS For 5 SS + * 10:11 Max HE-MCS For 6 SS + * 12:13 Max HE-MCS For 7 SS + * 14:15 Max HE-MCS For 8 SS + * + * 0 indicates support for HE-MCS 0-7 for n spatial streams + * 1 indicates support for HE-MCS 0-9 for n spatial streams + * 2 indicates support for HE-MCS 0-11 for n spatial streams + * 3 indicates that n spatial streams is not supported for HE PPDUs + * + * Related: NA + * + * Supported Feature: 11AX + * + * Usage: External + * + * + */ +#define CFG_HE_RX_MCS_MAP_160 CFG_INI_UINT( \ "he_rx_mcs_map_160", \ 0, \ 0xFFFF, \ - 0xFFF0, \ + 0xFFFA, \ CFG_VALUE_OR_DEFAULT, \ "He Rx Mcs Map 160") -#define CFG_HE_TX_MCS_MAP_160 CFG_UINT( \ +/* 11AX related INI configuration */ +/* + * + * he_tx_mcs_map_160 - configure Tx HE-MCS Map for 160 MHz + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0xFFFA + * + * This ini is used to configure Tx HE-MCS Map for 160 MHz + * 0:1 Max HE-MCS For 1 SS + * 2:3 Max HE-MCS For 2 SS + * 4:5 Max HE-MCS For 3 SS + * 6:7 Max HE-MCS For 4 SS + * 8:9 Max HE-MCS For 5 SS + * 10:11 Max HE-MCS For 6 SS + * 12:13 Max HE-MCS For 7 SS + * 14:15 Max HE-MCS For 8 SS + * + * 0 indicates support for HE-MCS 0-7 for n spatial streams + * 1 indicates support for HE-MCS 0-9 for n spatial streams + * 2 indicates support for HE-MCS 0-11 for n spatial streams + * 3 indicates that n spatial streams is not supported for HE PPDUs + * + * Related: NA + * + * Supported Feature: 11AX + * + * Usage: External + * + * + */ +#define CFG_HE_TX_MCS_MAP_160 CFG_INI_UINT( \ "he_tx_mcs_map_160", \ 0, \ 0xFFFF, \ - 0xFFF0, \ + 0xFFFA, \ CFG_VALUE_OR_DEFAULT, \ "He Tx Mcs Map 160") diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h index 78b3a208ed5b6bd56a7810d315bfdf309a3f3184..71eb4111519709b303e3c3994a9fbc751c14acf2 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ht_caps.h @@ -292,8 +292,12 @@ * @Min: 0 * @Max: 15 * @Default: 0 - * gMaxAmsduNum is the number of MSDU's transmitted in the 11n aggregate + * + * gMaxAmsduNum is the number of MSDU's transmitted in the aggregated * frame. Setting it to a value larger than 1 enables transmit aggregation. + * Set the value to 0 to enable FW automode selection where it decides + * the maximum number of MSDUs in AMSDU based on connection mode. + * * It is a PHY parameter that applies to all vdev's in firmware. * * Supported Feature: 11n aggregation diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ibss.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ibss.h index 6295a0d54a927e961fbcba52efd0abc567a847c2..dd15791db384d72c936cbf2562fdfa5d1b8b0224 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ibss.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_ibss.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -42,13 +42,13 @@ /* * - * gAdHocChannel5G - Default 5Ghz IBSS channel if channel is not + * gAdHocChannel5G - Default 5Ghz IBSS channel if channel freq is not * provided by supplicant. - * @Min: 36 - * @Max: 165 - * @Default: 44 + * @Min: 5180 + * @Max: 5825 + * @Default: 5220 * - * This ini is used to set default 5Ghz IBSS channel + * This ini is used to set default 5Ghz IBSS channel frequency * if channel is not provided by supplicant and band is 5Ghz * * Related: None @@ -60,22 +60,22 @@ * */ #define CFG_IBSS_ADHOC_CHANNEL_5GHZ CFG_INI_UINT( \ - "gAdHocChannel5G", \ - 36, \ - 165, \ - 44, \ + "ad_hoc_ch_freq_5g", \ + 5180, \ + 5825, \ + 5220, \ CFG_VALUE_OR_DEFAULT, \ - "Default 5Ghz IBSS channel if not provided by supplicant") + "Default 5Ghz IBSS ch freq if not provided by supplicant") /* * - * gAdHocChannel24G - Default 2.4Ghz IBSS channel if channel is not + * gAdHocChannel24G - Default 2.4Ghz IBSS channel if channel freq is not * provided by supplicant. - * @Min: 1 - * @Max: 14 - * @Default: 6 + * @Min: 2412 + * @Max: 2484 + * @Default: 2437 * - * This ini is used to set default 2.4Ghz IBSS channel + * This ini is used to set default 2.4Ghz IBSS channel frequency * if channel is not provided by supplicant and band is 2.4Ghz * * Related: None @@ -87,12 +87,12 @@ * */ #define CFG_IBSS_ADHOC_CHANNEL_24GHZ CFG_INI_UINT( \ - "gAdHocChannel24G", \ - 1, \ - 14, \ - 6, \ + "ad_hoc_ch_freq_2g", \ + 2412, \ + 2484, \ + 2437, \ CFG_VALUE_OR_DEFAULT, \ - "Default 2.4Ghz IBSS channel if not provided by supplicant") + "Default 2.4Ghz IBSS ch freq if not provided by supplicant") /* * diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_lfr.h index 21ef8d17de1fa045ab146c61358b658724bd943f..123aaa80ada4945dcb8d378956b0febb8e38ba89 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_lfr.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_lfr.h @@ -115,7 +115,7 @@ * */ #define CFG_LFR_MAWC_ROAM_RSSI_HIGH_ADJUST CFG_INI_UINT( \ - "mawc_roam_ap_rssi_threshold", \ + "mawc_roam_rssi_high_adjust", \ 3, \ 5, \ 5, \ @@ -530,6 +530,93 @@ CFG_VALUE_OR_DEFAULT, \ "RSSI threshold offset for 2G to 5G roam") +/* + * + * roam_data_rssi_threshold_triggers - triggers of data rssi threshold for roam + * @Min: 0 + * @Max: 0xffff + * @Default: 0x3 + * + * If the DUT is connected to an AP with weak signal, during latest + * rx_data_inactivity_time, if there is no activity or avg of data_rssi is + * better than roam_data_rssi_threshold(-70dbM), then suppress roaming + * triggered by roam_data_rssi_threshold_triggers: low RSSI or bg scan. + * Triggers bitmap definition: + * ROAM_DATA_RSSI_FLAG_LOW_RSSI 1<<0 + * ROAM_DATA_RSSI_FLAG_BACKGROUND 1<<1 + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_ROAM_DATA_RSSI_THRESHOLD_TRIGGERS CFG_INI_UINT( \ + "roam_data_rssi_threshold_triggers", \ + 0, \ + 0xffff, \ + 0x3, \ + CFG_VALUE_OR_DEFAULT, \ + "Triggers of DATA RSSI threshold for roam") + +/* + * + * roam_data_rssi_threshold - Data RSSI threshold for background roam + * @Min: -96 + * @Max: 0 + * @Default: -70 + * + * If the DUT is connected to an AP with weak signal, during latest + * rx_data_inactivity_time, if there is no activity or avg of data_rssi is + * better than roam_data_rssi_threshold(-70dbM), then suppress roaming + * triggered by roam_data_rssi_threshold_triggers: low RSSI or bg scan. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_ROAM_DATA_RSSI_THRESHOLD CFG_INI_INT( \ + "roam_data_rssi_threshold", \ + -96, \ + 0, \ + -70, \ + CFG_VALUE_OR_DEFAULT, \ + "DATA RSSI threshold for roam") + +/* + * + * rx_data_inactivity_time - Duration to check data rssi + * @Min: 0 + * @Max: 100000 ms + * @Default: 2000 + * + * If the DUT is connected to an AP with weak signal, during latest + * rx_data_inactivity_time, if there is no activity or avg of data_rssi is + * better than roam_data_rssi_threshold(-70dbM), then suppress roaming + * triggered by roam_data_rssi_threshold_triggers: low RSSI or bg scan. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_RX_DATA_INACTIVITY_TIME CFG_INI_UINT( \ + "rx_data_inactivity_time", \ + 0, \ + 100000, \ + 2000, \ + CFG_VALUE_OR_DEFAULT, \ + "Rx inactivity time to check data rssi") + /* * * roamscan_adaptive_dwell_mode - Sets dwell time adaptive mode @@ -1019,6 +1106,7 @@ "Maximum penalty that can be applied to 5GHz RSSI") /* + * * max_num_pre_auth - Configure max number of pre-auth * @Min: 0 * @Max: 256 @@ -1028,6 +1116,7 @@ * * Usage: Internal * + * */ #define CFG_LFR_MAX_NUM_PRE_AUTH CFG_UINT( \ "max_num_pre_auth", \ @@ -1038,6 +1127,7 @@ "") /* + * * roam_preauth_retry_count * * @Min: 1 @@ -1073,7 +1163,7 @@ * @Default: 5 * * Time to wait (in ms) after sending an preauth or reassoc - * request which didn’t have an ack, before considering + * request which didn't have an ack, before considering * it as a failure and making another software retry. * * Related: N/A @@ -2599,6 +2689,31 @@ 0, \ "Config roam scan policy") +/* + * + * enable_ft_im_roaming - FW needs to perform FT initial moiblity association + * instead of FT roaming for deauth roam trigger + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to FT roaming for deauth roam trigger behavior from HOST + * 0 - To disable FT-IM + * 1 - To enable FT-IM + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: Internal + * + * + */ +#define CFG_FT_IM_ROAMING CFG_INI_BOOL( \ + "enable_ft_im_roaming", \ + 1, \ + "FT roaming for deauth roam trigger") + /* * * roam_scan_inactivity_time - Device inactivity monitoring time in @@ -2696,6 +2811,36 @@ CFG_VALUE_OR_DEFAULT, \ "Roam scan period post inactivity") +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/* + * + * enable_roam_reason_vsie - Enable/Disable inclusion of Roam Reason + * in Re(association) frame + * + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable fw to include/exclude roam reason vsie in + * Re(association) + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: internal + * + * + */ +#define CFG_ENABLE_ROAM_REASON_VSIE CFG_INI_BOOL( \ + "enable_roam_reason_vsie", \ + 0, \ + "To Enable enable_roam_reason_vsie") +#define ROAM_REASON_VSIE_ALL CFG(CFG_ENABLE_ROAM_REASON_VSIE) +#else +#define ROAM_REASON_VSIE_ALL +#endif + #define CFG_LFR_ALL \ CFG(CFG_LFR_MAWC_ROAM_ENABLED) \ CFG(CFG_LFR_MAWC_ROAM_TRAFFIC_THRESHOLD) \ @@ -2715,6 +2860,9 @@ CFG(CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_THRESHOLD) \ CFG(CFG_LFR_ROAM_BG_SCAN_CLIENT_BITMAP) \ CFG(CFG_LFR_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G) \ + CFG(CFG_ROAM_DATA_RSSI_THRESHOLD_TRIGGERS) \ + CFG(CFG_ROAM_DATA_RSSI_THRESHOLD) \ + CFG(CFG_RX_DATA_INACTIVITY_TIME) \ CFG(CFG_LFR_ADAPTIVE_ROAMSCAN_DWELL_MODE) \ CFG(CFG_LFR_PER_ROAM_ENABLE) \ CFG(CFG_LFR_PER_ROAM_CONFIG_HIGH_RATE_TH) \ @@ -2775,6 +2923,7 @@ CFG(CFG_LFR_ROAM_FORCE_RSSI_TRIGGER) \ CFG(CFG_ROAM_SCAN_SCAN_POLICY) \ CFG(CFG_ROAM_SCAN_INACTIVITY_TIME) \ + CFG(CFG_FT_IM_ROAMING) \ CFG(CFG_ROAM_INACTIVE_COUNT) \ CFG(CFG_POST_INACTIVITY_ROAM_SCAN_PERIOD) \ CFG(CFG_BSS_LOAD_TRIG_5G_RSSI_THRES) \ @@ -2784,6 +2933,7 @@ ROAM_OFFLOAD_ALL \ LFR_ESE_ALL \ LFR_SUBNET_DETECTION_ALL \ - SAE_SINGLE_PMK_ALL + SAE_SINGLE_PMK_ALL \ + ROAM_REASON_VSIE_ALL #endif /* CFG_MLME_LFR_H__ */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h index 284b49fdb91e6a754645e71481b275327fcd91b3..cb7a5873ff6722bb6b57c8e98fd4074a9583441e 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_obss_ht40.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -243,6 +244,27 @@ 0, \ "Enable obss color collision offload") +/* + * + * bss_color_collision_det_sta - Enables BSS color collision detection in STA + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini used to enable or disable the BSS color collision detection in + * STA mode if obss_color_collision_offload is enabled. + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_BSS_CLR_COLLISION_DETCN_STA CFG_INI_BOOL( \ + "bss_color_collision_det_sta", \ + 1, \ + "BSS color collision detection in STA") + #define CFG_OBSS_HT40_ALL \ CFG(CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME) \ CFG(CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME) \ @@ -253,6 +275,7 @@ CFG(CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY) \ CFG(CFG_OBSS_HT40_OVERRIDE_HT40_20_24GHZ) \ CFG(CFG_OBSS_DETECTION_OFFLOAD) \ + CFG(CFG_BSS_CLR_COLLISION_DETCN_STA) \ CFG(CFG_OBSS_COLOR_COLLISION_OFFLOAD) #endif /* CFG_MLME_OBSS_HT40_H__ */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_power.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_power.h index eab93a1f6e40f48076b8acfcad98880d0282bcfb..81763ef8bc41d6ca8d4ea86559d6796fc2ec3a6c 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_power.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_power.h @@ -29,6 +29,9 @@ * @Min: 0 minimum length of tx power * @Max: default data length of tx power in string format * @Default: 1, 14, 20 + * + * This ini contains the string in the form of first_channel number, + * number of channels and max tx power triplets */ #define CFG_MAX_TX_POWER_2_4_DATA "1, 14, 20" #define CFG_MAX_TX_POWER_2_4 CFG_STRING( \ @@ -44,6 +47,9 @@ * @Min: 0 minimum length of tx power * @Max: default data length of tx power in string format * @Default: 36, 126, 20 + * + * This ini contains the string in the form of first_channel number, + * number of channels and max tx power triplets */ #define CFG_MAX_TX_POWER_5_DATA "36, 126, 20" #define CFG_MAX_TX_POWER_5 CFG_STRING( \ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_rates.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_rates.h index eb886a368d59648d966e53b5028db98c111406e2..d3786f9a7cd1b20f89ec5146588e135cd4d15678 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_rates.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_rates.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +31,7 @@ #define CFG_SUPPORTED_MCS_SET_LEN 16 #define CFG_BASIC_MCS_SET_LEN 16 #define CFG_CURRENT_MCS_SET_LEN 16 +#define CFG_MLME_RATE_MASK_LEN 4 /* * @@ -221,6 +223,78 @@ CFG_CURRENT_MCS_SET_DATA, \ "current MCS set") +/* + * + * ratemask_type - PHY type for the ratemask. + * @Min: 0 No rate mask set defined - disabled the configuration + * @Max: 4 + * @Default: 0 + * + * This ini is used to set the PHY type for ratemask in rate selection. + * + * 0 = Disables the configuration + * 1 = The rate mask specified is for CCK/OFDM configuration + * 2 = The rate mask specified is for HT configuration + * 3 = The rate mask specified is for VHT configuration + * 4 = The rate mask specified is for HE/11ax configuration + * + * Related: CFG_RATEMASK_SET + * + * Usage: External + */ +#define CFG_RATEMASK_TYPE CFG_INI_UINT( \ + "ratemask_type", \ + 0, \ + 4, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Ratemask type") + +/* + * + * ratemask_set - ratemasks for a PHY type used in rate selection + * @Min: default data length of ratemask in string format + * @Max: default data length of ratemask in string format + * @Default: 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF + * + * This is used to set the rate mask value to be used in rate selection. + * Each of the four words must be configured. + * A bit value of 1 represents rate is enabled + * A bit value of 0 represents rate is disabled + * + * [b31-b0],[b63-b32],[b95-b64],[b127-b96] + * For HE targets, 12 bits correpond to one NSS setting. Ex: + * b0-13 => NSS1, MCS 0-13 + * b14-27 => NSS2, MCS 0-13 and so on for other NSS. + * Note that the bit representation is continuous. + * + * For VHT targets, 12 bits correspond to one NSS setting. + * b0-11 => NSS1, MCS 0-11 + * b12-23 => NSS2, MCS 0-11 and so on for other NSS. + * + * For HT targets, 8 bits correspond to one NSS setting. + * b0-7 => NSS1, MCS 0-7 + * b8-15 => NSS2, MCS 0-7 and so on for other NSS. + * + * For OFDM/CCK targets, 8 bits correspond to one NSS setting. + * Bit position |-b3-|-b2-|-b1-|-b0-| + * Rates in Mbps |-1 -|-2 -|-5.5|-11-| CCK Rates + * + * Bit position |-b11-|-b10-|-b09-|-b08-|-b07-|-b06-|-b05-|-b04-| + * Rates in Mbps |- 9 -|- 18-|-36 -|-54 -|- 6 -|-12 -| -24-|-48- | OFDM Rates + * + * Related: CFG_RATEMASK_TYPE + * + * Usage: External + */ +#define CFG_RATEMASK_DATA "0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF" +#define CFG_RATEMASK_SET CFG_INI_STRING( \ + "ratemask_set", \ + 0, \ + sizeof(CFG_RATEMASK_DATA) - 1, \ + CFG_RATEMASK_DATA, \ + "Ratemasks for rate selection") + #define CFG_RATES_ALL \ CFG(CFG_MAX_HT_MCS_FOR_TX_DATA) \ CFG(CFG_DISABLE_ABG_RATE_FOR_TX_DATA) \ @@ -232,6 +306,8 @@ CFG(CFG_SUPPORTED_RATES_11A) \ CFG(CFG_SUPPORTED_MCS_SET) \ CFG(CFG_BASIC_MCS_SET) \ - CFG(CFG_CURRENT_MCS_SET) + CFG(CFG_CURRENT_MCS_SET) \ + CFG(CFG_RATEMASK_TYPE) \ + CFG(CFG_RATEMASK_SET) #endif /* __CFG_MLME_RATES_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_reg.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_reg.h index 7f435eda8df1f518448ccba0e5469baa205fe21c..4da66ab7aa7f4ab1c0ebb6ed4025bee2c19fc359 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_reg.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_reg.h @@ -73,14 +73,20 @@ /* * - * etsi13_srd_chan_in_master_mode - Enable/disable ETSI SRD channels in + * etsi_srd_chan_in_master_mode - Enable/disable ETSI SRD channels in * master mode PCL and ACS functionality * @Min: 0 - * @Max: 1 - * @Default: 0 + * @Max: 0xFF + * @Default: 6 * - * etsi13_srd_chan_in_master_mode is to enable/disable ETSI SRD channels in + * etsi_srd_chan_in_master_mode is to enable/disable ETSI SRD channels in * master mode PCL and ACS functionality + * Bit map for enabling the SRD mode in various modes are as follows:- + * BIT 0:- Enable/Disable SRD channels for SAP. + * BIT 1:- Enable/Disable SRD channels for P2P-GO. + * BIT 2:- Enable/Disable SRD channels for NAN. + * Rest of the bits are currently reserved for future SRD channel support for + * other vdevs. * * Related: None * @@ -90,11 +96,37 @@ * * */ -#define CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE CFG_INI_BOOL( \ +#define CFG_ETSI_SRD_CHAN_IN_MASTER_MODE CFG_INI_UINT( \ "etsi13_srd_chan_in_master_mode", \ 0, \ + 0xff, \ + 6, \ + CFG_VALUE_OR_DEFAULT, \ "enable/disable ETSI SRD channels in master mode") +/* + * + * enable_nan_indoor_channel - Enable Indoor channels for NAN + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to support to indoor channels for NAN interface + * Customer can config this item to enable/disable NAN in indoor channel + * + * Related: None + * + * Supported Feature: NAN + * + * Usage: External + * + * + */ +#define CFG_INDOOR_CHANNEL_SUPPORT_FOR_NAN CFG_INI_BOOL( \ + "enable_nan_indoor_channel", \ + 0, \ + "enable/disable indoor channels for NAN") + #ifdef SAP_AVOID_ACS_FREQ_LIST #define SAP_AVOID_ACS_FREQ_LIST_DEFAULT "" @@ -297,17 +329,42 @@ 0, \ "Enable Pending list req") +/* + * + * retain_nol_across_regdmn - Retain NOL across reg domain + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to set if NOL needs to be retained + * on the reg domain change. + * + * Related: None + * + * Supported Feature: SAP + * + * Usage: External + * + * + */ +#define CFG_RETAIN_NOL_ACROSS_REG_DOMAIN CFG_INI_BOOL( \ + "retain_nol_across_regdmn", \ + 1, \ + "Retain NOL even if the regdomain changes") + #define CFG_REG_ALL \ CFG(CFG_SELF_GEN_FRM_PWR) \ CFG(CFG_ENABLE_PENDING_CHAN_LIST_REQ) \ CFG(CFG_ENABLE_11D_IN_WORLD_MODE) \ - CFG(CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE) \ + CFG(CFG_ETSI_SRD_CHAN_IN_MASTER_MODE) \ + CFG(CFG_INDOOR_CHANNEL_SUPPORT_FOR_NAN) \ CFG(CFG_RESTART_BEACONING_ON_CH_AVOID) \ CFG(CFG_INDOOR_CHANNEL_SUPPORT) \ CFG(CFG_SCAN_11D_INTERVAL) \ CFG(CFG_VALID_CHANNEL_LIST) \ CFG(CFG_COUNTRY_CODE) \ CFG(CFG_IGNORE_FW_REG_OFFLOAD_IND) \ + CFG(CFG_RETAIN_NOL_ACROSS_REG_DOMAIN) \ CFG_SAP_AVOID_ACS_FREQ_LIST_ALL #endif /* CFG_MLME_REG_H__ */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sap.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sap.h index 51f590e5f7c18ad013f155bfaed0ae181c6c5cd3..4e0dc86e8e2388c9efc0407790f4f7d1cdad743f 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sap.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sap.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -229,7 +230,7 @@ * gSapGetPeerInfo - Enable/Disable remote peer info query support * @Min: 0 - Disable remote peer info query support * @Max: 1 - Enable remote peer info query support - * @Default: 0 + * @Default: 1 * * This ini is used to enable/disable remote peer info query support * @@ -239,7 +240,7 @@ */ #define CFG_SAP_GET_PEER_INFO CFG_INI_BOOL( \ "gSapGetPeerInfo", \ - 0, \ + 1, \ "sap get peer info") /* @@ -269,7 +270,7 @@ * gSoftApMaxPeers - Set Max peers connected for SAP * @Min: 1 * @Max: 32 - * @Default: 32 + * @Default: 10 * * This ini is used to set Max peers connected for SAP * @@ -285,7 +286,7 @@ "gSoftApMaxPeers", \ 1, \ 32, \ - 32, \ + 10, \ CFG_VALUE_OR_DEFAULT, \ "max no of peers") @@ -741,6 +742,29 @@ #define CFG_SAP_SAE #endif /* WLAN_FEATURE_SAE */ +/* + * + * + * enable_sap_fils_discovery - Enable/Disable fils discovery for 6Ghz SAP + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * Enable: 6Ghz SAP transmits fils discovery frame at every 20ms + * Disable: 6Ghz SAP transmits probe response frame at every 20ms + * + * Related: None + * + * Supported Feature: SAP + * Usage: External + * + * + */ +#define CFG_6G_SAP_FILS_DISCOVERY_ENABLED CFG_INI_BOOL( \ + "enable_6g_sap_fils_discovery", \ + 1, \ + "Enable/Disable fils discovery for SAP") + #define CFG_SAP_ALL \ CFG_SAP_SAE \ CFG(CFG_AP_ENABLE_RANDOM_BSSID) \ @@ -775,6 +799,7 @@ CFG(CFG_SAP_11AC_OVERRIDE) \ CFG(CFG_GO_FORCE_11N_FOR_11AC) \ CFG(CFG_GO_11AC_OVERRIDE) \ - CFG(CFG_IS_SAP_BCAST_DEAUTH_ENABLED) + CFG(CFG_IS_SAP_BCAST_DEAUTH_ENABLED) \ + CFG(CFG_6G_SAP_FILS_DISCOVERY_ENABLED) #endif /* __CFG_MLME_SAP_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_scoring.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_scoring.h index cbcb0e9c939ce91fc485b8b8c42722963c97a610..9744e1a2726f77836674232fa20c35ee81a0455a 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_scoring.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_scoring.h @@ -321,6 +321,36 @@ CFG_VALUE_OR_DEFAULT, \ "OCE WAN Weightage") +/* + * + * sae_pk_ap_weightage - update scoring param based on SAE PK ap weightage + * @Min: 0 + * @Max: 10 + * @Default: 3 + * + * This ini is used to calculate SAE PK ap weightage in roam score. SAE Public + * Key (SAE-PK) authentication is an extension of SAE that is intended for use + * cases where authentication is based on a password that might be + * distributed to or obtained by a potential adversary. With SAE-PK, the AP in + * an infrastructure network is additionally authenticated based on a static + * public/private key pair. This ini is also used for WFA certification. + * + * Related: None + * + * Supported Feature: STA + * + * Usage: External + * + * + */ +#define CFG_SAE_PK_AP_WEIGHTAGE CFG_INI_UINT( \ + "sae_pk_ap_weightage", \ + 0, \ + 10, \ + PLATFORM_VALUE(3, 0), \ + CFG_VALUE_OR_DEFAULT,\ + "SAE-PK AP weightage") + /* * * best_rssi_threshold - Best Rssi for score calculation @@ -1169,6 +1199,33 @@ CFG_VALUE_OR_DEFAULT, \ "Minimum RSSI of candidate AP for Bmiss roam trigger") +/* + * + * min_rssi_for_2g_to_5g_roam - Candidate AP minimum RSSI for + * 2G to 5G roam trigger (in dBm) + * @Min: -120 + * @Max: 0 + * @Default: -70 + * + * Minimum RSSI value of the candidate AP to consider it as candidate + * for 2G to 5G roam. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: Internal/External + * + * + */ +#define CFG_2G_TO_5G_ROAM_MIN_RSSI CFG_INI_INT( \ + "min_rssi_for_2g_to_5g_roam", \ + -120, \ + 0, \ + -70, \ + CFG_VALUE_OR_DEFAULT, \ + "Minimum RSSI of candidate AP for 2G to 5G roam trigger") + /* * * idle_roam_score_delta - Roam score delta value in percentage for idle roam. @@ -1267,6 +1324,7 @@ CFG(CFG_SCORING_PCL_WEIGHTAGE) \ CFG(CFG_SCORING_CHAN_CONGESTION_WEIGHTAGE) \ CFG(CFG_SCORING_OCE_WAN_WEIGHTAGE) \ + CFG(CFG_SAE_PK_AP_WEIGHTAGE) \ CFG(CFG_SCORING_BEST_RSSI_THRESHOLD) \ CFG(CFG_SCORING_GOOD_RSSI_THRESHOLD) \ CFG(CFG_SCORING_BAD_RSSI_THRESHOLD) \ @@ -1295,6 +1353,7 @@ CFG(CFG_APSD_ENABLED) \ CFG(CFG_DISCONNECT_ROAM_TRIGGER_MIN_RSSI) \ CFG(CFG_BMISS_ROAM_MIN_RSSI) \ + CFG(CFG_2G_TO_5G_ROAM_MIN_RSSI) \ CFG(CFG_IDLE_ROAM_SCORE_DELTA) \ CFG(CFG_BTM_ROAM_SCORE_DELTA) \ CFG(CFG_VENDOR_ROAM_SCORE_ALGORITHM) \ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sta.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sta.h index ed89fa7975df29f79652e7d2824e6dde999cbbd0..3d3e068a3d18f6de8663b2e42e8e0cd5fc92c2e8 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sta.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_sta.h @@ -125,7 +125,7 @@ * gStaPrefer80MHzOver160MHz - set sta preference to connect in 80HZ/160HZ * @Min: 0 * @Max: 1 - * @Default: 1 + * @Default: 0 * * This ini is used to set sta preference to connect in 80HZ/160HZ * @@ -142,7 +142,7 @@ */ #define CFG_STA_PREFER_80MHZ_OVER_160MHZ CFG_INI_BOOL( \ "gStaPrefer80MHzOver160MHz", \ - 1, \ + 0, \ "Sta preference to connect in 80HZ/160HZ") /* @@ -193,6 +193,31 @@ 0, \ "send deauth before connection") +/* + * + * deauth_retry_cnt- No. of deauth retries if the Tx is failed + * @Min: 0 + * @Max: 4 + * @Default: 2 + * + * This ini is used to set retry deauth if Tx is not success. + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_DEAUTH_RETRY_CNT CFG_INI_UINT( \ + "deauth_retry_cnt", \ + 0, \ + 4, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "Set Deauth retry count") + /* * * gDot11PMode - 802.11p mode @@ -289,30 +314,6 @@ CFG_VALUE_OR_DEFAULT, \ "Set maximum channel guard time") -/* - * - * force_rsne_override - force rsnie override from user - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to enable/disable test mode to force rsne override used in - * security enhancement test cases to pass the RSNIE sent by user in - * assoc request. - * - * Related: None - * - * Supported Feature: STA - * - * Usage: internal - * - * - */ -#define CFG_FORCE_RSNE_OVERRIDE CFG_INI_BOOL( \ - "force_rsne_override", \ - 0, \ - "Set obss active dwelltime") - /* * * SingleTIDRC - Set replay counter for all TID's @@ -465,11 +466,11 @@ CFG(CFG_PPS_ENABLE_5G_EBT) \ CFG(CFG_ENABLE_DEAUTH_BEFORE_CONNECTION) \ CFG(CFG_DOT11P_MODE) \ + CFG(CFG_DEAUTH_RETRY_CNT) \ CFG(CFG_ENABLE_GO_CTS2SELF_FOR_STA) \ CFG(CFG_QCN_IE_SUPPORT) \ CFG(CFG_STA_MCAST_MCC_REST_TIME) \ CFG(CFG_FILS_MAX_CHAN_GUARD_TIME) \ - CFG(CFG_FORCE_RSNE_OVERRIDE) \ CFG(CFG_SINGLE_TID_RC) \ CFG(CFG_STA_KEEPALIVE_METHOD) \ CFG(CFG_WT_CNF_TIMEOUT) \ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h index 3c20e6acaaf2e6d9f96a5fa71a084a5e799e54e8..cc4bb01740fcb8f984774dcdec58ba01ef62fb0c 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_vht_caps.h @@ -597,6 +597,26 @@ 0, \ "Enable subfee in vendor vht ie") +/* + * + * enable_vhtmcs_10_11_support - Enable/Disable vht mcs 10, 11 support + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable mcs 10, 11 support. + * + * Related: NA + * + * Usage: Internal + * + * + */ +#define CFG_ENABLE_VHT_MCS_10_11 CFG_INI_BOOL( \ + "enable_vhtmcs_10_11_support", \ + 1, \ + "Enable/Disable vht mcs 10, 11 support") + #define CFG_VHT_CAPS_ALL \ CFG(CFG_VHT_SUPP_CHAN_WIDTH) \ CFG(CFG_VHT_SU_BEAMFORMEE_CAP) \ @@ -630,6 +650,7 @@ CFG(CFG_ENABLE_SUBFEE_IN_VENDOR_VHTIE) \ CFG(CFG_TX_BF_CAP) \ CFG(CFG_AS_CAP) \ - CFG(CFG_DISABLE_LDPC_WITH_TXBF_AP) + CFG(CFG_DISABLE_LDPC_WITH_TXBF_AP) \ + CFG(CFG_ENABLE_VHT_MCS_10_11) #endif /* __CFG_MLME_VHT_CAPS_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h index c93ca73c9e959808200f88fc12094ad936279212..519d8e9f35f1e1816a64f71799a257ffab0df4da 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,7 +68,34 @@ CFG_VALUE_OR_DEFAULT, \ "fine timing measurement capability") +/* + * + * oem_6g_support_disable - oem 6g support is disabled + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to show OEM is 6Ghz disabled. For legacy OEM apps + * having no support for 6Ghz, the default value is 1 and thus driver will + * not serve 6Ghz info to legacy oem application. + * OEM apps supporting 6Ghz sets the ini value to 0 to get 6Ghz + * information from driver. + * + * Related: None + * + * Supported Feature: WIFI POS + * + * Usage: Internal/External + * + * + */ +#define CFG_OEM_SIXG_SUPPORT_DISABLE CFG_INI_BOOL( \ + "oem_6g_support_disable", \ + 1, \ + "oem 6Ghz support Enabled/disabled") + #define CFG_WIFI_POS_ALL \ - CFG(CFG_FINE_TIME_MEAS_CAPABILITY) + CFG(CFG_FINE_TIME_MEAS_CAPABILITY) \ + CFG(CFG_OEM_SIXG_SUPPORT_DISABLE) #endif /* __CFG_MLME_WIFI_POS_H */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_qos.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_qos.h index db28b214dd81564997651e569a95d484155aedb4..6d35ce2d96b74d871a118b17d581ffe252063c63 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_qos.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/cfg_qos.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -402,7 +402,7 @@ * gTxAggSwRetry - Configure Tx aggregation sw retry * @Min: 0 * @Max: 64 - * @Default: 0 + * @Default: 16 * * gTxAggSwRetry gives an option to configure Tx aggregation sw * retry. This can be useful in debugging throughput issues. @@ -419,7 +419,7 @@ "gTxAggSwRetry", \ 0, \ 64, \ - 0, \ + 16, \ CFG_VALUE_OR_DEFAULT, \ "Tx aggregation retry value") /* @@ -427,7 +427,7 @@ * gTxNonAggSwRetry - Configure Tx non aggregation sw retry * @Min: 0 * @Max: 64 - * @Default: 0 + * @Default: 16 * * gTxNonAggSwRetry gives an option to configure Tx non aggregation sw * retry. This can be useful in debugging throughput issues. @@ -444,7 +444,7 @@ "gTxNonAggSwRetry", \ 0, \ 64, \ - 0, \ + 16, \ CFG_VALUE_OR_DEFAULT, \ "Tx non aggregation retry value") /* diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_ext_mlme_obj_types.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_ext_mlme_obj_types.h new file mode 100644 index 0000000000000000000000000000000000000000..73e9e5424a5fabd7f9fc703e30b089bf5bd133e3 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_ext_mlme_obj_types.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ +/** + * DOC: wlan_ext_mlme_obj_types.h + * + * This header file is included by the converged control path mlme + * component to map legacy private structures to the external + * (ext)typedefs used by the converged code. This mechanism allows the + * legacy structs to be included as part of the global objmgr objects. + */ + +#ifndef __WLAN_EXT_MLME_OBJ_TYPE_H__ +#define __WLAN_EXT_MLME_OBJ_TYPE_H__ + +/** + * typedef mlme_pdev_ext_t - Opaque definition of pdev mlme pointer + * Define ext_pdev_ptr from external umac/mlme component point to this type + */ +struct opaque_mlme_pdev_ext; +typedef struct opaque_mlme_pdev_ext mlme_pdev_ext_t; + +/** + * typedef mlme_vdev_ext_t - Definition of vdev mlme pointer + * Define ext_vdev_ptr from external umac/mlme component point to this type + */ +typedef struct mlme_legacy_priv mlme_vdev_ext_t; + +/** + * typedef mlme_psoc_ext_t - Definition of psoc mlme pointer + * Define ext_psoc_ptr from external umac/mlme component point to this type + */ +typedef struct wlan_mlme_psoc_ext_obj mlme_psoc_ext_t; + +#endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_api.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_api.h index d58988a57c1cc6455dc3a322cd6a4a2cdf5acc76..6139aface233bd1391525ff5b481cf96a5e028c6 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -258,7 +257,7 @@ QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t *band_capability); + uint32_t *band_capability); /** * wlan_mlme_set_band_capability() - Set the Band capability config @@ -268,7 +267,7 @@ QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t band_capability); + uint32_t band_capability); /** * wlan_mlme_get_prevent_link_down() - Get the prevent link down config @@ -525,6 +524,16 @@ QDF_STATUS wlan_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, int value); +/** + * wlan_mlme_get_assoc_sta_limit() - Get the assoc sta limit + * @psoc: pointer to psoc object + * @value: Pointer to value that needs to be filled by MLME + * + * Return: QDF Status + */ +QDF_STATUS wlan_mlme_get_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, + int *value); + /** * wlan_mlme_set_rmc_action_period_freq() - Set the rmc action period frequency * @psoc: pointer to psoc object @@ -556,7 +565,7 @@ QDF_STATUS wlan_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, bool value); /** - * wlan_mlme_is_sap_bcast_deauth_enabled() - get the enable/disable value + * wlan_mlme_get_sap_bcast_deauth_enabled() - get the enable/disable value * for broadcast deauth in sap * @psoc: pointer to psoc object * @value: Value that needs to get from the caller @@ -564,8 +573,8 @@ QDF_STATUS wlan_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ QDF_STATUS -wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, - bool *value); +wlan_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, + bool *value); /** * wlan_mlme_get_sap_allow_all_channels() - get the value of sap allow all @@ -578,6 +587,18 @@ wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc, bool *value); +/** + * wlan_mlme_is_6g_sap_fd_enabled() - get the enable/disable value + * for 6g sap fils discovery + * @psoc: pointer to psoc object + * @value: Value that needs to get from the caller + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_is_6g_sap_fd_enabled(struct wlan_objmgr_psoc *psoc, + bool *value); + /** * wlan_mlme_get_sap_allow_all_channels() - get the value sap max peers * @psoc: pointer to psoc object @@ -1892,6 +1913,30 @@ QDF_STATUS wlan_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc, bool *value); +/** + * wlan_mlme_get_srd_master_mode_for_vdev - Get SRD master mode for vdev + * @psoc: pointer to psoc object + * @vdev_opmode: vdev operating mode + * @value: pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_srd_master_mode_for_vdev(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE vdev_opmode, + bool *value); + +/** + * wlan_mlme_get_indoor_support_for_nan - Get indoor channel support for NAN + * @psoc: pointer to psoc object + * @value: pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_indoor_support_for_nan(struct wlan_objmgr_psoc *psoc, + bool *value); + /** * wlan_mlme_get_vht_enable2x2() - Enables/disables VHT Tx/Rx MCS values for 2x2 * @psoc: psoc context @@ -2225,6 +2270,16 @@ QDF_STATUS wlan_mlme_get_self_gen_frm_pwr(struct wlan_objmgr_psoc *psoc, uint32_t *value); +/** + * wlan_mlme_get_4way_hs_offload() - get 4-way hs offload to fw cfg + * @psoc: pointer to psoc object + * @val: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value); + /** * wlan_mlme_get_bmiss_skip_full_scan_value() - To get value of * bmiss_skip_full_scan ini @@ -2271,39 +2326,6 @@ QDF_STATUS wlan_mlme_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc, bool *disabled); -/** - * wlan_mlme_get_mgmt_max_retry() - Get the - * max mgmt retry - * @psoc: pointer to psoc object - * @max_retry: output pointer to hold user config - * - * Return: QDF Status - */ -QDF_STATUS -wlan_mlme_get_mgmt_max_retry(struct wlan_objmgr_psoc *psoc, - uint8_t *max_retry); -/** - * wlan_mlme_get_status_ring_buffer() - Get the - * status of ring buffer - * @psoc: pointer to psoc object - * @enable_ring_buffer: output pointer to point the configured value of - * ring buffer - * - * Return: QDF_STATUS - */ -QDF_STATUS -wlan_mlme_get_status_ring_buffer(struct wlan_objmgr_psoc *psoc, - bool *enable_ring_buffer); - -/** - * wlan_mlme_get_peer_unmap_conf() - Indicate if peer unmap confirmation - * support is enabled or disabled - * @psoc: pointer to psoc object - * - * Return: true if peer unmap confirmation support is enabled, else false - */ -bool wlan_mlme_get_peer_unmap_conf(struct wlan_objmgr_psoc *psoc); - /** * mlme_get_roam_trigger_str() - Get the string for enum * WMI_ROAM_TRIGGER_REASON_ID reason. @@ -2410,16 +2432,123 @@ char *mlme_get_roam_fail_reason_str(uint32_t result); char *mlme_get_sub_reason_str(uint32_t sub_reason); /** - * wlan_mlme_get_4way_hs_offload() - get 4-way hs offload to fw cfg + * wlan_mlme_get_mgmt_max_retry() - Get the + * max mgmt retry * @psoc: pointer to psoc object - * @val: Pointer to the value which will be filled for the caller + * @max_retry: output pointer to hold user config * * Return: QDF Status */ QDF_STATUS -wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value); +wlan_mlme_get_mgmt_max_retry(struct wlan_objmgr_psoc *psoc, + uint8_t *max_retry); + +/** + * wlan_mlme_get_status_ring_buffer() - Get the + * status of ring buffer + * @psoc: pointer to psoc object + * @enable_ring_buffer: output pointer to point the configured value of + * ring buffer + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_mlme_get_status_ring_buffer(struct wlan_objmgr_psoc *psoc, + bool *enable_ring_buffer); + +/** + * wlan_mlme_get_peer_unmap_conf() - Indicate if peer unmap confirmation + * support is enabled or disabled + * @psoc: pointer to psoc object + * + * Return: true if peer unmap confirmation support is enabled, else false + */ +bool wlan_mlme_get_peer_unmap_conf(struct wlan_objmgr_psoc *psoc); + +#ifdef WLAN_FEATURE_SAE +/** + * wlan_mlme_get_sae_assoc_retry_count() - Get the sae assoc retry count + * @psoc: pointer to psoc object + * @retry_count: assoc retry count + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_sae_assoc_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count); +/** + * wlan_mlme_get_sae_assoc_retry_count() - Get the sae auth retry count + * @psoc: pointer to psoc object + * @retry_count: auth retry count + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_sae_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count); + +/** + * wlan_mlme_get_sae_roam_auth_retry_count() - Get the sae roam auth retry count + * @psoc: pointer to psoc object + * @retry_count: auth retry count + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_sae_roam_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count); + +#else +static inline QDF_STATUS +wlan_mlme_get_sae_assoc_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + *retry_count = 0; + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +wlan_mlme_get_sae_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + *retry_count = 0; + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +wlan_mlme_get_sae_roam_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + *retry_count = 0; + return QDF_STATUS_SUCCESS; +} +#endif #ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * wlan_mlme_get_roam_reason_vsie_status() - Indicate if roam reason + * vsie is enabled or disabled + * @psoc: pointer to psoc object + * @roam_reason_vsie_enabled: pointer to hold value of roam reason + * vsie + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_mlme_get_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t *roam_reason_vsie_enabled); + +/** + * wlan_mlme_set_roam_reason_vsie_status() - Update roam reason vsie status + * @psoc: pointer to psoc object + * @roam_reason_vsie_enabled: value of roam reason vsie + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_mlme_set_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t roam_reason_vsie_enabled); + /** * wlan_mlme_get_roaming_triggers - Get the roaming triggers bitmap * @psoc: Pointer to PSOC object @@ -2428,6 +2557,20 @@ wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value); */ uint32_t wlan_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc); #else +static inline QDF_STATUS +wlan_mlme_get_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t *roam_reason_vsie_enable) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline QDF_STATUS +wlan_mlme_set_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t roam_reason_vsie_enable) +{ + return QDF_STATUS_E_FAILURE; +} + static inline uint32_t wlan_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc) { @@ -2435,15 +2578,4 @@ uint32_t wlan_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc) } #endif -/** - * wlan_mlme_get_dfs_chan_ageout_time() - Get the DFS Channel ageout time - * @psoc: pointer to psoc object - * @dfs_chan_ageout_time: output pointer to hold configured value of DFS - * Channel ageout time - * - * Return: QDF Status - */ -QDF_STATUS -wlan_mlme_get_dfs_chan_ageout_time(struct wlan_objmgr_psoc *psoc, - uint8_t *dfs_chan_ageout_time); #endif /* _WLAN_MLME_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 2ba82029a19c6c6f0b010cc758b372d5a9967bc8..adfcd8b680823e919da8f063ae698bbacbeb8e2a 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,6 +29,9 @@ #include #include +#define OWE_TRANSITION_OUI_TYPE "\x50\x6f\x9a\x1c" +#define OWE_TRANSITION_OUI_SIZE 4 + #define CFG_PMKID_MODES_OKC (0x1) #define CFG_PMKID_MODES_PMKSA_CACHING (0x2) @@ -42,6 +45,13 @@ #define CFG_VHT_TX_MCS_MAP_STAMAX 0xFFFF #define CFG_VHT_TX_MCS_MAP_STADEF 0xFFFE +#define STA_DOT11_MODE_INDX 0 +#define P2P_DEV_DOT11_MODE_INDX 4 +#define NAN_DISC_DOT11_MODE_INDX 8 +#define OCB_DOT11_MODE_INDX 12 +#define TDLS_DOT11_MODE_INDX 16 +#define NDI_DOT11_MODE_INDX 20 + /* Roam debugging related macro defines */ #define MAX_ROAM_DEBUG_BUF_SIZE 250 #define MAX_ROAM_EVENTS_SUPPORTED 5 @@ -49,7 +59,7 @@ #define TIME_STRING_LEN 24 #define ROAM_CHANNEL_BUF_SIZE 300 -#define LINE_STR "=========================================" +#define LINE_STR "==============================================================" /* * MLME_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF + 1 is * assumed to be the default fw supported BF antennas, if fw @@ -63,7 +73,7 @@ #define CFG_STR_DATA_LEN 17 #define CFG_EDCA_DATA_LEN 17 #define CFG_MAX_TX_POWER_2_4_LEN 128 -#define CFG_MAX_TX_POWER_5_LEN 128 +#define CFG_MAX_TX_POWER_5_LEN 256 #define CFG_POWER_USAGE_MAX_LEN 4 #define CFG_MAX_STR_LEN 256 #define MAX_VENDOR_IES_LEN 1532 @@ -194,13 +204,29 @@ enum mlme_dot11_mode { MLME_DOT11_MODE_11AX_ONLY }; +/** + * enum mlme_vdev_dot11_mode - Dot11 mode of the vdev + * MLME_VDEV_DOT11_MODE_AUTO: vdev uses mlme_dot11_mode + * MLME_VDEV_DOT11_MODE_11N: vdev supports 11N mode + * MLME_VDEV_DOT11_MODE_11AC: vdev supports 11AC mode + * MLME_VDEV_DOT11_MODE_11AX: vdev supports 11AX mode + */ +enum mlme_vdev_dot11_mode { + MLME_VDEV_DOT11_MODE_AUTO, + MLME_VDEV_DOT11_MODE_11N, + MLME_VDEV_DOT11_MODE_11AC, + MLME_VDEV_DOT11_MODE_11AX, +}; + /** * struct wlan_mlme_dot11_mode - dot11 mode * * @dot11_mode: dot11 mode supported + * @vdev_type_dot11_mode: dot11 mode supported by different vdev types */ struct wlan_mlme_dot11_mode { enum mlme_dot11_mode dot11_mode; + uint32_t vdev_type_dot11_mode; }; /** @@ -387,9 +413,6 @@ struct wlan_mlme_edca_params { #define MLME_NUM_WLM_LATENCY_LEVEL 4 #define MLME_RMENABLEDCAP_MAX_LEN 5 -#define LFR3_STA_ROAM_DISABLE_BY_P2P BIT(0) -#define LFR3_STA_ROAM_DISABLE_BY_NAN BIT(1) - /** * struct mlme_ht_capabilities_info - HT Capabilities Info * @l_sig_tx_op_protection: L-SIG TXOP Protection Mechanism support @@ -669,6 +692,7 @@ struct wlan_mlme_wps_params { * @go_11ac_override: Override GO bandwidth to 11ac * @sap_sae_enabled: enable sae in sap mode * @is_sap_bcast_deauth_enabled: enable bcast deauth for sap + * @is_6g_sap_fd_enabled: enable fils discovery on sap */ struct wlan_mlme_cfg_sap { uint8_t cfg_ssid[WLAN_SSID_MAX_LEN]; @@ -706,6 +730,7 @@ struct wlan_mlme_cfg_sap { bool go_11ac_override; bool sap_sae_enabled; bool is_sap_bcast_deauth_enabled; + bool is_6g_sap_fd_enabled; }; /** @@ -718,6 +743,7 @@ struct wlan_mlme_cfg_sap { * @dfs_prefer_non_dfs: perefer non dfs channel after radar * @dfs_disable_japan_w53: Disable W53 channels * @sap_tx_leakage_threshold: sap tx leakage threshold + * @dfs_pri_multiplier: dfs_pri_multiplier for handle missing pulses */ struct wlan_mlme_dfs_cfg { bool dfs_master_capable; @@ -728,6 +754,7 @@ struct wlan_mlme_dfs_cfg { bool dfs_prefer_non_dfs; bool dfs_disable_japan_w53; uint32_t sap_tx_leakage_threshold; + uint32_t dfs_pri_multiplier; }; /** @@ -855,6 +882,10 @@ struct mlme_vht_capabilities_info { uint8_t as_cap; bool disable_ldpc_with_txbf_ap; bool vht_mcs_10_11_supp; + uint8_t extended_nss_bw_supp; + uint8_t vht_extended_nss_bw_cap; + uint8_t max_nsts_total; + bool restricted_80p80_bw_supp; }; /** @@ -1093,6 +1124,42 @@ struct wlan_mlme_chainmask { bool enable_bt_chain_separation; }; +/** + * enum wlan_mlme_ratemask_type: Type of PHY for ratemask + * @WLAN_MLME_RATEMASK_TYPE_NO_MASK: no ratemask set + * @WLAN_MLME_RATEMASK_TYPE_CCK: CCK/OFDM rate + * @WLAN_MLEM_RATEMASK_TYPE_HT: HT rate + * @WLAN_MLME_RATEMASK_TYPE_VHT: VHT rate + * @WLAN_MLME_RATEMASK_TYPE_HE: HE rate + * + * This is used for 'type' values in wlan_mlme_ratemask + */ +enum wlan_mlme_ratemask_type { + WLAN_MLME_RATEMASK_TYPE_NO_MASK = 0, + WLAN_MLME_RATEMASK_TYPE_CCK = 1, + WLAN_MLME_RATEMASK_TYPE_HT = 2, + WLAN_MLME_RATEMASK_TYPE_VHT = 3, + WLAN_MLME_RATEMASK_TYPE_HE = 4, + /* keep this last */ + WLAN_MLME_RATEMASK_TYPE_MAX, +}; + +/** + * struct wlan_mlme_ratemask - ratemask config parameters + * @type: Type of PHY the mask to be applied + * @lower32: Lower 32 bits in the 1st 64-bit value + * @higher32: Higher 32 bits in the 1st 64-bit value + * @lower32_2: Lower 32 bits in the 2nd 64-bit value + * @higher32_2: Higher 32 bits in the 2nd 64-bit value + */ +struct wlan_mlme_ratemask { + enum wlan_mlme_ratemask_type type; + uint32_t lower32; + uint32_t higher32; + uint32_t lower32_2; + uint32_t higher32_2; +}; + /* struct wlan_mlme_generic - Generic CFG config items * * @band_capability: HW Band Capability - Both or 2.4G only or 5G only @@ -1123,20 +1190,20 @@ struct wlan_mlme_chainmask { * @data_stall_recovery_fw_support: whether FW supports Data stall recovery. * @enable_change_channel_bandwidth: enable/disable change channel bw in mission * mode + * @disable_4way_hs_offload: enable/disable 4 way handshake offload to firmware * @as_enabled: antenna sharing enabled or not (FW capability) * @mgmt_retry_max: maximum retries for management frame * @bmiss_skip_full_scan: Decide if full scan can be skipped in firmware if no * candidate is found in partial scan based on channel map * @enable_ring_buffer: Decide to enable/disable ring buffer for bug report * @enable_peer_unmap_conf_support: Indicate whether to send conf for peer unmap - * @disable_4way_hs_offload: enable/disable 4 way handshake offload to firmware - * @dfs_chan_ageout_time: Set DFS Channel ageout time * @stop_all_host_scan_support: Target capability that indicates if the target * supports stop all host scan request type. + * @sae_connect_retries: sae connect retry bitmask */ struct wlan_mlme_generic { - enum band_info band_capability; - enum band_info band; + uint32_t band_capability; + uint32_t band; uint8_t select_5ghz_margin; uint8_t sub_20_chan_width; uint8_t ito_repeat_count; @@ -1162,15 +1229,14 @@ struct wlan_mlme_generic { bool enable_beacon_reception_stats; bool enable_remove_time_stamp_sync_cmd; bool data_stall_recovery_fw_support; - bool enable_change_channel_bandwidth; + bool disable_4way_hs_offload; bool as_enabled; uint8_t mgmt_retry_max; bool bmiss_skip_full_scan; bool enable_ring_buffer; bool enable_peer_unmap_conf_support; - bool disable_4way_hs_offload; - uint8_t dfs_chan_ageout_time; bool stop_all_host_scan_support; + uint32_t sae_connect_retries; }; /* @@ -1189,6 +1255,29 @@ struct wlan_mlme_product_details_cfg { char manufacture_product_version[WLAN_CFG_MFR_PRODUCT_VERSION_LEN + 1]; }; +/* + * struct acs_weight - Normalize ACS weight for mentioned channels + * @chan_freq: frequency of the channel + * @normalize_weight: Normalization factor of the frequency + */ +struct acs_weight { + uint32_t chan_freq; + uint8_t normalize_weight; +}; + +/* + * struct acs_weight_range - Normalize ACS weight for mentioned channel range + * @start_freq: frequency of the start channel + * @end_freq: frequency of the end channel + * @normalize_weight: Normalization factor for freq range + */ +struct acs_weight_range { + uint32_t start_freq; + uint32_t end_freq; + uint8_t normalize_weight; +}; + +#define MAX_ACS_WEIGHT_RANGE 10 #define MLME_GET_DFS_CHAN_WEIGHT(np_chan_weight) (np_chan_weight & 0x000000FF) /* @@ -1197,18 +1286,26 @@ struct wlan_mlme_product_details_cfg { * @auto_channel_select_weight - to set acs channel weight * @is_vendor_acs_support - enable application based channel selection * @is_acs_support_for_dfs_ltecoex - enable channel for dfs and lte coex - * @np_chan_weightage: Weightage to be given to non preferred channels. * @is_external_acs_policy - control external policy + * @normalize_weight_chan: Weight factor to be considered in ACS + * @normalize_weight_num_chan: Number of freq items for normalization. + * @normalize_weight_range: Frequency range for weight normalization + * @num_weight_range: num of ranges provided by user * @force_sap_start: Force SAP start when no channel is found suitable + * @np_chan_weightage: Weightage to be given to non preferred channels. */ struct wlan_mlme_acs { bool is_acs_with_more_param; uint32_t auto_channel_select_weight; bool is_vendor_acs_support; bool is_acs_support_for_dfs_ltecoex; - uint32_t np_chan_weightage; bool is_external_acs_policy; + struct acs_weight normalize_weight_chan[NUM_CHANNELS]; + uint16_t normalize_weight_num_chan; + struct acs_weight_range normalize_weight_range[MAX_ACS_WEIGHT_RANGE]; + uint16_t num_weight_range; bool force_sap_start; + uint32_t np_chan_weightage; }; /* @@ -1239,6 +1336,7 @@ struct wlan_mlme_cfg_twt { * @is_override_ht20_40_24g: use channel bonding in 2.4 GHz * @obss_detection_offload_enabled: Enable OBSS detection offload * @obss_color_collision_offload_enabled: Enable obss color collision + * @bss_color_collision_det_sta: STA BSS color collision detection offload */ struct wlan_mlme_obss_ht40 { uint32_t active_dwelltime; @@ -1251,6 +1349,7 @@ struct wlan_mlme_obss_ht40 { bool is_override_ht20_40_24g; bool obss_detection_offload_enabled; bool obss_color_collision_offload_enabled; + bool bss_color_collision_det_sta; }; /** @@ -1315,6 +1414,7 @@ enum station_keepalive_method { * @dot11p_mode: Set 802.11p mode * @fils_max_chan_guard_time: Set maximum channel guard time * @current_rssi: Current rssi + * @deauth_retry_cnt: Deauth retry count * @ignore_peer_erp_info: Ignore peer infrormation * @sta_prefer_80mhz_over_160mhz: Set Sta preference to connect in 80HZ/160HZ * @enable_5g_ebt: Set default 5G early beacon termination @@ -1334,13 +1434,13 @@ struct wlan_mlme_sta_cfg { enum dot11p_mode dot11p_mode; uint8_t fils_max_chan_guard_time; uint8_t current_rssi; + uint8_t deauth_retry_cnt; bool ignore_peer_erp_info; bool sta_prefer_80mhz_over_160mhz; bool enable_5g_ebt; bool deauth_before_connection; bool enable_go_cts2self_for_sta; bool qcn_ie_support; - bool force_rsne_override; bool single_tid; bool allow_tpc_from_ap; enum station_keepalive_method sta_keepalive_method; @@ -1403,7 +1503,9 @@ struct bss_load_trigger { #define AKM_FT_FILS 2 #define AKM_SAE 3 #define AKM_OWE 4 -#define AKM_SUITEB 5 + +#define LFR3_STA_ROAM_DISABLE_BY_P2P BIT(0) +#define LFR3_STA_ROAM_DISABLE_BY_NAN BIT(1) /* * @mawc_roam_enabled: Enable/Disable MAWC during roaming @@ -1420,6 +1522,8 @@ struct bss_load_trigger { * below which the connection is idle. * @idle_roam_min_rssi: Minimum rssi of connected AP to be considered for * idle roam trigger. + * @enable_roam_reason_vsie: Enable/disable incluison of roam reason + * vsie in Re(assoc) frame * @roam_trigger_bitmap: Bitmap of roaming triggers. * @sta_roam_disable STA roaming disabled by interfaces * @early_stop_scan_enable: Set early stop scan @@ -1444,6 +1548,10 @@ struct bss_load_trigger { * @roam_bg_scan_bad_rssi_threshold:RSSI threshold for background roam * @roam_bg_scan_client_bitmap: Bitmap used to identify the scan clients * @roam_bg_scan_bad_rssi_offset_2g:RSSI threshold offset for 2G to 5G roam + * @roam_data_rssi_threshold_triggers: triggers of bad data RSSI threshold to + * roam + * @roam_data_rssi_threshold: Bad data RSSI threshold to roam + * @rx_data_inactivity_time: Rx duration to check data RSSI * @adaptive_roamscan_dwell_mode: Sets dwell time adaptive mode * @per_roam_enable: To enabled/disable PER based roaming in FW * @per_roam_config_high_rate_th: Rate at which PER based roam will stop @@ -1488,6 +1596,7 @@ struct bss_load_trigger { * @enable_adaptive_11r Flag to check if adaptive 11r ini is enabled * @tgt_adaptive_11r_cap: Flag to check if target supports adaptive * 11r + * @enable_ft_im_roaming: Flag to enable/disable FT-IM * @roam_scan_home_away_time: The home away time to firmware * @roam_scan_n_probes: The number of probes to be sent for firmware roaming * @delay_before_vdev_stop:Wait time for tx complete before vdev stop @@ -1525,6 +1634,7 @@ struct wlan_mlme_lfr_cfg { uint32_t idle_data_packet_count; uint32_t idle_roam_band; int32_t idle_roam_min_rssi; + bool enable_roam_reason_vsie; uint32_t roam_trigger_bitmap; uint32_t sta_roam_disable; #endif @@ -1552,6 +1662,9 @@ struct wlan_mlme_lfr_cfg { uint32_t roam_bg_scan_bad_rssi_threshold; uint32_t roam_bg_scan_client_bitmap; uint32_t roam_bg_scan_bad_rssi_offset_2g; + uint32_t roam_data_rssi_threshold_triggers; + int32_t roam_data_rssi_threshold; + uint32_t rx_data_inactivity_time; uint32_t adaptive_roamscan_dwell_mode; uint32_t per_roam_enable; uint32_t per_roam_config_high_rate_th; @@ -1597,6 +1710,7 @@ struct wlan_mlme_lfr_cfg { bool enable_adaptive_11r; bool tgt_adaptive_11r_cap; #endif + bool enable_ft_im_roaming; uint16_t roam_scan_home_away_time; uint32_t roam_scan_n_probes; uint8_t delay_before_vdev_stop; @@ -1784,6 +1898,7 @@ struct wlan_mlme_wmm_params { * @pcl_weightage: PCL weightage * @channel_congestion_weightage: channel congestion weightage * @oce_wan_weightage: OCE WAN metrics weightage + * @sae_pk_ap_weightage: SAE-PK AP weigtage */ struct wlan_mlme_weight_config { uint8_t rssi_weightage; @@ -1797,6 +1912,7 @@ struct wlan_mlme_weight_config { uint8_t pcl_weightage; uint8_t channel_congestion_weightage; uint8_t oce_wan_weightage; + uint8_t sae_pk_ap_weightage; }; /** @@ -1936,8 +2052,18 @@ struct mlme_power_usage { /* * struct wlan_mlme_power - power related config items - * @max_tx_power_24: max power Tx for 2.4 ghz - * @max_tx_power_5: max power Tx for 5 ghz + * @max_tx_power_24: max power Tx for 2.4 ghz, this is based on frequencies + * @max_tx_power_5: max power Tx for 5 ghz, this is based on frequencies + * @max_tx_power_24_chan: max power Tx for 2.4 ghz, this is based on channel + * numbers, this is added to parse the ini values to maintain the backward + * compatibility, these channel numbers are converted to frequencies and copied + * to max_tx_power_24 structure, once this conversion is done this structure + * should not be used. + * @max_tx_power_5_chan: max power Tx for 5 ghz, this is based on channel + * numbers, this is added to parse the ini values to maintain the backward + * compatibility, these channel numbers are converted to frequencies and copied + * to max_tx_power_24 structure, once this conversion is done this structure + * should not be used. * @power_usage: power usage mode, min, max, mod * @tx_power_2g: limit tx power in 2.4 ghz * @tx_power_5g: limit tx power in 5 ghz @@ -1948,6 +2074,8 @@ struct mlme_power_usage { struct wlan_mlme_power { struct mlme_max_tx_power_24 max_tx_power_24; struct mlme_max_tx_power_5 max_tx_power_5; + struct mlme_max_tx_power_24 max_tx_power_24_chan; + struct mlme_max_tx_power_5 max_tx_power_5_chan; struct mlme_power_usage power_usage; uint8_t tx_power_2g; uint8_t tx_power_5g; @@ -2046,9 +2174,11 @@ struct wlan_mlme_wep_cfg { /** * struct wlan_mlme_wifi_pos_cfg - WIFI POS configs * @fine_time_meas_cap: fine timing measurement capability information + * @oem_6g_support_disable: oem is 6Ghz disabled if set */ struct wlan_mlme_wifi_pos_cfg { uint32_t fine_time_meas_cap; + bool oem_6g_support_disable; }; #define MLME_SET_BIT(value, bit_offset) ((value) |= (1 << (bit_offset))) @@ -2097,18 +2227,21 @@ struct wlan_mlme_btm { */ struct wlan_mlme_fe_wlm { bool latency_enable; + bool latency_reset; uint8_t latency_level; uint32_t latency_flags[MLME_NUM_WLM_LATENCY_LEVEL]; }; /** * struct wlan_mlme_fe_rrm - RRM related configs - * @rrm_enabled: Flag to check if RRM is enabled + * @rrm_enabled: Flag to check if RRM is enabled for STA + * @sap_rrm_enabled: Flag to check if RRM is enabled for SAP * @rrm_rand_interval: RRM randomization interval * @rm_capability: RM enabled capabilities IE */ struct wlan_mlme_fe_rrm { bool rrm_enabled; + bool sap_rrm_enabled; uint8_t rrm_rand_interval; uint8_t rm_capability[MLME_RMENABLEDCAP_MAX_LEN]; }; @@ -2132,15 +2265,27 @@ struct wlan_mlme_mwc { }; #endif +/** + * enum mlme_reg_srd_master_modes - Bitmap of SRD master modes supported + * @MLME_SRD_MASTER_MODE_SAP: SRD master mode for SAP + * @MLME_SRD_MASTER_MODE_P2P_GO: SRD master mode for P2P-GO + * @MLME_SRD_MASTER_MODE_NAN: SRD master mode for NAN + */ +enum mlme_reg_srd_master_modes { + MLME_SRD_MASTER_MODE_SAP = 1, + MLME_SRD_MASTER_MODE_P2P_GO = 2, + MLME_SRD_MASTER_MODE_NAN = 4, +}; + /** * struct wlan_mlme_reg - REG related configs * @self_gen_frm_pwr: self-generated frame power in tx chain mask * for CCK rates - * @etsi13_srd_chan_in_master_mode: etsi13 srd chan in master mode + * @etsi_srd_chan_in_master_mode: etsi srd chan in master mode * @restart_beaconing_on_ch_avoid: restart beaconing on ch avoid * @indoor_channel_support: indoor channel support * @scan_11d_interval: scan 11d interval - * @valid_channel_list: array for valid channel list + * @valid_channel_freq_list: array for valid channel list * @valid_channel_list_num: valid channel list number * @country_code: country code * @country_code_len: country code length @@ -2151,16 +2296,18 @@ struct wlan_mlme_mwc { * @ignore_fw_reg_offload_ind: Ignore fw regulatory offload indication * @enable_pending_chan_list_req: enables/disables scan channel * list command to FW till the current scan is complete. + * @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain. + * @enable_nan_on_indoor_channels: Enable nan on Indoor channels */ struct wlan_mlme_reg { uint32_t self_gen_frm_pwr; - bool etsi13_srd_chan_in_master_mode; + uint8_t etsi_srd_chan_in_master_mode; enum restart_beaconing_on_ch_avoid_rule restart_beaconing_on_ch_avoid; bool indoor_channel_support; uint32_t scan_11d_interval; - uint8_t valid_channel_list[CFG_VALID_CHANNEL_LIST_LEN]; - uint8_t valid_channel_list_num; + uint32_t valid_channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; + uint32_t valid_channel_list_num; uint8_t country_code[CFG_COUNTRY_CODE_LEN + 1]; uint8_t country_code_len; bool enable_11d_in_world_mode; @@ -2170,6 +2317,8 @@ struct wlan_mlme_reg { #endif bool ignore_fw_reg_offload_ind; bool enable_pending_chan_list_req; + bool retain_nol_across_regdmn_update; + bool enable_nan_on_indoor_channels; }; /** @@ -2290,7 +2439,13 @@ struct wlan_mlme_cfg { struct wlan_mlme_dot11_mode dot11_mode; struct wlan_mlme_reg reg; struct roam_trigger_score_delta trig_score_delta[NUM_OF_ROAM_TRIGGERS]; - struct roam_trigger_min_rssi trig_min_rssi[NUM_OF_ROAM_TRIGGERS]; + struct roam_trigger_min_rssi trig_min_rssi[NUM_OF_ROAM_MIN_RSSI]; + struct wlan_mlme_ratemask ratemask_cfg; +}; + +enum pkt_origin { + FW, + HOST }; /** @@ -2328,4 +2483,13 @@ struct mlme_roam_debug_info { struct wmi_neighbor_report_data data_11kv; }; +/** + * struct wlan_ies - Generic WLAN Information Element(s) format + * @len: Total length of the IEs + * @data: IE data + */ +struct wlan_ies { + uint16_t len; + uint8_t *data; +}; #endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 75398400850b7c967b95ea6d7c07db9418ae7f38..b91b7ea8b5cef82daed50377b26a87f3b980634d 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -101,6 +102,17 @@ QDF_STATUS ucfg_mlme_global_init(void); */ QDF_STATUS ucfg_mlme_global_deinit(void); +/** + * ucfg_mlme_cfg_chan_to_freq() - convert channel numbers to frequencies + * @pdev: pointer to pdev object + * + * convert the channels numbers received as part of cfg items to + * frequencies. + * + * Return: None + */ +void ucfg_mlme_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev); + /** * wlan_mlme_get_power_usage() - Get the power usage info * @psoc: pointer to psoc object @@ -225,7 +237,7 @@ QDF_STATUS ucfg_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, */ static inline QDF_STATUS ucfg_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t *band_capability) + uint32_t *band_capability) { return wlan_mlme_get_band_capability(psoc, band_capability); } @@ -239,7 +251,7 @@ QDF_STATUS ucfg_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, */ static inline QDF_STATUS ucfg_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t band_capability) + uint32_t band_capability) { return wlan_mlme_set_band_capability(psoc, band_capability); } @@ -751,6 +763,28 @@ QDF_STATUS ucfg_mlme_set_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, uint32_t sap_tx_leakage_threshold); +/* + * ucfg_mlme_get_dfs_pri_multiplier() - Get dfs pri multiplier + * @psoc: pointer to psoc object + * @dfs_pri_multiplier: Pointer to the value which will be filled + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_dfs_pri_multiplier(struct wlan_objmgr_psoc *psoc, + uint32_t *dfs_pri_multiplier); + +/* + * ucfg_mlme_set_dfs_pri_multiplier() - Set dfs pri multiplier + * @psoc: pointer to psoc object + * @dfs_pri_multiplier: Value that needs to be set. + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_dfs_pri_multiplier(struct wlan_objmgr_psoc *psoc, + uint32_t dfs_pri_multiplier); + /* * ucfg_mlme_get_dfs_filter_offload() - Get the dfs filter offload * @psoc: pointer to psoc object @@ -773,6 +807,17 @@ QDF_STATUS ucfg_mlme_set_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, bool dfs_filter_offload); +/** + * ucfg_mlme_get_oem_6g_supported() - Get oem 6Ghz supported + * @psoc: pointer to psoc object + * @oem_6g_supported: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_oem_6g_supported(struct wlan_objmgr_psoc *psoc, + bool *oem_6g_supported); + /** * ucfg_mlme_get_fine_time_meas_cap() - Get fine timing measurement capability * @psoc: pointer to psoc object @@ -949,17 +994,6 @@ QDF_STATUS ucfg_mlme_get_go_cts2self_for_sta(struct wlan_objmgr_psoc *psoc, bool *val); -/** - * ucfg_mlme_get_force_rsne_override() - Force rsnie override from user - * @psoc: pointer to psoc object - * @val: Pointer to the value which will be filled for the caller - * - * Return: QDF Status - */ -QDF_STATUS -ucfg_mlme_get_force_rsne_override(struct wlan_objmgr_psoc *psoc, - bool *val); - /** * ucfg_mlme_get_qcn_ie_support() - QCN IE support or not * @psoc: pointer to psoc object @@ -994,25 +1028,26 @@ ucfg_mlme_is_override_ht20_40_24g(struct wlan_objmgr_psoc *psoc, bool *val); #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** - * ucfg_mlme_get_roaming_offload() - Get roaming offload setting + * ucfg_mlme_get_roam_disable_config() - Get sta roam disable value * @psoc: pointer to psoc object - * @val: Pointer to enable/disable roaming offload + * @val: Pointer to bitmap of interfaces for those sta roaming is disabled * * Return: QDF Status */ QDF_STATUS -ucfg_mlme_get_roaming_offload(struct wlan_objmgr_psoc *psoc, - bool *val); +ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, + uint32_t *val); /** - * ucfg_mlme_get_roam_disable_config() - Get sta roam disable value + * ucfg_mlme_get_roaming_offload() - Get roaming offload setting * @psoc: pointer to psoc object - * @val: Pointer to bitmap of interfaces for those sta roaming is disabled + * @val: Pointer to enable/disable roaming offload * * Return: QDF Status */ -QDF_STATUS ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, - uint32_t *val); +QDF_STATUS +ucfg_mlme_get_roaming_offload(struct wlan_objmgr_psoc *psoc, + bool *val); /** * ucfg_mlme_set_roaming_offload() - Enable/disable roaming offload @@ -1038,9 +1073,9 @@ ucfg_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc) return wlan_mlme_get_roaming_triggers(psoc); } #else -static inline -QDF_STATUS ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, - uint32_t *val) +static inline QDF_STATUS +ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, + uint32_t *val) { return QDF_STATUS_E_FAILURE; } @@ -1359,6 +1394,22 @@ QDF_STATUS ucfg_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, return wlan_mlme_set_assoc_sta_limit(psoc, value); } +/** + * ucfg_mlme_get_assoc_sta_limit() - Get the assoc sta limit + * @psoc: pointer to psoc object + * @value: Pointer to variable that needs to be filled by MLME + * + * Inline UCFG API to be used by HDD/OSIF callers + * + * Return: QDF Status + */ +static inline +QDF_STATUS ucfg_mlme_get_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, + int *value) +{ + return wlan_mlme_get_assoc_sta_limit(psoc, value); +} + /** * ucfg_mlme_set_rmc_action_period_freq() - Set the rmc action period frequency * @psoc: pointer to psoc object @@ -1425,7 +1476,7 @@ QDF_STATUS ucfg_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, } /** - * ucfg_mlme_is_sap_bcast_deauth_enabled() - get the sap bcast deauth + * ucfg_mlme_get_sap_bcast_deauth_enabled() - get the sap bcast deauth * enabled value * @psoc: pointer to psoc object * @value: Value that needs to be get from the caller @@ -1435,10 +1486,27 @@ QDF_STATUS ucfg_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ static inline QDF_STATUS -ucfg_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, - bool *value) +ucfg_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, + bool *value) { - return wlan_mlme_is_sap_bcast_deauth_enabled(psoc, value); + return wlan_mlme_get_sap_bcast_deauth_enabled(psoc, value); +} + +/** + * ucfg_mlme_is_6g_sap_fd_enabled() - get the sap fils discovery + * enabled value + * @psoc: pointer to psoc object + * @value: Value that needs to be get from the caller + * + * Inline UCFG API to be used by HDD/OSIF callers + * + * Return: QDF Status + */ +static inline QDF_STATUS +ucfg_mlme_is_6g_sap_fd_enabled(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + return wlan_mlme_is_6g_sap_fd_enabled(psoc, value); } /** @@ -3154,6 +3222,34 @@ ucfg_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value) return wlan_mlme_get_wmm_mode(psoc, value); } +/** + * ucfg_mlme_cfg_get_wlm_level() - Get the WLM level value + * @psoc: pointer to psoc object + * @level: level that needs to be filled. + * + * Return: QDF Status + */ +static inline +QDF_STATUS ucfg_mlme_cfg_get_wlm_level(struct wlan_objmgr_psoc *psoc, + uint8_t *level) +{ + return mlme_get_cfg_wlm_level(psoc, level); +} + +/** + * ucfg_mlme_cfg_get_wlm_reset() - Get the WLM reset flag + * @psoc: pointer to psoc object + * @reset: reset that needs to be filled. + * + * Return: QDF Status + */ +static inline +QDF_STATUS ucfg_mlme_cfg_get_wlm_reset(struct wlan_objmgr_psoc *psoc, + bool *reset) +{ + return mlme_get_cfg_wlm_reset(psoc, reset); +} + #ifdef WLAN_FEATURE_11AX /** * ucfg_mlme_update_tgt_he_cap() - Update tgt he cap in mlme component @@ -3699,7 +3795,7 @@ ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(struct wlan_objmgr_psoc *psoc, #endif /** - * ucfg_mlme_get_etsi13_srd_chan_in_master_mode - get etsi13 srd chan + * ucfg_mlme_get_etsi_srd_chan_in_master_mode - get etsi srd chan * in master mode * @psoc: pointer to psoc object * @value: pointer to the value which will be filled for the caller @@ -3707,8 +3803,21 @@ ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ QDF_STATUS -ucfg_mlme_get_etsi13_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, - bool *value); +ucfg_mlme_get_etsi_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, + uint8_t *value); + +/** + * ucfg_mlme_get_srd_master_mode_for_vdev() - Get SRD master mode for vdev + * @psoc: pointer to psoc object + * @vdev_opmode: vdev opmode + * @value: pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_srd_master_mode_for_vdev(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE vdev_opmode, + bool *value); #ifdef SAP_AVOID_ACS_FREQ_LIST /** @@ -3780,7 +3889,19 @@ ucfg_mlme_get_scan_11d_interval(struct wlan_objmgr_psoc *psoc, uint32_t *value); /** - * ucfg_mlme_get_valid_channel_list() - get valid channel list + * ucfg_mlme_get_nol_across_regdmn() - get scan 11d interval + * @psoc: pointer to psoc object + * @value: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ + +QDF_STATUS +ucfg_mlme_get_nol_across_regdmn(struct wlan_objmgr_psoc *psoc, bool *value); + +/** + * ucfg_mlme_get_valid_channel_freq_list() - get valid channel + * list * @psoc: pointer to psoc object * @channel_list: pointer to return channel list * @channel_list_num: pointer to return channel list number @@ -3788,9 +3909,9 @@ ucfg_mlme_get_scan_11d_interval(struct wlan_objmgr_psoc *psoc, * Return: QDF Status */ QDF_STATUS -ucfg_mlme_get_valid_channel_list(struct wlan_objmgr_psoc *psoc, - uint8_t *channel_list, - uint32_t *channel_list_num); +ucfg_mlme_get_valid_channel_freq_list(struct wlan_objmgr_psoc *psoc, + uint32_t *channel_list, + uint32_t *channel_list_num); #ifdef FEATURE_LFR_SUBNET_DETECTION /** @@ -3860,6 +3981,36 @@ QDF_STATUS ucfg_mlme_set_obss_color_collision_offload_enabled( struct wlan_objmgr_psoc *psoc, uint8_t value); +/** + * ucfg_mlme_set_bss_color_collision_det_sta() - Enable bss color + * collision detection offload for STA mode + * @psoc: pointer to psoc object + * @value: enable or disable + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_bss_color_collision_det_sta(struct wlan_objmgr_psoc *psoc, + uint8_t value); + +/** + * ucfg_mlme_set_restricted_80p80_bw_supp() - Set the restricted 80p80 support + * @psoc: pointer to psoc object + * @restricted_80p80_supp: Value to be set from the caller + * + * Return: QDF Status + */ +QDF_STATUS ucfg_mlme_set_restricted_80p80_bw_supp(struct wlan_objmgr_psoc *psoc, + bool restricted_80p80_supp); + +/** + * ucfg_mlme_get_restricted_80p80_bw_supp() - Get the restricted 80p80 support + * @psoc: pointer to psoc object + * + * Return: true or false + */ +bool ucfg_mlme_get_restricted_80p80_bw_supp(struct wlan_objmgr_psoc *psoc); + /** * ucfg_mlme_get_channel_bonding_24ghz() - get channel bonding mode of 24ghz * @psoc: pointer to psoc object @@ -3983,4 +4134,49 @@ ucfg_mlme_get_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, mlme_get_discon_reason_n_from_ap(psoc, vdev_id, from_ap, reason_code); } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * ucfg_mlme_get_roam_reason_vsie_status() - Get roam reason vsie is + * enabled or disabled + * @psoc: pointer to psoc object + * @roam_reason_vsie_enabled: pointer to hold value of roam reason vsie + * + * Return: Success if able to get bcn rpt err vsie value, else failure + */ +static inline QDF_STATUS +ucfg_mlme_get_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t *roam_reason_vsie_enabled) +{ + return wlan_mlme_get_roam_reason_vsie_status(psoc, + roam_reason_vsie_enabled); +} + +/** + * ucfg_mlme_set_roam_reason_vsie_status() - Update roam reason vsie status + * value with user configured value + * @psoc: pointer to psoc object + * @roam_reason_vsie_enabled: value of roam reason vsie status + * + * Return: Success if able to get bcn rpt err vsie value, else failure + */ +static inline QDF_STATUS +ucfg_mlme_set_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t roam_reason_vsie_enabled) +{ + return wlan_mlme_set_roam_reason_vsie_status(psoc, + roam_reason_vsie_enabled); +} + +#endif + +/** + * ucfg_is_roaming_enabled() - Check if roaming enabled + * to firmware. + * @psoc: psoc context + * @vdev_id: vdev id + * + * Return: True if Roam state machine is in + * WLAN_ROAM_RSO_ENABLED/WLAN_ROAMING_IN_PROG/WLAN_ROAM_SYNCH_IN_PROG + */ +bool ucfg_is_roaming_enabled(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id); #endif /* _WLAN_MLME_UCFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_api.c b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_api.c index 7626ba35f7c48498e11936e2928fb61dc017d955..2fa9d7df4928ec4b77678af20671e9218d0705c9 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -63,9 +62,9 @@ QDF_STATUS wlan_mlme_set_cfg_str(uint8_t *src, struct mlme_cfg_str *dst_cfg_str, uint8_t wlan_mlme_get_tx_power(struct wlan_objmgr_psoc *psoc, enum band_info band) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return 0; @@ -82,9 +81,9 @@ uint8_t wlan_mlme_get_tx_power(struct wlan_objmgr_psoc *psoc, char *wlan_mlme_get_power_usage(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return NULL; @@ -95,9 +94,9 @@ QDF_STATUS wlan_mlme_get_ht_cap_info(struct wlan_objmgr_psoc *psoc, struct mlme_ht_capabilities_info *ht_cap_info) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -110,9 +109,9 @@ QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc, struct mlme_ht_capabilities_info ht_cap_info) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -124,9 +123,9 @@ QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -138,9 +137,9 @@ QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -157,9 +156,9 @@ QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -171,9 +170,9 @@ QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -188,11 +187,11 @@ QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, } QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t *band_capability) + uint32_t *band_capability) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -202,12 +201,12 @@ QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, } QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc, - uint8_t band_capability) + uint32_t band_capability) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -219,9 +218,9 @@ QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc, bool *prevent_link_down) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -233,9 +232,9 @@ QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_select_5ghz_margin(struct wlan_objmgr_psoc *psoc, uint8_t *select_5ghz_margin) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -247,9 +246,9 @@ QDF_STATUS wlan_mlme_get_select_5ghz_margin(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, bool *rtt_mac_randomization) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -261,9 +260,9 @@ QDF_STATUS wlan_mlme_get_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_crash_inject(struct wlan_objmgr_psoc *psoc, bool *crash_inject) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -275,9 +274,9 @@ QDF_STATUS wlan_mlme_get_crash_inject(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_lpass_support(struct wlan_objmgr_psoc *psoc, bool *lpass_support) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -289,9 +288,9 @@ QDF_STATUS wlan_mlme_get_lpass_support(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_self_recovery(struct wlan_objmgr_psoc *psoc, bool *self_recovery) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -303,9 +302,9 @@ QDF_STATUS wlan_mlme_get_self_recovery(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sub_20_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t *sub_20_chan_width) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -317,9 +316,9 @@ QDF_STATUS wlan_mlme_get_sub_20_chan_width(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_fw_timeout_crash(struct wlan_objmgr_psoc *psoc, bool *fw_timeout_crash) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -331,9 +330,9 @@ QDF_STATUS wlan_mlme_get_fw_timeout_crash(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_ito_repeat_count(struct wlan_objmgr_psoc *psoc, uint8_t *ito_repeat_count) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -345,9 +344,9 @@ QDF_STATUS wlan_mlme_get_ito_repeat_count(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_sap_inactivity_override(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return; @@ -357,7 +356,7 @@ void wlan_mlme_get_sap_inactivity_override(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_acs_with_more_param(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -369,7 +368,7 @@ QDF_STATUS wlan_mlme_get_acs_with_more_param(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_auto_channel_weight(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT); @@ -383,7 +382,7 @@ QDF_STATUS wlan_mlme_get_auto_channel_weight(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_vendor_acs_support(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -396,7 +395,7 @@ QDF_STATUS wlan_mlme_get_acs_support_for_dfs_ltecoex(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -409,7 +408,7 @@ QDF_STATUS wlan_mlme_get_external_acs_policy(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -421,7 +420,7 @@ wlan_mlme_get_external_acs_policy(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_tx_chainmask_cck(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -433,7 +432,7 @@ QDF_STATUS wlan_mlme_get_tx_chainmask_cck(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_tx_chainmask_1ss(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -446,9 +445,9 @@ void wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc, struct mlme_tgt_caps *tgt_caps) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return; @@ -464,9 +463,9 @@ wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_he_ul_mumimo(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -478,9 +477,9 @@ QDF_STATUS wlan_mlme_cfg_get_he_ul_mumimo(struct wlan_objmgr_psoc *psoc, QDF_STATUS mlme_cfg_get_he_caps(struct wlan_objmgr_psoc *psoc, tDot11fIEhe_cap *he_cap) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -492,9 +491,9 @@ QDF_STATUS mlme_cfg_get_he_caps(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_set_he_ul_mumimo(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -512,9 +511,9 @@ QDF_STATUS wlan_mlme_cfg_set_he_ul_mumimo(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_enable_ul_mimo(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -526,9 +525,9 @@ QDF_STATUS wlan_mlme_cfg_get_enable_ul_mimo(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_enable_ul_ofdm(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -538,13 +537,39 @@ QDF_STATUS wlan_mlme_cfg_get_enable_ul_ofdm(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +/* mlme_get_min_rate_cap() - get minimum capability for HE-MCS between + * ini value and fw capability. + * + * Rx HE-MCS Map and Tx HE-MCS Map subfields format where 2-bit indicates + * 0 indicates support for HE-MCS 0-7 for n spatial streams + * 1 indicates support for HE-MCS 0-9 for n spatial streams + * 2 indicates support for HE-MCS 0-11 for n spatial streams + * 3 indicates that n spatial streams is not supported for HE PPDUs + * + */ +static uint16_t mlme_get_min_rate_cap(uint16_t val1, uint16_t val2) +{ + uint16_t ret = 0, i; + + for (i = 0; i < 8; i++) { + if (((val1 >> (2 * i)) & 0x3) == 0x3 || + ((val2 >> (2 * i)) & 0x3) == 0x3) { + ret |= 0x3 << (2 * i); + continue; + } + ret |= QDF_MIN((val1 >> (2 * i)) & 0x3, + (val2 >> (2 * i)) & 0x3) << (2 * i); + } + return ret; +} + QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc, struct wma_tgt_cfg *wma_cfg) { uint8_t chan_width; QDF_STATUS status = QDF_STATUS_SUCCESS; tDot11fIEhe_cap *he_cap = &wma_cfg->he_cap; - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); uint8_t value; uint16_t tx_mcs_map = 0; uint16_t rx_mcs_map = 0; @@ -782,8 +807,12 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc, mlme_obj->cfg.he_caps.dot11_he_cap.rx_full_bw_su_he_mu_non_cmpr_sigb = he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb; - tx_mcs_map = he_cap->tx_he_mcs_map_lt_80; - rx_mcs_map = he_cap->rx_he_mcs_map_lt_80; + tx_mcs_map = mlme_get_min_rate_cap( + mlme_obj->cfg.he_caps.dot11_he_cap.tx_he_mcs_map_lt_80, + he_cap->tx_he_mcs_map_lt_80); + rx_mcs_map = mlme_get_min_rate_cap( + mlme_obj->cfg.he_caps.dot11_he_cap.rx_he_mcs_map_lt_80, + he_cap->rx_he_mcs_map_lt_80); if (!mlme_obj->cfg.vht_caps.vht_cap_info.enable2x2) { nss = 2; tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, HE_MCS_DISABLE, nss); @@ -796,8 +825,12 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc, if (cfg_in_range(CFG_HE_TX_MCS_MAP_LT_80, tx_mcs_map)) mlme_obj->cfg.he_caps.dot11_he_cap.tx_he_mcs_map_lt_80 = tx_mcs_map; - tx_mcs_map = *((uint16_t *)he_cap->tx_he_mcs_map_160); - rx_mcs_map = *((uint16_t *)he_cap->rx_he_mcs_map_160); + tx_mcs_map = mlme_get_min_rate_cap( + *((uint16_t *)mlme_obj->cfg.he_caps.dot11_he_cap.tx_he_mcs_map_160), + *((uint16_t *)he_cap->tx_he_mcs_map_160)); + rx_mcs_map = mlme_get_min_rate_cap( + *((uint16_t *)mlme_obj->cfg.he_caps.dot11_he_cap.rx_he_mcs_map_160), + *((uint16_t *)he_cap->rx_he_mcs_map_160)); if (!mlme_obj->cfg.vht_caps.vht_cap_info.enable2x2) { nss = 2; @@ -841,7 +874,7 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_num_11b_tx_chains(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -853,7 +886,7 @@ QDF_STATUS wlan_mlme_get_num_11b_tx_chains(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_bt_chain_separation_flag(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -865,7 +898,7 @@ QDF_STATUS wlan_mlme_get_bt_chain_separation_flag(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_num_11ag_tx_chains(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -879,8 +912,8 @@ QDF_STATUS wlan_mlme_configure_chain_mask(struct wlan_objmgr_psoc *psoc, { int ret_val; uint8_t ch_msk_val; - struct wma_caps_per_phy non_dbs_phy_cap; - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wma_caps_per_phy non_dbs_phy_cap = {0}; + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); QDF_STATUS status; bool enable2x2, as_enabled, enable_bt_chain_sep; uint8_t dual_mac_feature; @@ -1017,9 +1050,9 @@ QDF_STATUS wlan_mlme_get_manufacturer_name(struct wlan_objmgr_psoc *psoc, uint8_t *pbuf, uint32_t *plen) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1033,9 +1066,9 @@ QDF_STATUS wlan_mlme_get_model_number(struct wlan_objmgr_psoc *psoc, uint8_t *pbuf, uint32_t *plen) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1050,9 +1083,9 @@ QDF_STATUS wlan_mlme_get_model_name(struct wlan_objmgr_psoc *psoc, uint8_t *pbuf, uint32_t *plen) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1066,9 +1099,9 @@ QDF_STATUS wlan_mlme_get_manufacture_product_version(struct wlan_objmgr_psoc *psoc, uint8_t *pbuf, uint32_t *plen) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1082,9 +1115,9 @@ QDF_STATUS wlan_mlme_get_manufacture_product_name(struct wlan_objmgr_psoc *psoc, uint8_t *pbuf, uint32_t *plen) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1098,9 +1131,9 @@ wlan_mlme_get_manufacture_product_name(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_tl_delayed_trgr_frm_int(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_TL_DELAYED_TRGR_FRM_INTERVAL); return; @@ -1113,9 +1146,9 @@ void wlan_mlme_get_tl_delayed_trgr_frm_int(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_dir_ac_vo(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1128,9 +1161,9 @@ QDF_STATUS wlan_mlme_get_wmm_dir_ac_vo(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_vo(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1142,9 +1175,9 @@ QDF_STATUS wlan_mlme_get_wmm_mean_data_rate_ac_vo(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1156,9 +1189,9 @@ wlan_mlme_get_wmm_mean_data_rate_ac_vo(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_vo(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1169,9 +1202,9 @@ QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_vo(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_sba_ac_vo(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { return QDF_STATUS_E_FAILURE; } @@ -1184,9 +1217,9 @@ wlan_mlme_get_wmm_sba_ac_vo(struct wlan_objmgr_psoc *psoc, uint16_t *value) QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_srv_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1198,9 +1231,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_srv_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1212,9 +1245,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_vo_sus_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1226,9 +1259,9 @@ wlan_mlme_get_wmm_dir_ac_vi(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_vi(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1242,9 +1275,9 @@ QDF_STATUS wlan_mlme_get_wmm_mean_data_rate_ac_vi(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1256,9 +1289,9 @@ wlan_mlme_get_wmm_mean_data_rate_ac_vi(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_vi(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1270,9 +1303,9 @@ QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_vi(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_sba_ac_vi(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1285,9 +1318,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_vi_srv_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1299,9 +1332,9 @@ wlan_mlme_get_wmm_uapsd_vi_srv_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_uapsd_vi_sus_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1313,9 +1346,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_vi_sus_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_dir_ac_be(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1327,9 +1360,9 @@ wlan_mlme_get_wmm_dir_ac_be(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_be(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1342,9 +1375,9 @@ QDF_STATUS wlan_mlme_get_wmm_mean_data_rate_ac_be(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1356,9 +1389,9 @@ wlan_mlme_get_wmm_mean_data_rate_ac_be(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_be(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1370,9 +1403,9 @@ QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_be(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_sba_ac_be(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1384,9 +1417,9 @@ wlan_mlme_get_wmm_sba_ac_be(struct wlan_objmgr_psoc *psoc, uint16_t *value) QDF_STATUS wlan_mlme_get_wmm_uapsd_be_srv_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1398,9 +1431,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_be_srv_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_uapsd_be_sus_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1412,9 +1445,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_be_sus_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_dir_ac_bk(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1426,9 +1459,9 @@ wlan_mlme_get_wmm_dir_ac_bk(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_wmm_nom_msdu_size_ac_bk(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1441,9 +1474,9 @@ QDF_STATUS wlan_mlme_get_wmm_mean_data_rate_ac_bk(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1455,9 +1488,9 @@ wlan_mlme_get_wmm_mean_data_rate_ac_bk(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_bk(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1469,9 +1502,9 @@ QDF_STATUS wlan_mlme_get_wmm_min_phy_rate_ac_bk(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_sba_ac_bk(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1484,9 +1517,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_bk_srv_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1499,9 +1532,9 @@ QDF_STATUS wlan_mlme_get_wmm_uapsd_bk_sus_intv(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1513,9 +1546,9 @@ wlan_mlme_get_wmm_uapsd_bk_sus_intv(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1527,9 +1560,9 @@ wlan_mlme_get_wmm_mode(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_80211e_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1541,9 +1574,9 @@ wlan_mlme_get_80211e_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_wmm_uapsd_mask(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1555,9 +1588,9 @@ wlan_mlme_get_wmm_uapsd_mask(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_implicit_qos_is_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1570,9 +1603,9 @@ QDF_STATUS wlan_mlme_get_implicit_qos_is_enabled(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_inactivity_interval(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_QOS_WMM_INACTIVITY_INTERVAL); return; @@ -1585,9 +1618,9 @@ void wlan_mlme_get_inactivity_interval(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_is_ts_burst_size_enable(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_QOS_WMM_BURST_SIZE_DEFN); return; @@ -1599,9 +1632,9 @@ void wlan_mlme_get_is_ts_burst_size_enable(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_ts_info_ack_policy(struct wlan_objmgr_psoc *psoc, enum mlme_ts_info_ack_policy *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_QOS_WMM_TS_INFO_ACK_POLICY); return; @@ -1614,9 +1647,9 @@ void wlan_mlme_get_ts_info_ack_policy(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_ts_acm_value_for_ac(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1628,9 +1661,9 @@ wlan_mlme_get_ts_acm_value_for_ac(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_listen_interval(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1642,9 +1675,9 @@ QDF_STATUS wlan_mlme_get_listen_interval(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc, int value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1659,9 +1692,9 @@ QDF_STATUS wlan_mlme_set_sap_listen_interval(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, int value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1673,12 +1706,26 @@ QDF_STATUS wlan_mlme_set_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_mlme_get_assoc_sta_limit(struct wlan_objmgr_psoc *psoc, + int *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.sap_cfg.assoc_sta_limit; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_set_rmc_action_period_freq(struct wlan_objmgr_psoc *psoc, int value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1693,9 +1740,9 @@ QDF_STATUS wlan_mlme_set_rmc_action_period_freq(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1707,9 +1754,9 @@ QDF_STATUS wlan_mlme_get_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1719,12 +1766,12 @@ QDF_STATUS wlan_mlme_set_sap_get_peer_info(struct wlan_objmgr_psoc *psoc, } QDF_STATUS -wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, - bool *value) +wlan_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, + bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1733,12 +1780,27 @@ wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +wlan_mlme_is_6g_sap_fd_enabled(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *value = mlme_obj->cfg.sap_cfg.is_6g_sap_fd_enabled; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1750,9 +1812,9 @@ QDF_STATUS wlan_mlme_get_sap_allow_all_channels(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_max_peers(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1764,9 +1826,9 @@ QDF_STATUS wlan_mlme_get_sap_max_peers(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_sap_max_peers(struct wlan_objmgr_psoc *psoc, int value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1781,9 +1843,9 @@ QDF_STATUS wlan_mlme_set_sap_max_peers(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_max_offload_peers(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1795,9 +1857,9 @@ QDF_STATUS wlan_mlme_get_sap_max_offload_peers(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_max_offload_reorder_buffs(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1809,9 +1871,9 @@ QDF_STATUS wlan_mlme_get_sap_max_offload_reorder_buffs(struct wlan_objmgr_psoc QDF_STATUS wlan_mlme_get_sap_chn_switch_bcn_count(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1823,9 +1885,9 @@ QDF_STATUS wlan_mlme_get_sap_chn_switch_bcn_count(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_chn_switch_mode(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1837,9 +1899,9 @@ QDF_STATUS wlan_mlme_get_sap_chn_switch_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_internal_restart(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1851,9 +1913,9 @@ QDF_STATUS wlan_mlme_get_sap_internal_restart(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_max_modulated_dtim(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1865,9 +1927,9 @@ QDF_STATUS wlan_mlme_get_sap_max_modulated_dtim(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_chan_pref_location(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1879,9 +1941,9 @@ QDF_STATUS wlan_mlme_get_sap_chan_pref_location(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_country_priority(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1893,9 +1955,9 @@ QDF_STATUS wlan_mlme_get_sap_country_priority(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_sap_reduced_beacon_interval(struct wlan_objmgr_psoc *psoc, int *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_REDUCED_BEACON_INTERVAL); return QDF_STATUS_E_FAILURE; @@ -1909,9 +1971,9 @@ QDF_STATUS wlan_mlme_get_sap_reduced_beacon_interval(struct wlan_objmgr_psoc QDF_STATUS wlan_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1923,9 +1985,9 @@ QDF_STATUS wlan_mlme_get_sap_chan_switch_rate_enabled(struct wlan_objmgr_psoc QDF_STATUS wlan_mlme_get_sap_force_11n_for_11ac(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1937,9 +1999,9 @@ QDF_STATUS wlan_mlme_get_sap_force_11n_for_11ac(struct wlan_objmgr_psoc QDF_STATUS wlan_mlme_get_go_force_11n_for_11ac(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -1951,9 +2013,9 @@ QDF_STATUS wlan_mlme_get_go_force_11n_for_11ac(struct wlan_objmgr_psoc QDF_STATUS wlan_mlme_is_sap_11ac_override(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_SAP_11AC_OVERRIDE); return QDF_STATUS_E_FAILURE; @@ -1966,9 +2028,9 @@ QDF_STATUS wlan_mlme_is_sap_11ac_override(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_is_go_11ac_override(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_GO_11AC_OVERRIDE); return QDF_STATUS_E_FAILURE; @@ -1981,9 +2043,9 @@ QDF_STATUS wlan_mlme_is_go_11ac_override(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_sap_11ac_override(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; mlme_obj->cfg.sap_cfg.sap_11ac_override = value; @@ -1994,9 +2056,9 @@ QDF_STATUS wlan_mlme_set_sap_11ac_override(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_go_11ac_override(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; mlme_obj->cfg.sap_cfg.go_11ac_override = value; @@ -2006,7 +2068,7 @@ QDF_STATUS wlan_mlme_set_go_11ac_override(struct wlan_objmgr_psoc *psoc, bool wlan_mlme_get_host_scan_abort_support(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return false; @@ -2017,7 +2079,7 @@ bool wlan_mlme_get_host_scan_abort_support(struct wlan_objmgr_psoc *psoc) QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2029,7 +2091,7 @@ QDF_STATUS wlan_mlme_get_oce_sta_enabled_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_oce_sap_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2075,7 +2137,7 @@ void wlan_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev) { uint16_t sap_connected_peer, go_connected_peer; struct wlan_objmgr_psoc *psoc = NULL; - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; uint8_t updated_fw_value = 0; psoc = wlan_pdev_get_psoc(pdev); @@ -2086,7 +2148,10 @@ void wlan_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev) wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE); go_connected_peer = wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE); - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) + return; if (sap_connected_peer || go_connected_peer) { updated_fw_value = mlme_obj->cfg.oce.feature_bitmap; @@ -2109,9 +2174,9 @@ void wlan_mlme_update_oce_flags(struct wlan_objmgr_pdev *pdev) bool wlan_mlme_is_ap_prot_enabled(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return false; @@ -2121,9 +2186,9 @@ bool wlan_mlme_is_ap_prot_enabled(struct wlan_objmgr_psoc *psoc) QDF_STATUS wlan_mlme_get_ap_protection_mode(struct wlan_objmgr_psoc *psoc, uint16_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2135,9 +2200,9 @@ QDF_STATUS wlan_mlme_get_ap_protection_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_is_ap_obss_prot_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2149,9 +2214,9 @@ QDF_STATUS wlan_mlme_is_ap_obss_prot_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_rts_threshold(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2163,7 +2228,7 @@ QDF_STATUS wlan_mlme_get_rts_threshold(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; tp_wma_handle wma_handle; wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -2173,7 +2238,7 @@ QDF_STATUS wlan_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2187,9 +2252,9 @@ QDF_STATUS wlan_mlme_set_rts_threshold(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_frag_threshold(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2201,7 +2266,7 @@ QDF_STATUS wlan_mlme_get_frag_threshold(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; tp_wma_handle wma_handle; wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -2211,7 +2276,7 @@ QDF_STATUS wlan_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2226,7 +2291,7 @@ QDF_STATUS wlan_mlme_set_frag_threshold(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2238,7 +2303,7 @@ QDF_STATUS wlan_mlme_get_fils_enabled_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2250,7 +2315,7 @@ QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2263,9 +2328,9 @@ QDF_STATUS wlan_mlme_get_sta_miracast_mcc_rest_time(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2278,9 +2343,9 @@ QDF_STATUS wlan_mlme_get_sap_mcc_chnl_avoid(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2293,9 +2358,9 @@ QDF_STATUS wlan_mlme_get_mcc_bcast_prob_resp(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2308,9 +2373,9 @@ QDF_STATUS wlan_mlme_get_mcc_rts_cts_prot(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2323,9 +2388,9 @@ QDF_STATUS wlan_mlme_get_mcc_feature(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2466,7 +2531,6 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params, return QDF_STATUS_SUCCESS; } -#ifdef CRYPTO_SET_KEY_CONVERGED QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, struct wlan_mlme_wep_cfg *wep_params, enum wep_key_id wep_keyid, uint8_t *default_key, @@ -2493,45 +2557,6 @@ QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } -#else -QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev, - struct wlan_mlme_wep_cfg *wep_params, - enum wep_key_id wep_keyid, uint8_t *default_key, - qdf_size_t *key_len) -{ - switch (wep_keyid) { - case MLME_WEP_DEFAULT_KEY_1: - wlan_mlme_get_cfg_str(default_key, - &wep_params->wep_default_key_1, - key_len); - break; - - case MLME_WEP_DEFAULT_KEY_2: - wlan_mlme_get_cfg_str(default_key, - &wep_params->wep_default_key_2, - key_len); - break; - - case MLME_WEP_DEFAULT_KEY_3: - wlan_mlme_get_cfg_str(default_key, - &wep_params->wep_default_key_3, - key_len); - break; - - case MLME_WEP_DEFAULT_KEY_4: - wlan_mlme_get_cfg_str(default_key, - &wep_params->wep_default_key_4, - key_len); - break; - - default: - mlme_legacy_err("Invalid key id:%d", wep_keyid); - return QDF_STATUS_E_INVAL; - } - mlme_legacy_debug("key_id:%d key_len:%zd", wep_keyid, *key_len); - return QDF_STATUS_SUCCESS; -} -#endif /* CRYPTO_SET_KEY_CONVERGED */ QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params, enum wep_key_id wep_keyid, uint8_t *key_to_set, @@ -2578,9 +2603,9 @@ QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params, QDF_STATUS wlan_mlme_is_11h_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2592,9 +2617,9 @@ wlan_mlme_is_11h_enabled(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_set_11h_enabled(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2606,9 +2631,9 @@ wlan_mlme_set_11h_enabled(struct wlan_objmgr_psoc *psoc, bool value) QDF_STATUS wlan_mlme_is_11d_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2620,9 +2645,9 @@ wlan_mlme_is_11d_enabled(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_set_11d_enabled(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2634,13 +2659,18 @@ wlan_mlme_set_11d_enabled(struct wlan_objmgr_psoc *psoc, bool value) QDF_STATUS wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; mlme_obj->cfg.vht_caps.vht_cap_info.supp_chan_width = value; + if (value == VHT_CAP_160_AND_80P80_SUPP || + value == VHT_CAP_160_SUPP) { + mlme_obj->cfg.vht_caps.vht_cap_info.vht_extended_nss_bw_cap = 1; + mlme_obj->cfg.vht_caps.vht_cap_info.extended_nss_bw_supp = 0; + } return QDF_STATUS_SUCCESS; } @@ -2648,9 +2678,9 @@ wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t value) QDF_STATUS wlan_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2662,9 +2692,9 @@ wlan_mlme_cfg_get_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_cfg_set_vht_ldpc_coding_cap(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2677,9 +2707,9 @@ QDF_STATUS wlan_mlme_cfg_set_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2691,9 +2721,9 @@ wlan_mlme_cfg_set_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2705,9 +2735,9 @@ wlan_mlme_cfg_get_short_gi_160_mhz(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_cfg_get_vht_tx_stbc(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2719,9 +2749,9 @@ wlan_mlme_cfg_get_vht_tx_stbc(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_cfg_get_vht_rx_stbc(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2734,9 +2764,9 @@ QDF_STATUS wlan_mlme_cfg_set_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2749,9 +2779,9 @@ QDF_STATUS wlan_mlme_cfg_get_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2763,9 +2793,9 @@ wlan_mlme_cfg_get_vht_tx_bfee_ant_supp(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2777,9 +2807,9 @@ QDF_STATUS wlan_mlme_cfg_get_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_set_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2791,9 +2821,9 @@ QDF_STATUS wlan_mlme_cfg_set_vht_rx_mcs_map(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_get_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2805,9 +2835,9 @@ QDF_STATUS wlan_mlme_cfg_get_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_cfg_set_vht_tx_mcs_map(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2820,9 +2850,9 @@ QDF_STATUS wlan_mlme_cfg_set_vht_rx_supp_data_rate(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2835,9 +2865,9 @@ QDF_STATUS wlan_mlme_cfg_set_vht_tx_supp_data_rate(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2850,9 +2880,9 @@ QDF_STATUS wlan_mlme_cfg_get_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2865,9 +2895,9 @@ QDF_STATUS wlan_mlme_cfg_set_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2879,9 +2909,9 @@ wlan_mlme_cfg_set_vht_basic_mcs_set(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_vht_enable_tx_bf(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2893,9 +2923,9 @@ wlan_mlme_get_vht_enable_tx_bf(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_vht_tx_su_beamformer(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2907,9 +2937,9 @@ wlan_mlme_get_vht_tx_su_beamformer(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_vht_channel_width(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2922,9 +2952,9 @@ wlan_mlme_get_vht_channel_width(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_vht_rx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2936,9 +2966,9 @@ wlan_mlme_get_vht_rx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_vht_tx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2950,9 +2980,9 @@ wlan_mlme_get_vht_tx_mcs_8_9(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_vht_rx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2964,9 +2994,9 @@ wlan_mlme_get_vht_rx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2978,9 +3008,9 @@ wlan_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value) QDF_STATUS wlan_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -2989,12 +3019,65 @@ wlan_mlme_get_vht20_mcs9(struct wlan_objmgr_psoc *psoc, bool *value) return QDF_STATUS_SUCCESS; } +QDF_STATUS +wlan_mlme_get_indoor_support_for_nan(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *value = false; + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_INVAL; + } + + *value = mlme_obj->cfg.reg.enable_nan_on_indoor_channels; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_get_srd_master_mode_for_vdev(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE vdev_opmode, + bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *value = false; + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_INVAL; + } + + switch (vdev_opmode) { + case QDF_SAP_MODE: + *value = mlme_obj->cfg.reg.etsi_srd_chan_in_master_mode & + MLME_SRD_MASTER_MODE_SAP; + break; + case QDF_P2P_GO_MODE: + *value = mlme_obj->cfg.reg.etsi_srd_chan_in_master_mode & + MLME_SRD_MASTER_MODE_P2P_GO; + break; + case QDF_NAN_DISC_MODE: + *value = mlme_obj->cfg.reg.etsi_srd_chan_in_master_mode & + MLME_SRD_MASTER_MODE_NAN; + break; + default: + mlme_legacy_err("Unexpected opmode %d", vdev_opmode); + *value = false; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3006,9 +3089,9 @@ wlan_mlme_get_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_set_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3020,9 +3103,9 @@ wlan_mlme_set_vht_enable2x2(struct wlan_objmgr_psoc *psoc, bool value) QDF_STATUS wlan_mlme_get_vht_enable_paid(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3034,9 +3117,9 @@ wlan_mlme_get_vht_enable_paid(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_vht_enable_gid(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3048,9 +3131,9 @@ wlan_mlme_get_vht_enable_gid(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_get_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3062,9 +3145,9 @@ wlan_mlme_get_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS wlan_mlme_set_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3076,9 +3159,9 @@ wlan_mlme_set_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool value) QDF_STATUS wlan_mlme_get_vendor_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3090,12 +3173,12 @@ wlan_mlme_get_vendor_vht_for_24ghz(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc, struct wma_tgt_vht_cap *cfg) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; struct mlme_vht_capabilities_info *vht_cap_info; uint32_t value = 0; bool hw_rx_ldpc_enabled; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3179,19 +3262,22 @@ mlme_update_vht_cap(struct wlan_objmgr_psoc *psoc, struct wma_tgt_vht_cap *cfg) if (vht_cap_info->short_gi_160mhz && !cfg->vht_short_gi_160) vht_cap_info->short_gi_160mhz = cfg->vht_short_gi_160; - vht_cap_info->vht_mcs_10_11_supp = cfg->vht_mcs_10_11_supp; - mlme_legacy_debug(" vht_mcs_10_11_supp %d", cfg->vht_mcs_10_11_supp); + if (cfg_get(psoc, CFG_ENABLE_VHT_MCS_10_11)) + vht_cap_info->vht_mcs_10_11_supp = cfg->vht_mcs_10_11_supp; + + mlme_legacy_debug("vht_mcs_10_11_supp %d", + vht_cap_info->vht_mcs_10_11_supp); return QDF_STATUS_SUCCESS; } QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; struct mlme_vht_capabilities_info *vht_cap_info; uint32_t temp = 0; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3230,9 +3316,9 @@ QDF_STATUS mlme_update_nss_vht_cap(struct wlan_objmgr_psoc *psoc) QDF_STATUS wlan_mlme_is_sap_uapsd_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3244,9 +3330,9 @@ QDF_STATUS wlan_mlme_is_sap_uapsd_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_dtim_selection_diversity(struct wlan_objmgr_psoc *psoc, uint32_t *dtim_selection_div) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *dtim_selection_div = cfg_default(CFG_DTIM_SELECTION_DIVERSITY); return QDF_STATUS_E_FAILURE; @@ -3260,9 +3346,9 @@ QDF_STATUS wlan_mlme_get_dtim_selection_diversity(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_bmps_min_listen_interval(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_BMPS_MINIMUM_LI); return QDF_STATUS_E_FAILURE; @@ -3276,9 +3362,9 @@ QDF_STATUS wlan_mlme_get_bmps_min_listen_interval(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_bmps_max_listen_interval(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_BMPS_MAXIMUM_LI); return QDF_STATUS_E_FAILURE; @@ -3292,9 +3378,9 @@ QDF_STATUS wlan_mlme_get_bmps_max_listen_interval(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_sap_uapsd_flag(struct wlan_objmgr_psoc *psoc, bool value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3306,9 +3392,9 @@ QDF_STATUS wlan_mlme_set_sap_uapsd_flag(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_rrm_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3319,9 +3405,9 @@ QDF_STATUS wlan_mlme_get_rrm_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_auto_bmps_timer_value(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_AUTO_BMPS_ENABLE_TIMER); return QDF_STATUS_E_FAILURE; @@ -3335,9 +3421,9 @@ QDF_STATUS wlan_mlme_get_auto_bmps_timer_value(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_is_bmps_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_ENABLE_PS); return QDF_STATUS_E_FAILURE; @@ -3351,9 +3437,9 @@ QDF_STATUS wlan_mlme_is_bmps_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_is_imps_enabled(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_ENABLE_IMPS); return QDF_STATUS_E_FAILURE; @@ -3366,9 +3452,9 @@ QDF_STATUS wlan_mlme_is_imps_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_override_bmps_imps(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3390,9 +3476,9 @@ QDF_STATUS wlan_mlme_get_self_gen_frm_pwr(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_SELF_GEN_FRM_PWR); mlme_legacy_err("Failed to get MLME Obj"); @@ -3409,7 +3495,7 @@ QDF_STATUS wlan_mlme_ibss_power_save_setup(struct wlan_objmgr_psoc *psoc, { struct wlan_mlme_ibss_cfg *ibss_cfg; int ret; - struct wlan_mlme_psoc_obj *mlme_obj = mlme_get_psoc_obj(psoc); + struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3491,14 +3577,30 @@ QDF_STATUS wlan_mlme_ibss_power_save_setup(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *value = cfg_default(CFG_DISABLE_4WAY_HS_OFFLOAD); + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + *value = mlme_obj->cfg.gen.disable_4way_hs_offload; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_bmiss_skip_full_scan_value(struct wlan_objmgr_psoc *psoc, bool *value) { + struct wlan_mlme_psoc_ext_obj *mlme_obj; - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_BMISS_SKIP_FULL_SCAN); mlme_legacy_err("Failed to get MLME Obj"); @@ -3530,9 +3632,9 @@ QDF_STATUS mlme_get_peer_phymode(struct wlan_objmgr_psoc *psoc, uint8_t *mac, QDF_STATUS mlme_set_tgt_wpa3_roam_cap(struct wlan_objmgr_psoc *psoc, uint32_t akm_bitmap) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3545,9 +3647,10 @@ QDF_STATUS wlan_mlme_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc, bool *disabled) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); - mlme_obj = mlme_get_psoc_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_FAILURE; @@ -3555,51 +3658,6 @@ wlan_mlme_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -QDF_STATUS -wlan_mlme_get_mgmt_max_retry(struct wlan_objmgr_psoc *psoc, - uint8_t *max_retry) -{ - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = mlme_get_psoc_obj(psoc); - - if (!mlme_obj) { - *max_retry = cfg_default(CFG_MGMT_RETRY_MAX); - return QDF_STATUS_E_FAILURE; - } - - *max_retry = mlme_obj->cfg.gen.mgmt_retry_max; - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -wlan_mlme_get_status_ring_buffer(struct wlan_objmgr_psoc *psoc, - bool *enable_ring_buffer) -{ - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = mlme_get_psoc_obj(psoc); - - if (!mlme_obj) { - *enable_ring_buffer = cfg_default(CFG_ENABLE_RING_BUFFER); - return QDF_STATUS_E_FAILURE; - } - - *enable_ring_buffer = mlme_obj->cfg.gen.enable_ring_buffer; - return QDF_STATUS_SUCCESS; -} - -bool wlan_mlme_get_peer_unmap_conf(struct wlan_objmgr_psoc *psoc) -{ - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = mlme_get_psoc_obj(psoc); - if (!mlme_obj) - return false; - - return mlme_obj->cfg.gen.enable_peer_unmap_conf_support; -} - char *mlme_get_roam_trigger_str(uint32_t roam_scan_trigger) { switch (roam_scan_trigger) { @@ -3661,8 +3719,9 @@ void wlan_mlme_set_sae_single_pmk_bss_cap(struct wlan_objmgr_psoc *psoc, vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_MLME_OBJMGR_ID); + if (!vdev) { - mlme_legacy_err("get vdev failed"); + mlme_err("get vdev failed"); return; } @@ -3682,6 +3741,8 @@ void wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, struct mlme_pmk_info *sae_single_pmk) { struct mlme_legacy_priv *mlme_priv; + uint32_t keymgmt; + bool is_sae_connection = false; mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); if (!mlme_priv) { @@ -3689,11 +3750,13 @@ void wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, return; } - mlme_legacy_debug("SAE_SPMK: single_pmk_ap:%d, pmk_len:%d", - mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap, - sae_single_pmk->pmk_len); + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + + if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) + is_sae_connection = true; - if (mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap) + if (mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap && + is_sae_connection) mlme_priv->mlme_roam.sae_single_pmk.pmk_info = *sae_single_pmk; } @@ -3834,65 +3897,190 @@ char *mlme_get_sub_reason_str(uint32_t sub_reason) switch (sub_reason) { case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: return "PERIODIC TIMER"; - case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: - return "INACTIVITY TIMER"; + case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: + return "LOW RSSI PERIODIC TIMER1"; case WMI_ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: - return "BTM DISASSOC TIMER"; + return "BTM DISASSOC IMMINENT TIMER"; case WMI_ROAM_TRIGGER_SUB_REASON_FULL_SCAN: return "FULL SCAN"; - case WMI_ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: - return "LOW RSSI PERIODIC SCAN"; case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: - return "CU PERIODIC SCAN"; + return "CU PERIODIC Timer1"; + case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI: + return "LOW RSSI INACTIVE TIMER"; + case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: + return "CU PERIODIC TIMER2"; + case WMI_ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_LOW_RSSI: + return "LOW RSSI PERIODIC TIMER2"; + case WMI_ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: + return "CU INACTIVITY TIMER"; default: return "NONE"; } } QDF_STATUS -wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value) +wlan_mlme_get_mgmt_max_retry(struct wlan_objmgr_psoc *psoc, + uint8_t *max_retry) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); - mlme_obj = mlme_get_psoc_obj(psoc); if (!mlme_obj) { - *value = cfg_default(CFG_DISABLE_4WAY_HS_OFFLOAD); - mlme_legacy_err("Failed to get MLME Obj"); + *max_retry = cfg_default(CFG_MGMT_RETRY_MAX); return QDF_STATUS_E_FAILURE; } - *value = mlme_obj->cfg.gen.disable_4way_hs_offload; + *max_retry = mlme_obj->cfg.gen.mgmt_retry_max; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_get_status_ring_buffer(struct wlan_objmgr_psoc *psoc, + bool *enable_ring_buffer) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) { + *enable_ring_buffer = cfg_default(CFG_ENABLE_RING_BUFFER); + return QDF_STATUS_E_FAILURE; + } + + *enable_ring_buffer = mlme_obj->cfg.gen.enable_ring_buffer; return QDF_STATUS_SUCCESS; } -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -uint32_t wlan_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc) +bool wlan_mlme_get_peer_unmap_conf(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) - return cfg_default(CFG_ROAM_TRIGGER_BITMAP); + return false; - return mlme_obj->cfg.lfr.roam_trigger_bitmap; + return mlme_obj->cfg.gen.enable_peer_unmap_conf_support; } + +#ifdef WLAN_FEATURE_SAE + +#define NUM_RETRY_BITS 3 +#define ROAM_AUTH_INDEX 2 +#define ASSOC_INDEX 1 +#define AUTH_INDEX 0 +#define MAX_RETRIES 2 +#define MAX_ROAM_AUTH_RETRIES 1 +#define MAX_AUTH_RETRIES 3 + +QDF_STATUS +wlan_mlme_get_sae_assoc_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) { + *retry_count = 0; + return QDF_STATUS_E_FAILURE; + } + + *retry_count = + WLAN_GET_BITS(mlme_obj->cfg.gen.sae_connect_retries, + ASSOC_INDEX * NUM_RETRY_BITS, NUM_RETRY_BITS); + + *retry_count = QDF_MIN(MAX_RETRIES, *retry_count); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_get_sae_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) { + *retry_count = 0; + return QDF_STATUS_E_FAILURE; + } + + *retry_count = + WLAN_GET_BITS(mlme_obj->cfg.gen.sae_connect_retries, + AUTH_INDEX * NUM_RETRY_BITS, NUM_RETRY_BITS); + + *retry_count = QDF_MIN(MAX_AUTH_RETRIES, *retry_count); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_get_sae_roam_auth_retry_count(struct wlan_objmgr_psoc *psoc, + uint8_t *retry_count) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) { + *retry_count = 0; + return QDF_STATUS_E_FAILURE; + } + + *retry_count = + WLAN_GET_BITS(mlme_obj->cfg.gen.sae_connect_retries, + ROAM_AUTH_INDEX * NUM_RETRY_BITS, NUM_RETRY_BITS); + + *retry_count = QDF_MIN(MAX_ROAM_AUTH_RETRIES, *retry_count); + + return QDF_STATUS_SUCCESS; +} + #endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS -wlan_mlme_get_dfs_chan_ageout_time(struct wlan_objmgr_psoc *psoc, - uint8_t *dfs_chan_ageout_time) +wlan_mlme_get_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t *roam_reason_vsie_enable) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { - *dfs_chan_ageout_time = - cfg_default(CFG_DFS_CHAN_AGEOUT_TIME); + *roam_reason_vsie_enable = + cfg_default(CFG_ENABLE_ROAM_REASON_VSIE); return QDF_STATUS_E_FAILURE; } - *dfs_chan_ageout_time = mlme_obj->cfg.gen.dfs_chan_ageout_time; + *roam_reason_vsie_enable = mlme_obj->cfg.lfr.enable_roam_reason_vsie; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_set_roam_reason_vsie_status(struct wlan_objmgr_psoc *psoc, + uint8_t roam_reason_vsie_enable) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + mlme_obj->cfg.lfr.enable_roam_reason_vsie = roam_reason_vsie_enable; return QDF_STATUS_SUCCESS; } + +uint32_t wlan_mlme_get_roaming_triggers(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return cfg_default(CFG_ROAM_TRIGGER_BITMAP); + + return mlme_obj->cfg.lfr.roam_trigger_bitmap; +} +#endif diff --git a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 5faa1f42d6cce3c41d77358df751e4d57ac67c6a..bdbc2aaa4243c5b1928d4c0e373c41cc76e0d5f8 100644 --- a/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -45,24 +46,6 @@ QDF_STATUS ucfg_mlme_init(void) { QDF_STATUS status; - status = wlan_objmgr_register_psoc_create_handler( - WLAN_UMAC_COMP_MLME, - mlme_psoc_object_created_notification, - NULL); - if (status != QDF_STATUS_SUCCESS) { - mlme_legacy_err("unable to register psoc create handle"); - return status; - } - - status = wlan_objmgr_register_psoc_destroy_handler( - WLAN_UMAC_COMP_MLME, - mlme_psoc_object_destroyed_notification, - NULL); - if (status != QDF_STATUS_SUCCESS) { - mlme_legacy_err("unable to register psoc create handle"); - return status; - } - status = wlan_objmgr_register_peer_create_handler( WLAN_UMAC_COMP_MLME, mlme_peer_object_created_notification, @@ -102,21 +85,6 @@ QDF_STATUS ucfg_mlme_deinit(void) if (QDF_IS_STATUS_ERROR(status)) mlme_legacy_err("unable to unregister peer create handle"); - status = wlan_objmgr_unregister_psoc_destroy_handler( - WLAN_UMAC_COMP_MLME, - mlme_psoc_object_destroyed_notification, - NULL); - if (QDF_IS_STATUS_ERROR(status)) - mlme_legacy_err("unable to unregister psoc destroy handle"); - - status = wlan_objmgr_unregister_psoc_create_handler( - WLAN_UMAC_COMP_MLME, - mlme_psoc_object_created_notification, - NULL); - - if (status != QDF_STATUS_SUCCESS) - mlme_legacy_err("unable to unregister psoc create handle"); - return status; } @@ -155,13 +123,111 @@ QDF_STATUS ucfg_mlme_pdev_close(struct wlan_objmgr_pdev *pdev) return QDF_STATUS_SUCCESS; } +/** + * ucfg_mlme_convert_power_cfg_chan_to_freq() - converts channel numbers to + * frequencies and copies the triplets to power_freq_data array + * @pdev: pointer to pdev object + * @max_length: Max length of the power chan data array + * @length: length of the data present in power_chan_data array + * @power_chan_data: Power data array from which channel numbers needs to be + * converted to frequencies + * @power_freq_data: Power data array in which the power data needs to be copied + * after conversion of channel numbers to frequencies + * + * power_data is received in the form of (first_channel_number, + * number_of_channels, max_tx_power) triplet, convert the channel numbers from + * the power_chan_data array to frequencies and copy the triplets + * (first_frequency, number_of_channels, max_tx_power) values to + * the power_freq_data array + * + * Return: Number of bytes filled in power_freq_data + */ + +static uint32_t ucfg_mlme_convert_power_cfg_chan_to_freq( + struct wlan_objmgr_pdev *pdev, + uint32_t max_length, + qdf_size_t length, + uint8_t *power_chan_data, + uint8_t *power_freq_data) +{ + uint32_t count = 0, rem_length = length, copied_length = 0, i = 0; + tSirMacChanInfo *pwr_cfg_data; + + pwr_cfg_data = qdf_mem_malloc(max_length); + if (!pwr_cfg_data) + return 0; + + mlme_legacy_debug("max_length %d length %zu", max_length, length); + while ((rem_length >= 3) && + (copied_length <= (max_length - (sizeof(tSirMacChanInfo))))) { + pwr_cfg_data[i].first_freq = wlan_reg_chan_to_freq( + pdev, + power_chan_data[count++]); + pwr_cfg_data[i].numChannels = power_chan_data[count++]; + pwr_cfg_data[i].maxTxPower = power_chan_data[count++]; + copied_length += sizeof(tSirMacChanInfo); + rem_length -= 3; + mlme_legacy_debug("First freq %d num channels %d max tx power %d", + pwr_cfg_data[i].first_freq, + pwr_cfg_data[i].numChannels, + pwr_cfg_data[i].maxTxPower); + i++; + } + + qdf_mem_zero(power_freq_data, max_length); + qdf_mem_copy(power_freq_data, pwr_cfg_data, copied_length); + qdf_mem_free(pwr_cfg_data); + return copied_length; +} + +void ucfg_mlme_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + struct wlan_mlme_psoc_ext_obj *mlme_obj; + struct wlan_mlme_cfg *mlme_cfg; + uint32_t converted_data_len = 0; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return; + + mlme_cfg = &mlme_obj->cfg; + + mlme_cfg->power.max_tx_power_24.max_len = CFG_MAX_TX_POWER_2_4_LEN; + converted_data_len = ucfg_mlme_convert_power_cfg_chan_to_freq( + pdev, + mlme_cfg->power.max_tx_power_24_chan.max_len, + mlme_cfg->power.max_tx_power_24_chan.len, + mlme_cfg->power.max_tx_power_24_chan.data, + mlme_cfg->power.max_tx_power_24.data); + if (!converted_data_len) { + mlme_legacy_err("mlme cfg power 2_4 data chan number to freq failed"); + return; + } + + mlme_cfg->power.max_tx_power_24.len = converted_data_len; + + mlme_cfg->power.max_tx_power_5.max_len = CFG_MAX_TX_POWER_5_LEN; + converted_data_len = ucfg_mlme_convert_power_cfg_chan_to_freq( + pdev, + mlme_cfg->power.max_tx_power_5_chan.max_len, + mlme_cfg->power.max_tx_power_5_chan.len, + mlme_cfg->power.max_tx_power_5_chan.data, + mlme_cfg->power.max_tx_power_5.data); + if (!converted_data_len) { + mlme_legacy_err("mlme cfg power 5 data chan number to freq failed"); + return; + } + mlme_cfg->power.max_tx_power_5.len = converted_data_len; +} + QDF_STATUS ucfg_mlme_get_sta_keep_alive_period(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_INFRA_STA_KEEP_ALIVE_PERIOD); return QDF_STATUS_E_INVAL; @@ -176,9 +242,9 @@ QDF_STATUS ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_ENABLE_DFS_MASTER_CAPABILITY); return QDF_STATUS_E_INVAL; @@ -189,13 +255,31 @@ ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_oem_6g_supported(struct wlan_objmgr_psoc *psoc, + bool *oem_6g_disable) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *oem_6g_disable = + cfg_default(CFG_OEM_SIXG_SUPPORT_DISABLE); + return QDF_STATUS_E_INVAL; + } + + *oem_6g_disable = mlme_obj->cfg.wifi_pos_cfg.oem_6g_support_disable; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_get_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, uint32_t *fine_time_meas_cap) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *fine_time_meas_cap = cfg_default(CFG_FINE_TIME_MEAS_CAPABILITY); @@ -211,9 +295,9 @@ QDF_STATUS ucfg_mlme_set_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, uint32_t fine_time_meas_cap) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -226,9 +310,9 @@ QDF_STATUS ucfg_mlme_get_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, bool *dfs_disable_channel_switch) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *dfs_disable_channel_switch = cfg_default(CFG_DISABLE_DFS_CH_SWITCH); @@ -245,9 +329,9 @@ QDF_STATUS ucfg_mlme_set_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, bool dfs_disable_channel_switch) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { return QDF_STATUS_E_INVAL; } @@ -262,9 +346,9 @@ QDF_STATUS ucfg_mlme_get_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, bool *dfs_ignore_cac) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *dfs_ignore_cac = cfg_default(CFG_IGNORE_CAC); return QDF_STATUS_E_INVAL; @@ -279,9 +363,9 @@ QDF_STATUS ucfg_mlme_set_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, bool dfs_ignore_cac) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -294,9 +378,9 @@ QDF_STATUS ucfg_mlme_get_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, uint32_t *sap_tx_leakage_threshold) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *sap_tx_leakage_threshold = cfg_default(CFG_SAP_TX_LEAKAGE_THRESHOLD); @@ -313,9 +397,9 @@ QDF_STATUS ucfg_mlme_set_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, uint32_t sap_tx_leakage_threshold) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -325,13 +409,48 @@ ucfg_mlme_set_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_dfs_pri_multiplier(struct wlan_objmgr_psoc *psoc, + uint32_t *dfs_pri_multiplier) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *dfs_pri_multiplier = + cfg_default(CFG_DFS_RADAR_PRI_MULTIPLIER); + return QDF_STATUS_E_INVAL; + } + + *dfs_pri_multiplier = + mlme_obj->cfg.dfs_cfg.dfs_pri_multiplier; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_dfs_pri_multiplier(struct wlan_objmgr_psoc *psoc, + uint32_t dfs_pri_multiplier) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.dfs_cfg.dfs_pri_multiplier = + dfs_pri_multiplier; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_get_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, bool *dfs_filter_offload) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *dfs_filter_offload = cfg_default(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD); @@ -347,9 +466,9 @@ QDF_STATUS ucfg_mlme_set_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, bool dfs_filter_offload) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -362,9 +481,9 @@ QDF_STATUS ucfg_mlme_get_pmkid_modes(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_PMKID_MODES); return QDF_STATUS_E_INVAL; @@ -379,9 +498,9 @@ QDF_STATUS ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc, uint32_t val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -394,9 +513,9 @@ QDF_STATUS ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_TWT_REQUESTOR); return QDF_STATUS_E_INVAL; @@ -411,9 +530,9 @@ QDF_STATUS ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -426,9 +545,9 @@ QDF_STATUS ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_TWT_RESPONDER); return QDF_STATUS_E_INVAL; @@ -443,9 +562,9 @@ QDF_STATUS ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -458,9 +577,9 @@ QDF_STATUS ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_BCAST_TWT); return QDF_STATUS_E_INVAL; @@ -475,9 +594,9 @@ QDF_STATUS ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -490,9 +609,9 @@ QDF_STATUS ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_TWT_CONGESTION_TIMEOUT); return QDF_STATUS_E_INVAL; @@ -507,9 +626,9 @@ QDF_STATUS ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc, uint32_t val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -522,9 +641,9 @@ QDF_STATUS ucfg_mlme_get_enable_twt(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_ENABLE_TWT); return QDF_STATUS_E_INVAL; @@ -539,9 +658,9 @@ QDF_STATUS ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -554,9 +673,9 @@ QDF_STATUS ucfg_mlme_get_dot11p_mode(struct wlan_objmgr_psoc *psoc, enum dot11p_mode *out_mode) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *out_mode = cfg_default(CFG_DOT11P_MODE); return QDF_STATUS_E_INVAL; @@ -571,9 +690,9 @@ QDF_STATUS ucfg_mlme_get_go_cts2self_for_sta(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_ENABLE_GO_CTS2SELF_FOR_STA); return QDF_STATUS_E_INVAL; @@ -584,30 +703,13 @@ ucfg_mlme_get_go_cts2self_for_sta(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -QDF_STATUS -ucfg_mlme_get_force_rsne_override(struct wlan_objmgr_psoc *psoc, - bool *val) -{ - struct wlan_mlme_psoc_obj *mlme_obj; - - mlme_obj = mlme_get_psoc_obj(psoc); - if (!mlme_obj) { - *val = cfg_default(CFG_FORCE_RSNE_OVERRIDE); - return QDF_STATUS_E_INVAL; - } - - *val = mlme_obj->cfg.sta.force_rsne_override; - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS ucfg_mlme_get_qcn_ie_support(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_QCN_IE_SUPPORT); return QDF_STATUS_E_INVAL; @@ -622,9 +724,9 @@ QDF_STATUS ucfg_mlme_get_tgt_gtx_usr_cfg(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_TGT_GTX_USR_CFG); return QDF_STATUS_E_INVAL; @@ -638,9 +740,9 @@ ucfg_mlme_get_tgt_gtx_usr_cfg(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_is_override_ht20_40_24g(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_OBSS_HT40_OVERRIDE_HT40_20_24GHZ); return QDF_STATUS_E_INVAL; @@ -651,12 +753,13 @@ ucfg_mlme_is_override_ht20_40_24g(struct wlan_objmgr_psoc *psoc, bool *val) } #ifdef WLAN_FEATURE_ROAM_OFFLOAD -QDF_STATUS ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, - uint32_t *val) +QDF_STATUS +ucfg_mlme_get_roam_disable_config(struct wlan_objmgr_psoc *psoc, + uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_STA_DISABLE_ROAM); return QDF_STATUS_E_INVAL; @@ -671,9 +774,9 @@ QDF_STATUS ucfg_mlme_get_roaming_offload(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR3_ROAMING_OFFLOAD); return QDF_STATUS_E_INVAL; @@ -688,9 +791,9 @@ QDF_STATUS ucfg_mlme_set_roaming_offload(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -704,9 +807,9 @@ QDF_STATUS ucfg_mlme_get_first_scan_bucket_threshold(struct wlan_objmgr_psoc *psoc, uint8_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_FIRST_SCAN_BUCKET_THRESHOLD); return QDF_STATUS_E_INVAL; @@ -720,9 +823,9 @@ ucfg_mlme_get_first_scan_bucket_threshold(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_is_mawc_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_MAWC_FEATURE_ENABLED); return QDF_STATUS_E_INVAL; @@ -735,9 +838,9 @@ ucfg_mlme_is_mawc_enabled(struct wlan_objmgr_psoc *psoc, bool *val) QDF_STATUS ucfg_mlme_set_mawc_enabled(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -750,9 +853,9 @@ QDF_STATUS ucfg_mlme_is_fast_transition_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_FAST_TRANSITION_ENABLED); return QDF_STATUS_E_INVAL; @@ -767,9 +870,9 @@ QDF_STATUS ucfg_mlme_set_fast_transition_enabled(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -783,9 +886,9 @@ QDF_STATUS ucfg_mlme_set_tgt_adaptive_11r_cap(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -799,9 +902,9 @@ QDF_STATUS ucfg_mlme_is_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED); return QDF_STATUS_E_INVAL; @@ -816,9 +919,9 @@ QDF_STATUS ucfg_mlme_set_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -831,9 +934,9 @@ QDF_STATUS ucfg_mlme_get_neighbor_scan_max_chan_time(struct wlan_objmgr_psoc *psoc, uint16_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_NEIGHBOR_SCAN_MAX_CHAN_TIME); return QDF_STATUS_E_INVAL; @@ -848,9 +951,9 @@ QDF_STATUS ucfg_mlme_get_neighbor_scan_min_chan_time(struct wlan_objmgr_psoc *psoc, uint16_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_NEIGHBOR_SCAN_MIN_CHAN_TIME); return QDF_STATUS_E_INVAL; @@ -865,9 +968,9 @@ QDF_STATUS ucfg_mlme_get_delay_before_vdev_stop(struct wlan_objmgr_psoc *psoc, uint8_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_DELAY_BEFORE_VDEV_STOP); return QDF_STATUS_E_INVAL; @@ -882,9 +985,9 @@ QDF_STATUS ucfg_mlme_get_roam_bmiss_final_bcnt(struct wlan_objmgr_psoc *psoc, uint8_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ROAM_BMISS_FINAL_BCNT); return QDF_STATUS_E_INVAL; @@ -899,9 +1002,9 @@ QDF_STATUS ucfg_mlme_get_roam_bmiss_first_bcnt(struct wlan_objmgr_psoc *psoc, uint8_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ROAM_BMISS_FIRST_BCNT); return QDF_STATUS_E_INVAL; @@ -915,9 +1018,9 @@ ucfg_mlme_get_roam_bmiss_first_bcnt(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_is_lfr_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_FEATURE_ENABLED); return QDF_STATUS_E_INVAL; @@ -931,9 +1034,9 @@ ucfg_mlme_is_lfr_enabled(struct wlan_objmgr_psoc *psoc, bool *val) QDF_STATUS ucfg_mlme_set_lfr_enabled(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -945,9 +1048,9 @@ ucfg_mlme_set_lfr_enabled(struct wlan_objmgr_psoc *psoc, bool val) QDF_STATUS ucfg_mlme_is_roam_prefer_5ghz(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ROAM_PREFER_5GHZ); return QDF_STATUS_E_INVAL; @@ -961,9 +1064,9 @@ ucfg_mlme_is_roam_prefer_5ghz(struct wlan_objmgr_psoc *psoc, bool *val) QDF_STATUS ucfg_mlme_set_roam_intra_band(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -975,9 +1078,9 @@ ucfg_mlme_set_roam_intra_band(struct wlan_objmgr_psoc *psoc, bool val) QDF_STATUS ucfg_mlme_get_home_away_time(struct wlan_objmgr_psoc *psoc, uint16_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ROAM_SCAN_HOME_AWAY_TIME); return QDF_STATUS_E_INVAL; @@ -992,9 +1095,9 @@ QDF_STATUS ucfg_mlme_set_fast_roam_in_concurrency_enabled(struct wlan_objmgr_psoc *psoc, bool val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1007,9 +1110,9 @@ ucfg_mlme_set_fast_roam_in_concurrency_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_is_ese_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR_ESE_FEATURE_ENABLED); return QDF_STATUS_E_INVAL; @@ -1025,9 +1128,9 @@ QDF_STATUS ucfg_mlme_get_opr_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf, qdf_size_t *len) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1039,9 +1142,9 @@ QDF_STATUS ucfg_mlme_get_ext_opr_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf, qdf_size_t *len) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1053,9 +1156,9 @@ QDF_STATUS ucfg_mlme_get_supported_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf, qdf_size_t *len) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1068,9 +1171,9 @@ QDF_STATUS ucfg_mlme_set_supported_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf, qdf_size_t len) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1083,9 +1186,9 @@ QDF_STATUS ucfg_mlme_get_current_mcs_set(struct wlan_objmgr_psoc *psoc, uint8_t *buf, qdf_size_t *len) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1098,9 +1201,9 @@ QDF_STATUS ucfg_mlme_get_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, uint32_t *wmi_wq_watchdog_timeout) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *wmi_wq_watchdog_timeout = cfg_default(CFG_WMI_WQ_WATCHDOG); return QDF_STATUS_E_INVAL; @@ -1116,9 +1219,9 @@ QDF_STATUS ucfg_mlme_set_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, uint32_t wmi_wq_watchdog_timeout) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1138,9 +1241,9 @@ QDF_STATUS ucfg_mlme_stats_get_periodic_display_time(struct wlan_objmgr_psoc *psoc, uint32_t *periodic_display_time) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *periodic_display_time = cfg_default(CFG_PERIODIC_STATS_DISPLAY_TIME); @@ -1160,9 +1263,9 @@ ucfg_mlme_stats_get_cfg_values(struct wlan_objmgr_psoc *psoc, int *link_speed_rssi_low, uint32_t *link_speed_rssi_report) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *link_speed_rssi_high = cfg_default(CFG_LINK_SPEED_RSSI_HIGH); @@ -1189,10 +1292,10 @@ ucfg_mlme_stats_get_cfg_values(struct wlan_objmgr_psoc *psoc, bool ucfg_mlme_stats_is_link_speed_report_actual(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; int report_link_speed = 0; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) report_link_speed = cfg_default(CFG_REPORT_MAX_LINK_SPEED); else @@ -1204,10 +1307,10 @@ bool ucfg_mlme_stats_is_link_speed_report_actual(struct wlan_objmgr_psoc *psoc) bool ucfg_mlme_stats_is_link_speed_report_max(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; int report_link_speed = 0; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) report_link_speed = cfg_default(CFG_REPORT_MAX_LINK_SPEED); else @@ -1220,10 +1323,10 @@ bool ucfg_mlme_stats_is_link_speed_report_max(struct wlan_objmgr_psoc *psoc) bool ucfg_mlme_stats_is_link_speed_report_max_scaled(struct wlan_objmgr_psoc *psoc) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; int report_link_speed = 0; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) report_link_speed = cfg_default(CFG_REPORT_MAX_LINK_SPEED); else @@ -1237,9 +1340,9 @@ QDF_STATUS ucfg_mlme_get_ps_data_inactivity_timeout(struct wlan_objmgr_psoc *psoc, uint32_t *inactivity_timeout) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *inactivity_timeout = cfg_default(CFG_PS_DATA_INACTIVITY_TIMEOUT); @@ -1254,9 +1357,9 @@ QDF_STATUS ucfg_mlme_set_ps_data_inactivity_timeout(struct wlan_objmgr_psoc *psoc, uint32_t inactivity_timeout) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1274,9 +1377,9 @@ QDF_STATUS ucfg_mlme_get_sta_keepalive_method(struct wlan_objmgr_psoc *psoc, enum station_keepalive_method *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1288,9 +1391,9 @@ QDF_STATUS ucfg_mlme_get_enable_deauth_to_disassoc_map(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1303,9 +1406,9 @@ QDF_STATUS ucfg_mlme_get_ap_random_bssid_enable(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1316,9 +1419,9 @@ ucfg_mlme_get_ap_random_bssid_enable(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_get_latency_enable(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { mlme_legacy_err("mlme obj null"); return QDF_STATUS_E_INVAL; @@ -1331,12 +1434,12 @@ ucfg_mlme_get_latency_enable(struct wlan_objmgr_psoc *psoc, bool *value) QDF_STATUS ucfg_mlme_get_ibss_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_ibss_cfg *ibss_cfg) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; if (!ibss_cfg) return QDF_STATUS_E_FAILURE; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { mlme_legacy_err("MLME Obj null on get IBSS config"); mlme_init_ibss_cfg(psoc, ibss_cfg); @@ -1349,9 +1452,9 @@ QDF_STATUS ucfg_mlme_get_ibss_cfg(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_set_ibss_auto_bssid(struct wlan_objmgr_psoc *psoc, uint32_t auto_bssid) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { mlme_legacy_err("MLME Obj null on get IBSS config"); return QDF_STATUS_E_INVAL; @@ -1365,9 +1468,9 @@ QDF_STATUS ucfg_mlme_get_mws_coex_4g_quick_tdm(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_MWS_COEX_4G_QUICK_FTDM); mlme_legacy_err("mlme obj null"); @@ -1383,9 +1486,9 @@ QDF_STATUS ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_MWS_COEX_5G_NR_PWR_LIMIT); mlme_legacy_err("mlme obj null"); @@ -1401,9 +1504,9 @@ QDF_STATUS ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_MWS_COEX_PCC_CHANNEL_AVOID_DELAY); mlme_legacy_err("mlme obj null"); @@ -1419,9 +1522,9 @@ QDF_STATUS ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_MWS_COEX_SCC_CHANNEL_AVOID_DELAY); mlme_legacy_err("mlme obj null"); @@ -1435,32 +1538,40 @@ ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(struct wlan_objmgr_psoc *psoc, #endif QDF_STATUS -ucfg_mlme_get_etsi13_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, - bool *value) +ucfg_mlme_get_etsi_srd_chan_in_master_mode(struct wlan_objmgr_psoc *psoc, + uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { - *value = cfg_default(CFG_ETSI13_SRD_CHAN_IN_MASTER_MODE); + *value = cfg_default(CFG_ETSI_SRD_CHAN_IN_MASTER_MODE); mlme_legacy_err("Failed to get MLME Obj"); return QDF_STATUS_E_INVAL; } - *value = mlme_obj->cfg.reg.etsi13_srd_chan_in_master_mode; + *value = mlme_obj->cfg.reg.etsi_srd_chan_in_master_mode; return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_srd_master_mode_for_vdev(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE vdev_opmode, + bool *value) +{ + return wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode, value); +} + #ifdef SAP_AVOID_ACS_FREQ_LIST QDF_STATUS ucfg_mlme_get_acs_avoid_freq_list(struct wlan_objmgr_psoc *psoc, uint16_t *freq_list, uint8_t *freq_list_num) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; qdf_size_t avoid_acs_freq_list_num; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { qdf_uint16_array_parse( cfg_default(CFG_SAP_AVOID_ACS_FREQ_LIST), @@ -1484,9 +1595,9 @@ QDF_STATUS ucfg_mlme_get_11d_in_world_mode(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_ENABLE_11D_IN_WORLD_MODE); mlme_legacy_err("Failed to get MLME Obj"); @@ -1502,9 +1613,9 @@ QDF_STATUS ucfg_mlme_get_restart_beaconing_on_ch_avoid(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_RESTART_BEACONING_ON_CH_AVOID); mlme_legacy_err("Failed to get MLME Obj"); @@ -1520,9 +1631,9 @@ QDF_STATUS ucfg_mlme_get_indoor_channel_support(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_INDOOR_CHANNEL_SUPPORT); mlme_legacy_err("Failed to get MLME Obj"); @@ -1538,9 +1649,9 @@ QDF_STATUS ucfg_mlme_get_scan_11d_interval(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_SCAN_11D_INTERVAL); mlme_legacy_err("Failed to get MLME Obj"); @@ -1552,27 +1663,59 @@ ucfg_mlme_get_scan_11d_interval(struct wlan_objmgr_psoc *psoc, } QDF_STATUS -ucfg_mlme_get_valid_channel_list(struct wlan_objmgr_psoc *psoc, - uint8_t *channel_list, - uint32_t *channel_list_num) +ucfg_mlme_get_nol_across_regdmn(struct wlan_objmgr_psoc *psoc, bool *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + *value = cfg_default(CFG_RETAIN_NOL_ACROSS_REG_DOMAIN); + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_INVAL; + } + + *value = mlme_obj->cfg.reg.retain_nol_across_regdmn_update; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_valid_channel_freq_list(struct wlan_objmgr_psoc *psoc, + uint32_t *channel_list, + uint32_t *channel_list_num) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; qdf_size_t valid_channel_list_num = 0; + uint8_t tmp_channel_list[CFG_VALID_CHANNEL_LIST_LEN]; + uint8_t i; + struct wlan_objmgr_pdev *pdev = NULL; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { qdf_uint8_array_parse(cfg_default(CFG_VALID_CHANNEL_LIST), - channel_list, + tmp_channel_list, CFG_VALID_CHANNEL_LIST_LEN, &valid_channel_list_num); *channel_list_num = (uint8_t)valid_channel_list_num; mlme_legacy_err("Failed to get MLME Obj"); + pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_MLME_NB_ID); + if (!pdev) { + mlme_legacy_err("null pdev"); + return QDF_STATUS_E_INVAL; + } + + for (i = 0; i < valid_channel_list_num; i++) { + channel_list[i] = + wlan_reg_chan_to_freq(pdev, tmp_channel_list[i]); + } + + wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; } *channel_list_num = (uint32_t)mlme_obj->cfg.reg.valid_channel_list_num; - qdf_mem_copy(channel_list, mlme_obj->cfg.reg.valid_channel_list, - *channel_list_num); + for (i = 0; i < *channel_list_num; i++) + channel_list[i] = mlme_obj->cfg.reg.valid_channel_freq_list[i]; return QDF_STATUS_SUCCESS; } @@ -1581,9 +1724,9 @@ ucfg_mlme_get_valid_channel_list(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_is_subnet_detection_enabled(struct wlan_objmgr_psoc *psoc, bool *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_LFR3_ENABLE_SUBNET_DETECTION); return QDF_STATUS_E_INVAL; @@ -1598,9 +1741,9 @@ QDF_STATUS ucfg_mlme_set_current_tx_power_level(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1613,9 +1756,9 @@ QDF_STATUS ucfg_mlme_get_current_tx_power_level(struct wlan_objmgr_psoc *psoc, uint8_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_CURRENT_TX_POWER_LEVEL); return QDF_STATUS_E_INVAL; @@ -1630,9 +1773,9 @@ QDF_STATUS ucfg_mlme_set_obss_detection_offload_enabled(struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1641,13 +1784,28 @@ ucfg_mlme_set_obss_detection_offload_enabled(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_set_bss_color_collision_det_sta(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.obss_ht40.bss_color_collision_det_sta = value; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_set_obss_color_collision_offload_enabled( struct wlan_objmgr_psoc *psoc, uint8_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1656,13 +1814,40 @@ ucfg_mlme_set_obss_color_collision_offload_enabled( return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_mlme_set_restricted_80p80_bw_supp(struct wlan_objmgr_psoc *psoc, + bool restricted_80p80_supp) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.vht_caps.vht_cap_info.restricted_80p80_bw_supp = + restricted_80p80_supp; + + return QDF_STATUS_SUCCESS; +} + +bool ucfg_mlme_get_restricted_80p80_bw_supp(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + + if (!mlme_obj) + return true; + + return mlme_obj->cfg.vht_caps.vht_cap_info.restricted_80p80_bw_supp; +} + QDF_STATUS ucfg_mlme_get_channel_bonding_24ghz(struct wlan_objmgr_psoc *psoc, uint32_t *val) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *val = cfg_default(CFG_CHANNEL_BONDING_MODE_24GHZ); return QDF_STATUS_E_INVAL; @@ -1676,9 +1861,9 @@ QDF_STATUS ucfg_mlme_set_channel_bonding_24ghz(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1691,9 +1876,9 @@ QDF_STATUS ucfg_mlme_get_channel_bonding_5ghz(struct wlan_objmgr_psoc *psoc, uint32_t *value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) { *value = cfg_default(CFG_CHANNEL_BONDING_MODE_5GHZ); return QDF_STATUS_E_INVAL; @@ -1707,9 +1892,9 @@ QDF_STATUS ucfg_mlme_set_channel_bonding_5ghz(struct wlan_objmgr_psoc *psoc, uint32_t value) { - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_obj; - mlme_obj = mlme_get_psoc_obj(psoc); + mlme_obj = mlme_get_psoc_ext_obj(psoc); if (!mlme_obj) return QDF_STATUS_E_INVAL; @@ -1750,3 +1935,13 @@ bool ucfg_mlme_validate_scan_period(uint32_t roam_scan_period) return is_valid; } + +bool ucfg_is_roaming_enabled(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + if (mlme_get_roam_state(psoc, vdev_id) == ROAM_RSO_STARTED) + return true; + + return false; +} diff --git a/drivers/staging/qcacld-3.0/components/nan/core/inc/nan_public_structs.h b/drivers/staging/qcacld-3.0/components/nan/core/inc/nan_public_structs.h index 1938c9e4c9d747bdb42cc513fcf13c0021852888..e8e189cb31b47f63e62fde5a917b8464226c8244 100644 --- a/drivers/staging/qcacld-3.0/components/nan/core/inc/nan_public_structs.h +++ b/drivers/staging/qcacld-3.0/components/nan/core/inc/nan_public_structs.h @@ -531,6 +531,39 @@ struct nan_event_params { uint8_t buf[]; }; +#define NAN_MSG_ID_DISABLE_INDICATION 26 +/** + * struct nan_msg_hdr - NAN msg header to be sent to userspace + * @msg_version: NAN msg version + * @msg_id: NAN message id + * @reserved: Reserved for now to avoid padding + * + * 8-byte control message header used by NAN + * + */ +struct nan_msg_hdr { + uint16_t msg_version:4; + uint16_t msg_id:12; + uint16_t reserved[3]; +}; + +#define NAN_STATUS_SUCCESS 0 +#define NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED 12 + +/** + * struct nan_disable_ind_msg - NAN disable ind params + * @msg_hdr: NAN msg header + * @reason: NAN disable reason, below are valid reasons for NAN disable ind + * NAN_STATUS_SUCCESS + * NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED + * @reserved: Reserved for now to avoid padding + */ +struct nan_disable_ind_msg { + struct nan_msg_hdr msg_hdr; + uint16_t reason; + uint16_t reserved; +}; + /** * struct nan_msg_params - NAN request params * @request_data_len: request data length @@ -573,14 +606,14 @@ struct nan_disable_req { /** * struct nan_enable_req - NAN request to enable NAN Discovery * @psoc: Pointer to the psoc object - * @social_chan_2g: Social channel in 2G band for the NAN Discovery - * @social_chan_5g: Social channel in 5G band for the NAN Discovery + * @social_chan_2g_freq: Social channel in 2G band for the NAN Discovery + * @social_chan_5g_freq: Social channel in 5G band for the NAN Discovery * @params: NAN request structure containing message for the target */ struct nan_enable_req { struct wlan_objmgr_psoc *psoc; - uint8_t social_chan_2g; - uint8_t social_chan_5g; + uint32_t social_chan_2g_freq; + uint32_t social_chan_5g_freq; /* Variable length, do not add anything after this */ struct nan_msg_params params; }; @@ -806,6 +839,8 @@ struct wlan_nan_rx_ops { * @nan_sap_supported: Target supports NAN Discovery with SAP concurrency * @ndi_sap_supported: Target supports NAN Datapth with SAP concurrency * @nan_vdev_allowed: Allow separate vdev creation for NAN discovery + * @sta_nan_ndi_ndi_allowed: 4 port concurrency of STA+NAN+NDI+NDI is supported + * by Fw or not. */ struct nan_tgt_caps { uint32_t nan_disable_supported:1; @@ -814,6 +849,7 @@ struct nan_tgt_caps { uint32_t nan_sap_supported:1; uint32_t ndi_sap_supported:1; uint32_t nan_vdev_allowed:1; + uint32_t sta_nan_ndi_ndi_allowed:1; }; #endif diff --git a/drivers/staging/qcacld-3.0/components/nan/core/inc/wlan_nan_api.h b/drivers/staging/qcacld-3.0/components/nan/core/inc/wlan_nan_api.h index d87b938b366d4575009ff273a53595ebd242d532..9cba0fffd401aac67fd9be08aaabf5a6fe427c5f 100644 --- a/drivers/staging/qcacld-3.0/components/nan/core/inc/wlan_nan_api.h +++ b/drivers/staging/qcacld-3.0/components/nan/core/inc/wlan_nan_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -185,12 +185,12 @@ wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc, struct policy_mgr_vdev_entry_info *conn_info); /** - * wlan_nan_get_disc_5g_ch: Get NAN Disc 5G channel + * wlan_nan_get_disc_5g_ch_freq: Get NAN Disc 5G channel frequency * @psoc: pointer to psoc object * - * Return: NAN Disc 5G channel + * Return: NAN Disc 5G channel frequency */ -uint8_t wlan_nan_get_disc_5g_ch(struct wlan_objmgr_psoc *psoc); +uint32_t wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc *psoc); /** * wlan_nan_get_sap_conc_support: Get NAN+SAP conc support @@ -200,6 +200,25 @@ uint8_t wlan_nan_get_disc_5g_ch(struct wlan_objmgr_psoc *psoc); */ bool wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc *psoc); +/** + * nan_disable_cleanup: Cleanup NAN state upon NAN disable + * @psoc: pointer to psoc object + * + * Return: Cleanup NAN state upon NAN disable + */ +QDF_STATUS nan_disable_cleanup(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_is_nan_allowed_on_freq() - Check if NAN is allowed on given freq + * @pdev: pdev context + * @freq: Frequency to be checked + * + * Check if NAN/NDP can be enabled on given frequency. + * + * Return: True if NAN is allowed on the given frequency + */ +bool wlan_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq); + #else /* WLAN_FEATURE_NAN */ static inline QDF_STATUS nan_init(void) { @@ -228,7 +247,8 @@ wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } -static inline uint8_t wlan_nan_get_disc_5g_ch(struct wlan_objmgr_psoc *psoc) +static inline uint32_t +wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc *psoc) { return 0; } @@ -238,5 +258,17 @@ bool wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc *psoc) { return false; } + +static inline +QDF_STATUS nan_disable_cleanup(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline +bool wlan_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq) +{ + return false; +} #endif /* WLAN_FEATURE_NAN */ #endif /* _WLAN_NAN_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_api.c b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_api.c index 96f480184698c7214e3d9c518c71ed6b3b28692b..64c3bd3aaaf5a838a123e29a5d017d30343de424 100644 --- a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_api.c +++ b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,6 +29,8 @@ #include "wlan_objmgr_psoc_obj.h" #include "wlan_objmgr_pdev_obj.h" #include "wlan_objmgr_vdev_obj.h" +#include "nan_ucfg_api.h" +#include static QDF_STATUS nan_psoc_obj_created_notification( struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -94,8 +96,18 @@ static QDF_STATUS nan_vdev_obj_created_notification( { struct nan_vdev_priv_obj *nan_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_psoc *psoc; nan_debug("nan_vdev_create_notif called"); + if (ucfg_is_nan_vdev(vdev)) { + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + nan_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + target_if_nan_set_vdev_feature_config(psoc, + wlan_vdev_get_id(vdev)); + } if (wlan_vdev_mlme_get_opmode(vdev) != QDF_NDI_MODE) { nan_debug("not a ndi vdev. do nothing"); return QDF_STATUS_SUCCESS; @@ -403,3 +415,24 @@ QDF_STATUS nan_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } + +bool wlan_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq) +{ + bool nan_allowed = true; + + /* Check for SRD channels */ + if (wlan_reg_is_etsi13_srd_chan_for_freq(pdev, freq)) + wlan_mlme_get_srd_master_mode_for_vdev(wlan_pdev_get_psoc(pdev), + QDF_NAN_DISC_MODE, + &nan_allowed); + + /* Check for Indoor channels */ + if (wlan_reg_is_freq_indoor(pdev, freq)) + wlan_mlme_get_indoor_support_for_nan(wlan_pdev_get_psoc(pdev), + &nan_allowed); + /* Check for dfs only if channel is not indoor */ + else if (wlan_reg_is_dfs_for_freq(pdev, freq)) + nan_allowed = false; + + return nan_allowed; +} diff --git a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main.c b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main.c index 61e6e47249afb03b971262e6a87627de279a10b5..e58de1fe1610fc3d642216fee36e7e8ca6d7b781 100644 --- a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main.c +++ b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -352,9 +353,9 @@ nan_increment_ndp_sessions(struct wlan_objmgr_psoc *psoc, sizeof(struct nan_datapath_channel_info)); peer_nan_obj->active_ndp_sessions++; - nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_STR"", + nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT"", peer_nan_obj->active_ndp_sessions, - QDF_MAC_ADDR_ARRAY(peer_ndi_mac->bytes)); + QDF_MAC_ADDR_REF(peer_ndi_mac->bytes)); qdf_spin_unlock_bh(&peer_nan_obj->lock); wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID); @@ -391,9 +392,9 @@ static QDF_STATUS nan_decrement_ndp_sessions(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } peer_nan_obj->active_ndp_sessions--; - nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_STR"", + nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT"", peer_nan_obj->active_ndp_sessions, - QDF_MAC_ADDR_ARRAY(peer_ndi_mac->bytes)); + QDF_MAC_ADDR_REF(peer_ndi_mac->bytes)); qdf_spin_unlock_bh(&peer_nan_obj->lock); wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID); @@ -434,8 +435,8 @@ ndi_remove_and_update_primary_connection(struct wlan_objmgr_psoc *psoc, while (peer) { peer_nan_obj = nan_get_peer_priv_obj(peer); if (!peer_nan_obj) - nan_err("NAN peer object for Peer " QDF_MAC_ADDR_STR " is NULL", - QDF_MAC_ADDR_ARRAY(wlan_peer_get_macaddr(peer))); + nan_err("NAN peer object for Peer " QDF_MAC_ADDR_FMT " is NULL", + QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer))); else if (peer_nan_obj->active_ndp_sessions) break; @@ -530,6 +531,7 @@ static QDF_STATUS nan_handle_confirm( struct wlan_objmgr_psoc *psoc; struct nan_psoc_priv_obj *psoc_nan_obj; struct nan_vdev_priv_obj *vdev_nan_obj; + struct wlan_objmgr_peer *peer; QDF_STATUS status; vdev_id = wlan_vdev_get_id(confirm->vdev); @@ -539,6 +541,17 @@ static QDF_STATUS nan_handle_confirm( return QDF_STATUS_E_NULL_VALUE; } + peer = wlan_objmgr_get_peer_by_mac(psoc, + confirm->peer_ndi_mac_addr.bytes, + WLAN_NAN_ID); + if (!peer && confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) { + nan_debug("Drop NDP confirm as peer isn't available"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (peer) + wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID); + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); if (!psoc_nan_obj) { nan_err("psoc_nan_obj is null"); @@ -557,8 +570,8 @@ static QDF_STATUS nan_handle_confirm( * This peer was created at ndp_indication but * confirm failed, so it needs to be deleted */ - nan_err("NDP confirm with reject and no active ndp sessions. deleting peer: "QDF_MAC_ADDR_STR" on vdev_id: %d", - QDF_MAC_ADDR_ARRAY(confirm->peer_ndi_mac_addr.bytes), + nan_err("NDP confirm with reject and no active ndp sessions. deleting peer: "QDF_MAC_ADDR_FMT" on vdev_id: %d", + QDF_MAC_ADDR_REF(confirm->peer_ndi_mac_addr.bytes), vdev_id); psoc_nan_obj->cb_obj.delete_peers_by_addr(vdev_id, confirm->peer_ndi_mac_addr); @@ -593,9 +606,9 @@ static QDF_STATUS nan_handle_confirm( return status; } - status = policy_mgr_current_connections_update(psoc, - vdev_id, channel, - POLICY_MGR_UPDATE_REASON_NDP_UPDATE); + status = policy_mgr_current_connections_update( + psoc, vdev_id, wlan_chan_to_freq(channel), + POLICY_MGR_UPDATE_REASON_NDP_UPDATE); if (QDF_STATUS_E_FAILURE == status) { nan_err("connections update failed!!"); return status; @@ -667,9 +680,9 @@ static QDF_STATUS nan_handle_ndp_ind( } nan_debug("role: %d, vdev: %d, csid: %d, peer_mac_addr " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, ndp_ind->role, vdev_id, ndp_ind->ncs_sk_type, - QDF_MAC_ADDR_ARRAY(ndp_ind->peer_mac_addr.bytes)); + QDF_MAC_ADDR_REF(ndp_ind->peer_mac_addr.bytes)); if ((ndp_ind->role == NAN_DATAPATH_ROLE_INITIATOR) || ((NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role) && @@ -812,9 +825,6 @@ static QDF_STATUS nan_handle_end_ind( wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID); } - policy_mgr_decr_active_session(psoc, QDF_NDI_MODE, - wlan_vdev_get_id(ind->vdev)); - psoc_nan_obj->cb_obj.ndp_delete_peers(ind->ndp_map, ind->num_ndp_ids); psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev, NDP_END_IND, ind); @@ -866,8 +876,8 @@ static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *nan_event) * State set to DISABLED OR DISABLE_IN_PROGRESS, try to * restore the single MAC mode. */ - psoc_nan_obj->nan_social_ch_2g = 0; - psoc_nan_obj->nan_social_ch_5g = 0; + psoc_nan_obj->nan_social_ch_2g_freq = 0; + psoc_nan_obj->nan_social_ch_5g_freq = 0; policy_mgr_check_n_start_opportunistic_timer(psoc); } goto done; @@ -877,10 +887,11 @@ static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *nan_event) goto fail; } fail: - psoc_nan_obj->nan_social_ch_2g = 0; - psoc_nan_obj->nan_social_ch_5g = 0; + psoc_nan_obj->nan_social_ch_2g_freq = 0; + psoc_nan_obj->nan_social_ch_5g_freq = 0; nan_set_discovery_state(psoc, NAN_DISC_DISABLED); policy_mgr_check_n_start_opportunistic_timer(psoc); + done: call_back = psoc_nan_obj->cb_obj.ucfg_nan_request_process_cb; if (call_back) @@ -889,14 +900,17 @@ static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *nan_event) return QDF_STATUS_SUCCESS; } -static QDF_STATUS nan_handle_disable_ind(struct nan_event_params *nan_event) +QDF_STATUS nan_disable_cleanup(struct wlan_objmgr_psoc *psoc) { struct nan_psoc_priv_obj *psoc_nan_obj; - struct wlan_objmgr_psoc *psoc; QDF_STATUS status; uint8_t vdev_id; - psoc = nan_event->psoc; + if (!psoc) { + nan_err("psoc is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); if (!psoc_nan_obj) { nan_err("psoc_nan_obj is NULL"); @@ -926,6 +940,11 @@ static QDF_STATUS nan_handle_disable_ind(struct nan_event_params *nan_event) return status; } +static QDF_STATUS nan_handle_disable_ind(struct nan_event_params *nan_event) +{ + return nan_disable_cleanup(nan_event->psoc); +} + static QDF_STATUS nan_handle_schedule_update( struct nan_datapath_sch_update_event *ind) { @@ -1084,7 +1103,7 @@ QDF_STATUS nan_datapath_event_handler(struct scheduler_msg *pe_msg) return status; } -bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint8_t nan_chan) +bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq) { if (!psoc) { nan_err("psoc object object is NULL"); @@ -1092,8 +1111,8 @@ bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint8_t nan_chan) } return (NAN_DISC_DISABLED == nan_get_discovery_state(psoc) && - policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE, nan_chan, - HW_MODE_20_MHZ)); + policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE, + nan_ch_freq, HW_MODE_20_MHZ)); } bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc) @@ -1108,7 +1127,7 @@ bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc) } QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc, - uint8_t nan_social_channel) + uint32_t nan_ch_freq) { QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_objmgr_pdev *pdev = NULL; @@ -1140,7 +1159,7 @@ QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc, } if (!policy_mgr_nan_sap_pre_enable_conc_check(psoc, PM_NAN_DISC_MODE, - nan_social_channel)) { + nan_ch_freq)) { nan_debug("NAN not enabled due to concurrency constraints"); status = QDF_STATUS_E_INVAL; goto pre_enable_failure; @@ -1156,8 +1175,8 @@ QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc, vdev_id = wlan_vdev_get_id(vdev); wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID); - status = policy_mgr_update_and_wait_for_connection_update(psoc, vdev_id, - nan_social_channel, + status = policy_mgr_update_and_wait_for_connection_update(psoc, vdev_id, + nan_ch_freq, POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY); if (QDF_IS_STATUS_ERROR(status)) { nan_err("Failed to set or wait for HW mode change"); @@ -1229,8 +1248,8 @@ static QDF_STATUS nan_discovery_enable_req(struct nan_enable_req *req) return QDF_STATUS_E_NULL_VALUE; } - psoc_nan_obj->nan_social_ch_2g = req->social_chan_2g; - psoc_nan_obj->nan_social_ch_5g = req->social_chan_5g; + psoc_nan_obj->nan_social_ch_2g_freq = req->social_chan_2g_freq; + psoc_nan_obj->nan_social_ch_5g_freq = req->social_chan_5g_freq; tx_ops = &psoc_nan_obj->tx_ops; if (!tx_ops->nan_discovery_req_tx) { @@ -1342,7 +1361,7 @@ wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc, } /* For policy_mgr use NAN mandatory Social ch 6 */ - conn_info->mhz = wlan_chan_to_freq(psoc_nan_obj->nan_social_ch_2g); + conn_info->mhz = psoc_nan_obj->nan_social_ch_2g_freq; conn_info->mac_id = psoc_nan_obj->nan_disc_mac_id; conn_info->chan_width = CH_WIDTH_20MHZ; conn_info->type = WMI_VDEV_TYPE_NAN; @@ -1350,7 +1369,7 @@ wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -uint8_t wlan_nan_get_disc_5g_ch(struct wlan_objmgr_psoc *psoc) +uint32_t wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc *psoc) { struct nan_psoc_priv_obj *psoc_nan_obj; @@ -1363,7 +1382,7 @@ uint8_t wlan_nan_get_disc_5g_ch(struct wlan_objmgr_psoc *psoc) if (nan_get_discovery_state(psoc) != NAN_DISC_ENABLED) return 0; - return psoc_nan_obj->nan_social_ch_5g; + return psoc_nan_obj->nan_social_ch_5g_freq; } bool wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc *psoc) diff --git a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main_i.h b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main_i.h index 88ee1745e50ebec25bac9aee1119e7d66c9d2479..2053d1549e13675d4f3c99263a31da025d842587 100644 --- a/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main_i.h +++ b/drivers/staging/qcacld-3.0/components/nan/core/src/nan_main_i.h @@ -83,7 +83,11 @@ enum nan_disc_state { * wait to kickout peer if peer is not reachable * @support_mp0_discovery: To support discovery of NAN cluster with Master * Preference (MP) as 0 when a new device is enabling NAN + * @max_ndp_sessions: max ndp sessions host supports * @max_ndi: max number of ndi host supports + * @nan_feature_config: Bitmap to enable/disable a particular NAN feature + * configuration in firmware. It's sent to firmware through + * WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES */ struct nan_cfg_params { bool enable; @@ -93,7 +97,9 @@ struct nan_cfg_params { bool nan_separate_iface_support; uint16_t ndp_keep_alive_period; bool support_mp0_discovery; + uint32_t max_ndp_sessions; uint32_t max_ndi; + uint32_t nan_feature_config; }; /** @@ -105,8 +111,8 @@ struct nan_cfg_params { * @tx_ops: Tx ops registered with Target IF interface * @rx_ops: Rx ops registered with Target IF interface * @disc_state: Present NAN Discovery state - * @nan_social_ch_2g: NAN 2G Social channel for discovery - * @nan_social_ch_5g: NAN 5G Social channel for discovery + * @nan_social_ch_2g_freq: NAN 2G Social channel for discovery + * @nan_social_ch_5g_freq: NAN 5G Social channel for discovery * @nan_disc_mac_id: MAC id used for NAN Discovery * @is_explicit_disable: Flag to indicate that NAN is being explicitly * disabled by driver or user-space @@ -120,8 +126,8 @@ struct nan_psoc_priv_obj { struct wlan_nan_tx_ops tx_ops; struct wlan_nan_rx_ops rx_ops; enum nan_disc_state disc_state; - uint8_t nan_social_ch_2g; - uint8_t nan_social_ch_5g; + uint32_t nan_social_ch_2g_freq; + uint32_t nan_social_ch_5g_freq; uint8_t nan_disc_mac_id; bool is_explicit_disable; void *request_context; @@ -230,12 +236,12 @@ QDF_STATUS nan_set_discovery_state(struct wlan_objmgr_psoc *psoc, /* * nan_discovery_pre_enable: Takes steps before sending NAN Enable to Firmware * @psoc: PSOC object - * @nan_social_channel: Primary social channel for NAN Discovery + * @nan_ch_freq: Primary social channel for NAN Discovery * * Return: status of operation */ QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc, - uint8_t nan_social_channel); + uint32_t nan_ch_freq); /* * nan_get_discovery_state: Returns the current NAN Discovery state @@ -248,11 +254,11 @@ enum nan_disc_state nan_get_discovery_state(struct wlan_objmgr_psoc *psoc); /* * nan_is_enable_allowed: Queries whether NAN Discovery is allowed * @psoc: PSOC object - * @nan_chan: Possible primary social channel for NAN Discovery + * @nan_ch_freq: Possible primary social channel for NAN Discovery * * Return: True if NAN Enable is allowed on given channel, False otherwise */ -bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint8_t nan_chan); +bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq); /* * nan_is_disc_active: Queries whether NAN Discovery is active diff --git a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan.h b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan.h index 732d596a21c3ddeda585b288488c2b6673d3520f..08396eb8b29f1dd9b813170708cd41ffbc00bcaa 100644 --- a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan.h +++ b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan.h @@ -149,7 +149,7 @@ * * @Min: 10 * @Max: 30 - * @Default: 20 + * @Default: 14 * * Related: None * @@ -164,10 +164,36 @@ "gNdpKeepAlivePeriod", \ 10, \ 30, \ - 20, \ + 14, \ CFG_VALUE_OR_DEFAULT, \ "Keep alive timeout of a peer") +/* + * + * ndp_max_sessions - To configure max ndp sessions + * supported by host. + * + * @Min: 1 + * @Max: 8 + * @Default: 8 + * + * Related: None + * + * Supported Feature: NAN + * + * Usage: Internal + * + * + */ + +#define CFG_NDP_MAX_SESSIONS CFG_INI_UINT( \ + "ndp_max_sessions", \ + 1, \ + 8, \ + 8, \ + CFG_VALUE_OR_DEFAULT, \ + "max ndp sessions host supports") + /* * * gSupportMp0Discovery - To support discovery of NAN cluster with @@ -213,6 +239,38 @@ CFG_VALUE_OR_DEFAULT, \ "Max number of NDI host supports") +/* + * + * nan_feature_config - Bitmap to enable/disable a particular NAN/NDP feature + * + * @Min: 0 + * @Max: 0xFFFF + * @Default: 0x1 + * + * This parameter helps to enable/disable a particular feature config by setting + * corresponding bit and send to firmware through the VDEV param + * WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES + * Acceptable values for this: + * BIT(0): Allow DW configuration from framework in sync role. + * If this is not set, firmware shall follow the spec/default behavior. + * BIT(1) to BIT(31): Reserved + * + * Related: None + * + * Supported Feature: NAN + * + * Usage: External + * + * + */ +#define CFG_NAN_FEATURE_CONFIG CFG_INI_UINT( \ + "nan_feature_config", \ + 0, \ + 0xFFFF, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable the specified NAN features in firmware") + #ifdef WLAN_FEATURE_NAN #define CFG_NAN_DISC CFG(CFG_NAN_ENABLE) \ CFG(CFG_NDP_KEEP_ALIVE_PERIOD) \ @@ -228,6 +286,8 @@ #define CFG_NAN_ALL CFG_NAN_DISC \ CFG_NAN_DP \ - CFG(CFG_NDI_MAX_SUPPORT) + CFG(CFG_NDP_MAX_SESSIONS) \ + CFG(CFG_NDI_MAX_SUPPORT) \ + CFG(CFG_NAN_FEATURE_CONFIG) #endif diff --git a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan_api.h b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan_api.h index 44730a5e3b0b677450d6268c09e8623bf14629bd..c2af195324d7e56b66a8aa92da1c2b914282d2d8 100644 --- a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan_api.h +++ b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/cfg_nan_api.h @@ -74,6 +74,16 @@ QDF_STATUS cfg_nan_get_ndp_inactivity_timeout(struct wlan_objmgr_psoc *psoc, QDF_STATUS cfg_nan_get_ndp_keepalive_period(struct wlan_objmgr_psoc *psoc, uint16_t *val); +/** + * cfg_nan_get_ndp_max_sessions() - get NDP max sessions host supports + * @psoc: pointer to psoc object + * @val: pointer to hold max ndp sessions + * + * Return: QDF_STATUS + */ +QDF_STATUS cfg_nan_get_ndp_max_sessions(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + /** * cfg_nan_get_max_ndi() - get max number of ndi host supports * @psoc: pointer to psoc object @@ -94,9 +104,10 @@ bool cfg_nan_get_support_mp0_discovery(struct wlan_objmgr_psoc *psoc); /** * cfg_nan_is_roam_config_disabled() - get value of nan config roam disable + * discovery * @psoc: pointer to psoc object * - * Return: Value of config nan roam disable + * Return: true on sta roam disable by nan else false */ bool cfg_nan_is_roam_config_disabled(struct wlan_objmgr_psoc *psoc); #else @@ -135,6 +146,13 @@ QDF_STATUS cfg_nan_get_ndp_keepalive_period(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +static inline +QDF_STATUS cfg_nan_get_ndp_max_sessions(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + return QDF_STATUS_SUCCESS; +} + static inline QDF_STATUS cfg_nan_get_max_ndi(struct wlan_objmgr_psoc *psoc, uint32_t *val) { diff --git a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/nan_ucfg_api.h b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/nan_ucfg_api.h index 86c5b431403e65bd57efe5d3b7772b7ec03eb731..4504b592acce30edb5f208fc9393d41737831459 100644 --- a/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/nan_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/nan/dispatcher/inc/nan_ucfg_api.h @@ -281,12 +281,12 @@ bool ucfg_is_nan_sap_supported(struct wlan_objmgr_psoc *psoc); * ucfg_is_nan_enable_allowed() - ucfg API to query if NAN Discovery is * allowed * @psoc: pointer to psoc object - * @nan_chan: NAN Discovery primary social channel + * @nan_ch_freq: NAN Discovery primary social channel * * Return: True if NAN Discovery enable is allowed, False otherwise */ bool ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc *psoc, - uint8_t nan_chan); + uint32_t nan_ch_freq); /** * ucfg_is_nan_disc_active() - ucfg API to query if NAN Discovery is @@ -386,6 +386,15 @@ ucfg_nan_set_vdev_creation_supp_by_fw(struct wlan_objmgr_psoc *psoc, bool set); */ bool ucfg_nan_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_nan_is_sta_nan_ndi_4_port_allowed- Get support for 4 port (STA + + * NAN Disc + NDI + NDI) + * @psoc: pointer to psoc object + * + * Return: True if 4 port concurrency allowed or not. + */ +bool ucfg_nan_is_sta_nan_ndi_4_port_allowed(struct wlan_objmgr_psoc *psoc); + /** * ucfg_disable_nan_discovery() - Disable NAN discovery * @psoc: pointer to psoc object @@ -414,6 +423,51 @@ QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id); + +/** + * ucfg_get_nan_feature_config() - Get NAN feature bitmap + * @psoc: pointer to psoc object + * @nan_feature_config: NAN feature config bitmap to be enabled in firmware + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc, + uint32_t *nan_feature_config); + +/** + * ucfg_is_nan_vdev() - Check if the current vdev supports NAN or not + * @vdev: pointer to vdev object + * + * Return true + * 1. If the VDEV type is NAN_DISC or + * 2. If the VDEV type is STA and nan_separate_iface feature is not supported + * + * Return: Bool + */ +bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_nan_disable_ind_to_userspace() - Send NAN disble ind to userspace + * @psoc: pointer to psoc object + * + * Prepare NAN disable indication and send it to userspace + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_is_nan_allowed_on_freq() - Check if NAN is allowed on given freq + * @pdev: pdev context + * @freq: Frequency to be checked + * + * Check if NAN/NDP can be enabled on given frequency. + * Validate SRD channels based on the ini and reg domain. Assume rest of the + * channels support NAN/NDP for now. + * + * Return: True if NAN is allowed on the given frequency + */ +bool ucfg_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq); #else /* WLAN_FEATURE_NAN */ static inline @@ -447,6 +501,12 @@ static inline bool ucfg_is_nan_disc_active(struct wlan_objmgr_psoc *psoc) return false; } +static inline +enum nan_datapath_state ucfg_nan_get_ndi_state(struct wlan_objmgr_vdev *vdev) +{ + return NAN_DATA_INVALID_STATE; +} + static inline bool ucfg_nan_is_enable_disable_in_progress(struct wlan_objmgr_psoc *psoc) { @@ -471,6 +531,12 @@ bool ucfg_nan_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) return false; } +static inline +bool ucfg_nan_is_sta_nan_ndi_4_port_allowed(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + static inline QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc, uint8_t *data, uint32_t data_len) @@ -484,5 +550,36 @@ ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id) { return QDF_STATUS_E_INVAL; } + +static inline +bool ucfg_is_nan_disable_supported(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +static inline +QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc, + uint32_t *nan_feature_config) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev) +{ + return false; +} + +static inline +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +bool ucfg_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq) +{ + return false; +} #endif /* WLAN_FEATURE_NAN */ #endif /* _NAN_UCFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/cfg_nan.c b/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/cfg_nan.c index 227e6bfb6661154f106eeb361c4e6845458b4df6..efc2fdd5a52babe8843ac613e43edab654484805 100644 --- a/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/cfg_nan.c +++ b/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/cfg_nan.c @@ -98,6 +98,21 @@ QDF_STATUS cfg_nan_get_ndp_keepalive_period(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS cfg_nan_get_ndp_max_sessions(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct nan_psoc_priv_obj *nan_obj = cfg_nan_get_priv_obj(psoc); + + if (!nan_obj) { + nan_err("NAN obj null"); + *val = cfg_default(CFG_NDP_MAX_SESSIONS); + return QDF_STATUS_E_INVAL; + } + + *val = nan_obj->cfg_param.max_ndp_sessions; + return QDF_STATUS_SUCCESS; +} + QDF_STATUS cfg_nan_get_max_ndi(struct wlan_objmgr_psoc *psoc, uint32_t *val) { struct nan_psoc_priv_obj *nan_obj = cfg_nan_get_priv_obj(psoc); diff --git a/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/nan_ucfg_api.c b/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/nan_ucfg_api.c index 5fad997b71d634ac1dd6a60cc38f072802c67fc4..5c150af68f738bee8a87666f3a5f2f1c2698774f 100644 --- a/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/nan_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/nan/dispatcher/src/nan_ucfg_api.c @@ -32,6 +32,7 @@ #include "wlan_policy_mgr_api.h" #include "cfg_ucfg_api.h" #include "cfg_nan.h" +#include "wlan_mlme_api.h" struct wlan_objmgr_psoc; struct wlan_objmgr_vdev; @@ -54,7 +55,11 @@ static void nan_cfg_init(struct wlan_objmgr_psoc *psoc, nan_obj->cfg_param.ndp_keep_alive_period = cfg_get(psoc, CFG_NDP_KEEP_ALIVE_PERIOD); + nan_obj->cfg_param.max_ndp_sessions = cfg_get(psoc, + CFG_NDP_MAX_SESSIONS); nan_obj->cfg_param.max_ndi = cfg_get(psoc, CFG_NDI_MAX_SUPPORT); + nan_obj->cfg_param.nan_feature_config = + cfg_get(psoc, CFG_NAN_FEATURE_CONFIG); } /** @@ -600,9 +605,10 @@ bool ucfg_is_ndi_dbs_supported(struct wlan_objmgr_psoc *psoc) return (psoc_priv->nan_caps.ndi_dbs_supported == 1); } -bool ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc *psoc, uint8_t nan_chan) +bool ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc *psoc, + uint32_t nan_ch_freq) { - return nan_is_enable_allowed(psoc, nan_chan); + return nan_is_enable_allowed(psoc, nan_ch_freq); } bool ucfg_is_nan_disc_active(struct wlan_objmgr_psoc *psoc) @@ -620,7 +626,7 @@ QDF_STATUS ucfg_nan_discovery_req(void *in_req, uint32_t req_type) struct osif_request *request = NULL; static const struct osif_request_params params = { .priv_size = 0, - .timeout_ms = 1000, + .timeout_ms = 4000, }; int err; @@ -652,7 +658,7 @@ QDF_STATUS ucfg_nan_discovery_req(void *in_req, uint32_t req_type) } status = nan_discovery_pre_enable(psoc, - req->social_chan_2g); + req->social_chan_2g_freq); if (QDF_IS_STATUS_SUCCESS(status)) { len = sizeof(struct nan_enable_req) + req->params.request_data_len; @@ -755,13 +761,20 @@ QDF_STATUS ucfg_nan_discovery_req(void *in_req, uint32_t req_type) if (req_type != NAN_GENERIC_REQ) { err = osif_request_wait_for_response(request); - if (err) + if (err) { nan_debug("NAN request: %u timed out: %d", req_type, err); + if (req_type == NAN_ENABLE_REQ) { + nan_set_discovery_state(psoc, + NAN_DISC_DISABLED); + policy_mgr_check_n_start_opportunistic_timer( + psoc); + } else if (req_type == NAN_DISABLE_REQ) + nan_disable_cleanup(psoc); + } if (req_type == NAN_DISABLE_REQ) psoc_priv->is_explicit_disable = false; - osif_request_put(request); } @@ -1034,7 +1047,7 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev) { uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint32_t ndi_cnt, sta_cnt, id; sta_cnt = policy_mgr_mode_specific_connection_count(psoc, @@ -1058,7 +1071,7 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc, return true; ndi_cnt = policy_mgr_get_mode_specific_conn_info(psoc, - chan_list, + freq_list, vdev_id_list, PM_NDI_MODE); @@ -1075,7 +1088,27 @@ bool ucfg_nan_is_sta_ndp_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (wlan_vdev_get_id(vdev) == vdev_id_list[id]) return true; - return false; + /* If the flow reaches here then it is 4th NDI with STA */ + if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(psoc)) + return false; + + /* The final freq would be provided by FW, it is not known now */ + return policy_mgr_allow_concurrency(psoc, PM_NDI_MODE, 0, + HW_MODE_20_MHZ); +} + +bool +ucfg_nan_is_sta_nan_ndi_4_port_allowed(struct wlan_objmgr_psoc *psoc) +{ + struct nan_psoc_priv_obj *psoc_nan_obj; + + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); + if (!psoc_nan_obj) { + nan_err("psoc_nan_obj is null"); + return false; + } + + return psoc_nan_obj->nan_caps.sta_nan_ndi_ndi_allowed; } static inline bool @@ -1096,12 +1129,30 @@ ucfg_nan_is_vdev_creation_supp_by_host(struct nan_psoc_priv_obj *nan_obj) return nan_obj->cfg_param.nan_separate_iface_support; } +static void ucfg_nan_cleanup_all_ndps(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + uint32_t ndi_count, vdev_id, i; + + ndi_count = policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE, + NULL); + for (i = 0; i < ndi_count; i++) { + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_NDI_MODE); + status = ucfg_nan_disable_ndi(psoc, vdev_id); + if (status == QDF_STATUS_E_TIMEOUT) + policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE, + vdev_id); + } +} + QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc, uint8_t *data, uint32_t data_len) { struct nan_disable_req *nan_req; QDF_STATUS status; + ucfg_nan_cleanup_all_ndps(psoc); + nan_req = qdf_mem_malloc(sizeof(*nan_req) + data_len); if (!nan_req) return -ENOMEM; @@ -1165,3 +1216,65 @@ ucfg_nan_set_vdev_creation_supp_by_fw(struct wlan_objmgr_psoc *psoc, bool set) psoc_nan_obj->nan_caps.nan_vdev_allowed = set; } + +QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc, + uint32_t *nan_feature_config) +{ + struct nan_psoc_priv_obj *psoc_nan_obj; + + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); + if (!psoc_nan_obj) { + nan_err("psoc_nan_obj is null"); + *nan_feature_config = cfg_default(CFG_NAN_FEATURE_CONFIG); + return QDF_STATUS_E_INVAL; + } + + *nan_feature_config = psoc_nan_obj->cfg_param.nan_feature_config; + return QDF_STATUS_SUCCESS; +} + +bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev) +{ + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NAN_DISC_MODE || + (!ucfg_nan_is_vdev_creation_allowed(wlan_vdev_get_psoc(vdev)) && + wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)) + return true; + + return false; +} + +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc) +{ + struct nan_psoc_priv_obj *psoc_nan_obj; + struct nan_event_params *disable_ind; + struct nan_disable_ind_msg msg = { + .msg_hdr.msg_id = NAN_MSG_ID_DISABLE_INDICATION, + .reason = 0, /* success */ }; + + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); + if (!psoc_nan_obj) { + nan_err("psoc_nan_obj is null"); + return QDF_STATUS_E_INVAL; + } + + disable_ind = qdf_mem_malloc(sizeof(struct nan_event_params) + + sizeof(msg)); + if (!disable_ind) { + nan_err("failed to alloc disable_ind"); + return QDF_STATUS_E_NOMEM; + } + disable_ind->psoc = psoc, + disable_ind->evt_type = nan_event_id_disable_ind; + disable_ind->buf_len = sizeof(msg); + qdf_mem_copy(disable_ind->buf, &msg, disable_ind->buf_len); + + psoc_nan_obj->cb_obj.os_if_nan_event_handler(disable_ind); + + qdf_mem_free(disable_ind); + return QDF_STATUS_SUCCESS; +} + +bool ucfg_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq) +{ + return wlan_is_nan_allowed_on_freq(pdev, freq); +} diff --git a/drivers/staging/qcacld-3.0/components/ocb/core/inc/wlan_ocb_main.h b/drivers/staging/qcacld-3.0/components/ocb/core/inc/wlan_ocb_main.h index ad0618024a4877e936a5cc16cb390856209fa7c7..e392a9e0d1145e582fcf5760ea78c33957444286 100644 --- a/drivers/staging/qcacld-3.0/components/ocb/core/inc/wlan_ocb_main.h +++ b/drivers/staging/qcacld-3.0/components/ocb/core/inc/wlan_ocb_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -82,7 +82,7 @@ enum ocb_southbound_event { * @ocb_channel_count: channel count * @channel_config: current channel configurations * @dp_soc: psoc data path handle - * @dp_pdev: pdev data path handle + * @dp_pdev_id: pdev data path ID * @ocb_cbs: legacy callback functions * @ocb_txops: tx opertions for target interface * @ocb_rxops: rx opertions for target interface @@ -93,7 +93,7 @@ struct ocb_pdev_obj { uint32_t ocb_channel_count; struct ocb_config *channel_config; void *dp_soc; - void *dp_pdev; + uint8_t dp_pdev_id; struct ocb_callbacks ocb_cbs; struct wlan_ocb_tx_ops ocb_txops; struct wlan_ocb_rx_ops ocb_rxops; diff --git a/drivers/staging/qcacld-3.0/components/ocb/core/src/wlan_ocb_main.c b/drivers/staging/qcacld-3.0/components/ocb/core/src/wlan_ocb_main.c index cc1e31309aa0185a320ab126f93eeaa383ad44df..bca6ff0adcb20ac1bf88c8d20fb0c227d2d75522 100644 --- a/drivers/staging/qcacld-3.0/components/ocb/core/src/wlan_ocb_main.c +++ b/drivers/staging/qcacld-3.0/components/ocb/core/src/wlan_ocb_main.c @@ -74,7 +74,6 @@ static QDF_STATUS ocb_set_chan_info(void *dp_soc, uint32_t vdev_id, struct ocb_config *config) { - struct cdp_vdev *dp_vdev; struct ol_txrx_ocb_set_chan ocb_set_chan; struct ol_txrx_ocb_chan_info *ocb_channel_info; @@ -83,16 +82,10 @@ static QDF_STATUS ocb_set_chan_info(void *dp_soc, return QDF_STATUS_E_INVAL; } - dp_vdev = cdp_get_vdev_from_vdev_id(dp_soc, dp_pdev, vdev_id); - if (!dp_vdev) { - ocb_err("DP vdev handle is NULL"); - return QDF_STATUS_E_FAILURE; - } - ocb_set_chan.ocb_channel_count = config->channel_count; /* release old settings */ - ocb_channel_info = cdp_get_ocb_chan_info(dp_soc, dp_vdev); + ocb_channel_info = cdp_get_ocb_chan_info(dp_soc, vdev_id); if (ocb_channel_info) qdf_mem_free(ocb_channel_info); @@ -118,7 +111,7 @@ static QDF_STATUS ocb_set_chan_info(void *dp_soc, ocb_set_chan.ocb_channel_info = NULL; } ocb_debug("Sync channel config to dp"); - cdp_set_ocb_chan_info(dp_soc, dp_vdev, ocb_set_chan); + cdp_set_ocb_chan_info(dp_soc, vdev_id, ocb_set_chan); return QDF_STATUS_SUCCESS; } @@ -167,7 +160,7 @@ static QDF_STATUS ocb_channel_config_status(struct ocb_rx_event *evt) /* Sync channel status to data path */ if (config_rsp.status == OCB_CHANNEL_CONFIG_SUCCESS) ocb_set_chan_info(ocb_obj->dp_soc, - ocb_obj->dp_pdev, + ocb_obj->pdev, vdev_id, ocb_obj->channel_config); qdf_mem_free(ocb_obj->channel_config); diff --git a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h index c1d96cdf798a3b2836083a97ca5eb32a749e0dce..9aa2e48cb1cfde9b23e66c0d47709a57d5bc49ff 100644 --- a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h +++ b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_public_structs.h @@ -23,15 +23,7 @@ #ifndef _WLAN_OCB_STRUCTS_H_ #define _WLAN_OCB_STRUCTS_H_ #include - -/* number of vdevs that can support OCB */ -#define OCB_VDEVS_NUM 1 - -/* maximum number of channels that can do OCB */ -#define OCB_CHANNELS_NUM 2 - -/* maximum number of channels in an OCB schedule */ -#define OCB_SCHEDULES_NUM 2 +#include "qca_vendor.h" /* Don't add the RX stats header to packets received on this channel */ #define OCB_CHANNEL_FLAG_DISABLE_RX_STATS_HDR (1 << 0) @@ -42,8 +34,6 @@ /* The size of the utc time error in bytes. */ #define OCB_SIZE_UTC_TIME_ERROR (5) -#define OCB_CHANNEL_MAX (5) - /** * struct ocb_utc_param - parameters to set UTC time * @vdev_id: vdev id diff --git a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h index de90f5b2a29d2e8a6c3808ae6067b73c35036291..121c2a25948bb2cb8aa2aa9acb9ed4493f143ce9 100644 --- a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/inc/wlan_ocb_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -194,14 +194,14 @@ QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *soc, void *dp_soc); /** - * ucfg_ocb_set_txrx_handle() - register pdev txrx handler + * ucfg_ocb_set_txrx_pdev_id() - register txrx pdev id * @soc: soc handle - * @txrx_handle: data path pdev txrx handle + * @pdev_id: data path pdev ID * * Return: QDF_STATUS_SUCCESS on success */ -QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle); +QDF_STATUS ucfg_ocb_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id); #else /** * ucfg_ocb_init() - OCB module initialization @@ -274,15 +274,15 @@ QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *soc, } /** - * ucfg_ocb_set_txrx_handle() - register pdev txrx handler + * ucfg_ocb_set_txrx_pdev_id() - register txrx pdev id * @soc: soc handle - * @txrx_handle: data path pdev txrx handle + * @pdev_id: data path pdev ID * * Return: QDF_STATUS_SUCCESS on success */ static inline -QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle) +QDF_STATUS ucfg_ocb_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id) { return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c index de87d31e6b3fadfaa3f756d6bbceb3feb31ea74a..4595342544bfda5960d2b274f96ef86994bf458c 100644 --- a/drivers/staging/qcacld-3.0/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/ocb/dispatcher/src/wlan_ocb_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -133,8 +134,8 @@ QDF_STATUS ocb_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } -QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle) +QDF_STATUS ucfg_ocb_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t pdev_id) { struct wlan_objmgr_pdev *pdev; struct ocb_pdev_obj *ocb_obj; @@ -151,7 +152,7 @@ QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc, ocb_err("OCB object is NULL"); return QDF_STATUS_E_FAILURE; } - ocb_obj->dp_pdev = txrx_handle; + ocb_obj->dp_pdev_id = pdev_id; return QDF_STATUS_SUCCESS; } @@ -279,7 +280,7 @@ QDF_STATUS ucfg_ocb_set_channel_config(struct wlan_objmgr_vdev *vdev, ocb_cbs->ocb_set_config_context = arg; state = wlan_vdev_mlme_get_state(vdev); - if (state != WLAN_VDEV_S_RUN) { + if (state != WLAN_VDEV_S_START) { /* Vdev is not started, start it */ ocb_debug("OCB vdev%d is not up", config->vdev_id); status = ocb_vdev_start(ocb_obj); diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.c b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.c index e903e4acbc272e9f98430e884423c8c497ddf0d9..4c835df29231a93947fc69558202ff2b2c5dd8ee 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.c +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.c @@ -552,7 +552,6 @@ static QDF_STATUS p2p_object_init_params( cfg_get(psoc, CFG_GO_LINK_MONITOR_PERIOD); p2p_soc_obj->param.p2p_device_addr_admin = cfg_get(psoc, CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED); - return QDF_STATUS_SUCCESS; } @@ -1075,8 +1074,8 @@ QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg) break; case P2P_EVENT_MGMT_TX_ACK_CNF: tx_conf_event = (struct p2p_tx_conf_event *)msg->bodyptr; - qdf_mem_free(tx_conf_event); qdf_nbuf_free(tx_conf_event->nbuf); + qdf_mem_free(tx_conf_event); break; case P2P_EVENT_LO_STOPPED: lo_stop_event = (struct p2p_lo_stop_event *)msg->bodyptr; @@ -1091,6 +1090,89 @@ QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } +bool p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len) +{ + const uint8_t *vendor_ie, *p2p_ie, *pos; + uint8_t rem_len, attr; + uint16_t attr_len; + + vendor_ie = (uint8_t *)p2p_get_p2pie_ptr(assoc_ie, assoc_ie_len); + if (!vendor_ie) { + p2p_debug("P2P IE not found"); + return false; + } + + rem_len = vendor_ie[1]; + if (rem_len < (2 + OUI_SIZE_P2P) || rem_len > WLAN_MAX_IE_LEN) { + p2p_err("Invalid IE len %d", rem_len); + return false; + } + + p2p_ie = vendor_ie + HEADER_LEN_P2P_IE; + rem_len -= OUI_SIZE_P2P; + + while (rem_len) { + attr = p2p_ie[0]; + attr_len = LE_READ_2(&p2p_ie[1]); + if (attr_len > rem_len) { + p2p_err("Invalid len %d for elem:%d", attr_len, attr); + return false; + } + + switch (attr) { + case P2P_ATTR_CAPABILITY: + case P2P_ATTR_DEVICE_ID: + case P2P_ATTR_GROUP_OWNER_INTENT: + case P2P_ATTR_STATUS: + case P2P_ATTR_LISTEN_CHANNEL: + case P2P_ATTR_OPERATING_CHANNEL: + case P2P_ATTR_GROUP_INFO: + case P2P_ATTR_MANAGEABILITY: + case P2P_ATTR_CHANNEL_LIST: + break; + + case P2P_ATTR_DEVICE_INFO: + if (attr_len < (QDF_MAC_ADDR_SIZE + + MAX_CONFIG_METHODS_LEN + 8 + + DEVICE_CATEGORY_MAX_LEN)) { + p2p_err("Invalid Device info attr len %d", + attr_len); + return false; + } + + /* move by attr id and 2 bytes of attr len */ + pos = p2p_ie + 3; + + /* + * the P2P Device info is of format: + * attr_id - 1 byte + * attr_len - 2 bytes + * device mac addr - 6 bytes + * config methods - 2 bytes + * primary device type - 8bytes + * -primary device type category - 1 byte + * -primary device type oui - 4bytes + * number of secondary device type - 2 bytes + */ + pos += ETH_ALEN + MAX_CONFIG_METHODS_LEN + + DEVICE_CATEGORY_MAX_LEN; + + if (!qdf_mem_cmp(pos, P2P_1X1_WAR_OUI, + P2P_1X1_OUI_LEN)) + return true; + + break; + default: + p2p_err("Invalid P2P attribute"); + break; + } + p2p_ie += (3 + attr_len); + rem_len -= (3 + attr_len); + } + + return false; +} + #ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event) @@ -1427,4 +1509,5 @@ QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; } + #endif /* WLAN_FEATURE_P2P_DEBUG */ diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.h b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.h index bf64de8cef06e95e35bf0e3c6b55c3c465000e63..1336cf42d341b51464ed470aa682d59c152b86a6 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.h +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_main.h @@ -467,6 +467,16 @@ QDF_STATUS p2p_msg_flush_callback(struct scheduler_msg *msg); */ QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg); +/** + * p2p_check_oui_and_force_1x1() - Function to get P2P client device + * attributes from assoc request frame IE passed in. + * @assoc_ie: Pointer to the IEs in the association req frame + * @assoc_ie_len: Total length of the IE in association req frame + * + * Return: true if the OUI is present else false + */ +bool p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len); + #ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * p2p_process_lo_stop() - Process lo stop event diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.c index bee12f880eba5786363c9d98815b1bafc6fb23c7..60be2c6cdea206a05d8d510cc7d928263a2fb8a0 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -117,11 +117,14 @@ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) mode = wlan_vdev_mlme_get_opmode(vdev); p2p_debug("vdev mode:%d", mode); - /* drop probe response for go, sap */ + /* drop probe response/disassoc/deauth for go, sap */ if ((mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) && - tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) { - p2p_debug("drop probe response, mode:%d", mode); + ((tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) || + (tx_ctx->frame_info.sub_type == P2P_MGMT_DISASSOC) || + (tx_ctx->frame_info.sub_type == P2P_MGMT_DEAUTH))) { + p2p_debug("drop frame, mode:%d, sub type:%d", mode, + tx_ctx->frame_info.sub_type); status = QDF_STATUS_E_FAILURE; } @@ -160,12 +163,15 @@ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) mode = wlan_vdev_mlme_get_opmode(vdev); p2p_debug("vdev mode:%d", mode); - /* drop probe response for sta, go, sap */ - if ((mode == QDF_STA_MODE || - mode == QDF_SAP_MODE || - mode == QDF_P2P_GO_MODE) && - tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) { - p2p_debug("drop probe response, mode:%d", mode); + /* drop probe response/disassoc/deauth for sta, go, sap */ + if ((mode == QDF_STA_MODE && + tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) || + ((mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) && + ((tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) || + (tx_ctx->frame_info.sub_type == P2P_MGMT_DISASSOC) || + (tx_ctx->frame_info.sub_type == P2P_MGMT_DEAUTH)))) { + p2p_debug("drop frame, mode:%d, sub type:%d", mode, + tx_ctx->frame_info.sub_type); status = QDF_STATUS_E_FAILURE; } @@ -240,7 +246,7 @@ static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx) * * Return: pointer to p2p ie */ -static const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len) +const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len) { return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI, P2P_OUI_SIZE, ie, ie_len); @@ -649,17 +655,6 @@ static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info) if (frame_info->sub_type == P2P_MGMT_NOT_SUPPORT) return "Not support sub frame"; - switch (frame_info->sub_type) { - case P2P_MGMT_PROBE_REQ: - return "P2P roc request"; - case P2P_MGMT_PROBE_RSP: - return "P2P cancel roc request"; - case P2P_MGMT_ACTION: - break; - default: - return "Invalid P2P command"; - } - if (frame_info->action_type == P2P_ACTION_PRESENCE_REQ) return "P2P action presence request"; if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP) @@ -693,7 +688,7 @@ static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info) case P2P_PUBLIC_ACTION_GAS_COMB_RSP: return "GAS come back response"; default: - return "Not support action frame"; + return "Other frame"; } } @@ -746,26 +741,12 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, return QDF_STATUS_E_FAILURE; } - frame_info->type = P2P_FRAME_MGMT; + frame_info->type = type; + frame_info->sub_type = sub_type; - if (sub_type == P2P_MGMT_PROBE_RSP) { - frame_info->sub_type = P2P_MGMT_PROBE_RSP; - p2p_debug("Probe Response"); + if (sub_type != P2P_MGMT_ACTION) return QDF_STATUS_SUCCESS; - } - - if (sub_type == P2P_MGMT_PROBE_REQ) { - frame_info->sub_type = P2P_MGMT_PROBE_REQ; - p2p_debug("Probe Request"); - return QDF_STATUS_SUCCESS; - } - - if (sub_type != P2P_MGMT_ACTION) { - p2p_debug("not support sub type"); - return QDF_STATUS_E_FAILURE; - } - frame_info->sub_type = P2P_MGMT_ACTION; buf += P2P_ACTION_OFFSET; if (length > P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET && buf[0] == P2P_PUBLIC_ACTION_FRAME && @@ -826,9 +807,9 @@ static QDF_STATUS p2p_tx_update_connection_status( if (tx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_debug("%s ---> OTA to " QDF_MAC_ADDR_STR, + p2p_debug("%s ---> OTA to " QDF_MAC_ADDR_FMT, p2p_get_frame_type_str(tx_frame_info), - QDF_MAC_ADDR_ARRAY(mac_to)); + QDF_MAC_ADDR_REF(mac_to)); if ((tx_frame_info->public_action_type == P2P_PUBLIC_ACTION_PROV_DIS_REQ) && @@ -870,9 +851,9 @@ static QDF_STATUS p2p_rx_update_connection_status( if (rx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_info("%s <--- OTA from " QDF_MAC_ADDR_STR, + p2p_info("%s <--- OTA from " QDF_MAC_ADDR_FMT, p2p_get_frame_type_str(rx_frame_info), - QDF_MAC_ADDR_ARRAY(mac_from)); + QDF_MAC_ADDR_REF(mac_from)); if ((rx_frame_info->public_action_type == P2P_PUBLIC_ACTION_PROV_DIS_REQ) && @@ -1579,8 +1560,8 @@ static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx, if (!p2p_soc_obj->p2p_cb.is_mgmt_protected( tx_ctx->vdev_id, wh->i_addr1)) { - p2p_debug("non rmf connection vdev %d "QDF_MAC_ADDR_STR, - tx_ctx->vdev_id, QDF_MAC_ADDR_ARRAY(wh->i_addr1)); + p2p_debug("non rmf connection vdev %d "QDF_MAC_ADDR_FMT, + tx_ctx->vdev_id, QDF_MAC_ADDR_REF(wh->i_addr1)); return QDF_STATUS_SUCCESS; } if (!qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) && @@ -1614,10 +1595,10 @@ static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx, *size - sizeof(*wh)); rmf_wh = (struct wlan_frame_hdr *)frame; (rmf_wh)->i_fc[1] |= IEEE80211_FC1_WEP; - p2p_debug("set protection 0x%x cat %d "QDF_MAC_ADDR_STR, + p2p_debug("set protection 0x%x cat %d "QDF_MAC_ADDR_FMT, tx_ctx->frame_info.sub_type, action_hdr->action_category, - QDF_MAC_ADDR_ARRAY(wh->i_addr1)); + QDF_MAC_ADDR_REF(wh->i_addr1)); qdf_nbuf_free(*ppkt); *ppbuf = frame; @@ -2054,6 +2035,28 @@ delete_action_frame_cookie(qdf_list_t *cookie_list, qdf_mem_free(action_cookie); } +/** + * delete_all_action_frame_cookie() - Delete all the cookies to given list + * @cookie_list: List of cookies + * + * This function deletes all the cookies from from given list. + * + * Return: None + */ +static void +delete_all_action_frame_cookie(qdf_list_t *cookie_list) +{ + qdf_list_node_t *node = NULL; + + p2p_debug("Delete cookie list %pK, size %d", cookie_list, + qdf_list_size(cookie_list)); + + while (!qdf_list_empty(cookie_list)) { + qdf_list_remove_front(cookie_list, &node); + qdf_mem_free(node); + } +} + /** * append_action_frame_cookie() - Append action cookie to given list * @cookie_list: List of cookies @@ -2114,8 +2117,8 @@ p2p_add_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, struct p2p_vdev_priv_obj *p2p_vdev_obj; struct wlan_objmgr_vdev *vdev; - p2p_debug("random_mac:vdev %d mac_addr:%pM rnd_cookie=%llu freq = %u", - vdev_id, mac, rnd_cookie, freq); + p2p_debug("random_mac:vdev %d mac_addr:"QDF_MAC_ADDR_FMT" rnd_cookie=%llu freq = %u", + vdev_id, QDF_MAC_ADDR_REF(mac), rnd_cookie, freq); vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); if (!vdev) { @@ -2157,8 +2160,8 @@ p2p_add_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, rnd_cookie); qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); - p2p_debug("random_mac:append %d vdev %d freq %d %pM rnd_cookie %llu", - append_ret, vdev_id, freq, mac, rnd_cookie); + p2p_debug("random_mac:append %d vdev %d freq %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu", + append_ret, vdev_id, freq, QDF_MAC_ADDR_REF(mac), rnd_cookie); if (!append_ret) { p2p_debug("random_mac:failed to append rnd_cookie"); return QDF_STATUS_E_NOMEM; @@ -2193,23 +2196,22 @@ p2p_add_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, p2p_vdev_obj->random_mac[i].freq = freq; qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); - p2p_debug("random_mac:add vdev %d freq %d %pM rnd_cookie %llu", - vdev_id, freq, mac, rnd_cookie); + p2p_debug("random_mac:add vdev %d freq %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu", + vdev_id, freq, QDF_MAC_ADDR_REF(mac), rnd_cookie); return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, - uint64_t rnd_cookie, uint32_t duration) + uint64_t rnd_cookie) { uint32_t i; struct action_frame_cookie *action_cookie; struct p2p_vdev_priv_obj *p2p_vdev_obj; struct wlan_objmgr_vdev *vdev; - p2p_debug("random_mac:vdev %d cookie %llu duration %d", vdev_id, - rnd_cookie, duration); + p2p_debug("random_mac:vdev %d cookie %llu", vdev_id, rnd_cookie); vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); if (!vdev) { @@ -2227,6 +2229,8 @@ p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { struct action_frame_random_mac *random_mac; + qdf_freq_t freq; + uint8_t addr[QDF_MAC_ADDR_SIZE]; random_mac = &p2p_vdev_obj->random_mac[i]; if (!random_mac->in_use) @@ -2242,16 +2246,25 @@ p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, action_cookie); if (qdf_list_empty(&random_mac->cookie_list)) { + random_mac->in_use = false; + freq = random_mac->freq; + qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE); qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); if (qdf_mc_timer_get_current_state( &random_mac->clear_timer) == - QDF_TIMER_STATE_RUNNING) + QDF_TIMER_STATE_RUNNING) { + p2p_debug("random_mac:stop timer on vdev %d addr " QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(addr)); qdf_mc_timer_stop(&random_mac->clear_timer); - qdf_mc_timer_start(&random_mac->clear_timer, duration); + } + + p2p_clear_mac_filter( + wlan_vdev_get_psoc(p2p_vdev_obj->vdev), + vdev_id, addr, freq); qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); - p2p_debug("random_mac:noref on vdev %d addr %pM", - vdev_id, random_mac->addr); + p2p_debug("random_mac:noref on vdev %d addr "QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(addr)); } break; } @@ -2261,6 +2274,93 @@ p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, return QDF_STATUS_SUCCESS; } +QDF_STATUS +p2p_random_mac_handle_tx_done(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint64_t rnd_cookie, uint32_t duration) +{ + uint32_t i; + struct action_frame_cookie *action_cookie; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + p2p_debug("random_mac:vdev %d cookie %llu duration %d", vdev_id, + rnd_cookie, duration); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("vdev is null"); + return QDF_STATUS_E_INVAL; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("p2p vdev object is NULL"); + return QDF_STATUS_E_INVAL; + } + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + struct action_frame_random_mac *random_mac; + qdf_freq_t freq; + uint8_t addr[QDF_MAC_ADDR_SIZE]; + + random_mac = &p2p_vdev_obj->random_mac[i]; + if (!random_mac->in_use) + continue; + action_cookie = find_action_frame_cookie( + &random_mac->cookie_list, rnd_cookie); + if (!action_cookie) + continue; + + /* If duration is zero then remove the cookie and also remove + * the filter from firmware. + */ + if (!duration) { + delete_action_frame_cookie(&random_mac->cookie_list, + action_cookie); + p2p_debug("random mac:clear mac addr on vdev %d addr " QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(random_mac->addr)); + + if (qdf_list_empty(&random_mac->cookie_list)) { + random_mac->in_use = false; + freq = random_mac->freq; + qdf_mem_copy(addr, random_mac->addr, + QDF_MAC_ADDR_SIZE); + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + p2p_clear_mac_filter( + wlan_vdev_get_psoc(p2p_vdev_obj->vdev), + vdev_id, addr, freq); + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + } + } else { + /* As duration is non zero start the timer for this + * duration. while the timer is running if tx cancel + * comes from supplicant then cookie will be removed + * and random mac filter will be removed from firmware. + * same thing will happen if timer expires without tx + * cancel from supplicant + */ + qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE); + + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + if (qdf_mc_timer_get_current_state( + &random_mac->clear_timer) == + QDF_TIMER_STATE_RUNNING) + qdf_mc_timer_stop(&random_mac->clear_timer); + qdf_mc_timer_start(&random_mac->clear_timer, duration); + p2p_debug("random_mac:start timer on vdev %d addr " QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(addr)); + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + } + } + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return QDF_STATUS_SUCCESS; +} + void p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev *vdev) { int32_t i; @@ -2301,8 +2401,8 @@ void p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev *vdev) qdf_mc_timer_stop(&p2p_vdev_obj->random_mac[i].clear_timer); p2p_clear_mac_filter(wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev), addr, freq); - p2p_debug("random_mac:delall vdev %d freq %d addr %pM", - wlan_vdev_get_id(vdev), freq, addr); + p2p_debug("random_mac:delall vdev %d freq %d addr "QDF_MAC_ADDR_FMT, + wlan_vdev_get_id(vdev), freq, QDF_MAC_ADDR_REF(addr)); qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); } @@ -2423,9 +2523,10 @@ QDF_STATUS p2p_process_set_rand_mac_rsp(struct p2p_mac_filter_rsp *resp) return QDF_STATUS_E_INVAL; } - p2p_debug("random_mac:get pending req on vdev %d set %d mac filter %pM freq %d", + p2p_debug("random_mac:get pending req on vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d", p2p_vdev_obj->pending_req.vdev_id, - p2p_vdev_obj->pending_req.set, p2p_vdev_obj->pending_req.mac, + p2p_vdev_obj->pending_req.set, + QDF_MAC_ADDR_REF(p2p_vdev_obj->pending_req.mac), p2p_vdev_obj->pending_req.freq); if (p2p_vdev_obj->pending_req.cb) p2p_vdev_obj->pending_req.cb( @@ -2452,9 +2553,9 @@ p2p_process_set_rand_mac(struct p2p_set_mac_filter_req *set_filter_req) p2p_debug("random_mac:set_filter_req is null"); return QDF_STATUS_E_INVAL; } - p2p_debug("random_mac:vdev %d set %d mac filter %pM freq %d", + p2p_debug("random_mac:vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d", set_filter_req->vdev_id, set_filter_req->set, - set_filter_req->mac, set_filter_req->freq); + QDF_MAC_ADDR_REF(set_filter_req->mac), set_filter_req->freq); soc = set_filter_req->soc; vdev = wlan_objmgr_get_vdev_by_id_from_psoc( @@ -2472,10 +2573,10 @@ p2p_process_set_rand_mac(struct p2p_set_mac_filter_req *set_filter_req) goto get_p2p_obj_failed; } if (p2p_vdev_obj->pending_req.soc) { - p2p_debug("random_mac:Busy on vdev %d set %d mac filter %pM freq %d", + p2p_debug("random_mac:Busy on vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d", p2p_vdev_obj->pending_req.vdev_id, p2p_vdev_obj->pending_req.set, - p2p_vdev_obj->pending_req.mac, + QDF_MAC_ADDR_REF(p2p_vdev_obj->pending_req.mac), p2p_vdev_obj->pending_req.freq); goto get_p2p_obj_failed; } @@ -2532,8 +2633,8 @@ p2p_set_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, struct scheduler_msg msg = {0}; QDF_STATUS status; - p2p_debug("random_mac:vdev %d freq %d set %d %pM", - vdev_id, freq, set, mac); + p2p_debug("random_mac:vdev %d freq %d set %d "QDF_MAC_ADDR_FMT, + vdev_id, freq, set, QDF_MAC_ADDR_REF(mac)); set_filter_req = qdf_mem_malloc(sizeof(*set_filter_req)); if (!set_filter_req) @@ -2652,8 +2753,9 @@ p2p_set_rand_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, } else { priv = osif_request_priv(request); ret = priv->result; - p2p_debug("random_mac:vdev %d freq %d result %d %pM rnd_cookie %llu", - vdev_id, freq, priv->result, mac, rnd_cookie); + p2p_debug("random_mac:vdev %d freq %d result %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu", + vdev_id, freq, priv->result, + QDF_MAC_ADDR_REF(mac), rnd_cookie); } } osif_request_put(request); @@ -2661,6 +2763,47 @@ p2p_set_rand_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, return ret; } +/** + * p2p_mac_clear_timeout() - clear random mac filter timeout + * @context: timer context + * + * This function will clear the mac addr rx filter in target if no + * reference to it. + * + * Return: void + */ +static void p2p_mac_clear_timeout(void *context) +{ + struct action_frame_random_mac *random_mac = context; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + uint32_t freq; + uint8_t addr[QDF_MAC_ADDR_SIZE]; + uint32_t vdev_id; + + if (!random_mac || !random_mac->p2p_vdev_obj) { + p2p_err("invalid context for mac_clear timeout"); + return; + } + p2p_vdev_obj = random_mac->p2p_vdev_obj; + if (!p2p_vdev_obj || !p2p_vdev_obj->vdev) + return; + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + + delete_all_action_frame_cookie(&random_mac->cookie_list); + random_mac->in_use = false; + freq = random_mac->freq; + qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE); + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + + vdev_id = wlan_vdev_get_id(p2p_vdev_obj->vdev); + p2p_debug("random_mac:clear timeout vdev %d " QDF_MAC_ADDR_FMT " freq %d", + vdev_id, QDF_MAC_ADDR_REF(addr), freq); + + p2p_clear_mac_filter(wlan_vdev_get_psoc(p2p_vdev_obj->vdev), + vdev_id, addr, freq); +} + /** * p2p_request_random_mac() - request random mac mgmt tx * @soc: soc @@ -2682,17 +2825,50 @@ p2p_request_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, uint32_t duration) { QDF_STATUS status; + uint32_t i; + struct wlan_objmgr_vdev *vdev; + struct p2p_vdev_priv_obj *p2p_vdev_obj; status = p2p_add_random_mac(soc, vdev_id, mac, freq, rnd_cookie); if (status == QDF_STATUS_E_EXISTS) return QDF_STATUS_SUCCESS; + else if (status != QDF_STATUS_SUCCESS) return status; - if (!p2p_set_rand_mac(soc, vdev_id, mac, freq, rnd_cookie)) - status = p2p_del_random_mac(soc, vdev_id, rnd_cookie, - duration); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("vdev is null"); + return QDF_STATUS_E_INVAL; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + p2p_debug("random_mac:p2p vdev object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + return QDF_STATUS_E_INVAL; + } + + if (!p2p_set_rand_mac(soc, vdev_id, mac, freq, rnd_cookie)) { + p2p_debug("random mac: failed to set rand mac address"); + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr, mac, + QDF_MAC_ADDR_SIZE)) { + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + p2p_mac_clear_timeout( + &p2p_vdev_obj->random_mac[i]); + status = QDF_STATUS_SUCCESS; + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + break; + } + } + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); return status; } @@ -2731,50 +2907,8 @@ p2p_rand_mac_tx_done(struct wlan_objmgr_psoc *soc, if (!tx_ctx || !tx_ctx->rand_mac_tx || !soc) return; - p2p_del_random_mac(soc, tx_ctx->vdev_id, tx_ctx->id, tx_ctx->duration); -} - -/** - * p2p_mac_clear_timeout() - clear random mac filter timeout - * @context: timer context - * - * This function will clear the mac addr rx filter in target if no - * reference to it. - * - * Return: void - */ -static void p2p_mac_clear_timeout(void *context) -{ - struct action_frame_random_mac *random_mac = context; - struct p2p_vdev_priv_obj *p2p_vdev_obj; - uint32_t freq; - uint8_t addr[QDF_MAC_ADDR_SIZE]; - uint32_t vdev_id; - bool clear = false; - - if (!random_mac || !random_mac->p2p_vdev_obj) { - p2p_err("invalid context for mac_clear timeout"); - return; - } - p2p_vdev_obj = random_mac->p2p_vdev_obj; - if (!p2p_vdev_obj || !p2p_vdev_obj->vdev) - return; - - qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); - if (qdf_list_empty(&random_mac->cookie_list)) { - random_mac->in_use = false; - clear = true; - } - freq = random_mac->freq; - qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE); - qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); - - vdev_id = wlan_vdev_get_id(p2p_vdev_obj->vdev); - p2p_debug("random_mac:clear timeout vdev %d %pM freq %d clr %d", - vdev_id, addr, freq, clear); - if (clear) - p2p_clear_mac_filter(wlan_vdev_get_psoc(p2p_vdev_obj->vdev), - vdev_id, addr, freq); + p2p_random_mac_handle_tx_done(soc, tx_ctx->vdev_id, tx_ctx->id, + tx_ctx->duration); } void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj) @@ -3059,10 +3193,10 @@ QDF_STATUS p2p_process_rx_mgmt( return QDF_STATUS_E_INVAL; } - p2p_debug("soc:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", - p2p_soc_obj->soc, rx_mgmt->frame_len, - rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, - rx_mgmt->rx_rssi, rx_mgmt->buf); + p2p_debug("soc:%pK, frame_len:%d, rx_freq:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", + p2p_soc_obj->soc, rx_mgmt->frame_len, + rx_mgmt->rx_freq, rx_mgmt->vdev_id, rx_mgmt->frm_type, + rx_mgmt->rx_rssi, rx_mgmt->buf); if (rx_mgmt->frm_type == MGMT_ACTION_VENDOR_SPECIFIC) { p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len, diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.h b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.h index 5b18b36f27766f2f7f449ef0f60e025fbcb5bc3a..08f0606eddf935ca8e779d311bc5669dedc995b2 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.h +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.h @@ -79,13 +79,19 @@ enum p2p_frame_type { * enum p2p_frame_sub_type - frame sub type * @P2P_MGMT_PROBE_REQ: probe request frame * @P2P_MGMT_PROBE_RSP: probe response frame + * @P2P_MGMT_DISASSOC: disassociation frame + * @P2P_MGMT_AUTH: authentication frame + * @P2P_MGMT_DEAUTH: deauthentication frame * @P2P_MGMT_ACTION: action frame * @P2P_MGMT_NOT_SUPPORT: not support sub frame type */ enum p2p_frame_sub_type { P2P_MGMT_PROBE_REQ = 4, P2P_MGMT_PROBE_RSP, - P2P_MGMT_ACTION = 13, + P2P_MGMT_DISASSOC = 10, + P2P_MGMT_AUTH, + P2P_MGMT_DEAUTH, + P2P_MGMT_ACTION, P2P_MGMT_NOT_SUPPORT, }; @@ -335,7 +341,6 @@ struct tx_action_context *p2p_find_tx_ctx_by_nbuf( * @soc: soc object * @vdev_id: vdev id * @rnd_cookie: random mac mgmt tx cookie - * @duration: timeout value to flush the addr in target. * * This function will del the mac addr filter from vdev random mac addr list. * If there is no reference to mac addr, it will set a clear timer to flush it @@ -346,7 +351,26 @@ struct tx_action_context *p2p_find_tx_ctx_by_nbuf( */ QDF_STATUS p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, - uint64_t rnd_cookie, uint32_t duration); + uint64_t rnd_cookie); + +/** + * p2p_random_mac_handle_tx_done() - del mac filter from given vdev rand mac + * list when mgmt tx done + * @soc: soc object + * @vdev_id: vdev id + * @rnd_cookie: random mac mgmt tx cookie + * @duration: timeout value to flush the addr in target. + * + * This function will del the mac addr filter from vdev random mac addr list + * and also remove the filter from firmware if duration is zero else start + * the timer for that duration. + * + * Return: QDF_STATUS_SUCCESS - del successfully. + * other : failed to del the mac address entry. + */ +QDF_STATUS +p2p_random_mac_handle_tx_done(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint64_t rnd_cookie, uint32_t duration); /** * p2p_check_random_mac() - check random mac addr or not @@ -435,4 +459,15 @@ void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); */ void p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); +/** + * p2p_get_p2pie_ptr() - get the pointer to p2p ie + * @ie: source ie + * @ie_len: source ie length + * + * This function finds out p2p ie by p2p oui and return the pointer. + * + * Return: pointer to p2p ie + */ +const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len); + #endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.c b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.c index 6f2ecec503fca905dcdfc5511069757acc4a06e2..c7668842e5e93839cd9c3cab53b3556e29b43431 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.c +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.c @@ -82,6 +82,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) struct wlan_objmgr_vdev *vdev; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; uint32_t go_num; + uint8_t ndp_num = 0, nan_disc_enabled_num = 0; + bool is_dbs; vdev = wlan_objmgr_get_vdev_by_id_from_psoc( p2p_soc_obj->soc, roc_ctx->vdev_id, @@ -122,7 +124,17 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) if (req->scan_req.dwell_time_passive < P2P_MAX_ROC_DURATION) { go_num = policy_mgr_mode_specific_connection_count( p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); - p2p_debug("present go number:%d", go_num); + policy_mgr_mode_specific_num_active_sessions(p2p_soc_obj->soc, + QDF_NDI_MODE, + &ndp_num); + policy_mgr_mode_specific_num_active_sessions(p2p_soc_obj->soc, + QDF_NAN_DISC_MODE, + &nan_disc_enabled_num); + p2p_debug("present go number:%d, NDP number:%d, NAN number:%d", + go_num, ndp_num, nan_disc_enabled_num); + + is_dbs = policy_mgr_is_hw_dbs_capable(p2p_soc_obj->soc); + if (go_num) req->scan_req.dwell_time_passive *= P2P_ROC_DURATION_MULTI_GO_PRESENT; @@ -132,8 +144,33 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) /* this is to protect too huge value if some customers * give a higher value from supplicant */ - if (req->scan_req.dwell_time_passive > P2P_MAX_ROC_DURATION) + + if (go_num && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_GO_PRESENT) { + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_GO_PRESENT; + } else if (ndp_num) { + if (is_dbs && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_DBS_NDP_PRESENT) + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_DBS_NDP_PRESENT; + else if (!is_dbs && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_NON_DBS_NDP_PRESENT) + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_NON_DBS_NDP_PRESENT; + } else if (nan_disc_enabled_num) { + if (is_dbs && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_DBS_NAN_PRESENT) + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_DBS_NAN_PRESENT; + else if (!is_dbs && req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT) + req->scan_req.dwell_time_passive = + P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT; + } else if (req->scan_req.dwell_time_passive > + P2P_MAX_ROC_DURATION) { req->scan_req.dwell_time_passive = P2P_MAX_ROC_DURATION; + } } p2p_debug("FW requested roc duration is:%d", req->scan_req.dwell_time_passive); diff --git a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.h b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.h index e82d8caee189b60b963988c3bf4965862eb2bab0..8ed91f7eb08ef331b540d8dbff6ec5467f206610 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.h +++ b/drivers/staging/qcacld-3.0/components/p2p/core/src/wlan_p2p_roc.h @@ -31,6 +31,11 @@ #define P2P_WAIT_CANCEL_ROC 1000 #define P2P_WAIT_CLEANUP_ROC 2000 #define P2P_MAX_ROC_DURATION 1500 +#define P2P_MAX_ROC_DURATION_GO_PRESENT 600 +#define P2P_MAX_ROC_DURATION_DBS_NDP_PRESENT 400 +#define P2P_MAX_ROC_DURATION_NON_DBS_NDP_PRESENT 250 +#define P2P_MAX_ROC_DURATION_DBS_NAN_PRESENT 450 +#define P2P_MAX_ROC_DURATION_NON_DBS_NAN_PRESENT 300 #define P2P_ROC_DURATION_MULTI_GO_PRESENT 6 #define P2P_ROC_DURATION_MULTI_GO_ABSENT 10 diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_api.h b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_api.h new file mode 100644 index 0000000000000000000000000000000000000000..d9d0757d7b74a516f73d93634c9ac1f008e06c1d --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_api.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Contains p2p public data structure definitions + */ + +#ifndef _WLAN_P2P_API_H_ +#define _WLAN_P2P_API_H_ + +#include + +/** + * wlan_p2p_check_oui_and_force_1x1() - Function to get P2P client device + * attributes from assoc request frames + * @assoc_ie: pointer to assoc request frame IEs + * @ie_len: length of the assoc request frame IE + * + * When assoc request is received from P2P STA device, this function checks + * for specific OUI present in the P2P device info attribute. The caller should + * take care of checking if this is called only in P2P GO mode. + * + * Return: True if OUI is present, else false. + */ +bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t ie_len); +#endif diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_cfg.h b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_cfg.h index cc5630c5b45b3a3bf399cdc8b6841d1fab2e112a..04a5b6c85e5a9a8fe187eace793ddf15abe226d2 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_cfg.h +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_cfg.h @@ -101,6 +101,6 @@ #define CFG_P2P_ALL \ CFG(CFG_GO_KEEP_ALIVE_PERIOD) \ CFG(CFG_GO_LINK_MONITOR_PERIOD) \ - CFG(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED) \ + CFG(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED) #endif diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h index d1c597ff35f1565b11edc7d7c9d704770832f0fe..33fd71c70b400bd08289242bf0d118278471f365 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,6 +27,15 @@ #define P2P_MAX_NOA_DESC 4 +#define HEADER_LEN_P2P_IE 6 +#define OUI_SIZE_P2P 4 + +#define P2P_1X1_WAR_OUI "\x00\x50\xf2\x04" +#define P2P_1X1_OUI_LEN 4 + +#define MAX_CONFIG_METHODS_LEN 2 +#define DEVICE_CATEGORY_MAX_LEN 1 + /** * struct p2p_ps_params - P2P powersave related params * @opp_ps: opportunistic power save @@ -94,7 +103,7 @@ struct p2p_event { /** * struct p2p_rx_mgmt_frame - rx mgmt frame structure * @frame_len: Frame length - * @rx_chan: RX channel + * @rx_freq: RX Frequency * @vdev_id: Vdev id * @frm_type: Frame type * @rx_rssi: RX rssi @@ -102,7 +111,7 @@ struct p2p_event { */ struct p2p_rx_mgmt_frame { uint32_t frame_len; - uint32_t rx_chan; + uint32_t rx_freq; uint32_t vdev_id; uint32_t frm_type; uint32_t rx_rssi; @@ -269,4 +278,67 @@ struct p2p_protocol_callbacks { bool (*is_mgmt_protected)(uint32_t vdev_id, const uint8_t *peer_addr); }; +/** + * enum p2p_attr_id - enum for P2P attributes ID in P2P IE + * @P2P_ATTR_STATUS - Attribute Status none + * @P2P_ATTR_MINOR_REASON_CODE: Minor reason code attribute + * @P2P_ATTR_CAPABILITY: Capability attribute + * @P2P_ATTR_DEVICE_ID: device ID attribute + * @P2P_ATTR_GROUP_OWNER_INTENT: Group owner intent attribute + * @P2P_ATTR_CONFIGURATION_TIMEOUT: Config timeout attribute + * @P2P_ATTR_LISTEN_CHANNEL: listen channel attribute + * @P2P_ATTR_GROUP_BSSID: Group BSSID attribute + * @P2P_ATTR_EXT_LISTEN_TIMING: Listen timing attribute + * @P2P_ATTR_INTENDED_INTERFACE_ADDR: Intended interface address attribute + * @P2P_ATTR_MANAGEABILITY: Manageability attribute + * @P2P_ATTR_CHANNEL_LIST: Channel list attribute + * @P2P_ATTR_NOTICE_OF_ABSENCE: Notice of Absence attribute + * @P2P_ATTR_DEVICE_INFO: Device Info attribute + * @P2P_ATTR_GROUP_INFO: Group Info attribute + * @P2P_ATTR_GROUP_ID: Group ID attribute + * @P2P_ATTR_INTERFACE: Interface attribute + * @P2P_ATTR_OPERATING_CHANNEL: Operating channel attribute + * @P2P_ATTR_INVITATION_FLAGS: Invitation flags attribute + * @P2P_ATTR_OOB_GO_NEG_CHANNEL: GO neg channel attribute + * @P2P_ATTR_SERVICE_HASH: Service HASH attribute + * @P2P_ATTR_SESSION_INFORMATION_DATA: Session Info data attribute + * @P2P_ATTR_CONNECTION_CAPABILITY = Connection capability attribute + * @P2P_ATTR_ADVERTISEMENT_ID = Advertisement ID attribute + * @P2P_ATTR_ADVERTISED_SERVICE = Advertised Service attribute + * @P2P_ATTR_SESSION_ID = Session ID attribute + * @P2P_ATTR_FEATURE_CAPABILITY = Feature capability attribute + * @P2P_ATTR_PERSISTENT_GROUP -Persistent group attribute + * @P2P_ATTR_VENDOR_SPECIFIC - Vendor specific attribute + */ +enum p2p_attr_id { + P2P_ATTR_STATUS = 0, + P2P_ATTR_MINOR_REASON_CODE = 1, + P2P_ATTR_CAPABILITY = 2, + P2P_ATTR_DEVICE_ID = 3, + P2P_ATTR_GROUP_OWNER_INTENT = 4, + P2P_ATTR_CONFIGURATION_TIMEOUT = 5, + P2P_ATTR_LISTEN_CHANNEL = 6, + P2P_ATTR_GROUP_BSSID = 7, + P2P_ATTR_EXT_LISTEN_TIMING = 8, + P2P_ATTR_INTENDED_INTERFACE_ADDR = 9, + P2P_ATTR_MANAGEABILITY = 10, + P2P_ATTR_CHANNEL_LIST = 11, + P2P_ATTR_NOTICE_OF_ABSENCE = 12, + P2P_ATTR_DEVICE_INFO = 13, + P2P_ATTR_GROUP_INFO = 14, + P2P_ATTR_GROUP_ID = 15, + P2P_ATTR_INTERFACE = 16, + P2P_ATTR_OPERATING_CHANNEL = 17, + P2P_ATTR_INVITATION_FLAGS = 18, + P2P_ATTR_OOB_GO_NEG_CHANNEL = 19, + P2P_ATTR_SERVICE_HASH = 21, + P2P_ATTR_SESSION_INFORMATION_DATA = 22, + P2P_ATTR_CONNECTION_CAPABILITY = 23, + P2P_ATTR_ADVERTISEMENT_ID = 24, + P2P_ATTR_ADVERTISED_SERVICE = 25, + P2P_ATTR_SESSION_ID = 26, + P2P_ATTR_FEATURE_CAPABILITY = 27, + P2P_ATTR_PERSISTENT_GROUP = 28, + P2P_ATTR_VENDOR_SPECIFIC = 221 +}; #endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_api.c b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_api.c new file mode 100644 index 0000000000000000000000000000000000000000..63f04cdd27d6a57b62818dfbe75c5dfb17737a47 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_api.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: This file contains P2P public API's exposed. + */ + +#include "wlan_p2p_api.h" +#include +#include "wlan_p2p_public_struct.h" +#include "../../core/src/wlan_p2p_main.h" + +bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len) +{ + if (!assoc_ie || !assoc_ie_len) + return false; + + return p2p_check_oui_and_force_1x1(assoc_ie, assoc_ie_len); +} diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_tgt_api.c b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_tgt_api.c index 8615c665e28f5cf24fe8a7f81ea4d898037ac29d..3416c87685aa99ece591513ec09d3c9ac3b9444e 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_tgt_api.c +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_tgt_api.c @@ -349,7 +349,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, pdata = (uint8_t *)qdf_nbuf_data(buf); rx_mgmt->frame_len = mgmt_rx_params->buf_len; - rx_mgmt->rx_chan = mgmt_rx_params->channel; + rx_mgmt->rx_freq = mgmt_rx_params->chan_freq; rx_mgmt->vdev_id = vdev_id; rx_mgmt->frm_type = frm_type; rx_mgmt->rx_rssi = mgmt_rx_params->snr + diff --git a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c index 7209c0c82a253b8dc1fe13e91e56e037f7e15fac..b15f078acd2a1f9df9467a1b752b5b07fed3a2ac 100644 --- a/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c @@ -433,7 +433,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, p2p_debug("invalid id for cookie 0x%llx", cookie); return QDF_STATUS_E_INVAL; } - p2p_del_random_mac(soc, wlan_vdev_get_id(vdev), cookie, 20); + p2p_del_random_mac(soc, wlan_vdev_get_id(vdev), cookie); cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); if (!cancel_tx) { @@ -586,8 +586,8 @@ QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; if (!soc || !cb_obj) { - p2p_err("psoc %pM cb_obj %pM context passed is NULL", soc, - cb_obj); + p2p_err("psoc: %pK or cb_obj: %pK context passed is NULL", + soc, cb_obj); return QDF_STATUS_E_INVAL; } diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h deleted file mode 100644 index f2ebbeced3153ceac2b69b679f7175e044479472..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Declare private API which shall be used internally only - * in pkt_capture component. This file shall include prototypes of - * pkt_capture data tx and data rx. - * - * Note: This API should be never accessed out of pkt_capture component. - */ - -#ifndef _WLAN_PKT_CAPTURE_DATA_TXRX_H_ -#define _WLAN_PKT_CAPTURE_DATA_TXRX_H_ - -#include "cdp_txrx_cmn_struct.h" -#include -#include - -#define SHORT_PREAMBLE 1 -#define LONG_PREAMBLE 0 -/** - * pkt_capture_data_process_type - data pkt types to process - * for packet capture mode - * @TXRX_PROCESS_TYPE_DATA_RX: process RX packets (normal rx + offloaded rx) - * @TXRX_PROCESS_TYPE_DATA_TX: process TX packets (ofloaded tx) - * @TXRX_PROCESS_TYPE_DATA_TX_COMPL: process TX compl packets (normal tx) - */ -enum pkt_capture_data_process_type { - TXRX_PROCESS_TYPE_DATA_RX, - TXRX_PROCESS_TYPE_DATA_TX, - TXRX_PROCESS_TYPE_DATA_TX_COMPL, -}; - -#define TXRX_PKTCAPTURE_PKT_FORMAT_8023 0 -#define TXRX_PKTCAPTURE_PKT_FORMAT_80211 1 - -/** - * pkt_capture_datapkt_process() - process data tx and rx packets - * for pkt capture mode. (normal tx/rx + offloaded tx/rx) - * @vdev_id: vdev id for which packet is captured - * @mon_buf_list: netbuf list - * @type: data process type - * @tid: tid number - * @status: Tx status - * @pkt_format: Frame format - * @bssid: bssid - * @pdev: pdev handle - * @tx_retry_cnt: tx retry count - * - * Return: none - */ -void pkt_capture_datapkt_process( - uint8_t vdev_id, - qdf_nbuf_t mon_buf_list, - enum pkt_capture_data_process_type type, - uint8_t tid, uint8_t status, bool pktformat, - uint8_t *bssid, htt_pdev_handle pdev, - uint8_t tx_retry_cnt); -/** - * pkt_capture_msdu_process_pkts() - process data rx pkts - * @bssid: bssid - * @head_msdu: pointer to head msdu - * @vdev_id: vdev_id - * @pdev: pdev handle - * - * Return: none - */ -void pkt_capture_msdu_process_pkts( - uint8_t *bssid, - qdf_nbuf_t head_msdu, - uint8_t vdev_id, - htt_pdev_handle pdev); - -/** - * pkt_capture_rx_in_order_drop_offload_pkt() - drop offload packets - * @head_msdu: pointer to head msdu - * - * Return: none - */ -void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu); - -/** - * pkt_capture_rx_in_order_offloaded_pkt() - check offloaded data pkt or not - * @rx_ind_msg: rx_ind_msg - * - * Return: false if it is not an offload packet - * true if it is offload packet - */ -bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg); - -/** - * pkt_capture_offload_deliver_indication_handler() - Handle offload data pkts - * @msg: offload netbuf msg - * @vdev_id: vdev id - * @bssid: bssid - * @pdev: pdev handle - * - * Return: none - */ -void pkt_capture_offload_deliver_indication_handler( - void *msg, uint8_t vdev_id, - uint8_t *bssid, htt_pdev_handle pdev); - -/** - * pkt_capture_tx_hdr_elem_t - tx packets header struture to - * be used to update radiotap header for packet capture mode - * @timestamp: timestamp - * @preamble: preamble - * @mcs: MCS - * @rate: rate - * @rssi_comb: rssi in dBm - * @nss: if nss 1 means 1ss and 2 means 2ss - * @bw: BW (0=>20MHz, 1=>40MHz, 2=>80MHz, 3=>160MHz) - * @stbc: STBC - * @sgi: SGI - * @ldpc: LDPC - * @beamformed: beamformed - * @dir: direction rx: 0 and tx: 1 - * @status: tx status - * @tx_retry_cnt: tx retry count - */ -struct pkt_capture_tx_hdr_elem_t { - uint32_t timestamp; - uint8_t preamble; - uint8_t mcs; - uint8_t rate; - uint8_t rssi_comb; - uint8_t nss; - uint8_t bw; - bool stbc; - bool sgi; - bool ldpc; - bool beamformed; - bool dir; /* rx:0 , tx:1 */ - uint8_t status; /* tx status */ - uint8_t tx_retry_cnt; -}; - -/** - * pkt_capture_tx_get_txcomplete_data_hdr() - extract Tx data hdr from Tx - * completion for pkt capture mode - * @msg_word: Tx completion htt msg - * @num_msdus: number of msdus - * - * Return: tx data hdr information - */ -struct htt_tx_data_hdr_information *pkt_capture_tx_get_txcomplete_data_hdr( - uint32_t *msg_word, - int num_msdus); - -#endif /* End of _WLAN_PKT_CAPTURE_DATA_TXRX_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_main.h b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_main.h index ae6ef0c4d5a18223bf6388057bc81ffbe8256c7e..cf92a568940ad4056d2dc4e3be21e2a345946c06 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_main.h +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_main.h @@ -30,7 +30,6 @@ #include #include "wlan_pkt_capture_priv.h" #include "wlan_pkt_capture_objmgr.h" -#include "wlan_objmgr_vdev_obj.h" #define pkt_capture_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_PKT_CAPTURE, level, ## args) @@ -52,28 +51,6 @@ #define PKT_CAPTURE_ENTER() pkt_capture_debug("enter") #define PKT_CAPTURE_EXIT() pkt_capture_debug("exit") -#define NORMALIZED_TO_NOISE_FLOOR (-96) -/** - * enum pkt_capture_tx_status - packet capture tx status - * @pktcapture_tx_status_ok: successfully sent + acked - * @pktcapture_tx_status_discard: discard - not sent - * @pktcapture_tx_status_no_ack: no_ack - sent, but no ack - * - * This enum has tx status types for packet capture mode - */ -enum pkt_capture_tx_status { - pkt_capture_tx_status_ok, - pkt_capture_tx_status_discard, - pkt_capture_tx_status_no_ack, -}; - -/** - * pkt_capture_get_vdev() - Get pkt capture objmgr vdev. - * - * Return: pkt capture objmgr vdev - */ -struct wlan_objmgr_vdev *pkt_capture_get_vdev(void); - /** * pkt_capture_vdev_create_notification() - Handler for vdev create notify. * @vdev: vdev which is going to be created by objmgr @@ -129,73 +106,4 @@ pkt_capture_psoc_create_notification(struct wlan_objmgr_psoc *psoc, void *arg); */ QDF_STATUS pkt_capture_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg); - -/** - * pkt_capture_register_callbacks - Register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * @mon_cb: callback to call - * @context: callback context - * - * Return: QDF_STATUS - */ -QDF_STATUS -pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t), - void *context); - -/** - * pkt_capture_deregister_callbacks - De-register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * - * Return: QDF_STATUS - */ -QDF_STATUS pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_set_pktcap_mode - Set packet capture mode - * @psoc: pointer to psoc object - * @mode: mode to be set - * - * Return: None - */ -void pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, - enum pkt_capture_mode mode); - -/** - * pkt_capture_get_pktcap_mode - Get packet capture mode - * - * Return: enum pkt_capture_mode - */ -enum pkt_capture_mode -pkt_capture_get_pktcap_mode(void); - -/** - * pkt_capture_drop_nbuf_list() - drop an nbuf list - * @buf_list: buffer list to be dropepd - * - * Return: number of buffers dropped - */ -uint32_t pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list); - -/** - * pkt_capture_record_channel() - Update Channel Information - * for packet capture mode - * @vdev: pointer to vdev - * - * Return: None - */ -void pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_mon() - Wrapper function to invoke mon cb - * @cb_ctx: packet capture callback context - * @msdu: packet - * @vdev: objmgr vdev - * @chan_num: channel number - * - * Return: None - */ -void pkt_capture_mon(struct pkt_capture_cb_context *cb_ctx, - qdf_nbuf_t msdu, struct wlan_objmgr_vdev *vdev, - uint8_t chan_num); #endif /* end of _WLAN_PKT_CAPTURE_MAIN_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h deleted file mode 100644 index f456107b9f0cdda87ae1109b951faa0d2a2fb122..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Declare mgmt txrx APIs which shall be used internally only - * in pkt_capture component. - * Note: These APIs should be never accessed out of pkt_capture component. - */ - -#ifndef _WLAN_PKT_CAPTURE_MGMT_TXRX_H_ -#define _WLAN_PKT_CAPTURE_MGMT_TXRX_H_ - -#include "wlan_pkt_capture_public_structs.h" - -#define PKTCAPTURE_PKT_FORMAT_8023 (0) -#define PKTCAPTURE_PKT_FORMAT_80211 (1) -#define WLAN_INVALID_TID (31) -#define RESERVE_BYTES (100) -#define RATE_LIMIT (16) -#define INVALID_RSSI_FOR_TX (-128) - -/** - * pkt_capture_process_mgmt_tx_data() - process management tx packets - * @pdev: pointer to pdev object - * @params: management offload event params - * @nbuf: netbuf - * @status: status - * - * Return: QDF_STATUS - */ -QDF_STATUS -pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, - struct mgmt_offload_event_params *params, - qdf_nbuf_t nbuf, - uint8_t status); -/** - * pkt_capture_mgmt_tx() - process mgmt tx completion - * for pkt capture mode - * @pdev: pointer to pdev object - * @nbuf: netbuf - * @chan_freq: channel freq - * @preamble_type: preamble_type - * - * Return: none - */ -void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, - qdf_nbuf_t nbuf, - uint16_t chan_freq, - uint8_t preamble_type); - -/** - * pkt_capture_mgmt_tx_completion() - process mgmt tx completion - * for pkt capture mode - * @pdev: pointer to pdev object - * @desc_id: desc_id - * @status: status - * @params: management offload event params - * - * Return: none - */ -void -pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, - uint32_t desc_id, - uint32_t status, - struct mgmt_offload_event_params *params); - -/** - * pkt_capture_mgmt_rx_ops() - Register packet capture mgmt rx ops - * @psoc: psoc context - * @is_register: register if true, unregister if false - * - * This funciton registers or deregisters rx callback - * to mgmt txrx component. - * - * Return: QDF_STATUS - */ -QDF_STATUS pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, - bool is_register); - -/** - * pkt_capture_mgmt_status_map() - map Tx status for MGMT packets - * with packet capture Tx status - * @status: Tx status - * - * Return: pkt_capture_tx_status enum - */ -enum pkt_capture_tx_status -pkt_capture_mgmt_status_map(uint8_t status); -#endif diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h deleted file mode 100644 index 630d92201d98a6dd5cce9ddf1cc66ea9fc2e72c5..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_mon_thread.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Declare APIs which shall be used for monitor thread access. - */ - -#ifndef _WLAN_PKT_CAPTURE_MON_THREAD_H_ -#define _WLAN_PKT_CAPTURE_MON_THREAD_H_ - -#include "wlan_pkt_capture_main.h" - -#define PKT_CAPTURE_RX_POST_EVENT 0x01 -#define PKT_CAPTURE_RX_SUSPEND_EVENT 0x02 -#define PKT_CAPTURE_RX_SHUTDOWN_EVENT 0x04 -#define PKT_CAPTURE_REGISTER_EVENT 0x08 - -/* - * Maximum number of packets to be allocated for - * Packet Capture Monitor thread. - */ -#define MAX_MON_PKT_SIZE 4000 - -/* timeout in msec to wait for mon thread to suspend */ -#define PKT_CAPTURE_SUSPEND_TIMEOUT 200 - -typedef void (*pkt_capture_mon_thread_cb)( - void *context, void *ppdev, void *monpkt, - uint8_t vdev_id, uint8_t tid, - uint8_t status, bool pkt_format, - uint8_t *bssid, - uint8_t tx_retry_cnt); - -/* - * struct pkt_capture_mon_pkt - mon packet wrapper for mon data from TXRX - * @list: List for storing mon packets - * @context: Callback context - * @pdev: pointer to pdev handle - * @monpkt: Mon skb - * @vdev_id: Vdev id to which this packet is destined - * @tid: Tid of mon packet - * @status: Tx packet status - * @pkt_format: Mon packet format, 0 = 802.3 format , 1 = 802.11 format - * @bssid: bssid - * @tx_retry_cnt: tx retry count - * @callback: Mon callback - */ -struct pkt_capture_mon_pkt { - struct list_head list; - void *context; - void *pdev; - void *monpkt; - uint8_t vdev_id; - uint8_t tid; - uint8_t status; - bool pkt_format; - uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint8_t tx_retry_cnt; - pkt_capture_mon_thread_cb callback; -}; - -/** - * struct pkt_capture_mon_context - packet capture mon thread context - * @mon_thread_lock: MON thread lock - * @mon_thread: MON thread handle - * @mon_start_event: Handle of Event for MON thread to signal startup - * @suspend_mon_event: Completion to suspend packet capture MON thread - * @resume_mon_event: Completion to resume packet capture MON thread - * @mon_shutdown: Completion for packet capture MON thread shutdown - * @mon_register_event: Completion for packet capture register - * @mon_wait_queue: Waitq for packet capture MON thread - * @mon_event_flag: Mon event flag - * @mon_thread_queue: MON buffer queue - * @mon_queue_lock: Spinlock to synchronize between tasklet and thread - * @mon_pkt_freeq_lock: Lock to synchronize free buffer queue access - * @mon_pkt_freeq: Free message queue for packet capture MON processing - * @is_mon_thread_suspended: flag to check mon thread suspended or not - */ -struct pkt_capture_mon_context { - /* MON thread lock */ - spinlock_t mon_thread_lock; - struct task_struct *mon_thread; - struct completion mon_start_event; - struct completion suspend_mon_event; - struct completion resume_mon_event; - struct completion mon_shutdown; - struct completion mon_register_event; - wait_queue_head_t mon_wait_queue; - unsigned long mon_event_flag; - struct list_head mon_thread_queue; - - /* Spinlock to synchronize between tasklet and thread */ - spinlock_t mon_queue_lock; - - /* Lock to synchronize free buffer queue access */ - spinlock_t mon_pkt_freeq_lock; - - struct list_head mon_pkt_freeq; - bool is_mon_thread_suspended; -}; - -/** - * struct radiotap_header - base radiotap header - * @it_version: radiotap version, always 0 - * @it_pad: padding (or alignment) - * @it_len: overall radiotap header length - * @it_present: (first) present word - */ -struct radiotap_header { - uint8_t it_version; - uint8_t it_pad; - __le16 it_len; - __le32 it_present; -} __packed; - -/** - * pkt_capture_suspend_mon_thread() - suspend packet capture mon thread - * vdev: pointer to vdev object manager - * - * Return: 0 on success, -EINVAL on failure - */ -int pkt_capture_suspend_mon_thread(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_resume_mon_thread() - resume packet capture mon thread - * vdev: pointer to vdev object manager - * - * Resume packet capture MON thread by completing RX thread resume event. - * - * Return: None - */ -void pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_drop_monpkt() - API to drop pending mon packets - * mon_ctx: pointer to packet capture mon context - * - * This api drops all the pending packets in the queue. - * - * Return: None - */ -void pkt_capture_drop_monpkt(struct pkt_capture_mon_context *mon_ctx); - -/** - * pkt_capture_indicate_monpkt() - API to Indicate rx data packet - * @vdev: pointer to vdev object manager - * @pkt: MON pkt pointer containing to mon data message buffer - * - * Return: None - */ -void pkt_capture_indicate_monpkt(struct wlan_objmgr_vdev *vdev, - struct pkt_capture_mon_pkt *pkt); - -/** - * pkt_capture_wakeup_mon_thread() - wakeup packet capture mon thread - * @vdev: pointer to vdev object - * - * This api wake up pkt_capture_mon_thread() to process pkt. - * - * Return: None - */ -void pkt_capture_wakeup_mon_thread(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_close_mon_thread() - close packet capture MON thread - * @mon_ctx: pointer to packet capture mon context - * - * This api closes packet capture MON thread. - * - * Return: None - */ -void pkt_capture_close_mon_thread(struct pkt_capture_mon_context *mon_ctx); - -/** - * pkt_capture_open_mon_thread() - open packet capture MON thread - * @mon_ctx: pointer to packet capture mon context - * - * This api opens the packet capture MON thread. - * - * Return: QDF_STATUS - */ -QDF_STATUS -pkt_capture_open_mon_thread(struct pkt_capture_mon_context *mon_ctx); - -/** - * pkt_capture_alloc_mon_thread() - alloc resources for - * packet capture MON thread - * @mon_ctx: pointer to packet capture mon context - * - * This api alloc resources for packet capture MON thread. - * - * Return: QDF_STATUS - */ -QDF_STATUS -pkt_capture_alloc_mon_thread(struct pkt_capture_mon_context *mon_ctx); - -/** - * pkt_capture_alloc_mon_pkt() - API to return next available mon packet - * @vdev: pointer to vdev object manager - * - * This api returns next available mon packet buffer used for mon data - * processing. - * - * Return: Pointer to pkt_capture_mon_pkt - */ -struct pkt_capture_mon_pkt * -pkt_capture_alloc_mon_pkt(struct wlan_objmgr_vdev *vdev); - -/** - * pkt_capture_free_mon_pkt_freeq() - free mon packet free queue - * @mon_ctx: pointer to packet capture mon context - * - * This API does mem free of the buffers available in free mon packet - * queue which is used for mon Data processing. - * - * Return: None - */ -void pkt_capture_free_mon_pkt_freeq(struct pkt_capture_mon_context *mon_ctx); -#endif /* _WLAN_PKT_CAPTURE_MON_THREAD_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_priv.h b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_priv.h index 62a0f1615827e3bec594d2f452d261b8e5f7b0c2..a83b4f5557633e271693f2de72d8a4de5a68e4cd 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_priv.h +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/core/inc/wlan_pkt_capture_priv.h @@ -29,7 +29,6 @@ #include "wlan_pkt_capture_objmgr.h" #include "wlan_pkt_capture_public_structs.h" -#include "wlan_pkt_capture_mon_thread.h" /** * struct pkt_capture_cfg - packet capture cfg to store ini values @@ -39,43 +38,21 @@ struct pkt_capture_cfg { enum pkt_capture_mode pkt_capture_mode; }; -/** - * struct pkt_capture_cb_context - packet capture callback context - * @mon_cb: monitor callback function pointer - * @mon_ctx: monitor callback context - * @pkt_capture_mode: packet capture mode - */ -struct pkt_capture_cb_context { - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t); - void *mon_ctx; - enum pkt_capture_mode pkt_capture_mode; -}; - /** * struct pkt_capture_vdev_priv - Private object to be stored in vdev * @vdev: pointer to vdev object - * @mon_ctx: pointer to packet capture mon context - * @cb_ctx: pointer to packet capture mon callback context - * @rx_ops: rx ops - * @tx_ops: tx ops */ struct pkt_capture_vdev_priv { struct wlan_objmgr_vdev *vdev; - struct pkt_capture_mon_context *mon_ctx; - struct pkt_capture_cb_context *cb_ctx; - struct wlan_pkt_capture_rx_ops rx_ops; - struct wlan_pkt_capture_tx_ops tx_ops; }; /** * struct pkt_psoc_priv - Private object to be stored in psoc * @psoc: pointer to psoc object * @cfg_param: INI config params for packet capture - * @cb_obj: struct contaning callback pointers */ struct pkt_psoc_priv { struct wlan_objmgr_psoc *psoc; struct pkt_capture_cfg cfg_param; - struct pkt_capture_callbacks cb_obj; }; #endif /* End of _WLAN_PKT_CAPTURE_PRIV_STRUCT_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c deleted file mode 100644 index fd65752b680128201023c33658750c9bb5d8bd47..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c +++ /dev/null @@ -1,864 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Implement various notification handlers which are accessed - * internally in pkt_capture component only. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define RESERVE_BYTES (100) - -/** - * pkt_capture_txrx_status_map() - map Tx status for data packets - * with packet capture Tx status - * @status: Tx status - * - * Return: pkt_capture_tx_status enum - */ -static enum pkt_capture_tx_status -pkt_capture_txrx_status_map(uint8_t status) -{ - enum pkt_capture_tx_status tx_status; - - switch (status) { - case htt_tx_status_ok: - tx_status = pkt_capture_tx_status_ok; - break; - case htt_tx_status_no_ack: - tx_status = pkt_capture_tx_status_no_ack; - break; - default: - tx_status = pkt_capture_tx_status_discard; - break; - } - - return tx_status; -} - -/** - * pkt_capture_get_tx_rate() - get tx rate for tx packet - * @preamble_type: preamble type - * @rate: rate code - * @preamble: preamble - * - * Return: rate - */ -static unsigned char pkt_capture_get_tx_rate( - uint8_t preamble_type, - uint8_t rate, - uint8_t *preamble) -{ - char ret = 0x0; - *preamble = LONG_PREAMBLE; - - if (preamble_type == 0) { - switch (rate) { - case 0x0: - ret = 0x60; - break; - case 0x1: - ret = 0x30; - break; - case 0x2: - ret = 0x18; - break; - case 0x3: - ret = 0x0c; - break; - case 0x4: - ret = 0x6c; - break; - case 0x5: - ret = 0x48; - break; - case 0x6: - ret = 0x24; - break; - case 0x7: - ret = 0x12; - break; - default: - break; - } - } else if (preamble_type == 1) { - switch (rate) { - case 0x0: - ret = 0x16; - *preamble = LONG_PREAMBLE; - case 0x1: - ret = 0xB; - *preamble = LONG_PREAMBLE; - break; - case 0x2: - ret = 0x4; - *preamble = LONG_PREAMBLE; - break; - case 0x3: - ret = 0x2; - *preamble = LONG_PREAMBLE; - break; - case 0x4: - ret = 0x16; - *preamble = SHORT_PREAMBLE; - break; - case 0x5: - ret = 0xB; - *preamble = SHORT_PREAMBLE; - break; - case 0x6: - ret = 0x4; - *preamble = SHORT_PREAMBLE; - break; - default: - break; - } - } else { - qdf_print("Invalid rate info\n"); - } - return ret; -} - -/** - * pkt_capture_tx_get_phy_info() - get phy info for tx packets for pkt - * capture mode(normal tx + offloaded tx) to prepare radiotap header - * @pktcapture_hdr: tx data header - * @tx_status: tx status to be updated with phy info - * - * Return: none - */ -static void pkt_capture_tx_get_phy_info( - struct pkt_capture_tx_hdr_elem_t *pktcapture_hdr, - struct mon_rx_status *tx_status) -{ - uint8_t preamble = 0; - uint8_t preamble_type = pktcapture_hdr->preamble; - uint8_t mcs = 0, bw = 0; - uint16_t vht_flags = 0, ht_flags = 0; - - switch (preamble_type) { - case 0x0: - case 0x1: - /* legacy */ - tx_status->rate = pkt_capture_get_tx_rate( - preamble_type, - pktcapture_hdr->rate, - &preamble); - break; - case 0x2: - ht_flags = 1; - bw = pktcapture_hdr->bw; - if (pktcapture_hdr->nss == 2) - mcs = 8 + pktcapture_hdr->mcs; - else - mcs = pktcapture_hdr->mcs; - break; - case 0x3: - vht_flags = 1; - bw = pktcapture_hdr->bw; - mcs = pktcapture_hdr->mcs; - - /* fallthrough */ - default: - break; - } - - tx_status->mcs = mcs; - tx_status->bw = bw; - tx_status->nr_ant = pktcapture_hdr->nss; - tx_status->is_stbc = pktcapture_hdr->stbc; - tx_status->sgi = pktcapture_hdr->sgi; - tx_status->ldpc = pktcapture_hdr->ldpc; - tx_status->beamformed = pktcapture_hdr->beamformed; - tx_status->vht_flag_values3[0] = mcs << 0x4 | (pktcapture_hdr->nss + 1); - tx_status->ht_flags = ht_flags; - tx_status->vht_flags = vht_flags; - tx_status->rtap_flags |= ((preamble == 1) ? BIT(1) : 0); - if (bw == 0) - tx_status->vht_flag_values2 = 0; - else if (bw == 1) - tx_status->vht_flag_values2 = 1; - else if (bw == 2) - tx_status->vht_flag_values2 = 4; -} - -/** - * pkt_capture_update_tx_status() - tx status for tx packets, for - * pkt capture mode(normal tx + offloaded tx) to prepare radiotap header - * @pdev: device handler - * @tx_status: tx status to be updated - * @mon_hdr: tx data header - * - * Return: none - */ -static void -pkt_capture_update_tx_status( - htt_pdev_handle pdev, - struct mon_rx_status *tx_status, - struct pkt_capture_tx_hdr_elem_t *pktcapture_hdr) -{ - struct mon_channel *ch_info = &pdev->mon_ch_info; - - tx_status->tsft = (u_int64_t)(pktcapture_hdr->timestamp); - tx_status->chan_freq = ch_info->ch_freq; - tx_status->chan_num = ch_info->ch_num; - - pkt_capture_tx_get_phy_info(pktcapture_hdr, tx_status); - - if (pktcapture_hdr->preamble == 0) - tx_status->ofdm_flag = 1; - else if (pktcapture_hdr->preamble == 1) - tx_status->cck_flag = 1; - - tx_status->ant_signal_db = pktcapture_hdr->rssi_comb; - tx_status->rssi_comb = pktcapture_hdr->rssi_comb; - tx_status->tx_status = pktcapture_hdr->status; - tx_status->tx_retry_cnt = pktcapture_hdr->tx_retry_cnt; - tx_status->add_rtap_ext = true; -} - -/** - * pkt_capture_rx_convert8023to80211() - convert 802.3 packet to 802.11 - * format from rx desc - * @bssid: bssid - * @msdu: netbuf - * @desc: rx desc - * - * Return: none - */ -static void -pkt_capture_rx_convert8023to80211(uint8_t *bssid, qdf_nbuf_t msdu, void *desc) -{ - struct ethernet_hdr_t *eth_hdr; - struct llc_snap_hdr_t *llc_hdr; - struct ieee80211_frame *wh; - uint8_t hdsize, new_hdsize; - struct ieee80211_qoscntl *qos_cntl; - uint16_t seq_no; - uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) + - sizeof(struct llc_snap_hdr_t)]; - const uint8_t ethernet_II_llc_snap_header_prefix[] = { - 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - uint16_t ether_type; - - struct htt_host_rx_desc_base *rx_desc = desc; - - eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu); - hdsize = sizeof(struct ethernet_hdr_t); - wh = (struct ieee80211_frame *)localbuf; - - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; - *(uint16_t *)wh->i_dur = 0; - - new_hdsize = 0; - - /* DA , BSSID , SA */ - qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(wh->i_addr2, bssid, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(wh->i_addr3, eth_hdr->src_addr, - QDF_MAC_ADDR_SIZE); - - wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; - - if (rx_desc->attention.more_data) - wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; - - if (rx_desc->attention.power_mgmt) - wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT; - - if (rx_desc->attention.fragment) - wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG; - - if (rx_desc->attention.order) - wh->i_fc[1] |= IEEE80211_FC1_ORDER; - - if (rx_desc->mpdu_start.retry) - wh->i_fc[1] |= IEEE80211_FC1_RETRY; - - seq_no = rx_desc->mpdu_start.seq_num; - seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) & IEEE80211_SEQ_SEQ_MASK; - qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no)); - - new_hdsize = sizeof(struct ieee80211_frame); - - if (rx_desc->attention.non_qos == 0) { - qos_cntl = - (struct ieee80211_qoscntl *)(localbuf + new_hdsize); - qos_cntl->i_qos[0] = - (rx_desc->mpdu_start.tid & IEEE80211_QOS_TID); - wh->i_fc[0] |= QDF_IEEE80211_FC0_SUBTYPE_QOS; - - qos_cntl->i_qos[1] = 0; - new_hdsize += sizeof(struct ieee80211_qoscntl); - } - - /* - * Prepare llc Header - */ - llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize); - ether_type = (eth_hdr->ethertype[0] << 8) | - (eth_hdr->ethertype[1]); - if (ether_type >= ETH_P_802_3_MIN) { - qdf_mem_copy(llc_hdr, - ethernet_II_llc_snap_header_prefix, - sizeof - (ethernet_II_llc_snap_header_prefix)); - if (ether_type == ETHERTYPE_AARP || - ether_type == ETHERTYPE_IPX) { - llc_hdr->org_code[2] = - BTEP_SNAP_ORGCODE_2; - /* 0xf8; bridge tunnel header */ - } - llc_hdr->ethertype[0] = eth_hdr->ethertype[0]; - llc_hdr->ethertype[1] = eth_hdr->ethertype[1]; - new_hdsize += sizeof(struct llc_snap_hdr_t); - } - - /* - * Remove 802.3 Header by adjusting the head - */ - qdf_nbuf_pull_head(msdu, hdsize); - - /* - * Adjust the head and prepare 802.11 Header - */ - qdf_nbuf_push_head(msdu, new_hdsize); - qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize); -} - -void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu) -{ - while (head_msdu) { - qdf_nbuf_t msdu = head_msdu; - - head_msdu = qdf_nbuf_next(head_msdu); - qdf_nbuf_free(msdu); - } -} - -bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg) -{ - uint32_t *msg_word; - - msg_word = (uint32_t *)qdf_nbuf_data(rx_ind_msg); - - /* check if it is for offloaded data pkt */ - return HTT_RX_IN_ORD_PADDR_IND_PKT_CAPTURE_MODE_IS_MONITOR_SET - (*(msg_word + 1)); -} - -void pkt_capture_msdu_process_pkts( - uint8_t *bssid, - qdf_nbuf_t head_msdu, - uint8_t vdev_id, htt_pdev_handle pdev) -{ - qdf_nbuf_t loop_msdu, pktcapture_msdu; - qdf_nbuf_t msdu, prev = NULL; - - pktcapture_msdu = NULL; - loop_msdu = head_msdu; - while (loop_msdu) { - msdu = qdf_nbuf_copy(loop_msdu); - - if (msdu) { - qdf_nbuf_push_head(msdu, - HTT_RX_STD_DESC_RESERVATION); - qdf_nbuf_set_next(msdu, NULL); - - if (!(pktcapture_msdu)) { - pktcapture_msdu = msdu; - prev = msdu; - } else { - qdf_nbuf_set_next(prev, msdu); - prev = msdu; - } - } - loop_msdu = qdf_nbuf_next(loop_msdu); - } - - if (!pktcapture_msdu) - return; - - pkt_capture_datapkt_process( - vdev_id, pktcapture_msdu, - TXRX_PROCESS_TYPE_DATA_RX, 0, 0, - TXRX_PKTCAPTURE_PKT_FORMAT_8023, - bssid, pdev, 0); -} - -/** - * pkt_capture_rx_data_cb(): callback to process data rx packets - * for pkt capture mode. (normal rx + offloaded rx) - * @context: objmgr vdev - * @ppdev: device handler - * @nbuf_list: netbuf list - * @vdev_id: vdev id for which packet is captured - * @tid: tid number - * @status: Tx status - * @pkt_format: Frame format - * @bssid: bssid - * @tx_retry_cnt: tx retry count - * - * Return: none - */ -static void -pkt_capture_rx_data_cb( - void *context, void *ppdev, void *nbuf_list, - uint8_t vdev_id, uint8_t tid, - uint8_t status, bool pkt_format, - uint8_t *bssid, uint8_t tx_retry_cnt) -{ - struct pkt_capture_vdev_priv *vdev_priv; - qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list; - struct wlan_objmgr_vdev *vdev = context; - htt_pdev_handle pdev = ppdev; - struct pkt_capture_cb_context *cb_ctx; - qdf_nbuf_t msdu, next_buf; - uint8_t drop_count; - struct htt_host_rx_desc_base *rx_desc; - struct mon_rx_status rx_status = {0}; - uint32_t headroom; - static uint8_t preamble_type; - static uint32_t vht_sig_a_1; - static uint32_t vht_sig_a_2; - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) - goto free_buf; - - cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) - goto free_buf; - - msdu = buf_list; - while (msdu) { - struct ethernet_hdr_t *eth_hdr; - - next_buf = qdf_nbuf_queue_next(msdu); - qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */ - - rx_desc = htt_rx_desc(msdu); - - /* - * Only the first mpdu has valid preamble type, so use it - * till the last mpdu is reached - */ - if (rx_desc->attention.first_mpdu) { - preamble_type = rx_desc->ppdu_start.preamble_type; - if (preamble_type == 8 || preamble_type == 9 || - preamble_type == 0x0c || preamble_type == 0x0d) { - vht_sig_a_1 = VHT_SIG_A_1(rx_desc); - vht_sig_a_2 = VHT_SIG_A_2(rx_desc); - } - } else { - rx_desc->ppdu_start.preamble_type = preamble_type; - if (preamble_type == 8 || preamble_type == 9 || - preamble_type == 0x0c || preamble_type == 0x0d) { - VHT_SIG_A_1(rx_desc) = vht_sig_a_1; - VHT_SIG_A_2(rx_desc) = vht_sig_a_2; - } - } - - if (rx_desc->attention.last_mpdu) { - preamble_type = 0; - vht_sig_a_1 = 0; - vht_sig_a_2 = 0; - } - - qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION); - - /* - * Get the channel info and update the rx status - */ - - /* need to update this to fill rx_status*/ - htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status); - rx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR; - rx_status.tx_status = status; - rx_status.tx_retry_cnt = tx_retry_cnt; - rx_status.add_rtap_ext = true; - - /* clear IEEE80211_RADIOTAP_F_FCS flag*/ - rx_status.rtap_flags &= ~(BIT(4)); - rx_status.rtap_flags &= ~(BIT(2)); - - /* - * convert 802.3 header format into 802.11 format - */ - if (vdev_id == HTT_INVALID_VDEV) { - eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu); - qdf_mem_copy(bssid, eth_hdr->src_addr, - QDF_MAC_ADDR_SIZE); - } - - pkt_capture_rx_convert8023to80211(bssid, msdu, rx_desc); - - /* - * Calculate the headroom and adjust head - * to prepare radiotap header. - */ - headroom = qdf_nbuf_headroom(msdu); - qdf_nbuf_update_radiotap(&rx_status, msdu, headroom); - pkt_capture_mon(cb_ctx, msdu, vdev, 0); - msdu = next_buf; - } - - return; - -free_buf: - drop_count = pkt_capture_drop_nbuf_list(buf_list); -} - -/** - * pkt_capture_tx_data_cb() - process data tx and rx packets - * for pkt capture mode. (normal tx/rx + offloaded tx/rx) - * @vdev_id: vdev id for which packet is captured - * @mon_buf_list: netbuf list - * @type: data process type - * @tid: tid number - * @status: Tx status - * @pktformat: Frame format - * @bssid: bssid - * @pdev: pdev handle - * @tx_retry_cnt: tx retry count - * - * Return: none - */ -static void -pkt_capture_tx_data_cb( - void *context, void *ppdev, void *nbuf_list, uint8_t vdev_id, - uint8_t tid, uint8_t status, bool pkt_format, - uint8_t *bssid, uint8_t tx_retry_cnt) -{ - qdf_nbuf_t msdu, next_buf; - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_vdev *vdev = context; - htt_pdev_handle pdev = ppdev; - struct pkt_capture_cb_context *cb_ctx; - uint8_t drop_count; - struct htt_tx_data_hdr_information *cmpl_desc = NULL; - struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0}; - struct ethernet_hdr_t *eth_hdr; - struct llc_snap_hdr_t *llc_hdr; - struct ieee80211_frame *wh; - uint8_t hdsize, new_hdsize; - struct ieee80211_qoscntl *qos_cntl; - uint16_t ether_type; - uint32_t headroom; - uint16_t seq_no, fc_ctrl; - struct mon_rx_status tx_status = {0}; - uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) + - sizeof(struct llc_snap_hdr_t)]; - const uint8_t ethernet_II_llc_snap_header_prefix[] = { - 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (qdf_unlikely(!vdev)) - goto free_buf; - - cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) - goto free_buf; - - msdu = nbuf_list; - while (msdu) { - next_buf = qdf_nbuf_queue_next(msdu); - qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */ - - cmpl_desc = (struct htt_tx_data_hdr_information *) - (qdf_nbuf_data(msdu)); - - pktcapture_hdr.timestamp = cmpl_desc->phy_timestamp_l32; - pktcapture_hdr.preamble = cmpl_desc->preamble; - pktcapture_hdr.mcs = cmpl_desc->mcs; - pktcapture_hdr.bw = cmpl_desc->bw; - pktcapture_hdr.nss = cmpl_desc->nss; - pktcapture_hdr.rssi_comb = cmpl_desc->rssi; - pktcapture_hdr.rate = cmpl_desc->rate; - pktcapture_hdr.stbc = cmpl_desc->stbc; - pktcapture_hdr.sgi = cmpl_desc->sgi; - pktcapture_hdr.ldpc = cmpl_desc->ldpc; - pktcapture_hdr.beamformed = cmpl_desc->beamformed; - pktcapture_hdr.status = status; - pktcapture_hdr.tx_retry_cnt = tx_retry_cnt; - - qdf_nbuf_pull_head( - msdu, - sizeof(struct htt_tx_data_hdr_information)); - - if (pkt_format == TXRX_PKTCAPTURE_PKT_FORMAT_8023) { - eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu); - hdsize = sizeof(struct ethernet_hdr_t); - wh = (struct ieee80211_frame *)localbuf; - - *(uint16_t *)wh->i_dur = 0; - - new_hdsize = 0; - - if (vdev_id == HTT_INVALID_VDEV) - qdf_mem_copy(bssid, eth_hdr->dest_addr, - QDF_MAC_ADDR_SIZE); - - /* BSSID , SA , DA */ - qdf_mem_copy(wh->i_addr1, bssid, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(wh->i_addr2, eth_hdr->src_addr, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(wh->i_addr3, eth_hdr->dest_addr, - QDF_MAC_ADDR_SIZE); - - seq_no = cmpl_desc->seqno; - seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) & - IEEE80211_SEQ_SEQ_MASK; - fc_ctrl = cmpl_desc->framectrl; - qdf_mem_copy(wh->i_fc, &fc_ctrl, sizeof(fc_ctrl)); - qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no)); - - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - - new_hdsize = sizeof(struct ieee80211_frame); - - if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) { - qos_cntl = (struct ieee80211_qoscntl *) - (localbuf + new_hdsize); - qos_cntl->i_qos[0] = - (tid & IEEE80211_QOS_TID); - qos_cntl->i_qos[1] = 0; - new_hdsize += sizeof(struct ieee80211_qoscntl); - } - /* - * Prepare llc Header - */ - llc_hdr = (struct llc_snap_hdr_t *) - (localbuf + new_hdsize); - ether_type = (eth_hdr->ethertype[0] << 8) | - (eth_hdr->ethertype[1]); - if (ether_type >= ETH_P_802_3_MIN) { - qdf_mem_copy( - llc_hdr, - ethernet_II_llc_snap_header_prefix, - sizeof - (ethernet_II_llc_snap_header_prefix)); - if (ether_type == ETHERTYPE_AARP || - ether_type == ETHERTYPE_IPX) { - llc_hdr->org_code[2] = - BTEP_SNAP_ORGCODE_2; - /* 0xf8; bridge tunnel header */ - } - llc_hdr->ethertype[0] = eth_hdr->ethertype[0]; - llc_hdr->ethertype[1] = eth_hdr->ethertype[1]; - new_hdsize += sizeof(struct llc_snap_hdr_t); - } - - /* - * Remove 802.3 Header by adjusting the head - */ - qdf_nbuf_pull_head(msdu, hdsize); - - /* - * Adjust the head and prepare 802.11 Header - */ - qdf_nbuf_push_head(msdu, new_hdsize); - qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize); - } - - pkt_capture_update_tx_status( - pdev, - &tx_status, - &pktcapture_hdr); - /* - * Calculate the headroom and adjust head - * to prepare radiotap header. - */ - headroom = qdf_nbuf_headroom(msdu); - qdf_nbuf_update_radiotap(&tx_status, msdu, headroom); - pkt_capture_mon(cb_ctx, msdu, vdev, 0); - msdu = next_buf; - } - return; - -free_buf: - drop_count = pkt_capture_drop_nbuf_list(nbuf_list); -} - -void pkt_capture_datapkt_process( - uint8_t vdev_id, - qdf_nbuf_t mon_buf_list, - enum pkt_capture_data_process_type type, - uint8_t tid, uint8_t status, bool pkt_format, - uint8_t *bssid, htt_pdev_handle pdev, - uint8_t tx_retry_cnt) -{ - uint8_t drop_count; - struct pkt_capture_mon_pkt *pkt; - pkt_capture_mon_thread_cb callback = NULL; - struct wlan_objmgr_vdev *vdev; - - status = pkt_capture_txrx_status_map(status); - vdev = pkt_capture_get_vdev(); - if (!vdev) - goto drop_rx_buf; - - pkt = pkt_capture_alloc_mon_pkt(vdev); - if (!pkt) - goto drop_rx_buf; - - switch (type) { - case TXRX_PROCESS_TYPE_DATA_RX: - callback = pkt_capture_rx_data_cb; - break; - case TXRX_PROCESS_TYPE_DATA_TX: - case TXRX_PROCESS_TYPE_DATA_TX_COMPL: - callback = pkt_capture_tx_data_cb; - break; - default: - return; - } - - pkt->callback = callback; - pkt->context = (void *)vdev; - pkt->pdev = (void *)pdev; - pkt->monpkt = (void *)mon_buf_list; - pkt->vdev_id = vdev_id; - pkt->tid = tid; - pkt->status = status; - pkt->pkt_format = pkt_format; - qdf_mem_copy(pkt->bssid, bssid, QDF_MAC_ADDR_SIZE); - pkt->tx_retry_cnt = tx_retry_cnt; - pkt_capture_indicate_monpkt(vdev, pkt); - return; - -drop_rx_buf: - drop_count = pkt_capture_drop_nbuf_list(mon_buf_list); -} - -struct htt_tx_data_hdr_information *pkt_capture_tx_get_txcomplete_data_hdr( - uint32_t *msg_word, - int num_msdus) -{ - int offset_dwords; - u_int32_t has_tx_tsf; - u_int32_t has_retry; - u_int32_t has_ack_rssi; - u_int32_t has_tx_tsf64; - u_int32_t has_tx_compl_payload; - struct htt_tx_compl_ind_append_retries *retry_list = NULL; - struct htt_tx_data_hdr_information *txcomplete_data_hrd_list = NULL; - - has_tx_compl_payload = HTT_TX_COMPL_IND_APPEND4_GET(*msg_word); - if (num_msdus <= 0 || !has_tx_compl_payload) - return NULL; - - offset_dwords = 1 + ((num_msdus + 1) >> 1); - - has_retry = HTT_TX_COMPL_IND_APPEND_GET(*msg_word); - if (has_retry) { - int retry_index = 0; - int width_for_each_retry = - (sizeof(struct htt_tx_compl_ind_append_retries) + - 3) >> 2; - - retry_list = (struct htt_tx_compl_ind_append_retries *) - (msg_word + offset_dwords); - while (retry_list) { - if (retry_list[retry_index++].flag == 0) - break; - } - offset_dwords += retry_index * width_for_each_retry; - } - has_tx_tsf = HTT_TX_COMPL_IND_APPEND1_GET(*msg_word); - if (has_tx_tsf) { - int width_for_each_tsf = - (sizeof(struct htt_tx_compl_ind_append_tx_tstamp)) >> 2; - offset_dwords += width_for_each_tsf * num_msdus; - } - - has_ack_rssi = HTT_TX_COMPL_IND_APPEND2_GET(*msg_word); - if (has_ack_rssi) - offset_dwords += ((num_msdus + 1) >> 1); - - has_tx_tsf64 = HTT_TX_COMPL_IND_APPEND3_GET(*msg_word); - if (has_tx_tsf64) - offset_dwords += (num_msdus << 1); - - txcomplete_data_hrd_list = (struct htt_tx_data_hdr_information *) - (msg_word + offset_dwords); - - return txcomplete_data_hrd_list; -} - -void pkt_capture_offload_deliver_indication_handler( - void *msg, uint8_t vdev_id, - uint8_t *bssid, htt_pdev_handle pdev) -{ - int nbuf_len; - qdf_nbuf_t netbuf; - uint8_t status; - uint8_t tid = 0; - bool pkt_format; - u_int32_t *msg_word = (u_int32_t *)msg; - u_int8_t *buf = (u_int8_t *)msg; - struct htt_tx_data_hdr_information *txhdr; - struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg; - - offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)msg; - - txhdr = (struct htt_tx_data_hdr_information *) - (msg_word + 1); - - nbuf_len = offload_deliver_msg->tx_mpdu_bytes; - - netbuf = qdf_nbuf_alloc(NULL, - roundup(nbuf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - - if (!netbuf) - return; - - qdf_nbuf_put_tail(netbuf, nbuf_len); - - qdf_mem_copy(qdf_nbuf_data(netbuf), - buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t), - nbuf_len); - - qdf_nbuf_push_head( - netbuf, - sizeof(struct htt_tx_data_hdr_information)); - - qdf_mem_copy(qdf_nbuf_data(netbuf), txhdr, - sizeof(struct htt_tx_data_hdr_information)); - - status = offload_deliver_msg->status; - pkt_format = offload_deliver_msg->format; - tid = offload_deliver_msg->tid_num; - - pkt_capture_datapkt_process( - vdev_id, - netbuf, TXRX_PROCESS_TYPE_DATA_TX, - tid, status, pkt_format, bssid, pdev, - offload_deliver_msg->tx_retry_cnt); -} diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_main.c index 324c38265f1f046ca44a1bb78489d11a1c764ba4..d64934664f20889b5ecbb9ebe42b1f3876af496e 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -23,21 +23,6 @@ #include "wlan_pkt_capture_main.h" #include "cfg_ucfg_api.h" -#include "wlan_pkt_capture_mon_thread.h" -#include "wlan_pkt_capture_mgmt_txrx.h" -#include "target_if_pkt_capture.h" -#include "cdp_txrx_ctrl.h" -#include "cds_utils.h" -#include "cdp_txrx_mon.h" -#include "wlan_policy_mgr_api.h" -#include "wlan_pkt_capture_tgt_api.h" - -static struct wlan_objmgr_vdev *gp_pkt_capture_vdev; - -struct wlan_objmgr_vdev *pkt_capture_get_vdev(void) -{ - return gp_pkt_capture_vdev; -} enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { @@ -57,289 +42,6 @@ enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) return psoc_priv->cfg_param.pkt_capture_mode; } -QDF_STATUS -pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t), - void *context) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_psoc *psoc; - enum pkt_capture_mode mode; - QDF_STATUS status; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return QDF_STATUS_E_INVAL; - } - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return QDF_STATUS_E_INVAL; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("vdev priv is NULL"); - return QDF_STATUS_E_INVAL; - } - - vdev_priv->cb_ctx->mon_cb = mon_cb; - vdev_priv->cb_ctx->mon_ctx = context; - - status = pkt_capture_mgmt_rx_ops(psoc, true); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to register pkt capture mgmt rx ops"); - goto mgmt_rx_ops_fail; - } - - target_if_pkt_capture_register_tx_ops(&vdev_priv->tx_ops); - target_if_pkt_capture_register_rx_ops(&vdev_priv->rx_ops); - pkt_capture_record_channel(vdev); - - status = tgt_pkt_capture_register_ev_handler(vdev); - if (QDF_IS_STATUS_ERROR(status)) - goto register_ev_handlers_fail; - - /* - * set register event bit so that mon thread will start - * processing packets in queue. - */ - set_bit(PKT_CAPTURE_REGISTER_EVENT, - &vdev_priv->mon_ctx->mon_event_flag); - - mode = pkt_capture_get_mode(psoc); - status = tgt_pkt_capture_send_mode(vdev, mode); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Unable to send packet capture mode to fw"); - goto send_mode_fail; - } - - return QDF_STATUS_SUCCESS; - -send_mode_fail: - tgt_pkt_capture_unregister_ev_handler(vdev); -register_ev_handlers_fail: - pkt_capture_mgmt_rx_ops(psoc, false); -mgmt_rx_ops_fail: - vdev_priv->cb_ctx->mon_cb = NULL; - vdev_priv->cb_ctx->mon_ctx = NULL; - - return status; -} - -QDF_STATUS pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_psoc *psoc; - QDF_STATUS status; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return QDF_STATUS_E_INVAL; - } - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return QDF_STATUS_E_INVAL; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("vdev priv is NULL"); - return QDF_STATUS_E_INVAL; - } - - status = tgt_pkt_capture_send_mode(vdev, PACKET_CAPTURE_MODE_DISABLE); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Unable to send packet capture mode to fw"); - - /* - * Clear packet capture register event so that mon thread will - * stop processing packets in queue. - */ - clear_bit(PKT_CAPTURE_REGISTER_EVENT, - &vdev_priv->mon_ctx->mon_event_flag); - set_bit(PKT_CAPTURE_RX_POST_EVENT, - &vdev_priv->mon_ctx->mon_event_flag); - wake_up_interruptible(&vdev_priv->mon_ctx->mon_wait_queue); - - /* - * Wait till current packet process completes in mon thread and - * flush the remaining packet in queue. - */ - wait_for_completion(&vdev_priv->mon_ctx->mon_register_event); - pkt_capture_drop_monpkt(vdev_priv->mon_ctx); - - status = tgt_pkt_capture_unregister_ev_handler(vdev); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Unable to unregister event handlers"); - - status = pkt_capture_mgmt_rx_ops(psoc, false); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Failed to unregister pkt capture mgmt rx ops"); - - vdev_priv->cb_ctx->mon_cb = NULL; - vdev_priv->cb_ctx->mon_ctx = NULL; - - return QDF_STATUS_SUCCESS; -} - -void pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, - enum pkt_capture_mode mode) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_vdev *vdev; - - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return; - } - - vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - WLAN_PKT_CAPTURE_ID); - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (vdev_priv) - vdev_priv->cb_ctx->pkt_capture_mode = mode; - else - pkt_capture_err("vdev_priv is NULL"); - - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); -} - -enum pkt_capture_mode -pkt_capture_get_pktcap_mode(void) -{ - enum pkt_capture_mode mode = PACKET_CAPTURE_MODE_DISABLE; - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_vdev *vdev; - struct wlan_objmgr_psoc *psoc; - - if (!gp_pkt_capture_vdev) - return PACKET_CAPTURE_MODE_DISABLE; - - psoc = wlan_vdev_get_psoc(gp_pkt_capture_vdev); - - - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return 0; - } - - if (!pkt_capture_get_mode(psoc)) - return 0; - - vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - WLAN_PKT_CAPTURE_ID); - if (!vdev) - return 0; - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) - pkt_capture_err("vdev_priv is NULL"); - else - mode = vdev_priv->cb_ctx->pkt_capture_mode; - - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); - return mode; -} - -/** - * pkt_capture_callback_ctx_create() - Create packet capture callback context - * @vdev_priv: pointer to packet capture vdev priv obj - * - * Return: QDF_STATUS - */ -static QDF_STATUS -pkt_capture_callback_ctx_create(struct pkt_capture_vdev_priv *vdev_priv) -{ - struct pkt_capture_cb_context *cb_ctx; - - cb_ctx = qdf_mem_malloc(sizeof(*cb_ctx)); - if (!cb_ctx) { - pkt_capture_err("MON context create failed"); - return QDF_STATUS_E_NOMEM; - } - - vdev_priv->cb_ctx = cb_ctx; - - return QDF_STATUS_SUCCESS; -} - -/** - * pkt_capture_callback_ctx_destroy() - Destroy packet capture callback context - * @vdev_priv: pointer to packet capture vdev priv obj - * - * Return: None - */ -static void -pkt_capture_callback_ctx_destroy(struct pkt_capture_vdev_priv *vdev_priv) -{ - qdf_mem_free(vdev_priv->cb_ctx); -} - -/** - * pkt_capture_mon_context_create() - Create packet capture mon context - * @vdev_priv: pointer to packet capture vdev priv obj - * - * This function allocates memory for packet capture mon context - * - * Return: QDF_STATUS - */ -static QDF_STATUS -pkt_capture_mon_context_create(struct pkt_capture_vdev_priv *vdev_priv) -{ - struct pkt_capture_mon_context *mon_context; - - mon_context = qdf_mem_malloc(sizeof(*mon_context)); - if (!mon_context) { - pkt_capture_err("MON context create failed"); - return QDF_STATUS_E_NOMEM; - } - - vdev_priv->mon_ctx = mon_context; - - return QDF_STATUS_SUCCESS; -} - -/** - * pkt_capture_mon_context_destroy() - Destroy packet capture mon context - * @vdev_priv: pointer to packet capture vdev priv obj - * - * Free packet capture mon context - * - * Return: None - */ -static void -pkt_capture_mon_context_destroy(struct pkt_capture_vdev_priv *vdev_priv) -{ - qdf_mem_free(vdev_priv->mon_ctx); -} - -uint32_t pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list) -{ - qdf_nbuf_t buf, next_buf; - uint32_t num_dropped = 0; - - buf = buf_list; - while (buf) { - QDF_NBUF_CB_RX_PEER_CACHED_FRM(buf) = 1; - next_buf = qdf_nbuf_queue_next(buf); - qdf_nbuf_free(buf); - buf = next_buf; - num_dropped++; - } - return num_dropped; -} - /** * pkt_capture_cfg_init() - Initialize packet capture cfg ini params * @psoc_priv: psoc private object @@ -360,14 +62,9 @@ pkt_capture_cfg_init(struct pkt_psoc_priv *psoc_priv) QDF_STATUS pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg) { - struct pkt_capture_mon_context *mon_ctx; struct pkt_capture_vdev_priv *vdev_priv; QDF_STATUS status; - if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || - !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev))) - return QDF_STATUS_SUCCESS; - vdev_priv = qdf_mem_malloc(sizeof(*vdev_priv)); if (!vdev_priv) return QDF_STATUS_E_NOMEM; @@ -382,45 +79,8 @@ pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg) } vdev_priv->vdev = vdev; - gp_pkt_capture_vdev = vdev; - - status = pkt_capture_callback_ctx_create(vdev_priv); - if (!QDF_IS_STATUS_SUCCESS(status)) { - pkt_capture_err("Failed to create callback context"); - goto detach_vdev_priv; - } - - status = pkt_capture_mon_context_create(vdev_priv); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to create mon context"); - goto destroy_pkt_capture_cb_context; - } - - mon_ctx = vdev_priv->mon_ctx; - - status = pkt_capture_alloc_mon_thread(mon_ctx); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to alloc mon thread"); - goto destroy_mon_context; - } - - status = pkt_capture_open_mon_thread(mon_ctx); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to open mon thread"); - goto open_mon_thread_fail; - } return status; -open_mon_thread_fail: - pkt_capture_free_mon_pkt_freeq(mon_ctx); -destroy_mon_context: - pkt_capture_mon_context_destroy(vdev_priv); -destroy_pkt_capture_cb_context: - pkt_capture_callback_ctx_destroy(vdev_priv); -detach_vdev_priv: - wlan_objmgr_vdev_component_obj_detach(vdev, - WLAN_UMAC_COMP_PKT_CAPTURE, - vdev_priv); free_vdev_priv: qdf_mem_free(vdev_priv); return status; @@ -432,10 +92,6 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) struct pkt_capture_vdev_priv *vdev_priv; QDF_STATUS status; - if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) || - !pkt_capture_get_mode(wlan_vdev_get_psoc(vdev))) - return QDF_STATUS_SUCCESS; - vdev_priv = pkt_capture_vdev_get_priv(vdev); if (!vdev_priv) { pkt_capture_err("vdev priv is NULL"); @@ -449,11 +105,7 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) if (QDF_IS_STATUS_ERROR(status)) pkt_capture_err("Failed to detach vdev component obj"); - pkt_capture_close_mon_thread(vdev_priv->mon_ctx); - pkt_capture_mon_context_destroy(vdev_priv); - pkt_capture_callback_ctx_destroy(vdev_priv); qdf_mem_free(vdev_priv); - gp_pkt_capture_vdev = NULL; return status; } @@ -508,40 +160,3 @@ pkt_capture_psoc_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg) qdf_mem_free(psoc_priv); return status; } - -void pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev) -{ - struct wlan_objmgr_pdev *pdev; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - uint8_t chan; - struct wlan_objmgr_psoc *psoc; - uint8_t vdev_id; - QDF_STATUS status; - - if (!gp_pkt_capture_vdev) { - pkt_capture_err("gp_pkt_capture_vdev is NULL"); - return; - } - - pdev = wlan_vdev_get_pdev(gp_pkt_capture_vdev); - if (!pdev) { - pkt_capture_err("pdev is NULL"); - return; - } - - vdev_id = wlan_vdev_get_id(gp_pkt_capture_vdev); - psoc = wlan_vdev_get_psoc(gp_pkt_capture_vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return; - } - - status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &chan); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to get channel"); - return; - } - - cdp_pktcapture_record_channel(soc, wlan_objmgr_pdev_get_pdev_id(pdev), - chan); -} diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c deleted file mode 100644 index 04c60b36004fff25db0b4fdee3d426e88e2b1397..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Implement mgmt txrx APIs which shall be used internally only - * in pkt_capture component. - * Note: These APIs should be never accessed out of pkt_capture component. - */ - -#include "wlan_pkt_capture_main.h" -#include "wlan_pkt_capture_priv.h" -#include "wlan_pkt_capture_mgmt_txrx.h" -#include "wlan_mlme_main.h" -#include "wlan_lmac_if_api.h" -#include "wlan_mgmt_txrx_utils_api.h" -#include "wlan_utility.h" -#include "cds_ieee80211_common.h" -#include "wmi_unified.h" - -enum pkt_capture_tx_status -pkt_capture_mgmt_status_map(uint8_t status) -{ - enum pkt_capture_tx_status tx_status; - - switch (status) { - case WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK: - tx_status = pkt_capture_tx_status_ok; - break; - case WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK: - tx_status = pkt_capture_tx_status_no_ack; - break; - default: - tx_status = pkt_capture_tx_status_discard; - break; - } - - return tx_status; -} - -/** - * pkt_capture_mgmtpkt_cb() - callback to process management packets - * for pkt capture mode - * @context: vdev handler - * @nbuf_list: netbuf list - * @vdev_id: vdev id for which packet is captured - * @tid: tid number - * @chan_num: Channel number - * @pkt_format: Frame format - * @tx_retry_cnt: tx retry count - * - * Return: none - */ -static void -pkt_capture_mgmtpkt_cb(void *context, void *ppdev, void *nbuf_list, - uint8_t vdev_id, uint8_t tid, uint8_t chan_num, - bool pkt_format, uint8_t *bssid, uint8_t tx_retry_cnt) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_objmgr_psoc *psoc = context; - struct pkt_capture_cb_context *cb_ctx; - struct wlan_objmgr_vdev *vdev; - qdf_nbuf_t msdu, next_buf; - uint32_t drop_count; - - vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - WLAN_PKT_CAPTURE_ID); - if (!vdev) { - pkt_capture_err("vdev is NULL"); - goto free_buf; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - goto release_vdev_ref; - } - - cb_ctx = vdev_priv->cb_ctx; - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { - pkt_capture_err("mon cb params are NULL"); - goto release_vdev_ref; - } - - msdu = nbuf_list; - while (msdu) { - next_buf = qdf_nbuf_queue_next(msdu); - qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */ - pkt_capture_mon(cb_ctx, msdu, vdev, chan_num); - msdu = next_buf; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); - return; - -release_vdev_ref: - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); -free_buf: - drop_count = pkt_capture_drop_nbuf_list(nbuf_list); - pkt_capture_debug("Dropped frames %u", drop_count); -} - -/** - * pkt_capture_mgmtpkt_process() - process management packets - * for pkt capture mode - * @psoc: pointer to psoc object - * @txrx_status: mon_rx_status to update radiotap header - * @nbuf: netbuf - * @status: Tx status - * - * Return: QDF_STATUS Enumeration - */ -static QDF_STATUS -pkt_capture_mgmtpkt_process(struct wlan_objmgr_psoc *psoc, - struct mon_rx_status *txrx_status, - qdf_nbuf_t nbuf, uint8_t status) -{ - struct wlan_objmgr_vdev *vdev; - struct pkt_capture_mon_pkt *pkt; - uint32_t headroom; - - vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - WLAN_PKT_CAPTURE_ID); - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return QDF_STATUS_E_FAILURE; - } - - /* - * Calculate the headroom and adjust head to prepare radiotap header - */ - headroom = qdf_nbuf_headroom(nbuf); - qdf_nbuf_update_radiotap(txrx_status, nbuf, headroom); - - pkt = pkt_capture_alloc_mon_pkt(vdev); - if (!pkt) { - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); - return QDF_STATUS_E_FAILURE; - } - - pkt->callback = pkt_capture_mgmtpkt_cb; - pkt->context = psoc; - pkt->monpkt = nbuf; - pkt->vdev_id = WLAN_INVALID_VDEV_ID; - pkt->tid = WLAN_INVALID_TID; - pkt->status = txrx_status->chan_num; - pkt->pkt_format = PKTCAPTURE_PKT_FORMAT_80211; - pkt_capture_indicate_monpkt(vdev, pkt); - - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); - return QDF_STATUS_SUCCESS; -} - -/** - * pkt_capture_is_rmf_enabled - API to check if rmf is enabled or not - * @pdev: pointer to pdev object - * @psoc: pointer to psoc object - * @addr: mac address - */ -static bool -pkt_capture_is_rmf_enabled(struct wlan_objmgr_pdev *pdev, - struct wlan_objmgr_psoc *psoc, - uint8_t *addr) -{ - struct pkt_psoc_priv *psoc_priv; - struct wlan_objmgr_vdev *vdev; - uint8_t vdev_id; - int rmf_enabled; - - psoc_priv = pkt_capture_psoc_get_priv(psoc); - if (!psoc_priv) { - pkt_capture_err("psoc priv is NULL"); - return false; - } - - vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, - addr, - WLAN_PKT_CAPTURE_ID); - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return false; - } - - vdev_id = wlan_vdev_get_id(vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); - - rmf_enabled = psoc_priv->cb_obj.get_rmf_status(vdev_id); - if (rmf_enabled < 0) { - pkt_capture_err("unable to get rmf status"); - return false; - } - - return true; -} - -/** - * pkt_capture_process_rmf_frame - process rmf frame - * @pdev: pointer to pdev object - * @psoc: pointer to psoc object - * @nbuf: netbuf - */ -static QDF_STATUS -pkt_capture_process_rmf_frame(struct wlan_objmgr_pdev *pdev, - struct wlan_objmgr_psoc *psoc, - qdf_nbuf_t nbuf) -{ - tpSirMacFrameCtl pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf)); - uint8_t mic_len, hdr_len, pdev_id; - struct ieee80211_frame *wh; - uint8_t *orig_hdr; - - wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); - - if (!QDF_IS_ADDR_BROADCAST(wh->i_addr1) && - !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - if (pfc->wep) { - QDF_STATUS status; - - orig_hdr = (uint8_t *)qdf_nbuf_data(nbuf); - pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); - status = mlme_get_peer_mic_len(psoc, pdev_id, - wh->i_addr1, - &mic_len, - &hdr_len); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Failed to get mic hdr"); - return QDF_STATUS_E_FAILURE; - } - - /* Strip privacy headers (and trailer) - * for a received frame - */ - qdf_mem_move(orig_hdr + hdr_len, wh, sizeof(*wh)); - qdf_nbuf_pull_head(nbuf, hdr_len); - qdf_nbuf_trim_tail(nbuf, mic_len); - } - } else { - qdf_nbuf_trim_tail(nbuf, IEEE80211_MMIE_LEN); - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS -pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, - struct mgmt_offload_event_params *params, - qdf_nbuf_t nbuf, - uint8_t status) -{ - struct mon_rx_status txrx_status = {0}; - struct wlan_objmgr_psoc *psoc; - tpSirMacFrameCtl pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf)); - struct ieee80211_frame *wh; - - psoc = wlan_pdev_get_psoc(pdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return QDF_STATUS_E_FAILURE; - } - - wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); - - if ((pfc->type == IEEE80211_FC0_TYPE_MGT) && - (pfc->subType == SIR_MAC_MGMT_DISASSOC || - pfc->subType == SIR_MAC_MGMT_DEAUTH || - pfc->subType == SIR_MAC_MGMT_ACTION)) { - if (pkt_capture_is_rmf_enabled(pdev, psoc, wh->i_addr2)) { - QDF_STATUS status; - - status = pkt_capture_process_rmf_frame(pdev, psoc, - nbuf); - if (QDF_IS_STATUS_ERROR(status)) - return status; - } - } - - txrx_status.tsft = (u_int64_t)params->tsf_l32; - txrx_status.chan_num = wlan_freq_to_chan(params->chan_freq); - txrx_status.chan_freq = params->chan_freq; - /* params->rate is in Kbps, convert into Mbps */ - txrx_status.rate = (params->rate_kbps / 1000); - if (params->rssi == INVALID_RSSI_FOR_TX) - /* RSSI -128 is invalid rssi for TX, make it 0 here, - * will be normalized during radiotap updation - */ - txrx_status.ant_signal_db = 0; - else - txrx_status.ant_signal_db = params->rssi; - - txrx_status.rssi_comb = txrx_status.ant_signal_db; - txrx_status.nr_ant = 1; - txrx_status.rtap_flags |= - ((txrx_status.rate == 6 /* Mbps */) ? BIT(1) : 0); - - if (txrx_status.rate == 6) - txrx_status.ofdm_flag = 1; - else - txrx_status.cck_flag = 1; - - txrx_status.rate = ((txrx_status.rate == 6 /* Mbps */) ? 0x0c : 0x02); - txrx_status.tx_status = status; - txrx_status.tx_retry_cnt = params->tx_retry_cnt; - txrx_status.add_rtap_ext = true; - - wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - - return pkt_capture_mgmtpkt_process(psoc, &txrx_status, - nbuf, status); -} - -void pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, - qdf_nbuf_t nbuf, - uint16_t chan_freq, - uint8_t preamble_type) -{ - qdf_nbuf_t wbuf; - int nbuf_len; - struct mgmt_offload_event_params params = {0}; - - if (!pdev) { - pkt_capture_err("pdev is NULL"); - return; - } - - nbuf_len = qdf_nbuf_len(nbuf); - wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - if (!wbuf) { - pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)", - nbuf_len); - return; - } - - qdf_nbuf_put_tail(wbuf, nbuf_len); - qdf_mem_copy(qdf_nbuf_data(wbuf), qdf_nbuf_data(nbuf), nbuf_len); - - params.chan_freq = chan_freq; - /* - * Filling Tpc in rssi field. - * As Tpc is not available, filling with default value of tpc - */ - params.rssi = 0; - /* Assigning the local timestamp as TSF timestamp is not available*/ - params.tsf_l32 = (uint32_t)jiffies; - - if (preamble_type == (1 << WMI_RATE_PREAMBLE_CCK)) - params.rate_kbps = 1000; /* Rate is 1 Mbps for CCK */ - else - params.rate_kbps = 6000; /* Rate is 6 Mbps for OFDM */ - - /* - * The mgmt tx packet is send to mon interface before tx completion. - * we do not have status for this packet, using magic number(0xFF) - * as status for mgmt tx packet - */ - if (QDF_STATUS_SUCCESS != - pkt_capture_process_mgmt_tx_data(pdev, ¶ms, wbuf, 0xFF)) - qdf_nbuf_free(wbuf); -} - -void -pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, - uint32_t desc_id, - uint32_t status, - struct mgmt_offload_event_params *params) -{ - qdf_nbuf_t wbuf, nbuf; - int nbuf_len; - - if (!pdev) { - pkt_capture_err("pdev is NULL"); - return; - } - - nbuf = mgmt_txrx_get_nbuf(pdev, desc_id); - if (!nbuf) - return; - - nbuf_len = qdf_nbuf_len(nbuf); - wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - if (!wbuf) { - pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)", - nbuf_len); - return; - } - - qdf_nbuf_put_tail(wbuf, nbuf_len); - qdf_mem_copy(qdf_nbuf_data(wbuf), qdf_nbuf_data(nbuf), nbuf_len); - - if (QDF_STATUS_SUCCESS != - pkt_capture_process_mgmt_tx_data( - pdev, params, wbuf, - pkt_capture_mgmt_status_map(status))) - qdf_nbuf_free(wbuf); -} - -/** - * process_pktcapture_mgmt_rx_data_cb() - process management rx packets - * @rx_params: mgmt rx event params - * @wbuf: netbuf - * - * Return: none - */ -static QDF_STATUS -pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_peer *peer, - qdf_nbuf_t wbuf, - struct mgmt_rx_event_params *rx_params, - enum mgmt_frame_type frm_type) -{ - struct mon_rx_status txrx_status = {0}; - struct ieee80211_frame *wh; - tpSirMacFrameCtl pfc; - qdf_nbuf_t nbuf; - int buf_len; - struct wlan_objmgr_vdev *vdev; - - if (!(pkt_capture_get_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY)) { - qdf_nbuf_free(wbuf); - return QDF_STATUS_E_FAILURE; - } - - buf_len = qdf_nbuf_len(wbuf); - nbuf = qdf_nbuf_alloc(NULL, roundup( - buf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - if (!nbuf) { - qdf_nbuf_free(wbuf); - return QDF_STATUS_E_FAILURE; - } - - qdf_nbuf_put_tail(nbuf, buf_len); - qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_data(wbuf), buf_len); - - qdf_nbuf_free(wbuf); - - pfc = (tpSirMacFrameCtl)(qdf_nbuf_data(nbuf)); - wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); - - if ((pfc->type == IEEE80211_FC0_TYPE_MGT) && - (pfc->subType == SIR_MAC_MGMT_DISASSOC || - pfc->subType == SIR_MAC_MGMT_DEAUTH || - pfc->subType == SIR_MAC_MGMT_ACTION)) { - struct wlan_objmgr_pdev *pdev; - - vdev = pkt_capture_get_vdev(); - pdev = wlan_vdev_get_pdev(vdev); - if (pkt_capture_is_rmf_enabled(pdev, psoc, wh->i_addr1)) { - QDF_STATUS status; - - status = pkt_capture_process_rmf_frame(pdev, psoc, - nbuf); - if (QDF_IS_STATUS_ERROR(status)) - return status; - } - } - - - txrx_status.tsft = (u_int64_t)rx_params->tsf_delta; - txrx_status.chan_num = rx_params->channel; - txrx_status.chan_freq = wlan_chan_to_freq(txrx_status.chan_num); - /* rx_params->rate is in Kbps, convert into Mbps */ - txrx_status.rate = (rx_params->rate / 1000); - txrx_status.ant_signal_db = rx_params->snr; - txrx_status.rssi_comb = rx_params->snr; - txrx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR; - txrx_status.nr_ant = 1; - txrx_status.rtap_flags |= - ((txrx_status.rate == 6 /* Mbps */) ? BIT(1) : 0); - - if (txrx_status.rate == 6) - txrx_status.ofdm_flag = 1; - else - txrx_status.cck_flag = 1; - - txrx_status.rate = ((txrx_status.rate == 6 /* Mbps */) ? 0x0c : 0x02); - txrx_status.add_rtap_ext = true; - - wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; - - if (QDF_STATUS_SUCCESS != - pkt_capture_mgmtpkt_process(psoc, &txrx_status, nbuf, 0)) - qdf_nbuf_free(nbuf); - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, - bool is_register) -{ - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; - QDF_STATUS status; - int num_of_entries; - - frm_cb_info.frm_type = MGMT_FRAME_TYPE_ALL; - frm_cb_info.mgmt_rx_cb = pkt_capture_mgmt_rx_data_cb; - num_of_entries = 1; - - if (is_register) - status = wlan_mgmt_txrx_register_rx_cb( - psoc, WLAN_UMAC_COMP_PKT_CAPTURE, - &frm_cb_info, num_of_entries); - else - status = wlan_mgmt_txrx_deregister_rx_cb( - psoc, WLAN_UMAC_COMP_PKT_CAPTURE, - &frm_cb_info, num_of_entries); - - return status; -} diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c b/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c deleted file mode 100644 index 13f374f4aa007173eaa157d084eb73b045eea69b..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/core/src/wlan_pkt_capture_mon_thread.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Define internal APIs related to the packet capture component - */ - -#include "wlan_pkt_capture_mon_thread.h" -#include -#include "cds_ieee80211_common.h" -#include -#include "cds_utils.h" -#include "cdp_txrx_mon.h" - -void pkt_capture_mon(struct pkt_capture_cb_context *cb_ctx, - qdf_nbuf_t msdu, struct wlan_objmgr_vdev *vdev, - uint8_t chan_num) -{ - struct radiotap_header *rthdr; - uint8_t rtlen; - tSirMacFrameCtl *fc; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); - - rthdr = (struct radiotap_header *)qdf_nbuf_data(msdu); - rtlen = rthdr->it_len; - fc = (tSirMacFrameCtl *)(qdf_nbuf_data(msdu) + rtlen); - - if ((fc->type == SIR_MAC_DATA_FRAME) && - (fc->subType == SIR_MAC_DATA_QOS_NULL)) { - qdf_nbuf_free(msdu); - return; - } - - if ((fc->type == SIR_MAC_MGMT_FRAME) && - (fc->subType == SIR_MAC_MGMT_AUTH)) { - cdp_pktcapture_record_channel( - soc, - wlan_objmgr_pdev_get_pdev_id(pdev), chan_num); - } - - if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { - pkt_capture_err("Monitor interface is deleted now"); - qdf_nbuf_free(msdu); - } - - if (cb_ctx->mon_cb(cb_ctx->mon_ctx, msdu) != QDF_STATUS_SUCCESS) { - pkt_capture_err("Frame Rx to HDD failed"); - qdf_nbuf_free(msdu); - } -} - -void pkt_capture_free_mon_pkt_freeq(struct pkt_capture_mon_context *mon_ctx) -{ - struct pkt_capture_mon_pkt *pkt; - - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - while (!list_empty(&mon_ctx->mon_pkt_freeq)) { - pkt = list_entry((&mon_ctx->mon_pkt_freeq)->next, - typeof(*pkt), list); - list_del(&pkt->list); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - qdf_mem_free(pkt); - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - } - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); -} - -/** - * pkt_capture_alloc_mon_pkt_freeq() - Function to allocate free buffer queue - * @mon_ctx: pointer to packet capture mon context - * - * This API allocates MAX_MON_PKT_SIZE number of mon packets - * which are used for mon data processing. - * - * Return: QDF_STATUS - */ -static QDF_STATUS -pkt_capture_alloc_mon_pkt_freeq(struct pkt_capture_mon_context *mon_ctx) -{ - struct pkt_capture_mon_pkt *pkt, *tmp; - int i; - - for (i = 0; i < MAX_MON_PKT_SIZE; i++) { - pkt = qdf_mem_malloc(sizeof(*pkt)); - if (!pkt) { - pkt_capture_err("mon packet freeq allocation fail"); - goto free; - } - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - list_add_tail(&pkt->list, - &mon_ctx->mon_pkt_freeq); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - } - - return QDF_STATUS_SUCCESS; -free: - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - list_for_each_entry_safe(pkt, tmp, - &mon_ctx->mon_pkt_freeq, - list) { - list_del(&pkt->list); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - qdf_mem_free(pkt); - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - } - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - - return QDF_STATUS_E_NOMEM; -} - -/** - * pkt_capture_free_mon_pkt() - api to release mon packet to the freeq - * @mon_ctx: Pointer to packet capture mon context - * @pkt: MON packet buffer to be returned to free queue. - * - * This api returns the mon packet used for mon data to the free queue - * - * Return: None - */ -static void -pkt_capture_free_mon_pkt(struct pkt_capture_mon_context *mon_ctx, - struct pkt_capture_mon_pkt *pkt) -{ - memset(pkt, 0, sizeof(*pkt)); - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - list_add_tail(&pkt->list, &mon_ctx->mon_pkt_freeq); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); -} - -struct pkt_capture_mon_pkt * -pkt_capture_alloc_mon_pkt(struct wlan_objmgr_vdev *vdev) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct pkt_capture_mon_context *mon_ctx; - struct pkt_capture_mon_pkt *pkt; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return NULL; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - return NULL; - } - - mon_ctx = vdev_priv->mon_ctx; - if (!mon_ctx) { - pkt_capture_err("packet capture mon context is NULL"); - return NULL; - } - - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - if (list_empty(&mon_ctx->mon_pkt_freeq)) { - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - return NULL; - } - - pkt = list_first_entry(&mon_ctx->mon_pkt_freeq, - struct pkt_capture_mon_pkt, list); - list_del(&pkt->list); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - - return pkt; -} - -void pkt_capture_indicate_monpkt(struct wlan_objmgr_vdev *vdev, - struct pkt_capture_mon_pkt *pkt) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct pkt_capture_mon_context *mon_ctx; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - return; - } - mon_ctx = vdev_priv->mon_ctx; - - spin_lock_bh(&mon_ctx->mon_queue_lock); - list_add_tail(&pkt->list, &mon_ctx->mon_thread_queue); - spin_unlock_bh(&mon_ctx->mon_queue_lock); - set_bit(PKT_CAPTURE_RX_POST_EVENT, &mon_ctx->mon_event_flag); - wake_up_interruptible(&mon_ctx->mon_wait_queue); -} - -void pkt_capture_wakeup_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct pkt_capture_mon_context *mon_ctx; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - return; - } - mon_ctx = vdev_priv->mon_ctx; - - set_bit(PKT_CAPTURE_RX_POST_EVENT, &mon_ctx->mon_event_flag); - wake_up_interruptible(&mon_ctx->mon_wait_queue); -} - -/** - * pkt_capture_process_from_queue() - function to process pending mon packets - * @mon_ctx: Pointer to packet capture mon context - * - * This api traverses the pending buffer list and calling the callback. - * This callback would essentially send the packet to HDD. - * - * Return: None - */ -static void -pkt_capture_process_from_queue(struct pkt_capture_mon_context *mon_ctx) -{ - struct pkt_capture_mon_pkt *pkt; - uint8_t vdev_id; - uint8_t tid; - - spin_lock_bh(&mon_ctx->mon_queue_lock); - while (!list_empty(&mon_ctx->mon_thread_queue)) { - pkt = list_first_entry(&mon_ctx->mon_thread_queue, - struct pkt_capture_mon_pkt, list); - list_del(&pkt->list); - spin_unlock_bh(&mon_ctx->mon_queue_lock); - vdev_id = pkt->vdev_id; - tid = pkt->tid; - pkt->callback(pkt->context, pkt->pdev, pkt->monpkt, vdev_id, - tid, pkt->status, pkt->pkt_format, pkt->bssid, - pkt->tx_retry_cnt); - pkt_capture_free_mon_pkt(mon_ctx, pkt); - spin_lock_bh(&mon_ctx->mon_queue_lock); - } - spin_unlock_bh(&mon_ctx->mon_queue_lock); -} - -/** - * pkt_capture_mon_thread() - packet capture mon thread - * @arg: Pointer to vdev object manager - * - * This api is the thread handler for mon Data packet processing. - * - * Return: thread exit code - */ -static int pkt_capture_mon_thread(void *arg) -{ - struct pkt_capture_mon_context *mon_ctx; - unsigned long pref_cpu = 0; - bool shutdown = false; - int status, i; - - if (!arg) { - pkt_capture_err("Bad Args passed to mon thread"); - return 0; - } - mon_ctx = (struct pkt_capture_mon_context *)arg; - set_user_nice(current, -1); -#ifdef MSM_PLATFORM - set_wake_up_idle(true); -#endif - - /** - * Find the available cpu core other than cpu 0 and - * bind the thread - */ - for_each_online_cpu(i) { - if (i == 0) - continue; - pref_cpu = i; - break; - } - - set_cpus_allowed_ptr(current, cpumask_of(pref_cpu)); - - complete(&mon_ctx->mon_start_event); - - while (!shutdown) { - status = - wait_event_interruptible(mon_ctx->mon_wait_queue, - test_bit(PKT_CAPTURE_RX_POST_EVENT, - &mon_ctx->mon_event_flag) || - test_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag)); - if (status == -ERESTARTSYS) - break; - - clear_bit(PKT_CAPTURE_RX_POST_EVENT, - &mon_ctx->mon_event_flag); - while (true) { - if (test_bit(PKT_CAPTURE_RX_SHUTDOWN_EVENT, - &mon_ctx->mon_event_flag)) { - clear_bit(PKT_CAPTURE_RX_SHUTDOWN_EVENT, - &mon_ctx->mon_event_flag); - if (test_bit( - PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag)) { - clear_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag); - complete(&mon_ctx->suspend_mon_event); - } - pkt_capture_info("Shutting down pktcap thread"); - shutdown = true; - break; - } - - /* - * if packet capture deregistratin happens stop - * processing packets in queue because mon cb will - * be set to NULL. - */ - if (test_bit(PKT_CAPTURE_REGISTER_EVENT, - &mon_ctx->mon_event_flag)) - pkt_capture_process_from_queue(mon_ctx); - else - complete(&mon_ctx->mon_register_event); - - if (test_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag)) { - clear_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag); - spin_lock(&mon_ctx->mon_thread_lock); - INIT_COMPLETION(mon_ctx->resume_mon_event); - complete(&mon_ctx->suspend_mon_event); - spin_unlock(&mon_ctx->mon_thread_lock); - wait_for_completion_interruptible - (&mon_ctx->resume_mon_event); - } - break; - } - } - pkt_capture_debug("Exiting packet capture mon thread"); - complete_and_exit(&mon_ctx->mon_shutdown, 0); - - return 0; -} - -void pkt_capture_close_mon_thread(struct pkt_capture_mon_context *mon_ctx) -{ - if (!mon_ctx->mon_thread) - return; - - /* Shut down mon thread */ - set_bit(PKT_CAPTURE_RX_SHUTDOWN_EVENT, - &mon_ctx->mon_event_flag); - set_bit(PKT_CAPTURE_RX_POST_EVENT, - &mon_ctx->mon_event_flag); - wake_up_interruptible(&mon_ctx->mon_wait_queue); - wait_for_completion(&mon_ctx->mon_shutdown); - mon_ctx->mon_thread = NULL; - pkt_capture_drop_monpkt(mon_ctx); - pkt_capture_free_mon_pkt_freeq(mon_ctx); -} - -QDF_STATUS -pkt_capture_open_mon_thread(struct pkt_capture_mon_context *mon_ctx) -{ - mon_ctx->mon_thread = kthread_create(pkt_capture_mon_thread, - mon_ctx, - "pkt_capture_mon_thread"); - - if (IS_ERR(mon_ctx->mon_thread)) { - pkt_capture_fatal("Could not Create packet capture mon thread"); - return QDF_STATUS_E_FAILURE; - } - wake_up_process(mon_ctx->mon_thread); - pkt_capture_debug("packet capture MON thread Created"); - - wait_for_completion_interruptible(&mon_ctx->mon_start_event); - pkt_capture_debug("packet capture MON Thread has started"); - - return QDF_STATUS_SUCCESS; -} - -void pkt_capture_drop_monpkt(struct pkt_capture_mon_context *mon_ctx) -{ - struct pkt_capture_mon_pkt *pkt, *tmp; - struct list_head local_list; - qdf_nbuf_t buf, next_buf; - - INIT_LIST_HEAD(&local_list); - spin_lock_bh(&mon_ctx->mon_queue_lock); - if (list_empty(&mon_ctx->mon_thread_queue)) { - spin_unlock_bh(&mon_ctx->mon_queue_lock); - return; - } - list_for_each_entry_safe(pkt, tmp, - &mon_ctx->mon_thread_queue, - list) - list_move_tail(&pkt->list, &local_list); - - spin_unlock_bh(&mon_ctx->mon_queue_lock); - - list_for_each_entry_safe(pkt, tmp, &local_list, list) { - list_del(&pkt->list); - buf = pkt->monpkt; - while (buf) { - next_buf = qdf_nbuf_queue_next(buf); - qdf_nbuf_free(buf); - buf = next_buf; - } - pkt_capture_free_mon_pkt(mon_ctx, pkt); - } -} - -int pkt_capture_suspend_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct pkt_capture_mon_context *mon_ctx; - int rc; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return -EINVAL; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - return -EINVAL; - } - mon_ctx = vdev_priv->mon_ctx; - if (!mon_ctx) { - pkt_capture_err("packet capture mon context is NULL"); - return -EINVAL; - } - - set_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag); - wake_up_interruptible(&mon_ctx->mon_wait_queue); - rc = wait_for_completion_timeout( - &mon_ctx->suspend_mon_event, - msecs_to_jiffies(PKT_CAPTURE_SUSPEND_TIMEOUT)); - if (!rc) { - clear_bit(PKT_CAPTURE_RX_SUSPEND_EVENT, - &mon_ctx->mon_event_flag); - pkt_capture_err("Failed to suspend packet capture mon thread"); - return -EINVAL; - } - mon_ctx->is_mon_thread_suspended = true; - - return 0; -} - -void pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - struct pkt_capture_vdev_priv *vdev_priv; - struct pkt_capture_mon_context *mon_ctx; - - if (!vdev) { - pkt_capture_err("vdev is NULL"); - return; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("packet capture vdev priv is NULL"); - return; - } - mon_ctx = vdev_priv->mon_ctx; - if (!mon_ctx) { - pkt_capture_err("packet capture mon context is NULL"); - return; - } - - if (mon_ctx->is_mon_thread_suspended) - complete(&mon_ctx->resume_mon_event); -} - -QDF_STATUS -pkt_capture_alloc_mon_thread(struct pkt_capture_mon_context *mon_ctx) -{ - spin_lock_init(&mon_ctx->mon_thread_lock); - init_waitqueue_head(&mon_ctx->mon_wait_queue); - init_completion(&mon_ctx->mon_start_event); - init_completion(&mon_ctx->suspend_mon_event); - init_completion(&mon_ctx->resume_mon_event); - init_completion(&mon_ctx->mon_shutdown); - init_completion(&mon_ctx->mon_register_event); - mon_ctx->mon_event_flag = 0; - spin_lock_init(&mon_ctx->mon_queue_lock); - spin_lock_init(&mon_ctx->mon_pkt_freeq_lock); - INIT_LIST_HEAD(&mon_ctx->mon_thread_queue); - spin_lock_bh(&mon_ctx->mon_pkt_freeq_lock); - INIT_LIST_HEAD(&mon_ctx->mon_pkt_freeq); - spin_unlock_bh(&mon_ctx->mon_pkt_freeq_lock); - - return pkt_capture_alloc_mon_pkt_freeq(mon_ctx); -} diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h index 38e93730c14d2ef898b10c0e207119c484ca46dc..86f286c7bd4375a187efc34815f513f767e749c0 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h @@ -33,63 +33,4 @@ enum pkt_capture_mode { PACKET_CAPTURE_MODE_DATA_MGMT, }; -/** - * struct mgmt_offload_event_params - Management offload event params - * @tsf_l32: The lower 32 bits of the TSF - * @chan_freq: channel frequency in MHz - * @rate_kbps: Rate kbps - * @rssi: combined RSSI, i.e. the sum of the snr + noise floor (dBm units) - * @buf_len: length of the frame in bytes - * @tx_status: 0: xmit ok - * 1: excessive retries - * 2: blocked by tx filtering - * 4: fifo underrun - * 8: swabort - * @buf: management frame buffer - * @tx_retry_cnt: tx retry count - */ -struct mgmt_offload_event_params { - uint32_t tsf_l32; - uint32_t chan_freq; - uint32_t rate_kbps; - uint32_t rssi; - uint32_t buf_len; - uint32_t tx_status; - uint8_t *buf; - uint8_t tx_retry_cnt; -}; - -/** - * struct pkt_capture_callbacks - callbacks to non-converged driver - * @get_rmf_status: callback to get rmf status - */ -struct pkt_capture_callbacks { - int (*get_rmf_status)(uint8_t vdev_id); -}; - -/** - * struct wlan_pkt_capture_tx_ops - structure of tx operation function - * pointers for packet capture component - * @pkt_capture_send_mode: send packet capture mode - * - */ -struct wlan_pkt_capture_tx_ops { - QDF_STATUS (*pkt_capture_send_mode)(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, - enum pkt_capture_mode mode); -}; - -/** - * struct wlan_pkt_capture_rx_ops - structure of rx operation function - * pointers for packet capture component - * @pkt_capture_register_ev_handlers: register mgmt offload event - * @pkt_capture_unregister_ev_handlers: unregister mgmt offload event - */ -struct wlan_pkt_capture_rx_ops { - QDF_STATUS (*pkt_capture_register_ev_handlers) - (struct wlan_objmgr_psoc *psoc); - QDF_STATUS (*pkt_capture_unregister_ev_handlers) - (struct wlan_objmgr_psoc *psoc); -}; - #endif /* _WLAN_PKT_CAPTURE_PUBLIC_STRUCTS_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h index ababaecc5f83965a429f51af09262d6fb3b537de..bc12c61e66face9d4a09049ad1127183515d3ddf 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h @@ -28,12 +28,6 @@ #include #include "wlan_pkt_capture_objmgr.h" #include "wlan_pkt_capture_public_structs.h" -#include "wlan_pkt_capture_mon_thread.h" -#include "wmi_unified.h" -#include "wmi_unified_param.h" -#include -#include "wlan_pkt_capture_data_txrx.h" -#include #ifdef WLAN_FEATURE_PKT_CAPTURE /** @@ -56,217 +50,11 @@ void ucfg_pkt_capture_deinit(void); /** * ucfg_pkt_capture_get_mode() - get packet capture mode - * @psoc: objmgr psoc handle - * - * Return: enum pkt_capture_mode - */ -enum pkt_capture_mode -ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc); - -/** - * ucfg_pkt_capture_suspend_mon_thread() - suspend packet capture mon thread - * vdev: pointer to vdev object manager - * - * Return: 0 on success, -EINVAL on failure - */ -int ucfg_pkt_capture_suspend_mon_thread(struct wlan_objmgr_vdev *vdev); - -/** - * ucfg_pkt_capture_resume_mon_thread() - resume packet capture mon thread - * vdev: pointer to vdev object manager - * - * Resume packet capture MON thread by completing RX thread resume event - * - * Return: None - */ -void ucfg_pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev); - -/** - * ucfg_pkt_capture_register_callbacks - Register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * mon_cb: callback to call - * context: callback context - * - * Return: QDF_STATUS - */ -QDF_STATUS -ucfg_pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t), - void *context); - -/** - * ucfg_pkt_capture_deregister_callbacks - De-register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * - * Return: QDF_STATUS - */ -QDF_STATUS -ucfg_pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev); - -/** - * ucfg_pkt_capturee_set_pktcap_mode - Set packet capture mode * @psoc: pointer to psoc object - * @mode: mode to be set - * - * Return: None - */ -void ucfg_pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, - enum pkt_capture_mode val); - -/** - * ucfg_pkt_capture_get_pktcap_mode - Get packet capture mode * * Return: enum pkt_capture_mode */ -enum pkt_capture_mode -ucfg_pkt_capture_get_pktcap_mode(void); - -/** - * ucfg_pkt_capture_process_mgmt_tx_data() - process management tx packets - * @pdev: pointer to pdev object - * @params: management offload event params - * @nbuf: netbuf - * @status: status - * - * Return: QDF_STATUS - */ -QDF_STATUS -ucfg_pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, - struct mgmt_offload_event_params *params, - qdf_nbuf_t nbuf, - uint8_t status); - -/** - * ucfg_pkt_capture_mgmt_tx() - process mgmt tx completion - * for pkt capture mode - * @pdev: pointer to pdev object - * @nbuf: netbuf - * @chan_freq: channel freq - * @preamble_type: preamble_type - * - * Return: none - */ -void -ucfg_pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, - qdf_nbuf_t nbuf, - uint16_t chan_freq, - uint8_t preamble_type); - -/** - * ucfg_pkt_capture_mgmt_tx_completion() - process mgmt tx completion - * for pkt capture mode - * @pdev: pointer to pdev object - * @desc_id: desc_id - * @status: status - * @params: management offload event params - * - * Return: none - */ -void -ucfg_pkt_capture_mgmt_tx_completion( - struct wlan_objmgr_pdev *pdev, - uint32_t desc_id, - uint32_t status, - struct mgmt_offload_event_params *params); - -/** - * ucfg_pkt_capture_rx_msdu_process() - process data rx pkts - * @bssid: bssid - * @head_msdu: pointer to head msdu - * @vdev_id: vdev_id - * @pdev: pdev handle - * - * Return: none - */ -void ucfg_pkt_capture_rx_msdu_process( - uint8_t *bssid, - qdf_nbuf_t head_msdu, - uint8_t vdev_id, htt_pdev_handle pdev); - -/** - * ucfg_pkt_capture_rx_offloaded_pkt() - check offloaded data pkt or not - * @rx_ind_msg: rx_ind_msg - * - * Return: 0 not an offload pkt - * 1 offload pkt - */ -bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg); - -/** - * ucfg_pkt_capture_rx_drop_offload_pkt() - drop offload packets - * @head_msdu: pointer to head msdu - * - * Return: none - */ -void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu); - -/** - * ucfg_pkt_capture_offload_deliver_indication_handler() - Handle offload - * data pkts - * @msg: offload netbuf msg - * @vdev_id: vdev id - * @bssid: bssid - * @pdev: pdev handle - * - * Return: none - */ -void ucfg_pkt_capture_offload_deliver_indication_handler( - void *msg, uint8_t vdev_id, - uint8_t *bssid, htt_pdev_handle pdev); - -/** - * ucfg_pkt_capture_tx_get_txcomplete_data_hdr() - extract Tx data hdr from Tx - * completion for pkt capture mode - * @msg_word: Tx completion htt msg - * @num_msdus: number of msdus - * - * Return: tx data hdr information - */ -struct htt_tx_data_hdr_information *ucfg_pkt_capture_tx_get_txcomplete_data_hdr( - uint32_t *msg_word, - int num_msdus); - -/** - * ucfg_pkt_capture_tx_completion_process() - process data tx packets - * @vdev_id: vdev id for which packet is captured - * @mon_buf_list: netbuf list - * @type: data process type - * @tid: tid number - * @status: Tx status - * @pktformat: Frame format - * @bssid: bssid - * @pdev: pdev handle - * @tx_retry_cnt: tx retry count - * - * Return: none - */ -void ucfg_pkt_capture_tx_completion_process( - uint8_t vdev_id, - qdf_nbuf_t mon_buf_list, - enum pkt_capture_data_process_type type, - uint8_t tid, uint8_t status, bool pkt_format, - uint8_t *bssid, htt_pdev_handle pdev, - uint8_t tx_retry_cnt); - -/** - * ucfg_pkt_capture_record_channel() - Update Channel Information - * for packet capture mode - * @vdev: pointer to vdev - * - * Return: None - */ -void ucfg_pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev); - -/** - * ucfg_pkt_capture_register_callbacks - ucfg API to register WMA callbacks - * @psoc: pointer to psoc object - * @cb_obj: Pointer to packet capture callback structure - * - * Return: status of operation - */ -int -ucfg_pkt_capture_register_wma_callbacks(struct wlan_objmgr_psoc *psoc, - struct pkt_capture_callbacks *cb_obj); +enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc); #else static inline QDF_STATUS ucfg_pkt_capture_init(void) @@ -284,117 +72,5 @@ enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { return PACKET_CAPTURE_MODE_DISABLE; } - -static inline -void ucfg_pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev) -{ -} - -static inline -int ucfg_pkt_capture_suspend_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - return 0; -} - -static inline QDF_STATUS -ucfg_pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t), - void *context) -{ - return QDF_STATUS_SUCCESS; -} - -static inline -QDF_STATUS ucfg_pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev) -{ - return QDF_STATUS_SUCCESS; -} - -static inline -void ucfg_pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, - uint8_t val) -{ -} - -static inline enum pkt_capture_mode -ucfg_pkt_capture_get_pktcap_mode(void) -{ - return PACKET_CAPTURE_MODE_DISABLE; -} - -static inline QDF_STATUS -ucfg_pkt_capture_process_mgmt_tx_data( - struct mgmt_offload_event_params *params, - qdf_nbuf_t nbuf, - uint8_t status) -{ - return 0; -} - -static inline void -ucfg_pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, - qdf_nbuf_t nbuf, - uint16_t chan_freq, - uint8_t preamble_type) -{ -} - -static inline void -ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, - uint32_t desc_id, - uint32_t status, - struct mgmt_offload_event_params *params) -{ -} - -static inline void -ucfg_pkt_capture_offload_deliver_indication_handler( - void *msg, uint8_t vdev_id, - uint8_t *bssid, htt_pdev_handle pdev) -{ -} - -static inline -struct htt_tx_data_hdr_information *ucfg_pkt_capture_tx_get_txcomplete_data_hdr( - uint32_t *msg_word, - int num_msdus) -{ - return NULL; -} - -static inline void -ucfg_pkt_capture_rx_msdu_process( - uint8_t *bssid, - qdf_nbuf_t head_msdu, - uint8_t vdev_id, htt_pdev_handle pdev) -{ -} - -static inline bool -ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg) -{ - return false; -} - -static inline void -ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu) -{ -} - -static inline void -ucfg_pkt_capture_tx_completion_process( - uint8_t vdev_id, - qdf_nbuf_t mon_buf_list, - enum pkt_capture_data_process_type type, - uint8_t tid, uint8_t status, bool pkt_format, - uint8_t *bssid, htt_pdev_handle pdev, - uint8_t tx_retry_cnt) -{ -} - -static inline void -ucfg_pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev) -{ -} #endif /* WLAN_FEATURE_PKT_CAPTURE */ #endif /* _WLAN_PKT_CAPTURE_UCFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_tgt_api.c b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_tgt_api.c deleted file mode 100644 index 2361906eeae299f4cad3318d57c44cd115461491..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_tgt_api.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: This file contains packet capture south bound interface definitions - */ - -#include "wlan_pkt_capture_tgt_api.h" - -QDF_STATUS -tgt_pkt_capture_register_ev_handler(struct wlan_objmgr_vdev *vdev) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_pkt_capture_rx_ops *rx_ops; - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return status; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("vdev priv is NULL"); - return status; - } - - rx_ops = &vdev_priv->rx_ops; - - if (!rx_ops->pkt_capture_register_ev_handlers) - return status; - - status = rx_ops->pkt_capture_register_ev_handlers(psoc); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Unable to register mgmt offload handler"); - - return status; -} - -QDF_STATUS -tgt_pkt_capture_unregister_ev_handler(struct wlan_objmgr_vdev *vdev) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_pkt_capture_rx_ops *rx_ops; - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return status; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("vdev priv is NULL"); - return status; - } - - rx_ops = &vdev_priv->rx_ops; - - if (!rx_ops->pkt_capture_unregister_ev_handlers) - return status; - - status = rx_ops->pkt_capture_unregister_ev_handlers(psoc); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Unable to register mgmt offload handler"); - - return status; -} - -QDF_STATUS -tgt_pkt_capture_send_mode(struct wlan_objmgr_vdev *vdev, - enum pkt_capture_mode mode) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct pkt_capture_vdev_priv *vdev_priv; - struct wlan_pkt_capture_tx_ops *tx_ops; - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return status; - } - - vdev_priv = pkt_capture_vdev_get_priv(vdev); - if (!vdev_priv) { - pkt_capture_err("vdev priv is NULL"); - return status; - } - - tx_ops = &vdev_priv->tx_ops; - - if (!tx_ops->pkt_capture_send_mode) - return status; - - status = tx_ops->pkt_capture_send_mode(psoc, wlan_vdev_get_id(vdev), - mode); - if (QDF_IS_STATUS_ERROR(status)) - pkt_capture_err("Unable to send packet capture mode to fw"); - - return status; -} diff --git a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c index ebe76bd83b0074f3f1e79470c47957150fb7f013..e16e09dbde0abb11b94fab1ced4b02946bde67d3 100644 --- a/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c @@ -23,75 +23,12 @@ #include "wlan_pkt_capture_objmgr.h" #include "wlan_pkt_capture_main.h" #include "wlan_pkt_capture_ucfg_api.h" -#include "wlan_pkt_capture_mon_thread.h" -#include "wlan_pkt_capture_mgmt_txrx.h" -#include "target_if_pkt_capture.h" -#include "wlan_pkt_capture_data_txrx.h" -#include "wlan_pkt_capture_tgt_api.h" enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { return pkt_capture_get_mode(psoc); } -/** - * ucfg_pkt_capture_register_callbacks - Register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * mon_cb: callback to call - * context: callback context - * - * Return: 0 in case of success, invalid in case of failure. - */ -QDF_STATUS -ucfg_pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, - QDF_STATUS (*mon_cb)(void *, qdf_nbuf_t), - void *context) -{ - return pkt_capture_register_callbacks(vdev, mon_cb, context); -} - -/** - * ucfg_pkt_capture_deregister_callbacks - De-register packet capture callbacks - * @vdev: pointer to wlan vdev object manager - * - * Return: 0 in case of success, invalid in case of failure. - */ -QDF_STATUS ucfg_pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev) -{ - return pkt_capture_deregister_callbacks(vdev); -} - -/** - * ucfg_pkt_capture_set_pktcap_mode - Set packet capture mode - * @psoc: pointer to psoc object - * @mode: mode to be set - * - * Return: None - */ -void ucfg_pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, - enum pkt_capture_mode mode) -{ - pkt_capture_set_pktcap_mode(psoc, mode); -} - -/** - * ucfg_pkt_capture_get_pktcap_mode - Get packet capture mode - * - * Return: enum pkt_capture_mode - */ -enum pkt_capture_mode -ucfg_pkt_capture_get_pktcap_mode(void) -{ - return pkt_capture_get_pktcap_mode(); -} - -/** - * ucfg_pkt_capture_init() - Packet capture component initialization. - * - * This function gets called when packet capture initializing. - * - * Return: QDF_STATUS_SUCCESS - in case of success. - */ QDF_STATUS ucfg_pkt_capture_init(void) { QDF_STATUS status; @@ -177,133 +114,3 @@ void ucfg_pkt_capture_deinit(void) if (QDF_IS_STATUS_ERROR(status)) pkt_capture_err("Failed to unregister psoc create handler"); } - -int ucfg_pkt_capture_suspend_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - return pkt_capture_suspend_mon_thread(vdev); -} - -void ucfg_pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev) -{ - pkt_capture_resume_mon_thread(vdev); -} - -/** - * ucfg_process_pktcapture_mgmt_tx_data() - process management tx packets - * @pdev: pointer to pdev object - * @params: management offload event params - * @nbuf: netbuf - * @status: status - * - * Return: QDF_STATUS - */ -QDF_STATUS -ucfg_pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, - struct mgmt_offload_event_params *params, - qdf_nbuf_t nbuf, - uint8_t status) -{ - return pkt_capture_process_mgmt_tx_data( - pdev, params, nbuf, - pkt_capture_mgmt_status_map(status)); -} - -void -ucfg_pkt_capture_mgmt_tx(struct wlan_objmgr_pdev *pdev, - qdf_nbuf_t nbuf, - uint16_t chan_freq, - uint8_t preamble_type) -{ - pkt_capture_mgmt_tx(pdev, nbuf, chan_freq, preamble_type); -} - -/** - * ucfg_process_pktcapture_mgmt_tx_completion(): process mgmt tx completion - * for pkt capture mode - * @pdev: pointer to pdev object - * @desc_id: desc_id - * @status: status - * @params: management offload event params - * - * Return: none - */ -void -ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, - uint32_t desc_id, - uint32_t status, - struct mgmt_offload_event_params *params) -{ - pkt_capture_mgmt_tx_completion(pdev, desc_id, status, params); -} - -void ucfg_pkt_capture_rx_msdu_process( - uint8_t *bssid, - qdf_nbuf_t head_msdu, - uint8_t vdev_id, htt_pdev_handle pdev) -{ - pkt_capture_msdu_process_pkts(bssid, head_msdu, - vdev_id, pdev); -} - -bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg) -{ - return pkt_capture_rx_in_order_offloaded_pkt(rx_ind_msg); -} - -void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu) -{ - pkt_capture_rx_in_order_drop_offload_pkt(head_msdu); -} - -void -ucfg_pkt_capture_offload_deliver_indication_handler( - void *msg, uint8_t vdev_id, - uint8_t *bssid, htt_pdev_handle pdev) -{ - pkt_capture_offload_deliver_indication_handler(msg, vdev_id, - bssid, pdev); -} - -struct htt_tx_data_hdr_information *ucfg_pkt_capture_tx_get_txcomplete_data_hdr( - uint32_t *msg_word, - int num_msdus) -{ - return pkt_capture_tx_get_txcomplete_data_hdr(msg_word, num_msdus); -} - -void -ucfg_pkt_capture_tx_completion_process( - uint8_t vdev_id, - qdf_nbuf_t mon_buf_list, - enum pkt_capture_data_process_type type, - uint8_t tid, uint8_t status, bool pkt_format, - uint8_t *bssid, htt_pdev_handle pdev, - uint8_t tx_retry_cnt) -{ - pkt_capture_datapkt_process( - vdev_id, - mon_buf_list, TXRX_PROCESS_TYPE_DATA_TX_COMPL, - tid, status, pkt_format, bssid, pdev, - tx_retry_cnt); -} - -void ucfg_pkt_capture_record_channel(struct wlan_objmgr_vdev *vdev) -{ - pkt_capture_record_channel(vdev); -} - -int -ucfg_pkt_capture_register_wma_callbacks(struct wlan_objmgr_psoc *psoc, - struct pkt_capture_callbacks *cb_obj) -{ - struct pkt_psoc_priv *psoc_priv = pkt_capture_psoc_get_priv(psoc); - - if (!psoc_priv) { - pkt_capture_err("psoc priv is NULL"); - return -EINVAL; - } - - psoc_priv->cb_obj.get_rmf_status = cb_obj->get_rmf_status; - - return 0; -} diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_main.h b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_main.h index e520343676eadd378acf2208e124c014171a5de8..fea451cfb9720ed19356bd7a5b4c5b1c48fcbb5a 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_main.h +++ b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_main.h @@ -315,22 +315,22 @@ void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc, void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc); /** - * pmo_core_psoc_set_txrx_handle() - update psoc pdev txrx layer handle + * pmo_core_psoc_set_txrx_pdev_id() - update psoc pdev txrx layer handle * @psoc: objmgr psoc handle - * @txrx_hdl: pdev txrx context handle + * @txrx_pdev_id: txrx pdev identifier * * Return: None */ -void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_hdl); +void pmo_core_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t txrx_pdev_id); /** * pmo_core_psoc_get_txrx_handle() - Get psoc pdev txrx handle * @psoc: objmgr psoc handle * - * Return: pdev txrx handle + * Return: txrx pdev identifier */ -void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc); +uint8_t pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc); /** * pmo_intersect_arp_ns_offload() - intersect config and firmware capability for diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_priv.h b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_priv.h index bf0296464962e63edf6bc7ccd30fad9bfa3dd0bb..1bbf04d24c1f51788328639fbec45fd3b02992e2 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_priv.h +++ b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_priv.h @@ -43,7 +43,7 @@ * @dp_hdl: psoc data path handle * @htc_hdl: htc layer handle * @hif_hdl: hif layer handle - * @txrx_hdl: txrx pdev handle + * @txrx_pdev_id: txrx pdev identifier * @pause_bitmap_notifier: registered callback to update pause bitmap value * @pmo_get_pause_bitmap: registered callback to get pause bitmap value * @get_dtim_period: register callback to get dtim period from mlme @@ -58,7 +58,7 @@ struct pmo_psoc_priv_obj { void *dp_hdl; void *htc_hdl; void *hif_hdl; - void *txrx_hdl; + uint8_t txrx_pdev_id; pmo_notify_pause_bitmap pause_bitmap_notifier; pmo_get_pause_bitmap get_pause_bitmap; pmo_get_vdev_dp_handle get_vdev_dp_handle; diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_suspend_resume.h b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_suspend_resume.h index 18289df20d94ce6997b1e101f1ab70c76a89ad0e..78325d9f7257b1b98c2fd82e4bfdeca917736d07 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_suspend_resume.h +++ b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_suspend_resume.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -216,45 +216,6 @@ pmo_core_psoc_get_power_save_mode(struct wlan_objmgr_psoc *psoc) return value; } -/** - * pmo_core_psoc_get_qpower_config() - get qpower configuration - * @psoc: objmgr psoc handle - * - * Power Save Offload configuration: - * 0 -> Power save offload is disabled - * 1 -> Legacy Power save enabled + Deep sleep Disabled - * 2 -> QPower enabled + Deep sleep Disabled - * 3 -> Legacy Power save enabled + Deep sleep Enabled - * 4 -> QPower enabled + Deep sleep Enabled - * 5 -> Duty cycling QPower enabled - * - * Return: enum powersave_qpower_mode with below values - * QPOWER_DISABLED if QPOWER is disabled - * QPOWER_ENABLED if QPOWER is enabled - * QPOWER_DUTY_CYCLING if DUTY CYCLING QPOWER is enabled - */ -static inline -enum pmo_power_save_qpower_mode pmo_core_psoc_get_qpower_config( - struct wlan_objmgr_psoc *psoc) -{ - uint8_t ps_mode = pmo_core_psoc_get_power_save_mode(psoc); - - switch (ps_mode) { - case pmo_ps_qpower_no_deep_sleep: - case pmo_ps_qpower_deep_sleep: - pmo_debug("QPOWER is enabled in power save mode %d", ps_mode); - return pmo_qpower_enabled; - case pmo_ps_duty_cycling_qpower: - pmo_debug("DUTY cycling QPOWER is enabled in power save mode %d", - ps_mode); - return pmo_qpower_duty_cycling; - default: - pmo_debug("QPOWER is disabled in power save mode %d", - ps_mode); - return pmo_qpower_disabled; - } -} - /** * pmo_core_vdev_get_pause_bitmap() - Get vdev pause bitmap * @psoc_ctx: psoc priv ctx @@ -393,6 +354,20 @@ QDF_STATUS pmo_core_config_listen_interval(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev, uint32_t mod_dtim); + +#ifdef SYSTEM_PM_CHECK +/** + * pmo_core_system_resume() - function to handle system resume notification + * @psoc: objmgr psoc handle + * + * Return: None + */ +void pmo_core_system_resume(struct wlan_objmgr_psoc *psoc); +#else +static inline void pmo_core_system_resume(struct wlan_objmgr_psoc *psoc) +{ +} +#endif #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */ #endif /* end of _WLAN_PMO_SUSPEND_RESUME_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_wow.h b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_wow.h index f1e2dda99af4da34e282fa617bde2e2d14708b91..1927dcb872afffeb1e91e40f6b3738f61b580758 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_wow.h +++ b/drivers/staging/qcacld-3.0/components/pmo/core/inc/wlan_pmo_wow.h @@ -108,7 +108,7 @@ #define PMO_WOW_MAX_EVENT_BM_LEN 4 #define PMO_WOW_FILTERS_ARP_NS 2 -#define PMO_WOW_FILTERS_PKT_OR_APF 3 +#define PMO_WOW_FILTERS_PKT_OR_APF 5 /** * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_arp.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_arp.c index 56044012b120fb2768e17b3d9532946a324b31b9..358a48b9526a2d37bc0ad970586f29f967a6f732 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_arp.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_arp.c @@ -49,9 +49,9 @@ static QDF_STATUS pmo_core_cache_arp_in_vdev_priv( qdf_mem_copy(&request->bssid.bytes, &peer_bssid.bytes, QDF_MAC_ADDR_SIZE); - pmo_debug("vdev self mac addr: %pM bss peer mac addr: %pM", - wlan_vdev_mlme_get_macaddr(vdev), - peer_bssid.bytes); + pmo_debug("vdev self mac addr: "QDF_MAC_ADDR_FMT" bss peer mac addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)), + QDF_MAC_ADDR_REF(peer_bssid.bytes)); request->enable = PMO_OFFLOAD_ENABLE; request->is_offload_applied = false; diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_gtk.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_gtk.c index b6d981c3acf58843d4243903042057d7aa8a6bfe..413bc3d5693dcb6b39512fd0abe0df70e3d61c2f 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_gtk.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_gtk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -72,6 +72,13 @@ static QDF_STATUS pmo_core_do_enable_gtk_offload( { QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t vdev_id; + enum QDF_OPMODE op_mode; + + op_mode = pmo_get_vdev_opmode(vdev); + if (QDF_NDI_MODE == op_mode) { + pmo_debug("gtk offload is not supported in NaN mode"); + return QDF_STATUS_E_INVAL; + } if (!pmo_core_is_vdev_supports_offload(vdev)) { pmo_debug("vdev in invalid opmode for gtk offload %d", @@ -134,9 +141,9 @@ static QDF_STATUS pmo_core_is_gtk_enabled_in_fwr( if (qdf_mem_cmp(&vdev_ctx->vdev_gtk_req.bssid, &peer_bssid, QDF_MAC_ADDR_SIZE)) { qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock); - pmo_err("cache request mac:%pM, peer mac:%pM are not same", - vdev_ctx->vdev_gtk_req.bssid.bytes, - peer_bssid.bytes); + pmo_err("cache request mac:"QDF_MAC_ADDR_FMT", peer mac:"QDF_MAC_ADDR_FMT" are not same", + QDF_MAC_ADDR_REF(vdev_ctx->vdev_gtk_req.bssid.bytes), + QDF_MAC_ADDR_REF(peer_bssid.bytes)); return QDF_STATUS_E_INVAL; } @@ -156,6 +163,13 @@ static QDF_STATUS pmo_core_do_disable_gtk_offload( struct pmo_gtk_req *op_gtk_req) { QDF_STATUS status = QDF_STATUS_SUCCESS; + enum QDF_OPMODE op_mode; + + op_mode = pmo_get_vdev_opmode(vdev); + if (QDF_NDI_MODE == op_mode) { + pmo_debug("gtk offload is not supported in NaN mode"); + return QDF_STATUS_E_INVAL; + } status = pmo_core_is_gtk_enabled_in_fwr(vdev, vdev_ctx); if (status != QDF_STATUS_SUCCESS) diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_main.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_main.c index 4907f580172fe404f52031cc7e194ba57a7c3630..f11f4d931c8575f15e91f41f772ead74766b0192 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_main.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -183,7 +183,9 @@ static void wlan_pmo_init_cfg(struct wlan_objmgr_psoc *psoc, psoc_cfg->sta_dynamic_dtim = cfg_get(psoc, CFG_PMO_ENABLE_DYNAMIC_DTIM); psoc_cfg->sta_mod_dtim = cfg_get(psoc, CFG_PMO_ENABLE_MODULATED_DTIM); psoc_cfg->enable_mc_list = cfg_get(psoc, CFG_PMO_MC_ADDR_LIST_ENABLE); - psoc_cfg->power_save_mode = cfg_get(psoc, CFG_PMO_POWERSAVE_OFFLOAD); + psoc_cfg->power_save_mode = cfg_get(psoc, CFG_PMO_POWERSAVE_MODE); + psoc_cfg->is_mod_dtim_on_sys_suspend_enabled = + cfg_get(psoc, CFG_PMO_MOD_DTIM_ON_SYS_SUSPEND); psoc_cfg->max_ps_poll = cfg_get(psoc, CFG_PMO_MAX_PS_POLL); psoc_cfg->wow_enable = cfg_get(psoc, CFG_PMO_WOW_ENABLE); @@ -386,24 +388,24 @@ void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc) return hif_hdl; } -void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_hdl) +void pmo_core_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t txrx_pdev_id) { struct pmo_psoc_priv_obj *psoc_ctx; pmo_psoc_with_ctx(psoc, psoc_ctx) { - psoc_ctx->txrx_hdl = txrx_hdl; + psoc_ctx->txrx_pdev_id = txrx_pdev_id; } } -void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc) +uint8_t pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc) { - void *txrx_hdl = NULL; + uint8_t txrx_pdev_id = OL_TXRX_INVALID_PDEV_ID; struct pmo_psoc_priv_obj *psoc_ctx; pmo_psoc_with_ctx(psoc, psoc_ctx) { - txrx_hdl = psoc_ctx->txrx_hdl; + txrx_pdev_id = psoc_ctx->txrx_pdev_id; } - return txrx_hdl; + return txrx_pdev_id; } diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c index b3ddf9ba2c33fd0f5dcb1f6aaf0df6c36a2aee57..f25fae44936443316255dc7ae71335d09d1c1171 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c @@ -57,8 +57,8 @@ static void pmo_core_fill_mc_list(struct pmo_vdev_priv_obj **vdev_ctx, QDF_MAC_ADDR_SIZE)) || (addr_fp && (!qdf_mem_cmp(ip->mc_addr[i].bytes, &addr_fp, 1)))) { - pmo_debug("MC/BC filtering Skip addr %pM", - ip->mc_addr[i].bytes); + pmo_debug("MC/BC filtering Skip addr "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(ip->mc_addr[i].bytes)); qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock); op_list->mc_cnt--; qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock); @@ -70,7 +70,8 @@ static void pmo_core_fill_mc_list(struct pmo_vdev_priv_obj **vdev_ctx, qdf_mem_copy(&op_list->mc_addr[j].bytes, ip->mc_addr[i].bytes, QDF_MAC_ADDR_SIZE); qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock); - pmo_debug("Index = %d, mac[%pM]", j, op_list->mc_addr[i].bytes); + pmo_debug("Index = %d, mac["QDF_MAC_ADDR_FMT"]", j, + QDF_MAC_ADDR_REF(op_list->mc_addr[i].bytes)); j++; } } diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_ns.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_ns.c index 4783952f504df6aeeaa4a4d2b48fe2d2f017cadd..1942be8131cda65168a52dbb4f69aa07584f4f9e 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_ns.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_ns.c @@ -98,9 +98,9 @@ static QDF_STATUS pmo_core_cache_ns_in_vdev_priv( status = QDF_STATUS_E_INVAL; goto out; } - pmo_debug("vdev self mac addr: %pM bss peer mac addr: %pM", - wlan_vdev_mlme_get_macaddr(vdev), - wlan_peer_get_macaddr(peer)); + pmo_debug("vdev self mac addr: "QDF_MAC_ADDR_FMT" bss peer mac addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wlan_vdev_mlme_get_macaddr(vdev)), + QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer))); /* get peer and peer mac accdress aka ap mac address */ qdf_mem_copy(&request.bssid, wlan_peer_get_macaddr(peer), diff --git a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_suspend_resume.c b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_suspend_resume.c index 45eadf16bd1cad07cfef1b1c3021c693c00b5856..1cc81f558a313a9c175553603b6094dfe5c652f8 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_suspend_resume.c +++ b/drivers/staging/qcacld-3.0/components/pmo/core/src/wlan_pmo_suspend_resume.c @@ -433,14 +433,19 @@ static void pmo_core_enable_runtime_pm_offloads(struct wlan_objmgr_psoc *psoc) { uint8_t vdev_id; struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; /* Iterate through VDEV list */ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) { vdev = pmo_psoc_get_vdev(psoc, vdev_id); if (!vdev) continue; + status = pmo_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) + continue; pmo_register_action_frame_patterns(vdev, QDF_RUNTIME_SUSPEND); + pmo_vdev_put_ref(vdev); } } @@ -448,14 +453,19 @@ static void pmo_core_disable_runtime_pm_offloads(struct wlan_objmgr_psoc *psoc) { uint8_t vdev_id; struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; /* Iterate through VDEV list */ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) { vdev = pmo_psoc_get_vdev(psoc, vdev_id); if (!vdev) continue; + status = pmo_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) + continue; pmo_clear_action_frame_patterns(vdev); + pmo_vdev_put_ref(vdev); } } @@ -636,19 +646,14 @@ static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_priv_obj *psoc_ctx) { uint8_t vdev_id; - struct cdp_vdev *vdev_dp; /* Iterate through VDEV list */ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) { - vdev_dp = pmo_core_vdev_get_dp_handle(psoc_ctx, vdev_id); - if (!vdev_dp) - continue; - /* When host resumes, by default unpause all active vdev */ if (pmo_core_vdev_get_pause_bitmap(psoc_ctx, vdev_id)) { cdp_fc_vdev_unpause(pmo_core_psoc_get_dp_handle(psoc), - vdev_dp, - 0xffffffff); + vdev_id, + 0xffffffff, 0); if (psoc_ctx->pause_bitmap_notifier) psoc_ctx->pause_bitmap_notifier(vdev_id, 0); } @@ -725,16 +730,19 @@ QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc, * @psoc: objmgr psoc handle * @psoc_ctx: pmo psoc private ctx * @wow_params: collection of wow enable override parameters + * @type: type of wow suspend * * Return: QDF status */ static QDF_STATUS pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc, struct pmo_psoc_priv_obj *psoc_ctx, - struct pmo_wow_enable_params *wow_params) + struct pmo_wow_enable_params *wow_params, + enum qdf_suspend_type type) { int host_credits, wmi_pending_cmds; struct pmo_wow_cmd_params param = {0}; + struct pmo_psoc_cfg *psoc_cfg = &psoc_ctx->psoc_cfg; QDF_STATUS status; pmo_enter(); @@ -805,6 +813,19 @@ pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc, pmo_info("Prevent link down, non-drv wow is enabled"); } + if (type == QDF_SYSTEM_SUSPEND) { + pmo_info("system suspend wow"); + param.flags |= WMI_WOW_FLAG_SYSTEM_SUSPEND_WOW; + } else { + pmo_info("RTPM wow"); + } + + if ((psoc_cfg) && + (psoc_cfg->is_mod_dtim_on_sys_suspend_enabled)) { + pmo_info("mod DTIM enabled"); + param.flags |= WMI_WOW_FLAG_MOD_DTIM_ON_SYS_SUSPEND; + } + status = pmo_tgt_psoc_send_wow_enable_req(psoc, ¶m); if (status != QDF_STATUS_SUCCESS) { pmo_err("Failed to enable wow in fw"); @@ -821,7 +842,7 @@ pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc, pmo_tgt_psoc_get_host_credits(psoc), pmo_tgt_psoc_get_pending_cmnds(psoc)); pmo_tgt_update_target_suspend_flag(psoc, false); - qdf_trigger_self_recovery(QDF_SUSPEND_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_SUSPEND_TIMEOUT); goto out; } @@ -839,7 +860,7 @@ pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc, pmo_err("No Credits after HTC ACK:%d, pending_cmds:%d," "cannot resume back", host_credits, wmi_pending_cmds); htc_dump_counter_info(pmo_core_psoc_get_htc_handle(psoc)); - qdf_trigger_self_recovery(QDF_SUSPEND_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_SUSPEND_NO_CREDIT); } pmo_debug("WOW enabled successfully in fw: credits:%d pending_cmds: %d", host_credits, wmi_pending_cmds); @@ -859,13 +880,12 @@ QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc, struct pmo_suspend_params param; struct pmo_psoc_priv_obj *psoc_ctx; void *dp_soc = pmo_core_psoc_get_dp_handle(psoc); - void *txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc); pmo_enter(); psoc_ctx = pmo_psoc_get_priv(psoc); - cdp_process_target_suspend_req(dp_soc, txrx_pdev); + cdp_process_target_suspend_req(dp_soc, OL_TXRX_PDEV_ID); qdf_event_reset(&psoc_ctx->wow.target_suspend); param.disable_target_intr = disable_target_intr; status = pmo_tgt_psoc_send_supend_req(psoc, ¶m); @@ -879,7 +899,7 @@ QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) { pmo_err("Failed to get ACK from firmware for pdev suspend"); pmo_tgt_update_target_suspend_flag(psoc, false); - qdf_trigger_self_recovery(QDF_SUSPEND_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_SUSPEND_TIMEOUT); } out: @@ -923,7 +943,9 @@ QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc, begin = qdf_get_log_timestamp_usecs(); if (wow_mode_selected) - status = pmo_core_enable_wow_in_fw(psoc, psoc_ctx, wow_params); + status = pmo_core_enable_wow_in_fw(psoc, psoc_ctx, + wow_params, + type); else status = pmo_core_psoc_suspend_target(psoc, 0); end = qdf_get_log_timestamp_usecs(); @@ -949,12 +971,13 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, { void *hif_ctx; void *dp_soc; - void *txrx_pdev; + uint8_t pdev_id; void *htc_ctx; QDF_STATUS status; int ret; struct pmo_wow_enable_params wow_params = {0}; qdf_time_t begin, end; + int pending; pmo_enter(); @@ -972,11 +995,12 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, hif_ctx = pmo_core_psoc_get_hif_handle(psoc); dp_soc = pmo_core_psoc_get_dp_handle(psoc); - txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc); + pdev_id = pmo_core_psoc_get_txrx_handle(psoc); htc_ctx = pmo_core_psoc_get_htc_handle(psoc); - if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) { - pmo_err("Invalid hif: %pK, dp: %pK, txrx: %pK, htc: %pK", - hif_ctx, dp_soc, txrx_pdev, htc_ctx); + if (!hif_ctx || !dp_soc || !htc_ctx || + pdev_id == OL_TXRX_INVALID_PDEV_ID) { + pmo_err("Invalid hif: %pK, dp: %pK, pdev_id: %d, htc: %pK", + hif_ctx, dp_soc, pdev_id, htc_ctx); status = QDF_STATUS_E_INVAL; goto dec_psoc_ref; } @@ -990,7 +1014,7 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, goto runtime_failure; } - status = cdp_runtime_suspend(dp_soc, txrx_pdev); + status = cdp_runtime_suspend(dp_soc, pdev_id); if (status != QDF_STATUS_SUCCESS) goto runtime_failure; @@ -1008,6 +1032,8 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, if (status != QDF_STATUS_SUCCESS) goto resume_htc; + hif_pm_set_link_state(hif_ctx, HIF_PM_LINK_STATE_DOWN); + status = pmo_core_psoc_bus_suspend_req(psoc, QDF_RUNTIME_SUSPEND, &wow_params); if (status != QDF_STATUS_SUCCESS) @@ -1019,6 +1045,13 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, goto pmo_bus_resume; } + pending = cdp_rx_get_pending(cds_get_context(QDF_MODULE_ID_SOC)); + if (pending) { + pmo_debug("Prevent suspend, RX frame pending %d", pending); + status = QDF_STATUS_E_BUSY; + goto resume_hif; + } + if (pld_cb) { begin = qdf_get_log_timestamp_usecs(); ret = pld_cb(); @@ -1047,6 +1080,8 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, PMO_CORE_PSOC_RUNTIME_PM_QDF_BUG(QDF_STATUS_SUCCESS != pmo_core_psoc_configure_resume(psoc, true)); + hif_pm_set_link_state(hif_ctx, HIF_PM_LINK_STATE_UP); + resume_htc: PMO_CORE_PSOC_RUNTIME_PM_QDF_BUG(QDF_STATUS_SUCCESS != pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false)); @@ -1054,7 +1089,7 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc, cdp_runtime_resume: PMO_CORE_PSOC_RUNTIME_PM_QDF_BUG(QDF_STATUS_SUCCESS != - cdp_runtime_resume(dp_soc, txrx_pdev)); + cdp_runtime_resume(dp_soc, pdev_id)); runtime_failure: hif_process_runtime_suspend_failure(hif_ctx); @@ -1074,7 +1109,7 @@ QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc, int ret; void *hif_ctx; void *dp_soc; - void *txrx_pdev; + uint8_t pdev_id; void *htc_ctx; QDF_STATUS status; qdf_time_t begin, end; @@ -1095,11 +1130,12 @@ QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc, hif_ctx = pmo_core_psoc_get_hif_handle(psoc); dp_soc = pmo_core_psoc_get_dp_handle(psoc); - txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc); + pdev_id = pmo_core_psoc_get_txrx_handle(psoc); htc_ctx = pmo_core_psoc_get_htc_handle(psoc); - if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) { - pmo_err("Invalid hif: %pK, dp: %pK, txrx: %pK, htc: %pK", - hif_ctx, dp_soc, txrx_pdev, htc_ctx); + if (!hif_ctx || !dp_soc || !htc_ctx || + pdev_id == OL_TXRX_INVALID_PDEV_ID) { + pmo_err("Invalid hif: %pK, dp: %pK, pdev_id: %d, htc: %pK", + hif_ctx, dp_soc, pdev_id, htc_ctx); status = QDF_STATUS_E_INVAL; goto dec_psoc_ref; } @@ -1126,6 +1162,8 @@ QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc, if (status != QDF_STATUS_SUCCESS) goto fail; + hif_pm_set_link_state(hif_ctx, HIF_PM_LINK_STATE_UP); + status = pmo_core_psoc_configure_resume(psoc, true); if (status != QDF_STATUS_SUCCESS) goto fail; @@ -1139,7 +1177,7 @@ QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc, goto fail; } - status = cdp_runtime_resume(dp_soc, txrx_pdev); + status = cdp_runtime_resume(dp_soc, pdev_id); if (status != QDF_STATUS_SUCCESS) goto fail; @@ -1147,7 +1185,7 @@ QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc, fail: if (status != QDF_STATUS_SUCCESS) - qdf_trigger_self_recovery(QDF_RESUME_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_RESUME_TIMEOUT); dec_psoc_ref: pmo_psoc_put_ref(psoc); @@ -1184,7 +1222,7 @@ QDF_STATUS pmo_core_psoc_send_host_wakeup_ind_to_fw( status = QDF_STATUS_E_FAILURE; goto out; } - pmo_debug("Host wakeup indication sent to fw"); + pmo_info("Host wakeup indication sent to fw"); status = qdf_wait_for_event_completion(&psoc_ctx->wow.target_resume, PMO_RESUME_TIMEOUT); @@ -1193,7 +1231,7 @@ QDF_STATUS pmo_core_psoc_send_host_wakeup_ind_to_fw( pmo_err("Pending commands %d credits %d", pmo_tgt_psoc_get_pending_cmnds(psoc), pmo_tgt_psoc_get_host_credits(psoc)); - qdf_trigger_self_recovery(QDF_RESUME_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_RESUME_TIMEOUT); } else { pmo_debug("Host wakeup received"); } @@ -1265,7 +1303,7 @@ QDF_STATUS pmo_core_psoc_resume_target(struct wlan_objmgr_psoc *psoc, pmo_fatal("Pending commands %d credits %d", pmo_tgt_psoc_get_pending_cmnds(psoc), pmo_tgt_psoc_get_host_credits(psoc)); - qdf_trigger_self_recovery(QDF_RESUME_TIMEOUT); + qdf_trigger_self_recovery(psoc, QDF_RESUME_TIMEOUT); } else { pmo_debug("Host wakeup received"); } @@ -1333,7 +1371,6 @@ void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack) struct pmo_psoc_priv_obj *psoc_ctx; struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)context; void *dp_soc = pmo_core_psoc_get_dp_handle(psoc); - void *txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc); QDF_STATUS status; pmo_enter(); @@ -1358,7 +1395,7 @@ void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack) &psoc_ctx->wow.wow_wake_lock, PMO_WAKE_LOCK_TIMEOUT); else - cdp_process_wow_ack_rsp(dp_soc, txrx_pdev); + cdp_process_wow_ack_rsp(dp_soc, OL_TXRX_PDEV_ID); } pmo_psoc_put_ref(psoc); @@ -1626,3 +1663,28 @@ QDF_STATUS pmo_core_config_modulated_dtim(struct wlan_objmgr_vdev *vdev, pmo_exit(); return status; } + +#ifdef SYSTEM_PM_CHECK +void pmo_core_system_resume(struct wlan_objmgr_psoc *psoc) +{ + struct pmo_psoc_priv_obj *psoc_ctx; + QDF_STATUS status; + + if (!psoc) { + pmo_err("psoc is NULL"); + return; + } + + status = pmo_psoc_get_ref(psoc); + if (status != QDF_STATUS_SUCCESS) { + pmo_err("pmo cannot get the reference out of psoc"); + return; + } + + psoc_ctx = pmo_psoc_get_priv(psoc); + + htc_system_resume(psoc_ctx->htc_hdl); + + pmo_psoc_put_ref(psoc); +} +#endif diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h index 52ebf59c30428d7b911f1ffd244499bd86bc29a7..d15706de88dbe8f13f5ffe672511244c9d96401d 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -116,13 +116,13 @@ * * gEnableDynamicDTIM - Enable Dynamic DTIM * @Min: 0 - * @Max: 9 + * @Max: 10 * @Default: 0 * * This ini is used to enable/disable dynamic DTIM. * * 0 - Disable Dynamic DTIM - * 1 to 5 - SLM will switch to DTIM specified here when host suspends and + * 1 to 10 - SLM will switch to DTIM specified here when host suspends and * switch DTIM1 when host resumes * * Usage: External @@ -132,7 +132,7 @@ #define CFG_PMO_ENABLE_DYNAMIC_DTIM CFG_INI_UINT( \ "gEnableDynamicDTIM", \ 0, \ - 9, \ + 10, \ 0, \ CFG_VALUE_OR_DEFAULT, \ "Enable Dynamic DTIM") @@ -193,35 +193,59 @@ /* * - * gEnablePowerSaveOffload - Enable Power Save Offload + * gOptimizedPowerManagement - Optimized Power Management * @Min: 0 - * @Max: 5 - * @Default: 2 + * @Max: 1 + * @Default: 1 * - * This ini is used to set Power Save Offload configuration: - * Current values of gEnablePowerSaveOffload: - * 0 -> Power save offload is disabled - * 1 -> Legacy Power save enabled + Deep sleep Disabled - * 2 -> QPower enabled + Deep sleep Disabled - * 3 -> Legacy Power save enabled + Deep sleep Enabled - * 4 -> QPower enabled + Deep sleep Enabled - * 5 -> Duty cycling QPower enabled + * This ini is used to set Optimized Power Management configuration: + * Current values of gOptimizedPowerManagement: + * 0 -> Disable optimized power management + * 1 -> Enable optimized power management * * Related: None * - * Supported Feature: Power Save + * Supported Feature: Optimized Power Management * * Usage: External * * */ -#define CFG_PMO_POWERSAVE_OFFLOAD CFG_INI_UINT( \ - "gEnablePowerSaveOffload", \ +#define CFG_PMO_POWERSAVE_MODE CFG_INI_UINT( \ + "gOptimizedPowerManagement", \ 0, \ - 5, \ - 2, \ + 1, \ + 1, \ CFG_VALUE_OR_DEFAULT, \ - "Enable Power Save Offload") + "Optimized Power Management") + +/* + * + * enable_mod_dtim_on_system_suspend - enable modulated DTIM + * on system suspend display off case + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to set modulated DTIM configuration: + * Current values of enable_mod_dtim_on_system_suspend: + * 0 -> Modulated DTIM will be enabled for every wow entry + * (RTPM wow + System suspend wow) + * 1 -> Enable modulated DTIM only for System suspend wow. + * For RTPM wow, the device will stay in DTIM 1 (non-modulated DTIM) + * + * Related: None + * + * Supported Feature: Modulated DTIM + * + * Usage: External + * + * + */ +#define CFG_PMO_MOD_DTIM_ON_SYS_SUSPEND CFG_INI_BOOL( \ + "enable_mod_dtim_on_system_suspend", \ + 0, \ + "Modulated DTIM on System suspend wow") /* * @@ -429,7 +453,7 @@ CFG(CFG_PMO_ENABLE_DYNAMIC_DTIM) \ CFG(CFG_PMO_ENABLE_MODULATED_DTIM) \ CFG(CFG_PMO_MC_ADDR_LIST_ENABLE) \ - CFG(CFG_PMO_POWERSAVE_OFFLOAD) \ + CFG(CFG_PMO_POWERSAVE_MODE) \ CFG(CFG_PMO_MAX_PS_POLL) \ CFG(CFG_PMO_WOWLAN_DEAUTH_ENABLE) \ CFG(CFG_PMO_WOWLAN_DISASSOC_ENABLE) \ @@ -437,6 +461,7 @@ CFG(CFG_PMO_ACTIVE_MODE) \ CFG(CFG_PMO_PWR_FAILURE) \ CFG(CFG_PMO_WOW_DATA_INACTIVITY_TIMEOUT) \ - CFG(CFG_RA_RATE_LIMIT_INTERVAL) + CFG(CFG_RA_RATE_LIMIT_INTERVAL) \ + CFG(CFG_PMO_MOD_DTIM_ON_SYS_SUSPEND) #endif /* WLAN_PMO_COMMON_CFG_H__ */ diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h index f9b95c8bb69a0b19098794b42e5bbcfcb7eca2c6..d905c0dc0e168bbfba97e8f376d3c11fbdbdce3e 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -85,11 +85,11 @@ enum pmo_beacon_dtim_policy { * @pmo_sta_ps_param_inactivity_time: TX/RX inactivity time in msec before going to sleep. * @pmo_sta_ps_param_uapsd: Set uapsd configuration. - * @pmo_sta_ps_param_qpower_pspoll_count: No of PS-Poll to send before - STA wakes up in QPower Mode. - * @pmo_sta_ps_enable_qpower: Enable QPower - * @pmo_sta_ps_param_qpower_max_tx_before_wake: Number of TX frames before the - entering the Active state + * @pmo_sta_ps_param_advanced_power_pspoll_count: No of PS-Poll to send before + STA wakes up in Advanced Power Save Mode. + * @pmo_sta_ps_enable_advanced_power: Enable Advanced Power Save + * @pmo_sta_ps_param_advanced_power_max_tx_before_wake: Number of TX frames + before the entering the Active state * @pmo_sta_ps_param_ito_repeat_count: Indicates ito repeated count */ enum pmo_sta_powersave_param { @@ -98,42 +98,12 @@ enum pmo_sta_powersave_param { pmo_sta_ps_param_pspoll_count = 2, pmo_sta_ps_param_inactivity_time = 3, pmo_sta_ps_param_uapsd = 4, - pmo_sta_ps_param_qpower_pspoll_count = 5, - pmo_sta_ps_enable_qpower = 6, - pmo_sta_ps_param_qpower_max_tx_before_wake = 7, + pmo_sta_ps_param_advanced_power_pspoll_count = 5, + pmo_sta_ps_enable_advanced_power = 6, + pmo_sta_ps_param_advanced_power_max_tx_before_wake = 7, pmo_sta_ps_param_ito_repeat_count = 8, }; -/** - * enum powersave_qpower_mode: QPOWER modes - * @pmo_qpower_disabled: Qpower is disabled - * @pmo_qpower_enabled: Qpower is enabled - * @pmo_qpower_duty_cycling: Qpower is enabled with duty cycling - */ -enum pmo_power_save_qpower_mode { - pmo_qpower_disabled = 0, - pmo_qpower_enabled = 1, - pmo_qpower_duty_cycling = 2 -}; - -/** - * enum powersave_qpower_mode: powersave_mode - * @pmo_ps_not_supported: Power save is not supported - * @pmo_ps_legacy_no_deep_sleep: Legacy pwr save enabled and deep sleep disabled - * @pmo_ps_qpower_no_deep_sleep: QPOWER enabled and deep sleep disabled - * @pmo_ps_legacy_deep_sleep: Legacy power save enabled and deep sleep enabled - * @pmo_ps_qpower_deep_sleep: QPOWER enabled and deep sleep enabled - * @pmo_ps_duty_cycling_qpower: QPOWER enabled in duty cycling mode - */ -enum pmo_powersave_mode { - pmo_ps_not_supported = 0, - pmo_ps_legacy_no_deep_sleep = 1, - pmo_ps_qpower_no_deep_sleep = 2, - pmo_ps_legacy_deep_sleep = 3, - pmo_ps_qpower_deep_sleep = 4, - pmo_ps_duty_cycling_qpower = 5 -}; - /** * enum wow_resume_trigger - resume trigger override setting values * @PMO_WOW_RESUME_TRIGGER_DEFAULT: fw to use platform default resume trigger @@ -183,21 +153,13 @@ enum pmo_wow_enable_type { }; /** - * enum powersave_qpower_mode: powersave_mode - * @PS_NOT_SUPPORTED: Power save is not supported - * @PS_LEGACY_NODEEPSLEEP: Legacy power save enabled and deep sleep disabled - * @PS_QPOWER_NODEEPSLEEP: QPOWER enabled and deep sleep disabled - * @PS_LEGACY_DEEPSLEEP: Legacy power save enabled and deep sleep enabled - * @PS_QPOWER_DEEPSLEEP: QPOWER enabled and deep sleep enabled - * @PS_DUTY_CYCLING_QPOWER: QPOWER enabled in duty cycling mode + * enum powersave_mode - powersave_mode + * @PMO_PS_ADVANCED_POWER_SAVE_DISABLE: Disable advanced power save mode + * @PMO_PS_ADVANCED_POWER_SAVE_ENABLE: Enable power save mode */ enum powersave_mode { - PS_NOT_SUPPORTED = 0, - PS_LEGACY_NODEEPSLEEP = 1, - PS_QPOWER_NODEEPSLEEP = 2, - PS_LEGACY_DEEPSLEEP = 3, - PS_QPOWER_DEEPSLEEP = 4, - PS_DUTY_CYCLING_QPOWER = 5 + PMO_PS_ADVANCED_POWER_SAVE_DISABLE = 0, + PMO_PS_ADVANCED_POWER_SAVE_ENABLE = 1 }; #define PMO_TARGET_SUSPEND_TIMEOUT (4000) @@ -341,6 +303,8 @@ enum active_apf_mode { * @active_mc_bc_apf_mode: Setting that determines how APF is applied in * active mode for MC/BC packets * @ito_repeat_count: Indicates ito repeated count + * @is_mod_dtim_on_sys_suspend_enabled: true when mod dtim is enabled for + * system suspend wow else false */ struct pmo_psoc_cfg { bool ptrn_match_enable_all_vdev; @@ -403,6 +367,7 @@ struct pmo_psoc_cfg { enum active_apf_mode active_uc_apf_mode; enum active_apf_mode active_mc_bc_apf_mode; uint8_t ito_repeat_count; + bool is_mod_dtim_on_sys_suspend_enabled; }; /** diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h index 228d7a8e6a119f187840be1dfbde33e49933e269..2ff6c1f000046191e962ee2a5be5cf4d885b5964 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h @@ -250,24 +250,6 @@ pmo_register_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc, QDF_STATUS pmo_unregister_get_beacon_interval_callback(struct wlan_objmgr_psoc *psoc); -/** - * pmo_register_get_vdev_dp_handle(): API to register get vdev datapath handle - * @psoc: objmgr psoc handle - * @handler: get vdev datapath handle callback - * - * Return QDF_STATUS status - in case of success else return error - */ -QDF_STATUS pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc, - pmo_get_vdev_dp_handle handler); - -/** - * pmo_unregister_get_vdev_dp_handle(): API to unregister get vdev dp handle - * @psoc: objmgr psoc handle - * - * Return QDF_STATUS status - in case of success else return error - */ -QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc); - /** * pmo_register_is_device_in_low_pwr_mode(): API to get register device power * save check notifier. @@ -401,19 +383,6 @@ pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } -static inline QDF_STATUS -pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc, - pmo_get_vdev_dp_handle handler) -{ - return QDF_STATUS_SUCCESS; -} - -static inline QDF_STATUS -QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc) -{ - return QDF_STATUS_SUCCESS; -} - static inline QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc, pmo_is_device_in_low_pwr_mode handler) diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index a662bb700b25b4ecef09675aa7bccdd09a45ff13..7d7d06c57bf4dc6b63e62264a97cbb74fddaa9ec 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -791,14 +791,14 @@ void ucfg_pmo_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc, void *hif_handle); /** - * ucfg_pmo_psoc_set_txrx_handle() - Set psoc pdev txrx layer handle + * ucfg_pmo_psoc_set_txrx_pdev_id() - Set psoc pdev txrx layer handle * @psoc: objmgr psoc handle - * @txrx_handle: pdev txrx context handle + * @txrx_pdev_id: txrx pdev identifier * * Return: None */ -void ucfg_pmo_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle); +void ucfg_pmo_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t txrx_pdev_id); /** * ucfg_pmo_psoc_user_space_suspend_req() - Handles user space suspend req @@ -1455,9 +1455,9 @@ ucfg_pmo_psoc_set_hif_handle( } static inline void -ucfg_pmo_psoc_set_txrx_handle( +ucfg_pmo_psoc_set_txrx_pdev_id( struct wlan_objmgr_psoc *psoc, - void *txrx_handle) + uint8_t txrx_pdev_id) { } @@ -1956,4 +1956,20 @@ ucfg_pmo_get_runtime_pm_delay(struct wlan_objmgr_psoc *psoc) */ bool ucfg_pmo_get_enable_sap_suspend(struct wlan_objmgr_psoc *psoc); + +#ifdef SYSTEM_PM_CHECK +/** + * ucfg_pmo_notify_system_resume() - system resume notification to pmo + * @psoc: pointer to psoc object + * + * Return: None + */ +void +ucfg_pmo_notify_system_resume(struct wlan_objmgr_psoc *psoc); +#else +static inline +void ucfg_pmo_notify_system_resume(struct wlan_objmgr_psoc *psoc) +{ +} +#endif #endif /* end of _WLAN_PMO_UCFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c index dd34891057f58c7f70f9cf28a08cd2c4f918be30..b6a458cf80c4da8473ab086803ab8a38d9e3a667 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c @@ -734,47 +734,6 @@ pmo_unregister_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } -QDF_STATUS pmo_register_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc, - pmo_get_vdev_dp_handle handler) -{ - struct pmo_psoc_priv_obj *psoc_ctx; - - if (!psoc) { - QDF_BUG(psoc); - pmo_err("psoc is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - if (!handler) { - QDF_BUG(handler); - pmo_err("pmo_get_vdev_dp_handle is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - pmo_psoc_with_ctx(psoc, psoc_ctx) { - psoc_ctx->get_vdev_dp_handle = handler; - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS pmo_unregister_get_vdev_dp_handle(struct wlan_objmgr_psoc *psoc) -{ - struct pmo_psoc_priv_obj *psoc_ctx; - - if (!psoc) { - QDF_BUG(psoc); - pmo_err("psoc is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - pmo_psoc_with_ctx(psoc, psoc_ctx) { - psoc_ctx->get_vdev_dp_handle = NULL; - } - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS pmo_register_get_dtim_period_callback(struct wlan_objmgr_psoc *psoc, pmo_get_dtim_period handler) { diff --git a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 1e9b3dcc335594135ead4193591d7d58209f36e6..641052d94949cb488f55ade98a775824d582e9b9 100644 --- a/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -370,10 +370,10 @@ void ucfg_pmo_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc, pmo_core_psoc_set_hif_handle(psoc, hif_handle); } -void ucfg_pmo_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc, - void *txrx_handle) +void ucfg_pmo_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t txrx_pdev_id) { - pmo_core_psoc_set_txrx_handle(psoc, txrx_handle); + pmo_core_psoc_set_txrx_pdev_id(psoc, txrx_pdev_id); } void ucfg_pmo_psoc_handle_initial_wake_up(void *cb_ctx) @@ -713,20 +713,13 @@ ucfg_pmo_get_max_ps_poll(struct wlan_objmgr_psoc *psoc) uint8_t ucfg_pmo_power_save_offload_enabled(struct wlan_objmgr_psoc *psoc) { - uint8_t powersave_offload_enabled; + uint8_t powersave_offload_enabled = PMO_PS_ADVANCED_POWER_SAVE_ENABLE; struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc); if (!pmo_psoc_ctx->psoc_cfg.max_ps_poll || !pmo_psoc_ctx->psoc_cfg.power_save_mode) powersave_offload_enabled = pmo_psoc_ctx->psoc_cfg.power_save_mode; - else if ((pmo_psoc_ctx->psoc_cfg.power_save_mode == - PS_QPOWER_NODEEPSLEEP) || - (pmo_psoc_ctx->psoc_cfg.power_save_mode == - PS_LEGACY_NODEEPSLEEP)) - powersave_offload_enabled = PS_LEGACY_NODEEPSLEEP; - else - powersave_offload_enabled = PS_LEGACY_DEEPSLEEP; pmo_debug("powersave offload enabled type:%d", powersave_offload_enabled); @@ -870,3 +863,10 @@ ucfg_pmo_get_active_mc_bc_apf_mode(struct wlan_objmgr_psoc *psoc) return pmo_psoc_ctx->psoc_cfg.active_mc_bc_apf_mode; } + +#ifdef SYSTEM_PM_CHECK +void ucfg_pmo_notify_system_resume(struct wlan_objmgr_psoc *psoc) +{ + pmo_core_system_resume(psoc); +} +#endif diff --git a/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/inc/target_if_ftm_time_sync.h b/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/inc/target_if_ftm_time_sync.h new file mode 100644 index 0000000000000000000000000000000000000000..566577e4af26659ee2f58986c20f25542e6b88a1 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/inc/target_if_ftm_time_sync.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Declare various api/struct which shall be used + * by FTM time sync component for wmi cmd (tx path) and + * event (rx) handling. + */ + +#ifndef _TARGET_IF_FTM_TIME_SYNC_H_ +#define _TARGET_IF_FTM_TIME_SYNC_H_ + +#include +#include +#include "wlan_ftm_time_sync_public_struct.h" + +/** + * target_if_ftm_time_sync_register_rx_ops() - Register FTM TIME SYNC component + * RX ops + * @rx_ops: FTM time sync component reception ops + * + * Return: None + */ +void target_if_ftm_time_sync_register_rx_ops(struct wlan_ftm_timesync_rx_ops + *rx_ops); + +/** + * target_if_ftm_time_sync_register_tx_ops() - Register FTM TIME SYNC component + * TX OPS + * @tx_ops: FTM time sync component transmit ops + * + * Return: None + */ +void target_if_ftm_time_sync_register_tx_ops(struct wlan_ftm_timesync_tx_ops + *tx_ops); +#endif /*_TARGET_IF_FTM_TIME_SYNC_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/src/target_if_ftm_time_sync.c b/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/src/target_if_ftm_time_sync.c new file mode 100644 index 0000000000000000000000000000000000000000..54b82943ceba64867a0f7b881ce583dcceeaae60 --- /dev/null +++ b/drivers/staging/qcacld-3.0/components/target_if/ftm_time_sync/src/target_if_ftm_time_sync.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: Target interface file for ftm time sync component to + * Implement api's which shall be used by ftm time sync component + * in target_if internally. + */ + +#include "target_if.h" +#include "target_if_ftm_time_sync.h" +#include "wlan_ftm_time_sync_public_struct.h" +#include + +static QDF_STATUS +target_if_ftm_time_sync_send_qtime(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint64_t lpass_ts) +{ + wmi_unified_t wmi_hdl; + + wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_hdl) + return QDF_STATUS_E_FAILURE; + + return wmi_unified_send_wlan_time_sync_qtime(wmi_hdl, vdev_id, + lpass_ts); +} + +static QDF_STATUS +target_if_ftm_time_sync_send_trigger(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, bool mode) +{ + wmi_unified_t wmi_hdl; + + wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_hdl) + return QDF_STATUS_E_FAILURE; + + return wmi_unified_send_wlan_time_sync_ftm_trigger(wmi_hdl, vdev_id, + mode); +} + +static int +target_if_time_sync_ftm_start_stop_event_handler(ol_scn_t scn_handle, + uint8_t *data, uint32_t len) +{ + struct ftm_time_sync_start_stop_params param; + struct wlan_objmgr_psoc *psoc; + wmi_unified_t wmi_handle; + + if (!data) { + target_if_err("%s: invalid pointer", __func__); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn_handle); + if (!psoc) { + target_if_err("psoc ptr is NULL"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return -EINVAL; + } + + if (wmi_unified_extract_time_sync_ftm_start_stop_params( + wmi_handle, data, ¶m) != QDF_STATUS_SUCCESS) { + target_if_err("Extraction of time sync ftm start stop failed"); + return -EINVAL; + } + + return 0; +} + +static QDF_STATUS +target_if_ftm_time_sync_start_stop_event(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + wmi_unified_t wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event( + wmi_handle, wmi_wlan_time_sync_ftm_start_stop_event_id, + target_if_time_sync_ftm_start_stop_event_handler); + if (status) { + target_if_err("Ftm timesync start stop event register failed"); + return QDF_STATUS_E_FAILURE; + } + + return status; +} + +static int +target_if_time_sync_master_slave_offset_event_handler(ol_scn_t scn_handle, + uint8_t *data, + uint32_t len) +{ + struct ftm_time_sync_offset param; + struct wlan_objmgr_psoc *psoc; + wmi_unified_t wmi_handle; + + if (!data) { + target_if_err("%s: invalid pointer", __func__); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn_handle); + if (!psoc) { + target_if_err("psoc ptr is NULL"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return -EINVAL; + } + + if (wmi_unified_extract_time_sync_ftm_offset( + wmi_handle, data, ¶m) != QDF_STATUS_SUCCESS) { + target_if_err("Extraction of timesync ftm offset param failed"); + return -EINVAL; + } + + return 0; +} + +static QDF_STATUS +target_if_ftm_time_sync_master_slave_offset(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + wmi_unified_t wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event( + wmi_handle, + wmi_wlan_time_sync_q_master_slave_offset_eventid, + target_if_time_sync_master_slave_offset_event_handler); + if (status) { + target_if_err("Ftm timesync offset event register failed"); + return QDF_STATUS_E_FAILURE; + } + + return status; +} + +void +target_if_ftm_time_sync_register_rx_ops(struct wlan_ftm_timesync_rx_ops *rx_ops) +{ + if (!rx_ops) { + target_if_err("FTM timesync rx_ops is null"); + return; + } + + rx_ops->ftm_timesync_register_start_stop = + target_if_ftm_time_sync_start_stop_event; + rx_ops->ftm_timesync_regiser_master_slave_offset = + target_if_ftm_time_sync_master_slave_offset; +} + +void +target_if_ftm_time_sync_register_tx_ops(struct wlan_ftm_timesync_tx_ops *tx_ops) +{ + if (!tx_ops) { + target_if_err("FTM timesync tx_ops is null"); + return; + } + + tx_ops->ftm_time_sync_send_qtime = target_if_ftm_time_sync_send_qtime; + tx_ops->ftm_time_sync_send_trigger = + target_if_ftm_time_sync_send_trigger; +} + diff --git a/drivers/staging/qcacld-3.0/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c b/drivers/staging/qcacld-3.0/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c index 5cbed5b4e1ed7a6c047dd529189b98e4e6fdc9c6..1b178b5d4101f683d3fb91e0ee64bd618b3ad785 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c +++ b/drivers/staging/qcacld-3.0/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c @@ -68,8 +68,8 @@ static int target_if_interop_issues_ap_event_handler(ol_scn_t sc, if (ret) return -EINVAL; - target_if_debug("interop issues ap macaddr: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(data.rap_addr.bytes)); + target_if_debug("interop issues ap macaddr: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(data.rap_addr.bytes)); return tgt_interop_issues_ap_info_callback(psoc, &data); } diff --git a/drivers/staging/qcacld-3.0/components/target_if/nan/inc/target_if_nan.h b/drivers/staging/qcacld-3.0/components/target_if/nan/inc/target_if_nan.h index be4a57a245eaa1774b377fc2400f5ede1ee3069b..38370cdde96326006c124f542ce71996041227a4 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/nan/inc/target_if_nan.h +++ b/drivers/staging/qcacld-3.0/components/target_if/nan/inc/target_if_nan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -98,4 +98,14 @@ QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc); * Return: 0 for success or error code */ int target_if_nan_rsp_handler(ol_scn_t scn, uint8_t *data, uint32_t len); + +/** + * target_if_nan_set_vdev_feature_config() - Init NAN feature config params + * @psoc: Pointer to PSOC Object + * @vdev_id: vdev_id of the current vdev + * + * This function updates NAN feature config bitmap to firmware + */ +void target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif /* _WIFI_POS_TGT_IF_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/target_if/nan/src/target_if_nan.c b/drivers/staging/qcacld-3.0/components/target_if/nan/src/target_if_nan.c index 3706b3f1108561bac7f3ba3a0eeab5d2e6ede3bb..8cad50898833d074c8e22134af03cd114e1c3105 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/nan/src/target_if_nan.c +++ b/drivers/staging/qcacld-3.0/components/target_if/nan/src/target_if_nan.c @@ -27,6 +27,7 @@ #include "wlan_nan_api.h" #include "wmi_unified_api.h" #include "scheduler_api.h" +#include static void target_if_nan_event_flush_cb(struct scheduler_msg *msg) { @@ -1161,3 +1162,29 @@ QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc) else return QDF_STATUS_SUCCESS; } + +void target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + QDF_STATUS status; + uint32_t nan_features; + struct vdev_set_params param; + wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return; + } + + ucfg_get_nan_feature_config(psoc, &nan_features); + target_if_debug("vdev_id:%d NAN features:0x%x", vdev_id, nan_features); + + param.vdev_id = vdev_id; + param.param_id = WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES; + param.param_value = nan_features; + + status = wmi_unified_vdev_set_param_send(wmi_handle, ¶m); + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("failed to set NAN_CONFIG_FEATURES(status = %d)", + status); +} diff --git a/drivers/staging/qcacld-3.0/components/target_if/p2p/src/target_if_p2p.c b/drivers/staging/qcacld-3.0/components/target_if/p2p/src/target_if_p2p.c index dbce5991f92f8f9152e5ac59286ea28ec2542756..df39148aa095e6005d4f4454351d34ad42454569 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/p2p/src/target_if_p2p.c +++ b/drivers/staging/qcacld-3.0/components/target_if/p2p/src/target_if_p2p.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -361,7 +361,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, target_if_debug("psoc:%pK, vdev_id:%d disable_noa:%d", psoc, vdev_id, disable_noa); - param.if_id = vdev_id; + param.vdev_id = vdev_id; param.param_id = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO; param.param_value = (uint32_t)disable_noa; diff --git a/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/inc/target_if_pkt_capture.h b/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/inc/target_if_pkt_capture.h deleted file mode 100644 index 10ded23c9568d6ccac43f3c28febf43f49a3dedf..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/inc/target_if_pkt_capture.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Declare various api/struct which shall be used - * by packet capture component for wmi cmd (tx path) and - * event (rx) handling. - */ - -#ifndef _TARGET_IF_PKT_CAPTURE_H_ -#define _TARGET_IF_PKT_CAPTURE_H_ - -#include -#include -#include -#include -#include -#include - -/** - * target_if_pkt_capture_register_rx_ops() - Register packet capture RX ops - * @rx_ops: packet capture component reception ops - * Return: None - */ -void -target_if_pkt_capture_register_rx_ops(struct wlan_pkt_capture_rx_ops *rx_ops); - -/** - * target_if_pkt_capture_register_tx_ops() - Register packet capture TX ops - * @tx_ops: pkt capture component transmit ops - * - * Return: None - */ -void target_if_pkt_capture_register_tx_ops(struct wlan_pkt_capture_tx_ops - *tx_ops); -#endif /* _TARGET_IF_PKT_CAPTURE_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/src/target_if_pkt_capture.c b/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/src/target_if_pkt_capture.c deleted file mode 100644 index 37df8f01bc05d8706cfb87a57bfae835a43fefa2..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/components/target_if/pkt_capture/src/target_if_pkt_capture.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/** - * DOC: Target interface file for pkt_capture component to - * Implement api's which shall be used by pkt_capture component - * in target_if internally. - */ - -#include -#include -#include -#include - -/** - * target_if_set_packet_capture_mode() - set packet capture mode - * @psoc: pointer to psoc object - * @vdev_id: vdev id - * @mode: mode to set - * - * Return: QDF_STATUS - */ -static QDF_STATUS -target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, - enum pkt_capture_mode mode) -{ - wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct vdev_set_params param; - - if (!wmi_handle) { - target_if_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - target_if_debug("psoc:%pK, vdev_id:%d mode:%d", - psoc, vdev_id, mode); - - param.if_id = vdev_id; - param.param_id = WMI_VDEV_PARAM_PACKET_CAPTURE_MODE; - param.param_value = (uint32_t)mode; - - status = wmi_unified_vdev_set_param_send(wmi_handle, ¶m); - if (QDF_IS_STATUS_SUCCESS(status)) - ucfg_pkt_capture_set_pktcap_mode(psoc, mode); - else - pkt_capture_err("failed to set packet capture mode"); - - return status; -} - -/** - * target_if_mgmt_offload_data_event_handler() - offload event handler - * @handle: scn handle - * @data: mgmt data - * @data_len: data length - * - * Process management offload frame. - * - * Return: 0 for success or error code - */ -static int -target_if_mgmt_offload_data_event_handler(void *handle, uint8_t *data, - uint32_t data_len) -{ - static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1; - struct mgmt_offload_event_params params; - struct wmi_unified *wmi_handle; - struct wlan_objmgr_psoc *psoc; - struct wlan_objmgr_pdev *pdev; - QDF_STATUS status; - qdf_nbuf_t wbuf; - - psoc = target_if_get_psoc_from_scn_hdl(handle); - if (!psoc) { - pkt_capture_err("psoc is NULL"); - return -EINVAL; - } - - wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); - if (!wmi_handle) { - target_if_err("Invalid WMI handle"); - return -EINVAL; - } - - pdev = target_if_get_pdev_from_scn_hdl(handle); - if (!pdev) { - pkt_capture_err("pdev is NULL"); - return -EINVAL; - } - - if (!(ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_MGMT_ONLY)) - return -EINVAL; - - status = wmi_unified_extract_vdev_mgmt_offload_event(wmi_handle, data, - ¶ms); - if (QDF_IS_STATUS_ERROR(status)) { - pkt_capture_err("Extract mgmt offload event failed"); - return -EINVAL; - } - - if (!params.buf) { - pkt_capture_err("Mgmt offload buf is NULL"); - return -EINVAL; - } - - if (params.buf_len < sizeof(struct ieee80211_hdr_3addr) || - params.buf_len > data_len) { - limit_prints_invalid_len++; - if (limit_prints_invalid_len == RATE_LIMIT) { - pkt_capture_debug( - "Invalid mgmt packet, data_len %u, params.buf_len %u", - data_len, params.buf_len); - limit_prints_invalid_len = 0; - } - return -EINVAL; - } - - wbuf = qdf_nbuf_alloc(NULL, - roundup(params.buf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - if (!wbuf) { - pkt_capture_err("Failed to allocate wbuf for mgmt pkt len(%u)", - params.buf_len); - return -ENOMEM; - } - - qdf_nbuf_put_tail(wbuf, params.buf_len); - qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL); - qdf_mem_copy(qdf_nbuf_data(wbuf), params.buf, params.buf_len); - - status = params.tx_status; - if (QDF_STATUS_SUCCESS != - ucfg_pkt_capture_process_mgmt_tx_data(pdev, ¶ms, - wbuf, status)) - qdf_nbuf_free(wbuf); - - return 0; -} - -/** - * target_if_register_mgmt_data_offload_event() - Register mgmt data offload - * event handler - * @psoc: wlan psoc object - * - * Return: QDF_STATUS - */ -static QDF_STATUS -target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc) -{ - wmi_unified_t wmi_handle; - - PKT_CAPTURE_ENTER(); - - if (!psoc) { - pkt_capture_err("psoc got NULL"); - return QDF_STATUS_E_FAILURE; - } - wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); - - if (ucfg_pkt_capture_get_mode(psoc) && - wmi_service_enabled(wmi_handle, - wmi_service_packet_capture_support)) { - uint8_t status; - - status = wmi_unified_register_event_handler( - wmi_handle, - wmi_mgmt_offload_data_event_id, - target_if_mgmt_offload_data_event_handler, - WMI_RX_WORK_CTX); - if (status) { - pkt_capture_err("Failed to register MGMT offload handler"); - return QDF_STATUS_E_FAILURE; - } - } - - PKT_CAPTURE_EXIT(); - - return QDF_STATUS_SUCCESS; -} - -/** - * target_if_unregister_mgmt_data_offload_event() - Unregister mgmt data offload - * event handler - * @psoc: wlan psoc object - * - * Return: QDF_STATUS - */ -static QDF_STATUS -target_if_unregister_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc) -{ - wmi_unified_t wmi_handle; - QDF_STATUS status; - - wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); - if (!wmi_handle) { - pkt_capture_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - status = wmi_unified_unregister_event(wmi_handle, - wmi_mgmt_offload_data_event_id); - if (status) - pkt_capture_err("unregister mgmt data offload event cb failed"); - - return status; -} - -void -target_if_pkt_capture_register_rx_ops(struct wlan_pkt_capture_rx_ops *rx_ops) -{ - if (!rx_ops) { - target_if_err("packet capture rx_ops is null"); - return; - } - - rx_ops->pkt_capture_register_ev_handlers = - target_if_register_mgmt_data_offload_event; - - rx_ops->pkt_capture_unregister_ev_handlers = - target_if_unregister_mgmt_data_offload_event; -} - -void -target_if_pkt_capture_register_tx_ops(struct wlan_pkt_capture_tx_ops *tx_ops) -{ - if (!tx_ops) { - target_if_err("packet capture tx_ops is null"); - return; - } - - tx_ops->pkt_capture_send_mode = target_if_set_packet_capture_mode; -} diff --git a/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_lphb.c b/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_lphb.c index 02c79de6d0542c0a01fa4ae9f7f83f4ceacf5655..0657676bf341ac0742b042ce0dbe1ccb25913c7f 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_lphb.c +++ b/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_lphb.c @@ -76,12 +76,12 @@ QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc, target_if_info("PMO --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, " "dev_ip=%08x, src_port=%d, dst_port=%d, timeout=%d, " - "session=%d, gateway_mac= %pM, time_period_sec=%d," + "session=%d, gateway_mac= "QDF_MAC_ADDR_FMT", time_period_sec=%d," "tcp_sn=%d", ts_lphb_tcp_param->srv_ip, ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port, ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout, ts_lphb_tcp_param->session, - ts_lphb_tcp_param->gateway_mac.bytes, + QDF_MAC_ADDR_REF(ts_lphb_tcp_param->gateway_mac.bytes), ts_lphb_tcp_param->time_period_sec, ts_lphb_tcp_param->tcp_sn); /* fill in values */ @@ -158,12 +158,12 @@ QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc, target_if_info("HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, " "dst_port=%d, interval=%d, timeout=%d, session=%d, " - "gateway_mac= %pM", + "gateway_mac= "QDF_MAC_ADDR_FMT, ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip, ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port, ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout, ts_lphb_udp_param->session, - ts_lphb_udp_param->gateway_mac.bytes); + QDF_MAC_ADDR_REF(ts_lphb_udp_param->gateway_mac.bytes)); /* fill in values */ hb_udp_params_fp.vdev_id = ts_lphb_udp_param->session; diff --git a/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_suspend_resume.c b/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_suspend_resume.c index fd61755db0863f373112cf690fdd0dbf4f437861..a1fc8a76c7c302bf22cab5954f1d09fbc3eea884 100644 --- a/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_suspend_resume.c +++ b/drivers/staging/qcacld-3.0/components/target_if/pmo/src/target_if_pmo_suspend_resume.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -74,7 +74,7 @@ QDF_STATUS target_if_pmo_send_vdev_update_param_req( return QDF_STATUS_E_INVAL; } - param.if_id = vdev_id; + param.vdev_id = vdev_id; param.param_id = param_id; param.param_value = param_value; target_if_debug("set vdev param vdev_id: %d value: %d for param_id: %d", @@ -112,7 +112,7 @@ QDF_STATUS target_if_pmo_send_vdev_ps_param_req( * result resume right after suspend (WOW_ENABLE). */ switch (param_id) { - case pmo_sta_ps_enable_qpower: + case pmo_sta_ps_enable_advanced_power: param_id = WMI_STA_PS_ENABLE_QPOWER; break; case pmo_sta_ps_param_inactivity_time: @@ -127,7 +127,7 @@ QDF_STATUS target_if_pmo_send_vdev_ps_param_req( } sta_ps_param.vdev_id = vdev_id; - sta_ps_param.param = param_id; + sta_ps_param.param_id = param_id; sta_ps_param.value = param_value; target_if_debug("set vdev param vdev_id: %d value: %d for param_id: %d", vdev_id, param_value, param_id); diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_cmds_process.c b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_cmds_process.c index 9c2e74c92ccec4922e26147e726ae4fb09538a87..f5c1f4da59e0b0748a4f8d918daa741fff7e2cf3 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_cmds_process.c +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_cmds_process.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -165,8 +165,8 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + tdls_debug("for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; status = scheduler_post_message(QDF_MODULE_ID_TDLS, @@ -228,8 +228,8 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); + tdls_debug("for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(delstareq->peermac.bytes)); msg.type = soc_obj->tdls_del_sta_req; msg.bodyptr = delstareq; status = scheduler_post_message(QDF_MODULE_ID_TDLS, @@ -311,8 +311,8 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) qdf_mem_copy(&addstareq->supported_rates, update_peer->supported_rates, update_peer->supported_rates_len); - tdls_debug("for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + tdls_debug("for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; @@ -452,25 +452,25 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) peer = tdls_get_peer(vdev_obj, mac); if (!peer) { - tdls_err("peer: " QDF_MAC_ADDR_STR " not exist. invalid", - QDF_MAC_ADDR_ARRAY(mac)); + tdls_err("peer: " QDF_MAC_ADDR_FMT " not exist. invalid", + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_INVAL; goto addrsp; } /* in add station, we accept existing valid sta_id if there is */ if ((peer->link_status > TDLS_LINK_CONNECTING) || - (TDLS_STA_INDEX_CHECK((peer->sta_id)))) { - tdls_notice("link_status %d sta_id %d add peer ignored", - peer->link_status, peer->sta_id); + (peer->valid_entry)) { + tdls_notice("link_status %d add peer ignored", + peer->link_status); status = QDF_STATUS_SUCCESS; goto addrsp; } /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", - QDF_MAC_ADDR_ARRAY(mac)); + tdls_notice(QDF_MAC_ADDR_FMT " TDLS setuping. Req declined.", + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_PERM; goto setlink; } @@ -478,9 +478,9 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) /* first to check if we reached to maximum supported TDLS peer. */ curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDR_STR + tdls_err(QDF_MAC_ADDR_FMT " Request declined. Current %d, Max allowed %d.", - QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + QDF_MAC_ADDR_REF(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); status = QDF_STATUS_E_PERM; goto setlink; @@ -490,8 +490,11 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) TDLS_LINK_CONNECTING, TDLS_LINK_SUCCESS); status = tdls_pe_add_peer(req); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err(QDF_MAC_ADDR_FMT " add peer failed with status %d", + QDF_MAC_ADDR_REF(mac), status); goto setlink; + } return QDF_STATUS_SUCCESS; @@ -628,8 +631,8 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * there is no harm to double-check. */ if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { - tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_err(QDF_MAC_ADDR_FMT " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_REF(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, tdls_soc->max_num_tdls_sta); @@ -640,8 +643,8 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * code to supplicant */ tdls_validate->status_code = QDF_STATUS_E_RESOURCES; - tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_err(QDF_MAC_ADDR_FMT " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_REF(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, tdls_soc->max_num_tdls_sta); @@ -692,17 +695,17 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) /* if tdls_mode is disabled, then decline the peer's request */ if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { - tdls_notice(QDF_MAC_ADDR_STR + tdls_notice(QDF_MAC_ADDR_FMT " TDLS mode is disabled. action %d declined.", - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + QDF_MAC_ADDR_REF(tdls_validate->peer_mac), tdls_validate->action_code); return -ENOTSUPP; } if (tdls_soc->tdls_nss_switch_in_progress) { tdls_err("nss switch in progress, action %d declined " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, tdls_validate->action_code, - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + QDF_MAC_ADDR_REF(tdls_validate->peer_mac)); return -EAGAIN; } } @@ -711,9 +714,9 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (tdls_is_progress(tdls_vdev, tdls_validate->peer_mac, true)) { tdls_err("setup is ongoing. action %d declined for " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, tdls_validate->action_code, - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + QDF_MAC_ADDR_REF(tdls_validate->peer_mac)); return -EPERM; } } @@ -745,8 +748,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) tdls_validate->peer_mac); if (curr_peer) { if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - tdls_err(QDF_MAC_ADDR_STR " already connected action %d declined.", - QDF_MAC_ADDR_ARRAY( + tdls_err(QDF_MAC_ADDR_FMT " already connected action %d declined.", + QDF_MAC_ADDR_REF( tdls_validate->peer_mac), tdls_validate->action_code); @@ -756,8 +759,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } } - tdls_debug("tdls_mgmt" QDF_MAC_ADDR_STR " action %d, dialog_token %d status %d, len = %zu", - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_debug("tdls_mgmt" QDF_MAC_ADDR_FMT " action %d, dialog_token %d status %d, len = %zu", + QDF_MAC_ADDR_REF(tdls_validate->peer_mac), tdls_validate->action_code, tdls_validate->dialog_token, tdls_validate->status_code, tdls_validate->len); @@ -766,8 +769,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_TEARDOWN == tdls_validate->action_code) { temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); if (!temp_peer) { - tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist", - QDF_MAC_ADDR_ARRAY( + tdls_err(QDF_MAC_ADDR_FMT " peer doesn't exist", + QDF_MAC_ADDR_REF( tdls_validate->peer_mac)); return -EPERM; } @@ -775,8 +778,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_IS_LINK_CONNECTED(temp_peer)) tdls_validate->responder = temp_peer->is_responder; else { - tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", - QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_err(QDF_MAC_ADDR_FMT " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", + QDF_MAC_ADDR_REF(tdls_validate->peer_mac), temp_peer->link_status, tdls_validate->dialog_token, tdls_validate->status_code, @@ -893,44 +896,42 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) curr_peer = tdls_find_peer(vdev_obj, mac); if (!curr_peer) { - tdls_err(QDF_MAC_ADDR_STR " not exist. return invalid", - QDF_MAC_ADDR_ARRAY(mac)); + tdls_err(QDF_MAC_ADDR_FMT " not exist. return invalid", + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_INVAL; goto updatersp; } /* in change station, we accept only when sta_id is valid */ if (curr_peer->link_status == TDLS_LINK_TEARING || - !(TDLS_STA_INDEX_CHECK(curr_peer->sta_id))) { - tdls_err(QDF_MAC_ADDR_STR " link %d. sta %d. update peer rejected", - QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, - curr_peer->sta_id); + !curr_peer->valid_entry) { + tdls_err(QDF_MAC_ADDR_FMT " link %d. update peer rejected", + QDF_MAC_ADDR_REF(mac), curr_peer->link_status); status = QDF_STATUS_E_PERM; goto updatersp; } if (curr_peer->link_status == TDLS_LINK_CONNECTED && - TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) { - tdls_err(QDF_MAC_ADDR_STR " link %d. sta %d. update peer is igonored as tdls state is already connected ", - QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, - curr_peer->sta_id); + curr_peer->valid_entry) { + tdls_err(QDF_MAC_ADDR_FMT " link %d. update peer is igonored as tdls state is already connected ", + QDF_MAC_ADDR_REF(mac), curr_peer->link_status); status = QDF_STATUS_SUCCESS; goto updatersp; } /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", - QDF_MAC_ADDR_ARRAY(mac)); + tdls_notice(QDF_MAC_ADDR_FMT " TDLS setuping. Req declined.", + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_PERM; goto setlink; } curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDR_STR + tdls_err(QDF_MAC_ADDR_FMT " Request declined. Current: %d, Max allowed: %d.", - QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + QDF_MAC_ADDR_REF(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); status = QDF_STATUS_E_PERM; goto setlink; @@ -942,8 +943,11 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) tdls_set_peer_caps(vdev_obj, mac, &req->update_peer_req); status = tdls_pe_update_peer(req); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err(QDF_MAC_ADDR_FMT " update peer failed with status %d", + QDF_MAC_ADDR_REF(mac), status); goto setlink; + } return QDF_STATUS_SUCCESS; @@ -1155,19 +1159,26 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); - if (!peer || !(TDLS_STA_INDEX_CHECK((peer->sta_id)))) { - tdls_err(QDF_MAC_ADDR_STR + if (!peer) { + tdls_err(QDF_MAC_ADDR_FMT " not found, ignore NL80211_TDLS_ENABLE_LINK", - QDF_MAC_ADDR_ARRAY(mac)); + QDF_MAC_ADDR_REF(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + if (!peer->valid_entry) { + tdls_err("invalid peer:" QDF_MAC_ADDR_FMT " link state %d", + QDF_MAC_ADDR_REF(mac), peer->link_status); status = QDF_STATUS_E_INVAL; goto error; } if (soc_obj->tdls_dp_vdev_update) soc_obj->tdls_dp_vdev_update(&soc_obj->soc, - peer->sta_id, - soc_obj->tdls_update_dp_vdev_flags, - false); + wlan_vdev_get_id(vdev), + soc_obj->tdls_update_dp_vdev_flags, + false); cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; cmd.cmd_id = 0; @@ -1263,7 +1274,7 @@ QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) struct tdls_osif_indication ind; psoc = rsp->psoc; - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id, WLAN_TDLS_SB_ID); if (!vdev) { tdls_err("invalid vdev"); @@ -1316,7 +1327,7 @@ QDF_STATUS tdls_send_mgmt_tx_completion( psoc = tx_complete->psoc; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - tx_complete->session_id, + tx_complete->vdev_id, WLAN_TDLS_SB_ID); if (!vdev) { @@ -1385,23 +1396,22 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) conn_rec = soc_obj->tdls_conn_info; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - if (INVALID_TDLS_PEER_ID == conn_rec[sta_idx].sta_id) { + if (!conn_rec[sta_idx].valid_entry) { conn_rec[sta_idx].session_id = rsp->session_id; - conn_rec[sta_idx].sta_id = rsp->sta_id; + conn_rec[sta_idx].valid_entry = true; conn_rec[sta_idx].index = sta_idx; qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, &rsp->peermac); - tdls_debug("TDLS: Add sta mac " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY + tdls_debug("TDLS: Add sta mac at idx %d" + QDF_MAC_ADDR_FMT, sta_idx, + QDF_MAC_ADDR_REF (rsp->peermac.bytes)); break; } } if (sta_idx < soc_obj->max_num_tdls_sta) { - status = tdls_set_sta_id(vdev_obj, rsp->peermac.bytes, - rsp->sta_id); + status = tdls_set_valid(vdev_obj, rsp->peermac.bytes); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("set staid failed"); status = QDF_STATUS_E_FAILURE; @@ -1451,8 +1461,8 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) const uint8_t *macaddr; struct tdls_osif_indication ind; - tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDR_STR, - rsp->session_id, QDF_MAC_ADDR_ARRAY(rsp->peermac.bytes)); + tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDR_FMT, + rsp->session_id, QDF_MAC_ADDR_REF(rsp->peermac.bytes)); psoc = rsp->psoc; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, WLAN_TDLS_SB_ID); @@ -1472,33 +1482,25 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) conn_rec = soc_obj->tdls_conn_info; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { if (conn_rec[sta_idx].session_id != rsp->session_id || - conn_rec[sta_idx].sta_id != rsp->sta_id) + qdf_mem_cmp(conn_rec[sta_idx].peer_mac.bytes, + rsp->peermac.bytes, QDF_MAC_ADDR_SIZE)) continue; macaddr = rsp->peermac.bytes; - tdls_debug("TDLS: del STA"); + tdls_debug("TDLS: del STA with sta_idx %d", sta_idx); curr_peer = tdls_find_peer(vdev_obj, macaddr); if (curr_peer) { - tdls_debug(QDF_MAC_ADDR_STR " status is %d", - QDF_MAC_ADDR_ARRAY(macaddr), + tdls_debug(QDF_MAC_ADDR_FMT " status is %d", + QDF_MAC_ADDR_REF(macaddr), curr_peer->link_status); id = wlan_vdev_get_id(vdev); - if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - soc_obj->tdls_dereg_peer( - soc_obj->tdls_peer_context, - id, curr_peer->sta_id); + if (TDLS_IS_LINK_CONNECTED(curr_peer)) tdls_decrement_peer_count(soc_obj); - } else if (TDLS_LINK_CONNECTING == - curr_peer->link_status) { - soc_obj->tdls_dereg_peer( - soc_obj->tdls_peer_context, - id, curr_peer->sta_id); - } } tdls_reset_peer(vdev_obj, macaddr); - conn_rec[sta_idx].sta_id = INVALID_TDLS_PEER_ID; + conn_rec[sta_idx].valid_entry = false; conn_rec[sta_idx].session_id = 0xff; conn_rec[sta_idx].index = INVALID_TDLS_PEER_INDEX; qdf_mem_zero(&conn_rec[sta_idx].peer_mac, @@ -1541,8 +1543,8 @@ tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, struct scheduler_msg msg = {0,}; QDF_STATUS status; - tdls_debug("update TDLS peer " QDF_MAC_ADDR_STR " vdev %d, state %d", - QDF_MAC_ADDR_ARRAY(peer_state->peer_macaddr), + tdls_debug("update TDLS peer " QDF_MAC_ADDR_FMT " vdev %d, state %d", + QDF_MAC_ADDR_REF(peer_state->peer_macaddr), peer_state->vdev_id, peer_state->peer_state); msg.type = soc_obj->tdls_update_peer_state; msg.reserved = 0; @@ -1591,18 +1593,18 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { - tdls_err(QDF_MAC_ADDR_STR + tdls_err(QDF_MAC_ADDR_FMT " not found, ignore NL80211_TDLS_ENABLE_LINK", - QDF_MAC_ADDR_ARRAY(mac)); + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_INVAL; goto error; } - tdls_debug("enable link for peer " QDF_MAC_ADDR_STR " link state %d", - QDF_MAC_ADDR_ARRAY(mac), peer->link_status); - if (!TDLS_STA_INDEX_CHECK(peer->sta_id)) { - tdls_err("invalid sta idx %u for " QDF_MAC_ADDR_STR, - peer->sta_id, QDF_MAC_ADDR_ARRAY(mac)); + tdls_debug("enable link for peer " QDF_MAC_ADDR_FMT " link state %d", + QDF_MAC_ADDR_REF(mac), peer->link_status); + if (!peer->valid_entry) { + tdls_err("invalid entry " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); status = QDF_STATUS_E_INVAL; goto error; } @@ -1614,8 +1616,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) id = wlan_vdev_get_id(vdev); status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, - id, mac, peer->sta_id, - peer->qos); + id, mac, peer->qos); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("TDLS register peer fail, status %d", status); goto error; @@ -1641,11 +1642,12 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) feature = soc_obj->tdls_configs.tdls_feature_flags; if (soc_obj->tdls_dp_vdev_update) - soc_obj->tdls_dp_vdev_update(&soc_obj->soc, - peer->sta_id, - soc_obj->tdls_update_dp_vdev_flags, - ((peer->link_status == - TDLS_LINK_CONNECTED) ? true : false)); + soc_obj->tdls_dp_vdev_update( + &soc_obj->soc, + wlan_vdev_get_id(vdev), + soc_obj->tdls_update_dp_vdev_flags, + ((peer->link_status == TDLS_LINK_CONNECTED) ? + true : false)); tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", TDLS_IS_BUFFER_STA_ENABLED(feature), @@ -1679,6 +1681,7 @@ static QDF_STATUS tdls_config_force_peer( const uint8_t *macaddr; uint32_t feature; QDF_STATUS status; + uint32_t chan_freq; struct tdls_peer_update_state *peer_update_param; macaddr = req->peer_addr; @@ -1694,12 +1697,23 @@ static QDF_STATUS tdls_config_force_peer( } feature = soc_obj->tdls_configs.tdls_feature_flags; - if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + if (!(TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) || !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); return QDF_STATUS_E_NOSUPPORT; } + /* + * In case of liberal external mode, supplicant will provide peer mac + * address but driver has to behave similar to implict mode ie + * establish tdls link with any peer that supports tdls and meets stats + */ + if (TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) { + tdls_debug("liberal mode set"); + return QDF_STATUS_SUCCESS; + } + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); if (!peer_update_param) { tdls_err("memory allocation failed"); @@ -1708,8 +1722,8 @@ static QDF_STATUS tdls_config_force_peer( peer = tdls_get_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer " QDF_MAC_ADDR_STR " does not exist", - QDF_MAC_ADDR_ARRAY(macaddr)); + tdls_err("peer " QDF_MAC_ADDR_FMT " does not exist", + QDF_MAC_ADDR_REF(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; } @@ -1734,9 +1748,10 @@ static QDF_STATUS tdls_config_force_peer( } soc_obj->tdls_external_peer_count++; + chan_freq = wlan_reg_legacy_chan_to_freq(pdev, req->chan); /* Validate if off channel is DFS channel */ - if (wlan_reg_is_dfs_ch(pdev, req->chan)) { + if (wlan_reg_is_dfs_for_freq(pdev, chan_freq)) { tdls_err("Resetting TDLS off-channel from %d to %d", req->chan, WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); req->chan = WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF; @@ -1770,8 +1785,8 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) struct wlan_objmgr_vdev *vdev; QDF_STATUS status; - tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(req->peer_addr)); + tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(req->peer_addr)); /* reference cnt is acquired in ucfg_tdls_oper */ vdev = req->vdev; @@ -1816,8 +1831,8 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) struct tdls_osif_indication ind; macaddr = req->peer_addr; - tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(macaddr)); + tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(macaddr)); vdev = req->vdev; if (!vdev) { @@ -1836,7 +1851,8 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) } feature = soc_obj->tdls_configs.tdls_feature_flags; - if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + if (!(TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) || !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); status = QDF_STATUS_E_NOSUPPORT; @@ -1845,8 +1861,8 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) peer = tdls_find_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer matching " QDF_MAC_ADDR_STR " not found", - QDF_MAC_ADDR_ARRAY(macaddr)); + tdls_err("peer matching " QDF_MAC_ADDR_FMT " not found", + QDF_MAC_ADDR_REF(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; } @@ -1855,8 +1871,9 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) TDLS_LINK_UNSPECIFIED); if (soc_obj->tdls_dp_vdev_update) - soc_obj->tdls_dp_vdev_update(&soc_obj->soc, - peer->sta_id, + soc_obj->tdls_dp_vdev_update( + &soc_obj->soc, + wlan_vdev_get_id(vdev), soc_obj->tdls_update_dp_vdev_flags, false); @@ -1936,9 +1953,9 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); type = evt->message_type; - tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_FMT "reason %d", tdls_evt_to_str(type), - QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), + QDF_MAC_ADDR_REF(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", @@ -1993,9 +2010,9 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); - tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_FMT "reason %d", tdls_evt_to_str(type), - QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); + QDF_MAC_ADDR_REF(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", @@ -2011,9 +2028,9 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, reason = evt->peer_reason; if (TDLS_LINK_CONNECTED == curr_peer->link_status) { - tdls_err("%s reason: %d for" QDF_MAC_ADDR_STR, + tdls_err("%s reason: %d for" QDF_MAC_ADDR_FMT, tdls_evt_to_str(type), evt->peer_reason, - QDF_MAC_ADDR_ARRAY(evt->peermac.bytes)); + QDF_MAC_ADDR_REF(evt->peermac.bytes)); if (reason == TDLS_TEARDOWN_RSSI || reason == TDLS_DISCONNECTED_PEER_DELETE || reason == TDLS_TEARDOWN_PTR_TIMEOUT || @@ -2117,7 +2134,7 @@ static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) conn_rec = soc_obj->tdls_conn_info; for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { - if (conn_rec[staidx].sta_id == INVALID_TDLS_PEER_ID) + if (!conn_rec[staidx].valid_entry) continue; curr_peer = tdls_find_all_peer(soc_obj, @@ -2129,8 +2146,9 @@ static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) if (curr_peer->spatial_streams == HW_MODE_SS_1x1) continue; - tdls_debug("Indicate TDLS teardown (staId %d)", - curr_peer->sta_id); + tdls_debug("Indicate TDLS teardown peer bssid " + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF( + curr_peer->peer_mac.bytes)); tdls_indicate_teardown(curr_peer->vdev_priv, curr_peer, TDLS_TEARDOWN_PEER_UNSPEC_REASON); @@ -2203,9 +2221,11 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) vdev_id = wlan_vdev_get_id(vdev); opmode = wlan_vdev_mlme_get_opmode(vdev); - channel = policy_mgr_get_channel(soc_obj->soc, + channel = wlan_freq_to_chan( + policy_mgr_get_channel( + soc_obj->soc, policy_mgr_convert_device_mode_to_qdf_type(opmode), - &vdev_id); + &vdev_id)); /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ if (WLAN_REG_IS_24GHZ_CH(channel)) diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_ct.c b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_ct.c index b47d4c3698bb30769d6a639e974c907263ff4fbc..291f76e46c3cf09b1fbba606f6b29c6b429c01f8 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_ct.c +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_ct.c @@ -85,13 +85,17 @@ void tdls_discovery_timeout_peer_cb(void *user_data) struct tdls_peer *peer; QDF_STATUS status; struct tdls_vdev_priv_obj *tdls_vdev; + struct wlan_objmgr_vdev *vdev; if (!user_data) { tdls_err("discovery time out data is null"); return; } - tdls_vdev = (struct tdls_vdev_priv_obj *) user_data; + vdev = tdls_get_vdev(user_data, WLAN_TDLS_NB_ID); + if (!vdev) + return; + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { head = &tdls_vdev->peer_list[i]; @@ -104,14 +108,15 @@ void tdls_discovery_timeout_peer_cb(void *user_data) &p_node); continue; } - tdls_debug(QDF_MAC_ADDR_STR " to idle state", - QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_debug(QDF_MAC_ADDR_FMT " to idle state", + QDF_MAC_ADDR_REF(peer->peer_mac.bytes)); tdls_set_peer_link_status(peer, TDLS_LINK_IDLE, TDLS_LINK_NOT_SUPPORTED); } } tdls_vdev->discovery_sent_cnt = 0; + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); /* add tdls power save prohibited */ @@ -381,8 +386,8 @@ void tdls_implicit_send_discovery_request( /* This function is called in mutex_lock */ temp_peer = tdls_is_progress(tdls_vdev_obj, NULL, 0); if (temp_peer) { - tdls_notice(QDF_MAC_ADDR_STR " ongoing. pre_setup ignored", - QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + tdls_notice(QDF_MAC_ADDR_FMT " ongoing. pre_setup ignored", + QDF_MAC_ADDR_REF(temp_peer->peer_mac.bytes)); goto done; } @@ -448,9 +453,9 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, if (0 == tdls_vdev->discovery_sent_cnt) qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); - tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_STR + tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_FMT " link_status %d", tdls_vdev->discovery_sent_cnt, - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->link_status); tdls_cfg = &tdls_vdev->threshold_config; @@ -464,9 +469,9 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERED, TDLS_LINK_SUCCESS); - tdls_debug("Rssi Threshold met: " QDF_MAC_ADDR_STR + tdls_debug("Rssi Threshold met: " QDF_MAC_ADDR_FMT " rssi = %d threshold= %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->rssi, tdls_cfg->rssi_trigger_threshold); @@ -479,9 +484,9 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, TDLS_EVENT_SETUP_REQ, &indication); } else { - tdls_debug("Rssi Threshold not met: " QDF_MAC_ADDR_STR + tdls_debug("Rssi Threshold not met: " QDF_MAC_ADDR_FMT " rssi = %d threshold = %d ", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->rssi, tdls_cfg->rssi_trigger_threshold); @@ -522,8 +527,12 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, return; } - if (TDLS_LINK_CONNECTED != curr_peer->link_status) + if (curr_peer->link_status != TDLS_LINK_CONNECTED) { + tdls_err("link state %d peer:" QDF_MAC_ADDR_FMT, + curr_peer->link_status, + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); return; + } tdls_set_peer_link_status(curr_peer, TDLS_LINK_TEARING, @@ -531,8 +540,9 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, tdls_notice("Teardown reason %d", reason); if (tdls_soc->tdls_dp_vdev_update) - tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc, - curr_peer->sta_id, + tdls_soc->tdls_dp_vdev_update( + &tdls_soc->soc, + wlan_vdev_get_id(tdls_vdev->vdev), tdls_soc->tdls_update_dp_vdev_flags, false); @@ -549,26 +559,31 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, /** * tdls_get_conn_info() - get the tdls connection information. * @tdls_soc: tdls soc object - * @idx: sta id + * @peer_mac: peer MAC address * * Function to check tdls sta index * * Return: tdls connection information */ static struct tdls_conn_info * -tdls_get_conn_info(struct tdls_soc_priv_obj *tdls_soc, uint8_t idx) +tdls_get_conn_info(struct tdls_soc_priv_obj *tdls_soc, + struct qdf_mac_addr *peer_mac) { uint8_t sta_idx; /* check if there is available index for this new TDLS STA */ for (sta_idx = 0; sta_idx < WLAN_TDLS_STA_MAX_NUM; sta_idx++) { - if (idx == tdls_soc->tdls_conn_info[sta_idx].sta_id) { - tdls_debug("tdls peer with sta_idx %u exists", idx); + if (!qdf_mem_cmp( + tdls_soc->tdls_conn_info[sta_idx].peer_mac.bytes, + peer_mac->bytes, QDF_MAC_ADDR_SIZE)) { + tdls_debug("tdls peer exists idx %d " QDF_MAC_ADDR_FMT, + sta_idx, + QDF_MAC_ADDR_REF(peer_mac->bytes)); tdls_soc->tdls_conn_info[sta_idx].index = sta_idx; return &tdls_soc->tdls_conn_info[sta_idx]; } } - tdls_err("tdls peer with staIdx %u not exists", idx); + tdls_err("tdls peer does not exists"); return NULL; } @@ -584,8 +599,8 @@ tdls_ct_process_idle_handler(struct wlan_objmgr_vdev *vdev, &tdls_soc_obj)) return; - if (INVALID_TDLS_PEER_ID == tdls_info->sta_id) { - tdls_err("peer (staidx %u) doesn't exists", tdls_info->sta_id); + if (!tdls_info->valid_entry) { + tdls_err("peer doesn't exists"); return; } @@ -597,9 +612,9 @@ tdls_ct_process_idle_handler(struct wlan_objmgr_vdev *vdev, return; } - tdls_debug(QDF_MAC_ADDR_STR + tdls_debug(QDF_MAC_ADDR_FMT " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->tx_pkt, curr_peer->rx_pkt, tdls_vdev_obj->threshold_config.idle_packet_n); @@ -612,13 +627,13 @@ tdls_ct_process_idle_handler(struct wlan_objmgr_vdev *vdev, (curr_peer->rx_pkt >= tdls_vdev_obj->threshold_config.idle_packet_n)) { /* this tdls link got back to normal, so keep it */ - tdls_debug("tdls link to " QDF_MAC_ADDR_STR + tdls_debug("tdls link to " QDF_MAC_ADDR_FMT " back to normal, will stay", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); } else { /* this tdls link needs to get torn down */ - tdls_notice("trigger tdls link to "QDF_MAC_ADDR_STR" down", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_notice("trigger tdls link to "QDF_MAC_ADDR_FMT" down", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); tdls_indicate_teardown(tdls_vdev_obj, curr_peer, TDLS_TEARDOWN_PEER_UNSPEC_REASON); @@ -639,8 +654,11 @@ void tdls_ct_idle_handler(void *user_data) return; idx = tdls_info->index; - if (idx == INVALID_TDLS_PEER_INDEX || idx >= WLAN_TDLS_STA_MAX_NUM) + if (idx == INVALID_TDLS_PEER_INDEX || idx >= WLAN_TDLS_STA_MAX_NUM) { + tdls_debug("invalid peer index %d" QDF_MAC_ADDR_FMT, idx, + QDF_MAC_ADDR_REF(tdls_info->peer_mac.bytes)); return; + } tdls_soc_obj = qdf_container_of(tdls_info, struct tdls_soc_priv_obj, tdls_conn_info[idx]); @@ -715,9 +733,9 @@ static void tdls_ct_process_connected_link( (curr_peer->rx_pkt < tdls_vdev->threshold_config.idle_packet_n))) { if (!curr_peer->is_peer_idle_timer_initialised) { - uint8_t sta_id = (uint8_t)curr_peer->sta_id; struct tdls_conn_info *tdls_info; - tdls_info = tdls_get_conn_info(tdls_soc, sta_id); + tdls_info = tdls_get_conn_info(tdls_soc, + &curr_peer->peer_mac); qdf_mc_timer_init(&curr_peer->peer_idle_timer, QDF_TIMER_TYPE_SW, tdls_ct_idle_handler, @@ -727,16 +745,16 @@ static void tdls_ct_process_connected_link( if (QDF_TIMER_STATE_RUNNING != curr_peer->peer_idle_timer.state) { tdls_warn("Tx/Rx Idle timer start: " - QDF_MAC_ADDR_STR "!", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + QDF_MAC_ADDR_FMT "!", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); tdls_timer_restart(tdls_vdev->vdev, &curr_peer->peer_idle_timer, tdls_vdev->threshold_config.idle_timeout_t); } } else if (QDF_TIMER_STATE_RUNNING == curr_peer->peer_idle_timer.state) { - tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDR_STR "!", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDR_FMT "!", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); qdf_mc_timer_stop(&curr_peer->peer_idle_timer); } } @@ -756,8 +774,8 @@ static void tdls_ct_process_cap_supported(struct tdls_peer *curr_peer, struct tdls_soc_priv_obj *tdls_soc_obj) { if (curr_peer->rx_pkt || curr_peer->tx_pkt) - tdls_debug(QDF_MAC_ADDR_STR "link_status %d tdls_support %d tx %d rx %d rssi %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + tdls_debug(QDF_MAC_ADDR_FMT "link_status %d tdls_support %d tx %d rx %d rssi %d", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->link_status, curr_peer->tdls_support, curr_peer->tx_pkt, curr_peer->rx_pkt, curr_peer->rssi); @@ -801,8 +819,8 @@ static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer, return; if (curr_peer->rx_pkt || curr_peer->tx_pkt) - tdls_debug(QDF_MAC_ADDR_STR "link_status %d tdls_support %d tx %d rx %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + tdls_debug(QDF_MAC_ADDR_FMT "link_status %d tdls_support %d tx %d rx %d", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), curr_peer->link_status, curr_peer->tdls_support, curr_peer->tx_pkt, curr_peer->rx_pkt); @@ -821,11 +839,14 @@ static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer, tdls_vdev->curr_candidate = curr_peer; tdls_implicit_send_discovery_request(tdls_vdev); } else { - curr_peer->tdls_support = TDLS_CAP_NOT_SUPPORTED; - tdls_set_peer_link_status( - curr_peer, - TDLS_LINK_IDLE, - TDLS_LINK_NOT_SUPPORTED); + if (curr_peer->link_status != TDLS_LINK_CONNECTING) { + curr_peer->tdls_support = + TDLS_CAP_NOT_SUPPORTED; + tdls_set_peer_link_status( + curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_NOT_SUPPORTED); + } } } } @@ -912,10 +933,8 @@ void tdls_ct_handler(void *user_data) if (!user_data) return; - vdev = (struct wlan_objmgr_vdev *)user_data; - - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, - WLAN_TDLS_NB_ID)) + vdev = tdls_get_vdev(user_data, WLAN_TDLS_NB_ID); + if (!vdev) return; tdls_ct_process_handler(vdev); @@ -1102,8 +1121,8 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, qdf_mem_copy(&chan_switch_params.peer_mac_addr, &conn_peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); - tdls_notice("Peer " QDF_MAC_ADDR_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", - QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), + tdls_notice("Peer " QDF_MAC_ADDR_FMT " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", + QDF_MAC_ADDR_REF(chan_switch_params.peer_mac_addr), chan_switch_params.vdev_id, chan_switch_params.tdls_off_ch, chan_switch_params.tdls_off_ch_bw_offset, @@ -1264,8 +1283,7 @@ void tdls_disable_offchan_and_teardown_links( for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; staidx++) { - if (tdls_soc->tdls_conn_info[staidx].sta_id - == INVALID_TDLS_PEER_ID) + if (!tdls_soc->tdls_conn_info[staidx].valid_entry) continue; curr_peer = tdls_find_all_peer(tdls_soc, @@ -1273,8 +1291,8 @@ void tdls_disable_offchan_and_teardown_links( if (!curr_peer) continue; - tdls_notice("indicate TDLS teardown (staId %d)", - curr_peer->sta_id); + tdls_notice("indicate TDLS teardown "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); /* Indicate teardown to supplicant */ tdls_indicate_teardown(tdls_vdev, @@ -1287,13 +1305,8 @@ void tdls_disable_offchan_and_teardown_links( */ tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); - if (tdls_soc->tdls_dereg_peer) - tdls_soc->tdls_dereg_peer( - tdls_soc->tdls_peer_context, - wlan_vdev_get_id(vdev), - curr_peer->sta_id); tdls_decrement_peer_count(tdls_soc); - tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; + tdls_soc->tdls_conn_info[staidx].valid_entry = false; tdls_soc->tdls_conn_info[staidx].session_id = 255; tdls_soc->tdls_conn_info[staidx].index = INVALID_TDLS_PEER_INDEX; diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c index 2219f7c6cbe65b59d619db8f24f855a76b1f108f..0a8e15aeea2341a17cf35ce28d4c67611a464364 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.c @@ -217,17 +217,17 @@ static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) WLAN_TDLS_PEER_SUB_LIST_SIZE); } qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, - tdls_ct_handler, vdev_obj->vdev); + tdls_ct_handler, soc_obj->soc); qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, - tdls_discovery_timeout_peer_cb, vdev_obj); + tdls_discovery_timeout_peer_cb, soc_obj->soc); return QDF_STATUS_SUCCESS; } static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj) { - qdf_mc_timer_stop(&vdev_obj->peer_update_timer); - qdf_mc_timer_stop(&vdev_obj->peer_discovery_timer); + qdf_mc_timer_stop_sync(&vdev_obj->peer_update_timer); + qdf_mc_timer_stop_sync(&vdev_obj->peer_discovery_timer); qdf_mc_timer_destroy(&vdev_obj->peer_update_timer); qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer); @@ -417,9 +417,8 @@ static int __tdls_get_all_peers_from_list( if (buf_len < 32 + 1) break; len = qdf_scnprintf(buf, buf_len, - QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), - curr_peer->sta_id, + QDF_MAC_ADDR_FMT "%4s%3s%5d\n", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), (curr_peer->tdls_support == TDLS_CAP_SUPPORTED) ? "Y" : "N", TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : @@ -492,8 +491,7 @@ static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) reset_session_id = tdls_vdev->session_id; for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; staidx++) { - if (tdls_soc->tdls_conn_info[staidx].sta_id - == INVALID_TDLS_PEER_ID) + if (!tdls_soc->tdls_conn_info[staidx].valid_entry) continue; if (tdls_soc->tdls_conn_info[staidx].session_id != reset_session_id) @@ -506,8 +504,8 @@ static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) if (!curr_peer) continue; - tdls_notice("indicate TDLS teardown (staId %d)", - curr_peer->sta_id); + tdls_notice("indicate TDLS teardown "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); /* Indicate teardown to supplicant */ tdls_indicate_teardown(tdls_vdev, @@ -516,13 +514,8 @@ static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); - if (tdls_soc->tdls_dereg_peer) - tdls_soc->tdls_dereg_peer( - tdls_soc->tdls_peer_context, - wlan_vdev_get_id(vdev), - curr_peer->sta_id); tdls_decrement_peer_count(tdls_soc); - tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; + tdls_soc->tdls_conn_info[staidx].valid_entry = false; tdls_soc->tdls_conn_info[staidx].session_id = 255; tdls_soc->tdls_conn_info[staidx].index = INVALID_TDLS_PEER_INDEX; @@ -699,7 +692,9 @@ void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, qdf_mc_timer_t *timer, uint32_t expiration_time) { - qdf_mc_timer_start(timer, expiration_time); + if (QDF_TIMER_STATE_RUNNING != + qdf_mc_timer_get_current_state(timer)) + qdf_mc_timer_start(timer, expiration_time); } /** @@ -958,7 +953,7 @@ tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc) tdls_debug("Enter"); if (!psoc) return QDF_STATUS_E_NULL_VALUE; - if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) && + if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) && !policy_mgr_is_hw_dbs_required_for_band( psoc, HW_MODE_MAC_BAND_2G) && policy_mgr_is_current_hwmode_dbs(psoc)) { diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.h b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.h index d9da54200b011c3e885011330191e57cb188c3d5..f9df6d91fc9a43d0b2e1467c70a99cdddd6bbc0a 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.h +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_main.h @@ -94,13 +94,13 @@ /** * struct tdls_conn_info - TDLS connection record * @session_id: session id - * @sta_id: sta id + * @valid_entry: valid entry(set to true upon peer create resp from firmware) * @peer_mac: peer address * @index: index to store array offset. */ struct tdls_conn_info { uint8_t session_id; - uint8_t sta_id; + bool valid_entry; uint8_t index; struct qdf_mac_addr peer_mac; }; @@ -165,6 +165,7 @@ struct tdls_set_state_info { * @tdls_external_peer_count: external tdls peer count * @tdls_nss_switch_in_progress: tdls antenna switch in progress * @tdls_nss_teardown_complete: tdls tear down complete + * @tdls_disable_in_progress: tdls is disable in progress * @tdls_nss_transition_mode: tdls nss transition mode * @tdls_teardown_peers_cnt: tdls tear down peer count * @set_state_info: set tdls state info @@ -172,7 +173,6 @@ struct tdls_set_state_info { * @tdls_evt_cb_data: tdls event user data * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath - * @tdls_dereg_peer: deregister tdls peer from datapath * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value @@ -183,6 +183,11 @@ struct tdls_set_state_info { * @tdls_update_dp_vdev_flags store CDP_UPDATE_TDLS_FLAGS * @tdls_idle_peer_data: provide information about idle peer * @tdls_ct_spinlock: connection tracker spin lock + * @is_prevent_suspend: prevent suspend or not + * @is_drv_supported: platform supports drv or not, enable/disable tdls wow + * based on this flag. + * @wake_lock: wake lock + * @runtime_lock: runtime lock * @tdls_osif_init_cb: Callback to initialize the tdls private * @tdls_osif_deinit_cb: Callback to deinitialize the tdls private */ @@ -215,7 +220,6 @@ struct tdls_soc_priv_obj { void *tdls_evt_cb_data; void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; - tdls_deregister_peer_callback tdls_dereg_peer; tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; @@ -226,6 +230,12 @@ struct tdls_soc_priv_obj { uint16_t tdls_del_all_peers; uint32_t tdls_update_dp_vdev_flags; qdf_spinlock_t tdls_ct_spinlock; +#ifdef TDLS_WOW_ENABLED + bool is_prevent_suspend; + bool is_drv_supported; + qdf_wake_lock_t wake_lock; + qdf_runtime_lock_t runtime_lock; +#endif tdls_vdev_init_cb tdls_osif_init_cb; tdls_vdev_deinit_cb tdls_osif_deinit_cb; }; @@ -273,7 +283,8 @@ struct tdls_peer_mlme_info { * @node: node * @vdev_priv: tdls vdev priv obj * @peer_mac: peer mac address - * @sta_id: station identifier + * @valid_entry: entry valid or not (set to true when peer create resp is + * received from FW) * @rssi: rssi * @tdls_support: tdls support * @link_status: tdls link status @@ -304,7 +315,7 @@ struct tdls_peer { qdf_list_node_t node; struct tdls_vdev_priv_obj *vdev_priv; struct qdf_mac_addr peer_mac; - uint16_t sta_id; + bool valid_entry; int8_t rssi; enum tdls_peer_capab tdls_support; enum tdls_link_state link_status; diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_mgmt.c b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_mgmt.c index 2307d0df0dca32d690de7bd18fe6c70879b35f6c..266f176dc97e23be033b8769358b28abc681d0c3 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_mgmt.c +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -55,8 +55,8 @@ QDF_STATUS tdls_set_rssi(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } - tdls_debug("rssi %d, peer " QDF_MAC_ADDR_STR, - rssi, QDF_MAC_ADDR_ARRAY(mac)); + tdls_debug("rssi %d, peer " QDF_MAC_ADDR_FMT, + rssi, QDF_MAC_ADDR_REF(mac)); tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj( vdev, WLAN_UMAC_COMP_TDLS); @@ -104,17 +104,17 @@ static QDF_STATUS tdls_process_rx_mgmt( return QDF_STATUS_E_INVAL; } - tdls_debug("soc:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", - tdls_soc_obj->soc, rx_mgmt->frame_len, - rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, - rx_mgmt->rx_rssi, rx_mgmt->buf); + tdls_debug("soc:%pK, frame_len:%d, rx_freq:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", + tdls_soc_obj->soc, rx_mgmt->frame_len, + rx_mgmt->rx_freq, rx_mgmt->vdev_id, rx_mgmt->frm_type, + rx_mgmt->rx_rssi, rx_mgmt->buf); if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1] == TDLS_PUBLIC_ACTION_DISC_RESP) { mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET]; tdls_notice("[TDLS] TDLS Discovery Response," - QDF_MAC_ADDR_STR " RSSI[%d] <--- OTA", - QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi); + QDF_MAC_ADDR_FMT " RSSI[%d] <--- OTA", + QDF_MAC_ADDR_REF(mac), rx_mgmt->rx_rssi); tdls_recv_discovery_resp(tdls_vdev, mac); tdls_set_rssi(tdls_vdev->vdev, mac, rx_mgmt->rx_rssi); } diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.c b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.c index d388690fd64bed81059ba80e6b61265c47bfb347..d370322703231ada652f7752ea466477fd3f2894 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.c +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.c @@ -27,6 +27,7 @@ #include #include #include "wlan_reg_ucfg_api.h" +#include static uint8_t calculate_hash_key(const uint8_t *macaddr) { @@ -60,8 +61,8 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, status = qdf_list_peek_next(head, p_node, &p_node); } - tdls_debug("no tdls peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(macaddr)); + tdls_debug("no tdls peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(macaddr)); return NULL; } @@ -189,12 +190,12 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, soc_obj->tdls_configs.tdls_pre_off_chan_bw, ®_bw_offset); - peer->sta_id = INVALID_TDLS_PEER_ID; + peer->valid_entry = false; qdf_list_insert_back(head, &peer->node); - tdls_debug("add tdls peer: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(macaddr)); + tdls_debug("add tdls peer: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(macaddr)); return peer; } @@ -227,8 +228,8 @@ tdls_find_progress_peer_in_list(qdf_list_t *head, status = qdf_list_peek_next(head, p_node, &p_node); continue; } else if (TDLS_LINK_CONNECTING == peer->link_status) { - tdls_debug(QDF_MAC_ADDR_STR " TDLS_LINK_CONNECTING", - QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_debug(QDF_MAC_ADDR_FMT " TDLS_LINK_CONNECTING", + QDF_MAC_ADDR_REF(peer->peer_mac.bytes)); return peer; } status = qdf_list_peek_next(head, p_node, &p_node); @@ -358,9 +359,9 @@ tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj) peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && TDLS_LINK_CONNECTED == peer->link_status) { - tdls_debug(QDF_MAC_ADDR_STR + tdls_debug(QDF_MAC_ADDR_FMT " TDLS_LINK_CONNECTED", - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_REF( peer->peer_mac.bytes)); return peer; } @@ -401,9 +402,11 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, vdev_id = wlan_vdev_get_id(vdev_obj->vdev); opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); - *channel = policy_mgr_get_channel(soc_obj->soc, + *channel = wlan_freq_to_chan( + policy_mgr_get_channel( + soc_obj->soc, policy_mgr_convert_device_mode_to_qdf_type(opmode), - &vdev_id); + &vdev_id)); *opclass = 0; } else { *channel = peer->pref_off_chan_num; @@ -474,7 +477,8 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, enum channel_state ch_state; struct wlan_objmgr_pdev *pdev; uint8_t chan_id; - enum band_info cur_band = BAND_ALL; + uint32_t cur_band; + qdf_freq_t ch_freq; vdev_obj = peer->vdev_priv; soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); @@ -509,12 +513,15 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, return; } - if (BAND_2G == cur_band) { + if (BIT(REG_BAND_2G) == cur_band) { tdls_err("sending the offchannel value as 0 as only 2g is supported"); peer_param->peer_cap.pref_off_channum = 0; peer_param->peer_cap.opclass_for_prefoffchan = 0; } - if (wlan_reg_is_dfs_ch(pdev, peer_param->peer_cap.pref_off_channum)) { + + ch_freq = wlan_reg_legacy_chan_to_freq(pdev, + peer_param->peer_cap.pref_off_channum); + if (wlan_reg_is_dfs_for_freq(pdev, ch_freq)) { tdls_err("Resetting TDLS off-channel from %d to %d", peer_param->peer_cap.pref_off_channum, WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); @@ -546,6 +553,84 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer->supported_oper_classes[i]; } +#ifdef TDLS_WOW_ENABLED +/** + * tdls_prevent_suspend(): Prevent suspend for TDLS + * + * Acquire wake lock and prevent suspend for TDLS + * + * Return None + */ +static void tdls_prevent_suspend(struct tdls_soc_priv_obj *tdls_soc) +{ + if (tdls_soc->is_prevent_suspend) + return; + + qdf_wake_lock_acquire(&tdls_soc->wake_lock, + WIFI_POWER_EVENT_WAKELOCK_TDLS); + qdf_runtime_pm_prevent_suspend(&tdls_soc->runtime_lock); + tdls_soc->is_prevent_suspend = true; +} + +/** + * tdls_allow_suspend(): Allow suspend for TDLS + * + * Release wake lock and allow suspend for TDLS + * + * Return None + */ +static void tdls_allow_suspend(struct tdls_soc_priv_obj *tdls_soc) +{ + if (!tdls_soc->is_prevent_suspend) + return; + + qdf_wake_lock_release(&tdls_soc->wake_lock, + WIFI_POWER_EVENT_WAKELOCK_TDLS); + qdf_runtime_pm_allow_suspend(&tdls_soc->runtime_lock); + tdls_soc->is_prevent_suspend = false; +} + +/** + * tdls_update_pmo_status() - Update PMO status by TDLS status + * @tdls_vdev: TDLS vdev object + * @old_status: old link status + * @new_status: new link status + * + * Return: None. + */ +static void tdls_update_pmo_status(struct tdls_vdev_priv_obj *tdls_vdev, + enum tdls_link_state old_status, + enum tdls_link_state new_status) +{ + struct tdls_soc_priv_obj *tdls_soc; + + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); + if (!tdls_soc) { + tdls_err("NULL psoc object"); + return; + } + + if (tdls_soc->is_drv_supported) + return; + + if ((old_status < TDLS_LINK_CONNECTING) && + (new_status == TDLS_LINK_CONNECTING)) + tdls_prevent_suspend(tdls_soc); + + if ((old_status > TDLS_LINK_IDLE) && + (new_status == TDLS_LINK_IDLE) && + (!tdls_soc->connected_peer_count) && + (!tdls_is_progress(tdls_vdev, NULL, 0))) + tdls_allow_suspend(tdls_soc); +} +#else +static void tdls_update_pmo_status(struct tdls_vdev_priv_obj *tdls_vdev, + enum tdls_link_state old_status, + enum tdls_link_state new_status) +{ +} +#endif + /** * tdls_set_link_status() - set link statue for TDLS peer * @vdev_obj: TDLS vdev object @@ -566,6 +651,7 @@ void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev_obj, uint32_t channel = 0; struct tdls_peer *peer; struct tdls_soc_priv_obj *soc_obj; + enum tdls_link_state old_status; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { @@ -574,7 +660,9 @@ void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev_obj, return; } + old_status = peer->link_status; peer->link_status = link_status; + tdls_update_pmo_status(vdev_obj, old_status, link_status); if (link_status >= TDLS_LINK_DISCOVERED) peer->discovery_attempt = 0; @@ -606,8 +694,16 @@ void tdls_set_peer_link_status(struct tdls_peer *peer, uint32_t channel = 0; struct tdls_soc_priv_obj *soc_obj; struct tdls_vdev_priv_obj *vdev_obj; + enum tdls_link_state old_status; + tdls_debug("state %d reason %d peer:" QDF_MAC_ADDR_FMT, + link_status, link_reason, + QDF_MAC_ADDR_REF(peer->peer_mac.bytes)); + + vdev_obj = peer->vdev_priv; + old_status = peer->link_status; peer->link_status = link_status; + tdls_update_pmo_status(vdev_obj, old_status, link_status); if (link_status >= TDLS_LINK_DISCOVERED) peer->discovery_attempt = 0; @@ -615,7 +711,6 @@ void tdls_set_peer_link_status(struct tdls_peer *peer, if (peer->is_forced_peer && peer->state_change_notification) { peer->reason = link_reason; - vdev_obj = peer->vdev_priv; soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); if (!soc_obj) { tdls_err("NULL psoc object"); @@ -685,8 +780,8 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, curr_peer->qos = is_qos_wmm_sta; } -QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t sta_id) +QDF_STATUS tdls_set_valid(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) { struct tdls_peer *peer; @@ -696,7 +791,7 @@ QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, return QDF_STATUS_E_FAILURE; } - peer->sta_id = sta_id; + peer->valid_entry = true; return QDF_STATUS_SUCCESS; } @@ -772,9 +867,17 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, ®_bw_offset); } + if (curr_peer->is_peer_idle_timer_initialised) { + tdls_debug(QDF_MAC_ADDR_FMT ": destroy idle timer ", + QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); + qdf_mc_timer_stop(&curr_peer->peer_idle_timer); + qdf_mc_timer_destroy(&curr_peer->peer_idle_timer); + curr_peer->is_peer_idle_timer_initialised = false; + } + tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, TDLS_LINK_UNSPECIFIED); - curr_peer->sta_id = INVALID_TDLS_PEER_ID; + curr_peer->valid_entry = false; return QDF_STATUS_SUCCESS; } @@ -799,9 +902,9 @@ void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj) while (QDF_IS_STATUS_SUCCESS(status)) { peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && peer->is_peer_idle_timer_initialised) { - tdls_debug(QDF_MAC_ADDR_STR + tdls_debug(QDF_MAC_ADDR_FMT ": destroy idle timer ", - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_REF( peer->peer_mac.bytes)); qdf_mc_timer_stop(&peer->peer_idle_timer); qdf_mc_timer_destroy(&peer->peer_idle_timer); diff --git a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.h b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.h index 41ffa8096f54598ebd11de42e09853afe48976f7..aa6f339eaba5c92538a1181c32bc5c19eb35baab 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.h +++ b/drivers/staging/qcacld-3.0/components/tdls/core/src/wlan_tdls_peer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -163,15 +163,14 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, struct tdls_update_peer_params *req_info); /** - * tdls_set_sta_id() - set station ID on a TDLS peer + * tdls_set_valid() - set station ID on a TDLS peer * @vdev_obj: TDLS vdev object * @macaddr: MAC address of the TDLS peer - * @sta_id: station ID * * Return: QDF_STATUS_SUCCESS if success; other values if failed */ -QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t sta_id); +QDF_STATUS tdls_set_valid(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr); /** * tdls_set_force_peer() - set/clear is_forced_peer flag on peer diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg.h b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg.h index da57d3551fdb4535465f54ad2a9716d8ecbfe467..5b9c728993d80a2cc0306c90b8ae28be561e493b 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg.h +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -150,7 +150,7 @@ * gEnableTDLSSupport - Enable support for TDLS. * @Min: 0 * @Max: 1 - * @Default: 0 + * @Default: 1 * * This ini is used to enable/disable TDLS support. * @@ -164,7 +164,7 @@ */ #define CFG_TDLS_SUPPORT_ENABLE CFG_INI_BOOL( \ "gEnableTDLSSupport", \ - 0, \ + 1, \ "enable/disable TDLS support") /* @@ -172,7 +172,7 @@ * gEnableTDLSImplicitTrigger - Enable Implicit TDLS. * @Min: 0 * @Max: 1 - * @Default: 0 + * @Default: 1 * * This ini is used to enable/disable implicit TDLS. * CLD driver initiates TDLS Discovery towards a peer whenever TDLS Setup @@ -189,7 +189,7 @@ */ #define CFG_TDLS_IMPLICIT_TRIGGER CFG_INI_BOOL( \ "gEnableTDLSImplicitTrigger", \ - 0, \ + 1, \ "enable/disable implicit TDLS") /* @@ -272,6 +272,30 @@ CFG_VALUE_OR_DEFAULT, \ "Attempts for sending TDLS discovery requests") +/* + * gTDLSMaxPeerCount - Max TDLS connected peer count + * @Min: 1 + * @Max: 8 + * @Default: 8 + * + * This ini is used to configure the max connected TDLS peer count. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: External + * + * + */ +#define CFG_TDLS_MAX_PEER_COUNT CFG_INI_UINT( \ + "gTDLSMaxPeerCount", \ + 1, \ + 8, \ + 8, \ + CFG_VALUE_OR_DEFAULT, \ + "Max TDLS peer count") + /* * * gTDLSIdleTimeout - Duration within which number of TX / RX frames meet the @@ -520,15 +544,24 @@ /* * - * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication - * window. - * @Min: 1 - * @Max: 5 - * @Default: 2 + * gTDLSExternalControl - Enable external TDLS control. + * @Min: 0 + * @Max: 2 + * @Default: 1 * - * This ini is used to configure buffering time in number of beacon intervals. + * This ini is used to enable/disable external TDLS control. + * TDLS external control works with TDLS implicit trigger. TDLS external + * control allows a user to add a MAC address of potential TDLS peers so + * that the CLD driver can initiate implicit TDLS setup to only those peers + * when criteria for TDLS setup (throughput and RSSI threshold) is met. + * There are two flavors of external control supported. If control default + * is set 1 it means strict external control where only for configured + * tdls peer mac address tdls link will be established. If control default + * is set 2 liberal tdls external control is needed which means + * tdls link will be established with configured peer mac address as well + * as any other peer which supports tdls. * - * Related: gEnableTDLSSupport. + * Related: gEnableTDLSSupport, gEnableTDLSImplicitTrigger. * * Supported Feature: TDLS * @@ -536,9 +569,12 @@ * * */ -#define CFG_TDLS_EXTERNAL_CONTROL CFG_INI_BOOL( \ +#define CFG_TDLS_EXTERNAL_CONTROL CFG_INI_UINT( \ "gTDLSExternalControl", \ + 0, \ + 2, \ 1, \ + CFG_VALUE_OR_DEFAULT, \ "Enable external TDLS control") /* @@ -569,7 +605,7 @@ * gEnableTDLSScan - Allow scan and maintain TDLS link. * @Min: 0 * @Max: 1 - * @Default: 0 + * @Default: 1 * * This ini is used to enable/disable TDLS scan. * 0: If peer is not buffer STA capable and device is not sleep STA @@ -592,7 +628,7 @@ */ #define CFG_TDLS_SCAN_ENABLE CFG_INI_BOOL( \ "gEnableTDLSScan", \ - 0, \ + 1, \ "Allow scan and maintain TDLS link") /* @@ -690,6 +726,7 @@ CFG(CFG_TDLS_TX_STATS_PERIOD) \ CFG(CFG_TDLS_TX_PACKET_THRESHOLD) \ CFG(CFG_TDLS_MAX_DISCOVERY_ATTEMPT) \ + CFG(CFG_TDLS_MAX_PEER_COUNT) \ CFG(CFG_TDLS_IDLE_TIMEOUT) \ CFG(CFG_TDLS_IDLE_PACKET_THRESHOLD) \ CFG(CFG_TDLS_RSSI_TRIGGER_THRESHOLD) \ diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h index f56d6d5fc70ab06fe4d36e48b79019e04372fe95..cd85ceb4d260b1a127daba72dd6114abe7d53d35 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h @@ -27,6 +27,7 @@ struct wlan_objmgr_psoc; +#ifdef FEATURE_WLAN_TDLS /** * cfg_tdls_get_support_enable() - get tdls support enable * @psoc: pointer to psoc object @@ -243,4 +244,176 @@ QDF_STATUS cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, bool val); +/** + * cfg_tdls_get_max_peer_count() - get tdls max peer count + * @psoc: pointer to psoc object + * + * This function gets tdls max peer count + */ +uint16_t cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS +cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + *val = 0; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + *val = 0; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + *val = 0; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_off_channel_enable_orig(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline void +cfg_tdls_restore_off_channel_enable(struct wlan_objmgr_psoc *psoc) +{ +} + +static inline void +cfg_tdls_store_off_channel_enable(struct wlan_objmgr_psoc *psoc) +{ +} + +static inline QDF_STATUS +cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_SUCCESS; +} + +static inline uint16_t +cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} +#endif /* FEATURE_WLAN_TDLS */ #endif /* _WLAN_TDLS_CFG_API_H_ */ diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 1c0de04a91821e0ba51e976080a59d7c1b0b52ca..b73866b415cb435386401713475ac3d830d4c19f 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -86,12 +86,8 @@ #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 -#define INVALID_TDLS_PEER_ID 0xFF #define INVALID_TDLS_PEER_INDEX 0xFF -#define TDLS_STA_INDEX_CHECK(sta_id) \ - (((sta_id) >= 0) && ((sta_id) < 0xFF)) - /** * enum tdls_add_oper - add peer type * @TDLS_OPER_NONE: none @@ -401,6 +397,11 @@ struct tx_frame { qdf_timer_t tx_timer; }; +enum tdls_configured_external_control { + TDLS_STRICT_EXTERNAL_CONTROL = 1, + TDLS_LIBERAL_EXTERNAL_CONTROL = 2, +}; + /** * enum tdls_feature_bit * @TDLS_FEATURE_OFF_CHANNEL: tdls off channel @@ -410,7 +411,8 @@ struct tx_frame { * @TDLS_FEATURE_SCAN: tdls scan * @TDLS_FEATURE_ENABLE: tdls enabled * @TDLS_FEAUTRE_IMPLICIT_TRIGGER: tdls implicit trigger - * @TDLS_FEATURE_EXTERNAL_CONTROL: tdls external control + * @TDLS_FEATURE_EXTERNAL_CONTROL: enforce strict tdls external control + * @TDLS_FEATURE_LIBERAL_EXTERNAL_CONTROL: liberal external tdls control */ enum tdls_feature_bit { TDLS_FEATURE_OFF_CHANNEL, @@ -420,7 +422,8 @@ enum tdls_feature_bit { TDLS_FEATURE_SCAN, TDLS_FEATURE_ENABLE, TDLS_FEAUTRE_IMPLICIT_TRIGGER, - TDLS_FEATURE_EXTERNAL_CONTROL + TDLS_FEATURE_EXTERNAL_CONTROL, + TDLS_FEATURE_LIBERAL_EXTERNAL_CONTROL, }; #define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ @@ -439,6 +442,8 @@ enum tdls_feature_bit { CHECK_BIT(flags, TDLS_FEAUTRE_IMPLICIT_TRIGGER) #define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ CHECK_BIT(flags, TDLS_FEATURE_EXTERNAL_CONTROL) +#define TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(flags) \ + CHECK_BIT(flags, TDLS_FEATURE_LIBERAL_EXTERNAL_CONTROL) /** * struct tdls_user_config - TDLS user configuration @@ -499,7 +504,7 @@ struct tdls_user_config { bool tdls_off_chan_enable; bool tdls_off_chan_enable_orig; bool tdls_wmm_mode_enable; - bool tdls_external_control; + uint8_t tdls_external_control; bool tdls_implicit_trigger_enable; bool tdls_scan_enable; bool tdls_sleep_sta_enable; @@ -549,7 +554,7 @@ struct tdls_tx_cnf { /** * struct tdls_rx_mgmt_frame - rx mgmt frame structure * @frame_len: frame length - * @rx_chan: rx channel + * @rx_freq: rx freq * @vdev_id: vdev id * @frm_type: frame type * @rx_rssi: rx rssi @@ -557,7 +562,7 @@ struct tdls_tx_cnf { */ struct tdls_rx_mgmt_frame { uint32_t frame_len; - uint32_t rx_chan; + uint32_t rx_freq; uint32_t vdev_id; uint32_t frm_type; uint32_t rx_rssi; @@ -603,18 +608,18 @@ typedef void (*tdls_evt_callback) (void *data, typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, uint32_t vdev_id, const uint8_t *mac, - uint16_t stat_id, uint8_t qos); /* This callback is used to deregister TDLS peer from the datapath */ -typedef QDF_STATUS (*tdls_deregister_peer_callback)(void *userdata, - uint32_t vdev_id, - uint8_t sta_id); +typedef QDF_STATUS +(*tdls_deregister_peer_callback)(void *userdata, + uint32_t vdev_id, + struct qdf_mac_addr *peer_mac); /* This callback is used to update datapath vdev flags */ typedef QDF_STATUS (*tdls_dp_vdev_update_flags_callback)(void *cbk_data, - uint8_t sta_id, + uint8_t vdev_id, uint32_t vdev_param, bool is_link_up); @@ -654,7 +659,6 @@ typedef void (*tdls_vdev_deinit_cb)(struct wlan_objmgr_vdev *vdev); * @tdls_evt_cb_data: tdls event data * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath - * @tdls_dereg_peer: deregister tdls peer from datapath * @tdls_dp_vdev_update: update vdev flags in datapath * @tdls_osif_init_cb: callback to initialize the tdls priv * @tdls_osif_deinit_cb: callback to deinitialize the tdls priv @@ -675,7 +679,6 @@ struct tdls_start_params { void *tdls_evt_cb_data; void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; - tdls_deregister_peer_callback tdls_dereg_peer; tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; tdls_vdev_init_cb tdls_osif_init_cb; tdls_vdev_deinit_cb tdls_osif_deinit_cb; @@ -884,9 +887,10 @@ struct tdls_ch_params { * @peer_chan: peer channel list * @peer_oper_classlen: peer operating class length * @peer_oper_class: peer operating class - * @pref_off_channum: peer offchannel number + * @pref_off_channum: preferred offchannel number * @pref_off_chan_bandwidth: peer offchannel bandwidth * @opclass_for_prefoffchan: operating class for offchannel + * @pref_offchan_freq: preferred offchannel frequency */ struct tdls_peer_params { uint8_t is_peer_responder; @@ -903,6 +907,7 @@ struct tdls_peer_params { uint8_t pref_off_channum; uint8_t pref_off_chan_bandwidth; uint8_t opclass_for_prefoffchan; + uint32_t pref_offchan_freq; }; /** @@ -928,6 +933,7 @@ struct tdls_peer_update_state { * @tdls_off_ch: Target Off Channel * @oper_class: Operating class for target channel * @is_responder: Responder or initiator + * @tdls_off_chan_freq: Target Off Channel frequency */ struct tdls_channel_switch_params { uint32_t vdev_id; @@ -937,6 +943,7 @@ struct tdls_channel_switch_params { uint8_t tdls_sw_mode; uint8_t oper_class; uint8_t is_responder; + uint32_t tdls_off_chan_freq; }; /** @@ -1187,24 +1194,24 @@ enum legacy_result_code { /** * struct tdls_send_mgmt_rsp - TDLS Response struct PE --> TDLS module - * @session_id: session id + * @vdev_id: vdev id * @status_code: status code as tSirResultCodes * @psoc: soc object */ struct tdls_send_mgmt_rsp { - uint8_t session_id; + uint8_t vdev_id; enum legacy_result_code status_code; struct wlan_objmgr_psoc *psoc; }; /** * struct tdls_mgmt_tx_completion_ind - TDLS TX completion PE --> TDLS module - * @session_id: session id + * @vdev_id: vdev_id * @tx_complete_status: tx complete status * @psoc: soc object */ struct tdls_mgmt_tx_completion_ind { - uint8_t session_id; /* Session ID */ + uint8_t vdev_id; uint32_t tx_complete_status; struct wlan_objmgr_psoc *psoc; }; @@ -1214,7 +1221,6 @@ struct tdls_mgmt_tx_completion_ind { * @status_code: status code as tSirResultCodes * @peermac: MAC address of the TDLS peer * @session_id: session id - * @sta_id: sta id * @sta_type: sta type * @tdls_oper: add peer type * @psoc: soc object @@ -1223,7 +1229,6 @@ struct tdls_add_sta_rsp { QDF_STATUS status_code; struct qdf_mac_addr peermac; uint8_t session_id; - uint16_t sta_id; uint16_t sta_type; enum tdls_add_oper tdls_oper; struct wlan_objmgr_psoc *psoc; @@ -1234,14 +1239,12 @@ struct tdls_add_sta_rsp { * @session_id: session id * @status_code: status code as tSirResultCodes * @peermac: MAC address of the TDLS peer - * @sta_id: sta id * @psoc: soc object */ struct tdls_del_sta_rsp { uint8_t session_id; QDF_STATUS status_code; struct qdf_mac_addr peermac; - uint16_t sta_id; struct wlan_objmgr_psoc *psoc; }; diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_cfg.c b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_cfg.c index fe5e50df432cc12366495a039ce0672d5af9b109..7d3a617eee595490d87871d07d1c7ce74661bf34 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_cfg.c +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_cfg.c @@ -369,3 +369,17 @@ cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +uint16_t +cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return 0; + } + + return soc_obj->max_num_tdls_sta; +} diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c index a2927b7b91aec2c06ab848ea1628fc5858551223..95d489afa4e66517423c214866b5a7a3b5e53641 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c @@ -184,9 +184,9 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info); return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR, + tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_FMT, info->vdev_id, info->message_type, info->peer_reason, - QDF_MAC_ADDR_ARRAY(info->peermac.bytes)); + QDF_MAC_ADDR_REF(info->peermac.bytes)); notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { tdls_err("mem allocate fail"); @@ -293,7 +293,7 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( pdata = (uint8_t *)qdf_nbuf_data(buf); rx_mgmt->frame_len = mgmt_rx_params->buf_len; - rx_mgmt->rx_chan = mgmt_rx_params->channel; + rx_mgmt->rx_freq = mgmt_rx_params->chan_freq; rx_mgmt->vdev_id = vdev_id; rx_mgmt->frm_type = frm_type; rx_mgmt->rx_rssi = mgmt_rx_params->rssi; diff --git a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index 3c1dfbd3b471ba19b6dffb0078928092ea7a595a..116f86fcc9632fddeb4a7bb0d1c5602260ff3034 100644 --- a/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/drivers/staging/qcacld-3.0/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -142,8 +142,12 @@ tdls_update_feature_flag(struct tdls_soc_priv_obj *tdls_soc_obj) 1 << TDLS_FEATURE_ENABLE : 0) | (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | - (tdls_soc_obj->tdls_configs.tdls_external_control ? - 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); + (tdls_soc_obj->tdls_configs.tdls_external_control & + TDLS_STRICT_EXTERNAL_CONTROL ? + 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0) | + (tdls_soc_obj->tdls_configs.tdls_external_control & + TDLS_LIBERAL_EXTERNAL_CONTROL ? + 1 << TDLS_FEATURE_LIBERAL_EXTERNAL_CONTROL : 0)); } /** @@ -218,15 +222,58 @@ static QDF_STATUS tdls_object_init_params( cfg_get(psoc, CFG_TDLS_IMPLICIT_TRIGGER); tdls_soc_obj->tdls_configs.tdls_external_control = cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL); + tdls_soc_obj->max_num_tdls_sta = + cfg_get(psoc, CFG_TDLS_MAX_PEER_COUNT); tdls_update_feature_flag(tdls_soc_obj); return QDF_STATUS_SUCCESS; } -static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) +#ifdef TDLS_WOW_ENABLED +/** + * tdls_wow_init(): Create/init wake lock for TDLS + * + * Create/init wake lock for TDLS if DVR isn't supported + * + * Return None + */ +static void tdls_wow_init(struct tdls_soc_priv_obj *soc_obj) { + soc_obj->is_prevent_suspend = false; + soc_obj->is_drv_supported = qdf_is_drv_supported(); + if (!soc_obj->is_drv_supported) { + qdf_wake_lock_create(&soc_obj->wake_lock, "wlan_tdls"); + qdf_runtime_lock_init(&soc_obj->runtime_lock); + } +} +/** + * tdls_wow_deinit(): Destroy/deinit wake lock for TDLS + * + * Destroy/deinit wake lock for TDLS if DVR isn't supported + * + * Return None + */ +static void tdls_wow_deinit(struct tdls_soc_priv_obj *soc_obj) +{ + if (!soc_obj->is_drv_supported) { + qdf_runtime_lock_deinit(&soc_obj->runtime_lock); + qdf_wake_lock_destroy(&soc_obj->wake_lock); + } +} +#else +static void tdls_wow_init(struct tdls_soc_priv_obj *soc_obj) +{ +} + +static void tdls_wow_deinit(struct tdls_soc_priv_obj *soc_obj) +{ +} +#endif + +static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) +{ tdls_object_init_params(soc_obj); soc_obj->connected_peer_count = 0; soc_obj->tdls_nss_switch_in_progress = false; @@ -238,13 +285,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->tdls_disable_in_progress = false; qdf_spinlock_create(&soc_obj->tdls_ct_spinlock); + tdls_wow_init(soc_obj); return QDF_STATUS_SUCCESS; } static QDF_STATUS tdls_global_deinit(struct tdls_soc_priv_obj *soc_obj) { + tdls_wow_deinit(soc_obj); qdf_spinlock_destroy(&soc_obj->tdls_ct_spinlock); + return QDF_STATUS_SUCCESS; } @@ -298,7 +348,6 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, /* Save callbacks to register/deregister TDLS sta with datapath */ soc_obj->tdls_reg_peer = req->tdls_reg_peer; - soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; soc_obj->tdls_peer_context = req->tdls_peer_context; /* Save legacy PE/WMA commands in TDLS soc object */ @@ -338,11 +387,9 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags)) soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM; - else - soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - soc_obj->tdls_conn_info[sta_idx].sta_id = INVALID_TDLS_PEER_ID; + soc_obj->tdls_conn_info[sta_idx].valid_entry = false; soc_obj->tdls_conn_info[sta_idx].index = INVALID_TDLS_PEER_INDEX; soc_obj->tdls_conn_info[sta_idx].session_id = 255; @@ -556,9 +603,9 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("%s for peer " QDF_MAC_ADDR_STR, + tdls_debug("%s for peer " QDF_MAC_ADDR_FMT, tdls_get_oper_str(cmd), - QDF_MAC_ADDR_ARRAY(macaddr)); + QDF_MAC_ADDR_REF(macaddr)); req = qdf_mem_malloc(sizeof(*req)); if (!req) { diff --git a/drivers/staging/qcacld-3.0/configs/default_defconfig b/drivers/staging/qcacld-3.0/configs/default_defconfig index 61cf9f4d23f1d52b9fc04d396875e1954b42ceab..aefbc655bee5a7508a0a6fc9dab7634575716f04 100644 --- a/drivers/staging/qcacld-3.0/configs/default_defconfig +++ b/drivers/staging/qcacld-3.0/configs/default_defconfig @@ -24,6 +24,44 @@ ifeq ($(CONFIG_CNSS_QCA6390), y) CONFIG_WDI3_IPA_OVER_GSI :=y CONFIG_DIRECT_BUF_RX_ENABLE := y CONFIG_WMI_DBR_SUPPORT := y + CONFIG_MORE_TX_DESC := y + CONFIG_FIX_TXDMA_ALIGNMENT := y +endif + +ifeq ($(CONFIG_CNSS_QCA6490), y) + CONFIG_DIRECT_BUF_RX_ENABLE := y + CONFIG_WMI_DBR_SUPPORT := y + CONFIG_WLAN_CFR_ENABLE := y + CONFIG_WLAN_ENH_CFR_ENABLE := y + ifeq ($(CONFIG_CNSS_EMULATION), y) + CONFIG_QCA_WIFI_NAPIER_EMULATION := y + endif + CONFIG_LITHIUM := y + CONFIG_WLAN_FEATURE_11AX := y + CONFIG_WLAN_FEATURE_DFS_OFFLOAD := y + ifeq ($(CONFIG_ARCH_SDM845), y) + CONFIG_IPA3 := n + endif + CONFIG_SCALE_INCLUDES := y + CONFIG_HASTINGS_BT_WAR := y + CONFIG_WDI3_IPA_OVER_GSI :=y + CONFIG_GENERIC_SHADOW_REGISTER_ACCESS_ENABLE :=y + CONFIG_DUMP_REO_QUEUE_INFO_IN_DDR :=y +endif + +ifeq ($(CONFIG_CNSS_QCA6750), y) + ifeq ($(CONFIG_CNSS_EMULATION), y) + CONFIG_QCA_WIFI_NAPIER_EMULATION := y + endif + CONFIG_LITHIUM := y + CONFIG_WLAN_FEATURE_11AX := y + CONFIG_WLAN_FEATURE_DFS_OFFLOAD := y + ifeq ($(CONFIG_ARCH_SDM845), y) + CONFIG_IPA3 := n + endif + CONFIG_SCALE_INCLUDES := y + CONFIG_HASTINGS_BT_WAR := y + CONFIG_WDI3_IPA_OVER_GSI :=y endif ifeq ($(CONFIG_CLD_HL_SDIO_CORE), y) @@ -37,24 +75,22 @@ ifeq ($(CONFIG_QCA_WIFI_SDIO), y) CONFIG_ROME_IF = sdio endif -ifeq ($(CONFIG_ICNSS), m) - CONFIG_ICNSS_MODULE := y -endif -ifeq ($(CONFIG_CNSS), m) - CONFIG_CNSS_MODULE := y -endif -ifeq ($(CONFIG_CNSS2), m) - CONFIG_CNSS2_MODULE := y +ifdef CONFIG_ICNSS + CONFIG_ROME_IF = snoc endif -ifeq ($(CONFIG_CNSS_GENL), m) - CONFIG_CNSS_GENL_MODULE := y + +ifdef CONFIG_ICNSS2 + CONFIG_ROME_IF = ipci endif -ifeq (y,$(findstring y,$(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE))) - CONFIG_ROME_IF = snoc +ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS2))) +ifndef CONFIG_ROME_IF + #use pci as default interface + CONFIG_ROME_IF = pci +endif endif -ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS_MODULE) $(CONFIG_CNSS2) $(CONFIG_CNSS2_MODULE))) +ifeq (m,$(findstring m,$(CONFIG_CNSS2))) ifndef CONFIG_ROME_IF #use pci as default interface CONFIG_ROME_IF = pci @@ -64,11 +100,10 @@ endif # Make WLAN as open-source driver by default WLAN_OPEN_SOURCE := y -ifeq (y,$(findstring y,$(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE))) +ifeq ($(CONFIG_ICNSS), y) CONFIG_HELIUMPLUS := y CONFIG_64BIT_PADDR := y CONFIG_FEATURE_TSO := y - CONFIG_FEATURE_TSO_DEBUG := y ifeq ($(CONFIG_INET_LRO), y) CONFIG_WLAN_LRO := y else @@ -78,7 +113,7 @@ endif ifneq ($(DEVELOPER_DISABLE_BUILD_TIMESTAMP), y) ifneq ($(WLAN_DISABLE_BUILD_TAG), y) -CONFIG_BUILD_TAG := y +CONFIG_BUILD_TAG := n endif endif @@ -104,17 +139,26 @@ ifeq ($(CONFIG_ARCH_MSM8917), y) endif endif -ifeq ($(CONFIG_ARCH_QCS405), y) +ifeq (y,$(findstring y,$(CONFIG_ARCH_QCS405) $(CONFIG_ARCH_QCS403))) + CONFIG_ARCH_QCS40X := y +endif + +ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_WLAN_SYNC_TSF_PLUS := y CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ := y CONFIG_RX_PERFORMANCE := y + CONFIG_TGT_NUM_MSDU_DESC := 900 + CONFIG_MULTI_IF_LOG := y + CONFIG_DFS_PRI_MULTIPLIER := y + CONFIG_DFS_OVERRIDE_RF_THRESHOLD := y endif CONFIG_WLAN_FEATURE_MBSSID := y -#Flag to enable Legacy Fast Roaming2(LFR2) -CONFIG_QCACLD_WLAN_LFR2 := y + #Flag to enable Legacy Fast Roaming3(LFR3) -ifneq ($(CONFIG_ARCH_SDX20), y) -CONFIG_QCACLD_WLAN_LFR3 := y +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) + CONFIG_QCACLD_WLAN_LFR3 := y +else + CONFIG_QCACLD_WLAN_LFR2 := y endif ifneq ($(CONFIG_MOBILE_ROUTER), y) @@ -127,8 +171,10 @@ CONFIG_WLAN_POWER_DEBUG := y CONFIG_FEATURE_BECN_STATS := y endif +#Disable the Export Symbol config +CONFIG_WLAN_DISABLE_EXPORT_SYMBOL := y + CONFIG_QCACLD_FEATURE_GREEN_AP := y -CONFIG_CRYPTO_COMPONENT := y #Flag to enable Android Packet Filtering CONFIG_QCACLD_FEATURE_APF := y @@ -142,7 +188,7 @@ CONFIG_QCACLD_FEATURE_FW_STATE := y CONFIG_QCACLD_FEATURE_COEX_CONFIG := n #Flag to enable get hw capability -ifeq ($(CONFIG_ARCH_QCS405), y) +ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_QCACLD_FEATURE_HW_CAPABILITY := y endif @@ -156,15 +202,17 @@ endif ifeq ($(CONFIG_ARCH_SM8150), y) CONFIG_QCACLD_FEATURE_METERING := y +CONFIG_DYNAMIC_RX_AGGREGATION := y endif -ifeq ($(CONFIG_ARCH_KONA), y) +ifeq ($(CONFIG_HELIUMPLUS), y) CONFIG_QCACLD_FEATURE_METERING := y -CONFIG_WDI3_STATS_UPDATE := y endif -ifeq ($(CONFIG_HELIUMPLUS), y) +ifeq ($(CONFIG_ARCH_KONA), y) CONFIG_QCACLD_FEATURE_METERING := y +CONFIG_WDI3_STATS_UPDATE := y +CONFIG_WLAN_SYNC_TSF_TIMER := y endif #Flag to enable Fast Transition (11r) feature @@ -182,8 +230,7 @@ CONFIG_SAE_SINGLE_PMK := y #Flag to enable FILS Feature (11ai) CONFIG_WLAN_FEATURE_FILS := y ifneq ($(CONFIG_QCA_CLD_WLAN),) - ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS_MODULE) $(CONFIG_CNSS2) \ - $(CONFIG_CNSS2_MODULE) $(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE))) + ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS2) $(CONFIG_ICNSS)$(CONFIG_ICNSS2))) #Flag to enable Protected Management Frames (11w) feature CONFIG_WLAN_FEATURE_11W := y #Flag to enable LTE CoEx feature @@ -194,6 +241,16 @@ ifneq ($(CONFIG_QCA_CLD_WLAN),) endif endif + ifeq (m,$(findstring m,$(CONFIG_CNSS2) $(CONFIG_ICNSS2))) + #Flag to enable Protected Management Frames (11w) feature + CONFIG_WLAN_FEATURE_11W := y + #Flag to enable LTE CoEx feature + CONFIG_QCOM_LTE_COEX := y + ifneq ($(CONFIG_MOBILE_ROUTER), y) + #Flag to enable LPSS feature + CONFIG_WLAN_FEATURE_LPSS := y + endif + endif endif #Flag to enable Protected Management Frames (11w) feature @@ -233,6 +290,9 @@ CONFIG_WLAN_FEATURE_DSRC := y endif ifneq ($(CONFIG_ROME_IF),usb) + #Flag to enable SAE + CONFIG_WLAN_FEATURE_SAE := y + ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable DISA CONFIG_WLAN_FEATURE_DISA := y @@ -240,9 +300,6 @@ ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable FIPS CONFIG_WLAN_FEATURE_FIPS := y - #Flag to enable SAE - CONFIG_WLAN_FEATURE_SAE := y - #Flag to enable Fast Path feature ifneq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_FASTPATH := y @@ -268,8 +325,12 @@ ifeq ($(CONFIG_ROME_IF), snoc) CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y endif -ifeq ($(CONFIG_ARCH_QCS405), y) +ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n +# Flag to improve TCP TX throughput for both +# CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY and CONFIG_WLAN_TX_FLOW_CONTROL_V2 +# disabled platform, avoid frame drop in driver +CONFIG_WLAN_PDEV_TX_FLOW_CONTROL := y endif # Flag to enable LFR Subnet Detection @@ -291,7 +352,7 @@ else CONFIG_LL_DP_SUPPORT := y endif -ifeq ($(CONFIG_HIF_PCI), y) +ifeq ($(CONFIG_ROME_IF),pci) ifneq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y) ifneq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y @@ -302,7 +363,7 @@ endif #Whether have QMI support CONFIG_QMI_SUPPORT := y -ifeq (y,$(findstring y,$(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE))) +ifeq ($(CONFIG_ICNSS), y) CONFIG_WIFI_3_0_ADRASTEA := y CONFIG_ADRASTEA_RRI_ON_DDR := y # Enable athdiag procfs debug support for adrastea @@ -314,9 +375,13 @@ CONFIG_ADRASTEA_SHADOW_REGISTERS := y endif endif +# Enable fw stats version 2 +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) +CONFIG_AR900B := y +endif + # NOTE: CONFIG_64BIT_PADDR requires CONFIG_HELIUMPLUS ifeq ($(CONFIG_HELIUMPLUS), y) -CONFIG_AR900B := y ifeq ($(CONFIG_64BIT_PADDR), y) CONFIG_HTT_PADDR64 := y @@ -331,6 +396,8 @@ endif endif #CONFIG_HELIUMPLUS ifeq ($(CONFIG_LITHIUM), y) +CONFIG_RX_DEFRAG_DO_NOT_REINJECT := y +CONFIG_IPA_SET_RESET_TX_DB_PA := y # # Enable Shadow V2 for all lithium platform # @@ -345,13 +412,27 @@ ifeq ($(CONFIG_CNSS_QCA6390), y) CONFIG_QCA_WIFI_QCA6390 := y endif +ifeq ($(CONFIG_CNSS_QCA6490), y) + CONFIG_QCA6490_HEADERS_DEF := y + CONFIG_QCA_WIFI_QCA6490 := y +endif + +ifeq ($(CONFIG_CNSS_QCA6750), y) + CONFIG_QCA6750_HEADERS_DEF := y + CONFIG_QCA_WIFI_QCA6750 := y +endif + ifeq ($(CONFIG_LITHIUM), y) # # Enable VERBOSE debug INI mechanism # CONFIG_VERBOSE_DEBUG := y +CONFIG_RX_DESC_SANITY_WAR := y ifeq ($(CONFIG_PCI_MSM), y) CONFIG_FEATURE_HAL_DELAYED_REG_WRITE := y +ifeq ($(CONFIG_CNSS_QCA6390), y) + CONFIG_SHADOW_WRITE_DELAY := y +endif endif endif @@ -361,17 +442,28 @@ CONFIG_DP_INTR_POLL_BASED := y CONFIG_TX_PER_PDEV_DESC_POOL := y CONFIG_DP_TRACE := y CONFIG_FEATURE_TSO := y -CONFIG_TSO_DEBUG_LOG_ENABLE := y +CONFIG_FEATURE_FORCE_WAKE := y CONFIG_DP_LFR := y CONFIG_DUP_RX_DESC_WAR := y CONFIG_HTT_PADDR64 := y CONFIG_RX_OL := y CONFIG_TX_TID_OVERRIDE := y +CONFIG_DP_TXRX_SOC_ATTACH := y CONFIG_WLAN_CLD_PM_QOS := y +CONFIG_DISABLE_DP_STATS := n +CONFIG_MAX_ALLOC_PAGE_SIZE := y CONFIG_REO_DESC_DEFER_FREE := y CONFIG_RXDMA_ERR_PKT_DROP := y CONFIG_DELIVERY_TO_STACK_STATUS_CHECK := y +CONFIG_DP_MEM_PRE_ALLOC := y + +ifeq ($(CONFIG_FEATURE_TSO), y) + CONFIG_FEATURE_TSO_STATS := y +endif +ifeq ($(CONFIG_DISABLE_DP_STATS), y) + CONFIG_FEATURE_TSO_STATS := n +endif endif # As per target team, build is done as follows: @@ -404,7 +496,19 @@ ifeq ($(CONFIG_DEBUG_FS), y) # configuration. CONFIG_WLAN_DEBUGFS := y + # Flag to enable streamfs. Depends on CONFIG_DEBUG_FS and + # CONFIG_RELAY in kernel configuration. +ifeq ($(CONFIG_RELAY), y) + CONFIG_WLAN_STREAMFS := y +endif +endif + +ifeq ($(CONFIG_WLAN_DEBUGFS), y) CONFIG_WLAN_MWS_INFO_DEBUGFS := y + CONFIG_WLAN_FEATURE_MIB_STATS := y +else + CONFIG_WLAN_MWS_INFO_DEBUGFS := n + CONFIG_WLAN_FEATURE_MIB_STATS := n endif # Feature flags which are not (currently) configurable via Kconfig @@ -431,9 +535,6 @@ CONFIG_WLAN_LOG_FATAL := y CONFIG_WLAN_LOG_ERROR := y CONFIG_WLAN_LOG_WARN := y CONFIG_WLAN_LOG_INFO := y -CONFIG_WLAN_LOG_DEBUG := y -CONFIG_WLAN_LOG_ENTER := y -CONFIG_WLAN_LOG_EXIT := y #Enable OL debug and wmi unified functions CONFIG_ATH_PERF_PWR_OFFLOAD := y @@ -446,6 +547,10 @@ ifeq ($(CONFIG_ROME_IF),pci) CONFIG_ATH_11AC_TXCOMPACT := y endif +ifeq ($(CONFIG_ROME_IF),ipci) + CONFIG_ATH_11AC_TXCOMPACT := y +endif + ifeq ($(CONFIG_ROME_IF),usb) CONFIG_ATH_11AC_TXCOMPACT := n endif @@ -455,6 +560,10 @@ ifeq ($(CONFIG_ROME_IF),pci) CONFIG_HIF_PCI := y endif +ifeq ($(CONFIG_ROME_IF),ipci) + CONFIG_HIF_IPCI := y +endif + #Enable USB specific APIS ifeq ($(CONFIG_ROME_IF),usb) CONFIG_HIF_USB := y @@ -485,14 +594,13 @@ endif CONFIG_FEATURE_AP_MCC_CH_AVOIDANCE := y else CONFIG_QCOM_ESE := y -CONFIG_QCA_IBSS_SUPPORT := y CONFIG_FEATURE_WLAN_RMC := y CONFIG_WLAN_OPEN_P2P_INTERFACE := y CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY := y endif -#enable 4addr support for QCS405 -ifeq ($(CONFIG_ARCH_QCS405), y) +#enable 4addr support for QCS40X +ifeq ($(CONFIG_ARCH_QCS40X), y) CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME := y endif @@ -520,6 +628,10 @@ ifeq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_CUSTOM_DSCP_UP_MAP := y endif +ifeq ($(CONFIG_ARCH_BENGAL), y) +CONFIG_SMMU_S1_UNMAP := y +endif + ifeq ($(CONFIG_ROME_IF), sdio) CONFIG_PKTLOG_LEGACY := y endif @@ -541,8 +653,10 @@ ifeq ($(CONFIG_LITHIUM), y) CONFIG_PKTLOG_LEGACY := n endif -ifeq ($(CONFIG_ARCH_BENGAL), y) -CONFIG_SMMU_S1_UNMAP := y +ifeq ($(CONFIG_LITHIUM), y) +CONFIG_WAPI_BIG_ENDIAN := y +else +CONFIG_WAPI_BIG_ENDIAN := n endif #Enable WDI Event support @@ -605,10 +719,7 @@ CONFIG_ATH_PCIE_ACCESS_DEBUG := n ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif @@ -636,6 +747,7 @@ endif ifeq ($(CONFIG_ARCH_KONA), y) ifeq ($(CONFIG_IPA_OFFLOAD), y) CONFIG_ENABLE_SMMU_S1_TRANSLATION := y +CONFIG_SMMU_S1_UNMAP := y endif endif @@ -684,24 +796,18 @@ CONFIG_FEATURE_HTC_CREDIT_HISTORY := y #Flag to enable MTRACE feature CONFIG_TRACE_RECORD_FEATURE := y -#Flag to enable p2p debug feature -CONFIG_WLAN_FEATURE_P2P_DEBUG := y - -#Flag to enable roam debug log -CONFIG_FEATURE_ROAM_DEBUG := y - #Flag to enable DFS Master feature CONFIG_WLAN_DFS_MASTER_ENABLE := y #Flag to enable WEXT support for STA/AP/P2P interfaces CONFIG_WLAN_WEXT_SUPPORT_ENABLE := y -#Flag to enable/disable MTRACE feature -CONFIG_ENABLE_MTRACE_LOG := y - #Flag to enable nud tracking feature CONFIG_WLAN_NUD_TRACKING := y +#Flag to enable/Disable Function call trace +CONFIG_FUNC_CALL_MAP := n + #Flag to enable wbuff feature CONFIG_WLAN_WBUFF := y @@ -741,9 +847,6 @@ CONFIG_FEATURE_WLAN_WAPI := y CONFIG_AGEIE_ON_SCAN_RESULTS := y -#Flag to enable FW log parsing support feature -CONFIG_FEATURE_FW_LOG_PARSING := y - CONFIG_PTT_SOCK_SVC_ENABLE := y CONFIG_SOFTAP_CHANNEL_RANGE := y CONFIG_FEATURE_WLAN_SCAN_PNO := y @@ -754,16 +857,16 @@ CONFIG_FEATURE_WLAN_LPHB := y CONFIG_QCA_SUPPORT_TX_THROTTLE := y CONFIG_WMI_INTERFACE_EVENT_LOGGING := y CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := y -CONFIG_FEATURE_WLAN_EXTSCAN := y +CONFIG_FEATURE_WLAN_EXTSCAN := n CONFIG_WMI_BCN_OFFLOAD := y CONFIG_160MHZ_SUPPORT := y CONFIG_MCL := y CONFIG_REG_CLIENT := y -CONFIG_LEGACY_CHAN_ENUM := y CONFIG_WLAN_PMO_ENABLE := y CONFIG_CONVERGED_P2P_ENABLE := y CONFIG_WLAN_POLICY_MGR_ENABLE := y CONFIG_FEATURE_BLACKLIST_MGR := y +CONFIG_FOURTH_CONNECTION := y CONFIG_SUPPORT_11AX := y CONFIG_HDD_INIT_WITH_RTNL_LOCK := y CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y @@ -774,7 +877,7 @@ CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY := n CONFIG_WLAN_FEATURE_TWT := y CONFIG_FW_THERMAL_THROTTLE := y -ifeq (y,$(findstring y,$(CONFIG_LITHIUM) $(CONFIG_ICNSS) $(CONFIG_ICNSS_MODULE))) +ifeq (y,$(findstring y,$(CONFIG_LITHIUM) $(CONFIG_ICNSS))) CONFIG_WLAN_FEATURE_BMI := n else CONFIG_WLAN_FEATURE_BMI := y @@ -817,7 +920,6 @@ ifeq ($(CONFIG_SLUB_DEBUG_ON), y) CONFIG_SCHED_HISTORY_SIZE := 256 CONFIG_TALLOC_DEBUG := y CONFIG_UNIT_TEST := y - CONFIG_RX_DESC_DEBUG_CHECK:= y CONFIG_REGISTER_OP_DEBUG := y CONFIG_ENABLE_QDF_PTR_HASH_DEBUG := y endif @@ -834,17 +936,19 @@ ifeq ($(CONFIG_LITHIUM), y) CONFIG_HIF_CE_DEBUG_DATA_BUF := y CONFIG_WLAN_RECORD_RX_PADDR := y CONFIG_HIF_CPU_PERF_AFFINE_MASK := y + CONFIG_WLAN_FEATURE_DP_RX_RING_HISTORY := y + CONFIG_ALLOW_PKT_DROPPING := y endif + CONFIG_RX_DESC_DEBUG_CHECK:= y CONFIG_WLAN_SUPPORT_DATA_STALL := y CONFIG_WLAN_DP_PER_RING_TYPE_CONFIG := y + CONFIG_WLAN_CE_INTERRUPT_THRESHOLD_CONFIG := y #Enable WMI TX/RX over QMI CONFIG_WMI_SEND_RECV_QMI := y CONFIG_WLAN_DP_PENDING_MEM_FLUSH := y + CONFIG_DYNAMIC_RX_AGGREGATION := y endif -#Flag to enable hdd memory dump feature -CONFIG_FEATURE_MEMDUMP_ENABLE := y - #Flag to enable/disable WLAN D0-WOW ifeq ($(CONFIG_PCI_MSM), y) ifeq ($(CONFIG_HIF_PCI), y) @@ -861,7 +965,6 @@ CONFIG_CHANNEL_HOPPING_ALL_BANDS := y endif ifeq ($(CONFIG_ARCH_SDXPRAIRIE), y) - CONFIG_FEATURE_MONITOR_MODE_SUPPORT := n ifneq ($(CONFIG_SLUB_DEBUG), y) CONFIG_DP_TRACE := n endif @@ -879,7 +982,7 @@ CONFIG_DESC_DUP_DETECT_DEBUG := y CONFIG_DEBUG_RX_RING_BUFFER := y endif -ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_CNSS_MODULE))) +ifeq ($(CONFIG_CNSS), y) ifeq ($(CONFIG_CNSS_SDIO), y) CONFIG_PLD_SDIO_CNSS_FLAG := y endif @@ -888,7 +991,18 @@ CONFIG_PLD_PCIE_CNSS_FLAG := y endif endif -ifeq (y,$(findstring y,$(CONFIG_CNSS2) $(CONFIG_CNSS2_MODULE))) +ifeq ($(CONFIG_ICNSS2), y) +CONFIG_PLD_IPCI_ICNSS_FLAG := y +endif + +ifeq ($(CONFIG_CNSS2), y) +ifeq ($(CONFIG_HIF_PCI), y) +CONFIG_PLD_PCIE_CNSS_FLAG := y +CONFIG_PLD_PCIE_INIT_FLAG := y +endif +endif + +ifeq ($(CONFIG_CNSS2), m) ifeq ($(CONFIG_HIF_PCI), y) CONFIG_PLD_PCIE_CNSS_FLAG := y CONFIG_PLD_PCIE_INIT_FLAG := y @@ -909,14 +1023,38 @@ ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y) CONFIG_WLAN_FEATURE_ELNA := y endif -ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) +#Enable DP Bus Vote CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y + +ifeq ($(CONFIG_CNSS_QCA6490), y) + +#Enable 6 GHz Band +CONFIG_BAND_6GHZ := y +CONFIG_RX_FISA := y +CONFIG_MORE_TX_DESC := y + endif -ifeq ($(CONFIG_ARCH_SDM660), y) -CONFIG_WLAN_FEATURE_PKT_CAPTURE := y +CONFIG_HANDLE_BC_EAP_TX_FRM := y + +ifeq ($(CONFIG_BAND_6GHZ), y) + +CONFIG_6G_SCAN_CHAN_SORT_ALGO := y + endif -ifeq ($(CONFIG_ARCH_BENGAL), y) -CONFIG_WLAN_FEATURE_PKT_CAPTURE := y +CONFIG_SAP_DHCP_FW_IND := y + +#Enable support to get ANI level +CONFIG_ANI_LEVEL_REQUEST := y + +ifeq ($(CONFIG_ARCH_QCS405), y) +CONFIG_FEATURE_WLAN_TIME_SYNC_FTM := y endif + +CONFIG_WLAN_HANG_EVENT := y + +CONFIG_FEATURE_GPIO_CFG := y + +#Enable VDEV Response wakelock feature +CONFIG_FEATURE_VDEV_RSP_WAKELOCK := y diff --git a/drivers/staging/qcacld-3.0/configs/genoa.common b/drivers/staging/qcacld-3.0/configs/genoa.common index 6cf78cc14377850660b9420603d2c14c32a28281..e4980ca651b35bab23844fa8588a86af2f34b507 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.common +++ b/drivers/staging/qcacld-3.0/configs/genoa.common @@ -14,6 +14,7 @@ CONFIG_QCACLD_WLAN_LFR2 := y CONFIG_QCACLD_WLAN_LFR3 := n CONFIG_QCOM_TDLS := y CONFIG_QCACLD_FEATURE_GREEN_AP := n +CONFIG_CRYPTO_COMPONENT := y CONFIG_QCOM_VOWIFI_11R := y CONFIG_WLAN_FEATURE_FILS := y CONFIG_WLAN_FEATURE_11W := y @@ -32,7 +33,6 @@ CONFIG_WIFI_POS_CONVERGED := y CONFIG_WIFI_POS_LEGACY := n CONFIG_FEATURE_WLAN_WAPI := y CONFIG_AGEIE_ON_SCAN_RESULTS := y -CONFIG_LEGACY_CHAN_ENUM := y CONFIG_WLAN_PMO_ENABLE := y CONFIG_CONVERGED_P2P_ENABLE := y CONFIG_WLAN_POLICY_MGR_ENABLE := y @@ -65,7 +65,7 @@ CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY := y BUILD_DEBUG_VERSION := y BUILD_DIAG_VERSION := n -CONFIG_REMOVE_PKT_LOG := n +CONFIG_REMOVE_PKT_LOG := y CONFIG_FEATURE_HTC_CREDIT_HISTORY := y CONFIG_TRACE_RECORD_FEATURE := y CONFIG_WLAN_NUD_TRACKING := n @@ -88,6 +88,10 @@ else CONFIG_WDI_EVENT_ENABLE := y endif +ifeq ($(CONFIG_REMOVE_PKT_LOG), n) +CONFIG_PKTLOG_LEGACY := y +endif + #Enable the type_specific_data in the ath_pktlog_arg ifeq ($(CONFIG_REMOVE_PKT_LOG), n) CONFIG_PKTLOG_HAS_SPECIFIC_DATA := y @@ -129,6 +133,8 @@ CONFIG_WLAN_FEATURE_SAE := y CONFIG_CHNL_MATRIX_RESTRICTION := n CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY := y CONFIG_WLAN_FEATURE_BMI := n +# Enable FW stats version 2 +CONFIG_AR900B := y #Flags to enable/disable vendor commands CONFIG_FEATURE_RSSI_MONITOR := n @@ -215,10 +221,12 @@ CONFIG_HOST_OPCLASS := y #Enable STATE MACHINE HISTORY CONFIG_SM_ENG_HIST := n -ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) +ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM) $(CONFIG_QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK))) CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y endif +CONFIG_SAP_DHCP_FW_IND := n + #Enable FW Offload CONFIG_WLAN_FW_OFFLOAD := y diff --git a/drivers/staging/qcacld-3.0/configs/genoa.pci.debug_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.pci.debug_defconfig index 86b78791066e25d1297be1a9de644c50084b5d49..b5e415ef924e864ebd9c9bd6fe438147e2176123 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.pci.debug_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.pci.debug_defconfig @@ -25,10 +25,7 @@ CONFIG_DATA_CE_SW_INDEX_NO_INLINE_UPDATE := y ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif @@ -56,6 +53,9 @@ ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y) CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ := y endif +ifeq ($(CONFIG_WLAN_DEBUGFS), y) + CONFIG_WLAN_FEATURE_MIB_STATS := y +endif ifeq ($(CONFIG_SLUB_DEBUG_ON), y) CONFIG_DESC_DUP_DETECT_DEBUG := y @@ -82,7 +82,6 @@ CONFIG_ADRASTEA_RRI_ON_DDR := y CONFIG_ATH_PROCFS_DIAG_SUPPORT := y CONFIG_ADRASTEA_SHADOW_REGISTERS := y CONFIG_HTT_PADDR64 := y -CONFIG_AR900B := y CONFIG_RX_OL := y CONFIG_QCN7605_SUPPORT := y @@ -115,6 +114,13 @@ CONFIG_PLD_PCIE_INIT_FLAG := y endif endif +ifeq ($(CONFIG_CNSS2), m) +ifeq ($(CONFIG_HIF_PCI), y) +CONFIG_PLD_PCIE_CNSS_FLAG := y +CONFIG_PLD_PCIE_INIT_FLAG := y +endif +endif + CONFIG_QCA_WIFI_FTM := y ifeq ($(CONFIG_NL80211_TESTMODE), y) QCA_WIFI_FTM_NL80211 :=y diff --git a/drivers/staging/qcacld-3.0/configs/genoa.pci.perf_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.pci.perf_defconfig index ee176dc5ae6867d56b246e5c3de86a36e01b69eb..b9b0a35e0eb64e9c5c3e2f4b58e5c39ea042614d 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.pci.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.pci.perf_defconfig @@ -24,10 +24,7 @@ CONFIG_DATA_CE_SW_INDEX_NO_INLINE_UPDATE := y ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif @@ -80,7 +77,6 @@ CONFIG_ADRASTEA_RRI_ON_DDR := y CONFIG_ATH_PROCFS_DIAG_SUPPORT := y CONFIG_ADRASTEA_SHADOW_REGISTERS := y CONFIG_HTT_PADDR64 := y -CONFIG_AR900B := y CONFIG_RX_OL := y CONFIG_QCN7605_SUPPORT := y diff --git a/drivers/staging/qcacld-3.0/configs/genoa.sdio.debug_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.sdio.debug_defconfig index 722c75ff8e4b333af1c16f13c4dbbbdd3242bf63..bc5038ece82f9cc3722d0515baa363824d5bb4b3 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.sdio.debug_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.sdio.debug_defconfig @@ -7,11 +7,14 @@ CONFIG_QCA_WIFI_SDIO := y CONFIG_ROME_IF = sdio CONFIG_HIF_SDIO := y CONFIG_LINUX_QCMBR := y -CONFIG_SDIO_TRANSFER = mailbox +CONFIG_SDIO_TRANSFER = adma +CONFIG_PLD_SDIO_CNSS2 := y # Data Path specific features CONFIG_ATH_11AC_TXCOMPACT := n CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y +CONFIG_TX_RESOURCE_HIGH_TH_IN_PER := 8 +CONFIG_TX_RESOURCE_LOW_TH_IN_PER := 2 CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y @@ -40,6 +43,9 @@ CONFIG_FEATURE_UNIT_TEST_SUSPEND := y CONFIG_LEAK_DETECTION := y endif +# Genoa features vs Rome +CONFIG_HTT_PADDR64 := y + CONFIG_QCA_WIFI_FTM := y ifeq ($(CONFIG_NL80211_TESTMODE), y) QCA_WIFI_FTM_NL80211 :=y @@ -49,4 +55,7 @@ endif CONFIG_LINUX_QCMBR :=y CONFIG_TGT_NUM_MSDU_DESC := 0 CONFIG_RX_PN_CHECK_OFFLOAD := y +CONFIG_QCN7605_SUPPORT := y +CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT := y +CONFIG_CFG_TGT_AST_SKID_LIMIT := 16 ################################### diff --git a/drivers/staging/qcacld-3.0/configs/genoa.sdio.perf_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.sdio.perf_defconfig index 0c73dcccc762997eb6e9b20326ba5224bdf79a91..7faff21bd5519fd586661bb02c3aba879622d8c6 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.sdio.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.sdio.perf_defconfig @@ -7,11 +7,14 @@ CONFIG_QCA_WIFI_SDIO := y CONFIG_ROME_IF = sdio CONFIG_HIF_SDIO := y CONFIG_LINUX_QCMBR := y -CONFIG_SDIO_TRANSFER = mailbox +CONFIG_SDIO_TRANSFER = adma +CONFIG_PLD_SDIO_CNSS2 := y # Data Path specific features CONFIG_ATH_11AC_TXCOMPACT := n CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y +CONFIG_TX_RESOURCE_HIGH_TH_IN_PER := 8 +CONFIG_TX_RESOURCE_LOW_TH_IN_PER := 2 CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y @@ -35,6 +38,8 @@ CONFIG_FEATURE_UNIT_TEST_SUSPEND := n CONFIG_LEAK_DETECTION := n endif +# Genoa features vs Rome +CONFIG_HTT_PADDR64 := y CONFIG_ENABLE_SIZE_OPTIMIZE := y @@ -55,4 +60,7 @@ QCA_WIFI_FTM_NL80211 := n CONFIG_LINUX_QCMBR := n CONFIG_TGT_NUM_MSDU_DESC := 0 CONFIG_RX_PN_CHECK_OFFLOAD := y +CONFIG_QCN7605_SUPPORT := y +CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT := y +CONFIG_CFG_TGT_AST_SKID_LIMIT := 16 ################################### diff --git a/drivers/staging/qcacld-3.0/configs/genoa.snoc.debug_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.snoc.debug_defconfig index c953a1519ab23efd62a3d52c189ee0121176088a..00193403998cab07197e18afa89aa585dd4d160f 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.snoc.debug_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.snoc.debug_defconfig @@ -11,7 +11,6 @@ CONFIG_ADRASTEA_RRI_ON_DDR := y CONFIG_ATH_PROCFS_DIAG_SUPPORT := y CONFIG_ADRASTEA_SHADOW_REGISTERS := y CONFIG_HTT_PADDR64 := y -CONFIG_AR900B := y CONFIG_HIF_SNOC:= y # Genoa specific features @@ -37,10 +36,7 @@ endif ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif diff --git a/drivers/staging/qcacld-3.0/configs/genoa.snoc.perf_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.snoc.perf_defconfig index 47f9c573bd9f2dbb4c5e05b88b0218681903bf1c..800c77405dff01196c6135fb443007bc0427556b 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.snoc.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.snoc.perf_defconfig @@ -11,7 +11,6 @@ CONFIG_ADRASTEA_RRI_ON_DDR := y CONFIG_ATH_PROCFS_DIAG_SUPPORT := y CONFIG_ADRASTEA_SHADOW_REGISTERS := y CONFIG_HTT_PADDR64 := y -CONFIG_AR900B := y CONFIG_HIF_SNOC:= y # Genoa specific features @@ -37,10 +36,7 @@ endif ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif diff --git a/drivers/staging/qcacld-3.0/configs/genoa.usb.debug_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.usb.debug_defconfig index f8158bfab93d34a650250d63825a8ae146fc6e3a..9c9ff3b2f83c03f69faf45eb1af2f4d0ff67f53b 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.usb.debug_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.usb.debug_defconfig @@ -10,11 +10,17 @@ CONFIG_PLD_USB_CNSS := y # Data Path specific features CONFIG_ATH_11AC_TXCOMPACT := n CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y +CONFIG_TX_RESOURCE_HIGH_TH_IN_PER := 8 +CONFIG_TX_RESOURCE_LOW_TH_IN_PER := 2 CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y +CONFIG_WLAN_SUPPORT_TXRX_HL_BUNDLE := y CONFIG_HL_DP_SUPPORT := y +# Enable Motion Detection Feature +CONFIG_FEATURE_MOTION_DETECTION := y + # Debug specific features CONFIG_MPC_UT_FRAMEWORK := y CONFIG_FEATURE_EPPING := y @@ -28,11 +34,12 @@ ifeq ($(CONFIG_DEBUG_FS), y) endif ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y) - CONFIG_WLAN_SYNC_TSF_PLUS := y CONFIG_WLAN_SYNC_TSF_PTP := y - CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ := y endif +CONFIG_WLAN_SYNC_TSF_PLUS := y +CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC := y + # Features gets enabled on slub debug CONFIG_WLAN_DEBUG_CRASH_INJECT := y CONFIG_FEATURE_MEMDUMP_ENABLE := y @@ -56,4 +63,8 @@ endif CONFIG_LINUX_QCMBR :=y CONFIG_QCN7605_SUPPORT := y CONFIG_TGT_NUM_MSDU_DESC := 0 +# For OOB wakeup +CONFIG_WLAN_FEATURE_WOW_PULSE := y +CONFIG_HTC_MAX_MSG_PER_BUNDLE_TX := 48 +CONFIG_CFG_TGT_AST_SKID_LIMIT := 16 ################################### diff --git a/drivers/staging/qcacld-3.0/configs/genoa.usb.perf_defconfig b/drivers/staging/qcacld-3.0/configs/genoa.usb.perf_defconfig index cecaea8f79c3473567663ab1b2e216094772aace..2fc9780f327b190cb30a1241d4ef901c9f24c7f3 100644 --- a/drivers/staging/qcacld-3.0/configs/genoa.usb.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/genoa.usb.perf_defconfig @@ -10,11 +10,17 @@ CONFIG_PLD_USB_CNSS := y # Data Path specific features CONFIG_ATH_11AC_TXCOMPACT := n CONFIG_QCA_HL_NETDEV_FLOW_CONTROL := y +CONFIG_TX_RESOURCE_HIGH_TH_IN_PER := 8 +CONFIG_TX_RESOURCE_LOW_TH_IN_PER := 2 CONFIG_FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL := y CONFIG_FEATURE_HL_DBS_GROUP_CREDIT_SHARING := y CONFIG_CREDIT_REP_THROUGH_CREDIT_UPDATE := y +CONFIG_WLAN_SUPPORT_TXRX_HL_BUNDLE := y CONFIG_HL_DP_SUPPORT := y +# Enable Motion Detection Feature +CONFIG_FEATURE_MOTION_DETECTION := y + # Debug specific features CONFIG_MPC_UT_FRAMEWORK := n CONFIG_FEATURE_EPPING := n @@ -22,6 +28,11 @@ CONFIG_WLAN_FEATURE_P2P_DEBUG := n CONFIG_WLAN_LOG_ENTER := n CONFIG_WLAN_LOG_EXIT := n +ifeq ($(CONFIG_DEBUG_FS), y) + CONFIG_WLAN_DEBUGFS := y + CONFIG_WLAN_POWER_DEBUGFS := y +endif + # Features gets enabled on slub debug CONFIG_WLAN_DEBUG_CRASH_INJECT := n CONFIG_FEATURE_MEMDUMP_ENABLE := n @@ -33,11 +44,12 @@ CONFIG_LEAK_DETECTION := n endif ifeq ($(CONFIG_NETWORK_PHY_TIMESTAMPING), y) - CONFIG_WLAN_SYNC_TSF_PLUS := y CONFIG_WLAN_SYNC_TSF_PTP := y - CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_IRQ := y endif +CONFIG_WLAN_SYNC_TSF_PLUS := y +CONFIG_WLAN_SYNC_TSF_PLUS_EXT_GPIO_SYNC := y + CONFIG_ENABLE_SIZE_OPTIMIZE := y # configure log buffer size @@ -61,4 +73,8 @@ QCA_WIFI_FTM_NL80211 := n CONFIG_LINUX_QCMBR := n CONFIG_QCN7605_SUPPORT := y CONFIG_TGT_NUM_MSDU_DESC := 0 +# For OOB wakeup +CONFIG_WLAN_FEATURE_WOW_PULSE := y +CONFIG_HTC_MAX_MSG_PER_BUNDLE_TX := 48 +CONFIG_CFG_TGT_AST_SKID_LIMIT := 16 ################################### diff --git a/drivers/staging/qcacld-3.0/configs/qca6174_defconfig b/drivers/staging/qcacld-3.0/configs/qca6174_defconfig index 4022b06297c285e9ff5d7d56e95311195e8fefbe..ebca507edc941212b3f711d6096a2a5777b83e1f 100644 --- a/drivers/staging/qcacld-3.0/configs/qca6174_defconfig +++ b/drivers/staging/qcacld-3.0/configs/qca6174_defconfig @@ -22,6 +22,16 @@ ifndef CONFIG_ROME_IF endif endif +ifeq (m,$(findstring m,$(CONFIG_CNSS) $(CONFIG_CNSS2))) +ifndef CONFIG_ROME_IF + #use pci as default interface + CONFIG_ROME_IF = pci +endif +endif + +# Enable FCC TYPE4 DURATION CHECK +CONFIG_DFS_FCC_TYPE4_DURATION_CHECK := y + # Make WLAN as open-source driver by default WLAN_OPEN_SOURCE := y @@ -70,11 +80,11 @@ ifeq ($(CONFIG_ARCH_QCS405), y) CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ := y endif -#Flag to enable Legacy Fast Roaming2(LFR2) -CONFIG_QCACLD_WLAN_LFR2 := y #Flag to enable Legacy Fast Roaming3(LFR3) -ifneq ($(CONFIG_ARCH_SDX20), y) -CONFIG_QCACLD_WLAN_LFR3 := y +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) + CONFIG_QCACLD_WLAN_LFR3 := y +else + CONFIG_QCACLD_WLAN_LFR2 := y endif ifneq ($(CONFIG_MOBILE_ROUTER), y) @@ -85,7 +95,6 @@ CONFIG_WLAN_SYSFS := y endif CONFIG_QCACLD_FEATURE_GREEN_AP := y -CONFIG_CRYPTO_COMPONENT := y #Flag to enable Android Packet Filtering CONFIG_QCACLD_FEATURE_APF := y @@ -139,6 +148,17 @@ ifneq ($(CONFIG_QCA_CLD_WLAN),) CONFIG_WLAN_FEATURE_LPSS := y endif endif + + ifeq (m,$(findstring m,$(CONFIG_CNSS2))) + #Flag to enable Protected Management Frames (11w) feature + CONFIG_WLAN_FEATURE_11W := y + #Flag to enable LTE CoEx feature + CONFIG_QCOM_LTE_COEX := y + ifneq ($(CONFIG_MOBILE_ROUTER), y) + #Flag to enable LPSS feature + CONFIG_WLAN_FEATURE_LPSS := y + endif + endif endif #Flag to enable Protected Management Frames (11w) feature @@ -154,10 +174,8 @@ ifeq ($(CONFIG_ROME_IF),usb) CONFIG_QCA_TXDESC_SANITY_CHECKS := y endif -ifneq ($(CONFIG_MOBILE_ROUTER), y) - #Flag to enable NAN - CONFIG_QCACLD_FEATURE_NAN := y -endif +#Flag to disable NAN +CONFIG_QCACLD_FEATURE_NAN := n ifneq ($(CONFIG_MOBILE_ROUTER), y) #Flag to enable NAN Data path @@ -184,6 +202,9 @@ CONFIG_WLAN_FEATURE_DSRC := y endif ifneq ($(CONFIG_ROME_IF),usb) + #Flag to enable SAE + CONFIG_WLAN_FEATURE_SAE := y + ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable DISA CONFIG_WLAN_FEATURE_DISA := y @@ -191,9 +212,6 @@ ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable FIPS CONFIG_WLAN_FEATURE_FIPS := y - #Flag to enable SAE - CONFIG_WLAN_FEATURE_SAE := y - # Flag to enable NAPI CONFIG_WLAN_NAPI := y CONFIG_WLAN_NAPI_DEBUG := n @@ -233,7 +251,7 @@ else CONFIG_LL_DP_SUPPORT := y endif -ifeq ($(CONFIG_HIF_PCI), y) +ifeq ($(CONFIG_ROME_IF),pci) ifneq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y) ifneq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y @@ -256,9 +274,13 @@ CONFIG_ADRASTEA_SHADOW_REGISTERS := y endif endif +# Enable fw stats version 2 +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) +CONFIG_AR900B := y +endif + # NOTE: CONFIG_64BIT_PADDR requires CONFIG_HELIUMPLUS ifeq ($(CONFIG_HELIUMPLUS), y) -CONFIG_AR900B := y ifeq ($(CONFIG_64BIT_PADDR), y) CONFIG_HTT_PADDR64 := y @@ -399,7 +421,6 @@ CONFIG_FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE := y CONFIG_FEATURE_AP_MCC_CH_AVOIDANCE := y else CONFIG_QCOM_ESE := y -CONFIG_QCA_IBSS_SUPPORT := y CONFIG_FEATURE_WLAN_RMC := y CONFIG_WLAN_OPEN_P2P_INTERFACE := y CONFIG_WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY := y @@ -472,13 +493,17 @@ CONFIG_ATH_PCIE_ACCESS_DEBUG := n ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif +#Set MAX IPA Offload Interface +ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) +ifeq ($(CONFIG_IPA_OFFLOAD), y) +CONFIG_NUM_IPA_IFACE := 2 +endif +endif + #Flag to enable SMMU S1 support ifeq ($(CONFIG_ARCH_SDM845), y) ifeq ($(CONFIG_IPA_OFFLOAD), y) @@ -492,6 +517,12 @@ CONFIG_ENABLE_SMMU_S1_TRANSLATION := y endif endif +ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) +ifeq ($(CONFIG_IPA_OFFLOAD), y) +CONFIG_ENABLE_SMMU_S1_TRANSLATION := y +endif +endif + ifeq ($(CONFIG_ARCH_SDX20), y) ifeq ($(CONFIG_QCA_WIFI_SDIO), y) ifeq ($(CONFIG_WCNSS_SKB_PRE_ALLOC), y) @@ -576,12 +607,11 @@ CONFIG_FEATURE_WLAN_LPHB := y CONFIG_QCA_SUPPORT_TX_THROTTLE := y CONFIG_WMI_INTERFACE_EVENT_LOGGING := y CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := y -CONFIG_FEATURE_WLAN_EXTSCAN := y +CONFIG_FEATURE_WLAN_EXTSCAN := n CONFIG_WMI_BCN_OFFLOAD := y CONFIG_160MHZ_SUPPORT := y CONFIG_MCL := y CONFIG_REG_CLIENT := y -CONFIG_LEGACY_CHAN_ENUM := y CONFIG_WLAN_PMO_ENABLE := y CONFIG_CONVERGED_P2P_ENABLE := y CONFIG_WLAN_POLICY_MGR_ENABLE := y @@ -696,16 +726,27 @@ CONFIG_PLD_PCIE_INIT_FLAG := y endif endif +ifeq ($(CONFIG_CNSS2), m) +ifeq ($(CONFIG_HIF_PCI), y) +CONFIG_PLD_PCIE_CNSS_FLAG := y +CONFIG_PLD_PCIE_INIT_FLAG := y +endif +endif + #Enable STATE MACHINE HISTORY CONFIG_SM_ENG_HIST := n #Enable Beacon Reception Stats +ifeq ($(CONFIG_WLAN_SYSFS), y) CONFIG_FEATURE_BECN_STATS := y +endif ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y endif +CONFIG_SAP_DHCP_FW_IND := y + #Enable FW Offload CONFIG_WLAN_FW_OFFLOAD := y diff --git a/drivers/staging/qcacld-3.0/configs/qca6390_defconfig b/drivers/staging/qcacld-3.0/configs/qca6390_defconfig index a2d54b86dfcb5c0f4e4a423b186f00fa36bd7545..b3493ed65b1009bb79a76419499f3b7b51cb65cd 100644 --- a/drivers/staging/qcacld-3.0/configs/qca6390_defconfig +++ b/drivers/staging/qcacld-3.0/configs/qca6390_defconfig @@ -14,6 +14,15 @@ ifeq ($(CONFIG_CNSS_QCA6390), y) CONFIG_SCALE_INCLUDES := y endif +ifeq ($(CONFIG_ENABLE_IPA), y) + CONFIG_IPA3 := y + CONFIG_WDI3_IPA_OVER_GSI := y +else + ifeq ($(CONFIG_ENABLE_IPA), n) + CONFIG_IPA3 := n + endif +endif + ifeq ($(CONFIG_CLD_HL_SDIO_CORE), y) CONFIG_QCA_WIFI_SDIO := y ifndef CONFIG_SDIO_TRANSFER @@ -36,6 +45,13 @@ ifndef CONFIG_ROME_IF endif endif +ifeq (m,$(findstring m,$(CONFIG_CNSS) $(CONFIG_CNSS2))) +ifndef CONFIG_ROME_IF + #use pci as default interface + CONFIG_ROME_IF = pci +endif +endif + # Make WLAN as open-source driver by default WLAN_OPEN_SOURCE := y @@ -43,7 +59,6 @@ ifeq ($(CONFIG_ICNSS), y) CONFIG_HELIUMPLUS := y CONFIG_64BIT_PADDR := y CONFIG_FEATURE_TSO := y - CONFIG_FEATURE_TSO_DEBUG := y ifeq ($(CONFIG_INET_LRO), y) CONFIG_WLAN_LRO := y else @@ -84,11 +99,11 @@ ifeq ($(CONFIG_ARCH_QCS405), y) CONFIG_WLAN_SYNC_TSF_PLUS_NOIRQ := y endif -#Flag to enable Legacy Fast Roaming2(LFR2) -CONFIG_QCACLD_WLAN_LFR2 := y #Flag to enable Legacy Fast Roaming3(LFR3) -ifneq ($(CONFIG_ARCH_SDX20), y) -CONFIG_QCACLD_WLAN_LFR3 := y +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) + CONFIG_QCACLD_WLAN_LFR3 := y +else + CONFIG_QCACLD_WLAN_LFR2 := y endif ifneq ($(CONFIG_MOBILE_ROUTER), y) @@ -99,7 +114,6 @@ CONFIG_WLAN_SYSFS := y endif CONFIG_QCACLD_FEATURE_GREEN_AP := y -CONFIG_CRYPTO_COMPONENT := y #Flag to enable Android Packet Filtering CONFIG_QCACLD_FEATURE_APF := y @@ -153,6 +167,17 @@ ifneq ($(CONFIG_QCA_CLD_WLAN),) CONFIG_WLAN_FEATURE_LPSS := y endif endif + + ifeq (m,$(findstring m,$(CONFIG_CNSS2))) + #Flag to enable Protected Management Frames (11w) feature + CONFIG_WLAN_FEATURE_11W := y + #Flag to enable LTE CoEx feature + CONFIG_QCOM_LTE_COEX := y + ifneq ($(CONFIG_MOBILE_ROUTER), y) + #Flag to enable LPSS feature + CONFIG_WLAN_FEATURE_LPSS := y + endif + endif endif #Flag to enable Protected Management Frames (11w) feature @@ -171,6 +196,7 @@ endif ifneq ($(CONFIG_MOBILE_ROUTER), y) #Flag to enable NAN CONFIG_QCACLD_FEATURE_NAN := y + CONFIG_NDP_SAP_CONCURRENCY_ENABLE := y endif ifneq ($(CONFIG_MOBILE_ROUTER), y) @@ -198,6 +224,9 @@ CONFIG_WLAN_FEATURE_DSRC := y endif ifneq ($(CONFIG_ROME_IF),usb) + #Flag to enable SAE + CONFIG_WLAN_FEATURE_SAE := y + ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable DISA CONFIG_WLAN_FEATURE_DISA := y @@ -205,9 +234,6 @@ ifneq ($(CONFIG_ROME_IF),sdio) #Flag to enable FIPS CONFIG_WLAN_FEATURE_FIPS := y - #Flag to enable SAE - CONFIG_WLAN_FEATURE_SAE := y - #Flag to enable Fast Path feature ifneq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_FASTPATH := y @@ -252,7 +278,7 @@ else CONFIG_LL_DP_SUPPORT := y endif -ifeq ($(CONFIG_HIF_PCI), y) +ifeq ($(CONFIG_ROME_IF),pci) ifneq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y) ifneq ($(CONFIG_LITHIUM), y) CONFIG_WLAN_TX_FLOW_CONTROL_LEGACY := y @@ -275,9 +301,13 @@ CONFIG_ADRASTEA_SHADOW_REGISTERS := y endif endif +# Enable fw stats version 2 +ifeq (y,$(findstring y,$(CONFIG_HELIUMPLUS) $(CONFIG_LITHIUM))) +CONFIG_AR900B := y +endif + # NOTE: CONFIG_64BIT_PADDR requires CONFIG_HELIUMPLUS ifeq ($(CONFIG_HELIUMPLUS), y) -CONFIG_AR900B := y ifeq ($(CONFIG_64BIT_PADDR), y) CONFIG_HTT_PADDR64 := y @@ -307,11 +337,11 @@ CONFIG_DP_INTR_POLL_BASED := y CONFIG_TX_PER_PDEV_DESC_POOL := y CONFIG_DP_TRACE := y CONFIG_FEATURE_TSO := y -CONFIG_TSO_DEBUG_LOG_ENABLE := y CONFIG_DP_LFR := y CONFIG_HTT_PADDR64 := y CONFIG_RX_OL := y CONFIG_TX_TID_OVERRIDE := y +CONFIG_DP_TXRX_SOC_ATTACH := y endif # As per target team, build is done as follows: @@ -371,9 +401,6 @@ CONFIG_WLAN_LOG_FATAL := y CONFIG_WLAN_LOG_ERROR := y CONFIG_WLAN_LOG_WARN := y CONFIG_WLAN_LOG_INFO := y -CONFIG_WLAN_LOG_DEBUG := y -CONFIG_WLAN_LOG_ENTER := y -CONFIG_WLAN_LOG_EXIT := y #Enable OL debug and wmi unified functions CONFIG_ATH_PERF_PWR_OFFLOAD := y @@ -497,10 +524,7 @@ CONFIG_ATH_PCIE_ACCESS_DEBUG := n ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif @@ -517,6 +541,13 @@ CONFIG_ENABLE_SMMU_S1_TRANSLATION := y endif endif +#Flag to enable SMMU S1 support +ifeq ($(CONFIG_ARCH_SDXPRAIRIE), y) +ifeq ($(CONFIG_IPA_OFFLOAD), y) +CONFIG_ENABLE_SMMU_S1_TRANSLATION := y +endif +endif + ifeq ($(CONFIG_ARCH_SDX20), y) ifeq ($(CONFIG_QCA_WIFI_SDIO), y) ifeq ($(CONFIG_WCNSS_SKB_PRE_ALLOC), y) @@ -550,21 +581,12 @@ CONFIG_FEATURE_HTC_CREDIT_HISTORY := y #Flag to enable MTRACE feature CONFIG_TRACE_RECORD_FEATURE := y -#Flag to enable p2p debug feature -CONFIG_WLAN_FEATURE_P2P_DEBUG := y - -#Flag to enable roam debug log -CONFIG_FEATURE_ROAM_DEBUG := y - #Flag to enable DFS Master feature CONFIG_WLAN_DFS_MASTER_ENABLE := y #Flag to enable WEXT support for STA/AP/P2P interfaces CONFIG_WLAN_WEXT_SUPPORT_ENABLE := y -#Flag to enable/disable MTRACE feature -CONFIG_ENABLE_MTRACE_LOG := y - #Flag to enable nud tracking feature CONFIG_WLAN_NUD_TRACKING := y @@ -588,9 +610,6 @@ CONFIG_FEATURE_WLAN_WAPI := y CONFIG_AGEIE_ON_SCAN_RESULTS := y -#Flag to enable FW log parsing support feature -CONFIG_FEATURE_FW_LOG_PARSING := y - CONFIG_PTT_SOCK_SVC_ENABLE := y CONFIG_SOFTAP_CHANNEL_RANGE := y CONFIG_FEATURE_WLAN_SCAN_PNO := y @@ -601,15 +620,16 @@ CONFIG_FEATURE_WLAN_LPHB := y CONFIG_QCA_SUPPORT_TX_THROTTLE := y CONFIG_WMI_INTERFACE_EVENT_LOGGING := y CONFIG_WLAN_FEATURE_LINK_LAYER_STATS := y -CONFIG_FEATURE_WLAN_EXTSCAN := y +CONFIG_WLAN_FEATURE_MIB_STATS := y +CONFIG_FEATURE_WLAN_EXTSCAN := n CONFIG_WMI_BCN_OFFLOAD := y CONFIG_160MHZ_SUPPORT := y CONFIG_MCL := y CONFIG_REG_CLIENT := y -CONFIG_LEGACY_CHAN_ENUM := y CONFIG_WLAN_PMO_ENABLE := y CONFIG_CONVERGED_P2P_ENABLE := y CONFIG_WLAN_POLICY_MGR_ENABLE := y +CONFIG_FEATURE_BLACKLIST_MGR := y CONFIG_SUPPORT_11AX := y CONFIG_HDD_INIT_WITH_RTNL_LOCK := y CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y @@ -618,7 +638,12 @@ CONFIG_WMI_CMD_STRINGS := y CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY := n CONFIG_WLAN_FEATURE_TWT := y + +ifeq (y,$(findstring y,$(CONFIG_LITHIUM) $(CONFIG_ICNSS))) +CONFIG_WLAN_FEATURE_BMI := n +else CONFIG_WLAN_FEATURE_BMI := y +endif #Flags to enable/disable vendor commands CONFIG_FEATURE_RSSI_MONITOR := y @@ -631,6 +656,7 @@ CONFIG_FEATURE_SAR_LIMITS := y CONFIG_FEATURE_CONCURRENCY_MATRIX := y CONFIG_FEATURE_SAP_COND_CHAN_SWITCH := y CONFIG_FEATURE_P2P_LISTEN_OFFLOAD := y +CONFIG_QCACLD_RX_DESC_MULTI_PAGE_ALLOC := y #Flags to enable/disable WMI APIs CONFIG_WMI_ROAM_SUPPORT := y @@ -671,9 +697,6 @@ ifeq ($(CONFIG_LITHIUM), y) CONFIG_FEATURE_UNIT_TEST_SUSPEND := y endif -#Flag to enable hdd memory dump feature -CONFIG_FEATURE_MEMDUMP_ENABLE := y - #Flag to enable/disable WLAN D0-WOW ifeq ($(CONFIG_PCI_MSM), y) ifeq ($(CONFIG_HIF_PCI), y) @@ -689,6 +712,13 @@ ifeq ($(CONFIG_ARCH_MSM8996), y) CONFIG_CHANNEL_HOPPING_ALL_BANDS := y endif +ifeq ($(CONFIG_ARCH_SDXPRAIRIE), y) + CONFIG_FEATURE_MONITOR_MODE_SUPPORT := n + ifneq ($(CONFIG_SLUB_DEBUG), y) + CONFIG_DP_TRACE := n + endif +endif + ifneq ($(CONFIG_HIF_USB), y) CONFIG_WLAN_LOGGING_SOCK_SVC := y endif @@ -698,7 +728,6 @@ CONFIG_DESC_DUP_DETECT_DEBUG := y CONFIG_DEBUG_RX_RING_BUFFER := y endif -CONFIG_DP_TRACE := y ifeq ($(CONFIG_CNSS), y) ifeq ($(CONFIG_CNSS_SDIO), y) @@ -716,16 +745,29 @@ CONFIG_PLD_PCIE_INIT_FLAG := y endif endif +ifeq ($(CONFIG_CNSS2), m) +ifeq ($(CONFIG_HIF_PCI), y) +CONFIG_PLD_PCIE_CNSS_FLAG := y +CONFIG_PLD_PCIE_INIT_FLAG := y +endif +endif + #Enable STATE MACHINE HISTORY CONFIG_SM_ENG_HIST := n +ifeq ($(CONFIG_WLAN_SYSFS), y) #Enable Beacon Reception Stats CONFIG_FEATURE_BECN_STATS := y +endif ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y endif +CONFIG_FOURTH_CONNECTION := y +CONFIG_FOURTH_CONNECTION_AUTO := y +CONFIG_SAP_DHCP_FW_IND := y + #Enable FW Offload CONFIG_WLAN_FW_OFFLOAD := y diff --git a/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig b/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig index 15795232b78bc464a6915dd1bfbd9a5e8b6d03fa..0dd909d814c07e82f70332460b122831ac7cfb23 100644 --- a/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig +++ b/drivers/staging/qcacld-3.0/configs/qcs40x.snoc.perf_defconfig @@ -23,10 +23,10 @@ CONFIG_WIFI_POS_CONVERGED := y CONFIG_WIFI_POS_LEGACY := n CONFIG_FEATURE_WLAN_WAPI := y CONFIG_AGEIE_ON_SCAN_RESULTS := y -CONFIG_LEGACY_CHAN_ENUM := y CONFIG_CONVERGED_P2P_ENABLE := y CONFIG_WLAN_POLICY_MGR_ENABLE := y -CONFIG_SUPPORT_11AX := y +CONFIG_SUPPORT_11AX := n +CONFIG_HOST_OPCLASS := y CONFIG_HDD_INIT_WITH_RTNL_LOCK := y CONFIG_CONVERGED_TDLS_ENABLE := y CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y @@ -34,6 +34,8 @@ CONFIG_WLAN_SPECTRAL_ENABLE := y CONFIG_WMI_CMD_STRINGS := n CONFIG_SOFTAP_CHANNEL_RANGE := y CONFIG_FEATURE_WLAN_SCAN_PNO := y +CONFIG_DFS_PRI_MULTIPLIER := y +CONFIG_DFS_OVERRIDE_RF_THRESHOLD := y # Interface specific features CONFIG_ROME_IF = snoc @@ -52,7 +54,7 @@ CONFIG_HIF_SNOC:= y CONFIG_WLAN_FASTPATH := y CONFIG_FEATURE_TSO := y CONFIG_WLAN_NAPI := y -CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y +CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n CONFIG_ATH_11AC_TXCOMPACT := y CONFIG_TX_CREDIT_RECLAIM_SUPPORT := n CONFIG_CHECKSUM_OFFLOAD := y @@ -62,7 +64,10 @@ CONFIG_FEATURE_MONITOR_MODE_SUPPORT := n CONFIG_DESC_DUP_DETECT_DEBUG := n CONFIG_DEBUG_RX_RING_BUFFER := n CONFIG_RX_PERFORMANCE := y -CONFIG_QCS403_MEM_OPTIMIZE := y +CONFIG_SLUB_MEM_OPTIMIZE := y +CONFIG_TGT_NUM_MSDU_DESC := 900 +CONFIG_WLAN_PDEV_TX_FLOW_CONTROL := y +CONFIG_FEATURE_WLAN_STA_4ADDR_SCHEME := y ifeq ($(CONFIG_INET_LRO), y) CONFIG_WLAN_LRO := y @@ -73,10 +78,7 @@ endif ifeq ($(CONFIG_IPA), y) CONFIG_IPA_OFFLOAD := y endif -ifeq ($(CONFIG_IPA3), m) -CONFIG_IPA3_MODULE := y -endif -ifeq (y, $(findstring y, $(CONFIG_IPA3) $(CONFIG_IPA3_MODULE))) +ifeq ($(CONFIG_IPA3), y) CONFIG_IPA_OFFLOAD := y endif @@ -97,7 +99,7 @@ CONFIG_FEATURE_HTC_CREDIT_HISTORY := y CONFIG_TRACE_RECORD_FEATURE := y CONFIG_WLAN_FEATURE_P2P_DEBUG := n CONFIG_WLAN_NUD_TRACKING := n -CONFIG_CP_STATS := y +CONFIG_CP_STATS := n CONFIG_FEATURE_FW_LOG_PARSING := y CONFIG_PTT_SOCK_SVC_ENABLE := y CONFIG_WMI_INTERFACE_EVENT_LOGGING := y @@ -152,7 +154,7 @@ CONFIG_WLAN_FEATURE_PACKET_FILTERING := y CONFIG_WLAN_NS_OFFLOAD := y CONFIG_FEATURE_WLAN_RA_FILTERING:= y CONFIG_FEATURE_WLAN_LPHB := y -CONFIG_FEATURE_WLAN_EXTSCAN := y +CONFIG_FEATURE_WLAN_EXTSCAN := n CONFIG_160MHZ_SUPPORT := y CONFIG_MCL := y CONFIG_MCL_REGDB := y @@ -164,6 +166,8 @@ CONFIG_WLAN_FEATURE_DISA := n CONFIG_WLAN_FEATURE_FIPS := n CONFIG_WLAN_FEATURE_SAE := y CONFIG_GTK_OFFLOAD := y +CONFIG_QCACLD_FEATURE_COEX_CONFIG := y +CONFIG_QCACLD_FEATURE_MPTA_HELPER := y CONFIG_WMI_ROAM_SUPPORT := y CONFIG_WMI_STA_SUPPORT := y CONFIG_REG_CLIENT := y @@ -195,6 +199,7 @@ endif CONFIG_WLAN_FW_OFFLOAD := y CONFIG_ENABLE_SIZE_OPTIMIZE := y +CONFIG_FEATURE_WLAN_TIME_SYNC_FTM := y # configure log buffer size CONFIG_CFG_NUM_DP_TRACE_RECORD := 1000 @@ -204,5 +209,5 @@ CONFIG_CFG_NUM_WMI_MGMT_EVENT_HISTORY := 16 CONFIG_CFG_NUM_TX_RX_HISTOGRAM := 16 # CONFIG_CFG_NUM_RX_IND_RECORD := 1024 - +CONFIG_SAP_DHCP_FW_IND := y ################################### diff --git a/drivers/staging/qcacld-3.0/configs/whunt_defconfig b/drivers/staging/qcacld-3.0/configs/whunt_defconfig index 0a3277616be88e22babbb28f6e98a5b2ef139df3..80f896793a2e06d9d905b25331d2a43dcc3ce7b0 100644 --- a/drivers/staging/qcacld-3.0/configs/whunt_defconfig +++ b/drivers/staging/qcacld-3.0/configs/whunt_defconfig @@ -5,3 +5,9 @@ CONFIG_BAND_6GHZ := y CONFIG_WLAN_FEATURE_11AX := y include $(WLAN_ROOT)/configs/default_defconfig + +#Enable BUS bandwidth Feature +CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y + +#Disable PM_QOS not supported in WHUNT +CONFIG_WLAN_CLD_PM_QOS := n diff --git a/drivers/staging/qcacld-3.0/core/bmi/inc/bmi.h b/drivers/staging/qcacld-3.0/core/bmi/inc/bmi.h index 583a1b117af947592197408144c8637fb5342b9b..586d6355ebf242b05f94da4825e4d808c02b8289 100644 --- a/drivers/staging/qcacld-3.0/core/bmi/inc/bmi.h +++ b/drivers/staging/qcacld-3.0/core/bmi/inc/bmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,6 +54,15 @@ QDF_STATUS ol_cds_init(qdf_device_t qdf_dev, void *hif_ctx); void ol_cds_free(void); void ol_init_ini_config(struct ol_context *ol_ctx, struct ol_config_info *cfg); +/** + * ol_set_fw_crashed_cb() - set firmware crashed callback + * @ol_ctx: ol context + * @callback_fn: fw crashed callback function + * + * Return: None + */ +void ol_set_fw_crashed_cb(struct ol_context *ol_ctx, + void (*callback_fn)(void)); void bmi_cleanup(struct ol_context *scn); QDF_STATUS bmi_done(struct ol_context *ol_ctx); void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx); @@ -76,6 +85,11 @@ ol_init_ini_config(struct ol_context *ol_ctx, struct ol_config_info *cfg) { } +static inline void +ol_set_fw_crashed_cb(struct ol_context *ol_ctx, void (*callback_fn)(void)) +{ +} + static inline void bmi_cleanup(struct ol_context *scn) { } diff --git a/drivers/staging/qcacld-3.0/core/bmi/src/i_bmi.h b/drivers/staging/qcacld-3.0/core/bmi/src/i_bmi.h index ae9857b328a546664d14f57f15e5fc4e1018403e..bde7417987a7c6b8f91b79ce1c35f50cf7f70341 100644 --- a/drivers/staging/qcacld-3.0/core/bmi/src/i_bmi.h +++ b/drivers/staging/qcacld-3.0/core/bmi/src/i_bmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -154,6 +154,7 @@ struct bmi_info { * @ramdump_work: Work for Ramdump collection * @fw_indication_work: Work for Fw inciation * @tgt_def: Target Defnition pointer + * @fw_crashed_cb: Callback for firmware crashed ind * * Structure to hold all ol BMI/Ramdump info */ @@ -168,6 +169,7 @@ struct ol_context { struct targetdef_t { struct targetdef_s *targetdef; } tgt_def; + void (*fw_crashed_cb)(void); }; #define GET_BMI_CONTEXT(ol_ctx) ((struct bmi_info *)ol_ctx) diff --git a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c index 0cc26269ee02343062abdc20fb470bf3786b0379..8dbc58beba2927463e0e75b22919e5a439592f19 100644 --- a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c +++ b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c @@ -545,13 +545,19 @@ struct ramdump_info { /** * if have platform driver support, reinit will be called by CNSS. - * recovery flag will be cleaned by reinit function. If not support, - * clean recovery flag in CLD driver. + * recovery flag will be cleaned and CRASHED indication will be sent + * to user space by reinit function. If not support, clean recovery + * flag and send CRASHED indication in CLD driver. */ -static inline void ol_check_clean_recovery_flag(struct device *dev) +static inline void ol_check_clean_recovery_flag(struct ol_context *ol_ctx) { - if (!pld_have_platform_driver_support(dev)) + qdf_device_t qdf_dev = ol_ctx->qdf_dev; + + if (!pld_have_platform_driver_support(qdf_dev->dev)) { cds_set_recovery_in_progress(false); + if (ol_ctx->fw_crashed_cb) + ol_ctx->fw_crashed_cb(); + } } #if !defined(QCA_WIFI_3_0) @@ -608,7 +614,7 @@ int ol_copy_ramdump(struct hif_opaque_softc *scn) return ret; } -void ramdump_work_handler(void *data) +static void __ramdump_work_handler(void *data) { int ret; uint32_t host_interest_address; @@ -645,7 +651,7 @@ void ramdump_work_handler(void *data) BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!"); ol_copy_ramdump(ramdump_scn); pld_device_crashed(qdf_dev->dev); - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); return; } @@ -672,10 +678,10 @@ void ramdump_work_handler(void *data) */ if (cds_is_load_or_unload_in_progress()) cds_set_recovery_in_progress(false); - else + else { pld_device_crashed(qdf_dev->dev); - - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); + } return; out_fail: @@ -686,7 +692,19 @@ void ramdump_work_handler(void *data) else pld_device_crashed(qdf_dev->dev); - ol_check_clean_recovery_flag(qdf_dev->dev); + ol_check_clean_recovery_flag(ol_ctx); +} + +void ramdump_work_handler(void *data) +{ + struct qdf_op_sync *op_sync; + + if (qdf_op_protect(&op_sync)) + return; + + __ramdump_work_handler(data); + + qdf_op_unprotect(op_sync); } void fw_indication_work_handler(void *data) @@ -696,6 +714,8 @@ void fw_indication_work_handler(void *data) pld_device_self_recovery(qdf_dev->dev, PLD_REASON_DEFAULT); + + ol_check_clean_recovery_flag(ol_ctx); } void ol_target_failure(void *instance, QDF_STATUS status) @@ -1920,3 +1940,9 @@ void ol_init_ini_config(struct ol_context *ol_ctx, { qdf_mem_copy(&ol_ctx->cfg_info, cfg, sizeof(struct ol_config_info)); } + +void ol_set_fw_crashed_cb(struct ol_context *ol_ctx, + void (*callback_fn)(void)) +{ + ol_ctx->fw_crashed_cb = callback_fn; +} diff --git a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw_common.c b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw_common.c index 4bc6b681a89a7f56be11417a7640df9f5b016ab3..7756e46370c66e8e3ea21d72ee49b9644a7ae043 100644 --- a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw_common.c +++ b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw_common.c @@ -30,6 +30,9 @@ #if defined(HIF_USB) #include "regtable_usb.h" #endif +#if defined(CONFIG_CNSS) +#include +#endif #include "i_bmi.h" #include "cds_api.h" diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_api.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_api.h index 23a92e25b3f0392cb7b53f7beb9acc21337974a7..3c43e6dad6832480dfa0321db44c5a70c8de7f75 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_api.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -327,8 +327,6 @@ QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc); void *cds_get_context(QDF_MODULE_ID module_id); -uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev, - struct cdp_vdev **vdev, uint8_t sessionId); void *cds_get_global_context(void); QDF_STATUS cds_alloc_context(QDF_MODULE_ID module_id, void **module_context, @@ -338,9 +336,6 @@ QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context); QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context); -QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type, - uint32_t *subType); - void cds_flush_work(void *work); void cds_flush_delayed_work(void *dwork); @@ -377,6 +372,10 @@ void cds_reset_recovery_reason(void); */ #define cds_trigger_recovery(reason) \ __cds_trigger_recovery(reason, __func__, __LINE__) + +void cds_trigger_recovery_psoc(void *psoc, enum qdf_hang_reason reason, + const char *func, const uint32_t line); + void __cds_trigger_recovery(enum qdf_hang_reason reason, const char *func, const uint32_t line); @@ -556,4 +555,40 @@ QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present); * Return: Status of map operation */ int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr); + +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * cds_is_pktcapture_enabled() - is packet capture support enabled + * + * Check is packet capture mode enabled from ini + * + * Return: 0 - disable, 1 - enable + */ +bool cds_is_pktcapture_enabled(void); + +/** + * cds_get_pktcapture_mode() - get pktcapture mode value + * + * Get the pktcapture mode value from hdd context + * + * Return: 0 - disable + * 1 - Mgmt packets + * 2 - Data packets + * 3 - Both Mgmt and Data packets + */ +uint8_t cds_get_pktcapture_mode(void); +#else +static inline +bool cds_is_pktcapture_enabled(void) +{ + return false; +} + +static inline +uint8_t cds_get_pktcapture_mode(void) +{ + return 0; +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #endif /* if !defined __CDS_API_H */ diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_config.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_config.h index d05934c5bb18011fba271a1f2ff4a771c570c767..75b30bce1c66bf40ace71e0eea36ffa5ff20fadd 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_config.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_config.h @@ -86,8 +86,10 @@ struct cds_config_info { uint8_t reorder_offload; uint8_t uc_offload_enabled; bool enable_rxthread; +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) uint32_t tx_flow_stop_queue_th; uint32_t tx_flow_start_queue_offset; +#endif uint8_t enable_dp_rx_threads; #ifdef WLAN_FEATURE_LPSS bool is_lpass_enabled; diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h index f43b168284460efa3b5871d31fb4fe55e3e57c59..9cc2f3c8beeb54fc0cd2e684bb29a95a76fda86d 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,8 +61,8 @@ struct ieee80211_frame_bar { uint8_t i_dur[2]; uint8_t i_ra[QDF_MAC_ADDR_SIZE]; uint8_t i_ta[QDF_MAC_ADDR_SIZE]; - uint8_t i_ctl; - uint8_t i_seq; + uint16_t i_ctl; + uint16_t i_seq; /* FCS */ } __packed; diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_sched.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_sched.h index c09b63d9c57f80db35f33d897378976cf8784bff..585d996b68a50f22f6648e7895233af0684d852e 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_sched.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_sched.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -78,6 +78,88 @@ struct cds_ol_rx_pkt { }; +#ifdef WLAN_FEATURE_PKT_CAPTURE +/* + * Maximum number of cds messages to be allocated for + * OL MON thread. + */ +#define CDS_MAX_OL_MON_PKT 4000 + +struct cds_sched_mon_context { + /* MON thread lock */ + spinlock_t ol_mon_thread_lock; + + /* OL MON thread handle */ + struct task_struct *ol_mon_thread; + + /* Handle of Event for MON thread to signal startup */ + struct completion ol_mon_start_event; + + /* Completion object to suspend OL MON thread */ + struct completion ol_suspend_mon_event; + + /* Completion objext to resume OL MON thread */ + struct completion ol_resume_mon_event; + + /* Completion object for OL MON thread shutdown */ + struct completion ol_mon_shutdown; + + /* Waitq for OL MON thread */ + wait_queue_head_t ol_mon_wait_queue; + + unsigned long ol_mon_event_flag; + + /* MON buffer queue */ + struct list_head ol_mon_thread_queue; + + /* Spinlock to synchronize between tasklet and thread */ + spinlock_t ol_mon_queue_lock; + + /* MON queue length */ + unsigned int ol_mon_queue_len; + + /* Lock to synchronize free buffer queue access */ + spinlock_t cds_ol_mon_pkt_freeq_lock; + + /* Free message queue for OL MON processing */ + struct list_head cds_ol_mon_pkt_freeq; + + /* MON thread affinity cpu */ + unsigned long mon_thread_cpu; + +}; + +#endif /* WLAN_FEATURE_PKT_CAPTURE */ +typedef void (*cds_ol_mon_thread_cb)( + void *context, void *monpkt, + uint8_t vdev_id, uint8_t tid, + uint8_t status, bool pkt_format); + +/* + * CDS message wrapper for mon data from TXRX + */ +struct cds_ol_mon_pkt { + struct list_head list; + void *context; + + /* mon skb */ + void *monpkt; + + /* vdev id to which this packet is destined */ + uint8_t vdev_id; + + uint8_t tid; + + /* Tx packet status */ + uint8_t status; + + /* 0 = 802.3 format , 1 = 802.11 format */ + bool pkt_format; + + /* Call back to further send this packet to txrx layer */ + cds_ol_mon_thread_cb callback; +}; + /* ** CDS Scheduler context ** The scheduler context contains the following: @@ -141,6 +223,10 @@ typedef struct _cds_sched_context { bool rx_affinity_required; uint8_t conf_rx_thread_ul_affinity; #endif + +#ifdef WLAN_FEATURE_PKT_CAPTURE + struct cds_sched_mon_context sched_mon_ctx; +#endif /* WLAN_FEATURE_PKT_CAPTURE */ } cds_sched_context, *p_cds_sched_context; /** @@ -190,9 +276,10 @@ struct cds_context { */ qdf_device_t qdf_ctx; - struct cdp_pdev *pdev_txrx_ctx; void *dp_soc; + void *dp_mem_pre_alloc_ctx; + /* Configuration handle used to get system configuration */ struct cdp_cfg *cfg_ctx; @@ -552,4 +639,162 @@ void cds_shutdown_notifier_call(void); */ void cds_resume_rx_thread(void); +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * cds_resume_mon_thread() - resume mon thread by completing its resume event + * + * Resume MON thread by completing RX thread resume event + * + * Return: None + */ +void cds_resume_mon_thread(void); + +/** + * cds_drop_monpkt() - API to drop pending mon packets + * @pschedcontext: Pointer to the global CDS Sched Context + * + * This api drops all the pending packets in the queue. + * + * Return: none + */ +void cds_drop_monpkt(p_cds_sched_context pschedcontext); + +/** + * cds_indicate_monpkt() - API to Indicate rx data packet + * @pschedcontext: pointer to CDS Sched Context + * @pkt: CDS OL MON pkt pointer containing to mon data message buffer + * + * Return: none + */ +void cds_indicate_monpkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt); + +/** + * cds_wakeup_mon_thread() - wakeup mon thread + * @Arg: Pointer to the global CDS Sched Context + * + * This api wake up cds_ol_mon_thread() to process pkt + * + * Return: none + */ +void cds_wakeup_mon_thread(p_cds_sched_context pschedcontext); + +/** + * cds_close_mon_thread() - close the Tlshim MON thread + * + * This api closes the Tlshim MON thread: + * + * Return: qdf status + */ +QDF_STATUS cds_close_mon_thread(void); + +/** + * cds_open_mon_thread() - open the Tlshim MON thread + * @pSchedContext: Pointer to the global CDS Sched Context + * + * This api opens the Tlshim MON thread: + * + * Return: qdf status + */ +QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext); + +/** + * cds_alloc_mon_thread() - alloc resources for MON thread + * @pSchedContext: Pointer to the global CDS Sched Context + * + * This api alloc resources for MON thread: + * + * Return: qdf status + */ +QDF_STATUS cds_alloc_mon_thread(p_cds_sched_context pschedcontext); + +/** + * cds_alloc_ol_mon_pkt() - API to return next available cds message + * @pSchedContext: Pointer to the global CDS Sched Context + * + * This api returns next available cds message buffer used for mon data + * processing + * + * Return: Pointer to cds message buffer + */ +struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext); + +/** + * cds_free_ol_mon_pkt() - api to release cds message to the freeq + * This api returns the cds message used for mon data to the free queue + * @pSchedContext: Pointer to the global CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue. + * + * Return: none + */ +void cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt); + +/** + * cds_free_ol_mon_pkt_freeq() - free cds buffer free queue + * @pSchedContext - pointer to the global CDS Sched Context + * + * This API does mem free of the buffers available in free cds buffer + * queue which is used for mon Data processing. + * + * Return: none + */ +void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext); +#else +static inline +void cds_resume_mon_thread(void) +{ +} + +static inline +void cds_drop_monpkt(p_cds_sched_context pschedcontext) +{ +} + +static inline +void cds_indicate_monpkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt) +{ +} + +static inline +void cds_wakeup_mon_thread(p_cds_sched_context pschedcontext) +{ +} + +static inline +QDF_STATUS cds_close_mon_thread(void) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS cds_alloc_mon_thread(p_cds_sched_context pschedcontext) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext) +{ + return NULL; +} + +static inline +void cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt) +{ +} + +static inline +void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext) +{ +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ #endif /* #ifndef __CDS_SCHED_H */ diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c index d8ebd1db36f996ef1f060979d30b8819b9dfe092..d28382a58d43a88f597bc6fd32680da9021df4e7 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +75,10 @@ #include "wlan_mlme_ucfg_api.h" #include "cfg_ucfg_api.h" #include "wlan_cp_stats_mc_ucfg_api.h" +#include +#include +#include +#include /* Preprocessor Definitions and Constants */ @@ -85,16 +91,23 @@ static struct __qdf_device g_qdf_ctx; static uint8_t cds_multicast_logging; +#define DRIVER_VER_LEN (11) +#define HANG_EVENT_VER_LEN (1) + +struct cds_hang_event_fixed_param { + uint16_t tlv_header; + uint8_t recovery_reason; + char driver_version[DRIVER_VER_LEN]; + char hang_event_version[HANG_EVENT_VER_LEN]; +} qdf_packed; + #ifdef QCA_WIFI_QCA8074 static inline int -cds_send_delba(void *pdev_handle, void *ctrl_peer, - uint8_t *peer_macaddr, uint8_t tid, void *vdev_handle, - uint8_t reason_code) +cds_send_delba(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *peer_macaddr, + uint8_t tid, uint8_t reason_code) { - struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)vdev_handle; - - return wma_dp_send_delba_ind(wlan_vdev_get_id(vdev), peer_macaddr, tid, - reason_code); + return wma_dp_send_delba_ind(vdev_id, peer_macaddr, tid, reason_code); } static struct ol_if_ops dp_ol_if_ops = { @@ -103,11 +116,19 @@ static struct ol_if_ops dp_ol_if_ops = { .peer_rx_reorder_queue_remove = target_if_peer_rx_reorder_queue_remove, .is_hw_dbs_2x2_capable = policy_mgr_is_dp_hw_dbs_2x2_capable, .lro_hash_config = target_if_lro_hash_config, - .rx_mic_error = wma_rx_mic_error_ind, .rx_invalid_peer = wma_rx_invalid_peer_ind, .is_roam_inprogress = wma_is_roam_in_progress, .get_con_mode = cds_get_conparam, .send_delba = cds_send_delba, +#ifdef DP_MEM_PRE_ALLOC + .dp_prealloc_get_context = dp_prealloc_get_context_memory, + .dp_prealloc_put_context = dp_prealloc_put_context_memory, + .dp_prealloc_get_consistent = dp_prealloc_get_coherent, + .dp_prealloc_put_consistent = dp_prealloc_put_coherent, + .dp_get_multi_pages = dp_prealloc_get_multi_pages, + .dp_put_multi_pages = dp_prealloc_put_multi_pages, +#endif + .dp_rx_get_pending = dp_rx_tm_get_pending, /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; #else @@ -158,43 +179,26 @@ static void cds_recovery_work_deinit(void) } } -/** cds_get_datapath_handles - Initialize pdev, vdev and soc - * @soc - soc handle - * @vdev - virtual handle - * @pdev - physical handle - */ -uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev, - struct cdp_vdev **vdev, uint8_t sessionId) +static bool cds_is_drv_connected(void) { + int ret; + qdf_device_t qdf_ctx; - (*soc) = cds_get_context(QDF_MODULE_ID_SOC); - - if (!(*soc)) { - cds_err("soc handle is invalid"); - return -EINVAL; - } - - (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!(*pdev)) { - cds_err("pdev handle is invalid"); - return -EINVAL; + qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + if (!qdf_ctx) { + cds_err("cds context is invalid"); + return false; } - (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev), - sessionId); + ret = pld_is_drv_connected(qdf_ctx->dev); - if (!(*vdev)) { - cds_err("vdev handle is invalid"); - return -EINVAL; - } - return 0; + return ((ret > 0) ? true : false); } -static bool cds_is_drv_connected(void) +static bool cds_is_drv_supported(void) { - int ret; qdf_device_t qdf_ctx; + struct pld_platform_cap cap = {0}; qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); if (!qdf_ctx) { @@ -202,9 +206,9 @@ static bool cds_is_drv_connected(void) return false; } - ret = pld_is_drv_connected(qdf_ctx->dev); + pld_get_platform_cap(qdf_ctx->dev, &cap); - return ((ret > 0) ? true : false); + return ((cap.cap_flag & PLD_HAS_DRV_SUPPORT) ? true : false); } static QDF_STATUS cds_wmi_send_recv_qmi(void *buf, uint32_t len, void * cb_ctx, @@ -215,7 +219,7 @@ static QDF_STATUS cds_wmi_send_recv_qmi(void *buf, uint32_t len, void * cb_ctx, qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); if (!qdf_ctx) { cds_err("cds context is invalid"); - return false; + return QDF_STATUS_E_INVAL; } if (pld_qmi_send(qdf_ctx->dev, 0, buf, len, cb_ctx, wmi_rx_cb)) @@ -224,6 +228,22 @@ static QDF_STATUS cds_wmi_send_recv_qmi(void *buf, uint32_t len, void * cb_ctx, return QDF_STATUS_SUCCESS; } +/** + * cds_update_recovery_reason() - update the recovery reason code + * @reason: recovery reason + * + * Return: None + */ +static void cds_update_recovery_reason(enum qdf_hang_reason recovery_reason) +{ + if (!gp_cds_context) { + cds_err("gp_cds_context is null"); + return; + } + + gp_cds_context->recovery_reason = recovery_reason; +} + QDF_STATUS cds_init(void) { QDF_STATUS status; @@ -240,12 +260,15 @@ QDF_STATUS cds_init(void) gp_cds_context->qdf_ctx = &g_qdf_ctx; - qdf_register_self_recovery_callback(__cds_trigger_recovery); + qdf_register_self_recovery_callback(cds_trigger_recovery_psoc); qdf_register_fw_down_callback(cds_is_fw_down); qdf_register_is_driver_unloading_callback(cds_is_driver_unloading); qdf_register_recovering_state_query_callback(cds_is_driver_recovering); qdf_register_drv_connected_callback(cds_is_drv_connected); + qdf_register_drv_supported_callback(cds_is_drv_supported); qdf_register_wmi_send_recv_qmi_callback(cds_wmi_send_recv_qmi); + qdf_register_recovery_reason_update(cds_update_recovery_reason); + qdf_register_get_bus_reg_dump(pld_get_bus_reg_dump); return QDF_STATUS_SUCCESS; @@ -267,6 +290,8 @@ void cds_deinit(void) if (!gp_cds_context) return; + qdf_register_get_bus_reg_dump(NULL); + qdf_register_recovery_reason_update(NULL); qdf_register_recovering_state_query_callback(NULL); qdf_register_fw_down_callback(NULL); qdf_register_is_driver_unloading_callback(NULL); @@ -347,6 +372,7 @@ cds_cfg_update_ac_specs_params(struct txrx_pdev_cfg_param_t *olcfg, } } +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) static inline void cds_cdp_set_flow_control_params(struct wlan_objmgr_psoc *psoc, struct txrx_pdev_cfg_param_t *cdp_cfg) @@ -356,6 +382,49 @@ cds_cdp_set_flow_control_params(struct wlan_objmgr_psoc *psoc, cdp_cfg->tx_flow_start_queue_offset = cfg_get(psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); } +#else +static inline void +cds_cdp_set_flow_control_params(struct wlan_objmgr_psoc *psoc, + struct txrx_pdev_cfg_param_t *cdp_cfg) +{} +#endif + +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +static inline void +cds_cdp_update_del_ack_params(struct wlan_objmgr_psoc *psoc, + struct txrx_pdev_cfg_param_t *cdp_cfg) +{ + cdp_cfg->del_ack_enable = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_ENABLE); + cdp_cfg->del_ack_pkt_count = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_PKT_CNT); + cdp_cfg->del_ack_timer_value = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE); +} +#else +static inline void +cds_cdp_update_del_ack_params(struct wlan_objmgr_psoc *psoc, + struct txrx_pdev_cfg_param_t *cdp_cfg) +{} +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +static inline void +cds_cdp_update_bundle_params(struct wlan_objmgr_psoc *psoc, + struct txrx_pdev_cfg_param_t *cdp_cfg) +{ + cdp_cfg->bundle_timer_value = + cfg_get(psoc, CFG_DP_HL_BUNDLE_TIMER_VALUE); + cdp_cfg->bundle_size = + cfg_get(psoc, CFG_DP_HL_BUNDLE_SIZE); +} +#else +static inline void +cds_cdp_update_bundle_params(struct wlan_objmgr_psoc *psoc, + struct txrx_pdev_cfg_param_t *cdp_cfg) +{ +} +#endif /** * cds_cdp_cfg_attach() - attach data path config module @@ -368,6 +437,7 @@ static void cds_cdp_cfg_attach(struct wlan_objmgr_psoc *psoc) struct txrx_pdev_cfg_param_t cdp_cfg = {0}; void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct hdd_context *hdd_ctx = gp_cds_context->hdd_context; + uint32_t gro_bit_set; cdp_cfg.is_full_reorder_offload = cfg_get(psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT); @@ -382,13 +452,26 @@ static void cds_cdp_cfg_attach(struct wlan_objmgr_psoc *psoc) cdp_cfg.enable_rxthread = hdd_ctx->enable_rxthread; cdp_cfg.ip_tcp_udp_checksum_offload = cfg_get(psoc, CFG_DP_TCP_UDP_CKSUM_OFFLOAD); + cdp_cfg.nan_ip_tcp_udp_checksum_offload = + cfg_get(psoc, CFG_DP_NAN_TCP_UDP_CKSUM_OFFLOAD); + cdp_cfg.p2p_ip_tcp_udp_checksum_offload = + cfg_get(psoc, CFG_DP_P2P_TCP_UDP_CKSUM_OFFLOAD); + cdp_cfg.legacy_mode_csum_disable = + cfg_get(psoc, CFG_DP_LEGACY_MODE_CSUM_DISABLE); cdp_cfg.ce_classify_enabled = cfg_get(psoc, CFG_DP_CE_CLASSIFY_ENABLE); cdp_cfg.tso_enable = cfg_get(psoc, CFG_DP_TSO); cdp_cfg.lro_enable = cfg_get(psoc, CFG_DP_LRO); + cdp_cfg.sg_enable = cfg_get(psoc, CFG_DP_SG); cdp_cfg.enable_data_stall_detection = cfg_get(psoc, CFG_DP_ENABLE_DATA_STALL_DETECTION); - cdp_cfg.gro_enable = cfg_get(psoc, CFG_DP_GRO); + gro_bit_set = cfg_get(psoc, CFG_DP_GRO); + if (gro_bit_set & DP_GRO_ENABLE_BIT_SET) { + cdp_cfg.gro_enable = true; + if (gro_bit_set & DP_TC_BASED_DYNAMIC_GRO) + cdp_cfg.tc_based_dyn_gro = true; + } + cdp_cfg.tc_ingress_prio = cfg_get(psoc, CFG_DP_TC_INGRESS_PRIO); cdp_cfg.enable_flow_steering = cfg_get(psoc, CFG_DP_FLOW_STEERING_ENABLED); cdp_cfg.disable_intra_bss_fwd = @@ -396,6 +479,10 @@ static void cds_cdp_cfg_attach(struct wlan_objmgr_psoc *psoc) cdp_cfg.pktlog_buffer_size = cfg_get(psoc, CFG_DP_PKTLOG_BUFFER_SIZE); + cds_cdp_update_del_ack_params(psoc, &cdp_cfg); + + cds_cdp_update_bundle_params(psoc, &cdp_cfg); + gp_cds_context->cfg_ctx = cdp_cfg_attach(soc, gp_cds_context->qdf_ctx, (void *)(&cdp_cfg)); if (!gp_cds_context->cfg_ctx) { @@ -501,6 +588,54 @@ cds_set_ac_specs_params(struct cds_config_info *cds_cfg) } } +static int cds_hang_event_notifier_call(struct notifier_block *block, + unsigned long state, + void *data) +{ + struct qdf_notifer_data *cds_hang_data = data; + uint32_t total_len; + struct cds_hang_event_fixed_param *cmd; + uint8_t *cds_hang_evt_buff; + + if (!cds_hang_data) + return NOTIFY_STOP_MASK; + + cds_hang_evt_buff = cds_hang_data->hang_data; + + if (!cds_hang_evt_buff) + return NOTIFY_STOP_MASK; + + total_len = sizeof(*cmd); + if (cds_hang_data->offset + total_len > QDF_WLAN_HANG_FW_OFFSET) + return NOTIFY_STOP_MASK; + + cds_hang_evt_buff = cds_hang_data->hang_data + cds_hang_data->offset; + cmd = (struct cds_hang_event_fixed_param *)cds_hang_evt_buff; + QDF_HANG_EVT_SET_HDR(&cmd->tlv_header, HANG_EVT_TAG_CDS, + QDF_HANG_GET_STRUCT_TLVLEN(*cmd)); + + cmd->recovery_reason = gp_cds_context->recovery_reason; + + /* userspace expects a fixed format */ + qdf_mem_set(&cmd->driver_version, DRIVER_VER_LEN, ' '); + qdf_mem_copy(&cmd->driver_version, QWLAN_VERSIONSTR, + qdf_min(sizeof(QWLAN_VERSIONSTR) - 1, + (size_t)DRIVER_VER_LEN)); + + /* userspace expects a fixed format */ + qdf_mem_set(&cmd->hang_event_version, HANG_EVENT_VER_LEN, ' '); + qdf_mem_copy(&cmd->hang_event_version, QDF_HANG_EVENT_VERSION, + qdf_min(sizeof(QDF_HANG_EVENT_VERSION) - 1, + (size_t)HANG_EVENT_VER_LEN)); + + cds_hang_data->offset += total_len; + return NOTIFY_OK; +} + +static qdf_notif_block cds_hang_event_notifier = { + .notif_block.notifier_call = cds_hang_event_notifier_call, +}; + /** * cds_open() - open the CDS Module * @@ -662,21 +797,25 @@ QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc) goto err_wma_close; } - cds_debug("target_type %d 8074:%d 6290:%d 6390: %d", + cds_debug("target_type %d 8074:%d 6290:%d 6390: %d 6490: %d 6750: %d", hdd_ctx->target_type, TARGET_TYPE_QCA8074, TARGET_TYPE_QCA6290, - TARGET_TYPE_QCA6390); + TARGET_TYPE_QCA6390, + TARGET_TYPE_QCA6490, + TARGET_TYPE_QCA6750); if (TARGET_TYPE_QCA6290 == hdd_ctx->target_type || - TARGET_TYPE_QCA6390 == hdd_ctx->target_type) + TARGET_TYPE_QCA6390 == hdd_ctx->target_type || + TARGET_TYPE_QCA6490 == hdd_ctx->target_type || + TARGET_TYPE_QCA6750 == hdd_ctx->target_type) gp_cds_context->dp_soc = cdp_soc_attach(LITHIUM_DP, - gp_cds_context->hif_context, psoc, + gp_cds_context->hif_context, htcInfo.target_psoc, gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx, &dp_ol_if_ops); else gp_cds_context->dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP, - gp_cds_context->hif_context, psoc, + gp_cds_context->hif_context, htcInfo.target_psoc, gp_cds_context->htc_ctx, gp_cds_context->qdf_ctx, &dp_ol_if_ops); @@ -722,6 +861,7 @@ QDF_STATUS cds_open(struct wlan_objmgr_psoc *psoc) } ucfg_mc_cp_stats_register_pmo_handler(); + qdf_hang_event_register_notifier(&cds_hang_event_notifier); return QDF_STATUS_SUCCESS; @@ -774,13 +914,18 @@ QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc) { QDF_STATUS qdf_status; struct dp_txrx_config dp_config; + struct hdd_context *hdd_ctx; - cds_set_context(QDF_MODULE_ID_TXRX, - cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_ctrl_objmgr_pdev *)gp_cds_context->cfg_ctx, - gp_cds_context->htc_ctx, - gp_cds_context->qdf_ctx, 0)); - if (!gp_cds_context->pdev_txrx_ctx) { + hdd_ctx = gp_cds_context->hdd_context; + if (!hdd_ctx) { + cds_err("HDD context is null"); + return QDF_STATUS_E_FAILURE; + } + + qdf_status = cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC), + gp_cds_context->htc_ctx, + gp_cds_context->qdf_ctx, 0); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { /* Critical Error ... Cannot proceed further */ cds_alert("Failed to open TXRX"); QDF_ASSERT(0); @@ -798,17 +943,25 @@ QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc) false : gp_cds_context->cds_cfg->enable_dp_rx_threads; qdf_status = dp_txrx_init(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), + OL_TXRX_PDEV_ID, &dp_config); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) goto intr_close; - ucfg_pmo_psoc_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx); - ucfg_ocb_set_txrx_handle(psoc, gp_cds_context->pdev_txrx_ctx); + ucfg_pmo_psoc_set_txrx_pdev_id(psoc, OL_TXRX_PDEV_ID); + ucfg_ocb_set_txrx_pdev_id(psoc, OL_TXRX_PDEV_ID); cds_debug("CDS successfully Opened"); + if (cdp_cfg_get(gp_cds_context->dp_soc, cfg_dp_tc_based_dyn_gro_enable)) + hdd_ctx->dp_agg_param.tc_based_dyn_gro = true; + else + hdd_ctx->dp_agg_param.tc_based_dyn_gro = false; + + hdd_ctx->dp_agg_param.tc_ingress_prio = + cdp_cfg_get(gp_cds_context->dp_soc, cfg_dp_tc_ingress_prio); + return 0; intr_close: @@ -816,7 +969,7 @@ QDF_STATUS cds_dp_open(struct wlan_objmgr_psoc *psoc) pdev_detach: cdp_pdev_detach(gp_cds_context->dp_soc, - cds_get_context(QDF_MODULE_ID_TXRX), false); + OL_TXRX_PDEV_ID, false); close: return QDF_STATUS_E_FAILURE; @@ -882,7 +1035,7 @@ QDF_STATUS cds_pre_enable(void) /* call Packetlog connect service */ if (QDF_GLOBAL_FTM_MODE != cds_get_conparam() && QDF_GLOBAL_EPPING_MODE != cds_get_conparam()) - cdp_pkt_log_con_service(soc, gp_cds_context->pdev_txrx_ctx, + cdp_pkt_log_con_service(soc, OL_TXRX_PDEV_ID, scn); /*call WMA pre start */ @@ -904,7 +1057,7 @@ QDF_STATUS cds_pre_enable(void) goto stop_wmi; } - errno = cdp_pdev_post_attach(soc, gp_cds_context->pdev_txrx_ctx); + errno = cdp_pdev_post_attach(soc, OL_TXRX_PDEV_ID); if (errno) { cds_err("Failed to attach pdev"); status = qdf_status_from_os_return(errno); @@ -933,6 +1086,7 @@ QDF_STATUS cds_pre_enable(void) } htc_stop(gp_cds_context->htc_ctx); + wma_wmi_work_close(); exit_with_status: return status; } @@ -990,7 +1144,7 @@ QDF_STATUS cds_enable(struct wlan_objmgr_psoc *psoc) } errno = cdp_pdev_attach_target(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX)); + OL_TXRX_PDEV_ID); if (errno) { cds_err("Failed to attach pdev target; errno:%d", errno); goto err_soc_target_detach; @@ -1093,7 +1247,6 @@ QDF_STATUS cds_post_disable(void) { tp_wma_handle wma_handle; struct hif_opaque_softc *hif_ctx; - struct cdp_pdev *txrx_pdev; struct scheduler_ctx *sched_ctx; QDF_STATUS qdf_status; @@ -1109,12 +1262,6 @@ QDF_STATUS cds_post_disable(void) return QDF_STATUS_E_INVAL; } - txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!txrx_pdev) { - cds_err("Failed to get txrx pdev!"); - return QDF_STATUS_E_INVAL; - } - /* flush any unprocessed scheduler messages */ sched_ctx = scheduler_get_context(); if (sched_ctx) @@ -1146,8 +1293,14 @@ QDF_STATUS cds_post_disable(void) return QDF_STATUS_E_INVAL; } + qdf_status = cds_close_mon_thread(); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + cds_err("Failed to close MON thread!"); + return QDF_STATUS_E_INVAL; + } + cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_pdev *)txrx_pdev, 1); + OL_TXRX_PDEV_ID, 1); return QDF_STATUS_SUCCESS; } @@ -1165,6 +1318,7 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc) { QDF_STATUS qdf_status; + qdf_hang_event_unregister_notifier(&cds_hang_event_notifier); qdf_status = cds_sched_close(); QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); if (QDF_IS_STATUS_ERROR(qdf_status)) @@ -1177,6 +1331,8 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc) dispatcher_psoc_close(psoc); + qdf_flush_work(&gp_cds_context->cds_recovery_work); + qdf_status = wma_wmi_work_close(); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { cds_err("Failed to close wma_wmi_work"); @@ -1243,18 +1399,13 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc) QDF_STATUS cds_dp_close(struct wlan_objmgr_psoc *psoc) { - void *ctx; - cdp_txrx_intr_detach(gp_cds_context->dp_soc); - ctx = cds_get_context(QDF_MODULE_ID_TXRX); dp_txrx_deinit(cds_get_context(QDF_MODULE_ID_SOC)); - cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_pdev *)ctx, 1); + cdp_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID, 1); - cds_set_context(QDF_MODULE_ID_TXRX, NULL); - ucfg_pmo_psoc_set_txrx_handle(psoc, NULL); + ucfg_pmo_psoc_set_txrx_pdev_id(psoc, OL_TXRX_INVALID_PDEV_ID); return QDF_STATUS_SUCCESS; } @@ -1334,12 +1485,6 @@ void *cds_get_context(QDF_MODULE_ID module_id) break; } - case QDF_MODULE_ID_TXRX: - { - context = (void *)gp_cds_context->pdev_txrx_ctx; - break; - } - case QDF_MODULE_ID_CFG: { context = gp_cds_context->cfg_ctx; @@ -1543,9 +1688,6 @@ QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context) case QDF_MODULE_ID_HDD: p_cds_context->hdd_context = context; break; - case QDF_MODULE_ID_TXRX: - p_cds_context->pdev_txrx_ctx = context; - break; case QDF_MODULE_ID_HIF: p_cds_context->hif_context = context; break; @@ -1593,10 +1735,6 @@ QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context) cds_mod_context = &gp_cds_context->hif_context; break; - case QDF_MODULE_ID_TXRX: - cds_mod_context = (void **)&gp_cds_context->pdev_txrx_ctx; - break; - case QDF_MODULE_ID_BMI: cds_mod_context = &gp_cds_context->g_ol_context; break; @@ -1627,62 +1765,6 @@ QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context) return QDF_STATUS_SUCCESS; } /* cds_free_context() */ -/** - * cds_get_vdev_types() - get vdev type - * @mode: mode - * @type: type - * @sub_type: sub_type - * - * Return: WMI vdev type - */ -QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint32_t *type, - uint32_t *sub_type) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - *type = 0; - *sub_type = 0; - - switch (mode) { - case QDF_STA_MODE: - *type = WMI_VDEV_TYPE_STA; - break; - case QDF_SAP_MODE: - *type = WMI_VDEV_TYPE_AP; - break; - case QDF_P2P_DEVICE_MODE: - *type = WMI_VDEV_TYPE_AP; - *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE; - break; - case QDF_P2P_CLIENT_MODE: - *type = WMI_VDEV_TYPE_STA; - *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT; - break; - case QDF_P2P_GO_MODE: - *type = WMI_VDEV_TYPE_AP; - *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO; - break; - case QDF_OCB_MODE: - *type = WMI_VDEV_TYPE_OCB; - break; - case QDF_IBSS_MODE: - *type = WMI_VDEV_TYPE_IBSS; - break; - case QDF_MONITOR_MODE: - *type = WMI_VDEV_TYPE_MONITOR; - break; - case QDF_NDI_MODE: - *type = WMI_VDEV_TYPE_NDI; - break; - case QDF_NAN_DISC_MODE: - *type = WMI_VDEV_TYPE_NAN; - break; - default: - cds_err("Invalid device mode %d", mode); - status = QDF_STATUS_E_INVAL; - break; - } - return status; -} /** * cds_flush_work() - flush pending works @@ -1816,7 +1898,6 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line) QDF_STATUS status; qdf_runtime_lock_t rtl; qdf_device_t qdf; - int ret = 0; /* NOTE! This code path is delicate! Think very carefully before * modifying the content or order of the following. Please review any @@ -1844,12 +1925,6 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line) return; } - if (!in_interrupt() && !irqs_disabled()) { - ret = pld_collect_rddm(qdf->dev); - if (ret < 0) - QDF_DEBUG_PANIC("Fail to collect FW ramdump %d", ret); - } - /* if *wlan* recovery is disabled, crash here for debugging */ if (!cds_is_self_recovery_enabled()) { QDF_DEBUG_PANIC("WLAN recovery is not enabled (via %s:%d)", @@ -1903,17 +1978,19 @@ void __cds_trigger_recovery(enum qdf_hang_reason reason, const char *func, gp_cds_context->recovery_reason = reason; - if (in_atomic()) { - __cds_recovery_caller.func = func; - __cds_recovery_caller.line = line; - qdf_queue_work(0, gp_cds_context->cds_recovery_wq, - &gp_cds_context->cds_recovery_work); - return; - } + __cds_recovery_caller.func = func; + __cds_recovery_caller.line = line; + qdf_queue_work(0, gp_cds_context->cds_recovery_wq, + &gp_cds_context->cds_recovery_work); +} - cds_trigger_recovery_handler(func, line); +void cds_trigger_recovery_psoc(void *psoc, enum qdf_hang_reason reason, + const char *func, const uint32_t line) +{ + __cds_trigger_recovery(reason, func, line); } + /** * cds_get_recovery_reason() - get self recovery reason * @reason: recovery reason @@ -2323,7 +2400,8 @@ uint32_t cds_get_log_indicator(void) */ void cds_wlan_flush_host_logs_for_fatal(void) { - wlan_flush_host_logs_for_fatal(); + if (cds_is_log_report_in_progress()) + wlan_flush_host_logs_for_fatal(); } /** @@ -2410,7 +2488,8 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal, */ void cds_logging_set_fw_flush_complete(void) { - wlan_logging_set_fw_flush_complete(); + if (cds_is_fatal_event_enabled()) + wlan_logging_set_fw_flush_complete(); } /** @@ -2747,7 +2826,9 @@ uint32_t cds_get_arp_stats_gw_ip(void *context) void cds_incr_arp_stats_tx_tgt_delivered(void) { struct hdd_context *hdd_ctx; - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_CDS_INCR_ARP_STATS_TX_TGT_DELIVERED; hdd_ctx = gp_cds_context->hdd_context; if (!hdd_ctx) { @@ -2755,9 +2836,15 @@ void cds_incr_arp_stats_tx_tgt_delivered(void) return; } - hdd_for_each_adapter(hdd_ctx, adapter) { - if (QDF_STA_MODE == adapter->device_mode) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->device_mode == QDF_STA_MODE) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, dbgid); break; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } if (adapter) @@ -2772,7 +2859,9 @@ void cds_incr_arp_stats_tx_tgt_delivered(void) void cds_incr_arp_stats_tx_tgt_acked(void) { struct hdd_context *hdd_ctx; - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_CDS_INCR_ARP_STATS_TX_TGT_ACKED; hdd_ctx = gp_cds_context->hdd_context; if (!hdd_ctx) { @@ -2780,9 +2869,15 @@ void cds_incr_arp_stats_tx_tgt_acked(void) return; } - hdd_for_each_adapter(hdd_ctx, adapter) { - if (QDF_STA_MODE == adapter->device_mode) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->device_mode == QDF_STA_MODE) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, dbgid); break; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } if (adapter) @@ -2800,17 +2895,12 @@ void cds_incr_arp_stats_tx_tgt_acked(void) static bool cds_get_cdp_vdev_stats(uint8_t vdev_id, struct cdp_vdev_stats *vdev_stats) { - void *soc; - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!vdev_stats) return false; - if (cds_get_datapath_handles(&soc, &pdev, &vdev, vdev_id)) - return false; - - if (cdp_host_get_vdev_stats(soc, vdev, vdev_stats, true)) + if (cdp_host_get_vdev_stats(soc, vdev_id, vdev_stats, true)) return false; return true; @@ -2956,7 +3046,6 @@ QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present) QDF_STATUS cds_smmu_mem_map_setup(qdf_device_t osdev, bool ipa_present) { osdev->smmu_s1_enabled = false; - osdev->iommu_mapping = NULL; return QDF_STATUS_SUCCESS; } #endif @@ -2966,3 +3055,31 @@ int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr) return 0; } #endif + +#ifdef WLAN_FEATURE_PKT_CAPTURE +bool cds_is_pktcapture_enabled(void) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = gp_cds_context->hdd_context; + if (!hdd_ctx) { + cds_err("HDD context is NULL"); + return false; + } + + return hdd_ctx->enable_pkt_capture_support; +} + +uint8_t cds_get_pktcapture_mode(void) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = gp_cds_context->hdd_context; + if (!hdd_ctx) { + cds_err("HDD context is NULL"); + return false; + } + + return hdd_ctx->val_pkt_capture_mode; +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_ieee80211_common_i.h b/drivers/staging/qcacld-3.0/core/cds/src/cds_ieee80211_common_i.h index c55accd6e3d5644d3a1874933159183da4ca0612..00e9ad1df5ee1dce4fea66ae909b6486b0a5db4c 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_ieee80211_common_i.h +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_ieee80211_common_i.h @@ -129,6 +129,8 @@ enum ieee80211_protmode { /* flagext */ #define IEEE80211_CHAN_DFS 0x0002 /* DFS required on channel */ +/* DFS required on channel for 2nd band of 80+80*/ +#define IEEE80211_CHAN_DFS_CFREQ2 0x0004 #define IEEE80211_SEQ_MASK 0xfff /* sequence generator mask */ #define MIN_SW_SEQ 0x100 /* minimum sequence for SW generate packect */ diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c index d583b047bd3fe0c1a173afae667b0a3c50b26185..b2f63ba0b9770c4b7ad01bb9b34e7498f6a054e1 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_sched.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -56,6 +56,17 @@ enum notifier_state { } notifier_state; static p_cds_sched_context gp_cds_sched_context; + +#ifdef WLAN_FEATURE_PKT_CAPTURE +static int cds_ol_mon_thread(void *arg); +static QDF_STATUS cds_alloc_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext); +static inline +int cds_set_mon_cpus_allowed_ptr(struct task_struct *task, unsigned long cpu) +{ + return set_cpus_allowed_ptr(task, cpumask_of(cpu)); +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #ifdef QCA_CONFIG_SMP static int cds_ol_rx_thread(void *arg); static uint32_t affine_cpu; @@ -507,6 +518,10 @@ QDF_STATUS cds_sched_open(void *p_cds_context, pSchedContext->high_throughput_required = false; pSchedContext->rx_affinity_required = false; #endif + + if (QDF_STATUS_SUCCESS != cds_alloc_mon_thread(pSchedContext)) + goto mon_freeqalloc_failure; + gp_cds_sched_context = pSchedContext; #ifdef QCA_CONFIG_SMP @@ -524,13 +539,29 @@ QDF_STATUS cds_sched_open(void *p_cds_context, wait_for_completion_interruptible(&pSchedContext->ol_rx_start_event); cds_debug("CDS OL Rx Thread has started"); #endif + + if (QDF_STATUS_SUCCESS != cds_open_mon_thread(pSchedContext)) + goto OL_MON_THREAD_START_FAILURE; + /* We're good now: Let's get the ball rolling!!! */ cds_debug("CDS Scheduler successfully Opened"); return QDF_STATUS_SUCCESS; +OL_MON_THREAD_START_FAILURE: +#ifdef QCA_CONFIG_SMP + /* Try and force the Main thread controller to exit */ + set_bit(RX_SHUTDOWN_EVENT, &pSchedContext->ol_rx_event_flag); + set_bit(RX_POST_EVENT, &pSchedContext->ol_rx_event_flag); + wake_up_interruptible(&pSchedContext->ol_rx_wait_queue); + /* Wait for RX Thread to exit */ + wait_for_completion(&pSchedContext->ol_rx_shutdown); +#endif + #ifdef QCA_CONFIG_SMP OL_RX_THREAD_START_FAILURE: #endif + cds_free_ol_mon_pkt_freeq(gp_cds_sched_context); +mon_freeqalloc_failure: #ifdef QCA_CONFIG_SMP qdf_cpuhp_unregister(&pSchedContext->cpuhp_event_handle); cds_free_ol_rx_pkt_freeq(gp_cds_sched_context); @@ -796,9 +827,7 @@ static int cds_ol_rx_thread(void *arg) set_user_nice(current, -1); #endif -#ifdef MSM_PLATFORM - set_wake_up_idle(true); -#endif + qdf_set_wake_up_idle(true); complete(&pSchedContext->ol_rx_start_event); @@ -888,6 +917,9 @@ QDF_STATUS cds_sched_close(void) } cds_close_rx_thread(); + + cds_close_mon_thread(); + gp_cds_sched_context = NULL; return QDF_STATUS_SUCCESS; } /* cds_sched_close() */ @@ -1041,3 +1073,462 @@ int cds_get_gfp_flags(void) return flags; } +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * cds_free_ol_mon_pkt_freeq() - free cds buffer free queue + * @pSchedContext - pointer to the global CDS Sched Context + * + * This API does mem free of the buffers available in free cds buffer + * queue which is used for mon Data processing. + * + * Return: none + */ +void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext) +{ + struct cds_ol_mon_pkt *pkt; + + if (!cds_is_pktcapture_enabled()) + return; + + spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + while (!list_empty(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq)) { + pkt = list_entry((&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq)->next, + typeof(*pkt), list); + list_del(&pkt->list); + spin_unlock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + qdf_mem_free(pkt); + spin_lock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + } + spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); +} + +/** + * cds_alloc_ol_mon_pkt_freeq() - Function to allocate free buffer queue + * @pSchedContext - pointer to the global CDS Sched Context + * + * This API allocates CDS_MAX_OL_MON_PKT number of cds message buffers + * which are used for mon data processing. + * + * Return: status of memory allocation + */ +static QDF_STATUS cds_alloc_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext) +{ + struct cds_ol_mon_pkt *pkt, *tmp; + int i; + + for (i = 0; i < CDS_MAX_OL_MON_PKT; i++) { + pkt = qdf_mem_malloc(sizeof(*pkt)); + if (!pkt) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s Vos packet allocation for ol mon thread failed", + __func__); + goto free; + } + spin_lock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + list_add_tail(&pkt->list, &pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq); + spin_unlock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + } + + return QDF_STATUS_SUCCESS; + +free: + spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + list_for_each_entry_safe(pkt, tmp, + &pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq, + list) { + list_del(&pkt->list); + spin_unlock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + qdf_mem_free(pkt); + spin_lock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + } + spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + return QDF_STATUS_E_NOMEM; +} + +/** + * cds_free_ol_mon_pkt() - api to release cds message to the freeq + * This api returns the cds message used for mon data to the free queue + * @pSchedContext: Pointer to the global CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue. + * + * Return: none + */ +void +cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt) +{ + memset(pkt, 0, sizeof(*pkt)); + spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + list_add_tail(&pkt->list, + &pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq); + spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); +} + +/** + * cds_alloc_ol_mon_pkt() - API to return next available cds message + * @pSchedContext: Pointer to the global CDS Sched Context + * + * This api returns next available cds message buffer used for mon data + * processing + * + * Return: Pointer to cds message buffer + */ +struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext) +{ + struct cds_ol_mon_pkt *pkt; + + spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + if (list_empty(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq)) { + spin_unlock_bh(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + return NULL; + } + pkt = list_first_entry(&pschedcontext-> + sched_mon_ctx.cds_ol_mon_pkt_freeq, + struct cds_ol_mon_pkt, list); + list_del(&pkt->list); + spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + return pkt; +} + +/** + * cds_indicate_monpkt() - indicate mon data packet + * @Arg: Pointer to the global CDS Sched Context + * @pkt: CDS data message buffer + * + * This api enqueues the mon packet into ol_mon_thread_queue and notifies + * cds_ol_mon_thread() + * + * Return: none + */ +void +cds_indicate_monpkt(p_cds_sched_context pschedcontext, + struct cds_ol_mon_pkt *pkt) +{ + spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + list_add_tail(&pkt->list, &pschedcontext-> + sched_mon_ctx.ol_mon_thread_queue); + spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + set_bit(RX_POST_EVENT, &pschedcontext->sched_mon_ctx.ol_mon_event_flag); + wake_up_interruptible(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue); +} + +/** + * cds_wakeup_mon_thread() - wakeup mon thread + * @Arg: Pointer to the global CDS Sched Context + * + * This api wake up cds_ol_mon_thread() to process pkt + * + * Return: none + */ +void +cds_wakeup_mon_thread(p_cds_sched_context pschedcontext) +{ + set_bit(RX_POST_EVENT, &pschedcontext->sched_mon_ctx.ol_mon_event_flag); + wake_up_interruptible(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue); +} + +/** + * cds_close_mon_thread() - close the Tlshim Rx thread + * + * This api closes the Tlshim Rx thread: + * + * Return: qdf status + */ +QDF_STATUS cds_close_mon_thread(void) +{ + if (!cds_is_pktcapture_enabled()) + return QDF_STATUS_SUCCESS; + + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH, + "%s: invoked", __func__); + + if (!gp_cds_sched_context) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: gp_cds_sched_context == NULL", __func__); + return QDF_STATUS_E_FAILURE; + } + + if (!gp_cds_sched_context->sched_mon_ctx.ol_mon_thread) + return QDF_STATUS_SUCCESS; + + /* Shut down Tlshim Rx thread */ + set_bit(RX_SHUTDOWN_EVENT, + &gp_cds_sched_context->sched_mon_ctx.ol_mon_event_flag); + set_bit(RX_POST_EVENT, + &gp_cds_sched_context->sched_mon_ctx.ol_mon_event_flag); + wake_up_interruptible(&gp_cds_sched_context-> + sched_mon_ctx.ol_mon_wait_queue); + wait_for_completion(&gp_cds_sched_context-> + sched_mon_ctx.ol_mon_shutdown); + gp_cds_sched_context->sched_mon_ctx.ol_mon_thread = NULL; + cds_drop_monpkt(gp_cds_sched_context); + cds_free_ol_mon_pkt_freeq(gp_cds_sched_context); + + return QDF_STATUS_SUCCESS; +} /* cds_close_mon_thread */ + +/** + * cds_open_mon_thread() - open the Tlshim Rx thread + * + * This api open the Tlshim Rx thread: + * + * Return: qdf status + */ +QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext) +{ + if (!cds_is_pktcapture_enabled()) + return QDF_STATUS_SUCCESS; + + pschedcontext->sched_mon_ctx.ol_mon_thread = kthread_create( + cds_ol_mon_thread, + pschedcontext, + "cds_ol_mon_thread"); + if (IS_ERR(pschedcontext->sched_mon_ctx.ol_mon_thread)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, + "%s: Could not Create CDS OL MON Thread", + __func__); + return QDF_STATUS_E_FAILURE; + } + wake_up_process(pschedcontext->sched_mon_ctx.ol_mon_thread); + cds_debug("CDS OL MON thread Created"); + + wait_for_completion_interruptible( + &pschedcontext->sched_mon_ctx.ol_mon_start_event); + cds_debug("CDS OL MON Thread has started"); + + return QDF_STATUS_SUCCESS; +} + +/** + * cds_drop_monpkt() - api to drop pending mon packets for a sta + * @pschedcontext: Pointer to the global CDS Sched Context + * + * This api drops all queued packets for a station. + * + * Return: none + */ +void cds_drop_monpkt(p_cds_sched_context pschedcontext) +{ + struct list_head local_list; + struct cds_ol_mon_pkt *pkt, *tmp; + qdf_nbuf_t buf, next_buf; + + INIT_LIST_HEAD(&local_list); + spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + if (list_empty(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue)) { + spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + return; + } + list_for_each_entry_safe(pkt, tmp, + &pschedcontext-> + sched_mon_ctx.ol_mon_thread_queue, + list) + list_move_tail(&pkt->list, &local_list); + + spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + + list_for_each_entry_safe(pkt, tmp, &local_list, list) { + list_del(&pkt->list); + buf = pkt->monpkt; + while (buf) { + next_buf = qdf_nbuf_queue_next(buf); + qdf_nbuf_free(buf); + buf = next_buf; + } + cds_free_ol_mon_pkt(pschedcontext, pkt); + } +} + +/** + * cds_mon_from_queue() - function to process pending mon packets + * @pschedcontext: Pointer to the global CDS Sched Context + * + * This api traverses the pending buffer list and calling the callback. + * This callback would essentially send the packet to HDD. + * + * Return: none + */ +static void cds_mon_from_queue(p_cds_sched_context pschedcontext) +{ + struct cds_ol_mon_pkt *pkt; + uint8_t vdev_id; + uint8_t tid; + + spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + while (!list_empty(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue)) { + pkt = list_first_entry(&pschedcontext-> + sched_mon_ctx.ol_mon_thread_queue, + struct cds_ol_mon_pkt, list); + list_del(&pkt->list); + spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + vdev_id = pkt->vdev_id; + tid = pkt->tid; + pkt->callback(pkt->context, pkt->monpkt, vdev_id, + tid, pkt->status, pkt->pkt_format); + cds_free_ol_mon_pkt(pschedcontext, pkt); + spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + } + spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); +} + +/** + * cds_ol_mon_thread() - cds main tlshim mon thread + * @Arg: pointer to the global CDS Sched Context + * + * This api is the thread handler for mon Data packet processing. + * + * Return: thread exit code + */ +static int cds_ol_mon_thread(void *arg) +{ + p_cds_sched_context pschedcontext = (p_cds_sched_context)arg; + unsigned long pref_cpu = 0; + bool shutdown = false; + int status, i; + + if (!arg) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + + set_user_nice(current, -1); +#ifdef MSM_PLATFORM + set_wake_up_idle(true); +#endif + + /** + * Find the available cpu core other than cpu 0 and + * bind the thread + */ + for_each_online_cpu(i) { + if (i == 0) + continue; + pref_cpu = i; + break; + } + + cds_set_mon_cpus_allowed_ptr(current, pref_cpu); + + complete(&pschedcontext->sched_mon_ctx.ol_mon_start_event); + + while (!shutdown) { + status = + wait_event_interruptible( + pschedcontext->sched_mon_ctx.ol_mon_wait_queue, + test_bit(RX_POST_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag) || + test_bit(RX_SUSPEND_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag)); + if (status == -ERESTARTSYS) + break; + + clear_bit(RX_POST_EVENT, + &pschedcontext->sched_mon_ctx.ol_mon_event_flag); + while (true) { + if (test_bit(RX_SHUTDOWN_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag)) { + clear_bit(RX_SHUTDOWN_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag); + if (test_bit( + RX_SUSPEND_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag)) { + clear_bit( + RX_SUSPEND_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag); + complete + (&pschedcontext-> + sched_mon_ctx.ol_suspend_mon_event); + } + QDF_TRACE(QDF_MODULE_ID_QDF, + QDF_TRACE_LEVEL_INFO, + "%s: Shutting down OL MON Thread", + __func__); + shutdown = true; + break; + } + cds_mon_from_queue(pschedcontext); + + if (test_bit(RX_SUSPEND_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag)) { + clear_bit(RX_SUSPEND_EVENT, + &pschedcontext-> + sched_mon_ctx.ol_mon_event_flag); + spin_lock(&pschedcontext-> + sched_mon_ctx.ol_mon_thread_lock); + INIT_COMPLETION + (pschedcontext-> + sched_mon_ctx.ol_resume_mon_event); + complete(&pschedcontext-> + sched_mon_ctx.ol_suspend_mon_event); + spin_unlock(&pschedcontext-> + sched_mon_ctx.ol_mon_thread_lock); + wait_for_completion_interruptible + (&pschedcontext-> + sched_mon_ctx.ol_resume_mon_event); + } + break; + } + } + + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, + "%s: Exiting CDS OL mon thread", __func__); + complete_and_exit(&pschedcontext->sched_mon_ctx.ol_mon_shutdown, 0); + + return 0; +} + +void cds_resume_mon_thread(void) +{ + p_cds_sched_context cds_sched_context; + + cds_sched_context = get_cds_sched_ctxt(); + if (!cds_sched_context) { + cds_err("cds_sched_context is NULL"); + return; + } + + complete(&cds_sched_context->sched_mon_ctx.ol_resume_mon_event); +} + +QDF_STATUS +cds_alloc_mon_thread(p_cds_sched_context pschedcontext) +{ + if (!cds_is_pktcapture_enabled()) + return QDF_STATUS_SUCCESS; + + spin_lock_init(&pschedcontext->sched_mon_ctx.ol_mon_thread_lock); + init_waitqueue_head(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue); + init_completion(&pschedcontext->sched_mon_ctx.ol_mon_start_event); + init_completion(&pschedcontext->sched_mon_ctx.ol_suspend_mon_event); + init_completion(&pschedcontext->sched_mon_ctx.ol_resume_mon_event); + init_completion(&pschedcontext->sched_mon_ctx.ol_mon_shutdown); + pschedcontext->sched_mon_ctx.ol_mon_event_flag = 0; + spin_lock_init(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock); + spin_lock_init(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + INIT_LIST_HEAD(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue); + spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + INIT_LIST_HEAD(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq); + spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock); + + return cds_alloc_ol_mon_pkt_freeq(pschedcontext); +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ diff --git a/drivers/staging/qcacld-3.0/core/cds/src/i_cds_packet.h b/drivers/staging/qcacld-3.0/core/cds/src/i_cds_packet.h index 947bcd6fef0f2a9312713afb594e1d3411a94e23..4bd19d1f553756d7a09f373c13660827a460bfea 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/i_cds_packet.h +++ b/drivers/staging/qcacld-3.0/core/cds/src/i_cds_packet.h @@ -37,7 +37,7 @@ * Rx Packet Struct * Buffer for the packet received from WMA has pointers to 802.11 * frame fields and additional information based on the type of frame. - * @channel: Channel number + * @frequency: Frequency * @snr: Signal to noise ratio * @rssi: Received signal strength indicator, normalized to -96 dBm as * normal noise floor by adding -96 to snr. All the configured @@ -57,7 +57,7 @@ * @rssi_raw: rssi based on actual noise floor in hardware. */ typedef struct { - uint8_t channel; + uint32_t frequency; uint8_t snr; uint32_t rssi; uint32_t timestamp; diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt.c index 65b1da1c47f28ae7f306441f5ba577a07c19684e..14e0174e679ce2aa61ef83ab169372e2f5589e19 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt.c @@ -38,6 +38,7 @@ #include #include "hif.h" #include +#include #define HTT_HTC_PKT_POOL_INIT_SIZE 100 /* enough for a large A-MPDU */ @@ -570,6 +571,13 @@ htt_attach(struct htt_pdev_t *pdev, int desc_pool_size) ol_tx_target_credit_update( pdev->txrx_pdev, ol_cfg_target_tx_credit( pdev->ctrl_pdev)); + DPTRACE(qdf_dp_trace_credit_record(QDF_HTT_ATTACH, + QDF_CREDIT_INC, + ol_cfg_target_tx_credit(pdev->ctrl_pdev), + qdf_atomic_read(&pdev->txrx_pdev->target_tx_credit), + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[0].credit), + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[1].credit))); + } else { enum wlan_frm_fmt frm_type; @@ -794,6 +802,8 @@ int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id) connect.EpCallbacks.EpTxCompleteMultiple = NULL; connect.EpCallbacks.EpRecv = htt_t2h_msg_handler; connect.EpCallbacks.ep_resume_tx_queue = htt_tx_resume_handler; + connect.EpCallbacks.ep_padding_credit_update = + htt_tx_padding_credit_update_handler; /* rx buffers currently are provided by HIF, not by EpRecvRefill */ connect.EpCallbacks.EpRecvRefill = NULL; diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_fw_stats.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_fw_stats.c index dfee683cb1510e87ab687163f99f8a5648323d70..2fdd9f3a67b55ae38dfcc108fa923bbeb41573f2 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_fw_stats.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_fw_stats.c @@ -310,7 +310,9 @@ htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats *wlan_pdev_stats, /* Num MPDUs requed by SW */ qdf_nofl_info("mpdus_requed :%d", tx->mpdus_requed); /* Excessive retries */ - qdf_nofl_info("excess retries :%d", tx->tx_ko); +#if defined(AR900B) + qdf_nofl_info("excess retries :%d", tx->tx_xretry); +#endif /* last data rate */ qdf_nofl_info("last rc :%d", tx->data_rc); /* scheduler self triggers */ @@ -327,6 +329,18 @@ htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats *wlan_pdev_stats, qdf_nofl_info("pdev resets :%d", tx->pdev_resets); /* PPDU > txop duration */ qdf_nofl_info("ppdu txop ovf :%d", tx->txop_ovf); +#if defined(AR900B) + qdf_nofl_info("seq_posted :%d", tx->seq_posted); + qdf_nofl_info("seq_failed_queueing :%d", tx->seq_failed_queueing); + qdf_nofl_info("seq_completed :%d", tx->seq_completed); + qdf_nofl_info("seq_restarted :%d", tx->seq_restarted); + qdf_nofl_info("mu_seq_posted :%d", tx->mu_seq_posted); + qdf_nofl_info("mpdus_sw_flush :%d", tx->mpdus_sw_flush); + qdf_nofl_info("mpdus_hw_filter :%d", tx->mpdus_hw_filter); + qdf_nofl_info("mpdus_truncated :%d", tx->mpdus_truncated); + qdf_nofl_info("mpdus_ack_failed :%d", tx->mpdus_ack_failed); + qdf_nofl_info("mpdus_expired :%d", tx->mpdus_expired); +#endif qdf_nofl_info("### Rx ###"); /* Cnts any change in ring routing mid-ppdu */ @@ -352,6 +366,9 @@ htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats *wlan_pdev_stats, qdf_nofl_info("phy_errs dropped :%d", rx->phy_err_drop); /* Number of mpdu errors - FCS, MIC, ENC etc. */ qdf_nofl_info("mpdu_errs :%d", rx->mpdu_errs); +#if defined(AR900B) + qdf_nofl_info("rx_ovfl_errs :%d", rx->rx_ovfl_errs); +#endif } diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_h2t.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_h2t.c index fecb7722e6d071afe21c6771e7f3a7d72eabc720..a2a4051dc88edd28ee2a92fc2b10fdbef5735e67 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_h2t.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_h2t.c @@ -305,9 +305,7 @@ QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); HTT_SEND_HTC_PKT(pdev, pkt); - if ((pdev->cfg.is_high_latency) && - (!pdev->cfg.default_tx_comp_req)) - ol_tx_target_credit_update(pdev->txrx_pdev, -1); + ol_tx_deduct_one_credit(pdev->txrx_pdev); return QDF_STATUS_SUCCESS; } @@ -762,9 +760,7 @@ htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev) htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt); #endif - if ((pdev->cfg.is_high_latency) && - (!pdev->cfg.default_tx_comp_req)) - ol_tx_target_credit_update(pdev->txrx_pdev, -1); + ol_tx_deduct_one_credit(pdev->txrx_pdev); return QDF_STATUS_SUCCESS; } @@ -877,9 +873,7 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev, htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt); #endif - if ((pdev->cfg.is_high_latency) && - (!pdev->cfg.default_tx_comp_req)) - ol_tx_target_credit_update(pdev->txrx_pdev, -1); + ol_tx_deduct_one_credit(pdev->txrx_pdev); return 0; } @@ -931,9 +925,7 @@ A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, uint8_t sync_cnt) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); HTT_SEND_HTC_PKT(pdev, pkt); - if ((pdev->cfg.is_high_latency) && - (!pdev->cfg.default_tx_comp_req)) - ol_tx_target_credit_update(pdev->txrx_pdev, -1); + ol_tx_deduct_one_credit(pdev->txrx_pdev); return A_OK; } @@ -1006,9 +998,7 @@ htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev, htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt); #endif - if ((pdev->cfg.is_high_latency) && - (!pdev->cfg.default_tx_comp_req)) - ol_tx_target_credit_update(pdev->txrx_pdev, -1); + ol_tx_deduct_one_credit(pdev->txrx_pdev); return 0; } diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_internal.h b/drivers/staging/qcacld-3.0/core/dp/htt/htt_internal.h index 1a82bcbd4389a4c92bfad5523430239d13e19c7c..17bd2cbc9c6dfe6c39b93c91446f3d6cb638fc25 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_internal.h +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -582,6 +582,8 @@ void htt_h2t_send_complete(void *context, HTC_PACKET *pkt); QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev); +int htt_tx_padding_credit_update_handler(void *context, int pad_credit); + #if defined(HELIUMPLUS) QDF_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev); @@ -1117,19 +1119,6 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *replenish_cnt); - -/** - * htt_rx_mon_get_rx_status() - Update information about the rx status, - * which is used later for radiotap updation. - * @pdev: Pointer to pdev handle - * @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); #else static inline int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, @@ -1140,13 +1129,6 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, { return 0; } - -static inline -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) -{ -} #endif #endif /* _HTT_INTERNAL__H_ */ diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_monitor_rx.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_monitor_rx.c index 6f59e26b9de03f8c203f51ab8af1ebebbe7e1894..7fafa7e48a9a7cd8396f077aea639c2c04e4ccc8 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_monitor_rx.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_monitor_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -422,6 +422,8 @@ static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc, rx_status->ldpc = ldpc; rx_status->beamformed = beamformed; rx_status->vht_flag_values3[0] = mcs << 0x4 | (nss + 1); + if (ht_flags) + rx_status->ht_mcs = mcs; rx_status->ht_flags = ht_flags; rx_status->vht_flags = vht_flags; rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0); @@ -458,10 +460,19 @@ static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc) return rtap_flags; } -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) +/** + * 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 + */ +static 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); @@ -469,12 +480,13 @@ void htt_rx_mon_get_rx_status(htt_pdev_handle pdev, 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); - if (rx_desc->ppdu_start.l_sig_rate_select) - rx_status->cck_flag = 1; - else - rx_status->ofdm_flag = 1; - + rx_status->chan_flags = channel_flags; rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb; rx_status->rssi_comb = rx_desc->ppdu_start.rssi_comb; rx_status->chan_noise_floor = pdev->txrx_pdev->chan_noise_floor; @@ -719,7 +731,8 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, #endif /* CONFIG_HL_SUPPORT */ #if defined(FEATURE_MONITOR_MODE_SUPPORT) -#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF) +#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF) && \ + !defined(QCA6490_HEADERS_DEF) && !defined(QCA6750_HEADERS_DEF) static void htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base *rx_desc, struct ieee80211_rx_status *rs) diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_hl.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_hl.c index d20d99002ceffa75eb14f00c574a2a4b7fb1c263..fbd80bf1c2c025354629a8642306d788a87385ad 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_hl.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_hl.c @@ -330,7 +330,7 @@ htt_rx_frag_pop_hl( *head_msdu = *tail_msdu = frag_msg; qdf_nbuf_set_next(*tail_msdu, NULL); - return 0; + return 1; } static inline int diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_ll.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_ll.c index 348092802f650692c883b2860b011308308e42df..210c3ef766a01b861b0803d689a681990875ae57 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_ll.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_rx_ll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -107,6 +107,22 @@ htt_get_first_packet_after_wow_wakeup(uint32_t *msg_word, qdf_nbuf_t buf) } } +/** + * htt_rx_ring_smmu_mapped() - check if rx ring is smmu mapped or not + * @pdev: HTT pdev handle + * + * Return: true or false. + */ +static inline bool htt_rx_ring_smmu_mapped(htt_pdev_handle pdev) +{ + if (qdf_mem_smmu_s1_enabled(pdev->osdev) && + pdev->is_ipa_uc_enabled && + pdev->rx_ring.smmu_map) + return true; + else + return false; +} + static inline qdf_nbuf_t htt_rx_netbuf_pop(htt_pdev_handle pdev) { int idx; @@ -375,14 +391,9 @@ static int htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) int filled = 0; int debt_served = 0; qdf_mem_info_t mem_map_table = {0}; - bool ipa_smmu = false; idx = *pdev->rx_ring.alloc_idx.vaddr; - if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled && - pdev->rx_ring.smmu_map) - ipa_smmu = true; - if ((idx < 0) || (idx > pdev->rx_ring.size_mask) || (num > pdev->rx_ring.size)) { QDF_TRACE(QDF_MODULE_ID_HTT, @@ -476,10 +487,12 @@ static int htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) pdev->rx_ring.buf.netbufs_ring[idx] = rx_netbuf; } - if (ipa_smmu) { + /* Caller already protected this function with refill_lock */ + if (qdf_nbuf_is_rx_ipa_smmu_map(rx_netbuf)) { qdf_update_mem_map_table(pdev->osdev, &mem_map_table, paddr, HTT_RX_BUF_SIZE); - cds_smmu_map_unmap(true, 1, &mem_map_table); + qdf_assert_always( + !cds_smmu_map_unmap(true, 1, &mem_map_table)); } pdev->rx_ring.buf.paddrs_ring[idx] = paddr_marked; @@ -1141,6 +1154,15 @@ htt_rx_hash_list_insert(struct htt_pdev_t *pdev, RX_HASH_LOG(qdf_print("rx hash: paddr 0x%x netbuf %pK bucket %d\n", paddr, netbuf, (int)i)); + if (htt_rx_ring_smmu_mapped(pdev)) { + if (qdf_unlikely(qdf_nbuf_is_rx_ipa_smmu_map(netbuf))) { + qdf_err("Already smmu mapped, nbuf: %pK", + netbuf); + qdf_assert_always(0); + } + qdf_nbuf_set_rx_ipa_smmu_map(netbuf, true); + } + HTT_RX_HASH_COUNT_INCR(pdev->rx_ring.hash_table[i]); HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]); @@ -1203,6 +1225,13 @@ qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, } } + if (netbuf && htt_rx_ring_smmu_mapped(pdev)) { + if (qdf_unlikely(!qdf_nbuf_is_rx_ipa_smmu_map(netbuf))) { + qdf_err("smmu not mapped nbuf: %pK", netbuf); + qdf_assert_always(0); + } + } + RX_HASH_LOG(qdf_print("rx hash: paddr 0x%llx, netbuf %pK, bucket %d\n", (unsigned long long)paddr, netbuf, (int)i)); HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]); @@ -1310,11 +1339,8 @@ static void htt_rx_hash_deinit(struct htt_pdev_t *pdev) if (!pdev->rx_ring.hash_table) return; - if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled && - pdev->rx_ring.smmu_map) - ipa_smmu = true; - qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock); + ipa_smmu = htt_rx_ring_smmu_mapped(pdev); hash_table = pdev->rx_ring.hash_table; pdev->rx_ring.hash_table = NULL; qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock); @@ -1329,14 +1355,26 @@ static void htt_rx_hash_deinit(struct htt_pdev_t *pdev) listnode_offset); if (hash_entry->netbuf) { if (ipa_smmu) { + if (qdf_unlikely( + !qdf_nbuf_is_rx_ipa_smmu_map( + hash_entry->netbuf))) { + qdf_err("nbuf: %pK NOT mapped", + hash_entry->netbuf); + qdf_assert_always(0); + } + qdf_nbuf_set_rx_ipa_smmu_map( + hash_entry->netbuf, + false); qdf_update_mem_map_table(pdev->osdev, &mem_map_table, QDF_NBUF_CB_PADDR( hash_entry->netbuf), HTT_RX_BUF_SIZE); - cds_smmu_map_unmap(false, 1, - &mem_map_table); + qdf_assert_always( + !cds_smmu_map_unmap( + false, 1, + &mem_map_table)); } #ifdef DEBUG_DMA_DONE qdf_nbuf_unmap(pdev->osdev, hash_entry->netbuf, @@ -1396,6 +1434,40 @@ int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num) return filled; } +#if defined(WLAN_FEATURE_TSF_PLUS) && !defined(CONFIG_HL_SUPPORT) +/** + * htt_rx_tail_msdu_timestamp() - update tail msdu tsf64 timestamp + * @tail_rx_desc: pointer to tail msdu descriptor + * @timestamp_rx_desc: pointer to timestamp msdu descriptor + * + * Return: none + */ +static inline void htt_rx_tail_msdu_timestamp( + struct htt_host_rx_desc_base *tail_rx_desc, + struct htt_host_rx_desc_base *timestamp_rx_desc) +{ + if (tail_rx_desc) { + if (!timestamp_rx_desc) { + tail_rx_desc->ppdu_end.wb_timestamp_lower_32 = 0; + tail_rx_desc->ppdu_end.wb_timestamp_upper_32 = 0; + } else { + if (timestamp_rx_desc != tail_rx_desc) { + tail_rx_desc->ppdu_end.wb_timestamp_lower_32 = + timestamp_rx_desc->ppdu_end.wb_timestamp_lower_32; + tail_rx_desc->ppdu_end.wb_timestamp_upper_32 = + timestamp_rx_desc->ppdu_end.wb_timestamp_upper_32; + } + } + } +} +#else +static inline void htt_rx_tail_msdu_timestamp( + struct htt_host_rx_desc_base *tail_rx_desc, + struct htt_host_rx_desc_base *timestamp_rx_desc) +{ +} +#endif + static int htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg, @@ -1409,12 +1481,12 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, unsigned int msdu_count = 0; uint8_t offload_ind, frag_ind; uint8_t peer_id; - struct htt_host_rx_desc_base *rx_desc; + struct htt_host_rx_desc_base *rx_desc = NULL; enum rx_pkt_fate status = RX_PKT_FATE_SUCCESS; qdf_dma_addr_t paddr; qdf_mem_info_t mem_map_table = {0}; int ret = 1; - bool ipa_smmu = false; + struct htt_host_rx_desc_base *timestamp_rx_desc = NULL; HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); @@ -1431,10 +1503,6 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); HTT_RX_CHECK_MSDU_COUNT(msdu_count); - if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled && - pdev->rx_ring.smmu_map) - ipa_smmu = true; - ol_rx_update_histogram_stats(msdu_count, frag_ind, offload_ind); htt_rx_dbg_rxbuf_httrxind(pdev, msdu_count); @@ -1460,11 +1528,24 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, } while (msdu_count > 0) { - if (ipa_smmu) { + if (qdf_nbuf_is_rx_ipa_smmu_map(msdu)) { + /* + * nbuf was already detached from hash_entry, + * there is no parallel IPA context to access + * this nbuf for smmu map/unmap, so updating + * this flag here without lock. + * + * This flag was not updated in netbuf_pop context + * htt_rx_hash_list_lookup (where lock held), to + * differentiate whether this nbuf to be + * smmu unmapped or it was never mapped so far. + */ + qdf_nbuf_set_rx_ipa_smmu_map(msdu, false); qdf_update_mem_map_table(pdev->osdev, &mem_map_table, QDF_NBUF_CB_PADDR(msdu), HTT_RX_BUF_SIZE); - cds_smmu_map_unmap(false, 1, &mem_map_table); + qdf_assert_always( + !cds_smmu_map_unmap(false, 1, &mem_map_table)); } /* @@ -1523,6 +1604,10 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, rx_desc = htt_rx_desc(msdu); htt_rx_extract_lro_info(msdu, rx_desc); + /* check if the msdu is last mpdu */ + if (rx_desc->attention.last_mpdu) + timestamp_rx_desc = rx_desc; + /* * Make the netbuf's data pointer point to the payload rather * than the descriptor. @@ -1640,6 +1725,8 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, } } + htt_rx_tail_msdu_timestamp(rx_desc, timestamp_rx_desc); + end: return ret; } @@ -2176,14 +2263,13 @@ int htt_rx_attach(struct htt_pdev_t *pdev) void htt_rx_detach(struct htt_pdev_t *pdev) { bool ipa_smmu = false; + qdf_nbuf_t nbuf; qdf_timer_stop(&pdev->rx_ring.refill_retry_timer); qdf_timer_free(&pdev->rx_ring.refill_retry_timer); htt_rx_dbg_rxbuf_deinit(pdev); - if (qdf_mem_smmu_s1_enabled(pdev->osdev) && pdev->is_ipa_uc_enabled && - pdev->rx_ring.smmu_map) - ipa_smmu = true; + ipa_smmu = htt_rx_ring_smmu_mapped(pdev); if (pdev->cfg.is_full_reorder_offload) { qdf_mem_free_consistent(pdev->osdev, pdev->osdev->dev, @@ -2200,29 +2286,31 @@ void htt_rx_detach(struct htt_pdev_t *pdev) qdf_mem_info_t mem_map_table = {0}; while (sw_rd_idx != *pdev->rx_ring.alloc_idx.vaddr) { + nbuf = pdev->rx_ring.buf.netbufs_ring[sw_rd_idx]; if (ipa_smmu) { + if (qdf_unlikely( + !qdf_nbuf_is_rx_ipa_smmu_map(nbuf))) { + qdf_err("smmu not mapped, nbuf: %pK", + nbuf); + qdf_assert_always(0); + } + qdf_nbuf_set_rx_ipa_smmu_map(nbuf, false); qdf_update_mem_map_table(pdev->osdev, &mem_map_table, - QDF_NBUF_CB_PADDR( - pdev->rx_ring.buf. - netbufs_ring[sw_rd_idx]), + QDF_NBUF_CB_PADDR(nbuf), HTT_RX_BUF_SIZE); - cds_smmu_map_unmap(false, 1, - &mem_map_table); + qdf_assert_always( + !cds_smmu_map_unmap(false, 1, + &mem_map_table)); } #ifdef DEBUG_DMA_DONE - qdf_nbuf_unmap(pdev->osdev, - pdev->rx_ring.buf. - netbufs_ring[sw_rd_idx], + qdf_nbuf_unmap(pdev->osdev, nbuf, QDF_DMA_BIDIRECTIONAL); #else - qdf_nbuf_unmap(pdev->osdev, - pdev->rx_ring.buf. - netbufs_ring[sw_rd_idx], + qdf_nbuf_unmap(pdev->osdev, nbuf, QDF_DMA_FROM_DEVICE); #endif - qdf_nbuf_free(pdev->rx_ring.buf. - netbufs_ring[sw_rd_idx]); + qdf_nbuf_free(nbuf); sw_rd_idx++; sw_rd_idx &= pdev->rx_ring.size_mask; } @@ -2257,6 +2345,7 @@ static QDF_STATUS htt_rx_hash_smmu_map(bool map, struct htt_pdev_t *pdev) struct htt_rx_hash_bucket **hash_table; struct htt_list_node *list_iter = NULL; qdf_mem_info_t mem_map_table = {0}; + qdf_nbuf_t nbuf; int ret; qdf_spin_lock_bh(&pdev->rx_ring.rx_hash_lock); @@ -2270,15 +2359,27 @@ static QDF_STATUS htt_rx_hash_smmu_map(bool map, struct htt_pdev_t *pdev) (struct htt_rx_hash_entry *)((char *)list_iter - pdev->rx_ring. listnode_offset); - if (hash_entry->netbuf) { + nbuf = hash_entry->netbuf; + if (nbuf) { + if (qdf_unlikely(map == + qdf_nbuf_is_rx_ipa_smmu_map(nbuf))) { + qdf_err("map/unmap err:%d, nbuf:%pK", + map, nbuf); + list_iter = list_iter->next; + continue; + } + qdf_nbuf_set_rx_ipa_smmu_map(nbuf, map); qdf_update_mem_map_table(pdev->osdev, &mem_map_table, - QDF_NBUF_CB_PADDR( - hash_entry->netbuf), + QDF_NBUF_CB_PADDR(nbuf), HTT_RX_BUF_SIZE); ret = cds_smmu_map_unmap(map, 1, &mem_map_table); if (ret) { + qdf_nbuf_set_rx_ipa_smmu_map(nbuf, + !map); + qdf_err("map: %d failure, nbuf: %pK", + map, nbuf); qdf_spin_unlock_bh( &pdev->rx_ring.rx_hash_lock); return QDF_STATUS_E_FAILURE; @@ -2288,6 +2389,7 @@ static QDF_STATUS htt_rx_hash_smmu_map(bool map, struct htt_pdev_t *pdev) } } + pdev->rx_ring.smmu_map = map; qdf_spin_unlock_bh(&pdev->rx_ring.rx_hash_lock); return QDF_STATUS_SUCCESS; @@ -2304,7 +2406,6 @@ QDF_STATUS htt_rx_update_smmu_map(struct htt_pdev_t *pdev, bool map) return QDF_STATUS_SUCCESS; qdf_spin_lock_bh(&pdev->rx_ring.refill_lock); - pdev->rx_ring.smmu_map = map; status = htt_rx_hash_smmu_map(map, pdev); qdf_spin_unlock_bh(&pdev->rx_ring.refill_lock); diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_t2h.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_t2h.c index 53796cc7d2d08c1c1cf424c16829567353be9a37..b792a85eb5956f6b8bf60b9e4922a4e13edec227 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_t2h.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_t2h.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -31,6 +31,7 @@ #include /* HTT_T2H_MSG_TYPE, etc. */ #include /* qdf_nbuf_t */ +#include #include #include #include /* htt_tx_status */ @@ -43,8 +44,6 @@ #include #include "pktlog_ac.h" #include -#include -#include /*--- target->host HTT message dispatch function ----------------------------*/ #ifndef DEBUG_CREDIT @@ -178,8 +177,7 @@ static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word) sizeof(struct htt_wdi_ipa_op_response_t) + len); cdp_ipa_op_response(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_pdev *)pdev->txrx_pdev, - op_msg_buffer); + OL_TXRX_PDEV_ID, op_msg_buffer); } #else static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word) @@ -350,12 +348,33 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, } case HTT_T2H_MSG_TYPE_RX_ADDBA: { - qdf_print("HTT_T2H_MSG_TYPE_RX_ADDBA not supported "); + uint16_t peer_id; + uint8_t tid; + uint8_t win_sz; + uint16_t start_seq_num; + + /* + * FOR NOW, the host doesn't need to know the initial + * sequence number for rx aggregation. + * Thus, any value will do - specify 0. + */ + start_seq_num = 0; + peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word); + tid = HTT_RX_ADDBA_TID_GET(*msg_word); + win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word); + ol_rx_addba_handler(pdev->txrx_pdev, peer_id, tid, + win_sz, start_seq_num, + 0 /* success */); break; } case HTT_T2H_MSG_TYPE_RX_DELBA: { - qdf_print("HTT_T2H_MSG_TYPE_RX_DELBA not supported "); + uint16_t peer_id; + uint8_t tid; + + peer_id = HTT_RX_DELBA_PEER_ID_GET(*msg_word); + tid = HTT_RX_DELBA_TID_GET(*msg_word); + ol_rx_delba_handler(pdev->txrx_pdev, peer_id, tid); break; } case HTT_T2H_MSG_TYPE_PEER_MAP: @@ -465,6 +484,11 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, pdev->txrx_pdev, compl_msg->desc_id, 1, 0, compl_msg->status); + DPTRACE(qdf_dp_trace_credit_record(QDF_TX_COMP, QDF_CREDIT_INC, + 1, qdf_atomic_read(&pdev->txrx_pdev->target_tx_credit), + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[0].credit), + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[1].credit))); + if (!ol_tx_get_is_mgmt_over_wmi_enabled()) { ol_tx_single_completion_handler(pdev->txrx_pdev, compl_msg->status, @@ -502,7 +526,8 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, } /*len is reduced by sizeof(*msg_word)*/ - pktlog_process_fw_msg(msg_word + 1, len - sizeof(*msg_word)); + pktlog_process_fw_msg(OL_TXRX_PDEV_ID, msg_word + 1, + len - sizeof(*msg_word)); break; } #endif @@ -534,6 +559,13 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, htt_credit_delta = htt_t2h_adjust_bus_target_delta(pdev, htt_credit_delta); htt_tx_group_credit_process(pdev, msg_word); + DPTRACE(qdf_dp_trace_credit_record(QDF_TX_CREDIT_UPDATE, + QDF_CREDIT_INC, htt_credit_delta, + qdf_atomic_read(&pdev->txrx_pdev->target_tx_credit) + + htt_credit_delta, + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[0].credit), + qdf_atomic_read(&pdev->txrx_pdev->txq_grps[1].credit))); + ol_tx_credit_completion_handler(pdev->txrx_pdev, htt_credit_delta); break; @@ -630,9 +662,10 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, switch (HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word)) { case HTT_RX_OFLD_PKT_ERR_TYPE_MIC_ERR: { - struct ol_error_info err_info; struct ol_txrx_vdev_t *vdev; struct ol_txrx_peer_t *peer; + uint64_t pn; + uint32_t key_id; uint16_t peer_id; int msg_len = qdf_nbuf_len(htt_t2h_msg); @@ -653,22 +686,14 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, break; } vdev = peer->vdev; - err_info.u.mic_err.vdev_id = vdev->vdev_id; - err_info.u.mic_err.key_id = - HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET + key_id = HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET (*(msg_word + 1)); - qdf_mem_copy(err_info.u.mic_err.da, - (uint8_t *)(msg_word + 2), - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(err_info.u.mic_err.sa, - (uint8_t *)(msg_word + 4), - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(&err_info.u.mic_err.pn, - (uint8_t *)(msg_word + 6), 6); - qdf_mem_copy(err_info.u.mic_err.ta, - peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); - - wma_indicate_err(OL_RX_ERR_TKIP_MIC, &err_info); + qdf_mem_copy(&pn, (uint8_t *)(msg_word + 6), 6); + + ol_rx_send_mic_err_ind(vdev->pdev, vdev->vdev_id, + peer->mac_addr.raw, 0, 0, + OL_RX_ERR_TKIP_MIC, htt_t2h_msg, + &pn, key_id); break; } default: @@ -1215,71 +1240,6 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus, break; } - case HTT_T2H_MSG_TYPE_TX_OFFLOAD_DELIVER_IND: - { - struct htt_tx_offload_deliver_ind_hdr_t - *offload_deliver_msg; - uint8_t vdev_id; - struct ol_txrx_vdev_t *vdev; - bool is_pkt_during_roam = false; - struct ol_txrx_pdev_t *txrx_pdev = pdev->txrx_pdev; - struct ol_txrx_peer_t *peer; - uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint32_t freq = 0; - - if (!(ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_DATA_ONLY)) - break; - - offload_deliver_msg = - (struct htt_tx_offload_deliver_ind_hdr_t *)msg_word; - is_pkt_during_roam = - (offload_deliver_msg->reserved_2 ? true : false); - - if (qdf_unlikely( - !pdev->cfg.is_full_reorder_offload)) { - break; - } - - /* Is FW sends offload data during roaming */ - if (is_pkt_during_roam) { - vdev_id = HTT_INVALID_VDEV; - freq = - (uint32_t)offload_deliver_msg->reserved_3; - htt_rx_mon_note_capture_channel( - pdev, cds_freq_to_chan(freq)); - } else { - vdev_id = offload_deliver_msg->vdev_id; - vdev = (struct ol_txrx_vdev_t *) - ol_txrx_get_vdev_from_vdev_id(vdev_id); - - if (vdev) { - qdf_spin_lock_bh( - &txrx_pdev->peer_ref_mutex); - peer = TAILQ_FIRST(&vdev->peer_list); - qdf_spin_unlock_bh( - &txrx_pdev->peer_ref_mutex); - if (peer) { - qdf_spin_lock_bh( - &peer->peer_info_lock); - qdf_mem_copy( - bssid, - &peer->mac_addr.raw, - QDF_MAC_ADDR_SIZE); - qdf_spin_unlock_bh( - &peer->peer_info_lock); - } else { - break; - } - } else { - break; - } - } - ucfg_pkt_capture_offload_deliver_indication_handler( - msg_word, - vdev_id, bssid, pdev); - break; - } case HTT_T2H_MSG_TYPE_RX_PN_IND: { u_int16_t peer_id; diff --git a/drivers/staging/qcacld-3.0/core/dp/htt/htt_tx.c b/drivers/staging/qcacld-3.0/core/dp/htt/htt_tx.c index dbba3e0cc89e6dee0894d161ea050490b1be9cc3..bd6667f0cec66aaab0de6fa8af38e717cabf4fe7 100644 --- a/drivers/staging/qcacld-3.0/core/dp/htt/htt_tx.c +++ b/drivers/staging/qcacld-3.0/core/dp/htt/htt_tx.c @@ -70,14 +70,18 @@ #endif /* QCA_WIFI_3_0 */ #if HTT_PADDR64 -#define HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(frag_filed_ptr) \ +#define HTT_TX_DESC_FRAG_FIELD_UPDATE(frag_filed_ptr, frag_desc_addr) \ do { \ + *frag_filed_ptr = qdf_get_lower_32_bits(frag_desc_addr); \ frag_filed_ptr++; \ /* frags_desc_ptr.hi */ \ - *frag_filed_ptr = 0; \ + *frag_filed_ptr = qdf_get_upper_32_bits(frag_desc_addr) & 0x1F; \ } while (0) #else -#define HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(frag_filed_ptr) {} +#define HTT_TX_DESC_FRAG_FIELD_UPDATE(frag_filed_ptr, frag_desc_addr) \ +do { \ + *frag_filed_ptr = qdf_get_lower_32_bits(frag_desc_addr); \ +} while (0) #endif /*--- setup / tear-down functions -------------------------------------------*/ @@ -134,13 +138,14 @@ static void htt_tx_frag_desc_field_update(struct htt_pdev_t *pdev, unsigned int target_page; unsigned int offset; struct qdf_mem_dma_page_t *dma_page; + qdf_dma_addr_t frag_desc_addr; target_page = index / pdev->frag_descs.desc_pages.num_element_per_page; offset = index % pdev->frag_descs.desc_pages.num_element_per_page; dma_page = &pdev->frag_descs.desc_pages.dma_pages[target_page]; - *fptr = (uint32_t)(dma_page->page_p_addr + + frag_desc_addr = (dma_page->page_p_addr + offset * pdev->frag_descs.size); - HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(fptr); + HTT_TX_DESC_FRAG_FIELD_UPDATE(fptr, frag_desc_addr); } /** @@ -865,8 +870,43 @@ htt_tx_send_nonstd(htt_pdev_handle pdev, return htt_tx_send_std(pdev, msdu, msdu_id); } +#ifndef QCA_TX_PADDING_CREDIT_SUPPORT +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + return 1; +} +#endif + #else /*ATH_11AC_TXCOMPACT */ +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT +static int htt_tx_padding_credit_update(htt_pdev_handle htt_pdev, + int pad_credit) +{ + int ret = 0; + + if (pad_credit) + qdf_atomic_add(pad_credit, + &htt_pdev->txrx_pdev->pad_reserve_tx_credit); + + ret = qdf_atomic_read(&htt_pdev->txrx_pdev->pad_reserve_tx_credit); + + return ret; +} + +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + struct htt_pdev_t *htt_pdev = (struct htt_pdev_t *)context; + + return htt_tx_padding_credit_update(htt_pdev, pad_credit); +} +#else +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + return 1; +} +#endif + #ifdef QCA_TX_HTT2_SUPPORT static inline HTC_ENDPOINT_ID htt_tx_htt2_get_ep_id(htt_pdev_handle pdev, qdf_nbuf_t msdu) diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_cfg.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_cfg.h index 6a79b4d26ed6704f9b06a6fac545d2dd242eae58..751e5458902a78e8773d9ea3f764d5abab7c1a71 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_cfg.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_cfg.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,18 +44,12 @@ enum wlan_frm_fmt { }; /* Max throughput */ -#ifdef QCS403_MEM_OPTIMIZE +#ifdef SLUB_MEM_OPTIMIZE #define MAX_THROUGHPUT 400 #else #define MAX_THROUGHPUT 800 #endif -#ifdef QCA_LL_TX_FLOW_CONTROL_V2 -#define TARGET_TX_CREDIT CFG_TGT_NUM_MSDU_DESC -#else -#define TARGET_TX_CREDIT 900 -#endif - /* Throttle period Different level Duty Cycle values*/ #define THROTTLE_DUTY_CYCLE_LEVEL0 (0) #define THROTTLE_DUTY_CYCLE_LEVEL1 (50) @@ -96,10 +91,15 @@ struct txrx_pdev_cfg_t { #endif struct wlan_ipa_uc_rsc_t ipa_uc_rsc; bool ip_tcp_udp_checksum_offload; + bool p2p_ip_tcp_udp_checksum_offload; + /* IP, TCP and UDP checksum offload for NAN Mode*/ + bool nan_tcp_udp_checksumoffload; bool enable_rxthread; bool ce_classify_enabled; +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) uint32_t tx_flow_stop_queue_th; uint32_t tx_flow_start_queue_offset; +#endif bool flow_steering_enabled; /* * To track if credit reporting through @@ -110,8 +110,11 @@ struct txrx_pdev_cfg_t { u8 credit_update_enabled; struct ol_tx_sched_wrr_ac_specs_t ac_specs[QCA_WLAN_AC_ALL]; bool gro_enable; + bool tc_based_dyn_gro; + uint32_t tc_ingress_prio; bool tso_enable; bool lro_enable; + bool sg_enable; bool enable_data_stall_detection; bool enable_flow_steering; bool disable_intra_bss_fwd; @@ -123,6 +126,20 @@ struct txrx_pdev_cfg_t { uint32_t uc_tx_partition_base; /* Flag to indicate whether new htt format is supported */ bool new_htt_format_enabled; + +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + /* enable the tcp delay ack feature in the driver */ + bool del_ack_enable; + /* timeout if no more tcp ack frames, unit is ms */ + uint16_t del_ack_timer_value; + /* the maximum number of replaced tcp ack frames */ + uint16_t del_ack_pkt_count; +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + uint16_t bundle_timer_value; + uint16_t bundle_size; +#endif uint8_t pktlog_buffer_size; }; @@ -133,8 +150,16 @@ struct txrx_pdev_cfg_t { * * Return: none */ +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_ctx, struct txrx_pdev_cfg_param_t *cfg_param); +#else +static inline +void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param) +{ +} +#endif /** * ol_pdev_cfg_attach - setup configuration parameters @@ -487,9 +512,11 @@ int ol_cfg_is_ip_tcp_udp_checksum_offload_enabled(struct cdp_cfg *cfg_pdev) } +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) int ol_cfg_get_tx_flow_stop_queue_th(struct cdp_cfg *cfg_pdev); int ol_cfg_get_tx_flow_start_queue_offset(struct cdp_cfg *cfg_pdev); +#endif bool ol_cfg_is_ce_classify_enabled(struct cdp_cfg *cfg_pdev); @@ -716,6 +743,60 @@ ol_cfg_is_htt_new_format_enabled(struct cdp_cfg *cfg_pdev) return cfg->new_htt_format_enabled; } +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +/** + * ol_cfg_get_del_ack_timer_value() - get delayed ack timer value + * @cfg_pdev: pdev handle + * + * Return: timer value + */ +int ol_cfg_get_del_ack_timer_value(struct cdp_cfg *cfg_pdev); + +/** + * ol_cfg_get_del_ack_enable_value() - get delayed ack enable value + * @cfg_pdev: pdev handle + * + * Return: enable/disable + */ +bool ol_cfg_get_del_ack_enable_value(struct cdp_cfg *cfg_pdev); + +/** + * ol_cfg_get_del_ack_count_value() - get delayed ack count value + * @cfg_pdev: pdev handle + * + * Return: count value + */ +int ol_cfg_get_del_ack_count_value(struct cdp_cfg *cfg_pdev); + +/** + * ol_cfg_update_del_ack_params() - update delayed ack params + * @cfg_ctx: cfg context + * @cfg_param: parameters + * + * Return: none + */ +void ol_cfg_update_del_ack_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param); +#else +/** + * ol_cfg_update_del_ack_params() - update delayed ack params + * @cfg_ctx: cfg context + * @cfg_param: parameters + * + * Return: none + */ +static inline +void ol_cfg_update_del_ack_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param) +{ +} +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +int ol_cfg_get_bundle_timer_value(struct cdp_cfg *cfg_pdev); +int ol_cfg_get_bundle_size(struct cdp_cfg *cfg_pdev); +#else +#endif /** * ol_cfg_get_wrr_skip_weight() - brief Query for the param of wrr_skip_weight * @pdev: handle to the physical device. diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_defines.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_defines.h index d873b128d268d96eea156b8ab0d3d20af837277b..c89a6e2d0b88097efb2731a75550020d2b9ac120 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_defines.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016, 2018-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,6 +22,8 @@ #ifndef _DEV_OL_DEFINES_H #define _DEV_OL_DEFINES_H +#define OL_TXRX_PDEV_ID 0 + #define NORMALIZED_TO_NOISE_FLOOR (-96) /** diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h index 3554b3467d956c60b7e9049318bf73111b34fc28..4f39903ae354baf26f1043aee47b06dafc954209 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -919,7 +919,8 @@ int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num) * @return network buffer handle to the MPDU */ #if defined(FEATURE_MONITOR_MODE_SUPPORT) -#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF) +#if !defined(QCA6290_HEADERS_DEF) && !defined(QCA6390_HEADERS_DEF) && \ + !defined(QCA6490_HEADERS_DEF) && !defined(QCA6750_HEADERS_DEF) qdf_nbuf_t htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev, qdf_nbuf_t head_msdu, diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_ctrl_api.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_ctrl_api.h index 858d770b8abd7e65f563469cc9850d4b09e98ff5..e829076b6f4bbb7be01267224815b81265d31bb7 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_ctrl_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_ctrl_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -54,11 +54,12 @@ * to the target has to be done in the separate pdev_attach_target call * that is invoked after HTC setup is complete. * - * @param pdev - txrx_pdev handle + * @param soc - datapath soc handle + * @param pdev_id - physical device instance id * @return 0 for success or error code */ int -ol_txrx_pdev_post_attach(struct cdp_pdev *pdev); +ol_txrx_pdev_post_attach(struct cdp_soc_t *soc, uint8_t pdev_id); /** * @brief Parameter type to be input to ol_txrx_peer_update @@ -280,14 +281,15 @@ void ol_txrx_tx_sync(ol_txrx_pdev_handle data_pdev, uint8_t sync_cnt); * when transmission completes. Rather, these specially-marked frames * are provided to the callback registered with this function. * - * @param data_vdev - which vdev the callback is being registered with + * @param soc - datapath soc handle + * @param vdev_id - id of which vdev the callback is being registered with * (Currently the callback is stored in the pdev rather than the vdev.) * @param callback - the function to call when tx frames marked as "no free" * are done being transmitted * @param ctxt - the context argument provided to the callback function */ void -ol_txrx_data_tx_cb_set(struct cdp_vdev *data_vdev, +ol_txrx_data_tx_cb_set(struct cdp_soc_t *soc, uint8_t vdev_id, ol_txrx_data_tx_cb callback, void *ctxt); /** @@ -301,32 +303,6 @@ ol_txrx_data_tx_cb_set(struct cdp_vdev *data_vdev, */ void ol_txrx_discard_tx_pending(ol_txrx_pdev_handle pdev); -/** - * @brief set the safemode of the device - * @details - * This flag is used to bypass the encrypt and decrypt processes when send and - * receive packets. It works like open AUTH mode, HW will treate all packets - * as non-encrypt frames because no key installed. For rx fragmented frames, - * it bypasses all the rx defragmentaion. - * - * @param vdev - the data virtual device object - * @param val - the safemode state - * @return - void - */ -void ol_txrx_set_safemode(ol_txrx_vdev_handle vdev, uint32_t val); - -/** - * @brief configure the drop unencrypted frame flag - * @details - * Rx related. When set this flag, all the unencrypted frames - * received over a secure connection will be discarded - * - * @param vdev - the data virtual device object - * @param val - flag - * @return - void - */ -void ol_txrx_set_drop_unenc(ol_txrx_vdev_handle vdev, uint32_t val); - void ol_txrx_peer_keyinstalled_state_update(ol_txrx_peer_handle data_peer, uint8_t val); @@ -432,27 +408,37 @@ int16_t ol_txrx_peer_rssi(ol_txrx_peer_handle peer); #if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) /** - * @brief Configure the bad peer tx limit setting. - * @details + * ol_txrx_bad_peer_txctl_set_setting() - Configure the bad peer tx + * limit setting. + * @soc_hdl: soc handle + * @pdev_id: datapath pdev identifier + * @enable: enable/disable setting + * @period: balance period in ms + * @txq_limit: balance txq limit * * @param pdev - the physics device */ void ol_txrx_bad_peer_txctl_set_setting( - struct cdp_pdev *pdev, + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, int enable, int period, int txq_limit); /** - * @brief Configure the bad peer tx threshold limit - * @details + * ol_txrx_bad_peer_txctl_update_threshold() - Configure the bad peer tx + * threshold limit + * @soc_hdl: soc handle + * @pdev_id: datapath pdev identifier + * @level: txctl level + * @tput_thresh throughput threshold + * @tx_limit: balance tx limit * * @param pdev - the physics device */ void ol_txrx_bad_peer_txctl_update_threshold( - struct cdp_pdev *pdev, + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, int level, int tput_thresh, int tx_limit); @@ -461,7 +447,7 @@ ol_txrx_bad_peer_txctl_update_threshold( static inline void ol_txrx_bad_peer_txctl_set_setting( - struct cdp_pdev *pdev, + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, int enable, int period, int txq_limit) @@ -470,7 +456,7 @@ ol_txrx_bad_peer_txctl_set_setting( static inline void ol_txrx_bad_peer_txctl_update_threshold( - struct cdp_pdev *pdev, + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, int level, int tput_thresh, int tx_limit) @@ -510,7 +496,8 @@ static inline void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id, void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev); void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev); -void ol_tx_dump_flow_pool_info(void *); +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl); +void ol_tx_dump_flow_pool_info_compact(struct ol_txrx_pdev_t *pdev); void ol_tx_clear_flow_pool_stats(void); void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, uint8_t flow_pool_id, uint16_t flow_pool_size); @@ -545,6 +532,7 @@ QDF_STATUS ol_tx_inc_pool_ref(struct ol_tx_flow_pool_t *pool); * Return: QDF_STATUS_SUCCESS - in case of success */ QDF_STATUS ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force); + #else static inline void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) @@ -553,9 +541,21 @@ static inline void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) static inline void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) { } -static inline void ol_tx_dump_flow_pool_info(void *ctx) + +#if defined(CONFIG_HL_SUPPORT) && defined(QCA_HL_NETDEV_FLOW_CONTROL) +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl); +void ol_tx_dump_flow_pool_info_compact(struct ol_txrx_pdev_t *pdev); +#else +static inline void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { } + +static inline +void ol_tx_dump_flow_pool_info_compact(struct ol_txrx_pdev_t *pdev) +{ +} +#endif + static inline void ol_tx_clear_flow_pool_stats(void) { } diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_htt_api.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_htt_api.h index 8c342dd058ae546765a82b0990e577c1da626569..c37651fee28cab54827998e6d720de429ee179b2 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_htt_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_htt_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,12 +36,27 @@ static inline uint16_t *ol_tx_msdu_id_storage(qdf_nbuf_t msdu) return (uint16_t *) (&QDF_NBUF_CB_TX_DESC_ID(msdu)); } + +/** + * @brief Deduct one credit from target_tx and one from any of the groups + * @details + * Deduct one credit from target_tx credit and one credit from any of the + * groups, whichever has more number of credits. + * + * @param pdev - the data physical device + */ +int ol_tx_deduct_one_credit(struct ol_txrx_pdev_t *pdev); #else static inline uint16_t *ol_tx_msdu_id_storage(qdf_nbuf_t msdu) { qdf_assert(qdf_nbuf_headroom(msdu) >= (sizeof(uint16_t) * 2 - 1)); return (uint16_t *) (((qdf_size_t) (qdf_nbuf_head(msdu) + 1)) & ~0x1); } + +static inline int ol_tx_deduct_one_credit(struct ol_txrx_pdev_t *pdev) +{ + return 0; +} #endif /** * @brief Tx MSDU download completion for a LL system @@ -117,6 +132,9 @@ enum htt_tx_status { /* no_ack - sent, but no ack */ htt_tx_status_no_ack = HTT_TX_COMPL_IND_STAT_NO_ACK, + /* drop may due to tx descriptor not enough*/ + htt_tx_status_drop = HTT_TX_COMPL_IND_STAT_DROP, + /* download_fail - host could not deliver the tx frame to target */ htt_tx_status_download_fail = HTT_HOST_ONLY_STATUS_CODE_START, }; @@ -233,6 +251,8 @@ ol_tx_desc_update_group_credit( u_int16_t tx_desc_id, int credit, u_int8_t absolute, enum htt_tx_status status); +void ol_tx_deduct_one_any_group_credit(ol_txrx_pdev_handle pdev); + #ifdef DEBUG_HL_LOGGING /** @@ -284,6 +304,9 @@ ol_tx_desc_update_group_credit( int credit, u_int8_t absolute, enum htt_tx_status status) { } + +static inline void ol_tx_deduct_one_any_group_credit(ol_txrx_pdev_handle pdev) +{} #endif /** @@ -503,6 +526,47 @@ ol_rx_sec_ind_handler(ol_txrx_pdev_handle pdev, enum htt_sec_type sec_type, int is_unicast, uint32_t *michael_key, uint32_t *rx_pn); +/** + * @brief Process an ADDBA message sent by the target. + * @details + * When the target notifies the host of an ADDBA event for a specified + * peer-TID, the host will set up the rx reordering state for the peer-TID. + * Specifically, the host will create a rx reordering array whose length + * is based on the window size specified in the ADDBA. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer the ADDBA event is for + * @param tid - which traffic ID within the peer the ADDBA event is for + * @param win_sz - how many sequence numbers are in the ARQ block ack window + * set up by the ADDBA event + * @param start_seq_num - the initial value of the sequence number during the + * block ack agreement, as specified by the ADDBA request. + * @param failed - indicate whether the target's ADDBA setup succeeded: + * 0 -> success, 1 -> fail + */ +void +ol_rx_addba_handler(ol_txrx_pdev_handle pdev, + uint16_t peer_id, + uint8_t tid, + uint8_t win_sz, uint16_t start_seq_num, uint8_t failed); + +/** + * @brief Process a DELBA message sent by the target. + * @details + * When the target notifies the host of a DELBA event for a specified + * peer-TID, the host will clean up the rx reordering state for the peer-TID. + * Specifically, the host will remove the rx reordering array, and will + * set the reorder window size to be 1 (stop and go ARQ). + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer the ADDBA event is for + * @param tid - which traffic ID within the peer the ADDBA event is for + */ +void +ol_rx_delba_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id, uint8_t tid); + enum htt_rx_flush_action { htt_rx_flush_release, htt_rx_flush_discard, diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_osif_api.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_osif_api.h index 203f27743e9ca1603f9a30a337f901257e43ae8e..a880d46a29bf6461883a0c15155cf9f7459058db 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_osif_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_osif_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -69,7 +69,7 @@ qdf_nbuf_t ol_txrx_osif_tso_segment(ol_txrx_vdev_handle txrx_vdev, int max_seg_payload_bytes, qdf_nbuf_t jumbo_tcp_frame); -qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb); +qdf_nbuf_t ol_tx_data(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t skb); void ol_rx_data_process(struct ol_txrx_peer_t *peer, qdf_nbuf_t rx_buf_list); diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_stats.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_stats.h index 4c2a073e02099ca9691f2206d0b9453c6c35cc25..8d966a51a90de5dd85fccef0aff0f3edf141d5d8 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_stats.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_txrx_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2014-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -78,6 +78,12 @@ struct ol_txrx_stats_tx_dropped { */ struct ol_txrx_stats_elem no_ack; + /* + * MSDUs which the target drop + * (lack of tx descriptor) + */ + struct ol_txrx_stats_elem target_drop; + /* MSDU which were dropped for other reasons */ struct ol_txrx_stats_elem others; }; diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_cfg.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_cfg.c index 2b58a429c04ac250aaba92514859319d7921cf98..111105298955eef212f3fbbf6d21005c0867934f 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_cfg.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_cfg.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +24,7 @@ unsigned int vow_config; +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /** * ol_tx_set_flow_control_parameters() - set flow control parameters * @cfg_ctx: cfg context @@ -40,6 +42,7 @@ void ol_tx_set_flow_control_parameters(struct cdp_cfg *cfg_pdev, cfg_ctx->tx_flow_stop_queue_th = cfg_param->tx_flow_stop_queue_th; } +#endif #ifdef CONFIG_HL_SUPPORT @@ -117,6 +120,39 @@ uint8_t ol_defrag_timeout_check(void) } #endif +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +/** + * ol_cfg_update_del_ack_params() - update delayed ack params + * @cfg_ctx: cfg context + * @cfg_param: parameters + * + * Return: none + */ +void ol_cfg_update_del_ack_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param) +{ + cfg_ctx->del_ack_enable = cfg_param->del_ack_enable; + cfg_ctx->del_ack_timer_value = cfg_param->del_ack_timer_value; + cfg_ctx->del_ack_pkt_count = cfg_param->del_ack_pkt_count; +} +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +static inline +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param) +{ + cfg_ctx->bundle_timer_value = cfg_param->bundle_timer_value; + cfg_ctx->bundle_size = cfg_param->bundle_size; +} +#else +static inline +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t *cfg_param) +{ +} +#endif + /* FIX THIS - * For now, all these configuration parameters are hardcoded. * Many of these should actually be determined dynamically instead. @@ -143,7 +179,7 @@ struct cdp_cfg *ol_pdev_cfg_attach(qdf_device_t osdev, void *pcfg_param) cfg_ctx->max_thruput_mbps = MAX_THROUGHPUT; cfg_ctx->max_nbuf_frags = 1; cfg_ctx->vow_config = vow_config; - cfg_ctx->target_tx_credit = TARGET_TX_CREDIT; + cfg_ctx->target_tx_credit = CFG_TGT_NUM_MSDU_DESC; cfg_ctx->throttle_period_ms = 40; cfg_ctx->dutycycle_level[0] = THROTTLE_DUTY_CYCLE_LEVEL0; cfg_ctx->dutycycle_level[1] = THROTTLE_DUTY_CYCLE_LEVEL1; @@ -165,16 +201,27 @@ struct cdp_cfg *ol_pdev_cfg_attach(qdf_device_t osdev, void *pcfg_param) cfg_ctx->enable_rxthread = cfg_param->enable_rxthread; cfg_ctx->ip_tcp_udp_checksum_offload = cfg_param->ip_tcp_udp_checksum_offload; + cfg_ctx->p2p_ip_tcp_udp_checksum_offload = + cfg_param->p2p_ip_tcp_udp_checksum_offload; + cfg_ctx->nan_tcp_udp_checksumoffload = + cfg_param->nan_ip_tcp_udp_checksum_offload; cfg_ctx->ce_classify_enabled = cfg_param->ce_classify_enabled; cfg_ctx->gro_enable = cfg_param->gro_enable; + cfg_ctx->tc_based_dyn_gro = cfg_param->tc_based_dyn_gro; + cfg_ctx->tc_ingress_prio = cfg_param->tc_ingress_prio; cfg_ctx->tso_enable = cfg_param->tso_enable; cfg_ctx->lro_enable = cfg_param->lro_enable; + cfg_ctx->sg_enable = cfg_param->sg_enable; cfg_ctx->enable_data_stall_detection = cfg_param->enable_data_stall_detection; cfg_ctx->enable_flow_steering = cfg_param->enable_flow_steering; cfg_ctx->disable_intra_bss_fwd = cfg_param->disable_intra_bss_fwd; cfg_ctx->pktlog_buffer_size = cfg_param->pktlog_buffer_size; + ol_cfg_update_del_ack_params(cfg_ctx, cfg_param); + + ol_cfg_update_bundle_params(cfg_ctx, cfg_param); + ol_tx_set_flow_control_parameters((struct cdp_cfg *)cfg_ctx, cfg_param); for (i = 0; i < QCA_WLAN_AC_ALL; i++) { @@ -193,6 +240,64 @@ struct cdp_cfg *ol_pdev_cfg_attach(qdf_device_t osdev, void *pcfg_param) return (struct cdp_cfg *)cfg_ctx; } +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + +int ol_cfg_get_bundle_timer_value(struct cdp_cfg *cfg_pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; + + return cfg->bundle_timer_value; +} + +int ol_cfg_get_bundle_size(struct cdp_cfg *cfg_pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; + + return cfg->bundle_size; +} +#endif + +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +/** + * ol_cfg_get_del_ack_timer_value() - get delayed ack timer value + * @cfg_pdev: pdev handle + * + * Return: timer value + */ +int ol_cfg_get_del_ack_timer_value(struct cdp_cfg *cfg_pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; + + return cfg->del_ack_timer_value; +} + +/** + * ol_cfg_get_del_ack_enable_value() - get delayed ack enable value + * @cfg_pdev: pdev handle + * + * Return: enable/disable + */ +bool ol_cfg_get_del_ack_enable_value(struct cdp_cfg *cfg_pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; + + return cfg->del_ack_enable; +} + +/** + * ol_cfg_get_del_ack_count_value() - get delayed ack count value + * @pdev: cfg_pdev handle + * + * Return: count value + */ +int ol_cfg_get_del_ack_count_value(struct cdp_cfg *cfg_pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; + + return cfg->del_ack_pkt_count; +} +#endif + int ol_cfg_is_high_latency(struct cdp_cfg *cfg_pdev) { struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)cfg_pdev; @@ -408,6 +513,7 @@ int ol_cfg_is_rx_thread_enabled(struct cdp_cfg *cfg_pdev) return cfg->enable_rxthread; } +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /** * ol_cfg_get_tx_flow_stop_queue_th() - return stop queue threshold * @pdev : handle to the physical device @@ -433,7 +539,7 @@ int ol_cfg_get_tx_flow_start_queue_offset(struct cdp_cfg *cfg_pdev) return cfg->tx_flow_start_queue_offset; } - +#endif #ifdef IPA_OFFLOAD unsigned int ol_cfg_ipa_uc_offload_enabled(struct cdp_cfg *cfg_pdev) diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.c index 6edb0af92f31e5d8bb1e12954079637091ff1942..c31121ed74745c8542c704c6308399593a7f4022 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,6 +33,7 @@ #include /* OL_RX_REORDER_TIMEOUT_UPDATE */ #include /* ol_rx_defrag_waitlist_flush */ #include +#include #include #ifdef QCA_SUPPORT_SW_TXRX_ENCAP #include /* ol_rx_decap_info_t, etc */ @@ -55,7 +56,6 @@ #include #include #include -#include #ifndef OL_RX_INDICATION_MAX_RECORDS #define OL_RX_INDICATION_MAX_RECORDS 2048 @@ -153,7 +153,7 @@ void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev, else data.mac_id = 0; - wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, (struct cdp_pdev *)pdev, + wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev->id, &data); } #else @@ -176,7 +176,7 @@ void ol_rx_send_pktlog_event(struct ol_txrx_pdev_t *pdev, else data.mac_id = 0; - wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, (struct cdp_pdev *)pdev, + wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev->id, &data); } #endif @@ -229,8 +229,15 @@ void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, qdf_nbuf_t head_msdu, void ol_rx_update_histogram_stats(uint32_t msdu_count, uint8_t frag_ind, uint8_t offload_ind) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return; @@ -301,7 +308,7 @@ static void ol_rx_process_inv_peer(ol_txrx_pdev_handle pdev, msg.wh = wh; msg.msdu = msdu; msg.vdev_id = vdev->vdev_id; - wdi_event_handler(WDI_EVENT_RX_PEER_INVALID, (struct cdp_pdev *)pdev, + wdi_event_handler(WDI_EVENT_RX_PEER_INVALID, pdev->id, &msg); } #else @@ -724,13 +731,14 @@ ol_rx_indication_handler(ol_txrx_pdev_handle pdev, pdev->htt_pdev, msdu), &key_id) == true) { - ol_rx_err(pdev->ctrl_pdev, - vdev->vdev_id, - peer->mac_addr.raw, - tid, 0, - OL_RX_ERR_TKIP_MIC, - msdu, &pn.pn48, - key_id); + ol_rx_send_mic_err_ind( + vdev->pdev, + vdev->vdev_id, + peer->mac_addr.raw, + tid, 0, + OL_RX_ERR_TKIP_MIC, + msdu, &pn.pn48, + key_id); } } @@ -800,9 +808,9 @@ ol_rx_sec_ind_handler(ol_txrx_pdev_handle pdev, return; } ol_txrx_dbg( - "sec spec for peer %pK ("QDF_MAC_ADDR_STR"): %s key of type %d\n", + "sec spec for peer %pK ("QDF_MAC_ADDR_FMT"): %s key of type %d\n", peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(peer->mac_addr.raw), is_unicast ? "ucast" : "mcast", sec_type); sec_index = is_unicast ? txrx_sec_ucast : txrx_sec_mcast; peer->security[sec_index].sec_type = sec_type; @@ -946,6 +954,43 @@ ol_rx_offload_deliver_ind_handler(ol_txrx_pdev_handle pdev, htt_rx_msdu_buff_replenish(htt_pdev); } +void +ol_rx_send_mic_err_ind(struct ol_txrx_pdev_t *pdev, uint8_t vdev_id, + uint8_t *peer_mac_addr, int tid, uint32_t tsf32, + enum ol_rx_err_type err_type, qdf_nbuf_t rx_frame, + uint64_t *pn, uint8_t key_id) +{ + struct cdp_rx_mic_err_info mic_failure_info; + qdf_ether_header_t *eth_hdr; + struct ol_if_ops *tops = NULL; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_soc_handle ol_txrx_soc = &soc->cdp_soc; + + if (err_type != OL_RX_ERR_TKIP_MIC) + return; + + if (qdf_nbuf_len(rx_frame) < sizeof(*eth_hdr)) + return; + + eth_hdr = (qdf_ether_header_t *)qdf_nbuf_data(rx_frame); + + qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.ta_mac_addr, + (struct qdf_mac_addr *)peer_mac_addr); + qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.da_mac_addr, + (struct qdf_mac_addr *)eth_hdr->ether_dhost); + mic_failure_info.key_id = key_id; + mic_failure_info.multicast = + IEEE80211_IS_MULTICAST(eth_hdr->ether_dhost); + qdf_mem_copy(mic_failure_info.tsc, pn, SIR_CIPHER_SEQ_CTR_SIZE); + mic_failure_info.frame_type = cdp_rx_frame_type_802_3; + mic_failure_info.data = NULL; + mic_failure_info.vdev_id = vdev_id; + + tops = ol_txrx_soc->ol_ops; + if (tops->rx_mic_error) + tops->rx_mic_error(soc->psoc, pdev->id, &mic_failure_info); +} + void ol_rx_mic_error_handler( ol_txrx_pdev_handle pdev, @@ -972,11 +1017,11 @@ ol_rx_mic_error_handler( if (htt_rx_msdu_desc_key_id( vdev->pdev->htt_pdev, msdu_desc, &key_id) == true) { - ol_rx_err(vdev->pdev->ctrl_pdev, - vdev->vdev_id, - peer->mac_addr.raw, tid, 0, - OL_RX_ERR_TKIP_MIC, msdu, - &pn.pn48, key_id); + ol_rx_send_mic_err_ind(vdev->pdev, + vdev->vdev_id, + peer->mac_addr.raw, tid, 0, + OL_RX_ERR_TKIP_MIC, msdu, + &pn.pn48, key_id); } } } @@ -1137,6 +1182,21 @@ void ol_rx_timestamp(struct cdp_cfg *cfg_pdev, msdu->tstamp = ns_to_ktime((u_int64_t)rx_ppdu_desc->tsf32 * NSEC_PER_USEC); } + +static inline void ol_rx_timestamp_update(ol_txrx_pdev_handle pdev, + qdf_nbuf_t head_msdu, + qdf_nbuf_t tail_msdu) +{ + qdf_nbuf_t loop_msdu; + struct htt_host_rx_desc_base *rx_desc; + + loop_msdu = head_msdu; + while (loop_msdu) { + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, loop_msdu); + ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, loop_msdu); + loop_msdu = qdf_nbuf_next(loop_msdu); + } +} #else void ol_rx_timestamp(struct cdp_cfg *cfg_pdev, void *rx_desc, qdf_nbuf_t msdu) @@ -1162,12 +1222,65 @@ void ol_rx_timestamp(struct cdp_cfg *cfg_pdev, msdu->tstamp = ns_to_ktime(tsf64_ns); } + +/** + * ol_rx_timestamp_update() - update msdu tsf64 timestamp + * @pdev: pointer to txrx handle + * @head_msdu: pointer to head msdu + * @tail_msdu: pointer to tail msdu + * + * Return: none + */ +static inline void ol_rx_timestamp_update(ol_txrx_pdev_handle pdev, + qdf_nbuf_t head_msdu, + qdf_nbuf_t tail_msdu) +{ + qdf_nbuf_t loop_msdu; + uint64_t hostime, detlahostime, tsf64_time; + struct htt_host_rx_desc_base *rx_desc; + + if (!ol_cfg_is_ptp_rx_opt_enabled(pdev->ctrl_pdev)) + return; + + if (!tail_msdu) + return; + + hostime = ktime_get_ns(); + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, tail_msdu); + if (rx_desc->ppdu_end.wb_timestamp_lower_32 == 0 && + rx_desc->ppdu_end.wb_timestamp_upper_32 == 0) { + detlahostime = hostime - pdev->last_host_time; + do_div(detlahostime, NSEC_PER_USEC); + tsf64_time = pdev->last_tsf64_time + detlahostime; + + rx_desc->ppdu_end.wb_timestamp_lower_32 = + tsf64_time & 0xFFFFFFFF; + rx_desc->ppdu_end.wb_timestamp_upper_32 = tsf64_time >> 32; + } else { + pdev->last_host_time = hostime; + pdev->last_tsf64_time = + (uint64_t)rx_desc->ppdu_end.wb_timestamp_upper_32 << 32 | + rx_desc->ppdu_end.wb_timestamp_lower_32; + } + + loop_msdu = head_msdu; + while (loop_msdu) { + ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, loop_msdu); + loop_msdu = qdf_nbuf_next(loop_msdu); + } +} #endif #else void ol_rx_timestamp(struct cdp_cfg *cfg_pdev, void *rx_desc, qdf_nbuf_t msdu) { } + +static inline void ol_rx_timestamp_update(ol_txrx_pdev_handle pdev, + qdf_nbuf_t head_msdu, + qdf_nbuf_t tail_msdu) +{ +} #endif #ifdef WLAN_FEATURE_DSRC @@ -1298,9 +1411,9 @@ ol_rx_deliver(struct ol_txrx_vdev_t *vdev, if (OL_RX_DECAP(vdev, peer, msdu, &info) != A_OK) { discard = 1; ol_txrx_dbg( - "decap error %pK from peer %pK ("QDF_MAC_ADDR_STR") len %d\n", + "decap error %pK from peer %pK ("QDF_MAC_ADDR_FMT") len %d\n", msdu, peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(peer->mac_addr.raw), qdf_nbuf_len(msdu)); goto DONE; } @@ -1354,6 +1467,8 @@ ol_rx_deliver(struct ol_txrx_vdev_t *vdev, ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, msdu); OL_TXRX_LIST_APPEND(deliver_list_head, deliver_list_tail, msdu); + QDF_NBUF_CB_DP_TRACE_PRINT(msdu) = false; + qdf_dp_trace_set_track(msdu, QDF_RX); } msdu = next; } @@ -1446,7 +1561,6 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, { struct ol_txrx_vdev_t *vdev = NULL; struct ol_txrx_peer_t *peer = NULL; - struct ol_txrx_peer_t *peer_head = NULL; htt_pdev_handle htt_pdev = NULL; int status; qdf_nbuf_t head_msdu = NULL, tail_msdu = NULL; @@ -1455,10 +1569,6 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, uint32_t msdu_count; uint8_t pktlog_bit; uint32_t filled = 0; - struct htt_host_rx_desc_base *rx_desc; - qdf_nbuf_t loop_msdu; - uint8_t bssid[QDF_MAC_ADDR_SIZE] = {0}; - bool offloaded_pkt; if (tid >= OL_TXRX_NUM_EXT_TIDS) { ol_txrx_err("invalid tid, %u", tid); @@ -1522,43 +1632,6 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ qdf_nbuf_set_next(tail_msdu, NULL); - /* Packet Capture Mode */ - - if ((ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_DATA_ONLY)) { - offloaded_pkt = ucfg_pkt_capture_rx_offloaded_pkt(rx_ind_msg); - if (peer) { - vdev = peer->vdev; - if (peer->vdev) { - qdf_spin_lock_bh(&pdev->peer_ref_mutex); - peer_head = TAILQ_FIRST(&vdev->peer_list); - qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - if (peer_head) { - qdf_spin_lock_bh( - &peer_head->peer_info_lock); - qdf_mem_copy(bssid, - &peer_head->mac_addr.raw, - QDF_MAC_ADDR_SIZE); - qdf_spin_unlock_bh( - &peer_head->peer_info_lock); - - ucfg_pkt_capture_rx_msdu_process( - bssid, head_msdu, - peer->vdev->vdev_id, - htt_pdev); - } - } - } else if (offloaded_pkt) { - ucfg_pkt_capture_rx_msdu_process( - bssid, head_msdu, - HTT_INVALID_VDEV, - htt_pdev); - - ucfg_pkt_capture_rx_drop_offload_pkt(head_msdu); - return; - } - } - /* Pktlog */ ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit); @@ -1580,15 +1653,9 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, } return; } - /*Loop msdu to fill tstamp with tsf64 time in ol_rx_timestamp*/ - loop_msdu = head_msdu; - while (loop_msdu) { - qdf_nbuf_t msdu = head_msdu; - rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, loop_msdu); - ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, msdu); - loop_msdu = qdf_nbuf_next(loop_msdu); - } + /*Loop msdu to fill tstamp with tsf64 time in ol_rx_timestamp*/ + ol_rx_timestamp_update(pdev, head_msdu, tail_msdu); peer->rx_opt_proc(vdev, peer, tid, head_msdu); } @@ -1614,12 +1681,18 @@ void ol_rx_pkt_dump_call( uint8_t peer_id, uint8_t status) { - ol_txrx_pdev_handle pdev; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_soc_handle soc_hdl = ol_txrx_soc_t_to_cdp_soc_t(soc); struct ol_txrx_peer_t *peer = NULL; ol_txrx_pktdump_cb packetdump_cb; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return; @@ -1634,7 +1707,7 @@ void ol_rx_pkt_dump_call( packetdump_cb = pdev->ol_rx_packetdump_cb; if (packetdump_cb && wlan_op_mode_sta == peer->vdev->opmode) - packetdump_cb(soc, (struct cdp_vdev *)peer->vdev, + packetdump_cb(soc_hdl, OL_TXRX_PDEV_ID, peer->vdev->vdev_id, msdu, status, RX_DATA_PKT); } #endif diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.h index a07df976b606c88f964d4ce6b5ea875921fdb89a..17c1101138fd90ee6fd3d6b328866802a3dadcfb 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -42,6 +42,28 @@ ol_rx_discard(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer, unsigned int tid, qdf_nbuf_t head_msdu); +/** + * ol_rx_send_mic_err_ind() - ol rx mic err handler + * @pdev: ol pdev + * @vdev_id: vdev id + * @peer_mac_addr: peer mac address + * @tid: TID + * @tsf32: TSF + * @err_type: error type + * @rx_frame: rx frame + * @pn: PN Number + * @key_id: key id + * + * This function handles rx error and send MIC error failure to HDD + * + * Return: none + */ +void +ol_rx_send_mic_err_ind(struct ol_txrx_pdev_t *pdev, uint8_t vdev_id, + uint8_t *peer_mac_addr, int tid, uint32_t tsf32, + enum ol_rx_err_type err_type, qdf_nbuf_t rx_frame, + uint64_t *pn, uint8_t key_id); + void ol_rx_frames_free(htt_pdev_handle htt_pdev, qdf_nbuf_t frames); void ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c index f946f9c2e5366af6167cfee1cad9dc531691e8b8..bfaef16fccad7e2546fb07a0cf0f5c9305c75fb8 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019,2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -58,7 +58,6 @@ #include #include #include /* qdf_system_time */ -#include #define DEFRAG_IEEE80211_ADDR_EQ(a1, a2) \ (!qdf_mem_cmp(a1, a2, QDF_MAC_ADDR_SIZE)) @@ -678,8 +677,7 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, struct ieee80211_frame *wh; uint8_t key[DEFRAG_IEEE80211_KEY_LEN]; htt_pdev_handle htt_pdev = pdev->htt_pdev; - struct ol_txrx_peer_t *peer_head = NULL; - uint8_t bssid[QDF_MAC_ADDR_SIZE]; + vdev = peer->vdev; /* bypass defrag for safe mode */ @@ -802,33 +800,6 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev, if (ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_802_3) ol_rx_defrag_nwifi_to_8023(pdev, msdu); - /* Packet Capture Mode */ - - if ((ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_DATA_ONLY)) { - if (peer) { - if (peer->vdev) { - qdf_spin_lock_bh(&pdev->peer_ref_mutex); - peer_head = TAILQ_FIRST(&vdev->peer_list); - qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - if (peer_head) { - qdf_spin_lock_bh( - &peer_head->peer_info_lock); - qdf_mem_copy(bssid, - &peer_head->mac_addr.raw, - QDF_MAC_ADDR_SIZE); - qdf_spin_unlock_bh( - &peer_head->peer_info_lock); - - ucfg_pkt_capture_rx_msdu_process( - bssid, msdu, - vdev->vdev_id, - htt_pdev); - } - } - } - } - ol_rx_fwd_check(vdev, peer, tid, msdu); } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c index b4a0c37dca29d63308f8dc70b9cc2bba7da658a1..0326908cb93b05e282d9c3ffec750fb8ce17f8dd 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c @@ -191,8 +191,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, QDF_NBUF_TX_EXT_TID_INVALID); } - if (!ol_txrx_fwd_desc_thresh_check( - (struct cdp_vdev *)vdev)) { + if (!ol_txrx_fwd_desc_thresh_check(vdev)) { /* Drop the packet*/ htt_rx_msdu_desc_free(pdev->htt_pdev, msdu); TXRX_STATS_MSDU_LIST_INCR( @@ -276,14 +275,17 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, /* * ol_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets * that has been forwarded from txrx layer without going to upper layers. + * @soc_hdl: Datapath soc handle * @vdev_id: vdev id * @fwd_tx_packets: pointer to forwarded tx packets count parameter * @fwd_rx_packets: pointer to forwarded rx packets count parameter * * Return: status -> A_OK - success, A_ERROR - failure */ -A_STATUS ol_get_intra_bss_fwd_pkts_count(uint8_t vdev_id, - uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets) +A_STATUS ol_get_intra_bss_fwd_pkts_count(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint64_t *fwd_tx_packets, + uint64_t *fwd_rx_packets) { struct ol_txrx_vdev_t *vdev = NULL; diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.h index 9fc63e7ff5bfd3b219a624d6644fd4bfc3d2326d..c2c5947f9504e7b75ac39517aea9056e6af48be3 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,9 +64,9 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev, unsigned int tid, qdf_nbuf_t msdu_list); A_STATUS -ol_get_intra_bss_fwd_pkts_count( - uint8_t vdev_id, - uint64_t *fwd_tx_packets, - uint64_t *fwd_rx_packets); +ol_get_intra_bss_fwd_pkts_count(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint64_t *fwd_tx_packets, + uint64_t *fwd_rx_packets); #endif /* _OL_RX_FWD_H_ */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c index d771f9b4061dc0e29505524dd0234930c7484746..2cb97488d1ed5ae18607d5a478e37c048d339456 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c @@ -167,14 +167,12 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, last_pncheck_print_time = current_time_ms; ol_txrx_warn( "PN check failed - TID %d, peer %pK " - "("QDF_MAC_ADDR_STR") %s\n" + "("QDF_MAC_ADDR_FMT") %s\n" " old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new seq num = %d\n", tid, peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5], + QDF_MAC_ADDR_REF(peer->mac_addr.raw), (index == txrx_sec_ucast) ? "ucast" : "mcast", last_pn->pn128[1], last_pn->pn128[0], @@ -186,14 +184,12 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev, } else { ol_txrx_dbg( "PN check failed - TID %d, peer %pK " - "("QDF_MAC_ADDR_STR") %s\n" + "("QDF_MAC_ADDR_FMT") %s\n" " old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new seq num = %d\n", tid, peer, - peer->mac_addr.raw[0], peer->mac_addr.raw[1], - peer->mac_addr.raw[2], peer->mac_addr.raw[3], - peer->mac_addr.raw[4], peer->mac_addr.raw[5], + QDF_MAC_ADDR_REF(peer->mac_addr.raw), (index == txrx_sec_ucast) ? "ucast" : "mcast", last_pn->pn128[1], last_pn->pn128[0], diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.c index 5ec5be971a10d9e12d07374a0a62a094ad6d7d0d..2fae0cfd02e7bd18929fb14f53f5713349d2fd71 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.c @@ -36,12 +36,24 @@ #include /*=== data types and defines ===*/ - -/*---*/ +#define OL_RX_REORDER_ROUND_PWR2(value) g_log2ceil[value] /*=== global variables ===*/ -/*---*/ +static char g_log2ceil[] = { + 1, /* 0 -> 1 */ + 1, /* 1 -> 1 */ + 2, /* 2 -> 2 */ + 4, 4, /* 3-4 -> 4 */ + 8, 8, 8, 8, /* 5-8 -> 8 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 9-16 -> 16 */ + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, /* 17-32 -> 32 */ + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, /* 33-64 -> 64 */ +}; /*=== function definitions ===*/ @@ -504,6 +516,108 @@ ol_rx_reorder_peer_cleanup(struct ol_txrx_vdev_t *vdev, /* functions called by HTT */ +void +ol_rx_addba_handler(ol_txrx_pdev_handle pdev, + uint16_t peer_id, + uint8_t tid, + uint8_t win_sz, uint16_t start_seq_num, uint8_t failed) +{ + uint8_t round_pwr2_win_sz; + unsigned int array_size; + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_t *rx_reorder; + void *array_mem = NULL; + + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + ol_txrx_err("invalid tid, %u", tid); + WARN_ON(1); + return; + } + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (!peer) { + ol_txrx_err("not able to find peer, %u", peer_id); + return; + } + + if (pdev->cfg.host_addba) { + ol_ctrl_rx_addba_complete(pdev->ctrl_pdev, + &peer->mac_addr.raw[0], tid, failed); + } + if (failed) + return; + + peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; /* invalid */ + rx_reorder = &peer->tids_rx_reorder[tid]; + + TXRX_ASSERT2(win_sz <= 64); + round_pwr2_win_sz = OL_RX_REORDER_ROUND_PWR2(win_sz); + array_size = + round_pwr2_win_sz * sizeof(struct ol_rx_reorder_array_elem_t); + + array_mem = qdf_mem_malloc(array_size); + if (!array_mem) { + ol_txrx_err("memory allocation failed"); + return; + } + + if (rx_reorder->array != &rx_reorder->base) { + ol_txrx_info("delete array for tid %d", tid); + qdf_mem_free(rx_reorder->array); + } + + rx_reorder->array = array_mem; + rx_reorder->win_sz = win_sz; + TXRX_ASSERT1(rx_reorder->array); + + rx_reorder->win_sz_mask = round_pwr2_win_sz - 1; + rx_reorder->num_mpdus = 0; + + peer->tids_next_rel_idx[tid] = + OL_RX_REORDER_IDX_INIT(start_seq_num, rx_reorder->win_sz, + rx_reorder->win_sz_mask); +} + +void +ol_rx_delba_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id, uint8_t tid) +{ + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_t *rx_reorder; + + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + ol_txrx_err("invalid tid, %u", tid); + WARN_ON(1); + return; + } + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (!peer) { + ol_txrx_err("not able to find peer, %u", peer_id); + return; + } + + peer->tids_next_rel_idx[tid] = INVALID_REORDER_INDEX; + rx_reorder = &peer->tids_rx_reorder[tid]; + + /* check that there really was a block ack agreement */ + TXRX_ASSERT1(rx_reorder->win_sz_mask != 0); + /* + * Deallocate the old rx reorder array. + * The call to ol_rx_reorder_init below + * will reset rx_reorder->array to point to + * the single-element statically-allocated reorder array + * used for non block-ack cases. + */ + if (rx_reorder->array != &rx_reorder->base) { + ol_txrx_dbg("delete reorder array, tid:%d", + tid); + qdf_mem_free(rx_reorder->array); + } + + /* set up the TID with default parameters (ARQ window size = 1) */ + ol_rx_reorder_init(rx_reorder, tid); +} + void ol_rx_flush_handler(ol_txrx_pdev_handle pdev, uint16_t peer_id, @@ -647,11 +761,11 @@ ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev, current_time_ms; ol_txrx_warn( "Tgt PN check failed - TID %d, peer %pK " - "("QDF_MAC_ADDR_STR")\n" + "("QDF_MAC_ADDR_FMT")\n" " PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new seq num = %d\n", tid, peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(peer->mac_addr.raw), pn.pn128[1], pn.pn128[0], pn.pn128[0] & 0xffffffffffffULL, @@ -660,11 +774,11 @@ ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev, } else { ol_txrx_dbg( "Tgt PN check failed - TID %d, peer %pK " - "("QDF_MAC_ADDR_STR")\n" + "("QDF_MAC_ADDR_FMT")\n" " PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" " new seq num = %d\n", tid, peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw), + QDF_MAC_ADDR_REF(peer->mac_addr.raw), pn.pn128[1], pn.pn128[0], pn.pn128[0] & 0xffffffffffffULL, diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.h index fa64010616751242299d9347613b01b7121bd9c0..07fa12fca823d598a8a817edba7b0be5d4323dcd 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_reorder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2017, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.c index 41bfdd3fd3b1e74be8b620af9f74cf6da2546559..d6c7d24981cb395b558d6fdc17e4567ff1cdf0f0 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,16 +43,20 @@ /** * ol_tx_data() - send data frame - * @vdev: virtual device handle + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id * @skb: skb * * Return: skb/NULL for success */ -qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb) +qdf_nbuf_t ol_tx_data(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t skb) { struct ol_txrx_pdev_t *pdev; qdf_nbuf_t ret; - ol_txrx_vdev_handle vdev = data_vdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); if (qdf_unlikely(!vdev)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, @@ -85,15 +89,22 @@ qdf_nbuf_t ol_tx_data(void *data_vdev, qdf_nbuf_t skb) } #ifdef IPA_OFFLOAD -qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb) +qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t skb) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id( + soc, OL_TXRX_PDEV_ID); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); qdf_nbuf_t ret; if (qdf_unlikely(!pdev)) { - qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__); - - ol_txrx_err("pdev is NULL"); + ol_txrx_err("%s: invalid pdev", __func__); + return skb; + } + if (qdf_unlikely(!vdev)) { + ol_txrx_err("%s: invalid vdev, vdev_id:%d", __func__, vdev_id); return skb; } @@ -122,41 +133,59 @@ qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb) #endif void -ol_txrx_data_tx_cb_set(struct cdp_vdev *pvdev, +ol_txrx_data_tx_cb_set(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, ol_txrx_data_tx_cb callback, void *ctxt) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + struct ol_txrx_pdev_t *pdev; + + if (!vdev || !vdev->pdev) + return; + pdev = vdev->pdev; pdev->tx_data_callback.func = callback; pdev->tx_data_callback.ctxt = ctxt; } -void -ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, +QDF_STATUS +ol_txrx_mgmt_tx_cb_set(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint8_t type, ol_txrx_mgmt_tx_cb download_cb, ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAILURE; TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES); pdev->tx_mgmt_cb.download_cb = download_cb; pdev->tx_mgmt_cb.ota_ack_cb = ota_ack_cb; pdev->tx_mgmt_cb.ctxt = ctxt; + + return QDF_STATUS_SUCCESS; } int -ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev, - qdf_nbuf_t tx_mgmt_frm, - uint8_t type, uint8_t use_6mbps, uint16_t chanfreq) +ol_txrx_mgmt_send_ext(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t tx_mgmt_frm, uint8_t type, + uint8_t use_6mbps, uint16_t chanfreq) { - struct ol_txrx_vdev_t *vdev = - (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + struct ol_txrx_pdev_t *pdev; struct ol_tx_desc_t *tx_desc; struct ol_txrx_msdu_info_t tx_msdu_info; int result = 0; + if (!vdev || !vdev->pdev) + return QDF_STATUS_E_FAULT; + + pdev = vdev->pdev; tx_msdu_info.tso_info.is_tso = 0; tx_msdu_info.htt.action.use_6mbps = use_6mbps; diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.h index b163e29d6dfd5138db40aac88b150f230f114adf..b3c69dee358e412280b74f772fb2eaba366b25ce 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,17 +29,20 @@ #include /* ol_tx_spec */ #include #include /* ol_tx_desc_t, ol_txrx_msdu_info_t */ +#include #include #ifdef IPA_OFFLOAD /** * ol_tx_send_ipa_data_frame() - send IPA data frame - * @vdev: vdev + * @soc_hdl: datapath soc handle + * @vdev: virtual interface id * @skb: skb * * Return: skb/ NULL is for success */ -qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb); +qdf_nbuf_t ol_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + qdf_nbuf_t skb); #endif #ifdef CONFIG_LL_DP_SUPPORT @@ -78,6 +81,31 @@ qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); #define OL_TX_LL ol_tx_ll_wrapper #endif +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +void ol_tx_hl_vdev_bundle_timer(void *context); + +void ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t *vdev); +qdf_nbuf_t +ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t *pdev); +#else +static inline +void ol_tx_hl_vdev_bundle_timer(void *context) +{ +} + +static inline +void ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t *vdev) +{ +} + +static inline +qdf_nbuf_t +ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t *pdev) +{ + return NULL; +} +#endif + #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL void ol_tx_vdev_ll_pause_queue_send(void *context); void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev); @@ -124,7 +152,8 @@ ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list); /** * ol_tx_non_std() - Allow the control-path SW to send data frames - * @data_vdev: which vdev should transmit the tx data frames + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @tx_spec: what non-standard handling to apply to the tx data frames * @msdu_list: NULL-terminated list of tx MSDUs * @@ -149,24 +178,34 @@ qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu_list); static inline qdf_nbuf_t -ol_tx_non_std(struct cdp_vdev *pvdev, +ol_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev; - return ol_tx_non_std_hl(vdev, tx_spec, msdu_list); + vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (!vdev) + return msdu_list; + else + return ol_tx_non_std_hl(vdev, tx_spec, msdu_list); } #else qdf_nbuf_t ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list); static inline qdf_nbuf_t -ol_tx_non_std(struct cdp_vdev *pvdev, +ol_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev; + + vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); - return ol_tx_non_std_ll(vdev, tx_spec, msdu_list); + if (!vdev) + return msdu_list; + else + return ol_tx_non_std_ll(vdev, tx_spec, msdu_list); } #endif @@ -175,7 +214,8 @@ void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); /** * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery * notifications for management frames. - * @ppdev: the data physical device object + * @soc: Datapath soc handle + * @pdev_id: Physical device instance id * @type: the type of mgmt frame the callback is used for * @download_cb: the callback for notification of delivery to the target * @ota_ack_cb: the callback for notification of delivery to the peer @@ -191,14 +231,15 @@ void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); * This function is used by the control SW to store a callback pointer * for a given type of management frame. */ -void -ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, +QDF_STATUS +ol_txrx_mgmt_tx_cb_set(struct cdp_soc_t *soc, uint8_t pdev_id, uint8_t type, ol_txrx_mgmt_tx_cb download_cb, ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt); /** * ol_txrx_mgmt_send_ext() - Transmit a management frame - * @pvdev: virtual device transmitting the frame + * @soc: Datapath soc handle + * @vdev_id: virtual interface id * @tx_mgmt_frm: management frame to transmit * @type: the type of management frame (determines what callback to use) * @use_6mbps: specify whether management frame to transmit should @@ -214,7 +255,7 @@ ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, * 1 - the frame was not accepted */ int -ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev, +ol_txrx_mgmt_send_ext(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t tx_mgmt_frm, uint8_t type, uint8_t use_6mbps, uint16_t chanfreq); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_classify.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_classify.c index bcff5b189d1246511c1dce8f6b5842d2b3f1b3bc..3d80f993b23f96df2ada90083cd32e30172c1e08 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_classify.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_classify.c @@ -334,33 +334,79 @@ ol_tx_tid( static inline struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev, + uint8_t *dest_addr, uint8_t *peer_id) { struct ol_txrx_peer_t *peer = NULL; + uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 }; + enum peer_debug_id_type id_type = PEER_DEBUG_ID_OL_INTERNAL; + + struct ol_txrx_peer_t *(*find_peer)(struct ol_txrx_pdev_t *pdev, + uint8_t *peer_mac_addr, + int mac_addr_is_aligned, + u8 check_valid, + enum peer_debug_id_type dbg_id) + = ol_txrx_peer_find_hash_find_get_ref; if (vdev->hlTdlsFlag) { - peer = ol_txrx_peer_find_hash_find_get_ref(pdev, - vdev->hl_tdls_ap_mac_addr.raw, 0, 1, - PEER_DEBUG_ID_OL_INTERNAL); + peer = find_peer(pdev, vdev->hl_tdls_ap_mac_addr.raw, + 0, 1, id_type); - if (peer && (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) { - ol_txrx_peer_release_ref(peer, - PEER_DEBUG_ID_OL_INTERNAL); + if (peer && (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) { + ol_txrx_peer_release_ref(peer, id_type); peer = NULL; } else { - if (peer) + if (peer) { *peer_id = peer->local_id; + return peer; + } } } - if (!peer) - peer = ol_txrx_assoc_peer_find(vdev); + /* Packets destined to TDLS Peer or AP with 'No TDLS Link'. + * Optimized to directly get the peer based on 'dest_addr' + */ + if (vdev->last_real_peer && + !qdf_mem_cmp(vdev->last_real_peer->mac_addr.raw, + dest_addr, QDF_MAC_ADDR_SIZE)) { + ol_txrx_peer_get_ref(vdev->last_real_peer, id_type); + *peer_id = vdev->last_real_peer->local_id; + peer = vdev->last_real_peer; + } else { + /* packets destined for other peers or AP with TDLS Link */ + if (vdev->last_real_peer && + !qdf_mem_cmp(vdev->hl_tdls_ap_mac_addr.raw, + zero_mac_addr, + QDF_MAC_ADDR_SIZE)) { + /* With No TDLS Link return last_real_peer for both AP + * and other bss peer + */ + ol_txrx_peer_get_ref(vdev->last_real_peer, id_type); + *peer_id = vdev->last_real_peer->local_id; + peer = vdev->last_real_peer; + } else { /* packet destined for other peers and AP when + * STA has TDLS link + */ + peer = find_peer(pdev, vdev->hl_tdls_ap_mac_addr.raw, + 0, 1, id_type); + + if (peer && + (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) { + ol_txrx_peer_release_ref(peer, id_type); + peer = NULL; + } else { + if (peer) + *peer_id = peer->local_id; + } + } + } return peer; } #else static struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev, + uint8_t *dest_addr, uint8_t *peer_id) { struct ol_txrx_peer_t *peer = NULL; @@ -410,9 +456,9 @@ ol_tx_classify( if (!peer) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Error: STA %pK ("QDF_MAC_ADDR_STR") trying to send bcast DA tx data frame w/o association\n", + "Error: STA %pK ("QDF_MAC_ADDR_FMT") trying to send bcast DA tx data frame w/o association\n", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); return NULL; /* error */ } else if ((peer->security[ OL_TXRX_PEER_SECURITY_MULTICAST].sec_type @@ -457,9 +503,9 @@ ol_tx_classify( if (!peer) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Error: vdev %pK ("QDF_MAC_ADDR_STR") trying to send bcast/mcast, but no self-peer found\n", + "Error: vdev %pK ("QDF_MAC_ADDR_FMT") trying to send bcast/mcast, but no self-peer found\n", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); return NULL; /* error */ } } @@ -503,7 +549,9 @@ ol_tx_classify( * then the frame is either for the AP itself, or is * supposed to be sent to the AP for forwarding. */ - peer = ol_tx_tdls_peer_find(pdev, vdev, &peer_id); + peer = ol_tx_tdls_peer_find(pdev, vdev, + dest_addr, + &peer_id); } else { peer = ol_txrx_peer_find_hash_find_get_ref(pdev, dest_addr, @@ -517,11 +565,9 @@ ol_tx_classify( * associated peer. It is illegitimate to send unicast * data if there is no peer to send it to. */ - QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_ERROR, - "Error: vdev %pK ("QDF_MAC_ADDR_STR") trying to send unicast tx data frame to an unknown peer\n", - vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + ol_txrx_err_rl("Error: vdev %pK (" QDF_MAC_ADDR_FMT ") trying to send unicast tx data frame to an unknown peer", + vdev, + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); return NULL; /* error */ } TX_SCHED_DEBUG_PRINT("Peer found\n"); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.c index 36df5222dd52411ee911f06c02f03826769434cc..f56d917c152a69504cd979b38a787e321abfde2b 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.c @@ -129,7 +129,99 @@ ol_tx_desc_count_inc(struct ol_txrx_vdev_t *vdev) #endif #ifndef QCA_LL_TX_FLOW_CONTROL_V2 +#ifdef QCA_LL_PDEV_TX_FLOW_CONTROL +/** + * ol_tx_do_pdev_flow_control_pause - pause queues when stop_th reached. + * @pdev: pdev handle + * + * Return: void + */ +static void ol_tx_do_pdev_flow_control_pause(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + + if (qdf_unlikely(pdev->tx_desc.num_free < + pdev->tx_desc.stop_th && + pdev->tx_desc.num_free >= + pdev->tx_desc.stop_priority_th && + pdev->tx_desc.status == + FLOW_POOL_ACTIVE_UNPAUSED)) { + pdev->tx_desc.status = FLOW_POOL_NON_PRIO_PAUSED; + /* pause network NON PRIORITY queues */ + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + pdev->pause_cb(vdev->vdev_id, + WLAN_STOP_NON_PRIORITY_QUEUE, + WLAN_DATA_FLOW_CONTROL); + } + } else if (qdf_unlikely((pdev->tx_desc.num_free < + pdev->tx_desc.stop_priority_th) && + pdev->tx_desc.status == + FLOW_POOL_NON_PRIO_PAUSED)) { + pdev->tx_desc.status = FLOW_POOL_ACTIVE_PAUSED; + /* pause priority queue */ + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + pdev->pause_cb(vdev->vdev_id, + WLAN_NETIF_PRIORITY_QUEUE_OFF, + WLAN_DATA_FLOW_CONTROL_PRIORITY); + } + } +} + +/** + * ol_tx_do_pdev_flow_control_unpause - unpause queues when start_th restored. + * @pdev: pdev handle + * + * Return: void + */ +static void ol_tx_do_pdev_flow_control_unpause(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + + switch (pdev->tx_desc.status) { + case FLOW_POOL_ACTIVE_PAUSED: + if (pdev->tx_desc.num_free > + pdev->tx_desc.start_priority_th) { + /* unpause priority queue */ + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + pdev->pause_cb(vdev->vdev_id, + WLAN_NETIF_PRIORITY_QUEUE_ON, + WLAN_DATA_FLOW_CONTROL_PRIORITY); + } + pdev->tx_desc.status = FLOW_POOL_NON_PRIO_PAUSED; + } + break; + case FLOW_POOL_NON_PRIO_PAUSED: + if (pdev->tx_desc.num_free > pdev->tx_desc.start_th) { + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + pdev->pause_cb(vdev->vdev_id, + WLAN_WAKE_NON_PRIORITY_QUEUE, + WLAN_DATA_FLOW_CONTROL); + } + pdev->tx_desc.status = FLOW_POOL_ACTIVE_UNPAUSED; + } + break; + case FLOW_POOL_INVALID: + if (pdev->tx_desc.num_free == pdev->tx_desc.pool_size) + ol_txrx_err("pool is INVALID State!!"); + break; + case FLOW_POOL_ACTIVE_UNPAUSED: + break; + default: + ol_txrx_err("pool is INACTIVE State!!\n"); + break; + }; +} +#else +static inline void +ol_tx_do_pdev_flow_control_pause(struct ol_txrx_pdev_t *pdev) +{ +} +static inline void +ol_tx_do_pdev_flow_control_unpause(struct ol_txrx_pdev_t *pdev) +{ +} +#endif /** * ol_tx_desc_alloc() - allocate descriptor from freelist * @pdev: pdev handle @@ -142,7 +234,6 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) { struct ol_tx_desc_t *tx_desc = NULL; - struct ol_txrx_vdev_t *vd; qdf_spin_lock_bh(&pdev->tx_mutex); if (pdev->tx_desc.freelist) { @@ -152,31 +243,7 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, return NULL; } ol_tx_desc_dup_detect_set(pdev, tx_desc); - if (qdf_unlikely(pdev->tx_desc.num_free < - pdev->tx_desc.stop_th && - pdev->tx_desc.num_free >= - pdev->tx_desc.stop_priority_th && - pdev->tx_desc.status == - FLOW_POOL_ACTIVE_UNPAUSED)) { - pdev->tx_desc.status = FLOW_POOL_NON_PRIO_PAUSED; - /* pause network NON PRIORITY queues */ - TAILQ_FOREACH(vd, &pdev->vdev_list, vdev_list_elem) { - pdev->pause_cb(vd->vdev_id, - WLAN_STOP_NON_PRIORITY_QUEUE, - WLAN_DATA_FLOW_CONTROL); - } - } else if (qdf_unlikely((pdev->tx_desc.num_free < - pdev->tx_desc.stop_priority_th) && - pdev->tx_desc.status == - FLOW_POOL_NON_PRIO_PAUSED)) { - pdev->tx_desc.status = FLOW_POOL_ACTIVE_PAUSED; - /* pause priority queue */ - TAILQ_FOREACH(vd, &pdev->vdev_list, vdev_list_elem) { - pdev->pause_cb(vd->vdev_id, - WLAN_NETIF_PRIORITY_QUEUE_OFF, - WLAN_DATA_FLOW_CONTROL_PRIORITY); - } - } + ol_tx_do_pdev_flow_control_pause(pdev); ol_tx_desc_sanity_checks(pdev, tx_desc); ol_tx_desc_compute_delay(tx_desc); ol_tx_desc_vdev_update(tx_desc, vdev); @@ -466,47 +533,13 @@ static void ol_tx_desc_free_common(struct ol_txrx_pdev_t *pdev, */ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) { - struct ol_txrx_vdev_t *vdev; - qdf_spin_lock_bh(&pdev->tx_mutex); ol_tx_desc_free_common(pdev, tx_desc); ol_tx_put_desc_global_pool(pdev, tx_desc); ol_tx_desc_vdev_rm(tx_desc); - - switch (pdev->tx_desc.status) { - case FLOW_POOL_ACTIVE_PAUSED: - if (pdev->tx_desc.num_free > pdev->tx_desc.start_priority_th) { - /* unpause priority queue */ - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - pdev->pause_cb(vdev->vdev_id, - WLAN_NETIF_PRIORITY_QUEUE_ON, - WLAN_DATA_FLOW_CONTROL_PRIORITY); - } - pdev->tx_desc.status = FLOW_POOL_NON_PRIO_PAUSED; - } - break; - case FLOW_POOL_NON_PRIO_PAUSED: - if (pdev->tx_desc.num_free > pdev->tx_desc.start_th) { - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - pdev->pause_cb(vdev->vdev_id, - WLAN_WAKE_NON_PRIORITY_QUEUE, - WLAN_DATA_FLOW_CONTROL); - } - pdev->tx_desc.status = FLOW_POOL_ACTIVE_UNPAUSED; - } - break; - case FLOW_POOL_INVALID: - if (pdev->tx_desc.num_free == pdev->tx_desc.pool_size) - ol_txrx_err("pool is INVALID State!!"); - break; - case FLOW_POOL_ACTIVE_UNPAUSED: - break; - default: - ol_txrx_err("pool is INACTIVE State!!\n"); - break; - }; + ol_tx_do_pdev_flow_control_unpause(pdev); qdf_spin_unlock_bh(&pdev->tx_mutex); } @@ -853,9 +886,11 @@ void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev, * DMA mapped address. In such case, there's no need for WLAN * driver to DMA unmap the skb. */ - if ((qdf_nbuf_get_users(msdu) <= 1) && - !qdf_nbuf_ipa_owned_get(msdu)) - qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_TO_DEVICE); + if (qdf_nbuf_get_users(msdu) <= 1) { + if (!qdf_nbuf_ipa_owned_get(msdu)) + qdf_nbuf_unmap(pdev->osdev, msdu, + QDF_DMA_TO_DEVICE); + } /* free the tx desc */ ol_tx_desc_free(pdev, tx_desc); @@ -933,10 +968,6 @@ void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev, } } else if (had_error == htt_tx_status_download_fail) { /* Failed to send to target */ - - /* This is to decrement skb->users count for TSO segment */ - if (tx_desc->pkt_type == OL_TX_FRM_TSO) - qdf_nbuf_tx_free(tx_desc->netbuf, had_error); goto free_tx_desc; } else { /* single regular frame, called from completion path */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.h index 70d31cedfb4e5472c63c4d737a463eb7bc4a83fe..96342bca7ce9a2288781278cb59f349d337588b7 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_desc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,7 +23,7 @@ #ifndef _OL_TX_DESC__H_ #define _OL_TX_DESC__H_ -#include /* TAILQ_HEAD */ +#include "queue.h" /* TAILQ_HEAD */ #include /* qdf_nbuf_t */ #include /* ol_txrx_vdev_t, etc. */ #include /*TXRX_ASSERT2 */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_hl.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_hl.c index 16c68e96c7a7d01a4c51fa997305678eb4209b46..2a222cb3507b7e870a793fd6c427adbb9b964afa 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_hl.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_hl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,7 +22,7 @@ #include /* qdf_nbuf_t */ #include /* QDF_NBUF_TX_EXT_TID_INVALID */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ #ifdef QCA_COMPUTE_TX_DELAY #include /* ethernet_hdr_t, etc. */ #include /* ipv6_traffic_class */ @@ -54,6 +54,18 @@ #include #include #include +#include "qdf_hrtimer.h" + +/* High/Low tx resource count in percentage */ +/* Set default high threashold to 15% */ +#ifndef TX_RESOURCE_HIGH_TH_IN_PER +#define TX_RESOURCE_HIGH_TH_IN_PER 15 +#endif + +/* Set default low threshold to 5% */ +#ifndef TX_RESOURCE_LOW_TH_IN_PER +#define TX_RESOURCE_LOW_TH_IN_PER 5 +#endif #ifdef QCA_HL_NETDEV_FLOW_CONTROL static u16 ol_txrx_tx_desc_alloc_table[TXRX_FC_MAX] = { @@ -227,56 +239,14 @@ struct ol_tx_desc_t *ol_tx_hl_desc_alloc(struct ol_txrx_pdev_t *pdev, } #endif -#ifdef QCA_HL_NETDEV_FLOW_CONTROL -/** - * ol_txrx_rsrc_threshold_lo() - set threshold low - when to start tx desc - * margin replenishment - * @desc_pool_size: tx desc pool size - * - * Return: threshold low - */ static inline uint16_t ol_txrx_rsrc_threshold_lo(int desc_pool_size) { int threshold_low; - /* - * 5% margin of unallocated desc is too much for per - * vdev mechanism. - * Define the value separately. - */ - threshold_low = TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED; - - return threshold_low; -} - -/** - * ol_txrx_rsrc_threshold_hi() - set threshold high - where to stop - * during tx desc margin replenishment - * @desc_pool_size: tx desc pool size - * - * Return: threshold high - */ -static inline uint16_t -ol_txrx_rsrc_threshold_hi(int desc_pool_size) -{ - int threshold_high; - /* when freeing up descriptors, - * keep going until there's a 7.5% margin - */ - threshold_high = ((15 * desc_pool_size) / 100) / 2; - - return threshold_high; -} - -#else - -static inline uint16_t -ol_txrx_rsrc_threshold_lo(int desc_pool_size) -{ - int threshold_low; /* always maintain a 5% margin of unallocated descriptors */ - threshold_low = (5 * desc_pool_size) / 100; + threshold_low = ((TX_RESOURCE_LOW_TH_IN_PER) * + desc_pool_size) / 100; return threshold_low; } @@ -288,11 +258,11 @@ ol_txrx_rsrc_threshold_hi(int desc_pool_size) /* when freeing up descriptors, keep going until * there's a 15% margin */ - threshold_high = (15 * desc_pool_size) / 100; + threshold_high = ((TX_RESOURCE_HIGH_TH_IN_PER) * + desc_pool_size) / 100; return threshold_high; } -#endif void ol_tx_init_pdev(ol_txrx_pdev_handle pdev) { @@ -492,6 +462,7 @@ int ol_txrx_mgmt_send_frame( * @tx_spec: indicate what non-standard transmission actions to apply * @msdu_list: the tx frames to send * @tx_comp_req: tx completion req + * @call_sched: will schedule the tx if true * * Return: NULL if all MSDUs are accepted */ @@ -500,7 +471,8 @@ ol_tx_hl_base( ol_txrx_vdev_handle vdev, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list, - int tx_comp_req) + int tx_comp_req, + bool call_sched) { struct ol_txrx_pdev_t *pdev = vdev->pdev; qdf_nbuf_t msdu = msdu_list; @@ -544,6 +516,12 @@ ol_tx_hl_base( /* OL_TXRX_PROT_AN_LOG(pdev->prot_an_tx_sent, msdu);*/ + qdf_dp_trace_log_pkt(vdev->vdev_id, msdu, QDF_TX, + QDF_TRACE_DEFAULT_PDEV_ID); + DPTRACE(qdf_dp_trace_data_pkt(msdu, QDF_TRACE_DEFAULT_PDEV_ID, + QDF_DP_TRACE_TX_PACKET_RECORD, + tx_desc->id, QDF_TX)); + if (tx_spec != OL_TX_SPEC_STD) { #if defined(FEATURE_WLAN_TDLS) if (tx_spec & OL_TX_SPEC_NO_FREE) { @@ -573,7 +551,15 @@ ol_tx_hl_base( tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; tx_msdu_info.htt.info.frame_type = htt_frm_type_data; tx_msdu_info.htt.info.l2_hdr_type = pdev->htt_pkt_type; - tx_msdu_info.htt.action.tx_comp_req = tx_comp_req; + + if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(msdu) + == 1) { + tx_msdu_info.htt.action.tx_comp_req = 1; + tx_desc->pkt_type = OL_TX_FRM_NO_FREE; + } else { + tx_msdu_info.htt.action.tx_comp_req = + tx_comp_req; + } /* If the vdev is in OCB mode, * parse the tx control header. @@ -697,20 +683,1007 @@ ol_tx_hl_base( MSDU_LOOP_BOTTOM: msdu = next; } - ol_tx_sched(pdev); + + if (call_sched) + ol_tx_sched(pdev); return NULL; /* all MSDUs were accepted */ } +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + +/** + * ol_tx_pdev_reset_driver_del_ack() - reset driver delayed ack enabled flag + * @soc_hdl: soc handle + * @pdev_id: datapath pdev identifier + * + * Return: none + */ +void +ol_tx_pdev_reset_driver_del_ack(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_vdev_t *vdev; + + if (!pdev) + return; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + vdev->driver_del_ack_enabled = false; + + dp_debug("vdev_id %d driver_del_ack_enabled %d", + vdev->vdev_id, vdev->driver_del_ack_enabled); + } +} + +/** + * ol_tx_vdev_set_driver_del_ack_enable() - set driver delayed ack enabled flag + * @soc_hdl: datapath soc handle + * @vdev_id: vdev id + * @rx_packets: number of rx packets + * @time_in_ms: time in ms + * @high_th: high threshold + * @low_th: low threshold + * + * Return: none + */ +void +ol_tx_vdev_set_driver_del_ack_enable(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + unsigned long rx_packets, + uint32_t time_in_ms, + uint32_t high_th, + uint32_t low_th) +{ + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *) + ol_txrx_get_vdev_from_vdev_id(vdev_id); + bool old_driver_del_ack_enabled; + + if ((!vdev) || (low_th > high_th)) + return; + + old_driver_del_ack_enabled = vdev->driver_del_ack_enabled; + if (rx_packets > high_th) + vdev->driver_del_ack_enabled = true; + else if (rx_packets < low_th) + vdev->driver_del_ack_enabled = false; + + if (old_driver_del_ack_enabled != vdev->driver_del_ack_enabled) { + dp_debug("vdev_id %d driver_del_ack_enabled %d rx_packets %ld time_in_ms %d high_th %d low_th %d", + vdev->vdev_id, vdev->driver_del_ack_enabled, + rx_packets, time_in_ms, high_th, low_th); + } +} + +/** + * ol_tx_hl_send_all_tcp_ack() - send all queued tcp ack packets + * @vdev: vdev handle + * + * Return: none + */ +void ol_tx_hl_send_all_tcp_ack(struct ol_txrx_vdev_t *vdev) +{ + int i; + struct tcp_stream_node *tcp_node_list; + struct tcp_stream_node *temp; + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + for (i = 0; i < OL_TX_HL_DEL_ACK_HASH_SIZE; i++) { + tcp_node_list = NULL; + qdf_spin_lock_bh(&vdev->tcp_ack_hash.node[i].hash_node_lock); + if (vdev->tcp_ack_hash.node[i].no_of_entries) + tcp_node_list = vdev->tcp_ack_hash.node[i].head; + + vdev->tcp_ack_hash.node[i].no_of_entries = 0; + vdev->tcp_ack_hash.node[i].head = NULL; + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.node[i].hash_node_lock); + + /* Send all packets */ + while (tcp_node_list) { + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + qdf_nbuf_t msdu_list; + + temp = tcp_node_list; + tcp_node_list = temp->next; + + msdu_list = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + temp->head, + tx_comp_req, false); + if (msdu_list) + qdf_nbuf_tx_free(msdu_list, 1/*error*/); + ol_txrx_vdev_free_tcp_node(vdev, temp); + } + } + ol_tx_sched(vdev->pdev); +} + +/** + * tcp_del_ack_tasklet() - tasklet function to send ack packets + * @data: vdev handle + * + * Return: none + */ +void tcp_del_ack_tasklet(void *data) +{ + struct ol_txrx_vdev_t *vdev = data; + + ol_tx_hl_send_all_tcp_ack(vdev); +} + +/** + * ol_tx_get_stream_id() - get stream_id from packet info + * @info: packet info + * + * Return: stream_id + */ +uint16_t ol_tx_get_stream_id(struct packet_info *info) +{ + return ((info->dst_port + info->dst_ip + info->src_port + info->src_ip) + & (OL_TX_HL_DEL_ACK_HASH_SIZE - 1)); +} + +/** + * ol_tx_is_tcp_ack() - check whether the packet is tcp ack frame + * @msdu: packet + * + * Return: true if the packet is tcp ack frame + */ +static bool +ol_tx_is_tcp_ack(qdf_nbuf_t msdu) +{ + uint16_t ether_type; + uint8_t protocol; + uint8_t flag, ip_header_len, tcp_header_len; + uint32_t seg_len; + uint8_t *skb_data; + uint32_t skb_len; + bool tcp_acked = false; + uint32_t tcp_header_off; + + qdf_nbuf_peek_header(msdu, &skb_data, &skb_len); + if (skb_len < (QDF_NBUF_TRAC_IPV4_OFFSET + + QDF_NBUF_TRAC_IPV4_HEADER_SIZE + + QDF_NBUF_TRAC_TCP_FLAGS_OFFSET)) + goto exit; + + ether_type = (uint16_t)(*(uint16_t *) + (skb_data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); + protocol = (uint16_t)(*(uint16_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); + + if ((QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE) == ether_type) && + (protocol == QDF_NBUF_TRAC_TCP_TYPE)) { + ip_header_len = ((uint8_t)(*(uint8_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_OFFSET)) & + QDF_NBUF_TRAC_IPV4_HEADER_MASK) << 2; + tcp_header_off = QDF_NBUF_TRAC_IPV4_OFFSET + ip_header_len; + + tcp_header_len = ((uint8_t)(*(uint8_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_HEADER_LEN_OFFSET))) >> 2; + seg_len = skb_len - tcp_header_len - tcp_header_off; + flag = (uint8_t)(*(uint8_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_FLAGS_OFFSET)); + + if ((flag == QDF_NBUF_TRAC_TCP_ACK_MASK) && (seg_len == 0)) + tcp_acked = true; + } + +exit: + + return tcp_acked; +} + +/** + * ol_tx_get_packet_info() - update packet info for passed msdu + * @msdu: packet + * @info: packet info + * + * Return: none + */ +void ol_tx_get_packet_info(qdf_nbuf_t msdu, struct packet_info *info) +{ + uint16_t ether_type; + uint8_t protocol; + uint8_t flag, ip_header_len, tcp_header_len; + uint32_t seg_len; + uint8_t *skb_data; + uint32_t skb_len; + uint32_t tcp_header_off; + + info->type = NO_TCP_PKT; + + qdf_nbuf_peek_header(msdu, &skb_data, &skb_len); + if (skb_len < (QDF_NBUF_TRAC_IPV4_OFFSET + + QDF_NBUF_TRAC_IPV4_HEADER_SIZE + + QDF_NBUF_TRAC_TCP_FLAGS_OFFSET)) + return; + + ether_type = (uint16_t)(*(uint16_t *) + (skb_data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); + protocol = (uint16_t)(*(uint16_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); + + if ((QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE) == ether_type) && + (protocol == QDF_NBUF_TRAC_TCP_TYPE)) { + ip_header_len = ((uint8_t)(*(uint8_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_OFFSET)) & + QDF_NBUF_TRAC_IPV4_HEADER_MASK) << 2; + tcp_header_off = QDF_NBUF_TRAC_IPV4_OFFSET + ip_header_len; + + tcp_header_len = ((uint8_t)(*(uint8_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_HEADER_LEN_OFFSET))) >> 2; + seg_len = skb_len - tcp_header_len - tcp_header_off; + flag = (uint8_t)(*(uint8_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_FLAGS_OFFSET)); + + info->src_ip = QDF_SWAP_U32((uint32_t)(*(uint32_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_SRC_ADDR_OFFSET))); + info->dst_ip = QDF_SWAP_U32((uint32_t)(*(uint32_t *) + (skb_data + QDF_NBUF_TRAC_IPV4_DEST_ADDR_OFFSET))); + info->src_port = QDF_SWAP_U16((uint16_t)(*(uint16_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_SPORT_OFFSET))); + info->dst_port = QDF_SWAP_U16((uint16_t)(*(uint16_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_DPORT_OFFSET))); + info->stream_id = ol_tx_get_stream_id(info); + + if ((flag == QDF_NBUF_TRAC_TCP_ACK_MASK) && (seg_len == 0)) { + info->type = TCP_PKT_ACK; + info->ack_number = (uint32_t)(*(uint32_t *) + (skb_data + tcp_header_off + + QDF_NBUF_TRAC_TCP_ACK_OFFSET)); + info->ack_number = QDF_SWAP_U32(info->ack_number); + } else { + info->type = TCP_PKT_NO_ACK; + } + } +} + +/** + * ol_tx_hl_find_and_send_tcp_stream() - find and send tcp stream for passed + * stream info + * @vdev: vdev handle + * @info: packet info + * + * Return: none + */ +void ol_tx_hl_find_and_send_tcp_stream(struct ol_txrx_vdev_t *vdev, + struct packet_info *info) +{ + uint8_t no_of_entries; + struct tcp_stream_node *node_to_be_remove = NULL; + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + /* remove tcp node from hash */ + qdf_spin_lock_bh(&vdev->tcp_ack_hash.node[info->stream_id]. + hash_node_lock); + + no_of_entries = vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries; + if (no_of_entries > 1) { + /* collision case */ + struct tcp_stream_node *head = + vdev->tcp_ack_hash.node[info->stream_id].head; + struct tcp_stream_node *temp; + + if ((head->dst_ip == info->dst_ip) && + (head->src_ip == info->src_ip) && + (head->src_port == info->src_port) && + (head->dst_port == info->dst_port)) { + node_to_be_remove = head; + vdev->tcp_ack_hash.node[info->stream_id].head = + head->next; + vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries--; + } else { + temp = head; + while (temp->next) { + if ((temp->next->dst_ip == info->dst_ip) && + (temp->next->src_ip == info->src_ip) && + (temp->next->src_port == info->src_port) && + (temp->next->dst_port == info->dst_port)) { + node_to_be_remove = temp->next; + temp->next = temp->next->next; + vdev->tcp_ack_hash. + node[info->stream_id]. + no_of_entries--; + break; + } + temp = temp->next; + } + } + } else if (no_of_entries == 1) { + /* Only one tcp_node */ + node_to_be_remove = + vdev->tcp_ack_hash.node[info->stream_id].head; + vdev->tcp_ack_hash.node[info->stream_id].head = NULL; + vdev->tcp_ack_hash.node[info->stream_id].no_of_entries = 0; + } + qdf_spin_unlock_bh(&vdev->tcp_ack_hash. + node[info->stream_id].hash_node_lock); + + /* send packets */ + if (node_to_be_remove) { + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + qdf_nbuf_t msdu_list; + + msdu_list = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + node_to_be_remove->head, + tx_comp_req, true); + if (msdu_list) + qdf_nbuf_tx_free(msdu_list, 1/*error*/); + ol_txrx_vdev_free_tcp_node(vdev, node_to_be_remove); + } +} + +static struct tcp_stream_node * +ol_tx_hl_rep_tcp_ack(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu, + struct packet_info *info, bool *is_found, + bool *start_timer) +{ + struct tcp_stream_node *node_to_be_remove = NULL; + struct tcp_stream_node *head = + vdev->tcp_ack_hash.node[info->stream_id].head; + struct tcp_stream_node *temp; + + if ((head->dst_ip == info->dst_ip) && + (head->src_ip == info->src_ip) && + (head->src_port == info->src_port) && + (head->dst_port == info->dst_port)) { + *is_found = true; + if ((head->ack_number < info->ack_number) && + (head->no_of_ack_replaced < + ol_cfg_get_del_ack_count_value(vdev->pdev->ctrl_pdev))) { + /* replace ack packet */ + qdf_nbuf_tx_free(head->head, 1); + head->head = msdu; + head->ack_number = info->ack_number; + head->no_of_ack_replaced++; + *start_timer = true; + + vdev->no_of_tcpack_replaced++; + + if (head->no_of_ack_replaced == + ol_cfg_get_del_ack_count_value( + vdev->pdev->ctrl_pdev)) { + node_to_be_remove = head; + vdev->tcp_ack_hash.node[info->stream_id].head = + head->next; + vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries--; + } + } else { + /* append and send packets */ + head->head->next = msdu; + node_to_be_remove = head; + vdev->tcp_ack_hash.node[info->stream_id].head = + head->next; + vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries--; + } + } else { + temp = head; + while (temp->next) { + if ((temp->next->dst_ip == info->dst_ip) && + (temp->next->src_ip == info->src_ip) && + (temp->next->src_port == info->src_port) && + (temp->next->dst_port == info->dst_port)) { + *is_found = true; + if ((temp->next->ack_number < + info->ack_number) && + (temp->next->no_of_ack_replaced < + ol_cfg_get_del_ack_count_value( + vdev->pdev->ctrl_pdev))) { + /* replace ack packet */ + qdf_nbuf_tx_free(temp->next->head, 1); + temp->next->head = msdu; + temp->next->ack_number = + info->ack_number; + temp->next->no_of_ack_replaced++; + *start_timer = true; + + vdev->no_of_tcpack_replaced++; + + if (temp->next->no_of_ack_replaced == + ol_cfg_get_del_ack_count_value( + vdev->pdev->ctrl_pdev)) { + node_to_be_remove = temp->next; + temp->next = temp->next->next; + vdev->tcp_ack_hash. + node[info->stream_id]. + no_of_entries--; + } + } else { + /* append and send packets */ + temp->next->head->next = msdu; + node_to_be_remove = temp->next; + temp->next = temp->next->next; + vdev->tcp_ack_hash. + node[info->stream_id]. + no_of_entries--; + } + break; + } + temp = temp->next; + } + } + return node_to_be_remove; +} + +/** + * ol_tx_hl_find_and_replace_tcp_ack() - find and replace tcp ack packet for + * passed packet info + * @vdev: vdev handle + * @msdu: packet + * @info: packet info + * + * Return: none + */ +void ol_tx_hl_find_and_replace_tcp_ack(struct ol_txrx_vdev_t *vdev, + qdf_nbuf_t msdu, + struct packet_info *info) +{ + uint8_t no_of_entries; + struct tcp_stream_node *node_to_be_remove = NULL; + bool is_found = false, start_timer = false; + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + /* replace ack if required or send packets */ + qdf_spin_lock_bh(&vdev->tcp_ack_hash.node[info->stream_id]. + hash_node_lock); + + no_of_entries = vdev->tcp_ack_hash.node[info->stream_id].no_of_entries; + if (no_of_entries > 0) { + node_to_be_remove = ol_tx_hl_rep_tcp_ack(vdev, msdu, info, + &is_found, + &start_timer); + } + + if (no_of_entries == 0 || !is_found) { + /* Alloc new tcp node */ + struct tcp_stream_node *new_node; + + new_node = ol_txrx_vdev_alloc_tcp_node(vdev); + if (!new_node) { + qdf_spin_unlock_bh(&vdev->tcp_ack_hash. + node[info->stream_id].hash_node_lock); + dp_alert("Malloc failed"); + return; + } + new_node->stream_id = info->stream_id; + new_node->dst_ip = info->dst_ip; + new_node->src_ip = info->src_ip; + new_node->dst_port = info->dst_port; + new_node->src_port = info->src_port; + new_node->ack_number = info->ack_number; + new_node->head = msdu; + new_node->next = NULL; + new_node->no_of_ack_replaced = 0; + + start_timer = true; + /* insert new_node */ + if (!vdev->tcp_ack_hash.node[info->stream_id].head) { + vdev->tcp_ack_hash.node[info->stream_id].head = + new_node; + vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries = 1; + } else { + struct tcp_stream_node *temp = + vdev->tcp_ack_hash.node[info->stream_id].head; + while (temp->next) + temp = temp->next; + + temp->next = new_node; + vdev->tcp_ack_hash.node[info->stream_id]. + no_of_entries++; + } + } + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.node[info->stream_id]. + hash_node_lock); + + /* start timer */ + if (start_timer && + (!qdf_atomic_read(&vdev->tcp_ack_hash.is_timer_running))) { + qdf_hrtimer_start(&vdev->tcp_ack_hash.timer, + qdf_ns_to_ktime(( + ol_cfg_get_del_ack_timer_value( + vdev->pdev->ctrl_pdev) * + 1000000)), + __QDF_HRTIMER_MODE_REL); + qdf_atomic_set(&vdev->tcp_ack_hash.is_timer_running, 1); + } + + /* send packets */ + if (node_to_be_remove) { + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + qdf_nbuf_t msdu_list = NULL; + + msdu_list = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + node_to_be_remove->head, + tx_comp_req, true); + if (msdu_list) + qdf_nbuf_tx_free(msdu_list, 1/*error*/); + ol_txrx_vdev_free_tcp_node(vdev, node_to_be_remove); + } +} + +/** + * ol_tx_hl_vdev_tcp_del_ack_timer() - delayed ack timer function + * @timer: timer handle + * + * Return: enum + */ +enum qdf_hrtimer_restart_status +ol_tx_hl_vdev_tcp_del_ack_timer(qdf_hrtimer_data_t *timer) +{ + struct ol_txrx_vdev_t *vdev = qdf_container_of(timer, + struct ol_txrx_vdev_t, + tcp_ack_hash.timer); + enum qdf_hrtimer_restart_status ret = __QDF_HRTIMER_NORESTART; + + qdf_sched_bh(&vdev->tcp_ack_hash.tcp_del_ack_tq); + qdf_atomic_set(&vdev->tcp_ack_hash.is_timer_running, 0); + return ret; +} + +/** + * ol_tx_hl_del_ack_queue_flush_all() - drop all queued packets + * @vdev: vdev handle + * + * Return: none + */ +void ol_tx_hl_del_ack_queue_flush_all(struct ol_txrx_vdev_t *vdev) +{ + int i; + struct tcp_stream_node *tcp_node_list; + struct tcp_stream_node *temp; + + qdf_hrtimer_cancel(&vdev->tcp_ack_hash.timer); + for (i = 0; i < OL_TX_HL_DEL_ACK_HASH_SIZE; i++) { + tcp_node_list = NULL; + qdf_spin_lock_bh(&vdev->tcp_ack_hash.node[i].hash_node_lock); + + if (vdev->tcp_ack_hash.node[i].no_of_entries) + tcp_node_list = vdev->tcp_ack_hash.node[i].head; + + vdev->tcp_ack_hash.node[i].no_of_entries = 0; + vdev->tcp_ack_hash.node[i].head = NULL; + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.node[i].hash_node_lock); + + /* free all packets */ + while (tcp_node_list) { + temp = tcp_node_list; + tcp_node_list = temp->next; + + qdf_nbuf_tx_free(temp->head, 1/*error*/); + ol_txrx_vdev_free_tcp_node(vdev, temp); + } + } + ol_txrx_vdev_deinit_tcp_del_ack(vdev); +} + +/** + * ol_txrx_vdev_init_tcp_del_ack() - initialize tcp delayed ack structure + * @vdev: vdev handle + * + * Return: none + */ +void ol_txrx_vdev_init_tcp_del_ack(struct ol_txrx_vdev_t *vdev) +{ + int i; + + vdev->driver_del_ack_enabled = false; + + dp_debug("vdev-id=%u, driver_del_ack_enabled=%d", + vdev->vdev_id, + vdev->driver_del_ack_enabled); + + vdev->no_of_tcpack = 0; + vdev->no_of_tcpack_replaced = 0; + + qdf_hrtimer_init(&vdev->tcp_ack_hash.timer, + ol_tx_hl_vdev_tcp_del_ack_timer, + __QDF_CLOCK_MONOTONIC, + __QDF_HRTIMER_MODE_REL, + QDF_CONTEXT_HARDWARE + ); + qdf_create_bh(&vdev->tcp_ack_hash.tcp_del_ack_tq, + tcp_del_ack_tasklet, + vdev); + qdf_atomic_init(&vdev->tcp_ack_hash.is_timer_running); + qdf_atomic_init(&vdev->tcp_ack_hash.tcp_node_in_use_count); + qdf_spinlock_create(&vdev->tcp_ack_hash.tcp_free_list_lock); + vdev->tcp_ack_hash.tcp_free_list = NULL; + for (i = 0; i < OL_TX_HL_DEL_ACK_HASH_SIZE; i++) { + qdf_spinlock_create(&vdev->tcp_ack_hash.node[i].hash_node_lock); + vdev->tcp_ack_hash.node[i].no_of_entries = 0; + vdev->tcp_ack_hash.node[i].head = NULL; + } +} + +/** + * ol_txrx_vdev_deinit_tcp_del_ack() - deinitialize tcp delayed ack structure + * @vdev: vdev handle + * + * Return: none + */ +void ol_txrx_vdev_deinit_tcp_del_ack(struct ol_txrx_vdev_t *vdev) +{ + struct tcp_stream_node *temp; + + qdf_destroy_bh(&vdev->tcp_ack_hash.tcp_del_ack_tq); + + qdf_spin_lock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); + while (vdev->tcp_ack_hash.tcp_free_list) { + temp = vdev->tcp_ack_hash.tcp_free_list; + vdev->tcp_ack_hash.tcp_free_list = temp->next; + qdf_mem_free(temp); + } + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); +} + +/** + * ol_txrx_vdev_free_tcp_node() - add tcp node in free list + * @vdev: vdev handle + * @node: tcp stream node + * + * Return: none + */ +void ol_txrx_vdev_free_tcp_node(struct ol_txrx_vdev_t *vdev, + struct tcp_stream_node *node) +{ + qdf_atomic_dec(&vdev->tcp_ack_hash.tcp_node_in_use_count); + + qdf_spin_lock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); + if (vdev->tcp_ack_hash.tcp_free_list) { + node->next = vdev->tcp_ack_hash.tcp_free_list; + vdev->tcp_ack_hash.tcp_free_list = node; + } else { + vdev->tcp_ack_hash.tcp_free_list = node; + node->next = NULL; + } + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); +} + +/** + * ol_txrx_vdev_alloc_tcp_node() - allocate tcp node + * @vdev: vdev handle + * + * Return: tcp stream node + */ +struct tcp_stream_node *ol_txrx_vdev_alloc_tcp_node(struct ol_txrx_vdev_t *vdev) +{ + struct tcp_stream_node *node = NULL; + + qdf_spin_lock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); + if (vdev->tcp_ack_hash.tcp_free_list) { + node = vdev->tcp_ack_hash.tcp_free_list; + vdev->tcp_ack_hash.tcp_free_list = node->next; + } + qdf_spin_unlock_bh(&vdev->tcp_ack_hash.tcp_free_list_lock); + + if (!node) { + node = qdf_mem_malloc(sizeof(struct ol_txrx_vdev_t)); + if (!node) + return NULL; + } + qdf_atomic_inc(&vdev->tcp_ack_hash.tcp_node_in_use_count); + return node; +} + qdf_nbuf_t ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) { struct ol_txrx_pdev_t *pdev = vdev->pdev; int tx_comp_req = pdev->cfg.default_tx_comp_req || pdev->cfg.request_tx_comp; + struct packet_info pkt_info; + qdf_nbuf_t temp; + + if (ol_tx_is_tcp_ack(msdu_list)) + vdev->no_of_tcpack++; + + /* check Enable through ini */ + if (!ol_cfg_get_del_ack_enable_value(vdev->pdev->ctrl_pdev) || + (!vdev->driver_del_ack_enabled)) { + if (qdf_atomic_read(&vdev->tcp_ack_hash.tcp_node_in_use_count)) + ol_tx_hl_send_all_tcp_ack(vdev); + + return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, + tx_comp_req, true); + } + + ol_tx_get_packet_info(msdu_list, &pkt_info); + + if (pkt_info.type == TCP_PKT_NO_ACK) { + ol_tx_hl_find_and_send_tcp_stream(vdev, &pkt_info); + temp = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, + tx_comp_req, true); + return temp; + } + + if (pkt_info.type == TCP_PKT_ACK) { + ol_tx_hl_find_and_replace_tcp_ack(vdev, msdu_list, &pkt_info); + return NULL; + } + + temp = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, + tx_comp_req, true); + return temp; +} +#else + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +void +ol_tx_pdev_reset_bundle_require(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + struct ol_txrx_vdev_t *vdev; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + vdev->bundling_required = false; + ol_txrx_info("vdev_id %d bundle_require %d\n", + vdev->vdev_id, vdev->bundling_required); + } +} + +void +ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_bytes, + uint32_t time_in_ms, uint32_t high_th, + uint32_t low_th) +{ + struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *) + ol_txrx_get_vdev_from_vdev_id(vdev_id); + bool old_bundle_required; + + if ((!vdev) || (low_th > high_th)) + return; + + old_bundle_required = vdev->bundling_required; + if (tx_bytes > ((high_th * time_in_ms * 1500) / 1000)) + vdev->bundling_required = true; + else if (tx_bytes < ((low_th * time_in_ms * 1500) / 1000)) + vdev->bundling_required = false; + + if (old_bundle_required != vdev->bundling_required) + ol_txrx_info("vdev_id %d bundle_require %d tx_bytes %ld time_in_ms %d high_th %d low_th %d\n", + vdev->vdev_id, vdev->bundling_required, tx_bytes, + time_in_ms, high_th, low_th); +} + +/** + * ol_tx_hl_queue_flush_all() - drop all packets in vdev bundle queue + * @vdev: vdev handle + * + * Return: none + */ +void +ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t *vdev) +{ + qdf_spin_lock_bh(&vdev->bundle_queue.mutex); + if (vdev->bundle_queue.txq.depth != 0) { + qdf_timer_stop(&vdev->bundle_queue.timer); + vdev->pdev->total_bundle_queue_length -= + vdev->bundle_queue.txq.depth; + qdf_nbuf_tx_free(vdev->bundle_queue.txq.head, 1/*error*/); + vdev->bundle_queue.txq.depth = 0; + vdev->bundle_queue.txq.head = NULL; + vdev->bundle_queue.txq.tail = NULL; + } + qdf_spin_unlock_bh(&vdev->bundle_queue.mutex); +} + +/** + * ol_tx_hl_vdev_queue_append() - append pkt in tx queue + * @vdev: vdev handle + * @msdu_list: msdu list + * + * Return: none + */ +static void +ol_tx_hl_vdev_queue_append(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu_list) +{ + qdf_spin_lock_bh(&vdev->bundle_queue.mutex); + + if (!vdev->bundle_queue.txq.head) { + qdf_timer_start( + &vdev->bundle_queue.timer, + ol_cfg_get_bundle_timer_value(vdev->pdev->ctrl_pdev)); + vdev->bundle_queue.txq.head = msdu_list; + vdev->bundle_queue.txq.tail = msdu_list; + } else { + qdf_nbuf_set_next(vdev->bundle_queue.txq.tail, msdu_list); + } + + while (qdf_nbuf_next(msdu_list)) { + vdev->bundle_queue.txq.depth++; + vdev->pdev->total_bundle_queue_length++; + msdu_list = qdf_nbuf_next(msdu_list); + } + + vdev->bundle_queue.txq.depth++; + vdev->pdev->total_bundle_queue_length++; + vdev->bundle_queue.txq.tail = msdu_list; + qdf_spin_unlock_bh(&vdev->bundle_queue.mutex); +} + +/** + * ol_tx_hl_vdev_queue_send_all() - send all packets in vdev bundle queue + * @vdev: vdev handle + * @call_sched: invoke scheduler + * + * Return: NULL for success + */ +static qdf_nbuf_t +ol_tx_hl_vdev_queue_send_all(struct ol_txrx_vdev_t *vdev, bool call_sched, + bool in_timer_context) +{ + qdf_nbuf_t msdu_list = NULL; + qdf_nbuf_t skb_list_head, skb_list_tail; + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + int pkt_to_sent; + + qdf_spin_lock_bh(&vdev->bundle_queue.mutex); + + if (!vdev->bundle_queue.txq.depth) { + qdf_spin_unlock_bh(&vdev->bundle_queue.mutex); + return msdu_list; + } + + if (likely((qdf_atomic_read(&vdev->tx_desc_count) + + vdev->bundle_queue.txq.depth) < + vdev->queue_stop_th)) { + qdf_timer_stop(&vdev->bundle_queue.timer); + vdev->pdev->total_bundle_queue_length -= + vdev->bundle_queue.txq.depth; + msdu_list = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + vdev->bundle_queue.txq.head, + tx_comp_req, call_sched); + vdev->bundle_queue.txq.depth = 0; + vdev->bundle_queue.txq.head = NULL; + vdev->bundle_queue.txq.tail = NULL; + } else { + pkt_to_sent = vdev->queue_stop_th - + qdf_atomic_read(&vdev->tx_desc_count); + + if (pkt_to_sent) { + skb_list_head = vdev->bundle_queue.txq.head; + + while (pkt_to_sent) { + skb_list_tail = + vdev->bundle_queue.txq.head; + vdev->bundle_queue.txq.head = + qdf_nbuf_next(vdev->bundle_queue.txq.head); + vdev->pdev->total_bundle_queue_length--; + vdev->bundle_queue.txq.depth--; + pkt_to_sent--; + if (!vdev->bundle_queue.txq.head) { + qdf_timer_stop( + &vdev->bundle_queue.timer); + break; + } + } + + qdf_nbuf_set_next(skb_list_tail, NULL); + msdu_list = ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + skb_list_head, tx_comp_req, + call_sched); + } - return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, tx_comp_req); + if (in_timer_context && vdev->bundle_queue.txq.head) { + qdf_timer_start( + &vdev->bundle_queue.timer, + ol_cfg_get_bundle_timer_value( + vdev->pdev->ctrl_pdev)); + } + } + qdf_spin_unlock_bh(&vdev->bundle_queue.mutex); + + return msdu_list; } +/** + * ol_tx_hl_pdev_queue_send_all() - send all packets from all vdev bundle queue + * @pdev: pdev handle + * + * Return: NULL for success + */ +qdf_nbuf_t +ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + qdf_nbuf_t msdu_list; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + msdu_list = ol_tx_hl_vdev_queue_send_all(vdev, false, false); + if (msdu_list) + qdf_nbuf_tx_free(msdu_list, 1/*error*/); + } + ol_tx_sched(pdev); + return NULL; /* all msdus were accepted */ +} + +/** + * ol_tx_hl_vdev_bundle_timer() - bundle timer function + * @vdev: vdev handle + * + * Return: none + */ +void +ol_tx_hl_vdev_bundle_timer(void *ctx) +{ + qdf_nbuf_t msdu_list; + struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)ctx; + + vdev->no_of_bundle_sent_in_timer++; + msdu_list = ol_tx_hl_vdev_queue_send_all(vdev, true, true); + if (msdu_list) + qdf_nbuf_tx_free(msdu_list, 1/*error*/); +} + +qdf_nbuf_t +ol_tx_hl(struct ol_txrx_vdev_t *vdev, qdf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + + /* No queuing for high priority packets */ + if (ol_tx_desc_is_high_prio(msdu_list)) { + vdev->no_of_pkt_not_added_in_queue++; + return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, + tx_comp_req, true); + } else if (vdev->bundling_required && + (ol_cfg_get_bundle_size(vdev->pdev->ctrl_pdev) > 1)) { + ol_tx_hl_vdev_queue_append(vdev, msdu_list); + + if (pdev->total_bundle_queue_length >= + ol_cfg_get_bundle_size(vdev->pdev->ctrl_pdev)) { + vdev->no_of_bundle_sent_after_threshold++; + return ol_tx_hl_pdev_queue_send_all(pdev); + } + } else { + if (vdev->bundle_queue.txq.depth != 0) { + ol_tx_hl_vdev_queue_append(vdev, msdu_list); + return ol_tx_hl_vdev_queue_send_all(vdev, true, false); + } else { + vdev->no_of_pkt_not_added_in_queue++; + return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, msdu_list, + tx_comp_req, true); + } + } + + return NULL; /* all msdus were accepted */ +} + +#else + +qdf_nbuf_t +ol_tx_hl(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req || + pdev->cfg.request_tx_comp; + + return ol_tx_hl_base(vdev, OL_TX_SPEC_STD, + msdu_list, tx_comp_req, true); +} +#endif +#endif + qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev, enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) @@ -724,20 +1697,19 @@ qdf_nbuf_t ol_tx_non_std_hl(struct ol_txrx_vdev_t *vdev, (pdev->tx_data_callback.func)) tx_comp_req = 1; } - return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req); + return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req, true); } #ifdef FEATURE_WLAN_TDLS -/** - * ol_txrx_copy_mac_addr_raw() - copy raw mac addr - * @vdev: the data virtual device - * @bss_addr: bss address - * - * Return: None - */ -void ol_txrx_copy_mac_addr_raw(struct cdp_vdev *pvdev, uint8_t *bss_addr) +void ol_txrx_copy_mac_addr_raw(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *bss_addr) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return; qdf_spin_lock_bh(&vdev->pdev->last_real_peer_mutex); if (bss_addr && vdev->last_real_peer && @@ -750,78 +1722,121 @@ void ol_txrx_copy_mac_addr_raw(struct cdp_vdev *pvdev, uint8_t *bss_addr) qdf_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex); } -/** - * ol_txrx_add_last_real_peer() - add last peer - * @pdev: the data physical device - * @vdev: virtual device - * @peer_id: peer id - * - * Return: None - */ void -ol_txrx_add_last_real_peer(struct cdp_pdev *ppdev, - struct cdp_vdev *pvdev, uint8_t *peer_id) +ol_txrx_add_last_real_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); ol_txrx_peer_handle peer; + if (!pdev || !vdev) + return; + peer = ol_txrx_find_peer_by_addr( (struct cdp_pdev *)pdev, - vdev->hl_tdls_ap_mac_addr.raw, - peer_id); + vdev->hl_tdls_ap_mac_addr.raw); qdf_spin_lock_bh(&pdev->last_real_peer_mutex); if (!vdev->last_real_peer && peer && - (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) { vdev->last_real_peer = peer; + qdf_mem_zero(vdev->hl_tdls_ap_mac_addr.raw, + QDF_MAC_ADDR_SIZE); + } qdf_spin_unlock_bh(&pdev->last_real_peer_mutex); } -/** - * is_vdev_restore_last_peer() - check for vdev last peer - * @peer: peer object - * - * Return: true if last peer is not null - */ -bool is_vdev_restore_last_peer(void *ppeer) +bool is_vdev_restore_last_peer(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) { - struct ol_txrx_peer_t *peer = ppeer; - struct ol_txrx_vdev_t *vdev; + struct ol_txrx_peer_t *peer; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return false; + + pdev = vdev->pdev; + peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, peer_mac); - vdev = peer->vdev; return vdev->last_real_peer && (vdev->last_real_peer == peer); } -/** - * ol_txrx_update_last_real_peer() - check for vdev last peer - * @pdev: the data physical device - * @peer: peer device - * @peer_id: peer id - * @restore_last_peer: restore last peer flag - * - * Return: None - */ -void ol_txrx_update_last_real_peer(struct cdp_pdev *ppdev, void *pvdev, - uint8_t *peer_id, bool restore_last_peer) +void ol_txrx_update_last_real_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t vdev_id, bool restore_last_peer) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); struct ol_txrx_peer_t *peer; - if (!restore_last_peer) + if (!restore_last_peer || !pdev || !vdev) return; peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, - vdev->hl_tdls_ap_mac_addr.raw, - peer_id); + vdev->hl_tdls_ap_mac_addr.raw); qdf_spin_lock_bh(&pdev->last_real_peer_mutex); if (!vdev->last_real_peer && peer && - (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) { vdev->last_real_peer = peer; + qdf_mem_zero(vdev->hl_tdls_ap_mac_addr.raw, + QDF_MAC_ADDR_SIZE); + } qdf_spin_unlock_bh(&pdev->last_real_peer_mutex); } + +void ol_txrx_set_peer_as_tdls_peer(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, bool val) +{ + ol_txrx_peer_handle peer; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return; + + pdev = vdev->pdev; + peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, peer_mac); + + ol_txrx_info_high("peer %pK, peer->ref_cnt %d", + peer, qdf_atomic_read(&peer->ref_cnt)); + + /* Mark peer as tdls */ + if (peer) + peer->is_tdls_peer = val; +} + +void ol_txrx_set_tdls_offchan_enabled(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, bool val) +{ + ol_txrx_peer_handle peer; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return; + + pdev = vdev->pdev; + peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, peer_mac); + + ol_txrx_info_high("peer %pK, peer->ref_cnt %d", + peer, qdf_atomic_read(&peer->ref_cnt)); + + /* Set TDLS Offchan operation enable/disable */ + if (peer && peer->is_tdls_peer) + peer->tdls_offchan_enabled = val; +} #endif #if defined(CONFIG_HL_SUPPORT) && defined(DEBUG_HL_LOGGING) @@ -884,15 +1899,23 @@ void ol_txrx_pdev_grp_stat_destroy(struct ol_txrx_pdev_t *pdev) /** * ol_txrx_hl_tdls_flag_reset() - reset tdls flag for vdev - * @vdev: the virtual device object + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @flag: flag * * Return: None */ void -ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *pvdev, bool flag) +ol_txrx_hl_tdls_flag_reset(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + bool flag) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: Invalid vdev_id %d", __func__, vdev_id); + return; + } vdev->hlTdlsFlag = flag; } @@ -1082,10 +2105,14 @@ void ol_txrx_update_tx_queue_groups( */ if (!vdev_bit_mask) { /* Set Group Pointer (vdev and peer) to NULL */ + ol_txrx_info("Group membership removed for vdev_id %d from group_id %d", + vdev->vdev_id, group_id); ol_tx_set_vdev_group_ptr( pdev, vdev->vdev_id, NULL); } else { /* Set Group Pointer (vdev and peer) */ + ol_txrx_info("Group membership updated for vdev_id %d to group_id %d", + vdev->vdev_id, group_id); ol_tx_set_vdev_group_ptr( pdev, vdev->vdev_id, group); } @@ -1093,6 +2120,8 @@ void ol_txrx_update_tx_queue_groups( } /* Update membership */ group->membership = membership; + ol_txrx_info("Group membership updated for group_id %d membership 0x%x", + group_id, group->membership); credit_update: /* Update Credit */ ol_txrx_update_group_credit(group, credit, absolute); @@ -1154,19 +2183,20 @@ int ol_txrx_distribute_group_credits(struct ol_txrx_pdev_t *pdev, */ #ifdef QCA_HL_NETDEV_FLOW_CONTROL -/** - * ol_txrx_register_hl_flow_control() -register hl netdev flow control callback - * @vdev_id: vdev_id - * @flowControl: flow control callback - * - * Return: 0 for success or error code - */ -int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc, +int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, tx_pause_callback flowcontrol) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - u32 desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + u32 desc_pool_size; + + if (!pdev || !flowcontrol) { + ol_txrx_err("pdev or pause_cb is NULL"); + return QDF_STATUS_E_INVAL; + } + desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev); /* * Assert if the tx descriptor pool size meets the requirements * Maximum 2 sessions are allowed on a band. @@ -1175,17 +2205,11 @@ int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc, ol_txrx_tx_desc_alloc_table[TXRX_FC_2GH_40M_2x2]) <= desc_pool_size); - if (!pdev || !flowcontrol) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "pdev or pause_cb is NULL"); - return QDF_STATUS_E_INVAL; - } - pdev->pause_cb = flowcontrol; return 0; } -int ol_txrx_set_vdev_os_queue_status(u8 vdev_id, +int ol_txrx_set_vdev_os_queue_status(struct cdp_soc_t *soc_hdl, u8 vdev_id, enum netif_action_type action) { struct ol_txrx_vdev_t *vdev = @@ -1214,12 +2238,8 @@ int ol_txrx_set_vdev_os_queue_status(u8 vdev_id, return 0; } -/** - * ol_txrx_set_vdev_tx_desc_limit() - Set TX descriptor limits for a vdev - * @vdev_id: vdev id for the vdev under consideration. - * @chan: Channel on which the vdev has been started. - */ -int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan) +int ol_txrx_set_vdev_tx_desc_limit(struct cdp_soc_t *soc_hdl, u8 vdev_id, + u32 chan_freq) { struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); @@ -1233,7 +2253,7 @@ int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan) } /* TODO: Handle no of spatial streams and channel BW */ - if (WLAN_REG_IS_5GHZ_CH(chan)) + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) fc_limit_id = TXRX_FC_5GH_80M_2x2; else fc_limit_id = TXRX_FC_2GH_40M_2x2; @@ -1247,4 +2267,83 @@ int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan) return 0; } + +void ol_tx_dump_flow_pool_info_compact(struct ol_txrx_pdev_t *pdev) +{ + char *comb_log_str; + int bytes_written = 0; + uint32_t free_size; + struct ol_txrx_vdev_t *vdev; + int i = 0; + + free_size = WLAN_MAX_VDEVS * 100; + comb_log_str = qdf_mem_malloc(free_size); + if (!comb_log_str) + return; + + qdf_spin_lock_bh(&pdev->tx_mutex); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + bytes_written += snprintf(&comb_log_str[bytes_written], + free_size, "%d (%d,%d)(%d,%d)(%d,%d) |", + vdev->vdev_id, vdev->tx_desc_limit, + qdf_atomic_read(&vdev->tx_desc_count), + qdf_atomic_read(&vdev->os_q_paused), + vdev->prio_q_paused, vdev->queue_stop_th, + vdev->queue_restart_th); + free_size -= bytes_written; + } + qdf_spin_unlock_bh(&pdev->tx_mutex); + qdf_nofl_debug("STATS | FC: %s", comb_log_str); + + free_size = WLAN_MAX_VDEVS * 100; + bytes_written = 0; + qdf_mem_zero(comb_log_str, free_size); + + bytes_written = snprintf(&comb_log_str[bytes_written], free_size, + "%d ", + qdf_atomic_read(&pdev->target_tx_credit)); + for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) { + bytes_written += snprintf(&comb_log_str[bytes_written], + free_size, "|%d, (0x%x, %d)", i, + OL_TXQ_GROUP_VDEV_ID_MASK_GET( + pdev->txq_grps[i].membership), + qdf_atomic_read( + &pdev->txq_grps[i].credit)); + free_size -= bytes_written; + } + qdf_nofl_debug("STATS | CREDIT: %s", comb_log_str); + qdf_mem_free(comb_log_str); +} + +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; + struct ol_txrx_vdev_t *vdev; + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + + qdf_spin_lock_bh(&pdev->tx_mutex); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + txrx_nofl_info("vdev_id %d", vdev->vdev_id); + txrx_nofl_info("limit %d available %d stop_threshold %d restart_threshold %d", + vdev->tx_desc_limit, + qdf_atomic_read(&vdev->tx_desc_count), + vdev->queue_stop_th, vdev->queue_restart_th); + txrx_nofl_info("q_paused %d prio_q_paused %d", + qdf_atomic_read(&vdev->os_q_paused), + vdev->prio_q_paused); + txrx_nofl_info("no_of_bundle_sent_after_threshold %lld", + vdev->no_of_bundle_sent_after_threshold); + txrx_nofl_info("no_of_bundle_sent_in_timer %lld", + vdev->no_of_bundle_sent_in_timer); + txrx_nofl_info("no_of_pkt_not_added_in_queue %lld", + vdev->no_of_pkt_not_added_in_queue); + } + qdf_spin_unlock_bh(&pdev->tx_mutex); +} #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll.c index 656d4be8fd7654b13bd2b44ee3b8991d25f576e2..6d697ce331f1e5213c4208a1657b816e27c220f5 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,7 +22,7 @@ #include /* qdf_nbuf_t */ #include /* QDF_NBUF_TX_EXT_TID_INVALID */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ #ifdef QCA_COMPUTE_TX_DELAY #include /* ethernet_hdr_t, etc. */ #include /* ipv6_traffic_class */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll_fastpath.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll_fastpath.c index 5fd936fa86c8b4054c70dfb91c1905929842eb69..3c13c1702dfb21260dfcc09ae61a0f8ca6d8ac6b 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll_fastpath.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_ll_fastpath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -48,7 +48,8 @@ #include #include -#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) +#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ + defined(HIF_IPCI) #include #endif @@ -108,7 +109,6 @@ static inline void ol_tx_trace_pkt(qdf_nbuf_t skb, uint16_t msdu_id, qdf_dp_trace_log_pkt(vdev_id, skb, QDF_TX, QDF_TRACE_DEFAULT_PDEV_ID); - qdf_dp_trace_set_track(skb, QDF_TX); DPTRACE(qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID, QDF_DP_TRACE_TX_PACKET_RECORD, msdu_id, QDF_TX)); @@ -383,6 +383,15 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) * pointer before the ce_send call. */ next = qdf_nbuf_next(msdu); + /* + * Increment the skb->users count here, for this SKB, to make + * sure it will be freed only after receiving Tx completion + * of the last segment. + * Decrement skb->users count before sending last segment + */ + if (qdf_nbuf_is_tso(msdu) && segments) + qdf_nbuf_inc_users(msdu); + /* init the current segment to the 1st segment in the list */ while (segments) { if (msdu_info.tso_info.curr_seg) @@ -429,7 +438,8 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) * the skb is freed only after receiving tx * completion for all segments of an nbuf. */ - if (segments) + if (segments != + (msdu_info.tso_info.num_segs - 1)) qdf_nbuf_inc_users(msdu); ol_tx_trace_pkt(msdu, tx_desc->id, @@ -451,6 +461,13 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) next_seg = NULL; } + /* Decrement the skb-users count if segment + * is the last segment or the only segment + */ + if (tx_desc->pkt_type == OL_TX_FRM_TSO && + segments == 0) + qdf_nbuf_tx_free(msdu, 0); + if ((ce_send_fast(pdev->ce_tx_hdl, msdu, ep_id, pkt_download_len) == 0)) { @@ -465,6 +482,12 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) tso_info->curr_seg = next_seg; ol_free_remaining_tso_segs(vdev, &msdu_info, true); + if (segments == + (msdu_info.tso_info.num_segs + - 1)) + qdf_nbuf_tx_free( + msdu, + QDF_NBUF_PKT_ERROR); } /* @@ -491,10 +514,14 @@ ol_tx_ll_fast(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list) * If TSO packet, free associated * remaining TSO segment descriptors */ - if (qdf_nbuf_is_tso(msdu)) + if (qdf_nbuf_is_tso(msdu)) { ol_free_remaining_tso_segs(vdev, &msdu_info, true); - + if (segments == + (msdu_info.tso_info.num_segs - 1)) + qdf_nbuf_tx_free(msdu, + QDF_NBUF_PKT_ERROR); + } TXRX_STATS_MSDU_LIST_INCR( pdev, tx.dropped.host_reject, msdu); /* the list of unaccepted MSDUs */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.c index af5c8f0e86c213292ceca8aa7b3d05d36d5ccf80..55ca3c3eac1536dae65d23eded2895bfde402c90 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.c @@ -68,6 +68,8 @@ ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT]; int i, j, peer_count; + ol_tx_hl_queue_flush_all(vdev); + /* flush VDEV TX queues */ for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { txq = &vdev->txqs[i]; @@ -517,6 +519,25 @@ ol_txrx_peer_tid_unpause_base( } } } + +/** + * ol_txrx_peer_unpause_base() - unpause all txqs for a given peer + * @pdev: the physical device object + * @peer: peer device object + * + * Return: None + */ +static void +ol_txrx_peer_unpause_base( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + int i; + + for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++) + ol_txrx_peer_tid_unpause_base(pdev, peer, i); +} + #ifdef QCA_BAD_PEER_TX_FLOW_CL /** * ol_txrx_peer_unpause_but_no_mgmt_q_base() - unpause all txqs except @@ -564,21 +585,37 @@ ol_txrx_peer_tid_unpause(ol_txrx_peer_handle peer, int tid) } void -ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) +ol_txrx_vdev_pause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + struct ol_txrx_pdev_t *pdev; struct ol_txrx_peer_t *peer; /* TO DO: log the queue pause */ /* acquire the mutex lock, since we'll be modifying the queues */ TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + + pdev = vdev->pdev; /* use peer_ref_mutex before accessing peer_list */ qdf_spin_lock_bh(&pdev->peer_ref_mutex); qdf_spin_lock_bh(&pdev->tx_queue_spinlock); TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { - ol_txrx_peer_pause_base(pdev, peer); + if (pause_type == PAUSE_TYPE_CHOP) { + if (!(peer->is_tdls_peer && peer->tdls_offchan_enabled)) + ol_txrx_peer_pause_base(pdev, peer); + } else if (pause_type == PAUSE_TYPE_CHOP_TDLS_OFFCHAN) { + if (peer->is_tdls_peer && peer->tdls_offchan_enabled) + ol_txrx_peer_pause_base(pdev, peer); + } else { + ol_txrx_peer_pause_base(pdev, peer); + } } qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); qdf_spin_unlock_bh(&pdev->peer_ref_mutex); @@ -586,28 +623,39 @@ ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } - -void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) +void ol_txrx_vdev_unpause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + struct ol_txrx_pdev_t *pdev; struct ol_txrx_peer_t *peer; /* TO DO: log the queue unpause */ /* acquire the mutex lock, since we'll be modifying the queues */ TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + pdev = vdev->pdev; /* take peer_ref_mutex before accessing peer_list */ qdf_spin_lock_bh(&pdev->peer_ref_mutex); qdf_spin_lock_bh(&pdev->tx_queue_spinlock); TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { - int i; - - for (i = 0; i < QDF_ARRAY_SIZE(peer->txqs); i++) - ol_txrx_peer_tid_unpause_base(pdev, peer, i); + if (pause_type == PAUSE_TYPE_CHOP) { + if (!(peer->is_tdls_peer && peer->tdls_offchan_enabled)) + ol_txrx_peer_unpause_base(pdev, peer); + } else if (pause_type == PAUSE_TYPE_CHOP_TDLS_OFFCHAN) { + if (peer->is_tdls_peer && peer->tdls_offchan_enabled) + ol_txrx_peer_unpause_base(pdev, peer); + } else { + ol_txrx_peer_unpause_base(pdev, peer); + } } qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); qdf_spin_unlock_bh(&pdev->peer_ref_mutex); @@ -615,9 +663,18 @@ void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } -void ol_txrx_vdev_flush(struct cdp_vdev *pvdev) +void ol_txrx_vdev_flush(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + + if (!vdev) + return; ol_tx_queue_vdev_flush(vdev->pdev, vdev); } @@ -817,10 +874,11 @@ ol_tx_bad_peer_update_tx_limit(struct ol_txrx_pdev_t *pdev, } void -ol_txrx_bad_peer_txctl_set_setting(struct cdp_pdev *ppdev, +ol_txrx_bad_peer_txctl_set_setting(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, int enable, int period, int txq_limit) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (enable) pdev->tx_peer_bal.enabled = ol_tx_peer_bal_enable; @@ -833,11 +891,12 @@ ol_txrx_bad_peer_txctl_set_setting(struct cdp_pdev *ppdev, } void -ol_txrx_bad_peer_txctl_update_threshold(struct cdp_pdev *ppdev, - int level, int tput_thresh, - int tx_limit) +ol_txrx_bad_peer_txctl_update_threshold(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int level, + int tput_thresh, int tx_limit) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); /* Set the current settingl */ pdev->tx_peer_bal.ctl_thresh[level].tput_thresh = @@ -1277,11 +1336,11 @@ ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset) if (peer) QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Q: %6d %5d %3d %4d ("QDF_MAC_ADDR_STR")", + "Q: %6d %5d %3d %4d ("QDF_MAC_ADDR_FMT")", record.num_frms, record.num_bytes, record.tid, record.peer_id, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); else QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1311,11 +1370,11 @@ ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset) if (peer) QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "DQ: %6d %5d %3d %4d ("QDF_MAC_ADDR_STR")", + "DQ: %6d %5d %3d %4d ("QDF_MAC_ADDR_FMT")", record.num_frms, record.num_bytes, record.tid, record.peer_id, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); else QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1345,11 +1404,11 @@ ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset) if (peer) QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "F: %6d %5d %3d %4d ("QDF_MAC_ADDR_STR")", + "F: %6d %5d %3d %4d ("QDF_MAC_ADDR_FMT")", record.num_frms, record.num_bytes, record.tid, record.peer_id, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); else QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1683,9 +1742,8 @@ void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *pdev, uint32_t reason) struct ol_txrx_vdev_t *vdev = NULL, *tmp; TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { - cdp_fc_vdev_pause( - cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_vdev *)vdev, reason); + cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC), + vdev->vdev_id, reason, 0); } } @@ -1703,7 +1761,7 @@ void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason) TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_vdev *)vdev, reason); + vdev->vdev_id, reason, 0); } } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.h index a5e7fbef728c54d8bd78f7e6bc59170f799fd20d..0688cb4e9bdb49ac7f06ae3347dbed29c4a221b7 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -229,18 +229,65 @@ ol_tx_queue_discard( #if (!defined(QCA_LL_LEGACY_TX_FLOW_CONTROL)) && (!defined(CONFIG_HL_SUPPORT)) static inline -void ol_txrx_vdev_flush(struct cdp_vdev *data_vdev) +void ol_txrx_vdev_flush(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { } #else -void ol_txrx_vdev_flush(struct cdp_vdev *pvdev); +/** + * ol_txrx_vdev_flush() - Drop all tx data for the specified virtual device + * @soc_hdl: soc handle + * @vdev_id: vdev id + * + * Returns: none + * + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + * This function would typically be used by the ctrl SW after it parks + * a STA vdev and then resumes it, but to a new AP. In this case, though + * the same vdev can be used, any old tx frames queued inside it would be + * stale, and would need to be discarded. + */ +void ol_txrx_vdev_flush(struct cdp_soc_t *soc_hdl, uint8_t vdev_id); #endif #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \ (defined(QCA_LL_TX_FLOW_CONTROL_V2)) || \ defined(CONFIG_HL_SUPPORT) -void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason); -void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason); +/** + * ol_txrx_vdev_pause- Suspend all tx data for the specified virtual device + * soc_hdl: Datapath soc handle + * @vdev_id: id of vdev + * @reason: the reason for which vdev queue is getting paused + * @pause_type: type of pause + * + * Return: none + * + * This function applies primarily to HL systems, but also + * applies to LL systems that use per-vdev tx queues for MCC or + * thermal throttling. As an example, this function could be + * used when a single-channel physical device supports multiple + * channels by jumping back and forth between the channels in a + * time-shared manner. As the device is switched from channel A + * to channel B, the virtual devices that operate on channel A + * will be paused. + */ +void ol_txrx_vdev_pause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type); + +/** + * ol_txrx_vdev_unpause - Resume tx for the specified virtual device + * soc_hdl: Datapath soc handle + * @vdev_id: id of vdev being unpaused + * @reason: the reason for which vdev queue is getting unpaused + * @pause_type: type of pause + * + * Return: none + * + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + */ +void ol_txrx_vdev_unpause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type); #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ #if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) @@ -434,8 +481,10 @@ ol_tx_queues_display(struct ol_txrx_pdev_t *pdev) #define ol_tx_queue_decs_reinit(peer, peer_id) /* no-op */ #ifdef QCA_SUPPORT_TX_THROTTLE -void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level); -void ol_tx_throttle_init_period(struct cdp_pdev *ppdev, int period, +void ol_tx_throttle_set_level(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int level); +void ol_tx_throttle_init_period(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int period, uint8_t *dutycycle_level); /** @@ -446,21 +495,23 @@ void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev); #else static inline void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev) {} -static inline void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level) +static inline void ol_tx_throttle_set_level(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int level) {} -static inline void ol_tx_throttle_init_period(struct cdp_pdev *ppdev, - int period, - uint8_t *dutycycle_level) +static inline void +ol_tx_throttle_init_period(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + int period, uint8_t *dutycycle_level) {} #endif #ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL + static inline bool -ol_tx_is_txq_last_serviced_queue(struct ol_txrx_pdev_t *pdev, - struct ol_tx_frms_queue_t *txq) +ol_tx_if_iterate_next_txq(struct ol_tx_frms_queue_t *first, + struct ol_tx_frms_queue_t *txq) { - return txq == pdev->tx_sched.last_used_txq; + return (first != txq); } /** @@ -540,8 +591,8 @@ ol_tx_set_peer_group_ptr( #else static inline bool -ol_tx_is_txq_last_serviced_queue(struct ol_txrx_pdev_t *pdev, - struct ol_tx_frms_queue_t *txq) +ol_tx_if_iterate_next_txq(struct ol_tx_frms_queue_t *first, + struct ol_tx_frms_queue_t *txq) { return 0; } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.c index aa4acf7c2d938375e3ade4d9e8d2c8b942480169..ec2742c79c359681209daf7560414015b3a05311 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.c @@ -427,7 +427,7 @@ ol_tx_sched_init_rr( } void -ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev, +ol_txrx_set_wmm_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct ol_tx_wmm_param_t wmm_param) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW, @@ -686,7 +686,6 @@ ol_tx_sched_select_init_wrr_adv(struct ol_txrx_pdev_t *pdev) struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; /* start selection from the front of the ordered list */ scheduler->index = 0; - pdev->tx_sched.last_used_txq = NULL; } static void @@ -738,11 +737,12 @@ ol_tx_sched_select_batch_wrr_adv( static int first = 1; int category_index = 0; struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; - struct ol_tx_frms_queue_t *txq; + struct ol_tx_frms_queue_t *txq, *first_txq = NULL; int index; struct ol_tx_sched_wrr_adv_category_info_t *category = NULL; int frames, bytes, used_credits = 0, tx_limit; u_int16_t tx_limit_flag; + u32 credit_rem = credit; /* * Just for good measure, do a sanity check that the initial credit @@ -813,17 +813,11 @@ ol_tx_sched_select_batch_wrr_adv( */ txq = TAILQ_FIRST(&category->state.head); - if (txq) { + while (txq) { TAILQ_REMOVE(&category->state.head, txq, list_elem); credit = ol_tx_txq_group_credit_limit(pdev, txq, credit); if (credit > category->specs.credit_reserve) { credit -= category->specs.credit_reserve; - /* - * this tx queue will download some frames, - * so update last_used_txq - */ - pdev->tx_sched.last_used_txq = txq; - tx_limit = ol_tx_bad_peer_dequeue_check(txq, category->specs.send_limit, &tx_limit_flag); @@ -852,33 +846,31 @@ ol_tx_sched_select_batch_wrr_adv( } sctx->frms += frames; ol_tx_txq_group_credit_update(pdev, txq, -credit, 0); + break; } else { - if (ol_tx_is_txq_last_serviced_queue(pdev, txq)) { - /* - * The scheduler has looked at all the active - * tx queues but none were able to download any - * of their tx frames. - * Nothing is changed, so if none were able - * to download before, - * they wont be able to download now. - * Return that no credit has been used, which - * will cause the scheduler to stop. - */ + /* + * Current txq belongs to a group which does not have + * enough credits, + * Iterate over to next txq and see if we can download + * packets from that queue. + */ + if (ol_tx_if_iterate_next_txq(first_txq, txq)) { + credit = credit_rem; + if (!first_txq) + first_txq = txq; + + TAILQ_INSERT_TAIL(&category->state.head, + txq, list_elem); + + txq = TAILQ_FIRST(&category->state.head); + } else { TAILQ_INSERT_HEAD(&category->state.head, txq, - list_elem); - return 0; - } - TAILQ_INSERT_TAIL(&category->state.head, txq, list_elem); - if (!pdev->tx_sched.last_used_txq) - pdev->tx_sched.last_used_txq = txq; + break; + } } - TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); - } else { - used_credits = 0; - /* TODO: find its reason */ - ol_txrx_err("Error, no TXQ can be popped"); - } + } /* while(txq) */ + return used_credits; } @@ -1116,10 +1108,12 @@ ol_tx_sched_init_wrr_adv( * settings of the scheduler, ie. VO, VI, BE, or BK. */ void -ol_txrx_set_wmm_param(struct cdp_pdev *pdev, +ol_txrx_set_wmm_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct ol_tx_wmm_param_t wmm_param) { - struct ol_txrx_pdev_t *data_pdev = (struct ol_txrx_pdev_t *)pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle data_pdev = + ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); struct ol_tx_sched_wrr_adv_t def_cfg; struct ol_tx_sched_wrr_adv_t *scheduler = data_pdev->tx_sched.scheduler; @@ -1447,7 +1441,50 @@ ol_tx_sched_dispatch( TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } - void +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT +static void replenish_tx_pad_credit(struct ol_txrx_pdev_t *pdev) +{ + int replenish_credit = 0, avail_targ_tx_credit = 0; + int cur_tx_pad_credit = 0, grp_credit = 0, i = 0; + qdf_atomic_t *tx_grp_credit = NULL; + + cur_tx_pad_credit = qdf_atomic_read(&pdev->pad_reserve_tx_credit); + if (cur_tx_pad_credit < MIN_TX_PAD_CREDIT_THRESH) { + replenish_credit = MAX_TX_PAD_CREDIT_THRESH - cur_tx_pad_credit; + avail_targ_tx_credit = qdf_atomic_read(&pdev->target_tx_credit); + replenish_credit = (replenish_credit < avail_targ_tx_credit) ? + replenish_credit : avail_targ_tx_credit; + if (replenish_credit < 0) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL, + "Tx Pad Credits = %d Target Tx Credits = %d", + cur_tx_pad_credit, + avail_targ_tx_credit); + qdf_assert(0); + } + qdf_atomic_add(replenish_credit, &pdev->pad_reserve_tx_credit); + qdf_atomic_add(-replenish_credit, &pdev->target_tx_credit); + + while (replenish_credit > 0) { + for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) { + tx_grp_credit = &pdev->txq_grps[i].credit; + grp_credit = qdf_atomic_read(tx_grp_credit); + if (grp_credit) { + qdf_atomic_add(-1, tx_grp_credit); + replenish_credit--; + } + if (!replenish_credit) + break; + } + } + } +} +#else +static void replenish_tx_pad_credit(struct ol_txrx_pdev_t *pdev) +{ +} +#endif + +void ol_tx_sched(struct ol_txrx_pdev_t *pdev) { struct ol_tx_sched_ctx sctx; @@ -1466,6 +1503,7 @@ ol_tx_sched(struct ol_txrx_pdev_t *pdev) *adf_os_print("BEFORE tx sched:\n"); *ol_tx_queues_display(pdev); */ + replenish_tx_pad_credit(pdev); qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); TAILQ_INIT(&sctx.head); @@ -1476,6 +1514,7 @@ ol_tx_sched(struct ol_txrx_pdev_t *pdev) int num_credits; qdf_spin_lock_bh(&pdev->tx_queue_spinlock); + replenish_tx_pad_credit(pdev); credit = qdf_atomic_read(&pdev->target_tx_credit); num_credits = ol_tx_sched_select_batch(pdev, &sctx, credit); if (num_credits > 0) { @@ -1487,6 +1526,13 @@ ol_tx_sched(struct ol_txrx_pdev_t *pdev) qdf_atomic_read(&pdev->target_tx_credit) - num_credits); #endif + DPTRACE(qdf_dp_trace_credit_record(QDF_TX_SCHED, + QDF_CREDIT_DEC, num_credits, + qdf_atomic_read(&pdev->target_tx_credit) - + num_credits, + qdf_atomic_read(&pdev->txq_grps[0].credit), + qdf_atomic_read(&pdev->txq_grps[1].credit))); + qdf_atomic_add(-num_credits, &pdev->target_tx_credit); } qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.h index 75b554e0846fb16b2b19b59968d73492cfadd928..51987d701b95240124db15b7c7b6db9041c5f252 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_sched.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -74,7 +74,7 @@ void ol_tx_sched_cur_state_display(struct ol_txrx_pdev_t *pdev); void ol_tx_sched_stats_clear(struct ol_txrx_pdev_t *pdev); void -ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev, +ol_txrx_set_wmm_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct ol_tx_wmm_param_t wmm_param); #else @@ -157,6 +157,14 @@ static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev, { ol_tx_target_credit_adjust(1, pdev, msdu); } + +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT + +#define MIN_TX_PAD_CREDIT_THRESH 4 +#define MAX_TX_PAD_CREDIT_THRESH 5 + +#endif /* QCA_TX_PADDING_CREDIT_SUPPORT */ + #else /* * LL does not need to keep track of target credit. @@ -180,5 +188,6 @@ static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev, qdf_nbuf_t msdu) { } + #endif #endif /* _OL_TX_SCHED__H_ */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.c index 1203a0d38cfbcfd47456e7b55bfe96ac969c3a0a..3ae328107c3e500b466d11a9a380d1f2b4cc55ec 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -22,7 +22,7 @@ #include /* qdf_nbuf_t */ #include /* QDF_NBUF_TX_EXT_TID_INVALID */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ #ifdef QCA_COMPUTE_TX_DELAY #include /* ethernet_hdr_t, etc. */ #include /* ipv6_traffic_class */ @@ -53,7 +53,7 @@ #include #include #include -#include + #ifdef TX_CREDIT_RECLAIM_SUPPORT #define OL_TX_CREDIT_RECLAIM(pdev) \ @@ -120,6 +120,7 @@ static inline void ol_tx_desc_update_comp_ts(struct ol_tx_desc_t *tx_desc) void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev) { struct ol_txrx_vdev_t *vdev; + bool trigger_unpause = false; qdf_spin_lock_bh(&pdev->tx_mutex); TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { @@ -143,9 +144,12 @@ void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev) WLAN_WAKE_NON_PRIORITY_QUEUE, WLAN_DATA_FLOW_CONTROL); qdf_atomic_set(&vdev->os_q_paused, 0); + trigger_unpause = true; } } qdf_spin_unlock_bh(&pdev->tx_mutex); + if (trigger_unpause) + ol_tx_hl_pdev_queue_send_all(pdev); } #endif @@ -259,11 +263,12 @@ ol_tx_send_nonstd(struct ol_txrx_pdev_t *pdev, } } -static inline void +static inline bool ol_tx_download_done_base(struct ol_txrx_pdev_t *pdev, A_STATUS status, qdf_nbuf_t msdu, uint16_t msdu_id) { struct ol_tx_desc_t *tx_desc; + bool is_frame_freed = false; tx_desc = ol_tx_desc_find(pdev, msdu_id); qdf_assert(tx_desc); @@ -286,6 +291,7 @@ ol_tx_download_done_base(struct ol_txrx_pdev_t *pdev, ol_tx_target_credit_incr(pdev, msdu); ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* download err */); + is_frame_freed = true; } else { if (OL_TX_DESC_NO_REFS(tx_desc)) { /* @@ -296,8 +302,10 @@ ol_tx_download_done_base(struct ol_txrx_pdev_t *pdev, ol_tx_desc_frame_free_nonstd(pdev, tx_desc, tx_desc->status != htt_tx_status_ok); + is_frame_freed = true; } } + return is_frame_freed; } void @@ -324,11 +332,27 @@ ol_tx_download_done_hl_free(void *txrx_pdev, { struct ol_txrx_pdev_t *pdev = txrx_pdev; struct ol_tx_desc_t *tx_desc; + bool is_frame_freed; tx_desc = ol_tx_desc_find(pdev, msdu_id); qdf_assert(tx_desc); - ol_tx_download_done_base(pdev, status, msdu, msdu_id); + DPTRACE(qdf_dp_trace_ptr(msdu, + QDF_DP_TRACE_FREE_PACKET_PTR_RECORD, + QDF_TRACE_DEFAULT_PDEV_ID, + qdf_nbuf_data_addr(msdu), + sizeof(qdf_nbuf_data(msdu)), tx_desc->id, + status)); + + is_frame_freed = ol_tx_download_done_base(pdev, status, msdu, msdu_id); + + /* + * if frame is freed in ol_tx_download_done_base then return. + */ + if (is_frame_freed) { + qdf_atomic_add(1, &pdev->tx_queue.rsrc_cnt); + return; + } if ((tx_desc->pkt_type != OL_TX_FRM_NO_FREE) && (tx_desc->pkt_type < OL_TXRX_MGMT_TYPE_BASE)) { @@ -368,6 +392,26 @@ ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev, } #endif /* QCA_COMPUTE_TX_DELAY */ +#if defined(CONFIG_HL_SUPPORT) +int ol_tx_deduct_one_credit(struct ol_txrx_pdev_t *pdev) +{ + /* TODO: Check if enough credits */ + + if (!pdev->cfg.default_tx_comp_req) { + ol_tx_target_credit_update(pdev, -1); + ol_tx_deduct_one_any_group_credit(pdev); + + DPTRACE(qdf_dp_trace_credit_record(QDF_TX_HTT_MSG, + QDF_CREDIT_DEC, 1, + qdf_atomic_read(&pdev->target_tx_credit), + qdf_atomic_read(&pdev->txq_grps[0].credit), + qdf_atomic_read(&pdev->txq_grps[1].credit))); + } + + return 0; +} +#endif /* CONFIG_HL_SUPPORT */ + #ifndef OL_TX_RESTORE_HDR #define OL_TX_RESTORE_HDR(__tx_desc, __msdu) #endif @@ -560,151 +604,6 @@ void ol_tx_flow_pool_unlock(struct ol_tx_desc_t *tx_desc) } #endif -#ifdef WLAN_FEATURE_PKT_CAPTURE -#define RESERVE_BYTES 100 -/** - * ol_tx_pkt_capture_tx_completion_process(): process tx packets - * for pkt capture mode - * @pdev: device handler - * @tx_desc: tx desc - * @payload: tx data header - * @tid: tid number - * @status: Tx status - * - * Return: none - */ -static void -ol_tx_pkt_capture_tx_completion_process( - ol_txrx_pdev_handle pdev, - struct ol_tx_desc_t *tx_desc, - struct htt_tx_data_hdr_information *payload_hdr, - uint8_t tid, uint8_t status) -{ - qdf_nbuf_t netbuf; - int nbuf_len; - struct qdf_tso_seg_elem_t *tso_seg = NULL; - struct ol_txrx_peer_t *peer; - uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint8_t pkt_type = 0; - - qdf_assert(tx_desc); - - ol_tx_flow_pool_lock(tx_desc); - /* - * In cases when vdev has gone down and tx completion - * are received, leads to NULL vdev access. - * So, check for NULL before dereferencing it. - */ - if (!tx_desc->vdev) { - ol_tx_flow_pool_unlock(tx_desc); - return; - } - - ol_tx_flow_pool_unlock(tx_desc); - - if (tx_desc->pkt_type == OL_TX_FRM_TSO) { - if (!tx_desc->tso_desc) - return; - - tso_seg = tx_desc->tso_desc; - nbuf_len = tso_seg->seg.total_len; - } else { - int i, extra_frag_len = 0; - - i = QDF_NBUF_CB_TX_NUM_EXTRA_FRAGS(tx_desc->netbuf); - if (i > 0) - extra_frag_len = - QDF_NBUF_CB_TX_EXTRA_FRAG_LEN(tx_desc->netbuf); - nbuf_len = qdf_nbuf_len(tx_desc->netbuf) - extra_frag_len; - } - - qdf_spin_lock_bh(&pdev->peer_ref_mutex); - peer = TAILQ_FIRST(&tx_desc->vdev->peer_list); - qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - if (!peer) - return; - - qdf_spin_lock_bh(&peer->peer_info_lock); - qdf_mem_copy(bssid, &peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); - qdf_spin_unlock_bh(&peer->peer_info_lock); - - netbuf = qdf_nbuf_alloc(NULL, - roundup(nbuf_len + RESERVE_BYTES, 4), - RESERVE_BYTES, 4, false); - if (!netbuf) - return; - - qdf_nbuf_put_tail(netbuf, nbuf_len); - - if (tx_desc->pkt_type == OL_TX_FRM_TSO) { - uint8_t frag_cnt, num_frags = 0; - int frag_len = 0; - uint32_t tcp_seq_num; - uint16_t ip_len; - - qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex); - - if (tso_seg->seg.num_frags > 0) - num_frags = tso_seg->seg.num_frags - 1; - - /*Num of frags in a tso seg cannot be less than 2 */ - if (num_frags < 1) { - qdf_print("ERROR: num of frags in tso segment is %d\n", - (num_frags + 1)); - qdf_nbuf_free(netbuf); - qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); - return; - } - - tcp_seq_num = tso_seg->seg.tso_flags.tcp_seq_num; - tcp_seq_num = qdf_cpu_to_be32(tcp_seq_num); - - ip_len = tso_seg->seg.tso_flags.ip_len; - ip_len = qdf_cpu_to_be16(ip_len); - - for (frag_cnt = 0; frag_cnt < num_frags; frag_cnt++) { - qdf_mem_copy(qdf_nbuf_data(netbuf) + frag_len, - tso_seg->seg.tso_frags[frag_cnt].vaddr, - tso_seg->seg.tso_frags[frag_cnt].length); - frag_len += tso_seg->seg.tso_frags[frag_cnt].length; - } - - qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); - - qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_PKT_LEN_OFFSET), - &ip_len, sizeof(ip_len)); - qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_TCP_SEQ_NUM_OFFSET), - &tcp_seq_num, sizeof(tcp_seq_num)); - } else { - qdf_mem_copy(qdf_nbuf_data(netbuf), - qdf_nbuf_data(tx_desc->netbuf), - nbuf_len); - } - - qdf_nbuf_push_head( - netbuf, - sizeof(struct htt_tx_data_hdr_information)); - qdf_mem_copy(qdf_nbuf_data(netbuf), payload_hdr, - sizeof(struct htt_tx_data_hdr_information)); - - ucfg_pkt_capture_tx_completion_process( - tx_desc->vdev_id, - netbuf, pkt_type, - tid, status, - TXRX_PKTCAPTURE_PKT_FORMAT_8023, bssid, - pdev->htt_pdev, payload_hdr->tx_retry_cnt); -} -#else -static void -ol_tx_pkt_capture_tx_completion_process( - ol_txrx_pdev_handle pdev, - struct ol_tx_desc_t *tx_desc, - struct htt_tx_data_hdr_information *payload_hdr, - uint8_t tid, uint8_t status) -{ -} -#endif /* WLAN_FEATURE_PKT_CAPTURE */ - #ifdef WLAN_FEATURE_TSF_PLUS static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps( u_int32_t *msg_word_header, u_int32_t **msg_word_payload, @@ -960,7 +859,6 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, uint32_t is_tx_desc_freed = 0; struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL; struct htt_tx_compl_ind_append_tx_tsf64 *txtstamp64_list = NULL; - struct htt_tx_data_hdr_information *pkt_capture_txcomp_hdr_list = NULL; u_int32_t *msg_word_header = (u_int32_t *)msg; /*msg_word skip header*/ u_int32_t *msg_word_payload = msg_word_header + 1; @@ -970,12 +868,9 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, union ol_tx_desc_list_elem_t *tx_desc_last = NULL; ol_tx_desc_list tx_descs; uint64_t tx_tsf64; - uint8_t tid; TAILQ_INIT(&tx_descs); - tid = HTT_TX_COMPL_IND_TID_GET(*msg_word); - ol_tx_delay_compute(pdev, status, desc_ids, num_msdus); if (status == htt_tx_status_ok) { txtstamp_list = ol_tx_get_txtstamps( @@ -985,13 +880,6 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, msg_word_header, &msg_word_payload, num_msdus); } - if ((ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_DATA_ONLY)) - pkt_capture_txcomp_hdr_list = - ucfg_pkt_capture_tx_get_txcomplete_data_hdr( - msg_word, - num_msdus); - for (i = 0; i < num_msdus; i++) { tx_desc_id = desc_ids[i]; if (tx_desc_id >= pdev->tx_desc.pool_size) { @@ -1017,14 +905,6 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, (u_int64_t)txtstamp_list->timestamp[i] ); - if (pkt_capture_txcomp_hdr_list) { - ol_tx_pkt_capture_tx_completion_process( - pdev, - tx_desc, - &pkt_capture_txcomp_hdr_list[i], - tid, status); - } - QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE); if (QDF_NBUF_CB_GET_PACKET_TYPE(netbuf) == @@ -1047,8 +927,8 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, if (tx_desc->pkt_type != OL_TX_FRM_TSO) { packetdump_cb = pdev->ol_tx_packetdump_cb; if (packetdump_cb) - packetdump_cb(soc, - (struct cdp_vdev *)tx_desc->vdev, + packetdump_cb(soc, pdev->id, + tx_desc->vdev_id, netbuf, status, TX_DATA_PKT); } #endif @@ -1153,6 +1033,22 @@ void ol_tx_desc_update_group_credit(ol_txrx_pdev_handle pdev, ol_tx_update_group_credit_stats(pdev); } +void ol_tx_deduct_one_any_group_credit(ol_txrx_pdev_handle pdev) +{ + int credits_group_0, credits_group_1; + + qdf_spin_lock_bh(&pdev->tx_queue_spinlock); + credits_group_0 = qdf_atomic_read(&pdev->txq_grps[0].credit); + credits_group_1 = qdf_atomic_read(&pdev->txq_grps[1].credit); + + if (credits_group_0 > credits_group_1) + ol_txrx_update_group_credit(&pdev->txq_grps[0], -1, 0); + else if (credits_group_1 != 0) + ol_txrx_update_group_credit(&pdev->txq_grps[1], -1, 0); + + qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); +} + #ifdef DEBUG_HL_LOGGING void ol_tx_update_group_credit_stats(ol_txrx_pdev_handle pdev) @@ -1184,7 +1080,8 @@ void ol_tx_dump_group_credit_stats(ol_txrx_pdev_handle pdev) { uint16_t i, j, is_break = 0; int16_t curr_index, old_index, wrap_around; - uint16_t curr_credit, old_credit, mem_vdevs; + uint16_t curr_credit, mem_vdevs; + uint16_t old_credit = 0; txrx_nofl_info("Group credit stats:"); txrx_nofl_info(" No: GrpID: Credit: Change: vdev_map"); @@ -1289,7 +1186,7 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev, #if !defined(REMOVE_PKT_LOG) packetdump_cb = pdev->ol_tx_packetdump_cb; if (packetdump_cb) - packetdump_cb(soc, (struct cdp_vdev *)tx_desc->vdev, + packetdump_cb(soc, pdev->id, tx_desc->vdev_id, netbuf, status, TX_MGMT_PKT); #endif @@ -1411,36 +1308,56 @@ ol_tx_inspect_handler(ol_txrx_pdev_handle pdev, #ifdef QCA_COMPUTE_TX_DELAY /** - * @brief updates the compute interval period for TSM stats. - * @details - * @param interval - interval for stats computation + * ol_tx_set_compute_interval - updates the compute interval + * period for TSM stats. + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * @param interval: interval for stats computation + * + * Return: None */ -void ol_tx_set_compute_interval(struct cdp_pdev *ppdev, uint32_t interval) +void ol_tx_set_compute_interval(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint32_t interval) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } pdev->tx_delay.avg_period_ticks = qdf_system_msecs_to_ticks(interval); } /** - * @brief Return the uplink (transmitted) packet count and loss count. - * @details + * ol_tx_packet_count() - Return the uplink (transmitted) packet count + and loss count. + * @soc_hdl: soc handle + * @pdev_id: pdev identifier + * @out_packet_count - number of packets transmitted + * @out_packet_loss_count - number of packets lost + * @category - access category of interest + * * This function will be called for getting uplink packet count and * loss count for given stream (access category) a regular interval. * This also resets the counters hence, the value returned is packets * counted in last 5(default) second interval. These counter are * incremented per access category in ol_tx_completion_handler() - * - * @param category - access category of interest - * @param out_packet_count - number of packets transmitted - * @param out_packet_loss_count - number of packets lost */ void -ol_tx_packet_count(struct cdp_pdev *ppdev, +ol_tx_packet_count(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint16_t *out_packet_count, uint16_t *out_packet_loss_count, int category) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + *out_packet_count = pdev->packet_count[category]; *out_packet_loss_count = pdev->packet_loss_count[category]; pdev->packet_count[category] = 0; @@ -1465,17 +1382,23 @@ static uint32_t ol_tx_delay_avg(uint64_t sum, uint32_t num) } void -ol_tx_delay(struct cdp_pdev *ppdev, +ol_tx_delay(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint32_t *queue_delay_microsec, uint32_t *tx_delay_microsec, int category) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int index; uint32_t avg_delay_ticks; struct ol_tx_delay_data *data; qdf_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + qdf_spin_lock_bh(&pdev->tx_delay.mutex); index = 1 - pdev->tx_delay.cats[category].in_progress_idx; @@ -1512,15 +1435,21 @@ ol_tx_delay(struct cdp_pdev *ppdev, } void -ol_tx_delay_hist(struct cdp_pdev *ppdev, +ol_tx_delay_hist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint16_t *report_bin_values, int category) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int index, i, j; struct ol_tx_delay_data *data; qdf_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + qdf_spin_lock_bh(&pdev->tx_delay.mutex); index = 1 - pdev->tx_delay.cats[category].in_progress_idx; @@ -1731,8 +1660,15 @@ ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev, #ifdef WLAN_FEATURE_TSF_PLUS void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return; @@ -1742,8 +1678,10 @@ void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb) void ol_deregister_timestamp_callback(void) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return; diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.h index 666c5ee30cfd5fc5435cf2d898299f58d650abf0..a3e84ab61c0b955d7c9f9845cd26985155ebfdf3 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_send.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -86,16 +86,19 @@ ol_tx_send_nonstd(struct ol_txrx_pdev_t *pdev, #ifdef QCA_COMPUTE_TX_DELAY /** * ol_tx_set_compute_interval() - update compute interval period for TSM stats - * @ppdev: physical device instance + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @interval: interval for stats computation * * Return: NONE */ -void ol_tx_set_compute_interval(struct cdp_pdev *ppdev, uint32_t interval); +void ol_tx_set_compute_interval(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint32_t interval); /** * ol_tx_packet_count() - Return the uplink (transmitted) packet counts - * @ppdev: physical device instance + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @out_packet_count: number of packets transmitted * @out_packet_loss_count: number of packets lost * @category: access category of interest @@ -109,13 +112,14 @@ void ol_tx_set_compute_interval(struct cdp_pdev *ppdev, uint32_t interval); * Return: NONE */ void -ol_tx_packet_count(struct cdp_pdev *ppdev, +ol_tx_packet_count(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint16_t *out_packet_count, uint16_t *out_packet_loss_count, int category); /** * ol_tx_delay() - get tx packet delay - * @ppdev: physical device instance + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @queue_delay_microsec: tx packet delay within queue, usec * @tx_delay_microsec: tx packet delay, usec * @category: packet category @@ -123,31 +127,34 @@ ol_tx_packet_count(struct cdp_pdev *ppdev, * Return: NONE */ void -ol_tx_delay(struct cdp_pdev *ppdev, +ol_tx_delay(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint32_t *queue_delay_microsec, uint32_t *tx_delay_microsec, int category); /** * ol_tx_delay_hist() - get tx packet delay histogram - * @ppdev: physical device instance + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @report_bin_values: bin * @category: packet category * * Return: NONE */ void -ol_tx_delay_hist(struct cdp_pdev *ppdev, +ol_tx_delay_hist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint16_t *report_bin_values, int category); #endif /* QCA_COMPUTE_TX_DELAY */ /** * ol_txrx_flow_control_cb() - call osif flow control callback - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @tx_resume: tx resume flag * * Return: none */ -void ol_txrx_flow_control_cb(struct cdp_vdev *vdev, bool tx_resume); +void ol_txrx_flow_control_cb(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + bool tx_resume); #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || (defined(CONFIG_HL_SUPPORT) && \ defined(QCA_HL_NETDEV_FLOW_CONTROL)) diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_throttle.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_throttle.c index c639877fca7f1b78058c144bec8a1348c75e0928..42ca4acb46555688ea6e16e09d5c21ca436ae0fb 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_throttle.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_tx_throttle.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -196,9 +196,11 @@ ol_tx_set_throttle_phase_time(struct ol_txrx_pdev_t *pdev, int level, int *ms) } #endif -void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level) +void ol_tx_throttle_set_level(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int level) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int ms = 0; if (level >= THROTTLE_LEVEL_MAX) { @@ -206,6 +208,11 @@ void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level) return; } + if (qdf_unlikely(!pdev)) { + ol_txrx_err("pdev is NULL"); + return; + } + ol_txrx_info("Setting throttle level %d\n", level); /* Set the current throttle level */ @@ -217,12 +224,25 @@ void ol_tx_throttle_set_level(struct cdp_pdev *ppdev, int level) qdf_timer_start(&pdev->tx_throttle.phase_timer, ms); } -void ol_tx_throttle_init_period(struct cdp_pdev *ppdev, int period, +void ol_tx_throttle_init_period(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, int period, uint8_t *dutycycle_level) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; int i; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + if (qdf_unlikely(!pdev)) { + ol_txrx_err("pdev is NULL"); + return; + } + /* Set the current throttle level */ pdev->tx_throttle.throttle_period_ms = period; @@ -260,7 +280,7 @@ void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev) dutycycle_level[i] = ol_cfg_throttle_duty_cycle_level(pdev->ctrl_pdev, i); - ol_tx_throttle_init_period((struct cdp_pdev *)pdev, + ol_tx_throttle_init_period(cds_get_context(QDF_MODULE_ID_SOC), pdev->id, throttle_period, &dutycycle_level[0]); qdf_timer_init(pdev->osdev, &pdev->tx_throttle.phase_timer, diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c index 08677154e0d54211c1bc53465565661854e82702..8466148dcaa82bd7b0d4d5a2cab6dc396f11beff 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,7 +27,7 @@ #include /* header files for utilities */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ /* header files for configuration API */ #include /* ol_cfg_is_high_latency */ @@ -61,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -75,13 +77,17 @@ #include "epping_main.h" #include #include +#include #include "wlan_qct_sys.h" #include #include #include "wlan_roam_debug.h" #include "cfg_ucfg_api.h" - +#ifdef DP_SUPPORT_RECOVERY_NOTIFY +#include +#include +#endif #define DPT_DEBUGFS_PERMS (QDF_FILE_USR_READ | \ QDF_FILE_USR_WRITE | \ @@ -103,32 +109,103 @@ enum dpt_set_param_debugfs { DPT_SET_PARAM_MAX, }; -QDF_STATUS ol_txrx_peer_state_update(struct cdp_pdev *pdev, - uint8_t *peer_mac, - enum ol_txrx_peer_state state); -static void ol_vdev_rx_set_intrabss_fwd(struct cdp_vdev *vdev, - bool val); -int ol_txrx_get_tx_pending(struct cdp_pdev *pdev_handle); +static void ol_vdev_rx_set_intrabss_fwd(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool val); +uint32_t ol_txrx_get_tx_pending(struct cdp_pdev *pdev_handle); extern void -ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev, +ol_txrx_set_wmm_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct ol_tx_wmm_param_t wmm_param); -extern void ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid, - uint64_t **last_pn, uint32_t **rmf_pn_replays); - /* thresh for peer's cached buf queue beyond which the elements are dropped */ #define OL_TXRX_CACHED_BUFQ_THRESH 128 +#ifdef DP_SUPPORT_RECOVERY_NOTIFY +static +int ol_peer_recovery_notifier_cb(struct notifier_block *block, + unsigned long state, void *data) +{ + struct qdf_notifer_data *notif_data = data; + qdf_notif_block *notif_block; + struct ol_txrx_peer_t *peer; + struct peer_hang_data hang_data = {0}; + enum peer_debug_id_type dbg_id; + + if (!data || !block) + return -EINVAL; + + notif_block = qdf_container_of(block, qdf_notif_block, notif_block); + + peer = notif_block->priv_data; + if (!peer) + return -EINVAL; + + if (notif_data->offset + sizeof(struct peer_hang_data) > + QDF_WLAN_HANG_FW_OFFSET) + return NOTIFY_STOP_MASK; + + QDF_HANG_EVT_SET_HDR(&hang_data.tlv_header, + HANG_EVT_TAG_DP_PEER_INFO, + QDF_HANG_GET_STRUCT_TLVLEN(struct peer_hang_data)); + + qdf_mem_copy(&hang_data.peer_mac_addr, &peer->mac_addr.raw, + QDF_MAC_ADDR_SIZE); + + for (dbg_id = 0; dbg_id < PEER_DEBUG_ID_MAX; dbg_id++) + if (qdf_atomic_read(&peer->access_list[dbg_id])) + hang_data.peer_timeout_bitmask |= (1 << dbg_id); + + qdf_mem_copy(notif_data->hang_data + notif_data->offset, + &hang_data, sizeof(struct peer_hang_data)); + notif_data->offset += sizeof(struct peer_hang_data); + + return 0; +} + +static qdf_notif_block ol_peer_recovery_notifier = { + .notif_block.notifier_call = ol_peer_recovery_notifier_cb, +}; + +static +QDF_STATUS ol_register_peer_recovery_notifier(struct ol_txrx_peer_t *peer) +{ + ol_peer_recovery_notifier.priv_data = peer; + + return qdf_hang_event_register_notifier(&ol_peer_recovery_notifier); +} + +static +QDF_STATUS ol_unregister_peer_recovery_notifier(void) +{ + return qdf_hang_event_unregister_notifier(&ol_peer_recovery_notifier); +} +#else +static inline +QDF_STATUS ol_register_peer_recovery_notifier(struct ol_txrx_peer_t *peer) +{ + return QDF_STATUS_SUCCESS; +} + +static +QDF_STATUS ol_unregister_peer_recovery_notifier(void) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * ol_tx_mark_first_wakeup_packet() - set flag to indicate that * fw is compatible for marking first packet after wow wakeup + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @value: 1 for enabled/ 0 for disabled * * Return: None */ -static void ol_tx_mark_first_wakeup_packet(uint8_t value) +static void ol_tx_mark_first_wakeup_packet(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t value) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { ol_txrx_err("pdev is NULL"); @@ -147,12 +224,20 @@ static void ol_tx_mark_first_wakeup_packet(uint8_t value) */ void ol_tx_set_is_mgmt_over_wmi_enabled(uint8_t value) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { - qdf_print("pdev is NULL"); + ol_txrx_err("pdev is NULL"); return; } + pdev->is_mgmt_over_wmi_enabled = value; } @@ -163,12 +248,20 @@ void ol_tx_set_is_mgmt_over_wmi_enabled(uint8_t value) */ uint8_t ol_tx_get_is_mgmt_over_wmi_enabled(void) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return 0; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { - qdf_print("pdev is NULL"); + ol_txrx_err("pdev is NULL"); return 0; } + return pdev->is_mgmt_over_wmi_enabled; } @@ -176,7 +269,7 @@ uint8_t ol_tx_get_is_mgmt_over_wmi_enabled(void) #ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID static void * ol_txrx_find_peer_by_addr_and_vdev(struct cdp_pdev *ppdev, - struct cdp_vdev *pvdev, uint8_t *peer_addr, uint8_t *peer_id) + struct cdp_vdev *pvdev, uint8_t *peer_addr) { struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; @@ -185,14 +278,30 @@ ol_txrx_find_peer_by_addr_and_vdev(struct cdp_pdev *ppdev, peer = ol_txrx_peer_vdev_find_hash(pdev, vdev, peer_addr, 0, 1); if (!peer) return NULL; - *peer_id = peer->local_id; ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); return peer; } -static QDF_STATUS ol_txrx_get_vdevid(void *ppeer, uint8_t *vdev_id) -{ - struct ol_txrx_peer_t *peer = ppeer; +/** + * ol_txrx_get_vdevid() - Get virtual interface id which peer registered + * @soc_hdl - data path soc handle + * @peer_mac - peer mac address + * @vdev_id - virtual interface id which peer registered + * + * Get virtual interface id which peer registered + * + * Return: QDF_STATUS_SUCCESS registration success + * QDF_STATUS_E_NOSUPPORT not support this feature + */ +static QDF_STATUS ol_txrx_get_vdevid(struct cdp_soc_t *soc_hdl, + uint8_t *peer_mac, uint8_t *vdev_id) +{ + uint8_t pdev_id = OL_TXRX_PDEV_ID; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_peer_t *peer = + ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac, 0, 1, + PEER_DEBUG_ID_OL_INTERNAL); if (!peer) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -201,41 +310,149 @@ static QDF_STATUS ol_txrx_get_vdevid(void *ppeer, uint8_t *vdev_id) } *vdev_id = peer->vdev->vdev_id; + ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); + return QDF_STATUS_SUCCESS; } -static struct cdp_vdev *ol_txrx_get_vdev_by_sta_id(struct cdp_pdev *ppdev, - uint8_t sta_id) +ol_txrx_vdev_handle +ol_txrx_get_vdev_by_peer_addr(struct cdp_pdev *ppdev, + struct qdf_mac_addr peer_addr) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_pdev_t *pdev = cdp_pdev_to_ol_txrx_pdev_t(ppdev); struct ol_txrx_peer_t *peer = NULL; ol_txrx_vdev_handle vdev; if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "PDEV not found for sta_id [%d]", sta_id); + "PDEV not found for peer_addr: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr.bytes)); return NULL; } - peer = ol_txrx_peer_get_ref_by_local_id((struct cdp_pdev *)pdev, sta_id, - PEER_DEBUG_ID_OL_INTERNAL); + peer = ol_txrx_peer_get_ref_by_addr(pdev, peer_addr.bytes, + PEER_DEBUG_ID_OL_INTERNAL); + if (!peer) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "PEER [%d] not found", sta_id); + "PDEV not found for peer_addr:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr.bytes)); return NULL; } vdev = peer->vdev; ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); - return (struct cdp_vdev *)vdev; + return vdev; +} + +/** + * ol_txrx_wrapper_get_vdev_by_peer_addr() - Get vdev handle by peer mac address + * @ppdev - data path device instance + * @peer_addr - peer mac address + * + * Get virtual interface handle by local peer mac address + * + * Return: Virtual interface instance handle + * NULL in case cannot find + */ +static struct cdp_vdev * +ol_txrx_wrapper_get_vdev_by_peer_addr(struct cdp_pdev *ppdev, + struct qdf_mac_addr peer_addr) +{ + return (struct cdp_vdev *)ol_txrx_get_vdev_by_peer_addr(ppdev, + peer_addr); +} + +/* + * ol_txrx_find_peer_exist - find peer if already exists + * @soc_hdl: datapath soc handle + * @pdev_id: physical device instance id + * @peer_mac_addr: peer mac address + * + * Return: true or false + */ +static bool ol_txrx_find_peer_exist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint8_t *peer_addr) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) + return false; + + return !!ol_txrx_find_peer_by_addr(ol_txrx_pdev_t_to_cdp_pdev(pdev), + peer_addr); +} + +/* + * ol_txrx_find_peer_exist_on_vdev - find if duplicate peer exists + * on the given vdev + * @soc_hdl: datapath soc handle + * @vdev_id: vdev instance id + * @peer_mac_addr: peer mac address + * + * Return: true or false + */ +static bool ol_txrx_find_peer_exist_on_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_addr) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return false; + + return !!ol_txrx_find_peer_by_addr_and_vdev( + ol_txrx_pdev_t_to_cdp_pdev(vdev->pdev), + ol_txrx_vdev_t_to_cdp_vdev(vdev), + peer_addr); +} + +/* + * ol_txrx_find_peer_exist_on_other_vdev - find if duplicate peer exists + * on other than the given vdev + * @soc_hdl: datapath soc handle + * @vdev_id: vdev instance id + * @peer_mac_addr: peer mac address + * @max_bssid: max number of bssids + * + * Return: true or false + */ +static bool ol_txrx_find_peer_exist_on_other_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_addr, + uint16_t max_bssid) +{ + int i; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_vdev_t *vdev; + + for (i = 0; i < max_bssid; i++) { + vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, i); + /* Need to check vdevs other than the vdev_id */ + if (vdev_id == i || !vdev) + continue; + if (ol_txrx_find_peer_by_addr_and_vdev( + ol_txrx_pdev_t_to_cdp_pdev(vdev->pdev), + ol_txrx_vdev_t_to_cdp_vdev(vdev), + peer_addr)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s: Duplicate peer "QDF_MAC_ADDR_FMT" already exist on vdev %d", + __func__, QDF_MAC_ADDR_REF(peer_addr), i); + return true; + } + } + + return false; } /** * ol_txrx_find_peer_by_addr() - find peer via peer mac addr and peer_id * @ppdev: pointer of type cdp_pdev * @peer_addr: peer mac addr - * @peer_id: pointer to fill in the value of peer->local_id for caller * * This function finds a peer with given mac address and returns its peer_id. * Note that this function does not increment the peer->ref_cnt. @@ -245,8 +462,7 @@ static struct cdp_vdev *ol_txrx_get_vdev_by_sta_id(struct cdp_pdev *ppdev, * Return: peer handle if peer is found, NULL if peer is not found. */ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *ppdev, - uint8_t *peer_addr, - uint8_t *peer_id) + uint8_t *peer_addr) { struct ol_txrx_peer_t *peer; struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; @@ -255,7 +471,6 @@ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *ppdev, PEER_DEBUG_ID_OL_INTERNAL); if (!peer) return NULL; - *peer_id = peer->local_id; ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); return peer; } @@ -264,7 +479,6 @@ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *ppdev, * ol_txrx_peer_get_ref_by_addr() - get peer ref via peer mac addr and peer_id * @pdev: pointer of type ol_txrx_pdev_handle * @peer_addr: peer mac addr - * @peer_id: pointer to fill in the value of peer->local_id for caller * * This function finds the peer with given mac address and returns its peer_id. * Note that this function increments the peer->ref_cnt. @@ -286,7 +500,6 @@ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *ppdev, */ ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev, u8 *peer_addr, - u8 *peer_id, enum peer_debug_id_type dbg_id) { struct ol_txrx_peer_t *peer; @@ -295,45 +508,7 @@ ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev, dbg_id); if (!peer) return NULL; - *peer_id = peer->local_id; - return peer; -} - -static uint16_t ol_txrx_local_peer_id(void *ppeer) -{ - ol_txrx_peer_handle peer = ppeer; - - return peer->local_id; -} - -/** - * @brief Find a txrx peer handle from a peer's local ID - * @details - * The control SW typically uses the txrx peer handle to refer to the peer. - * In unusual circumstances, if it is infeasible for the control SW maintain - * the txrx peer handle but it can maintain a small integer local peer ID, - * this function allows the peer handled to be retrieved, based on the local - * peer ID. - * - * @param pdev - the data physical device object - * @param local_peer_id - the ID txrx assigned locally to the peer in question - * @return handle to the txrx peer object - */ -ol_txrx_peer_handle -ol_txrx_peer_find_by_local_id(struct cdp_pdev *ppdev, - uint8_t local_peer_id) -{ - struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - - if ((local_peer_id == OL_TXRX_INVALID_LOCAL_PEER_ID) || - (local_peer_id >= OL_TXRX_NUM_LOCAL_PEER_IDS)) { - return NULL; - } - qdf_spin_lock_bh(&pdev->local_peer_ids.lock); - peer = pdev->local_peer_ids.map[local_peer_id]; - qdf_spin_unlock_bh(&pdev->local_peer_ids.lock); return peer; } @@ -677,25 +852,32 @@ static inline void ol_txrx_debugfs_exit(ol_txrx_pdev_handle pdev) /** * ol_txrx_pdev_attach() - allocate txrx pdev - * @ctrl_pdev: cfg pdev + * @soc_hdl: datapath soc handle * @htc_pdev: HTC pdev * @osdev: os dev + * @pdev_id: pdev identifier for pdev attach * - * Return: txrx pdev handle - * NULL for failure + * Return: QDF_STATUS_SUCCESS on success + * QDF error code for failure */ -static struct cdp_pdev * +static QDF_STATUS ol_txrx_pdev_attach(ol_txrx_soc_handle soc, - struct cdp_ctrl_objmgr_pdev *ctrl_pdev, HTC_HANDLE htc_pdev, qdf_device_t osdev, uint8_t pdev_id) { + struct ol_txrx_soc_t *ol_soc = cdp_soc_t_to_ol_txrx_soc_t(soc); struct ol_txrx_pdev_t *pdev; - struct cdp_cfg *cfg_pdev = (struct cdp_cfg *)ctrl_pdev; + struct cdp_cfg *cfg_pdev = cds_get_context(QDF_MODULE_ID_CFG); + QDF_STATUS status; int i, tid; + if (pdev_id == OL_TXRX_INVALID_PDEV_ID) + return QDF_STATUS_E_INVAL; + pdev = qdf_mem_malloc(sizeof(*pdev)); - if (!pdev) + if (!pdev) { + status = QDF_STATUS_E_NOMEM; goto fail0; + } /* init LL/HL cfg here */ pdev->cfg.is_high_latency = ol_cfg_is_high_latency(cfg_pdev); @@ -715,6 +897,9 @@ ol_txrx_pdev_attach(ol_txrx_soc_handle soc, /* store provided params */ pdev->ctrl_pdev = cfg_pdev; pdev->osdev = osdev; + pdev->id = pdev_id; + pdev->soc = ol_soc; + ol_soc->pdev_list[pdev_id] = pdev; for (i = 0; i < htt_num_sec_types; i++) pdev->sec_types[i] = (enum ol_sec_type)i; @@ -731,26 +916,34 @@ ol_txrx_pdev_attach(ol_txrx_soc_handle soc, qdf_spinlock_create(&pdev->tx_mutex); /* do initial set up of the peer ID -> peer object lookup map */ - if (ol_txrx_peer_find_attach(pdev)) + if (ol_txrx_peer_find_attach(pdev)) { + status = QDF_STATUS_E_FAILURE; goto fail1; + } /* initialize the counter of the target's tx buffer availability */ qdf_atomic_init(&pdev->target_tx_credit); qdf_atomic_init(&pdev->orig_target_tx_credit); + qdf_atomic_init(&pdev->pad_reserve_tx_credit); + qdf_atomic_add(1, &pdev->pad_reserve_tx_credit); if (ol_cfg_is_high_latency(cfg_pdev)) { qdf_spinlock_create(&pdev->tx_queue_spinlock); pdev->tx_sched.scheduler = ol_tx_sched_attach(pdev); - if (!pdev->tx_sched.scheduler) + if (!pdev->tx_sched.scheduler) { + status = QDF_STATUS_E_FAILURE; goto fail2; + } } ol_txrx_pdev_txq_log_init(pdev); ol_txrx_pdev_grp_stats_init(pdev); pdev->htt_pdev = htt_pdev_alloc(pdev, cfg_pdev, htc_pdev, osdev); - if (!pdev->htt_pdev) + if (!pdev->htt_pdev) { + status = QDF_STATUS_E_FAILURE; goto fail3; + } htt_register_rx_pkt_dump_callback(pdev->htt_pdev, ol_rx_pkt_dump_call); @@ -786,7 +979,7 @@ ol_txrx_pdev_attach(ol_txrx_soc_handle soc, ol_txrx_debugfs_init(pdev); - return (struct cdp_pdev *)pdev; + return QDF_STATUS_SUCCESS; fail3: ol_txrx_peer_find_detach(pdev); @@ -796,26 +989,30 @@ ol_txrx_pdev_attach(ol_txrx_soc_handle soc, qdf_spinlock_destroy(&pdev->tx_queue_spinlock); fail1: + qdf_spinlock_destroy(&pdev->req_list_spinlock); qdf_spinlock_destroy(&pdev->tx_mutex); ol_txrx_tso_stats_deinit(pdev); ol_txrx_fw_stats_desc_pool_deinit(pdev); qdf_mem_free(pdev); fail0: - return NULL; + return status; } #if !defined(REMOVE_PKT_LOG) && !defined(QVIT) /** * htt_pkt_log_init() - API to initialize packet log - * @handle: pdev handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @scn: HIF context * * Return: void */ -void htt_pkt_log_init(struct cdp_pdev *ppdev, void *scn) +void htt_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn) { - struct ol_txrx_pdev_t *handle = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle handle = + ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (handle->pkt_log_init) return; @@ -823,6 +1020,7 @@ void htt_pkt_log_init(struct cdp_pdev *ppdev, void *scn) if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && !QDF_IS_EPPING_ENABLED(cds_get_conparam())) { pktlog_sethandle(&handle->pl_dev, scn); + pktlog_set_pdev_id(handle->pl_dev, pdev_id); pktlog_set_callback_regtype(PKTLOG_DEFAULT_CALLBACK_REGISTRATION); if (pktlogmod_init(scn)) qdf_print(" pktlogmod_init failed"); @@ -849,34 +1047,69 @@ static void htt_pktlogmod_exit(struct ol_txrx_pdev_t *handle) } #else -void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *ol_sc) { } +void htt_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev, void *scn) { } static void htt_pktlogmod_exit(ol_txrx_pdev_handle handle) { } #endif +#ifdef QCA_LL_PDEV_TX_FLOW_CONTROL /** - * ol_txrx_pdev_post_attach() - attach txrx pdev + * ol_txrx_pdev_set_threshold() - set pdev pool stop/start threshold * @pdev: txrx pdev * + * Return: void + */ +static void ol_txrx_pdev_set_threshold(struct ol_txrx_pdev_t *pdev) +{ + uint32_t stop_threshold; + uint32_t start_threshold; + uint16_t desc_pool_size = pdev->tx_desc.pool_size; + + stop_threshold = ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev); + start_threshold = stop_threshold + + ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev); + pdev->tx_desc.start_th = (start_threshold * desc_pool_size) / 100; + pdev->tx_desc.stop_th = (stop_threshold * desc_pool_size) / 100; + pdev->tx_desc.stop_priority_th = + (TX_PRIORITY_TH * pdev->tx_desc.stop_th) / 100; + if (pdev->tx_desc.stop_priority_th >= MAX_TSO_SEGMENT_DESC) + pdev->tx_desc.stop_priority_th -= MAX_TSO_SEGMENT_DESC; + + pdev->tx_desc.start_priority_th = + (TX_PRIORITY_TH * pdev->tx_desc.start_th) / 100; + if (pdev->tx_desc.start_priority_th >= MAX_TSO_SEGMENT_DESC) + pdev->tx_desc.start_priority_th -= MAX_TSO_SEGMENT_DESC; + pdev->tx_desc.status = FLOW_POOL_ACTIVE_UNPAUSED; +} +#else +static inline void ol_txrx_pdev_set_threshold(struct ol_txrx_pdev_t *pdev) +{ +} +#endif + +/** + * ol_txrx_pdev_post_attach() - attach txrx pdev + * @soc_hdl: datapath soc handle + * @pdev_id: physical device instance id + * * Return: 0 for success */ int -ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev) +ol_txrx_pdev_post_attach(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; uint16_t i; uint16_t fail_idx = 0; int ret = 0; uint16_t desc_pool_size; struct hif_opaque_softc *osc = cds_get_context(QDF_MODULE_ID_HIF); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); uint16_t desc_element_size = sizeof(union ol_tx_desc_list_elem_t); union ol_tx_desc_list_elem_t *c_element; unsigned int sig_bit; uint16_t desc_per_page; - uint32_t stop_threshold; - uint32_t start_threshold; - if (!osc) { + if (!osc || !pdev) { ret = -EINVAL; goto ol_attach_fail; } @@ -1018,21 +1251,7 @@ ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev) (uint32_t *)pdev->tx_desc.freelist, (uint32_t *)(pdev->tx_desc.freelist + desc_pool_size)); - stop_threshold = ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev); - start_threshold = stop_threshold + - ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev); - pdev->tx_desc.start_th = (start_threshold * desc_pool_size) / 100; - pdev->tx_desc.stop_th = (stop_threshold * desc_pool_size) / 100; - pdev->tx_desc.stop_priority_th = - (TX_PRIORITY_TH * pdev->tx_desc.stop_th) / 100; - if (pdev->tx_desc.stop_priority_th >= MAX_TSO_SEGMENT_DESC) - pdev->tx_desc.stop_priority_th -= MAX_TSO_SEGMENT_DESC; - - pdev->tx_desc.start_priority_th = - (TX_PRIORITY_TH * pdev->tx_desc.start_th) / 100; - if (pdev->tx_desc.start_priority_th >= MAX_TSO_SEGMENT_DESC) - pdev->tx_desc.start_priority_th -= MAX_TSO_SEGMENT_DESC; - pdev->tx_desc.status = FLOW_POOL_ACTIVE_UNPAUSED; + ol_txrx_pdev_set_threshold(pdev); /* check what format of frames are expected to be delivered by the OS */ pdev->frame_format = ol_cfg_frame_type(pdev->ctrl_pdev); @@ -1364,7 +1583,8 @@ ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev) /** * ol_txrx_pdev_attach_target() - send target configuration * - * @pdev - the physical device being initialized + * @soc_hdl - data path soc handle + * @pdev_id - device instance id * * The majority of the data SW setup are done by the pdev_attach * functions, but this function completes the data SW setup by @@ -1372,9 +1592,14 @@ ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev) * * Return: 0 - success 1 - failure */ -static int ol_txrx_pdev_attach_target(struct cdp_pdev *ppdev) +static int ol_txrx_pdev_attach_target(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) + return QDF_STATUS_E_FAULT; return htt_attach_target(pdev->htt_pdev) == QDF_STATUS_SUCCESS ? 0:1; } @@ -1425,7 +1650,8 @@ static void ol_tx_free_descs_inuse(ol_txrx_pdev_handle pdev) /** * ol_txrx_pdev_pre_detach() - detach the data SW state - * @pdev - the data physical device object being removed + * @soc_hdl - datapath soc handle + * @pdev_id - the data physical device id being removed * @force - delete the pdev (and its vdevs and peers) even if * there are outstanding references by the target to the vdevs * and peers within the pdev @@ -1433,11 +1659,14 @@ static void ol_tx_free_descs_inuse(ol_txrx_pdev_handle pdev) * This function is used when the WLAN driver is being removed to * detach the host data component within the driver. * - * Return: None + * Return: none */ -static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force) +static void ol_txrx_pdev_pre_detach(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + int force) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); /* preconditions */ TXRX_ASSERT2(pdev); @@ -1474,7 +1703,7 @@ static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force) } /* to get flow pool status before freeing descs */ - ol_tx_dump_flow_pool_info((void *)pdev); + ol_tx_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC)); ol_tx_free_descs_inuse(pdev); ol_tx_deregister_flow_control(pdev); @@ -1529,11 +1758,14 @@ static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force) #ifdef QCA_COMPUTE_TX_DELAY qdf_spinlock_destroy(&pdev->tx_delay.mutex); #endif + + return; } /** * ol_txrx_pdev_detach() - delete the data SW state - * @ppdev - the data physical device object being removed + * @soc_hdl - data path soc handle + * @pdev_id - device instance id * @force - delete the pdev (and its vdevs and peers) even if * there are outstanding references by the target to the vdevs * and peers within the pdev @@ -1543,18 +1775,26 @@ static void ol_txrx_pdev_pre_detach(struct cdp_pdev *ppdev, int force) * All virtual devices within the physical device need to be deleted * (ol_txrx_vdev_detach) before the physical device itself is deleted. * - * Return: None + * Return: Success or Failure */ -static void ol_txrx_pdev_detach(struct cdp_pdev *ppdev, int force) +static QDF_STATUS ol_txrx_pdev_detach(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + int force) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); struct ol_txrx_stats_req_internal *req, *temp_req; int i = 0; + if (!soc) { + ol_txrx_err("soc is NULL"); + return QDF_STATUS_E_FAILURE; + } + /*checking to ensure txrx pdev structure is not NULL */ if (!pdev) { ol_txrx_err("pdev is NULL"); - return; + return QDF_STATUS_E_FAILURE; } qdf_spin_lock_bh(&pdev->req_list_spinlock); @@ -1598,8 +1838,12 @@ static void ol_txrx_pdev_detach(struct cdp_pdev *ppdev, int force) ol_txrx_pdev_grp_stat_destroy(pdev); ol_txrx_debugfs_exit(pdev); + ol_unregister_peer_recovery_notifier(); + soc->pdev_list[pdev->id] = NULL; qdf_mem_free(pdev); + + return QDF_STATUS_SUCCESS; } #if defined(QCA_HL_NETDEV_FLOW_CONTROL) @@ -1632,22 +1876,27 @@ ol_txrx_vdev_per_vdev_tx_desc_init(struct ol_txrx_vdev_t *vdev) * ol_txrx_vdev_attach - Allocate and initialize the data object * for a new virtual device. * - * @data_pdev - the physical device the virtual device belongs to + * @@soc_hdl - data path soc handle + * @pdev_id - physical device instance id * @vdev_mac_addr - the MAC address of the virtual device * @vdev_id - the ID used to identify the virtual device to the target * @op_mode - whether this virtual device is operating as an AP, * an IBSS, or a STA * @subtype: Subtype of the operating vdev * - * Return: success: handle to new data vdev object, failure: NULL + * Return: QDF_STATUS_SUCCESS on success, + QDF error code on failure */ -static struct cdp_vdev * -ol_txrx_vdev_attach(struct cdp_pdev *ppdev, +static QDF_STATUS +ol_txrx_vdev_attach(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint8_t *vdev_mac_addr, uint8_t vdev_id, enum wlan_op_mode op_mode, enum wlan_op_subtype subtype) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + struct ol_txrx_vdev_t *vdev; QDF_STATUS qdf_status; @@ -1655,9 +1904,14 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev, TXRX_ASSERT2(pdev); TXRX_ASSERT2(vdev_mac_addr); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return QDF_STATUS_E_INVAL; + } + vdev = qdf_mem_malloc(sizeof(*vdev)); if (!vdev) - return NULL; /* failure */ + return QDF_STATUS_E_NOMEM; /* failure */ /* store provided params */ vdev->pdev = pdev; @@ -1680,8 +1934,6 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev, TAILQ_INIT(&vdev->peer_list); vdev->last_real_peer = NULL; - ol_txrx_hl_tdls_flag_reset((struct cdp_vdev *)vdev, false); - #ifdef QCA_IBSS_SUPPORT vdev->ibss_peer_num = 0; vdev->ibss_peer_heart_beat_timer = 0; @@ -1714,19 +1966,35 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev, vdev->txrx_stats.txack_success = 0; vdev->txrx_stats.txack_failed = 0; + vdev->bundling_required = false; + qdf_spinlock_create(&vdev->bundle_queue.mutex); + vdev->bundle_queue.txq.head = NULL; + vdev->bundle_queue.txq.tail = NULL; + vdev->bundle_queue.txq.depth = 0; + qdf_timer_init( + pdev->osdev, + &vdev->bundle_queue.timer, + ol_tx_hl_vdev_bundle_timer, + vdev, QDF_TIMER_TYPE_SW); + /* Default MAX Q depth for every VDEV */ vdev->ll_pause.max_q_depth = ol_tx_cfg_max_tx_queue_depth_ll(vdev->pdev->ctrl_pdev); qdf_status = qdf_event_create(&vdev->wait_delete_comp); + + ol_txrx_vdev_init_tcp_del_ack(vdev); + /* add this vdev into the pdev's list */ TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) pdev->monitor_vdev = vdev; + ol_txrx_hl_tdls_flag_reset(soc_hdl, vdev_id, false); + ol_txrx_dbg( - "Created vdev %pK ("QDF_MAC_ADDR_STR")\n", + "Created vdev %pK ("QDF_MAC_ADDR_FMT")\n", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); /* * We've verified that htt_op_mode == wlan_op_mode, @@ -1734,16 +2002,16 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev, */ htt_vdev_attach(pdev->htt_pdev, vdev_id, op_mode); - return (struct cdp_vdev *)vdev; + return QDF_STATUS_SUCCESS; } /** - *ol_txrx_vdev_register - Link a vdev's data object with the + * ol_txrx_vdev_register - Link a vdev's data object with the * matching OS shim vdev object. * - * @txrx_vdev: the virtual device's data object + * @soc_hdl: datapath soc handle + * @vdev_id: the virtual device's id * @osif_vdev: the virtual device's OS shim object - * @ctrl_vdev: UMAC vdev objmgr handle * @txrx_ops: (pointers to)functions used for tx and rx data xfer * * The data object for a virtual device is created by the @@ -1757,29 +2025,28 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev, * vdev objects, so the data SW can use the OS shim vdev handle * when passing rx data received by a vdev up to the OS shim. */ -static void ol_txrx_vdev_register(struct cdp_vdev *pvdev, void *osif_vdev, - struct cdp_ctrl_objmgr_vdev *ctrl_vdev, - struct ol_txrx_ops *txrx_ops) +static QDF_STATUS ol_txrx_vdev_register(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + ol_osif_vdev_handle osif_vdev, + struct ol_txrx_ops *txrx_ops) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); if (qdf_unlikely(!vdev) || qdf_unlikely(!txrx_ops)) { qdf_print("vdev/txrx_ops is NULL!"); qdf_assert(0); - return; + return QDF_STATUS_E_FAILURE; } vdev->osif_dev = osif_vdev; - vdev->ctrl_vdev = ctrl_vdev; vdev->rx = txrx_ops->rx.rx; vdev->stats_rx = txrx_ops->rx.stats_rx; vdev->tx_comp = txrx_ops->tx.tx_comp; txrx_ops->tx.tx = ol_tx_data; -} -void ol_txrx_set_safemode(ol_txrx_vdev_handle vdev, uint32_t val) -{ - vdev->safemode = val; + return QDF_STATUS_SUCCESS; } /** @@ -1801,11 +2068,6 @@ ol_txrx_set_privacy_filters(ol_txrx_vdev_handle vdev, vdev->num_filters = num; } -void ol_txrx_set_drop_unenc(ol_txrx_vdev_handle vdev, uint32_t val) -{ - vdev->drop_unenc = val; -} - #if defined(CONFIG_HL_SUPPORT) || defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) static void @@ -1860,7 +2122,8 @@ ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev) /** * ol_txrx_vdev_detach - Deallocate the specified data virtual * device object. - * @data_vdev: data object for the virtual device in question + * @soc_hdl - data path soc handle + * @vdev_id: vdev id * @callback: function to call (if non-NULL) once the vdev has * been wholly deleted * @callback_context: context to provide in the callback @@ -1880,13 +2143,18 @@ ol_txrx_tx_desc_reset_vdev(ol_txrx_vdev_handle vdev) * vdev_detach call, or if it's deferred until all in-progress peer * deletions have completed. */ -static void -ol_txrx_vdev_detach(struct cdp_vdev *pvdev, +static QDF_STATUS +ol_txrx_vdev_detach(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, ol_txrx_vdev_delete_cb callback, void *context) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); struct ol_txrx_pdev_t *pdev; + if (qdf_unlikely(!vdev)) + return QDF_STATUS_E_FAILURE; + /* preconditions */ TXRX_ASSERT2(vdev); pdev = vdev->pdev; @@ -1915,6 +2183,9 @@ ol_txrx_vdev_detach(struct cdp_vdev *pvdev, qdf_timer_free(&vdev->ll_pause.timer); qdf_spinlock_destroy(&vdev->ll_pause.mutex); + qdf_timer_free(&vdev->bundle_queue.timer); + qdf_spinlock_destroy(&vdev->bundle_queue.mutex); + qdf_spin_lock_bh(&vdev->flow_control_lock); vdev->osif_flow_control_cb = NULL; vdev->osif_flow_control_is_pause = NULL; @@ -1934,23 +2205,23 @@ ol_txrx_vdev_detach(struct cdp_vdev *pvdev, if (!TAILQ_EMPTY(&vdev->peer_list)) { /* debug print - will be removed later */ ol_txrx_dbg( - "not deleting vdev object %pK ("QDF_MAC_ADDR_STR") until deletion finishes for all its peers\n", + "not deleting vdev object %pK ("QDF_MAC_ADDR_FMT") until deletion finishes for all its peers\n", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); /* indicate that the vdev needs to be deleted */ vdev->delete.pending = 1; vdev->delete.callback = callback; vdev->delete.context = context; qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - return; + return QDF_STATUS_E_FAILURE; } qdf_spin_unlock_bh(&pdev->peer_ref_mutex); qdf_event_destroy(&vdev->wait_delete_comp); ol_txrx_dbg( - "deleting vdev obj %pK ("QDF_MAC_ADDR_STR")\n", + "deleting vdev obj %pK ("QDF_MAC_ADDR_FMT")\n", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); htt_vdev_detach(pdev->htt_pdev, vdev->vdev_id); @@ -1974,6 +2245,8 @@ ol_txrx_vdev_detach(struct cdp_vdev *pvdev, qdf_mem_free(vdev); if (callback) callback(context); + + return QDF_STATUS_SUCCESS; } /** @@ -2034,20 +2307,24 @@ void ol_txrx_flush_rx_frames(struct ol_txrx_peer_t *peer, static void ol_txrx_flush_cache_rx_queue(void) { - uint8_t sta_id; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev; + struct ol_txrx_vdev_t *vdev; + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) return; - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev, - sta_id); - if (!peer) - continue; - ol_txrx_flush_rx_frames(peer, 1); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + ol_txrx_flush_rx_frames(peer, 1); + } } } @@ -2078,10 +2355,8 @@ static void ol_txrx_dump_peer_access_list(ol_txrx_peer_handle peer) /** * ol_txrx_peer_attach - Allocate and set up references for a * data peer object. - * @data_pdev: data physical device object that will indirectly - * own the data_peer object - * @data_vdev - data virtual device object that will directly - * own the data_peer object + * @soc_hdl - data path soc handle + * @vdev_id - virtual device instance id * @peer_mac_addr - MAC address of the new peer * * When an association with a peer starts, the host's control SW @@ -2095,14 +2370,15 @@ static void ol_txrx_dump_peer_access_list(ol_txrx_peer_handle peer) * so a reference within the control peer object can be set to the * data peer object. * - * Return: handle to new data peer object, or NULL if the attach - * fails + * Return: QDF status code */ -static void * -ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, - struct cdp_ctrl_objmgr_peer *ctrl_peer) +static QDF_STATUS +ol_txrx_peer_attach(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac_addr) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); struct ol_txrx_peer_t *peer; struct ol_txrx_peer_t *temp_peer; uint8_t i; @@ -2134,9 +2410,9 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, (union ol_txrx_align_mac_addr_t *)peer_mac_addr) && (check_valid == 0 || temp_peer->valid)) { ol_txrx_info_high( - "vdev_id %d ("QDF_MAC_ADDR_STR") already exists.\n", + "vdev_id %d ("QDF_MAC_ADDR_FMT") already exists.\n", vdev->vdev_id, - QDF_MAC_ADDR_ARRAY(peer_mac_addr)); + QDF_MAC_ADDR_REF(peer_mac_addr)); if (qdf_atomic_read(&temp_peer->delete_in_progress)) { vdev->wait_on_peer_id = temp_peer->local_id; qdf_event_reset(&vdev->wait_delete_comp); @@ -2144,7 +2420,7 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, break; } else { qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - return NULL; + return QDF_STATUS_E_FAILURE; } } if (cmp_wait_mac && !ol_txrx_peer_find_mac_addr_cmp( @@ -2153,9 +2429,9 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, (check_valid == 0 || temp_peer->valid)) { ol_txrx_info_high( - "vdev_id %d ("QDF_MAC_ADDR_STR") old peer exists.\n", + "vdev_id %d ("QDF_MAC_ADDR_FMT") old peer exists.\n", vdev->vdev_id, - QDF_MAC_ADDR_ARRAY(vdev->last_peer_mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->last_peer_mac_addr.raw)); if (qdf_atomic_read(&temp_peer->delete_in_progress)) { vdev->wait_on_peer_id = temp_peer->local_id; qdf_event_reset(&vdev->wait_delete_comp); @@ -2164,7 +2440,7 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, } else { qdf_spin_unlock_bh(&pdev->peer_ref_mutex); ol_txrx_err("peer not found"); - return NULL; + return QDF_STATUS_E_FAILURE; } } } @@ -2184,17 +2460,16 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, wlan_roam_debug_dump_table(); vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID; - return NULL; + return QDF_STATUS_E_FAILURE; } } peer = qdf_mem_malloc(sizeof(*peer)); if (!peer) - return NULL; /* failure */ + return QDF_STATUS_E_NOMEM; /* store provided params */ peer->vdev = vdev; - peer->ctrl_peer = peer->ctrl_peer; qdf_mem_copy(&peer->mac_addr.raw[0], peer_mac_addr, QDF_MAC_ADDR_SIZE); @@ -2246,9 +2521,9 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, ol_txrx_peer_find_hash_add(pdev, peer); QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "vdev %pK created peer %pK ref_cnt %d ("QDF_MAC_ADDR_STR")\n", + "vdev %pK created peer %pK ref_cnt %d ("QDF_MAC_ADDR_FMT")\n", vdev, peer, qdf_atomic_read(&peer->ref_cnt), - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); /* * For every peer MAp message search and set if bss_peer */ @@ -2264,24 +2539,25 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr, * progress to "auth" state once the authentication completes. */ peer->state = OL_TXRX_PEER_STATE_INVALID; - ol_txrx_peer_state_update((struct cdp_pdev *)pdev, peer->mac_addr.raw, + ol_txrx_peer_state_update(soc_hdl, peer->mac_addr.raw, OL_TXRX_PEER_STATE_DISC); #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI peer->rssi_dbm = HTT_RSSI_INVALID; #endif - if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) { + 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((struct cdp_vdev *)vdev, true); + ol_vdev_rx_set_intrabss_fwd(soc_hdl, vdev_id, true); } ol_txrx_local_peer_id_alloc(pdev, peer); - return (void *)peer; + return QDF_STATUS_SUCCESS; } #undef PEER_DEL_TIMEOUT @@ -2337,79 +2613,115 @@ ol_txrx_peer_get_peer_mac_addr(void *ppeer) #ifdef WLAN_FEATURE_11W /** * ol_txrx_get_pn_info() - Returns pn info from peer - * @peer: handle to peer + * @soc_hdl: soc handle + * @peer_mac: mac address of the peer + * @vdev_id: vdev identifier * @last_pn_valid: return last_rmf_pn_valid value from peer. * @last_pn: return last_rmf_pn value from peer. * @rmf_pn_replays: return rmf_pn_replays value from peer. * * Return: NONE */ -void -ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid, +static void +ol_txrx_get_pn_info(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t vdev_id, uint8_t **last_pn_valid, uint64_t **last_pn, uint32_t **rmf_pn_replays) { - ol_txrx_peer_handle peer = ppeer; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; + ol_txrx_peer_handle peer; + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + + peer = ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac, 0, 1, + PEER_DEBUG_ID_OL_INTERNAL); + if (!peer) + return; + *last_pn_valid = &peer->last_rmf_pn_valid; *last_pn = &peer->last_rmf_pn; *rmf_pn_replays = &peer->rmf_pn_replays; + + ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); } #else -void -ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid, - uint64_t **last_pn, uint32_t **rmf_pn_replays) +static void +ol_txrx_get_pn_info(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, + uint8_t vdev_id, uint8_t **last_pn_valid, + uint64_t **last_pn, uint32_t **rmf_pn_replays) { } #endif /** * ol_txrx_get_opmode() - Return operation mode of vdev - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * - * Return: operation mode. + * Return: interface opmode if SUCCESS, + * 0 if interface does not exist. */ -static int ol_txrx_get_opmode(struct cdp_vdev *pvdev) +static int ol_txrx_get_opmode(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev; + + vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { + ol_txrx_err("vdev for id %d is NULL", vdev_id); + return 0; + } return vdev->opmode; } /** * ol_txrx_get_peer_state() - Return peer state of peer - * @peer: peer handle + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id + * @peer_mac: peer mac addr * * Return: return peer state */ -static int ol_txrx_get_peer_state(void *ppeer) +static int ol_txrx_get_peer_state(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac) { - ol_txrx_peer_handle peer = ppeer; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = + ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + ol_txrx_peer_handle peer; + enum ol_txrx_peer_state peer_state; - return peer->state; -} + if (!pdev) + return QDF_STATUS_E_FAILURE; -/** - * ol_txrx_get_vdev_for_peer() - Return vdev from peer handle - * @peer: peer handle - * - * Return: vdev handle from peer - */ -static struct cdp_vdev *ol_txrx_get_vdev_for_peer(void *ppeer) -{ - ol_txrx_peer_handle peer = ppeer; + peer = ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac, 0, 1, + PEER_DEBUG_ID_OL_INTERNAL); + if (!peer) + return QDF_STATUS_E_FAILURE; + + peer_state = peer->state; + ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); - return (struct cdp_vdev *)peer->vdev; + return peer_state; } /** * ol_txrx_get_vdev_mac_addr() - Return mac addr of vdev - * @vdev: vdev handle + * @soc_hdl: datapath soc handle + x @vdev_id: virtual interface id * * Return: vdev mac address */ static uint8_t * -ol_txrx_get_vdev_mac_addr(struct cdp_vdev *pvdev) +ol_txrx_get_vdev_mac_addr(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); if (!vdev) return NULL; @@ -2447,14 +2759,20 @@ ol_txrx_pdev_handle ol_txrx_get_pdev_from_vdev(ol_txrx_vdev_handle vdev) /** * ol_txrx_get_ctrl_pdev_from_vdev() - Return control pdev of vdev - * @vdev: vdev handle + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id * * Return: Handle to control pdev */ static struct cdp_cfg * -ol_txrx_get_ctrl_pdev_from_vdev(struct cdp_vdev *pvdev) +ol_txrx_get_ctrl_pdev_from_vdev(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return NULL; return vdev->pdev->ctrl_pdev; } @@ -2477,18 +2795,25 @@ ol_txrx_is_rx_fwd_disabled(struct cdp_vdev *pvdev) #ifdef QCA_IBSS_SUPPORT /** * ol_txrx_update_ibss_add_peer_num_of_vdev() - update and return peer num - * @vdev: vdev handle + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id * @peer_num_delta: peer nums to be adjusted * * Return: -1 for failure or total peer nums after adjustment. */ static int16_t -ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_vdev *pvdev, +ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, int16_t peer_num_delta) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); int16_t new_peer_num; + if (!vdev) + return QDF_STATUS_E_FAILURE; + new_peer_num = vdev->ibss_peer_num + peer_num_delta; if (new_peer_num > MAX_PEERS || new_peer_num < 0) return OL_TXRX_INVALID_NUM_PEERS; @@ -2501,15 +2826,19 @@ ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_vdev *pvdev, /** * ol_txrx_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart * beat timer - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @timer_value_sec: new heart beat timer value * * Return: Old timer value set in vdev. */ -static uint16_t ol_txrx_set_ibss_vdev_heart_beat_timer(struct cdp_vdev *pvdev, - uint16_t timer_value_sec) +static uint16_t +ol_txrx_set_ibss_vdev_heart_beat_timer(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint16_t timer_value_sec) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); uint16_t old_timer_value = vdev->ibss_peer_heart_beat_timer; vdev->ibss_peer_heart_beat_timer = timer_value_sec; @@ -2518,110 +2847,41 @@ static uint16_t ol_txrx_set_ibss_vdev_heart_beat_timer(struct cdp_vdev *pvdev, } #else /* !QCA_IBSS_SUPPORT */ static inline int16_t -ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_vdev *pvdev, +ol_txrx_update_ibss_add_peer_num_of_vdev(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, int16_t peer_num_delta) { return 0; } -static inline uint16_t -ol_txrx_set_ibss_vdev_heart_beat_timer(struct cdp_vdev *pvdev, - uint16_t timer_value_sec) +static uint16_t ol_txrx_set_ibss_vdev_heart_beat_timer( + struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint16_t timer_value_sec) { return 0; } #endif /* QCA_IBSS_SUPPORT */ -/** - * ol_txrx_remove_peers_for_vdev() - remove all vdev peers with lock held - * @vdev: vdev handle - * @callback: callback function to remove the peer. - * @callback_context: handle for callback function - * @remove_last_peer: Does it required to last peer. - * - * Return: NONE - */ -static void -ol_txrx_remove_peers_for_vdev(struct cdp_vdev *pvdev, - ol_txrx_vdev_peer_remove_cb callback, - void *callback_context, bool remove_last_peer) -{ - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - ol_txrx_peer_handle peer, temp; - int self_removed = 0; - /* remove all remote peers for vdev */ - qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex); - - temp = NULL; - TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list, peer_list_t, - peer_list_elem) { - if (qdf_atomic_read(&peer->delete_in_progress)) - continue; - if (temp) { - qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); - callback(callback_context, temp->mac_addr.raw, - vdev->vdev_id, temp); - qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex); - } - /* self peer is deleted last */ - if (peer == TAILQ_FIRST(&vdev->peer_list)) { - self_removed = 1; - break; - } - temp = peer; - } - - qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); - - if (self_removed) - ol_txrx_info("self peer removed by caller"); - - if (remove_last_peer) { - /* remove IBSS bss peer last */ - peer = TAILQ_FIRST(&vdev->peer_list); - callback(callback_context, (uint8_t *) &vdev->mac_addr, - vdev->vdev_id, peer); - } -} - -/** - * ol_txrx_remove_peers_for_vdev_no_lock() - remove vdev peers with no lock. - * @vdev: vdev handle - * @callback: callback function to remove the peer. - * @callback_context: handle for callback function - * - * Return: NONE - */ -static void -ol_txrx_remove_peers_for_vdev_no_lock(struct cdp_vdev *pvdev, - ol_txrx_vdev_peer_remove_cb callback, - void *callback_context) -{ - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - ol_txrx_peer_handle peer = NULL; - ol_txrx_peer_handle tmp_peer = NULL; - - TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, peer_list_elem, tmp_peer) { - ol_txrx_info_high( - "peer found for vdev id %d. deleting the peer", - vdev->vdev_id); - callback(callback_context, (uint8_t *)&vdev->mac_addr, - vdev->vdev_id, peer); - } -} - #ifdef WLAN_FEATURE_DSRC /** * ol_txrx_set_ocb_chan_info() - set OCB channel info to vdev. - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * @ocb_set_chan: OCB channel information to be set in vdev. * * Return: NONE */ -static void ol_txrx_set_ocb_chan_info(struct cdp_vdev *pvdev, +static void +ol_txrx_set_ocb_chan_info(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, struct ol_txrx_ocb_set_chan ocb_set_chan) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("pdev is NULL"); + return; + } vdev->ocb_channel_info = ocb_set_chan.ocb_channel_info; vdev->ocb_channel_count = ocb_set_chan.ocb_channel_count; @@ -2629,40 +2889,33 @@ static void ol_txrx_set_ocb_chan_info(struct cdp_vdev *pvdev, /** * ol_txrx_get_ocb_chan_info() - return handle to vdev ocb_channel_info - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * * Return: handle to struct ol_txrx_ocb_chan_info */ static struct ol_txrx_ocb_chan_info * -ol_txrx_get_ocb_chan_info(struct cdp_vdev *pvdev) +ol_txrx_get_ocb_chan_info(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("pdev is NULL"); + return NULL; + } return vdev->ocb_channel_info; } #endif -/** - * @brief specify the peer's authentication state - * @details - * Specify the peer's authentication state (none, connected, authenticated) - * to allow the data SW to determine whether to filter out invalid data frames. - * (In the "connected" state, where security is enabled, but authentication - * has not completed, tx and rx data frames other than EAPOL or WAPI should - * be discarded.) - * This function is only relevant for systems in which the tx and rx filtering - * are done in the host rather than in the target. - * - * @param data_peer - which peer has changed its state - * @param state - the new state of the peer - * - * Return: QDF Status - */ -QDF_STATUS ol_txrx_peer_state_update(struct cdp_pdev *ppdev, +QDF_STATUS ol_txrx_peer_state_update(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac, enum ol_txrx_peer_state state) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = + ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); struct ol_txrx_peer_t *peer; int peer_ref_cnt; @@ -3061,9 +3314,9 @@ int ol_txrx_peer_release_ref(ol_txrx_peer_handle peer, */ ol_txrx_tx_desc_reset_vdev(vdev); ol_txrx_dbg( - "deleting vdev object %pK ("QDF_MAC_ADDR_STR") - its last peer is done", + "deleting vdev object %pK ("QDF_MAC_ADDR_FMT") - its last peer is done", vdev, - QDF_MAC_ADDR_ARRAY(vdev->mac_addr.raw)); + QDF_MAC_ADDR_REF(vdev->mac_addr.raw)); /* all peers are gone, go ahead and delete it */ qdf_mem_free(vdev); if (vdev_delete_cb) @@ -3140,14 +3393,18 @@ ol_txrx_clear_peer_internal(struct ol_txrx_peer_t *peer) /** * ol_txrx_clear_peer() - clear peer - * @sta_id: sta id + * peer_addr: peer mac address * * Return: QDF Status */ -static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id) +static QDF_STATUS +ol_txrx_clear_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr) { + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = + ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; QDF_STATUS status; if (!pdev) { @@ -3155,13 +3412,8 @@ static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id) return QDF_STATUS_E_FAILURE; } - if (sta_id >= WLAN_MAX_STA_COUNT) { - ol_txrx_err("Invalid sta id %d", sta_id); - return QDF_STATUS_E_INVAL; - } - - peer = ol_txrx_peer_get_ref_by_local_id(ppdev, sta_id, - PEER_DEBUG_ID_OL_INTERNAL); + peer = ol_txrx_peer_get_ref_by_addr(pdev, peer_addr.bytes, + PEER_DEBUG_ID_OL_INTERNAL); /* Return success, if the peer is already cleared by * data path via peer detach function. @@ -3169,8 +3421,8 @@ static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id) if (!peer) return QDF_STATUS_SUCCESS; - ol_txrx_dbg("Clear peer rx frames: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + ol_txrx_dbg("Clear peer rx frames: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); ol_txrx_clear_peer_internal(peer); status = ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_INTERNAL); @@ -3187,11 +3439,15 @@ void peer_unmap_timer_handler(void *data) { ol_txrx_peer_handle peer = (ol_txrx_peer_handle)data; + if (!peer) + return; + ol_txrx_err("all unmap events not received for peer %pK, ref_cnt %d", peer, qdf_atomic_read(&peer->ref_cnt)); - ol_txrx_err("peer %pK ("QDF_MAC_ADDR_STR")", + ol_txrx_err("peer %pK ("QDF_MAC_ADDR_FMT")", peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); + ol_register_peer_recovery_notifier(peer); cds_trigger_recovery(QDF_PEER_UNMAP_TIMEDOUT); } @@ -3199,20 +3455,36 @@ void peer_unmap_timer_handler(void *data) /** * ol_txrx_peer_detach() - Delete a peer's data object. - * @peer - the object to detach + + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id + * @peer_mac: peer MAC address * @bitmap - bitmap indicating special handling of request. - * * When the host's control SW disassociates a peer, it calls * this function to detach and delete the peer. The reference * stored in the control peer object to the data peer * object (set up by a call to ol_peer_store()) is provided. * - * Return: None + * Return: SUCCESS or Failure */ -static void ol_txrx_peer_detach(void *ppeer, uint32_t bitmap) +static QDF_STATUS ol_txrx_peer_detach(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, uint32_t bitmap) { - ol_txrx_peer_handle peer = ppeer; - struct ol_txrx_vdev_t *vdev = peer->vdev; + ol_txrx_peer_handle peer; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + + if (!vdev) + return QDF_STATUS_E_FAILURE; + + peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)vdev->pdev, + peer_mac); + if (!peer) + return QDF_STATUS_E_FAILURE; + + ol_txrx_info_high("%s peer %pK, peer->ref_cnt %d", __func__, + peer, qdf_atomic_read(&peer->ref_cnt)); /* redirect peer's rx delivery function to point to a discard func */ peer->rx_opt_proc = ol_rx_discard; @@ -3226,9 +3498,9 @@ static void ol_txrx_peer_detach(void *ppeer, uint32_t bitmap) /* htt_rx_reorder_log_print(vdev->pdev->htt_pdev); */ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "%s:peer %pK ("QDF_MAC_ADDR_STR")", + "%s:peer %pK ("QDF_MAC_ADDR_FMT")", __func__, peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); qdf_spin_lock_bh(&vdev->pdev->last_real_peer_mutex); if (vdev->last_real_peer == peer) @@ -3267,11 +3539,15 @@ static void ol_txrx_peer_detach(void *ppeer, uint32_t bitmap) * reference, added by the PEER_MAP message. */ ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_PEER_ATTACH); + + return QDF_STATUS_SUCCESS; } /** * ol_txrx_peer_detach_force_delete() - Detach and delete a peer's data object - * @ppeer - the object to detach + * @soc_hdl - datapath soc handle + * @vdev_id - virtual interface id + * @peer_mac - peer mac address * * Detach a peer and force peer object to be removed. It is called during * roaming scenario when the firmware has already deleted a peer. @@ -3280,55 +3556,79 @@ static void ol_txrx_peer_detach(void *ppeer, uint32_t bitmap) * * Return: None */ -static void ol_txrx_peer_detach_force_delete(void *ppeer) +static void ol_txrx_peer_detach_force_delete(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, uint8_t *peer_mac) { - ol_txrx_peer_handle peer = ppeer; - ol_txrx_pdev_handle pdev = peer->vdev->pdev; + struct ol_txrx_peer_t *peer; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); - ol_txrx_info_high("peer %pK, peer->ref_cnt %d", - peer, qdf_atomic_read(&peer->ref_cnt)); + if (!vdev || !vdev->pdev) + return; + + pdev = vdev->pdev; + peer = ol_txrx_find_peer_by_addr(ol_txrx_pdev_t_to_cdp_pdev(pdev), + peer_mac); + if (!peer) + return; /* Clear the peer_id_to_obj map entries */ ol_txrx_peer_remove_obj_map_entries(pdev, peer); - ol_txrx_peer_detach(peer, 1 << CDP_PEER_DELETE_NO_SPECIAL); + ol_txrx_peer_detach(soc_hdl, vdev_id, peer_mac, + 1 << CDP_PEER_DELETE_NO_SPECIAL); } /** * ol_txrx_peer_detach_sync() - peer detach sync callback - * @ppeer - the peer object + * @soc_hdl - datapath soc handle + * @vdev_id - virtual interface id + * @peer_mac - peer mac address * @peer_unmap_sync - peer unmap sync cb. * @bitmap - bitmap indicating special handling of request. * * Return: None */ -static void ol_txrx_peer_detach_sync(void *ppeer, +static void ol_txrx_peer_detach_sync(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t *peer_mac, ol_txrx_peer_unmap_sync_cb peer_unmap_sync, uint32_t bitmap) { - ol_txrx_peer_handle peer = ppeer; - ol_txrx_pdev_handle pdev = peer->vdev->pdev; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); - ol_txrx_info_high("%s peer %pK, peer->ref_cnt %d", __func__, - peer, qdf_atomic_read(&peer->ref_cnt)); + if (!vdev || !vdev->pdev) + return; + pdev = vdev->pdev; if (!pdev->peer_unmap_sync_cb) pdev->peer_unmap_sync_cb = peer_unmap_sync; - ol_txrx_peer_detach(peer, bitmap); + ol_txrx_peer_detach(soc_hdl, vdev_id, peer_mac, bitmap); } /** * ol_txrx_peer_unmap_sync_cb_set() - set peer unmap sync callback - * @ppdev - TXRX pdev context + * @soc_hdl - datapath soc handle + * pdev_id - physical device instance id * @peer_unmap_sync - peer unmap sync callback * * Return: None */ static void ol_txrx_peer_unmap_sync_cb_set( - struct cdp_pdev *ppdev, + struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, ol_txrx_peer_unmap_sync_cb peer_unmap_sync) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + + if (!pdev) + return; if (!pdev->peer_unmap_sync_cb) pdev->peer_unmap_sync_cb = peer_unmap_sync; @@ -3343,11 +3643,13 @@ static void ol_txrx_peer_unmap_sync_cb_set( * Return: None */ static void -ol_txrx_peer_flush_frags(struct cdp_pdev *ppdev, uint8_t vdev_id, +ol_txrx_peer_flush_frags(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, uint8_t *peer_mac) { struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = + ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) return; @@ -3400,8 +3702,15 @@ static void ol_txrx_dump_tx_desc(ol_txrx_pdev_handle pdev_handle) */ static QDF_STATUS ol_txrx_wait_for_pending_tx(int timeout) { - struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct ol_txrx_pdev_t *txrx_pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return QDF_STATUS_E_FAULT; + } + txrx_pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!txrx_pdev) { ol_txrx_err("txrx context is null"); return QDF_STATUS_E_FAULT; @@ -3428,18 +3737,22 @@ static QDF_STATUS ol_txrx_wait_for_pending_tx(int timeout) #ifdef FEATURE_RUNTIME_PM /** * ol_txrx_runtime_suspend() - ensure TXRX is ready to runtime suspend - * @txrx_pdev: TXRX pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * TXRX is ready to runtime suspend if there are no pending packets * in the tx queue. * * Return: QDF_STATUS */ -static QDF_STATUS ol_txrx_runtime_suspend(struct cdp_pdev *ppdev) +static QDF_STATUS ol_txrx_runtime_suspend(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - struct ol_txrx_pdev_t *txrx_pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct cdp_pdev *txrx_pdev = (struct cdp_pdev *) + ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); - if (ol_txrx_get_tx_pending((struct cdp_pdev *)txrx_pdev)) + if (ol_txrx_get_tx_pending(txrx_pdev)) return QDF_STATUS_E_BUSY; else return QDF_STATUS_SUCCESS; @@ -3447,13 +3760,15 @@ static QDF_STATUS ol_txrx_runtime_suspend(struct cdp_pdev *ppdev) /** * ol_txrx_runtime_resume() - ensure TXRX is ready to runtime resume - * @txrx_pdev: TXRX pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * This is a dummy function for symmetry. * * Return: QDF_STATUS_SUCCESS */ -static QDF_STATUS ol_txrx_runtime_resume(struct cdp_pdev *ppdev) +static QDF_STATUS ol_txrx_runtime_resume(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { return QDF_STATUS_SUCCESS; } @@ -3461,26 +3776,29 @@ static QDF_STATUS ol_txrx_runtime_resume(struct cdp_pdev *ppdev) /** * ol_txrx_bus_suspend() - bus suspend - * @ppdev: TXRX pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * Ensure that ol_txrx is ready for bus suspend * * Return: QDF_STATUS */ -static QDF_STATUS ol_txrx_bus_suspend(struct cdp_pdev *ppdev) +static QDF_STATUS ol_txrx_bus_suspend(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { return ol_txrx_wait_for_pending_tx(SUSPEND_DRAIN_WAIT); } /** * ol_txrx_bus_resume() - bus resume - * @ppdev: TXRX pdev context + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * Dummy function for symetry * * Return: QDF_STATUS_SUCCESS */ -static QDF_STATUS ol_txrx_bus_resume(struct cdp_pdev *ppdev) +static QDF_STATUS ol_txrx_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { return QDF_STATUS_SUCCESS; } @@ -3494,7 +3812,7 @@ static QDF_STATUS ol_txrx_bus_resume(struct cdp_pdev *ppdev) * * Return: count of pending frames */ -int ol_txrx_get_tx_pending(struct cdp_pdev *ppdev) +uint32_t ol_txrx_get_tx_pending(struct cdp_pdev *ppdev) { struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; uint32_t total; @@ -3687,21 +4005,39 @@ struct ol_txrx_stats_req_internal return req; } +/** + * ol_txrx_fw_stats_get() - Get fw stats + * + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id + * @req: specifications of stats request + * @per_vdev: bool input whether stats requested per vdev or not + * @response_expected: bool input whether expecting response or not + * + * Return: success or failure + */ static A_STATUS -ol_txrx_fw_stats_get(struct cdp_vdev *pvdev, struct ol_txrx_stats_req *req, - bool per_vdev, bool response_expected) +ol_txrx_fw_stats_get(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + struct ol_txrx_stats_req *req, bool per_vdev, + bool response_expected) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); + struct ol_txrx_pdev_t *pdev; uint8_t cookie = FW_STATS_DESC_POOL_SIZE; struct ol_txrx_stats_req_internal *non_volatile_req; struct ol_txrx_fw_stats_desc_t *desc = NULL; struct ol_txrx_fw_stats_desc_elem_t *elem = NULL; + if (!vdev) + return A_EINVAL; + + pdev = vdev->pdev; if (!pdev || req->stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS || req->stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) { - return A_ERROR; + return A_EINVAL; } /* @@ -3720,7 +4056,7 @@ ol_txrx_fw_stats_get(struct cdp_vdev *pvdev, struct ol_txrx_stats_req *req, desc = ol_txrx_fw_stats_desc_alloc(pdev); if (!desc) { qdf_mem_free(non_volatile_req); - return A_ERROR; + return A_NO_MEMORY; } /* use the desc id as the cookie */ @@ -4205,10 +4541,11 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev, pdev->stats.pub.tx.dropped.download_fail.pkts + pdev->stats.pub.tx.dropped.target_discard.pkts + pdev->stats.pub.tx.dropped.no_ack.pkts + + pdev->stats.pub.tx.dropped.target_drop.pkts + pdev->stats.pub.tx.dropped.others.pkts; if (level == QDF_STATS_VERBOSITY_LEVEL_LOW) { - txrx_nofl_dbg("STATS |%u %u|TX: %lld tso %lld ok %lld drops(%u-%lld %u-%lld %u-%lld ?-%lld hR-%lld)|RX: %lld drops(E %lld PI %lld ME %lld) fwd(S %d F %d SF %d)|", + txrx_nofl_dbg("STATS |%u %u|TX: %lld tso %lld ok %lld drops(%u-%lld %u-%lld %u-%lld %u-%lld ?-%lld hR-%lld)|RX: %lld drops(E %lld PI %lld ME %lld) fwd(S %d F %d SF %d)|", pdev->tx_desc.num_free, pdev->tx_desc.pool_size, pdev->stats.pub.tx.from_stack.pkts, @@ -4221,6 +4558,8 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev, target_discard.pkts, htt_tx_status_no_ack, pdev->stats.pub.tx.dropped.no_ack.pkts, + htt_tx_status_drop, + pdev->stats.pub.tx.dropped.target_drop.pkts, pdev->stats.pub.tx.dropped.others.pkts, pdev->stats.pub.tx.dropped.host_reject.pkts, pdev->stats.pub.rx.delivered.pkts, @@ -4245,8 +4584,9 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev, tx_dropped, pdev->stats.pub.tx.dropped.download_fail.bytes + pdev->stats.pub.tx.dropped.target_discard.bytes + + pdev->stats.pub.tx.dropped.target_drop.bytes + pdev->stats.pub.tx.dropped.no_ack.bytes); - txrx_nofl_info("successfully delivered: %lld (%lld B), download fail: %lld (%lld B), target discard: %lld (%lld B), no ack: %lld (%lld B) others: %lld (%lld B)", + txrx_nofl_info("successfully delivered: %lld (%lld B), download fail: %lld (%lld B), target discard: %lld (%lld B), no ack: %lld (%lld B),target drop: %lld (%lld B), others: %lld (%lld B)", pdev->stats.pub.tx.delivered.pkts, pdev->stats.pub.tx.delivered.bytes, pdev->stats.pub.tx.dropped.download_fail.pkts, @@ -4255,6 +4595,8 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev, pdev->stats.pub.tx.dropped.target_discard.bytes, pdev->stats.pub.tx.dropped.no_ack.pkts, pdev->stats.pub.tx.dropped.no_ack.bytes, + pdev->stats.pub.tx.dropped.target_drop.pkts, + pdev->stats.pub.tx.dropped.target_drop.bytes, pdev->stats.pub.tx.dropped.others.pkts, pdev->stats.pub.tx.dropped.others.bytes); txrx_nofl_info("Tx completions per HTT message:\n" @@ -4354,9 +4696,21 @@ ol_txrx_peer_stats_copy(ol_txrx_pdev_handle pdev, } #endif /* QCA_ENABLE_OL_TXRX_PEER_STATS */ -static void ol_vdev_rx_set_intrabss_fwd(struct cdp_vdev *pvdev, bool val) +/** + * ol_vdev_rx_set_intrabss_fwd() - Get fw stats + * + * @soc_hdl: datapath soc handle + * @vdev_id: virtual interface id + * @val: enable or disable + * + * Return: void + */ +static void ol_vdev_rx_set_intrabss_fwd(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool val) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, + vdev_id); if (!vdev) return; @@ -4366,12 +4720,14 @@ static void ol_vdev_rx_set_intrabss_fwd(struct cdp_vdev *pvdev, bool val) /** * ol_txrx_update_mac_id() - update mac_id for vdev + * @soc_hdl: Datapath soc handle * @vdev_id: vdev id * @mac_id: mac id * * Return: none */ -static void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id) +static void ol_txrx_update_mac_id(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint8_t mac_id) { struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *) @@ -4387,38 +4743,44 @@ static void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id) /** * ol_txrx_get_tx_ack_count() - get tx ack count - * @pdev: pdev reference + * @soc_hdl: Datapath soc handle * @vdev_id: vdev_id * * Return: tx ack count */ -static uint32_t ol_txrx_get_tx_ack_stats(struct cdp_pdev *pdev, +static uint32_t ol_txrx_get_tx_ack_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Invalid vdev_id %d", __func__, vdev_id); return 0; } + return vdev->txrx_stats.txack_success; } /** * ol_txrx_display_stats() - Display OL TXRX display stats + * @soc_hdl: Datapath soc handle * @value: Module id for which stats needs to be displayed + * @verb_level: verbose level of stats to be displayed * * Return: status */ static QDF_STATUS -ol_txrx_display_stats(void *soc, uint16_t value, +ol_txrx_display_stats(struct cdp_soc_t *soc_hdl, uint16_t value, enum qdf_stats_verbosity_level verb_level) { - ol_txrx_pdev_handle pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id( + soc, + OL_TXRX_PDEV_ID); QDF_STATUS status = QDF_STATUS_SUCCESS; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: pdev is NULL", __func__); @@ -4433,7 +4795,10 @@ ol_txrx_display_stats(void *soc, uint16_t value, ol_txrx_stats_display_tso(pdev); break; case CDP_DUMP_TX_FLOW_POOL_INFO: - ol_tx_dump_flow_pool_info((void *)pdev); + if (verb_level == QDF_STATS_VERBOSITY_LEVEL_LOW) + ol_tx_dump_flow_pool_info_compact(pdev); + else + ol_tx_dump_flow_pool_info(soc_hdl); break; case CDP_TXRX_DESC_STATS: qdf_nbuf_tx_desc_count_display(); @@ -4470,20 +4835,23 @@ ol_txrx_display_stats(void *soc, uint16_t value, /** * ol_txrx_clear_stats() - Clear OL TXRX stats - * @value: Module id for which stats needs to be cleared + * @soc - ol soc handle + * @pdev_id: pdev identifier + * @value - Module id for which stats needs to be cleared * - * Return: None + * Return: 0 - success/ non-zero failure */ -static void ol_txrx_clear_stats(uint16_t value) +static QDF_STATUS ol_txrx_clear_stats(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t value) { - ol_txrx_pdev_handle pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); QDF_STATUS status = QDF_STATUS_SUCCESS; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: pdev is NULL", __func__); - return; + return QDF_STATUS_E_INVAL; } switch (value) { @@ -4520,6 +4888,7 @@ static void ol_txrx_clear_stats(uint16_t value) break; } + return status; } /** @@ -4530,9 +4899,21 @@ static void ol_txrx_clear_stats(uint16_t value) */ static inline int ol_txrx_drop_nbuf_list(qdf_nbuf_t buf_list) { + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; int num_dropped = 0; qdf_nbuf_t buf, next_buf; - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return 0; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return 0; + } buf = buf_list; while (buf) { @@ -4720,14 +5101,21 @@ static QDF_STATUS ol_txrx_enqueue_rx_frames( void ol_rx_data_process(struct ol_txrx_peer_t *peer, qdf_nbuf_t rx_buf_list) { + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; /* * Firmware data path active response will use shim RX thread * T2H MSG running on SIRQ context, * IPA kernel module API should not be called on SIRQ CTXT */ ol_txrx_rx_fp data_rx = NULL; - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + goto drop_rx_buf; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if ((!peer) || (!pdev)) { ol_txrx_err("peer/pdev is NULL"); goto drop_rx_buf; @@ -4798,7 +5186,9 @@ void ol_rx_data_process(struct ol_txrx_peer_t *peer, static QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc) { struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev = + ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); union ol_txrx_peer_update_param_t param; struct privacy_exemption privacy_filter; @@ -4807,14 +5197,9 @@ static QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc) return QDF_STATUS_E_INVAL; } - if (sta_desc->sta_id >= WLAN_MAX_STA_COUNT) { - ol_txrx_err("Invalid sta id :%d", - sta_desc->sta_id); - return QDF_STATUS_E_INVAL; - } + peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, + sta_desc->peer_addr.bytes); - peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev, - sta_desc->sta_id); if (!peer) return QDF_STATUS_E_FAULT; @@ -4841,24 +5226,23 @@ static QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc) /** * ol_txrx_register_ocb_peer - Function to register the OCB peer * @mac_addr: MAC address of the self peer - * @peer_id: Pointer to the peer ID * * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure */ -static QDF_STATUS ol_txrx_register_ocb_peer(uint8_t *mac_addr, - uint8_t *peer_id) +static QDF_STATUS ol_txrx_register_ocb_peer(uint8_t *mac_addr) { - ol_txrx_pdev_handle pdev; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev = + ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); ol_txrx_peer_handle peer; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - ol_txrx_err("Unable to find pdev!"); + if (!pdev || !soc) { + ol_txrx_err("Unable to find pdev or soc!"); return QDF_STATUS_E_FAILURE; } peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev, - mac_addr, peer_id); + mac_addr); if (!peer) { ol_txrx_err("Unable to find OCB peer!"); return QDF_STATUS_E_FAILURE; @@ -4867,7 +5251,7 @@ static QDF_STATUS ol_txrx_register_ocb_peer(uint8_t *mac_addr, ol_txrx_set_ocb_peer(pdev, peer); /* Set peer state to connected */ - ol_txrx_peer_state_update((struct cdp_pdev *)pdev, peer->mac_addr.raw, + ol_txrx_peer_state_update((struct cdp_soc_t *)soc, peer->mac_addr.raw, OL_TXRX_PEER_STATE_AUTH); return QDF_STATUS_SUCCESS; @@ -4918,15 +5302,18 @@ bool ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev, /** * ol_txrx_register_pause_cb() - register pause callback + * @soc_hdl: Datapath soc handle * @pause_cb: pause callback * * Return: QDF status */ -static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc, +static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc_hdl, tx_pause_callback pause_cb) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev || !pause_cb) { ol_txrx_err("pdev or pause_cb is NULL"); return QDF_STATUS_E_INVAL; @@ -4952,10 +5339,18 @@ static void ol_txrx_offld_flush_handler(void *context, qdf_nbuf_t rxpkt, uint16_t staid) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + if (qdf_unlikely(!soc)) { + ol_txrx_err("Invalid soc context"); + qdf_assert(0); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) { - ol_txrx_err("Invalid context"); + ol_txrx_err("Invalid pdev context"); qdf_assert(0); return; } @@ -4979,11 +5374,18 @@ static void ol_txrx_offld_flush(void *data) { p_cds_sched_context sched_ctx = get_cds_sched_ctxt(); struct cds_ol_rx_pkt *pkt; - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; if (qdf_unlikely(!sched_ctx)) return; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) { ol_txrx_err("TXRX module context is NULL"); return; @@ -5017,8 +5419,16 @@ static void ol_txrx_offld_flush(void *data) static void ol_register_offld_flush_cb(void (offld_flush_cb)(void *)) { struct hif_opaque_softc *hif_device; - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc NULL!"); + TXRX_ASSERT2(0); + goto out; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev NULL!"); TXRX_ASSERT2(0); @@ -5060,8 +5470,15 @@ static void ol_register_offld_flush_cb(void (offld_flush_cb)(void *)) static void ol_deregister_offld_flush_cb(void) { struct hif_opaque_softc *hif_device; - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev NULL!"); return; @@ -5082,17 +5499,19 @@ static void ol_deregister_offld_flush_cb(void) /** * ol_register_data_stall_detect_cb() - register data stall callback - * @opaque_pdev: dev handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @data_stall_detect_callback: data stall callback function * * * Return: QDF_STATUS Enumeration */ static QDF_STATUS ol_register_data_stall_detect_cb( - struct cdp_pdev *opaque_pdev, - data_stall_detect_cb data_stall_detect_callback) + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + data_stall_detect_cb data_stall_detect_callback) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)opaque_pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { ol_txrx_err("pdev NULL!"); @@ -5104,17 +5523,19 @@ static QDF_STATUS ol_register_data_stall_detect_cb( /** * ol_deregister_data_stall_detect_cb() - de-register data stall callback - * @opaque_pdev: dev handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @data_stall_detect_callback: data stall callback function * * * Return: QDF_STATUS Enumeration */ static QDF_STATUS ol_deregister_data_stall_detect_cb( - struct cdp_pdev *opaque_pdev, - data_stall_detect_cb data_stall_detect_callback) + struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + data_stall_detect_cb data_stall_detect_callback) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)opaque_pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { ol_txrx_err("pdev NULL!"); @@ -5126,7 +5547,6 @@ static QDF_STATUS ol_deregister_data_stall_detect_cb( /** * ol_txrx_post_data_stall_event() - post data stall event - * @opaque_pdev: dev handle * @indicator: Module triggering data stall * @data_stall_type: data stall event type * @pdev_id: pdev id @@ -5136,15 +5556,22 @@ static QDF_STATUS ol_deregister_data_stall_detect_cb( * Return: None */ static void ol_txrx_post_data_stall_event( - struct cdp_pdev *opaque_pdev, + struct cdp_soc_t *soc_hdl, enum data_stall_log_event_indicator indicator, enum data_stall_log_event_type data_stall_type, uint32_t pdev_id, uint32_t vdev_id_bitmap, enum data_stall_log_recovery_type recovery_type) { + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); struct data_stall_event_info data_stall_info; - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)opaque_pdev; + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: pdev is NULL.", __func__); @@ -5183,18 +5610,28 @@ ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len) qdf_nbuf_data(nbuf), len, true); } -/** - * ol_txrx_get_vdev_from_vdev_id() - get vdev from vdev_id - * @vdev_id: vdev_id - * - * Return: vdev handle - * NULL if not found. - */ struct cdp_vdev *ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_vdev_handle vdev = NULL; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return NULL; + } + + vdev = ol_txrx_get_vdev_from_soc_vdev_id(soc, vdev_id); + + return ol_txrx_vdev_t_to_cdp_vdev(vdev); +} + +struct ol_txrx_vdev_t *ol_txrx_get_vdev_from_soc_vdev_id( + struct ol_txrx_soc_t *soc, uint8_t vdev_id) +{ + ol_txrx_pdev_handle pdev; ol_txrx_vdev_handle vdev = NULL; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) return NULL; @@ -5203,36 +5640,42 @@ struct cdp_vdev *ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id) break; } - return (struct cdp_vdev *)vdev; + return vdev; } /** * ol_txrx_get_mon_vdev_from_pdev() - get monitor mode vdev from pdev - * @ppdev: the physical device the virtual device belongs to + * @soc_hdl: datapath soc handle + * @pdev_id: the physical device id the virtual device belongs to * - * Return: vdev handle - * NULL if not found. + * Return: vdev id + * error if not found. */ -struct cdp_vdev *ol_txrx_get_mon_vdev_from_pdev(struct cdp_pdev *ppdev) +uint8_t ol_txrx_get_mon_vdev_from_pdev(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = (struct ol_txrx_soc_t *)soc_hdl; + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (qdf_unlikely(!pdev)) - return NULL; + return -EINVAL; - return (struct cdp_vdev *)pdev->monitor_vdev; + return pdev->monitor_vdev->vdev_id; } /** * ol_txrx_set_wisa_mode() - set wisa mode - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: vdev_id * @enable: enable flag * * Return: QDF STATUS */ -static QDF_STATUS ol_txrx_set_wisa_mode(struct cdp_vdev *pvdev, bool enable) +static QDF_STATUS ol_txrx_set_wisa_mode(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool enable) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); if (!vdev) return QDF_STATUS_E_INVAL; @@ -5274,30 +5717,31 @@ static QDF_STATUS ol_txrx_soc_attach_target(ol_txrx_soc_handle soc) * * MCL legacy OL do nothing here * - * Return: noe + * Return: none */ -static void ol_txrx_soc_detach(void *soc) +static void ol_txrx_soc_detach(struct cdp_soc_t *soc) { qdf_mem_free(soc); } /** * ol_txrx_pkt_log_con_service() - connect packet log service - * @ppdev: physical device handle + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @scn: device context * * Return: noe */ #ifdef REMOVE_PKT_LOG -static void ol_txrx_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn) +static void ol_txrx_pkt_log_con_service(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *scn) { } #else -static void ol_txrx_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn) +static void ol_txrx_pkt_log_con_service(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *scn) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - - htt_pkt_log_init((struct cdp_pdev *)pdev, scn); + htt_pkt_log_init(soc_hdl, pdev_id, scn); pktlog_htc_attach(); } #endif @@ -5305,28 +5749,35 @@ static void ol_txrx_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn) /* OL wrapper functions for CDP abstraction */ /** * ol_txrx_wrapper_flush_rx_frames() - flush rx frames on the queue - * @peer: peer handle + * @soc: data path soc handle + * @pdev_id: datapath pdev identifier + * @peer_mac: peer mac address * @drop: rx packets drop or deliver * * Return: none */ -static void ol_txrx_wrapper_flush_rx_frames(void *peer, bool drop) +static void ol_txrx_wrapper_flush_rx_frames(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, void *peer_mac, + bool drop) { - ol_txrx_flush_rx_frames((ol_txrx_peer_handle)peer, drop); -} + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_peer_t *peer; -/** - * ol_txrx_wrapper_get_vdev_from_vdev_id() - get vdev instance from vdev id - * @ppdev: pdev handle - * @vdev_id: interface id - * - * Return: virtual interface instance - */ -static -struct cdp_vdev *ol_txrx_wrapper_get_vdev_from_vdev_id(struct cdp_pdev *ppdev, - uint8_t vdev_id) -{ - return ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + + peer = ol_txrx_peer_find_hash_find_get_ref(pdev, peer_mac, 0, 1, + PEER_DEBUG_ID_OL_INTERNAL); + if (!peer) { + ol_txrx_err("peer "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); + return; + } + + ol_txrx_flush_rx_frames(peer, drop); } /** @@ -5336,33 +5787,14 @@ struct cdp_vdev *ol_txrx_wrapper_get_vdev_from_vdev_id(struct cdp_pdev *ppdev, * * Return: QDF STATUS */ -static QDF_STATUS ol_txrx_wrapper_register_peer(struct cdp_pdev *pdev, - struct ol_txrx_desc_type *sta_desc) +static QDF_STATUS ol_txrx_wrapper_register_peer( + struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + struct ol_txrx_desc_type *sta_desc) { return ol_txrx_register_peer(sta_desc); } -/** - * ol_txrx_wrapper_peer_find_by_local_id() - Find a txrx peer handle - * @pdev - the data physical device object - * @local_peer_id - the ID txrx assigned locally to the peer in question - * - * The control SW typically uses the txrx peer handle to refer to the peer. - * In unusual circumstances, if it is infeasible for the control SW maintain - * the txrx peer handle but it can maintain a small integer local peer ID, - * this function allows the peer handled to be retrieved, based on the local - * peer ID. - * - * @return handle to the txrx peer object - */ -static void * -ol_txrx_wrapper_peer_find_by_local_id(struct cdp_pdev *pdev, - uint8_t local_peer_id) -{ - return (void *)ol_txrx_peer_find_by_local_id( - pdev, local_peer_id); -} - /** * ol_txrx_wrapper_cfg_is_high_latency() - device is high or low latency device * @pdev: pdev handle @@ -5377,7 +5809,8 @@ static int ol_txrx_wrapper_cfg_is_high_latency(struct cdp_cfg *cfg_pdev) /** * ol_txrx_wrapper_peer_state_update() - specify the peer's authentication state - * @data_peer - which peer has changed its state + * @soc_hdl - datapath soc handle + * @peer_mac - mac address of which peer has changed its state * @state - the new state of the peer * * Specify the peer's authentication state (none, connected, authenticated) @@ -5390,59 +5823,12 @@ static int ol_txrx_wrapper_cfg_is_high_latency(struct cdp_cfg *cfg_pdev) * * Return: QDF Status */ -static QDF_STATUS ol_txrx_wrapper_peer_state_update(struct cdp_pdev *pdev, - uint8_t *peer_mac, enum ol_txrx_peer_state state) +static QDF_STATUS ol_txrx_wrapper_peer_state_update( + struct cdp_soc_t *soc_hdl, + uint8_t *peer_mac, + enum ol_txrx_peer_state state) { - return ol_txrx_peer_state_update(pdev, - peer_mac, state); -} - -/** - * ol_txrx_wrapper_find_peer_by_addr() - find peer instance by address - * @pdev: pdev handle - * @peer_addr: peer address want to find - * @peer_id: peer id - * - * Return: peer instance pointer - */ -static void *ol_txrx_wrapper_find_peer_by_addr(struct cdp_pdev *pdev, - uint8_t *peer_addr, uint8_t *peer_id) -{ - return ol_txrx_find_peer_by_addr(pdev, - peer_addr, peer_id); -} - -/** - * ol_txrx_wrapper_peer_get_ref_by_addr() - get peer reference by address - * @pdev: pdev handle - * @peer_addr: peer address we want to find - * @peer_id: peer id - * @debug_id: peer debug id for tracking - * - * Return: peer instance pointer - */ -static void * -ol_txrx_wrapper_peer_get_ref_by_addr(struct cdp_pdev *pdev, - u8 *peer_addr, uint8_t *peer_id, - enum peer_debug_id_type debug_id) -{ - return ol_txrx_peer_get_ref_by_addr((ol_txrx_pdev_handle)pdev, - peer_addr, peer_id, debug_id); -} - -/** - * ol_txrx_wrapper_peer_release_ref() - release peer reference - * @peer: peer handle - * @debug_id: peer debug id for tracking - * - * Release peer ref acquired by peer get ref api - * - * Return: void - */ -static void ol_txrx_wrapper_peer_release_ref(void *peer, - enum peer_debug_id_type debug_id) -{ - ol_txrx_peer_release_ref(peer, debug_id); + return ol_txrx_peer_state_update(soc_hdl, peer_mac, state); } /** @@ -5463,15 +5849,18 @@ ol_txrx_wrapper_set_flow_control_parameters(struct cdp_cfg *cfg_pdev, /** * ol_txrx_get_cfg() - get ini/cgf values in legacy dp - * @soc: soc context + * @soc_hdl: soc context * @cfg_param: cfg parameters * * Return: none */ -static uint32_t ol_txrx_get_cfg(void *soc, enum cdp_dp_cfg cfg) +static uint32_t ol_txrx_get_cfg(struct cdp_soc_t *soc_hdl, enum cdp_dp_cfg cfg) { struct txrx_pdev_cfg_t *cfg_ctx; - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id( + soc, + OL_TXRX_PDEV_ID); uint32_t value = 0; if (!pdev) { @@ -5487,15 +5876,30 @@ static uint32_t ol_txrx_get_cfg(void *soc, enum cdp_dp_cfg cfg) case cfg_dp_enable_ip_tcp_udp_checksum_offload: value = cfg_ctx->ip_tcp_udp_checksum_offload; break; + case cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload: + value = cfg_ctx->p2p_ip_tcp_udp_checksum_offload; + break; + case cfg_dp_enable_nan_ip_tcp_udp_checksum_offload: + value = cfg_ctx->nan_tcp_udp_checksumoffload; + break; case cfg_dp_tso_enable: value = cfg_ctx->tso_enable; break; case cfg_dp_lro_enable: value = cfg_ctx->lro_enable; break; + case cfg_dp_sg_enable: + value = cfg_ctx->sg_enable; + break; case cfg_dp_gro_enable: value = cfg_ctx->gro_enable; break; + case cfg_dp_tc_based_dyn_gro_enable: + value = cfg_ctx->tc_based_dyn_gro; + break; + case cfg_dp_tc_ingress_prio: + value = cfg_ctx->tc_ingress_prio; + break; #ifdef QCA_LL_TX_FLOW_CONTROL_V2 case cfg_dp_tx_flow_start_queue_offset: value = cfg_ctx->tx_flow_start_queue_offset; @@ -5536,11 +5940,79 @@ static uint32_t ol_txrx_get_cfg(void *soc, enum cdp_dp_cfg cfg) return value; } +/* + * ol_get_pdev_param: function to get parameters from pdev + * @cdp_soc: txrx soc handle + * @pdev_id: id of pdev handle + * @param: parameter type to be get + * @val: parameter type to be get + * + * Return: SUCCESS or FAILURE + */ +static QDF_STATUS ol_get_pdev_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + enum cdp_pdev_param_type param, + cdp_config_param_type *val) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *olpdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + struct cdp_pdev *pdev = ol_txrx_pdev_t_to_cdp_pdev(olpdev); + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + switch (param) { + case CDP_TX_PENDING: + val->cdp_pdev_param_tx_pending = ol_txrx_get_tx_pending(pdev); + break; + default: + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +/* + * ol_set_pdev_param: function to get parameters from pdev + * @cdp_soc: txrx soc handle + * @pdev_id: id of pdev handle + * @param: parameter type to be get + * @val: parameter type to be get + * + * Return: SUCCESS or FAILURE + */ +static QDF_STATUS ol_set_pdev_param(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + enum cdp_pdev_param_type param, + cdp_config_param_type val) +{ + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *olpdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + struct cdp_pdev *pdev = ol_txrx_pdev_t_to_cdp_pdev(olpdev); + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + switch (param) { + case CDP_MONITOR_CHANNEL: + { + ol_htt_mon_note_chan(pdev, val.cdp_pdev_param_monitor_chan); + break; + } + default: + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + #ifdef WDI_EVENT_ENABLE -void *ol_get_pldev(struct cdp_pdev *txrx_pdev) +void *ol_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct ol_txrx_pdev_t *pdev = - (struct ol_txrx_pdev_t *)txrx_pdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + if (pdev) return pdev->pl_dev; @@ -5553,6 +6025,8 @@ void *ol_get_pldev(struct cdp_pdev *txrx_pdev) * tx data packet, tx mgmt. packet and rx data packet * dump callback handler. * + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * @ol_tx_packetdump_cb: tx packetdump cb * @ol_rx_packetdump_cb: rx packetdump cb * @@ -5563,10 +6037,12 @@ void *ol_get_pldev(struct cdp_pdev *txrx_pdev) * */ static inline -void ol_register_packetdump_callback(ol_txrx_pktdump_cb ol_tx_packetdump_cb, +void ol_register_packetdump_callback(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + ol_txrx_pktdump_cb ol_tx_packetdump_cb, ol_txrx_pktdump_cb ol_rx_packetdump_cb) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { ol_txrx_err("pdev is NULL"); @@ -5581,6 +6057,8 @@ void ol_register_packetdump_callback(ol_txrx_pktdump_cb ol_tx_packetdump_cb, * ol_deregister_packetdump_callback() - deregidters * tx data packet, tx mgmt. packet and rx data packet * dump callback handler + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle * * This function is used to deregidter tx data pkt., * tx mgmt. pkt and rx data pkt. dump callback @@ -5589,9 +6067,11 @@ void ol_register_packetdump_callback(ol_txrx_pktdump_cb ol_tx_packetdump_cb, * */ static inline -void ol_deregister_packetdump_callback(void) +void ol_deregister_packetdump_callback(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!pdev) { ol_txrx_err("pdev is NULL"); @@ -5602,6 +6082,117 @@ void ol_deregister_packetdump_callback(void) pdev->ol_rx_packetdump_cb = NULL; } +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * ol_txrx_register_pktcapture_cb() - Register pkt capture mode callback + * @soc: soc handle + * @pdev_id: pdev id + * @context: virtual device's osif_dev + * @cb: callback to register + * + * Return: QDF_STATUS Enumeration + */ +static QDF_STATUS ol_txrx_register_pktcapture_cb( + struct cdp_soc_t *soc, + uint8_t pdev_id, + void *context, + QDF_STATUS(cb)(void *, qdf_nbuf_t)) +{ + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id( + cdp_soc_t_to_ol_txrx_soc_t(soc), + pdev_id); + + if (!pdev) { + ol_txrx_err("pdev NULL!"); + return QDF_STATUS_E_INVAL; + } + + pdev->mon_osif_dev = context; + pdev->mon_cb = cb; + return QDF_STATUS_SUCCESS; +} + +/** + * ol_txrx_deregister_pktcapture_cb() - Register pkt capture mode callback + * @soc: soc handle + * @pdev_id: pdev id + * + * Return: QDF_STATUS Enumeration + */ +static QDF_STATUS ol_txrx_deregister_pktcapture_cb(struct cdp_soc_t *soc, + uint8_t pdev_id) +{ + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id( + cdp_soc_t_to_ol_txrx_soc_t(soc), + pdev_id); + + if (qdf_unlikely(!pdev)) { + qdf_print("%s: pdev is NULL!\n", __func__); + qdf_assert(0); + return QDF_STATUS_E_INVAL; + } + + pdev->mon_osif_dev = NULL; + pdev->mon_cb = NULL; + + return QDF_STATUS_SUCCESS; +} + +/** + * ol_txrx_get_pktcapture_mode() - return pktcapture mode + * @soc: soc handle + * @pdev_id: pdev id + * + * Return: 0 - disable + * 1 - Mgmt packets + * 2 - Data packets + * 3 - Both Mgmt and Data packets + */ +static uint8_t ol_txrx_get_pktcapture_mode(struct cdp_soc_t *soc, + uint8_t pdev_id) +{ + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id( + cdp_soc_t_to_ol_txrx_soc_t(soc), + pdev_id); + + if (!pdev) { + qdf_print("%s: pdev is NULL\n", __func__); + return 0; + } + + if (!pdev->mon_cb || !pdev->mon_osif_dev) + return 0; + + return pdev->pktcapture_mode_value; +} + +/** + * ol_txrx_set_pktcapture_mode() - set pktcapture mode + * @soc: soc handle + * @pdev_id: pdev id + * @val : 0 - disable + * 1 - Mgmt packets + * 2 - Data packets + * 3 - Both Mgmt and Data packets + * + * Return: none + */ +static void ol_txrx_set_pktcapture_mode(struct cdp_soc_t *soc, + uint8_t pdev_id, uint8_t val) +{ + struct ol_txrx_pdev_t *pdev = ol_txrx_get_pdev_from_pdev_id( + cdp_soc_t_to_ol_txrx_soc_t(soc), + pdev_id); + + if (!pdev) { + qdf_print("%s: pdev is NULL\n", __func__); + return; + } + + pdev->pktcapture_mode_value = val; +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + static struct cdp_cmn_ops ol_ops_cmn = { .txrx_soc_attach_target = ol_txrx_soc_attach_target, .txrx_vdev_attach = ol_txrx_vdev_attach, @@ -5619,14 +6210,12 @@ static struct cdp_cmn_ops ol_ops_cmn = { .txrx_vdev_register = ol_txrx_vdev_register, .txrx_soc_detach = ol_txrx_soc_detach, .txrx_get_vdev_mac_addr = ol_txrx_get_vdev_mac_addr, - .txrx_get_vdev_from_vdev_id = ol_txrx_wrapper_get_vdev_from_vdev_id, .txrx_get_ctrl_pdev_from_vdev = ol_txrx_get_ctrl_pdev_from_vdev, .txrx_get_mon_vdev_from_pdev = ol_txrx_get_mon_vdev_from_pdev, .txrx_mgmt_send_ext = ol_txrx_mgmt_send_ext, .txrx_mgmt_tx_cb_set = ol_txrx_mgmt_tx_cb_set, .txrx_data_tx_cb_set = ol_txrx_data_tx_cb_set, .txrx_peer_unmap_sync_cb_set = ol_txrx_peer_unmap_sync_cb_set, - .txrx_get_tx_pending = ol_txrx_get_tx_pending, .flush_cache_rx_queue = ol_txrx_flush_cache_rx_queue, .txrx_fw_stats_get = ol_txrx_fw_stats_get, .display_stats = ol_txrx_display_stats, @@ -5663,7 +6252,15 @@ static struct cdp_misc_ops ol_ops_misc = { .pkt_log_init = htt_pkt_log_init, .pkt_log_con_service = ol_txrx_pkt_log_con_service, .register_pktdump_cb = ol_register_packetdump_callback, - .unregister_pktdump_cb = ol_deregister_packetdump_callback + .unregister_pktdump_cb = ol_deregister_packetdump_callback, +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + .pdev_reset_driver_del_ack = ol_tx_pdev_reset_driver_del_ack, + .vdev_set_driver_del_ack_enable = ol_tx_vdev_set_driver_del_ack_enable, +#endif +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + .vdev_set_bundle_require_flag = ol_tx_vdev_set_bundle_require, + .pdev_reset_bundle_require_flag = ol_tx_pdev_reset_bundle_require, +#endif }; static struct cdp_flowctl_ops ol_ops_flowctl = { @@ -5779,28 +6376,24 @@ static struct cdp_cfg_ops ol_ops_cfg = { static struct cdp_peer_ops ol_ops_peer = { .register_peer = ol_txrx_wrapper_register_peer, .clear_peer = ol_txrx_clear_peer, - .peer_get_ref_by_addr = ol_txrx_wrapper_peer_get_ref_by_addr, - .peer_release_ref = ol_txrx_wrapper_peer_release_ref, - .find_peer_by_addr = ol_txrx_wrapper_find_peer_by_addr, - .find_peer_by_addr_and_vdev = ol_txrx_find_peer_by_addr_and_vdev, - .local_peer_id = ol_txrx_local_peer_id, - .peer_find_by_local_id = ol_txrx_wrapper_peer_find_by_local_id, + .find_peer_exist = ol_txrx_find_peer_exist, + .find_peer_exist_on_vdev = ol_txrx_find_peer_exist_on_vdev, + .find_peer_exist_on_other_vdev = ol_txrx_find_peer_exist_on_other_vdev, .peer_state_update = ol_txrx_wrapper_peer_state_update, .get_vdevid = ol_txrx_get_vdevid, - .get_vdev_by_sta_id = ol_txrx_get_vdev_by_sta_id, + .get_vdev_by_peer_addr = ol_txrx_wrapper_get_vdev_by_peer_addr, .register_ocb_peer = ol_txrx_register_ocb_peer, .peer_get_peer_mac_addr = ol_txrx_peer_get_peer_mac_addr, .get_peer_state = ol_txrx_get_peer_state, - .get_vdev_for_peer = ol_txrx_get_vdev_for_peer, .update_ibss_add_peer_num_of_vdev = ol_txrx_update_ibss_add_peer_num_of_vdev, - .remove_peers_for_vdev = ol_txrx_remove_peers_for_vdev, - .remove_peers_for_vdev_no_lock = ol_txrx_remove_peers_for_vdev_no_lock, #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) .copy_mac_addr_raw = ol_txrx_copy_mac_addr_raw, .add_last_real_peer = ol_txrx_add_last_real_peer, .is_vdev_restore_last_peer = is_vdev_restore_last_peer, .update_last_real_peer = ol_txrx_update_last_real_peer, + .set_tdls_offchan_enabled = ol_txrx_set_tdls_offchan_enabled, + .set_peer_as_tdls_peer = ol_txrx_set_peer_as_tdls_peer, #endif /* CONFIG_HL_SUPPORT */ .peer_detach_force_delete = ol_txrx_peer_detach_force_delete, .peer_flush_frags = ol_txrx_peer_flush_frags, @@ -5823,6 +6416,8 @@ static struct cdp_ctrl_ops ol_ops_ctrl = { .txrx_get_pldev = ol_get_pldev, .txrx_wdi_event_sub = wdi_event_sub, .txrx_wdi_event_unsub = wdi_event_unsub, + .txrx_get_pdev_param = ol_get_pdev_param, + .txrx_set_pdev_param = ol_set_pdev_param }; /* WINplatform specific structures */ @@ -5831,7 +6426,7 @@ static struct cdp_me_ops ol_ops_me = { }; static struct cdp_mon_ops ol_ops_mon = { - .txrx_monitor_record_channel = ol_htt_mon_note_chan, + /* EMPTY FOR MCL */ }; static struct cdp_host_stats_ops ol_ops_host_stats = { @@ -5847,31 +6442,11 @@ static struct cdp_raw_ops ol_ops_raw = { }; #ifdef WLAN_FEATURE_PKT_CAPTURE -/** - * ol_txrx_pktcapture_record_channel() - Update Channel Information - * for packet capture mode - * @soc: pointer to cdp_soc_t - * @pdev_id: pdev id - * @mon_ch: channel - * - * Return: None - */ -static void -ol_txrx_pktcapture_record_channel(struct cdp_soc_t *soc, - uint8_t pdev_id, int mon_ch) -{ - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - qdf_print("%s: pdev is NULL\n", __func__); - return; - } - - htt_rx_mon_note_capture_channel(pdev->htt_pdev, mon_ch); -} - static struct cdp_pktcapture_ops ol_ops_pkt_capture = { - .txrx_pktcapture_record_channel = ol_txrx_pktcapture_record_channel, + .txrx_pktcapture_cb_register = ol_txrx_register_pktcapture_cb, + .txrx_pktcapture_cb_deregister = ol_txrx_deregister_pktcapture_cb, + .txrx_pktcapture_set_mode = ol_txrx_set_pktcapture_mode, + .txrx_pktcapture_get_mode = ol_txrx_get_pktcapture_mode, }; #endif /* #ifdef WLAN_FEATURE_PKT_CAPTURE */ @@ -5907,23 +6482,20 @@ static struct cdp_ops ol_txrx_ops = { #endif }; -/* - * Local prototype added to temporarily address warning caused by - * -Wmissing-prototypes. A more correct solution, namely to expose - * a prototype in an appropriate header file, will come later. - */ -struct cdp_soc_t *ol_txrx_soc_attach(void *scn_handle, - struct ol_if_ops *dp_ol_if_ops); -struct cdp_soc_t *ol_txrx_soc_attach(void *scn_handle, - struct ol_if_ops *dp_ol_if_ops) +ol_txrx_soc_handle ol_txrx_soc_attach(void *scn_handle, + struct ol_if_ops *dp_ol_if_ops) { - struct cdp_soc_t *soc = qdf_mem_malloc(sizeof(struct cdp_soc_t)); + struct ol_txrx_soc_t *soc; + soc = qdf_mem_malloc(sizeof(*soc)); if (!soc) return NULL; - soc->ops = &ol_txrx_ops; - return soc; + soc->psoc = scn_handle; + soc->cdp_soc.ops = &ol_txrx_ops; + soc->cdp_soc.ol_ops = dp_ol_if_ops; + + return ol_txrx_soc_t_to_cdp_soc_t(soc); } bool ol_txrx_get_new_htt_msg_format(struct ol_txrx_pdev_t *pdev) @@ -5937,8 +6509,10 @@ bool ol_txrx_get_new_htt_msg_format(struct ol_txrx_pdev_t *pdev) void ol_txrx_set_new_htt_msg_format(uint8_t val) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { qdf_print("%s: pdev is NULL\n", __func__); return; @@ -5948,8 +6522,15 @@ void ol_txrx_set_new_htt_msg_format(uint8_t val) bool ol_txrx_get_peer_unmap_conf_support(void) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return false; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { qdf_print("%s: pdev is NULL\n", __func__); return false; @@ -5959,8 +6540,15 @@ bool ol_txrx_get_peer_unmap_conf_support(void) void ol_txrx_set_peer_unmap_conf_support(bool val) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { qdf_print("%s: pdev is NULL\n", __func__); return; @@ -5971,8 +6559,15 @@ void ol_txrx_set_peer_unmap_conf_support(bool val) #ifdef WLAN_FEATURE_TSF_PLUS bool ol_txrx_get_tx_compl_tsf64(void) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return false; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { qdf_print("%s: pdev is NULL\n", __func__); return false; @@ -5982,12 +6577,20 @@ bool ol_txrx_get_tx_compl_tsf64(void) void ol_txrx_set_tx_compl_tsf64(bool val) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { - qdf_print("%s: pdev is NULL\n", __func__); + ol_txrx_err("pdev is NULL"); return; } + pdev->enable_tx_compl_tsf64 = val; } #else diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.h index 7f457156ca36dce9d95220406931201989eefb13..d677f1b7f36050a03cfd9ddedf310795c2a75987 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,7 @@ #include #include #include +#include /* * Pool of tx descriptors reserved for @@ -66,13 +67,22 @@ enum ol_txrx_fc_limit_id { ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev, u8 *peer_addr, - u8 *peer_id, enum peer_debug_id_type - dbg_id); + dbg_id); int ol_txrx_peer_release_ref(ol_txrx_peer_handle peer, enum peer_debug_id_type dbg_id); +/** + * ol_txrx_soc_attach() - initialize the soc + * @scn_handle: Opaque SOC handle from control plane + * @dp_ol_if_ops: Offload Operations + * + * Return: SOC handle on success, NULL on failure + */ +ol_txrx_soc_handle ol_txrx_soc_attach(void *scn_handle, + struct ol_if_ops *dp_ol_if_ops); + /** * ol_tx_desc_pool_size_hl() - allocate tx descriptor pool size for HL systems * @ctrl_pdev: the control pdev handle @@ -107,23 +117,31 @@ ol_tx_desc_pool_size_hl(struct cdp_cfg *ctrl_pdev); #define TXRX_HL_TX_DESC_QUEUE_RESTART_TH \ (TXRX_HL_TX_DESC_HI_PRIO_RESERVED + 100) +struct peer_hang_data { + uint16_t tlv_header; + uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE]; + uint16_t peer_timeout_bitmask; +} qdf_packed; + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) void -ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *vdev, bool flag); +ol_txrx_hl_tdls_flag_reset(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool flag); #else static inline void -ol_txrx_hl_tdls_flag_reset(struct cdp_vdev *vdev, bool flag) +ol_txrx_hl_tdls_flag_reset(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, bool flag) { } #endif #ifdef WDI_EVENT_ENABLE -void *ol_get_pldev(struct cdp_pdev *txrx_pdev); +void *ol_get_pldev(struct cdp_soc_t *soc, uint8_t pdev_id); #else static inline -void *ol_get_pldev(struct cdp_pdev *txrx_pdev) +void *ol_get_pldev(struct cdp_soc_t *soc, uint8_t pdev_id) { return NULL; } @@ -131,14 +149,26 @@ void *ol_get_pldev(struct cdp_pdev *txrx_pdev) #ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID ol_txrx_peer_handle -ol_txrx_peer_find_by_local_id(struct cdp_pdev *pdev, - uint8_t local_peer_id); -ol_txrx_peer_handle ol_txrx_peer_get_ref_by_local_id(struct cdp_pdev *ppdev, uint8_t local_peer_id, enum peer_debug_id_type dbg_id); #endif /* QCA_SUPPORT_TXRX_LOCAL_PEER_ID */ +/** + * ol_txrx_get_pdev_from_pdev_id() - Returns pdev object given the pdev id + * @soc: core DP soc context + * @pdev_id: pdev id from pdev object can be retrieved + * + * Return: Pointer to DP pdev object + */ + +static inline struct ol_txrx_pdev_t * +ol_txrx_get_pdev_from_pdev_id(struct ol_txrx_soc_t *soc, + uint8_t pdev_id) +{ + return soc->pdev_list[pdev_id]; +} + /* * @nbuf: buffer which contains data to be displayed * @nbuf_paddr: physical address of the buffer @@ -149,38 +179,122 @@ ol_txrx_peer_get_ref_by_local_id(struct cdp_pdev *ppdev, void ol_txrx_dump_pkt(qdf_nbuf_t nbuf, uint32_t nbuf_paddr, int len); +/** + * ol_txrx_get_vdev_from_vdev_id() - get vdev from vdev_id + * @vdev_id: vdev_id + * + * Return: vdev handle + * NULL if not found. + */ struct cdp_vdev *ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id); /** - * ol_txrx_get_mon_vdev_from_pdev() - get monitor mode vdev from pdev - * @ppdev: the physical device the virtual device belongs to + * ol_txrx_get_vdev_from_soc_vdev_id() - get vdev from soc and vdev_id + * @soc: datapath soc handle + * @vdev_id: vdev_id * * Return: vdev handle - * NULL if not found. + * NULL if not found. + */ +struct ol_txrx_vdev_t *ol_txrx_get_vdev_from_soc_vdev_id( + struct ol_txrx_soc_t *soc, uint8_t vdev_id); + +/** + * ol_txrx_get_mon_vdev_from_pdev() - get monitor mode vdev from pdev + * @soc: datapath soc handle + * @pdev_id: the physical device id the virtual device belongs to + * + * Return: vdev id + * error if not found. */ -struct cdp_vdev *ol_txrx_get_mon_vdev_from_pdev(struct cdp_pdev *ppdev); +uint8_t ol_txrx_get_mon_vdev_from_pdev(struct cdp_soc_t *soc, + uint8_t pdev_id); + +/** + * ol_txrx_get_vdev_by_peer_addr() - Get vdev handle by peer mac address + * @ppdev - data path device instance + * @peer_addr - peer mac address + * + * Get virtual interface handle by local peer mac address + * + * Return: Virtual interface instance handle + * NULL in case cannot find + */ +ol_txrx_vdev_handle +ol_txrx_get_vdev_by_peer_addr(struct cdp_pdev *ppdev, + struct qdf_mac_addr peer_addr); void *ol_txrx_find_peer_by_addr(struct cdp_pdev *pdev, - uint8_t *peer_addr, - uint8_t *peer_id); + uint8_t *peer_addr); -void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *scn); +/** + * @brief specify the peer's authentication state + * @details + * Specify the peer's authentication state (none, connected, authenticated) + * to allow the data SW to determine whether to filter out invalid data frames. + * (In the "connected" state, where security is enabled, but authentication + * has not completed, tx and rx data frames other than EAPOL or WAPI should + * be discarded.) + * This function is only relevant for systems in which the tx and rx filtering + * are done in the host rather than in the target. + * + * @param soc - datapath soc handle + * @param peer_mac - mac address of which peer has changed its state + * @param state - the new state of the peer + * + * Return: QDF Status + */ +QDF_STATUS ol_txrx_peer_state_update(struct cdp_soc_t *soc_hdl, + uint8_t *peer_mac, + enum ol_txrx_peer_state state); + +void htt_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn); void peer_unmap_timer_handler(void *data); #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL -int ol_txrx_register_tx_flow_control(uint8_t vdev_id, +/** + * ol_txrx_register_tx_flow_control() - register tx flow control callback + * @soc_hdl: soc handle + * @vdev_id: vdev_id + * @flowControl: flow control callback + * @osif_fc_ctx: callback context + * @flow_control_is_pause: is vdev paused by flow control + * + * Return: 0 for success or error code + */ +int ol_txrx_register_tx_flow_control(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, ol_txrx_tx_flow_control_fp flow_control, void *osif_fc_ctx, ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause); -int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id); +/** + * ol_txrx_de_register_tx_flow_control_cb() - deregister tx flow control + * callback + * @soc_hdl: soc handle + * @vdev_id: vdev_id + * + * Return: 0 for success or error code + */ +int ol_txrx_deregister_tx_flow_control_cb(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id); -bool ol_txrx_get_tx_resource(uint8_t sta_id, +bool ol_txrx_get_tx_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr, unsigned int low_watermark, unsigned int high_watermark_offset); -int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth); +/** + * ol_txrx_ll_set_tx_pause_q_depth() - set pause queue depth + * @soc_hdl: soc handle + * @vdev_id: vdev id + * @pause_q_depth: pause queue depth + * + * Return: 0 for success or error code + */ +int ol_txrx_ll_set_tx_pause_q_depth(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, int pause_q_depth); #endif void ol_tx_init_pdev(ol_txrx_pdev_handle pdev); @@ -228,12 +342,75 @@ ol_txrx_pdev_grp_stat_destroy(struct ol_txrx_pdev_t *pdev) {} #endif #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) -void ol_txrx_copy_mac_addr_raw(struct cdp_vdev *pvdev, uint8_t *bss_addr); -void ol_txrx_add_last_real_peer(struct cdp_pdev *ppdev, - struct cdp_vdev *pvdev, uint8_t *peer_id); -bool is_vdev_restore_last_peer(void *ppeer); -void ol_txrx_update_last_real_peer(struct cdp_pdev *ppdev, void *pvdev, - uint8_t *peer_id, bool restore_last_peer); +/** + * ol_txrx_copy_mac_addr_raw() - copy raw mac addr + * @soc_hdl: datapath soc handle + * @vdev_id: the data virtual device id + * @bss_addr: bss address + * + * Return: None + */ +void ol_txrx_copy_mac_addr_raw(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *bss_addr); + +/** + * ol_txrx_add_last_real_peer() - add last peer + * @soc_hdl: datapath soc handle + * @pdev_id: the data physical device id + * @vdev_id: virtual device id + * + * Return: None + */ +void ol_txrx_add_last_real_peer(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id); + +/** + * is_vdev_restore_last_peer() - check for vdev last peer + * @soc: datapath soc handle + * vdev_id: vdev id + * @peer_mac: peer mac address + * + * Return: true if last peer is not null + */ +bool is_vdev_restore_last_peer(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac); + +/** + * ol_txrx_update_last_real_peer() - check for vdev last peer + * @soc: datapath soc handle + * @pdev_id: the data physical device id + * @vdev_id: vdev_id + * @restore_last_peer: restore last peer flag + * + * Return: None + */ +void ol_txrx_update_last_real_peer(struct cdp_soc_t *soc, uint8_t pdev_id, + uint8_t vdev_id, + bool restore_last_peer); + +/** + * ol_txrx_set_peer_as_tdls_peer() - mark peer as tdls peer + * @soc: pointer to SOC handle + * @vdev_id: virtual interface id + * @peer_mac: peer mac address + * @value: false/true + * + * Return: None + */ +void ol_txrx_set_peer_as_tdls_peer(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val); + +/** + * ol_txrx_set_tdls_offchan_enabled() - set tdls offchan enabled + * @soc: pointer to SOC handle + * @vdev_id: virtual interface id + * @peer_mac: peer mac address + * @value: false/true + * + * Return: None + */ +void ol_txrx_set_tdls_offchan_enabled(struct cdp_soc_t *soc, uint8_t vdev_id, + uint8_t *peer_mac, bool val); #endif #if defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG) @@ -292,6 +469,78 @@ uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev) #endif #endif +/** + * cdp_soc_t_to_ol_txrx_soc_t() - typecast cdp_soc_t to ol_txrx_soc_t + * @soc: OL soc handle + * + * Return: struct ol_txrx_soc_t pointer + */ +static inline +struct ol_txrx_soc_t *cdp_soc_t_to_ol_txrx_soc_t(ol_txrx_soc_handle soc) +{ + return (struct ol_txrx_soc_t *)soc; +} + +/** + * ol_txrx_soc_t_to_cdp_soc_t() - typecast ol_txrx_soc_t to cdp_soc + * @soc: Opaque soc handle + * + * Return: struct cdp_soc_t pointer + */ +static inline +ol_txrx_soc_handle ol_txrx_soc_t_to_cdp_soc_t(struct ol_txrx_soc_t *soc) +{ + return (struct cdp_soc_t *)soc; +} + +/** + * cdp_pdev_to_ol_txrx_pdev_t() - typecast cdp_pdev to ol_txrx_pdev_t + * @pdev: OL pdev handle + * + * Return: struct ol_txrx_pdev_t pointer + */ +static inline +struct ol_txrx_pdev_t *cdp_pdev_to_ol_txrx_pdev_t(struct cdp_pdev *pdev) +{ + return (struct ol_txrx_pdev_t *)pdev; +} + +/** + * ol_txrx_pdev_t_to_cdp_pdev() - typecast ol_txrx_pdev_t to cdp_pdev + * @pdev: Opaque pdev handle + * + * Return: struct cdp_pdev pointer + */ +static inline +struct cdp_pdev *ol_txrx_pdev_t_to_cdp_pdev(struct ol_txrx_pdev_t *pdev) +{ + return (struct cdp_pdev *)pdev; +} + +/** + * cdp_vdev_to_ol_txrx_vdev_t() - typecast cdp_vdev to ol_txrx_vdev_t + * @vdev: OL vdev handle + * + * Return: struct ol_txrx_vdev_t pointer + */ +static inline +struct ol_txrx_vdev_t *cdp_vdev_to_ol_txrx_vdev_t(struct cdp_vdev *vdev) +{ + return (struct ol_txrx_vdev_t *)vdev; +} + +/** + * ol_txrx_vdev_t_to_cdp_vdev() - typecast ol_txrx_vdev_t to cdp_vdev + * @vdev: Opaque vdev handle + * + * Return: struct cdp_vdev pointer + */ +static inline +struct cdp_vdev *ol_txrx_vdev_t_to_cdp_vdev(struct ol_txrx_vdev_t *vdev) +{ + return (struct cdp_vdev *)vdev; +} + #ifdef QCA_LL_TX_FLOW_CONTROL_V2 void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc); uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev); @@ -314,16 +563,26 @@ uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev); * Return: true ; forward the packet, i.e., below threshold * false; not enough descriptors, drop the packet */ -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev); +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev); /** * ol_tx_desc_thresh_reached() - is tx desc threshold reached - * @vdev: vdev handle + * @soc_hdl: Datapath soc handle + * @vdev_id: id of vdev * * Return: true if tx desc available reached threshold or false otherwise */ -static inline bool ol_tx_desc_thresh_reached(struct cdp_vdev *vdev) +static inline bool ol_tx_desc_thresh_reached(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { + struct ol_txrx_vdev_t *vdev; + + vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { + dp_err("vdev is NULL"); + return false; + } + return !(ol_txrx_fwd_desc_thresh_check(vdev)); } @@ -341,7 +600,7 @@ uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev) } static inline -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev) +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev) { return true; } @@ -374,10 +633,39 @@ struct ol_txrx_stats_req_internal uint8_t desc_id); #ifdef QCA_HL_NETDEV_FLOW_CONTROL -int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc, +/** + * ol_txrx_register_hl_flow_control() -register hl netdev flow control callback + * @soc_hdl: soc handle + * @pdev_id: datapath pdev identifier + * @flowControl: flow control callback + * + * Return: 0 for success or error code + */ +int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, tx_pause_callback flowcontrol); -int ol_txrx_set_vdev_os_queue_status(u8 vdev_id, enum netif_action_type action); -int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan); + +/** + * ol_txrx_set_vdev_os_queue_status() - Set OS queue status for a vdev + * @soc_hdl: soc handle + * @vdev_id: vdev id for the vdev under consideration. + * @action: action to be done on queue for vdev + * + * Return: 0 on success, -EINVAL on failure + */ +int ol_txrx_set_vdev_os_queue_status(struct cdp_soc_t *soc_hdl, u8 vdev_id, + enum netif_action_type action); + +/** + * ol_txrx_set_vdev_tx_desc_limit() - Set TX descriptor limits for a vdev + * @soc_hdl: soc handle + * @vdev_id: vdev id for the vdev under consideration. + * @chan_freq: channel frequency on which the vdev has been started. + * + * Return: 0 on success, -EINVAL on failure + */ +int ol_txrx_set_vdev_tx_desc_limit(struct cdp_soc_t *soc_hdl, u8 vdev_id, + u32 chan_freq); #endif /** @@ -437,4 +725,195 @@ bool ol_txrx_get_tx_compl_tsf64(void); * return NONE */ void ol_txrx_set_tx_compl_tsf64(bool val); + +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + +/** + * ol_txrx_vdev_init_tcp_del_ack() - initialize tcp delayed ack structure + * @vdev: vdev handle + * + * Return: none + */ +void ol_txrx_vdev_init_tcp_del_ack(struct ol_txrx_vdev_t *vdev); + +/** + * ol_txrx_vdev_deinit_tcp_del_ack() - deinitialize tcp delayed ack structure + * @vdev: vdev handle + * + * Return: none + */ +void ol_txrx_vdev_deinit_tcp_del_ack(struct ol_txrx_vdev_t *vdev); + +/** + * ol_txrx_vdev_free_tcp_node() - add tcp node in free list + * @vdev: vdev handle + * @node: tcp stream node + * + * Return: none + */ +void ol_txrx_vdev_free_tcp_node(struct ol_txrx_vdev_t *vdev, + struct tcp_stream_node *node); + +/** + * ol_txrx_vdev_alloc_tcp_node() - allocate tcp node + * @vdev: vdev handle + * + * Return: tcp stream node + */ +struct tcp_stream_node * +ol_txrx_vdev_alloc_tcp_node(struct ol_txrx_vdev_t *vdev); + +/** + * ol_tx_pdev_reset_driver_del_ack() - reset driver delayed ack enabled flag + * @ppdev: the data physical device + * + * Return: none + */ +void +ol_tx_pdev_reset_driver_del_ack(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * ol_tx_vdev_set_driver_del_ack_enable() - set driver delayed ack enabled flag + * @soc_hdl: datapath soc handle + * @vdev_id: vdev id + * @rx_packets: number of rx packets + * @time_in_ms: time in ms + * @high_th: high threshold + * @low_th: low threshold + * + * Return: none + */ +void +ol_tx_vdev_set_driver_del_ack_enable(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + unsigned long rx_packets, + uint32_t time_in_ms, + uint32_t high_th, + uint32_t low_th); + +/** + * ol_tx_hl_send_all_tcp_ack() - send all queued tcp ack packets + * @vdev: vdev handle + * + * Return: none + */ +void ol_tx_hl_send_all_tcp_ack(struct ol_txrx_vdev_t *vdev); + +/** + * tcp_del_ack_tasklet() - tasklet function to send ack packets + * @data: vdev handle + * + * Return: none + */ +void tcp_del_ack_tasklet(void *data); + +/** + * ol_tx_get_stream_id() - get stream_id from packet info + * @info: packet info + * + * Return: stream_id + */ +uint16_t ol_tx_get_stream_id(struct packet_info *info); + +/** + * ol_tx_get_packet_info() - update packet info for passed msdu + * @msdu: packet + * @info: packet info + * + * Return: none + */ +void ol_tx_get_packet_info(qdf_nbuf_t msdu, struct packet_info *info); + +/** + * ol_tx_hl_find_and_send_tcp_stream() - find and send tcp stream for passed + * stream info + * @vdev: vdev handle + * @info: packet info + * + * Return: none + */ +void ol_tx_hl_find_and_send_tcp_stream(struct ol_txrx_vdev_t *vdev, + struct packet_info *info); + +/** + * ol_tx_hl_find_and_replace_tcp_ack() - find and replace tcp ack packet for + * passed packet info + * @vdev: vdev handle + * @msdu: packet + * @info: packet info + * + * Return: none + */ +void ol_tx_hl_find_and_replace_tcp_ack(struct ol_txrx_vdev_t *vdev, + qdf_nbuf_t msdu, + struct packet_info *info); + +/** + * ol_tx_hl_vdev_tcp_del_ack_timer() - delayed ack timer function + * @timer: timer handle + * + * Return: enum + */ +enum qdf_hrtimer_restart_status +ol_tx_hl_vdev_tcp_del_ack_timer(qdf_hrtimer_data_t *timer); + +/** + * ol_tx_hl_del_ack_queue_flush_all() - drop all queued packets + * @vdev: vdev handle + * + * Return: none + */ +void ol_tx_hl_del_ack_queue_flush_all(struct ol_txrx_vdev_t *vdev); + +#else + +static inline +void ol_txrx_vdev_init_tcp_del_ack(struct ol_txrx_vdev_t *vdev) +{ +} + +static inline +void ol_txrx_vdev_deinit_tcp_del_ack(struct ol_txrx_vdev_t *vdev) +{ +} + +static inline +void ol_tx_pdev_reset_driver_del_ack(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ +} + +static inline +void ol_tx_vdev_set_driver_del_ack_enable(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + unsigned long rx_packets, + uint32_t time_in_ms, + uint32_t high_th, + uint32_t low_th) +{ +} + +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +void ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_bytes, + uint32_t time_in_ms, uint32_t high_th, + uint32_t low_th); + +void ol_tx_pdev_reset_bundle_require(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +#else + +static inline +void ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_bytes, + uint32_t time_in_ms, uint32_t high_th, + uint32_t low_th) +{ +} + +static inline +void ol_tx_pdev_reset_bundle_require(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) +{ +} +#endif + #endif /* _OL_TXRX__H_ */ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_event.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_event.c index 3dc5d97ce0ed8877f6d5d673121ef71641e021ca..d9ff0c30fe818bef9f4dcdc58cfc0f8cfbbc583a 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_event.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_event.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -17,6 +17,7 @@ */ #include "ol_txrx_types.h" +#include "ol_txrx.h" static inline wdi_event_subscribe *wdi_event_next_sub(wdi_event_subscribe * wdi_sub) @@ -66,24 +67,28 @@ wdi_event_iter_sub(struct ol_txrx_pdev_t *pdev, void wdi_event_handler(enum WDI_EVENT event, - struct cdp_pdev *ppdev, void *data) + uint8_t pdev_id, void *data) { uint32_t event_index; wdi_event_subscribe *wdi_sub; - struct ol_txrx_pdev_t *txrx_pdev = - (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle txrx_pdev; /* * Input validation */ if (!event) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Invalid WDI event in %s\n", __func__); + ol_txrx_err("Invalid WDI event"); + return; + } + if (!soc) { + ol_txrx_err("Invalid soc"); return; } + + txrx_pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); if (!txrx_pdev) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Invalid pdev in WDI event handler\n"); + ol_txrx_err("Invalid pdev"); return; } /* @@ -99,15 +104,15 @@ wdi_event_handler(enum WDI_EVENT event, } int -wdi_event_sub(struct cdp_pdev *ppdev, - void *pevent_cb_sub, uint32_t event) +wdi_event_sub(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + wdi_event_subscribe *pevent_cb_sub, uint32_t event) { uint32_t event_index; wdi_event_subscribe *wdi_sub; - struct ol_txrx_pdev_t *txrx_pdev = - (struct ol_txrx_pdev_t *)ppdev; - wdi_event_subscribe *event_cb_sub = - (wdi_event_subscribe *)pevent_cb_sub; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle txrx_pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); + wdi_event_subscribe *event_cb_sub = pevent_cb_sub; /* Input validation */ if (!txrx_pdev || !txrx_pdev->wdi_event_list) { @@ -149,16 +154,22 @@ wdi_event_sub(struct cdp_pdev *ppdev, } int -wdi_event_unsub(struct cdp_pdev *ppdev, - void *pevent_cb_sub, uint32_t event) +wdi_event_unsub(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + wdi_event_subscribe *pevent_cb_sub, uint32_t event) { uint32_t event_index = event - WDI_EVENT_BASE; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle txrx_pdev = ol_txrx_get_pdev_from_pdev_id(soc, + pdev_id); - struct ol_txrx_pdev_t *txrx_pdev = - (struct ol_txrx_pdev_t *)ppdev; + wdi_event_subscribe *event_cb_sub = pevent_cb_sub; - wdi_event_subscribe *event_cb_sub = - (wdi_event_subscribe *)pevent_cb_sub; + /* Input validation */ + if (!txrx_pdev) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "Invalid txrx_pdev in %s", __func__); + return -EINVAL; + } /* Input validation */ if (!event_cb_sub) { diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_flow_control.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_flow_control.c index cd14b58c92865426b997b2a960dec20104d61834..bec7b1fd6b0e4377a1818d96460e43f60797f052 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_flow_control.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_flow_control.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -83,9 +83,8 @@ ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) } #endif -bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev) +bool ol_txrx_fwd_desc_thresh_check(struct ol_txrx_vdev_t *txrx_vdev) { - struct ol_txrx_vdev_t *txrx_vdev = (struct ol_txrx_vdev_t *)vdev; struct ol_tx_flow_pool_t *pool; bool enough_desc_flag; @@ -113,8 +112,15 @@ bool ol_txrx_fwd_desc_thresh_check(struct cdp_vdev *vdev) */ void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { qdf_print("pdev is NULL"); return; @@ -174,10 +180,13 @@ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) { int i = 0; struct ol_tx_flow_pool_t *pool = NULL; + struct cdp_soc_t *soc; if (!ol_tx_get_is_mgmt_over_wmi_enabled()) ol_tx_deregister_global_mgmt_pool(pdev); + soc = cds_get_context(QDF_MODULE_ID_SOC); + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); while (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { pool = TAILQ_FIRST(&pdev->tx_desc.flow_pool_list); @@ -187,7 +196,7 @@ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) ol_txrx_info("flow pool list is not empty %d!!!\n", i++); if (i == 1) - ol_tx_dump_flow_pool_info((void *)pdev); + ol_tx_dump_flow_pool_info(soc); ol_tx_dec_pool_ref(pool, true); qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); @@ -210,7 +219,8 @@ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) */ static int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; uint16_t i, size; union ol_tx_desc_list_elem_t *temp_list = NULL; struct ol_tx_desc_t *tx_desc = NULL; @@ -220,6 +230,14 @@ static int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force) QDF_ASSERT(0); return -ENOMEM; } + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + QDF_ASSERT(0); + return -ENOMEM; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); QDF_ASSERT(0); @@ -294,7 +312,8 @@ QDF_STATUS ol_tx_inc_pool_ref(struct ol_tx_flow_pool_t *pool) QDF_STATUS ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; if (!pool) { ol_txrx_err("flow pool is NULL"); @@ -302,6 +321,13 @@ QDF_STATUS ol_tx_dec_pool_ref(struct ol_tx_flow_pool_t *pool, bool force) return QDF_STATUS_E_INVAL; } + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + QDF_ASSERT(0); + return QDF_STATUS_E_INVAL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); QDF_ASSERT(0); @@ -347,20 +373,62 @@ static const char *ol_tx_flow_pool_status_to_str } } +void ol_tx_dump_flow_pool_info_compact(struct ol_txrx_pdev_t *pdev) +{ + char *comb_log_str; + int bytes_written = 0; + uint32_t free_size; + struct ol_tx_flow_pool_t *pool = NULL; + + free_size = WLAN_MAX_VDEVS * 100 + 100; + comb_log_str = qdf_mem_malloc(free_size); + if (!comb_log_str) + return; + + bytes_written = snprintf(&comb_log_str[bytes_written], free_size, + "G:(%d,%d) ", + pdev->tx_desc.pool_size, + pdev->tx_desc.num_free); + + free_size -= bytes_written; + + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); + TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list, + flow_pool_list_elem) { + qdf_spin_lock_bh(&pool->flow_pool_lock); + bytes_written += snprintf(&comb_log_str[bytes_written], + free_size, "| %d (%d,%d)", + pool->flow_pool_id, + pool->flow_pool_size, + pool->avail_desc); + free_size -= bytes_written; + qdf_spin_unlock_bh(&pool->flow_pool_lock); + } + qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); + qdf_nofl_debug("STATS | FC: %s", comb_log_str); + qdf_mem_free(comb_log_str); +} + /** * ol_tx_dump_flow_pool_info() - dump global_pool and flow_pool info - * @ctx: cdp_soc context, required only in lithium_dp flow control. - * Remove void * while cleaning up cds_get_context. + * @soc_hdl: cdp_soc context, required only in lithium_dp flow control. * * Return: none */ -void ol_tx_dump_flow_pool_info(void *ctx) +void ol_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool = NULL, *pool_prev = NULL; struct ol_tx_flow_pool_t tmp_pool; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + QDF_ASSERT(0); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("ERROR: pdev NULL"); QDF_ASSERT(0); /* traceback */ @@ -426,8 +494,15 @@ void ol_tx_dump_flow_pool_info(void *ctx) */ void ol_tx_clear_flow_pool_stats(void) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is null"); return; @@ -500,11 +575,18 @@ static int ol_tx_move_desc_n(struct ol_tx_flow_pool_t *src_pool, static int ol_tx_distribute_descs_to_deficient_pools(struct ol_tx_flow_pool_t *src_pool) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *dst_pool = NULL; uint16_t desc_count = src_pool->avail_desc; uint16_t desc_move_count = 0; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return -EINVAL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return -EINVAL; @@ -557,7 +639,8 @@ ol_tx_distribute_descs_to_deficient_pools(struct ol_tx_flow_pool_t *src_pool) struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, uint16_t flow_pool_size) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool; uint16_t size = 0, i; struct ol_tx_desc_t *tx_desc; @@ -565,6 +648,12 @@ struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, uint32_t stop_threshold; uint32_t start_threshold; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return NULL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return NULL; @@ -633,8 +722,15 @@ struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, */ int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return -EINVAL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if ((!pdev) || (!pool) || (pool->status != FLOW_POOL_INVALID)) { ol_txrx_err("Invalid pool/pdev"); return -EINVAL; @@ -662,10 +758,18 @@ int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool) */ static struct ol_tx_flow_pool_t *ol_tx_get_flow_pool(uint8_t flow_pool_id) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool = NULL; bool is_found = false; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + QDF_ASSERT(0); + return NULL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("ERROR: pdev NULL"); QDF_ASSERT(0); /* traceback */ @@ -754,7 +858,8 @@ static void ol_tx_flow_pool_vdev_unmap(struct ol_tx_flow_pool_t *pool, void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, uint8_t flow_pool_id, uint16_t flow_pool_size) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool; uint8_t pool_create = 0; enum htt_flow_type type = flow_type; @@ -762,6 +867,12 @@ void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, ol_txrx_dbg("flow_id %d flow_type %d flow_pool_id %d flow_pool_size %d", flow_id, flow_type, flow_pool_id, flow_pool_size); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) { ol_txrx_err("pdev is NULL"); return; @@ -812,13 +923,20 @@ void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, uint8_t flow_pool_id) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool; enum htt_flow_type type = flow_type; ol_txrx_dbg("flow_id %d flow_type %d flow_pool_id %d", flow_id, flow_type, flow_pool_id); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) { ol_txrx_err("pdev is NULL"); return; @@ -859,7 +977,8 @@ void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, */ int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *dst_pool = NULL; struct ol_tx_flow_pool_t *tmp_pool = NULL; uint16_t total_desc_req = 0; @@ -869,6 +988,12 @@ int ol_tx_distribute_descs_to_deficient_pools_from_global_pool(void) struct ol_tx_desc_t *tx_desc; uint8_t free_invalid_pool = 0; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return -EINVAL; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (!pdev) { ol_txrx_err("pdev is NULL"); return -EINVAL; @@ -995,12 +1120,25 @@ static void ol_tx_flow_pool_update(struct ol_tx_flow_pool_t *pool, uint16_t deficient_count, uint16_t overflow_count) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - uint32_t stop_threshold = - ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev); - uint32_t start_threshold = stop_threshold + - ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; + uint32_t stop_threshold; + uint32_t start_threshold; + + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + stop_threshold = ol_cfg_get_tx_flow_stop_queue_th(pdev->ctrl_pdev); + start_threshold = stop_threshold + + ol_cfg_get_tx_flow_start_queue_offset(pdev->ctrl_pdev); pool->flow_pool_size = new_pool_size; pool->start_th = (start_threshold * new_pool_size) / 100; pool->stop_th = (stop_threshold * new_pool_size) / 100; @@ -1029,7 +1167,8 @@ static void ol_tx_flow_pool_update(struct ol_tx_flow_pool_t *pool, static void ol_tx_flow_pool_resize(struct ol_tx_flow_pool_t *pool, uint16_t new_pool_size) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; uint16_t diff = 0, overflow_count = 0, deficient_count = 0; uint16_t move_desc_to_global = 0, move_desc_from_global = 0; union ol_tx_desc_list_elem_t *temp_list = NULL; @@ -1037,6 +1176,17 @@ static void ol_tx_flow_pool_resize(struct ol_tx_flow_pool_t *pool, struct ol_tx_desc_t *tx_desc = NULL; uint16_t temp = 0; + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("pdev is NULL"); + return; + } + qdf_spin_lock_bh(&pool->flow_pool_lock); if (pool->flow_pool_size == new_pool_size) { qdf_spin_unlock_bh(&pool->flow_pool_lock); @@ -1161,12 +1311,19 @@ static void ol_tx_flow_pool_resize(struct ol_tx_flow_pool_t *pool, void ol_tx_flow_pool_resize_handler(uint8_t flow_pool_id, uint16_t flow_pool_size) { - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); + ol_txrx_pdev_handle pdev; struct ol_tx_flow_pool_t *pool; ol_txrx_dbg("flow_pool_id %d flow_pool_size %d", flow_pool_id, flow_pool_size); + if (qdf_unlikely(!soc)) { + ol_txrx_err("soc is NULL"); + return; + } + + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); if (qdf_unlikely(!pdev)) { ol_txrx_err("pdev is NULL"); return; @@ -1212,19 +1369,20 @@ ol_txrx_map_to_netif_reason_type(uint32_t reason) } } -/* - * ol_txrx_vdev_pause() - pause vdev network queues - * @vdev: vdev handle - * @reason: network queue pause reason - * - * Return: none - */ -void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) +void ol_txrx_vdev_pause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + struct ol_txrx_pdev_t *pdev; enum netif_reason_type netif_reason; + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + + pdev = vdev->pdev; if (qdf_unlikely((!pdev) || (!pdev->pause_cb))) { ol_txrx_err("invalid pdev"); return; @@ -1239,17 +1397,27 @@ void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) /** * ol_txrx_vdev_unpause() - unpause vdev network queues + * @soc_hdl: datapath soc handle * @vdev: vdev handle * @reason: network queue pause reason + * @pause_type: type of pause * * Return: none */ -void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) +void ol_txrx_vdev_unpause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; - struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + struct ol_txrx_pdev_t *pdev; enum netif_reason_type netif_reason; + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + + pdev = vdev->pdev; if (qdf_unlikely((!pdev) || (!pdev->pause_cb))) { ol_txrx_err("invalid pdev"); return; @@ -1272,10 +1440,12 @@ void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) */ void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *pdev, uint32_t reason) { + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); struct ol_txrx_vdev_t *vdev = NULL, *tmp; TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { - ol_txrx_vdev_pause((struct cdp_vdev *)vdev, reason); + ol_txrx_vdev_pause(ol_txrx_soc_t_to_cdp_soc_t(soc), + vdev->vdev_id, reason, 0); } } @@ -1288,9 +1458,11 @@ void ol_txrx_pdev_pause(struct ol_txrx_pdev_t *pdev, uint32_t reason) */ void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason) { + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); struct ol_txrx_vdev_t *vdev = NULL, *tmp; TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { - ol_txrx_vdev_unpause((struct cdp_vdev *)vdev, reason); + ol_txrx_vdev_unpause(ol_txrx_soc_t_to_cdp_soc_t(soc), + vdev->vdev_id, reason, 0); } } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_internal.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_internal.h index 677cbb92249105826a8b9d3c8d5b4628be806527..dcd3e42ac56cc4a9bcf5741c5dbf6529819a3553 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_internal.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_internal.h @@ -94,6 +94,9 @@ #define txrx_nofl_dbg(params...) \ QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TXRX, params) +#define ol_txrx_err_rl(params...) \ + QDF_TRACE_ERROR_RL(QDF_MODULE_ID_TXRX, params) + /* * define PN check failure message print rate * as 1 second @@ -115,6 +118,8 @@ #define txrx_nofl_info(params...) #define txrx_nofl_dbg(params...) +#define ol_txrx_err_rl(params...) + #endif /* TXRX_PRINT_ENABLE */ /*--- tx credit debug printouts ---*/ @@ -209,6 +214,9 @@ ol_rx_mpdu_list_next(struct ol_txrx_pdev_t *pdev, netbuf); \ else if (status == htt_tx_status_no_ack) \ TXRX_STATS_MSDU_INCR(pdev, tx.dropped.no_ack, netbuf); \ + else if (status == htt_tx_status_drop) \ + TXRX_STATS_MSDU_INCR(pdev, tx.dropped.target_drop, \ + netbuf); \ else if (status == htt_tx_status_download_fail) \ TXRX_STATS_MSDU_INCR(pdev, tx.dropped.download_fail, \ netbuf); \ @@ -265,6 +273,12 @@ ol_rx_mpdu_list_next(struct ol_txrx_pdev_t *pdev, TXRX_STATS_ADD(_pdev, pub.tx.dropped.no_ack.bytes, \ _b_cntrs); \ break; \ + case htt_tx_status_drop: \ + TXRX_STATS_ADD(_pdev, \ + pub.tx.dropped.target_drop.pkts, _p_cntrs);\ + TXRX_STATS_ADD(_pdev, \ + pub.tx.dropped.target_drop.bytes, _b_cntrs);\ + break; \ case htt_tx_status_download_fail: \ TXRX_STATS_ADD(_pdev, \ pub.tx.dropped.download_fail.pkts, _p_cntrs); \ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.c index 13084b7023af04a315e34ac1c443f2d714915139..a5febdcf048884988040d8f4bbad428f44d05183 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.c @@ -23,7 +23,7 @@ #include /* qdf_atomic_read */ /* header files for utilities */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ /* header files for configuration API */ #include /* ol_cfg_is_high_latency */ @@ -106,28 +106,26 @@ struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = { }; #endif -/** - * ol_txrx_ipa_uc_get_resource() - Client request resource information - * @pdev: handle to the HTT instance - * - * OL client will request IPA UC related resource information - * Resource information will be distributted to IPA module - * All of the required resources should be pre-allocated - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_ipa_resources *ipa_res; qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!osdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: qdf device is null!", __func__); return QDF_STATUS_E_NOENT; } + ipa_res = &pdev->ipa_resource; htt_ipa_uc_get_resource(pdev->htt_pdev, &ipa_res->ce_sr, &ipa_res->tx_comp_ring, @@ -145,7 +143,7 @@ QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev) &ipa_res->tx_comp_ring->mem_info)) || (0 == qdf_mem_get_dma_addr(osdev, &ipa_res->rx_rdy_ring->mem_info)) -#if defined(QCA_WIFI_3_0) && IS_ENABLED(CONFIG_IPA3) +#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3) || (0 == qdf_mem_get_dma_addr(osdev, &ipa_res->rx2_rdy_ring->mem_info)) #endif @@ -155,21 +153,20 @@ QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_set_doorbell_paddr() - Client set IPA UC doorbell register - * @pdev: handle to the HTT instance - * - * IPA UC let know doorbell register physical address - * WLAN firmware will use this physical address to notify IPA UC - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_ipa_resources *ipa_res; int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; ret = htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev, ipa_res->tx_comp_doorbell_dmaaddr, ipa_res->rx_ready_doorbell_dmaaddr); @@ -183,23 +180,18 @@ QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *ppdev) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_set_active() - Client notify IPA UC data path active or not - * @pdev: handle to the HTT instance - * @uc_active: WDI UC path enable or not - * @is_tx: TX path or RX path - * - * IPA UC let know doorbell register physical address - * WLAN firmware will use this physical address to notify IPA UC - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *ppdev, bool uc_active, - bool is_tx) +QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool uc_active, bool is_tx) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ret = htt_h2t_ipa_uc_set_active(pdev->htt_pdev, uc_active, is_tx); if (ret) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -210,16 +202,16 @@ QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *ppdev, bool uc_active, return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware - * @pdev: handle to the device instance - * @op_msg: op response message from firmware - * - * Return: none - */ -QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg) +QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t *op_msg) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } if (pdev->ipa_uc_op_cb) { pdev->ipa_uc_op_cb(op_msg, pdev->usr_ctxt); @@ -233,17 +225,18 @@ QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *ppdev, uint8_t *op_msg) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function - * @pdev: handle to the device instance - * @op_cb: handler function pointer - * - * Return: none - */ -QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *ppdev, - ipa_uc_op_cb_type op_cb, void *usr_ctxt) +QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + ipa_uc_op_cb_type op_cb, + void *usr_ctxt) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } pdev->ipa_uc_op_cb = op_cb; pdev->usr_ctxt = usr_ctxt; @@ -251,17 +244,17 @@ QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *ppdev, return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_get_stat() - Get firmware wdi status - * @pdev: handle to the HTT instance - * - * Return: none - */ -QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ret = htt_h2t_ipa_uc_get_stats(pdev->htt_pdev); if (ret) { @@ -273,27 +266,15 @@ QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *ppdev) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_enable_autonomy() - Enable autonomy RX path - * @pdev: handle to the device instance - * - * Set all RX packet route to IPA - * Return: none - */ -QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { /* TBD */ return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_disable_autonomy() - Disable autonomy RX path - * @pdev: handle to the device instance - * - * Disable RX packet route to host - * Return: none - */ -QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) { /* TBD */ return QDF_STATUS_SUCCESS; @@ -357,6 +338,7 @@ static inline void ol_txrx_ipa_wdi_tx_smmu_params( QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(tx_smmu) = 0; } +#ifdef QCA_WIFI_3_0 /** * ol_txrx_ipa_wdi_rx_smmu_params() - Config IPA RX params * @ipa_res: IPA resources @@ -389,6 +371,25 @@ static inline void ol_txrx_ipa_wdi_rx_smmu_params( QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = 0; } +#else +static inline void ol_txrx_ipa_wdi_rx_smmu_params( + struct ol_txrx_ipa_resources *ipa_res, + qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu) +{ + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN1_PROD; + qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE( + rx_smmu), + &ipa_res->rx_rdy_ring->sgtable, + sizeof(sgtable_t)); + QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(rx_smmu) = + ipa_res->rx_rdy_ring->mem_info.size; + QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_DOORBELL_PA(rx_smmu) = + ipa_res->rx_proc_done_idx->mem_info.pa; + QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = 0; +} + +#endif #else @@ -442,6 +443,7 @@ static inline void ol_txrx_ipa_wdi_tx_params( QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(tx) = 0; } +#ifdef QCA_WIFI_3_0 /** * ol_txrx_ipa_wdi_rx_params() - Config IPA RX params * @ipa_res: IPA resources @@ -469,33 +471,36 @@ static inline void ol_txrx_ipa_wdi_rx_params( QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = 0; } -/** - * ol_txrx_ipa_setup() - Setup and connect IPA pipes - * @pdev: handle to the device instance - * @ipa_i2w_cb: IPA to WLAN callback - * @ipa_w2i_cb: WLAN to IPA callback - * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback - * @ipa_desc_size: IPA descriptor size - * @ipa_priv: handle to the HTT instance - * @is_rm_enabled: Is IPA RM enabled or not - * @p_tx_pipe_handle: pointer to Tx pipe handle - * @p_rx_pipe_handle: pointer to Rx pipe handle - * @is_smmu_enabled: Is SMMU enabled or not - * @sys_in: parameters to setup sys pipe in mcc mode - * @over_gsi: is ipa ver gsi fw - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +#else + +static inline void ol_txrx_ipa_wdi_rx_params( + struct ol_txrx_ipa_resources *ipa_res, + qdf_ipa_wdi_pipe_setup_info_t *rx) +{ + QDF_IPA_WDI_SETUP_INFO_CLIENT(rx) = IPA_CLIENT_WLAN1_PROD; + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(rx) = + ipa_res->rx_rdy_ring->mem_info.pa; + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(rx) = + ipa_res->rx_rdy_ring->mem_info.size; + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_DOORBELL_PA(rx) = + ipa_res->rx_proc_done_idx->mem_info.pa; + QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = 0; +} + +#endif + +QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *p_tx_pipe_handle, uint32_t *p_rx_pipe_handle, bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_ipa_resources *ipa_res; qdf_ipa_ep_cfg_t *tx_cfg; qdf_ipa_ep_cfg_t *rx_cfg; qdf_ipa_wdi_pipe_setup_info_t *tx; @@ -508,6 +513,11 @@ QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0; int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!osdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: qdf device is null!", __func__); @@ -619,23 +629,34 @@ QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, /** * ol_txrx_ipa_cleanup() - Disconnect IPA pipes + * @soc_hdl: soc handle + * @pdev_id: pdev id * @tx_pipe_handle: Tx pipe handle * @rx_pipe_handle: Rx pipe handle * * Return: QDF_STATUS */ -QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle) +QDF_STATUS ol_txrx_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, + uint32_t rx_pipe_handle) { int ret; struct ol_txrx_ipa_resources *ipa_res; + struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); - ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + ol_txrx_pdev_handle pdev; - if (!pdev || !osdev) { + if (!soc || !osdev) { ol_txrx_err("%s invalid instance", __func__); return QDF_STATUS_E_FAILURE; } + pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID); + if (!pdev) { + ol_txrx_err("%s NULL pdev invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + ipa_res = &pdev->ipa_resource; if (osdev->smmu_s1_enabled) { ret = pld_smmu_unmap(osdev->dev, @@ -686,9 +707,10 @@ QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr, int ret = -EINVAL; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "%s: Add Partial hdr: %s, %pM", - __func__, ifname, mac_addr); + "%s: Add Partial hdr: %s, "QDF_MAC_ADDR_FMT, + __func__, ifname, QDF_MAC_ADDR_REF(mac_addr)); + qdf_mem_zero(&in, sizeof(qdf_ipa_wdi_reg_intf_in_params_t)); qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t)); memcpy(&uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN); qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr); @@ -755,18 +777,18 @@ QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes - * @pdev: handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); QDF_STATUS status; int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + status = htt_rx_update_smmu_map(pdev->htt_pdev, true); if (status != QDF_STATUS_SUCCESS) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -789,23 +811,23 @@ QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) return QDF_STATUS_E_FAILURE; } - ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, true); - ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, false); + ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, true); + ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, false); return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes - * @pdev: handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Disable IPA pipes", __func__); ret = qdf_ipa_wdi_disable_pipes(); @@ -995,41 +1017,34 @@ static inline void ol_txrx_ipa_rx_params( osdev); } -/** - * ol_txrx_ipa_setup() - Setup and connect IPA pipes - * @pdev: handle to the device instance - * @ipa_i2w_cb: IPA to WLAN callback - * @ipa_w2i_cb: WLAN to IPA callback - * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback - * @ipa_desc_size: IPA descriptor size - * @ipa_priv: handle to the HTT instance - * @is_rm_enabled: Is IPA RM enabled or not - * @p_tx_pipe_handle: pointer to Tx pipe handle - * @p_rx_pipe_handle: pointer to Rx pipe handle - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, +QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, uint32_t *p_tx_pipe_handle, uint32_t *p_rx_pipe_handle) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_ipa_resources *ipa_res; qdf_ipa_wdi_in_params_t pipe_in; qdf_ipa_wdi_out_params_t pipe_out; uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0; - int ret; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + if (!osdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: qdf device is null!", __func__); return QDF_STATUS_E_NOENT; } + ipa_res = &pdev->ipa_resource; qdf_mem_zero(&pipe_in, sizeof(pipe_in)); qdf_mem_zero(&pipe_out, sizeof(pipe_out)); @@ -1128,12 +1143,16 @@ QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb, /** * ol_txrx_ipa_cleanup() - Disconnect IPA pipes + * @soc_hdl: soc handle + * @pdev_id: pdev id * @tx_pipe_handle: Tx pipe handle * @rx_pipe_handle: Rx pipe handle * * Return: QDF_STATUS */ -QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle) +QDF_STATUS ol_txrx_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, + uint32_t rx_pipe_handle) { int ret; @@ -1222,7 +1241,8 @@ static int ol_txrx_ipa_add_header_info(char *ifname, uint8_t *mac_addr, struct ol_txrx_ipa_uc_tx_hdr *uc_tx_hdr = NULL; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - "Add Partial hdr: %s, %pM", ifname, mac_addr); + "Add Partial hdr: %s, "QDF_MAC_ADDR_FMT, ifname, + QDF_MAC_ADDR_REF(mac_addr)); /* dynamically allocate the memory to add the hdrs */ ipa_hdr = qdf_mem_malloc(sizeof(qdf_ipa_ioc_add_hdr_t) @@ -1489,19 +1509,20 @@ QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes - * @pdev: handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_ipa_resources *ipa_res; int result; QDF_STATUS status; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; status = htt_rx_update_smmu_map(pdev->htt_pdev, true); if (status != QDF_STATUS_SUCCESS) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, @@ -1527,7 +1548,7 @@ QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) __func__, result); goto smmu_unmap; } - ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, true); + ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, true); /* ACTIVATE RX PIPE */ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, @@ -1547,7 +1568,7 @@ QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) __func__, result); goto smmu_unmap; } - ol_txrx_ipa_uc_set_active((struct cdp_pdev *)pdev, true, false); + ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, false); return QDF_STATUS_SUCCESS; @@ -1561,18 +1582,19 @@ QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *ppdev) return QDF_STATUS_E_FAILURE; } -/** - * ol_txrx_ipa_uc_disable_pipes() – Suspend traffic and disable Tx/Rx pipes - * @pdev: handle to the device instance - * - * Return: QDF_STATUS - */ -QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *ppdev) +QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - ol_txrx_pdev_handle pdev = (ol_txrx_pdev_handle)ppdev; - struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + struct ol_txrx_ipa_resources *ipa_res; int result; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Disable RX PIPE", __func__); result = qdf_ipa_suspend_wdi_pipe(ipa_res->rx_pipe_handle); @@ -1659,12 +1681,18 @@ QDF_STATUS ol_txrx_ipa_set_perf_level(int client, #endif /* CONFIG_IPA_WDI_UNIFIED_API */ #ifdef FEATURE_METERING -QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *ppdev, - uint8_t reset_stats) +QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t reset_stats) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int result; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + result = htt_h2t_ipa_uc_get_share_stats(pdev->htt_pdev, reset_stats); if (result) { @@ -1676,12 +1704,18 @@ QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *ppdev, return QDF_STATUS_SUCCESS; } -QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *ppdev, - uint64_t quota_bytes) +QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint64_t quota_bytes) { - struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); int result; + if (!pdev) { + ol_txrx_err("%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + result = htt_h2t_ipa_uc_set_quota(pdev->htt_pdev, quota_bytes); if (result) { diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.h index 60896efe39a22c171a57b40ee8f2bcc532f44360..53872551af18fba654c775e6132ef05d0b59b719 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -83,7 +83,7 @@ struct ol_txrx_ipa_uc_rx_hdr { #define OL_TXRX_IPA_IPV4_NAME_EXT "_ipv4" #define OL_TXRX_IPA_IPV6_NAME_EXT "_ipv6" -#define OL_TXRX_IPA_MAX_IFACE 3 +#define OL_TXRX_IPA_MAX_IFACE MAX_IPA_IFACE #define OL_TXRX_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header) #define OL_TXRX_IPA_WLAN_IPA_HEADER sizeof(struct ipa_header) @@ -92,7 +92,7 @@ struct ol_txrx_ipa_uc_rx_hdr { #define OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET \ (OL_TXRX_IPA_WLAN_FRAG_HEADER + OL_TXRX_IPA_WLAN_IPA_HEADER) -#if defined(QCA_WIFI_3_0) && IS_ENABLED(CONFIG_IPA3) +#if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3) #define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res, osdev) \ do { \ QDF_IPA_PIPE_IN_UL_RDY_RING_RP_VA(pipe_in) = \ @@ -113,45 +113,204 @@ struct ol_txrx_ipa_uc_rx_hdr { #define OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res, osdev) #endif /* IPA3 */ -QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *pdev); -QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_pdev *pdev); -QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_pdev *pdev, bool uc_active, - bool is_tx); -QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_pdev *pdev, uint8_t *op_msg); -QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_pdev *pdev, - ipa_uc_op_cb_type op_cb, void *usr_ctxt); -QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_pdev *pdev); -QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_pdev *pdev); -QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_pdev *pdev); +/** + * ol_txrx_ipa_uc_get_resource() - Client request resource information + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * OL client will request IPA UC related resource information + * Resource information will be distributted to IPA module + * All of the required resources should be pre-allocated + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + +/** + * ol_txrx_ipa_uc_set_doorbell_paddr() - Client set IPA UC doorbell register + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * IPA UC let know doorbell register physical address + * WLAN firmware will use this physical address to notify IPA UC + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + +/** + * ol_txrx_ipa_uc_set_active() - Client notify IPA UC data path active or not + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * @uc_active: WDI UC path enable or not + * @is_tx: TX path or RX path + * + * IPA UC let know doorbell register physical address + * WLAN firmware will use this physical address to notify IPA UC + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + bool uc_active, bool is_tx); + +/** + * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * @op_msg: op response message from firmware + * + * Return: none + */ +QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t *op_msg); + +/** + * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * @op_cb: handler function pointer + * + * Return: none + */ +QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + ipa_uc_op_cb_type op_cb, + void *usr_ctxt); + +/** + * ol_txrx_ipa_uc_get_stat() - Get firmware wdi status + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * Return: none + */ +QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * ol_txrx_ipa_enable_autonomy() - Enable autonomy RX path + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * Set all RX packet route to IPA + * Return: none + */ +QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + +/** + * ol_txrx_ipa_disable_autonomy() - Disable autonomy RX path + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * Disable RX packet route to host + * Return: none + */ +QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + #ifdef CONFIG_IPA_WDI_UNIFIED_API -QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, - uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, - uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, - bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in, - bool over_gsi); +/** + * ol_txrx_ipa_setup() - Setup and connect IPA pipes + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * @ipa_i2w_cb: IPA to WLAN callback + * @ipa_w2i_cb: WLAN to IPA callback + * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback + * @ipa_desc_size: IPA descriptor size + * @ipa_priv: handle to the HTT instance + * @is_rm_enabled: Is IPA RM enabled or not + * @p_tx_pipe_handle: pointer to Tx pipe handle + * @p_rx_pipe_handle: pointer to Rx pipe handle + * @is_smmu_enabled: Is SMMU enabled or not + * @sys_in: parameters to setup sys pipe in mcc mode + * @over_gsi: is ipa ver gsi fw + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, + uint32_t ipa_desc_size, + void *ipa_priv, bool is_rm_enabled, + uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, + bool is_smmu_enabled, + qdf_ipa_sys_connect_params_t *sys_in, + bool over_gsi); #else /* CONFIG_IPA_WDI_UNIFIED_API */ -QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *pdev, void *ipa_i2w_cb, - void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, - uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, - uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle); +/** + * ol_txrx_ipa_setup() - Setup and connect IPA pipes + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * @ipa_i2w_cb: IPA to WLAN callback + * @ipa_w2i_cb: WLAN to IPA callback + * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback + * @ipa_desc_size: IPA descriptor size + * @ipa_priv: handle to the HTT instance + * @is_rm_enabled: Is IPA RM enabled or not + * @p_tx_pipe_handle: pointer to Tx pipe handle + * @p_rx_pipe_handle: pointer to Rx pipe handle + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + void *ipa_i2w_cb, void *ipa_w2i_cb, + void *ipa_wdi_meter_notifier_cb, + uint32_t ipa_desc_size, void *ipa_priv, + bool is_rm_enabled, uint32_t *tx_pipe_handle, + uint32_t *rx_pipe_handle); #endif /* CONFIG_IPA_WDI_UNIFIED_API */ -QDF_STATUS ol_txrx_ipa_cleanup(uint32_t tx_pipe_handle, - uint32_t rx_pipe_handle); +QDF_STATUS ol_txrx_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint32_t tx_pipe_handle, + uint32_t rx_pipe_handle); QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr, qdf_ipa_client_type_t prod_client, qdf_ipa_client_type_t cons_client, uint8_t session_id, bool is_ipv6_enabled); QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled); -QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_pdev *pdev); -QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_pdev *pdev); + +/** + * ol_txrx_ipa_enable_pipes() - Enable and resume traffic on Tx/Rx pipes + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * ol_txrx_ipa_disable_pipes() – Suspend traffic and disable Tx/Rx pipes + * @soc_hdl: data path soc handle + * @pdev_id: device instance id + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); QDF_STATUS ol_txrx_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps); #ifdef FEATURE_METERING -QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_pdev *pdev, - uint8_t reset_stats); -QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_pdev *pdev, - uint64_t quota_bytes); +/** + * ol_txrx_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW + * @soc_hdl: data path soc handle + * @pdev_id: physical device instance id + * @value: reset stats + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t reset_stats); +/** + * ol_txrx_ipa_uc_set_quota() - set quota limit to FW + * @soc_hdl: data path soc handle + * @pdev_id: physical device instance number + * @value: quota limit bytes + * + * Return: QDF_STATUS + */ +QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + uint64_t quota_bytes); #endif #endif #endif /* _OL_TXRX_IPA_H_*/ diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_legacy_flow_control.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_legacy_flow_control.c index bcf28c28310e9b3af917f1fdab643b3596959178..cad4dee01da4b9fc0af7b005ecea64ff44324562 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_legacy_flow_control.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_legacy_flow_control.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -38,25 +38,16 @@ #include #include -/** - * ol_txrx_vdev_pause- Suspend all tx data for the specified virtual device - * - * @data_vdev - the virtual device being paused - * @reason - the reason for which vdev queue is getting paused - * - * This function applies primarily to HL systems, but also - * applies to LL systems that use per-vdev tx queues for MCC or - * thermal throttling. As an example, this function could be - * used when a single-channel physical device supports multiple - * channels by jumping back and forth between the channels in a - * time-shared manner. As the device is switched from channel A - * to channel B, the virtual devices that operate on channel A - * will be paused. - * - */ -void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) +void ol_txrx_vdev_pause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } /* TO DO: log the queue pause */ /* acquire the mutex lock, since we'll be modifying the queues */ @@ -71,19 +62,17 @@ void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason) TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } -/** - * ol_txrx_vdev_unpause - Resume tx for the specified virtual device - * - * @data_vdev - the virtual device being unpaused - * @reason - the reason for which vdev queue is getting unpaused - * - * This function applies primarily to HL systems, but also applies to - * LL systems that use per-vdev tx queues for MCC or thermal throttling. - * - */ -void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) +void ol_txrx_vdev_unpause(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + uint32_t reason, uint32_t pause_type) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } + /* TO DO: log the queue unpause */ /* acquire the mutex lock, since we'll be modifying the queues */ TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); @@ -105,22 +94,15 @@ void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason) TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } -/** - * ol_txrx_vdev_flush - Drop all tx data for the specified virtual device - * - * @data_vdev - the virtual device being flushed - * - * This function applies primarily to HL systems, but also applies to - * LL systems that use per-vdev tx queues for MCC or thermal throttling. - * This function would typically be used by the ctrl SW after it parks - * a STA vdev and then resumes it, but to a new AP. In this case, though - * the same vdev can be used, any old tx frames queued inside it would be - * stale, and would need to be discarded. - * - */ -void ol_txrx_vdev_flush(struct cdp_vdev *pvdev) +void ol_txrx_vdev_flush(struct cdp_soc_t *soc_hdl, uint8_t vdev_id) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } qdf_spin_lock_bh(&vdev->ll_pause.mutex); qdf_timer_stop(&vdev->ll_pause.timer); @@ -129,11 +111,11 @@ void ol_txrx_vdev_flush(struct cdp_vdev *pvdev) qdf_nbuf_t next = qdf_nbuf_next(vdev->ll_pause.txq.head); qdf_nbuf_set_next(vdev->ll_pause.txq.head, NULL); - if (QDF_NBUF_CB_PADDR(vdev->ll_pause.txq.head) && - !qdf_nbuf_ipa_owned_get(vdev->ll_pause.txq.head)) { - qdf_nbuf_unmap(vdev->pdev->osdev, - vdev->ll_pause.txq.head, - QDF_DMA_TO_DEVICE); + if (QDF_NBUF_CB_PADDR(vdev->ll_pause.txq.head)) { + if (!qdf_nbuf_ipa_owned_get(vdev->ll_pause.txq.head)) + qdf_nbuf_unmap(vdev->pdev->osdev, + vdev->ll_pause.txq.head, + QDF_DMA_TO_DEVICE); } qdf_nbuf_tx_free(vdev->ll_pause.txq.head, QDF_NBUF_PKT_ERROR); @@ -151,6 +133,9 @@ static void ol_tx_vdev_ll_pause_queue_send_base(struct ol_txrx_vdev_t *vdev) { int max_to_accept; + if (!vdev) + return; + qdf_spin_lock_bh(&vdev->ll_pause.mutex); if (vdev->ll_pause.paused_reason) { qdf_spin_unlock_bh(&vdev->ll_pause.mutex); @@ -429,52 +414,8 @@ void ol_tx_vdev_ll_pause_queue_send(void *context) ol_tx_vdev_ll_pause_queue_send_base(vdev); } -/** - * ol_txrx_get_vdev_from_sta_id() - get vdev from sta_id - * @sta_id: sta_id - * - * Return: vdev handle - * NULL if not found. - */ -static ol_txrx_vdev_handle ol_txrx_get_vdev_from_sta_id(uint8_t sta_id) -{ - struct ol_txrx_peer_t *peer = NULL; - ol_txrx_pdev_handle pdev = NULL; - - if (sta_id >= WLAN_MAX_STA_COUNT) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "Invalid sta id passed"); - return NULL; - } - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "PDEV not found for sta_id [%d]", sta_id); - return NULL; - } - - peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev, sta_id); - - if (!peer) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "PEER [%d] not found", sta_id); - return NULL; - } - - return peer->vdev; -} - -/** - * ol_txrx_register_tx_flow_control() - register tx flow control callback - * @vdev_id: vdev_id - * @flowControl: flow control callback - * @osif_fc_ctx: callback context - * @flow_control_is_pause: is vdev paused by flow control - * - * Return: 0 for success or error code - */ -int ol_txrx_register_tx_flow_control(uint8_t vdev_id, +int ol_txrx_register_tx_flow_control(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, ol_txrx_tx_flow_control_fp flowControl, void *osif_fc_ctx, ol_txrx_tx_flow_control_is_pause_fp @@ -497,14 +438,8 @@ int ol_txrx_register_tx_flow_control(uint8_t vdev_id, return 0; } -/** - * ol_txrx_de_register_tx_flow_control_cb() - deregister tx flow control - * callback - * @vdev_id: vdev_id - * - * Return: 0 for success or error code - */ -int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id) +int ol_txrx_deregister_tx_flow_control_cb(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id) { struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); @@ -525,22 +460,36 @@ int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id) /** * ol_txrx_get_tx_resource() - if tx resource less than low_watermark - * @sta_id: sta id + * soc_hdl: soc handle + * @pdev_id: datapath pdev identifier + * @peer_addr: peer mac address * @low_watermark: low watermark * @high_watermark_offset: high watermark offset value * * Return: true/false */ bool -ol_txrx_get_tx_resource(uint8_t sta_id, +ol_txrx_get_tx_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, + struct qdf_mac_addr peer_addr, unsigned int low_watermark, unsigned int high_watermark_offset) { - ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_sta_id(sta_id); + struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl); + ol_txrx_pdev_handle pdev = + ol_txrx_get_pdev_from_pdev_id(soc, pdev_id); + ol_txrx_vdev_handle vdev; + + if (qdf_unlikely(!pdev)) { + ol_txrx_err("pdev is NULL"); + return true; + } + vdev = ol_txrx_get_vdev_by_peer_addr(ol_txrx_pdev_t_to_cdp_pdev(pdev), + peer_addr); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Invalid sta_id %d", __func__, sta_id); + "%s: Invalid peer address: " QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(peer_addr.bytes)); /* Return true so caller do not understand that resource * is less than low_watermark. * sta_id validation will be done in ol_tx_send_data_frame @@ -565,14 +514,8 @@ ol_txrx_get_tx_resource(uint8_t sta_id, return true; } -/** - * ol_txrx_ll_set_tx_pause_q_depth() - set pause queue depth - * @vdev_id: vdev id - * @pause_q_depth: pause queue depth - * - * Return: 0 for success or error code - */ -int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth) +int ol_txrx_ll_set_tx_pause_q_depth(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + int pause_q_depth) { struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); @@ -590,9 +533,16 @@ int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth) return 0; } -void ol_txrx_flow_control_cb(struct cdp_vdev *pvdev, bool tx_resume) +void ol_txrx_flow_control_cb(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, + bool tx_resume) { - struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev; + struct ol_txrx_vdev_t *vdev = + (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); + + if (qdf_unlikely(!vdev)) { + ol_txrx_err("vdev is NULL"); + return; + } qdf_spin_lock_bh(&vdev->flow_control_lock); if ((vdev->osif_flow_control_cb) && (vdev->osif_fc_ctx)) @@ -626,6 +576,7 @@ static bool ol_txrx_flow_control_is_pause(ol_txrx_vdev_handle vdev) void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev) { struct ol_txrx_vdev_t *vdev; + struct cdp_soc_t *soc_hdl = ol_txrx_soc_t_to_cdp_soc_t(pdev->soc); TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { if ((qdf_atomic_read(&vdev->os_q_paused) && @@ -635,8 +586,8 @@ void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev) if (pdev->tx_desc.num_free > vdev->tx_fl_hwm) { qdf_atomic_set(&vdev->os_q_paused, 0); qdf_spin_unlock(&pdev->tx_mutex); - ol_txrx_flow_control_cb((struct cdp_vdev *)vdev, - true); + ol_txrx_flow_control_cb(soc_hdl, + vdev->vdev_id, true); } else { qdf_spin_unlock(&pdev->tx_mutex); } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_peer_find.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_peer_find.c index 0bb5d1a963d460cb4e859ce2bcd3556af4d50376..1f10c5b32b0d8cca6530c34a8538b1ccf0c46828 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_peer_find.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_peer_find.c @@ -22,7 +22,7 @@ #include /* qdf_mem_malloc, etc. */ #include /* qdf_device_t, qdf_print */ /* header files for utilities */ -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ /* header files for configuration API */ #include /* ol_cfg_max_peer_id */ @@ -832,9 +832,9 @@ void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent) hash_list_elem) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW, - "%*shash idx %d -> %pK ("QDF_MAC_ADDR_STR")\n", + "%*shash idx %d -> %pK ("QDF_MAC_ADDR_FMT")\n", indent + 4, " ", i, peer, - QDF_MAC_ADDR_ARRAY(peer->mac_addr.raw)); + QDF_MAC_ADDR_REF(peer->mac_addr.raw)); } } } diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h index ca36d531a5d484fe528980f43a206eff0fce898d..f9fedd30279d34f6f7f5c504eabec41153747431 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,7 +25,7 @@ #include /* qdf_nbuf_t */ #include -#include /* TAILQ */ +#include "queue.h" /* TAILQ */ #include /* A_UINT8 */ #include /* htt_sec_type, htt_pkt_type, etc. */ #include /* qdf_atomic_t */ @@ -42,6 +42,7 @@ #include "cdp_txrx_flow_ctrl_v2.h" #include "cdp_txrx_peer_ops.h" #include +#include "qdf_hrtimer.h" /* * The target may allocate multiple IDs for a peer. @@ -80,6 +81,8 @@ #define ETHERTYPE_OCB_TX 0x8151 #define ETHERTYPE_OCB_RX 0x8152 +#define OL_TXRX_MAX_PDEV_CNT 1 + struct ol_txrx_pdev_t; struct ol_txrx_vdev_t; struct ol_txrx_peer_t; @@ -456,6 +459,7 @@ struct ol_tx_group_credit_stats_t { }; +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /** * enum flow_pool_status - flow pool status * @FLOW_POOL_ACTIVE_UNPAUSED : pool is active (can take/put descriptors) @@ -527,7 +531,7 @@ struct ol_tx_flow_pool_t { uint16_t stop_priority_th; uint16_t start_priority_th; }; - +#endif #define OL_TXRX_INVALID_PEER_UNMAP_COUNT 0xF /* @@ -567,6 +571,23 @@ struct ol_txrx_fw_stats_desc_elem_t { struct ol_txrx_fw_stats_desc_t desc; }; +/** + * struct ol_txrx_soc_t - soc reference structure + * @cdp_soc: common base structure + * @cdp_ctrl_objmgr_psoc: opaque handle for UMAC psoc object + * @pdev_list: list of all the pdev on a soc + * + * This is the reference to the soc and all the data + * which is soc specific. + */ +struct ol_txrx_soc_t { + /* Common base structure - Should be the first member */ + struct cdp_soc_t cdp_soc; + + struct cdp_ctrl_objmgr_psoc *psoc; + struct ol_txrx_pdev_t *pdev_list[OL_TXRX_MAX_PDEV_CNT]; +}; + /* * As depicted in the diagram below, the pdev contains an array of * NUM_EXT_TID ol_tx_active_queues_in_tid_t elements. @@ -621,6 +642,9 @@ struct ol_txrx_fw_stats_desc_elem_t { * `------' */ struct ol_txrx_pdev_t { + /* soc - reference to soc structure */ + struct ol_txrx_soc_t *soc; + /* ctrl_pdev - handle for querying config info */ struct cdp_cfg *ctrl_pdev; @@ -629,6 +653,13 @@ struct ol_txrx_pdev_t { htt_pdev_handle htt_pdev; +#ifdef WLAN_FEATURE_PKT_CAPTURE + void *mon_osif_dev; + QDF_STATUS (*mon_cb)(void *osif_dev, + qdf_nbuf_t msdu_list); + uint8_t pktcapture_mode_value; +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #ifdef WLAN_FEATURE_FASTPATH struct CE_handle *ce_tx_hdl; /* Handle to Tx packet posting CE */ struct CE_handle *ce_htt_msg_hdl; /* Handle to TxRx completion CE */ @@ -683,6 +714,11 @@ struct ol_txrx_pdev_t { qdf_atomic_t target_tx_credit; qdf_atomic_t orig_target_tx_credit; + /* + * needed for SDIO HL, Genoa Adma + */ + qdf_atomic_t pad_reserve_tx_credit; + struct { uint16_t pool_size; struct ol_txrx_fw_stats_desc_elem_t *pool; @@ -774,13 +810,18 @@ struct ol_txrx_pdev_t { #ifdef DESC_DUP_DETECT_DEBUG unsigned long *free_list_bitmap; #endif +#ifdef QCA_LL_PDEV_TX_FLOW_CONTROL uint16_t stop_th; uint16_t start_th; uint16_t stop_priority_th; uint16_t start_priority_th; enum flow_pool_status status; +#endif } tx_desc; + /* The pdev_id for this pdev */ + uint8_t id; + uint8_t is_mgmt_over_wmi_enabled; #if defined(QCA_LL_TX_FLOW_CONTROL_V2) struct ol_txrx_pool_stats pool_stats; @@ -899,7 +940,6 @@ struct ol_txrx_pdev_t { struct { enum ol_tx_scheduler_status tx_sched_status; struct ol_tx_sched_t *scheduler; - struct ol_tx_frms_queue_t *last_used_txq; } tx_sched; /* * tx_queue only applies for HL, but is defined unconditionally to avoid @@ -1069,9 +1109,82 @@ struct ol_txrx_pdev_t { uint8_t peer_id_unmap_ref_cnt; bool enable_peer_unmap_conf_support; bool enable_tx_compl_tsf64; + uint64_t last_host_time; + uint64_t last_tsf64_time; /* Current noise-floor reading for the pdev channel */ int16_t chan_noise_floor; + uint32_t total_bundle_queue_length; +}; + +#define OL_TX_HL_DEL_ACK_HASH_SIZE 256 + +/** + * enum ol_tx_hl_packet_type - type for tcp packet + * @TCP_PKT_ACK: TCP ACK frame + * @TCP_PKT_NO_ACK: TCP frame, but not the ack + * @NO_TCP_PKT: Not the TCP frame + */ +enum ol_tx_hl_packet_type { + TCP_PKT_ACK, + TCP_PKT_NO_ACK, + NO_TCP_PKT +}; + +/** + * struct packet_info - tcp packet information + */ +struct packet_info { + /** @type: flag the packet type */ + enum ol_tx_hl_packet_type type; + /** @stream_id: stream identifier */ + uint16_t stream_id; + /** @ack_number: tcp ack number */ + uint32_t ack_number; + /** @dst_ip: destination ip address */ + uint32_t dst_ip; + /** @src_ip: source ip address */ + uint32_t src_ip; + /** @dst_port: destination port */ + uint16_t dst_port; + /** @src_port: source port */ + uint16_t src_port; +}; + +/** + * struct tcp_stream_node - tcp stream node + */ +struct tcp_stream_node { + /** @next: next tcp stream node */ + struct tcp_stream_node *next; + /** @no_of_ack_replaced: count for ack replaced frames */ + uint8_t no_of_ack_replaced; + /** @stream_id: stream identifier */ + uint16_t stream_id; + /** @dst_ip: destination ip address */ + uint32_t dst_ip; + /** @src_ip: source ip address */ + uint32_t src_ip; + /** @dst_port: destination port */ + uint16_t dst_port; + /** @src_port: source port */ + uint16_t src_port; + /** @ack_number: tcp ack number */ + uint32_t ack_number; + /** @head: point to the tcp ack frame */ + qdf_nbuf_t head; +}; + +/** + * struct tcp_del_ack_hash_node - hash node for tcp delayed ack + */ +struct tcp_del_ack_hash_node { + /** @hash_node_lock: spin lock */ + qdf_spinlock_t hash_node_lock; + /** @no_of_entries: number of entries */ + uint8_t no_of_entries; + /** @head: the head of the steam node list */ + struct tcp_stream_node *head; }; struct ol_txrx_vdev_t { @@ -1169,6 +1282,33 @@ struct ol_txrx_vdev_t { ol_txrx_tx_flow_control_is_pause_fp osif_flow_control_is_pause; void *osif_fc_ctx; +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + /** @driver_del_ack_enabled: true if tcp delayed ack enabled*/ + bool driver_del_ack_enabled; + /** @no_of_tcpack_replaced: number of tcp ack replaced */ + uint32_t no_of_tcpack_replaced; + /** @no_of_tcpack: number of tcp ack frames */ + uint32_t no_of_tcpack; + + /** @tcp_ack_hash: hash table for tcp delay ack running information */ + struct { + /** @node: tcp ack frame will be stored in this hash table */ + struct tcp_del_ack_hash_node node[OL_TX_HL_DEL_ACK_HASH_SIZE]; + /** @timer: timeout if no more tcp ack feeding */ + __qdf_hrtimer_data_t timer; + /** @is_timer_running: is timer running? */ + qdf_atomic_t is_timer_running; + /** @tcp_node_in_use_count: number of nodes in use */ + qdf_atomic_t tcp_node_in_use_count; + /** @tcp_del_ack_tq: bh to handle the tcp delayed ack */ + qdf_bh_t tcp_del_ack_tq; + /** @tcp_free_list: free list */ + struct tcp_stream_node *tcp_free_list; + /** @tcp_free_list_lock: spin lock */ + qdf_spinlock_t tcp_free_list_lock; + } tcp_ack_hash; +#endif + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) union ol_txrx_align_mac_addr_t hl_tdls_ap_mac_addr; bool hlTdlsFlag; @@ -1214,6 +1354,20 @@ struct ol_txrx_vdev_t { uint64_t fwd_rx_packets; bool is_wisa_mode_enable; uint8_t mac_id; + + uint64_t no_of_bundle_sent_after_threshold; + uint64_t no_of_bundle_sent_in_timer; + uint64_t no_of_pkt_not_added_in_queue; + bool bundling_required; + struct { + struct { + qdf_nbuf_t head; + qdf_nbuf_t tail; + int depth; + } txq; + qdf_spinlock_t mutex; + qdf_timer_t timer; + } bundle_queue; }; struct ol_rx_reorder_array_elem_t { @@ -1392,6 +1546,8 @@ struct ol_txrx_peer_t { qdf_time_t last_deauth_rcvd; qdf_atomic_t fw_create_pending; qdf_timer_t peer_unmap_timer; + bool is_tdls_peer; /* Mark peer as tdls peer */ + bool tdls_offchan_enabled; /* TDLS OffChan operation in use */ }; struct ol_rx_remote_data { diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/wdi_event_api.h b/drivers/staging/qcacld-3.0/core/dp/txrx/wdi_event_api.h index 3997d076dd0b00dcd266080311adc45882e72a85..11358b25e0520a016923e9841e8f4f7d32104f9b 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/wdi_event_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/wdi_event_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -21,6 +21,7 @@ #include "wdi_event.h" #include +#include struct ol_txrx_pdev_t; #ifdef WDI_EVENT_ENABLE @@ -34,14 +35,14 @@ struct ol_txrx_pdev_t; * The order in which callback functions from multiple subscribers are * invoked is unspecified. * - * @param pdev - the event physical device, that maintains the event lists + * @param soc_hdl - datapath soc handle + * @param pdev_id - physical device instance id * @param event_cb_sub - the callback and context for the event subscriber * @param event - which event's notifications are being subscribed to * @return error code, or 0 for success */ -int wdi_event_sub(struct cdp_pdev *ppdev, - void *event_cb_sub, - uint32_t event); +int wdi_event_sub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, uint32_t event); /** * @brief Unsubscribe from a specified WDI event. @@ -51,25 +52,25 @@ int wdi_event_sub(struct cdp_pdev *ppdev, * This function shall only be called if there was a successful prior call * to event_sub() on the same wdi_event_subscribe object. * - * @param pdev - the event physical device with the list of event subscribers + * @param soc_hdl - datapath soc handle + * @param pdev_id - physical device instance id * @param event_cb_sub - the event subscription object * @param event - which event is being unsubscribed * @return error code, or 0 for success */ -int wdi_event_unsub(struct cdp_pdev *ppdev, - void *event_cb_sub, - uint32_t event); +int wdi_event_unsub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, uint32_t event); void wdi_event_handler(enum WDI_EVENT event, - struct cdp_pdev *txrx_pdev, void *data); + uint8_t pdev_id, void *data); A_STATUS wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev); A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev); #else static inline void wdi_event_handler(enum WDI_EVENT event, - struct cdp_pdev *txrx_pdev, void *data) + uint8_t pdev_id, void *data) { } @@ -83,14 +84,15 @@ static inline A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev) return A_OK; } -static inline int wdi_event_sub(struct cdp_pdev *ppdev, void *event_cb_sub, +static inline int wdi_event_sub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, uint32_t event) { return 0; } -static inline int wdi_event_unsub(struct cdp_pdev *ppdev, - void *event_cb_sub, +static inline int wdi_event_unsub(struct cdp_soc_t *soc, uint8_t pdev_id, + wdi_event_subscribe *event_cb_sub, uint32_t event) { return 0; diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c new file mode 100644 index 0000000000000000000000000000000000000000..a939f0ab37323c989ef8c5917332d67f6fab5aac --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.c @@ -0,0 +1,1385 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include "hal_rx_flow.h" +#include "dp_htt.h" +#include "dp_internal.h" +#include +#include + +static void dp_rx_fisa_flush_flow_wrap(struct dp_fisa_rx_sw_ft *sw_ft); + +/** REO will push frame into REO2FW RING */ +#define REO_DESTINATION_FW 6 + +#if defined(FISA_DEBUG_ENABLE) +/** + * hex_dump_skb_data() - Helper function to dump skb while debugging + * @nbuf: Nbuf to be dumped + * @dump: dump enable/disable dumping + * + * Return: NONE + */ +static void hex_dump_skb_data(qdf_nbuf_t nbuf, bool dump) +{ + qdf_nbuf_t next_nbuf; + int i = 0; + + if (!dump) + return; + + if (!nbuf) + return; + + dp_fisa_debug("%ps: skb: %pK skb->next:%pK frag_list %pK skb->data:%pK len %d data_len %d", + (void *)_RET_IP_, nbuf, qdf_nbuf_next(nbuf), + skb_shinfo(nbuf)->frag_list, qdf_nbuf_data(nbuf), + nbuf->len, nbuf->data_len); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, nbuf->data, + 64); + + next_nbuf = skb_shinfo(nbuf)->frag_list; + while (next_nbuf) { + dp_fisa_debug("%d nbuf:%pK nbuf->next:%pK nbuf->data:%pK len %d", + i, next_nbuf, qdf_nbuf_next(next_nbuf), + qdf_nbuf_data(next_nbuf), + qdf_nbuf_len(next_nbuf)); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + qdf_nbuf_data(next_nbuf), 64); + next_nbuf = qdf_nbuf_next(next_nbuf); + i++; + } +} + +/** + * dump_tlvs() - Helper function to dump TLVs of msdu + * @hal_soc_hdl: Handle to TLV functions + * @buf: Pointer to TLV header + * @dbg_level: level control output of TLV dump + * + * Return: NONE + */ +static void dump_tlvs(hal_soc_handle_t hal_soc_hdl, uint8_t *buf, + uint8_t dbg_level) +{ + uint32_t fisa_aggr_count, fisa_timeout, cumulat_l4_csum, cumulat_ip_len; + int flow_aggr_cont; + + hal_rx_dump_pkt_tlvs(hal_soc_hdl, buf, dbg_level); + + flow_aggr_cont = hal_rx_get_fisa_flow_agg_continuation(hal_soc_hdl, + buf); + fisa_aggr_count = hal_rx_get_fisa_flow_agg_count(hal_soc_hdl, buf); + fisa_timeout = hal_rx_get_fisa_timeout(hal_soc_hdl, buf); + cumulat_l4_csum = hal_rx_get_fisa_cumulative_l4_checksum(hal_soc_hdl, + buf); + cumulat_ip_len = hal_rx_get_fisa_cumulative_ip_length(hal_soc_hdl, buf); + + dp_fisa_debug("flow_aggr_cont %d, fisa_timeout %d, fisa_aggr_count %d, cumulat_l4_csum %d, cumulat_ip_len %d", + flow_aggr_cont, fisa_timeout, fisa_aggr_count, cumulat_l4_csum, + cumulat_ip_len); +} +#else +static void hex_dump_skb_data(qdf_nbuf_t nbuf, bool dump) +{ +} + +static void dump_tlvs(hal_soc_handle_t hal_soc_hdl, uint8_t *buf, + uint8_t dbg_level) +{ +} +#endif + +/** + * nbuf_skip_rx_pkt_tlv() - Function to skip the TLVs and mac header from msdu + * @hal_soc_hdl: Handle to hal_soc to get the TLV info + * @nbuf: msdu for which TLVs has to be skipped + * + * Return: None + */ +static void nbuf_skip_rx_pkt_tlv(hal_soc_handle_t hal_soc_hdl, qdf_nbuf_t nbuf) +{ + uint8_t *rx_tlv_hdr; + uint32_t l2_hdr_offset; + + rx_tlv_hdr = qdf_nbuf_data(nbuf); + l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(hal_soc_hdl, + rx_tlv_hdr); + qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + l2_hdr_offset); +} + +/** + * print_flow_tuple() - Debug function to dump flow tuple + * @flow_tuple: flow tuple containing tuple info + * + * Return: NONE + */ +static void print_flow_tuple(struct cdp_rx_flow_tuple_info *flow_tuple) +{ + dp_info("dest_ip_127_96 0x%x", flow_tuple->dest_ip_127_96); + dp_info("dest_ip_95_64 0x%x", flow_tuple->dest_ip_95_64); + dp_info("dest_ip_63_32 0x%x", flow_tuple->dest_ip_63_32); + dp_info("dest_ip_31_0 0x%x", flow_tuple->dest_ip_31_0); + dp_info("src_ip_127_96 0x%x", flow_tuple->src_ip_127_96); + dp_info("src_ip_95_64 0x%x", flow_tuple->src_ip_95_64); + dp_info("src_ip_63_32 0x%x", flow_tuple->src_ip_63_32); + dp_info("src_ip_31_0 0x%x", flow_tuple->src_ip_31_0); + dp_info("dest_port 0x%x", flow_tuple->dest_port); + dp_info("src_port 0x%x", flow_tuple->src_port); + dp_info("l4_protocol 0x%x", flow_tuple->l4_protocol); +} + +/** + * get_flow_tuple_from_nbuf() - Get the flow tuple from msdu + * @hal_soc_hdl: Handle to hal soc + * @flow_tuple_info: return argument where the flow is populated + * @nbuf: msdu from which flow tuple is extracted. + * @rx_tlv_hdr: Pointer to msdu TLVs + * + * Return: None + */ +static void +get_flow_tuple_from_nbuf(hal_soc_handle_t hal_soc_hdl, + struct cdp_rx_flow_tuple_info *flow_tuple_info, + qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr) +{ + struct iphdr *iph; + struct tcphdr *tcph; + uint32_t ip_hdr_offset = HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr); + uint32_t tcp_hdr_offset = HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr); + uint32_t l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(hal_soc_hdl, + rx_tlv_hdr); + + flow_tuple_info->tuple_populated = true; + + qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + l2_hdr_offset); + + iph = (struct iphdr *)(qdf_nbuf_data(nbuf) + ip_hdr_offset); + tcph = (struct tcphdr *)(qdf_nbuf_data(nbuf) + ip_hdr_offset + + tcp_hdr_offset); + + flow_tuple_info->dest_ip_31_0 = qdf_ntohl(iph->daddr); + flow_tuple_info->dest_ip_63_32 = 0; + flow_tuple_info->dest_ip_95_64 = 0; + flow_tuple_info->dest_ip_127_96 = + HAL_IP_DA_SA_PREFIX_IPV4_COMPATIBLE_IPV6; + + flow_tuple_info->src_ip_31_0 = qdf_ntohl(iph->saddr); + flow_tuple_info->src_ip_63_32 = 0; + flow_tuple_info->src_ip_95_64 = 0; + flow_tuple_info->src_ip_127_96 = + HAL_IP_DA_SA_PREFIX_IPV4_COMPATIBLE_IPV6; + + flow_tuple_info->dest_port = qdf_ntohs(tcph->dest); + flow_tuple_info->src_port = qdf_ntohs(tcph->source); + flow_tuple_info->l4_protocol = iph->protocol; + dp_fisa_debug("l4_protocol %d", flow_tuple_info->l4_protocol); + + qdf_nbuf_push_head(nbuf, RX_PKT_TLVS_LEN + l2_hdr_offset); + + dp_fisa_debug("head_skb: %pK head_skb->next:%pK head_skb->data:%pK len %d data_len %d", + nbuf, qdf_nbuf_next(nbuf), qdf_nbuf_data(nbuf), nbuf->len, + nbuf->data_len); +} + +/** + * dp_rx_fisa_setup_hw_fse() - Populate flow so as to update DDR flow table + * @fisa_hdl: Handle fisa context + * @hashed_flow_idx: Index to flow table + * @rx_flow_info: tuple to be populated in flow table + * @flow_steer_info: REO index to which flow to be steered + * + * Return: Pointer to DDR flow table entry + */ +static void * +dp_rx_fisa_setup_hw_fse(struct dp_rx_fst *fisa_hdl, + uint32_t hashed_flow_idx, + struct cdp_rx_flow_tuple_info *rx_flow_info, + uint32_t flow_steer_info) +{ + struct hal_rx_flow flow; + void *hw_fse; + + flow.reo_destination_indication = flow_steer_info; + flow.fse_metadata = 0xDEADBEEF; + flow.tuple_info.dest_ip_127_96 = rx_flow_info->dest_ip_127_96; + flow.tuple_info.dest_ip_95_64 = rx_flow_info->dest_ip_95_64; + flow.tuple_info.dest_ip_63_32 = rx_flow_info->dest_ip_63_32; + flow.tuple_info.dest_ip_31_0 = rx_flow_info->dest_ip_31_0; + flow.tuple_info.src_ip_127_96 = rx_flow_info->src_ip_127_96; + flow.tuple_info.src_ip_95_64 = rx_flow_info->src_ip_95_64; + flow.tuple_info.src_ip_63_32 = rx_flow_info->src_ip_63_32; + flow.tuple_info.src_ip_31_0 = rx_flow_info->src_ip_31_0; + flow.tuple_info.dest_port = rx_flow_info->dest_port; + flow.tuple_info.src_port = rx_flow_info->src_port; + flow.tuple_info.l4_protocol = rx_flow_info->l4_protocol; + flow.reo_destination_handler = HAL_RX_FSE_REO_DEST_FT; + hw_fse = hal_rx_flow_setup_fse(fisa_hdl->hal_rx_fst, hashed_flow_idx, + &flow); + + return hw_fse; +} + +/** + * dp_rx_fisa_update_sw_ft_entry() - Helper function to update few SW FT entry + * @sw_ft_entry: Pointer to softerware flow tabel entry + * @flow_hash: flow_hash for the flow + * @vdev: Saving dp_vdev in FT later used in the flushing the flow + * @flow_id: Flow ID of the flow + * + * Return: NONE + */ +static void dp_rx_fisa_update_sw_ft_entry(struct dp_fisa_rx_sw_ft *sw_ft_entry, + uint32_t flow_hash, + struct dp_vdev *vdev, + struct dp_soc *soc_hdl, + uint32_t flow_id) +{ + sw_ft_entry->flow_hash = flow_hash; + sw_ft_entry->flow_id = flow_id; + sw_ft_entry->vdev = vdev; + sw_ft_entry->soc_hdl = soc_hdl; +} + +/** + * is_same_flow() - Function to compare flow tuple to decide if they match + * @tuple1: flow tuple 1 + * @tuple2: flow tuple 2 + * + * Return: true if they match, false if they differ + */ +static bool is_same_flow(struct cdp_rx_flow_tuple_info *tuple1, + struct cdp_rx_flow_tuple_info *tuple2) +{ + if ((tuple1->src_port ^ tuple2->src_port) | + (tuple1->dest_port ^ tuple2->dest_port) | + (tuple1->src_ip_31_0 ^ tuple2->src_ip_31_0) | + (tuple1->src_ip_63_32 ^ tuple2->src_ip_63_32) | + (tuple1->src_ip_95_64 ^ tuple2->src_ip_95_64) | + (tuple1->src_ip_127_96 ^ tuple2->src_ip_127_96) | + (tuple1->dest_ip_31_0 ^ tuple2->dest_ip_31_0) | + /* DST IP check not required? */ + (tuple1->dest_ip_63_32 ^ tuple2->dest_ip_63_32) | + (tuple1->dest_ip_95_64 ^ tuple2->dest_ip_95_64) | + (tuple1->dest_ip_127_96 ^ tuple2->dest_ip_127_96) | + (tuple1->l4_protocol ^ tuple2->l4_protocol)) + return false; + else + return true; +} + +/** + * dp_rx_fisa_add_ft_entry() - Add new flow to HW and SW FT if it is not added + * @fisa_hdl: handle to FISA context + * @flow_idx_hash: Hashed flow index + * @nbuf: nbuf belonging to new flow + * @vdev: Handle DP vdev to save in SW flow table + * @rx_tlv_hdr: Pointer to TLV header + * + * Return: pointer to sw FT entry on success, NULL otherwise + */ +static struct dp_fisa_rx_sw_ft * +dp_rx_fisa_add_ft_entry(struct dp_rx_fst *fisa_hdl, + uint32_t flow_idx_hash, + qdf_nbuf_t nbuf, struct dp_vdev *vdev, + uint8_t *rx_tlv_hdr, + uint32_t reo_dest_indication) +{ + struct dp_fisa_rx_sw_ft *sw_ft_entry; + uint32_t flow_hash; + uint32_t hashed_flow_idx; + uint32_t skid_count = 0, max_skid_length; + struct cdp_rx_flow_tuple_info rx_flow_tuple_info; + bool is_fst_updated = false; + bool is_flow_tcp, is_flow_udp, is_flow_ipv6; + hal_soc_handle_t hal_soc_hdl = fisa_hdl->soc_hdl->hal_soc; + uint32_t reo_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); + + is_flow_tcp = HAL_RX_TLV_GET_TCP_PROTO(rx_tlv_hdr); + is_flow_udp = HAL_RX_TLV_GET_UDP_PROTO(rx_tlv_hdr); + is_flow_ipv6 = HAL_RX_TLV_GET_IPV6(rx_tlv_hdr); + + if (is_flow_ipv6 || !(is_flow_tcp || is_flow_udp)) { + dp_fisa_debug("Not UDP or TCP IPV4 flow"); + return NULL; + } + + /* Get the hash from TLV + * FSE FT Toeplitz hash is same Common parser hash available in TLV + * common parser toeplitz hash is same as FSE toeplitz hash as + * toeplitz key is same. + */ + rx_flow_tuple_info.tuple_populated = false; + flow_hash = flow_idx_hash; + hashed_flow_idx = flow_hash & fisa_hdl->hash_mask; + max_skid_length = fisa_hdl->max_skid_length; + + dp_fisa_debug("flow_hash 0x%x hashed_flow_idx 0x%x", flow_hash, + hashed_flow_idx); + dp_fisa_debug("max_skid_length 0x%x", max_skid_length); + qdf_spin_lock_bh(&fisa_hdl->dp_rx_fst_lock); + do { + sw_ft_entry = &(((struct dp_fisa_rx_sw_ft *) + fisa_hdl->base)[hashed_flow_idx]); + if (!sw_ft_entry->is_populated) { + /* Add SW FT entry */ + dp_rx_fisa_update_sw_ft_entry(sw_ft_entry, + flow_hash, vdev, + fisa_hdl->soc_hdl, + hashed_flow_idx); + if (!rx_flow_tuple_info.tuple_populated) + get_flow_tuple_from_nbuf(hal_soc_hdl, + &rx_flow_tuple_info, + nbuf, rx_tlv_hdr); + + /* Add HW FT entry */ + sw_ft_entry->hw_fse = + dp_rx_fisa_setup_hw_fse(fisa_hdl, + hashed_flow_idx, + &rx_flow_tuple_info, + reo_dest_indication); + sw_ft_entry->is_populated = true; + sw_ft_entry->napi_id = reo_id; + sw_ft_entry->reo_dest_indication = reo_dest_indication; + qdf_mem_copy(&sw_ft_entry->rx_flow_tuple_info, + &rx_flow_tuple_info, + sizeof(struct cdp_rx_flow_tuple_info)); + + sw_ft_entry->is_flow_tcp = is_flow_tcp; + sw_ft_entry->is_flow_udp = is_flow_udp; + + is_fst_updated = true; + fisa_hdl->add_flow_count++; + break; + } + /* else */ + if (!rx_flow_tuple_info.tuple_populated) + get_flow_tuple_from_nbuf(hal_soc_hdl, + &rx_flow_tuple_info, + nbuf, rx_tlv_hdr); + + if (is_same_flow(&sw_ft_entry->rx_flow_tuple_info, + &rx_flow_tuple_info)) { + sw_ft_entry->vdev = vdev; + dp_fisa_debug("It is same flow fse entry idx %d", + hashed_flow_idx); + /* Incoming flow tuple matches with existing + * entry. This is subsequent skbs of the same + * flow. Earlier entry made is not reflected + * yet in FSE cache + */ + break; + } + /* else */ + /* hash collision move to the next FT entry */ + dp_fisa_debug("Hash collision %d", fisa_hdl->hash_collision_cnt); + fisa_hdl->hash_collision_cnt++; +#ifdef NOT_YET /* assist Flow eviction algorithm */ + /* uint32_t lru_ft_entry_time = 0xffffffff, lru_ft_entry_idx = 0; */ + if (fisa_hdl->hw_ft_entry->timestamp < lru_ft_entry_time) { + lru_ft_entry_time = fisa_hdl->hw_ft_entry->timestamp; + lru_ft_entry_idx = hashed_flow_idx; + } +#endif + skid_count++; + hashed_flow_idx++; + hashed_flow_idx &= fisa_hdl->hash_mask; + } while (skid_count <= max_skid_length); + + /* + * fisa_hdl->flow_eviction_cnt++; + * if (skid_count > max_skid_length) + * Remove LRU flow from HW FT + * Remove LRU flow from SW FT + */ + qdf_spin_unlock_bh(&fisa_hdl->dp_rx_fst_lock); + + if (skid_count > max_skid_length) { + dp_fisa_debug("Max skid length reached flow cannot be added, evict exiting flow"); + return NULL; + } + + /** + * Send HTT cache invalidation command to firmware to + * reflect the flow update + */ + if (is_fst_updated && + (qdf_atomic_inc_return(&fisa_hdl->fse_cache_flush_posted) == 1)) { + /* return 1 after increment implies FSE cache flush message + * already posted. so start restart the timer + */ + qdf_timer_start(&fisa_hdl->fse_cache_flush_timer, + FSE_CACHE_FLUSH_TIME_OUT); + + } + dp_fisa_debug("sw_ft_entry %pK", sw_ft_entry); + return sw_ft_entry; +} + +/** + * is_flow_idx_valid() - Function to decide if flow_idx TLV is valid + * @flow_invalid: flow invalid TLV value + * @flow_timeout: flow timeout TLV value, set when FSE timedout flow search + * + * Return: True if flow_idx value is valid + */ +static bool is_flow_idx_valid(bool flow_invalid, bool flow_timeout) +{ + if (!flow_invalid && !flow_timeout) + return true; + else + return false; +} + +/** + * dp_rx_get_fisa_flow() - Get FT entry corresponding to incoming nbuf + * @fisa_hdl: handle to FISA context + * @vdev: handle to DP vdev + * @nbuf: incoming msdu + * + * Return: handle SW FT entry for nbuf flow + */ +static struct dp_fisa_rx_sw_ft * +dp_rx_get_fisa_flow(struct dp_rx_fst *fisa_hdl, struct dp_vdev *vdev, + qdf_nbuf_t nbuf) +{ + uint8_t *rx_tlv_hdr; + uint32_t flow_idx; + uint32_t reo_destination_indication; + bool flow_invalid, flow_timeout, flow_idx_valid; + struct dp_fisa_rx_sw_ft *sw_ft_entry = NULL; + struct dp_fisa_rx_sw_ft *sw_ft_base = (struct dp_fisa_rx_sw_ft *) + fisa_hdl->base; + hal_soc_handle_t hal_soc_hdl = fisa_hdl->soc_hdl->hal_soc; + + if (QDF_NBUF_CB_RX_TCP_PROTO(nbuf)) + return sw_ft_entry; + + rx_tlv_hdr = qdf_nbuf_data(nbuf); + hal_rx_msdu_get_reo_destination_indication(hal_soc_hdl, rx_tlv_hdr, + &reo_destination_indication); + /* + * Compare reo_destination_indication between reo ring descriptor + * and rx_pkt_tlvs, if they are different, then likely these kind + * of frames re-injected by FW or touched by other module already, + * skip FISA to avoid REO2SW ring mismatch issue for same flow. + */ + if (reo_destination_indication != qdf_nbuf_get_rx_reo_dest_ind(nbuf)) + return sw_ft_entry; + + hal_rx_msdu_get_flow_params(hal_soc_hdl, rx_tlv_hdr, &flow_invalid, + &flow_timeout, &flow_idx); + + dp_fisa_debug("nbuf %pK fl_idx %d fl_inv %d fl_timeout %d", + nbuf, flow_idx, flow_invalid, flow_timeout); + + flow_idx_valid = is_flow_idx_valid(flow_invalid, flow_timeout); + if (flow_idx_valid) { + /* If flow index is invalid, fail to get flow */ + if (qdf_unlikely(flow_idx >= fisa_hdl->max_entries)) { + dp_info("flow_idx is invalid 0x%x", flow_idx); + hal_rx_dump_pkt_tlvs(hal_soc_hdl, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO_HIGH); + DP_STATS_INC(fisa_hdl, invalid_flow_index, 1); + return NULL; + } + sw_ft_entry = &sw_ft_base[flow_idx]; + sw_ft_entry->vdev = vdev; + + return sw_ft_entry; + } + + /* else new flow, add entry to FT */ + sw_ft_entry = dp_rx_fisa_add_ft_entry(fisa_hdl, flow_idx, nbuf, vdev, + rx_tlv_hdr, + reo_destination_indication); + + return sw_ft_entry; +} + +#ifdef NOT_YET +/** + * dp_rx_fisa_aggr_tcp() - Aggregate incoming to TCP nbuf + * @fisa_flow: Handle to SW flow entry, which holds the aggregated nbuf + * @nbuf: Incoming nbuf + * + * Return: FISA_AGGR_DONE on successful aggregation + */ +static enum fisa_aggr_ret +dp_rx_fisa_aggr_tcp(struct dp_fisa_rx_sw_ft *fisa_flow, qdf_nbuf_t nbuf) +{ + qdf_nbuf_t head_skb = fisa_flow->head_skb; + struct iphdr *iph; + uint32_t tcp_data_len; + + fisa_flow->bytes_aggregated += qdf_nbuf_len(nbuf); + if (!head_skb) { + /* First nbuf for the flow */ + dp_fisa_debug("first head skb"); + fisa_flow->head_skb = nbuf; + return FISA_AGGR_DONE; + } + + tcp_data_len = (ntohs(iph->tot_len) - sizeof(struct iphdr) - + sizeof(struct tcphdr)); + qdf_nbuf_pull_head(nbuf, (nbuf->len - tcp_data_len)); + + if (qdf_nbuf_get_ext_list(head_skb)) { + /* this is 3rd skb after head skb, 2nd skb */ + fisa_flow->last_skb->next = nbuf; + } else { + /* 1st skb after head skb */ + qdf_nbuf_append_ext_list(head_skb, nbuf, + fisa_flow->cumulative_ip_length); + qdf_nbuf_set_is_frag(head, 1); + } + + fisa_flow->last_skb = nbuf; + fisa_flow->aggr_count++; + + /* move it to while flushing the flow, that is update before flushing */ + return FISA_AGGR_DONE; +} +#else +static enum fisa_aggr_ret +dp_rx_fisa_aggr_tcp(struct dp_rx_fst *fisa_hdl, + struct dp_fisa_rx_sw_ft *fisa_flow, qdf_nbuf_t nbuf) +{ + return FISA_AGGR_DONE; +} +#endif + +/** + * get_transport_payload_offset() - Get offset to payload + * @fisa_hdl: Handle to FISA context + * @rx_tlv_hdr: TLV hdr pointer + * + * Return: Offset value to transport payload + */ +static int get_transport_payload_offset(struct dp_rx_fst *fisa_hdl, + uint8_t *rx_tlv_hdr) +{ + uint32_t eth_hdr_len = HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr); + uint32_t ip_hdr_len = HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr); + + /* ETHERNET_HDR_LEN + ip_hdr_len + UDP/TCP; */ + return (eth_hdr_len + ip_hdr_len + sizeof(struct udphdr)); +} + +/** + * get_transport_header_offset() - Get transport header offset + * @fisa_flow: Handle to FISA sw flow entry + * @rx_tlv_hdr: TLV hdr pointer + * + * Return: Offset value to transport header + */ +static int get_transport_header_offset(struct dp_fisa_rx_sw_ft *fisa_flow, + uint8_t *rx_tlv_hdr) + +{ + uint32_t eth_hdr_len = HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr); + uint32_t ip_hdr_len = HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr); + + /* ETHERNET_HDR_LEN + ip_hdr_len */ + return (eth_hdr_len + ip_hdr_len); +} + +/** + * dp_rx_fisa_aggr_udp() - Aggregate incoming to UDP nbuf + * @fisa_flow: Handle to SW flow entry, which holds the aggregated nbuf + * @nbuf: Incoming nbuf + * + * Return: FISA_AGGR_DONE on successful aggregation + */ +static enum fisa_aggr_ret +dp_rx_fisa_aggr_udp(struct dp_rx_fst *fisa_hdl, + struct dp_fisa_rx_sw_ft *fisa_flow, qdf_nbuf_t nbuf) +{ + qdf_nbuf_t head_skb = fisa_flow->head_skb; + uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf); + uint32_t l2_hdr_offset = + hal_rx_msdu_end_l3_hdr_padding_get(fisa_hdl->soc_hdl->hal_soc, + rx_tlv_hdr); + struct udphdr *udp_hdr; + uint32_t transport_payload_offset; + + qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN + l2_hdr_offset); + + udp_hdr = (struct udphdr *)(qdf_nbuf_data(nbuf) + + get_transport_header_offset(fisa_flow, rx_tlv_hdr)); + + /** + * Incoming nbuf is of size greater than ongoing aggregation + * then flush the aggregate and start new aggregation for nbuf + */ + if (head_skb && + (qdf_ntohs(udp_hdr->len) > + qdf_ntohs(fisa_flow->head_skb_udp_hdr->len))) { + /* current msdu should not take into account for flushing */ + fisa_flow->adjusted_cumulative_ip_length -= + (qdf_ntohs(udp_hdr->len) - sizeof(struct udphdr)); + fisa_flow->cur_aggr--; + dp_rx_fisa_flush_flow_wrap(fisa_flow); + /* napi_flush_cumulative_ip_length not include current msdu */ + fisa_flow->napi_flush_cumulative_ip_length -= + qdf_ntohs(udp_hdr->len); + head_skb = NULL; + } + + if (!head_skb) { + dp_fisa_debug("first head skb nbuf %pK", nbuf); + /* First nbuf for the flow */ + fisa_flow->head_skb = nbuf; + fisa_flow->head_skb_udp_hdr = udp_hdr; + fisa_flow->cur_aggr_gso_size = qdf_ntohs(udp_hdr->len) - + sizeof(struct udphdr); + fisa_flow->adjusted_cumulative_ip_length = + qdf_ntohs(udp_hdr->len); + fisa_flow->head_skb_ip_hdr_offset = + HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr); + fisa_flow->head_skb_l4_hdr_offset = + HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr); + + return FISA_AGGR_DONE; + } + + transport_payload_offset = + get_transport_payload_offset(fisa_hdl, rx_tlv_hdr); + + hex_dump_skb_data(nbuf, false); + qdf_nbuf_pull_head(nbuf, transport_payload_offset); + hex_dump_skb_data(nbuf, false); + + fisa_flow->bytes_aggregated += qdf_nbuf_len(nbuf); + + if (qdf_nbuf_get_ext_list(head_skb)) { + /* + * This is 3rd skb for flow. + * After head skb, 2nd skb in fraglist + */ + qdf_nbuf_set_next(fisa_flow->last_skb, nbuf); + } else { + /* 1st skb after head skb + * implement qdf wrapper set_ext_list + */ + skb_shinfo(head_skb)->frag_list = nbuf; + qdf_nbuf_set_is_frag(nbuf, 1); + } + + fisa_flow->last_skb = nbuf; + fisa_flow->aggr_count++; + + dp_fisa_debug("Stiched head skb fisa_flow %pK", fisa_flow); + hex_dump_skb_data(fisa_flow->head_skb, false); + + /** + * Incoming nbuf is of size less than ongoing aggregation + * then flush the aggregate + */ + if (qdf_ntohs(udp_hdr->len) < + qdf_ntohs(fisa_flow->head_skb_udp_hdr->len)) + dp_rx_fisa_flush_flow_wrap(fisa_flow); + + return FISA_AGGR_DONE; +} +/** + * dp_fisa_rx_linear_skb() - Linearize fraglist skb to linear skb + * @vdev: handle to DP vdev + * @head_skb: non linear skb + * @size: Total length of non linear stiched skb + * + * Return: Linearized skb pointer + */ +static qdf_nbuf_t dp_fisa_rx_linear_skb(struct dp_vdev *vdev, + qdf_nbuf_t head_skb, uint32_t size) +{ +#if 0 + qdf_nbuf_t linear_skb, ext_skb, next_skb; + + linear_skb = qdf_nbuf_alloc(vdev->osdev, size, 0, 0, FALSE); + if (!linear_skb) + return NULL; + + dp_fisa_debug("head %pK data %pK tail %pK\n", head_skb->head, + head_skb->data, head_skb->tail); + ext_skb = skb_shinfo(head_skb)->frag_list; + if (ext_skb) { + skb_put_data(linear_skb, head_skb->data, 1512); + dp_fisa_debug("%d: len %d\n", __LINE__, ext_skb->len); + skb_put_data(linear_skb, ext_skb->data, ext_skb->len); + } else { + dp_fisa_debug("%d: len %d\n", __LINE__, head_skb->len); + skb_put_data(linear_skb, head_skb->data, head_skb->len); + goto done; + } + + next_skb = ext_skb->next; + while (next_skb) { + dp_fisa_debug("%d: len %d\n", __LINE__, next_skb->len); + skb_put_data(linear_skb, next_skb->data, next_skb->len); + next_skb = next_skb->next; + } + +done: + skb_copy_header(linear_skb, head_skb); + skb_reset_transport_header(linear_skb); + skb_reset_network_header(linear_skb); + linear_skb->pkt_type = PACKET_HOST; + skb_set_mac_header(linear_skb, 0); + linear_skb->ip_summed = CHECKSUM_PARTIAL; + dp_fisa_debug("linear skb %pK len %d gso_size %d mac_len %d net_header %d mac_header %d", + linear_skb, linear_skb->len, + skb_shinfo(linear_skb)->gso_size, linear_skb->mac_len, + linear_skb->network_header, linear_skb->mac_header); + + return linear_skb; +#endif + return NULL; +} + +/** + * dp_rx_fisa_flush_udp_flow() - Flush all aggregated nbuf of the udp flow + * @vdev: handle to dp_vdev + * @fisa_flow: Flow for which aggregates to be flushed + * + * Return: None + */ +static void +dp_rx_fisa_flush_udp_flow(struct dp_vdev *vdev, + struct dp_fisa_rx_sw_ft *fisa_flow) +{ + qdf_nbuf_t head_skb = fisa_flow->head_skb; + struct iphdr *head_skb_iph; + struct udphdr *head_skb_udp_hdr; + struct skb_shared_info *shinfo; + qdf_nbuf_t linear_skb; + struct dp_vdev *fisa_flow_vdev; + + dp_fisa_debug("head_skb %pK", head_skb); + dp_fisa_debug("cumulative ip length %d", + fisa_flow->adjusted_cumulative_ip_length); + if (!head_skb) { + dp_fisa_debug("Already flushed"); + return; + } + + head_skb->hash = QDF_NBUF_CB_RX_FLOW_ID(head_skb); + head_skb->sw_hash = 1; + if (qdf_nbuf_get_ext_list(head_skb)) { + __sum16 pseudo; + + shinfo = skb_shinfo(head_skb); + /* Update the head_skb before flush */ + dp_fisa_debug("cumu ip length host order 0x%x", + fisa_flow->adjusted_cumulative_ip_length); + head_skb_iph = (struct iphdr *)(qdf_nbuf_data(head_skb) + + fisa_flow->head_skb_ip_hdr_offset); + dp_fisa_debug("iph ptr %pK", head_skb_iph); + + head_skb_udp_hdr = fisa_flow->head_skb_udp_hdr; + + dp_fisa_debug("udph ptr %pK", head_skb_udp_hdr); + + dp_fisa_debug("tot_len 0x%x", qdf_ntohs(head_skb_iph->tot_len)); + + /* data_len is total length of non head_skb, + * cumulative ip length is including head_skb ip length also + */ + head_skb->data_len = + (fisa_flow->adjusted_cumulative_ip_length) - + qdf_ntohs(head_skb_udp_hdr->len); + + head_skb->len += head_skb->data_len; + + head_skb_iph->tot_len = + qdf_htons((fisa_flow->adjusted_cumulative_ip_length) + + /* IP hdr len */ + fisa_flow->head_skb_l4_hdr_offset); + pseudo = ~csum_tcpudp_magic(head_skb_iph->saddr, + head_skb_iph->daddr, + fisa_flow->adjusted_cumulative_ip_length, + head_skb_iph->protocol, 0); + + head_skb_iph->check = 0; + head_skb_iph->check = ip_fast_csum((u8 *)head_skb_iph, + head_skb_iph->ihl); + + head_skb_udp_hdr->len = + qdf_htons(qdf_ntohs(head_skb_iph->tot_len) - + fisa_flow->head_skb_l4_hdr_offset); + head_skb_udp_hdr->check = pseudo; + head_skb->csum_start = (u8 *)head_skb_udp_hdr - head_skb->head; + head_skb->csum_offset = offsetof(struct udphdr, check); + + shinfo->gso_size = fisa_flow->cur_aggr_gso_size; + dp_fisa_debug("gso_size %d, udp_len %d\n", shinfo->gso_size, + qdf_ntohs(head_skb_udp_hdr->len)); + shinfo->gso_segs = fisa_flow->cur_aggr; + shinfo->gso_type = SKB_GSO_UDP_L4; + head_skb->ip_summed = CHECKSUM_PARTIAL; + } + + qdf_nbuf_set_next(fisa_flow->head_skb, NULL); + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(fisa_flow->head_skb) = 1; + if (fisa_flow->last_skb) + qdf_nbuf_set_next(fisa_flow->last_skb, NULL); + + hex_dump_skb_data(fisa_flow->head_skb, false); + + fisa_flow_vdev = dp_get_vdev_from_soc_vdev_id_wifi3(fisa_flow->soc_hdl, + QDF_NBUF_CB_RX_VDEV_ID(fisa_flow->head_skb)); + if (qdf_unlikely(!fisa_flow_vdev || + (fisa_flow_vdev != fisa_flow->vdev))) { + qdf_nbuf_free(fisa_flow->head_skb); + goto out; + } + dp_fisa_debug("fisa_flow->curr_aggr %d", fisa_flow->cur_aggr); + linear_skb = dp_fisa_rx_linear_skb(vdev, fisa_flow->head_skb, 24000); + if (linear_skb) { + if (!vdev->osif_rx || QDF_STATUS_SUCCESS != + vdev->osif_rx(vdev->osif_vdev, linear_skb)) + qdf_nbuf_free(linear_skb); + /* Free non linear skb */ + qdf_nbuf_free(fisa_flow->head_skb); + } else { + if (!vdev->osif_rx || QDF_STATUS_SUCCESS != + vdev->osif_rx(vdev->osif_vdev, fisa_flow->head_skb)) + qdf_nbuf_free(fisa_flow->head_skb); + } + +out: + fisa_flow->head_skb = NULL; + fisa_flow->last_skb = NULL; + + fisa_flow->flush_count++; +} + +/** + * dp_rx_fisa_flush_tcp_flow() - Flush all aggregated nbuf of the TCP flow + * @vdev: handle to dp_vdev + * @fisa_flow: Flow for which aggregates to be flushed + * + * Return: None + */ +static void +dp_rx_fisa_flush_tcp_flow(struct dp_vdev *vdev, + struct dp_fisa_rx_sw_ft *fisa_flow) +{ + qdf_nbuf_t head_skb = fisa_flow->head_skb; + struct iphdr *head_skb_iph; + struct skb_shared_info *shinfo; + + if (!head_skb) { + dp_fisa_debug("Already flushed"); + return; + } + + shinfo = skb_shinfo(head_skb); + + /* Update the head_skb before flush */ + head_skb->hash = fisa_flow->flow_hash; + head_skb->sw_hash = 1; + shinfo->gso_type = SKB_GSO_UDP_L4; + + head_skb_iph = (struct iphdr *)(qdf_nbuf_data(head_skb) + + fisa_flow->head_skb_ip_hdr_offset); + + head_skb_iph->tot_len = fisa_flow->adjusted_cumulative_ip_length; + head_skb_iph->check = ip_fast_csum((u8 *)head_skb_iph, + head_skb_iph->ihl); + + qdf_nbuf_set_next(fisa_flow->head_skb, NULL); + if (fisa_flow->last_skb) + qdf_nbuf_set_next(fisa_flow->last_skb, NULL); + vdev->osif_rx(vdev->osif_vdev, fisa_flow->head_skb); + + fisa_flow->head_skb = NULL; + + fisa_flow->flush_count++; +} + +/** + * dp_rx_fisa_flush_flow() - Flush all aggregated nbuf of the flow + * @vdev: handle to dp_vdev + * @fisa_flow: Flow for which aggregates to be flushed + * + * Return: None + */ +static void dp_rx_fisa_flush_flow(struct dp_vdev *vdev, + struct dp_fisa_rx_sw_ft *flow) +{ + dp_fisa_debug("dp_rx_fisa_flush_flow"); + + if (flow->is_flow_udp) + dp_rx_fisa_flush_udp_flow(vdev, flow); + else + dp_rx_fisa_flush_tcp_flow(vdev, flow); +} + +/** + * dp_fisa_aggregation_should_stop - check if fisa aggregate should stop + * @fisa_flow: Handle SW flow entry + * @hal_aggr_count: current aggregate count from RX PKT TLV + * @hal_cumulative_ip_len: current cumulative ip length from RX PKT TLV + * @rx_tlv_hdr: current msdu RX PKT TLV + * + * Return: true - current flow aggregation should stop, + false - continue to aggregate. + */ +static bool dp_fisa_aggregation_should_stop( + struct dp_fisa_rx_sw_ft *fisa_flow, + uint32_t hal_aggr_count, + uint16_t hal_cumulative_ip_len, + uint8_t *rx_tlv_hdr) +{ + uint32_t msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr); + uint32_t l4_hdr_offset = HAL_RX_TLV_GET_IP_OFFSET(rx_tlv_hdr) + + HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv_hdr); + uint32_t cumulative_ip_len_delta = hal_cumulative_ip_len - + fisa_flow->hal_cumultive_ip_len; + /** + * current cumulative ip length should > last cumulative_ip_len + * and <= last cumulative_ip_len + 1478, also current aggregate + * count should be equal to last aggregate count + 1, + * cumulative_ip_len delta should be equal to current msdu length + * - l4 header offset, + * otherwise, current fisa flow aggregation should be stopped. + */ + if (fisa_flow->do_not_aggregate || + hal_cumulative_ip_len <= fisa_flow->hal_cumultive_ip_len || + cumulative_ip_len_delta > FISA_MAX_SINGLE_CUMULATIVE_IP_LEN || + (fisa_flow->last_hal_aggr_count + 1) != hal_aggr_count || + cumulative_ip_len_delta != (msdu_len - l4_hdr_offset)) + return true; + + return false; +} + +/** + * dp_add_nbuf_to_fisa_flow() - Aggregate incoming nbuf + * @fisa_hdl: handle to fisa context + * @vdev: handle DP vdev + * @nbuf: Incoming nbuf + * @fisa_flow: Handle SW flow entry + * + * Return: Success on aggregation + */ +static int dp_add_nbuf_to_fisa_flow(struct dp_rx_fst *fisa_hdl, + struct dp_vdev *vdev, qdf_nbuf_t nbuf, + struct dp_fisa_rx_sw_ft *fisa_flow) +{ + bool flow_aggr_cont; + uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf); + bool flow_invalid, flow_timeout; + uint32_t flow_idx; + uint16_t hal_cumulative_ip_len; + hal_soc_handle_t hal_soc_hdl = fisa_hdl->soc_hdl->hal_soc; + uint32_t hal_aggr_count; + uint8_t napi_id = QDF_NBUF_CB_RX_CTX_ID(nbuf); + + dump_tlvs(hal_soc_hdl, rx_tlv_hdr, QDF_TRACE_LEVEL_ERROR); + dp_fisa_debug("nbuf: %pK nbuf->next:%pK nbuf->data:%pK len %d data_len %d", + nbuf, qdf_nbuf_next(nbuf), qdf_nbuf_data(nbuf), nbuf->len, + nbuf->data_len); + + /* Packets of the same flow are arriving on a different REO than + * the one configured. + */ + if (qdf_unlikely(fisa_flow->napi_id != napi_id)) { + QDF_BUG(0); + return FISA_AGGR_NOT_ELIGIBLE; + } + + hal_cumulative_ip_len = hal_rx_get_fisa_cumulative_ip_length( + hal_soc_hdl, + rx_tlv_hdr); + flow_aggr_cont = hal_rx_get_fisa_flow_agg_continuation(hal_soc_hdl, + rx_tlv_hdr); + hal_aggr_count = hal_rx_get_fisa_flow_agg_count(hal_soc_hdl, + rx_tlv_hdr); + + if (!flow_aggr_cont) { + /* Start of new aggregation for the flow + * Flush previous aggregates for this flow + */ + dp_fisa_debug("no fgc nbuf %pK, flush %pK napi %d", nbuf, + fisa_flow, QDF_NBUF_CB_RX_CTX_ID(nbuf)); + dp_rx_fisa_flush_flow(vdev, fisa_flow); + /* Clear of previoud context values */ + fisa_flow->napi_flush_cumulative_l4_checksum = 0; + fisa_flow->napi_flush_cumulative_ip_length = 0; + fisa_flow->cur_aggr = 0; + fisa_flow->do_not_aggregate = false; + if (hal_cumulative_ip_len > FISA_MAX_SINGLE_CUMULATIVE_IP_LEN) + qdf_assert(0); + } else if (qdf_unlikely(dp_fisa_aggregation_should_stop( + fisa_flow, + hal_aggr_count, + hal_cumulative_ip_len, + rx_tlv_hdr))) { + /* Either HW cumulative ip length is wrong, or packet is missed + * Flush the flow and do not aggregate until next start new + * aggreagtion + */ + dp_rx_fisa_flush_flow(vdev, fisa_flow); + fisa_flow->do_not_aggregate = true; + fisa_flow->cur_aggr = 0; + fisa_flow->napi_flush_cumulative_ip_length = 0; + goto invalid_fisa_assist; + } else { + /* takecare to skip the udp hdr len for sub sequent cumulative + * length + */ + fisa_flow->cur_aggr++; + } + hal_rx_msdu_get_flow_params(hal_soc_hdl, rx_tlv_hdr, &flow_invalid, + &flow_timeout, &flow_idx); + dp_fisa_debug("nbuf %pK cumulat_ip_length %d flow %pK fl aggr cont %d", + nbuf, hal_cumulative_ip_len, fisa_flow, flow_aggr_cont); + + fisa_flow->aggr_count++; + fisa_flow->last_hal_aggr_count = hal_aggr_count; + fisa_flow->hal_cumultive_ip_len = hal_cumulative_ip_len; + + if (!fisa_flow->head_skb) { + /* This is start of aggregation for the flow, save the offsets*/ + fisa_flow->napi_flush_cumulative_l4_checksum = 0; + fisa_flow->cur_aggr = 0; + } + + fisa_flow->adjusted_cumulative_ip_length = + /* cumulative ip len has all the aggr msdu udp header len + * Aggr UDP msdu has one UDP header len + */ + (hal_cumulative_ip_len - + (fisa_flow->cur_aggr * sizeof(struct udphdr))) - + fisa_flow->napi_flush_cumulative_ip_length; + + /** + * cur_aggr does not include the head_skb, so compare with + * FISA_FLOW_MAX_AGGR_COUNT - 1. + */ + if (fisa_flow->cur_aggr > (FISA_FLOW_MAX_AGGR_COUNT - 1)) + dp_err("HAL cumulative_ip_length %d", hal_cumulative_ip_len); + + dp_fisa_debug("hal cum_len 0x%x - napI_cumu_len 0x%x = flow_cum_len 0x%x cur_aggr %d", + hal_cumulative_ip_len, + fisa_flow->napi_flush_cumulative_ip_length, + fisa_flow->adjusted_cumulative_ip_length, + fisa_flow->cur_aggr); + + if (fisa_flow->adjusted_cumulative_ip_length > + FISA_FLOW_MAX_CUMULATIVE_IP_LEN) { + dp_err("fisa_flow %pK nbuf %pK", fisa_flow, nbuf); + dp_err("fisa_flow->adjusted_cumulative_ip_length %d", + fisa_flow->adjusted_cumulative_ip_length); + dp_err("HAL cumulative_ip_length %d", hal_cumulative_ip_len); + dp_err("napi_flush_cumulative_ip_length %d", + fisa_flow->napi_flush_cumulative_ip_length); + qdf_assert(0); + } + + if (fisa_flow->is_flow_udp) { + dp_rx_fisa_aggr_udp(fisa_hdl, fisa_flow, nbuf); + } else if (fisa_flow->is_flow_tcp) { + qdf_assert(0); + dp_rx_fisa_aggr_tcp(fisa_hdl, fisa_flow, nbuf); + } + + return FISA_AGGR_DONE; + +invalid_fisa_assist: + /* Not eligible aggregation deliver frame without FISA */ + return FISA_AGGR_NOT_ELIGIBLE; +} + +/** + * dp_is_nbuf_bypass_fisa() - FISA bypass check for RX frame + * @nbuf: RX nbuf pointer + * + * Return: true if FISA should be bypassed else false + */ +static bool dp_is_nbuf_bypass_fisa(qdf_nbuf_t nbuf) +{ + /* RX frame from non-regular path or DHCP packet */ + if (qdf_nbuf_is_exc_frame(nbuf) || + qdf_nbuf_is_ipv4_dhcp_pkt(nbuf) || + qdf_nbuf_is_da_mcbc(nbuf)) + return true; + + return false; +} + +/** + * dp_rx_fisa_flush_by_vdev_ctx_id() - Flush fisa aggregates per vdev and rx + * context id + * @soc: core txrx main context + * @vdev: Handle DP vdev + * @rx_ctx_id: Rx context id + * + * Return: Success on flushing the flows for the vdev and rx ctx id + */ +static +QDF_STATUS dp_rx_fisa_flush_by_vdev_ctx_id(struct dp_soc *soc, + struct dp_vdev *vdev, + uint8_t rx_ctx_id) +{ + struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; + int ft_size = fisa_hdl->max_entries; + int i; + + for (i = 0; i < ft_size; i++) { + if (sw_ft_entry[i].is_populated && + vdev == sw_ft_entry[i].vdev && + sw_ft_entry[i].napi_id == rx_ctx_id) { + dp_fisa_debug("flushing %d %pk vdev %pK napi id:%d", i, + &sw_ft_entry[i], vdev, rx_ctx_id); + dp_rx_fisa_flush_flow_wrap(&sw_ft_entry[i]); + } + } + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_fisa_disallowed_for_vdev() - Check if fisa is allowed on vdev + * @soc: core txrx main context + * @vdev: Handle DP vdev + * @rx_ctx_id: Rx context id + * + * Return: true if fisa is disallowed for vdev else false + */ +static bool dp_fisa_disallowed_for_vdev(struct dp_soc *soc, + struct dp_vdev *vdev, + uint8_t rx_ctx_id) +{ + if (!vdev->fisa_disallowed[rx_ctx_id]) { + if (vdev->fisa_force_flushed[rx_ctx_id]) + vdev->fisa_force_flushed[rx_ctx_id] = 0; + return false; + } + + if (!vdev->fisa_force_flushed[rx_ctx_id]) { + dp_rx_fisa_flush_by_vdev_ctx_id(soc, vdev, rx_ctx_id); + vdev->fisa_force_flushed[rx_ctx_id] = 1; + } + + return true; +} + +/** + * dp_fisa_rx() - Entry function to FISA to handle aggregation + * @soc: core txrx main context + * @vdev: Handle DP vdev + * @nbuf_list: List nbufs to be aggregated + * + * Return: Success on aggregation + */ +QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf_list) +{ + struct dp_rx_fst *dp_fisa_rx_hdl = soc->rx_fst; + qdf_nbuf_t head_nbuf; + qdf_nbuf_t next_nbuf; + struct dp_fisa_rx_sw_ft *fisa_flow; + int fisa_ret; + uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf_list); + + head_nbuf = nbuf_list; + + while (head_nbuf) { + next_nbuf = head_nbuf->next; + qdf_nbuf_set_next(head_nbuf, NULL); + + /* bypass FISA check */ + if (dp_is_nbuf_bypass_fisa(head_nbuf)) + goto deliver_nbuf; + + if (dp_fisa_disallowed_for_vdev(soc, vdev, rx_ctx_id)) + goto deliver_nbuf; + + if (qdf_atomic_read(&soc->skip_fisa_param.skip_fisa)) { + if (!soc->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { + dp_rx_fisa_flush_by_ctx_id(soc, rx_ctx_id); + soc->skip_fisa_param. + fisa_force_flush[rx_ctx_id] = 1; + } + goto deliver_nbuf; + } else if (soc->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { + soc->skip_fisa_param.fisa_force_flush[rx_ctx_id] = 0; + } + + qdf_nbuf_push_head(head_nbuf, RX_PKT_TLVS_LEN + + QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(head_nbuf)); + + /* Add new flow if the there is no ongoing flow */ + fisa_flow = dp_rx_get_fisa_flow(dp_fisa_rx_hdl, vdev, + head_nbuf); + + /* Fragmented skb do not handle via fisa + * get that flow and deliver that flow to rx_thread + */ + if (qdf_unlikely(qdf_nbuf_get_ext_list(head_nbuf))) { + dp_fisa_debug("Fragmented skb, will not be FISAed"); + if (fisa_flow) + dp_rx_fisa_flush_flow(vdev, fisa_flow); + goto pull_nbuf; + } + + if (!fisa_flow) + goto pull_nbuf; + + fisa_ret = dp_add_nbuf_to_fisa_flow(dp_fisa_rx_hdl, vdev, + head_nbuf, fisa_flow); + if (fisa_ret == FISA_AGGR_DONE) + goto next_msdu; + +pull_nbuf: + nbuf_skip_rx_pkt_tlv(dp_fisa_rx_hdl->soc_hdl->hal_soc, + head_nbuf); + +deliver_nbuf: /* Deliver without FISA */ + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(head_nbuf) = 1; + qdf_nbuf_set_next(head_nbuf, NULL); + hex_dump_skb_data(head_nbuf, false); + if (!vdev->osif_rx || QDF_STATUS_SUCCESS != + vdev->osif_rx(vdev->osif_vdev, head_nbuf)) + qdf_nbuf_free(head_nbuf); +next_msdu: + head_nbuf = next_nbuf; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) +{ + struct dp_rx_fst *rx_fst = soc->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + &((struct dp_fisa_rx_sw_ft *)rx_fst->base)[0]; + int ft_size = rx_fst->max_entries; + int i; + uint64_t avg_aggregated; + + dp_info("Num of flows programmed %d", rx_fst->add_flow_count); + dp_info("Num of flows evicted %d", rx_fst->del_flow_count); + dp_info("Hash collision count %d", rx_fst->hash_collision_cnt); + + for (i = 0; i < ft_size; i++, sw_ft_entry++) { + if (!sw_ft_entry->is_populated) + continue; + + dp_info("FLOw ID %d is %s on napi/ring %d", + sw_ft_entry->flow_id, + sw_ft_entry->is_flow_udp ? "udp" : "tcp", + sw_ft_entry->napi_id); + dp_info("num msdu aggr %d", sw_ft_entry->aggr_count); + dp_info("flush count %d", sw_ft_entry->flush_count); + dp_info("bytes_aggregated %llu", sw_ft_entry->bytes_aggregated); + avg_aggregated = sw_ft_entry->bytes_aggregated; + qdf_do_div(avg_aggregated, sw_ft_entry->flush_count); + dp_info("avg aggregation %llu", avg_aggregated); + print_flow_tuple(&sw_ft_entry->rx_flow_tuple_info); + } + return QDF_STATUS_SUCCESS; +} + +/** + * dp_rx_fisa_flush_flow_wrap() - flush fisa flow by invoking + * dp_rx_fisa_flush_flow() + * @sw_ft: fisa flow for which aggregates to be flushed + * + * Return: None. + */ +static void dp_rx_fisa_flush_flow_wrap(struct dp_fisa_rx_sw_ft *sw_ft) +{ + /* Save the ip_len and checksum as hardware assist is + * always based on his start of aggregation + */ + sw_ft->napi_flush_cumulative_l4_checksum = + sw_ft->cumulative_l4_checksum; + sw_ft->napi_flush_cumulative_ip_length = + sw_ft->hal_cumultive_ip_len; + dp_fisa_debug("napi_flush_cumulative_ip_length 0x%x", + sw_ft->napi_flush_cumulative_ip_length); + + dp_rx_fisa_flush_flow(sw_ft->vdev, + sw_ft); + sw_ft->cur_aggr = 0; +} + +QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id) +{ + struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; + int ft_size = fisa_hdl->max_entries; + int i; + + for (i = 0; i < ft_size; i++) { + if (sw_ft_entry[i].napi_id == napi_id && + sw_ft_entry[i].is_populated) { + dp_fisa_debug("flushing %d %pK napi_id %d", i, + &sw_ft_entry[i], napi_id); + dp_rx_fisa_flush_flow_wrap(&sw_ft_entry[i]); + } + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS dp_rx_fisa_flush_by_vdev_id(struct dp_soc *soc, uint8_t vdev_id) +{ + struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; + int ft_size = fisa_hdl->max_entries; + int i; + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + if (qdf_unlikely(!vdev)) { + dp_err("null vdev by vdev_id %d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < ft_size; i++) { + if (vdev == sw_ft_entry[i].vdev) { + dp_fisa_debug("flushing %d %pk vdev %pK", i, + &sw_ft_entry[i], vdev); + dp_rx_fisa_flush_flow_wrap(&sw_ft_entry[i]); + } + } + + return QDF_STATUS_SUCCESS; +} + +void dp_set_fisa_disallowed_for_vdev(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + uint8_t rx_ctx_id, uint8_t val) +{ + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct dp_vdev *vdev; + + vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id); + if (qdf_unlikely(!vdev)) + return; + + vdev->fisa_disallowed[rx_ctx_id] = val; +} diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.h b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..2642c584ae4ab55079e6970a0bca5ad9a4b24871 --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_fisa_rx.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include + +//#define FISA_DEBUG_ENABLE + +#ifdef FISA_DEBUG_ENABLE +#define dp_fisa_debug dp_info +#else +#define dp_fisa_debug dp_debug +#endif + +#if defined(WLAN_SUPPORT_RX_FISA) + +#define FSE_CACHE_FLUSH_TIME_OUT 5 /* milliSeconds */ +#define FISA_UDP_MAX_DATA_LEN 1470 /* udp max data length */ +#define FISA_UDP_HDR_LEN 8 /* udp header length */ +#define FISA_FLOW_MAX_AGGR_COUNT 16 /* max flow aggregate count */ +/* single packet max cumulative ip length */ +#define FISA_MAX_SINGLE_CUMULATIVE_IP_LEN \ + (FISA_UDP_MAX_DATA_LEN + FISA_UDP_HDR_LEN) +/* max flow cumulative ip length */ +#define FISA_FLOW_MAX_CUMULATIVE_IP_LEN \ + (FISA_MAX_SINGLE_CUMULATIVE_IP_LEN * FISA_FLOW_MAX_AGGR_COUNT) + +/** + * dp_rx_dump_fisa_stats() - Dump fisa stats + * @soc: core txrx main context + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc); + +/** + * dp_fisa_rx() - FISA Rx packet delivery entry function + * @soc: core txrx main context + * @vdev: core txrx vdev + * @nbuf_list: Delivery list of nbufs + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_fisa_rx(struct dp_soc *dp_fisa_rx_hdl, struct dp_vdev *vdev, + qdf_nbuf_t nbuf_list); + +/** + * dp_rx_fisa_flush_by_ctx_id() - FISA Rx flush function to flush + * aggregation at end of NAPI + * @soc: core txrx main context + * @napi_id: Flows which are rxed on the NAPI ID to be flushed + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id); + +/** + * dp_rx_fisa_flush_by_vdev_id() - Flush fisa aggregates per vdev id + * @soc: core txrx main context + * @vdev_id: vdev ID + * + * Return: Success on flushing the flows for the vdev + */ +QDF_STATUS dp_rx_fisa_flush_by_vdev_id(struct dp_soc *soc, uint8_t vdev_id); + +/** + * dp_rx_skip_fisa() - Set flags to skip fisa aggregation + * @cdp_soc: core txrx main context + * @value: allow or skip fisa + * + * Return: None + */ +static inline +void dp_rx_skip_fisa(struct cdp_soc_t *cdp_soc, uint32_t value) +{ + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + + qdf_atomic_set(&soc->skip_fisa_param.skip_fisa, !value); +} + +/** + * dp_set_fisa_disallowed_for_vdev() - Set fisa disallowed flag for vdev + * @cdp_soc: core txrx main context + * @vdev_id: Vdev id + * @rx_ctx_id: rx context id + * @val: value to be set + * + * Return: None + */ +void dp_set_fisa_disallowed_for_vdev(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, + uint8_t rx_ctx_id, uint8_t val); +#else +static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; +} + +void dp_rx_dump_fisa_table(struct dp_soc *soc) +{ +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_fst.c b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_fst.c new file mode 100644 index 0000000000000000000000000000000000000000..f1929a249fc046e028c02a7241f471bf2ff3c95d --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_fst.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include "dp_types.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "cfg_dp.h" +#include "wlan_cfg.h" +#include "dp_types.h" +#include "hal_rx_flow.h" +#include "dp_htt.h" +#include "dp_internal.h" + +#ifdef WLAN_SUPPORT_RX_FISA + +void dp_rx_dump_fisa_table(struct dp_soc *soc) +{ + hal_rx_dump_fse_table(soc->rx_fst->hal_rx_fst); +} + +/** + * dp_rx_flow_send_htt_operation_cmd() - Invalidate FSE cache on FT change + * @pdev: handle to DP pdev + * @fse_op: Cache operation code + * @rx_flow_tuple: flow tuple whose entry has to be invalidated + * + * Return: Success if we successfully send FW HTT command + */ +static QDF_STATUS +dp_rx_flow_send_htt_operation_cmd(struct dp_pdev *pdev, + enum dp_htt_flow_fst_operation fse_op, + struct cdp_rx_flow_tuple_info *rx_flow_tuple) +{ + struct dp_htt_rx_flow_fst_operation fse_op_cmd; + struct cdp_rx_flow_info rx_flow_info; + + rx_flow_info.is_addr_ipv4 = true; + rx_flow_info.op_code = CDP_FLOW_FST_ENTRY_ADD; + qdf_mem_copy(&rx_flow_info.flow_tuple_info, rx_flow_tuple, + sizeof(struct cdp_rx_flow_tuple_info)); + rx_flow_info.fse_metadata = 0xDADA; + fse_op_cmd.pdev_id = pdev->pdev_id; + fse_op_cmd.op_code = fse_op; + fse_op_cmd.rx_flow = &rx_flow_info; + + return dp_htt_rx_flow_fse_operation(pdev, &fse_op_cmd); +} + +/** + * dp_fisa_fse_cache_flush_timer() - FSE cache flush timeout handler + * @arg: SoC handle + * + * Return: None + */ +static void dp_fisa_fse_cache_flush_timer(void *arg) +{ + struct dp_soc *soc = (struct dp_soc *)arg; + struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct cdp_rx_flow_tuple_info rx_flow_tuple_info = { 0 }; + static uint32_t fse_cache_flush_rec_idx; + struct fse_cache_flush_history *fse_cache_flush_rec; + QDF_STATUS status; + + fse_cache_flush_rec = &fisa_hdl->cache_fl_rec[fse_cache_flush_rec_idx % + MAX_FSE_CACHE_FL_HST]; + fse_cache_flush_rec->timestamp = qdf_get_log_timestamp(); + fse_cache_flush_rec->flows_added = + qdf_atomic_read(&fisa_hdl->fse_cache_flush_posted); + fse_cache_flush_rec_idx++; + dp_info("FSE cache flush for %d flows", + fse_cache_flush_rec->flows_added); + + qdf_atomic_set(&fisa_hdl->fse_cache_flush_posted, 0); + status = + dp_rx_flow_send_htt_operation_cmd(soc->pdev_list[0], + DP_HTT_FST_CACHE_INVALIDATE_FULL, + &rx_flow_tuple_info); + if (QDF_IS_STATUS_ERROR(status)) { + dp_err("Failed to send the cache invalidation\n"); + /* + * Not big impact cache entry gets updated later + */ + } +} + +/** + * dp_rx_fst_attach() - Initialize Rx FST and setup necessary parameters + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: Handle to flow search table entry + */ +QDF_STATUS dp_rx_fst_attach(struct dp_soc *soc, struct dp_pdev *pdev) +{ + struct dp_rx_fst *fst; + uint8_t *hash_key; + struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx; + QDF_STATUS status; + + /* Check if it is enabled in the INI */ + if (!wlan_cfg_is_rx_fisa_enabled(cfg)) { + dp_err("RX FISA feature is disabled"); + return QDF_STATUS_E_NOSUPPORT; + } + +#ifdef NOT_YET /* Not required for now */ + /* Check if FW supports */ + if (!wlan_psoc_nif_fw_ext_cap_get((void *)pdev->ctrl_pdev, + WLAN_SOC_CEXT_RX_FSE_SUPPORT)) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "rx fse disabled in FW\n"); + wlan_cfg_set_rx_flow_tag_enabled(cfg, false); + return QDF_STATUS_E_NOSUPPORT; + } +#endif + if (soc->rx_fst) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "RX FST already allocated\n"); + return QDF_STATUS_SUCCESS; + } + + fst = qdf_mem_malloc(sizeof(struct dp_rx_fst)); + if (!fst) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "RX FST allocation failed\n"); + return QDF_STATUS_E_NOMEM; + } + + fst->max_skid_length = wlan_cfg_rx_fst_get_max_search(cfg); + fst->max_entries = wlan_cfg_get_rx_flow_search_table_size(cfg); + hash_key = wlan_cfg_rx_fst_get_hash_key(cfg); + + fst->hash_mask = fst->max_entries - 1; + fst->num_entries = 0; + dp_err("FST setup params FT size %d, hash_mask 0x%x, skid_length %d", + fst->max_entries, fst->hash_mask, fst->max_skid_length); + + fst->base = (uint8_t *)qdf_mem_malloc(DP_RX_GET_SW_FT_ENTRY_SIZE * + fst->max_entries); + + if (!fst->base) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "Rx fst->base allocation failed, #entries:%d\n", + fst->max_entries); + + goto out2; + } + + fst->hal_rx_fst = hal_rx_fst_attach(soc->osdev, + &fst->hal_rx_fst_base_paddr, + fst->max_entries, + fst->max_skid_length, hash_key); + + if (qdf_unlikely(!fst->hal_rx_fst)) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "Rx Hal fst allocation failed, #entries:%d\n", + fst->max_entries); + goto out1; + } + + qdf_spinlock_create(&fst->dp_rx_fst_lock); + + status = qdf_timer_init(soc->osdev, &fst->fse_cache_flush_timer, + dp_fisa_fse_cache_flush_timer, (void *)soc, + QDF_TIMER_TYPE_WAKE_APPS); + if (QDF_IS_STATUS_ERROR(status)) { + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "Failed to init cache_flush_timer\n"); + goto timer_init_fail; + } + + qdf_atomic_init(&fst->fse_cache_flush_posted); + + fst->soc_hdl = soc; + soc->rx_fst = fst; + soc->fisa_enable = true; + qdf_atomic_init(&soc->skip_fisa_param.skip_fisa); + + QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, + "Rx FST attach successful, #entries:%d\n", + fst->max_entries); + + return QDF_STATUS_SUCCESS; + +timer_init_fail: + qdf_spinlock_destroy(&fst->dp_rx_fst_lock); + hal_rx_fst_detach(fst->hal_rx_fst, soc->osdev); +out1: + qdf_mem_free(fst->base); +out2: + qdf_mem_free(fst); + return QDF_STATUS_E_NOMEM; +} + +/** + * dp_rx_flow_send_fst_fw_setup() - Program FST parameters in FW/HW post-attach + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: Success when fst parameters are programmed in FW, error otherwise + */ +QDF_STATUS dp_rx_flow_send_fst_fw_setup(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + struct dp_htt_rx_flow_fst_setup fisa_hw_fst_setup_cmd = {0}; + struct dp_rx_fst *fst = soc->rx_fst; + struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx; + QDF_STATUS status; + + /* mac_id = 0 is used to configure both macs with same FT */ + fisa_hw_fst_setup_cmd.pdev_id = 0; + fisa_hw_fst_setup_cmd.max_entries = fst->max_entries; + fisa_hw_fst_setup_cmd.max_search = fst->max_skid_length; + fisa_hw_fst_setup_cmd.base_addr_lo = fst->hal_rx_fst_base_paddr & + 0xffffffff; + fisa_hw_fst_setup_cmd.base_addr_hi = (fst->hal_rx_fst_base_paddr >> 32); + fisa_hw_fst_setup_cmd.ip_da_sa_prefix = HTT_RX_IPV4_COMPATIBLE_IPV6; + fisa_hw_fst_setup_cmd.hash_key_len = HAL_FST_HASH_KEY_SIZE_BYTES; + fisa_hw_fst_setup_cmd.hash_key = wlan_cfg_rx_fst_get_hash_key(cfg); + + status = dp_htt_rx_flow_fst_setup(pdev, &fisa_hw_fst_setup_cmd); + + return status; +} + +/** + * dp_rx_fst_detach() - De-initialize Rx FST + * @soc: SoC handle + * @pdev: Pdev handle + * + * Return: None + */ +void dp_rx_fst_detach(struct dp_soc *soc, struct dp_pdev *pdev) +{ + struct dp_rx_fst *dp_fst; + + dp_fst = soc->rx_fst; + if (qdf_likely(dp_fst)) { + qdf_timer_sync_cancel(&dp_fst->fse_cache_flush_timer); + hal_rx_fst_detach(dp_fst->hal_rx_fst, soc->osdev); + qdf_mem_free(dp_fst->base); + qdf_spinlock_destroy(&dp_fst->dp_rx_fst_lock); + qdf_mem_free(dp_fst); + } + soc->rx_fst = NULL; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "Rx FST detached\n"); +} +#else /* WLAN_SUPPORT_RX_FISA */ + +#endif /* !WLAN_SUPPORT_RX_FISA */ + diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c index ee457758e84e534777c06b477ad8992f210fed23..6bffa2f9a7a786637c2dfd60a056a514c49d2195 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.c @@ -17,12 +17,14 @@ */ #include +#include "dp_peer.h" +#include "dp_internal.h" #include #include #include /* Timeout in ms to wait for a DP rx thread */ -#define DP_RX_THREAD_WAIT_TIMEOUT 200 +#define DP_RX_THREAD_WAIT_TIMEOUT 1000 #define DP_RX_TM_DEBUG 0 #if DP_RX_TM_DEBUG @@ -102,7 +104,7 @@ static void dp_rx_tm_thread_dump_stats(struct dp_rx_thread *rx_thread) if (!total_queued) return; - dp_info("thread:%u - qlen:%u queued:(total:%u %s) dequeued:%u stack:%u gro_flushes: %u gro_flushes_by_vdev_del: %u rx_flushes: %u max_len:%u invalid(peer:%u vdev:%u rx-handle:%u others:%u)", + dp_info("thread:%u - qlen:%u queued:(total:%u %s) dequeued:%u stack:%u gro_flushes: %u gro_flushes_by_vdev_del: %u rx_flushes: %u max_len:%u invalid(peer:%u vdev:%u rx-handle:%u others:%u enq fail:%u)", rx_thread->id, qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue), total_queued, @@ -116,7 +118,8 @@ static void dp_rx_tm_thread_dump_stats(struct dp_rx_thread *rx_thread) rx_thread->stats.dropped_invalid_peer, rx_thread->stats.dropped_invalid_vdev, rx_thread->stats.dropped_invalid_os_rx_handles, - rx_thread->stats.dropped_others); + rx_thread->stats.dropped_others, + rx_thread->stats.dropped_enq_fail); } QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_hdl) @@ -131,6 +134,83 @@ QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_hdl) return QDF_STATUS_SUCCESS; } +#ifdef FEATURE_ALLOW_PKT_DROPPING +/* + * dp_check_and_update_pending() - Check and Set RX Pending flag + * @tm_handle_cmn - DP thread pointer + * + * Returns: QDF_STATUS_SUCCESS on success or qdf error code on + * failure + */ +static inline +QDF_STATUS dp_check_and_update_pending(struct dp_rx_tm_handle_cmn + *tm_handle_cmn) +{ + struct dp_txrx_handle_cmn *txrx_handle_cmn; + struct dp_rx_tm_handle *rx_tm_hdl = + (struct dp_rx_tm_handle *)tm_handle_cmn; + struct dp_soc *dp_soc; + uint32_t rx_pending_hl_threshold; + uint32_t rx_pending_lo_threshold; + uint32_t nbuf_queued_total = 0; + uint32_t nbuf_dequeued_total = 0; + uint32_t rx_flushed_total = 0; + uint32_t pending = 0; + int i; + + txrx_handle_cmn = + dp_rx_thread_get_txrx_handle(tm_handle_cmn); + if (!txrx_handle_cmn) { + dp_err("invalid txrx_handle_cmn!"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + dp_soc = (struct dp_soc *)dp_txrx_get_soc_from_ext_handle( + txrx_handle_cmn); + if (!dp_soc) { + dp_err("invalid soc!"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + rx_pending_hl_threshold = wlan_cfg_rx_pending_hl_threshold( + dp_soc->wlan_cfg_ctx); + rx_pending_lo_threshold = wlan_cfg_rx_pending_lo_threshold( + dp_soc->wlan_cfg_ctx); + + for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) { + if (likely(rx_tm_hdl->rx_thread[i])) { + nbuf_queued_total += + rx_tm_hdl->rx_thread[i]->stats.nbuf_queued_total; + nbuf_dequeued_total += + rx_tm_hdl->rx_thread[i]->stats.nbuf_dequeued; + rx_flushed_total += + rx_tm_hdl->rx_thread[i]->stats.rx_flushed; + } + } + + if (nbuf_queued_total > (nbuf_dequeued_total + rx_flushed_total)) + pending = nbuf_queued_total - (nbuf_dequeued_total + + rx_flushed_total); + + if (unlikely(pending > rx_pending_hl_threshold)) + qdf_atomic_set(&rx_tm_hdl->allow_dropping, 1); + else if (pending < rx_pending_lo_threshold) + qdf_atomic_set(&rx_tm_hdl->allow_dropping, 0); + + return QDF_STATUS_SUCCESS; +} + +#else +static inline +QDF_STATUS dp_check_and_update_pending(struct dp_rx_tm_handle_cmn + *tm_handle_cmn) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * dp_rx_tm_thread_enqueue() - enqueue nbuf list into rx_thread * @rx_thread - rx_thread in which the nbuf needs to be queued @@ -151,9 +231,11 @@ static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread, qdf_nbuf_t head_ptr, next_ptr_list; uint32_t temp_qlen; uint32_t num_elements_in_nbuf; + uint32_t nbuf_queued; struct dp_rx_tm_handle_cmn *tm_handle_cmn; uint8_t reo_ring_num = QDF_NBUF_CB_RX_CTX_ID(nbuf_list); qdf_wait_queue_head_t *wait_q_ptr; + uint8_t allow_dropping; tm_handle_cmn = rx_thread->rtm_handle_cmn; @@ -172,6 +254,16 @@ static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread, } num_elements_in_nbuf = QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf_list); + nbuf_queued = num_elements_in_nbuf; + + allow_dropping = qdf_atomic_read( + &((struct dp_rx_tm_handle *)tm_handle_cmn)->allow_dropping); + if (unlikely(allow_dropping)) { + qdf_nbuf_list_free(nbuf_list); + rx_thread->stats.dropped_enq_fail += num_elements_in_nbuf; + nbuf_queued = 0; + goto enq_done; + } dp_rx_tm_walk_skb_list(nbuf_list); @@ -191,6 +283,8 @@ static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread, if (!head_ptr) goto enq_done; + QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(head_ptr) = num_elements_in_nbuf; + next_ptr_list = head_ptr->next; if (next_ptr_list) { @@ -207,7 +301,10 @@ static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread, enq_done: temp_qlen = qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue); - rx_thread->stats.nbuf_queued[reo_ring_num] += num_elements_in_nbuf; + rx_thread->stats.nbuf_queued[reo_ring_num] += nbuf_queued; + rx_thread->stats.nbuf_queued_total += nbuf_queued; + + dp_check_and_update_pending(tm_handle_cmn); if (temp_qlen > rx_thread->stats.nbufq_max_len) rx_thread->stats.nbufq_max_len = temp_qlen; @@ -276,41 +373,6 @@ static qdf_nbuf_t dp_rx_tm_thread_dequeue(struct dp_rx_thread *rx_thread) return head; } -/** - * dp_rx_thread_get_nbuf_vdev_handle() - get vdev handle from nbuf - * dequeued from rx thread - * @soc: soc handle - * @pdev: pdev handle - * @rx_thread: rx_thread whose nbuf was dequeued - * @nbuf_list: nbuf list dequeued from rx_thread - * - * Returns: vdev handle on Success, NULL on failure - */ -static struct cdp_vdev * -dp_rx_thread_get_nbuf_vdev_handle(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, - struct dp_rx_thread *rx_thread, - qdf_nbuf_t nbuf_list) -{ - uint32_t num_list_elements = 0; - struct cdp_vdev *vdev; - uint8_t vdev_id; - - vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf_list); - vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id); - if (!vdev) { - num_list_elements = - QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf_list); - rx_thread->stats.dropped_invalid_vdev += - num_list_elements; - dp_err("vdev not found for vdev_id %u!, pkt dropped", - vdev_id); - return NULL; - } - - return vdev; -} - /** * dp_rx_thread_process_nbufq() - process nbuf queue of a thread * @rx_thread - rx_thread whose nbuf queue needs to be processed @@ -320,12 +382,11 @@ dp_rx_thread_get_nbuf_vdev_handle(ol_txrx_soc_handle soc, static int dp_rx_thread_process_nbufq(struct dp_rx_thread *rx_thread) { qdf_nbuf_t nbuf_list; - struct cdp_vdev *vdev; + uint8_t vdev_id; ol_txrx_rx_fp stack_fn; ol_osif_vdev_handle osif_vdev; ol_txrx_soc_handle soc; uint32_t num_list_elements = 0; - struct cdp_pdev *pdev; struct dp_txrx_handle_cmn *txrx_handle_cmn; @@ -333,10 +394,8 @@ static int dp_rx_thread_process_nbufq(struct dp_rx_thread *rx_thread) dp_rx_thread_get_txrx_handle(rx_thread->rtm_handle_cmn); soc = dp_txrx_get_soc_from_ext_handle(txrx_handle_cmn); - pdev = dp_txrx_get_pdev_from_ext_handle(txrx_handle_cmn); - - if (!soc || !pdev) { - dp_err("invalid soc or pdev!"); + if (!soc) { + dp_err("invalid soc!"); QDF_BUG(0); return -EFAULT; } @@ -350,16 +409,11 @@ static int dp_rx_thread_process_nbufq(struct dp_rx_thread *rx_thread) QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf_list); rx_thread->stats.nbuf_dequeued += num_list_elements; - vdev = dp_rx_thread_get_nbuf_vdev_handle(soc, pdev, rx_thread, - nbuf_list); - if (!vdev) { - qdf_nbuf_list_free(nbuf_list); - goto dequeue_rx_thread; - } - cdp_get_os_rx_handles_from_vdev(soc, vdev, &stack_fn, + vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf_list); + cdp_get_os_rx_handles_from_vdev(soc, vdev_id, &stack_fn, &osif_vdev); - dp_debug("rx_thread %pK sending packet %pK to stack", rx_thread, - nbuf_list); + dp_debug("rx_thread %pK sending packet %pK to stack", + rx_thread, nbuf_list); if (!stack_fn || !osif_vdev || QDF_STATUS_SUCCESS != stack_fn(osif_vdev, nbuf_list)) { rx_thread->stats.dropped_invalid_os_rx_handles += @@ -369,8 +423,6 @@ static int dp_rx_thread_process_nbufq(struct dp_rx_thread *rx_thread) rx_thread->stats.nbuf_sent_to_stack += num_list_elements; } - -dequeue_rx_thread: nbuf_list = dp_rx_tm_thread_dequeue(rx_thread); } @@ -469,13 +521,13 @@ static int dp_rx_thread_loop(void *arg) int status; struct dp_rx_tm_handle_cmn *tm_handle_cmn; - tm_handle_cmn = rx_thread->rtm_handle_cmn; - if (!arg) { dp_err("bad Args passed"); return 0; } + tm_handle_cmn = rx_thread->rtm_handle_cmn; + qdf_set_user_nice(qdf_get_current_task(), -1); qdf_set_wake_up_idle(true); @@ -773,6 +825,7 @@ void dp_rx_thread_flush_by_vdev_id(struct dp_rx_thread *rx_thread, } qdf_nbuf_queue_head_unlock(&rx_thread->nbuf_queue); + qdf_event_reset(&rx_thread->vdev_del_event); qdf_set_bit(RX_VDEV_DEL_EVENT, &rx_thread->event_flag); qdf_wake_up_interruptible(&rx_thread->wait_q); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.h b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.h index cd82010c2edece99b845b2a29c858f827712ebb7..f7f8864f74560ba1c12c75fd6c33dcc1124264c4 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_rx_thread.h @@ -40,6 +40,7 @@ struct dp_rx_tm_handle_cmn; /** * struct dp_rx_thread_stats - structure holding stats for DP RX thread * @nbuf_queued: packets queued into the thread per reo ring + * @nbuf_queued_total: packets queued into the thread for all reo rings * @nbuf_dequeued: packets de-queued from the thread * @nbuf_sent_to_stack: packets sent to the stack. some dequeued packets may be * dropped due to no peer or vdev, hence this stat. @@ -50,10 +51,11 @@ struct dp_rx_tm_handle_cmn; * @rx_flushed: packets flushed after vdev delete * @dropped_invalid_peer: packets(nbuf_list) dropped due to no peer * @dropped_others: packets dropped due to other reasons - + * @dropped_enq_fail: packets dropped due to pending queue full */ struct dp_rx_thread_stats { unsigned int nbuf_queued[DP_RX_TM_MAX_REO_RINGS]; + unsigned int nbuf_queued_total; unsigned int nbuf_dequeued; unsigned int nbuf_sent_to_stack; unsigned int gro_flushes; @@ -64,6 +66,7 @@ struct dp_rx_thread_stats { unsigned int dropped_invalid_peer; unsigned int dropped_invalid_os_rx_handles; unsigned int dropped_others; + unsigned int dropped_enq_fail; }; /** @@ -126,12 +129,14 @@ enum dp_rx_thread_state { * @txrx_handle_cmn: opaque txrx handle to get to pdev and soc * @state: state of the rx_threads. All of them should be in the same state. * @rx_thread: array of pointers of type struct dp_rx_thread + * @allow_dropping: flag to indicate frame dropping is enabled */ struct dp_rx_tm_handle { uint8_t num_dp_rx_threads; struct dp_txrx_handle_cmn *txrx_handle_cmn; enum dp_rx_thread_state state; struct dp_rx_thread **rx_thread; + qdf_atomic_t allow_dropping; }; /** diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.c b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.c index 7b7de29f6fd64a2e97a23edae4d1f14b8b525d30..a830ed3796353335c71346b61df413431255c5db 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -18,15 +18,34 @@ #include #include +#include "dp_types.h" +#include #include #include +#include "dp_tx_desc.h" +#include "dp_rx.h" +#include +#include -QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id, struct dp_txrx_config *config) { struct dp_txrx_handle *dp_ext_hdl; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; uint8_t num_dp_rx_threads; + struct dp_pdev *pdev; + + if (qdf_unlikely(!soc)) { + dp_err("soc is NULL"); + return 0; + } + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(cdp_soc_t_to_dp_soc(soc), + pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return 0; + } dp_ext_hdl = qdf_mem_malloc(sizeof(*dp_ext_hdl)); if (!dp_ext_hdl) { @@ -36,7 +55,7 @@ QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, dp_info("dp_txrx_handle allocated"); dp_ext_hdl->soc = soc; - dp_ext_hdl->pdev = pdev; + dp_ext_hdl->pdev = dp_pdev_to_cdp_pdev(pdev); cdp_soc_set_dp_txrx_handle(soc, dp_ext_hdl); qdf_mem_copy(&dp_ext_hdl->config, config, sizeof(*config)); dp_ext_hdl->rx_tm_hdl.txrx_handle_cmn = @@ -73,3 +92,662 @@ QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc) return QDF_STATUS_SUCCESS; } + +#ifdef DP_MEM_PRE_ALLOC + +/* Num elements in REO ring */ +#define REO_DST_RING_SIZE 1024 + +/* Num elements in TCL Data ring */ +#define TCL_DATA_RING_SIZE 3072 + +/* Num elements in WBM2SW ring */ +#define WBM2SW_RELEASE_RING_SIZE 4096 + +/* Num elements in WBM Idle Link */ +#define WBM_IDLE_LINK_RING_SIZE (32 * 1024) + +/* Num TX desc in TX desc pool */ +#define DP_TX_DESC_POOL_SIZE 4096 + +/** + * struct dp_consistent_prealloc - element representing DP pre-alloc memory + * @ring_type: HAL ring type + * @size: size of pre-alloc memory + * @in_use: whether this element is in use (occupied) + * @va_unaligned: Unaligned virtual address + * @va_aligned: aligned virtual address. + * @pa_unaligned: Unaligned physical address. + * @pa_aligned: Aligned physical address. + */ + +struct dp_consistent_prealloc { + enum hal_ring_type ring_type; + uint32_t size; + uint8_t in_use; + void *va_unaligned; + void *va_aligned; + qdf_dma_addr_t pa_unaligned; + qdf_dma_addr_t pa_aligned; +}; + +/** + * struct dp_multi_page_prealloc - element representing DP pre-alloc multiple + pages memory + * @desc_type: source descriptor type for memory allocation + * @element_size: single element size + * @element_num: total number of elements should be allocated + * @in_use: whether this element is in use (occupied) + * @cacheable: coherent memory or cacheable memory + * @pages: multi page information storage + */ +struct dp_multi_page_prealloc { + enum dp_desc_type desc_type; + size_t element_size; + uint16_t element_num; + bool in_use; + bool cacheable; + struct qdf_mem_multi_page_t pages; +}; + +/** + * struct dp_consistent_prealloc_unaligned - element representing DP pre-alloc + unaligned memory + * @ring_type: HAL ring type + * @size: size of pre-alloc memory + * @in_use: whether this element is in use (occupied) + * @va_unaligned: unaligned virtual address + * @pa_unaligned: unaligned physical address + */ +struct dp_consistent_prealloc_unaligned { + enum hal_ring_type ring_type; + uint32_t size; + bool in_use; + void *va_unaligned; + qdf_dma_addr_t pa_unaligned; +}; + +/** + * struct dp_prealloc_context - element representing DP prealloc context memory + * @ctxt_type: DP context type + * @size: size of pre-alloc memory + * @in_use: check if element is being used + * @addr: address of memory allocated + */ +struct dp_prealloc_context { + enum dp_ctxt_type ctxt_type; + uint32_t size; + bool in_use; + void *addr; +}; + +static struct dp_prealloc_context g_dp_context_allocs[] = { + {DP_PDEV_TYPE, (sizeof(struct dp_pdev)), false, NULL}, +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY + /* 4 Rx ring history */ + {DP_RX_RING_HIST_TYPE, sizeof(struct dp_rx_history), false, NULL}, + {DP_RX_RING_HIST_TYPE, sizeof(struct dp_rx_history), false, NULL}, + {DP_RX_RING_HIST_TYPE, sizeof(struct dp_rx_history), false, NULL}, + {DP_RX_RING_HIST_TYPE, sizeof(struct dp_rx_history), false, NULL}, + /* 1 Rx error ring history */ + {DP_RX_ERR_RING_HIST_TYPE, sizeof(struct dp_rx_err_history), + false, NULL}, +#ifndef RX_DEFRAG_DO_NOT_REINJECT + /* 1 Rx reinject ring history */ + {DP_RX_REINJECT_RING_HIST_TYPE, sizeof(struct dp_rx_reinject_history), + false, NULL}, +#endif /* RX_DEFRAG_DO_NOT_REINJECT */ +#endif /* WLAN_FEATURE_DP_RX_RING_HISTORY */ +}; + +static struct dp_consistent_prealloc g_dp_consistent_allocs[] = { + /* 5 REO DST rings */ + {REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + {REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + {REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + {REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + {REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + /* 3 TCL data rings */ + {TCL_DATA, (sizeof(struct tlv_32_hdr) + sizeof(struct tcl_data_cmd)) * TCL_DATA_RING_SIZE, 0, NULL, NULL, 0, 0}, + {TCL_DATA, (sizeof(struct tlv_32_hdr) + sizeof(struct tcl_data_cmd)) * TCL_DATA_RING_SIZE, 0, NULL, NULL, 0, 0}, + {TCL_DATA, (sizeof(struct tlv_32_hdr) + sizeof(struct tcl_data_cmd)) * TCL_DATA_RING_SIZE, 0, NULL, NULL, 0, 0}, + /* 4 WBM2SW rings */ + {WBM2SW_RELEASE, (sizeof(struct wbm_release_ring)) * WBM2SW_RELEASE_RING_SIZE, 0, NULL, NULL, 0, 0}, + {WBM2SW_RELEASE, (sizeof(struct wbm_release_ring)) * WBM2SW_RELEASE_RING_SIZE, 0, NULL, NULL, 0, 0}, + {WBM2SW_RELEASE, (sizeof(struct wbm_release_ring)) * WBM2SW_RELEASE_RING_SIZE, 0, NULL, NULL, 0, 0}, + {WBM2SW_RELEASE, (sizeof(struct wbm_release_ring)) * WBM2SW_RELEASE_RING_SIZE, 0, NULL, 0, 0}, + /* SW2WBM link descriptor return ring */ + {SW2WBM_RELEASE, (sizeof(struct wbm_release_ring)) * WLAN_CFG_WBM_RELEASE_RING_SIZE, 0, NULL, 0, 0}, + /* 1 WBM idle link desc ring */ + {WBM_IDLE_LINK, (sizeof(struct wbm_link_descriptor_ring)) * WBM_IDLE_LINK_RING_SIZE, 0, NULL, NULL, 0, 0}, + /* 2 RXDMA DST ERR rings */ + {RXDMA_DST, (sizeof(struct reo_entrance_ring)) * WLAN_CFG_RXDMA_ERR_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + {RXDMA_DST, (sizeof(struct reo_entrance_ring)) * WLAN_CFG_RXDMA_ERR_DST_RING_SIZE, 0, NULL, NULL, 0, 0}, + /* REFILL ring 0 */ + {RXDMA_BUF, (sizeof(struct wbm_buffer_ring)) * WLAN_CFG_RXDMA_REFILL_RING_SIZE, 0, NULL, NULL, 0, 0}, + +}; + +/* Number of HW link descriptors needed (rounded to power of 2) */ +#define NUM_HW_LINK_DESCS (32 * 1024) + +/* Size in bytes of HW LINK DESC */ +#define HW_LINK_DESC_SIZE 128 + +/* Size in bytes of TX Desc (rounded to power of 2) */ +#define TX_DESC_SIZE 128 + +/* Size in bytes of TX TSO Desc (rounded to power of 2) */ +#define TX_TSO_DESC_SIZE 256 + +/* Size in bytes of TX TSO Num Seg Desc (rounded to power of 2) */ +#define TX_TSO_NUM_SEG_DESC_SIZE 16 + +#define NON_CACHEABLE 0 +#define CACHEABLE 1 + +static struct dp_multi_page_prealloc g_dp_multi_page_allocs[] = { + /* 4 TX DESC pools */ + {DP_TX_DESC_TYPE, TX_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_DESC_TYPE, TX_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_DESC_TYPE, TX_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_DESC_TYPE, TX_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + + /* 4 Tx EXT DESC NON Cacheable pools */ + {DP_TX_EXT_DESC_TYPE, HAL_TX_EXT_DESC_WITH_META_DATA, DP_TX_DESC_POOL_SIZE, 0, NON_CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_TYPE, HAL_TX_EXT_DESC_WITH_META_DATA, DP_TX_DESC_POOL_SIZE, 0, NON_CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_TYPE, HAL_TX_EXT_DESC_WITH_META_DATA, DP_TX_DESC_POOL_SIZE, 0, NON_CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_TYPE, HAL_TX_EXT_DESC_WITH_META_DATA, DP_TX_DESC_POOL_SIZE, 0, NON_CACHEABLE, { 0 } }, + + /* 4 Tx EXT DESC Link Cacheable pools */ + {DP_TX_EXT_DESC_LINK_TYPE, sizeof(struct dp_tx_ext_desc_elem_s), DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_LINK_TYPE, sizeof(struct dp_tx_ext_desc_elem_s), DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_LINK_TYPE, sizeof(struct dp_tx_ext_desc_elem_s), DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_EXT_DESC_LINK_TYPE, sizeof(struct dp_tx_ext_desc_elem_s), DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + + /* 4 TX TSO DESC pools */ + {DP_TX_TSO_DESC_TYPE, TX_TSO_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_DESC_TYPE, TX_TSO_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_DESC_TYPE, TX_TSO_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_DESC_TYPE, TX_TSO_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + + /* 4 TX TSO NUM SEG DESC pools */ + {DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + {DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } }, + + /* DP RX DESCs BUF pools */ + {DP_RX_DESC_BUF_TYPE, sizeof(union dp_rx_desc_list_elem_t), + WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE * WLAN_CFG_RXDMA_REFILL_RING_SIZE, 0, CACHEABLE, { 0 } }, + +#ifndef DISABLE_MON_CONFIG + /* 2 DP RX DESCs Status pools */ + {DP_RX_DESC_STATUS_TYPE, sizeof(union dp_rx_desc_list_elem_t), + WLAN_CFG_RXDMA_MONITOR_STATUS_RING_SIZE + 1, 0, CACHEABLE, { 0 } }, + {DP_RX_DESC_STATUS_TYPE, sizeof(union dp_rx_desc_list_elem_t), + WLAN_CFG_RXDMA_MONITOR_STATUS_RING_SIZE + 1, 0, CACHEABLE, { 0 } }, +#endif + + /* DP HW Link DESCs pools */ + {DP_HW_LINK_DESC_TYPE, HW_LINK_DESC_SIZE, NUM_HW_LINK_DESCS, 0, NON_CACHEABLE, { 0 } }, + +}; + +static struct dp_consistent_prealloc_unaligned + g_dp_consistent_unaligned_allocs[] = { + /* CE-0 */ + {CE_SRC, (sizeof(struct ce_srng_src_desc) * 16 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + /* CE-1 */ + {CE_DST, (sizeof(struct ce_srng_dest_desc) * 512 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + {CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 512 + + CE_DESC_RING_ALIGN), false, NULL, 0}, + /* CE-2 */ + {CE_DST, (sizeof(struct ce_srng_dest_desc) * 32 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + {CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 32 + + CE_DESC_RING_ALIGN), false, NULL, 0}, + /* CE-3 */ + {CE_SRC, (sizeof(struct ce_srng_src_desc) * 32 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + /* CE-4 */ + {CE_SRC, (sizeof(struct ce_srng_src_desc) * 256 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + /* CE-5 */ + {CE_DST, (sizeof(struct ce_srng_dest_desc) * 512 + CE_DESC_RING_ALIGN), + false, NULL, 0}, + {CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 512 + + CE_DESC_RING_ALIGN), false, NULL, 0}, +}; + +void dp_prealloc_deinit(void) +{ + int i; + struct dp_prealloc_context *cp; + struct dp_consistent_prealloc *p; + struct dp_multi_page_prealloc *mp; + struct dp_consistent_prealloc_unaligned *up; + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_allocs); i++) { + p = &g_dp_consistent_allocs[i]; + + if (qdf_unlikely(p->in_use)) + dp_info("i %d: consistent_mem in use while free", i); + + if (p->va_aligned) { + dp_info("i %d: va aligned %pK pa aligned %pK size %d", + i, p->va_aligned, (void *)p->pa_aligned, + p->size); + qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev, + p->size, + p->va_unaligned, + p->pa_unaligned, 0); + qdf_mem_zero(p, sizeof(*p)); + } + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_multi_page_allocs); i++) { + mp = &g_dp_multi_page_allocs[i]; + + if (qdf_unlikely(mp->in_use)) + dp_info("i %d: multi-page mem in use while free", i); + + if (mp->pages.num_pages) { + dp_info("i %d: type %d cacheable_pages %pK " + "dma_pages %pK num_pages %d", + i, mp->desc_type, + mp->pages.cacheable_pages, + mp->pages.dma_pages, + mp->pages.num_pages); + qdf_mem_multi_pages_free(qdf_ctx, &mp->pages, + 0, mp->cacheable); + qdf_mem_zero(mp, sizeof(*mp)); + } + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) { + up = &g_dp_consistent_unaligned_allocs[i]; + + if (qdf_unlikely(up->in_use)) + dp_info("i %d: unaligned mem in use while free", i); + + if (up->va_unaligned) { + dp_info("i %d: va unalign %pK pa unalign %pK size %d", + i, up->va_unaligned, + (void *)up->pa_unaligned, up->size); + qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev, + up->size, + up->va_unaligned, + up->pa_unaligned, 0); + qdf_mem_zero(up, sizeof(*up)); + } + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) { + cp = &g_dp_context_allocs[i]; + if (qdf_unlikely(up->in_use)) + dp_warn("i %d: context in use while free", i); + + if (cp->addr) { + qdf_mem_free(cp->addr); + cp->addr = NULL; + } + } +} + +QDF_STATUS dp_prealloc_init(void) +{ + int i; + struct dp_prealloc_context *cp; + struct dp_consistent_prealloc *p; + struct dp_multi_page_prealloc *mp; + struct dp_consistent_prealloc_unaligned *up; + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + if (!qdf_ctx) { + dp_err("qdf_ctx is NULL"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + /*Context pre-alloc*/ + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) { + cp = &g_dp_context_allocs[i]; + cp->addr = qdf_mem_malloc(cp->size); + + if (qdf_unlikely(!cp->addr)) { + dp_warn("i %d: unable to preallocate %d bytes memory!", + i, cp->size); + break; + } + } + + if (i != QDF_ARRAY_SIZE(g_dp_context_allocs)) { + dp_err("unable to allocate context memory!"); + goto deinit; + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_allocs); i++) { + p = &g_dp_consistent_allocs[i]; + p->in_use = 0; + p->va_aligned = + qdf_aligned_mem_alloc_consistent(qdf_ctx, + &p->size, + &p->va_unaligned, + &p->pa_unaligned, + &p->pa_aligned, + DP_RING_BASE_ALIGN); + if (qdf_unlikely(!p->va_unaligned)) { + dp_warn("i %d: unable to preallocate %d bytes memory!", + i, p->size); + break; + } else { + dp_info("i %d: va aligned %pK pa aligned %pK size %d", i, + p->va_aligned, (void *)p->pa_aligned, p->size); + } + } + + if (i != QDF_ARRAY_SIZE(g_dp_consistent_allocs)) { + dp_info("unable to allocate consistent memory!"); + goto deinit; + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_multi_page_allocs); i++) { + mp = &g_dp_multi_page_allocs[i]; + mp->in_use = false; + qdf_mem_multi_pages_alloc(qdf_ctx, &mp->pages, + mp->element_size, + mp->element_num, + 0, mp->cacheable); + if (qdf_unlikely(!mp->pages.num_pages)) { + dp_warn("i %d: preallocate %d bytes multi-pages failed!", + i, (int)(mp->element_size * mp->element_num)); + break; + } else { + mp->pages.is_mem_prealloc = true; + dp_info("i %d: cacheable_pages %pK dma_pages %pK num_pages %d", + i, mp->pages.cacheable_pages, + mp->pages.dma_pages, + mp->pages.num_pages); + } + } + + if (i != QDF_ARRAY_SIZE(g_dp_multi_page_allocs)) { + dp_info("unable to allocate multi-pages memory!"); + goto deinit; + } + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) { + up = &g_dp_consistent_unaligned_allocs[i]; + up->in_use = 0; + up->va_unaligned = qdf_mem_alloc_consistent(qdf_ctx, + qdf_ctx->dev, + up->size, + &up->pa_unaligned); + if (qdf_unlikely(!up->va_unaligned)) { + dp_warn("i %d: fail to prealloc unaligned %d bytes!", + i, up->size); + break; + } + dp_info("i %d: va unalign %pK pa unalign %pK size %d", + i, up->va_unaligned, + (void *)up->pa_unaligned, up->size); + } + + if (i != QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs)) { + dp_info("unable to allocate unaligned memory!"); + /** + * Only if unaligned memory prealloc fail, is deinit + * necessary for all other DP srng/multi-pages memory? + */ + goto deinit; + } + + return QDF_STATUS_SUCCESS; +deinit: + dp_prealloc_deinit(); + return QDF_STATUS_E_FAILURE; +} + +void *dp_prealloc_get_context_memory(uint32_t ctxt_type) +{ + int i; + struct dp_prealloc_context *cp; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) { + cp = &g_dp_context_allocs[i]; + + if ((ctxt_type == cp->ctxt_type) && !cp->in_use) { + cp->in_use = true; + return cp->addr; + } + } + + return NULL; +} + +QDF_STATUS dp_prealloc_put_context_memory(uint32_t ctxt_type, void *vaddr) +{ + int i; + struct dp_prealloc_context *cp; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_context_allocs); i++) { + cp = &g_dp_context_allocs[i]; + + if ((ctxt_type == cp->ctxt_type) && vaddr == cp->addr) { + qdf_mem_zero(cp->addr, cp->size); + cp->in_use = false; + return QDF_STATUS_SUCCESS; + } + } + + return QDF_STATUS_E_FAILURE; +} + +void *dp_prealloc_get_coherent(uint32_t *size, void **base_vaddr_unaligned, + qdf_dma_addr_t *paddr_unaligned, + qdf_dma_addr_t *paddr_aligned, + uint32_t align, + uint32_t ring_type) +{ + int i; + struct dp_consistent_prealloc *p; + void *va_aligned = NULL; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_allocs); i++) { + p = &g_dp_consistent_allocs[i]; + if (p->ring_type == ring_type && !p->in_use && + p->va_unaligned && *size <= p->size) { + p->in_use = 1; + *base_vaddr_unaligned = p->va_unaligned; + *paddr_unaligned = p->pa_unaligned; + *paddr_aligned = p->pa_aligned; + va_aligned = p->va_aligned; + *size = p->size; + dp_info("index %i -> ring type %s va-aligned %pK", i, + dp_srng_get_str_from_hal_ring_type(ring_type), + va_aligned); + break; + } + } + + return va_aligned; +} + +void dp_prealloc_put_coherent(qdf_size_t size, void *vaddr_unligned, + qdf_dma_addr_t paddr) +{ + int i; + struct dp_consistent_prealloc *p; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_allocs); i++) { + p = &g_dp_consistent_allocs[i]; + if (p->va_unaligned == vaddr_unligned) { + dp_info("index %d, returned", i); + p->in_use = 0; + qdf_mem_zero(p->va_unaligned, p->size); + break; + } + } + + if (i == QDF_ARRAY_SIZE(g_dp_consistent_allocs)) + dp_err("unable to find vaddr %pK", vaddr_unligned); +} + +void dp_prealloc_get_multi_pages(uint32_t desc_type, + size_t element_size, + uint16_t element_num, + struct qdf_mem_multi_page_t *pages, + bool cacheable) +{ + int i; + struct dp_multi_page_prealloc *mp; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_multi_page_allocs); i++) { + mp = &g_dp_multi_page_allocs[i]; + + if (desc_type == mp->desc_type && !mp->in_use && + mp->pages.num_pages && element_size == mp->element_size && + element_num <= mp->element_num) { + mp->in_use = true; + *pages = mp->pages; + + dp_info("i %d: desc_type %d cacheable_pages %pK" + "dma_pages %pK num_pages %d", + i, desc_type, + mp->pages.cacheable_pages, + mp->pages.dma_pages, + mp->pages.num_pages); + break; + } + } +} + +void dp_prealloc_put_multi_pages(uint32_t desc_type, + struct qdf_mem_multi_page_t *pages) +{ + int i; + struct dp_multi_page_prealloc *mp; + bool mp_found = false; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_multi_page_allocs); i++) { + mp = &g_dp_multi_page_allocs[i]; + + if (desc_type == mp->desc_type) { + /* compare different address by cacheable flag */ + mp_found = mp->cacheable ? + (mp->pages.cacheable_pages == + pages->cacheable_pages) : + (mp->pages.dma_pages == pages->dma_pages); + /* find it, put back to prealloc pool */ + if (mp_found) { + dp_info("i %d: desc_type %d returned", + i, desc_type); + mp->in_use = false; + qdf_mem_multi_pages_zero(&mp->pages, + mp->cacheable); + break; + } + } + } + + if (qdf_unlikely(!mp_found)) + dp_warn("Not prealloc pages %pK desc_type %d" + "cacheable_pages %pK dma_pages %pK", + pages, + desc_type, + pages->cacheable_pages, + pages->dma_pages); +} + +void *dp_prealloc_get_consistent_mem_unaligned(size_t size, + qdf_dma_addr_t *base_addr, + uint32_t ring_type) +{ + int i; + struct dp_consistent_prealloc_unaligned *up; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) { + up = &g_dp_consistent_unaligned_allocs[i]; + + if (ring_type == up->ring_type && size == up->size && + up->va_unaligned && !up->in_use) { + up->in_use = true; + *base_addr = up->pa_unaligned; + dp_info("i %d: va unalign %pK pa unalign %pK size %d", + i, up->va_unaligned, + (void *)up->pa_unaligned, up->size); + return up->va_unaligned; + } + } + + return NULL; +} + +void dp_prealloc_put_consistent_mem_unaligned(void *va_unaligned) +{ + int i; + struct dp_consistent_prealloc_unaligned *up; + + for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) { + up = &g_dp_consistent_unaligned_allocs[i]; + + if (va_unaligned == up->va_unaligned) { + dp_info("index %d, returned", i); + up->in_use = false; + qdf_mem_zero(up->va_unaligned, up->size); + break; + } + } + + if (i == QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs)) + dp_err("unable to find vaddr %pK", va_unaligned); +} +#endif + +/** + * dp_rx_tm_get_pending() - get number of frame in thread + * nbuf queue pending + * @soc: ol_txrx_soc_handle object + * + * Return: number of frames + */ +#ifdef FEATURE_WLAN_DP_RX_THREADS +int dp_rx_tm_get_pending(ol_txrx_soc_handle soc) +{ + int i; + int num_pending = 0; + struct dp_rx_thread *rx_thread; + struct dp_txrx_handle *dp_ext_hdl; + struct dp_rx_tm_handle *rx_tm_hdl; + + if (!soc) + return 0; + + dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc); + if (!dp_ext_hdl) + return 0; + + rx_tm_hdl = &dp_ext_hdl->rx_tm_hdl; + + for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) { + rx_thread = rx_tm_hdl->rx_thread[i]; + if (!rx_thread) + continue; + num_pending += qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue); + } + + if (num_pending) + dp_debug("pending frames in thread queue %d", num_pending); + + return num_pending; +} +#else +int dp_rx_tm_get_pending(ol_txrx_soc_handle soc) +{ + return 0; +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.h b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.h index 16d83a6539ce2d1d491d921be14449b7e382b116..fdd3c2f7519d8fa20299f883d1fe41681aeb3e96 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.h +++ b/drivers/staging/qcacld-3.0/core/dp/txrx3.0/dp_txrx.h @@ -94,11 +94,12 @@ dp_txrx_get_pdev_from_ext_handle(struct dp_txrx_handle_cmn *txrx_cmn_hdl) /** * dp_txrx_init() - initialize DP TXRX module * @soc: ol_txrx_soc_handle + * @pdev_id: id of dp pdev handle * @config: configuration for DP TXRX modules * * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure */ -QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, +QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id, struct dp_txrx_config *config); /** @@ -349,8 +350,8 @@ QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask) #else static inline -QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, - struct dp_txrx_config *config) +QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id, + struct dp_txrx_config *config) { return QDF_STATUS_SUCCESS; } @@ -408,4 +409,134 @@ QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask) } #endif /* FEATURE_WLAN_DP_RX_THREADS */ + +#ifdef DP_MEM_PRE_ALLOC +/** + * dp_prealloc_init() - Pre-allocate DP memory + * + * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure + */ +QDF_STATUS dp_prealloc_init(void); + +/** + * dp_prealloc_deinit() - Free pre-alloced DP memory + * + * Return: None + */ +void dp_prealloc_deinit(void); + +/** + * dp_prealloc_get_context_memory() - gets pre-alloc DP context memory from + * global pool + * @ctxt_type: type of DP context + * + * This is done only as part of init happening in a single context. Hence + * no lock is used for protection + * + * Return: Address of context + */ +void *dp_prealloc_get_context_memory(uint32_t ctxt_type); + +/** + * dp_prealloc_put_context_memory() - puts back pre-alloc DP context memory to + * global pool + * @ctxt_type: type of DP context + * @vaddr: address of DP context + * + * This is done only as part of de-init happening in a single context. Hence + * no lock is used for protection + * + * Return: Failure if address not found + */ +QDF_STATUS dp_prealloc_put_context_memory(uint32_t ctxt_type, void *vaddr); + +/** + * dp_prealloc_get_coherent() - gets pre-alloc DP memory + * @size: size of memory needed + * @base_vaddr_unaligned: Unaligned virtual address. + * @paddr_unaligned: Unaligned physical address. + * @paddr_aligned: Aligned physical address. + * @align: Base address alignment. + * @align: alignment needed + * @ring_type: HAL ring type + * + * Return: unaligned virtual address if success or null if memory alloc fails. + */ +void *dp_prealloc_get_coherent(uint32_t *size, void **base_vaddr_unaligned, + qdf_dma_addr_t *paddr_unaligned, + qdf_dma_addr_t *paddr_aligned, + uint32_t align, + uint32_t ring_type); +/** + * dp_prealloc_put_coherent() - puts back pre-alloc DP memory + * @size: size of memory to be returned + * @base_vaddr_unaligned: Unaligned virtual address. + * @paddr_unaligned: Unaligned physical address. + * + * Return: None + */ +void dp_prealloc_put_coherent(qdf_size_t size, void *vaddr_unligned, + qdf_dma_addr_t paddr); + +/** + * dp_prealloc_get_multi_page() - gets pre-alloc DP multi-pages memory + * @src_type: the source that do memory allocation + * @element_size: single element size + * @element_num: total number of elements should be allocated + * @pages: multi page information storage + * @cacheable: coherent memory or cacheable memory + * + * Return: None. + */ +void dp_prealloc_get_multi_pages(uint32_t src_type, + size_t element_size, + uint16_t element_num, + struct qdf_mem_multi_page_t *pages, + bool cacheable); + +/** + * dp_prealloc_put_multi_pages() - puts back pre-alloc DP multi-pages memory + * @src_type: the source that do memory freement + * @pages: multi page information storage + * + * Return: None + */ +void dp_prealloc_put_multi_pages(uint32_t src_type, + struct qdf_mem_multi_page_t *pages); +/** + * dp_prealloc_get_consistent_mem_unaligned() - gets pre-alloc unaligned + consistent memory + * @size: total memory size + * @base_addr: pointer to dma address. + * @ring_type: HAL ring type that requires memory + * + * Return: memory virtual address pointer, NULL if fail + */ +void *dp_prealloc_get_consistent_mem_unaligned(size_t size, + qdf_dma_addr_t *base_addr, + uint32_t ring_type); +/** + * dp_prealloc_put_consistent_mem_unaligned() - puts back pre-alloc unaligned + consistent memory + * @va_unaligned: memory virtual address pointer. + * + * Return: None + */ +void dp_prealloc_put_consistent_mem_unaligned(void *va_unaligned); + +#else +static inline QDF_STATUS dp_prealloc_init(void) { return QDF_STATUS_SUCCESS; } + +static inline void dp_prealloc_deinit(void) { } + +#endif + +/** + * dp_rx_tm_get_pending() - get number of frame in thread + * nbuf queue pending + * @soc: ol_txrx_soc_handle object + * + * Return: number of frames + */ +int dp_rx_tm_get_pending(ol_txrx_soc_handle soc); #endif /* _DP_TXRX_H */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_config.h b/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_config.h index 0fd6445bed571123171ac72e863ac5e66544a75d..d31766b6d6f18b2c3bba01b500da2328e9e2d482 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_config.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_config.h @@ -277,6 +277,66 @@ enum hdd_dot11_mode { 1, \ "Wlan logging enable") +/* + * + * host_log_custom_nl_proto - Host log netlink protocol + * @Min: 0 + * @Max: 32 + * @Default: 2 + * + * This ini is used to set host log netlink protocol. The default + * value is 2 (NETLINK_USERSOCK), customer should avoid selecting the + * netlink protocol that already used on their platform by other + * applications or services. By choosing the non-default value(2), + * Customer need to change the netlink protocol of application receive + * tool(cnss_diag) accordingly. Available values could be: + * + * host_log_custom_nl_proto = 0 - NETLINK_ROUTE, Routing/device hook + * host_log_custom_nl_proto = 1 - NETLINK_UNUSED, Unused number + * host_log_custom_nl_proto = 2 - NETLINK_USERSOCK, Reserved for user + * mode socket protocols + * host_log_custom_nl_proto = 3 - NETLINK_FIREWALL, Unused number, + * formerly ip_queue + * host_log_custom_nl_proto = 4 - NETLINK_SOCK_DIAG, socket monitoring + * host_log_custom_nl_proto = 5 - NETLINK_NFLOG, netfilter/iptables ULOG + * host_log_custom_nl_proto = 6 - NETLINK_XFRM, ipsec + * host_log_custom_nl_proto = 7 - NETLINK_SELINUX, SELinux event + * notifications + * host_log_custom_nl_proto = 8 - NETLINK_ISCSI, Open-iSCSI + * host_log_custom_nl_proto = 9 - NETLINK_AUDIT, auditing + * host_log_custom_nl_proto = 10 - NETLINK_FIB_LOOKUP + * host_log_custom_nl_proto = 11 - NETLINK_CONNECTOR + * host_log_custom_nl_proto = 12 - NETLINK_NETFILTER, netfilter subsystem + * host_log_custom_nl_proto = 13 - NETLINK_IP6_FW + * host_log_custom_nl_proto = 14 - NETLINK_DNRTMSG, DECnet routing messages + * host_log_custom_nl_proto = 15 - NETLINK_KOBJECT_UEVENT, Kernel + * messages to userspace + * host_log_custom_nl_proto = 16 - NETLINK_GENERIC, leave room for + * NETLINK_DM (DM Events) + * host_log_custom_nl_proto = 18 - NETLINK_SCSITRANSPORT, SCSI Transports + * host_log_custom_nl_proto = 19 - NETLINK_ECRYPTFS + * host_log_custom_nl_proto = 20 - NETLINK_RDMA + * host_log_custom_nl_proto = 21 - NETLINK_CRYPTO, Crypto layer + * host_log_custom_nl_proto = 22 - NETLINK_SMC, SMC monitoring + * + * The max value is: MAX_LINKS which is 32 + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_HOST_LOG_CUSTOM_NETLINK_PROTO CFG_INI_UINT( \ + "host_log_custom_nl_proto", \ + 0, \ + 32, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "host log custom netlink protocol") + /* * * wlanLoggingToConsole - Wlan logging to console @@ -293,7 +353,8 @@ enum hdd_dot11_mode { #define CFG_WLAN_LOGGING_SUPPORT_ALL \ CFG(CFG_WLAN_LOGGING_SUPPORT) \ - CFG(CFG_WLAN_LOGGING_CONSOLE_SUPPORT) + CFG(CFG_WLAN_LOGGING_CONSOLE_SUPPORT) \ + CFG(CFG_HOST_LOG_CUSTOM_NETLINK_PROTO) #else #define CFG_WLAN_LOGGING_SUPPORT_ALL #endif @@ -436,6 +497,41 @@ enum hdd_runtime_pm_cfg { #define CFG_ENABLE_RUNTIME_PM_ALL #endif +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI +/* + * + * enable_qmi_stats - enable periodic stats over qmi + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable periodic stats over qmi if DUT is + * in RTPM suspended state to avoid WoW enter/exit for every stats + * request. + * + * 0: Periodic stats over QMI is disabled + * 1: Periodic stats over QMI is enabled + * Related: None + * + * Supported Feature: Power Save + * + * Usage: External + * + * + */ +#define CFG_ENABLE_QMI_STATS CFG_INI_UINT( \ + "enable_qmi_stats", \ + 0, \ + 1, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "This ini is used to enable periodic stats over qmi") +#define CFG_ENABLE_QMI_STATS_ALL \ + CFG(CFG_ENABLE_QMI_STATS) +#else +#define CFG_ENABLE_QMI_STATS_ALL +#endif + /* * * gInformBssRssiRaw - Report rssi in cfg80211_inform_bss_frame @@ -514,12 +610,12 @@ enum hdd_runtime_pm_cfg { /* * - * gOperatingChannel- Default STA operating channel + * def_sta_operating_freq - Default STA operating Freq * @Min: 0 - * @Max: 14 - * @Default: 1 + * @Max: 2484 + * @Default: 2412 * - * This ini is used to specify the default operating channel of a STA during + * This ini is used to specify the default operating frequency of a STA during * initialization. * * Related: None @@ -530,14 +626,13 @@ enum hdd_runtime_pm_cfg { * * */ -#define CFG_OPERATING_CHANNEL CFG_INI_UINT( \ - "gOperatingChannel", \ +#define CFG_OPERATING_FREQUENCY CFG_INI_UINT( \ + "def_sta_operating_freq", \ 0, \ - 14, \ - 1, \ + 2484, \ + 2412, \ CFG_VALUE_OR_DEFAULT, \ - "Default Operating Channel") - + "Default STA Operating Frequency") #ifdef DHCP_SERVER_OFFLOAD #define IPADDR_NUM_ENTRIES (4) #define IPADDR_STRING_LENGTH (16) @@ -865,7 +960,7 @@ struct dhcp_server { /* * * gActionOUIConnect1x1 - Used to specify action OUIs for 1x1 connection - * @Default: 000C43 00 25 42 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C + * @Default: 000C43 00 25 C2 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C 001018 06 02FF009C0000 BC 25 48 * Note: User should strictly add new action OUIs at the end of this * default value. * @@ -873,7 +968,7 @@ struct dhcp_server { * OUI 1 : 000C43 * OUI data Len : 00 * Info Mask : 25 - Check for NSS and Band - * Capabilities: 42 - NSS == 2 && Band == 2G + * Capabilities: C2 - NSS == 2 && Band == 2G || Band == 5G * OUI 2 : 001018 * OUI data Len : 06 * OUI Data : 02FFF02C0000 @@ -912,7 +1007,7 @@ struct dhcp_server { "gActionOUIConnect1x1", \ 0, \ ACTION_OUI_MAX_STR_LEN, \ - "000C43 00 25 42 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C 001018 06 02FF009C0000 BC 25 48", \ + "000C43 00 25 C2 001018 06 02FFF02C0000 BC 25 42 001018 06 02FF040C0000 BC 25 42 00037F 00 35 6C 001018 06 02FF009C0000 BC 25 48", \ "Used to specify action OUIs for 1x1 connection") /* @@ -1177,7 +1272,7 @@ struct dhcp_server { * gActionOUIReconnAssocTimeout=00E04C 00 01 * Explain: 00E04C: OUI * 00: data length is 0 - * 01: infio mask, only OUI present in Info mask + * 01: info mask, only OUI present in Info mask * Note: User should strictly add new action OUIs at the end of this * default value. * Refer to gEnableActionOUI for more detail about the format. @@ -1197,6 +1292,43 @@ struct dhcp_server { "00E04C 00 01", \ "Used to specify action OUIs to reconnect when assoc timeout") +/* + * + * gActionOUIDisableTWT - Used to specify action OUIs to control TWT param + * while joining the candidate AP + * + * This ini is used to specify AP OUIs. Some APs advertise TWT but do not + * follow through when the STA reaches out to them. Thus, TWT will be + * disabled when we receive OUIs of those APs. + * Note: User should strictly add new action OUIs at the end of this + * default value. + * + * Default OUIs: (All values in Hex) + * OUI 1: 001018 + * OUI data Len: 00 + * Info Mask : 01 - only OUI present in Info mask + * + * OUI 2: 000986 + * OUI data Len: 00 + * Info Mask : 01 - only OUI present in Info mask + * + * Refer to gEnableActionOUI for more detail about the format. + * + * Related: gEnableActionOUI + * + * Supported Feature: Action OUIs + * + * Usage: External + * + * + */ +#define CFG_ACTION_OUI_DISABLE_TWT CFG_INI_STRING( \ + "gActionOUIDisableTWT", \ + 0, \ + ACTION_OUI_MAX_STR_LEN, \ + "001018 00 01 000986 00 01", \ + "Used to specify action OUIs to control TWT configuration") + /* End of action oui inis */ #ifdef ENABLE_MTRACE_LOG @@ -1537,6 +1669,7 @@ enum host_log_level { #define CFG_HDD_ALL \ CFG_ENABLE_PACKET_LOG_ALL \ CFG_ENABLE_RUNTIME_PM_ALL \ + CFG_ENABLE_QMI_STATS_ALL \ CFG_VC_MODE_BITMAP_ALL \ CFG_WLAN_AUTO_SHUTDOWN_ALL \ CFG_WLAN_LOGGING_SUPPORT_ALL \ @@ -1551,6 +1684,7 @@ enum host_log_level { CFG(CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA) \ CFG(CFG_ACTION_OUI_SWITCH_TO_11N_MODE) \ CFG(CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT) \ + CFG(CFG_ACTION_OUI_DISABLE_TWT) \ CFG(CFG_ADVERTISE_CONCURRENT_OPERATION) \ CFG(CFG_BUG_ON_REINIT_FAILURE) \ CFG(CFG_DBS_SCAN_SELECTION) \ @@ -1567,7 +1701,7 @@ enum host_log_level { CFG(CFG_INFORM_BSS_RSSI_RAW) \ CFG(CFG_MULTICAST_HOST_FW_MSGS) \ CFG(CFG_NUM_VDEV_ENABLE) \ - CFG(CFG_OPERATING_CHANNEL) \ + CFG(CFG_OPERATING_FREQUENCY) \ CFG(CFG_PRIVATE_WEXT_CONTROL) \ CFG(CFG_PROVISION_INTERFACE_POOL) \ CFG(CFG_TIMER_MULTIPLIER) \ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_dp_cfg.h b/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_dp_cfg.h index 427aa0be1bb5b8dd9153b6807951771fdf06c443..e55996114031569d543e7ee0530e5d8acc96fe93 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_dp_cfg.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/hdd_dp_cfg.h @@ -648,7 +648,7 @@ /* * * gBusLowTputCntThreshold - Threshold count to trigger low Tput - * GRO flush skip + * GRO flush skip * @Min: 0 * @Max: 200 * @Default: 10 @@ -673,8 +673,158 @@ CFG_VALUE_OR_DEFAULT, \ "Threshold to trigger GRO flush skip for low T-put") +/* + * + * gHandleLatencyCriticalClients - Enable the handling of latency critical + * clients in bus bandwidth timer. + * @Default: false + * + * This ini enables the handling of latency critical clients, eg: 11g/a + * clients, when they are running their corresponding peak throughput. + * + * Supported Feature: Latency critical clients in host + * + * Usage: External + * + * + */ +#define CFG_DP_BUS_HANDLE_LATENCY_CRITICAL_CLIENTS \ + CFG_INI_BOOL( \ + "gHandleLatencyCriticalClients", \ + false, \ + "Control to enable latency critical clients") + #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +/* + * + * gDriverDelAckHighThreshold - High Threshold inorder to trigger TCP + * delay ack feature in the host. + * @Min: 0 + * @Max: 70000 + * @Default: 300 + * + * This ini specifies the threshold of RX packets transmitted + * over a period of 100 ms beyond which TCP delay ack can be enabled + * to improve TCP RX throughput requirement. + * + * Supported Feature: Tcp Delayed Ack in the host + * + * Usage: Internal + * + * + */ +#define CFG_DP_DRIVER_TCP_DELACK_HIGH_THRESHOLD \ + CFG_INI_UINT( \ + "gDriverDelAckHighThreshold", \ + 0, \ + 70000, \ + 300, \ + CFG_VALUE_OR_DEFAULT, \ + "TCP delack high threshold") + +/* + * + * gDriverDelAckLowThreshold - Low Threshold inorder to disable TCP + * delay ack feature in the host. + * @Min: 0 + * @Max: 70000 + * @Default: 100 + * + * This ini is used to mention the Low Threshold inorder to disable TCP Del + * Ack feature in the host. + * + * Supported Feature: Tcp Delayed Ack in the host + * + * Usage: Internal + * + * + */ +#define CFG_DP_DRIVER_TCP_DELACK_LOW_THRESHOLD \ + CFG_INI_UINT( \ + "gDriverDelAckLowThreshold", \ + 0, \ + 70000, \ + 100, \ + CFG_VALUE_OR_DEFAULT, \ + "TCP delack low threshold") + +/* + * + * gDriverDelAckTimerValue - Timeout value (ms) to send out all TCP del + * ack frames + * @Min: 1 + * @Max: 15 + * @Default: 3 + * + * This ini specifies the time out value to send out all pending TCP delay + * ACK frames. + * + * Supported Feature: Tcp Delayed Ack in the host + * + * Usage: Internal + * + * + */ +#define CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE \ + CFG_INI_UINT( \ + "gDriverDelAckTimerValue", \ + 1, \ + 15, \ + 3, \ + CFG_VALUE_OR_DEFAULT, \ + "Send out all TCP Del Acks if time out") + +/* + * + * gDriverDelAckPktCount - The maximum number of TCP delay ack frames + * @Min: 0 + * @Max: 50 + * @Default: 20 + * + * This ini specifies the maximum number of TCP delayed ack frames. + * + * Supported Feature: Tcp Delayed Ack in the host + * + * Usage: Internal + * + * + */ +#define CFG_DP_DRIVER_TCP_DELACK_PKT_CNT \ + CFG_INI_UINT( \ + "gDriverDelAckPktCount", \ + 0, \ + 50, \ + 20, \ + CFG_VALUE_OR_DEFAULT, \ + "No of TCP Del ACK count") + +/* + * + * gDriverDelAckEnable - Control to enable Dynamic Configuration of Tcp + * Delayed Ack in the host. + * @Default: true + * + * This ini is used to enable Dynamic Configuration of Tcp Delayed Ack + * in the host. + * + * Related: gDriverDelAckHighThreshold, gDriverDelAckLowThreshold, + * gDriverDelAckPktCount, gDriverDelAckTimerValue + * + * Supported Feature: Tcp Delayed Ack in the host + * + * Usage: Internal + * + * + */ +#define CFG_DP_DRIVER_TCP_DELACK_ENABLE \ + CFG_INI_BOOL( \ + "gDriverDelAckEnable", \ + true, \ + "Enable tcp del ack in the driver") +#endif + /* * * NAPI_CPU_AFFINITY_MASK - CPU mask to affine NAPIs @@ -1130,6 +1280,46 @@ #define CFG_DP_ENABLE_NUD_TRACKING_ALL #endif +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + +#define CFG_DP_HL_BUNDLE_HIGH_TH \ + CFG_INI_UINT( \ + "tx_bundle_high_threashold", \ + 0, \ + 70000, \ + 4330, \ + CFG_VALUE_OR_DEFAULT, \ + "tx bundle high threashold") + +#define CFG_DP_HL_BUNDLE_LOW_TH \ + CFG_INI_UINT( \ + "tx_bundle_low_threashold", \ + 0, \ + 70000, \ + 4000, \ + CFG_VALUE_OR_DEFAULT, \ + "tx bundle low threashold") + +#define CFG_DP_HL_BUNDLE_TIMER_VALUE \ + CFG_INI_UINT( \ + "tx_bundle_timer_in_ms", \ + 10, \ + 10000, \ + 100, \ + CFG_VALUE_OR_DEFAULT, \ + "tx bundle timer value in ms") + +#define CFG_DP_HL_BUNDLE_SIZE \ + CFG_INI_UINT( \ + "tx_bundle_size", \ + 0, \ + 64, \ + 16, \ + CFG_VALUE_OR_DEFAULT, \ + "tx bundle size") + +#endif + /* * * gWmiCreditCount - Credit count for WMI exchange @@ -1185,11 +1375,34 @@ CFG(CFG_DP_TCP_DELACK_THRESHOLD_LOW) \ CFG(CFG_DP_TCP_DELACK_TIMER_COUNT) \ CFG(CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD) \ - CFG(CFG_DP_BUS_LOW_BW_CNT_THRESHOLD) + CFG(CFG_DP_BUS_LOW_BW_CNT_THRESHOLD) \ + CFG(CFG_DP_BUS_HANDLE_LATENCY_CRITICAL_CLIENTS) + #else #define CFG_HDD_DP_BUS_BANDWIDTH #endif +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +#define CFG_DP_DRIVER_TCP_DELACK \ + CFG(CFG_DP_DRIVER_TCP_DELACK_HIGH_THRESHOLD) \ + CFG(CFG_DP_DRIVER_TCP_DELACK_LOW_THRESHOLD) \ + CFG(CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE) \ + CFG(CFG_DP_DRIVER_TCP_DELACK_PKT_CNT) \ + CFG(CFG_DP_DRIVER_TCP_DELACK_ENABLE) +#else +#define CFG_DP_DRIVER_TCP_DELACK +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +#define CFG_DP_HL_BUNDLE \ + CFG(CFG_DP_HL_BUNDLE_HIGH_TH) \ + CFG(CFG_DP_HL_BUNDLE_LOW_TH) \ + CFG(CFG_DP_HL_BUNDLE_TIMER_VALUE) \ + CFG(CFG_DP_HL_BUNDLE_SIZE) +#else +#define CFG_DP_HL_BUNDLE +#endif + #define CFG_HDD_DP_ALL \ CFG(CFG_DP_NAPI_CE_CPU_MASK) \ CFG(CFG_DP_RX_THREAD_CPU_MASK) \ @@ -1209,7 +1422,9 @@ CFG(CFG_DP_HTC_WMI_CREDIT_CNT) \ CFG_DP_ENABLE_FASTPATH_ALL \ CFG_HDD_DP_BUS_BANDWIDTH \ + CFG_DP_DRIVER_TCP_DELACK \ CFG_HDD_DP_LEGACY_TX_FLOW \ CFG_DP_ENABLE_NUD_TRACKING_ALL \ - CFG_DP_CONFIG_DP_TRACE_ALL + CFG_DP_CONFIG_DP_TRACE_ALL \ + CFG_DP_HL_BUNDLE #endif diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/qc_sap_ioctl.h b/drivers/staging/qcacld-3.0/core/hdd/inc/qc_sap_ioctl.h index cdd2164900900385855da79645ecb6a84b759a78..7226536b5a837260b7ee4823ef2dec5f95619028 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/qc_sap_ioctl.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/qc_sap_ioctl.h @@ -226,7 +226,7 @@ enum { QCSAP_PARAM_CHAN_WIDTH, QCSAP_PARAM_SET_TXRX_STATS, QCASAP_SET_11AX_RATE, - QCASAP_SET_PEER_RATE, + QCASAP_SET_PEER_RATE, /* Not Supported */ QCASAP_PARAM_DCM, QCASAP_PARAM_RANGE_EXT, QCSAP_SET_DEFAULT_AMPDU, @@ -236,9 +236,11 @@ enum { QCSAP_SET_BTCOEX_LOW_RSSI_THRESHOLD, }; -int iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); +int iw_get_channel_list_with_cc(struct net_device *dev, + mac_handle_t mac_handle, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); #endif /* __linux__ */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_assoc.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_assoc.h index 0edbb2fa67e5e7b534093f027457f569322ee609..e3e2c72cec123acf19ab3673084bfb0267cd881b 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_assoc.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_assoc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,14 +33,6 @@ #define HDD_TIME_STRING_LEN 24 -/* Preprocessor Definitions and Constants */ -#ifdef FEATURE_WLAN_TDLS -#define HDD_MAX_NUM_TDLS_STA 8 -#define HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN 1 -#else -#define HDD_MAX_NUM_TDLS_STA 0 - -#endif /* Timeout (in ms) for Link to Up before Registering Station */ #define ASSOC_LINKUP_TIMEOUT 60 @@ -141,12 +133,10 @@ struct hdd_conn_flag { * @conn_state: connection state of the NIC * @bssid: BSSID * @SSID: SSID Info - * @sta_id: Station ID * @peer_macaddr:Peer Mac Address of the IBSS Stations * @auth_type: Auth Type * @uc_encrypt_type: Unicast Encryption Type * @mc_encrypt_type: Multicast Encryption Type - * @channel: Operation Channel * @is_authenticated: Remembers authenticated state * @dot11mode: dot11mode * @proxy_arp_service: proxy arp service @@ -154,7 +144,7 @@ struct hdd_conn_flag { * @gtk_installed: gtk installed state * @nss: number of spatial streams negotiated * @rate_flags: rate flags for current connection - * @freq: channel frequency + * @chan_freq: channel frequency * @txrate: txrate structure holds nss & datarate info * @rxrate: rx rate info * @noise: holds noise information @@ -178,12 +168,10 @@ struct hdd_connection_info { eConnectionState conn_state; struct qdf_mac_addr bssid; tCsrSSIDInfo ssid; - uint8_t sta_id[MAX_PEERS]; struct qdf_mac_addr peer_macaddr[MAX_PEERS]; enum csr_akm_type auth_type; eCsrEncryptionType uc_encrypt_type; eCsrEncryptionType mc_encrypt_type; - uint8_t channel; uint8_t is_authenticated; uint32_t dot11mode; uint8_t proxy_arp_service; @@ -191,7 +179,7 @@ struct hdd_connection_info { bool gtk_installed; uint8_t nss; uint32_t rate_flags; - uint32_t freq; + uint32_t chan_freq; struct rate_info txrate; struct rate_info rxrate; int8_t noise; @@ -201,10 +189,14 @@ struct hdd_connection_info { tDot11fIEhs20vendor_ie hs20vendor_ie; struct ieee80211_ht_operation ht_operation; struct ieee80211_vht_operation vht_operation; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) \ + && defined(WLAN_FEATURE_11AX) + struct ieee80211_he_operation *he_operation; + uint32_t he_oper_len; +#endif uint32_t roam_count; int8_t signal; int32_t assoc_status_code; - uint32_t cca; tCsrSSIDInfo last_ssid; enum csr_akm_type last_auth_type; char auth_time[HDD_TIME_STRING_LEN]; @@ -332,7 +324,6 @@ int hdd_set_csr_auth_type(struct hdd_adapter *adapter, * hdd_roam_register_tdlssta() - register new TDLS station * @adapter: pointer to adapter * @peerMac: pointer to peer MAC address - * @staId: station identifier * @qos: Quality of service * * Construct the txrx_desc and register the new STA with the Data Plane. @@ -341,21 +332,9 @@ int hdd_set_csr_auth_type(struct hdd_adapter *adapter, * Return: QDF_STATUS enumeration */ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, - const uint8_t *peerMac, uint16_t staId, - uint8_t qos); + const uint8_t *peerMac, uint8_t qos); #endif -QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter, - uint8_t staId); - -/** - * hdd_perform_roam_set_key_complete() - perform set key complete - * @adapter: pointer to adapter - * - * Return: none - */ -void hdd_perform_roam_set_key_complete(struct hdd_adapter *adapter); - #ifdef FEATURE_WLAN_ESE /** * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results @@ -376,8 +355,17 @@ hdd_indicate_ese_bcn_report_no_results(const struct hdd_adapter *adapter, const uint8_t numBss); #endif /* FEATURE_WLAN_ESE */ +/** + * hdd_change_peer_state() - change peer state + * @adapter: HDD adapter + * @peer_mac_addr: Peer MAC address + * @sta_state: peer state + * @roam_synch_in_progress: roam synch in progress + * + * Return: QDF status + */ QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter, - uint8_t sta_id, + uint8_t *peer_mac_addr, enum ol_txrx_peer_state sta_state, bool roam_synch_in_progress); #ifdef WLAN_FEATURE_ROAM_OFFLOAD @@ -389,24 +377,51 @@ static inline bool hdd_is_roam_sync_in_progress(struct csr_roam_info *roaminfo) } #endif +/** + * hdd_update_dp_vdev_flags() - update datapath vdev flags + * @cbk_data: callback data + * @vdev_id: virtual interface id + * @vdev_param: vdev parameter + * @is_link_up: link state up or down + * + * Return: QDF status + */ QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data, - uint8_t sta_id, + uint8_t vdev_id, uint32_t vdev_param, bool is_link_up); QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter, struct csr_roam_info *roam_info, - uint8_t sta_id, struct bss_description *bss_desc); -bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id, +/** + * hdd_save_peer() - Save peer MAC address in adapter peer table. + * @sta_ctx: pointer to hdd station context + * @peer_mac_addr: mac address of new peer + * + * This information is passed to iwconfig later. The peer that joined + * last is passed as information to iwconfig. + + * Return: true if success, false otherwise + */ +bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, struct qdf_mac_addr *peer_mac_addr); -void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id); + +/** + * hdd_delete_peer() - removes peer from hdd station context peer table + * @sta_ctx: pointer to hdd station context + * @peer_mac_addr: mac address of peer to be deleted + * + * Return: None + */ +void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, + struct qdf_mac_addr *peer_mac_addr); #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter, - const tSirMacAddr bssid, int channel); + const tSirMacAddr bssid, uint32_t ch_freq); /** * hdd_save_gtk_params() - Save GTK offload params * @adapter: HDD adapter @@ -420,7 +435,7 @@ void hdd_save_gtk_params(struct hdd_adapter *adapter, #else static inline QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter, - const tSirMacAddr bssid, int channel) + const tSirMacAddr bssid, uint32_t ch_freq) { return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h index 00658744e402501e803df19c4b87a223fb4fd54e..5647133e2b8bc49e1841b13b32686b2e41bfec0f 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h @@ -47,9 +47,6 @@ struct hdd_context; #define FW_MODULE_LOG_LEVEL_STRING_LENGTH (512) #define TX_SCHED_WRR_PARAMS_NUM (5) -/* Number of items that can be configured */ -#define MAX_CFG_INI_ITEMS 1024 - /* Defines for all of the things we read from the configuration (registry). */ #ifdef CONFIG_DP_TRACE @@ -103,9 +100,6 @@ struct hdd_context; */ struct hdd_config { - /* Bitmap to track what is explicitly configured */ - DECLARE_BITMAP(bExplicitCfg, MAX_CFG_INI_ITEMS); - /* Config parameters */ enum hdd_dot11_mode dot11Mode; @@ -143,6 +137,7 @@ struct hdd_config { /* WLAN Logging */ bool wlan_logging_enable; bool wlan_logging_to_console; + uint8_t host_log_custom_nl_proto; #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ #ifdef FEATURE_WLAN_AUTO_SHUTDOWN @@ -176,8 +171,17 @@ struct hdd_config { uint32_t tcp_delack_timer_count; bool enable_tcp_param_update; uint32_t bus_low_cnt_threshold; + bool enable_latency_crit_clients; #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + bool del_ack_enable; + uint32_t del_ack_threshold_high; + uint32_t del_ack_threshold_low; + uint16_t del_ack_timer_value; + uint16_t del_ack_pkt_count; +#endif + #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL uint32_t tx_flow_low_watermark; uint32_t tx_flow_hi_watermark_offset; @@ -201,12 +205,15 @@ struct hdd_config { uint8_t dp_trace_config[DP_TRACE_CONFIG_STRING_LENGTH]; #endif uint8_t enable_nud_tracking; - uint8_t operating_channel; + uint32_t operating_chan_freq; uint8_t num_vdevs; uint8_t enable_concurrent_sta[CFG_CONCURRENT_IFACE_MAX_LEN]; uint8_t dbs_scan_selection[CFG_DBS_SCAN_PARAM_LENGTH]; #ifdef FEATURE_RUNTIME_PM uint8_t runtime_pm; +#endif +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI + bool is_qmi_stats_enabled; #endif uint8_t inform_bss_rssi_raw; @@ -219,6 +226,13 @@ struct hdd_config { #ifdef WLAN_FEATURE_TSF_PLUS uint8_t tsf_ptp_options; #endif /* WLAN_FEATURE_TSF_PLUS */ + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE + uint32_t pkt_bundle_threshold_high; + uint32_t pkt_bundle_threshold_low; + uint16_t pkt_bundle_timer_value; + uint16_t pkt_bundle_size; +#endif uint32_t dp_proto_event_bitmap; #ifdef SAR_SAFETY_FEATURE @@ -232,6 +246,7 @@ struct hdd_config { bool config_sar_safety_sleep_index; #endif bool get_roam_chan_from_fw; + uint32_t fisa_enable; #ifdef WLAN_FEATURE_PERIODIC_STA_STATS /* Periodicity of logging */ @@ -287,7 +302,36 @@ QDF_STATUS hdd_hex_string_to_u16_array(char *str, uint16_t *int_array, void hdd_cfg_print_global_config(struct hdd_context *hdd_ctx); -QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss); +QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t tx_nss, + uint8_t rx_nss); + +/** + * hdd_get_tx_nss() - Get the number of spatial streams supported by the + * adapter + * + * @adapter: the pointer to adapter + * @tx_nss: the number Tx of spatial streams supported by the adapter + * + * This function is used to get the number of Tx spatial streams supported by + * the adapter. + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_get_tx_nss(struct hdd_adapter *adapter, uint8_t *tx_nss); + +/** + * hdd_get_rx_nss() - Get the number of spatial streams supported by the + * adapter + * + * @adapter: the pointer to adapter + * @rx_nss: the number Rx of spatial streams supported by the adapter + * + * This function is used to get the number of Rx spatial streams supported by + * the adapter. + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_get_rx_nss(struct hdd_adapter *adapter, uint8_t *rx_nss); /** * hdd_dfs_indicate_radar() - Block tx as radar found on the channel @@ -312,7 +356,6 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx); * gRuntimePM=0 * gWlanAutoShutdown = 0 * gEnableSuspend=0 - * gEnablePowerSaveOffload=0 * gEnableWoW=0 * * Return: None diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfr.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfr.h new file mode 100644 index 0000000000000000000000000000000000000000..223b7f11799840ece706a4277cd2fb32107d41a0 --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfr.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC : wlan_hdd_cfr.h + * + * WLAN Host Device Driver cfr capture implementation + * + */ + +#if !defined(_WLAN_HDD_CFR_H) +#define _WLAN_HDD_CFR_H + +#ifdef WLAN_CFR_ENABLE + +#define HDD_INVALID_GROUP_ID 16 +#define ENHANCED_CFR_VERSION 2 + +/** + * wlan_hdd_cfg80211_peer_cfr_capture_cfg() - configure peer cfr capture + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function starts CFR capture + * + * Return: 0 on success and errno on failure + */ +int +wlan_hdd_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + +#define FEATURE_CFR_VENDOR_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV, \ + .doit = wlan_hdd_cfg80211_peer_cfr_capture_cfg \ +}, +#else +#define FEATURE_CFR_VENDOR_COMMANDS +#endif /* WLAN_CFR_ENABLE */ +#endif /* _WLAN_HDD_CFR_H */ + diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_debugfs_mibstat.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_debugfs_mibstat.h new file mode 100644 index 0000000000000000000000000000000000000000..e42236cd3b75f9a555304a5b819d7e67e10af9df --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_debugfs_mibstat.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_debugfs_mibstat.h + * + * WLAN Host Device Driver implementation to update + * debugfs with MIB statistics + */ + +#ifndef _WLAN_HDD_DEBUGFS_MIBSTAT_H +#define _WLAN_HDD_DEBUGFS_MIBSTAT_H + +#define DEBUGFS_MIBSTATS_BUF_SIZE 4096 + +#include + +#if defined(WLAN_FEATURE_MIB_STATS) && defined(WLAN_DEBUGFS) +/** + * hdd_debugfs_process_mib_stats() - Process mib stats from fw + * + * This function is used to store mib stats to global variable mib_stats. + * + * Return: None + */ +void hdd_debugfs_process_mib_stats(struct hdd_adapter *adapter, + struct stats_event *stats); + +/** + * wlan_hdd_create_mib_stats_file() - API to create MIB stats file + * @adapter: interface adapter pointer + * + * Return: 0 on success and errno on failure + */ +int wlan_hdd_create_mib_stats_file(struct hdd_adapter *adapter); + +/** + * wlan_hdd_destroy_mib_stats_lock() - API to destroy MIB stats lock + * + * Return: No return + */ +void wlan_hdd_destroy_mib_stats_lock(void); +#else +static inline int wlan_hdd_create_mib_stats_file(struct hdd_adapter *adapter) +{ + return 0; +} + +static inline void wlan_hdd_destroy_mib_stats_lock(void) +{ +} +#endif +#endif /* #ifndef _WLAN_HDD_DEBUGFS_MIBSTAT_H */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_driver_ops.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_driver_ops.h index 543d37642886d30bdacc3fd3540edfd1f63a1a2c..976f67c55d4a40769a4c966cde350f851e45ec43 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_driver_ops.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_driver_ops.h @@ -137,4 +137,22 @@ int hdd_soc_idle_restart_lock(struct device *dev); */ void hdd_soc_idle_restart_unlock(void); +#ifdef FORCE_WAKE +/** + * hdd_set_hif_init_phase() - Enable/disable the + * init_phase flag + * @hif_ctx: hif opaque handle + * @hal_init_phase: init phase flag + * + * Return: None + */ +void hdd_set_hif_init_phase(struct hif_opaque_softc *hif_ctx, + bool init_phase); +#else +static inline +void hdd_set_hif_init_phase(struct hif_opaque_softc *hif_ctx, + bool init_phase) +{ +} +#endif /* FORCE_WAKE */ #endif /* __WLAN_HDD_DRIVER_OPS_H__ */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_gpio.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..b0c15d81e2a024adbdece797c8758f9d2fc7175f --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_gpio.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_gpio.h + * + * This Header file provide declaration for cfg80211 command handler API + */ + +#ifndef __WLAN_HDD_GPIO_H__ +#define __WLAN_HDD_GPIO_H__ + +#include +#include +#include + +#ifdef WLAN_FEATURE_GPIO_CFG +#include + +#define FEATURE_GPIO_CFG_VENDOR_COMMANDS \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = wlan_hdd_cfg80211_set_gpio_config, \ + vendor_command_policy(wlan_cfg80211_gpio_config_policy, \ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX) \ +}, + +/** + * wlan_hdd_cfg80211_set_gpio_config() - set GPIO config + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data to be passed via vendor interface + * @data_len: Length of the data to be passed + * + * Return: Return the Success or Failure code + */ +int wlan_hdd_cfg80211_set_gpio_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len); +#else +#define FEATURE_GPIO_CFG_VENDOR_COMMANDS +#endif /* WLAN_FEATURE_GPIO_CFG */ +#endif /* __WLAN_CFG80211_GPIO_CFG_H__ */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_hang_event.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_hang_event.h new file mode 100644 index 0000000000000000000000000000000000000000..3376b2ce4b69f592a7989792dacd356d0574bc1d --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_hang_event.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ +#ifndef WLAN_HDD_HANG_EVENT_H +#define WLAN_HDD_HANG_EVENT_H +#include +#include + +#ifdef WLAN_HANG_EVENT +/** + * wlan_hdd_hang_event_notifier_register() - HDD hang event notifier register + * @hdd_ctx: HDD context + * + * This function registers hdd layer notifier for the hang event notifier chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_hdd_hang_event_notifier_register(struct hdd_context *hdd_ctx); +/** + * wlan_hdd_hang_event_notifier_unregister() - HDD hang event notifier + * unregister + * @hdd_ctx: HDD context + * + * This function unregisters hdd layer notifier for the hang event notifier + * chain. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_hdd_hang_event_notifier_unregister(void); +#else +static inline +QDF_STATUS wlan_hdd_hang_event_notifier_register(struct hdd_context *hdd_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +QDF_STATUS wlan_hdd_hang_event_notifier_unregister(void) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h index 4731d6ad1b9949e9e9e0d30176b9c83bb9ed893e..bda8772593a972c371630866134b6ca417e2e359 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -47,9 +48,6 @@ #include #include #include -#ifdef CLD_PM_QOS -#include -#endif #include #include #include @@ -61,6 +59,7 @@ #include #include #include +#include #if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) #include #endif @@ -106,11 +105,19 @@ #include "wma_sar_public_structs.h" #include "wlan_mlme_ucfg_api.h" #include "pld_common.h" +#include #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH #include "qdf_periodic_work.h" #endif +#if defined(CLD_PM_QOS) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#include +#endif + +#include "wlan_hdd_sta_info.h" + /* * Preprocessor definitions and constants */ @@ -141,7 +148,9 @@ struct hdd_apf_context { #endif /* FEATURE_WLAN_APF */ /** Number of Tx Queues */ -#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_HL_NETDEV_FLOW_CONTROL) +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \ + defined(QCA_HL_NETDEV_FLOW_CONTROL) || \ + defined(QCA_LL_PDEV_TX_FLOW_CONTROL) #define NUM_TX_QUEUES 5 #else #define NUM_TX_QUEUES 4 @@ -191,6 +200,11 @@ static inline bool in_compat_syscall(void) { return is_compat_task(); } #define HDD_NUM_NL80211_BANDS ((enum nl80211_band)IEEE80211_NUM_BANDS) #endif +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) +#define HDD_NL80211_BAND_6GHZ NL80211_BAND_6GHZ +#endif + #define TSF_GPIO_PIN_INVALID 255 /** Length of the TX queue for the netdev */ @@ -364,7 +378,6 @@ enum hdd_adapter_flags { #define HDD_MIN_TX_POWER (-100) /* minimum tx power */ #define HDD_MAX_TX_POWER (+100) /* maximum tx power */ -#define HDD_ENABLE_SIFS_BURST_DEFAULT (1) /* If IPA UC data path is enabled, target should reserve extra tx descriptors * for IPA data path. * Then host data path should allow less TX packet pumping in case @@ -426,6 +439,81 @@ enum hdd_auth_key_mgmt { HDD_AUTH_KEY_MGMT_CCKM = BIT(2) }; +/** + * wlan_net_dev_ref_dbgid - Debug IDs to detect net device reference leaks + */ +/* + * New value added to the enum must also be reflected in function + * net_dev_ref_debug_string_from_id() + */ +typedef enum { + NET_DEV_HOLD_ID_RESERVED = 0, + NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS = 1, + NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER = 2, + NET_DEV_HOLD_GET_SAP_OPERATING_BAND = 3, + NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL = 4, + NET_DEV_HOLD_IS_ANY_STA_CONNECTING = 5, + NET_DEV_HOLD_SAP_DESTROY_CTX_ALL = 6, + NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER = 7, + NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO = 8, + NET_DEV_HOLD_SET_RPS_CPU_MASK = 9, + NET_DEV_HOLD_DFS_INDICATE_RADAR = 10, + NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED = 11, + NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS = 12, + NET_DEV_HOLD_STA_DESTROY_CTX_ALL = 13, + NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR = 14, + NET_DEV_HOLD_DEINIT_ALL_ADAPTERS = 15, + NET_DEV_HOLD_STOP_ALL_ADAPTERS = 16, + NET_DEV_HOLD_RESET_ALL_ADAPTERS = 17, + NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN = 18, + NET_DEV_HOLD_START_ALL_ADAPTERS = 19, + NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR = 20, + NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR = 21, + NET_DEV_HOLD_GET_ADAPTER_BY_VDEV = 22, + NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE = 23, + NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME = 24, + NET_DEV_HOLD_GET_ADAPTER = 25, + NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ = 26, + NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS = 27, + NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS = 28, + NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS = 29, + NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER = 30, + NET_DEV_HOLD_CLEAR_RPS_CPU_MASK = 31, + NET_DEV_HOLD_BUS_BW_WORK_HANDLER = 32, + NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT = 33, + NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY = 34, + NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY = 35, + NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP = 36, + NET_DEV_HOLD_INDICATE_MGMT_FRAME = 37, + NET_DEV_HOLD_STATE_INFO_DUMP = 38, + NET_DEV_HOLD_DISABLE_ROAMING = 39, + NET_DEV_HOLD_ENABLE_ROAMING = 40, + NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE = 41, + NET_DEV_HOLD_GET_CON_SAP_ADAPTER = 42, + NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED = 43, + NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS = 44, + NET_DEV_HOLD_DEL_P2P_INTERFACE = 45, + NET_DEV_HOLD_IS_NDP_ALLOWED = 46, + NET_DEV_HOLD_NDI_OPEN = 47, + NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG = 48, + NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY = 49, + NET_DEV_HOLD_SUSPEND_WLAN = 50, + NET_DEV_HOLD_RESUME_WLAN = 51, + NET_DEV_HOLD_SSR_RESTART_SAP = 52, + NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES = 53, + NET_DEV_HOLD_CFG80211_SUSPEND_WLAN = 54, + NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA = 55, + NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP = 56, + NET_DEV_HOLD_CACHE_STATION_STATS_CB = 57, + NET_DEV_HOLD_DISPLAY_TXRX_STATS = 58, + NET_DEV_HOLD_CDS_INCR_ARP_STATS_TX_TGT_DELIVERED = 59, + NET_DEV_HOLD_CDS_INCR_ARP_STATS_TX_TGT_ACKED = 60, + NET_DEV_HOLD_GET_MODE_SPECIFIC_INTERFACE_COUNT = 61, + + /* Keep it at the end */ + NET_DEV_HOLD_ID_MAX +} wlan_net_dev_ref_dbgid; + /** * struct hdd_tx_rx_histogram - structure to keep track of tx and rx packets * received over 100ms intervals @@ -440,6 +528,8 @@ enum hdd_auth_key_mgmt { * @next_tx_level: pld_bus_width_type voting level (high or low) * determined on the basis of tx packets received in the * last 100ms interval + * @is_rx_pm_qos_high Capture rx_pm_qos voting + * @is_tx_pm_qos_high Capture tx_pm_qos voting * @qtime timestamp when the record is added * * The structure keeps track of throughput requirements of wlan driver. @@ -452,8 +542,8 @@ struct hdd_tx_rx_histogram { uint32_t next_vote_level; uint32_t next_rx_level; uint32_t next_tx_level; - bool rx_pm_qos_high; - bool tx_pm_qos_high; + bool is_rx_pm_qos_high; + bool is_tx_pm_qos_high; uint64_t qtime; }; @@ -700,13 +790,13 @@ struct hdd_beacon_data { /** * struct hdd_mon_set_ch_info - Holds monitor mode channel switch params - * @channel: Channel number. + * @freq: Channel frequency. * @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; + uint32_t freq; uint8_t cb_mode; uint32_t channel_width; eCsrPhyMode phy_mode; @@ -746,7 +836,6 @@ struct hdd_station_ctx { struct qdf_mac_addr requested_bssid; struct hdd_connection_info conn_info; struct hdd_connection_info cache_conn_info; - struct hdd_roaming_info roam_info; int ft_carrier_on; int ibss_sta_generation; bool ibss_enc_key_installed; @@ -754,7 +843,6 @@ struct hdd_station_ctx { tSirPeerInfoRspParams ibss_peer_info; bool hdd_reassoc_scenario; int sta_debug_state; - uint8_t broadcast_sta_id; struct hdd_mon_set_ch_info ch_info; bool ap_supports_immediate_power_save; }; @@ -781,6 +869,8 @@ enum bss_state { * When a STA is disassociated userspace thread can wait on this * event. The event will be set when the STA Disassociation * processing in UMAC has completed. + * @qdf_sta_eap_frm_done_event: Event to synchronize P2P GO disassoc + * frame and EAP frame. * @qdf_status: Used to communicate state from other threads to the * userspace thread. */ @@ -789,6 +879,7 @@ struct hdd_hostapd_state { qdf_event_t qdf_event; qdf_event_t qdf_stop_bss_event; qdf_event_t qdf_sta_disassoc_event; + qdf_event_t qdf_sta_eap_frm_done_event; QDF_STATUS qdf_status; }; @@ -827,6 +918,45 @@ struct hdd_rate_info { enum tx_rate_info rate_flags; }; +/** + * struct hdd_mic_info - mic error info in HDD + * @ta_mac_addr: transmitter mac address + * @multicast: Flag for multicast + * @key_id: Key ID + * @tsc: Sequence number + * @vdev_id: vdev id + * + */ +struct hdd_mic_error_info { + struct qdf_mac_addr ta_mac_addr; + bool multicast; + uint8_t key_id; + uint8_t tsc[SIR_CIPHER_SEQ_CTR_SIZE]; + uint16_t vdev_id; +}; + +enum hdd_mic_work_status { + MIC_UNINITIALIZED, + MIC_INITIALIZED, + MIC_SCHEDULED, + MIC_DISABLED +}; + +/** + * struct hdd_mic_work - mic work info in HDD + * @mic_error_work: mic error work + * @status: sattus of mic error work + * @info: Pointer to mic error information + * @lock: lock to synchronixe mic error work + * + */ +struct hdd_mic_work { + qdf_work_t work; + enum hdd_mic_work_status status; + struct hdd_mic_error_info *info; + qdf_spinlock_t lock; +}; + /** * struct hdd_fw_txrx_stats - fw txrx status in HDD * (refer to station_info struct in Kernel) @@ -858,157 +988,6 @@ struct hdd_fw_txrx_stats { struct hdd_rate_info rx_rate; }; -/** - * struct dhcp_phase - Per Peer DHCP Phases - * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or - * DHCP_DELINE message in OFFER phase - * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase - * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase - * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or - * ACK phase (Renewal process) - */ -enum dhcp_phase { - DHCP_PHASE_ACK, - DHCP_PHASE_DISCOVER, - DHCP_PHASE_OFFER, - DHCP_PHASE_REQUEST -}; - -/** - * struct dhcp_nego_status - Per Peer DHCP Negotiation Status - * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated - * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST - * (Renewal process) phase - */ -enum dhcp_nego_status { - DHCP_NEGO_STOP, - DHCP_NEGO_IN_PROGRESS -}; - -/** - * struct hdd_station_info - Per station structure kept in HDD for - * multiple station support for SoftAP - * @in_use: Is the station entry in use? - * @sta_id: Station ID reported back from HAL (through SAP). - * Broadcast uses station ID zero by default. - * @sta_type: Type of station i.e. p2p client or infrastructure station - * @sta_mac: MAC address of the station - * @peer_state: Current Station state so HDD knows how to deal with packet - * queue. Most recent states used to change TLSHIM STA state. - * @is_qos_enabled: Track QoS status of station - * @is_deauth_in_progress: The station entry for which Deauth is in progress - * @nss: Number of spatial streams supported - * @rate_flags: Rate Flags for this connection - * @ecsa_capable: Extended CSA capabilities - * @max_phy_rate: Calcuated maximum phy rate based on mode, nss, mcs etc. - * @tx_packets: The number of frames from host to firmware - * @tx_bytes: Bytes send to current station - * @rx_packets: Packets received from current station - * @rx_bytes: Bytes received from current station - * @last_tx_rx_ts: Last tx/rx timestamp with current station - * @assoc_ts: Current station association timestamp - * @tx_rate: Tx rate with current station reported from F/W - * @rx_rate: Rx rate with current station reported from F/W - * @ampdu: Ampdu enable or not of the station - * @sgi_enable: Short GI enable or not of the station - * @tx_stbc: Tx Space-time block coding enable/disable - * @rx_stbc: Rx Space-time block coding enable/disable - * @ch_width: Channel Width of the connection - * @mode: Mode of the connection - * @max_supp_idx: Max supported rate index of the station - * @max_ext_idx: Max extended supported rate index of the station - * @max_mcs_idx: Max supported mcs index of the station - * @rx_mcs_map: VHT Rx mcs map - * @tx_mcs_map: VHT Tx mcs map - * @freq : Frequency of the current station - * @dot11_mode: 802.11 Mode of the connection - * @ht_present: HT caps present or not in the current station - * @vht_present: VHT caps present or not in the current station - * @ht_caps: HT capabilities of current station - * @vht_caps: VHT capabilities of current station - * @reason_code: Disconnection reason code for current station - * @rssi: RSSI of the current station reported from F/W - * @capability: Capability information of current station - * @support_mode: Max supported mode of a station currently - * connected to sap - * @rx_retry_cnt: Number of rx retries received from current station - * Currently this feature is not supported from FW - * @rx_mc_bc_cnt: Multicast broadcast packet count received from - * current station - * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt - * feature or not, if first bit is 1 it indicates that FW supports this - * feature, if it is 0 it indicates FW doesn't support this feature - * @tx_failed: the number of tx failed frames - * @peer_rssi_per_chain: the average value of RSSI (dbm) per chain - * @tx_retry_succeed: the number of frames retried but successfully transmit - * @rx_last_pkt_rssi: the rssi (dbm) calculate by last packet - * @tx_retry: the number of retried frames from host to firmware - * @tx_retry_exhaust: the number of frames retried but finally failed - * from host to firmware - * @tx_total_fw: the number of all frames from firmware to remote station - * @tx_retry_fw: the number of retried frames from firmware to remote station - * @tx_retry_exhaust_fw: the number of frames retried but finally failed from - * firmware to remote station - * @assoc_req_ies: Assoc request IEs of the peer station - */ -struct hdd_station_info { - bool in_use; - uint8_t sta_id; - eStationType sta_type; - struct qdf_mac_addr sta_mac; - enum ol_txrx_peer_state peer_state; - bool is_qos_enabled; - bool is_deauth_in_progress; - uint8_t nss; - uint32_t rate_flags; - uint8_t ecsa_capable; - uint32_t max_phy_rate; - uint32_t tx_packets; - uint64_t tx_bytes; - uint32_t rx_packets; - uint64_t rx_bytes; - qdf_time_t last_tx_rx_ts; - qdf_time_t assoc_ts; - qdf_time_t disassoc_ts; - uint32_t tx_rate; - uint32_t rx_rate; - bool ampdu; - bool sgi_enable; - bool tx_stbc; - bool rx_stbc; - tSirMacHTChannelWidth ch_width; - uint8_t mode; - uint8_t max_supp_idx; - uint8_t max_ext_idx; - uint8_t max_mcs_idx; - uint8_t rx_mcs_map; - uint8_t tx_mcs_map; - uint32_t freq; - uint8_t dot11_mode; - bool ht_present; - bool vht_present; - struct ieee80211_ht_cap ht_caps; - struct ieee80211_vht_cap vht_caps; - uint32_t reason_code; - int8_t rssi; - enum dhcp_phase dhcp_phase; - enum dhcp_nego_status dhcp_nego_status; - uint16_t capability; - uint8_t support_mode; - uint32_t rx_retry_cnt; - uint32_t rx_mc_bc_cnt; - uint32_t tx_failed; - uint32_t peer_rssi_per_chain[WMI_MAX_CHAINS]; - uint32_t tx_retry_succeed; - uint32_t rx_last_pkt_rssi; - uint32_t tx_retry; - uint32_t tx_retry_exhaust; - uint32_t tx_total_fw; - uint32_t tx_retry_fw; - uint32_t tx_retry_exhaust_fw; - struct wlan_ies assoc_req_ies; -}; - /** * struct hdd_ap_ctx - SAP/P2PGO specific information * @hostapd_state: state control information @@ -1023,7 +1002,7 @@ struct hdd_station_info { * @wep_def_key_idx: WEP default key index * @sap_context: Pointer to context maintained by SAP (opaque to HDD) * @sap_config: SAP configuration - * @operating_channel: channel upon which the SAP is operating + * @operating_chan_freq: channel upon which the SAP is operating * @beacon: Beacon information * @vendor_acs_timer: Timer for ACS * @vendor_acs_timer_initialized: Is @vendor_acs_timer initialized? @@ -1043,7 +1022,7 @@ struct hdd_ap_ctx { uint8_t wep_def_key_idx; struct sap_context *sap_context; struct sap_config sap_config; - uint8_t operating_channel; + uint32_t operating_chan_freq; struct hdd_beacon_data *beacon; qdf_mc_timer_t vendor_acs_timer; bool vendor_acs_timer_initialized; @@ -1103,11 +1082,11 @@ struct hdd_netif_queue_history { /** * struct hdd_chan_change_params - channel related information - * @chan: operating channel + * @chan_freq: operating channel frequency * @chan_params: channel parameters */ struct hdd_chan_change_params { - uint8_t chan; + uint32_t chan_freq; struct ch_params chan_params; }; @@ -1161,16 +1140,46 @@ struct rcpi_info { struct hdd_context; +#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION +/** + * enum qdisc_filter_status - QDISC filter status + * @QDISC_FILTER_RTNL_LOCK_FAIL: rtnl lock acquire failed + * @QDISC_FILTER_PRIO_MATCH: qdisc filter with priority match + * @QDISC_FILTER_PRIO_MISMATCH: no filter match with configured priority + */ +enum qdisc_filter_status { + QDISC_FILTER_RTNL_LOCK_FAIL, + QDISC_FILTER_PRIO_MATCH, + QDISC_FILTER_PRIO_MISMATCH, +}; +#endif + /** * struct hdd_adapter - hdd vdev/net_device context * @vdev: object manager vdev context * @vdev_lock: lock to protect vdev context access * @vdev_id: Unique identifier assigned to the vdev * @event_flags: a bitmap of hdd_adapter_flags - * @latency_level: 0 - normal, 1 - moderate, 2 - low, 3 - ultralow + * @mic_work: mic work information + * @gpio_tsf_sync_work: work to sync send TSF CAP WMI command + * @cache_sta_count: number of currently cached stations * @acs_complete_event: acs complete event + * @latency_level: 0 - normal, 1 - moderate, 2 - low, 3 - ultralow * @last_disconnect_reason: Last disconnected internal reason code * as per enum qca_disconnect_reason_codes + * @connect_req_status: Last disconnected internal status code + * as per enum qca_sta_connect_fail_reason_codes + * @upgrade_udp_qos_threshold: The threshold for user priority upgrade for + any UDP packet. + * @handle_feature_update: Handle feature update only if it is triggered + * by hdd_netdev_feature_update + * @netdev_features_update_work: work for handling the netdev features update + for the adapter. + * @gro_disallowed: Flag to check if GRO is enabled or disable for adapter + * @gro_flushed: Flag to indicate if GRO explicit flush is done or not + * @delete_in_progress: Flag to indicate that the adapter delete is in + * progress, and any operation using rtnl lock inside + * the driver can be avoided/skipped. */ struct hdd_adapter { /* Magic cookie for adapter sanity verification. Note that this @@ -1188,8 +1197,6 @@ struct hdd_adapter { qdf_spinlock_t vdev_lock; uint8_t vdev_id; - void *txrx_vdev; - /** Handle to the network device */ struct net_device *dev; @@ -1219,6 +1226,8 @@ struct hdd_adapter { #ifdef WLAN_NUD_TRACKING struct hdd_nud_tracking_info nud_tracking; #endif + + struct hdd_mic_work mic_work; bool disconnection_in_progress; qdf_mutex_t disconnection_status_lock; unsigned long event_flags; @@ -1245,7 +1254,6 @@ struct hdd_adapter { /* QDF event for session open */ qdf_event_t qdf_session_open_event; - qdf_event_t acs_complete_event; #ifdef FEATURE_MONITOR_MODE_SUPPORT /* QDF event for monitor mode vdev up */ @@ -1278,10 +1286,15 @@ struct hdd_adapter { /** Multiple station supports */ /** Per-station structure */ - spinlock_t sta_info_lock; /* To protect access to station Info */ + + /* TODO: Will be removed as a part of next phase of clean up */ struct hdd_station_info sta_info[WLAN_MAX_STA_COUNT]; struct hdd_station_info cache_sta_info[WLAN_MAX_STA_COUNT]; + /* TODO: _list from name will be removed after clean up */ + struct hdd_sta_info_obj sta_info_list; + struct hdd_sta_info_obj cache_sta_info_list; + qdf_atomic_t cache_sta_count; #ifdef FEATURE_WLAN_WAPI struct hdd_wapi_info wapi_info; @@ -1303,6 +1316,7 @@ struct hdd_adapter { } session; qdf_atomic_t ch_switch_in_progress; + qdf_event_t acs_complete_event; #ifdef WLAN_FEATURE_TSF /* tsf value received from firmware */ @@ -1321,8 +1335,13 @@ struct hdd_adapter { uint64_t last_target_time; /* to store the count of continuous invalid tstamp-pair */ int continuous_error_count; + /* to store the count of continuous capture retry */ + int continuous_cap_retry_count; /* to indicate whether tsf_sync has been initialized */ qdf_atomic_t tsf_sync_ready_flag; +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC + qdf_work_t gpio_tsf_sync_work; +#endif #endif /* WLAN_FEATURE_TSF_PLUS */ #endif @@ -1347,6 +1366,7 @@ struct hdd_adapter { #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH unsigned long prev_rx_packets; unsigned long prev_tx_packets; + unsigned long prev_tx_bytes; uint64_t prev_fwd_tx_packets; uint64_t prev_fwd_rx_packets; #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ @@ -1370,6 +1390,7 @@ struct hdd_adapter { bool is_link_layer_stats_set; #endif uint8_t link_status; + uint8_t upgrade_udp_qos_threshold; /* variable for temperature in Celsius */ int temperature; @@ -1395,10 +1416,10 @@ struct hdd_adapter { /* debugfs entry */ struct dentry *debugfs_phy; /* - * The pre cac channel is saved here and will be used when the SAP's - * channel needs to be moved from the existing 2.4GHz channel. + * The pre cac channel frequency is saved here and will be used when + * the SAP's channel needs to be moved from the existing 2.4GHz channel. */ - uint8_t pre_cac_chan; + uint32_t pre_cac_freq; /* * Indicate if HO fails during disconnect so that @@ -1417,7 +1438,7 @@ struct hdd_adapter { uint32_t track_src_port; uint32_t track_dest_port; uint32_t track_dest_ipv4; - uint32_t mon_chan; + uint32_t mon_chan_freq; uint32_t mon_bandwidth; uint16_t latency_level; #ifdef FEATURE_MONITOR_MODE_SUPPORT @@ -1436,8 +1457,12 @@ struct hdd_adapter { #ifdef WLAN_FEATURE_MOTION_DETECTION bool motion_detection_mode; + bool motion_det_cfg; + bool motion_det_in_progress; + uint32_t motion_det_baseline_value; #endif /* WLAN_FEATURE_MOTION_DETECTION */ enum qca_disconnect_reason_codes last_disconnect_reason; + enum wlan_status_code connect_req_status; #ifdef WLAN_FEATURE_PERIODIC_STA_STATS /* Indicate whether to display sta periodic stats */ @@ -1447,6 +1472,18 @@ struct hdd_adapter { qdf_mutex_t sta_periodic_stats_lock; #endif /* WLAN_FEATURE_PERIODIC_STA_STATS */ qdf_event_t peer_cleanup_done; +#ifdef FEATURE_OEM_DATA + bool oem_data_in_progress; + void *cookie; + bool response_expected; +#endif + bool handle_feature_update; + + qdf_work_t netdev_features_update_work; + qdf_atomic_t gro_disallowed; + uint8_t gro_flushed[DP_MAX_RX_THREADS]; + bool delete_in_progress; + qdf_atomic_t net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]; }; #define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station) @@ -1564,11 +1601,11 @@ enum driver_modules_status { /** * struct acs_dfs_policy - Define ACS policies * @acs_dfs_mode: Dfs mode enabled/disabled. - * @acs_channel: pre defined channel to avoid ACS. + * @acs_chan_freq: pre defined channel frequency to avoid ACS. */ struct acs_dfs_policy { enum dfs_mode acs_dfs_mode; - uint8_t acs_channel; + uint32_t acs_chan_freq; }; /** @@ -1628,10 +1665,12 @@ enum hdd_sta_smps_param { * enum RX_OFFLOAD - Receive offload modes * @CFG_LRO_ENABLED: Large Rx offload * @CFG_GRO_ENABLED: Generic Rx Offload + * @CFG_DYNAMIC_GRO_ENABLED: Dynamic GRO enabled */ enum RX_OFFLOAD { CFG_LRO_ENABLED = 1, CFG_GRO_ENABLED, + CFG_DYNAMIC_GRO_ENABLED, }; /* One per STA: 1 for BCMC_STA_ID, 1 for each SAP_SELF_STA_ID, @@ -1704,17 +1743,65 @@ struct hdd_fw_ver_info { uint32_t crmid; }; +/** + * The logic for get current index of history is dependent on this + * value being power of 2. + */ +#define WLAN_HDD_ADAPTER_OPS_HISTORY_MAX 4 +QDF_COMPILE_TIME_ASSERT(adapter_ops_history_size, + (WLAN_HDD_ADAPTER_OPS_HISTORY_MAX & + (WLAN_HDD_ADAPTER_OPS_HISTORY_MAX - 1)) == 0); + +/** + * enum hdd_adapter_ops_event - events for adapter ops history + * @WLAN_HDD_ADAPTER_OPS_WORK_POST: adapter ops work posted + * @WLAN_HDD_ADAPTER_OPS_WORK_SCHED: adapter ops work scheduled + */ +enum hdd_adapter_ops_event { + WLAN_HDD_ADAPTER_OPS_WORK_POST, + WLAN_HDD_ADAPTER_OPS_WORK_SCHED, +}; + +/** + * struct hdd_adapter_ops_record - record of adapter ops history + * @timestamp: time of the occurence of event + * @event: event + * @vdev_id: vdev id corresponding to the event + */ +struct hdd_adapter_ops_record { + uint64_t timestamp; + enum hdd_adapter_ops_event event; + int vdev_id; +}; + +/** + * struct hdd_adapter_ops_history - history of adapter ops + * @index: index to store the next event + * @entry: array of events + */ +struct hdd_adapter_ops_history { + qdf_atomic_t index; + struct hdd_adapter_ops_record entry[WLAN_HDD_ADAPTER_OPS_HISTORY_MAX]; +}; + /** * struct hdd_context - hdd shared driver and psoc/device context * @psoc: object manager psoc context * @pdev: object manager pdev context * @iftype_data_2g: Interface data for 2g band * @iftype_data_5g: Interface data for 5g band + * @num_latency_critical_clients: Number of latency critical clients connected * @bus_bw_work: work for periodically computing DDR bus bandwidth requirements * @g_event_flags: a bitmap of hdd_driver_flags * @psoc_idle_timeout_work: delayed work for psoc idle shutdown * @dynamic_nss_chains_support: Per vdev dynamic nss chains update capability * @sar_cmd_params: SAR command params to be configured to the FW + * @rx_aggregation: rx aggregation enable or disable state + * @gro_force_flush: gro force flushed indication flag + * @tc_based_dyn_gro: TC based dynamic GRO enable/disable flag + * @tc_ingress_prio: TC ingress priority + * @adapter_ops_wq: High priority workqueue for handling adapter operations + * @is_dual_mac_cfg_updated: indicate whether dual mac cfg has been updated */ struct hdd_context { struct wlan_objmgr_psoc *psoc; @@ -1724,8 +1811,6 @@ struct hdd_context { qdf_spinlock_t hdd_adapter_lock; qdf_list_t hdd_adapters; /* List of adapters */ - struct hdd_adapter *sta_to_adapter[HDD_MAX_ADAPTERS]; - /** Pointer for firmware image data */ const struct firmware *fw; @@ -1742,16 +1827,26 @@ struct hdd_context { struct ieee80211_channel *channels_2ghz; struct ieee80211_channel *channels_5ghz; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if (defined(CONFIG_BAND_6GHZ) && defined(CFG80211_6GHZ_BAND_SUPPORTED)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) struct ieee80211_sband_iftype_data *iftype_data_2g; struct ieee80211_sband_iftype_data *iftype_data_5g; #endif +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) + + struct ieee80211_sband_iftype_data *iftype_data_6g; +#endif /* Completion variable to indicate Mc Thread Suspended */ struct completion mc_sus_event_var; bool is_scheduler_suspended; +#ifdef WLAN_FEATURE_PKT_CAPTURE + bool is_ol_mon_thread_suspended; +#endif + #ifdef QCA_CONFIG_SMP bool is_ol_rx_thread_suspended; #endif @@ -1772,6 +1867,7 @@ struct hdd_context { int32_t oem_pid; #endif + qdf_atomic_t num_latency_critical_clients; /** Concurrency Parameters*/ uint32_t concurrency_mode; @@ -1793,7 +1889,9 @@ struct hdd_context { int cur_rx_level; uint64_t prev_no_rx_offload_pkts; uint64_t prev_rx_offload_pkts; + /* Count of non TSO packets in previous bus bw delta time */ uint64_t prev_no_tx_offload_pkts; + /* Count of TSO packets in previous bus bw delta time */ uint64_t prev_tx_offload_pkts; int cur_tx_level; uint64_t prev_tx; @@ -1840,7 +1938,7 @@ struct hdd_context { #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE qdf_mc_timer_t skip_acs_scan_timer; uint8_t skip_acs_scan_status; - uint8_t *last_acs_channel_list; + uint32_t *last_acs_freq_list; uint8_t num_of_channels; qdf_spinlock_t acs_skip_lock; #endif @@ -2007,7 +2105,6 @@ struct hdd_context { unsigned long derived_intf_addr_mask; struct sar_limit_cmd_params *sar_cmd_params; - #ifdef SAR_SAFETY_FEATURE qdf_mc_timer_t sar_safety_timer; qdf_mc_timer_t sar_safety_unsolicited_timer; @@ -2015,30 +2112,43 @@ struct hdd_context { qdf_atomic_t sar_safety_req_resp_event_in_progress; #endif -#ifdef CLD_PM_QOS - struct pm_qos_request pm_qos_req; -#endif qdf_time_t runtime_resume_start_time_stamp; qdf_time_t runtime_suspend_done_time_stamp; +#if defined(CLD_PM_QOS) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) + struct pm_qos_request pm_qos_req; +#endif +#ifdef WLAN_FEATURE_PKT_CAPTURE + /* enable packet capture support */ + bool enable_pkt_capture_support; + /* value for packet capturte mode */ + uint8_t val_pkt_capture_mode; +#endif bool roam_ch_from_fw_supported; + struct { + qdf_atomic_t rx_aggregation; + uint8_t gro_force_flush[DP_MAX_RX_THREADS]; + bool tc_based_dyn_gro; + uint32_t tc_ingress_prio; + } dp_agg_param; #ifdef FW_THERMAL_THROTTLE_SUPPORT uint8_t dutycycle_off_percent; #endif + + qdf_workqueue_t *adapter_ops_wq; + struct hdd_adapter_ops_history adapter_ops_history; + bool is_dual_mac_cfg_updated; }; /** * struct hdd_vendor_acs_chan_params - vendor acs channel parameters - * @channel_count: channel count - * @channel_list: pointer to channel list * @pcl_count: pcl list count - * @vendor_pcl_list: pointer to pcl list + * @vendor_pcl_list: pointer to pcl frequency (MHz) list * @vendor_weight_list: pointer to pcl weight list */ struct hdd_vendor_acs_chan_params { - uint32_t channel_count; - uint8_t *channel_list; uint32_t pcl_count; - uint8_t *vendor_pcl_list; + uint32_t *vendor_pcl_list; uint8_t *vendor_weight_list; }; @@ -2055,18 +2165,18 @@ struct hdd_external_acs_timer_context { /** * struct hdd_vendor_chan_info - vendor channel info * @band: channel operating band - * @pri_ch: primary channel - * @ht_sec_ch: secondary channel - * @vht_seg0_center_ch: segment0 for vht - * @vht_seg1_center_ch: vht segment 1 + * @pri_chan_freq: primary channel freq in MHz + * @ht_sec_chan_freq: secondary channel freq in MHz + * @vht_seg0_center_chan_freq: segment0 for vht in MHz + * @vht_seg1_center_chan_freq: vht segment 1 in MHz * @chan_width: channel width */ struct hdd_vendor_chan_info { uint8_t band; - uint8_t pri_ch; - uint8_t ht_sec_ch; - uint8_t vht_seg0_center_ch; - uint8_t vht_seg1_center_ch; + uint32_t pri_chan_freq; + uint32_t ht_sec_chan_freq; + uint32_t vht_seg0_center_chan_freq; + uint32_t vht_seg1_center_chan_freq; uint8_t chan_width; }; @@ -2102,9 +2212,63 @@ struct hdd_channel_info { * Function declarations and documentation */ +/** + * wlan_hdd_history_get_next_index() - get next index to store the history + entry + * @curr_idx: current index + * @max_entries: max entries in the history + * + * Returns: The index at which record is to be stored in history + */ +static inline uint32_t wlan_hdd_history_get_next_index(qdf_atomic_t *curr_idx, + uint32_t max_entries) +{ + uint32_t idx = qdf_atomic_inc_return(curr_idx); + + return idx & (max_entries - 1); +} + +/** + * hdd_adapter_ops_record_event() - record an entry in the adapter ops history + * @hdd_ctx: pointer to hdd context + * @event: event + * @vdev_id: vdev id corresponding to event + * + * Returns: None + */ +static inline void +hdd_adapter_ops_record_event(struct hdd_context *hdd_ctx, + enum hdd_adapter_ops_event event, + int vdev_id) +{ + struct hdd_adapter_ops_history *adapter_hist; + struct hdd_adapter_ops_record *record; + uint32_t idx; + + adapter_hist = &hdd_ctx->adapter_ops_history; + + idx = wlan_hdd_history_get_next_index(&adapter_hist->index, + WLAN_HDD_ADAPTER_OPS_HISTORY_MAX); + + record = &adapter_hist->entry[idx]; + record->event = event; + record->vdev_id = vdev_id; + record->timestamp = qdf_get_log_timestamp(); +} + +/** + * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo + * @adapter: HDD adapter + * @chan_freq: Channel frequency + * @chan_bw: Bandwidth + * + * Checks if the given bandwidth is valid for the given channel number. + * + * Return: 0 for success, non-zero for failure + */ int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, - uint32_t chan_number, - enum phy_ch_width chan_bw); + qdf_freq_t chan_freq, + enum phy_ch_width chan_bw); /** * hdd_get_front_adapter() - Get the first adapter from the adapter list @@ -2234,37 +2398,58 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context); /** - * hdd_for_each_adapter - adapter iterator macro - * @hdd_ctx: the global HDD context - * @adapter: an hdd_adapter pointer to use as a cursor + * hdd_adapter_dev_hold_debug - Debug API to call dev_hold + * @adapter: hdd_adapter pointer + * @dbgid: Debug ID corresponding to API that is requesting the dev_hold + * + * Return: none */ -#define hdd_for_each_adapter(hdd_ctx, adapter) \ - for (hdd_get_front_adapter(hdd_ctx, &adapter); \ - adapter; \ - hdd_get_next_adapter(hdd_ctx, adapter, &adapter)) +void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, + wlan_net_dev_ref_dbgid dbgid); /** - * __hdd_take_ref_and_fetch_front_adapter - Helper macro to lock, fetch front - * adapter, take ref and unlock. + * hdd_adapter_dev_put_debug - Debug API to call dev_put + * @adapter: hdd_adapter pointer + * @dbgid: Debug ID corresponding to API that is requesting the dev_put + * + * Return: none + */ +void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, + wlan_net_dev_ref_dbgid dbgid); + +/** + * __hdd_take_ref_and_fetch_front_adapter_safe - Helper macro to lock, fetch + * front and next adapters, take ref and unlock. * @hdd_ctx: the global HDD context * @adapter: an hdd_adapter pointer to use as a cursor + * @next_adapter: hdd_adapter pointer to next adapter + * @dbgid: debug ID to detect reference leaks */ -#define __hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter) \ +#define __hdd_take_ref_and_fetch_front_adapter_safe(hdd_ctx, adapter, \ + next_adapter, dbgid) \ qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \ hdd_get_front_adapter_no_lock(hdd_ctx, &adapter), \ - (adapter) ? dev_hold(adapter->dev) : (false), \ + (adapter) ? hdd_adapter_dev_hold_debug(adapter, dbgid) : (false), \ + hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &next_adapter), \ + (next_adapter) ? hdd_adapter_dev_hold_debug(next_adapter, dbgid) : \ + (false), \ qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock) /** - * __hdd_take_ref_and_fetch_next_adapter - Helper macro to lock, fetch next + * __hdd_take_ref_and_fetch_next_adapter_safe - Helper macro to lock, fetch next * adapter, take ref and unlock. * @hdd_ctx: the global HDD context - * @adapter: an hdd_adapter pointer to use as a cursor + * @adapter: hdd_adapter pointer to use as a cursor + * @next_adapter: hdd_adapter pointer to next adapter + * @dbgid: debug ID to detect reference leaks */ -#define __hdd_take_ref_and_fetch_next_adapter(hdd_ctx, adapter) \ +#define __hdd_take_ref_and_fetch_next_adapter_safe(hdd_ctx, adapter, \ + next_adapter, dbgid) \ qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \ - hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter), \ - (adapter) ? dev_hold(adapter->dev) : (false), \ + adapter = next_adapter, \ + hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &next_adapter), \ + (next_adapter) ? hdd_adapter_dev_hold_debug(next_adapter, dbgid) : \ + (false), \ qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock) /** @@ -2274,30 +2459,41 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, #define __hdd_is_adapter_valid(_adapter) !!_adapter /** - * hdd_for_each_adapter_dev_held - Adapter iterator with dev_hold called + * hdd_for_each_adapter_dev_held_safe - Adapter iterator with dev_hold called + * in a delete safe manner * @hdd_ctx: the global HDD context * @adapter: an hdd_adapter pointer to use as a cursor + * @next_adapter: hdd_adapter pointer to the next adapter * * This iterator will take the reference of the netdev associated with the - * given adapter so as to prevent it from being removed in other context. - * If the control goes inside the loop body then the dev_hold has been invoked. + * given adapter so as to prevent it from being removed in other context. It + * also takes the reference of the next adapter if exist. This avoids infinite + * loop due to deletion of the adapter list entry inside the loop. Deletion of + * list entry will make the list entry to point to self. If the control goes + * inside the loop body then the dev_hold has been invoked. * * ***** NOTE ***** - * Before the end of each iteration, dev_put(adapter->dev) must be - * called. Not calling this will keep hold of a reference, thus preventing - * unregister of the netdevice. + * Before the end of each iteration, hdd_adapter_dev_put_debug(adapter, dbgid) + * must be called. Not calling this will keep hold of a reference, thus + * preventing unregister of the netdevice. If the loop is terminated in + * between with return/goto/break statements, + * hdd_adapter_dev_put_debug(next_adapter, dbgid) must be done along with + * hdd_adapter_dev_put_debug(adapter, dbgid) before termination of the loop. * * Usage example: - * hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { - * - * - * dev_put(adapter->dev) - * } - */ -#define hdd_for_each_adapter_dev_held(hdd_ctx, adapter) \ - for (__hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter); \ + * hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, dbgid) { + * + * + * hdd_adapter_dev_put_debug(adapter, dbgid) + * } + */ +#define hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, \ + dbgid) \ + for (__hdd_take_ref_and_fetch_front_adapter_safe(hdd_ctx, adapter, \ + next_adapter, dbgid); \ __hdd_is_adapter_valid(adapter); \ - __hdd_take_ref_and_fetch_next_adapter(hdd_ctx, adapter)) + __hdd_take_ref_and_fetch_next_adapter_safe(hdd_ctx, adapter, \ + next_adapter, dbgid)) /** * wlan_hdd_get_adapter_by_vdev_id_from_objmgr() - Fetch adapter from objmgr @@ -2394,7 +2590,7 @@ struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, * * Return: home channel if connected/started or invalid channel 0 */ -uint8_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter); +uint32_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter); /* * hdd_get_adapter_by_rand_macaddr() - find Random mac adapter @@ -2422,8 +2618,16 @@ hdd_get_adapter_by_rand_macaddr(struct hdd_context *hdd_ctx, */ bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter); -int hdd_vdev_create(struct hdd_adapter *adapter, - csr_roam_complete_cb callback, void *ctx); +/** + * hdd_vdev_create() - Create the vdev in the firmware + * @adapter: hdd adapter + * + * This function will create the vdev in the firmware + * + * Return: 0 when the vdev create is sent to firmware or -EINVAL when + * there is a failure to send the command. + */ +int hdd_vdev_create(struct hdd_adapter *adapter); int hdd_vdev_destroy(struct hdd_adapter *adapter); int hdd_vdev_ready(struct hdd_adapter *adapter); @@ -2462,8 +2666,24 @@ uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx, enum QDF_OPMODE interface_type); void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, uint8_t *releaseAddr); -uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx, - enum QDF_OPMODE mode); + +/** + * hdd_get_operating_chan_freq() - return operating channel of the device mode + * @hdd_ctx: Pointer to the HDD context. + * @mode: Device mode for which operating channel is required. + * Supported modes: + * QDF_STA_MODE, + * QDF_P2P_CLIENT_MODE, + * QDF_SAP_MODE, + * QDF_P2P_GO_MODE. + * + * This API returns the operating channel of the requested device mode + * + * Return: channel frequency, or + * 0 if the requested device mode is not found. + */ +uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, + enum QDF_OPMODE mode); void hdd_set_conparam(int32_t con_param); enum QDF_GLOBAL_MODE hdd_get_conparam(void); @@ -2486,7 +2706,26 @@ struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx); void hdd_allow_suspend(uint32_t reason); void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason); +#ifdef QCA_IBSS_SUPPORT +/** + * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA. + * @struct hdd_adapter Hdd adapter. + * + * This function sets the IBSS power save config parameters to WMA + * which will send it to firmware if FW supports IBSS power save + * before vdev start. + * + * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE + * on failure. + */ QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter); +#else +static inline QDF_STATUS +hdd_set_ibss_power_save_params(struct hdd_adapter *adapter) +{ + return QDF_STATUS_SUCCESS; +} +#endif /** * wlan_hdd_validate_context() - check the HDD context @@ -2554,6 +2793,63 @@ bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx); QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, const char *func); +/** + * hdd_is_any_adapter_connected() - Check if any adapter is in connected state + * @hdd_ctx: the global hdd context + * + * Returns: true, if any of the adapters is in connected state, + * false, if none of the adapters is in connected state. + */ +bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx); + +/** + * hdd_add_latency_critical_client() - Add latency critical client + * @hdd_ctx: Global HDD context + * @phymode: the phymode of the connected adapter + * + * This function adds to the latency critical count if the present + * connection is also a latency critical one. + * + * Returns: None + */ +static inline void +hdd_add_latency_critical_client(struct hdd_context *hdd_ctx, + enum qca_wlan_802_11_mode phymode) +{ + switch (phymode) { + case QCA_WLAN_802_11_MODE_11A: + case QCA_WLAN_802_11_MODE_11G: + qdf_atomic_inc(&hdd_ctx->num_latency_critical_clients); + break; + default: + break; + } +} + +/** + * hdd_del_latency_critical_client() - Add tlatency critical client + * @hdd_ctx: Global HDD context + * @phymode: the phymode of the connected adapter + * + * This function removes from the latency critical count if the present + * connection is also a latency critical one. + * + * Returns: None + */ +static inline void +hdd_del_latency_critical_client(struct hdd_context *hdd_ctx, + enum qca_wlan_802_11_mode phymode) +{ + switch (phymode) { + case QCA_WLAN_802_11_MODE_11A: + case QCA_WLAN_802_11_MODE_11G: + qdf_atomic_dec(&hdd_ctx->num_latency_critical_clients); + break; + default: + break; + } +} + #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH /** * hdd_bus_bw_compute_prev_txrx_stats() - get tx and rx stats @@ -2640,6 +2936,23 @@ hdd_get_current_throughput_level(struct hdd_context *hdd_ctx) return hdd_ctx->cur_vote_level; } +#ifdef DP_MEM_PRE_ALLOC +static inline +void *hdd_get_prealloc_dma_mem_unaligned(size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type) +{ + return dp_prealloc_get_consistent_mem_unaligned(size, paddr, + ring_type); +} + +static inline +void hdd_put_prealloc_dma_mem_unaligned(void *vaddr) +{ + dp_prealloc_put_consistent_mem_unaligned(vaddr); +} +#endif + /** * hdd_set_current_throughput_level() - update the current vote * level @@ -2732,6 +3045,41 @@ hdd_is_low_tput_gro_enable(struct hdd_context *hdd_ctx) #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ +/** + * hdd_init_adapter_ops_wq() - Init global workqueue for adapter operations. + * @hdd_ctx: pointer to HDD context + * + * Return: QDF_STATUS_SUCCESS if workqueue is allocated, + * QDF_STATUS_E_NOMEM if workqueue aloocation fails. + */ +QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx); + +/** + * hdd_deinit_adapter_ops_wq() - Deinit global workqueue for adapter operations. + * @hdd_ctx: pointer to HDD context + * + * Return: None + */ +void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx); + +/** + * hdd_adapter_feature_update_work_init() - Init per adapter work for netdev + * feature update + * @adapter: pointer to adapter structure + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter); + +/** + * hdd_adapter_feature_update_work_deinit() - Deinit per adapter work for + * netdev feature update + * @adapter: pointer to adapter structure + * + * Return: QDF_STATUS + */ +void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter); + int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask); int hdd_init(void); @@ -2814,8 +3162,8 @@ int wlan_hdd_scan_abort(struct hdd_adapter *adapter); * @vdev_id: vdev id * @cnt: number of active ndp sessions * - * This HDD callback registered with policy manager to indicates number of - * active ndp sessions to hdd. + * This HDD callback registerd with policy manager to indicates number of active + * ndp sessions to hdd. * * Return: none */ @@ -3189,7 +3537,47 @@ static inline void hdd_set_sg_flags(struct hdd_context *hdd_ctx, struct net_device *wlan_dev){} #endif +/** + * hdd_set_netdev_flags() - set netdev flags for adapter as per ini config + * @adapter: hdd adapter context + * + * This function sets netdev feature flags for the adapter. + * + * Return: none + */ +void hdd_set_netdev_flags(struct hdd_adapter *adapter); + #ifdef FEATURE_TSO +/** + * hdd_get_tso_csum_feature_flags() - Return TSO and csum flags if enabled + * + * Return: Enabled feature flags set, 0 on failure + */ +static inline netdev_features_t hdd_get_tso_csum_feature_flags(void) +{ + netdev_features_t netdev_features = 0; + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (!soc) { + hdd_err("soc handle is NULL"); + return 0; + } + + if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) { + netdev_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + + if (cdp_cfg_get(soc, cfg_dp_tso_enable)) { + /* + * Enable TSO only if IP/UDP/TCP TX checksum flag is + * enabled. + */ + netdev_features |= NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_SG; + } + } + return netdev_features; +} + /** * hdd_set_tso_flags() - enable TSO flags in the network device * @hdd_ctx: HDD context @@ -3203,19 +3591,9 @@ static inline void hdd_set_sg_flags(struct hdd_context *hdd_ctx, static inline void hdd_set_tso_flags(struct hdd_context *hdd_ctx, struct net_device *wlan_dev) { - if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), - cfg_dp_tso_enable) && - cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), - cfg_dp_enable_ip_tcp_udp_checksum_offload)){ - /* - * We want to enable TSO only if IP/UDP/TCP TX checksum flag is - * enabled. - */ - hdd_debug("TSO Enabled"); - wlan_dev->features |= - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG; - } + hdd_debug("TSO Enabled"); + + wlan_dev->features |= hdd_get_tso_csum_feature_flags(); } #else static inline void hdd_set_tso_flags(struct hdd_context *hdd_ctx, @@ -3223,10 +3601,32 @@ static inline void hdd_set_tso_flags(struct hdd_context *hdd_ctx, { hdd_set_sg_flags(hdd_ctx, wlan_dev); } + +static inline netdev_features_t hdd_get_tso_csum_feature_flags(void) +{ + return 0; +} #endif /* FEATURE_TSO */ -void hdd_get_ibss_peer_info_cb(void *context, - tSirPeerInfoRspParams *peer_info); +/** + * wlan_hdd_get_host_log_nl_proto() - Get host log netlink protocol + * @hdd_ctx: HDD context + * + * This function returns with host log netlink protocol settings + * + * Return: none + */ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +static inline int wlan_hdd_get_host_log_nl_proto(struct hdd_context *hdd_ctx) +{ + return hdd_ctx->config->host_log_custom_nl_proto; +} +#else +static inline int wlan_hdd_get_host_log_nl_proto(struct hdd_context *hdd_ctx) +{ + return NETLINK_USERSOCK; +} +#endif #ifdef CONFIG_CNSS_LOGGER /** @@ -3244,7 +3644,10 @@ void hdd_get_ibss_peer_info_cb(void *context, */ static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx) { - hdd_ctx->radio_index = nl_srv_init(hdd_ctx->wiphy); + int proto; + + proto = wlan_hdd_get_host_log_nl_proto(hdd_ctx); + hdd_ctx->radio_index = nl_srv_init(hdd_ctx->wiphy, proto); /* radio_index is assigned from 0, so only >=0 will be valid index */ if (hdd_ctx->radio_index >= 0) @@ -3264,15 +3667,30 @@ static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx) */ static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx) { - return nl_srv_init(hdd_ctx->wiphy); + int proto; + + proto = wlan_hdd_get_host_log_nl_proto(hdd_ctx); + return nl_srv_init(hdd_ctx->wiphy, proto); } #endif QDF_STATUS hdd_sme_open_session_callback(uint8_t vdev_id, QDF_STATUS qdf_status); QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id); +/** + * hdd_reassoc() - perform a userspace-directed reassoc + * @adapter: Adapter upon which the command was received + * @bssid: BSSID with which to reassociate + * @ch_freq: channel upon which to reassociate + * @src: The source for the trigger of this action + * + * This function performs a userspace-directed reassoc operation + * + * Return: 0 for success non-zero for failure + */ int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid, - uint8_t channel, const handoff_src src); + uint32_t ch_freq, const handoff_src src); + int hdd_register_cb(struct hdd_context *hdd_ctx); void hdd_deregister_cb(struct hdd_context *hdd_ctx); int hdd_start_station_adapter(struct hdd_adapter *adapter); @@ -3570,7 +3988,8 @@ static inline void hdd_send_peer_status_ind_to_app( return; } - ch_info.chan_id = chan_info->chan_id; + /* chan_id is obsoleted by mhz */ + ch_info.chan_id = 0; ch_info.mhz = chan_info->mhz; ch_info.band_center_freq1 = chan_info->band_center_freq1; ch_info.band_center_freq2 = chan_info->band_center_freq2; @@ -3904,16 +4323,16 @@ void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool disconnecting); /** * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface. * @adapter: Handle to adapter - * @chan: Monitor mode channel + * @freq: Monitor mode frequency (MHz) * @bandwidth: Capture channel bandwidth * * Return: 0 on success else error code. */ -int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, +int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, uint32_t bandwidth); #else static inline -int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, +int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, uint32_t bandwidth) { return 0; @@ -4113,6 +4532,18 @@ void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx, * QDF_STATUS_E_FAILURE on failure */ QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event); + +/** + * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event + * @ctx: HDD context + * @sir_md_bl_evt: motion detect baseline event + * + * Callback for Motion Detection Baseline Event + * + * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and + * QDF_STATUS_E_FAILURE on failure + */ +QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event); #endif /* WLAN_FEATURE_MOTION_DETECTION */ /** @@ -4167,7 +4598,25 @@ int hdd_psoc_idle_shutdown(struct device *dev); */ int hdd_psoc_idle_restart(struct device *dev); +/** + * hdd_common_roam_callback() - common sme roam callback + * @psoc: Object Manager Psoc + * @session_id: session id for which callback is called + * @roam_info: pointer to roam info + * @roam_status: roam status + * @roam_result: roam result + * + * Return: QDF_STATUS enumeration + */ +QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + struct csr_roam_info *roam_info, + uint32_t roam_id, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result); + #ifdef WLAN_FEATURE_PKT_CAPTURE + /** * wlan_hdd_is_session_type_monitor() - check if session type is MONITOR * @session_type: session type @@ -4190,6 +4639,7 @@ bool wlan_hdd_check_mon_concurrency(void); * wlan_hdd_add_monitor_check() - check for monitor intf and add if needed * @hdd_ctx: pointer to hdd context * @adapter: output pointer to hold created monitor adapter + * @type: type of the interface * @name: name of the interface * @rtnl_held: True if RTNL lock is held * @name_assign_type: the name of assign type of the netdev @@ -4199,8 +4649,8 @@ bool wlan_hdd_check_mon_concurrency(void); */ int wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, struct hdd_adapter **adapter, - const char *name, bool rtnl_held, - unsigned char name_assign_type); + enum nl80211_iftype type, const char *name, + bool rtnl_held, unsigned char name_assign_type); /** * wlan_hdd_del_monitor() - delete monitor interface @@ -4230,8 +4680,8 @@ bool wlan_hdd_check_mon_concurrency(void) static inline int wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, struct hdd_adapter **adapter, - const char *name, bool rtnl_held, - unsigned char name_assign_type) + enum nl80211_iftype type, const char *name, + bool rtnl_held, unsigned char name_assign_type) { return 0; } @@ -4243,9 +4693,37 @@ void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, } #endif /* WLAN_FEATURE_PKT_CAPTURE */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ + defined(WLAN_FEATURE_11AX) +/** + * hdd_cleanup_conn_info() - Cleanup connectin info + * @adapter: Adapter upon which the command was received + * + * This function frees the memory allocated for the connection + * info structure + * + * Return: none + */ +void hdd_cleanup_conn_info(struct hdd_adapter *adapter); +/** + * hdd_sta_destroy_ctx_all() - cleanup all station contexts + * @hdd_ctx: Global HDD context + * + * This function destroys all the station contexts + * + * Return: none + */ +void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx); +#else +static inline void hdd_cleanup_conn_info(struct hdd_adapter *adapter) +{ +} +static inline void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) +{ +} +#endif + #ifdef FEATURE_MONITOR_MODE_SUPPORT -void hdd_set_sme_monitor_mode_cb(enum QDF_OPMODE device_mode, - struct sme_session_params *session_param); void hdd_sme_monitor_mode_callback(uint8_t vdev_id); @@ -4254,10 +4732,6 @@ QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter); QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, uint8_t session_type); #else -static inline void -hdd_set_sme_monitor_mode_cb(enum QDF_OPMODE device_mode, - struct sme_session_params *session_param) {} - static inline void hdd_sme_monitor_mode_callback(uint8_t vdev_id) {} static inline QDF_STATUS @@ -4281,4 +4755,14 @@ hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, */ void hdd_init_start_completion(void); +/** + * hdd_netdev_feature_update - Update the netdev features + * @net_dev: Handle to net_device + * + * This func holds the rtnl_lock. Do not call with rtnl_lock held. + * + * Return: None + */ +void hdd_netdev_update_features(struct hdd_adapter *adapter); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_nan.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_nan.h index e49e15f1cb561257a56b4d5792426eaae33beec3..bd75c95aa32a52e82276da5a631bbbf7083413b8 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_nan.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_nan.h @@ -31,23 +31,6 @@ struct hdd_context; struct wiphy; struct wireless_dev; -/** - * wlan_hdd_cfg80211_nan_request() - handle NAN request - * @wiphy: pointer to wireless wiphy structure. - * @wdev: pointer to wireless_dev structure. - * @data: Pointer to the data to be passed via vendor interface - * @data_len:Length of the data to be passed - * - * This function is called by userspace to send a NAN request to - * firmware. This is an SSR-protected wrapper function. - * - * Return: 0 on success, negative errno on failure - */ -int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, - struct wireless_dev *wdev, - const void *data, - int data_len); - bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx); /** @@ -68,14 +51,6 @@ int wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy, int data_len); #define FEATURE_NAN_VENDOR_COMMANDS \ - { \ - .info.vendor_id = QCA_NL80211_VENDOR_ID, \ - .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN, \ - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ - WIPHY_VENDOR_CMD_NEED_NETDEV | \ - WIPHY_VENDOR_CMD_NEED_RUNNING, \ - .doit = wlan_hdd_cfg80211_nan_request \ - }, \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN_EXT, \ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_oemdata.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_oemdata.h index 8119f20b5b7241c6744edc58917664863a903d11..49157f150db68f071cc953d31837a9e10d02e789 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_oemdata.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_oemdata.h @@ -29,6 +29,9 @@ struct hdd_context; +#ifdef FEATURE_OEM_DATA +#define WLAN_WAIT_TIME_GET_OEM_DATA 1000 +#endif #ifdef FEATURE_OEM_DATA_SUPPORT #ifndef OEM_DATA_REQ_SIZE @@ -109,7 +112,6 @@ struct oem_data_cap { /** * struct hdd_channel_info - Channel information - * @chan_id: channel id * @reserved0: reserved for padding and future use * @mhz: primary 20 MHz channel frequency in mhz * @band_center_freq1: Center frequency 1 in MHz @@ -121,7 +123,6 @@ struct oem_data_cap { * @reg_info_2: regulatory information field 2 which contains antennamax */ struct hdd_channel_info { - uint32_t chan_id; uint32_t reserved0; uint32_t mhz; uint32_t band_center_freq1; @@ -213,8 +214,22 @@ int oem_activate_service(struct hdd_context *hdd_ctx); int oem_deactivate_service(void); void hdd_send_oem_data_rsp_msg(struct oem_data_rsp *oem_rsp); + +/** + * update_channel_bw_info() - set bandwidth info for the chan + * @hdd_ctx: hdd context + * @chan_freq: channel freq for which info are required + * @chan_info: struct where the bandwidth info is filled + * + * This function finds the maximum bandwidth allowed, secondary + * channel offset and center freq for the channel as per regulatory + * domain and uses these info calculate the phy mode for the + * channel. + * + * Return: void + */ void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx, - uint16_t chan, + uint32_t chan_freq, void *hdd_chan_info); #else static inline int oem_activate_service(struct hdd_context *hdd_ctx) @@ -230,7 +245,7 @@ static inline int oem_deactivate_service(void) static inline void hdd_send_oem_data_rsp_msg(void *oem_rsp) {} static inline void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx, - uint16_t chan, + uint32_t chan_freq, void *hdd_chan_info) {} #endif /* FEATURE_OEM_DATA_SUPPORT */ @@ -266,12 +281,15 @@ int wlan_hdd_cfg80211_oem_data_handler(struct wiphy *wiphy, /** * hdd_oem_event_handler_cb() - callback for oem data event * @oem_event_data: oem data received in the event from the FW + * @vdev_id: vdev id * * Return: None */ -void hdd_oem_event_handler_cb(const struct oem_data *oem_event_data); +void hdd_oem_event_handler_cb(const struct oem_data *oem_event_data, + uint8_t vdev_id); #else -static inline void hdd_oem_event_handler_cb(void *oem_event_data) +static inline void hdd_oem_event_handler_cb(void *oem_event_data, + uint8_t vdev_id) { } #endif diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_p2p.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_p2p.h index bd2413c352218ea67e0d740e58f36992b0a0380c..39d80f10f8a5c2b8f2e9a7c2dda8c9344fe494b3 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_p2p.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_p2p.h @@ -66,13 +66,13 @@ int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command); * @frm_len: frame length * @pb_frames: frame bytes * @frame_type: frame type - * @rx_chan: channel on which frame was received + * @rx_freq: frequency on which frame was received * @rx_rssi: rssi * @rx_flags: rx flags of the frame */ void hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, uint32_t frm_len, uint8_t *pb_frames, - uint8_t frame_type, uint32_t rx_chan, + uint8_t frame_type, uint32_t rx_freq, int8_t rx_rssi, enum rxmgmt_flags rx_flags); diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_power.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_power.h index 0de2faa856d300cdbba6867e76ebb4868f27e43b..7c9aa63092a035bec8a2e9db60d2960a3d9529ab 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_power.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_power.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -129,6 +129,18 @@ struct pkt_filter_cfg { #endif +#ifdef FEATURE_ANI_LEVEL_REQUEST +/** + * ani_priv - structure to store the priv data for get ani request + * @num_freq: number of freq received from the FW + * @ani: data received from the FW + */ +struct ani_priv { + uint32_t num_freq; + struct wmi_host_ani_level_event *ani; +}; +#endif + /** * enum suspend_resume_state - Suspend resume state * @HDD_WLAN_EARLY_SUSPEND: Early suspend state. @@ -429,16 +441,15 @@ int wlan_hdd_ipv6_changed(struct notifier_block *nb, unsigned long data, void *arg); /** - * hdd_set_qpower_config() - set qpower config to firmware + * hdd_set_power_config() - set power config to firmware * @hddctx: HDD context * @adapter: HDD adapter - * @qpower: new qpower config value + * @power: new power config value * * Return: 0 on success; Errno on failure */ -int hdd_set_qpower_config(struct hdd_context *hddctx, - struct hdd_adapter *adapter, - uint8_t qpower); +int hdd_set_power_config(struct hdd_context *hddctx, + struct hdd_adapter *adapter, uint8_t power); #ifdef FEATURE_WLAN_DIAG_SUPPORT /** @@ -539,6 +550,36 @@ hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev, } #endif /* WLAN_SUSPEND_RESUME_TEST */ +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * wlan_hdd_mon_thread_resume() - Resume MON thread + * @hdd_ctx: HDD context + * + * Check if MON thread is suspended, and resume if yes. + * + * Return: None + */ +void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx); + +/** + * wlan_hdd_mon_thread_suspend() - Suspend MON thread + * @hdd_ctx: HDD context + * + * To suspend MON thread + * + * Return: 0 for success + */ +int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx); + +#else +static inline void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx) {} +static inline int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx) +{ + return 0; +} + +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #ifdef QCA_CONFIG_SMP /** * wlan_hdd_rx_thread_resume() - Resume RX thread @@ -568,4 +609,19 @@ static inline int wlan_hdd_rx_thread_suspend(struct hdd_context *hdd_ctx) } #endif +#ifdef FEATURE_ANI_LEVEL_REQUEST +/** + * wlan_hdd_get_ani_level() - Wrapper to call API to fetch ani level + * @adapter: pointer to HDD adapter + * @ani: pointer to structure storing ani level for channels + * @parsed_freqs: parsed freqs from the get ani command + * @num_freqs: number of parsed channels + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_hdd_get_ani_level(struct hdd_adapter *adapter, + struct wmi_host_ani_level_event *ani, + uint32_t *parsed_freqs, + uint8_t num_freqs); +#endif /* FEATURE_ANI_LEVEL_REQUEST */ #endif /* __WLAN_HDD_POWER_H */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_regulatory.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_regulatory.h index 789231c80035794a8f861a83eeba835d89e70ed0..4ab1b717eb59790cfc84787b8bcbaf8578dc774c 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_regulatory.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_regulatory.h @@ -61,14 +61,24 @@ void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx); */ int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code); +/** + * hdd_reg_legacy_setband_to_reg_wifi_band_bitmap() - Convert the user space + * band input to a bitmap of band capabilities, with reg_wifi_band as the + * bit value + * @qca_setband: user space/setband value band input, can be 0, 1, or 2 + * + * Return: bitmap on top of reg_wifi_band of bands enabled + */ +uint32_t hdd_reg_legacy_setband_to_reg_wifi_band_bitmap(uint8_t qca_setband); + /** * hdd_reg_set_band() - helper function for setting the regulatory band * @hdd_ctx: the HDD context to set the band for - * @ui_band: the UI band to configure + * @band_bitmap: the band bitmap to configure * * Return: zero for success, non-zero error code for failure */ -int hdd_reg_set_band(struct net_device *dev, u8 ui_band); +int hdd_reg_set_band(struct net_device *dev, uint32_t band_bitmap); /** * hdd_update_indoor_channel() - enable/disable indoor channel diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_softap_tx_rx.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_softap_tx_rx.h index 89e5f6b0a8ceb2d5c338165f31b278a709796d23..61a61e75e0fd4fc98612793f883cc538214de8f8 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_softap_tx_rx.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_softap_tx_rx.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -70,10 +71,9 @@ void hdd_softap_tx_timeout(struct net_device *dev); * hdd_softap_init_tx_rx() - Initialize Tx/Rx module * @adapter: pointer to adapter context * - * Return: QDF_STATUS_E_FAILURE if any errors encountered, - * QDF_STATUS_SUCCESS otherwise + * Return: None */ -QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter); +void hdd_softap_init_tx_rx(struct hdd_adapter *adapter); /** * hdd_softap_deinit_tx_rx() - Deinitialize Tx/Rx module @@ -87,27 +87,14 @@ QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter); /** * hdd_softap_init_tx_rx_sta() - Initialize Tx/Rx for a softap station * @adapter: pointer to adapter context - * @sta_id: Station ID to initialize * @sta_mac: pointer to the MAC address of the station * * Return: QDF_STATUS_E_FAILURE if any errors encountered, * QDF_STATUS_SUCCESS otherwise */ QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter, - uint8_t sta_id, struct qdf_mac_addr *sta_mac); -/** - * hdd_softap_deinit_tx_rx_sta() - Deinitialize Tx/Rx for a softap station - * @adapter: pointer to adapter context - * @sta_id: Station ID to deinitialize - * - * Return: QDF_STATUS_E_FAILURE if any errors encountered, - * QDF_STATUS_SUCCESS otherwise - */ -QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter, - uint8_t sta_id); - /** * hdd_softap_rx_packet_cbk() - Receive packet handler * @adapter_context: pointer to HDD adapter @@ -125,19 +112,18 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf); /** * hdd_softap_deregister_sta() - Deregister a STA with the Data Path * @adapter: pointer to adapter context - * @sta_id: Station ID to deregister + * @sta_info: double pointer to HDD station info structure * * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error */ QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, - uint8_t sta_id); + struct hdd_station_info **sta_info); /** * hdd_softap_register_sta() - Register a SoftAP STA * @adapter: pointer to adapter context * @auth_required: is additional authentication required? * @privacy_required: should 802.11 privacy bit be set? - * @sta_id: station ID assigned to this station * @sta_mac: station MAC address * @wmm_enabled: is WMM enabled for this STA? * @@ -146,7 +132,6 @@ QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, bool auth_required, bool privacy_required, - uint8_t sta_id, struct qdf_mac_addr *sta_mac, bool wmm_enabled); @@ -180,20 +165,6 @@ QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter, struct qdf_mac_addr *sta_mac, enum ol_txrx_peer_state state); -/** - * hdd_softap_get_sta_id() - Find station ID from MAC address - * @adapter: pointer to adapter context - * @sta_mac: MAC address of the destination - * @sta_id: Station ID associated with the MAC address - * - * Return: QDF_STATUS_SUCCESS if a match was found, in which case - * @sta_id is populated, QDF_STATUS_E_FAILURE if a match is - * not found - */ -QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter, - struct qdf_mac_addr *sta_mac, - uint8_t *sta_id); - #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL /** * hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler @@ -229,27 +200,123 @@ void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume) } #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ +#ifdef SAP_DHCP_FW_IND /** * hdd_post_dhcp_ind() - Send DHCP START/STOP indication to FW * @adapter: pointer to hdd adapter - * @sta_id: peer station ID + * @mac_addr: mac address * @type: WMA message type * * Return: error number */ int hdd_post_dhcp_ind(struct hdd_adapter *adapter, - uint8_t sta_id, uint16_t type); + uint8_t *mac_addr, uint16_t type); /** - * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet + * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet * @adapter: pointer to hdd adapter * @skb: pointer to OS packet (sk_buff) * @dir: direction * + * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW + * through WMI message, during DHCP based IP address acquisition phase. + * + * - Send DHCP_START notification to FW when SAP gets DHCP Discovery + * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK + * + * DHCP subtypes are determined by a status octet in the DHCP Message type + * option (option code 53 (0x35)). + * + * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK, + * and transitioned per DHCP message type as it arrives. + * + * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase + * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase + * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase + * or ACK phase (Renewal process) + * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase + * or DHCP_DELINE message in OFFER phase + * * Return: error number */ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, struct sk_buff *skb, enum qdf_proto_dir dir); +#else +static inline +int hdd_post_dhcp_ind(struct hdd_adapter *adapter, + uint8_t *mac_addr, uint16_t type) +{ + return 0; +} + +static inline +int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, + struct sk_buff *skb, + enum qdf_proto_dir dir) +{ + return 0; +} +#endif + +/** + * hdd_softap_check_wait_for_tx_eap_pkt() - Check and wait for eap failure + * pkt completion event + * @adapter: pointer to hdd adapter + * @mac_addr: mac address of peer + * + * Check and wait for eap failure pkt tx completion. + * + * Return: void + */ +void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter, + struct qdf_mac_addr *mac_addr); + +#ifndef QCA_LL_LEGACY_TX_FLOW_CONTROL +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0)) +/** + * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan + * @adapter: pointer to HDD adapter + * @skb: pointer to skb data packet + * + * Return: pointer to skb structure + */ +static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + hdd_skb_fill_gso_size(adapter->dev, skb); + if (skb_cloned(skb)) { + ++adapter->hdd_stats.tx_rx_stats.tx_orphaned; + skb_orphan(skb); + return skb; + } + + if (unlikely(hdd_ctx->config->tx_orphan_enable)) { + /* + * For UDP packets we want to orphan the packet to allow the app + * to send more packets. The flow would ultimately be controlled + * by the limited number of tx descriptors for the vdev. + */ + ++adapter->hdd_stats.tx_rx_stats.tx_orphaned; + skb_orphan(skb); + } + + return skb; +} +#else +static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ + struct sk_buff *nskb; + + hdd_skb_fill_gso_size(adapter->dev, skb); + nskb = skb_unshare(skb, GFP_ATOMIC); + + return nskb; +} +#endif +#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ #endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_sysfs.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_sysfs.h index c908ca1301deb94bf73d7f264f30b8cb5e7729e4..253344f6c8f04ab703c6eeec1eac8045e0dffccd 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_sysfs.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_sysfs.h @@ -20,6 +20,9 @@ #define _WLAN_HDD_SYSFS_H_ #ifdef WLAN_SYSFS + +#define MAX_SYSFS_USER_COMMAND_SIZE_LENGTH (32) + /** * hdd_sysfs_create_driver_root_obj() - create driver root kobject * @@ -48,6 +51,44 @@ void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc); * Return: none */ void hdd_sysfs_destroy_version_interface(void); + +/** + * hdd_sysfs_dp_aggregation_create() - API to create dp aggregation + * related sysfs entry + * + * file path: /sys/kernel/wifi/dp_aggregation + * + * usage: + * echo [0/1] > dp_aggregation + * + * Return: 0 on success and errno on failure + */ +int +hdd_sysfs_dp_aggregation_create(void); + +/** + * hdd_sysfs_dp_aggregation_destroy() - API to destroy dp aggregation + * related sysfs entry + * + * Return: None + */ +void +hdd_sysfs_dp_aggregation_destroy(void); + +/** + * hdd_sys_validate_and_copy_buf() - validate sysfs input buf and copy into + * destination buffer + * @dest_buf - pointer to destination buffer where data should be copied + * @dest_buf_size - size of destination buffer + * @src_buf - pointer to constant sysfs source buffer + * @src_buf_size - size of source buffer + * + * Return: 0 for success and error code for failure + */ +int +hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size, + char const *src_buf, size_t src_buf_size); + #ifdef WLAN_POWER_DEBUG /** * hdd_sysfs_create_powerstats_interface() - create power_stats interface @@ -102,6 +143,24 @@ static inline void hdd_sysfs_destroy_version_interface(void) { } + +static inline int +hdd_sysfs_dp_aggregation_create(void) +{ + return 0; +} + +static inline void +hdd_sysfs_dp_aggregation_destroy(void) +{ +} + +static inline int +hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size, + char const *src_buf, size_t src_buf_size) +{ + return -EPERM; +} #endif #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tdls.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tdls.h index 84d3c087a86fa20759cac810ae2af88a1a9c4556..73a510125946f63873c85aedd4067e42278e0a09 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tdls.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tdls.h @@ -160,11 +160,7 @@ int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy, int data_len); QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id, - const uint8_t *mac, uint16_t sta_id, - uint8_t qos); - -QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id, - uint8_t sta_id); + const uint8_t *mac, uint8_t qos); /** * hdd_init_tdls_config() - initialize tdls config @@ -203,15 +199,7 @@ static inline int wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy, static inline QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id, - const uint8_t *mac, uint16_t sta_id, - uint8_t qos) -{ - return QDF_STATUS_SUCCESS; -} - -static inline -QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id, - uint8_t sta_id) + const uint8_t *mac, uint8_t qos) { return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tsf.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tsf.h index a1c670bc20d79acf9b28b99791d642e8b3db6242..f3dd3b310354952b8c3505a1adc468266013359b 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tsf.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tsf.h @@ -161,15 +161,6 @@ static inline int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf) #endif #if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF) -/** - * hdd_tsf_is_ptp_enabled() - check ini configuration - * @hdd: pointer to hdd context - * - * This function checks tsf configuration for ptp - * - * Return: true on enable, false on disable - */ -bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd); /** * hdd_tsf_is_tx_set() - check ini configuration * @hdd: pointer to hdd context diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tx_rx.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tx_rx.h index 4fe91bb6b80c527fb7043a4efcceb66a7e92cfea..a6677d2076e138c78f0f3791652ffd1bf858b20a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tx_rx.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_tx_rx.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -40,6 +41,17 @@ struct hdd_context; #define hdd_dp_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_HDD_DATA, params) #define hdd_dp_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HDD_DATA, params) +#define hdd_dp_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_HDD_DATA, params) +#define hdd_dp_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_HDD_DATA, params) +#define hdd_dp_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_HDD_DATA, params) +#define hdd_dp_nofl_info(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_HDD_DATA, params) +#define hdd_dp_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_HDD_DATA, params) + #define hdd_dp_alert_rl(params...) \ QDF_TRACE_FATAL_RL(QDF_MODULE_ID_HDD_DATA, params) #define hdd_dp_err_rl(params...) \ @@ -104,6 +116,43 @@ QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id); */ QDF_STATUS hdd_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rxBuf); +#if defined(WLAN_SUPPORT_RX_FISA) +/** + * hdd_rx_fisa_cbk() - Entry function to FISA to handle aggregation + * @soc: core txrx main context + * @vdev: Handle DP vdev + * @nbuf_list: List nbufs to be aggregated + * + * Return: Success on aggregation + */ +QDF_STATUS hdd_rx_fisa_cbk(void *dp_soc, void *dp_vdev, qdf_nbuf_t rxbuf_list); + +/** + * hdd_rx_fisa_flush_by_ctx_id() - Flush function to end of context + * flushing of aggregates + * @soc: core txrx main context + * @ring_num: REO number to flush the flow Rxed on the REO + * + * Return: Success on flushing the flows for the REO + */ +QDF_STATUS hdd_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num); + +/** + * hdd_rx_fisa_flush_by_vdev_id() - Flush fisa aggregates per vdev id + * @soc: core txrx main context + * @vdev_id: vdev ID + * + * Return: Success on flushing the flows for the vdev + */ +QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id); +#else +static inline QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, + uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * hdd_rx_deliver_to_stack() - HDD helper function to deliver RX pkts to stack * @adapter: pointer to HDD adapter context @@ -170,18 +219,6 @@ void hdd_disable_rx_ol_in_concurrency(bool disable); */ void hdd_disable_rx_ol_for_low_tput(struct hdd_context *hdd_ctx, bool disable); -/** - * hdd_get_peer_sta_id() - Get the StationID using the Peer Mac address - * @sta_ctx: pointer to HDD Station Context - * @mac_address: pointer to Peer Mac address - * @sta_id: pointer to returned Station Index - * - * Return: QDF_STATUS_SUCCESS/QDF_STATUS_E_FAILURE - */ -QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx, - struct qdf_mac_addr *mac_address, - uint8_t *sta_id); - /** * hdd_reset_all_adapters_connectivity_stats() - reset connectivity stats * @hdd_ctx: pointer to HDD Station Context @@ -241,8 +278,17 @@ void hdd_register_tx_flow_control(struct hdd_adapter *adapter, ol_txrx_tx_flow_control_fp flow_control_fp, ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause); void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter); + +/** + * hdd_get_tx_resource() - check tx resources and take action + * @adapter: adapter handle + * @mac_addr: mac address + * @timer_value: timer value + * + * Return: none + */ void hdd_get_tx_resource(struct hdd_adapter *adapter, - uint8_t STAId, uint16_t timer_value); + struct qdf_mac_addr *mac_addr, uint16_t timer_value); #else static inline void hdd_tx_resume_cb(void *adapter_context, bool tx_resume) @@ -261,8 +307,19 @@ static inline void hdd_register_tx_flow_control(struct hdd_adapter *adapter, static inline void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter) { } -static inline void hdd_get_tx_resource(struct hdd_adapter *adapter, - uint8_t STAId, uint16_t timer_value) + + +/** + * hdd_get_tx_resource() - check tx resources and take action + * @adapter: adapter handle + * @mac_addr: mac address + * @timer_value: timer value + * + * Return: none + */ +static inline +void hdd_get_tx_resource(struct hdd_adapter *adapter, + struct qdf_mac_addr *mac_addr, uint16_t timer_value) { } #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ @@ -291,9 +348,6 @@ static inline void {} #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ -int hdd_get_peer_idx(struct hdd_station_ctx *sta_ctx, - struct qdf_mac_addr *addr); - const char *hdd_reason_type_to_string(enum netif_reason_type reason); const char *hdd_action_type_to_string(enum netif_action_type action); @@ -302,34 +356,65 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter, #ifdef FEATURE_MONITOR_MODE_SUPPORT int hdd_set_mon_rx_cb(struct net_device *dev); +#else +static inline +int hdd_set_mon_rx_cb(struct net_device *dev) +{ + return 0; +} +#endif +#ifdef WLAN_FEATURE_PKT_CAPTURE /** - * hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer. - * @context: pointer to qdf context - * @rxBuf: pointer to rx qdf_nbuf + * hdd_set_pktcapture_cb() - Set pkt capture mode callback + * @dev: Pointer to net_device structure + * @pdev_id: pdev id * - * TL will call this to notify the HDD when one or more packets were - * received for a registered STA. + * Return: 0 on success; non-zero for failure + */ +int hdd_set_pktcapture_cb(struct net_device *dev, uint8_t pdev_id); + +/** + * hdd_reset_pktcapture_cb() - Reset pkt capture mode callback + * @pdev_id: pdev id * - * Return: QDF_STATUS + * Return: None */ -QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf); +void hdd_reset_pktcapture_cb(uint8_t pdev_id); #else static inline -int hdd_set_mon_rx_cb(struct net_device *dev) +int hdd_set_pktcapture_cb(struct net_device *dev, uint8_t pdev_id) { - return 0; + return -ENOTSUPP; } static inline -QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf) +void hdd_reset_pktcapture_cb(uint8_t pdev_id) { - return QDF_STATUS_SUCCESS; } -#endif +#endif /* WLAN_FEATURE_PKT_CAPTURE */ void hdd_send_rps_ind(struct hdd_adapter *adapter); void hdd_send_rps_disable_ind(struct hdd_adapter *adapter); + +/** + * hdd_adapter_set_rps() - Enable/disable RPS for mode specified + * @vdev_id: vdev id of adapter for which RPS needs to be enabled + * @enable: Set true to enable RPS in SAP mode + * + * Callback function registered with ipa + * + * Return: none + */ +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void hdd_adapter_set_rps(uint8_t vdev_id, bool enable); +#else +static inline +void hdd_adapter_set_rps(uint8_t vdev_id, bool enable) +{ +} +#endif + void wlan_hdd_classify_pkt(struct sk_buff *skb); #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH @@ -371,6 +456,17 @@ void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir) {} #endif +/** + * hdd_set_udp_qos_upgrade_config() - Set the threshold for UDP packet + * QoS upgrade. + * @adapter: adapter for which this configuration is to be applied + * @priority: the threshold priority + * + * Returns: 0 on success, -EINVAL on failure + */ +int hdd_set_udp_qos_upgrade_config(struct hdd_adapter *adapter, + uint8_t priority); + /* * As of the 4.7 kernel, net_device->trans_start is removed. Create shims to * support compiling against older versions of the kernel. @@ -473,4 +569,5 @@ wlan_hdd_dump_queue_history_state(struct hdd_netif_queue_history *q_hist, */ bool wlan_hdd_rx_rpm_mark_last_busy(struct hdd_context *hdd_ctx, void *hif_ctx); + #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_wmm.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_wmm.h index 8473104c4d6a5add2be88e21c2e6ed94de834218..a519f1f8e31dbaca5a341532eebe47d4b2c8c78a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_wmm.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_wmm.h @@ -260,7 +260,10 @@ QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter); * * Return: Qdisc queue index. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev, select_queue_fallback_t fallback); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_apf.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_apf.c index 85cdeb97ea541bdacf11557770d12460b43e7ab1..c49b471e96c68c92b9eb477eec2c4f7af7e5d8b7 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_apf.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_apf.c @@ -239,6 +239,8 @@ static int hdd_set_reset_apf_offload(struct hdd_context *hdd_ctx, ret = -EINVAL; goto fail; } + + apf_set_offload.session_id = adapter->vdev_id; apf_set_offload.total_length = nla_get_u32(tb[APF_PACKET_SIZE]); if (!apf_set_offload.total_length) { @@ -263,7 +265,6 @@ static int hdd_set_reset_apf_offload(struct hdd_context *hdd_ctx, apf_set_offload.current_length = prog_len; nla_memcpy(apf_set_offload.program, tb[APF_PROGRAM], prog_len); - apf_set_offload.session_id = adapter->vdev_id; /* Parse and fetch filter Id */ if (!tb[APF_FILTER_ID]) { @@ -508,6 +509,11 @@ static int hdd_apf_read_memory(struct hdd_adapter *adapter, struct nlattr **tb) return -EINVAL; } read_mem_params.addr_offset = nla_get_u32(tb[APF_CURRENT_OFFSET]); + if (read_mem_params.addr_offset > MAX_APF_MEMORY_LEN) { + hdd_err("attr apf memory offset should be less than %d", + MAX_APF_MEMORY_LEN); + return -EINVAL; + } /* Read length */ if (!tb[APF_PACKET_SIZE]) { diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c index 3208b24bfa72ab6013e0ea31c5a821dfae8c35bc..7cf4b2e7723d4806926375b511854cb2463394f5 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -52,6 +52,7 @@ #include #include #include +#include "ol_txrx.h" #include #include #include @@ -69,9 +70,10 @@ #include #include #include "wlan_blm_ucfg_api.h" +#include "wlan_hdd_sta_info.h" #include "wlan_hdd_periodic_sta_stats.h" -#include "wlan_pkt_capture_ucfg_api.h" +#include /* These are needed to recognize WPA and RSN suite types */ #define HDD_WPA_OUI_SIZE 4 @@ -173,8 +175,24 @@ static const int beacon_filter_table[] = { #endif }; +/* HE operation BIT positins */ +#if defined(WLAN_FEATURE_11AX) +#define HE_OPERATION_DFLT_PE_DURATION_POS 0 +#define HE_OPERATION_TWT_REQUIRED_POS 3 +#define HE_OPERATION_RTS_THRESHOLD_POS 4 +#define HE_OPERATION_VHT_OPER_POS 14 +#define HE_OPERATION_CO_LOCATED_BSS_POS 15 +#define HE_OPERATION_ER_SU_DISABLE_POS 16 +#define HE_OPERATION_OPER_INFO_6G_POS 17 +#define HE_OPERATION_RESERVED_POS 18 +#define HE_OPERATION_BSS_COLOR_POS 24 +#define HE_OPERATION_PARTIAL_BSS_COLOR_POS 30 +#define HE_OPERATION_BSS_COL_DISABLED_POS 31 +#endif + #if defined(WLAN_FEATURE_SAE) && \ - defined(CFG80211_EXTERNAL_AUTH_SUPPORT) + (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) /** * wlan_hdd_sae_callback() - Sends SAE info to supplicant * @adapter: pointer adapter context @@ -343,14 +361,15 @@ bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter) enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx) { - uint8_t staChannel = 0; + uint32_t sta_freq = 0; if (eConnectionState_Associated == sta_ctx->conn_info.conn_state) - staChannel = sta_ctx->conn_info.channel; + sta_freq = sta_ctx->conn_info.chan_freq; - if (staChannel > 0 && staChannel < 14) + if (wlan_reg_is_24ghz_ch_freq(sta_freq)) return BAND_2G; - else if (staChannel >= 36 && staChannel <= 184) + else if (wlan_reg_is_5ghz_ch_freq(sta_freq) || + wlan_reg_is_6ghz_chan_freq(sta_freq)) return BAND_5G; else /* If station is not connected return as BAND_ALL */ return BAND_ALL; @@ -380,15 +399,18 @@ hdd_conn_get_connected_cipher_algo(struct hdd_station_ctx *sta_ctx, struct hdd_adapter *hdd_get_sta_connection_in_progress( struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_station_ctx *hdd_sta_ctx; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS; if (!hdd_ctx) { hdd_err("HDD context is NULL"); return NULL; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if ((QDF_STA_MODE == adapter->device_mode) || (QDF_P2P_CLIENT_MODE == adapter->device_mode) || @@ -397,6 +419,10 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress( hdd_sta_ctx->conn_info.conn_state) { hdd_debug("vdev_id %d: Connection is in progress", adapter->vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; } else if ((eConnectionState_Associated == hdd_sta_ctx->conn_info.conn_state) && @@ -405,9 +431,14 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress( adapter->vdev_id)) { hdd_debug("vdev_id %d: Key exchange is in progress", adapter->vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; } @@ -862,15 +893,15 @@ static void hdd_copy_ht_operation(struct hdd_station_ctx *hdd_sta_ctx, static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, tDot11fIEVHTOperation *roam_ops) { - ieee_ops->center_freq_seg0_idx = roam_ops->chanCenterFreqSeg1; - ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg2; + ieee_ops->center_freq_seg0_idx = roam_ops->chan_center_freq_seg0; + ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg1; } #else static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, tDot11fIEVHTOperation *roam_ops) { - ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg1; - ieee_ops->center_freq_seg2_idx = roam_ops->chanCenterFreqSeg2; + ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg0; + ieee_ops->center_freq_seg2_idx = roam_ops->chan_center_freq_seg1; } #endif /* KERNEL_VERSION(4, 12, 0) */ @@ -896,6 +927,112 @@ static void hdd_copy_vht_operation(struct hdd_station_ctx *hdd_sta_ctx, hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ + defined(WLAN_FEATURE_11AX) +static void hdd_copy_he_operation(struct hdd_station_ctx *hdd_sta_ctx, + struct csr_roam_info *roam_info) +{ + tDot11fIEhe_op *roam_he_operation = &roam_info->he_operation; + struct ieee80211_he_operation *hdd_he_operation; + uint32_t he_oper_params = 0; + uint32_t len = 0, filled = 0; + uint8_t he_oper_6g_params = 0; + uint32_t he_oper_len; + + if (!roam_he_operation->present) + return; + if (roam_he_operation->vht_oper_present) + len += 3; + if (roam_he_operation->co_located_bss) + len += 1; + if (roam_he_operation->oper_info_6g_present) + len += 5; + + he_oper_len = sizeof(struct ieee80211_he_operation) + len; + + hdd_he_operation = qdf_mem_malloc(he_oper_len); + if (!hdd_he_operation) + return; + + /* Fill he_oper_params */ + he_oper_params |= roam_he_operation->default_pe << + HE_OPERATION_DFLT_PE_DURATION_POS; + he_oper_params |= roam_he_operation->twt_required << + HE_OPERATION_TWT_REQUIRED_POS; + he_oper_params |= roam_he_operation->txop_rts_threshold << + HE_OPERATION_RTS_THRESHOLD_POS; + he_oper_params |= roam_he_operation->vht_oper_present << + HE_OPERATION_VHT_OPER_POS; + he_oper_params |= roam_he_operation->co_located_bss << + HE_OPERATION_CO_LOCATED_BSS_POS; + he_oper_params |= roam_he_operation->er_su_disable << + HE_OPERATION_ER_SU_DISABLE_POS; + he_oper_params |= roam_he_operation->oper_info_6g_present << + HE_OPERATION_OPER_INFO_6G_POS; + he_oper_params |= roam_he_operation->reserved2 << + HE_OPERATION_RESERVED_POS; + he_oper_params |= roam_he_operation->bss_color << + HE_OPERATION_BSS_COLOR_POS; + he_oper_params |= roam_he_operation->partial_bss_col << + HE_OPERATION_PARTIAL_BSS_COLOR_POS; + he_oper_params |= roam_he_operation->bss_col_disabled << + HE_OPERATION_BSS_COL_DISABLED_POS; + + hdd_he_operation->he_oper_params = he_oper_params; + + /* Fill he_mcs_nss set */ + qdf_mem_copy(&hdd_he_operation->he_mcs_nss_set, + roam_he_operation->basic_mcs_nss, + sizeof(hdd_he_operation->he_mcs_nss_set)); + + /* Fill he_params_optional fields */ + + if (roam_he_operation->vht_oper_present) { + hdd_he_operation->optional[filled++] = + roam_he_operation->vht_oper.info.chan_width; + hdd_he_operation->optional[filled++] = + roam_he_operation->vht_oper.info.center_freq_seg0; + hdd_he_operation->optional[filled++] = + roam_he_operation->vht_oper.info.center_freq_seg1; + } + if (roam_he_operation->co_located_bss) + hdd_he_operation->optional[filled++] = + roam_he_operation->maxbssid_ind.info.data; + + if (roam_he_operation->oper_info_6g_present) { + hdd_he_operation->optional[filled++] = + roam_he_operation->oper_info_6g.info.primary_ch; + he_oper_6g_params |= + roam_he_operation->oper_info_6g.info.ch_width << 0; + he_oper_6g_params |= + roam_he_operation->oper_info_6g.info.dup_bcon << 2; + he_oper_6g_params |= + roam_he_operation->oper_info_6g.info.reserved << 3; + + hdd_he_operation->optional[filled++] = he_oper_6g_params; + hdd_he_operation->optional[filled++] = + roam_he_operation->oper_info_6g.info.center_freq_seg0; + hdd_he_operation->optional[filled++] = + roam_he_operation->oper_info_6g.info.center_freq_seg1; + hdd_he_operation->optional[filled] = + roam_he_operation->oper_info_6g.info.min_rate; + } + + if (hdd_sta_ctx->cache_conn_info.he_operation) { + qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); + hdd_sta_ctx->cache_conn_info.he_operation = NULL; + } + + hdd_sta_ctx->cache_conn_info.he_oper_len = he_oper_len; + + hdd_sta_ctx->cache_conn_info.he_operation = hdd_he_operation; +} +#else +static inline void hdd_copy_he_operation(struct hdd_station_ctx *hdd_sta_ctx, + struct csr_roam_info *roam_info) +{ +} +#endif /** * hdd_save_bss_info() - save connection info in hdd sta ctx @@ -910,8 +1047,6 @@ static void hdd_save_bss_info(struct hdd_adapter *adapter, struct hdd_station_ctx *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - hdd_sta_ctx->conn_info.freq = cds_chan_to_freq( - hdd_sta_ctx->conn_info.channel); if (roam_info->vht_caps.present) { hdd_sta_ctx->conn_info.conn_flag.vht_present = true; hdd_copy_vht_caps(&hdd_sta_ctx->conn_info.vht_caps, @@ -949,9 +1084,15 @@ static void hdd_save_bss_info(struct hdd_adapter *adapter, } else { hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; } + + /* Cleanup already existing he info */ + hdd_cleanup_conn_info(adapter); + /* Cache last connection info */ qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_info, sizeof(hdd_sta_ctx->cache_conn_info)); + + hdd_copy_he_operation(hdd_sta_ctx, roam_info); } /** @@ -979,17 +1120,6 @@ hdd_conn_save_connect_info(struct hdd_adapter *adapter, qdf_copy_macaddr(&sta_ctx->conn_info.bssid, &roam_info->bssid); - /* - * Save the Station ID for this station from - * the 'Roam Info'. For IBSS mode, sta_id is - * assigned in NEW_PEER_IND. For reassoc, the - * sta_id doesn't change and it may be invalid - * in this structure so no change here. - */ - if (!roam_info->fReassocReq) { - sta_ctx->conn_info.sta_id[0] = - roam_info->staId; - } } else if (eCSR_BSS_TYPE_IBSS == bss_type) { qdf_copy_macaddr(&sta_ctx->conn_info.bssid, &roam_info->bssid); @@ -1021,8 +1151,8 @@ hdd_conn_save_connect_info(struct hdd_adapter *adapter, sta_ctx->conn_info.last_auth_type = sta_ctx->conn_info.auth_type; - sta_ctx->conn_info.channel = - roam_info->u.pConnectedProfile->operationChannel; + sta_ctx->conn_info.chan_freq = + roam_info->u.pConnectedProfile->op_freq; /* Save the ssid for the connection */ qdf_mem_copy(&sta_ctx->conn_info.ssid.SSID, @@ -1240,6 +1370,8 @@ hdd_send_new_ap_channel_info(struct net_device *dev, { union iwreq_data wrqu; struct bss_description *descriptor = roam_info->bss_desc; + mac_handle_t mac_hdl; + struct wlan_objmgr_pdev *pdev; if (!descriptor) { hdd_err("bss descriptor is null"); @@ -1249,10 +1381,20 @@ hdd_send_new_ap_channel_info(struct net_device *dev, * Send the Channel event, the supplicant needs this to generate * the Adjacent AP report. */ - hdd_debug("Sending up an SIOCGIWFREQ, channelId: %d", - descriptor->channelId); + hdd_debug("Sending up an SIOCGIWFREQ, channel freq: %d", + descriptor->chan_freq); memset(&wrqu, '\0', sizeof(wrqu)); - wrqu.freq.m = descriptor->channelId; + mac_hdl = hdd_adapter_get_mac_handle(adapter); + if (!mac_hdl) { + hdd_err("MAC handle invalid, falling back!"); + return; + } + pdev = MAC_CONTEXT(mac_hdl)->pdev; + if (!pdev) { + hdd_err("pdev invalid in MAC context, falling back!"); + return; + } + wrqu.freq.m = wlan_reg_freq_to_chan(pdev, descriptor->chan_freq); wrqu.freq.e = 0; wrqu.freq.i = 0; wireless_send_event(adapter->dev, SIOCGIWFREQ, &wrqu, NULL); @@ -1383,11 +1525,12 @@ static void hdd_send_association_event(struct net_device *dev, ucfg_p2p_status_connect(adapter->vdev); - hdd_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_STR + hdd_nofl_info("%s(vdevid-%d): " QDF_MAC_ADDR_FMT " connected to " - QDF_MAC_ADDR_STR, dev->name, adapter->vdev_id, - QDF_MAC_ADDR_ARRAY(adapter->mac_addr.bytes), - QDF_MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data)); + QDF_MAC_ADDR_FMT, dev->name, adapter->vdev_id, + QDF_MAC_ADDR_REF(adapter->mac_addr.bytes), + QDF_MAC_ADDR_REF(wrqu.ap_addr.sa_data)); + hdd_send_update_beacon_ies_event(adapter, roam_info); /* @@ -1415,7 +1558,6 @@ static void hdd_send_association_event(struct net_device *dev, } qdf_copy_macaddr(&peer_macaddr, &sta_ctx->conn_info.bssid); - chan_info.chan_id = roam_info->chan_info.chan_id; chan_info.mhz = roam_info->chan_info.mhz; chan_info.info = roam_info->chan_info.info; chan_info.band_center_freq1 = @@ -1430,8 +1572,8 @@ static void hdd_send_association_event(struct net_device *dev, ret = hdd_objmgr_set_peer_mlme_state(adapter->vdev, WLAN_ASSOC_STATE); if (ret) - hdd_err("Peer object %pM fail to set associated state", - peer_macaddr.bytes); + hdd_err("Peer object "QDF_MAC_ADDR_FMT" fail to set associated state", + QDF_MAC_ADDR_REF(peer_macaddr.bytes)); /* send peer status indication to oem app */ hdd_send_peer_status_ind_to_app(&peer_macaddr, @@ -1447,21 +1589,23 @@ static void hdd_send_association_event(struct net_device *dev, roam_info->tdls_prohibited, adapter->vdev); #endif + + hdd_add_latency_critical_client( + hdd_ctx, + hdd_convert_cfgdot11mode_to_80211mode( + sta_ctx->conn_info.dot11mode)); /* start timer in sta/p2p_cli */ hdd_bus_bw_compute_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_start(hdd_ctx); - - if (ucfg_pkt_capture_get_pktcap_mode()) - ucfg_pkt_capture_record_channel(adapter->vdev); } else if (eConnectionState_IbssConnected == /* IBss Associated */ sta_ctx->conn_info.conn_state) { policy_mgr_update_connection_info(hdd_ctx->psoc, adapter->vdev_id); memcpy(wrqu.ap_addr.sa_data, sta_ctx->conn_info.bssid.bytes, ETH_ALEN); - hdd_debug("%s(vdevid-%d): new IBSS peer connection to BSSID " QDF_MAC_ADDR_STR, + hdd_debug("%s(vdevid-%d): new IBSS peer connection to BSSID " QDF_MAC_ADDR_FMT, dev->name, adapter->vdev_id, - QDF_MAC_ADDR_ARRAY(sta_ctx->conn_info.bssid.bytes)); + QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes)); } else { /* Not Associated */ hdd_nofl_info("%s(vdevid-%d): disconnected", dev->name, adapter->vdev_id); @@ -1495,6 +1639,10 @@ static void hdd_send_association_event(struct net_device *dev, false, adapter->vdev); + hdd_del_latency_critical_client( + hdd_ctx, + hdd_convert_cfgdot11mode_to_80211mode( + sta_ctx->conn_info.dot11mode)); /* stop timer in sta/p2p_cli */ hdd_bus_bw_compute_reset_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_try_stop(hdd_ctx); @@ -1530,8 +1678,7 @@ static void hdd_send_association_event(struct net_device *dev, */ static void hdd_conn_remove_connect_info(struct hdd_station_ctx *sta_ctx) { - /* Remove sta_id, bssid and peer_macaddr */ - sta_ctx->conn_info.sta_id[0] = HDD_WLAN_INVALID_STA_ID; + /* Remove bssid and peer_macaddr */ qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE); qdf_mem_zero(&sta_ctx->conn_info.peer_macaddr[0], QDF_MAC_ADDR_SIZE); @@ -1638,8 +1785,8 @@ static void hdd_print_bss_info(struct hdd_station_ctx *hdd_sta_ctx) conn_info = &hdd_sta_ctx->conn_info; hdd_nofl_debug("*********** WIFI DATA LOGGER **************"); - hdd_nofl_debug("chan: %d dot11mode %d AKM %d ssid: \"%.*s\" ,roam_count %d nss %d legacy %d mcs %d signal %d noise: %d", - conn_info->freq, conn_info->dot11mode, + hdd_nofl_debug("freq: %d dot11mode %d AKM %d ssid: \"%.*s\" ,roam_count %d nss %d legacy %d mcs %d signal %d noise: %d", + conn_info->chan_freq, conn_info->dot11mode, conn_info->last_auth_type, conn_info->last_ssid.SSID.length, conn_info->last_ssid.SSID.ssId, conn_info->roam_count, @@ -1655,6 +1802,82 @@ static void hdd_print_bss_info(struct hdd_station_ctx *hdd_sta_ctx) conn_info->hs20vendor_ie.release_num : 0); } +/** + * hdd_cm_set_default_wlm_mode - reset the default wlm mode if + * wlm_latency_reset_on_disconnect is set. + *@adapter: adapter pointer + * + * return: None. + */ +static void hdd_cm_set_default_wlm_mode(struct hdd_adapter *adapter) +{ + QDF_STATUS status; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + bool reset; + uint8_t def_level; + mac_handle_t mac_handle; + uint16_t vdev_id; + + if (!hdd_ctx) { + hdd_err("hdd_ctx is NULL"); + return; + } + + status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("could not get wlm reset flag"); + return; + } + if (!reset) + return; + + status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &def_level); + if (QDF_IS_STATUS_ERROR(status)) + def_level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + + mac_handle = hdd_ctx->mac_handle; + vdev_id = adapter->vdev_id; + + status = sme_set_wlm_latency_level(mac_handle, vdev_id, def_level); + if (QDF_IS_STATUS_SUCCESS(status)) { + hdd_debug("reset wlm mode %x on disconnection", def_level); + adapter->latency_level = def_level; + } else { + hdd_err("reset wlm mode failed: %d", status); + } +} + +/** + * hdd_reset_udp_qos_upgrade_config() - Reset the threshold for UDP packet + * QoS upgrade. + * @adapter: adapter for which this configuration is to be applied + * + * Return: None + */ +static void hdd_reset_udp_qos_upgrade_config(struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + bool reset; + QDF_STATUS status; + + if (!hdd_ctx) { + hdd_err("hdd_ctx is NULL"); + return; + } + + status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("could not get the wlm reset flag"); + return; + } + + if (reset) { + adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; + hdd_debug("UDP packets qos upgrade to: %d", + adapter->upgrade_udp_qos_threshold); + } +} + /** * hdd_dis_connect_handler() - disconnect event handler * @adapter: pointer to adapter @@ -1680,12 +1903,12 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, struct net_device *dev = adapter->dev; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - uint8_t sta_id; bool sendDisconInd = true; mac_handle_t mac_handle; struct wlan_ies disconnect_ies = {0}; bool from_ap = false; uint32_t reason_code = 0; + struct wlan_objmgr_vdev *vdev; if (!dev) { hdd_err("net_dev is released return"); @@ -1698,14 +1921,16 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, WLAN_CONTROL_PATH); if (ucfg_ipa_is_enabled() && - (sta_ctx->conn_info.sta_id[0] != HDD_WLAN_INVALID_STA_ID)) + QDF_IS_STATUS_SUCCESS(wlan_hdd_validate_mac_address( + &sta_ctx->conn_info.bssid))) ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, adapter->device_mode, - sta_ctx->conn_info.sta_id[0], adapter->vdev_id, WLAN_IPA_STA_DISCONNECT, sta_ctx->conn_info.bssid.bytes); + hdd_cm_set_default_wlm_mode(adapter); + hdd_reset_udp_qos_upgrade_config(adapter); hdd_periodic_sta_stats_stop(adapter); #ifdef FEATURE_WLAN_AUTO_SHUTDOWN @@ -1738,7 +1963,7 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, hdd_clear_roam_profile_ie(adapter); hdd_wmm_init(adapter); - wlan_deregister_txrx_packetdump(); + wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); /* indicate 'disconnect' status to wpa_supplicant... */ hdd_send_association_event(dev, roam_info); @@ -1807,6 +2032,15 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, mac_handle = hdd_ctx->mac_handle; sme_ft_reset(mac_handle, adapter->vdev_id); sme_reset_key(mac_handle, adapter->vdev_id); + + if (adapter->device_mode == QDF_STA_MODE) { + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + wlan_crypto_reset_vdev_params(vdev); + hdd_objmgr_put_vdev(vdev); + } + } + hdd_remove_beacon_filter(adapter); if (sme_is_beacon_report_started(mac_handle, adapter->vdev_id)) { @@ -1815,9 +2049,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, adapter->vdev_id, SCAN_EVENT_TYPE_MAX, true); } - if (eCSR_ROAM_IBSS_LEAVE != roam_status) { - sta_id = sta_ctx->conn_info.sta_id[0]; /* clear scan cache for Link Lost */ + if (roam_status != eCSR_ROAM_IBSS_LEAVE) { if (eCSR_ROAM_LOSTLINK == roam_status) { wlan_hdd_cfg80211_unlink_bss(adapter, sta_ctx->conn_info.bssid.bytes, @@ -1826,11 +2059,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, sme_remove_bssid_from_scan_list(mac_handle, sta_ctx->conn_info.bssid.bytes); } - if (sta_id < HDD_MAX_ADAPTERS) - hdd_ctx->sta_to_adapter[sta_id] = NULL; - else - hdd_debug("invalid sta_id %d", sta_id); } + /* Clear saved connection information in HDD */ hdd_conn_remove_connect_info(sta_ctx); /* @@ -1857,6 +2087,14 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc); adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; + /* + * Reset hdd_reassoc_scenario to false here. After roaming in + * 802.1x or WPA3 security, EAPOL is handled at supplicant and + * the hdd_reassoc_scenario flag will not be reset if disconnection + * happens before EAP/EAPOL at supplicant is complete. + */ + sta_ctx->hdd_reassoc_scenario = false; + /* Unblock anyone waiting for disconnect to complete */ complete(&adapter->disconnect_comp_var); @@ -1898,47 +2136,37 @@ static void hdd_set_peer_authorized_event(uint32_t vdev_id) complete(&adapter->sta_authorized_event); } -/** - * hdd_change_peer_state() - change peer state - * @adapter: HDD adapter - * @sta_state: peer state - * @roam_synch_in_progress: roam synch in progress - * - * Return: QDF status - */ +#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) +static inline +void hdd_set_unpause_queue(void *soc, struct hdd_adapter *adapter) +{ + unsigned long rc; + /* wait for event from firmware to set the event */ + rc = wait_for_completion_timeout( + &adapter->sta_authorized_event, + msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT)); + if (!rc) + hdd_debug("timeout waiting for sta_authorized_event"); + + cdp_fc_vdev_unpause(soc, adapter->vdev_id, + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, + 0); +} +#else +static inline +void hdd_set_unpause_queue(void *soc, struct hdd_adapter *adapter) +{ } +#endif + QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter, - uint8_t sta_id, + uint8_t *peer_mac, enum ol_txrx_peer_state sta_state, bool roam_synch_in_progress) { QDF_STATUS err; - uint8_t *peer_mac_addr; - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer; - - if (!pdev) { - hdd_err("Failed to get txrx context"); - return QDF_STATUS_E_FAULT; - } - - if (sta_id >= WLAN_MAX_STA_COUNT) { - hdd_err("Invalid sta id: %d", sta_id); - return QDF_STATUS_E_INVAL; - } - - peer = cdp_peer_find_by_local_id(soc, - (struct cdp_pdev *)pdev, sta_id); - if (!peer) - return QDF_STATUS_E_FAULT; - - peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer); - if (!peer_mac_addr) { - hdd_err("peer mac addr is NULL"); - return QDF_STATUS_E_FAULT; - } - err = cdp_peer_state_update(soc, pdev, peer_mac_addr, sta_state); + err = cdp_peer_state_update(soc, peer_mac, sta_state); if (err != QDF_STATUS_SUCCESS) { hdd_err("peer state update failed"); return QDF_STATUS_E_FAULT; @@ -1957,7 +2185,8 @@ QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter, INIT_COMPLETION(adapter->sta_authorized_event); #endif - err = sme_set_peer_authorized(peer_mac_addr, + err = sme_set_peer_authorized( + peer_mac, hdd_set_peer_authorized_event, adapter->vdev_id); if (err != QDF_STATUS_SUCCESS) { @@ -1967,46 +2196,22 @@ QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter, if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) { -#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) - void *vdev; - unsigned long rc; - - /* wait for event from firmware to set the event */ - rc = wait_for_completion_timeout( - &adapter->sta_authorized_event, - msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT)); - if (!rc) - hdd_debug("timeout waiting for sta_authorized_event"); - - vdev = (void *)cdp_peer_get_vdev(soc, peer); - cdp_fc_vdev_unpause(soc, (struct cdp_vdev *)vdev, - OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); -#endif + hdd_set_unpause_queue(soc, adapter); } } return QDF_STATUS_SUCCESS; } -/** - * hdd_update_dp_vdev_flags() - update datapath vdev flags - * @cbk_data: callback data - * @sta_id: station id - * @vdev_param: vdev parameter - * @is_link_up: link state up or down - * - * Return: QDF status - */ QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data, - uint8_t sta_id, + uint8_t vdev_id, uint32_t vdev_param, bool is_link_up) { - struct cdp_vdev *data_vdev; QDF_STATUS status = QDF_STATUS_SUCCESS; void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct hdd_context *hdd_ctx; - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); struct wlan_objmgr_psoc **psoc; + cdp_config_param_type val; if (!cbk_data) return status; @@ -2022,17 +2227,68 @@ QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data, if (!hdd_ctx->tdls_nap_active) return status; - data_vdev = cdp_peer_get_vdev_by_sta_id(soc, pdev, sta_id); - if (!data_vdev) { + if (vdev_id == WLAN_INVALID_VDEV_ID) { status = QDF_STATUS_E_FAILURE; return status; } - cdp_txrx_set_vdev_param(soc, data_vdev, vdev_param, is_link_up); + val.cdp_vdev_param_tdls_flags = is_link_up; + cdp_txrx_set_vdev_param(soc, vdev_id, vdev_param, val); return status; } +/** + * hdd_conn_change_peer_state() - Change the state of the peer + * @adapter: pointer to adapter + * @roam_info: pointer to roam info + * @mac_addr: peer mac address + * @sta_state: peer state + * + * Return: QDF_STATUS enumeration + */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static QDF_STATUS hdd_conn_change_peer_state(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info, + uint8_t *mac_addr, + enum ol_txrx_peer_state sta_state) +{ + return hdd_change_peer_state(adapter, mac_addr, sta_state, + roam_info->roamSynchInProgress); +} +#else +static QDF_STATUS hdd_conn_change_peer_state(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info, + uint8_t *mac_addr, + enum ol_txrx_peer_state sta_state) +{ + return hdd_change_peer_state(adapter, mac_addr, sta_state, + false); +} +#endif + +#if defined(WLAN_SUPPORT_RX_FISA) +/** + * hdd_rx_register_fisa_ops() - FISA callback functions + * @txrx_ops: operations handle holding callback functions + * @hdd_rx_fisa_cbk: callback for fisa aggregation handle function + * @hdd_rx_fisa_flush: callback function to flush fisa aggregation + * + * Return: None + */ +static inline void +hdd_rx_register_fisa_ops(struct ol_txrx_ops *txrx_ops) +{ + txrx_ops->rx.osif_fisa_rx = hdd_rx_fisa_cbk; + txrx_ops->rx.osif_fisa_flush = hdd_rx_fisa_flush_by_ctx_id; +} +#else +static inline void +hdd_rx_register_fisa_ops(struct ol_txrx_ops *txrx_ops) +{ +} +#endif + /** * hdd_roam_register_sta() - register station * @adapter: pointer to adapter @@ -2044,21 +2300,23 @@ QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data, */ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter, struct csr_roam_info *roam_info, - uint8_t sta_id, struct bss_description *bss_desc) { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - struct ol_txrx_desc_type txrx_desc = { 0 }; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct ol_txrx_desc_type txrx_desc = {0}; struct ol_txrx_ops txrx_ops; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); if (!bss_desc) return QDF_STATUS_E_FAILURE; /* Get the Station ID from the one saved during the association */ - txrx_desc.sta_id = sta_id; + if (!QDF_IS_ADDR_BROADCAST(roam_info->bssid.bytes)) + WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, + roam_info->bssid.bytes); + else + WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, + adapter->mac_addr.bytes); /* set the QoS field appropriately */ if (hdd_wmm_is_active(adapter)) @@ -2089,27 +2347,24 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter, txrx_ops.rx.rx_flush = NULL; } - txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info; - - adapter->txrx_vdev = (void *)cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); - if (!adapter->txrx_vdev) { - return QDF_STATUS_E_FAILURE; + if (adapter->hdd_ctx->config->fisa_enable && + (adapter->device_mode != QDF_MONITOR_MODE)) { + hdd_debug("FISA feature enabled"); + hdd_rx_register_fisa_ops(&txrx_ops); } + txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info; + txrx_ops.tx.tx = NULL; - cdp_vdev_register(soc, - (struct cdp_vdev *)adapter->txrx_vdev, adapter, - (struct cdp_ctrl_objmgr_vdev *)adapter->vdev, &txrx_ops); + cdp_vdev_register(soc, adapter->vdev_id, (ol_osif_vdev_handle)adapter, + &txrx_ops); if (!txrx_ops.tx.tx) { hdd_err("%s vdev register fail", __func__); return QDF_STATUS_E_FAILURE; } adapter->tx_fn = txrx_ops.tx.tx; - qdf_status = cdp_peer_register(soc, - (struct cdp_pdev *)pdev, &txrx_desc); + qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("cdp_peer_register() failed Status: %d [0x%08X]", qdf_status, qdf_status); @@ -2121,30 +2376,23 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter, * Connections that do not need Upper layer auth, transition * TLSHIM directly to 'Authenticated' state */ - qdf_status = - hdd_change_peer_state(adapter, txrx_desc.sta_id, - OL_TXRX_PEER_STATE_AUTH, -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - roam_info->roamSynchInProgress -#else - false -#endif - ); + qdf_status = hdd_conn_change_peer_state( + adapter, roam_info, + txrx_desc.peer_addr.bytes, + OL_TXRX_PEER_STATE_AUTH); hdd_conn_set_authenticated(adapter, true); hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true); } else { - hdd_debug("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", - sta_ctx->conn_info.sta_id[0]); - qdf_status = - hdd_change_peer_state(adapter, txrx_desc.sta_id, - OL_TXRX_PEER_STATE_CONN, -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - roam_info->roamSynchInProgress -#else - false -#endif - ); + hdd_debug("ULA auth Sta: " QDF_MAC_ADDR_FMT + " Changing TL state to CONNECTED at Join time", + QDF_MAC_ADDR_REF(txrx_desc.peer_addr.bytes)); + + qdf_status = hdd_conn_change_peer_state( + adapter, roam_info, + txrx_desc.peer_addr.bytes, + OL_TXRX_PEER_STATE_CONN); + hdd_conn_set_authenticated(adapter, false); hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, false); } @@ -2276,8 +2524,6 @@ static void hdd_send_re_assoc_event(struct net_device *dev, uint8_t *final_req_ie = NULL; tCsrRoamConnectedProfile roam_profile; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - int chan_no; - int freq; qdf_mem_zero(&roam_profile, sizeof(roam_profile)); @@ -2336,14 +2582,8 @@ static void hdd_send_re_assoc_event(struct net_device *dev, qdf_mem_copy(rsp_rsn_ie, assoc_rsp, len); qdf_mem_zero(rsp_rsn_ie + len, IW_GENERIC_IE_MAX - len); - chan_no = roam_info->bss_desc->channelId; - if (chan_no <= 14) - freq = ieee80211_channel_to_frequency(chan_no, - NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency(chan_no, - NL80211_BAND_5GHZ); - chan = ieee80211_get_channel(adapter->wdev.wiphy, freq); + chan = ieee80211_get_channel(adapter->wdev.wiphy, + roam_info->bss_desc->chan_freq); sme_roam_get_connect_profile(hdd_ctx->mac_handle, adapter->vdev_id, &roam_profile); @@ -2424,89 +2664,124 @@ bool hdd_is_roam_sync_in_progress(struct csr_roam_info *roaminfo) } #endif +#ifdef QCA_IBSS_SUPPORT /** - * hdd_get_ibss_peer_sta_id() - get sta id for IBSS peer - * @hddstactx: pointer to HDD sta context - * @roaminfo: pointer to roaminfo structure + * hdd_roam_ibss_indication_handler() - update the status of the IBSS + * @adapter: pointer to adapter + * @roam_info: pointer to roam info + * @roam_id: roam id + * @roam_status: roam status + * @roam_result: roam result * - * This function returns sta_id for IBSS peer. If peer is broadcast - * MAC address return self sta_id(0) else find the peer sta id of - * the peer. + * Here we update the status of the Ibss when we receive information that we + * have started/joined an ibss session. * - * Return: sta_id (HDD_WLAN_INVALID_STA_ID if peer not found). + * Return: none */ -static uint8_t hdd_get_ibss_peer_sta_id(struct hdd_station_ctx *hddstactx, - struct csr_roam_info *roaminfo) +static void hdd_roam_ibss_indication_handler(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info, + uint32_t roam_id, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result) { - uint8_t sta_id = HDD_WLAN_INVALID_STA_ID; - QDF_STATUS status; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (qdf_is_macaddr_broadcast(&roaminfo->peerMac)) { - sta_id = 0; - } else { - status = hdd_get_peer_sta_id(hddstactx, - &roaminfo->peerMac, &sta_id); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("Unable to find station ID for " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roaminfo->peerMac.bytes)); + hdd_debug("%s: id %d, status %d, result %d", + adapter->dev->name, roam_id, + roam_status, roam_result); + + switch (roam_result) { + /* both IBSS Started and IBSS Join should come in here. */ + case eCSR_ROAM_RESULT_IBSS_STARTED: + case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS: + case eCSR_ROAM_RESULT_IBSS_COALESCED: + { + if (!roam_info) { + QDF_ASSERT(0); + return; } - } - return sta_id; -} + /* When IBSS Started comes from CSR, we need to move + * connection state to IBSS Disconnected (meaning no peers + * are in the IBSS). + */ + hdd_conn_set_connection_state(adapter, + eConnectionState_IbssDisconnected); + /* notify wmm */ + hdd_wmm_connect(adapter, roam_info, + eCSR_BSS_TYPE_IBSS); -/** - * hdd_change_sta_state_authenticated()- - * This function changes STA state to authenticated - * @adapter: pointer to the adapter structure. - * @roaminfo: pointer to the RoamInfo structure. - * - * This is called from hdd_RoamSetKeyCompleteHandler - * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw. - * - * Return: 0 on success and errno on failure - */ -static int hdd_change_sta_state_authenticated(struct hdd_adapter *adapter, - struct csr_roam_info *roaminfo) -{ - QDF_STATUS status; - uint32_t timeout, auto_bmps_timer_val; - uint8_t sta_id = HDD_WLAN_INVALID_STA_ID; - struct hdd_station_ctx *hddstactx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + hdd_roam_register_sta(adapter, roam_info, roam_info->bss_desc); - ucfg_mlme_get_auto_bmps_timer_value(hdd_ctx->psoc, - &auto_bmps_timer_val); - timeout = hddstactx->hdd_reassoc_scenario ? - AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE : - (auto_bmps_timer_val * 1000); + if (roam_info->bss_desc) { + struct cfg80211_bss *bss; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + struct ieee80211_channel *chan; +#endif + /* we created the IBSS, notify supplicant */ + hdd_debug("%s: created ibss " QDF_MAC_ADDR_FMT, + adapter->dev->name, + QDF_MAC_ADDR_REF( + roam_info->bss_desc->bssId)); - if (QDF_IBSS_MODE == adapter->device_mode) - sta_id = hdd_get_ibss_peer_sta_id(hddstactx, roaminfo); - else - sta_id = hddstactx->conn_info.sta_id[0]; + /* we must first give cfg80211 the BSS information */ + bss = wlan_hdd_cfg80211_update_bss_db(adapter, + roam_info); + if (!bss) { + hdd_err("%s: unable to create IBSS entry", + adapter->dev->name); + return; + } + hdd_debug("Enabling queues"); + wlan_hdd_netif_queue_control(adapter, + WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, + WLAN_CONTROL_PATH); - hdd_debug("Changing Peer state to AUTHENTICATED for StaId = %d", - sta_id); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + chan = ieee80211_get_channel( + adapter->wdev.wiphy, + roam_info->bss_desc->chan_freq); - /* Connections that do not need Upper layer authentication, - * transition TL to 'Authenticated' state after the keys are set - */ - status = hdd_change_peer_state(adapter, sta_id, OL_TXRX_PEER_STATE_AUTH, - hdd_is_roam_sync_in_progress(roaminfo)); - hdd_conn_set_authenticated(adapter, true); - hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true); + if (chan) + cfg80211_ibss_joined(adapter->dev, + bss->bssid, chan, + GFP_KERNEL); + else + hdd_warn("%s: freq: %d, can't find channel", + adapter->dev->name, + roam_info->bss_desc->chan_freq); +#else + cfg80211_ibss_joined(adapter->dev, bss->bssid, + GFP_KERNEL); +#endif + cfg80211_put_bss( + hdd_ctx->wiphy, + bss); + } + if (eCSR_ROAM_RESULT_IBSS_STARTED == roam_result) { + policy_mgr_incr_active_session(hdd_ctx->psoc, + adapter->device_mode, adapter->vdev_id); + hdd_green_ap_start_state_mc(hdd_ctx, + adapter->device_mode, true); + } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roam_result || + eCSR_ROAM_RESULT_IBSS_COALESCED == roam_result) { + policy_mgr_update_connection_info(hdd_ctx->psoc, + adapter->vdev_id); + } + break; + } - if ((QDF_STA_MODE == adapter->device_mode) || - (QDF_P2P_CLIENT_MODE == adapter->device_mode)) { - sme_ps_enable_auto_ps_timer(hdd_ctx->mac_handle, - adapter->vdev_id, - timeout); + case eCSR_ROAM_RESULT_IBSS_START_FAILED: + { + hdd_err("%s: unable to create IBSS", adapter->dev->name); + break; } - return qdf_status_to_os_return(status); + default: + hdd_err("%s: unexpected result %d", + adapter->dev->name, (int)roam_result); + break; + } } /** @@ -2529,6 +2804,114 @@ static inline bool hdd_is_key_install_required_for_ibss( else return false; } +#else +/** + * hdd_roam_ibss_indication_handler() - update the status of the IBSS + * @adapter: pointer to adapter + * @roam_info: pointer to roam info + * @roam_id: roam id + * @roam_status: roam status + * @roam_result: roam result + * + * This function is dummy + * + * Return: none + */ +static inline void +hdd_roam_ibss_indication_handler(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info, + uint32_t roam_id, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result) +{ +} + +/** + * hdd_get_ibss_peer_sta_id() - get sta id for IBSS peer + * @hddstactx: pointer to HDD sta context + * @roaminfo: pointer to roaminfo structure + * + * This function is dummy + * + * Return: WLAN_MAX_STA_COUNT if peer not found. + */ +static inline uint8_t +hdd_get_ibss_peer_sta_id(struct hdd_station_ctx *hddstactx, + struct csr_roam_info *roaminfo) +{ + return WLAN_MAX_STA_COUNT; +} + +/** + * hdd_is_key_install_required_for_ibss() - check encryption type to identify + * if key installation is required + * @encr_type: encryption type + * + * This function is dummy + * + * Return: true. + */ +static inline bool +hdd_is_key_install_required_for_ibss(eCsrEncryptionType encr_type) +{ + return true; +} +#endif + +/** + * hdd_change_sta_state_authenticated()- + * This function changes STA state to authenticated + * @adapter: pointer to the adapter structure. + * @roaminfo: pointer to the RoamInfo structure. + * + * This is called from hdd_RoamSetKeyCompleteHandler + * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw. + * + * Return: 0 on success and errno on failure + */ +static int hdd_change_sta_state_authenticated(struct hdd_adapter *adapter, + struct csr_roam_info *roaminfo) +{ + QDF_STATUS status; + uint8_t *mac_addr; + uint32_t timeout, auto_bmps_timer_val; + struct hdd_station_ctx *hddstactx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + ucfg_mlme_get_auto_bmps_timer_value(hdd_ctx->psoc, + &auto_bmps_timer_val); + timeout = hddstactx->hdd_reassoc_scenario ? + AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE : + (auto_bmps_timer_val * 1000); + + if (QDF_IBSS_MODE == adapter->device_mode) + mac_addr = roaminfo->peerMac.bytes; + else + mac_addr = hddstactx->conn_info.bssid.bytes; + + hdd_debug("Changing Peer state to AUTHENTICATED for Sta = " + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); + + /* Connections that do not need Upper layer authentication, + * transition TL to 'Authenticated' state after the keys are set + */ + + status = hdd_change_peer_state(adapter, mac_addr, + OL_TXRX_PEER_STATE_AUTH, + hdd_is_roam_sync_in_progress(roaminfo)); + hdd_conn_set_authenticated(adapter, true); + hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true); + + if ((QDF_STA_MODE == adapter->device_mode) || + (QDF_P2P_CLIENT_MODE == adapter->device_mode)) { + sme_ps_enable_auto_ps_timer(hdd_ctx->mac_handle, + adapter->vdev_id, + timeout); + } + + return qdf_status_to_os_return(status); +} /** * hdd_change_peer_state_after_set_key() - change the peer state on set key @@ -2638,8 +3021,8 @@ hdd_roam_set_key_complete_handler(struct hdd_adapter *adapter, * directly into 'authenticated' state. */ hdd_debug("Set Key completion roam_status =%d roam_result=%d " - QDF_MAC_ADDR_STR, roam_status, roam_result, - QDF_MAC_ADDR_ARRAY(roam_info->peerMac.bytes)); + QDF_MAC_ADDR_FMT, roam_status, roam_result, + QDF_MAC_ADDR_REF(roam_info->peerMac.bytes)); connected = hdd_conn_get_connected_cipher_algo(sta_ctx, &algorithm); @@ -2658,40 +3041,6 @@ hdd_roam_set_key_complete_handler(struct hdd_adapter *adapter, return QDF_STATUS_SUCCESS; } -/** - * hdd_perform_roam_set_key_complete() - perform set key complete - * @adapter: pointer to adapter - * - * Return: none - */ -void hdd_perform_roam_set_key_complete(struct hdd_adapter *adapter) -{ - QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct csr_roam_info *roam_info; - - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - roam_info->fAuthRequired = false; - qdf_mem_copy(roam_info->bssid.bytes, - sta_ctx->roam_info.bssid, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(roam_info->peerMac.bytes, - sta_ctx->roam_info.peer_mac, QDF_MAC_ADDR_SIZE); - - qdf_ret_status = - hdd_roam_set_key_complete_handler(adapter, - roam_info, - sta_ctx->roam_info.roam_id, - sta_ctx->roam_info.roam_status, - eCSR_ROAM_RESULT_AUTHENTICATED); - if (qdf_ret_status != QDF_STATUS_SUCCESS) - hdd_err("Set Key complete failure"); - - sta_ctx->roam_info.defer_key_complete = false; - qdf_mem_free(roam_info); -} - #if defined(WLAN_FEATURE_FILS_SK) && \ (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) @@ -2717,6 +3066,45 @@ void hdd_clear_fils_connection_info(struct hdd_adapter *adapter) } #endif +/** + * hdd_netif_queue_enable() - Enable the network queue for a + * particular adapter. + * @adapter: pointer to the adapter structure + * + * This function schedules a work to update the netdev features + * and enable the network queue if the feature "disable checksum/tso + * for legacy connections" is enabled via INI. If not, it will + * retain the existing behavior by just enabling the network queues. + * + * Returns: none + */ +static inline void hdd_netif_queue_enable(struct hdd_adapter *adapter) +{ + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + if (cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) { + hdd_adapter_ops_record_event(hdd_ctx, + WLAN_HDD_ADAPTER_OPS_WORK_POST, + adapter->vdev_id); + qdf_queue_work(0, hdd_ctx->adapter_ops_wq, + &adapter->netdev_features_update_work); + } else { + wlan_hdd_netif_queue_control(adapter, + WLAN_WAKE_ALL_NETIF_QUEUE, + WLAN_CONTROL_PATH); + } +} + +static void hdd_save_connect_status(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info) +{ + if (!roam_info) + return; + + adapter->connect_req_status = roam_info->reasonCode; +} + /** * hdd_association_completion_handler() - association completion handler * @adapter: pointer to adapter @@ -2737,6 +3125,7 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, struct net_device *dev = adapter->dev; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + int8_t snr = 0; QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; uint8_t *reqRsnIe; uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN, ie_len; @@ -2746,6 +3135,7 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, tSirResultCodes timeout_reason = 0; bool ok; mac_handle_t mac_handle; + uint32_t conn_info_freq; void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!hdd_ctx) { @@ -2759,6 +3149,24 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, return QDF_STATUS_E_NULL_VALUE; } + hdd_get_rssi_snr_by_bssid(adapter, sta_ctx->conn_info.bssid.bytes, + &adapter->rssi, &snr); + + /* If RSSi is reported as positive then it is invalid */ + if (adapter->rssi > 0) { + hdd_debug_rl("RSSI invalid %d", adapter->rssi); + adapter->rssi = 0; + } + + hdd_debug("snr: %d, rssi: %d", snr, adapter->rssi); + + sta_ctx->conn_info.signal = adapter->rssi; + sta_ctx->conn_info.noise = + sta_ctx->conn_info.signal - snr; + sta_ctx->cache_conn_info.signal = sta_ctx->conn_info.signal; + sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise; + + hdd_save_connect_status(adapter, roam_info); /* * reset scan reject params if connection is success or we received * final failure from CSR after trying with all APs. @@ -2891,15 +3299,10 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, sta_ctx->ft_carrier_on = false; ft_carrier_on = true; } - if (roam_info->staId < HDD_MAX_ADAPTERS) - hdd_ctx->sta_to_adapter[roam_info->staId] = adapter; - else - hdd_err("Wrong Staid: %d", roam_info->staId); if (ucfg_ipa_is_enabled()) ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, adapter->device_mode, - roam_info->staId, adapter->vdev_id, WLAN_IPA_STA_CONNECT, roam_info->bssid.bytes); @@ -2908,17 +3311,18 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, wlan_hdd_auto_shutdown_enable(hdd_ctx, false); #endif + conn_info_freq = sta_ctx->conn_info.chan_freq; + if (policy_mgr_is_chan_ok_for_dnbs(hdd_ctx->psoc, - sta_ctx->conn_info.channel, - &ok)) { - hdd_err("Unable to check DNBS eligibility for chan:%d", - sta_ctx->conn_info.channel); + conn_info_freq, &ok)) { + hdd_err("Unable to check DNBS eligibility for chan(freq):%u", + sta_ctx->conn_info.chan_freq); return QDF_STATUS_E_FAILURE; } if (!ok) { - hdd_err("Chan:%d not suitable for DNBS", - sta_ctx->conn_info.channel); + hdd_err("Chan(freq):%u not suitable for DNBS", + sta_ctx->conn_info.chan_freq); wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_OFF, WLAN_CONTROL_PATH); @@ -2943,6 +3347,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, if (!reqRsnIe) return QDF_STATUS_E_NOMEM; + if (roam_info->fReassocReq || ft_carrier_on) + hdd_nud_indicate_roam(adapter); + /* * For reassoc, the station is already registered, all we need * is to change the state of the STA in TL. @@ -2960,8 +3367,11 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, uint8_t *rsp_rsn_ie = qdf_mem_malloc(sizeof(uint8_t) * DOT11F_IE_RSN_MAX_LEN); - if (!rsp_rsn_ie) + if (!rsp_rsn_ie) { + qdf_mem_free(reqRsnIe); return QDF_STATUS_E_NOMEM; + } + /* add bss_id to cfg80211 data base */ bss = @@ -3081,11 +3491,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, } hdd_debug("ft_carrier_on is %d, sending roamed indication", ft_carrier_on); - chan = - ieee80211_get_channel - (adapter->wdev.wiphy, - (int)roam_info->bss_desc-> - channelId); + chan = ieee80211_get_channel( + adapter->wdev.wiphy, + roam_info->bss_desc->chan_freq); roam_bss = wlan_cfg80211_get_bss( @@ -3098,9 +3506,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, pConnectedProfile->SSID.length); cdp_hl_fc_set_td_limit(soc, - adapter->vdev_id, - sta_ctx-> - conn_info.channel); + adapter->vdev_id, + conn_info_freq); hdd_send_roamed_ind( dev, @@ -3118,37 +3525,12 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, assoc_rsp_len, roam_info); } - if (sme_get_ftptk_state - (mac_handle, - adapter->vdev_id)) { - sme_set_ftptk_state - (mac_handle, - adapter->vdev_id, - false); - roam_info->fAuthRequired = - false; - - qdf_mem_copy(sta_ctx-> - roam_info.bssid, - roam_info->bssid.bytes, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(sta_ctx-> - roam_info.peer_mac, - roam_info->peerMac.bytes, - QDF_MAC_ADDR_SIZE); - sta_ctx->roam_info.roam_id = - roam_id; - sta_ctx->roam_info.roam_status = - roam_status; - sta_ctx->roam_info. - defer_key_complete = true; - } } else if (!hddDisconInProgress) { hdd_debug("ft_carrier_on is %d, sending connect indication", ft_carrier_on); cdp_hl_fc_set_td_limit(soc, - adapter->vdev_id, - sta_ctx->conn_info.channel); + adapter->vdev_id, + conn_info_freq); hdd_connect_result(dev, roam_info-> bssid.bytes, @@ -3185,9 +3567,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, reqRsnLength); else { hdd_debug("sending connect indication to nl80211:for bssid " - QDF_MAC_ADDR_STR + QDF_MAC_ADDR_FMT " result:%d and Status:%d", - QDF_MAC_ADDR_ARRAY + QDF_MAC_ADDR_REF (roam_info->bssid.bytes), roam_result, roam_status); @@ -3206,8 +3588,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, roam_info->status_code); } cdp_hl_fc_set_td_limit(soc, - adapter->vdev_id, - sta_ctx->conn_info.channel); + adapter->vdev_id, + conn_info_freq); } } if (!hddDisconInProgress) { @@ -3223,13 +3605,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, */ qdf_status = hdd_roam_register_sta(adapter, roam_info, - sta_ctx->conn_info.sta_id[0], roam_info->bss_desc); hdd_debug("Enabling queues"); - wlan_hdd_netif_queue_control(adapter, - WLAN_WAKE_ALL_NETIF_QUEUE, - WLAN_CONTROL_PATH); - + hdd_netif_queue_enable(adapter); } qdf_mem_free(rsp_rsn_ie); } else { @@ -3243,16 +3621,15 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, adapter->vdev_id, &reqRsnLength, reqRsnIe); - cdp_hl_fc_set_td_limit(soc, - adapter->vdev_id, - sta_ctx->conn_info.channel); + cdp_hl_fc_set_td_limit(soc, adapter->vdev_id, + conn_info_freq); hdd_send_re_assoc_event(dev, adapter, roam_info, reqRsnIe, reqRsnLength); /* Reassoc successfully */ if (roam_info->fAuthRequired) { qdf_status = hdd_change_peer_state(adapter, - sta_ctx->conn_info.sta_id[0], + roam_info->bssid.bytes, OL_TXRX_PEER_STATE_CONN, #ifdef WLAN_FEATURE_ROAM_OFFLOAD roam_info->roamSynchInProgress @@ -3265,11 +3642,13 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, adapter->vdev, false); } else { - hdd_debug("sta_id: %d Changing TL state to AUTHENTICATED", - sta_ctx->conn_info.sta_id[0]); + hdd_debug("sta: " QDF_MAC_ADDR_FMT + "Changing TL state to AUTHENTICATED", + QDF_MAC_ADDR_REF( + roam_info->bssid.bytes)); qdf_status = hdd_change_peer_state(adapter, - sta_ctx->conn_info.sta_id[0], + roam_info->bssid.bytes, OL_TXRX_PEER_STATE_AUTH, #ifdef WLAN_FEATURE_ROAM_OFFLOAD roam_info->roamSynchInProgress @@ -3298,9 +3677,7 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, hdd_debug("LFR3:netif_tx_wake_all_queues"); #endif hdd_debug("Enabling queues"); - wlan_hdd_netif_queue_control(adapter, - WLAN_WAKE_ALL_NETIF_QUEUE, - WLAN_CONTROL_PATH); + hdd_netif_queue_enable(adapter); } qdf_mem_free(reqRsnIe); @@ -3323,23 +3700,21 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, hdd_ctx->psoc); } else { bool connect_timeout = false; - /* do we need to change the HW mode */ - policy_mgr_check_n_start_opportunistic_timer(hdd_ctx->psoc); if (roam_info && roam_info->is_fils_connection && eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roam_result) qdf_copy_macaddr(&roam_info->bssid, &sta_ctx->requested_bssid); if (roam_info) - hdd_err("%s(vdevid-%d): connection failed with " QDF_MAC_ADDR_STR + hdd_err("%s(vdevid-%d): connection failed with " QDF_MAC_ADDR_FMT " result: %d and Status: %d", dev->name, adapter->vdev_id, - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes), + QDF_MAC_ADDR_REF(roam_info->bssid.bytes), roam_result, roam_status); else - hdd_err("%s(vdevid-%d): connection failed with " QDF_MAC_ADDR_STR + hdd_err("%s(vdevid-%d): connection failed with " QDF_MAC_ADDR_FMT " result: %d and Status: %d", dev->name, adapter->vdev_id, - QDF_MAC_ADDR_ARRAY(sta_ctx->requested_bssid.bytes), + QDF_MAC_ADDR_REF(sta_ctx->requested_bssid.bytes), roam_result, roam_status); if ((eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roam_result) || @@ -3402,22 +3777,22 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, roam_info->nAssocRspLength); } hdd_err("send connect failure to nl80211: for bssid " - QDF_MAC_ADDR_STR + QDF_MAC_ADDR_FMT " result: %d and Status: %d reasoncode: %d", - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes), + QDF_MAC_ADDR_REF(roam_info->bssid.bytes), roam_result, roam_status, roam_info->reasonCode); sta_ctx->conn_info.assoc_status_code = roam_info->status_code; } else { hdd_err("connect failed: for bssid " - QDF_MAC_ADDR_STR + QDF_MAC_ADDR_FMT " result: %d and status: %d ", - QDF_MAC_ADDR_ARRAY(sta_ctx->requested_bssid.bytes), + QDF_MAC_ADDR_REF(sta_ctx->requested_bssid.bytes), roam_result, roam_status); } hdd_debug("Invoking packetdump deregistration API"); - wlan_deregister_txrx_packetdump(); + wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); /* inform association failure event to nl80211 */ if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == @@ -3478,12 +3853,14 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, timeout_reason); } - /* Check to change TDLS state in FW - * as connection failed. - */ if (roam_status == eCSR_ROAM_ASSOCIATION_FAILURE || roam_status == eCSR_ROAM_CANCELLED) { + /* notify connect faiilure on final failure */ ucfg_tdls_notify_connect_failure(hdd_ctx->psoc); + /* do we need to change the HW mode on final failure */ + policy_mgr_check_n_start_opportunistic_timer( + hdd_ctx->psoc); + /* * Enable roaming on other STA iface except this one. * Firmware dosent support connection on one STA iface @@ -3539,191 +3916,35 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, return QDF_STATUS_SUCCESS; } -/** - * hdd_roam_ibss_indication_handler() - update the status of the IBSS - * @adapter: pointer to adapter - * @roam_info: pointer to roam info - * @roam_id: roam id - * @roam_status: roam status - * @roam_result: roam result - * - * Here we update the status of the Ibss when we receive information that we - * have started/joined an ibss session. - * - * Return: none - */ -static void hdd_roam_ibss_indication_handler(struct hdd_adapter *adapter, - struct csr_roam_info *roam_info, - uint32_t roam_id, - eRoamCmdStatus roam_status, - eCsrRoamResult roam_result) -{ - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - hdd_debug("%s: id %d, status %d, result %d", - adapter->dev->name, roam_id, - roam_status, roam_result); - - switch (roam_result) { - /* both IBSS Started and IBSS Join should come in here. */ - case eCSR_ROAM_RESULT_IBSS_STARTED: - case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS: - case eCSR_ROAM_RESULT_IBSS_COALESCED: - { - struct hdd_station_ctx *hdd_sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - - if (!roam_info) { - QDF_ASSERT(0); - return; - } - - /* When IBSS Started comes from CSR, we need to move - * connection state to IBSS Disconnected (meaning no peers - * are in the IBSS). - */ - hdd_conn_set_connection_state(adapter, - eConnectionState_IbssDisconnected); - /* notify wmm */ - hdd_wmm_connect(adapter, roam_info, - eCSR_BSS_TYPE_IBSS); - - hdd_sta_ctx->broadcast_sta_id = roam_info->staId; - - if (roam_info->staId < HDD_MAX_ADAPTERS) - hdd_ctx->sta_to_adapter[roam_info->staId] = - adapter; - else - hdd_debug("invalid sta id %d", roam_info->staId); - - hdd_roam_register_sta(adapter, roam_info, - roam_info->staId, - roam_info->bss_desc); - - if (roam_info->bss_desc) { - struct cfg80211_bss *bss; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) - struct ieee80211_channel *chan; - int chan_no; - unsigned int freq; -#endif - /* we created the IBSS, notify supplicant */ - hdd_debug("%s: created ibss " QDF_MAC_ADDR_STR, - adapter->dev->name, - QDF_MAC_ADDR_ARRAY( - roam_info->bss_desc->bssId)); - - /* we must first give cfg80211 the BSS information */ - bss = wlan_hdd_cfg80211_update_bss_db(adapter, - roam_info); - if (!bss) { - hdd_err("%s: unable to create IBSS entry", - adapter->dev->name); - return; - } - hdd_debug("Enabling queues"); - wlan_hdd_netif_queue_control(adapter, - WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, - WLAN_CONTROL_PATH); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) - chan_no = roam_info->bss_desc->channelId; - - if (chan_no <= 14) - freq = ieee80211_channel_to_frequency(chan_no, - HDD_NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency(chan_no, - HDD_NL80211_BAND_5GHZ); - - chan = ieee80211_get_channel(adapter->wdev.wiphy, freq); - - if (chan) - cfg80211_ibss_joined(adapter->dev, - bss->bssid, chan, - GFP_KERNEL); - else - hdd_warn("%s: chanId: %d, can't find channel", - adapter->dev->name, - (int)roam_info->bss_desc->channelId); -#else - cfg80211_ibss_joined(adapter->dev, bss->bssid, - GFP_KERNEL); -#endif - cfg80211_put_bss( - hdd_ctx->wiphy, - bss); - } - if (eCSR_ROAM_RESULT_IBSS_STARTED == roam_result) { - policy_mgr_incr_active_session(hdd_ctx->psoc, - adapter->device_mode, adapter->vdev_id); - hdd_green_ap_start_state_mc(hdd_ctx, - adapter->device_mode, true); - } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roam_result || - eCSR_ROAM_RESULT_IBSS_COALESCED == roam_result) { - policy_mgr_update_connection_info(hdd_ctx->psoc, - adapter->vdev_id); - } - break; - } - - case eCSR_ROAM_RESULT_IBSS_START_FAILED: - { - hdd_err("%s: unable to create IBSS", adapter->dev->name); - break; - } - - default: - hdd_err("%s: unexpected result %d", - adapter->dev->name, (int)roam_result); - break; - } -} - -/** - * hdd_save_peer() - Save peer MAC address in adapter peer table. - * @sta_ctx: pointer to hdd station context - * @sta_id: station ID - * @peer_mac_addr: mac address of new peer - * - * This information is passed to iwconfig later. The peer that joined - * last is passed as information to iwconfig. - - * Return: true if success, false otherwise - */ -bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id, +bool hdd_save_peer(struct hdd_station_ctx *sta_ctx, struct qdf_mac_addr *peer_mac_addr) { int idx; + struct qdf_mac_addr *mac_addr; for (idx = 0; idx < MAX_PEERS; idx++) { - if (HDD_WLAN_INVALID_STA_ID == sta_ctx->conn_info.sta_id[idx]) { - hdd_debug("adding peer: %pM, sta_id: %d, at idx: %d", - peer_mac_addr, sta_id, idx); - sta_ctx->conn_info.sta_id[idx] = sta_id; - qdf_copy_macaddr( - &sta_ctx->conn_info.peer_macaddr[idx], - peer_mac_addr); + mac_addr = &sta_ctx->conn_info.peer_macaddr[idx]; + if (qdf_is_macaddr_zero(mac_addr)) { + hdd_debug("adding peer: "QDF_MAC_ADDR_FMT" at idx: %d", + QDF_MAC_ADDR_REF(peer_mac_addr->bytes), idx); + qdf_copy_macaddr(mac_addr, peer_mac_addr); return true; } } + return false; } -/** - * hdd_delete_peer() - removes peer from hdd station context peer table - * @sta_ctx: pointer to hdd station context - * @sta_id: station ID - * - * Return: None - */ -void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, uint8_t sta_id) +void hdd_delete_peer(struct hdd_station_ctx *sta_ctx, + struct qdf_mac_addr *peer_mac_addr) { int i; + struct qdf_mac_addr *mac_addr; for (i = 0; i < MAX_PEERS; i++) { - if (sta_id == sta_ctx->conn_info.sta_id[i]) { - sta_ctx->conn_info.sta_id[i] = HDD_WLAN_INVALID_STA_ID; + mac_addr = &sta_ctx->conn_info.peer_macaddr[i]; + if (qdf_is_macaddr_equal(mac_addr, peer_mac_addr)) { + qdf_zero_macaddr(mac_addr); return; } } @@ -3739,8 +3960,8 @@ bool hdd_any_valid_peer_present(struct hdd_adapter *adapter) mac_addr = &sta_ctx->conn_info.peer_macaddr[i]; if (!qdf_is_macaddr_zero(mac_addr) && !qdf_is_macaddr_broadcast(mac_addr)) { - hdd_debug("peer: index: %u " QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY(mac_addr->bytes)); + hdd_debug("peer: index: %u " QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(mac_addr->bytes)); return true; } } @@ -3758,7 +3979,7 @@ bool hdd_any_valid_peer_present(struct hdd_adapter *adapter) * false otherwise. */ static bool roam_remove_ibss_station(struct hdd_adapter *adapter, - uint8_t sta_id) + uint8_t *mac_addr) { bool successful = false; int idx = 0; @@ -3768,12 +3989,9 @@ static bool roam_remove_ibss_station(struct hdd_adapter *adapter, struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); for (idx = 0; idx < MAX_PEERS; idx++) { - if (sta_id == sta_ctx->conn_info.sta_id[idx]) { - sta_ctx->conn_info.sta_id[idx] = - HDD_WLAN_INVALID_STA_ID; - - qdf_zero_macaddr(&sta_ctx->conn_info. - peer_macaddr[idx]); + if (WLAN_ADDR_EQ(mac_addr, + sta_ctx->conn_info.peer_macaddr[idx].bytes)) { + qdf_zero_macaddr(&sta_ctx->conn_info.peer_macaddr[idx]); successful = true; @@ -3785,13 +4003,11 @@ static bool roam_remove_ibss_station(struct hdd_adapter *adapter, empty_slots++; } else { - if (sta_ctx->conn_info.sta_id[idx] != - HDD_WLAN_INVALID_STA_ID) { + if (hdd_is_valid_mac_address( + sta_ctx->conn_info.peer_macaddr[idx].bytes)) valid_idx = idx; - } else { - /* Found an empty slot */ + else empty_slots++; - } } } @@ -3804,17 +4020,13 @@ static bool roam_remove_ibss_station(struct hdd_adapter *adapter, /* Find next active sta_id, to have a valid sta trigger for TL. */ if (successful) { if (del_idx == 0) { - if (sta_ctx->conn_info.sta_id[valid_idx] != - HDD_WLAN_INVALID_STA_ID) { - sta_ctx->conn_info.sta_id[0] = - sta_ctx->conn_info.sta_id[valid_idx]; + if (hdd_is_valid_mac_address( + sta_ctx->conn_info.peer_macaddr[valid_idx].bytes)) { qdf_copy_macaddr(&sta_ctx->conn_info. peer_macaddr[0], &sta_ctx->conn_info. peer_macaddr[valid_idx]); - sta_ctx->conn_info.sta_id[valid_idx] = - HDD_WLAN_INVALID_STA_ID; qdf_zero_macaddr(&sta_ctx->conn_info. peer_macaddr[valid_idx]); } @@ -3894,7 +4106,6 @@ hdd_roam_mic_error_indication_handler(struct hdd_adapter *adapter, GFP_KERNEL); } -#ifdef CRYPTO_SET_KEY_CONVERGED static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, uint32_t *roam_id) { @@ -3905,7 +4116,8 @@ static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, if (!vdev) return QDF_STATUS_E_FAILURE; ret = wlan_cfg80211_crypto_add_key(vdev, - WLAN_CRYPTO_KEY_TYPE_UNICAST, 0); + WLAN_CRYPTO_KEY_TYPE_UNICAST, 0, + false); hdd_objmgr_put_vdev(vdev); if (ret != 0) { hdd_err("crypto add key fail, status: %d", ret); @@ -3914,20 +4126,6 @@ static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, return QDF_STATUS_SUCCESS; } -#else -static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter, - uint32_t *roam_id) -{ - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - return sme_roam_set_key(hdd_ctx->mac_handle, - adapter->vdev_id, - &sta_ctx->ibss_enc_key, - roam_id); -} -#endif /** * roam_roam_connect_status_update_handler() - IBSS connect status update @@ -3948,7 +4146,6 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, eRoamCmdStatus roam_status, eCsrRoamResult roam_result) { - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct wlan_objmgr_vdev *vdev; QDF_STATUS qdf_status; @@ -3961,32 +4158,25 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, eCsrEncryptionType encr_type = sta_ctx->ibss_enc_key.encType; hdd_debug("IBSS New Peer indication from SME " - "with peerMac " QDF_MAC_ADDR_STR " BSSID: " - QDF_MAC_ADDR_STR " and stationID= %d", - QDF_MAC_ADDR_ARRAY(roam_info->peerMac.bytes), - QDF_MAC_ADDR_ARRAY(sta_ctx->conn_info.bssid.bytes), + "with peerMac " QDF_MAC_ADDR_FMT " BSSID: " + QDF_MAC_ADDR_FMT " and stationID= %d", + QDF_MAC_ADDR_REF(roam_info->peerMac.bytes), + QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes), roam_info->staId); if (!hdd_save_peer (WLAN_HDD_GET_STATION_CTX_PTR(adapter), - roam_info->staId, &roam_info->peerMac)) { hdd_warn("Max reached: Can't register new IBSS peer"); break; } - if (roam_info->staId < HDD_MAX_ADAPTERS) - hdd_ctx->sta_to_adapter[roam_info->staId] = adapter; - else - hdd_debug("invalid sta id %d", roam_info->staId); - if (hdd_is_key_install_required_for_ibss(encr_type)) roam_info->fAuthRequired = true; /* Register the Station with datapath for the new peer. */ qdf_status = hdd_roam_register_sta(adapter, roam_info, - roam_info->staId, roam_info->bss_desc); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("Cannot register STA for IBSS. qdf_status: %d [%08X]", @@ -4045,21 +4235,17 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - if (!roam_remove_ibss_station(adapter, roam_info->staId)) + if (!roam_remove_ibss_station(adapter, + roam_info->peerMac.bytes)) hdd_warn("IBSS peer departed by cannot find peer in our registration table with TL"); hdd_debug("IBSS Peer Departed from SME " - "with peerMac " QDF_MAC_ADDR_STR " BSSID: " - QDF_MAC_ADDR_STR " and stationID= %d", - QDF_MAC_ADDR_ARRAY(roam_info->peerMac.bytes), - QDF_MAC_ADDR_ARRAY(sta_ctx->conn_info.bssid.bytes), + "with peerMac " QDF_MAC_ADDR_FMT " BSSID: " + QDF_MAC_ADDR_FMT " and stationID= %d", + QDF_MAC_ADDR_REF(roam_info->peerMac.bytes), + QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes), roam_info->staId); - if (roam_info->staId < HDD_MAX_ADAPTERS) - hdd_ctx->sta_to_adapter[roam_info->staId] = NULL; - else - hdd_debug("invalid sta id %d", roam_info->staId); - sta_ctx->ibss_sta_generation++; cfg80211_del_sta(adapter->dev, @@ -4092,21 +4278,18 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter, #ifdef FEATURE_WLAN_TDLS QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, - const uint8_t *peerMac, uint16_t sta_id, - uint8_t qos) + const uint8_t *peerMac, uint8_t qos) { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; struct ol_txrx_desc_type txrx_desc = { 0 }; struct ol_txrx_ops txrx_ops; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_vdev *txrx_vdev; /* * TDLS sta in BSS should be set as STA type TDLS and STA MAC should * be peer MAC, here we are working on direct Link */ - txrx_desc.sta_id = sta_id; + WLAN_ADDR_COPY(txrx_desc.peer_addr.bytes, peerMac); /* set the QoS field appropriately .. */ txrx_desc.is_qos_enabled = qos; @@ -4123,22 +4306,13 @@ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, txrx_ops.rx.rx_stack = NULL; txrx_ops.rx.rx_flush = NULL; } - txrx_vdev = cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); - if (!txrx_vdev) - return QDF_STATUS_E_FAILURE; - - cdp_vdev_register(soc, txrx_vdev, - adapter, - (struct cdp_ctrl_objmgr_vdev *)adapter->vdev, + cdp_vdev_register(soc, adapter->vdev_id, (ol_osif_vdev_handle)adapter, &txrx_ops); adapter->tx_fn = txrx_ops.tx.tx; txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info; /* Register the Station with TL... */ - qdf_status = cdp_peer_register(soc, - (struct cdp_pdev *)pdev, &txrx_desc); + qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("cdp_peer_register() failed Status: %d [0x%08X]", qdf_status, qdf_status); @@ -4148,33 +4322,6 @@ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, return qdf_status; } -/** - * hdd_roam_deregister_tdlssta() - deregister new TDLS station - * @adapter: pointer to adapter - * @sta_id: station identifier - * - * Return: QDF_STATUS enumeration - */ -QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter, - uint8_t sta_id) -{ - QDF_STATUS qdf_status; - - qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX), - sta_id); - - return qdf_status; -} - -#else - -inline QDF_STATUS hdd_roam_deregister_tdlssta(struct hdd_adapter *adapter, - uint8_t sta_id) -{ - return QDF_STATUS_SUCCESS; -} - #endif #ifdef WLAN_FEATURE_11W @@ -4334,8 +4481,8 @@ hdd_indicate_cckm_pre_auth(struct hdd_adapter *adapter, memset(buf, '\0', sizeof(buf)); /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */ - hdd_debug("CCXPREAUTHNOTIFY=" QDF_MAC_ADDR_STR " %d:%d", - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes), + hdd_debug("CCXPREAUTHNOTIFY=" QDF_MAC_ADDR_FMT " %d:%d", + QDF_MAC_ADDR_REF(roam_info->bssid.bytes), roam_info->timestamp[0], roam_info->timestamp[1]); nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY="); @@ -4669,6 +4816,7 @@ hdd_is_8021x_sha256_auth_type(struct hdd_station_ctx *sta_ctx) { return false; } + #endif /* @@ -4696,14 +4844,14 @@ static void hdd_roam_channel_switch_handler(struct hdd_adapter *adapter, REASON_DRIVER_ENABLED, RSO_CHANNEL_SWITCH); - chan_change.chan = roam_info->chan_info.chan_id; + chan_change.chan_freq = roam_info->chan_info.mhz; chan_change.chan_params.ch_width = roam_info->chan_info.ch_width; chan_change.chan_params.sec_ch_offset = roam_info->chan_info.sec_ch_offset; - chan_change.chan_params.center_freq_seg0 = + chan_change.chan_params.mhz_freq_seg0 = roam_info->chan_info.band_center_freq1; - chan_change.chan_params.center_freq_seg1 = + chan_change.chan_params.mhz_freq_seg1 = roam_info->chan_info.band_center_freq2; bss = wlan_hdd_cfg80211_update_bss_db(adapter, roam_info); @@ -5322,15 +5470,22 @@ bool hdd_is_fils_connection(struct hdd_adapter *adapter) * * Return: 0 on success, error number otherwise */ +#ifdef WLAN_FEATURE_11W static int32_t hdd_process_genie(struct hdd_adapter *adapter, u8 *bssid, eCsrEncryptionType *encrypt_type, eCsrEncryptionType *mc_encrypt_type, enum csr_akm_type *auth_type, -#ifdef WLAN_FEATURE_11W uint8_t *mfp_required, uint8_t *mfp_capable, -#endif uint16_t gen_ie_len, uint8_t *gen_ie) +#else +static int32_t hdd_process_genie(struct hdd_adapter *adapter, + u8 *bssid, + eCsrEncryptionType *encrypt_type, + eCsrEncryptionType *mc_encrypt_type, + enum csr_akm_type *auth_type, + uint16_t gen_ie_len, uint8_t *gen_ie) +#endif { mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); tDot11fIERSN dot11_rsn_ie = {0}; @@ -5338,9 +5493,7 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter, uint8_t *rsn_ie; uint16_t rsn_ie_len; uint32_t parse_status; -#ifdef WLAN_CONV_CRYPTO_SUPPORTED uint16_t rsn_cap = 0; -#endif /* * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically @@ -5387,11 +5540,9 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter, *mfp_required = (dot11_rsn_ie.RSN_Cap[0] >> 6) & 0x1; *mfp_capable = csr_is_mfpc_capable(&dot11_rsn_ie); #endif -#ifdef WLAN_CONV_CRYPTO_SUPPORTED qdf_mem_copy(&rsn_cap, dot11_rsn_ie.RSN_Cap, sizeof(rsn_cap)); wlan_crypto_set_vdev_param(adapter->vdev, WLAN_CRYPTO_PARAM_RSN_CAP, rsn_cap); -#endif } else if (gen_ie[0] == DOT11F_EID_WPA) { /* Validity checks */ if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) || @@ -5433,6 +5584,25 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter, return 0; } +#ifdef WLAN_FEATURE_11W +/** + * hdd_set_def_mfp_cap: Set default value for MFPCapable + * @profile: Source profile + * + * Return: None + */ +static void hdd_set_def_mfp_cap( + struct csr_roam_profile *roam_profile) +{ + roam_profile->MFPCapable = roam_profile->MFPEnabled; +} +#else +static void hdd_set_def_mfp_cap( + struct csr_roam_profile *roam_profile) +{ +} +#endif + /** * hdd_set_def_rsne_override() - set default encryption type and auth type * in profile. @@ -5449,9 +5619,8 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter, static void hdd_set_def_rsne_override( struct csr_roam_profile *roam_profile, enum csr_akm_type *auth_type) { - hdd_debug("Set def values in roam profile"); - roam_profile->MFPCapable = roam_profile->MFPEnabled; + hdd_set_def_mfp_cap(roam_profile); roam_profile->EncryptionType.numEntries = 2; roam_profile->mcEncryptionType.numEntries = 2; /* Use the cipher type in the RSN IE */ @@ -5464,6 +5633,95 @@ static void hdd_set_def_rsne_override( *auth_type = eCSR_AUTH_TYPE_RSN_PSK; } +#ifdef WLAN_FEATURE_11W +/** + * hdd_update_values_mfp_cap: Update values for MFPCapable,MFPEnabled + * @profile: Source profile + * + * Return: None + */ +static void hdd_update_values_mfp_cap( + struct csr_roam_profile *roam_profile, + uint8_t mfp_required, uint8_t mfp_capable ) +{ + hdd_debug("mfp_required = %d, mfp_capable = %d", + mfp_required, mfp_capable); + roam_profile->MFPRequired = mfp_required; + roam_profile->MFPCapable = mfp_capable; +} +#else +static void hdd_update_values_mfp_cap( + struct csr_roam_profile *roam_profile, + uint8_t mfp_required, uint8_t mfp_capable ) +{ +} +#endif + +#ifdef WLAN_FEATURE_11W +/** + * hdd_set_mfp_enable: Set value for MFPEnabled + * @profile: Source profile + * + * Return: None + */ +static void hdd_set_mfp_enable(struct csr_roam_profile *roam_profile) +{ + /* + * Reset MFPEnabled if testmode RSNE passed doesn't have MFPR + * or MFPC bit set + */ + if (roam_profile->MFPEnabled && + !(roam_profile->MFPRequired || + roam_profile->MFPCapable)) { + hdd_debug("Reset MFPEnabled"); + roam_profile->MFPEnabled = 0; + } +} +#else +static void hdd_set_mfp_enable(struct csr_roam_profile *roam_profile) +{ +} +#endif + +#ifdef WLAN_FEATURE_11W +static uint32_t wlan_hdd_process_genie(struct hdd_adapter *adapter, + u8 *bssid, + eCsrEncryptionType *encrypt_type, + eCsrEncryptionType *mc_encrypt_type, + enum csr_akm_type *auth_type, + uint8_t *mfp_required, + uint8_t *mfp_capable, + uint16_t gen_ie_len, uint8_t *gen_ie) +{ + uint32_t status; + + status = hdd_process_genie(adapter, bssid, + encrypt_type, mc_encrypt_type, + auth_type, mfp_required, mfp_capable, + gen_ie_len, gen_ie); + + return status; +} +#else +static uint32_t wlan_hdd_process_genie(struct hdd_adapter *adapter, + u8 *bssid, + eCsrEncryptionType *encrypt_type, + eCsrEncryptionType *mc_encrypt_type, + enum csr_akm_type *auth_type, + uint8_t *mfp_required, + uint8_t *mfp_capable, + uint16_t gen_ie_len, uint8_t *gen_ie) +{ + uint32_t status; + + status = hdd_process_genie(adapter, bssid, + encrypt_type, mc_encrypt_type, + auth_type, gen_ie_len, gen_ie); + + return status; +} +#endif + /** * hdd_set_genie_to_csr() - set genie to csr * @adapter: pointer to adapter @@ -5480,10 +5738,8 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter, eCsrEncryptionType rsn_encrypt_type; eCsrEncryptionType mc_rsn_encrypt_type; struct hdd_context *hdd_ctx; -#ifdef WLAN_FEATURE_11W uint8_t mfp_required = 0; uint8_t mfp_capable = 0; -#endif u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */ roam_profile = hdd_roam_profile(adapter); @@ -5501,14 +5757,12 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter, /* The actual processing may eventually be more extensive than this. */ /* Right now, just consume any PMKIDs that are sent in by the app. */ - status = hdd_process_genie(adapter, bssid, - &rsn_encrypt_type, - &mc_rsn_encrypt_type, rsn_auth_type, -#ifdef WLAN_FEATURE_11W - &mfp_required, &mfp_capable, -#endif - security_ie[1] + 2, - security_ie); + status = wlan_hdd_process_genie(adapter, bssid, + &rsn_encrypt_type, + &mc_rsn_encrypt_type, rsn_auth_type, + &mfp_required, &mfp_capable, + security_ie[1] + 2, + security_ie); if (status == 0) { /* @@ -5541,41 +5795,28 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter, roam_profile->EncryptionType.encryptionType[0] = mc_rsn_encrypt_type; } -#ifdef WLAN_FEATURE_11W - hdd_debug("mfp_required = %d, mfp_capable = %d", - mfp_required, mfp_capable); - roam_profile->MFPRequired = mfp_required; - roam_profile->MFPCapable = mfp_capable; -#endif + + hdd_update_values_mfp_cap(roam_profile, mfp_required, + mfp_capable); } -#ifdef WLAN_CONV_CRYPTO_SUPPORTED + if (QDF_STATUS_SUCCESS != wlan_set_vdev_crypto_prarams_from_ie( adapter->vdev, security_ie, (security_ie[1] + 2))) hdd_err("Failed to set the crypto params from IE"); -#endif hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (hdd_ctx->force_rsne_override && (security_ie[0] == DOT11F_EID_RSN)) { hdd_warn("Test mode enabled set def Auth and enc type. RSN IE passed in connect req: "); - qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, roam_profile->pRSNReqIE, roam_profile->nRSNReqIELength); roam_profile->force_rsne_override = true; - hdd_debug("MFPEnabled %d", roam_profile->MFPEnabled); - /* - * Reset MFPEnabled if testmode RSNE passed doesn't have MFPR - * or MFPC bit set - */ - if (roam_profile->MFPEnabled && - !(roam_profile->MFPRequired || - roam_profile->MFPCapable)) { - hdd_debug("Reset MFPEnabled"); - roam_profile->MFPEnabled = 0; - } + hdd_set_mfp_enable(roam_profile); + /* If parsing failed set the def value for the roam profile */ if (status) hdd_set_def_rsne_override(roam_profile, rsn_auth_type); @@ -5844,7 +6085,7 @@ void hdd_roam_profile_init(struct hdd_adapter *adapter) /* Set the numOfChannels to zero to scan all the channels */ roam_profile->ChannelInfo.numOfChannels = 0; - roam_profile->ChannelInfo.ChannelList = NULL; + roam_profile->ChannelInfo.freq_list = NULL; roam_profile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c index 93b18105d79c194007f8b5df6074126493b2b2d0..68f9492dff61958bf125e5b9c1fb1e59c3f99ca0 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c @@ -47,6 +47,7 @@ #include "wlan_fwol_ucfg_api.h" #include "cfg_ucfg_api.h" #include "hdd_dp_cfg.h" +#include "wlan_hdd_object_manager.h" /** * get_next_line() - find and locate the new line pointer @@ -480,6 +481,43 @@ static void hdd_set_fine_time_meas_cap(struct hdd_context *hdd_ctx) hdd_debug("fine time meas capability - Enabled: %04x", capability); } +/** + * hdd_set_oem_6g_supported() - set oem 6g support enabled/disable + * @hdd_ctx: HDD context + * + * This function is used to pass oem 6g support enabled/disable value + * coming from INI to SME. This function make sure that configure + * INI is supported by the device. + * + * Return: None + */ +static void hdd_set_oem_6g_supported(struct hdd_context *hdd_ctx) +{ + bool oem_6g_disable = true; + bool is_reg_6g_support, set_wifi_pos_6g_disabled; + + ucfg_mlme_get_oem_6g_supported(hdd_ctx->psoc, &oem_6g_disable); + is_reg_6g_support = wlan_reg_is_6ghz_supported(hdd_ctx->psoc); + set_wifi_pos_6g_disabled = (oem_6g_disable || !is_reg_6g_support); + + /** + * Host uses following truth table to set wifi pos 6Ghz disable in + * ucfg_wifi_pos_set_oem_6g_supported(). + * ----------------------------------------------------------------- + * oem_6g_disable INI value | reg domain 6G support | Disable 6Ghz | + * ----------------------------------------------------------------- + * 1 | 1 | 1 | + * 1 | 0 | 1 | + * 0 | 1 | 0 | + * 0 | 0 | 1 | + * ----------------------------------------------------------------- + */ + ucfg_wifi_pos_set_oem_6g_supported(hdd_ctx->psoc, + set_wifi_pos_6g_disabled); + hdd_debug("oem 6g support is - %s", + set_wifi_pos_6g_disabled ? "Disbaled" : "Enabled"); +} + /** * hdd_convert_string_to_u8_array() - used to convert string into u8 array * @str: String to be converted @@ -856,8 +894,8 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx) */ /* This param cannot be configured from INI */ sme_config->csr_config.send_smps_action = true; - sme_config->csr_config.AdHocChannel5G = ibss_cfg.adhoc_ch_5g; - sme_config->csr_config.AdHocChannel24 = ibss_cfg.adhoc_ch_2g; + sme_config->csr_config.ad_hoc_ch_freq_5g = ibss_cfg.adhoc_ch_5g; + sme_config->csr_config.ad_hoc_ch_freq_2g = ibss_cfg.adhoc_ch_2g; sme_config->csr_config.ProprietaryRatesEnabled = 0; sme_config->csr_config.HeartbeatThresh50 = 40; ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc, @@ -890,6 +928,7 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx) sme_config->csr_config.max_intf_count = hdd_ctx->max_intf_count; hdd_set_fine_time_meas_cap(hdd_ctx); + hdd_set_oem_6g_supported(hdd_ctx); cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs); @@ -1018,7 +1057,8 @@ hdd_set_nss_params(struct hdd_adapter *adapter, * Ensure that nss is either 1 or 2 before calling this. * * @adapter: the pointer to adapter - * @nss: the number of spatial streams to be updated + * @tx_nss: the Tx number of spatial streams to be updated + * @rx_nss: the Rx number of spatial streams to be updated * * This function is used to modify the number of spatial streams * supported when not in connected state. @@ -1026,7 +1066,8 @@ hdd_set_nss_params(struct hdd_adapter *adapter, * Return: QDF_STATUS_SUCCESS if nss is correctly updated, * otherwise QDF_STATUS_E_FAILURE would be returned */ -QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) +QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t tx_nss, + uint8_t rx_nss) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint32_t rx_supp_data_rate, tx_supp_data_rate; @@ -1039,16 +1080,16 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) uint8_t enable2x2; mac_handle_t mac_handle; bool bval = 0; - uint8_t tx_nss, rx_nss; uint8_t band, max_supp_nss; - if ((nss == 2) && (hdd_ctx->num_rf_chains != 2)) { + if ((tx_nss == 2 || rx_nss == 2) && (hdd_ctx->num_rf_chains != 2)) { hdd_err("No support for 2 spatial streams"); return QDF_STATUS_E_INVAL; } - if (nss > MAX_VDEV_NSS) { - hdd_debug("Cannot support %d nss streams", nss); + if (tx_nss > MAX_VDEV_NSS || rx_nss > MAX_VDEV_NSS) { + hdd_debug("Cannot support tx_nss: %d rx_nss: %d", tx_nss, + rx_nss); return QDF_STATUS_E_INVAL; } @@ -1065,10 +1106,6 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) } max_supp_nss = MAX_VDEV_NSS; - /* Till now we dont have support for different rx, tx nss values */ - tx_nss = nss; - rx_nss = nss; - /* * If FW is supporting the dynamic nss update, this command is meant to * be per vdev, so update only the ini params of that particular vdev @@ -1110,7 +1147,7 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) * update of nss and chains per vdev feature, for the upcoming * connection */ - enable2x2 = (nss == 1) ? 0 : 1; + enable2x2 = (rx_nss == 2) ? 1 : 0; if (bval == enable2x2) { hdd_debug("NSS same as requested"); @@ -1128,14 +1165,18 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) return QDF_STATUS_E_FAILURE; } - if (!enable2x2) { - /* 1x1 */ - rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; + if (tx_nss == 1 && rx_nss == 2) { + /* 1x2 */ + rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; - } else { + } else if (enable2x2) { /* 2x2 */ rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; + } else { + /* 1x1 */ + rx_supp_data_rate = VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; + tx_supp_data_rate = VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; } /* Update Rx Highest Long GI data Rate */ @@ -1191,7 +1232,7 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) if (QDF_IS_STATUS_SUCCESS(qdf_status)) { mcs_set[0] = mcs_set_temp[0]; if (enable2x2) - for (val_len = 0; val_len < nss; val_len++) + for (val_len = 0; val_len < rx_nss; val_len++) mcs_set[val_len] = WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; if (ucfg_mlme_set_supported_mcs_set( @@ -1205,13 +1246,109 @@ QDF_STATUS hdd_update_nss(struct hdd_adapter *adapter, uint8_t nss) status = false; hdd_err("Could not get MCS SET from CFG"); } - sme_update_he_cap_nss(mac_handle, adapter->vdev_id, nss); + sme_update_he_cap_nss(mac_handle, adapter->vdev_id, rx_nss); #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES - if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, nss)) + if (QDF_STATUS_SUCCESS != sme_update_nss(mac_handle, rx_nss)) status = false; hdd_set_policy_mgr_user_cfg(hdd_ctx); return (status == false) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS; } + +QDF_STATUS hdd_get_tx_nss(struct hdd_adapter *adapter, uint8_t *tx_nss) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_mlme_nss_chains *dynamic_cfg; + enum band_info operating_band; + uint8_t proto_generic_nss; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_INVAL; + + proto_generic_nss = wlan_vdev_mlme_get_nss(vdev); + if (hdd_ctx->dynamic_nss_chains_support) { + dynamic_cfg = mlme_get_dynamic_vdev_config(vdev); + if (!dynamic_cfg) { + hdd_err("nss chain dynamic config NULL"); + hdd_objmgr_put_vdev(vdev); + return QDF_STATUS_E_INVAL; + } + if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) { + operating_band = hdd_get_sap_operating_band( + adapter->hdd_ctx); + } else { + operating_band = hdd_conn_get_connected_band( + &adapter->session.station); + } + switch (operating_band) { + case BAND_2G: + *tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ]; + break; + case BAND_5G: + *tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]; + break; + default: + *tx_nss = proto_generic_nss; + } + if (*tx_nss > proto_generic_nss) + *tx_nss = proto_generic_nss; + } else + *tx_nss = proto_generic_nss; + hdd_objmgr_put_vdev(vdev); + + return status; +} + +QDF_STATUS hdd_get_rx_nss(struct hdd_adapter *adapter, uint8_t *rx_nss) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_mlme_nss_chains *dynamic_cfg; + enum band_info operating_band; + uint8_t proto_generic_nss; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return QDF_STATUS_E_INVAL; + + proto_generic_nss = wlan_vdev_mlme_get_nss(vdev); + if (hdd_ctx->dynamic_nss_chains_support) { + dynamic_cfg = mlme_get_dynamic_vdev_config(vdev); + if (!dynamic_cfg) { + hdd_err("nss chain dynamic config NULL"); + hdd_objmgr_put_vdev(vdev); + return QDF_STATUS_E_INVAL; + } + if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) { + operating_band = hdd_get_sap_operating_band( + adapter->hdd_ctx); + } else { + operating_band = hdd_conn_get_connected_band( + &adapter->session.station); + } + switch (operating_band) { + case BAND_2G: + *rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ]; + break; + case BAND_5G: + *rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; + break; + default: + *rx_nss = proto_generic_nss; + } + if (*rx_nss > proto_generic_nss) + *rx_nss = proto_generic_nss; + } else + *rx_nss = proto_generic_nss; + hdd_objmgr_put_vdev(vdev); + + return status; +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c index 5713c5f526c0fc2c38484b555b44f1514176e3e4..94d24ddb25ef388896a49dc859ac6dcde26c39ba 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include "sir_params.h" @@ -48,6 +49,7 @@ #include "wlan_hdd_main.h" #include "wlan_hdd_power.h" #include "wlan_hdd_trace.h" +#include "wlan_hdd_tx_rx.h" #include "qdf_str.h" #include "qdf_trace.h" #include "qdf_types.h" @@ -68,9 +70,6 @@ #include "pld_common.h" #include "wmi_unified_param.h" -#ifdef WLAN_UMAC_CONVERGENCE -#include "wlan_cfg80211.h" -#endif #include #include #include @@ -146,8 +145,15 @@ #include "wlan_hdd_hw_capability.h" #include "wlan_hdd_oemdata.h" #include "os_if_fwol.h" +#include "wlan_hdd_sta_info.h" #include "sme_api.h" #include "wlan_hdd_thermal.h" +#include +#include "wlan_hdd_cfr.h" +#include +#include "hif.h" +#include "wlan_hdd_ioctl.h" +#include "wlan_hdd_gpio.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -388,6 +394,66 @@ static struct ieee80211_supported_band wlan_hdd_band_5_ghz = { .vht_cap.vht_supported = 1, }; +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) + +static struct ieee80211_channel hdd_channels_6_ghz[NUM_6GHZ_CHANNELS]; + +static struct ieee80211_supported_band wlan_hdd_band_6_ghz = { + .channels = NULL, + .n_channels = 0, + .band = HDD_NL80211_BAND_6GHZ, + .bitrates = a_mode_rates, + .n_bitrates = a_mode_rates_size, +}; + +#define HDD_SET_6GHZCHAN(ch, freq, chan, flag) { \ + (ch).band = HDD_NL80211_BAND_6GHZ; \ + (ch).center_freq = (freq); \ + (ch).hw_value = (chan); \ + (ch).flags = (flag); \ + (ch).max_antenna_gain = 0; \ + (ch).max_power = 0; \ +} + +static void hdd_init_6ghz(struct hdd_context *hdd_ctx) +{ + uint32_t i; + struct wiphy *wiphy = hdd_ctx->wiphy; + struct ieee80211_channel *chlist = hdd_channels_6_ghz; + uint32_t num = ARRAY_SIZE(hdd_channels_6_ghz); + QDF_STATUS status; + uint32_t band_capability; + + hdd_enter(); + + status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to get MLME Band Capability"); + return; + } + + if (!(band_capability & (BIT(REG_BAND_6G)))) { + hdd_debug("6ghz band not enabled"); + return; + } + + qdf_mem_zero(chlist, sizeof(*chlist) * num); + for (i = 0; i < num; i++) + HDD_SET_6GHZCHAN(chlist[i], 5945 + i * 20, 1 + i * 4, \ + IEEE80211_CHAN_DISABLED); + wiphy->bands[HDD_NL80211_BAND_6GHZ] = &wlan_hdd_band_6_ghz; + wiphy->bands[HDD_NL80211_BAND_6GHZ]->channels = chlist; + wiphy->bands[HDD_NL80211_BAND_6GHZ]->n_channels = num; + + hdd_exit(); +} +#else +static void hdd_init_6ghz(struct hdd_context *hdd_ctx) +{ +} +#endif + #if defined(CFG80211_IFTYPE_AKM_SUITES_SUPPORT) /*akm suits supported by sta*/ static const u32 hdd_sta_akm_suites[] = { @@ -411,6 +477,8 @@ static const u32 hdd_sta_akm_suites[] = { WLAN_AKM_SUITE_FT_EAP_SHA_384, RSN_AUTH_KEY_MGMT_CCKM, RSN_AUTH_KEY_MGMT_OSEN, + WAPI_PSK_AKM_SUITE, + WAPI_CERT_AKM_SUITE, }; /*akm suits supported by AP*/ @@ -862,11 +930,7 @@ static int __wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy, WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT : 0); set = set | (tdls_off_channel ? WIIF_TDLS_OFFCHANNEL_SUPPORT : 0); - if (tdls_sleep_sta_enable || tdls_buffer_sta || - tdls_off_channel) - max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN; - else - max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA; + max_num_tdls_sta = cfg_tdls_get_max_peer_count(hdd_ctx->psoc); hdd_debug("TDLS Feature supported value %x", set); if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION, @@ -1050,9 +1114,49 @@ hdd_convert_hang_reason(enum qdf_hang_reason reason) case QDF_WMI_EXCEED_MAX_PENDING_CMDS: ret_val = QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS; break; + case QDF_AP_STA_CONNECT_REQ_TIMEOUT: + ret_val = QCA_WLAN_HANG_AP_STA_CONNECT_REQ_TIMEOUT; + break; + case QDF_STA_AP_CONNECT_REQ_TIMEOUT: + ret_val = QCA_WLAN_HANG_STA_AP_CONNECT_REQ_TIMEOUT; + break; + case QDF_MAC_HW_MODE_CHANGE_TIMEOUT: + ret_val = QCA_WLAN_HANG_MAC_HW_MODE_CHANGE_TIMEOUT; + break; + case QDF_MAC_HW_MODE_CONFIG_TIMEOUT: + ret_val = QCA_WLAN_HANG_MAC_HW_MODE_CONFIG_TIMEOUT; + break; + case QDF_VDEV_START_RESPONSE_TIMED_OUT: + ret_val = QCA_WLAN_HANG_VDEV_START_RESPONSE_TIMED_OUT; + break; + case QDF_VDEV_RESTART_RESPONSE_TIMED_OUT: + ret_val = QCA_WLAN_HANG_VDEV_RESTART_RESPONSE_TIMED_OUT; + break; + case QDF_VDEV_STOP_RESPONSE_TIMED_OUT: + ret_val = QCA_WLAN_HANG_VDEV_STOP_RESPONSE_TIMED_OUT; + break; + case QDF_VDEV_DELETE_RESPONSE_TIMED_OUT: + ret_val = QCA_WLAN_HANG_VDEV_DELETE_RESPONSE_TIMED_OUT; + break; + case QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT: + ret_val = QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; + break; + case QDF_WMI_BUF_SEQUENCE_MISMATCH: + ret_val = QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; + break; + case QDF_HAL_REG_WRITE_FAILURE: + ret_val = QCA_WLAN_HANG_REG_WRITE_FAILURE; + break; + case QDF_SUSPEND_NO_CREDIT: + ret_val = QCA_WLAN_HANG_SUSPEND_NO_CREDIT; + break; + case QCA_HANG_BUS_FAILURE: + ret_val = QCA_WLAN_HANG_BUS_FAILURE; + break; case QDF_REASON_UNSPECIFIED: default: ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED; + break; } return ret_val; } @@ -1061,11 +1165,13 @@ hdd_convert_hang_reason(enum qdf_hang_reason reason) * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace * @hdd_ctx: Pointer to hdd context * @reason: cds recovery reason + * @data: Hang Data * * Return: 0 on success or failure reason */ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, - enum qdf_hang_reason reason) + enum qdf_hang_reason reason, uint8_t *data, + size_t data_len) { struct sk_buff *vendor_event; enum qca_wlan_vendor_hang_reason hang_reason; @@ -1083,9 +1189,10 @@ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, if (sta_adapter) wdev = &(sta_adapter->wdev); + vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, wdev, - sizeof(uint32_t), + sizeof(uint32_t) + data_len, HANG_REASON_INDEX, GFP_KERNEL); if (!vendor_event) { @@ -1096,7 +1203,9 @@ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, hang_reason = hdd_convert_hang_reason(reason); if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON, - (uint32_t)hang_reason)) { + (uint32_t)hang_reason) || + nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA, + data_len, data)) { hdd_err("QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail"); kfree_skb(vendor_event); return -EINVAL; @@ -1130,7 +1239,7 @@ int wlan_hdd_get_adjacent_chan(uint8_t chan, bool upper) if (upper && (ch_idx < (NUM_CHANNELS - 1))) ch_idx++; - else if (!upper && (ch_idx > CHAN_ENUM_1)) + else if (!upper && (ch_idx > CHAN_ENUM_2412)) ch_idx--; else return -EINVAL; @@ -1583,10 +1692,6 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = }, BCN_RECV_FEATURE_VENDOR_EVENTS - -#ifdef WLAN_UMAC_CONVERGENCE - COMMON_VENDOR_EVENTS -#endif [QCA_NL80211_VENDOR_SUBCMD_ROAM_INDEX] = { .vendor_id = QCA_NL80211_VENDOR_ID, .subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM, @@ -1714,8 +1819,8 @@ int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter) { struct hdd_adapter *con_sap_adapter; struct sap_config *sap_config, *con_sap_config; - int con_ch; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint32_t con_ch_freq; if (!hdd_ctx) { hdd_err("hdd context is NULL"); @@ -1736,71 +1841,76 @@ int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter) sap_config = &adapter->session.ap.sap_config; con_sap_config = &con_sap_adapter->session.ap.sap_config; - con_ch = con_sap_adapter->session.ap.operating_channel; + con_ch_freq = con_sap_adapter->session.ap.operating_chan_freq; - if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev, con_ch)) + if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, con_ch_freq)) return 0; - hdd_debug("Only SCC AP-AP DFS Permitted (ch=%d, con_ch=%d)", - sap_config->channel, con_ch); + hdd_debug("Only SCC AP-AP DFS Permitted (ch_freq=%d, con_ch_freq=%d)", + sap_config->chan_freq, con_ch_freq); hdd_debug("Overriding guest AP's channel"); - sap_config->channel = con_ch; + sap_config->chan_freq = con_ch_freq; if (con_sap_config->acs_cfg.acs_mode == true) { - if (con_ch != con_sap_config->acs_cfg.pri_ch && - con_ch != con_sap_config->acs_cfg.ht_sec_ch) { + if (con_ch_freq != con_sap_config->acs_cfg.pri_ch_freq && + con_ch_freq != con_sap_config->acs_cfg.ht_sec_ch_freq) { hdd_err("Primary AP channel config error"); - hdd_err("Operating ch: %d ACS ch: %d %d", - con_ch, con_sap_config->acs_cfg.pri_ch, - con_sap_config->acs_cfg.ht_sec_ch); + hdd_err("Operating ch: %d ACS ch freq: %d Sec Freq %d", + con_ch_freq, + con_sap_config->acs_cfg.pri_ch_freq, + con_sap_config->acs_cfg.ht_sec_ch_freq); return -EINVAL; } /* Sec AP ACS info is overwritten with Pri AP due to DFS * MCC restriction. So free ch list allocated in do_acs * func for Sec AP and realloc for Pri AP ch list size */ - if (sap_config->acs_cfg.ch_list) { - qdf_mem_free(sap_config->acs_cfg.ch_list); - sap_config->acs_cfg.ch_list = NULL; + if (sap_config->acs_cfg.freq_list) { + qdf_mem_free(sap_config->acs_cfg.freq_list); + sap_config->acs_cfg.freq_list = NULL; } - if (sap_config->acs_cfg.master_ch_list) { - qdf_mem_free(sap_config->acs_cfg.master_ch_list); - sap_config->acs_cfg.master_ch_list = NULL; + if (sap_config->acs_cfg.master_freq_list) { + qdf_mem_free(sap_config->acs_cfg.master_freq_list); + sap_config->acs_cfg.master_freq_list = NULL; } qdf_mem_copy(&sap_config->acs_cfg, - &con_sap_config->acs_cfg, - sizeof(struct sap_acs_cfg)); - sap_config->acs_cfg.ch_list = qdf_mem_malloc( - sizeof(uint8_t) * - con_sap_config->acs_cfg.ch_list_count); - if (!sap_config->acs_cfg.ch_list) { + &con_sap_config->acs_cfg, + sizeof(struct sap_acs_cfg)); + + sap_config->acs_cfg.freq_list = + qdf_mem_malloc(sizeof(uint32_t) * + con_sap_config->acs_cfg.ch_list_count); + if (!sap_config->acs_cfg.freq_list) { sap_config->acs_cfg.ch_list_count = 0; return -ENOMEM; } - qdf_mem_copy(sap_config->acs_cfg.ch_list, - con_sap_config->acs_cfg.ch_list, - con_sap_config->acs_cfg.ch_list_count); + qdf_mem_copy(sap_config->acs_cfg.freq_list, + con_sap_config->acs_cfg.freq_list, + con_sap_config->acs_cfg.ch_list_count * + sizeof(uint32_t)); - sap_config->acs_cfg.master_ch_list = - qdf_mem_malloc(sizeof(uint8_t) * + sap_config->acs_cfg.master_freq_list = + qdf_mem_malloc(sizeof(uint32_t) * con_sap_config->acs_cfg.master_ch_list_count); - if (!sap_config->acs_cfg.master_ch_list) { + if (!sap_config->acs_cfg.master_freq_list) { sap_config->acs_cfg.master_ch_list_count = 0; - qdf_mem_free(sap_config->acs_cfg.ch_list); - sap_config->acs_cfg.ch_list = NULL; + qdf_mem_free(sap_config->acs_cfg.freq_list); + sap_config->acs_cfg.freq_list = NULL; return -ENOMEM; } - qdf_mem_copy(sap_config->acs_cfg.master_ch_list, - con_sap_config->acs_cfg.master_ch_list, - con_sap_config->acs_cfg.master_ch_list_count); + qdf_mem_copy(sap_config->acs_cfg.master_freq_list, + con_sap_config->acs_cfg.master_freq_list, + con_sap_config->acs_cfg.master_ch_list_count * + sizeof(uint32_t)); } else { - sap_config->acs_cfg.pri_ch = con_ch; + sap_config->acs_cfg.pri_ch_freq = con_ch_freq; if (sap_config->acs_cfg.ch_width > eHT_CHANNEL_WIDTH_20MHZ) - sap_config->acs_cfg.ht_sec_ch = con_sap_config->sec_ch; + sap_config->acs_cfg.ht_sec_ch_freq = + con_sap_config->sec_ch_freq; } - return con_ch; + return con_ch_freq; } /** @@ -1824,20 +1934,28 @@ static int wlan_hdd_set_acs_ch_range( if (hw_mode == QCA_ACS_MODE_IEEE80211B) { sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11b; - sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1); - sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_14); + sap_cfg->acs_cfg.start_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_2412); + sap_cfg->acs_cfg.end_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_2484); } else if (hw_mode == QCA_ACS_MODE_IEEE80211G) { sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11g; - sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1); - sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_13); + sap_cfg->acs_cfg.start_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_2412); + sap_cfg->acs_cfg.end_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_2472); } else if (hw_mode == QCA_ACS_MODE_IEEE80211A) { sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11a; - sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_36); - sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173); + sap_cfg->acs_cfg.start_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_5180); + sap_cfg->acs_cfg.end_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_5865); } else if (hw_mode == QCA_ACS_MODE_IEEE80211ANY) { sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_abg; - sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1); - sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173); + sap_cfg->acs_cfg.start_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_2412); + sap_cfg->acs_cfg.end_ch_freq = + wlan_reg_ch_to_freq(CHAN_ENUM_5865); } if (ht_enabled) @@ -1847,19 +1965,23 @@ static int wlan_hdd_set_acs_ch_range( sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac; /* Parse ACS Chan list from hostapd */ - if (!sap_cfg->acs_cfg.ch_list) + if (!sap_cfg->acs_cfg.freq_list) return -EINVAL; - sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[0]; - sap_cfg->acs_cfg.end_ch = - sap_cfg->acs_cfg.ch_list[sap_cfg->acs_cfg.ch_list_count - 1]; + sap_cfg->acs_cfg.start_ch_freq = sap_cfg->acs_cfg.freq_list[0]; + sap_cfg->acs_cfg.end_ch_freq = + sap_cfg->acs_cfg.freq_list[sap_cfg->acs_cfg.ch_list_count - 1]; for (i = 0; i < sap_cfg->acs_cfg.ch_list_count; i++) { /* avoid channel as start channel */ - if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.ch_list[i] && - sap_cfg->acs_cfg.ch_list[i] != 0) - sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[i]; - if (sap_cfg->acs_cfg.end_ch < sap_cfg->acs_cfg.ch_list[i]) - sap_cfg->acs_cfg.end_ch = sap_cfg->acs_cfg.ch_list[i]; + if (sap_cfg->acs_cfg.start_ch_freq > + sap_cfg->acs_cfg.freq_list[i] && + sap_cfg->acs_cfg.freq_list[i] != 0) + sap_cfg->acs_cfg.start_ch_freq = + sap_cfg->acs_cfg.freq_list[i]; + if (sap_cfg->acs_cfg.end_ch_freq < + sap_cfg->acs_cfg.freq_list[i]) + sap_cfg->acs_cfg.end_ch_freq = + sap_cfg->acs_cfg.freq_list[i]; } return 0; @@ -1873,17 +1995,19 @@ static void hdd_update_acs_channel_list(struct sap_config *sap_config, for (i = 0; i < acs_list_count; i++) { if (BAND_2G == band) { - if (WLAN_REG_IS_24GHZ_CH( - sap_config->acs_cfg.ch_list[i])) { - sap_config->acs_cfg.ch_list[temp_count] = - sap_config->acs_cfg.ch_list[i]; + if (WLAN_REG_IS_24GHZ_CH_FREQ( + sap_config->acs_cfg.freq_list[i])) { + sap_config->acs_cfg.freq_list[temp_count] = + sap_config->acs_cfg.freq_list[i]; temp_count++; } } else if (BAND_5G == band) { - if (WLAN_REG_IS_5GHZ_CH( - sap_config->acs_cfg.ch_list[i])) { - sap_config->acs_cfg.ch_list[temp_count] = - sap_config->acs_cfg.ch_list[i]; + if (WLAN_REG_IS_5GHZ_CH_FREQ( + sap_config->acs_cfg.freq_list[i]) || + WLAN_REG_IS_6GHZ_CHAN_FREQ( + sap_config->acs_cfg.freq_list[i])) { + sap_config->acs_cfg.freq_list[temp_count] = + sap_config->acs_cfg.freq_list[i]; temp_count++; } } @@ -1924,10 +2048,10 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter) hdd_err("SAP config is NULL"); return -EINVAL; } - if (hdd_ctx->acs_policy.acs_channel) - sap_config->channel = hdd_ctx->acs_policy.acs_channel; + if (hdd_ctx->acs_policy.acs_chan_freq) + sap_config->chan_freq = hdd_ctx->acs_policy.acs_chan_freq; else - sap_config->channel = AUTO_CHANNEL_SELECT; + sap_config->chan_freq = AUTO_CHANNEL_SELECT; ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc, &mcc_to_scc_switch); /* @@ -1937,7 +2061,7 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter) if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION != mcc_to_scc_switch && !(policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) && - IS_24G_CH(sap_config->acs_cfg.end_ch))) { + WLAN_REG_IS_24GHZ_CH_FREQ(sap_config->acs_cfg.end_ch_freq))) { status = wlan_hdd_sap_cfg_dfs_override(adapter); if (status < 0) return status; @@ -1960,8 +2084,8 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter) conc_connection_info = policy_mgr_get_conn_info(&i); if (conc_connection_info[0].mac == conc_connection_info[1].mac) { - if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg. - pcl_channels[0])) { + if (!WLAN_REG_IS_24GHZ_CH_FREQ( + sap_config->acs_cfg.pcl_chan_freq[0])) { sap_config->acs_cfg.band = QCA_ACS_MODE_IEEE80211A; hdd_update_acs_channel_list(sap_config, @@ -2023,14 +2147,13 @@ static void hdd_update_vendor_pcl_list(struct hdd_context *hdd_ctx, */ for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { acs_chan_params->vendor_pcl_list[i] = - sap_config->acs_cfg.ch_list[i]; + sap_config->acs_cfg.freq_list[i]; acs_chan_params->vendor_weight_list[i] = 0; for (j = 0; j < sap_config->acs_cfg.pcl_ch_count; j++) { - if (sap_config->acs_cfg.ch_list[i] == - sap_config->acs_cfg.pcl_channels[j]) { + if (sap_config->acs_cfg.freq_list[i] == + sap_config->acs_cfg.pcl_chan_freq[j]) { acs_chan_params->vendor_weight_list[i] = - sap_config-> - acs_cfg.pcl_channels_weight_list[j]; + sap_config->acs_cfg.pcl_channels_weight_list[j]; break; } } @@ -2043,13 +2166,13 @@ static void hdd_update_vendor_pcl_list(struct hdd_context *hdd_ctx, * for all the given channel * @adapter: pointer to SAP adapter struct * @channel_count: channel count - * @channel_list: channel list + * @freq_list: channel frequency (MHz) list * * Return: Status of of channel information updation */ -static int hdd_update_reg_chan_info(struct hdd_adapter *adapter, - uint32_t channel_count, - uint8_t *channel_list) +static int +hdd_update_reg_chan_info(struct hdd_adapter *adapter, + uint32_t channel_count, uint32_t *freq_list) { int i; struct hdd_channel_info *icv; @@ -2071,8 +2194,8 @@ static int hdd_update_reg_chan_info(struct hdd_adapter *adapter, for (i = 0; i < channel_count; i++) { icv = &sap_config->channel_info[i]; - chan = channel_list[i]; - + chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, + freq_list[i]); if (chan == 0) continue; @@ -2100,7 +2223,8 @@ static int hdd_update_reg_chan_info(struct hdd_adapter *adapter, } icv->flags = 0; - icv->flags = cds_get_vendor_reg_flags(hdd_ctx->pdev, chan, + icv->flags = cds_get_vendor_reg_flags(hdd_ctx->pdev, + icv->ieee_chan_number, sap_config->acs_cfg.ch_width, sap_config->acs_cfg.is_ht_enabled, sap_config->acs_cfg.is_vht_enabled, @@ -2141,8 +2265,14 @@ static int hdd_update_reg_chan_info(struct hdd_adapter *adapter, #define CHAN_INFO_ATTR_VHT_SEG_1 \ QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 +#define CHAN_INFO_ATTR_FREQ_VHT_SEG_0 \ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 +#define CHAN_INFO_ATTR_FREQ_VHT_SEG_1 \ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + /** * hdd_cfg80211_update_channel_info() - add channel info attributes + * @hdd_ctx: pointer to hdd context * @skb: pointer to sk buff * @hdd_ctx: pointer to hdd station context * @idx: attribute index @@ -2150,12 +2280,14 @@ static int hdd_update_reg_chan_info(struct hdd_adapter *adapter, * Return: Success(0) or reason code for failure */ static int32_t -hdd_cfg80211_update_channel_info(struct sk_buff *skb, - struct sap_config *sap_config, int idx) +hdd_cfg80211_update_channel_info(struct hdd_context *hdd_ctx, + struct sk_buff *skb, + struct sap_config *sap_config, int idx) { struct nlattr *nla_attr, *channel; struct hdd_channel_info *icv; int i; + uint32_t freq_seg_0, freq_seg_1; nla_attr = nla_nest_start(skb, idx); if (!nla_attr) @@ -2171,6 +2303,14 @@ hdd_cfg80211_update_channel_info(struct sk_buff *skb, hdd_err("channel info not found"); goto fail; } + + freq_seg_0 = wlan_reg_legacy_chan_to_freq( + hdd_ctx->pdev, + icv->vht_center_freq_seg0); + freq_seg_1 = wlan_reg_legacy_chan_to_freq( + hdd_ctx->pdev, + icv->vht_center_freq_seg1); + if (nla_put_u16(skb, CHAN_INFO_ATTR_FREQ, icv->freq) || nla_put_u32(skb, CHAN_INFO_ATTR_FLAGS, @@ -2190,7 +2330,11 @@ hdd_cfg80211_update_channel_info(struct sk_buff *skb, nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_0, icv->vht_center_freq_seg0) || nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_1, - icv->vht_center_freq_seg1)) { + icv->vht_center_freq_seg1) || + nla_put_u32(skb, CHAN_INFO_ATTR_FREQ_VHT_SEG_0, + freq_seg_0) || + nla_put_u32(skb, CHAN_INFO_ATTR_FREQ_VHT_SEG_1, + freq_seg_1)) { hdd_err("put fail"); goto fail; } @@ -2213,8 +2357,12 @@ hdd_cfg80211_update_channel_info(struct sk_buff *skb, #undef CHAN_INFO_ATTR_VHT_SEG_0 #undef CHAN_INFO_ATTR_VHT_SEG_1 +#undef CHAN_INFO_ATTR_FREQ_VHT_SEG_0 +#undef CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + /** * hdd_cfg80211_update_pcl() - add pcl info attributes + * @hdd_ctx: pointer to hdd context * @skb: pointer to sk buff * @hdd_ctx: pointer to hdd station context * @idx: attribute index @@ -2224,15 +2372,16 @@ hdd_cfg80211_update_channel_info(struct sk_buff *skb, * Return: Success(0) or reason code for failure */ static int32_t -hdd_cfg80211_update_pcl(struct sk_buff *skb, +hdd_cfg80211_update_pcl(struct hdd_context *hdd_ctx, + struct sk_buff *skb, uint8_t ch_list_count, int idx, - uint8_t *vendor_pcl_list, uint8_t *vendor_weight_list) + uint32_t *vendor_pcl_list, uint8_t *vendor_weight_list) { struct nlattr *nla_attr, *channel; int i; + uint8_t chan; nla_attr = nla_nest_start(skb, idx); - if (!nla_attr) goto fail; @@ -2240,8 +2389,13 @@ hdd_cfg80211_update_pcl(struct sk_buff *skb, channel = nla_nest_start(skb, i); if (!channel) goto fail; - if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL, - vendor_pcl_list[i]) || + + chan = (uint8_t)wlan_reg_freq_to_chan(hdd_ctx->pdev, + vendor_pcl_list[i]); + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL, chan) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_PCL_FREQ, + vendor_pcl_list[i]) || nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT, vendor_weight_list[i])) { hdd_err("put fail"); @@ -2272,29 +2426,11 @@ static void hdd_get_scan_band(struct hdd_context *hdd_ctx, } } - -/** - * hdd_get_freq_list: API to get Frequency list based on channel list - * @channel_list: channel list - * @freq_list: frequency list - * @channel_count: channel count - * - * Return: None - */ -static void hdd_get_freq_list(uint8_t *channel_list, uint32_t *freq_list, - uint32_t channel_count) -{ - int count; - - for (count = 0; count < channel_count ; count++) - freq_list[count] = cds_chan_to_freq(channel_list[count]); -} - /** * wlan_hdd_sap_get_valid_channellist() - Get SAPs valid channel list * @ap_adapter: adapter * @channel_count: valid channel count - * @channel_list: valid channel list + * @freq_list: valid channel frequency (MHz) list * @band: frequency band * * This API returns valid channel list for SAP after removing nol and @@ -2304,45 +2440,43 @@ static void hdd_get_freq_list(uint8_t *channel_list, uint32_t *freq_list, */ static int wlan_hdd_sap_get_valid_channellist(struct hdd_adapter *adapter, uint32_t *channel_count, - uint8_t *channel_list, + uint32_t *freq_list, enum band_info band) { struct sap_config *sap_config; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - uint8_t tmp_chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t pcl_freqs[NUM_CHANNELS] = {0}; uint32_t chan_count; - uint8_t i; + uint32_t i; QDF_STATUS status; struct wlan_objmgr_pdev *pdev = hdd_ctx->pdev; - uint8_t tmp_chan; sap_config = &adapter->session.ap.sap_config; - status = - policy_mgr_get_valid_chans(hdd_ctx->psoc, - tmp_chan_list, - &chan_count); + status = policy_mgr_get_valid_chans(hdd_ctx->psoc, + pcl_freqs, + &chan_count); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Failed to get channel list"); return -EINVAL; } + *channel_count = 0; for (i = 0; i < chan_count; i++) { - tmp_chan = tmp_chan_list[i]; - if (*channel_count < QDF_MAX_NUM_CHAN) { - if ((band == BAND_2G) && - (WLAN_REG_IS_24GHZ_CH(tmp_chan)) && - (!wlan_reg_is_disable_ch(pdev, tmp_chan))) { - channel_list[*channel_count] = tmp_chan; - *channel_count += 1; - } else if ((band == BAND_5G) && - (WLAN_REG_IS_5GHZ_CH(tmp_chan)) && - (!wlan_reg_is_disable_ch(pdev, tmp_chan))) { - channel_list[*channel_count] = tmp_chan; - *channel_count += 1; - } - } else { + if (*channel_count >= NUM_CHANNELS) break; + + if (band == BAND_2G && + WLAN_REG_IS_24GHZ_CH_FREQ(pcl_freqs[i]) && + !wlan_reg_is_disable_for_freq(pdev, pcl_freqs[i])) { + freq_list[*channel_count] = pcl_freqs[i]; + *channel_count += 1; + } else if (band == BAND_5G && + (WLAN_REG_IS_5GHZ_CH_FREQ(pcl_freqs[i]) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_freqs[i])) && + !wlan_reg_is_disable_for_freq(pdev, pcl_freqs[i])) { + freq_list[*channel_count] = pcl_freqs[i]; + *channel_count += 1; } } @@ -2354,24 +2488,111 @@ static int wlan_hdd_sap_get_valid_channellist(struct hdd_adapter *adapter, return 0; } +/** + * hdd_get_external_acs_event_len() - Get event buffer length for external ACS + * @channel_count: number of channels for ACS operation + * + * Return: External ACS event (SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG) buffer length. + */ +static int hdd_get_external_acs_event_len(uint32_t channel_count) +{ + uint32_t len = NLMSG_HDRLEN; + uint32_t i; + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_OFFLOAD_ENABLED */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_ADD_CHAN_STATS_SUPPORT */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_WIDTH */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_BAND */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PHY_MODE */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_FREQ_LIST */ + len += nla_total_size(channel_count * sizeof(u32)); + + for (i = 0; i < channel_count; i++) { + /* QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_PCL_FREQ */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT */ + len += nla_total_size(sizeof(u8)); + } + + for (i = 0; i < channel_count; i++) { + /* QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ */ + len += nla_total_size(sizeof(u16)); + + /* QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT */ + len += nla_total_size(sizeof(u32)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 */ + len += nla_total_size(sizeof(u8)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 */ + len += nla_total_size(sizeof(u32)); + + /* VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 */ + len += nla_total_size(sizeof(u32)); + } + + /* QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY */ + len += nla_total_size(sizeof(u32)); + + return len; +} + int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, uint8_t reason) { - struct sk_buff *skb; + struct sk_buff *skb = NULL; struct sap_config *sap_config; uint32_t channel_count = 0, status = -EINVAL; - uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0}; - uint32_t freq_list[QDF_MAX_NUM_CHAN] = {0}; - uint8_t vendor_pcl_list[QDF_MAX_NUM_CHAN] = {0}; - uint8_t vendor_weight_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t *freq_list; + uint32_t vendor_pcl_list[NUM_CHANNELS] = {0}; + uint8_t vendor_weight_list[NUM_CHANNELS] = {0}; struct hdd_vendor_acs_chan_params acs_chan_params; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); enum band_info band = BAND_2G; eCsrPhyMode phy_mode; enum qca_wlan_vendor_attr_external_acs_policy acs_policy; - uint32_t i; + uint32_t i, id; QDF_STATUS qdf_status; bool is_external_acs_policy = cfg_default(CFG_EXTERNAL_ACS_POLICY); + uint32_t len; if (!hdd_ctx) { hdd_err("HDD context is NULL"); @@ -2392,8 +2613,8 @@ int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, if (conc_connection_info[0].mac == conc_connection_info[1].mac) { - if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg. - pcl_channels[0])) { + if (!WLAN_REG_IS_24GHZ_CH_FREQ( + sap_config->acs_cfg.pcl_chan_freq[0])) { sap_config->acs_cfg.band = QCA_ACS_MODE_IEEE80211A; hdd_update_acs_channel_list(sap_config, @@ -2409,66 +2630,61 @@ int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, hdd_get_scan_band(hdd_ctx, &adapter->session.ap.sap_config, &band); - if (sap_config->acs_cfg.ch_list) { + freq_list = qdf_mem_malloc(sizeof(uint32_t) * NUM_CHANNELS); + if (!freq_list) + return -ENOMEM; + + if (sap_config->acs_cfg.freq_list) { /* Copy INI or hostapd provided ACS channel range*/ - qdf_mem_copy(channel_list, sap_config->acs_cfg.ch_list, - sap_config->acs_cfg.ch_list_count); + for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) + freq_list[i] = sap_config->acs_cfg.freq_list[i]; channel_count = sap_config->acs_cfg.ch_list_count; } else { /* No channel list provided, copy all valid channels */ wlan_hdd_sap_get_valid_channellist(adapter, &channel_count, - channel_list, + freq_list, band); } sap_config->channel_info = qdf_mem_malloc( sizeof(struct hdd_channel_info) * channel_count); - if (!sap_config->channel_info) - return -ENOMEM; + if (!sap_config->channel_info) { + status = -ENOMEM; + goto fail; + } + + hdd_update_reg_chan_info(adapter, channel_count, freq_list); - hdd_update_reg_chan_info(adapter, channel_count, channel_list); - hdd_get_freq_list(channel_list, freq_list, channel_count); /* Get phymode */ phy_mode = adapter->session.ap.sap_config.acs_cfg.hw_mode; - skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, - &(adapter->wdev), - EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, - QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG, - GFP_KERNEL); - + len = hdd_get_external_acs_event_len(channel_count); + id = QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG; + skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, &adapter->wdev, + len, id, GFP_KERNEL); if (!skb) { hdd_err("cfg80211_vendor_event_alloc failed"); - qdf_mem_free(sap_config->channel_info); - return -ENOMEM; + status = -ENOMEM; + goto fail; } /* * Application expects pcl to be a subset of channel list * Remove all channels which are not in channel list from pcl * and add weight as zero */ - acs_chan_params.channel_count = channel_count; - acs_chan_params.channel_list = channel_list; acs_chan_params.vendor_pcl_list = vendor_pcl_list; acs_chan_params.vendor_weight_list = vendor_weight_list; hdd_update_vendor_pcl_list(hdd_ctx, &acs_chan_params, sap_config); - if (acs_chan_params.channel_count) { - hdd_debug("ACS channel list: len: %d", - acs_chan_params.channel_count); - for (i = 0; i < acs_chan_params.channel_count; i++) - hdd_debug("%d ", acs_chan_params.channel_list[i]); - } - if (acs_chan_params.pcl_count) { hdd_debug("ACS PCL list: len: %d", acs_chan_params.pcl_count); for (i = 0; i < acs_chan_params.pcl_count; i++) - hdd_debug("channel:%d, weight:%d ", + hdd_debug("channel_frequency: %u, weight: %u", acs_chan_params. vendor_pcl_list[i], acs_chan_params. @@ -2507,9 +2723,8 @@ int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, goto fail; } status = - hdd_cfg80211_update_pcl(skb, - acs_chan_params. - pcl_count, + hdd_cfg80211_update_pcl(hdd_ctx, skb, + acs_chan_params.pcl_count, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL, vendor_pcl_list, vendor_weight_list); @@ -2517,9 +2732,9 @@ int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, if (status != 0) goto fail; - status = hdd_cfg80211_update_channel_info(skb, sap_config, - QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO); + id = QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO; + status = hdd_cfg80211_update_channel_info(hdd_ctx, skb, sap_config, id); if (status != 0) goto fail; @@ -2531,11 +2746,14 @@ int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter, goto fail; cfg80211_vendor_event(skb, GFP_KERNEL); + qdf_mem_free(freq_list); qdf_mem_free(sap_config->channel_info); return 0; fail: - qdf_mem_free(sap_config->channel_info); + qdf_mem_free(freq_list); + if (sap_config->channel_info) + qdf_mem_free(sap_config->channel_info); if (skb) kfree_skb(skb); return status; @@ -2648,18 +2866,16 @@ static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx, for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { for (j = 0; j < avoid_acs_freq_list_num; j++) { - if (sap_config->acs_cfg.ch_list[i] == - wlan_reg_freq_to_chan( - hdd_ctx->pdev, - avoid_acs_freq_list[j])) { - hdd_debug("skip channel %d", - sap_config->acs_cfg.ch_list[i]); + if (sap_config->acs_cfg.freq_list[i] == + avoid_acs_freq_list[j]) { + hdd_debug("skip freq %d", + sap_config->acs_cfg.freq_list[i]); break; } } if (j == avoid_acs_freq_list_num) - sap_config->acs_cfg.ch_list[ch_cnt++] = - sap_config->acs_cfg.ch_list[i]; + sap_config->acs_cfg.freq_list[ch_cnt++] = + sap_config->acs_cfg.freq_list[i]; } sap_config->acs_cfg.ch_list_count = ch_cnt; } @@ -2670,6 +2886,44 @@ static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx, } #endif +/** + * wlan_hdd_trim_acs_channel_list() - Trims ACS channel list with + * intersection of PCL + * @pcl: preferred channel list + * @pcl_count: Preferred channel list count + * @org_ch_list: ACS channel list from user space + * @org_ch_list_count: ACS channel count from user space + * + * Return: None + */ +static void wlan_hdd_trim_acs_channel_list(uint32_t *pcl, uint8_t pcl_count, + uint32_t *org_freq_list, + uint8_t *org_ch_list_count) +{ + uint16_t i, j, ch_list_count = 0; + + if (*org_ch_list_count >= NUM_CHANNELS) { + hdd_err("org_ch_list_count too big %d", + *org_ch_list_count); + return; + } + + if (pcl_count >= NUM_CHANNELS) { + hdd_err("pcl_count is too big %d", pcl_count); + return; + } + + hdd_debug("Update ACS chan freq with PCL"); + for (j = 0; j < *org_ch_list_count; j++) + for (i = 0; i < pcl_count; i++) + if (pcl[i] == org_freq_list[j]) { + org_freq_list[ch_list_count++] = pcl[i]; + break; + } + + *org_ch_list_count = ch_list_count; +} + /** * wlan_hdd_handle_zero_acs_list() - Handle worst case of acs channel * trimmed to zero @@ -2689,24 +2943,23 @@ static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx, * Return: None */ static void wlan_hdd_handle_zero_acs_list(struct hdd_context *hdd_ctx, - uint8_t *acs_ch_list, + uint32_t *acs_freq_list, uint8_t *acs_ch_list_count, - uint8_t *org_ch_list, + uint32_t *org_freq_list, uint8_t org_ch_list_count) { uint16_t i, sta_count; - uint8_t acs_chan_default = 0; + uint32_t acs_chan_default = 0; if (!acs_ch_list_count || *acs_ch_list_count > 0 || - !acs_ch_list) + !acs_freq_list) { return; - - if (!org_ch_list_count || !org_ch_list) + } + if (!org_ch_list_count || !org_freq_list) return; if (!policy_mgr_is_force_scc(hdd_ctx->psoc)) return; - sta_count = policy_mgr_mode_specific_connection_count (hdd_ctx->psoc, PM_STA_MODE, NULL); sta_count += policy_mgr_mode_specific_connection_count @@ -2715,18 +2968,18 @@ static void wlan_hdd_handle_zero_acs_list(struct hdd_context *hdd_ctx, return; for (i = 0; i < org_ch_list_count; i++) { - if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev, - org_ch_list[i])) { - acs_chan_default = org_ch_list[i]; + if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, + org_freq_list[i])) { + acs_chan_default = org_freq_list[i]; break; } } if (!acs_chan_default) - acs_chan_default = org_ch_list[0]; + acs_chan_default = org_freq_list[0]; - acs_ch_list[0] = acs_chan_default; + acs_freq_list[0] = acs_chan_default; *acs_ch_list_count = 1; - hdd_debug("retore acs chan list to single ch %d", acs_chan_default); + hdd_debug("retore acs chan list to single freq %d", acs_chan_default); } /** @@ -2750,23 +3003,19 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct sap_config *sap_config; struct sk_buff *temp_skbuff; - int ret, i, ch_cnt = 0; + int ret, i; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1]; bool ht_enabled, ht40_enabled, vht_enabled; uint8_t ch_width; enum qca_wlan_vendor_acs_hw_mode hw_mode; enum policy_mgr_con_mode pm_mode; QDF_STATUS qdf_status; - bool skip_etsi13_srd_chan = false; bool is_vendor_acs_support = false; bool is_external_acs_policy = false; bool sap_force_11n_for_11ac = 0; bool go_force_11n_for_11ac = 0; - bool etsi13_srd_chan; bool go_11ac_override = 0; bool sap_11ac_override = 0; - uint8_t conc_channel; - mac_handle_t mac_handle; /* ***Note*** Donot set SME config related to ACS operation here because * ACS operation is not synchronouse and ACS for Second AP may come when @@ -2826,7 +3075,6 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, hdd_nofl_info("ACS request vid %d hw mode %d", adapter->vdev_id, hw_mode); - if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED]) ht_enabled = nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED]); @@ -2879,7 +3127,6 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, qdf_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg)); - hdd_debug("channel width =%d hw_mode %d", ch_width, hw_mode); if (ch_width == 160) sap_config->acs_cfg.ch_width = CH_WIDTH_160MHZ; else if (ch_width == 80) @@ -2889,63 +3136,63 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, else sap_config->acs_cfg.ch_width = CH_WIDTH_20MHZ; - /* hw_mode = a/b/g: QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST and - * QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attrs are present, and - * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is used for obtaining the - * channel list, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST is ignored - * since it contains the frequency values of the channels in - * the channel list. - * hw_mode = any: only QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attr - * is present - */ - - if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]) { - char *tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]); - + /* Firstly try to get channel frequencies */ + if (tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) { + uint32_t *freq = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]); sap_config->acs_cfg.ch_list_count = nla_len( - tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]); + tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) / + sizeof(uint32_t); if (sap_config->acs_cfg.ch_list_count) { - sap_config->acs_cfg.ch_list = qdf_mem_malloc( - sap_config->acs_cfg.ch_list_count); - sap_config->acs_cfg.master_ch_list = qdf_mem_malloc( - sap_config->acs_cfg.ch_list_count); - if (!sap_config->acs_cfg.ch_list || - !sap_config->acs_cfg.master_ch_list) { + sap_config->acs_cfg.freq_list = qdf_mem_malloc( + sap_config->acs_cfg.ch_list_count * + sizeof(uint32_t)); + sap_config->acs_cfg.master_freq_list = qdf_mem_malloc( + sap_config->acs_cfg.ch_list_count * + sizeof(uint32_t)); + if (!sap_config->acs_cfg.freq_list || + !sap_config->acs_cfg.master_freq_list) { ret = -ENOMEM; goto out; } - qdf_mem_copy(sap_config->acs_cfg.ch_list, tmp, - sap_config->acs_cfg.ch_list_count); - qdf_mem_copy(sap_config->acs_cfg.master_ch_list, tmp, - sap_config->acs_cfg.ch_list_count); + for (i = 0; i < sap_config->acs_cfg.ch_list_count; + i++) { + sap_config->acs_cfg.master_freq_list[i] = + freq[i]; + sap_config->acs_cfg.freq_list[i] = freq[i]; + } sap_config->acs_cfg.master_ch_list_count = sap_config->acs_cfg.ch_list_count; } - } else if (tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) { - uint32_t *freq = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]); + } else if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]) { + uint8_t *tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]); + sap_config->acs_cfg.ch_list_count = nla_len( - tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) / - sizeof(uint32_t); + tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]); if (sap_config->acs_cfg.ch_list_count) { - sap_config->acs_cfg.ch_list = qdf_mem_malloc( - sap_config->acs_cfg.ch_list_count); - sap_config->acs_cfg.master_ch_list = qdf_mem_malloc( - sap_config->acs_cfg.ch_list_count); - if (!sap_config->acs_cfg.ch_list || - !sap_config->acs_cfg.master_ch_list) { + sap_config->acs_cfg.freq_list = qdf_mem_malloc( + sap_config->acs_cfg.ch_list_count * + sizeof(uint32_t)); + sap_config->acs_cfg.master_freq_list = qdf_mem_malloc( + sap_config->acs_cfg.ch_list_count * + sizeof(uint32_t)); + if (!sap_config->acs_cfg.freq_list || + !sap_config->acs_cfg.master_freq_list) { ret = -ENOMEM; goto out; } - /* convert frequency to channel */ - for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) - sap_config->acs_cfg.ch_list[i] = - ieee80211_frequency_to_channel(freq[i]); - qdf_mem_copy(sap_config->acs_cfg.master_ch_list, - sap_config->acs_cfg.ch_list, - sap_config->acs_cfg.ch_list_count); + /* convert channel to frequency */ + for (i = 0; i < sap_config->acs_cfg.ch_list_count; + i++) { + sap_config->acs_cfg.freq_list[i] = + wlan_reg_legacy_chan_to_freq( + hdd_ctx->pdev, + tmp[i]); + sap_config->acs_cfg.master_freq_list[i] = + sap_config->acs_cfg.freq_list[i]; + } sap_config->acs_cfg.master_ch_list_count = sap_config->acs_cfg.ch_list_count; } @@ -2957,38 +3204,17 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, goto out; } - ucfg_mlme_get_etsi13_srd_chan_in_master_mode(hdd_ctx->psoc, - &etsi13_srd_chan); - skip_etsi13_srd_chan = - !etsi13_srd_chan && - wlan_reg_is_etsi13_regdmn(hdd_ctx->pdev); - - if (skip_etsi13_srd_chan) { - for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { - if (wlan_reg_is_etsi13_srd_chan(hdd_ctx->pdev, - sap_config->acs_cfg. - ch_list[i])) - sap_config->acs_cfg.ch_list[i] = 0; - else - sap_config->acs_cfg.ch_list[ch_cnt++] = - sap_config->acs_cfg.ch_list[i]; - } - sap_config->acs_cfg.ch_list_count = ch_cnt; - } - hdd_avoid_acs_channels(hdd_ctx, sap_config); pm_mode = policy_mgr_convert_device_mode_to_qdf_type(adapter->device_mode); /* consult policy manager to get PCL */ qdf_status = policy_mgr_get_pcl(hdd_ctx->psoc, pm_mode, - sap_config->acs_cfg.pcl_channels, + sap_config->acs_cfg.pcl_chan_freq, &sap_config->acs_cfg.pcl_ch_count, sap_config->acs_cfg. pcl_channels_weight_list, - QDF_MAX_NUM_CHAN); - if (qdf_status != QDF_STATUS_SUCCESS) - hdd_err("Get PCL failed"); + NUM_CHANNELS); sap_config->acs_cfg.band = hw_mode; @@ -2999,69 +3225,52 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, sap_config->acs_cfg.acs_mode = true; - conc_channel = policy_mgr_mode_specific_get_channel(hdd_ctx->psoc, - PM_STA_MODE); - if (is_external_acs_policy && conc_channel) { - if ((conc_channel >= WLAN_REG_CH_NUM(CHAN_ENUM_36) && - sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) || - (conc_channel <= WLAN_REG_CH_NUM(CHAN_ENUM_14) && - (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B || - sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G))) { - sap_config->acs_cfg.pri_ch = conc_channel; - wlan_sap_set_sap_ctx_acs_cfg( - WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config); - mac_handle = hdd_ctx->mac_handle; - sap_config_acs_result(mac_handle, - WLAN_HDD_GET_SAP_CTX_PTR(adapter), - sap_config->acs_cfg.ht_sec_ch); - sap_config->ch_params.ch_width = - sap_config->acs_cfg.ch_width; - sap_config->ch_params.sec_ch_offset = - sap_config->acs_cfg.ht_sec_ch; - sap_config->ch_params.center_freq_seg0 = - sap_config->acs_cfg.vht_seg0_center_ch; - sap_config->ch_params.center_freq_seg1 = - sap_config->acs_cfg.vht_seg1_center_ch; - /*notify hostapd about channel override */ - wlan_hdd_cfg80211_acs_ch_select_evt(adapter); - ret = 0; - goto out; - } - } - if (is_external_acs_policy && policy_mgr_is_force_scc(hdd_ctx->psoc) && policy_mgr_get_connection_count(hdd_ctx->psoc)) { - policy_mgr_trim_acs_channel_list( - sap_config->acs_cfg.pcl_channels, + wlan_hdd_trim_acs_channel_list( + sap_config->acs_cfg.pcl_chan_freq, sap_config->acs_cfg.pcl_ch_count, - sap_config->acs_cfg.ch_list, + sap_config->acs_cfg.freq_list, &sap_config->acs_cfg.ch_list_count); if (!sap_config->acs_cfg.ch_list_count && sap_config->acs_cfg.master_ch_list_count) wlan_hdd_handle_zero_acs_list( hdd_ctx, - sap_config->acs_cfg.ch_list, + sap_config->acs_cfg.freq_list, &sap_config->acs_cfg.ch_list_count, - sap_config->acs_cfg.master_ch_list, + sap_config->acs_cfg.master_freq_list, sap_config->acs_cfg.master_ch_list_count); /* if it is only one channel, send ACS event to upper layer */ if (sap_config->acs_cfg.ch_list_count == 1) { - sap_config->acs_cfg.pri_ch = - sap_config->acs_cfg.ch_list[0]; + sap_config->acs_cfg.start_ch_freq = + sap_config->acs_cfg.freq_list[0]; + sap_config->acs_cfg.end_ch_freq = + sap_config->acs_cfg.freq_list[0]; + sap_config->acs_cfg.pri_ch_freq = + sap_config->acs_cfg.freq_list[0]; wlan_sap_set_sap_ctx_acs_cfg( WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config); sap_config_acs_result(hdd_ctx->mac_handle, WLAN_HDD_GET_SAP_CTX_PTR(adapter), - sap_config->acs_cfg.ht_sec_ch); + sap_config->acs_cfg.ht_sec_ch_freq); sap_config->ch_params.ch_width = sap_config->acs_cfg.ch_width; sap_config->ch_params.sec_ch_offset = - sap_config->acs_cfg.ht_sec_ch; + wlan_reg_freq_to_chan(hdd_ctx->pdev, + sap_config->acs_cfg.ht_sec_ch_freq); sap_config->ch_params.center_freq_seg0 = - sap_config->acs_cfg.vht_seg0_center_ch; + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sap_config->acs_cfg.vht_seg0_center_ch_freq); sap_config->ch_params.center_freq_seg1 = - sap_config->acs_cfg.vht_seg1_center_ch; + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sap_config->acs_cfg.vht_seg1_center_ch_freq); + sap_config->ch_params.mhz_freq_seg0 = + sap_config->acs_cfg.vht_seg0_center_ch_freq; + sap_config->ch_params.mhz_freq_seg1 = + sap_config->acs_cfg.vht_seg1_center_ch_freq; /*notify hostapd about channel override */ wlan_hdd_cfg80211_acs_ch_select_evt(adapter); ret = 0; @@ -3070,7 +3279,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, } ret = wlan_hdd_set_acs_ch_range(sap_config, hw_mode, - ht_enabled, vht_enabled); + ht_enabled, vht_enabled); if (ret) { hdd_err("set acs channel range failed"); goto out; @@ -3080,7 +3289,8 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, ucfg_mlme_is_sap_11ac_override(hdd_ctx->psoc, &sap_11ac_override); /* ACS override for android */ if (ht_enabled && - sap_config->acs_cfg.end_ch >= WLAN_REG_CH_NUM(CHAN_ENUM_36) && + sap_config->acs_cfg.end_ch_freq >= + WLAN_REG_CH_TO_FREQ(CHAN_ENUM_5180) && ((adapter->device_mode == QDF_SAP_MODE && !sap_force_11n_for_11ac && sap_11ac_override) || @@ -3095,24 +3305,32 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, sap_config->acs_cfg.ch_width = ch_width; } - /* No VHT80 in 2.4G so perform ACS accordingly */ - if (sap_config->acs_cfg.end_ch <= 14 && - sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ) { - sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ; - hdd_debug("resetting to 40Mhz in 2.4Ghz"); + /* Check 2.4ghz cbmode and update BW if only 2.4 channels are present */ + if (sap_config->acs_cfg.end_ch_freq <= + WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484) && + sap_config->acs_cfg.ch_width >= eHT_CHANNEL_WIDTH_40MHZ) { + uint32_t channel_bonding_mode; + + ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, + &channel_bonding_mode); + sap_config->acs_cfg.ch_width = channel_bonding_mode ? + eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ; + + hdd_debug("Only 2.4ghz channels, resetting BW to %d 2.4 cbmode %d", + sap_config->acs_cfg.ch_width, channel_bonding_mode); } hdd_nofl_debug("ACS Config country %s ch_width %d hw_mode %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d", hdd_ctx->reg.alpha2, ch_width, sap_config->acs_cfg.hw_mode, sap_config->acs_cfg.ch_width, - ht_enabled, vht_enabled, sap_config->acs_cfg.start_ch, - sap_config->acs_cfg.end_ch, + ht_enabled, vht_enabled, sap_config->acs_cfg.start_ch_freq, + sap_config->acs_cfg.end_ch_freq, sap_config->acs_cfg.band); host_log_acs_req_event(adapter->dev->name, csr_phy_mode_str(sap_config->acs_cfg.hw_mode), ch_width, ht_enabled, vht_enabled, - sap_config->acs_cfg.start_ch, - sap_config->acs_cfg.end_ch); + sap_config->acs_cfg.start_ch_freq, + sap_config->acs_cfg.end_ch_freq); sap_config->acs_cfg.is_ht_enabled = ht_enabled; sap_config->acs_cfg.is_vht_enabled = vht_enabled; @@ -3188,6 +3406,91 @@ void wlan_hdd_undo_acs(struct hdd_adapter *adapter) &adapter->session.ap.sap_config); } +/** + * hdd_fill_acs_chan_freq() - Populate channel frequencies (MHz) selected in ACS + * @hdd_ctx: pointer to hdd context + * @sap_cfg: sap acs configuration + * @vendor_event: output pointer to populate channel frequencies (MHz) + * + * Return: If populated successfully return 0 else negative value. + */ +static int hdd_fill_acs_chan_freq(struct hdd_context *hdd_ctx, + struct sap_config *sap_cfg, + struct sk_buff *vendor_event) +{ + uint32_t id; + int errno; + + id = QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY; + errno = nla_put_u32(vendor_event, id, sap_cfg->acs_cfg.pri_ch_freq); + if (errno) { + hdd_err("VENDOR_ATTR_ACS_PRIMARY_FREQUENCY put fail"); + return errno; + } + + id = QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY; + errno = nla_put_u32(vendor_event, id, sap_cfg->acs_cfg.ht_sec_ch_freq); + if (errno) { + hdd_err("VENDOR_ATTR_ACS_SECONDARY_FREQUENCY put fail"); + return errno; + } + + id = QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY; + errno = nla_put_u32(vendor_event, id, + sap_cfg->acs_cfg.vht_seg0_center_ch_freq); + if (errno) { + hdd_err("VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY put fail"); + return errno; + } + + id = QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY; + errno = nla_put_u32(vendor_event, id, + sap_cfg->acs_cfg.vht_seg1_center_ch_freq); + if (errno) { + hdd_err("VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY put fail"); + return errno; + } + + return 0; +} + +static int hdd_get_acs_evt_data_len(void) +{ + uint32_t len = NLMSG_HDRLEN; + + /* QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY */ + len += nla_total_size(sizeof(u32)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH */ + len += nla_total_size(sizeof(u16)); + + /* QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE */ + len += nla_total_size(sizeof(u8)); + + return len; +} + /** * wlan_hdd_cfg80211_acs_ch_select_evt: Callback function for ACS evt * @adapter: Pointer to SAP adapter struct @@ -3199,7 +3502,6 @@ void wlan_hdd_undo_acs(struct hdd_adapter *adapter) * * Return: None */ - void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -3208,51 +3510,71 @@ void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter) struct sk_buff *vendor_event; int ret_val; uint16_t ch_width; + uint8_t pri_channel; + uint8_t ht_sec_channel; + uint8_t vht_seg0_center_ch, vht_seg1_center_ch; + uint32_t id = QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX; + uint32_t len = hdd_get_acs_evt_data_len(); qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); qdf_event_set(&adapter->acs_complete_event); vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, - &(adapter->wdev), - 4 * sizeof(u8) + 1 * sizeof(u16) + 4 + NLMSG_HDRLEN, - QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX, - GFP_KERNEL); + &adapter->wdev, len, id, + GFP_KERNEL); if (!vendor_event) { hdd_err("cfg80211_vendor_event_alloc failed"); return; } - ret_val = nla_put_u8(vendor_event, - QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL, - sap_cfg->acs_cfg.pri_ch); + ret_val = hdd_fill_acs_chan_freq(hdd_ctx, sap_cfg, vendor_event); if (ret_val) { - hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail"); + hdd_err("failed to put frequencies"); kfree_skb(vendor_event); return; } + pri_channel = wlan_reg_freq_to_chan(hdd_ctx->pdev, + sap_cfg->acs_cfg.pri_ch_freq); + + ht_sec_channel = wlan_reg_freq_to_chan(hdd_ctx->pdev, + sap_cfg->acs_cfg.ht_sec_ch_freq); + ret_val = nla_put_u8(vendor_event, - QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, - sap_cfg->acs_cfg.ht_sec_ch); + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL, + pri_channel); if (ret_val) { - hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail"); + hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail"); kfree_skb(vendor_event); return; } + ret_val = nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL, + ht_sec_channel); + if (ret_val) { + hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail"); + kfree_skb(vendor_event); + return; + } + vht_seg0_center_ch = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sap_cfg->acs_cfg.vht_seg0_center_ch_freq); ret_val = nla_put_u8(vendor_event, QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, - sap_cfg->acs_cfg.vht_seg0_center_ch); + vht_seg0_center_ch); if (ret_val) { hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL put fail"); kfree_skb(vendor_event); return; } - + vht_seg1_center_ch = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sap_cfg->acs_cfg.vht_seg1_center_ch_freq); ret_val = nla_put_u8(vendor_event, QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, - sap_cfg->acs_cfg.vht_seg1_center_ch); + vht_seg1_center_ch); if (ret_val) { hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL put fail"); kfree_skb(vendor_event); @@ -3276,14 +3598,14 @@ void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter) kfree_skb(vendor_event); return; } - if (sap_cfg->acs_cfg.pri_ch > 14) + if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_cfg->acs_cfg.pri_ch_freq)) ret_val = nla_put_u8(vendor_event, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, - QCA_ACS_MODE_IEEE80211A); + QCA_ACS_MODE_IEEE80211G); else ret_val = nla_put_u8(vendor_event, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, - QCA_ACS_MODE_IEEE80211G); + QCA_ACS_MODE_IEEE80211A); if (ret_val) { hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE put fail"); @@ -3291,10 +3613,11 @@ void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter) return; } - hdd_debug("ACS result for %s: PRI_CH: %d SEC_CH: %d VHT_SEG0: %d VHT_SEG1: %d ACS_BW: %d", - adapter->dev->name, sap_cfg->acs_cfg.pri_ch, - sap_cfg->acs_cfg.ht_sec_ch, sap_cfg->acs_cfg.vht_seg0_center_ch, - sap_cfg->acs_cfg.vht_seg1_center_ch, ch_width); + hdd_debug("ACS result for %s: PRI_CH_FREQ: %d SEC_CH_FREQ: %d VHT_SEG0: %d VHT_SEG1: %d ACS_BW: %d", + adapter->dev->name, sap_cfg->acs_cfg.pri_ch_freq, + sap_cfg->acs_cfg.ht_sec_ch_freq, + sap_cfg->acs_cfg.vht_seg0_center_ch_freq, + sap_cfg->acs_cfg.vht_seg1_center_ch_freq, ch_width); cfg80211_vendor_event(vendor_event, GFP_KERNEL); } @@ -3670,6 +3993,10 @@ __wlan_hdd_cfg80211_get_features(struct wiphy *wiphy, wlan_hdd_cfg80211_set_feature(feature_flags, QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS); + if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) + wlan_hdd_cfg80211_set_feature(feature_flags, + QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS); + if (wma_is_p2p_lo_capable()) wlan_hdd_cfg80211_set_feature(feature_flags, QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD); @@ -4020,8 +4347,8 @@ static int hdd_set_bssid_prefs(struct hdd_context *hdd_ctx, nla_memcpy(roam_params->bssid_favored[i].bytes, tb2[PARAM_ROAM_BSSID], QDF_MAC_ADDR_SIZE); - hdd_debug(QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roam_params->bssid_favored[i].bytes)); + hdd_debug(QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(roam_params->bssid_favored[i].bytes)); /* Parse and fetch preference factor*/ if (!tb2[PARAM_RSSI_MODIFIER]) { hdd_err("BSSID Preference score failed"); @@ -4112,6 +4439,10 @@ static int hdd_set_blacklist_bssid(struct hdd_context *hdd_ctx, tb2[PARAM_SET_BSSID], QDF_MAC_ADDR_SIZE); ap_info.reject_ap_type = USERSPACE_AVOID_TYPE; + ap_info.reject_reason = + REASON_USERSPACE_AVOID_LIST; + ap_info.source = ADDED_BY_DRIVER; + /* This BSSID is avoided and not blacklisted */ ucfg_blm_add_bssid_to_reject_list(hdd_ctx->pdev, &ap_info); @@ -4120,8 +4451,8 @@ static int hdd_set_blacklist_bssid(struct hdd_context *hdd_ctx, } nla_memcpy(roam_params->bssid_avoid_list[j].bytes, tb2[PARAM_SET_BSSID], QDF_MAC_ADDR_SIZE); - hdd_debug(QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roam_params-> + hdd_debug(QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(roam_params-> bssid_avoid_list[j].bytes)); i++; j++; @@ -4754,6 +5085,16 @@ hdd_roam_control_config_buf_size(struct hdd_context *hdd_ctx, if (tb[QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD]) skb_len += NLA_HDRLEN + sizeof(uint32_t); + if (tb[QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME]) + /* + * Response has 3 nests, 1 atrribure value and a + * attribute list of frequencies. + */ + skb_len += 3 * nla_total_size(0) + + nla_total_size(sizeof(uint32_t)) + + (nla_total_size(sizeof(uint32_t)) * + NUM_CHANNELS); + return skb_len; } @@ -4775,8 +5116,11 @@ hdd_roam_control_config_fill_data(struct hdd_context *hdd_ctx, uint8_t vdev_id, { QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t roam_control; - struct nlattr *config; + struct nlattr *config, *get_freq_scheme, *get_freq; uint32_t full_roam_scan_period; + uint8_t num_channels = 0; + uint32_t i = 0, freq_list[NUM_CHANNELS] = { 0 }; + struct hdd_adapter *hdd_adapter = NULL; config = nla_nest_start(skb, PARAM_ROAM_CONTROL_CONFIG); if (!config) { @@ -4814,7 +5158,54 @@ hdd_roam_control_config_fill_data(struct hdd_context *hdd_ctx, uint8_t vdev_id, } } + if (tb[QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME]) { + hdd_adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + if (!hdd_adapter) { + hdd_info("HDD adapter is NULL"); + return -EINVAL; + } + + hdd_debug("Get roam scan frequencies req received"); + status = hdd_get_roam_scan_freq(hdd_adapter, + hdd_ctx->mac_handle, + freq_list, &num_channels); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_info("failed to get roam scan freq"); + goto out; + } + + hdd_debug("num_channels %d", num_channels); + get_freq_scheme = nla_nest_start( + skb, QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME); + if (!get_freq_scheme) { + hdd_info("failed to nest start for roam scan freq"); + return -EINVAL; + } + + if (nla_put_u32(skb, PARAM_SCAN_FREQ_LIST_TYPE, 0)) { + hdd_info("failed to put list type"); + return -EINVAL; + } + + get_freq = nla_nest_start( + skb, QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST); + if (!get_freq) { + hdd_info("failed to nest start for roam scan freq"); + return -EINVAL; + } + + for (i = 0; i < num_channels; i++) { + if (nla_put_u32(skb, PARAM_SCAN_FREQ_LIST, + freq_list[i])) { + hdd_info("failed to put freq at index %d", i); + return -EINVAL; + } + } + nla_nest_end(skb, get_freq); + nla_nest_end(skb, get_freq_scheme); + } nla_nest_end(skb, config); + out: return qdf_status_to_os_return(status); } @@ -5093,8 +5484,6 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy, struct roam_ext_params *roam_params = NULL; int ret; - hdd_enter_dev(dev); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); return -EPERM; @@ -5242,16 +5631,18 @@ wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx, enum QDF_OPMODE device_mode) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct hdd_ap_ctx *ap_ctx; struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if ((device_mode == adapter->device_mode) && (device_mode == QDF_SAP_MODE)) { ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - /* * if there is SAP already running on DFS channel, * do not disable scan on dfs channels. Note that @@ -5259,10 +5650,15 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx, * single radio. But then we can have multiple * radios !! */ - if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state( - hdd_ctx->pdev, - ap_ctx->operating_channel)) { + if (CHANNEL_STATE_DFS == + wlan_reg_get_channel_state_for_freq( + hdd_ctx->pdev, + ap_ctx->operating_chan_freq)) { hdd_err("SAP running on DFS channel"); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } } @@ -5271,19 +5667,24 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx, (device_mode == QDF_STA_MODE)) { sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - /* * if STA is already connected on DFS channel, * do not disable scan on dfs channels */ if (hdd_conn_is_connected(sta_ctx) && - (CHANNEL_STATE_DFS == - wlan_reg_get_channel_state(hdd_ctx->pdev, - sta_ctx->conn_info.channel))) { + (CHANNEL_STATE_DFS == + wlan_reg_get_channel_state_for_freq( + hdd_ctx->pdev, + sta_ctx->conn_info.chan_freq))) { hdd_err("client connected on DFS channel"); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } return false; @@ -5481,9 +5882,7 @@ static int __wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy, QDF_STATUS status; bool wisa_mode; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); mac_handle_t mac_handle; - struct cdp_vdev *txrx_vdev = NULL; hdd_enter_dev(dev); ret_val = wlan_hdd_validate_context(hdd_ctx); @@ -5517,15 +5916,8 @@ static int __wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy, hdd_err("Unable to set WISA mode: %d to FW", wisa_mode); ret_val = -EINVAL; } - if (QDF_IS_STATUS_SUCCESS(status) || !wisa_mode) { - txrx_vdev = cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); - if (!txrx_vdev) - ret_val = -EINVAL; - else - cdp_set_wisa_mode(soc, txrx_vdev, wisa_mode); - } + if (QDF_IS_STATUS_SUCCESS(status) || !wisa_mode) + cdp_set_wisa_mode(soc, adapter->vdev_id, wisa_mode); err: hdd_exit(); return ret_val; @@ -5942,8 +6334,9 @@ __wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy, features |= WIFI_LOGGER_PACKET_FATE_SUPPORTED; hdd_debug("Supported logger features: 0x%0x", features); } else { - hdd_debug("Ring buffer disabled"); + hdd_info("Ring buffer disable"); } + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN); if (!reply_skb) { @@ -6416,6 +6809,13 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES] = { .type = NLA_BINARY, .len = SIR_MAC_MAX_ADD_IE_LENGTH + 2}, + [QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE] = { + .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_TX_CHAINS] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 }, }; @@ -6598,8 +6998,8 @@ static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter, wlan_vdev_obj_lock(vdev); wlan_vdev_mlme_cap_set(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); wlan_vdev_obj_unlock(vdev); - chan = policy_mgr_get_channel(hdd_ctx->psoc, pmode, - &vdev_id); + chan = wlan_freq_to_chan( + policy_mgr_get_channel(hdd_ctx->psoc, pmode, &vdev_id)); if (!chan || wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, chan)) { hdd_err("unable to send avoid_freq"); @@ -6748,6 +7148,61 @@ static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_adapter *adapter, return ret_val; } +/** + * hdd_set_roam_reason_vsie_status() - enable/disable inclusion of + * roam reason vsie in Reassoc + * + * @adapter: hdd adapter + * @attr: nla attr sent by supplicant + * + * Return: 0 on success, negative errno on failure + */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static int hdd_set_roam_reason_vsie_status(struct hdd_adapter *adapter, + const struct nlattr *attr) +{ + uint8_t roam_reason_vsie_enabled; + int errno; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct hdd_context *hdd_ctx = NULL; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("hdd_ctx failure"); + return -EINVAL; + } + + roam_reason_vsie_enabled = nla_get_u8(attr); + if (roam_reason_vsie_enabled > 1) + roam_reason_vsie_enabled = 1; + + status = + ucfg_mlme_set_roam_reason_vsie_status(hdd_ctx->psoc, + roam_reason_vsie_enabled); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("set roam reason vsie failed"); + return -EINVAL; + } + + errno = sme_cli_set_command + (adapter->vdev_id, + WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, + roam_reason_vsie_enabled, VDEV_CMD); + if (errno) { + hdd_err("Failed to set beacon report error vsie"); + status = QDF_STATUS_E_FAILURE; + } + + return qdf_status_to_os_return(status); +} +#else +static int hdd_set_roam_reason_vsie_status(struct hdd_adapter *adapter, + const struct nlattr *attr) +{ + return -ENOTSUPP; +} +#endif + static int hdd_config_access_policy(struct hdd_adapter *adapter, struct nlattr *tb[]) { @@ -6809,7 +7264,6 @@ static int hdd_config_mpdu_aggregation(struct hdd_adapter *adapter, struct nlattr *rx_attr = tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]; uint8_t tx_size, rx_size; - struct sir_set_tx_rx_aggregation_size request; QDF_STATUS status; /* nothing to do if neither attribute is present */ @@ -6833,17 +7287,154 @@ static int hdd_config_mpdu_aggregation(struct hdd_adapter *adapter, return -EINVAL; } - qdf_mem_zero(&request, sizeof(request)); - request.tx_aggregation_size = tx_size; - request.rx_aggregation_size = rx_size; - request.vdev_id = adapter->vdev_id; - request.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU; + status = wma_set_tx_rx_aggr_size(adapter->vdev_id, + tx_size, + rx_size, + WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU); + + return qdf_status_to_os_return(status); +} + +static QDF_STATUS +hdd_populate_vdev_chains(struct wlan_mlme_nss_chains *nss_chains_cfg, + uint8_t tx_chains, + uint8_t rx_chains, + enum nss_chains_band_info band, + struct wlan_objmgr_vdev *vdev) +{ + struct wlan_mlme_nss_chains *dynamic_cfg; + + nss_chains_cfg->num_rx_chains[band] = rx_chains; + nss_chains_cfg->num_tx_chains[band] = tx_chains; + + dynamic_cfg = ucfg_mlme_get_dynamic_vdev_config(vdev); + if (!dynamic_cfg) { + hdd_err("nss chain dynamic config NULL"); + return QDF_STATUS_E_FAILURE; + } + /* + * If user gives any nss value, then chains will be adjusted based on + * nss (in SME func sme_validate_user_nss_chain_params). + * If Chains are not suitable as per current NSS then, we need to + * return, and the below logic is added for the same. + */ + + if ((dynamic_cfg->rx_nss[band] > rx_chains) || + (dynamic_cfg->tx_nss[band] > tx_chains)) { + hdd_err("Chains less than nss, configure correct nss first."); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +int +hdd_set_dynamic_antenna_mode(struct hdd_adapter *adapter, + uint8_t num_rx_chains, + uint8_t num_tx_chains) +{ + enum nss_chains_band_info band; + struct wlan_mlme_nss_chains user_cfg; + QDF_STATUS status; + mac_handle_t mac_handle; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; + int ret; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + mac_handle = hdd_ctx->mac_handle; + if (!mac_handle) { + hdd_err("NULL MAC handle"); + return -EINVAL; + } + + if (!hdd_is_vdev_in_conn_state(adapter)) { + hdd_debug("Vdev (id %d) not in connected/started state, cannot accept command", + adapter->vdev_id); + return -EINVAL; + } + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + hdd_err("vdev is NULL"); + return -EINVAL; + } + + qdf_mem_zero(&user_cfg, sizeof(user_cfg)); + for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { + status = hdd_populate_vdev_chains(&user_cfg, + num_rx_chains, + num_tx_chains, band, vdev); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_objmgr_put_vdev(vdev); + return -EINVAL; + } + } + hdd_objmgr_put_vdev(vdev); - status = wma_set_tx_rx_aggregation_size(&request); + status = sme_nss_chains_update(mac_handle, + &user_cfg, + adapter->vdev_id); if (QDF_IS_STATUS_ERROR(status)) - hdd_err("failed to set aggr sizes err %d", status); + return -EINVAL; - return qdf_status_to_os_return(status); + return 0; +} + +static int hdd_config_vdev_chains(struct hdd_adapter *adapter, + struct nlattr *tb[]) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint8_t tx_chains, rx_chains; + struct nlattr *tx_attr = + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_TX_CHAINS]; + struct nlattr *rx_attr = + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS]; + + if (!tx_attr && !rx_attr) + return 0; + + tx_chains = nla_get_u8(tx_attr); + rx_chains = nla_get_u8(rx_attr); + + if (hdd_ctx->dynamic_nss_chains_support) + return hdd_set_dynamic_antenna_mode(adapter, rx_chains, + tx_chains); + return 0; +} + +static int hdd_config_tx_rx_nss(struct hdd_adapter *adapter, + struct nlattr *tb[]) +{ + uint8_t tx_nss, rx_nss; + QDF_STATUS status; + + struct nlattr *tx_attr = + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS]; + struct nlattr *rx_attr = + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS]; + + if (!tx_attr && !rx_attr) + return 0; + + tx_nss = nla_get_u8(tx_attr); + rx_nss = nla_get_u8(rx_attr); + hdd_debug("tx_nss %d rx_nss %d", tx_nss, rx_nss); + /* Only allow NSS for tx_rx_nss for 1x1, 1x2, 2x2 */ + if (!((tx_nss == 1 && rx_nss == 2) || (tx_nss == 1 && rx_nss == 1) || + (tx_nss == 2 && rx_nss == 2))) { + hdd_err("Setting tx_nss %d rx_nss %d not allowed", tx_nss, + rx_nss); + return 0; + } + status = hdd_update_nss(adapter, tx_nss, rx_nss); + if (status != QDF_STATUS_SUCCESS) + hdd_debug("Can't set tx_nss %d rx_nss %d", tx_nss, rx_nss); + + return 0; } static int hdd_config_ant_div_period(struct hdd_adapter *adapter, @@ -7020,15 +7611,31 @@ static int hdd_config_scan_enable(struct hdd_adapter *adapter, return 0; } -static int hdd_config_qpower(struct hdd_adapter *adapter, - const struct nlattr *attr) +/** + * hdd_config_udp_qos_upgrade_threshold() - NL attribute handler to parse + * priority upgrade threshold value. + * @adapter: adapter for which this configuration is to be applied + * @attr: NL attribute + * + * Returns: 0 on success, -EINVAL on failure + */ +static int hdd_config_udp_qos_upgrade_threshold(struct hdd_adapter *adapter, + const struct nlattr *attr) +{ + uint8_t priority = nla_get_u8(attr); + + return hdd_set_udp_qos_upgrade_config(adapter, priority); +} + +static int hdd_config_power(struct hdd_adapter *adapter, + const struct nlattr *attr) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - uint8_t qpower; + uint8_t power; - qpower = nla_get_u8(attr); + power = nla_get_u8(attr); - return hdd_set_qpower_config(hdd_ctx, adapter, qpower); + return hdd_set_power_config(hdd_ctx, adapter, power); } static int hdd_config_stats_avg_factor(struct hdd_adapter *adapter, @@ -7441,6 +8048,9 @@ static int hdd_config_latency_level(struct hdd_adapter *adapter, uint16_t latency_level; QDF_STATUS status; + if (!hdd_is_wlm_latency_manager_supported(hdd_ctx)) + return -ENOTSUPP; + latency_level = nla_get_u16(attr); switch (latency_level) { case QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL: @@ -7506,14 +8116,8 @@ static int hdd_config_rsn_ie(struct hdd_adapter *adapter, const struct nlattr *attr) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - bool override_enabled; uint8_t force_rsne_override; - /* ignore unless support explicitly enabled */ - ucfg_mlme_get_force_rsne_override(hdd_ctx->psoc, &override_enabled); - if (!override_enabled) - return 0; - force_rsne_override = nla_get_u8(attr); if (force_rsne_override > 1) { hdd_err("Invalid value %d", force_rsne_override); @@ -7642,7 +8246,7 @@ static const struct independent_setters independent_setters[] = { {QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE, hdd_config_scan_enable}, {QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, - hdd_config_qpower}, + hdd_config_power}, {QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, hdd_config_stats_avg_factor}, {QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, @@ -7695,6 +8299,12 @@ static const struct independent_setters independent_setters[] = { {QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS, hdd_set_elna_bypass}, #endif + {QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON, + hdd_set_roam_reason_vsie_status}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT, + hdd_config_power}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE, + hdd_config_udp_qos_upgrade_threshold}, }; #ifdef WLAN_FEATURE_ELNA @@ -7725,6 +8335,50 @@ static int hdd_get_elna_bypass(struct hdd_adapter *adapter, } #endif +/** + * hdd_get_roam_reason_vsie_status() - Get roam_reason_vsie + * @adapter: Pointer to HDD adapter + * @skb: sk buffer to hold nl80211 attributes + * @attr: Pointer to struct nlattr + * + * Return: 0 on success; error number otherwise + */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static int hdd_get_roam_reason_vsie_status(struct hdd_adapter *adapter, + struct sk_buff *skb, + const struct nlattr *attr) +{ + uint8_t roam_reason_vsie_enabled; + struct hdd_context *hdd_ctx = NULL; + QDF_STATUS status; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + status = ucfg_mlme_get_roam_reason_vsie_status + (hdd_ctx->psoc, + &roam_reason_vsie_enabled); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("get roam reason vsie failed"); + return -EINVAL; + } + hdd_debug("is roam_reason_vsie_enabled %d", roam_reason_vsie_enabled); + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON, + roam_reason_vsie_enabled)) { + hdd_err("nla_put failure"); + return -EINVAL; + } + + return 0; +} +#else +static int hdd_get_roam_reason_vsie_status(struct hdd_adapter *adapter, + struct sk_buff *skb, + const struct nlattr *attr) +{ + return -EINVAL; +} +#endif + /** * typedef config_getter_fn - get configuration handler * @adapter: The adapter being configured @@ -7750,56 +8404,173 @@ struct config_getters { config_getter_fn cb; }; -/* vtable for config getters */ -static const struct config_getters config_getters[] = { -#ifdef WLAN_FEATURE_ELNA - {QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS, - sizeof(uint8_t), - hdd_get_elna_bypass}, -#endif -}; - /** - * hdd_get_configuration() - Handle get configuration - * @adapter: adapter upon which the vendor command was received - * @tb: parsed attribute array - * - * This is a table-driven function which dispatches attributes - * in a QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION - * vendor command. + * hdd_get_optimized_power_config() - Get the number of spatial streams + * supported by the adapter + * @adapter: Pointer to HDD adapter + * @skb: sk buffer to hold nl80211 attributes + * @attr: Pointer to struct nlattr * - * Return: 0 if there were no issues, otherwise errno of the last issue + * Return: 0 on success; error number otherwise */ -static int hdd_get_configuration(struct hdd_adapter *adapter, - struct nlattr **tb) +static int hdd_get_optimized_power_config(struct hdd_adapter *adapter, + struct sk_buff *skb, + const struct nlattr *attr) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - uint32_t i, id; - unsigned long nl_buf_len = NLMSG_HDRLEN; - struct sk_buff *skb; - struct nlattr *attr; - config_getter_fn cb; - int errno = 0; + uint8_t optimized_power_cfg; + int errno; - for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) { - id = config_getters[i].id; - attr = tb[id]; - if (!attr) - continue; + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; - nl_buf_len += NLA_HDRLEN + - NLA_ALIGN(config_getters[i].max_attr_len); - } + optimized_power_cfg = ucfg_pmo_get_power_save_mode(hdd_ctx->psoc); - skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); - if (!skb) { - hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); - return -ENOMEM; + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT, + optimized_power_cfg)) { + hdd_err("nla_put failure"); + return -EINVAL; } - for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) { - id = config_getters[i].id; - attr = tb[id]; + return 0; +} + +/** + * hdd_get_tx_nss_config() - Get the number of tx spatial streams supported by + * the adapter + * @adapter: Pointer to HDD adapter + * @skb: sk buffer to hold nl80211 attributes + * @attr: Pointer to struct nlattr + * + * Return: 0 on success; error number otherwise + */ +static int hdd_get_tx_nss_config(struct hdd_adapter *adapter, + struct sk_buff *skb, + const struct nlattr *attr) +{ + uint8_t tx_nss; + QDF_STATUS status; + + if (!hdd_is_vdev_in_conn_state(adapter)) { + hdd_err("Not in connected state"); + return -EINVAL; + } + + status = hdd_get_tx_nss(adapter, &tx_nss); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Failed to get nss"); + return -EINVAL; + } + + hdd_debug("tx_nss %d", tx_nss); + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS, tx_nss)) { + hdd_err("nla_put failure"); + return -EINVAL; + } + + return 0; +} + +/** + * hdd_get_rx_nss_config() - Get the number of rx spatial streams supported by + * the adapter + * @adapter: Pointer to HDD adapter + * @skb: sk buffer to hold nl80211 attributes + * @attr: Pointer to struct nlattr + * + * Return: 0 on success; error number otherwise + */ +static int hdd_get_rx_nss_config(struct hdd_adapter *adapter, + struct sk_buff *skb, + const struct nlattr *attr) +{ + uint8_t rx_nss; + QDF_STATUS status; + + if (!hdd_is_vdev_in_conn_state(adapter)) { + hdd_err("Not in connected state"); + return -EINVAL; + } + + status = hdd_get_rx_nss(adapter, &rx_nss); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Failed to get nss"); + return -EINVAL; + } + + hdd_debug("rx_nss %d", rx_nss); + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS, rx_nss)) { + hdd_err("nla_put failure"); + return -EINVAL; + } + + return 0; +} + +/* vtable for config getters */ +static const struct config_getters config_getters[] = { +#ifdef WLAN_FEATURE_ELNA + {QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS, + sizeof(uint8_t), + hdd_get_elna_bypass}, +#endif + {QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON, + sizeof(uint8_t), + hdd_get_roam_reason_vsie_status}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT, + sizeof(uint8_t), + hdd_get_optimized_power_config}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS, + sizeof(uint8_t), + hdd_get_tx_nss_config}, + {QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS, + sizeof(uint8_t), + hdd_get_rx_nss_config}, +}; + +/** + * hdd_get_configuration() - Handle get configuration + * @adapter: adapter upon which the vendor command was received + * @tb: parsed attribute array + * + * This is a table-driven function which dispatches attributes + * in a QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION + * vendor command. + * + * Return: 0 if there were no issues, otherwise errno of the last issue + */ +static int hdd_get_configuration(struct hdd_adapter *adapter, + struct nlattr **tb) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint32_t i, id; + unsigned long nl_buf_len = NLMSG_HDRLEN; + struct sk_buff *skb; + struct nlattr *attr; + config_getter_fn cb; + int errno = 0; + + for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) { + id = config_getters[i].id; + attr = tb[id]; + if (!attr) + continue; + + nl_buf_len += NLA_HDRLEN + + NLA_ALIGN(config_getters[i].max_attr_len); + } + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); + if (!skb) { + hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); + return -ENOMEM; + } + + for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) { + id = config_getters[i].id; + attr = tb[id]; if (!attr) continue; @@ -7877,6 +8648,8 @@ static const interdependent_setter_fn interdependent_setters[] = { hdd_config_ant_div_snr_weight, wlan_hdd_cfg80211_wifi_set_reorder_timeout, wlan_hdd_cfg80211_wifi_set_rx_blocksize, + hdd_config_vdev_chains, + hdd_config_tx_rx_nss, }; /** @@ -8094,6 +8867,31 @@ static void hdd_disable_runtime_pm_for_user(struct hdd_context *hdd_ctx) qdf_runtime_pm_prevent_suspend(&ctx->user); } +/** + * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt + * cmd + * @req_type: twt setup request type + * @twt_cmd: pointer to store twt command + * + * Return: QDF_STATUS_SUCCESS on success, else other qdf error values + */ +static QDF_STATUS +hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd) +{ + if (req_type == QCA_WLAN_VENDOR_TWT_SETUP_REQUEST) { + *twt_cmd = WMI_HOST_TWT_COMMAND_REQUEST_TWT; + } else if (req_type == QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST) { + *twt_cmd = WMI_HOST_TWT_COMMAND_SUGGEST_TWT; + } else if (req_type == QCA_WLAN_VENDOR_TWT_SETUP_DEMAND) { + *twt_cmd = WMI_HOST_TWT_COMMAND_DEMAND_TWT; + } else { + hdd_err_rl("Invalid TWT_SETUP_REQ_TYPE %d", req_type); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + /** * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration * vendor command @@ -8629,7 +9427,14 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, hdd_err_rl("TWT_SETUP_REQ_TYPE is must"); goto send_err; } - params.twt_cmd = nla_get_u8(tb2[cmd_id]); + + status = hdd_twt_setup_req_type_to_cmd( + nla_get_u8(tb2[cmd_id]), + ¶ms.twt_cmd); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err_rl("TWT cmd type is invalid"); + goto send_err; + } cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER; if (tb2[cmd_id]) @@ -8993,7 +9798,7 @@ static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy, struct nlattr *tb [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1]; - hdd_enter_dev(wdev->netdev); + hdd_enter(); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); @@ -9236,8 +10041,8 @@ wlan_hdd_add_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, } nla_memcpy(add_req->mac_address.bytes, tb[PARAM_SRC_MAC_ADDR], QDF_MAC_ADDR_SIZE); - hdd_debug("input src mac address: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(add_req->mac_address.bytes)); + hdd_debug("input src mac address: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(add_req->mac_address.bytes)); if (!qdf_is_macaddr_equal(&add_req->mac_address, &adapter->mac_addr)) { @@ -9252,8 +10057,8 @@ wlan_hdd_add_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, goto fail; } nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], QDF_MAC_ADDR_SIZE); - hdd_debug("input dst mac address: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(dst_addr.bytes)); + hdd_debug("input dst mac address: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(dst_addr.bytes)); if (!tb[PARAM_IP_PACKET]) { hdd_err("attr ip packet failed"); @@ -9364,8 +10169,8 @@ wlan_hdd_del_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, return -ENOMEM; qdf_copy_macaddr(&del_req->mac_address, &adapter->mac_addr); - hdd_debug(QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(del_req->mac_address.bytes)); + hdd_debug(QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(del_req->mac_address.bytes)); del_req->ucPtrnId = pattern_id; hdd_debug("Request Id: %u Pattern id: %d", request_id, del_req->ucPtrnId); @@ -9630,15 +10435,7 @@ static uint32_t wlan_hdd_populate_weigh_pcl( /* convert channel number to frequency */ for (i = 0; i < chan_weights->pcl_len; i++) { - if (chan_weights->pcl_list[i] <= - ARRAY_SIZE(hdd_channels_2_4_ghz)) - w_pcl[i].freq = ieee80211_channel_to_frequency( - chan_weights->pcl_list[i], - HDD_NL80211_BAND_2GHZ); - else - w_pcl[i].freq = ieee80211_channel_to_frequency( - chan_weights->pcl_list[i], - HDD_NL80211_BAND_5GHZ); + w_pcl[i].freq = chan_weights->pcl_list[i]; w_pcl[i].weight = chan_weights->weight_list[i]; if (intf_mode == PM_SAP_MODE || intf_mode == PM_P2P_GO_MODE) @@ -9663,17 +10460,8 @@ static uint32_t wlan_hdd_populate_weigh_pcl( break; } if (j == chan_weights->pcl_len) { - if (chan_weights->saved_chan_list[i] <= - ARRAY_SIZE(hdd_channels_2_4_ghz)) - w_pcl[chan_idx].freq = - ieee80211_channel_to_frequency( - chan_weights->saved_chan_list[i], - HDD_NL80211_BAND_2GHZ); - else - w_pcl[chan_idx].freq = - ieee80211_channel_to_frequency( - chan_weights->saved_chan_list[i], - HDD_NL80211_BAND_5GHZ); + w_pcl[chan_idx].freq = + chan_weights->saved_chan_list[i]; if (!chan_weights->weighed_valid_list[i]) { w_pcl[chan_idx].flag = @@ -9716,8 +10504,8 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, QDF_STATUS status; uint32_t pcl_len = 0; uint32_t pcl_len_legacy = 0; - uint32_t freq_list[QDF_MAX_NUM_CHAN]; - uint32_t freq_list_legacy[QDF_MAX_NUM_CHAN]; + uint32_t freq_list[NUM_CHANNELS]; + uint32_t freq_list_legacy[NUM_CHANNELS]; enum policy_mgr_con_mode intf_mode; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX + 1]; struct sk_buff *reply_skb; @@ -9759,11 +10547,10 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, if (!chan_weights) return -ENOMEM; - status = policy_mgr_get_pcl(hdd_ctx->psoc, - intf_mode, chan_weights->pcl_list, - &chan_weights->pcl_len, - chan_weights->weight_list, - QDF_ARRAY_SIZE(chan_weights->weight_list)); + status = policy_mgr_get_pcl( + hdd_ctx->psoc, intf_mode, chan_weights->pcl_list, + &chan_weights->pcl_len, chan_weights->weight_list, + QDF_ARRAY_SIZE(chan_weights->weight_list)); if (status != QDF_STATUS_SUCCESS) { hdd_err("Get pcl failed"); qdf_mem_free(chan_weights); @@ -9776,21 +10563,13 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, * QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_WEIGHED_PCL. */ pcl_len_legacy = chan_weights->pcl_len; - for (i = 0; i < pcl_len_legacy; i++) { - if (WLAN_REG_IS_24GHZ_CH(chan_weights->pcl_list[i])) - freq_list_legacy[i] = - ieee80211_channel_to_frequency(chan_weights->pcl_list[i], - HDD_NL80211_BAND_2GHZ); - else - freq_list_legacy[i] = - ieee80211_channel_to_frequency(chan_weights->pcl_list[i], - HDD_NL80211_BAND_5GHZ); - } - chan_weights->saved_num_chan = POLICY_MGR_MAX_CHANNEL_LIST; + for (i = 0; i < pcl_len_legacy; i++) + freq_list_legacy[i] = chan_weights->pcl_list[i]; + chan_weights->saved_num_chan = NUM_CHANNELS; sme_get_valid_channels(chan_weights->saved_chan_list, &chan_weights->saved_num_chan); policy_mgr_get_valid_chan_weights(hdd_ctx->psoc, chan_weights); - w_pcl = qdf_mem_malloc(sizeof(struct weighed_pcl) * QDF_MAX_NUM_CHAN); + w_pcl = qdf_mem_malloc(sizeof(struct weighed_pcl) * NUM_CHANNELS); if (!w_pcl) { qdf_mem_free(chan_weights); return -ENOMEM; @@ -9925,7 +10704,7 @@ static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy, int ret = 0; enum policy_mgr_con_mode intf_mode; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX + 1]; - uint32_t channel_hint; + uint32_t ch_freq; hdd_enter_dev(ndev); @@ -9959,12 +10738,11 @@ static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy, return -EINVAL; } - channel_hint = cds_freq_to_chan(nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ])); - + ch_freq = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ]); /* check pcl table */ if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, intf_mode, - channel_hint, HW_MODE_20_MHZ)) { + ch_freq, HW_MODE_20_MHZ)) { hdd_err("Set channel hint failed due to concurrency check"); return -EINVAL; } @@ -9972,7 +10750,7 @@ static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy, if (0 != wlan_hdd_check_remain_on_channel(adapter)) hdd_warn("Remain On Channel Pending"); - if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, channel_hint, + if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, ch_freq, POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { hdd_err("Failed to change hw mode"); return -EINVAL; @@ -10038,9 +10816,9 @@ static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy, struct net_device *dev = wdev->netdev; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_station_ctx *hdd_sta_ctx; + struct hdd_station_info *sta_info; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1]; uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; - uint32_t sta_id; struct sk_buff *reply_skb; uint32_t rate_flags = 0; uint8_t nss; @@ -10077,8 +10855,8 @@ static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy, qdf_mem_copy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), QDF_MAC_ADDR_SIZE); - hdd_debug("peerMac="QDF_MAC_ADDR_STR" for device_mode:%d", - QDF_MAC_ADDR_ARRAY(peer_mac), adapter->device_mode); + hdd_debug("peerMac="QDF_MAC_ADDR_FMT" for device_mode:%d", + QDF_MAC_ADDR_REF(peer_mac), adapter->device_mode); if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) { @@ -10087,41 +10865,40 @@ static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy, eConnectionState_Associated) || qdf_mem_cmp(hdd_sta_ctx->conn_info.bssid.bytes, peer_mac, QDF_MAC_ADDR_SIZE)) { - hdd_err("Not Associated to mac "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_mac)); + hdd_err("Not Associated to mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); return -EINVAL; } nss = hdd_sta_ctx->conn_info.nss; - freq = cds_chan_to_freq( - hdd_sta_ctx->conn_info.channel); + freq = hdd_sta_ctx->conn_info.chan_freq; rate_flags = hdd_sta_ctx->conn_info.rate_flags; } else if (adapter->device_mode == QDF_P2P_GO_MODE || adapter->device_mode == QDF_SAP_MODE) { - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - if (adapter->sta_info[sta_id].in_use && - !qdf_is_macaddr_broadcast( - &adapter->sta_info[sta_id].sta_mac) && - !qdf_mem_cmp( - &adapter->sta_info[sta_id].sta_mac.bytes, - peer_mac, QDF_MAC_ADDR_SIZE)) - break; + if (QDF_IS_ADDR_BROADCAST(peer_mac)) { + hdd_err("Ignore bcast/self sta"); + return -EINVAL; } - if (WLAN_MAX_STA_COUNT == sta_id) { - hdd_err("No active peer with mac="QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_mac)); + sta_info = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, peer_mac, + STA_INFO_CFG80211_GET_LINK_PROPERTIES); + + if (!sta_info) { + hdd_err("No active peer with mac = " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); return -EINVAL; } - nss = adapter->sta_info[sta_id].nss; - freq = cds_chan_to_freq( - (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_channel); - rate_flags = adapter->sta_info[sta_id].rate_flags; + nss = sta_info->nss; + freq = (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_chan_freq; + rate_flags = sta_info->rate_flags; + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_CFG80211_GET_LINK_PROPERTIES); } else { - hdd_err("Not Associated! with mac "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_mac)); + hdd_err("Not Associated! with mac "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); return -EINVAL; } @@ -10215,15 +10992,17 @@ static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy, static const struct nla_policy wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY] = {.type = NLA_U32}, [QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST] = { - .type = NLA_NESTED }, + .type = NLA_NESTED}, }; static const struct nla_policy wlan_hdd_set_acs_dfs_config_policy[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT] = {.type = NLA_U32}, }; /** @@ -10253,7 +11032,7 @@ __wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy, int ret; struct acs_dfs_policy *acs_policy; int mode = DFS_MODE_NONE; - int channel_hint = 0; + uint32_t freq_hint = 0; hdd_enter_dev(wdev->netdev); @@ -10291,15 +11070,25 @@ __wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy, * SCM sends this attribute to provide an active channel, * to skip redundant ACS between drivers, and save driver start up time */ - if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]) - channel_hint = nla_get_u8( + if (tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT]) { + freq_hint = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT]); + } else if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]) { + uint32_t channel_hint = nla_get_u8( tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]); - if (!IS_CHANNEL_VALID(channel_hint)) { - hdd_err("acs channel is not valid"); + freq_hint = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, + channel_hint); + } + + if (freq_hint && !WLAN_REG_IS_24GHZ_CH_FREQ(freq_hint) && + !WLAN_REG_IS_5GHZ_CH_FREQ(freq_hint) && + !WLAN_REG_IS_6GHZ_CHAN_FREQ(freq_hint)) { + hdd_err("acs channel frequency is not valid"); return -EINVAL; } - acs_policy->acs_channel = channel_hint; + + acs_policy->acs_chan_freq = freq_hint; return 0; } @@ -10365,21 +11154,28 @@ static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode( */ uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; - uint8_t operating_channel = 0; + struct hdd_adapter *adapter, *next_adapter = NULL; + uint32_t operating_chan_freq; uint8_t sap_operating_band = 0; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_SAP_OPERATING_BAND; - hdd_for_each_adapter(hdd_ctx, adapter) { - if (adapter->device_mode != QDF_SAP_MODE) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->device_mode != QDF_SAP_MODE) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } - operating_channel = adapter->session.ap.operating_channel; - if (IS_24G_CH(operating_channel)) + operating_chan_freq = adapter->session.ap.operating_chan_freq; + if (WLAN_REG_IS_24GHZ_CH_FREQ(operating_chan_freq)) sap_operating_band = BAND_2G; - else if (IS_5G_CH(operating_channel)) + else if (WLAN_REG_IS_5GHZ_CH_FREQ(operating_chan_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(operating_chan_freq)) sap_operating_band = BAND_5G; else sap_operating_band = BAND_ALL; + + hdd_adapter_dev_put_debug(adapter, dbgid); } return sap_operating_band; @@ -10512,6 +11308,7 @@ static int hdd_validate_avoid_freq_chanlist( unsigned int range_idx, ch_idx; unsigned int unsafe_channel_index, unsafe_channel_count = 0; bool ch_found = false; + uint32_t ch_idx_freq; unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, (uint16_t)NUM_CHANNELS); @@ -10533,21 +11330,23 @@ static int hdd_validate_avoid_freq_chanlist( ch_idx++) { if (INVALID_CHANNEL == wlan_reg_get_chan_enum(ch_idx)) continue; + ch_idx_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, + ch_idx); for (unsafe_channel_index = 0; unsafe_channel_index < unsafe_channel_count; unsafe_channel_index++) { - if (ch_idx == + if (ch_idx_freq == hdd_ctx->unsafe_channel_list[ unsafe_channel_index]) { - hdd_info("Duplicate channel %d", - ch_idx); + hdd_info("Duplicate channel freq %d", + ch_idx_freq); ch_found = true; break; } } if (!ch_found) { hdd_ctx->unsafe_channel_list[ - unsafe_channel_count++] = ch_idx; + unsafe_channel_count++] = (uint16_t)ch_idx_freq; } ch_found = false; } @@ -10661,7 +11460,7 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy, for (unsafe_channel_index = 0; unsafe_channel_index < unsafe_channel_count; unsafe_channel_index++) { - hdd_debug("Channel %d is not safe", + hdd_debug("Channel frequency %d is not safe", hdd_ctx->unsafe_channel_list[unsafe_channel_index]); } if (hdd_local_unsafe_channel_updated(hdd_ctx, local_unsafe_list, @@ -10730,9 +11529,10 @@ __wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, struct hdd_adapter *hostapd_adapter = WLAN_HDD_GET_PRIV_PTR(ndev); struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1]; - uint8_t config_channel = 0; struct hdd_ap_ctx *ap_ctx; int ret; + uint32_t chan_freq = 0; + bool chan_freq_present = false; QDF_STATUS status; hdd_enter(); @@ -10753,33 +11553,44 @@ __wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, return -EINVAL; } - if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]) { + if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY]) { + chan_freq = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY]); + chan_freq_present = true; + } else if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]) { + uint32_t config_channel = + nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]); + + chan_freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, + config_channel); + chan_freq_present = true; + } + + if (chan_freq_present) { if (!test_bit(SOFTAP_BSS_STARTED, &hostapd_adapter->event_flags)) { hdd_err("SAP is not started yet. Restart sap will be invalid"); return -EINVAL; } - config_channel = - nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]); - - if (!((IS_24G_CH(config_channel)) || - (IS_5G_CH(config_channel)))) { - hdd_err("Channel %d is not valid to restart SAP", - config_channel); + if (!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq) && + !WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) && + !WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq)) { + hdd_err("Channel frequency %u is invalid to restart SAP", + chan_freq); return -ENOTSUPP; } ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter); - ap_ctx->sap_config.channel = config_channel; + ap_ctx->sap_config.chan_freq = chan_freq; ap_ctx->sap_config.ch_params.ch_width = ap_ctx->sap_config.ch_width_orig; ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN; - wlan_reg_set_channel_params(hdd_ctx->pdev, - ap_ctx->sap_config.channel, - ap_ctx->sap_config.sec_ch, - &ap_ctx->sap_config.ch_params); + wlan_reg_set_channel_params_for_freq( + hdd_ctx->pdev, chan_freq, + ap_ctx->sap_config.sec_ch_freq, + &ap_ctx->sap_config.ch_params); hdd_restart_sap(hostapd_adapter); } @@ -10787,7 +11598,6 @@ __wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, if (tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST]) { uint32_t freq_len, i; uint32_t *freq; - uint8_t chans[QDF_MAX_NUM_CHAN]; hdd_debug("setting mandatory freq/chan list"); @@ -10795,7 +11605,7 @@ __wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST])/ sizeof(uint32_t); - if (freq_len > QDF_MAX_NUM_CHAN) { + if (freq_len > NUM_CHANNELS) { hdd_err("insufficient space to hold channels"); return -ENOMEM; } @@ -10806,12 +11616,11 @@ __wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, hdd_debug("freq_len=%d", freq_len); for (i = 0; i < freq_len; i++) { - chans[i] = ieee80211_frequency_to_channel(freq[i]); hdd_debug("freq[%d]=%d", i, freq[i]); } status = policy_mgr_set_sap_mandatory_channels( - hdd_ctx->psoc, chans, freq_len); + hdd_ctx->psoc, freq, freq_len); if (QDF_IS_STATUS_ERROR(status)) return -EINVAL; } @@ -10852,194 +11661,6 @@ static int wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy, return errno; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * define short names for the global vendor params - * used by wlan_hdd_cfg80211_wakelock_stats_rsp_callback() - */ -#define PARAM_TOTAL_CMD_EVENT_WAKE \ - QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE -#define PARAM_CMD_EVENT_WAKE_CNT_PTR \ - QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR -#define PARAM_CMD_EVENT_WAKE_CNT_SZ \ - QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ -#define PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE \ - QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE -#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR \ - QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR -#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ \ - QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ -#define PARAM_TOTAL_RX_DATA_WAKE \ - QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE -#define PARAM_RX_UNICAST_CNT \ - QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT -#define PARAM_RX_MULTICAST_CNT \ - QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT -#define PARAM_RX_BROADCAST_CNT \ - QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT -#define PARAM_ICMP_PKT \ - QCA_WLAN_VENDOR_ATTR_ICMP_PKT -#define PARAM_ICMP6_PKT \ - QCA_WLAN_VENDOR_ATTR_ICMP6_PKT -#define PARAM_ICMP6_RA \ - QCA_WLAN_VENDOR_ATTR_ICMP6_RA -#define PARAM_ICMP6_NA \ - QCA_WLAN_VENDOR_ATTR_ICMP6_NA -#define PARAM_ICMP6_NS \ - QCA_WLAN_VENDOR_ATTR_ICMP6_NS -#define PARAM_ICMP4_RX_MULTICAST_CNT \ - QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT -#define PARAM_ICMP6_RX_MULTICAST_CNT \ - QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT -#define PARAM_OTHER_RX_MULTICAST_CNT \ - QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT -#define PARAM_RSSI_BREACH_CNT \ - QCA_WLAN_VENDOR_ATTR_RSSI_BREACH_CNT -#define PARAM_LOW_RSSI_CNT \ - QCA_WLAN_VENDOR_ATTR_LOW_RSSI_CNT -#define PARAM_GSCAN_CNT \ - QCA_WLAN_VENDOR_ATTR_GSCAN_CNT -#define PARAM_PNO_COMPLETE_CNT \ - QCA_WLAN_VENDOR_ATTR_PNO_COMPLETE_CNT -#define PARAM_PNO_MATCH_CNT \ - QCA_WLAN_VENDOR_ATTR_PNO_MATCH_CNT - -/** - * hdd_send_wakelock_stats() - API to send wakelock stats - * @ctx: context to be passed to callback - * @data: data passed to callback - * - * This function is used to send wake lock stats to HAL layer - * - * Return: 0 on success, error number otherwise. - */ -static uint32_t hdd_send_wakelock_stats(struct hdd_context *hdd_ctx, - const struct sir_wake_lock_stats *data) -{ - struct sk_buff *skb; - uint32_t nl_buf_len; - uint32_t total_rx_data_wake, rx_multicast_cnt; - uint32_t ipv6_rx_multicast_addr_cnt; - uint32_t icmpv6_cnt; - - hdd_enter(); - - nl_buf_len = NLMSG_HDRLEN; - nl_buf_len += - QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX * - (NLMSG_HDRLEN + sizeof(uint32_t)); - - skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); - - if (!skb) { - hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); - return -ENOMEM; - } - - hdd_debug("wow_ucast_wake_up_count %d", - data->wow_ucast_wake_up_count); - hdd_debug("wow_bcast_wake_up_count %d", - data->wow_bcast_wake_up_count); - hdd_debug("wow_ipv4_mcast_wake_up_count %d", - data->wow_ipv4_mcast_wake_up_count); - hdd_debug("wow_ipv6_mcast_wake_up_count %d", - data->wow_ipv6_mcast_wake_up_count); - hdd_debug("wow_ipv6_mcast_ra_stats %d", - data->wow_ipv6_mcast_ra_stats); - hdd_debug("wow_ipv6_mcast_ns_stats %d", - data->wow_ipv6_mcast_ns_stats); - hdd_debug("wow_ipv6_mcast_na_stats %d", - data->wow_ipv6_mcast_na_stats); - hdd_debug("wow_icmpv4_count %d", data->wow_icmpv4_count); - hdd_debug("wow_icmpv6_count %d", - data->wow_icmpv6_count); - hdd_debug("wow_rssi_breach_wake_up_count %d", - data->wow_rssi_breach_wake_up_count); - hdd_debug("wow_low_rssi_wake_up_count %d", - data->wow_low_rssi_wake_up_count); - hdd_debug("wow_gscan_wake_up_count %d", - data->wow_gscan_wake_up_count); - hdd_debug("wow_pno_complete_wake_up_count %d", - data->wow_pno_complete_wake_up_count); - hdd_debug("wow_pno_match_wake_up_count %d", - data->wow_pno_match_wake_up_count); - - ipv6_rx_multicast_addr_cnt = - data->wow_ipv6_mcast_wake_up_count; - - icmpv6_cnt = - data->wow_icmpv6_count; - - rx_multicast_cnt = - data->wow_ipv4_mcast_wake_up_count + - ipv6_rx_multicast_addr_cnt; - - total_rx_data_wake = - data->wow_ucast_wake_up_count + - data->wow_bcast_wake_up_count + - rx_multicast_cnt; - - if (nla_put_u32(skb, PARAM_TOTAL_CMD_EVENT_WAKE, 0) || - nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_PTR, 0) || - nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_SZ, 0) || - nla_put_u32(skb, PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE, 0) || - nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR, 0) || - nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ, 0) || - nla_put_u32(skb, PARAM_TOTAL_RX_DATA_WAKE, - total_rx_data_wake) || - nla_put_u32(skb, PARAM_RX_UNICAST_CNT, - data->wow_ucast_wake_up_count) || - nla_put_u32(skb, PARAM_RX_MULTICAST_CNT, - rx_multicast_cnt) || - nla_put_u32(skb, PARAM_RX_BROADCAST_CNT, - data->wow_bcast_wake_up_count) || - nla_put_u32(skb, PARAM_ICMP_PKT, - data->wow_icmpv4_count) || - nla_put_u32(skb, PARAM_ICMP6_PKT, - icmpv6_cnt) || - nla_put_u32(skb, PARAM_ICMP6_RA, - data->wow_ipv6_mcast_ra_stats) || - nla_put_u32(skb, PARAM_ICMP6_NA, - data->wow_ipv6_mcast_na_stats) || - nla_put_u32(skb, PARAM_ICMP6_NS, - data->wow_ipv6_mcast_ns_stats) || - nla_put_u32(skb, PARAM_ICMP4_RX_MULTICAST_CNT, - data->wow_ipv4_mcast_wake_up_count) || - nla_put_u32(skb, PARAM_ICMP6_RX_MULTICAST_CNT, - ipv6_rx_multicast_addr_cnt) || - nla_put_u32(skb, PARAM_OTHER_RX_MULTICAST_CNT, 0) || - nla_put_u32(skb, PARAM_RSSI_BREACH_CNT, - data->wow_rssi_breach_wake_up_count) || - nla_put_u32(skb, PARAM_LOW_RSSI_CNT, - data->wow_low_rssi_wake_up_count) || - nla_put_u32(skb, PARAM_GSCAN_CNT, - data->wow_gscan_wake_up_count) || - nla_put_u32(skb, PARAM_PNO_COMPLETE_CNT, - data->wow_pno_complete_wake_up_count) || - nla_put_u32(skb, PARAM_PNO_MATCH_CNT, - data->wow_pno_match_wake_up_count)) { - hdd_err("nla put fail"); - goto nla_put_failure; - } - - cfg80211_vendor_cmd_reply(skb); - - hdd_exit(); - return 0; - -nla_put_failure: - kfree_skb(skb); - return -EINVAL; -} -#endif - -#ifdef QCA_SUPPORT_CP_STATS -static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx) -{ - return wlan_cfg80211_mc_cp_stats_get_wakelock_stats(hdd_ctx->psoc, - hdd_ctx->wiphy); -} -#else /** * wlan_hdd_process_wake_lock_stats() - wrapper function to absract cp_stats * or legacy get_wake_lock_stats API. @@ -11049,23 +11670,9 @@ static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx) */ static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx) { - int ret; - QDF_STATUS qdf_status; - struct sir_wake_lock_stats wake_lock_stats = {0}; - - qdf_status = wma_get_wakelock_stats(&wake_lock_stats); - if (qdf_status != QDF_STATUS_SUCCESS) { - hdd_err("failed to get wakelock stats(err=%d)", qdf_status); - return -EINVAL; - } - - ret = hdd_send_wakelock_stats(hdd_ctx, &wake_lock_stats); - if (ret) - hdd_err("Failed to post wake lock stats"); - - return ret; + return wlan_cfg80211_mc_cp_stats_get_wakelock_stats(hdd_ctx->psoc, + hdd_ctx->wiphy); } -#endif /** * __wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats @@ -11225,6 +11832,26 @@ static int wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy, return errno; } +const struct nla_policy setband_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_SETBAND_MASK] = {.type = NLA_U32}, +}; + +static uint32_t +wlan_vendor_bitmap_to_reg_wifi_band_bitmap(uint32_t vendor_bitmap) +{ + uint32_t reg_bitmap = 0; + + if (vendor_bitmap & QCA_SETBAND_2G) + reg_bitmap |= BIT(REG_BAND_2G); + if (vendor_bitmap & QCA_SETBAND_5G) + reg_bitmap |= BIT(REG_BAND_5G); + if (vendor_bitmap & QCA_SETBAND_6G) + reg_bitmap |= BIT(REG_BAND_6G); + + return reg_bitmap; +} + /** *__wlan_hdd_cfg80211_setband() - set band * @wiphy: Pointer to wireless phy @@ -11242,8 +11869,7 @@ static int __wlan_hdd_cfg80211_setband(struct wiphy *wiphy, struct net_device *dev = wdev->netdev; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; int ret; - static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] - = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 } }; + uint32_t reg_wifi_band_bitmap = 0, band_val, band_mask; hdd_enter(); @@ -11252,36 +11878,51 @@ static int __wlan_hdd_cfg80211_setband(struct wiphy *wiphy, return ret; if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, - data, data_len, policy)) { + data, data_len, setband_policy)) { hdd_err("Invalid ATTR"); return -EINVAL; } - if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) { + if (tb[QCA_WLAN_VENDOR_ATTR_SETBAND_MASK]) { + band_mask = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_MASK]); + reg_wifi_band_bitmap = + wlan_vendor_bitmap_to_reg_wifi_band_bitmap(band_mask); + } else if (tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) { + band_val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]); + reg_wifi_band_bitmap = + hdd_reg_legacy_setband_to_reg_wifi_band_bitmap( + band_val); + } + + if (!reg_wifi_band_bitmap) { hdd_err("attr SETBAND_VALUE failed"); return -EINVAL; } - ret = hdd_reg_set_band(dev, - nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE])); + ret = hdd_reg_set_band(dev, reg_wifi_band_bitmap); hdd_exit(); return ret; } /** - *wlan_hdd_validate_acs_channel() - validate channel provided by ACS + *wlan_hdd_validate_acs_channel() - validate channel frequency provided by ACS * @adapter: hdd adapter - * @channel: channel number + * @chan_freq: channel frequency in MHz * * return: QDF status based on success or failure */ static QDF_STATUS wlan_hdd_validate_acs_channel(struct hdd_adapter *adapter, - int channel, int chan_bw) + uint32_t chan_freq, int chan_bw) { + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint8_t channel; + if (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, channel)) + wlan_hdd_validate_operation_channel(adapter, chan_freq)) return QDF_STATUS_E_FAILURE; + + channel = (uint8_t)wlan_reg_freq_to_chan(hdd_ctx->pdev, chan_freq); if ((wlansap_is_channel_in_nol_list(WLAN_HDD_GET_SAP_CTX_PTR(adapter), channel, PHY_SINGLE_CHANNEL_CENTERED))) { @@ -11308,16 +11949,21 @@ static void hdd_update_acs_sap_config(struct hdd_context *hdd_ctx, QDF_STATUS status; uint32_t channel_bonding_mode; - sap_config->channel = channel_list->pri_ch; + sap_config->chan_freq = channel_list->pri_chan_freq; sap_config->ch_params.center_freq_seg0 = - channel_list->vht_seg0_center_ch; + wlan_reg_freq_to_chan(hdd_ctx->pdev, + channel_list->vht_seg0_center_chan_freq); sap_config->ch_params.center_freq_seg1 = - channel_list->vht_seg1_center_ch; + wlan_reg_freq_to_chan(hdd_ctx->pdev, + channel_list->vht_seg1_center_chan_freq); + + sap_config->ch_params.sec_ch_offset = + wlan_reg_freq_to_chan(hdd_ctx->pdev, + channel_list->ht_sec_chan_freq); - sap_config->ch_params.sec_ch_offset = channel_list->ht_sec_ch; sap_config->ch_params.ch_width = channel_list->chan_width; - if (sap_config->channel >= 36) { + if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_config->chan_freq)) { status = ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc, &ch_width); @@ -11330,13 +11976,14 @@ static void hdd_update_acs_sap_config(struct hdd_context *hdd_ctx, sap_config->ch_width_orig = channel_bonding_mode ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ; } - sap_config->acs_cfg.pri_ch = channel_list->pri_ch; + sap_config->acs_cfg.pri_ch_freq = channel_list->pri_chan_freq; sap_config->acs_cfg.ch_width = channel_list->chan_width; - sap_config->acs_cfg.vht_seg0_center_ch = - channel_list->vht_seg0_center_ch; - sap_config->acs_cfg.vht_seg1_center_ch = - channel_list->vht_seg1_center_ch; - sap_config->acs_cfg.ht_sec_ch = channel_list->ht_sec_ch; + sap_config->acs_cfg.vht_seg0_center_ch_freq = + channel_list->vht_seg0_center_chan_freq; + sap_config->acs_cfg.vht_seg1_center_ch_freq = + channel_list->vht_seg1_center_chan_freq; + sap_config->acs_cfg.ht_sec_ch_freq = + channel_list->ht_sec_chan_freq; } static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, @@ -11348,6 +11995,7 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); QDF_STATUS status = QDF_STATUS_SUCCESS; mac_handle_t mac_handle; + uint32_t ch; if (!channel_list) { hdd_err("channel_list is NULL"); @@ -11363,9 +12011,9 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer); } - if (channel_list->pri_ch == 0) { + if (channel_list->pri_chan_freq == 0) { /* Check mode, set default channel */ - channel_list->pri_ch = 6; + channel_list->pri_chan_freq = 2437; /* * sap_select_default_oper_chan(mac_handle, * sap_config->acs_cfg.hw_mode); @@ -11383,9 +12031,11 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, /* DFS detected on current channel */ case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: + ch = wlan_reg_freq_to_chan(hdd_ctx->pdev, + channel_list->pri_chan_freq); + wlan_sap_update_next_channel( - WLAN_HDD_GET_SAP_CTX_PTR(adapter), - channel_list->pri_ch, + WLAN_HDD_GET_SAP_CTX_PTR(adapter), (uint8_t)ch, channel_list->chan_width); status = sme_update_new_channel_event( mac_handle, @@ -11394,14 +12044,15 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, /* LTE coex event on current channel */ case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: - sap_config->acs_cfg.pri_ch = channel_list->pri_ch; + ch = wlan_reg_freq_to_chan(hdd_ctx->pdev, + channel_list->pri_chan_freq); + sap_config->acs_cfg.pri_ch_freq = channel_list->pri_chan_freq; sap_config->acs_cfg.ch_width = channel_list->chan_width; hdd_ap_ctx->sap_config.ch_width_orig = channel_list->chan_width; wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id, CSA_REASON_LTE_COEX); - hdd_switch_sap_channel(adapter, sap_config->acs_cfg.pri_ch, - true); + hdd_switch_sap_channel(adapter, (uint8_t)ch, true); break; default: @@ -11426,12 +12077,24 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 #define SET_CHAN_CHANNEL_WIDTH \ QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH -#define SET_CHAN_MAX QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX + +#define SET_CHAN_FREQ_LIST QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST +#define SET_CHAN_FREQUENCY_PRIMARY \ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY +#define SET_CHAN_FREQUENCY_SECONDARY \ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY +#define SET_CHAN_SEG0_CENTER_FREQUENCY \ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 +#define SET_CHAN_SEG1_CENTER_FREQUENCY \ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 + +#define SET_CHAN_MAX QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX #define SET_EXT_ACS_BAND QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND static const struct nla_policy acs_chan_config_policy[SET_CHAN_MAX + 1] = { [SET_CHAN_REASON] = {.type = NLA_U8}, [SET_CHAN_CHAN_LIST] = {.type = NLA_NESTED}, + [SET_CHAN_FREQ_LIST] = {.type = NLA_NESTED}, }; static const struct nla_policy acs_chan_list_policy[SET_CHAN_MAX + 1] = { @@ -11441,21 +12104,29 @@ static const struct nla_policy acs_chan_list_policy[SET_CHAN_MAX + 1] = { [SET_CHAN_SEG1_CENTER_CHANNEL] = {.type = NLA_U8}, [SET_CHAN_CHANNEL_WIDTH] = {.type = NLA_U8}, [SET_EXT_ACS_BAND] = {.type = NLA_U8}, + + [SET_CHAN_FREQUENCY_PRIMARY] = {.type = NLA_U32}, + [SET_CHAN_FREQUENCY_SECONDARY] = {.type = NLA_U32}, + [SET_CHAN_SEG0_CENTER_FREQUENCY] = {.type = NLA_U32}, + [SET_CHAN_SEG1_CENTER_FREQUENCY] = {.type = NLA_U32}, }; /** - * hdd_parse_vendor_acs_chan_config() - API to parse vendor acs channel config - * @channel_list: pointer to hdd_vendor_chan_info - * @reason: channel change reason + * hdd_extract_external_acs_frequencies() - API to parse and extract vendor acs + * channel frequency (in MHz) configuration. + * @hdd_ctx: pointer to hdd context + * @list_ptr: pointer to hdd_vendor_chan_info * @channel_cnt: channel count * @data: data * @data_len: data len * * Return: 0 on success, negative errno on failure */ -static int hdd_parse_vendor_acs_chan_config(struct hdd_vendor_chan_info - **chan_list_ptr, uint8_t *reason, uint8_t *channel_cnt, - const void *data, int data_len) +static int +hdd_extract_external_acs_frequencies(struct hdd_context *hdd_ctx, + struct hdd_vendor_chan_info **list_ptr, + uint8_t *channel_cnt, + const void *data, int data_len) { int rem; uint32_t i = 0; @@ -11470,89 +12141,256 @@ static int hdd_parse_vendor_acs_chan_config(struct hdd_vendor_chan_info return -EINVAL; } - if (tb[SET_CHAN_REASON]) - *reason = nla_get_u8(tb[SET_CHAN_REASON]); + nla_for_each_nested(curr_attr, tb[SET_CHAN_FREQ_LIST], rem) + i++; - if (!tb[SET_CHAN_CHAN_LIST]) { - hdd_err("channel list empty"); + if (!i) { + hdd_err_rl("Error: channel count is zero"); return -EINVAL; } - nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) - i++; - - if (i > MAX_CHANNEL) { - hdd_err("Error: Exceeded max channels: %u", MAX_CHANNEL); + if (i > NUM_CHANNELS) { + hdd_err_rl("Error: Exceeded max channels: %u", NUM_CHANNELS); return -ENOMEM; } - *channel_cnt = (uint8_t)i; - - if (i == 0) - hdd_err("incorrect channel count"); - - channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) * - (*channel_cnt)); + channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) * i); if (!channel_list) return -ENOMEM; + *channel_cnt = (uint8_t)i; i = 0; - nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) { + nla_for_each_nested(curr_attr, tb[SET_CHAN_FREQ_LIST], rem) { if (wlan_cfg80211_nla_parse_nested(tb2, SET_CHAN_MAX, curr_attr, acs_chan_list_policy)) { - hdd_err("nla_parse failed"); + hdd_err_rl("nla_parse failed"); qdf_mem_free(channel_list); + *channel_cnt = 0; return -EINVAL; } - if (tb2[SET_EXT_ACS_BAND]) { + + if (tb2[SET_EXT_ACS_BAND]) channel_list[i].band = nla_get_u8(tb2[SET_EXT_ACS_BAND]); - } - /* Parse and Fetch allowed SSID list*/ - if (tb2[SET_CHAN_PRIMARY_CHANNEL]) { - channel_list[i].pri_ch = - nla_get_u8( - tb2[SET_CHAN_PRIMARY_CHANNEL]); - } - if (tb2[SET_CHAN_SECONDARY_CHANNEL]) { - channel_list[i].ht_sec_ch = - nla_get_u8(tb2[SET_CHAN_SECONDARY_CHANNEL]); - } - if (tb2[SET_CHAN_SEG0_CENTER_CHANNEL]) { - channel_list[i].vht_seg0_center_ch = - nla_get_u8(tb2[SET_CHAN_SEG0_CENTER_CHANNEL]); - } - if (tb2[SET_CHAN_SEG1_CENTER_CHANNEL]) { - channel_list[i].vht_seg1_center_ch = - nla_get_u8(tb2[SET_CHAN_SEG1_CENTER_CHANNEL]); - } - if (tb2[SET_CHAN_CHANNEL_WIDTH]) { + + if (tb2[SET_CHAN_FREQUENCY_PRIMARY]) + channel_list[i].pri_chan_freq = + nla_get_u32(tb2[SET_CHAN_FREQUENCY_PRIMARY]); + + if (tb2[SET_CHAN_FREQUENCY_SECONDARY]) + channel_list[i].ht_sec_chan_freq = + nla_get_u32(tb2[SET_CHAN_FREQUENCY_SECONDARY]); + + if (tb2[SET_CHAN_SEG0_CENTER_FREQUENCY]) + channel_list[i].vht_seg0_center_chan_freq = + nla_get_u32(tb2[SET_CHAN_SEG0_CENTER_FREQUENCY]); + + if (tb2[SET_CHAN_SEG1_CENTER_FREQUENCY]) + channel_list[i].vht_seg1_center_chan_freq = + nla_get_u32(tb2[SET_CHAN_SEG1_CENTER_FREQUENCY]); + + if (tb2[SET_CHAN_CHANNEL_WIDTH]) channel_list[i].chan_width = nla_get_u8(tb2[SET_CHAN_CHANNEL_WIDTH]); - } - hdd_debug("index %d pri %d sec %d seg0 %d seg1 %d width %d", - i, channel_list[i].pri_ch, - channel_list[i].ht_sec_ch, - channel_list[i].vht_seg0_center_ch, - channel_list[i].vht_seg1_center_ch, - channel_list[i].chan_width); + + hdd_debug("index %d, pri_chan_freq %u, ht_sec_chan_freq %u seg0_freq %u seg1_freq %u width %u", + i, channel_list[i].pri_chan_freq, + channel_list[i].ht_sec_chan_freq, + channel_list[i].vht_seg0_center_chan_freq, + channel_list[i].vht_seg1_center_chan_freq, + channel_list[i].chan_width); i++; } - *chan_list_ptr = channel_list; + *list_ptr = channel_list; return 0; } /** - * Undef short names for vendor set channel configuration - */ -#undef SET_CHAN_REASON -#undef SET_CHAN_CHAN_LIST -#undef SET_CHAN_PRIMARY_CHANNEL -#undef SET_CHAN_SECONDARY_CHANNEL + * hdd_extract_external_acs_channels() - API to parse and extract vendor acs + * channel configuration. + * @hdd_ctx: pointer to hdd context + * @list_ptr: pointer to hdd_vendor_chan_info + * @channel_cnt: channel count + * @data: data + * @data_len: data len + * + * Return: 0 on success, negative errno on failure + */ +static int +hdd_extract_external_acs_channels(struct hdd_context *hdd_ctx, + struct hdd_vendor_chan_info **list_ptr, + uint8_t *channel_cnt, + const void *data, int data_len) +{ + int rem; + uint32_t i = 0; + struct nlattr *tb[SET_CHAN_MAX + 1]; + struct nlattr *tb2[SET_CHAN_MAX + 1]; + struct nlattr *curr_attr; + struct hdd_vendor_chan_info *channel_list; + + if (wlan_cfg80211_nla_parse(tb, SET_CHAN_MAX, data, data_len, + acs_chan_config_policy)) { + hdd_err("Invalid ATTR"); + return -EINVAL; + } + + nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) + i++; + + if (!i) { + hdd_err_rl("Error: channel count is zero"); + return -EINVAL; + } + + if (i > NUM_CHANNELS) { + hdd_err_rl("Error: Exceeded max channels: %u", NUM_CHANNELS); + return -ENOMEM; + } + + channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) * i); + if (!channel_list) + return -ENOMEM; + + *channel_cnt = (uint8_t)i; + i = 0; + nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) { + if (wlan_cfg80211_nla_parse_nested(tb2, SET_CHAN_MAX, + curr_attr, + acs_chan_list_policy)) { + hdd_err("nla_parse failed"); + qdf_mem_free(channel_list); + *channel_cnt = 0; + return -EINVAL; + } + + if (tb2[SET_EXT_ACS_BAND]) { + channel_list[i].band = + nla_get_u8(tb2[SET_EXT_ACS_BAND]); + } + + if (tb2[SET_CHAN_PRIMARY_CHANNEL]) { + uint32_t ch = + nla_get_u8(tb2[SET_CHAN_PRIMARY_CHANNEL]); + + channel_list[i].pri_chan_freq = + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, ch); + } + + if (tb2[SET_CHAN_SECONDARY_CHANNEL]) { + uint32_t ch = + nla_get_u8(tb2[SET_CHAN_SECONDARY_CHANNEL]); + + channel_list[i].ht_sec_chan_freq = + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, ch); + } + + if (tb2[SET_CHAN_SEG0_CENTER_CHANNEL]) { + uint32_t ch = + nla_get_u8(tb2[SET_CHAN_SEG0_CENTER_CHANNEL]); + + channel_list[i].vht_seg0_center_chan_freq = + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, ch); + } + + if (tb2[SET_CHAN_SEG1_CENTER_CHANNEL]) { + uint32_t ch = + nla_get_u8(tb2[SET_CHAN_SEG1_CENTER_CHANNEL]); + + channel_list[i].vht_seg1_center_chan_freq = + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, ch); + } + + if (tb2[SET_CHAN_CHANNEL_WIDTH]) { + channel_list[i].chan_width = + nla_get_u8(tb2[SET_CHAN_CHANNEL_WIDTH]); + } + hdd_debug("index %d, pri_chan_freq %u, ht_sec_chan_freq %u seg0_freq %u seg1_freq %u width %u", + i, channel_list[i].pri_chan_freq, + channel_list[i].ht_sec_chan_freq, + channel_list[i].vht_seg0_center_chan_freq, + channel_list[i].vht_seg1_center_chan_freq, + channel_list[i].chan_width); + i++; + } + *list_ptr = channel_list; + + return 0; +} + +/** + * hdd_parse_vendor_acs_chan_config() - API to parse vendor acs channel config + * @hdd_ctx: pointer to hdd context + * @channel_list: pointer to hdd_vendor_chan_info + * @reason: channel change reason + * @channel_cnt: channel count + * @data: data + * @data_len: data len + * + * Return: 0 on success, negative errno on failure + */ +static int +hdd_parse_vendor_acs_chan_config(struct hdd_context *hdd_ctx, + struct hdd_vendor_chan_info **chan_list_ptr, + uint8_t *reason, uint8_t *channel_cnt, + const void *data, int data_len) +{ + struct nlattr *tb[SET_CHAN_MAX + 1]; + int ret; + + if (wlan_cfg80211_nla_parse(tb, SET_CHAN_MAX, data, data_len, + acs_chan_config_policy)) { + hdd_err("Invalid ATTR"); + return -EINVAL; + } + + if (tb[SET_CHAN_REASON]) + *reason = nla_get_u8(tb[SET_CHAN_REASON]); + + if (!tb[SET_CHAN_FREQ_LIST] && !tb[SET_CHAN_CHAN_LIST]) { + hdd_err("Both channel list and frequency list are empty"); + return -EINVAL; + } + + if (tb[SET_CHAN_FREQ_LIST]) { + ret = hdd_extract_external_acs_frequencies(hdd_ctx, + chan_list_ptr, + channel_cnt, + data, data_len); + if (ret) { + hdd_err("Failed to extract frequencies"); + return ret; + } + + return 0; + } + + ret = hdd_extract_external_acs_channels(hdd_ctx, chan_list_ptr, + channel_cnt, data, data_len); + if (ret) + hdd_err("Failed to extract channels"); + + return ret; +} + +/** + * Undef short names for vendor set channel configuration + */ +#undef SET_CHAN_REASON +#undef SET_CHAN_CHAN_LIST +#undef SET_CHAN_PRIMARY_CHANNEL +#undef SET_CHAN_SECONDARY_CHANNEL #undef SET_CHAN_SEG0_CENTER_CHANNEL #undef SET_CHAN_SEG1_CENTER_CHANNEL + +#undef SET_CHAN_FREQ_LIST +#undef SET_CHAN_FREQUENCY_PRIMARY +#undef SET_CHAN_FREQUENCY_SECONDARY +#undef SET_CHAN_SEG0_CENTER_FREQUENCY +#undef SET_CHAN_SEG1_CENTER_FREQUENCY + #undef SET_CHAN_CHANNEL_WIDTH #undef SET_CHAN_MAX @@ -11595,8 +12433,9 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy, return -EINVAL; } - ret_val = hdd_parse_vendor_acs_chan_config(&channel_list, &reason, - &channel_cnt, data, data_len); + ret_val = hdd_parse_vendor_acs_chan_config(hdd_ctx, &channel_list, + &reason, &channel_cnt, data, + data_len); channel_list_ptr = channel_list; if (ret_val) return ret_val; @@ -11604,14 +12443,14 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy, /* Validate channel to be set */ while (channel_cnt && channel_list) { qdf_status = wlan_hdd_validate_acs_channel(adapter, - channel_list->pri_ch, + channel_list->pri_chan_freq, channel_list->chan_width); if (qdf_status == QDF_STATUS_SUCCESS) break; else if (channel_cnt == 1) { - hdd_err("invalid channel %d received from app", - channel_list->pri_ch); - channel_list->pri_ch = 0; + hdd_err("invalid channel frequ %u received from app", + channel_list->pri_chan_freq); + channel_list->pri_chan_freq = 0; break; } @@ -11626,7 +12465,8 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy, return -EINVAL; } - hdd_debug("received primary channel as %d", channel_list->pri_ch); + hdd_debug("received primary channel freq as %d", + channel_list->pri_chan_freq); ret_val = hdd_update_acs_channel(adapter, reason, channel_cnt, channel_list); @@ -11689,6 +12529,108 @@ static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy, return errno; } +static uint32_t +wlan_reg_wifi_band_bitmap_to_vendor_bitmap(uint32_t reg_wifi_band_bitmap) +{ + uint32_t vendor_mask = 0; + + if (reg_wifi_band_bitmap & BIT(REG_BAND_2G)) + vendor_mask |= QCA_SETBAND_2G; + if (reg_wifi_band_bitmap & BIT(REG_BAND_5G)) + vendor_mask |= QCA_SETBAND_5G; + if (reg_wifi_band_bitmap & BIT(REG_BAND_6G)) + vendor_mask |= QCA_SETBAND_6G; + + return vendor_mask; +} + +/** + *__wlan_hdd_cfg80211_getband() - get band + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * Return: 0 on success, negative errno on failure + */ +static int __wlan_hdd_cfg80211_getband(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct sk_buff *skb; + QDF_STATUS status = QDF_STATUS_SUCCESS; + int ret; + uint32_t reg_wifi_band_bitmap, vendor_band_mask; + + hdd_enter(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, + sizeof(uint32_t) + + NLA_HDRLEN); + + if (!skb) { + hdd_err("cfg80211_vendor_event_alloc failed"); + return -ENOMEM; + } + + status = ucfg_reg_get_band(hdd_ctx->pdev, ®_wifi_band_bitmap); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("failed to get band"); + goto failure; + } + + vendor_band_mask = wlan_reg_wifi_band_bitmap_to_vendor_bitmap( + reg_wifi_band_bitmap); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_SETBAND_MASK, + vendor_band_mask)) { + hdd_err("nla put failure"); + goto failure; + } + + cfg80211_vendor_cmd_reply(skb); + + hdd_exit(); + + return 0; + +failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_getband() - Wrapper to getband + * @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_getband(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_getband(wiphy, wdev, data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + /** * wlan_hdd_cfg80211_sar_convert_limit_set() - Convert limit set value * @nl80211_value: Vendor command attribute value @@ -11699,6 +12641,7 @@ static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy, */ static int wlan_hdd_cfg80211_sar_convert_limit_set(u32 nl80211_value, u32 *wmi_value) + { int ret = 0; @@ -12249,6 +13192,7 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy, struct hdd_station_ctx *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); mac_handle_t mac_handle; + bool roaming_enabled; hdd_enter_dev(dev); @@ -12279,6 +13223,13 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]); hdd_debug("isFastRoamEnabled %d", is_fast_roam_enabled); + /* + * Get current roaming state and decide whether to wait for RSO_STOP + * response or not. + */ + roaming_enabled = ucfg_is_roaming_enabled(hdd_ctx->pdev, + adapter->vdev_id); + /* Update roaming */ mac_handle = hdd_ctx->mac_handle; qdf_status = sme_config_fast_roaming(mac_handle, adapter->vdev_id, @@ -12289,6 +13240,7 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy, ret = qdf_status_to_os_return(qdf_status); if (eConnectionState_Associated == hdd_sta_ctx->conn_info.conn_state && + roaming_enabled && QDF_IS_STATUS_SUCCESS(qdf_status) && !is_fast_roam_enabled) { INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event); @@ -12630,29 +13582,6 @@ static int hdd_set_clear_connectivity_check_stats_info( return err; } -void hdd_update_cca_info_cb(hdd_handle_t hdd_handle, uint32_t congestion, - uint32_t vdev_id) -{ - struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); - int status; - struct hdd_adapter *adapter = NULL; - struct hdd_station_ctx *hdd_sta_ctx; - - status = wlan_hdd_validate_context(hdd_ctx); - if (status != 0) - return; - - adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); - if (!adapter) { - hdd_err("vdev_id %d does not exist with host", vdev_id); - return; - } - - hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - hdd_sta_ctx->conn_info.cca = congestion; - hdd_info("congestion:%d", congestion); -} - static const struct nla_policy qca_wlan_vendor_set_trace_level_policy[ QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM] = {.type = NLA_NESTED }, @@ -12802,6 +13731,7 @@ static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy, struct nlattr *tb[STATS_SET_MAX + 1]; struct net_device *dev = wdev->netdev; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct set_arp_stats_params arp_stats_params = {0}; int err = 0; @@ -12828,6 +13758,11 @@ static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy, return -EINVAL; } + if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) { + hdd_debug("Not Associated"); + return 0; + } + if (hdd_is_roaming_in_progress(hdd_ctx)) return -EINVAL; @@ -13364,10 +14299,9 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy, QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, "Data stall due to NUD failure"); cdp_post_data_stall_event(soc, - cds_get_context(QDF_MODULE_ID_TXRX), DATA_STALL_LOG_INDICATOR_FRAMEWORK, DATA_STALL_LOG_NUD_FAILURE, - 0xFF, 0XFF, + OL_TXRX_PDEV_ID, 0XFF, DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); } @@ -13881,30 +14815,276 @@ int wlan_hdd_send_mode_change_event(void) return err; } -const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { - { - .info.vendor_id = QCA_NL80211_VENDOR_ID, - .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY, - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | - WIPHY_VENDOR_CMD_NEED_NETDEV, - .doit = is_driver_dfs_capable - }, - { - .info.vendor_id = QCA_NL80211_VENDOR_ID, - .info.subcmd = - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS, - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | - WIPHY_VENDOR_CMD_NEED_NETDEV | - WIPHY_VENDOR_CMD_NEED_RUNNING, - .doit = wlan_hdd_cfg80211_extscan_get_valid_channels - }, -#ifdef WLAN_FEATURE_STATS_EXT - { - .info.vendor_id = QCA_NL80211_VENDOR_ID, - .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT, - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | - WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, - .doit = wlan_hdd_cfg80211_stats_ext_request + +/* Short name for QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS command */ + +#define EXTSCAN_CONFIG_MAX \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +#define EXTSCAN_CONFIG_REQUEST_ID \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID +#define EXTSCAN_CONFIG_WIFI_BAND \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND +#define ETCAN_CONFIG_MAX_CHANNELS \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS +#define EXTSCAN_RESULTS_NUM_CHANNELS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS +#define EXTSCAN_RESULTS_CHANNELS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS + +/** + * hdd_remove_dsrc_channels () - remove dsrc chanels + * @hdd_ctx: hdd context + * @wiphy: Pointer to wireless phy + * @chan_list: channel list + * @num_channels: number of channels + * + * Return: none + */ +static void hdd_remove_dsrc_channels(struct hdd_context *hdd_ctx, + struct wiphy *wiphy, uint32_t *chan_list, + uint8_t *num_channels) +{ + uint8_t num_chan_temp = 0; + int i; + + for (i = 0; i < *num_channels; i++) { + if (!wlan_reg_is_dsrc_chan(hdd_ctx->pdev, + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + chan_list[i]))) { + chan_list[num_chan_temp] = chan_list[i]; + num_chan_temp++; + } + } + *num_channels = num_chan_temp; +} + +/** + * hdd_remove_passive_channels () - remove passive channels + * @wiphy: Pointer to wireless phy + * @chan_list: channel list + * @num_channels: number of channels + * + * Return: none + */ +static void hdd_remove_passive_channels(struct wiphy *wiphy, + uint32_t *chan_list, + uint8_t *num_channels) +{ + uint8_t num_chan_temp = 0; + int i, j, k; + + for (i = 0; i < *num_channels; i++) + for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) { + if (!wiphy->bands[j]) + continue; + for (k = 0; k < wiphy->bands[j]->n_channels; k++) { + if ((chan_list[i] == + wiphy->bands[j]->channels[k].center_freq) + && (!(wiphy->bands[j]->channels[k].flags & + IEEE80211_CHAN_PASSIVE_SCAN)) + ) { + chan_list[num_chan_temp] = chan_list[i]; + num_chan_temp++; + } + } + } + + *num_channels = num_chan_temp; +} + +/** + * __wlan_hdd_cfg80211_extscan_get_valid_channels () - get valid channels + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Data length + * + * Return: none + */ +static int +__wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, + struct wireless_dev + *wdev, const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + uint32_t chan_list[CFG_VALID_CHANNEL_LIST_LEN] = {0}; + uint8_t num_channels = 0, i, buf[256] = {0}; + struct nlattr *tb[EXTSCAN_CONFIG_MAX + + 1]; + uint32_t requestId, maxChannels; + tWifiBand wifi_band; + QDF_STATUS status; + struct sk_buff *reply_skb; + int ret, len = 0; + + /* ENTER_DEV() intentionally not used in a frequently invoked API */ + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return -EINVAL; + + if (wlan_cfg80211_nla_parse( + tb, + EXTSCAN_CONFIG_MAX, + data, data_len, wlan_hdd_extscan_config_policy)) { + hdd_err("Invalid ATTR"); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[EXTSCAN_CONFIG_REQUEST_ID]) { + hdd_err("attr request id failed"); + return -EINVAL; + } + requestId = + nla_get_u32(tb + [EXTSCAN_CONFIG_REQUEST_ID]); + + /* Parse and fetch wifi band */ + if (!tb + [EXTSCAN_CONFIG_WIFI_BAND]) { + hdd_err("attr wifi band failed"); + return -EINVAL; + } + wifi_band = + nla_get_u32(tb + [EXTSCAN_CONFIG_WIFI_BAND]); + if (!tb + [ETCAN_CONFIG_MAX_CHANNELS]) { + hdd_err("attr max channels failed"); + return -EINVAL; + } + maxChannels = + nla_get_u32(tb + [ETCAN_CONFIG_MAX_CHANNELS]); + + if (maxChannels > CFG_VALID_CHANNEL_LIST_LEN) { + hdd_err("Max channels %d exceeded Valid channel list len %d", + maxChannels, CFG_VALID_CHANNEL_LIST_LEN); + return -EINVAL; + } + + hdd_err("Req Id: %u Wifi band: %d Max channels: %d", requestId, + wifi_band, maxChannels); + status = sme_get_valid_channels_by_band(hdd_ctx->mac_handle, + wifi_band, chan_list, + &num_channels); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("sme_get_valid_channels_by_band failed (err=%d)", + status); + return -EINVAL; + } + + num_channels = QDF_MIN(num_channels, maxChannels); + + hdd_remove_dsrc_channels(hdd_ctx, wiphy, chan_list, &num_channels); + if ((QDF_SAP_MODE == adapter->device_mode) || + !strncmp(hdd_get_fwpath(), "ap", 2)) + hdd_remove_passive_channels(wiphy, chan_list, + &num_channels); + + hdd_debug("Number of channels: %d", num_channels); + for (i = 0; i < num_channels; i++) + len += scnprintf(buf + len, sizeof(buf) - len, + "%u ", chan_list[i]); + + hdd_debug("Channels: %s", buf); + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(u32) * + num_channels + + NLMSG_HDRLEN); + + if (reply_skb) { + if (nla_put_u32( + reply_skb, + EXTSCAN_RESULTS_NUM_CHANNELS, + num_channels) || + nla_put( + reply_skb, + EXTSCAN_RESULTS_CHANNELS, + sizeof(u32) * num_channels, chan_list)) { + hdd_err("nla put fail"); + kfree_skb(reply_skb); + return -EINVAL; + } + ret = cfg80211_vendor_cmd_reply(reply_skb); + return ret; + } + + hdd_err("valid channels: buffer alloc fail"); + return -EINVAL; +} + +#undef EXTSCAN_CONFIG_MAX +#undef EXTSCAN_CONFIG_REQUEST_ID +#undef EXTSCAN_CONFIG_WIFI_BAND +#undef ETCAN_CONFIG_MAX_CHANNELS +#undef EXTSCAN_RESULTS_NUM_CHANNELS +#undef EXTSCAN_RESULTS_CHANNELS + +/** + * wlan_hdd_cfg80211_extscan_get_valid_channels() - get ext scan valid channels + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Data length + * + * Return: 0 on success, negative errno on failure + */ +static int wlan_hdd_cfg80211_extscan_get_valid_channels( + struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int errno; + + errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, + data, data_len); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno; +} + +const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = is_driver_dfs_capable + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_get_valid_channels + }, +#ifdef WLAN_FEATURE_STATS_EXT + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_stats_ext_request }, #endif #ifdef FEATURE_WLAN_EXTSCAN @@ -14112,7 +15292,6 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_NETDEV, .doit = wlan_hdd_cfg80211_get_wifi_info }, -#ifndef WLAN_UMAC_CONVERGENCE { .info.vendor_id = QCA_NL80211_VENDOR_ID, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION, @@ -14121,7 +15300,6 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_wifi_configuration_set }, -#endif { .info.vendor_id = QCA_NL80211_VENDOR_ID, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION, @@ -14159,9 +15337,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { { .info.vendor_id = QCA_NL80211_VENDOR_ID, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA, - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | - WIPHY_VENDOR_CMD_NEED_NETDEV | - WIPHY_VENDOR_CMD_NEED_RUNNING, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV, .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data }, { @@ -14422,6 +15598,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_setband }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GETBAND, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_getband, + }, { .info.vendor_id = QCA_NL80211_VENDOR_ID, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING, @@ -14498,9 +15682,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_BSS_TRANSITION_VENDOR_COMMANDS FEATURE_SPECTRAL_SCAN_VENDOR_COMMANDS -#ifdef WLAN_UMAC_CONVERGENCE - COMMON_VENDOR_COMMANDS -#endif + FEATURE_CFR_VENDOR_COMMANDS FEATURE_11AX_VENDOR_COMMANDS { @@ -14519,6 +15701,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { FEATURE_MPTA_HELPER_COMMANDS FEATURE_HW_CAPABILITY_COMMANDS FEATURE_THERMAL_VENDOR_COMMANDS + FEATURE_GPIO_CFG_VENDOR_COMMANDS }; struct hdd_context *hdd_cfg80211_wiphy_alloc(void) @@ -14678,7 +15861,8 @@ static void wlan_hdd_cfg80211_set_wiphy_oce_scan_flags(struct wiphy *wiphy) #endif #if defined(WLAN_FEATURE_SAE) && \ - defined(CFG80211_EXTERNAL_AUTH_SUPPORT) + (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) /** * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature * @wiphy: Pointer to wiphy @@ -14728,6 +15912,7 @@ static void wlan_hdd_copy_dsrc_ch(char *ch_ptr, int ch_arr_len) qdf_mem_copy(ch_ptr, &hdd_channels_dot11p[0], ch_arr_len); } + static void wlan_hdd_get_num_srd_ch_and_len(struct hdd_config *hdd_cfg, int *num_ch, int *ch_len) { @@ -14803,7 +15988,41 @@ wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index) #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if (defined(CONFIG_BAND_6GHZ) && defined(CFG80211_6GHZ_BAND_SUPPORTED)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) +static QDF_STATUS +wlan_hdd_iftype_data_alloc_6ghz(struct hdd_context *hdd_ctx) +{ + hdd_ctx->iftype_data_6g = + qdf_mem_malloc(sizeof(*hdd_ctx->iftype_data_6g)); + + if (!hdd_ctx->iftype_data_6g) + return QDF_STATUS_E_NOMEM; + + return QDF_STATUS_SUCCESS; +} + +static void +wlan_hdd_iftype_data_mem_free_6ghz(struct hdd_context *hdd_ctx) +{ + qdf_mem_free(hdd_ctx->iftype_data_6g); + hdd_ctx->iftype_data_6g = NULL; +} +#else +static inline QDF_STATUS +wlan_hdd_iftype_data_alloc_6ghz(struct hdd_context *hdd_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +wlan_hdd_iftype_data_mem_free_6ghz(struct hdd_context *hdd_ctx) +{ +} +#endif + static QDF_STATUS wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx) { @@ -14824,26 +16043,35 @@ wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx) return QDF_STATUS_E_NOMEM; } + if (QDF_IS_STATUS_ERROR(wlan_hdd_iftype_data_alloc_6ghz(hdd_ctx))) { + hdd_err("mem alloc failed for 6g iftype data"); + qdf_mem_free(hdd_ctx->iftype_data_5g); + qdf_mem_free(hdd_ctx->iftype_data_2g); + hdd_ctx->iftype_data_2g = NULL; + hdd_ctx->iftype_data_5g = NULL; + return QDF_STATUS_E_NOMEM; + } + return QDF_STATUS_SUCCESS; } -#else -static inline QDF_STATUS -wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx) -{ - return QDF_STATUS_SUCCESS; -} -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) static void wlan_hdd_iftype_data_mem_free(struct hdd_context *hdd_ctx) { + wlan_hdd_iftype_data_mem_free_6ghz(hdd_ctx); qdf_mem_free(hdd_ctx->iftype_data_5g); qdf_mem_free(hdd_ctx->iftype_data_2g); hdd_ctx->iftype_data_5g = NULL; hdd_ctx->iftype_data_2g = NULL; } #else +static QDF_STATUS +wlan_hdd_iftype_data_alloc(struct hdd_context *hdd_ctx) + +{ + return QDF_STATUS_SUCCESS; +} + static inline void wlan_hdd_iftype_data_mem_free(struct hdd_context *hdd_ctx) { @@ -14954,8 +16182,8 @@ int wlan_hdd_cfg80211_init(struct device *dev, | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR); - wlan_hdd_set_nan_if_mode(wiphy); + wlan_hdd_set_nan_if_mode(wiphy); /* * In case of static linked driver at the time of driver unload, @@ -15034,6 +16262,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, hdd_add_channel_switch_support(&wiphy->flags); wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS; wlan_hdd_cfg80211_action_frame_randomization_init(wiphy); + wlan_hdd_set_nan_supported_bands(wiphy); hdd_exit(); @@ -15178,7 +16407,7 @@ static void wlan_hdd_update_ht_cap(struct hdd_context *hdd_ctx) static void wlan_hdd_update_band_cap_in_wiphy(struct hdd_context *hdd_ctx) { int i, j; - uint8_t band_capability; + uint32_t band_capability; QDF_STATUS status; struct ieee80211_supported_band *band; @@ -15196,7 +16425,7 @@ static void wlan_hdd_update_band_cap_in_wiphy(struct hdd_context *hdd_ctx) band = hdd_ctx->wiphy->bands[i]; if (HDD_NL80211_BAND_2GHZ == i && - BAND_5G == band_capability) { + BIT(REG_BAND_5G) == band_capability) { /* 5G only */ #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY /* Enable social channels for P2P */ @@ -15210,7 +16439,7 @@ static void wlan_hdd_update_band_cap_in_wiphy(struct hdd_context *hdd_ctx) IEEE80211_CHAN_DISABLED; continue; } else if (HDD_NL80211_BAND_5GHZ == i && - BAND_2G == band_capability) { + BIT(REG_BAND_2G) == band_capability) { /* 2G only */ band->channels[j].flags |= IEEE80211_CHAN_DISABLED; @@ -15234,15 +16463,12 @@ static void wlan_hdd_update_lfr_wiphy(struct hdd_context *hdd_ctx) bool fast_transition_enabled; bool lfr_enabled; bool ese_enabled; - bool roam_offload; ucfg_mlme_is_fast_transition_enabled(hdd_ctx->psoc, &fast_transition_enabled); ucfg_mlme_is_lfr_enabled(hdd_ctx->psoc, &lfr_enabled); ucfg_mlme_is_ese_enabled(hdd_ctx->psoc, &ese_enabled); - ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload); - if (fast_transition_enabled || lfr_enabled || ese_enabled || - roam_offload) + if (fast_transition_enabled || lfr_enabled || ese_enabled) hdd_ctx->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; } #else @@ -15250,13 +16476,11 @@ static void wlan_hdd_update_lfr_wiphy(struct hdd_context *hdd_ctx) { bool fast_transition_enabled; bool lfr_enabled; - bool roam_offload; ucfg_mlme_is_fast_transition_enabled(hdd_ctx->psoc, &fast_transition_enabled); ucfg_mlme_is_lfr_enabled(hdd_ctx->psoc, &lfr_enabled); - ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload); - if (fast_transition_enabled || lfr_enabled || roam_offload) + if (fast_transition_enabled || lfr_enabled) hdd_ctx->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; } #endif @@ -15392,7 +16616,12 @@ QDF_STATUS wlan_hdd_update_wiphy_supported_band(struct hdd_context *hdd_ctx) hdd_err("could not get VHT capability"); if (is_vht_for_24ghz && - sme_is_feature_supported_by_fw(DOT11AC)) + sme_is_feature_supported_by_fw(DOT11AC) && + (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO || + cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY || + cfg->dot11Mode == eHDD_DOT11_MODE_11ac || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) wlan_hdd_band_2_4_ghz.vht_cap.vht_supported = 1; } if (!hdd_is_5g_supported(hdd_ctx) || @@ -15423,6 +16652,18 @@ QDF_STATUS wlan_hdd_update_wiphy_supported_band(struct hdd_context *hdd_ctx) HDD_NL80211_BAND_5GHZ]->channels + len_5g_ch, len_srd_ch); + if (cfg->dot11Mode != eHDD_DOT11_MODE_AUTO && + cfg->dot11Mode != eHDD_DOT11_MODE_11ac && + cfg->dot11Mode != eHDD_DOT11_MODE_11ac_ONLY && + cfg->dot11Mode != eHDD_DOT11_MODE_11ax && + cfg->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY) + wlan_hdd_band_5_ghz.vht_cap.vht_supported = 0; + + if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax || + cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) + hdd_init_6ghz(hdd_ctx); + return QDF_STATUS_SUCCESS; } @@ -15597,45 +16838,6 @@ void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter) WNM_NOTIFICATION_FRAME_SIZE); } -#if defined(FEATURE_WLAN_WAPI) && !defined(CRYPTO_SET_KEY_CONVERGED) -static void wlan_hdd_cfg80211_set_key_wapi(struct hdd_adapter *adapter, - uint8_t key_index, - const uint8_t *mac_addr, - const uint8_t *key, - int key_len) -{ - tCsrRoamSetKey set_key; - QDF_STATUS status; - uint32_t roam_id = INVALID_ROAM_ID; - mac_handle_t mac_handle; - - hdd_debug("Device_mode %s(%d)", - qdf_opmode_str(adapter->device_mode), adapter->device_mode); - - qdf_mem_zero(&set_key, sizeof(set_key)); - set_key.keyId = key_index; - set_key.encType = eCSR_ENCRYPT_TYPE_WPI; - set_key.keyDirection = eSIR_TX_RX; - set_key.paeRole = 0; - if (!mac_addr || is_broadcast_ether_addr(mac_addr)) - qdf_set_macaddr_broadcast(&set_key.peerMac); - else - qdf_mem_copy(set_key.peerMac.bytes, mac_addr, - QDF_MAC_ADDR_SIZE); - - set_key.keyLength = key_len; - memcpy(set_key.Key, key, key_len); - - hdd_debug("WAPI KEY LENGTH:0x%04x", key_len); - - mac_handle = hdd_adapter_get_mac_handle(adapter); - status = sme_roam_set_key(mac_handle, adapter->vdev_id, - &set_key, &roam_id); - if (status != QDF_STATUS_SUCCESS) - hdd_err("sme_roam_set_key failed status: %d", status); -} -#endif /* FEATURE_WLAN_WAPI */ - bool wlan_hdd_is_ap_supports_immediate_power_save(uint8_t *ies, int length) { const uint8_t *vendor_ie; @@ -15665,48 +16867,50 @@ bool wlan_hdd_is_ap_supports_immediate_power_save(uint8_t *ies, int length) * channel list. */ QDF_STATUS wlan_hdd_validate_operation_channel(struct hdd_adapter *adapter, - int channel) + uint32_t ch_freq) { - uint32_t num_ch = 0; - u8 valid_ch[CFG_VALID_CHANNEL_LIST_LEN]; - u32 indx = 0; - bool is_valid_channel = false; - uint8_t count; - QDF_STATUS status; - bool value; - struct hdd_context *hdd_ctx; + bool value = 0; + uint32_t i; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct regulatory_channel *cur_chan_list; + QDF_STATUS status = QDF_STATUS_E_INVAL; - num_ch = CFG_VALID_CHANNEL_LIST_LEN; - hdd_ctx = WLAN_HDD_GET_CTX(adapter); status = ucfg_mlme_get_sap_allow_all_channels(hdd_ctx->psoc, &value); if (status != QDF_STATUS_SUCCESS) hdd_err("Unable to fetch sap allow all channels"); + if (value) { /* Validate the channel */ - for (count = CHAN_ENUM_1; count <= CHAN_ENUM_173; count++) { - if (channel == WLAN_REG_CH_NUM(count)) { - is_valid_channel = true; + for (i = CHAN_ENUM_2412; i < NUM_CHANNELS; i++) { + if (ch_freq == WLAN_REG_CH_TO_FREQ(i)) { + status = QDF_STATUS_SUCCESS; break; } } - if (!is_valid_channel) { - hdd_err("Invalid Channel: %d", channel); - return QDF_STATUS_E_FAILURE; - } } else { - ucfg_mlme_get_valid_channel_list(hdd_ctx->psoc, valid_ch, - &num_ch); - for (indx = 0; indx < num_ch; indx++) { - if (channel == valid_ch[indx]) - break; + cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * + sizeof(struct regulatory_channel)); + if (!cur_chan_list) + return QDF_STATUS_E_NOMEM; + + if (wlan_reg_get_current_chan_list( + hdd_ctx->pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { + qdf_mem_free(cur_chan_list); + return QDF_STATUS_E_INVAL; } - if (indx >= num_ch) { - hdd_err("Invalid Channel: %d", channel); - return QDF_STATUS_E_FAILURE; + for (i = 0; i < NUM_CHANNELS; i++) { + if (ch_freq != cur_chan_list[i].center_freq) + continue; + if (cur_chan_list[i].state != CHANNEL_STATE_DISABLE && + cur_chan_list[i].state != CHANNEL_STATE_INVALID) + status = QDF_STATUS_SUCCESS; + break; } + qdf_mem_free(cur_chan_list); } - return QDF_STATUS_SUCCESS; + + return status; } @@ -15967,8 +17171,8 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, memcpy(adapter->mac_addr.bytes, ndev->dev_addr, QDF_MAC_ADDR_SIZE); pr_info("wlan: Generated HotSpot BSSID " - QDF_MAC_ADDR_STR "\n", - QDF_MAC_ADDR_ARRAY(ndev->dev_addr)); + QDF_MAC_ADDR_FMT "\n", + QDF_MAC_ADDR_REF(ndev->dev_addr)); } hdd_set_ap_ops(adapter->dev); @@ -16272,7 +17476,6 @@ static int wlan_hdd_change_station(struct wiphy *wiphy, return errno; } -#ifdef CRYPTO_SET_KEY_CONVERGED #ifdef FEATURE_WLAN_ESE static bool hdd_is_krk_enc_type(uint32_t cipher_type) { @@ -16302,9 +17505,21 @@ static bool hdd_is_btk_enc_type(uint32_t cipher_type) return false; } #endif -#endif -#ifdef CRYPTO_SET_KEY_CONVERGED +#ifdef QCA_IBSS_SUPPORT +/** + * wlan_hdd_add_key_ibss() - API to add IBSS key + * @adapter: Pointer to adapter + * @pairwise: need to add key pairwise + * @key_index: key index + * @mac_addr: Pointer to mac_addr + * @params: Pointer to key params + * @key_already_installed: pointer to key already installed state + * + * This API will add IBSS key for given mac address. + * + * Return: 0 for success, error number on failure. + */ static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter, bool pairwise, u8 key_index, const u8 *mac_addr, struct key_params *params, @@ -16326,7 +17541,7 @@ static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter, if (!vdev) return -EINVAL; errno = wlan_cfg80211_crypto_add_key(vdev, WLAN_CRYPTO_KEY_TYPE_GROUP, - key_index); + key_index, false); if (errno) { hdd_err("add_ibss_key failed, errno: %d", errno); hdd_objmgr_put_vdev(vdev); @@ -16342,6 +17557,29 @@ static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter, return 0; } +#else +/** + * wlan_hdd_add_key_ibss() - API to add IBSS key + * @adapter: Pointer to adapter + * @pairwise: need to add key pairwise + * @key_index: key index + * @mac_addr: Pointer to mac_addr + * @params: Pointer to key params + * @key_already_installed: pointer to key already installed state + * + * This function is dummy + * + * Return: 0 + */ +static inline int +wlan_hdd_add_key_ibss(struct hdd_adapter *adapter, + bool pairwise, u8 key_index, + const u8 *mac_addr, struct key_params *params, + bool *key_already_installed) +{ + return 0; +} +#endif static int wlan_hdd_add_key_sap(struct hdd_adapter *adapter, bool pairwise, u8 key_index, @@ -16368,10 +17606,11 @@ static int wlan_hdd_add_key_sap(struct hdd_adapter *adapter, if (hostapd_state->bss_state == BSS_START) { errno = - wlan_cfg80211_crypto_add_key(vdev, (pairwise ? - WLAN_CRYPTO_KEY_TYPE_UNICAST : - WLAN_CRYPTO_KEY_TYPE_GROUP), - key_index); + wlan_cfg80211_crypto_add_key(vdev, + (pairwise ? + WLAN_CRYPTO_KEY_TYPE_UNICAST : + WLAN_CRYPTO_KEY_TYPE_GROUP), + key_index, true); if (!errno) wma_update_set_key(adapter->vdev_id, pairwise, key_index, cipher); @@ -16386,18 +17625,9 @@ static int wlan_hdd_add_key_sta(struct hdd_adapter *adapter, mac_handle_t mac_handle, bool *ft_mode) { struct wlan_objmgr_vdev *vdev; - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); int errno; QDF_STATUS status; - if (!pairwise) { - /* set group key */ - if (sta_ctx->roam_info.defer_key_complete) { - hdd_debug("Perform Set key Complete"); - hdd_perform_roam_set_key_complete(adapter); - } - } /* The supplicant may attempt to set the PTK once * pre-authentication is done. Save the key in the * UMAC and include it in the ADD BSS request @@ -16413,7 +17643,7 @@ static int wlan_hdd_add_key_sta(struct hdd_adapter *adapter, errno = wlan_cfg80211_crypto_add_key(vdev, (pairwise ? WLAN_CRYPTO_KEY_TYPE_UNICAST : WLAN_CRYPTO_KEY_TYPE_GROUP), - key_index); + key_index, true); hdd_objmgr_put_vdev(vdev); if (!errno && adapter->send_mode_change) { wlan_hdd_send_mode_change_event(); @@ -16494,6 +17724,9 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (pairwise) wma_set_peer_ucast_cipher(mac_address.bytes, cipher); + cdp_peer_flush_frags(cds_get_context(QDF_MODULE_ID_SOC), + wlan_vdev_get_id(vdev), mac_address.bytes); + switch (adapter->device_mode) { case QDF_IBSS_MODE: errno = wlan_hdd_add_key_ibss(adapter, pairwise, key_index, @@ -16524,340 +17757,6 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, return errno; } -#else /* !CRYPTO_SET_KEY_CONVERGED */ -/* - * FUNCTION: __wlan_hdd_cfg80211_add_key - * This function is used to initialize the key information - */ -static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, - struct net_device *ndev, - u8 key_index, bool pairwise, - const u8 *mac_addr, - struct key_params *params) -{ - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); - tCsrRoamSetKey set_key; - int errno; - uint32_t roam_id = INVALID_ROAM_ID; - QDF_STATUS status; - struct hdd_context *hdd_ctx; - mac_handle_t mac_handle; - - hdd_enter(); - - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); - return -EINVAL; - } - - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) - return -EINVAL; - - qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_ADD_KEY, - adapter->vdev_id, params->key_len); - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - errno = wlan_hdd_validate_context(hdd_ctx); - - if (errno) - return errno; - - hdd_debug("Device_mode %s(%d)", - qdf_opmode_str(adapter->device_mode), adapter->device_mode); - - if (CSR_MAX_NUM_KEY <= key_index) { - hdd_err("Invalid key index %d", key_index); - - return -EINVAL; - } - - if (CSR_MAX_KEY_LEN < params->key_len) { - hdd_err("Invalid key length %d", params->key_len); - - return -EINVAL; - } - - if (WLAN_CRYPTO_RSC_SIZE < params->seq_len) { - hdd_err("Invalid seq length %d", params->seq_len); - - return -EINVAL; - } - - hdd_debug("key index %d, key length %d, seq length %d", - key_index, params->key_len, params->seq_len); - - /*extract key idx, key len and key */ - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - set_key.keyId = key_index; - set_key.keyLength = params->key_len; - qdf_mem_copy(&set_key.Key[0], params->key, params->key_len); - qdf_mem_copy(&set_key.keyRsc[0], params->seq, params->seq_len); - - mac_handle = hdd_ctx->mac_handle; - - switch (params->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - set_key.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; - break; - - case WLAN_CIPHER_SUITE_WEP104: - set_key.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; - break; - - case WLAN_CIPHER_SUITE_TKIP: - { - u8 *key = &set_key.Key[0]; - - set_key.encType = eCSR_ENCRYPT_TYPE_TKIP; - qdf_mem_zero(key, CSR_MAX_KEY_LEN); - - /* Supplicant sends the 32bytes key in this order - * - * |--------------|----------|----------| - * | Tk1 |TX-MIC | RX Mic | - * |--------------|----------|----------| - * <---16bytes---><--8bytes--><--8bytes--> - * - * Sme expects the 32 bytes key to be in the below order - * - * |--------------|----------|----------| - * | Tk1 |RX-MIC | TX Mic | - * |--------------|----------|----------| - * <---16bytes---><--8bytes--><--8bytes--> - */ - /* Copy the Temporal Key 1 (TK1) */ - qdf_mem_copy(key, params->key, 16); - - /*Copy the rx mic first */ - qdf_mem_copy(&key[16], ¶ms->key[24], 8); - - /*Copy the tx mic */ - qdf_mem_copy(&key[24], ¶ms->key[16], 8); - - break; - } - - case WLAN_CIPHER_SUITE_CCMP: - set_key.encType = eCSR_ENCRYPT_TYPE_AES; - break; - -#ifdef FEATURE_WLAN_WAPI - case WLAN_CIPHER_SUITE_SMS4: - { - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - wlan_hdd_cfg80211_set_key_wapi(adapter, key_index, - mac_addr, params->key, - params->key_len); - return 0; - } -#endif - -#ifdef FEATURE_WLAN_ESE - case WLAN_CIPHER_SUITE_KRK: - set_key.encType = eCSR_ENCRYPT_TYPE_KRK; - break; -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - case WLAN_CIPHER_SUITE_BTK: - set_key.encType = eCSR_ENCRYPT_TYPE_BTK; - break; -#endif -#endif - -#ifdef WLAN_FEATURE_11W - case WLAN_CIPHER_SUITE_AES_CMAC: - set_key.encType = eCSR_ENCRYPT_TYPE_AES_CMAC; - break; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - set_key.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_128; - break; - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - set_key.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_256; - break; -#endif -#endif - case WLAN_CIPHER_SUITE_GCMP: - set_key.encType = eCSR_ENCRYPT_TYPE_AES_GCMP; - break; - case WLAN_CIPHER_SUITE_GCMP_256: - set_key.encType = eCSR_ENCRYPT_TYPE_AES_GCMP_256; - break; - - default: - hdd_err("Unsupported cipher type: %u", params->cipher); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return -EOPNOTSUPP; - } - - hdd_debug("encryption type %d", set_key.encType); - - if (!pairwise) { - /* set group key */ - hdd_debug("setting Broadcast key"); - set_key.keyDirection = eSIR_RX_ONLY; - qdf_set_macaddr_broadcast(&set_key.peerMac); - } else { - /* set pairwise key */ - hdd_debug("setting pairwise key"); - set_key.keyDirection = eSIR_TX_RX; - qdf_mem_copy(set_key.peerMac.bytes, mac_addr, QDF_MAC_ADDR_SIZE); - } - - cdp_peer_flush_frags(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), - adapter->vdev_id, set_key.peerMac.bytes); - - if ((QDF_IBSS_MODE == adapter->device_mode) && !pairwise) { - /* if a key is already installed, block all subsequent ones */ - if (adapter->session.station.ibss_enc_key_installed) { - hdd_debug("IBSS key installed already"); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return 0; - } - - set_key.keyDirection = eSIR_TX_RX; - /*Set the group key */ - status = sme_roam_set_key(mac_handle, - adapter->vdev_id, &set_key, &roam_id); - - if (0 != status) { - hdd_err("sme_roam_set_key failed, status: %d", status); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return -EINVAL; - } - /* Save the keys here and call sme_roam_set_key for setting - * the PTK after peer joins the IBSS network - */ - qdf_mem_copy(&adapter->session.station.ibss_enc_key, - &set_key, sizeof(tCsrRoamSetKey)); - - adapter->session.station.ibss_enc_key_installed = 1; - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return qdf_status_to_os_return(status); - } - if ((adapter->device_mode == QDF_SAP_MODE) || - (adapter->device_mode == QDF_P2P_GO_MODE)) { - struct hdd_hostapd_state *hostapd_state = - WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); - struct hdd_ap_ctx *ap_ctx = - WLAN_HDD_GET_AP_CTX_PTR(adapter); - - if (hostapd_state->bss_state == BSS_START) { - status = wlansap_set_key_sta( - WLAN_HDD_GET_SAP_CTX_PTR(adapter), &set_key); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("wlansap_set_key_sta failed status: %d", - status); - } - } - - /* Save the key in ap ctx for use on START_BSS and restart */ - if (pairwise || - eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == set_key.encType || - eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == set_key.encType) - qdf_mem_copy(&ap_ctx->wep_key[key_index], &set_key, - sizeof(tCsrRoamSetKey)); - else - qdf_mem_copy(&ap_ctx->group_key, &set_key, - sizeof(tCsrRoamSetKey)); - - } else if ((adapter->device_mode == QDF_STA_MODE) || - (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct csr_roam_profile *roam_profile; - - if (!pairwise) { - /* set group key */ - if (sta_ctx->roam_info.defer_key_complete) { - hdd_debug("Perform Set key Complete"); - hdd_perform_roam_set_key_complete(adapter); - } - } - - roam_profile = hdd_roam_profile(adapter); - roam_profile->Keys.KeyLength[key_index] = params->key_len; - - roam_profile->Keys.defaultIndex = key_index; - - qdf_mem_copy(&roam_profile->Keys.KeyMaterial[key_index][0], - params->key, params->key_len); - - hdd_debug("Set key for peerMac "QDF_MAC_ADDR_STR" direction %d", - QDF_MAC_ADDR_ARRAY(set_key.peerMac.bytes), - set_key.keyDirection); - - /* The supplicant may attempt to set the PTK once - * pre-authentication is done. Save the key in the - * UMAC and include it in the ADD BSS request - */ - status = sme_ft_update_key(mac_handle, - adapter->vdev_id, &set_key); - if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { - hdd_debug("Update PreAuth Key success"); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return 0; - } else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { - hdd_err("Update PreAuth Key failed"); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return -EINVAL; - } - - /* issue set key request to SME */ - status = sme_roam_set_key(mac_handle, - adapter->vdev_id, &set_key, - &roam_id); - - if (0 != status) { - hdd_err("sme_roam_set_key failed, status: %d", status); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return -EINVAL; - } - - if (adapter->send_mode_change) { - wlan_hdd_send_mode_change_event(); - adapter->send_mode_change = false; - } - - /* in case of IBSS as there was no information - * available about WEP keys during IBSS join, group - * key initialized with NULL key, so re-initialize - * group key with correct value - */ - if ((eCSR_BSS_TYPE_START_IBSS == roam_profile->BSSType) && - !((HDD_AUTH_KEY_MGMT_802_1X == - (sta_ctx->auth_key_mgmt & HDD_AUTH_KEY_MGMT_802_1X)) - && (eCSR_AUTH_TYPE_OPEN_SYSTEM == - sta_ctx->conn_info.auth_type) - ) - && ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) - || (WLAN_CIPHER_SUITE_WEP104 == params->cipher) - ) - ) { - set_key.keyDirection = eSIR_RX_ONLY; - qdf_set_macaddr_broadcast(&set_key.peerMac); - - hdd_debug("Set key peerMac "QDF_MAC_ADDR_STR" direction %d", - QDF_MAC_ADDR_ARRAY(set_key.peerMac.bytes), - set_key.keyDirection); - - status = sme_roam_set_key(mac_handle, - adapter->vdev_id, &set_key, - &roam_id); - - if (0 != status) { - hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status); - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - return -EINVAL; - } - } - } - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - hdd_exit(); - return 0; -} -#endif /* CRYPTO_SET_KEY_CONVERGED */ static int wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, @@ -17065,24 +17964,6 @@ static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy, return errno; } -#ifndef CRYPTO_SET_KEY_CONVERGED -#ifdef FEATURE_WLAN_WAPI -static bool hdd_is_wapi_enc_type(eCsrEncryptionType encrypt_type) -{ - if (encrypt_type == eCSR_ENCRYPT_TYPE_WPI) - return true; - - return false; -} -#else -static bool hdd_is_wapi_enc_type(eCsrEncryptionType encrypt_type) -{ - return false; -} -#endif -#endif - -#ifdef CRYPTO_SET_KEY_CONVERGED static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, @@ -17123,6 +18004,10 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, if (0 != ret) return ret; crypto_key = wlan_crypto_get_key(adapter->vdev, key_index); + if (!crypto_key) { + hdd_err("Invalid NULL key info"); + return -EINVAL; + } hdd_debug("unicast %d, cipher %d", unicast, crypto_key->cipher_type); if (!IS_WEP_CIPHER(crypto_key->cipher_type)) return 0; @@ -17144,167 +18029,13 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, wlan_cfg80211_crypto_add_key(adapter->vdev, (unicast ? WLAN_CRYPTO_KEY_TYPE_UNICAST : WLAN_CRYPTO_KEY_TYPE_GROUP), - key_index); + key_index, true); wma_update_set_key(adapter->vdev_id, unicast, key_index, crypto_key->cipher_type); } return ret; } -#else -/* - * FUNCTION: __wlan_hdd_cfg80211_set_default_key - * This function is used to set the default tx key index - */ -static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, - struct net_device *ndev, - u8 key_index, - bool unicast, bool multicast) -{ - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); - struct hdd_context *hdd_ctx; - mac_handle_t mac_handle; - int status; - - hdd_enter(); - - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); - return -EINVAL; - } - - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) - return -EINVAL; - - qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, - adapter->vdev_id, key_index); - - hdd_debug("Device_mode %s(%d) key_index = %d", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode, key_index); - - if (CSR_MAX_NUM_KEY <= key_index) { - hdd_err("Invalid key index: %d", key_index); - return -EINVAL; - } - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - status = wlan_hdd_validate_context(hdd_ctx); - - if (0 != status) - return status; - - mac_handle = hdd_ctx->mac_handle; - - if ((adapter->device_mode == QDF_STA_MODE) || - (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct csr_roam_profile *roam_profile; - - roam_profile = hdd_roam_profile(adapter); - - if ((eCSR_ENCRYPT_TYPE_TKIP != - sta_ctx->conn_info.uc_encrypt_type) && - !hdd_is_wapi_enc_type( - sta_ctx->conn_info.uc_encrypt_type) && - (eCSR_ENCRYPT_TYPE_AES != - sta_ctx->conn_info.uc_encrypt_type) && - (eCSR_ENCRYPT_TYPE_AES_GCMP != - sta_ctx->conn_info.uc_encrypt_type) && - (eCSR_ENCRYPT_TYPE_AES_GCMP_256 != - sta_ctx->conn_info.uc_encrypt_type)) { - /* If default key index is not same as previous one, - * then update the default key index - */ - - tCsrRoamSetKey set_key; - uint32_t roam_id = INVALID_ROAM_ID; - tCsrKeys *keys = &roam_profile->Keys; - - hdd_debug("Default tx key index %d", key_index); - keys->defaultIndex = (u8) key_index; - qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey)); - set_key.keyId = key_index; - set_key.keyLength = keys->KeyLength[key_index]; - - qdf_mem_copy(&set_key.Key[0], - &keys->KeyMaterial[key_index][0], - keys->KeyLength[key_index]); - - set_key.keyDirection = eSIR_TX_RX; - - qdf_copy_macaddr(&set_key.peerMac, - &sta_ctx->conn_info.bssid); - - if (keys->KeyLength[key_index] == - WLAN_CRYPTO_KEY_WEP40_LEN && - roam_profile->EncryptionType. - encryptionType[0] == eCSR_ENCRYPT_TYPE_WEP104) { - /* In the case of dynamic wep - * supplicant hardcodes DWEP type to - * eCSR_ENCRYPT_TYPE_WEP104 even - * though ap is configured for WEP-40 - * encryption. In this canse the key - * length is 5 but the encryption type - * is 104 hence checking the key - * length(5) and encryption type(104) - * and switching encryption type to 40 - */ - roam_profile->EncryptionType. - encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40; - roam_profile->mcEncryptionType. - encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40; - } - - set_key.encType = - roam_profile->EncryptionType. - encryptionType[0]; - - /* Issue set key request */ - status = sme_roam_set_key(mac_handle, - adapter->vdev_id, &set_key, - &roam_id); - - if (0 != status) { - hdd_err("sme_roam_set_key failed, status: %d", - status); - return -EINVAL; - } - } - } else if (QDF_SAP_MODE == adapter->device_mode) { - struct hdd_ap_ctx *ap_ctx = - WLAN_HDD_GET_AP_CTX_PTR(adapter); - struct csr_roam_profile *profile = - wlan_sap_get_roam_profile(ap_ctx->sap_context); - - if (!profile) { - hdd_err("Failed to get SAP Roam Profile"); - return -EINVAL; - } - /* In SoftAp mode setting key direction for default mode */ - if ((eCSR_ENCRYPT_TYPE_TKIP != - profile->EncryptionType.encryptionType[0]) && - (eCSR_ENCRYPT_TYPE_AES != - profile->EncryptionType.encryptionType[0]) && - (eCSR_ENCRYPT_TYPE_AES_GCMP != - profile->EncryptionType.encryptionType[0]) && - (eCSR_ENCRYPT_TYPE_AES_GCMP_256 != - profile->EncryptionType.encryptionType[0])) { - /* Saving key direction for default key index to TX default */ - ap_ctx->wep_key[key_index].keyDirection = - eSIR_TX_DEFAULT; - hdd_debug("WEP default key index set to SAP context %d", - key_index); - ap_ctx->wep_def_key_idx = key_index; - } - } - - hdd_exit(); - return status; -} -#endif static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, @@ -17397,10 +18128,9 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, uint32_t ie_length = wlan_hdd_get_frame_len(bss_desc); const char *ie = ((ie_length != 0) ? (const char *)&bss_desc->ieFields : NULL); - uint32_t freq, i; + uint32_t i; struct cfg80211_bss *bss_status = NULL; struct hdd_context *hdd_ctx; - struct timespec ts; struct hdd_config *cfg_param; struct wlan_cfg80211_inform_bss bss_data = {0}; @@ -17438,9 +18168,7 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, /* Android does not want the timestamp from the frame. * Instead it wants a monotonic increasing value */ - get_monotonic_boottime(&ts); - bss_data.mgmt->u.probe_resp.timestamp = - ((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); + bss_data.mgmt->u.probe_resp.timestamp = qdf_get_monotonic_boottime(); bss_data.mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval; bss_data.mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo; @@ -17456,26 +18184,10 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, (u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); } - if (bss_desc->channelId <= ARRAY_SIZE(hdd_channels_2_4_ghz) && - (wiphy->bands[HDD_NL80211_BAND_2GHZ])) { - freq = - ieee80211_channel_to_frequency(bss_desc->channelId, - HDD_NL80211_BAND_2GHZ); - } else if ((bss_desc->channelId > ARRAY_SIZE(hdd_channels_2_4_ghz)) - && (wiphy->bands[HDD_NL80211_BAND_5GHZ])) { - freq = - ieee80211_channel_to_frequency(bss_desc->channelId, - HDD_NL80211_BAND_5GHZ); - } else { - hdd_err("Invalid channel: %d", bss_desc->channelId); - qdf_mem_free(bss_data.mgmt); - return NULL; - } - - bss_data.chan = ieee80211_get_channel(wiphy, freq); - if (!bss_data.chan) { - hdd_err("chan pointer is NULL, chan_no: %d freq: %d", - bss_desc->channelId, freq); + bss_data.chan = ieee80211_get_channel(wiphy, bss_desc->chan_freq); + if (!bss_data.chan) { + hdd_err("chan pointer is NULL, chan freq: %d", + bss_desc->chan_freq); qdf_mem_free(bss_data.mgmt); return NULL; } @@ -17496,8 +18208,8 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) bss_data.per_chain_rssi[i] = WLAN_INVALID_PER_CHAIN_RSSI; - hdd_debug("BSSID: " QDF_MAC_ADDR_STR " Channel:%d RSSI:%d TSF %u seq %d is_prob_resp %d", - QDF_MAC_ADDR_ARRAY(bss_data.mgmt->bssid), + hdd_debug("BSSID: " QDF_MAC_ADDR_FMT " Channel:%d RSSI:%d TSF %u seq %d is_prob_resp %d", + QDF_MAC_ADDR_REF(bss_data.mgmt->bssid), bss_data.chan->center_freq, (int)(bss_data.rssi / 100), bss_desc->timeStamp[0], ((bss_desc->seq_ctrl.seqNumHi << HIGH_SEQ_NUM_OFFSET) | bss_desc->seq_ctrl.seqNumLo), @@ -17571,7 +18283,7 @@ int wlan_hdd_cfg80211_pmksa_candidate_notify(struct hdd_adapter *adapter, return -EINVAL; } - hdd_info(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes)); + hdd_info(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(roam_info->bssid.bytes)); cfg80211_pmksa_candidate_notify(dev, index, roam_info->bssid.bytes, preauth, GFP_KERNEL); @@ -17610,8 +18322,8 @@ wlan_hdd_cfg80211_roam_metrics_preauth(struct hdd_adapter *adapter, wrqu.data.pointer = metrics_notification; wrqu.data.length = scnprintf(metrics_notification, sizeof(metrics_notification), - "QCOM: LFR_PREAUTH_INIT " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes)); + "QCOM: LFR_PREAUTH_INIT " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(roam_info->bssid.bytes)); wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); @@ -17651,8 +18363,8 @@ wlan_hdd_cfg80211_roam_metrics_preauth_status(struct hdd_adapter *adapter, memset(metrics_notification, 0, sizeof(metrics_notification)); scnprintf(metrics_notification, sizeof(metrics_notification), - "QCOM: LFR_PREAUTH_STATUS " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes)); + "QCOM: LFR_PREAUTH_STATUS " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(roam_info->bssid.bytes)); if (1 == preauth_status) strlcat(metrics_notification, " true", @@ -17703,8 +18415,8 @@ wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter, wrqu.data.length = scnprintf(metrics_notification, sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes)); + QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(roam_info->bssid.bytes)); wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); @@ -17718,7 +18430,7 @@ wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter, #ifdef FEATURE_MONITOR_MODE_SUPPORT static void hdd_mon_select_cbmode(struct hdd_adapter *adapter, - uint8_t operationChannel, + uint32_t op_freq, struct ch_params *ch_params) { struct hdd_station_ctx *station_ctx = @@ -17758,16 +18470,16 @@ void hdd_mon_select_cbmode(struct hdd_adapter *adapter, ch_info->channel_width = ch_params->ch_width; ch_info->phy_mode = hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode); - ch_info->channel = operationChannel; + ch_info->freq = op_freq; ch_info->cb_mode = ch_params->ch_width; - hdd_debug("ch_info width %d, phymode %d channel %d", + hdd_debug("ch_info width %d, phymode %d channel freq %d", ch_info->channel_width, ch_info->phy_mode, - ch_info->channel); + ch_info->freq); } #else static void hdd_mon_select_cbmode(struct hdd_adapter *adapter, - uint8_t operationChannel, + uint32_t op_freq, struct ch_params *ch_params) { } @@ -17776,15 +18488,15 @@ void hdd_mon_select_cbmode(struct hdd_adapter *adapter, /** * hdd_select_cbmode() - select channel bonding mode * @adapter: Pointer to adapter - * @operatingChannel: Operating channel + * @oper_freq: Operating frequency (MHz) * @ch_params: channel info struct to populate * * Return: none */ -void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel, - struct ch_params *ch_params) +void hdd_select_cbmode(struct hdd_adapter *adapter, qdf_freq_t oper_freq, + struct ch_params *ch_params) { - uint8_t sec_ch = 0; + uint32_t sec_ch_freq = 0; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); /* @@ -17792,19 +18504,19 @@ void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel, * the channel params */ if ((ch_params->ch_width == CH_WIDTH_40MHZ) && - (WLAN_REG_IS_24GHZ_CH(operationChannel))) { - if (operationChannel >= 1 && operationChannel <= 5) - sec_ch = operationChannel + 4; - else if (operationChannel >= 6 && operationChannel <= 13) - sec_ch = operationChannel - 4; + (WLAN_REG_IS_24GHZ_CH_FREQ(oper_freq))) { + if (oper_freq >= 2412 && oper_freq <= 2432) + sec_ch_freq = oper_freq + 20; + else if (oper_freq >= 2437 && oper_freq <= 2472) + sec_ch_freq = oper_freq - 20; } /* This call decides required channel bonding mode */ - wlan_reg_set_channel_params(hdd_ctx->pdev, operationChannel, - sec_ch, ch_params); + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, oper_freq, + sec_ch_freq, ch_params); if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) - hdd_mon_select_cbmode(adapter, operationChannel, ch_params); + hdd_mon_select_cbmode(adapter, oper_freq, ch_params); } /** @@ -17824,8 +18536,8 @@ bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter, struct hdd_adapter *ap_adapter; struct hdd_ap_ctx *hdd_ap_ctx; struct hdd_hostapd_state *hostapd_state; - uint8_t channel = 0; QDF_STATUS status; + uint32_t ch_freq = 0; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -17862,8 +18574,8 @@ bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter, } /* sap is on non-dfs channel, nothing to handle */ - if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev, - hdd_ap_ctx->operating_channel)) { + if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, + hdd_ap_ctx->operating_chan_freq)) { hdd_debug("sap is on non-dfs channel, sta is allowed"); return true; } @@ -17871,14 +18583,14 @@ bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter, * find out by looking in to scan cache where sta is going to * connect by passing its roam_profile. */ - status = policy_mgr_get_channel_from_scan_result(hdd_ctx->psoc, - roam_profile, &channel); + status = policy_mgr_get_channel_from_scan_result( + hdd_ctx->psoc, roam_profile, &ch_freq); /* * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz * channels for roaming case. */ - if (WLAN_REG_IS_24GHZ_CH(channel)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { hdd_info("sap is on dfs, new sta conn on 2.4 is allowed"); return true; } @@ -17889,9 +18601,9 @@ bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter, * better move SAP to STA's channel to make scc, so we have room * for 3port MCC scenario. */ - if (!channel || wlan_reg_is_dfs_ch(hdd_ctx->pdev, channel) || - !policy_mgr_is_safe_channel(hdd_ctx->psoc, channel)) - channel = policy_mgr_get_nondfs_preferred_channel( + if (!ch_freq || wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, ch_freq) || + !policy_mgr_is_safe_channel(hdd_ctx->psoc, ch_freq)) + ch_freq = policy_mgr_get_nondfs_preferred_channel( hdd_ctx->psoc, PM_SAP_MODE, true); hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); @@ -17900,7 +18612,7 @@ bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter, CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS); status = wlansap_set_channel_change_with_csa( - WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), channel, + WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), ch_freq, hdd_ap_ctx->sap_config.ch_width_orig, false); if (QDF_STATUS_SUCCESS != status) { @@ -17975,8 +18687,9 @@ int wlan_hdd_cfg80211_check_pmf_valid(struct csr_roam_profile *roam_profile) static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, const u8 *ssid, size_t ssid_len, const u8 *bssid, const u8 *bssid_hint, - u8 operatingChannel, - enum nl80211_chan_width ch_width) + uint32_t oper_freq, + enum nl80211_chan_width ch_width, + uint32_t ch_freq_hint) { int status = 0; QDF_STATUS qdf_status; @@ -17986,7 +18699,6 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, struct csr_roam_profile *roam_profile; enum csr_akm_type rsn_auth_type; struct sme_config_params *sme_config; - uint8_t channel = 0; mac_handle_t mac_handle; uint8_t wmm_mode = 0; uint8_t value = 0; @@ -18159,16 +18871,14 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, hdd_objmgr_put_vdev(vdev); roam_profile->csrPersona = adapter->device_mode; - if (operatingChannel) { - roam_profile->ChannelInfo.ChannelList = - &operatingChannel; + if (oper_freq) { + roam_profile->ChannelInfo.freq_list = &oper_freq; roam_profile->ChannelInfo.numOfChannels = 1; } else { - roam_profile->ChannelInfo.ChannelList = NULL; + roam_profile->ChannelInfo.freq_list = NULL; roam_profile->ChannelInfo.numOfChannels = 0; } - if ((QDF_IBSS_MODE == adapter->device_mode) - && operatingChannel) { + if (QDF_IBSS_MODE == adapter->device_mode && oper_freq) { /* * Need to post the IBSS power save parameters * to WMA. WMA will configure this parameters @@ -18188,13 +18898,15 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, * In IBSS mode while operating in 2.4 GHz, * the device supports only 20 MHz. */ - if (WLAN_REG_IS_24GHZ_CH(operatingChannel)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(oper_freq)) roam_profile->ch_params.ch_width = CH_WIDTH_20MHZ; - hdd_select_cbmode(adapter, operatingChannel, + hdd_select_cbmode(adapter, oper_freq, &roam_profile->ch_params); } + roam_profile->freq_hint = ch_freq_hint; + if (wlan_hdd_cfg80211_check_pmf_valid(roam_profile)) { status = -EINVAL; goto conn_failure; @@ -18330,22 +19042,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, /* Reset connect_in_progress */ hdd_set_connection_in_progress(false); - roam_profile->ChannelInfo.ChannelList = NULL; + roam_profile->ChannelInfo.freq_list = NULL; roam_profile->ChannelInfo.numOfChannels = 0; - - if ((QDF_STA_MODE == adapter->device_mode) - && policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) - && !policy_mgr_is_hw_dbs_2x2_capable( - hdd_ctx->psoc)) { - policy_mgr_get_channel_from_scan_result( - hdd_ctx->psoc, - roam_profile, &channel); - hdd_info("Move to single MAC mode(optimization) if applicable"); - if (channel) - policy_mgr_checkn_update_hw_mode_single_mac_mode( - hdd_ctx->psoc, channel); - } - } else { hdd_err("No valid Roam profile"); status = -EINVAL; @@ -18460,23 +19158,21 @@ static bool wlan_hdd_fils_data_in_limits(struct cfg80211_connect_params *req) req->fils_erp_next_seq_num, req->auth_type, req->fils_erp_username_len, req->fils_erp_rrk_len, req->fils_erp_realm_len); - if (req->fils_erp_rrk_len || req->fils_erp_realm_len || - req->fils_erp_username_len || - req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH || + + if (req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH || req->fils_erp_realm_len > FILS_MAX_REALM_LEN || req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) { hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu", req->fils_erp_username_len, req->fils_erp_rrk_len, req->fils_erp_realm_len); - return true; + return false; } if (!req->fils_erp_rrk || !req->fils_erp_realm || - !req->fils_erp_username) { - hdd_err("buffer incorrect, user=%pK rrk=%pK realm=%pK", + !req->fils_erp_username) + hdd_err("ERP info is NULL, user=%pK rrk=%pK realm=%pK", req->fils_erp_username, req->fils_erp_rrk, req->fils_erp_realm); - } return true; } @@ -18939,7 +19635,6 @@ static inline void wlan_hdd_save_hlp_ie(struct csr_roam_profile *roam_profile, {} #endif -#ifdef WLAN_CONV_CRYPTO_SUPPORTED /** * hdd_populate_crypto_auth_type() - populate auth type for crypto * @vdev: pointed to vdev obmgr @@ -19049,6 +19744,8 @@ static void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev, hdd_populate_crypto_cipher_type(req->crypto.cipher_group, vdev, WLAN_CRYPTO_PARAM_MCAST_CIPHER); + + wlan_crypto_free_vdev_key(vdev); } /** @@ -19080,40 +19777,6 @@ static void hdd_set_crypto_key_mgmt_param(struct hdd_adapter *adapter) hdd_objmgr_put_vdev(vdev); } -#else - -static inline -void hdd_populate_crypto_auth_type(struct wlan_objmgr_vdev *vdev, - enum nl80211_auth_type auth_type) -{ -} - -static inline -void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev, - u32 key_mgmt) -{ -} - -static inline -void hdd_populate_crypto_cipher_type(u32 cipher, - struct wlan_objmgr_vdev *vdev, - wlan_crypto_param_type - cipher_param_type) -{ -} - -static inline -void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev, - struct cfg80211_connect_params *req) -{ -} - -static inline void hdd_set_crypto_key_mgmt_param(struct hdd_adapter *adapter) -{ -} - -#endif - /** * wlan_hdd_cfg80211_set_ie() - set IEs * @adapter: Pointer to adapter @@ -19490,6 +20153,7 @@ static int wlan_hdd_cfg80211_set_ie(struct hdd_adapter *adapter, return 0; } +#ifdef QCA_IBSS_SUPPORT /** * hdd_is_wpaie_present() - check for WPA ie * @ie: Pointer to ie @@ -19527,493 +20191,349 @@ static bool hdd_is_wpaie_present(const uint8_t *ie, uint8_t ie_len) return false; } -#ifdef CRYPTO_SET_KEY_CONVERGED -static void wlan_hdd_cfg80211_store_wep_key(struct hdd_adapter *adapter, - struct wlan_objmgr_vdev *vdev, - struct cfg80211_connect_params *req) -{ - struct key_params params; - - qdf_mem_zero(¶ms, sizeof(params)); - params.cipher = req->crypto.ciphers_pairwise[0]; - params.key_len = req->key_len; - params.key = req->key; - wlan_cfg80211_store_key(vdev, req->key_idx, - WLAN_CRYPTO_KEY_TYPE_UNICAST, - NULL, ¶ms); -} -#else -static void wlan_hdd_cfg80211_store_wep_key(struct hdd_adapter *adapter, - struct wlan_objmgr_vdev *vdev, - struct cfg80211_connect_params *req) -{ - struct csr_roam_profile *roam_profile; - - roam_profile = hdd_roam_profile(adapter); - hdd_debug("setting default wep key, key_idx = %hu key_len %hu", - req->key_idx, req->key_len); - qdf_mem_copy(&roam_profile->Keys.KeyMaterial[req->key_idx][0], - req->key, req->key_len); - roam_profile->Keys.KeyLength[req->key_idx] = req->key_len; - roam_profile->Keys.defaultIndex = req->key_idx; -} -#endif /* !CRYPTO_SET_KEY_CONVERGED */ - /** - * wlan_hdd_cfg80211_set_privacy() - set security parameters during connection + * wlan_hdd_cfg80211_set_privacy_ibss() - set ibss privacy * @adapter: Pointer to adapter - * @req: Pointer to security parameters + * @param: Pointer to IBSS parameters + * + * This function is used to initialize the security settings in IBSS mode * * Return: 0 for success, non-zero for failure */ -static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter, - struct cfg80211_connect_params *req) +static int wlan_hdd_cfg80211_set_privacy_ibss(struct hdd_adapter *adapter, + struct cfg80211_ibss_params + *params) { + uint32_t ret; int status = 0; - struct hdd_station_ctx *sta_ctx; + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + struct hdd_station_ctx *sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); struct csr_roam_profile *roam_profile; - struct wlan_objmgr_vdev *vdev; - - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - sta_ctx->wpa_versions = req->crypto.wpa_versions; - roam_profile = hdd_roam_profile(adapter); - - /* populate auth,akm and cipher params for crypto */ - vdev = hdd_objmgr_get_vdev(adapter); - if (!vdev) - return -EINVAL; - hdd_populate_crypto_params(vdev, req); + hdd_enter(); - /*set authentication type */ - status = wlan_hdd_cfg80211_set_auth_type(adapter, req->auth_type); + sta_ctx->wpa_versions = 0; + qdf_mem_zero(&sta_ctx->ibss_enc_key, sizeof(tCsrRoamSetKey)); + sta_ctx->ibss_enc_key_installed = 0; - if (wlan_hdd_is_conn_type_fils(req)) { - status = wlan_hdd_cfg80211_set_fils_config(adapter, req); + if (params->ie_len && (params->ie)) { + if (wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, params->ie, + params->ie_len)) { + sta_ctx->wpa_versions = NL80211_WPA_VERSION_2; + encryptionType = eCSR_ENCRYPT_TYPE_AES; + } else if (hdd_is_wpaie_present(params->ie, params->ie_len)) { + tDot11fIEWPA dot11_wpa_ie; + mac_handle_t mac_handle = + hdd_adapter_get_mac_handle(adapter); + const u8 *ie; - if (0 > status) { - hdd_err("Failed to set fils config"); - goto release_vdev_ref; + memset(&dot11_wpa_ie, 0, sizeof(dot11_wpa_ie)); + ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WPA, + params->ie, params->ie_len); + if (ie) { + sta_ctx->wpa_versions = NL80211_WPA_VERSION_1; + /* Unpack the WPA IE + * Skip past the EID byte and length byte + * and four byte WiFi OUI + */ + if (ie[1] < DOT11F_IE_WPA_MIN_LEN || + ie[1] > DOT11F_IE_WPA_MAX_LEN) { + hdd_err("invalid ie len:%d", ie[1]); + return -EINVAL; + } + ret = dot11f_unpack_ie_wpa( + MAC_CONTEXT(mac_handle), + (uint8_t *)&ie[2 + 4], + ie[1] - 4, &dot11_wpa_ie, false); + if (DOT11F_FAILED(ret)) { + hdd_err("unpack failed ret: 0x%x", ret); + return -EINVAL; + } + /* + * Extract the multicast cipher, the + * encType for unicast cipher for + * wpa-none is none + */ + encryptionType = + hdd_translate_wpa_to_csr_encryption_type + (dot11_wpa_ie.multicast_cipher); + } } - } - /*set key mgmt type */ - if (req->crypto.n_akm_suites) { status = - wlan_hdd_set_akm_suite(adapter, req->crypto.akm_suites[0]); - if (0 > status) { - hdd_err("Failed to set akm suite"); - goto release_vdev_ref; - } - } - - /*set pairwise cipher type */ - if (req->crypto.n_ciphers_pairwise) { - status = wlan_hdd_cfg80211_set_cipher(adapter, - req->crypto. - ciphers_pairwise[0], - true); - if (0 > status) { - hdd_err("Failed to set unicast cipher type"); - goto release_vdev_ref; - } - } else { - /*Reset previous cipher suite to none */ - status = wlan_hdd_cfg80211_set_cipher(adapter, 0, true); - if (0 > status) { - hdd_err("Failed to set unicast cipher type"); - goto release_vdev_ref; - } - } - - /*set group cipher type */ - status = - wlan_hdd_cfg80211_set_cipher(adapter, req->crypto.cipher_group, - false); - - if (0 > status) { - hdd_err("Failed to set mcast cipher type"); - goto release_vdev_ref; - } -#ifdef WLAN_FEATURE_11W - roam_profile->MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED); -#endif + wlan_hdd_cfg80211_set_ie(adapter, params->ie, + params->ie_len); - /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile */ - if (req->ie_len) { - status = - wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len); if (0 > status) { - hdd_err("Failed to parse the WPA/RSN IE"); - goto release_vdev_ref; + hdd_err("Failed to parse WPA/RSN IE"); + return status; } } - /*incase of WEP set default key information */ - if (req->key && req->key_len) { - u32 cipher = req->crypto.ciphers_pairwise[0]; - - if ((WLAN_CIPHER_SUITE_WEP40 == cipher) || - (WLAN_CIPHER_SUITE_WEP104 == cipher)) { - enum hdd_auth_key_mgmt key_mgmt = - sta_ctx->auth_key_mgmt; + roam_profile = hdd_roam_profile(adapter); + roam_profile->AuthType.authType[0] = + sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; - if (key_mgmt & HDD_AUTH_KEY_MGMT_802_1X) { - hdd_err("Dynamic WEP not supported"); - status = -EOPNOTSUPP; - goto release_vdev_ref; - } + if (params->privacy) { + /* Security enabled IBSS, At this time there is no information + * available about the security parameters, so initialise the + * encryption type to eCSR_ENCRYPT_TYPE_WEP40_STATICKEY. + * The correct security parameters will be updated later in + * wlan_hdd_cfg80211_add_key Hal expects encryption type to be + * set inorder enable privacy bit in beacons + */ - if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= - req->key_len) && (CSR_MAX_NUM_KEY > req->key_idx)) - wlan_hdd_cfg80211_store_wep_key(adapter, - vdev, req); - } + encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; } -release_vdev_ref: - hdd_objmgr_put_vdev(vdev); - + hdd_debug("encryptionType=%d", encryptionType); + sta_ctx->conn_info.uc_encrypt_type = encryptionType; + roam_profile->EncryptionType.numEntries = 1; + roam_profile->EncryptionType.encryptionType[0] = + encryptionType; return status; } /** - * wlan_hdd_clear_wapi_privacy() - reset WAPI settings in HDD layer - * @adapter: pointer to HDD adapter object + * __wlan_hdd_cfg80211_join_ibss() - join ibss + * @wiphy: Pointer to wiphy + * @dev: Pointer to network device + * @param: Pointer to IBSS join parameters * - * This function resets all WAPI related parameters imposed before STA - * connection starts. It's invoked when privacy checking against concurrency - * fails, to make sure no improper WAPI settings are still populated before - * returning an error to the upper layer requester. + * This function is used to create/join an IBSS network * - * Return: none + * Return: 0 for success, non-zero for failure */ -#ifdef FEATURE_WLAN_WAPI -static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter) -{ - adapter->wapi_info.wapi_mode = 0; - adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN; -} -#else -static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter) +static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) { -} -#endif - -/** - * wlan_hdd_cfg80211_clear_privacy() - reset STA security parameters - * @adapter: pointer to HDD adapter object - * - * This function resets all privacy related parameters imposed - * before STA connection starts. It's invoked when privacy checking - * against concurrency fails, to make sure no improper settings are - * still populated before returning an error to the upper layer requester. - * - * Return: none - */ -static void wlan_hdd_cfg80211_clear_privacy(struct hdd_adapter *adapter) -{ - struct hdd_station_ctx *hdd_sta_ctx = + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct csr_roam_profile *roam_profile; + int status; + struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct qdf_mac_addr bssid; + uint8_t channelNum = 0; + mac_handle_t mac_handle; + struct wlan_mlme_ibss_cfg ibss_cfg = {0}; + uint8_t conn_info_channel; - hdd_debug("resetting all privacy configurations"); + hdd_enter(); - hdd_sta_ctx->wpa_versions = 0; + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EINVAL; + } - hdd_sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_NONE; - hdd_sta_ctx->roam_profile.AuthType.authType[0] = eCSR_AUTH_TYPE_NONE; + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + return -EINVAL; - hdd_sta_ctx->conn_info.uc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE; - hdd_sta_ctx->roam_profile.EncryptionType.numEntries = 0; - hdd_sta_ctx->conn_info.mc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE; - hdd_sta_ctx->roam_profile.mcEncryptionType.numEntries = 0; + qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + adapter->vdev_id, adapter->device_mode); - wlan_hdd_clear_wapi_privacy(adapter); -} + hdd_debug("Device_mode %s(%d)", + qdf_opmode_str(adapter->device_mode), adapter->device_mode); -static int wlan_hdd_wait_for_disconnect(mac_handle_t mac_handle, - struct hdd_adapter *adapter, - uint16_t reason, - tSirMacReasonCodes mac_reason) -{ - eConnectionState prev_conn_state; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - QDF_STATUS status = QDF_STATUS_SUCCESS; - int ret = 0; - unsigned long rc; - uint32_t wait_time = SME_DISCONNECT_TIMEOUT; + status = wlan_hdd_validate_context(hdd_ctx); - /* Return if already disconnected */ - if (sta_ctx->conn_info.conn_state == eConnectionState_NotConnected || - sta_ctx->conn_info.conn_state == eConnectionState_IbssDisconnected) - return 0; + if (0 != status) + return status; - /* If already in disconnecting state just wait for its completion */ - if (sta_ctx->conn_info.conn_state == eConnectionState_Disconnecting) - goto wait_for_disconnect; + if (QDF_IS_STATUS_ERROR(ucfg_mlme_get_ibss_cfg(hdd_ctx->psoc, + &ibss_cfg))) { + return -EINVAL; + } - INIT_COMPLETION(adapter->disconnect_comp_var); - prev_conn_state = sta_ctx->conn_info.conn_state; - hdd_conn_set_connection_state(adapter, eConnectionState_Disconnecting); + mac_handle = hdd_ctx->mac_handle; + if (NULL != + params->chandef.chan) { + uint32_t numChans = CFG_VALID_CHANNEL_LIST_LEN; + uint32_t validChan[CFG_VALID_CHANNEL_LIST_LEN]; + int indx; - status = sme_roam_disconnect(mac_handle, adapter->vdev_id, reason, - mac_reason); - if (status == QDF_STATUS_CMD_NOT_QUEUED && - prev_conn_state == eConnectionState_Connecting) { - /* - * Wait here instead of returning directly, this will block the - * next connect command and allow processing of the scan for - * ssid and the previous connect command in CSR. - */ - hdd_debug("CSR not connected but scan for SSID is in progress, wait for scan to be aborted or completed."); - } else if (QDF_IS_STATUS_ERROR(status)) { - hdd_debug("SB Disconnect in progress/SME is disconencted/Connect removed from pending queue: status = %d", - status); - /* - * Wait here instead of returning directly. This will block the - * next connect command and allow processing of the disconnect - * in SME. As disconnect is already in progress, wait here for - * WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS instead of - * SME_DISCONNECT_TIMEOUT. - */ - wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS; + /* Get channel number */ + channelNum = ieee80211_frequency_to_channel( + params-> + chandef. + chan-> + center_freq); + ucfg_mlme_get_valid_channel_freq_list(hdd_ctx->psoc, validChan, + &numChans); + + for (indx = 0; indx < numChans; indx++) { + if (channelNum == + wlan_reg_freq_to_chan(hdd_ctx->pdev, validChan[indx])) + break; + } + if (indx >= numChans) { + hdd_err("Not valid Channel: %d", channelNum); + return -EINVAL; + } } -wait_for_disconnect: - rc = wait_for_completion_timeout(&adapter->disconnect_comp_var, - msecs_to_jiffies(wait_time)); + /* Disable NAN Discovery if enabled */ + ucfg_nan_disable_concurrency(hdd_ctx->psoc); - if (!rc && QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("Disconnect timed out!!!"); - ret = -ETIMEDOUT; + if (!policy_mgr_allow_concurrency( + hdd_ctx->psoc, PM_IBSS_MODE, + wlan_reg_chan_to_freq(hdd_ctx->pdev, channelNum), + HW_MODE_20_MHZ)) { + hdd_err("This concurrency combination is not allowed"); + return -ECONNREFUSED; } - hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected); + status = policy_mgr_reset_connection_update(hdd_ctx->psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("qdf_reset_connection_update failed status: %d", status); - return ret; -} + status = policy_mgr_current_connections_update( + hdd_ctx->psoc, adapter->vdev_id, + wlan_reg_chan_to_freq(hdd_ctx->pdev, channelNum), + POLICY_MGR_UPDATE_REASON_JOIN_IBSS); + if (QDF_STATUS_E_FAILURE == status) { + hdd_err("connections update failed!!"); + return -EINVAL; + } -static void wlan_hdd_wait_for_roaming(mac_handle_t mac_handle, - struct hdd_adapter *adapter) -{ - struct hdd_context *hdd_ctx; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - unsigned long rc; + if (QDF_STATUS_SUCCESS == status) { + status = policy_mgr_wait_for_connection_update( + hdd_ctx->psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("qdf wait for event failed!!"); + return -EINVAL; + } + } - if (adapter->device_mode != QDF_STA_MODE) - return; + /*Try disconnecting if already in connected state */ + status = wlan_hdd_try_disconnect(adapter, + eSIR_MAC_UNSPEC_FAILURE_REASON); + if (0 > status) { + hdd_err("Failed to disconnect the existing IBSS connection"); + return -EALREADY; + } - /* Return if not in connected state */ - if (sta_ctx->conn_info.conn_state != eConnectionState_Associated) - return; + roam_profile = hdd_roam_profile(adapter); - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - sme_stop_roaming(mac_handle, adapter->vdev_id, - REASON_DRIVER_DISABLED, - RSO_INVALID_REQUESTOR); - /* - * If firmware has already started roaming process, driver - * needs to wait for processing of this disconnect request. - * - */ - INIT_COMPLETION(adapter->roaming_comp_var); - if (hdd_is_roaming_in_progress(hdd_ctx) || - sme_neighbor_middle_of_roaming(mac_handle, - adapter->vdev_id)) { - rc = wait_for_completion_timeout(&adapter->roaming_comp_var, - msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM)); - if (!rc) { - hdd_err("roaming_comp_var time out vdev id: %d", - adapter->vdev_id); - /* Clear roaming in progress flag */ - hdd_set_roaming_in_progress(false); + if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) { + hdd_err("Interface type is not set to IBSS"); + return -EINVAL; + } + + /* enable selected protection checks in IBSS mode */ + roam_profile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK; + + /* BSSID is provided by upper layers hence no need to AUTO generate */ + if (params->bssid) { + if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0) + == QDF_STATUS_E_FAILURE) { + hdd_err("Unable to update MLME IBSS Auto BSSID config"); + return -EIO; } - if (adapter->roam_ho_fail) { - INIT_COMPLETION(adapter->disconnect_comp_var); - hdd_conn_set_connection_state(adapter, - eConnectionState_Disconnecting); + qdf_mem_copy(bssid.bytes, params->bssid, QDF_MAC_ADDR_SIZE); + } else if (ibss_cfg.coalesing_enable == 0) { + if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0) + == QDF_STATUS_E_FAILURE) { + hdd_err("Unable to update MLME IBSS Auto BSSID config"); + return -EIO; } + qdf_copy_macaddr(&bssid, &ibss_cfg.bssid); } -} -int wlan_hdd_try_disconnect(struct hdd_adapter *adapter, - enum eSirMacReasonCodes reason) -{ - mac_handle_t mac_handle; + if (cfg_in_range(CFG_BEACON_INTERVAL, params->beacon_interval)) + roam_profile->beaconInterval = params->beacon_interval; + else + roam_profile->beaconInterval = cfg_get(hdd_ctx->psoc, + CFG_BEACON_INTERVAL); - mac_handle = hdd_adapter_get_mac_handle(adapter); - wlan_hdd_wait_for_roaming(mac_handle, adapter); + /* Set Channel */ + if (channelNum) { + /* Set the Operational Channel */ + hdd_debug("set channel %d", channelNum); + roam_profile->ChannelInfo.numOfChannels = 1; + sta_ctx->conn_info.chan_freq = + wlan_reg_chan_to_freq(hdd_ctx->pdev, + channelNum); + roam_profile->ChannelInfo.freq_list = + &sta_ctx->conn_info.chan_freq; + } - return wlan_hdd_wait_for_disconnect(mac_handle, adapter, - eCSR_DISCONNECT_REASON_UNSPECIFIED, - reason); + /* Initialize security parameters */ + status = wlan_hdd_cfg80211_set_privacy_ibss(adapter, params); + if (status < 0) { + hdd_err("failed to set security parameters"); + return status; + } + + conn_info_channel = + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sta_ctx->conn_info.chan_freq); + /* Issue connect start */ + status = wlan_hdd_cfg80211_connect_start(adapter, params->ssid, + params->ssid_len, + bssid.bytes, NULL, + conn_info_channel, + params->chandef.width, + 0); + + if (0 > status) { + hdd_err("connect failed"); + return status; + } + hdd_exit(); + return 0; } /** - * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present - * @adapter: Pointer to the HDD adapter - * @req: Pointer to the structure cfg_connect_params receieved from user space + * wlan_hdd_cfg80211_join_ibss() - join ibss + * @wiphy: Pointer to wiphy + * @dev: Pointer to network device + * @param: Pointer to IBSS join parameters * - * This function will start reassociation if prev_bssid is set and bssid/ - * bssid_hint, channel/channel_hint parameters are present in connect request. + * This function is used to create/join an IBSS network * - * Return: 0 if connect was for ReAssociation, non-zero error code otherwise - */ -#if defined(CFG80211_CONNECT_PREV_BSSID) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) -static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter, - struct cfg80211_connect_params *req) -{ - int status = -EINVAL; - const uint8_t *bssid = NULL; - uint16_t channel = 0; - struct hdd_station_ctx *sta_ctx; - - if (req->bssid) - bssid = req->bssid; - else if (req->bssid_hint) - bssid = req->bssid_hint; - - if (req->channel) - channel = req->channel->hw_value; - else if (req->channel_hint) - channel = req->channel_hint->hw_value; - - if (bssid && channel && req->prev_bssid) { - hdd_debug("REASSOC Attempt on channel %d to " QDF_MAC_ADDR_STR, - channel, QDF_MAC_ADDR_ARRAY(bssid)); - /* - * Save BSSID in a separate variable as - * roam_profile's BSSID is getting zeroed out in the - * association process. In case of join failure - * we should send valid BSSID to supplicant - */ - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - qdf_mem_copy(sta_ctx->requested_bssid.bytes, bssid, - QDF_MAC_ADDR_SIZE); - - hdd_set_roaming_in_progress(true); - - status = hdd_reassoc(adapter, bssid, channel, - CONNECT_CMD_USERSPACE); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_set_roaming_in_progress(false); - hdd_debug("Failed with status: %d", status); - } - } - return status; -} -#else -static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter, - struct cfg80211_connect_params *req) -{ - return -ENOTSUPP; -} -#endif - - -/** - * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to - * connect in HT20 mode - * @hdd_ctx: hdd context - * @adapter: Pointer to the HDD adapter - * @req: Pointer to the structure cfg_connect_params receieved from user space - * - * This function will check if supplicant has indicated to to connect in HT20 - * mode. this is currently applicable only for 2.4Ghz mode only. - * if feature is enabled and supplicant indicate HT20 set - * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false. - * - * Return: void + * Return: 0 for success, non-zero for failure */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) -static void -wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx, - struct hdd_adapter *adapter, - struct cfg80211_connect_params *req) -{ - struct csr_roam_profile *roam_profile; - bool is_override_ht20_40_24g; - - roam_profile = hdd_roam_profile(adapter); - - roam_profile->force_24ghz_in_ht20 = false; - - ucfg_mlme_is_override_ht20_40_24g(hdd_ctx->psoc, - &is_override_ht20_40_24g); - if (is_override_ht20_40_24g && - !(req->ht_capa.cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) - roam_profile->force_24ghz_in_ht20 = true; - - if (is_override_ht20_40_24g) - hdd_nofl_debug("HT cap %x", req->ht_capa.cap_info); -} -#else -static inline void -wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx, - struct hdd_adapter *adapter, - struct cfg80211_connect_params *req) +static int wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) { - struct csr_roam_profile *roam_profile; - - roam_profile = hdd_roam_profile(adapter); - - roam_profile->force_24ghz_in_ht20 = false; -} -#endif + int errno; + struct osif_vdev_sync *vdev_sync; -static inline void hdd_dump_connect_req(struct hdd_adapter *adapter, - struct net_device *ndev, - struct cfg80211_connect_params *req) -{ - uint32_t i; + errno = osif_vdev_sync_op_start(dev, &vdev_sync); + if (errno) + return errno; - hdd_nofl_debug("cfg80211_connect req for %s(vdevid-%d): mode %d freq %d SSID %.*s auth type %d WPA ver %d n_akm %d n_cipher %d grp_cipher %x mfp %d freq hint %d", - ndev->name, adapter->vdev_id, adapter->device_mode, - req->channel ? req->channel->center_freq : 0, - (int)req->ssid_len, req->ssid, req->auth_type, - req->crypto.wpa_versions, - req->crypto.n_akm_suites, req->crypto.n_ciphers_pairwise, - req->crypto.cipher_group, req->mfp, - req->channel_hint ? req->channel_hint->center_freq : 0); - if (req->bssid) - hdd_nofl_debug("BSSID %pM", req->bssid); - if (req->bssid_hint) - hdd_nofl_debug("BSSID hint %pM", req->bssid_hint); - if (req->prev_bssid) - hdd_nofl_debug("prev BSSID %pM", req->prev_bssid); + errno = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params); - for (i = 0; i < req->crypto.n_akm_suites; i++) - hdd_nofl_debug("akm[%d] = %x", i, req->crypto.akm_suites[i]); + osif_vdev_sync_op_stop(vdev_sync); - for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) - hdd_nofl_debug("cipher_pairwise[%d] = %x", i, - req->crypto.ciphers_pairwise[i]); + return errno; } /** - * __wlan_hdd_cfg80211_connect() - cfg80211 connect api + * __wlan_hdd_cfg80211_leave_ibss() - leave ibss * @wiphy: Pointer to wiphy * @dev: Pointer to network device - * @req: Pointer to cfg80211 connect request * - * This function is used to start the association process + * This function is used to leave an IBSS network * * Return: 0 for success, non-zero for failure */ -static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_connect_params *req) +static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev) { + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct csr_roam_profile *roam_profile; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); int status; - u16 channel, sap_cnt, sta_cnt; - const u8 *bssid = NULL; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) - const u8 *bssid_hint = req->bssid_hint; -#else - const u8 *bssid_hint = NULL; -#endif - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); - struct hdd_context *hdd_ctx; + mac_handle_t mac_handle; + unsigned long rc; + tSirUpdateIE update_ie; hdd_enter(); @@ -20026,714 +20546,615 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, return -EINVAL; qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_CONNECT, - adapter->vdev_id, adapter->device_mode); - - if (adapter->device_mode != QDF_STA_MODE && - adapter->device_mode != QDF_P2P_CLIENT_MODE) { - hdd_err("Device_mode %s(%d) is not supported", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - return -EINVAL; - } - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (!hdd_ctx) { - hdd_err("HDD context is null"); - return -EINVAL; - } + TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, + adapter->vdev_id, eCSR_DISCONNECT_REASON_IBSS_LEAVE); status = wlan_hdd_validate_context(hdd_ctx); if (0 != status) return status; - if (req->bssid) - bssid = req->bssid; - else if (bssid_hint) - bssid = bssid_hint; + hdd_debug("Device_mode %s(%d)", + qdf_opmode_str(adapter->device_mode), adapter->device_mode); - if (bssid && hdd_get_adapter_by_macaddr(hdd_ctx, (uint8_t *)bssid)) { - hdd_err("adapter exist with same mac address " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(bssid)); + roam_profile = hdd_roam_profile(adapter); + + /* Issue disconnect only if interface type is set to IBSS */ + if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) { + hdd_err("BSS Type is not set to IBSS"); return -EINVAL; } - - hdd_dump_connect_req(adapter, ndev, req); - /* - * Disable NAN Discovery if incoming connection is P2P or if a STA - * connection already exists and if this is a case of STA+STA - * or SAP+STA concurrency - */ - sta_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, - PM_STA_MODE, NULL); - sap_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, - PM_SAP_MODE, NULL); - - if (adapter->device_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) { - hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P: %d", - sap_cnt, sta_cnt, - (adapter->device_mode == QDF_P2P_CLIENT_MODE)); - ucfg_nan_disable_concurrency(hdd_ctx->psoc); + /* Clearing add IE of beacon */ + qdf_mem_copy(update_ie.bssid.bytes, adapter->mac_addr.bytes, + sizeof(tSirMacAddr)); + update_ie.vdev_id = adapter->vdev_id; + update_ie.ieBufferlength = 0; + update_ie.pAdditionIEBuffer = NULL; + update_ie.append = true; + update_ie.notify = true; + mac_handle = hdd_ctx->mac_handle; + if (sme_update_add_ie(mac_handle, + &update_ie, + eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) { + hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); } - /* - * STA+NDI concurrency gets preference over NDI+NDI. Disable - * first NDI in case an NDI+NDI concurrency exists. - */ - ucfg_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc, false); - /* - * In STA + STA roaming scenario, connection to same ssid but different - * bssid is allowed on both vdevs. So there could be a race where the - * STA1 connectes to a bssid when roaming is in progress on STA2 for - * the same bssid. Here the firwmare would have already created peer for - * the roam candidate and host would have created peer on the other - * vdev. When roam synch indication is received, then peer create fails - * at host for the roaming vdev due to duplicate peer detection logic. - * Still roam synch confirm is sent to the firmware. - * When disconnection is received for STA1, then del bss is sent for - * this vdev and firmware asserts as the peer was not created for this - * vdev. - */ - if (hdd_is_roaming_in_progress(hdd_ctx) || - sme_is_any_session_in_middle_of_roaming(hdd_ctx->mac_handle)) { - hdd_err("Roaming in progress. Defer connect"); - return -EBUSY; + /* Reset WNI_CFG_PROBE_RSP Flags */ + wlan_hdd_reset_prob_rspies(adapter); + + /* Issue Disconnect request */ + INIT_COMPLETION(adapter->disconnect_comp_var); + status = sme_roam_disconnect(mac_handle, + adapter->vdev_id, + eCSR_DISCONNECT_REASON_IBSS_LEAVE, + eSIR_MAC_UNSPEC_FAILURE_REASON); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("sme_roam_disconnect failed status: %d", + status); + return -EAGAIN; } - /* - * Check if this is reassoc to same bssid, if reassoc is success, return + /* wait for mc thread to cleanup and then return to upper stack + * so by the time upper layer calls the change interface, we are + * all set to proceed further */ - status = wlan_hdd_reassoc_bssid_hint(adapter, req); - if (!status) { - return status; + rc = wait_for_completion_timeout(&adapter->disconnect_comp_var, + msecs_to_jiffies(SME_DISCONNECT_TIMEOUT)); + if (!rc) { + hdd_err("Failed to disconnect, timed out"); + return -ETIMEDOUT; } - /* Try disconnecting if already in connected state */ - status = wlan_hdd_try_disconnect(adapter, - eSIR_MAC_UNSPEC_FAILURE_REASON); - if (0 > status) { - hdd_err("Failed to disconnect the existing connection"); - return -EALREADY; - } - - /*initialise security parameters */ - status = wlan_hdd_cfg80211_set_privacy(adapter, req); - - if (status < 0) { - hdd_err("Failed to set security params"); - return status; - } - - if (req->channel) - channel = req->channel->hw_value; - else - channel = 0; - - wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req); - - status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid, - req->ssid_len, req->bssid, - bssid_hint, channel, 0); - if (status) { - wlan_hdd_cfg80211_clear_privacy(adapter); - hdd_err("connect failed"); - } - hdd_exit(); - - return status; -} + hdd_exit(); + return 0; +} /** - * wlan_hdd_cfg80211_connect() - cfg80211 connect api + * wlan_hdd_cfg80211_leave_ibss() - leave ibss * @wiphy: Pointer to wiphy * @dev: Pointer to network device - * @req: Pointer to cfg80211 connect request + * + * This function is used to leave an IBSS network * * Return: 0 for success, non-zero for failure */ -static int wlan_hdd_cfg80211_connect(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_connect_params *req) +static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev) { int errno; struct osif_vdev_sync *vdev_sync; - errno = osif_vdev_sync_op_start(ndev, &vdev_sync); + errno = osif_vdev_sync_op_start(dev, &vdev_sync); if (errno) return errno; - errno = __wlan_hdd_cfg80211_connect(wiphy, ndev, req); + errno = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev); osif_vdev_sync_op_stop(vdev_sync); return errno; } - +#else /** - * hdd_ieee80211_reason_code_to_str() - return string conversion of reason code - * @reason: ieee80211 reason code. + * wlan_hdd_cfg80211_join_ibss() - join ibss + * @wiphy: Pointer to wiphy + * @dev: Pointer to network device + * @param: Pointer to IBSS join parameters * - * This utility function helps log string conversion of reason code. + * This function is dummy * - * Return: string conversion of reason code, if match found; - * "Unknown" otherwise. + * Return: 0 */ -static const char *hdd_ieee80211_reason_code_to_str(uint16_t reason) +static inline int +wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) { - switch (reason) { - CASE_RETURN_STRING(WLAN_REASON_UNSPECIFIED); - CASE_RETURN_STRING(WLAN_REASON_PREV_AUTH_NOT_VALID); - CASE_RETURN_STRING(WLAN_REASON_DEAUTH_LEAVING); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_AP_BUSY); - CASE_RETURN_STRING(WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); - CASE_RETURN_STRING(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_STA_HAS_LEFT); - CASE_RETURN_STRING(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_POWER); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_SUPP_CHAN); - CASE_RETURN_STRING(WLAN_REASON_INVALID_IE); - CASE_RETURN_STRING(WLAN_REASON_MIC_FAILURE); - CASE_RETURN_STRING(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); - CASE_RETURN_STRING(WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT); - CASE_RETURN_STRING(WLAN_REASON_IE_DIFFERENT); - CASE_RETURN_STRING(WLAN_REASON_INVALID_GROUP_CIPHER); - CASE_RETURN_STRING(WLAN_REASON_INVALID_PAIRWISE_CIPHER); - CASE_RETURN_STRING(WLAN_REASON_INVALID_AKMP); - CASE_RETURN_STRING(WLAN_REASON_UNSUPP_RSN_VERSION); - CASE_RETURN_STRING(WLAN_REASON_INVALID_RSN_IE_CAP); - CASE_RETURN_STRING(WLAN_REASON_IEEE8021X_FAILED); - CASE_RETURN_STRING(WLAN_REASON_CIPHER_SUITE_REJECTED); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_UNSPECIFIED_QOS); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_LOW_ACK); - CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP); - CASE_RETURN_STRING(WLAN_REASON_QSTA_LEAVE_QBSS); - CASE_RETURN_STRING(WLAN_REASON_QSTA_NOT_USE); - CASE_RETURN_STRING(WLAN_REASON_QSTA_REQUIRE_SETUP); - CASE_RETURN_STRING(WLAN_REASON_QSTA_TIMEOUT); - CASE_RETURN_STRING(WLAN_REASON_QSTA_CIPHER_NOT_SUPP); - CASE_RETURN_STRING(WLAN_REASON_MESH_PEER_CANCELED); - CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_PEERS); - CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIG); - CASE_RETURN_STRING(WLAN_REASON_MESH_CLOSE); - CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_RETRIES); - CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIRM_TIMEOUT); - CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_GTK); - CASE_RETURN_STRING(WLAN_REASON_MESH_INCONSISTENT_PARAM); - CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_SECURITY); - CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_ERROR); - CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_NOFORWARD); - CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE); - CASE_RETURN_STRING(WLAN_REASON_MAC_EXISTS_IN_MBSS); - CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN_REGULATORY); - CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN); - default: - return "Unknown"; - } + return 0; } /** - * hdd_qca_reason_to_str() - return string conversion of qca reason code - * @reason: enum qca_disconnect_reason_codes + * wlan_hdd_cfg80211_leave_ibss() - leave ibss + * @wiphy: Pointer to wiphy + * @dev: Pointer to network device * - * This utility function helps log string conversion of qca reason code. + * This function is dummy * - * Return: string conversion of reason code, if match found; - * "Unknown" otherwise. + * Return: 0 */ -static const char * -hdd_qca_reason_to_str(enum qca_disconnect_reason_codes reason) +static inline int +wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev) { - switch (reason) { - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_DEVICE_RECOVERY); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_KEY_TIMEOUT); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_IFACE_DOWN); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_INACTIVITY); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE); - CASE_RETURN_STRING(QCA_DISCONNECT_REASON_USER_TRIGGERED); - case QCA_DISCONNECT_REASON_UNSPECIFIED: - return ""; - default: - return "Unknown"; - } + return 0; } +#endif -/** - * wlan_hdd_sir_mac_to_qca_reason() - Convert to qca internal disconnect reason - * @internal_reason: Mac reason code of type @enum eSirMacReasonCodes - * - * Check if it is internal reason code and convert it to the - * enum qca_disconnect_reason_codes. - * - * Return: Reason code of type enum qca_disconnect_reason_codes - */ -static enum qca_disconnect_reason_codes -wlan_hdd_sir_mac_to_qca_reason(enum eSirMacReasonCodes internal_reason) +static void wlan_hdd_cfg80211_store_wep_key(struct hdd_adapter *adapter, + struct wlan_objmgr_vdev *vdev, + struct cfg80211_connect_params *req) { - enum qca_disconnect_reason_codes reason = - QCA_DISCONNECT_REASON_UNSPECIFIED; - switch (internal_reason) { - case eSIR_MAC_HOST_TRIGGERED_ROAM_FAILURE: - reason = QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE; - break; - case eSIR_MAC_FW_TRIGGERED_ROAM_FAILURE: - reason = QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE; - break; - case eSIR_MAC_GATEWAY_REACHABILITY_FAILURE: - reason = - QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE; - break; - case eSIR_MAC_UNSUPPORTED_CHANNEL_CSA: - reason = QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA; - break; - case eSIR_MAC_OPER_CHANNEL_DISABLED_INDOOR: - reason = - QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR; - break; - case eSIR_MAC_OPER_CHANNEL_USER_DISABLED: - reason = - QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED; - break; - case eSIR_MAC_DEVICE_RECOVERY: - reason = QCA_DISCONNECT_REASON_DEVICE_RECOVERY; - break; - case eSIR_MAC_KEY_TIMEOUT: - reason = QCA_DISCONNECT_REASON_KEY_TIMEOUT; - break; - case eSIR_MAC_OPER_CHANNEL_BAND_CHANGE: - reason = QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE; - break; - case eSIR_MAC_IFACE_DOWN: - reason = QCA_DISCONNECT_REASON_IFACE_DOWN; - break; - case eSIR_MAC_PEER_XRETRY_FAIL: - reason = QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL; - break; - case eSIR_MAC_PEER_INACTIVITY: - reason = QCA_DISCONNECT_REASON_PEER_INACTIVITY; - break; - case eSIR_MAC_SA_QUERY_TIMEOUT: - reason = QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT; - break; - case eSIR_MAC_CHANNEL_SWITCH_FAILED: - reason = QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE; - break; - case eSIR_MAC_BEACON_MISSED: - reason = QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE; - break; - case eSIR_MAC_USER_TRIGGERED_ROAM_FAILURE: - reason = QCA_DISCONNECT_REASON_USER_TRIGGERED; - break; - default: - hdd_debug("No QCA reason code for mac reason: %u", - internal_reason); - /* Unspecified reason by default */ - } + struct key_params params; - return reason; + qdf_mem_zero(¶ms, sizeof(params)); + params.cipher = req->crypto.ciphers_pairwise[0]; + params.key_len = req->key_len; + params.key = req->key; + wlan_cfg80211_store_key(vdev, req->key_idx, + WLAN_CRYPTO_KEY_TYPE_UNICAST, + NULL, ¶ms); } /** - * wlan_hdd_get_ieee80211_disconnect_reason() - Get ieee80211 disconnect reason - * @adapter: pointer to adapter structure - * @reason: Mac Disconnect reason code as per @enum eSirMacReasonCodes - * - * Reason codes that are greater than eSIR_MAC_REASON_PROP_START are internal - * reason codes. Convert them to qca reason code format and cache in adapter - * and return UNSPECIFIED. + * wlan_hdd_cfg80211_set_privacy() - set security parameters during connection + * @adapter: Pointer to adapter + * @req: Pointer to security parameters * - * Return: Reason code of type ieee80211_reasoncode. + * Return: 0 for success, non-zero for failure */ -static enum ieee80211_reasoncode -wlan_hdd_get_cfg80211_disconnect_reason(struct hdd_adapter *adapter, - enum eSirMacReasonCodes reason) +static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter, + struct cfg80211_connect_params *req) { - enum ieee80211_reasoncode ieee80211_reason = WLAN_REASON_UNSPECIFIED; + int status = 0; + struct hdd_station_ctx *sta_ctx; + struct csr_roam_profile *roam_profile; + struct wlan_objmgr_vdev *vdev; - /* - * Convert and cache internal reason code in adapter. This can be - * sent to userspace with a vendor event. - */ - if (reason >= eSIR_MAC_REASON_PROP_START) { - adapter->last_disconnect_reason = - wlan_hdd_sir_mac_to_qca_reason(reason); - /* - * Applications expect reason code as 0 for beacon miss failure - * due to backward compatibility. So send ieee80211_reason as 0. - */ - if (reason == eSIR_MAC_BEACON_MISSED) - ieee80211_reason = 0; - } else { - ieee80211_reason = (enum ieee80211_reasoncode)reason; - adapter->last_disconnect_reason = - QCA_DISCONNECT_REASON_UNSPECIFIED; + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + sta_ctx->wpa_versions = req->crypto.wpa_versions; + roam_profile = hdd_roam_profile(adapter); + + /* populate auth,akm and cipher params for crypto */ + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + hdd_populate_crypto_params(vdev, req); + + /*set authentication type */ + status = wlan_hdd_cfg80211_set_auth_type(adapter, req->auth_type); + + if (wlan_hdd_is_conn_type_fils(req)) { + status = wlan_hdd_cfg80211_set_fils_config(adapter, req); + + if (0 > status) { + hdd_err("Failed to set fils config"); + goto release_vdev_ref; + } } - return ieee80211_reason; -} + /*set key mgmt type */ + if (req->crypto.n_akm_suites) { + status = + wlan_hdd_set_akm_suite(adapter, req->crypto.akm_suites[0]); + if (0 > status) { + hdd_err("Failed to set akm suite"); + goto release_vdev_ref; + } + } -#if defined(CFG80211_DISCONNECTED_V2) || \ -(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) -void -wlan_hdd_cfg80211_indicate_disconnect(struct hdd_adapter *adapter, - bool locally_generated, - enum eSirMacReasonCodes reason, - uint8_t *disconnect_ies, - uint16_t disconnect_ies_len) -{ - enum ieee80211_reasoncode ieee80211_reason; + /*set pairwise cipher type */ + if (req->crypto.n_ciphers_pairwise) { + status = wlan_hdd_cfg80211_set_cipher(adapter, + req->crypto. + ciphers_pairwise[0], + true); + if (0 > status) { + hdd_err("Failed to set unicast cipher type"); + goto release_vdev_ref; + } + } else { + /*Reset previous cipher suite to none */ + status = wlan_hdd_cfg80211_set_cipher(adapter, 0, true); + if (0 > status) { + hdd_err("Failed to set unicast cipher type"); + goto release_vdev_ref; + } + } - ieee80211_reason = wlan_hdd_get_cfg80211_disconnect_reason(adapter, - reason); - hdd_nofl_info("Disconnect reason: %u %s vendor: %u %s LG: %u", - ieee80211_reason, - hdd_ieee80211_reason_code_to_str(ieee80211_reason), - adapter->last_disconnect_reason, - hdd_qca_reason_to_str(adapter->last_disconnect_reason), - locally_generated); - cfg80211_disconnected(adapter->dev, ieee80211_reason, disconnect_ies, - disconnect_ies_len, locally_generated, - GFP_KERNEL); -} -#else -void -wlan_hdd_cfg80211_indicate_disconnect(struct hdd_adapter *adapter, - bool locally_generated, - enum eSirMacReasonCodes reason, - uint8_t *disconnect_ies, - uint16_t disconnect_ies_len) -{ - enum ieee80211_reasoncode ieee80211_reason; + /*set group cipher type */ + status = + wlan_hdd_cfg80211_set_cipher(adapter, req->crypto.cipher_group, + false); - ieee80211_reason = wlan_hdd_get_cfg80211_disconnect_reason(adapter, - reason); - hdd_nofl_info("Disconnect reason: %u %s vendor: %u %s LG: %u", - ieee80211_reason, - hdd_ieee80211_reason_code_to_str(ieee80211_reason), - adapter->last_disconnect_reason, - hdd_qca_reason_to_str(adapter->last_disconnect_reason), - locally_generated); - cfg80211_disconnected(adapter->dev, ieee80211_reason, disconnect_ies, - disconnect_ies_len, GFP_KERNEL); -} + if (0 > status) { + hdd_err("Failed to set mcast cipher type"); + goto release_vdev_ref; + } +#ifdef WLAN_FEATURE_11W + roam_profile->MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED); #endif -int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason, - tSirMacReasonCodes mac_reason) -{ - int ret; - mac_handle_t mac_handle; + /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile */ + if (req->ie_len) { + status = + wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len); + if (0 > status) { + hdd_err("Failed to parse the WPA/RSN IE"); + goto release_vdev_ref; + } + } - mac_handle = hdd_adapter_get_mac_handle(adapter); - wlan_hdd_wait_for_roaming(mac_handle, adapter); + /*incase of WEP set default key information */ + if (req->key && req->key_len) { + u32 cipher = req->crypto.ciphers_pairwise[0]; - /*stop tx queues */ - hdd_debug("Disabling queues"); - wlan_hdd_netif_queue_control(adapter, - WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); + if ((WLAN_CIPHER_SUITE_WEP40 == cipher) || + (WLAN_CIPHER_SUITE_WEP104 == cipher)) { + enum hdd_auth_key_mgmt key_mgmt = + sta_ctx->auth_key_mgmt; - ret = wlan_hdd_wait_for_disconnect(mac_handle, adapter, reason, - mac_reason); + if (key_mgmt & HDD_AUTH_KEY_MGMT_802_1X) { + hdd_err("Dynamic WEP not supported"); + status = -EOPNOTSUPP; + goto release_vdev_ref; + } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) - /* Sending disconnect event to userspace for kernel version < 3.11 - * is handled by __cfg80211_disconnect call to __cfg80211_disconnected - */ - wlan_hdd_cfg80211_indicate_disconnect(adapter, true, - mac_reason, NULL, 0); -#endif + if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= + req->key_len) && (CSR_MAX_NUM_KEY > req->key_idx)) + wlan_hdd_cfg80211_store_wep_key(adapter, + vdev, req); + } + } +release_vdev_ref: + hdd_objmgr_put_vdev(vdev); - return ret; + return status; } /** - * __wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api - * @wiphy: Pointer to wiphy - * @dev: Pointer to network device - * @reason: Disconnect reason code + * wlan_hdd_clear_wapi_privacy() - reset WAPI settings in HDD layer + * @adapter: pointer to HDD adapter object * - * This function is used to issue a disconnect request to SME + * This function resets all WAPI related parameters imposed before STA + * connection starts. It's invoked when privacy checking against concurrency + * fails, to make sure no improper WAPI settings are still populated before + * returning an error to the upper layer requester. * - * Return: 0 for success, non-zero for failure + * Return: none */ -static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, - struct net_device *dev, u16 reason) +#ifdef FEATURE_WLAN_WAPI +static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter) { - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - int status; - struct hdd_station_ctx *sta_ctx = + adapter->wapi_info.wapi_mode = 0; + adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN; +} +#else +static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter) +{ +} +#endif + +/** + * wlan_hdd_cfg80211_clear_privacy() - reset STA security parameters + * @adapter: pointer to HDD adapter object + * + * This function resets all privacy related parameters imposed + * before STA connection starts. It's invoked when privacy checking + * against concurrency fails, to make sure no improper settings are + * still populated before returning an error to the upper layer requester. + * + * Return: none + */ +static void wlan_hdd_cfg80211_clear_privacy(struct hdd_adapter *adapter) +{ + struct hdd_station_ctx *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - struct wlan_objmgr_vdev *vdev; - bool enable_deauth_to_disassoc_map; - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); - return -EINVAL; - } + hdd_debug("resetting all privacy configurations"); - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) - return -EINVAL; + hdd_sta_ctx->wpa_versions = 0; - qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_DISCONNECT, - adapter->vdev_id, reason); + hdd_sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_NONE; + hdd_sta_ctx->roam_profile.AuthType.authType[0] = eCSR_AUTH_TYPE_NONE; - hdd_print_netdev_txq_status(dev); - status = wlan_hdd_validate_context(hdd_ctx); + hdd_sta_ctx->conn_info.uc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE; + hdd_sta_ctx->roam_profile.EncryptionType.numEntries = 0; + hdd_sta_ctx->conn_info.mc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE; + hdd_sta_ctx->roam_profile.mcEncryptionType.numEntries = 0; - if (0 != status) - return status; + wlan_hdd_clear_wapi_privacy(adapter); +} - qdf_mutex_acquire(&adapter->disconnection_status_lock); - if (adapter->disconnection_in_progress) { - qdf_mutex_release(&adapter->disconnection_status_lock); - hdd_debug("Disconnect is already in progress"); +static int wlan_hdd_wait_for_disconnect(mac_handle_t mac_handle, + struct hdd_adapter *adapter, + uint16_t reason, + tSirMacReasonCodes mac_reason) +{ + eConnectionState prev_conn_state; + struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + QDF_STATUS status = QDF_STATUS_SUCCESS; + int ret = 0; + unsigned long rc; + uint32_t wait_time = SME_DISCONNECT_TIMEOUT; + void *hif_ctx; + + /* Return if already disconnected */ + if (sta_ctx->conn_info.conn_state == eConnectionState_NotConnected || + sta_ctx->conn_info.conn_state == eConnectionState_IbssDisconnected) return 0; - } - adapter->disconnection_in_progress = true; - qdf_mutex_release(&adapter->disconnection_status_lock); - /* Issue disconnect request to SME, if station is in connected state */ - if ((sta_ctx->conn_info.conn_state == eConnectionState_Associated) || - (sta_ctx->conn_info.conn_state == eConnectionState_Connecting)) { - eCsrRoamDisconnectReason reasonCode = - eCSR_DISCONNECT_REASON_UNSPECIFIED; + /* If already in disconnecting state just wait for its completion */ + if (sta_ctx->conn_info.conn_state == eConnectionState_Disconnecting) + goto wait_for_disconnect; - switch (reason) { - case WLAN_REASON_MIC_FAILURE: - reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR; - break; + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + if (hif_ctx) { + /* + * Trigger runtime sync resume before sending disconneciton + */ + hif_pm_runtime_sync_resume(hif_ctx); + } - case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY: - case WLAN_REASON_DISASSOC_AP_BUSY: - case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: - reasonCode = eCSR_DISCONNECT_REASON_DISASSOC; - break; + INIT_COMPLETION(adapter->disconnect_comp_var); + prev_conn_state = sta_ctx->conn_info.conn_state; + hdd_conn_set_connection_state(adapter, eConnectionState_Disconnecting); - case WLAN_REASON_PREV_AUTH_NOT_VALID: - case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: - reasonCode = eCSR_DISCONNECT_REASON_DEAUTH; - break; + status = sme_roam_disconnect(mac_handle, adapter->vdev_id, reason, + mac_reason); + if (status == QDF_STATUS_CMD_NOT_QUEUED && + prev_conn_state == eConnectionState_Connecting) { + /* + * Wait here instead of returning directly, this will block the + * next connect command and allow processing of the scan for + * ssid and the previous connect command in CSR. + */ + hdd_debug("CSR not connected but scan for SSID is in progress, wait for scan to be aborted or completed."); + } else if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("SB Disconnect in progress/SME is disconencted/Connect removed from pending queue: status = %d", + status); + /* + * Wait here instead of returning directly. This will block the + * next connect command and allow processing of the disconnect + * in SME. As disconnect is already in progress, wait here for + * WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS instead of + * SME_DISCONNECT_TIMEOUT. + */ + wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS; + } - case WLAN_REASON_DEAUTH_LEAVING: - status = ucfg_mlme_get_enable_deauth_to_disassoc_map( - hdd_ctx->psoc, - &enable_deauth_to_disassoc_map); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; +wait_for_disconnect: + rc = wait_for_completion_timeout(&adapter->disconnect_comp_var, + msecs_to_jiffies(wait_time)); - reasonCode = - enable_deauth_to_disassoc_map ? - eCSR_DISCONNECT_REASON_STA_HAS_LEFT : - eCSR_DISCONNECT_REASON_DEAUTH; - qdf_dp_trace_dump_all( - WLAN_DEAUTH_DPTRACE_DUMP_COUNT, - QDF_TRACE_DEFAULT_PDEV_ID); - break; - case WLAN_REASON_DISASSOC_STA_HAS_LEFT: - reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT; - break; - default: - reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED; - break; - } + if (!rc && QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Disconnect timed out!!!"); + ret = -ETIMEDOUT; + } - vdev = hdd_objmgr_get_vdev(adapter); - if (!vdev) - return -EINVAL; - if (ucfg_scan_get_vdev_status(vdev) != - SCAN_NOT_IN_PROGRESS) - wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, - adapter->vdev_id, INVALID_SCAN_ID, - false); - wlan_hdd_cleanup_remain_on_channel_ctx(adapter); - /* First clean up the tdls peers if any */ - hdd_notify_sta_disconnect(adapter->vdev_id, - false, true, vdev); - hdd_objmgr_put_vdev(vdev); + hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected); - hdd_nofl_info("%s(vdevid-%d): Received Disconnect reason:%d %s", - dev->name, adapter->vdev_id, reason, - hdd_ieee80211_reason_code_to_str(reason)); - status = wlan_hdd_disconnect(adapter, reasonCode, reason); - if (0 != status) { - hdd_err("wlan_hdd_disconnect failed, status: %d", status); - hdd_set_disconnect_status(adapter, false); - return -EINVAL; + return ret; +} + +static void wlan_hdd_wait_for_roaming(mac_handle_t mac_handle, + struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx; + unsigned long rc; + struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + if (adapter->device_mode != QDF_STA_MODE) + return; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + /* Return if not in connected state */ + if (sta_ctx->conn_info.conn_state != eConnectionState_Associated) + return; + + sme_stop_roaming(mac_handle, adapter->vdev_id, + REASON_DRIVER_DISABLED, + RSO_INVALID_REQUESTOR); + /* + * If firmware has already started roaming process, driver + * needs to wait for processing of this disconnect request. + * + */ + INIT_COMPLETION(adapter->roaming_comp_var); + if (hdd_is_roaming_in_progress(hdd_ctx) || + sme_neighbor_middle_of_roaming(mac_handle, + adapter->vdev_id)) { + rc = wait_for_completion_timeout(&adapter->roaming_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM)); + if (!rc) { + hdd_err("roaming_comp_var time out vdev id: %d", + adapter->vdev_id); + /* Clear roaming in progress flag */ + hdd_set_roaming_in_progress(false); + } + if (adapter->roam_ho_fail) { + INIT_COMPLETION(adapter->disconnect_comp_var); + hdd_conn_set_connection_state(adapter, + eConnectionState_Disconnecting); } - } else { - hdd_err("Unexpected cfg disconnect called while in state: %d", - sta_ctx->conn_info.conn_state); - hdd_set_disconnect_status(adapter, false); } +} - return status; +int wlan_hdd_try_disconnect(struct hdd_adapter *adapter, + enum eSirMacReasonCodes reason) +{ + mac_handle_t mac_handle; + + mac_handle = hdd_adapter_get_mac_handle(adapter); + wlan_hdd_wait_for_roaming(mac_handle, adapter); + + return wlan_hdd_wait_for_disconnect(mac_handle, adapter, + eCSR_DISCONNECT_REASON_UNSPECIFIED, + reason); } /** - * wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api - * @wiphy: Pointer to wiphy - * @dev: Pointer to network device - * @reason: Disconnect reason code + * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present + * @adapter: Pointer to the HDD adapter + * @req: Pointer to the structure cfg_connect_params receieved from user space * - * Return: 0 for success, non-zero for failure + * This function will start reassociation if prev_bssid is set and bssid/ + * bssid_hint, channel/channel_hint parameters are present in connect request. + * + * Return: 0 if connect was for ReAssociation, non-zero error code otherwise */ -static int wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, - struct net_device *dev, u16 reason) +#if defined(CFG80211_CONNECT_PREV_BSSID) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) +static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter, + struct cfg80211_connect_params *req) { - int errno; - struct osif_vdev_sync *vdev_sync; + int status = -EINVAL; + const uint8_t *bssid = NULL; + uint32_t ch_freq = 0; + struct hdd_station_ctx *sta_ctx; - errno = osif_vdev_sync_op_start(dev, &vdev_sync); - if (errno) - return errno; + if (req->bssid) + bssid = req->bssid; + else if (req->bssid_hint) + bssid = req->bssid_hint; - errno = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason); + if (req->channel) + ch_freq = req->channel->center_freq; + else if (req->channel_hint) + ch_freq = req->channel_hint->center_freq; - osif_vdev_sync_op_stop(vdev_sync); + if (bssid && ch_freq && req->prev_bssid) { + hdd_debug("REASSOC Attempt on ch freq %d to " QDF_MAC_ADDR_FMT, + ch_freq, QDF_MAC_ADDR_REF(bssid)); + /* + * Save BSSID in a separate variable as + * roam_profile's BSSID is getting zeroed out in the + * association process. In case of join failure + * we should send valid BSSID to supplicant + */ + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + qdf_mem_copy(sta_ctx->requested_bssid.bytes, bssid, + QDF_MAC_ADDR_SIZE); - return errno; + hdd_set_roaming_in_progress(true); + + status = hdd_reassoc(adapter, bssid, ch_freq, + CONNECT_CMD_USERSPACE); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_set_roaming_in_progress(false); + hdd_debug("Failed with status: %d", status); + } + } + + return status; +} +#else +static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter, + struct cfg80211_connect_params *req) +{ + return -ENOTSUPP; } +#endif + /** - * wlan_hdd_cfg80211_set_privacy_ibss() - set ibss privacy - * @adapter: Pointer to adapter - * @param: Pointer to IBSS parameters + * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to + * connect in HT20 mode + * @hdd_ctx: hdd context + * @adapter: Pointer to the HDD adapter + * @req: Pointer to the structure cfg_connect_params receieved from user space * - * This function is used to initialize the security settings in IBSS mode + * This function will check if supplicant has indicated to to connect in HT20 + * mode. this is currently applicable only for 2.4Ghz mode only. + * if feature is enabled and supplicant indicate HT20 set + * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false. * - * Return: 0 for success, non-zero for failure + * Return: void */ -static int wlan_hdd_cfg80211_set_privacy_ibss(struct hdd_adapter *adapter, - struct cfg80211_ibss_params - *params) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) +static void +wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, + struct cfg80211_connect_params *req) { - uint32_t ret; - int status = 0; - eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); struct csr_roam_profile *roam_profile; + bool is_override_ht20_40_24g; - hdd_enter(); - - sta_ctx->wpa_versions = 0; - qdf_mem_zero(&sta_ctx->ibss_enc_key, sizeof(tCsrRoamSetKey)); - sta_ctx->ibss_enc_key_installed = 0; + roam_profile = hdd_roam_profile(adapter); - if (params->ie_len && (params->ie)) { - if (wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, params->ie, - params->ie_len)) { - sta_ctx->wpa_versions = NL80211_WPA_VERSION_2; - encryptionType = eCSR_ENCRYPT_TYPE_AES; - } else if (hdd_is_wpaie_present(params->ie, params->ie_len)) { - tDot11fIEWPA dot11_wpa_ie; - mac_handle_t mac_handle = - hdd_adapter_get_mac_handle(adapter); - const u8 *ie; + roam_profile->force_24ghz_in_ht20 = false; - memset(&dot11_wpa_ie, 0, sizeof(dot11_wpa_ie)); - ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WPA, - params->ie, params->ie_len); - if (ie) { - sta_ctx->wpa_versions = NL80211_WPA_VERSION_1; - /* Unpack the WPA IE - * Skip past the EID byte and length byte - * and four byte WiFi OUI - */ - if (ie[1] < DOT11F_IE_WPA_MIN_LEN || - ie[1] > DOT11F_IE_WPA_MAX_LEN) { - hdd_err("invalid ie len:%d", ie[1]); - return -EINVAL; - } - ret = dot11f_unpack_ie_wpa( - MAC_CONTEXT(mac_handle), - (uint8_t *)&ie[2 + 4], - ie[1] - 4, &dot11_wpa_ie, false); - if (DOT11F_FAILED(ret)) { - hdd_err("unpack failed ret: 0x%x", ret); - return -EINVAL; - } - /* - * Extract the multicast cipher, the - * encType for unicast cipher for - * wpa-none is none - */ - encryptionType = - hdd_translate_wpa_to_csr_encryption_type - (dot11_wpa_ie.multicast_cipher); - } - } - - status = - wlan_hdd_cfg80211_set_ie(adapter, params->ie, - params->ie_len); + ucfg_mlme_is_override_ht20_40_24g(hdd_ctx->psoc, + &is_override_ht20_40_24g); + if (is_override_ht20_40_24g && + !(req->ht_capa.cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + roam_profile->force_24ghz_in_ht20 = true; - if (0 > status) { - hdd_err("Failed to parse WPA/RSN IE"); - return status; - } - } + if (is_override_ht20_40_24g) + hdd_nofl_debug("HT cap %x", req->ht_capa.cap_info); +} +#else +static inline void +wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, + struct cfg80211_connect_params *req) +{ + struct csr_roam_profile *roam_profile; roam_profile = hdd_roam_profile(adapter); - roam_profile->AuthType.authType[0] = - sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; - if (params->privacy) { - /* Security enabled IBSS, At this time there is no information - * available about the security parameters, so initialise the - * encryption type to eCSR_ENCRYPT_TYPE_WEP40_STATICKEY. - * The correct security parameters will be updated later in - * wlan_hdd_cfg80211_add_key Hal expects encryption type to be - * set inorder enable privacy bit in beacons - */ + roam_profile->force_24ghz_in_ht20 = false; +} +#endif - encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; - } - hdd_debug("encryptionType=%d", encryptionType); - sta_ctx->conn_info.uc_encrypt_type = encryptionType; - roam_profile->EncryptionType.numEntries = 1; - roam_profile->EncryptionType.encryptionType[0] = - encryptionType; - return status; +static inline void hdd_dump_connect_req(struct hdd_adapter *adapter, + struct net_device *ndev, + struct cfg80211_connect_params *req) +{ + uint32_t i; + + hdd_nofl_debug("cfg80211_connect req for %s(vdevid-%d): mode %d freq %d SSID %.*s auth type %d WPA ver %d n_akm %d n_cipher %d grp_cipher %x mfp %d freq hint %d", + ndev->name, adapter->vdev_id, adapter->device_mode, + req->channel ? req->channel->center_freq : 0, + (int)req->ssid_len, req->ssid, req->auth_type, + req->crypto.wpa_versions, + req->crypto.n_akm_suites, req->crypto.n_ciphers_pairwise, + req->crypto.cipher_group, req->mfp, + req->channel_hint ? req->channel_hint->center_freq : 0); + if (req->bssid) + hdd_nofl_debug("BSSID "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(req->bssid)); + if (req->bssid_hint) + hdd_nofl_debug("BSSID hint "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(req->bssid_hint)); + if (req->prev_bssid) + hdd_nofl_debug("prev BSSID "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(req->prev_bssid)); + + for (i = 0; i < req->crypto.n_akm_suites; i++) + hdd_nofl_debug("akm[%d] = %x", i, req->crypto.akm_suites[i]); + + for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) + hdd_nofl_debug("cipher_pairwise[%d] = %x", i, + req->crypto.ciphers_pairwise[i]); } /** - * __wlan_hdd_cfg80211_join_ibss() - join ibss + * __wlan_hdd_cfg80211_connect() - cfg80211 connect api * @wiphy: Pointer to wiphy * @dev: Pointer to network device - * @param: Pointer to IBSS join parameters + * @req: Pointer to cfg80211 connect request * - * This function is used to create/join an IBSS network + * This function is used to start the association process * * Return: 0 for success, non-zero for failure */ -static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_ibss_params *params) +static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req) { - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - struct csr_roam_profile *roam_profile; int status; - struct hdd_station_ctx *sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - struct qdf_mac_addr bssid; - u8 channelNum = 0; - mac_handle_t mac_handle; - struct wlan_mlme_ibss_cfg ibss_cfg = {0}; + uint32_t ch_freq, sap_cnt, sta_cnt; + const u8 *bssid = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + const u8 *bssid_hint = req->bssid_hint; +#else + const u8 *bssid_hint = NULL; +#endif + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); + struct hdd_context *hdd_ctx; + uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS], i; + bool disable_nan = true; + uint32_t ch_freq_hint = 0; hdd_enter(); @@ -20746,195 +21167,477 @@ static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, return -EINVAL; qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + TRACE_CODE_HDD_CFG80211_CONNECT, adapter->vdev_id, adapter->device_mode); + if (adapter->device_mode != QDF_STA_MODE && + adapter->device_mode != QDF_P2P_CLIENT_MODE) { + hdd_err("Device_mode %s(%d) is not supported", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + return -EINVAL; + } + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("HDD context is null"); + return -EINVAL; + } + status = wlan_hdd_validate_context(hdd_ctx); if (0 != status) return status; - if (QDF_IS_STATUS_ERROR(ucfg_mlme_get_ibss_cfg(hdd_ctx->psoc, - &ibss_cfg))) { + if (req->bssid) + bssid = req->bssid; + else if (bssid_hint) + bssid = bssid_hint; + + if (bssid && hdd_get_adapter_by_macaddr(hdd_ctx, (uint8_t *)bssid)) { + hdd_err("adapter exist with same mac address " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid)); return -EINVAL; } - mac_handle = hdd_ctx->mac_handle; - if (NULL != - params->chandef.chan) { - uint32_t numChans = CFG_VALID_CHANNEL_LIST_LEN; - uint8_t validChan[CFG_VALID_CHANNEL_LIST_LEN]; - int indx; + hdd_dump_connect_req(adapter, ndev, req); - /* Get channel number */ - channelNum = ieee80211_frequency_to_channel( - params-> - chandef. - chan-> - center_freq); - ucfg_mlme_get_valid_channel_list(hdd_ctx->psoc, validChan, - &numChans); + /* + * Disable NAN Discovery if incoming connection is P2P or if a STA + * connection already exists and if this is a case of STA+STA + * or SAP+STA concurrency + */ + sta_cnt = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, NULL, + vdev_id_list, + PM_STA_MODE); + sap_cnt = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, NULL, + &vdev_id_list[sta_cnt], + PM_SAP_MODE); - for (indx = 0; indx < numChans; indx++) { - if (channelNum == validChan[indx]) - break; - } - if (indx >= numChans) { - hdd_err("Not valid Channel: %d", channelNum); - return -EINVAL; + if (adapter->device_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) { + for (i = 0; i < sta_cnt + sap_cnt; i++) + if (vdev_id_list[i] == adapter->vdev_id) + disable_nan = false; + if (disable_nan) { + hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P: %d", + sap_cnt, sta_cnt, + (adapter->device_mode == QDF_P2P_CLIENT_MODE)); + ucfg_nan_disable_concurrency(hdd_ctx->psoc); } } + /* + * STA+NDI concurrency gets preference over NDI+NDI. Disable + * first NDI in case an NDI+NDI concurrency exists if FW does + * not support 4 port concurrency of two NDI + NAN with STA. + */ + if (!ucfg_nan_is_sta_nan_ndi_4_port_allowed(hdd_ctx->psoc)) + ucfg_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc, + false); - /* Disable NAN Discovery if enabled */ - ucfg_nan_disable_concurrency(hdd_ctx->psoc); - - if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, - PM_IBSS_MODE, channelNum, HW_MODE_20_MHZ)) { - hdd_err("This concurrency combination is not allowed"); - return -ECONNREFUSED; - } - - status = policy_mgr_reset_connection_update(hdd_ctx->psoc); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("qdf_reset_connection_update failed status: %d", status); - - status = policy_mgr_current_connections_update(hdd_ctx->psoc, - adapter->vdev_id, channelNum, - POLICY_MGR_UPDATE_REASON_JOIN_IBSS); - if (QDF_STATUS_E_FAILURE == status) { - hdd_err("connections update failed!!"); - return -EINVAL; + /* + * In STA + STA roaming scenario, connection to same ssid but different + * bssid is allowed on both vdevs. So there could be a race where the + * STA1 connectes to a bssid when roaming is in progress on STA2 for + * the same bssid. Here the firwmare would have already created peer for + * the roam candidate and host would have created peer on the other + * vdev. When roam synch indication is received, then peer create fails + * at host for the roaming vdev due to duplicate peer detection logic. + * Still roam synch confirm is sent to the firmware. + * When disconnection is received for STA1, then del bss is sent for + * this vdev and firmware asserts as the peer was not created for this + * vdev. + */ + if (hdd_is_roaming_in_progress(hdd_ctx) || + sme_is_any_session_in_middle_of_roaming(hdd_ctx->mac_handle)) { + hdd_err("Roaming in progress. Defer connect"); + return -EBUSY; } - if (QDF_STATUS_SUCCESS == status) { - status = policy_mgr_wait_for_connection_update( - hdd_ctx->psoc); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("qdf wait for event failed!!"); - return -EINVAL; - } - } + /* + * Check if this is reassoc to same bssid, if reassoc is success, return + */ + status = wlan_hdd_reassoc_bssid_hint(adapter, req); + if (!status) + return status; - /*Try disconnecting if already in connected state */ + /* Try disconnecting if already in connected state */ status = wlan_hdd_try_disconnect(adapter, eSIR_MAC_UNSPEC_FAILURE_REASON); if (0 > status) { - hdd_err("Failed to disconnect the existing IBSS connection"); + hdd_err("Failed to disconnect the existing connection"); return -EALREADY; } - roam_profile = hdd_roam_profile(adapter); + /*initialise security parameters */ + status = wlan_hdd_cfg80211_set_privacy(adapter, req); + if (status < 0) { + hdd_err("Failed to set security params"); + return status; + } - if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) { - hdd_err("Interface type is not set to IBSS"); - return -EINVAL; + if (req->channel) + ch_freq = req->channel->center_freq; + else + ch_freq = 0; + + if (req->channel_hint) + ch_freq_hint = req->channel_hint->center_freq; + + wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req); + + status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid, + req->ssid_len, req->bssid, + bssid_hint, ch_freq, 0, + ch_freq_hint); + if (status) { + wlan_hdd_cfg80211_clear_privacy(adapter); + hdd_err("connect failed"); } - /* enable selected protection checks in IBSS mode */ - roam_profile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK; + hdd_exit(); - /* BSSID is provided by upper layers hence no need to AUTO generate */ - if (params->bssid) { - if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0) - == QDF_STATUS_E_FAILURE) { - hdd_err("Unable to update MLME IBSS Auto BSSID config"); - return -EIO; - } - qdf_mem_copy(bssid.bytes, params->bssid, QDF_MAC_ADDR_SIZE); - } else if (ibss_cfg.coalesing_enable == 0) { - if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0) - == QDF_STATUS_E_FAILURE) { - hdd_err("Unable to update MLME IBSS Auto BSSID config"); - return -EIO; - } - qdf_copy_macaddr(&bssid, &ibss_cfg.bssid); + return status; +} + +/** + * wlan_hdd_cfg80211_connect() - cfg80211 connect api + * @wiphy: Pointer to wiphy + * @dev: Pointer to network device + * @req: Pointer to cfg80211 connect request + * + * Return: 0 for success, non-zero for failure + */ +static int wlan_hdd_cfg80211_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(ndev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_connect(wiphy, ndev, req); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + +/** + * hdd_ieee80211_reason_code_to_str() - return string conversion of reason code + * @reason: ieee80211 reason code. + * + * This utility function helps log string conversion of reason code. + * + * Return: string conversion of reason code, if match found; + * "Unknown" otherwise. + */ +static const char *hdd_ieee80211_reason_code_to_str(uint16_t reason) +{ + switch (reason) { + CASE_RETURN_STRING(WLAN_REASON_UNSPECIFIED); + CASE_RETURN_STRING(WLAN_REASON_PREV_AUTH_NOT_VALID); + CASE_RETURN_STRING(WLAN_REASON_DEAUTH_LEAVING); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_AP_BUSY); + CASE_RETURN_STRING(WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); + CASE_RETURN_STRING(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_STA_HAS_LEFT); + CASE_RETURN_STRING(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_POWER); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_SUPP_CHAN); + CASE_RETURN_STRING(WLAN_REASON_INVALID_IE); + CASE_RETURN_STRING(WLAN_REASON_MIC_FAILURE); + CASE_RETURN_STRING(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); + CASE_RETURN_STRING(WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT); + CASE_RETURN_STRING(WLAN_REASON_IE_DIFFERENT); + CASE_RETURN_STRING(WLAN_REASON_INVALID_GROUP_CIPHER); + CASE_RETURN_STRING(WLAN_REASON_INVALID_PAIRWISE_CIPHER); + CASE_RETURN_STRING(WLAN_REASON_INVALID_AKMP); + CASE_RETURN_STRING(WLAN_REASON_UNSUPP_RSN_VERSION); + CASE_RETURN_STRING(WLAN_REASON_INVALID_RSN_IE_CAP); + CASE_RETURN_STRING(WLAN_REASON_IEEE8021X_FAILED); + CASE_RETURN_STRING(WLAN_REASON_CIPHER_SUITE_REJECTED); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_UNSPECIFIED_QOS); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_LOW_ACK); + CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP); + CASE_RETURN_STRING(WLAN_REASON_QSTA_LEAVE_QBSS); + CASE_RETURN_STRING(WLAN_REASON_QSTA_NOT_USE); + CASE_RETURN_STRING(WLAN_REASON_QSTA_REQUIRE_SETUP); + CASE_RETURN_STRING(WLAN_REASON_QSTA_TIMEOUT); + CASE_RETURN_STRING(WLAN_REASON_QSTA_CIPHER_NOT_SUPP); + CASE_RETURN_STRING(WLAN_REASON_MESH_PEER_CANCELED); + CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_PEERS); + CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIG); + CASE_RETURN_STRING(WLAN_REASON_MESH_CLOSE); + CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_RETRIES); + CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIRM_TIMEOUT); + CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_GTK); + CASE_RETURN_STRING(WLAN_REASON_MESH_INCONSISTENT_PARAM); + CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_SECURITY); + CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_ERROR); + CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_NOFORWARD); + CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE); + CASE_RETURN_STRING(WLAN_REASON_MAC_EXISTS_IN_MBSS); + CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN_REGULATORY); + CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN); + default: + return "Unknown"; + } +} + +/** + * hdd_qca_reason_to_str() - return string conversion of qca reason code + * @reason: enum qca_disconnect_reason_codes + * + * This utility function helps log string conversion of qca reason code. + * + * Return: string conversion of reason code, if match found; + * "Unknown" otherwise. + */ +static const char * +hdd_qca_reason_to_str(enum qca_disconnect_reason_codes reason) +{ + switch (reason) { + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_DEVICE_RECOVERY); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_KEY_TIMEOUT); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_IFACE_DOWN); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_PEER_INACTIVITY); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE); + CASE_RETURN_STRING(QCA_DISCONNECT_REASON_USER_TRIGGERED); + case QCA_DISCONNECT_REASON_UNSPECIFIED: + return ""; + default: + return "Unknown"; + } +} + +/** + * wlan_hdd_sir_mac_to_qca_reason() - Convert to qca internal disconnect reason + * @internal_reason: Mac reason code of type @enum eSirMacReasonCodes + * + * Check if it is internal reason code and convert it to the + * enum qca_disconnect_reason_codes. + * + * Return: Reason code of type enum qca_disconnect_reason_codes + */ +static enum qca_disconnect_reason_codes +wlan_hdd_sir_mac_to_qca_reason(enum eSirMacReasonCodes internal_reason) +{ + enum qca_disconnect_reason_codes reason = + QCA_DISCONNECT_REASON_UNSPECIFIED; + switch (internal_reason) { + case eSIR_MAC_HOST_TRIGGERED_ROAM_FAILURE: + reason = QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE; + break; + case eSIR_MAC_FW_TRIGGERED_ROAM_FAILURE: + reason = QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE; + break; + case eSIR_MAC_GATEWAY_REACHABILITY_FAILURE: + reason = + QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE; + break; + case eSIR_MAC_UNSUPPORTED_CHANNEL_CSA: + reason = QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA; + break; + case eSIR_MAC_OPER_CHANNEL_DISABLED_INDOOR: + reason = + QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR; + break; + case eSIR_MAC_OPER_CHANNEL_USER_DISABLED: + reason = + QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED; + break; + case eSIR_MAC_DEVICE_RECOVERY: + reason = QCA_DISCONNECT_REASON_DEVICE_RECOVERY; + break; + case eSIR_MAC_KEY_TIMEOUT: + reason = QCA_DISCONNECT_REASON_KEY_TIMEOUT; + break; + case eSIR_MAC_OPER_CHANNEL_BAND_CHANGE: + reason = QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE; + break; + case eSIR_MAC_IFACE_DOWN: + reason = QCA_DISCONNECT_REASON_IFACE_DOWN; + break; + case eSIR_MAC_PEER_XRETRY_FAIL: + reason = QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL; + break; + case eSIR_MAC_PEER_INACTIVITY: + reason = QCA_DISCONNECT_REASON_PEER_INACTIVITY; + break; + case eSIR_MAC_SA_QUERY_TIMEOUT: + reason = QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT; + break; + case eSIR_MAC_CHANNEL_SWITCH_FAILED: + reason = QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE; + break; + case eSIR_MAC_BEACON_MISSED: + reason = QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE; + break; + case eSIR_MAC_USER_TRIGGERED_ROAM_FAILURE: + reason = QCA_DISCONNECT_REASON_USER_TRIGGERED; + break; + default: + hdd_debug("No QCA reason code for mac reason: %u", + internal_reason); + /* Unspecified reason by default */ } - if (cfg_in_range(CFG_BEACON_INTERVAL, params->beacon_interval)) - roam_profile->beaconInterval = params->beacon_interval; - else - roam_profile->beaconInterval = cfg_get(hdd_ctx->psoc, - CFG_BEACON_INTERVAL); + return reason; +} - /* Set Channel */ - if (channelNum) { - /* Set the Operational Channel */ - hdd_debug("set channel %d", channelNum); - roam_profile->ChannelInfo.numOfChannels = 1; - sta_ctx->conn_info.channel = channelNum; - roam_profile->ChannelInfo.ChannelList = - &sta_ctx->conn_info.channel; - } +/** + * wlan_hdd_get_ieee80211_disconnect_reason() - Get ieee80211 disconnect reason + * @adapter: pointer to adapter structure + * @reason: Mac Disconnect reason code as per @enum eSirMacReasonCodes + * + * Reason codes that are greater than eSIR_MAC_REASON_PROP_START are internal + * reason codes. Convert them to qca reason code format and cache in adapter + * and return UNSPECIFIED. + * Rest of the reason codes are valid ieee80211 reason codes. + * + * Return: Reason code of type ieee80211_reasoncode. + */ +static enum ieee80211_reasoncode +wlan_hdd_get_cfg80211_disconnect_reason(struct hdd_adapter *adapter, + enum eSirMacReasonCodes reason) +{ + enum ieee80211_reasoncode ieee80211_reason = WLAN_REASON_UNSPECIFIED; - /* Initialize security parameters */ - status = wlan_hdd_cfg80211_set_privacy_ibss(adapter, params); - if (status < 0) { - hdd_err("failed to set security parameters"); - return status; + /* + * Convert and cache internal reason code in adapter. This can be + * sent to userspace with a vendor event. + */ + if (reason >= eSIR_MAC_REASON_PROP_START) { + adapter->last_disconnect_reason = + wlan_hdd_sir_mac_to_qca_reason(reason); + /* + * Applications expect reason code as 0 for beacon miss failure + * due to backward compatibility. So send ieee80211_reason as 0. + */ + if (reason == eSIR_MAC_BEACON_MISSED) + ieee80211_reason = 0; + } else { + ieee80211_reason = (enum ieee80211_reasoncode)reason; + adapter->last_disconnect_reason = + QCA_DISCONNECT_REASON_UNSPECIFIED; } - /* Issue connect start */ - status = wlan_hdd_cfg80211_connect_start(adapter, params->ssid, - params->ssid_len, - bssid.bytes, NULL, - sta_ctx->conn_info. - channel, - params->chandef.width); + return ieee80211_reason; +} - if (0 > status) { - hdd_err("connect failed"); - return status; - } - hdd_exit(); - return 0; +#if defined(CFG80211_DISCONNECTED_V2) || \ +(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) +void +wlan_hdd_cfg80211_indicate_disconnect(struct hdd_adapter *adapter, + bool locally_generated, + enum eSirMacReasonCodes reason, + uint8_t *disconnect_ies, + uint16_t disconnect_ies_len) +{ + enum ieee80211_reasoncode ieee80211_reason; + + ieee80211_reason = wlan_hdd_get_cfg80211_disconnect_reason(adapter, + reason); + hdd_nofl_info("Disconnect reason: %u %s vendor: %u %s LG: %u", + ieee80211_reason, + hdd_ieee80211_reason_code_to_str(ieee80211_reason), + adapter->last_disconnect_reason, + hdd_qca_reason_to_str(adapter->last_disconnect_reason), + locally_generated); + cfg80211_disconnected(adapter->dev, ieee80211_reason, disconnect_ies, + disconnect_ies_len, locally_generated, + GFP_KERNEL); +} +#else +void +wlan_hdd_cfg80211_indicate_disconnect(struct hdd_adapter *adapter, + bool locally_generated, + enum eSirMacReasonCodes reason, + uint8_t *disconnect_ies, + uint16_t disconnect_ies_len) +{ + enum ieee80211_reasoncode ieee80211_reason; + + ieee80211_reason = wlan_hdd_get_cfg80211_disconnect_reason(adapter, + reason); + hdd_nofl_info("Disconnect reason: %u %s vendor: %u %s LG: %u", + ieee80211_reason, + hdd_ieee80211_reason_code_to_str(ieee80211_reason), + adapter->last_disconnect_reason, + hdd_qca_reason_to_str(adapter->last_disconnect_reason), + locally_generated); + cfg80211_disconnected(adapter->dev, ieee80211_reason, disconnect_ies, + disconnect_ies_len, GFP_KERNEL); } +#endif -/** - * wlan_hdd_cfg80211_join_ibss() - join ibss - * @wiphy: Pointer to wiphy - * @dev: Pointer to network device - * @param: Pointer to IBSS join parameters - * - * This function is used to create/join an IBSS network - * - * Return: 0 for success, non-zero for failure - */ -static int wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_ibss_params *params) +int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason, + tSirMacReasonCodes mac_reason) { - int errno; - struct osif_vdev_sync *vdev_sync; + int ret; + mac_handle_t mac_handle; - errno = osif_vdev_sync_op_start(dev, &vdev_sync); - if (errno) - return errno; + mac_handle = hdd_adapter_get_mac_handle(adapter); + wlan_hdd_wait_for_roaming(mac_handle, adapter); - errno = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params); + /*stop tx queues */ + hdd_debug("Disabling queues"); + wlan_hdd_netif_queue_control(adapter, + WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); - osif_vdev_sync_op_stop(vdev_sync); + /* Disable STA power-save mode */ + if ((adapter->device_mode == QDF_STA_MODE) && + wlan_hdd_set_powersave(adapter, false, 0)) + hdd_debug("Not disable PS for STA"); - return errno; + ret = wlan_hdd_wait_for_disconnect(mac_handle, adapter, reason, + mac_reason); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) + /* Sending disconnect event to userspace for kernel version < 3.11 + * is handled by __cfg80211_disconnect call to __cfg80211_disconnected + */ + wlan_hdd_cfg80211_indicate_disconnect(adapter, true, + mac_reason, NULL, 0); +#endif + + return ret; } /** - * __wlan_hdd_cfg80211_leave_ibss() - leave ibss + * __wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api * @wiphy: Pointer to wiphy * @dev: Pointer to network device + * @reason: Disconnect reason code * - * This function is used to leave an IBSS network + * This function is used to issue a disconnect request to SME * * Return: 0 for success, non-zero for failure */ -static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, - struct net_device *dev) +static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, u16 reason) { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - struct csr_roam_profile *roam_profile; - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); int status; - mac_handle_t mac_handle; - unsigned long rc; - tSirUpdateIE update_ie; + struct hdd_station_ctx *sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; + bool enable_deauth_to_disassoc_map; if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); @@ -20945,79 +21648,111 @@ static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, return -EINVAL; qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, - adapter->vdev_id, eCSR_DISCONNECT_REASON_IBSS_LEAVE); + TRACE_CODE_HDD_CFG80211_DISCONNECT, + adapter->vdev_id, reason); + hdd_print_netdev_txq_status(dev); status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) return status; - hdd_debug("Device_mode %s(%d)", - qdf_opmode_str(adapter->device_mode), adapter->device_mode); + qdf_mutex_acquire(&adapter->disconnection_status_lock); + if (adapter->disconnection_in_progress) { + qdf_mutex_release(&adapter->disconnection_status_lock); + hdd_debug("Disconnect is already in progress"); + return 0; + } + adapter->disconnection_in_progress = true; + qdf_mutex_release(&adapter->disconnection_status_lock); - roam_profile = hdd_roam_profile(adapter); + /* Issue disconnect request to SME, if station is in connected state */ + if ((sta_ctx->conn_info.conn_state == eConnectionState_Associated) || + (sta_ctx->conn_info.conn_state == eConnectionState_Connecting)) { + eCsrRoamDisconnectReason reasonCode = + eCSR_DISCONNECT_REASON_UNSPECIFIED; - /* Issue disconnect only if interface type is set to IBSS */ - if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) { - hdd_err("BSS Type is not set to IBSS"); - return -EINVAL; - } - /* Clearing add IE of beacon */ - qdf_mem_copy(update_ie.bssid.bytes, adapter->mac_addr.bytes, - sizeof(tSirMacAddr)); - update_ie.smeSessionId = adapter->vdev_id; - update_ie.ieBufferlength = 0; - update_ie.pAdditionIEBuffer = NULL; - update_ie.append = true; - update_ie.notify = true; - mac_handle = hdd_ctx->mac_handle; - if (sme_update_add_ie(mac_handle, - &update_ie, - eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) { - hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); - } + switch (reason) { + case WLAN_REASON_MIC_FAILURE: + reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR; + break; - /* Reset WNI_CFG_PROBE_RSP Flags */ - wlan_hdd_reset_prob_rspies(adapter); + case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY: + case WLAN_REASON_DISASSOC_AP_BUSY: + case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: + reasonCode = eCSR_DISCONNECT_REASON_DISASSOC; + break; + + case WLAN_REASON_PREV_AUTH_NOT_VALID: + case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + reasonCode = eCSR_DISCONNECT_REASON_DEAUTH; + break; + + case WLAN_REASON_DEAUTH_LEAVING: + status = ucfg_mlme_get_enable_deauth_to_disassoc_map( + hdd_ctx->psoc, + &enable_deauth_to_disassoc_map); + if (QDF_IS_STATUS_ERROR(status)) + return -EINVAL; + + reasonCode = + enable_deauth_to_disassoc_map ? + eCSR_DISCONNECT_REASON_STA_HAS_LEFT : + eCSR_DISCONNECT_REASON_DEAUTH; + qdf_dp_trace_dump_all( + WLAN_DEAUTH_DPTRACE_DUMP_COUNT, + QDF_TRACE_DEFAULT_PDEV_ID); + break; + case WLAN_REASON_DISASSOC_STA_HAS_LEFT: + reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT; + break; + default: + reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED; + break; + } + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + if (ucfg_scan_get_vdev_status(vdev) != SCAN_NOT_IN_PROGRESS) + wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, + adapter->vdev_id, INVALID_SCAN_ID, + false); - /* Issue Disconnect request */ - INIT_COMPLETION(adapter->disconnect_comp_var); - status = sme_roam_disconnect(mac_handle, - adapter->vdev_id, - eCSR_DISCONNECT_REASON_IBSS_LEAVE, - eSIR_MAC_UNSPEC_FAILURE_REASON); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("sme_roam_disconnect failed status: %d", - status); - return -EAGAIN; - } + wlan_hdd_cleanup_remain_on_channel_ctx(adapter); + /* First clean up the tdls peers if any */ + hdd_notify_sta_disconnect(adapter->vdev_id, + false, true, vdev); + hdd_objmgr_put_vdev(vdev); - /* wait for mc thread to cleanup and then return to upper stack - * so by the time upper layer calls the change interface, we are - * all set to proceed further - */ - rc = wait_for_completion_timeout(&adapter->disconnect_comp_var, - msecs_to_jiffies(SME_DISCONNECT_TIMEOUT)); - if (!rc) { - hdd_err("Failed to disconnect, timed out"); - return -ETIMEDOUT; + hdd_nofl_info("%s(vdevid-%d): Received Disconnect reason:%d %s", + dev->name, adapter->vdev_id, reason, + hdd_ieee80211_reason_code_to_str(reason)); + status = wlan_hdd_disconnect(adapter, reasonCode, reason); + if (0 != status) { + hdd_err("wlan_hdd_disconnect failed, status: %d", status); + hdd_set_disconnect_status(adapter, false); + return -EINVAL; + } + } else { + hdd_err("Unexpected cfg disconnect called while in state: %d", + sta_ctx->conn_info.conn_state); + hdd_set_disconnect_status(adapter, false); } - hdd_exit(); - return 0; + return status; } /** - * wlan_hdd_cfg80211_leave_ibss() - leave ibss + * wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api * @wiphy: Pointer to wiphy * @dev: Pointer to network device - * - * This function is used to leave an IBSS network + * @reason: Disconnect reason code * * Return: 0 for success, non-zero for failure */ -static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, - struct net_device *dev) +static int wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, u16 reason) { int errno; struct osif_vdev_sync *vdev_sync; @@ -21026,7 +21761,7 @@ static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, if (errno) return errno; - errno = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev); + errno = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason); osif_vdev_sync_op_stop(vdev_sync); @@ -21181,7 +21916,20 @@ static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy, } /** - * __wlan_hdd_set_txq_params() - dummy implementation of set tx queue params + * Default val of cwmin, this value is used to overide the + * incorrect user set value + */ +#define DEFAULT_CWMIN 15 + +/** + * Default val of cwmax, this value is used to overide the + * incorrect user set value + */ +#define DEFAULT_CWMAX 1023 + +/** + * __wlan_hdd_set_txq_params() - implementation of set tx queue params + * to configure internal EDCA parameters * @wiphy: Pointer to wiphy * @dev: Pointer to network device * @params: Pointer to tx queue parameters @@ -21192,8 +21940,44 @@ static int __wlan_hdd_set_txq_params(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_txq_params *params) { + QDF_STATUS status; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + mac_handle_t mac_handle; + tSirMacEdcaParamRecord txq_edca_params; + static const uint8_t ieee_ac_to_qca_ac[] = { + [IEEE80211_AC_VO] = QCA_WLAN_AC_VO, + [IEEE80211_AC_VI] = QCA_WLAN_AC_VI, + [IEEE80211_AC_BE] = QCA_WLAN_AC_BE, + [IEEE80211_AC_BK] = QCA_WLAN_AC_BK, + }; + hdd_enter(); - return 0; + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + mac_handle = hdd_ctx->mac_handle; + if (params->cwmin == 0 || params->cwmin > DEFAULT_CWMAX) + params->cwmin = DEFAULT_CWMIN; + + if (params->cwmax < params->cwmin || params->cwmax > DEFAULT_CWMAX) + params->cwmax = DEFAULT_CWMAX; + + txq_edca_params.cw.min = convert_cw(params->cwmin); + txq_edca_params.cw.max = convert_cw(params->cwmax); + txq_edca_params.aci.aifsn = params->aifs; + /* The txop is multiple of 32us units */ + txq_edca_params.txoplimit = params->txop; + txq_edca_params.aci.aci = + ieee_ac_to_qca_ac[params->ac]; + + status = sme_update_session_txq_edca_params(mac_handle, + adapter->vdev_id, + &txq_edca_params); + + hdd_exit(); + return qdf_status_to_os_return(status); } /** @@ -21222,6 +22006,120 @@ static int wlan_hdd_set_txq_params(struct wiphy *wiphy, return errno; } +/** + * hdd_softap_deauth_current_sta() - Deauth current sta + * @sta_info: pointer to the current station info structure + * @adapter: pointer to adapter structure + * @hdd_ctx: pointer to hdd context + * @hapd_state: pointer to hostapd state structure + * @param: pointer to del sta params + * + * Return: QDF_STATUS on success, corresponding QDF failure status on failure + */ +static +QDF_STATUS hdd_softap_deauth_current_sta(struct hdd_adapter *adapter, + struct hdd_station_info *sta_info, + struct hdd_hostapd_state *hapd_state, + struct csr_del_sta_params *param) +{ + qdf_event_t *disassoc_event = &hapd_state->qdf_sta_disassoc_event; + struct hdd_context *hdd_ctx; + QDF_STATUS qdf_status; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("hdd_ctx is NULL"); + return QDF_STATUS_E_INVAL; + } + + qdf_event_reset(&hapd_state->qdf_sta_disassoc_event); + + if (!qdf_is_macaddr_broadcast(¶m->peerMacAddr)) + sme_send_disassoc_req_frame(hdd_ctx->mac_handle, + adapter->vdev_id, + (uint8_t *)¶m->peerMacAddr, + param->reason_code, 0); + + qdf_status = hdd_softap_sta_deauth(adapter, param); + + if (QDF_IS_STATUS_SUCCESS(qdf_status)) { + sta_info->is_deauth_in_progress = true; + qdf_status = qdf_wait_for_event_completion( + disassoc_event, + SME_PEER_DISCONNECT_TIMEOUT); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + hdd_warn("Deauth time expired"); + } else { + sta_info->is_deauth_in_progress = false; + hdd_debug("STA removal failed for ::" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); + return QDF_STATUS_E_NOENT; + } + return QDF_STATUS_SUCCESS; +} + +/** + * hdd_softap_deauth_all_sta() - Deauth all sta in the sta list + * @hdd_ctx: pointer to hdd context + * @adapter: pointer to adapter structure + * @hapd_state: pointer to hostapd state structure + * @param: pointer to del sta params + * + * Return: QDF_STATUS on success, corresponding QDF failure status on failure + */ +static +QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter, + struct hdd_hostapd_state *hapd_state, + struct csr_del_sta_params *param) +{ + QDF_STATUS status; + bool is_sap_bcast_deauth_enabled = false; + struct hdd_context *hdd_ctx; + struct hdd_station_info *sta_info, *tmp = NULL; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("hdd_ctx is NULL"); + return QDF_STATUS_E_INVAL; + } + + ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc, + &is_sap_bcast_deauth_enabled); + + if (is_sap_bcast_deauth_enabled) + return QDF_STATUS_E_INVAL; + + hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, + STA_INFO_SOFTAP_DEAUTH_ALL_STA) { + if (!sta_info->is_deauth_in_progress) { + hdd_debug("Delete STA with MAC:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); + qdf_mem_copy(param->peerMacAddr.bytes, + sta_info->sta_mac.bytes, + QDF_MAC_ADDR_SIZE); + status = + hdd_softap_deauth_current_sta(adapter, sta_info, + hapd_state, param); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &sta_info, true, + STA_INFO_SOFTAP_DEAUTH_ALL_STA); + if (tmp) + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &tmp, true, + STA_INFO_SOFTAP_DEAUTH_ALL_STA); + return status; + } + } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_DEAUTH_ALL_STA); + } + + return QDF_STATUS_SUCCESS; +} + /** * __wlan_hdd_cfg80211_del_station() - delete station v2 * @wiphy: Pointer to wiphy @@ -21237,11 +22135,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx; - QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; struct hdd_hostapd_state *hapd_state; - uint8_t sta_id; uint8_t *mac; mac_handle_t mac_handle; + struct hdd_station_info *sta_info; hdd_enter(); @@ -21266,123 +22163,54 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, mac = (uint8_t *) param->peerMacAddr.bytes; mac_handle = hdd_ctx->mac_handle; - if ((QDF_SAP_MODE == adapter->device_mode) || - (QDF_P2P_GO_MODE == adapter->device_mode)) { - - hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); - if (!hapd_state) { - hdd_err("Hostapd State is Null"); - return 0; - } + if (QDF_SAP_MODE != adapter->device_mode && + QDF_P2P_GO_MODE != adapter->device_mode) + goto fn_end; - if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *) mac)) { - uint16_t i; + hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + if (!hapd_state) { + hdd_err("Hostapd State is Null"); + return 0; + } - bool is_sap_bcast_deauth_enabled = false; + if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac)) { + if (!QDF_IS_STATUS_SUCCESS(hdd_softap_deauth_all_sta(adapter, + hapd_state, + param))) + goto fn_end; + } else { + if (param->reason_code == eSIR_MAC_1X_AUTH_FAILURE_REASON) + hdd_softap_check_wait_for_tx_eap_pkt( + adapter, (struct qdf_mac_addr *)mac); - ucfg_mlme_is_sap_bcast_deauth_enabled( - hdd_ctx->psoc, - &is_sap_bcast_deauth_enabled); - hdd_debug("is_sap_bcast_deauth_enabled %d", - is_sap_bcast_deauth_enabled); - - if (is_sap_bcast_deauth_enabled) - goto fn_end; - - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - if ((adapter->sta_info[i].in_use) && - (!adapter->sta_info[i]. - is_deauth_in_progress)) { - qdf_mem_copy( + sta_info = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, mac, - adapter->sta_info[i]. - sta_mac.bytes, - QDF_MAC_ADDR_SIZE); - - hdd_debug("Delete STA with MAC::" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); - - if (hdd_ctx->dev_dfs_cac_status == - DFS_CAC_IN_PROGRESS) - goto fn_end; - - qdf_event_reset(&hapd_state->qdf_sta_disassoc_event); - qdf_status = - hdd_softap_sta_deauth(adapter, - param); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) { - adapter->sta_info[i]. - is_deauth_in_progress = true; - qdf_status = - qdf_wait_for_event_completion( - &hapd_state-> - qdf_sta_disassoc_event, - SME_PEER_DISCONNECT_TIMEOUT); - if (!QDF_IS_STATUS_SUCCESS( - qdf_status)) - hdd_warn("Deauth wait time expired"); - } - } - } - } else { - qdf_status = - hdd_softap_get_sta_id(adapter, - (struct qdf_mac_addr *) mac, - &sta_id); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - hdd_debug("Skip DEL STA as this is not used::" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); - return -ENOENT; - } + STA_INFO_CFG80211_DEL_STATION); - if (adapter->sta_info[sta_id].is_deauth_in_progress == - true) { - hdd_debug("Skip DEL STA as deauth is in progress::" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); - return -ENOENT; - } - - adapter->sta_info[sta_id].is_deauth_in_progress = true; - - hdd_debug("ucast, Delete STA with MAC:" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); - - /* Case: SAP in ACS selected DFS ch and client connected - * Now Radar detected. Then if random channel is another - * DFS ch then new CAC is initiated and no TX allowed. - * So do not send any mgmt frames as it will timeout - * during CAC. - */ - - if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) - goto fn_end; - - qdf_event_reset(&hapd_state->qdf_sta_disassoc_event); - sme_send_disassoc_req_frame(mac_handle, - adapter->vdev_id, - (uint8_t *)¶m->peerMacAddr, - param->reason_code, 0); - qdf_status = hdd_softap_sta_deauth(adapter, - param); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - adapter->sta_info[sta_id].is_deauth_in_progress = - false; - hdd_debug("STA removal failed for ::" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); - return -ENOENT; - } - qdf_status = qdf_wait_for_event_completion( - &hapd_state-> - qdf_sta_disassoc_event, - SME_PEER_DISCONNECT_TIMEOUT); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) - hdd_warn("Deauth wait time expired"); + if (!sta_info) { + hdd_debug("Skip DEL STA as this is not used::" + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); + return -ENOENT; + } + if (sta_info->is_deauth_in_progress) { + hdd_debug("Skip DEL STA as deauth is in progress::" + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, + true, + STA_INFO_CFG80211_DEL_STATION); + return -ENOENT; } + + hdd_debug("ucast, Delete STA with MAC:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); + hdd_softap_deauth_current_sta(adapter, sta_info, hapd_state, + param); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_CFG80211_DEL_STATION); } fn_end: @@ -21521,8 +22349,8 @@ static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, set = params->sta_flags_set; - hdd_debug("mask 0x%x set 0x%x " QDF_MAC_ADDR_STR, mask, set, - QDF_MAC_ADDR_ARRAY(mac)); + hdd_debug("mask 0x%x set 0x%x " QDF_MAC_ADDR_FMT, mask, set, + QDF_MAC_ADDR_REF(mac)); if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { @@ -21574,13 +22402,24 @@ static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, return errno; } -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, tPmkidCacheInfo *pmk_cache) { QDF_STATUS result; struct wlan_crypto_pmksa *pmksa; struct wlan_objmgr_vdev *vdev; + mac_handle_t mac_handle; + struct hdd_context *hdd_ctx; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("HDD context is null"); + return QDF_STATUS_E_INVAL; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return QDF_STATUS_E_INVAL; + mac_handle = hdd_ctx->mac_handle; vdev = hdd_objmgr_get_vdev(adapter); if (!vdev) @@ -21591,7 +22430,15 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, hdd_objmgr_put_vdev(vdev); return QDF_STATUS_E_NOMEM; } - qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID); + + if (!pmk_cache->ssid_len) { + qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID); + } else { + qdf_mem_copy(pmksa->ssid, pmk_cache->ssid, pmk_cache->ssid_len); + qdf_mem_copy(pmksa->cache_id, pmk_cache->cache_id, + WLAN_CACHE_ID_LEN); + pmksa->ssid_len = pmk_cache->ssid_len; + } qdf_mem_copy(pmksa->pmkid, pmk_cache->PMKID, PMKID_LEN); qdf_mem_copy(pmksa->pmk, pmk_cache->pmk, pmk_cache->pmk_len); pmksa->pmk_len = pmk_cache->pmk_len; @@ -21601,6 +22448,11 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, qdf_mem_zero(pmksa, sizeof(*pmksa)); qdf_mem_free(pmksa); } + + if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len) + sme_roam_set_psk_pmk(mac_handle, adapter->vdev_id, + pmk_cache->pmk, pmk_cache->pmk_len, + false); hdd_objmgr_put_vdev(vdev); return result; @@ -21638,34 +22490,6 @@ QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter) return result; } -#else -static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, - tPmkidCacheInfo *pmk_cache) -{ - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - return sme_roam_set_pmkid_cache( - hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache, 1, false); -} - -static QDF_STATUS wlan_hdd_del_pmksa_cache(struct hdd_adapter *adapter, - tPmkidCacheInfo *pmk_cache) -{ - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - return sme_roam_del_pmkid_from_cache( - hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache, - false); -} - -QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter) -{ - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - return sme_roam_del_pmkid_from_cache( - hdd_ctx->mac_handle, adapter->vdev_id, NULL, true); -} -#endif #if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) @@ -21678,11 +22502,9 @@ QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter) static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa) { if (!pmksa->bssid) { - hdd_warn("bssid (%pK) is NULL", - pmksa->bssid); + hdd_warn("bssid is NULL"); if (!pmksa->ssid || !pmksa->cache_id) { - hdd_err("either ssid (%pK) or cache_id (%pK) are NULL", - pmksa->ssid, pmksa->cache_id); + hdd_err("either ssid or cache_id are NULL"); return false; } } @@ -21702,9 +22524,9 @@ static void hdd_fill_pmksa_info(struct hdd_adapter *adapter, struct cfg80211_pmksa *pmksa, bool is_delete) { if (pmksa->bssid) { - hdd_debug("%s PMKSA for " QDF_MAC_ADDR_STR, + hdd_debug("%s PMKSA for " QDF_MAC_ADDR_FMT, is_delete ? "Delete" : "Set", - QDF_MAC_ADDR_ARRAY(pmksa->bssid)); + QDF_MAC_ADDR_REF(pmksa->bssid)); qdf_mem_copy(pmk_cache->BSSID.bytes, pmksa->bssid, QDF_MAC_ADDR_SIZE); } else { @@ -21760,8 +22582,8 @@ static void hdd_fill_pmksa_info(struct hdd_adapter *adapter, { mac_handle_t mac_handle; - hdd_debug("%s PMKSA for " QDF_MAC_ADDR_STR, is_delete ? "Delete" : "Set", - QDF_MAC_ADDR_ARRAY(pmksa->bssid)); + hdd_debug("%s PMKSA for " QDF_MAC_ADDR_FMT, is_delete ? "Delete" : "Set", + QDF_MAC_ADDR_REF(pmksa->bssid)); qdf_mem_copy(pmk_cache->BSSID.bytes, pmksa->bssid, QDF_MAC_ADDR_SIZE); @@ -21842,7 +22664,8 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, sme_set_del_pmkid_cache(hdd_ctx->psoc, adapter->vdev_id, pmk_cache, true); - qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); + qdf_mem_zero(pmk_cache, sizeof(pmk_cache)); + qdf_mem_free(pmk_cache); hdd_exit(); @@ -21915,28 +22738,37 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, if (0 != status) return status; - qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_DEL_PMKSA, - adapter->vdev_id, 0); - pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); if (!pmk_cache) return -ENOMEM; + qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DEL_PMKSA, + adapter->vdev_id, 0); + hdd_fill_pmksa_info(adapter, pmk_cache, pmksa, true); + /* clear single_pmk_info information */ + sme_clear_sae_single_pmk_info(hdd_ctx->psoc, adapter->vdev_id, + pmk_cache); + /* Delete the PMKID CSR cache */ if (QDF_STATUS_SUCCESS != wlan_hdd_del_pmksa_cache(adapter, pmk_cache)) { - hdd_err("Failed to delete PMKSA for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pmksa->bssid)); + if (!pmksa->bssid) + hdd_err("Failed to delete PMKSA for null bssid"); + else + hdd_err("Failed to delete PMKSA for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pmksa->bssid)); status = -EINVAL; } sme_set_del_pmkid_cache(hdd_ctx->psoc, adapter->vdev_id, pmk_cache, false); + qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); qdf_mem_free(pmk_cache); + hdd_exit(); return status; @@ -22002,7 +22834,9 @@ static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, return errno; status = wlan_hdd_flush_pmksa_cache(adapter); - if (QDF_IS_STATUS_ERROR(status)) { + if (status == QDF_STATUS_E_NOSUPPORT) { + errno = -EOPNOTSUPP; + } else if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Cannot flush PMKIDCache"); errno = -EINVAL; } @@ -22229,7 +23063,8 @@ void wlan_hdd_cfg80211_update_replay_counter_cb( for (i = 0; i < 8; i++) temp_replay_counter[7 - i] = (uint8_t) p[i]; - hdd_debug("gtk_rsp_param bssid %pM", gtk_rsp_param->bssid.bytes); + hdd_debug("gtk_rsp_param bssid "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(gtk_rsp_param->bssid.bytes)); /* Update replay counter to NL */ cfg80211_gtk_rekey_notify(adapter->dev, gtk_rsp_param->bssid.bytes, @@ -22459,8 +23294,8 @@ static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, config->num_accept_mac = params->n_acl_entries; for (i = 0; i < params->n_acl_entries; i++) { hdd_debug("** Add ACL MAC entry %i in WhiletList :" - QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF( params->mac_addrs[i].addr)); qdf_mem_copy(&config->accept_mac[i], @@ -22471,8 +23306,8 @@ static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, config->num_deny_mac = params->n_acl_entries; for (i = 0; i < params->n_acl_entries; i++) { hdd_debug("** Add ACL MAC entry %i in BlackList :" - QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF( params->mac_addrs[i].addr)); qdf_mem_copy(&config->deny_mac[i], @@ -22824,8 +23659,6 @@ static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx; - uint8_t channel; - uint16_t freq; int ret; enum phy_ch_width ch_width; @@ -22847,15 +23680,61 @@ static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy, wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id, CSA_REASON_USER_INITIATED); - freq = csa_params->chandef.chan->center_freq; - channel = cds_freq_to_chan(freq); - ch_width = hdd_map_nl_chan_width(csa_params->chandef.width); - ret = hdd_softap_set_channel_change(dev, channel, ch_width, false); + ret = + hdd_softap_set_channel_change(dev, + csa_params->chandef.chan->center_freq, + ch_width, false); return ret; } +enum qca_wlan_802_11_mode +hdd_convert_cfgdot11mode_to_80211mode(enum csr_cfgdot11mode mode) +{ + switch (mode) { + case eCSR_CFG_DOT11_MODE_11A: + return QCA_WLAN_802_11_MODE_11A; + case eCSR_CFG_DOT11_MODE_11B: + return QCA_WLAN_802_11_MODE_11B; + case eCSR_CFG_DOT11_MODE_11G: + return QCA_WLAN_802_11_MODE_11G; + case eCSR_CFG_DOT11_MODE_11N: + return QCA_WLAN_802_11_MODE_11N; + case eCSR_CFG_DOT11_MODE_11AC: + return QCA_WLAN_802_11_MODE_11AC; + case eCSR_CFG_DOT11_MODE_11G_ONLY: + return QCA_WLAN_802_11_MODE_11G; + case eCSR_CFG_DOT11_MODE_11N_ONLY: + return QCA_WLAN_802_11_MODE_11N; + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + return QCA_WLAN_802_11_MODE_11AC; + case eCSR_CFG_DOT11_MODE_11AX: + return QCA_WLAN_802_11_MODE_11AX; + case eCSR_CFG_DOT11_MODE_11AX_ONLY: + return QCA_WLAN_802_11_MODE_11AX; + case eCSR_CFG_DOT11_MODE_ABG: + case eCSR_CFG_DOT11_MODE_AUTO: + default: + return QCA_WLAN_802_11_MODE_INVALID; + } +} + +bool hdd_is_legacy_connection(struct hdd_adapter *adapter) +{ + struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + int connection_mode; + + connection_mode = hdd_convert_cfgdot11mode_to_80211mode( + sta_ctx->conn_info.dot11mode); + if (connection_mode == QCA_WLAN_802_11_MODE_11A || + connection_mode == QCA_WLAN_802_11_MODE_11B || + connection_mode == QCA_WLAN_802_11_MODE_11G) + return true; + else + return false; +} + /** * wlan_hdd_cfg80211_channel_switch()- function to switch * channel in SAP/GO @@ -22887,8 +23766,8 @@ static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy, #endif int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter, - uint8_t channel, - enum policy_mgr_conn_update_reason reason) + uint32_t chan_freq, + enum policy_mgr_conn_update_reason reason) { QDF_STATUS status; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -22899,8 +23778,9 @@ int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter, if (!QDF_IS_STATUS_SUCCESS(status)) hdd_err("clearing event failed"); - status = policy_mgr_current_connections_update(hdd_ctx->psoc, - adapter->vdev_id, channel, reason); + status = policy_mgr_current_connections_update( + hdd_ctx->psoc, adapter->vdev_id, + chan_freq, reason); switch (status) { case QDF_STATUS_E_FAILURE: /* @@ -22922,7 +23802,7 @@ int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter, return -EINVAL; } if (QDF_MONITOR_MODE == adapter->device_mode) - hdd_info("Monitor mode:channel:%d (SMM->DBS)", channel); + hdd_info("Monitor mode:channel freq:%d (SMM->DBS)", chan_freq); break; default: @@ -22961,9 +23841,8 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, struct qdf_mac_addr bssid; struct csr_roam_profile roam_profile; struct ch_params ch_params; - uint8_t sec_ch = 0; int ret; - uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq); + enum channel_state chan_freq_state; uint8_t max_fw_bw; enum phy_ch_width ch_width; @@ -22979,24 +23858,28 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, if (!adapter) return -EIO; - hdd_debug("%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; - 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 = hdd_map_nl_chan_width(chandef->width); - hdd_select_cbmode(adapter, chan_num, &roam_profile.ch_params); + hdd_debug("%s: set monitor mode freq %d", + adapter->dev->name, chandef->chan->center_freq); - qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, - QDF_MAC_ADDR_SIZE); + /* Verify channel state before accepting this request */ + chan_freq_state = + wlan_reg_get_channel_state_for_freq(hdd_ctx->pdev, + chandef->chan->center_freq); + if (chan_freq_state == CHANNEL_STATE_DISABLE || + chan_freq_state == CHANNEL_STATE_INVALID) { + hdd_err("Invalid chan freq received for monitor mode aborting"); + return -EINVAL; + } - ch_params.ch_width = hdd_map_nl_chan_width(chandef->width); /* Verify the BW before accepting this request */ ch_width = hdd_map_nl_chan_width(chandef->width); + if (ch_width > CH_WIDTH_10MHZ || + (!cds_is_sub_20_mhz_enabled() && ch_width > CH_WIDTH_160MHZ)) { + hdd_err("invalid BW received %d", ch_width); + return -EINVAL; + } + max_fw_bw = sme_get_vht_ch_width(); if ((ch_width == CH_WIDTH_160MHZ && @@ -23007,22 +23890,26 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, ch_width, max_fw_bw); return -EINVAL; } + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + ch_info = &sta_ctx->ch_info; + roam_profile.ChannelInfo.freq_list = &ch_info->freq; + roam_profile.ChannelInfo.numOfChannels = 1; + roam_profile.phyMode = ch_info->phy_mode; + roam_profile.ch_params.ch_width = ch_width; + hdd_select_cbmode(adapter, chandef->chan->center_freq, + &roam_profile.ch_params); - /* - * CDS api expects secondary channel for calculating - * the channel params - */ - if ((ch_params.ch_width == CH_WIDTH_40MHZ) && - (WLAN_REG_IS_24GHZ_CH(chan_num))) { - if (chan_num >= 1 && chan_num <= 5) - sec_ch = chan_num + 4; - else if (chan_num >= 6 && chan_num <= 13) - sec_ch = chan_num - 4; - } - wlan_reg_set_channel_params(hdd_ctx->pdev, chan_num, - sec_ch, &ch_params); - if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan_num, - POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { + qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, + QDF_MAC_ADDR_SIZE); + + ch_params.ch_width = ch_width; + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, + chandef->chan->center_freq, + 0, &ch_params); + + if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, + chandef->chan->center_freq, + POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { hdd_err("Failed to change hw mode"); return -EINVAL; } @@ -23039,11 +23926,12 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, } adapter->monitor_mode_vdev_up_in_progress = true; - status = sme_roam_channel_change_req(mac_handle, bssid, &ch_params, + status = sme_roam_channel_change_req(mac_handle, bssid, + &roam_profile.ch_params, &roam_profile); if (status) { - hdd_err("Failed to set sme_RoamChannel for monitor mode status: %d", - status); + hdd_err_rl("Failed to set sme_RoamChannel for monitor mode status: %d", + status); adapter->monitor_mode_vdev_up_in_progress = false; ret = qdf_status_to_os_return(status); return ret; @@ -23152,7 +24040,8 @@ static void hdd_update_chan_info(struct hdd_context *hdd_ctx, #endif #if defined(WLAN_FEATURE_FILS_SK) &&\ - defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) &&\ + (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) ||\ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) &&\ (defined(CFG80211_UPDATE_CONNECT_PARAMS) ||\ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))) @@ -23386,7 +24275,8 @@ wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy, #endif #if defined(WLAN_FEATURE_SAE) && \ - defined(CFG80211_EXTERNAL_AUTH_SUPPORT) + (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) #if defined(CFG80211_EXTERNAL_AUTH_AP_SUPPORT) /** * wlan_hdd_extauth_cache_pmkid() - Extract and cache pmkid @@ -23404,10 +24294,11 @@ wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter, { tPmkidCacheInfo *pmk_cache; QDF_STATUS result; + if (params->pmkid) { pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); if (!pmk_cache) - return; + return; qdf_mem_copy(pmk_cache->BSSID.bytes, params->bssid, QDF_MAC_ADDR_SIZE); @@ -23419,6 +24310,7 @@ wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter, qdf_mem_free(pmk_cache); } + } /** @@ -23489,8 +24381,8 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, if (ret) return ret; - hdd_debug("external_auth status: %d peer mac: " QDF_MAC_ADDR_STR, - params->status, QDF_MAC_ADDR_ARRAY(params->bssid)); + hdd_debug("external_auth status: %d peer mac: " QDF_MAC_ADDR_FMT, + params->status, QDF_MAC_ADDR_REF(params->bssid)); mac_handle = hdd_ctx->mac_handle; qdf_mem_copy(peer_mac_addr.bytes, params->bssid, QDF_MAC_ADDR_SIZE); @@ -23630,7 +24522,7 @@ void wlan_hdd_init_chan_info(struct hdd_context *hdd_ctx) hdd_ctx->chan_info = qdf_mem_malloc(sizeof(struct scan_chan_info) - * QDF_MAX_NUM_CHAN); + * NUM_CHANNELS); if (!hdd_ctx->chan_info) return; mutex_init(&hdd_ctx->chan_info_lock); @@ -23889,7 +24781,8 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { .update_connect_params = wlan_hdd_cfg80211_update_connect_params, #endif #if defined(WLAN_FEATURE_SAE) && \ - defined(CFG80211_EXTERNAL_AUTH_SUPPORT) + (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) .external_auth = wlan_hdd_cfg80211_external_auth, #endif #if defined(WLAN_FEATURE_NAN) && \ @@ -23900,4 +24793,5 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { .del_nan_func = wlan_hdd_cfg80211_del_nan_func, .nan_change_conf = wlan_hdd_cfg80211_nan_change_conf, #endif + }; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.h index 7687778d2e900b5f4aee00164a6df49a14a4ff91..0841113ce35bcb2db840eb219344c6e1a7e8c93f 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -125,12 +125,20 @@ struct hdd_context; #if !defined(TDLS_MGMT_VERSION2) #define TDLS_MGMT_VERSION2 0 #endif - #endif +/** + * hdd_convert_cfgdot11mode_to_80211mode() - Function to convert cfg dot11 mode + * to 80211 mode + * @mode: cfg dot11 mode + * + * Return: 80211 mode + */ +enum qca_wlan_802_11_mode +hdd_convert_cfgdot11mode_to_80211mode(enum csr_cfgdot11mode mode); + #define HDD_SET_BIT(__param, __val) ((__param) |= (1 << (__val))) -#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS) #define MAX_SCAN_SSID 10 #define IS_CHANNEL_VALID(channel) ((channel >= 0 && channel < 15) \ @@ -314,9 +322,9 @@ void hdd_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); QDF_STATUS wlan_hdd_validate_operation_channel(struct hdd_adapter *adapter, - int channel); + uint32_t ch_freq); -void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel, +void hdd_select_cbmode(struct hdd_adapter *adapter, uint32_t oper_freq, struct ch_params *ch_params); /** @@ -357,11 +365,14 @@ int wlan_hdd_send_avoid_freq_event(struct hdd_context *hdd_ctx, * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace * @hdd_ctx: Pointer to hdd context * @reason: cds recovery reason + * @data: Hang Data + * @data_len: Hang Data len * * Return: 0 on success or failure reason */ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, - uint32_t reason); + uint32_t reason, uint8_t *data, + size_t data_len); int wlan_hdd_send_avoid_freq_for_dnbs(struct hdd_context *hdd_ctx, uint8_t op_chan); @@ -431,7 +442,18 @@ void hdd_send_roam_scan_ch_list_event(struct hdd_context *hdd_ctx, #endif int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter); -int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint8_t channel); + +/** + * wlan_hdd_request_pre_cac() - Start pre CAC in the driver + * @hdd_ctx: the HDD context to operate against + * @chan_freq: channel freq option provided by userspace + * + * Sets the driver to the required hardware mode and start an adapter for + * pre CAC which will mimic an AP. + * + * Return: Zero on success, non-zero value on error + */ +int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint32_t chan_freq); int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter); int wlan_hdd_enable_dfs_chan_scan(struct hdd_context *hdd_ctx, @@ -490,7 +512,7 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, /** * wlan_hdd_change_hw_mode_for_given_chnl() - change HW mode for given channel * @adapter: pointer to adapter - * @channel: given channel number + * @chan_freq: given channel frequency * @reason: reason for HW mode change is needed * * This API decides and sets hardware mode to DBS based on given channel. @@ -500,8 +522,8 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter, * Return: 0 for success and non-zero for failure */ int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter, - uint8_t channel, - enum policy_mgr_conn_update_reason reason); + uint32_t chan_freq, + enum policy_mgr_conn_update_reason reason); /** * hdd_rate_info_bw: an HDD internal rate bandwidth representation @@ -562,17 +584,6 @@ int wlan_hdd_try_disconnect(struct hdd_adapter *adapter, int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason, tSirMacReasonCodes mac_reason); -/** - * hdd_update_cca_info_cb() - stores congestion value in station context - * @hdd_handle: HDD handle - * @congestion: congestion - * @vdev_id: vdev id - * - * Return: None - */ -void hdd_update_cca_info_cb(hdd_handle_t hdd_handle, uint32_t congestion, - uint32_t vdev_id); - /** * wlan_hdd_get_adjacent_chan(): Gets next/previous channel * to the channel passed. @@ -654,12 +665,10 @@ int wlan_hdd_send_mode_change_event(void); * wlan_hdd_restore_channels() - Restore the channels which were cached * and disabled in wlan_hdd_disable_channels api. * @hdd_ctx: Pointer to the HDD context - * @notify_sap_event: Indicates if SAP event needs to be notified * * Return: 0 on success, Error code on failure */ -int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx, - bool notify_sap_event); +int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx); /** * hdd_store_sar_config() - Store SAR config in HDD context @@ -700,4 +709,26 @@ QDF_STATUS wlan_hdd_send_sta_authorized_event( struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, const struct qdf_mac_addr *mac_addr); + +/** + * hdd_is_legacy_connection() - Is adapter connection is legacy + * @adapter: Handle to hdd_adapter + * + * Return: true if connection mode is legacy, false otherwise. + */ +bool hdd_is_legacy_connection(struct hdd_adapter *adapter); + +/** + * hdd_set_dynamic_antenna_mode() - set dynamic antenna mode + * @adapter: Pointer to network adapter + * @num_rx_chains: number of chains to be used for receiving data + * @num_tx_chains: number of chains to be used for transmitting data + * + * This function will set dynamic antenna mode + * + * Return: 0 for success + */ +int hdd_set_dynamic_antenna_mode(struct hdd_adapter *adapter, + uint8_t num_rx_chains, + uint8_t num_tx_chains); #endif diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfr.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfr.c new file mode 100644 index 0000000000000000000000000000000000000000..4d8bc5c65f544fa28eab38cc9c7fd98fa97640d5 --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfr.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_cfr.c + * + * WLAN Host Device Driver CFR capture Implementation + */ + +#include +#include +#include +#include +#include "wlan_hdd_includes.h" +#include "osif_sync.h" +#include "wlan_hdd_cfr.h" +#include "wlan_cfr_ucfg_api.h" + +const struct nla_policy cfr_config_policy[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR] = { + .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE] = {.type = NLA_FLAG}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE] = { + .type = NLA_FLAG}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK] = {.type = NLA_U64}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA] = { + .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA] = { + .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK] = { + .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK] = { + .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER] = { + .type = NLA_U32}, +}; + +static QDF_STATUS +wlan_cfg80211_cfr_set_group_config(struct wlan_objmgr_vdev *vdev, + struct nlattr *tb[]) +{ + struct cfr_wlanconfig_param params = { 0 }; + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER]) { + params.grp_id = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER]); + hdd_debug("group_id %d", params.grp_id); + } + + if (params.grp_id >= HDD_INVALID_GROUP_ID) { + hdd_err("invalid group id"); + return QDF_STATUS_E_INVAL; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA]) { + nla_memcpy(¶ms.ta[0], + tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA], + QDF_MAC_ADDR_SIZE); + hdd_debug("ta " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(¶ms.ta[0])); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK]) { + nla_memcpy(¶ms.ta_mask[0], + tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK], + QDF_MAC_ADDR_SIZE); + hdd_debug("ta_mask " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(¶ms.ta_mask[0])); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA]) { + nla_memcpy(¶ms.ra[0], + tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA], + QDF_MAC_ADDR_SIZE); + hdd_debug("ra " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(¶ms.ra[0])); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK]) { + nla_memcpy(¶ms.ra_mask[0], + tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK], + QDF_MAC_ADDR_SIZE); + hdd_debug("ra_mask " QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(¶ms.ra_mask[0])); + } + + if (!qdf_is_macaddr_zero((struct qdf_mac_addr *)¶ms.ta) || + !qdf_is_macaddr_zero((struct qdf_mac_addr *)¶ms.ra) || + !qdf_is_macaddr_zero((struct qdf_mac_addr *)¶ms.ta_mask) || + !qdf_is_macaddr_zero((struct qdf_mac_addr *)¶ms.ra_mask)) { + hdd_debug("set tara config"); + ucfg_cfr_set_tara_config(vdev, ¶ms); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS]) { + params.nss = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS]); + hdd_debug("nss %d", params.nss); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW]) { + params.bw = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW]); + hdd_debug("bw %d", params.bw); + } + + if (params.nss || params.bw) { + hdd_debug("set bw nss"); + ucfg_cfr_set_bw_nss(vdev, ¶ms); + } + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER]) { + params.expected_mgmt_subtype = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER]); + hdd_debug("expected_mgmt_subtype %d(%x)", + params.expected_mgmt_subtype, + params.expected_mgmt_subtype); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER]) { + params.expected_ctrl_subtype = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER]); + hdd_debug("expected_mgmt_subtype %d(%x)", + params.expected_ctrl_subtype, + params.expected_ctrl_subtype); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER]) { + params.expected_data_subtype = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER]); + hdd_debug("expected_mgmt_subtype %d(%x)", + params.expected_data_subtype, + params.expected_data_subtype); + } + if (!params.expected_mgmt_subtype || + !params.expected_ctrl_subtype || + !params.expected_data_subtype) { + hdd_debug("set frame type"); + ucfg_cfr_set_frame_type_subtype(vdev, ¶ms); + } + + return QDF_STATUS_SUCCESS; +} + +static enum capture_type convert_vendor_cfr_capture_type( + enum qca_wlan_vendor_cfr_capture_type type) +{ + switch (type) { + case QCA_WLAN_VENDOR_CFR_DIRECT_FTM: + return RCC_DIRECTED_FTM_FILTER; + case QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK: + return RCC_ALL_FTM_ACK_FILTER; + case QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP: + return RCC_DIRECTED_NDPA_NDP_FILTER; + case QCA_WLAN_VENDOR_CFR_TA_RA: + return RCC_TA_RA_FILTER; + case QCA_WLAN_VENDOR_CFR_ALL_PACKET: + return RCC_NDPA_NDP_ALL_FILTER; + default: + hdd_err("invalid capture type"); + return RCC_DIS_ALL_MODE; + } +} + +static int +wlan_cfg80211_cfr_set_config(struct wlan_objmgr_vdev *vdev, + struct nlattr *tb[]) +{ + struct nlattr *group[QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX + 1]; + struct nlattr *group_list; + struct cfr_wlanconfig_param params = { 0 }; + enum capture_type type; + enum qca_wlan_vendor_cfr_capture_type vendor_capture_type; + int rem = 0; + int maxtype; + int attr; + uint64_t ul_mu_user_mask = 0; + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION]) { + params.cap_dur = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION]); + ucfg_cfr_set_capture_duration(vdev, ¶ms); + hdd_debug("params.cap_dur %d", params.cap_dur); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL]) { + params.cap_intvl = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL]); + ucfg_cfr_set_capture_interval(vdev, ¶ms); + hdd_debug("params.cap_intvl %d", params.cap_intvl); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE]) { + vendor_capture_type = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE]); + if ((vendor_capture_type < QCA_WLAN_VENDOR_CFR_DIRECT_FTM) || + (vendor_capture_type > QCA_WLAN_VENDOR_CFR_ALL_PACKET)) { + hdd_err_rl("invalid capture type %d", + vendor_capture_type); + return -EINVAL; + } + type = convert_vendor_cfr_capture_type(vendor_capture_type); + ucfg_cfr_set_rcc_mode(vdev, type, 1); + hdd_debug("type %d", type); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK]) { + ul_mu_user_mask = nla_get_u64(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK]); + hdd_debug("ul_mu_user_mask_lower %d", + params.ul_mu_user_mask_lower); + } + + if (ul_mu_user_mask) { + params.ul_mu_user_mask_lower = + (uint32_t)(ul_mu_user_mask & 0xffffffff); + params.ul_mu_user_mask_lower = + (uint32_t)(ul_mu_user_mask >> 32); + hdd_debug("set ul mu user maks"); + ucfg_cfr_set_ul_mu_user_mask(vdev, ¶ms); + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT]) { + params.freeze_tlv_delay_cnt_thr = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT]); + if (params.freeze_tlv_delay_cnt_thr) { + params.freeze_tlv_delay_cnt_en = 1; + ucfg_cfr_set_freeze_tlv_delay_cnt(vdev, ¶ms); + hdd_debug("freeze_tlv_delay_cnt_thr %d", + params.freeze_tlv_delay_cnt_thr); + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE]) { + maxtype = QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX; + attr = QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE; + nla_for_each_nested(group_list, tb[attr], rem) { + if (wlan_cfg80211_nla_parse(group, maxtype, + nla_data(group_list), + nla_len(group_list), + cfr_config_policy)) { + hdd_err("nla_parse failed for cfr config group"); + return -EINVAL; + } + wlan_cfg80211_cfr_set_group_config(vdev, group); + } + } + + return 0; +} + +static int +wlan_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy, + struct hdd_adapter *adapter, + const void *data, + int data_len) +{ + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX + 1]; + struct cfr_wlanconfig_param params = { 0 }; + struct wlan_objmgr_vdev *vdev; + uint8_t version = 0; + bool is_start_capture = false; + QDF_STATUS status; + int ret; + + if (wlan_cfg80211_nla_parse( + tb, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX, + data, + data_len, + cfr_config_policy)) { + hdd_err("Invalid ATTR"); + return -EINVAL; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION]) { + version = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION]); + hdd_debug("version %d", version); + if (version != ENHANCED_CFR_VERSION) { + hdd_err("unsupported version"); + return -EFAULT; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE]) { + is_start_capture = nla_get_flag(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE]); + } + + if (is_start_capture && + !tb[QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP]) { + hdd_err("Invalid group bitmap"); + return -EINVAL; + } + + vdev = adapter->vdev; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_CFR_ID); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("can't get vdev"); + return qdf_status_to_os_return(status); + } + + if (is_start_capture) { + ret = wlan_cfg80211_cfr_set_config(vdev, tb); + if (ret) { + hdd_err("set config failed"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + return ret; + } + params.en_cfg = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP]); + hdd_debug("params.en_cfg %d", params.en_cfg); + ucfg_cfr_set_en_bitmap(vdev, ¶ms); + } else { + hdd_debug("cleanup rcc mode"); + ucfg_cfr_set_rcc_mode(vdev, RCC_DIS_ALL_MODE, 0); + } + ucfg_cfr_subscribe_ppdu_desc(wlan_vdev_get_pdev(vdev), + is_start_capture); + ucfg_cfr_committed_rcc_config(vdev); + if (!is_start_capture) { + ucfg_cfr_stop_indication(vdev); + hdd_debug("stop indication done"); + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); + + return 0; +} + +static int __wlan_hdd_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter; + + hdd_enter(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + adapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + return -EINVAL; + + wlan_cfg80211_peer_cfr_capture_cfg(wiphy, adapter, + data, data_len); + + hdd_exit(); + + return ret; +} + +int wlan_hdd_cfg80211_peer_cfr_capture_cfg(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int errno; + + errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_peer_cfr_capture_cfg(wiphy, wdev, + data, data_len); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno; +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_coex_config.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_coex_config.c index fe2755fc18a441b23c2cd91887c55562ae19d042..b4e83bb022d48f2212330b0e304c96c45857ece4 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_coex_config.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_coex_config.c @@ -29,6 +29,7 @@ #include "qca_vendor.h" #include "wlan_osif_request_manager.h" #include "osif_sync.h" +#include "wlan_fwol_ucfg_api.h" static const struct nla_policy coex_config_three_way_policy[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX + 1] = { @@ -67,6 +68,7 @@ static int __wlan_hdd_cfg80211_set_coex_config(struct wiphy *wiphy, struct nlattr *tb[QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX + 1]; uint32_t config_type; struct coex_config_params coex_cfg_params = {0}; + struct wlan_fwol_coex_config config = {0}; int errno; QDF_STATUS status; @@ -76,6 +78,16 @@ static int __wlan_hdd_cfg80211_set_coex_config(struct wiphy *wiphy, if (errno != 0) return errno; + status = ucfg_fwol_get_coex_config_params(hdd_ctx->psoc, &config); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Unable to get coex config params"); + return -EINVAL; + } + if (!config.btc_three_way_coex_config_legacy_enable) { + hdd_err("Coex legacy feature should be enable first"); + return -EINVAL; + } + if (wlan_cfg80211_nla_parse(tb, QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX, data, data_len, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_conc_ut.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_conc_ut.c index fc5f1ba408969e2440ad66504c4c6b5e756d3e60..a5ea9b2e1873ccc9f7fe12fb9d14101f675013d9 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_conc_ut.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_conc_ut.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,7 +64,7 @@ struct report_t { bool status; char result_code[MAX_ALLOWED_CHAR_IN_REPORT]; char reason[MAX_ALLOWED_CHAR_IN_REPORT]; - char pcl[2 * QDF_MAX_NUM_CHAN]; + char pcl[2 * NUM_CHANNELS]; }; static struct report_t report[NUMBER_OF_SCENARIO]; @@ -230,7 +230,7 @@ void fill_report(struct hdd_context *hdd_ctx, char *title, if (pcl) { qdf_mem_zero(report[report_idx].pcl, sizeof(report[report_idx].pcl)); - for (i = 0; i < QDF_MAX_NUM_CHAN; i++) { + for (i = 0; i < NUM_CHANNELS; i++) { if (pcl[i] == 0) break; qdf_mem_zero(buf, sizeof(buf)); @@ -622,9 +622,9 @@ static void wlan_hdd_map_subtypes_hdd_wma(enum policy_mgr_con_mode *dst, void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx) { enum policy_mgr_con_mode sub_type; - uint8_t pcl[QDF_MAX_NUM_CHAN] = {0}, - weight_list[QDF_MAX_NUM_CHAN] = {0}; - uint32_t pcl_len = 0; + uint8_t pcl[NUM_CHANNELS] = {0}, + weight_list[NUM_CHANNELS] = {0}; + uint32_t pcl_len = 0, i, pcl_freqs[NUM_CHANNELS] = {0}; bool status = false; enum policy_mgr_pcl_type pcl_type; char reason[20] = {0}; @@ -634,7 +634,6 @@ void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx) ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, &system_pref); - sme_cbacks.sme_get_valid_channels = sme_get_valid_channels; sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; /* flush the entire table first */ ret = policy_mgr_psoc_enable(hdd_ctx->psoc); @@ -655,8 +654,11 @@ void wlan_hdd_one_connection_scenario(struct hdd_context *hdd_ctx) sub_type, system_pref); /* check PCL value for second connection is correct or no */ - policy_mgr_get_pcl(hdd_ctx->psoc, sub_type, pcl, &pcl_len, - weight_list, QDF_ARRAY_SIZE(weight_list)); + policy_mgr_get_pcl(hdd_ctx->psoc, sub_type, pcl_freqs, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); + for (i = 0; i < pcl_len; i++) + pcl[i] = wlan_freq_to_chan(pcl_freqs[i]); + status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, 0, 0, reason, sizeof(reason)); @@ -676,9 +678,9 @@ void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx, { uint8_t vdevid = 0, tx_stream = 2, rx_stream = 2; uint8_t type = WMI_VDEV_TYPE_STA, channel_id = first_chnl, mac_id = 1; - uint8_t pcl[QDF_MAX_NUM_CHAN] = {0}, - weight_list[QDF_MAX_NUM_CHAN] = {0}; - uint32_t pcl_len = 0; + uint8_t pcl[NUM_CHANNELS] = {0}, + weight_list[NUM_CHANNELS] = {0}; + uint32_t pcl_len = 0, i, pcl_freqs[NUM_CHANNELS]; enum policy_mgr_chain_mode chain_mask = first_chain_mask; enum policy_mgr_con_mode sub_type, next_sub_type, dummy_type; enum policy_mgr_pcl_type pcl_type; @@ -695,7 +697,6 @@ void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx, sub_type < PM_MAX_NUM_OF_MODE; sub_type++) { type = wlan_hdd_valid_type_of_persona(sub_type); - sme_cbacks.sme_get_valid_channels = sme_get_valid_channels; sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; /* flush the entire table first */ ret = policy_mgr_psoc_enable(hdd_ctx->psoc); @@ -707,10 +708,10 @@ void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx, /* sub_type mapping between HDD and WMA are different */ wlan_hdd_map_subtypes_hdd_wma(&dummy_type, &sub_type); /* add first connection as STA */ - policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc, - vdevid, tx_stream, - rx_stream, chain_mask, type, dummy_type, - channel_id, mac_id); + policy_mgr_incr_connection_count_utfw( + hdd_ctx->psoc, vdevid, tx_stream, + rx_stream, chain_mask, type, dummy_type, + wlan_chan_to_freq(channel_id), mac_id); /* validate one connection is created or no */ if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 1) { hdd_err("Test failed - No. of connection is not 1"); @@ -736,8 +737,11 @@ void wlan_hdd_two_connections_scenario(struct hdd_context *hdd_ctx, hdd_ctx->psoc)); /* check PCL for second connection is correct or no */ policy_mgr_get_pcl(hdd_ctx->psoc, - next_sub_type, pcl, &pcl_len, - weight_list, QDF_ARRAY_SIZE(weight_list)); + next_sub_type, pcl_freqs, &pcl_len, + weight_list, + QDF_ARRAY_SIZE(weight_list)); + for (i = 0; i < pcl_len; i++) + pcl[i] = wlan_freq_to_chan(pcl_freqs[i]); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id, 0, reason, sizeof(reason)); @@ -763,8 +767,8 @@ void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx, uint8_t channel_id_1 = first_chnl, channel_id_2 = second_chnl; uint8_t mac_id_1, mac_id_2; uint8_t type_1 = WMI_VDEV_TYPE_STA, type_2 = WMI_VDEV_TYPE_STA; - uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; - uint32_t pcl_len = 0; + uint8_t pcl[NUM_CHANNELS] = {0}, weight_list[NUM_CHANNELS] = {0}; + uint32_t pcl_len = 0, i, pcl_freqs[NUM_CHANNELS]; enum policy_mgr_chain_mode chain_mask_1; enum policy_mgr_chain_mode chain_mask_2; enum policy_mgr_con_mode sub_type_1, sub_type_2, next_sub_type; @@ -802,7 +806,6 @@ void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx, type_1 = wlan_hdd_valid_type_of_persona(sub_type_1); - sme_cbacks.sme_get_valid_channels = sme_get_valid_channels; sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; /* flush the entire table first */ ret = policy_mgr_psoc_enable(hdd_ctx->psoc); @@ -814,9 +817,10 @@ void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx, /* sub_type mapping between HDD and WMA are different */ wlan_hdd_map_subtypes_hdd_wma(&dummy_type_1, &sub_type_1); /* add first connection as STA */ - policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc, - vdevid_1, tx_stream_1, rx_stream_1, chain_mask_1, - type_1, dummy_type_1, channel_id_1, mac_id_1); + policy_mgr_incr_connection_count_utfw( + hdd_ctx->psoc, vdevid_1, tx_stream_1, rx_stream_1, + chain_mask_1, type_1, dummy_type_1, + wlan_chan_to_freq(channel_id_1), mac_id_1); /* validate one connection is created or no */ if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 1) { hdd_err("Test fail - No. of connection not 1"); @@ -829,10 +833,11 @@ void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx, /* sub_type mapping between HDD and WMA are different */ wlan_hdd_map_subtypes_hdd_wma(&dummy_type_2, &sub_type_2); - policy_mgr_incr_connection_count_utfw(hdd_ctx->psoc, - vdevid_2, tx_stream_2, rx_stream_2, - chain_mask_2, type_2, - dummy_type_2, channel_id_2, mac_id_2); + policy_mgr_incr_connection_count_utfw( + hdd_ctx->psoc, vdevid_2, tx_stream_2, + rx_stream_2, chain_mask_2, type_2, + dummy_type_2, + wlan_chan_to_freq(channel_id_2), mac_id_2); /* validate two connections are created or no */ if (policy_mgr_get_connection_count(hdd_ctx->psoc) != 2) { @@ -858,11 +863,13 @@ void wlan_hdd_three_connections_scenario(struct hdd_context *hdd_ctx, system_pref, policy_mgr_is_hw_dbs_capable( hdd_ctx->psoc)); - policy_mgr_get_pcl(hdd_ctx->psoc, - next_sub_type, - pcl, &pcl_len, - weight_list, + policy_mgr_get_pcl( + hdd_ctx->psoc, next_sub_type, + pcl_freqs, &pcl_len, weight_list, QDF_ARRAY_SIZE(weight_list)); + for (i = 0; i < pcl_len; i++) + pcl[i] = + wlan_freq_to_chan(pcl_freqs[i]); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id_1, channel_id_2, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_data_stall_detection.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_data_stall_detection.c index 95bad52d8c7b7d7e392a0c16442bbcd14c3e6f01..9f82edbb7dccbcc7830215fcd7be999ca3c87174 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_data_stall_detection.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_data_stall_detection.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -29,6 +29,7 @@ #include "cdp_txrx_cmn.h" #include "cdp_txrx_misc.h" #include "ol_txrx_types.h" +#include "ol_defines.h" #ifdef FEATURE_WLAN_DIAG_SUPPORT #include "host_diag_core_event.h" #include "host_diag_core_log.h" @@ -60,9 +61,9 @@ static inline void hdd_data_stall_send_event(uint32_t reason) /** * hdd_data_stall_process_event() - Process data stall event - * @data_stall_info: data stall message + * @message: data stall message * - * Process data stall event + * Process data stall message * * Return: void */ @@ -74,7 +75,7 @@ static void hdd_data_stall_process_event( /** * hdd_data_stall_process_cb() - Process data stall message - * @info: data stall message + * @message: data stall message * * Process data stall message * @@ -118,10 +119,8 @@ int hdd_register_data_stall_detect_cb(void) /* Register the data stall callback */ hdd_debug("Register data stall detect callback"); - status = cdp_data_stall_cb_register( - soc, - cds_get_context(QDF_MODULE_ID_TXRX), - hdd_data_stall_process_cb); + status = cdp_data_stall_cb_register(soc, OL_TXRX_PDEV_ID, + hdd_data_stall_process_cb); return qdf_status_to_os_return(status); } @@ -132,9 +131,7 @@ int hdd_deregister_data_stall_detect_cb(void) /* De-Register the data stall callback */ hdd_debug("De-Register data stall detect callback"); - status = cdp_data_stall_cb_deregister( - soc, - cds_get_context(QDF_MODULE_ID_TXRX), - hdd_data_stall_process_cb); + status = cdp_data_stall_cb_deregister(soc, OL_TXRX_PDEV_ID, + hdd_data_stall_process_cb); return qdf_status_to_os_return(status); } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs.c index ae2d5a5960511588886c4b9b3170480a04b039bc..c7f369c3356f7f07d464d690f0f92bf723603b8f 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs.c @@ -33,6 +33,7 @@ #include #include #include +#include #define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8 #define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512 @@ -545,6 +546,9 @@ QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter) &fops_patterngen)) return QDF_STATUS_E_FAILURE; + if (wlan_hdd_create_mib_stats_file(adapter)) + return QDF_STATUS_E_FAILURE; + if (wlan_hdd_create_ll_stats_file(adapter)) return QDF_STATUS_E_FAILURE; @@ -562,5 +566,6 @@ QDF_STATUS hdd_debugfs_init(struct hdd_adapter *adapter) void hdd_debugfs_exit(struct hdd_adapter *adapter) { debugfs_remove_recursive(adapter->debugfs_phy); + wlan_hdd_destroy_mib_stats_lock(); } #endif /* #ifdef WLAN_OPEN_SOURCE */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_connect.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_connect.c index f673b14c1dd96c71a038454974eed151b1b18eb4..8367be50dc7e557fcb1580f6afc2bbcf39afe541 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_connect.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_connect.c @@ -360,7 +360,7 @@ wlan_hdd_connect_info_debugfs(struct hdd_adapter *adapter, uint8_t *buf, } ret_val = scnprintf(buf + length, buf_avail_len - length, "ssid = %s\n" - "bssid = " QDF_MAC_ADDR_STR "\n" + "bssid = " QDF_FULL_MAC_FMT "\n" "connect_time = %s\n" "auth_time = %s\n" "freq = %u\n" @@ -371,10 +371,10 @@ wlan_hdd_connect_info_debugfs(struct hdd_adapter *adapter, uint8_t *buf, "last_auth_type = %s\n" "dot11mode = %s\n", conn_info->last_ssid.SSID.ssId, - QDF_MAC_ADDR_ARRAY(conn_info->bssid.bytes), + QDF_FULL_MAC_REF(conn_info->bssid.bytes), conn_info->connect_time, conn_info->auth_time, - conn_info->freq, + conn_info->chan_freq, hdd_ch_width_str(conn_info->ch_width), conn_info->signal, tx_bit_rate, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_llstat.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_llstat.c index c2bdc4399a7f0e1b0cfb20ef03313e3d74b5eede..8098c0d777deb490d3224ab14ca163748af9e9ac 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_llstat.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_llstat.c @@ -76,11 +76,13 @@ void hdd_debugfs_process_iface_stats(struct hdd_adapter *adapter, buffer += len; ll_stats.len += len; len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len, - "\nmode: %u, MAC_ADDR: %pM, state: %u, roaming: %u, capabilities: %u, SSID: %s, BSSID_MAC: %pM, ap_country_str: %s, country_str: %s", - iface_info->mode, &iface_info->macAddr.bytes[0], + "\nmode: %u, MAC_ADDR: "QDF_FULL_MAC_FMT", state: %u, roaming: %u, capabilities: %u, SSID: %s, BSSID_MAC: "QDF_FULL_MAC_FMT", ap_country_str: %s, country_str: %s", + iface_info->mode, + QDF_FULL_MAC_REF(iface_info->macAddr.bytes), iface_info->state, iface_info->roaming, iface_info->capabilities, iface_info->ssid, - &iface_info->bssid.bytes[0], iface_info->apCountryStr, + QDF_FULL_MAC_REF(iface_info->bssid.bytes), + iface_info->apCountryStr, iface_info->countryStr); link_stats = &iface_stat->link_stats; @@ -184,9 +186,9 @@ void hdd_debugfs_process_peer_stats(struct hdd_adapter *adapter, void *data) ll_stats.len += len; len = scnprintf(buffer, DEBUGFS_LLSTATS_BUF_SIZE - ll_stats.len, - "\nType: %d, peer_mac: %pM, capabilities: %u\nnum_rates: %d", + "\nType: %d, peer_mac: "QDF_FULL_MAC_FMT", capabilities: %u\nnum_rates: %d", wmi_to_sir_peer_type(peer_info->type), - &peer_info->peer_macaddr.bytes[0], + QDF_FULL_MAC_REF(peer_info->peer_macaddr.bytes), peer_info->capabilities, peer_info->num_rate); num_rate = peer_info->num_rate; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_mibstat.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_mibstat.c new file mode 100644 index 0000000000000000000000000000000000000000..dd5aadcb326adb3aadf6dd4f715f7451d094415e --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_mibstat.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_debugfs_mibstat.c + * + * WLAN Host Device Driver implementation to update + * debugfs with MIB statistics + */ + +#include +#include "osif_sync.h" +#include +#include +#include + +struct mib_stats_buf { + ssize_t len; + uint8_t *result; +}; + +static struct mib_stats_buf mib_stats; + +qdf_mutex_t mibstats_lock; + +void hdd_debugfs_process_mib_stats(struct hdd_adapter *adapter, + struct stats_event *stats) +{ + ssize_t len = 0; + uint8_t *buffer; + + hdd_enter(); + + qdf_mutex_acquire(&mibstats_lock); + if (!mib_stats.result) { + qdf_mutex_release(&mibstats_lock); + hdd_err("MIB statistics buffer is NULL"); + return; + } + + buffer = mib_stats.result; + buffer += mib_stats.len; + + len = scnprintf(buffer, DEBUGFS_MIBSTATS_BUF_SIZE - mib_stats.len, + "dot11RTSSuccessCount %d " + "\ndot11RTSFailureCount %d " + "\ndot11QosFailedCount %d " + "\ndot11QosRetryCount %d " + "\ndot11QosTransmittedFrameCount %d " + "\ndot11QosMPDUsReceivedCount %d " + "\ndot11TransmittedAMPDUCount %d " + "\ndot11QosACKFailureCount %d", + stats->mib_stats->mib_mac_statistics.rts_success_cnt, + stats->mib_stats->mib_mac_statistics.rts_fail_cnt, + stats->mib_stats->mib_qos_counters.qos_failed_cnt, + stats->mib_stats->mib_qos_counters.qos_retry_cnt, + stats->mib_stats->mib_qos_counters.qos_tx_frame_cnt, + stats->mib_stats->mib_qos_counters.qos_mpdu_rx_cnt, + stats->mib_stats->mib_counters_group3.tx_ampdu_cnt, + stats->mib_stats-> + mib_qos_counters.tx_qos_ack_fail_cnt_up + ); + + buffer += len; + mib_stats.len += len; + qdf_mutex_release(&mibstats_lock); + + hdd_exit(); +} + +static inline void wlan_hdd_mibstats_free_buf(void) +{ + qdf_mutex_acquire(&mibstats_lock); + qdf_mem_free(mib_stats.result); + mib_stats.result = NULL; + mib_stats.len = 0; + qdf_mutex_release(&mibstats_lock); +} + +static int wlan_hdd_mibstats_alloc_buf(void) +{ + qdf_mutex_acquire(&mibstats_lock); + if (mib_stats.result) { + qdf_mutex_release(&mibstats_lock); + hdd_err("Buffer is already allocated"); + return 0; + } + mib_stats.len = 0; + mib_stats.result = qdf_mem_malloc(DEBUGFS_MIBSTATS_BUF_SIZE); + if (!mib_stats.result) { + qdf_mutex_release(&mibstats_lock); + return -EINVAL; + } + qdf_mutex_release(&mibstats_lock); + return 0; +} + +/** + * hdd_debugfs_mib_stats_update() - Update userspace with local stats buffer + * @buf: userspace buffer (to which data is being copied into) + * @count: max data that can be copied into buf in bytes + * @pos: offset (where data should be copied into) + * + * This function copies mib statistics buffer into debugfs + * entry. + * + * Return: number of characters copied; 0 on no-copy + */ +static ssize_t hdd_debugfs_mib_stats_update(char __user *buf, + size_t count, loff_t *pos) +{ + ssize_t ret_cnt; + + hdd_enter(); + qdf_mutex_acquire(&mibstats_lock); + if (!mib_stats.result) { + qdf_mutex_release(&mibstats_lock); + hdd_err("Trying to read from NULL buffer"); + return 0; + } + + ret_cnt = simple_read_from_buffer(buf, count, pos, + mib_stats.result, + mib_stats.len); + qdf_mutex_release(&mibstats_lock); + hdd_debug("mib stats read req: count: %zu, pos: %lld", count, *pos); + + hdd_exit(); + return ret_cnt; +} + +/** + * __wlan_hdd_release_mib_stats_debugfs() - Function to free private + * memory on release + * @net_dev: net_device context used to register the debugfs file + * + * Return: Errno + */ +static int __wlan_hdd_release_mib_stats_debugfs(struct net_device *net_dev) + +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); + struct hdd_context *hdd_ctx; + int errno; + + hdd_enter_dev(net_dev); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + + wlan_hdd_mibstats_free_buf(); + + hdd_exit(); + + return 0; +} + +/** + * wlan_hdd_release_mib_stats_debugfs() - SSR wrapper function to free + * private memory on release + * @inode: Pointer to inode structure + * @file: file pointer + * + * Return: Errno + */ +static int wlan_hdd_release_mib_stats_debugfs(struct inode *inode, + struct file *file) +{ + struct net_device *net_dev = file_inode(file)->i_private; + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_release_mib_stats_debugfs(net_dev); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + +/** + * __wlan_hdd_read_mib_stats_debugfs() - mib_stats debugfs handler + * @net_dev: net_device context used to register the debugfs file + * @buf: text being written to the debugfs + * @count: size of @buf + * @pos: (unused) offset into the virtual file system + * + * Return: Number of bytes read on success, error number otherwise + */ +static ssize_t __wlan_hdd_read_mib_stats_debugfs(struct net_device *net_dev, + char __user *buf, + size_t count, loff_t *pos) + +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); + struct hdd_context *hdd_ctx; + ssize_t ret; + + hdd_enter_dev(net_dev); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + goto free_buf; + + if (*pos == 0) { + ret = wlan_hdd_get_mib_stats(adapter); + if (ret) + goto free_buf; + } + + /* All the events are received and buffer is populated */ + ret = hdd_debugfs_mib_stats_update(buf, count, pos); + hdd_debug("%zu characters written into debugfs", ret); + + hdd_exit(); + + return ret; + +free_buf: + wlan_hdd_mibstats_free_buf(); + + hdd_exit(); + + return ret; +} + +/** + * wlan_hdd_read_mib_stats_debugfs() - SSR wrapper function to read + * mib stats + * @file: file pointer + * @buf: buffer + * @count: count + * @pos: position pointer + * + * Return: Number of bytes read on success, error number otherwise + */ +static ssize_t wlan_hdd_read_mib_stats_debugfs(struct file *file, + char __user *buf, size_t count, + loff_t *pos) +{ + struct net_device *net_dev = file_inode(file)->i_private; + struct osif_vdev_sync *vdev_sync; + ssize_t err_size; + + err_size = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (err_size) + return err_size; + + err_size = __wlan_hdd_read_mib_stats_debugfs(net_dev, buf, + count, pos); + + osif_vdev_sync_op_stop(vdev_sync); + + return err_size; +} + +/** + * __wlan_hdd_open_mib_stats_debugfs() - Function to save private on open + * @net_dev: net_device context used to register the debugfs file + * + * Return: Errno + */ +static int __wlan_hdd_open_mib_stats_debugfs(struct net_device *net_dev) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); + struct hdd_context *hdd_ctx; + int errno; + + hdd_enter_dev(net_dev); + + errno = hdd_validate_adapter(adapter); + if (errno) + return errno; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + + errno = wlan_hdd_mibstats_alloc_buf(); + if (errno) + return errno; + + hdd_exit(); + + return 0; +} + +/** + * wlan_hdd_open_mib_stats_debugfs() - SSR wrapper to save private + * on open + * @inode: Pointer to inode structure + * @file: file pointer + * + * Return: Errno + */ +static int wlan_hdd_open_mib_stats_debugfs(struct inode *inode, + struct file *file) +{ + struct net_device *net_dev = inode->i_private; + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_open_mib_stats_debugfs(net_dev); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + +static const struct file_operations fops_mib_stats = { + .read = wlan_hdd_read_mib_stats_debugfs, + .open = wlan_hdd_open_mib_stats_debugfs, + .release = wlan_hdd_release_mib_stats_debugfs, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +int wlan_hdd_create_mib_stats_file(struct hdd_adapter *adapter) +{ + if (!debugfs_create_file("mib_stats", 0444, adapter->debugfs_phy, + adapter->dev, &fops_mib_stats)) + return -EINVAL; + + if (QDF_IS_STATUS_ERROR(qdf_mutex_create( + &mibstats_lock))) { + hdd_debug("mibstats lock init failed!"); + return QDF_STATUS_E_FAILURE; + } + + return 0; +} + +void wlan_hdd_destroy_mib_stats_lock(void) +{ + qdf_mutex_destroy(&mibstats_lock); +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_offload.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_offload.c index 0a9a1fc4fb23876e724244e166d2ff516dce7e7a..06a90f25bf697e8703a2ad629ba602e85a55bfdd 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_offload.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_offload.c @@ -98,8 +98,8 @@ wlan_hdd_mc_addr_list_info_debugfs(struct hdd_context *hdd_ctx, } ret = scnprintf(buf + length, buf_avail_len - length, - QDF_MAC_ADDR_STR "\n", - QDF_MAC_ADDR_ARRAY(mc_addr_list.mc_addr[i].bytes)); + QDF_FULL_MAC_FMT "\n", + QDF_FULL_MAC_REF(mc_addr_list.mc_addr[i].bytes)); if (ret <= 0) return length; length += ret; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_roam.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_roam.c index 6051f669d932d9f48baa56de4b8db13def123eb9..d843f1c741ffae8749729b8db0b32b54b6b9f400 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_roam.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_debugfs_roam.c @@ -476,16 +476,16 @@ wlan_hdd_update_roam_stats(struct hdd_context *hdd_ctx, ret = scnprintf(buf + length, buf_avail_len - length, "\nSTA roamed from " - QDF_MAC_ADDR_STR " to " - QDF_MAC_ADDR_STR "\n", - QDF_MAC_ADDR_ARRAY(scan->old_bssid), - QDF_MAC_ADDR_ARRAY(scan->new_bssid)); + QDF_FULL_MAC_FMT " to " + QDF_FULL_MAC_FMT "\n", + QDF_FULL_MAC_REF(scan->old_bssid), + QDF_FULL_MAC_REF(scan->new_bssid)); } else { ret = scnprintf(buf + length, buf_avail_len - length, - "\nSTA is connected to " QDF_MAC_ADDR_STR + "\nSTA is connected to " QDF_FULL_MAC_FMT " before and after scan, not roamed\n", - QDF_MAC_ADDR_ARRAY(scan->old_bssid)); + QDF_FULL_MAC_REF(scan->old_bssid)); } if (ret <= 0) goto free_mem; @@ -526,8 +526,8 @@ wlan_hdd_update_roam_stats(struct hdd_context *hdd_ctx, ret = scnprintf(buf + length, buf_avail_len - length, - QDF_MAC_ADDR_STR " %4u %3u %3u\n", - QDF_MAC_ADDR_ARRAY(bssid), + QDF_FULL_MAC_FMT " %4u %3u %3u\n", + QDF_FULL_MAC_REF(bssid), scan->cand[rci].freq, scan->cand[rci].score, scan->cand[rci].rssi); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c index 14aec92e349fb5a36e829b695d11a187cdd24bd9..a52a5c9f5796434ecbbbe2580e516c2a0e1c1d02 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c @@ -35,6 +35,7 @@ #include "wlan_policy_mgr_api.h" #include "qwlan_version.h" #include "bmi.h" +#include #include "cdp_txrx_bus.h" #include "cdp_txrx_misc.h" #include "pld_common.h" @@ -43,6 +44,8 @@ #include "wlan_hdd_debugfs.h" #include "cfg_ucfg_api.h" #include +#include +#include #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -93,6 +96,31 @@ static int hdd_get_bandwidth_level(void *data) return ret; } +#ifdef DP_MEM_PRE_ALLOC + +/** + * hdd_get_consistent_mem_unaligned() - API to get consistent unaligned mem + * @size: Size of memory required + * @paddr: Pointer to paddr to be filled in by API + * @ring_type: Pointer to ring type for which consistent memory is needed + * + * Return: Virtual address of consistent memory on success, else null + */ +static inline +void *hdd_get_consistent_mem_unaligned(size_t size, + qdf_dma_addr_t *paddr, + uint32_t ring_type) +{ + return hdd_get_prealloc_dma_mem_unaligned(size, paddr, ring_type); +} + +static inline +void hdd_put_consistent_mem_unaligned(void *vaddr) +{ + hdd_put_prealloc_dma_mem_unaligned(vaddr); +} +#endif + /** * hdd_set_recovery_in_progress() - API to set recovery in progress * @data: Context @@ -170,7 +198,21 @@ static void hdd_hif_init_driver_state_callbacks(void *data, cbk->is_driver_unloading = hdd_is_driver_unloading; cbk->is_target_ready = hdd_is_target_ready; cbk->get_bandwidth_level = hdd_get_bandwidth_level; +#ifdef DP_MEM_PRE_ALLOC + cbk->prealloc_get_consistent_mem_unaligned = + hdd_get_consistent_mem_unaligned; + cbk->prealloc_put_consistent_mem_unaligned = + hdd_put_consistent_mem_unaligned; +#endif +} + +#ifdef FORCE_WAKE +void hdd_set_hif_init_phase(struct hif_opaque_softc *hif_ctx, + bool hal_init_phase) +{ + hif_srng_init_phase(hif_ctx, hal_init_phase); } +#endif /* FORCE_WAKE */ /** @@ -179,7 +221,7 @@ static void hdd_hif_init_driver_state_callbacks(void *data, * * Return: None */ -#ifdef QCS403_MEM_OPTIMIZE +#ifdef SLUB_MEM_OPTIMIZE static void hdd_hif_set_attribute(struct hif_opaque_softc *hif_ctx) { hif_set_attribute(hif_ctx, HIF_LOWDESC_CE_NO_PKTLOG_CFG); @@ -189,6 +231,38 @@ static void hdd_hif_set_attribute(struct hif_opaque_softc *hif_ctx) {} #endif +/** + + * hdd_hif_set_ce_max_yield_time() - Wrapper API to set CE max yield time + * @hif_ctx: hif context + * @bus_type: underlying bus type + * @ce_service_max_yield_time: max yield time to be set + * + * Return: None + */ +#if defined(CONFIG_SLUB_DEBUG_ON) +#define CE_SNOC_MAX_YIELD_TIME_US 2000 + +static void hdd_hif_set_ce_max_yield_time(struct hif_opaque_softc *hif_ctx, + enum qdf_bus_type bus_type, + uint32_t ce_service_max_yield_time) +{ + if (bus_type == QDF_BUS_TYPE_SNOC && + ce_service_max_yield_time < CE_SNOC_MAX_YIELD_TIME_US) + ce_service_max_yield_time = CE_SNOC_MAX_YIELD_TIME_US; + + hif_set_ce_service_max_yield_time(hif_ctx, ce_service_max_yield_time); +} + +#else +static void hdd_hif_set_ce_max_yield_time(struct hif_opaque_softc *hif_ctx, + enum qdf_bus_type bus_type, + uint32_t ce_service_max_yield_time) +{ + hif_set_ce_service_max_yield_time(hif_ctx, ce_service_max_yield_time); +} +#endif + /** * hdd_init_cds_hif_context() - API to set CDS HIF Context * @hif: HIF Context @@ -243,6 +317,8 @@ static enum qdf_bus_type to_bus_type(enum pld_bus_type bus_type) return QDF_BUS_TYPE_SDIO; case PLD_BUS_TYPE_USB: return QDF_BUS_TYPE_USB; + case PLD_BUS_TYPE_IPCI: + return QDF_BUS_TYPE_IPCI; default: return QDF_BUS_TYPE_NONE; } @@ -266,7 +342,7 @@ int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid, hdd_hif_init_driver_state_callbacks(dev, &cbk); - hif_ctx = hif_open(qdf_ctx, mode, bus_type, &cbk); + hif_ctx = hif_open(qdf_ctx, mode, bus_type, &cbk, hdd_ctx->psoc); if (!hif_ctx) { hdd_err("hif_open error"); return -ENOMEM; @@ -306,7 +382,8 @@ int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid, } } - hif_set_ce_service_max_yield_time(hif_ctx, + hdd_hif_set_ce_max_yield_time( + hif_ctx, bus_type, cfg_get(hdd_ctx->psoc, CFG_DP_CE_SERVICE_MAX_YIELD_TIME)); ucfg_pmo_psoc_set_hif_handle(hdd_ctx->psoc, hif_ctx); @@ -411,40 +488,12 @@ static void hdd_abort_system_suspend(struct device *dev) } #endif -/* Total wait time for pm freeze is 10 seconds */ -#define HDD_SLEEP_FOR_PM_FREEZE_TIME (500) -#define HDD_MAX_ATTEMPT_SLEEP_FOR_PM_FREEZE_TIME (20) - -static int hdd_wait_for_pm_freeze(void) -{ - uint8_t count = 0; - - while (pm_freezing) { - hdd_info("pm freezing wait for %d ms", - HDD_SLEEP_FOR_PM_FREEZE_TIME); - msleep(HDD_SLEEP_FOR_PM_FREEZE_TIME); - count++; - if (count > HDD_MAX_ATTEMPT_SLEEP_FOR_PM_FREEZE_TIME) { - hdd_err("timeout occurred for pm freezing"); - return -EBUSY; - } - } - - return 0; -} - int hdd_soc_idle_restart_lock(struct device *dev) { hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART); hdd_abort_system_suspend(dev); - if (hdd_wait_for_pm_freeze()) { - hdd_allow_suspend( - WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART); - return -EBUSY; - } - return 0; } @@ -485,6 +534,8 @@ static int __hdd_soc_probe(struct device *dev, if (errno) goto unlock; + dp_prealloc_init(); + hdd_ctx = hdd_context_create(dev); if (IS_ERR(hdd_ctx)) { errno = PTR_ERR(hdd_ctx); @@ -657,17 +708,17 @@ static int hdd_soc_recovery_reinit(struct device *dev, return errno; errno = __hdd_soc_recovery_reinit(dev, bdev, bid, bus_type); - if (errno) - return errno; + osif_psoc_sync_trans_stop(psoc_sync); - return 0; + return errno; } static void __hdd_soc_remove(struct device *dev) { struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + void *hif_ctx; QDF_BUG(hdd_ctx); if (!hdd_ctx) @@ -676,6 +727,15 @@ static void __hdd_soc_remove(struct device *dev) pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR); + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + if (hif_ctx) { + /* + * Trigger runtime sync resume before setting unload in progress + * such that resume can happen successfully + */ + hif_pm_runtime_sync_resume(hif_ctx); + } + cds_set_driver_loaded(false); cds_set_unload_in_progress(true); @@ -684,6 +744,7 @@ static void __hdd_soc_remove(struct device *dev) if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { hdd_wlan_stop_modules(hdd_ctx, false); + qdf_nbuf_deinit_replenish_timer(); } else { hdd_wlan_exit(hdd_ctx); } @@ -694,6 +755,8 @@ static void __hdd_soc_remove(struct device *dev) cds_set_unload_in_progress(false); pr_info("%s: Driver De-initialized\n", WLAN_MODULE_NAME); + + dp_prealloc_deinit(); } /** @@ -732,11 +795,12 @@ static inline void hdd_wlan_ssr_shutdown_event(void) { } #endif /** - * hdd_send_hang_reason() - Send hang reason to the userspace + * hdd_send_hang_data() - Send hang data to userspace + * @data: Hang data * * Return: None */ -static void hdd_send_hang_reason(void) +static void hdd_send_hang_data(uint8_t *data, size_t data_len) { enum qdf_hang_reason reason = QDF_REASON_UNSPECIFIED; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); @@ -746,7 +810,7 @@ static void hdd_send_hang_reason(void) cds_get_recovery_reason(&reason); cds_reset_recovery_reason(); - wlan_hdd_send_hang_reason_event(hdd_ctx, reason); + wlan_hdd_send_hang_reason_event(hdd_ctx, reason, data, data_len); } /** @@ -772,7 +836,6 @@ static void hdd_psoc_shutdown_notify(struct hdd_context *hdd_ctx) cds_shutdown_notifier_purge(); hdd_wlan_ssr_shutdown_event(); - hdd_send_hang_reason(); } /** @@ -1029,18 +1092,21 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params) struct hdd_context *hdd_ctx; void *hif_ctx; void *dp_soc; - void *dp_pdev; struct pmo_wow_enable_params pmo_params; + int pending; hdd_info("starting bus suspend"); hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + err = wlan_hdd_validate_context(hdd_ctx); - if (err) { - hdd_err("Invalid hdd context: %d", err); + if (err) return err; - } + /* Wait for the stop module if already in progress */ + hdd_psoc_idle_timer_stop(hdd_ctx); + + /* If Wifi is off, return success for system suspend */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Module closed; skipping suspend"); return 0; @@ -1059,8 +1125,7 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params) } dp_soc = cds_get_context(QDF_MODULE_ID_SOC); - dp_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - err = qdf_status_to_os_return(cdp_bus_suspend(dp_soc, dp_pdev)); + err = qdf_status_to_os_return(cdp_bus_suspend(dp_soc, OL_TXRX_PDEV_ID)); if (err) { hdd_err("Failed cdp bus suspend: %d", err); return err; @@ -1087,17 +1152,34 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params) goto late_hif_resume; } + hif_system_pm_set_state_suspended(hif_ctx); + err = hif_bus_suspend(hif_ctx); if (err) { hdd_err("Failed hif bus suspend: %d", err); goto resume_pmo; } + pending = cdp_rx_get_pending(cds_get_context(QDF_MODULE_ID_SOC)); + if (pending) { + hdd_debug("Prevent suspend, RX frame pending %d", pending); + err = -EBUSY; + goto resume_hif; + } + + /* + * Remove bus votes at the very end, after making sure there are no + * pending bus transactions from WLAN SOC for TX/RX. + */ pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE); hdd_info("bus suspend succeeded"); return 0; +resume_hif: + status = hif_bus_resume(hif_ctx); + QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); + resume_pmo: status = ucfg_pmo_psoc_bus_resume_req(hdd_ctx->psoc, QDF_SYSTEM_SUSPEND); @@ -1108,8 +1190,9 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params) QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); resume_cdp: - status = cdp_bus_resume(dp_soc, dp_pdev); + status = cdp_bus_resume(dp_soc, OL_TXRX_PDEV_ID); QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); + hif_system_pm_set_state_on(hif_ctx); return err; } @@ -1146,17 +1229,24 @@ int wlan_hdd_bus_suspend_noirq(void) uint32_t pending_events; hdd_debug("start bus_suspend_noirq"); - errno = wlan_hdd_validate_context(hdd_ctx); - if (errno) { - hdd_err("Invalid HDD context: errno %d", errno); - return errno; + + if (!hdd_ctx) { + hdd_err_rl("hdd context is NULL"); + return -ENODEV; } + /* If Wifi is off, return success for system suspend */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver module closed; skip bus-noirq suspend"); return 0; } + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) { + hdd_err("Invalid HDD context: errno %d", errno); + return errno; + } + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); if (!hif_ctx) { hdd_err("hif_ctx is null"); @@ -1218,31 +1308,46 @@ int wlan_hdd_bus_resume(void) int status; QDF_STATUS qdf_status; void *dp_soc; - void *dp_pdev; if (cds_is_driver_recovering()) return 0; hdd_info("starting bus resume"); - status = wlan_hdd_validate_context(hdd_ctx); - if (status) { - hdd_err("Invalid hdd context"); - return status; + if (!hdd_ctx) { + hdd_err_rl("hdd context is NULL"); + return -ENODEV; } + /* If Wifi is off, return success for system resume */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Module closed; return success"); return 0; } + status = wlan_hdd_validate_context(hdd_ctx); + if (status) { + hdd_err("Invalid hdd context"); + return status; + } + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); if (!hif_ctx) { hdd_err("Failed to get hif context"); return -EINVAL; } - pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_MEDIUM); + /* + * Add bus votes at the beginning, before making sure there are any + * bus transactions from WLAN SOC for TX/RX. + */ + if (hdd_is_any_adapter_connected(hdd_ctx)) { + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_MEDIUM); + } else { + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_NONE); + } status = hif_bus_resume(hif_ctx); if (status) { @@ -1250,6 +1355,8 @@ int wlan_hdd_bus_resume(void) goto out; } + hif_system_pm_set_state_resuming(hif_ctx); + qdf_status = ucfg_pmo_psoc_bus_resume_req(hdd_ctx->psoc, QDF_SYSTEM_SUSPEND); status = qdf_status_to_os_return(qdf_status); @@ -1258,6 +1365,8 @@ int wlan_hdd_bus_resume(void) goto out; } + hif_system_pm_set_state_on(hif_ctx); + status = hif_bus_late_resume(hif_ctx); if (status) { hdd_err("Failed hif bus late resume"); @@ -1265,8 +1374,7 @@ int wlan_hdd_bus_resume(void) } dp_soc = cds_get_context(QDF_MODULE_ID_SOC); - dp_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - qdf_status = cdp_bus_resume(dp_soc, dp_pdev); + qdf_status = cdp_bus_resume(dp_soc, OL_TXRX_PDEV_ID); status = qdf_status_to_os_return(qdf_status); if (status) { hdd_err("Failed cdp bus resume"); @@ -1277,6 +1385,7 @@ int wlan_hdd_bus_resume(void) return 0; out: + hif_system_pm_set_state_suspended(hif_ctx); if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() || cds_is_fw_down()) return 0; @@ -1306,17 +1415,23 @@ int wlan_hdd_bus_resume_noirq(void) if (cds_is_driver_recovering()) return 0; - status = wlan_hdd_validate_context(hdd_ctx); - if (status) { - hdd_err("Invalid HDD context: %d", status); - return status; + if (!hdd_ctx) { + hdd_err_rl("hdd context is NULL"); + return -ENODEV; } + /* If Wifi is off, return success for system resume */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Module closed return success"); return 0; } + status = wlan_hdd_validate_context(hdd_ctx); + if (status) { + hdd_err("Invalid HDD context: %d", status); + return status; + } + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); if (!hif_ctx) return -EINVAL; @@ -1405,13 +1520,15 @@ static int wlan_hdd_runtime_suspend(struct device *dev) return -EBUSY; } + if (ucfg_ipa_is_tx_pending(hdd_ctx->pdev)) { + hdd_debug("IPA TX comps pending, ignore rtpm suspend"); + return -EBUSY; + } + status = ucfg_pmo_psoc_bus_runtime_suspend(hdd_ctx->psoc, hdd_pld_runtime_suspend_cb); err = qdf_status_to_os_return(status); - if (status == QDF_STATUS_SUCCESS) - hdd_bus_bw_compute_timer_stop(hdd_ctx); - hdd_ctx->runtime_suspend_done_time_stamp = qdf_get_log_timestamp_usecs(); delta = hdd_ctx->runtime_suspend_done_time_stamp - @@ -1422,6 +1539,11 @@ static int wlan_hdd_runtime_suspend(struct device *dev) hdd_debug("Runtime suspend done result: %d total cxpc up time %lu microseconds", err, delta); + if (status == QDF_STATUS_SUCCESS) + hdd_bus_bw_compute_timer_stop(hdd_ctx); + + hdd_debug("Runtime suspend done result: %d", err); + return err; } @@ -1459,8 +1581,12 @@ static int wlan_hdd_runtime_resume(struct device *dev) hdd_debug("Starting runtime resume"); hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (wlan_hdd_validate_context(hdd_ctx)) + + if (cds_is_driver_recovering()) { + hdd_debug("Recovery in progress, state:0x%x", + cds_get_driver_state()); return 0; + } if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver module closed skipping runtime resume"); @@ -1770,6 +1896,12 @@ static void wlan_hdd_pld_notify_handler(struct device *dev, static void wlan_hdd_pld_uevent(struct device *dev, struct pld_uevent_data *event_data) { + struct qdf_notifer_data hang_evt_data; + enum qdf_hang_reason reason = QDF_REASON_UNSPECIFIED; + uint8_t bus_type; + + bus_type = pld_get_bus_type(dev); + switch (event_data->uevent) { case PLD_FW_DOWN: hdd_info("Received firmware down indication"); @@ -1793,18 +1925,44 @@ wlan_hdd_pld_uevent(struct device *dev, struct pld_uevent_data *event_data) * thus defer the cleanup to be done during * hdd_soc_recovery_shutdown */ - if (qdf_in_interrupt()) + if (qdf_in_interrupt() || bus_type == PLD_BUS_TYPE_PCIE) break; hdd_soc_recovery_cleanup(); qdf_atomic_set(&is_recovery_cleanup_done, 1); + break; + case PLD_FW_HANG_EVENT: + hdd_info("Received firmware hang event"); + cds_get_recovery_reason(&reason); + hang_evt_data.hang_data = + qdf_mem_malloc(QDF_HANG_EVENT_DATA_SIZE); + if (!hang_evt_data.hang_data) + return; + hang_evt_data.offset = 0; + qdf_hang_event_notifier_call(reason, &hang_evt_data); + hang_evt_data.offset = QDF_WLAN_HANG_FW_OFFSET; + if (event_data->hang_data.hang_event_data_len >= + QDF_HANG_EVENT_DATA_SIZE / 2) + event_data->hang_data.hang_event_data_len = + QDF_HANG_EVENT_DATA_SIZE / 2; + if (event_data->hang_data.hang_event_data_len) + qdf_mem_copy((hang_evt_data.hang_data + + hang_evt_data.offset), + event_data->hang_data.hang_event_data, + event_data->hang_data.hang_event_data_len); + + hdd_send_hang_data(hang_evt_data.hang_data, + QDF_HANG_EVENT_DATA_SIZE); + qdf_mem_free(hang_evt_data.hang_data); + break; default: /* other events intentionally not handled */ hdd_debug("Received uevent %d", event_data->uevent); break; } + } #ifdef FEATURE_RUNTIME_PM diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.c index 2e4886df9c7b666ef6acda79c0598c3442032617..3eec3dcfefaa5a2eac0c866e2651b8a388db2605 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.c @@ -32,8 +32,7 @@ #include "cds_sched.h" #include #include "wlan_extscan_ucfg_api.h" - -#define EXTSCAN_PARAM_MAX QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +#include "wlan_hdd_scan.h" /* amount of time to wait for a synchronous request/response operation */ #define WLAN_WAIT_TIME_EXTSCAN 1000 @@ -59,86 +58,6 @@ struct hdd_ext_scan_context { }; static struct hdd_ext_scan_context ext_scan_context; -static const -struct nla_policy wlan_hdd_extscan_config_policy[EXTSCAN_PARAM_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = {.type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = {.type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = {.type = NLA_U8}, - - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = {.type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = {.type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = {.type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = { - .type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] = { - .type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] = { - .type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = { - .type = NLA_U8}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = { - .type = NLA_U8}, - - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = { - .type = NLA_UNSPEC, - .len = QDF_MAC_ADDR_SIZE}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = { - .type = NLA_S32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = { - .type = NLA_S32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = { - .type = NLA_U32}, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = { - .type = NLA_BINARY, - .len = IEEE80211_MAX_SSID_LEN + 1 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = { - .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] = { - .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] = { - .type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] = { - .type = NLA_S32 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] = { - .type = NLA_S32 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] = { - .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = { - .type = NLA_U32}, -}; - static const struct nla_policy wlan_hdd_pno_config_policy[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM] = { @@ -423,7 +342,7 @@ wlan_hdd_cfg80211_extscan_cached_results_ind(struct hdd_context *hdd_ctx, ap->ts += hdd_ctx->ext_scan_start_since_boot; hdd_debug("Timestamp %llu " "Ssid: %s " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "Rssi %d " "RTT %u " @@ -433,7 +352,7 @@ wlan_hdd_cfg80211_extscan_cached_results_ind(struct hdd_context *hdd_ctx, "Ie length %d", ap->ts, ap->ssid, - QDF_MAC_ADDR_ARRAY(ap->bssid.bytes), + QDF_MAC_ADDR_REF(ap->bssid.bytes), ap->channel, ap->rssi, ap->rtt, @@ -587,7 +506,7 @@ wlan_hdd_cfg80211_extscan_hotlist_match_ind(struct hdd_context *hdd_ctx, hdd_debug("[i=%d] Timestamp %llu " "Ssid: %s " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "Rssi %d " "RTT %u " @@ -595,7 +514,7 @@ wlan_hdd_cfg80211_extscan_hotlist_match_ind(struct hdd_context *hdd_ctx, i, data->ap[i].ts, data->ap[i].ssid, - QDF_MAC_ADDR_ARRAY(data->ap[i].bssid.bytes), + QDF_MAC_ADDR_REF(data->ap[i].bssid.bytes), data->ap[i].channel, data->ap[i].rssi, data->ap[i].rtt, data->ap[i].rtt_sd); @@ -717,11 +636,11 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind( ap_info = &data->ap[0]; for (i = 0; i < data->numResults; i++) { hdd_debug("[i=%d] " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "numOfRssi %d", i, - QDF_MAC_ADDR_ARRAY(ap_info->bssid.bytes), + QDF_MAC_ADDR_REF(ap_info->bssid.bytes), ap_info->channel, ap_info->numOfRssi); rssi = &(ap_info)->rssi[0]; for (j = 0; j < ap_info->numOfRssi; j++) @@ -812,7 +731,6 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(struct hdd_context *hdd_ctx, data) { struct sk_buff *skb; - struct timespec ts; struct hdd_ext_scan_context *context; int flags = cds_get_gfp_flags(); @@ -848,13 +766,12 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(struct hdd_context *hdd_ctx, * Android does not want the time stamp from the frame. * Instead it wants a monotonic increasing value since boot */ - get_monotonic_boottime(&ts); - data->ap.ts = ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); + data->ap.ts = qdf_get_monotonic_boottime(); hdd_debug("Req Id %u More Data %u", data->requestId, data->moreData); hdd_debug("AP Info: Timestamp %llu Ssid: %s " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "Rssi %d " "RTT %u " @@ -864,7 +781,7 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(struct hdd_context *hdd_ctx, "IE Length %d", data->ap.ts, data->ap.ssid, - QDF_MAC_ADDR_ARRAY(data->ap.bssid.bytes), + QDF_MAC_ADDR_REF(data->ap.bssid.bytes), data->ap.channel, data->ap.rssi, data->ap.rtt, @@ -1131,7 +1048,7 @@ wlan_hdd_cfg80211_extscan_epno_match_found(struct hdd_context *hdd_ctx, for (i = 0; i < data->num_results; i++) { data->ap[i].channel = cds_chan_to_freq(data->ap[i].channel); hdd_debug("AP Info: Timestamp %llu) Ssid: %s " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "Rssi %d " "RTT %u " @@ -1141,7 +1058,7 @@ wlan_hdd_cfg80211_extscan_epno_match_found(struct hdd_context *hdd_ctx, "IE Length %d", data->ap[i].ts, data->ap[i].ssid, - QDF_MAC_ADDR_ARRAY(data->ap[i].bssid.bytes), + QDF_MAC_ADDR_REF(data->ap[i].bssid.bytes), data->ap[i].channel, data->ap[i].rssi, data->ap[i].rtt, @@ -1237,7 +1154,7 @@ wlan_hdd_cfg80211_passpoint_match_found(void *ctx, data->request_id, data->id, data->anqp_len, num_matches); for (i = 0; i < num_matches; i++) { hdd_debug("AP Info: Timestamp %llu Ssid: %s " - "Bssid (" QDF_MAC_ADDR_STR ") " + "Bssid (" QDF_MAC_ADDR_FMT ") " "Channel %u " "Rssi %d " "RTT %u " @@ -1247,7 +1164,7 @@ wlan_hdd_cfg80211_passpoint_match_found(void *ctx, "IE Length %d", data->ap.ts, data->ap.ssid, - QDF_MAC_ADDR_ARRAY(data->ap.bssid.bytes), + QDF_MAC_ADDR_REF(data->ap.bssid.bytes), data->ap.channel, data->ap.rssi, data->ap.rtt, @@ -1880,8 +1797,8 @@ static int hdd_parse_ap_rssi_threshold(struct nlattr *attr, return -EINVAL; } nla_memcpy(ap->bssid.bytes, tb[id], QDF_MAC_ADDR_SIZE); - hdd_debug("BSSID: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(ap->bssid.bytes)); + hdd_debug("BSSID: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(ap->bssid.bytes)); /* Parse and fetch low RSSI */ id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW; @@ -2291,226 +2208,6 @@ int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy, return errno; } -/** - * hdd_remove_dsrc_channels () - remove dsrc chanels - * @hdd_ctx: hdd context - * @wiphy: Pointer to wireless phy - * @chan_list: channel list - * @num_channels: number of channels - * - * Return: none - */ -static void hdd_remove_dsrc_channels(struct hdd_context *hdd_ctx, - struct wiphy *wiphy, uint32_t *chan_list, - uint8_t *num_channels) -{ - uint8_t num_chan_temp = 0; - int i; - - for (i = 0; i < *num_channels; i++) { - if (!wlan_reg_is_dsrc_chan(hdd_ctx->pdev, - wlan_reg_freq_to_chan( - hdd_ctx->pdev, - chan_list[i]))) { - chan_list[num_chan_temp] = chan_list[i]; - num_chan_temp++; - } - } - *num_channels = num_chan_temp; -} - -/** - * hdd_remove_passive_channels () - remove passive channels - * @wiphy: Pointer to wireless phy - * @chan_list: channel list - * @num_channels: number of channels - * - * Return: none - */ -static void hdd_remove_passive_channels(struct wiphy *wiphy, - uint32_t *chan_list, - uint8_t *num_channels) -{ - uint8_t num_chan_temp = 0; - int i, j, k; - - for (i = 0; i < *num_channels; i++) - for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) { - if (!wiphy->bands[j]) - continue; - for (k = 0; k < wiphy->bands[j]->n_channels; k++) { - if ((chan_list[i] == - wiphy->bands[j]->channels[k].center_freq) - && (!(wiphy->bands[j]->channels[k].flags & - IEEE80211_CHAN_PASSIVE_SCAN)) - ) { - chan_list[num_chan_temp] = chan_list[i]; - num_chan_temp++; - } - } - } - - *num_channels = num_chan_temp; -} - -/** - * __wlan_hdd_cfg80211_extscan_get_valid_channels () - get valid channels - * @wiphy: Pointer to wireless phy - * @wdev: Pointer to wireless device - * @data: Pointer to data - * @data_len: Data length - * - * Return: none - */ -static int -__wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, - struct wireless_dev - *wdev, const void *data, - int data_len) -{ - struct hdd_context *hdd_ctx = wiphy_priv(wiphy); - struct net_device *dev = wdev->netdev; - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - uint32_t chan_list[CFG_VALID_CHANNEL_LIST_LEN] = {0}; - uint8_t num_channels = 0, i, buf[256] = {0}; - struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + - 1]; - uint32_t requestId, maxChannels; - tWifiBand wifi_band; - QDF_STATUS status; - struct sk_buff *reply_skb; - int ret, len = 0; - - /* ENTER_DEV() intentionally not used in a frequently invoked API */ - - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); - return -EPERM; - } - - ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) - return -EINVAL; - - if (wlan_cfg80211_nla_parse(tb, - QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, - data, data_len, wlan_hdd_extscan_config_policy)) { - hdd_err("Invalid ATTR"); - return -EINVAL; - } - - /* Parse and fetch request Id */ - if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { - hdd_err("attr request id failed"); - return -EINVAL; - } - requestId = - nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); - - /* Parse and fetch wifi band */ - if (!tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]) { - hdd_err("attr wifi band failed"); - return -EINVAL; - } - wifi_band = - nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]); - - if (!tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]) { - hdd_err("attr max channels failed"); - return -EINVAL; - } - maxChannels = - nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]); - - if (maxChannels > CFG_VALID_CHANNEL_LIST_LEN) { - hdd_err("Max channels %d exceeded Valid channel list len %d", - maxChannels, CFG_VALID_CHANNEL_LIST_LEN); - return -EINVAL; - } - - hdd_debug("Req Id: %u Wifi band: %d Max channels: %d", requestId, - wifi_band, maxChannels); - status = sme_get_valid_channels_by_band(hdd_ctx->mac_handle, - wifi_band, chan_list, - &num_channels); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("sme_get_valid_channels_by_band failed (err=%d)", - status); - return -EINVAL; - } - - num_channels = QDF_MIN(num_channels, maxChannels); - - hdd_remove_dsrc_channels(hdd_ctx, wiphy, chan_list, &num_channels); - if ((QDF_SAP_MODE == adapter->device_mode) || - !strncmp(hdd_get_fwpath(), "ap", 2)) - hdd_remove_passive_channels(wiphy, chan_list, - &num_channels); - - hdd_debug("Number of channels: %d", num_channels); - for (i = 0; i < num_channels; i++) - len += scnprintf(buf + len, sizeof(buf) - len, - "%u ", chan_list[i]); - - hdd_debug("Channels: %s", buf); - - reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + - sizeof(u32) * - num_channels + - NLMSG_HDRLEN); - - if (reply_skb) { - if (nla_put_u32(reply_skb, - QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS, - num_channels) || - nla_put(reply_skb, - QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS, - sizeof(u32) * num_channels, chan_list)) { - hdd_err("nla put fail"); - kfree_skb(reply_skb); - return -EINVAL; - } - ret = cfg80211_vendor_cmd_reply(reply_skb); - return ret; - } - - hdd_err("valid channels: buffer alloc fail"); - return -EINVAL; -} - -/** - * wlan_hdd_cfg80211_extscan_get_valid_channels() - get ext scan valid channels - * @wiphy: Pointer to wireless phy - * @wdev: Pointer to wireless device - * @data: Pointer to data - * @data_len: Data length - * - * Return: 0 on success, negative errno on failure - */ -int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, - struct wireless_dev *wdev, - const void *data, int data_len) -{ - struct osif_psoc_sync *psoc_sync; - int errno; - - errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); - if (errno) - return errno; - - errno = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, - data, data_len); - - osif_psoc_sync_op_stop(psoc_sync); - - return errno; -} - /** * hdd_extscan_update_dwell_time_limits() - update dwell times * @req_msg: Pointer to request message diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.h index c515c424e7cba9a0ef25503934c89a3cdcdea2a0..bf3be445f95a162793d9b9f5a940287d4fed22ff 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ext_scan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,18 +26,14 @@ * */ -#include "wlan_hdd_main.h" struct hdd_context; #define EXTSCAN_EVENT_BUF_SIZE 4096 -int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, - struct wireless_dev - *wdev, const void *data, - int data_len); - #ifdef FEATURE_WLAN_EXTSCAN +#include "wlan_hdd_main.h" + /* * Used to allocate the size of 4096 for the EXTScan NL data. * The size of 4096 is considered assuming that all data per diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_gpio.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..b2a48695506de8baf26b5cf1cec507ba3f1edbea --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_gpio.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: defines driver functions interfacing with linux kernel + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_hdd_main.h" +#include "cfg_ucfg_api.h" +#include + +/** + * wlan_cfg80211_set_gpio_config - Set the gpio configuration + * @wiphy: pointer to wiphy + * @wdev: pointer to wireless_wdev + * @data: pointer to data + * @data_len: data length + * + * __wlan_cfg80211_set_gpio_config will forward the GPIO setting to FW by + * WMI_GPIO_CONFIG/OUTPUT_CMDID + * + * Return: 0 on success; errno on failure + */ +static int +__wlan_hdd_cfg80211_set_gpio_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter; + + hdd_enter(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + adapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + return -EINVAL; + + ret = wlan_cfg80211_start_gpio_config(wiphy, + hdd_ctx->psoc, + data, data_len); + hdd_exit(); + + return ret; +} + +/** + * wlan_hdd_cfg80211_set_gpio_config() - Set GPIO Configuration + * @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 + */ +int wlan_hdd_cfg80211_set_gpio_config(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int errno; + + errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (errno) + return errno; + + hdd_err("__DEBUG__"); + errno = __wlan_hdd_cfg80211_set_gpio_config(wiphy, + wdev, + data, + data_len); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno; +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hang_event.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hang_event.c new file mode 100644 index 0000000000000000000000000000000000000000..ef793545b54bddc161a7de66fb94e42b0bf5813a --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hang_event.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * 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. + */ +#include +#include +#include +#include +#include "wlan_hdd_object_manager.h" +#include + +struct hdd_hang_event_fixed_param { + uint16_t tlv_header; + uint8_t vdev_id; + uint8_t vdev_opmode; + uint8_t vdev_state; + uint8_t vdev_substate; +} qdf_packed; + +struct hdd_scan_fixed_param { + uint16_t tlv_header; + uint8_t last_scan_reject_vdev_id; + enum scan_reject_states last_scan_reject_reason; + unsigned long last_scan_reject_timestamp; + uint8_t scan_reject_cnt; +} qdf_packed; + +static int wlan_hdd_recovery_notifier_call(struct notifier_block *block, + unsigned long state, + void *data) +{ + qdf_notif_block *notif_block = qdf_container_of(block, qdf_notif_block, + notif_block); + struct hdd_context *hdd_ctx; + struct qdf_notifer_data *hdd_hang_data = data; + uint8_t *hdd_buf_ptr; + struct hdd_adapter *adapter, *next_adapter = NULL; + uint32_t total_len; + struct wlan_objmgr_vdev *vdev; + struct hdd_hang_event_fixed_param *cmd; + struct hdd_scan_fixed_param *cmd_scan; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL; + + if (!data) + return NOTIFY_STOP_MASK; + + hdd_ctx = notif_block->priv_data; + if (!hdd_ctx) + return NOTIFY_STOP_MASK; + + if (state == QDF_SCAN_ATTEMPT_FAILURES) { + total_len = sizeof(*cmd_scan); + hdd_buf_ptr = hdd_hang_data->hang_data + hdd_hang_data->offset; + if (hdd_hang_data->offset + total_len > QDF_WLAN_HANG_FW_OFFSET) + return NOTIFY_STOP_MASK; + cmd_scan = (struct hdd_scan_fixed_param *)hdd_buf_ptr; + QDF_HANG_EVT_SET_HDR(&cmd_scan->tlv_header, + HANG_EVT_TAG_OS_IF_SCAN, + QDF_HANG_GET_STRUCT_TLVLEN(struct hdd_scan_fixed_param)); + cmd_scan->last_scan_reject_vdev_id = + hdd_ctx->last_scan_reject_vdev_id; + cmd_scan->last_scan_reject_reason = + hdd_ctx->last_scan_reject_reason; + cmd_scan->scan_reject_cnt = + hdd_ctx->scan_reject_cnt; + hdd_hang_data->offset += total_len; + } + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + hdd_adapter_dev_put_debug(adapter, dbgid); + continue; + } + total_len = sizeof(*cmd); + hdd_buf_ptr = hdd_hang_data->hang_data + hdd_hang_data->offset; + if (hdd_hang_data->offset + total_len > + QDF_WLAN_HANG_FW_OFFSET) { + hdd_objmgr_put_vdev(vdev); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); + return NOTIFY_STOP_MASK; + } + cmd = (struct hdd_hang_event_fixed_param *)hdd_buf_ptr; + QDF_HANG_EVT_SET_HDR(&cmd->tlv_header, + HANG_EVT_TAG_OS_IF, + QDF_HANG_GET_STRUCT_TLVLEN(struct hdd_hang_event_fixed_param)); + cmd->vdev_id = wlan_vdev_get_id(vdev); + cmd->vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); + cmd->vdev_state = wlan_vdev_mlme_get_state(vdev); + cmd->vdev_substate = wlan_vdev_mlme_get_substate(vdev); + hdd_hang_data->offset += total_len; + hdd_objmgr_put_vdev(vdev); + hdd_adapter_dev_put_debug(adapter, dbgid); + } + + return NOTIFY_OK; +} + +static qdf_notif_block hdd_recovery_notifier = { + .notif_block.notifier_call = wlan_hdd_recovery_notifier_call, +}; + +QDF_STATUS wlan_hdd_hang_event_notifier_register(struct hdd_context *hdd_ctx) +{ + hdd_recovery_notifier.priv_data = hdd_ctx; + return qdf_hang_event_register_notifier(&hdd_recovery_notifier); +} + +QDF_STATUS wlan_hdd_hang_event_notifier_unregister(void) +{ + return qdf_hang_event_unregister_notifier(&hdd_recovery_notifier); +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c index 4e4b35e3437a4ac093226df38c440e9182f85f6f..bea7dcf0d8aa53dc5655a007bca9d4dbe7fc4211 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -91,6 +91,7 @@ #include "wlan_fwol_ucfg_api.h" #include "nan_ucfg_api.h" #include +#include "wlan_hdd_sta_info.h" #define ACS_SCAN_EXPIRY_TIMEOUT_S 4 @@ -106,6 +107,12 @@ #define HDD_MAX_CUSTOM_START_EVENT_SIZE 64 +#ifdef NDP_SAP_CONCURRENCY_ENABLE +#define MAX_SAP_NUM_CONCURRENCY_WITH_NAN 2 +#else +#define MAX_SAP_NUM_CONCURRENCY_WITH_NAN 1 +#endif + #ifndef BSS_MEMBERSHIP_SELECTOR_HT_PHY #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 #endif @@ -205,7 +212,7 @@ static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = { {6, {5265, 5850}, {2430, 2700}, {1170, 1300} }, {7, {5850, 6500}, {2700, 3000}, {1300, 1444} }, {8, {7020, 7800}, {3240, 3600}, {1560, 1733} }, - {9, {7800, 8667}, {3600, 4000}, {1560, 1733} } + {9, {7800, 8667}, {3600, 4000}, {1730, 1920} } }; /* Function definitions */ @@ -323,32 +330,33 @@ static int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter) * Called when, 1. bss stopped, 2. channel switch * * @adapter: pointer to hdd adapter - * @channel: current channel + * @chan_freq: current channel frequency * * Return: None */ static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter, - uint8_t channel) + uint32_t chan_freq) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_hostapd_state *hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); - hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d", - hostapd_state->bss_state, channel, - atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); + hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d", + hostapd_state->bss_state, chan_freq, + atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); /* Return if BSS is already stopped */ if (hostapd_state->bss_state == BSS_STOP) return; - if (!wlan_reg_chan_has_dfs_attribute(hdd_ctx->pdev, channel)) + if (!wlan_reg_chan_has_dfs_attribute_for_freq(hdd_ctx->pdev, + chan_freq)) return; /* Release wakelock when no more DFS channels are used */ if (atomic_dec_and_test(&hdd_ctx->sap_dfs_ref_cnt)) { - hdd_err("DFS: allowing suspend (chan: %d)", channel); + hdd_err("DFS: allowing suspend (chan_freq: %d)", chan_freq); qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock, WIFI_POWER_EVENT_WAKELOCK_DFS); qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.dfs); @@ -361,31 +369,32 @@ static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter, * Called when, 1. bss started, 2. channel switch * * @adapter: pointer to hdd adapter - * @channel: current channel + * @chna_freq: current channel frequency * * Return - None */ static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter, - uint8_t channel) + uint32_t chan_freq) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_hostapd_state *hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); - hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d", - hostapd_state->bss_state, channel, - atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); + hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d", + hostapd_state->bss_state, chan_freq, + atomic_read(&hdd_ctx->sap_dfs_ref_cnt)); /* Return if BSS is already started && wakelock is acquired */ if ((hostapd_state->bss_state == BSS_START) && (atomic_read(&hdd_ctx->sap_dfs_ref_cnt) >= 1)) return; - if (!wlan_reg_chan_has_dfs_attribute(hdd_ctx->pdev, channel)) + if (!wlan_reg_chan_has_dfs_attribute_for_freq(hdd_ctx->pdev, + chan_freq)) return; /* Acquire wakelock if we have at least one DFS channel in use */ if (atomic_inc_return(&hdd_ctx->sap_dfs_ref_cnt) == 1) { - hdd_err("DFS: preventing suspend (chan: %d)", channel); + hdd_err("DFS: preventing suspend (chan_freq: %d)", chan_freq); qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.dfs); qdf_wake_lock_acquire(&hdd_ctx->sap_dfs_wakelock, WIFI_POWER_EVENT_WAKELOCK_DFS); @@ -704,9 +713,9 @@ static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) if (adapter_temp) { if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) return 0; - hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_STR, + hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, adapter_temp->dev->name, - QDF_MAC_ADDR_ARRAY(mac_addr.bytes)); + QDF_MAC_ADDR_REF(mac_addr.bytes)); return -EINVAL; } @@ -725,8 +734,8 @@ static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) return -EINVAL; } - hdd_debug("Changing MAC to " QDF_MAC_ADDR_STR " of interface %s ", - QDF_MAC_ADDR_ARRAY(mac_addr.bytes), + hdd_debug("Changing MAC to " QDF_MAC_ADDR_FMT " of interface %s ", + QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); @@ -758,19 +767,15 @@ static int hdd_hostapd_set_mac_address(struct net_device *net_dev, void *addr) return errno; } -static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id) +static void hdd_clear_sta(struct hdd_adapter *adapter, + struct hdd_station_info *sta_info) { struct hdd_ap_ctx *ap_ctx; - struct hdd_station_info *sta_info; struct csr_del_sta_params del_sta_params; ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - if (sta_id == ap_ctx->broadcast_sta_id) - return; - - sta_info = &adapter->sta_info[sta_id]; - if (!sta_info->in_use) + if (qdf_is_macaddr_broadcast(&sta_info->sta_mac)) return; wlansap_populate_del_sta_params(sta_info->sta_mac.bytes, @@ -783,11 +788,16 @@ static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id) static void hdd_clear_all_sta(struct hdd_adapter *adapter) { - uint8_t sta_id; + struct hdd_station_info *sta_info, *tmp = NULL; hdd_enter_dev(adapter->dev); - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) - hdd_clear_sta(adapter, sta_id); + + hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, + STA_INFO_HDD_CLEAR_ALL_STA) { + hdd_clear_sta(adapter, sta_info); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_HDD_CLEAR_ALL_STA); + } } static int hdd_stop_bss_link(struct hdd_adapter *adapter) @@ -849,7 +859,7 @@ QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter, return QDF_STATUS_E_FAILURE; } - freq = cds_chan_to_freq(chan_change.chan); + freq = chan_change.chan_freq; chan = ieee80211_get_channel(adapter->wdev.wiphy, freq); @@ -890,9 +900,9 @@ QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter, break; case CH_WIDTH_80P80MHZ: chandef.width = NL80211_CHAN_WIDTH_80P80; - if (chan_change.chan_params.center_freq_seg1) - chandef.center_freq2 = cds_chan_to_freq( - chan_change.chan_params.center_freq_seg1); + if (chan_change.chan_params.mhz_freq_seg1) + chandef.center_freq2 = + chan_change.chan_params.mhz_freq_seg1; break; case CH_WIDTH_160MHZ: chandef.width = NL80211_CHAN_WIDTH_160; @@ -904,9 +914,9 @@ QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter, if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) || (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) || (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) { - if (chan_change.chan_params.center_freq_seg0) - chandef.center_freq1 = cds_chan_to_freq( - chan_change.chan_params.center_freq_seg0); + if (chan_change.chan_params.mhz_freq_seg0) + chandef.center_freq1 = + chan_change.chan_params.mhz_freq_seg0; } hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d", @@ -1157,7 +1167,7 @@ static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->vdev_id, CSA_REASON_PRE_CAC_SUCCESS); i = hdd_softap_set_channel_change(ap_adapter->dev, - ap_adapter->pre_cac_chan, + ap_adapter->pre_cac_freq, CH_WIDTH_MAX, false); if (0 != i) { hdd_err("failed to change channel"); @@ -1205,7 +1215,7 @@ static QDF_STATUS hdd_handle_acs_scan_event(struct sap_event *sap_event, struct hdd_context *hdd_ctx; struct sap_acs_scan_complete_event *comp_evt; QDF_STATUS qdf_status; - int chan_list_size; + int freq_list_size; hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (!hdd_ctx) { @@ -1215,22 +1225,22 @@ static QDF_STATUS hdd_handle_acs_scan_event(struct sap_event *sap_event, comp_evt = &sap_event->sapevt.sap_acs_scan_comp; hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; qdf_spin_lock(&hdd_ctx->acs_skip_lock); - qdf_mem_free(hdd_ctx->last_acs_channel_list); - hdd_ctx->last_acs_channel_list = NULL; + qdf_mem_free(hdd_ctx->last_acs_freq_list); + hdd_ctx->last_acs_freq_list = NULL; hdd_ctx->num_of_channels = 0; /* cache the previous ACS scan channel list . * If the following OBSS scan chan list is covered by ACS chan list, * we can skip OBSS Scan to save SAP starting total time. */ - if (comp_evt->num_of_channels && comp_evt->channellist) { - chan_list_size = comp_evt->num_of_channels * - sizeof(comp_evt->channellist[0]); - hdd_ctx->last_acs_channel_list = qdf_mem_malloc( - chan_list_size); - if (hdd_ctx->last_acs_channel_list) { - qdf_mem_copy(hdd_ctx->last_acs_channel_list, - comp_evt->channellist, - chan_list_size); + if (comp_evt->num_of_channels && comp_evt->freq_list) { + freq_list_size = comp_evt->num_of_channels * + sizeof(comp_evt->freq_list[0]); + hdd_ctx->last_acs_freq_list = qdf_mem_malloc( + freq_list_size); + if (hdd_ctx->last_acs_freq_list) { + qdf_mem_copy(hdd_ctx->last_acs_freq_list, + comp_evt->freq_list, + freq_list_size); hdd_ctx->num_of_channels = comp_evt->num_of_channels; } } @@ -1356,6 +1366,10 @@ static int calcuate_max_phy_rate(int mode, int nss, int ch_width, if (mode == SIR_SME_PHY_MODE_HT) { /* check for HT Mode */ maxidx = ht_mcs_idx; + if (maxidx > 7) { + hdd_err("ht_mcs_idx %d is incorrect", ht_mcs_idx); + return maxrate; + } if (nss == 1) { supported_mcs_rate = supported_mcs_rate_nss1; } else if (nss == 2) { @@ -1455,17 +1469,14 @@ static int hdd_convert_dot11mode_from_phymode(int phymode) static void hdd_fill_station_info(struct hdd_adapter *adapter, tSap_StationAssocReassocCompleteEvent *event) { - struct hdd_station_info *stainfo; - uint8_t i = 0, oldest_disassoc_sta_idx = WLAN_MAX_STA_COUNT + 1; + struct hdd_station_info *stainfo, *cache_sta_info; + struct hdd_station_info *oldest_disassoc_sta_info = NULL; qdf_time_t oldest_disassoc_sta_ts = 0; bool is_dot11_mode_abgn; - if (event->staId >= WLAN_MAX_STA_COUNT) { - hdd_err("invalid sta id"); - return; - } - - stainfo = &adapter->sta_info[event->staId]; + stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + event->staMac.bytes, + STA_INFO_FILL_STATION_INFO); if (!stainfo) { hdd_err("invalid stainfo"); @@ -1474,7 +1485,7 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter, qdf_mem_copy(&stainfo->capability, &event->capability_info, sizeof(uint16_t)); - stainfo->freq = cds_chan_to_freq(event->chan_info.chan_id); + stainfo->freq = event->chan_info.mhz; stainfo->sta_type = event->staType; stainfo->dot11_mode = hdd_convert_dot11mode_from_phymode(event->chan_info.info); @@ -1511,6 +1522,7 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter, * should always be true. */ is_dot11_mode_abgn = true; + stainfo->ecsa_capable = event->ecsa_capable; if (event->vht_caps.present) { stainfo->vht_present = true; @@ -1535,61 +1547,74 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter, stainfo->dhcp_phase = DHCP_PHASE_ACK; stainfo->dhcp_nego_status = DHCP_NEGO_STOP; - while (i < WLAN_MAX_STA_COUNT) { - if (!qdf_mem_cmp(adapter->cache_sta_info[i].sta_mac.bytes, - event->staMac.bytes, - QDF_MAC_ADDR_SIZE)) - break; - i++; - } - if (i >= WLAN_MAX_STA_COUNT) { - i = 0; - while (i < WLAN_MAX_STA_COUNT) { - if (adapter->cache_sta_info[i].in_use != TRUE) - break; + cache_sta_info = + hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list, + event->staMac.bytes, + STA_INFO_FILL_STATION_INFO); - if (adapter->cache_sta_info[i].disassoc_ts && - (!oldest_disassoc_sta_ts || - (qdf_system_time_after( - oldest_disassoc_sta_ts, - adapter-> - cache_sta_info[i].disassoc_ts)))) { - oldest_disassoc_sta_ts = - adapter-> - cache_sta_info[i].disassoc_ts; - oldest_disassoc_sta_idx = i; - } - i++; - } - } + if (!cache_sta_info) { + cache_sta_info = qdf_mem_malloc(sizeof(*cache_sta_info)); + if (!cache_sta_info) + goto exit; - if ((i == WLAN_MAX_STA_COUNT) && oldest_disassoc_sta_ts) { - hdd_debug("reached max cached sta_id, removing oldest stainfo"); - i = oldest_disassoc_sta_idx; - } - if (i < WLAN_MAX_STA_COUNT) { - if (adapter->cache_sta_info[i].assoc_req_ies.data) { - qdf_mem_free( - adapter->cache_sta_info[i].assoc_req_ies.data); - adapter->cache_sta_info[i].assoc_req_ies.data = NULL; - adapter->cache_sta_info[i].assoc_req_ies.len = 0; - } - qdf_mem_zero(&adapter->cache_sta_info[i], - sizeof(*stainfo)); - qdf_mem_copy(&adapter->cache_sta_info[i], - stainfo, sizeof(struct hdd_station_info)); - adapter->cache_sta_info[i].assoc_req_ies.data = + qdf_mem_copy(cache_sta_info, stainfo, sizeof(*cache_sta_info)); + cache_sta_info->is_attached = 0; + cache_sta_info->assoc_req_ies.data = qdf_mem_malloc(event->ies_len); - if (adapter->cache_sta_info[i].assoc_req_ies.data) { - qdf_mem_copy( - adapter->cache_sta_info[i].assoc_req_ies.data, - event->ies, event->ies_len); - adapter->cache_sta_info[i].assoc_req_ies.len = - event->ies_len; + if (cache_sta_info->assoc_req_ies.data) { + qdf_mem_copy(cache_sta_info->assoc_req_ies.data, + event->ies, event->ies_len); + cache_sta_info->assoc_req_ies.len = event->ies_len; } + qdf_atomic_init(&cache_sta_info->ref_cnt); + + /* + * If cache_sta_info is not present and cache limit is not + * reached, then create and attach. Else find the cache that is + * the oldest and replace that with the new cache. + */ + if (qdf_atomic_read(&adapter->cache_sta_count) < + WLAN_MAX_STA_COUNT) { + hdd_sta_info_attach(&adapter->cache_sta_info_list, + cache_sta_info); + qdf_atomic_inc(&adapter->cache_sta_count); + } else { + struct hdd_station_info *temp_sta_info, *tmp = NULL; + struct hdd_sta_info_obj *sta_list = + &adapter->cache_sta_info_list; + + hdd_debug("reached max caching, removing oldest"); + + /* Find the oldest cached station */ + hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list, + temp_sta_info, tmp, + STA_INFO_FILL_STATION_INFO) { + if (temp_sta_info->disassoc_ts && + (!oldest_disassoc_sta_ts || + qdf_system_time_after( + oldest_disassoc_sta_ts, + temp_sta_info->disassoc_ts))) { + oldest_disassoc_sta_ts = + temp_sta_info->disassoc_ts; + oldest_disassoc_sta_info = + temp_sta_info; + } + hdd_put_sta_info_ref( + sta_list, &temp_sta_info, + true, + STA_INFO_FILL_STATION_INFO); + } + /* Remove the oldest and store the current */ + hdd_sta_info_detach(&adapter->cache_sta_info_list, + &oldest_disassoc_sta_info); + hdd_sta_info_attach(&adapter->cache_sta_info_list, + cache_sta_info); + } } else { - hdd_debug("reached max sta_id, stainfo can't be cached"); + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, + &cache_sta_info, true, + STA_INFO_FILL_STATION_INFO); } hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d", @@ -1610,6 +1635,10 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter, stainfo->max_mcs_idx, stainfo->rx_mcs_map, stainfo->tx_mcs_map); +exit: + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_FILL_STATION_INFO); + return; } void hdd_stop_sap_due_to_invalid_channel(struct work_struct *work) @@ -1657,7 +1686,7 @@ hdd_hostapd_apply_action_oui(struct hdd_context *hdd_ctx, if (ch_width != eHT_CHANNEL_WIDTH_20MHZ) return; - freq = cds_chan_to_freq(event->chan_info.chan_id); + freq = event->chan_info.mhz; if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) attr.enable_2g = true; else if (WLAN_REG_IS_5GHZ_CH_FREQ(freq)) @@ -1686,7 +1715,6 @@ hdd_hostapd_apply_action_oui(struct hdd_context *hdd_ctx, hdd_err("Failed to disable aggregation for peer"); } -#ifdef CRYPTO_SET_KEY_CONVERGED static void hdd_hostapd_set_sap_key(struct hdd_adapter *adapter) { struct wlan_crypto_key *crypto_key; @@ -1705,34 +1733,66 @@ static void hdd_hostapd_set_sap_key(struct hdd_adapter *adapter) wma_update_set_key(adapter->vdev_id, true, 0, crypto_key->cipher_type); } -#else -static void hdd_hostapd_set_sap_key(struct hdd_adapter *adapter) -{ - struct hdd_ap_ctx *ap_ctx; - QDF_STATUS status; - uint8_t i; - ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - /* Set group key / WEP key every time when BSS is restarted */ - if (ap_ctx->group_key.keyLength) { - status = wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter), - &ap_ctx->group_key); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("wlansap_set_key_sta failed"); - } else { - for (i = 0; i < CSR_MAX_NUM_KEY; i++) { - if (!ap_ctx->wep_key[i].keyLength) - continue; +/** + * hdd_hostapd_chan_change() - prepare new operation chan info to kernel + * @adapter: pointre to hdd_adapter + * @sap_event: pointer to sap_event + * + * Return: QDF_STATUS + */ +static QDF_STATUS hdd_hostapd_chan_change(struct hdd_adapter *adapter, + struct sap_event *sap_event) +{ + struct hdd_chan_change_params chan_change; + struct ch_params sap_ch_param = {0}; + eCsrPhyMode phy_mode; + bool legacy_phymode; + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct sap_ch_selected_s *sap_chan_selected = + &sap_event->sapevt.sap_ch_selected; + + sap_ch_param.ch_width = sap_chan_selected->ch_width; + sap_ch_param.mhz_freq_seg0 = + sap_chan_selected->vht_seg0_center_ch_freq; + sap_ch_param.mhz_freq_seg1 = + sap_chan_selected->vht_seg1_center_ch_freq; + + wlan_reg_set_channel_params_for_freq( + hdd_ctx->pdev, + sap_chan_selected->pri_ch_freq, + sap_chan_selected->ht_sec_ch_freq, + &sap_ch_param); + + phy_mode = wlan_sap_get_phymode( + WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - status = wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR - (adapter), - &ap_ctx->wep_key[i]); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("set_key failed idx: %d", i); - } + switch (phy_mode) { + case eCSR_DOT11_MODE_11n: + case eCSR_DOT11_MODE_11n_ONLY: + case eCSR_DOT11_MODE_11ac: + case eCSR_DOT11_MODE_11ac_ONLY: + case eCSR_DOT11_MODE_11ax: + case eCSR_DOT11_MODE_11ax_ONLY: + legacy_phymode = false; + break; + default: + legacy_phymode = true; + break; } + + chan_change.chan_freq = sap_chan_selected->pri_ch_freq; + chan_change.chan_params.ch_width = sap_chan_selected->ch_width; + chan_change.chan_params.sec_ch_offset = + sap_ch_param.sec_ch_offset; + chan_change.chan_params.mhz_freq_seg0 = + sap_chan_selected->vht_seg0_center_ch_freq; + chan_change.chan_params.mhz_freq_seg1 = + sap_chan_selected->vht_seg1_center_ch_freq; + + return hdd_chan_change_notify(adapter, adapter->dev, + chan_change, legacy_phymode); } -#endif QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, void *context) @@ -1761,17 +1821,14 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN; struct hdd_adapter *con_sap_adapter; QDF_STATUS status = QDF_STATUS_SUCCESS; - struct hdd_chan_change_params chan_change; tSap_StationAssocReassocCompleteEvent *event; tSap_StationSetKeyCompleteEvent *key_complete; int ret = 0; - struct ch_params sap_ch_param = {0}; - eCsrPhyMode phy_mode; - bool legacy_phymode; tSap_StationDisassocCompleteEvent *disassoc_comp; - struct hdd_station_info *stainfo, *cache_stainfo; + struct hdd_station_info *stainfo, *cache_stainfo, *tmp = NULL; mac_handle_t mac_handle; struct sap_config *sap_config; + struct sap_context *sap_ctx = NULL; dev = context; if (!dev) { @@ -1812,7 +1869,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, } mac_handle = hdd_ctx->mac_handle; - dfs_info.channel = ap_ctx->operating_channel; + dfs_info.channel = wlan_reg_freq_to_chan( + hdd_ctx->pdev, ap_ctx->operating_chan_freq); sme_get_country_code(mac_handle, dfs_info.country_code, &cc_len); sta_id = sap_event->sapevt.sapStartBssCompleteEvent.staId; sap_config = &adapter->session.ap.sap_config; @@ -1823,28 +1881,27 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, sap_event->sapevt.sapStartBssCompleteEvent. status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS", sap_event->sapevt.sapStartBssCompleteEvent. - operatingChannel, + operating_chan_freq, sap_event->sapevt.sapStartBssCompleteEvent.staId); - ap_ctx->operating_channel = + ap_ctx->operating_chan_freq = sap_event->sapevt.sapStartBssCompleteEvent - .operatingChannel; + .operating_chan_freq; adapter->vdev_id = sap_event->sapevt.sapStartBssCompleteEvent.sessionId; - - sap_config->channel = + sap_config->chan_freq = sap_event->sapevt.sapStartBssCompleteEvent. - operatingChannel; + operating_chan_freq; sap_config->ch_params.ch_width = sap_event->sapevt.sapStartBssCompleteEvent.ch_width; - hdd_nofl_info("AP started vid %d chan %d BW %d", + hdd_nofl_info("AP started vid %d freq %d BW %d", adapter->vdev_id, - ap_ctx->operating_channel, + ap_ctx->operating_chan_freq, sap_config->ch_params.ch_width); sap_config->ch_params = ap_ctx->sap_context->ch_params; - sap_config->sec_ch = ap_ctx->sap_context->secondary_ch; + sap_config->sec_ch_freq = ap_ctx->sap_context->sec_ch_freq; hostapd_state->qdf_status = sap_event->sapevt.sapStartBssCompleteEvent.status; @@ -1857,8 +1914,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, /* DFS requirement: DO NOT transmit during CAC. */ if (CHANNEL_STATE_DFS != - wlan_reg_get_channel_state(hdd_ctx->pdev, - ap_ctx->operating_channel) + wlan_reg_get_channel_state_for_freq( + hdd_ctx->pdev, ap_ctx->operating_chan_freq) || ignoreCAC || hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE) ap_ctx->dfs_cac_block_tx = false; @@ -1892,7 +1949,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, cdp_hl_fc_set_td_limit( cds_get_context(QDF_MODULE_ID_SOC), adapter->vdev_id, - ap_ctx->operating_channel); + ap_ctx->operating_chan_freq); hdd_register_tx_flow_control(adapter, hdd_softap_tx_resume_timer_expired_handler, @@ -1918,7 +1975,6 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, status = ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, adapter->device_mode, - ap_ctx->broadcast_sta_id, adapter->vdev_id, WLAN_IPA_AP_CONNECT, adapter->dev->dev_addr); @@ -1930,7 +1986,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, wlan_hdd_auto_shutdown_enable(hdd_ctx, true); #endif hdd_hostapd_channel_prevent_suspend(adapter, - ap_ctx->operating_channel); + ap_ctx->operating_chan_freq); hostapd_state->bss_state = BSS_START; hdd_start_tsf_sync(adapter); @@ -1962,16 +2018,18 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, we_event = IWEVCUSTOM; we_custom_event_generic = we_custom_start_event; hdd_ipa_set_tx_flow_info(); + sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); + if (!sap_ctx) { + hdd_err("sap ctx is null"); + return QDF_STATUS_E_FAILURE; + } - if (policy_mgr_is_hw_mode_change_after_vdev_up( - hdd_ctx->psoc)) { + if (sap_ctx->is_chan_change_inprogress) { hdd_debug("check for possible hw mode change"); status = policy_mgr_set_hw_mode_on_channel_switch( hdd_ctx->psoc, adapter->vdev_id); if (QDF_IS_STATUS_ERROR(status)) hdd_debug("set hw mode change not done"); - policy_mgr_set_do_hw_mode_change_flag( - hdd_ctx->psoc, false); } hdd_debug("check for SAP restart"); policy_mgr_check_concurrent_intf_and_restart_sap( @@ -1995,10 +2053,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); hdd_hostapd_channel_allow_suspend(adapter, - ap_ctx->operating_channel); + ap_ctx->operating_chan_freq); /* Invalidate the channel info. */ - ap_ctx->operating_channel = 0; + ap_ctx->operating_chan_freq = 0; /* reset the dfs_cac_status and dfs_cac_block_tx flag only when * the last BSS is stopped @@ -2169,8 +2227,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, memcpy(msg.src_addr.sa_data, &sap_event->sapevt.sapStationMICFailureEvent. staMac, QDF_MAC_ADDR_SIZE); - hdd_debug("MIC MAC " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(msg.src_addr.sa_data)); + hdd_debug("MIC MAC " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(msg.src_addr.sa_data)); if (sap_event->sapevt.sapStationMICFailureEvent. multicast == true) msg.flags = IW_MICFAILURE_GROUP; @@ -2203,8 +2261,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, case eSAP_STA_REASSOC_EVENT: event = &sap_event->sapevt.sapStationAssocReassocCompleteEvent; if (eSAP_STATUS_FAILURE == event->status) { - hdd_info("assoc failure: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + hdd_info("assoc failure: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wrqu.addr.sa_data)); break; } @@ -2213,8 +2271,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, wrqu.addr.sa_family = ARPHRD_ETHER; memcpy(wrqu.addr.sa_data, &event->staMac, QDF_MAC_ADDR_SIZE); - hdd_info("associated " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + hdd_info("associated " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wrqu.addr.sa_data)); we_event = IWEVREGISTERED; if ((eCSR_ENCRYPT_TYPE_NONE == ap_ctx->encryption_type) || @@ -2230,40 +2288,35 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, adapter, true, ap_ctx->privacy, - event->staId, (struct qdf_mac_addr *) wrqu.addr.sa_data, event->wmmEnabled); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) hdd_err("Failed to register STA %d " - QDF_MAC_ADDR_STR "", qdf_status, - QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + QDF_MAC_ADDR_FMT, qdf_status, + QDF_MAC_ADDR_REF(wrqu.addr.sa_data)); } else { qdf_status = hdd_softap_register_sta( adapter, false, ap_ctx->privacy, - event->staId, (struct qdf_mac_addr *) wrqu.addr.sa_data, event->wmmEnabled); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) hdd_err("Failed to register STA %d " - QDF_MAC_ADDR_STR "", qdf_status, - QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + QDF_MAC_ADDR_FMT, qdf_status, + QDF_MAC_ADDR_REF(wrqu.addr.sa_data)); } sta_id = event->staId; if (QDF_IS_STATUS_SUCCESS(qdf_status)) hdd_fill_station_info(adapter, event); - adapter->sta_info[sta_id].ecsa_capable = event->ecsa_capable; - if (ucfg_ipa_is_enabled()) { status = ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, adapter->device_mode, - event->staId, adapter->vdev_id, WLAN_IPA_CLIENT_CONNECT_EX, event->staMac.bytes); @@ -2344,8 +2397,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, memcpy(wrqu.addr.sa_data, &disassoc_comp->staMac, QDF_MAC_ADDR_SIZE); - cache_stainfo = hdd_get_stainfo(adapter->cache_sta_info, - disassoc_comp->staMac); + cache_stainfo = hdd_get_sta_info_by_mac( + &adapter->cache_sta_info_list, + disassoc_comp->staMac.bytes, + STA_INFO_HOSTAPD_SAP_EVENT_CB); if (cache_stainfo) { /* Cache the disassoc info */ cache_stainfo->rssi = disassoc_comp->rssi; @@ -2353,6 +2408,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, cache_stainfo->rx_rate = disassoc_comp->rx_rate; cache_stainfo->rx_mc_bc_cnt = disassoc_comp->rx_mc_bc_cnt; + cache_stainfo->rx_retry_cnt = + disassoc_comp->rx_retry_cnt; cache_stainfo->reason_code = disassoc_comp->reason_code; cache_stainfo->disassoc_ts = qdf_system_ticks(); hdd_debug("Cache_stainfo rssi %d txrate %d rxrate %d reason_code %d", @@ -2360,9 +2417,12 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, cache_stainfo->tx_rate, cache_stainfo->rx_rate, cache_stainfo->reason_code); + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, + &cache_stainfo, true, + STA_INFO_HOSTAPD_SAP_EVENT_CB); } - hdd_nofl_info("SAP disassociated " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + hdd_nofl_info("SAP disassociated " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wrqu.addr.sa_data)); qdf_status = qdf_event_set(&hostapd_state->qdf_sta_disassoc_event); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) @@ -2374,46 +2434,56 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, else hdd_debug(" MAC initiated disassociation"); we_event = IWEVEXPIRED; - qdf_status = - hdd_softap_get_sta_id(adapter, - &sap_event->sapevt. - sapStationDisassocCompleteEvent.staMac, - &sta_id); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - hdd_err("Failed to find sta id status: %d", qdf_status); - return QDF_STATUS_E_FAILURE; - } DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD, adapter->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID, QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC)); - stainfo = hdd_get_stainfo(adapter->sta_info, - disassoc_comp->staMac); - if (stainfo) { - /* Send DHCP STOP indication to FW */ - stainfo->dhcp_phase = DHCP_PHASE_ACK; - if (stainfo->dhcp_nego_status == - DHCP_NEGO_IN_PROGRESS) - hdd_post_dhcp_ind(adapter, sta_id, - WMA_DHCP_STOP_IND); - stainfo->dhcp_nego_status = DHCP_NEGO_STOP; + stainfo = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, + disassoc_comp->staMac.bytes, + STA_INFO_HOSTAPD_SAP_EVENT_CB); + if (!stainfo) { + hdd_err("Failed to find the right station"); + return QDF_STATUS_E_INVAL; } - hdd_softap_deregister_sta(adapter, sta_id); + + /* Send DHCP STOP indication to FW */ + stainfo->dhcp_phase = DHCP_PHASE_ACK; + if (stainfo->dhcp_nego_status == + DHCP_NEGO_IN_PROGRESS) + hdd_post_dhcp_ind(adapter, + disassoc_comp->staMac.bytes, + WMA_DHCP_STOP_IND); + stainfo->dhcp_nego_status = DHCP_NEGO_STOP; + + hdd_softap_deregister_sta(adapter, &stainfo); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_HOSTAPD_SAP_EVENT_CB); ap_ctx->ap_active = false; - spin_lock_bh(&adapter->sta_info_lock); - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - if (adapter->sta_info[i].in_use - && i != - (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> - broadcast_sta_id) { + + hdd_for_each_sta_ref_safe(adapter->sta_info_list, stainfo, + tmp, STA_INFO_HOSTAPD_SAP_EVENT_CB) { + if (!qdf_is_macaddr_broadcast( + &stainfo->sta_mac)) { ap_ctx->ap_active = true; + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &stainfo, true, + STA_INFO_HOSTAPD_SAP_EVENT_CB); + if (tmp) + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &tmp, true, + STA_INFO_HOSTAPD_SAP_EVENT_CB); break; } + hdd_put_sta_info_ref(&adapter->sta_info_list, + &stainfo, true, + STA_INFO_HOSTAPD_SAP_EVENT_CB); } - spin_unlock_bh(&adapter->sta_info_lock); #ifdef FEATURE_WLAN_AUTO_SHUTDOWN wlan_hdd_auto_shutdown_enable(hdd_ctx, true); @@ -2476,8 +2546,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, return QDF_STATUS_E_NOMEM; snprintf(unknownSTAEvent, IW_CUSTOM_MAX, - "JOIN_UNKNOWN_STA-"QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(sap_event->sapevt.sapUnknownSTAJoin.macaddr.bytes)); + "JOIN_UNKNOWN_STA-"QDF_FULL_MAC_FMT, + QDF_FULL_MAC_REF(sap_event->sapevt.sapUnknownSTAJoin.macaddr.bytes)); we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ wrqu.data.pointer = unknownSTAEvent; wrqu.data.length = strlen(unknownSTAEvent); @@ -2491,10 +2561,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, return QDF_STATUS_E_NOMEM; snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, - "Peer "QDF_MAC_ADDR_STR" denied" + "Peer "QDF_FULL_MAC_FMT" denied" " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect" " one or more devices to enable the new device connection", - QDF_MAC_ADDR_ARRAY(sap_event->sapevt.sapMaxAssocExceeded.macaddr.bytes)); + QDF_FULL_MAC_REF(sap_event->sapevt.sapMaxAssocExceeded.macaddr.bytes)); we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ wrqu.data.pointer = maxAssocExceededEvent; wrqu.data.length = strlen(maxAssocExceededEvent); @@ -2527,12 +2597,11 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, case eSAP_CHANNEL_CHANGE_EVENT: if (hostapd_state->bss_state != BSS_STOP) { /* Allow suspend for old channel */ - hdd_hostapd_channel_allow_suspend( - adapter, ap_ctx->operating_channel); + hdd_hostapd_channel_allow_suspend(adapter, + ap_ctx->sap_context->freq_before_ch_switch); /* Prevent suspend for new channel */ - hdd_hostapd_channel_prevent_suspend( - adapter, - sap_event->sapevt.sap_ch_selected.pri_ch); + hdd_hostapd_channel_prevent_suspend(adapter, + sap_event->sapevt.sap_ch_selected.pri_ch_freq); } /* SME/PE is already updated for new operation * channel. So update HDD layer also here. This @@ -2542,93 +2611,66 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, * this case if AP2 is started it needs current * operation channel for MCC DFS restriction */ - ap_ctx->operating_channel = - sap_event->sapevt.sap_ch_selected.pri_ch; - ap_ctx->sap_config.acs_cfg.pri_ch = - sap_event->sapevt.sap_ch_selected.pri_ch; - ap_ctx->sap_config.acs_cfg.ht_sec_ch = - sap_event->sapevt.sap_ch_selected.ht_sec_ch; - ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch = - sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch; - ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch = - sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch; + ap_ctx->operating_chan_freq = + sap_event->sapevt.sap_ch_selected.pri_ch_freq; + ap_ctx->sap_config.acs_cfg.pri_ch_freq = + sap_event->sapevt.sap_ch_selected.pri_ch_freq; + ap_ctx->sap_config.acs_cfg.ht_sec_ch_freq = + sap_event->sapevt.sap_ch_selected.ht_sec_ch_freq; + ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch_freq = + sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch_freq; + ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch_freq = + sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch_freq; ap_ctx->sap_config.acs_cfg.ch_width = sap_event->sapevt.sap_ch_selected.ch_width; - sap_ch_param.ch_width = - sap_event->sapevt.sap_ch_selected.ch_width; - sap_ch_param.center_freq_seg0 = - sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch; - sap_ch_param.center_freq_seg1 = - sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch; - wlan_reg_set_channel_params(hdd_ctx->pdev, - sap_event->sapevt.sap_ch_selected.pri_ch, - sap_event->sapevt.sap_ch_selected.ht_sec_ch, - &sap_ch_param); - cdp_hl_fc_set_td_limit(cds_get_context(QDF_MODULE_ID_SOC), adapter->vdev_id, - ap_ctx->operating_channel); - - phy_mode = wlan_sap_get_phymode( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - - switch (phy_mode) { - case eCSR_DOT11_MODE_11n: - case eCSR_DOT11_MODE_11n_ONLY: - case eCSR_DOT11_MODE_11ac: - case eCSR_DOT11_MODE_11ac_ONLY: - case eCSR_DOT11_MODE_11ax: - case eCSR_DOT11_MODE_11ax_ONLY: - legacy_phymode = false; - break; - default: - legacy_phymode = true; - break; + ap_ctx->operating_chan_freq); + sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); + if (!sap_ctx) { + hdd_err("sap ctx is null"); + return QDF_STATUS_E_FAILURE; } - chan_change.chan = - sap_event->sapevt.sap_ch_selected.pri_ch; - chan_change.chan_params.ch_width = - sap_event->sapevt.sap_ch_selected.ch_width; - chan_change.chan_params.sec_ch_offset = - sap_ch_param.sec_ch_offset; - chan_change.chan_params.center_freq_seg0 = - sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch; - chan_change.chan_params.center_freq_seg1 = - sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch; - - return hdd_chan_change_notify(adapter, dev, - chan_change, legacy_phymode); + if (sap_ctx->is_chan_change_inprogress) { + hdd_debug("check for possible hw mode change"); + status = policy_mgr_set_hw_mode_on_channel_switch( + hdd_ctx->psoc, adapter->vdev_id); + if (QDF_IS_STATUS_ERROR(status)) + hdd_debug("set hw mode change not done"); + } + + return hdd_hostapd_chan_change(adapter, sap_event); case eSAP_ACS_SCAN_SUCCESS_EVENT: return hdd_handle_acs_scan_event(sap_event, adapter); case eSAP_ACS_CHANNEL_SELECTED: - ap_ctx->sap_config.acs_cfg.pri_ch = - sap_event->sapevt.sap_ch_selected.pri_ch; - ap_ctx->sap_config.acs_cfg.ht_sec_ch = - sap_event->sapevt.sap_ch_selected.ht_sec_ch; - ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch = - sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch; - ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch = - sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch; + ap_ctx->sap_config.acs_cfg.pri_ch_freq = + sap_event->sapevt.sap_ch_selected.pri_ch_freq; + ap_ctx->sap_config.acs_cfg.ht_sec_ch_freq = + sap_event->sapevt.sap_ch_selected.ht_sec_ch_freq; + ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch_freq = + sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch_freq; + ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch_freq = + sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch_freq; ap_ctx->sap_config.acs_cfg.ch_width = sap_event->sapevt.sap_ch_selected.ch_width; - hdd_nofl_info("ACS Completed vid %d chan %d BW %d", + hdd_nofl_info("ACS Completed vid %d freq %d BW %d", adapter->vdev_id, - ap_ctx->sap_config.acs_cfg.pri_ch, + ap_ctx->sap_config.acs_cfg.pri_ch_freq, ap_ctx->sap_config.acs_cfg.ch_width); wlan_hdd_cfg80211_acs_ch_select_evt(adapter); return QDF_STATUS_SUCCESS; case eSAP_ECSA_CHANGE_CHAN_IND: - hdd_debug("Channel change indication from peer for channel %d", - sap_event->sapevt.sap_chan_cng_ind.new_chan); + hdd_debug("Channel change indication from peer for channel freq %d", + sap_event->sapevt.sap_chan_cng_ind.new_chan_freq); wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id, CSA_REASON_PEER_ACTION_FRAME); if (hdd_softap_set_channel_change(dev, - sap_event->sapevt.sap_chan_cng_ind.new_chan, + sap_event->sapevt.sap_chan_cng_ind.new_chan_freq, CH_WIDTH_MAX, false)) return QDF_STATUS_E_FAILURE; else @@ -2647,8 +2689,6 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, return QDF_STATUS_SUCCESS; case eSAP_CHANNEL_CHANGE_RESP: - hdd_debug("Channel change rsp status = %d", - sap_event->sapevt.ch_change_rsp_status); /* * Set the ch_switch_in_progress flag to zero and also enable * roaming once channel change process (success/failure) @@ -2658,13 +2698,17 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, policy_mgr_set_chan_switch_complete_evt(hdd_ctx->psoc); wlan_hdd_enable_roaming(adapter, RSO_SAP_CHANNEL_CHANGE); + if (CHANNEL_STATE_DFS != + wlan_reg_get_channel_state_for_freq(hdd_ctx->pdev, + ap_ctx->operating_chan_freq)) + ap_ctx->dfs_cac_block_tx = false; /* Check any other sap need restart */ if (ap_ctx->sap_context->csa_reason == CSA_REASON_UNSAFE_CHANNEL) hdd_unsafe_channel_restart_sap(hdd_ctx); - return QDF_STATUS_SUCCESS; + return hdd_hostapd_chan_change(adapter, sap_event); default: hdd_debug("SAP message is not handled"); goto stopbss; @@ -2770,7 +2814,7 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle, tDot11fIEWPA dot11_wpa_ie = {0}; if (!mac_handle) { - hdd_err("Error haHandle returned NULL"); + hdd_err("NULL mac Handle"); return -EINVAL; } /* Validity checks */ @@ -2793,14 +2837,13 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle, ret = sme_unpack_rsn_ie(mac_handle, rsn_ie, rsn_ie_len, &dot11_rsn_ie, false); if (DOT11F_FAILED(ret)) { - hdd_err("unpack failed, ret: 0x%x", ret); + hdd_err("unpack failed, 0x%x", ret); return -EINVAL; } /* Copy out the encryption and authentication types */ - hdd_debug("pairwise cipher suite count: %d", - dot11_rsn_ie.pwise_cipher_suite_count); - hdd_debug("authentication suite count: %d", - dot11_rsn_ie.akm_suite_cnt); + hdd_debug("pairwise cipher count: %d akm count:%d", + dot11_rsn_ie.pwise_cipher_suite_count, + dot11_rsn_ie.akm_suite_cnt); /* * Translate akms in akm suite */ @@ -2835,15 +2878,13 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle, rsn_ie, rsn_ie_len, &dot11_wpa_ie, false); if (DOT11F_FAILED(ret)) { - hdd_err("unpack failed, ret: 0x%x", ret); + hdd_err("unpack failed, 0x%x", ret); return -EINVAL; } /* Copy out the encryption and authentication types */ - hdd_debug("WPA unicast cipher suite count: %d", - dot11_wpa_ie.unicast_cipher_count); - hdd_debug("WPA authentication suite count: %d", - dot11_wpa_ie.auth_suite_count); - /* dot11_wpa_ie.auth_suite_count */ + hdd_debug("WPA unicast cipher suite count: %d akm count: %d", + dot11_wpa_ie.unicast_cipher_count, + dot11_wpa_ie.auth_suite_count); /* * Translate akms in akm suite */ @@ -2869,23 +2910,19 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle, return QDF_STATUS_SUCCESS; } -/** - * hdd_is_any_sta_connecting() - check if any sta is connecting - * @hdd_ctx: hdd context - * - * Return: true if any sta is connecting - */ -static bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx) +bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_STA_CONNECTING; if (!hdd_ctx) { hdd_err("HDD context is NULL"); return false; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if ((adapter->device_mode == QDF_STA_MODE) || (adapter->device_mode == QDF_P2P_CLIENT_MODE) || @@ -2894,29 +2931,21 @@ static bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx) eConnectionState_Connecting) { hdd_debug("vdev_id %d: connecting", adapter->vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } return false; } -/** - * hdd_softap_set_channel_change() - - * This function to support SAP channel change with CSA IE - * set in the beacons. - * - * @dev: pointer to the net device. - * @target_channel: target channel number. - * @target_bw: Target bandwidth to move. - * If no bandwidth is specified, the value is CH_WIDTH_MAX - * @forced: Force to switch channel, ignore SCC/MCC check - * - * Return: 0 for success, non zero for failure - */ -int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, - enum phy_ch_width target_bw, bool forced) +int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq, + enum phy_ch_width target_bw, bool forced) { QDF_STATUS status; int ret = 0; @@ -2952,7 +2981,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, } ret = hdd_validate_channel_and_bandwidth(adapter, - target_channel, target_bw); + target_chan_freq, target_bw); if (ret) { hdd_err("Invalid CH and BW combo"); return ret; @@ -3004,7 +3033,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, hdd_ctx->psoc, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), - target_channel, + target_chan_freq, adapter->vdev_id, forced, sap_ctx->csa_reason)) { @@ -3052,13 +3081,13 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, status = wlansap_set_channel_change_with_csa( WLAN_HDD_GET_SAP_CTX_PTR(adapter), - (uint32_t)target_channel, + target_chan_freq, target_bw, (forced && !scc_on_lte_coex) || is_p2p_go_session); if (QDF_STATUS_SUCCESS != status) { - hdd_err("SAP set channel failed for channel: %d, bw: %d", - target_channel, target_bw); + hdd_err("SAP set channel failed for channel freq: %d, bw: %d", + target_chan_freq, target_bw); /* * If channel change command fails then clear the * radar found flag and also restart the netif @@ -3080,19 +3109,8 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH -/** - * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA - * @ap_adapter: HDD adapter - * @target_channel: Channel to which switch must happen - * @target_bw: Bandwidth of the target channel - * @forced: Force to switch channel, ignore SCC/MCC check - * - * Invokes the necessary API to perform channel switch for the SAP or GO - * - * Return: None - */ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, - uint32_t target_channel, + uint32_t target_chan_freq, uint32_t target_bw, bool forced) { @@ -3106,7 +3124,7 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, return; } - ret = hdd_softap_set_channel_change(dev, target_channel, + ret = hdd_softap_set_channel_change(dev, target_chan_freq, target_bw, forced); if (ret) { hdd_err("channel switch failed"); @@ -3115,7 +3133,7 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, } void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, + uint8_t vdev_id, uint32_t ch_freq, uint32_t channel_bw, bool forced) { @@ -3126,7 +3144,8 @@ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, hdd_err("Adapter is NULL"); return; } - hdd_sap_restart_with_channel_switch(ap_adapter, channel, + hdd_sap_restart_with_channel_switch(ap_adapter, + ch_freq, channel_bw, forced); } @@ -3147,17 +3166,16 @@ void wlan_hdd_set_sap_csa_reason(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, QDF_STATUS wlan_hdd_get_channel_for_sap_restart( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch) + uint8_t vdev_id, uint32_t *ch_freq) { mac_handle_t mac_handle; struct hdd_ap_ctx *hdd_ap_ctx; - uint8_t intf_ch = 0, sap_ch = 0; struct hdd_context *hdd_ctx; uint8_t mcc_to_scc_switch = 0; struct ch_params ch_params; struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev( psoc, vdev_id); + uint32_t sap_ch_freq, intf_ch_freq; struct sap_context *sap_context; enum sap_csa_reason_code csa_reason = CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL; @@ -3173,7 +3191,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( return QDF_STATUS_E_FAILURE; } - if (!channel || !sec_ch) { + if (!ch_freq) { hdd_err("Null parameters"); return QDF_STATUS_E_FAILURE; } @@ -3199,24 +3217,23 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( return QDF_STATUS_E_FAILURE; } - intf_ch = wlansap_get_chan_band_restrict(sap_context); - if (intf_ch) { + intf_ch_freq = wlansap_get_chan_band_restrict(sap_context); + if (intf_ch_freq) { csa_reason = CSA_REASON_BAND_RESTRICTED; goto sap_restart; } - if (policy_mgr_get_connection_count(psoc) == 1) { - /* - * If STA+SAP sessions are on DFS channel and STA+SAP SCC is - * enabled on DFS channel then move the SAP out of DFS channel - * as soon as STA gets disconnect. - */ - if (policy_mgr_is_sap_restart_required_after_sta_disconnect( - psoc, &intf_ch)) { - hdd_debug("Move the sap to user configured channel %u", - intf_ch); - goto sap_restart; - } + /* + * If STA+SAP sessions are on DFS channel and STA+SAP SCC is + * enabled on DFS channel then move the SAP out of DFS channel + * as soon as STA gets disconnect. + */ + if (policy_mgr_is_sap_restart_required_after_sta_disconnect( + psoc, vdev_id, &intf_ch_freq)) { + hdd_debug("Move the sap (vdev %d) to user configured channel %u", + vdev_id, intf_ch_freq); + goto sap_restart; } + if (ap_adapter->device_mode == QDF_P2P_GO_MODE && !policy_mgr_go_scc_enforced(psoc)) { wlansap_context_put(sap_context); @@ -3231,53 +3248,131 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( * supported, return from here if DBS is not supported. * Need to take care of 3 port cases with 2 STA iface in future. */ - intf_ch = wlansap_check_cc_intf(sap_context); - policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch); - hdd_debug("sap_vdev %d intf_ch: %d, orig ch: %d", - vdev_id, intf_ch, sap_ch); + intf_ch_freq = wlansap_check_cc_intf(sap_context); + policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch_freq); + hdd_debug("sap_vdev %d intf_ch: %d, orig freq: %d", + vdev_id, intf_ch_freq, sap_ch_freq); if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION != mcc_to_scc_switch) { if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( - hdd_ctx->psoc, &intf_ch, sap_ch, vdev_id))) { - hdd_debug("can't move sap to chan: %u", - intf_ch); + hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id))) { wlansap_context_put(sap_context); + hdd_debug("can't move sap to chan(freq): %u", + intf_ch_freq); return QDF_STATUS_E_FAILURE; } } sap_restart: - if (!intf_ch) { + if (!intf_ch_freq) { wlansap_context_put(sap_context); hdd_debug("interface channel is 0"); return QDF_STATUS_E_FAILURE; } else { sap_context->csa_reason = csa_reason; } - - hdd_debug("SAP restart orig chan: %d, new chan: %d", - hdd_ap_ctx->sap_config.channel, intf_ch); + hdd_debug("SAP restart orig chan freq: %d, new freq: %d", + hdd_ap_ctx->sap_config.chan_freq, intf_ch_freq); ch_params.ch_width = CH_WIDTH_MAX; hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH; - wlan_reg_set_channel_params(hdd_ctx->pdev, - intf_ch, - 0, - &ch_params); - - wlansap_get_sec_channel(ch_params.sec_ch_offset, intf_ch, sec_ch); - - *channel = intf_ch; + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, + intf_ch_freq, 0, + &ch_params); + *ch_freq = intf_ch_freq; hdd_debug("SAP channel change with CSA/ECSA"); - hdd_sap_restart_chan_switch_cb(psoc, vdev_id, - intf_ch, - ch_params.ch_width, false); + hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq, + ch_params.ch_width, false); wlansap_context_put(sap_context); return QDF_STATUS_SUCCESS; } + +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + uint32_t keymgmt; + struct hdd_adapter *ap_adapter; + struct hdd_ap_ctx *ap_ctx; + struct sap_context *sap_context; + struct sap_config *sap_config; + uint32_t capable = 0; + + if (!psoc) { + hdd_err("PSOC is NULL"); + return 0; + } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_HDD_ID_OBJ_MGR); + if (!vdev) { + hdd_err("vdev is NULL %d", vdev_id); + return 0; + } + + ap_adapter = wlan_hdd_get_adapter_from_vdev( + psoc, vdev_id); + if (!ap_adapter) { + hdd_err("ap_adapter is NULL %d", vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + if (ap_adapter->device_mode != QDF_SAP_MODE) { + hdd_err("unexpected device mode %d", ap_adapter->device_mode); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + sap_config = &ap_ctx->sap_config; + sap_context = ap_ctx->sap_context; + if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) { + hdd_err("sap_context is get failed %d", vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + /* SAP is allowed on 6GHz with explicit indication from user space: + * a. SAP is started on 6Ghz already. + * b. SAP is configured on 6Ghz fixed channel from userspace. + * c. SAP is configured by ACS range which includes any 6Ghz channel. + */ + if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ( + ap_ctx->operating_chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + } else { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_config->chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + else if (sap_context && WLAN_REG_IS_6GHZ_CHAN_FREQ( + sap_context->chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + } + if (wlansap_is_6ghz_included_in_acs_range(sap_context)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + if (!keymgmt || (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_NONE | + 1 << WLAN_CRYPTO_KEY_MGMT_SAE | + 1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B | + 1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192 | + 1 << WLAN_CRYPTO_KEY_MGMT_OWE))) { + capable |= CONN_6GHZ_FLAG_SECURITY_ALLOWED; + } + capable |= CONN_6GHZ_FLAG_VALID; + hdd_debug("vdev_id %d keymgmt 0x%08x capable 0x%x", + vdev_id, keymgmt, capable); + wlansap_context_put(sap_context); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + + return capable; +} +#else +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + return 0; +} +#endif #endif #ifdef WLAN_FEATURE_TSF_PTP @@ -3331,6 +3426,11 @@ bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter) adapter->session.ap.beacon = NULL; } + if (!sap_ctx) { + hdd_debug("sap context is NULL"); + return true; + } + hdd_debug("destroying sap context"); if (QDF_IS_STATUS_ERROR(sap_destroy_ctx(sap_ctx))) @@ -3343,7 +3443,7 @@ bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter) void hdd_sap_destroy_ctx_all(struct hdd_context *hdd_ctx, bool is_ssr) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; /* sap_ctx is not destroyed as it will be leveraged for sap restart */ if (is_ssr) @@ -3351,12 +3451,34 @@ void hdd_sap_destroy_ctx_all(struct hdd_context *hdd_ctx, bool is_ssr) hdd_debug("destroying all the sap context"); - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_SAP_DESTROY_CTX_ALL) { if (adapter->device_mode == QDF_SAP_MODE) hdd_sap_destroy_ctx(adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_SAP_DESTROY_CTX_ALL); } } +static void +hdd_indicate_peers_deleted(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct hdd_adapter *adapter; + + if (!psoc) { + hdd_err("psoc obj is NULL"); + return; + } + + adapter = wlan_hdd_get_adapter_from_vdev(psoc, vdev_id); + if (hdd_validate_adapter(adapter)) { + hdd_err("invalid adapter"); + return; + } + + hdd_sap_indicate_disconnect_for_sta(adapter); +} + QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) { struct hdd_hostapd_state *phostapdBuf; @@ -3366,6 +3488,8 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) int ret; enum dfs_mode acs_dfs_mode; bool acs_with_more_param = 0; + uint8_t enable_sifs_burst = 0; + bool is_6g_sap_fd_enabled = 0; hdd_enter(); @@ -3379,8 +3503,8 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) } if (!reinit) { - adapter->session.ap.sap_config.channel = - hdd_ctx->acs_policy.acs_channel; + adapter->session.ap.sap_config.chan_freq = + hdd_ctx->acs_policy.acs_chan_freq; acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode; adapter->session.ap.sap_config.acs_dfs_mode = wlan_hdd_get_dfs_mode(acs_dfs_mode); @@ -3404,54 +3528,64 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) status = qdf_event_create(&phostapdBuf->qdf_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD qdf event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; } status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD stop bss event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; } status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD sta disassoc event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; + } + + status = qdf_event_create(&phostapdBuf->qdf_sta_eap_frm_done_event); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Hostapd HDD sta eap frm done event init failed!!"); + goto error_deinit_sap_session; } /* Register as a wireless device */ hdd_register_hostapd_wext(adapter->dev); + /* Cache station count initialize to zero */ + qdf_atomic_init(&adapter->cache_sta_count); + /* Initialize the data path module */ - status = hdd_softap_init_tx_rx(adapter); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("hdd_softap_init_tx_rx failed"); - goto error_release_sap_session; - } + hdd_softap_init_tx_rx(adapter); status = hdd_wmm_adapter_init(adapter); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]", status, status); - goto error_release_wmm; + goto error_release_softap_tx_rx; } set_bit(WMM_INIT_DONE, &adapter->event_flags); + status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("Failed to get sifs burst value, use default"); + ret = wma_cli_set_command(adapter->vdev_id, WMI_PDEV_PARAM_BURST_ENABLE, - HDD_ENABLE_SIFS_BURST_DEFAULT, + enable_sifs_burst, PDEV_CMD); - if (0 != ret) hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed: %d", ret); - if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), - cfg_dp_enable_ip_tcp_udp_checksum_offload)) - adapter->dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - adapter->dev->features |= NETIF_F_RXCSUM; - hdd_set_tso_flags(hdd_ctx, adapter->dev); + ucfg_mlme_is_6g_sap_fd_enabled(hdd_ctx->psoc, &is_6g_sap_fd_enabled); + hdd_debug("6g sap fd enabled %d", is_6g_sap_fd_enabled); + if (is_6g_sap_fd_enabled) + wlan_vdev_mlme_feat_ext_cap_set(adapter->vdev, + WLAN_VDEV_FEXT_FILS_DISC_6G_SAP); + + hdd_set_netdev_flags(adapter); if (!reinit) { adapter->session.ap.sap_config.acs_cfg.acs_mode = false; @@ -3459,21 +3593,20 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) sizeof(struct sap_acs_cfg)); } + sme_set_del_peers_ind_callback(hdd_ctx->mac_handle, + &hdd_indicate_peers_deleted); /* rcpi info initialization */ qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); - hdd_exit(); return status; -error_release_wmm: - hdd_softap_deinit_tx_rx(adapter); -error_release_sap_session: +error_release_softap_tx_rx: hdd_unregister_wext(adapter->dev); + hdd_softap_deinit_tx_rx(adapter); +error_deinit_sap_session: hdd_hostapd_deinit_sap_session(adapter); error_release_vdev: - QDF_BUG(!hdd_vdev_destroy(adapter)); - hdd_exit(); return status; } @@ -3489,6 +3622,14 @@ void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx, clear_bit(WMM_INIT_DONE, &adapter->event_flags); } qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); + if (qdf_atomic_read(&adapter->ch_switch_in_progress)) { + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); + policy_mgr_set_chan_switch_complete_evt(hdd_ctx->psoc); + + /* Re-enable roaming on all connected STA vdev */ + wlan_hdd_enable_roaming(adapter, RSO_SAP_CHANNEL_CHANGE); + } + hdd_softap_deinit_tx_rx(adapter); /* * if we are being called during driver unload, @@ -3681,8 +3822,6 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, struct sme_config_params *sme_config; struct sap_config *sap_config; - hdd_enter(); - if (!dev) { hdd_err("Called with dev = NULL"); return -ENODEV; @@ -3693,9 +3832,10 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, TRACE_CODE_HDD_CFG80211_SET_CHANNEL, adapter->vdev_id, channel_type); - hdd_debug("Device_mode %s(%d) freq = %d", + hdd_debug("Dev_mode %s(%d) freq %d, ch_bw %d ccfs1 %d ccfs2 %d", qdf_opmode_str(adapter->device_mode), - adapter->device_mode, chandef->chan->center_freq); + adapter->device_mode, chandef->chan->center_freq, + chandef->width, chandef->center_freq1, chandef->center_freq2); hdd_ctx = WLAN_HDD_GET_CTX(adapter); status = wlan_hdd_validate_context(hdd_ctx); @@ -3704,53 +3844,38 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, mac_handle = hdd_ctx->mac_handle; - /* - * Do freq to chan conversion - * TODO: for 11a - */ + /* Check freq range */ + if ((wlan_reg_min_chan_freq() > + chandef->chan->center_freq) || + (wlan_reg_max_chan_freq() < chandef->chan->center_freq)) { + hdd_err("channel: %d is outside valid freq range", + chandef->chan->center_freq); + return -EINVAL; + } channel = ieee80211_frequency_to_channel(chandef->chan->center_freq); - if (NL80211_CHAN_WIDTH_80P80 == chandef->width || - NL80211_CHAN_WIDTH_160 == chandef->width) { + if (NL80211_CHAN_WIDTH_80P80 == chandef->width) { + if ((wlan_reg_min_chan_freq() > chandef->center_freq2) || + (wlan_reg_max_chan_freq() < chandef->center_freq2)) { + hdd_err("center_freq2: %d is outside valid freq range", + chandef->center_freq2); + return -EINVAL; + } + if (chandef->center_freq2) channel_seg2 = ieee80211_frequency_to_channel( - chandef->center_freq2); + chandef->center_freq2); else hdd_err("Invalid center_freq2"); } - /* Check freq range */ - if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) || - (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) { - hdd_err("Channel: %d is outside valid range from %d to %d", - channel, WNI_CFG_CURRENT_CHANNEL_STAMIN, - WNI_CFG_CURRENT_CHANNEL_STAMAX); - return -EINVAL; - } - - /* Check freq range */ - - if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) || - (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) { - hdd_err("Channel: %d is outside valid range from %d to %d", - channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN, - WNI_CFG_CURRENT_CHANNEL_STAMAX); - return -EINVAL; - } - num_ch = CFG_VALID_CHANNEL_LIST_LEN; - if ((QDF_SAP_MODE != adapter->device_mode) && - (QDF_P2P_GO_MODE != adapter->device_mode)) { - if (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, channel)) { - hdd_err("Invalid Channel: %d", channel); - return -EINVAL; - } - hdd_debug("set channel to [%d] for device mode %s(%d)", channel, - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); + if (QDF_STATUS_SUCCESS != wlan_hdd_validate_operation_channel( + adapter, wlan_reg_chan_to_freq(hdd_ctx->pdev, channel))) { + hdd_err("Invalid Channel: %d", channel); + return -EINVAL; } if ((adapter->device_mode == QDF_STA_MODE) || @@ -3768,32 +3893,20 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, roam_profile = hdd_roam_profile(adapter); num_ch = roam_profile->ChannelInfo.numOfChannels = 1; - sta_ctx->conn_info.channel = channel; - roam_profile->ChannelInfo.ChannelList = - &sta_ctx->conn_info.channel; - } else if ((adapter->device_mode == QDF_SAP_MODE) - || (adapter->device_mode == QDF_P2P_GO_MODE) - ) { + sta_ctx->conn_info.chan_freq = chandef->chan->center_freq; + roam_profile->ChannelInfo.freq_list = + &sta_ctx->conn_info.chan_freq; + } else if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) { sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config); - if (QDF_P2P_GO_MODE == adapter->device_mode) { - if (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, - channel)) { - hdd_err("Invalid Channel: %d", channel); - return -EINVAL; - } - sap_config->channel = channel; - sap_config->ch_params.center_freq_seg1 = channel_seg2; - } else { - /* set channel to what hostapd configured */ - if (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, - channel)) { - hdd_err("Invalid Channel: %d", channel); - return -EINVAL; - } + sap_config->chan_freq = chandef->chan->center_freq; + sap_config->ch_params.center_freq_seg1 = channel_seg2; + sap_config->ch_params.center_freq_seg0 = + ieee80211_frequency_to_channel(chandef->center_freq1); - sap_config->channel = channel; + if (QDF_SAP_MODE == adapter->device_mode) { + /* set channel to what hostapd configured */ + sap_config->chan_freq = chandef->chan->center_freq; sap_config->ch_params.center_freq_seg1 = channel_seg2; sme_config = qdf_mem_malloc(sizeof(*sme_config)); @@ -3807,13 +3920,15 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, case NL80211_CHAN_HT20: case NL80211_CHAN_NO_HT: sme_config->csr_config.obssEnabled = false; - sap_config->sec_ch = 0; + sap_config->sec_ch_freq = 0; break; case NL80211_CHAN_HT40MINUS: - sap_config->sec_ch = sap_config->channel - 4; + sap_config->sec_ch_freq = + sap_config->chan_freq - 20; break; case NL80211_CHAN_HT40PLUS: - sap_config->sec_ch = sap_config->channel + 4; + sap_config->sec_ch_freq = + sap_config->chan_freq + 20; break; default: hdd_err("Error!!! Invalid HT20/40 mode !"); @@ -3830,7 +3945,7 @@ int wlan_hdd_set_channel(struct wiphy *wiphy, hdd_err("Invalid device mode failed to set valid channel"); return -EINVAL; } - hdd_exit(); + return status; } @@ -4252,6 +4367,8 @@ int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter) wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, WLAN_EID_INTERWORKING); + wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, + WLAN_EID_ADVERTISEMENT_PROTOCOL); wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, WLAN_ELEMID_RSNXE); #ifdef FEATURE_WLAN_WAPI @@ -4271,7 +4388,7 @@ int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter) wlan_hdd_add_sap_obss_scan_ie(adapter, genie, &total_ielen); qdf_copy_macaddr(&update_ie.bssid, &adapter->mac_addr); - update_ie.smeSessionId = adapter->vdev_id; + update_ie.vdev_id = adapter->vdev_id; if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { update_ie.ieBufferlength = total_ielen; @@ -4376,12 +4493,21 @@ static void wlan_hdd_set_sap_hwmode(struct hdd_adapter *adapter) u8 checkRatesfor11g = true; u8 require_ht = false, require_vht = false; const u8 *ie; + ssize_t size; config->SapHw_mode = eCSR_DOT11_MODE_11b; + size = beacon->head_len - sizeof(mgmt_frame->u.beacon) - + (sizeof(*mgmt_frame) - sizeof(mgmt_frame->u)); + + if (size <= 0) { + hdd_err_rl("Invalid length: %zu", size); + return; + } + ie = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES, &mgmt_frame->u.beacon.variable[0], - beacon->head_len); + size); if (ie) { ie += 1; wlan_hdd_check_11gmode(ie, &require_ht, &require_vht, @@ -4396,7 +4522,7 @@ static void wlan_hdd_set_sap_hwmode(struct hdd_adapter *adapter) &checkRatesfor11g, &config->SapHw_mode); } - if (config->channel > 14) + if (WLAN_REG_IS_5GHZ_CH_FREQ(config->chan_freq)) config->SapHw_mode = eCSR_DOT11_MODE_11a; ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY, @@ -4468,71 +4594,78 @@ QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx, hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN && con_sap_config->acs_cfg.hw_mode == sap_config->acs_cfg.hw_mode) { - uint8_t con_sap_st_ch, con_sap_end_ch; - uint8_t cur_sap_st_ch, cur_sap_end_ch; - uint8_t bandStartChannel, bandEndChannel; - - con_sap_st_ch = - con_sap_config->acs_cfg.start_ch; - con_sap_end_ch = - con_sap_config->acs_cfg.end_ch; - cur_sap_st_ch = sap_config->acs_cfg.start_ch; - cur_sap_end_ch = sap_config->acs_cfg.end_ch; - - wlansap_extend_to_acs_range(mac_handle, &cur_sap_st_ch, - &cur_sap_end_ch, &bandStartChannel, - &bandEndChannel); - - wlansap_extend_to_acs_range(mac_handle, - &con_sap_st_ch, &con_sap_end_ch, + uint32_t con_sap_st_ch_freq, con_sap_end_ch_freq; + uint32_t cur_sap_st_ch_freq, cur_sap_end_ch_freq; + uint32_t bandStartChannel, bandEndChannel; + + con_sap_st_ch_freq = + con_sap_config->acs_cfg.start_ch_freq; + con_sap_end_ch_freq = + con_sap_config->acs_cfg.end_ch_freq; + cur_sap_st_ch_freq = + sap_config->acs_cfg.start_ch_freq; + cur_sap_end_ch_freq = + sap_config->acs_cfg.end_ch_freq; + + wlansap_extend_to_acs_range( + mac_handle, &cur_sap_st_ch_freq, + &cur_sap_end_ch_freq, + &bandStartChannel, &bandEndChannel); + + wlansap_extend_to_acs_range( + mac_handle, &con_sap_st_ch_freq, + &con_sap_end_ch_freq, &bandStartChannel, &bandEndChannel); - if (con_sap_st_ch <= cur_sap_st_ch && - con_sap_end_ch >= cur_sap_end_ch) { + if (con_sap_st_ch_freq <= cur_sap_st_ch_freq && + con_sap_end_ch_freq >= cur_sap_end_ch_freq) { sap_config->acs_cfg.skip_scan_status = eSAP_SKIP_ACS_SCAN; - } else if (con_sap_st_ch >= cur_sap_st_ch && - con_sap_end_ch >= cur_sap_end_ch) { + } else if (con_sap_st_ch_freq >= cur_sap_st_ch_freq && + con_sap_end_ch_freq >= + cur_sap_end_ch_freq) { sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN; sap_config->acs_cfg.skip_scan_range1_stch = - cur_sap_st_ch; + cur_sap_st_ch_freq; sap_config->acs_cfg.skip_scan_range1_endch = - con_sap_st_ch - 1; + con_sap_st_ch_freq - 5; sap_config->acs_cfg.skip_scan_range2_stch = 0; sap_config->acs_cfg.skip_scan_range2_endch = 0; - } else if (con_sap_st_ch <= cur_sap_st_ch && - con_sap_end_ch <= cur_sap_end_ch) { + } else if (con_sap_st_ch_freq <= cur_sap_st_ch_freq && + con_sap_end_ch_freq <= + cur_sap_end_ch_freq) { sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN; sap_config->acs_cfg.skip_scan_range1_stch = - con_sap_end_ch + 1; + con_sap_end_ch_freq + 5; sap_config->acs_cfg.skip_scan_range1_endch = - cur_sap_end_ch; + cur_sap_end_ch_freq; sap_config->acs_cfg.skip_scan_range2_stch = 0; sap_config->acs_cfg.skip_scan_range2_endch = 0; - } else if (con_sap_st_ch >= cur_sap_st_ch && - con_sap_end_ch <= cur_sap_end_ch) { + } else if (con_sap_st_ch_freq >= cur_sap_st_ch_freq && + con_sap_end_ch_freq <= + cur_sap_end_ch_freq) { sap_config->acs_cfg.skip_scan_status = eSAP_DO_PAR_ACS_SCAN; sap_config->acs_cfg.skip_scan_range1_stch = - cur_sap_st_ch; + cur_sap_st_ch_freq; sap_config->acs_cfg.skip_scan_range1_endch = - con_sap_st_ch - 1; + con_sap_st_ch_freq - 5; sap_config->acs_cfg.skip_scan_range2_stch = - con_sap_end_ch; + con_sap_end_ch_freq; sap_config->acs_cfg.skip_scan_range2_endch = - cur_sap_end_ch + 1; + cur_sap_end_ch_freq + 5; } else sap_config->acs_cfg.skip_scan_status = @@ -4628,7 +4761,7 @@ static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter) if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n) sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac; - if (sap_cfg->channel >= 36) { + if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_cfg->chan_freq)) { status = ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc, &ch_width); @@ -4693,19 +4826,18 @@ hdd_check_and_disconnect_sta_on_invalid_channel(struct hdd_context *hdd_ctx, tSirMacReasonCodes reason) { struct hdd_adapter *sta_adapter; - uint8_t sta_chan; + uint32_t sta_chan_freq; - sta_chan = hdd_get_operating_channel(hdd_ctx, QDF_STA_MODE); - - if (!sta_chan) { + sta_chan_freq = hdd_get_operating_chan_freq(hdd_ctx, QDF_STA_MODE); + if (!sta_chan_freq) { hdd_err("STA not connected"); return; } - hdd_err("STA connected on chan %d", sta_chan); + hdd_err("STA connected on %d", sta_chan_freq); - if (sme_is_channel_valid(hdd_ctx->mac_handle, sta_chan)) { - hdd_err("STA connected on chan %d and it is valid", sta_chan); + if (sme_is_channel_valid(hdd_ctx->mac_handle, sta_chan_freq)) { + hdd_err("STA connected on %d and it is valid", sta_chan_freq); return; } @@ -4716,7 +4848,7 @@ hdd_check_and_disconnect_sta_on_invalid_channel(struct hdd_context *hdd_ctx, return; } - hdd_err("chan %d not valid, issue disconnect", sta_chan); + hdd_err("chan %d not valid, issue disconnect", sta_chan_freq); /* Issue Disconnect request */ wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH, reason); } @@ -4749,8 +4881,7 @@ static struct ieee80211_channel *wlan_hdd_get_wiphy_channel( return wiphy_channel; } -int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx, - bool notify_sap_event) +int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx) { struct hdd_cache_channels *cache_chann; struct wiphy *wiphy; @@ -4806,10 +4937,8 @@ int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx, } qdf_mutex_release(&hdd_ctx->cache_channel_lock); - if (notify_sap_event) - ucfg_reg_notify_sap_event(hdd_ctx->pdev, false); - else - ucfg_reg_restore_cached_channels(hdd_ctx->pdev); + + ucfg_reg_restore_cached_channels(hdd_ctx->pdev); status = sme_update_channel_list(hdd_ctx->mac_handle); if (status) hdd_err("Can't Restore channel list"); @@ -4882,7 +5011,7 @@ int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx) } qdf_mutex_release(&hdd_ctx->cache_channel_lock); - status = ucfg_reg_notify_sap_event(hdd_ctx->pdev, true); + ucfg_reg_disable_cached_channels(hdd_ctx->pdev); status = sme_update_channel_list(hdd_ctx->mac_handle); hdd_exit(); @@ -4894,8 +5023,7 @@ int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx) return 0; } -int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx, - bool notify_sap_event) +int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx) { return 0; } @@ -4985,30 +5113,6 @@ static void wlan_hdd_dhcp_offload_enable(struct hdd_context *hdd_ctx, } #endif /* DHCP_SERVER_OFFLOAD */ -#ifdef WLAN_CONV_CRYPTO_SUPPORTED -/** - * hdd_set_vdev_crypto_prarams_from_ie - Sets vdev crypto params from IE info - * @vdev: vdev pointer - * @ie_ptr: pointer to IE - * @ie_len: IE length - * - * Return: QDF_STATUS_SUCCESS or error code - */ -static QDF_STATUS -hdd_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, - uint8_t *ie_ptr, uint16_t ie_len) -{ - return wlan_set_vdev_crypto_prarams_from_ie(vdev, ie_ptr, ie_len); -} -#else -static QDF_STATUS -hdd_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, - uint8_t *ie_ptr, uint16_t ie_len) -{ - return QDF_STATUS_SUCCESS; -} -#endif - #ifdef FEATURE_AP_MCC_CH_AVOIDANCE static void wlan_hdd_set_sap_mcc_chnl_avoid(struct hdd_context *hdd_ctx) { @@ -5058,7 +5162,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, struct hdd_hostapd_state *hostapd_state; mac_handle_t mac_handle; int32_t i; - uint32_t ii; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint8_t mcc_to_scc_switch = 0, conc_rule1 = 0; struct sme_config_params *sme_config; @@ -5126,7 +5229,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); config = &adapter->session.ap.sap_config; - if (!config->channel) { + if (!config->chan_freq) { hdd_err("Invalid channel"); ret = -EINVAL; goto free; @@ -5184,33 +5287,26 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->dtim_period = beacon->dtim_period; - hdd_debug("acs_mode %d", config->acs_cfg.acs_mode); - if (config->acs_cfg.acs_mode == true) { - hdd_debug("acs_channel %d, acs_dfs_mode %d", - hdd_ctx->acs_policy.acs_channel, - hdd_ctx->acs_policy.acs_dfs_mode); + hdd_debug("acs_chan_freq %u, acs_dfs_mode %u", + hdd_ctx->acs_policy.acs_chan_freq, + hdd_ctx->acs_policy.acs_dfs_mode); - if (hdd_ctx->acs_policy.acs_channel) - config->channel = hdd_ctx->acs_policy.acs_channel; + if (hdd_ctx->acs_policy.acs_chan_freq) + config->chan_freq = hdd_ctx->acs_policy.acs_chan_freq; mode = hdd_ctx->acs_policy.acs_dfs_mode; config->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode); } policy_mgr_update_user_config_sap_chan(hdd_ctx->psoc, - config->channel); - hdd_debug("config->channel %d, config->acs_dfs_mode %d", - config->channel, config->acs_dfs_mode); - - hdd_debug("****config->dtim_period=%d***", - config->dtim_period); - + config->chan_freq); ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc, &mcc_to_scc_switch); - if (adapter->device_mode == QDF_SAP_MODE) { + if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) { ie = wlan_get_ie_ptr_from_eid(WLAN_EID_COUNTRY, beacon->tail, beacon->tail_len); - if (ie) { + if ((adapter->device_mode == QDF_SAP_MODE) && ie) { if (ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN) { hdd_err("Invalid Country IE len: %d", ie[1]); ret = -EINVAL; @@ -5234,18 +5330,19 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, */ ret = 0; if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) || - WLAN_REG_IS_5GHZ_CH(config->channel)) { + !WLAN_REG_IS_24GHZ_CH_FREQ(config->chan_freq)) { ret = wlan_hdd_sap_cfg_dfs_override(adapter); if (ret < 0) goto error; } - if (!ret && wlan_reg_is_dfs_ch(hdd_ctx->pdev, config->channel)) + if (!ret && wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, + config->chan_freq)) hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; if (QDF_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(adapter, - config->channel)) { - hdd_err("Invalid Channel: %d", config->channel); + config->chan_freq)) { + hdd_err("Invalid Ch_freq: %d", config->chan_freq); ret = -EINVAL; goto error; } @@ -5255,8 +5352,8 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, /* reject SAP if DFS channel scan is not allowed */ if (!(enable_dfs_scan) && (CHANNEL_STATE_DFS == - wlan_reg_get_channel_state(hdd_ctx->pdev, - config->channel))) { + wlan_reg_get_channel_state_for_freq(hdd_ctx->pdev, + config->chan_freq))) { hdd_err("No SAP start on DFS channel"); ret = -EOPNOTSUPP; goto error; @@ -5272,10 +5369,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, wlansap_set_dfs_preferred_channel_location(mac_handle); wlan_hdd_set_sap_mcc_chnl_avoid(hdd_ctx); - } else if (adapter->device_mode == QDF_P2P_GO_MODE) { - config->countryCode[0] = hdd_ctx->reg.alpha2[0]; - config->countryCode[1] = hdd_ctx->reg.alpha2[1]; - config->ieee80211d = 0; } else { config->ieee80211d = 0; } @@ -5295,13 +5388,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, if (ie) { /* To access ie[15], length needs to be at least 14 */ if (ie[1] < 14) { - hdd_err("**Wps Ie Length(%hhu) is too small***", + hdd_err("Wps Ie Length(%hhu) is too small", ie[1]); ret = -EINVAL; goto error; } else if (memcmp(&ie[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0) { - hdd_debug("** WPS IE(len %d) ***", (ie[1] + 2)); + hdd_debug("WPS IE(len %d)", (ie[1] + 2)); /* Check 15 bit of WPS IE as it contain information for * wps state */ @@ -5313,7 +5406,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, } } } else { - hdd_debug("WPS disabled"); config->wps_state = SAP_WPS_DISABLED; } /* Forward WPS PBC probe request frame up */ @@ -5359,14 +5451,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->mcRSNEncryptType = mc_rsn_encrypt_type; (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> encryption_type = rsn_encrypt_type; - hdd_debug("CSR EncryptionType = %d mcEncryptionType = %d", - rsn_encrypt_type, mc_rsn_encrypt_type); - hdd_debug("CSR AKM Suites %d", + hdd_debug("CSR Encryption: %d mcEncryption: %d num_akm_suites:%d", + rsn_encrypt_type, mc_rsn_encrypt_type, config->akm_list.numEntries); - for (ii = 0; ii < config->akm_list.numEntries; - ii++) - hdd_debug("CSR AKM Suite [%d] = %d", ii, - config->akm_list.authType[ii]); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + config->akm_list.authType, + config->akm_list.numEntries); } } @@ -5412,31 +5503,22 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->mcRSNEncryptType = mc_rsn_encrypt_type; (WLAN_HDD_GET_AP_CTX_PTR(adapter))-> encryption_type = rsn_encrypt_type; - hdd_debug("CSR EncryptionType = %d mcEncryptionType = %d", - rsn_encrypt_type, - mc_rsn_encrypt_type); - hdd_debug("CSR AKM Suites %d", + hdd_debug("CSR Encryption: %d mcEncryption: %d num_akm_suites:%d", + rsn_encrypt_type, mc_rsn_encrypt_type, config->akm_list.numEntries); - for (ii = 0; ii < config->akm_list.numEntries; - ii++) - hdd_debug("CSR AKM Suite [%d] = %d", ii, - config->akm_list. - authType[ii]); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + config->akm_list.authType, + config->akm_list.numEntries); } } } if (config->RSNWPAReqIELength > sizeof(config->RSNWPAReqIE)) { - hdd_err("**RSNWPAReqIELength is too large***"); + hdd_err("RSNWPAReqIELength is too large"); ret = -EINVAL; goto error; } - status = hdd_set_vdev_crypto_prarams_from_ie(adapter->vdev, - config->RSNWPAReqIE, - config->RSNWPAReqIELength - ); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("Failed to set crypto params from IE"); config->SSIDinfo.ssidHidden = false; @@ -5446,7 +5528,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, switch (hidden_ssid) { case NL80211_HIDDEN_SSID_NOT_IN_USE: - hdd_debug("HIDDEN_SSID_NOT_IN_USE"); config->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE; break; case NL80211_HIDDEN_SSID_ZERO_LEN: @@ -5509,12 +5590,15 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, ie++; for (i = 0; i < config->supported_rates.numRates; i++) { - if (ie[i]) { + if (ie[i]) config->supported_rates.rate[i] = ie[i]; - hdd_debug("Configured Supported rate is %2x", - config->supported_rates.rate[i]); - } } + hdd_debug("Configured Num Supported rates: %d", + config->supported_rates.numRates); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + config->supported_rates.rate, + config->supported_rates.numRates); } ie = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES, beacon->tail, @@ -5530,12 +5614,16 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->extended_rates.numRates = ie[0]; ie++; for (i = 0; i < config->extended_rates.numRates; i++) { - if (ie[i]) { + if (ie[i]) config->extended_rates.rate[i] = ie[i]; - hdd_debug("Configured ext Supported rate is %2x", - config->extended_rates.rate[i]); - } } + + hdd_debug("Configured Num Extended rates: %d", + config->extended_rates.numRates); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, + config->extended_rates.rate, + config->extended_rates.numRates); } config->require_h2e = false; @@ -5549,10 +5637,10 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, wlan_hdd_set_sap_hwmode(adapter); status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + if (QDF_IS_STATUS_ERROR(qdf_status)) hdd_err("Failed to get vht_for_24ghz"); - if (IS_24G_CH(config->channel) && bval && + if (WLAN_REG_IS_24GHZ_CH_FREQ(config->chan_freq) && bval && (config->SapHw_mode == eCSR_DOT11_MODE_11n || config->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY)) config->SapHw_mode = eCSR_DOT11_MODE_11ac; @@ -5601,9 +5689,21 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, } config->ch_params.ch_width = config->ch_width_orig; - wlan_reg_set_channel_params(hdd_ctx->pdev, config->channel, - config->sec_ch, &config->ch_params); + if ((config->ch_params.ch_width == CH_WIDTH_80P80MHZ) && + ucfg_mlme_get_restricted_80p80_bw_supp(hdd_ctx->psoc)) { + if (!((config->ch_params.center_freq_seg0 == 138 && + config->ch_params.center_freq_seg1 == 155) || + (config->ch_params.center_freq_seg1 == 138 && + config->ch_params.center_freq_seg0 == 155))) { + config->ch_params.center_freq_seg1 = 0; + config->ch_width_orig = CH_WIDTH_80MHZ; + config->ch_params.ch_width = config->ch_width_orig; + } + } + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, config->chan_freq, + config->sec_ch_freq, + &config->ch_params); if (0 != wlan_hdd_cfg80211_update_apies(adapter)) { hdd_err("SAP Not able to set AP IEs"); ret = -EINVAL; @@ -5617,14 +5717,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->mfpCapable, config->mfpRequired); #endif - hdd_debug("SOftAP macaddress : " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(adapter->mac_addr.bytes)); - hdd_debug("ssid =%s, beaconint=%d, channel=%d", - config->SSIDinfo.ssid.ssId, (int)config->beacon_int, - (int)config->channel); - hdd_debug("hw_mode=%x, privacy=%d, authType=%d", - config->SapHw_mode, config->privacy, config->authType); - hdd_debug("RSN/WPALen=%d", (int)config->RSNWPAReqIELength); + hdd_nofl_debug("SAP mac:" QDF_MAC_ADDR_FMT " SSID: %.*s BCNINTV:%d Freq:%d HW mode:%d privacy:%d akm:%d acs_mode:%d acs_dfs_mode %d dtim period:%d", + QDF_MAC_ADDR_REF(adapter->mac_addr.bytes), + config->SSIDinfo.ssid.length, + config->SSIDinfo.ssid.ssId, (int)config->beacon_int, + config->chan_freq, config->SapHw_mode, config->privacy, + config->authType, config->acs_cfg.acs_mode, + config->acs_dfs_mode, config->dtim_period); mutex_lock(&hdd_ctx->sap_lock); if (cds_is_driver_unloading()) { @@ -5651,7 +5750,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), - config->channel, HW_MODE_20_MHZ)) { + config->chan_freq, HW_MODE_20_MHZ)) { mutex_unlock(&hdd_ctx->sap_lock); hdd_err("This concurrency combination is not allowed"); @@ -5688,9 +5787,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, goto error; } - hdd_debug("Waiting for Scan to complete(auto mode) and BSS to start"); - - qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, + qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, SME_CMD_START_BSS_TIMEOUT); wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL); @@ -5703,7 +5800,8 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, hdd_set_connection_in_progress(false); sme_get_command_q_status(mac_handle); wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - QDF_ASSERT(0); + if (!cds_is_driver_recovering()) + QDF_ASSERT(0); ret = -EINVAL; goto error; } @@ -5944,7 +6042,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, } qdf_copy_macaddr(&update_ie.bssid, &adapter->mac_addr); - update_ie.smeSessionId = adapter->vdev_id; + update_ie.vdev_id = adapter->vdev_id; update_ie.ieBufferlength = 0; update_ie.pAdditionIEBuffer = NULL; update_ie.append = true; @@ -6044,6 +6142,29 @@ int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, return errno; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) +/* + * Beginning with 4.7 struct ieee80211_channel uses enum nl80211_band + */ +static inline +enum nl80211_band ieee80211_channel_band(const struct ieee80211_channel *chan) +{ + return chan->band; +} +#else +/* + * Prior to 4.7 struct ieee80211_channel used enum ieee80211_band. However the + * ieee80211_band enum values are assigned from enum nl80211_band so we can safely + * typecast one to another. + */ +static inline +enum nl80211_band ieee80211_channel_band(const struct ieee80211_channel *chan) +{ + enum ieee80211_band band = chan->band; + return (enum nl80211_band)band; +} +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \ defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT) /** @@ -6098,7 +6219,7 @@ static void hdd_update_beacon_rate(struct hdd_adapter *adapter, struct cfg80211_bitrate_mask *beacon_rate_mask; enum nl80211_band band; - band = params->chandef.chan->band; + band = ieee80211_channel_band(params->chandef.chan); beacon_rate_mask = ¶ms->beacon_rate; if (beacon_rate_mask->control[band].legacy) { adapter->session.ap.sap_config.beacon_tx_rate = @@ -6120,7 +6241,7 @@ static void hdd_update_beacon_rate(struct hdd_adapter *adapter, /** * wlan_hdd_ap_ap_force_scc_override() - force Same band SCC chan override * @adapter: SAP adapter pointer - * @channel: SAP starting channel + * @freq: SAP starting channel freq * @new_chandef: new override SAP channel * * The function will override the second SAP chan to the first SAP's home @@ -6130,18 +6251,18 @@ static void hdd_update_beacon_rate(struct hdd_adapter *adapter, */ static bool wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, - uint8_t channel, + uint32_t freq, struct cfg80211_chan_def *new_chandef) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint32_t cc_count, i; - uint8_t op_ch[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct ch_params ch_params; enum nl80211_channel_type channel_type; struct hdd_adapter *con_adapter; uint8_t con_vdev_id; - uint8_t con_chan; + uint32_t con_freq; uint8_t mcc_to_scc_switch; struct ieee80211_channel *ieee_chan; @@ -6163,34 +6284,34 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, (mcc_to_scc_switch != QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)) return false; cc_count = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, - &op_ch[0], + &op_freq[0], &vdev_id[0], PM_SAP_MODE); if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) cc_count = cc_count + policy_mgr_get_mode_specific_conn_info( hdd_ctx->psoc, - &op_ch[cc_count], + &op_freq[cc_count], &vdev_id[cc_count], PM_P2P_GO_MODE); for (i = 0 ; i < cc_count; i++) { - if (channel == op_ch[i]) + if (freq == op_freq[i]) continue; if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) break; - if (wlan_reg_is_same_band_channels(channel, - op_ch[i])) + if (wlan_reg_is_same_band_freqs(freq, + op_freq[i])) break; } if (i >= cc_count) return false; - con_chan = op_ch[i]; + con_freq = op_freq[i]; con_vdev_id = vdev_id[i]; con_adapter = hdd_get_adapter_by_vdev(hdd_ctx, con_vdev_id); if (!con_adapter) return false; ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy, - cds_chan_to_freq(con_chan)); + con_freq); if (!ieee_chan) { hdd_err("channel converion failed"); return false; @@ -6198,9 +6319,9 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, if (!wlan_sap_get_ch_params(WLAN_HDD_GET_SAP_CTX_PTR(con_adapter), &ch_params)) - wlan_reg_set_channel_params(hdd_ctx->pdev, - con_chan, 0, - &ch_params); + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, + con_freq, 0, + &ch_params); switch (ch_params.sec_ch_offset) { case PHY_SINGLE_CHANNEL_CENTERED: channel_type = NL80211_CHAN_HT20; @@ -6222,9 +6343,8 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, break; case CH_WIDTH_80P80MHZ: new_chandef->width = NL80211_CHAN_WIDTH_80P80; - if (ch_params.center_freq_seg1) - new_chandef->center_freq2 = cds_chan_to_freq( - ch_params.center_freq_seg1); + if (ch_params.mhz_freq_seg1) + new_chandef->center_freq2 = ch_params.mhz_freq_seg1; break; case CH_WIDTH_160MHZ: new_chandef->width = NL80211_CHAN_WIDTH_160; @@ -6235,18 +6355,41 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter, if ((ch_params.ch_width == CH_WIDTH_80MHZ) || (ch_params.ch_width == CH_WIDTH_80P80MHZ) || (ch_params.ch_width == CH_WIDTH_160MHZ)) { - if (ch_params.center_freq_seg0) - new_chandef->center_freq1 = cds_chan_to_freq( - ch_params.center_freq_seg0); + if (ch_params.mhz_freq_seg0) + new_chandef->center_freq1 = ch_params.mhz_freq_seg0; } - hdd_debug("override AP ch %d to first AP(vdev_id %d) chan:%d width:%d freq1:%d freq2:%d ", - channel, con_vdev_id, new_chandef->chan->center_freq, + hdd_debug("override AP freq %d to first AP(vdev_id %d) center_freq:%d width:%d freq1:%d freq2:%d ", + freq, con_vdev_id, new_chandef->chan->center_freq, new_chandef->width, new_chandef->center_freq1, new_chandef->center_freq2); return true; } +#ifdef NDP_SAP_CONCURRENCY_ENABLE +/** + * hdd_sap_nan_check_and_disable_unsupported_ndi: Wrapper function for + * ucfg_nan_check_and_disable_unsupported_ndi + * @psoc: pointer to psoc object + * @force: When set forces NDI disable + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc, + bool force) +{ + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS +hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc, + bool force) +{ + return ucfg_nan_check_and_disable_unsupported_ndi(psoc, force); +} +#endif + /** * __wlan_hdd_cfg80211_start_ap() - start soft ap mode * @wiphy: Pointer to wiphy structure @@ -6271,6 +6414,10 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_chan_def new_chandef; struct cfg80211_chan_def *chandef; + uint16_t sap_ch; + bool srd_channel_allowed, disable_nan = true; + enum QDF_OPMODE vdev_opmode; + uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS], i; hdd_enter(); @@ -6297,11 +6444,10 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, if (0 != status) return status; - hdd_debug("adapter = %pK, Device mode %s(%d) sub20 %d", - adapter, qdf_opmode_str(adapter->device_mode), - adapter->device_mode, cds_is_sub_20_mhz_enabled()); - - hdd_nofl_info("Request to start AP vid %d", adapter->vdev_id); + hdd_nofl_info("%s(vdevid-%d): START AP: Device mode %s(%d) sub20 %d", + dev->name, adapter->vdev_id, + qdf_opmode_str(adapter->device_mode), + adapter->device_mode, cds_is_sub_20_mhz_enabled()); if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->psoc)) { status = policy_mgr_wait_for_connection_update( hdd_ctx->psoc); @@ -6321,7 +6467,8 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, chandef = ¶ms->chandef; if ((adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) && - wlan_hdd_ap_ap_force_scc_override(adapter, channel, + wlan_hdd_ap_ap_force_scc_override(adapter, + chandef->chan->center_freq, &new_chandef)) { chandef = &new_chandef; channel = ieee80211_frequency_to_channel( @@ -6341,8 +6488,8 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, policy_mgr_init_sap_mandatory_2g_chan( hdd_ctx->psoc); - policy_mgr_add_sap_mandatory_chan(hdd_ctx->psoc, - channel); + policy_mgr_add_sap_mandatory_chan( + hdd_ctx->psoc, wlan_chan_to_freq(channel)); } else { policy_mgr_init_sap_mandatory_2g_chan( hdd_ctx->psoc); @@ -6357,10 +6504,12 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( hdd_ctx->psoc); - sta_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, - PM_STA_MODE, NULL); - sap_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, - PM_SAP_MODE, NULL); + sta_cnt = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, NULL, + vdev_id_list, + PM_STA_MODE); + sap_cnt = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, NULL, + &vdev_id_list[sta_cnt], + PM_SAP_MODE); hdd_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u", sta_sap_scc_on_dfs_chan, sta_cnt); @@ -6375,9 +6524,15 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, hdd_err("SAP not allowed on DFS channel if no dfs master capability!!"); return -EINVAL; } - if (!wlan_reg_is_etsi13_srd_chan_allowed_master_mode(hdd_ctx->pdev) && + + vdev_opmode = wlan_vdev_mlme_get_opmode(adapter->vdev); + ucfg_mlme_get_srd_master_mode_for_vdev(hdd_ctx->psoc, vdev_opmode, + &srd_channel_allowed); + + if (!srd_channel_allowed && wlan_reg_is_etsi13_srd_chan(hdd_ctx->pdev, channel)) { - hdd_err("SAP not allowed on SRD channel."); + hdd_err("vdev opmode %d not allowed on SRD channel.", + vdev_opmode); return -EINVAL; } if (cds_is_sub_20_mhz_enabled()) { @@ -6415,24 +6570,30 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, } /* Disable NAN Disc before starting P2P GO or STA+SAP or SAP+SAP */ - if (adapter->device_mode == QDF_P2P_GO_MODE || sta_cnt || sap_cnt) { - hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P_GO: %d", - sap_cnt, sta_cnt, - (adapter->device_mode == QDF_P2P_GO_MODE)); - ucfg_nan_disable_concurrency(hdd_ctx->psoc); + if (adapter->device_mode == QDF_P2P_GO_MODE || sta_cnt || + (sap_cnt > (MAX_SAP_NUM_CONCURRENCY_WITH_NAN - 1))) { + for (i = 0; i < sta_cnt + sap_cnt; i++) + if (vdev_id_list[i] == adapter->vdev_id) + disable_nan = false; + if (disable_nan) { + hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P_GO: %d", + sap_cnt, sta_cnt, + (adapter->device_mode == QDF_P2P_GO_MODE)); + ucfg_nan_disable_concurrency(hdd_ctx->psoc); + } } - /* NDI + SAP not supported */ - ucfg_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc, true); - if (!policy_mgr_nan_sap_pre_enable_conc_check(hdd_ctx->psoc, - PM_SAP_MODE, channel)) + /* NDI + SAP conditional supported */ + hdd_sap_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc, true); + if (!policy_mgr_nan_sap_pre_enable_conc_check( + hdd_ctx->psoc, PM_SAP_MODE, wlan_chan_to_freq(channel))) hdd_debug("NAN disabled due to concurrency constraints"); /* check if concurrency is allowed */ if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), - channel, + wlan_chan_to_freq(channel), channel_width)) { hdd_err("Connection failed due to concurrency check failure"); return -EINVAL; @@ -6455,15 +6616,16 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, * back to single MAC 2x2 (if initial was 2x2). */ - policy_mgr_checkn_update_hw_mode_single_mac_mode(hdd_ctx->psoc, - channel); + policy_mgr_checkn_update_hw_mode_single_mac_mode( + hdd_ctx->psoc, wlan_chan_to_freq(channel)); if (status != QDF_STATUS_SUCCESS) { hdd_err("Failed to stop DBS opportunistic timer"); return -EINVAL; } - status = policy_mgr_current_connections_update(hdd_ctx->psoc, - adapter->vdev_id, channel, + status = policy_mgr_current_connections_update( + hdd_ctx->psoc, adapter->vdev_id, + wlan_chan_to_freq(channel), POLICY_MGR_UPDATE_REASON_START_AP); if (status == QDF_STATUS_E_FAILURE) { hdd_err("ERROR: connections update failed!!"); @@ -6473,7 +6635,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, if (QDF_STATUS_SUCCESS == status) { status = policy_mgr_wait_for_connection_update(hdd_ctx->psoc); if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("ERROR: qdf wait for event failed!!"); + hdd_err("qdf wait for event failed!!"); return -EINVAL; } } @@ -6563,11 +6725,10 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, * If Do_Not_Break_Stream enabled send avoid channel list * to application. */ - if (policy_mgr_is_dnsc_set(adapter->vdev) && - sap_config->channel) { - wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, - sap_config->channel); - } + sap_ch = wlan_reg_freq_to_chan(hdd_ctx->pdev, + sap_config->chan_freq); + if (sap_ch && policy_mgr_is_dnsc_set(adapter->vdev)) + wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, sap_ch); ucfg_mlme_get_sap_inactivity_override(hdd_ctx->psoc, &val); if (val) { @@ -6730,8 +6891,8 @@ int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter) { struct sap_event sap_event; - int sta_id; struct sap_context *sap_ctx; + struct hdd_station_info *sta_info, *tmp = NULL; hdd_enter(); @@ -6741,33 +6902,33 @@ void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter) return; } - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - if (adapter->sta_info[sta_id].in_use) { - hdd_debug("sta_id: %d in_use: %d %pK", - sta_id, adapter->sta_info[sta_id].in_use, - adapter); + hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, + STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA) { + hdd_debug("sta_mac: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); - if (qdf_is_macaddr_broadcast( - &adapter->sta_info[sta_id].sta_mac)) { - hdd_softap_deregister_sta(adapter, sta_id); - continue; - } + if (qdf_is_macaddr_broadcast(&sta_info->sta_mac)) { + hdd_softap_deregister_sta(adapter, &sta_info); + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &sta_info, true, + STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA); + continue; + } + + sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; + + qdf_mem_copy( + &sap_event.sapevt.sapStationDisassocCompleteEvent.staMac, + &sta_info->sta_mac, sizeof(struct qdf_mac_addr)); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA); - sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; - qdf_mem_copy( - &sap_event.sapevt. - sapStationDisassocCompleteEvent.staMac, - &adapter->sta_info[sta_id].sta_mac, - sizeof(struct qdf_mac_addr)); - sap_event.sapevt.sapStationDisassocCompleteEvent. - reason = + sap_event.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_MAC_INITATED_DISASSOC; - sap_event.sapevt.sapStationDisassocCompleteEvent. - status_code = + sap_event.sapevt.sapStationDisassocCompleteEvent.status_code = QDF_STATUS_E_RESOURCES; - hdd_hostapd_sap_event_cb(&sap_event, - sap_ctx->user_context); - } + hdd_hostapd_sap_event_cb(&sap_event, sap_ctx->user_context); } hdd_exit(); @@ -6776,25 +6937,32 @@ void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter) bool hdd_is_peer_associated(struct hdd_adapter *adapter, struct qdf_mac_addr *mac_addr) { - uint32_t cnt; - struct hdd_station_info *sta_info; + bool is_associated = false; + struct hdd_station_info *sta_info, *tmp = NULL; if (!adapter || !mac_addr) { hdd_err("Invalid adapter or mac_addr"); return false; } - sta_info = adapter->sta_info; - spin_lock_bh(&adapter->sta_info_lock); - for (cnt = 0; cnt < WLAN_MAX_STA_COUNT; cnt++) { - if ((sta_info[cnt].in_use) && - !qdf_mem_cmp(&(sta_info[cnt].sta_mac), mac_addr, - QDF_MAC_ADDR_SIZE)) + hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, + STA_INFO_IS_PEER_ASSOCIATED) { + if (!qdf_mem_cmp(&sta_info->sta_mac, mac_addr, + QDF_MAC_ADDR_SIZE)) { + is_associated = true; + hdd_put_sta_info_ref(&adapter->sta_info_list, + &sta_info, true, + STA_INFO_IS_PEER_ASSOCIATED); + if (tmp) + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &tmp, true, + STA_INFO_IS_PEER_ASSOCIATED); break; + } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_IS_PEER_ASSOCIATED); } - spin_unlock_bh(&adapter->sta_info_lock); - if (cnt != WLAN_MAX_STA_COUNT) - return true; - return false; + return is_associated; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.h index d36774c09b3c0976a19c4f43b5148e6a419e7fd6..f75bcc0ebb09822cbc2e634c8f8ad9650341dedb 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.h @@ -43,14 +43,38 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx, enum csr_akm_type hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]); +/** + * hdd_softap_set_channel_change() - + * This function to support SAP channel change with CSA IE + * set in the beacons. + * + * @dev: pointer to the net device. + * @target_chan_freq: target channel frequency. + * @target_bw: Target bandwidth to move. + * If no bandwidth is specified, the value is CH_WIDTH_MAX + * @forced: Force to switch channel, ignore SCC/MCC check + * + * Return: 0 for success, non zero for failure + */ int hdd_softap_set_channel_change(struct net_device *dev, - int target_channel, + int target_chan_freq, enum phy_ch_width target_bw, bool forced); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA + * @ap_adapter: HDD adapter + * @target_chan_freq: Channel frequency to which switch must happen + * @target_bw: Bandwidth of the target channel + * @forced: Force to switch channel, ignore SCC/MCC check + * + * Invokes the necessary API to perform channel switch for the SAP or GO + * + * Return: None + */ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter, - uint32_t target_channel, + uint32_t target_chan_freq, uint32_t target_bw, bool forced); /** @@ -58,7 +82,7 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter, * a different channel * @psoc: PSOC object information * @vdev_id: vdev id - * @channel: channel to switch + * @ch_freq: channel to switch * @forced: Force to switch channel, ignore SCC/MCC check * * This function restarts SAP with a different channel @@ -67,7 +91,7 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter, * */ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint32_t channel, + uint8_t vdev_id, uint32_t ch_freq, uint32_t channel_bw, bool forced); /** @@ -75,8 +99,7 @@ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, * suitable channel and restart SAP * @psoc: PSOC object information * @vdev_id: vdev id - * @channel: channel to be returned - * @sec_ch: secondary channel to be returned + * @ch_freq: channel to be returned * * This function gets the channel parameters to restart SAP * @@ -85,8 +108,20 @@ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch); + uint8_t vdev_id, uint32_t *ch_freq); + +/** + * hdd_get_ap_6ghz_capable() - Get ap vdev 6ghz capable flags + * @psoc: PSOC object information + * @vdev_id: vdev id + * + * This function gets 6ghz capable information based on hdd ap adapter + * context. + * + * Return: uint32_t, vdev 6g capable flags from enum conn_6ghz_flag + */ +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif /** @@ -262,4 +297,11 @@ hdd_check_and_disconnect_sta_on_invalid_channel(struct hdd_context *hdd_ctx, */ void hdd_stop_sap_due_to_invalid_channel(struct work_struct *work); +/** + * hdd_is_any_sta_connecting() - check if any sta is connecting + * @hdd_ctx: hdd context + * + * Return: true if any sta is connecting + */ +bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx); #endif /* end #if !defined(WLAN_HDD_HOSTAPD_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd_wext.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd_wext.c index 2a9037f0401b66433c99e0abb7f277f920895c9a..4a0518099490cdb95f504f35794a0a10722016be 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd_wext.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd_wext.c @@ -37,12 +37,14 @@ #endif #include "wlan_hdd_power.h" #include "wlan_policy_mgr_ucfg.h" +#include #include #include "wlan_dfs_utils_api.h" #include #include #include "wlan_mlme_ucfg_api.h" #include "wlan_reg_ucfg_api.h" +#include "wlan_hdd_sta_info.h" #define WE_WLAN_VERSION 1 /* WEXT limitation: MAX allowed buf len for any * @@ -140,11 +142,8 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev, int *value = (int *)extra; int sub_cmd = value[0]; struct hdd_context *hdd_ctx; - struct cdp_vdev *vdev = NULL; - struct cdp_pdev *pdev = NULL; - void *soc = NULL; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct cdp_txrx_stats_req req = {0}; - uint8_t count = 0; struct hdd_station_info *sta_info; hdd_enter_dev(dev); @@ -158,39 +157,43 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev, if (0 != ret) return ret; + if (qdf_unlikely(!soc)) { + hdd_err("soc is NULL"); + return -EINVAL; + } + switch (sub_cmd) { case QCSAP_PARAM_SET_TXRX_STATS: { - ret = cds_get_datapath_handles(&soc, &pdev, &vdev, - adapter->vdev_id); - if (ret != 0) { - hdd_err("Invalid Handles"); - break; - } req.stats = value[1]; req.mac_id = value[2]; hdd_info("QCSAP_PARAM_SET_TXRX_STATS stats_id: %d mac_id: %d", req.stats, req.mac_id); - sta_info = adapter->sta_info; + if (value[1] == CDP_TXRX_STATS_28) { req.peer_addr = (char *)&adapter->mac_addr; - ret = cdp_txrx_stats_request(soc, vdev, &req); - - for (count = 0; count < WLAN_MAX_STA_COUNT; count++) { - if (sta_info->in_use) { - hdd_debug("sta: %d: bss_id: %pM", - sta_info->sta_id, - (void *)&sta_info->sta_mac); - req.peer_addr = - (char *)&sta_info->sta_mac; - ret = cdp_txrx_stats_request(soc, vdev, - &req); - } - - sta_info++; + ret = cdp_txrx_stats_request(soc, adapter->vdev_id, + &req); + + hdd_for_each_sta_ref( + adapter->sta_info_list, sta_info, + STA_INFO_SAP_SET_TWO_INTS_GETNONE) { + hdd_debug("bss_id: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( + sta_info->sta_mac.bytes)); + + req.peer_addr = (char *) + &sta_info->sta_mac; + ret = cdp_txrx_stats_request( + soc, adapter->vdev_id, &req); + hdd_put_sta_info_ref( + &adapter->sta_info_list, &sta_info, + true, + STA_INFO_SAP_SET_TWO_INTS_GETNONE); } } else { - ret = cdp_txrx_stats_request(soc, vdev, &req); + ret = cdp_txrx_stats_request(soc, adapter->vdev_id, + &req); } break; @@ -234,12 +237,6 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev, case QCSAP_SET_BA_AGEING_TIMEOUT: hdd_info("QCSAP_SET_BA_AGEING_TIMEOUT: AC[%d] timeout[%d]", value[1], value[2]); - ret = cds_get_datapath_handles(&soc, &pdev, &vdev, - adapter->vdev_id); - if (ret != 0) { - hdd_err("Invalid Handles"); - break; - } /* * value[1] : suppose to be access class, value between[0-3] * value[2]: suppose to be duration in seconds @@ -280,8 +277,8 @@ static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size) for (i = 0; i < size; i++) { macArray = (macList + i)->bytes; - pr_info("ACL entry %i - "QDF_MAC_ADDR_STR"\n", - i, QDF_MAC_ADDR_ARRAY(macArray)); + pr_info("ACL entry %i - "QDF_MAC_ADDR_FMT"\n", + i, QDF_MAC_ADDR_REF(macArray)); } } @@ -339,72 +336,6 @@ static QDF_STATUS hdd_print_acl(struct hdd_adapter *adapter) return QDF_STATUS_SUCCESS; } -/** - * hdd_get_aid_rc() - Get AID and rate code passed from user - * @aid: pointer to AID - * @rc: pointer to rate code - * @set_value: value passed from user - * - * If target is 11ax capable, set_value will have AID left shifted 16 bits - * and 16 bits for rate code. If the target is not 11ax capable, rate code - * will only be 8 bits. - * - * Return: None - */ -static void hdd_get_aid_rc(uint8_t *aid, uint16_t *rc, int set_value) -{ - uint8_t rc_bits; - - if (sme_is_feature_supported_by_fw(DOT11AX)) - rc_bits = 16; - else - rc_bits = 8; - - *aid = set_value >> rc_bits; - *rc = set_value & ((1 << (rc_bits + 1)) - 1); -} - -/** - * hdd_set_peer_rate() - set peer rate - * @adapter: adapter being modified - * @set_value: rate code with AID - * - * Return: 0 on success, negative errno on failure - */ -static int hdd_set_peer_rate(struct hdd_adapter *adapter, int set_value) -{ - uint8_t aid, *peer_mac; - uint16_t rc; - QDF_STATUS status; - - if (adapter->device_mode != QDF_SAP_MODE) { - hdd_err("Invalid devicde mode - %d", adapter->device_mode); - return -EINVAL; - } - - hdd_get_aid_rc(&aid, &rc, set_value); - - if ((adapter->sta_info[aid].in_use) && - (OL_TXRX_PEER_STATE_CONN == adapter->sta_info[aid].peer_state)) { - peer_mac = - (uint8_t *)&(adapter->sta_info[aid].sta_mac.bytes[0]); - hdd_info("Peer AID: %d MAC_ADDR: "QDF_MAC_ADDR_STR, - aid, QDF_MAC_ADDR_ARRAY(peer_mac)); - } else { - hdd_err("No matching peer found for AID: %d", aid); - return -EINVAL; - } - - status = sme_set_peer_param(peer_mac, WMI_PEER_PARAM_FIXED_RATE, - rc, adapter->vdev_id); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("Failed to set peer fixed rate - status: %d", status); - return -EIO; - } - - return 0; -} - int static __iw_softap_setparam(struct net_device *dev, struct iw_request_info *info, @@ -471,9 +402,9 @@ static __iw_softap_setparam(struct net_device *dev, CSA_REASON_USER_INITIATED); hdd_debug("SET Channel Change to new channel= %d", set_value); - ret = hdd_softap_set_channel_change(dev, set_value, - CH_WIDTH_MAX, - false); + ret = hdd_softap_set_channel_change(dev, + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, set_value), + CH_WIDTH_MAX, false); } else { hdd_err("Channel Change Failed, Device in test mode"); ret = -EINVAL; @@ -752,8 +683,8 @@ static __iw_softap_setparam(struct net_device *dev, if (config->SapHw_mode != eCSR_DOT11_MODE_11ac && config->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) { - hdd_err("SET_VHT_RATE error: SapHw_mode= 0x%x, ch: %d", - config->SapHw_mode, config->channel); + hdd_err("SET_VHT_RATE: SapHw_mode= 0x%x, ch_freq: %d", + config->SapHw_mode, config->chan_freq); ret = -EIO; break; } @@ -897,7 +828,9 @@ static __iw_softap_setparam(struct net_device *dev, if (adapter->device_mode != QDF_SAP_MODE) return -EINVAL; - ret = wlansap_set_dfs_target_chnl(mac_handle, set_value); + ret = wlansap_set_dfs_target_chnl(mac_handle, + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, + set_value)); break; } @@ -921,7 +854,6 @@ static __iw_softap_setparam(struct net_device *dev, case QCASAP_SET_RADAR_CMD: { struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - uint8_t ch = ap_ctx->operating_channel; struct wlan_objmgr_pdev *pdev; struct radar_found_info radar; @@ -934,10 +866,11 @@ static __iw_softap_setparam(struct net_device *dev, } qdf_mem_zero(&radar, sizeof(radar)); - if (wlan_reg_is_dfs_ch(pdev, ch)) + if (wlan_reg_is_dfs_for_freq(pdev, ap_ctx->operating_chan_freq)) tgt_dfs_process_radar_ind(pdev, &radar); else - hdd_debug("Ignore set radar, op ch(%d) is not dfs", ch); + hdd_debug("Ignore set radar, op ch_freq(%d) is not dfs", + ap_ctx->operating_chan_freq); break; } @@ -964,7 +897,7 @@ static __iw_softap_setparam(struct net_device *dev, case QCASAP_NSS_CMD: { hdd_debug("QCASAP_NSS_CMD val %d", set_value); - hdd_update_nss(adapter, set_value); + hdd_update_nss(adapter, set_value, set_value); ret = wma_cli_set_command(adapter->vdev_id, WMI_VDEV_PARAM_NSS, set_value, VDEV_CMD); @@ -1029,7 +962,8 @@ static __iw_softap_setparam(struct net_device *dev, break; default: if (soc) - cdp_clear_stats(soc, set_value); + cdp_clear_stats(soc, OL_TXRX_PDEV_ID, + set_value); } break; } @@ -1053,9 +987,6 @@ static __iw_softap_setparam(struct net_device *dev, &adapter->session.ap. sap_config); break; - case QCASAP_SET_PEER_RATE: - ret = hdd_set_peer_rate(adapter, set_value); - break; case QCASAP_PARAM_DCM: hdd_debug("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value); ret = wma_cli_set_command(adapter->vdev_id, @@ -1208,7 +1139,7 @@ static __iw_softap_getparam(struct net_device *dev, switch (sub_cmd) { case QCSAP_PARAM_MAX_ASSOC: - if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc, *value) != + if (ucfg_mlme_get_assoc_sta_limit(hdd_ctx->psoc, value) != QDF_STATUS_SUCCESS) { hdd_err("CFG_ASSOC_STA_LIMIT failed"); ret = -EIO; @@ -1492,8 +1423,8 @@ int __iw_softap_modify_acl(struct net_device *dev, i++; cmd = (int)(*(value + i)); - hdd_debug("Modify ACL mac:" QDF_MAC_ADDR_STR " type: %d cmd: %d", - QDF_MAC_ADDR_ARRAY(peer_mac), list_type, cmd); + hdd_debug("Modify ACL mac:" QDF_MAC_ADDR_FMT " type: %d cmd: %d", + QDF_MAC_ADDR_REF(peer_mac), list_type, cmd); qdf_status = wlansap_modify_acl( WLAN_HDD_GET_SAP_CTX_PTR(adapter), @@ -1532,6 +1463,7 @@ static __iw_softap_getchannel(struct net_device *dev, { struct hdd_adapter *adapter = (netdev_priv(dev)); struct hdd_context *hdd_ctx; + struct hdd_ap_ctx *ap_ctx; int *value = (int *)extra; int ret; @@ -1547,9 +1479,11 @@ static __iw_softap_getchannel(struct net_device *dev, return ret; *value = 0; + ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) - *value = (WLAN_HDD_GET_AP_CTX_PTR( - adapter))->operating_channel; + *value = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + ap_ctx->operating_chan_freq); hdd_exit(); return 0; } @@ -1749,10 +1683,9 @@ static __iw_softap_getassoc_stamacaddr(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct hdd_adapter *adapter = (netdev_priv(dev)); - struct hdd_station_info *sta_info = adapter->sta_info; + struct hdd_station_info *sta_info; struct hdd_context *hdd_ctx; char *buf; - int cnt = 0; int left; int ret; /* maclist_index must be u32 to match userspace */ @@ -1799,18 +1732,17 @@ static __iw_softap_getassoc_stamacaddr(struct net_device *dev, maclist_index = sizeof(maclist_index); left = wrqu->data.length - maclist_index; - spin_lock_bh(&adapter->sta_info_lock); - while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) { - if ((sta_info[cnt].in_use) && - (!qdf_is_macaddr_broadcast(&sta_info[cnt].sta_mac))) { - memcpy(&buf[maclist_index], &(sta_info[cnt].sta_mac), + hdd_for_each_sta_ref(adapter->sta_info_list, sta_info, + STA_INFO_SAP_GETASSOC_STAMACADDR) { + if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) { + memcpy(&buf[maclist_index], &sta_info->sta_mac, QDF_MAC_ADDR_SIZE); maclist_index += QDF_MAC_ADDR_SIZE; left -= QDF_MAC_ADDR_SIZE; } - cnt++; + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SAP_GETASSOC_STAMACADDR); } - spin_unlock_bh(&adapter->sta_info_lock); *((u32 *) buf) = maclist_index; wrqu->data.length = maclist_index; @@ -1887,8 +1819,8 @@ static __iw_softap_disassoc_sta(struct net_device *dev, */ peer_macaddr = (uint8_t *) (extra); - hdd_debug("data " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_macaddr)); + hdd_debug("data " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_macaddr)); wlansap_populate_del_sta_params(peer_macaddr, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, SIR_MAC_MGMT_DISASSOC, @@ -1980,22 +1912,19 @@ static int iw_get_char_setnone(struct net_device *dev, return errno; } -static int __iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +static int iw_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { uint32_t num_channels = 0; uint8_t i = 0; - uint8_t band_start_channel = CHAN_ENUM_1; - uint8_t band_end_channel = MAX_5GHZ_CHANNEL; struct hdd_adapter *hostapd_adapter = (netdev_priv(dev)); struct channel_list_info *channel_list = - (struct channel_list_info *) extra; - bool enable_dfs_scan = true; - enum band_info cur_band = BAND_ALL; + (struct channel_list_info *)extra; + struct regulatory_channel *cur_chan_list = NULL; struct hdd_context *hdd_ctx; int ret; - bool is_dfs_mode_enabled = false; + QDF_STATUS status; hdd_enter_dev(dev); @@ -2008,77 +1937,89 @@ static int __iw_get_channel_list(struct net_device *dev, if (0 != ret) return ret; - if (QDF_STATUS_SUCCESS != ucfg_reg_get_band(hdd_ctx->pdev, - &cur_band)) { - hdd_err("not able get the current frequency band"); + cur_chan_list = qdf_mem_malloc(sizeof(*cur_chan_list) * NUM_CHANNELS); + if (!cur_chan_list) + return -ENOMEM; + + status = ucfg_reg_get_current_chan_list(hdd_ctx->pdev, cur_chan_list); + if (status != QDF_STATUS_SUCCESS) { + hdd_err_rl("Failed to get the current channel list"); + qdf_mem_free(cur_chan_list); return -EIO; } - wrqu->data.length = sizeof(struct channel_list_info); - - if (BAND_2G == cur_band) { - band_start_channel = CHAN_ENUM_1; - band_end_channel = CHAN_ENUM_14; - } else if (BAND_5G == cur_band) { - band_start_channel = CHAN_ENUM_36; - band_end_channel = MAX_5GHZ_CHANNEL; - } - - if (cur_band != BAND_2G) - band_end_channel = MAX_5GHZ_CHANNEL; - ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc, - &enable_dfs_scan); - if (hostapd_adapter->device_mode == QDF_STA_MODE && - enable_dfs_scan) { - is_dfs_mode_enabled = true; - } else if (hostapd_adapter->device_mode == QDF_SAP_MODE) { - if (QDF_STATUS_SUCCESS != ucfg_mlme_get_dfs_master_capability( - hdd_ctx->psoc, &is_dfs_mode_enabled)) { - hdd_err("Fail to get dfs master mode capability"); - return -EINVAL; - } - } - hdd_debug("curBand = %d, StartChannel = %hu, EndChannel = %hu is_dfs_mode_enabled = %d ", - cur_band, band_start_channel, band_end_channel, - is_dfs_mode_enabled); - - for (i = band_start_channel; i <= band_end_channel; i++) { - if ((CHANNEL_STATE_ENABLE == - wlan_reg_get_channel_state(hdd_ctx->pdev, - WLAN_REG_CH_NUM(i))) || - (is_dfs_mode_enabled && CHANNEL_STATE_DFS == - wlan_reg_get_channel_state(hdd_ctx->pdev, - WLAN_REG_CH_NUM(i)))) { - channel_list->channels[num_channels] = - WLAN_REG_CH_NUM(i); - num_channels++; - } - } + for (i = 0; i < NUM_CHANNELS; i++) { + /* + * current channel list includes all channels. do not report + * disabled channels + */ + if (cur_chan_list[i].chan_flags & REGULATORY_CHAN_DISABLED) + continue; + + /* + * do not include 6 GHz channels since they are ambiguous with + * 2.4 GHz and 5 GHz channels. 6 GHz-aware applications should + * not be using this interface, but instead should be using the + * frequency-based interface + */ + if (wlan_reg_is_6ghz_chan_freq(cur_chan_list[i].center_freq)) + continue; + channel_list->channels[num_channels] = + cur_chan_list[i].chan_num; + num_channels++; - hdd_debug("number of channels %d", num_channels); + } + qdf_mem_free(cur_chan_list); + hdd_debug_rl("number of channels %d", num_channels); channel_list->num_channels = num_channels; + wrqu->data.length = num_channels + 1; hdd_exit(); - return 0; } -int iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +int iw_get_channel_list_with_cc(struct net_device *dev, + mac_handle_t mac_handle, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) { - int errno; - struct osif_vdev_sync *vdev_sync; - - errno = osif_vdev_sync_op_start(dev, &vdev_sync); - if (errno) - return errno; + uint8_t i, len; + char *buf; + uint8_t ubuf[CFG_COUNTRY_CODE_LEN] = {0}; + uint8_t ubuf_len = CFG_COUNTRY_CODE_LEN; + struct channel_list_info channel_list; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + hdd_enter_dev(dev); + memset(&channel_list, 0, sizeof(channel_list)); - errno = __iw_get_channel_list(dev, info, wrqu, extra); + if (0 != iw_get_channel_list(dev, info, wrqu, (char *)&channel_list)) { + hdd_err_rl("GetChannelList Failed!!!"); + return -EINVAL; + } + buf = extra; + /* + * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. + * Maximum buffer needed = 5 * number of channels. + * Check if sufficient buffer is available and then + * proceed to fill the buffer. + */ + if (WE_MAX_STR_LEN < (5 * CFG_VALID_CHANNEL_LIST_LEN)) { + hdd_err_rl("Insufficient Buffer to populate channel list"); + return -EINVAL; + } + len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", channel_list.num_channels); + ucfg_reg_get_cc_and_src(mac->psoc, ubuf); + /* Printing Country code in getChannelList */ + for (i = 0; i < (ubuf_len - 1); i++) + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, "%c", ubuf[i]); - osif_vdev_sync_op_stop(vdev_sync); + for (i = 0; i < channel_list.num_channels; i++) + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, " %u", channel_list.channels[i]); + wrqu->data.length = strlen(extra) + 1; - return errno; + hdd_exit(); + return 0; } static @@ -2267,37 +2208,36 @@ static int hdd_softap_get_sta_info(struct hdd_adapter *adapter, uint8_t *buf, int size) { - int i; int written; - uint8_t bc_sta_id; + struct hdd_station_info *sta; hdd_enter(); - bc_sta_id = WLAN_HDD_GET_AP_CTX_PTR(adapter)->broadcast_sta_id; - written = scnprintf(buf, size, "\nstaId staAddress\n"); - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - struct hdd_station_info *sta = &adapter->sta_info[i]; - if (written >= size - 1) + hdd_for_each_sta_ref(adapter->sta_info_list, sta, + STA_INFO_SOFTAP_GET_STA_INFO) { + if (written >= size - 1) { + hdd_put_sta_info_ref(&adapter->sta_info_list, + &sta, true, + STA_INFO_SOFTAP_GET_STA_INFO); break; + } - if (!sta->in_use) - continue; - - if (i == bc_sta_id) + if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes)) { + hdd_put_sta_info_ref(&adapter->sta_info_list, + &sta, true, + STA_INFO_SOFTAP_GET_STA_INFO); continue; + } written += scnprintf(buf + written, size - written, - "%5d "QDF_MAC_ADDR_STR" ecsa=%d\n", - sta->sta_id, - sta->sta_mac.bytes[0], - sta->sta_mac.bytes[1], - sta->sta_mac.bytes[2], - sta->sta_mac.bytes[3], - sta->sta_mac.bytes[4], - sta->sta_mac.bytes[5], + QDF_FULL_MAC_FMT + " ecsa=%d\n", + QDF_FULL_MAC_REF(sta->sta_mac.bytes), sta->ecsa_capable); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true, + STA_INFO_SOFTAP_GET_STA_INFO); } hdd_exit(); @@ -2305,6 +2245,63 @@ static int hdd_softap_get_sta_info(struct hdd_adapter *adapter, return 0; } +static int __iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_context *hdd_ctx; + mac_handle_t mac_handle; + + hdd_enter_dev(dev); + + if (hdd_validate_adapter(adapter)) { + hdd_err_rl("Invalid adapter!!!"); + return -ENODEV; + } + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + ret = hdd_check_private_wext_control(hdd_ctx, info); + if (0 != ret) + return ret; + + mac_handle = hdd_ctx->mac_handle; + + ret = iw_get_channel_list_with_cc(dev, mac_handle, + info, wrqu, extra); + + if (0 != ret) + return -EINVAL; + + hdd_exit(); + return 0; +} + +static int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(dev, &vdev_sync); + if (errno) + return errno; + + errno = __iw_softap_get_channel_list(dev, info, wrqu, extra); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + static int __iw_softap_get_sta_info(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -2442,7 +2439,7 @@ int __iw_get_softap_linkspeed(struct net_device *dev, struct qdf_mac_addr mac_address; char macaddr_string[MAC_ADDRESS_STR_LEN + 1]; QDF_STATUS status = QDF_STATUS_E_FAILURE; - int rc, ret, i; + int rc, ret; hdd_enter_dev(dev); @@ -2482,17 +2479,23 @@ int __iw_get_softap_linkspeed(struct net_device *dev, * link speed for first connected client will be returned. */ if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) { - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - if (adapter->sta_info[i].in_use && - (!qdf_is_macaddr_broadcast - (&adapter->sta_info[i].sta_mac))) { - qdf_copy_macaddr( - &mac_address, - &adapter->sta_info[i]. - sta_mac); + struct hdd_station_info *sta_info; + + hdd_for_each_sta_ref(adapter->sta_info_list, sta_info, + STA_INFO_GET_SOFTAP_LINKSPEED) { + if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) { + qdf_copy_macaddr(&mac_address, + &sta_info->sta_mac); status = QDF_STATUS_SUCCESS; + hdd_put_sta_info_ref( + &adapter->sta_info_list, + &sta_info, true, + STA_INFO_GET_SOFTAP_LINKSPEED); break; } + hdd_put_sta_info_ref(&adapter->sta_info_list, + &sta_info, true, + STA_INFO_GET_SOFTAP_LINKSPEED); } } if (!QDF_IS_STATUS_SUCCESS(status)) { @@ -2546,12 +2549,11 @@ iw_get_softap_linkspeed(struct net_device *dev, * @wrqu: iwpriv command parameter * @extra * - * This function will call wlan_hdd_get_peer_rssi + * This function will call wlan_cfg80211_mc_cp_stats_get_peer_rssi * to get rssi * * Return: 0 on success, otherwise error value */ -#ifdef QCA_SUPPORT_CP_STATS static int __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -2604,8 +2606,8 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, wrqu->data.length += scnprintf(extra + wrqu->data.length, IW_PRIV_SIZE_MASK - wrqu->data.length, - "[%pM] [%d]\n", - rssi_info->peer_stats[i].peer_macaddr, + "["QDF_FULL_MAC_FMT"] [%d]\n", + QDF_FULL_MAC_REF(rssi_info->peer_stats[i].peer_macaddr), rssi_info->peer_stats[i].peer_rssi); wrqu->data.length++; @@ -2614,84 +2616,6 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, return 0; } -#else -static int -__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct hdd_adapter *adapter = netdev_priv(dev); - struct hdd_context *hddctx; - char macaddrarray[MAC_ADDRESS_STR_LEN]; - struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT; - int ret; - char *rssi_info_output = extra; - struct sir_peer_sta_info peer_sta_info; - struct sir_peer_info *rssi_info; - int i; - int buf; - int length; - - hdd_enter(); - - hddctx = WLAN_HDD_GET_CTX(adapter); - ret = wlan_hdd_validate_context(hddctx); - if (ret != 0) - return ret; - - ret = hdd_check_private_wext_control(hddctx, info); - if (0 != ret) - return ret; - - hdd_debug("wrqu->data.length= %d", wrqu->data.length); - - if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { - if (copy_from_user(macaddrarray, - wrqu->data.pointer, - MAC_ADDRESS_STR_LEN - 1)) { - hdd_info("failed to copy data from user buffer"); - return -EFAULT; - } - - macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0'; - hdd_debug("%s", macaddrarray); - - if (!mac_pton(macaddrarray, macaddress.bytes)) - hdd_err("String to Hex conversion Failed"); - } - - ret = wlan_hdd_get_peer_rssi(adapter, &macaddress, &peer_sta_info); - if (ret) { - hdd_err("Unable to retrieve peer rssi: %d", ret); - return ret; - } - /* - * The iwpriv tool default print is before mac addr and rssi. - * Add '\n' before first rssi item to align the first rssi item - * with others - * - * wlan getRSSI: - * [macaddr1] [rssi1] - * [macaddr2] [rssi2] - * [macaddr3] [rssi3] - */ - length = scnprintf(rssi_info_output, WE_MAX_STR_LEN, "\n"); - rssi_info = &peer_sta_info.info[0]; - for (i = 0; i < peer_sta_info.sta_num; i++) { - buf = scnprintf - ( - rssi_info_output + length, WE_MAX_STR_LEN - length, - "[%pM] [%d]\n", - rssi_info[i].peer_macaddr.bytes, - rssi_info[i].rssi - ); - length += buf; - } - wrqu->data.length = length + 1; - hdd_exit(); - - return 0; -} -#endif /** * iw_get_peer_rssi() - get station's rssi @@ -3129,7 +3053,7 @@ static const struct iw_priv_args hostapd_private_args[] = { { WE_SET_THERMAL_THROTTLE_CFG, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, - 0, "setThermalCfg" + 0, "set_thermal_cfg" } , #endif /* FW_THERMAL_THROTTLE_SUPPORT */ @@ -3143,7 +3067,7 @@ static const struct iw_priv_args hostapd_private_args[] = { { QCSAP_IOCTL_GET_CHANNEL_LIST, 0, - IW_PRIV_TYPE_BYTE | sizeof(struct channel_list_info), + IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getChannelList" } , @@ -3241,12 +3165,6 @@ static const struct iw_priv_args hostapd_private_args[] = { 0, "set_11ax_rate" } , - { - QCASAP_SET_PEER_RATE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - 0, "set_peer_rate" - } - , { QCASAP_PARAM_DCM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, @@ -3301,7 +3219,7 @@ static const iw_handler hostapd_private[] = { [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl, [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = - iw_get_channel_list, + iw_softap_get_channel_list, [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info, [QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT - SIOCIWFIRSTPRIV] = diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.c index 702c15bf674f2b73b8b95be0487418ce2aa02ce3..41b306fd07e3c28320213adeeb76b03777ad313c 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,6 +38,7 @@ #include "wma.h" #include "wlan_hdd_napi.h" #include "wlan_mlme_ucfg_api.h" +#include "target_type.h" #ifdef FEATURE_WLAN_ESE #include #include @@ -45,6 +46,7 @@ #include "hif.h" #include "wlan_scan_ucfg_api.h" #include "wlan_reg_ucfg_api.h" +#include "qdf_func_tracker.h" #if defined(LINUX_QCMBR) #define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13) @@ -64,13 +66,6 @@ */ #define SIZE_OF_GETCOUNTRYREV_OUTPUT 20 -/* - * Ibss prop IE from command will be of size: - * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length) - * OUI_DATA should be at least 3 bytes long - */ -#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3) - #ifdef FEATURE_WLAN_ESE #define TID_MIN_VALUE 0 #define TID_MAX_VALUE 15 @@ -149,8 +144,6 @@ struct hdd_drv_cmd { #define WLAN_HDD_MAX_TCP_PORT 65535 #endif -static uint16_t cesium_pid; - /** * drv_cmd_validate() - Validates for space in hdd driver command * @command: pointer to input data (its a NULL terminated string) @@ -175,7 +168,7 @@ struct tsm_priv { }; static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics, - const uint32_t sta_id, void *context) + void *context) { struct osif_request *request; struct tsm_priv *priv; @@ -225,7 +218,6 @@ static int hdd_get_tsm_stats(struct hdd_adapter *adapter, cookie = osif_request_cookie(request); status = sme_get_tsm_stats(hdd_ctx->mac_handle, hdd_get_tsm_stats_cb, - hdd_sta_ctx->conn_info.sta_id[0], hdd_sta_ctx->conn_info.bssid, cookie, tid); if (QDF_STATUS_SUCCESS != status) { @@ -250,16 +242,15 @@ static int hdd_get_tsm_stats(struct hdd_adapter *adapter, } #endif /*FEATURE_WLAN_ESE */ -/** - * hdd_get_ibss_peer_info_cb() - IBSS peer Info request callback - * @context: callback context (adapter supplied by caller) - * @peer_info: Peer info response - * - * This is an asynchronous callback function from SME when the peer info - * is received - * - * Return: 0 for success non-zero for failure +#ifdef QCA_IBSS_SUPPORT +/* + * Ibss prop IE from command will be of size: + * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length) + * OUI_DATA should be at least 3 bytes long */ +#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3) +static uint16_t cesium_pid; + void hdd_get_ibss_peer_info_cb(void *context, tSirPeerInfoRspParams *peer_info) @@ -313,13 +304,14 @@ QDF_STATUS hdd_cfg80211_get_ibss_peer_info_all(struct hdd_adapter *adapter) { QDF_STATUS status; unsigned long rc; + struct qdf_mac_addr bcast = QDF_MAC_ADDR_BCAST_INIT; INIT_COMPLETION(adapter->ibss_peer_info_comp); status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle, adapter, hdd_get_ibss_peer_info_cb, - true, 0xFF); + true, bcast.bytes); if (QDF_STATUS_SUCCESS == status) { rc = wait_for_completion_timeout @@ -348,7 +340,7 @@ QDF_STATUS hdd_cfg80211_get_ibss_peer_info_all(struct hdd_adapter *adapter) * Return: 0 for success non-zero for failure */ static QDF_STATUS -hdd_cfg80211_get_ibss_peer_info(struct hdd_adapter *adapter, uint8_t sta_id) +hdd_cfg80211_get_ibss_peer_info(struct hdd_adapter *adapter, uint8_t *mac_addr) { unsigned long rc; QDF_STATUS status; @@ -358,7 +350,7 @@ hdd_cfg80211_get_ibss_peer_info(struct hdd_adapter *adapter, uint8_t sta_id) status = sme_request_ibss_peer_info(adapter->hdd_ctx->mac_handle, adapter, hdd_get_ibss_peer_info_cb, - false, sta_id); + false, mac_addr); if (QDF_STATUS_SUCCESS == status) { rc = wait_for_completion_timeout( @@ -417,196 +409,855 @@ hdd_parse_get_ibss_peer_info(uint8_t *command, return QDF_STATUS_SUCCESS; } -static void hdd_get_band_helper(struct hdd_context *hdd_ctx, int *ui_band) +static void hdd_tx_fail_ind_callback(uint8_t *macaddr, uint8_t seq_no) { - enum band_info band = -1; + int payload_len; + struct sk_buff *skb; + struct nlmsghdr *nlh; + uint8_t *data; - ucfg_reg_get_band(hdd_ctx->pdev, &band); - switch (band) { - case BAND_ALL: - *ui_band = WLAN_HDD_UI_BAND_AUTO; - break; + payload_len = ETH_ALEN; - case BAND_2G: - *ui_band = WLAN_HDD_UI_BAND_2_4_GHZ; - break; + if (0 == cesium_pid || !cesium_nl_srv_sock) { + hdd_err("cesium process not registered"); + return; + } - case BAND_5G: - *ui_band = WLAN_HDD_UI_BAND_5_GHZ; - break; + skb = nlmsg_new(payload_len, GFP_ATOMIC); + if (!skb) { + hdd_err("nlmsg_new() failed for msg size[%d]", + NLMSG_SPACE(payload_len)); + return; + } - default: - hdd_warn("Invalid Band %d", band); - *ui_band = -1; - break; + nlh = nlmsg_put(skb, cesium_pid, seq_no, 0, payload_len, NLM_F_REQUEST); + + if (!nlh) { + hdd_err("nlmsg_put() failed for msg size[%d]", + NLMSG_SPACE(payload_len)); + + kfree_skb(skb); + return; + } + + data = nlmsg_data(nlh); + memcpy(data, macaddr, ETH_ALEN); + + if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0) { + hdd_err("nlmsg_unicast() failed for msg size[%d]", + NLMSG_SPACE(payload_len)); } } /** - * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel - * @data: input data - * @target_ap_bssid: pointer to bssid (output parameter) - * @channel: pointer to channel (output parameter) + * hdd_parse_user_params() - return a pointer to the next argument + * @command: Input argument string + * @arg: Output pointer to the next argument * - * Return: 0 if parsing is successful; -EINVAL otherwise + * This function parses argument stream and finds the pointer + * to the next argument + * + * Return: 0 if the next argument found; -EINVAL otherwise */ -static int _hdd_parse_bssid_and_chan(const uint8_t **data, - uint8_t *bssid, - uint8_t *channel) +static int hdd_parse_user_params(uint8_t *command, uint8_t **arg) { - const uint8_t *in_ptr; - int v = 0; - int temp_int; - uint8_t temp_buf[32]; + uint8_t *cursor; - /* 12 hexa decimal digits, 5 ':' and '\0' */ - uint8_t mac_addr[18]; + cursor = strnchr(command, strlen(command), SPACE_ASCII_VALUE); - if (!data || !*data) + /* no argument remains ? */ + if (!cursor) return -EINVAL; - in_ptr = *data; - - in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); - /* no argument after the command */ - if (!in_ptr) - goto error; - /* no space after the command */ - else if (SPACE_ASCII_VALUE != *in_ptr) - goto error; - - /* remove empty spaces */ - while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) - in_ptr++; - - /* no argument followed by spaces */ - if ('\0' == *in_ptr) - goto error; - - v = sscanf(in_ptr, "%17s", mac_addr); - if (!((1 == v) && hdd_is_valid_mac_address(mac_addr))) { - hdd_err("Invalid MAC address or All hex inputs are not read (%d)", - v); - goto error; - } - - bssid[0] = hex_to_bin(mac_addr[0]) << 4 | - hex_to_bin(mac_addr[1]); - bssid[1] = hex_to_bin(mac_addr[3]) << 4 | - hex_to_bin(mac_addr[4]); - bssid[2] = hex_to_bin(mac_addr[6]) << 4 | - hex_to_bin(mac_addr[7]); - bssid[3] = hex_to_bin(mac_addr[9]) << 4 | - hex_to_bin(mac_addr[10]); - bssid[4] = hex_to_bin(mac_addr[12]) << 4 | - hex_to_bin(mac_addr[13]); - bssid[5] = hex_to_bin(mac_addr[15]) << 4 | - hex_to_bin(mac_addr[16]); + /* no space after the current arg ? */ + if (SPACE_ASCII_VALUE != *cursor) + return -EINVAL; - /* point to the next argument */ - in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); - /* no argument after the command */ - if (!in_ptr) - goto error; + cursor++; /* remove empty spaces */ - while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) - in_ptr++; - - /* no argument followed by spaces */ - if ('\0' == *in_ptr) - goto error; - - /* get the next argument ie the channel number */ - v = sscanf(in_ptr, "%31s ", temp_buf); - if (1 != v) - goto error; + while (SPACE_ASCII_VALUE == *cursor) + cursor++; - v = kstrtos32(temp_buf, 10, &temp_int); - if ((v < 0) || (temp_int < 0) || - (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + /* no argument after the spaces ? */ + if ('\0' == *cursor) return -EINVAL; - *channel = temp_int; - *data = in_ptr; + *arg = cursor; + return 0; -error: - *data = in_ptr; - return -EINVAL; } /** - * hdd_parse_send_action_frame_data() - HDD Parse send action frame data - * @command: Pointer to input data - * @bssid: Pointer to target Ap bssid - * @channel: Pointer to the Target AP channel - * @dwell_time: Pointer to the time to stay off-channel - * after transmitting action frame - * @buf: Pointer to data - * @buf_len: Pointer to data length - * - * This function parses the send action frame data passed in the format - * SENDACTIONFRAME + * hdd_parse_ibsstx_fail_event_params - Parse params + * for SETIBSSTXFAILEVENT + * @command: Input ibss tx fail event argument + * @tx_fail_count: (Output parameter) Tx fail counter + * @pid: (Output parameter) PID * - * Return: 0 for success non-zero for failure + * Return: 0 if the parsing succeeds; -EINVAL otherwise */ -static int -hdd_parse_send_action_frame_v1_data(const uint8_t *command, - uint8_t *bssid, - uint8_t *channel, uint8_t *dwell_time, - uint8_t **buf, uint8_t *buf_len) +static int hdd_parse_ibsstx_fail_event_params(uint8_t *command, + uint8_t *tx_fail_count, + uint16_t *pid) { - const uint8_t *in_ptr = command; - const uint8_t *end_ptr; - int temp_int; - int j = 0; - int i = 0; - int v = 0; - uint8_t temp_buf[32]; - uint8_t temp_u8 = 0; - - if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel)) - return -EINVAL; + uint8_t *param = NULL; + int ret; - /* point to the next argument */ - in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); - /* no argument after the command */ - if (!in_ptr) - return -EINVAL; - /* removing empty spaces */ - while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) - in_ptr++; + ret = hdd_parse_user_params(command, ¶m); - /* no argument followed by spaces */ - if ('\0' == *in_ptr) - return -EINVAL; + if (0 == ret && param) { + if (1 != sscanf(param, "%hhu", tx_fail_count)) { + ret = -EINVAL; + goto done; + } + } else { + goto done; + } - /* getting the next argument ie the dwell time */ - v = sscanf(in_ptr, "%31s ", temp_buf); - if (1 != v) - return -EINVAL; + if (0 == *tx_fail_count) { + *pid = 0; + goto done; + } - v = kstrtos32(temp_buf, 10, &temp_int); - if (v < 0 || temp_int < 0) - return -EINVAL; + command = param; + command++; - *dwell_time = temp_int; + ret = hdd_parse_user_params(command, ¶m); - /* point to the next argument */ - in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); - /* no argument after the command */ - if (!in_ptr) - return -EINVAL; - /* removing empty spaces */ - while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) - in_ptr++; + if (0 == ret) { + if (1 != sscanf(param, "%hu", pid)) { + ret = -EINVAL; + goto done; + } + } else { + goto done; + } - /* no argument followed by spaces */ - if ('\0' == *in_ptr) - return -EINVAL; +done: + return ret; +} - /* find the length of data */ - end_ptr = in_ptr; +/* Function header is left blank intentionally */ +static int hdd_parse_set_ibss_oui_data_command(uint8_t *command, uint8_t *ie, + int32_t *oui_length, int32_t limit) +{ + uint8_t len; + uint8_t data; + + while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) { + command++; + limit--; + } + + len = 2; + + while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && + (limit > 1)) { + sscanf(command, "%02x", (unsigned int *)&data); + ie[len++] = data; + command += 2; + limit -= 2; + } + + *oui_length = len - 2; + + while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) { + command++; + limit--; + } + + while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && + (limit > 1)) { + sscanf(command, "%02x", (unsigned int *)&data); + ie[len++] = data; + command += 2; + limit -= 2; + } + + ie[0] = WLAN_ELEMID_VENDOR; + ie[1] = len - 2; + + return len; +} + +/** + * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command + * @adapter: Pointer to adapter + * @hdd_ctx: Pointer to HDD context + * @command: Pointer to command string + * @command_len : Command length + * @priv_data : Pointer to priv data + * + * Return: + * int status code + */ +static int drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int i = 0; + int status; + int ret = 0; + uint8_t *ibss_ie; + int32_t oui_length = 0; + uint32_t ibss_ie_length; + uint8_t *value = command; + tSirModifyIE modify_ie; + struct csr_roam_profile *roam_profile; + mac_handle_t mac_handle; + + if (QDF_IBSS_MODE != adapter->device_mode) { + hdd_debug("Device_mode %s(%d) not IBSS", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + return ret; + } + + hdd_debug("received command %s", ((char *)value)); + + /* validate argument of command */ + if (strlen(value) <= command_len) { + hdd_err("No arguments in command length %zu", + strlen(value)); + ret = -EFAULT; + goto exit; + } + + /* moving to arguments of commands */ + value = value + command_len; + command_len = strlen(value); + + /* oui_data can't be less than 3 bytes */ + if (command_len < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) { + hdd_err("Invalid SETIBSSBEACONOUIDATA command length %d", + command_len); + ret = -EFAULT; + goto exit; + } + + ibss_ie = qdf_mem_malloc(command_len); + if (!ibss_ie) { + hdd_err("Could not allocate memory for command length %d", + command_len); + ret = -ENOMEM; + goto exit; + } + + ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie, + &oui_length, + command_len); + if (ibss_ie_length <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) { + hdd_err("Could not parse command %s return length %d", + value, ibss_ie_length); + ret = -EFAULT; + qdf_mem_free(ibss_ie); + goto exit; + } + + roam_profile = hdd_roam_profile(adapter); + + qdf_copy_macaddr(&modify_ie.bssid, + roam_profile->BSSIDs.bssid); + + modify_ie.vdev_id = adapter->vdev_id; + modify_ie.notify = true; + modify_ie.ieID = WLAN_ELEMID_VENDOR; + modify_ie.ieIDLen = ibss_ie_length; + modify_ie.ieBufferlength = ibss_ie_length; + modify_ie.pIEBuffer = ibss_ie; + modify_ie.oui_length = oui_length; + + hdd_warn("ibss_ie length %d oui_length %d ibss_ie:", + ibss_ie_length, oui_length); + while (i < modify_ie.ieBufferlength) + hdd_warn("0x%x", ibss_ie[i++]); + + /* Probe Bcn modification */ + mac_handle = hdd_ctx->mac_handle; + sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_BCN); + + /* Populating probe resp frame */ + sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_RESP); + + qdf_mem_free(ibss_ie); + + status = sme_send_cesium_enable_ind(mac_handle, + adapter->vdev_id); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("Could not send cesium enable indication %d", + status); + ret = -EINVAL; + goto exit; + } + +exit: + return ret; +} + +static int drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int ret = 0; + int status = QDF_STATUS_SUCCESS; + struct hdd_station_ctx *sta_ctx = NULL; + char *extra = NULL; + int idx = 0; + int length = 0; + uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + uint32_t print_break_index = 0; + + if (QDF_IBSS_MODE != adapter->device_mode) { + hdd_warn("Unsupported in mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + return -EINVAL; + } + + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + hdd_debug("Received GETIBSSPEERINFOALL Command"); + + /* Handle the command */ + status = hdd_cfg80211_get_ibss_peer_info_all(adapter); + if (QDF_STATUS_SUCCESS == status) { + size_t user_size = qdf_min(WLAN_MAX_BUF_SIZE, + priv_data->total_len); + + /* + * The variable extra needed to be allocated on the heap since + * amount of memory required to copy the data for 32 devices + * exceeds the size of 1024 bytes of default stack size. On + * 64 bit devices, the default max stack size of 2048 bytes + */ + extra = qdf_mem_malloc(user_size); + + if (!extra) { + hdd_err("memory allocation failed"); + ret = -ENOMEM; + goto exit; + } + + /* Copy number of stations */ + length = scnprintf(extra, user_size, "%d ", + sta_ctx->ibss_peer_info.numPeers); + print_break_index = length; + for (idx = 0; idx < sta_ctx->ibss_peer_info.numPeers; + idx++) { + int8_t rssi; + uint32_t tx_rate; + + qdf_mem_copy(mac_addr, + sta_ctx->ibss_peer_info.peerInfoParams[idx]. + mac_addr, sizeof(mac_addr)); + + tx_rate = + sta_ctx->ibss_peer_info.peerInfoParams[idx]. + txRate; + /* + * Only lower 3 bytes are rate info. Mask of the MSByte + */ + tx_rate &= 0x00FFFFFF; + + rssi = sta_ctx->ibss_peer_info.peerInfoParams[idx]. + rssi; + + length += scnprintf(extra + length, + user_size - length, + QDF_FULL_MAC_FMT" %d %d ", + QDF_FULL_MAC_REF(mac_addr), + tx_rate, rssi); + /* + * cdf_trace_msg has limitation of 512 bytes for the + * print buffer. Hence printing the data in two chunks. + * The first chunk will have the data for 16 devices + * and the second chunk will have the rest. + */ + if (idx < NUM_OF_STA_DATA_TO_PRINT) + print_break_index = length; + } + + /* + * Copy the data back into buffer, if the data to copy is + * more than 512 bytes than we will split the data and do + * it in two shots + */ + if (copy_to_user(priv_data->buf, extra, print_break_index)) { + hdd_err("Copy into user data buffer failed"); + ret = -EFAULT; + goto mem_free; + } + + /* This overwrites the last space, which we already copied */ + extra[print_break_index - 1] = '\0'; + hdd_debug("%s", extra); + + if (length > print_break_index) { + if (copy_to_user + (priv_data->buf + print_break_index, + extra + print_break_index, + length - print_break_index + 1)) { + hdd_err("Copy into user data buffer failed"); + ret = -EFAULT; + goto mem_free; + } + hdd_debug("%s", &extra[print_break_index]); + } + } else { + /* Command failed, log error */ + hdd_err("GETIBSSPEERINFOALL command failed with status code %d", + status); + ret = -EINVAL; + goto exit; + } + ret = 0; + +mem_free: + qdf_mem_free(extra); +exit: + return ret; +} + +/* Peer Info command */ +static int drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int ret = 0; + uint8_t *value = command; + QDF_STATUS status; + struct hdd_station_ctx *sta_ctx = NULL; + char extra[128] = { 0 }; + uint32_t length = 0; + struct qdf_mac_addr peer_macaddr; + + if (QDF_IBSS_MODE != adapter->device_mode) { + hdd_warn("Unsupported in mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + return -EINVAL; + } + + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + hdd_debug("Received GETIBSSPEERINFO Command"); + + /* if there are no peers, no need to continue with the command */ + if (eConnectionState_IbssConnected != + sta_ctx->conn_info.conn_state) { + hdd_err("No IBSS Peers coalesced"); + ret = -EINVAL; + goto exit; + } + + /* Parse the incoming command buffer */ + status = hdd_parse_get_ibss_peer_info(value, &peer_macaddr); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("Invalid GETIBSSPEERINFO command"); + ret = -EINVAL; + goto exit; + } + + /* Handle the command */ + status = hdd_cfg80211_get_ibss_peer_info(adapter, peer_macaddr.bytes); + if (QDF_STATUS_SUCCESS == status) { + uint32_t tx_rate = + sta_ctx->ibss_peer_info.peerInfoParams[0].txRate; + /* Only lower 3 bytes are rate info. Mask of the MSByte */ + tx_rate &= 0x00FFFFFF; + + length = scnprintf(extra, sizeof(extra), "%d %d", + (int)tx_rate, + (int)sta_ctx->ibss_peer_info. + peerInfoParams[0].rssi); + length = QDF_MIN(priv_data->total_len, length + 1); + + /* Copy the data back into buffer */ + if (copy_to_user(priv_data->buf, &extra, length)) { + hdd_err("copy data to user buffer failed GETIBSSPEERINFO command"); + ret = -EFAULT; + goto exit; + } + } else { + /* Command failed, log error */ + hdd_err("GETIBSSPEERINFO command failed with status code %d", + status); + ret = -EINVAL; + goto exit; + } + + /* Success ! */ + hdd_debug("%s", extra); + ret = 0; + +exit: + return ret; +} + +static int drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int ret = 0; + char *value; + uint8_t tx_fail_count = 0; + uint16_t pid = 0; + mac_handle_t mac_handle; + + value = command; + + ret = hdd_parse_ibsstx_fail_event_params(value, &tx_fail_count, &pid); + + if (0 != ret) { + hdd_err("Failed to parse SETIBSSTXFAILEVENT arguments"); + goto exit; + } + + hdd_debug("tx_fail_cnt=%hhu, pid=%hu", tx_fail_count, pid); + mac_handle = hdd_ctx->mac_handle; + + if (0 == tx_fail_count) { + /* Disable TX Fail Indication */ + if (QDF_STATUS_SUCCESS == + sme_tx_fail_monitor_start_stop_ind(mac_handle, + tx_fail_count, + NULL)) { + cesium_pid = 0; + } else { + hdd_err("failed to disable TX Fail Event"); + ret = -EINVAL; + } + } else { + if (QDF_STATUS_SUCCESS == + sme_tx_fail_monitor_start_stop_ind(mac_handle, + tx_fail_count, + (void *)hdd_tx_fail_ind_callback)) { + cesium_pid = pid; + hdd_debug("Registered Cesium pid %u", + cesium_pid); + } else { + hdd_err("Failed to enable TX Fail Monitoring"); + ret = -EINVAL; + } + } + +exit: + return ret; +} +#else +/** + * drv_cmd_get_ibss_peer_info() - get ibss peer info all + * @adapter: Pointer to adapter + * @hdd_ctx: Pointer to HDD context + * @command: Pointer to command string + * @command_len : Command length + * @priv_data : Pointer to priv data + * + * This function is dummy + * + * Return: 0 + */ +static inline int +drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + return 0; +} + +/** + * drv_cmd_get_ibss_peer_info() - get ibss peer info + * @adapter: Pointer to adapter + * @hdd_ctx: Pointer to HDD context + * @command: Pointer to command string + * @command_len : Command length + * @priv_data : Pointer to priv data + * + * This function is dummy + * + * Return: 0 + */ +static inline int +drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + return 0; +} + +/** + * drv_cmd_set_ibss_tx_fail_event() - set ibss tx fail event + * @adapter: Pointer to adapter + * @hdd_ctx: Pointer to HDD context + * @command: Pointer to command string + * @command_len : Command length + * @priv_data : Pointer to priv data + * + * This function is dummy + * + * Return: 0 + */ +static inline int +drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + return 0; +} + +/** + * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command + * @adapter: Pointer to adapter + * @hdd_ctx: Pointer to HDD context + * @command: Pointer to command string + * @command_len : Command length + * @priv_data : Pointer to priv data + * + * This function is dummy + * + * Return: 0 + */ +static inline int +drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + return 0; +} +#endif + +static void hdd_get_band_helper(struct hdd_context *hdd_ctx, int *ui_band) +{ + enum band_info band = -1; + + ucfg_reg_get_band(hdd_ctx->pdev, &band); + switch (band) { + case BAND_ALL: + *ui_band = WLAN_HDD_UI_BAND_AUTO; + break; + + case BAND_2G: + *ui_band = WLAN_HDD_UI_BAND_2_4_GHZ; + break; + + case BAND_5G: + *ui_band = WLAN_HDD_UI_BAND_5_GHZ; + break; + + default: + hdd_warn("Invalid Band %d", band); + *ui_band = -1; + break; + } +} + +/** + * hdd_check_and_fill_freq() - to validate chan and convert into freq + * @in_chan: input as channel number or freq to be checked + * @freq: frequency for input in_chan (output parameter) + * + * This function checks input "in_chan" is channel number, if yes then fills + * appropriate frequency into "freq" out param. If the "in_param" is greater + * than WNI_CFG_CURRENT_CHANNEL_STAMAX then checks for valid frequencies. + * + * Return: true if "in_chan" is valid channel/frequency; false otherwise + */ +static bool hdd_check_and_fill_freq(uint32_t in_chan, qdf_freq_t *freq) +{ + if (in_chan <= WNI_CFG_CURRENT_CHANNEL_STAMAX) + *freq = wlan_chan_to_freq(in_chan); + else if (WLAN_REG_IS_24GHZ_CH_FREQ(in_chan) || + WLAN_REG_IS_5GHZ_CH_FREQ(in_chan) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(in_chan)) + *freq = in_chan; + else + return false; + + return true; +} + +/** + * _hdd_parse_bssid_and_chan() - helper function to parse bssid and channel + * @data: input data + * @target_ap_bssid: pointer to bssid (output parameter) + * @freq: pointer to freq (output parameter) + * + * Return: 0 if parsing is successful; -EINVAL otherwise + */ +static int _hdd_parse_bssid_and_chan(const uint8_t **data, + uint8_t *bssid, + qdf_freq_t *freq) +{ + const uint8_t *in_ptr; + int v = 0; + int temp_int; + uint8_t temp_buf[32]; + + /* 12 hexa decimal digits, 5 ':' and '\0' */ + uint8_t mac_addr[18]; + + if (!data || !*data) + return -EINVAL; + + in_ptr = *data; + + in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); + /* no argument after the command */ + if (!in_ptr) + goto error; + /* no space after the command */ + else if (SPACE_ASCII_VALUE != *in_ptr) + goto error; + + /* remove empty spaces */ + while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) + in_ptr++; + + /* no argument followed by spaces */ + if ('\0' == *in_ptr) + goto error; + + v = sscanf(in_ptr, "%17s", mac_addr); + if (!((1 == v) && hdd_is_valid_mac_address(mac_addr))) { + hdd_err("Invalid MAC address or All hex inputs are not read (%d)", + v); + goto error; + } + + bssid[0] = hex_to_bin(mac_addr[0]) << 4 | + hex_to_bin(mac_addr[1]); + bssid[1] = hex_to_bin(mac_addr[3]) << 4 | + hex_to_bin(mac_addr[4]); + bssid[2] = hex_to_bin(mac_addr[6]) << 4 | + hex_to_bin(mac_addr[7]); + bssid[3] = hex_to_bin(mac_addr[9]) << 4 | + hex_to_bin(mac_addr[10]); + bssid[4] = hex_to_bin(mac_addr[12]) << 4 | + hex_to_bin(mac_addr[13]); + bssid[5] = hex_to_bin(mac_addr[15]) << 4 | + hex_to_bin(mac_addr[16]); + + /* point to the next argument */ + in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); + /* no argument after the command */ + if (!in_ptr) + goto error; + + /* remove empty spaces */ + while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) + in_ptr++; + + /* no argument followed by spaces */ + if ('\0' == *in_ptr) + goto error; + + /* get the next argument ie the channel/freq number */ + v = sscanf(in_ptr, "%31s ", temp_buf); + if (1 != v) + goto error; + + v = kstrtos32(temp_buf, 10, &temp_int); + if (v < 0 || temp_int < 0) + goto error; + else if (!hdd_check_and_fill_freq(temp_int, freq)) + goto error; + + *data = in_ptr; + return 0; +error: + *data = in_ptr; + return -EINVAL; +} + +/** + * hdd_parse_send_action_frame_v1_data() - HDD Parse send action frame data + * @command: Pointer to input data + * @bssid: Pointer to target Ap bssid + * @channel: Pointer to the Target AP channel + * @dwell_time: Pointer to the time to stay off-channel + * after transmitting action frame + * @buf: Pointer to data + * @buf_len: Pointer to data length + * + * This function parses the send action frame data passed in the format + * SENDACTIONFRAME + * + * + * Return: 0 for success non-zero for failure + */ +static int +hdd_parse_send_action_frame_v1_data(const uint8_t *command, + uint8_t *bssid, + qdf_freq_t *freq, uint8_t *dwell_time, + uint8_t **buf, uint8_t *buf_len) +{ + const uint8_t *in_ptr = command; + const uint8_t *end_ptr; + int temp_int; + int j = 0; + int i = 0; + int v = 0; + uint8_t temp_buf[32]; + uint8_t temp_u8 = 0; + + if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, freq)) + return -EINVAL; + + /* point to the next argument */ + in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); + /* no argument after the command */ + if (!in_ptr) + return -EINVAL; + /* removing empty spaces */ + while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) + in_ptr++; + + /* no argument followed by spaces */ + if ('\0' == *in_ptr) + return -EINVAL; + + /* getting the next argument ie the dwell time */ + v = sscanf(in_ptr, "%31s ", temp_buf); + if (1 != v) + return -EINVAL; + + v = kstrtos32(temp_buf, 10, &temp_int); + if (v < 0 || temp_int < 0) + return -EINVAL; + + *dwell_time = temp_int; + + /* point to the next argument */ + in_ptr = strnchr(in_ptr, strlen(in_ptr), SPACE_ASCII_VALUE); + /* no argument after the command */ + if (!in_ptr) + return -EINVAL; + /* removing empty spaces */ + while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr)) + in_ptr++; + + /* no argument followed by spaces */ + if ('\0' == *in_ptr) + return -EINVAL; + + /* find the length of data */ + end_ptr = in_ptr; while (('\0' != *end_ptr)) end_ptr++; @@ -652,20 +1303,20 @@ hdd_parse_send_action_frame_v1_data(const uint8_t *command, * hdd_parse_reassoc_command_data() - HDD Parse reassoc command data * @command: Pointer to input data (its a NULL terminated string) * @bssid: Pointer to target Ap bssid - * @channel: Pointer to the Target AP channel + * @freq: Pointer to the Target AP frequency * * This function parses the reasoc command data passed in the format - * REASSOC + * REASSOC * * Return: 0 for success non-zero for failure */ static int hdd_parse_reassoc_command_v1_data(const uint8_t *command, uint8_t *bssid, - uint8_t *channel) + qdf_freq_t *freq) { const uint8_t *in_ptr = command; - if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, channel)) + if (_hdd_parse_bssid_and_chan(&in_ptr, bssid, freq)) return -EINVAL; return 0; @@ -674,7 +1325,7 @@ static int hdd_parse_reassoc_command_v1_data(const uint8_t *command, #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter, const tSirMacAddr bssid, - int channel) + uint32_t ch_freq) { struct hdd_station_ctx *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -685,24 +1336,13 @@ QDF_STATUS hdd_wma_send_fastreassoc_cmd(struct hdd_adapter *adapter, qdf_mem_copy(connected_bssid, hdd_sta_ctx->conn_info.bssid.bytes, ETH_ALEN); return sme_fast_reassoc(adapter->hdd_ctx->mac_handle, - roam_profile, bssid, channel, + roam_profile, bssid, ch_freq, adapter->vdev_id, connected_bssid); } #endif -/** - * hdd_reassoc() - perform a userspace-directed reassoc - * @adapter: Adapter upon which the command was received - * @bssid: BSSID with which to reassociate - * @channel: channel upon which to reassociate - * @src: The source for the trigger of this action - * - * This function performs a userspace-directed reassoc operation - * - * Return: 0 for success non-zero for failure - */ int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid, - uint8_t channel, const handoff_src src) + uint32_t ch_freq, const handoff_src src) { struct hdd_station_ctx *sta_ctx; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -745,23 +1385,21 @@ int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid, * use the current connections's channel. */ if (!memcmp(bssid, sta_ctx->conn_info.bssid.bytes, - QDF_MAC_ADDR_SIZE)) { + QDF_MAC_ADDR_SIZE)) { hdd_warn("Reassoc BSSID is same as currently associated AP bssid"); - channel = sta_ctx->conn_info.channel; + ch_freq = sta_ctx->conn_info.chan_freq; } - /* Check channel number is a valid channel number */ if (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, channel)) { - hdd_err("Invalid Channel: %d", channel); + wlan_hdd_validate_operation_channel(adapter, ch_freq)) { + hdd_err("Invalid Ch freq: %d", ch_freq); ret = -EINVAL; goto exit; } /* Proceed with reassoc */ if (roaming_offload_enabled(hdd_ctx)) { - status = hdd_wma_send_fastreassoc_cmd(adapter, - bssid, (int)channel); + status = hdd_wma_send_fastreassoc_cmd(adapter, bssid, ch_freq); if (status != QDF_STATUS_SUCCESS) { hdd_err("Failed to send fast reassoc cmd"); ret = -EINVAL; @@ -769,7 +1407,7 @@ int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid, } else { tCsrHandoffRequest handoff; - handoff.channel = channel; + handoff.ch_freq = ch_freq; handoff.src = src; qdf_mem_copy(handoff.bssid.bytes, bssid, QDF_MAC_ADDR_SIZE); sme_handoff_request(hdd_ctx->mac_handle, adapter->vdev_id, @@ -786,27 +1424,28 @@ int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid, * * This function parses the v1 REASSOC command with the format * - * REASSOC xx:xx:xx:xx:xx:xx CH + * REASSOC xx:xx:xx:xx:xx:xx CH/FREQ * * Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the - * BSSID and CH is the ASCII representation of the channel. For - * example + * BSSID and CH/FREQ is the ASCII representation of the channel/frequency. + * For example * * REASSOC 00:0a:0b:11:22:33 48 + * REASSOC 00:0a:0b:11:22:33 2412 * * Return: 0 for success non-zero for failure */ static int hdd_parse_reassoc_v1(struct hdd_adapter *adapter, const char *command) { - uint8_t channel = 0; + qdf_freq_t freq = 0; tSirMacAddr bssid; int ret; - ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel); + ret = hdd_parse_reassoc_command_v1_data(command, bssid, &freq); if (ret) hdd_err("Failed to parse reassoc command data"); else - ret = hdd_reassoc(adapter, bssid, channel, REASSOC); + ret = hdd_reassoc(adapter, bssid, freq, REASSOC); return ret; } @@ -830,6 +1469,7 @@ static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter, { struct android_wifi_reassoc_params params; tSirMacAddr bssid; + qdf_freq_t freq = 0; int ret; if (total_len < sizeof(params) + 8) { @@ -844,8 +1484,18 @@ static int hdd_parse_reassoc_v2(struct hdd_adapter *adapter, hdd_err("MAC address parsing failed"); ret = -EINVAL; } else { - ret = hdd_reassoc(adapter, bssid, params.channel, REASSOC); + /* + * In Reassoc command, user can send channel number or frequency + * along with BSSID. If params.channel param of REASSOC command + * is less than WNI_CFG_CURRENT_CHANNEL_STAMAX, then host + * consider this as channel number else frequency. + */ + if (!hdd_check_and_fill_freq(params.channel, &freq)) + return -EINVAL; + + ret = hdd_reassoc(adapter, bssid, freq, REASSOC); } + return ret; } @@ -871,7 +1521,7 @@ static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command, /* both versions start with "REASSOC " * v1 has a bssid and channel # as an ASCII string - * REASSOC xx:xx:xx:xx:xx:xx CH + * REASSOC xx:xx:xx:xx:xx:xx CH/FREQ * v2 has a C struct * REASSOC * @@ -900,7 +1550,7 @@ static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command, * hdd_sendactionframe() - send a userspace-supplied action frame * @adapter: Adapter upon which the command was received * @bssid: BSSID target of the action frame - * @channel: Channel upon which to send the frame + * @freq: Frequency upon which to send the frame * @dwell_time: Amount of time to dwell when the frame is sent * @payload_len:Length of the payload * @payload: Payload of the frame @@ -911,7 +1561,7 @@ static int hdd_parse_reassoc(struct hdd_adapter *adapter, const char *command, */ static int hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, - const uint8_t channel, const uint8_t dwell_time, + const qdf_freq_t freq, const uint8_t dwell_time, const int payload_len, const uint8_t *payload) { struct ieee80211_channel chan; @@ -927,6 +1577,11 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, struct cfg80211_mgmt_tx_params params; #endif + if (payload_len < sizeof(tSirMacVendorSpecificFrameHdr)) { + hdd_warn("Invalid payload length: %d", payload_len); + return -EINVAL; + } + if (QDF_STA_MODE != adapter->device_mode) { hdd_warn("Unsupported in mode %s(%d)", qdf_opmode_str(adapter->device_mode), @@ -955,7 +1610,7 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, goto exit; } - chan.center_freq = sme_chn_to_freq(channel); + chan.center_freq = freq; /* Check if it is specific action frame */ if (vendor->category == SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY) { @@ -963,16 +1618,14 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, if (!qdf_mem_cmp(vendor->Oui, oui, 3)) { /* - * if the channel number is different from operating - * channel then no need to send action frame + * if the freq number is different from operating + * freq then no need to send action frame */ - if (channel != 0) { - if (channel != - sta_ctx->conn_info.channel) { - hdd_warn("channel(%d) is different from operating channel(%d)", - channel, - sta_ctx->conn_info. - channel); + if (freq) { + if (freq != sta_ctx->conn_info.chan_freq) { + hdd_warn("freq(%u) is different from operating freq(%u)", + freq, + sta_ctx->conn_info.chan_freq); ret = -EINVAL; goto exit; } @@ -988,17 +1641,15 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, adapter->vdev_id); } else { /* - * 0 is accepted as current home channel, + * 0 is accepted as current home frequency, * delayed transmission of action frame is ok. */ - chan.center_freq = - sme_chn_to_freq(sta_ctx->conn_info. - channel); + chan.center_freq = sta_ctx->conn_info.chan_freq; } } } if (chan.center_freq == 0) { - hdd_err("Invalid channel number: %d", channel); + hdd_nofl_err("Invalid freq : %d", freq); ret = -EINVAL; goto exit; } @@ -1064,20 +1715,20 @@ hdd_sendactionframe(struct hdd_adapter *adapter, const uint8_t *bssid, static int hdd_parse_sendactionframe_v1(struct hdd_adapter *adapter, const char *command) { - uint8_t channel = 0; + qdf_freq_t freq = 0; uint8_t dwell_time = 0; uint8_t payload_len = 0; uint8_t *payload = NULL; tSirMacAddr bssid; int ret; - ret = hdd_parse_send_action_frame_v1_data(command, bssid, &channel, + ret = hdd_parse_send_action_frame_v1_data(command, bssid, &freq, &dwell_time, &payload, &payload_len); if (ret) { - hdd_err("Failed to parse send action frame data"); + hdd_nofl_err("Failed to parse send action frame data"); } else { - ret = hdd_sendactionframe(adapter, bssid, channel, + ret = hdd_sendactionframe(adapter, bssid, freq, dwell_time, payload_len, payload); qdf_mem_free(payload); } @@ -1106,6 +1757,7 @@ hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter, tSirMacAddr bssid; int ret; int len_wo_payload = 0; + qdf_freq_t freq = 0; /* The params are located after "SENDACTIONFRAME " */ total_len -= 16; @@ -1139,8 +1791,13 @@ hdd_parse_sendactionframe_v2(struct hdd_adapter *adapter, return -EINVAL; } - ret = hdd_sendactionframe(adapter, bssid, params->channel, - params->dwell_time, params->len, params->data); + if (!hdd_check_and_fill_freq(params->channel, &freq)) { + hdd_err("Invalid channel: %d", params->channel); + return -EINVAL; + } + + ret = hdd_sendactionframe(adapter, bssid, freq, params->dwell_time, + params->len, params->data); return ret; } @@ -1196,8 +1853,9 @@ hdd_parse_sendactionframe(struct hdd_adapter *adapter, const char *command, /** * hdd_parse_channellist() - HDD Parse channel list + * @hdd_ctx: hdd context * @command: Pointer to input channel list - * @channel_list: Pointer to local output array to record + * @channel_freq_list: Pointer to local output array to record * channel list * @num_channels: Pointer to number of roam scan channels * @@ -1214,7 +1872,9 @@ hdd_parse_sendactionframe(struct hdd_adapter *adapter, const char *command, * Return: 0 for success non-zero for failure */ static int -hdd_parse_channellist(const uint8_t *command, uint8_t *channel_list, +hdd_parse_channellist(struct hdd_context *hdd_ctx, + const uint8_t *command, + uint32_t *channel_freq_list, uint8_t *num_channels) { const uint8_t *in_ptr = command; @@ -1291,10 +1951,11 @@ hdd_parse_channellist(const uint8_t *command, uint8_t *channel_list, (temp_int > WNI_CFG_CURRENT_CHANNEL_STAMAX)) { return -EINVAL; } - channel_list[j] = temp_int; + channel_freq_list[j] = + wlan_reg_chan_to_freq(hdd_ctx->pdev, temp_int); hdd_debug("Channel %d added to preferred channel list", - channel_list[j]); + channel_freq_list[j]); } return 0; @@ -1327,14 +1988,21 @@ static int hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter, const char *command) { - uint8_t channel_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t num_chan = 0; QDF_STATUS status; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); int ret; mac_handle_t mac_handle; - ret = hdd_parse_channellist(command, channel_list, &num_chan); + if (!hdd_ctx) { + hdd_err("invalid hdd ctx"); + ret = -EINVAL; + goto exit; + } + + ret = hdd_parse_channellist(hdd_ctx, command, channel_freq_list, + &num_chan); if (ret) { hdd_err("Failed to parse channel list information"); goto exit; @@ -1352,7 +2020,8 @@ hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter, } mac_handle = hdd_ctx->mac_handle; - if (!sme_validate_channel_list(mac_handle, channel_list, num_chan)) { + if (!sme_validate_channel_list(mac_handle, + channel_freq_list, num_chan)) { hdd_err("List contains invalid channel(s)"); ret = -EINVAL; goto exit; @@ -1360,7 +2029,8 @@ hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter, status = sme_change_roam_scan_channel_list(mac_handle, adapter->vdev_id, - channel_list, num_chan); + channel_freq_list, + num_chan); if (QDF_STATUS_SUCCESS != status) { hdd_err("Failed to update channel list information"); ret = -EINVAL; @@ -1393,7 +2063,7 @@ hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter, const char *command) { const uint8_t *value; - uint8_t channel_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t channel; uint8_t num_chan; int i; @@ -1433,11 +2103,13 @@ hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter, ret = -EINVAL; goto exit; } - channel_list[i] = channel; + channel_freq_list[i] = wlan_reg_chan_to_freq(hdd_ctx->pdev, + channel); } mac_handle = hdd_ctx->mac_handle; - if (!sme_validate_channel_list(mac_handle, channel_list, num_chan)) { + if (!sme_validate_channel_list(mac_handle, channel_freq_list, + num_chan)) { hdd_err("List contains invalid channel(s)"); ret = -EINVAL; goto exit; @@ -1445,7 +2117,7 @@ hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter, status = sme_change_roam_scan_channel_list(mac_handle, adapter->vdev_id, - channel_list, num_chan); + channel_freq_list, num_chan); if (QDF_STATUS_SUCCESS != status) { hdd_err("Failed to update channel list information"); ret = -EINVAL; @@ -1725,8 +2397,8 @@ static QDF_STATUS hdd_parse_plm_cmd(uint8_t *command, req->mac_addr.bytes[count] = content; } - hdd_debug("MAC addr " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(req->mac_addr.bytes)); + hdd_debug("MAC addr " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(req->mac_addr.bytes)); in_ptr = strpbrk(in_ptr, " "); @@ -1774,8 +2446,9 @@ static QDF_STATUS hdd_parse_plm_cmd(uint8_t *command, content > WNI_CFG_CURRENT_CHANNEL_STAMAX) return QDF_STATUS_E_FAILURE; - req->plm_ch_list[count] = content; - hdd_debug(" ch- %d", req->plm_ch_list[count]); + req->plm_ch_freq_list[count] = + cds_chan_to_freq(content); + hdd_debug(" ch-freq- %d", req->plm_ch_freq_list[count]); } } /* If PLM START */ @@ -1965,8 +2638,9 @@ static int hdd_set_app_type1_parser(struct hdd_adapter *adapter, params.pass_length = strlen(password); qdf_mem_copy(params.password, password, params.pass_length); - hdd_debug("%d %pM %.8s %u %.16s %u", - params.vdev_id, params.wakee_mac_addr.bytes, + hdd_debug("%d "QDF_MAC_ADDR_FMT" %.8s %u %.16s %u", + params.vdev_id, + QDF_MAC_ADDR_REF(params.wakee_mac_addr.bytes), params.identification_id, params.id_length, params.password, params.pass_length); @@ -2026,7 +2700,7 @@ static int hdd_set_app_type2_parser(struct hdd_adapter *adapter, return -EINVAL; } - if (6 != sscanf(mac_addr, QDF_MAC_ADDR_STR, + if (6 != sscanf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", &gateway_mac[0], &gateway_mac[1], &gateway_mac[2], &gateway_mac[3], &gateway_mac[4], &gateway_mac[5])) { hdd_err("Invalid MacAddress Input %s", mac_addr); @@ -2079,8 +2753,8 @@ static int hdd_set_app_type2_parser(struct hdd_adapter *adapter, params.tcp_rx_timeout_val = ucfg_pmo_extwow_app2_tcp_rx_timeout(hdd_ctx->psoc); - hdd_debug("%pM %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u", - gateway_mac, rc4_key, params.ip_id, + hdd_debug(QDF_MAC_ADDR_FMT" %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u", + QDF_MAC_ADDR_REF(gateway_mac), rc4_key, params.ip_id, params.ip_device_ip, params.ip_server_ip, params.tcp_seq, params.tcp_ack_seq, params.tcp_src_port, params.tcp_dst_port, params.keepalive_init, params.keepalive_min, @@ -2300,6 +2974,145 @@ static int hdd_conc_set_dwell_time(struct hdd_adapter *adapter, return retval; } +static int hdd_enable_unit_test_commands(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx) +{ + enum pld_bus_type bus_type = pld_get_bus_type(hdd_ctx->parent_dev); + u32 arg[2]; + QDF_STATUS status; + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE || + hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) + return -EPERM; + + if (adapter->vdev_id >= WLAN_MAX_VDEVS) { + hdd_err_rl("Invalid vdev id"); + return -EINVAL; + } + + if (bus_type == PLD_BUS_TYPE_PCIE) { + arg[0] = 360; + arg[1] = 3; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_TX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + + arg[0] = 361; + arg[1] = 1; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_TX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + + if (hdd_ctx->target_type == TARGET_TYPE_QCA6390) { + arg[0] = 37; + arg[1] = 3000; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_RX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + } + + if (hdd_ctx->target_type == TARGET_TYPE_QCA6490) { + arg[0] = 39; + arg[1] = 3000; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_RX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + } + } else if (bus_type == PLD_BUS_TYPE_SNOC) { + arg[0] = 7; + arg[1] = 1; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + 0x44, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + } else { + return -EINVAL; + } + return 0; +} + +static int hdd_disable_unit_test_commands(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx) +{ + enum pld_bus_type bus_type = pld_get_bus_type(hdd_ctx->parent_dev); + u32 arg[2]; + QDF_STATUS status; + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE || + hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) + return -EPERM; + + if (adapter->vdev_id >= WLAN_MAX_VDEVS) { + hdd_err_rl("Invalid vdev id"); + return -EINVAL; + } + + if (bus_type == PLD_BUS_TYPE_PCIE) { + arg[0] = 360; + arg[1] = 0; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_TX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + + arg[0] = 361; + arg[1] = 0; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_TX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + + arg[0] = 39; + arg[1] = 0; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + WLAN_MODULE_RX, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + + } else if (bus_type == PLD_BUS_TYPE_SNOC) { + arg[0] = 7; + arg[1] = 0; + + status = sme_send_unit_test_cmd(adapter->vdev_id, + 0x44, + 2, + arg); + if (status != QDF_STATUS_SUCCESS) + return qdf_status_to_os_return(status); + } else { + return -EINVAL; + } + return 0; +} + static void hdd_get_link_status_cb(uint8_t status, void *context) { struct osif_request *request; @@ -2362,174 +3175,44 @@ static int wlan_hdd_get_link_status(struct hdd_adapter *adapter) * value is 0 */ hdd_warn("Not associated!"); - return 0; - } - - request = osif_request_alloc(¶ms); - if (!request) { - hdd_err("Request allocation failure"); - return 0; - } - cookie = osif_request_cookie(request); - - status = sme_get_link_status(adapter->hdd_ctx->mac_handle, - hdd_get_link_status_cb, - cookie, adapter->vdev_id); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("Unable to retrieve link status"); - /* return a cached value */ - } else { - /* request is sent -- wait for the response */ - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_err("SME timed out while retrieving link status"); - /* return a cached value */ - } else { - /* update the adapter with the fresh results */ - priv = osif_request_priv(request); - adapter->link_status = priv->link_status; - } - } - - /* - * either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. - * regardless we are done with the request. - */ - osif_request_put(request); - - /* either callback updated adapter stats or it has cached data */ - return adapter->link_status; -} - -static void hdd_tx_fail_ind_callback(uint8_t *macaddr, uint8_t seq_no) -{ - int payload_len; - struct sk_buff *skb; - struct nlmsghdr *nlh; - uint8_t *data; - - payload_len = ETH_ALEN; - - if (0 == cesium_pid || !cesium_nl_srv_sock) { - hdd_err("cesium process not registered"); - return; - } - - skb = nlmsg_new(payload_len, GFP_ATOMIC); - if (!skb) { - hdd_err("nlmsg_new() failed for msg size[%d]", - NLMSG_SPACE(payload_len)); - return; - } - - nlh = nlmsg_put(skb, cesium_pid, seq_no, 0, payload_len, NLM_F_REQUEST); - - if (!nlh) { - hdd_err("nlmsg_put() failed for msg size[%d]", - NLMSG_SPACE(payload_len)); - - kfree_skb(skb); - return; - } - - data = nlmsg_data(nlh); - memcpy(data, macaddr, ETH_ALEN); - - if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0) { - hdd_err("nlmsg_unicast() failed for msg size[%d]", - NLMSG_SPACE(payload_len)); - } -} - - -/** - * hdd_parse_user_params() - return a pointer to the next argument - * @command: Input argument string - * @arg: Output pointer to the next argument - * - * This function parses argument stream and finds the pointer - * to the next argument - * - * Return: 0 if the next argument found; -EINVAL otherwise - */ -static int hdd_parse_user_params(uint8_t *command, uint8_t **arg) -{ - uint8_t *cursor; - - cursor = strnchr(command, strlen(command), SPACE_ASCII_VALUE); - - /* no argument remains ? */ - if (!cursor) - return -EINVAL; - - /* no space after the current arg ? */ - if (SPACE_ASCII_VALUE != *cursor) - return -EINVAL; - - cursor++; - - /* remove empty spaces */ - while (SPACE_ASCII_VALUE == *cursor) - cursor++; - - /* no argument after the spaces ? */ - if ('\0' == *cursor) - return -EINVAL; - - *arg = cursor; - - return 0; -} - -/** - * hdd_parse_ibsstx_fail_event_params - Parse params - * for SETIBSSTXFAILEVENT - * @command: Input ibss tx fail event argument - * @tx_fail_count: (Output parameter) Tx fail counter - * @pid: (Output parameter) PID - * - * Return: 0 if the parsing succeeds; -EINVAL otherwise - */ -static int hdd_parse_ibsstx_fail_event_params(uint8_t *command, - uint8_t *tx_fail_count, - uint16_t *pid) -{ - uint8_t *param = NULL; - int ret; - - ret = hdd_parse_user_params(command, ¶m); - - if (0 == ret && param) { - if (1 != sscanf(param, "%hhu", tx_fail_count)) { - ret = -EINVAL; - goto done; - } - } else { - goto done; - } - - if (0 == *tx_fail_count) { - *pid = 0; - goto done; + return 0; } - command = param; - command++; - - ret = hdd_parse_user_params(command, ¶m); + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return 0; + } + cookie = osif_request_cookie(request); - if (0 == ret) { - if (1 != sscanf(param, "%hu", pid)) { - ret = -EINVAL; - goto done; - } + status = sme_get_link_status(adapter->hdd_ctx->mac_handle, + hdd_get_link_status_cb, + cookie, adapter->vdev_id); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("Unable to retrieve link status"); + /* return a cached value */ } else { - goto done; + /* request is sent -- wait for the response */ + ret = osif_request_wait_for_response(request); + if (ret) { + hdd_err("SME timed out while retrieving link status"); + /* return a cached value */ + } else { + /* update the adapter with the fresh results */ + priv = osif_request_priv(request); + adapter->link_status = priv->link_status; + } } -done: - return ret; + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + osif_request_put(request); + + /* either callback updated adapter stats or it has cached data */ + return adapter->link_status; } #ifdef FEATURE_WLAN_ESE @@ -2552,7 +3235,8 @@ static int hdd_parse_ibsstx_fail_event_params(uint8_t *command, * * Return: 0 for success non-zero for failure */ -static int hdd_parse_ese_beacon_req(uint8_t *command, +static int hdd_parse_ese_beacon_req(struct wlan_objmgr_pdev *pdev, + uint8_t *command, tCsrEseBeaconReq *req) { uint8_t *in_ptr = command; @@ -2639,7 +3323,8 @@ static int hdd_parse_ese_beacon_req(uint8_t *command, temp_int); return -EINVAL; } - req->bcnReq[j].channel = temp_int; + req->bcnReq[j].ch_freq = + wlan_reg_chan_to_freq(pdev, temp_int); break; case 2: /* Scan mode */ @@ -2670,10 +3355,10 @@ static int hdd_parse_ese_beacon_req(uint8_t *command, } for (j = 0; j < req->numBcnReqIe; j++) { - hdd_debug("Index: %d Measurement Token: %u Channel: %u Scan Mode: %u Measurement Duration: %u", + hdd_debug("Index: %d Measurement Token: %u ch_freq: %u Scan Mode: %u Measurement Duration: %u", j, req->bcnReq[j].measurementToken, - req->bcnReq[j].channel, + req->bcnReq[j].ch_freq, req->bcnReq[j].scanMode, req->bcnReq[j].measurementDuration); } @@ -2787,8 +3472,9 @@ int wlan_hdd_set_mc_rate(struct hdd_adapter *adapter, int target_rate) rate_update.mcastDataRate5GHz = target_rate; rate_update.bcastDataRate = -1; qdf_copy_macaddr(&rate_update.bssid, &adapter->mac_addr); - hdd_debug("MC Target rate %d, mac = %pM, dev_mode %s(%d)", - rate_update.mcastDataRate24GHz, rate_update.bssid.bytes, + hdd_debug("MC Target rate %d, mac = "QDF_MAC_ADDR_FMT", dev_mode %s(%d)", + rate_update.mcastDataRate24GHz, + QDF_MAC_ADDR_REF(rate_update.bssid.bytes), qdf_opmode_str(adapter->device_mode), adapter->device_mode); status = sme_send_rate_update_ind(hdd_ctx->mac_handle, &rate_update); if (QDF_STATUS_SUCCESS != status) { @@ -2877,6 +3563,7 @@ static int drv_cmd_set_band(struct hdd_adapter *adapter, { int err; uint8_t band; + uint32_t band_bitmap; /* * Parse the band value passed from userspace. The first 8 bytes @@ -2888,7 +3575,9 @@ static int drv_cmd_set_band(struct hdd_adapter *adapter, return err; } - return hdd_reg_set_band(adapter->dev, band); + band_bitmap = hdd_reg_legacy_setband_to_reg_wifi_band_bitmap(band); + + return hdd_reg_set_band(adapter->dev, band_bitmap); } static int drv_cmd_set_wmmps(struct hdd_adapter *adapter, @@ -3559,7 +4248,7 @@ void hdd_get_roam_scan_ch_cb(hdd_handle_t hdd_handle, } static uint32_t -hdd_get_roam_chan_from_fw(struct hdd_adapter *adapter, uint8_t *chan_list, +hdd_get_roam_chan_from_fw(struct hdd_adapter *adapter, uint32_t *chan_list, uint8_t *num_channels) { QDF_STATUS status = QDF_STATUS_E_INVAL; @@ -3606,25 +4295,44 @@ hdd_get_roam_chan_from_fw(struct hdd_adapter *adapter, uint8_t *chan_list, priv = osif_request_priv(request); *num_channels = priv->roam_ch.num_channels; for (i = 0; i < *num_channels; i++) - chan_list[i] = wlan_reg_freq_to_chan( - hdd_ctx->pdev, priv->roam_ch.chan_list[i]); + chan_list[i] = priv->roam_ch.chan_list[i]; cleanup: osif_request_put(request); return ret; } -#else -static bool is_roam_ch_from_fw_supported(struct hdd_context *hdd_ctx) -{ - return false; -} -static uint32_t -hdd_get_roam_chan_from_fw(struct hdd_adapter *adapter, uint8_t *chan_list, - uint8_t *num_channels) +int +hdd_get_roam_scan_freq(struct hdd_adapter *adapter, mac_handle_t mac_handle, + uint32_t *chan_list, uint8_t *num_channels) { - return QDF_STATUS_E_INVAL; + int ret = 0; + + if (!adapter || !mac_handle || !chan_list || !num_channels) { + hdd_err("failed to get roam scan channel, invalid input"); + return -EFAULT; + } + + if (is_roam_ch_from_fw_supported(adapter->hdd_ctx)) { + ret = hdd_get_roam_chan_from_fw(adapter, chan_list, + num_channels); + if (ret != QDF_STATUS_SUCCESS) { + hdd_err("failed to get roam scan channel list from FW"); + return -EFAULT; + } + + return ret; + } + + if (sme_get_roam_scan_channel_list(mac_handle, chan_list, + num_channels, adapter->vdev_id) != + QDF_STATUS_SUCCESS) { + hdd_err("failed to get roam scan channel list"); + return -EFAULT; + } + + return ret; } #endif @@ -3635,35 +4343,18 @@ static int drv_cmd_get_roam_scan_channels(struct hdd_adapter *adapter, struct hdd_priv_data *priv_data) { int ret = 0; - uint8_t channel_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t num_channels = 0; uint8_t j = 0; char extra[128] = { 0 }; int len; + uint8_t chan; - if (is_roam_ch_from_fw_supported(hdd_ctx)) { - ret = hdd_get_roam_chan_from_fw(adapter, channel_list, - &num_channels); - if (ret == QDF_STATUS_SUCCESS) { - goto fill_ch_resp; - } else { - hdd_err("failed to get roam scan channel list from FW"); - ret = -EFAULT; - goto exit; - } - } - - if (QDF_STATUS_SUCCESS != - sme_get_roam_scan_channel_list(hdd_ctx->mac_handle, - channel_list, - &num_channels, - adapter->vdev_id)) { - hdd_err("failed to get roam scan channel list"); - ret = -EFAULT; + ret = hdd_get_roam_scan_freq(adapter, hdd_ctx->mac_handle, freq_list, + &num_channels); + if (ret != QDF_STATUS_SUCCESS) goto exit; - } -fill_ch_resp: qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL, adapter->vdev_id, num_channels); @@ -3675,10 +4366,11 @@ static int drv_cmd_get_roam_scan_channels(struct hdd_adapter *adapter, */ len = scnprintf(extra, sizeof(extra), "%s %d", command, num_channels); - for (j = 0; (j < num_channels) && len <= sizeof(extra); j++) + for (j = 0; (j < num_channels) && len <= sizeof(extra); j++) { + chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, freq_list[j]); len += scnprintf(extra + len, sizeof(extra) - len, - " %d", channel_list[j]); - + " %d", chan); + } len = QDF_MIN(priv_data->total_len, len + 1); if (copy_to_user(priv_data->buf, &extra, len)) { hdd_err("failed to copy data to user buffer"); @@ -4531,7 +5223,7 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter, { int ret = 0; uint8_t *value = command; - uint8_t channel = 0; + qdf_freq_t freq = 0; tSirMacAddr bssid; uint32_t roam_id = INVALID_ROAM_ID; tCsrRoamModifyProfileFields mod_fields; @@ -4547,6 +5239,7 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter, } sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); /* if not associated, no need to proceed with reassoc */ if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) { @@ -4556,14 +5249,13 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter, } ret = hdd_parse_reassoc_command_v1_data(value, bssid, - &channel); + &freq); if (ret) { hdd_err("Failed to parse reassoc command data"); goto exit; } mac_handle = hdd_ctx->mac_handle; - /* * if the target bssid is same as currently associated AP, * issue reassoc to same AP @@ -4572,9 +5264,8 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter, QDF_MAC_ADDR_SIZE)) { hdd_warn("Reassoc BSSID is same as currently associated AP bssid"); if (roaming_offload_enabled(hdd_ctx)) { - channel = sta_ctx->conn_info.channel; - hdd_wma_send_fastreassoc_cmd(adapter, bssid, - channel); + hdd_wma_send_fastreassoc_cmd( + adapter, bssid, sta_ctx->conn_info.chan_freq); } else { sme_get_modify_profile_fields(mac_handle, adapter->vdev_id, @@ -4585,19 +5276,19 @@ static int drv_cmd_fast_reassoc(struct hdd_adapter *adapter, return 0; } - /* Check channel number is a valid channel number */ - if (channel && (QDF_STATUS_SUCCESS != - wlan_hdd_validate_operation_channel(adapter, channel))) { - hdd_err("Invalid Channel [%d]", channel); + /* Check freq number is a valid freq number */ + if (freq && QDF_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(adapter, freq)) { + hdd_err("Invalid freq [%d]", freq); return -EINVAL; } if (roaming_offload_enabled(hdd_ctx)) { - hdd_wma_send_fastreassoc_cmd(adapter, bssid, (int)channel); + hdd_wma_send_fastreassoc_cmd(adapter, bssid, freq); goto exit; } /* Proceed with reassoc */ - req.channel = channel; + req.ch_freq = freq; req.src = FASTREASSOC; qdf_mem_copy(req.bssid.bytes, bssid, sizeof(tSirMacAddr)); sme_handoff_request(mac_handle, adapter->vdev_id, &req); @@ -4868,184 +5559,43 @@ static int drv_cmd_miracast(struct hdd_adapter *adapter, /* Filtertype value should be either 0-Disabled, 1-Source, 2-sink */ hdd_ctx->miracast_value = filter_type; - ret_status = sme_set_miracast(hdd_ctx->mac_handle, filter_type); - if (QDF_STATUS_SUCCESS != ret_status) { - hdd_err("Failed to set miracast"); - return -EBUSY; - } - ret_status = ucfg_scan_set_miracast(hdd_ctx->psoc, - filter_type ? true : false); - if (QDF_IS_STATUS_ERROR(ret_status)) { - hdd_err("Failed to set miracastn scan"); - return -EBUSY; - } - - if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) - return wlan_hdd_set_mas(adapter, filter_type); - -exit: - return ret; -} - -/* Function header is left blank intentionally */ -static int hdd_parse_set_ibss_oui_data_command(uint8_t *command, uint8_t *ie, - int32_t *oui_length, int32_t limit) -{ - uint8_t len; - uint8_t data; - - while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) { - command++; - limit--; - } - - len = 2; - - while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && - (limit > 1)) { - sscanf(command, "%02x", (unsigned int *)&data); - ie[len++] = data; - command += 2; - limit -= 2; - } - - *oui_length = len - 2; - - while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) { - command++; - limit--; - } - - while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && - (limit > 1)) { - sscanf(command, "%02x", (unsigned int *)&data); - ie[len++] = data; - command += 2; - limit -= 2; - } - - ie[0] = WLAN_ELEMID_VENDOR; - ie[1] = len - 2; - - return len; -} - -/** - * drv_cmd_set_ibss_beacon_oui_data() - set ibss oui data command - * @adapter: Pointer to adapter - * @hdd_ctx: Pointer to HDD context - * @command: Pointer to command string - * @command_len : Command length - * @priv_data : Pointer to priv data - * - * Return: - * int status code - */ -static int drv_cmd_set_ibss_beacon_oui_data(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) -{ - int i = 0; - int status; - int ret = 0; - uint8_t *ibss_ie; - int32_t oui_length = 0; - uint32_t ibss_ie_length; - uint8_t *value = command; - tSirModifyIE modify_ie; - struct csr_roam_profile *roam_profile; - mac_handle_t mac_handle; - - if (QDF_IBSS_MODE != adapter->device_mode) { - hdd_debug("Device_mode %s(%d) not IBSS", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - return ret; - } - - hdd_debug("received command %s", ((char *)value)); - - /* validate argument of command */ - if (strlen(value) <= command_len) { - hdd_err("No arguments in command length %zu", - strlen(value)); - ret = -EFAULT; - goto exit; - } - - /* moving to arguments of commands */ - value = value + command_len; - command_len = strlen(value); - - /* oui_data can't be less than 3 bytes */ - if (command_len < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) { - hdd_err("Invalid SETIBSSBEACONOUIDATA command length %d", - command_len); - ret = -EFAULT; - goto exit; - } - - ibss_ie = qdf_mem_malloc(command_len); - if (!ibss_ie) { - hdd_err("Could not allocate memory for command length %d", - command_len); - ret = -ENOMEM; - goto exit; - } - - ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie, - &oui_length, - command_len); - if (ibss_ie_length <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) { - hdd_err("Could not parse command %s return length %d", - value, ibss_ie_length); - ret = -EFAULT; - qdf_mem_free(ibss_ie); - goto exit; - } - - roam_profile = hdd_roam_profile(adapter); - - qdf_copy_macaddr(&modify_ie.bssid, - roam_profile->BSSIDs.bssid); - - modify_ie.smeSessionId = adapter->vdev_id; - modify_ie.notify = true; - modify_ie.ieID = WLAN_ELEMID_VENDOR; - modify_ie.ieIDLen = ibss_ie_length; - modify_ie.ieBufferlength = ibss_ie_length; - modify_ie.pIEBuffer = ibss_ie; - modify_ie.oui_length = oui_length; - - hdd_warn("ibss_ie length %d oui_length %d ibss_ie:", - ibss_ie_length, oui_length); - while (i < modify_ie.ieBufferlength) - hdd_warn("0x%x", ibss_ie[i++]); - - /* Probe Bcn modification */ - mac_handle = hdd_ctx->mac_handle; - sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_BCN); - - /* Populating probe resp frame */ - sme_modify_add_ie(mac_handle, &modify_ie, eUPDATE_IE_PROBE_RESP); - - qdf_mem_free(ibss_ie); - - status = sme_send_cesium_enable_ind(mac_handle, - adapter->vdev_id); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("Could not send cesium enable indication %d", - status); - ret = -EINVAL; - goto exit; + ret_status = sme_set_miracast(hdd_ctx->mac_handle, filter_type); + if (QDF_STATUS_SUCCESS != ret_status) { + hdd_err("Failed to set miracast"); + return -EBUSY; + } + ret_status = ucfg_scan_set_miracast(hdd_ctx->psoc, + filter_type ? true : false); + if (QDF_IS_STATUS_ERROR(ret_status)) { + hdd_err("Failed to set miracastn scan"); + return -EBUSY; } + if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) + return wlan_hdd_set_mas(adapter, filter_type); + exit: return ret; } +static int drv_cmd_tput_debug_mode_enable(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + u8 *command, + u8 command_len, + struct hdd_priv_data *priv_data) +{ + return hdd_enable_unit_test_commands(adapter, hdd_ctx); +} + +static int drv_cmd_tput_debug_mode_disable(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + u8 *command, + u8 command_len, + struct hdd_priv_data *priv_data) +{ + return hdd_disable_unit_test_commands(adapter, hdd_ctx); +} + #ifdef FEATURE_WLAN_RMC /* Function header is left blank intentionally */ static int hdd_parse_setrmcenable_command(uint8_t *command, @@ -5151,473 +5701,207 @@ static int hdd_parse_setrmcrate_command(uint8_t *command, if ('\0' == *in_ptr) return 0; - v = sscanf(in_ptr, "%31s ", buf); - if (1 != v) - return -EINVAL; - - v = kstrtos32(buf, 10, &temp_int); - if (v < 0) - return -EINVAL; - - switch (temp_int) { - default: - hdd_warn("Unsupported rate: %d", temp_int); - return -EINVAL; - case 0: - case 6: - case 9: - case 12: - case 18: - case 24: - case 36: - case 48: - case 54: - *tx_flags = TX_RATE_LEGACY; - *rate = temp_int * 10; - break; - case 65: - *tx_flags = TX_RATE_HT20; - *rate = temp_int * 10; - break; - case 72: - *tx_flags = TX_RATE_HT20 | TX_RATE_SGI; - *rate = 722; - break; - } - - hdd_debug("Rate: %d", *rate); - - return 0; -} - -static int drv_cmd_set_rmc_enable(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) -{ - int ret = 0; - uint8_t *value = command; - uint8_t rmc_enable = 0; - int status; - mac_handle_t mac_handle; - - if ((QDF_IBSS_MODE != adapter->device_mode) && - (QDF_SAP_MODE != adapter->device_mode)) { - hdd_err("Received SETRMCENABLE cmd in invalid mode %s(%d)", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - hdd_err("SETRMCENABLE cmd is allowed only in IBSS/SOFTAP mode"); - ret = -EINVAL; - goto exit; - } - - status = hdd_parse_setrmcenable_command(value, &rmc_enable); - if (status) { - hdd_err("Invalid SETRMCENABLE command"); - ret = -EINVAL; - goto exit; - } - - hdd_debug("rmc_enable %d", rmc_enable); - mac_handle = hdd_ctx->mac_handle; - - if (true == rmc_enable) { - status = sme_enable_rmc(mac_handle, adapter->vdev_id); - } else if (false == rmc_enable) { - status = sme_disable_rmc(mac_handle, adapter->vdev_id); - } else { - hdd_err("Invalid SETRMCENABLE command %d", rmc_enable); - ret = -EINVAL; - goto exit; - } - - if (QDF_STATUS_SUCCESS != status) { - hdd_err("SETRMC %d failed status %d", rmc_enable, status); - ret = -EINVAL; - goto exit; - } - -exit: - return ret; -} - -static int drv_cmd_set_rmc_action_period(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) -{ - int ret = 0; - uint8_t *value = command; - uint32_t action_period = 0; - int status; - mac_handle_t mac_handle; - - if ((QDF_IBSS_MODE != adapter->device_mode) && - (QDF_SAP_MODE != adapter->device_mode)) { - hdd_err("Received SETRMC cmd in invalid mode %s(%d)", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - hdd_err("SETRMC cmd is allowed only in IBSS/SOFTAP mode"); - ret = -EINVAL; - goto exit; - } - - status = hdd_parse_setrmcactionperiod_command(value, &action_period); - if (status) { - hdd_err("Invalid SETRMCACTIONPERIOD command"); - ret = -EINVAL; - goto exit; - } - - hdd_debug("action_period %d", action_period); - mac_handle = hdd_ctx->mac_handle; - - if (ucfg_mlme_set_rmc_action_period_freq(hdd_ctx->psoc, - action_period) != - QDF_STATUS_SUCCESS) { - hdd_err("Could not set SETRMCACTIONPERIOD %d", action_period); - ret = -EINVAL; - goto exit; - } - - status = sme_send_rmc_action_period(mac_handle, - adapter->vdev_id); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("Could not send cesium enable indication %d", - status); - ret = -EINVAL; - goto exit; - } - -exit: - return ret; -} - -static int drv_cmd_set_rmc_tx_rate(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) -{ - int ret = 0; - uint8_t *value = command; - uint32_t rate = 0; - enum tx_rate_info tx_flags = 0; - tSirRateUpdateInd params = {0}; - int status; - bool bval = false; - - if ((QDF_IBSS_MODE != adapter->device_mode) && - (QDF_SAP_MODE != adapter->device_mode)) { - hdd_err("Received SETRMCTXRATE cmd in invalid mode %s(%d)", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - hdd_err("SETRMCTXRATE cmd is allowed only in IBSS/SOFTAP mode"); - ret = -EINVAL; - goto exit; - } - - status = hdd_parse_setrmcrate_command(value, &rate, &tx_flags); - if (status) { - hdd_err("Invalid SETRMCTXRATE command"); - ret = -EINVAL; - goto exit; - } - hdd_debug("rate %d", rate); - - /* - * Fill the user specifieed RMC rate param - * and the derived tx flags. - */ - status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("unable to get vht_enable2x2"); - ret = -EINVAL; - goto exit; - } - params.nss = (bval == 0) ? 0 : 1; - params.reliableMcastDataRate = rate; - params.reliableMcastDataRateTxFlag = tx_flags; - params.dev_mode = adapter->device_mode; - params.bcastDataRate = -1; - memcpy(params.bssid.bytes, - adapter->mac_addr.bytes, - sizeof(params.bssid)); - status = sme_send_rate_update_ind(hdd_ctx->mac_handle, - ¶ms); - -exit: - return ret; -} -#endif /* FEATURE_WLAN_RMC */ - -static int drv_cmd_get_ibss_peer_info_all(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) -{ - int ret = 0; - int status = QDF_STATUS_SUCCESS; - struct hdd_station_ctx *sta_ctx = NULL; - char *extra = NULL; - int idx = 0; - int length = 0; - uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; - uint32_t print_break_index = 0; - - if (QDF_IBSS_MODE != adapter->device_mode) { - hdd_warn("Unsupported in mode %s(%d)", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - return -EINVAL; - } - - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - hdd_debug("Received GETIBSSPEERINFOALL Command"); - - /* Handle the command */ - status = hdd_cfg80211_get_ibss_peer_info_all(adapter); - if (QDF_STATUS_SUCCESS == status) { - size_t user_size = qdf_min(WLAN_MAX_BUF_SIZE, - priv_data->total_len); - - /* - * The variable extra needed to be allocated on the heap since - * amount of memory required to copy the data for 32 devices - * exceeds the size of 1024 bytes of default stack size. On - * 64 bit devices, the default max stack size of 2048 bytes - */ - extra = qdf_mem_malloc(user_size); + v = sscanf(in_ptr, "%31s ", buf); + if (1 != v) + return -EINVAL; - if (!extra) { - hdd_err("memory allocation failed"); - ret = -ENOMEM; - goto exit; - } + v = kstrtos32(buf, 10, &temp_int); + if (v < 0) + return -EINVAL; - /* Copy number of stations */ - length = scnprintf(extra, user_size, "%d ", - sta_ctx->ibss_peer_info.numPeers); - print_break_index = length; - for (idx = 0; idx < sta_ctx->ibss_peer_info.numPeers; - idx++) { - int8_t rssi; - uint32_t tx_rate; + switch (temp_int) { + default: + hdd_warn("Unsupported rate: %d", temp_int); + return -EINVAL; + case 0: + case 6: + case 9: + case 12: + case 18: + case 24: + case 36: + case 48: + case 54: + *tx_flags = TX_RATE_LEGACY; + *rate = temp_int * 10; + break; + case 65: + *tx_flags = TX_RATE_HT20; + *rate = temp_int * 10; + break; + case 72: + *tx_flags = TX_RATE_HT20 | TX_RATE_SGI; + *rate = 722; + break; + } - qdf_mem_copy(mac_addr, - sta_ctx->ibss_peer_info.peerInfoParams[idx]. - mac_addr, sizeof(mac_addr)); + hdd_debug("Rate: %d", *rate); - tx_rate = - sta_ctx->ibss_peer_info.peerInfoParams[idx]. - txRate; - /* - * Only lower 3 bytes are rate info. Mask of the MSByte - */ - tx_rate &= 0x00FFFFFF; + return 0; +} - rssi = sta_ctx->ibss_peer_info.peerInfoParams[idx]. - rssi; +static int drv_cmd_set_rmc_enable(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + int ret = 0; + uint8_t *value = command; + uint8_t rmc_enable = 0; + int status; + mac_handle_t mac_handle; - length += scnprintf(extra + length, - user_size - length, - QDF_MAC_ADDR_STR" %d %d ", - QDF_MAC_ADDR_ARRAY(mac_addr), - tx_rate, rssi); - /* - * cdf_trace_msg has limitation of 512 bytes for the - * print buffer. Hence printing the data in two chunks. - * The first chunk will have the data for 16 devices - * and the second chunk will have the rest. - */ - if (idx < NUM_OF_STA_DATA_TO_PRINT) - print_break_index = length; - } + if ((QDF_IBSS_MODE != adapter->device_mode) && + (QDF_SAP_MODE != adapter->device_mode)) { + hdd_err("Received SETRMCENABLE cmd in invalid mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + hdd_err("SETRMCENABLE cmd is allowed only in IBSS/SOFTAP mode"); + ret = -EINVAL; + goto exit; + } - /* - * Copy the data back into buffer, if the data to copy is - * more than 512 bytes than we will split the data and do - * it in two shots - */ - if (copy_to_user(priv_data->buf, extra, print_break_index)) { - hdd_err("Copy into user data buffer failed"); - ret = -EFAULT; - goto mem_free; - } + status = hdd_parse_setrmcenable_command(value, &rmc_enable); + if (status) { + hdd_err("Invalid SETRMCENABLE command"); + ret = -EINVAL; + goto exit; + } - /* This overwrites the last space, which we already copied */ - extra[print_break_index - 1] = '\0'; - hdd_debug("%s", extra); + hdd_debug("rmc_enable %d", rmc_enable); + mac_handle = hdd_ctx->mac_handle; - if (length > print_break_index) { - if (copy_to_user - (priv_data->buf + print_break_index, - extra + print_break_index, - length - print_break_index + 1)) { - hdd_err("Copy into user data buffer failed"); - ret = -EFAULT; - goto mem_free; - } - hdd_debug("%s", &extra[print_break_index]); - } + if (true == rmc_enable) { + status = sme_enable_rmc(mac_handle, adapter->vdev_id); + } else if (false == rmc_enable) { + status = sme_disable_rmc(mac_handle, adapter->vdev_id); } else { - /* Command failed, log error */ - hdd_err("GETIBSSPEERINFOALL command failed with status code %d", - status); + hdd_err("Invalid SETRMCENABLE command %d", rmc_enable); + ret = -EINVAL; + goto exit; + } + + if (QDF_STATUS_SUCCESS != status) { + hdd_err("SETRMC %d failed status %d", rmc_enable, status); ret = -EINVAL; goto exit; } - ret = 0; -mem_free: - qdf_mem_free(extra); exit: return ret; } -/* Peer Info command */ -static int drv_cmd_get_ibss_peer_info(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) +static int drv_cmd_set_rmc_action_period(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) { int ret = 0; uint8_t *value = command; - QDF_STATUS status; - struct hdd_station_ctx *sta_ctx = NULL; - char extra[128] = { 0 }; - uint32_t length = 0; - uint8_t sta_id = 0; - struct qdf_mac_addr peer_macaddr; - - if (QDF_IBSS_MODE != adapter->device_mode) { - hdd_warn("Unsupported in mode %s(%d)", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode); - return -EINVAL; - } - - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - - hdd_debug("Received GETIBSSPEERINFO Command"); + uint32_t action_period = 0; + int status; + mac_handle_t mac_handle; - /* if there are no peers, no need to continue with the command */ - if (eConnectionState_IbssConnected != - sta_ctx->conn_info.conn_state) { - hdd_err("No IBSS Peers coalesced"); + if ((QDF_IBSS_MODE != adapter->device_mode) && + (QDF_SAP_MODE != adapter->device_mode)) { + hdd_err("Received SETRMC cmd in invalid mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + hdd_err("SETRMC cmd is allowed only in IBSS/SOFTAP mode"); ret = -EINVAL; goto exit; } - /* Parse the incoming command buffer */ - status = hdd_parse_get_ibss_peer_info(value, &peer_macaddr); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("Invalid GETIBSSPEERINFO command"); + status = hdd_parse_setrmcactionperiod_command(value, &action_period); + if (status) { + hdd_err("Invalid SETRMCACTIONPERIOD command"); ret = -EINVAL; goto exit; } - /* Get station index for the peer mac address and sanitize it */ - hdd_get_peer_sta_id(sta_ctx, &peer_macaddr, &sta_id); + hdd_debug("action_period %d", action_period); + mac_handle = hdd_ctx->mac_handle; - if (sta_id > MAX_PEERS) { - hdd_err("Invalid StaIdx %d returned", sta_id); + if (ucfg_mlme_set_rmc_action_period_freq(hdd_ctx->psoc, + action_period) != + QDF_STATUS_SUCCESS) { + hdd_err("Could not set SETRMCACTIONPERIOD %d", action_period); ret = -EINVAL; goto exit; } - /* Handle the command */ - status = hdd_cfg80211_get_ibss_peer_info(adapter, sta_id); - if (QDF_STATUS_SUCCESS == status) { - uint32_t tx_rate = - sta_ctx->ibss_peer_info.peerInfoParams[0].txRate; - /* Only lower 3 bytes are rate info. Mask of the MSByte */ - tx_rate &= 0x00FFFFFF; - - length = scnprintf(extra, sizeof(extra), "%d %d", - (int)tx_rate, - (int)sta_ctx->ibss_peer_info. - peerInfoParams[0].rssi); - length = QDF_MIN(priv_data->total_len, length + 1); - - /* Copy the data back into buffer */ - if (copy_to_user(priv_data->buf, &extra, length)) { - hdd_err("copy data to user buffer failed GETIBSSPEERINFO command"); - ret = -EFAULT; - goto exit; - } - } else { - /* Command failed, log error */ - hdd_err("GETIBSSPEERINFO command failed with status code %d", + status = sme_send_rmc_action_period(mac_handle, + adapter->vdev_id); + if (QDF_STATUS_SUCCESS != status) { + hdd_err("Could not send cesium enable indication %d", status); ret = -EINVAL; goto exit; } - /* Success ! */ - hdd_debug("%s", extra); - ret = 0; - exit: return ret; } -static int drv_cmd_set_ibss_tx_fail_event(struct hdd_adapter *adapter, - struct hdd_context *hdd_ctx, - uint8_t *command, - uint8_t command_len, - struct hdd_priv_data *priv_data) +static int drv_cmd_set_rmc_tx_rate(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) { int ret = 0; - char *value; - uint8_t tx_fail_count = 0; - uint16_t pid = 0; - mac_handle_t mac_handle; - - value = command; - - ret = hdd_parse_ibsstx_fail_event_params(value, &tx_fail_count, &pid); + uint8_t *value = command; + uint32_t rate = 0; + enum tx_rate_info tx_flags = 0; + tSirRateUpdateInd params = {0}; + int status; + bool bval = false; - if (0 != ret) { - hdd_err("Failed to parse SETIBSSTXFAILEVENT arguments"); + if ((QDF_IBSS_MODE != adapter->device_mode) && + (QDF_SAP_MODE != adapter->device_mode)) { + hdd_err("Received SETRMCTXRATE cmd in invalid mode %s(%d)", + qdf_opmode_str(adapter->device_mode), + adapter->device_mode); + hdd_err("SETRMCTXRATE cmd is allowed only in IBSS/SOFTAP mode"); + ret = -EINVAL; goto exit; } - hdd_debug("tx_fail_cnt=%hhu, pid=%hu", tx_fail_count, pid); - mac_handle = hdd_ctx->mac_handle; + status = hdd_parse_setrmcrate_command(value, &rate, &tx_flags); + if (status) { + hdd_err("Invalid SETRMCTXRATE command"); + ret = -EINVAL; + goto exit; + } + hdd_debug("rate %d", rate); - if (0 == tx_fail_count) { - /* Disable TX Fail Indication */ - if (QDF_STATUS_SUCCESS == - sme_tx_fail_monitor_start_stop_ind(mac_handle, - tx_fail_count, - NULL)) { - cesium_pid = 0; - } else { - hdd_err("failed to disable TX Fail Event"); - ret = -EINVAL; - } - } else { - if (QDF_STATUS_SUCCESS == - sme_tx_fail_monitor_start_stop_ind(mac_handle, - tx_fail_count, - (void *)hdd_tx_fail_ind_callback)) { - cesium_pid = pid; - hdd_debug("Registered Cesium pid %u", - cesium_pid); - } else { - hdd_err("Failed to enable TX Fail Monitoring"); - ret = -EINVAL; - } + /* + * Fill the user specifieed RMC rate param + * and the derived tx flags. + */ + status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("unable to get vht_enable2x2"); + ret = -EINVAL; + goto exit; } + params.nss = (bval == 0) ? 0 : 1; + params.reliableMcastDataRate = rate; + params.reliableMcastDataRateTxFlag = tx_flags; + params.dev_mode = adapter->device_mode; + params.bcastDataRate = -1; + memcpy(params.bssid.bytes, + adapter->mac_addr.bytes, + sizeof(params.bssid)); + status = sme_send_rate_update_ind(hdd_ctx->mac_handle, + ¶ms); exit: return ret; } +#endif /* FEATURE_WLAN_RMC */ #ifdef FEATURE_WLAN_ESE static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter, @@ -5628,12 +5912,19 @@ static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter, { int ret = 0; uint8_t *value = command; - uint8_t channel_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t num_channels = 0; QDF_STATUS status; mac_handle_t mac_handle; - ret = hdd_parse_channellist(value, channel_list, &num_channels); + if (!hdd_ctx) { + hdd_err("invalid hdd ctx"); + ret = -EINVAL; + goto exit; + } + + ret = hdd_parse_channellist(hdd_ctx, value, channel_freq_list, + &num_channels); if (ret) { hdd_err("Failed to parse channel list information"); goto exit; @@ -5647,7 +5938,7 @@ static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter, } mac_handle = hdd_ctx->mac_handle; - if (!sme_validate_channel_list(mac_handle, channel_list, + if (!sme_validate_channel_list(mac_handle, channel_freq_list, num_channels)) { hdd_err("List contains invalid channel(s)"); ret = -EINVAL; @@ -5656,7 +5947,7 @@ static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter, status = sme_set_ese_roam_scan_channel_list(mac_handle, adapter->vdev_id, - channel_list, + channel_freq_list, num_channels); if (QDF_STATUS_SUCCESS != status) { hdd_err("Failed to update channel list information"); @@ -5828,7 +6119,7 @@ static int drv_cmd_ccx_beacon_req(struct hdd_adapter *adapter, return -EINVAL; } - ret = hdd_parse_ese_beacon_req(value, &req); + ret = hdd_parse_ese_beacon_req(hdd_ctx->pdev, value, &req); if (ret) { hdd_err("Failed to parse ese beacon req"); goto exit; @@ -6002,6 +6293,8 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter, uint8_t *value = command; struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT; struct qdf_mac_addr selfmac = QDF_MAC_ADDR_BCAST_INIT; + struct hdd_adapter *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER; ret = hdd_parse_setmaxtxpower_command(value, &tx_power); if (ret) { @@ -6009,7 +6302,8 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter, return ret; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { /* Assign correct self MAC address */ qdf_copy_macaddr(&bssid, &adapter->mac_addr); @@ -6017,19 +6311,24 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter, &adapter->mac_addr); hdd_debug("Device mode %d max tx power %d selfMac: " - QDF_MAC_ADDR_STR " bssId: " QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT " bssId: " QDF_MAC_ADDR_FMT, adapter->device_mode, tx_power, - QDF_MAC_ADDR_ARRAY(selfmac.bytes), - QDF_MAC_ADDR_ARRAY(bssid.bytes)); + QDF_MAC_ADDR_REF(selfmac.bytes), + QDF_MAC_ADDR_REF(bssid.bytes)); status = sme_set_max_tx_power(hdd_ctx->mac_handle, bssid, selfmac, tx_power); if (QDF_STATUS_SUCCESS != status) { hdd_err("Set max tx power failed"); ret = -EINVAL; + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); goto exit; } hdd_debug("Set max tx power success"); + hdd_adapter_dev_put_debug(adapter, dbgid); } exit: @@ -6473,9 +6772,9 @@ static int hdd_set_rx_filter(struct hdd_adapter *adapter, bool action, sizeof(adapter->mc_addr_list.addr[i])); hdd_debug("%s RX filter : addr =" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, action ? "setting" : "clearing", - QDF_MAC_ADDR_ARRAY(filter->multicastAddr[j].bytes)); + QDF_MAC_ADDR_REF(filter->multicastAddr[j].bytes)); j++; } if (j == SIR_MAX_NUM_MULTICAST_ADDRESS) @@ -6767,79 +7066,6 @@ wlan_hdd_soc_set_antenna_mode_cb(enum set_antenna_mode_status status, osif_request_put(request); } -static QDF_STATUS -hdd_populate_vdev_chains(struct wlan_mlme_nss_chains *nss_chains_cfg, - uint8_t tx_chains, - uint8_t rx_chains, - enum nss_chains_band_info band, - struct wlan_objmgr_vdev *vdev) -{ - struct wlan_mlme_nss_chains *dynamic_cfg; - - nss_chains_cfg->num_rx_chains[band] = rx_chains; - nss_chains_cfg->num_tx_chains[band] = tx_chains; - - dynamic_cfg = ucfg_mlme_get_dynamic_vdev_config(vdev); - if (!dynamic_cfg) { - hdd_err("nss chain dynamic config NULL"); - return QDF_STATUS_E_FAILURE; - } - /* - * If user gives any nss value, then chains will be adjusted based on - * nss (in SME func sme_validate_user_nss_chain_params). - * If Chains are not suitable as per current NSS then, we need to - * return, and the below logic is added for the same. - */ - - if ((dynamic_cfg->rx_nss[band] > rx_chains) || - (dynamic_cfg->tx_nss[band] > tx_chains)) { - hdd_err("Chains less than nss, configure correct nss first."); - return QDF_STATUS_E_FAILURE; - } - - return QDF_STATUS_SUCCESS; -} - -static int -hdd_set_dynamic_antenna_mode(struct hdd_adapter *adapter, - uint8_t num_rx_chains, - uint8_t num_tx_chains) -{ - enum nss_chains_band_info band; - struct wlan_mlme_nss_chains user_cfg; - QDF_STATUS status; - mac_handle_t mac_handle; - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - - mac_handle = hdd_ctx->mac_handle; - if (!mac_handle) { - hdd_err("NULL MAC handle"); - return -EINVAL; - } - - if (!hdd_is_vdev_in_conn_state(adapter)) { - hdd_debug("Vdev (id %d) not in connected/started state, cannot accept command", - adapter->vdev_id); - return -EINVAL; - } - - qdf_mem_zero(&user_cfg, sizeof(user_cfg)); - for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { - status = hdd_populate_vdev_chains(&user_cfg, - num_rx_chains, - num_tx_chains, band, - adapter->vdev); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; - } - status = sme_nss_chains_update(mac_handle, - &user_cfg, - adapter->vdev_id); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; - - return 0; -} int hdd_set_antenna_mode(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx, int mode) { @@ -7228,7 +7454,9 @@ static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter, wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id, CSA_REASON_USER_INITIATED); - status = hdd_softap_set_channel_change(dev, chan_number, width, true); + status = hdd_softap_set_channel_change(dev, + wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, chan_number), + width, true); if (status) { hdd_err("Set channel change fail"); return status; @@ -7333,6 +7561,7 @@ static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx, { struct hdd_adapter *adapter, *next = NULL; QDF_STATUS status; + uint8_t ap_ch; if (!hdd_ctx) return; @@ -7342,10 +7571,13 @@ static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx, status = hdd_get_front_adapter(hdd_ctx, &adapter); while (adapter && (status == QDF_STATUS_SUCCESS)) { if (!hdd_validate_adapter(adapter) && - (adapter->device_mode == QDF_SAP_MODE) && - (check_disable_channels(hdd_ctx, - adapter->session.ap.operating_channel))) - wlan_hdd_stop_sap(adapter); + adapter->device_mode == QDF_SAP_MODE) { + ap_ch = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + adapter->session.ap.operating_chan_freq); + if (check_disable_channels(hdd_ctx, ap_ch)) + wlan_hdd_stop_sap(adapter); + } status = hdd_get_next_adapter(hdd_ctx, adapter, &next); adapter = next; @@ -7375,7 +7607,7 @@ static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr) struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint8_t *param; int j, i, temp_int, ret = 0, num_channels; - uint32_t parsed_channels[MAX_CHANNEL]; + uint32_t parsed_channels[NUM_CHANNELS]; bool is_command_repeated = false; if (!hdd_ctx) { @@ -7408,7 +7640,7 @@ static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr) return -EINVAL; } - if (temp_int < 0 || temp_int > MAX_CHANNEL) { + if (temp_int < 0 || temp_int > NUM_CHANNELS) { hdd_err("Invalid Number of channel received"); return -EINVAL; } @@ -7420,7 +7652,7 @@ static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr) * Restore and Free the cache channels when the command is * received with num channels as 0 */ - wlan_hdd_restore_channels(hdd_ctx, false); + wlan_hdd_restore_channels(hdd_ctx); return 0; } @@ -7642,6 +7874,238 @@ static int drv_cmd_get_disable_chan_list(struct hdd_adapter *adapter, return 0; } #endif + +#ifdef FEATURE_ANI_LEVEL_REQUEST +static int drv_cmd_get_ani_level(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + char *extra; + int copied_length = 0, j, temp_int, ret = 0; + uint8_t *param, num_freqs, num_recv_channels; + uint32_t parsed_freqs[MAX_NUM_FREQS_FOR_ANI_LEVEL]; + struct wmi_host_ani_level_event ani[MAX_NUM_FREQS_FOR_ANI_LEVEL]; + size_t user_size = priv_data->total_len; + + hdd_debug("Received Command to get ANI level"); + + param = strnchr(command, strlen(command), ' '); + + /* No argument after the command */ + if (!param) + return -EINVAL; + + /* No space after the command */ + else if (SPACE_ASCII_VALUE != *param) + return -EINVAL; + + param++; + + /* Removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param)) + param++; + + /*no argument followed by spaces */ + if ('\0' == *param) + return -EINVAL; + + /* Getting the first argument ie the number of channels */ + if (sscanf(param, "%d ", &temp_int) != 1) { + hdd_err("Cannot get number of freq from input"); + return -EINVAL; + } + + if (temp_int < 0 || temp_int > MAX_NUM_FREQS_FOR_ANI_LEVEL) { + hdd_err("Invalid Number of channel received"); + return -EINVAL; + } + + hdd_debug("Number of freq to fetch ANI level are: %d", temp_int); + + if (!temp_int) + return 0; + + num_freqs = temp_int; + + for (j = 0; j < num_freqs; j++) { + /* + * Param pointing to the beginning of first space + * after number of channels. + */ + param = strpbrk(param, " "); + /*no channel list after the number of channels argument*/ + if (!param) { + hdd_err("Invalid No of freq provided in the list"); + ret = -EINVAL; + goto parse_failed; + } + + param++; + + /* Removing empty space */ + while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param)) + param++; + + if ('\0' == *param) { + hdd_err("No freq is provided in the list"); + ret = -EINVAL; + goto parse_failed; + } + + if (sscanf(param, "%d ", &temp_int) != 1) { + hdd_err("Cannot read freq number"); + ret = -EINVAL; + goto parse_failed; + } + + hdd_debug("channel_freq[%d] = %d", j, temp_int); + parsed_freqs[j] = temp_int; + } + + /* Extra arguments check */ + param = strpbrk(param, " "); + if (param) { + while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param)) + param++; + + if ('\0' != *param) { + hdd_err("Invalid argument received"); + ret = -EINVAL; + goto parse_failed; + } + } + + qdf_mem_zero(ani, sizeof(ani)); + hdd_debug("num_freq: %d", num_freqs); + if (QDF_IS_STATUS_ERROR(wlan_hdd_get_ani_level(adapter, ani, + parsed_freqs, + num_freqs))) { + hdd_err("Unable to retrieve ani level"); + return -EINVAL; + } + + extra = qdf_mem_malloc(user_size); + if (!extra) { + hdd_err("memory allocation failed"); + ret = -ENOMEM; + goto parse_failed; + } + + /* + * Find the number of channels that are populated. If freq is not + * filled then stop count there + */ + for (num_recv_channels = 0; + (num_recv_channels < num_freqs && + ani[num_recv_channels].chan_freq); num_recv_channels++) + ; + + for (j = 0; j < num_recv_channels; j++) { + /* Sanity check for ANI level validity */ + if (ani[j].ani_level > MAX_ANI_LEVEL) + continue; + + copied_length += scnprintf(extra + copied_length, + user_size - copied_length, "%d:%d\n", + ani[j].chan_freq, ani[j].ani_level); + } + + if (copied_length == 0) { + hdd_err("ANI level not fetched"); + ret = -EINVAL; + goto free; + } + + hdd_debug("data: %s", extra); + + if (copy_to_user(priv_data->buf, extra, copied_length + 1)) { + hdd_err("failed to copy data to user buffer"); + ret = -EFAULT; + goto free; + } + +free: + qdf_mem_free(extra); + +parse_failed: + return ret; +} + +#else +static int drv_cmd_get_ani_level(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + return 0; +} +#endif + +#ifdef FUNC_CALL_MAP +static int drv_cmd_get_function_call_map(struct hdd_adapter *adapter, + struct hdd_context *hdd_ctx, + uint8_t *command, + uint8_t command_len, + struct hdd_priv_data *priv_data) +{ + char *cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); + uint8_t *param; + int temp_int; + + param = strnchr(command, strlen(command), ' '); + /*no argument after the command*/ + if (NULL == param) + return -EINVAL; + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *param) + return -EINVAL; + + param++; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param)) + param++; + + /*no argument followed by spaces*/ + if ('\0' == *param) + return -EINVAL; + + /*getting the first argument */ + if (sscanf(param, "%d ", &temp_int) != 1) { + hdd_err("No option given"); + return -EINVAL; + } + + if (temp_int < 0 || temp_int > 1) { + hdd_err("Invalid option given"); + return -EINVAL; + } + + /* Read the buffer */ + if (temp_int) { + /* + * These logs are required as these indicates the start and end of the + * dump for the auto script to parse + */ + hdd_info("Function call map dump start"); + qdf_get_func_call_map(cc_buf); + qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, + cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); + hdd_info("Function call map dump end"); + } else { + qdf_clear_func_call_map(); + hdd_info("Function call map clear"); + } + qdf_mem_free(cc_buf); + + return 0; +} +#endif + /* * The following table contains all supported WLAN HDD * IOCTL driver commands and the handler for each of them. @@ -7713,6 +8177,8 @@ static const struct hdd_drv_cmd hdd_drv_cmds[] = { {"GETDWELLTIME", drv_cmd_get_dwell_time, false}, {"SETDWELLTIME", drv_cmd_set_dwell_time, true}, {"MIRACAST", drv_cmd_miracast, true}, + {"TPUT_DEBUG_MODE_ENABLE", drv_cmd_tput_debug_mode_enable, false}, + {"TPUT_DEBUG_MODE_DISABLE", drv_cmd_tput_debug_mode_disable, false}, {"SETIBSSBEACONOUIDATA", drv_cmd_set_ibss_beacon_oui_data, true}, #ifdef FEATURE_WLAN_RMC {"SETRMCENABLE", drv_cmd_set_rmc_enable, true}, @@ -7759,6 +8225,10 @@ static const struct hdd_drv_cmd hdd_drv_cmds[] = { {"GETANTENNAMODE", drv_cmd_get_antenna_mode, false}, {"SET_DISABLE_CHANNEL_LIST", drv_cmd_set_disable_chan_list, true}, {"GET_DISABLE_CHANNEL_LIST", drv_cmd_get_disable_chan_list, false}, + {"GET_ANI_LEVEL", drv_cmd_get_ani_level, false}, +#ifdef FUNC_CALL_MAP + {"GET_FUNCTION_CALL_MAP", drv_cmd_get_function_call_map, true}, +#endif {"STOP", drv_cmd_dummy, false}, /* Deprecated commands */ {"RXFILTER-START", drv_cmd_dummy, false}, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.h index f96e78f5fbec447775ee0fb370702f82ec560585..92180146713f8d56e736d98402a7496daf3de36e 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ioctl.h @@ -65,6 +65,22 @@ int hdd_set_antenna_mode(struct hdd_adapter *adapter, void hdd_get_roam_scan_ch_cb(hdd_handle_t hdd_handle, struct roam_scan_ch_resp *roam_ch, void *context); + +/** + * hdd_get_roam_scan_freq() - roam scan freq list + * @adapter: Pointer to hdd adapter + * @mac_handle: pointer to mac_handle + * @chan_list: Pointer to hold roam scan freq list + * @num_channels: Pointer to hold num of roam scan channels in list + * + * This function gets roam scan frequencies from FW if FW is capable else + * roam scan frequencies are taken from host maintained list. + * + * Return: 0 on success else error value + */ +int +hdd_get_roam_scan_freq(struct hdd_adapter *adapter, mac_handle_t mac_handle, + uint32_t *chan_list, uint8_t *num_channels); #else static inline void hdd_get_roam_scan_ch_cb(hdd_handle_t hdd_handle, @@ -72,6 +88,34 @@ hdd_get_roam_scan_ch_cb(hdd_handle_t hdd_handle, void *context) { } + +static inline int +hdd_get_roam_scan_freq(struct hdd_adapter *adapter, mac_handle_t mac_handle, + uint32_t *chan_list, uint8_t *num_channels) +{ + return -EFAULT; +} +#endif + +#ifdef QCA_IBSS_SUPPORT +/** + * hdd_get_ibss_peer_info_cb() - IBSS peer Info request callback + * @context: callback context (adapter supplied by caller) + * @peer_info: Peer info response + * + * This is an asynchronous callback function from SME when the peer info + * is received + * + * Return: 0 for success non-zero for failure + */ +void hdd_get_ibss_peer_info_cb(void *context, + tSirPeerInfoRspParams *peer_info); +#else +static inline void +hdd_get_ibss_peer_info_cb(void *context, + tSirPeerInfoRspParams *peer_info) +{ +} #endif #endif /* end #if !defined(WLAN_HDD_IOCTL_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c index c121e5fdfebf1016e69281e2e4c75e0c73f08bac..87c831c940f4023d411f70d127a56d0cbc18b048 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,7 +33,7 @@ void hdd_ipa_set_tx_flow_info(void) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx; struct hdd_ap_ctx *hdd_ap_ctx; struct hdd_hostapd_state *hostapd_state; @@ -55,6 +55,7 @@ void hdd_ipa_set_tx_flow_info(void) void *soc = cds_get_context(QDF_MODULE_ID_SOC); #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ struct wlan_objmgr_psoc *psoc; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -70,14 +71,16 @@ void hdd_ipa_set_tx_flow_info(void) psoc = hdd_ctx->psoc; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { switch (adapter->device_mode) { case QDF_STA_MODE: sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if (eConnectionState_Associated == sta_ctx->conn_info.conn_state) { - staChannel = - sta_ctx->conn_info.channel; + staChannel = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sta_ctx->conn_info.chan_freq); qdf_copy_macaddr(&staBssid, &sta_ctx->conn_info.bssid); #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL @@ -89,8 +92,9 @@ void hdd_ipa_set_tx_flow_info(void) sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if (eConnectionState_Associated == sta_ctx->conn_info.conn_state) { - p2pChannel = - sta_ctx->conn_info.channel; + p2pChannel = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + sta_ctx->conn_info.chan_freq); qdf_copy_macaddr(&p2pBssid, &sta_ctx->conn_info.bssid); p2pMode = "CLI"; @@ -105,7 +109,9 @@ void hdd_ipa_set_tx_flow_info(void) if (hostapd_state->bss_state == BSS_START && hostapd_state->qdf_status == QDF_STATUS_SUCCESS) { - p2pChannel = hdd_ap_ctx->operating_channel; + p2pChannel = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + hdd_ap_ctx->operating_chan_freq); qdf_copy_macaddr(&p2pBssid, &adapter->mac_addr); #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL @@ -120,7 +126,9 @@ void hdd_ipa_set_tx_flow_info(void) if (hostapd_state->bss_state == BSS_START && hostapd_state->qdf_status == QDF_STATUS_SUCCESS) { - apChannel = hdd_ap_ctx->operating_channel; + apChannel = wlan_reg_freq_to_chan( + hdd_ctx->pdev, + hdd_ap_ctx->operating_chan_freq); qdf_copy_macaddr(&apBssid, &adapter->mac_addr); #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL @@ -202,6 +210,8 @@ void hdd_ipa_set_tx_flow_info(void) if (!preAdapterContext) { hdd_err("SCC: Previous adapter context NULL"); + hdd_adapter_dev_put_debug( + adapter, dbgid); continue; } @@ -211,7 +221,7 @@ void hdd_ipa_set_tx_flow_info(void) preAdapterContext-> tx_flow_hi_watermark_offset = 0; cdp_fc_ll_set_tx_pause_q_depth(soc, - preAdapterContext->session_id, + preAdapterContext->vdev_id, hdd_ctx->config-> tx_hbw_flow_max_queue_depth); hdd_info("SCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d", @@ -250,6 +260,8 @@ void hdd_ipa_set_tx_flow_info(void) if (!adapter5) { hdd_err("MCC: 5GHz adapter context NULL"); + hdd_adapter_dev_put_debug( + adapter, dbgid); continue; } adapter5->tx_flow_low_watermark = @@ -260,7 +272,7 @@ void hdd_ipa_set_tx_flow_info(void) hdd_ctx->config-> tx_hbw_flow_hi_watermark_offset; cdp_fc_ll_set_tx_pause_q_depth(soc, - adapter5->session_id, + adapter5->vdev_id, hdd_ctx->config-> tx_hbw_flow_max_queue_depth); hdd_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d", @@ -278,6 +290,8 @@ void hdd_ipa_set_tx_flow_info(void) if (!adapter2_4) { hdd_err("MCC: 2.4GHz adapter context NULL"); + hdd_adapter_dev_put_debug( + adapter, dbgid); continue; } adapter2_4->tx_flow_low_watermark = @@ -288,7 +302,7 @@ void hdd_ipa_set_tx_flow_info(void) hdd_ctx->config-> tx_lbw_flow_hi_watermark_offset; cdp_fc_ll_set_tx_pause_q_depth(soc, - adapter2_4->session_id, + adapter2_4->vdev_id, hdd_ctx->config-> tx_lbw_flow_max_queue_depth); hdd_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d", @@ -310,6 +324,7 @@ void hdd_ipa_set_tx_flow_info(void) } targetChannel = 0; #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -349,6 +364,28 @@ static void hdd_ipa_set_wake_up_idle(bool wake_up_idle) } #endif +/** + * hdd_ipa_send_to_nw_stack() - Check if IPA supports NAPI + * polling during RX + * @skb : data buffer sent to network stack + * + * If IPA LAN RX supports NAPI polling mechanism use + * netif_receive_skb instead of netif_rx_ni to forward the skb + * to network stack. + * + * Return: Return value from netif_rx_ni/netif_receive_skb + */ +static int hdd_ipa_send_to_nw_stack(qdf_nbuf_t skb) +{ + int result; + + if (qdf_ipa_get_lan_rx_napi()) + result = netif_receive_skb(skb); + else + result = netif_rx_ni(skb); + return result; +} + #ifdef QCA_CONFIG_SMP /** @@ -361,12 +398,16 @@ static void hdd_ipa_set_wake_up_idle(bool wake_up_idle) * In this manner, UDP/TCP packets are sent in an aggregated way to the stack. * For IP/ICMP packets, simply call netif_rx_ni. * + * Check if IPA supports NAPI polling then use netif_receive_skb + * instead of netif_rx_ni. + * * Return: return value from the netif_rx_ni/netif_rx api. */ static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb) { int ret; - ret = netif_rx_ni(skb); + + ret = hdd_ipa_send_to_nw_stack(skb); return ret; } #else @@ -380,13 +421,13 @@ static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb) ip_h = (struct iphdr *)(skb->data); if ((skb->protocol == htons(ETH_P_IP)) && (ip_h->protocol == IPPROTO_ICMP)) { - result = netif_rx_ni(skb); + result = hdd_ipa_send_to_nw_stack(skb); } else { /* Call netif_rx_ni for every IPA_WLAN_RX_SOFTIRQ_THRESH packets * to avoid excessive softirq's. */ if (atomic_dec_and_test(&softirq_mitigation_cntr)) { - result = netif_rx_ni(skb); + result = hdd_ipa_send_to_nw_stack(skb); atomic_set(&softirq_mitigation_cntr, IPA_WLAN_RX_SOFTIRQ_THRESH); } else { @@ -460,14 +501,10 @@ void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t nbuf, qdf_netdev_t dev) adapter->stats.rx_bytes += nbuf->len; result = hdd_ipa_aggregated_rx_ind(nbuf); - if (result == NET_RX_SUCCESS) { + if (result == NET_RX_SUCCESS) ++adapter->hdd_stats.tx_rx_stats.rx_delivered[cpu_index]; - } else { + else ++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index]; - DPTRACE(qdf_dp_log_proto_pkt_info(NULL, NULL, 0, 0, QDF_RX, - QDF_TRACE_DEFAULT_MSDU_ID, - QDF_TX_RX_STATUS_DROP)); - } /* * Restore PF_WAKE_UP_IDLE flag in the task structure diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lpass.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lpass.c index 28be8189d9c56a094a6fd76c9b6f198d9e6b4292..5bcc702c65926907afa44eb6736456ec287a7c1a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lpass.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lpass.c @@ -34,33 +34,32 @@ * wlan_hdd_get_channel_info() - Get channel info * @hdd_ctx: HDD context * @chan_info: Pointer to the structure that stores channel info - * @chan_id: Channel ID + * @chan_freq: Channel freq * * Fill in the channel info to chan_info structure. */ static void wlan_hdd_get_channel_info(struct hdd_context *hdd_ctx, struct svc_channel_info *chan_info, - uint32_t chan_id) + uint32_t chan_freq) { uint32_t reg_info_1; uint32_t reg_info_2; QDF_STATUS status = QDF_STATUS_E_FAILURE; - status = sme_get_reg_info(hdd_ctx->mac_handle, chan_id, + status = sme_get_reg_info(hdd_ctx->mac_handle, chan_freq, ®_info_1, ®_info_2); if (status != QDF_STATUS_SUCCESS) return; - chan_info->mhz = cds_chan_to_freq(chan_id); + chan_info->mhz = chan_freq; chan_info->band_center_freq1 = chan_info->mhz; chan_info->band_center_freq2 = 0; chan_info->info = 0; if (CHANNEL_STATE_DFS == - wlan_reg_get_channel_state(hdd_ctx->pdev, - chan_id)) + wlan_reg_get_channel_state_for_freq(hdd_ctx->pdev, chan_freq)) WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_DFS); - hdd_update_channel_bw_info(hdd_ctx, chan_id, + hdd_update_channel_bw_info(hdd_ctx, chan_freq, chan_info); chan_info->reg_info_1 = reg_info_1; chan_info->reg_info_2 = reg_info_2; @@ -88,6 +87,7 @@ static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data, uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN; int i; uint32_t chan_id; + uint32_t *chan_freq_list, chan_freq_len; struct svc_channel_info *chan_info; bool lpass_support; QDF_STATUS status; @@ -122,17 +122,30 @@ static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data, data->lpss_support = 1; else data->lpss_support = 0; - data->numChannels = WLAN_SVC_MAX_NUM_CHAN; - sme_get_cfg_valid_channels(data->channel_list, - &data->numChannels); + + chan_freq_list = + qdf_mem_malloc(sizeof(uint32_t) * WLAN_SVC_MAX_NUM_CHAN); + if (!chan_freq_list) + return -ENOMEM; + + chan_freq_len = WLAN_SVC_MAX_NUM_CHAN; + sme_get_cfg_valid_channels(chan_freq_list, &chan_freq_len); + + data->numChannels = chan_freq_len; for (i = 0; i < data->numChannels; i++) { chan_info = &data->channel_info[i]; + data->channel_list[i] = + wlan_reg_freq_to_chan(hdd_ctx->pdev, chan_freq_list[i]); chan_id = data->channel_list[i]; chan_info->chan_id = chan_id; - wlan_hdd_get_channel_info(hdd_ctx, chan_info, chan_id); + wlan_hdd_get_channel_info(hdd_ctx, + chan_info, + chan_freq_list[i]); } + qdf_mem_free(chan_freq_list); + sme_get_country_code(hdd_ctx->mac_handle, data->country_code, &buflen); data->is_on = is_on; data->vdev_id = adapter->vdev_id; @@ -140,8 +153,7 @@ static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data, if (sta_ctx) { data->is_connected = is_connected; data->rssi = adapter->rssi; - data->freq = - cds_chan_to_freq(sta_ctx->conn_info.channel); + data->freq = sta_ctx->conn_info.chan_freq; if (WLAN_SVC_MAX_SSID_LEN >= sta_ctx->conn_info.ssid.SSID.length) { data->ssid_len = sta_ctx->conn_info.ssid.SSID.length; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lro.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lro.c index 4b9ed69f646cc42282b5c6a348daf28e25e367f2..97972ecd063d9e961e3173c97a3b957465451294 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lro.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_lro.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,7 +38,8 @@ (LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \ LRO_TCP_DATA_CSUM | LRO_TCP_SEQ_NUM | LRO_TCP_WIN) -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) static qdf_lro_ctx_t wlan_hdd_get_lro_ctx(struct sk_buff *skb) { return (qdf_lro_ctx_t)QDF_NBUF_CB_RX_LRO_CTX(skb); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c index 1ec6bc1251aadc26294c0427e2bd0e67f99bcfc7..e53c8e08c118db75ed990c22e7628e361f50d3d6 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -52,6 +53,7 @@ #include "wlan_hdd_periodic_sta_stats.h" #include "wlan_hdd_scan.h" #include "wlan_policy_mgr_ucfg.h" +#include "wlan_osif_priv.h" #include #ifdef CONFIG_LEAK_DETECTION #include "qdf_debug_domain.h" @@ -141,6 +143,7 @@ #include "enet.h" #include #include +#include #include "wlan_hdd_sysfs.h" #include "wlan_disa_ucfg_api.h" #include "wlan_disa_obj_mgmt_api.h" @@ -160,6 +163,8 @@ #include "wlan_mlme_ucfg_api.h" #include "wlan_fwol_ucfg_api.h" #include "wlan_policy_mgr_ucfg.h" +#include "qdf_func_tracker.h" + #ifdef CNSS_GENL #include #endif @@ -173,11 +178,19 @@ #include #include #include "wlan_blm_ucfg_api.h" -#include "nan_ucfg_api.h" -#include "wlan_osif_priv.h" -#include "cfg_nan_api.h" -#include +#include "ftm_time_sync_ucfg_api.h" +#include "ol_txrx.h" +#include "wlan_hdd_sta_info.h" +#include "mac_init_api.h" #include "wlan_pkt_capture_ucfg_api.h" +#include +#include "cfg_nan_api.h" +#include +#include +#include "wlan_global_lmac_if_api.h" +#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION +#include +#endif #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -203,6 +216,15 @@ #define PANIC_ON_BUG_STR "" #endif +#define MAX_NET_DEV_REF_LEAK_ITERATIONS 10 +#define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10 + +#ifdef FEATURE_TSO +#define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) +#else +#define TSO_FEATURE_FLAGS 0 +#endif + int wlan_start_ret_val; static DECLARE_COMPLETION(wlan_start_comp); static qdf_atomic_t wlan_hdd_state_fops_ref; @@ -212,33 +234,6 @@ static struct class *class; static dev_t device; static bool hdd_loaded = false; -#if 0 -static struct gwlan_loader *wlan_loader; -static ssize_t wlan_boot_cb(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count); -struct gwlan_loader { - bool loaded_state; - struct kobject *boot_wlan_obj; - struct attribute_group *attr_group; -}; - -static struct kobj_attribute wlan_boot_attribute = - __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb); - -static struct attribute *attrs[] = { - &wlan_boot_attribute.attr, - NULL, -}; -#define MODULE_INITIALIZED 1 - -#ifdef MULTI_IF_NAME -#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME -#else -#define WLAN_LOADER_NAME "boot_wlan" -#endif -#endif - /* the Android framework expects this param even though we don't use it */ #define BUF_LEN 20 static char fwpath_buffer[BUF_LEN]; @@ -261,8 +256,6 @@ static qdf_wake_lock_t wlan_wake_lock; #define WOW_MIN_PATTERN_SIZE 6 #define WOW_MAX_PATTERN_SIZE 64 -/* max peer can be tdls peers + self peer + bss peer */ -#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2) #define IS_IDLE_STOP (!cds_is_driver_unloading() && \ !cds_is_driver_recovering() && !cds_is_driver_loading()) @@ -347,7 +340,11 @@ static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { [QDF_MODULE_ID_BLACKLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL}, + [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL}, + [QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL}, + [QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL}, + [QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL}, }; struct notifier_block hdd_netdev_notifier; @@ -357,6 +354,231 @@ struct sock *cesium_nl_srv_sock; static void wlan_hdd_auto_shutdown_cb(void); #endif +QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + struct csr_roam_info *roam_info, + uint32_t roam_id, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result) +{ + struct hdd_context *hdd_ctx; + struct hdd_adapter *adapter; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + adapter = wlan_hdd_get_adapter_from_vdev(psoc, session_id); + if (!adapter) + return QDF_STATUS_E_INVAL; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) + return QDF_STATUS_E_INVAL; + + switch (adapter->device_mode) { + case QDF_STA_MODE: + case QDF_NDI_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_DEVICE_MODE: + status = hdd_sme_roam_callback(adapter, roam_info, roam_id, + roam_status, roam_result); + break; + case QDF_SAP_MODE: + case QDF_P2P_GO_MODE: + status = wlansap_roam_callback(adapter->session.ap.sap_context, + roam_info, roam_id, roam_status, + roam_result); + break; + default: + hdd_err("Wrong device mode"); + break; + } + + return status; +} +/** + * hdd_mic_flush_work() - disable and flush pending mic work + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_mic_flush_work(struct hdd_adapter *adapter) +{ + hdd_debug("Flush the MIC error work"); + + qdf_spin_lock_bh(&adapter->mic_work.lock); + if (adapter->mic_work.status != MIC_SCHEDULED) { + qdf_spin_unlock_bh(&adapter->mic_work.lock); + return; + } + adapter->mic_work.status = MIC_DISABLED; + qdf_spin_unlock_bh(&adapter->mic_work.lock); + + qdf_flush_work(&adapter->mic_work.work); +} + +/** + * hdd_mic_enable_work() - enable mic error work + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_mic_enable_work(struct hdd_adapter *adapter) +{ + hdd_debug("Enable the MIC error work"); + + qdf_spin_lock_bh(&adapter->mic_work.lock); + if (adapter->mic_work.status == MIC_DISABLED) + adapter->mic_work.status = MIC_INITIALIZED; + qdf_spin_unlock_bh(&adapter->mic_work.lock); +} + +/** + * hdd_mic_deinit_work() - deinitialize mic error work + * @hdd_adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_mic_deinit_work(struct hdd_adapter *adapter) +{ + hdd_debug("DeInitialize the MIC error work"); + + if (adapter->mic_work.status != MIC_UNINITIALIZED) { + qdf_destroy_work(NULL, &adapter->mic_work.work); + + qdf_spin_lock_bh(&adapter->mic_work.lock); + adapter->mic_work.status = MIC_UNINITIALIZED; + if (adapter->mic_work.info) { + qdf_mem_free(adapter->mic_work.info); + adapter->mic_work.info = NULL; + } + qdf_spin_unlock_bh(&adapter->mic_work.lock); + qdf_spinlock_destroy(&adapter->mic_work.lock); + } +} + +/** + * hdd_process_sta_mic_error() - Indicate STA mic error to supplicant + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_process_sta_mic_error(struct hdd_adapter *adapter) +{ + struct hdd_station_ctx *sta_ctx; + struct hdd_mic_error_info *info; + + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + if (eConnectionState_Associated != + sta_ctx->conn_info.conn_state) + return; + + info = adapter->mic_work.info; + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(adapter->dev, + (uint8_t *)&info->ta_mac_addr, + info->multicast ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE, + info->key_id, + info->tsc, + GFP_KERNEL); +} + +/** + * hdd_process_sap_mic_error() - Indicate SAP mic error to supplicant + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_process_sap_mic_error(struct hdd_adapter *adapter) +{ + struct hdd_mic_error_info *info; + + info = adapter->mic_work.info; + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(adapter->dev, + (uint8_t *)&info->ta_mac_addr, + info->multicast ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE, + info->key_id, + info->tsc, + GFP_KERNEL); +} + +/** + * __hdd_process_mic_error() - Indicate mic error to supplicant + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +__hdd_process_mic_error(struct hdd_adapter *adapter) +{ + if (adapter->device_mode == QDF_STA_MODE || + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + hdd_process_sta_mic_error(adapter); + } else if (adapter->device_mode == QDF_SAP_MODE || + adapter->device_mode == QDF_P2P_GO_MODE) { + hdd_process_sap_mic_error(adapter); + } else { + hdd_err("Invalid interface type:%d", adapter->device_mode); + } +} + +/** + * hdd_process_mic_error() - process mic error work + * @data: void pointer to hdd adapter + * + * Return: None + */ +static void +hdd_process_mic_error(void *data) +{ + struct hdd_adapter *adapter = data; + struct osif_vdev_sync *vdev_sync; + + if (hdd_validate_adapter(adapter)) + goto exit; + + if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync)) + goto exit; + + __hdd_process_mic_error(adapter); + + osif_vdev_sync_op_stop(vdev_sync); +exit: + qdf_spin_lock_bh(&adapter->mic_work.lock); + if (adapter->mic_work.info) { + qdf_mem_free(adapter->mic_work.info); + adapter->mic_work.info = NULL; + } + if (adapter->mic_work.status == MIC_SCHEDULED) + adapter->mic_work.status = MIC_INITIALIZED; + qdf_spin_unlock_bh(&adapter->mic_work.lock); +} + +/** + * hdd_mic_init_work() - init mic error work + * @hdd_adapter: Pointer to hdd adapter + * + * Return: None + */ +static void +hdd_mic_init_work(struct hdd_adapter *adapter) +{ + qdf_spinlock_create(&adapter->mic_work.lock); + qdf_create_work(0, &adapter->mic_work.work, + hdd_process_mic_error, adapter); + adapter->mic_work.status = MIC_INITIALIZED; + adapter->mic_work.info = NULL; +} + void hdd_start_complete(int ret) { wlan_start_ret_val = ret; @@ -372,10 +594,14 @@ void hdd_start_complete(int ret) */ static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; - hdd_for_each_adapter(hdd_ctx, adapter) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_SET_RPS_CPU_MASK) { hdd_send_rps_ind(adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_SET_RPS_CPU_MASK); + } } #ifdef QCA_HL_NETDEV_FLOW_CONTROL @@ -600,76 +826,11 @@ uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBU uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR; #endif -/** - * hdd_get_valid_chan() - return current chan list from regulatory. - * @hdd_ctx: HDD context - * @chan_list: buf hold returned chan list - * @chan_num: input buf size and output returned chan num - * - * This function helps get current available chan list from regulatory - * module. It excludes the "disabled" and "invalid" channels. - * - * Return: 0 for success. - */ -static int hdd_get_valid_chan(struct hdd_context *hdd_ctx, - uint8_t *chan_list, - uint32_t *chan_num) -{ - int i = 0, j = 0; - struct regulatory_channel *cur_chan_list; - struct wlan_objmgr_pdev *pdev; - - if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num) - return -EINVAL; - - pdev = hdd_ctx->pdev; - cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * - sizeof(struct regulatory_channel)); - if (!cur_chan_list) - return -ENOMEM; - - if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) != - QDF_STATUS_SUCCESS) { - qdf_mem_free(cur_chan_list); - return -EINVAL; - } - - for (i = 0; i < NUM_CHANNELS; i++) { - uint32_t ch = cur_chan_list[i].chan_num; - enum channel_state state = wlan_reg_get_channel_state(pdev, - ch); - - if (state != CHANNEL_STATE_DISABLE && - state != CHANNEL_STATE_INVALID && - j < *chan_num) { - chan_list[j] = (uint8_t)ch; - j++; - } - } - *chan_num = j; - qdf_mem_free(cur_chan_list); - return 0; -} - -/** - * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo - * @adapter: HDD adapter - * @chan_number: Channel number - * @chan_bw: Bandwidth - * - * Checks if the given bandwidth is valid for the given channel number. - * - * Return: 0 for success, non-zero for failure - */ int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, - uint32_t chan_number, - enum phy_ch_width chan_bw) + qdf_freq_t chan_freq, + enum phy_ch_width chan_bw) { - uint8_t chan[NUM_CHANNELS]; - uint32_t len = NUM_CHANNELS, i; - bool found = false; mac_handle_t mac_handle; - int ret; mac_handle = hdd_adapter_get_mac_handle(adapter); if (!mac_handle) { @@ -677,39 +838,34 @@ int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, return -EINVAL; } - ret = hdd_get_valid_chan(adapter->hdd_ctx, chan, - &len); - if (ret) { - hdd_err("error %d in getting valid channel list", ret); - return ret; - } - - for (i = 0; i < len; i++) { - if (chan[i] == chan_number) { - found = true; - break; - } - } - - if (found == false) { - hdd_err("Channel not in driver's valid channel list"); + if (INVALID_CHANNEL == wlan_reg_get_chan_enum_for_freq(chan_freq)) { + hdd_err("Channel freq %d not in driver's valid channel list", chan_freq); return -EOPNOTSUPP; } - if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) && - (!WLAN_REG_IS_5GHZ_CH(chan_number))) { - hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number); + if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) && + (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) && + (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { + hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq); return -EINVAL; } - if (WLAN_REG_IS_24GHZ_CH(chan_number)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { if (chan_bw == CH_WIDTH_80MHZ) { hdd_err("BW80 not possible in 2.4GHz band"); return -EINVAL; } - if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) && - (chan_bw != CH_WIDTH_MAX)) { - hdd_err("Only BW20 possible on channel 14"); + if ((chan_bw != CH_WIDTH_20MHZ) && (chan_freq == 2484) && + (chan_bw != CH_WIDTH_MAX)) { + hdd_err("Only BW20 possible on channel freq 2484"); + return -EINVAL; + } + } + + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { + if ((chan_bw != CH_WIDTH_20MHZ) && (chan_freq == 5825) && + (chan_bw != CH_WIDTH_MAX)) { + hdd_err("Only BW20 possible on channel freq 5825"); return -EINVAL; } } @@ -717,23 +873,29 @@ int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, return 0; } -uint8_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter) +uint32_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter) { - uint8_t home_channel = 0; + uint32_t home_chan_freq = 0; + struct hdd_context *hdd_ctx; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (!hdd_ctx) { + hdd_err("hdd context is NULL"); + return 0; + } if ((adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) && test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { - home_channel = adapter->session.ap.operating_channel; + home_chan_freq = adapter->session.ap.operating_chan_freq; } else if ((adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) && adapter->session.station.conn_info.conn_state == eConnectionState_Associated) { - home_channel = - adapter->session.station.conn_info.channel; + home_chan_freq = adapter->session.station.conn_info.chan_freq; } - return home_channel; + return home_chan_freq; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) @@ -841,6 +1003,9 @@ static int __hdd_netdev_notifier_call(struct net_device *net_dev, */ wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev); break; + case NETDEV_FEAT_CHANGE: + hdd_debug("vdev %d netdev Feature 0x%llx\n", + adapter->vdev_id, net_dev->features); default: break; @@ -1215,17 +1380,7 @@ bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx) return true; } -/** - * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA. - * @struct hdd_adapter Hdd adapter. - * - * This function sets the IBSS power save config parameters to WMA - * which will send it to firmware if FW supports IBSS power save - * before vdev start. - * - * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE - * on failure. - */ +#ifdef QCA_IBSS_SUPPORT QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -1238,6 +1393,7 @@ QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter) return ucfg_mlme_ibss_power_save_setup(hdd_ctx->psoc, adapter->vdev_id); } +#endif #ifdef FEATURE_RUNTIME_PM /** @@ -1302,8 +1458,8 @@ void hdd_update_macaddr(struct hdd_context *hdd_ctx, hw_macaddr.bytes, QDF_MAC_ADDR_SIZE); hdd_ctx->num_provisioned_addr++; hdd_debug("hdd_ctx->provisioned_mac_addr[0]: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdd_ctx-> + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdd_ctx-> provisioned_mac_addr[0].bytes)); } else { qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes, @@ -1311,9 +1467,8 @@ void hdd_update_macaddr(struct hdd_context *hdd_ctx, QDF_MAC_ADDR_SIZE); hdd_ctx->num_derived_addr++; hdd_debug("hdd_ctx->derived_mac_addr[0]: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( - hdd_ctx->derived_mac_addr[0].bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes)); } for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA - hdd_ctx->num_provisioned_addr); @@ -1335,9 +1490,8 @@ void hdd_update_macaddr(struct hdd_context *hdd_ctx, hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02; hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3; hdd_debug("hdd_ctx->derived_mac_addr[%d]: " - QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY( - hdd_ctx->derived_mac_addr[i].bytes)); + QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); hdd_ctx->num_derived_addr++; } } @@ -1366,7 +1520,6 @@ static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) tdls_cfg.tdls_evt_cb_data = psoc; tdls_cfg.tdls_peer_context = hdd_ctx; tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer; - tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer; tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed; tdls_cfg.tdls_wmm_cb_data = psoc; tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback; @@ -1401,7 +1554,8 @@ void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc, adapter = wlan_hdd_get_adapter_from_vdev(psoc, vdev_id); if (adapter && cfg_nan_is_roam_config_disabled(psoc)) { - hdd_debug("vdev_id:%d ndp active sessions %d", vdev_id, cnt); + hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id, + cnt ? "" : " no more"); if (!cnt) wlan_hdd_enable_roaming(adapter, RSO_NDP_CON_ON_NDI); else @@ -1684,9 +1838,8 @@ static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, struct wiphy *wiphy = hdd_ctx->wiphy; struct ieee80211_supported_band *band_5g = wiphy->bands[HDD_NL80211_BAND_5GHZ]; - uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ; - struct wma_caps_per_phy caps_per_phy; - uint8_t val = 0; + uint32_t ch_width; + struct wma_caps_per_phy caps_per_phy = {0}; bool vht_enable_2x2; uint32_t tx_highest_data_rate; uint32_t rx_highest_data_rate; @@ -1751,32 +1904,22 @@ static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, - VHT_CAP_160_AND_80P80_SUPP); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not set the VHT CAP 160"); band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; - ch_width = eHT_CHANNEL_WIDTH_80P80MHZ; + ch_width = VHT_CAP_160_AND_80P80_SUPP; } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, - VHT_CAP_160_SUPP); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not set the VHT CAP 160"); band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; - ch_width = eHT_CHANNEL_WIDTH_160MHZ; + ch_width = VHT_CAP_160_SUPP; + } else { + ch_width = VHT_CAP_NO_160M_SUPP; } - status = - ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not get channel_width"); - - val = QDF_MIN(val, ch_width); - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val); + status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); if (QDF_IS_STATUS_ERROR(status)) hdd_err("could not set the channel width"); + else + hdd_debug("supported channel width %d", ch_width); if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; @@ -2008,7 +2151,7 @@ static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx) QDF_STATUS status; bool b2g_vht_cfg = false; bool b2g_vht_target = false; - struct wma_caps_per_phy caps_per_phy; + struct wma_caps_per_phy caps_per_phy = {0}; struct wmi_unified *wmi_handle; wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); @@ -2068,8 +2211,48 @@ static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext); } -#if defined(WLAN_FEATURE_11AX) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if (((defined(CONFIG_BAND_6GHZ) && defined(CFG80211_6GHZ_BAND_SUPPORTED)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) && defined(WLAN_FEATURE_11AX)) +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) +static void +hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) +{ + struct ieee80211_supported_band *band_6g = + hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; + uint8_t *phy_info = + hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; + uint8_t max_fw_bw = sme_get_vht_ch_width(); + + if (!band_6g || !phy_info) { + hdd_debug("6ghz not supported in wiphy"); + return; + } + + hdd_ctx->iftype_data_6g->types_mask = + (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); + hdd_ctx->iftype_data_6g->he_cap.has_he = true; + band_6g->n_iftype_data = 1; + + if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + phy_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; + if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) + phy_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) + phy_info[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; + + band_6g->iftype_data = hdd_ctx->iftype_data_6g; +} +#else +static inline void +hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) +{ +} +#endif + static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) { tDot11fIEhe_cap he_cap_cfg; @@ -2081,6 +2264,9 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) uint8_t *phy_info_5g = hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info; uint8_t max_fw_bw = sme_get_vht_ch_width(); + uint32_t channel_bonding_mode_2g; + uint8_t *phy_info_2g = + hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); @@ -2093,6 +2279,12 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present; band_2g->n_iftype_data = 1; band_2g->iftype_data = hdd_ctx->iftype_data_2g; + + ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, + &channel_bonding_mode_2g); + if (channel_bonding_mode_2g) + phy_info_2g[0] |= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; } if (band_5g) { hdd_ctx->iftype_data_5g->types_mask = @@ -2110,6 +2302,8 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) phy_info_5g[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; } + + hdd_update_wiphy_he_caps_6ghz(hdd_ctx); } #else static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) @@ -2117,11 +2311,39 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) } #endif +static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) +{ + ucfg_mlme_cfg_chan_to_freq(pdev); +} + +static uint32_t hdd_update_band_cap_from_dot11mode( + struct hdd_context *hdd_ctx, uint32_t band_capability) +{ + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) + return band_capability; + + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) + band_capability = (band_capability & (~BIT(REG_BAND_5G))); + + if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) + band_capability = (band_capability & (~BIT(REG_BAND_2G))); + + if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && + hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) + band_capability = (band_capability & (~BIT(REG_BAND_6G))); + + qdf_debug("Update band capability %x", band_capability); + return band_capability; +} + int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) { int ret; struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); - uint8_t temp_band_cap, band_capability; + uint32_t temp_band_cap, band_capability; struct cds_config_info *cds_cfg = cds_get_ini_config(); uint8_t antenna_mode; uint8_t sub_20_chan_width; @@ -2160,20 +2382,17 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) ret = qdf_status_to_os_return(status); goto dispatcher_close; } - - cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), - (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev); - - wlan_pdev_set_dp_handle(hdd_ctx->pdev, - cds_get_context(QDF_MODULE_ID_TXRX)); + /* + * For 6GHz support this api is added to convert mlme cfgs + * channel numbers to frequency + */ + hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count); ucfg_ipa_set_dp_handle(hdd_ctx->psoc, cds_get_context(QDF_MODULE_ID_SOC)); - ucfg_ipa_set_txrx_handle(hdd_ctx->psoc, - cds_get_context(QDF_MODULE_ID_TXRX)); + ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID); ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev, hdd_softap_ipa_start_xmit); ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev, @@ -2205,6 +2424,9 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) goto pdev_close; } + band_capability = + hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); + /* first store the INI band capability */ temp_band_cap = band_capability; @@ -2216,17 +2438,14 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) cfg->services.is_11k_offload_supported; /* - * now overwrite the target band capability with INI - * setting if INI setting is a subset + * merge the target band capability with INI setting if the merge has + * at least 1 band enabled */ - if ((band_capability == BAND_ALL) && - (temp_band_cap != BAND_ALL)) - band_capability = temp_band_cap; - else if ((band_capability != BAND_ALL) && - (temp_band_cap != BAND_ALL) && - (band_capability != temp_band_cap)) { + temp_band_cap &= band_capability; + if (!temp_band_cap) hdd_warn("ini BandCapability not supported by the target"); - } + else + band_capability = temp_band_cap; status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability); if (QDF_IS_STATUS_ERROR(status)) { @@ -2289,7 +2508,10 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); - if (cfg->services.en_11ax) { + if (cfg->services.en_11ax && + (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax || + hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) { hdd_debug("11AX: 11ax is enabled - update HDD config"); hdd_update_tgt_he_cap(hdd_ctx, cfg); hdd_update_wiphy_he_cap(hdd_ctx); @@ -2349,6 +2571,11 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) hdd_err("set tx_bfee_ant_supp failed"); } + status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc, + cfg->restricted_80p80_bw_supp); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Failed to set MLME restircted 80p80 BW support"); + if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && !cfg->tx_bfee_8ss_enabled) { status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc, @@ -2395,6 +2622,14 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) if (QDF_IS_STATUS_ERROR(status)) hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD"); + if (!cfg->obss_color_collision_offloaded) { + status = ucfg_mlme_set_bss_color_collision_det_sta( + hdd_ctx->psoc, + cfg->obss_color_collision_offloaded); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA"); + } + ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &bval); if (bval) ucfg_mlme_set_bcast_twt(hdd_ctx->psoc, cfg->bcast_twt_support); @@ -2415,7 +2650,7 @@ int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct hdd_ap_ctx *ap_ctx; bool dfs_disable_channel_switch = false; @@ -2432,22 +2667,25 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) return true; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_DFS_INDICATE_RADAR) { ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); if ((QDF_SAP_MODE == adapter->device_mode || QDF_P2P_GO_MODE == adapter->device_mode) && - (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev, - ap_ctx->operating_channel))) { + (wlan_reg_is_passive_or_disable_for_freq(hdd_ctx->pdev, + ap_ctx->operating_chan_freq))) { WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx = true; hdd_info("tx blocked for vdev: %d", adapter->vdev_id); - if (adapter->txrx_vdev) + if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX) cdp_fc_vdev_flush( cds_get_context(QDF_MODULE_ID_SOC), - adapter->txrx_vdev); + adapter->vdev_id); } + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_DFS_INDICATE_RADAR); } return true; @@ -2504,7 +2742,8 @@ static void hdd_mon_mode_ether_setup(struct net_device *dev) */ static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx) { - ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED); + ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, + PMO_PS_ADVANCED_POWER_SAVE_DISABLE); ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH); } @@ -2602,11 +2841,9 @@ static int hdd_mon_open(struct net_device *net_dev) */ static int __hdd_pktcapture_open(struct net_device *dev) { + int ret; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - struct hdd_adapter *sta_adapter; - QDF_STATUS status; - int ret; hdd_enter_dev(dev); @@ -2614,38 +2851,20 @@ static int __hdd_pktcapture_open(struct net_device *dev) if (ret) return ret; - sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); - if (!sta_adapter) { - hdd_err("No station interface found"); - return -EINVAL; - } - - adapter->vdev = hdd_objmgr_get_vdev(sta_adapter); - if (!adapter->vdev) { - hdd_err("station interface is not up"); - return -EINVAL; - } - hdd_mon_mode_ether_setup(dev); - status = ucfg_pkt_capture_register_callbacks(adapter->vdev, - hdd_mon_rx_packet_cbk, - adapter); - ret = qdf_status_to_os_return(status); - if (ret) { - hdd_objmgr_put_vdev(adapter->vdev); - return ret; - } + ret = hdd_set_pktcapture_cb(dev, OL_TXRX_PDEV_ID); - set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); + if (!ret) + set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); return ret; } /** - * hdd_pktcapture_open() - Wrapper function for __hdd_pktcapture_open to + * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to * protect it from SSR - * @dev: Pointer to net_device structure + * @dev: Pointer to net_device structure * * This is called in response to ifconfig up * @@ -2666,72 +2885,6 @@ static int hdd_pktcapture_open(struct net_device *net_dev) return errno; } - -/** - * hdd_del_monitor_interface() - Delete monitor interface - * @hdd_ctx: hdd context - * - * Return: void - */ -static void hdd_del_monitor_interface(struct hdd_context *hdd_ctx) -{ - struct hdd_adapter *adapter; - - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) { - struct osif_vdev_sync *vdev_sync; - - vdev_sync = osif_vdev_sync_unregister(adapter->dev); - - if (hdd_is_interface_up(adapter)) { - hdd_stop_adapter(hdd_ctx, adapter); - hdd_deinit_adapter(hdd_ctx, adapter, true); - } - - hdd_close_adapter(hdd_ctx, adapter, true); - - if (vdev_sync) { - osif_vdev_sync_wait_for_ops(vdev_sync); - osif_vdev_sync_destroy(vdev_sync); - } - } -} - -/** - * hdd_close_monitor_interface() - Close monitor interface - * @hdd_ctx: hdd context - * - * Return: void - */ -static void hdd_close_monitor_interface(struct hdd_context *hdd_ctx) -{ - struct hdd_adapter *adapter; - - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) { - struct osif_vdev_sync *vdev_sync; - - vdev_sync = osif_vdev_sync_unregister( - adapter->dev); - - wlan_hdd_del_monitor(hdd_ctx, adapter, true); - - if (vdev_sync) { - osif_vdev_sync_wait_for_ops(vdev_sync); - osif_vdev_sync_destroy(vdev_sync); - } - } -} -#else -static inline void -hdd_del_monitor_interface(struct hdd_context *hdd_ctx) -{ -} - -static inline void -hdd_close_monitor_interface(struct hdd_context *hdd_ctx) -{ -} #endif static QDF_STATUS @@ -2758,6 +2911,11 @@ wlan_hdd_update_dbs_scan_and_fw_mode_config(void) if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc)) return QDF_STATUS_SUCCESS; + if (hdd_ctx->is_dual_mac_cfg_updated) { + hdd_debug("dual mac config has already been updated, skip"); + return QDF_STATUS_SUCCESS; + } + cfg.scan_config = 0; cfg.fw_mode_config = 0; cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; @@ -2796,10 +2954,11 @@ wlan_hdd_update_dbs_scan_and_fw_mode_config(void) cfg.scan_config, cfg.fw_mode_config); status = sme_soc_set_dual_mac_config(cfg); - if (status != QDF_STATUS_SUCCESS) { + if (QDF_IS_STATUS_ERROR(status)) { hdd_err("sme_soc_set_dual_mac_config failed %d", status); return status; } + hdd_ctx->is_dual_mac_cfg_updated = true; return QDF_STATUS_SUCCESS; } @@ -2834,12 +2993,14 @@ int hdd_start_adapter(struct hdd_adapter *adapter) goto err_start_adapter; hdd_nud_ignore_tracking(adapter, false); + hdd_mic_enable_work(adapter); break; case QDF_P2P_GO_MODE: case QDF_SAP_MODE: ret = hdd_start_ap_adapter(adapter); if (ret) goto err_start_adapter; + hdd_mic_enable_work(adapter); break; case QDF_IBSS_MODE: /* @@ -2879,6 +3040,44 @@ int hdd_start_adapter(struct hdd_adapter *adapter) return -EINVAL; } +/** + * hdd_enable_power_management() - API to Enable Power Management + * + * API invokes Bus Interface Layer power management functionality + * + * Return: None + */ +static void hdd_enable_power_management(void) +{ + void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + + if (!hif_ctx) { + hdd_err("Bus Interface Context is Invalid"); + return; + } + + hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); +} + +/** + * hdd_disable_power_management() - API to disable Power Management + * + * API disable Bus Interface Layer Power management functionality + * + * Return: None + */ +static void hdd_disable_power_management(void) +{ + void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + + if (!hif_ctx) { + hdd_err("Bus Interface Context is Invalid"); + return; + } + + hif_disable_power_management(hif_ctx); +} + void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx) { void *hif_sc; @@ -3054,8 +3253,8 @@ int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value, } } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax && sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) { - hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d", - sap_config->SapHw_mode, sap_config->channel); + hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d", + sap_config->SapHw_mode, sap_config->chan_freq); return -EIO; } @@ -3092,34 +3291,6 @@ int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate) return set_value; } -#ifdef FEATURE_WLAN_WAPI -/** - * hdd_wapi_security_sta_exist() - return wapi security sta exist or not - * - * This API returns the wapi security station exist or not - * - * Return: true - wapi security station exist - */ -static bool hdd_wapi_security_sta_exist(void) -{ - struct hdd_adapter *adapter = NULL; - struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - - hdd_for_each_adapter(hdd_ctx, adapter) { - if ((adapter->device_mode == QDF_STA_MODE) && - adapter->wapi_info.wapi_mode && - (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN)) - return true; - } - return false; -} -#else -static bool hdd_wapi_security_sta_exist(void) -{ - return false; -} -#endif - #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) @@ -3146,22 +3317,46 @@ static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( */ static bool hdd_is_chan_switch_in_progress(void) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if ((adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) && qdf_atomic_read(&adapter->ch_switch_in_progress)) { hdd_debug("channel switch progress for vdev_id %d", adapter->vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } + hdd_adapter_dev_put_debug(adapter, dbgid); } return false; } +/** + * hdd_is_cac_in_progress() - Check if any SAP connection is performing + * CAC on DFS channel + * + * Return: true, if any of existing SAP is performing CAC + * or else false + */ +static bool hdd_is_cac_in_progress(void) +{ + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + + if (!hdd_ctx) + return false; + + return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS); +} static void hdd_register_policy_manager_callback( struct wlan_objmgr_psoc *psoc) @@ -3176,12 +3371,13 @@ static void hdd_register_policy_manager_callback( hdd_cbacks.get_mode_for_non_connected_vdev = wlan_hdd_get_mode_for_non_connected_vdev; hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode; - hdd_cbacks.hdd_wapi_security_sta_exist = - hdd_wapi_security_sta_exist; hdd_cbacks.hdd_is_chan_switch_in_progress = hdd_is_chan_switch_in_progress; + hdd_cbacks.hdd_is_cac_in_progress = + hdd_is_cac_in_progress; hdd_cbacks.wlan_hdd_set_sap_csa_reason = wlan_hdd_set_sap_csa_reason; + hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = hdd_indicate_active_ndp_cnt; @@ -3240,9 +3436,7 @@ static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) { /* DO NOT REMOVE these checks; for false positives, read above first */ - wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc); - wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc); - wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc); + wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc); /* many adapter resources are not freed by design during SSR */ if (is_ssr) @@ -3282,8 +3476,8 @@ static void hdd_skip_acs_scan_timer_handler(void *data) hdd_debug("ACS Scan result expired. Reset ACS scan skip"); hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; qdf_spin_lock(&hdd_ctx->acs_skip_lock); - qdf_mem_free(hdd_ctx->last_acs_channel_list); - hdd_ctx->last_acs_channel_list = NULL; + qdf_mem_free(hdd_ctx->last_acs_freq_list); + hdd_ctx->last_acs_freq_list = NULL; hdd_ctx->num_of_channels = 0; qdf_spin_unlock(&hdd_ctx->acs_skip_lock); @@ -3317,8 +3511,8 @@ static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) hdd_err("Cannot deallocate ACS Skip timer"); } qdf_spin_lock(&hdd_ctx->acs_skip_lock); - qdf_mem_free(hdd_ctx->last_acs_channel_list); - hdd_ctx->last_acs_channel_list = NULL; + qdf_mem_free(hdd_ctx->last_acs_freq_list); + hdd_ctx->last_acs_freq_list = NULL; hdd_ctx->num_of_channels = 0; qdf_spin_unlock(&hdd_ctx->acs_skip_lock); } @@ -3480,7 +3674,6 @@ static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) */ static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) { - void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); int ret; if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { @@ -3496,7 +3689,7 @@ static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock); if (hdd_ctx->runtime_pm_prevented) { - hif_pm_runtime_put_noidle(hif_ctx, RTPM_ID_QOS_NOTIFY); + pm_runtime_put_noidle(hdd_ctx->parent_dev); hdd_ctx->runtime_pm_prevented = false; } @@ -3515,46 +3708,6 @@ static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) } #endif -/** - * hdd_enable_power_management() - API to Enable Power Management - * - * API invokes Bus Interface Layer power management functionality - * - * Return: None - */ -static void hdd_enable_power_management(struct hdd_context *hdd_ctx) -{ - void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); - - if (!hif_ctx) { - hdd_err("Bus Interface Context is Invalid"); - return; - } - - hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); - hdd_wlan_register_pm_qos_notifier(hdd_ctx); -} - -/** - * hdd_disable_power_management() - API to disable Power Management - * - * API disable Bus Interface Layer Power management functionality - * - * Return: None - */ -static void hdd_disable_power_management(struct hdd_context *hdd_ctx) -{ - void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); - - if (!hif_ctx) { - hdd_err("Bus Interface Context is Invalid"); - return; - } - - hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); - hif_disable_power_management(hif_ctx); -} - /** * hdd_register_notifiers - Register netdev notifiers. * @hdd_ctx: HDD context @@ -3585,8 +3738,14 @@ static int hdd_register_notifiers(struct hdd_context *hdd_ctx) goto unregister_inetaddr_notifier; } + ret = hdd_wlan_register_pm_qos_notifier(hdd_ctx); + if (ret) + goto unregister_nud_notifier; + return 0; +unregister_nud_notifier: + hdd_nud_unregister_netevent_notifier(hdd_ctx); unregister_inetaddr_notifier: unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); unregister_ip6_notifier: @@ -3595,6 +3754,20 @@ static int hdd_register_notifiers(struct hdd_context *hdd_ctx) return ret; } +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI +static inline +void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) +{ + wmi_set_qmi_stats(get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc), + hdd_ctx->config->is_qmi_stats_enabled); +} +#else +static inline +void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) +{ +} +#endif + int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) { int ret = 0; @@ -3638,6 +3811,7 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) } hdd_bus_bandwidth_init(hdd_ctx); + hdd_init_adapter_ops_wq(hdd_ctx); pld_set_fw_log_mode(hdd_ctx->parent_dev, hdd_ctx->config->enable_fw_log); ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid, @@ -3715,6 +3889,8 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) goto psoc_close; } + hdd_set_qmi_stats_enabled(hdd_ctx); + hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); if (hdd_ctx->config->rx_thread_affinity_mask) @@ -3740,6 +3916,8 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) ret = qdf_status_to_os_return(status); goto close; } + /* Set IRQ affinity for WLAN DP and CE IRQS */ + hif_config_irq_set_perf_affinity_hint(hif_ctx); ret = hdd_register_cb(hdd_ctx); if (ret) { @@ -3768,15 +3946,21 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) hdd_register_policy_manager_callback( hdd_ctx->psoc); + /* + * Call this function before hdd_enable_power_management. Since + * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID + * to FW when power save isn't enable. + */ hdd_spectral_register_to_dbr(hdd_ctx); hdd_sysfs_create_driver_root_obj(); hdd_sysfs_create_version_interface(hdd_ctx->psoc); hdd_sysfs_create_powerstats_interface(); + hdd_sysfs_dp_aggregation_create(); hdd_update_hw_sw_info(hdd_ctx); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_enable_power_management(hdd_ctx); + hdd_enable_power_management(); hdd_err("in ftm mode, no need to configure cds modules"); ret = -EINVAL; break; @@ -3788,12 +3972,14 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) goto destroy_driver_sysfs; } - hdd_enable_power_management(hdd_ctx); + hdd_enable_power_management(); hdd_skip_acs_scan_timer_init(hdd_ctx); wlan_hdd_init_tx_rx_histogram(hdd_ctx); + hdd_set_hif_init_phase(hif_ctx, false); + break; default: @@ -3806,11 +3992,14 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) hdd_ctx->driver_status = DRIVER_MODULES_ENABLED; hdd_nofl_debug("Wlan transitioned (now ENABLED)"); + ucfg_ipa_reg_rps_enable_cb(hdd_ctx->pdev, + hdd_adapter_set_rps); hdd_exit(); return 0; destroy_driver_sysfs: + hdd_sysfs_dp_aggregation_destroy(); hdd_sysfs_destroy_powerstats_interface(); hdd_sysfs_destroy_version_interface(); hdd_sysfs_destroy_driver_root_obj(); @@ -3844,6 +4033,7 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) psoc_close: hdd_component_psoc_close(hdd_ctx->psoc); + wlan_global_lmac_if_close(hdd_ctx->psoc); cds_deinit_ini_config(); cds_free: @@ -3853,6 +4043,7 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); hdd_hif_close(hdd_ctx, hif_ctx); power_down: + hdd_deinit_adapter_ops_wq(hdd_ctx); hdd_bus_bandwidth_deinit(hdd_ctx); if (!reinit && !unint) pld_power_off(qdf_dev->dev); @@ -4094,19 +4285,11 @@ static int __hdd_stop(struct net_device *dev) WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); - if (adapter->device_mode == QDF_STA_MODE) { + if (adapter->device_mode == QDF_STA_MODE) hdd_lpass_notify_stop(hdd_ctx); - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) - hdd_close_monitor_interface(hdd_ctx); - } - - if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && - adapter->vdev) { - ucfg_pkt_capture_deregister_callbacks(adapter->vdev); - hdd_objmgr_put_vdev(adapter->vdev); - adapter->vdev = NULL; - } + if (wlan_hdd_is_session_type_monitor(adapter->device_mode)) + hdd_reset_pktcapture_cb(OL_TXRX_PDEV_ID); /* * NAN data interface is different in some sense. The traffic on NDI is @@ -4307,9 +4490,9 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr) if (adapter_temp) { if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) return 0; - hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_STR, + hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, adapter_temp->dev->name, - QDF_MAC_ADDR_ARRAY(mac_addr.bytes)); + QDF_MAC_ADDR_REF(mac_addr.bytes)); return -EINVAL; } @@ -4317,9 +4500,9 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr) if (QDF_IS_STATUS_ERROR(qdf_ret_status)) return -EINVAL; - hdd_nofl_debug("Changing MAC to " QDF_MAC_ADDR_STR - " of the interface %s ", - QDF_MAC_ADDR_ARRAY(mac_addr.bytes), dev->name); + hdd_nofl_debug("Changing MAC to " + QDF_MAC_ADDR_FMT " of the interface %s ", + QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); @@ -4364,8 +4547,8 @@ static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx) if (i < 0 || i >= hdd_ctx->num_derived_addr) return NULL; qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask); - hdd_nofl_debug("Assigning MAC from derived list" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes)); + hdd_nofl_debug("Assigning MAC from derived list" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); /* Copy the mac in dynamic mac list at first free position */ for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { @@ -4395,8 +4578,8 @@ static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx) if (i < 0 || i >= hdd_ctx->num_provisioned_addr) return NULL; qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask); - hdd_debug("Assigning MAC from provisioned list" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdd_ctx->provisioned_mac_addr[i].bytes)); + hdd_debug("Assigning MAC from provisioned list" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes)); /* Copy the mac in dynamic mac list at first free position */ for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { @@ -4457,15 +4640,15 @@ void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, provisioned_intf_addr_mask); hdd_debug("Releasing MAC from provisioned list"); hdd_debug( - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(releaseAddr)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(releaseAddr)); } else { qdf_atomic_clear_bit( mac_pos_in_mask, &hdd_ctx-> derived_intf_addr_mask); hdd_debug("Releasing MAC from derived list"); - hdd_debug(QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(releaseAddr)); + hdd_debug(QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(releaseAddr)); } qdf_zero_macaddr(&hdd_ctx-> dynamic_mac_list[i].dynamic_mac); @@ -4477,8 +4660,8 @@ void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, } if (i == QDF_MAX_CONCURRENCY_PERSONA) - hdd_err("Releasing non existing MAC" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(releaseAddr)); + hdd_err("Releasing non existing MAC" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(releaseAddr)); } /** @@ -4552,8 +4735,8 @@ static void __hdd_set_multicast_list(struct net_device *dev) 0, ETH_ALEN); memcpy(&(mc_list_request->mc_addr[i].bytes), ha->addr, ETH_ALEN); - hdd_debug("mlist[%d] = %pM", i, - mc_list_request->mc_addr[i].bytes); + hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes)); i++; } } @@ -4600,66 +4783,261 @@ static const struct ethtool_ops wlan_ethtool_ops = { }; #endif -static const struct net_device_ops wlan_drv_ops = { - .ndo_open = hdd_open, - .ndo_stop = hdd_stop, - .ndo_uninit = hdd_uninit, - .ndo_start_xmit = hdd_hard_start_xmit, - .ndo_tx_timeout = hdd_tx_timeout, - .ndo_get_stats = hdd_get_stats, - .ndo_do_ioctl = hdd_ioctl, - .ndo_set_mac_address = hdd_set_mac_address, - .ndo_select_queue = hdd_select_queue, - .ndo_set_rx_mode = hdd_set_multicast_list, -}; - -#ifdef FEATURE_MONITOR_MODE_SUPPORT -/* Monitor mode net_device_ops, doesnot Tx and most of operations. */ -static const struct net_device_ops wlan_mon_drv_ops = { - .ndo_open = hdd_mon_open, - .ndo_stop = hdd_stop, - .ndo_get_stats = hdd_get_stats, -}; - -#ifdef WLAN_FEATURE_TSF_PTP /** - * hdd_set_station_ops() - update net_device ops for monitor mode - * @dev: Handle to struct net_device to be updated. - * Return: None + * __hdd_fix_features - Adjust the feature flags needed to be updated + * @net_dev: Handle to net_device + * @features: Currently enabled feature flags + * + * Return: Adjusted feature flags on success, old feature on failure */ -void hdd_set_station_ops(struct net_device *dev) +static netdev_features_t __hdd_fix_features(struct net_device *net_dev, + netdev_features_t features) { - if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { - dev->netdev_ops = &wlan_mon_drv_ops; - } else { - dev->netdev_ops = &wlan_drv_ops; - dev->ethtool_ops = &wlan_ethtool_ops; + netdev_features_t feature_change_req = features; + netdev_features_t feature_tso_csum; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); + + if (!adapter->handle_feature_update) { + hdd_debug("Not triggered by hdd_netdev_update_features"); + return features; } -} -#else -void hdd_set_station_ops(struct net_device *dev) -{ - if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) - dev->netdev_ops = &wlan_mon_drv_ops; + + feature_tso_csum = hdd_get_tso_csum_feature_flags(); + if (hdd_is_legacy_connection(adapter)) + /* Disable checksum and TSO */ + feature_change_req &= ~feature_tso_csum; else - dev->netdev_ops = &wlan_drv_ops; -} + /* Enable checksum and TSO */ + feature_change_req |= feature_tso_csum; -#endif -#else -#ifdef WLAN_FEATURE_TSF_PTP -void hdd_set_station_ops(struct net_device *dev) -{ - dev->netdev_ops = &wlan_drv_ops; - dev->ethtool_ops = &wlan_ethtool_ops; + hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx", + adapter->device_mode, net_dev->features, + feature_change_req); + + return feature_change_req; } -#else -void hdd_set_station_ops(struct net_device *dev) + +/** + * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR + * @net_dev: Pointer to net_device structure + * @features: Updated features set + * + * Adjusts the feature request, do not update the device yet. + * + * Return: updated feature for success, incoming feature as is on failure + */ +static netdev_features_t hdd_fix_features(struct net_device *net_dev, + netdev_features_t features) { - dev->netdev_ops = &wlan_drv_ops; -} -#endif -#endif + int errno; + int changed_features = features; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (errno) + return features; + + changed_features = __hdd_fix_features(net_dev, features); + + osif_vdev_sync_op_stop(vdev_sync); + + return changed_features; +} + +/** + * __hdd_set_features - Update device config for resultant change in feature + * @net_dev: Handle to net_device + * @features: Existing + requested feature after resolving the dependency + * + * Return: 0 on success, non zero error on failure + */ +static int __hdd_set_features(struct net_device *net_dev, + netdev_features_t features) +{ + struct hdd_adapter *adapter = netdev_priv(net_dev); + cdp_config_param_type vdev_param; + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (!adapter->handle_feature_update) { + hdd_debug("Not triggered by hdd_netdev_update_features"); + return 0; + } + + if (!soc) { + hdd_err("soc handle is NULL"); + return 0; + } + + hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx", + adapter->device_mode, adapter->vdev_id, net_dev->features, + features); + + if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) + vdev_param.cdp_enable_tx_checksum = true; + else + vdev_param.cdp_enable_tx_checksum = false; + + if (cdp_txrx_set_vdev_param(soc, adapter->vdev_id, CDP_ENABLE_CSUM, + vdev_param)) + hdd_debug("Failed to set DP vdev params"); + + return 0; +} + +/** + * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR + * @net_dev: Pointer to net_device structure + * @features: Updated features set + * + * Is called to update device configurations for changed features. + * + * Return: 0 for success, non-zero for failure + */ +static int hdd_set_features(struct net_device *net_dev, + netdev_features_t features) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); + if (errno) { + /* + * Only invoke from netdev_feature_update_work expected, + * which is from CLD inside. + * Ignore others from upper stack during loading phase, + * and return success to avoid failure print from kernel. + */ + hdd_debug("VDEV in transition, ignore set_features"); + return 0; + } + + errno = __hdd_set_features(net_dev, features); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + +#define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT 10 +#define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS 20 + +void hdd_netdev_update_features(struct hdd_adapter *adapter) +{ + struct net_device *net_dev = adapter->dev; + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + bool request_feature_update = false; + int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT; + + if (!soc) { + hdd_err("soc handle is NULL"); + return; + } + + if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) + return; + + switch (adapter->device_mode) { + case QDF_STA_MODE: + if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) + request_feature_update = true; + break; + default: + break; + } + + if (request_feature_update) { + hdd_debug("Update net_dev features for device mode %d", + adapter->device_mode); + while (!adapter->delete_in_progress) { + if (rtnl_trylock()) { + adapter->handle_feature_update = true; + netdev_update_features(net_dev); + adapter->handle_feature_update = false; + rtnl_unlock(); + break; + } + + if (wait_count--) { + qdf_sleep( + HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS); + } else { + /* + * We have failed to updated the netdev + * features for very long, so enable the queues + * now. The impact of not being able to update + * the netdev feature is lower TPUT when + * switching from legacy to non-legacy mode. + */ + hdd_err("Failed to update netdev features for device mode %d", + adapter->device_mode); + break; + } + } + } +} + +static const struct net_device_ops wlan_drv_ops = { + .ndo_open = hdd_open, + .ndo_stop = hdd_stop, + .ndo_uninit = hdd_uninit, + .ndo_start_xmit = hdd_hard_start_xmit, + .ndo_fix_features = hdd_fix_features, + .ndo_set_features = hdd_set_features, + .ndo_tx_timeout = hdd_tx_timeout, + .ndo_get_stats = hdd_get_stats, + .ndo_do_ioctl = hdd_ioctl, + .ndo_set_mac_address = hdd_set_mac_address, + .ndo_select_queue = hdd_select_queue, + .ndo_set_rx_mode = hdd_set_multicast_list, +}; + +#ifdef FEATURE_MONITOR_MODE_SUPPORT +/* Monitor mode net_device_ops, doesnot Tx and most of operations. */ +static const struct net_device_ops wlan_mon_drv_ops = { + .ndo_open = hdd_mon_open, + .ndo_stop = hdd_stop, + .ndo_get_stats = hdd_get_stats, +}; + +#ifdef WLAN_FEATURE_TSF_PTP +/** + * hdd_set_station_ops() - update net_device ops for monitor mode + * @dev: Handle to struct net_device to be updated. + * Return: None + */ +void hdd_set_station_ops(struct net_device *dev) +{ + if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { + dev->netdev_ops = &wlan_mon_drv_ops; + } else { + dev->netdev_ops = &wlan_drv_ops; + dev->ethtool_ops = &wlan_ethtool_ops; + } +} +#else +void hdd_set_station_ops(struct net_device *dev) +{ + if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) + dev->netdev_ops = &wlan_mon_drv_ops; + else + dev->netdev_ops = &wlan_drv_ops; +} + +#endif +#else +#ifdef WLAN_FEATURE_TSF_PTP +void hdd_set_station_ops(struct net_device *dev) +{ + dev->netdev_ops = &wlan_drv_ops; + dev->ethtool_ops = &wlan_ethtool_ops; +} +#else +void hdd_set_station_ops(struct net_device *dev) +{ + dev->netdev_ops = &wlan_drv_ops; +} +#endif +#endif #ifdef WLAN_FEATURE_PKT_CAPTURE /* Packet Capture mode net_device_ops, doesnot Tx and most of operations. */ @@ -4700,6 +5078,7 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, struct hdd_adapter *adapter; struct hdd_station_ctx *sta_ctx; QDF_STATUS qdf_status; + uint8_t latency_level; /* cfg80211 initialization and registration */ dev = alloc_netdev_mq(sizeof(*adapter), name, @@ -4720,9 +5099,8 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, qdf_mem_zero(adapter, sizeof(*adapter)); sta_ctx = &adapter->session.station; - qdf_mem_set(sta_ctx->conn_info.sta_id, - sizeof(sta_ctx->conn_info.sta_id), - HDD_WLAN_INVALID_STA_ID); + qdf_mem_zero(sta_ctx->conn_info.peer_macaddr, + sizeof(sta_ctx->conn_info.peer_macaddr)); adapter->dev = dev; adapter->hdd_ctx = hdd_ctx; adapter->magic = WLAN_HDD_ADAPTER_MAGIC; @@ -4732,19 +5110,22 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, if (QDF_IS_STATUS_ERROR(qdf_status)) goto free_net_dev; - init_completion(&adapter->vdev_destroy_event); - qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type); if (QDF_IS_STATUS_ERROR(qdf_status)) { hdd_err_rl("create monitor mode vdve up event failed"); goto free_net_dev; } + init_completion(&adapter->vdev_destroy_event); + adapter->offloads_configured = false; adapter->is_link_up_service_needed = false; adapter->disconnection_in_progress = false; adapter->send_mode_change = true; + /* Cache station count initialize to zero */ + qdf_atomic_init(&adapter->cache_sta_count); + /* Init the net_device structure */ strlcpy(dev->name, name, IFNAMSIZ); @@ -4762,6 +5143,13 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; adapter->wdev.wiphy = hdd_ctx->wiphy; adapter->wdev.netdev = dev; + qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + hdd_debug("Can't get latency level"); + latency_level = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + } + adapter->latency_level = latency_level; /* set dev's parent to underlying device */ SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); @@ -4818,33 +5206,6 @@ static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_ return QDF_STATUS_SUCCESS; } -QDF_STATUS hdd_sme_open_session_callback(uint8_t vdev_id, - QDF_STATUS qdf_status) -{ - struct hdd_adapter *adapter; - struct hdd_context *hdd_ctx; - - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (!hdd_ctx) { - hdd_err("Invalid HDD_CTX"); - return QDF_STATUS_E_FAILURE; - } - - adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); - if (!adapter) { - hdd_err("NULL adapter for %d", vdev_id); - return QDF_STATUS_E_INVAL; - } - - if (qdf_status == QDF_STATUS_SUCCESS) - set_bit(SME_SESSION_OPENED, &adapter->event_flags); - - qdf_event_set(&adapter->qdf_session_open_event); - hdd_debug("session %d opened", adapter->vdev_id); - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) { struct hdd_adapter *adapter; @@ -4867,13 +5228,6 @@ QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) return QDF_STATUS_NOT_INITIALIZED; } - /* - * For NAN Data interface, the close session results in the final - * indication to the userspace - */ - if (adapter->device_mode == QDF_NDI_MODE) - hdd_ndp_session_end_handler(adapter); - clear_bit(SME_SESSION_OPENED, &adapter->event_flags); /* @@ -4920,21 +5274,6 @@ int hdd_vdev_ready(struct hdd_adapter *adapter) return qdf_status_to_os_return(status); } -static void hdd_cleanup_cached_sta_info(struct hdd_adapter *adapter) -{ - uint16_t sta_id; - struct wlan_ies *ies; - - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - ies = &adapter->cache_sta_info[sta_id].assoc_req_ies; - if (ies->data && ies->len) { - qdf_mem_free(ies->data); - ies->data = NULL; - ies->len = 0; - } - } -} - int hdd_vdev_destroy(struct hdd_adapter *adapter) { QDF_STATUS status; @@ -4963,7 +5302,8 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), NULL) == 1) || - !policy_mgr_get_connection_count(hdd_ctx->psoc)) + (!policy_mgr_get_connection_count(hdd_ctx->psoc) && + !hdd_is_any_sta_connecting(hdd_ctx))) policy_mgr_check_and_stop_opportunistic_timer(hdd_ctx->psoc, adapter->vdev_id); @@ -4973,15 +5313,18 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) ucfg_pmo_del_wow_pattern(vdev); status = ucfg_reg_11d_vdev_delete_update(vdev); - hdd_cleanup_cached_sta_info(adapter); ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN); + wlan_hdd_scan_abort(adapter); hdd_objmgr_put_vdev(vdev); + /* Disable serialization for vdev before sending vdev delete */ + wlan_ser_vdev_queue_disable(adapter->vdev); + /* close sme session (destroy vdev in firmware via legacy API) */ INIT_COMPLETION(adapter->vdev_destroy_event); - status = sme_close_session(hdd_ctx->mac_handle, adapter->vdev_id); + status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("failed to close sme session; status:%d", status); + hdd_err("failed to delete vdev; status:%d", status); goto release_vdev; } @@ -4992,11 +5335,8 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) if (rc) { clear_bit(SME_SESSION_OPENED, &adapter->event_flags); - if (adapter->device_mode == QDF_NDI_MODE) - hdd_ndp_session_end_handler(adapter); - if (status == QDF_STATUS_E_TIMEOUT) { - hdd_err("timed out waiting for sme close session"); + hdd_err("timed out waiting for sme vdev delete"); sme_cleanup_session(hdd_ctx->mac_handle, vdev_id); } } @@ -5015,34 +5355,6 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) return 0; } -static int hdd_set_sme_session_param(struct hdd_adapter *adapter, - struct sme_session_params *session_param, - csr_roam_complete_cb callback, - void *callback_ctx) -{ - uint32_t type; - uint32_t sub_type; - QDF_STATUS status; - - /* determine vdev (sub)type */ - status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("failed to get vdev type: %d", status); - return qdf_status_to_os_return(status); - } - session_param->sme_session_id = adapter->vdev_id; - session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr; - session_param->type_of_persona = type; - session_param->subtype_of_persona = sub_type; - session_param->session_open_cb = hdd_sme_open_session_callback; - session_param->session_close_cb = hdd_sme_close_session_callback; - session_param->callback = callback; - session_param->callback_ctx = callback_ctx; - hdd_set_sme_monitor_mode_cb(adapter->device_mode, session_param); - - return 0; -} - void hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter) { @@ -5085,73 +5397,60 @@ bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter) return 0; } -int hdd_vdev_create(struct hdd_adapter *adapter, - csr_roam_complete_cb callback, void *ctx) +int hdd_vdev_create(struct hdd_adapter *adapter) { QDF_STATUS status; int errno; bool bval; struct hdd_context *hdd_ctx; - struct sme_session_params sme_session_params = {0}; struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct wlan_vdev_create_params vdev_params = {0}; + uint16_t max_peer_count; hdd_nofl_debug("creating new vdev"); /* do vdev create via objmgr */ hdd_ctx = WLAN_HDD_GET_CTX(adapter); - errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter); - if (errno) { - hdd_err("failed to create objmgr vdev: %d", errno); - return errno; - } - - /* Open a SME session (prepare vdev in firmware via legacy API) */ - status = qdf_event_reset(&adapter->qdf_session_open_event); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("failed to reinit session open event"); - errno = qdf_status_to_os_return(status); - goto objmgr_vdev_destroy_procedure; - } - errno = hdd_set_sme_session_param(adapter, &sme_session_params, - callback, ctx); - if (errno) { - hdd_err("failed to populating SME params"); - goto objmgr_vdev_destroy_procedure; - } - status = sme_open_session(hdd_ctx->mac_handle, &sme_session_params); + status = sme_check_for_duplicate_session(hdd_ctx->mac_handle, + adapter->mac_addr.bytes); if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("failed to open sme session: %d", status); + hdd_err("Duplicate session is existing with same mac address"); errno = qdf_status_to_os_return(status); - goto objmgr_vdev_destroy_procedure; + return errno; } - /* block on a completion variable until sme session is opened */ - status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event, - SME_CMD_VDEV_CREATE_DELETE_TIMEOUT); - if (QDF_STATUS_SUCCESS != status) { - if (adapter->qdf_session_open_event.force_set) - /* - * SSR/PDR has caused shutdown, which has forcefully - * set the event. - */ - hdd_err("Session open event forcefully set"); + vdev_params.opmode = adapter->device_mode; + qdf_mem_copy(vdev_params.macaddr, + adapter->mac_addr.bytes, + QDF_NET_MAC_ADDR_MAX_LEN); - else if (QDF_STATUS_E_TIMEOUT == status) - hdd_err("Session failed to open within timeout period"); - else - hdd_err("Failed to wait for session open event(status-%d)", - status); - errno = -ETIMEDOUT; - set_bit(SME_SESSION_OPENED, &adapter->event_flags); - goto hdd_vdev_destroy_procedure; + vdev_params.size_vdev_priv = sizeof(*osif_priv); + vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); + if (!vdev) { + hdd_err("failed to create vdev"); + return -EINVAL; } - if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) { - hdd_err("Session failed to open due to vdev create failure"); - errno = -EINVAL; - goto objmgr_vdev_destroy_procedure; + /* Initialize the vdev OS private structure*/ + osif_priv = wlan_vdev_get_ospriv(vdev); + osif_priv->wdev = adapter->dev->ieee80211_ptr; + osif_priv->legacy_osif_priv = adapter; + + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != + QDF_STATUS_SUCCESS) { + errno = QDF_STATUS_E_INVAL; + sme_vdev_delete(hdd_ctx->mac_handle, vdev); + wlan_objmgr_vdev_obj_delete(vdev); + return -EINVAL; } + set_bit(SME_SESSION_OPENED, &adapter->event_flags); + qdf_spin_lock_bh(&adapter->vdev_lock); + adapter->vdev_id = wlan_vdev_get_id(vdev); + adapter->vdev = vdev; + qdf_spin_unlock_bh(&adapter->vdev_lock); + /* firmware ready for component communication, raise vdev_ready event */ errno = hdd_vdev_ready(adapter); if (errno) { @@ -5181,7 +5480,12 @@ int hdd_vdev_create(struct hdd_adapter *adapter, vdev = hdd_objmgr_get_vdev(adapter); if (!vdev) goto hdd_vdev_destroy_procedure; - wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT); + + /* Max peer can be tdls peers + self peer + bss peer */ + max_peer_count = cfg_tdls_get_max_peer_count(hdd_ctx->psoc); + max_peer_count += 2; + wlan_vdev_set_max_peer_count(vdev, max_peer_count); + hdd_objmgr_put_vdev(vdev); } @@ -5202,16 +5506,6 @@ int hdd_vdev_create(struct hdd_adapter *adapter, return 0; - /* - * Due to legacy constraints, we need to destroy in the same order as - * create. So, split error handling into 2 cases to accommodate. - */ - -objmgr_vdev_destroy_procedure: - QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter)); - - return errno; - hdd_vdev_destroy_procedure: QDF_BUG(!hdd_vdev_destroy(adapter)); @@ -5226,6 +5520,7 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) int ret_val; mac_handle_t mac_handle; bool bval = false; + uint8_t enable_sifs_burst = 0; uint32_t fine_time_meas_cap = 0, roam_triggers; hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -5236,7 +5531,8 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) hdd_err("unable to get vht_enable2x2"); sme_set_pdev_ht_vht_ies(mac_handle, bval); - sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id); + sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id, + adapter->device_mode); hdd_roam_profile_init(adapter); hdd_register_wext(adapter->dev); @@ -5244,16 +5540,11 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected); sme_roam_reset_configs(mac_handle, adapter->vdev_id); - qdf_mem_set(sta_ctx->conn_info.sta_id, - sizeof(sta_ctx->conn_info.sta_id), - HDD_WLAN_INVALID_STA_ID); - /* set fast roaming capability in sme session */ status = sme_config_fast_roaming(mac_handle, adapter->vdev_id, true); - /* Set the default operation channel */ - sta_ctx->conn_info.channel = - hdd_ctx->config->operating_channel; + /* Set the default operation channel freq*/ + sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq; /* Make the default Auth Type as OPEN */ sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; @@ -5276,29 +5567,19 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) set_bit(WMM_INIT_DONE, &adapter->event_flags); + status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("Failed to get sifs burst value, use default"); + ret_val = sme_cli_set_command(adapter->vdev_id, WMI_PDEV_PARAM_BURST_ENABLE, - HDD_ENABLE_SIFS_BURST_DEFAULT, + enable_sifs_burst, PDEV_CMD); if (ret_val) hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val); - /* - * In case of USB tethering, LRO is disabled. If SSR happened - * during that time, then as part of SSR init, do not enable - * the LRO again. Keep the LRO state same as before SSR. - */ - if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), - cfg_dp_lro_enable) && - !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) - adapter->dev->features |= NETIF_F_LRO; - - if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), - cfg_dp_enable_ip_tcp_udp_checksum_offload)) - adapter->dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - adapter->dev->features |= NETIF_F_RXCSUM; - hdd_set_tso_flags(hdd_ctx, adapter->dev); + hdd_set_netdev_flags(adapter); /* rcpi info initialization */ qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); @@ -5334,6 +5615,102 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter) return status; } +static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid) +{ + static const char *strings[] = { + "NET_DEV_HOLD_ID_RESERVED", + "NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS", + "NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER", + "NET_DEV_HOLD_GET_SAP_OPERATING_BAND", + "NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL", + "NET_DEV_HOLD_IS_ANY_STA_CONNECTING", + "NET_DEV_HOLD_SAP_DESTROY_CTX_ALL", + "NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER", + "NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO", + "NET_DEV_HOLD_SET_RPS_CPU_MASK", + "NET_DEV_HOLD_DFS_INDICATE_RADAR", + "NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED", + "NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS", + "NET_DEV_HOLD_STA_DESTROY_CTX_ALL", + "NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR", + "NET_DEV_HOLD_DEINIT_ALL_ADAPTERS", + "NET_DEV_HOLD_STOP_ALL_ADAPTERS", + "NET_DEV_HOLD_RESET_ALL_ADAPTERS", + "NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN", + "NET_DEV_HOLD_START_ALL_ADAPTERS", + "NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR", + "NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR", + "NET_DEV_HOLD_GET_ADAPTER_BY_VDEV", + "NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE", + "NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME", + "NET_DEV_HOLD_GET_ADAPTER", + "NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ", + "NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS", + "NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS", + "NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS", + "NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER", + "NET_DEV_HOLD_CLEAR_RPS_CPU_MASK", + "NET_DEV_HOLD_BUS_BW_WORK_HANDLER", + "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT", + "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY", + "NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY", + "NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP", + "NET_DEV_HOLD_INDICATE_MGMT_FRAME", + "NET_DEV_HOLD_STATE_INFO_DUMP", + "NET_DEV_HOLD_DISABLE_ROAMING", + "NET_DEV_HOLD_ENABLE_ROAMING", + "NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE", + "NET_DEV_HOLD_GET_CON_SAP_ADAPTER", + "NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED", + "NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS", + "NET_DEV_HOLD_DEL_P2P_INTERFACE", + "NET_DEV_HOLD_IS_NDP_ALLOWED", + "NET_DEV_HOLD_NDI_OPEN", + "NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG", + "NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY", + "NET_DEV_HOLD_SUSPEND_WLAN", + "NET_DEV_HOLD_RESUME_WLAN", + "NET_DEV_HOLD_SSR_RESTART_SAP", + "NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES", + "NET_DEV_HOLD_CFG80211_SUSPEND_WLAN", + "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA", + "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP", + "NET_DEV_HOLD_CACHE_STATION_STATS_CB", + "NET_DEV_HOLD_DISPLAY_TXRX_STATS", + "NET_DEV_HOLD_ID_MAX"}; + int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); + + if (dbgid >= num_dbg_strings) { + char *ret = ""; + + hdd_err("Debug string not found for debug id %d", dbgid); + return ret; + } + + return (char *)strings[dbgid]; +} + +static void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter) +{ + int i, id; + + for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) { + for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) { + if (!qdf_atomic_read( + &adapter->net_dev_hold_ref_count[id])) + break; + hdd_info("net_dev held for debug id %s", + net_dev_ref_debug_string_from_id(id)); + qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS); + } + if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) { + hdd_err("net_dev hold reference leak detected for debug id: %s", + net_dev_ref_debug_string_from_id(id)); + QDF_BUG(0); + } + } +} + /** * hdd_deinit_station_mode() - De-initialize the station adapter * @hdd_ctx: global hdd context @@ -5408,6 +5785,36 @@ void hdd_deinit_adapter(struct hdd_context *hdd_ctx, hdd_exit(); } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ + defined(WLAN_FEATURE_11AX) +void hdd_cleanup_conn_info(struct hdd_adapter *adapter) +{ + struct hdd_station_ctx *hdd_sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + if (!hdd_sta_ctx) + return; + + if (hdd_sta_ctx->cache_conn_info.he_operation) { + qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); + hdd_sta_ctx->cache_conn_info.he_operation = NULL; + } +} + +void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter, *next_adapter = NULL; + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_STA_DESTROY_CTX_ALL) { + if (adapter->device_mode == QDF_STA_MODE) + hdd_cleanup_conn_info(adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_STA_DESTROY_CTX_ALL); + } +} +#endif + static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, bool rtnl_held) @@ -5422,10 +5829,13 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, } hdd_nud_deinit_tracking(adapter); + hdd_mic_deinit_work(adapter); qdf_mutex_destroy(&adapter->disconnection_status_lock); hdd_periodic_sta_stats_mutex_destroy(adapter); hdd_apf_context_destroy(adapter); qdf_spinlock_destroy(&adapter->vdev_lock); + hdd_sta_info_deinit(&adapter->sta_info_list); + hdd_sta_info_deinit(&adapter->cache_sta_info_list); wlan_hdd_debugfs_csr_deinit(adapter); if (adapter->device_mode == QDF_STA_MODE) @@ -5459,13 +5869,20 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (!qdf_mem_cmp(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr))) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return QDF_STATUS_E_FAILURE; } + hdd_adapter_dev_put_debug(adapter, dbgid); } return QDF_STATUS_SUCCESS; @@ -5570,11 +5987,6 @@ static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; QDF_STATUS status; - if (!hdd_ctx) { - hdd_err("hdd_ctx is invalid"); - goto err; - } - if (!adapter) { hdd_err("adapter is invalid"); goto err; @@ -5654,6 +6066,16 @@ static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) goto err; + coex_cfg_params.config_type = + WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; + coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan; + + status = sme_send_coex_config_cmd(&coex_cfg_params); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to send coex BT sco allow wlan 2g scan"); + goto err; + } + return 0; err: return -EINVAL; @@ -5676,7 +6098,7 @@ int hdd_set_fw_params(struct hdd_adapter *adapter) QDF_STATUS status; struct hdd_context *hdd_ctx; bool bval = false; - uint8_t enable_tx_sch_delay, dfs_chan_ageout_time; + uint8_t enable_tx_sch_delay; uint32_t dtim_sel_diversity, enable_secondary_rate; bool sap_xlna_bypass; @@ -5751,16 +6173,6 @@ int hdd_set_fw_params(struct hdd_adapter *adapter) goto error; } - wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc, - &dfs_chan_ageout_time); - ret = sme_cli_set_command(adapter->vdev_id, - WMI_PDEV_PARAM_SET_DFS_CHAN_AGEOUT_TIME, - dfs_chan_ageout_time, PDEV_CMD); - if (ret) { - hdd_err("Failed to set DFS_CHAN_AGEOUT_TIME"); - goto error; - } - if (adapter->device_mode == QDF_STA_MODE) { status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc, &upper_brssi_thresh); @@ -5917,7 +6329,7 @@ static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx, */ WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr); hdd_debug("locally administered bit reset in sta mode: " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_addr)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); } static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) @@ -5934,6 +6346,25 @@ static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) osif_vdev_sync_op_stop(vdev_sync); } +static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx, + enum QDF_OPMODE mode) +{ + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; + u8 intf_count = 0; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_GET_MODE_SPECIFIC_INTERFACE_COUNT; + + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->device_mode == mode) + intf_count++; + + hdd_adapter_dev_put_debug(adapter, dbgid); + } + return intf_count; +} + /** * hdd_open_adapter() - open and setup the hdd adatper * @hdd_ctx: global hdd context @@ -5956,7 +6387,9 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio { struct net_device *ndev = NULL; struct hdd_adapter *adapter = NULL; + u8 intf_count = 0; QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t i; if (hdd_ctx->current_intf_count >= WLAN_MAX_VDEVS) { /* @@ -5977,9 +6410,9 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); if (QDF_STATUS_E_FAILURE == status) { - hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR + hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT " already exists", - QDF_MAC_ADDR_ARRAY(mac_addr)); + QDF_MAC_ADDR_REF(mac_addr)); return NULL; } @@ -5995,12 +6428,24 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); if (QDF_STATUS_E_FAILURE == status) { - hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR + hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT " already exists", - QDF_MAC_ADDR_ARRAY(mac_addr)); + QDF_MAC_ADDR_REF(mac_addr)); return NULL; } } + /* Check for max no of supported VDEVs before creating + * another one. + */ + intf_count = hdd_get_mode_specific_interface_count( + hdd_ctx, + session_type); + if (CFG_TGT_DEFAULT_MAX_STA_VDEVS && + (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS)) { + hdd_err("Max limit reached sta vdev-current %d max %d", + intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS); + return NULL; + } /* fall through */ case QDF_P2P_CLIENT_MODE: @@ -6061,6 +6506,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio WLAN_CONTROL_PATH); hdd_nud_init_tracking(adapter); + hdd_mic_init_work(adapter); + if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_DEVICE_MODE) hdd_sysfs_create_adapter_root_obj(adapter); @@ -6097,6 +6544,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); + hdd_mic_init_work(adapter); + /* * Workqueue which gets scheduled in IPv4 notification * callback @@ -6112,6 +6561,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio INIT_WORK(&adapter->ipv6_notifier_work, hdd_ipv6_notifier_work_queue); #endif + break; case QDF_FTM_MODE: adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, @@ -6135,6 +6585,9 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); + + hdd_mic_init_work(adapter); + break; default: hdd_err("Invalid session type %d", session_type); @@ -6142,7 +6595,13 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio return NULL; } + status = hdd_adapter_feature_update_work_init(adapter); + if (QDF_IS_STATUS_ERROR(status)) + goto err_cleanup_adapter; + + adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; qdf_spinlock_create(&adapter->vdev_lock); + qdf_atomic_init(&hdd_ctx->num_latency_critical_clients); hdd_init_completion(adapter); INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); @@ -6152,41 +6611,36 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio qdf_mutex_create(&adapter->blocked_scan_request_q_lock); qdf_event_create(&adapter->acs_complete_event); qdf_event_create(&adapter->peer_cleanup_done); + hdd_sta_info_init(&adapter->sta_info_list); + hdd_sta_info_init(&adapter->cache_sta_info_list); + qdf_atomic_init(&adapter->gro_disallowed); - if (QDF_STATUS_SUCCESS == status) { - /* Add it to the hdd's session list. */ - status = hdd_add_adapter_back(hdd_ctx, adapter); - } + for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++) + qdf_atomic_init( + &adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]); - if (QDF_STATUS_SUCCESS != status) { - if (adapter) { - hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); - adapter = NULL; - } + /* Add it to the hdd's session list. */ + status = hdd_add_adapter_back(hdd_ctx, adapter); + if (QDF_STATUS_SUCCESS != status) + goto err_destroy_adapter_features_update_work; - return NULL; - } hdd_apf_context_init(adapter); - if (QDF_STATUS_SUCCESS == status) { - policy_mgr_set_concurrency_mode(hdd_ctx->psoc, - session_type); + policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type); - /* Adapter successfully added. Increment the vdev count */ - hdd_ctx->current_intf_count++; + /* Adapter successfully added. Increment the vdev count */ + hdd_ctx->current_intf_count++; - hdd_debug("current_intf_count=%d", - hdd_ctx->current_intf_count); + hdd_debug("current_intf_count=%d", hdd_ctx->current_intf_count); - hdd_check_and_restart_sap_with_non_dfs_acs(); - } + hdd_check_and_restart_sap_with_non_dfs_acs(); if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter)) hdd_err("Interface %s wow debug_fs init failed", netdev_name(adapter->dev)); hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev), - session_type); + session_type); if (adapter->device_mode == QDF_STA_MODE) wlan_hdd_debugfs_csr_init(adapter); @@ -6195,9 +6649,16 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio return adapter; -err_free_netdev: - wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); +err_destroy_adapter_features_update_work: + hdd_adapter_feature_update_work_deinit(adapter); + +err_cleanup_adapter: + if (adapter) { + hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); + adapter = NULL; + } +err_free_netdev: if (ndev) free_netdev(ndev); @@ -6213,7 +6674,7 @@ static void __hdd_close_adapter(struct hdd_context *hdd_ctx, policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); qdf_event_destroy(&adapter->acs_complete_event); qdf_event_destroy(&adapter->peer_cleanup_done); - + hdd_adapter_feature_update_work_deinit(adapter); hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); if (hdd_ctx->current_intf_count != 0) @@ -6230,6 +6691,7 @@ void hdd_close_adapter(struct hdd_context *hdd_ctx, */ hdd_bus_bw_compute_timer_stop(hdd_ctx); + hdd_check_for_net_dev_ref_leak(adapter); hdd_remove_adapter(hdd_ctx, adapter); __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); @@ -6244,8 +6706,10 @@ void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) hdd_enter(); - while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx, - &adapter))) { + while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter( + hdd_ctx, &adapter))) { + hdd_check_for_net_dev_ref_leak(adapter); + hdd_remove_front_adapter(hdd_ctx, &adapter); vdev_sync = osif_vdev_sync_unregister(adapter->dev); if (vdev_sync) osif_vdev_sync_wait_for_ops(vdev_sync); @@ -6295,7 +6759,7 @@ void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter) } qdf_copy_macaddr(&update_ie.bssid, bssid); - update_ie.smeSessionId = adapter->vdev_id; + update_ie.vdev_id = adapter->vdev_id; update_ie.ieBufferlength = 0; update_ie.pAdditionIEBuffer = NULL; update_ie.append = true; @@ -6349,6 +6813,36 @@ hdd_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) hdd_debug("peer_cleanup_done wait fail"); } +#ifdef FUNC_CALL_MAP + +/** + * hdd_dump_func_call_map() - Dump the function call map + * + * Return: None + */ + +static void hdd_dump_func_call_map(void) +{ + char *cc_buf; + + cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); + /* + * These logs are required as these indicates the start and end of the + * dump for the auto script to parse + */ + hdd_info("Function call map dump start"); + qdf_get_func_call_map(cc_buf); + qdf_trace_hex_dump(QDF_MODULE_ID_HDD, + QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); + hdd_info("Function call map dump end"); + qdf_mem_free(cc_buf); +} +#else +static inline void hdd_dump_func_call_map(void) +{ +} +#endif + QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) { @@ -6366,17 +6860,16 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, hdd_enter(); - if (adapter->device_mode == QDF_STA_MODE && - ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) - hdd_del_monitor_interface(hdd_ctx); - if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX) wlan_hdd_cfg80211_deregister_frames(adapter); hdd_nud_ignore_tracking(adapter, true); hdd_nud_reset_tracking(adapter); hdd_nud_flush_work(adapter); + hdd_mic_flush_work(adapter); hdd_stop_tsf_sync(adapter); + cds_flush_work(&adapter->scan_block_work); + wlan_hdd_cfg80211_scan_block(adapter); hdd_debug("Disabling queues"); wlan_hdd_netif_queue_control(adapter, @@ -6455,8 +6948,13 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu, NULL); - } else if (adapter->device_mode == QDF_NAN_DISC_MODE && - ucfg_is_nan_disc_active(hdd_ctx->psoc)) + } + + if ((adapter->device_mode == QDF_NAN_DISC_MODE || + (adapter->device_mode == QDF_STA_MODE && + !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) && + ucfg_is_nan_disable_supported(hdd_ctx->psoc) && + ucfg_is_nan_disc_active(hdd_ctx->psoc)) ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0); wlan_hdd_scan_abort(adapter); @@ -6491,34 +6989,11 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, adapter->vdev_id); } - - /* - * During vdev destroy, if any STA is in connecting state the - * roam command will be in active queue and thus vdev destroy is - * queued in pending queue. In case STA tries to connect to - * multiple BSSID and fails to connect, due to auth/assoc - * timeouts it may take more than vdev destroy time to get - * completed. On vdev destroy timeout vdev is moved to logically - * deleted state. Once connection is completed, vdev destroy is - * activated and to release the self-peer ref count it try to - * get the ref of the vdev, which fails as vdev is logically - * deleted and this leads to peer ref leak. So before vdev - * destroy is queued abort any STA ongoing connection to avoid - * vdev destroy timeout. - */ - if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) - hdd_abort_ongoing_sta_connection(hdd_ctx); - + hdd_cleanup_conn_info(adapter); hdd_vdev_destroy(adapter); break; case QDF_MONITOR_MODE: - if (wlan_hdd_is_session_type_monitor(QDF_MONITOR_MODE) && - adapter->vdev) { - ucfg_pkt_capture_deregister_callbacks(adapter->vdev); - hdd_objmgr_put_vdev(adapter->vdev); - adapter->vdev = NULL; - } wlan_hdd_scan_abort(adapter); hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); @@ -6550,6 +7025,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, if (!wlan_sap_is_pre_cac_context(sap_ctx) && (hdd_ctx->sap_pre_cac_work.fn)) cds_flush_work(&hdd_ctx->sap_pre_cac_work); + wlansap_cleanup_cac_timer(sap_ctx); /* fallthrough */ @@ -6570,23 +7046,6 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, hdd_deregister_tx_flow_control(adapter); hdd_destroy_acs_timer(adapter); - /** - * During vdev destroy, If any STA is in connecting state the - * roam command will be in active queue and thus vdev destroy is - * queued in pending queue. In case STA is tries to connected to - * multiple BSSID and fails to connect, due to auth/assoc - * timeouts it may take more than vdev destroy time to get - * completes. If vdev destroy timeout vdev is moved to logically - * deleted state. Once connection is completed, vdev destroy is - * activated and to release the self-peer ref count it try to - * get the ref of the vdev, which fails as vdev is logically - * deleted and this leads to peer ref leak. So before vdev - * destroy is queued abort any STA ongoing connection to avoid - * vdev destroy timeout. - */ - if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) - hdd_abort_ongoing_sta_connection(hdd_ctx); - mutex_lock(&hdd_ctx->sap_lock); if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { status = wlansap_stop_bss( @@ -6620,7 +7079,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, qdf_copy_macaddr(&update_ie.bssid, &adapter->mac_addr); - update_ie.smeSessionId = adapter->vdev_id; + update_ie.vdev_id = adapter->vdev_id; update_ie.ieBufferlength = 0; update_ie.pAdditionIEBuffer = NULL; update_ie.append = false; @@ -6641,9 +7100,19 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, /* Reset WNI_CFG_PROBE_RSP Flags */ wlan_hdd_reset_prob_rspies(adapter); } - clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); - qdf_mem_free(adapter->session.ap.beacon); - adapter->session.ap.beacon = NULL; + + /* + * Note to restart sap after SSR driver needs below information + * and is not cleared/freed on purpose in case of SAP SSR + */ + if (!cds_is_driver_recovering()) { + clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); + qdf_mem_free(adapter->session.ap.beacon); + adapter->session.ap.beacon = NULL; + } + + /* Clear all the cached sta info */ + hdd_clear_cached_sta_info(adapter); /* * If Do_Not_Break_Stream was enabled clear avoid channel list. @@ -6661,6 +7130,8 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, cancel_work_sync(&adapter->ipv6_notifier_work); #endif #endif + sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); + if (adapter->device_mode == QDF_SAP_MODE) { ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, adapter->vdev_id); @@ -6673,8 +7144,8 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, case QDF_OCB_MODE: sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), - sta_ctx->conn_info.sta_id[0]); + OL_TXRX_PDEV_ID, + sta_ctx->conn_info.peer_macaddr[0]); hdd_deregister_hl_netdev_fc_timer(adapter); hdd_deregister_tx_flow_control(adapter); hdd_vdev_destroy(adapter); @@ -6689,6 +7160,8 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, adapter->scan_info.default_scan_ies_len = 0; } + /* This function should be invoked at the end of this api*/ + hdd_dump_func_call_map(); hdd_exit(); return QDF_STATUS_SUCCESS; @@ -6702,33 +7175,118 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, */ void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; hdd_enter(); - hdd_for_each_adapter(hdd_ctx, adapter) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) { hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_DEINIT_ALL_ADAPTERS); + } hdd_exit(); } QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; hdd_enter(); if (hdd_ctx->sap_pre_cac_work.fn) cds_flush_work(&hdd_ctx->sap_pre_cac_work); - hdd_for_each_adapter(hdd_ctx, adapter) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_STOP_ALL_ADAPTERS) { hdd_stop_adapter(hdd_ctx, adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_STOP_ALL_ADAPTERS); + } hdd_exit(); return QDF_STATUS_SUCCESS; } +void hdd_set_netdev_flags(struct hdd_adapter *adapter) +{ + bool enable_csum = false; + bool enable_lro; + enum QDF_OPMODE device_mode; + struct hdd_context *hdd_ctx; + ol_txrx_soc_handle soc; + uint64_t temp; + + if (!adapter || !adapter->dev) { + hdd_err("invalid input!"); + return; + } + device_mode = adapter->device_mode; + + hdd_ctx = adapter->hdd_ctx; + soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (!soc || !hdd_ctx) { + hdd_err("invalid SOC or HDD context!"); + return; + } + + /* Determine device_mode specific configuration */ + + enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable); + enable_csum = !!cdp_cfg_get(soc, + cfg_dp_enable_ip_tcp_udp_checksum_offload); + switch (device_mode) { + case QDF_P2P_DEVICE_MODE: + case QDF_P2P_CLIENT_MODE: + enable_csum = !!cdp_cfg_get(soc, + cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); + break; + case QDF_P2P_GO_MODE: + enable_csum = !!cdp_cfg_get(soc, + cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); + enable_lro = false; + break; + case QDF_SAP_MODE: + enable_lro = false; + break; + case QDF_NDI_MODE: + case QDF_NAN_DISC_MODE: + enable_csum = !!cdp_cfg_get(soc, + cfg_dp_enable_nan_ip_tcp_udp_checksum_offload); + break; + default: + break; + } + + /* Set netdev flags */ + + /* + * In case of USB tethering, LRO is disabled. If SSR happened + * during that time, then as part of SSR init, do not enable + * the LRO again. Keep the LRO state same as before SSR. + */ + if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) + adapter->dev->features |= NETIF_F_LRO; + + if (enable_csum) + adapter->dev->features |= + (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + + if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) + adapter->dev->features |= TSO_FEATURE_FLAGS; + + if (cdp_cfg_get(soc, cfg_dp_sg_enable)) + adapter->dev->features |= NETIF_F_SG; + + adapter->dev->features |= NETIF_F_RXCSUM; + temp = (uint64_t)adapter->dev->features; + + hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp); +} + static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) { @@ -6782,31 +7340,31 @@ static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) qdf_mc_timer_stop(&adapter->tx_flow_control_timer); } } +#else +static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) +{ +} #endif QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; - struct hdd_station_ctx *sta_ctx; - struct qdf_mac_addr peer_macaddr; + struct hdd_adapter *adapter, *next_adapter = NULL; bool value; struct wlan_objmgr_vdev *vdev; hdd_enter(); - /* do not flush work if it is not created */ - if (hdd_ctx->sap_pre_cac_work.fn) - cds_flush_work(&hdd_ctx->sap_pre_cac_work); + ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); - hdd_for_each_adapter(hdd_ctx, adapter) { + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_RESET_ALL_ADAPTERS) { hdd_info("[SSR] reset adapter with device mode %s(%d)", qdf_opmode_str(adapter->device_mode), adapter->device_mode); -#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL - hdd_adapter_abort_tx_flow(adapter); -#endif + hdd_adapter_abort_tx_flow(adapter); if ((adapter->device_mode == QDF_STA_MODE) || (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { /* Stop tdls timers */ @@ -6815,9 +7373,8 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) hdd_notify_tdls_reset_adapter(vdev); hdd_objmgr_put_vdev(vdev); } - adapter->session.station.hdd_reassoc_scenario = false; } - ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); + if (value && adapter->device_mode == QDF_SAP_MODE) { wlan_hdd_netif_queue_control(adapter, @@ -6828,6 +7385,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); } + /* * Clear fc flag if it was set before SSR to avoid TX queues * permanently stopped after SSR. @@ -6839,71 +7397,22 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) WLAN_START_ALL_NETIF_QUEUE, WLAN_DATA_FLOW_CONTROL); - if ((adapter->device_mode == QDF_P2P_GO_MODE || - adapter->device_mode == QDF_SAP_MODE) && - test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { - hdd_sap_indicate_disconnect_for_sta(adapter); - clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); - } - hdd_reset_scan_operation(hdd_ctx, adapter); - hdd_deinit_tx_rx(adapter); - policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, - adapter->device_mode, adapter->vdev_id); - hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, - false); + if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { hdd_wmm_adapter_close(adapter); clear_bit(WMM_INIT_DONE, &adapter->event_flags); } - if (adapter->device_mode == QDF_STA_MODE) - hdd_clear_fils_connection_info(adapter); - - if (adapter->device_mode == QDF_SAP_MODE) { - wlansap_cleanup_cac_timer( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - /* - * If adapter is SAP, set session ID to invalid - * since SAP session will be cleanup during SSR. - */ - wlansap_set_invalid_session( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - } - - /* Release vdev ref count to avoid vdev object leak */ - if (adapter->device_mode == QDF_P2P_GO_MODE || - adapter->device_mode == QDF_SAP_MODE) - wlansap_release_vdev_ref( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - - /* Delete connection peers if any to avoid peer object leaks */ - if (adapter->device_mode == QDF_STA_MODE || - adapter->device_mode == QDF_P2P_CLIENT_MODE) { - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - qdf_copy_macaddr(&peer_macaddr, - &sta_ctx->conn_info.bssid); - - } - - hdd_nud_ignore_tracking(adapter, true); - hdd_nud_reset_tracking(adapter); - hdd_nud_flush_work(adapter); - if (adapter->device_mode != QDF_SAP_MODE && adapter->device_mode != QDF_P2P_GO_MODE && adapter->device_mode != QDF_FTM_MODE) hdd_set_disconnect_status(adapter, false); - hdd_stop_tsf_sync(adapter); - - hdd_softap_deinit_tx_rx(adapter); - hdd_deregister_hl_netdev_fc_timer(adapter); - hdd_deregister_tx_flow_control(adapter); - - /* Destroy vdev which will be recreated during reinit. */ - hdd_vdev_destroy(adapter); + hdd_stop_adapter(hdd_ctx, adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_RESET_ALL_ADAPTERS); } hdd_exit(); @@ -6913,17 +7422,25 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN; if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { hdd_info("FTM mode, don't close the module"); return true; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || - test_bit(SME_SESSION_OPENED, &adapter->event_flags)) + test_bit(SME_SESSION_OPENED, &adapter->event_flags)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return false; @@ -7394,17 +7911,9 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, if (WLAN_STATUS_SUCCESS == status) { struct ieee80211_channel *chan; - int freq; - int chan_no = roam_info->bss_desc->channelId; - if (chan_no <= 14) - freq = ieee80211_channel_to_frequency(chan_no, - HDD_NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency(chan_no, - HDD_NL80211_BAND_5GHZ); - - chan = ieee80211_get_channel(adapter->wdev.wiphy, freq); + chan = ieee80211_get_channel(adapter->wdev.wiphy, + roam_info->bss_desc->chan_freq); bss = wlan_cfg80211_get_bss(adapter->wdev.wiphy, chan, bssid, roam_info->u.pConnectedProfile->SSID.ssId, roam_info->u.pConnectedProfile->SSID.length); @@ -7442,8 +7951,8 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, #endif #ifdef FEATURE_MONITOR_MODE_SUPPORT -int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, - uint32_t bandwidth) +int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, + uint32_t bandwidth) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -7454,17 +7963,25 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, struct ch_params ch_params; enum phy_ch_width max_fw_bw; enum phy_ch_width ch_width; + int ret; if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) { hdd_err("Not supported, device is not in monitor mode"); return -EINVAL; } + /* Verify the BW before accepting this request */ ch_width = bandwidth; + + if (ch_width > CH_WIDTH_10MHZ || + (!cds_is_sub_20_mhz_enabled() && ch_width > CH_WIDTH_160MHZ)) { + hdd_err("invalid BW received %d", ch_width); + return -EINVAL; + } + max_fw_bw = sme_get_vht_ch_width(); hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width); - if ((ch_width == CH_WIDTH_160MHZ && max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || (ch_width == CH_WIDTH_80P80MHZ && @@ -7473,50 +7990,35 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, ch_width, max_fw_bw); return -EINVAL; } - /* Validate Channel */ - if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) { - hdd_err("Channel %d Not supported", chan); - return -EINVAL; - } - - if (WLAN_REG_IS_24GHZ_CH(chan)) { - if (bandwidth == CH_WIDTH_80MHZ) { - hdd_err("BW80 not possible in 2.4GHz band"); - return -EINVAL; - } - if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) && - (bandwidth != CH_WIDTH_MAX)) { - hdd_err("Only BW20 possible on channel 14"); - return -EINVAL; - } - } - if (WLAN_REG_IS_5GHZ_CH(chan)) { - if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) && - (bandwidth != CH_WIDTH_MAX)) { - hdd_err("Only BW20 possible on channel 165"); - return -EINVAL; - } + ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth); + if (ret) { + hdd_err("Invalid CH and BW combo"); + return ret; } - hdd_debug("Set monitor mode Channel %d", chan); + hdd_debug("Set monitor mode frequency %d", freq); qdf_mem_zero(&roam_profile, sizeof(roam_profile)); - roam_profile.ChannelInfo.ChannelList = &ch_info->channel; + roam_profile.ChannelInfo.freq_list = &ch_info->freq; roam_profile.ChannelInfo.numOfChannels = 1; roam_profile.phyMode = ch_info->phy_mode; roam_profile.ch_params.ch_width = bandwidth; - hdd_select_cbmode(adapter, chan, &roam_profile.ch_params); + hdd_select_cbmode(adapter, freq, + &roam_profile.ch_params); + qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, QDF_MAC_ADDR_SIZE); ch_params.ch_width = bandwidth; - wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params); + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, freq, 0, + &ch_params); + if (ch_params.ch_width == CH_WIDTH_INVALID) { hdd_err("Invalid capture channel or bandwidth for a country"); return -EINVAL; } - if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan, - POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { + if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq, + POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { hdd_err("Failed to change hw mode"); return -EINVAL; } @@ -7534,7 +8036,7 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, adapter->monitor_mode_vdev_up_in_progress = true; status = sme_roam_channel_change_req(hdd_ctx->mac_handle, - bssid, &ch_params, + bssid, &roam_profile.ch_params, &roam_profile); if (status) { hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", @@ -7543,7 +8045,7 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, return qdf_status_to_os_return(status); } - adapter->mon_chan = chan; + adapter->mon_chan_freq = freq; adapter->mon_bandwidth = bandwidth; /* block on a completion variable until vdev up success*/ @@ -7572,7 +8074,7 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan, } #endif -#ifdef MSM_PLATFORM +#if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) /** * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO * @adapter: pointer to adapter @@ -7590,9 +8092,13 @@ static void hdd_stop_p2p_go(struct hdd_adapter *adapter) static inline void hdd_delete_sta(struct hdd_adapter *adapter) { } + #else -static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter) +static void hdd_stop_p2p_go(struct hdd_adapter *adapter) { + hdd_debug("[SSR] send stop iface ap to supplicant"); + cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, + GFP_KERNEL); } /** @@ -7617,15 +8123,20 @@ static void hdd_delete_sta(struct hdd_adapter *adapter) QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; eConnectionState conn_state; bool value; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS; hdd_enter(); - hdd_for_each_adapter(hdd_ctx, adapter) { - if (!hdd_is_interface_up(adapter)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (!hdd_is_interface_up(adapter) && + adapter->device_mode != QDF_NDI_MODE) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } hdd_debug("[SSR] start adapter with device mode %s(%d)", qdf_opmode_str(adapter->device_mode), @@ -7679,6 +8190,13 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) WLAN_STATUS_ASSOC_DENIED_UNSPEC, GFP_KERNEL, false, 0); } + if ((adapter->device_mode == QDF_NAN_DISC_MODE || + (adapter->device_mode == QDF_STA_MODE && + !ucfg_nan_is_vdev_creation_allowed( + hdd_ctx->psoc))) && + cds_is_driver_recovering()) + ucfg_nan_disable_ind_to_userspace( + hdd_ctx->psoc); hdd_register_tx_flow_control(adapter, hdd_tx_resume_timer_expired_handler, @@ -7691,6 +8209,7 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) hdd_lpass_notify_start(hdd_ctx, adapter); hdd_nud_ignore_tracking(adapter, false); + hdd_mic_enable_work(adapter); break; case QDF_SAP_MODE: @@ -7699,6 +8218,8 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) if (value) hdd_start_ap_adapter(adapter); + hdd_mic_enable_work(adapter); + break; case QDF_P2P_GO_MODE: @@ -7706,19 +8227,30 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) break; case QDF_MONITOR_MODE: if (wlan_hdd_is_session_type_monitor( - QDF_MONITOR_MODE) && - ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { - ucfg_pkt_capture_register_callbacks( - adapter->vdev, - hdd_mon_rx_packet_cbk, - adapter); + QDF_MONITOR_MODE)) { + hdd_set_pktcapture_cb(adapter->dev, + OL_TXRX_PDEV_ID); break; } hdd_start_station_adapter(adapter); hdd_set_mon_rx_cb(adapter->dev); - wlan_hdd_set_mon_chan(adapter, adapter->mon_chan, - adapter->mon_bandwidth); + + /* + * Do not set channel for monitor mode if monitor iface + * went down during SSR, as for set channels host sends + * vdev start command to FW. For the interfaces went + * down during SSR, host stops those adapters by sending + * vdev stop/down/delete commands to FW. So FW doesn't + * sends response for vdev start and vdev start response + * timer expires and thus host triggers ASSERT. + */ + if (!test_bit(DOWN_DURING_SSR, &adapter->event_flags)) + wlan_hdd_set_mon_chan( + adapter, adapter->mon_chan_freq, + adapter->mon_bandwidth); break; + case QDF_NDI_MODE: + hdd_ndi_start(adapter->dev->name, 0); default: break; } @@ -7727,14 +8259,20 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) * applicable to all interfaces */ wlan_hdd_cfg80211_register_frames(adapter); + hdd_adapter_dev_put_debug(adapter, dbgid); } - hdd_for_each_adapter(hdd_ctx, adapter) { - if (!hdd_is_interface_up(adapter)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (!hdd_is_interface_up(adapter)) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } if (adapter->device_mode == QDF_P2P_GO_MODE) hdd_stop_p2p_go(adapter); + + hdd_adapter_dev_put_debug(adapter, dbgid); } hdd_exit(); @@ -7742,6 +8280,35 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) return QDF_STATUS_SUCCESS; } +void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, + wlan_net_dev_ref_dbgid dbgid) +{ + if (dbgid >= NET_DEV_HOLD_ID_MAX) { + hdd_err("Invalid debug id: %d", dbgid); + QDF_BUG(0); + } + dev_hold(adapter->dev); + qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]); +} + +void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, + wlan_net_dev_ref_dbgid dbgid) +{ + if (dbgid >= NET_DEV_HOLD_ID_MAX) { + hdd_err("Invalid debug id: %d", dbgid); + QDF_BUG(0); + } + + if (qdf_atomic_dec_return( + &adapter->net_dev_hold_ref_count[dbgid]) < 0) { + hdd_err("dev_put detected without dev_hold for debug id: %s", + net_dev_ref_debug_string_from_id(dbgid)); + QDF_BUG(0); + } + + dev_put(adapter->dev); +} + QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter **out_adapter) { @@ -7929,15 +8496,24 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context) struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if ((adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE || adapter->device_mode == QDF_P2P_DEVICE_MODE) && ucfg_p2p_check_random_mac(hdd_ctx->psoc, - adapter->vdev_id, mac_addr)) + adapter->vdev_id, mac_addr)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; @@ -7946,12 +8522,20 @@ struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (!qdf_mem_cmp(adapter->mac_addr.bytes, - mac_addr, sizeof(tSirMacAddr))) + mac_addr, sizeof(tSirMacAddr))) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; @@ -7960,11 +8544,19 @@ struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV; - hdd_for_each_adapter(hdd_ctx, adapter) { - if (adapter->vdev_id == vdev_id) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->vdev_id == vdev_id) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; @@ -7973,13 +8565,20 @@ struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx, struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx, struct hdd_adapter *reference) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter == reference) { dev_hold(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); break; } + hdd_adapter_dev_put_debug(adapter, dbgid); } return adapter; @@ -7993,11 +8592,19 @@ void hdd_adapter_put(struct hdd_adapter *adapter) struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, const char *iface_name) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME; - hdd_for_each_adapter(hdd_ctx, adapter) { - if (!qdf_str_cmp(adapter->dev->name, iface_name)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (!qdf_str_cmp(adapter->dev->name, iface_name)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; @@ -8016,11 +8623,19 @@ struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx, enum QDF_OPMODE mode) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; - hdd_for_each_adapter(hdd_ctx, adapter) { - if (adapter->device_mode == mode) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter->device_mode == mode) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; @@ -8046,71 +8661,41 @@ enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) return adapter->device_mode; } -/** - * hdd_get_operating_channel() - return operating channel of the device mode - * @hdd_ctx: Pointer to the HDD context. - * @mode: Device mode for which operating channel is required. - * Supported modes: - * QDF_STA_MODE, - * QDF_P2P_CLIENT_MODE, - * QDF_SAP_MODE, - * QDF_P2P_GO_MODE. - * - * This API returns the operating channel of the requested device mode - * - * Return: channel number. "0" id the requested device is not found OR it is - * not connected. - */ -uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx, - enum QDF_OPMODE mode) +uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, + enum QDF_OPMODE mode) { - struct hdd_adapter *adapter; - uint8_t operatingChannel = 0; + struct hdd_adapter *adapter, *next_adapter = NULL; + uint32_t oper_chan_freq = 0; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (mode == adapter->device_mode) { - switch (adapter->device_mode) { - case QDF_STA_MODE: - case QDF_P2P_CLIENT_MODE: - if (hdd_conn_is_connected - (WLAN_HDD_GET_STATION_CTX_PTR - (adapter))) { - operatingChannel = - (WLAN_HDD_GET_STATION_CTX_PTR - (adapter))->conn_info. - channel; - } - break; - case QDF_SAP_MODE: - case QDF_P2P_GO_MODE: - /* softap connection info */ - if (test_bit - (SOFTAP_BSS_STARTED, - &adapter->event_flags)) - operatingChannel = - (WLAN_HDD_GET_AP_CTX_PTR - (adapter))->operating_channel; - break; - default: - break; - } - - /* Found the device of interest. break the loop */ + oper_chan_freq = + hdd_get_adapter_home_channel(adapter); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); break; } + hdd_adapter_dev_put_debug(adapter, dbgid); } - return operatingChannel; + return oper_chan_freq; } static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context * hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS; hdd_enter(); - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE || adapter->device_mode == QDF_IBSS_MODE || @@ -8119,6 +8704,7 @@ static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context * adapter->device_mode == QDF_P2P_GO_MODE) { hdd_unregister_wext(adapter->dev); } + hdd_adapter_dev_put_debug(adapter, dbgid); } hdd_exit(); @@ -8128,11 +8714,14 @@ static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context * QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS; hdd_enter(); - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE || adapter->device_mode == QDF_IBSS_MODE || @@ -8143,6 +8732,7 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) adapter->vdev_id, INVALID_SCAN_ID, true); } + hdd_adapter_dev_put_debug(adapter, dbgid); } hdd_exit(); @@ -8159,11 +8749,13 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) */ static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; int err; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS; - - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE || adapter->device_mode == QDF_IBSS_MODE || @@ -8174,10 +8766,9 @@ static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) if (err) hdd_err("Unable to stop scheduled scan"); } + hdd_adapter_dev_put_debug(adapter, dbgid); } - hdd_exit(); - return QDF_STATUS_SUCCESS; } @@ -8198,6 +8789,7 @@ void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status) */ void hdd_unregister_notifiers(struct hdd_context *hdd_ctx) { + hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); hdd_nud_unregister_netevent_notifier(hdd_ctx); hdd_wlan_unregister_ip6_notifier(hdd_ctx); @@ -8392,6 +8984,9 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_abort_mac_scan_all_adapters(hdd_ctx); hdd_abort_sched_scan_all_adapters(hdd_ctx); + if (wlan_hdd_is_session_type_monitor(QDF_MONITOR_MODE)) + hdd_reset_pktcapture_cb(OL_TXRX_PDEV_ID); + hdd_stop_all_adapters(hdd_ctx); hdd_deinit_all_adapters(hdd_ctx, false); } @@ -8435,6 +9030,9 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx) #ifdef FEATURE_WLAN_CH_AVOID mutex_destroy(&hdd_ctx->avoid_freq_lock); #endif + + /* This function should be invoked at the end of this api*/ + hdd_dump_func_call_map(); } /** @@ -8497,16 +9095,96 @@ QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx) struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER; - hdd_for_each_adapter(hdd_ctx, adapter) { - if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return adapter; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return NULL; } +/** + * hdd_rx_mic_error_ind() - MIC error indication handler + * @psoc: opaque handle for UMAC psoc object + * @pdev_id: physical device instance id + * @mic_failure_info: mic failure information + * + * This function indicates the Mic failure to the supplicant + * + * Return: None + */ +static void +hdd_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, + struct cdp_rx_mic_err_info *mic_failure_info) +{ + struct wiphy *wiphy; + struct pdev_osif_priv *pdev_priv; + struct hdd_context *hdd_ctx; + struct hdd_adapter *adapter; + struct hdd_mic_error_info *hdd_mic_info; + struct wlan_objmgr_pdev *pdev; + + if (!psoc) + return; + + pdev = wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, + pdev_id, WLAN_MLME_SB_ID); + if (!pdev) + return; + + pdev_priv = wlan_pdev_get_ospriv(pdev); + wiphy = pdev_priv->wiphy; + hdd_ctx = wiphy_priv(wiphy); + + if (wlan_hdd_validate_context(hdd_ctx)) + goto release_ref_and_return; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, mic_failure_info->vdev_id); + if (hdd_validate_adapter(adapter)) + goto release_ref_and_return; + + hdd_mic_info = qdf_mem_malloc(sizeof(*hdd_mic_info)); + if (!hdd_mic_info) + goto release_ref_and_return; + + qdf_copy_macaddr(&hdd_mic_info->ta_mac_addr, + &mic_failure_info->ta_mac_addr); + hdd_mic_info->multicast = mic_failure_info->multicast; + hdd_mic_info->key_id = mic_failure_info->key_id; + qdf_mem_copy(&hdd_mic_info->tsc, &mic_failure_info->tsc, + SIR_CIPHER_SEQ_CTR_SIZE); + hdd_mic_info->vdev_id = mic_failure_info->vdev_id; + + qdf_spin_lock_bh(&adapter->mic_work.lock); + if (adapter->mic_work.status != MIC_INITIALIZED) { + qdf_spin_unlock_bh(&adapter->mic_work.lock); + qdf_mem_free(hdd_mic_info); + goto release_ref_and_return; + } + /* + * Store mic error info pointer in adapter + * for freeing up the alocated memory in case + * the work scheduled below is flushed or deinitialized. + */ + adapter->mic_work.status = MIC_SCHEDULED; + adapter->mic_work.info = hdd_mic_info; + qdf_sched_work(0, &adapter->mic_work.work); + qdf_spin_unlock_bh(&adapter->mic_work.lock); + +release_ref_and_return: + wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_SB_ID); +} + /* wake lock APIs for HDD */ void hdd_prevent_suspend(uint32_t reason) { @@ -8643,7 +9321,6 @@ static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx, { static uint32_t counter; static bool data_in_time_period; - ol_txrx_pdev_handle pdev; ol_txrx_soc_handle soc; uint32_t periodic_stats_disp_time = 0; @@ -8658,12 +9335,6 @@ static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx, return; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - hdd_err("pdev is NULL"); - return; - } - counter++; if (data_in_interval) data_in_time_period = data_in_interval; @@ -8679,6 +9350,9 @@ static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx, cdp_display_stats(soc, CDP_TXRX_PATH_STATS, QDF_STATS_VERBOSITY_LEVEL_LOW); + cdp_display_stats(soc, + CDP_DUMP_TX_FLOW_POOL_INFO, + QDF_STATS_VERBOSITY_LEVEL_LOW); wlan_hdd_display_netif_queue_history (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW); qdf_dp_trace_dump_stats(); @@ -8696,17 +9370,29 @@ static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx, */ static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; - hdd_for_each_adapter(hdd_ctx, adapter) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_CLEAR_RPS_CPU_MASK) { hdd_send_rps_disable_ind(adapter); + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_CLEAR_RPS_CPU_MASK); + } } -#ifdef CLD_PM_QOS +#if defined(CLD_PM_QOS) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) #define PLD_REMOVE_PM_QOS(x) #define PLD_REQUEST_PM_QOS(x, y) +/** + * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting + * @mask: return variable of cpumask for the TPUT + * @high_throughput: only update high cores mask for high TPUT + * + * Return: none + */ static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, - bool high_throughput) + bool high_throughput) { cpumask_set_cpu(0, mask); cpumask_set_cpu(1, mask); @@ -8721,6 +9407,15 @@ static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, } } +#ifdef MSM_PLATFORM +#define COPY_CPU_MASK(a, b) cpumask_copy(a, b) +#define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \ + cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)) +#else +#define COPY_CPU_MASK(a, b) /* no-op*/ +#define DUMP_CPU_AFFINE() /* no-op*/ +#endif + /** * hdd_pm_qos_update_request() - API to request for pm_qos * @hdd_ctx: handle to hdd context @@ -8728,27 +9423,10 @@ static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, * * Return: none */ -#ifdef FEATURE_RUNTIME_PM static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, - enum pld_bus_width_type next_vote_level, cpumask_t *pm_qos_cpu_mask) { - cpumask_copy(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); - - /* Latency value to be read from INI */ - if (cpumask_empty(pm_qos_cpu_mask) && - hdd_ctx->config->runtime_pm == hdd_runtime_pm_dynamic) - pm_qos_update_request(&hdd_ctx->pm_qos_req, - PM_QOS_DEFAULT_VALUE); - else - pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); -} -#else -static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, - enum pld_bus_width_type next_vote_level, - cpumask_t *pm_qos_cpu_mask) -{ - cpumask_copy(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); + COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); /* Latency value to be read from INI */ if (cpumask_empty(pm_qos_cpu_mask)) @@ -8757,9 +9435,8 @@ static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, else pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); } -#endif -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && defined(MSM_PLATFORM) /** * hdd_update_pm_qos_affine_cores() - Update PM_qos request for AFFINE_CORES * @hdd_ctx: handle to hdd context @@ -8782,6 +9459,7 @@ static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) hdd_update_pm_qos_affine_cores(hdd_ctx); pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + DUMP_CPU_AFFINE(); hdd_info("Set cpu_mask %*pb for affine_cores", cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)); } @@ -8803,13 +9481,12 @@ static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) } static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, - bool high_throughput) + bool high_throughput) { } static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, - enum pld_bus_width_type next_vote_level, - cpumask_t *pm_qos_cpu_mask) + cpumask_t *pm_qos_cpu_mask) { } #endif @@ -8848,8 +9525,10 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count; uint32_t bus_low_cnt_threshold = hdd_ctx->config->bus_low_cnt_threshold; cpumask_t pm_qos_cpu_mask; - bool rx_pm_qos_high = false; - bool tx_pm_qos_high = false; + bool is_rx_pm_qos_high = false; + bool is_tx_pm_qos_high = false; + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + int i; cpumask_clear(&pm_qos_cpu_mask); @@ -8871,6 +9550,14 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, if (++hdd_ctx->bus_low_vote_cnt >= bus_low_cnt_threshold) qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 1); } else { + if (qdf_atomic_read(&hdd_ctx->low_tput_gro_enable) && + hdd_ctx->enable_dp_rx_threads) { + /* flush pending rx pkts when LOW->IDLE */ + hdd_debug("flush queued GRO pkts"); + for (i = 0; i < cdp_get_num_rx_contexts(soc); i++) { + dp_rx_gro_flush_ind(soc, i); + } + } hdd_ctx->bus_low_vote_cnt = 0; qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 0); } @@ -8882,7 +9569,22 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_ctx->cur_vote_level = next_vote_level; vote_level_change = true; - pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level); + /* + * 11g/a clients are latency sensitive, and any delay in DDR + * access for fetching the packet can cause throughput drop. + * For 11g/a clients LOW voting level is not sufficient for + * peak throughput. Vote for higher DDR frequency if latency + * critical connections are present. + */ + if (hdd_ctx->config->enable_latency_crit_clients && + (next_vote_level == PLD_BUS_WIDTH_LOW || + next_vote_level == PLD_BUS_WIDTH_IDLE) && + qdf_atomic_read(&hdd_ctx->num_latency_critical_clients)) + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_LOW_LATENCY); + else + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + next_vote_level); if ((next_vote_level == PLD_BUS_WIDTH_LOW) || (next_vote_level == PLD_BUS_WIDTH_IDLE)) { @@ -8961,13 +9663,13 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, */ if (avg_no_rx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) { rxthread_high_tput_req = true; - rx_pm_qos_high = true; + is_rx_pm_qos_high = true; } else { rxthread_high_tput_req = false; - rx_pm_qos_high = false; + is_rx_pm_qos_high = false; } - hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, rx_pm_qos_high); + hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_rx_pm_qos_high); if (cds_sched_handle_throughput_req(rxthread_high_tput_req)) hdd_warn("Rx thread high_tput(%d) affinity request failed", @@ -8996,8 +9698,6 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, */ if (hdd_ctx->en_tcp_delack_no_lro) { rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND; - hdd_debug("TCP DELACK trigger level %d, average_rx: %llu", - next_rx_level, avg_rx); } if (hdd_ctx->config->enable_tcp_adv_win_scale) @@ -9025,11 +9725,11 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_ctx->prev_tx = tx_packets; if (avg_no_tx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) - tx_pm_qos_high = true; + is_tx_pm_qos_high = true; else - tx_pm_qos_high = false; + is_tx_pm_qos_high = false; - hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, tx_pm_qos_high); + hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_tx_pm_qos_high); if (avg_tx > hdd_ctx->config->tcp_tx_high_tput_thres) next_tx_level = WLAN_SVC_TP_HIGH; @@ -9039,9 +9739,6 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, if ((hdd_ctx->config->enable_tcp_limit_output) && (hdd_ctx->cur_tx_level != next_tx_level)) { struct wlan_tx_tp_data tx_tp_data = {0}; - - hdd_debug("change TCP TX trigger level %d, average_tx: %llu", - next_tx_level, avg_tx); hdd_ctx->cur_tx_level = next_tx_level; tx_level_change = true; tx_tp_data.level = next_tx_level; @@ -9053,15 +9750,17 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, if (vote_level_change || tx_level_change || rx_level_change) { /* Clear all the mask if no silver/gold vote is required */ if (next_vote_level < PLD_BUS_WIDTH_HIGH) { - rx_pm_qos_high = false; - tx_pm_qos_high = false; + is_rx_pm_qos_high = false; + is_tx_pm_qos_high = false; cpumask_clear(&pm_qos_cpu_mask); } hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level; hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level; - hdd_ctx->hdd_txrx_hist[index].rx_pm_qos_high = rx_pm_qos_high; - hdd_ctx->hdd_txrx_hist[index].tx_pm_qos_high = tx_pm_qos_high; + hdd_ctx->hdd_txrx_hist[index].is_rx_pm_qos_high = + is_rx_pm_qos_high; + hdd_ctx->hdd_txrx_hist[index].is_tx_pm_qos_high = + is_tx_pm_qos_high; hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level; hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets; hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets; @@ -9069,8 +9768,11 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_ctx->hdd_txrx_hist_idx++; hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK; - hdd_pm_qos_update_request(hdd_ctx, next_vote_level, - &pm_qos_cpu_mask); + /* Clear all the mask if no silver/gold vote is required */ + if (next_vote_level < PLD_BUS_WIDTH_MEDIUM) + cpumask_clear(&pm_qos_cpu_mask); + + hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); } hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false); @@ -9078,6 +9780,37 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_periodic_sta_stats_display(hdd_ctx); } +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +/** + * hdd_set_driver_del_ack_enable() - set driver delayed ack enabled flag + * @vdev_id: vdev id + * @hdd_ctx: handle to hdd context + * @rx_packets: receive packet count + * + * Return: none + */ +static inline +void hdd_set_driver_del_ack_enable(uint16_t vdev_id, + struct hdd_context *hdd_ctx, + uint64_t rx_packets) +{ + struct hdd_config *cfg = hdd_ctx->config; + + cdp_vdev_set_driver_del_ack_enable(cds_get_context(QDF_MODULE_ID_SOC), + vdev_id, rx_packets, + cfg->bus_bw_compute_interval, + cfg->del_ack_threshold_high, + cfg->del_ack_threshold_low); +} +#else +static inline +void hdd_set_driver_del_ack_enable(uint16_t vdev_id, + struct hdd_context *hdd_ctx, + uint64_t rx_packets) +{ +} +#endif + #ifdef WDI3_STATS_UPDATE static inline void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx, @@ -9102,11 +9835,180 @@ static void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx, } #endif +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +static inline +void hdd_set_vdev_bundle_require_flag(uint16_t vdev_id, + struct hdd_context *hdd_ctx, + uint64_t tx_bytes) +{ + struct hdd_config *cfg = hdd_ctx->config; + + cdp_vdev_set_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC), + vdev_id, tx_bytes, + cfg->bus_bw_compute_interval, + cfg->pkt_bundle_threshold_high, + cfg->pkt_bundle_threshold_low); +} +#else +static inline +void hdd_set_vdev_bundle_require_flag(uint16_t vdev_id, + struct hdd_context *hdd_ctx, + uint64_t tx_bytes) +{ +} +#endif + #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) + +#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION +static enum qdisc_filter_status +__hdd_check_for_prio_filter_in_clsact_qdisc(struct tcf_block *block, + uint32_t prio) +{ + struct tcf_chain *chain; + struct tcf_proto *tp; + enum qdisc_filter_status ret = QDISC_FILTER_PRIO_MISMATCH; + + if (!rtnl_trylock()) + return QDISC_FILTER_RTNL_LOCK_FAIL; + + list_for_each_entry(chain, &block->chain_list, list) { + for (tp = rtnl_dereference(chain->filter_chain); tp; + tp = rtnl_dereference(tp->next)) { + if (tp->prio == (prio << 16)) + ret = QDISC_FILTER_PRIO_MATCH; + } + } + rtnl_unlock(); + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +/** + * hdd_check_for_prio_filter_in_clsact_qdisc() - Check if priority 3 filter + * is configured in the ingress clsact qdisc + * @qdisc: pointer to clsact qdisc + * + * Return: true if priority 3 filter is present else false + */ +static enum qdisc_filter_status +hdd_check_for_prio_filter_in_clsact_qdisc(struct Qdisc *qdisc, uint32_t prio) +{ + const struct Qdisc_class_ops *cops; + struct tcf_block *ingress_block; + + cops = qdisc->ops->cl_ops; + if (qdf_unlikely(!cops || !cops->tcf_block)) + return QDISC_FILTER_PRIO_MISMATCH; + + ingress_block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL); + if (qdf_unlikely(!ingress_block)) + return QDISC_FILTER_PRIO_MISMATCH; + + return __hdd_check_for_prio_filter_in_clsact_qdisc(ingress_block, prio); +} +#else +static enum qdisc_filter_status +hdd_check_for_prio_filter_in_clsact_qdisc(struct Qdisc *qdisc, uint32_t prio) +{ + const struct Qdisc_class_ops *cops; + struct tcf_block *ingress_block; + + cops = qdisc->ops->cl_ops; + if (qdf_unlikely(!cops || !cops->tcf_block)) + return QDISC_FILTER_PRIO_MISMATCH; + + ingress_block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS); + if (qdf_unlikely(!ingress_block)) + return QDISC_FILTER_PRIO_MISMATCH; + + return __hdd_check_for_prio_filter_in_clsact_qdisc(ingress_block, prio); +} +#endif + +/** + * hdd_rx_check_qdisc_for_adapter() - Check if any ingress qdisc is configured + * for given adapter + * @adapter: pointer to HDD adapter context + * @rx_ctx_id: Rx context id + * + * The function checks if ingress qdisc is registered for a given + * net device. + * + * Return: None + */ +static void +hdd_rx_check_qdisc_for_adapter(struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx = adapter->hdd_ctx; + struct netdev_queue *ingress_q; + struct Qdisc *ingress_qdisc; + bool disable_gro = false; + enum qdisc_filter_status ret; + + if (!adapter->dev->ingress_queue) + goto reset_wl; + + rcu_read_lock(); + + ingress_q = rcu_dereference(adapter->dev->ingress_queue); + if (qdf_unlikely(!ingress_q)) + goto reset; + + ingress_qdisc = rcu_dereference(ingress_q->qdisc); + if (qdf_unlikely(!ingress_qdisc)) + goto reset; + + if (qdf_str_eq(ingress_qdisc->ops->id, "ingress")) { + disable_gro = true; + } else if (qdf_str_eq(ingress_qdisc->ops->id, "clsact")) { + ret = hdd_check_for_prio_filter_in_clsact_qdisc(ingress_qdisc, + hdd_ctx->dp_agg_param.tc_ingress_prio); + + if (ret == QDISC_FILTER_RTNL_LOCK_FAIL) { + rcu_read_unlock(); + return; + } else if (ret == QDISC_FILTER_PRIO_MISMATCH) { + goto reset; + } + + disable_gro = true; + } + + if (disable_gro) { + rcu_read_unlock(); + + if (qdf_likely(qdf_atomic_read(&adapter->gro_disallowed))) + return; + + hdd_debug("ingress qdisc/filter configured disable GRO"); + qdf_atomic_set(&adapter->gro_disallowed, 1); + + return; + } + +reset: + rcu_read_unlock(); + +reset_wl: + if (qdf_unlikely(qdf_atomic_read(&adapter->gro_disallowed))) { + hdd_debug("ingress qdisc/filter removed enable GRO"); + qdf_atomic_set(&adapter->gro_disallowed, 0); + } +} +#else +static inline void +hdd_rx_check_qdisc_for_adapter(struct hdd_adapter *adapter) +{ +} +#endif + static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL; - uint64_t tx_packets = 0, rx_packets = 0; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL, + *con_sap_adapter = NULL; + uint64_t tx_packets = 0, rx_packets = 0, tx_bytes = 0; uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0; uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0; uint64_t total_tx = 0, total_rx = 0; @@ -9114,6 +10016,7 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) bool connected = false; uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0; uint64_t sta_tx_bytes = 0, sap_tx_bytes = 0; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_BUS_BW_WORK_HANDLER; if (wlan_hdd_validate_context(hdd_ctx)) goto stop_work; @@ -9121,33 +10024,42 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) if (hdd_ctx->is_wiphy_suspended) return; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { /* * Validate magic so we don't end up accessing * an invalid adapter. */ - if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) + if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } if ((adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) && WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.conn_state != eConnectionState_Associated) { - + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } if ((adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) && WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) { - + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } + if (hdd_ctx->dp_agg_param.tc_based_dyn_gro || + hdd_ctx->ol_enable == CFG_DYNAMIC_GRO_ENABLED) + hdd_rx_check_qdisc_for_adapter(adapter); + tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets, adapter->prev_tx_packets); rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets, adapter->prev_rx_packets); + tx_bytes = HDD_BW_GET_DIFF(adapter->stats.tx_bytes, + adapter->prev_tx_bytes); if (adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE || @@ -9176,6 +10088,12 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) if (adapter->device_mode == QDF_STA_MODE) sta_tx_bytes = adapter->stats.tx_bytes; + hdd_set_driver_del_ack_enable(adapter->vdev_id, hdd_ctx, + rx_packets); + + hdd_set_vdev_bundle_require_flag(adapter->vdev_id, hdd_ctx, + tx_bytes); + total_rx += adapter->stats.rx_packets; total_tx += adapter->stats.tx_packets; @@ -9184,8 +10102,10 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) adapter->prev_rx_packets = adapter->stats.rx_packets; adapter->prev_fwd_tx_packets = fwd_tx_packets; adapter->prev_fwd_rx_packets = fwd_rx_packets; + adapter->prev_tx_bytes = adapter->stats.tx_bytes; qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock); connected = true; + hdd_adapter_dev_put_debug(adapter, dbgid); } if (!connected) { @@ -9235,7 +10155,9 @@ int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx) hdd_enter(); qdf_spinlock_create(&hdd_ctx->bus_bw_lock); + hdd_pm_qos_add_request(hdd_ctx); + status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work, hdd_bus_bw_work_handler, hdd_ctx); @@ -9255,13 +10177,134 @@ void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx) QDF_BUG(!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work)); qdf_periodic_work_destroy(&hdd_ctx->bus_bw_work); - hdd_pm_qos_remove_request(hdd_ctx); qdf_spinlock_destroy(&hdd_ctx->bus_bw_lock); + hdd_pm_qos_remove_request(hdd_ctx); hdd_exit(); } #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ +/** + * __hdd_adapter_param_update_work() - Gist of the work to process + * netdev feature update. + * @adapter: pointer to adapter structure + * + * This function assumes that the adapter pointer is always valid. + * So the caller shoudl always validate adapter pointer before calling + * this function + * + * Returns: None + */ +static inline void +__hdd_adapter_param_update_work(struct hdd_adapter *adapter) +{ + /** + * This check is needed in case the work got scheduled after the + * interface got disconnected. During disconnection, the network queues + * are paused and hence should not be, mistakenly, restarted here. + * There are two approaches to handle this case + * 1) Flush the work during disconnection + * 2) Check for connected state in work + * + * Since the flushing of work during disconnection will need to be + * done at multiple places or entry points, instead its preferred to + * check the connection state and skip the operation here. + */ + if (!hdd_adapter_is_connected_sta(adapter)) + return; + + hdd_netdev_update_features(adapter); + + hdd_debug("Enabling queues"); + wlan_hdd_netif_queue_control(adapter, WLAN_WAKE_ALL_NETIF_QUEUE, + WLAN_CONTROL_PATH); +} + +/** + * hdd_adapter_param_update_work() - work to process the netdev features + * update. + * @arg: private data passed to work + * + * Returns: None + */ +static void hdd_adapter_param_update_work(void *arg) +{ + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + struct hdd_adapter *adapter = arg; + struct osif_vdev_sync *vdev_sync; + int errno; + + if (!hdd_ctx) { + hdd_err("Invalid hdd context"); + return; + } + + hdd_adapter_ops_record_event(hdd_ctx, + WLAN_HDD_ADAPTER_OPS_WORK_SCHED, + WLAN_INVALID_VDEV_ID); + + if (hdd_validate_adapter(adapter)) { + hdd_err("netdev features update request for invalid adapter"); + return; + } + + errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync); + if (errno) + return; + + __hdd_adapter_param_update_work(adapter); + + osif_vdev_sync_op_stop(vdev_sync); +} + +QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx) +{ + hdd_enter(); + + hdd_ctx->adapter_ops_wq = + qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq"); + if (!hdd_ctx->adapter_ops_wq) + return QDF_STATUS_E_NOMEM; + + hdd_exit(); + + return QDF_STATUS_SUCCESS; +} + +void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx) +{ + hdd_enter(); + + qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq); + qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq); + + hdd_exit(); +} + +QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter) +{ + QDF_STATUS status; + + hdd_enter(); + + status = qdf_create_work(0, &adapter->netdev_features_update_work, + hdd_adapter_param_update_work, adapter); + + hdd_exit(); + + return status; +} + +void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter) +{ + hdd_enter(); + + qdf_cancel_work(&adapter->netdev_features_update_work); + qdf_flush_work(&adapter->netdev_features_update_work); + + hdd_exit(); +} + static uint8_t *convert_level_to_string(uint32_t level) { switch (level) { @@ -9279,7 +10322,6 @@ static uint8_t *convert_level_to_string(uint32_t level) } } - /** * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram * @hdd_ctx: hdd context @@ -9328,9 +10370,9 @@ void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx) convert_level_to_string( hdd_ctx->hdd_txrx_hist[i]. next_tx_level), - hdd_ctx->hdd_txrx_hist[i].rx_pm_qos_high ? + hdd_ctx->hdd_txrx_hist[i].is_rx_pm_qos_high ? "HIGH" : "LOW", - hdd_ctx->hdd_txrx_hist[i].tx_pm_qos_high ? + hdd_ctx->hdd_txrx_hist[i].is_tx_pm_qos_high ? "HIGH" : "LOW"); } } @@ -9369,7 +10411,9 @@ hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) char temp_str[20 * WLAN_REASON_TYPE_MAX]; char *comb_log_str; uint32_t comb_log_str_size; - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT; comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1; comb_log_str = qdf_mem_malloc(comb_log_str_size); @@ -9378,7 +10422,8 @@ hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) bytes_written = 0; - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { curr_time = qdf_system_ticks(); total = curr_time - adapter->start_time; delta = curr_time - adapter->last_time; @@ -9423,7 +10468,7 @@ hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) adapter_num++; /* dev_put has to be done here */ - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); } /* using QDF_TRACE to avoid printing function name */ @@ -9537,21 +10582,24 @@ void wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx, enum qdf_stats_verbosity_level verb_lvl) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = + NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY; if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) { hdd_display_netif_queue_history_compact(hdd_ctx); return; } - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter->vdev_id == CDP_INVALID_VDEV_ID) { - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } wlan_hdd_display_adapter_netif_queue_stats(adapter); /* dev_put has to be done here */ - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -9563,9 +10611,11 @@ wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx, */ void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { qdf_mem_zero(adapter->queue_oper_stats, sizeof(adapter->queue_oper_stats)); qdf_mem_zero(adapter->queue_oper_history, @@ -9574,6 +10624,7 @@ void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) adapter->start_time = adapter->last_time = qdf_system_ticks(); adapter->total_pause_time = 0; adapter->total_unpause_time = 0; + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -9747,8 +10798,9 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, hdd_debug("chan:%d width:%d", channel, hdd_ap_ctx->sap_config.ch_width_orig); - policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, - adapter->vdev_id, channel, + policy_mgr_change_sap_channel_with_csa( + hdd_ctx->psoc, adapter->vdev_id, + wlan_chan_to_freq(channel), hdd_ap_ctx->sap_config.ch_width_orig, forced); } @@ -9821,28 +10873,36 @@ hdd_store_sap_restart_channel(uint8_t restart_chan, uint8_t *restart_chan_store) */ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; uint32_t i; bool found = false; uint8_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0}; - uint8_t restart_chan; + uint8_t restart_chan, ap_chan; uint8_t scc_on_lte_coex = 0; + uint32_t restart_freq, ap_chan_freq; bool value; QDF_STATUS status; bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE); bool is_vendor_acs_support = cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; - hdd_for_each_adapter(hdd_ctxt, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctxt, adapter, next_adapter, + dbgid) { if (!(adapter->device_mode == QDF_SAP_MODE && adapter->session.ap.sap_config.acs_cfg.acs_mode)) { - hdd_debug("skip device mode:%d acs:%d", - adapter->device_mode, - adapter->session.ap.sap_config. - acs_cfg.acs_mode); + hdd_debug_rl("skip device mode:%d acs:%d", + adapter->device_mode, + adapter->session.ap.sap_config.acs_cfg.acs_mode); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } + ap_chan = wlan_reg_freq_to_chan( + hdd_ctxt->pdev, + adapter->session.ap.operating_chan_freq); + ap_chan_freq = adapter->session.ap.operating_chan_freq; + found = false; status = ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc, @@ -9854,30 +10914,31 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) * is set, no need to move SAP. */ if ((policy_mgr_is_sta_sap_scc( - hdd_ctxt->psoc, - adapter->session.ap.operating_channel) && - scc_on_lte_coex) || - policy_mgr_nan_sap_scc_on_unsafe_ch_chk( - hdd_ctxt->psoc, - adapter->session.ap.operating_channel)) { + hdd_ctxt->psoc, + adapter->session.ap.operating_chan_freq) && + scc_on_lte_coex) || + policy_mgr_nan_sap_scc_on_unsafe_ch_chk( + hdd_ctxt->psoc, + adapter->session.ap.operating_chan_freq)) { hdd_debug("SAP allowed in unsafe SCC channel"); } else { for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) { - if (adapter->session.ap.operating_channel == - hdd_ctxt->unsafe_channel_list[i]) { + if (ap_chan_freq == + hdd_ctxt->unsafe_channel_list[i]) { found = true; - hdd_debug("operating ch:%d is unsafe", - adapter->session.ap.operating_channel); + hdd_debug("op ch freq:%d is unsafe", + ap_chan_freq); break; } } } if (!found) { hdd_store_sap_restart_channel( - adapter->session.ap.operating_channel, + ap_chan, restart_chan_store); hdd_debug("ch:%d is safe. no need to change channel", - adapter->session.ap.operating_channel); + ap_chan); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } @@ -9896,6 +10957,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) { hdd_update_acs_timer_reason(adapter, QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } @@ -9906,18 +10968,19 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) if (policy_mgr_is_force_scc(hdd_ctxt->psoc) && WLAN_REG_IS_SAME_BAND_CHANNELS( - restart_chan_store[i], - adapter->session.ap. - operating_channel)) { + restart_chan_store[i], + ap_chan)) { restart_chan = restart_chan_store[i]; break; } } - if (!restart_chan) - restart_chan = + if (!restart_chan) { + restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - + restart_chan = wlan_reg_freq_to_chan(hdd_ctxt->pdev, + restart_freq); + } if (!restart_chan) { hdd_err("fail to restart SAP"); } else { @@ -9928,7 +10991,8 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) * 0. Otherwise these settings will override * the ACS while restart. */ - hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT; + hdd_ctxt->acs_policy.acs_chan_freq = + AUTO_CHANNEL_SELECT; ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc, &value); if (value) { @@ -9937,6 +11001,10 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) CSA_REASON_UNSAFE_CHANNEL); hdd_switch_sap_channel(adapter, restart_chan, true); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return; } else { @@ -9944,9 +11012,15 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) wlan_hdd_send_svc_nlink_msg( hdd_ctxt->radio_index, WLAN_SVC_LTE_COEX_IND, NULL, 0); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return; } } + /* dev_put has to be done here */ + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -9978,23 +11052,29 @@ static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) (uint16_t)NUM_CHANNELS); for (index = 0; index < unsafe_channel_count; index++) { - hdd_debug("channel %d is not safe", - hdd_ctx->unsafe_channel_list[index]); + hdd_debug("channel frequency %d is not safe", + hdd_ctx->unsafe_channel_list[index]); } - ucfg_policy_mgr_init_chan_avoidance(hdd_ctx->psoc, - hdd_ctx->unsafe_channel_list, - hdd_ctx->unsafe_channel_count); + ucfg_policy_mgr_init_chan_avoidance( + hdd_ctx->psoc, + (qdf_freq_t *)hdd_ctx->unsafe_channel_list, + hdd_ctx->unsafe_channel_count); } static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx) { uint8_t restart_chan; + uint32_t restart_freq; - restart_chan = wlansap_get_safe_channel_from_pcl_and_acs_range( + restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( WLAN_HDD_GET_SAP_CTX_PTR(adapter)); + + restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, + restart_freq); + if (!restart_chan) { hdd_alert("fail to restart SAP"); return; @@ -10005,7 +11085,7 @@ static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, * reset to 0. Otherwise these settings will override * the ACS while restart. */ - hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT; + hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT; hdd_debug("sending coex indication"); @@ -10113,13 +11193,14 @@ wlan_hdd_get_adapter_by_vdev_id_from_objmgr(struct hdd_context *hdd_ctx, void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) { struct hdd_context *hdd_ctx = NULL; - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; int i, num_adapters; uint8_t vdev_id[WLAN_MAX_VDEVS]; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame_ind->frameBuf; QDF_STATUS status; struct wlan_objmgr_vdev *vdev; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (wlan_hdd_validate_context(hdd_ctx)) @@ -10139,11 +11220,12 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) } } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) { num_adapters = 0; - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, + next_adapter, dbgid) { vdev_id[num_adapters] = adapter->vdev_id; num_adapters++; /* dev_put has to be done here */ - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); } adapter = NULL; @@ -10170,7 +11252,7 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) frame_ind->frame_len, frame_ind->frameBuf, frame_ind->frameType, - frame_ind->rxChan, + frame_ind->rx_freq, frame_ind->rxRssi, frame_ind->rx_flags); wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); @@ -10188,7 +11270,7 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) frame_ind->frame_len, frame_ind->frameBuf, frame_ind->frameType, - frame_ind->rxChan, + frame_ind->rx_freq, frame_ind->rxRssi, frame_ind->rx_flags); } @@ -10485,6 +11567,7 @@ static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx) errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync); if (errno) { hdd_info("psoc busy, abort idle shutdown; errno:%d", errno); + errno = -EAGAIN; goto exit; } @@ -10617,6 +11700,8 @@ static void hdd_init_wlan_logging_params(struct hdd_config *config, config->wlan_logging_to_console = cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT); + config->host_log_custom_nl_proto = + cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO); } #else static void hdd_init_wlan_logging_params(struct hdd_config *config, @@ -10678,6 +11763,20 @@ static void hdd_init_runtime_pm(struct hdd_config *config, } #endif +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI +static void hdd_init_qmi_stats(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ + config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS); +} +#else +static void hdd_init_qmi_stats(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) + +{ +} +#endif + #ifdef FEATURE_WLAN_DYNAMIC_CVM static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, struct wlan_objmgr_psoc *psoc) @@ -10751,7 +11850,6 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) { struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; struct hdd_config *config = hdd_ctx->config; - if (!psoc) { hdd_err("Invalid psoc"); return; @@ -10778,7 +11876,7 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL); config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT); config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG); - config->operating_channel = cfg_get(psoc, CFG_OPERATING_CHANNEL); + config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY); config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE); qdf_str_lcopy(config->enable_concurrent_sta, cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA), @@ -10826,6 +11924,9 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) cfg_get(psoc, CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA), ACTION_OUI_MAX_STR_LEN); + qdf_str_lcopy(config->action_oui_str[ACTION_OUI_DISABLE_TWT], + cfg_get(psoc, CFG_ACTION_OUI_DISABLE_TWT), + ACTION_OUI_MAX_STR_LEN); qdf_str_lcopy(config->action_oui_str[ACTION_OUI_HOST_RECONN], cfg_get(psoc, CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT), ACTION_OUI_MAX_STR_LEN); @@ -10848,6 +11949,7 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) hdd_init_dhcp_server_ip(hdd_ctx); hdd_dp_cfg_update(psoc, hdd_ctx); hdd_sar_cfg_update(config, psoc); + hdd_init_qmi_stats(config, psoc); } struct hdd_context *hdd_context_create(struct device *dev) @@ -10923,6 +12025,7 @@ struct hdd_context *hdd_context_create(struct device *dev) goto err_deinit_hdd_context; hdd_set_wlan_logging(hdd_ctx); + qdf_atomic_init(&hdd_ctx->adapter_ops_history.index); skip_multicast_logging: hdd_set_trace_level_for_each(hdd_ctx); @@ -10970,6 +12073,7 @@ int hdd_start_station_adapter(struct hdd_adapter *adapter) QDF_STATUS status; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); int ret; + bool reset; hdd_enter_dev(adapter->dev); if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) { @@ -10978,7 +12082,7 @@ int hdd_start_station_adapter(struct hdd_adapter *adapter) return qdf_status_to_os_return(QDF_STATUS_SUCCESS); } - ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter); + ret = hdd_vdev_create(adapter); if (ret) { hdd_err("failed to create vdev: %d", ret); return ret; @@ -10998,11 +12102,21 @@ int hdd_start_station_adapter(struct hdd_adapter *adapter) hdd_register_hl_netdev_fc_timer(adapter, hdd_tx_resume_timer_expired_handler); - status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, - adapter->vdev_id, - adapter->latency_level); - if (QDF_IS_STATUS_ERROR(status)) - hdd_warn("set latency level failed, %u", status); + status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("could not get the wlm reset flag"); + reset = false; + } + + if (!reset) { + status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, + adapter->vdev_id, + adapter->latency_level); + if (QDF_IS_STATUS_ERROR(status)) + hdd_warn("set wlm mode failed, %u", status); + else + hdd_debug("set wlm mode %d", adapter->latency_level); + } hdd_exit(); @@ -11045,12 +12159,20 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); } - ret = hdd_vdev_create(adapter, wlansap_roam_callback, - adapter->session.ap.sap_context); + ret = hdd_vdev_create(adapter); if (ret) { hdd_err("failed to create vdev, status:%d", ret); - hdd_sap_destroy_ctx(adapter); - return ret; + goto sap_destroy_ctx; + } + + status = sap_acquire_vdev_ref(hdd_ctx->psoc, + WLAN_HDD_GET_SAP_CTX_PTR(adapter), + adapter->vdev_id); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Failed to get vdev ref for sap for session_id: %u", + adapter->vdev_id); + ret = qdf_status_to_os_return(status); + goto sap_vdev_destroy; } if (adapter->device_mode == QDF_SAP_MODE) { @@ -11072,7 +12194,8 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) if (QDF_STATUS_SUCCESS != status) { hdd_err("Error Initializing the AP mode: %d", status); - return qdf_status_to_os_return(status); + ret = qdf_status_to_os_return(status); + goto sap_release_ref; } hdd_register_tx_flow_control(adapter, @@ -11085,8 +12208,17 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) hdd_exit(); return 0; + +sap_release_ref: + sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); +sap_vdev_destroy: + hdd_vdev_destroy(adapter); +sap_destroy_ctx: + hdd_sap_destroy_ctx(adapter); + return ret; } +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /** * hdd_txrx_populate_cds_config() - Populate txrx cds configuration * @cds_cfg: CDS Configuration @@ -11105,6 +12237,13 @@ static inline void hdd_txrx_populate_cds_config(struct cds_config_info /* configuration for DP RX Threads */ cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads; } +#else +static inline void hdd_txrx_populate_cds_config(struct cds_config_info + *cds_cfg, + struct hdd_context *hdd_ctx) +{ +} +#endif /** * hdd_update_cds_config() - API to update cds configuration parameters @@ -11117,6 +12256,7 @@ static int hdd_update_cds_config(struct hdd_context *hdd_ctx) struct cds_config_info *cds_cfg; int value; uint8_t band_capability; + uint32_t band_bitmap; uint8_t ito_repeat_count; bool crash_inject; bool self_recovery; @@ -11182,10 +12322,11 @@ static int hdd_update_cds_config(struct hdd_context *hdd_ctx) cds_cfg->ito_repeat_count = ito_repeat_count; - status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); + status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); if (QDF_IS_STATUS_ERROR(status)) goto exit; + band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); cds_cfg->bandcapability = band_capability; cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs; cds_cfg->enable_tx_compl_tsf64 = @@ -11211,10 +12352,11 @@ static int hdd_update_user_config(struct hdd_context *hdd_ctx) { struct wlan_objmgr_psoc_user_config *user_config; uint8_t band_capability; + uint32_t band_bitmap; QDF_STATUS status; bool value = false; - status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); + status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); if (QDF_IS_STATUS_ERROR(status)) return -EIO; @@ -11233,6 +12375,7 @@ static int hdd_update_user_config(struct hdd_context *hdd_ctx) if (!QDF_IS_STATUS_SUCCESS(status)) hdd_err("Invalid 11h_enable flag"); user_config->is_11h_support_enabled = value; + band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); user_config->band_capability = band_capability; wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config); @@ -11550,7 +12693,7 @@ void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num) macaddr_b3 ^= (1 << INTF_MACADDR_MASK); buf[0] |= 0x02; buf[3] = macaddr_b3; - hdd_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(buf)); + hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf)); hdd_ctx->num_derived_addr++; } } @@ -11590,8 +12733,8 @@ static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) { buf = hdd_ctx->provisioned_mac_addr[iter].bytes; qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); - hdd_info("provisioned MAC Addr [%d]" QDF_MAC_ADDR_STR, iter, - QDF_MAC_ADDR_ARRAY(buf)); + hdd_info("provisioned MAC Addr [%d]" QDF_MAC_ADDR_FMT, iter, + QDF_MAC_ADDR_REF(buf)); } @@ -11612,8 +12755,8 @@ static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) addr += mac_addr_size) { buf = hdd_ctx->derived_mac_addr[iter].bytes; qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); - hdd_debug("derived MAC Addr [%d]" QDF_MAC_ADDR_STR, iter, - QDF_MAC_ADDR_ARRAY(buf)); + hdd_debug("derived MAC Addr [%d]" QDF_MAC_ADDR_FMT, iter, + QDF_MAC_ADDR_REF(buf)); } hdd_ctx->num_derived_addr = no_of_mac_addr; } @@ -11803,7 +12946,9 @@ static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx) cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb); /* Register HL netdev flow control callback */ - cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb); + cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb); + /* Register rx mic error indication handler */ + cdp_register_rx_mic_error_ind_handler(soc, hdd_rx_mic_error_ind); /* * Note that the cds_pre_enable() sequence triggers the cfg download. @@ -12308,7 +13453,7 @@ static void hdd_v2_flow_pool_map(int vdev_id) QDF_STATUS status; status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), + OL_TXRX_PDEV_ID, vdev_id); /* * For Adrastea flow control v2 is based on FW MAP events, @@ -12331,7 +13476,7 @@ static void hdd_v2_flow_pool_map(int vdev_id) static void hdd_v2_flow_pool_unmap(int vdev_id) { cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), vdev_id); + OL_TXRX_PDEV_ID, vdev_id); } /** @@ -12417,6 +13562,7 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx) bool value; enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode; bool bval = false; + qdf_device_t qdf_ctx; mac_handle = hdd_ctx->mac_handle; @@ -12513,8 +13659,14 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx) * IPA module before configuring them to FW. Sequence required as crash * observed otherwise. */ - if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev, - cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) { + + qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + if (!qdf_ctx) { + hdd_err("QDF device context is NULL"); + goto out; + } + + if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev, qdf_ctx)) { hdd_err("Failed to setup pipes"); goto out; } @@ -12547,7 +13699,8 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx) /* Donot disable rx offload on concurrency for lithium based targets */ if (!(hdd_ctx->target_type == TARGET_TYPE_QCA6290 || - hdd_ctx->target_type == TARGET_TYPE_QCA6390)) + hdd_ctx->target_type == TARGET_TYPE_QCA6390 || + hdd_ctx->target_type == TARGET_TYPE_QCA6490)) if (hdd_ctx->ol_enable) dp_cbs.hdd_disable_rx_ol_in_concurrency = hdd_disable_rx_ol_in_concurrency; @@ -12593,6 +13746,7 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx) hdd_hastings_bt_war_initialize(hdd_ctx); + wlan_hdd_hang_event_notifier_register(hdd_ctx); return 0; cds_disable: @@ -12617,6 +13771,7 @@ static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx) hdd_enter(); + wlan_hdd_hang_event_notifier_unregister(); /* De-init features */ hdd_features_deinit(hdd_ctx); @@ -12690,6 +13845,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) } } + hdd_bus_bw_compute_timer_stop(hdd_ctx); hdd_deregister_policy_manager_callback(hdd_ctx->psoc); /* free user wowl patterns */ @@ -12705,19 +13861,15 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) case DRIVER_MODULES_ENABLED: hdd_debug("Wlan transitioning (CLOSED <- ENABLED)"); - if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { - hdd_disable_power_management(hdd_ctx); - break; - } - - if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE || + hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) break; wlan_hdd_deinit_tx_rx_histogram(hdd_ctx); hdd_skip_acs_scan_timer_deinit(hdd_ctx); - hdd_disable_power_management(hdd_ctx); + hdd_disable_power_management(); if (hdd_deconfigure_cds(hdd_ctx)) { hdd_err("Failed to de-configure CDS"); QDF_ASSERT(0); @@ -12733,13 +13885,13 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) goto done; } + hdd_sysfs_dp_aggregation_destroy(); hdd_sysfs_destroy_powerstats_interface(); hdd_sysfs_destroy_version_interface(); hdd_sysfs_destroy_driver_root_obj(); hdd_debug("Closing CDS modules!"); if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) { - wma_release_pending_vdev_refs(); qdf_status = cds_post_disable(); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("Failed to process post CDS disable! :%d", @@ -12782,6 +13934,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) hdd_err("Failed to destroy pdev; errno:%d", ret); QDF_ASSERT(0); } + wlan_global_lmac_if_close(hdd_ctx->psoc); } /* @@ -12833,13 +13986,16 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) wlan_hdd_free_sar_config(hdd_ctx); hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop); + hdd_sta_destroy_ctx_all(hdd_ctx); pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE); + hdd_deinit_adapter_ops_wq(hdd_ctx); hdd_bus_bandwidth_deinit(hdd_ctx); hdd_check_for_leaks(hdd_ctx, is_recovery_stop); hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); /* Once the firmware sequence is completed reset this flag */ hdd_ctx->imps_enabled = false; + hdd_ctx->is_dual_mac_cfg_updated = false; hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; hdd_debug("Wlan transitioned (now CLOSED)"); @@ -12865,9 +14021,10 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) { struct hdd_context *hdd_ctx; struct hdd_station_ctx *hdd_sta_ctx; - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; uint16_t len = 0; char *buf = *buf_ptr; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -12883,10 +14040,12 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) "\n is_scheduler_suspended %d", hdd_ctx->is_scheduler_suspended); - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter->dev) len += scnprintf(buf + len, *size - len, - "\n device name: %s", adapter->dev->name); + "\n device name: %s", + adapter->dev->name); len += scnprintf(buf + len, *size - len, "\n device_mode: %d", adapter->device_mode); switch (adapter->device_mode) { @@ -12901,6 +14060,7 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) default: break; } + hdd_adapter_dev_put_debug(adapter, dbgid); } *size -= len; @@ -12950,7 +14110,7 @@ void hdd_dp_trace_init(struct hdd_config *config) uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH; uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT; uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY; - uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP; + uint32_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP; uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS]; uint8_t num_entries = 0; uint32_t bw_compute_interval; @@ -13104,6 +14264,9 @@ static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) "p2p%d", hdd_ctx->p2p_device_address.bytes); if (QDF_IS_STATUS_ERROR(status)) { + if (!is_p2p_locally_administered) + wlan_hdd_release_intf_addr(hdd_ctx, + hdd_ctx->p2p_device_address.bytes); hdd_err("Failed to open p2p interface"); return QDF_STATUS_E_INVAL; } @@ -13123,10 +14286,15 @@ static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx) uint8_t *mac_addr; mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE); + if (!mac_addr) + return QDF_STATUS_E_INVAL; + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE, "wlanocb%d", mac_addr); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); hdd_err("Failed to open 802.11p interface"); + } return status; } @@ -13142,10 +14310,15 @@ static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx) iface_name = hdd_ctx->config->enable_concurrent_sta; mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); + if (!mac_addr) + return QDF_STATUS_E_INVAL; + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, iface_name, mac_addr); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); hdd_err("Failed to open concurrent station interface"); + } return status; } @@ -13164,10 +14337,15 @@ hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) return hdd_open_ocb_interface(hdd_ctx); mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); + if (!mac_addr) + return QDF_STATUS_E_INVAL; + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, "wlan%d", mac_addr); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); return status; + } /* opening concurrent STA is best effort, continue on error */ hdd_open_concurrent_interface(hdd_ctx); @@ -13182,10 +14360,15 @@ hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) */ if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) { mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE); + if (!mac_addr) + goto err_close_adapters; + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE, "wifi-aware%d", mac_addr); - if (status) + if (status) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); goto err_close_adapters; + } } /* Open 802.11p Interface */ if (dot11p_mode == CFG_11P_CONCURRENT) { @@ -13204,19 +14387,43 @@ hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx) { - uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); + QDF_STATUS status; + uint8_t *mac_addr; + + mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); + if (!mac_addr) + return QDF_STATUS_E_INVAL; + + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, + "wlan%d", mac_addr); - return hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, - "wlan%d", mac_addr); + if (QDF_IS_STATUS_ERROR(status)) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); + return status; + } + + return QDF_STATUS_SUCCESS; } static QDF_STATUS hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx) { - uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); + QDF_STATUS status; + uint8_t *mac_addr; + + mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); + if (!mac_addr) + return QDF_STATUS_E_INVAL; + + status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, + "wlan%d", mac_addr); + + if (QDF_IS_STATUS_ERROR(status)) { + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); + return status; + } - return hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, - "wlan%d", mac_addr); + return QDF_STATUS_SUCCESS; } static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx) @@ -13277,6 +14484,8 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx) osif_request_manager_init(); hdd_driver_memdump_init(); + hdd_dp_trace_init(hdd_ctx->config); + errno = hdd_wlan_start_modules(hdd_ctx, false); if (errno) { hdd_err("Failed to start modules; errno:%d", errno); @@ -13300,8 +14509,6 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx) goto stop_modules; } - hdd_dp_trace_init(hdd_ctx->config); - errno = hdd_initialize_mac_address(hdd_ctx); if (errno) { hdd_err("MAC initializtion failed: %d", errno); @@ -13371,7 +14578,8 @@ QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) if (hdd_ctx->rps) hdd_set_rps_cpu_mask(hdd_ctx); - if (driver_mode != QDF_GLOBAL_FTM_MODE) + if (driver_mode != QDF_GLOBAL_FTM_MODE && + driver_mode != QDF_GLOBAL_EPPING_MODE) hdd_psoc_idle_timer_start(hdd_ctx); return QDF_STATUS_SUCCESS; @@ -13475,15 +14683,13 @@ QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) { struct hdd_adapter *adapter = NULL; struct hdd_context *hdd_ctx; - QDF_STATUS status; struct sme_motion_det_en motion_det; if (!ctx || !event) return QDF_STATUS_E_INVAL; hdd_ctx = (struct hdd_context *)ctx; - status = wlan_hdd_validate_context(hdd_ctx); - if (0 != status) + if (wlan_hdd_validate_context(hdd_ctx)) return QDF_STATUS_E_INVAL; adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id); @@ -13492,6 +14698,10 @@ QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) return QDF_STATUS_E_INVAL; } + /* When motion is detected, reset the motion_det_in_progress flag */ + if (event->status) + adapter->motion_det_in_progress = false; + hdd_debug("Motion Detection CB vdev_id=%u, status=%u", event->vdev_id, event->status); @@ -13504,6 +14714,42 @@ QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) return QDF_STATUS_SUCCESS; } + +/** + * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event + * @ctx: HDD context + * @event: motion detect baseline event + * + * Callback for Motion Detection Baseline completion + * + * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and + * QDF_STATUS_E_FAILURE on failure + */ +QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event) +{ + struct hdd_adapter *adapter = NULL; + struct hdd_context *hdd_ctx; + + if (!ctx || !event) + return QDF_STATUS_E_INVAL; + + hdd_ctx = (struct hdd_context *)ctx; + if (wlan_hdd_validate_context(hdd_ctx)) + return QDF_STATUS_E_INVAL; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id); + if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) { + hdd_err("Invalid adapter or adapter has invalid magic"); + return QDF_STATUS_E_INVAL; + } + + hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d", + event->vdev_id, event->bl_baseline_value); + + adapter->motion_det_baseline_value = event->bl_baseline_value; + + return QDF_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_MOTION_DETECTION */ /** @@ -13576,11 +14822,6 @@ int hdd_register_cb(struct hdd_context *hdd_ctx) hdd_set_connection_in_progress, hdd_is_connection_in_progress); - status = sme_congestion_register_callback(mac_handle, - hdd_update_cca_info_cb); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("set congestion callback failed"); - status = sme_set_bt_activity_info_cb(mac_handle, hdd_bt_activity_cb); if (!QDF_IS_STATUS_SUCCESS(status)) @@ -13593,10 +14834,18 @@ int hdd_register_cb(struct hdd_context *hdd_ctx) #ifdef WLAN_FEATURE_MOTION_DETECTION sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx); + sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx); #endif /* WLAN_FEATURE_MOTION_DETECTION */ - sme_set_oem_data_event_handler_cb(mac_handle, hdd_oem_event_handler_cb); + mac_register_sesssion_open_close_cb(hdd_ctx->mac_handle, + hdd_sme_close_session_callback, + hdd_common_roam_callback); + sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); + status = sme_set_monitor_mode_cb(mac_handle, + hdd_sme_monitor_mode_callback); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err_rl("Register monitor mode callback failed"); hdd_exit(); @@ -13625,8 +14874,6 @@ void hdd_deregister_cb(struct hdd_context *hdd_ctx) mac_handle = hdd_ctx->mac_handle; - sme_reset_oem_data_event_handler_cb(mac_handle); - sme_deregister_tx_queue_cb(mac_handle); sme_reset_link_layer_stats_ind_cb(mac_handle); @@ -13702,14 +14949,16 @@ void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter, uint32_t mlme_operation_requestor) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter); - struct hdd_adapter *adapter = NULL; struct csr_roam_profile *roam_profile; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING; if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) return; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { roam_profile = hdd_roam_profile(adapter); sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -13722,6 +14971,7 @@ void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter, REASON_DRIVER_DISABLED, mlme_operation_requestor); } + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -13729,14 +14979,16 @@ void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter, uint32_t mlme_operation_requestor) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter); - struct hdd_adapter *adapter = NULL; struct csr_roam_profile *roam_profile; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ENABLE_ROAMING; if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) return; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { roam_profile = hdd_roam_profile(adapter); sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -13749,6 +15001,7 @@ void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter, REASON_DRIVER_ENABLED, mlme_operation_requestor); } + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -13870,9 +15123,10 @@ void wlan_hdd_auto_shutdown_cb(void) void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; bool ap_connected = false, sta_connected = false; mac_handle_t mac_handle; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE; mac_handle = hdd_ctx->mac_handle; if (!mac_handle) @@ -13893,12 +15147,19 @@ void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) /* To enable shutdown timer check conncurrency */ if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) { - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, + next_adapter, dbgid) { if (adapter->device_mode == QDF_STA_MODE) { if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)-> conn_info.conn_state == eConnectionState_Associated) { sta_connected = true; + hdd_adapter_dev_put_debug(adapter, + dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug( + next_adapter, + dbgid); break; } } @@ -13907,9 +15168,16 @@ void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) if (WLAN_HDD_GET_AP_CTX_PTR(adapter)-> ap_active == true) { ap_connected = true; + hdd_adapter_dev_put_debug(adapter, + dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug( + next_adapter, + dbgid); break; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } } @@ -13933,11 +15201,13 @@ hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, bool check_start_bss) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter); - struct hdd_adapter *adapter, *con_sap_adapter; + struct hdd_adapter *adapter, *con_sap_adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER; con_sap_adapter = NULL; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (adapter && ((adapter->device_mode == QDF_SAP_MODE) || (adapter->device_mode == QDF_P2P_GO_MODE)) && adapter != this_sap_adapter) { @@ -13945,19 +15215,29 @@ hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { con_sap_adapter = adapter; + hdd_adapter_dev_put_debug(adapter, + dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug( + next_adapter, + dbgid); break; } } else { con_sap_adapter = adapter; + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); break; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } return con_sap_adapter; } -#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter) { return adapter->device_mode == QDF_STA_MODE || @@ -13970,31 +15250,48 @@ static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter) adapter->device_mode == QDF_P2P_GO_MODE; } -static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx) +bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { if (hdd_adapter_is_sta(adapter) && WLAN_HDD_GET_STATION_CTX_PTR(adapter)-> conn_info.conn_state == eConnectionState_Associated) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } if (hdd_adapter_is_ap(adapter) && WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; } if (adapter->device_mode == QDF_NDI_MODE && WLAN_HDD_GET_STATION_CTX_PTR(adapter)-> - conn_info.conn_state == eConnectionState_NdiConnected) + conn_info.conn_state == eConnectionState_NdiConnected) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return true; + } + hdd_adapter_dev_put_debug(adapter, dbgid); } return false; } +#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx) { qdf_periodic_work_start(&hdd_ctx->bus_bw_work, @@ -14014,7 +15311,7 @@ void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx) { hdd_enter(); - if (hdd_any_adapter_is_assoc(hdd_ctx)) + if (hdd_is_any_adapter_connected(hdd_ctx)) __hdd_bus_bw_compute_timer_start(hdd_ctx); hdd_exit(); @@ -14023,11 +15320,28 @@ void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx) static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx) { if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work)) - return; + goto exit; ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0); hdd_reset_tcp_delack(hdd_ctx); hdd_reset_tcp_adv_win_scale(hdd_ctx); + cdp_pdev_reset_driver_del_ack(cds_get_context(QDF_MODULE_ID_SOC), + OL_TXRX_PDEV_ID); + cdp_pdev_reset_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC), + OL_TXRX_PDEV_ID); + +exit: + /** + * This check if for the case where the bus bw timer is forcibly + * stopped. We should remove the bus bw voting, if no adapter is + * connected + */ + if (!hdd_is_any_adapter_connected(hdd_ctx)) { + qdf_atomic_set(&hdd_ctx->num_latency_critical_clients, 0); + hdd_ctx->cur_vote_level = PLD_BUS_WIDTH_NONE; + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_NONE); + } } void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx) @@ -14043,7 +15357,7 @@ void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx) { hdd_enter(); - if (!hdd_any_adapter_is_assoc(hdd_ctx)) + if (!hdd_is_any_adapter_connected(hdd_ctx)) __hdd_bus_bw_compute_timer_stop(hdd_ctx); hdd_exit(); @@ -14056,6 +15370,7 @@ void hdd_bus_bw_compute_prev_txrx_stats(struct hdd_adapter *adapter) qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock); adapter->prev_tx_packets = adapter->stats.tx_packets; adapter->prev_rx_packets = adapter->stats.rx_packets; + adapter->prev_tx_bytes = adapter->stats.tx_bytes; cdp_get_intra_bss_fwd_pkts_count(cds_get_context(QDF_MODULE_ID_SOC), adapter->vdev_id, &adapter->prev_fwd_tx_packets, @@ -14072,6 +15387,7 @@ void hdd_bus_bw_compute_reset_prev_txrx_stats(struct hdd_adapter *adapter) adapter->prev_rx_packets = 0; adapter->prev_fwd_tx_packets = 0; adapter->prev_fwd_rx_packets = 0; + adapter->prev_tx_bytes = 0; qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock); } @@ -14171,9 +15487,10 @@ void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit) hdd_err("SAP Not able to set AP IEs"); goto end; } - wlan_reg_set_channel_params(hdd_ctx->pdev, - hdd_ap_ctx->sap_config.channel, 0, - &hdd_ap_ctx->sap_config.ch_params); + wlan_reg_set_channel_params_for_freq( + hdd_ctx->pdev, + hdd_ap_ctx->sap_config.chan_freq, + 0, &hdd_ap_ctx->sap_config.ch_params); qdf_event_reset(&hostapd_state->qdf_event); if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb, @@ -14183,7 +15500,7 @@ void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit) goto end; hdd_debug("Waiting for SAP to start"); - qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, + qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, SME_CMD_START_BSS_TIMEOUT); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("SAP Start failed"); @@ -14209,7 +15526,11 @@ void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit) * in hdd_stop_adapter */ hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again"); - + /* Free the beacon memory in case of failure in the sap restart */ + if (ap_adapter->session.ap.beacon) { + qdf_mem_free(ap_adapter->session.ap.beacon); + ap_adapter->session.ap.beacon = NULL; + } } #ifdef QCA_CONFIG_SMP @@ -14322,6 +15643,38 @@ void hdd_deinit(void) #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000) #endif +static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; + int ret; + QDF_STATUS qdf_status; + uint8_t latency_level; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) + return; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return; + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, + &latency_level); + if (QDF_IS_STATUS_ERROR(qdf_status)) + adapter->latency_level = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + else + adapter->latency_level = latency_level; + + adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; + hdd_debug("UDP packets qos reset to: %d", + adapter->upgrade_udp_qos_threshold); + hdd_adapter_dev_put_debug(adapter, dbgid); + } +} + static int wlan_hdd_state_ctrl_param_open(struct inode *inode, struct file *file) { @@ -14357,6 +15710,7 @@ static void hdd_inform_wifi_off(void) if (ret) return; + hdd_set_adapter_wlm_def_level(hdd_ctx); __hdd_inform_wifi_off(); osif_psoc_sync_op_stop(psoc_sync); @@ -14367,6 +15721,36 @@ void hdd_init_start_completion(void) INIT_COMPLETION(wlan_start_comp); } +#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) +static void hdd_inform_wifi_on(void) +{ + int ret; + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + struct osif_psoc_sync *psoc_sync; + + hdd_nofl_debug("inform regdomain for wifi on"); + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return; + if (!wlan_hdd_validate_modules_state(hdd_ctx)) + return; + if (!hdd_ctx->wiphy) + return; + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return; + if (hdd_ctx->wiphy->registered) + hdd_send_wiphy_regd_sync_event(hdd_ctx); + + osif_psoc_sync_op_stop(psoc_sync); +} +#else +static void hdd_inform_wifi_on(void) +{ +} +#endif + static int hdd_driver_load(void); static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, const char __user *user_buf, @@ -14379,6 +15763,7 @@ static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, int ret; unsigned long rc; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + bool turning_on = false; if (copy_from_user(buf, user_buf, 3)) { pr_err("Failed to read buffer\n"); @@ -14386,13 +15771,15 @@ static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, } if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) { - pr_debug("Wifi turning off from UI\n"); + hdd_info("Wifi turning off from UI\n"); hdd_inform_wifi_off(); goto exit; } - if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0) - pr_info("Wifi Turning On from UI\n"); + if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0) { + hdd_info("Wifi Turning On from UI\n"); + turning_on = true; + } if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) { pr_err("Invalid value received from framework"); @@ -14422,8 +15809,10 @@ static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, */ if (hdd_ctx) hdd_psoc_idle_timer_stop(hdd_ctx); - exit: + if (turning_on) + hdd_inform_wifi_on(); + return count; } @@ -14599,13 +15988,18 @@ static QDF_STATUS hdd_component_init(void) if (QDF_IS_STATUS_ERROR(status)) goto blm_deinit; + status = ucfg_ftm_timesync_init(); + if (QDF_IS_STATUS_ERROR(status)) + goto pkt_capture_deinit; + return QDF_STATUS_SUCCESS; +pkt_capture_deinit: + ucfg_pkt_capture_deinit(); blm_deinit: ucfg_blm_deinit(); tdls_deinit: ucfg_tdls_deinit(); - policy_deinit: policy_mgr_deinit(); interop_issues_ap_deinit: @@ -14646,6 +16040,7 @@ static QDF_STATUS hdd_component_init(void) static void hdd_component_deinit(void) { /* deinitialize non-converged components */ + ucfg_ftm_timesync_deinit(); ucfg_pkt_capture_deinit(); ucfg_blm_deinit(); ucfg_tdls_deinit(); @@ -15127,6 +16522,13 @@ static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx, con_mode = next_mode; hdd_info("Driver mode successfully changed to %d", next_mode); + if (con_mode == QDF_GLOBAL_FTM_MODE) + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_VERY_HIGH); + else if (con_mode == QDF_GLOBAL_MISSION_MODE) + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_NONE); + return 0; } @@ -15341,183 +16743,57 @@ static void hdd_driver_unload(void) * Trigger runtime sync resume before setting unload in progress * such that resume can happen successfully */ - hif_pm_runtime_sync_resume(hif_ctx); - } - - cds_set_driver_loaded(false); - cds_set_unload_in_progress(true); - - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (hdd_ctx) { - hdd_psoc_idle_timer_stop(hdd_ctx); - /* - * Runtime PM sync resume may have started the bus bandwidth - * periodic work hence stop it. - */ - hdd_bus_bw_compute_timer_stop(hdd_ctx); - } - - /* - * Stop the trans before calling unregister_driver as that involves a - * call to pld_remove which in itself is a psoc transaction - */ - osif_driver_sync_trans_stop(driver_sync); - - /* trigger SoC remove */ - wlan_hdd_unregister_driver(); - - status = osif_driver_sync_trans_start_wait(&driver_sync); - QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Unable to unload wlan; status:%u", status); - return; - } - - osif_driver_sync_unregister(); - osif_driver_sync_wait_for_ops(driver_sync); - - hdd_driver_mode_change_unregister(); - pld_deinit(); - wlan_hdd_state_ctrl_param_destroy(); - hdd_set_conparam(0); - qdf_wake_lock_destroy(&wlan_wake_lock); - hdd_component_deinit(); - hdd_deinit(); - - osif_driver_sync_trans_stop(driver_sync); - osif_driver_sync_destroy(driver_sync); - - osif_sync_deinit(); - - hdd_qdf_deinit(); -} - -#if 0 -/** - * wlan_boot_cb() - Wlan boot callback - * @kobj: object whose directory we're creating the link in. - * @attr: attribute the user is interacting with - * @buff: the buffer containing the user data - * @count: number of bytes in the buffer - * - * This callback is invoked when the fs is ready to start the - * wlan driver initialization. - * - * Return: 'count' on success or a negative error code in case of failure - */ -static ssize_t wlan_boot_cb(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, - size_t count) -{ - - if (wlan_loader->loaded_state) { - hdd_err("wlan driver already initialized"); - return -EALREADY; - } - - if (hdd_driver_load()) - return -EIO; - - wlan_loader->loaded_state = MODULE_INITIALIZED; - - return count; -} - -/** - * hdd_sysfs_cleanup() - cleanup sysfs - * - * Return: None - * - */ -static void hdd_sysfs_cleanup(void) -{ - /* remove from group */ - if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) - sysfs_remove_group(wlan_loader->boot_wlan_obj, - wlan_loader->attr_group); - - /* unlink the object from parent */ - kobject_del(wlan_loader->boot_wlan_obj); - - /* free the object */ - kobject_put(wlan_loader->boot_wlan_obj); - - kfree(wlan_loader->attr_group); - kfree(wlan_loader); - - wlan_loader = NULL; -} - -/** - * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is - * ready - * - * This is creates the syfs entry boot_wlan. Which shall be invoked - * when the filesystem is ready. - * - * QDF API cannot be used here since this function is called even before - * initializing WLAN driver. - * - * Return: 0 for success, errno on failure - */ -static int wlan_init_sysfs(void) -{ - int ret = -ENOMEM; + hif_pm_runtime_sync_resume(hif_ctx); + } - wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); - if (!wlan_loader) - return -ENOMEM; + cds_set_driver_loaded(false); + cds_set_unload_in_progress(true); - wlan_loader->boot_wlan_obj = NULL; - wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)), - GFP_KERNEL); - if (!wlan_loader->attr_group) - goto error_return; + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (hdd_ctx) { + hdd_psoc_idle_timer_stop(hdd_ctx); + /* + * Runtime PM sync resume may have started the bus bandwidth + * periodic work hence stop it. + */ + hdd_bus_bw_compute_timer_stop(hdd_ctx); + } - wlan_loader->loaded_state = 0; - wlan_loader->attr_group->attrs = attrs; + /* + * Stop the trans before calling unregister_driver as that involves a + * call to pld_remove which in itself is a psoc transaction + */ + osif_driver_sync_trans_stop(driver_sync); - wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME, - kernel_kobj); - if (!wlan_loader->boot_wlan_obj) { - hdd_err("sysfs create and add failed"); - goto error_return; - } + /* trigger SoC remove */ + wlan_hdd_unregister_driver(); - ret = sysfs_create_group(wlan_loader->boot_wlan_obj, - wlan_loader->attr_group); - if (ret) { - hdd_err("sysfs create group failed; errno:%d", ret); - goto error_return; + status = osif_driver_sync_trans_start_wait(&driver_sync); + QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Unable to unload wlan; status:%u", status); + return; } - return 0; + osif_driver_sync_unregister(); + osif_driver_sync_wait_for_ops(driver_sync); -error_return: - hdd_sysfs_cleanup(); + hdd_driver_mode_change_unregister(); + pld_deinit(); + wlan_hdd_state_ctrl_param_destroy(); + hdd_set_conparam(0); + qdf_wake_lock_destroy(&wlan_wake_lock); + hdd_component_deinit(); + hdd_deinit(); - return ret; -} + osif_driver_sync_trans_stop(driver_sync); + osif_driver_sync_destroy(driver_sync); -/** - * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan - * - * Return: 0 on success or errno on failure - */ -static int wlan_deinit_sysfs(void) -{ - if (!wlan_loader) { - hdd_err("wlan_loader is null"); - return -EINVAL; - } + osif_sync_deinit(); - hdd_sysfs_cleanup(); - return 0; + hdd_qdf_deinit(); } -#endif /* MODULE */ - /** * hdd_module_init() - Module init helper * @@ -15642,6 +16918,22 @@ void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx) } +/** + * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace + * + * Return: void + */ +static void hdd_svc_fw_crashed_ind(void) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + + hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, + WLAN_SVC_FW_CRASHED_IND, + NULL, 0) : 0; +} + /** * hdd_update_ol_config - API to update ol configuration parameters * @hdd_ctx: HDD context @@ -15669,6 +16961,7 @@ static void hdd_update_ol_config(struct hdd_context *hdd_ctx) cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); ol_init_ini_config(ol_ctx, &cfg); + ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); } #ifdef FEATURE_RUNTIME_PM @@ -15759,6 +17052,25 @@ void hdd_update_dp_config_rx_softirq_limits(struct hdd_context *hdd_ctx, } #endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */ +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) +static void +hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx, + struct cdp_config_params *params) +{ + params->tx_flow_stop_queue_threshold = + cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); + params->tx_flow_start_queue_offset = + cfg_get(hdd_ctx->psoc, + CFG_DP_TX_FLOW_START_QUEUE_OFFSET); +} +#else +static inline void +hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx, + struct cdp_config_params *params) +{ +} +#endif + /** * hdd_update_dp_config() - Propagate config parameters to Lithium * datapath @@ -15775,14 +17087,16 @@ static int hdd_update_dp_config(struct hdd_context *hdd_ctx) soc = cds_get_context(QDF_MODULE_ID_SOC); params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO); params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO); - params.tx_flow_stop_queue_threshold = - cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); - params.tx_flow_start_queue_offset = - cfg_get(hdd_ctx->psoc, - CFG_DP_TX_FLOW_START_QUEUE_OFFSET); + hdd_update_dp_config_queue_threshold(hdd_ctx, ¶ms); params.flow_steering_enable = cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED); params.napi_enable = hdd_ctx->napi_enable; + params.p2p_tcp_udp_checksumoffload = + cfg_get(hdd_ctx->psoc, + CFG_DP_P2P_TCP_UDP_CKSUM_OFFLOAD); + params.nan_tcp_udp_checksumoffload = + cfg_get(hdd_ctx->psoc, + CFG_DP_NAN_TCP_UDP_CKSUM_OFFLOAD); params.tcp_udp_checksumoffload = cfg_get(hdd_ctx->psoc, CFG_DP_TCP_UDP_CKSUM_OFFLOAD); @@ -16192,10 +17506,10 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator( void *ctx) { struct hdd_station_ctx *hdd_sta_ctx; - uint8_t sta_id = 0; uint8_t *sta_mac; struct hdd_context *hdd_ctx; mac_handle_t mac_handle; + struct hdd_station_info *sta_info; struct hdd_is_connection_in_progress_priv *context = ctx; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); @@ -16230,7 +17544,7 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator( sme_neighbor_middle_of_roaming( mac_handle, adapter->vdev_id)) || - hdd_is_roaming_in_progress(hdd_ctx)) { + hdd_is_roaming_in_progress(hdd_ctx)) { hdd_debug("%pK(%d) mode %d Reassociation in progress", WLAN_HDD_GET_STATION_CTX_PTR(adapter), adapter->vdev_id, adapter->device_mode); @@ -16251,9 +17565,9 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator( && sme_is_sta_key_exchange_in_progress( mac_handle, adapter->vdev_id)) { sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]); - hdd_debug("client " QDF_MAC_ADDR_STR + hdd_debug("client " QDF_MAC_ADDR_FMT " is in middle of WPS/EAPOL exchange.", - QDF_MAC_ADDR_ARRAY(sta_mac)); + QDF_MAC_ADDR_REF(sta_mac)); context->out_vdev_id = adapter->vdev_id; context->out_reason = EAPOL_IN_PROGRESS; @@ -16263,23 +17577,29 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator( } } else if ((QDF_SAP_MODE == adapter->device_mode) || (QDF_P2P_GO_MODE == adapter->device_mode)) { - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - if (!((adapter->sta_info[sta_id].in_use) - && (OL_TXRX_PEER_STATE_CONN == - adapter->sta_info[sta_id].peer_state))) + hdd_for_each_sta_ref(adapter->sta_info_list, sta_info, + STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) { + if (sta_info->peer_state != + OL_TXRX_PEER_STATE_CONN) { + hdd_put_sta_info_ref( + &adapter->sta_info_list, &sta_info, true, + STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); continue; + } - sta_mac = (uint8_t *) - &(adapter->sta_info[sta_id]. - sta_mac.bytes[0]); - hdd_debug("client " QDF_MAC_ADDR_STR + sta_mac = sta_info->sta_mac.bytes; + hdd_debug("client " QDF_MAC_ADDR_FMT " of SAP/GO is in middle of WPS/EAPOL exchange", - QDF_MAC_ADDR_ARRAY(sta_mac)); + QDF_MAC_ADDR_REF(sta_mac)); context->out_vdev_id = adapter->vdev_id; context->out_reason = SAP_EAPOL_IN_PROGRESS; context->connection_in_progress = true; + hdd_put_sta_info_ref( + &adapter->sta_info_list, &sta_info, true, + STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); + return QDF_STATUS_E_ABORTED; } if (hdd_ctx->connection_in_progress) { @@ -16387,7 +17707,7 @@ void hdd_restart_sap(struct hdd_adapter *ap_adapter) hdd_info("Waiting for SAP to start"); qdf_status = - qdf_wait_for_event_completion(&hostapd_state->qdf_event, + qdf_wait_single_event(&hostapd_state->qdf_event, SME_CMD_START_BSS_TIMEOUT); wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); @@ -16424,6 +17744,7 @@ void hdd_check_and_restart_sap_with_non_dfs_acs(void) struct hdd_context *hdd_ctx; struct cds_context *cds_ctx; uint8_t restart_chan; + uint32_t restart_freq; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -16446,18 +17767,22 @@ void hdd_check_and_restart_sap_with_non_dfs_acs(void) ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE); if (ap_adapter && test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) && - wlan_reg_is_dfs_ch(hdd_ctx->pdev, - ap_adapter->session.ap.operating_channel)) { + wlan_reg_is_dfs_for_freq( + hdd_ctx->pdev, + ap_adapter->session.ap.operating_chan_freq)) { if (policy_mgr_get_dfs_master_dynamic_enabled( hdd_ctx->psoc, ap_adapter->vdev_id)) return; hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS"); - restart_chan = + restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter)); + + restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, + restart_freq); if (!restart_chan || - wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan)) + wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, restart_freq)) restart_chan = SAP_DEFAULT_5GHZ_CHANNEL; wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->vdev_id, CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS); @@ -16647,92 +17972,8 @@ void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) wlan_hdd_enable_roaming(adapter, RSO_START_BSS); } -#ifdef FEATURE_MONITOR_MODE_SUPPORT - -void hdd_set_sme_monitor_mode_cb(enum QDF_OPMODE device_mode, - struct sme_session_params *session_param) -{ - if (device_mode == QDF_MONITOR_MODE) - session_param->session_monitor_mode_cb = - hdd_sme_monitor_mode_callback; -} - -void hdd_sme_monitor_mode_callback(uint8_t vdev_id) -{ - struct hdd_adapter *adapter; - struct hdd_context *hdd_ctx; - - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (!hdd_ctx) { - hdd_err_rl("Invalid HDD_CTX"); - return; - } - - adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); - if (!adapter) { - hdd_err_rl("NULL adapter"); - return; - } - - if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { - hdd_err_rl("Invalid magic"); - return; - } - - if (adapter->magic == WLAN_HDD_ADAPTER_MAGIC) - qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); - - hdd_debug("monitor mode vdev up completed"); - adapter->monitor_mode_vdev_up_in_progress = false; -} - -QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, - uint8_t session_type) -{ - QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - - if (session_type == QDF_MONITOR_MODE) { - qdf_status = qdf_event_create( - &adapter->qdf_monitor_mode_vdev_up_event); - } - return qdf_status; -} - -QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - - if (!adapter->monitor_mode_vdev_up_in_progress) - return status; - - /* block on a completion variable until vdev up success*/ - status = qdf_wait_for_event_completion( - &adapter->qdf_monitor_mode_vdev_up_event, - WLAN_MONITOR_MODE_VDEV_UP_EVT); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err_rl("monitor mode vdev up event time out vdev id: %d", - adapter->vdev_id); - if (adapter->qdf_monitor_mode_vdev_up_event.force_set) - /* - * SSR/PDR has caused shutdown, which has - * forcefully set the event. - */ - hdd_err_rl("monitor mode vdev up event forcefully set"); - else if (status == QDF_STATUS_E_TIMEOUT) - hdd_err_rl("monitor mode vdev up event timed out"); - else - hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", - status); - - adapter->monitor_mode_vdev_up_in_progress = false; - return status; - } - - return QDF_STATUS_SUCCESS; -} -#endif - #ifdef WLAN_FEATURE_PKT_CAPTURE + /** * wlan_hdd_is_session_type_monitor() - check if session type is MONITOR * @session_type: session type @@ -16742,14 +17983,7 @@ QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) */ bool wlan_hdd_is_session_type_monitor(uint8_t session_type) { - struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - - if (!hdd_ctx) { - cds_err("HDD context is NULL"); - return false; - } - - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) && + if (cds_is_pktcapture_enabled() && cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE && session_type == QDF_MONITOR_MODE) return true; @@ -16774,7 +18008,7 @@ bool wlan_hdd_check_mon_concurrency(void) return -EINVAL; } - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { + if (cds_is_pktcapture_enabled()) { if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) == (QDF_STA_MASK | QDF_MONITOR_MASK)) { hdd_err("STA + MON mode is UP"); @@ -16801,11 +18035,6 @@ void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, hdd_stop_adapter(hdd_ctx, adapter); hdd_close_adapter(hdd_ctx, adapter, true); - if (adapter->vdev) { - hdd_objmgr_put_vdev(adapter->vdev); - adapter->vdev = NULL; - } - hdd_open_p2p_interface(hdd_ctx); } @@ -16813,6 +18042,7 @@ void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, * wlan_hdd_add_monitor_check() - check for monitor intf and add if needed * @hdd_ctx: pointer to hdd context * @adapter: output pointer to hold created monitor adapter + * @type: type of the interface * @name: name of the interface * @rtnl_held: True if RTNL lock is held * @name_assign_type: the name of assign type of the netdev @@ -16823,28 +18053,29 @@ void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, int wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, struct hdd_adapter **adapter, - const char *name, bool rtnl_held, - unsigned char name_assign_type) + enum nl80211_iftype type, const char *name, + bool rtnl_held, unsigned char name_assign_type) { struct hdd_adapter *sta_adapter; struct hdd_adapter *mon_adapter; uint32_t mode; uint8_t num_open_session = 0; - QDF_STATUS status; - /* if no interface is up do not add monitor mode */ - if (!hdd_is_any_interface_open(hdd_ctx)) - return -EINVAL; + if (!cds_is_pktcapture_enabled()) + return 0; /* * If add interface request is for monitor mode, then it can run in * parallel with only one station interface. * If there is no existing station interface return error */ - status = policy_mgr_mode_specific_num_open_sessions(hdd_ctx->psoc, - QDF_MONITOR_MODE, - &num_open_session); - if (QDF_IS_STATUS_ERROR(status)) + if (type != NL80211_IFTYPE_MONITOR) + return 0; + + if (QDF_STATUS_SUCCESS != policy_mgr_mode_specific_num_open_sessions( + hdd_ctx->psoc, + QDF_MONITOR_MODE, + &num_open_session)) return -EINVAL; if (num_open_session) { @@ -16853,10 +18084,10 @@ wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, } /* Ensure there is only one station interface */ - status = policy_mgr_mode_specific_num_open_sessions(hdd_ctx->psoc, - QDF_STA_MODE, - &num_open_session); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_STATUS_SUCCESS != policy_mgr_mode_specific_num_open_sessions( + hdd_ctx->psoc, + QDF_STA_MODE, + &num_open_session)) return -EINVAL; if (num_open_session != 1) { @@ -16871,10 +18102,10 @@ wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, return -EINVAL; } - status = policy_mgr_mode_specific_num_open_sessions(hdd_ctx->psoc, - QDF_SAP_MODE, - &num_open_session); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_STATUS_SUCCESS != policy_mgr_mode_specific_num_open_sessions( + hdd_ctx->psoc, + QDF_SAP_MODE, + &num_open_session)) return -EINVAL; if (num_open_session) { @@ -16898,6 +18129,7 @@ wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, vdev_sync = osif_vdev_sync_unregister(adapter->dev); if (vdev_sync) osif_vdev_sync_wait_for_ops(vdev_sync); + wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); hdd_stop_adapter(hdd_ctx, adapter); @@ -16925,6 +18157,83 @@ wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, } #endif /* WLAN_FEATURE_PKT_CAPTURE */ +#ifdef FEATURE_MONITOR_MODE_SUPPORT + +void hdd_sme_monitor_mode_callback(uint8_t vdev_id) +{ + struct hdd_adapter *adapter; + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err_rl("Invalid HDD_CTX"); + return; + } + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + if (!adapter) { + hdd_err_rl("NULL adapter"); + return; + } + + if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { + hdd_err_rl("Invalid magic"); + return; + } + + if (adapter->magic == WLAN_HDD_ADAPTER_MAGIC) + qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); + + hdd_debug("monitor mode vdev up completed"); + adapter->monitor_mode_vdev_up_in_progress = false; +} + +QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, + uint8_t session_type) +{ + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + + if (session_type == QDF_MONITOR_MODE) { + qdf_status = qdf_event_create( + &adapter->qdf_monitor_mode_vdev_up_event); + } + return qdf_status; +} + +QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!adapter->monitor_mode_vdev_up_in_progress) + return status; + + /* block on a completion variable until vdev up success*/ + status = qdf_wait_for_event_completion( + &adapter->qdf_monitor_mode_vdev_up_event, + WLAN_MONITOR_MODE_VDEV_UP_EVT); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err_rl("monitor mode vdev up event time out vdev id: %d", + adapter->vdev_id); + if (adapter->qdf_monitor_mode_vdev_up_event.force_set) + /* + * SSR/PDR has caused shutdown, which has + * forcefully set the event. + */ + hdd_err_rl("monitor mode vdev up event forcefully set"); + else if (status == QDF_STATUS_E_TIMEOUT) + hdd_err_rl("mode vdev up event timed out"); + else + hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", + status); + + adapter->monitor_mode_vdev_up_in_progress = false; + return status; + } + + return QDF_STATUS_SUCCESS; +} +#endif + /* Register the module init/exit functions */ module_init(hdd_module_init); module_exit(hdd_module_exit); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_mpta_helper.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_mpta_helper.c index fe4502f05f1c2a9d0f0290e6b9f5f1ad483a7fa4..726ecce26dcf658fb0ff0b647c32c5b3e52ac9bb 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_mpta_helper.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_mpta_helper.c @@ -61,14 +61,13 @@ __wlan_hdd_cfg80211_mpta_helper_config(struct wiphy *wiphy, const void *data, int data_len) { - struct net_device *netdev = wdev->netdev; struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct nlattr *tb[QCA_MPTA_HELPER_VENDOR_ATTR_MAX + 1]; struct coex_config_params coex_cfg_params = {0}; int errno; QDF_STATUS status; - hdd_enter_dev(netdev); + hdd_enter_dev(wdev->netdev); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan.c index 79ab02c9fc32faa0080da65634e24f49128a93d1..8ff27af80bf60f8bf5b45f523cf304e5f3a88506 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -50,65 +50,6 @@ bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx) sme_is_feature_supported_by_fw(NAN); } -/** - * __wlan_hdd_cfg80211_nan_request() - cfg80211 NAN request handler - * @wiphy: driver's wiphy struct - * @wdev: wireless device to which the request is targeted - * @data: actual request data (netlink-encapsulated) - * @data_len: length of @data - * - * This is called when userspace needs to send a nan request to - * firmware. The wlan host driver simply de-encapsulates the - * request from the netlink payload and then forwards it to - * firmware via SME. - * - * Return: 0 on success, negative errno on failure - */ -static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, - struct wireless_dev *wdev, - const void *data, int data_len) -{ - int ret_val; - struct hdd_context *hdd_ctx = wiphy_priv(wiphy); - - hdd_enter_dev(wdev->netdev); - - ret_val = wlan_hdd_validate_context(hdd_ctx); - if (ret_val) - return ret_val; - - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err_rl("Command not allowed in FTM mode"); - return -EPERM; - } - - if (!cfg_nan_get_enable(hdd_ctx->psoc)) { - hdd_err_rl("NaN support is not enabled in INI"); - return -EPERM; - } - - return os_if_nan_legacy_req(hdd_ctx->psoc, data, data_len); -} - -int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, - struct wireless_dev *wdev, const void *data, - int data_len) - -{ - struct osif_psoc_sync *psoc_sync; - int errno; - - errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); - if (errno) - return errno; - - errno = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len); - - osif_psoc_sync_op_stop(psoc_sync); - - return errno; -} - /** * __wlan_hdd_cfg80211_nan_ext_request() - cfg80211 NAN extended request handler * @wiphy: driver's wiphy struct @@ -128,6 +69,8 @@ static int __wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy, { int ret_val; struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_enter_dev(wdev->netdev); @@ -145,8 +88,8 @@ static int __wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy, return -EPERM; } - return os_if_process_nan_req(hdd_ctx->psoc, - data, data_len); + return os_if_process_nan_req(hdd_ctx->psoc, adapter->vdev_id, + data, data_len); } int wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.c index bb17165435d88b6fe6c79d04d76a1b5d02247df5..6bea10ccb12594da278db83e99a8d6a23af9a4d5 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -41,6 +42,7 @@ #include "wlan_mlme_ucfg_api.h" #include "qdf_util.h" #include +#include "wlan_fwol_ucfg_api.h" /** * hdd_nan_datapath_target_config() - Configure NAN datapath features @@ -118,33 +120,88 @@ static int hdd_close_ndi(struct hdd_adapter *adapter) * * Return: true if allowed, false otherwise */ +#ifdef NDP_SAP_CONCURRENCY_ENABLE static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_NDP_ALLOWED; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + switch (adapter->device_mode) { + case QDF_P2P_GO_MODE: + if (test_bit(SOFTAP_BSS_STARTED, + &adapter->event_flags)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); + return false; + } + break; + case QDF_P2P_CLIENT_MODE: + case QDF_IBSS_MODE: + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_conn_is_connected(sta_ctx) || + hdd_is_connecting(sta_ctx)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); + return false; + } + break; + default: + break; + } + hdd_adapter_dev_put_debug(adapter, dbgid); + } + + return true; +} +#else +static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter, *next_adapter = NULL; + struct hdd_station_ctx *sta_ctx; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_NDP_ALLOWED; + + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { switch (adapter->device_mode) { case QDF_P2P_GO_MODE: case QDF_SAP_MODE: if (test_bit(SOFTAP_BSS_STARTED, - &adapter->event_flags)) + &adapter->event_flags)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return false; + } break; case QDF_P2P_CLIENT_MODE: case QDF_IBSS_MODE: sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if (hdd_conn_is_connected(sta_ctx) || - hdd_is_connecting(sta_ctx)) + hdd_is_connecting(sta_ctx)) { + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return false; + } break; default: break; } + hdd_adapter_dev_put_debug(adapter, dbgid); } return true; } +#endif /* NDP_SAP_CONCURRENCY_ENABLE */ /** * hdd_ndi_start_bss() - Start BSS on NAN data interface @@ -163,6 +220,7 @@ static int hdd_ndi_start_bss(struct hdd_adapter *adapter, uint8_t wmm_mode = 0; struct hdd_context *hdd_ctx; uint8_t value = 0; + uint32_t oper_freq; hdd_enter(); @@ -192,9 +250,10 @@ static int hdd_ndi_start_bss(struct hdd_adapter *adapter, if (!operating_channel) operating_channel = NAN_SOCIAL_CHANNEL_2_4GHZ; + oper_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, operating_channel); roam_profile->ChannelInfo.numOfChannels = 1; - roam_profile->ChannelInfo.ChannelList = &operating_channel; + roam_profile->ChannelInfo.freq_list = &oper_freq; roam_profile->SSIDs.numOfSSIDs = 1; roam_profile->SSIDs.SSIDList->SSID.length = 0; @@ -224,7 +283,7 @@ static int hdd_ndi_start_bss(struct hdd_adapter *adapter, hdd_info("sme_RoamConnect issued successfully for NDI"); } - roam_profile->ChannelInfo.ChannelList = NULL; + roam_profile->ChannelInfo.freq_list = NULL; roam_profile->ChannelInfo.numOfChannels = 0; hdd_exit(); @@ -318,7 +377,6 @@ void hdd_ndp_event_handler(struct hdd_adapter *adapter, { bool success; struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(adapter->vdev); - uint8_t sta_id; if (roam_status == eCSR_ROAM_NDP_STATUS_UPDATE) { switch (roam_result) { @@ -327,9 +385,8 @@ void hdd_ndp_event_handler(struct hdd_adapter *adapter, NAN_DATAPATH_RSP_STATUS_SUCCESS); hdd_debug("posting ndi create status: %d (%s) to umac", success, success ? "Success" : "Failure"); - sta_id = roam_info->ndp.ndi_create_params.sta_id; os_if_nan_post_ndi_create_rsp(psoc, adapter->vdev_id, - success, sta_id); + success); return; case eCSR_ROAM_RESULT_NDI_DELETE_RSP: success = (roam_info->ndp.ndi_create_params.status == @@ -426,8 +483,9 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter) int32_t ret_val; mac_handle_t mac_handle; bool bval = false; + uint8_t enable_sifs_burst = 0; - ret_val = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter); + ret_val = hdd_vdev_create(adapter); if (ret_val) { hdd_err("failed to create vdev: %d", ret_val); return ret_val; @@ -443,7 +501,8 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter) hdd_err("unable to get vht_enable2x2"); sme_set_pdev_ht_vht_ies(mac_handle, bval); - sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id); + sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id, + adapter->device_mode); hdd_roam_profile_init(adapter); hdd_register_wext(wlan_dev); @@ -466,13 +525,18 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter) set_bit(WMM_INIT_DONE, &adapter->event_flags); + status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst); + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_err("Failed to get sifs burst value, use default"); + ret_val = wma_cli_set_command((int)adapter->vdev_id, - (int)WMI_PDEV_PARAM_BURST_ENABLE, - (int)HDD_ENABLE_SIFS_BURST_DEFAULT, - PDEV_CMD); + (int)WMI_PDEV_PARAM_BURST_ENABLE, + enable_sifs_burst, + PDEV_CMD); if (0 != ret_val) hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val); + hdd_set_netdev_flags(adapter); update_ndi_state(adapter, NAN_DATA_NDI_CREATING_STATE); return ret_val; @@ -491,7 +555,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter) int hdd_ndi_open(char *iface_name) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct qdf_mac_addr random_ndi_mac; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); uint8_t ndi_adapter_count = 0; @@ -503,9 +567,11 @@ int hdd_ndi_open(char *iface_name) return -EINVAL; } - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_NDI_OPEN) { if (WLAN_HDD_IS_NDI(adapter)) ndi_adapter_count++; + hdd_adapter_dev_put_debug(adapter, NET_DEV_HOLD_NDI_OPEN); } if (ndi_adapter_count >= MAX_NDI_ADAPTERS) { hdd_err("Can't allow more than %d NDI adapters", @@ -530,6 +596,8 @@ int hdd_ndi_open(char *iface_name) adapter = hdd_open_adapter(hdd_ctx, QDF_NDI_MODE, iface_name, ndi_mac_addr, NET_NAME_UNKNOWN, true); if (!adapter) { + if (!cfg_nan_get_ndi_mac_randomize(hdd_ctx->psoc)) + wlan_hdd_release_intf_addr(hdd_ctx, ndi_mac_addr); hdd_err("hdd_open_adapter failed"); return -EINVAL; } @@ -614,7 +682,6 @@ int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id) struct hdd_adapter *adapter; struct hdd_station_ctx *sta_ctx; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - uint8_t sta_id; if (!hdd_ctx) { hdd_err("hdd_ctx is null"); @@ -634,15 +701,6 @@ int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id) return -EINVAL; } - sta_id = sta_ctx->broadcast_sta_id; - if (sta_id >= HDD_MAX_ADAPTERS) { - hdd_err("Error: Invalid sta id %u", sta_id); - return -EINVAL; - } - - /* Since, the interface is being deleted, remove the broadcast id. */ - hdd_ctx->sta_to_adapter[sta_id] = NULL; - os_if_nan_set_ndp_delete_transaction_id(adapter->vdev, transaction_id); os_if_nan_set_ndi_state(adapter->vdev, NAN_DATA_NDI_DELETING_STATE); @@ -668,7 +726,6 @@ void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id, uint16_t ndp_inactivity_timeout = 0; uint16_t ndp_keep_alive_period; struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT; - uint8_t sta_id; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -688,12 +745,6 @@ void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id, return; } - sta_id = ndi_rsp->sta_id; - if (sta_id >= HDD_MAX_ADAPTERS) { - hdd_err("Error: Invalid sta id %u", sta_id); - return; - } - roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return; @@ -727,10 +778,9 @@ void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id, ndi_rsp->reason /* create_reason */); } - sta_ctx->broadcast_sta_id = sta_id; - hdd_save_peer(sta_ctx, sta_id, &bc_mac_addr); - hdd_roam_register_sta(adapter, roam_info, sta_id, &tmp_bss_descp); - hdd_ctx->sta_to_adapter[sta_id] = adapter; + hdd_save_peer(sta_ctx, &bc_mac_addr); + qdf_copy_macaddr(&roam_info->bssid, &bc_mac_addr); + hdd_roam_register_sta(adapter, roam_info, &tmp_bss_descp); qdf_mem_free(roam_info); } @@ -760,7 +810,7 @@ void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id) struct hdd_context *hdd_ctx; struct hdd_adapter *adapter; struct hdd_station_ctx *sta_ctx; - uint8_t sta_id; + struct qdf_mac_addr bc_mac_addr = QDF_MAC_ADDR_BCAST_INIT; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -780,17 +830,19 @@ void hdd_ndi_drv_ndi_delete_rsp_handler(uint8_t vdev_id) return; } - sta_id = sta_ctx->broadcast_sta_id; - if (sta_id < HDD_MAX_ADAPTERS) { - hdd_ctx->sta_to_adapter[sta_id] = NULL; - hdd_delete_peer(sta_ctx, sta_id); - sta_ctx->broadcast_sta_id = HDD_WLAN_INVALID_STA_ID; - } + hdd_delete_peer(sta_ctx, &bc_mac_addr); wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); + /* + * For NAN Data interface, the close session results in the final + * indication to the userspace + */ + if (adapter->device_mode == QDF_NDI_MODE) + hdd_ndp_session_end_handler(adapter); + complete(&adapter->disconnect_comp_var); } @@ -834,7 +886,7 @@ int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id, } /* save peer in ndp ctx */ - if (false == hdd_save_peer(sta_ctx, sta_id, peer_mac_addr)) { + if (!hdd_save_peer(sta_ctx, peer_mac_addr)) { hdd_err("Ndp peer table full. cannot save new peer"); return -EPERM; } @@ -842,19 +894,37 @@ int hdd_ndp_new_peer_handler(uint8_t vdev_id, uint16_t sta_id, roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return -ENOMEM; + qdf_copy_macaddr(&roam_info->bssid, peer_mac_addr); /* this function is called for each new peer */ - hdd_roam_register_sta(adapter, roam_info, sta_id, &tmp_bss_descp); - hdd_ctx->sta_to_adapter[sta_id] = adapter; + hdd_roam_register_sta(adapter, roam_info, &tmp_bss_descp); + + qdf_copy_macaddr(&roam_info->bssid, peer_mac_addr); + /* perform following steps for first new peer ind */ if (fist_peer) { hdd_debug("Set ctx connection state to connected"); + /* Disable LRO/GRO for NDI Mode */ + if (hdd_ctx->ol_enable && + !ucfg_is_nan_dbs_supported(hdd_ctx->psoc)) { + hdd_debug("Disable LRO/GRO in NDI Mode"); + hdd_disable_rx_ol_in_concurrency(true); + } + hdd_bus_bw_compute_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_start(hdd_ctx); sta_ctx->conn_info.conn_state = eConnectionState_NdiConnected; hdd_wmm_connect(adapter, roam_info, eCSR_BSS_TYPE_NDI); - wlan_hdd_netif_queue_control(adapter, - WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH); + wlan_hdd_netif_queue_control( + adapter, + WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, + WLAN_CONTROL_PATH); + /* + * This is called only for first peer. So, no.of NDP sessions + * are always 1 + */ + if (!ucfg_is_ndi_dbs_supported(hdd_ctx->psoc)) + hdd_indicate_active_ndp_cnt(hdd_ctx->psoc, vdev_id, 1); } qdf_mem_free(roam_info); return 0; @@ -873,10 +943,22 @@ void hdd_cleanup_ndi(struct hdd_context *hdd_ctx, hdd_conn_set_connection_state(adapter, eConnectionState_NdiDisconnected); hdd_debug("Stop netif tx queues."); - wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE, + wlan_hdd_netif_queue_control(adapter, + WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH); hdd_bus_bw_compute_reset_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_try_stop(hdd_ctx); + if ((hdd_ctx->ol_enable && + !ucfg_is_nan_dbs_supported(hdd_ctx->psoc)) && + ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 0) || + ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1) && + (policy_mgr_mode_specific_connection_count( + hdd_ctx->psoc, + PM_STA_MODE, + NULL) == 1)))) { + hdd_debug("Enable LRO/GRO"); + hdd_disable_rx_ol_in_concurrency(false); + } } /** @@ -911,12 +993,17 @@ void hdd_ndp_peer_departed_handler(uint8_t vdev_id, uint16_t sta_id, return; } - hdd_delete_peer(sta_ctx, sta_id); - hdd_ctx->sta_to_adapter[sta_id] = NULL; + hdd_delete_peer(sta_ctx, peer_mac_addr); if (last_peer) { hdd_debug("No more ndp peers."); hdd_cleanup_ndi(hdd_ctx, adapter); qdf_event_set(&adapter->peer_cleanup_done); + /* + * This is called only for last peer. So, no.of NDP sessions + * are always 0 + */ + if (!ucfg_is_ndi_dbs_supported(hdd_ctx->psoc)) + hdd_indicate_active_ndp_cnt(hdd_ctx->psoc, vdev_id, 0); } } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.h index b9c78ee832f4f188f244a2c30bf41d06d260980b..0d0c1b73260ee38b157578ff6f592fc3ade7bb4f 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nan_datapath.h @@ -69,6 +69,19 @@ void hdd_ndp_session_end_handler(struct hdd_adapter *adapter); void hdd_cleanup_ndi(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter); + +/** + * hdd_ndi_start(): Start NDI adapter and create NDI vdev + * @iface_name: NDI interface name + * @transaction_id: Transaction id given by framework to start the NDI. + * Framework expects this in the immediate response when + * the NDI is created by it. + * + * Create NDI move interface and vdev. + * + * Return: 0 upon success + */ +int hdd_ndi_start(char *iface_name, uint16_t transaction_id); #else #define WLAN_HDD_IS_NDI(adapter) (false) #define WLAN_HDD_IS_NDI_CONNECTED(adapter) (false) @@ -101,13 +114,17 @@ static inline void hdd_cleanup_ndi(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) { } + +static inline int hdd_ndi_start(char *iface_name, uint16_t transaction_id) +{ + return 0; +} #endif /* WLAN_FEATURE_NAN */ enum nan_datapath_state; struct nan_datapath_inf_create_rsp; int hdd_ndi_open(char *iface_name); -int hdd_ndi_start(char *iface_name, uint16_t transaction_id); int hdd_ndi_delete(uint8_t vdev_id, char *iface_name, uint16_t transaction_id); void hdd_ndi_close(uint8_t vdev_id); void hdd_ndi_drv_ndi_create_rsp_handler(uint8_t vdev_id, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.c index 62f46a853c595cad7eca306f02f80b7241f29df6..51eaac61234ee4d84ff3968d66f60572524c8ca2 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.c @@ -199,13 +199,13 @@ static bool hdd_nud_honour_failure(struct hdd_adapter *adapter) ->nud_tracking.tx_rx_stats.gw_rx_packets); if (!tx_transmitted || !tx_acked || !gw_rx_pkt) { - hdd_debug("NUD_FAILURE_HONORED [mac:%pM]", - adapter->nud_tracking.gw_mac_addr.bytes); + hdd_debug("NUD_FAILURE_HONORED [mac:"QDF_MAC_ADDR_FMT"]", + QDF_MAC_ADDR_REF(adapter->nud_tracking.gw_mac_addr.bytes)); hdd_nud_stats_info(adapter); return true; } - hdd_debug("NUD_FAILURE_NOT_HONORED [mac:%pM]", - adapter->nud_tracking.gw_mac_addr.bytes); + hdd_debug("NUD_FAILURE_NOT_HONORED [mac:"QDF_MAC_ADDR_FMT"]", + QDF_MAC_ADDR_REF(adapter->nud_tracking.gw_mac_addr.bytes)); hdd_nud_stats_info(adapter); return false; } @@ -252,6 +252,8 @@ hdd_handle_nud_fail_sta(struct hdd_context *hdd_ctx, ap_info.bssid = sta_ctx->conn_info.bssid; ap_info.reject_ap_type = DRIVER_AVOID_TYPE; + ap_info.reject_reason = REASON_NUD_FAILURE; + ap_info.source = ADDED_BY_DRIVER; ucfg_blm_add_bssid_to_reject_list(hdd_ctx->pdev, &ap_info); if (roaming_offload_enabled(hdd_ctx)) @@ -490,7 +492,20 @@ static void hdd_nud_filter_netevent(struct neighbour *neigh) case NUD_FAILED: hdd_debug("NUD_FAILED [0x%x]", neigh->nud_state); - hdd_nud_process_failure_event(adapter); + /* + * This condition is to handle the scenario where NUD_FAILED + * events are received without any NUD_PROBE/INCOMPLETE event + * post roaming. Nud state is set to NONE as part of roaming. + * NUD_FAILED is not honored when the curr state is any state + * other than NUD_PROBE/INCOMPLETE so post roaming, nud state + * is moved to NUD_PROBE to honor future NUD_FAILED events. + */ + if (adapter->nud_tracking.curr_state == NUD_NONE) { + hdd_nud_capture_stats(adapter, NUD_PROBE); + hdd_nud_set_tracking(adapter, NUD_PROBE, true); + } else { + hdd_nud_process_failure_event(adapter); + } break; default: hdd_debug("NUD Event For Other State [0x%x]", @@ -573,3 +588,8 @@ void hdd_nud_unregister_netevent_notifier(struct hdd_context *hdd_ctx) hdd_debug("Unregistered netevent notifier"); } } + +void hdd_nud_indicate_roam(struct hdd_adapter *adapter) +{ + hdd_nud_set_tracking(adapter, NUD_NONE, false); +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.h index 001e94d1c9b3567f187db4cac7937bfe406717cb..446346ba61193dcc0088ee4011bd236b440b30e1 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_nud_tracking.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -149,6 +149,14 @@ void hdd_nud_unregister_netevent_notifier(struct hdd_context *hdd_ctx); */ void hdd_nud_flush_work(struct hdd_adapter *adapter); +/** + * hdd_nud_indicate_roam() - reset NUD when roaming happens + * @adapter: Pointer to hdd adapter + * + * Return: None + */ +void hdd_nud_indicate_roam(struct hdd_adapter *adapter); + #else static inline void hdd_nud_set_gateway_addr(struct hdd_adapter *adapter, struct qdf_mac_addr gw_mac_addr) @@ -192,5 +200,10 @@ static inline void hdd_nud_flush_work(struct hdd_adapter *adapter) { } + +static inline void +hdd_nud_indicate_roam(struct hdd_adapter *adapter) +{ +} #endif /* WLAN_NUD_TRACKING */ #endif /* end of _WLAN_NUD_TRACKING_H_ */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.c index 14f24ab1846ab8c375a5d2a9060917171cac147a..fa7a5206d3522a8c7065213c37145dc90de92bf3 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.c @@ -30,7 +30,14 @@ #define LOW_2GHZ_FREQ 2312 #define HIGH_2GHZ_FREQ 2732 #define LOW_5GHZ_FREQ 4912 -#define HIGH_5GHZ_FREQ 6100 + +#ifdef CONFIG_BAND_6GHZ +#define HIGH_5GHZ_FREQ 7200 +#else +#define HIGH_5GHZ_FREQ 5930 +#endif + +#define HIGH_5GHZ_FREQ_NO_6GHZ 5930 static void hdd_init_pdev_os_priv(struct hdd_context *hdd_ctx, struct pdev_osif_priv *os_priv) @@ -47,7 +54,6 @@ static void hdd_deinit_pdev_os_priv(struct wlan_objmgr_pdev *pdev) os_if_spectral_netlink_deinit(pdev); wlan_cfg80211_scan_priv_deinit(pdev); } - static void hdd_init_psoc_qdf_ctx(struct wlan_objmgr_psoc *psoc) { qdf_device_t qdf_ctx; @@ -152,6 +158,11 @@ int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx) reg_cap_ptr->low_5ghz_chan = LOW_5GHZ_FREQ; reg_cap_ptr->high_5ghz_chan = HIGH_5GHZ_FREQ; + if (!wlan_reg_is_6ghz_supported(psoc)) { + hdd_debug("disabling 6ghz channels"); + reg_cap_ptr->high_5ghz_chan = HIGH_5GHZ_FREQ_NO_6GHZ; + } + pdev = wlan_objmgr_pdev_obj_create(psoc, priv); if (!pdev) { hdd_err("pdev obj create failed"); @@ -159,6 +170,7 @@ int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx) goto free_priv; } + status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_HDD_ID_OBJ_MGR); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Failed to acquire pdev ref; status:%d", status); @@ -210,63 +222,6 @@ int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx) return qdf_status_to_os_return(status); } -int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, - struct hdd_adapter *adapter) -{ - QDF_STATUS status; - int errno = 0; - struct wlan_objmgr_vdev *vdev; - struct vdev_osif_priv *osif_priv; - struct wlan_vdev_create_params vdev_params = {0}; - - QDF_BUG(pdev); - if (!pdev) { - hdd_err("pdev is null"); - return -EINVAL; - } - - vdev_params.opmode = adapter->device_mode; - qdf_mem_copy(vdev_params.macaddr, - adapter->mac_addr.bytes, - QDF_NET_MAC_ADDR_MAX_LEN); - - vdev_params.size_vdev_priv = sizeof(*osif_priv); - - vdev = wlan_objmgr_vdev_obj_create(pdev, &vdev_params); - if (!vdev) { - hdd_err("Failed to create vdev object"); - errno = -ENOMEM; - return errno; - } - - /* Initialize the vdev OS private structure*/ - osif_priv = wlan_vdev_get_ospriv(vdev); - osif_priv->wdev = adapter->dev->ieee80211_ptr; - osif_priv->legacy_osif_priv = adapter; - - /* - * To enable legacy use cases, we need to delay physical vdev destroy - * until after the sme session has been closed. We accomplish this by - * getting a reference here. - */ - status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Failed to acquire vdev ref; status:%d", status); - errno = qdf_status_to_os_return(status); - goto vdev_destroy; - } - - qdf_spin_lock_bh(&adapter->vdev_lock); - adapter->vdev = vdev; - adapter->vdev_id = wlan_vdev_get_id(vdev); - qdf_spin_unlock_bh(&adapter->vdev_lock); - - return 0; - -vdev_destroy: - wlan_objmgr_vdev_obj_delete(vdev); - return errno; -} int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter) { diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.h index 070ff288dbe0cd99d24bcde68c91361a26e3740c..cf877677b77a49c6bcdf68d7ae7b372727caf408 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_object_manager.h @@ -109,19 +109,6 @@ int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx); */ int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx); -/** - * hdd_objmgr_create_and_store_vdev() - Create vdev and store in hdd adapter - * @pdev: pdev pointer - * @adapter: hdd adapter - * - * This API creates the vdev object and store the vdev reference to the - * given @adapter. Also, creates a self peer for the vdev. - * - * Return: 0 for success, negative error code for failure - */ -int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, - struct hdd_adapter *adapter); - /** * hdd_objmgr_release_and_destroy_vdev() - Delete vdev and remove from adapter * @adapter: hdd adapter diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c index 72d11cd7333f5193ea869c5ea6007f16efd8866b..4302abb9fc96c81a7471e4629579d122b9bdb460 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -41,6 +41,7 @@ #include #include #include +#include "ol_txrx.h" /* Structure definitions for WLAN_SET_DOT11P_CHANNEL_SCHED */ #define AIFSN_MIN (2) @@ -216,60 +217,37 @@ static int hdd_ocb_register_sta(struct hdd_adapter *adapter) { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; struct ol_txrx_desc_type sta_desc = {0}; - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - uint8_t peer_id; struct ol_txrx_ops txrx_ops; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_vdev *vdev; + struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX); qdf_status = cdp_peer_register_ocb_peer(soc, - adapter->mac_addr.bytes, - &peer_id); + adapter->mac_addr.bytes); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("Error registering OCB Self Peer!"); return -EINVAL; } - if (peer_id >= HDD_MAX_ADAPTERS) { - hdd_err("Error: Invalid peer_id: %u", peer_id); - return -EINVAL; - } - - hdd_ctx->sta_to_adapter[peer_id] = adapter; - - sta_desc.sta_id = peer_id; + WLAN_ADDR_COPY(sta_desc.peer_addr.bytes, adapter->mac_addr.bytes); sta_desc.is_qos_enabled = 1; /* Register the vdev transmit and receive functions */ qdf_mem_zero(&txrx_ops, sizeof(txrx_ops)); txrx_ops.rx.rx = hdd_rx_packet_cbk; - vdev = cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); - if (!vdev) - return -EINVAL; - cdp_vdev_register(soc, vdev, adapter, - (struct cdp_ctrl_objmgr_vdev *)adapter->vdev, + cdp_vdev_register(soc, adapter->vdev_id, (ol_osif_vdev_handle)adapter, &txrx_ops); txrx_ops.rx.stats_rx = hdd_tx_rx_collect_connectivity_stats_info; adapter->tx_fn = txrx_ops.tx.tx; - qdf_status = cdp_peer_register(soc, (struct cdp_pdev *)pdev, &sta_desc); + qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &sta_desc); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("Failed to register. Status= %d [0x%08X]", qdf_status, qdf_status); return -EINVAL; } - if (sta_ctx->conn_info.sta_id[0] != HDD_WLAN_INVALID_STA_ID && - sta_ctx->conn_info.sta_id[0] != peer_id) { - hdd_err("The ID for the OCB station has changed."); - } - - sta_ctx->conn_info.sta_id[0] = peer_id; qdf_copy_macaddr(&sta_ctx->conn_info.peer_macaddr[0], &adapter->mac_addr); @@ -1964,7 +1942,7 @@ static int __wlan_hdd_cfg80211_dcc_update_ndl(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_DCC_UPDATE_NDL_ACTIVE_STATE_ARRAY]); /* Check channel count. Per 11p spec, max 2 channels allowed */ - if (!channel_count || channel_count > TGT_NUM_OCB_CHANNELS) { + if (!channel_count || channel_count > CFG_TGT_NUM_OCB_CHANNELS) { hdd_err("Invalid channel_count %d", channel_count); return -EINVAL; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_oemdata.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_oemdata.c index d23a256a84091da469e59faa46c1cb08baa84766..ca6e470a5ed744277d669a91917e655a3f0e8c0d 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_oemdata.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_oemdata.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,7 +38,8 @@ #include "sme_api.h" #include "wlan_nlink_srv.h" #include "wlan_hdd_oemdata.h" - +#include "wlan_osif_request_manager.h" +#include "wlan_hdd_main.h" #ifdef FEATURE_OEM_DATA_SUPPORT #ifdef CNSS_GENL #include @@ -58,9 +59,10 @@ static int populate_oem_data_cap(struct hdd_adapter *adapter, { QDF_STATUS status; struct hdd_config *config; - uint32_t num_chan; - uint8_t *chan_list; + uint32_t num_chan, i; + uint32_t *chan_freq_list; uint8_t band_capability; + uint32_t band_bitmap; uint16_t neighbor_scan_min_chan_time; uint16_t neighbor_scan_max_chan_time; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -71,17 +73,18 @@ static int populate_oem_data_cap(struct hdd_adapter *adapter, return -EINVAL; } - status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); + status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Failed to get MLME band capability"); return -EIO; } - chan_list = qdf_mem_malloc(sizeof(uint8_t) * OEM_CAP_MAX_NUM_CHANNELS); - if (!chan_list) { - hdd_err("Memory allocation failed"); + band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); + + chan_freq_list = + qdf_mem_malloc(sizeof(uint32_t) * OEM_CAP_MAX_NUM_CHANNELS); + if (!chan_freq_list) return -ENOMEM; - } strlcpy(data_cap->oem_target_signature, OEM_TARGET_SIGNATURE, OEM_TARGET_SIGNATURE_LEN); @@ -107,27 +110,28 @@ static int populate_oem_data_cap(struct hdd_adapter *adapter, /* request for max num of channels */ num_chan = OEM_CAP_MAX_NUM_CHANNELS; - status = sme_get_cfg_valid_channels( - &chan_list[0], &num_chan); + status = sme_get_cfg_valid_channels(&chan_freq_list[0], &num_chan); if (QDF_STATUS_SUCCESS != status) { hdd_err("failed to get valid channel list, status: %d", status); - qdf_mem_free(chan_list); + qdf_mem_free(chan_freq_list); return -EINVAL; } /* make sure num channels is not more than chan list array */ if (num_chan > OEM_CAP_MAX_NUM_CHANNELS) { - hdd_err("Num of channels-%d > length-%d of chan_list", + hdd_err("Num of channels-%d > length-%d of chan_freq_list", num_chan, OEM_CAP_MAX_NUM_CHANNELS); - qdf_mem_free(chan_list); + qdf_mem_free(chan_freq_list); return -ENOMEM; } data_cap->num_channels = num_chan; - qdf_mem_copy(data_cap->channel_list, chan_list, - sizeof(uint8_t) * num_chan); + for (i = 0; i < num_chan; i++) { + data_cap->channel_list[i] = + wlan_reg_freq_to_chan(hdd_ctx->pdev, chan_freq_list[i]); + } - qdf_mem_free(chan_list); + qdf_mem_free(chan_freq_list); return 0; } @@ -186,7 +190,8 @@ static void send_oem_reg_rsp_nlink_msg(void) uint8_t *num_interfaces; uint8_t *device_mode; uint8_t *vdev_id; - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG; /* OEM msg is always to a specific process & cannot be a broadcast */ if (p_hdd_ctx->oem_pid == 0) { @@ -217,7 +222,8 @@ static void send_oem_reg_rsp_nlink_msg(void) *num_interfaces = 0; /* Iterate through each adapter and fill device mode and vdev id */ - hdd_for_each_adapter(p_hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(p_hdd_ctx, adapter, next_adapter, + dbgid) { device_mode = buf++; vdev_id = buf++; *device_mode = adapter->device_mode; @@ -226,6 +232,7 @@ static void send_oem_reg_rsp_nlink_msg(void) hdd_debug("num_interfaces: %d, device_mode: %d, vdev_id: %d", *num_interfaces, *device_mode, *vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); } ani_hdr->length = @@ -381,25 +388,12 @@ static QDF_STATUS oem_process_data_req_msg(int oem_data_len, char *oem_data) return status; } -/** - * update_channel_bw_info() - set bandwidth info for the chan - * @hdd_ctx: hdd context - * @chan: channel for which info are required - * @chan_info: struct where the bandwidth info is filled - * - * This function find the maximum bandwidth allowed, secondary - * channel offset and center freq for the channel as per regulatory - * domain and using these info calculate the phy mode for the - * channel. - * - * Return: void - */ void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx, - uint16_t chan, void *chan_info) + uint32_t chan_freq, void *chan_info) { struct ch_params ch_params = {0}; - uint16_t sec_ch_2g = 0; - WLAN_PHY_MODE phy_mode; + enum wlan_phymode phy_mode; + uint16_t fw_phy_mode; uint32_t wni_dot11_mode; struct hdd_channel_info *hdd_chan_info = chan_info; @@ -408,28 +402,32 @@ void hdd_update_channel_bw_info(struct hdd_context *hdd_ctx, /* Passing CH_WIDTH_MAX will give the max bandwidth supported */ ch_params.ch_width = CH_WIDTH_MAX; - wlan_reg_set_channel_params(hdd_ctx->pdev, chan, sec_ch_2g, &ch_params); + wlan_reg_set_channel_params_for_freq( + hdd_ctx->pdev, chan_freq, 0, &ch_params); if (ch_params.center_freq_seg0) hdd_chan_info->band_center_freq1 = cds_chan_to_freq(ch_params.center_freq_seg0); - if (ch_params.ch_width < CH_WIDTH_INVALID) - phy_mode = wma_chan_phy_mode(chan, ch_params.ch_width, + if (ch_params.ch_width < CH_WIDTH_INVALID) { + phy_mode = wma_chan_phy_mode(chan_freq, ch_params.ch_width, wni_dot11_mode); + } else /* * If channel width is CH_WIDTH_INVALID, It mean channel is * invalid and should not have been received in channel info * req. Set invalid phymode in this case. */ - phy_mode = MODE_UNKNOWN; + phy_mode = WLAN_PHYMODE_AUTO; + + fw_phy_mode = wma_host_to_fw_phymode(phy_mode); - hdd_debug("chan %d dot11_mode %d ch_width %d sec offset %d freq_seg0 %d phy_mode %d", - chan, wni_dot11_mode, ch_params.ch_width, - ch_params.sec_ch_offset, - hdd_chan_info->band_center_freq1, phy_mode); + hdd_debug("chan %d dot11_mode %d ch_width %d sec offset %d freq_seg0 %d phy_mode %d fw_phy_mode %d", + chan_freq, wni_dot11_mode, ch_params.ch_width, + ch_params.sec_ch_offset, + hdd_chan_info->band_center_freq1, phy_mode, fw_phy_mode); - WMI_SET_CHANNEL_MODE(hdd_chan_info, phy_mode); + WMI_SET_CHANNEL_MODE(hdd_chan_info, fw_phy_mode); } /** @@ -448,12 +446,12 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) tAniMsgHdr *ani_hdr; struct hdd_channel_info *pHddChanInfo; struct hdd_channel_info hddChanInfo; - uint8_t chanId; uint32_t reg_info_1; uint32_t reg_info_2; QDF_STATUS status = QDF_STATUS_E_FAILURE; int i; uint8_t *buf; + uint32_t chan_freq; /* OEM msg is always to a specific process and cannot be a broadcast */ if (p_hdd_ctx->oem_pid == 0) { @@ -492,25 +490,26 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) i * sizeof(*pHddChanInfo)); - chanId = chanList[i]; - status = sme_get_reg_info(p_hdd_ctx->mac_handle, chanId, + chan_freq = wlan_reg_legacy_chan_to_freq( + p_hdd_ctx->pdev, chanList[i]); + status = sme_get_reg_info(p_hdd_ctx->mac_handle, chan_freq, ®_info_1, ®_info_2); if (QDF_STATUS_SUCCESS == status) { /* copy into hdd chan info struct */ - hddChanInfo.chan_id = chanId; hddChanInfo.reserved0 = 0; - hddChanInfo.mhz = cds_chan_to_freq(chanId); + hddChanInfo.mhz = chan_freq; hddChanInfo.band_center_freq1 = hddChanInfo.mhz; hddChanInfo.band_center_freq2 = 0; hddChanInfo.info = 0; if (CHANNEL_STATE_DFS == - wlan_reg_get_channel_state(p_hdd_ctx->pdev, chanId)) + wlan_reg_get_channel_state_for_freq( + p_hdd_ctx->pdev, chan_freq)) WMI_SET_CHANNEL_FLAG(&hddChanInfo, WMI_CHAN_FLAG_DFS); hdd_update_channel_bw_info(p_hdd_ctx, - chanId, &hddChanInfo); + chan_freq, &hddChanInfo); hddChanInfo.reg_info_1 = reg_info_1; hddChanInfo.reg_info_2 = reg_info_2; } else { @@ -518,10 +517,9 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) * channel info struct */ hdd_debug("sme_get_reg_info failed for chan: %d, fill 0s", - chanId); - hddChanInfo.chan_id = chanId; + chan_freq); hddChanInfo.reserved0 = 0; - hddChanInfo.mhz = 0; + hddChanInfo.mhz = chan_freq; hddChanInfo.band_center_freq1 = 0; hddChanInfo.band_center_freq2 = 0; hddChanInfo.info = 0; @@ -718,7 +716,6 @@ void hdd_send_peer_status_ind_to_oem_app(struct qdf_mac_addr *peer_mac, peer_info->reserved0 |= 0x01; if (chan_info) { - peer_info->peer_chan_info.chan_id = chan_info->chan_id; peer_info->peer_chan_info.reserved0 = 0; peer_info->peer_chan_info.mhz = chan_info->mhz; peer_info->peer_chan_info.band_center_freq1 = @@ -731,15 +728,14 @@ void hdd_send_peer_status_ind_to_oem_app(struct qdf_mac_addr *peer_mac, } skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + ani_hdr->length))); - hdd_info("sending peer " QDF_MAC_ADDR_STR - " status(%d), peer_capability(%d), vdev_id(%d), chanId(%d)" + hdd_info("sending peer " QDF_MAC_ADDR_FMT + " status(%d), peer_capability(%d), vdev_id(%d)," " to oem app pid(%d), center freq 1 (%d), center freq 2 (%d)," " info (0x%x), frequency (%d),reg info 1 (0x%x)," " reg info 2 (0x%x)", - QDF_MAC_ADDR_ARRAY(peer_mac->bytes), + QDF_MAC_ADDR_REF(peer_mac->bytes), peer_status, peer_capability, - vdev_id, peer_info->peer_chan_info.chan_id, - p_hdd_ctx->oem_pid, + vdev_id, p_hdd_ctx->oem_pid, peer_info->peer_chan_info.band_center_freq1, peer_info->peer_chan_info.band_center_freq2, peer_info->peer_chan_info.info, @@ -1135,46 +1131,100 @@ oem_data_attr_policy[QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX + 1] = { .type = NLA_BINARY, .len = OEM_DATA_MAX_SIZE }, + + [QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED] = {.type = NLA_FLAG}, }; -void hdd_oem_event_handler_cb(const struct oem_data *oem_event_data) +void hdd_oem_event_handler_cb(const struct oem_data *oem_event_data, + uint8_t vdev_id) { struct sk_buff *vendor_event; + struct osif_request *request; uint32_t len; int ret; + struct oem_data *oem_data; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - + struct hdd_adapter *hdd_adapter = hdd_get_adapter_by_vdev(hdd_ctx, + vdev_id); hdd_enter(); ret = wlan_hdd_validate_context(hdd_ctx); if (ret) return; - len = nla_total_size(oem_event_data->data_len) + NLMSG_HDRLEN; - vendor_event = - cfg80211_vendor_event_alloc( + if (hdd_validate_adapter(hdd_adapter)) + return; + + if (!oem_event_data || !(oem_event_data->data)) { + hdd_err("Invalid oem event data"); + return; + } + + if (hdd_adapter->response_expected) { + request = osif_request_get(hdd_adapter->cookie); + if (!request) { + hdd_err("Invalid request"); + return; + } + + oem_data = osif_request_priv(request); + oem_data->data_len = oem_event_data->data_len; + oem_data->data = qdf_mem_malloc(oem_data->data_len); + if (!oem_data->data) { + hdd_err("Memory allocation failure"); + return; + } + qdf_mem_copy(oem_data->data, oem_event_data->data, + oem_data->data_len); + oem_data->vdev_id = hdd_adapter->vdev_id; + osif_request_complete(request); + osif_request_put(request); + } else { + len = nla_total_size(oem_event_data->data_len) + NLMSG_HDRLEN; + vendor_event = + cfg80211_vendor_event_alloc( hdd_ctx->wiphy, NULL, len, QCA_NL80211_VENDOR_SUBCMD_OEM_DATA_INDEX, GFP_KERNEL); - if (!vendor_event) { - hdd_err("cfg80211_vendor_event_alloc failed"); - return; - } + if (!vendor_event) { + hdd_err("cfg80211_vendor_event_alloc failed"); + return; + } - ret = nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA, - oem_event_data->data_len, oem_event_data->data); - if (ret) { - hdd_err("OEM event put fails status %d", ret); - kfree_skb(vendor_event); - return; + ret = nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA, + oem_event_data->data_len, oem_event_data->data); + if (ret) { + hdd_err("OEM event put fails status %d", ret); + kfree_skb(vendor_event); + return; + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); } - cfg80211_vendor_event(vendor_event, GFP_KERNEL); - hdd_exit(); } +/** + *wlan_hdd_free_oem_data: delete data of priv data + *@priv: osif request private data + * + *Return: void + */ +static void wlan_hdd_free_oem_data(void *priv) +{ + struct oem_data *local_priv = priv; + + if (!local_priv) + return; + + if (local_priv->data) { + qdf_mem_free(local_priv->data); + local_priv->data = NULL; + } +} + /** * __wlan_hdd_cfg80211_oem_data_handler() - the handler for oem data * @wiphy: wiphy structure pointer @@ -1190,17 +1240,34 @@ __wlan_hdd_cfg80211_oem_data_handler(struct wiphy *wiphy, const void *data, int data_len) { struct net_device *dev = wdev->netdev; - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_SUCCESS; int ret; + struct sk_buff *skb = NULL; struct oem_data oem_data = {0}; + struct oem_data *get_oem_data = NULL; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX + 1]; + struct osif_request *request = NULL; + struct oem_data *priv; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_GET_OEM_DATA, + .dealloc = wlan_hdd_free_oem_data, + }; ret = wlan_hdd_validate_context(hdd_ctx); if (ret) return ret; + if (hdd_validate_adapter(adapter)) + return -EINVAL; + + if (adapter->oem_data_in_progress) { + hdd_err("oem request already in progress"); + return -EBUSY; + } + if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX, data, data_len, oem_data_attr_policy)) { @@ -1214,18 +1281,87 @@ __wlan_hdd_cfg80211_oem_data_handler(struct wiphy *wiphy, } oem_data.data_len = - nla_len(tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA]); + nla_len(tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA]); if (!oem_data.data_len) { hdd_err("oem data len is 0!"); return -EINVAL; } - oem_data.vdev_id = adapter->vdev_id; oem_data.data = nla_data(tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA]); - status = sme_oem_data_cmd(hdd_ctx->mac_handle, &oem_data); + if (tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED]) + adapter->response_expected = nla_get_flag( + tb[QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED]); + + if (adapter->response_expected) { + int skb_len = 0; + + adapter->oem_data_in_progress = true; + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("request allocation failure"); + ret = -ENOMEM; + goto err; + } + + adapter->cookie = osif_request_cookie(request); + + status = sme_oem_data_cmd(hdd_ctx->mac_handle, + hdd_oem_event_handler_cb, + &oem_data, adapter->vdev_id); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failure while sending command to fw"); + ret = -EAGAIN; + goto err; + } + ret = osif_request_wait_for_response(request); + if (ret) { + hdd_err("Timedout while retrieving oem get data"); + goto err; + } + + get_oem_data = osif_request_priv(request); + if (!get_oem_data || !(get_oem_data->data)) { + hdd_err("invalid get_oem_data"); + ret = -EINVAL; + goto err; + } + + skb_len = NLMSG_HDRLEN + NLA_HDRLEN + get_oem_data->data_len; + + skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + skb_len); + if (!skb) { + hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); + ret = -ENOMEM; + goto err; + } + + if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA, + get_oem_data->data_len, get_oem_data->data)) { + hdd_err("nla put failure"); + kfree_skb(skb); + ret = -EINVAL; + goto err; + } + wlan_cfg80211_vendor_cmd_reply(skb); + + } else { + status = sme_oem_data_cmd(hdd_ctx->mac_handle, + hdd_oem_event_handler_cb, + &oem_data, adapter->vdev_id); + return qdf_status_to_os_return(status); + } + +err: + if (request) + osif_request_put(request); + adapter->oem_data_in_progress = false; + adapter->response_expected = false; + + return ret; - return qdf_status_to_os_return(status); } int wlan_hdd_cfg80211_oem_data_handler(struct wiphy *wiphy, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_p2p.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_p2p.c index 97133f0e4e4595f007e51001147a06ca685f3a5b..b47d4b072b96497dde1db781e26bba1e87e1be25 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_p2p.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_p2p.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -51,7 +52,6 @@ #include "wlan_p2p_cfg_api.h" #include "wlan_policy_mgr_ucfg.h" #include "nan_ucfg_api.h" -#include "wlan_pkt_capture_ucfg_api.h" /* Ms to Time Unit Micro Sec */ #define MS_TO_TU_MUS(x) ((x) * 1024) @@ -451,6 +451,7 @@ int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command) hdd_debug("P2P_SET GO noa: count=%d interval=%d duration=%d", count, interval, duration); duration = MS_TO_TU_MUS(duration); + interval = MS_TO_TU_MUS(interval); /* PS Selection * Periodic noa (2) * Single NOA (4) @@ -458,15 +459,21 @@ int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command) noa.opp_ps = 0; noa.ct_window = 0; if (count == 1) { + if (duration > interval) + duration = interval; noa.duration = 0; noa.single_noa_duration = duration; noa.ps_selection = P2P_POWER_SAVE_TYPE_SINGLE_NOA; } else { + if (count && (duration >= interval)) { + hdd_err("Duration should be less than interval"); + return -EINVAL; + } noa.duration = duration; noa.single_noa_duration = 0; noa.ps_selection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA; } - noa.interval = MS_TO_TU_MUS(interval); + noa.interval = interval; noa.count = count; noa.vdev_id = adapter->vdev_id; @@ -644,6 +651,11 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, return ERR_PTR(-EINVAL); } + if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { + hdd_err("Concurrency not allowed with standalone monitor mode"); + return ERR_PTR(-EINVAL); + } + ret = wlan_hdd_validate_context(hdd_ctx); if (ret) return ERR_PTR(ret); @@ -681,17 +693,13 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, } adapter = NULL; - if ((ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) && - (type == NL80211_IFTYPE_MONITOR)) { - ret = wlan_hdd_add_monitor_check(hdd_ctx, &adapter, name, - true, name_assign_type); - if (ret) - return ERR_PTR(-EINVAL); - - if (adapter) { - hdd_exit(); - return adapter->dev->ieee80211_ptr; - } + ret = wlan_hdd_add_monitor_check(hdd_ctx, &adapter, type, name, + true, name_assign_type); + if (ret) + return ERR_PTR(-EINVAL); + if (adapter) { + hdd_exit(); + return adapter->dev->ieee80211_ptr; } adapter = NULL; @@ -709,10 +717,17 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, p2p_device_address.bytes, name_assign_type, true); } else { + uint8_t *device_address; + + device_address = wlan_hdd_get_intf_addr(hdd_ctx, mode); + if (!device_address) + return ERR_PTR(-EINVAL); + adapter = hdd_open_adapter(hdd_ctx, mode, name, - wlan_hdd_get_intf_addr(hdd_ctx, - mode), + device_address, name_assign_type, true); + if (!adapter) + wlan_hdd_release_intf_addr(hdd_ctx, device_address); } if (!adapter) { @@ -720,6 +735,8 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, return ERR_PTR(-ENOSPC); } + adapter->delete_in_progress = false; + /* ensure physcial soc is up */ ret = hdd_trigger_psoc_idle_restart(hdd_ctx); if (ret) { @@ -849,6 +866,7 @@ int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) } else if (wlan_hdd_is_session_type_monitor( adapter->device_mode)) { wlan_hdd_del_monitor(hdd_ctx, adapter, TRUE); + hdd_reset_pktcapture_cb(OL_TXRX_PDEV_ID); } else { wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); @@ -866,7 +884,9 @@ int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) { int errno; struct osif_vdev_sync *vdev_sync; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); + adapter->delete_in_progress = true; errno = osif_vdev_sync_trans_start_wait(wdev->netdev, &vdev_sync); if (errno) return errno; @@ -944,18 +964,17 @@ wlan_hdd_cfg80211_convert_rxmgmt_flags(enum rxmgmt_flags flag, static void __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, uint32_t frm_len, uint8_t *pb_frames, - uint8_t frame_type, uint32_t rx_chan, + uint8_t frame_type, uint32_t rx_freq, int8_t rx_rssi, enum rxmgmt_flags rx_flags) { - uint16_t freq; uint8_t type = 0; uint8_t sub_type = 0; struct hdd_context *hdd_ctx; uint8_t *dest_addr; enum nl80211_rxmgmt_flags nl80211_flag = 0; - hdd_debug("Frame Type = %d Frame Length = %d", - frame_type, frm_len); + hdd_debug("Frame Type = %d Frame Length = %d freq = %d", + frame_type, frm_len, rx_freq); if (!adapter) { hdd_err("adapter is NULL"); @@ -993,7 +1012,7 @@ __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, * we are dropping action frame */ hdd_err("adapter for action frame is NULL Macaddr = " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(dest_addr)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(dest_addr)); hdd_debug("Frame Type = %d Frame Length = %d subType = %d", frame_type, frm_len, sub_type); /* @@ -1026,12 +1045,6 @@ __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, /* Channel indicated may be wrong. TODO */ /* Indicate an action frame. */ - if (rx_chan <= MAX_NO_OF_2_4_CHANNELS) - freq = ieee80211_channel_to_frequency(rx_chan, - NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency(rx_chan, - NL80211_BAND_5GHZ); if (hdd_is_qos_action_frame(pb_frames, frm_len)) sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle, @@ -1046,23 +1059,23 @@ __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, - freq, rx_rssi * 100, pb_frames, + rx_freq, rx_rssi * 100, pb_frames, frm_len, NL80211_RXMGMT_FLAG_ANSWERED | nl80211_flag); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, - freq, rx_rssi * 100, pb_frames, + rx_freq, rx_rssi * 100, pb_frames, frm_len, NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); #else - cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, freq, - rx_rssi * 100, - pb_frames, frm_len, GFP_ATOMIC); + cfg80211_rx_mgmt(adapter->dev->ieee80211_ptr, rx_freq, + rx_rssi * 100, + pb_frames, frm_len, GFP_ATOMIC); #endif /* LINUX_VERSION_CODE */ } void hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, uint32_t frm_len, uint8_t *pb_frames, - uint8_t frame_type, uint32_t rx_chan, + uint8_t frame_type, uint32_t rx_freq, int8_t rx_rssi, enum rxmgmt_flags rx_flags) { int errno; @@ -1073,7 +1086,7 @@ void hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter, return; __hdd_indicate_mgmt_frame_to_user(adapter, frm_len, pb_frames, - frame_type, rx_chan, + frame_type, rx_freq, rx_rssi, rx_flags); osif_vdev_sync_op_stop(vdev_sync); } @@ -1216,16 +1229,18 @@ static uint32_t set_first_connection_operating_channel( enum QDF_OPMODE dev_mode) { uint8_t operating_channel; + uint32_t oper_chan_freq; - operating_channel = hdd_get_operating_channel( - hdd_ctx, dev_mode); - if (!operating_channel) { + oper_chan_freq = hdd_get_operating_chan_freq(hdd_ctx, dev_mode); + if (!oper_chan_freq) { hdd_err(" First adpter operating channel is invalid"); return -EINVAL; } + operating_channel = wlan_reg_freq_to_chan(hdd_ctx->pdev, + oper_chan_freq); hdd_info("First connection channel No.:%d and quota:%dms", - operating_channel, set_value); + operating_channel, set_value); /* Move the time quota for first channel to bits 15-8 */ set_value = set_value << 8; @@ -1255,8 +1270,9 @@ static uint32_t set_second_connection_operating_channel( { uint8_t operating_channel; - operating_channel = policy_mgr_get_mcc_operating_channel( - hdd_ctx->psoc, vdev_id); + operating_channel = wlan_freq_to_chan( + policy_mgr_get_mcc_operating_channel( + hdd_ctx->psoc, vdev_id)); if (operating_channel == 0) { hdd_err("Second adapter operating channel is invalid"); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_periodic_sta_stats.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_periodic_sta_stats.c index 1627f8528a1f1dc35d7f91917b8655ce0871b706..887813ba1ce96f0824cc52fd75eb369951486c14 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_periodic_sta_stats.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_periodic_sta_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -41,26 +41,31 @@ void hdd_periodic_sta_stats_init(struct hdd_adapter *adapter) void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; struct hdd_stats sta_stats; struct hdd_config *hdd_cfg; char *dev_name; bool should_log; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY; if (!hdd_ctx) return; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { should_log = false; - if (adapter->device_mode != QDF_STA_MODE) + if (adapter->device_mode != QDF_STA_MODE) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } hdd_cfg = hdd_ctx->config; qdf_mutex_acquire(&adapter->sta_periodic_stats_lock); if (!adapter->is_sta_periodic_stats_enabled) { qdf_mutex_release(&adapter->sta_periodic_stats_lock); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } @@ -89,6 +94,7 @@ void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx) hdd_nofl_info("%s: Rx DNS responses: %d", dev_name, sta_stats.hdd_dns_stats.rx_dns_rsp_count); } + hdd_adapter_dev_put_debug(adapter, dbgid); } } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c index b9a754721a16e29f98972cef0d249614f8792d82..f27a1eee511c52fb4d266cb37e10b19ebfe6f03b 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -62,6 +62,7 @@ #include #include +#include #include "hif.h" #include "hif_unit_test_suspend.h" #include "sme_power_save_api.h" @@ -79,8 +80,8 @@ #include #include "wlan_p2p_ucfg_api.h" #include "wlan_mlme_ucfg_api.h" +#include "wlan_osif_request_manager.h" #include -#include "wlan_pkt_capture_ucfg_api.h" #include "wlan_hdd_thermal.h" /* Preprocessor definitions and constants */ @@ -124,6 +125,46 @@ void hdd_wlan_offload_event(uint8_t type, uint8_t state) } #endif +#ifdef WLAN_FEATURE_PKT_CAPTURE + +/* timeout in msec to wait for RX_THREAD to suspend */ +#define HDD_MONTHREAD_SUSPEND_TIMEOUT 200 + +void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx) +{ + if (hdd_ctx->is_ol_mon_thread_suspended) { + cds_resume_mon_thread(); + hdd_ctx->is_ol_mon_thread_suspended = false; + } +} + +int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx) +{ + p_cds_sched_context cds_sched_context = get_cds_sched_ctxt(); + int rc; + + if (!cds_sched_context) + return -EINVAL; + + set_bit(RX_SUSPEND_EVENT, + &cds_sched_context->sched_mon_ctx.ol_mon_event_flag); + wake_up_interruptible(&cds_sched_context-> + sched_mon_ctx.ol_mon_wait_queue); + rc = wait_for_completion_timeout( + &cds_sched_context->sched_mon_ctx.ol_suspend_mon_event, + msecs_to_jiffies(HDD_MONTHREAD_SUSPEND_TIMEOUT)); + if (!rc) { + clear_bit(RX_SUSPEND_EVENT, + &cds_sched_context->sched_mon_ctx.ol_mon_event_flag); + hdd_err("Failed to stop tl_shim mon thread"); + return -EINVAL; + } + hdd_ctx->is_ol_mon_thread_suspended = true; + + return 0; +} +#endif + #ifdef QCA_CONFIG_SMP /* timeout in msec to wait for RX_THREAD to suspend */ @@ -217,6 +258,7 @@ static void hdd_disable_gtk_offload(struct hdd_adapter *adapter) /** * __wlan_hdd_ipv6_changed() - IPv6 notifier callback function * @net_dev: net_device whose IP address changed + * @event: event from kernel, NETDEV_UP or NETDEV_DOWN * * This is a callback function that is registered with the kernel via * register_inet6addr_notifier() which allows the driver to be @@ -224,7 +266,8 @@ static void hdd_disable_gtk_offload(struct hdd_adapter *adapter) * * Return: None */ -static void __wlan_hdd_ipv6_changed(struct net_device *net_dev) +static void __wlan_hdd_ipv6_changed(struct net_device *net_dev, + unsigned long event) { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); struct hdd_context *hdd_ctx; @@ -241,9 +284,12 @@ static void __wlan_hdd_ipv6_changed(struct net_device *net_dev) if (errno) goto exit; - if (adapter->device_mode == QDF_STA_MODE || - adapter->device_mode == QDF_P2P_CLIENT_MODE || - adapter->device_mode == QDF_NDI_MODE) { + /* Only need to be notified for ipv6_add_addr + * No need for ipv6_del_addr or addrconf_ifdown + */ + if (event == NETDEV_UP && + (adapter->device_mode == QDF_STA_MODE || + adapter->device_mode == QDF_P2P_CLIENT_MODE)) { hdd_debug("invoking sme_dhcp_done_ind"); sme_dhcp_done_ind(hdd_ctx->mac_handle, adapter->vdev_id); schedule_work(&adapter->ipv6_notifier_work); @@ -263,7 +309,7 @@ int wlan_hdd_ipv6_changed(struct notifier_block *nb, if (osif_vdev_sync_op_start(net_dev, &vdev_sync)) return NOTIFY_DONE; - __wlan_hdd_ipv6_changed(net_dev); + __wlan_hdd_ipv6_changed(net_dev, data); osif_vdev_sync_op_stop(vdev_sync); @@ -408,7 +454,7 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter, /* check if offload cache and send is required or not */ status = ucfg_pmo_ns_offload_check(psoc, trigger, adapter->vdev_id); if (QDF_IS_STATUS_ERROR(status)) { - hdd_info("NS offload is not required"); + hdd_debug("NS offload is not required"); goto free_req; } @@ -466,7 +512,7 @@ void hdd_disable_ns_offload(struct hdd_adapter *adapter, status = ucfg_pmo_ns_offload_check(hdd_ctx->psoc, trigger, adapter->vdev_id); if (status != QDF_STATUS_SUCCESS) { - hdd_err("Flushing of NS offload not required"); + hdd_debug("Flushing of NS offload not required"); goto out; } @@ -487,6 +533,34 @@ void hdd_disable_ns_offload(struct hdd_adapter *adapter, } +/** + * hdd_send_ps_config_to_fw() - Check user pwr save config set/reset PS + * @adapter: pointer to hdd adapter + * + * This function checks the power save configuration saved in MAC context + * and sends power save config to FW. + * + * Return: None + */ +static void hdd_send_ps_config_to_fw(struct hdd_adapter *adapter) +{ + struct mac_context *mac_ctx; + struct hdd_context *hdd_ctx; + + if (hdd_validate_adapter(adapter)) + return; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + mac_ctx = MAC_CONTEXT(hdd_ctx->mac_handle); + + if (mac_ctx->usr_cfg_ps_enable) + sme_ps_enable_disable(hdd_ctx->mac_handle, adapter->vdev_id, + SME_PS_ENABLE); + else + sme_ps_enable_disable(hdd_ctx->mac_handle, adapter->vdev_id, + SME_PS_DISABLE); +} + /** * __hdd_ipv6_notifier_work_queue() - IPv6 notification work function * @adapter: adapter whose IP address changed @@ -516,6 +590,7 @@ static void __hdd_ipv6_notifier_work_queue(struct hdd_adapter *adapter) hdd_enable_ns_offload(adapter, pmo_ipv6_change_notify); + hdd_send_ps_config_to_fw(adapter); exit: hdd_exit(); } @@ -638,7 +713,8 @@ void hdd_disable_host_offloads(struct hdd_adapter *adapter, hdd_disable_arp_offload(adapter, trigger); hdd_disable_ns_offload(adapter, trigger); hdd_disable_mc_addr_filtering(adapter, trigger); - hdd_disable_hw_filter(adapter); + if (adapter->device_mode != QDF_NDI_MODE) + hdd_disable_hw_filter(adapter); hdd_disable_action_frame_patterns(adapter); out: hdd_exit(); @@ -825,6 +901,7 @@ static void __hdd_ipv4_notifier_work_queue(struct hdd_adapter *adapter) if (ifa && hdd_ctx->is_fils_roaming_supported) sme_send_hlp_ie_info(hdd_ctx->mac_handle, adapter->vdev_id, roam_profile, ifa->ifa_local); + hdd_send_ps_config_to_fw(adapter); exit: hdd_exit(); } @@ -872,8 +949,7 @@ static void __wlan_hdd_ipv4_changed(struct net_device *net_dev) goto exit; if (adapter->device_mode == QDF_STA_MODE || - adapter->device_mode == QDF_P2P_CLIENT_MODE || - adapter->device_mode == QDF_NDI_MODE) { + adapter->device_mode == QDF_P2P_CLIENT_MODE) { hdd_debug("invoking sme_dhcp_done_ind"); sme_dhcp_done_ind(hdd_ctx->mac_handle, adapter->vdev_id); @@ -996,7 +1072,7 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter, status = ucfg_pmo_check_arp_offload(psoc, trigger, adapter->vdev_id); if (QDF_IS_STATUS_ERROR(status)) { - hdd_info("ARP offload not required"); + hdd_debug("ARP offload not required"); goto free_req; } @@ -1162,7 +1238,7 @@ hdd_suspend_wlan(void) { struct hdd_context *hdd_ctx; QDF_STATUS status; - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; uint32_t conn_state_mask = 0; hdd_info("WLAN being suspended by OS"); @@ -1179,9 +1255,13 @@ hdd_suspend_wlan(void) return -EINVAL; } - hdd_for_each_adapter(hdd_ctx, adapter) { - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_SUSPEND_WLAN) { + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) { + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_SUSPEND_WLAN); continue; + } /* stop all TX queues before suspend */ hdd_debug("Disabling queues for dev mode %s", @@ -1196,6 +1276,7 @@ hdd_suspend_wlan(void) /* Configure supported OffLoads */ hdd_enable_host_offloads(adapter, pmo_apps_suspend); hdd_update_conn_state_mask(adapter, &conn_state_mask); + hdd_adapter_dev_put_debug(adapter, NET_DEV_HOLD_SUSPEND_WLAN); } status = ucfg_pmo_psoc_user_space_suspend_req(hdd_ctx->psoc, @@ -1220,7 +1301,7 @@ hdd_suspend_wlan(void) static int hdd_resume_wlan(void) { struct hdd_context *hdd_ctx; - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; QDF_STATUS status; hdd_info("WLAN being resumed by OS"); @@ -1241,9 +1322,13 @@ static int hdd_resume_wlan(void) hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME); /*loop through all adapters. Concurrency */ - hdd_for_each_adapter(hdd_ctx, adapter) { - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_RESUME_WLAN) { + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) { + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_RESUME_WLAN); continue; + } /* Disable supported OffLoads */ hdd_disable_host_offloads(adapter, pmo_apps_resume); @@ -1257,6 +1342,8 @@ static int hdd_resume_wlan(void) if (adapter->device_mode == QDF_STA_MODE) status = hdd_disable_default_pkt_filters(adapter); + + hdd_adapter_dev_put_debug(adapter, NET_DEV_HOLD_RESUME_WLAN); } ucfg_ipa_resume(hdd_ctx->pdev); @@ -1289,17 +1376,20 @@ void hdd_svc_fw_shutdown_ind(struct device *dev) */ static void hdd_ssr_restart_sap(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; hdd_enter(); - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_SSR_RESTART_SAP) { if (adapter->device_mode == QDF_SAP_MODE) { if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) { hdd_debug("Restart prev SAP session"); wlan_hdd_start_sap(adapter, true); } } + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_SSR_RESTART_SAP); } hdd_exit(); @@ -1308,7 +1398,6 @@ static void hdd_ssr_restart_sap(struct hdd_context *hdd_ctx) QDF_STATUS hdd_wlan_shutdown(void) { struct hdd_context *hdd_ctx; - struct hdd_adapter *adapter; void *soc = cds_get_context(QDF_MODULE_ID_SOC); hdd_info("WLAN driver shutting down!"); @@ -1324,24 +1413,23 @@ QDF_STATUS hdd_wlan_shutdown(void) policy_mgr_clear_concurrent_session_count(hdd_ctx->psoc); hdd_debug("Invoking packetdump deregistration API"); - wlan_deregister_txrx_packetdump(); + wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); /* resume wlan threads before adapter reset which does vdev destroy */ if (hdd_ctx->is_scheduler_suspended) { scheduler_resume(); hdd_ctx->is_scheduler_suspended = false; hdd_ctx->is_wiphy_suspended = false; + ucfg_pmo_resume_all_components(hdd_ctx->psoc, + QDF_SYSTEM_SUSPEND); } wlan_hdd_rx_thread_resume(hdd_ctx); dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC)); - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) - ucfg_pkt_capture_resume_mon_thread(adapter->vdev); - } + if (cds_is_pktcapture_enabled()) + wlan_hdd_mon_thread_resume(hdd_ctx); /* * After SSR, FW clear its txrx stats. In host, @@ -1356,11 +1444,6 @@ QDF_STATUS hdd_wlan_shutdown(void) * increment their counts from 0. */ hdd_reset_all_adapters_connectivity_stats(hdd_ctx); - /* - * Purge all active and pending list to avoid vdev destroy timeout and - * thus avoid peer/vdev refcount leak. - */ - sme_purge_pdev_all_ser_cmd_list(hdd_ctx->mac_handle); hdd_reset_all_adapters(hdd_ctx); @@ -1415,9 +1498,10 @@ static inline void hdd_wlan_ssr_reinit_event(void) */ static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES) { if (hdd_is_interface_up(adapter) && (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_DEVICE_MODE) && @@ -1427,6 +1511,8 @@ static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx) adapter->scan_info.default_scan_ies, adapter->scan_info.default_scan_ies_len); } + hdd_adapter_dev_put_debug(adapter, + NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES); } } @@ -1542,6 +1628,10 @@ QDF_STATUS hdd_wlan_re_init(void) hdd_ssr_restart_sap(hdd_ctx); hdd_is_interface_down_during_ssr(hdd_ctx); hdd_wlan_ssr_reinit_event(); + + if (hdd_ctx->hdd_wlan_suspended) + hdd_ctx->hdd_wlan_suspended = false; + return QDF_STATUS_SUCCESS; err_re_init: @@ -1694,7 +1784,6 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) { struct hdd_context *hdd_ctx = wiphy_priv(wiphy); QDF_STATUS status = QDF_STATUS_SUCCESS; - struct hdd_adapter *adapter; int exit_code; hdd_enter(); @@ -1748,11 +1837,10 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) if (hdd_ctx->enable_dp_rx_threads) dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC)); - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) - ucfg_pkt_capture_resume_mon_thread(adapter->vdev); - } + if (cds_is_pktcapture_enabled()) + wlan_hdd_mon_thread_resume(hdd_ctx); + + ucfg_pmo_notify_system_resume(hdd_ctx->psoc); qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN, @@ -1774,15 +1862,21 @@ static int _wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) struct hdd_context *hdd_ctx = wiphy_priv(wiphy); int errno; - errno = wlan_hdd_validate_context(hdd_ctx); - if (errno) - return errno; + if(!hdd_ctx) { + hdd_err_rl("hdd context is null"); + return -ENODEV; + } + /* If Wifi is off, return success for system resume */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Modules not Enabled "); return 0; } + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); errno = __wlan_hdd_cfg80211_resume_wlan(wiphy); hif_pm_runtime_put(hif_ctx, RTPM_ID_SUSPEND_RESUME); @@ -1832,16 +1926,17 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, struct cfg80211_wowlan *wow) { struct hdd_context *hdd_ctx = wiphy_priv(wiphy); - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; mac_handle_t mac_handle; int rc; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CFG80211_SUSPEND_WLAN; hdd_enter(); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam() || QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in mode %d", - hdd_get_conparam()); + hdd_err_rl("Command not allowed in mode %d", + hdd_get_conparam()); return -EINVAL; } @@ -1849,6 +1944,9 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, if (0 != rc) return rc; + /* Wait for the stop module if already in progress */ + hdd_psoc_idle_timer_stop(hdd_ctx); + if (hdd_ctx->config->is_wow_disabled) { hdd_info_rl("wow is disabled"); return -EINVAL; @@ -1865,9 +1963,12 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, * "dfs_cac_block_tx" is set to true when RADAR is found and stay true * until CAC is done for a SoftAP which is in started state. */ - hdd_for_each_adapter(hdd_ctx, adapter) { - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } if (QDF_SAP_MODE == adapter->device_mode) { if (BSS_START == @@ -1878,6 +1979,10 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, hdd_err("RADAR detection in progress, do not allow suspend"); wlan_hdd_inc_suspend_stats(hdd_ctx, SUSPEND_FAIL_RADAR); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return -EAGAIN; } else if (!ucfg_pmo_get_enable_sap_suspend( hdd_ctx->psoc)) { @@ -1885,6 +1990,10 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, * suspend */ hdd_err("SAP does not support suspend!!"); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return -EOPNOTSUPP; } } else if (QDF_P2P_GO_MODE == adapter->device_mode) { @@ -1894,9 +2003,14 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, * suspend */ hdd_err("GO does not support suspend!!"); + hdd_adapter_dev_put_debug(adapter, dbgid); + if (next_adapter) + hdd_adapter_dev_put_debug(next_adapter, + dbgid); return -EOPNOTSUPP; } } + hdd_adapter_dev_put_debug(adapter, dbgid); } /* p2p cleanup task based on scheduler */ ucfg_p2p_cleanup_tx_by_psoc(hdd_ctx->psoc); @@ -1908,11 +2022,15 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, } /* flush any pending powersave timers */ - hdd_for_each_adapter(hdd_ctx, adapter) { - if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, + dbgid) { + if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) { + hdd_adapter_dev_put_debug(adapter, dbgid); continue; + } sme_ps_timer_flush_sync(mac_handle, adapter->vdev_id); + hdd_adapter_dev_put_debug(adapter, dbgid); } /* @@ -1960,11 +2078,9 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, goto resume_ol_rx; } - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) - if (ucfg_pkt_capture_suspend_mon_thread(adapter->vdev)) - goto resume_dp_thread; + if (cds_is_pktcapture_enabled()) { + if (wlan_hdd_mon_thread_suspend(hdd_ctx)) + goto resume_dp_thread; } qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, @@ -1985,12 +2101,9 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, if (hdd_ctx->enable_dp_rx_threads) dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC)); - /* Resume packet capture MON thread */ - if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) { - adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); - if (adapter) - ucfg_pkt_capture_resume_mon_thread(adapter->vdev); - } + /* Resume tlshim MON thread */ + if (cds_is_pktcapture_enabled()) + wlan_hdd_mon_thread_resume(hdd_ctx); resume_ol_rx: /* Resume tlshim Rx thread */ @@ -2010,15 +2123,21 @@ static int _wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, struct hdd_context *hdd_ctx = wiphy_priv(wiphy); int errno; - errno = wlan_hdd_validate_context(hdd_ctx); - if (errno) - return errno; + if(!hdd_ctx) { + hdd_err_rl("hdd context is null"); + return -ENODEV; + } + /* If Wifi is off, return success for system suspend */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Modules not Enabled "); return 0; } + errno = wlan_hdd_validate_context(hdd_ctx); + if (errno) + return errno; + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); errno = hif_pm_runtime_get_sync(hif_ctx, RTPM_ID_SUSPEND_RESUME); if (errno) @@ -2299,18 +2418,119 @@ int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy, return errno; } -#ifdef QCA_SUPPORT_CP_STATS static void wlan_hdd_get_tx_power(struct hdd_adapter *adapter, int *dbm) + { wlan_cfg80211_mc_cp_stats_get_tx_power(adapter->vdev, dbm); } -#else -static void wlan_hdd_get_tx_power(struct hdd_adapter *adapter, int *dbm) + +#ifdef FEATURE_ANI_LEVEL_REQUEST +static void hdd_get_ani_level_cb(struct wmi_host_ani_level_event *ani, + uint8_t num, void *context) +{ + struct osif_request *request; + struct ani_priv *priv; + uint8_t min_recv_freqs = QDF_MIN(num, MAX_NUM_FREQS_FOR_ANI_LEVEL); + + request = osif_request_get(context); + if (!request) { + hdd_err("Obsolete request"); + return; + } + + /* propagate response back to requesting thread */ + priv = osif_request_priv(request); + priv->ani = qdf_mem_malloc(min_recv_freqs * + sizeof(struct wmi_host_ani_level_event)); + if (!priv->ani) + goto complete; + + priv->num_freq = min_recv_freqs; + qdf_mem_copy(priv->ani, ani, + min_recv_freqs * sizeof(struct wmi_host_ani_level_event)); + +complete: + osif_request_complete(request); + osif_request_put(request); +} + +/** + * wlan_hdd_get_ani_level_dealloc() - Dealloc mem allocated in priv data + * @priv: the priv data + * + * Return: None + */ +static void wlan_hdd_get_ani_level_dealloc(void *priv) { - wlan_hdd_get_class_astats(adapter); - *dbm = adapter->hdd_stats.class_a_stat.max_pwr; + struct ani_priv *ani = priv; + + if (ani->ani) + qdf_mem_free(ani->ani); +} + +QDF_STATUS wlan_hdd_get_ani_level(struct hdd_adapter *adapter, + struct wmi_host_ani_level_event *ani, + uint32_t *parsed_freqs, + uint8_t num_freqs) +{ + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + int ret; + QDF_STATUS status; + void *cookie; + struct osif_request *request; + struct ani_priv *priv; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = 1000, + .dealloc = wlan_hdd_get_ani_level_dealloc, + }; + + if (!hdd_ctx) { + hdd_err("Invalid HDD context"); + return QDF_STATUS_E_INVAL; + } + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + cookie = osif_request_cookie(request); + + status = sme_get_ani_level(hdd_ctx->mac_handle, parsed_freqs, + num_freqs, hdd_get_ani_level_cb, cookie); + + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Unable to retrieve ani level"); + goto complete; + } else { + /* request was sent -- wait for the response */ + ret = osif_request_wait_for_response(request); + if (ret) { + hdd_err("SME timed out while retrieving ANI level"); + status = QDF_STATUS_E_TIMEOUT; + goto complete; + } + } + + priv = osif_request_priv(request); + + qdf_mem_copy(ani, priv->ani, sizeof(struct wmi_host_ani_level_event) * + priv->num_freq); + +complete: + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + osif_request_put(request); + + hdd_exit(); + return status; } #endif + /** * __wlan_hdd_cfg80211_get_txpower() - get TX power * @wiphy: Pointer to wiphy @@ -2412,43 +2632,39 @@ int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, return errno; } -int hdd_set_qpower_config(struct hdd_context *hddctx, - struct hdd_adapter *adapter, - u8 qpower) +int hdd_set_power_config(struct hdd_context *hddctx, + struct hdd_adapter *adapter, + uint8_t power) { QDF_STATUS status; - if (!ucfg_pmo_get_power_save_mode(hddctx->psoc)) { - hdd_err("qpower is disabled in configuration"); - return -EINVAL; - } if (adapter->device_mode != QDF_STA_MODE && adapter->device_mode != QDF_P2P_CLIENT_MODE) { - hdd_info("QPOWER only allowed in STA/P2P-Client modes:%d", + hdd_info("Advanced power save only allowed in STA/P2P-Client modes:%d", adapter->device_mode); return -EINVAL; } - if (qpower > PS_DUTY_CYCLING_QPOWER || - qpower < PS_LEGACY_NODEEPSLEEP) { - hdd_err("invalid qpower value: %d", qpower); + if (power > PMO_PS_ADVANCED_POWER_SAVE_ENABLE || + power < PMO_PS_ADVANCED_POWER_SAVE_DISABLE) { + hdd_err("invalid power value: %d", power); return -EINVAL; } if (ucfg_pmo_get_max_ps_poll(hddctx->psoc)) { - if ((qpower == PS_QPOWER_NODEEPSLEEP) || - (qpower == PS_LEGACY_NODEEPSLEEP)) - qpower = PS_LEGACY_NODEEPSLEEP; - else - qpower = PS_LEGACY_DEEPSLEEP; - hdd_info("Qpower disabled, %d", qpower); - } - status = wma_set_qpower_config(adapter->vdev_id, qpower); + hdd_info("Disable advanced power save since max ps poll is enabled"); + power = PMO_PS_ADVANCED_POWER_SAVE_DISABLE; + } + + status = wma_set_power_config(adapter->vdev_id, power); if (status != QDF_STATUS_SUCCESS) { - hdd_err("failed to configure qpower: %d", status); + hdd_err("failed to configure power: %d", status); return -EINVAL; } + /* cache latest userspace power save config to reapply after SSR */ + ucfg_pmo_set_power_save_mode(hddctx->psoc, power); + return 0; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_regulatory.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_regulatory.c index 565b4b51aaeb707d007f88c32792dda9f41f9220..3bc1b0a86e882e82d3d50dbf3fd85dac196a33ad 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_regulatory.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_regulatory.c @@ -208,11 +208,11 @@ void hdd_reset_global_reg_params(void) static void reg_program_config_vars(struct hdd_context *hdd_ctx, struct reg_config_vars *config_vars) { - uint8_t band_capability = 0, indoor_chnl_marking = 0; - uint32_t scan_11d_interval = 0; + uint8_t indoor_chnl_marking = 0; + uint32_t band_capability = 0, scan_11d_interval = 0; bool indoor_chan_enabled = false; uint32_t restart_beaconing = 0; - bool enable_srd_chan = false; + uint8_t enable_srd_chan; QDF_STATUS status; bool country_priority = 0; bool value = false; @@ -232,6 +232,9 @@ static void reg_program_config_vars(struct hdd_context *hdd_ctx, hdd_err("Invalid 11d_enable flag"); config_vars->enable_11d_support = value; + ucfg_mlme_get_nol_across_regdmn(hdd_ctx->psoc, &value); + config_vars->retain_nol_across_regdmn_update = value; + ucfg_mlme_get_scan_11d_interval(hdd_ctx->psoc, &scan_11d_interval); config_vars->scan_11d_interval = scan_11d_interval; @@ -255,8 +258,8 @@ static void reg_program_config_vars(struct hdd_context *hdd_ctx, &restart_beaconing); config_vars->restart_beaconing = restart_beaconing; - ucfg_mlme_get_etsi13_srd_chan_in_master_mode(hdd_ctx->psoc, - &enable_srd_chan); + ucfg_mlme_get_etsi_srd_chan_in_master_mode(hdd_ctx->psoc, + &enable_srd_chan); config_vars->enable_srd_chan_in_master_mode = enable_srd_chan; ucfg_mlme_get_11d_in_world_mode(hdd_ctx->psoc, @@ -659,7 +662,7 @@ void hdd_update_indoor_channel(struct hdd_context *hdd_ctx, { int band_num; int chan_num; - enum channel_enum chan_enum = CHAN_ENUM_1; + enum channel_enum chan_enum = CHAN_ENUM_2412; struct ieee80211_channel *wiphy_chan, *wiphy_chan_144 = NULL; struct regulatory_channel *cds_chan; uint8_t band_capability; @@ -682,7 +685,7 @@ void hdd_update_indoor_channel(struct hdd_context *hdd_ctx, wiphy_chan = &(wiphy->bands[band_num]->channels[chan_num]); cds_chan = &(reg_channels[chan_enum]); - if (chan_enum == CHAN_ENUM_144) + if (chan_enum == CHAN_ENUM_5720) wiphy_chan_144 = wiphy_chan; chan_enum++; @@ -746,111 +749,60 @@ int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code) return qdf_status_to_os_return(status); } -int hdd_reg_set_band(struct net_device *dev, u8 ui_band) +uint32_t hdd_reg_legacy_setband_to_reg_wifi_band_bitmap(uint8_t qca_setband) { - struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - mac_handle_t mac_handle; - enum band_info band; - QDF_STATUS status; - struct hdd_context *hdd_ctx; - enum band_info current_band; - enum band_info connected_band; - uint8_t band_capability; - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint32_t band_bitmap = 0; - switch (ui_band) { - case WLAN_HDD_UI_BAND_AUTO: - band = BAND_ALL; + switch (qca_setband) { + case QCA_SETBAND_AUTO: + band_bitmap |= (BIT(REG_BAND_2G) | BIT(REG_BAND_5G)); break; - case WLAN_HDD_UI_BAND_5_GHZ: - band = BAND_5G; + case QCA_SETBAND_5G: + band_bitmap |= BIT(REG_BAND_5G); break; - case WLAN_HDD_UI_BAND_2_4_GHZ: - band = BAND_2G; + case QCA_SETBAND_2G: + band_bitmap |= BIT(REG_BAND_2G); break; default: - hdd_err("Invalid band value %u", ui_band); - return -EINVAL; + hdd_err("Invalid band value %u", qca_setband); + return 0; } - hdd_debug("change band to %u", band); + return band_bitmap; +} - status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); - if (QDF_IS_STATUS_ERROR(status)) - return -EIO; +int hdd_reg_set_band(struct net_device *dev, uint32_t band_bitmap) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_context *hdd_ctx; + uint32_t current_band; - if ((band == BAND_2G && band_capability == 2) || - (band == BAND_5G && band_capability == 1) || - (band == BAND_ALL && band_capability != 0)) { - hdd_err("band value %u violate INI settings %u", - band, band_capability); - return -EIO; - } + hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (band == BAND_ALL) { - hdd_debug("Auto band received. Setting band same as ini value %d", - band_capability); - band = band_capability; + if (!band_bitmap) { + hdd_err("Can't disable all bands"); + return -EINVAL; } - if (ucfg_reg_get_curr_band(hdd_ctx->pdev, ¤t_band) != + hdd_debug("change band to %u", band_bitmap); + + if (ucfg_reg_get_band(hdd_ctx->pdev, ¤t_band) != QDF_STATUS_SUCCESS) { hdd_debug("Failed to get current band config"); return -EIO; } - if (current_band == band) + if (current_band == band_bitmap) { + hdd_debug("band is the same so not updating"); return 0; - - hdd_ctx->curr_band = band; - - /* Change band request received. - * Abort pending scan requests, flush the existing scan results, - * and change the band capability - */ - hdd_debug("Current band value = %u, new setting %u ", - current_band, band); - - mac_handle = hdd_ctx->mac_handle; - hdd_for_each_adapter(hdd_ctx, adapter) { - wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, - adapter->vdev_id, INVALID_SCAN_ID, false); - connected_band = hdd_conn_get_connected_band( - WLAN_HDD_GET_STATION_CTX_PTR(adapter)); - - /* Handling is done only for STA and P2P */ - if (band != BAND_ALL && - ((adapter->device_mode == QDF_STA_MODE) || - (adapter->device_mode == QDF_P2P_CLIENT_MODE)) && - (hdd_conn_is_connected( - WLAN_HDD_GET_STATION_CTX_PTR(adapter))) - && (connected_band != band)) { - status = QDF_STATUS_SUCCESS; - - /* STA already connected on current - * band, So issue disconnect first, - * then change the band - */ - - hdd_debug("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect", - qdf_opmode_str(adapter->device_mode), - adapter->device_mode, current_band, band); - - status = wlan_hdd_disconnect(adapter, - eCSR_DISCONNECT_REASON_UNSPECIFIED, - eSIR_MAC_OPER_CHANNEL_BAND_CHANGE); - if (status) { - hdd_err("Hdd disconnect failed, status: %d", - status); - return -EINVAL; - } - } - ucfg_scan_flush_results(hdd_ctx->pdev, NULL); } - if (QDF_IS_STATUS_ERROR(ucfg_reg_set_band(hdd_ctx->pdev, band))) { - hdd_err("Failed to set the band value to %u", band); + hdd_ctx->curr_band = wlan_reg_band_bitmap_to_band_info(band_bitmap); + + if (QDF_IS_STATUS_ERROR(ucfg_reg_set_band(hdd_ctx->pdev, + band_bitmap))) { + hdd_err("Failed to set the band bitmap value to %u", + band_bitmap); return -EINVAL; } @@ -1158,6 +1110,7 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt, { uint16_t *local_unsafe_list; uint16_t local_unsafe_list_count; + uint8_t i; /* Basic sanity */ if (!hdd_ctxt) { @@ -1182,10 +1135,12 @@ void hdd_ch_avoid_ind(struct hdd_context *hdd_ctxt, qdf_mem_zero(hdd_ctxt->unsafe_channel_list, sizeof(hdd_ctxt->unsafe_channel_list)); - hdd_ctxt->unsafe_channel_count = unsafe_chan_list->ch_cnt; + hdd_ctxt->unsafe_channel_count = unsafe_chan_list->chan_cnt; - qdf_mem_copy(hdd_ctxt->unsafe_channel_list, unsafe_chan_list->ch_list, - sizeof(hdd_ctxt->unsafe_channel_list)); + for (i = 0; i < unsafe_chan_list->chan_cnt; i++) { + hdd_ctxt->unsafe_channel_list[i] = + unsafe_chan_list->chan_freq_list[i]; + } hdd_debug("number of unsafe channels is %d ", hdd_ctxt->unsafe_channel_count); @@ -1245,6 +1200,7 @@ static void map_nl_reg_rule_flags(uint16_t drv_reg_rule_flag, *regd_rule_flag |= NL80211_RRF_NO_OUTDOOR; if (drv_reg_rule_flag & REGULATORY_CHAN_NO_OFDM) *regd_rule_flag |= NL80211_RRF_NO_OFDM; + *regd_rule_flag |= NL80211_RRF_AUTO_BW; } /** @@ -1270,6 +1226,26 @@ static enum nl80211_dfs_regions dfs_reg_to_nl80211_dfs_regions( } } +/** + * hdd_set_dfs_pri_multiplier() - Set dfs_pri_multiplier for ETSI region + * @dfs_region: DFS region + * + * Return: none + */ +#ifdef DFS_PRI_MULTIPLIER +static void hdd_set_dfs_pri_multiplier(struct hdd_context *hdd_ctx, + enum dfs_reg dfs_region) +{ + if (dfs_region == DFS_ETSI_REGION) + wlan_sap_set_dfs_pri_multiplier(hdd_ctx->mac_handle); +} +#else +static inline void hdd_set_dfs_pri_multiplier(struct hdd_context *hdd_ctx, + enum dfs_reg dfs_region) +{ +} +#endif + void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx) { struct ieee80211_regdomain *regd; @@ -1307,6 +1283,9 @@ void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx) qdf_mem_copy(regd->alpha2, reg_rules->alpha2, REG_ALPHA2_LEN + 1); regd->dfs_region = dfs_reg_to_nl80211_dfs_regions(reg_rules->dfs_region); + + hdd_set_dfs_pri_multiplier(hdd_ctx, reg_rules->dfs_region); + regd_rules = regd->reg_rules; hdd_debug("Regulatory Domain %s", regd->alpha2); hdd_debug("start freq\tend freq\t@ max_bw\tant_gain\tpwr\tflags"); @@ -1339,6 +1318,60 @@ void hdd_send_wiphy_regd_sync_event(struct hdd_context *hdd_ctx) } #endif +#if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ + (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) +static void +fill_wiphy_6ghz_band_channels(struct wiphy *wiphy, + struct regulatory_channel *chan_list) +{ + fill_wiphy_band_channels(wiphy, chan_list, NL80211_BAND_6GHZ); +} +#else +static void +fill_wiphy_6ghz_band_channels(struct wiphy *wiphy, + struct regulatory_channel *chan_list) +{ +} +#endif + +#define HDD_MAX_CHAN_INFO_LOG 192 + +/** + * hdd_regulatory_chanlist_dump() - Dump regulatory channel list info + * @chan_list: regulatory channel list + * + * Return: void + */ +static void hdd_regulatory_chanlist_dump(struct regulatory_channel *chan_list) +{ + uint32_t i; + uint8_t info[HDD_MAX_CHAN_INFO_LOG]; + int len = 0; + struct regulatory_channel *chan; + uint32_t count = 0; + int ret; + + hdd_debug("start (freq MHz, tx power dBm):"); + for (i = 0; i < NUM_CHANNELS; i++) { + chan = &chan_list[i]; + if ((chan->chan_flags & REGULATORY_CHAN_DISABLED)) + continue; + count++; + ret = scnprintf(info + len, sizeof(info) - len, "%d %d ", + chan->center_freq, chan->tx_power); + if (ret <= 0) + break; + len += ret; + if (len >= (sizeof(info) - 20)) { + hdd_debug("%s", info); + len = 0; + } + } + if (len > 0) + hdd_debug("%s", info); + hdd_debug("end total_count %d", count); +} + static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev, struct regulatory_channel *chan_list, @@ -1356,10 +1389,11 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc, hdd_ctx = wiphy_priv(wiphy); hdd_debug("process channel list update from regulatory"); + hdd_regulatory_chanlist_dump(chan_list); fill_wiphy_band_channels(wiphy, chan_list, NL80211_BAND_2GHZ); fill_wiphy_band_channels(wiphy, chan_list, NL80211_BAND_5GHZ); - + fill_wiphy_6ghz_band_channels(wiphy, chan_list); cc_src = ucfg_reg_get_cc_and_src(hdd_ctx->psoc, alpha2); qdf_mem_copy(hdd_ctx->reg.alpha2, alpha2, REG_ALPHA2_LEN + 1); sme_set_cc_src(hdd_ctx->mac_handle, cc_src); @@ -1399,14 +1433,20 @@ int hdd_update_regulatory_config(struct hdd_context *hdd_ctx) int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy) { bool offload_enabled; - struct regulatory_channel cur_chan_list[NUM_CHANNELS]; + struct regulatory_channel *cur_chan_list; enum country_src cc_src; uint8_t alpha2[REG_ALPHA2_LEN + 1]; + cur_chan_list = qdf_mem_malloc(sizeof(*cur_chan_list) * NUM_CHANNELS); + if (!cur_chan_list) { + return -ENOMEM; + } + ucfg_reg_register_chan_change_callback(hdd_ctx->psoc, hdd_regulatory_dyn_cbk, NULL); + wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; /* Check the kernel version for upstream commit aced43ce780dc5 that * has support for processing user cell_base hints when wiphy is @@ -1423,11 +1463,12 @@ int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy) hdd_ctx->reg_offload = true; ucfg_reg_get_current_chan_list(hdd_ctx->pdev, cur_chan_list); + hdd_regulatory_chanlist_dump(cur_chan_list); fill_wiphy_band_channels(wiphy, cur_chan_list, NL80211_BAND_2GHZ); fill_wiphy_band_channels(wiphy, cur_chan_list, NL80211_BAND_5GHZ); - + fill_wiphy_6ghz_band_channels(wiphy, cur_chan_list); cc_src = ucfg_reg_get_cc_and_src(hdd_ctx->psoc, alpha2); qdf_mem_copy(hdd_ctx->reg.alpha2, alpha2, REG_ALPHA2_LEN + 1); sme_set_cc_src(hdd_ctx->mac_handle, cc_src); @@ -1435,6 +1476,7 @@ int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy) hdd_ctx->reg_offload = false; } + qdf_mem_free(cur_chan_list); return 0; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rssi_monitor.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rssi_monitor.c index 5fa6511ebb160a0dd57a207edf119b79a97b53bd..06c21aa6d42db41c08eb906279c2cc13f63c275c 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rssi_monitor.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rssi_monitor.c @@ -206,8 +206,8 @@ void hdd_rssi_threshold_breached(hdd_handle_t hdd_handle, hdd_debug("Req Id: %u Current rssi: %d", data->request_id, data->curr_rssi); - hdd_debug("Current BSSID: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(data->curr_bssid.bytes)); + hdd_debug("Current BSSID: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(data->curr_bssid.bytes)); if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, data->request_id) || diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.c index fc1b479186f64dffa982b83b01165ba1470e55b4..082134e59cdad8f86196bf5898263770e6321861 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.c @@ -24,6 +24,7 @@ #include #include #include "wlan_hdd_rx_monitor.h" +#include "ol_txrx.h" /** * hdd_rx_monitor_callback(): Callback function for receive monitor mode @@ -120,11 +121,13 @@ void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx, int hdd_enable_monitor_mode(struct net_device *dev) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + uint8_t vdev_id; hdd_enter_dev(dev); - return cdp_set_monitor_mode(soc, - (struct cdp_vdev *)cdp_get_mon_vdev_from_pdev(soc, - (struct cdp_pdev *)pdev), false); + vdev_id = cdp_get_mon_vdev_from_pdev(soc, OL_TXRX_PDEV_ID); + if (vdev_id < 0) + return -EINVAL; + + return cdp_set_monitor_mode(soc, vdev_id, false); } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.h index 61f8ed231d711cfc069df855d43ba2c4e3cfe07e..49a8cb07b8c2afb9f0e3e2dacf16d7dd7e446fb6 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_rx_monitor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -21,7 +21,8 @@ struct ol_txrx_ops; -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx, ol_txrx_rx_mon_fp rx_monitor_cb); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c index f1c4903255f876a978e04ead06362c4e43fc7ff7..5bfa6a928a8c200f5f40b437d356ee9937f0afd0 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c @@ -83,8 +83,8 @@ static int wlan_hdd_set_chan_before_pre_cac(struct hdd_adapter *ap_adapter, * wlan_hdd_validate_and_get_pre_cac_ch() - Validate and get pre cac channel * @hdd_ctx: HDD context * @ap_adapter: AP adapter - * @channel: Channel requested by userspace - * @pre_cac_chan: Pointer to the pre CAC channel + * @chan_freq: Channel frequency requested by userspace + * @pre_cac_chan_freq: Pointer to the pre CAC channel frequency storage * * Validates the channel provided by userspace. If user provided channel 0, * a valid outdoor channel must be selected from the regulatory channel. @@ -93,18 +93,18 @@ static int wlan_hdd_set_chan_before_pre_cac(struct hdd_adapter *ap_adapter, */ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, struct hdd_adapter *ap_adapter, - uint8_t channel, - uint8_t *pre_cac_chan) + uint32_t chan_freq, + uint32_t *pre_cac_chan_freq) { uint32_t i; QDF_STATUS status; uint32_t weight_len = 0; uint32_t len = CFG_VALID_CHANNEL_LIST_LEN; - uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0}; - uint8_t pcl_weights[QDF_MAX_NUM_CHAN] = {0}; + uint32_t freq_list[NUM_CHANNELS] = {0}; + uint8_t pcl_weights[NUM_CHANNELS] = {0}; mac_handle_t mac_handle; - if (channel == 0) { + if (!chan_freq) { /* Channel is not obtained from PCL because PCL may not have * the entire channel list. For example: if SAP is up on * channel 6 and PCL is queried for the next SAP interface, @@ -113,23 +113,23 @@ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, * first channel from the valid channel list. */ status = policy_mgr_get_valid_chans(hdd_ctx->psoc, - channel_list, &len); + freq_list, &len); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Failed to get channel list"); return -EINVAL; } policy_mgr_update_with_safe_channel_list(hdd_ctx->psoc, - channel_list, &len, + freq_list, &len, pcl_weights, weight_len); for (i = 0; i < len; i++) { - if (wlan_reg_is_dfs_ch(hdd_ctx->pdev, - channel_list[i])) { - *pre_cac_chan = channel_list[i]; + if (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, + freq_list[i])) { + *pre_cac_chan_freq = freq_list[i]; break; } } - if (*pre_cac_chan == 0) { + if (*pre_cac_chan_freq == 0) { hdd_err("unable to find outdoor channel"); return -EINVAL; } @@ -139,21 +139,21 @@ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, * the user is expected to take care of this. */ mac_handle = hdd_ctx->mac_handle; - if (!sme_is_channel_valid(mac_handle, channel) || - !wlan_reg_is_dfs_ch(hdd_ctx->pdev, channel)) { - hdd_err("Invalid channel for pre cac:%d", channel); + if (!sme_is_channel_valid(mac_handle, chan_freq) || + !wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, chan_freq)) { + hdd_err("Invalid channel for pre cac:%d", chan_freq); return -EINVAL; } - *pre_cac_chan = channel; + *pre_cac_chan_freq = chan_freq; } - hdd_debug("selected pre cac channel:%d", *pre_cac_chan); + hdd_debug("selected pre cac channel:%d", *pre_cac_chan_freq); return 0; } /** * __wlan_hdd_request_pre_cac() - Start pre CAC in the driver * @hdd_ctx: the HDD context to operate against - * @channel: Channel option provided by userspace + * @chan_freq: Channel frequency option provided by userspace * @out_adapter: out parameter for the newly created pre-cac adapter * * Sets the driver to the required hardware mode and start an adapter for @@ -162,10 +162,11 @@ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, * Return: Zero on success, non-zero value on error */ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, - uint8_t channel, + uint32_t chan_freq, struct hdd_adapter **out_adapter) { - uint8_t pre_cac_chan = 0, *mac_addr; + uint8_t *mac_addr; + uint32_t pre_cac_chan_freq = 0; int ret; struct hdd_adapter *ap_adapter, *pre_cac_adapter; struct hdd_ap_ctx *hdd_ap_ctx; @@ -174,11 +175,15 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, struct net_device *dev; struct cfg80211_chan_def chandef; enum nl80211_channel_type channel_type; - uint32_t freq; struct ieee80211_channel *chan; mac_handle_t mac_handle; bool val; + if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { + hdd_debug("Pre CAC is not supported on non-dbs platforms"); + return -EINVAL; + } + if (policy_mgr_get_connection_count(hdd_ctx->psoc) > 1) { hdd_err("pre cac not allowed in concurrency"); return -EINVAL; @@ -203,16 +208,16 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, return -EINVAL; } - if (wlan_reg_is_dfs_ch(hdd_ctx->pdev, - hdd_ap_ctx->operating_channel)) { + if (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, + hdd_ap_ctx->operating_chan_freq)) { hdd_err("SAP is already on DFS channel:%d", - hdd_ap_ctx->operating_channel); + hdd_ap_ctx->operating_chan_freq); return -EINVAL; } - if (!WLAN_REG_IS_24GHZ_CH(hdd_ap_ctx->operating_channel)) { + if (!WLAN_REG_IS_24GHZ_CH_FREQ(hdd_ap_ctx->operating_chan_freq)) { hdd_err("pre CAC alllowed only when SAP is in 2.4GHz:%d", - hdd_ap_ctx->operating_channel); + hdd_ap_ctx->operating_chan_freq); return -EINVAL; } @@ -222,10 +227,10 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, return -EINVAL; } - hdd_debug("channel:%d", channel); + hdd_debug("channel: %d", chan_freq); - ret = wlan_hdd_validate_and_get_pre_cac_ch(hdd_ctx, ap_adapter, channel, - &pre_cac_chan); + ret = wlan_hdd_validate_and_get_pre_cac_ch( + hdd_ctx, ap_adapter, chan_freq, &pre_cac_chan_freq); if (ret != 0) { hdd_err("can't validate pre-cac channel"); goto release_intf_addr_and_return_failure; @@ -299,8 +304,8 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, channel_type = NL80211_CHAN_HT20; break; case CH_WIDTH_40MHZ: - if (ap_adapter->session.ap.sap_config.sec_ch > - ap_adapter->session.ap.sap_config.channel) + if (ap_adapter->session.ap.sap_config.sec_ch_freq > + ap_adapter->session.ap.sap_config.chan_freq) channel_type = NL80211_CHAN_HT40PLUS; else channel_type = NL80211_CHAN_HT40MINUS; @@ -310,18 +315,16 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, break; } - freq = cds_chan_to_freq(pre_cac_chan); - chan = ieee80211_get_channel(wiphy, freq); + chan = ieee80211_get_channel(wiphy, pre_cac_chan_freq); if (!chan) { hdd_err("channel converion failed"); goto stop_close_pre_cac_adapter; } - cfg80211_chandef_create(&chandef, chan, channel_type); hdd_debug("orig width:%d channel_type:%d freq:%d", ap_adapter->session.ap.sap_config.ch_width_orig, - channel_type, freq); + channel_type, pre_cac_chan_freq); /* * Doing update after opening and starting pre-cac adapter will make * sure that driver won't do hardware mode change if there are any @@ -330,10 +333,8 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, * connection update should result in DBS mode */ status = policy_mgr_update_and_wait_for_connection_update( - hdd_ctx->psoc, - ap_adapter->vdev_id, - pre_cac_chan, - POLICY_MGR_UPDATE_REASON_PRE_CAC); + hdd_ctx->psoc, ap_adapter->vdev_id, pre_cac_chan_freq, + POLICY_MGR_UPDATE_REASON_PRE_CAC); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("error in moving to DBS mode"); goto stop_close_pre_cac_adapter; @@ -364,14 +365,17 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, goto stop_close_pre_cac_adapter; } - ret = wlan_hdd_set_chan_before_pre_cac(ap_adapter, - hdd_ap_ctx->operating_channel); + ret = wlan_hdd_set_chan_before_pre_cac( + ap_adapter, + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + hdd_ap_ctx->operating_chan_freq)); if (ret != 0) { hdd_err("failed to set channel before pre cac"); goto stop_close_pre_cac_adapter; } - ap_adapter->pre_cac_chan = pre_cac_chan; + ap_adapter->pre_cac_freq = pre_cac_chan_freq; *out_adapter = pre_cac_adapter; @@ -394,7 +398,7 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, return -EINVAL; } -int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint8_t channel) +int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint32_t chan_freq) { struct hdd_adapter *adapter; struct osif_vdev_sync *vdev_sync; @@ -405,7 +409,7 @@ int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint8_t channel) if (errno) return errno; - errno = __wlan_hdd_request_pre_cac(hdd_ctx, channel, &adapter); + errno = __wlan_hdd_request_pre_cac(hdd_ctx, chan_freq, &adapter); if (errno) goto destroy_sync; @@ -447,7 +451,6 @@ __wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy, *tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX + 1]; uint32_t freq_len, i; uint32_t *freq; - uint8_t chans[QDF_MAX_NUM_CHAN] = {0}; bool is_dfs_mode_enabled = false; hdd_enter_dev(dev); @@ -499,7 +502,7 @@ __wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST])/ sizeof(uint32_t); - if (freq_len > QDF_MAX_NUM_CHAN) { + if (freq_len > NUM_CHANNELS) { hdd_err("insufficient space to hold channels"); return -ENOMEM; } @@ -509,14 +512,8 @@ __wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy, freq = nla_data( tb[QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST]); - for (i = 0; i < freq_len; i++) { - if (freq[i] == 0) - chans[i] = 0; - else - chans[i] = ieee80211_frequency_to_channel(freq[i]); - + for (i = 0; i < freq_len; i++) hdd_debug("freq[%d]=%d", i, freq[i]); - } /* * The input frequency list from user space is designed to be a @@ -527,7 +524,7 @@ __wlan_hdd_cfg80211_conditional_chan_switch(struct wiphy *wiphy, * If channel is zero, any channel in the available outdoor regulatory * domain will be selected. */ - ret = wlan_hdd_request_pre_cac(hdd_ctx, chans[0]); + ret = wlan_hdd_request_pre_cac(hdd_ctx, freq[0]); if (ret) { hdd_err("pre cac request failed with reason:%d", ret); return ret; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c index 24952d94f6c895fae73471dc2f49651d6875e56b..1b427fdcc443f1d92005076036c7cf9ceee87099 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c @@ -42,9 +42,6 @@ #include "wlan_p2p_ucfg_api.h" #include "cfg_ucfg_api.h" -#ifdef WLAN_UMAC_CONVERGENCE -#include "wlan_cfg80211.h" -#endif #include #include #include "wlan_utility.h" @@ -234,9 +231,9 @@ static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx, if (hdd_ctx->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN) return false; qdf_spin_lock(&hdd_ctx->acs_skip_lock); - if (!hdd_ctx->last_acs_channel_list || - hdd_ctx->num_of_channels == 0 || - request->n_channels == 0) { + if (!hdd_ctx->last_acs_freq_list || + hdd_ctx->num_of_channels == 0 || + request->n_channels == 0) { qdf_spin_unlock(&hdd_ctx->acs_skip_lock); return false; } @@ -245,16 +242,16 @@ static bool wlan_hdd_sap_skip_scan_check(struct hdd_context *hdd_ctx, bool find = false; for (j = 0; j < hdd_ctx->num_of_channels; j++) { - if (hdd_ctx->last_acs_channel_list[j] == - request->channels[i]->hw_value) { + if (hdd_ctx->last_acs_freq_list[j] == + request->channels[i]->center_freq) { find = true; break; } } if (!find) { skip = false; - hdd_debug("Chan %d isn't in ACS chan list", - request->channels[i]->hw_value); + hdd_debug("Freq %d isn't in ACS freq list", + request->channels[i]->center_freq); break; } } @@ -463,7 +460,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, int status; struct hdd_scan_info *scan_info = NULL; struct hdd_adapter *con_sap_adapter; - uint16_t con_dfs_ch; + uint32_t con_dfs_ch_freq; uint8_t curr_vdev_id; enum scan_reject_states curr_reason; static uint32_t scan_ebusy_cnt; @@ -537,14 +534,15 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, /* Block All Scan during DFS operation and send null scan result */ con_sap_adapter = hdd_get_con_sap_adapter(adapter, true); if (con_sap_adapter) { - con_dfs_ch = con_sap_adapter->session.ap.sap_config.channel; - if (con_dfs_ch == AUTO_CHANNEL_SELECT) - con_dfs_ch = - con_sap_adapter->session.ap.operating_channel; + con_dfs_ch_freq = + con_sap_adapter->session.ap.sap_config.chan_freq; + if (con_dfs_ch_freq == AUTO_CHANNEL_SELECT) + con_dfs_ch_freq = + con_sap_adapter->session.ap.operating_chan_freq; if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) && - wlan_reg_is_dfs_ch(hdd_ctx->pdev, con_dfs_ch) && - !policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( + wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, con_dfs_ch_freq) && + !policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( hdd_ctx->psoc)) { /* Provide empty scan result during DFS operation since * scanning not supported during DFS. Reason is @@ -997,7 +995,7 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, n_channels += wiphy->bands[band]->n_channels; } - if (MAX_CHANNEL < n_channels) { + if (n_channels > NUM_CHANNELS) { hdd_err("Exceed max number of channels: %d", n_channels); return -EINVAL; } @@ -1291,10 +1289,13 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, bool pno_offload_enabled; uint8_t scan_backoff_multiplier; bool enable_connected_scan; + enum QDF_GLOBAL_MODE curr_mode; + curr_mode = hdd_get_conparam(); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); + if (QDF_GLOBAL_FTM_MODE == curr_mode || + QDF_GLOBAL_MONITOR_MODE == curr_mode) { + hdd_err_rl("Command not allowed in FTM/Monitor mode"); return -EINVAL; } @@ -1419,10 +1420,13 @@ static int __wlan_hdd_cfg80211_sched_scan_stop(struct net_device *dev) { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); int errno; + enum QDF_GLOBAL_MODE curr_mode; + curr_mode = hdd_get_conparam(); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { - hdd_err_rl("Command not allowed in FTM mode"); + if (QDF_GLOBAL_FTM_MODE == curr_mode || + QDF_GLOBAL_MONITOR_MODE == curr_mode) { + hdd_err_rl("Command not allowed in FTM/Monitor mode"); return -EINVAL; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h index f840744014371898c5451175668c59523bf8e44d..3f7020e3b3907b2a0abd2c23dfbcc37256f522ca 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h @@ -30,6 +30,8 @@ #include "csr_inside_api.h" #include +#define EXTSCAN_PARAM_MAX QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + int hdd_scan_context_init(struct hdd_context *hdd_ctx); void hdd_scan_context_destroy(struct hdd_context *hdd_ctx); @@ -131,5 +133,86 @@ void hdd_reset_scan_reject_params(struct hdd_context *hdd_ctx, * Return: none */ void wlan_hdd_cfg80211_scan_block(struct hdd_adapter *adapter); + +static const +struct nla_policy wlan_hdd_extscan_config_policy[EXTSCAN_PARAM_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = {.type = NLA_U8}, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = {.type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] = { + .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = { + .type = NLA_U8}, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = { + .type = NLA_UNSPEC, + .len = QDF_MAC_ADDR_SIZE}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = { + .type = NLA_S32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = { + .type = NLA_S32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BASE] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = { + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = { + .type = NLA_BINARY, + .len = IEEE80211_MAX_SSID_LEN + 1 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = { + .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] = { + .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] = { + .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] = { + .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] = { + .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] = { + .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = { + .type = NLA_U32}, +}; + #endif /* end #if !defined(WLAN_HDD_SCAN_H) */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c index d7d0fad26757094deadc70ce923420b2533bef21..556eaf02c5255348801fcaf61b86ab28a3edafc1 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -44,6 +44,8 @@ #include "wlan_ipa_ucfg_api.h" #include "wlan_policy_mgr_ucfg.h" #include +#include "wlan_hdd_sta_info.h" +#include "ol_defines.h" #include /* Preprocessor definitions and constants */ @@ -202,41 +204,117 @@ static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, return skb; } +#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ + +#define IEEE8021X_AUTH_TYPE_EAP 0 +#define EAP_CODE_OFFSET 18 +#define EAP_CODE_FAILURE 4 + +/* Wait EAP Failure frame timeout in (MS) */ +#define EAP_FRM_TIME_OUT 80 -#else /** - * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan - * @adapter: pointer to HDD adapter - * @skb: pointer to skb data packet + * hdd_softap_inspect_tx_eap_pkt() - Inspect eap pkt tx/tx-completion + * @adapter: pointer to hdd adapter + * @skb: sk_buff + * @tx_comp: tx sending or tx completion + * + * Inspect the EAP-Failure pkt tx sending and tx completion. * - * Return: pointer to skb structure + * Return: void */ -static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, - struct sk_buff *skb) { +static void hdd_softap_inspect_tx_eap_pkt(struct hdd_adapter *adapter, + struct sk_buff *skb, + bool tx_comp) +{ + struct qdf_mac_addr *mac_addr; + uint8_t *data; + uint8_t auth_type, eap_code; + struct hdd_station_info *sta_info; + struct hdd_hostapd_state *hapd_state; + + if (qdf_likely(QDF_NBUF_CB_GET_PACKET_TYPE(skb) != + QDF_NBUF_CB_PACKET_TYPE_EAPOL) || skb->len < (EAP_CODE_OFFSET + 1)) + return; - struct sk_buff *nskb; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0)) - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); -#endif + if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() || + cds_is_load_or_unload_in_progress()) { + hdd_debug("Recovery/(Un)load in Progress. Ignore!!!"); + return; + } + if (adapter->device_mode != QDF_P2P_GO_MODE) + return; + hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + if (!hapd_state || hapd_state->bss_state != BSS_START) { + hdd_debug("Hostapd State is not START"); + return; + } + data = skb->data; + auth_type = *(uint8_t *)(data + EAPOL_PACKET_TYPE_OFFSET); + if (auth_type != IEEE8021X_AUTH_TYPE_EAP) + return; + eap_code = *(uint8_t *)(data + EAP_CODE_OFFSET); + if (eap_code != EAP_CODE_FAILURE) + return; + mac_addr = (struct qdf_mac_addr *)skb->data; + sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + mac_addr->bytes, + STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT); + if (!sta_info) + return; + if (tx_comp) { + hdd_debug("eap_failure frm tx done "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr->bytes)); + qdf_atomic_clear_bit(PENDING_TYPE_EAP_FAILURE, + &sta_info->pending_eap_frm_type); + qdf_event_set(&hapd_state->qdf_sta_eap_frm_done_event); + } else { + hdd_debug("eap_failure frm tx pending "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr->bytes)); + qdf_event_reset(&hapd_state->qdf_sta_eap_frm_done_event); + qdf_atomic_set_bit(PENDING_TYPE_EAP_FAILURE, + &sta_info->pending_eap_frm_type); + QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 1; + } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT); +} - hdd_skb_fill_gso_size(adapter->dev, skb); +void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter, + struct qdf_mac_addr *mac_addr) +{ + struct hdd_station_info *sta_info; + QDF_STATUS qdf_status; + struct hdd_hostapd_state *hapd_state; - nskb = skb_unshare(skb, GFP_ATOMIC); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0)) - if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) { - /* - * For UDP packets we want to orphan the packet to allow the app - * to send more packets. The flow would ultimately be controlled - * by the limited number of tx descriptors for the vdev. - */ - ++adapter->hdd_stats.tx_rx_stats.tx_orphaned; - skb_orphan(skb); + if (adapter->device_mode != QDF_P2P_GO_MODE) + return; + hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + if (!hapd_state || hapd_state->bss_state != BSS_START) { + hdd_err("Hostapd State is not START"); + return; } -#endif - return nskb; + sta_info = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, + mac_addr->bytes, + STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT); + if (!sta_info) + return; + if (qdf_atomic_test_bit(PENDING_TYPE_EAP_FAILURE, + &sta_info->pending_eap_frm_type)) { + hdd_debug("eap_failure frm pending "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr->bytes)); + qdf_status = qdf_wait_for_event_completion( + &hapd_state->qdf_sta_eap_frm_done_event, + EAP_FRM_TIME_OUT); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + hdd_debug("eap_failure tx timeout"); + } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT); } -#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ +#ifdef SAP_DHCP_FW_IND /** * hdd_post_dhcp_ind() - Send DHCP START/STOP indication to FW * @adapter: pointer to hdd adapter @@ -245,13 +323,14 @@ static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, * * Return: error number */ -int hdd_post_dhcp_ind(struct hdd_adapter *adapter, - uint8_t sta_id, uint16_t type) +int hdd_post_dhcp_ind(struct hdd_adapter *adapter, uint8_t *mac_addr, + uint16_t type) { tAniDHCPInd pmsg; QDF_STATUS status = QDF_STATUS_SUCCESS; - hdd_debug("Post DHCP indication,sta_id=%d, type=%d", sta_id, type); + hdd_debug("Post DHCP indication,sta_mac=" QDF_MAC_ADDR_FMT + " , type=%d", QDF_MAC_ADDR_REF(mac_addr), type); if (!adapter) { hdd_err("NULL adapter"); @@ -265,7 +344,7 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter, adapter->mac_addr.bytes, QDF_MAC_ADDR_SIZE); qdf_mem_copy(pmsg.peerMacAddr.bytes, - adapter->sta_info[sta_id].sta_mac.bytes, + mac_addr, QDF_MAC_ADDR_SIZE); status = wma_process_dhcp_ind(cds_get_context(QDF_MODULE_ID_WMA), @@ -291,8 +370,7 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter, static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf) { struct hdd_ap_ctx *hdd_ap_ctx; - struct qdf_mac_addr *dest_mac_addr; - uint8_t sta_id; + uint8_t *dest_mac_addr; struct hdd_adapter *adapter = context; if (hdd_validate_adapter(adapter)) @@ -304,59 +382,19 @@ static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf) return; } - dest_mac_addr = (struct qdf_mac_addr *)(netbuf->data + - DHCP_CLIENT_MAC_ADDR_OFFSET); + dest_mac_addr = netbuf->data + DHCP_CLIENT_MAC_ADDR_OFFSET; - if (QDF_STATUS_SUCCESS != - hdd_softap_get_sta_id(adapter, - dest_mac_addr, &sta_id)) { - QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, - QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Failed to find right station", __func__); - return; - } - - hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND); + hdd_post_dhcp_ind(adapter, dest_mac_addr, WMA_DHCP_STOP_IND); } -/** - * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet - * @adapter: pointer to hdd adapter - * @skb: pointer to OS packet (sk_buff) - * @dir: direction - * - * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW - * through WMI message, during DHCP based IP address acquisition phase. - * - * - Send DHCP_START notification to FW when SAP gets DHCP Discovery - * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK - * - * DHCP subtypes are determined by a status octet in the DHCP Message type - * option (option code 53 (0x35)). - * - * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK, - * and transitioned per DHCP message type as it arrives. - * - * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase - * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase - * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase - * or ACK phase (Renewal process) - * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase - * or DHCP_DELINE message in OFFER phase - * - * Return: error number - */ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, struct sk_buff *skb, enum qdf_proto_dir dir) { enum qdf_proto_subtype subtype = QDF_PROTO_INVALID; struct hdd_station_info *hdd_sta_info; - uint8_t sta_id; int errno = 0; struct qdf_mac_addr *src_mac; - QDF_STATUS status; - if (((adapter->device_mode == QDF_SAP_MODE) || (adapter->device_mode == QDF_P2P_GO_MODE)) && @@ -366,14 +404,16 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, src_mac = (struct qdf_mac_addr *)(skb->data + DHCP_CLIENT_MAC_ADDR_OFFSET); - status = hdd_softap_get_sta_id(adapter, src_mac, &sta_id); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("invalid station id"); - return -EINVAL; - } subtype = qdf_nbuf_get_dhcp_subtype(skb); - hdd_sta_info = &adapter->sta_info[sta_id]; + hdd_sta_info = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, + src_mac->bytes, + STA_INFO_SOFTAP_INSPECT_DHCP_PACKET); + if (!hdd_sta_info) { + hdd_debug("Station not found"); + return -EINVAL; + } hdd_debug("ENTER: type=%d, phase=%d, nego_status=%d", subtype, @@ -385,8 +425,10 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, if (dir != QDF_RX) break; if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP) - errno = hdd_post_dhcp_ind(adapter, sta_id, - WMA_DHCP_START_IND); + errno = hdd_post_dhcp_ind( + adapter, + hdd_sta_info->sta_mac.bytes, + WMA_DHCP_START_IND); hdd_sta_info->dhcp_phase = DHCP_PHASE_DISCOVER; hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS; break; @@ -397,8 +439,10 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, if (dir != QDF_RX) break; if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP) - errno = hdd_post_dhcp_ind(adapter, sta_id, - WMA_DHCP_START_IND); + errno = hdd_post_dhcp_ind( + adapter, + hdd_sta_info->sta_mac.bytes, + WMA_DHCP_START_IND); hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS; case QDF_PROTO_DHCP_DECLINE: if (dir == QDF_RX) @@ -422,10 +466,17 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter, hdd_debug("EXIT: phase=%d, nego_status=%d", hdd_sta_info->dhcp_phase, hdd_sta_info->dhcp_nego_status); + hdd_put_sta_info_ref(&adapter->sta_info_list, &hdd_sta_info, + true, STA_INFO_SOFTAP_INSPECT_DHCP_PACKET); } return errno; } +#else +static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf) +{ +} +#endif /** * __hdd_softap_hard_start_xmit() - Transmit a frame @@ -447,9 +498,11 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev); struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); struct hdd_context *hdd_ctx = adapter->hdd_ctx; - struct qdf_mac_addr *dest_mac_addr; - uint8_t sta_id; + struct qdf_mac_addr *dest_mac_addr, *mac_addr; + static struct qdf_mac_addr bcast_mac_addr = QDF_MAC_ADDR_BCAST_INIT; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint32_t num_seg; + struct hdd_station_info *sta_info = NULL; ++adapter->hdd_stats.tx_rx_stats.tx_called; adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; @@ -466,6 +519,11 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, goto drop_pkt; } + if (hdd_ctx->hdd_wlan_suspended) { + hdd_err_rl("Device is system suspended, drop pkt"); + goto drop_pkt; + } + /* * If the device is operating on a DFS Channel * then check if SAP is in CAC WAIT state and @@ -499,53 +557,42 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, dest_mac_addr = (struct qdf_mac_addr *)skb->data; - if (QDF_NBUF_CB_GET_IS_BCAST(skb) || - QDF_NBUF_CB_GET_IS_MCAST(skb)) { - /* The BC/MC station ID is assigned during BSS - * starting phase. SAP will return the station ID - * used for BC/MC traffic. - */ - sta_id = ap_ctx->broadcast_sta_id; - } else { - if (QDF_STATUS_SUCCESS != - hdd_softap_get_sta_id(adapter, - dest_mac_addr, &sta_id)) { + /* In case of mcast, fetch the bcast sta_info. Else use the pkt addr */ + if (QDF_NBUF_CB_GET_IS_MCAST(skb)) + mac_addr = &bcast_mac_addr; + else + mac_addr = dest_mac_addr; + + sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + mac_addr->bytes, + STA_INFO_SOFTAP_HARD_START_XMIT); + + if (!QDF_NBUF_CB_GET_IS_BCAST(skb) && !QDF_NBUF_CB_GET_IS_MCAST(skb)) { + if (!sta_info) { QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH, "%s: Failed to find right station", __func__); goto drop_pkt; } - if (sta_id >= WLAN_MAX_STA_COUNT) { - QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, - QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Failed to find right station", __func__); - goto drop_pkt; - } else if (!adapter->sta_info[sta_id].in_use) { + if (sta_info->is_deauth_in_progress) { QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: STA %d is unregistered", __func__, - sta_id); - goto drop_pkt; - } else if (adapter->sta_info[sta_id]. - is_deauth_in_progress) { - QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, - QDF_TRACE_LEVEL_INFO_HIGH, - "%s: STA %d deauth in progress", __func__, - sta_id); + "%s: STA " QDF_MAC_ADDR_FMT + "deauth in progress", __func__, + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); goto drop_pkt; } - if ((OL_TXRX_PEER_STATE_CONN != - adapter->sta_info[sta_id].peer_state) - && (OL_TXRX_PEER_STATE_AUTH != - adapter->sta_info[sta_id].peer_state)) { + if (sta_info->peer_state != OL_TXRX_PEER_STATE_CONN && + sta_info->peer_state != OL_TXRX_PEER_STATE_AUTH) { QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH, "%s: Station not connected yet", __func__); goto drop_pkt; - } else if (OL_TXRX_PEER_STATE_CONN == - adapter->sta_info[sta_id].peer_state) { + } + + if (sta_info->peer_state == OL_TXRX_PEER_STATE_CONN) { if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) { QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH, @@ -556,8 +603,14 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, } } - hdd_get_tx_resource(adapter, sta_id, - WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + if (QDF_NBUF_CB_GET_IS_BCAST(skb) || QDF_NBUF_CB_GET_IS_MCAST(skb)) + hdd_get_tx_resource( + adapter, &adapter->mac_addr, + WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + else + hdd_get_tx_resource( + adapter, dest_mac_addr, + WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); /* Get TL AC corresponding to Qdisc queue index/AC. */ ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping]; @@ -588,22 +641,26 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__); adapter->stats.tx_bytes += skb->len; - adapter->sta_info[sta_id].tx_bytes += skb->len; - if (qdf_nbuf_is_tso(skb)) { - num_seg = qdf_nbuf_get_tso_num_seg(skb); - adapter->stats.tx_packets += num_seg; - adapter->sta_info[sta_id].tx_packets += num_seg; - } else { - ++adapter->stats.tx_packets; - adapter->sta_info[sta_id].tx_packets++; - hdd_ctx->no_tx_offload_pkt_cnt++; + if (sta_info) { + sta_info->tx_bytes += skb->len; + + if (qdf_nbuf_is_tso(skb)) { + num_seg = qdf_nbuf_get_tso_num_seg(skb); + adapter->stats.tx_packets += num_seg; + sta_info->tx_packets += num_seg; + } else { + ++adapter->stats.tx_packets; + sta_info->tx_packets++; + hdd_ctx->no_tx_offload_pkt_cnt++; + } + sta_info->last_tx_rx_ts = qdf_system_ticks(); } - adapter->sta_info[sta_id].last_tx_rx_ts = qdf_system_ticks(); QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0; hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_TX); + hdd_softap_inspect_tx_eap_pkt(adapter, skb, false); hdd_event_eapol_log(skb, QDF_TX); QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK; @@ -624,30 +681,34 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb, goto drop_pkt_and_release_skb; } - if (adapter->tx_fn(adapter->txrx_vdev, - (qdf_nbuf_t)skb) != NULL) { + if (adapter->tx_fn(soc, adapter->vdev_id, (qdf_nbuf_t)skb)) { QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Failed to send packet to txrx for sta_id:%d", - __func__, sta_id); + "%s: Failed to send packet to txrx for sta: " + QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(dest_mac_addr->bytes)); ++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac]; goto drop_pkt_and_release_skb; } netif_trans_update(dev); wlan_hdd_sar_unsolicited_timer_start(hdd_ctx); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_HARD_START_XMIT); return; drop_pkt_and_release_skb: qdf_net_buf_debug_release_skb(skb); drop_pkt: - qdf_dp_trace_data_pkt(skb, QDF_TRACE_DEFAULT_PDEV_ID, QDF_DP_TRACE_DROP_PACKET_RECORD, 0, QDF_TX); kfree_skb(skb); drop_pkt_accounting: + if (sta_info) + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_HARD_START_XMIT); ++adapter->stats.tx_dropped; ++adapter->hdd_stats.tx_rx_stats.tx_dropped; } @@ -733,12 +794,12 @@ static void __hdd_softap_tx_timeout(struct net_device *dev) QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, "Detected data stall due to continuous TX timeouts"); adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; + if (cdp_cfg_get(soc, cfg_dp_enable_data_stall)) cdp_post_data_stall_event(soc, - cds_get_context(QDF_MODULE_ID_TXRX), DATA_STALL_LOG_INDICATOR_HOST_DRIVER, DATA_STALL_LOG_HOST_SOFTAP_TX_TIMEOUT, - 0xFF, 0xFF, + OL_TXRX_PDEV_ID, 0xFF, DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); } } @@ -755,22 +816,9 @@ void hdd_softap_tx_timeout(struct net_device *net_dev) osif_vdev_sync_op_stop(vdev_sync); } -QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter) +void hdd_softap_init_tx_rx(struct hdd_adapter *adapter) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - - uint8_t STAId = 0; - qdf_mem_zero(&adapter->stats, sizeof(struct net_device_stats)); - - spin_lock_init(&adapter->sta_info_lock); - - for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) { - qdf_mem_zero(&adapter->sta_info[STAId], - sizeof(struct hdd_station_info)); - } - - return status; } QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter) @@ -779,57 +827,174 @@ QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter) if (!adapter) return QDF_STATUS_E_FAILURE; - adapter->txrx_vdev = NULL; adapter->tx_fn = NULL; return QDF_STATUS_SUCCESS; } -QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter, - uint8_t sta_id, - struct qdf_mac_addr *sta_mac) +static void +hdd_reset_sta_info_during_reattach(struct hdd_station_info *sta_info) { - spin_lock_bh(&adapter->sta_info_lock); - if (adapter->sta_info[sta_id].in_use) { - spin_unlock_bh(&adapter->sta_info_lock); - hdd_err("Reinit of in use station %d", sta_id); - return QDF_STATUS_E_FAILURE; + sta_info->in_use = 0; + sta_info->sta_id = 0; + sta_info->sta_type = 0; + qdf_mem_zero(&sta_info->sta_mac, QDF_MAC_ADDR_SIZE); + sta_info->peer_state = 0; + sta_info->is_qos_enabled = 0; + sta_info->is_deauth_in_progress = 0; + sta_info->nss = 0; + sta_info->rate_flags = 0; + sta_info->ecsa_capable = 0; + sta_info->max_phy_rate = 0; + sta_info->tx_packets = 0; + sta_info->tx_bytes = 0; + sta_info->rx_packets = 0; + sta_info->rx_bytes = 0; + sta_info->last_tx_rx_ts = 0; + sta_info->assoc_ts = 0; + sta_info->disassoc_ts = 0; + sta_info->tx_rate = 0; + sta_info->rx_rate = 0; + sta_info->ampdu = 0; + sta_info->sgi_enable = 0; + sta_info->tx_stbc = 0; + sta_info->rx_stbc = 0; + sta_info->ch_width = 0; + sta_info->mode = 0; + sta_info->max_supp_idx = 0; + sta_info->max_ext_idx = 0; + sta_info->max_mcs_idx = 0; + sta_info->rx_mcs_map = 0; + sta_info->tx_mcs_map = 0; + sta_info->freq = 0; + sta_info->dot11_mode = 0; + sta_info->ht_present = 0; + sta_info->vht_present = 0; + qdf_mem_zero(&sta_info->ht_caps, sizeof(sta_info->ht_caps)); + qdf_mem_zero(&sta_info->vht_caps, sizeof(sta_info->vht_caps)); + sta_info->reason_code = 0; + sta_info->rssi = 0; + sta_info->dhcp_phase = 0; + sta_info->dhcp_nego_status = 0; + sta_info->capability = 0; + sta_info->support_mode = 0; + sta_info->rx_retry_cnt = 0; + sta_info->rx_mc_bc_cnt = 0; + + if (sta_info->assoc_req_ies.len) { + qdf_mem_free(sta_info->assoc_req_ies.data); + sta_info->assoc_req_ies.data = NULL; + sta_info->assoc_req_ies.len = 0; + } + + sta_info->pending_eap_frm_type = 0; +} + +/** + * hdd_sta_info_re_attach() - Re-Attach the station info structure into the list + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that is to be attached to the + * container object. + * + * This function re-attaches the station if it gets re-connect after + * disconnecting and before its all references are released. + * + * Return: QDF STATUS SUCCESS on successful attach, error code otherwise + */ + +static QDF_STATUS hdd_sta_info_re_attach( + struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *sta_info, + struct qdf_mac_addr *sta_mac) +{ + if (!sta_info_container || !sta_info) { + hdd_err("Parameter(s) null"); + return QDF_STATUS_E_INVAL; } - qdf_mem_zero(&adapter->sta_info[sta_id], - sizeof(struct hdd_station_info)); + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + if (sta_info->is_attached) { + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + hdd_err("sta info is alredy attached"); + return QDF_STATUS_SUCCESS; + } - adapter->sta_info[sta_id].in_use = true; - adapter->sta_info[sta_id].is_deauth_in_progress = false; - qdf_copy_macaddr(&adapter->sta_info[sta_id].sta_mac, sta_mac); + hdd_reset_sta_info_during_reattach(sta_info); + /* Add one extra ref for reattach */ + hdd_take_sta_info_ref(sta_info_container, sta_info, false, + STA_INFO_ATTACH_DETACH); + qdf_mem_copy(&sta_info->sta_mac, sta_mac, sizeof(struct qdf_mac_addr)); + sta_info->is_attached = true; + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); - spin_unlock_bh(&adapter->sta_info_lock); return QDF_STATUS_SUCCESS; } -QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter, - uint8_t sta_id) +QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter, + struct qdf_mac_addr *sta_mac) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct hdd_hostapd_state *hostapd_state; + struct hdd_station_info *sta_info; + QDF_STATUS status; - hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + sta_mac->bytes, + STA_INFO_SOFTAP_INIT_TX_RX_STA); + + if (sta_info) { + hdd_err("Reinit of in use station " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_mac->bytes)); + status = hdd_sta_info_re_attach(&adapter->sta_info_list, + sta_info, sta_mac); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_INIT_TX_RX_STA); + return status; + } - spin_lock_bh(&adapter->sta_info_lock); + sta_info = qdf_mem_malloc(sizeof(struct hdd_station_info)); + if (!sta_info) + return QDF_STATUS_E_NOMEM; - if (false == adapter->sta_info[sta_id].in_use) { - spin_unlock_bh(&adapter->sta_info_lock); - hdd_err("Deinit station not inited %d", sta_id); - return QDF_STATUS_E_FAILURE; - } + sta_info->is_deauth_in_progress = false; + qdf_mem_copy(&sta_info->sta_mac, sta_mac, sizeof(struct qdf_mac_addr)); - adapter->sta_info[sta_id].in_use = false; - adapter->sta_info[sta_id].is_deauth_in_progress = false; + status = hdd_sta_info_attach(&adapter->sta_info_list, sta_info); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to attach station: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_mac->bytes)); + qdf_mem_free(sta_info); + } - spin_unlock_bh(&adapter->sta_info_lock); return status; } +/** + * hdd_softap_tsf_timestamp_rx() - time stamp Rx netbuf + * @context: pointer to HDD context + * @netbuf: pointer to a Rx netbuf + * + * Return: None + */ +#ifdef WLAN_FEATURE_TSF_PLUS +static inline void hdd_softap_tsf_timestamp_rx(struct hdd_context *hdd_ctx, + qdf_nbuf_t netbuf) +{ + uint64_t target_time; + + if (!hdd_tsf_is_rx_set(hdd_ctx)) + return; + + target_time = ktime_to_us(netbuf->tstamp); + hdd_rx_timestamp(netbuf, target_time); +} +#else +static inline void hdd_softap_tsf_timestamp_rx(struct hdd_context *hdd_ctx, + qdf_nbuf_t netbuf) +{ +} +#endif + /** * hdd_softap_notify_tx_compl_cbk() - callback to notify tx completion * @skb: pointer to skb data @@ -850,6 +1015,9 @@ static void hdd_softap_notify_tx_compl_cbk(struct sk_buff *skb, if (QDF_NBUF_CB_PACKET_TYPE_DHCP == QDF_NBUF_CB_GET_PACKET_TYPE(skb)) { hdd_debug("sending DHCP indication"); hdd_softap_notify_dhcp_ind(context, skb); + } else if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == + QDF_NBUF_CB_PACKET_TYPE_EAPOL) { + hdd_softap_inspect_tx_eap_pkt(adapter, skb, true); } } @@ -862,7 +1030,7 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf) struct sk_buff *next = NULL; struct hdd_context *hdd_ctx = NULL; struct qdf_mac_addr *src_mac; - uint8_t sta_id; + struct hdd_station_info *sta_info; /* Sanity check on inputs */ if (unlikely((!adapter_context) || (!rx_buf))) { @@ -895,7 +1063,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf) skb->next = NULL; /* Debug code, remove later */ -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG, "%s: skb %pK skb->len %d\n", __func__, skb, skb->len); #endif @@ -919,16 +1088,19 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf) /* Send DHCP Indication to FW */ src_mac = (struct qdf_mac_addr *)(skb->data + QDF_NBUF_SRC_MAC_OFFSET); - if (QDF_STATUS_SUCCESS == - hdd_softap_get_sta_id(adapter, src_mac, &sta_id)) { - if (sta_id < WLAN_MAX_STA_COUNT) { - adapter->sta_info[sta_id].rx_packets++; - adapter->sta_info[sta_id].rx_bytes += skb->len; - adapter->sta_info[sta_id].last_tx_rx_ts = - qdf_system_ticks(); - hdd_softap_inspect_dhcp_packet(adapter, skb, - QDF_RX); - } + sta_info = hdd_get_sta_info_by_mac( + &adapter->sta_info_list, + (uint8_t *)src_mac, + STA_INFO_SOFTAP_RX_PACKET_CBK); + + if (sta_info) { + sta_info->rx_packets++; + sta_info->rx_bytes += skb->len; + sta_info->last_tx_rx_ts = qdf_system_ticks(); + hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_RX); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, + true, + STA_INFO_SOFTAP_RX_PACKET_CBK); } if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(skb) && @@ -958,26 +1130,25 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf) */ qdf_net_buf_debug_release_skb(skb); + hdd_softap_tsf_timestamp_rx(hdd_ctx, skb); + qdf_status = hdd_rx_deliver_to_stack(adapter, skb); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) { + if (QDF_IS_STATUS_SUCCESS(qdf_status)) ++adapter->hdd_stats.tx_rx_stats.rx_delivered[cpu_index]; - } else { + else ++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index]; - DPTRACE(qdf_dp_log_proto_pkt_info(NULL, NULL, 0, 0, - QDF_RX, - QDF_TRACE_DEFAULT_MSDU_ID, - QDF_TX_RX_STATUS_DROP)); - } } return QDF_STATUS_SUCCESS; } QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, - uint8_t sta_id) + struct hdd_station_info **sta_info) { struct hdd_context *hdd_ctx; + struct qdf_mac_addr *mac_addr; + struct hdd_station_info *sta = *sta_info; if (!adapter) { hdd_err("NULL adapter"); @@ -989,33 +1160,37 @@ QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, return QDF_STATUS_E_INVAL; } + if (!sta) { + hdd_err("Invalid station"); + return QDF_STATUS_E_INVAL; + } + hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (sta_id >= WLAN_MAX_STA_COUNT) { - hdd_err("Error: Invalid sta_id: %u", sta_id); + if (!hdd_ctx) { + hdd_err("HDD context is null"); return QDF_STATUS_E_INVAL; } - if (adapter->sta_info[sta_id].in_use) { - if (ucfg_ipa_is_enabled()) { - if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, - adapter->device_mode, - adapter->sta_info[sta_id].sta_id, - adapter->vdev_id, - WLAN_IPA_CLIENT_DISCONNECT, - adapter->sta_info[sta_id].sta_mac. - bytes) != QDF_STATUS_SUCCESS) - hdd_debug("WLAN_CLIENT_DISCONNECT event failed"); - } - spin_lock_bh(&adapter->sta_info_lock); - qdf_mem_zero(&adapter->sta_info[sta_id], - sizeof(struct hdd_station_info)); - spin_unlock_bh(&adapter->sta_info_lock); - } + /* + * If the address is a broadcast address then the CDP layers expects + * the self mac address of the adapter. + */ + if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes)) + mac_addr = &adapter->mac_addr; + else + mac_addr = &sta->sta_mac; - hdd_softap_deinit_tx_rx_sta(adapter, sta_id); + if (ucfg_ipa_is_enabled()) { + if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, + adapter->device_mode, + adapter->vdev_id, + WLAN_IPA_CLIENT_DISCONNECT, + mac_addr->bytes) != QDF_STATUS_SUCCESS) + hdd_debug("WLAN_CLIENT_DISCONNECT event failed"); + } + hdd_sta_info_detach(&adapter->sta_info_list, &sta); - hdd_ctx->sta_to_adapter[sta_id] = NULL; ucfg_mlme_update_oce_flags(hdd_ctx->pdev); return QDF_STATUS_SUCCESS; @@ -1024,41 +1199,39 @@ QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter, QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, bool auth_required, bool privacy_required, - uint8_t sta_id, struct qdf_mac_addr *sta_mac, bool wmm_enabled) { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - struct ol_txrx_desc_type txrx_desc = { 0 }; + struct ol_txrx_desc_type txrx_desc = {0}; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct ol_txrx_ops txrx_ops; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_vdev *txrx_vdev = NULL; - - hdd_info("STA:%u, Auth:%u, Priv:%u, WMM:%u", - sta_id, auth_required, privacy_required, wmm_enabled); + struct hdd_ap_ctx *ap_ctx; + struct hdd_station_info *sta_info; - if (sta_id >= WLAN_MAX_STA_COUNT) { - hdd_err("Error: Invalid sta_id: %u", sta_id); - return qdf_status; - } + ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); /* - * Clean up old entry if it is not cleaned up properly + * If the address is a broadcast address, then provide the self mac addr + * to the data path. Else provide the mac address of the connected peer. */ - if (adapter->sta_info[sta_id].in_use) { - hdd_debug("clean up old entry for STA %d", sta_id); - hdd_softap_deregister_sta(adapter, sta_id); - } - - /* Get the Station ID from the one saved during the association. */ - txrx_desc.sta_id = sta_id; + if (qdf_is_macaddr_broadcast(sta_mac) && ap_ctx) + qdf_mem_copy(&txrx_desc.peer_addr, &adapter->mac_addr, + QDF_MAC_ADDR_SIZE); + else + qdf_mem_copy(&txrx_desc.peer_addr, sta_mac, + QDF_MAC_ADDR_SIZE); - /* Save the adapter Pointer for this sta_id */ - hdd_ctx->sta_to_adapter[sta_id] = adapter; + qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_mac); + sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + sta_mac->bytes, + STA_INFO_SOFTAP_REGISTER_STA); - qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_id, sta_mac); + if (!sta_info) { + hdd_debug("STA not found"); + return QDF_STATUS_E_INVAL; + } txrx_desc.is_qos_enabled = wmm_enabled; @@ -1078,27 +1251,18 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, txrx_ops.rx.rx_flush = NULL; } - txrx_vdev = cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); - if (!txrx_vdev) - return QDF_STATUS_E_FAILURE; - cdp_vdev_register(soc, - txrx_vdev, - adapter, - (struct cdp_ctrl_objmgr_vdev *)adapter->vdev, + adapter->vdev_id, + (ol_osif_vdev_handle)adapter, &txrx_ops); - adapter->txrx_vdev = (void *)cdp_get_vdev_from_vdev_id(soc, - (struct cdp_pdev *)pdev, - adapter->vdev_id); adapter->tx_fn = txrx_ops.tx.tx; - qdf_status = cdp_peer_register(soc, - (struct cdp_pdev *)pdev, &txrx_desc); + qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_debug("cdp_peer_register() failed to register. Status = %d [0x%08X]", qdf_status, qdf_status); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_REGISTER_STA); return qdf_status; } @@ -1108,34 +1272,42 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, * put TL directly into 'authenticated' state */ - adapter->sta_info[sta_id].sta_id = sta_id; - adapter->sta_info[sta_id].is_qos_enabled = wmm_enabled; + sta_info->is_qos_enabled = wmm_enabled; if (!auth_required) { - hdd_debug("open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", - adapter->sta_info[sta_id].sta_id); + hdd_debug("open/shared auth STA MAC= " QDF_MAC_ADDR_FMT + ". Changing TL state to AUTHENTICATED at Join time", + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); /* Connections that do not need Upper layer auth, * transition TL directly to 'Authenticated' state. */ - qdf_status = hdd_change_peer_state(adapter, txrx_desc.sta_id, - OL_TXRX_PEER_STATE_AUTH, false); + qdf_status = hdd_change_peer_state(adapter, + txrx_desc.peer_addr.bytes, + OL_TXRX_PEER_STATE_AUTH, + false); - adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_AUTH; + sta_info->peer_state = OL_TXRX_PEER_STATE_AUTH; if (!qdf_is_macaddr_broadcast(sta_mac)) qdf_status = wlan_hdd_send_sta_authorized_event( adapter, hdd_ctx, sta_mac); } else { - hdd_debug("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", - adapter->sta_info[sta_id].sta_id); + hdd_debug("ULA auth STA MAC = " QDF_MAC_ADDR_FMT + ". Changing TL state to CONNECTED at Join time", + QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); + + qdf_status = hdd_change_peer_state(adapter, + txrx_desc.peer_addr.bytes, + OL_TXRX_PEER_STATE_CONN, + false); - qdf_status = hdd_change_peer_state(adapter, txrx_desc.sta_id, - OL_TXRX_PEER_STATE_CONN, false); - adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_CONN; + sta_info->peer_state = OL_TXRX_PEER_STATE_CONN; } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_REGISTER_STA); hdd_debug("Enabling queues"); wlan_hdd_netif_queue_control(adapter, WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, @@ -1155,11 +1327,9 @@ QDF_STATUS hdd_softap_register_bc_sta(struct hdd_adapter *adapter, bool privacy_required) { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct qdf_mac_addr broadcast_macaddr = QDF_MAC_ADDR_BCAST_INIT; struct hdd_ap_ctx *ap_ctx; uint8_t sta_id; - ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); sta_id = ap_ctx->broadcast_sta_id; @@ -1168,34 +1338,20 @@ QDF_STATUS hdd_softap_register_bc_sta(struct hdd_adapter *adapter, return qdf_status; } - hdd_ctx->sta_to_adapter[sta_id] = adapter; qdf_status = hdd_softap_register_sta(adapter, false, - privacy_required, sta_id, + privacy_required, &broadcast_macaddr, 0); return qdf_status; } -/** - * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA - * @adapter: pointer to adapter context - * - * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error - */ -static QDF_STATUS hdd_softap_deregister_bc_sta(struct hdd_adapter *adapter) -{ - struct hdd_ap_ctx *ap_ctx; - - ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - return hdd_softap_deregister_sta(adapter, ap_ctx->broadcast_sta_id); -} - QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - uint8_t sta_id = 0, indoor_chnl_marking = 0; + uint8_t indoor_chnl_marking = 0; struct hdd_context *hdd_ctx; struct hdd_ap_ctx *ap_ctx; + struct hdd_station_info *sta_info, *tmp = NULL; hdd_ctx = WLAN_HDD_GET_CTX(adapter); ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); @@ -1208,25 +1364,17 @@ QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter) * driver unload in progress check otherwise it can lead to peer * object leak */ - status = hdd_softap_deregister_bc_sta(adapter); - - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_debug("Failed to deregister BC sta Id %d", - ap_ctx->broadcast_sta_id); - - for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { - /* This excludes BC sta as it is already deregistered */ - if (adapter->sta_info[sta_id].in_use) { - status = hdd_softap_deregister_sta(adapter, sta_id); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("Failed to deregister sta Id %d", - sta_id); - } - } + + hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, + STA_INFO_SOFTAP_STOP_BSS) { + status = hdd_softap_deregister_sta(adapter, &sta_info); + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_STOP_BSS); } + if (adapter->device_mode == QDF_SAP_MODE && !hdd_ctx->config->disable_channel) - wlan_hdd_restore_channels(hdd_ctx, true); + wlan_hdd_restore_channels(hdd_ctx); /* Mark the indoor channel (passive) to enable */ if (indoor_chnl_marking && adapter->device_mode == QDF_SAP_MODE) { @@ -1238,7 +1386,6 @@ QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter) if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev, adapter->device_mode, - ap_ctx->broadcast_sta_id, adapter->vdev_id, WLAN_IPA_AP_DISCONNECT, adapter->dev->dev_addr) != @@ -1253,52 +1400,41 @@ QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter, struct qdf_mac_addr *sta_mac, enum ol_txrx_peer_state state) { - uint8_t sta_id = WLAN_MAX_STA_COUNT; QDF_STATUS qdf_status; + struct hdd_station_info *sta_info; + struct qdf_mac_addr mac_addr; hdd_enter_dev(adapter->dev); - qdf_status = hdd_softap_get_sta_id(adapter, sta_mac, &sta_id); - if (QDF_STATUS_SUCCESS != qdf_status) { - hdd_debug("Failed to find right station"); - return qdf_status; - } + sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, + sta_mac->bytes, + STA_INFO_SOFTAP_CHANGE_STA_STATE); - if (false == - qdf_is_macaddr_equal(&adapter->sta_info[sta_id].sta_mac, - sta_mac)) { - hdd_err("Station %u MAC address not matching", sta_id); - return QDF_STATUS_E_FAILURE; + if (!sta_info) { + hdd_debug("Failed to find right station MAC: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_mac->bytes)); + return QDF_STATUS_E_INVAL; } + if (qdf_is_macaddr_broadcast(&sta_info->sta_mac)) + qdf_mem_copy(&mac_addr, &adapter->mac_addr, QDF_MAC_ADDR_SIZE); + else + qdf_mem_copy(&mac_addr, sta_mac, QDF_MAC_ADDR_SIZE); + qdf_status = - hdd_change_peer_state(adapter, sta_id, state, false); - hdd_debug("Station %u changed to state %d", sta_id, state); + hdd_change_peer_state(adapter, mac_addr.bytes, + state, false); + hdd_debug("Station " QDF_MAC_ADDR_FMT " changed to state %d", + QDF_MAC_ADDR_REF(mac_addr.bytes), state); if (QDF_STATUS_SUCCESS == qdf_status) { - adapter->sta_info[sta_id].peer_state = - OL_TXRX_PEER_STATE_AUTH; + sta_info->peer_state = OL_TXRX_PEER_STATE_AUTH; p2p_peer_authorized(adapter->vdev, sta_mac->bytes); } + hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true, + STA_INFO_SOFTAP_CHANGE_STA_STATE); hdd_exit(); return qdf_status; } -QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter, - struct qdf_mac_addr *sta_mac, - uint8_t *sta_id) -{ - uint8_t i; - - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - if (!qdf_mem_cmp - (&adapter->sta_info[i].sta_mac, sta_mac, - QDF_MAC_ADDR_SIZE) && adapter->sta_info[i].in_use) { - *sta_id = i; - return QDF_STATUS_SUCCESS; - } - } - - return QDF_STATUS_E_FAILURE; -} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.c new file mode 100644 index 0000000000000000000000000000000000000000..6b1f81a15eab2c648668f7976e79893c9981a23f --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_sta_info.c + * + * Store and manage station info structure. + * + */ + +#include +#include "wlan_hdd_sta_info.h" + +#define HDD_MAX_PEERS 32 + +char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id) +{ + static const char *strings[] = { + "STA_INFO_ID_RESERVED", + "STA_INFO_CFG80211_GET_LINK_PROPERTIES", + "STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT", + "STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT", + "STA_INFO_SOFTAP_INSPECT_DHCP_PACKET", + "STA_INFO_SOFTAP_HARD_START_XMIT", + "STA_INFO_SOFTAP_INIT_TX_RX_STA", + "STA_INFO_SOFTAP_RX_PACKET_CBK", + "STA_INFO_SOFTAP_REGISTER_STA", + "STA_INFO_GET_CACHED_STATION_REMOTE", + "STA_INFO_HDD_GET_STATION_REMOTE", + "STA_INFO_WLAN_HDD_GET_STATION_REMOTE", + "STA_INFO_SOFTAP_DEAUTH_CURRENT_STA", + "STA_INFO_SOFTAP_DEAUTH_ALL_STA", + "STA_INFO_CFG80211_DEL_STATION", + "STA_INFO_HDD_CLEAR_ALL_STA", + "STA_INFO_FILL_STATION_INFO", + "STA_INFO_HOSTAPD_SAP_EVENT_CB", + "STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA", + "STA_INFO_IS_PEER_ASSOCIATED", + "STA_INFO_SAP_SET_TWO_INTS_GETNONE", + "STA_INFO_SAP_GETASSOC_STAMACADDR", + "STA_INFO_SOFTAP_GET_STA_INFO", + "STA_INFO_GET_SOFTAP_LINKSPEED", + "STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR", + "STA_INFO_SOFTAP_STOP_BSS", + "STA_INFO_SOFTAP_CHANGE_STA_STATE", + "STA_INFO_CLEAR_CACHED_STA_INFO", + "STA_INFO_ATTACH_DETACH", + "STA_INFO_SHOW", + "STA_INFO_ID_MAX"}; + int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); + + if (id >= num_dbg_strings) { + char *ret = ""; + + hdd_err("Debug string not found for debug id %d", id); + return ret; + } + + return (char *)strings[id]; +} + +QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container) +{ + if (!sta_info_container) { + hdd_err("Parameter null"); + return QDF_STATUS_E_INVAL; + } + + qdf_spinlock_create(&sta_info_container->sta_obj_lock); + qdf_list_create(&sta_info_container->sta_obj, HDD_MAX_PEERS); + + return QDF_STATUS_SUCCESS; +} + +void hdd_sta_info_deinit(struct hdd_sta_info_obj *sta_info_container) +{ + if (!sta_info_container) { + hdd_err("Parameter null"); + return; + } + + qdf_list_destroy(&sta_info_container->sta_obj); + qdf_spinlock_destroy(&sta_info_container->sta_obj_lock); +} + +QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *sta_info) +{ + if (!sta_info_container || !sta_info) { + hdd_err("Parameter(s) null"); + return QDF_STATUS_E_INVAL; + } + + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + hdd_take_sta_info_ref(sta_info_container, sta_info, false, + STA_INFO_ATTACH_DETACH); + qdf_list_insert_front(&sta_info_container->sta_obj, + &sta_info->sta_node); + sta_info->is_attached = true; + + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + + return QDF_STATUS_SUCCESS; +} + +void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **sta_info) +{ + struct hdd_station_info *info; + + if (!sta_info_container || !sta_info) { + hdd_err("Parameter(s) null"); + return; + } + + info = *sta_info; + + if (!info) + return; + + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + if (info->is_attached) { + info->is_attached = false; + hdd_put_sta_info_ref(sta_info_container, sta_info, false, + STA_INFO_ATTACH_DETACH); + } else { + hdd_info("Stainfo is already detached"); + } + + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); +} + +struct hdd_station_info *hdd_get_sta_info_by_mac( + struct hdd_sta_info_obj *sta_info_container, + const uint8_t *mac_addr, + wlan_sta_info_dbgid sta_info_dbgid) +{ + struct hdd_station_info *sta_info = NULL; + + if (!mac_addr || !sta_info_container) { + hdd_err("Parameter(s) null"); + return NULL; + } + + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + qdf_list_for_each(&sta_info_container->sta_obj, sta_info, sta_node) { + if (qdf_is_macaddr_equal(&sta_info->sta_mac, + (struct qdf_mac_addr *)mac_addr)) { + hdd_take_sta_info_ref(sta_info_container, + sta_info, false, sta_info_dbgid); + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + return sta_info; + } + } + + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + + return NULL; +} + +void hdd_take_sta_info_ref(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *sta_info, + bool lock_required, + wlan_sta_info_dbgid sta_info_dbgid) +{ + if (!sta_info_container || !sta_info) { + hdd_err("Parameter(s) null"); + return; + } + + if (sta_info_dbgid >= STA_INFO_ID_MAX) { + hdd_err("Invalid sta_info debug id %d", sta_info_dbgid); + return; + } + + if (lock_required) + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + qdf_atomic_inc(&sta_info->ref_cnt); + qdf_atomic_inc(&sta_info->ref_cnt_dbgid[sta_info_dbgid]); + + if (lock_required) + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); +} + +void +hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **sta_info, bool lock_required, + wlan_sta_info_dbgid sta_info_dbgid) +{ + struct hdd_station_info *info; + struct qdf_mac_addr addr; + + if (!sta_info_container || !sta_info) { + hdd_err("Parameter(s) null"); + return; + } + + info = *sta_info; + + if (!info) { + hdd_err("station info NULL"); + return; + } + + if (sta_info_dbgid >= STA_INFO_ID_MAX) { + hdd_err("Invalid sta_info debug id %d", sta_info_dbgid); + return; + } + + if (lock_required) + qdf_spin_lock_bh(&sta_info_container->sta_obj_lock); + + /* + * In case the put_ref is called more than twice for a single take_ref, + * this will result in either a BUG or page fault. In both the cases, + * the root cause would be known and the buggy put_ref can be taken + * care of. + */ + if (!qdf_atomic_read(&info->ref_cnt_dbgid[sta_info_dbgid])) { + hdd_err("Sta_info ref count put is detected without get for debug id %s", + sta_info_string_from_dbgid(sta_info_dbgid)); + + QDF_BUG(0); + } + + qdf_atomic_dec(&info->ref_cnt); + qdf_atomic_dec(&info->ref_cnt_dbgid[sta_info_dbgid]); + + if (qdf_atomic_read(&info->ref_cnt)) { + if (lock_required) + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + return; + } + + qdf_copy_macaddr(&addr, &info->sta_mac); + if (info->assoc_req_ies.len) { + qdf_mem_free(info->assoc_req_ies.data); + info->assoc_req_ies.data = NULL; + info->assoc_req_ies.len = 0; + } + + qdf_list_remove_node(&sta_info_container->sta_obj, &info->sta_node); + qdf_mem_free(info); + *sta_info = NULL; + + if (lock_required) + qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock); + + hdd_nofl_debug("STA_INFO: " QDF_MAC_ADDR_FMT " freed", + QDF_MAC_ADDR_REF(addr.bytes)); +} + +void hdd_clear_cached_sta_info(struct hdd_adapter *adapter) +{ + struct hdd_station_info *sta_info = NULL, *tmp = NULL; + + if (!adapter) { + hdd_err("Parameter null"); + return; + } + + hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list, sta_info, tmp, + STA_INFO_CLEAR_CACHED_STA_INFO) { + hdd_sta_info_detach(&adapter->cache_sta_info_list, &sta_info); + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &sta_info, + true, STA_INFO_CLEAR_CACHED_STA_INFO); + } +} + +QDF_STATUS +hdd_get_front_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **out_sta_info) +{ + QDF_STATUS status; + qdf_list_node_t *node; + + *out_sta_info = NULL; + + status = qdf_list_peek_front(&sta_info_container->sta_obj, &node); + + if (QDF_IS_STATUS_ERROR(status)) + return status; + + *out_sta_info = + qdf_container_of(node, struct hdd_station_info, sta_node); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *current_sta_info, + struct hdd_station_info **out_sta_info) +{ + QDF_STATUS status; + qdf_list_node_t *node; + + if (!current_sta_info) + return QDF_STATUS_E_INVAL; + + *out_sta_info = NULL; + + status = qdf_list_peek_next(&sta_info_container->sta_obj, + ¤t_sta_info->sta_node, + &node); + + if (QDF_IS_STATUS_ERROR(status)) + return status; + + *out_sta_info = + qdf_container_of(node, struct hdd_station_info, sta_node); + + return QDF_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.h new file mode 100644 index 0000000000000000000000000000000000000000..8a337034b518c73ac7e9a65f2411d08b8b89ce6f --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sta_info.h @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +/** + * DOC: wlan_hdd_sta_info.h + * + * Store and manage station info structure. + * + */ +#if !defined(__WLAN_HDD_STA_INFO_H) +#define __WLAN_HDD_STA_INFO_H + +#include +#include "qdf_lock.h" +#include "qdf_types.h" +#include "qdf_list.h" +#include "sap_api.h" +#include "cdp_txrx_cmn_struct.h" +#include "sir_mac_prot_def.h" +#include +#include + +/* Opaque handle for abstraction */ +#define hdd_sta_info_entry qdf_list_node_t + +/** + * struct dhcp_phase - Per Peer DHCP Phases + * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or + * DHCP_DELINE message in OFFER phase + * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase + * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase + * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or + * ACK phase (Renewal process) + */ +enum dhcp_phase { + DHCP_PHASE_ACK, + DHCP_PHASE_DISCOVER, + DHCP_PHASE_OFFER, + DHCP_PHASE_REQUEST +}; + +/** + * struct dhcp_nego_status - Per Peer DHCP Negotiation Status + * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated + * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST + * (Renewal process) phase + */ +enum dhcp_nego_status { + DHCP_NEGO_STOP, + DHCP_NEGO_IN_PROGRESS +}; + +/** + * Pending frame type of EAP_FAILURE, bit number used in "pending_eap_frm_type" + * of sta_info. + */ +#define PENDING_TYPE_EAP_FAILURE 0 + +/** + * enum wlan_sta_info_dbgid - sta info put/get debug id + * @STA_INFO_ID_RESERVED: Reserved + * @STA_INFO_CFG80211_GET_LINK_PROPERTIES: Get link properties + * @STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT: Inspect the EAP-Failure + * @STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT: Check and wait for eap failure + * pkt tx completion + * @STA_INFO_SOFTAP_INSPECT_DHCP_PACKET: Inspect DHCP packet + * @STA_INFO_SOFTAP_HARD_START_XMIT: Transmit a frame + * @STA_INFO_SOFTAP_INIT_TX_RX_STA: Initialize Tx/Rx for a softap station + * @STA_INFO_SOFTAP_RX_PACKET_CBK: Receive packet handler + * @STA_INFO_SOFTAP_REGISTER_STA: Register a SoftAP STA + * @STA_INFO_GET_CACHED_STATION_REMOTE: Get cached peer's info + * @STA_INFO_HDD_GET_STATION_REMOTE: Get remote peer's info + * @STA_INFO_WLAN_HDD_GET_STATION_REMOTE: NL80211_CMD_GET_STATION handler for + * SoftAP + * @STA_INFO_SOFTAP_DEAUTH_CURRENT_STA: Deauth current sta + * @STA_INFO_SOFTAP_DEAUTH_ALL_STA: Deauth all sta in the sta list + * @STA_INFO_CFG80211_DEL_STATION: CFG80211 del station handler + * @STA_INFO_HDD_CLEAR_ALL_STA: Clear all stations + * @STA_INFO_FILL_STATION_INFO: Fill stainfo for connected station + * @STA_INFO_HOSTAPD_SAP_EVENT_CB: SAP event handler + * @STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA: Indicating disconnect indication + * to the supplicant + * @STA_INFO_IS_PEER_ASSOCIATED: Is peer connected to softap + * @STA_INFO_SAP_SET_TWO_INTS_GETNONE: Generic "set two integer" ioctl handler + * @STA_INFO_SAP_GETASSOC_STAMACADDR: Handler to get assoc station mac address + * @STA_INFO_SOFTAP_GET_STA_INFO: Get station info handler + * @STA_INFO_GET_SOFTAP_LINKSPEED: Get link speed handler + * @STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR: Check adapter connection based on + * device mode + * @STA_INFO_SOFTAP_STOP_BSS: Stop BSS + * @STA_INFO_SOFTAP_CHANGE_STA_STATE: Change the state of a SoftAP station + * @STA_INFO_CLEAR_CACHED_STA_INFO: Clear the cached sta info + * @STA_INFO_ATTACH_DETACH: Station info attach/detach + * @STA_INFO_SHOW: Station info show + * + */ +/* + * New value added to the enum must also be reflected in function + * sta_info_string_from_dbgid() + */ +typedef enum { + STA_INFO_ID_RESERVED = 0, + STA_INFO_CFG80211_GET_LINK_PROPERTIES = 1, + STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT = 2, + STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT = 3, + STA_INFO_SOFTAP_INSPECT_DHCP_PACKET = 4, + STA_INFO_SOFTAP_HARD_START_XMIT = 5, + STA_INFO_SOFTAP_INIT_TX_RX_STA = 6, + STA_INFO_SOFTAP_RX_PACKET_CBK = 7, + STA_INFO_SOFTAP_REGISTER_STA = 8, + STA_INFO_GET_CACHED_STATION_REMOTE = 9, + STA_INFO_HDD_GET_STATION_REMOTE = 10, + STA_INFO_WLAN_HDD_GET_STATION_REMOTE = 11, + STA_INFO_SOFTAP_DEAUTH_CURRENT_STA = 12, + STA_INFO_SOFTAP_DEAUTH_ALL_STA = 13, + STA_INFO_CFG80211_DEL_STATION = 14, + STA_INFO_HDD_CLEAR_ALL_STA = 15, + STA_INFO_FILL_STATION_INFO = 16, + STA_INFO_HOSTAPD_SAP_EVENT_CB = 17, + STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA = 18, + STA_INFO_IS_PEER_ASSOCIATED = 19, + STA_INFO_SAP_SET_TWO_INTS_GETNONE = 20, + STA_INFO_SAP_GETASSOC_STAMACADDR = 21, + STA_INFO_SOFTAP_GET_STA_INFO = 22, + STA_INFO_GET_SOFTAP_LINKSPEED = 23, + STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR = 24, + STA_INFO_SOFTAP_STOP_BSS = 25, + STA_INFO_SOFTAP_CHANGE_STA_STATE = 26, + STA_INFO_CLEAR_CACHED_STA_INFO = 27, + STA_INFO_ATTACH_DETACH = 28, + STA_INFO_SHOW = 29, + + STA_INFO_ID_MAX, +} wlan_sta_info_dbgid; + +/** + * sta_info_string_from_dbgid() - Convert dbgid to respective string + * @id - debug id + * + * Debug support function to convert dbgid to string. + * Please note to add new string in the array at index equal to + * its enum value in wlan_sta_info_dbgid. + */ +char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id); + +/** + * struct hdd_station_info - Per station structure kept in HDD for + * multiple station support for SoftAP + * @in_use: Is the station entry in use? + * @sta_id: Station ID reported back from HAL (through SAP). + * Broadcast uses station ID zero by default. + * @sta_type: Type of station i.e. p2p client or infrastructure station + * @sta_mac: MAC address of the station + * @peer_state: Current Station state so HDD knows how to deal with packet + * queue. Most recent states used to change TLSHIM STA state. + * @is_qos_enabled: Track QoS status of station + * @is_deauth_in_progress: The station entry for which Deauth is in progress + * @nss: Number of spatial streams supported + * @rate_flags: Rate Flags for this connection + * @ecsa_capable: Extended CSA capabilities + * @max_phy_rate: Calcuated maximum phy rate based on mode, nss, mcs etc. + * @tx_packets: The number of frames from host to firmware + * @tx_bytes: Bytes send to current station + * @rx_packets: Packets received from current station + * @rx_bytes: Bytes received from current station + * @last_tx_rx_ts: Last tx/rx timestamp with current station + * @assoc_ts: Current station association timestamp + * @tx_rate: Tx rate with current station reported from F/W + * @rx_rate: Rx rate with current station reported from F/W + * @ampdu: Ampdu enable or not of the station + * @sgi_enable: Short GI enable or not of the station + * @tx_stbc: Tx Space-time block coding enable/disable + * @rx_stbc: Rx Space-time block coding enable/disable + * @ch_width: Channel Width of the connection + * @mode: Mode of the connection + * @max_supp_idx: Max supported rate index of the station + * @max_ext_idx: Max extended supported rate index of the station + * @max_mcs_idx: Max supported mcs index of the station + * @rx_mcs_map: VHT Rx mcs map + * @tx_mcs_map: VHT Tx mcs map + * @freq : Frequency of the current station + * @dot11_mode: 802.11 Mode of the connection + * @ht_present: HT caps present or not in the current station + * @vht_present: VHT caps present or not in the current station + * @ht_caps: HT capabilities of current station + * @vht_caps: VHT capabilities of current station + * @reason_code: Disconnection reason code for current station + * @rssi: RSSI of the current station reported from F/W + * @capability: Capability information of current station + * @support_mode: Max supported mode of a station currently + * connected to sap + * @rx_retry_cnt: Number of rx retries received from current station + * Currently this feature is not supported from FW + * @rx_mc_bc_cnt: Multicast broadcast packet count received from + * current station + * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt + * feature or not, if first bit is 1 it indicates that FW supports this + * feature, if it is 0 it indicates FW doesn't support this feature + * @tx_failed: the number of tx failed frames + * @peer_rssi_per_chain: the average value of RSSI (dbm) per chain + * @tx_retry_succeed: the number of frames retried but successfully transmit + * @rx_last_pkt_rssi: the rssi (dbm) calculate by last packet + * @tx_retry: the number of retried frames from host to firmware + * @tx_retry_exhaust: the number of frames retried but finally failed + * from host to firmware + * @tx_total_fw: the number of all frames from firmware to remote station + * @tx_retry_fw: the number of retried frames from firmware to remote station + * @tx_retry_exhaust_fw: the number of frames retried but finally failed from + * firmware to remote station + * @sta_info: The sta_info node for the station info list maintained in adapter + * @assoc_req_ies: Assoc request IEs of the peer station + * @ref_cnt: Reference count to synchronize sta_info access + * @ref_cnt_dbgid: Reference count to debug sta_info synchronization issues + * @pending_eap_frm_type: EAP frame type in tx queue without tx completion + * @is_attached: Flag to check if the stainfo is attached/detached + */ +struct hdd_station_info { + bool in_use; + uint8_t sta_id; + eStationType sta_type; + struct qdf_mac_addr sta_mac; + enum ol_txrx_peer_state peer_state; + bool is_qos_enabled; + bool is_deauth_in_progress; + uint8_t nss; + uint32_t rate_flags; + uint8_t ecsa_capable; + uint32_t max_phy_rate; + uint32_t tx_packets; + uint64_t tx_bytes; + uint32_t rx_packets; + uint64_t rx_bytes; + qdf_time_t last_tx_rx_ts; + qdf_time_t assoc_ts; + qdf_time_t disassoc_ts; + uint32_t tx_rate; + uint32_t rx_rate; + bool ampdu; + bool sgi_enable; + bool tx_stbc; + bool rx_stbc; + tSirMacHTChannelWidth ch_width; + uint8_t mode; + uint8_t max_supp_idx; + uint8_t max_ext_idx; + uint8_t max_mcs_idx; + uint8_t rx_mcs_map; + uint8_t tx_mcs_map; + uint32_t freq; + uint8_t dot11_mode; + bool ht_present; + bool vht_present; + struct ieee80211_ht_cap ht_caps; + struct ieee80211_vht_cap vht_caps; + uint32_t reason_code; + int8_t rssi; + enum dhcp_phase dhcp_phase; + enum dhcp_nego_status dhcp_nego_status; + uint16_t capability; + uint8_t support_mode; + uint32_t rx_retry_cnt; + uint32_t rx_mc_bc_cnt; + uint32_t tx_failed; + uint32_t peer_rssi_per_chain[WMI_MAX_CHAINS]; + uint32_t tx_retry_succeed; + uint32_t rx_last_pkt_rssi; + uint32_t tx_retry; + uint32_t tx_retry_exhaust; + uint32_t tx_total_fw; + uint32_t tx_retry_fw; + uint32_t tx_retry_exhaust_fw; + qdf_list_node_t sta_node; + struct wlan_ies assoc_req_ies; + qdf_atomic_t ref_cnt; + qdf_atomic_t ref_cnt_dbgid[STA_INFO_ID_MAX]; + unsigned long pending_eap_frm_type; + bool is_attached; +}; + +/** + * struct hdd_sta_info_obj - Station info container structure + * @sta_obj: The sta info object that stores the sta_info + * @sta_obj_lock: Lock to protect the sta_obj read/write access + */ +struct hdd_sta_info_obj { + qdf_list_t sta_obj; + qdf_spinlock_t sta_obj_lock; +}; + +/** + * hdd_put_sta_info_ref() - Release sta_info ref for synchronization + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: Station info structure to be released. + * @lock_required: Flag to acquire lock or not + * @sta_info_dbgid: Debug ID of the caller API + * + * Return: None + */ +void hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **sta_info, + bool lock_required, + wlan_sta_info_dbgid sta_info_dbgid); + +/** + * hdd_take_sta_info_ref() - Increment sta info ref. + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: Station info structure to be released. + * @lock_required: Flag to acquire lock or not + * @sta_info_dbgid: Debug ID of the caller API + * + * This function has to be accompanied by hdd_put_sta_info when the work with + * the sta info is done. Failure to do so will result in a mem leak. + * + * Return: None + */ +void hdd_take_sta_info_ref(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *sta_info, + bool lock_required, + wlan_sta_info_dbgid sta_info_dbgid); + +/** + * hdd_get_front_sta_info_no_lock() - Get the first sta_info from the sta list + * This API doesnot use any lock in it's implementation. It is the caller's + * directive to ensure concurrency safety. + * + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @out_sta_info: The station info structure that acts as the container object. + * + * Return: QDF_STATUS + */ +QDF_STATUS +hdd_get_front_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **out_sta_info); + +/** + * hdd_get_next_sta_info_no_lock() - Get the next sta_info from the sta list + * This API doesnot use any lock in it's implementation. It is the caller's + * directive to ensure concurrency safety. + * + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @out_sta_info: The station info structure that acts as the container object. + * + * Return: QDF_STATUS + */ +QDF_STATUS +hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *current_sta_info, + struct hdd_station_info **out_sta_info); + +/* Abstract wrapper to check sta_info validity */ +#define __hdd_is_station_valid(sta_info) sta_info + +/** + * __hdd_take_ref_and_fetch_front_sta_info - Helper macro to lock, fetch front + * sta_info, take ref and unlock. + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + */ +#define __hdd_take_ref_and_fetch_front_sta_info(sta_info_container, sta_info, \ + sta_info_dbgid) \ + qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \ + hdd_get_front_sta_info_no_lock(&sta_info_container, &sta_info), \ + (sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \ + sta_info, false, sta_info_dbgid) : \ + (false), \ + qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock) + +/** + * __hdd_take_ref_and_fetch_next_sta_info - Helper macro to lock, fetch next + * sta_info, take ref and unlock. + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + */ +#define __hdd_take_ref_and_fetch_next_sta_info(sta_info_container, sta_info, \ + sta_info_dbgid) \ + qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \ + hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \ + &sta_info), \ + (sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \ + sta_info, false, sta_info_dbgid) : \ + (false), \ + qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock) + +/** + * hdd_for_each_sta_ref - Iterate over each station stored in the sta info + * container with ref taken + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + * @sta_info_dbgid: Debug ID of the caller API + * + * The sta_info will contain the structure that is fetched for that particular + * iteration. + * + * ***** NOTE ***** + * Before the end of each iteration, dev_put(adapter->dev) must be + * called. Not calling this will keep hold of a reference, thus preventing + * unregister of the netdevice. + * + * Usage example: + * hdd_for_each_sta_ref(sta_info_container, sta_info, sta_info_dbgid) { + * + * + * hdd_put_sta_info_ref(sta_info_container, sta_info, true, + * sta_info_dbgid) + * } + */ +#define hdd_for_each_sta_ref(sta_info_container, sta_info, sta_info_dbgid) \ + for (__hdd_take_ref_and_fetch_front_sta_info(sta_info_container, \ + sta_info, sta_info_dbgid);\ + __hdd_is_station_valid(sta_info); \ + __hdd_take_ref_and_fetch_next_sta_info(sta_info_container, \ + sta_info, sta_info_dbgid)) + +/** + * __hdd_take_ref_and_fetch_front_sta_info_safe - Helper macro to lock, fetch + * front sta_info, take ref and unlock in a delete safe manner. + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + */ +#define __hdd_take_ref_and_fetch_front_sta_info_safe(sta_info_container, \ + sta_info, next_sta_info, \ + sta_info_dbgid) \ + qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \ + hdd_get_front_sta_info_no_lock(&sta_info_container, &sta_info), \ + (sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \ + sta_info, false, sta_info_dbgid) : \ + (false), \ + hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \ + &next_sta_info), \ + (next_sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \ + next_sta_info, false, \ + sta_info_dbgid) : \ + (false), \ + qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock) + +/** + * __hdd_take_ref_and_fetch_next_sta_info_safe - Helper macro to lock, fetch + * next sta_info, take ref and unlock. + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + */ +#define __hdd_take_ref_and_fetch_next_sta_info_safe(sta_info_container, \ + sta_info, next_sta_info, \ + sta_info_dbgid) \ + sta_info = next_sta_info, \ + qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \ + hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \ + &next_sta_info), \ + (next_sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \ + next_sta_info, false, \ + sta_info_dbgid) : \ + (false), \ + qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock) + +/** + * hdd_for_each_sta_ref_safe - Iterate over each station stored in the sta info + * container in a delete safe manner + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that acts as the iterator object. + * @next_sta_info: A temporary node for maintaing del safe. + * @sta_info_dbgid: Debug ID of the caller API + * + * The sta_info will contain the structure that is fetched for that particular + * iteration. The next_sta_info is used to store the next station before the + * current station is deleted so as to provide a safe way to iterate the list + * while deletion is undergoing. + * + * ***** NOTE ***** + * Before the end of each iteration, hdd_put_sta_info_ref must be + * called. Not calling this will keep hold of a reference, thus preventing + * deletion of the station info + * + * Usage example: + * hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info, + * sta_info_dbgid) { + * + * + * hdd_put_sta_info_ref(sta_info_container, sta_info, true, + * sta_info_dbgid) + * } + */ +#define hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info, \ + sta_info_dbgid) \ + for (__hdd_take_ref_and_fetch_front_sta_info_safe(sta_info_container, \ + sta_info, \ + next_sta_info, \ + sta_info_dbgid); \ + __hdd_is_station_valid(sta_info); \ + __hdd_take_ref_and_fetch_next_sta_info_safe(sta_info_container, \ + sta_info, \ + next_sta_info, \ + sta_info_dbgid)) + +/** + * wlan_sta_info_init() - Initialise the wlan hdd station info container obj + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * + * Return: QDF_STATUS_SUCCESS on success, failure code otherwise + */ +QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container); + +/** + * wlan_sta_info_deinit() - Deinit the wlan hdd station info container obj + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * + * Return: None + */ +void hdd_sta_info_deinit(struct hdd_sta_info_obj *sta_info_container); + +/** + * hdd_sta_info_detach() - Detach the station info structure from the list + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that has to be detached from the + * container object. + * + * Return: None + */ +void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info **sta_info); + +/** + * hdd_sta_info_attach() - Attach the station info structure into the list + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @sta_info: The station info structure that is to be attached to the + * container object. + * + * Return: QDF STATUS SUCCESS on successful attach, error code otherwise + */ +QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container, + struct hdd_station_info *sta_info); + +/** + * hdd_get_sta_info_by_mac() - Find the sta_info structure by mac addr + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * @mac_addr: The mac addr by which the sta_info has to be fetched. + * @sta_info_dbgid: Debug ID of the caller API + * + * Return: Pointer to the hdd_station_info structure which contains the mac + * address passed + */ +struct hdd_station_info *hdd_get_sta_info_by_mac( + struct hdd_sta_info_obj *sta_info_container, + const uint8_t *mac_addr, + wlan_sta_info_dbgid sta_info_dbgid); + +/** + * hdd_clear_cached_sta_info() - Clear the cached sta info from the container + * @sta_info_container: The station info container obj that stores and maintains + * the sta_info obj. + * + * Return: None + */ +void hdd_clear_cached_sta_info(struct hdd_adapter *hdd_adapter); + +#endif /* __WLAN_HDD_STA_INFO_H */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.c index d0003ddf8fadbc9f1aa350df6b5f8db61fc53231..93ba5f17ef6593bea36ad2b8417578e7f027ce03 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,10 +34,13 @@ #include #include #include "wlan_mlme_ucfg_api.h" +#include "wlan_hdd_sta_info.h" #include #include #include #include +#include "wlan_hdd_object_manager.h" + /* * define short names for the global vendor params * used by __wlan_hdd_cfg80211_get_station_cmd() @@ -53,6 +56,9 @@ #define STATION_MAX \ QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX +#define STA_INFO_CONNECT_FAIL_REASON_CODE \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE + /* define short names for get station info attributes */ #define LINK_INFO_STANDARD_NL80211_ATTR \ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR @@ -70,6 +76,8 @@ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION #define VHT_OPERATION \ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION +#define HE_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION #define INFO_ASSOC_FAIL_REASON \ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON #define REMOTE_MAX_PHY_RATE \ @@ -146,7 +154,12 @@ hdd_get_station_policy[STATION_MAX + 1] = { [STATION_REMOTE] = {.type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE}, }; -#ifdef QCA_SUPPORT_CP_STATS +const struct nla_policy +hdd_get_sta_policy[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC] = {.type = NLA_BINARY, + .len = QDF_MAC_ADDR_SIZE}, +}; + static int hdd_get_sta_congestion(struct hdd_adapter *adapter, uint32_t *congestion) { @@ -160,17 +173,6 @@ static int hdd_get_sta_congestion(struct hdd_adapter *adapter, *congestion = cca_stats.congestion; return 0; } -#else -static int hdd_get_sta_congestion(struct hdd_adapter *adapter, - uint32_t *congestion) -{ - struct hdd_station_ctx *hdd_sta_ctx; - - hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - *congestion = hdd_sta_ctx->conn_info.cca; - return 0; -} -#endif /** * hdd_get_station_assoc_fail() - Handle get station assoc fail @@ -414,6 +416,7 @@ static void hdd_get_max_tx_bitrate(struct hdd_context *hdd_ctx, uint8_t tx_mcs_index, tx_nss = 1; uint16_t my_tx_rate; struct hdd_station_ctx *hdd_sta_ctx; + struct wlan_objmgr_vdev *vdev; hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); @@ -425,14 +428,22 @@ static void hdd_get_max_tx_bitrate(struct hdd_context *hdd_ctx, my_tx_rate = adapter->hdd_stats.class_a_stat.tx_rate; if (!(tx_rate_flags & TX_RATE_LEGACY)) { - tx_nss = adapter->hdd_stats.class_a_stat.tx_nss; - if (tx_nss > 1 && - policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) && - !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) { - hdd_debug("Hw mode is DBS, Reduce nss(%d) to 1", - tx_nss); - tx_nss--; + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + /* + * Take static NSS for reporting max rates. + * NSS from FW is not reliable as it changes + * as per the environment quality. + */ + tx_nss = wlan_vdev_mlme_get_nss(vdev); + hdd_objmgr_put_vdev(vdev); + } else { + tx_nss = adapter->hdd_stats.class_a_stat.tx_nss; } + hdd_check_and_update_nss(hdd_ctx, &tx_nss, NULL); + + if (tx_mcs_index == INVALID_MCS_IDX) + tx_mcs_index = 0; } if (hdd_report_max_rate(hdd_ctx->mac_handle, &sinfo.txrate, sinfo.signal, tx_rate_flags, tx_mcs_index, @@ -509,7 +520,7 @@ static int32_t hdd_add_survey_info(struct sk_buff *skb, if (!nla_attr) goto fail; if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY, - hdd_sta_ctx->cache_conn_info.freq) || + hdd_sta_ctx->cache_conn_info.chan_freq) || nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE, (hdd_sta_ctx->cache_conn_info.noise + 100))) { hdd_err("put fail"); @@ -613,6 +624,47 @@ hdd_add_ap_standard_info(struct sk_buff *skb, return -EINVAL; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ + defined(WLAN_FEATURE_11AX) +static int32_t hdd_add_he_oper_info( + struct sk_buff *skb, + struct hdd_station_ctx *hdd_sta_ctx) +{ + int32_t ret = 0; + + if (!hdd_sta_ctx->cache_conn_info.he_oper_len || + !hdd_sta_ctx->cache_conn_info.he_operation) + return ret; + + if (nla_put(skb, HE_OPERATION, + hdd_sta_ctx->cache_conn_info.he_oper_len, + hdd_sta_ctx->cache_conn_info.he_operation)) + ret = -EINVAL; + + qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); + hdd_sta_ctx->cache_conn_info.he_operation = NULL; + hdd_sta_ctx->cache_conn_info.he_oper_len = 0; + return ret; +} + +static int32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx) +{ + return hdd_sta_ctx->cache_conn_info.he_oper_len; +} +#else +static inline uint32_t hdd_add_he_oper_info( + struct sk_buff *skb, + struct hdd_station_ctx *hdd_sta_ctx) +{ + return 0; +} + +static uint32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx) +{ + return 0; +} +#endif + /** * hdd_get_station_info() - send BSS information to supplicant * @hdd_ctx: pointer to hdd context @@ -625,7 +677,7 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, { struct sk_buff *skb = NULL; uint8_t *tmp_hs20 = NULL, *ies = NULL; - uint32_t nl_buf_len, ie_len = 0; + uint32_t nl_buf_len, ie_len = 0, hdd_he_op_len = 0; struct hdd_station_ctx *hdd_sta_ctx; QDF_STATUS status; @@ -635,7 +687,7 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, nl_buf_len += sizeof(hdd_sta_ctx-> cache_conn_info.last_ssid.SSID.length) + QDF_MAC_ADDR_SIZE + - sizeof(hdd_sta_ctx->cache_conn_info.freq) + + sizeof(hdd_sta_ctx->cache_conn_info.chan_freq) + sizeof(hdd_sta_ctx->cache_conn_info.noise) + sizeof(hdd_sta_ctx->cache_conn_info.signal) + (sizeof(uint32_t) * 2) + @@ -666,6 +718,9 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, if (QDF_IS_STATUS_SUCCESS(status)) nl_buf_len += ie_len; + hdd_he_op_len = hdd_get_he_op_len(hdd_sta_ctx); + nl_buf_len += hdd_he_op_len; + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); if (!skb) { hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); @@ -708,6 +763,10 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, hdd_err("put fail"); goto fail; } + if (hdd_add_he_oper_info(skb, hdd_sta_ctx)) { + hdd_err("put fail"); + goto fail; + } if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) if (nla_put(skb, AP_INFO_HS20_INDICATION, (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) @@ -1047,29 +1106,33 @@ static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width) /** * hdd_get_peer_stats - get the peer stats + * @vdev_id: vdev id * @mac_addr: mac address * @stainfo: station info pointer * * Return: None */ -static void hdd_get_peer_stats(struct qdf_mac_addr mac_addr, +static void hdd_get_peer_stats(uint8_t vdev_id, + struct qdf_mac_addr mac_addr, struct hdd_station_info *stainfo) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_peer *peer; - uint8_t peer_id; struct cdp_peer_stats *peer_stats; + QDF_STATUS status; - peer = cdp_peer_find_by_addr(soc, txrx_pdev, mac_addr.bytes, &peer_id); - if (peer) { - peer_stats = cdp_host_get_peer_stats(soc, peer); - if (peer_stats) { - stainfo->rx_retry_cnt = peer_stats->rx.rx_retries; - stainfo->rx_mc_bc_cnt = peer_stats->rx.multicast.num + - peer_stats->rx.bcast.num; - } + peer_stats = qdf_mem_malloc(sizeof(*peer_stats)); + if (!peer_stats) + return; + + status = cdp_host_get_peer_stats(soc, vdev_id, mac_addr.bytes, + peer_stats); + if (status == QDF_STATUS_SUCCESS) { + stainfo->rx_retry_cnt = peer_stats->rx.rx_retries; + stainfo->rx_mc_bc_cnt = peer_stats->rx.multicast.num + + peer_stats->rx.bcast.num; } + + qdf_mem_free(peer_stats); } /** @@ -1087,16 +1150,18 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, struct qdf_mac_addr mac_addr) { - struct hdd_station_info *stainfo = hdd_get_stainfo( - adapter->cache_sta_info, - mac_addr); + struct hdd_station_info *stainfo; struct sk_buff *skb = NULL; uint32_t nl_buf_len = NLMSG_HDRLEN; uint8_t channel_width; + stainfo = hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list, + mac_addr.bytes, + STA_INFO_GET_CACHED_STATION_REMOTE); + if (!stainfo) { - hdd_err("peer " QDF_MAC_ADDR_STR " not found", - QDF_MAC_ADDR_ARRAY(mac_addr.bytes)); + hdd_err("peer " QDF_MAC_ADDR_FMT " not found", + QDF_MAC_ADDR_REF(mac_addr.bytes)); return -EINVAL; } @@ -1117,6 +1182,9 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx, skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); if (!skb) { + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, + &stainfo, true, + STA_INFO_GET_CACHED_STATION_REMOTE); hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); return -ENOMEM; } @@ -1142,11 +1210,13 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx, hdd_err("remote ch put fail"); goto fail; } - if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate)) { + /* Convert the data from kbps to mbps as expected by the user space */ + if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate / 1000)) { hdd_err("tx rate put fail"); goto fail; } - if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) { + /* Convert the data from kbps to mbps as expected by the user space */ + if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate / 1000)) { hdd_err("rx rate put fail"); goto fail; } @@ -1181,19 +1251,18 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx, hdd_err("Failed to put assoc req IEs"); goto fail; } - qdf_mem_free(stainfo->assoc_req_ies.data); - stainfo->assoc_req_ies.data = NULL; - stainfo->assoc_req_ies.len = 0; } - qdf_mem_zero(stainfo, sizeof(*stainfo)); + hdd_sta_info_detach(&adapter->cache_sta_info_list, &stainfo); + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true, + STA_INFO_GET_CACHED_STATION_REMOTE); + qdf_atomic_dec(&adapter->cache_sta_count); return cfg80211_vendor_cmd_reply(skb); fail: + hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true, + STA_INFO_GET_CACHED_STATION_REMOTE); if (skb) kfree_skb(skb); - qdf_mem_free(stainfo->assoc_req_ies.data); - stainfo->assoc_req_ies.data = NULL; - stainfo->assoc_req_ies.len = 0; return -EINVAL; } @@ -1235,7 +1304,7 @@ static int hdd_get_connected_station_info(struct hdd_context *hdd_ctx, (NLA_ALIGN(sizeof(stainfo->dot11_mode)) + NLA_HDRLEN) + (NLA_ALIGN(sizeof(stainfo->mode)) + NLA_HDRLEN); - hdd_get_peer_stats(mac_addr, stainfo); + hdd_get_peer_stats(adapter->vdev_id, mac_addr, stainfo); status = ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value); if (status != QDF_STATUS_SUCCESS) @@ -1420,10 +1489,13 @@ static int hdd_get_station_remote(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, struct qdf_mac_addr mac_addr) { - struct hdd_station_info *stainfo = hdd_get_stainfo(adapter->sta_info, - mac_addr); int status = 0; bool is_associated = false; + struct hdd_station_info *stainfo = + hdd_get_sta_info_by_mac( + &adapter->sta_info_list, + mac_addr.bytes, + STA_INFO_HDD_GET_STATION_REMOTE); if (!stainfo) { status = hdd_get_cached_station_remote(hdd_ctx, adapter, @@ -1435,11 +1507,15 @@ static int hdd_get_station_remote(struct hdd_context *hdd_ctx, if (!is_associated) { status = hdd_get_cached_station_remote(hdd_ctx, adapter, mac_addr); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_HDD_GET_STATION_REMOTE); return status; } status = hdd_get_connected_station_info(hdd_ctx, adapter, mac_addr, stainfo); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_HDD_GET_STATION_REMOTE); return status; } @@ -1505,8 +1581,8 @@ __hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE], QDF_MAC_ADDR_SIZE); - hdd_debug("STATION_REMOTE " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_addr.bytes)); + hdd_debug("STATION_REMOTE " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr.bytes)); status = hdd_get_station_remote(hdd_ctx, adapter, mac_addr); } else { @@ -1538,3 +1614,215 @@ int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, return errno; } +static uint32_t +hdd_get_connect_fail_reason_code_len(struct hdd_adapter *adapter) +{ + if (adapter->connect_req_status == STATUS_SUCCESS) + return 0; + + return nla_total_size(sizeof(uint32_t)); +} + +/** + * hdd_get_umac_to_osif_connect_fail_reason() - Convert to qca internal connect + * fail reason + * @internal_reason: Mac reason code of type @wlan_status_code + * + * Check if it is internal status code and convert it to the + * enum qca_sta_connect_fail_reason_codes. + * + * Return: Reason code of type enum qca_sta_connect_fail_reason_codes + */ +static enum qca_sta_connect_fail_reason_codes +hdd_get_umac_to_osif_connect_fail_reason(enum wlan_status_code internal_reason) +{ + enum qca_sta_connect_fail_reason_codes reason = 0; + + if (internal_reason < STATUS_PROP_START) + return reason; + + switch (internal_reason) { + case STATUS_NO_NETWORK_FOUND: + reason = QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND; + break; + case STATUS_AUTH_TX_FAIL: + reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL; + break; + case STATUS_AUTH_NO_ACK_RECEIVED: + reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED; + break; + case STATUS_AUTH_NO_RESP_RECEIVED: + reason = QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED; + break; + case STATUS_ASSOC_TX_FAIL: + reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL; + break; + case STATUS_ASSOC_NO_ACK_RECEIVED: + reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED; + break; + case STATUS_ASSOC_NO_RESP_RECEIVED: + reason = QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED; + break; + default: + hdd_debug("QCA code not present for internal status code %d", + internal_reason); + } + + return reason; +} + +/** + * hdd_add_connect_fail_reason_code() - Fills connect fail reason code + * @skb: pointer to skb + * @adapter: pointer to hdd adapter + * + * Return: on success 0 else error code + */ +static int hdd_add_connect_fail_reason_code(struct sk_buff *skb, + struct hdd_adapter *adapter) +{ + uint32_t reason; + + reason = hdd_get_umac_to_osif_connect_fail_reason( + adapter->connect_req_status); + if (!reason) + return 0; + + if (nla_put_u32(skb, STA_INFO_CONNECT_FAIL_REASON_CODE, reason)) { + hdd_err("put fail"); + return -EINVAL; + } + + return 0; +} + +/** + * hdd_get_station_info_ex() - send STA info to userspace, for STA mode only + * @hdd_ctx: pointer to hdd context + * @adapter: pointer to adapter + * + * Return: 0 if success else error status + */ +static int hdd_get_station_info_ex(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter) +{ + struct sk_buff *skb; + uint32_t nl_buf_len = 0, connect_fail_rsn_len; + + connect_fail_rsn_len = hdd_get_connect_fail_reason_code_len(adapter); + nl_buf_len = connect_fail_rsn_len; + + nl_buf_len += NLMSG_HDRLEN; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); + if (!skb) { + hdd_err_rl("cfg80211_vendor_cmd_alloc_reply_skb failed"); + return -ENOMEM; + } + + if (connect_fail_rsn_len) { + if (hdd_add_connect_fail_reason_code(skb, adapter)) { + hdd_err_rl("hdd_add_connect_fail_reason_code fail"); + return -ENOMEM; + } + } + + return cfg80211_vendor_cmd_reply(skb); +} + +/** + * __hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd + * @wiphy: pointer to wireless phy + * @wdev: wireless device + * @data: data + * @data_len: data length + * + * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO. + * Validate cmd attributes and send the station info to upper layers. + * + * Return: Success(0) or reason code for failure + */ +static int +__hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1]; + struct qdf_mac_addr mac_addr; + int32_t status; + + hdd_enter_dev(dev); + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE || + hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { + hdd_err_rl("Command not allowed in FTM / Monitor mode"); + status = -EPERM; + goto out; + } + + status = wlan_hdd_validate_context(hdd_ctx); + if (status != 0) + goto out; + + status = wlan_cfg80211_nla_parse(tb, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX, + data, data_len, + hdd_get_sta_policy); + if (status) { + hdd_err_rl("Invalid ATTR"); + goto out; + } + + switch (adapter->device_mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + status = hdd_get_station_info_ex(hdd_ctx, adapter); + break; + case QDF_SAP_MODE: + case QDF_P2P_GO_MODE: + if (!tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC]) { + hdd_err_rl("MAC address is not present"); + status = -EINVAL; + goto out; + } + + nla_memcpy(mac_addr.bytes, + tb[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC], + QDF_MAC_ADDR_SIZE); + hdd_debug("STA " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr.bytes)); + break; + default: + hdd_err_rl("Invalid device_mode: %d", adapter->device_mode); + status = -EINVAL; + goto out; + } + + hdd_exit(); +out: + return status; +} + +int32_t hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct osif_vdev_sync *vdev_sync; + int errno; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __hdd_cfg80211_get_sta_info_cmd(wiphy, wdev, data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.h index 84e2c86930157e3f90ac2842bbd56fb39e67f01d..8bf904cbce28014f8716d4ee3d28ddbcdec8f8dc 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_station_info.h @@ -43,6 +43,23 @@ int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, const void *data, int data_len); +/** + * hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd + * @wiphy: corestack handler + * @wdev: wireless device + * @data: data + * @data_len: data length + * + * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO. + * Validate cmd attributes and send the sta info to upper layers. + * + * Return: Success(0) or reason code for failure + */ +int32_t hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + #define FEATURE_STATION_INFO_VENDOR_COMMANDS \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ @@ -51,6 +68,14 @@ int32_t hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, WIPHY_VENDOR_CMD_NEED_NETDEV | \ WIPHY_VENDOR_CMD_NEED_RUNNING, \ .doit = hdd_cfg80211_get_station_cmd \ +}, \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = hdd_cfg80211_get_sta_info_cmd, \ }, #else /* FEATURE_STATION_INFO */ #define FEATURE_STATION_INFO_VENDOR_COMMANDS diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.c index 33682b871fa7d1cb0f8e01915e23503ebe93576d..cbb8eb39f339e0bbe9d49585bb532ff226e018d6 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,13 +36,16 @@ #include "wlan_hdd_hostapd.h" #include "wlan_osif_request_manager.h" #include "wlan_hdd_debugfs_llstat.h" +#include "wlan_hdd_debugfs_mibstat.h" #include "wlan_reg_services_api.h" #include #include "wlan_cp_stats_mc_ucfg_api.h" #include "wlan_mlme_ucfg_api.h" #include "wlan_mlme_ucfg_api.h" -#include "cdp_txrx_misc.h" +#include "wlan_hdd_sta_info.h" #include "cdp_txrx_host_stats.h" +#include "cdp_txrx_misc.h" +#include "wlan_hdd_object_manager.h" #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) #define HDD_INFO_SIGNAL STATION_INFO_SIGNAL @@ -59,6 +63,8 @@ #define HDD_INFO_RX_BYTES64 0 #define HDD_INFO_INACTIVE_TIME 0 #define HDD_INFO_CONNECTED_TIME 0 +#define HDD_INFO_RX_MPDUS 0 +#define HDD_INFO_FCS_ERROR_COUNT 0 #else #define HDD_INFO_SIGNAL BIT(NL80211_STA_INFO_SIGNAL) #define HDD_INFO_SIGNAL_AVG BIT(NL80211_STA_INFO_SIGNAL_AVG) @@ -75,6 +81,8 @@ #define HDD_INFO_RX_BYTES64 BIT(NL80211_STA_INFO_RX_BYTES64) #define HDD_INFO_INACTIVE_TIME BIT(NL80211_STA_INFO_INACTIVE_TIME) #define HDD_INFO_CONNECTED_TIME BIT(NL80211_STA_INFO_CONNECTED_TIME) +#define HDD_INFO_RX_MPDUS BIT_ULL(NL80211_STA_INFO_RX_MPDUS) +#define HDD_INFO_FCS_ERROR_COUNT BIT_ULL(NL80211_STA_INFO_FCS_ERROR_COUNT) #endif /* kernel version less than 4.0.0 && no_backport */ #define HDD_LINK_STATS_MAX 5 @@ -158,12 +166,12 @@ static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = { {6, {5265, 5850}, {2430, 2700}, {1170, 1300} }, {7, {5850, 6500}, {2700, 3000}, {1300, 1444} }, {8, {7020, 7800}, {3240, 3600}, {1560, 1733} }, - {9, {7800, 8667}, {3600, 4000}, {1560, 1733} } + {9, {7800, 8667}, {3600, 4000}, {1730, 1920} } }; /*array index points to MCS and array value points respective rssi*/ static int rssi_mcs_tbl[][12] = { -/* MCS 0 1 2 3 4 5 6 7 8 9 10 11*/ +/* MCS 0 1 2 3 4 5 6 7 8 9 10 11*/ {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57, -52, -48}, /* 20 */ {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54, -49, -45}, /* 40 */ {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51, -46, -42} /* 80 */ @@ -432,7 +440,10 @@ static bool put_wifi_interface_info(struct wifi_interface_info *stats, CFG_COUNTRY_CODE_LEN, stats->apCountryStr) || nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, - CFG_COUNTRY_CODE_LEN, stats->countryStr)) { + CFG_COUNTRY_CODE_LEN, stats->countryStr) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE, + stats->time_slice_duty_cycle)) { hdd_err("QCA_WLAN_VENDOR_ATTR put fail"); return false; } @@ -598,9 +609,9 @@ bool hdd_get_interface_info(struct hdd_adapter *adapter, if ((eConnectionState_Associated == sta_ctx->conn_info.conn_state) && (!sta_ctx->conn_info.is_authenticated)) { - hdd_err("client " QDF_MAC_ADDR_STR + hdd_err("client " QDF_MAC_ADDR_FMT " is in the middle of WPS/EAPOL exchange.", - QDF_MAC_ADDR_ARRAY(adapter->mac_addr.bytes)); + QDF_MAC_ADDR_REF(adapter->mac_addr.bytes)); info->state = WIFI_AUTHENTICATING; } if (eConnectionState_Associated == @@ -749,11 +760,14 @@ hdd_link_layer_process_iface_stats(struct hdd_adapter *adapter, { struct sk_buff *vendor_event; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - int status; - status = wlan_hdd_validate_context(hdd_ctx); - if (0 != status) - return; + /* + * There is no need for wlan_hdd_validate_context here. This is a NB + * operation that will come with DSC synchronization. This ensures that + * no driver transition will take place as long as this operation is + * not complete. Thus the need to check validity of hdd_context is not + * required. + */ /* * Allocate a size of 4096 for the interface stats comprising @@ -1032,6 +1046,7 @@ hdd_link_layer_process_radio_stats(struct hdd_adapter *adapter, radio_stat++; } + hdd_exit(); } static void hdd_process_ll_stats(tSirLLStatsResults *results, @@ -1737,6 +1752,61 @@ __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, return 0; } +#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI +/** + * wlan_hdd_qmi_get_sync_resume() - Get operation to trigger RTPM + * sync resume without WoW exit + * @hdd_ctx: hdd context + * @dev: device context + * + * Returns: 0 for success, non-zero for failure + */ +static inline +int wlan_hdd_qmi_get_sync_resume(struct hdd_context *hdd_ctx, + struct device *dev) +{ + if (!hdd_ctx->config->is_qmi_stats_enabled) { + hdd_debug("periodic stats over qmi is disabled"); + return 0; + } + + return pld_qmi_send_get(dev); +} + +/** + * wlan_hdd_qmi_put_suspend() - Put operation to trigger RTPM suspend + * without WoW entry + * @hdd_ctx: hdd context + * @dev: device context + * + * Returns: 0 for success, non-zero for failure + */ +static inline +int wlan_hdd_qmi_put_suspend(struct hdd_context *hdd_ctx, + struct device *dev) +{ + if (!hdd_ctx->config->is_qmi_stats_enabled) { + hdd_debug("periodic stats over qmi is disabled"); + return 0; + } + + return pld_qmi_send_put(dev); +} +#else +static inline +int wlan_hdd_qmi_get_sync_resume(struct hdd_context *hdd_ctx, + struct device *dev) +{ + return 0; +} + +static inline int wlan_hdd_qmi_put_suspend(struct hdd_context *hdd_ctx, + struct device *dev) +{ + return 0; +} +#endif /* end if of WLAN_FEATURE_WMI_SEND_RECV_QMI */ + /** * wlan_hdd_cfg80211_ll_stats_get() - get ll stats * @wiphy: Pointer to wiphy @@ -1751,10 +1821,15 @@ int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, const void *data, int data_len) { + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct osif_vdev_sync *vdev_sync; int errno; qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + errno = wlan_hdd_validate_context(hdd_ctx); + if (0 != errno) + return -EINVAL; + if (!qdf_ctx) return -EINVAL; @@ -1762,13 +1837,13 @@ int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, if (errno) return errno; - errno = pld_qmi_send_get(qdf_ctx->dev); + errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev); if (errno) goto end; errno = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len); - pld_qmi_send_put(qdf_ctx->dev); + wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev); end: osif_vdev_sync_op_stop(vdev_sync); @@ -4133,32 +4208,27 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy, struct qdf_mac_addr macaddr; struct sir_peer_info_ext peer_info; struct hdd_fw_txrx_stats txrx_stats; - int status; - int i; + int status, i; status = wlan_hdd_validate_context(hddctx); if (status != 0) return status; - hdd_debug("Peer %pM", mac); - - for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { - if (!qdf_mem_cmp(adapter->sta_info[i].sta_mac.bytes, - mac, - QDF_MAC_ADDR_SIZE)) { - stainfo = &adapter->sta_info[i]; - break; - } - } + hdd_debug("Peer "QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac)); + stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac, + STA_INFO_WLAN_HDD_GET_STATION_REMOTE); if (!stainfo) { - hdd_err("peer %pM not found", mac); + hdd_err("peer "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(mac)); return -EINVAL; } qdf_mem_copy(macaddr.bytes, mac, QDF_MAC_ADDR_SIZE); status = wlan_hdd_get_peer_info(adapter, macaddr, &peer_info); if (status) { + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_WLAN_HDD_GET_STATION_REMOTE); hdd_err("fail to get peer info from fw"); return -EPERM; } @@ -4178,6 +4248,8 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy, WLAN_HDD_TGT_NOISE_FLOOR_DBM; wlan_hdd_fill_rate_info(&txrx_stats, &peer_info); wlan_hdd_fill_station_info(hddctx->psoc, sinfo, stainfo, &txrx_stats); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_WLAN_HDD_GET_STATION_REMOTE); return status; } @@ -4222,8 +4294,10 @@ static void wlan_hdd_fill_os_he_rateflags(struct rate_info *os_rate, * fill RATE_INFO_BW_HE_RU. */ if (rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 | - TX_RATE_HE20)) { - if (rate_flags & TX_RATE_HE80) + TX_RATE_HE20 | TX_RATE_HE160)) { + if (rate_flags & TX_RATE_HE160) + hdd_set_rate_bw(os_rate, HDD_RATE_BW_160); + else if (rate_flags & TX_RATE_HE80) hdd_set_rate_bw(os_rate, HDD_RATE_BW_80); else if (rate_flags & TX_RATE_HE40) hdd_set_rate_bw(os_rate, HDD_RATE_BW_40); @@ -4273,9 +4347,11 @@ static void wlan_hdd_fill_os_rate_info(enum tx_rate_info rate_flags, wlan_hdd_fill_os_he_rateflags(os_rate, rate_flags, dcm, guard_interval); - if (rate_flags & (TX_RATE_VHT80 | TX_RATE_VHT40 | - TX_RATE_VHT20)) { - if (rate_flags & TX_RATE_VHT80) + if (rate_flags & (TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 | + TX_RATE_VHT20)) { + if (rate_flags & TX_RATE_VHT160) + hdd_set_rate_bw(os_rate, HDD_RATE_BW_160); + else if (rate_flags & TX_RATE_VHT80) hdd_set_rate_bw(os_rate, HDD_RATE_BW_80); else if (rate_flags & TX_RATE_VHT40) hdd_set_rate_bw(os_rate, HDD_RATE_BW_40); @@ -4300,7 +4376,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, uint8_t mcs_index, uint16_t fw_rate, uint8_t nss) { - uint8_t i, j, rssidx; + uint8_t i, j, rssidx = 0; uint16_t max_rate = 0; uint32_t vht_mcs_map; bool is_vht20_mcs9 = false; @@ -4335,12 +4411,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, &link_speed_rssi_low, &link_speed_rssi_report); - /* we do not want to necessarily report the current speed */ - if (ucfg_mlme_stats_is_link_speed_report_max(hdd_ctx->psoc)) { - /* report the max possible speed */ - rssidx = 0; - } else if (ucfg_mlme_stats_is_link_speed_report_max_scaled( - hdd_ctx->psoc)) { + if (ucfg_mlme_stats_is_link_speed_report_max_scaled(hdd_ctx->psoc)) { /* report the max possible speed with RSSI scaling */ if (signal >= link_speed_rssi_high) { /* report the max possible speed */ @@ -4355,15 +4426,8 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, /* report actual speed */ rssidx = 3; } - } else { - /* unknown, treat as eHDD_LINK_SPEED_REPORT_MAX */ - hdd_err("Invalid value for reportMaxLinkSpeed: %u", - link_speed_rssi_report); - rssidx = 0; } - max_rate = 0; - /* Get Basic Rate Set */ if (0 != ucfg_mlme_get_opr_rate_set(hdd_ctx->psoc, operational_rates, &or_leng)) { @@ -4423,7 +4487,8 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, } rate_flag = 0; - if (rate_flags & (TX_RATE_VHT80 | TX_RATE_HE80)) + if (rate_flags & (TX_RATE_VHT80 | TX_RATE_HE80 | + TX_RATE_HE160 | TX_RATE_VHT160)) mode = 2; else if (rate_flags & (TX_RATE_HT40 | TX_RATE_VHT40 | TX_RATE_HE40)) @@ -4433,7 +4498,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 | TX_RATE_VHT80 | TX_RATE_HE20 | TX_RATE_HE40 | - TX_RATE_HE80)) { + TX_RATE_HE80 | TX_RATE_HE160 | TX_RATE_VHT160)) { stat = ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &vht_mcs_map); if (QDF_IS_STATUS_ERROR(stat)) @@ -4467,7 +4532,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, } if (rate_flags & (TX_RATE_HE20 | TX_RATE_HE40 | - TX_RATE_HE80)) + TX_RATE_HE80 | TX_RATE_HE160)) max_mcs_idx = 11; if (rssidx != 0) { @@ -4521,7 +4586,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, if ((j < MAX_HT_MCS_IDX) && (current_rate > max_rate)) max_rate = current_rate; - } + } if (nss == 2) max_mcs_idx += MAX_HT_MCS_IDX; @@ -4538,7 +4603,9 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, if ((max_rate < fw_rate) || (0 == max_rate)) { max_rate = fw_rate; } - + hdd_debug("RLMS %u, rate_flags 0x%x, max_rate %d mcs %d nss %d", + link_speed_rssi_report, rate_flags, + max_rate, max_mcs_idx, nss); wlan_hdd_fill_os_rate_info(rate_flags, max_rate, rate, max_mcs_idx, nss, 0, 0); @@ -4625,6 +4692,7 @@ static void hdd_fill_fcs_and_mpdu_count(struct hdd_adapter *adapter, sinfo->fcs_err_count = adapter->hdd_stats.peer_stats.fcs_count; hdd_debug("RX mpdu count %d fcs_err_count %d", sinfo->rx_mpdu_count, sinfo->fcs_err_count); + sinfo->filled |= HDD_INFO_FCS_ERROR_COUNT | HDD_INFO_RX_MPDUS; } #else static void hdd_fill_fcs_and_mpdu_count(struct hdd_adapter *adapter, @@ -4633,32 +4701,20 @@ static void hdd_fill_fcs_and_mpdu_count(struct hdd_adapter *adapter, } #endif -/** - * hdd_check_and_update_nss() - Check and update NSS as per DBS capability - * @hdd_ctx: HDD Context pointer - * @tx_nss: pointer to variable storing the tx_nss - * @rx_nss: pointer to variable storing the rx_nss - * - * The parameters include the NSS obtained from the FW or static NSS. This NSS - * could be invalid in the case the current HW mode is DBS where the connection - * are 1x1. Rectify these NSS values as per the current HW mode. - * - * Return: none - */ -static void hdd_check_and_update_nss(struct hdd_context *hdd_ctx, - uint8_t *tx_nss, uint8_t *rx_nss) +void hdd_check_and_update_nss(struct hdd_context *hdd_ctx, + uint8_t *tx_nss, uint8_t *rx_nss) { - if ((*tx_nss > 1) && + if (tx_nss && (*tx_nss > 1) && policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) && !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) { hdd_debug("Hw mode is DBS, Reduce tx nss(%d) to 1", *tx_nss); (*tx_nss)--; } - if ((*rx_nss > 1) && + if (rx_nss && (*rx_nss > 1) && policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) && !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) { - hdd_debug("Hw mode is DBS, Reduce tx nss(%d) to 1", *rx_nss); + hdd_debug("Hw mode is DBS, Reduce rx nss(%d) to 1", *rx_nss); (*rx_nss)--; } } @@ -4982,20 +5038,20 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); int errno; - if (!qdf_ctx) - return -EINVAL; - errno = wlan_hdd_validate_context(hdd_ctx); if (errno) return errno; - errno = pld_qmi_send_get(qdf_ctx->dev); + if (!qdf_ctx) + return -EINVAL; + + errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev); if (errno) return errno; errno = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo); - pld_qmi_send_put(qdf_ctx->dev); + wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev); return errno; } @@ -5176,13 +5232,12 @@ static bool wlan_hdd_update_survey_info(struct wiphy *wiphy, { bool filled = false; int i, j = 0; - uint32_t channel = 0, opfreq; /* Initialization Required */ + uint32_t opfreq = 0; /* Initialization Required */ struct hdd_context *hdd_ctx; hdd_ctx = WLAN_HDD_GET_CTX(adapter); - sme_get_operation_channel(hdd_ctx->mac_handle, &channel, + sme_get_operation_channel(hdd_ctx->mac_handle, &opfreq, adapter->vdev_id); - opfreq = wlan_reg_chan_to_freq(hdd_ctx->pdev, channel); mutex_lock(&hdd_ctx->chan_info_lock); @@ -5222,7 +5277,7 @@ static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, int status; bool filled = false; - if (idx > QDF_MAX_NUM_CHAN - 1) + if (idx > NUM_CHANNELS - 1) return -EINVAL; hdd_ctx = WLAN_HDD_GET_CTX(adapter); @@ -5533,7 +5588,34 @@ int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, return status; } -#ifdef QCA_SUPPORT_CP_STATS +#ifdef WLAN_FEATURE_MIB_STATS +QDF_STATUS wlan_hdd_get_mib_stats(struct hdd_adapter *adapter) +{ + int ret = 0; + struct stats_event *stats; + + if (!adapter) { + hdd_err("Invalid context, adapter"); + return QDF_STATUS_E_FAULT; + } + + stats = wlan_cfg80211_mc_cp_stats_get_mib_stats( + adapter->vdev, + &ret); + if (ret || !stats) { + wlan_cfg80211_mc_cp_stats_free_stats_event(stats); + return ret; + } + +#ifdef WLAN_DEBUGFS + hdd_debugfs_process_mib_stats(adapter, stats); +#endif + + wlan_cfg80211_mc_cp_stats_free_stats_event(stats); + return ret; +} +#endif + QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value) { int ret = 0, i; @@ -5591,131 +5673,6 @@ QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value) hdd_err("bss peer not present in returned result"); return QDF_STATUS_E_FAULT; } -#else /* QCA_SUPPORT_CP_STATS */ -struct rssi_priv { - int8_t rssi; -}; - -/** - * hdd_get_rssi_cb() - "Get RSSI" callback function - * @rssi: Current RSSI of the station - * @sta_id: ID of the station - * @context: opaque context originally passed to SME. HDD always passes - * a cookie for the request context - * - * Return: None - */ -static void hdd_get_rssi_cb(int8_t rssi, uint32_t sta_id, void *context) -{ - struct osif_request *request; - struct rssi_priv *priv; - - request = osif_request_get(context); - if (!request) { - hdd_err("Obsolete request"); - return; - } - - priv = osif_request_priv(request); - priv->rssi = rssi; - osif_request_complete(request); - osif_request_put(request); -} - -QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value) -{ - struct hdd_context *hdd_ctx; - struct hdd_station_ctx *sta_ctx; - QDF_STATUS status; - int ret; - void *cookie; - struct osif_request *request; - struct rssi_priv *priv; - static const struct osif_request_params params = { - .priv_size = sizeof(*priv), - .timeout_ms = WLAN_WAIT_TIME_STATS, - }; - - if (!adapter) { - hdd_err("Invalid context, adapter"); - return QDF_STATUS_E_FAULT; - } - if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { - hdd_err("Recovery in Progress. State: 0x%x Ignore!!!", - cds_get_driver_state()); - /* return a cached value */ - *rssi_value = adapter->rssi; - return QDF_STATUS_SUCCESS; - } - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - - if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) { - hdd_debug("Not associated!, rssi on disconnect %d", - adapter->rssi_on_disconnect); - *rssi_value = adapter->rssi_on_disconnect; - return QDF_STATUS_SUCCESS; - } - - if (sta_ctx->hdd_reassoc_scenario) { - hdd_debug("Roaming in progress, return cached RSSI"); - *rssi_value = adapter->rssi; - return QDF_STATUS_SUCCESS; - } - - request = osif_request_alloc(¶ms); - if (!request) { - hdd_err("Request allocation failure, return cached RSSI"); - *rssi_value = adapter->rssi; - return QDF_STATUS_SUCCESS; - } - cookie = osif_request_cookie(request); - - status = sme_get_rssi(hdd_ctx->mac_handle, hdd_get_rssi_cb, - sta_ctx->conn_info.sta_id[0], - sta_ctx->conn_info.bssid, adapter->rssi, - cookie); - if (QDF_STATUS_SUCCESS != status) { - hdd_err("Unable to retrieve RSSI"); - /* we'll returned a cached value below */ - } else { - /* request was sent -- wait for the response */ - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_warn("SME timed out while retrieving RSSI"); - /* we'll returned a cached value below */ - } else { - /* update the adapter with the fresh results */ - priv = osif_request_priv(request); - - adapter->rssi = priv->rssi; - - /* - * for new connection there might be no valid previous - * RSSI. - */ - if (!adapter->rssi) { - hdd_get_rssi_snr_by_bssid(adapter, - sta_ctx->conn_info.bssid.bytes, - &adapter->rssi, NULL); - } - } - } - - /* - * either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. - * regardless we are done with the request. - */ - osif_request_put(request); - - *rssi_value = adapter->rssi; - hdd_debug("RSSI = %d", *rssi_value); - - return QDF_STATUS_SUCCESS; -} -#endif /* QCA_SUPPORT_CP_STATS */ struct snr_priv { int8_t snr; @@ -5730,7 +5687,7 @@ struct snr_priv { * * Return: None */ -static void hdd_get_snr_cb(int8_t snr, uint32_t sta_id, void *context) +static void hdd_get_snr_cb(int8_t snr, void *context) { struct osif_request *request; struct snr_priv *priv; @@ -5785,7 +5742,6 @@ QDF_STATUS wlan_hdd_get_snr(struct hdd_adapter *adapter, int8_t *snr) cookie = osif_request_cookie(request); status = sme_get_snr(hdd_ctx->mac_handle, hdd_get_snr_cb, - sta_ctx->conn_info.sta_id[0], sta_ctx->conn_info.bssid, cookie); if (QDF_STATUS_SUCCESS != status) { hdd_err("Unable to retrieve RSSI"); @@ -5942,115 +5898,6 @@ int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed) return 0; } -struct peer_rssi_priv { - struct sir_peer_sta_info peer_sta_info; -}; - -/** - * hdd_get_peer_rssi_cb() - get peer station's rssi callback - * @sta_rssi: pointer of peer information - * @context: get rssi callback context - * - * This function will fill rssi information to rssi priv - * adapter - * - */ -static void hdd_get_peer_rssi_cb(struct sir_peer_info_resp *sta_rssi, - void *context) -{ - struct osif_request *request; - struct peer_rssi_priv *priv; - struct sir_peer_info *rssi_info; - uint8_t peer_num; - - if ((!sta_rssi)) { - hdd_err("Bad param, sta_rssi [%pK]", sta_rssi); - return; - } - - request = osif_request_get(context); - if (!request) { - hdd_err("Obsolete request"); - return; - } - - priv = osif_request_priv(request); - - peer_num = sta_rssi->count; - rssi_info = sta_rssi->info; - - hdd_debug("%d peers", peer_num); - - if (peer_num > MAX_PEER_STA) { - hdd_warn("Exceed max peer sta to handle one time %d", peer_num); - peer_num = MAX_PEER_STA; - } - - qdf_mem_copy(priv->peer_sta_info.info, rssi_info, - peer_num * sizeof(*rssi_info)); - priv->peer_sta_info.sta_num = peer_num; - - osif_request_complete(request); - osif_request_put(request); - -} - -int wlan_hdd_get_peer_rssi(struct hdd_adapter *adapter, - struct qdf_mac_addr *macaddress, - struct sir_peer_sta_info *peer_sta_info) -{ - QDF_STATUS status; - void *cookie; - int ret; - struct sir_peer_info_req rssi_req; - struct osif_request *request; - struct peer_rssi_priv *priv; - static const struct osif_request_params params = { - .priv_size = sizeof(*priv), - .timeout_ms = WLAN_WAIT_TIME_STATS, - }; - - if (!adapter || !macaddress || !peer_sta_info) { - hdd_err("adapter [%pK], macaddress [%pK], peer_sta_info[%pK]", - adapter, macaddress, peer_sta_info); - return -EFAULT; - } - - request = osif_request_alloc(¶ms); - if (!request) { - hdd_err("Request allocation failure"); - return -ENOMEM; - } - - cookie = osif_request_cookie(request); - priv = osif_request_priv(request); - - qdf_mem_copy(&rssi_req.peer_macaddr, macaddress, - QDF_MAC_ADDR_SIZE); - rssi_req.sessionid = adapter->vdev_id; - status = sme_get_peer_info(adapter->hdd_ctx->mac_handle, - rssi_req, - cookie, - hdd_get_peer_rssi_cb); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("Unable to retrieve statistics for rssi"); - ret = -EFAULT; - } else { - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_err("SME timed out while retrieving rssi"); - ret = -EFAULT; - } else { - *peer_sta_info = priv->peer_sta_info; - ret = 0; - } - } - - osif_request_put(request); - - return ret; -} - struct peer_info_priv { struct sir_peer_sta_ext_info peer_sta_ext_info; }; @@ -6162,122 +6009,23 @@ int wlan_hdd_get_peer_info(struct hdd_adapter *adapter, return ret; } -#ifndef QCA_SUPPORT_CP_STATS -struct class_a_stats { - tCsrGlobalClassAStatsInfo class_a_stats; -}; - -/** - * hdd_get_class_a_statistics_cb() - Get Class A stats callback function - * @stats: pointer to Class A stats - * @context: user context originally registered with SME (always the - * cookie from the request context) - * - * Return: None - */ -static void hdd_get_class_a_statistics_cb(void *stats, void *context) -{ - struct osif_request *request; - struct class_a_stats *priv; - tCsrGlobalClassAStatsInfo *returned_stats; - - hdd_enter(); - if (!stats) { - hdd_err("Bad param, stats"); - return; - } - - request = osif_request_get(context); - if (!request) { - hdd_err("Obsolete request"); - return; - } - - returned_stats = stats; - priv = osif_request_priv(request); - priv->class_a_stats = *returned_stats; - osif_request_complete(request); - osif_request_put(request); - hdd_exit(); -} - -QDF_STATUS wlan_hdd_get_class_astats(struct hdd_adapter *adapter) -{ - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - QDF_STATUS status; - int ret; - void *cookie; - struct osif_request *request; - struct class_a_stats *priv; - static const struct osif_request_params params = { - .priv_size = sizeof(*priv), - .timeout_ms = WLAN_WAIT_TIME_STATS, - }; - - if (!adapter) { - hdd_err("adapter is NULL"); - return QDF_STATUS_E_FAULT; - } - if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { - hdd_debug("Recovery in Progress. State: 0x%x Ignore!!!", - cds_get_driver_state()); - return QDF_STATUS_SUCCESS; - } - - request = osif_request_alloc(¶ms); - if (!request) { - hdd_err("Request allocation failure"); - return QDF_STATUS_E_NOMEM; - } - cookie = osif_request_cookie(request); - - /* query only for Class A statistics (which include link speed) */ - status = sme_get_statistics(adapter->hdd_ctx->mac_handle, - eCSR_HDD, SME_GLOBAL_CLASSA_STATS, - hdd_get_class_a_statistics_cb, - sta_ctx->conn_info.sta_id[0], - cookie, adapter->vdev_id); - if (QDF_STATUS_SUCCESS != status) { - hdd_warn("Unable to retrieve Class A statistics"); - goto return_cached_results; - } - - /* request was sent -- wait for the response */ - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_warn("SME timed out while retrieving Class A statistics"); - goto return_cached_results; - } - - /* update the adapter with the fresh results */ - priv = osif_request_priv(request); - adapter->hdd_stats.class_a_stat = priv->class_a_stats; - -return_cached_results: - /* - * either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. - * regardless we are done with the request. - */ - osif_request_put(request); - - return QDF_STATUS_SUCCESS; -} -#endif - -#ifdef QCA_SUPPORT_CP_STATS int wlan_hdd_get_station_stats(struct hdd_adapter *adapter) { int ret = 0; struct stats_event *stats; struct wlan_mlme_nss_chains *dynamic_cfg; uint32_t tx_nss, rx_nss; + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; - stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->vdev, + stats = wlan_cfg80211_mc_cp_stats_get_station_stats(vdev, &ret); if (ret || !stats) { wlan_cfg80211_mc_cp_stats_free_stats_event(stats); - return ret; + goto out; } /* save summary stats to legacy location */ @@ -6318,10 +6066,12 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter) adapter->hdd_stats.peer_stats.fcs_count = stats->peer_adv_stats->fcs_count; - dynamic_cfg = mlme_get_dynamic_vdev_config(adapter->vdev); + dynamic_cfg = mlme_get_dynamic_vdev_config(vdev); if (!dynamic_cfg) { hdd_err("nss chain dynamic config NULL"); - return -EINVAL; + wlan_cfg80211_mc_cp_stats_free_stats_event(stats); + ret = -EINVAL; + goto out; } switch (hdd_conn_get_connected_band(&adapter->session.station)) { @@ -6334,15 +6084,15 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter) rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]; break; default: - tx_nss = wlan_vdev_mlme_get_nss(adapter->vdev); - rx_nss = wlan_vdev_mlme_get_nss(adapter->vdev); + tx_nss = wlan_vdev_mlme_get_nss(vdev); + rx_nss = wlan_vdev_mlme_get_nss(vdev); } /* Intersection of self and AP's NSS capability */ - if (tx_nss > wlan_vdev_mlme_get_nss(adapter->vdev)) - tx_nss = wlan_vdev_mlme_get_nss(adapter->vdev); + if (tx_nss > wlan_vdev_mlme_get_nss(vdev)) + tx_nss = wlan_vdev_mlme_get_nss(vdev); - if (rx_nss > wlan_vdev_mlme_get_nss(adapter->vdev)) - rx_nss = wlan_vdev_mlme_get_nss(adapter->vdev); + if (rx_nss > wlan_vdev_mlme_get_nss(vdev)) + rx_nss = wlan_vdev_mlme_get_nss(vdev); /* save class a stats to legacy location */ adapter->hdd_stats.class_a_stat.tx_nss = tx_nss; @@ -6372,123 +6122,10 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter) sizeof(stats->vdev_chain_rssi[0].chain_rssi)); wlan_cfg80211_mc_cp_stats_free_stats_event(stats); - return 0; -} -#else /* QCA_SUPPORT_CP_STATS */ -struct station_stats { - tCsrSummaryStatsInfo summary_stats; - tCsrGlobalClassAStatsInfo class_a_stats; - struct csr_per_chain_rssi_stats_info per_chain_rssi_stats; -}; - -/** - * hdd_get_station_statistics_cb() - Get stats callback function - * @stats: pointer to combined station stats - * @context: user context originally registered with SME (always the - * cookie from the request context) - * - * Return: None - */ -static void hdd_get_station_statistics_cb(void *stats, void *context) -{ - struct osif_request *request; - struct station_stats *priv; - tCsrSummaryStatsInfo *summary_stats; - tCsrGlobalClassAStatsInfo *class_a_stats; - struct csr_per_chain_rssi_stats_info *per_chain_rssi_stats; - - if ((!stats) || (!context)) { - hdd_err("Bad param, stats [%pK] context [%pK]", - stats, context); - return; - } - - request = osif_request_get(context); - if (!request) { - hdd_err("Obsolete request"); - return; - } - - summary_stats = (tCsrSummaryStatsInfo *) stats; - class_a_stats = (tCsrGlobalClassAStatsInfo *) (summary_stats + 1); - per_chain_rssi_stats = (struct csr_per_chain_rssi_stats_info *) - (class_a_stats + 1); - priv = osif_request_priv(request); - - /* copy over the stats. do so as a struct copy */ - priv->summary_stats = *summary_stats; - priv->class_a_stats = *class_a_stats; - priv->per_chain_rssi_stats = *per_chain_rssi_stats; - - osif_request_complete(request); - osif_request_put(request); -} - -int wlan_hdd_get_station_stats(struct hdd_adapter *adapter) -{ - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - QDF_STATUS status; - int errno; - void *cookie; - struct osif_request *request; - struct station_stats *priv; - static const struct osif_request_params params = { - .priv_size = sizeof(*priv), - .timeout_ms = WLAN_WAIT_TIME_STATS, - }; - - if (!adapter) { - hdd_err("adapter is NULL"); - return 0; - } - - request = osif_request_alloc(¶ms); - if (!request) { - hdd_err("Request allocation failure"); - return -ENOMEM; - } - cookie = osif_request_cookie(request); - - /* query only for Summary & Class A statistics */ - status = sme_get_statistics(adapter->hdd_ctx->mac_handle, - eCSR_HDD, - SME_SUMMARY_STATS | - SME_GLOBAL_CLASSA_STATS | - SME_PER_CHAIN_RSSI_STATS, - hdd_get_station_statistics_cb, - sta_ctx->conn_info.sta_id[0], - cookie, - adapter->vdev_id); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Failed to retrieve statistics, status %d", status); - goto put_request; - } - - /* request was sent -- wait for the response */ - errno = osif_request_wait_for_response(request); - if (errno) { - hdd_err("Failed to wait for statistics, errno %d", errno); - goto put_request; - } - - /* update the adapter with the fresh results */ - priv = osif_request_priv(request); - adapter->hdd_stats.summary_stat = priv->summary_stats; - adapter->hdd_stats.class_a_stat = priv->class_a_stats; - adapter->hdd_stats.per_chain_rssi_stats = priv->per_chain_rssi_stats; - -put_request: - /* - * either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. - * regardless we are done with the request. - */ - osif_request_put(request); - - /* either callback updated adapter stats or it has cached data */ - return 0; +out: + hdd_objmgr_put_vdev(vdev); + return ret; } -#endif /* QCA_SUPPORT_CP_STATS */ struct temperature_priv { int temperature; @@ -6579,13 +6216,15 @@ int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature) void wlan_hdd_display_txrx_stats(struct hdd_context *ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_tx_rx_stats *stats; int i = 0; uint32_t total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused; + wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CACHE_STATION_STATS_CB; - hdd_for_each_adapter_dev_held(ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(ctx, adapter, next_adapter, + dbgid) { total_rx_pkt = 0; total_rx_dropped = 0; total_rx_delv = 0; @@ -6593,7 +6232,7 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx) stats = &adapter->hdd_stats.tx_rx_stats; if (adapter->vdev_id == INVAL_VDEV_ID) { - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); continue; } @@ -6606,7 +6245,7 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx) } /* dev_put has to be done here */ - dev_put(adapter->dev); + hdd_adapter_dev_put_debug(adapter, dbgid); hdd_debug("TX - called %u, dropped %u orphan %u", stats->tx_called, stats->tx_dropped, @@ -6632,6 +6271,7 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx) } } +#ifdef QCA_SUPPORT_CP_STATS /** * hdd_lost_link_cp_stats_info_cb() - callback function to get lost * link information @@ -6662,10 +6302,10 @@ static void hdd_lost_link_cp_stats_info_cb(void *stats_ev) continue; } adapter->rssi_on_disconnect = - ev->vdev_summary_stats[i].stats.rssi; - hdd_debug("rssi %d for " QDF_MAC_ADDR_STR, + ev->vdev_summary_stats[i].stats.rssi; + hdd_debug("rssi %d for " QDF_MAC_ADDR_FMT, adapter->rssi_on_disconnect, - QDF_MAC_ADDR_ARRAY(adapter->mac_addr.bytes)); + QDF_MAC_ADDR_REF(adapter->mac_addr.bytes)); } } @@ -6675,28 +6315,28 @@ void wlan_hdd_register_cp_stats_cb(struct hdd_context *hdd_ctx) hdd_ctx->psoc, hdd_lost_link_cp_stats_info_cb); } +#endif QDF_STATUS hdd_update_sta_arp_stats(struct hdd_adapter *adapter) { - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_peer *peer; - uint8_t peer_id; struct cdp_peer_stats *peer_stats; struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); struct hdd_arp_stats_s *arp_stats; + QDF_STATUS status; - peer = cdp_peer_find_by_addr(cds_get_context(QDF_MODULE_ID_SOC), - txrx_pdev, sta_ctx->conn_info.bssid.bytes, - &peer_id); - - if (!peer) - return QDF_STATUS_E_FAILURE; + peer_stats = qdf_mem_malloc(sizeof(*peer_stats)); + if (!peer_stats) + return QDF_STATUS_E_NOMEM; - peer_stats = cdp_host_get_peer_stats(cds_get_context(QDF_MODULE_ID_SOC), - peer); + status = cdp_host_get_peer_stats(cds_get_context(QDF_MODULE_ID_SOC), + adapter->vdev_id, + sta_ctx->conn_info.bssid.bytes, + peer_stats); - if (!peer_stats) - return QDF_STATUS_E_FAILURE; + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(peer_stats); + return status; + } arp_stats = &adapter->hdd_stats.hdd_arp_stats; @@ -6704,6 +6344,7 @@ QDF_STATUS hdd_update_sta_arp_stats(struct hdd_adapter *adapter) arp_stats->tx_arp_req_count - arp_stats->tx_dropped; arp_stats->tx_ack_cnt = arp_stats->tx_host_fw_sent - peer_stats->tx.no_ack_count[QDF_PROTO_ARP_REQ]; + qdf_mem_free(peer_stats); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.h index ab42db9991d04a5d8a1ae9cd72b4c14c6b74b7e1..7e60de61acaf8cc5d8939af00928f9614b3351a9 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_stats.h @@ -352,6 +352,16 @@ int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, uint8_t *mac, int32_t *rcpi_value, enum rcpi_measurement_type measurement_type); +#ifdef WLAN_FEATURE_MIB_STATS +/** + * wlan_hdd_get_mib_stats() - Get the mib statistics + * @adapter: adapter upon which the measurement is requested + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS wlan_hdd_get_mib_stats(struct hdd_adapter *adapter); +#endif + /** * wlan_hdd_get_rssi() - Get the current RSSI * @adapter: adapter upon which the measurement is requested @@ -398,20 +408,6 @@ int wlan_hdd_get_linkspeed_for_peermac(struct hdd_adapter *adapter, */ int wlan_hdd_get_link_speed(struct hdd_adapter *adapter, uint32_t *link_speed); -/** - * wlan_hdd_get_peer_rssi() - get station's rssi - * @adapter: hostapd interface - * @macaddress: peer sta mac address or ff:ff:ff:ff:ff:ff to query all peer - * @peer_sta_info: output pointer which will fill by peer sta info - * - * This function will call sme_get_peer_info to get rssi - * - * Return: 0 on success, otherwise error value - */ -int wlan_hdd_get_peer_rssi(struct hdd_adapter *adapter, - struct qdf_mac_addr *macaddress, - struct sir_peer_sta_info *peer_sta_info); - /** * wlan_hdd_get_peer_info() - get peer info * @adapter: hostapd interface @@ -425,17 +421,6 @@ int wlan_hdd_get_peer_rssi(struct hdd_adapter *adapter, int wlan_hdd_get_peer_info(struct hdd_adapter *adapter, struct qdf_mac_addr macaddress, struct sir_peer_info_ext *peer_info_ext); - -#ifndef QCA_SUPPORT_CP_STATS -/** - * wlan_hdd_get_class_astats() - Get Class A statistics - * @adapter: adapter for which statistics are desired - * - * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated - */ -QDF_STATUS wlan_hdd_get_class_astats(struct hdd_adapter *adapter); -#endif - /** * wlan_hdd_get_station_stats() - Get station statistics * @adapter: adapter for which statistics are desired @@ -486,6 +471,21 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, uint8_t mcs_index, uint16_t fw_rate, uint8_t nss); +/** + * hdd_check_and_update_nss() - Check and update NSS as per DBS capability + * @hdd_ctx: HDD Context pointer + * @tx_nss: pointer to variable storing the tx_nss + * @rx_nss: pointer to variable storing the rx_nss + * + * The parameters include the NSS obtained from the FW or static NSS. This NSS + * could be invalid in the case the current HW mode is DBS where the connection + * are 1x1. Rectify these NSS values as per the current HW mode. + * + * Return: none + */ +void hdd_check_and_update_nss(struct hdd_context *hdd_ctx, + uint8_t *tx_nss, uint8_t *rx_nss); +#ifdef QCA_SUPPORT_CP_STATS /** * wlan_hdd_register_cp_stats_cb() - Register hdd stats specific * callbacks to the cp stats component @@ -495,6 +495,9 @@ bool hdd_report_max_rate(mac_handle_t mac_handle, */ void wlan_hdd_register_cp_stats_cb(struct hdd_context *hdd_ctx); +#else +static inline void wlan_hdd_register_cp_stats_cb(struct hdd_context *hdd_ctx) {} +#endif /** * hdd_update_sta_arp_stats() - update arp stats diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_subnet_detect.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_subnet_detect.c index 995c36114217a2b088f32e7178c1b81b3bf656a1..fb2ae30cfdcb70b53e45f18db5f7b698506fbaa9 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_subnet_detect.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_subnet_detect.c @@ -151,8 +151,8 @@ static int __wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy, req.vdev_id = adapter->vdev_id; hdd_debug("Configuring gateway for session %d", req.vdev_id); - hdd_debug("mac:%pM, ipv4:%pI4 (type %d), ipv6:%pI6c (type %d)", - req.gw_mac_addr.bytes, + hdd_debug("mac:"QDF_MAC_ADDR_FMT", ipv4:%pI4 (type %d), ipv6:%pI6c (type %d)", + QDF_MAC_ADDR_REF(req.gw_mac_addr.bytes), req.ipv4_addr, req.ipv4_addr_type, req.ipv6_addr, req.ipv6_addr_type); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sysfs.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sysfs.c index c2a72a9282ab3b1b6d92ca232e50e73ce427f789..2c0d4ea8da419bf017a67da6d2300ba6b1a1c4f1 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sysfs.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_sysfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -37,6 +37,9 @@ #include #endif #include "osif_sync.h" +#if defined(WLAN_SUPPORT_RX_FISA) +#include "dp_fisa_rx.h" +#endif #define MAX_PSOC_ID_SIZE 10 @@ -51,6 +54,19 @@ static struct kobject *driver_kobject; static struct kobject *fw_kobject; static struct kobject *psoc_kobject; +#if defined(WLAN_SUPPORT_RX_FISA) +static inline +void hdd_rx_skip_fisa(ol_txrx_soc_handle dp_soc, uint32_t value) +{ + dp_rx_skip_fisa(dp_soc, value); +} +#else +static inline +void hdd_rx_skip_fisa(ol_txrx_soc_handle dp_soc, uint32_t value) +{ +} +#endif + static ssize_t __show_driver_version(char *buf) { return scnprintf(buf, PAGE_SIZE, QWLAN_VERSIONSTR); @@ -216,6 +232,7 @@ static ssize_t __show_device_power_stats(struct hdd_context *hdd_ctx, ret_cnt = osif_request_wait_for_response(request); if (ret_cnt) { hdd_err("Target response timed out Power stats"); + sme_reset_power_debug_stats_cb(hdd_ctx->mac_handle); ret_cnt = -ETIMEDOUT; goto cleanup; } @@ -499,6 +516,162 @@ void hdd_sysfs_destroy_version_interface(void) } } +int +hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size, + char const *source_buf, size_t source_buf_size) +{ + if (source_buf_size > (dest_buf_size - 1)) { + hdd_err_rl("Command length is larger than %zu bytes", + dest_buf_size); + return -EINVAL; + } + + /* sysfs already provides kernel space buffer so copy from user + * is not needed. Doing this extra copy operation just to ensure + * the local buf is properly null-terminated. + */ + strlcpy(dest_buf, source_buf, dest_buf_size); + /* default 'echo' cmd takes new line character to here */ + if (dest_buf[source_buf_size - 1] == '\n') + dest_buf[source_buf_size - 1] = '\0'; + + return 0; +} + +static ssize_t +__hdd_sysfs_dp_aggregation_show(struct hdd_context *hdd_ctx, + struct kobj_attribute *attr, char *buf) +{ + if (!wlan_hdd_validate_modules_state(hdd_ctx)) + return -EINVAL; + + hdd_debug("dp_aggregation: %d", + qdf_atomic_read(&hdd_ctx->dp_agg_param.rx_aggregation)); + + return 0; +} + +static ssize_t hdd_sysfs_dp_aggregation_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + ssize_t errno_size; + int ret; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return ret; + + errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), + &psoc_sync); + if (errno_size) + return errno_size; + + errno_size = __hdd_sysfs_dp_aggregation_show(hdd_ctx, attr, buf); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno_size; +} + +static ssize_t +__hdd_sysfs_dp_aggregation_store(struct hdd_context *hdd_ctx, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1]; + char *sptr, *token; + uint32_t value; + int ret; + ol_txrx_soc_handle dp_soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (!wlan_hdd_validate_modules_state(hdd_ctx) || !dp_soc) + return -EINVAL; + + ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local), + buf, count); + + if (ret) { + hdd_err_rl("invalid input"); + return ret; + } + + sptr = buf_local; + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou32(token, 0, &value)) + return -EINVAL; + + hdd_debug("dp_aggregation: %d", value); + + hdd_rx_skip_fisa(dp_soc, value); + qdf_atomic_set(&hdd_ctx->dp_agg_param.rx_aggregation, !!value); + + return count; +} + +static ssize_t +hdd_sysfs_dp_aggregation_store(struct kobject *kobj, + struct kobj_attribute *attr, + char const *buf, size_t count) +{ + struct osif_psoc_sync *psoc_sync; + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + ssize_t errno_size; + int ret; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) + return ret; + + errno_size = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), + &psoc_sync); + if (errno_size) + return errno_size; + + errno_size = __hdd_sysfs_dp_aggregation_store(hdd_ctx, attr, + buf, count); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno_size; +} + +static struct kobj_attribute dp_aggregation_attribute = + __ATTR(dp_aggregation, 0664, hdd_sysfs_dp_aggregation_show, + hdd_sysfs_dp_aggregation_store); + +int hdd_sysfs_dp_aggregation_create(void) +{ + int error; + + if (!driver_kobject) { + hdd_err("could not get driver kobject!"); + return -EINVAL; + } + + error = sysfs_create_file(driver_kobject, + &dp_aggregation_attribute.attr); + if (error) + hdd_err("could not create dp_aggregation sysfs file"); + + return error; +} + +void +hdd_sysfs_dp_aggregation_destroy(void) +{ + if (!driver_kobject) { + hdd_err("could not get driver kobject!"); + return; + } + + sysfs_remove_file(driver_kobject, &dp_aggregation_attribute.attr); +} + #ifdef WLAN_POWER_DEBUG void hdd_sysfs_create_powerstats_interface(void) { @@ -522,6 +695,7 @@ void hdd_sysfs_destroy_powerstats_interface(void) } sysfs_remove_file(driver_kobject, &power_stats_attribute.attr); } +#endif void hdd_sysfs_create_driver_root_obj(void) { @@ -551,7 +725,6 @@ void hdd_sysfs_destroy_driver_root_obj(void) driver_kobject = NULL; } } -#endif #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS static int hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tdls.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tdls.c index 7045a081bb88fe28cef490d1470f7e6a2644ca6b..f4341236e486fd8628479c4cdcac10190b776874 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tdls.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tdls.c @@ -848,8 +848,7 @@ int wlan_hdd_tdls_antenna_switch(struct hdd_context *hdd_ctx, } QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id, - const uint8_t *mac, uint16_t sta_id, - uint8_t qos) + const uint8_t *mac, uint8_t qos) { struct hdd_adapter *adapter; struct hdd_context *hddctx; @@ -865,27 +864,7 @@ QDF_STATUS hdd_tdls_register_peer(void *userdata, uint32_t vdev_id, return QDF_STATUS_E_FAILURE; } - return hdd_roam_register_tdlssta(adapter, mac, sta_id, qos); -} - -QDF_STATUS hdd_tdls_deregister_peer(void *userdata, uint32_t vdev_id, - uint8_t sta_id) -{ - struct hdd_adapter *adapter; - struct hdd_context *hddctx; - - hddctx = userdata; - if (!hddctx) { - hdd_err("Invalid hddctx"); - return QDF_STATUS_E_INVAL; - } - adapter = hdd_get_adapter_by_vdev(hddctx, vdev_id); - if (!adapter) { - hdd_err("Invalid adapter"); - return QDF_STATUS_E_FAILURE; - } - - return hdd_roam_deregister_tdlssta(adapter, sta_id); + return hdd_roam_register_tdlssta(adapter, mac, qos); } void hdd_init_tdls_config(struct tdls_start_params *tdls_cfg) @@ -900,7 +879,7 @@ void hdd_config_tdls_with_band_switch(struct hdd_context *hdd_ctx) { struct wlan_objmgr_vdev *tdls_obj_vdev; int offchmode; - enum band_info current_band; + uint32_t current_band; bool tdls_off_ch; if (!hdd_ctx) { @@ -908,7 +887,7 @@ void hdd_config_tdls_with_band_switch(struct hdd_context *hdd_ctx) return; } - if (ucfg_reg_get_curr_band(hdd_ctx->pdev, ¤t_band) != + if (ucfg_reg_get_band(hdd_ctx->pdev, ¤t_band) != QDF_STATUS_SUCCESS) { hdd_err("Failed to get current band config"); return; @@ -923,7 +902,8 @@ void hdd_config_tdls_with_band_switch(struct hdd_context *hdd_ctx) * If 2g or 5g is not supported. Disable tdls off channel only when * tdls off channel is enabled currently. */ - if (current_band == BAND_ALL) { + if ((current_band & BIT(REG_BAND_2G)) && + (current_band & BIT(REG_BAND_5G))) { if (cfg_tdls_get_off_channel_enable_orig( hdd_ctx->psoc, &tdls_off_ch) != QDF_STATUS_SUCCESS) { diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_thermal.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_thermal.c index 37ad8ea44e5f4ffe0df7d96c1f959100e40a9ffb..46cf12f00d23f5a2c27ce2eaaa2f0d9a5b6d24c2 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_thermal.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_thermal.c @@ -210,7 +210,7 @@ QDF_STATUS hdd_restore_thermal_mitigation_config(struct hdd_context *hdd_ctx) dc_off_percent = hdd_ctx->dutycycle_off_percent; dc = thermal_temp.thermal_sampling_time; - if (!dc_off_percent) + if(!dc_off_percent) enable = false; hdd_debug("dc %d dc_off_per %d enable %d", dc, dc_off_percent, enable); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_trace.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_trace.c index a71759546b78579b8a63e3c4d6f4de0f7c1aa0f0..39b8377d9b831fd3c68615e43d87cdcfd7bf5fc5 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_trace.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_trace.c @@ -46,13 +46,13 @@ hdd_trace_dump(void *mac, tp_qdf_trace_record record, uint16_t index) index, record->qtime, record->time, record->session, "RX SME MSG:", get_e_roam_cmd_status_str(record->data), - record->data); + record->data); else hdd_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", index, record->qtime, record->time, record->session, "HDD Event:", hdd_trace_event_string(record->code), - record->data); + record->data); } /** diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tsf.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tsf.c index 0f8b79b6540fcfb39102ff356391f05f59085077..d5de120c740ab9754cca7db165afde083601997a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tsf.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tsf.c @@ -27,17 +27,31 @@ #include "wlan_fwol_ucfg_api.h" #include #include -#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ +#if defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ) || \ + defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) #include -static int tsf_gpio_irq_num = -1; #endif + #include "ol_txrx_api.h" +#ifdef WLAN_FEATURE_TSF_PLUS +#ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ +#ifndef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +static int tsf_gpio_irq_num = -1; +#endif +#endif +#endif static struct completion tsf_sync_get_completion_evt; #define WLAN_TSF_SYNC_GET_TIMEOUT 2000 #define WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS 500 #define WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS 100 -#define WLAN_HDD_SOFTAP_INTERVEL_TIMES 100 +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +#define WLAN_HDD_SOFTAP_INTERVAL_TIMES 1 +#else +#define WLAN_HDD_SOFTAP_INTERVAL_TIMES 100 +#endif +#define OUTPUT_HIGH 1 +#define OUTPUT_LOW 0 #ifdef WLAN_FEATURE_TSF_PLUS #ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ @@ -61,8 +75,11 @@ enum hdd_tsf_op_result { }; #ifdef WLAN_FEATURE_TSF_PLUS +#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC +#define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 1 +#else #define WLAN_HDD_CAPTURE_TSF_RESYNC_INTERVAL 9 - +#endif static inline void hdd_set_th_sync_status(struct hdd_adapter *adapter, bool initialized) { @@ -130,7 +147,10 @@ static bool hdd_tsf_is_initialized(struct hdd_adapter *adapter) return true; } -#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && defined(WLAN_FEATURE_TSF_PLUS) +#if (defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) && \ + defined(WLAN_FEATURE_TSF_PLUS)) || \ + defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) || \ + defined(WLAN_FEATURE_TSF_TIMER_SYNC) /** * hdd_tsf_reset_gpio() - Reset TSF GPIO used for host timer sync * @adapter: pointer to adapter @@ -207,7 +227,7 @@ static QDF_STATUS hdd_tsf_set_gpio(struct hdd_context *hdd_ctx) #endif #ifdef WLAN_FEATURE_TSF_PLUS -bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd) +static bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd) { uint32_t tsf_ptp_options; @@ -272,6 +292,181 @@ bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd) else return false; } +#else + +static bool hdd_tsf_is_ptp_enabled(struct hdd_context *hdd) +{ + return false; +} +#endif + +#ifdef WLAN_FEATURE_TSF_PLUS +static inline +uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx) +{ + return hdd_tsf_is_raw_set(hdd_ctx) ? + ktime_get_ns() : ktime_get_real_ns(); +} +#endif + +#if defined(WLAN_FEATURE_TSF_PLUS) && \ + defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) +#define MAX_CONTINUOUS_RETRY_CNT 10 +static uint32_t +hdd_wlan_retry_tsf_cap(struct hdd_adapter *adapter) +{ + struct hdd_context *hddctx; + int count = adapter->continuous_cap_retry_count; + + hddctx = WLAN_HDD_GET_CTX(adapter); + if (count == MAX_CONTINUOUS_RETRY_CNT) { + hdd_debug("Max retry countr reached"); + return 0; + } + qdf_atomic_set(&hddctx->cap_tsf_flag, 0); + count++; + adapter->continuous_cap_retry_count = count; + return (count * WLAN_HDD_CAPTURE_TSF_REQ_TIMEOUT_MS); +} + +static void +hdd_wlan_restart_tsf_cap(struct hdd_adapter *adapter) +{ + struct hdd_context *hddctx; + int count = adapter->continuous_cap_retry_count; + + hddctx = WLAN_HDD_GET_CTX(adapter); + if (count == MAX_CONTINUOUS_RETRY_CNT) { + hdd_debug("Restart TSF CAP"); + qdf_atomic_set(&hddctx->cap_tsf_flag, 0); + adapter->continuous_cap_retry_count = 0; + qdf_mc_timer_start(&adapter->host_target_sync_timer, + WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS); + } +} + +static void +hdd_update_host_time(struct hdd_adapter *adapter) +{ + struct hdd_context *hdd_ctx; + u64 host_time; + char *name = NULL; + + hdd_ctx = adapter->hdd_ctx; + + if (!hdd_tsf_is_initialized(adapter)) { + hdd_err("tsf is not init, exit"); + return; + } + + host_time = hdd_get_monotonic_host_time(hdd_ctx); + hdd_update_timestamp(adapter, 0, host_time); + name = adapter->dev->name; + + hdd_debug("iface: %s - host_time: %llu", + (!name ? "none" : name), host_time); +} + +static +void hdd_tsf_ext_gpio_sync_work(void *data) +{ + QDF_STATUS status; + struct hdd_adapter *adapter; + struct hdd_context *hdd_ctx; + uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID; + + adapter = data; + hdd_ctx = adapter->hdd_ctx; + status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc, + &tsf_sync_gpio_pin); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("tsf sync gpio host pin error"); + return; + } + gpio_set_value(tsf_sync_gpio_pin, OUTPUT_HIGH); + hdd_update_host_time(adapter); + usleep_range(50, 100); + gpio_set_value(tsf_sync_gpio_pin, OUTPUT_LOW); + + status = wma_cli_set_command((int)adapter->vdev_id, + (int)GEN_PARAM_CAPTURE_TSF, + adapter->vdev_id, GEN_CMD); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("cap tsf fail"); + qdf_mc_timer_stop(&adapter->host_capture_req_timer); + qdf_mc_timer_destroy(&adapter->host_capture_req_timer); + } +} + +static void +hdd_tsf_gpio_sync_work_init(struct hdd_adapter *adapter) +{ + qdf_create_work(0, &adapter->gpio_tsf_sync_work, + hdd_tsf_ext_gpio_sync_work, adapter); +} + +static void +hdd_tsf_gpio_sync_work_deinit(struct hdd_adapter *adapter) +{ + qdf_destroy_work(0, &adapter->gpio_tsf_sync_work); +} + +static void +hdd_tsf_stop_ext_gpio_sync(struct hdd_adapter *adapter) +{ + qdf_cancel_work(&adapter->gpio_tsf_sync_work); +} + +static void +hdd_tsf_start_ext_gpio_sync(struct hdd_adapter *adapter) +{ + qdf_sched_work(0, &adapter->gpio_tsf_sync_work); +} + +static bool hdd_tsf_cap_sync_send(struct hdd_adapter *adapter) +{ + hdd_tsf_start_ext_gpio_sync(adapter); + return true; +} +#elif defined(WLAN_FEATURE_TSF_PLUS) && \ + !defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) +static void +hdd_wlan_restart_tsf_cap(struct hdd_adapter *adapter) +{ +} + +static void +hdd_tsf_gpio_sync_work_init(struct hdd_adapter *adapter) +{ +} + +static void +hdd_tsf_gpio_sync_work_deinit(struct hdd_adapter *adapter) +{ +} + +static void +hdd_tsf_stop_ext_gpio_sync(struct hdd_adapter *adapter) +{ +} + +static void +hdd_tsf_start_ext_gpio_sync(struct hdd_adapter *adapter) +{ +} + +static bool +hdd_tsf_cap_sync_send(struct hdd_adapter *adapter) +{ + hdd_tsf_start_ext_gpio_sync(adapter); + return false; +} + +#else +static bool hdd_tsf_cap_sync_send(struct hdd_adapter *adapter) +{ + return false; +} #endif static enum hdd_tsf_op_result hdd_capture_tsf_internal( @@ -325,6 +520,10 @@ static enum hdd_tsf_op_result hdd_capture_tsf_internal( buf[0] = TSF_RETURN; init_completion(&tsf_sync_get_completion_evt); + + if (hdd_tsf_cap_sync_send(adapter)) + return HDD_TSF_OP_SUCC; + ret = wma_cli_set_command((int)adapter->vdev_id, (int)GEN_PARAM_CAPTURE_TSF, adapter->vdev_id, GEN_CMD); @@ -414,10 +613,11 @@ static enum hdd_tsf_op_result hdd_indicate_tsf_internal( /* to distinguish 32-bit overflow case, this inverval should: * equal or less than (1/2 * OVERFLOW_INDICATOR32 us) */ -#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ +#if defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ) || \ + defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) #define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 2 #else -#define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 10 +#define WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC 4 #endif #define OVERFLOW_INDICATOR32 (((int64_t)0x1) << 32) #define CAP_TSF_TIMER_FIX_SEC 1 @@ -446,6 +646,7 @@ enum hdd_tsf_op_result __hdd_start_tsf_sync(struct hdd_adapter *adapter) return HDD_TSF_OP_FAIL; } + hdd_tsf_gpio_sync_work_init(adapter); ret = qdf_mc_timer_start(&adapter->host_target_sync_timer, WLAN_HDD_CAPTURE_TSF_INIT_INTERVAL_MS); if (ret != QDF_STATUS_SUCCESS && ret != QDF_STATUS_E_ALREADY) { @@ -470,6 +671,8 @@ enum hdd_tsf_op_result __hdd_stop_tsf_sync(struct hdd_adapter *adapter) hdd_err("Failed to stop timer, ret: %d", ret); return HDD_TSF_OP_FAIL; } + hdd_tsf_stop_ext_gpio_sync(adapter); + hdd_tsf_gpio_sync_work_deinit(adapter); return HDD_TSF_OP_SUCC; } @@ -618,6 +821,7 @@ static inline int32_t hdd_get_hosttime_from_targettime( if (in_cap_state) qdf_spin_lock_bh(&adapter->host_target_sync_lock); + hdd_wlan_restart_tsf_cap(adapter); /* at present, target_time is only 32bit in fact */ delta32_target = (int64_t)((target_time & U32_MAX) - (adapter->last_target_time & U32_MAX)); @@ -709,33 +913,30 @@ static inline int32_t hdd_get_soctime_from_tsf64time( qdf_spin_lock_bh(&adapter->host_target_sync_lock); /* at present, target_time is 64bit (g_tsf64), us*/ - if (tsf64_time > adapter->last_target_global_tsf_time) + if (tsf64_time > adapter->last_target_global_tsf_time) { delta64_tsf64time = tsf64_time - - adapter->last_target_global_tsf_time; - else { - if (in_cap_state) - qdf_spin_unlock_bh(&adapter->host_target_sync_lock); - return -EINVAL; - } + adapter->last_target_global_tsf_time; + delta64_soctime = delta64_tsf64time * NSEC_PER_USEC; - delta64_soctime = delta64_tsf64time * NSEC_PER_USEC; + /* soc_time (ns)*/ + ret = hdd_uint64_plus(adapter->last_tsf_sync_soc_time, + delta64_soctime, soc_time); + } else { + delta64_tsf64time = adapter->last_target_global_tsf_time - + tsf64_time; + delta64_soctime = delta64_tsf64time * NSEC_PER_USEC; + + /* soc_time (ns)*/ + ret = hdd_uint64_minus(adapter->last_tsf_sync_soc_time, + delta64_soctime, soc_time); + } - /* soc_time (ns)*/ - ret = hdd_uint64_plus(adapter->last_tsf_sync_soc_time, - delta64_soctime, soc_time); if (in_cap_state) qdf_spin_unlock_bh(&adapter->host_target_sync_lock); return ret; } -static inline -uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx) -{ - return hdd_tsf_is_raw_set(hdd_ctx) ? - ktime_get_ns() : ktime_get_real_ns(); -} - static void hdd_capture_tsf_timer_expired_handler(void *arg) { uint32_t tsf_op_resp; @@ -749,6 +950,7 @@ static void hdd_capture_tsf_timer_expired_handler(void *arg) } #ifndef WLAN_FEATURE_TSF_PLUS_NOIRQ +#ifndef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) { struct hdd_adapter *adapter; @@ -784,6 +986,7 @@ static irqreturn_t hdd_tsf_captured_irq_handler(int irq, void *arg) return IRQ_HANDLED; } #endif +#endif void hdd_capture_req_timer_expired_handler(void *arg) { @@ -902,12 +1105,9 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter) */ interval = (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC - CAP_TSF_TIMER_FIX_SEC) * MSEC_PER_SEC; - if (adapter->device_mode == QDF_SAP_MODE || - adapter->device_mode == QDF_P2P_GO_MODE) { - interval *= WLAN_HDD_SOFTAP_INTERVEL_TIMES; - } adapter->continuous_error_count = 0; + adapter->continuous_cap_retry_count = 0; hdd_debug("ts-pair updated: interval: %d", interval); break; @@ -928,7 +1128,7 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, struct hdd_station_ctx *hdd_sta_ctx; struct hdd_adapter *adapter; struct hdd_context *hdd_ctx; - uint64_t tsf_sync_qtime; + uint64_t tsf_sync_qtime, host_time, reg_qtime, qtime; ssize_t size; struct net_device *net_dev = container_of(dev, struct net_device, dev); @@ -955,17 +1155,25 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, tsf_sync_qtime = adapter->last_tsf_sync_soc_time; do_div(tsf_sync_qtime, NSEC_PER_USEC); + reg_qtime = qdf_get_log_timestamp(); + host_time = hdd_get_monotonic_host_time(hdd_ctx); + + qtime = qdf_log_timestamp_to_usecs(reg_qtime); + do_div(host_time, NSEC_PER_USEC); + if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) { - size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", + size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu "QDF_FULL_MAC_FMT" %llu %llu\n", buf, adapter->last_target_time, tsf_sync_qtime, - hdd_sta_ctx->conn_info.bssid.bytes); + QDF_FULL_MAC_REF(hdd_sta_ctx->conn_info.bssid.bytes), + qtime, host_time); } else { - size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", + size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu "QDF_FULL_MAC_FMT" %llu %llu\n", buf, adapter->last_target_time, tsf_sync_qtime, - adapter->mac_addr.bytes); + QDF_FULL_MAC_REF(adapter->mac_addr.bytes), + qtime, host_time); } return size; @@ -1050,16 +1258,20 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter, CAP_TSF_TIMER_FIX_SEC) * MSEC_PER_SEC; if (adapter->device_mode == QDF_SAP_MODE || adapter->device_mode == QDF_P2P_GO_MODE) { - interval *= WLAN_HDD_SOFTAP_INTERVEL_TIMES; + interval *= WLAN_HDD_SOFTAP_INTERVAL_TIMES; } adapter->continuous_error_count = 0; + adapter->continuous_cap_retry_count = 0; hdd_debug("ts-pair updated: interval: %d", interval); break; case HDD_TS_STATUS_WAITING: interval = 0; hdd_warn("TS status is waiting due to one or more pair not updated"); + + if (!target_time && !host_time) + interval = hdd_wlan_retry_tsf_cap(adapter); break; } qdf_spin_unlock_bh(&adapter->host_target_sync_lock); @@ -1105,13 +1317,13 @@ static ssize_t __hdd_wlan_tsf_show(struct device *dev, } else { if (adapter->device_mode == QDF_STA_MODE || adapter->device_mode == QDF_P2P_CLIENT_MODE) { - size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", + size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu "QDF_FULL_MAC_FMT"\n", buf, target_time, host_time, - hdd_sta_ctx->conn_info.bssid.bytes); + QDF_FULL_MAC_REF(hdd_sta_ctx->conn_info.bssid.bytes)); } else { - size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n", + size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu "QDF_FULL_MAC_FMT"\n", buf, target_time, host_time, - adapter->mac_addr.bytes); + QDF_FULL_MAC_REF(adapter->mac_addr.bytes)); } } @@ -1273,6 +1485,7 @@ enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf, { struct hdd_adapter *adapter; struct net_device *net_dev = netbuf->dev; + struct skb_shared_hwtstamps hwtstamps; if (!net_dev) return HDD_TSF_OP_FAIL; @@ -1285,7 +1498,9 @@ enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf, int32_t ret = hdd_get_soctime_from_tsf64time(adapter, tsf64_time, &soc_time); if (!ret) { - netbuf->tstamp = soc_time; + hwtstamps.hwtstamp = soc_time; + *skb_hwtstamps(netbuf) = hwtstamps; + netbuf->tstamp = ktime_set(0, 0); return HDD_TSF_OP_SUCC; } } @@ -1337,7 +1552,7 @@ int hdd_tx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time) if (!sk) return -EINVAL; - if ((skb_shinfo(netbuf)->tx_flags & SKBTX_SW_TSTAMP) && + if ((skb_shinfo(netbuf)->tx_flags & SKBTX_HW_TSTAMP) && !(skb_shinfo(netbuf)->tx_flags & SKBTX_IN_PROGRESS)) { struct sock_exterr_skb *serr; qdf_nbuf_t new_netbuf; @@ -1374,7 +1589,7 @@ int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time) return 0; /* reset tstamp when failed */ - netbuf->tstamp = ns_to_ktime(0); + netbuf->tstamp = ktime_set(0, 0); return -EINVAL; } @@ -1412,14 +1627,10 @@ static inline int __hdd_indicate_tsf(struct hdd_adapter *adapter, return 0; } -#ifdef WLAN_FEATURE_TSF_PLUS_NOIRQ +#if defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) static inline enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) { - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) { - hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini"); - return HDD_TSF_OP_FAIL; - } if (hdd_tsf_is_tx_set(hdd_ctx)) ol_register_timestamp_callback(hdd_tx_timestamp); @@ -1434,9 +1645,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) qdf_mc_timer_t *cap_timer; struct hdd_adapter *adapter, *adapternode_ptr, *next_ptr; - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) - return HDD_TSF_OP_SUCC; - if (hdd_tsf_is_tx_set(hdd_ctx)) ol_deregister_timestamp_callback(); @@ -1464,20 +1672,79 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) return HDD_TSF_OP_SUCC; } -#else -#ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ + +#elif defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC) static enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) { int ret; QDF_STATUS status; - uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID; + uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID; - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) { - hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini"); + status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc, + &tsf_sync_gpio_pin); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("tsf gpio irq host pin error"); + goto fail; + } + + if (tsf_sync_gpio_pin == TSF_GPIO_PIN_INVALID) { + hdd_err("gpio host pin is invalid"); + goto fail; + } + + ret = gpio_request(tsf_sync_gpio_pin, "wlan_tsf"); + if (ret) { + hdd_err("gpio host pin is invalid"); goto fail; } + ret = gpio_direction_output(tsf_sync_gpio_pin, OUTPUT_LOW); + if (ret) { + hdd_err("gpio host pin is invalid"); + goto fail_free_gpio; + } + + if (hdd_tsf_is_tx_set(hdd_ctx)) + ol_register_timestamp_callback(hdd_tx_timestamp); + + return HDD_TSF_OP_SUCC; + +fail_free_gpio: + gpio_free(tsf_sync_gpio_pin); +fail: + return HDD_TSF_OP_FAIL; +} + +static +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) +{ + QDF_STATUS status; + uint32_t tsf_sync_gpio_pin = TSF_GPIO_PIN_INVALID; + + status = ucfg_fwol_get_tsf_sync_host_gpio_pin(hdd_ctx->psoc, + &tsf_sync_gpio_pin); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_INVAL; + + if (tsf_sync_gpio_pin == TSF_GPIO_PIN_INVALID) + return QDF_STATUS_E_INVAL; + + if (hdd_tsf_is_tx_set(hdd_ctx)) + ol_deregister_timestamp_callback(); + + gpio_free(tsf_sync_gpio_pin); + return HDD_TSF_OP_SUCC; +} + +#elif defined(WLAN_FEATURE_TSF_PLUS_EXT_GPIO_IRQ) +static +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) +{ + int ret; + QDF_STATUS status; + uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID; + status = ucfg_fwol_get_tsf_irq_host_gpio_pin(hdd_ctx->psoc, &tsf_irq_gpio_pin); if (QDF_IS_STATUS_ERROR(status)) { @@ -1535,9 +1802,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) QDF_STATUS status; uint32_t tsf_irq_gpio_pin = TSF_GPIO_PIN_INVALID; - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) - return HDD_TSF_OP_SUCC; - status = ucfg_fwol_get_tsf_irq_host_gpio_pin(hdd_ctx->psoc, &tsf_irq_gpio_pin); if (QDF_IS_STATUS_ERROR(status)) @@ -1557,17 +1821,25 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) return HDD_TSF_OP_SUCC; } + +#elif defined(WLAN_FEATURE_TSF_TIMER_SYNC) +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) +{ + return HDD_TSF_OP_SUCC; +} + +static inline +enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) +{ + return HDD_TSF_OP_SUCC; +} #else static inline enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(struct hdd_context *hdd_ctx) { int ret; - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) { - hdd_info("To enable TSF_PLUS, set gtsf_ptp_options in ini"); - return HDD_TSF_OP_FAIL; - } - ret = cnss_common_register_tsf_captured_handler( hdd_ctx->parent_dev, hdd_tsf_captured_irq_handler, @@ -1587,9 +1859,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) { int ret; - if (!hdd_tsf_is_ptp_enabled(hdd_ctx)) - return HDD_TSF_OP_SUCC; - if (hdd_tsf_is_tx_set(hdd_ctx)) ol_deregister_timestamp_callback(); @@ -1606,7 +1875,6 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(struct hdd_context *hdd_ctx) } #endif -#endif void hdd_tsf_notify_wlan_state_change(struct hdd_adapter *adapter, eConnectionState old_state, eConnectionState new_state) @@ -2107,7 +2375,8 @@ void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx) if (wlan_hdd_tsf_plus_init(hdd_ctx) != HDD_TSF_OP_SUCC) goto fail; - wlan_hdd_phc_init(hdd_ctx); + if (hdd_tsf_is_ptp_enabled(hdd_ctx)) + wlan_hdd_phc_init(hdd_ctx); return; @@ -2123,7 +2392,8 @@ void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx) if (!qdf_atomic_read(&hdd_ctx->tsf_ready_flag)) return; - wlan_hdd_phc_deinit(hdd_ctx); + if (hdd_tsf_is_ptp_enabled(hdd_ctx)) + wlan_hdd_phc_deinit(hdd_ctx); wlan_hdd_tsf_plus_deinit(hdd_ctx); qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0); qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tx_rx.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tx_rx.c index 692ce4cc0f5b7004bad2b00d810c5e4dd828cc40..b73aec06bdc85e5a1434aa7dfdc35cd0cc2023f5 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tx_rx.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_tx_rx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -48,6 +49,7 @@ #include #include #include +#include #include "wlan_hdd_nan_datapath.h" #include "pld_common.h" #include @@ -60,12 +62,18 @@ #include "wlan_hdd_nud_tracking.h" #include "dp_txrx.h" +#if defined(WLAN_SUPPORT_RX_FISA) +#include "dp_fisa_rx.h" +#endif +#include #include "cfg_ucfg_api.h" #include "target_type.h" #include "wlan_hdd_object_manager.h" +#include "nan_public_structs.h" +#include "nan_ucfg_api.h" #include -#ifdef QCA_LL_TX_FLOW_CONTROL_V2 +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /* * Mapping Linux AC interpretation to SME AC. * Host has 5 tx queues, 4 flow-controlled queues for regular traffic and @@ -126,6 +134,7 @@ void hdd_tx_resume_timer_expired_handler(void *adapter_context) { struct hdd_adapter *adapter = (struct hdd_adapter *)adapter_context; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); u32 p_qpaused; u32 np_qpaused; @@ -134,6 +143,10 @@ void hdd_tx_resume_timer_expired_handler(void *adapter_context) return; } + cdp_display_stats(soc, CDP_DUMP_TX_FLOW_POOL_INFO, + QDF_STATS_VERBOSITY_LEVEL_LOW); + wlan_hdd_display_netif_queue_history(hdd_ctx, + QDF_STATS_VERBOSITY_LEVEL_LOW); hdd_debug("Enabling queues"); spin_lock_bh(&adapter->pause_map_lock); p_qpaused = adapter->pause_map & BIT(WLAN_DATA_FLOW_CONTROL_PRIORITY); @@ -347,19 +360,13 @@ void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter) } } -/** - * hdd_get_tx_resource() - check tx resources and take action - * @adapter: adapter handle - * @STAId: station id - * @timer_value: timer value - * - * Return: none - */ void hdd_get_tx_resource(struct hdd_adapter *adapter, - uint8_t STAId, uint16_t timer_value) + struct qdf_mac_addr *mac_addr, uint16_t timer_value) { if (false == - cdp_fc_get_tx_resource(cds_get_context(QDF_MODULE_ID_SOC), STAId, + cdp_fc_get_tx_resource(cds_get_context(QDF_MODULE_ID_SOC), + OL_TXRX_PDEV_ID, + *mac_addr, adapter->tx_flow_low_watermark, adapter->tx_flow_hi_watermark_offset)) { hdd_debug("Disabling queues lwm %d hwm offset %d", @@ -379,45 +386,11 @@ void hdd_get_tx_resource(struct hdd_adapter *adapter, } } } - -#else -/** - * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan - * @adapter: pointer to HDD adapter - * @skb: pointer to skb data packet - * - * Return: pointer to skb structure - */ -static inline struct sk_buff *hdd_skb_orphan(struct hdd_adapter *adapter, - struct sk_buff *skb) { - - struct sk_buff *nskb; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0)) - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); -#endif - - hdd_skb_fill_gso_size(adapter->dev, skb); - - nskb = skb_unshare(skb, GFP_ATOMIC); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0)) - if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) { - /* - * For UDP packets we want to orphan the packet to allow the app - * to send more packets. The flow would ultimately be controlled - * by the limited number of tx descriptors for the vdev. - */ - ++adapter->hdd_stats.tx_rx_stats.tx_orphaned; - skb_orphan(skb); - } -#endif - return nskb; -} #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ uint32_t hdd_txrx_get_tx_ack_count(struct hdd_adapter *adapter) { return cdp_get_tx_ack_stats(cds_get_context(QDF_MODULE_ID_SOC), - cds_get_context(QDF_MODULE_ID_TXRX), adapter->vdev_id); } @@ -465,6 +438,27 @@ void hdd_event_eapol_log(struct sk_buff *skb, enum qdf_proto_dir dir) } #endif /* FEATURE_WLAN_DIAG_SUPPORT */ +int hdd_set_udp_qos_upgrade_config(struct hdd_adapter *adapter, + uint8_t priority) +{ + if (adapter->device_mode != QDF_STA_MODE) { + hdd_info_rl("Data priority upgrade only allowed in STA mode:%d", + adapter->device_mode); + return -EINVAL; + } + + if (priority >= QCA_WLAN_AC_ALL) { + hdd_err_rl("Invlid data priority: %d", priority); + return -EINVAL; + } + + adapter->upgrade_udp_qos_threshold = priority; + + hdd_debug("UDP packets qos upgrade to: %d", priority); + + return 0; +} + /** * wlan_hdd_classify_pkt() - classify packet * @skb - sk buff @@ -503,50 +497,6 @@ void wlan_hdd_classify_pkt(struct sk_buff *skb) QDF_NBUF_CB_PACKET_TYPE_ICMPv6; } -/** - * hdd_get_transmit_sta_id() - function to retrieve station id to be used for - * sending traffic towards a particular destination address. The destination - * address can be unicast, multicast or broadcast - * - * @adapter: Handle to adapter context - * @dst_addr: Destination address - * @station_id: station id - * - * Returns: None - */ -static void hdd_get_transmit_sta_id(struct hdd_adapter *adapter, - struct sk_buff *skb, uint8_t *station_id) -{ - bool mcbc_addr = false; - QDF_STATUS status; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct qdf_mac_addr *dst_addr = NULL; - - dst_addr = (struct qdf_mac_addr *)skb->data; - status = hdd_get_peer_sta_id(sta_ctx, dst_addr, station_id); - if (QDF_IS_STATUS_ERROR(status)) { - if (QDF_NBUF_CB_GET_IS_BCAST(skb) || - QDF_NBUF_CB_GET_IS_MCAST(skb)) { - hdd_debug("Received MC/BC packet for transmission"); - mcbc_addr = true; - } - } - - if (adapter->device_mode == QDF_IBSS_MODE || - adapter->device_mode == QDF_NDI_MODE) { - /* - * This check is necessary to make sure station id is not - * overwritten for UC traffic in IBSS or NDI mode - */ - if (mcbc_addr) - *station_id = sta_ctx->broadcast_sta_id; - } else { - /* For the rest, traffic is directed to AP/P2P GO */ - if (eConnectionState_Associated == sta_ctx->conn_info.conn_state) - *station_id = sta_ctx->conn_info.sta_id[0]; - } -} - /** * hdd_clear_tx_rx_connectivity_stats() - clear connectivity stats * @hdd_ctx: pointer to HDD Station Context @@ -594,7 +544,8 @@ void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx) /** * hdd_is_tx_allowed() - check if Tx is allowed based on current peer state * @skb: pointer to OS packet (sk_buff) - * @peer_id: Peer STA ID in peer table + * @vdev_id: virtual interface id + * @peer_mac: Peer mac address * * This function gets the peer state from DP and check if it is either * in OL_TXRX_PEER_STATE_CONN or OL_TXRX_PEER_STATE_AUTH. Only EAP packets @@ -603,24 +554,15 @@ void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx) * * Return: true if Tx is allowed and false otherwise. */ -static inline bool hdd_is_tx_allowed(struct sk_buff *skb, uint8_t peer_id) +static inline bool hdd_is_tx_allowed(struct sk_buff *skb, uint8_t vdev_id, + uint8_t *peer_mac) { enum ol_txrx_peer_state peer_state; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - void *peer; QDF_BUG(soc); - QDF_BUG(pdev); - - peer = cdp_peer_find_by_local_id(soc, pdev, peer_id); - if (!peer) { - hdd_err_rl("Unable to find peer entry for sta_id: %d", peer_id); - return false; - } - - peer_state = cdp_peer_state_get(soc, peer); + peer_state = cdp_peer_state_get(soc, vdev_id, peer_mac); if (likely(OL_TXRX_PEER_STATE_AUTH == peer_state)) return true; if (OL_TXRX_PEER_STATE_CONN == peer_state && @@ -895,6 +837,99 @@ void hdd_tx_rx_collect_connectivity_stats_info(struct sk_buff *skb, } } +/** + * hdd_is_xmit_allowed_on_ndi() - Verify if xmit is allowed on NDI + * @adapter: The adapter structure + * + * Return: True if xmit is allowed on NDI and false otherwise + */ +static bool hdd_is_xmit_allowed_on_ndi(struct hdd_adapter *adapter) +{ + enum nan_datapath_state state; + + state = ucfg_nan_get_ndi_state(adapter->vdev); + return (state == NAN_DATA_NDI_CREATED_STATE || + state == NAN_DATA_CONNECTED_STATE || + state == NAN_DATA_CONNECTING_STATE || + state == NAN_DATA_PEER_CREATE_STATE); +} + +/** + * hdd_get_transmit_mac_addr() - Get the mac address to validate the xmit + * @adapter: The adapter structure + * @skb: The network buffer + * @mac_addr_tx_allowed: The mac address to be filled + * + * Return: None + */ +static +void hdd_get_transmit_mac_addr(struct hdd_adapter *adapter, struct sk_buff *skb, + struct qdf_mac_addr *mac_addr_tx_allowed) +{ + struct hdd_station_ctx *sta_ctx = &adapter->session.station; + bool is_mc_bc_addr = false; + + if (QDF_NBUF_CB_GET_IS_BCAST(skb) || QDF_NBUF_CB_GET_IS_MCAST(skb)) + is_mc_bc_addr = true; + + if (adapter->device_mode == QDF_IBSS_MODE) { + if (is_mc_bc_addr) + qdf_copy_macaddr(mac_addr_tx_allowed, + &adapter->mac_addr); + else + qdf_copy_macaddr(mac_addr_tx_allowed, + (struct qdf_mac_addr *)skb->data); + } else if (adapter->device_mode == QDF_NDI_MODE && + hdd_is_xmit_allowed_on_ndi(adapter)) { + if (is_mc_bc_addr) + qdf_copy_macaddr(mac_addr_tx_allowed, + &adapter->mac_addr); + else + qdf_copy_macaddr(mac_addr_tx_allowed, + (struct qdf_mac_addr *)skb->data); + } else { + if (sta_ctx->conn_info.conn_state == + eConnectionState_Associated) + qdf_copy_macaddr(mac_addr_tx_allowed, + &sta_ctx->conn_info.bssid); + } +} + +#ifdef HANDLE_BROADCAST_EAPOL_TX_FRAME +/** + * wlan_hdd_fix_broadcast_eapol() - Fix broadcast eapol + * @adapter: pointer to adapter + * @skb: pointer to OS packet (sk_buff) + * + * Override DA of broadcast eapol with bssid addr. + * + * Return: None + */ +static void wlan_hdd_fix_broadcast_eapol(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ + struct ethhdr *eh = (struct ethhdr *)skb->data; + unsigned char *ap_mac_addr = + &adapter->session.station.conn_info.bssid.bytes[0]; + + if (qdf_unlikely((QDF_NBUF_CB_GET_PACKET_TYPE(skb) == + QDF_NBUF_CB_PACKET_TYPE_EAPOL) && + QDF_NBUF_CB_GET_IS_BCAST(skb))) { + hdd_debug("SA: "QDF_MAC_ADDR_FMT " override DA: "QDF_MAC_ADDR_FMT " with AP mac address "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(&eh->h_source[0]), + QDF_MAC_ADDR_REF(&eh->h_dest[0]), + QDF_MAC_ADDR_REF(ap_mac_addr)); + + qdf_mem_copy(&eh->h_dest, ap_mac_addr, QDF_MAC_ADDR_SIZE); + } +} +#else +static void wlan_hdd_fix_broadcast_eapol(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ +} +#endif /* HANDLE_BROADCAST_EAPOL_TX_FRAME */ + /** * __hdd_hard_start_xmit() - Transmit a frame * @skb: pointer to OS packet (sk_buff) @@ -916,13 +951,14 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, enum sme_qos_wmmuptype up; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); bool granted; - uint8_t STAId; struct hdd_station_ctx *sta_ctx = &adapter->session.station; - struct qdf_mac_addr *mac_addr; + struct qdf_mac_addr mac_addr; + struct qdf_mac_addr mac_addr_tx_allowed = QDF_MAC_ADDR_ZERO_INIT; uint8_t pkt_type = 0; bool is_arp = false; struct wlan_objmgr_vdev *vdev; - struct hdd_context *hdd_ctx = adapter->hdd_ctx; + struct hdd_context *hdd_ctx; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); #ifdef QCA_WIFI_FTM if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { @@ -933,6 +969,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, ++adapter->hdd_stats.tx_rx_stats.tx_called; adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; + qdf_mem_copy(mac_addr.bytes, skb->data, sizeof(mac_addr.bytes)); if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() || cds_is_load_or_unload_in_progress()) { @@ -941,6 +978,18 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, goto drop_pkt; } + hdd_ctx = adapter->hdd_ctx; + if (wlan_hdd_validate_context(hdd_ctx)) { + QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_HDD_DATA, + "Invalid HDD context"); + goto drop_pkt; + } + + if (hdd_ctx->hdd_wlan_suspended) { + hdd_err_rl("Device is system suspended, drop pkt"); + goto drop_pkt; + } + wlan_hdd_classify_pkt(skb); if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == QDF_NBUF_CB_PACKET_TYPE_ARP) { if (qdf_nbuf_data_is_arp_req(skb) && @@ -957,23 +1006,15 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, hdd_tx_rx_collect_connectivity_stats_info(skb, adapter, PKT_TYPE_REQ, &pkt_type); - if (cds_is_driver_recovering()) { - QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN, - "Recovery in progress, dropping the packet"); - goto drop_pkt; - } - - STAId = HDD_WLAN_INVALID_STA_ID; - - hdd_get_transmit_sta_id(adapter, skb, &STAId); - if (STAId >= WLAN_MAX_STA_COUNT) { + hdd_get_transmit_mac_addr(adapter, skb, &mac_addr_tx_allowed); + if (qdf_is_macaddr_zero(&mac_addr_tx_allowed)) { QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH, - "Invalid station id, transmit operation suspended"); + "tx not allowed, transmit operation suspended"); goto drop_pkt; } - hdd_get_tx_resource(adapter, STAId, - WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + hdd_get_tx_resource(adapter, &mac_addr, + WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); /* Get TL AC corresponding to Qdisc queue index/AC. */ ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping]; @@ -1068,11 +1109,9 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, adapter->stats.tx_bytes += skb->len; - mac_addr = (struct qdf_mac_addr *)skb->data; - vdev = hdd_objmgr_get_vdev(adapter); if (vdev) { - ucfg_tdls_update_tx_pkt_cnt(vdev, mac_addr); + ucfg_tdls_update_tx_pkt_cnt(vdev, &mac_addr); hdd_objmgr_put_vdev(vdev); } @@ -1094,9 +1133,13 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, sizeof(qdf_nbuf_data(skb)), QDF_TX)); - if (!hdd_is_tx_allowed(skb, STAId)) { - QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Tx not allowed for sta_id: %d"), STAId); + if (!hdd_is_tx_allowed(skb, adapter->vdev_id, + mac_addr_tx_allowed.bytes)) { + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, + QDF_TRACE_LEVEL_INFO_HIGH, + FL("Tx not allowed for sta: " + QDF_MAC_ADDR_FMT), QDF_MAC_ADDR_REF( + mac_addr_tx_allowed.bytes)); ++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac]; goto drop_pkt_and_release_skb; } @@ -1122,11 +1165,13 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb, goto drop_pkt_and_release_skb; } - if (adapter->tx_fn(adapter->txrx_vdev, - (qdf_nbuf_t)skb) != NULL) { + wlan_hdd_fix_broadcast_eapol(adapter, skb); + + if (adapter->tx_fn(soc, adapter->vdev_id, (qdf_nbuf_t)skb)) { QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Failed to send packet to txrx for sta_id: %d", - __func__, STAId); + "%s: Failed to send packet to txrx for sta_id: " + QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(mac_addr.bytes)); ++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac]; goto drop_pkt_and_release_skb; } @@ -1189,23 +1234,6 @@ netdev_tx_t hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) return NETDEV_TX_OK; } -QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx, - struct qdf_mac_addr *mac_address, - uint8_t *sta_id) -{ - uint8_t idx; - - for (idx = 0; idx < MAX_PEERS; idx++) { - if (!qdf_mem_cmp(&sta_ctx->conn_info.peer_macaddr[idx], - mac_address, QDF_MAC_ADDR_SIZE)) { - *sta_id = sta_ctx->conn_info.sta_id[idx]; - return QDF_STATUS_SUCCESS; - } - } - - return QDF_STATUS_E_FAILURE; -} - /** * __hdd_tx_timeout() - TX timeout handler * @dev: pointer to network device @@ -1288,12 +1316,12 @@ static void __hdd_tx_timeout(struct net_device *dev) QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, "Data stall due to continuous TX timeouts"); adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; + if (cdp_cfg_get(soc, cfg_dp_enable_data_stall)) cdp_post_data_stall_event(soc, - cds_get_context(QDF_MODULE_ID_TXRX), DATA_STALL_LOG_INDICATOR_HOST_DRIVER, DATA_STALL_LOG_HOST_STA_TX_TIMEOUT, - 0xFF, 0xFF, + OL_TXRX_PDEV_ID, 0xFF, DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); } } @@ -1353,14 +1381,24 @@ QDF_STATUS hdd_deinit_tx_rx(struct hdd_adapter *adapter) if (!adapter) return QDF_STATUS_E_FAILURE; - adapter->txrx_vdev = NULL; adapter->tx_fn = NULL; return QDF_STATUS_SUCCESS; } #ifdef FEATURE_MONITOR_MODE_SUPPORT -QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf) +/** + * 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) { struct hdd_adapter *adapter; int rxstat; @@ -1426,30 +1464,6 @@ QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf) } #endif -/** - * hdd_get_peer_idx() - Get the idx for given address in peer table - * @sta_ctx: pointer to HDD Station Context - * @addr: pointer to Peer Mac address - * - * Return: index when success else INVALID_PEER_IDX - */ -int hdd_get_peer_idx(struct hdd_station_ctx *sta_ctx, - struct qdf_mac_addr *addr) -{ - uint8_t idx; - - for (idx = 0; idx < MAX_PEERS; idx++) { - if (sta_ctx->conn_info.sta_id[idx] == HDD_WLAN_INVALID_STA_ID) - continue; - if (qdf_mem_cmp(&sta_ctx->conn_info.peer_macaddr[idx], - addr, sizeof(struct qdf_mac_addr))) - continue; - return idx; - } - - return INVALID_PEER_IDX; -} - /* * hdd_is_mcast_replay() - checks if pkt is multicast replay * @skb: packet skb @@ -1492,12 +1506,16 @@ static void hdd_resolve_rx_ol_mode(struct hdd_context *hdd_ctx) } else if (cdp_cfg_get(soc, cfg_dp_lro_enable)) { hdd_debug("Rx offload LRO is enabled"); hdd_ctx->ol_enable = CFG_LRO_ENABLED; + } else if (cdp_cfg_get(soc, cfg_dp_tc_based_dyn_gro_enable)) { + hdd_debug("Dynamic Rx offload GRO is enabled"); + hdd_ctx->ol_enable = CFG_DYNAMIC_GRO_ENABLED; } else { hdd_debug("Rx offload: GRO is enabled"); hdd_ctx->ol_enable = CFG_GRO_ENABLED; } } +#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION /** * hdd_gro_rx_bh_disable() - GRO RX/flush function. * @napi_to_use: napi to be used to give packets to the stack, gro flush @@ -1518,18 +1536,71 @@ static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter, QDF_STATUS status = QDF_STATUS_SUCCESS; struct hdd_context *hdd_ctx = adapter->hdd_ctx; gro_result_t gro_res; + uint32_t rx_aggregation; + uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(skb); + int32_t gro_disallowed; + + rx_aggregation = qdf_atomic_read(&hdd_ctx->dp_agg_param.rx_aggregation); + gro_disallowed = qdf_atomic_read(&adapter->gro_disallowed); skb_set_hash(skb, QDF_NBUF_CB_RX_FLOW_ID(skb), PKT_HASH_TYPE_L4); local_bh_disable(); gro_res = napi_gro_receive(napi_to_use, skb); - if (hdd_get_current_throughput_level(hdd_ctx) == PLD_BUS_WIDTH_IDLE) { + if (hdd_get_current_throughput_level(hdd_ctx) == PLD_BUS_WIDTH_IDLE || + !rx_aggregation || gro_disallowed) { if (gro_res != GRO_DROP && gro_res != GRO_NORMAL) { adapter->hdd_stats.tx_rx_stats. rx_gro_low_tput_flush++; napi_gro_flush(napi_to_use, false); } + if (!rx_aggregation) + hdd_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] = 1; + if (gro_disallowed) + adapter->gro_flushed[rx_ctx_id] = 1; + } + local_bh_enable(); + + if (gro_res == GRO_DROP) + status = QDF_STATUS_E_GRO_DROP; + + return status; +} + +#else /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ + +/** + * hdd_gro_rx_bh_disable() - GRO RX/flush function. + * @napi_to_use: napi to be used to give packets to the stack, gro flush + * @skb: pointer to sk_buff + * + * Function calls napi_gro_receive for the skb. If the skb indicates that a + * flush needs to be done (set by the lower DP layer), the function also calls + * napi_gro_flush. Local softirqs are disabled (and later enabled) while making + * napi_gro__ calls. + * + * Return: QDF_STATUS_SUCCESS if not dropped by napi_gro_receive or + * QDF error code. + */ +static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter, + struct napi_struct *napi_to_use, + struct sk_buff *skb) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct hdd_context *hdd_ctx = adapter->hdd_ctx; + gro_result_t gro_res; + + skb_set_hash(skb, QDF_NBUF_CB_RX_FLOW_ID(skb), PKT_HASH_TYPE_L4); + + local_bh_disable(); + gro_res = napi_gro_receive(napi_to_use, skb); + + if (hdd_get_current_throughput_level(hdd_ctx) == PLD_BUS_WIDTH_IDLE) { + if (gro_res != GRO_DROP && gro_res != GRO_NORMAL) { + adapter->hdd_stats.tx_rx_stats.rx_gro_low_tput_flush++; + napi_gro_flush(napi_to_use, false); + } } local_bh_enable(); @@ -1538,6 +1609,7 @@ static QDF_STATUS hdd_gro_rx_bh_disable(struct hdd_adapter *adapter, return status; } +#endif /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ /** * hdd_gro_rx_dp_thread() - Handle Rx procesing via GRO for DP thread @@ -1698,7 +1770,9 @@ static void hdd_register_rx_ol_cb(struct hdd_context *hdd_ctx, cdp_register_rx_offld_flush_cb(soc, hdd_qdf_lro_flush); hdd_ctx->receive_offload_cb = hdd_lro_rx; hdd_debug("LRO is enabled"); - } else if (hdd_ctx->ol_enable == CFG_GRO_ENABLED) { + } else if (hdd_ctx->ol_enable == CFG_GRO_ENABLED || + hdd_ctx->ol_enable == CFG_DYNAMIC_GRO_ENABLED) { + qdf_atomic_set(&hdd_ctx->dp_agg_param.rx_aggregation, 1); if (lithium_based_target) { /* no flush registration needed, it happens in DP thread */ hdd_ctx->receive_offload_cb = hdd_gro_rx_dp_thread; @@ -1769,7 +1843,8 @@ int hdd_rx_ol_init(struct hdd_context *hdd_ctx) bool lithium_based_target = false; if (hdd_ctx->target_type == TARGET_TYPE_QCA6290 || - hdd_ctx->target_type == TARGET_TYPE_QCA6390) + hdd_ctx->target_type == TARGET_TYPE_QCA6390 || + hdd_ctx->target_type == TARGET_TYPE_QCA6490) lithium_based_target = true; hdd_resolve_rx_ol_mode(hdd_ctx); @@ -1890,10 +1965,19 @@ QDF_STATUS hdd_rx_pkt_thread_enqueue_cbk(void *adapter, } hdd_adapter = (struct hdd_adapter *)adapter; - if (hdd_validate_adapter(hdd_adapter)) + if (hdd_validate_adapter(hdd_adapter)) { + hdd_err_rl("adapter validate failed"); return QDF_STATUS_E_FAILURE; + } vdev_id = hdd_adapter->vdev_id; + + if (vdev_id >= WLAN_UMAC_VDEV_ID_MAX) { + hdd_info_rl("Vdev invalid. Dropping packets"); + qdf_nbuf_list_free(nbuf_list); + return QDF_STATUS_E_NETDOWN; + } + head_ptr = nbuf_list; while (head_ptr) { qdf_nbuf_cb_update_vdev_id(head_ptr, vdev_id); @@ -1903,6 +1987,141 @@ QDF_STATUS hdd_rx_pkt_thread_enqueue_cbk(void *adapter, return dp_rx_enqueue_pkt(cds_get_context(QDF_MODULE_ID_SOC), nbuf_list); } +#ifdef CONFIG_HL_SUPPORT +QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ + struct hdd_context *hdd_ctx = adapter->hdd_ctx; + int status = QDF_STATUS_E_FAILURE; + int netif_status; + + adapter->hdd_stats.tx_rx_stats.rx_non_aggregated++; + hdd_ctx->no_rx_offload_pkt_cnt++; + netif_status = netif_rx_ni(skb); + + if (netif_status == NET_RX_SUCCESS) + status = QDF_STATUS_SUCCESS; + + return status; +} +#else + +#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION +#if defined(WLAN_SUPPORT_RX_FISA) +/** + * hdd_set_fisa_disallowed_for_vdev() - Set fisa disallowed bit for a vdev + * @soc: DP soc handle + * @vdev_id: Vdev id + * @rx_ctx_id: rx context id + * @val: Enable or disable + * + * The function sets the fisa disallowed flag for a given vdev + * + * Return: None + */ +static inline +void hdd_set_fisa_disallowed_for_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t rx_ctx_id, uint8_t val) +{ + dp_set_fisa_disallowed_for_vdev(soc, vdev_id, rx_ctx_id, val); +} +#else +static inline +void hdd_set_fisa_disallowed_for_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t rx_ctx_id, uint8_t val) +{ +} +#endif + +QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, + struct sk_buff *skb) +{ + struct hdd_context *hdd_ctx = adapter->hdd_ctx; + int status = QDF_STATUS_E_FAILURE; + int netif_status; + bool skb_receive_offload_ok = false; + uint8_t rx_ctx_id; + ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (QDF_NBUF_CB_RX_TCP_PROTO(skb) && + !QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb)) + skb_receive_offload_ok = true; + + if (hdd_ctx->ol_enable == CFG_DYNAMIC_GRO_ENABLED || + hdd_ctx->ol_enable == CFG_GRO_ENABLED) + rx_ctx_id = 0; + else + rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(skb); + + if (qdf_atomic_read(&adapter->gro_disallowed) == 0 && + adapter->gro_flushed[rx_ctx_id] != 0) { + if (qdf_likely(soc)) + hdd_set_fisa_disallowed_for_vdev(soc, adapter->vdev_id, + rx_ctx_id, 0); + adapter->gro_flushed[rx_ctx_id] = 0; + } else if (qdf_atomic_read(&adapter->gro_disallowed) && + adapter->gro_flushed[rx_ctx_id] == 0) { + if (qdf_likely(soc)) + hdd_set_fisa_disallowed_for_vdev(soc, adapter->vdev_id, + rx_ctx_id, 1); + } + + if (skb_receive_offload_ok && hdd_ctx->receive_offload_cb && + !hdd_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] && + !adapter->gro_flushed[rx_ctx_id]) { + status = hdd_ctx->receive_offload_cb(adapter, skb); + + if (QDF_IS_STATUS_SUCCESS(status)) { + adapter->hdd_stats.tx_rx_stats.rx_aggregated++; + return status; + } + + if (status == QDF_STATUS_E_GRO_DROP) { + adapter->hdd_stats.tx_rx_stats.rx_gro_dropped++; + return status; + } + } + + /* + * The below case handles the scenario when rx_aggregation is + * re-enabled dynamically, in which case gro_force_flush needs + * to be reset to 0 to allow GRO. + */ + if (qdf_atomic_read(&hdd_ctx->dp_agg_param.rx_aggregation) && + hdd_ctx->dp_agg_param.gro_force_flush[rx_ctx_id]) + hdd_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] = 0; + + adapter->hdd_stats.tx_rx_stats.rx_non_aggregated++; + + /* Account for GRO/LRO ineligible packets, mostly UDP */ + hdd_ctx->no_rx_offload_pkt_cnt++; + + if (qdf_likely(hdd_ctx->enable_dp_rx_threads || + hdd_ctx->enable_rxthread)) { + local_bh_disable(); + netif_status = netif_receive_skb(skb); + local_bh_enable(); + } else if (qdf_unlikely(QDF_NBUF_CB_RX_PEER_CACHED_FRM(skb))) { + /* + * Frames before peer is registered to avoid contention with + * NAPI softirq. + * Refer fix: + * qcacld-3.0: Do netif_rx_ni() for frames received before + * peer assoc + */ + netif_status = netif_rx_ni(skb); + } else { /* NAPI Context */ + netif_status = netif_receive_skb(skb); + } + + if (netif_status == NET_RX_SUCCESS) + status = QDF_STATUS_SUCCESS; + + return status; +} + +#else /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ + QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, struct sk_buff *skb) { @@ -1957,6 +2176,8 @@ QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, return status; } +#endif /* WLAN_FEATURE_DYNAMIC_RX_AGGREGATION */ +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) static bool hdd_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb) @@ -1976,6 +2197,9 @@ QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id) struct hdd_context *hdd_ctx; ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); + if (qdf_unlikely(!soc)) + return QDF_STATUS_E_FAILURE; + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (unlikely(!hdd_ctx)) { QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, @@ -1990,6 +2214,10 @@ QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id) return QDF_STATUS_E_FAILURE; } + /* do fisa flush for this vdev */ + if (hdd_ctx->config->fisa_enable) + hdd_rx_fisa_flush_by_vdev_id(soc, vdev_id); + if (hdd_ctx->enable_dp_rx_threads) dp_txrx_flush_pkts_by_vdev_id(soc, vdev_id); @@ -1998,6 +2226,24 @@ QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id) return QDF_STATUS_SUCCESS; } +#if defined(WLAN_SUPPORT_RX_FISA) +QDF_STATUS hdd_rx_fisa_cbk(void *dp_soc, void *dp_vdev, qdf_nbuf_t nbuf_list) +{ + return dp_fisa_rx((struct dp_soc *)dp_soc, (struct dp_vdev *)dp_vdev, + nbuf_list); +} + +QDF_STATUS hdd_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num) +{ + return dp_rx_fisa_flush_by_ctx_id((struct dp_soc *)dp_soc, ring_num); +} + +QDF_STATUS hdd_rx_fisa_flush_by_vdev_id(void *dp_soc, uint8_t vdev_id) +{ + return dp_rx_fisa_flush_by_vdev_id((struct dp_soc *)dp_soc, vdev_id); +} +#endif + QDF_STATUS hdd_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rxBuf) { @@ -2148,11 +2394,6 @@ QDF_STATUS hdd_rx_packet_cbk(void *adapter_context, hdd_tx_rx_collect_connectivity_stats_info( skb, adapter, PKT_TYPE_RX_REFUSED, &pkt_type); - DPTRACE(qdf_dp_log_proto_pkt_info(NULL, NULL, 0, 0, - QDF_RX, - QDF_TRACE_DEFAULT_MSDU_ID, - QDF_TX_RX_STATUS_DROP)); - } } @@ -2635,6 +2876,37 @@ void hdd_print_netdev_txq_status(struct net_device *dev) } } +#ifdef WLAN_FEATURE_PKT_CAPTURE +/** + * hdd_set_pktcapture_cb() - Set pkt capture mode callback + * @dev: Pointer to net_device structure + * @pdev_id: pdev id + * + * Return: 0 on success; non-zero for failure + */ +int hdd_set_pktcapture_cb(struct net_device *dev, uint8_t pdev_id) +{ + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + + return cdp_register_pktcapture_cb(soc, pdev_id, adapter, + hdd_mon_rx_packet_cbk); +} + +/** + * hdd_reset_pktcapture_cb() - Reset pkt capture mode callback + * @pdev_id: pdev id + * + * Return: None + */ +void hdd_reset_pktcapture_cb(uint8_t pdev_id) +{ + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + + cdp_deregister_pktcapture_cb(soc, pdev_id); +} +#endif /* WLAN_FEATURE_PKT_CAPTURE */ + #ifdef FEATURE_MONITOR_MODE_SUPPORT /** * hdd_set_mon_rx_cb() - Set Monitor mode Rx callback @@ -2651,30 +2923,16 @@ int hdd_set_mon_rx_cb(struct net_device *dev) struct ol_txrx_desc_type sta_desc = {0}; struct ol_txrx_ops txrx_ops; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_peer *peer; - uint8_t peer_id; - - peer = cdp_peer_find_by_addr(soc, pdev, adapter->mac_addr.bytes, - &peer_id); - if (!peer) { - hdd_err("Peer %pM not found", adapter->mac_addr.bytes); - return -EINVAL; - } - - sta_desc.sta_id = peer_id; + WLAN_ADDR_COPY(sta_desc.peer_addr.bytes, adapter->mac_addr.bytes); qdf_mem_zero(&txrx_ops, sizeof(txrx_ops)); txrx_ops.rx.rx = hdd_mon_rx_packet_cbk; hdd_monitor_set_rx_monitor_cb(&txrx_ops, hdd_rx_monitor_callback); - cdp_vdev_register(soc, - (struct cdp_vdev *)cdp_get_mon_vdev_from_pdev(soc, - (struct cdp_pdev *)pdev), - adapter, (struct cdp_ctrl_objmgr_vdev *)adapter->vdev, - &txrx_ops); + cdp_vdev_register(soc, adapter->vdev_id, + (ol_osif_vdev_handle)adapter, + &txrx_ops); /* peer is created wma_vdev_attach->wma_create_peer */ - qdf_status = cdp_peer_register(soc, - (struct cdp_pdev *)pdev, &sta_desc); + qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &sta_desc); if (QDF_STATUS_SUCCESS != qdf_status) { hdd_err("cdp_peer_register() failed to register. Status= %d [0x%08X]", qdf_status, qdf_status); @@ -2751,7 +3009,7 @@ void hdd_send_rps_ind(struct hdd_adapter *adapter) for (i = 0; i < rps_data.num_queues; i++) { hdd_debug("cpu_map_list[%d] = 0x%x", - i, rps_data.cpu_map_list[i]); + i, rps_data.cpu_map_list[i]); } strlcpy(rps_data.ifname, adapter->dev->name, @@ -2808,6 +3066,32 @@ void hdd_send_rps_disable_ind(struct hdd_adapter *adapter) cds_cfg->rps_enabled = false; } +#ifdef IPA_LAN_RX_NAPI_SUPPORT +void hdd_adapter_set_rps(uint8_t vdev_id, bool enable) +{ + struct hdd_context *hdd_ctx; + struct hdd_adapter *adapter; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) + return; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + if (!adapter) { + hdd_err_rl("Adapter not found for vdev_id: %d", vdev_id); + return; + } + + hdd_debug("Set RPS to %d for vdev_id %d", enable, vdev_id); + if (!hdd_ctx->rps) { + if (enable) + hdd_send_rps_ind(adapter); + else + hdd_send_rps_disable_ind(adapter); + } +} +#endif + void hdd_tx_queue_cb(hdd_handle_t hdd_handle, uint32_t vdev_id, enum netif_action_type action, enum netif_reason_type reason) @@ -2947,6 +3231,8 @@ static void hdd_ini_bus_bandwidth(struct hdd_config *config, cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL); config->bus_low_cnt_threshold = cfg_get(psoc, CFG_DP_BUS_LOW_BW_CNT_THRESHOLD); + config->enable_latency_crit_clients = + cfg_get(psoc, CFG_DP_BUS_HANDLE_LATENCY_CRITICAL_CLIENTS); } /** @@ -3071,25 +3357,84 @@ hdd_dp_nud_tracking_cfg_update(struct hdd_config *config, } #endif +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK +static void hdd_ini_tcp_del_ack_settings(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ + config->del_ack_threshold_high = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_HIGH_THRESHOLD); + config->del_ack_threshold_low = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_LOW_THRESHOLD); + config->del_ack_enable = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_ENABLE); + config->del_ack_pkt_count = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_PKT_CNT); + config->del_ack_timer_value = + cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE); +} +#else +static void hdd_ini_tcp_del_ack_settings(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ +} +#endif + +#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE +static void hdd_dp_hl_bundle_cfg_update(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ + config->pkt_bundle_threshold_high = + cfg_get(psoc, CFG_DP_HL_BUNDLE_HIGH_TH); + config->pkt_bundle_threshold_low = + cfg_get(psoc, CFG_DP_HL_BUNDLE_LOW_TH); + config->pkt_bundle_timer_value = + cfg_get(psoc, CFG_DP_HL_BUNDLE_TIMER_VALUE); + config->pkt_bundle_size = + cfg_get(psoc, CFG_DP_HL_BUNDLE_SIZE); +} +#else +static void hdd_dp_hl_bundle_cfg_update(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ +} +#endif + void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc, struct hdd_context *hdd_ctx) { struct hdd_config *config; - qdf_size_t array_out_size; + uint16_t cfg_len; config = hdd_ctx->config; + cfg_len = qdf_str_len(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST)) + + 1; hdd_ini_tx_flow_control(config, psoc); hdd_ini_bus_bandwidth(config, psoc); hdd_ini_tcp_settings(config, psoc); + + hdd_ini_tcp_del_ack_settings(config, psoc); + + hdd_dp_hl_bundle_cfg_update(config, psoc); + config->napi_cpu_affinity_mask = cfg_get(psoc, CFG_DP_NAPI_CE_CPU_MASK); config->rx_thread_ul_affinity_mask = cfg_get(psoc, CFG_DP_RX_THREAD_UL_CPU_MASK); config->rx_thread_affinity_mask = cfg_get(psoc, CFG_DP_RX_THREAD_CPU_MASK); - qdf_uint8_array_parse(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST), - config->cpu_map_list, - sizeof(config->cpu_map_list), &array_out_size); + config->fisa_enable = cfg_get(psoc, CFG_DP_RX_FISA_ENABLE); + if (cfg_len < CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN) { + qdf_str_lcopy(config->cpu_map_list, + cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST), + cfg_len); + } else { + hdd_err("ini string length greater than max size %d", + CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN); + cfg_len = qdf_str_len(cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST)); + qdf_str_lcopy(config->cpu_map_list, + cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST), + cfg_len); + } config->tx_orphan_enable = cfg_get(psoc, CFG_DP_TX_ORPHAN_ENABLE); config->rx_mode = cfg_get(psoc, CFG_DP_RX_MODE); hdd_set_rx_mode_value(hdd_ctx); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c index 78a45935d1a39b115506df96760f55605ca95a3c..62b25d8a3556f69e1c1536c50cb6b1b946ce7f7b 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c @@ -55,6 +55,8 @@ #include "dbglog_host.h" #include "wma.h" +#include + #include "wlan_hdd_power.h" #include "qwlan_version.h" #include "wlan_hdd_host_offload.h" @@ -2216,29 +2218,8 @@ #define WE_MAC_PWR_DEBUG_CMD 4 /* subcommand 5 is unused */ +/* subcommand 6 is unused */ -/* - * - * ibssPeerInfo - Print the ibss peers's MAC, rate and RSSI - * - * @INPUT: sta_id - * - * @OUTPUT: print ibss peer corresponding to sta_id in info logs - * PEER ADDR : 8c:fd:f0:01:9c:bf TxRate: 1 Mbps RSSI: -35 - * - * This IOCTL is used to print the specific ibss peers's MAC, - * rate and RSSI in info logs - * - * @E.g: iwpriv wlan0 ibssPeerInfo - * iwpriv wlan0 ibssPeerInfo 0 - * - * Supported Feature: IBSS - * - * Usage: Internal/External - * - * - */ -#define WE_IBSS_GET_PEER_INFO 6 #define WE_UNIT_TEST_CMD 7 #define WE_MTRACE_DUMP_CMD 8 @@ -3174,7 +3155,6 @@ void hdd_wlan_get_stats(struct hdd_adapter *adapter, uint16_t *length, * * Return - length of written content, negative number on error */ -#ifdef QCA_SUPPORT_CP_STATS static int wlan_hdd_write_suspend_resume_stats(struct hdd_context *hdd_ctx, char *buffer, uint16_t max_len) { @@ -3212,72 +3192,7 @@ static int wlan_hdd_write_suspend_resume_stats(struct hdd_context *hdd_ctx, return ret; } -#else -static int wlan_hdd_write_suspend_resume_stats(struct hdd_context *hdd_ctx, - char *buffer, uint16_t max_len) -{ - QDF_STATUS status; - struct suspend_resume_stats *sr_stats; - struct sir_wake_lock_stats wow_stats; - - sr_stats = &hdd_ctx->suspend_resume_stats; - - status = wma_get_wakelock_stats(&wow_stats); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Failed to get WoW stats"); - return qdf_status_to_os_return(status); - } - return scnprintf(buffer, max_len, - "\n" - "Suspends: %u\n" - "Resumes: %u\n" - "\n" - "Suspend Fail Reasons\n" - "\tIPA: %u\n" - "\tRadar: %u\n" - "\tRoam: %u\n" - "\tScan: %u\n" - "\tInitial Wakeup: %u\n" - "\n" - "WoW Wake Reasons\n" - "\tunicast: %u\n" - "\tbroadcast: %u\n" - "\tIPv4 multicast: %u\n" - "\tIPv6 multicast: %u\n" - "\tIPv6 multicast RA: %u\n" - "\tIPv6 multicast NS: %u\n" - "\tIPv6 multicast NA: %u\n" - "\tICMPv4: %u\n" - "\tICMPv6: %u\n" - "\tRSSI Breach: %u\n" - "\tLow RSSI: %u\n" - "\tG-Scan: %u\n" - "\tPNO Complete: %u\n" - "\tPNO Match: %u\n", - sr_stats->suspends, - sr_stats->resumes, - sr_stats->suspend_fail[SUSPEND_FAIL_IPA], - sr_stats->suspend_fail[SUSPEND_FAIL_RADAR], - sr_stats->suspend_fail[SUSPEND_FAIL_ROAM], - sr_stats->suspend_fail[SUSPEND_FAIL_SCAN], - sr_stats->suspend_fail[SUSPEND_FAIL_INITIAL_WAKEUP], - wow_stats.wow_ucast_wake_up_count, - wow_stats.wow_bcast_wake_up_count, - wow_stats.wow_ipv4_mcast_wake_up_count, - wow_stats.wow_ipv6_mcast_wake_up_count, - wow_stats.wow_ipv6_mcast_ra_stats, - wow_stats.wow_ipv6_mcast_ns_stats, - wow_stats.wow_ipv6_mcast_na_stats, - wow_stats.wow_icmpv4_count, - wow_stats.wow_icmpv6_count, - wow_stats.wow_rssi_breach_wake_up_count, - wow_stats.wow_low_rssi_wake_up_count, - wow_stats.wow_gscan_wake_up_count, - wow_stats.wow_pno_complete_wake_up_count, - wow_stats.wow_pno_match_wake_up_count); -} -#endif /** * hdd_wlan_list_fw_profile() - Get fw profiling points * @length: Size of the data copied @@ -3392,57 +3307,7 @@ int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value) return ret; } -/** - * hdd_wlan_get_ibss_peer_info() - Print IBSS peer information - * @adapter: Adapter upon which the IBSS client is active - * @sta_id: Station index of the IBSS peer - * - * Return: QDF_STATUS_STATUS if the peer was found and displayed, - * otherwise an appropriate QDF_STATUS_E_* failure code. - */ -static QDF_STATUS hdd_wlan_get_ibss_peer_info(struct hdd_adapter *adapter, - uint8_t sta_id) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; - struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - tSirPeerInfoRspParams *peer_info = &sta_ctx->ibss_peer_info; - - INIT_COMPLETION(adapter->ibss_peer_info_comp); - status = sme_request_ibss_peer_info(mac_handle, adapter, - hdd_get_ibss_peer_info_cb, - false, sta_id); - - if (QDF_STATUS_SUCCESS == status) { - unsigned long rc; - - rc = wait_for_completion_timeout - (&adapter->ibss_peer_info_comp, - msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT)); - if (!rc) { - hdd_err("failed wait on ibss_peer_info_comp"); - return QDF_STATUS_E_FAILURE; - } - - /** Print the peer info */ - hdd_debug("peer_info->numIBSSPeers = %d ", peer_info->numPeers); - { - uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; - uint32_t tx_rate = peer_info->peerInfoParams[0].txRate; - - qdf_mem_copy(mac_addr, peer_info->peerInfoParams[0]. - mac_addr, sizeof(mac_addr)); - hdd_debug("PEER ADDR : %pM TxRate: %d Mbps RSSI: %d", - mac_addr, (int)tx_rate, - (int)peer_info->peerInfoParams[0].rssi); - } - } else { - hdd_warn("Warning: sme_request_ibss_peer_info Request failed"); - } - - return status; -} - +#ifdef QCA_IBSS_SUPPORT /** * hdd_wlan_get_ibss_peer_info_all() - Print all IBSS peers * @adapter: Adapter upon which the IBSS clients are active @@ -3456,12 +3321,13 @@ static QDF_STATUS hdd_wlan_get_ibss_peer_info_all(struct hdd_adapter *adapter) mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); tSirPeerInfoRspParams *peer_info = &sta_ctx->ibss_peer_info; + struct qdf_mac_addr bcast = QDF_MAC_ADDR_BCAST_INIT; int i; INIT_COMPLETION(adapter->ibss_peer_info_comp); status = sme_request_ibss_peer_info(mac_handle, adapter, hdd_get_ibss_peer_info_cb, - true, 0xFF); + true, bcast.bytes); if (QDF_STATUS_SUCCESS == status) { unsigned long rc; @@ -3486,8 +3352,8 @@ static QDF_STATUS hdd_wlan_get_ibss_peer_info_all(struct hdd_adapter *adapter) peer_info->peerInfoParams[i].mac_addr, sizeof(mac_addr)); - hdd_debug(" PEER ADDR : %pM TxRate: %d Mbps RSSI: %d", - mac_addr, (int)tx_rate, + hdd_debug(" PEER ADDR : "QDF_MAC_ADDR_FMT" TxRate: %d Mbps RSSI: %d", + QDF_MAC_ADDR_REF(mac_addr), (int)tx_rate, (int)peer_info->peerInfoParams[i].rssi); } } else { @@ -3496,6 +3362,37 @@ static QDF_STATUS hdd_wlan_get_ibss_peer_info_all(struct hdd_adapter *adapter) return status; } +#else +/** + * hdd_wlan_get_ibss_peer_info() - Print IBSS peer information + * @adapter: Adapter upon which the IBSS client is active + * @sta_id: Station index of the IBSS peer + * + * This function is dummy + * + * Return: QDF_STATUS_STATUS + */ +static inline QDF_STATUS +hdd_wlan_get_ibss_peer_info(struct hdd_adapter *adapter, + uint8_t sta_id) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * hdd_wlan_get_ibss_peer_info_all() - Print all IBSS peers + * @adapter: Adapter upon which the IBSS clients are active + * + * This function is dummy + * + * Return: QDF_STATUS_STATUS + */ +static inline QDF_STATUS +hdd_wlan_get_ibss_peer_info_all(struct hdd_adapter *adapter) +{ + return QDF_STATUS_SUCCESS; +} +#endif /** * hdd_get_ldpc() - Get adapter LDPC @@ -3938,7 +3835,7 @@ int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode) mac_handle_t mac_handle = hdd_ctx->mac_handle; bool band_24 = false, band_5g = false; bool ch_bond24 = false, ch_bond5g = false; - struct sme_config_params *sme_config; + struct sme_config_params *sme_config = NULL; struct csr_config_params *csr_config; uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; uint8_t vhtchanwidth; @@ -3946,7 +3843,7 @@ int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode) enum hdd_dot11_mode hdd_dot11mode = hdd_ctx->config->dot11Mode; enum band_info curr_band = BAND_ALL; int retval = 0; - uint8_t band_capability; + uint32_t band_capability; QDF_STATUS status; uint32_t channel_bonding_mode; @@ -4678,7 +4575,7 @@ static int hdd_we_set_nss(struct hdd_adapter *adapter, int nss) return -EINVAL; } - status = hdd_update_nss(adapter, nss); + status = hdd_update_nss(adapter, nss, nss); if (QDF_IS_STATUS_ERROR(status)) hdd_err("cfg set failed, value %d status %d", nss, status); @@ -4893,6 +4790,8 @@ static int hdd_we_set_amsdu(struct hdd_adapter *adapter, int amsdu) static int hdd_we_clear_stats(struct hdd_adapter *adapter, int option) { + QDF_STATUS status; + hdd_debug("option %d", option); switch (option) { @@ -4913,8 +4812,13 @@ static int hdd_we_clear_stats(struct hdd_adapter *adapter, int option) hdd_clear_napi_stats(); break; default: - cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), - option); + status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), + OL_TXRX_PDEV_ID, + option); + if (status != QDF_STATUS_SUCCESS) + hdd_debug("Failed to dump stats for option: %d", + option); + break; } return 0; @@ -5576,11 +5480,28 @@ static int hdd_we_motion_det_start_stop(struct hdd_adapter *adapter, int value) hdd_err("Invalid value %d in mt_start", value); return -EINVAL; } + + if (!adapter->motion_det_cfg) { + hdd_err("Motion Detection config values not available"); + return -EINVAL; + } + + if (!adapter->motion_det_baseline_value) { + hdd_err("Motion Detection Baselining not started/completed"); + return -EAGAIN; + } + motion_det.vdev_id = adapter->vdev_id; motion_det.enable = value; - if (!value) + if (value) { + /* For motion detection start, set motion_det_in_progress */ + adapter->motion_det_in_progress = true; + } else { + /* For motion detection stop, reset motion_det_in_progress */ + adapter->motion_det_in_progress = false; adapter->motion_detection_mode = 0; + } sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det); @@ -5605,6 +5526,12 @@ static int hdd_we_motion_det_base_line_start_stop(struct hdd_adapter *adapter, return -EINVAL; } + /* Do not send baselining start/stop during motion detection phase */ + if (adapter->motion_det_in_progress) { + hdd_err("Motion detection still in progress, try later"); + return -EAGAIN; + } + motion_det_base_line.vdev_id = adapter->vdev_id; motion_det_base_line.enable = value; sme_motion_det_base_line_enable(hdd_ctx->mac_handle, @@ -6206,7 +6133,7 @@ static int __iw_setnone_getint(struct net_device *dev, } case WE_GET_MAX_ASSOC: { - if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc, *value) != + if (ucfg_mlme_get_assoc_sta_limit(hdd_ctx->psoc, value) != QDF_STATUS_SUCCESS) { hdd_err("CFG_ASSOC_STA_LIMIT failed"); ret = -EIO; @@ -7183,50 +7110,10 @@ static int __iw_get_char_setnone(struct net_device *dev, case WE_GET_CHANNEL_LIST: { - QDF_STATUS status; - uint8_t i, len; - char *buf; - uint8_t ubuf[CFG_COUNTRY_CODE_LEN]; - uint8_t ubuf_len = CFG_COUNTRY_CODE_LEN; - struct channel_list_info channel_list; - - memset(&channel_list, 0, sizeof(channel_list)); - status = iw_get_channel_list(dev, info, wrqu, - (char *)&channel_list); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("GetChannelList Failed!!!"); - return -EINVAL; - } - buf = extra; - /* - * Maximum channels = CFG_VALID_CHANNEL_LIST_LEN. - * Maximum buffer needed = 5 * number of channels. - * Check ifsufficient buffer is available and then - * proceed to fill the buffer. - */ - if (WE_MAX_STR_LEN < - (5 * CFG_VALID_CHANNEL_LIST_LEN)) { - hdd_err("Insufficient Buffer to populate channel list"); + if (0 != + iw_get_channel_list_with_cc(dev, mac_handle, + info, wrqu, extra)) return -EINVAL; - } - len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", - channel_list.num_channels); - if (QDF_STATUS_SUCCESS == sme_get_country_code(mac_handle, - ubuf, - &ubuf_len)) { - /* Printing Country code in getChannelList */ - for (i = 0; i < (ubuf_len - 1); i++) - len += scnprintf(buf + len, - WE_MAX_STR_LEN - len, - "%c", ubuf[i]); - } - for (i = 0; i < channel_list.num_channels; i++) { - len += - scnprintf(buf + len, WE_MAX_STR_LEN - len, - " %u", channel_list.channels[i]); - } - wrqu->data.length = strlen(extra) + 1; - break; } #ifdef FEATURE_WLAN_TDLS @@ -7275,28 +7162,17 @@ static int __iw_get_char_setnone(struct net_device *dev, int length = 0, buf = 0; for (idx = 0; idx < MAX_PEERS; idx++) { - if (HDD_WLAN_INVALID_STA_ID != - sta_ctx->conn_info.sta_id[idx]) { - buf = snprintf - ((extra + length), - WE_MAX_STR_LEN - length, - "\n%d ."QDF_MAC_ADDR_STR"\n", - sta_ctx->conn_info.sta_id[idx], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[0], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[1], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[2], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[3], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[4], - sta_ctx->conn_info. - peer_macaddr[idx].bytes[5] - ); - length += buf; - } + if (!hdd_is_valid_mac_address( + sta_ctx->conn_info.peer_macaddr[idx].bytes)) + continue; + + buf = snprintf + ((extra + length), + WE_MAX_STR_LEN - length, + "\n" QDF_FULL_MAC_FMT "\n", + QDF_FULL_MAC_REF(sta_ctx->conn_info. + peer_macaddr[idx].bytes)); + length += buf; } wrqu->data.length = strlen(extra) + 1; break; @@ -7552,7 +7428,9 @@ static int __iw_setnone_getnone(struct net_device *dev, tSirMacAddr bssid; uint32_t roam_id = INVALID_ROAM_ID; uint8_t operating_ch = - adapter->session.station.conn_info.channel; + wlan_reg_freq_to_chan( + hdd_ctx->pdev, + adapter->session.station.conn_info.chan_freq); tCsrRoamModifyProfileFields mod_fields; sme_get_modify_profile_fields(mac_handle, adapter->vdev_id, @@ -7717,9 +7595,11 @@ static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, hdd_err("Invalid input params received for the IOCTL"); return 0; } - policy_mgr_update_connection_info_utfw(hdd_ctx->psoc, + policy_mgr_update_connection_info_utfw( + hdd_ctx->psoc, apps_args[0], apps_args[1], apps_args[2], apps_args[3], - apps_args[4], apps_args[5], apps_args[6], apps_args[7]); + apps_args[4], apps_args[5], + wlan_chan_to_freq(apps_args[6]), apps_args[7]); } break; @@ -7743,8 +7623,8 @@ static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, case WE_POLICY_MANAGER_PCL_CMD: { - uint8_t pcl[QDF_MAX_NUM_CHAN] = {0}; - uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t pcl[NUM_CHANNELS] = {0}; + uint8_t weight_list[NUM_CHANNELS] = {0}; uint32_t pcl_len = 0, i = 0; hdd_debug(" is called"); @@ -7754,9 +7634,9 @@ static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, return 0; } policy_mgr_get_pcl(hdd_ctx->psoc, apps_args[0], - pcl, &pcl_len, - weight_list, QDF_ARRAY_SIZE(weight_list)); - hdd_debug("PCL list for role[%d] is {", apps_args[0]); + pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); + hdd_debug("PCL Freq list for role[%d] is {", apps_args[0]); for (i = 0 ; i < pcl_len; i++) hdd_debug(" %d, ", pcl[i]); hdd_debug("}--------->\n"); @@ -7778,8 +7658,8 @@ static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, return 0; } policy_mgr_current_connections_update( - hdd_ctx->psoc, - adapter->vdev_id, apps_args[0], + hdd_ctx->psoc, adapter->vdev_id, + wlan_chan_to_freq(apps_args[0]), POLICY_MGR_UPDATE_REASON_UT); } break; @@ -7794,8 +7674,9 @@ static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, hdd_err("Invalid input params received for the IOCTL"); return 0; } - allow = policy_mgr_allow_concurrency(hdd_ctx->psoc, - apps_args[0], apps_args[1], apps_args[2]); + allow = policy_mgr_allow_concurrency( + hdd_ctx->psoc, apps_args[0], + wlan_chan_to_freq(apps_args[1]), apps_args[2]); hdd_debug("allow %d {0 = don't allow, 1 = allow}", allow); } break; @@ -7895,6 +7776,34 @@ static void hdd_ch_avoid_unit_cmd(struct hdd_context *hdd_ctx, { } #endif + +#ifdef FW_THERMAL_THROTTLE_SUPPORT +/** + * hdd_send_thermal_mgmt_cmd - Send thermal management params + * @mac_handle: Opaque handle to the global MAC context + * @lower_thresh_deg: Lower threshold value of Temperature + * @higher_thresh_deg: Higher threshold value of Temperature + * + * Return: QDF_STATUS + */ +#ifndef QCN7605_SUPPORT +static QDF_STATUS hdd_send_thermal_mgmt_cmd(mac_handle_t mac_handle, + uint16_t lower_thresh_deg, + uint16_t higher_thresh_deg) +{ + return sme_set_thermal_mgmt(mac_handle, lower_thresh_deg, + higher_thresh_deg); +} +#else +static QDF_STATUS hdd_send_thermal_mgmt_cmd(mac_handle_t mac_handle, + uint16_t lower_thresh_deg, + uint16_t higher_thresh_deg) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif /* FW_THERMAL_THROTTLE_SUPPORT */ + /** * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler * @dev: device upon which the ioctl was received @@ -7920,9 +7829,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, int *apps_args = (int *) extra; struct hdd_context *hdd_ctx; int ret, num_args; - void *soc = NULL; - struct cdp_pdev *pdev = NULL; - struct cdp_vdev *vdev = NULL; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct cdp_txrx_stats_req req = {0}; hdd_enter_dev(dev); @@ -7943,13 +7850,6 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, hdd_debug("Received length %d", wrqu->data.length); switch (sub_cmd) { - case WE_IBSS_GET_PEER_INFO: - { - pr_info("Station ID = %d\n", apps_args[0]); - hdd_wlan_get_ibss_peer_info(adapter, apps_args[0]); - } - break; - case WE_P2P_NOA_CMD: { struct p2p_app_set_ps p2p_noa; @@ -8010,7 +7910,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, for (i = 0; i < len; i++) { pr_info("|table_index[%d]\t\t\n", i); pr_info("|\t|vdev_id - %-10d|\n", conn_info->vdev_id); - pr_info("|\t|chan - %-10d|\n", conn_info->chan); + pr_info("|\t|freq - %-10d|\n", conn_info->freq); pr_info("|\t|bw - %-10d|\n", conn_info->bw); pr_info("|\t|mode - %-10d|\n", conn_info->mode); pr_info("|\t|mac - %-10d|\n", conn_info->mac); @@ -8152,29 +8052,26 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, break; case WE_SET_TXRX_STATS: { - ret = cds_get_datapath_handles(&soc, &pdev, &vdev, - adapter->vdev_id); - - if (ret != 0) { - hdd_err("Invalid handles"); - break; - } - req.stats = apps_args[0]; /* default value of secondary parameter is 0(mac_id) */ req.mac_id = apps_args[1]; hdd_debug("WE_SET_TXRX_STATS stats cmd: %d mac_id: %d", - req.stats, req.mac_id); + req.stats, req.mac_id); + if (qdf_unlikely(!soc)) { + hdd_err("soc is NULL"); + return -EINVAL; + } + if (apps_args[0] == CDP_TXRX_STATS_28) { if (sta_ctx->conn_info.is_authenticated) { - hdd_debug("ap mac addr: %pM", - (void *)&sta_ctx->conn_info.bssid); + hdd_debug("ap mac addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes)); req.peer_addr = (char *)&sta_ctx->conn_info.bssid; } } - ret = cdp_txrx_stats_request(soc, vdev, &req); + ret = cdp_txrx_stats_request(soc, adapter->vdev_id, &req); break; } #ifdef WLAN_FEATURE_MOTION_DETECTION @@ -8204,6 +8101,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, motion_det_cfg.md_fine_thr_low = apps_args[13]; adapter->motion_detection_mode = apps_args[14]; sme_motion_det_config(hdd_ctx->mac_handle, &motion_det_cfg); + adapter->motion_det_cfg = true; } break; case WE_MOTION_DET_BASE_LINE_CONFIG_PARAM: @@ -8253,9 +8151,9 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, return qdf_status_to_os_return(status); if (!apps_args[6]) { - status = sme_set_thermal_mgmt(hdd_ctx->mac_handle, - apps_args[4], - apps_args[5]); + status = hdd_send_thermal_mgmt_cmd(hdd_ctx->mac_handle, + apps_args[4], + apps_args[5]); if (QDF_IS_STATUS_ERROR(status)) return qdf_status_to_os_return(status); } @@ -8942,8 +8840,8 @@ static int __iw_set_keepalive_params(struct net_device *dev, request->destIpv4Addr[0], request->destIpv4Addr[1], request->destIpv4Addr[2], request->destIpv4Addr[3]); - hdd_debug("Dest MAC address: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(request->dest_macaddr.bytes)); + hdd_debug("Dest MAC address: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(request->dest_macaddr.bytes)); break; } @@ -9125,113 +9023,10 @@ static int iw_set_packet_filter_params(struct net_device *dev, } #endif -#ifdef QCA_SUPPORT_CP_STATS static int hdd_get_wlan_stats(struct hdd_adapter *adapter) { return wlan_hdd_get_station_stats(adapter); } -#else /* QCA_SUPPORT_CP_STATS */ -struct hdd_statistics_priv { - tCsrSummaryStatsInfo summary_stats; - tCsrGlobalClassAStatsInfo class_a_stats; - tCsrGlobalClassDStatsInfo class_d_stats; -}; - -/** - * hdd_statistics_cb() - "Get statistics" callback function - * @stats: statistics payload - * @context: opaque context originally passed to SME. HDD always passes - * a cookie for the request context - * - * Return: None - */ -static void hdd_statistics_cb(void *stats, void *context) -{ - struct osif_request *request; - struct hdd_statistics_priv *priv; - tCsrSummaryStatsInfo *summary_stats; - tCsrGlobalClassAStatsInfo *class_a_stats; - tCsrGlobalClassDStatsInfo *class_d_stats; - - request = osif_request_get(context); - if (!request) { - hdd_err("Obsolete request"); - return; - } - - priv = osif_request_priv(request); - - summary_stats = (tCsrSummaryStatsInfo *)stats; - priv->summary_stats = *summary_stats; - - class_a_stats = (tCsrGlobalClassAStatsInfo *)(summary_stats + 1); - priv->class_a_stats = *class_a_stats; - - class_d_stats = (tCsrGlobalClassDStatsInfo *)(class_a_stats + 1); - priv->class_d_stats = *class_d_stats; - - osif_request_complete(request); - osif_request_put(request); -} - -static int hdd_get_wlan_stats(struct hdd_adapter *adapter) -{ - int ret = 0; - void *cookie; - QDF_STATUS status; - struct osif_request *request; - struct hdd_station_ctx *sta_ctx; - struct hdd_statistics_priv *priv; - struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - static const struct osif_request_params params = { - .priv_size = sizeof(*priv), - .timeout_ms = WLAN_WAIT_TIME_STATS, - }; - - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - request = osif_request_alloc(¶ms); - if (!request) { - hdd_warn("request allocation failed"); - return -EINVAL; - } - - cookie = osif_request_cookie(request); - status = sme_get_statistics(hdd_ctx->mac_handle, eCSR_HDD, - SME_SUMMARY_STATS | - SME_GLOBAL_CLASSA_STATS | - SME_GLOBAL_CLASSD_STATS, - hdd_statistics_cb, - sta_ctx->conn_info.sta_id[0], - cookie, adapter->vdev_id); - - if (QDF_STATUS_SUCCESS != status) { - hdd_warn("Unable to retrieve SME statistics"); - goto put_request; - } - - /* request was sent -- wait for the response */ - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_err("Failed to wait for statistics, errno %d", ret); - goto put_request; - } - - /* update the adapter cache with the fresh results */ - priv = osif_request_priv(request); - adapter->hdd_stats.summary_stat = priv->summary_stats; - adapter->hdd_stats.class_a_stat = priv->class_a_stats; - adapter->hdd_stats.class_d_stat = priv->class_d_stats; - -put_request: - /* - * either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. - * regardless we are done with the request. - */ - osif_request_put(request); - return ret; -} -#endif /* QCA_SUPPORT_CP_STATS */ static int __iw_get_statistics(struct net_device *dev, struct iw_request_info *info, @@ -9940,7 +9735,15 @@ static int __iw_set_two_ints_getnone(struct net_device *dev, hdd_set_dump_dp_trace(value[1], value[2]); break; case WE_SET_MON_MODE_CHAN: - ret = wlan_hdd_set_mon_chan(adapter, value[1], value[2]); + if (value[1] > 256) + ret = wlan_hdd_set_mon_chan(adapter, value[1], + value[2]); + else + ret = wlan_hdd_set_mon_chan( + adapter, + wlan_reg_legacy_chan_to_freq( + hdd_ctx->pdev, value[1]), + value[2]); break; case WE_SET_WLAN_SUSPEND: ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev, @@ -10947,12 +10750,6 @@ static const struct iw_priv_args we_private_args[] = { 0, ""}, - /* handlers for sub-ioctl */ - {WE_IBSS_GET_PEER_INFO, - IW_PRIV_TYPE_INT | MAX_VAR_ARGS, - 0, - "ibssPeerInfo"}, - #ifdef TRACE_RECORD /* handlers for sub-ioctl */ {WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wmm.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wmm.c index 4a66bd9098734ad5ec0fd2a89054211fb68578c6..118415bf905ec39cf6105b8b4134e5f4360f7e81 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wmm.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wmm.c @@ -163,13 +163,11 @@ static void hdd_wmm_enable_tl_uapsd(struct hdd_wmm_qos_context *qos_context) &delayed_trgr_frm_int); /* everything is in place to notify TL */ status = - sme_enable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR(adapter))-> - conn_info.sta_id[0], ac_type, - ac->tspec.ts_info.tid, - ac->tspec.ts_info.up, - service_interval, suspension_interval, - direction, psb, adapter->vdev_id, - delayed_trgr_frm_int); + sme_enable_uapsd_for_ac(ac_type, ac->tspec.ts_info.tid, + ac->tspec.ts_info.up, + service_interval, suspension_interval, + direction, psb, adapter->vdev_id, + delayed_trgr_frm_int); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Failed to enable U-APSD for AC=%d", ac_type); @@ -204,10 +202,7 @@ static void hdd_wmm_disable_tl_uapsd(struct hdd_wmm_qos_context *qos_context) /* have we previously enabled UAPSD? */ if (ac->is_uapsd_info_valid == true) { - status = - sme_disable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR - (adapter))->conn_info.sta_id[0], - ac_type, adapter->vdev_id); + status = sme_disable_uapsd_for_ac(ac_type, adapter->vdev_id); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Failed to disable U-APSD for AC=%d", ac_type); @@ -1684,6 +1679,51 @@ QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter) return QDF_STATUS_SUCCESS; } +/** + * hdd_check_and_upgrade_udp_qos() - Check and upgrade the qos for UDP packets + * if the current set priority is below the + * pre-configured threshold for upgrade. + * @adapter: [in] pointer to the adapter context (Should not be invalid) + * @skb: [in] pointer to the packet to be transmitted + * @user_pri: [out] priority set for this packet + * + * This function checks if the packet is a UDP packet and upgrades its + * priority if its below the pre-configured upgrade threshold. + * The upgrade order is as below: + * BK -> BE -> VI -> VO + * + * Return: none + */ +static inline void +hdd_check_and_upgrade_udp_qos(struct hdd_adapter *adapter, + qdf_nbuf_t skb, + enum sme_qos_wmmuptype *user_pri) +{ + /* Upgrade UDP pkt priority alone */ + if (!(qdf_nbuf_is_ipv4_udp_pkt(skb) || qdf_nbuf_is_ipv6_udp_pkt(skb))) + return; + + switch (adapter->upgrade_udp_qos_threshold) { + case QCA_WLAN_AC_BK: + break; + case QCA_WLAN_AC_BE: + if (*user_pri == qca_wlan_ac_to_sme_qos(QCA_WLAN_AC_BK)) + *user_pri = qca_wlan_ac_to_sme_qos(QCA_WLAN_AC_BE); + + break; + case QCA_WLAN_AC_VI: + case QCA_WLAN_AC_VO: + if (*user_pri < + qca_wlan_ac_to_sme_qos(adapter->upgrade_udp_qos_threshold)) + *user_pri = qca_wlan_ac_to_sme_qos( + adapter->upgrade_udp_qos_threshold); + + break; + default: + break; + } +} + /** * hdd_wmm_classify_pkt() - Function which will classify an OS packet * into a WMM AC based on DSCP @@ -1805,6 +1845,12 @@ void hdd_wmm_classify_pkt(struct hdd_adapter *adapter, dscp = (tos >> 2) & 0x3f; *user_pri = adapter->dscp_to_up_map[dscp]; + /* + * Upgrade the priority, if the user priority of this packet is + * less than the configured threshold. + */ + hdd_check_and_upgrade_udp_qos(adapter, skb, user_pri); + #ifdef HDD_WMM_DEBUG hdd_debug("tos is %d, dscp is %d, up is %d", tos, dscp, *user_pri); #endif /* HDD_WMM_DEBUG */ @@ -1823,7 +1869,9 @@ static uint16_t __hdd_get_queue_index(uint16_t up) return hdd_linux_up_to_ac_map[up]; } -#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_HL_NETDEV_FLOW_CONTROL) +#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \ + defined(QCA_HL_NETDEV_FLOW_CONTROL) || \ + defined(QCA_LL_PDEV_TX_FLOW_CONTROL) /** * hdd_get_queue_index() - get queue index * @up: user priority @@ -1898,7 +1946,13 @@ static uint16_t hdd_wmm_select_queue(struct net_device *dev, return index; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) +uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) +{ + return hdd_wmm_select_queue(dev, skb); +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev, select_queue_fallback_t fallback) @@ -2152,8 +2206,6 @@ QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter, } status = sme_enable_uapsd_for_ac( - (WLAN_HDD_GET_STATION_CTX_PTR( - adapter))->conn_info.sta_id[0], SME_AC_VO, 7, 7, srv_value, sus_value, SME_QOS_WMM_TS_DIR_BOTH, 1, adapter->vdev_id, @@ -2177,8 +2229,6 @@ QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter, } status = sme_enable_uapsd_for_ac( - (WLAN_HDD_GET_STATION_CTX_PTR( - adapter))->conn_info.sta_id[0], SME_AC_VI, 5, 5, srv_value, sus_value, SME_QOS_WMM_TS_DIR_BOTH, 1, adapter->vdev_id, @@ -2202,8 +2252,6 @@ QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter, } status = sme_enable_uapsd_for_ac( - (WLAN_HDD_GET_STATION_CTX_PTR( - adapter))->conn_info.sta_id[0], SME_AC_BK, 2, 2, srv_value, sus_value, SME_QOS_WMM_TS_DIR_BOTH, 1, adapter->vdev_id, @@ -2227,8 +2275,6 @@ QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter, } status = sme_enable_uapsd_for_ac( - (WLAN_HDD_GET_STATION_CTX_PTR( - adapter))->conn_info.sta_id[0], SME_AC_BE, 3, 3, srv_value, sus_value, SME_QOS_WMM_TS_DIR_BOTH, 1, adapter->vdev_id, diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/ani_global.h b/drivers/staging/qcacld-3.0/core/mac/inc/ani_global.h index 81fd0a930615c183ab47dba43c5957fc7b836988..662b3dd287a4e8dfad8b1b74726955b779a9ba8a 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/ani_global.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/ani_global.h @@ -306,7 +306,7 @@ typedef struct { typedef struct sAniSirLim { /* //////////////////////////////////// TIMER RELATED START /////////////////////////////////////////// */ - tLimTimers limTimers; + tLimTimers lim_timers; /* / Flag to track if LIM timers are created or not */ uint32_t gLimTimersCreated; @@ -685,19 +685,22 @@ typedef struct sRrmContext { } tRrmContext, *tpRrmContext; /** - * enum auth_tx_ack_status - Indicate TX status of AUTH - * @LIM_AUTH_ACK_NOT_RCD : Default status while waiting for ack status. - * @LIM_AUTH_ACK_RCD_SUCCESS : Ack is received. - * @LIM_AUTH_ACK_RCD_FAILURE : No Ack received. + * enum tx_ack_status - Indicate TX status + * @LIM_ACK_NOT_RCD: Default status while waiting for ack status. + * @LIM_ACK_RCD_SUCCESS: Ack is received. + * @LIM_ACK_RCD_FAILURE: No Ack received. + * @LIM_TX_FAILED: Failed to TX * * Indicate if driver is waiting for ACK status of auth or ACK received for AUTH * OR NO ACK is received for the auth sent. */ -enum auth_tx_ack_status { - LIM_AUTH_ACK_NOT_RCD, - LIM_AUTH_ACK_RCD_SUCCESS, - LIM_AUTH_ACK_RCD_FAILURE, +enum tx_ack_status { + LIM_ACK_NOT_RCD, + LIM_ACK_RCD_SUCCESS, + LIM_ACK_RCD_FAILURE, + LIM_TX_FAILED, }; + /** * struct vdev_type_nss - vdev type nss structure * @sta: STA Nss value. @@ -746,6 +749,14 @@ struct mgmt_beacon_probe_filter { uint8_t sap_channel[WLAN_MAX_VDEVS]; }; +#ifdef FEATURE_ANI_LEVEL_REQUEST +struct ani_level_params { + void (*ani_level_cb)(struct wmi_host_ani_level_event *ani, uint8_t num, + void *context); + void *context; +}; +#endif + /** * struct mac_context - Global MAC context */ @@ -786,17 +797,21 @@ struct mac_context { struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_pdev *pdev; void (*chan_info_cb)(struct scan_chan_info *chan_info); + void (*del_peers_ind_cb)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); /* Based on INI parameter */ uint32_t dual_mac_feature_disable; enum country_src reg_hint_src; uint32_t rx_packet_drop_counter; - enum auth_tx_ack_status auth_ack_status; + enum tx_ack_status auth_ack_status; + enum tx_ack_status assoc_ack_status; uint8_t user_configured_nss; bool ignore_assoc_disallowed; uint32_t peer_rssi; uint32_t peer_txrate; uint32_t peer_rxrate; + uint32_t rx_retry_cnt; uint32_t rx_mc_bc_cnt; /* 11k Offload Support */ bool is_11k_offload_supported; @@ -824,6 +839,11 @@ struct mac_context { #endif bool obss_scan_offload; bool bcn_reception_stats; + csr_session_close_cb session_close_cb; + csr_roam_complete_cb session_roam_complete_cb; +#ifdef FEATURE_ANI_LEVEL_REQUEST + struct ani_level_params ani_params; +#endif }; #ifdef FEATURE_WLAN_TDLS diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/ani_system_defs.h b/drivers/staging/qcacld-3.0/core/mac/inc/ani_system_defs.h index f47ad239c020dd519afbc6e35e696d49d3c371f5..63a1b772d2a8a166b7cabfb221e91e16466be1d2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/ani_system_defs.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/ani_system_defs.h @@ -71,10 +71,8 @@ enum ani_akm_type { ANI_AKM_TYPE_FT_RSN_PSK, ANI_AKM_TYPE_RSN_PSK_SHA256, ANI_AKM_TYPE_RSN_8021X_SHA256, -#ifdef WLAN_FEATURE_SAE ANI_AKM_TYPE_SAE, ANI_AKM_TYPE_FT_SAE, -#endif ANI_AKM_TYPE_SUITEB_EAP_SHA256, ANI_AKM_TYPE_SUITEB_EAP_SHA384, ANI_AKM_TYPE_FT_SUITEB_EAP_SHA384, diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/mac_init_api.h b/drivers/staging/qcacld-3.0/core/mac/inc/mac_init_api.h index e4f5f7f574921d498b574b5db51b01edba635d2c..1190df8e306c55dbbf5122f997c1a3e624c9b3c0 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/mac_init_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/mac_init_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -101,4 +101,14 @@ QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle, */ QDF_STATUS mac_close(mac_handle_t mac_handle); +/** + * mac_register_sesssion_open_close_cb() - register open/close session cb + * @mac_handle: Opaque handle to the MAC context + * @close_session: callback to be registered with SME for closing the session + * @callback: Common callback to hdd for all modes + */ +void mac_register_sesssion_open_close_cb(mac_handle_t mac_handle, + csr_session_close_cb close_session, + csr_roam_complete_cb callback); + #endif /* __MAC_INIT_API_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h index 919a083dc7a30714167672b6cc788944a30562cd..dce79f3998d4578411a696c9e86103fe9fe8a570 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/qwlan_version.h @@ -31,10 +31,10 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 2 -#define QWLAN_VERSION_PATCH 05 -#define QWLAN_VERSION_EXTRA "C" -#define QWLAN_VERSION_BUILD 23 +#define QWLAN_VERSION_PATCH 022 +#define QWLAN_VERSION_EXTRA "B" +#define QWLAN_VERSION_BUILD 12 -#define QWLAN_VERSIONSTR "5.2.05.23C" +#define QWLAN_VERSIONSTR "5.2.022.12B" #endif /* QWLAN_VERSION_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h b/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h index a2280cfc97b6061c5935e1b5b113ea4d053067e3..bd90e119ce3fe2cc9f6cd918b175afeceba24a4c 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h @@ -48,6 +48,7 @@ struct mac_context; #include "wlan_policy_mgr_api.h" #include "wlan_tdls_public_structs.h" #include "qca_vendor.h" +#include "wlan_cp_stats_mc_defs.h" #define OFFSET_OF(structType, fldName) (&((structType *)0)->fldName) @@ -75,29 +76,24 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN]; #define MAXNUM_PERIODIC_TX_PTRNS 6 /* FW response timeout values in milli seconds */ -#define SIR_PEER_ASSOC_TIMEOUT (4000) /* 4 seconds */ +#define SIR_PEER_ASSOC_TIMEOUT (4000) /* 4 seconds */ + #ifdef FEATURE_RUNTIME_PM /* Add extra PMO_RESUME_TIMEOUT for runtime PM resume timeout */ -#define SIR_DELETE_STA_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) -#define SIR_VDEV_START_REQUEST_TIMEOUT (6000 + PMO_RESUME_TIMEOUT) -#define SIR_VDEV_STOP_REQUEST_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) -#define SIR_VDEV_DELETE_REQUEST_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) +#define SIR_DELETE_STA_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) #define SIR_VDEV_PLCY_MGR_TIMEOUT (2000 + PMO_RESUME_TIMEOUT) #else -#define SIR_DELETE_STA_TIMEOUT (4000) /* 4 seconds */ -#define SIR_VDEV_START_REQUEST_TIMEOUT (6000) -#define SIR_VDEV_STOP_REQUEST_TIMEOUT (4000) +#define SIR_DELETE_STA_TIMEOUT (4000) /* 4 seconds */ #define SIR_VDEV_PLCY_MGR_TIMEOUT (2000) -#define SIR_VDEV_DELETE_REQUEST_TIMEOUT (4000) #endif - /* This should not be greater than MAX_NUMBER_OF_CONC_CONNECTIONS */ #define MAX_VDEV_SUPPORTED 4 #define MAX_POWER_DBG_ARGS_SUPPORTED 8 #define QOS_MAP_MAX_EX 21 -#define QOS_MAP_LEN_MIN 16 +#define QOS_MAP_RANGE_NUM 8 +#define QOS_MAP_LEN_MIN (QOS_MAP_RANGE_NUM * 2) #define QOS_MAP_LEN_MAX \ (QOS_MAP_LEN_MIN + 2 * QOS_MAP_MAX_EX) #define NUM_CHAINS_MAX 2 @@ -327,6 +323,7 @@ struct fils_join_rsp_params { struct rrm_config_param { uint8_t rrm_enabled; + bool sap_rrm_enabled; uint8_t max_randn_interval; uint8_t rm_capability[RMENABLEDCAP_MAX_LEN]; }; @@ -389,7 +386,7 @@ struct register_mgmt_frame { typedef struct sSirSmeRsp { uint16_t messageType; /* eWNI_SME_*_RSP */ uint16_t length; - uint8_t sessionId; + uint8_t vdev_id; tSirResultCodes status_code; struct wlan_objmgr_psoc *psoc; } tSirSmeRsp, *tpSirSmeRsp; @@ -562,7 +559,9 @@ struct sir_vht_config { uint32_t vht_link_adapt:2; uint32_t rx_antpattern:1; uint32_t tx_antpattern:1; - uint32_t unused:2; + uint32_t extended_nss_bw_supp:2; + uint8_t max_nsts_total:2; + uint8_t vht_extended_nss_bw_cap:1; }; @@ -595,7 +594,7 @@ struct add_ie_params { struct start_bss_req { uint16_t messageType; /* eWNI_SME_START_BSS_REQ */ uint16_t length; - uint8_t sessionId; + uint8_t vdev_id; struct qdf_mac_addr bssid; struct qdf_mac_addr self_macaddr; uint16_t beaconInterval; @@ -605,7 +604,7 @@ struct start_bss_req { #endif enum bss_type bssType; tSirMacSSid ssId; - uint8_t channelId; + uint32_t oper_ch_freq; ePhyChanBondState cbMode; uint8_t vht_channel_width; uint8_t center_freq_seg0; @@ -690,12 +689,8 @@ struct bss_description { int8_t rssi; int8_t rssi_raw; int8_t sinr; - /* channelId what peer sent in beacon/probersp. */ - uint8_t channelId; - /* channelId on which we are parked at. */ - /* used only in scan case. */ - uint8_t channelIdSelf; - uint8_t sSirBssDescriptionRsvd[3]; + /* channel frequency what peer sent in beacon/probersp. */ + uint32_t chan_freq; /* Based on system time, not a relative time. */ uint64_t received_time; uint32_t parentTSF; @@ -706,17 +701,10 @@ struct bss_description { #ifdef FEATURE_WLAN_ESE uint16_t QBSSLoad_present; uint16_t QBSSLoad_avail; - /* To achieve 8-byte alignment with ESE enabled */ - uint32_t reservedPadding5; #endif /* whether it is from a probe rsp */ uint8_t fProbeRsp; - /* Actual channel the beacon/probe response was received on */ - uint8_t rx_channel; tSirMacSeqCtl seq_ctrl; - uint32_t WscIeLen; - uint8_t WscIeProbeRsp[WSCIE_PROBE_RSP_LEN]; - uint8_t reservedPadding4; uint32_t tsf_delta; struct scan_mbssid_info mbssid_info; #ifdef WLAN_FEATURE_FILS_SK @@ -762,8 +750,8 @@ struct start_bss_rsp { }; struct report_channel_list { - uint8_t numChannels; - uint8_t channelNumber[SIR_ESE_MAX_MEAS_IE_REQS]; + uint8_t num_channels; + uint32_t chan_freq_lst[SIR_ESE_MAX_MEAS_IE_REQS]; }; #ifdef FEATURE_OEM_DATA_SUPPORT @@ -844,7 +832,6 @@ typedef struct sAniGetTsmStatsReq { /* Common for all types are requests */ uint16_t msgType; /* message type is same as the request type */ uint16_t msgLen; /* length of the entire request */ - uint8_t staId; uint8_t tid; /* traffic id */ struct qdf_mac_addr bssId; void *tsmStatsCallback; @@ -863,10 +850,6 @@ typedef struct sAniGetTsmStatsRsp { */ uint8_t sessionId; uint32_t rc; /* success/failure */ - uint32_t staId; /* - * Per STA stats request must - * contain valid - */ struct qdf_mac_addr bssid; /* bssid to get the tsm stats for */ tAniTrafStrmMetrics tsmMetrics; void *tsmStatsReq; /* tsm stats request backup */ @@ -921,7 +904,7 @@ typedef struct sEsePEContext { struct join_req { uint16_t messageType; /* eWNI_SME_JOIN_REQ */ uint16_t length; - uint8_t sessionId; + uint8_t vdev_id; tSirMacSSid ssId; tSirMacAddr self_mac_addr; /* self Mac address */ enum bss_type bsstype; /* add new type for BT-AMP STA and AP Modules */ @@ -1025,7 +1008,7 @@ struct join_req { struct join_rsp { uint16_t messageType; /* eWNI_SME_JOIN_RSP */ uint16_t length; - uint8_t sessionId; /* Session ID */ + uint8_t vdev_id; /* Session ID */ tSirResultCodes status_code; tAniAuthType authType; uint32_t vht_channel_width; @@ -1065,6 +1048,9 @@ struct join_rsp { tDot11fIEVHTCaps vht_caps; tDot11fIEHTInfo ht_operation; tDot11fIEVHTOperation vht_operation; +#ifdef WLAN_FEATURE_11AX + tDot11fIEhe_op he_operation; +#endif tDot11fIEhs20vendor_ie hs20vendor_ie; bool is_fils_connection; uint16_t fils_seq_num; @@ -1075,7 +1061,6 @@ struct join_rsp { }; struct oem_channel_info { - uint8_t chan_id; uint32_t mhz; uint32_t band_center_freq1; uint32_t band_center_freq2; @@ -1195,7 +1180,7 @@ typedef enum eSirSmeStatusChangeCode { struct new_bss_info { struct qdf_mac_addr bssId; - uint8_t channelNumber; + uint32_t freq; uint8_t reserved; tSirMacSSid ssId; }; @@ -1203,8 +1188,6 @@ struct new_bss_info { struct ap_new_caps { uint16_t capabilityInfo; struct qdf_mac_addr bssId; - uint8_t channelId; - uint8_t reserved[3]; tSirMacSSid ssId; }; @@ -1245,7 +1228,7 @@ struct wm_status_change_ntf { uint16_t disassocReasonCode; /* none for eSIR_SME_LOST_LINK_WITH_PEER */ /* eSIR_SME_CHANNEL_SWITCH */ - uint8_t newChannelId; + uint32_t new_freq; /* eSIR_SME_JOINED_NEW_BSS */ struct new_bss_info newBssInfo; /* none for eSIR_SME_LEAVING_BSS */ @@ -1285,7 +1268,7 @@ struct disassoc_rsp { struct disassoc_ind { uint16_t messageType; /* eWNI_SME_DISASSOC_IND */ uint16_t length; - uint8_t sessionId; /* Session Identifier */ + uint8_t vdev_id; tSirResultCodes status_code; struct qdf_mac_addr bssid; struct qdf_mac_addr peer_macaddr; @@ -1299,7 +1282,7 @@ struct disassoc_ind { struct disassoc_cnf { uint16_t messageType; /* eWNI_SME_DISASSOC_CNF */ uint16_t length; - uint8_t sme_session_id; + uint8_t vdev_id; tSirResultCodes status_code; struct qdf_mac_addr bssid; struct qdf_mac_addr peer_macaddr; @@ -1325,12 +1308,24 @@ struct sir_sme_discon_done_ind { struct deauth_req { uint16_t messageType; /* eWNI_SME_DEAUTH_REQ */ uint16_t length; - uint8_t sessionId; /* Session ID */ + uint8_t vdev_id; /* Session ID */ struct qdf_mac_addr bssid; /* AP BSSID */ struct qdf_mac_addr peer_macaddr; uint16_t reasonCode; }; +/** + * struct deauth_retry_params - deauth retry params + * @peer_mac: peer mac + * @reason_code: reason for disconnect indication + * @retry_cnt: retry count + */ +struct deauth_retry_params { + struct qdf_mac_addr peer_macaddr; + uint16_t reason_code; + uint8_t retry_cnt; +}; + /* / Definition for Deauthetication response */ struct deauth_rsp { uint16_t messageType; /* eWNI_SME_DEAUTH_RSP */ @@ -1344,7 +1339,7 @@ struct deauth_rsp { struct deauth_ind { uint16_t messageType; /* eWNI_SME_DEAUTH_IND */ uint16_t length; - uint8_t sessionId; /* Added for BT-AMP */ + uint8_t vdev_id; tSirResultCodes status_code; struct qdf_mac_addr bssid; /* AP BSSID */ struct qdf_mac_addr peer_macaddr; @@ -1359,7 +1354,7 @@ struct deauth_ind { struct deauth_cnf { uint16_t messageType; /* eWNI_SME_DEAUTH_CNF */ uint16_t length; - uint8_t sme_session_id; + uint8_t vdev_id; tSirResultCodes status_code; struct qdf_mac_addr bssid; struct qdf_mac_addr peer_macaddr; @@ -1380,7 +1375,7 @@ struct switch_channel_ind { uint16_t messageType; /* eWNI_SME_SWITCH_CHL_IND */ uint16_t length; uint8_t sessionId; - uint16_t newChannelId; + uint32_t freq; struct ch_params chan_params; struct qdf_mac_addr bssid; /* BSSID */ QDF_STATUS status; @@ -1408,7 +1403,7 @@ struct missed_beacon_ind { struct set_context_req { uint16_t messageType; /* eWNI_SME_SET_CONTEXT_REQ */ uint16_t length; - uint8_t sessionId; /* Session ID */ + uint8_t vdev_id; /* vdev ID */ struct qdf_mac_addr peer_macaddr; struct qdf_mac_addr bssid; /* BSSID */ tSirKeyMaterial keyMaterial; @@ -1424,64 +1419,11 @@ struct set_context_rsp { struct qdf_mac_addr peer_macaddr; }; -/*******************PE Statistics*************************/ - -/* - * tpAniGetPEStatsReq is tied to - * for SME ==> PE eWNI_SME_GET_STATISTICS_REQ msgId and - * for PE ==> HAL SIR_HAL_GET_STATISTICS_REQ msgId - */ -typedef struct sAniGetPEStatsReq { - /* Common for all types are requests */ - uint16_t msgType; /* message type is same as the request type */ - uint16_t msgLen; /* length of the entire request */ - uint32_t staId; /* Per STA stats request must contain valid */ - /* categories of stats requested. look at ePEStatsMask */ - uint32_t statsMask; - uint8_t sessionId; -} tAniGetPEStatsReq, *tpAniGetPEStatsReq; - -/* - * tpAniGetPEStatsRsp is tied to - * for PE ==> SME eWNI_SME_GET_STATISTICS_RSP msgId and - * for HAL ==> PE SIR_HAL_GET_STATISTICS_RSP msgId - */ -typedef struct sAniGetPEStatsRsp { - /* Common for all types are responses */ - uint16_t msgType; /* message type is same as the request type */ - /* length of the entire request, includes the pStatsBuf length too */ - uint16_t msgLen; - uint8_t sessionId; - uint32_t rc; /* success/failure */ - uint32_t staId; /* Per STA stats request must contain valid */ - /* categories of stats requested. look at ePEStatsMask */ - uint32_t statsMask; - /* void *pStatsBuf; */ - /* - * The Stats buffer starts here and can be an aggregate of more than one - * statistics structure depending on statsMask. The void pointer - * "pStatsBuf" is commented out intentionally and the src code that uses - * this structure should take that into account. - */ -} tAniGetPEStatsRsp, *tpAniGetPEStatsRsp; - -typedef struct sAniGetRssiReq { - /* Common for all types are requests */ - uint16_t msgType; /* message type is same as the request type */ - uint16_t msgLen; /* length of the entire request */ - uint8_t sessionId; - uint8_t staId; - int8_t lastRSSI; /* in case of error, return last RSSI */ - void *rssiCallback; - void *pDevContext; /* device context */ -} tAniGetRssiReq, *tpAniGetRssiReq; - typedef struct sAniGetSnrReq { /* Common for all types are requests */ uint16_t msgType; /* message type is same as the request type */ uint16_t msgLen; /* length of the entire request */ uint8_t sessionId; - uint8_t staId; void *snrCallback; void *pDevContext; /* device context */ int8_t snr; @@ -1517,29 +1459,7 @@ typedef struct sAniTXFailMonitorInd { void *txFailIndCallback; } tAniTXFailMonitorInd, *tpAniTXFailMonitorInd; -#ifndef QCA_SUPPORT_CP_STATS -/** - * enum tx_rate_info - tx_rate flags - * @TX_RATE_LEGACY: Legacy rates - * @TX_RATE_HT20: HT20 rates - * @TX_RATE_HT40: HT40 rates - * @TX_RATE_SGI: Rate with Short guard interval - * @TX_RATE_LGI: Rate with Long guard interval - * @TX_RATE_VHT20: VHT 20 rates - * @TX_RATE_VHT40: VHT 40 rates - * @TX_RATE_VHT80: VHT 80 rates - */ -enum tx_rate_info { - TX_RATE_LEGACY = 0x1, - TX_RATE_HT20 = 0x2, - TX_RATE_HT40 = 0x4, - TX_RATE_SGI = 0x8, - TX_RATE_LGI = 0x10, - TX_RATE_VHT20 = 0x20, - TX_RATE_VHT40 = 0x40, - TX_RATE_VHT80 = 0x80 -}; -#endif + /**********************PE Statistics end*************************/ typedef struct sSirP2PNoaAttr { @@ -1698,8 +1618,8 @@ typedef struct sSirAggrQosRsp { struct qos_map_set { uint8_t present; uint8_t num_dscp_exceptions; - uint8_t dscp_exceptions[21][2]; - uint8_t dscp_range[8][2]; + uint8_t dscp_exceptions[QOS_MAP_MAX_EX][2]; + uint8_t dscp_range[QOS_MAP_RANGE_NUM][2]; }; typedef struct sSmeIbssPeerInd { @@ -1708,14 +1628,12 @@ typedef struct sSmeIbssPeerInd { uint8_t sessionId; struct qdf_mac_addr peer_addr; - uint16_t staId; /* Beacon will be appended for new Peer indication. */ } tSmeIbssPeerInd, *tpSmeIbssPeerInd; struct ibss_peer_inactivity_ind { uint8_t bss_idx; - uint8_t staIdx; struct qdf_mac_addr peer_addr; }; @@ -1878,7 +1796,7 @@ typedef struct sSirAPWPSIEs { struct update_config { uint16_t messageType; /* eWNI_SME_UPDATE_CONFIG */ uint16_t length; - uint8_t sme_session_id; + uint8_t vdev_id; uint16_t capab; uint32_t value; }; @@ -1897,14 +1815,14 @@ enum sir_update_session_param_type { * struct sir_update_session_param * @message_type: SME message type * @length: size of struct sir_update_session_param - * @session_id: Session ID + * @vdev_id: vdev ID * @param_type: parameter to be updated * @param_val: Parameter value to update */ struct sir_update_session_param { uint16_t message_type; uint16_t length; - uint8_t session_id; + uint8_t vdev_id; uint32_t param_type; uint32_t param_val; }; @@ -1913,13 +1831,13 @@ struct sir_update_session_param { * struct sir_set_he_bss_color * @message_type: SME message type * @length: size of struct sir_set_he_bss_color - * @session_id: Session ID + * @vdev_id: vdev ID * @bss_color: bss color value */ struct sir_set_he_bss_color { uint16_t message_type; uint16_t length; - uint8_t session_id; + uint8_t vdev_id; uint8_t bss_color; }; @@ -2047,7 +1965,7 @@ enum rxmgmt_flags { typedef struct sSirSmeMgmtFrameInd { uint16_t frame_len; - uint32_t rxChan; + uint32_t rx_freq; uint8_t sessionId; uint8_t frameType; int8_t rxRssi; @@ -2148,7 +2066,7 @@ typedef struct { uint8_t mcencryption; tAniEdType gp_mgmt_cipher_suite; uint8_t ChannelCount; - uint8_t ChannelCache[SIR_ROAM_MAX_CHANNELS]; + uint32_t chan_freq_cache[SIR_ROAM_MAX_CHANNELS]; #ifdef WLAN_FEATURE_11W bool mfp_enabled; #endif @@ -2198,6 +2116,9 @@ typedef enum { * @bg_scan_bad_rssi_thresh: Bad RSSI threshold to perform bg scan. * @bad_rssi_thresh_offset_2g: Offset from Bad RSSI threshold for 2G to 5G Roam * @bg_scan_client_bitmap: Bitmap to identify the client scans to snoop. + * @roam_data_rssi_threshold_triggers: Bad data RSSI threshold to roam + * @roam_data_rssi_threshold: Bad data RSSI threshold to roam + * @rx_data_inactivity_time: rx duration to check data RSSI * * This structure holds all the key parameters related to * initial connection and also roaming connections. @@ -2231,6 +2152,9 @@ struct roam_ext_params { int8_t bg_scan_bad_rssi_thresh; uint8_t roam_bad_rssi_thresh_offset_2g; uint32_t bg_scan_client_bitmap; + uint32_t roam_data_rssi_threshold_triggers; + int32_t roam_data_rssi_threshold; + uint32_t rx_data_inactivity_time; }; /** @@ -2345,7 +2269,7 @@ struct roam_offload_scan_req { struct pmkid_mode_bits pmkid_modes; bool is_adaptive_11r_connection; bool is_sae_single_pmk; - + bool enable_ft_im_roaming; /* Idle/Disconnect roam parameters */ struct wmi_idle_roam_params idle_roam_params; struct wmi_disconnect_roam_params disconnect_roam_params; @@ -2390,7 +2314,7 @@ struct roam_offload_scan_req { uint32_t roam_inactive_data_packet_count; uint32_t roam_scan_period_after_inactivity; uint32_t btm_query_bitmask; - struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_TRIGGERS]; + struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_MIN_RSSI]; struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS]; uint32_t full_roam_scan_period; }; @@ -2449,8 +2373,8 @@ struct sir_wifi_start_log { */ struct sir_pcl_list { uint32_t pcl_len; - uint8_t pcl_list[128]; - uint8_t weight_list[128]; + uint8_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; }; /** @@ -2466,12 +2390,12 @@ struct sir_pcl_list { * @weight_list: Weights assigned by policy manager */ struct sir_pcl_chan_weights { - uint8_t pcl_list[128]; + uint8_t pcl_list[NUM_CHANNELS]; uint32_t pcl_len; - uint8_t saved_chan_list[128]; + uint8_t saved_chan_list[NUM_CHANNELS]; uint32_t saved_num_chan; - uint8_t weighed_valid_list[128]; - uint8_t weight_list[128]; + uint8_t weighed_valid_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; }; /** @@ -2588,7 +2512,7 @@ typedef struct sAniHandoffReq { uint16_t msgLen; /* length of the entire request */ uint8_t sessionId; uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint8_t channel; + uint32_t ch_freq; uint8_t handoff_src; } tAniHandoffReq, *tpAniHandoffReq; @@ -2628,18 +2552,20 @@ typedef struct sSirScanOffloadEvent { /** * struct sSirUpdateChanParam - channel parameters - * @chanId: ID of the channel + * @freq: Frequency of the channel * @pwr: power level * @dfsSet: is dfs supported or not * @half_rate: is the channel operating at 10MHz * @quarter_rate: is the channel operating at 5MHz + * @nan_disabled: is NAN disabled on @freq */ typedef struct sSirUpdateChanParam { - uint8_t chanId; + uint32_t freq; uint8_t pwr; bool dfsSet; bool half_rate; bool quarter_rate; + bool nan_disabled; } tSirUpdateChanParam, *tpSirUpdateChanParam; typedef struct sSirUpdateChan { @@ -2669,46 +2595,6 @@ struct link_speed_info { uint32_t estLinkSpeed; /* Linkspeed from firmware */ }; -/** - * struct sir_peer_info_req - peer info request struct - * @peer_macaddr: MAC address - * @sessionid: vdev id - * - * peer info request message's struct - */ -struct sir_peer_info_req { - struct qdf_mac_addr peer_macaddr; - uint8_t sessionid; -}; - -/** - * struct sir_peer_info - peer information struct - * @peer_macaddr: MAC address - * @rssi: rssi - * @tx_rate: last tx rate - * @rx_rate: last rx rate - * - * a station's information - */ -struct sir_peer_info { - struct qdf_mac_addr peer_macaddr; - int8_t rssi; - uint32_t tx_rate; - uint32_t rx_rate; -}; - -/** - * struct sir_peer_info_resp - all peers information struct - * @count: peer's number - * @info: peer information - * - * all station's information - */ -struct sir_peer_info_resp { - uint8_t count; - struct sir_peer_info info[0]; -}; - /** * struct sir_peer_info_ext_req - peer info request struct * @peer_macaddr: MAC address @@ -2772,17 +2658,6 @@ struct sir_peer_info_ext_resp { struct sir_peer_info_ext info[0]; }; -/** - * @sta_num: number of peer station which has valid info - * @info: peer information - * - * all SAP peer station's information retrieved - */ -struct sir_peer_sta_info { - uint8_t sta_num; - struct sir_peer_info info[MAX_PEER_STA]; -}; - /** * @sta_num: number of peer station which has valid info * @info: peer extended information @@ -2828,7 +2703,7 @@ typedef struct sSirDelPeriodicTxPtrn { *--------------------------------------------------------------------------*/ typedef struct { bool allPeerInfoReqd; /* If set, all IBSS peers stats are reported */ - uint8_t staIdx; /* If allPeerInfoReqd is not set, only stats */ + struct qdf_mac_addr peer_mac; /* of peer with staIdx is reported */ } tSirIbssGetPeerInfoReqParams, *tpSirIbssGetPeerInfoReqParams; @@ -2922,7 +2797,7 @@ typedef struct sSirSmeDfsEventInd { typedef struct sSirChanChangeRequest { uint16_t messageType; uint16_t messageLen; - uint8_t targetChannel; + uint32_t target_chan_freq; uint8_t sec_ch_offset; enum phy_ch_width ch_width; uint8_t center_freq_seg_0; @@ -2938,7 +2813,7 @@ typedef struct sSirChanChangeRequest { typedef struct sSirChanChangeResponse { uint8_t sessionId; - uint8_t newChannelNumber; + uint32_t new_op_freq; uint8_t channelChangeStatus; } tSirChanChangeResponse, *tpSirChanChangeResponse; @@ -2965,7 +2840,7 @@ typedef enum tUpdateIEsType { /* Modify particular IE in addition IE for prob resp Bcn */ typedef struct sSirModifyIE { struct qdf_mac_addr bssid; - uint16_t smeSessionId; + uint16_t vdev_id; bool notify; uint8_t ieID; uint8_t ieIDLen; /*ie length as per spec */ @@ -2991,7 +2866,7 @@ typedef struct sSirModifyIEsInd { /* Message format for Update IE message sent to PE */ typedef struct sSirUpdateIE { struct qdf_mac_addr bssid; - uint16_t smeSessionId; + uint16_t vdev_id; bool append; bool notify; uint16_t ieBufferlength; @@ -3010,7 +2885,7 @@ typedef struct sSirUpdateIEsInd { typedef struct sSirDfsCsaIeRequest { uint16_t msgType; uint16_t msgLen; - uint8_t targetChannel; + uint32_t target_chan_freq; uint8_t csaIeRequired; uint8_t bssid[QDF_MAC_ADDR_SIZE]; struct ch_params ch_params; @@ -3143,11 +3018,14 @@ struct roam_offload_synch_ind { struct qdf_mac_addr src_mac; uint16_t hlp_data_len; uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN]; + bool is_ft_im_roam; + enum wlan_phymode phy_mode; /*phy mode sent by fw */ }; #ifdef WLAN_FEATURE_ROAM_OFFLOAD struct handoff_failure_ind { uint8_t vdev_id; + struct qdf_mac_addr bssid; }; struct roam_offload_synch_fail { @@ -3565,6 +3443,8 @@ struct sir_set_vdev_ies_per_band { uint16_t msg_type; uint16_t len; uint32_t vdev_id; + uint16_t dot11_mode; + enum QDF_OPMODE device_mode; }; /** @@ -3694,6 +3574,7 @@ struct wifi_interface_info { uint8_t apCountryStr[CFG_COUNTRY_CODE_LEN]; /* country string for this association */ uint8_t countryStr[CFG_COUNTRY_CODE_LEN]; + uint8_t time_slice_duty_cycle; }; /** @@ -4465,14 +4346,14 @@ struct chip_pwr_save_fail_detected_params { * struct hdd_default_scan_ie - HDD default scan IE structure * @message_type: message type to be set with eWNI_SME_DEFAULT_SCAN_IE * @length: length of the struct hdd_default_scan_ie - * @session_id: Session Id + * @vdev_id: vdev_id * @ie_len: Default scan IE length * @ie_data: Pointer to default scan IE data */ struct hdd_default_scan_ie { uint16_t message_type; uint16_t length; - uint16_t session_id; + uint16_t vdev_id; uint16_t ie_len; uint8_t ie_data[MAX_DEFAULT_SCAN_IE_LEN]; }; @@ -4532,12 +4413,14 @@ struct cfg_action_frm_tb_ppdu { * @msgType: nss update msg type * @msgLen: length of the msg * @new_nss: new spatial stream value + * @ch_width: channel width - optional * @vdev_id: session id */ struct sir_nss_update_request { uint16_t msgType; uint16_t msgLen; uint8_t new_nss; + uint8_t ch_width; uint32_t vdev_id; }; @@ -4578,30 +4461,18 @@ struct sir_qos_params { uint8_t cwmax; }; -/** - * enum powersave_qpower_mode: QPOWER modes - * @QPOWER_DISABLED: Qpower is disabled - * @QPOWER_ENABLED: Qpower is enabled - * @QPOWER_DUTY_CYCLING: Qpower is enabled with duty cycling - */ -enum powersave_qpower_mode { - QPOWER_DISABLED = 0, - QPOWER_ENABLED = 1, - QPOWER_DUTY_CYCLING = 2 -}; - /** * struct sir_sme_ext_change_chan_req - channel change request * @message_type: message id * @length: msg length * @new_channel: new channel - * @session_id: session id + * @vdev_id: vdev id */ struct sir_sme_ext_cng_chan_req { uint16_t message_type; /* eWNI_SME_EXT_CHANGE_CHANNEL */ uint16_t length; uint32_t new_channel; - uint8_t session_id; + uint8_t vdev_id; }; #define IGNORE_NUD_FAIL 0 @@ -4612,11 +4483,11 @@ struct sir_sme_ext_cng_chan_req { /** * struct sir_sme_ext_change_chan_ind. * @session_id: session id - * @new_channel: new channel to change + * @new_chan_freq: new channel frequency to change to */ struct sir_sme_ext_cng_chan_ind { uint8_t session_id; - uint8_t new_channel; + uint32_t new_chan_freq; }; /** @@ -4686,6 +4557,7 @@ struct adaptive_dwelltime_params { */ struct csa_offload_params { uint8_t channel; + uint32_t csa_chan_freq; uint8_t switch_mode; uint8_t sec_chan_offset; uint8_t new_ch_width; @@ -4729,11 +4601,11 @@ struct sme_obss_ht40_scanind_msg { * @obss_active_total_per_channel: total active scan time per channel * @bsswidth_ch_trans_delay: OBSS transition delay time * @obss_activity_threshold: OBSS activity threshold - * @self_sta_id: self sta identification + * @self_sta_idx: self sta identification * @bss_id: BSS index * @fortymhz_intolerent: Ht40mhz intolerance * @channel_count: channel count - * @channels: channel information + * @chan_freq_list: List of channel frequencies in MHz * @current_operatingclass: operating class * @iefield_len: ie's length * @iefiled: ie's information @@ -4755,7 +4627,7 @@ struct obss_ht40_scanind { uint8_t bss_id; uint8_t fortymhz_intolerent; uint8_t channel_count; - uint8_t channels[SIR_ROAM_MAX_CHANNELS]; + uint32_t chan_freq_list[SIR_ROAM_MAX_CHANNELS]; uint8_t current_operatingclass; uint16_t iefield_len; uint8_t iefield[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; @@ -4814,93 +4686,6 @@ struct sir_apf_get_offload { uint32_t max_bytes_for_apf_inst; }; -#ifndef QCA_SUPPORT_CP_STATS -/** - * struct sir_wake_lock_stats - wake lock stats structure - * @wow_unspecified_wake_up_count: number of non-wow related wake ups - * @wow_ucast_wake_up_count: Unicast wakeup count - * @wow_bcast_wake_up_count: Broadcast wakeup count - * @wow_ipv4_mcast_wake_up_count: ipv4 multicast wakeup count - * @wow_ipv6_mcast_wake_up_count: ipv6 multicast wakeup count - * @wow_ipv6_mcast_ra_stats: ipv6 multicast ra stats - * @wow_ipv6_mcast_ns_stats: ipv6 multicast ns stats - * @wow_ipv6_mcast_na_stats: ipv6 multicast na stats - * @wow_icmpv4_count: ipv4 icmp packet count - * @wow_icmpv6_count: ipv6 icmp packet count - * @wow_rssi_breach_wake_up_count: rssi breach wakeup count - * @wow_low_rssi_wake_up_count: low rssi wakeup count - * @wow_gscan_wake_up_count: gscan wakeup count - * @wow_pno_complete_wake_up_count: pno complete wakeup count - * @wow_pno_match_wake_up_count: pno match wakeup count - * @wow_oem_response_wake_up_count: oem response wakeup count - * @pwr_save_fail_detected: pwr save fail detected wakeup count - */ -struct sir_wake_lock_stats { - uint32_t wow_unspecified_wake_up_count; - uint32_t wow_ucast_wake_up_count; - uint32_t wow_bcast_wake_up_count; - uint32_t wow_ipv4_mcast_wake_up_count; - uint32_t wow_ipv6_mcast_wake_up_count; - uint32_t wow_ipv6_mcast_ra_stats; - uint32_t wow_ipv6_mcast_ns_stats; - uint32_t wow_ipv6_mcast_na_stats; - uint32_t wow_icmpv4_count; - uint32_t wow_icmpv6_count; - uint32_t wow_rssi_breach_wake_up_count; - uint32_t wow_low_rssi_wake_up_count; - uint32_t wow_gscan_wake_up_count; - uint32_t wow_pno_complete_wake_up_count; - uint32_t wow_pno_match_wake_up_count; - uint32_t wow_oem_response_wake_up_count; - uint32_t pwr_save_fail_detected; -}; - -/** - * struct sir_vdev_wow_stats - container for per vdev wow related stat counters - * @ucast: Unicast wakeup count - * @bcast: Broadcast wakeup count - * @ipv4_mcast: ipv4 multicast wakeup count - * @ipv6_mcast: ipv6 multicast wakeup count - * @ipv6_mcast_ra: ipv6 multicast ra stats - * @ipv6_mcast_ns: ipv6 multicast ns stats - * @ipv6_mcast_na: ipv6 multicast na stats - * @icmpv4: ipv4 icmp packet count - * @icmpv6: ipv6 icmp packet count - * @rssi_breach: rssi breach wakeup count - * @low_rssi: low rssi wakeup count - * @gscan: gscan wakeup count - * @pno_complete: pno complete wakeup count - * @pno_match: pno match wakeup count - * @oem_response: oem response wakeup count - * @scan_11d: 11d scan wakeup count - * @motion_detect: motion detection wakeup count - * @motion_detect_bl: motion detection baselining wakeup count - */ -struct sir_vdev_wow_stats { - uint32_t ucast; - uint32_t bcast; - uint32_t ipv4_mcast; - uint32_t ipv6_mcast; - uint32_t ipv6_mcast_ra; - uint32_t ipv6_mcast_ns; - uint32_t ipv6_mcast_na; - uint32_t icmpv4; - uint32_t icmpv6; - uint32_t rssi_breach; - uint32_t low_rssi; - uint32_t gscan; - uint32_t pno_complete; - uint32_t pno_match; - uint32_t oem_response; - uint32_t pwr_save_fail_detected; - uint32_t scan_11d; -#ifdef WLAN_FEATURE_MOTION_DETECTION - uint32_t motion_detect; - uint32_t motion_detect_bl; -#endif /* WLAN_FEATURE_MOTION_DETECTION */ -}; -#endif - #ifdef WLAN_FEATURE_NAN #define IFACE_NAME_SIZE 64 @@ -5339,56 +5124,6 @@ struct sme_ndp_peer_ind { }; #endif /* WLAN_FEATURE_NAN */ -/** - * struct sir_set_tx_rx_aggregation_size - sets tx rx aggregation size - * @vdev_id: vdev id of the session - * @aggr_type: TX Aggregation Type (0=A-MPDU, 1=A-MSDU) - * @tx_aggregation_size: Tx aggregation size - * @tx_aggregation_size_be: Tx aggregation size for be queue - * @tx_aggregation_size_bk: Tx aggregation size for bk queue - * @tx_aggregation_size_vi: Tx aggregation size for vi queue - * @tx_aggregation_size_vo: Tx aggregation size for vo queue - * @rx_aggregation_size: Rx aggregation size - */ -struct sir_set_tx_rx_aggregation_size { - uint8_t vdev_id; - wmi_vdev_custom_aggr_type_t aggr_type; - uint32_t tx_aggregation_size; - uint32_t tx_aggregation_size_be; - uint32_t tx_aggregation_size_bk; - uint32_t tx_aggregation_size_vi; - uint32_t tx_aggregation_size_vo; - uint32_t rx_aggregation_size; -}; - -/** - * struct sir_set_tx_sw_retry_threshold - set sw retry threshold - * @vdev_id: vdev id of the session - * @tx_aggr_sw_retry_threshold_be: aggr sw retry threshold for BE - * @tx_aggr_sw_retry_threshold_bk: aggr sw retry threshold for BK - * @tx_aggr_sw_retry_threshold_vi: aggr sw retry threshold for VI - * @tx_aggr_sw_retry_threshold_vo: aggr sw retry threshold for VO - * @tx_aggr_sw_retry_threshold: aggr sw retry threshold - * @tx_non_aggr_sw_retry_threshold_be: non aggr sw retry threshold for BE - * @tx_non_aggr_sw_retry_threshold_bk: non aggr sw retry threshold for BK - * @tx_non_aggr_sw_retry_threshold_vi: non aggr sw retry threshold for VI - * @tx_non_aggr_sw_retry_threshold_vo: non aggr sw retry threshold for VO - * @tx_non_aggr_sw_retry_threshold: non aggr sw retry threshold - */ -struct sir_set_tx_sw_retry_threshold { - uint8_t vdev_id; - uint32_t tx_aggr_sw_retry_threshold_be; - uint32_t tx_aggr_sw_retry_threshold_bk; - uint32_t tx_aggr_sw_retry_threshold_vi; - uint32_t tx_aggr_sw_retry_threshold_vo; - uint32_t tx_aggr_sw_retry_threshold; - uint32_t tx_non_aggr_sw_retry_threshold_be; - uint32_t tx_non_aggr_sw_retry_threshold_bk; - uint32_t tx_non_aggr_sw_retry_threshold_vi; - uint32_t tx_non_aggr_sw_retry_threshold_vo; - uint32_t tx_non_aggr_sw_retry_threshold; -}; - /** * struct sir_p2p_lo_start - p2p listen offload start * @vdev_id: vdev identifier @@ -5443,7 +5178,7 @@ struct sir_mac_pwr_dbg_cmd { * struct sme_send_disassoc_frm_req - send disassoc request frame * @msg_type: message type * @length: length of message - * @session_id: session id + * @vdev_id: vdev id * @peer_mac: peer mac address * @reason: reason for disassoc * @wait_for_ack: wait for acknowledgment @@ -5451,7 +5186,7 @@ struct sir_mac_pwr_dbg_cmd { struct sme_send_disassoc_frm_req { uint16_t msg_type; uint16_t length; - uint8_t session_id; + uint8_t vdev_id; uint8_t peer_mac[6]; uint16_t reason; uint8_t wait_for_ack; @@ -5462,14 +5197,14 @@ struct sir_mac_pwr_dbg_cmd { * policy * @msg_type: message id * @msg_len: message length - * @sme_session_id: sme session id + * @vdev_id: vdev id * @ie: vendor ie * @access_policy: access policy for vendor ie */ struct sme_update_access_policy_vendor_ie { uint16_t msg_type; uint16_t length; - uint32_t sme_session_id; + uint32_t vdev_id; uint8_t ie[WLAN_MAX_IE_LEN + 2]; uint8_t access_policy; }; @@ -5670,6 +5405,7 @@ struct ppet_hdr { #define HE_CH_WIDTH_COMBINE(b0, b1, b2, b3, b4, b5, b6) \ ((uint8_t)(b0) | ((b1) << 1) | ((b2) << 2) | ((b3) << 3) | \ ((b4) << 4) | ((b5) << 5) | ((b6) << 6)) +#define HE_CH_WIDTH_CLR_BIT(ch_wd, bit) (((ch_wd) >> (bit)) & ~1) /* * MCS values are interpreted as in IEEE 11ax-D1.4 spec onwards @@ -5697,6 +5433,14 @@ struct ppet_hdr { #define HE_MCS_0_11 0x2 #define HE_MCS_DISABLE 0x3 +#define HE_6G_MIN_MPDU_START_SAPCE_BIT_POS 0 +#define HE_6G_MAX_AMPDU_LEN_EXP_BIT_POS 3 +#define HE_6G_MAX_MPDU_LEN_BIT_POS 6 +#define HE_6G_SMPS_BIT_POS 9 +#define HE_6G_RD_RESP_BIT_POS 11 +#define HE_6G_RX_ANT_PATTERN_BIT_POS 12 +#define HE_6G_TX_ANT_PATTERN_BIT_POS 13 + /* * Following formuala has been arrived at using karnaugh map and unit tested * with sample code. Take MCS for each NSS as 2 bit value first and solve for @@ -5908,6 +5652,10 @@ struct sir_peer_set_rx_blocksize { * @retry_delay: Retry delay received during last rejection in ms * @ expected_rssi: RSSI at which STA can initate * @time_during_rejection: Timestamp during last rejection in millisec + * @reject_reason: reason to add the BSSID to BLM + * @source: Source of adding the BSSID to BLM + * @original_timeout: original timeout sent by the AP + * @received_time: Timestamp when the AP was added to the Blacklist */ struct sir_rssi_disallow_lst { qdf_list_node_t node; @@ -5915,6 +5663,10 @@ struct sir_rssi_disallow_lst { uint32_t retry_delay; int8_t expected_rssi; qdf_time_t time_during_rejection; + enum blm_reject_ap_reason reject_reason; + enum blm_reject_ap_source source; + uint32_t original_timeout; + qdf_time_t received_time; }; /** @@ -5993,14 +5745,14 @@ struct sir_sae_info { * struct sir_sae_msg - SAE msg used for message posting * @message_type: message type * @length: message length - * @session_id: SME session id + * @vdev_id: vdev id * @sae_status: SAE status, 0: Success, Non-zero: Failure. * @peer_mac_addr: peer MAC address */ struct sir_sae_msg { uint16_t message_type; uint16_t length; - uint16_t session_id; + uint16_t vdev_id; uint8_t sae_status; tSirMacAddr peer_mac_addr; }; @@ -6008,23 +5760,37 @@ struct sir_sae_msg { /** * struct set_pcl_req - Request message to set the PCL * @chan_weights: PCL channel weights - * @band: Supported band + * @band_mask: Supported band mask */ struct set_pcl_req { struct wmi_pcl_chan_weights chan_weights; - enum band_info band; + uint32_t band_mask; }; +#ifdef WLAN_FEATURE_MOTION_DETECTION /** * struct sir_md_evt - motion detection event status * @vdev_id: vdev id * @status: md event status */ -#ifdef WLAN_FEATURE_MOTION_DETECTION struct sir_md_evt { uint8_t vdev_id; uint32_t status; }; + +/** + * struct sir_md_bl_evt - motion detection baseline event values + * @vdev_id: vdev id + * @bl_baseline_value: baseline correlation value calculated during baselining + * @bl_max_corr_reserved: max corr value obtained during baselining phase in % + * @bl_min_corr_reserved: min corr value obtained during baselining phase in % + */ +struct sir_md_bl_evt { + uint8_t vdev_id; + uint32_t bl_baseline_value; + uint32_t bl_max_corr_reserved; + uint32_t bl_min_corr_reserved; +}; #endif /* WLAN_FEATURE_MOTION_DETECTION */ #ifdef WLAN_MWS_INFO_DEBUGFS @@ -6038,4 +5804,18 @@ struct sir_get_mws_coex_info { uint32_t cmd_id; }; #endif /* WLAN_MWS_INFO_DEBUGFS */ + +/* + * struct sir_update_session_txq_edca_param + * @message_type: SME message type + * @length: size of struct sir_update_session_txq_edca_param + * @vdev_id: vdev ID + * @txq_edca_params: txq edca parameter to update + */ +struct sir_update_session_txq_edca_param { + uint16_t message_type; + uint16_t length; + uint8_t vdev_id; + tSirMacEdcaParamRecord txq_edca_params; +}; #endif /* __SIR_API_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h b/drivers/staging/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h index cb9975bb12ae7efd9bfa156f46cbf2b87686f864..a7623d4188d5e8b2d670f3c08db9e8b181b1020b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/sir_mac_prot_def.h @@ -54,9 +54,6 @@ #define SIR_MAC_CTRL_FRAME 0x1 #define SIR_MAC_DATA_FRAME 0x2 -#define SIR_MAC_FRAME_TYPE_START 0x0 -#define SIR_MAC_FRAME_TYPE_END 0x3 - /* Data frame subtype definitions */ #define SIR_MAC_DATA_DATA 0 #define SIR_MAC_DATA_DATA_ACK 1 @@ -75,9 +72,6 @@ #define SIR_MAC_DATA_QOS_NULL_POLL 14 #define SIR_MAC_DATA_QOS_NULL_ACK_POLL 15 -#define SIR_MAC_FRAME_SUBTYPE_START 0 -#define SIR_MAC_FRAME_SUBTYPE_END 16 - #define SIR_MAC_DATA_QOS_MASK 8 #define SIR_MAC_DATA_NULL_MASK 4 #define SIR_MAC_DATA_POLL_MASK 2 @@ -103,9 +97,7 @@ #define SIR_MAC_ACTION_TX 1 #define SIR_MAC_ACTION_RX 2 -#define SIR_MAC_BA_POLICY_DELAYED 0 #define SIR_MAC_BA_POLICY_IMMEDIATE 1 -#define SIR_MAC_BA_AMSDU_SUPPORTED 1 #define SIR_MAC_BA_DEFAULT_BUFF_SIZE 64 #define MAX_BA_BUFF_SIZE 256 @@ -139,11 +131,6 @@ /* HT Action Field Codes */ #define SIR_MAC_SM_POWER_SAVE 1 -/* DLP action frame types */ -#define SIR_MAC_DLP_REQ 0 -#define SIR_MAC_DLP_RSP 1 -#define SIR_MAC_DLP_TEARDOWN 2 - /* block acknowledgment action frame types */ #define SIR_MAC_ACTION_VENDOR_SPECIFIC 9 #define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F @@ -159,27 +146,12 @@ #define SIR_MAC_ACTION_GAS_COMEBACK_REQUEST 0x0C #define SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE 0x0D -#ifdef WLAN_FEATURE_11W -/* 11w SA query request/response action frame category code */ -#define SIR_MAC_SA_QUERY_REQ 0 -#define SIR_MAC_SA_QUERY_RSP 1 -#endif - -/* WNM Action field values; IEEE Std 802.11-2012, 8.5.14.1, Table 8-250 */ -#define SIR_MAC_WNM_BSS_TM_QUERY 6 -#define SIR_MAC_WNM_BSS_TM_REQUEST 7 -#define SIR_MAC_WNM_BSS_TM_RESPONSE 8 -#define SIR_MAC_WNM_NOTIF_REQUEST 26 -#define SIR_MAC_WNM_NOTIF_RESPONSE 27 - /* Protected Dual of Public Action(PDPA) frames Action field */ #define SIR_MAC_PDPA_GAS_INIT_REQ 10 #define SIR_MAC_PDPA_GAS_INIT_RSP 11 #define SIR_MAC_PDPA_GAS_COMEBACK_REQ 12 #define SIR_MAC_PDPA_GAS_COMEBACK_RSP 13 -#define SIR_MAC_MAX_RANDOM_LENGTH 2306 - /* ----------------------------------------------------------------------------- */ /* EID (Element ID) definitions */ /* and their min/max lengths */ @@ -201,9 +173,21 @@ #define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80 866 #define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80 866 +#define VHT_CAP_NO_160M_SUPP 0 #define VHT_CAP_160_SUPP 1 #define VHT_CAP_160_AND_80P80_SUPP 2 +#define VHT_NO_EXTD_NSS_BW_SUPP 0 +#define VHT_EXTD_NSS_80_HALF_NSS_160 1 +#define VHT_EXTD_NSS_80_HALF_NSS_80P80 2 +#define VHT_EXTD_NSS_80_3QUART_NSS_80P80 3 +#define VHT_EXTD_NSS_160_HALF_NSS_80P80 1 +#define VHT_EXTD_NSS_160_3QUART_NSS_80P80 2 +#define VHT_EXTD_NSS_2X_NSS_160_1X_NSS_80P80 3 +#define VHT_EXTD_NSS_2X_NSS_80_1X_NSS_80P80 3 + +#define VHT_MAX_NSS 8 + #define VHT_MCS_1x1 0xFFFC #define VHT_MCS_2x2 0xFFF3 @@ -267,7 +251,10 @@ #define SIR_MAC_B_PR_SSID_OFFSET 12 /* Association/Reassociation offsets */ -#define SIR_MAC_REASSOC_SSID_OFFSET 10 +#define SIR_MAC_REASSOC_REQ_SSID_OFFSET 10 + +/* Association Request offsets */ +#define SIR_MAC_ASSOC_REQ_SSID_OFFSET 4 /* / Transaction sequence number definitions (used in Authentication frames) */ #define SIR_MAC_AUTH_FRAME_1 1 @@ -1037,7 +1024,7 @@ typedef struct sSirMacCfParamSetIE { } qdf_packed tSirMacCfParamSetIE; typedef struct sSirMacChanInfo { - tSirMacChanNum firstChanNum; + uint32_t first_freq; uint8_t numChannels; int8_t maxTxPower; } qdf_packed tSirMacChanInfo; @@ -1079,7 +1066,7 @@ typedef struct sSirMacMeasReqIE { /* VHT Capabilities Info */ typedef struct sSirMacVHTCapabilityInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; uint32_t txAntPattern:1; uint32_t rxAntPattern:1; uint32_t vhtLinkAdaptCap:2; @@ -1119,27 +1106,29 @@ typedef struct sSirMacVHTCapabilityInfo { uint32_t vhtLinkAdaptCap:2; uint32_t rxAntPattern:1; uint32_t txAntPattern:1; - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; #endif } qdf_packed tSirMacVHTCapabilityInfo; typedef struct sSirMacVHTTxSupDataRateInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint16_t reserved:3; + uint16_t reserved:2; + uint16_t vht_extended_nss_bw_cap:1; uint16_t txSupDataRate:13; #else uint16_t txSupDataRate:13; - uint16_t reserved:3; + uint16_t vht_extended_nss_bw_cap:1; + uint16_t reserved:2; #endif } qdf_packed tSirMacVHTTxSupDataRateInfo; typedef struct sSirMacVHTRxSupDataRateInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint16_t reserved:3; + uint16_t max_nsts_total:3; uint16_t rxSupDataRate:13; #else uint16_t rxSupDataRate:13; - uint16_t reserved:3; + uint16_t max_nsts_total:3; #endif } qdf_packed tSirMacVHTRxSupDataRateInfo; @@ -1901,7 +1890,10 @@ struct he_capability_info { /* * frame parser does not include optional 160 and 80+80 mcs set for MIN IE len */ -#define SIR_MAC_HE_CAP_MIN_LEN (DOT11F_IE_HE_CAP_MIN_LEN + 8) +#define SIR_MAC_HE_CAP_MIN_LEN (DOT11F_IE_HE_CAP_MIN_LEN) +#define HE_CAP_160M_MCS_MAP_LEN 4 +#define HE_CAP_80P80_MCS_MAP_LEN 4 +#define HE_CAP_OUI_LEN 3 /* QOS action frame definitions */ @@ -2004,7 +1996,7 @@ struct he_capability_info { #define SIR_MAC_VHT_CAP_LINK_ADAPT_CAP 26 #define SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN 28 #define SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN 29 -#define SIR_MAC_VHT_CAP_RESERVED2 30 +#define SIR_MAC_VHT_CAP_EXTD_NSS_BW 30 #define SIR_MAC_HT_CAP_ADVCODING_S 0 #define SIR_MAC_HT_CAP_CHWIDTH40_S 1 diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/wlan_tgt_def_config_hl.h b/drivers/staging/qcacld-3.0/core/mac/inc/wlan_tgt_def_config_hl.h index 482202052832e0582920718faea122cb063e8e7a..5de6d8d4f7fe36b73fb0fecc32bab8203643bea1 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/wlan_tgt_def_config_hl.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/wlan_tgt_def_config_hl.h @@ -59,7 +59,9 @@ * probably always be appropriate; it is probably not necessary to * determine this value dynamically. */ +#ifndef CFG_TGT_AST_SKID_LIMIT #define CFG_TGT_AST_SKID_LIMIT 6 +#endif /* * total number of peers per device. * currently set to 8 to bring up IP3.9 for memory size problem diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/wni_api.h b/drivers/staging/qcacld-3.0/core/mac/inc/wni_api.h index 61d8c969ab3fb792c5d4159771fcab22f4aa89c4..58ac862944eca82d9d3871a83c9ff79c5b957afa 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/wni_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/wni_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -41,7 +42,6 @@ enum eWniMsgTypes { eWNI_SME_SYS_READY_IND = SIR_SME_MSG_TYPES_BEGIN + 1, eWNI_SME_JOIN_REQ = SIR_SME_MSG_TYPES_BEGIN + 2, eWNI_SME_JOIN_RSP = SIR_SME_MSG_TYPES_BEGIN + 3, - eWNI_SME_SETCONTEXT_REQ = SIR_SME_MSG_TYPES_BEGIN + 4, eWNI_SME_SETCONTEXT_RSP = SIR_SME_MSG_TYPES_BEGIN + 5, eWNI_SME_REASSOC_REQ = SIR_SME_MSG_TYPES_BEGIN + 6, eWNI_SME_REASSOC_RSP = SIR_SME_MSG_TYPES_BEGIN + 7, @@ -70,9 +70,10 @@ enum eWniMsgTypes { eWNI_SME_DELTS_REQ = SIR_SME_MSG_TYPES_BEGIN + 30, eWNI_SME_DELTS_RSP = SIR_SME_MSG_TYPES_BEGIN + 31, eWNI_SME_DELTS_IND = SIR_SME_MSG_TYPES_BEGIN + 32, - eWNI_SME_GET_STATISTICS_REQ = SIR_SME_MSG_TYPES_BEGIN + 33, - eWNI_SME_GET_STATISTICS_RSP = SIR_SME_MSG_TYPES_BEGIN + 34, - eWNI_SME_GET_RSSI_REQ = SIR_SME_MSG_TYPES_BEGIN + 35, + /* + * unused SIR_SME_MSG_TYPES_BEGIN + 33 to + * to SIR_SME_MSG_TYPES_BEGIN + 35 + */ eWNI_SME_ASSOC_IND_UPPER_LAYER = SIR_SME_MSG_TYPES_BEGIN + 36, eWNI_SME_WPS_PBC_PROBE_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 37, eWNI_SME_UPPER_LAYER_ASSOC_CNF = SIR_SME_MSG_TYPES_BEGIN + 38, @@ -87,12 +88,11 @@ enum eWniMsgTypes { eWNI_SME_BEACON_REPORT_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 45, eWNI_SME_BEACON_REPORT_RESP_XMIT_IND = SIR_SME_MSG_TYPES_BEGIN + 46, - eWNI_SME_ADD_STA_SELF_RSP = SIR_SME_MSG_TYPES_BEGIN + 47, - eWNI_SME_DEL_STA_SELF_RSP = SIR_SME_MSG_TYPES_BEGIN + 48, + /* unused SIR_SME_MSG_TYPES_BEGIN + 47, */ + /* unused SIR_SME_MSG_TYPES_BEGIN + 48, */ eWNI_SME_FT_PRE_AUTH_REQ = SIR_SME_MSG_TYPES_BEGIN + 49, eWNI_SME_FT_PRE_AUTH_RSP = SIR_SME_MSG_TYPES_BEGIN + 50, - eWNI_SME_FT_UPDATE_KEY = SIR_SME_MSG_TYPES_BEGIN + 51, eWNI_SME_FT_AGGR_QOS_REQ = SIR_SME_MSG_TYPES_BEGIN + 52, eWNI_SME_FT_AGGR_QOS_RSP = SIR_SME_MSG_TYPES_BEGIN + 53, @@ -157,7 +157,7 @@ enum eWniMsgTypes { eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND = SIR_SME_MSG_TYPES_BEGIN + 88, /* update in beacons/probe rsp */ eWNI_SME_STATS_EXT_EVENT = SIR_SME_MSG_TYPES_BEGIN + 89, - eWNI_SME_GET_PEER_INFO_IND = SIR_SME_MSG_TYPES_BEGIN + 90, + /* Unused SIR_SME_MSG_TYPES_BEGIN + 90 */ eWNI_SME_GET_PEER_INFO_EXT_IND = SIR_SME_MSG_TYPES_BEGIN + 91, /* indicates Additional IE from hdd to PE */ eWNI_SME_UPDATE_ADDITIONAL_IES = SIR_SME_MSG_TYPES_BEGIN + 93, @@ -247,7 +247,9 @@ enum eWniMsgTypes { eWNI_SME_GET_ROAM_SCAN_CH_LIST_EVENT = SIR_SME_MSG_TYPES_BEGIN + 161, eWNI_SME_MONITOR_MODE_VDEV_UP = SIR_SME_MSG_TYPES_BEGIN + 162, - eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 163 + eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS = SIR_SME_MSG_TYPES_BEGIN + 163, + eWNI_SME_ABORT_CONN_TIMER = SIR_SME_MSG_TYPES_BEGIN + 164, + eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 165 }; typedef struct sAniCfgTxRateCtrs { diff --git a/drivers/staging/qcacld-3.0/core/mac/src/cfg/cfgUtil/dot11f.frms b/drivers/staging/qcacld-3.0/core/mac/src/cfg/cfgUtil/dot11f.frms index 0304985e0ee9a010d055e4d44c15f83f6a1cccba..cb1faf5623fbe94b1c7253bd3e792ac8190659d0 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/drivers/staging/qcacld-3.0/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -155,6 +155,8 @@ const ANI_WDS_INFO_MAX_LENGTH = 64; const SIR_MAC_MAX_NUMBER_OF_RATES = 12; const HT_MAX_SUPPORTED_MCS_SET = 16; const MAX_SUPPORTED_NEIGHBOR_RPT = 15; +const MAX_QOS_DSCP_DATA_LEN = 58; +const QOS_DSCP_RANGE_LEN = 16; ///////////////////////////////////////////////////////////////////////////// // Wi-Fi Protected Setup TLV Identifiers // @@ -2036,6 +2038,14 @@ IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01) } +IE BeaconReportStatus (EID_VENDOR_SPECIFIC) OUI (0x00, 0x00, 0x00F, 0x22) +{ + sub_type, 1; + version, 1; + length, 1; + reason_code, 1; +} + IE Vendor1IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x10, 0x18) { } @@ -2398,26 +2408,27 @@ IE VHTCaps (EID_VHT_CAPABILITIES) vhtLinkAdaptCap: 2; rxAntPattern: 1; txAntPattern: 1; - reserved1: 2; + extended_nss_bw_supp: 2; } rxMCSMap, 2; { rxHighSupDataRate: 13; - reserved2: 3; + max_nsts_total: 3; } txMCSMap, 2; { txSupDataRate: 13; - reserved3: 3; + vht_extended_nss_bw_cap: 1; + reserved: 2; } } IE VHTOperation (EID_VHT_OPERATION_ELEMENT) { - chanWidth, 1; - chanCenterFreqSeg1, 1; - chanCenterFreqSeg2, 1; - basicMCSSet, 2; + chanWidth, 1; + chan_center_freq_seg0, 1; + chan_center_freq_seg1, 1; + basicMCSSet, 2; } IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD) @@ -2550,7 +2561,8 @@ IE HTInfo (EID_HT_INFO) nonGFDevicesPresent: 1; transmitBurstLimit: 1; obssNonHTStaPresent:1; - reserved: 11; + chan_center_freq_seg2:8; + reserved: 3; } @@ -2577,16 +2589,17 @@ IE HTInfo (EID_HT_INFO) IE OperatingMode (EID_OPERATING_MODE) { { //Operating Mode field - chanWidth: 2; - reserved: 2; - rxNSS: 3; - rxNSSType: 1; + chanWidth: 2; + vht_160_80p80_supp: 1; + no_ldpc: 1; + rxNSS: 3; + rxNSSType: 1; } } IE QosMapSet (EID_QOS_MAP_SET) { - dscp_exceptions[0..60]; + dscp_exceptions[QOS_DSCP_RANGE_LEN..MAX_QOS_DSCP_DATA_LEN]; } CONTAINERIE RICDataDesc @@ -2988,7 +3001,8 @@ IE he_op (EID_EXTN_ID_ELEMENT) OUI (0x24) } { er_su_disable: 1; - reserved2: 7; + oper_info_6g_present: 1; + reserved2: 6; } { bss_color:6; @@ -3012,6 +3026,35 @@ IE he_op (EID_EXTN_ID_ELEMENT) OUI (0x24) data, 1; } }; + OPTIONAL UNION oper_info_6g (DISCRIMINATOR oper_info_6g_present) + { + info (oper_info_6g_present IS 1) + { + primary_ch, 1; + { // control + ch_width: 2; + dup_bcon: 1; + reserved: 5; + } + center_freq_seg0, 1; + center_freq_seg1, 1; + min_rate, 1; + } + }; +} + +IE he_6ghz_band_cap (EID_EXTN_ID_ELEMENT) OUI (0x3B) +{ + { // capabilities_information + min_mpdu_start_spacing :3; + max_ampdu_len_exp: 3; + max_mpdu_len: 3; + sm_pow_save: 2; + rd_responder: 1; + rx_ant_pattern_consistency: 1; + tx_ant_pattern_consistency: 1; + reserved: 2; + } } IE mu_edca_param_set (EID_EXTN_ID_ELEMENT) OUI (0x26) @@ -3480,6 +3523,7 @@ FRAME Beacon // C.f. Sec. 7.2.3.1 OPTIE qcn_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE esp_information; @@ -3576,6 +3620,7 @@ FRAME Beacon2 OPTIE qcn_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE esp_information; @@ -3648,6 +3693,7 @@ FRAME BeaconIEs OPTIE qcn_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE esp_information; @@ -3699,6 +3745,7 @@ FRAME AssocRequest // 7.2.3.4 OPTIE hs20vendor_ie; OPTIE qcn_ie; OPTIE he_cap; + OPTIE he_6ghz_band_cap; OPTIE osen_ie; OPTIE roaming_consortium_sel; } // End frame AssocRequest. @@ -3744,6 +3791,7 @@ FRAME AssocResponse // 7.2.3.5 OPTIE qcn_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE MBO_IE; @@ -3765,6 +3813,7 @@ FRAME ReAssocRequest // 7.2.3.6 OPTIE MobilityDomain; OPTIE FTInfo; OPTIE RICDataDesc[2]; + OPTIE SuppOperatingClasses; OPTIE WPAOpaque; OPTIE HTCaps; OPTIE WMMCaps; @@ -3786,6 +3835,7 @@ FRAME ReAssocRequest // 7.2.3.6 OPTIE vendor_vht_ie; OPTIE hs20vendor_ie; OPTIE he_cap; + OPTIE he_6ghz_band_cap; } // End frame ReAssocRequest. FRAME ReAssocResponse // 7.2.3.7 @@ -3823,6 +3873,7 @@ FRAME ReAssocResponse // 7.2.3.7 OPTIE vendor_vht_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE MBO_IE; @@ -3843,6 +3894,7 @@ FRAME ProbeRequest // 7.2.3.8 OPTIE ExtCap; OPTIE qcn_ie; OPTIE he_cap; + OPTIE he_6ghz_band_cap; } // End frame ProbeRequest. FRAME ProbeResponse // 7.2.3.9 @@ -3905,6 +3957,7 @@ FRAME ProbeResponse // 7.2.3.9 OPTIE qcn_ie; OPTIE he_cap; OPTIE he_op; + OPTIE he_6ghz_band_cap; OPTIE bss_color_change; OPTIE mu_edca_param_set; OPTIE esp_information; @@ -4071,7 +4124,7 @@ FRAME RadioMeasurementRequest FF DialogToken; FF NumOfRepetitions; //Measurement Request IE. - MANDIE MeasurementRequest[1..2]; + MANDIE MeasurementRequest[1..5]; } FRAME RadioMeasurementReport @@ -4081,6 +4134,7 @@ FRAME RadioMeasurementReport FF DialogToken; //Measurement Report elements. MANDIE MeasurementReport[1..4]; + OPTIE BeaconReportStatus; } FRAME LinkMeasurementRequest diff --git a/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.c b/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.c index 3e7bdea015977b994be95697d202989c15dd81e0..326d7f9be14a67af18eaff682cbaa83da6fded72 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.c @@ -158,44 +158,6 @@ static inline tpDphHashNode get_node(struct mac_context *mac, uint8_t assocId, return &hash_table->pDphNodeArray[assocId]; } -/* --------------------------------------------------------------------- */ -/** - * dph_lookup_assoc_id - * - * FUNCTION: - * This function looks up assocID given the station Id. It traverses the complete table to do this. - * Need to find an efficient way to do this. - * LOGIC: - * - * ASSUMPTIONS: - * - * NOTE: - * - * @param mac pointer to global Mac structure. - * @param staIdx station ID - * @param *assocId pointer to associd to be returned by this function. - * @return pointer to the dph node. - */ -tpDphHashNode dph_lookup_assoc_id(struct mac_context *mac, uint16_t staIdx, - uint16_t *assocId, - struct dph_hash_table *hash_table) -{ - uint8_t i; - - for (i = 0; i < hash_table->size; i++) { - if ((hash_table->pDphNodeArray[i].added) && - (hash_table->pDphNodeArray[i].staIndex == staIdx)) { - *assocId = i; - break; - } - - } - if (i == hash_table->size) - return NULL; - return &hash_table->pDphNodeArray[i]; - -} - /** ------------------------------------------------------------- \fn dph_init_sta_state \brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId @@ -209,11 +171,10 @@ tpDphHashNode dph_lookup_assoc_id(struct mac_context *mac, uint16_t staIdx, -------------------------------------------------------------*/ tpDphHashNode dph_init_sta_state(struct mac_context *mac, tSirMacAddr staAddr, - uint16_t assocId, uint8_t validStaIdx, + uint16_t assocId, struct dph_hash_table *hash_table) { tpDphHashNode sta, pnext; - uint16_t staIdx = STA_INVALID_IDX; if (assocId >= hash_table->size) { pe_err("Invalid Assoc Id %d", assocId); @@ -221,7 +182,6 @@ tpDphHashNode dph_init_sta_state(struct mac_context *mac, tSirMacAddr staAddr, } sta = get_node(mac, (uint8_t) assocId, hash_table); - staIdx = sta->staIndex; pnext = sta->next; /* Clear the STA node except for the next pointer */ @@ -230,10 +190,6 @@ tpDphHashNode dph_init_sta_state(struct mac_context *mac, tSirMacAddr staAddr, /* Initialize the assocId */ sta->assocId = assocId; - if (true == validStaIdx) - sta->staIndex = staIdx; - else - sta->staIndex = STA_INVALID_IDX; /* Initialize STA mac address */ qdf_mem_copy(sta->staAddr, staAddr, sizeof(tSirMacAddr)); @@ -272,7 +228,7 @@ tpDphHashNode dph_add_hash_entry(struct mac_context *mac, tSirMacAddr staAddr, pe_debug("assocId %d index %d STA addr", assocId, index); - pe_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(staAddr)); + pe_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(staAddr)); if (assocId >= hash_table->size) { pe_err("invalid STA id %d", assocId); @@ -302,7 +258,7 @@ tpDphHashNode dph_add_hash_entry(struct mac_context *mac, tSirMacAddr staAddr, return NULL; } else { if (dph_init_sta_state - (mac, staAddr, assocId, false, hash_table) == NULL) { + (mac, staAddr, assocId, hash_table) == NULL) { pe_err("could not Init STA id: %d", assocId); return NULL; } @@ -344,7 +300,7 @@ QDF_STATUS dph_delete_hash_entry(struct mac_context *mac, tSirMacAddr staAddr, uint16_t index = hash_function(mac, staAddr, hash_table->size); pe_debug("assocId %d index %d STA addr", assocId, index); - pe_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(staAddr)); + pe_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(staAddr)); if (assocId >= hash_table->size) { pe_err("invalid STA id %d", assocId); @@ -380,7 +336,7 @@ QDF_STATUS dph_delete_hash_entry(struct mac_context *mac, tSirMacAddr staAddr, ptr->next = 0; } else { pe_err("Entry not present STA addr"); - pe_err(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(staAddr)); + pe_err(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(staAddr)); return QDF_STATUS_E_FAILURE; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.h b/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.h index 57eccb51f096447e6b10ae8bbcd29448d0f07193..ef7583398427cd4416f58a0368ecf18a5627d739 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/dph/dph_hash_table.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015, 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -57,9 +57,6 @@ struct dph_hash_table { tpDphHashNode dph_lookup_hash_entry(struct mac_context *mac, uint8_t staAddr[], uint16_t *pStaId, struct dph_hash_table *hash_table); -tpDphHashNode dph_lookup_assoc_id(struct mac_context *mac, uint16_t staIdx, - uint16_t *assocId, - struct dph_hash_table *hash_table); /* Get a pointer to the hash node */ tpDphHashNode dph_get_hash_entry(struct mac_context *mac, uint16_t staId, @@ -87,7 +84,7 @@ void dph_hash_table_init(struct mac_context *mac, /* Initialize STA state */ tpDphHashNode dph_init_sta_state(struct mac_context *mac, tSirMacAddr staAddr, - uint16_t staId, uint8_t validStaIdx, + uint16_t staId, struct dph_hash_table *hash_table); #endif diff --git a/drivers/staging/qcacld-3.0/core/mac/src/include/dot11f.h b/drivers/staging/qcacld-3.0/core/mac/src/include/dot11f.h index b1e8253059bbb723ef78cb92f94f62cb0f5e685b..247f261d8cc329e764e4f55da7fe6746d35c6b53 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/include/dot11f.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/include/dot11f.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -3643,13 +3643,14 @@ typedef struct sDot11fIEVHTCaps { uint32_t vhtLinkAdaptCap:2; uint32_t rxAntPattern:1; uint32_t txAntPattern:1; - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; uint16_t rxMCSMap; uint16_t rxHighSupDataRate:13; - uint16_t reserved2:3; + uint16_t max_nsts_total:3; uint16_t txMCSMap; uint16_t txSupDataRate:13; - uint16_t reserved3:3; + uint16_t vht_extended_nss_bw_cap:1; + uint16_t reserved:2; } tDot11fIEVHTCaps; #define DOT11F_EID_VHTCAPS (191) @@ -3689,8 +3690,8 @@ uint32_t dot11f_get_packed_ie_VHTCaps( typedef struct sDot11fIEVHTOperation { uint8_t present; uint8_t chanWidth; - uint8_t chanCenterFreqSeg1; - uint8_t chanCenterFreqSeg2; + uint8_t chan_center_freq_seg0; + uint8_t chan_center_freq_seg1; uint16_t basicMCSSet; } tDot11fIEVHTOperation; @@ -4407,6 +4408,48 @@ uint32_t dot11f_get_packed_ie_AID( }; /* End extern "C". */ #endif /* C++ */ +/* EID 221 (0xdd) {OUI 0x00, 0x00, 0x0f, 0x22} */ +typedef struct sDot11fIEBeaconReportStatus { + uint8_t present; + uint8_t sub_type; + uint8_t version; + uint8_t length; + uint8_t reason_code; +} tDot11fIEBeaconReportStatus; + +#define DOT11F_EID_BEACONREPORTSTATUS (221) + +/* N.B. These #defines do *not* include the EID & length */ +#define DOT11F_IE_BEACONREPORTSTATUS_MIN_LEN (8) + +#define DOT11F_IE_BEACONREPORTSTATUS_MAX_LEN (8) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +__must_check uint32_t dot11f_unpack_ie_BeaconReportStatus( + tpAniSirGlobal, + uint8_t *, + uint8_t, + tDot11fIEBeaconReportStatus*, + bool); + +uint32_t dot11f_pack_ie_BeaconReportStatus( + tpAniSirGlobal, + tDot11fIEBeaconReportStatus *, + uint8_t *, + uint32_t, + uint32_t*); + +uint32_t dot11f_get_packed_ie_BeaconReportStatus( + tpAniSirGlobal, + tDot11fIEBeaconReportStatus *, + uint32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ + /* EID 4 (0x04) */ typedef struct sDot11fIECFParams { uint8_t present; @@ -5355,7 +5398,8 @@ typedef struct sDot11fIEHTInfo { uint16_t nonGFDevicesPresent:1; uint16_t transmitBurstLimit:1; uint16_t obssNonHTStaPresent:1; - uint16_t reserved:11; + uint16_t chan_center_freq_seg2:8; + uint16_t reserved:3; uint16_t basicSTBCMCS:7; uint16_t dualCTSProtection:1; uint16_t secondaryBeacon:1; @@ -5863,7 +5907,8 @@ uint32_t dot11f_get_packed_ie_OBSSScanParameters( typedef struct sDot11fIEOperatingMode { uint8_t present; uint8_t chanWidth:2; - uint8_t reserved:2; + uint8_t vht_160_80p80_supp:1; + uint8_t no_ldpc:1; uint8_t rxNSS:3; uint8_t rxNSSType:1; } tDot11fIEOperatingMode; @@ -6606,15 +6651,15 @@ uint32_t dot11f_get_packed_ie_QOSCapsStation( typedef struct sDot11fIEQosMapSet { uint8_t present; uint8_t num_dscp_exceptions; - uint8_t dscp_exceptions[60]; + uint8_t dscp_exceptions[58]; } tDot11fIEQosMapSet; #define DOT11F_EID_QOSMAPSET (110) /* N.B. These #defines do *not* include the EID & length */ -#define DOT11F_IE_QOSMAPSET_MIN_LEN (0) +#define DOT11F_IE_QOSMAPSET_MIN_LEN (16) -#define DOT11F_IE_QOSMAPSET_MAX_LEN (60) +#define DOT11F_IE_QOSMAPSET_MAX_LEN (58) #ifdef __cplusplus extern "C" { @@ -8863,6 +8908,52 @@ uint32_t dot11f_get_packed_ie_fragment_ie( }; /* End extern "C". */ #endif /* C++ */ +/* EID 255 (0xff) Extended EID 59 (0x3b) */ +typedef struct sDot11fIEhe_6ghz_band_cap { + uint8_t present; + uint16_t min_mpdu_start_spacing:3; + uint16_t max_ampdu_len_exp:3; + uint16_t max_mpdu_len:3; + uint16_t sm_pow_save:2; + uint16_t rd_responder:1; + uint16_t rx_ant_pattern_consistency:1; + uint16_t tx_ant_pattern_consistency:1; + uint16_t reserved:2; +} tDot11fIEhe_6ghz_band_cap; + +#define DOT11F_EID_HE_6GHZ_BAND_CAP (255) + +/* N.B. These #defines do *not* include the EID & length */ +#define DOT11F_IE_HE_6GHZ_BAND_CAP_MIN_LEN (2) + +#define DOT11F_IE_HE_6GHZ_BAND_CAP_MAX_LEN (2) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +__must_check uint32_t dot11f_unpack_ie_he_6ghz_band_cap( + tpAniSirGlobal, + uint8_t *, + uint8_t, + tDot11fIEhe_6ghz_band_cap*, + bool); + +uint32_t dot11f_pack_ie_he_6ghz_band_cap( + tpAniSirGlobal, + tDot11fIEhe_6ghz_band_cap *, + uint8_t *, + uint32_t, + uint32_t*); + +uint32_t dot11f_get_packed_ie_he_6ghz_band_cap( + tpAniSirGlobal, + tDot11fIEhe_6ghz_band_cap *, + uint32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ + /* EID 255 (0xff) Extended EID 35 (0x23) */ typedef struct sDot11fIEhe_cap { uint8_t present; @@ -9016,7 +9107,8 @@ typedef struct sDot11fIEhe_op { uint16_t vht_oper_present:1; uint16_t co_located_bss:1; uint8_t er_su_disable:1; - uint8_t reserved2:7; + uint8_t oper_info_6g_present:1; + uint8_t reserved2:6; uint8_t bss_color:6; uint8_t partial_bss_col:1; uint8_t bss_col_disabled:1; @@ -9033,6 +9125,17 @@ typedef struct sDot11fIEhe_op { uint8_t data; } info; /* co_located_bss = 1 */ } maxbssid_ind; + union { + struct { + uint8_t primary_ch; + uint8_t ch_width:2; + uint8_t dup_bcon:1; + uint8_t reserved:5; + uint8_t center_freq_seg0; + uint8_t center_freq_seg1; + uint8_t min_rate; + } info; /* oper_info_6g_present = 1 */ + } oper_info_6g; } tDot11fIEhe_op; #define DOT11F_EID_HE_OP (255) @@ -9040,7 +9143,7 @@ typedef struct sDot11fIEhe_op { /* N.B. These #defines do *not* include the EID & length */ #define DOT11F_IE_HE_OP_MIN_LEN (6) -#define DOT11F_IE_HE_OP_MAX_LEN (10) +#define DOT11F_IE_HE_OP_MAX_LEN (15) #ifdef __cplusplus extern "C" { @@ -9587,6 +9690,7 @@ typedef struct sDot11fAssocRequest{ tDot11fIEhs20vendor_ie hs20vendor_ie; tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEosen_ie osen_ie; tDot11fIEroaming_consortium_sel roaming_consortium_sel; } tDot11fAssocRequest; @@ -9653,6 +9757,7 @@ typedef struct sDot11fAssocResponse{ tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEMBO_IE MBO_IE; @@ -9776,6 +9881,7 @@ typedef struct sDot11fBeacon{ tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEesp_information esp_information; @@ -9878,6 +9984,7 @@ typedef struct sDot11fBeacon2{ tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEesp_information esp_information; @@ -9961,6 +10068,7 @@ typedef struct sDot11fBeaconIEs{ tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEesp_information esp_information; @@ -10290,19 +10398,20 @@ uint32_t dot11f_get_packed_operating_mode_size(tpAniSirGlobal pCtx, #endif /* C++ */ typedef struct sDot11fProbeRequest{ - tDot11fIESSID SSID; - tDot11fIESuppRates SuppRates; - tDot11fIERequestedInfo RequestedInfo; - tDot11fIEExtSuppRates ExtSuppRates; - tDot11fIEDSParams DSParams; - tDot11fIEHTCaps HTCaps; - tDot11fIEWscProbeReq WscProbeReq; - tDot11fIEWFATPC WFATPC; - tDot11fIEP2PProbeReq P2PProbeReq; - tDot11fIEVHTCaps VHTCaps; - tDot11fIEExtCap ExtCap; - tDot11fIEqcn_ie qcn_ie; - tDot11fIEhe_cap he_cap; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIERequestedInfo RequestedInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEDSParams DSParams; + tDot11fIEHTCaps HTCaps; + tDot11fIEWscProbeReq WscProbeReq; + tDot11fIEWFATPC WFATPC; + tDot11fIEP2PProbeReq P2PProbeReq; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEqcn_ie qcn_ie; + tDot11fIEhe_cap he_cap; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; } tDot11fProbeRequest; #define DOT11F_PROBEREQUEST (21) @@ -10382,6 +10491,7 @@ typedef struct sDot11fProbeResponse{ tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEesp_information esp_information; @@ -10434,11 +10544,12 @@ uint32_t dot11f_get_packed_qos_map_configure_size(tpAniSirGlobal pCtx, #endif /* C++ */ typedef struct sDot11fRadioMeasurementReport{ - tDot11fFfCategory Category; - tDot11fFfAction Action; - tDot11fFfDialogToken DialogToken; - uint16_t num_MeasurementReport; - tDot11fIEMeasurementReport MeasurementReport[4]; + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + uint16_t num_MeasurementReport; + tDot11fIEMeasurementReport MeasurementReport[4]; + tDot11fIEBeaconReportStatus BeaconReportStatus; } tDot11fRadioMeasurementReport; #define DOT11F_RADIOMEASUREMENTREPORT (24) @@ -10467,7 +10578,7 @@ typedef struct sDot11fRadioMeasurementRequest{ tDot11fFfDialogToken DialogToken; tDot11fFfNumOfRepetitions NumOfRepetitions; uint16_t num_MeasurementRequest; - tDot11fIEMeasurementRequest MeasurementRequest[2]; + tDot11fIEMeasurementRequest MeasurementRequest[5]; } tDot11fRadioMeasurementRequest; #define DOT11F_RADIOMEASUREMENTREQUEST (25) @@ -10491,43 +10602,45 @@ uint32_t dot11f_get_packed_radio_measurement_request_size(tpAniSirGlobal pCtx, #endif /* C++ */ typedef struct sDot11fReAssocRequest{ - tDot11fFfCapabilities Capabilities; - tDot11fFfListenInterval ListenInterval; - tDot11fFfCurrentAPAddress CurrentAPAddress; - tDot11fIESSID SSID; - tDot11fIESuppRates SuppRates; - tDot11fIEExtSuppRates ExtSuppRates; - tDot11fIEPowerCaps PowerCaps; - tDot11fIESuppChannels SuppChannels; - tDot11fIERSNOpaque RSNOpaque; - tDot11fIEQOSCapsStation QOSCapsStation; - tDot11fIERRMEnabledCap RRMEnabledCap; - tDot11fIEMobilityDomain MobilityDomain; - tDot11fIEFTInfo FTInfo; - uint16_t num_RICDataDesc; - tDot11fIERICDataDesc RICDataDesc[2]; - tDot11fIEWPAOpaque WPAOpaque; - tDot11fIEHTCaps HTCaps; - tDot11fIEWMMCaps WMMCaps; - tDot11fIEWMMInfoStation WMMInfoStation; - tDot11fIEWscIEOpaque WscIEOpaque; - tDot11fIEWAPIOpaque WAPIOpaque; - tDot11fIEWAPI WAPI; - tDot11fIEESERadMgmtCap ESERadMgmtCap; - tDot11fIEESEVersion ESEVersion; - tDot11fIEESECckmOpaque ESECckmOpaque; - uint16_t num_WMMTSPEC; - tDot11fIEWMMTSPEC WMMTSPEC[4]; - tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; - tDot11fIEP2PIEOpaque P2PIEOpaque; - tDot11fIEWFDIEOpaque WFDIEOpaque; - tDot11fIEVHTCaps VHTCaps; - tDot11fIEExtCap ExtCap; - tDot11fIEOperatingMode OperatingMode; - tDot11fIEQosMapSet QosMapSet; - tDot11fIEvendor_vht_ie vendor_vht_ie; - tDot11fIEhs20vendor_ie hs20vendor_ie; - tDot11fIEhe_cap he_cap; + tDot11fFfCapabilities Capabilities; + tDot11fFfListenInterval ListenInterval; + tDot11fFfCurrentAPAddress CurrentAPAddress; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEPowerCaps PowerCaps; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + uint16_t num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIEWPAOpaque WPAOpaque; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEWscIEOpaque WscIEOpaque; + tDot11fIEWAPIOpaque WAPIOpaque; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESEVersion ESEVersion; + tDot11fIEESECckmOpaque ESECckmOpaque; + uint16_t num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; + tDot11fIEP2PIEOpaque P2PIEOpaque; + tDot11fIEWFDIEOpaque WFDIEOpaque; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEQosMapSet QosMapSet; + tDot11fIEvendor_vht_ie vendor_vht_ie; + tDot11fIEhs20vendor_ie hs20vendor_ie; + tDot11fIEhe_cap he_cap; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; } tDot11fReAssocRequest; #define DOT11F_REASSOCREQUEST (26) @@ -10586,6 +10699,7 @@ typedef struct sDot11fReAssocResponse{ tDot11fIEvendor_vht_ie vendor_vht_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEbss_color_change bss_color_change; tDot11fIEmu_edca_param_set mu_edca_param_set; tDot11fIEMBO_IE MBO_IE; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/include/dph_global.h b/drivers/staging/qcacld-3.0/core/mac/src/include/dph_global.h index 5bb058fd510c667d8b502190a57113156a109efb..6b8cd2b71a191e2340afce441805a55d9a166b86 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/include/dph_global.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/include/dph_global.h @@ -77,6 +77,9 @@ struct parsed_ies { tDot11fIEHTInfo ht_operation; tDot11fIEVHTOperation vht_operation; tDot11fIEhs20vendor_ie hs20vendor_ie; +#ifdef WLAN_FEATURE_11AX + tDot11fIEhe_op he_operation; +#endif }; /* STA state node */ @@ -141,18 +144,19 @@ typedef struct sDphHashNode { */ uint8_t htSupportedChannelWidthSet:1; uint8_t htSecondaryChannelOffset:2; - uint16_t bssId; /* BSSID */ uint16_t assocId; /* Association ID */ - /* This is the real sta index generated by HAL */ - uint16_t staIndex; uint8_t staAddr[6]; uint8_t staType; uint8_t vhtSupportedChannelWidthSet; + enum phy_ch_width ch_width; uint8_t vhtSupportedRxNss; uint8_t vhtBeamFormerCapable; uint8_t vht_su_bfee_capable; uint8_t vht_mcs_10_11_supp; + uint8_t vht_160mhz_nss; + uint8_t vht_80p80mhz_nss; + uint8_t vht_extended_nss_bw_cap; #ifdef WLAN_FEATURE_11W TX_TIMER pmfSaQueryTimer; uint16_t pmfSaQueryCurrentTransId; @@ -181,7 +185,8 @@ typedef struct sDphHashNode { #ifdef WLAN_FEATURE_11AX tDot11fIEhe_cap he_config; #endif - + /* Peer operation class, extracted from ASSOC request frame*/ + tDot11fIESuppOperatingClasses supp_operating_classes; /* * When a station with already an existing dph entry tries to * associate again, the old dph entry will be zeroed out except diff --git a/drivers/staging/qcacld-3.0/core/mac/src/include/parser_api.h b/drivers/staging/qcacld-3.0/core/mac/src/include/parser_api.h index 2842e2742b74fa888b6eec3e3bac207bdc5a9a15..7c98e4213563f2801a0a5f8a1adb27279d287781 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/include/parser_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/include/parser_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -201,7 +201,7 @@ typedef struct sSirProbeRespBeacon { tSirMacSSid ssId; tSirMacRateSet supportedRates; tSirMacRateSet extendedRates; - tSirMacChanNum channelNumber; + uint32_t chan_freq; tSirMacCfParamSet cfParamSet; tSirMacTim tim; tSirMacEdcaParamSetIE edcaParams; @@ -329,6 +329,7 @@ typedef struct sSirAssocReq { tSirMacSupportedChannelIE supportedChannels; tDot11fIEHTCaps HTCaps; tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIESuppOperatingClasses supp_operating_classes; /* / This is set if the frame is a reassoc request: */ uint8_t reassocRequest; uint8_t ssidPresent; @@ -357,6 +358,7 @@ typedef struct sSirAssocReq { tDot11fIEvendor_vht_ie vendor_vht_ie; tDot11fIEhs20vendor_ie hs20vendor_ie; tDot11fIEhe_cap he_cap; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; tDot11fIEqcn_ie qcn_ie; bool is_sae_authenticated; } tSirAssocReq, *tpSirAssocReq; @@ -459,6 +461,7 @@ typedef struct sSirAssocRsp { tDot11fIEqcn_ie qcn_ie; tDot11fIEhe_cap he_cap; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap; bool mu_edca_present; tSirMacEdcaParamSetIE mu_edca; #ifdef WLAN_FEATURE_FILS_SK @@ -697,7 +700,7 @@ populate_dot_11_f_ext_chann_switch_ann(struct mac_context *mac_ptr, void populate_dot11f_vht_tx_power_env(struct mac_context *mac, tDot11fIEvht_transmit_power_env *pDot11f, - enum phy_ch_width ch_width, uint8_t chan); + enum phy_ch_width ch_width, uint32_t chan_freq); /* / Populate a tDot11fIEChannelSwitchWrapper */ void populate_dot11f_chan_switch_wrapper(struct mac_context *mac, @@ -1022,7 +1025,7 @@ QDF_STATUS populate_dot11f_rrm_ie(struct mac_context *mac, struct pe_session *pe_session); void populate_mdie(struct mac_context *mac, tDot11fIEMobilityDomain *pDot11f, - uint8_t mdie[SIR_MDIE_SIZE]); + uint8_t mdie[]); #ifdef WLAN_FEATURE_FILS_SK /** @@ -1146,6 +1149,18 @@ QDF_STATUS populate_dot11f_he_caps(struct mac_context *, struct pe_session *, tDot11fIEhe_cap *); QDF_STATUS populate_dot11f_he_operation(struct mac_context *, struct pe_session *, tDot11fIEhe_op *); +/** + * populate_dot11f_he_6ghz_cap() - pouldate HE 6GHz caps IE + * @mac_ctx: Global MAC context + * @session: PE session + * @he_6g_cap: pointer to HE 6GHz IE + * + * Populdate the HE 6GHz IE based on the session. + */ +QDF_STATUS +populate_dot11f_he_6ghz_cap(struct mac_context *mac_ctx, + struct pe_session *session, + tDot11fIEhe_6ghz_band_cap *he_6g_cap); #ifdef WLAN_FEATURE_11AX_BSS_COLOR QDF_STATUS populate_dot11f_he_bss_color_change(struct mac_context *mac_ctx, struct pe_session *session, @@ -1172,6 +1187,14 @@ static inline QDF_STATUS populate_dot11f_he_operation(struct mac_context *mac_ct return QDF_STATUS_SUCCESS; } +static inline QDF_STATUS +populate_dot11f_he_6ghz_cap(struct mac_context *mac_ctx, + struct pe_session *session, + tDot11fIEhe_6ghz_band_cap *he_6g_cap) +{ + return QDF_STATUS_SUCCESS; +} + static inline QDF_STATUS populate_dot11f_he_bss_color_change( struct mac_context *mac_ctx, struct pe_session *session, @@ -1205,6 +1228,20 @@ QDF_STATUS populate_dot11f_twt_extended_caps(struct mac_context *mac_ctx, } #endif +/** + * populate_dot11f_btm_caps() - populate btm extended capabilities + * @mac_ctx: Global MAC context. + * @pe_session: Pointer to the PE session. + * @dot11f: Pointer to the extended capabilities of the session. + * + * Disable btm for SAE types for Helium firmware limit + * + * Return: QDF_STATUS Success or Failure + */ +QDF_STATUS populate_dot11f_btm_caps(struct mac_context *mac_ctx, + struct pe_session *pe_session, + struct sDot11fIEExtCap *dot11f); + /** * lim_truncate_ppet: truncates ppet of trailling zeros * @ppet: ppet to truncate diff --git a/drivers/staging/qcacld-3.0/core/mac/src/include/sir_debug.h b/drivers/staging/qcacld-3.0/core/mac/src/include/sir_debug.h index 989f27b968178a3711c1e03e01356cff1ef4d8d0..68609756fc382d33134edd18f3656b556aaa5ff2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/include/sir_debug.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/include/sir_debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012, 2014-2015, 2017-2019 The Linux Foundation. All + * Copyright (c) 2011-2012, 2014-2015, 2017-2019, 2021 The Linux Foundation. All * rights reserved. * * Permission to use, copy, modify, and/or distribute this software for @@ -57,6 +57,10 @@ QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_PE, params) #define pe_nofl_debug(params...) \ QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_PE, params) +#define pe_nofl_rl_debug(params...) \ + QDF_TRACE_DEBUG_RL_NO_FL(QDF_MODULE_ID_PE, params) +#define pe_nofl_rl_info(params...) \ + QDF_TRACE_INFO_RL_NO_FL(QDF_MODULE_ID_PE, params) #define PE_ENTER() QDF_TRACE_ENTER(QDF_MODULE_ID_PE, "enter") #define PE_EXIT() QDF_TRACE_EXIT(QDF_MODULE_ID_PE, "exit") diff --git a/drivers/staging/qcacld-3.0/core/mac/src/include/sir_params.h b/drivers/staging/qcacld-3.0/core/mac/src/include/sir_params.h index e140e29072084933403d1403346948d5bffb64e4..a6e30c3dfab193050aaced47819c40d671225a80 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/include/sir_params.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/include/sir_params.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -137,15 +137,6 @@ enum cap_bitmap { /* MAX_FEATURE_SUPPORTED = 32 */ }; -typedef enum eSriLinkState { - eSIR_LINK_IDLE_STATE = 0, - eSIR_LINK_PREASSOC_STATE = 1, - eSIR_LINK_POSTASSOC_STATE = 2, - eSIR_LINK_AP_STATE = 3, - eSIR_LINK_IBSS_STATE = 4, - eSIR_LINK_DOWN_STATE = 5, -} tSirLinkState; - /* / Mailbox Message Structure Define */ typedef struct sSirMbMsg { uint16_t type; @@ -170,25 +161,25 @@ typedef struct sSirMbMsg { * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM * @type: Message type * @msg_len: Message length - * @session_id: session id + * @vdev_id: vdev id * @data: Pointer to data tobe transmitted */ struct sir_mgmt_msg { uint16_t type; uint16_t msg_len; - uint8_t session_id; + uint8_t vdev_id; uint8_t *data; }; /** * struct sir_cfg_action_frm_tb_ppdu - cfg to set action frame in he tb ppdu * @type: Message type - * @session_id: session id + * @vdev_id: vdev id * @cfg: enable/disable cfg */ struct sir_cfg_action_frm_tb_ppdu { uint16_t type; - uint8_t session_id; + uint8_t vdev_id; uint8_t cfg; }; @@ -222,7 +213,6 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_DELETE_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 3) #define SIR_HAL_DELETE_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 4) #define SIR_HAL_ADD_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 5) -#define SIR_HAL_ADD_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 6) #define SIR_HAL_DELETE_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 7) #define SIR_HAL_DELETE_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 8) /* @@ -231,9 +221,7 @@ struct sir_cfg_action_frm_tb_ppdu { */ #define SIR_HAL_SEND_BEACON_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 17) -#define SIR_HAL_SET_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 18) #define SIR_HAL_SET_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 19) -#define SIR_HAL_SET_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 20) #define SIR_HAL_SET_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 21) #define SIR_HAL_UPDATE_EDCA_PROFILE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 22) @@ -259,7 +247,6 @@ struct sir_cfg_action_frm_tb_ppdu { * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 57) are unused */ -#define SIR_HAL_SET_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 58) #define SIR_HAL_SET_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 59) #define SIR_HAL_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 60) #define SIR_HAL_DPU_MIC_ERROR (SIR_HAL_ITC_MSG_TYPES_BEGIN + 61) @@ -275,12 +262,9 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_GET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 72) /* * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 73) thru - * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 87) are unused + * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89) are unused */ -/* / PE <-> HAL statistics messages */ -#define SIR_HAL_GET_STATISTICS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 88) -#define SIR_HAL_GET_STATISTICS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89) #define SIR_HAL_SET_KEY_DONE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 90) /* / PE <-> HAL BTC messages */ @@ -301,9 +285,10 @@ struct sir_cfg_action_frm_tb_ppdu { /* / PE <-> HAL Host Offload message */ #define SIR_HAL_SET_HOST_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 100) -#define SIR_HAL_ADD_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101) -#define SIR_HAL_ADD_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102) -#define SIR_HAL_DEL_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103) +/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101) is unused */ +/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102) is unused */ +/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103) is unused */ + /* * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 104) thru * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 108) are unused @@ -316,8 +301,6 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_P2P_NOA_ATTR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 112) /* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 113) is unused */ -#define SIR_HAL_SET_LINK_STATE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 114) - #define SIR_HAL_WLAN_SUSPEND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 115) #define SIR_HAL_WLAN_RESUME_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 116) @@ -464,9 +447,6 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_STATS_EXT_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194) /* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 195) is unused */ #endif /* WLAN_FEATURE_STATS_EXT */ - -#define SIR_HAL_HIDE_SSID_VDEV_RESTART (SIR_HAL_ITC_MSG_TYPES_BEGIN + 196) - /* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 197) is unused */ #ifdef FEATURE_WLAN_EXTSCAN @@ -522,7 +502,6 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_SET_DHCP_SERVER_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222) #endif /* DHCP_SERVER_OFFLOAD */ #define SIR_HAL_LED_FLASHING_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223) -#define SIR_HAL_PROCESS_FW_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224) #ifdef WLAN_FEATURE_ROAM_OFFLOAD #define SIR_HAL_ROAM_OFFLOAD_SYNCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225) @@ -625,8 +604,10 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_INIT_ROAM_OFFLOAD_PARAM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 380) -#define SIR_HAL_GET_PEER_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 386) - +/* + * Unused SIR_HAL_ITC_MSG_TYPES_BEGIN + 381 to + * SIR_HAL_ITC_MSG_TYPES_BEGIN + 386 + */ #define SIR_HAL_GET_PEER_INFO_EXT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 387) /* ARP Debug stats */ @@ -672,9 +653,9 @@ struct sir_cfg_action_frm_tb_ppdu { #define SIR_HAL_SET_ROAM_TRIGGERS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 413) #define SIR_HAL_ROAM_SCAN_CH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 414) -#define SIR_HAL_SEND_MAX_TX_POWER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 415) #define SIR_HAL_REQ_SEND_DELBA_REQ_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 415) +#define SIR_HAL_SEND_MAX_TX_POWER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 416) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) @@ -737,8 +718,9 @@ struct sir_cfg_action_frm_tb_ppdu { (SIR_LIM_TIMEOUT_MSG_START + 0x28) #define SIR_LIM_AUTH_RETRY_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2D) +#define SIR_LIM_AUTH_SAE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2E) -#define SIR_LIM_AUTH_SAE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2E) +#define SIR_LIM_PROCESS_DEFERRED_QUEUE (SIR_LIM_TIMEOUT_MSG_START + 0x2F) #define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF) diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_admit_control.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_admit_control.h index 83b531f1846b10cb7f01d0dae5d7603dca0e3b72..3830f7dd4eadcce1105e86d351b87bae2e23ad7e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_admit_control.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_admit_control.h @@ -74,20 +74,17 @@ lim_admit_control_delete_ts(struct mac_context *mac, QDF_STATUS lim_admit_control_init(struct mac_context *mac); #ifdef FEATURE_WLAN_ESE QDF_STATUS lim_send_hal_msg_add_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct mac_tspec_ie tspecIE, uint8_t sessionId, uint16_t tsm_interval); #else QDF_STATUS lim_send_hal_msg_add_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct mac_tspec_ie tspecIE, uint8_t sessionId); #endif QDF_STATUS lim_send_hal_msg_del_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct delts_req_info delts, uint8_t sessionId, uint8_t *bssId); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_api.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_api.h index 99583c7c532be28befde63115066474543ecbe1e..893c56472b11a356f91f830b163dedaefb900dd8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_api.h @@ -68,9 +68,42 @@ #define LIM_IS_CONNECTION_ACTIVE(pe_session) (pe_session->LimRxedBeaconCntDuringHB) /*mac->lim.gLimProcessDefdMsgs*/ #define GET_LIM_PROCESS_DEFD_MESGS(mac) (mac->lim.gLimProcessDefdMsgs) + +/** + * lim_post_msg_api() - post normal priority PE message + * @mac: mac context + * @msg: message to be posted + * + * This function is called to post a message to the tail of the PE + * message queue to be processed in the MC Thread with normal + * priority. + * + * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS on error + */ +QDF_STATUS lim_post_msg_api(struct mac_context *mac, struct scheduler_msg *msg); + +static inline void +lim_post_msg_to_process_deferred_queue(struct mac_context *mac) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + if (!mac->lim.gLimProcessDefdMsgs || !mac->lim.gLimDeferredMsgQ.size) + return; + + msg.type = SIR_LIM_PROCESS_DEFERRED_QUEUE; + msg.bodyptr = NULL; + msg.bodyval = 0; + + status = lim_post_msg_api(mac, &msg); + if (QDF_IS_STATUS_ERROR(status)) + pe_err("Failed to post lim msg:0x%x", msg.type); +} + #define SET_LIM_PROCESS_DEFD_MESGS(mac, val) \ - mac->lim.gLimProcessDefdMsgs = val; \ - pe_debug("Defer LIM msg %d", val); + mac->lim.gLimProcessDefdMsgs = val; \ + pe_debug("Defer LIM msg %d", val); \ + lim_post_msg_to_process_deferred_queue(mac); /* LIM exported function templates */ #define LIM_MIN_BCN_PR_LENGTH 12 @@ -114,6 +147,20 @@ QDF_STATUS lim_start(struct mac_context *mac); QDF_STATUS pe_start(struct mac_context *mac); void pe_stop(struct mac_context *mac); +#ifdef WLAN_FEATURE_11W +/** + * lim_stop_pmfcomeback_timer() - stop pmf comeback timer + * @session: Pointer to PE session + * + * Return: None + */ +void lim_stop_pmfcomeback_timer(struct pe_session *session); +#else +static inline void lim_stop_pmfcomeback_timer(struct pe_session *session) +{ +} +#endif + /** * pe_register_mgmt_rx_frm_callback() - registers callback for receiving * mgmt rx frames @@ -156,19 +203,6 @@ void pe_register_callbacks_with_wma(struct mac_context *mac, */ void lim_cleanup(struct mac_context *); -/** - * lim_post_msg_api() - post normal priority PE message - * @mac: mac context - * @msg: message to be posted - * - * This function is called to post a message to the tail of the PE - * message queue to be processed in the MC Thread with normal - * priority. - * - * Return: QDF_STATUS_SUCCESS on success, other QDF_STATUS on error - */ -QDF_STATUS lim_post_msg_api(struct mac_context *mac, struct scheduler_msg *msg); - /** * lim_post_msg_high_priority() - post high priority PE message * @mac: mac context @@ -189,20 +223,64 @@ QDF_STATUS lim_post_msg_high_priority(struct mac_context *mac, */ void lim_message_processor(struct mac_context *, struct scheduler_msg *); +#ifdef QCA_IBSS_SUPPORT +/** + * lim_handle_ibss_coalescing() - Function to handle IBSS coalescing. + * @param mac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pRxPacketInfo - Pointer to RX packet info structure + * @pe_session - pointer to pe session + * + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + * @return Status whether to process or ignore received Beacon Frame + */ +QDF_STATUS +lim_handle_ibss_coalescing(struct mac_context *mac, + tpSchBeaconStruct pBeacon, + uint8_t *pRxPacketInfo, + struct pe_session *pe_session); +#else /** - * Function to handle IBSS coalescing. - * Beacon Processing module to call this. + * lim_handle_ibss_coalescing() - Function to handle IBSS coalescing. + * @param mac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pRxPacketInfo - Pointer to RX packet info structure + * @pe_session - pointer to pe session + * + * This function is dummy + * + * @return Status whether to process or ignore received Beacon Frame */ -QDF_STATUS lim_handle_ibss_coalescing(struct mac_context *, - tpSchBeaconStruct, - uint8_t *, struct pe_session *); +static inline QDF_STATUS +lim_handle_ibss_coalescing(struct mac_context *mac, + tpSchBeaconStruct pBeacon, + uint8_t *pRxPacketInfo, + struct pe_session *pe_session) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /* / Function used by other Sirius modules to read global SME state */ static inline tLimSmeStates lim_get_sme_state(struct mac_context *mac) { return mac->lim.gLimSmeState; } -void lim_received_hb_handler(struct mac_context *, uint8_t, +/** + * lim_received_hb_handler() - This function is called by + * sch_beacon_process() upon receiving a Beacon on STA. This + * also gets called upon receiving Probe Response after heat + * beat failure is detected. + * + * @mac - global mac structure + * @chan_freq - channel frequency indicated in Beacon, Probe + * + * Response return - none + */ +void lim_received_hb_handler(struct mac_context *, uint32_t, struct pe_session *); /* / Function that triggers STA context deletion */ @@ -284,6 +362,10 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, struct bss_description *bss_desc_ptr, enum sir_roam_op_code reason); +void +lim_check_ft_initial_im_association(struct roam_offload_synch_ind *roam_synch, + struct pe_session *session_entry); + /** * pe_disconnect_callback() - Callback to handle deauth event is received * from firmware @@ -366,10 +448,10 @@ static inline void lim_get_phy_mode(struct mac_context *mac, uint32_t *phyMode, /* ----------------------------------------------------------------------- */ static inline void lim_get_rf_band_new(struct mac_context *mac, - enum band_info *band, + enum reg_wifi_band *band, struct pe_session *pe_session) { - *band = pe_session ? pe_session->limRFBand : BAND_UNKNOWN; + *band = pe_session ? pe_session->limRFBand : REG_BAND_UNKNOWN; } /** diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft.h index 6ab207d257d28a9e1c08a74ebe7140eb9f69043d..f26d5c8c81734909010732665490ff9d2a5350f8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,14 +64,39 @@ void lim_handle_ft_pre_auth_rsp(struct mac_context *mac, QDF_STATUS status, QDF_STATUS lim_ft_setup_auth_session(struct mac_context *mac, struct pe_session *pe_session); void lim_process_mlm_reassoc_cnf(struct mac_context *mac_ctx, uint32_t *msg); +/** + * lim_process_sta_mlm_add_bss_rsp_ft() - Handle ft add bss response + * @mac: Global MAC context + * @add_bss_rsp: Bss params rsp data + * @pe_session: PE Session + * + * Function to handle fast roaming add bss response in FT reassoc state, + * send reassociation Request. + * + * Return: None + */ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, - struct scheduler_msg *limMsgQ, struct pe_session *pe_session); + struct add_bss_rsp *add_bss_rsp, + struct pe_session *pe_session); void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx, tLimMlmReassocReq *reassoc_req); + +/** + * lim_preauth_scan_event_handler() - Process preauth scan events + * @mac_ctx:Pointer to global MAC structure + * @event: Scan event + * @vdev_id: vdev id + * @scan_id: scan id from WMA scan event. + * + * If scan event signifies failure or successful completion, operation + * is complete. + * If scan event signifies that STA is on foreign channel, send auth frame + * + * Return: void + */ void lim_preauth_scan_event_handler(struct mac_context *mac_ctx, - enum sir_scan_event_type event, - uint8_t session_id, - uint32_t scan_id); + enum sir_scan_event_type event, + uint8_t vdev_id, uint32_t scan_id); QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, struct pe_session *session_entry, tSirFTPreAuthReq *ft_preauth_req); #else @@ -91,15 +116,17 @@ static inline void lim_handle_ft_pre_auth_rsp(struct mac_context *mac, static inline void lim_process_mlm_reassoc_cnf(struct mac_context *mac_ctx, uint32_t *msg) {} -static inline void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, - struct scheduler_msg *limMsgQ, struct pe_session *pe_session) +static inline +void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, + struct add_bss_rsp *add_bss_rsp, + struct pe_session *pe_session) {} static inline void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx, tLimMlmReassocReq *reassoc_req) {} static inline void lim_preauth_scan_event_handler(struct mac_context *mac_ctx, enum sir_scan_event_type event, - uint8_t session_id, uint32_t scan_id) + uint8_t vdev_id, uint32_t scan_id) {} static inline int lim_process_ft_pre_auth_req(struct mac_context *mac, struct scheduler_msg *pMsg) @@ -112,11 +139,23 @@ static inline int lim_process_ft_pre_auth_req(struct mac_context *mac, void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, struct pe_session *ft_session, - struct pe_session *pe_session); + struct pe_session *pe_session, + enum wlan_phymode bss_phymode); -void lim_ft_prepare_add_bss_req(struct mac_context *mac, uint8_t updateEntry, - struct pe_session *ft_session, - struct bss_description *bssDescription); +/** + * lim_ft_prepare_add_bss_req() - Create Add Bss Req to the new AP + * @mac: Global MAC context + * @add_bss_params: Bss params including rsp data + * @pe_session: PE Session + * + * This will be used when we are ready to FT to the new AP. + * The newly created ft Session entry is passed to this function + * + * Return: None + */ +void lim_ft_prepare_add_bss_req(struct mac_context *mac, + struct pe_session *ft_session, + struct bss_description *bssDescription); QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, struct pe_session *session_entry, tSirFTPreAuthReq *ft_preauth_req); @@ -124,15 +163,15 @@ QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, static inline void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, struct pe_session *ft_session, - struct pe_session *pe_session) + struct pe_session *pe_session, + enum wlan_phymode bss_phymode) {} static inline void lim_ft_prepare_add_bss_req(struct mac_context *mac, - uint8_t updateEntry, struct pe_session *ft_session, + struct pe_session *ft_session, struct bss_description *bssDescription) {} #endif -bool lim_process_ft_update_key(struct mac_context *mac, uint32_t *msg_buf); QDF_STATUS lim_process_ft_aggr_qos_req(struct mac_context *mac, uint32_t *msg_buf); void lim_process_ft_aggr_qos_rsp(struct mac_context *mac, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft_defs.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft_defs.h index 60f6848f8e5f404c28df599b9223786a20cae353..b851c1a52613e3193c32a6d19de15b5fe89cc74e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft_defs.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_ft_defs.h @@ -51,7 +51,7 @@ typedef struct sSirFTPreAuthReq { * We expect only one response per request. */ bool bPreAuthRspProcessed; - uint8_t preAuthchannelNum; + uint16_t pre_auth_channel_freq; /* BSSID currently associated to suspend the link */ tSirMacAddr currbssId; tSirMacAddr preAuthbssId; /* BSSID to preauth to */ @@ -68,7 +68,7 @@ typedef struct sSirFTPreAuthReq { typedef struct sSirFTPreAuthRsp { uint16_t messageType; /* eWNI_SME_FT_PRE_AUTH_RSP */ uint16_t length; - uint8_t smeSessionId; + uint8_t vdev_id; tSirMacAddr preAuthbssId; /* BSSID to preauth to */ QDF_STATUS status; uint16_t ft_ies_length; @@ -83,7 +83,7 @@ typedef struct sSirFTPreAuthRsp { typedef struct sSirFTUpdateKeyInfo { uint16_t messageType; uint16_t length; - uint32_t smeSessionId; + uint32_t vdev_id; struct qdf_mac_addr bssid; tSirKeyMaterial keyMaterial; } tSirFTUpdateKeyInfo, *tpSirFTUpdateKeyInfo; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_global.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_global.h index be266725c364252b32344fed98a83f18a7a41e5f..6a71333aaae5051ce494cd16b38524fb782a0e05 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_global.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_global.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -266,6 +266,7 @@ struct lim_sta_context { #ifdef WLAN_FEATURE_11AX bool he_capable; #endif + bool force_1x1; uint8_t *owe_ie; uint32_t owe_ie_len; }; @@ -414,6 +415,7 @@ typedef enum eLimChannelSwitchState { /* Channel Switch Info */ typedef struct sLimChannelSwitchInfo { tLimChannelSwitchState state; + uint32_t sw_target_freq; uint8_t primaryChannel; uint8_t ch_center_freq_seg0; uint8_t ch_center_freq_seg1; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_session.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_session.h index 61479f3d840736fce93990c05ecb0bc11ca60735..698b686bde86604d3947a7db8cf130f84863a83a 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_session.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_session.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -37,7 +37,8 @@ typedef struct sPowersaveoffloadInfo { #ifdef WLAN_FEATURE_11W struct comeback_timer_info { struct mac_context *mac; - uint8_t session_id; + uint8_t vdev_id; + uint8_t retried; tLimMlmStates lim_prev_mlm_state; /* Previous MLM State */ tLimMlmStates lim_mlm_state; /* MLM State */ }; @@ -135,6 +136,9 @@ struct obss_detection_cfg { * @ap_ecsa_wakelock: wakelock to complete CSA operation. * @ap_ecsa_runtime_lock: runtime lock to complete SAP CSA operation. * to Adaptive 11R network + * @prev_auth_seq_num: Sequence number of previously received auth frame to + * detect duplicate frames. + * @prev_auth_mac_addr: mac_addr of the sta correspond to @prev_auth_seq_num */ struct pe_session { /* To check session table is in use or free */ @@ -151,7 +155,6 @@ struct pe_session { tSirMacAddr bssId; tSirMacAddr self_mac_addr; tSirMacSSid ssId; - uint8_t bss_idx; uint8_t valid; tLimMlmStates limMlmState; /* MLM State */ tLimMlmStates limPrevMlmState; /* Previous MLM State */ @@ -180,7 +183,7 @@ struct pe_session { uint8_t htRecommendedTxWidthSet; /* Identifies the 40 MHz extension channel */ ePhyChanBondState htSecondaryChannelOffset; - enum band_info limRFBand; + enum reg_wifi_band limRFBand; uint8_t limIbssActive; /* TO SUPPORT CONCURRENCY */ /* These global varibales moved to session Table to support BT-AMP : Oct 9th review */ @@ -192,7 +195,7 @@ struct pe_session { /* Parameters For Reassociation */ tSirMacAddr limReAssocbssId; - tSirMacChanNum limReassocChannelId; + uint32_t lim_reassoc_chan_freq; /* CB paramaters required/duplicated for Reassoc since re-assoc mantains its own params in lim */ uint8_t reAssocHtSupportedChannelWidthSet; uint8_t reAssocHtRecommendedTxWidthSet; @@ -206,20 +209,14 @@ struct pe_session { /** BSS Table parameters **/ - /* - * staId: Start BSS: this is the Sta Id for the BSS. - * Join: this is the selfStaId - * In both cases above, the peer STA ID wll be stored in dph hash table. - */ - uint16_t staId; uint16_t statypeForBss; /* to know session is for PEER or SELF */ uint8_t shortSlotTimeSupported; uint8_t dtimPeriod; tSirMacRateSet rateSet; tSirMacRateSet extRateSet; tSirMacHTOperatingMode htOperMode; - uint8_t currentOperChannel; - uint8_t currentReqChannel; + qdf_freq_t curr_op_freq; + uint32_t curr_req_chan_freq; uint8_t LimRxedBeaconCntDuringHB; /* Time stamp of the last beacon received from the BSS to which STA is connected. */ @@ -232,7 +229,7 @@ struct pe_session { uint8_t *beacon; /* Used to store last beacon / probe response before assoc. */ uint32_t assocReqLen; - uint8_t *assocReq; /* Used to store association request frame sent out while associating. */ + uint8_t *assoc_req; /* Used to store association request frame */ uint32_t assocRspLen; uint8_t *assocRsp; /* Used to store association response received while associating */ @@ -313,10 +310,8 @@ struct pe_session { uint8_t limWmeEnabled:1; /* WME */ uint8_t limWsmEnabled:1; /* WSM */ uint8_t limHcfEnabled:1; - uint8_t lim11dEnabled:1; #ifdef WLAN_FEATURE_11W uint8_t limRmfEnabled:1; /* 11W */ - tAniEdType mgmt_cipher_type; #endif uint32_t lim11hEnable; @@ -489,6 +484,10 @@ struct pe_session { /* Fast Transition (FT) */ tftPEContext ftPEContext; bool isNonRoamReassoc; +#ifdef WLAN_FEATURE_11W + qdf_mc_timer_t pmf_retry_timer; + struct comeback_timer_info pmf_retry_timer_info; +#endif /* WLAN_FEATURE_11W */ uint8_t is_key_installed; /* timer for resetting protection fileds at regular intervals */ qdf_mc_timer_t protection_fields_reset_timer; @@ -540,12 +539,14 @@ struct pe_session { tDot11fIEhe_cap he_config; tDot11fIEhe_op he_op; uint32_t he_sta_obsspd; + bool he_6ghz_band; #ifdef WLAN_FEATURE_11AX_BSS_COLOR tDot11fIEbss_color_change he_bss_color_change; struct bss_color_info bss_color_info[MAX_BSS_COLOR_VALUE]; uint8_t bss_color_changing; #endif #endif + struct deauth_retry_params deauth_retry; bool enable_bcast_probe_rsp; uint8_t ht_client_cnt; bool force_24ghz_in_ht20; @@ -556,6 +557,7 @@ struct pe_session { #endif /* previous auth frame's sequence number */ uint16_t prev_auth_seq_num; + tSirMacAddr prev_auth_mac_addr; struct obss_detection_cfg obss_offload_cfg; struct obss_detection_cfg current_obss_detection; bool is_session_obss_offload_enabled; @@ -579,13 +581,11 @@ struct pe_session { bool enable_session_twt_support; uint32_t cac_duration_ms; tSirResultCodes stop_bss_reason; + uint16_t prot_status_code; + tSirResultCodes result_code; uint32_t dfs_regdomain; }; -struct session_params { - uint16_t session_id; -}; - /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ @@ -652,18 +652,32 @@ struct pe_session *pe_find_session_by_bssid(struct mac_context *mac, uint8_t *bs uint8_t *sessionId); /** - * pe_find_session_by_bss_idx() - looks up the PE session given the bss_idx. + * pe_find_session_by_vdev_id() - looks up the PE session given the vdev_id. + * @mac: pointer to global adapter context + * @vdev_id: vdev id the session * - * @mac: pointer to global adapter context - * @bss_idx: bss index of the session + * Return: pointer to the session context or NULL if session is not found. + */ +struct pe_session *pe_find_session_by_vdev_id(struct mac_context *mac, + uint8_t vdev_id); + +/** + * pe_find_session_by_vdev_id_and_state() - Find PE session by vdev_id and + * mlm state. + * @mac: pointer to global adapter context + * @vdev_id: vdev id the session + * @vdev_id: vdev id the session * - * This function returns the session context if the session - * corresponding to the given bss_idx is found in the PE session table. + * During LFR2 roaming, new pe session is created before old pe session + * deleted, the 2 pe sessions have different pe session id, but same vdev id, + * can't get correct pe session by vdev id at this time. * * Return: pointer to the session context or NULL if session is not found. */ -struct pe_session *pe_find_session_by_bss_idx(struct mac_context *mac, - uint8_t bss_idx); +struct pe_session +*pe_find_session_by_vdev_id_and_state(struct mac_context *mac, + uint8_t vdev_id, + enum eLimMlmStates lim_state); /** * pe_find_session_by_peer_sta() - looks up the PE session given the Peer @@ -697,21 +711,6 @@ struct pe_session *pe_find_session_by_peer_sta(struct mac_context *mac, uint8_t struct pe_session *pe_find_session_by_session_id(struct mac_context *mac, uint8_t sessionId); -/** - * pe_find_session_by_bssid() - looks up the PE session given staid. - * - * @mac: pointer to global adapter context - * @staid: StaId of the session - * @sessionId: session ID is returned here, if session is found. - * - * This function returns the session context and the session ID if the session - * corresponding to the given StaId is found in the PE session table. - * - * Return: pointer to the session context or NULL if session is not found. - */ -struct pe_session *pe_find_session_by_sta_id(struct mac_context *mac, uint8_t staid, - uint8_t *sessionId); - /** * pe_delete_session() - deletes the PE session given the session ID. * @@ -722,20 +721,6 @@ struct pe_session *pe_find_session_by_sta_id(struct mac_context *mac, uint8_t st */ void pe_delete_session(struct mac_context *mac, struct pe_session *pe_session); - -/** - * pe_find_session_by_sme_session_id() - looks up the PE session for given sme - * session id - * @mac_ctx: pointer to global adapter context - * @sme_session_id: sme session id - * - * looks up the PE session for given sme session id - * - * Return: pe session entry for given sme session if found else NULL - */ -struct pe_session *pe_find_session_by_sme_session_id(struct mac_context *mac_ctx, - uint8_t sme_session_id); - /** * pe_find_session_by_scan_id() - looks up the PE session for given scan id * @mac_ctx: pointer to global adapter context diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_trace.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_trace.h index 9884a99e22edc470e969f5ddd86285e845fb0ba9..80a656ac437678c0ea0439c44074fa6deeed1ba7 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_trace.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/lim_trace.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_api.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_api.h index 45f7ddab16cf2979675b7506da88ea4016749995..c874bf378684731070b45dbfcec9709453b80825 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_api.h @@ -90,6 +90,24 @@ QDF_STATUS rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, tpSirBeaconReportXmitInd beacon_xmit_ind); +/** + * rrm_reject_req - Reject rrm request + * @radiomes_report: radio measurement report + * @rrm_req: Array of Measurement request IEs + * @num_report: Num of report + * @index: Measurement index + * @measurement_type: Measurement Type + * + * Reject the Radio Resource Measurement request, if one is + * already in progress + * + * Return: QDF_STATUS + */ +QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report, + tDot11fRadioMeasurementRequest *rrm_req, + uint8_t *num_report, uint8_t index, + uint8_t measurement_type); + void lim_update_rrm_capability(struct mac_context *mac_ctx, struct join_req *join_req); #endif diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_global.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_global.h index 04bfb6addad925d3030d8b7d9993ceefd730057e..9e257e762d3cde17ecdbd127513bd795f456fc13 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_global.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/include/rrm_global.h @@ -27,7 +27,9 @@ ========================================================================*/ -#define MAX_MEASUREMENT_REQUEST 2 +#define MAX_MEASUREMENT_REQUEST 5 +#define MAX_NUM_CHANNELS 255 + #define DEFAULT_RRM_IDX 0 typedef enum eRrmRetStatus { @@ -43,10 +45,11 @@ typedef enum eRrmMsgReqSource { eRRM_MSG_SOURCE_ESE_UPLOAD = 3, /* ese upload approach */ } tRrmMsgReqSource; -typedef struct sSirChannelInfo { - uint8_t regulatoryClass; - uint8_t channelNum; -} tSirChannelInfo, *tpSirChannelInfo; +struct sir_channel_info { + uint8_t reg_class; + uint8_t chan_num; + uint32_t chan_freq; +}; typedef struct sSirBeaconReportReqInd { uint16_t messageType; /* eWNI_SME_BEACON_REPORT_REQ_IND */ @@ -55,14 +58,14 @@ typedef struct sSirBeaconReportReqInd { tSirMacAddr bssId; uint16_t measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; /* ms */ uint16_t randomizationInterval; /* ms */ - tSirChannelInfo channelInfo; + struct sir_channel_info channel_info; /* 0: wildcard */ tSirMacAddr macaddrBssid; /* 0:Passive, 1: Active, 2: table mode */ uint8_t fMeasurementtype[SIR_ESE_MAX_MEAS_IE_REQS]; tAniSSID ssId; /* May be wilcard. */ uint16_t uDialogToken; - struct report_channel_list channelList; /* From AP channel report. */ + struct report_channel_list channel_list; /* From AP channel report. */ tRrmMsgReqSource msgSource; } tSirBeaconReportReqInd, *tpSirBeaconReportReqInd; @@ -217,7 +220,10 @@ typedef struct sRrmPEContext { /* Dialog token for the request initiated from station. */ uint8_t DialogToken; uint16_t prev_rrm_report_seq_num; + uint8_t num_active_request; tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST]; + uint32_t beacon_rpt_chan_list[MAX_NUM_CHANNELS]; + uint8_t beacon_rpt_chan_num; } tRrmPEContext, *tpRrmPEContext; /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_admit_control.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_admit_control.c index b910eb95a91e03651d8fe7ca92b9ee14eb512c32..2ab5220c03203ea13ba2dc65138cb360582b2720 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_admit_control.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_admit_control.c @@ -604,9 +604,10 @@ lim_validate_access_policy(struct mac_context *mac, } if (retval != QDF_STATUS_SUCCESS) - pe_warn("accPol: %d staId: %d lle: %d wme: %d wsm: %d", - accessPolicy, pSta->staIndex, pSta->lleEnabled, - pSta->wmeEnabled, pSta->wsmEnabled); + pe_warn("accPol: %d lle: %d wme: %d wsm: %d sta mac " + QDF_MAC_ADDR_FMT, accessPolicy, pSta->lleEnabled, + pSta->wmeEnabled, pSta->wsmEnabled, + QDF_MAC_ADDR_REF(pSta->staAddr)); return retval; } @@ -792,7 +793,6 @@ QDF_STATUS lim_admit_control_init(struct mac_context *mac) \fn lim_send_hal_msg_add_ts \brief Send halMsg_AddTs to HAL \param struct mac_context *mac - \param uint16_t staIdx \param uint8_t tspecIdx \param struct mac_tspec_ie tspecIE \param tSirTclasInfo *tclasInfo @@ -803,14 +803,12 @@ QDF_STATUS lim_admit_control_init(struct mac_context *mac) #ifdef FEATURE_WLAN_ESE QDF_STATUS lim_send_hal_msg_add_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct mac_tspec_ie tspecIE, uint8_t sessionId, uint16_t tsm_interval) #else QDF_STATUS lim_send_hal_msg_add_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct mac_tspec_ie tspecIE, uint8_t sessionId) @@ -831,7 +829,6 @@ lim_send_hal_msg_add_ts(struct mac_context *mac, if (!pAddTsParam) return QDF_STATUS_E_NOMEM; - pAddTsParam->sta_idx = staIdx; pAddTsParam->tspec_idx = tspecIdx; qdf_mem_copy(&pAddTsParam->tspec, &tspecIE, sizeof(struct mac_tspec_ie)); @@ -870,7 +867,6 @@ lim_send_hal_msg_add_ts(struct mac_context *mac, \fn lim_send_hal_msg_del_ts \brief Send halMsg_AddTs to HAL \param struct mac_context *mac - \param uint16_t staIdx \param uint8_t tspecIdx \param tSirAddtsReqInfo addts \return QDF_STATUS - status @@ -878,7 +874,6 @@ lim_send_hal_msg_add_ts(struct mac_context *mac, QDF_STATUS lim_send_hal_msg_del_ts(struct mac_context *mac, - uint16_t staIdx, uint8_t tspecIdx, struct delts_req_info delts, uint8_t sessionId, uint8_t *bssId) @@ -896,7 +891,6 @@ lim_send_hal_msg_del_ts(struct mac_context *mac, msg.bodyval = 0; /* filling message parameters. */ - pDelTsParam->staIdx = staIdx; pDelTsParam->tspecIdx = tspecIdx; qdf_mem_copy(&pDelTsParam->bssId, bssId, sizeof(tSirMacAddr)); @@ -998,8 +992,8 @@ void lim_process_hal_add_ts_rsp(struct mac_context *mac, /* Delete TSPEC */ /* 090803: Pull the hash table from the session */ - pSta = dph_lookup_assoc_id(mac, pAddTsRspMsg->sta_idx, &assocId, - &pe_session->dph.dphHashTable); + pSta = dph_lookup_hash_entry(mac, peerMacAddr, &assocId, + &pe_session->dph.dphHashTable); if (pSta) lim_admit_control_delete_ts(mac, assocId, &pAddTsRspMsg->tspec.tsinfo, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c index f68373961b3a152066417a6434d424457073ae1c..44175b47c204249e9f7eddd36cfb301b8bc452fa 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c @@ -75,7 +75,17 @@ #include "cfg_ucfg_api.h" #include "wlan_mlme_public_struct.h" #include "wlan_scan_utils_api.h" -#include "wlan_pkt_capture_ucfg_api.h" +#include +#include + +struct pe_hang_event_fixed_param { + uint16_t tlv_header; + uint8_t vdev_id; + uint8_t limmlmstate; + uint8_t limprevmlmstate; + uint8_t limsmestate; + uint8_t limprevsmestate; +} qdf_packed; static void __lim_init_bss_vars(struct mac_context *mac) { @@ -586,6 +596,17 @@ static inline void lim_nan_register_callbacks(struct mac_context *mac_ctx) } #endif +#ifdef WLAN_FEATURE_11W +void lim_stop_pmfcomeback_timer(struct pe_session *session) +{ + if (session->opmode != QDF_STA_MODE) + return; + + qdf_mc_timer_stop(&session->pmf_retry_timer); + session->pmf_retry_timer_info.retried = false; +} +#endif + /* * pe_shutdown_notifier_cb - Shutdown notifier callback * @ctx: Pointer to Global MAC structure @@ -605,6 +626,7 @@ static void pe_shutdown_notifier_cb(void *ctx) if (LIM_IS_AP_ROLE(session)) qdf_mc_timer_stop(&session-> protection_fields_reset_timer); + lim_stop_pmfcomeback_timer(session); } } } @@ -632,8 +654,7 @@ static bool is_mgmt_protected(uint32_t vdev_id, if (!mac_ctx) return false; - session = pe_find_session_by_sme_session_id(mac_ctx, - vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { /* couldn't find session */ pe_err("Session not found for vdev_id: %d", vdev_id); @@ -656,6 +677,7 @@ static bool is_mgmt_protected(uint32_t vdev_id, return protected; } + #else /** * is_mgmt_protected - check RMF enabled for the peer @@ -729,6 +751,54 @@ static QDF_STATUS lim_unregister_sap_bcn_callback(struct mac_context *mac_ctx) return status; } +static int pe_hang_event_notifier_call(struct notifier_block *block, + unsigned long state, + void *data) +{ + qdf_notif_block *notif_block = qdf_container_of(block, qdf_notif_block, + notif_block); + struct mac_context *mac; + struct pe_session *session; + struct qdf_notifer_data *pe_hang_data = data; + uint8_t *pe_data; + uint8_t i; + struct pe_hang_event_fixed_param *cmd; + size_t size; + + if (!data) + return NOTIFY_STOP_MASK; + + mac = notif_block->priv_data; + if (!mac) + return NOTIFY_STOP_MASK; + + size = sizeof(*cmd); + for (i = 0; i < mac->lim.maxBssId; i++) { + session = &mac->lim.gpSession[i]; + if (!session->valid) + continue; + if (pe_hang_data->offset + size > QDF_WLAN_HANG_FW_OFFSET) + return NOTIFY_STOP_MASK; + + pe_data = (pe_hang_data->hang_data + pe_hang_data->offset); + cmd = (struct pe_hang_event_fixed_param *)pe_data; + QDF_HANG_EVT_SET_HDR(&cmd->tlv_header, HANG_EVT_TAG_LEGACY_MAC, + QDF_HANG_GET_STRUCT_TLVLEN(*cmd)); + cmd->vdev_id = session->vdev_id; + cmd->limmlmstate = session->limMlmState; + cmd->limprevmlmstate = session->limPrevMlmState; + cmd->limsmestate = session->limSmeState; + cmd->limprevsmestate = session->limPrevSmeState; + pe_hang_data->offset += size; + } + + return NOTIFY_OK; +} + +static qdf_notif_block pe_hang_event_notifier = { + .notif_block.notifier_call = pe_hang_event_notifier_call, +}; + /** ------------------------------------------------------------- \fn pe_open \brief will be called in Open sequence from mac_open @@ -758,9 +828,9 @@ QDF_STATUS pe_open(struct mac_context *mac, struct cds_config_info *cds_cfg) return QDF_STATUS_E_NOMEM; } - mac->lim.limTimers.gpLimCnfWaitTimer = + mac->lim.lim_timers.gpLimCnfWaitTimer = qdf_mem_malloc(sizeof(TX_TIMER) * (mac->lim.maxStation + 1)); - if (!mac->lim.limTimers.gpLimCnfWaitTimer) { + if (!mac->lim.lim_timers.gpLimCnfWaitTimer) { status = QDF_STATUS_E_NOMEM; goto pe_open_timer_fail; } @@ -797,14 +867,17 @@ QDF_STATUS pe_open(struct mac_context *mac, struct cds_config_info *cds_cfg) pe_err("%s: Shutdown notifier register failed", __func__); } + pe_hang_event_notifier.priv_data = mac; + qdf_hang_event_register_notifier(&pe_hang_event_notifier); + return status; /* status here will be QDF_STATUS_SUCCESS */ pe_open_lock_fail: qdf_mem_free(mac->lim.gpSession); mac->lim.gpSession = NULL; pe_open_psession_fail: - qdf_mem_free(mac->lim.limTimers.gpLimCnfWaitTimer); - mac->lim.limTimers.gpLimCnfWaitTimer = NULL; + qdf_mem_free(mac->lim.lim_timers.gpLimCnfWaitTimer); + mac->lim.lim_timers.gpLimCnfWaitTimer = NULL; pe_open_timer_fail: pe_free_dph_node_array_buffer(); @@ -825,6 +898,7 @@ QDF_STATUS pe_close(struct mac_context *mac) if (ANI_DRIVER_TYPE(mac) == QDF_DRIVER_TYPE_MFG) return QDF_STATUS_SUCCESS; + qdf_hang_event_unregister_notifier(&pe_hang_event_notifier); lim_cleanup(mac); lim_unregister_sap_bcn_callback(mac); @@ -838,8 +912,8 @@ QDF_STATUS pe_close(struct mac_context *mac) if (mac->lim.gpSession[i].valid == true) pe_delete_session(mac, &mac->lim.gpSession[i]); } - qdf_mem_free(mac->lim.limTimers.gpLimCnfWaitTimer); - mac->lim.limTimers.gpLimCnfWaitTimer = NULL; + qdf_mem_free(mac->lim.lim_timers.gpLimCnfWaitTimer); + mac->lim.lim_timers.gpLimCnfWaitTimer = NULL; qdf_mem_free(mac->lim.gpSession); mac->lim.gpSession = NULL; @@ -893,10 +967,6 @@ void pe_stop(struct mac_context *mac) static void pe_free_nested_messages(struct scheduler_msg *msg) { switch (msg->type) { - case WMA_SET_LINK_STATE_RSP: - pe_debug("WMA_SET_LINK_STATE_RSP"); - qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg); - break; default: break; } @@ -1186,13 +1256,6 @@ static QDF_STATUS pe_handle_mgmt_frame(struct wlan_objmgr_psoc *psoc, uint8_t *pRxPacketInfo; int ret; - /* skip offload packets */ - if (ucfg_pkt_capture_get_mode(psoc) && - mgmt_rx_params->status & WMI_RX_OFFLOAD_MON_MODE) { - qdf_nbuf_free(buf); - return QDF_STATUS_SUCCESS; - } - mac = cds_get_context(QDF_MODULE_ID_PE); if (!mac) { /* cannot log a failure without a valid mac */ @@ -1331,25 +1394,11 @@ void pe_register_callbacks_with_wma(struct mac_context *mac, pe_err("Registering roaming callbacks with WMA failed"); } -/** - *\brief lim_received_hb_handler() - * - * This function is called by sch_beacon_process() upon - * receiving a Beacon on STA. This also gets called upon - * receiving Probe Response after heat beat failure is - * detected. - * - * param mac - global mac structure - * param channel - channel number indicated in Beacon, Probe Response - * return - none - */ - void -lim_received_hb_handler(struct mac_context *mac, uint8_t channelId, +lim_received_hb_handler(struct mac_context *mac, uint32_t chan_freq, struct pe_session *pe_session) { - if ((channelId == 0) - || (channelId == pe_session->currentOperChannel)) + if (chan_freq == 0 || chan_freq == pe_session->curr_op_freq) pe_session->LimRxedBeaconCntDuringHB++; pe_session->pmmOffloadInfo.bcnmiss = false; @@ -1401,22 +1450,15 @@ lim_update_overlap_sta_param(struct mac_context *mac, tSirMacAddr bssId, } } +#ifdef QCA_IBSS_SUPPORT /** - * lim_ibss_enc_type_matched + * lim_ibss_enc_type_matched() - API to check enc type match + * @param pBeacon - Parsed Beacon Frame structure + * @param pSession - Pointer to the PE session * - ***FUNCTION: * This function compares the encryption type of the peer with self * while operating in IBSS mode and detects mismatch. * - ***LOGIC: - * - ***ASSUMPTIONS: - * - ***NOTE: - * - * @param pBeacon - Parsed Beacon Frame structure - * @param pSession - Pointer to the PE session - * * @return true if encryption type is matched; false otherwise */ static bool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon, @@ -1449,26 +1491,6 @@ static bool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon, return false; } -/** - * lim_handle_ibs_scoalescing() - * - ***FUNCTION: - * This function is called upon receiving Beacon/Probe Response - * while operating in IBSS mode. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * - ***NOTE: - * - * @param mac - Pointer to Global MAC structure - * @param pBeacon - Parsed Beacon Frame structure - * @param pRxPacketInfo - Pointer to RX packet info structure - * - * @return Status whether to process or ignore received Beacon Frame - */ - QDF_STATUS lim_handle_ibss_coalescing(struct mac_context *mac, tpSchBeaconStruct pBeacon, @@ -1487,7 +1509,7 @@ lim_handle_ibss_coalescing(struct mac_context *mac, */ if ((!pBeacon->capabilityInfo.ibss) || lim_cmp_ssid(&pBeacon->ssId, pe_session) || - (pe_session->currentOperChannel != pBeacon->channelNumber)) + (pe_session->curr_op_freq != pBeacon->chan_freq)) retCode = QDF_STATUS_E_INVAL; else if (lim_ibss_enc_type_matched(pBeacon, pe_session) != true) { pe_debug("peer privacy: %d peer wpa: %d peer rsn: %d self encType: %d", @@ -1510,6 +1532,7 @@ lim_handle_ibss_coalescing(struct mac_context *mac, } return retCode; } /*** end lim_handle_ibs_scoalescing() ***/ +#endif /** * lim_enc_type_matched() - matches security type of incoming beracon with @@ -1619,13 +1642,13 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac, { uint8_t len; struct ap_new_caps apNewCaps; - uint8_t newChannel; + uint32_t new_chan_freq; QDF_STATUS status = QDF_STATUS_SUCCESS; bool security_caps_matched = true; apNewCaps.capabilityInfo = lim_get_u16((uint8_t *) &pBeacon->capabilityInfo); - newChannel = (uint8_t) pBeacon->channelNumber; + new_chan_freq = pBeacon->chan_freq; security_caps_matched = lim_enc_type_matched(mac, pBeacon, pe_session); @@ -1638,8 +1661,8 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac, SIR_MAC_GET_PRIVACY(pe_session->limCurrentBssCaps)) || (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) != SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps)) || - ((newChannel != pe_session->currentOperChannel) && - (newChannel != 0)) || + ((new_chan_freq != pe_session->curr_op_freq) && + (new_chan_freq != 0)) || (false == security_caps_matched) ))) { if (false == pe_session->fWaitForProbeRsp) { @@ -1653,12 +1676,13 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac, pe_session->fWaitForProbeRsp = true; pe_warn("AP capabilities are not matching, sending directed probe request"); status = - lim_send_probe_req_mgmt_frame(mac, &pe_session->ssId, - pe_session->bssId, - pe_session->currentOperChannel, - pe_session->self_mac_addr, - pe_session->dot11mode, - NULL, NULL); + lim_send_probe_req_mgmt_frame( + mac, &pe_session->ssId, + pe_session->bssId, + pe_session->curr_op_freq, + pe_session->self_mac_addr, + pe_session->dot11mode, + NULL, NULL); if (QDF_STATUS_SUCCESS != status) { pe_err("send ProbeReq failed"); @@ -1675,9 +1699,9 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac, qdf_mem_copy(apNewCaps.bssId.bytes, pe_session->bssId, QDF_MAC_ADDR_SIZE); - if (newChannel != pe_session->currentOperChannel) { - pe_err("Channel Change from %d --> %d Ignoring beacon!", - pe_session->currentOperChannel, newChannel); + if (new_chan_freq != pe_session->curr_op_freq) { + pe_err("Channel freq Change from %d --> %d Ignoring beacon!", + pe_session->curr_op_freq, new_chan_freq); return; } @@ -1695,8 +1719,7 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac, (pBeacon->rsnPresent || pBeacon->wpaPresent)) { pe_err("BSS Caps (Privacy) bit 0 in beacon, but WPA or RSN IE present, Ignore Beacon!"); return; - } else - apNewCaps.channelId = pe_session->currentOperChannel; + } qdf_mem_copy((uint8_t *) &apNewCaps.ssId, (uint8_t *) &pBeacon->ssId, pBeacon->ssId.length + 1); @@ -1823,7 +1846,7 @@ void lim_ps_offload_handle_missed_beacon_ind(struct mac_context *mac, { struct missed_beacon_ind *missed_beacon_ind = msg->bodyptr; struct pe_session *pe_session = - pe_find_session_by_bss_idx(mac, missed_beacon_ind->bss_idx); + pe_find_session_by_vdev_id(mac, missed_beacon_ind->bss_idx); if (!pe_session) { pe_err("session does not exist for vdev_id %d", @@ -1880,6 +1903,65 @@ void lim_fill_join_rsp_ht_caps(struct pe_session *session, #endif #ifdef WLAN_FEATURE_ROAM_OFFLOAD +#ifdef WLAN_FEATURE_11W +static void pe_set_rmf_caps(struct mac_context *mac_ctx, + struct pe_session *ft_session, + struct roam_offload_synch_ind *roam_synch) +{ + uint8_t *assoc_body; + uint16_t len; + tDot11fReAssocRequest *assoc_req; + uint32_t status; + tSirMacRsnInfo rsn_ie; + + assoc_body = (uint8_t *)roam_synch + roam_synch->reassoc_req_offset + + sizeof(tSirMacMgmtHdr); + len = roam_synch->reassoc_req_length - sizeof(tSirMacMgmtHdr); + + assoc_req = qdf_mem_malloc(sizeof(*assoc_req)); + if (!assoc_req) + return; + + /* delegate to the framesc-generated code, */ + status = dot11f_unpack_re_assoc_request(mac_ctx, assoc_body, len, + assoc_req, false); + if (DOT11F_FAILED(status)) { + pe_err("Failed to parse a Re-association Request (0x%08x, %d bytes):", + status, len); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, + assoc_body, len); + qdf_mem_free(assoc_req); + return; + } else if (DOT11F_WARNED(status)) { + pe_debug("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):", + status, len); + } + ft_session->limRmfEnabled = false; + if (!assoc_req->RSNOpaque.present) { + qdf_mem_free(assoc_req); + return; + } + rsn_ie.info[0] = WLAN_ELEMID_RSN; + rsn_ie.info[1] = assoc_req->RSNOpaque.num_data; + + rsn_ie.length = assoc_req->RSNOpaque.num_data + 2; + qdf_mem_copy(&rsn_ie.info[2], assoc_req->RSNOpaque.data, + assoc_req->RSNOpaque.num_data); + qdf_mem_free(assoc_req); + wlan_set_vdev_crypto_prarams_from_ie(ft_session->vdev, rsn_ie.info, + rsn_ie.length); + + ft_session->limRmfEnabled = + lim_get_vdev_rmf_capable(mac_ctx, ft_session); +} +#else +static inline void pe_set_rmf_caps(struct mac_context *mac_ctx, + struct pe_session *ft_session, + struct roam_offload_synch_ind *roam_synch) +{ +} +#endif + /** * sir_parse_bcn_fixed_fields() - Parse fixed fields in Beacon IE's * @@ -1927,7 +2009,7 @@ lim_roam_gen_mbssid_beacon(struct mac_context *mac, bcn_prb_ptr = (uint8_t *)roam_ind + roam_ind->beaconProbeRespOffset; - rx_param.channel = wlan_freq_to_chan(roam_ind->chan_freq); + rx_param.chan_freq = roam_ind->chan_freq; rx_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(mac->pdev); rx_param.rssi = roam_ind->rssi; @@ -1952,8 +2034,8 @@ lim_roam_gen_mbssid_beacon(struct mac_context *mac, scan_entry = scan_node->entry; if (qdf_is_macaddr_equal(&roam_ind->bssid, &scan_entry->bssid)) { - pe_debug("matched BSSID %pM bcn len %d profiles %d", - scan_entry->bssid.bytes, + pe_debug("matched BSSID "QDF_MAC_ADDR_FMT" bcn len %d profiles %d", + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes), scan_entry->raw_frame.len, list_count); nontx_bcn_prbrsp = scan_entry->raw_frame.ptr; @@ -2048,17 +2130,17 @@ lim_roam_gen_beacon_descr(struct mac_context *mac, ie_offset = SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET; if (qdf_is_macaddr_zero((struct qdf_mac_addr *)mac_hdr->bssId)) { - pe_debug("bssid is 0 in beacon/probe update it with bssId %pM in sync ind", - roam_ind->bssid.bytes); + pe_debug("bssid is 0 in beacon/probe update it with bssId "QDF_MAC_ADDR_FMT" in sync ind", + QDF_MAC_ADDR_REF(roam_ind->bssid.bytes)); qdf_mem_copy(mac_hdr->bssId, roam_ind->bssid.bytes, sizeof(tSirMacAddr)); } if (qdf_mem_cmp(&roam_ind->bssid.bytes, &mac_hdr->bssId, QDF_MAC_ADDR_SIZE) != 0) { - pe_debug("LFR3:MBSSID Beacon/Prb Rsp: %d bssid %pM", + pe_debug("LFR3:MBSSID Beacon/Prb Rsp: %d bssid "QDF_MAC_ADDR_FMT, roam_ind->isBeacon, - mac_hdr->bssId); + QDF_MAC_ADDR_REF(mac_hdr->bssId)); /* * Its a MBSSID non-tx BSS roaming scenario. * Generate non tx BSS beacon/probe response @@ -2142,10 +2224,10 @@ lim_roam_fill_bss_descr(struct mac_context *mac, qdf_mem_free(parsed_frm_ptr); return QDF_STATUS_E_FAILURE; } - pe_debug("LFR3:Beacon/Prb Rsp: %d bssid %pM beacon %pM", + pe_debug("LFR3:Beacon/Prb Rsp: %d bssid "QDF_MAC_ADDR_FMT" beacon "QDF_MAC_ADDR_FMT, roam_synch_ind_ptr->isBeacon, - roam_synch_ind_ptr->bssid.bytes, - mac_hdr->bssId); + QDF_MAC_ADDR_REF(roam_synch_ind_ptr->bssid.bytes), + QDF_MAC_ADDR_REF(mac_hdr->bssId)); status = lim_roam_gen_beacon_descr(mac, roam_synch_ind_ptr, @@ -2174,25 +2256,33 @@ lim_roam_fill_bss_descr(struct mac_context *mac, sizeof(bss_desc_ptr->length) + ie_len); bss_desc_ptr->fProbeRsp = !roam_synch_ind_ptr->isBeacon; + bss_desc_ptr->rssi = roam_synch_ind_ptr->rssi; /* Copy Timestamp */ bss_desc_ptr->scansystimensec = qdf_get_monotonic_boottime_ns(); - if (parsed_frm_ptr->dsParamsPresent) { - bss_desc_ptr->channelId = parsed_frm_ptr->channelNumber; + if (parsed_frm_ptr->he_op.oper_info_6g_present) { + bss_desc_ptr->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev, + parsed_frm_ptr->he_op.oper_info_6g.info.primary_ch, + BIT(REG_BAND_6G)); + } else if (parsed_frm_ptr->dsParamsPresent) { + bss_desc_ptr->chan_freq = parsed_frm_ptr->chan_freq; } else if (parsed_frm_ptr->HTInfo.present) { - bss_desc_ptr->channelId = parsed_frm_ptr->HTInfo.primaryChannel; + bss_desc_ptr->chan_freq = + wlan_reg_chan_to_freq(mac->pdev, + parsed_frm_ptr->HTInfo. + primaryChannel); } else { /* * If DS Params or HTIE is not present in the probe resp or * beacon, then use the channel frequency provided by firmware * to fill the channel in the BSS descriptor.*/ - bss_desc_ptr->channelId = - cds_freq_to_chan(roam_synch_ind_ptr->chan_freq); + bss_desc_ptr->chan_freq = roam_synch_ind_ptr->chan_freq; } - bss_desc_ptr->channelIdSelf = bss_desc_ptr->channelId; - bss_desc_ptr->nwType = lim_get_nw_type(mac, bss_desc_ptr->channelId, - SIR_MAC_MGMT_FRAME, - parsed_frm_ptr); + bss_desc_ptr->nwType = lim_get_nw_type( + mac, + bss_desc_ptr->chan_freq, + SIR_MAC_MGMT_FRAME, + parsed_frm_ptr); bss_desc_ptr->sinr = 0; bss_desc_ptr->beaconInterval = parsed_frm_ptr->beaconInterval; @@ -2204,6 +2294,11 @@ lim_roam_fill_bss_descr(struct mac_context *mac, qdf_mem_copy((uint8_t *) &bss_desc_ptr->bssId, (uint8_t *)roam_synch_ind_ptr->bssid.bytes, sizeof(tSirMacAddr)); + + qdf_mem_copy((uint8_t *)&bss_desc_ptr->seq_ctrl, + (uint8_t *)&mac_hdr->seqControl, + sizeof(tSirMacSeqCtl)); + bss_desc_ptr->received_time = (uint64_t)qdf_mc_timer_get_system_time(); if (parsed_frm_ptr->mdiePresent) { @@ -2212,8 +2307,8 @@ lim_roam_fill_bss_descr(struct mac_context *mac, (uint8_t *)parsed_frm_ptr->mdie, SIR_MDIE_SIZE); } - - pe_debug("chan: %d rssi: %d ie_len %d", bss_desc_ptr->channelId, + pe_debug("chan: %d rssi: %d ie_len %d", + bss_desc_ptr->chan_freq, bss_desc_ptr->rssi, ie_len); if (ie_len) { qdf_mem_copy(&bss_desc_ptr->ieFields, @@ -2266,28 +2361,6 @@ lim_copy_and_free_hlp_data_from_session(struct pe_session *session_ptr, {} #endif -#ifdef WLAN_FEATURE_11W -/** - * lim_get_rmf_enabled - Get if the connection is PMF enabled - * @session: Pointer to PE session - * - * Return: True if the session is PMF enabled - */ -static bool lim_get_rmf_enabled(struct pe_session *session) -{ - if (session->limRmfEnabled) - return true; - - return false; -} -#else -static inline bool -lim_get_rmf_enabled(struct pe_session *session) -{ - return false; -} -#endif - static uint8_t *lim_process_rmf_disconnect_frame(struct mac_context *mac, struct pe_session *session, @@ -2298,6 +2371,7 @@ uint8_t *lim_process_rmf_disconnect_frame(struct mac_context *mac, struct wlan_frame_hdr *mac_hdr; uint8_t mic_len, hdr_len, pdev_id; uint8_t *orig_ptr, *efrm; + int32_t mgmtcipherset; uint32_t mmie_len; QDF_STATUS status; @@ -2348,7 +2422,15 @@ uint8_t *lim_process_rmf_disconnect_frame(struct mac_context *mac, return NULL; } - mmie_len = (session->mgmt_cipher_type == eSIR_ED_AES_128_CMAC ? + mgmtcipherset = wlan_crypto_get_param(session->vdev, + WLAN_CRYPTO_PARAM_MGMT_CIPHER); + if (mgmtcipherset < 0) { + pe_err("Invalid mgmt cipher"); + *extracted_length = 0; + return NULL; + } + + mmie_len = (mgmtcipherset & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC) ? cds_get_mmie_size() : cds_get_gmac_mmie_size()); efrm = orig_ptr + deauth_disassoc_frame_len; @@ -2375,7 +2457,7 @@ pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, uint16_t extracted_frm_len; bool is_pmf_connection; - session = pe_find_session_by_sme_session_id(mac, vdev_id); + session = pe_find_session_by_vdev_id(mac, vdev_id); if (!session) { pe_err("LFR3: Vdev %d doesn't exist", vdev_id); return QDF_STATUS_E_FAILURE; @@ -2400,7 +2482,7 @@ pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, * In that case, get peer will fail and reason code received * from the WMI_ROAM_EVENTID will be sent to upper layers. */ - is_pmf_connection = lim_get_rmf_enabled(session); + is_pmf_connection = lim_get_vdev_rmf_capable(mac, session); if (is_pmf_connection) { extracted_frm = lim_process_rmf_disconnect_frame( mac, session, @@ -2450,6 +2532,35 @@ lim_fill_fils_ft(struct pe_session *src_session, {} #endif +/** + * lim_check_ft_initial_im_association() - To check FT initial mobility(im) + * association + * @roam_synch: A pointer to roam sync ind structure + * @session_entry: pe session + * + * This function is to check ft_initial_im_association. + * + * Return: None + */ +void +lim_check_ft_initial_im_association(struct roam_offload_synch_ind *roam_synch, + struct pe_session *session_entry) +{ + tpSirMacMgmtHdr hdr; + uint8_t *assoc_req_ptr; + + assoc_req_ptr = (uint8_t *) roam_synch + roam_synch->reassoc_req_offset; + hdr = (tpSirMacMgmtHdr) assoc_req_ptr; + + if (hdr->fc.type == SIR_MAC_MGMT_FRAME && + hdr->fc.subType == SIR_MAC_MGMT_ASSOC_REQ && + session_entry->is11Rconnection) { + pe_debug("Frame subtype: %d and connection is %d", + hdr->fc.subType, session_entry->is11Rconnection); + roam_synch->is_ft_im_roam = true; + } +} + QDF_STATUS pe_roam_synch_callback(struct mac_context *mac_ctx, struct roam_offload_synch_ind *roam_sync_ind_ptr, @@ -2461,7 +2572,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, uint8_t session_id; tpDphHashNode curr_sta_ds; uint16_t aid; - tpAddBssParams add_bss_params; + struct bss_params *add_bss_params; QDF_STATUS status = QDF_STATUS_E_FAILURE; uint16_t join_rsp_len; @@ -2469,7 +2580,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, pe_err("LFR3:roam_sync_ind_ptr is NULL"); return status; } - session_ptr = pe_find_session_by_sme_session_id(mac_ctx, + session_ptr = pe_find_session_by_vdev_id(mac_ctx, roam_sync_ind_ptr->roamed_vdev_id); if (!session_ptr) { pe_err("LFR3:Unable to find session"); @@ -2513,8 +2624,9 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, return status; } - pe_debug("LFR3:Received ROAM_OFFLOAD_SYNCH_IND bssid %pM auth: %d vdevId: %d", - roam_sync_ind_ptr->bssid.bytes, roam_sync_ind_ptr->authStatus, + pe_debug("LFR3:Received ROAM_OFFLOAD_SYNCH_IND bssid "QDF_MAC_ADDR_FMT" auth: %d vdevId: %d", + QDF_MAC_ADDR_REF(roam_sync_ind_ptr->bssid.bytes), + roam_sync_ind_ptr->authStatus, roam_sync_ind_ptr->roamed_vdev_id); /* @@ -2556,15 +2668,16 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, ft_session_ptr->csaOffloadEnable = session_ptr->csaOffloadEnable; /* Next routine will update nss and vdev_nss with AP's capabilities */ - lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr); - + lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, + session_ptr, roam_sync_ind_ptr->phy_mode); + pe_set_rmf_caps(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); /* Next routine may update nss based on dot11Mode */ - lim_ft_prepare_add_bss_req(mac_ctx, false, ft_session_ptr, bss_desc); + lim_ft_prepare_add_bss_req(mac_ctx, ft_session_ptr, bss_desc); if (session_ptr->is11Rconnection) lim_fill_fils_ft(session_ptr, ft_session_ptr); roam_sync_ind_ptr->add_bss_params = - (tpAddBssParams) ft_session_ptr->ftPEContext.pAddBssReq; + (struct bss_params *) ft_session_ptr->ftPEContext.pAddBssReq; add_bss_params = ft_session_ptr->ftPEContext.pAddBssReq; lim_delete_tdls_peers(mac_ctx, session_ptr); curr_sta_ds = dph_lookup_hash_entry(mac_ctx, session_ptr->bssId, &aid, @@ -2585,19 +2698,12 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, DPH_STA_HASH_INDEX_PEER, &ft_session_ptr->dph.dphHashTable); if (!curr_sta_ds) { - pe_err("LFR3:failed to add hash entry for %pM", - add_bss_params->staContext.staMac); + pe_err("LFR3:failed to add hash entry for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(add_bss_params->staContext.staMac)); ft_session_ptr->bRoamSynchInProgress = false; return status; } - add_bss_params->bss_idx = roam_sync_ind_ptr->roamed_vdev_id; - ft_session_ptr->bss_idx = (uint8_t)add_bss_params->bss_idx; - - curr_sta_ds->bssId = add_bss_params->bss_idx; - curr_sta_ds->staIndex = add_bss_params->staContext.staIdx; - rrm_cache_mgmt_tx_power(mac_ctx, add_bss_params->txMgmtPower, - ft_session_ptr); mac_ctx->roam.reassocRespLen = roam_sync_ind_ptr->reassocRespLength; mac_ctx->roam.pReassocResp = qdf_mem_malloc(mac_ctx->roam.reassocRespLen); @@ -2621,6 +2727,8 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, lim_process_assoc_rsp_frame(mac_ctx, mac_ctx->roam.pReassocResp, LIM_REASSOC, ft_session_ptr); + lim_check_ft_initial_im_association(roam_sync_ind_ptr, ft_session_ptr); + lim_copy_and_free_hlp_data_from_session(ft_session_ptr, roam_sync_ind_ptr); @@ -2676,7 +2784,6 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, 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; roam_sync_ind_ptr->join_rsp->timingMeasCap = curr_sta_ds->timingMeasCap; roam_sync_ind_ptr->join_rsp->nss = curr_sta_ds->nss; roam_sync_ind_ptr->join_rsp->max_rate_flags = diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.c index fd163cdb5c3d883ece612fe8062e390f7131c675..9dbb4a89fd62e2e97e8a72a8e8803ed5c0ad8e62 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -42,7 +42,6 @@ #include "lim_assoc_utils.h" #include "lim_security_utils.h" #include "lim_ser_des_utils.h" -#include "lim_sta_hash_api.h" #include "lim_admit_control.h" #include "lim_send_messages.h" #include "lim_ibss_peer_mgmt.h" @@ -55,6 +54,7 @@ #include "lim_types.h" #include "wlan_utility.h" #include "wlan_mlme_api.h" +#include "wma.h" #ifdef FEATURE_WLAN_TDLS #define IS_TDLS_PEER(type) ((type) == STA_ENTRY_TDLS_PEER) @@ -301,260 +301,6 @@ uint8_t lim_check_mcs_set(struct mac_context *mac, uint8_t *supportedMCSSet) #define SECURITY_SUITE_TYPE_GCMP 0x8 #define SECURITY_SUITE_TYPE_GCMP_256 0x9 -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * is_non_rsn_cipher()- API to check whether cipher suit is rsn or not - * @cipher_suite: cipher suit - * - * Return: True in case non ht cipher else false - */ -static inline bool is_non_rsn_cipher(uint8_t cipher_suite) -{ - uint8_t cipher_mask; - - cipher_mask = cipher_suite & SECURITY_SUITE_TYPE_MASK; - if ((cipher_mask == SECURITY_SUITE_TYPE_CCMP) || - (cipher_mask == SECURITY_SUITE_TYPE_GCMP) || - (cipher_mask == SECURITY_SUITE_TYPE_GCMP_256)) - return false; - - return true; -} - -/** - * lim_check_rx_rsn_ie_match()- validate received rsn ie with supported cipher - * suites. - * @mac_ctx: pointer to global mac structure - * @rx_rsn_ie: received rsn IE pointer - * @session_entry: pe session entry - * @sta_is_ht: peer station HT capability - * @pmf_connection: set to true if this is pmf connection - * - * This function is called during Association/Reassociation - * frame handling to determine whether received RSN in - * Assoc/Reassoc request frames include supported cipher suites or not. - * - * Return: QDF_STATUS_SUCCESS if ALL supported cipher suites are present in the - * received rsn IE else failure status. - */ - -uint8_t lim_check_rx_rsn_ie_match(struct mac_context *mac_ctx, - tDot11fIERSN * const rx_rsn_ie, - struct pe_session *session_entry, uint8_t sta_is_ht, - bool *pmf_connection) -{ - tDot11fIERSN *rsn_ie; - bool match = false; - uint8_t i, j, only_non_ht_cipher = 1; -#ifdef WLAN_FEATURE_11W - bool we_are_pmf_capable; - bool we_require_pmf; - bool they_are_pmf_capable; - bool they_require_pmf; -#endif - - /* RSN IE should be received from PE */ - rsn_ie = &session_entry->gStartBssRSNIe; - - if (!rx_rsn_ie) { - pe_debug("Rx RSN IE is NULL"); - return eSIR_MAC_UNSPEC_FAILURE_STATUS; - } - - /* We should have only one AKM in assoc/reassoc request */ - if (rx_rsn_ie->akm_suite_cnt != 1) { - pe_debug("Invalid RX akm_suite_cnt %d", - rx_rsn_ie->akm_suite_cnt); - return eSIR_MAC_INVALID_AKMP_STATUS; - } - /* Check if we support the received AKM */ - for (i = 0; i < rsn_ie->akm_suite_cnt; i++) - if (!qdf_mem_cmp(&rx_rsn_ie->akm_suite[0], - &rsn_ie->akm_suite[i], - sizeof(rsn_ie->akm_suite[i]))) { - match = true; - break; - } - if (!match) { - pe_debug("Invalid RX akm_suite"); - return eSIR_MAC_INVALID_AKMP_STATUS; - } - - /* Check groupwise cipher suite */ - for (i = 0; i < sizeof(rx_rsn_ie->gp_cipher_suite); i++) - if (rsn_ie->gp_cipher_suite[i] != - rx_rsn_ie->gp_cipher_suite[i]) { - pe_debug("Invalid groupwise cipher suite"); - return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; - } - - /* - * For each Pairwise cipher suite check whether we support - * received pairwise - */ - match = false; - for (i = 0; i < rx_rsn_ie->pwise_cipher_suite_count; i++) { - for (j = 0; j < rsn_ie->pwise_cipher_suite_count; j++) { - if (!qdf_mem_cmp(&rx_rsn_ie->pwise_cipher_suites[i], - &rsn_ie->pwise_cipher_suites[j], - sizeof(rsn_ie->pwise_cipher_suites[j]))) { - match = true; - break; - } - } - - if (sta_is_ht) -#ifdef ANI_LITTLE_BYTE_ENDIAN - only_non_ht_cipher = is_non_rsn_cipher( - rx_rsn_ie->pwise_cipher_suites[i][3]); -#else - only_non_ht_cipher = is_non_rsn_cipher( - rx_rsn_ie->pwise_cipher_suites[i][0]); -#endif - } - - if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) { - pe_debug("Invalid pairwise cipher suite"); - return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS; - } - /* - * Check RSN capabilities - * Bit 0 of First Byte - PreAuthentication Capability - */ - if (((rx_rsn_ie->RSN_Cap[0] >> 0) & 0x1) == true) { - /* this is supported by AP only */ - pe_debug("Invalid RSN information element capabilities"); - return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS; - } - - *pmf_connection = false; - -#ifdef WLAN_FEATURE_11W - we_are_pmf_capable = session_entry->pLimStartBssReq->pmfCapable; - we_require_pmf = session_entry->pLimStartBssReq->pmfRequired; - they_are_pmf_capable = (rx_rsn_ie->RSN_Cap[0] >> 7) & 0x1; - they_require_pmf = (rx_rsn_ie->RSN_Cap[0] >> 6) & 0x1; - - if ((they_require_pmf && they_are_pmf_capable && !we_are_pmf_capable) || - (we_require_pmf && !they_are_pmf_capable)) { - pe_debug("Association fail, robust management frames policy" - " violation they_require_pmf =%d" - " theyArePMFCapable %d weArePMFCapable %d" - " weRequirePMF %d theyArePMFCapable %d", - they_require_pmf, they_are_pmf_capable, - we_are_pmf_capable, we_require_pmf, - they_are_pmf_capable); - return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION; - } - - if (they_are_pmf_capable && we_are_pmf_capable) - *pmf_connection = true; - - pe_debug("weAreCapable %d, weRequire %d, theyAreCapable %d," - " theyRequire %d, PMFconnection %d", - we_are_pmf_capable, we_require_pmf, they_are_pmf_capable, - they_require_pmf, *pmf_connection); -#endif - - return eSIR_MAC_SUCCESS_STATUS; -} - -/** - * lim_check_rx_wpa_ie_match() - to check supported cipher suites - * - * @mac: pointer to global mac structure - * @rx_wpaie: Received WPA IE in (Re)Assco req - * @session_entry: pointer to PE session - * @sta_is_ht: peer station is HT - * - * This function is called during Association/Reassociation - * frame handling to determine whether received RSN in - * Assoc/Reassoc request frames include supported cipher suites or not. - * - * Return: Success if ALL supported cipher suites are present in the - * received wpa IE else failure status. - */ - -uint8_t -lim_check_rx_wpa_ie_match(struct mac_context *mac, tDot11fIEWPA *rx_wpaie, - struct pe_session *session_entry, uint8_t sta_is_ht) -{ - tDot11fIEWPA *wpa_ie; - bool match = false; - uint8_t i, j, only_non_ht_cipher = 1; - - /* WPA IE should be received from PE */ - wpa_ie = &session_entry->gStartBssWPAIe; - - /* We should have only one AKM in assoc/reassoc request */ - if (rx_wpaie->auth_suite_count != 1) { - pe_debug("Invalid RX auth_suite_count %d", - rx_wpaie->auth_suite_count); - return eSIR_MAC_INVALID_AKMP_STATUS; - } - /* Check if we support the received AKM */ - for (i = 0; i < wpa_ie->auth_suite_count; i++) - if (!qdf_mem_cmp(&rx_wpaie->auth_suites[0], - &wpa_ie->auth_suites[i], - sizeof(wpa_ie->auth_suites[i]))) { - match = true; - break; - } - if (!match) { - pe_debug("Invalid RX auth_suites"); - return eSIR_MAC_INVALID_AKMP_STATUS; - } - - /* Check groupwise cipher suite */ - for (i = 0; i < 4; i++) { - if (wpa_ie->multicast_cipher[i] != - rx_wpaie->multicast_cipher[i]) { - pe_debug("Invalid groupwise cipher suite"); - return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; - } - } - - /* - * For each Pairwise cipher suite check whether we support - * received pairwise - */ - match = false; - for (i = 0; i < rx_wpaie->unicast_cipher_count; i++) { - for (j = 0; j < wpa_ie->unicast_cipher_count; j++) { - if (!qdf_mem_cmp(rx_wpaie->unicast_ciphers[i], - wpa_ie->unicast_ciphers[j], 4)) { - match = true; - break; - } - } - - if ((sta_is_ht) -#ifdef ANI_LITTLE_BYTE_ENDIAN - && - ((rx_wpaie-> - unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) == - SECURITY_SUITE_TYPE_CCMP)) -#else - && - ((rx_wpaie-> - unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) == - SECURITY_SUITE_TYPE_CCMP)) -#endif - { - only_non_ht_cipher = 0; - } - - } - - if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) { - pe_debug("Invalid pairwise cipher suite"); - return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS; - } - - return eSIR_MAC_SUCCESS_STATUS; -} -#endif - /** * lim_cleanup_rx_path() * @@ -602,7 +348,7 @@ lim_cleanup_rx_path(struct mac_context *mac, tpDphHashNode sta, MTRACE(mac_trace (mac, TRACE_CODE_TIMER_DEACTIVATE, pe_session->peSessionId, eLIM_ADDTS_RSP_TIMER)); - tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer); + tx_timer_deactivate(&mac->lim.lim_timers.gLimAddtsRspTimer); pe_debug("Reset gLimAddtsSent flag and send addts timeout to SME"); lim_process_sme_addts_rsp_timeout(mac, mac->lim.gLimAddtsRspTimerCount); @@ -659,7 +405,7 @@ lim_cleanup_rx_path(struct mac_context *mac, tpDphHashNode sta, if (!pe_session->add_bss_failed) { if (pe_session->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) { retCode = - lim_del_bss(mac, sta, pe_session->bss_idx, + lim_del_bss(mac, sta, pe_session->vdev_id, pe_session); } else retCode = lim_del_sta(mac, @@ -693,10 +439,10 @@ lim_send_del_sta_cnf(struct mac_context *mac, struct qdf_mac_addr sta_dsaddr, tLimMlmDeauthCnf mlmDeauthCnf; tLimMlmPurgeStaInd mlmPurgeStaInd; - pe_debug("Sessionid: %d staDsAssocId: %d Trigger: %d status_code: %d sta_dsaddr: "QDF_MAC_ADDR_STR, + pe_debug("Sessionid: %d staDsAssocId: %d Trigger: %d status_code: %d sta_dsaddr: "QDF_MAC_ADDR_FMT, pe_session->peSessionId, staDsAssocId, mlmStaContext.cleanupTrigger, status_code, - QDF_MAC_ADDR_ARRAY(sta_dsaddr.bytes)); + QDF_MAC_ADDR_REF(sta_dsaddr.bytes)); if (LIM_IS_STA_ROLE(pe_session)) { /* Set BSSID at CFG to null */ @@ -868,10 +614,10 @@ lim_reject_association(struct mac_context *mac_ctx, tSirMacAddr peer_addr, { tpDphHashNode sta_ds; - pe_debug("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " QDF_MAC_ADDR_STR, + pe_debug("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " QDF_MAC_ADDR_FMT, session_entry->peSessionId, auth_type, sub_type, add_pre_auth_context, sta_id, delete_sta, result_code, - QDF_MAC_ADDR_ARRAY(peer_addr)); + QDF_MAC_ADDR_REF(peer_addr)); if (add_pre_auth_context) { /* Create entry for this STA in pre-auth list */ @@ -967,8 +713,9 @@ lim_decide_ap_protection_on_ht20_delete(struct mac_context *mac_ctx, { uint32_t i = 0; - pe_debug("(%d) A HT 20 STA is disassociated. Addr is %pM", - session_entry->gLimHt20Params.numSta, sta_ds->staAddr); + pe_debug("(%d) A HT 20 STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLimHt20Params.numSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); if (session_entry->gLimHt20Params.numSta > 0) { for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { @@ -1014,7 +761,7 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, { uint32_t phy_mode; tHalBitVal erp_enabled = eHAL_CLEAR; - enum band_info rf_band = BAND_UNKNOWN; + enum reg_wifi_band rf_band = REG_BAND_UNKNOWN; uint32_t i; if (!sta_ds) @@ -1024,7 +771,7 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, lim_get_phy_mode(mac_ctx, &phy_mode, session_entry); erp_enabled = sta_ds->erpEnabled; - if ((BAND_5G == rf_band) && + if ((REG_BAND_5G == rf_band) && (true == session_entry->htCapability) && (session_entry->beaconParams.llaCoexist) && (false == sta_ds->mlmStaContext.htCapability)) { @@ -1035,8 +782,9 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, * HT station leaving ==> this case is commonly handled * between both the bands below. */ - pe_debug("(%d) A 11A STA is disassociated. Addr is %pM", - session_entry->gLim11aParams.numSta, sta_ds->staAddr); + pe_debug("(%d) A 11A STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLim11aParams.numSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->protStaCache[i].active && (!qdf_mem_cmp( @@ -1056,12 +804,13 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, } /* we are HT or 11G and 11B station is getting deleted */ - if ((BAND_2G == rf_band) && + if ((REG_BAND_2G == rf_band) && (phy_mode == WNI_CFG_PHY_MODE_11G || session_entry->htCapability) && (erp_enabled == eHAL_CLEAR)) { - pe_debug("(%d) A legacy STA is disassociated. Addr is %pM", - session_entry->gLim11bParams.numSta, sta_ds->staAddr); + pe_debug("(%d) A legacy STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLim11bParams.numSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->protStaCache[i].active && (!qdf_mem_cmp( @@ -1086,11 +835,12 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, * we are HT AP and non-11B station is leaving. * 11g station is leaving */ - if ((BAND_2G == rf_band) && + if ((REG_BAND_2G == rf_band) && session_entry->htCapability && !sta_ds->mlmStaContext.htCapability) { - pe_debug("(%d) A 11g STA is disassociated. Addr is %pM", - session_entry->gLim11bParams.numSta, sta_ds->staAddr); + pe_debug("(%d) A 11g STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLim11bParams.numSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->protStaCache[i].active && (!qdf_mem_cmp( @@ -1120,8 +870,9 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, * HT non-GF leaving */ if (!sta_ds->htGreenfield) { - pe_debug("(%d) A non-GF STA is disassociated. Addr is %pM", - session_entry->gLimNonGfParams.numSta, sta_ds->staAddr); + pe_debug("(%d) A non-GF STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLimNonGfParams.numSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->protStaCache[i].active && (!qdf_mem_cmp( @@ -1158,9 +909,9 @@ lim_decide_ap_protection_on_delete(struct mac_context *mac_ctx, if ((false == session_entry->beaconParams. fLsigTXOPProtectionFullSupport) && (false == sta_ds->htLsigTXOPProtection)) { - pe_debug("(%d) A HT LSIG not supporting STA is disassociated. Addr is %pM", + pe_debug("(%d) A HT LSIG not supporting STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, session_entry->gLimLsigTxopParams.numSta, - sta_ds->staAddr); + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->protStaCache[i].active && (!qdf_mem_cmp( @@ -1200,9 +951,9 @@ static void lim_decide_short_preamble(struct mac_context *mac_ctx, uint32_t i; if (sta_ds->shortPreambleEnabled == eHAL_CLEAR) { - pe_debug("(%d) A non-short preamble STA is disassociated. Addr is %pM", - session_entry->gLimNoShortParams.numNonShortPreambleSta, - sta_ds->staAddr); + pe_debug("(%d) A non-short preamble STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, + session_entry->gLimNoShortParams.numNonShortPreambleSta, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) { if (session_entry->gLimNoShortParams. staNoShortCache[i].active && @@ -1255,9 +1006,9 @@ lim_decide_short_slot(struct mac_context *mac_ctx, tpDphHashNode sta_ds, if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR) return; - pe_debug("(%d) A non-short slottime STA is disassociated. Addr is %pM", + pe_debug("(%d) A non-short slottime STA is disassociated. Addr is "QDF_MAC_ADDR_FMT, mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta, - sta_ds->staAddr); + QDF_MAC_ADDR_REF(sta_ds->staAddr)); val = mac_ctx->mlme_cfg->feature_flags.enable_short_slot_time_11g; @@ -1333,11 +1084,124 @@ lim_decide_short_slot(struct mac_context *mac_ctx, tpDphHashNode sta_ds, } } +static uint8_t lim_get_nss_from_vht_mcs_map(uint16_t mcs_map) +{ + uint8_t nss = 0; + uint16_t mcs_mask = 0x3; + + for (nss = 0; nss < VHT_MAX_NSS; nss++) { + if ((mcs_map & mcs_mask) == mcs_mask) + return nss; + + mcs_mask = (mcs_mask << 2); + } + + return nss; +} + +static void lim_get_vht_gt80_nss(struct mac_context *mac_ctx, + struct sDphHashNode *sta_ds, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *session) +{ + uint8_t nss; + + if (!vht_caps->vht_extended_nss_bw_cap) { + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + pe_debug("peer does not support vht extnd nss bw"); + + return; + } + + nss = lim_get_nss_from_vht_mcs_map(vht_caps->rxMCSMap); + + if (!nss) { + pe_debug("Invalid peer VHT MCS map %0X", vht_caps->rxMCSMap); + nss = 1; + } + + switch (vht_caps->supportedChannelWidthSet) { + case VHT_CAP_NO_160M_SUPP: + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_160) { + sta_ds->vht_160mhz_nss = nss / 2; + sta_ds->vht_80p80mhz_nss = 0; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_80P80) { + sta_ds->vht_160mhz_nss = nss / 2; + sta_ds->vht_80p80mhz_nss = nss / 2; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_3QUART_NSS_80P80) { + sta_ds->vht_160mhz_nss = (nss * 3) / 4; + sta_ds->vht_80p80mhz_nss = (nss * 3) / 4; + } else { + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + } + break; + case VHT_CAP_160_SUPP: + sta_ds->vht_160mhz_nss = nss; + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_160_HALF_NSS_80P80) { + sta_ds->vht_80p80mhz_nss = nss / 2; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_160_3QUART_NSS_80P80) { + sta_ds->vht_80p80mhz_nss = (nss * 3) / 4; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_2X_NSS_160_1X_NSS_80P80) { + if (nss > (VHT_MAX_NSS / 2)) { + pe_debug("Invalid extnd nss bw support val"); + sta_ds->vht_80p80mhz_nss = nss / 2; + break; + } + sta_ds->vht_160mhz_nss = nss * 2; + if (session->nss == MAX_VDEV_NSS) + break; + if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) + break; + session->nss *= 2; + } else { + sta_ds->vht_80p80mhz_nss = 0; + } + break; + case VHT_CAP_160_AND_80P80_SUPP: + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_2X_NSS_80_1X_NSS_80P80) { + if (nss > (VHT_MAX_NSS / 2)) { + pe_debug("Invalid extnd nss bw support val"); + break; + } + if (session->nss == MAX_VDEV_NSS) + break; + if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) + break; + session->nss *= 2; + } else { + sta_ds->vht_160mhz_nss = nss; + sta_ds->vht_80p80mhz_nss = nss; + } + break; + default: + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + } + pe_debug("AP Nss config: 160MHz: %d, 80P80MHz %d", + sta_ds->vht_160mhz_nss, sta_ds->vht_80p80mhz_nss); + sta_ds->vht_160mhz_nss = QDF_MIN(sta_ds->vht_160mhz_nss, session->nss); + sta_ds->vht_80p80mhz_nss = QDF_MIN(sta_ds->vht_80p80mhz_nss, + session->nss); + pe_debug("Session Nss config: 160MHz: %d, 80P80MHz %d, session Nss %d", + sta_ds->vht_160mhz_nss, sta_ds->vht_80p80mhz_nss, + session->nss); +} + QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, struct supported_rates *rates, tDot11fIEVHTCaps *peer_vht_caps, struct pe_session *session_entry, - uint8_t nss) + uint8_t nss, + struct sDphHashNode *sta_ds) { uint32_t self_sta_dot11mode = 0; uint16_t mcs_map_mask = MCSMAPMASK1x1; @@ -1349,6 +1213,9 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, if (!IS_DOT11_MODE_VHT(self_sta_dot11mode)) return QDF_STATUS_SUCCESS; + if (!peer_vht_caps || !peer_vht_caps->present) + return QDF_STATUS_SUCCESS; + vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; rates->vhtRxMCSMap = (uint16_t)vht_cap_info->rx_mcs_map; @@ -1386,9 +1253,6 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, } } - if ((!peer_vht_caps) || (!peer_vht_caps->present)) - return QDF_STATUS_SUCCESS; - rates->vhtTxHighestDataRate = QDF_MIN(rates->vhtTxHighestDataRate, peer_vht_caps->txSupDataRate); @@ -1402,24 +1266,19 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, if ((peer_vht_caps->txMCSMap & mcs_map_mask) < (rates->vhtRxMCSMap & mcs_map_mask)) { rates->vhtRxMCSMap &= ~(mcs_map_mask); - rates->vhtRxMCSMap |= - (peer_vht_caps->txMCSMap & mcs_map_mask); + rates->vhtRxMCSMap |= (peer_vht_caps->txMCSMap & mcs_map_mask); } if ((peer_vht_caps->rxMCSMap & mcs_map_mask) < (rates->vhtTxMCSMap & mcs_map_mask)) { rates->vhtTxMCSMap &= ~(mcs_map_mask); - rates->vhtTxMCSMap |= - (peer_vht_caps->rxMCSMap & mcs_map_mask); + rates->vhtTxMCSMap |= (peer_vht_caps->rxMCSMap & mcs_map_mask); } if (mcs_map_mask2x2) { - uint16_t peer_mcs_map, self_mcs_map; - peer_mcs_map = - peer_vht_caps->txMCSMap & mcs_map_mask2x2; - self_mcs_map = - rates->vhtRxMCSMap & mcs_map_mask2x2; + peer_mcs_map = peer_vht_caps->txMCSMap & mcs_map_mask2x2; + self_mcs_map = rates->vhtRxMCSMap & mcs_map_mask2x2; if ((self_mcs_map != mcs_map_mask2x2) && ((peer_mcs_map == mcs_map_mask2x2) || @@ -1428,10 +1287,8 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, rates->vhtRxMCSMap |= peer_mcs_map; } - peer_mcs_map = - (peer_vht_caps->rxMCSMap & mcs_map_mask2x2); - self_mcs_map = - (rates->vhtTxMCSMap & mcs_map_mask2x2); + peer_mcs_map = (peer_vht_caps->rxMCSMap & mcs_map_mask2x2); + self_mcs_map = (rates->vhtTxMCSMap & mcs_map_mask2x2); if ((self_mcs_map != mcs_map_mask2x2) && ((peer_mcs_map == mcs_map_mask2x2) || @@ -1441,13 +1298,22 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, } } - pe_debug("RxMCSMap %x TxMCSMap %x", - rates->vhtRxMCSMap, rates->vhtTxMCSMap); + pe_debug("RxMCSMap %x TxMCSMap %x", rates->vhtRxMCSMap, + rates->vhtTxMCSMap); + + if (!session_entry) + return QDF_STATUS_SUCCESS; + + session_entry->supported_nss_1x1 = + ((rates->vhtTxMCSMap & VHT_MCS_1x1) == VHT_MCS_1x1) ? + true : false; + + if (!sta_ds || CH_WIDTH_80MHZ >= session_entry->ch_width) + return QDF_STATUS_SUCCESS; - if (session_entry) - session_entry->supported_nss_1x1 = - ((rates->vhtTxMCSMap & VHT_MCS_1x1) == - VHT_MCS_1x1) ? true : false; + sta_ds->vht_extended_nss_bw_cap = + peer_vht_caps->vht_extended_nss_bw_cap; + lim_get_vht_gt80_nss(mac_ctx, sta_ds, peer_vht_caps, session_entry); return QDF_STATUS_SUCCESS; } @@ -1611,8 +1477,8 @@ QDF_STATUS lim_populate_own_rate_set(struct mac_context *mac_ctx, lim_dump_ht_mcs_mask(rates->supportedMCSSet, NULL); } - lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, - session_entry, session_entry->nss); + lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, session_entry, + session_entry->nss, NULL); lim_populate_he_mcs_set(mac_ctx, rates, he_caps, session_entry, session_entry->nss); @@ -1713,7 +1579,9 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, uint8_t basicOnly, struct pe_session *pe_session, tDot11fIEVHTCaps *pVHTCaps, - tDot11fIEhe_cap *he_caps) + tDot11fIEhe_cap *he_caps, + struct sDphHashNode *sta_ds, + struct bss_description *bss_desc) { tSirMacRateSet tempRateSet; tSirMacRateSet tempRateSet2; @@ -1722,7 +1590,6 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, uint8_t aRateIndex = 0; uint8_t bRateIndex = 0; tDot11fIEhe_cap *peer_he_caps; - struct bss_description *bssDescription; tSchBeaconStruct *pBeaconStruct = NULL; /* copy operational rate set from pe_session */ @@ -1773,6 +1640,7 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, * Sort rates in tempRateSet (they are likely to be already sorted) * put the result in pSupportedRates */ + qdf_mem_zero(pRates, sizeof(*pRates)); for (i = 0; i < tempRateSet.numRates; i++) { min = 0; @@ -1823,7 +1691,8 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, tempRateSet.rate[min] = 0xff; } - if (IS_DOT11_MODE_HT(pe_session->dot11mode)) { + if (IS_DOT11_MODE_HT(pe_session->dot11mode) && + !lim_is_he_6ghz_band(pe_session)) { val_len = SIZE_OF_SUPPORTED_MCS_SET; if (wlan_mlme_get_cfg_str( pRates->supportedMCSSet, @@ -1854,24 +1723,23 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, pe_session->supported_nss_1x1 = ((pRates->supportedMCSSet[1] != 0) ? false : true); } - lim_populate_vht_mcs_set(mac, pRates, pVHTCaps, - pe_session, pe_session->nss); + lim_populate_vht_mcs_set(mac, pRates, pVHTCaps, pe_session, + pe_session->nss, sta_ds); if (lim_check_valid_mcs_for_nss(pe_session, he_caps)) { peer_he_caps = he_caps; } else { - bssDescription = &pe_session->lim_join_req->bssDescription; - if (!bssDescription) { + if (!bss_desc) { pe_err("bssDescription is NULL"); return QDF_STATUS_E_INVAL; } pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct)); if (!pBeaconStruct) return QDF_STATUS_E_NOMEM; - lim_extract_ap_capabilities(mac, - (uint8_t *)bssDescription->ieFields, - lim_get_ielen_from_bss_description( - bssDescription), + + lim_extract_ap_capabilities( + mac, (uint8_t *)bss_desc->ieFields, + lim_get_ielen_from_bss_description(bss_desc), pBeaconStruct); peer_he_caps = &pBeaconStruct->he_cap; } @@ -2117,7 +1985,7 @@ QDF_STATUS lim_populate_matching_rate_set(struct mac_context *mac_ctx, sta_ds->supportedRates.supportedMCSSet); } lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps, - session_entry, session_entry->nss); + session_entry, session_entry->nss, sta_ds); lim_populate_he_mcs_set(mac_ctx, &sta_ds->supportedRates, he_caps, session_entry, session_entry->nss); /* @@ -2179,8 +2047,8 @@ static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps) SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | (input_caps.txAntPattern << SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (input_caps.reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + (input_caps.extended_nss_bw_supp << + SIR_MAC_VHT_CAP_EXTD_NSS_BW)); return vht_caps; } @@ -2259,8 +2127,8 @@ lim_add_sta(struct mac_context *mac_ctx, else sta_Addr = &sta_mac; - pe_debug(QDF_MAC_ADDR_STR ": Subtype(Assoc/Reassoc): %d", - QDF_MAC_ADDR_ARRAY(*sta_Addr), sta_ds->mlmStaContext.subType); + pe_debug(QDF_MAC_ADDR_FMT ": Subtype(Assoc/Reassoc): %d", + QDF_MAC_ADDR_REF(*sta_Addr), sta_ds->mlmStaContext.subType); qdf_mem_copy((uint8_t *) add_sta_params->staMac, (uint8_t *) *sta_Addr, sizeof(tSirMacAddr)); @@ -2279,7 +2147,6 @@ lim_add_sta(struct mac_context *mac_ctx, add_sta_params->wmmEnabled = sta_ds->qosMode; add_sta_params->listenInterval = sta_ds->mlmStaContext.listenInterval; - add_sta_params->shortPreambleSupported = sta_ds->shortPreambleEnabled; if (LIM_IS_AP_ROLE(session_entry) && (sta_ds->mlmStaContext.subType == LIM_REASSOC)) { /* @@ -2291,41 +2158,24 @@ lim_add_sta(struct mac_context *mac_ctx, sta_ds->valid = 0; sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; - pe_debug("Assoc ID: %d wmmEnabled: %d listenInterval: %d" - " shortPreambleSupported: %d", add_sta_params->assocId, - add_sta_params->wmmEnabled, add_sta_params->listenInterval, - add_sta_params->shortPreambleSupported); - /* This will indicate HAL to "allocate" a new STA index */ -#ifdef FEATURE_WLAN_TDLS - /* - * As there is corner case in-between add_sta and change_sta,if del_sta - * for other staIdx happened, firmware return wrong staIdx - * (recently removed staIdx). Until we get a confirmation from the - * firmware team it is now return correct staIdx for same sta_mac_addr - * for update case, we want to get around it by passing valid staIdx - * given by add_sta time. - */ - if ((STA_ENTRY_TDLS_PEER == sta_ds->staType) && (true == update_entry)) - add_sta_params->staIdx = sta_ds->staIndex; - else -#endif - add_sta_params->staIdx = STA_INVALID_IDX; + pe_debug("Assoc ID: %d wmmEnabled: %d listenInterval: %d", + add_sta_params->assocId, add_sta_params->wmmEnabled, + add_sta_params->listenInterval); add_sta_params->staType = sta_ds->staType; add_sta_params->updateSta = update_entry; add_sta_params->status = QDF_STATUS_SUCCESS; - add_sta_params->respReqd = 1; /* Update VHT/HT Capability */ if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry)) { add_sta_params->htCapable = - sta_ds->mlmStaContext.htCapability && - session_entry->htCapability; + sta_ds->mlmStaContext.htCapability && + session_entry->htCapability;; add_sta_params->vhtCapable = - sta_ds->mlmStaContext.vhtCapability && - session_entry->vhtCapability; + sta_ds->mlmStaContext.vhtCapability && + session_entry->vhtCapability; } #ifdef FEATURE_WLAN_TDLS /* SystemRole shouldn't be matter if staType is TDLS peer */ @@ -2340,9 +2190,10 @@ lim_add_sta(struct mac_context *mac_ctx, add_sta_params->vhtCapable = session_entry->vhtCapability; } - pe_debug("StaIdx: %d updateSta: %d htcapable: %d vhtCapable: %d", - add_sta_params->staIdx, add_sta_params->updateSta, - add_sta_params->htCapable, add_sta_params->vhtCapable); + pe_debug("updateSta: %d htcapable: %d vhtCapable: %d sta mac" + QDF_MAC_ADDR_FMT, add_sta_params->updateSta, + add_sta_params->htCapable, add_sta_params->vhtCapable, + QDF_MAC_ADDR_REF(add_sta_params->staMac)); /* * If HT client is connected to SAP DUT and self cap is NSS = 2 then @@ -2366,29 +2217,21 @@ lim_add_sta(struct mac_context *mac_ctx, lim_update_sta_he_capable(mac_ctx, add_sta_params, sta_ds, session_entry); - add_sta_params->greenFieldCapable = sta_ds->htGreenfield; add_sta_params->maxAmpduDensity = sta_ds->htAMpduDensity; add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor; - add_sta_params->fDsssCckMode40Mhz = sta_ds->htDsssCckRate40MHzSupport; add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz; add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz; - add_sta_params->lsigTxopProtection = sta_ds->htLsigTXOPProtection; - add_sta_params->maxAmsduSize = sta_ds->htMaxAmsduLength; - add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet; + add_sta_params->ch_width = sta_ds->ch_width; add_sta_params->mimoPS = sta_ds->htMIMOPSState; - pe_debug("greenFieldCapable: %d maxAmpduDensity: %d maxAmpduDensity: %d", - add_sta_params->greenFieldCapable, - add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize); + pe_debug("maxAmpduDensity: %d maxAmpduDensity: %d", + add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize); - pe_debug("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d fShortGI40Mhz: %d", - add_sta_params->fDsssCckMode40Mhz, + pe_debug("fShortGI20Mhz: %d fShortGI40Mhz: %d", add_sta_params->fShortGI20Mhz, add_sta_params->fShortGI40Mhz); - pe_debug("lsigTxopProtection: %d maxAmsduSize: %d txChannelWidth: %d mimoPS: %d", - add_sta_params->lsigTxopProtection, - add_sta_params->maxAmsduSize, add_sta_params->ch_width, - add_sta_params->mimoPS); + pe_debug("txChannelWidth: %d mimoPS: %d", add_sta_params->ch_width, + add_sta_params->mimoPS); if (add_sta_params->vhtCapable) { if (sta_ds->vhtSupportedChannelWidthSet) @@ -2495,7 +2338,8 @@ lim_add_sta(struct mac_context *mac_ctx, lim_populate_vht_caps(vht_caps); } - lim_add_he_cap(add_sta_params, assoc_req); + lim_add_he_cap(mac_ctx, session_entry, + add_sta_params, assoc_req); } else if (LIM_IS_IBSS_ROLE(session_entry)) { @@ -2608,8 +2452,7 @@ lim_add_sta(struct mac_context *mac_ctx, * we need to defer the message until we get the * response back from HAL. */ - if (add_sta_params->respReqd) - SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false); + SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false); add_sta_params->nwType = session_entry->nwType; @@ -2673,8 +2516,7 @@ lim_add_sta(struct mac_context *mac_ctx, ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q); if (QDF_STATUS_SUCCESS != ret_code) { - if (add_sta_params->respReqd) - SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); + SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); pe_err("ADD_STA_REQ for aId %d failed (reason %X)", sta_ds->assocId, ret_code); qdf_mem_free(add_sta_params); @@ -2738,26 +2580,6 @@ lim_del_sta(struct mac_context *mac, 0, VDEV_CMD); } } - /* */ - /* DPH contains the STA index only for "peer" STA entries. */ - /* LIM global contains "self" STA index */ - /* Thus, */ - /* if( STA role ) */ - /* get STA index from LIM global */ - /* else */ - /* get STA index from DPH */ - /* */ - -#ifdef FEATURE_WLAN_TDLS - if (LIM_IS_STA_ROLE(pe_session) && - (sta->staType != STA_ENTRY_TDLS_PEER)) -#else - if (LIM_IS_STA_ROLE(pe_session)) -#endif - pDelStaParams->staIdx = pe_session->staId; - - else - pDelStaParams->staIdx = sta->staIndex; pDelStaParams->assocId = sta->assocId; sta->valid = 0; @@ -2811,10 +2633,11 @@ lim_del_sta(struct mac_context *mac, msgQ.bodyval = 0; pe_debug("Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ " - "for STAID: %X and AssocID: %d MAC : " - QDF_MAC_ADDR_STR, pDelStaParams->sessionId, - pDelStaParams->staIdx, pDelStaParams->assocId, - QDF_MAC_ADDR_ARRAY(sta->staAddr)); + "for mac_addr "QDF_MAC_ADDR_FMT" and AssocID: %d MAC : " + QDF_MAC_ADDR_FMT, pDelStaParams->sessionId, + QDF_MAC_ADDR_REF(pDelStaParams->staMac), + pDelStaParams->assocId, + QDF_MAC_ADDR_REF(sta->staAddr)); MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); retCode = wma_post_ctrl_msg(mac, &msgQ); @@ -2865,7 +2688,7 @@ static void lim_set_mbssid_info(struct pe_session *pe_session) */ QDF_STATUS -lim_add_sta_self(struct mac_context *mac, uint16_t staIdx, uint8_t updateSta, +lim_add_sta_self(struct mac_context *mac, uint8_t updateSta, struct pe_session *pe_session) { tpAddStaParams pAddStaParams = NULL; @@ -2899,7 +2722,6 @@ lim_add_sta_self(struct mac_context *mac, uint16_t staIdx, uint8_t updateSta, pAddStaParams->assocId = pe_session->limAID; pAddStaParams->staType = STA_ENTRY_SELF; pAddStaParams->status = QDF_STATUS_SUCCESS; - pAddStaParams->respReqd = 1; /* Update PE session ID */ pAddStaParams->sessionId = pe_session->peSessionId; @@ -2909,52 +2731,27 @@ lim_add_sta_self(struct mac_context *mac, uint16_t staIdx, uint8_t updateSta, pAddStaParams->maxTxPower = pe_session->maxTxPower; - /* This will indicate HAL to "allocate" a new STA index */ - pAddStaParams->staIdx = staIdx; pAddStaParams->updateSta = updateSta; - qdf_mem_copy(&pAddStaParams->mbssid_info, - &pe_session->lim_join_req->bssDescription.mbssid_info, - sizeof(struct scan_mbssid_info)); lim_set_mbssid_info(pe_session); - pAddStaParams->shortPreambleSupported = - mac->mlme_cfg->ht_caps.short_preamble; - lim_populate_own_rate_set(mac, &pAddStaParams->supportedRates, NULL, false, pe_session, NULL, NULL); if (IS_DOT11_MODE_HT(selfStaDot11Mode)) { pAddStaParams->htCapable = true; - pAddStaParams->greenFieldCapable = - lim_get_ht_capability(mac, eHT_GREENFIELD, - pe_session); + pAddStaParams->ch_width = mac->roam.configParam.channelBondingMode5GHz; pAddStaParams->mimoPS = lim_get_ht_capability(mac, eHT_MIMO_POWER_SAVE, pe_session); - pAddStaParams->rifsMode = - lim_get_ht_capability(mac, eHT_RIFS_MODE, - pe_session); - pAddStaParams->lsigTxopProtection = - lim_get_ht_capability(mac, eHT_LSIG_TXOP_PROTECTION, - pe_session); pAddStaParams->maxAmpduDensity = lim_get_ht_capability(mac, eHT_MPDU_DENSITY, pe_session); pAddStaParams->maxAmpduSize = lim_get_ht_capability(mac, eHT_MAX_RX_AMPDU_FACTOR, pe_session); - pAddStaParams->maxAmsduSize = - lim_get_ht_capability(mac, eHT_MAX_AMSDU_LENGTH, - pe_session); - pAddStaParams->max_amsdu_num = - lim_get_ht_capability(mac, eHT_MAX_AMSDU_NUM, - pe_session); - pAddStaParams->fDsssCckMode40Mhz = - lim_get_ht_capability(mac, eHT_DSSS_CCK_MODE_40MHZ, - pe_session); pAddStaParams->fShortGI20Mhz = pe_session->ht_config.ht_sgi20; pAddStaParams->fShortGI40Mhz = pe_session->ht_config.ht_sgi40; } @@ -3011,8 +2808,8 @@ lim_add_sta_self(struct mac_context *mac, uint16_t staIdx, uint8_t updateSta, msgQ.bodyptr = pAddStaParams; msgQ.bodyval = 0; - pe_debug(QDF_MAC_ADDR_STR ": vdev %d Sending WMA_ADD_STA_REQ. LI %d", - QDF_MAC_ADDR_ARRAY(pAddStaParams->staMac), + pe_debug(QDF_MAC_ADDR_FMT ": vdev %d Sending WMA_ADD_STA_REQ.LI %d", + QDF_MAC_ADDR_REF(pAddStaParams->staMac), pe_session->vdev_id, pAddStaParams->listenInterval); MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); @@ -3049,7 +2846,7 @@ void lim_handle_cnf_wait_timeout(struct mac_context *mac, uint16_t staId) struct pe_session *pe_session = NULL; pe_session = pe_find_session_by_session_id(mac, - mac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId); + mac->lim.lim_timers.gpLimCnfWaitTimer[staId].sessionId); if (!pe_session) { pe_err("Session Does not exist for given sessionID"); return; @@ -3114,7 +2911,7 @@ lim_delete_dph_hash_entry(struct mac_context *mac_ctx, tSirMacAddr sta_addr, return; } - beacon_params.bss_idx = session_entry->bss_idx; + beacon_params.bss_idx = session_entry->vdev_id; sta_ds = dph_lookup_hash_entry(mac_ctx, sta_addr, &aid, &session_entry->dph.dphHashTable); @@ -3123,7 +2920,8 @@ lim_delete_dph_hash_entry(struct mac_context *mac_ctx, tSirMacAddr sta_addr, return; } - pe_debug("Deleting DPH Hash entry for STAID: %X", sta_id); + pe_debug("Deleting DPH Hash entry sta mac " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sta_addr)); /* * update the station count and perform associated actions * do this before deleting the dph hash entry @@ -3172,8 +2970,9 @@ lim_delete_dph_hash_entry(struct mac_context *mac_ctx, tSirMacAddr sta_addr, #ifdef WLAN_FEATURE_11W if (sta_ds->rmfEnabled) { - pe_debug("delete pmf timer sta-idx:%d assoc-id:%d", - sta_ds->staIndex, sta_ds->assocId); + pe_debug("delete pmf timer assoc-id:%d sta mac " + QDF_MAC_ADDR_FMT, sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); tx_timer_delete(&sta_ds->pmfSaQueryTimer); } #endif @@ -3182,6 +2981,7 @@ lim_delete_dph_hash_entry(struct mac_context *mac_ctx, tSirMacAddr sta_addr, if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id, &session_entry->dph.dphHashTable) != QDF_STATUS_SUCCESS) pe_err("error deleting hash entry"); + lim_ap_check_6g_compatible_peer(mac_ctx, session_entry); } /** @@ -3244,8 +3044,9 @@ lim_check_and_announce_join_success(struct mac_context *mac_ctx, if (!LIM_IS_STA_ROLE(session_entry)) return; - pe_debug("Received Beacon/PR with BSSID:%pM pe session %d vdev %d", - session_entry->bssId, session_entry->peSessionId, + pe_debug("Received Beacon/PR with BSSID:"QDF_MAC_ADDR_FMT" pe session %d vdev %d", + QDF_MAC_ADDR_REF(session_entry->bssId), + session_entry->peSessionId, session_entry->vdev_id); /* Deactivate Join Failure timer */ @@ -3301,9 +3102,9 @@ lim_check_and_announce_join_success(struct mac_context *mac_ctx, */ if (!session_entry->ignore_assoc_disallowed && beacon_probe_rsp->assoc_disallowed) { - pe_err("Connection fails due to assoc disallowed reason(%d):%pM PESessionID %d", + pe_err("Connection fails due to assoc disallowed reason(%d):"QDF_MAC_ADDR_FMT" PESessionID %d", beacon_probe_rsp->assoc_disallowed_reason, - session_entry->bssId, + QDF_MAC_ADDR_REF(session_entry->bssId), session_entry->peSessionId); mlm_join_cnf.resultCode = eSIR_SME_ASSOC_REFUSED; mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; @@ -3349,7 +3150,7 @@ lim_check_and_announce_join_success(struct mac_context *mac_ctx, (uint32_t *) &mlm_join_cnf); if (session_entry->vhtCapability && - beacon_probe_rsp->vendor_vht_ie.VHTCaps.present) { + beacon_probe_rsp->vendor_vht_ie.VHTCaps.present) { session_entry->is_vendor_specific_vhtcaps = true; session_entry->vendor_specific_vht_ie_sub_type = beacon_probe_rsp->vendor_vht_ie.sub_type; @@ -3441,41 +3242,27 @@ QDF_STATUS lim_del_bss(struct mac_context *mac, tpDphHashNode sta, uint16_t bss_idx, struct pe_session *pe_session) { - tpDeleteBssParams pDelBssParams = NULL; struct scheduler_msg msgQ = {0}; QDF_STATUS retCode = QDF_STATUS_SUCCESS; - pDelBssParams = qdf_mem_malloc(sizeof(tDeleteBssParams)); - if (!pDelBssParams) - return QDF_STATUS_E_NOMEM; - - pDelBssParams->sessionId = pe_session->peSessionId; /* update PE session Id */ - /* DPH was storing the AssocID in staID field, */ /* staID is actually assigned by HAL when AddSTA message is sent. */ if (sta) { - pDelBssParams->bss_idx = sta->bssId; sta->valid = 0; sta->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; - } else - pDelBssParams->bss_idx = bss_idx; + } pe_session->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; MTRACE(mac_trace (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE)); if ((pe_session->peSessionId == - mac->lim.limTimers.gLimJoinFailureTimer.sessionId) + mac->lim.lim_timers.gLimJoinFailureTimer.sessionId) && (true == - tx_timer_running(&mac->lim.limTimers.gLimJoinFailureTimer))) { + tx_timer_running(&mac->lim.lim_timers.gLimJoinFailureTimer))) { lim_deactivate_and_change_timer(mac, eLIM_JOIN_FAIL_TIMER); } - pDelBssParams->status = QDF_STATUS_SUCCESS; - pDelBssParams->respReqd = 1; - qdf_mem_copy(pDelBssParams->bssid, pe_session->bssId, - sizeof(tSirMacAddr)); - pDelBssParams->smesessionId = pe_session->smeSessionId; /* we need to defer the message until we get the response back from HAL. */ SET_LIM_PROCESS_DEFD_MESGS(mac, false); @@ -3484,12 +3271,12 @@ lim_del_bss(struct mac_context *mac, tpDphHashNode sta, uint16_t bss_idx, else msgQ.type = WMA_DELETE_BSS_REQ; msgQ.reserved = 0; - msgQ.bodyptr = pDelBssParams; - msgQ.bodyval = 0; + msgQ.bodyptr = NULL; + msgQ.bodyval = pe_session->smeSessionId; - pe_debug("Sessionid %d : Sending HAL_DELETE_BSS_REQ BSSID:" QDF_MAC_ADDR_STR, + pe_debug("Sessionid %d : Sending HAL_DELETE_BSS_REQ BSSID:" QDF_MAC_ADDR_FMT, pe_session->peSessionId, - QDF_MAC_ADDR_ARRAY(pe_session->bssId)); + QDF_MAC_ADDR_REF(pe_session->bssId)); MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); retCode = wma_post_ctrl_msg(mac, &msgQ); @@ -3497,7 +3284,6 @@ lim_del_bss(struct mac_context *mac, tpDphHashNode sta, uint16_t bss_idx, SET_LIM_PROCESS_DEFD_MESGS(mac, true); pe_err("Posting DELETE_BSS_REQ to HAL failed, reason=%X", retCode); - qdf_mem_free(pDelBssParams); } return retCode; @@ -3512,9 +3298,10 @@ lim_del_bss(struct mac_context *mac, tpDphHashNode sta, uint16_t bss_idx, * * Return : void */ -static void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, - tpAddBssParams pAddBssParams, - tDot11fIEVHTCaps *vht_caps, struct pe_session *pe_session) +void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, + struct bss_params *pAddBssParams, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *pe_session) { pAddBssParams->staContext.vht_caps = ((vht_caps->maxMPDULen << @@ -3555,8 +3342,8 @@ static void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | (vht_caps->txAntPattern << SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (vht_caps->reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + (vht_caps->extended_nss_bw_supp << + SIR_MAC_VHT_CAP_EXTD_NSS_BW)); pAddBssParams->staContext.maxAmpduSize = SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( @@ -3573,19 +3360,26 @@ static void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, * Return : void */ static void lim_update_vht_oper_assoc_resp(struct mac_context *mac_ctx, - tpAddBssParams pAddBssParams, + struct bss_params *pAddBssParams, tDot11fIEVHTOperation *vht_oper, struct pe_session *pe_session) { - if (vht_oper->chanWidth && - pe_session->ch_width) { - pAddBssParams->ch_width = vht_oper->chanWidth + 1; - - pAddBssParams->ch_center_freq_seg0 = - vht_oper->chanCenterFreqSeg1; - - pAddBssParams->ch_center_freq_seg1 = - vht_oper->chanCenterFreqSeg2; + int16_t ccfs0 = vht_oper->chan_center_freq_seg0; + int16_t ccfs1 = vht_oper->chan_center_freq_seg1; + int16_t offset = abs((ccfs0 - ccfs1)); + uint8_t ch_width; + + ch_width = pAddBssParams->ch_width; + if (vht_oper->chanWidth && pe_session->ch_width) { + ch_width = CH_WIDTH_80MHZ; + if (ccfs1 && offset == 8) + ch_width = CH_WIDTH_160MHZ; + else if (ccfs1 && offset > 16) + ch_width = CH_WIDTH_80P80MHZ; } + if (ch_width > pe_session->ch_width) + ch_width = pe_session->ch_width; + pAddBssParams->ch_width = ch_width; + pAddBssParams->staContext.ch_width = ch_width; } #ifdef WLAN_SUPPORT_TWT @@ -3608,16 +3402,35 @@ static inline void lim_set_sta_ctx_twt(tAddStaParams *sta_ctx, } #endif +void lim_sta_add_bss_update_ht_parameter(uint32_t bss_chan_freq, + tDot11fIEHTCaps* ht_cap, + tDot11fIEHTInfo* ht_inf, + bool chan_width_support, + struct bss_params *add_bss) +{ + if (!ht_cap->present) + return; + + add_bss->htCapable = ht_cap->present; + + if (!ht_inf->present) + return; + + if (chan_width_support && ht_cap->supportedChannelWidthSet) + add_bss->ch_width = ht_inf->recommendedTxWidthSet; + else + add_bss->ch_width = CH_WIDTH_20MHZ; +} + QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp, tpSchBeaconStruct pBeaconStruct, struct bss_description *bssDescription, uint8_t updateEntry, struct pe_session *pe_session) { - struct scheduler_msg msgQ = {0}; - tpAddBssParams pAddBssParams = NULL; + struct bss_params *pAddBssParams = NULL; uint32_t retCode; tpDphHashNode sta = NULL; - uint8_t chanWidthSupp = 0; + bool chan_width_support = false; bool is_vht_cap_in_vendor_ie = false; tDot11fIEVHTCaps *vht_caps = NULL; tDot11fIEVHTOperation *vht_oper = NULL; @@ -3628,7 +3441,7 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info; /* Package SIR_HAL_ADD_BSS_REQ message parameters */ - pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams)); + pAddBssParams = qdf_mem_malloc(sizeof(struct bss_params)); if (!pAddBssParams) { retCode = QDF_STATUS_E_NOMEM; goto returnFailure; @@ -3636,36 +3449,12 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId, sizeof(tSirMacAddr)); - /* Fill in tAddBssParams self_mac_addr */ - qdf_mem_copy(pAddBssParams->self_mac_addr, - pe_session->self_mac_addr, sizeof(tSirMacAddr)); - - pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE; - - pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; - - /* Update PE session ID */ - pAddBssParams->sessionId = pe_session->peSessionId; - pAddBssParams->bss_idx = pe_session->smeSessionId; pAddBssParams->beaconInterval = bssDescription->beaconInterval; pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; pAddBssParams->updateBss = updateEntry; - pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; - pAddBssParams->cfParamSet.cfpPeriod = - pBeaconStruct->cfParamSet.cfpPeriod; - pAddBssParams->cfParamSet.cfpMaxDuration = - pBeaconStruct->cfParamSet.cfpMaxDuration; - pAddBssParams->cfParamSet.cfpDurRemaining = - pBeaconStruct->cfParamSet.cfpDurRemaining; - - pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates; - qdf_mem_copy(pAddBssParams->rateSet.rate, - pAssocRsp->supportedRates.rate, - pAssocRsp->supportedRates.numRates); - if (IS_DOT11_MODE_11B(pe_session->dot11mode) && bssDescription->nwType != eSIR_11B_NW_TYPE) { pAddBssParams->nwType = eSIR_11B_NW_TYPE; @@ -3675,58 +3464,22 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp pAddBssParams->shortSlotTimeSupported = (uint8_t) pAssocRsp->capabilityInfo.shortSlotTime; - pAddBssParams->llaCoexist = - (uint8_t) pe_session->beaconParams.llaCoexist; pAddBssParams->llbCoexist = (uint8_t) pe_session->beaconParams.llbCoexist; - pAddBssParams->llgCoexist = - (uint8_t) pe_session->beaconParams.llgCoexist; - pAddBssParams->ht20Coexist = - (uint8_t) pe_session->beaconParams.ht20Coexist; - - pAddBssParams->dot11_mode = pe_session->dot11mode; - - if (IS_DOT11_MODE_HT(pe_session->dot11mode)) - chanWidthSupp = lim_get_ht_capability(mac, - eHT_SUPPORTED_CHANNEL_WIDTH_SET, - pe_session); /* Use the advertised capabilities from the received beacon/PR */ - if (IS_DOT11_MODE_HT(pe_session->dot11mode) - && (pAssocRsp->HTCaps.present)) { - pAddBssParams->htCapable = pAssocRsp->HTCaps.present; - if (pBeaconStruct->HTInfo.present) { - pAddBssParams->htOperMode = - (tSirMacHTOperatingMode) pAssocRsp->HTInfo.opMode; - pAddBssParams->dualCTSProtection = - (uint8_t) pAssocRsp->HTInfo.dualCTSProtection; - - if ((pAssocRsp->HTCaps.supportedChannelWidthSet) - && (chanWidthSupp)) { - pAddBssParams->ch_width = (uint8_t) - pAssocRsp->HTInfo.recommendedTxWidthSet; - if (pAssocRsp->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId + 2; - else if (pAssocRsp->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId - 2; - } else { - pAddBssParams->ch_width = CH_WIDTH_20MHZ; - pAddBssParams->ch_center_freq_seg0 = 0; - } - pAddBssParams->llnNonGFCoexist = - (uint8_t) pAssocRsp->HTInfo.nonGFDevicesPresent; - pAddBssParams->fLsigTXOPProtectionFullSupport = - (uint8_t) pAssocRsp->HTInfo. - lsigTXOPProtectionFullSupport; - pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode; - } + if (IS_DOT11_MODE_HT(pe_session->dot11mode)) { + chan_width_support = + lim_get_ht_capability(mac, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + pe_session); + lim_sta_add_bss_update_ht_parameter(bssDescription->chan_freq, + &pAssocRsp->HTCaps, + &pAssocRsp->HTInfo, + chan_width_support, + pAddBssParams); } - pAddBssParams->currentOperChannel = bssDescription->channelId; if (pe_session->vhtCapability && (pAssocRsp->VHTCaps.present)) { pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present; vht_caps = &pAssocRsp->VHTCaps; @@ -3776,8 +3529,8 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp &pe_session->dph.dphHashTable); if (!sta) { pe_err("Couldn't get assoc id for " "MAC ADDR: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( pAddBssParams->staContext.staMac)); return QDF_STATUS_E_FAILURE; } @@ -3786,18 +3539,11 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp pe_session->gUapsdPerAcBitmask; pAddBssParams->staContext.maxSPLen = 0; - pAddBssParams->staContext.shortPreambleSupported = - (uint8_t) pAssocRsp->capabilityInfo.shortPreamble; pAddBssParams->staContext.updateSta = updateEntry; if (IS_DOT11_MODE_HT(pe_session->dot11mode) && pBeaconStruct->HTCaps.present) { - pAddBssParams->staContext.us32MaxAmpduDuration = 0; pAddBssParams->staContext.htCapable = 1; - pAddBssParams->staContext.greenFieldCapable = - (uint8_t) pAssocRsp->HTCaps.greenField; - pAddBssParams->staContext.lsigTxopProtection = - (uint8_t) pAssocRsp->HTCaps.lsigTXOPProtection; if (pe_session->ht_config.ht_tx_stbc) pAddBssParams->staContext.stbc_capable = pAssocRsp->HTCaps.rxSTBC; @@ -3836,6 +3582,19 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp if (vht_caps && pAddBssParams->staContext.stbc_capable) pAddBssParams->staContext.stbc_capable = vht_caps->rxSTBC; + if (pe_session->ch_width == CH_WIDTH_160MHZ || + pe_session->ch_width == CH_WIDTH_80P80MHZ) { + sta_context->vht_160mhz_nss = + sta->vht_160mhz_nss; + sta_context->vht_80p80mhz_nss = + sta->vht_80p80mhz_nss; + sta_context->vht_extended_nss_bw_cap = + sta->vht_extended_nss_bw_cap; + } else { + sta_context->vht_160mhz_nss = 0; + sta_context->vht_80p80mhz_nss = 0; + sta_context->vht_extended_nss_bw_cap = 0; + } } if (lim_is_session_he_capable(pe_session) && pAssocRsp->he_cap.present) { @@ -3852,12 +3611,15 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp * width has been taken into account for calculating * pe_session->ch_width */ - if (chanWidthSupp && + if (chan_width_support && ((pAssocRsp->HTCaps.supportedChannelWidthSet) || (pBeaconStruct->HTCaps.supportedChannelWidthSet))) { + pAddBssParams->ch_width = + pe_session->ch_width; pAddBssParams->staContext.ch_width = pe_session->ch_width; } else { + pAddBssParams->ch_width = CH_WIDTH_20MHZ; sta_context->ch_width = CH_WIDTH_20MHZ; if (!vht_cap_info->enable_txbf_20mhz) sta_context->vhtTxBFCapable = 0; @@ -3866,12 +3628,8 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState) pAssocRsp->HTCaps.mimoPowerSave; - pAddBssParams->staContext.maxAmsduSize = - (uint8_t) pAssocRsp->HTCaps.maximalAMSDUsize; pAddBssParams->staContext.maxAmpduDensity = pAssocRsp->HTCaps.mpduDensity; - pAddBssParams->staContext.fDsssCckMode40Mhz = - (uint8_t) pAssocRsp->HTCaps.dsssCckMode40MHz; /* * We will check gShortGI20Mhz and gShortGI40Mhz from * session entry if they are set then we will use what ever @@ -3934,10 +3692,22 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp } } - if (pBeaconStruct->HTInfo.present) - pAddBssParams->staContext.rifsMode = - pAssocRsp->HTInfo.rifsMode; - + } + if (lim_is_he_6ghz_band(pe_session)) { + if (lim_is_session_he_capable(pe_session) && + pAssocRsp->he_cap.present) { + lim_intersect_ap_he_caps(pe_session, + pAddBssParams, + NULL, + pAssocRsp); + lim_update_he_stbc_capable(&pAddBssParams->staContext); + lim_update_he_6gop_assoc_resp(pAddBssParams, + &pAssocRsp->he_op, + pe_session); + lim_update_he_6ghz_band_caps(mac, + &pAssocRsp->he_6ghz_band_cap, + &pAddBssParams->staContext); + } } pAddBssParams->staContext.smesessionId = pe_session->smeSessionId; @@ -3978,11 +3748,6 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp pAddBssParams->staContext.encryptType = pe_session->encryptType; pAddBssParams->maxTxPower = pe_session->maxTxPower; - /* FIXME_GEN4 - Any other value that can be used for initialization? */ - pAddBssParams->status = QDF_STATUS_SUCCESS; - pAddBssParams->respReqd = true; - /* update persona */ - pAddBssParams->halPersona = (uint8_t)pe_session->opmode; if (QDF_P2P_CLIENT_MODE == pe_session->opmode) pAddBssParams->staContext.p2pCapableSta = 1; @@ -4016,7 +3781,6 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp if (pe_session->isNonRoamReassoc) pAddBssParams->nonRoamReassoc = 1; - pAddBssParams->nss = pe_session->nss; pe_debug("update %d MxAmpduDen %d mimoPS %d vht_mcs11 %d shortSlot %d BI %d DTIM %d enc type %d p2p cab STA %d", updateEntry, @@ -4042,45 +3806,38 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp /* we need to defer the message until we get the response back */ SET_LIM_PROCESS_DEFD_MESGS(mac, false); - msgQ.type = WMA_ADD_BSS_REQ; - /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ - msgQ.reserved = 0; - msgQ.bodyptr = pAddBssParams; - msgQ.bodyval = 0; - - MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); - - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { + retCode = wma_send_peer_assoc_req(pAddBssParams); + if (QDF_IS_STATUS_ERROR(retCode)) { SET_LIM_PROCESS_DEFD_MESGS(mac, true); - qdf_mem_free(pAddBssParams); - pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X", - retCode); - goto returnFailure; - - } else - return retCode; + pe_err("wma_send_peer_assoc_req failed=%X", + retCode); + } + qdf_mem_free(pAddBssParams); returnFailure: /* Clean-up will be done by the caller... */ return retCode; } -QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updateEntry, - struct pe_session *pe_session) +QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, + struct pe_session *pe_session) { - struct scheduler_msg msgQ = {0}; - tpAddBssParams pAddBssParams = NULL; + struct bss_params *pAddBssParams = NULL; uint32_t retCode; tSchBeaconStruct *pBeaconStruct; - uint8_t chanWidthSupp = 0; + bool chan_width_support = false; tDot11fIEVHTOperation *vht_oper = NULL; tDot11fIEVHTCaps *vht_caps = NULL; uint32_t listen_interval = MLME_CFG_LISTEN_INTERVAL; - struct bss_description *bssDescription = - &pe_session->lim_join_req->bssDescription; + struct bss_description *bssDescription = NULL; struct mlme_vht_capabilities_info *vht_cap_info; + if (!pe_session->lim_join_req) { + pe_err("Lim Join request is NULL"); + return QDF_STATUS_E_FAILURE; + } + + bssDescription = &pe_session->lim_join_req->bssDescription; vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info; pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct)); @@ -4088,7 +3845,7 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat return QDF_STATUS_E_NOMEM; /* Package SIR_HAL_ADD_BSS_REQ message parameters */ - pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams)); + pAddBssParams = qdf_mem_malloc(sizeof(struct bss_params)); if (!pAddBssParams) { retCode = QDF_STATUS_E_NOMEM; goto returnFailure; @@ -4105,94 +3862,31 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId, sizeof(tSirMacAddr)); - /* Fill in tAddBssParams self_mac_addr */ - qdf_mem_copy(pAddBssParams->self_mac_addr, - pe_session->self_mac_addr, sizeof(tSirMacAddr)); - /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on - * top of an already established Infra link. This lead to issues in - * concurrent data transfer. - */ - - pAddBssParams->bssType = pe_session->bssType; /* eSIR_INFRASTRUCTURE_MODE; */ - pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; - pAddBssParams->beaconInterval = bssDescription->beaconInterval; pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; - pAddBssParams->updateBss = updateEntry; - - pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; - pAddBssParams->cfParamSet.cfpPeriod = - pBeaconStruct->cfParamSet.cfpPeriod; - pAddBssParams->cfParamSet.cfpMaxDuration = - pBeaconStruct->cfParamSet.cfpMaxDuration; - pAddBssParams->cfParamSet.cfpDurRemaining = - pBeaconStruct->cfParamSet.cfpDurRemaining; - - pAddBssParams->rateSet.numRates = - pBeaconStruct->supportedRates.numRates; - qdf_mem_copy(pAddBssParams->rateSet.rate, - pBeaconStruct->supportedRates.rate, - pBeaconStruct->supportedRates.numRates); + pAddBssParams->updateBss = false; pAddBssParams->nwType = bssDescription->nwType; pAddBssParams->shortSlotTimeSupported = (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime; - pAddBssParams->llaCoexist = - (uint8_t) pe_session->beaconParams.llaCoexist; pAddBssParams->llbCoexist = (uint8_t) pe_session->beaconParams.llbCoexist; - pAddBssParams->llgCoexist = - (uint8_t) pe_session->beaconParams.llgCoexist; - pAddBssParams->ht20Coexist = - (uint8_t) pe_session->beaconParams.ht20Coexist; /* Use the advertised capabilities from the received beacon/PR */ - if (IS_DOT11_MODE_HT(pe_session->dot11mode) - && (pBeaconStruct->HTCaps.present)) { - pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; - if (pBeaconStruct->HTInfo.present) { - pAddBssParams->htOperMode = - (tSirMacHTOperatingMode) pBeaconStruct->HTInfo. - opMode; - pAddBssParams->dualCTSProtection = - (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection; - - chanWidthSupp = - lim_get_ht_capability(mac, - eHT_SUPPORTED_CHANNEL_WIDTH_SET, - pe_session); - if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) - && (chanWidthSupp)) { - pAddBssParams->ch_width = - (uint8_t) pBeaconStruct->HTInfo. - recommendedTxWidthSet; - if (pBeaconStruct->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId + 2; - - if (pBeaconStruct->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId - 2; - } else { - pAddBssParams->ch_width = CH_WIDTH_20MHZ; - pAddBssParams->ch_center_freq_seg0 = 0; - } - pAddBssParams->llnNonGFCoexist = - (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent; - pAddBssParams->fLsigTXOPProtectionFullSupport = - (uint8_t) pBeaconStruct->HTInfo. - lsigTXOPProtectionFullSupport; - pAddBssParams->fRIFSMode = - pBeaconStruct->HTInfo.rifsMode; - } + if (IS_DOT11_MODE_HT(pe_session->dot11mode)) { + chan_width_support = + lim_get_ht_capability(mac, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + pe_session); + lim_sta_add_bss_update_ht_parameter(bssDescription->chan_freq, + &pBeaconStruct->HTCaps, + &pBeaconStruct->HTInfo, + chan_width_support, + pAddBssParams); } - pAddBssParams->currentOperChannel = bssDescription->channelId; - if (pe_session->vhtCapability && (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps))) { @@ -4205,15 +3899,6 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat pe_debug("VHT Operation is present in vendor Specific IE"); } - - if ((vht_oper) && - vht_oper->chanWidth && - chanWidthSupp) { - pAddBssParams->ch_center_freq_seg0 = - vht_oper->chanCenterFreqSeg1; - pAddBssParams->ch_center_freq_seg1 = - vht_oper->chanCenterFreqSeg2; - } /* * in limExtractApCapability function intersection of FW * advertised channel width and AP advertised channel width has @@ -4234,6 +3919,7 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat lim_update_bss_he_capable(mac, pAddBssParams); lim_add_bss_he_cfg(pAddBssParams, pe_session); } + /* * Populate the STA-related parameters here * Note that the STA here refers to the AP @@ -4249,20 +3935,11 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat pAddBssParams->staContext.assocId = 0; pAddBssParams->staContext.uAPSD = 0; pAddBssParams->staContext.maxSPLen = 0; - pAddBssParams->staContext.shortPreambleSupported = - (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble; - pAddBssParams->staContext.updateSta = updateEntry; - - pAddBssParams->dot11_mode = pe_session->dot11mode; + pAddBssParams->staContext.updateSta = false; if (IS_DOT11_MODE_HT(pe_session->dot11mode) && (pBeaconStruct->HTCaps.present)) { - pAddBssParams->staContext.us32MaxAmpduDuration = 0; pAddBssParams->staContext.htCapable = 1; - pAddBssParams->staContext.greenFieldCapable = - (uint8_t) pBeaconStruct->HTCaps.greenField; - pAddBssParams->staContext.lsigTxopProtection = - (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection; if (pe_session->vhtCapability && (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || IS_BSS_VHT_CAPABLE( @@ -4294,8 +3971,8 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat lim_intersect_ap_he_caps(pe_session, pAddBssParams, pBeaconStruct, NULL); - if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && - (chanWidthSupp)) { + if (pBeaconStruct->HTCaps.supportedChannelWidthSet && + chan_width_support) { pAddBssParams->staContext.ch_width = (uint8_t) pBeaconStruct->HTInfo. recommendedTxWidthSet; @@ -4311,12 +3988,8 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps. mimoPowerSave; - pAddBssParams->staContext.maxAmsduSize = - (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize; pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; - pAddBssParams->staContext.fDsssCckMode40Mhz = - (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz; /* * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. * if they are set then we will use what ever Beacon coming @@ -4362,10 +4035,6 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat else pAddBssParams->staContext.vhtLdpcCapable = 0; } - - if (pBeaconStruct->HTInfo.present) - pAddBssParams->staContext.rifsMode = - pBeaconStruct->HTInfo.rifsMode; } /* * If WMM IE or 802.11E IE is not present @@ -4387,24 +4056,15 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat pBeaconStruct->HTCaps.supportedMCSSet, false, pe_session, &pBeaconStruct->VHTCaps, - &pBeaconStruct->he_cap); + &pBeaconStruct->he_cap, NULL, + bssDescription); pAddBssParams->staContext.encryptType = pe_session->encryptType; pAddBssParams->maxTxPower = pe_session->maxTxPower; - pAddBssParams->status = QDF_STATUS_SUCCESS; - pAddBssParams->respReqd = true; - pAddBssParams->staContext.smesessionId = pe_session->smeSessionId; pAddBssParams->staContext.sessionId = pe_session->peSessionId; - pAddBssParams->sessionId = pe_session->peSessionId; - pAddBssParams->bss_idx = pe_session->smeSessionId; - - pAddBssParams->halPersona = (uint8_t)pe_session->opmode; - - pAddBssParams->bSpectrumMgtEnabled = pe_session->spectrumMgtEnabled; - pAddBssParams->extSetStaKeyParamValid = 0; #ifdef WLAN_FEATURE_11W @@ -4413,19 +4073,12 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat pAddBssParams->staContext.rmfEnabled = 1; } #endif - - pAddBssParams->nss = pe_session->nss; - /* Set a new state for MLME */ pe_session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE; MTRACE(mac_trace (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId, pe_session->limMlmState)); - - /* we need to defer the message until we get the response back from HAL. */ - SET_LIM_PROCESS_DEFD_MESGS(mac, false); - if (cds_is_5_mhz_enabled()) { pAddBssParams->ch_width = CH_WIDTH_5MHZ; pAddBssParams->staContext.ch_width = CH_WIDTH_5MHZ; @@ -4437,26 +4090,15 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updat if (lim_is_fils_connection(pe_session)) pAddBssParams->no_ptk_4_way = true; - msgQ.type = WMA_ADD_BSS_REQ; - /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ - msgQ.reserved = 0; - msgQ.bodyptr = pAddBssParams; - msgQ.bodyval = 0; - - MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); - - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { - SET_LIM_PROCESS_DEFD_MESGS(mac, true); - qdf_mem_free(pAddBssParams); - pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X", - retCode); - goto returnFailure; - - } else { - qdf_mem_free(pBeaconStruct); - return retCode; - } + retCode = wma_pre_assoc_req(pAddBssParams); + lim_process_sta_add_bss_rsp_pre_assoc(mac, pAddBssParams, + pe_session, retCode); + qdf_mem_free(pAddBssParams); + /* + * Set retCode sucess as lim_process_sta_add_bss_rsp_pre_assoc take + * care of failure + */ + retCode = QDF_STATUS_SUCCESS; returnFailure: /* Clean-up will be done by the caller... */ @@ -4611,8 +4253,8 @@ QDF_STATUS lim_is_dot11h_power_capabilities_in_range(struct mac_context *mac, int8_t localMaxTxPower; uint8_t local_pwr_constraint; - localMaxTxPower = lim_get_regulatory_max_transmit_power( - mac, pe_session->currentOperChannel); + localMaxTxPower = wlan_reg_get_channel_reg_power_for_freq( + mac->pdev, pe_session->curr_op_freq); local_pwr_constraint = mac->mlme_cfg->power.local_power_constraint; localMaxTxPower -= (int8_t)local_pwr_constraint; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.h index db2609fab1a96d69a28396a4670b1ed00b71ef22..f0f669e90cfd2f933c580ce653a74766b134d091 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_assoc_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,12 +43,6 @@ uint8_t lim_compare_capabilities(struct mac_context *, tSirAssocReq *, tSirMacCapabilityInfo *, struct pe_session *); uint8_t lim_check_rx_basic_rates(struct mac_context *, tSirMacRateSet, struct pe_session *); -uint8_t lim_check_rx_rsn_ie_match(struct mac_context *mac_ctx, - tDot11fIERSN * const rx_rsn_ie, - struct pe_session *session_entry, uint8_t sta_is_ht, - bool *pmf_connection); -uint8_t lim_check_rx_wpa_ie_match(struct mac_context *, tDot11fIEWPA *, struct pe_session *, - uint8_t); uint8_t lim_check_mcs_set(struct mac_context *mac, uint8_t *supportedMCSSet); QDF_STATUS lim_cleanup_rx_path(struct mac_context *, tpDphHashNode, struct pe_session *); @@ -62,7 +56,9 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, uint8_t basicOnly, struct pe_session *pe_session, tDot11fIEVHTCaps *pVHTCaps, - tDot11fIEhe_cap *he_caps); + tDot11fIEhe_cap *he_caps, + struct sDphHashNode *sta_ds, + struct bss_description *bss_desc); /** * lim_populate_own_rate_set() - comprises the basic and extended rates read @@ -107,7 +103,7 @@ QDF_STATUS lim_populate_matching_rate_set(struct mac_context *mac_ctx, QDF_STATUS lim_add_sta(struct mac_context *, tpDphHashNode, uint8_t, struct pe_session *); QDF_STATUS lim_del_bss(struct mac_context *, tpDphHashNode, uint16_t, struct pe_session *); QDF_STATUS lim_del_sta(struct mac_context *, tpDphHashNode, bool, struct pe_session *); -QDF_STATUS lim_add_sta_self(struct mac_context *, uint16_t, uint8_t, struct pe_session *); +QDF_STATUS lim_add_sta_self(struct mac_context *, uint8_t, struct pe_session *); #ifdef WLAN_FEATURE_HOST_ROAM void lim_restore_pre_reassoc_state(struct mac_context *, @@ -184,14 +180,55 @@ void lim_update_re_assoc_globals(struct mac_context *mac, void lim_update_assoc_sta_datas(struct mac_context *mac, tpDphHashNode sta, tpSirAssocRsp pAssocRsp, + struct pe_session *pe_session, + tSchBeaconStruct *beacon); + +/** + * lim_sta_add_bss_update_ht_parameter() - function to update ht related + * parameters when add bss request + * @bss_chan_freq: operating frequency of bss + * @ht_cap: ht capability extract from beacon/assoc response + * @ht_inf: ht information extract from beacon/assoc response + * @chan_width_support: local wide bandwith support capability + * @add_bss: add bss request struct to be updated + * + * Return: none + */ +void lim_sta_add_bss_update_ht_parameter(uint32_t bss_chan_freq, + tDot11fIEHTCaps* ht_cap, + tDot11fIEHTInfo* ht_inf, + bool chan_width_support, + struct bss_params *add_bss); + +/** + * lim_sta_send_add_bss() - add bss and send peer assoc after receive assoc + * rsp in sta mode + *.@mac: pointer to Global MAC structure + * @pAssocRsp: contains the structured assoc/reassoc Response got from AP + * @beaconstruct: the ProbeRsp/Beacon structured details + * @bssDescription: bss description passed to PE from the SME + * @updateEntry: bool flag of whether update bss and sta + * @pe_session: pointer to pe session + * + * Return: none + */ +QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, + tpSirAssocRsp pAssocRsp, + tpSchBeaconStruct pBeaconStruct, + struct bss_description *bssDescription, + uint8_t updateEntry, struct pe_session *pe_session); -QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp, - tpSchBeaconStruct pBeaconStruct, - struct bss_description *bssDescription, - uint8_t updateEntry, struct pe_session *pe_session); -QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, uint8_t updateEntry, - struct pe_session *pe_session); +/** + * lim_sta_send_add_bss_pre_assoc() - add bss after channel switch and before + * associate req in sta mode + *.@mac: pointer to Global MAC structure + * @pe_session: pointer to pe session + * + * Return: none + */ +QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, + struct pe_session *pe_session); void lim_prepare_and_send_del_sta_cnf(struct mac_context *mac, tpDphHashNode sta, @@ -271,6 +308,7 @@ void lim_send_sme_tsm_ie_ind(struct mac_context *mac, * @peer_vht_caps: pointer to peer vht capabilities * @session_entry: pe session entry * @nss: number of spatial streams + * @sta_ds: pointer to peer sta data structure * * Populates vht mcs rate set based on peer and self capabilities * @@ -280,7 +318,8 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, struct supported_rates *rates, tDot11fIEVHTCaps *peer_vht_caps, struct pe_session *session_entry, - uint8_t nss); + uint8_t nss, + struct sDphHashNode *sta_ds); /** * lim_extract_ies_from_deauth_disassoc() - Extract IEs from deauth/disassoc @@ -299,4 +338,18 @@ void lim_extract_ies_from_deauth_disassoc(struct pe_session *session, uint8_t *deauth_disassoc_frame, uint16_t deauth_disassoc_frame_len); + +/** + * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response. + * @mac_ctx Pointer to Global MAC structure + * @pAddBssParams: parameters required for add bss params. + * @vht_caps: VHT capabilities. + * @pe_session : session entry. + * + * Return : void + */ +void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, + struct bss_params *pAddBssParams, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *pe_session); #endif /* __LIM_ASSOC_UTILS_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft.c index 2f4e6269c0860ca6de3b3c6e0f9d609c86842e7a..c6f17ee065e471cb515efe1f786516881faed1ee 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,15 +36,10 @@ #include #include #include +#include #include "wmm_apsd.h" #include "wma.h" -extern void lim_send_set_sta_key_req(struct mac_context *mac, - tLimMlmSetKeysReq * pMlmSetKeysReq, - uint16_t staIdx, - uint8_t defWEPIdx, - struct pe_session *pe_session, bool sendRsp); - /*-------------------------------------------------------------------------- Initialize the FT variables. ------------------------------------------------------------------------*/ @@ -70,13 +65,13 @@ void lim_ft_cleanup_all_ft_sessions(struct mac_context *mac) void lim_ft_cleanup(struct mac_context *mac, struct pe_session *pe_session) { if (!pe_session) { - pe_debug("pe_session is NULL"); + pe_err("pe_session is NULL"); return; } /* Nothing to be done if the session is not in STA mode */ if (!LIM_IS_STA_ROLE(pe_session)) { - pe_err("pe_session is not in STA mode"); + pe_debug("pe_session is not in STA mode"); return; } @@ -118,13 +113,14 @@ void lim_ft_cleanup(struct mac_context *mac, struct pe_session *pe_session) * *------------------------------------------------------------------*/ void lim_ft_prepare_add_bss_req(struct mac_context *mac, - uint8_t updateEntry, struct pe_session *ft_session, + struct pe_session *ft_session, struct bss_description *bssDescription) { - tpAddBssParams pAddBssParams = NULL; + struct bss_params *pAddBssParams = NULL; tAddStaParams *sta_ctx; - uint8_t chanWidthSupp = 0; + bool chan_width_support = false; tSchBeaconStruct *pBeaconStruct; + tDot11fIEVHTCaps *vht_caps = NULL; /* Nothing to be done if the session is not in STA mode */ if (!LIM_IS_STA_ROLE(ft_session)) { @@ -137,7 +133,7 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, return; /* Package SIR_HAL_ADD_BSS_REQ message parameters */ - pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams)); + pAddBssParams = qdf_mem_malloc(sizeof(struct bss_params)); if (!pAddBssParams) { qdf_mem_free(pBeaconStruct); return; @@ -154,55 +150,32 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId, sizeof(tSirMacAddr)); - - /* Fill in tAddBssParams self_mac_addr */ - qdf_mem_copy(pAddBssParams->self_mac_addr, ft_session->self_mac_addr, - sizeof(tSirMacAddr)); - - pAddBssParams->bssType = ft_session->bssType; - pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; - pAddBssParams->beaconInterval = bssDescription->beaconInterval; pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; - pAddBssParams->updateBss = updateEntry; - - pAddBssParams->reassocReq = true; - - pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; - pAddBssParams->cfParamSet.cfpPeriod = - pBeaconStruct->cfParamSet.cfpPeriod; - pAddBssParams->cfParamSet.cfpMaxDuration = - pBeaconStruct->cfParamSet.cfpMaxDuration; - pAddBssParams->cfParamSet.cfpDurRemaining = - pBeaconStruct->cfParamSet.cfpDurRemaining; - - pAddBssParams->rateSet.numRates = - pBeaconStruct->supportedRates.numRates; - qdf_mem_copy(pAddBssParams->rateSet.rate, - pBeaconStruct->supportedRates.rate, - pBeaconStruct->supportedRates.numRates); + pAddBssParams->updateBss = false; pAddBssParams->nwType = bssDescription->nwType; pAddBssParams->shortSlotTimeSupported = (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime; - pAddBssParams->llaCoexist = - (uint8_t) ft_session->beaconParams.llaCoexist; pAddBssParams->llbCoexist = (uint8_t) ft_session->beaconParams.llbCoexist; - pAddBssParams->llgCoexist = - (uint8_t) ft_session->beaconParams.llgCoexist; - pAddBssParams->ht20Coexist = - (uint8_t) ft_session->beaconParams.ht20Coexist; #ifdef WLAN_FEATURE_11W pAddBssParams->rmfEnabled = ft_session->limRmfEnabled; #endif - /* Use the advertised capabilities from the received beacon/PR */ if (IS_DOT11_MODE_HT(ft_session->dot11mode) && (pBeaconStruct->HTCaps.present)) { - pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; + chan_width_support = + lim_get_ht_capability(mac, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + ft_session); + lim_sta_add_bss_update_ht_parameter(bssDescription->chan_freq, + &pBeaconStruct->HTCaps, + &pBeaconStruct->HTInfo, + chan_width_support, + pAddBssParams); qdf_mem_copy(&pAddBssParams->staContext.capab_info, &pBeaconStruct->capabilityInfo, sizeof(pAddBssParams->staContext.capab_info)); @@ -210,44 +183,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, (uint8_t *) &pBeaconStruct->HTCaps + sizeof(uint8_t), sizeof(pAddBssParams->staContext.ht_caps)); - - if (pBeaconStruct->HTInfo.present) { - pAddBssParams->htOperMode = - (tSirMacHTOperatingMode) pBeaconStruct->HTInfo. - opMode; - pAddBssParams->dualCTSProtection = - (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection; - - chanWidthSupp = lim_get_ht_capability(mac, - eHT_SUPPORTED_CHANNEL_WIDTH_SET, - ft_session); - if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && - (chanWidthSupp)) { - pAddBssParams->ch_width = (uint8_t) - pBeaconStruct->HTInfo.recommendedTxWidthSet; - if (pBeaconStruct->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId + 2; - else if (pBeaconStruct->HTInfo.secondaryChannelOffset == - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - pAddBssParams->ch_center_freq_seg0 = - bssDescription->channelId - 2; - } else { - pAddBssParams->ch_width = CH_WIDTH_20MHZ; - pAddBssParams->ch_center_freq_seg0 = 0; - } - pAddBssParams->llnNonGFCoexist = - (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent; - pAddBssParams->fLsigTXOPProtectionFullSupport = - (uint8_t) pBeaconStruct->HTInfo. - lsigTXOPProtectionFullSupport; - pAddBssParams->fRIFSMode = - pBeaconStruct->HTInfo.rifsMode; - } } - pAddBssParams->currentOperChannel = bssDescription->channelId; ft_session->htSecondaryChannelOffset = pBeaconStruct->HTInfo.secondaryChannelOffset; sta_ctx = &pAddBssParams->staContext; @@ -255,55 +192,24 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, if (ft_session->vhtCapability && ft_session->vhtCapabilityPresentInBeacon) { pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; - if (pBeaconStruct->VHTOperation.chanWidth && chanWidthSupp) { + if (pBeaconStruct->VHTOperation.chanWidth && chan_width_support) pAddBssParams->ch_width = pBeaconStruct->VHTOperation.chanWidth + 1; - pAddBssParams->ch_center_freq_seg0 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg1; - pAddBssParams->ch_center_freq_seg1 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg2; - } - pAddBssParams->staContext.vht_caps = - ((pBeaconStruct->VHTCaps.maxMPDULen << - SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | - (pBeaconStruct->VHTCaps.supportedChannelWidthSet << - SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | - (pBeaconStruct->VHTCaps.ldpcCodingCap << - SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | - (pBeaconStruct->VHTCaps.shortGI80MHz << - SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | - (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz << - SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | - (pBeaconStruct->VHTCaps.txSTBC << - SIR_MAC_VHT_CAP_TXSTBC) | - (pBeaconStruct->VHTCaps.rxSTBC << - SIR_MAC_VHT_CAP_RXSTBC) | - (pBeaconStruct->VHTCaps.suBeamFormerCap << - SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | - (pBeaconStruct->VHTCaps.suBeamformeeCap << - SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | - (pBeaconStruct->VHTCaps.csnofBeamformerAntSup << - SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | - (pBeaconStruct->VHTCaps.numSoundingDim << - SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | - (pBeaconStruct->VHTCaps.muBeamformerCap << - SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) | - (pBeaconStruct->VHTCaps.muBeamformeeCap << - SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | - (pBeaconStruct->VHTCaps.vhtTXOPPS << - SIR_MAC_VHT_CAP_TXOPPS) | - (pBeaconStruct->VHTCaps.htcVHTCap << - SIR_MAC_VHT_CAP_HTC_CAP) | - (pBeaconStruct->VHTCaps.maxAMPDULenExp << - SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | - (pBeaconStruct->VHTCaps.vhtLinkAdaptCap << - SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | - (pBeaconStruct->VHTCaps.rxAntPattern << - SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | - (pBeaconStruct->VHTCaps.txAntPattern << - SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (pBeaconStruct->VHTCaps.reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + vht_caps = &pBeaconStruct->VHTCaps; + lim_update_vhtcaps_assoc_resp(mac, pAddBssParams, + vht_caps, ft_session); + } else if (ft_session->vhtCapability && + pBeaconStruct->vendor_vht_ie.VHTCaps.present) { + pe_debug("VHT caps are present in vendor specific IE"); + pAddBssParams->vhtCapable = + pBeaconStruct->vendor_vht_ie.VHTCaps.present; + if (pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth && + chan_width_support) + pAddBssParams->ch_width = + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1; + vht_caps = &pBeaconStruct->vendor_vht_ie.VHTCaps; + lim_update_vhtcaps_assoc_resp(mac, pAddBssParams, + vht_caps, ft_session); } else { pAddBssParams->vhtCapable = 0; } @@ -314,8 +220,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, lim_add_bss_he_cfg(pAddBssParams, ft_session); } - pe_debug("SIR_HAL_ADD_BSS_REQ with channel: %d", - pAddBssParams->currentOperChannel); + pe_debug("SIR_HAL_ADD_BSS_REQ with frequency: %d", + bssDescription->chan_freq); /* Populate the STA-related parameters here */ /* Note that the STA here refers to the AP */ @@ -330,9 +236,7 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, pAddBssParams->staContext.assocId = 0; pAddBssParams->staContext.uAPSD = 0; pAddBssParams->staContext.maxSPLen = 0; - pAddBssParams->staContext.shortPreambleSupported = - (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble; - pAddBssParams->staContext.updateSta = updateEntry; + pAddBssParams->staContext.updateSta = false; pAddBssParams->staContext.encryptType = ft_session->encryptType; #ifdef WLAN_FEATURE_11W @@ -342,14 +246,9 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, if (IS_DOT11_MODE_HT(ft_session->dot11mode) && (pBeaconStruct->HTCaps.present)) { - pAddBssParams->staContext.us32MaxAmpduDuration = 0; pAddBssParams->staContext.htCapable = 1; - pAddBssParams->staContext.greenFieldCapable = - (uint8_t) pBeaconStruct->HTCaps.greenField; - pAddBssParams->staContext.lsigTxopProtection = - (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection; - if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && - (chanWidthSupp)) { + if (pBeaconStruct->HTCaps.supportedChannelWidthSet && + chan_width_support) { pAddBssParams->staContext.ch_width = (uint8_t) pBeaconStruct->HTInfo.recommendedTxWidthSet; } else { @@ -373,8 +272,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, lim_intersect_ap_he_caps(ft_session, pAddBssParams, pBeaconStruct, NULL); - if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && - (chanWidthSupp)) { + if (pBeaconStruct->HTCaps.supportedChannelWidthSet && + chan_width_support) { sta_ctx->ch_width = (uint8_t) pBeaconStruct->HTInfo.recommendedTxWidthSet; if (pAddBssParams->staContext.vhtCapable && @@ -389,22 +288,14 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps. mimoPowerSave; - pAddBssParams->staContext.maxAmsduSize = - (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize; pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; - pAddBssParams->staContext.fDsssCckMode40Mhz = - (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz; pAddBssParams->staContext.fShortGI20Mhz = (uint8_t) pBeaconStruct->HTCaps.shortGI20MHz; pAddBssParams->staContext.fShortGI40Mhz = (uint8_t) pBeaconStruct->HTCaps.shortGI40MHz; pAddBssParams->staContext.maxAmpduSize = pBeaconStruct->HTCaps.maxRxAMPDUFactor; - - if (pBeaconStruct->HTInfo.present) - pAddBssParams->staContext.rifsMode = - pBeaconStruct->HTInfo.rifsMode; } if ((ft_session->limWmeEnabled @@ -433,7 +324,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, pBeaconStruct->HTCaps.supportedMCSSet, false, ft_session, &pBeaconStruct->VHTCaps, - &pBeaconStruct->he_cap); + &pBeaconStruct->he_cap, NULL, + bssDescription); } pAddBssParams->maxTxPower = ft_session->maxTxPower; @@ -444,14 +336,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, pAddBssParams->staContext.rmfEnabled = 1; } #endif - - pAddBssParams->status = QDF_STATUS_SUCCESS; - pAddBssParams->respReqd = true; - pAddBssParams->staContext.sessionId = ft_session->peSessionId; pAddBssParams->staContext.smesessionId = ft_session->smeSessionId; - pAddBssParams->sessionId = ft_session->peSessionId; - pAddBssParams->bss_idx = ft_session->smeSessionId; /* Set a new state for MLME */ if (!lim_is_roam_synch_in_progress(ft_session)) { @@ -462,8 +348,6 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, ft_session->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE)); } - pAddBssParams->halPersona = (uint8_t)ft_session->opmode; - ft_session->ftPEContext.pAddBssReq = pAddBssParams; pe_debug("Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap"); @@ -474,12 +358,101 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, #endif #if defined(WLAN_FEATURE_ROAM_OFFLOAD) + +/** + * lim_convert_phymode_to_dot11mode() - get dot11 mode from phymode + * @phymode: phymode + * + * The function is to convert the phymode to corresponding dot11 mode + * + * Return: dot11mode. + */ +static uint8_t lim_convert_phymode_to_dot11mode(enum wlan_phymode phymode) +{ + + if (IS_WLAN_PHYMODE_HE(phymode)) + return MLME_DOT11_MODE_11AX; + + if (IS_WLAN_PHYMODE_VHT(phymode)) + return MLME_DOT11_MODE_11AC; + + if (IS_WLAN_PHYMODE_HT(phymode)) + return MLME_DOT11_MODE_11N; + + if (phymode == WLAN_PHYMODE_11G) + return MLME_DOT11_MODE_11G; + + if (phymode == WLAN_PHYMODE_11G_ONLY) + return MLME_DOT11_MODE_11G_ONLY; + + if (phymode == WLAN_PHYMODE_11A) + return MLME_DOT11_MODE_11A; + + if (phymode == WLAN_PHYMODE_11B) + return MLME_DOT11_MODE_11B; + + return MLME_DOT11_MODE_ALL; +} + +/** + * lim_calculate_dot11_mode() - calculate dot11 mode. + * @mac_context: mac context + * @bcn: beacon structure + * @band: reg_wifi_band + * + * The function is to calculate dot11 mode in case fw doen't send phy mode. + * + * Return: dot11mode. + */ +static uint8_t lim_calculate_dot11_mode(struct mac_context *mac_ctx, + tSchBeaconStruct *bcn, + enum reg_wifi_band band) +{ + enum mlme_dot11_mode self_dot11_mode; + enum mlme_dot11_mode new_dot11_mode; + + self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; + + if (band == REG_BAND_2G) + new_dot11_mode = MLME_DOT11_MODE_11G; + else + new_dot11_mode = MLME_DOT11_MODE_11A; + + switch (self_dot11_mode) { + case MLME_DOT11_MODE_11AX: + case MLME_DOT11_MODE_11AX_ONLY: + case MLME_DOT11_MODE_ALL: + if (bcn->he_cap.present) + return MLME_DOT11_MODE_11AX; + else if (bcn->VHTCaps.present || + bcn->vendor_vht_ie.present) + return MLME_DOT11_MODE_11AC; + else if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + case MLME_DOT11_MODE_11AC: + case MLME_DOT11_MODE_11AC_ONLY: + if (bcn->VHTCaps.present || + bcn->vendor_vht_ie.present) + return MLME_DOT11_MODE_11AC; + else if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + case MLME_DOT11_MODE_11N: + case MLME_DOT11_MODE_11N_ONLY: + if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + default: + return new_dot11_mode; + } + +} + /** * lim_fill_dot11mode() - to fill 802.11 mode in FT session * @mac_ctx: pointer to mac ctx * @ft_session: FT session * @pe_session: PE session * @bcn: AP beacon pointer + * @bss_phymode: bss phy mode * * This API fills FT session's dot11mode either from pe session or * from CFG depending on the condition. @@ -489,48 +462,24 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, static void lim_fill_dot11mode(struct mac_context *mac_ctx, struct pe_session *ft_session, struct pe_session *pe_session, - tSchBeaconStruct *bcn) + tSchBeaconStruct *bcn, + enum wlan_phymode bss_phymode) { - uint32_t self_dot11_mode; - if (pe_session->ftPEContext.pFTPreAuthReq && !csr_is_roam_offload_enabled(mac_ctx)) { ft_session->dot11mode = pe_session->ftPEContext.pFTPreAuthReq->dot11mode; return; } - self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; - pe_debug("selfDot11Mode: %d", self_dot11_mode); - if (ft_session->limRFBand == BAND_2G) - ft_session->dot11mode = MLME_DOT11_MODE_11G; - else - ft_session->dot11mode = MLME_DOT11_MODE_11A; - switch (self_dot11_mode) { - case MLME_DOT11_MODE_11AX: - case MLME_DOT11_MODE_11AX_ONLY: - if (bcn->he_cap.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AX; - else if (bcn->VHTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AC; - else if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - case MLME_DOT11_MODE_11AC: - case MLME_DOT11_MODE_11AC_ONLY: - if (bcn->VHTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AC; - else if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - case MLME_DOT11_MODE_11N: - case MLME_DOT11_MODE_11N_ONLY: - if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - default: - break; - } + if (bss_phymode == WLAN_PHYMODE_AUTO) + ft_session->dot11mode = lim_calculate_dot11_mode( + mac_ctx, bcn, + ft_session->limRFBand); + + else + ft_session->dot11mode = + lim_convert_phymode_to_dot11mode(bss_phymode); } #elif defined(WLAN_FEATURE_HOST_ROAM) /** @@ -539,6 +488,7 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, * @ft_session: FT session * @pe_session: PE session * @bcn: AP beacon pointer + * @bss_phymode: bss phy mode * * This API fills FT session's dot11mode either from pe session. * @@ -547,7 +497,8 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, static void lim_fill_dot11mode(struct mac_context *mac_ctx, struct pe_session *ft_session, struct pe_session *pe_session, - tSchBeaconStruct *bcn) + tSchBeaconStruct *bcn, + enum wlan_phymode bss_phymode) { ft_session->dot11mode = pe_session->ftPEContext.pFTPreAuthReq->dot11mode; @@ -563,9 +514,12 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, *------------------------------------------------------------------*/ void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, - struct pe_session *ft_session, struct pe_session *pe_session) + struct pe_session *ft_session, + struct pe_session *pe_session, + enum wlan_phymode bss_phymode) { uint8_t currentBssUapsd; + uint8_t bss_chan_id; int8_t localPowerConstraint; int8_t regMax; tSchBeaconStruct *pBeaconStruct; @@ -608,18 +562,21 @@ void lim_fill_ft_session(struct mac_context *mac, qdf_mem_copy(ft_session->ssId.ssId, pBeaconStruct->ssId.ssId, ft_session->ssId.length); /* Copy The channel Id to the session Table */ - ft_session->limReassocChannelId = pbssDescription->channelId; - ft_session->currentOperChannel = pbssDescription->channelId; + bss_chan_id = + wlan_reg_freq_to_chan(mac->pdev, pbssDescription->chan_freq); + ft_session->lim_reassoc_chan_freq = pbssDescription->chan_freq; + ft_session->curr_op_freq = pbssDescription->chan_freq; + ft_session->limRFBand = lim_get_rf_band(ft_session->curr_op_freq); - ft_session->limRFBand = lim_get_rf_band( - ft_session->currentOperChannel); - - lim_fill_dot11mode(mac, ft_session, pe_session, pBeaconStruct); - pe_debug("dot11mode: %d", ft_session->dot11mode); + lim_fill_dot11mode(mac, ft_session, pe_session, pBeaconStruct, + bss_phymode); + pe_debug("dot11mode: %d bss_phymode %d", ft_session->dot11mode, + bss_phymode); ft_session->vhtCapability = - (IS_DOT11_MODE_VHT(ft_session->dot11mode) - && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + (IS_DOT11_MODE_VHT(ft_session->dot11mode) && + (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || + IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps))); ft_session->htCapability = (IS_DOT11_MODE_HT(ft_session->dot11mode) && pBeaconStruct->HTCaps.present); @@ -629,14 +586,14 @@ void lim_fill_ft_session(struct mac_context *mac, lim_update_session_he_capable(mac, ft_session); /* Assign default configured nss value in the new session */ - if (IS_5G_CH(ft_session->currentOperChannel)) + if (wlan_reg_is_5ghz_ch_freq(ft_session->curr_op_freq)) ft_session->vdev_nss = mac->vdev_type_nss_5g.sta; else ft_session->vdev_nss = mac->vdev_type_nss_2g.sta; ft_session->nss = ft_session ->vdev_nss; - if (ft_session->limRFBand == BAND_2G) { + if (ft_session->limRFBand == REG_BAND_2G) { cbEnabledMode = mac->roam.configParam.channelBondingMode24GHz; } else { cbEnabledMode = mac->roam.configParam.channelBondingMode5GHz; @@ -651,9 +608,14 @@ void lim_fill_ft_session(struct mac_context *mac, pBeaconStruct->VHTOperation.present && ft_session->vhtCapability) { ft_session->vhtCapabilityPresentInBeacon = 1; + } else if (IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps) && + pBeaconStruct->vendor_vht_ie.VHTOperation.present && + ft_session->vhtCapability){ + ft_session->vhtCapabilityPresentInBeacon = 1; } else { ft_session->vhtCapabilityPresentInBeacon = 0; } + if (ft_session->htRecommendedTxWidthSet) { ft_session->ch_width = CH_WIDTH_40MHZ; if (ft_session->vhtCapabilityPresentInBeacon && @@ -661,20 +623,33 @@ void lim_fill_ft_session(struct mac_context *mac, ft_session->ch_width = pBeaconStruct->VHTOperation.chanWidth + 1; ft_session->ch_center_freq_seg0 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + pBeaconStruct->VHTOperation.chan_center_freq_seg0; + ft_session->ch_center_freq_seg1 = + pBeaconStruct->VHTOperation.chan_center_freq_seg1; + } else if (ft_session->vhtCapabilityPresentInBeacon && + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth){ + ft_session->ch_width = + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1; + ft_session->ch_center_freq_seg0 = + pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg0; ft_session->ch_center_freq_seg1 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg2; + pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg1; + } else { if (pBeaconStruct->HTInfo.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) ft_session->ch_center_freq_seg0 = - pbssDescription->channelId + 2; + bss_chan_id + 2; else if (pBeaconStruct->HTInfo.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) ft_session->ch_center_freq_seg0 = - pbssDescription->channelId - 2; - else + bss_chan_id - 2; + else { pe_warn("Invalid sec ch offset"); + ft_session->ch_width = CH_WIDTH_20MHZ; + ft_session->ch_center_freq_seg0 = 0; + ft_session->ch_center_freq_seg1 = 0; + } } } else { ft_session->ch_width = CH_WIDTH_20MHZ; @@ -711,11 +686,11 @@ void lim_fill_ft_session(struct mac_context *mac, ft_session->shortSlotTimeSupported = true; } - regMax = lim_get_regulatory_max_transmit_power(mac, - ft_session-> - currentOperChannel); + regMax = wlan_reg_get_channel_reg_power_for_freq( + mac->pdev, ft_session->curr_op_freq); localPowerConstraint = regMax; lim_extract_ap_capability(mac, (uint8_t *) pbssDescription->ieFields, + lim_get_ielen_from_bss_description(pbssDescription), &ft_session->limCurrentBssQosCaps, ¤tBssUapsd, @@ -739,9 +714,7 @@ void lim_fill_ft_session(struct mac_context *mac, tx_pwr_attr.reg_max = regMax; tx_pwr_attr.ap_tx_power = localPowerConstraint; tx_pwr_attr.ini_tx_power = mac->mlme_cfg->power.max_tx_power; - tx_pwr_attr.frequency = - wlan_reg_get_channel_freq(mac->pdev, - ft_session->currentOperChannel); + tx_pwr_attr.frequency = ft_session->curr_op_freq; #ifdef FEATURE_WLAN_ESE ft_session->maxTxPower = lim_get_max_tx_power(mac, &tx_pwr_attr); @@ -765,7 +738,7 @@ void lim_fill_ft_session(struct mac_context *mac, #ifdef WLAN_FEATURE_11W ft_session->limRmfEnabled = pe_session->limRmfEnabled; #endif - if ((ft_session->limRFBand == BAND_2G) && + if ((ft_session->limRFBand == REG_BAND_2G) && (ft_session->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ)) lim_init_obss_params(mac, ft_session); @@ -788,97 +761,6 @@ void lim_fill_ft_session(struct mac_context *mac, } #endif -/*------------------------------------------------------------------ - * - * This function is called to process the update key request from SME - * - *------------------------------------------------------------------*/ -bool lim_process_ft_update_key(struct mac_context *mac, uint32_t *msg_buf) -{ - tAddBssParams *pAddBssParams; - tSirFTUpdateKeyInfo *pKeyInfo; - struct pe_session *pe_session; - uint8_t sessionId; - - /* Sanity Check */ - if (!mac || !msg_buf) - return false; - - pKeyInfo = (tSirFTUpdateKeyInfo *)msg_buf; - - pe_session = pe_find_session_by_bssid(mac, pKeyInfo->bssid.bytes, - &sessionId); - if (!pe_session) { - pe_err("%s: Unable to find session for the following bssid", - __func__); - lim_print_mac_addr(mac, pKeyInfo->bssid.bytes, LOGE); - return false; - } - - /* Nothing to be done if the session is not in STA mode */ - if (!LIM_IS_STA_ROLE(pe_session)) { - pe_err("pe_session is not in STA mode"); - return false; - } - - if (!pe_session->ftPEContext.pAddBssReq) { - /* AddBss Req is NULL, save the keys to configure them later. */ - tpLimMlmSetKeysReq pMlmSetKeysReq = - &pe_session->ftPEContext.PreAuthKeyInfo. - extSetStaKeyParam; - - qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); - qdf_copy_macaddr(&pMlmSetKeysReq->peer_macaddr, - &pKeyInfo->bssid); - pMlmSetKeysReq->sessionId = pe_session->peSessionId; - pMlmSetKeysReq->smesessionId = pe_session->smeSessionId; - pMlmSetKeysReq->edType = pKeyInfo->keyMaterial.edType; - pMlmSetKeysReq->numKeys = pKeyInfo->keyMaterial.numKeys; - qdf_mem_copy((uint8_t *) &pMlmSetKeysReq->key, - (uint8_t *) &pKeyInfo->keyMaterial.key, - sizeof(tSirKeys)); - - pe_session->ftPEContext.PreAuthKeyInfo. - extSetStaKeyParamValid = true; - - if (!pe_session->ftPEContext.pAddStaReq) { - pe_err("pAddStaReq is NULL"); - lim_send_set_sta_key_req(mac, pMlmSetKeysReq, 0, 0, - pe_session, false); - pe_session->ftPEContext.PreAuthKeyInfo. - extSetStaKeyParamValid = false; - } - } else { - pAddBssParams = pe_session->ftPEContext.pAddBssReq; - - /* Store the key information in the ADD BSS parameters */ - pAddBssParams->extSetStaKeyParamValid = 1; - pAddBssParams->extSetStaKeyParam.encType = - pKeyInfo->keyMaterial.edType; - qdf_mem_copy((uint8_t *) &pAddBssParams->extSetStaKeyParam.key, - (uint8_t *) &pKeyInfo->keyMaterial.key, - sizeof(tSirKeys)); - - pAddBssParams->extSetStaKeyParam.singleTidRc = - (uint8_t)mac->mlme_cfg->sta.single_tid; - pe_debug("Key valid: %d keyLength: %d", - pAddBssParams->extSetStaKeyParamValid, - pAddBssParams->extSetStaKeyParam.key[0].keyLength); - - pAddBssParams->extSetStaKeyParam.staIdx = 0; - - pe_debug("BSSID: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pKeyInfo->bssid.bytes)); - - qdf_copy_macaddr(&pAddBssParams->extSetStaKeyParam.peer_macaddr, - &pKeyInfo->bssid); - - pAddBssParams->extSetStaKeyParam.sendRsp = false; - - } - return true; -} - static void lim_ft_send_aggr_qos_rsp(struct mac_context *mac, uint8_t rspReqd, struct aggr_add_ts_param *aggrQosRsp, @@ -949,18 +831,20 @@ void lim_process_ft_aggr_qos_rsp(struct mac_context *mac, if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) && (pAggrQosRspMsg->status[i] != QDF_STATUS_SUCCESS)) { sir_copy_mac_addr(peerMacAddr, pe_session->bssId); - addTsParam.sta_idx = pAggrQosRspMsg->staIdx; addTsParam.pe_session_id = pAggrQosRspMsg->sessionId; addTsParam.tspec = pAggrQosRspMsg->tspec[i]; addTsParam.tspec_idx = pAggrQosRspMsg->tspecIdx; - lim_send_delts_req_action_frame(mac, peerMacAddr, rspReqd, + lim_send_delts_req_action_frame(mac, peerMacAddr, + rspReqd, &addTsParam.tspec.tsinfo, &addTsParam.tspec, pe_session); pSta = - dph_lookup_assoc_id(mac, addTsParam.sta_idx, - &assocId, - &pe_session->dph.dphHashTable); + dph_lookup_hash_entry(mac, peerMacAddr, + &assocId, + &pe_session-> + dph.dphHashTable); + if (pSta) { lim_admit_control_delete_ts(mac, assocId, &addTsParam.tspec. @@ -1021,7 +905,6 @@ QDF_STATUS lim_process_ft_aggr_qos_req(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } - pAggrAddTsParam->staIdx = pe_session->staId; /* Fill in the sessionId specific to PE */ pAggrAddTsParam->sessionId = sessionId; pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx; @@ -1090,7 +973,7 @@ QDF_STATUS lim_process_ft_aggr_qos_req(struct mac_context *mac, lim_send_edca_params(mac, pe_session->gLimEdcaParamsActive, - pSta->bssId, false); + pe_session->vdev_id, false); if (QDF_STATUS_SUCCESS != lim_tspec_add(mac, pSta->staAddr, pSta->assocId, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft_preauth.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft_preauth.c index 3c31b357691c46ddda925d54f9dd08bf8e122c1c..0a77b623dd9ff2d667297ee38d6a7913820b6f7e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft_preauth.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ft_preauth.c @@ -142,8 +142,8 @@ int lim_process_ft_pre_auth_req(struct mac_context *mac_ctx, &session_id); if (!session) { pe_err("Unable to find session for the bssid" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(ft_pre_auth_req->currbssId)); /* Post the FT Pre Auth Response to SME */ lim_post_ft_pre_auth_rsp(mac_ctx, QDF_STATUS_E_FAILURE, NULL, 0, session); @@ -190,8 +190,8 @@ int lim_process_ft_pre_auth_req(struct mac_context *mac_ctx, * Dont need to suspend if APs are in same channel and DUT * is not in MCC state */ - if ((session->currentOperChannel != - session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) + if ((session->curr_op_freq != + session->ftPEContext.pFTPreAuthReq->pre_auth_channel_freq) || lim_is_in_mcc(mac_ctx)) { /* Need to suspend link only if the channels are different */ pe_debug("Performing pre-auth on diff channel(session %pK)", @@ -273,14 +273,14 @@ void lim_perform_ft_pre_auth(struct mac_context *mac, QDF_STATUS status, authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; authFrame.authStatusCode = 0; - mac->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId = + mac->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId = pe_session->peSessionId; /* Start timer here to come back to operating channel */ - mac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = + mac->lim.lim_timers.gLimFTPreAuthRspTimer.sessionId = pe_session->peSessionId; if (TX_SUCCESS != - tx_timer_activate(&mac->lim.limTimers.gLimFTPreAuthRspTimer)) { + tx_timer_activate(&mac->lim.lim_timers.gLimFTPreAuthRspTimer)) { pe_err("FT Auth Rsp Timer Start Failed"); goto preauth_fail; } @@ -318,6 +318,7 @@ QDF_STATUS lim_ft_setup_auth_session(struct mac_context *mac, { struct pe_session *ft_session = NULL; uint8_t sessionId = 0; + struct sSirFTPreAuthReq *req; ft_session = pe_find_session_by_bssid(mac, pe_session->limReAssocbssId, @@ -334,15 +335,13 @@ QDF_STATUS lim_ft_setup_auth_session(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } - if (pe_session->ftPEContext.pFTPreAuthReq && - pe_session->ftPEContext.pFTPreAuthReq->pbssDescription) { + req = pe_session->ftPEContext.pFTPreAuthReq; + if (req && req->pbssDescription) { lim_fill_ft_session(mac, - pe_session->ftPEContext.pFTPreAuthReq-> - pbssDescription, ft_session, - pe_session); - - lim_ft_prepare_add_bss_req(mac, false, ft_session, - pe_session->ftPEContext.pFTPreAuthReq->pbssDescription); + req->pbssDescription, ft_session, + pe_session, WLAN_PHYMODE_AUTO); + lim_ft_prepare_add_bss_req(mac, ft_session, + req->pbssDescription); } return QDF_STATUS_SUCCESS; @@ -470,11 +469,11 @@ void lim_handle_ft_pre_auth_rsp(struct mac_context *mac, QDF_STATUS status, ft_session->ht_config = pe_session->ht_config; ft_session->limSmeState = eLIM_SME_WT_REASSOC_STATE; - if (IS_5G_CH(pe_session->ftPEContext.pFTPreAuthReq-> - preAuthchannelNum)) - ft_session->vdev_nss = mac->vdev_type_nss_5g.sta; - else + if (wlan_reg_is_24ghz_ch_freq(pe_session->ftPEContext. + pFTPreAuthReq->pre_auth_channel_freq)) ft_session->vdev_nss = mac->vdev_type_nss_2g.sta; + else + ft_session->vdev_nss = mac->vdev_type_nss_5g.sta; pe_debug("created session (%pK) with id = %d", ft_session, ft_session->peSessionId); @@ -485,18 +484,17 @@ void lim_handle_ft_pre_auth_rsp(struct mac_context *mac, QDF_STATUS status, lim_print_mac_addr(mac, pe_session->limReAssocbssId, LOGD); } send_rsp: - if ((pe_session->currentOperChannel != - pe_session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) || + if ((pe_session->curr_op_freq != + pe_session->ftPEContext.pFTPreAuthReq->pre_auth_channel_freq) || lim_is_in_mcc(mac)) { /* Need to move to the original AP channel */ lim_process_abort_scan_ind(mac, pe_session->smeSessionId, pe_session->ftPEContext.pFTPreAuthReq->scan_id, mac->lim.req_id | PREAUTH_REQUESTOR_ID); } else { - pe_debug("Pre auth on same channel as connected AP channel %d\ - and no mcc pe sessions exist", - pe_session->ftPEContext.pFTPreAuthReq-> - preAuthchannelNum); + pe_debug("Pre auth on same freq as connected AP freq %d and no mcc pe sessions exist", + pe_session->ftPEContext.pFTPreAuthReq-> + pre_auth_channel_freq); lim_ft_process_pre_auth_result(mac, pe_session); } } @@ -521,7 +519,7 @@ void lim_process_ft_preauth_rsp_timeout(struct mac_context *mac_ctx) */ pe_err("FT Pre-Auth Time Out!!!!"); session = pe_find_session_by_session_id(mac_ctx, - mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); + mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer.sessionId); if (!session) { pe_err("Session Does not exist for given sessionID"); return; @@ -539,7 +537,7 @@ void lim_process_ft_preauth_rsp_timeout(struct mac_context *mac_ctx) if (!session->ftPEContext.pFTPreAuthReq) { /* Auth Rsp might already be posted to SME and ftcleanup done */ pe_err("pFTPreAuthReq is NULL sessionId: %d", - mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); + mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer.sessionId); return; } @@ -610,7 +608,7 @@ void lim_post_ft_pre_auth_rsp(struct mac_context *mac_ctx, qdf_mem_free(ft_pre_auth_rsp); return; } - ft_pre_auth_rsp->smeSessionId = session->smeSessionId; + ft_pre_auth_rsp->vdev_id = session->vdev_id; /* The bssid of the AP we are sending Auth1 to. */ if (session->ftPEContext.pFTPreAuthReq) sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId, @@ -720,7 +718,7 @@ QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, req->scan_req.chan_list.num_chan = 1; req->scan_req.chan_list.chan[0].freq = - cds_chan_to_freq(ft_preauth_req->preAuthchannelNum); + ft_preauth_req->pre_auth_channel_freq; req->scan_req.dwell_time_active = LIM_FT_PREAUTH_SCAN_TIME; req->scan_req.dwell_time_passive = LIM_FT_PREAUTH_SCAN_TIME; @@ -734,25 +732,9 @@ QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, return status; } -/** - * lim_preauth_scan_event_handler() - Process firmware preauth scan events - * - * @mac_ctx:Pointer to global MAC structure - * @event: Scan event - * @session_id: session entry - * @scan_id: scan id from WMA scan event. - * - * If scan event signifies failure or successful completion, operation - * is complete. - * If scan event signifies that STA is on foreign channel, send auth frame - * - * Return: void - */ - void lim_preauth_scan_event_handler(struct mac_context *mac_ctx, - enum sir_scan_event_type event, - uint8_t session_id, - uint32_t scan_id) + enum sir_scan_event_type event, + uint8_t vdev_id, uint32_t scan_id) { struct pe_session *session_entry; @@ -769,14 +751,12 @@ void lim_preauth_scan_event_handler(struct mac_context *mac_ctx, /* For the first pre-auth request * need to get it by sme session id (vdev id) */ - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - session_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); } if (!session_entry) { - pe_err("SmeSessionId:%d PeSessionId:%d does not exist", - session_id, - mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); + pe_err("vdev_id :%d PeSessionId:%d does not exist", vdev_id, + mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer.sessionId); return; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c index 680c6651e64d7a39cd8be40c8c5b68692beb3126..46bb6ca3fc0ddb08a495d25c86992c8515ac96b2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c @@ -22,7 +22,6 @@ #include "wni_cfg.h" #include "lim_utils.h" #include "lim_assoc_utils.h" -#include "lim_sta_hash_api.h" #include "sch_api.h" /* sch_set_fixed_beacon_fields for IBSS coalesce */ #include "lim_security_utils.h" #include "lim_send_messages.h" @@ -460,7 +459,7 @@ ibss_dph_entry_add(struct mac_context *mac, /* send a status change notification */ static void ibss_status_chg_notify(struct mac_context *mac, tSirMacAddr peerAddr, - uint16_t staIndex, uint16_t status, uint8_t sessionId) + uint16_t status, uint8_t sessionId) { tLimIbssPeerNode *peerNode; @@ -477,7 +476,7 @@ ibss_status_chg_notify(struct mac_context *mac, tSirMacAddr peerAddr, peerNode->beaconLen = 0; } - lim_send_sme_ibss_peer_ind(mac, peerAddr, staIndex, + lim_send_sme_ibss_peer_ind(mac, peerAddr, beacon, bcnLen, status, sessionId); if (beacon) { @@ -568,7 +567,7 @@ void ibss_bss_add(struct mac_context *mac, struct pe_session *pe_session) mlmStartReq.txChannelWidthSet = pe_session->htRecommendedTxWidthSet; /* reading the channel num from session Table */ - mlmStartReq.channelNumber = pe_session->currentOperChannel; + mlmStartReq.oper_ch_freq = pe_session->curr_op_freq; mlmStartReq.cbMode = pe_session->pLimStartBssReq->cbMode; @@ -602,9 +601,9 @@ void ibss_bss_delete(struct mac_context *mac_ctx, struct pe_session *session) session->limMlmState); return; } - status = lim_del_bss(mac_ctx, NULL, session->bss_idx, session); + status = lim_del_bss(mac_ctx, NULL, session->vdev_id, session); if (QDF_IS_STATUS_ERROR(status)) - pe_err("delBss failed for bss: %d", session->bss_idx); + pe_err("delBss failed for bss: %d", session->vdev_id); } /** @@ -673,7 +672,6 @@ void lim_ibss_delete_all_peers(struct mac_context *mac, if (sta) { ibss_status_chg_notify(mac, pCurrNode->peerMacAddr, - sta->staIndex, eWNI_SME_IBSS_PEER_DEPARTED_IND, pe_session->smeSessionId); lim_del_sta(mac, sta, false, pe_session); @@ -826,7 +824,7 @@ lim_ibss_decide_protection(struct mac_context *mac, tpDphHashNode sta, tpUpdateBeaconParams pBeaconParams, struct pe_session *pe_session) { - enum band_info rfBand = BAND_UNKNOWN; + enum reg_wifi_band rfBand = REG_BAND_UNKNOWN; uint32_t phyMode; tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; @@ -839,7 +837,7 @@ lim_ibss_decide_protection(struct mac_context *mac, tpDphHashNode sta, } lim_get_rf_band_new(mac, &rfBand, pe_session); - if (BAND_2G == rfBand) { + if (REG_BAND_2G == rfBand) { lim_get_phy_mode(mac, &phyMode, pe_session); /* We are 11G or 11n. Check if we need protection from 11b Stations. */ @@ -864,52 +862,11 @@ lim_ibss_decide_protection(struct mac_context *mac, tpDphHashNode sta, return; } -/** - * lim_ibss_peer_find() - * - ***FUNCTION: - * This function is called while adding a context at - * DPH & Polaris for a peer in IBSS. - * If peer is found in the list, capabilities from the - * returned BSS description are used at DPH node & Polaris. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * - ***NOTE: - * - * @param macAddr - MAC address of the peer - * - * @return Pointer to peer node if found, else NULL - */ tLimIbssPeerNode *lim_ibss_peer_find(struct mac_context *mac, tSirMacAddr macAddr) { return ibss_peer_find(mac, macAddr); } -/** - * lim_ibss_sta_add() - * - ***FUNCTION: - * This function is called to add an STA context in IBSS role - * whenever a data frame is received from/for a STA that failed - * hash lookup at DPH. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac Pointer to Global MAC structure - * @param peerAdddr MAC address of the peer being added - * @return retCode Indicates success or failure return code - * @return - */ - QDF_STATUS lim_ibss_sta_add(struct mac_context *mac, void *pBody, struct pe_session *pe_session) { @@ -965,7 +922,7 @@ lim_ibss_sta_add(struct mac_context *mac, void *pBody, struct pe_session *pe_ses sch_set_fixed_beacon_fields(mac, pe_session); beaconParams.bss_idx = - pe_session->bss_idx; + pe_session->vdev_id; lim_send_beacon_params(mac, &beaconParams, pe_session); } @@ -1004,8 +961,8 @@ lim_ibss_search_and_delete_peer(struct mac_context *mac_ctx, prev_node = temp_node = mac_ctx->lim.gLimIbssPeerList; - pe_debug(" PEER ADDR :" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_addr)); + pe_debug(" PEER ADDR :" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr)); /** Compare Peer */ while (temp_node) { @@ -1051,6 +1008,7 @@ lim_ibss_search_and_delete_peer(struct mac_context *mac_ctx, * @mac_ptr: Pointer to Global MAC structure * @session_entry: Session entry * @mac_addr: Mac Address of the IBSS peer + * @del_sta: del sta sent to firmware if true * * This function is called delete IBSS peer. * @@ -1059,13 +1017,14 @@ lim_ibss_search_and_delete_peer(struct mac_context *mac_ctx, */ static void lim_ibss_delete_peer(struct mac_context *mac_ctx, - struct pe_session *session_entry, tSirMacAddr mac_addr) + struct pe_session *session_entry, tSirMacAddr mac_addr, + bool del_sta) { tpDphHashNode sta = NULL; uint16_t peer_idx = 0; - pe_debug("Delete peer :" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_addr)); + pe_debug("Delete peer :" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr)); sta = dph_lookup_hash_entry(mac_ctx, mac_addr, &peer_idx, @@ -1073,12 +1032,12 @@ lim_ibss_delete_peer(struct mac_context *mac_ctx, dphHashTable); if (!sta) { - pe_err("DPH Entry for STA %pM is missing", - mac_addr); + pe_err("DPH Entry for STA "QDF_MAC_ADDR_FMT" is missing", + QDF_MAC_ADDR_REF(mac_addr)); return; } - if (STA_INVALID_IDX != sta->staIndex) { + if (del_sta) { lim_del_sta(mac_ctx, sta, true, session_entry); } else { @@ -1129,9 +1088,9 @@ void lim_process_ibss_del_sta_rsp(struct mac_context *mac_ctx, status = eSIR_SME_REFUSED; goto skip_event; } - pe_debug("Deleted STA associd %d staId %d MAC " QDF_MAC_ADDR_STR, - sta_ds->assocId, sta_ds->staIndex, - QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); + pe_debug("Deleted STA associd %d MAC " QDF_MAC_ADDR_FMT, + sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, del_sta_params->assocId, pe_session); @@ -1140,7 +1099,6 @@ void lim_process_ibss_del_sta_rsp(struct mac_context *mac_ctx, ibss_status_chg_notify(mac_ctx, del_sta_params->staMac, - sta_ds->staIndex, eWNI_SME_IBSS_PEER_DEPARTED_IND, pe_session->smeSessionId); @@ -1170,31 +1128,28 @@ lim_ibss_add_sta_rsp(struct mac_context *mac, void *msg, struct pe_session *pe_s dph_lookup_hash_entry(mac, pAddStaParams->staMac, &peerIdx, &pe_session->dph.dphHashTable); if (!sta) { - pe_err("IBSS: ADD_STA_RSP for unknown MAC addr: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pAddStaParams->staMac)); + pe_err("IBSS: ADD_STA_RSP for unknown MAC addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pAddStaParams->staMac)); qdf_mem_free(pAddStaParams); return QDF_STATUS_E_FAILURE; } if (pAddStaParams->status != QDF_STATUS_SUCCESS) { - pe_err("IBSS: ADD_STA_RSP error: %x for MAC:"QDF_MAC_ADDR_STR, + pe_err("IBSS: ADD_STA_RSP error: %x for MAC:"QDF_MAC_ADDR_FMT, pAddStaParams->status, - QDF_MAC_ADDR_ARRAY(pAddStaParams->staMac)); + QDF_MAC_ADDR_REF(pAddStaParams->staMac)); lim_ibss_delete_peer(mac, - pe_session, pAddStaParams->staMac); + pe_session, pAddStaParams->staMac, false); qdf_mem_free(pAddStaParams); return QDF_STATUS_E_FAILURE; } - sta->bssId = pAddStaParams->bss_idx; - sta->staIndex = pAddStaParams->staIdx; sta->valid = 1; sta->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; pe_debug("IBSS: sending IBSS_NEW_PEER msg to SME!"); ibss_status_chg_notify(mac, pAddStaParams->staMac, - sta->staIndex, eWNI_SME_IBSS_NEW_PEER_IND, pe_session->smeSessionId); @@ -1203,38 +1158,34 @@ lim_ibss_add_sta_rsp(struct mac_context *mac, void *msg, struct pe_session *pe_s return QDF_STATUS_SUCCESS; } -void lim_ibss_del_bss_rsp_when_coalescing(struct mac_context *mac, void *msg, +void lim_ibss_del_bss_rsp_when_coalescing(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, struct pe_session *pe_session) { - tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; - pe_debug("IBSS: DEL_BSS_RSP Rcvd during coalescing!"); - if (!pDelBss) { + if (!vdev_stop_rsp) { pe_err("IBSS: DEL_BSS_RSP(coalesce) with no body!"); - goto end; + return; } - if (pDelBss->status != QDF_STATUS_SUCCESS) { - pe_err("IBSS: DEL_BSS_RSP(coalesce) error: %x Bss: %d", - pDelBss->status, pDelBss->bss_idx); - goto end; + if (vdev_stop_rsp->status != QDF_STATUS_SUCCESS) { + pe_err("IBSS: DEL_BSS_RSP(coalesce) error: %x", + vdev_stop_rsp->status); + return; } /* Delete peer entries. */ /* add the new bss */ ibss_bss_add(mac, pe_session); -end: - if (pDelBss) - qdf_mem_free(pDelBss); } -void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, void *msg, +void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, + uint32_t op_chan_freq, struct pe_session *pe_session) { uint8_t infoLen; struct new_bss_info newBssInfo; - tpAddBssParams pAddBss = msg; tpSirMacMgmtHdr pHdr = mac->lim.ibss_info.mac_hdr; tpSchBeaconStruct pBeacon = mac->lim.ibss_info.beacon; @@ -1248,7 +1199,7 @@ void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, void *msg, qdf_mem_zero((void *)&newBssInfo, sizeof(newBssInfo)); qdf_mem_copy(newBssInfo.bssId.bytes, pHdr->bssId, QDF_MAC_ADDR_SIZE); - newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel; + newBssInfo.freq = op_chan_freq; qdf_mem_copy((uint8_t *) &newBssInfo.ssId, (uint8_t *) &pBeacon->ssId, pBeacon->ssId.length + 1); @@ -1266,20 +1217,20 @@ void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, void *msg, ibss_coalesce_free(mac); } -void lim_ibss_del_bss_rsp(struct mac_context *mac, void *msg, struct pe_session *pe_session) +void lim_ibss_del_bss_rsp(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session) { tSirResultCodes rc = eSIR_SME_SUCCESS; - tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; - tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; SET_LIM_PROCESS_DEFD_MESGS(mac, true); - if (!pDelBss) { + if (!vdev_stop_rsp) { pe_err("IBSS: DEL_BSS_RSP with no body!"); rc = eSIR_SME_REFUSED; goto end; } - pe_session = pe_find_session_by_session_id(mac, pDelBss->sessionId); + pe_session = pe_find_session_by_vdev_id(mac, vdev_stop_rsp->vdev_id); if (!pe_session) { pe_err("Session Does not exist for given sessionID"); goto end; @@ -1292,26 +1243,17 @@ void lim_ibss_del_bss_rsp(struct mac_context *mac, void *msg, struct pe_session * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME. */ if (true == mac->lim.gLimIbssCoalescingHappened) { - - lim_ibss_del_bss_rsp_when_coalescing(mac, msg, pe_session); + lim_ibss_del_bss_rsp_when_coalescing(mac, vdev_stop_rsp, + pe_session); return; } - if (pDelBss->status != QDF_STATUS_SUCCESS) { - pe_err("IBSS: DEL_BSS_RSP error: %x Bss: %d", - pDelBss->status, pDelBss->bss_idx); + if (vdev_stop_rsp->status != QDF_STATUS_SUCCESS) { + pe_err("IBSS: DEL_BSS_RSP error: %x", vdev_stop_rsp->status); rc = eSIR_SME_STOP_BSS_FAILURE; goto end; } - if (lim_set_link_state(mac, eSIR_LINK_IDLE_STATE, nullBssid, - pe_session->self_mac_addr, NULL, - NULL) != QDF_STATUS_SUCCESS) { - pe_err("IBSS: DEL_BSS_RSP setLinkState failed"); - rc = eSIR_SME_REFUSED; - goto end; - } - lim_ibss_delete(mac, pe_session); dph_hash_table_init(mac, &pe_session->dph.dphHashTable); @@ -1332,8 +1274,6 @@ void lim_ibss_del_bss_rsp(struct mac_context *mac, void *msg, struct pe_session cfg_default(CFG_SHORT_SLOT_TIME_ENABLED); end: - if (pDelBss) - qdf_mem_free(pDelBss); /* Delete PE session once BSS is deleted */ if (pe_session) { lim_send_sme_rsp(mac, eWNI_SME_STOP_BSS_RSP, rc, @@ -1357,26 +1297,6 @@ static void lim_ibss_bss_delete(struct mac_context *mac, pe_err("Deliver WLAN_VDEV_SM_EV_DOWN failed"); } -/** - * lim_ibss_coalesce() - * - ***FUNCTION: - * This function is called upon receiving Beacon/Probe Response - * while operating in IBSS mode. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * - ***NOTE: - * - * @param mac - Pointer to Global MAC structure - * @param pBeacon - Parsed Beacon Frame structure - * @param pBD - Pointer to received BD - * - * @return Status whether to process or ignore received Beacon Frame - */ - QDF_STATUS lim_ibss_coalesce(struct mac_context *mac, tpSirMacMgmtHdr pHdr, @@ -1394,9 +1314,9 @@ lim_ibss_coalesce(struct mac_context *mac, sir_copy_mac_addr(currentBssId, pe_session->bssId); - pe_debug("Current BSSID :" QDF_MAC_ADDR_STR " Received BSSID :" - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(currentBssId), - QDF_MAC_ADDR_ARRAY(pHdr->bssId)); + pe_debug("Current BSSID :" QDF_MAC_ADDR_FMT " Received BSSID :" + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(currentBssId), + QDF_MAC_ADDR_REF(pHdr->bssId)); /* Check for IBSS Coalescing only if Beacon is from different BSS */ if (qdf_mem_cmp(currentBssId, pHdr->bssId, sizeof(tSirMacAddr)) @@ -1414,7 +1334,7 @@ lim_ibss_coalesce(struct mac_context *mac, pPeerNode = ibss_peer_find(mac, pHdr->sa); if (pPeerNode) { lim_ibss_delete_peer(mac, pe_session, - pHdr->sa); + pHdr->sa, true); pe_warn("Peer attempting to reconnect before HB timeout, deleted"); return QDF_STATUS_E_INVAL; } @@ -1430,8 +1350,8 @@ lim_ibss_coalesce(struct mac_context *mac, */ mac->lim.gLimIbssCoalescingHappened = true; ibss_coalesce_save(mac, pHdr, pBeacon); - pe_debug("IBSS Coalescing happened Delete BSSID :" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(currentBssId)); + pe_debug("IBSS Coalescing happened Delete BSSID :" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(currentBssId)); lim_ibss_bss_delete(mac, pe_session); return QDF_STATUS_SUCCESS; @@ -1514,7 +1434,7 @@ lim_ibss_coalesce(struct mac_context *mac, if (beaconParams.paramChangeBitmap) { pe_err("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params"); sch_set_fixed_beacon_fields(mac, pe_session); - beaconParams.bss_idx = pe_session->bss_idx; + beaconParams.bss_idx = pe_session->vdev_id; lim_send_beacon_params(mac, &beaconParams, pe_session); } } else @@ -1537,16 +1457,6 @@ lim_ibss_coalesce(struct mac_context *mac, return QDF_STATUS_SUCCESS; } /*** end lim_handle_ibs_scoalescing() ***/ -/** - * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure - * - * @mac_ctx: global mac context - * @session: PE session entry - * - * Hanlde IBSS hearbeat failure. - * - * Return: None. - */ void lim_ibss_heart_beat_handle(struct mac_context *mac_ctx, struct pe_session *session) { tLimIbssPeerNode *tempnode, *prevnode; @@ -1554,7 +1464,6 @@ void lim_ibss_heart_beat_handle(struct mac_context *mac_ctx, struct pe_session * uint16_t peer_idx = 0; tpDphHashNode stads = 0; uint32_t threshold = 0; - uint16_t sta_idx = 0; /* * MLM BSS is started and if PE in scanmode then MLM state will be @@ -1593,8 +1502,6 @@ void lim_ibss_heart_beat_handle(struct mac_context *mac_ctx, struct pe_session * tempnode->peerMacAddr, &peer_idx, &session->dph.dphHashTable); if (stads) { - sta_idx = stads->staIndex; - (void)lim_del_sta(mac_ctx, stads, false, session); lim_delete_dph_hash_entry(mac_ctx, @@ -1603,7 +1510,7 @@ void lim_ibss_heart_beat_handle(struct mac_context *mac_ctx, struct pe_session * session); /* Send indication. */ ibss_status_chg_notify(mac_ctx, - tempnode->peerMacAddr, sta_idx, + tempnode->peerMacAddr, eWNI_SME_IBSS_PEER_DEPARTED_IND, session->smeSessionId); } @@ -1662,18 +1569,6 @@ void lim_ibss_heart_beat_handle(struct mac_context *mac_ctx, struct pe_session * } } -/** - * lim_ibss_decide_protection_on_delete() - decides protection related info. - * - * @mac_ctx: global mac context - * @stads: station hash node - * @bcn_param: beacon parameters - * @session: PE session entry - * - * Decides all the protection related information. - * - * Return: None - */ void lim_ibss_decide_protection_on_delete(struct mac_context *mac_ctx, tpDphHashNode stads, tpUpdateBeaconParams bcn_param, @@ -1681,14 +1576,14 @@ void lim_ibss_decide_protection_on_delete(struct mac_context *mac_ctx, { uint32_t phymode; tHalBitVal erpenabled = eHAL_CLEAR; - enum band_info rfband = BAND_UNKNOWN; + enum reg_wifi_band rfband = REG_BAND_UNKNOWN; uint32_t i; if (!stads) return; lim_get_rf_band_new(mac_ctx, &rfband, session); - if (BAND_2G != rfband) + if (REG_BAND_2G != rfband) return; lim_get_phy_mode(mac_ctx, &phymode, session); @@ -1739,7 +1634,7 @@ __lim_ibss_peer_inactivity_handler(struct mac_context *mac, } /* delete the peer for which heartbeat is observed */ - lim_ibss_delete_peer(mac, pe_session, ind->peer_addr.bytes); + lim_ibss_delete_peer(mac, pe_session, ind->peer_addr.bytes, true); } /** ------------------------------------------------------------- diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h index d3f9241094fc228c5d33c73e21453b2a4146b6fc..ec092b2c40b479b47da74f967df891df99610815 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h @@ -30,8 +30,9 @@ #include "sir_common.h" #include "lim_utils.h" +#ifdef QCA_IBSS_SUPPORT /** - * ibss_bss_delete()- start the ibss + * ibss_bss_add()- add the ibss * @mac_ctx: Pointer to Global MAC structure * @session: pe session * @@ -49,7 +50,7 @@ void ibss_bss_add(struct mac_context *mac_ctx, struct pe_session *session); void ibss_bss_delete(struct mac_context *mac_ctx, struct pe_session *session); /** - * lim_ibss_delete_all_peers: delete all IBSS peers. + * lim_ibss_delete_all_peers() - delete all IBSS peers. * @mac_ctx: Pointer to Global MAC structure * @session: pe session * @@ -57,6 +58,12 @@ void ibss_bss_delete(struct mac_context *mac_ctx, struct pe_session *session); */ void lim_ibss_delete_all_peers(struct mac_context *mac_ctx, struct pe_session *session); +/** + * lim_ibss_init() - API to init IBSS + * @mac_ctx: Pointer to Global MAC structure + * + * Return: None + */ void lim_ibss_init(struct mac_context *); /** @@ -69,16 +76,50 @@ void lim_ibss_init(struct mac_context *); */ void lim_ibss_delete(struct mac_context *, struct pe_session *pe_session); +/** + * lim_ibss_coalesce() - API to process IBSS Beacon/Probe Response + * @param mac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + * @return Status whether to process or ignore received Beacon Frame + */ QDF_STATUS lim_ibss_coalesce(struct mac_context *, tpSirMacMgmtHdr, tpSchBeaconStruct, uint8_t *, uint32_t, uint16_t, struct pe_session *); + +/** + * lim_ibss_sta_add() - API to add an STA context in IBSS role + * @param mac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * + * This function is called to add an STA context in IBSS role + * whenever a data frame is received from/for a STA that failed + * hash lookup at DPH. + * + * @return retCode Indicates success or failure return code + */ QDF_STATUS lim_ibss_sta_add(struct mac_context *, void *, struct pe_session *); + +/** + * lim_ibss_add_sta_rsp() - API to process STA add response in IBSS role + * @param mac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * + * This function is called to add an STA context in IBSS role + * whenever a data frame is received from/for a STA that failed + * hash lookup at DPH. + * + * @return retCode Indicates success or failure return code + */ QDF_STATUS lim_ibss_add_sta_rsp(struct mac_context *, void *, struct pe_session *); /** * lim_process_ibss_del_sta_rsp()- Handle ibss delete * peer resp from firmware - * * @mac_ptr: Pointer to Global MAC structure * @lim_msg: delete sta response * @pe_session: pe session @@ -89,13 +130,342 @@ QDF_STATUS lim_ibss_add_sta_rsp(struct mac_context *, void *, struct pe_session void lim_process_ibss_del_sta_rsp(struct mac_context *mac_ctx, struct scheduler_msg *lim_msg, struct pe_session *pe_session); + +/** + * lim_ibss_peer_find() - API to find IBSS peer + * @mac: pointer to mac context + * @param macAddr - MAC address of the peer + * + * This function is called while adding a context at + * DPH & Polaris for a peer in IBSS. + * If peer is found in the list, capabilities from the + * returned BSS description are used at DPH node & Polaris. + * + * @return Pointer to peer node if found, else NULL + */ tLimIbssPeerNode *lim_ibss_peer_find(struct mac_context *mac, tSirMacAddr macAddr); -void lim_ibss_del_bss_rsp(struct mac_context *, void *, struct pe_session *); -void lim_ibss_del_bss_rsp_when_coalescing(struct mac_context *, void *, struct pe_session *); -void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, void *msg, + +/** + * lim_ibss_del_bss_rsp() - Handle ibss delete + * response + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to del bss response + * @pe_session: pointer to pe session + * + * Return: None + * + */ +void lim_ibss_del_bss_rsp(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session); + +/** + * lim_ibss_del_bss_rsp_when_coalescing() - Handle ibss delete + * response when coalescing + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to del bss response + * @pe_session: pointer to pe session + * + * Return: None + * + */ +void lim_ibss_del_bss_rsp_when_coalescing(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session); + +/** + * lim_ibss_add_bss_rsp_when_coalescing()- Handle ADD BSS rsp of IBSS coalescing + * @mac_ptr: Pointer to Global MAC structure + * @op_chan_freq: operating chan freq + * @pe_session: PE session pointer + * + * Return: None + */ +void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, + uint32_t op_chan_freq, struct pe_session *pe_session); + +/** + * lim_ibss_decide_protection_on_delete() - decides protection related info. + * @mac_ctx: global mac context + * @stads: station hash node + * @bcn_param: beacon parameters + * @session: PE session entry + * + * Decides all the protection related information. + * + * Return: None + */ void lim_ibss_decide_protection_on_delete(struct mac_context *mac, tpDphHashNode sta, tpUpdateBeaconParams pBeaconParams, struct pe_session *pe_session); + +/** + * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure + * @mac_ctx: global mac context + * @session: PE session entry + * + * Hanlde IBSS hearbeat failure. + * + * Return: None. + */ void lim_ibss_heart_beat_handle(struct mac_context *mac, struct pe_session *pe_session); + +/** + * lim_process_ibss_peer_inactivity() - Handle inactive IBSS peer + * @mac: Global MAC context + * @buf: pointer to buffer + * + * Internal function. Deletes FW indicated peer which is inactive + * + * Return: None + */ void lim_process_ibss_peer_inactivity(struct mac_context *mac, void *buf); +#else +/** + * ibss_bss_add()- api to add ibss + * @mac_ctx: Pointer to Global MAC structure + * @session: pe session + * + * Return: None + */ +static inline +void ibss_bss_add(struct mac_context *mac_ctx, struct pe_session *session) +{ +} + +/** + * ibss_bss_delete()- delete the current BSS + * @mac_ctx: Pointer to Global MAC structure + * @session: pe session + * + * Return: None + */ +static inline +void ibss_bss_delete(struct mac_context *mac_ctx, struct pe_session *session) +{ +} + +/** + * lim_ibss_delete_all_peers: delete all IBSS peers. + * @mac_ctx: Pointer to Global MAC structure + * @session: pe session + * + * Return: None + */ +static inline +void lim_ibss_delete_all_peers(struct mac_context *mac_ctx, + struct pe_session *session) +{ +} + +/** + * lim_ibss_init() - API to init IBSS + * @mac_ctx: Pointer to Global MAC structure + * + * This function is dummy. + * + * Return: None + */ +static inline +void lim_ibss_init(struct mac_context *mac) +{ +} + +/** + * lim_ibss_delete() - Delete ibss while tearing down an IBSS + * @mac: Pointer to Global MAC structure + * @session: Pointer to session entry + * + * Return: none + */ +static inline +void lim_ibss_delete(struct mac_context *mac, struct pe_session *session) +{ +} + +/** + * lim_ibss_coalesce() - API to process IBSS Beacon/Probe Response + * @param mac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * + * This function is dummy. + * + * @return Status whether to process or ignore received Beacon Frame + */ +static inline +QDF_STATUS lim_ibss_coalesce(struct mac_context *mac, + tpSirMacMgmtHdr pHdr, + tpSchBeaconStruct pBeacon, + uint8_t *pIEs, + uint32_t ieLen, uint16_t fTsfLater, + struct pe_session *pe_session) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * lim_ibss_sta_add() - API to add an STA context in IBSS role + * @param mac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * + * This function is dummy. + * + * @return retCode Indicates success or failure return code + */ +static inline +QDF_STATUS lim_ibss_sta_add(struct mac_context *mac, void *pBody, + struct pe_session *pe_session) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * lim_ibss_add_sta_rsp() - API to process STA add response in IBSS role + * @param mac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * + * This function is funny. + * + * @return retCode Indicates success or failure return code + */ +static inline +QDF_STATUS lim_ibss_add_sta_rsp(struct mac_context *mac, + void *msg, struct pe_session *pe_session) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * lim_process_ibss_del_sta_rsp()- Handle ibss delete + * peer resp from firmware + * @mac_ptr: Pointer to Global MAC structure + * @lim_msg: delete sta response + * @pe_session: pe session + * + * This function is dymmy. + * + * Return: None + */ +static inline +void lim_process_ibss_del_sta_rsp(struct mac_context *mac_ctx, + struct scheduler_msg *lim_msg, + struct pe_session *pe_session) +{ +} + +/** + * lim_ibss_peer_find() - API to find IBSS peer + * @mac: pointer to mac context + * @param macAddr - MAC address of the peer + * + * This function is dymmy. + * + * @return Pointer to peer node if found, else NULL + */ +static inline +tLimIbssPeerNode *lim_ibss_peer_find(struct mac_context *mac, + tSirMacAddr macAddr) +{ + return NULL; +} + +/** + * lim_ibss_del_bss_rsp() - Handle ibss delete + * response + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to del bss response + * @pe_session: pointer to pe session + * + * This function is dymmy. + * + * Return: None + */ +static inline +void lim_ibss_del_bss_rsp(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session) +{ +} + +/** + * lim_ibss_del_bss_rsp_when_coalescing() - Handle ibss delete + * response when coalescing + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to del bss response + * @pe_session: pointer to pe session + * + * Return: None + * + */ +static inline +void lim_ibss_del_bss_rsp_when_coalescing(struct mac_context *mac, + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session) +{ +} + +/** + * lim_ibss_add_bss_rsp_when_coalescing()- Handle ADD BSS rsp of IBSS coalescing + * @mac_ptr: Pointer to Global MAC structure + * @op_chan_freq: operating chan freq + * @pe_session: PE session pointer + * + * Return: None + */ +static inline +void lim_ibss_add_bss_rsp_when_coalescing(struct mac_context *mac, + uint32_t op_chan_freq, + struct pe_session *pe_session) +{ +} + +/** + * lim_ibss_decide_protection_on_delete() - decides protection related info. + * @mac_ctx: global mac context + * @stads: station hash node + * @bcn_param: beacon parameters + * @session: PE session entry + * + * This function is dummy. + * + * Return: None + */ +static inline +void lim_ibss_decide_protection_on_delete(struct mac_context *mac, + tpDphHashNode sta, + tpUpdateBeaconParams pBeaconParams, + struct pe_session *pe_session) +{ +} + +/** + * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure + * @mac_ctx: global mac context + * @session: PE session entry + * + * This function is dummy. + * + * Return: None. + */ +static inline +void lim_ibss_heart_beat_handle(struct mac_context *mac, + struct pe_session *pe_session) +{ +} + +/** + * lim_process_ibss_peer_inactivity() - Handle inactive IBSS peer + * @mac: Global MAC context + * @buf: pointer to buffer + * + * This function is dummy. + * + * Return: None + */ +static inline +void lim_process_ibss_peer_inactivity(struct mac_context *mac, void *buf) +{ +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_link_monitoring_algo.c index 48281ca966cf8b097bfc48562f4a66378c6d3259..e118b35ad8222ee80e38f8b438dbd568183a0b4b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_link_monitoring_algo.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_link_monitoring_algo.c @@ -44,8 +44,7 @@ #include "lim_ft_defs.h" #include "lim_session.h" #include "lim_ser_des_utils.h" -#include "cdp_txrx_cmn.h" -#include "cdp_txrx_peer_ops.h" +#include "wlan_blm_api.h" /** * lim_delete_sta_util - utility function for deleting station context @@ -63,15 +62,14 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext { tpDphHashNode stads; - pe_debug("Deleting station: staId: %d, reasonCode: %d", - msg->staId, msg->reasonCode); + pe_debug("Deleting station: reasonCode: %d", msg->reasonCode); if (LIM_IS_IBSS_ROLE(session_entry)) { return; } - stads = dph_lookup_assoc_id(mac_ctx, msg->staId, &msg->assocId, - &session_entry->dph.dphHashTable); + stads = dph_lookup_hash_entry(mac_ctx, msg->addr2, &msg->assocId, + &session_entry->dph.dphHashTable); if (!stads) { pe_err("Invalid STA limSystemRole: %d", @@ -80,17 +78,8 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext } stads->del_sta_ctx_rssi = msg->rssi; - /* check and see if same staId. This is to avoid the scenario - * where we're trying to delete a staId we just added. - */ - if (stads->staIndex != msg->staId) { - pe_err("staid mismatch: %d vs %d", stads->staIndex, msg->staId); - return; - } - if (LIM_IS_AP_ROLE(session_entry)) { - pe_debug("Delete Station staId: %d, assocId: %d", - msg->staId, msg->assocId); + pe_debug("Delete Station assocId: %d", msg->assocId); /* * Check if Deauth/Disassoc is triggered from Host. * If mlmState is in some transient state then @@ -104,8 +93,7 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext eLIM_MLM_WT_ASSOC_CNF_STATE) && (stads->mlmStaContext.mlmState != eLIM_MLM_ASSOCIATED_STATE)))) { - pe_err("Inv Del STA staId: %d, assocId: %d", - msg->staId, msg->assocId); + pe_err("Inv Del STA assocId: %d", msg->assocId); return; } else { lim_send_disassoc_mgmt_frame(mac_ctx, @@ -130,8 +118,7 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext /* TearDownLink with AP */ tLimMlmDeauthInd mlm_deauth_ind; - pe_debug("Delete Station (staId: %d, assocId: %d)", - msg->staId, msg->assocId); + pe_debug("Delete Station (assocId: %d)", msg->assocId); if ((stads && ((stads->mlmStaContext.mlmState != @@ -149,8 +136,8 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext pe_debug("Received SIR_LIM_DELETE_STA_CONTEXT_IND for " "STA that either has no context or " "in some transit state, Addr = " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(msg->bssId)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(msg->bssId)); return; } @@ -201,12 +188,13 @@ void lim_delete_sta_context(struct mac_context *mac_ctx, struct pe_session *session_entry; tpDphHashNode sta_ds; enum eSirMacReasonCodes reason_code; + struct reject_ap_info ap_info; if (!msg) { pe_err("Invalid body pointer in message"); return; } - session_entry = pe_find_session_by_sme_session_id(mac_ctx, msg->vdev_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); if (!session_entry) { pe_err("session not found for given sme session"); qdf_mem_free(msg); @@ -255,6 +243,14 @@ void lim_delete_sta_context(struct mac_context *mac_ctx, session_entry->peSessionId, reason_code, eLIM_LINK_MONITORING_DEAUTH); + qdf_mem_copy(&ap_info.bssid, msg->addr2, + QDF_MAC_ADDR_SIZE); + ap_info.reject_ap_type = DRIVER_AVOID_TYPE; + ap_info.reject_reason = REASON_STA_KICKOUT; + ap_info.source = ADDED_BY_DRIVER; + wlan_blm_add_bssid_to_reject_list(mac_ctx->pdev, + &ap_info); + /* only break for STA role (non TDLS) */ break; } @@ -375,6 +371,7 @@ lim_tear_down_link_with_ap(struct mac_context *mac, uint8_t sessionId, pe_info("Session %d Vdev %d reason code %d trigger %d", pe_session->peSessionId, pe_session->vdev_id, reasonCode, trigger); + /* Announce loss of link to Roaming algorithm */ /* and cleanup by sending SME_DISASSOC_REQ to SME */ @@ -420,8 +417,8 @@ lim_tear_down_link_with_ap(struct mac_context *mac, uint8_t sessionId, mac->lim.gLimHeartBeatApMacIndex = 1; pe_debug("HB Failure on MAC " - QDF_MAC_ADDR_STR" Store it on Index %d", - QDF_MAC_ADDR_ARRAY(sta->staAddr), apCount); + QDF_MAC_ADDR_FMT" Store it on Index %d", + QDF_MAC_ADDR_REF(sta->staAddr), apCount); sir_copy_mac_addr(mac->lim.gLimHeartBeatApMac[apCount], sta->staAddr); @@ -502,7 +499,8 @@ void lim_handle_heart_beat_failure(struct mac_context *mac_ctx, * DFS channel then only send the probe request otherwise tear * down the link */ - curr_chan = session->currentOperChannel; + curr_chan = wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq); if (!lim_isconnected_on_dfs_channel(mac_ctx, curr_chan)) { /* Detected continuous Beacon Misses */ session->LimHBFailureStatus = true; @@ -520,14 +518,14 @@ void lim_handle_heart_beat_failure(struct mac_context *mac_ctx, scan_ie = &session->lim_join_req->addIEScan; lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId, - session->bssId, curr_chan, + session->bssId, session->curr_op_freq, session->self_mac_addr, session->dot11mode, &scan_ie->length, scan_ie->addIEdata); } else { lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId, - session->bssId, curr_chan, + session->bssId, session->curr_op_freq, session->self_mac_addr, session->dot11mode, NULL, NULL); } @@ -576,8 +574,7 @@ void lim_rx_invalid_peer_process(struct mac_context *mac_ctx, return; } - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - msg->vdev_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); if (!session_entry) { pe_err_rl("session not found for given sme session"); qdf_mem_free(msg); @@ -604,35 +601,20 @@ void lim_req_send_delba_ind_process(struct mac_context *mac_ctx, struct lim_delba_req_info *req = (struct lim_delba_req_info *)lim_msg->bodyptr; QDF_STATUS status; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer, *pdev; - uint8_t peer_id; + void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); if (!req) { pe_err("Invalid body pointer in message"); return; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - pe_err("delba pdev is NULL"); - goto error; - } - peer = cdp_peer_get_ref_by_addr(soc, pdev, req->peer_macaddr, &peer_id, - PEER_DEBUG_ID_WMA_DELBA_REQ); - if (!peer) { - pe_err("delba PEER [%pM] not found", req->peer_macaddr); - goto error; - } status = lim_send_delba_action_frame(mac_ctx, req->vdev_id, req->peer_macaddr, req->tid, req->reason_code); if (status != QDF_STATUS_SUCCESS) - cdp_delba_tx_completion(soc, peer, req->tid, + cdp_delba_tx_completion(dp_soc, req->peer_macaddr, + req->vdev_id, req->tid, WMI_MGMT_TX_COMP_TYPE_DISCARD); - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ); - -error: qdf_mem_free(req); lim_msg->bodyptr = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c index d251afe3380c205f9a47bb6f9588866697b8aebb..60abe3eed6c404cc6c7be550f5badce9dda251db 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_action_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -80,10 +80,10 @@ void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId) return; } - mac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId; + mac->lim.lim_timers.gLimChannelSwitchTimer.sessionId = sessionId; status = policy_mgr_check_and_set_hw_mode_for_channel_switch(mac->psoc, pe_session->smeSessionId, - pe_session->gLimChannelSwitch.primaryChannel, + pe_session->gLimChannelSwitch.sw_target_freq, POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA); /* @@ -97,8 +97,9 @@ void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId) * So contunue with CSA from here. */ if (status == QDF_STATUS_E_FAILURE) { - pe_err("Failed to set required HW mode for channel %d, ignore CSA", - pe_session->gLimChannelSwitch.primaryChannel); + pe_err("Failed to set required HW mode for channel %d freq %d, ignore CSA", + pe_session->gLimChannelSwitch.primaryChannel, + pe_session->gLimChannelSwitch.sw_target_freq); return; } @@ -117,7 +118,7 @@ void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId) (mac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_CHANNEL_SWITCH_TIMER)); - if (tx_timer_activate(&mac->lim.limTimers.gLimChannelSwitchTimer) != + if (tx_timer_activate(&mac->lim.lim_timers.gLimChannelSwitchTimer) != TX_SUCCESS) { pe_err("tx_timer_activate failed"); } @@ -154,13 +155,13 @@ QDF_STATUS lim_start_channel_switch(struct mac_context *mac, MTRACE(mac_trace (mac, TRACE_CODE_TIMER_DEACTIVATE, pe_session->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); - if (tx_timer_deactivate(&mac->lim.limTimers.gLimChannelSwitchTimer) != + if (tx_timer_deactivate(&mac->lim.lim_timers.gLimChannelSwitchTimer) != QDF_STATUS_SUCCESS) { pe_err("tx_timer_deactivate failed!"); return QDF_STATUS_E_FAILURE; } - if (tx_timer_change(&mac->lim.limTimers.gLimChannelSwitchTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimChannelSwitchTimer, pe_session->gLimChannelSwitch.switchTimeoutValue, 0) != TX_SUCCESS) { pe_err("tx_timer_change failed"); @@ -237,6 +238,9 @@ static void __lim_process_channel_switch_action_frame(struct mac_context *mac_ct bcn_period = (uint16_t)val; ch_switch_params->primaryChannel = chnl_switch_frame->ChanSwitchAnn.newChannel; + ch_switch_params->sw_target_freq = wlan_reg_legacy_chan_to_freq + (mac_ctx->pdev, + chnl_switch_frame->ChanSwitchAnn.newChannel); ch_switch_params->switchCount = chnl_switch_frame->ChanSwitchAnn.switchCount; ch_switch_params->switchTimeoutValue = @@ -330,7 +334,7 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx, tDot11fext_channel_switch_action_frame *ext_channel_switch_frame; uint32_t frame_len; uint32_t status; - uint8_t target_channel; + uint32_t target_freq; hdr = WMA_GET_RX_MAC_HEADER(rx_packet_info); body = WMA_GET_RX_MPDU_DATA(rx_packet_info); @@ -357,7 +361,7 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx, status, frame_len); } - if (!wlan_reg_is_6ghz_supported(mac_ctx->pdev) && + if (!wlan_reg_is_6ghz_supported(mac_ctx->psoc) && (wlan_reg_is_6ghz_op_class(mac_ctx->pdev, ext_channel_switch_frame-> ext_chan_switch_ann_action.op_class))) { @@ -366,8 +370,10 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx, return; } - target_channel = - ext_channel_switch_frame->ext_chan_switch_ann_action.new_channel; + target_freq = + wlan_reg_chan_opclass_to_freq(ext_channel_switch_frame->ext_chan_switch_ann_action.new_channel, + ext_channel_switch_frame->ext_chan_switch_ann_action.op_class, + false); /* Free ext_channel_switch_frame here as its no longer needed */ qdf_mem_free(ext_channel_switch_frame); @@ -376,14 +382,14 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx, * channel and if is valid in the current regulatory domain, * and no concurrent session is running. */ - if (!((session_entry->currentOperChannel != target_channel) && - ((wlan_reg_get_channel_state(mac_ctx->pdev, target_channel) == + if (!(session_entry->curr_op_freq != target_freq && + ((wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) == CHANNEL_STATE_ENABLE) || - (wlan_reg_get_channel_state(mac_ctx->pdev, target_channel) == + (wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) == CHANNEL_STATE_DFS && - !policy_mgr_concurrent_open_sessions_running( - mac_ctx->psoc))))) { - pe_err("Channel: %d is not valid", target_channel); + !policy_mgr_concurrent_open_sessions_running( + mac_ctx->psoc))))) { + pe_err("Channel freq: %d is not valid", target_freq); return; } @@ -402,7 +408,7 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx, /* No need to extract op mode as BW will be decided in * in SAP FSM depending on previous BW. */ - ext_cng_chan_ind->new_channel = target_channel; + ext_cng_chan_ind->new_chan_freq = target_freq; mmh_msg.type = eWNI_SME_EXT_CHANGE_CHANNEL_IND; mmh_msg.bodyptr = ext_cng_chan_ind; @@ -476,7 +482,7 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct goto end; } - if (CHAN_ENUM_14 >= session->currentOperChannel) + if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz; else cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz; @@ -508,9 +514,8 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct operating_mode_frm->OperatingMode.chanWidth)) { uint32_t fw_vht_ch_wd = wma_get_vht_ch_width(); - pe_debug("received Chanwidth: %d staIdx: %d", - (operating_mode_frm->OperatingMode.chanWidth), - sta_ptr->staIndex); + pe_debug("received Chanwidth: %d", + operating_mode_frm->OperatingMode.chanWidth); pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x", mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2], @@ -547,7 +552,7 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct ch_bw = eHT_CHANNEL_WIDTH_20MHZ; } lim_check_vht_op_mode_change(mac_ctx, session, ch_bw, - sta_ptr->staIndex, mac_hdr->sa); + mac_hdr->sa); } update_nss: @@ -556,7 +561,7 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct sta_ptr->vhtSupportedRxNss = operating_mode_frm->OperatingMode.rxNSS + 1; lim_set_nss_change(mac_ctx, session, sta_ptr->vhtSupportedRxNss, - sta_ptr->staIndex, mac_hdr->sa); + mac_hdr->sa); } end: @@ -574,10 +579,11 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct * * Return: none */ -static void __lim_process_gid_management_action_frame(struct mac_context *mac_ctx, - uint8_t *rx_pkt_info, struct pe_session *session) +static void +__lim_process_gid_management_action_frame(struct mac_context *mac_ctx, + uint8_t *rx_pkt_info, + struct pe_session *session) { - uint8_t *body_ptr; uint16_t aid; uint32_t frame_len, status, membership = 0, usr_position = 0; @@ -615,8 +621,6 @@ static void __lim_process_gid_management_action_frame(struct mac_context *mac_ct pe_err("Failed to get STA entry from hash table"); goto out; } - pe_debug("received Gid Management Action Frame staIdx: %d", - sta_ptr->staIndex); pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x", mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2], @@ -626,8 +630,7 @@ static void __lim_process_gid_management_action_frame(struct mac_context *mac_ct mem_upper = (uint32_t *) &vht_member_status->membershipStatusArray[4]; if (*mem_lower && *mem_upper) { - pe_err("rcved frame with mult group ID set, staIdx = %d", - sta_ptr->staIndex); + pe_err("rcved frame with mult group ID set"); goto out; } if (*mem_lower) { @@ -636,8 +639,7 @@ static void __lim_process_gid_management_action_frame(struct mac_context *mac_ct mem_cur = mem_upper; membership += sizeof(uint32_t); } else { - pe_err("rcved Gid frame with no group ID set, staIdx: %d", - sta_ptr->staIndex); + pe_err("rcved Gid frame with no group ID set"); goto out; } while (!(*mem_cur & 1)) { @@ -645,8 +647,7 @@ static void __lim_process_gid_management_action_frame(struct mac_context *mac_ct ++membership; } if (*mem_cur) { - pe_err("rcved frame with mult group ID set, staIdx: %d", - sta_ptr->staIndex); + pe_err("rcved frame with mult group ID set"); goto out; } @@ -654,7 +655,7 @@ static void __lim_process_gid_management_action_frame(struct mac_context *mac_ct vht_user_position = &gid_mgmt_frame->VhtUserPositionArray; usr_position = vht_user_position->userPositionArray[membership] & 0x3; lim_check_membership_user_position(mac_ctx, session, membership, - usr_position, sta_ptr->staIndex); + usr_position); out: qdf_mem_free(gid_mgmt_frame); return; @@ -835,7 +836,7 @@ static void __lim_process_add_ts_rsp(struct mac_context *mac_ctx, &session->dph.dphHashTable); if (sta_ds_ptr) lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive, - sta_ds_ptr->bssId, false); + session->vdev_id, false); else pe_err("Self entry missing in Hash Table"); sir_copy_mac_addr(peer_macaddr, session->bssId); @@ -861,12 +862,12 @@ static void __lim_process_add_ts_rsp(struct mac_context *mac_ctx, ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < QCA_WLAN_AC_ALL))) { #ifdef FEATURE_WLAN_ESE retval = lim_send_hal_msg_add_ts(mac_ctx, - sta_ptr->staIndex, tspec_info->idx, + tspec_info->idx, addts.tspec, session->peSessionId, addts.tsmIE.msmt_interval); #else retval = lim_send_hal_msg_add_ts(mac_ctx, - sta_ptr->staIndex, tspec_info->idx, + tspec_info->idx, addts.tspec, session->peSessionId); #endif if (QDF_STATUS_SUCCESS != retval) { @@ -985,7 +986,7 @@ static void __lim_process_del_ts_req(struct mac_context *mac_ctx, SIR_MAC_ACCESSPOLICY_BOTH))){ /* send message to HAL to delete TS */ if (QDF_STATUS_SUCCESS != lim_send_hal_msg_del_ts(mac_ctx, - sta_ptr->staIndex, tspec_idx, + tspec_idx, delts, session->peSessionId, session->bssId)) { pe_warn("DelTs with UP: %d failed ignoring request", @@ -1036,7 +1037,7 @@ static void __lim_process_del_ts_req(struct mac_context *mac_ctx, &session->dph.dphHashTable); if (sta_ds_ptr) lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive, - sta_ds_ptr->bssId, false); + session->vdev_id, false); else pe_err("Self entry missing in Hash Table"); @@ -1076,7 +1077,7 @@ static void __lim_process_qos_map_configure_frame(struct mac_context *mac_ctx, lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType, (uint8_t *)mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), 0, - WMA_GET_RX_CH(rx_pkt_info), session, + WMA_GET_RX_FREQ(rx_pkt_info), session, WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), RXMGMT_FLAG_NONE); } @@ -1259,7 +1260,7 @@ __lim_process_sm_power_save_update(struct mac_context *mac, uint8_t *pRxPacketIn /** Update in the HAL Station Table for the Update of the Protection Mode */ pSta->htMIMOPSState = state; - lim_post_sm_state_update(mac, pSta->staIndex, pSta->htMIMOPSState, + lim_post_sm_state_update(mac, pSta->htMIMOPSState, pSta->staAddr, pe_session->smeSessionId); } @@ -1296,7 +1297,7 @@ __lim_process_radio_measure_request(struct mac_context *mac, uint8_t *pRxPacketI mac->rrm.rrmPEContext.prev_rrm_report_seq_num = curr_seq_num; lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType, (uint8_t *)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0, - WMA_GET_RX_CH(pRxPacketInfo), pe_session, + WMA_GET_RX_FREQ(pRxPacketInfo), pe_session, WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo), RXMGMT_FLAG_NONE); @@ -1527,7 +1528,7 @@ static void __lim_process_sa_query_response_action_frame(struct mac_context *mac (uint8_t *)pHdr, frame_len + sizeof(tSirMacMgmtHdr), 0, - WMA_GET_RX_CH(pRxPacketInfo), + WMA_GET_RX_FREQ(pRxPacketInfo), pe_session, WMA_GET_RX_RSSI_NORMALIZED( pRxPacketInfo), RXMGMT_FLAG_NONE); @@ -1636,15 +1637,10 @@ static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i tDot11faddba_req *addba_req; uint32_t frame_len, status; QDF_STATUS qdf_status; - uint8_t peer_id; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer, *pdev; - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - pe_err("pdev is NULL"); - return; - } + tpDphHashNode sta_ds; + uint16_t aid, buff_size; + bool he_cap = false; mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); @@ -1668,25 +1664,38 @@ static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i pe_warn("warning: unpack addba Req(0x%08x, %d bytes)", status, frame_len); } - pe_debug("token %d tid %d timeout %d buff_size %d ssn %d", + + sta_ds = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid, + &session->dph.dphHashTable); + if (sta_ds && lim_is_session_he_capable(session)) + he_cap = lim_is_sta_he_capable(sta_ds); + + if (he_cap) + buff_size = MAX_BA_BUFF_SIZE; + else + buff_size = SIR_MAC_BA_DEFAULT_BUFF_SIZE; + + if (mac_ctx->usr_cfg_ba_buff_size) + buff_size = mac_ctx->usr_cfg_ba_buff_size; + + if (addba_req->addba_param_set.buff_size) + buff_size = QDF_MIN(buff_size, + addba_req->addba_param_set.buff_size); + + pe_debug("token %d tid %d timeout %d buff_size in frame %d buf_size calculated %d ssn %d", addba_req->DialogToken.token, addba_req->addba_param_set.tid, addba_req->ba_timeout.timeout, - addba_req->addba_param_set.buff_size, + addba_req->addba_param_set.buff_size, buff_size, addba_req->ba_start_seq_ctrl.ssn); - peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->sa, &peer_id, - PEER_DEBUG_ID_WMA_ADDBA_REQ); - if (!peer) { - pe_err("PEER [%pM] not found", mac_hdr->sa); - goto error; - } - - qdf_status = cdp_addba_requestprocess(soc, peer, - addba_req->DialogToken.token, - addba_req->addba_param_set.tid, - addba_req->ba_timeout.timeout, - addba_req->addba_param_set.buff_size, - addba_req->ba_start_seq_ctrl.ssn); + qdf_status = cdp_addba_requestprocess( + soc, mac_hdr->sa, + session->vdev_id, + addba_req->DialogToken.token, + addba_req->addba_param_set.tid, + addba_req->ba_timeout.timeout, + buff_size, + addba_req->ba_start_seq_ctrl.ssn); if (QDF_STATUS_SUCCESS == qdf_status) { qdf_status = lim_send_addba_response_frame(mac_ctx, @@ -1698,16 +1707,15 @@ static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i mac_hdr->fc.wep); if (qdf_status != QDF_STATUS_SUCCESS) { pe_err("Failed to send addba response frame"); - cdp_addba_resp_tx_completion(soc, peer, - addba_req->addba_param_set.tid, - WMI_MGMT_TX_COMP_TYPE_DISCARD); + cdp_addba_resp_tx_completion( + soc, mac_hdr->sa, session->vdev_id, + addba_req->addba_param_set.tid, + WMI_MGMT_TX_COMP_TYPE_DISCARD); } } else { pe_err_rl("Failed to process addba request"); } - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_ADDBA_REQ); - error: qdf_mem_free(addba_req); return; @@ -1731,15 +1739,7 @@ static void lim_process_delba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i tDot11fdelba_req *delba_req; uint32_t frame_len, status; QDF_STATUS qdf_status; - uint8_t peer_id; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer, *pdev; - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - pe_err("pdev is NULL"); - return; - } mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); @@ -1765,18 +1765,9 @@ static void lim_process_delba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_i status, frame_len); } - peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->sa, &peer_id, - PEER_DEBUG_ID_WMA_DELBA_REQ); - if (!peer) { - pe_err("PEER [%pM] not found", mac_hdr->sa); - goto error; - } - - qdf_status = cdp_delba_process(soc, peer, + qdf_status = cdp_delba_process(soc, mac_hdr->sa, session->vdev_id, delba_req->delba_param_set.tid, delba_req->Reason.code); - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ); - if (QDF_STATUS_SUCCESS != qdf_status) pe_err("Failed to process delba request"); @@ -1945,9 +1936,9 @@ void lim_process_action_frame(struct mac_context *mac_ctx, pe_debug("WNM Action category: %d action: %d", action_hdr->category, action_hdr->actionID); switch (action_hdr->actionID) { - case SIR_MAC_WNM_BSS_TM_QUERY: - case SIR_MAC_WNM_BSS_TM_REQUEST: - case SIR_MAC_WNM_BSS_TM_RESPONSE: + case WNM_BSS_TM_QUERY: + case WNM_BSS_TM_REQUEST: + case WNM_BSS_TM_RESPONSE: if (cfg_p2p_is_roam_config_disabled(mac_ctx->psoc) && session && LIM_IS_STA_ROLE(session) && (policy_mgr_mode_specific_connection_count( @@ -1957,8 +1948,8 @@ void lim_process_action_frame(struct mac_context *mac_ctx, pe_debug("p2p session active drop BTM frame"); break; } - case SIR_MAC_WNM_NOTIF_REQUEST: - case SIR_MAC_WNM_NOTIF_RESPONSE: + case WNM_NOTIF_REQUEST: + case WNM_NOTIF_RESPONSE: rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); /* Forward to the SME to HDD to wpa_supplicant */ @@ -1967,7 +1958,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, (uint8_t *) mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), + WMA_GET_RX_FREQ(rx_pkt_info), session, rssi, RXMGMT_FLAG_NONE); break; default: @@ -2055,7 +2046,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, frame_len + sizeof(tSirMacMgmtHdr), session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), + WMA_GET_RX_FREQ(rx_pkt_info), session, WMA_GET_RX_RSSI_NORMALIZED( rx_pkt_info), RXMGMT_FLAG_NONE); @@ -2115,7 +2106,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, (uint8_t *) mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), session, + WMA_GET_RX_FREQ(rx_pkt_info), session, WMA_GET_RX_RSSI_NORMALIZED( rx_pkt_info), RXMGMT_FLAG_NONE); break; @@ -2131,14 +2122,14 @@ void lim_process_action_frame(struct mac_context *mac_ctx, pe_debug("SA Query Action category: %d action: %d", action_hdr->category, action_hdr->actionID); switch (action_hdr->actionID) { - case SIR_MAC_SA_QUERY_REQ: + case SA_QUERY_REQUEST: /**11w SA query request action frame received**/ /* Respond directly to the incoming request in LIM */ __lim_process_sa_query_request_action_frame(mac_ctx, (uint8_t *)rx_pkt_info, session); break; - case SIR_MAC_SA_QUERY_RSP: + case SA_QUERY_RESPONSE: /**11w SA query response action frame received**/ /* Handle based on the current SA Query state */ __lim_process_sa_query_response_action_frame(mac_ctx, @@ -2179,7 +2170,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, (uint8_t *)hdr, frame_len + sizeof(tSirMacMgmtHdr), session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), + WMA_GET_RX_FREQ(rx_pkt_info), session, WMA_GET_RX_RSSI_NORMALIZED( rx_pkt_info), RXMGMT_FLAG_NONE); @@ -2199,7 +2190,7 @@ void lim_process_action_frame(struct mac_context *mac_ctx, mac_hdr->fc.subType, (uint8_t *) mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), session, rssi, + WMA_GET_RX_FREQ(rx_pkt_info), session, rssi, RXMGMT_FLAG_NONE); break; default: @@ -2208,8 +2199,9 @@ void lim_process_action_frame(struct mac_context *mac_ctx, } break; case ACTION_CATEGORY_BACK: - pe_debug("Rcvd Block Ack for %pM; action: %d", - session->self_mac_addr, action_hdr->actionID); + pe_debug("Rcvd Block Ack for "QDF_MAC_ADDR_FMT"; action: %d", + QDF_MAC_ADDR_REF(session->self_mac_addr), + action_hdr->actionID); switch (action_hdr->actionID) { case ADDBA_REQUEST: lim_process_addba_req(mac_ctx, rx_pkt_info, session); @@ -2303,7 +2295,7 @@ void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pBd) mac_hdr->fc.subType, (uint8_t *) mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), 0, - WMA_GET_RX_CH(pBd), NULL, + WMA_GET_RX_FREQ(pBd), NULL, WMA_GET_RX_RSSI_NORMALIZED(pBd), RXMGMT_FLAG_NONE); break; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index bed0d05f759e3c02710216b6e8b5e6cdce010941..9ede9a818aed858a60db5d2b1a4fc6c02fa895b9 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,11 +33,11 @@ #include "lim_assoc_utils.h" #include "lim_security_utils.h" #include "lim_ser_des_utils.h" -#include "lim_sta_hash_api.h" #include "lim_admit_control.h" #include "cds_packet.h" #include "lim_session_utils.h" #include "utils_parser.h" +#include "wlan_p2p_api.h" #include "qdf_types.h" #include "cds_utils.h" @@ -65,6 +65,7 @@ static void lim_convert_supported_channels(struct mac_context *mac_ctx, uint8_t chn_count; uint8_t next_ch_no; uint8_t channel_offset = 0; + uint32_t chan_freq; if (assoc_req->supportedChannels.length >= SIR_MAX_SUPPORTED_CHANNEL_LIST) { @@ -93,9 +94,12 @@ static void lim_convert_supported_channels(struct mac_context *mac_ctx, if (chn_count <= 1) continue; next_ch_no = first_ch_no; - if (BAND_5G == lim_get_rf_band(first_ch_no)) + chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + first_ch_no); + + if (REG_BAND_5G == lim_get_rf_band(chan_freq)) channel_offset = SIR_11A_FREQUENCY_OFFSET; - else if (BAND_2G == lim_get_rf_band(first_ch_no)) + else if (REG_BAND_2G == lim_get_rf_band(chan_freq)) channel_offset = SIR_11B_FREQUENCY_OFFSET; else continue; @@ -165,17 +169,17 @@ static QDF_STATUS lim_check_sta_in_pe_entries(struct mac_context *mac_ctx, eLIM_MLM_WT_DEL_BSS_RSP_STATE || sta_ds->sta_deletion_in_progress) { pe_debug( - "Deletion is in progress (%d) for peer:%pM in mlmState %d", + "Deletion is in progress (%d) for peer:"QDF_MAC_ADDR_FMT" in mlmState %d", sta_ds->sta_deletion_in_progress, - sta_ds->staAddr, + QDF_MAC_ADDR_REF(sta_ds->staAddr), sta_ds->mlmStaContext.mlmState); *dup_entry = true; return QDF_STATUS_E_AGAIN; } sta_ds->sta_deletion_in_progress = true; pe_err("Sending Disassoc and Deleting existing STA entry:" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( session->self_mac_addr)); lim_send_disassoc_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, @@ -287,7 +291,7 @@ static bool lim_chk_assoc_req_parse_error(struct mac_context *mac_ctx, return true; pe_warn("Assoc Req rejected: frame parsing error. source addr:" - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(hdr->sa)); lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa, sub_type, 0, session, false); return false; @@ -323,9 +327,9 @@ static bool lim_chk_capab(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, if (lim_compare_capabilities(mac_ctx, assoc_req, local_cap, session) == false) { pe_warn("Rcvd %s Req with unsupported capab from" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); /* * Capabilities of requesting STA does not match with * local capabilities. Respond with 'unsupported capabilities' @@ -359,11 +363,11 @@ static bool lim_chk_ssid(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, return true; pe_err("%s Req with ssid wrong(Rcvd: %.*s self: %.*s) from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", assoc_req->ssId.length, assoc_req->ssId.ssId, session->ssId.length, session->ssId.ssId, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); /* * Received Re/Association Request with either Broadcast SSID OR with @@ -416,9 +420,9 @@ static bool lim_chk_rates(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, return true; pe_warn("Assoc Req rejected: unsupported rates, soruce addr: %s" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); /* * Requesting STA does not support ALL BSS basic rates. Respond with * 'basic rates not supported' status code. @@ -449,8 +453,8 @@ static bool lim_chk_11g_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, (session->dot11mode == MLME_DOT11_MODE_11G_ONLY) && (assoc_req->HTCaps.present)) { pe_err("SOFTAP was in 11G only mode, rejecting legacy STA: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); lim_send_assoc_rsp_mgmt_frame( mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, 1, hdr->sa, sub_type, 0, session, false); @@ -479,8 +483,8 @@ static bool lim_chk_11n_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, (session->dot11mode == MLME_DOT11_MODE_11N_ONLY) && (!assoc_req->HTCaps.present)) { pe_err("SOFTAP was in 11N only mode, rejecting legacy STA: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); lim_send_assoc_rsp_mgmt_frame( mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, 1, hdr->sa, sub_type, 0, session, false); @@ -647,17 +651,17 @@ lim_process_for_spectrum_mgmt(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, */ if (!assoc_req->powerCapabilityPresent) { pe_warn("LIM Info: Missing Power capability IE in %s Req from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); } if (!assoc_req->supportedChannelsPresent) { pe_warn("LIM Info: Missing Supported channel IE in %s Req from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); } } else { /* Assoc request has mandatory fields */ @@ -666,19 +670,19 @@ lim_process_for_spectrum_mgmt(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, mac_ctx, assoc_req, session); if (QDF_STATUS_SUCCESS != status) { pe_warn("LIM Info: MinTxPower(STA) > MaxTxPower(AP) in %s Req from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); } status = lim_is_dot11h_supported_channels_valid( mac_ctx, assoc_req); if (QDF_STATUS_SUCCESS != status) { pe_warn("LIM Info: wrong supported channels (STA) in %s Req from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); } /* IEs are valid, use them if needed */ } @@ -721,9 +725,9 @@ static bool lim_chk_mcs(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, if ((assoc_req->HTCaps.present) && (lim_check_mcs_set(mac_ctx, assoc_req->HTCaps.supportedMCSSet) == false)) { pe_warn("rcvd %s req with unsupported MCS Rate Set from " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); /* * Requesting STA does not support ALL BSS MCS basic Rate set * rates. Spec does not define any status code for this @@ -825,8 +829,6 @@ static void lim_print_ht_cap(struct mac_context *mac_ctx, struct pe_session *ses } } -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT - static enum mac_status_code lim_check_crypto_param(tpSirAssocReq assoc_req, struct wlan_crypto_params *peer_crypto_params) @@ -848,25 +850,18 @@ static enum mac_status_code lim_check_rsn_ie(struct pe_session *session, struct mac_context *mac_ctx, tpSirAssocReq assoc_req, - tDot11fIERSN *rsn, bool *pmf_connection) { struct wlan_objmgr_vdev *vdev; - - uint8_t buffer[WLAN_MAX_IE_LEN]; - uint32_t dot11f_status, written = 0, nbuffer = WLAN_MAX_IE_LEN; tSirMacRsnInfo rsn_ie; struct wlan_crypto_params peer_crypto_params; - dot11f_status = dot11f_pack_ie_rsn(mac_ctx, rsn, buffer, - nbuffer, &written); - if (DOT11F_FAILED(dot11f_status)) { - pe_err("Failed to re-pack the RSN IE (0x%0x8)", dot11f_status); - return eSIR_MAC_INVALID_IE_STATUS; - } + rsn_ie.info[0] = WLAN_ELEMID_RSN; + rsn_ie.info[1] = assoc_req->rsn.length; - rsn_ie.length = (uint8_t) written; - qdf_mem_copy(&rsn_ie.info[0], buffer, rsn_ie.length); + rsn_ie.length = assoc_req->rsn.length + 2; + qdf_mem_copy(&rsn_ie.info[2], assoc_req->rsn.info, + assoc_req->rsn.length); if (wlan_crypto_check_rsn_match(mac_ctx->psoc, session->smeSessionId, &rsn_ie.info[0], rsn_ie.length, &peer_crypto_params)) { @@ -877,8 +872,11 @@ enum mac_status_code lim_check_rsn_ie(struct pe_session *session, pe_err("vdev is NULL"); return eSIR_MAC_UNSPEC_FAILURE_STATUS; } + if ((peer_crypto_params.rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) && + wlan_crypto_vdev_is_pmf_enabled(vdev)) + *pmf_connection = true; - *pmf_connection = wlan_crypto_vdev_is_pmf_enabled(vdev); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); return lim_check_crypto_param(assoc_req, &peer_crypto_params); @@ -916,32 +914,12 @@ static enum mac_status_code lim_check_wpa_ie(struct pe_session *session, return eSIR_MAC_INVALID_IE_STATUS; } -#else -static enum mac_status_code lim_check_rsn_ie(struct pe_session *session, - struct mac_context *mac_ctx, - tpSirAssocReq assoc_req, - tDot11fIERSN *rsn, - bool *pmf_connection) -{ - return lim_check_rx_rsn_ie_match(mac_ctx, rsn, session, - assoc_req->HTCaps.present, - pmf_connection); -} - -static enum mac_status_code lim_check_wpa_ie(struct pe_session *session, - struct mac_context *mac_ctx, - tpSirAssocReq assoc_req, - tDot11fIEWPA *wpa) -{ - return lim_check_rx_wpa_ie_match(mac_ctx, wpa, session, - assoc_req->HTCaps.present); -} -#endif /** * lim_check_sae_pmf_cap() - check pmf capability for SAE STA * @session: pointer to pe session entry * @rsn: pointer to RSN + * @akm_type: AKM type * * This function checks if SAE STA is pmf capable when SAE SAP is pmf * capable. Reject with eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION @@ -949,21 +927,24 @@ static enum mac_status_code lim_check_wpa_ie(struct pe_session *session, * * Return: mac_status_code */ -#ifdef WLAN_FEATURE_SAE +#if defined(WLAN_FEATURE_SAE) && defined(WLAN_FEATURE_11W) static enum mac_status_code lim_check_sae_pmf_cap(struct pe_session *session, - tDot11fIERSN *rsn) + tDot11fIERSN *rsn, + enum ani_akm_type akm_type) { enum mac_status_code status = eSIR_MAC_SUCCESS_STATUS; if (session->pLimStartBssReq->pmfCapable && - (rsn->RSN_Cap[0] & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) == 0) + (rsn->RSN_Cap[0] & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) == 0 && + akm_type == ANI_AKM_TYPE_SAE) status = eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION_STATUS; return status; } #else static enum mac_status_code lim_check_sae_pmf_cap(struct pe_session *session, - tDot11fIERSN *rsn) + tDot11fIERSN *rsn, + enum ani_akm_type akm_type) { return eSIR_MAC_SUCCESS_STATUS; } @@ -1002,13 +983,13 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, qdf_mem_zero((uint8_t *) &dot11f_ie_rsn, sizeof(dot11f_ie_rsn)); qdf_mem_zero((uint8_t *) &dot11f_ie_wpa, sizeof(dot11f_ie_wpa)); pe_debug("RSN enabled auth, Re/Assoc req from STA: " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(hdr->sa)); if (assoc_req->rsnPresent) { if (!(assoc_req->rsn.length)) { pe_warn("Re/Assoc rejected from: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); /* * rcvd Assoc req frame with RSN IE but * length is zero @@ -1036,12 +1017,11 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, if (SIR_MAC_OUI_VERSION_1 == dot11f_ie_rsn.version) { /* check the groupwise and pairwise cipher suites */ status = lim_check_rsn_ie(session, mac_ctx, assoc_req, - &dot11f_ie_rsn, pmf_connection); if (eSIR_MAC_SUCCESS_STATUS != status) { pe_warn("Re/Assoc rejected from: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); lim_send_assoc_rsp_mgmt_frame( mac_ctx, status, 1, hdr->sa, sub_type, @@ -1049,8 +1029,8 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, return false; } } else { - pe_warn("Re/Assoc rejected from: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_warn("Re/Assoc rejected from: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); /* * rcvd Assoc req frame with RSN IE but * IE version is wrong @@ -1064,12 +1044,12 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, *akm_type = lim_translate_rsn_oui_to_akm_type( dot11f_ie_rsn.akm_suite[0]); - if (*akm_type == ANI_AKM_TYPE_SAE) - status = lim_check_sae_pmf_cap(session, &dot11f_ie_rsn); + status = lim_check_sae_pmf_cap(session, &dot11f_ie_rsn, + *akm_type); if (eSIR_MAC_SUCCESS_STATUS != status) { /* Reject pmf disable SAE STA */ - pe_warn("Re/Assoc rejected from: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_warn("Re/Assoc rejected from: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1, hdr->sa, sub_type, 0, session, false); @@ -1079,8 +1059,8 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, } else if (assoc_req->wpaPresent) { if (!(assoc_req->wpa.length)) { pe_warn("Re/Assoc rejected from: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); /* rcvd Assoc req frame with invalid WPA IE length */ lim_send_assoc_rsp_mgmt_frame( @@ -1106,8 +1086,8 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, &dot11f_ie_wpa); if (eSIR_MAC_SUCCESS_STATUS != status) { pe_warn("Re/Assoc rejected from: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); /* * rcvd Assoc req frame with WPA IE * but there is mismatch @@ -1222,9 +1202,9 @@ static bool lim_process_assoc_req_no_sta_ctx(struct mac_context *mac_ctx, hdr->sa, session, false); pe_warn("rcvd %s req, sessionid: %d, without pre-auth ctx" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - session->peSessionId, QDF_MAC_ADDR_ARRAY(hdr->sa)); + session->peSessionId, QDF_MAC_ADDR_REF(hdr->sa)); return false; } /* Delete 'pre-auth' context of STA */ @@ -1294,9 +1274,10 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, if (sta_ds->sta_deletion_in_progress || (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)) { - pe_debug("%s: peer:%pM in mlmState %d (%s) and sta del %d", + pe_debug("%s: peer:"QDF_MAC_ADDR_FMT" in mlmState %d (%s) and sta del %d", (sub_type == LIM_ASSOC) ? "Assoc" : "ReAssoc", - sta_ds->staAddr, sta_ds->mlmStaContext.mlmState, + QDF_MAC_ADDR_REF(sta_ds->staAddr), + sta_ds->mlmStaContext.mlmState, lim_mlm_state_str(sta_ds->mlmStaContext.mlmState), sta_ds->sta_deletion_in_progress); lim_update_assoc_drop_count(mac_ctx, sub_type); @@ -1391,8 +1372,8 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, *update_ctx = true; /* Free pmf query timer before resetting the sta_ds */ lim_delete_pmf_query_timer(sta_ds); - if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, true, - &session->dph.dphHashTable) == NULL) { + if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, + &session->dph.dphHashTable) == NULL) { pe_err("could not Init STAid: %d", peer_idx); return false; } @@ -1437,7 +1418,8 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, lim_send_assoc_rsp_mgmt_frame( mac_ctx, eSIR_MAC_QAP_NO_BANDWIDTH_REASON, - 1, hdr->sa, sub_type, 0, session, false); + 1, hdr->sa, sub_type, 0, session, + false); #ifdef WLAN_DEBUG mac_ctx->lim.gLimNumAssocReqDropACRejectTS++; #endif @@ -1460,6 +1442,14 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, return true; } +static void lim_update_sta_ds_op_classes(tpSirAssocReq assoc_req, + tpDphHashNode sta_ds) +{ + qdf_mem_copy(&sta_ds->supp_operating_classes, + &assoc_req->supp_operating_classes, + sizeof(tDot11fIESuppOperatingClasses)); +} + /** * lim_update_sta_ds() - updates ds dph entry * @mac_ctx: pointer to Global MAC structure @@ -1474,6 +1464,8 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * @peer_idx: peer index * @qos_mode: qos mode * @pmf_connection: flag indicating pmf connection + * @force_1x1: Flag to check if the HT capable STA needs to be downgraded to 1x1 + * nss. * * Updates ds dph entry * @@ -1486,7 +1478,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, tAniAuthType auth_type, enum ani_akm_type akm_type, bool *assoc_req_copied, uint16_t peer_idx, - tHalBitVal qos_mode, bool pmf_connection) + tHalBitVal qos_mode, bool pmf_connection, + bool force_1x1) { tHalBitVal wme_mode, wsm_mode; uint8_t *ht_cap_ie = NULL; @@ -1525,11 +1518,17 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, *assoc_req_copied = true; } - sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present; - if ((vht_caps) && vht_caps->present) - sta_ds->mlmStaContext.vhtCapability = vht_caps->present; - else - sta_ds->mlmStaContext.vhtCapability = false; + if (!assoc_req->wmeInfoPresent) { + sta_ds->mlmStaContext.htCapability = 0; + sta_ds->mlmStaContext.vhtCapability = 0; + } else { + sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present; + if ((vht_caps) && vht_caps->present) + sta_ds->mlmStaContext.vhtCapability = vht_caps->present; + else + sta_ds->mlmStaContext.vhtCapability = false; + } + lim_update_stads_he_capable(sta_ds, assoc_req); sta_ds->qos.addtsPresent = (assoc_req->addtsPresent == 0) ? false : true; @@ -1548,6 +1547,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->mlmStaContext.authType = auth_type; sta_ds->mlmStaContext.akm_type = akm_type; sta_ds->staType = STA_ENTRY_PEER; + sta_ds->mlmStaContext.force_1x1 = force_1x1; pe_debug("auth_type = %d, akm_type = %d", auth_type, akm_type); @@ -1559,7 +1559,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo; if (IS_DOT11_MODE_HT(session->dot11mode) && - assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) { + sta_ds->mlmStaContext.htCapability) { sta_ds->htGreenfield = (uint8_t) assoc_req->HTCaps.greenField; sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity; sta_ds->htDsssCckRate40MHzSupport = @@ -1594,64 +1594,63 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->htSupportedChannelWidthSet = (uint8_t) assoc_req->HTCaps.supportedChannelWidthSet; - /* - * peer just follows AP; so when we are softAP/GO, - * we just store our session entry's secondary channel offset - * here in peer INFRA STA. However, if peer's 40MHz channel - * width support is disabled then secondary channel will be zero - */ - sta_ds->htSecondaryChannelOffset = - (sta_ds->htSupportedChannelWidthSet) ? - session->htSecondaryChannelOffset : 0; - if (assoc_req->operMode.present) { - enum phy_ch_width ch_width; - - ch_width = assoc_req->operMode.chanWidth; - if (session->ch_width < ch_width) - ch_width = session->ch_width; - - sta_ds->vhtSupportedChannelWidthSet = - (uint8_t) ((ch_width == CH_WIDTH_80MHZ) ? - WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ); - sta_ds->htSupportedChannelWidthSet = - (uint8_t) (ch_width ? - eHT_CHANNEL_WIDTH_40MHZ : - eHT_CHANNEL_WIDTH_20MHZ); - } else if ((vht_caps) && vht_caps->present) { + if (session->ch_width > CH_WIDTH_20MHZ && + session->ch_width <= CH_WIDTH_80P80MHZ && + sta_ds->htSupportedChannelWidthSet) { /* - * Check if STA has enabled it's channel bonding mode. - * If channel bonding mode is enabled, we decide based - * on SAP's current configuration. else, we set it to - * VHT20. + * peer just follows AP; so when we are softAP/GO, + * we just store our session entry's secondary channel + * offset here in peer INFRA STA. However, if peer's + * 40MHz channel width support is disabled then + * secondary channel will be zero */ - sta_ds->vhtSupportedChannelWidthSet = - (uint8_t) ((sta_ds->htSupportedChannelWidthSet - == eHT_CHANNEL_WIDTH_20MHZ) ? - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ : - session->ch_width - 1); - } - /* Lesser among the AP and STA bandwidth of operation. */ - sta_ds->htSupportedChannelWidthSet = - (sta_ds->htSupportedChannelWidthSet < - session->htSupportedChannelWidthSet) ? - sta_ds->htSupportedChannelWidthSet : - session->htSupportedChannelWidthSet; - - if (!sta_ds->htSupportedChannelWidthSet) - sta_ds->vhtSupportedChannelWidthSet = - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + sta_ds->htSecondaryChannelOffset = + session->htSecondaryChannelOffset; + sta_ds->ch_width = CH_WIDTH_40MHZ; + if (sta_ds->mlmStaContext.vhtCapability) { + if (assoc_req->operMode.present) { + sta_ds->ch_width = + assoc_req->operMode.chanWidth; + } else if (vht_caps->supportedChannelWidthSet == + VHT_CAP_160_AND_80P80_SUPP) { + sta_ds->ch_width = CH_WIDTH_80P80MHZ; + } else if (vht_caps->supportedChannelWidthSet == + VHT_CAP_160_SUPP) { + if (vht_caps->vht_extended_nss_bw_cap && + vht_caps->extended_nss_bw_supp) + sta_ds->ch_width = + CH_WIDTH_80P80MHZ; + else + sta_ds->ch_width = + CH_WIDTH_160MHZ; + } else if (vht_caps->vht_extended_nss_bw_cap) { + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_160) + sta_ds->ch_width = + CH_WIDTH_160MHZ; + else if (vht_caps->extended_nss_bw_supp > + VHT_EXTD_NSS_80_HALF_NSS_160) + sta_ds->ch_width = + CH_WIDTH_80P80MHZ; + else + sta_ds->ch_width = + CH_WIDTH_80MHZ; + } else { + sta_ds->ch_width = CH_WIDTH_80MHZ; + } + sta_ds->ch_width = QDF_MIN(sta_ds->ch_width, + session->ch_width); + } + } else { + sta_ds->htSupportedChannelWidthSet = 0; + sta_ds->htSecondaryChannelOffset = 0; + sta_ds->ch_width = CH_WIDTH_20MHZ; + } sta_ds->htLdpcCapable = (uint8_t) assoc_req->HTCaps.advCodingCap; } - if ((vht_caps) && vht_caps->present && - assoc_req->wmeInfoPresent) { - sta_ds->vhtLdpcCapable = - (uint8_t) vht_caps->ldpcCodingCap; - } - if (assoc_req->ExtCap.present) sta_ds->non_ecsa_capable = !((struct s_ext_cap *)assoc_req->ExtCap.bytes)-> @@ -1659,14 +1658,12 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, else sta_ds->non_ecsa_capable = 1; - if (!assoc_req->wmeInfoPresent) { - sta_ds->mlmStaContext.htCapability = 0; - sta_ds->mlmStaContext.vhtCapability = 0; - } - - if (sta_ds->mlmStaContext.vhtCapability && vht_caps) { + if (sta_ds->mlmStaContext.vhtCapability && + session->vhtCapability) { sta_ds->htMaxRxAMpduFactor = vht_caps->maxAMPDULenExp; + sta_ds->vhtLdpcCapable = + (uint8_t)vht_caps->ldpcCodingCap; if (session->vht_config.su_beam_formee && vht_caps->suBeamFormerCap) sta_ds->vhtBeamFormerCapable = 1; @@ -1710,8 +1707,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, &assoc_req->he_cap) != QDF_STATUS_SUCCESS) { /* Could not update hash table entry at DPH with rateset */ pe_err("Couldn't update hash entry for aid: %d MacAddr: " - QDF_MAC_ADDR_STR, - peer_idx, QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, + peer_idx, QDF_MAC_ADDR_REF(hdr->sa)); /* Release AID */ lim_release_peer_idx(mac_ctx, peer_idx, session); @@ -1733,7 +1730,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, ((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2) ? 1 : 2; } - + lim_update_stads_he_6ghz_op(session, sta_ds); + lim_update_sta_ds_op_classes(assoc_req, sta_ds); /* Add STA context at MAC HW (BMU, RHP & TFP) */ sta_ds->qosMode = false; sta_ds->lleEnabled = false; @@ -1817,9 +1815,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, session); return false; } - pe_debug("Created pmf timer sta-idx:%d assoc-id:%d sta mac" QDF_MAC_ADDR_STR, - sta_ds->staIndex, sta_ds->assocId, - QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); + pe_debug("Created pmf timer assoc-id:%d sta mac" QDF_MAC_ADDR_FMT, + sta_ds->assocId, QDF_MAC_ADDR_REF(sta_ds->staAddr)); } #endif @@ -1830,6 +1827,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->timingMeasCap = 0; pe_debug("ExtCap not present"); } + lim_ap_check_6g_compatible_peer(mac_ctx, session); return true; } @@ -1900,8 +1898,9 @@ static bool lim_update_sta_ctx(struct mac_context *mac_ctx, struct pe_session *s eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE; if (lim_del_sta(mac_ctx, sta_ds, true, session) != QDF_STATUS_SUCCESS) { - pe_err("Couldn't DEL STA, assocId: %d staId: %d", - sta_ds->assocId, sta_ds->staIndex); + pe_err("Couldn't DEL STA, assocId: %d sta mac" + QDF_MAC_ADDR_FMT, sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); lim_reject_association(mac_ctx, sta_ds->staAddr, sta_ds->mlmStaContext.subType, true, sta_ds->mlmStaContext.authType, @@ -2039,13 +2038,11 @@ static void lim_defer_sme_indication(struct mac_context *mac_ctx, bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, struct pe_session *session, - uint8_t sub_type, - tpSirMacMgmtHdr hdr, + uint8_t sub_type, tpSirMacMgmtHdr hdr, tpSirAssocReq assoc_req, enum ani_akm_type akm_type, - bool pmf_connection, - bool *assoc_req_copied, - bool dup_entry) + bool pmf_connection, bool *assoc_req_copied, + bool dup_entry, bool force_1x1) { uint16_t peer_idx; struct tLimPreAuthNode *sta_pre_auth_ctx; @@ -2083,9 +2080,9 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, return false; /* STA is Associated ! */ - pe_debug("Received: %s Req successful from " QDF_MAC_ADDR_STR, + pe_debug("Received: %s Req successful from " QDF_MAC_ADDR_FMT, (sub_type == LIM_ASSOC) ? "Assoc" : "ReAssoc", - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); /* * AID for this association will be same as the peer Index used in DPH @@ -2114,7 +2111,7 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, if (!sta_ds) { /* Could not add hash table entry at DPH */ pe_err("couldn't add hash entry at DPH for aid: %d MacAddr:" - QDF_MAC_ADDR_STR, peer_idx, QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_FMT, peer_idx, QDF_MAC_ADDR_REF(hdr->sa)); /* Release AID */ lim_release_peer_idx(mac_ctx, peer_idx, session); @@ -2142,7 +2139,7 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, if (!lim_update_sta_ds(mac_ctx, hdr, session, assoc_req, sub_type, sta_ds, auth_type, akm_type, assoc_req_copied, peer_idx, qos_mode, - pmf_connection)) + pmf_connection, force_1x1)) return false; /* BTAMP: Storing the parsed assoc request in the session array */ @@ -2164,7 +2161,7 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, * Update in the HAL Sta Table for the Update of the Protection * Mode */ - lim_post_sm_state_update(mac_ctx, sta_ds->staIndex, + lim_post_sm_state_update(mac_ctx, sta_ds->htMIMOPSState, sta_ds->staAddr, session->smeSessionId); } @@ -2199,8 +2196,8 @@ lim_peer_present_on_any_sta(struct mac_context *mac_ctx, uint8_t *peer_addr) peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); mode = wlan_vdev_mlme_get_opmode(wlan_peer_get_vdev(peer)); if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) { - pe_debug("duplicate mac detected!!! Peer " QDF_MAC_ADDR_STR " present on STA vdev %d", - QDF_MAC_ADDR_ARRAY(peer_addr), peer_vdev_id); + pe_debug("duplicate mac detected!!! Peer " QDF_MAC_ADDR_FMT " present on STA vdev %d", + QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id); sta_peer_present = true; } @@ -2236,9 +2233,9 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in tSirMacCapabilityInfo local_cap; tpDphHashNode sta_ds = NULL; tpSirAssocReq assoc_req; - bool dup_entry = false; - struct wlan_objmgr_vdev *vdev; + bool dup_entry = false, force_1x1 = false; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; lim_get_phy_mode(mac_ctx, &phy_mode, session); @@ -2247,18 +2244,18 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); - pe_nofl_debug("Assoc req RX: subtype %d vdev %d sys role %d lim state %d rssi %d from " QDF_MAC_ADDR_STR, - sub_type, session->vdev_id, GET_LIM_SYSTEM_ROLE(session), - session->limMlmState, - WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_nofl_rl_debug("Assoc req RX: subtype %d vdev %d sys role %d lim state %d rssi %d from " QDF_MAC_ADDR_FMT, + sub_type, session->vdev_id, + GET_LIM_SYSTEM_ROLE(session), session->limMlmState, + WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), + QDF_MAC_ADDR_REF(hdr->sa)); if (LIM_IS_STA_ROLE(session)) { pe_err("Rcvd unexpected ASSOC REQ, sessionid: %d sys sub_type: %d for role: %d from: " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session->peSessionId, sub_type, GET_LIM_SYSTEM_ROLE(session), - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, WMA_GET_RX_MPDU_DATA(rx_pkt_info), frame_len); @@ -2266,14 +2263,13 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in } if (session->limMlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) { pe_err("drop ASSOC REQ on sessionid: %d " - "role: %d from: "QDF_MAC_ADDR_STR" in limMlmState: %d", + "role: %d from: "QDF_MAC_ADDR_FMT" in limMlmState: %d", session->peSessionId, GET_LIM_SYSTEM_ROLE(session), - QDF_MAC_ADDR_ARRAY(hdr->sa), + QDF_MAC_ADDR_REF(hdr->sa), eLIM_MLM_WT_DEL_BSS_RSP_STATE); return; } - vdev = session->vdev; if (!vdev) { pe_err("vdev is NULL"); @@ -2283,6 +2279,7 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP) { pe_err("SAP is not up, drop ASSOC REQ on sessionid: %d", session->peSessionId); + return; } @@ -2306,9 +2303,9 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in if (sta_ds) { if (hdr->fc.retry > 0) { pe_err("STA is initiating Assoc Req after ACK lost. Do not process sessionid: %d sys sub_type=%d for role=%d from: " - QDF_MAC_ADDR_STR, session->peSessionId, + QDF_MAC_ADDR_FMT, session->peSessionId, sub_type, GET_LIM_SYSTEM_ROLE(session), - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); return; } else if (!sta_ds->rmfEnabled && (sub_type == LIM_REASSOC)) { /* @@ -2336,10 +2333,10 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in sub_type, sta_ds, session, false); pe_err("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type: %d for role: %d from: " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session->peSessionId, sub_type, session->limSystemRole, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + QDF_MAC_ADDR_REF(hdr->sa)); return; } } @@ -2371,9 +2368,9 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in * ignore it */ pe_err("Rcvd: %s Req, sessionid: %d from a BC/MC address" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc", - session->peSessionId, QDF_MAC_ADDR_ARRAY(hdr->sa)); + session->peSessionId, QDF_MAC_ADDR_REF(hdr->sa)); return; } @@ -2500,10 +2497,28 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in return; } + if (session->opmode == QDF_P2P_GO_MODE) { + /* + * WAR: In P2P GO mode, if the P2P client device + * is only HT capable and not VHT capable, but the P2P + * GO device is VHT capable and advertises 2x2 NSS with + * HT capablity client device, which results in IOT + * issues. + * When GO is operating in DBS mode, GO beacons + * advertise 2x2 capability but include OMN IE to + * indicate current operating mode of 1x1. But here + * peer device is only HT capable and will not + * understand OMN IE. + */ + force_1x1 = wlan_p2p_check_oui_and_force_1x1( + frm_body + LIM_ASSOC_REQ_IE_OFFSET, + frame_len - LIM_ASSOC_REQ_IE_OFFSET); + } + /* Send assoc indication to SME */ if (!lim_send_assoc_ind_to_sme(mac_ctx, session, sub_type, hdr, assoc_req, akm_type, pmf_connection, - &assoc_req_copied, dup_entry)) + &assoc_req_copied, dup_entry, force_1x1)) goto error; return; @@ -2574,7 +2589,7 @@ static void lim_fill_assoc_ind_vht_info(struct mac_context *mac_ctx, uint8_t i; bool nw_type_11b = true; - if (session_entry->limRFBand == BAND_2G) { + if (session_entry->limRFBand == REG_BAND_2G) { if (session_entry->vhtCapability && assoc_req->VHTCaps.present) assoc_ind->chan_info.info = MODE_11AC_VHT20_2G; else if (session_entry->htCapability @@ -2685,6 +2700,39 @@ static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq, } } +/** + *lim_convert_channel_width_enum() - map between two channel width enums + *@ch_width: channel width of enum type phy_ch_width + * + *Return: channel width of enum type tSirMacHTChannelWidth + */ +static tSirMacHTChannelWidth +lim_convert_channel_width_enum(enum phy_ch_width ch_width) +{ + switch (ch_width) { + case CH_WIDTH_20MHZ: + return eHT_CHANNEL_WIDTH_20MHZ; + case CH_WIDTH_40MHZ: + return eHT_CHANNEL_WIDTH_40MHZ; + case CH_WIDTH_80MHZ: + return eHT_CHANNEL_WIDTH_80MHZ; + case CH_WIDTH_160MHZ: + return eHT_CHANNEL_WIDTH_160MHZ; + case CH_WIDTH_80P80MHZ: + return eHT_CHANNEL_WIDTH_80P80MHZ; + case CH_WIDTH_MAX: + return eHT_MAX_CHANNEL_WIDTH; + case CH_WIDTH_5MHZ: + break; + case CH_WIDTH_10MHZ: + break; + case CH_WIDTH_INVALID: + break; + } + pe_debug("invalid enum: %d", ch_width); + return eHT_CHANNEL_WIDTH_20MHZ; +} + bool lim_fill_lim_assoc_ind_params( tpLimMlmAssocInd assoc_ind, struct mac_context *mac_ctx, @@ -2729,20 +2777,23 @@ bool lim_fill_lim_assoc_ind_params( /* Fill in RSN IE information */ assoc_ind->rsnIE.length = 0; /* if WPS IE is present, ignore RSN IE */ - if (assoc_req->addIEPresent && assoc_req->addIE.length) - wpsie = limGetWscIEPtr(mac_ctx, - assoc_req->addIE.addIEdata, - assoc_req->addIE.length); + if (assoc_req->addIEPresent && assoc_req->addIE.length) { + wpsie = limGetWscIEPtr( + mac_ctx, + assoc_req->addIE.addIEdata, + assoc_req->addIE.length); + } if (assoc_req->rsnPresent && !wpsie) { pe_debug("Assoc Req RSN IE len: %d", assoc_req->rsn.length); assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length; assoc_ind->rsnIE.rsnIEdata[0] = WLAN_ELEMID_RSN; assoc_ind->rsnIE.rsnIEdata[1] = - assoc_req->rsn.length; - qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2], - assoc_req->rsn.info, - assoc_req->rsn.length); + assoc_req->rsn.length; + qdf_mem_copy( + &assoc_ind->rsnIE.rsnIEdata[2], + assoc_req->rsn.info, + assoc_req->rsn.length); } /* Fill in 802.11h related info */ if (assoc_req->powerCapabilityPresent && @@ -2752,8 +2803,9 @@ bool lim_fill_lim_assoc_ind_params( assoc_req->powerCapability.minTxPower; assoc_ind->powerCap.maxTxPower = assoc_req->powerCapability.maxTxPower; - lim_convert_supported_channels(mac_ctx, assoc_ind, - assoc_req); + lim_convert_supported_channels( + mac_ctx, assoc_ind, + assoc_req); } else { assoc_ind->spectrumMgtIndicator = false; } @@ -2780,9 +2832,10 @@ bool lim_fill_lim_assoc_ind_params( assoc_ind->addIE.length = 0; if (assoc_req->addIEPresent) { - qdf_mem_copy(&assoc_ind->addIE.addIEdata, - assoc_req->addIE.addIEdata, - assoc_req->addIE.length); + qdf_mem_copy( + &assoc_ind->addIE.addIEdata, + assoc_req->addIE.addIEdata, + assoc_req->addIE.length); assoc_ind->addIE.length = assoc_req->addIE.length; } /* @@ -2822,16 +2875,12 @@ bool lim_fill_lim_assoc_ind_params( /* Required for indicating the frames to upper layer */ assoc_ind->assocReqLength = assoc_req->assocReqFrameLength; assoc_ind->assocReqPtr = assoc_req->assocReqFrame; - assoc_ind->beaconPtr = session_entry->beacon; assoc_ind->beaconLength = session_entry->bcnLen; - assoc_ind->chan_info.chan_id = - session_entry->currentOperChannel; - assoc_ind->chan_info.mhz = - cds_chan_to_freq(session_entry->currentOperChannel); + assoc_ind->chan_info.mhz = session_entry->curr_op_freq; assoc_ind->chan_info.band_center_freq1 = - cds_chan_to_freq(session_entry->currentOperChannel); + session_entry->curr_op_freq; assoc_ind->chan_info.band_center_freq2 = 0; assoc_ind->chan_info.reg_info_1 = (session_entry->maxTxPower << 16); @@ -2851,16 +2900,16 @@ bool lim_fill_lim_assoc_ind_params( assoc_ind->max_mcs_idx = 0xff; assoc_ind->rx_mcs_map = 0xff; assoc_ind->tx_mcs_map = 0xff; + if (assoc_req->supportedRates.numRates) assoc_ind->max_supp_idx = - lim_get_max_rate_idx( - &assoc_req->supportedRates); + lim_get_max_rate_idx(&assoc_req->supportedRates); if (assoc_req->extendedRates.numRates) assoc_ind->max_ext_idx = - lim_get_max_rate_idx( - &assoc_req->extendedRates); + lim_get_max_rate_idx(&assoc_req->extendedRates); + if (sta_ds->mlmStaContext.htCapability) { - /* ampdu */ + /* ampdu */ assoc_ind->ampdu = true; /* sgi */ @@ -2876,7 +2925,6 @@ bool lim_fill_lim_assoc_ind_params( sta_ds->htSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ; - /* mode */ assoc_ind->mode = SIR_SME_PHY_MODE_HT; maxidx = 0; @@ -2905,7 +2953,10 @@ bool lim_fill_lim_assoc_ind_params( assoc_ind->he_caps_present = assoc_req->he_cap.present; assoc_ind->is_sae_authenticated = assoc_req->is_sae_authenticated; - + /* updates HE bandwidth in assoc indication */ + if (wlan_reg_is_6ghz_chan_freq(session_entry->curr_op_freq)) + assoc_ind->ch_width = + lim_convert_channel_width_enum(sta_ds->ch_width); return true; } @@ -2943,9 +2994,9 @@ QDF_STATUS lim_send_mlm_assoc_ind(struct mac_context *mac_ctx, sub_type = LIM_ASSOC; pe_debug("Sessionid: %d ssid: %s sub_type: %d Associd: %d staAddr: " - QDF_MAC_ADDR_STR, session_entry->peSessionId, + QDF_MAC_ADDR_FMT, session_entry->peSessionId, assoc_req->ssId.ssId, sub_type, sta_ds->assocId, - QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); + QDF_MAC_ADDR_REF(sta_ds->staAddr)); if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) { temp = sizeof(tLimMlmAssocInd); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 8ef0ed122c3d2851309c3bf42cac0339e413ad9f..0c02b3eb2b4e835c5bd605c7c6a1d1d36953bcbc 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -39,14 +39,10 @@ #include "lim_assoc_utils.h" #include "lim_security_utils.h" #include "lim_ser_des_utils.h" -#include "lim_sta_hash_api.h" #include "lim_send_messages.h" #include "lim_process_fils.h" #include "wlan_blm_api.h" -extern QDF_STATUS sch_beacon_edca_process(struct mac_context *mac, - tSirMacEdcaParamSetIE *edca, struct pe_session *pe_session); - /** * lim_update_stads_htcap() - Updates station Descriptor HT capability * @mac_ctx: Pointer to Global MAC structure @@ -133,12 +129,13 @@ static void lim_update_stads_htcap(struct mac_context *mac_ctx, */ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, tSchBeaconStruct *beacon) { uint32_t phy_mode; bool qos_mode; tDot11fIEVHTCaps *vht_caps = NULL; tDot11fIEhe_cap *he_cap = NULL; + struct bss_description *bss_desc = NULL; lim_get_phy_mode(mac_ctx, &phy_mode, session_entry); sta_ds->staType = STA_ENTRY_SELF; @@ -189,15 +186,21 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, } if (IS_DOT11_MODE_HE(session_entry->dot11mode)) - lim_update_stads_he_caps(sta_ds, assoc_rsp, session_entry); + lim_update_stads_he_caps(sta_ds, assoc_rsp, + session_entry, beacon); if (lim_is_sta_he_capable(sta_ds)) he_cap = &assoc_rsp->he_cap; + if (session_entry->lim_join_req) + bss_desc = &session_entry->lim_join_req->bssDescription; + if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates, assoc_rsp->HTCaps.supportedMCSSet, false, session_entry, - vht_caps, he_cap) != QDF_STATUS_SUCCESS) { + vht_caps, he_cap, sta_ds, + bss_desc) != + QDF_STATUS_SUCCESS) { pe_err("could not get rateset and extended rate set"); return; } @@ -471,47 +474,6 @@ static void lim_stop_reassoc_retry_timer(struct mac_context *mac_ctx) lim_deactivate_and_change_timer(mac_ctx, eLIM_REASSOC_FAIL_TIMER); } -#ifdef WLAN_FEATURE_11W -static void -lim_handle_assoc_reject_status(struct mac_context *mac_ctx, - struct pe_session *session_entry, - tpSirAssocRsp assoc_rsp, - tSirMacAddr source_addr) -{ - struct sir_rssi_disallow_lst ap_info = {{0}}; - uint32_t timeout_value = - assoc_rsp->TimeoutInterval.timeoutValue; - - if (!(session_entry->limRmfEnabled && - assoc_rsp->status_code == eSIR_MAC_TRY_AGAIN_LATER && - (assoc_rsp->TimeoutInterval.present && - (assoc_rsp->TimeoutInterval.timeoutType == - SIR_MAC_TI_TYPE_ASSOC_COMEBACK)))) - return; - - /* - * Add to rssi reject list, which takes care of retry - * delay too. Fill the RSSI as 0, so the only param - * which will allow the bssid to connect is retry delay. - */ - ap_info.retry_delay = timeout_value; - qdf_mem_copy(ap_info.bssid.bytes, source_addr, QDF_MAC_ADDR_SIZE); - ap_info.expected_rssi = LIM_MIN_RSSI; - lim_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info); - - pe_debug("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER recvd. Add to time reject list(rssi reject in mac_ctx %d", - timeout_value); -} -#else -static void -lim_handle_assoc_reject_status(struct mac_context *mac_ctx, - struct pe_session *session_entry, - tpSirAssocRsp assoc_rsp, - tSirMacAddr source_addr) -{ -} -#endif - /** * lim_get_nss_supported_by_ap() - finds out nss from AP's beacons * @vht_caps: VHT capabilities @@ -520,9 +482,20 @@ lim_handle_assoc_reject_status(struct mac_context *mac_ctx, * Return: nss advertised by AP in beacon */ static uint8_t lim_get_nss_supported_by_ap(tDot11fIEVHTCaps *vht_caps, - tDot11fIEHTCaps *ht_caps) + tDot11fIEHTCaps *ht_caps, + tDot11fIEhe_cap *he_caps) { - if (vht_caps->present) { + + if (he_caps->present) { + if ((he_caps->rx_he_mcs_map_lt_80 & 0xC0) != 0xC0) + return NSS_4x4_MODE; + + if ((he_caps->rx_he_mcs_map_lt_80 & 0x30) != 0x30) + return NSS_3x3_MODE; + + if ((he_caps->rx_he_mcs_map_lt_80 & 0x0C) != 0x0C) + return NSS_2x2_MODE; + } else if (vht_caps->present) { if ((vht_caps->rxMCSMap & 0xC0) != 0xC0) return NSS_4x4_MODE; @@ -545,13 +518,81 @@ static uint8_t lim_get_nss_supported_by_ap(tDot11fIEVHTCaps *vht_caps, return NSS_1x1_MODE; } -static void clean_up_ft_sha384(tpSirAssocRsp assoc_rsp, bool sha384_akm) +#ifdef WLAN_FEATURE_11AX +static void lim_process_he_info(tpSirProbeRespBeacon beacon, + tpDphHashNode sta_ds) { - if (sha384_akm) { - qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); - qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); + if (beacon->he_op.present) + sta_ds->parsed_ies.he_operation = beacon->he_op; +} +#else +static inline void lim_process_he_info(tpSirProbeRespBeacon beacon, + tpDphHashNode sta_ds) +{ +} +#endif + +#ifdef WLAN_FEATURE_11W + +#define MAX_RETRY_TIMER 1500 +static QDF_STATUS +lim_handle_pmfcomeback_timer(struct pe_session *session_entry, + tpSirAssocRsp assoc_rsp) +{ + uint16_t timeout_value; + + if (session_entry->opmode != QDF_STA_MODE) + return QDF_STATUS_E_FAILURE; + + if (session_entry->limRmfEnabled && + session_entry->pmf_retry_timer_info.retried && + assoc_rsp->status_code == eSIR_MAC_TRY_AGAIN_LATER) { + pe_debug("Already retry in progress"); + return QDF_STATUS_SUCCESS; } + + /* + * Handle association Response for sta mode with RMF enabled and TRY + * again later with timeout interval and Assoc comeback type + */ + if (!session_entry->limRmfEnabled || assoc_rsp->status_code != + eSIR_MAC_TRY_AGAIN_LATER || !assoc_rsp->TimeoutInterval.present || + assoc_rsp->TimeoutInterval.timeoutType != + SIR_MAC_TI_TYPE_ASSOC_COMEBACK || + session_entry->pmf_retry_timer_info.retried) + return QDF_STATUS_E_FAILURE; + + timeout_value = assoc_rsp->TimeoutInterval.timeoutValue; + if (timeout_value < 10) { + /* + * if this value is less than 10 then our timer + * will fail to start and due to this we will + * never re-attempt. Better modify the timer + * value here. + */ + timeout_value = 10; + } + timeout_value = QDF_MIN(MAX_RETRY_TIMER, timeout_value); + pe_debug("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER recvd.Starting timer to wait timeout: %d", + timeout_value); + if (QDF_STATUS_SUCCESS != + qdf_mc_timer_start(&session_entry->pmf_retry_timer, + timeout_value)) { + pe_err("Failed to start comeback timer"); + return QDF_STATUS_E_FAILURE; + } + session_entry->pmf_retry_timer_info.retried = true; + + return QDF_STATUS_SUCCESS; } +#else +static QDF_STATUS +lim_handle_pmfcomeback_timer(struct pe_session *session_entry, + tpSirAssocRsp assoc_rsp) +{ + return QDF_STATUS_E_FAILURE; +} +#endif /** * lim_process_assoc_rsp_frame() - Processes assoc response @@ -581,16 +622,15 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, tLimMlmAssocCnf assoc_cnf; tSchBeaconStruct *beacon; #ifdef WLAN_FEATURE_ROAM_OFFLOAD - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; struct csr_roam_session *roam_session; #endif uint8_t ap_nss; int8_t rssi; - enum ani_akm_type auth_type; - bool sha384_akm; + QDF_STATUS status; #ifdef WLAN_FEATURE_ROAM_OFFLOAD - sme_sessionid = session_entry->smeSessionId; + vdev_id = session_entry->vdev_id; #endif assoc_cnf.resultCode = eSIR_SME_SUCCESS; /* Update PE session Id */ @@ -613,7 +653,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, } else { hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); - rssi = (uint)abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info)); + rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); } if (!hdr) { @@ -621,11 +661,11 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, return; } - pe_nofl_info("Assoc rsp RX: subtype %d vdev %d sys role %d lim state %d rssi %d from " QDF_MAC_ADDR_STR, - subtype, session_entry->vdev_id, - GET_LIM_SYSTEM_ROLE(session_entry), - session_entry->limMlmState, rssi, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_nofl_rl_info("Assoc rsp RX: subtype %d vdev %d sys role %d lim state %d rssi %d from " QDF_MAC_ADDR_FMT, + subtype, session_entry->vdev_id, + GET_LIM_SYSTEM_ROLE(session_entry), + session_entry->limMlmState, rssi, + QDF_MAC_ADDR_REF(hdr->sa)); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, (uint8_t *)hdr, frame_len + SIR_MAC_HDR_LEN_3A); @@ -665,8 +705,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, * other than one to which request was initiated. * Ignore this and wait until Assoc Failure Timeout */ - pe_warn("received AssocRsp from unexpected peer "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_warn("received AssocRsp from unexpected peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); qdf_mem_free(beacon); return; } @@ -679,8 +719,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, * other than one to which request was initiated. * Ignore this and wait until Reassoc Failure Timeout. */ - pe_warn("received ReassocRsp from unexpected peer "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_warn("received ReassocRsp from unexpected peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); qdf_mem_free(beacon); return; } @@ -737,7 +777,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, #ifdef WLAN_FEATURE_ROAM_OFFLOAD roam_session = - &mac_ctx->roam.roamSession[sme_sessionid]; + &mac_ctx->roam.roamSession[vdev_id]; if (assoc_rsp->sha384_ft_subelem.r0kh_id.present) { roam_session->ftSmeContext.r0kh_id_len = assoc_rsp->sha384_ft_subelem.r0kh_id.num_PMK_R0_ID; @@ -761,26 +801,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, lim_update_ese_tspec(mac_ctx, session_entry, assoc_rsp); #endif - auth_type = session_entry->connected_akm; - sha384_akm = lim_is_sha384_akm(auth_type); - - if (assoc_rsp->capabilityInfo.ibss) { - /* - * Received Re/Association Response from peer - * with IBSS capability set. - * Ignore the frame and wait until Re/assoc - * failure timeout. - */ - pe_err("received Re/AssocRsp frame with IBSS capability"); - clean_up_ft_sha384(assoc_rsp, sha384_akm); - qdf_mem_free(assoc_rsp); - qdf_mem_free(beacon); - return; - } - if (lim_get_capability_info(mac_ctx, &caps, session_entry) != QDF_STATUS_SUCCESS) { - clean_up_ft_sha384(assoc_rsp, sha384_akm); qdf_mem_free(assoc_rsp); qdf_mem_free(beacon); pe_err("could not retrieve Capabilities"); @@ -788,19 +810,11 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, } lim_copy_u16((uint8_t *) &mac_capab, caps); - /* Stop Association failure timer */ - if (subtype == LIM_ASSOC) - lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); - else - lim_stop_reassoc_retry_timer(mac_ctx); - - lim_handle_assoc_reject_status(mac_ctx, session_entry, assoc_rsp, - hdr->sa); - if (eSIR_MAC_XS_FRAME_LOSS_POOR_CHANNEL_RSSI_STATUS == assoc_rsp->status_code && assoc_rsp->rssi_assoc_rej.present) { struct sir_rssi_disallow_lst ap_info = {{0}}; + if (!assoc_rsp->rssi_assoc_rej.retry_delay) ap_info.expected_rssi = assoc_rsp->rssi_assoc_rej.delta_rssi + WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info) + @@ -808,11 +822,31 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, else ap_info.expected_rssi = assoc_rsp->rssi_assoc_rej.delta_rssi + WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); + ap_info.retry_delay = assoc_rsp->rssi_assoc_rej.retry_delay * QDF_MC_TIMER_TO_MS_UNIT; qdf_mem_copy(ap_info.bssid.bytes, hdr->sa, QDF_MAC_ADDR_SIZE); + ap_info.reject_reason = REASON_ASSOC_REJECT_OCE; + ap_info.source = ADDED_BY_DRIVER; + ap_info.original_timeout = ap_info.retry_delay; + ap_info.received_time = qdf_mc_timer_get_system_time(); lim_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info); } + + status = lim_handle_pmfcomeback_timer(session_entry, assoc_rsp); + /* return if retry again timer is started and ignore this assoc resp */ + if (QDF_IS_STATUS_SUCCESS(status)) { + qdf_mem_free(beacon); + qdf_mem_free(assoc_rsp); + return; + } + + /* Stop Association failure timer */ + if (subtype == LIM_ASSOC) + lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); + else + lim_stop_reassoc_retry_timer(mac_ctx); + if (assoc_rsp->status_code != eSIR_MAC_SUCCESS_STATUS) { /* *Re/Association response was received @@ -862,27 +896,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, goto assocReject; } - /* - * Association Response received with success code - * Set the link state to POSTASSOC now that we have received - * assoc/reassoc response - * NOTE: for BTAMP case, it is being handled in - * lim_process_mlm_assoc_req - */ - if (!lim_is_roam_synch_in_progress(session_entry)) { - if (lim_set_link_state - (mac_ctx, eSIR_LINK_POSTASSOC_STATE, - session_entry->bssId, - session_entry->self_mac_addr, NULL, - NULL) != QDF_STATUS_SUCCESS) { - pe_err("Set link state to POSTASSOC failed"); - qdf_mem_free(beacon); - clean_up_ft_sha384(assoc_rsp, sha384_akm); - qdf_mem_free(assoc_rsp); - return; - } - } - if (assoc_rsp->QosMapSet.present) qdf_mem_copy(&session_entry->QosMapSet, &assoc_rsp->QosMapSet, @@ -901,7 +914,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, QDF_STATUS_SUCCESS), assoc_rsp->status_code); ap_nss = lim_get_nss_supported_by_ap(&assoc_rsp->VHTCaps, - &assoc_rsp->HTCaps); + &assoc_rsp->HTCaps, + &assoc_rsp->he_cap); if (subtype == LIM_REASSOC) { pe_debug("Successfully Reassociated with BSS"); @@ -951,7 +965,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, lim_is_roam_synch_in_progress(session_entry)) { pe_debug("Sending self sta"); lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, - session_entry); + session_entry, NULL); lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds); /* Store assigned AID for TIM processing */ @@ -964,7 +978,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, if (!lim_is_roam_synch_in_progress(session_entry)) { lim_send_edca_params(mac_ctx, session_entry->gLimEdcaParamsActive, - sta_ds->bssId, false); + session_entry->vdev_id, false); lim_add_ft_sta_self(mac_ctx, (assoc_rsp->aid & 0x3FFF), session_entry); @@ -1004,8 +1018,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, qdf_mem_free(beacon); return; } - pe_debug("Successfully Associated with BSS " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(hdr->sa)); + pe_debug("Successfully Associated with BSS " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(hdr->sa)); #ifdef FEATURE_WLAN_ESE if (session_entry->eseContext.tsm.tsmInfo.state) session_entry->eseContext.tsm.tsmMetrics.RoamingCount = 0; @@ -1024,7 +1038,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, assoc_cnf.protStatusCode = eSIR_SME_SUCCESS; lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, (uint32_t *) &assoc_cnf); - clean_up_ft_sha384(assoc_rsp, sha384_akm); qdf_mem_free(assoc_rsp); qdf_mem_free(beacon); return; @@ -1040,17 +1053,18 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, session_entry->smeSessionId, session_entry->nss); - lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, session_entry); /* * Extract the AP capabilities from the beacon that * was received earlier - */ + */ ie_len = lim_get_ielen_from_bss_description( &session_entry->lim_join_req->bssDescription); lim_extract_ap_capabilities(mac_ctx, (uint8_t *)session_entry->lim_join_req->bssDescription.ieFields, ie_len, beacon); + lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, + session_entry, beacon); if (lim_is_session_he_capable(session_entry)) { session_entry->mu_edca_present = assoc_rsp->mu_edca_present; if (session_entry->mu_edca_present) { @@ -1078,6 +1092,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, if (beacon->VHTOperation.present) sta_ds->parsed_ies.vht_operation = beacon->VHTOperation; + lim_process_he_info(beacon, sta_ds); + if (mac_ctx->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) lim_decide_sta_protection_on_assoc(mac_ctx, beacon, @@ -1100,7 +1116,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, beacon, &session_entry->lim_join_req->bssDescription, true, session_entry)) { - clean_up_ft_sha384(assoc_rsp, sha384_akm); qdf_mem_free(assoc_rsp); qdf_mem_free(beacon); return; @@ -1116,10 +1131,10 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, && (session_entry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) { pe_err("Assoc Rejected by the peer mlmestate: %d sessionid: %d Reason: %d MACADDR:" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session_entry->limMlmState, session_entry->peSessionId, - assoc_cnf.resultCode, QDF_MAC_ADDR_ARRAY(hdr->sa)); + assoc_cnf.resultCode, QDF_MAC_ADDR_REF(hdr->sa)); session_entry->limMlmState = eLIM_MLM_IDLE_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c index 570d8994272ede8f49668e00ecc44bda6f5c870c..4805c6d7ca75bf8a6f1d76d3ac0ca43c55d95fb2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -103,7 +103,6 @@ static inline unsigned int is_auth_valid(struct mac_context *mac, * * Return: QDF_STATUS */ -#ifdef CRYPTO_SET_KEY_CONVERGED static QDF_STATUS lim_get_wep_key_sap(struct pe_session *pe_session, struct wlan_mlme_wep_cfg *wep_params, uint8_t key_id, @@ -116,20 +115,6 @@ static QDF_STATUS lim_get_wep_key_sap(struct pe_session *pe_session, default_key, key_len); } -#else -static QDF_STATUS lim_get_wep_key_sap(struct pe_session *pe_session, - struct wlan_mlme_wep_cfg *wep_params, - uint8_t key_id, - uint8_t *default_key, - qdf_size_t *key_len) -{ - *key_len = pe_session->WEPKeyMaterial[key_id].key[0].keyLength; - qdf_mem_copy(default_key, pe_session->WEPKeyMaterial[key_id].key[0].key, - *key_len); - - return QDF_STATUS_SUCCESS; -} -#endif static void lim_process_auth_shared_system_algo(struct mac_context *mac_ctx, tpSirMacMgmtHdr mac_hdr, @@ -151,9 +136,9 @@ static void lim_process_auth_shared_system_algo(struct mac_context *mac_ctx, cfg_privacy_opt_imp = (uint8_t) val; if (!cfg_privacy_opt_imp) { pe_err("rx Auth frame for unsupported auth algorithm %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Authenticator does not have WEP @@ -336,12 +321,12 @@ static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx, /* Create entry for this STA in pre-auth list */ auth_node = lim_acquire_free_pre_auth_node(mac_ctx, preauth_table); if (!auth_node) { - pe_debug("Max pre-auth nodes reached " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + pe_debug("Max pre-auth nodes reached " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } - pe_debug("Creating preauth node for SAE peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + pe_debug("Creating preauth node for SAE peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); qdf_mem_copy((uint8_t *)auth_node->peerMacAddr, mac_hdr->sa, sizeof(tSirMacAddr)); auth_node->mlmState = mlm_state; @@ -353,6 +338,64 @@ static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx, lim_add_pre_auth_node(mac_ctx, auth_node); } +void lim_sae_auth_cleanup_retry(struct mac_context *mac_ctx, + uint8_t vdev_id) +{ + struct pe_session *pe_session; + + pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); + if (!pe_session) { + pe_err("session not found for given vdev_id %d", vdev_id); + return; + } + + pe_debug("sae auth cleanup for vdev_id %d", vdev_id); + lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); + mlme_free_sae_auth_retry(pe_session->vdev); +} + +#define SAE_AUTH_ALGO_BYTES 2 +#define SAE_AUTH_SEQ_NUM_BYTES 2 +#define SAE_AUTH_SEQ_OFFSET 1 + +/** + * lim_is_sae_auth_algo_match()- Match SAE auth seq in queued SAE auth and + * SAE auth rx frame + * @queued_frame: Pointer to queued SAE auth retry frame + * @q_len: length of queued sae auth retry frame + * @rx_pkt_info: Rx packet + * + * Return: True if SAE auth seq is mached else false + */ +static bool lim_is_sae_auth_algo_match(uint8_t *queued_frame, uint16_t q_len, + uint8_t *rx_pkt_info) +{ + tpSirMacMgmtHdr qmac_hdr = (tpSirMacMgmtHdr)queued_frame; + uint16_t *rxbody_ptr, *qbody_ptr, rxframe_len, min_len; + + min_len = sizeof(tSirMacMgmtHdr) + SAE_AUTH_ALGO_BYTES + + SAE_AUTH_SEQ_NUM_BYTES; + + rxframe_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); + if (rxframe_len < min_len || q_len < min_len) { + pe_debug("rxframe_len %d, queued_frame_len %d, min_len %d", + rxframe_len, q_len, min_len); + return false; + } + + rxbody_ptr = (uint16_t *)WMA_GET_RX_MPDU_DATA(rx_pkt_info); + qbody_ptr = (uint16_t *)((uint8_t *)qmac_hdr + sizeof(tSirMacMgmtHdr)); + + pe_debug("sae_auth : rx pkt auth seq %d queued pkt auth seq %d", + rxbody_ptr[SAE_AUTH_SEQ_OFFSET], + qbody_ptr[SAE_AUTH_SEQ_OFFSET]); + if (rxbody_ptr[SAE_AUTH_SEQ_OFFSET] == + qbody_ptr[SAE_AUTH_SEQ_OFFSET]) + return true; + + return false; +} + /** * lim_process_sae_auth_frame()-Process SAE authentication frame * @mac_ctx: MAC context @@ -368,13 +411,15 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, uint32_t frame_len; uint8_t *body_ptr; enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE; + struct sae_auth_retry *sae_retry; mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); - pe_nofl_info("Received SAE Auth frame type %d subtype %d", - mac_hdr->fc.type, mac_hdr->fc.subType); + pe_nofl_rl_info("SAE Auth RX type %d subtype %d from " QDF_MAC_ADDR_FMT, + mac_hdr->fc.type, mac_hdr->fc.subType, + QDF_MAC_ADDR_REF(mac_hdr->sa)); if (LIM_IS_STA_ROLE(pe_session) && pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE) @@ -403,11 +448,20 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, } } + sae_retry = mlme_get_sae_auth_retry(pe_session->vdev); + if (LIM_IS_STA_ROLE(pe_session) && sae_retry && + sae_retry->sae_auth.data) { + if (lim_is_sae_auth_algo_match( + sae_retry->sae_auth.data, sae_retry->sae_auth.len, + rx_pkt_info)) + lim_sae_auth_cleanup_retry(mac_ctx, + pe_session->vdev_id); + } lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType, (uint8_t *)mac_hdr, frame_len + sizeof(tSirMacMgmtHdr), pe_session->smeSessionId, - WMA_GET_RX_CH(rx_pkt_info), pe_session, + WMA_GET_RX_FREQ(rx_pkt_info), pe_session, WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), rx_flags); } @@ -443,8 +497,8 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, &pMlmDisassocReq->peer_macaddr.bytes, QDF_MAC_ADDR_SIZE))) { pe_debug("TODO:Ack for disassoc frame is pending Issue delsta for " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( pMlmDisassocReq->peer_macaddr.bytes)); lim_process_disassoc_ack_timeout(mac_ctx); is_connected = false; @@ -456,8 +510,8 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, &pMlmDeauthReq->peer_macaddr.bytes, QDF_MAC_ADDR_SIZE))) { pe_debug("TODO:Ack for deauth frame is pending Issue delsta for " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( pMlmDeauthReq->peer_macaddr.bytes)); lim_process_deauth_ack_timeout(mac_ctx); is_connected = false; @@ -483,9 +537,9 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, #endif ) { pe_err("STA is already connected but received auth frame" - "Send the Deauth and lim Delete Station Context" - "(staId: %d, associd: %d) ", - sta_ds_ptr->staIndex, associd); + "Send the Deauth and lim Delete Station Context" + "(associd: %d) sta mac" QDF_MAC_ADDR_FMT, + associd, QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, (uint8_t *) mac_hdr->sa, @@ -547,8 +601,9 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, && !sta_ds_ptr->rmfEnabled #endif ) { - pe_debug("lim Delete Station Context staId: %d associd: %d", - sta_ds_ptr->staIndex, associd); + pe_debug("lim Del Sta Ctx associd: %d sta mac" + QDF_MAC_ADDR_FMT, associd, + QDF_MAC_ADDR_REF(sta_ds_ptr->staAddr)); lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, (uint8_t *)auth_node->peerMacAddr, @@ -581,9 +636,15 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, if (lim_is_auth_algo_supported(mac_ctx, (tAniAuthType) rx_auth_frm_body->authAlgoNumber, pe_session)) { - - if (lim_get_session_by_macaddr(mac_ctx, mac_hdr->sa)) { - + struct wlan_objmgr_vdev *vdev; + + vdev = + wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev, + mac_hdr->sa, + WLAN_LEGACY_MAC_ID); + /* SA is same as any of the device vdev, return failure */ + if (vdev) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber; auth_frame->authTransactionSeqNumber = @@ -609,9 +670,9 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, break; default: pe_err("rx Auth frm for unsupported auth algo %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Responding party does not support the @@ -633,9 +694,9 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx, } } else { pe_err("received Authentication frame for unsupported auth algorithm %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Responding party does not support the @@ -689,8 +750,9 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, mac_hdr->sa, sizeof(tSirMacAddr)))) { /* Update the FTIEs in the saved auth response */ - pe_warn("rx PreAuth frm2 in smestate: %d from: %pM", - pe_session->limSmeState, mac_hdr->sa); + pe_warn("rx PreAuth frm2 in smestate: %d from: "QDF_MAC_ADDR_FMT, + pe_session->limSmeState, + QDF_MAC_ADDR_REF(mac_hdr->sa)); pe_session->ftPEContext.saved_auth_rsp_length = 0; if ((body_ptr) && (frame_len < MAX_FTIE_SIZE)) { @@ -722,7 +784,7 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, */ pe_warn("received Auth frame2 from unexpected peer" - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -761,9 +823,9 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, */ pe_warn("rx Auth frame2 for unexpected auth algo %d" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } } @@ -774,9 +836,9 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, * Return Auth confirm with received failure code to SME */ pe_err("rx Auth frame from peer with failure code %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authStatusCode, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED, rx_auth_frm_body->authStatusCode, pe_session); @@ -800,7 +862,8 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, return; } - pe_debug("add new auth node: for %pM", mac_hdr->sa); + pe_debug("add new auth node: for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); qdf_mem_copy((uint8_t *) auth_node->peerMacAddr, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, sizeof(tSirMacAddr)); @@ -829,9 +892,9 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx, */ pe_err("rx Auth frm from peer for unsupported auth algo %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber; @@ -933,9 +996,9 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, /* AuthFrame 3 */ if (rx_auth_frm_body->authAlgoNumber != eSIR_SHARED_KEY) { pe_err("rx Auth frame3 from peer with auth algo number %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Received Authentication frame3 with algorithm other than * Shared Key authentication type. Reject with Auth frame4 @@ -960,8 +1023,8 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, */ if (!mac_hdr->fc.wep) { pe_err("received Auth frame3 from peer with no WEP bit set " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* WEP bit is not set in FC of Auth Frame3 */ auth_frame->authAlgoNumber = eSIR_SHARED_KEY; auth_frame->authTransactionSeqNumber = @@ -978,8 +1041,8 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa); if (!auth_node) { pe_warn("received AuthFrame3 from peer that has no preauth context " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * No 'pre-auth' context exists for this STA that sent * an Authentication frame3. Send Auth frame4 with @@ -998,8 +1061,8 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, if (auth_node->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) { pe_warn("auth response timer timedout for peer " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Received Auth Frame3 after Auth Response timeout. * Reject by sending Auth Frame4 with @@ -1026,9 +1089,9 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, * to delete STA context. */ pe_err("rx Auth frm3 from peer with status code %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authStatusCode, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } /* @@ -1061,8 +1124,8 @@ static void lim_process_auth_frame_type3(struct mac_context *mac_ctx, pe_session); return; } else { - pe_warn("Challenge failure for peer "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + pe_warn("Challenge failure for peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Challenge Failure. * Send Authentication frame4 with 'challenge failure' @@ -1096,9 +1159,9 @@ static void lim_process_auth_frame_type4(struct mac_context *mac_ctx, * Log error and ignore the frame. */ pe_warn("received unexpected Auth frame4 from peer in state %d, addr " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, pe_session->limMlmState, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -1110,9 +1173,9 @@ static void lim_process_auth_frame_type4(struct mac_context *mac_ctx, * failure to SME. */ pe_err("received Auth frame4 from peer with invalid auth algo %d" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authAlgoNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -1125,8 +1188,8 @@ static void lim_process_auth_frame_type4(struct mac_context *mac_ctx, * Wait until Authentication Failure Timeout. */ - pe_warn("received Auth frame4 from unexpected peer "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + pe_warn("received Auth frame4 from unexpected peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -1139,9 +1202,9 @@ static void lim_process_auth_frame_type4(struct mac_context *mac_ctx, */ pe_err("received Authentication frame from peer with invalid auth seq number %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, rx_auth_frm_body->authTransactionSeqNumber, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -1175,8 +1238,8 @@ static void lim_process_auth_frame_type4(struct mac_context *mac_ctx, * Authentication failure. * Return Auth confirm with received failure code to SME */ - pe_err("Authentication failure from peer "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + pe_err("Authentication failure from peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED, rx_auth_frm_body->authStatusCode, pe_session); @@ -1239,8 +1302,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (!frame_len) { /* Log error */ - pe_err("received Auth frame with no body from: %pM", - mac_hdr->sa); + pe_err("received Auth frame with no body from: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } @@ -1249,22 +1312,25 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, * Received Auth frame from a BC/MC address * Log error and ignore it */ - pe_err("received Auth frame from a BC/MC addr: %pM", - mac_hdr->sa); + pe_err("received Auth frame from a BC/MC addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } curr_seq_num = (mac_hdr->seqControl.seqNumHi << 4) | (mac_hdr->seqControl.seqNumLo); if (pe_session->prev_auth_seq_num == curr_seq_num && + !qdf_mem_cmp(pe_session->prev_auth_mac_addr, &mac_hdr->sa, + ETH_ALEN) && mac_hdr->fc.retry) { pe_debug("auth frame, seq num: %d is already processed, drop it", curr_seq_num); return; } - /* save seq number in pe_session */ + /* save seq number and mac_addr in pe_session */ pe_session->prev_auth_seq_num = curr_seq_num; + qdf_mem_copy(pe_session->prev_auth_mac_addr, mac_hdr->sa, ETH_ALEN); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); @@ -1274,12 +1340,12 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, } auth_alg = *(uint16_t *) body_ptr; - pe_nofl_info("Auth RX: vdev %d sys role %d lim_state %d from " QDF_MAC_ADDR_STR " rssi %d auth_alg %d seq %d", - pe_session->vdev_id, GET_LIM_SYSTEM_ROLE(pe_session), - pe_session->limMlmState, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa), - WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), - auth_alg, curr_seq_num); + pe_nofl_rl_info("Auth RX: vdev %d sys role %d lim_state %d from " QDF_MAC_ADDR_FMT " rssi %d auth_alg %d seq %d", + pe_session->vdev_id, GET_LIM_SYSTEM_ROLE(pe_session), + pe_session->limMlmState, + QDF_MAC_ADDR_REF(mac_hdr->sa), + WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), + auth_alg, curr_seq_num); /* Restore default failure timeout */ if (QDF_P2P_CLIENT_MODE == pe_session->opmode && @@ -1322,8 +1388,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, */ if (pe_session->bTkipCntrMeasActive && LIM_IS_AP_ROLE(pe_session)) { - pe_err("Tkip counter enabled, send deauth to: %pM", - mac_hdr->sa); + pe_err("Tkip counter enabled, send deauth to: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, mac_hdr->sa, pe_session, false); @@ -1351,8 +1417,9 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, auth_frame->authStatusCode = eSIR_MAC_CHALLENGE_FAILURE_STATUS; /* Log error */ - pe_err("rx Auth frm with wep bit set role: %d %pM", - GET_LIM_SYSTEM_ROLE(pe_session), mac_hdr->sa); + pe_err("rx Auth frm with wep bit set role: %d "QDF_MAC_ADDR_FMT, + GET_LIM_SYSTEM_ROLE(pe_session), + QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_send_auth_mgmt_frame(mac_ctx, auth_frame, mac_hdr->sa, LIM_NO_WEP_IN_FC, pe_session); @@ -1379,8 +1446,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (!cfg_privacy_opt_imp) { pe_err("received Authentication frame3 from peer that while privacy option is turned OFF " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Privacy option is not implemented. * So reject Authentication frame received with @@ -1408,8 +1475,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa); if (!auth_node) { pe_err("rx Auth frame with no preauth ctx with WEP bit set " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * No 'pre-auth' context exists for this STA * that sent an Authentication frame with FC @@ -1435,9 +1502,9 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, (auth_node->mlmState != eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) { pe_err("received Authentication frame from peer that is in state %d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, auth_node->mlmState, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* * Should not have received Authentication frame * with WEP bit set in FC in other states. @@ -1496,8 +1563,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, SIR_MAC_WEP_IV_LENGTH)); if (decrypt_result == LIM_DECRYPT_ICV_FAIL) { pe_err("received Authentication frame from peer that failed decryption: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_hdr->sa)); /* ICV failure */ lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa); auth_frame->authAlgoNumber = eSIR_SHARED_KEY; @@ -1583,9 +1650,9 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, break; default: /* Invalid Authentication Frame received. Ignore it. */ - pe_warn("rx auth frm with invalid authseq no: %d from: %pM", + pe_warn("rx auth frm with invalid authseq no: %d from: "QDF_MAC_ADDR_FMT, rx_auth_frm_body->authTransactionSeqNumber, - mac_hdr->sa); + QDF_MAC_ADDR_REF(mac_hdr->sa)); break; } free: @@ -1613,7 +1680,8 @@ bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt) { tpSirMacMgmtHdr dot11_hdr; uint16_t auth_alg, frm_len; - uint8_t *frm_body; + uint8_t *frm_body, pdev_id; + struct wlan_objmgr_vdev *vdev; dot11_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt); frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt); @@ -1632,12 +1700,19 @@ bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt) ((dot11_hdr->seqControl.seqNumHi << 8) | (dot11_hdr->seqControl.seqNumLo << 4) | (dot11_hdr->seqControl.fragNum)), *(uint16_t *)(frm_body + 2)); + pdev_id = wlan_objmgr_pdev_get_pdev_id(mac->pdev); + vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc( + mac->psoc, pdev_id, dot11_hdr->da, WLAN_LEGACY_SME_ID); + if (vdev) { + lim_sae_auth_cleanup_retry(mac, vdev->vdev_objmgr.vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + } lim_send_sme_mgmt_frame_ind(mac, dot11_hdr->fc.subType, (uint8_t *)dot11_hdr, frm_len + sizeof(tSirMacMgmtHdr), SME_SESSION_ID_ANY, - WMA_GET_RX_CH(rx_pkt), NULL, + WMA_GET_RX_FREQ(rx_pkt), NULL, WMA_GET_RX_RSSI_NORMALIZED(rx_pkt), RXMGMT_FLAG_NONE); return true; @@ -1668,8 +1743,8 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *p pBody = WMA_GET_RX_MPDU_DATA(pBd); frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd); - pe_debug("Auth Frame Received: BSSID " QDF_MAC_ADDR_STR " (RSSI %d)", - QDF_MAC_ADDR_ARRAY(pHdr->bssId), + pe_debug("Auth Frame Received: BSSID " QDF_MAC_ADDR_FMT " (RSSI %d)", + QDF_MAC_ADDR_REF(pHdr->bssId), (uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pBd))); if (frameLen == 0) { diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_beacon_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_beacon_frame.c index c14e5310558ab3e09a24b522c4ea08ddf73627dd..b14b6376f130985ac1a3e4ff7d116c6885bb270f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_beacon_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_beacon_frame.c @@ -59,6 +59,9 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, { tpSirMacMgmtHdr mac_hdr; tSchBeaconStruct *bcn_ptr; + uint8_t *frame; + const uint8_t *owe_transition_ie; + uint16_t frame_len; mac_ctx->lim.gLimNumBeaconsRcvd++; @@ -67,10 +70,12 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, * beacon counter */ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); + frame = WMA_GET_RX_MPDU_DATA(rx_pkt_info); + frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info); - pe_debug("Beacon (len %d): " QDF_MAC_ADDR_STR " RSSI %d", + pe_debug("Beacon (len %d): " QDF_MAC_ADDR_FMT " RSSI %d", WMA_GET_RX_MPDU_LEN(rx_pkt_info), - QDF_MAC_ADDR_ARRAY(mac_hdr->sa), + QDF_MAC_ADDR_REF(mac_hdr->sa), (uint)abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info))); @@ -114,6 +119,19 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) { + owe_transition_ie = wlan_get_vendor_ie_ptr_from_oui( + OWE_TRANSITION_OUI_TYPE, + OWE_TRANSITION_OUI_SIZE, + frame + SIR_MAC_B_PR_SSID_OFFSET, + frame_len - SIR_MAC_B_PR_SSID_OFFSET); + if (session->connected_akm == ANI_AKM_TYPE_OWE && + owe_transition_ie) { + pe_debug("vdev:%d Drop OWE rx beacon. Wait for probe for join success", + session->vdev_id); + qdf_mem_free(bcn_ptr); + return; + } + if (session->beacon) { qdf_mem_free(session->beacon); session->beacon = NULL; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_cfg_updates.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_cfg_updates.c index a975af7fdb9d55ffaeb74232e86e4786d9eaaa06..31f1be6d43b6ae1a86a88d52b0bc6431cff4cd1a 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_cfg_updates.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_cfg_updates.c @@ -233,7 +233,5 @@ static void lim_update_config(struct mac_context *mac, struct pe_session *pe_ses if (pe_session->limWsmEnabled && LIM_IS_AP_ROLE(pe_session)) pe_session->limHcfEnabled = 1; - pe_session->lim11dEnabled = mac->mlme_cfg->gen.enabled_11d ? 1 : 0; - pe_debug("Updated Lim shadow state based on CFG"); } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_deauth_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_deauth_frame.c index 6bd2d0d4a3d35fbde0f3e3399af2c9408ba8b50d..b1ab6715309209e9838a82c9641824cc07fc19a8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_deauth_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_deauth_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -75,11 +75,13 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo); frame_rssi = (int32_t)WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); +#ifdef WLAN_FEATURE_11W frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); if (frameLen < sizeof(reasonCode)) { pe_err("Deauth Frame length invalid %d", frameLen); return ; } +#endif if (LIM_IS_STA_ROLE(pe_session) && ((eLIM_SME_WT_DISASSOC_STATE == pe_session->limSmeState) || @@ -147,11 +149,12 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Get reasonCode from Deauthentication frame body */ reasonCode = sir_read_u16(pBody); - pe_nofl_info("Deauth RX: vdev %d from %pM for %pM RSSI = %d reason %d mlm state = %d, sme state = %d systemrole = %d ", - pe_session->vdev_id, pHdr->sa, pHdr->da, frame_rssi, - reasonCode, pe_session->limMlmState, - pe_session->limSmeState, - GET_LIM_SYSTEM_ROLE(pe_session)); + pe_nofl_rl_info("Deauth RX: vdev %d from " QDF_MAC_ADDR_FMT " for " QDF_MAC_ADDR_FMT " RSSI = %d reason %d mlm state = %d, sme state = %d systemrole = %d ", + pe_session->vdev_id, QDF_MAC_ADDR_REF(pHdr->sa), + QDF_MAC_ADDR_REF(pHdr->da), frame_rssi, + reasonCode, pe_session->limMlmState, + pe_session->limSmeState, + GET_LIM_SYSTEM_ROLE(pe_session)); lim_diag_event_report(mac, WLAN_PE_DIAG_DEAUTH_FRAME_EVENT, pe_session, 0, reasonCode); @@ -174,8 +177,8 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Invalid reasonCode in received Deauthentication frame */ /* Log error and ignore the frame */ pe_err("received Deauth frame with invalid reasonCode %d from " - QDF_MAC_ADDR_STR, reasonCode, - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_FMT, reasonCode, + QDF_MAC_ADDR_REF(pHdr->sa)); break; } @@ -194,8 +197,8 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Invalid reasonCode in received Deauth frame */ /* Log error and ignore the frame */ pe_err("received Deauth frame with invalid reasonCode %d from " - QDF_MAC_ADDR_STR, reasonCode, - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_FMT, reasonCode, + QDF_MAC_ADDR_REF(pHdr->sa)); break; } @@ -203,9 +206,9 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Received Deauth frame in either IBSS */ /* or un-known role. Log and ignore it */ pe_err("received Deauth frame with reasonCode %d in role %d from " - QDF_MAC_ADDR_STR, reasonCode, + QDF_MAC_ADDR_FMT, reasonCode, GET_LIM_SYSTEM_ROLE(pe_session), - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_REF(pHdr->sa)); return; } @@ -258,10 +261,10 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, } if (!IS_REASSOC_BSSID(mac, pHdr->sa, pe_session)) { pe_debug("Rcv Deauth from unknown/different " - "AP while ReAssoc. Ignore " QDF_MAC_ADDR_STR - "limReAssocbssId : " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pHdr->sa), - QDF_MAC_ADDR_ARRAY(pe_session->limReAssocbssId)); + "AP while ReAssoc. Ignore " QDF_MAC_ADDR_FMT + "limReAssocbssId : " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pHdr->sa), + QDF_MAC_ADDR_REF(pe_session->limReAssocbssId)); return; } @@ -270,10 +273,10 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, */ if (!IS_CURRENT_BSSID(mac, pHdr->sa, pe_session)) { pe_debug("received DeAuth from the New AP to " - "which ReAssoc is sent " QDF_MAC_ADDR_STR - "pe_session->bssId: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pHdr->sa), - QDF_MAC_ADDR_ARRAY(pe_session->bssId)); + "which ReAssoc is sent " QDF_MAC_ADDR_FMT + "pe_session->bssId: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pHdr->sa), + QDF_MAC_ADDR_REF(pe_session->bssId)); lim_restore_pre_reassoc_state(mac, eSIR_SME_REASSOC_REFUSED, @@ -290,7 +293,7 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, if (!IS_CURRENT_BSSID(mac, pHdr->bssId, pe_session)) { pe_err("received DeAuth from an AP other " "than we're trying to join. Ignore. " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(pHdr->sa)); if (lim_search_pre_auth_list(mac, pHdr->sa)) { pe_debug("Preauth entry exist. Deleting"); @@ -324,7 +327,6 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi tLimMlmAssocCnf mlmAssocCnf; uint16_t aid; tpDphHashNode sta_ds; - tpSirAssocRsp assoc_rsp; sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid, &pe_session->dph.dphHashTable); @@ -344,9 +346,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi */ pe_debug("received Deauth frame state %X with failure " - "code %d from " QDF_MAC_ADDR_STR, + "code %d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); lim_restore_from_auth_state(mac_ctx, eSIR_SME_DEAUTH_WHILE_JOIN, @@ -356,9 +358,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi case eLIM_MLM_AUTHENTICATED_STATE: pe_debug("received Deauth frame state %X with " - "reasonCode=%d from " QDF_MAC_ADDR_STR, + "reasonCode=%d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); /* / Issue Deauth Indication to SME. */ qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr, addr, sizeof(tSirMacAddr)); @@ -382,9 +384,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi * if any and issue ASSOC_CNF to SME. */ pe_debug("received Deauth frame state %X with " - "reasonCode=%d from " QDF_MAC_ADDR_STR, + "reasonCode=%d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); if (lim_search_pre_auth_list(mac_ctx, addr)) lim_delete_pre_auth_node(mac_ctx, addr); @@ -419,9 +421,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi case eLIM_MLM_WT_ADD_STA_RSP_STATE: pe_session->fDeauthReceived = true; pe_debug("Received Deauth frame in state %X with Reason " - "Code %d from Peer" QDF_MAC_ADDR_STR, + "Code %d from Peer" QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); return; case eLIM_MLM_IDLE_STATE: @@ -431,9 +433,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi && (STA_ENTRY_TDLS_PEER == sta_ds->staType)) { pe_err("received Deauth frame in state %X with " "reason code %d from Tdls peer" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); lim_send_sme_tdls_del_sta_ind(mac_ctx, sta_ds, pe_session, rc); @@ -461,23 +463,23 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi case eLIM_MLM_WT_REASSOC_RSP_STATE: pe_err("received Deauth frame state %X with " - "reasonCode=%d from " QDF_MAC_ADDR_STR, + "reasonCode=%d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); break; case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: pe_err("received Deauth frame in FT state %X with " - "reasonCode=%d from " QDF_MAC_ADDR_STR, + "reasonCode=%d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); break; default: pe_err("received Deauth frame in state %X with " - "reasonCode=%d from " QDF_MAC_ADDR_STR, + "reasonCode=%d from " QDF_MAC_ADDR_FMT, pe_session->limMlmState, rc, - QDF_MAC_ADDR_ARRAY(addr)); + QDF_MAC_ADDR_REF(addr)); return; } break; @@ -508,8 +510,9 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi * Already in the process of deleting context for the peer * and received Deauthentication frame. Log and Ignore. */ - pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d", - sta_ds->sta_deletion_in_progress, addr, + pe_debug("Deletion is in progress (%d) for peer:"QDF_MAC_ADDR_FMT" in mlmState %d", + sta_ds->sta_deletion_in_progress, + QDF_MAC_ADDR_REF(addr), sta_ds->mlmStaContext.mlmState); return; } @@ -540,10 +543,6 @@ void lim_perform_deauth(struct mac_context *mac_ctx, struct pe_session *pe_sessi lim_delete_pre_auth_node(mac_ctx, addr); if (pe_session->limAssocResponseData) { - assoc_rsp = (tpSirAssocRsp) pe_session-> - limAssocResponseData; - qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); - qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); qdf_mem_free(pe_session->limAssocResponseData); pe_session->limAssocResponseData = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_disassoc_frame.c index 9fe6164892322dbd395ecc83cdbb8542277a39fd..c7c7e3d213668cce56f7bfb04989fcf34aa34fcc 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_disassoc_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_disassoc_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -147,11 +147,12 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Get reasonCode from Disassociation frame body */ reasonCode = sir_read_u16(pBody); - pe_nofl_info("Disassoc RX: vdev %d from %pM for %pM RSSI = %d reason %d mlm state = %d, sme state = %d systemrole = %d ", - pe_session->vdev_id, pHdr->sa, pHdr->da, frame_rssi, - reasonCode, pe_session->limMlmState, - pe_session->limSmeState, - GET_LIM_SYSTEM_ROLE(pe_session)); + pe_nofl_rl_info("Disassoc RX: vdev %d from " QDF_MAC_ADDR_FMT " for " QDF_MAC_ADDR_FMT " RSSI = %d reason %d mlm state = %d, sme state = %d systemrole = %d ", + pe_session->vdev_id, QDF_MAC_ADDR_REF(pHdr->sa), + QDF_MAC_ADDR_REF(pHdr->da), frame_rssi, + reasonCode, pe_session->limMlmState, + pe_session->limSmeState, + GET_LIM_SYSTEM_ROLE(pe_session)); lim_diag_event_report(mac, WLAN_PE_DIAG_DISASSOC_FRAME_EVENT, pe_session, 0, reasonCode); @@ -169,8 +170,8 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, * Log error. */ pe_err("received Disassoc frame from STA that does not have context" - "reasonCode=%d, addr " QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(pHdr->sa)); + "reasonCode=%d, addr " QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(pHdr->sa)); return; } @@ -235,8 +236,8 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, default: /* Invalid reasonCode in received Disassociation frame */ - pe_warn("received Disassoc frame with invalid reasonCode: %d from " QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(pHdr->sa)); + pe_warn("received Disassoc frame with invalid reasonCode: %d from " QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(pHdr->sa)); break; } } else if (LIM_IS_STA_ROLE(pe_session) && @@ -252,8 +253,8 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* as long as we're not about to channel switch */ if (pe_session->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE) { - pe_err("Ignoring disassoc frame due to upcoming channel switch, from "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + pe_err("Ignoring disassoc frame due to upcoming channel switch, from "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pHdr->sa)); return; } break; @@ -265,9 +266,9 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, /* Received Disassociation frame in either IBSS */ /* or un-known role. Log and ignore it */ pe_err("received Disassoc frame with invalid reasonCode: %d in role:" - "%d in sme state: %d from " QDF_MAC_ADDR_STR, reasonCode, + "%d in sme state: %d from " QDF_MAC_ADDR_FMT, reasonCode, GET_LIM_SYSTEM_ROLE(pe_session), pe_session->limSmeState, - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_REF(pHdr->sa)); return; } @@ -279,8 +280,9 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, * Already in the process of deleting context for the peer * and received Disassociation frame. Log and Ignore. */ - pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d", - sta->sta_deletion_in_progress, pHdr->sa, + pe_debug("Deletion is in progress (%d) for peer:"QDF_MAC_ADDR_FMT" in mlmState %d", + sta->sta_deletion_in_progress, + QDF_MAC_ADDR_REF(pHdr->sa), sta->mlmStaContext.mlmState); return; } @@ -295,9 +297,9 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, eLIM_MLM_WT_ASSOC_CNF_STATE) sta->mlmStaContext.updateContext = 1; - pe_err("received Disassoc frame from peer that is in state: %X, addr "QDF_MAC_ADDR_STR, + pe_err("received Disassoc frame from peer that is in state: %X, addr "QDF_MAC_ADDR_FMT, sta->mlmStaContext.mlmState, - QDF_MAC_ADDR_ARRAY(pHdr->sa)); + QDF_MAC_ADDR_REF(pHdr->sa)); } /* if (sta->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */ @@ -308,6 +310,10 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo, ap_info.expected_rssi = frame_rssi + wlan_blm_get_rssi_blacklist_threshold(mac->pdev); qdf_mem_copy(ap_info.bssid.bytes, pHdr->sa, QDF_MAC_ADDR_SIZE); + ap_info.reject_reason = REASON_ASSOC_REJECT_POOR_RSSI; + ap_info.source = ADDED_BY_DRIVER; + ap_info.original_timeout = ap_info.retry_delay; + ap_info.received_time = qdf_mc_timer_get_system_time(); lim_add_bssid_to_reject_list(mac->pdev, &ap_info); } lim_extract_ies_from_deauth_disassoc(pe_session, (uint8_t *)pHdr, @@ -359,7 +365,6 @@ void lim_perform_disassoc(struct mac_context *mac_ctx, int32_t frame_rssi, tLimMlmDisassocInd mlmDisassocInd; uint16_t aid; tpDphHashNode sta_ds; - tpSirAssocRsp assoc_rsp; sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid, &pe_session->dph.dphHashTable); @@ -390,10 +395,6 @@ void lim_perform_disassoc(struct mac_context *mac_ctx, int32_t frame_rssi, pe_debug("received Disassoc from AP while waiting for Reassoc Rsp"); if (pe_session->limAssocResponseData) { - assoc_rsp = (tpSirAssocRsp) pe_session-> - limAssocResponseData; - qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); - qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); qdf_mem_free(pe_session->limAssocResponseData); pe_session->limAssocResponseData = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c index 9b74ae02368684bea39e92372d986d366653da2c..c69ef138e4362b961565d1dea68c254e7cd5b031 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c @@ -61,7 +61,8 @@ static int lim_get_crypto_digest_len(uint8_t *type) return SHA384_DIGEST_SIZE; else if (!strcmp(type, HMAC_SHA256_CRYPTO_TYPE)) return SHA256_DIGEST_SIZE; - return -EINVAL; + + return 0; } /** @@ -283,6 +284,11 @@ static QDF_STATUS lim_get_key_from_prf(uint8_t *type, uint8_t *secret, uint8_t crypto_digest_len = lim_get_crypto_digest_len(type); uint8_t tmp_hash[SHA384_DIGEST_SIZE] = {0}; + if (!crypto_digest_len) { + pe_err("Incorrect crypto length"); + return QDF_STATUS_E_FAILURE; + } + addr[0] = count; len[0] = sizeof(count); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_message_queue.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_message_queue.c index 749a36a9374a2e733694c84f6c18494a9a7b5ad2..196f3322dc00da196aff2c551ebca322a6214000 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -59,6 +60,9 @@ #include "cds_ieee80211_common.h" #include #include "wlan_mlme_public_struct.h" +#include "wma.h" +#include "wma_internal.h" +#include "../../core/src/vdev_mgr_ops.h" #include "wlan_p2p_cfg_api.h" void lim_log_session_states(struct mac_context *mac); @@ -84,9 +88,10 @@ static void lim_process_sae_msg_sta(struct mac_context *mac, /* SAE authentication is completed. * Restore from auth state */ - if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer)) + if (tx_timer_running(&mac->lim.lim_timers.sae_auth_timer)) lim_deactivate_and_change_timer(mac, eLIM_AUTH_SAE_TIMER); + lim_sae_auth_cleanup_retry(mac, session->vdev_id); /* success */ if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS) lim_restore_from_auth_state(mac, @@ -119,6 +124,7 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, { struct tLimPreAuthNode *sta_pre_auth_ctx; struct lim_assoc_data *assoc_req; + bool assoc_ind_sent; /* Extract pre-auth context for the STA and move limMlmState * of preauth node to eLIM_MLM_AUTHENTICATED_STATE @@ -128,8 +134,8 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, if (!sta_pre_auth_ctx) { pe_debug("No preauth node created for " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr)); return; } @@ -137,8 +143,8 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, if (sae_msg->sae_status != IEEE80211_STATUS_SUCCESS) { pe_debug("SAE authentication failed for " - QDF_MAC_ADDR_STR " status: %u", - QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr), + QDF_MAC_ADDR_FMT " status: %u", + QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr), sae_msg->sae_status); if (assoc_req->present) { pe_debug("Assoc req cached; clean it up"); @@ -162,14 +168,16 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, assoc_req->present = false; pe_debug("Assoc req cached; handle it"); - if (lim_send_assoc_ind_to_sme(mac, session, - assoc_req->sub_type, - &assoc_req->hdr, - assoc_req->assoc_req, - ANI_AKM_TYPE_SAE, - assoc_req->pmf_connection, - &assoc_req_copied, - assoc_req->dup_entry) == false) + assoc_ind_sent = + lim_send_assoc_ind_to_sme(mac, session, + assoc_req->sub_type, + &assoc_req->hdr, + assoc_req->assoc_req, + ANI_AKM_TYPE_SAE, + assoc_req->pmf_connection, + &assoc_req_copied, + assoc_req->dup_entry, false); + if (!assoc_ind_sent) lim_process_assoc_cleanup(mac, session, assoc_req->assoc_req, assoc_req->sta_ds, @@ -194,8 +202,7 @@ static void lim_process_sae_msg(struct mac_context *mac, struct sir_sae_msg *bod return; } - session = pe_find_session_by_sme_session_id(mac, - sae_msg->session_id); + session = pe_find_session_by_vdev_id(mac, sae_msg->vdev_id); if (!session) { pe_err("SAE:Unable to find session"); return; @@ -209,9 +216,9 @@ static void lim_process_sae_msg(struct mac_context *mac, struct sir_sae_msg *bod } pe_debug("SAE:status %d limMlmState %d opmode %d peer: " - QDF_MAC_ADDR_STR, sae_msg->sae_status, + QDF_MAC_ADDR_FMT, sae_msg->sae_status, session->limMlmState, session->opmode, - QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr)); + QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr)); if (LIM_IS_STA_ROLE(session)) lim_process_sae_msg_sta(mac, session, sae_msg); else if (LIM_IS_AP_ROLE(session)) @@ -415,9 +422,8 @@ static void lim_process_set_default_scan_ie_request(struct mac_context *mac_ctx, if (!local_ie_buf) return; - pe_session = pe_find_session_by_sme_session_id(mac_ctx, - - set_ie_params->session_id); + pe_session = pe_find_session_by_vdev_id(mac_ctx, + set_ie_params->vdev_id); if (lim_update_ext_cap_ie(mac_ctx, (uint8_t *)set_ie_params->ie_data, local_ie_buf, &local_ie_len, pe_session)) { @@ -429,7 +435,7 @@ static void lim_process_set_default_scan_ie_request(struct mac_context *mac_ctx, if (!wma_ie_params) goto scan_ie_send_fail; - wma_ie_params->vdev_id = set_ie_params->session_id; + wma_ie_params->vdev_id = set_ie_params->vdev_id; wma_ie_params->ie_id = DEFAULT_SCAN_IE_ID; wma_ie_params->length = local_ie_len; wma_ie_params->data = (uint8_t *)(wma_ie_params) @@ -519,11 +525,11 @@ static bool def_msg_decision(struct mac_context *mac_ctx, if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) { /* Defer processing this message */ if (lim_defer_msg(mac_ctx, lim_msg) != TX_SUCCESS) { - QDF_TRACE(QDF_MODULE_ID_PE, LOGE, - FL("Unable to Defer Msg")); + pe_err_rl("Unable to Defer Msg"); lim_log_session_states(mac_ctx); lim_handle_defer_msg_error(mac_ctx, lim_msg); } + return true; } @@ -546,8 +552,7 @@ static bool def_msg_decision(struct mac_context *mac_ctx, mgmt_pkt_defer = false; } - if ((lim_msg->type != WMA_ADD_BSS_RSP) && - (lim_msg->type != WMA_DELETE_BSS_RSP) && + if ((lim_msg->type != WMA_DELETE_BSS_RSP) && (lim_msg->type != WMA_DELETE_BSS_HO_FAIL_RSP) && (lim_msg->type != WMA_ADD_STA_RSP) && (lim_msg->type != WMA_DELETE_STA_RSP) && @@ -629,7 +634,9 @@ __lim_pno_match_fwd_bcn_probepsp(struct mac_context *pmac, uint8_t *rx_pkt_info, result->ap[i].beaconPeriod = frame->beaconInterval; result->ap[i].capability = lim_get_u16((uint8_t *) &frame->capabilityInfo); - result->ap[i].channel = WMA_GET_RX_CH(rx_pkt_info); + result->ap[i].channel = wlan_reg_freq_to_chan( + pmac->pdev, + WMA_GET_RX_FREQ(rx_pkt_info)); result->ap[i].rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); result->ap[i].rtt = 0; result->ap[i].rtt_sd = 0; @@ -680,7 +687,9 @@ __lim_ext_scan_forward_bcn_probe_rsp(struct mac_context *pmac, uint8_t *rx_pkt_i result->ap.beaconPeriod = frame->beaconInterval; result->ap.capability = lim_get_u16((uint8_t *) &frame->capabilityInfo); - result->ap.channel = WMA_GET_RX_CH(rx_pkt_info); + result->ap.channel = wlan_reg_freq_to_chan( + pmac->pdev, + WMA_GET_RX_FREQ(rx_pkt_info)); result->ap.rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); result->ap.rtt = 0; result->ap.rtt_sd = 0; @@ -819,8 +828,7 @@ __lim_handle_beacon(struct mac_context *mac, struct scheduler_msg *pMsg, static void lim_fill_sap_bcn_pkt_meta(struct scan_cache_entry *scan_entry, cds_pkt_t *rx_pkt) { - rx_pkt->pkt_meta.channel = scan_entry->channel.chan_idx; - + rx_pkt->pkt_meta.frequency = scan_entry->channel.chan_freq; rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame); rx_pkt->pkt_meta.mpdu_len = scan_entry->raw_frame.len; rx_pkt->pkt_meta.mpdu_data_len = rx_pkt->pkt_meta.mpdu_len - @@ -945,7 +953,8 @@ void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev, for (session_id = 0; session_id < mac_ctx->lim.maxBssId; session_id++) { if (filter->sap_channel[session_id] && (filter->sap_channel[session_id] == - scan_entry->channel.chan_idx)) { + wlan_reg_freq_to_chan(pdev, + scan_entry->channel.chan_freq))) { if (!pkt) { status = lim_allocate_and_get_bcn( mac_ctx, &pkt, &rx_pkt_info, @@ -1003,7 +1012,8 @@ uint32_t lim_defer_msg(struct mac_context *mac, struct scheduler_msg *pMsg) (mac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED))); } else { - pe_err("Dropped lim message (0x%X) Message %s", pMsg->type, lim_msg_str(pMsg->type)); + pe_err_rl("Dropped lim message (0x%X) Message %s", pMsg->type, + lim_msg_str(pMsg->type)); MTRACE(mac_trace_msg_rx (mac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED))); @@ -1169,7 +1179,7 @@ lim_check_mgmt_registered_frames(struct mac_context *mac_ctx, uint8_t *buff_desc (uint8_t *) hdr, WMA_GET_RX_PAYLOAD_LEN(buff_desc) + sizeof(tSirMacMgmtHdr), mgmt_frame->sessionId, - WMA_GET_RX_CH(buff_desc), session_entry, + WMA_GET_RX_FREQ(buff_desc), session_entry, WMA_GET_RX_RSSI_NORMALIZED(buff_desc), RXMGMT_FLAG_NONE); @@ -1253,7 +1263,7 @@ lim_handle80211_frames(struct mac_context *mac, struct scheduler_msg *limMsg, struct pe_session *pe_session = NULL; uint8_t sessionId; bool isFrmFt = false; - uint8_t channel; + uint32_t frequency; bool is_hw_sbs_capable = false; *pDeferMsg = false; @@ -1262,14 +1272,15 @@ lim_handle80211_frames(struct mac_context *mac, struct scheduler_msg *limMsg, pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo); isFrmFt = WMA_GET_RX_FT_DONE(pRxPacketInfo); - channel = WMA_GET_RX_CH(pRxPacketInfo); + frequency = WMA_GET_RX_FREQ(pRxPacketInfo); fc = pHdr->fc; is_hw_sbs_capable = policy_mgr_is_hw_sbs_capable(mac->psoc); - if (IS_5G_CH(channel) && - (!is_hw_sbs_capable || - (is_hw_sbs_capable && wlan_reg_is_dfs_ch(mac->pdev, channel))) && + if (WLAN_REG_IS_5GHZ_CH_FREQ(frequency) && + (!is_hw_sbs_capable || + (is_hw_sbs_capable && + wlan_reg_is_dfs_for_freq(mac->pdev, frequency))) && mac->sap.SapDfsInfo.is_dfs_cac_timer_running) { pe_session = pe_find_session_by_bssid(mac, pHdr->bssId, &sessionId); @@ -1568,6 +1579,20 @@ static void lim_process_sme_obss_scan_ind(struct mac_context *mac_ctx, return; } +static void +lim_process_vdev_delete(struct mac_context *mac_ctx, + struct del_vdev_params *vdev_param) +{ + tp_wma_handle wma_handle; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + WMA_LOGE("%s: WMA context is invalid", __func__); + return; + } + wma_vdev_detach(wma_handle, vdev_param); +} + /** * lim_process_messages() - Process messages from upper layers. * @@ -1586,7 +1611,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, uint8_t i; struct pe_session *session_entry = NULL; uint8_t defer_msg = false; - tLinkStateParams *link_state_param; uint16_t pkt_len = 0; cds_pkt_t *body_ptr = NULL; QDF_STATUS qdf_status; @@ -1635,10 +1659,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, case SIR_LIM_UPDATE_BEACON: lim_update_beacon(mac_ctx); break; - case WMA_SWITCH_CHANNEL_RSP: - lim_process_switch_channel_rsp(mac_ctx, msg->bodyptr); - msg->bodyptr = NULL; - break; #ifdef ANI_SIR_IBSS_PEER_CACHING case WMA_IBSS_STA_ADD: lim_ibss_sta_add(mac_ctx, msg->bodyptr); @@ -1732,7 +1752,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, case eWNI_SME_START_BSS_REQ: case eWNI_SME_STOP_BSS_REQ: case eWNI_SME_SWITCH_CHL_IND: - case eWNI_SME_SETCONTEXT_REQ: case eWNI_SME_DISASSOC_CNF: case eWNI_SME_DEAUTH_CNF: case eWNI_SME_ASSOC_CNF: @@ -1745,11 +1764,9 @@ static void lim_process_messages(struct mac_context *mac_ctx, #if defined FEATURE_WLAN_ESE case eWNI_SME_ESE_ADJACENT_AP_REPORT: #endif - case eWNI_SME_FT_UPDATE_KEY: case eWNI_SME_FT_PRE_AUTH_REQ: case eWNI_SME_FT_AGGR_QOS_REQ: case eWNI_SME_REGISTER_MGMT_FRAME_REQ: - case eWNI_SME_GET_STATISTICS_REQ: #ifdef FEATURE_WLAN_ESE case eWNI_SME_GET_TSM_STATS_REQ: #endif /* FEATURE_WLAN_ESE */ @@ -1763,6 +1780,7 @@ static void lim_process_messages(struct mac_context *mac_ctx, case eWNI_SME_SET_ADDBA_ACCEPT: case eWNI_SME_UPDATE_EDCA_PROFILE: case WNI_SME_UPDATE_MU_EDCA_PARAMS: + case eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS: case WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU: case WNI_SME_REGISTER_BCN_REPORT_SEND_CB: /* These messages are from HDD.No need to respond to HDD */ @@ -1796,9 +1814,9 @@ static void lim_process_messages(struct mac_context *mac_ctx, msg->bodyptr, sizeof(tSirP2PNoaAttr)); pe_debug("bssId" - QDF_MAC_ADDR_STR + QDF_MAC_ADDR_FMT " ctWin=%d oppPsFlag=%d", - QDF_MAC_ADDR_ARRAY(session_entry->bssId), + QDF_MAC_ADDR_REF(session_entry->bssId), session_entry->p2pGoPsUpdate.ctWin, session_entry->p2pGoPsUpdate.oppPsFlag); pe_debug("uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d", @@ -1886,12 +1904,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: lim_handle_update_olbc_cache(mac_ctx); break; - case WMA_ADD_BSS_RSP: - lim_process_mlm_add_bss_rsp(mac_ctx, msg); - break; - case WMA_HIDDEN_SSID_RESTART_RSP: - lim_process_mlm_update_hidden_ssid_rsp(mac_ctx, msg); - break; case WMA_ADD_STA_RSP: lim_process_add_sta_rsp(mac_ctx, msg); break; @@ -1900,7 +1912,7 @@ static void lim_process_messages(struct mac_context *mac_ctx, break; case WMA_DELETE_BSS_RSP: case WMA_DELETE_BSS_HO_FAIL_RSP: - lim_handle_delete_bss_rsp(mac_ctx, msg); + lim_handle_delete_bss_rsp(mac_ctx, msg->bodyptr); break; case WMA_CSA_OFFLOAD_EVENT: lim_handle_csa_offload_msg(mac_ctx, msg); @@ -1912,10 +1924,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, case WMA_SET_STAKEY_RSP: lim_process_mlm_set_sta_key_rsp(mac_ctx, msg); break; - case WMA_GET_STATISTICS_RSP: - lim_send_sme_pe_statistics_rsp(mac_ctx, msg->type, - (void *)msg->bodyptr); - break; case WMA_SET_MIMOPS_RSP: case WMA_SET_TX_POWER_RSP: qdf_mem_free((void *)msg->bodyptr); @@ -1940,24 +1948,6 @@ static void lim_process_messages(struct mac_context *mac_ctx, case WMA_AGGR_QOS_RSP: lim_process_ft_aggr_qos_rsp(mac_ctx, msg); break; - case WMA_SET_LINK_STATE_RSP: - link_state_param = (tLinkStateParams *) msg->bodyptr; - session_entry = link_state_param->session; - if (link_state_param->ft -#if defined WLAN_FEATURE_ROAM_OFFLOAD - && !session_entry->bRoamSynchInProgress -#endif - ) - lim_send_reassoc_req_with_ft_ies_mgmt_frame(mac_ctx, - session_entry->pLimMlmReassocReq, - session_entry); - if (link_state_param->callback) - link_state_param->callback(mac_ctx, - link_state_param->callbackArg, - link_state_param->status); - qdf_mem_free((void *)(msg->bodyptr)); - msg->bodyptr = NULL; - break; case WMA_RX_CHN_STATUS_EVENT: lim_process_rx_channel_status_event(mac_ctx, msg->bodyptr); break; @@ -1986,8 +1976,8 @@ static void lim_process_messages(struct mac_context *mac_ctx, beacon_params.paramChangeBitmap = 0; for (i = 0; i < mac_ctx->lim.maxBssId; i++) { vdev_id = ((uint8_t *)msg->bodyptr)[i]; - session_entry = pe_find_session_by_sme_session_id( - mac_ctx, vdev_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, + vdev_id); if (!session_entry) continue; session_entry->sap_advertise_avoid_ch_ie = @@ -2004,10 +1994,12 @@ static void lim_process_messages(struct mac_context *mac_ctx, * restart, in such a case, beacon params will be * reset and thus will not contain Q2Q IE, by default */ - if (wlan_reg_get_channel_state(mac_ctx->pdev, - session_entry->currentOperChannel) + if (wlan_reg_get_channel_state( + mac_ctx->pdev, + wlan_reg_freq_to_chan( + mac_ctx->pdev, session_entry->curr_op_freq)) != CHANNEL_STATE_DFS) { - beacon_params.bss_idx = session_entry->bss_idx; + beacon_params.bss_idx = session_entry->vdev_id; beacon_params.beaconInterval = session_entry->beaconParams.beaconInterval; beacon_params.paramChangeBitmap |= @@ -2132,6 +2124,16 @@ static void lim_process_messages(struct mac_context *mac_ctx, qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; + case eWNI_SME_VDEV_DELETE_REQ: + lim_process_vdev_delete(mac_ctx, msg->bodyptr); + /* Do not free msg->bodyptr, same memory used to send resp */ + msg->bodyptr = NULL; + break; + case SIR_LIM_PROCESS_DEFERRED_QUEUE: + break; + case eWNI_SME_ABORT_CONN_TIMER: + lim_deactivate_timers_for_vdev(mac_ctx, msg->bodyval); + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_host_roam.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_host_roam.c index f2c2fc0dbae6fde65a4a65f1900b68578f87b565..e7ab7994f0166652344f3d91e41c4968a55cd87f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_host_roam.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_host_roam.c @@ -42,6 +42,8 @@ #endif #include "wma_if.h" #include "rrm_api.h" +#include "wma.h" + static void lim_handle_sme_reaasoc_result(struct mac_context *, tSirResultCodes, uint16_t, struct pe_session *); /** @@ -71,10 +73,10 @@ void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx, return; } - pe_debug("ReAssoc Req on session: %d role: %d mlm: %d " QDF_MAC_ADDR_STR, + pe_debug("ReAssoc Req on session: %d role: %d mlm: %d " QDF_MAC_ADDR_FMT, reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session), session->limMlmState, - QDF_MAC_ADDR_ARRAY(reassoc_req->peerMacAddr)); + QDF_MAC_ADDR_REF(reassoc_req->peerMacAddr)); if (LIM_IS_AP_ROLE(session) || (session->limMlmState != @@ -85,9 +87,9 @@ void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx, * parameters code. */ - pe_warn("unexpect msg state: %X role: %d MAC" QDF_MAC_ADDR_STR, + pe_warn("unexpect msg state: %X role: %d MAC" QDF_MAC_ADDR_FMT, session->limMlmState, GET_LIM_SYSTEM_ROLE(session), - QDF_MAC_ADDR_ARRAY(reassoc_req->peerMacAddr)); + QDF_MAC_ADDR_REF(reassoc_req->peerMacAddr)); lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; @@ -121,7 +123,7 @@ void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx, goto end; } /* assign the sessionId to the timer object */ - mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId = + mac_ctx->lim.lim_timers.gLimReassocFailureTimer.sessionId = reassoc_req->sessionId; session->limPrevMlmState = session->limMlmState; session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; @@ -370,31 +372,21 @@ QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param) return QDF_STATUS_SUCCESS; } -/** - * lim_process_sta_mlm_add_bss_rsp_ft() - Handle the ADD BSS response - * @mac: Global MAC context - * @limMsgQ: ADD BSS Parameters - * @pe_session: PE Session - * - * Function to handle WMA_ADD_BSS_RSP, in FT reassoc state. - * Send ReAssociation Request. - * - *Return: None - */ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, - struct scheduler_msg *limMsgQ, struct pe_session *pe_session) + struct add_bss_rsp *add_bss_rsp, + struct pe_session *pe_session) { tLimMlmReassocCnf mlmReassocCnf; /* keep sme */ tpDphHashNode sta = NULL; tpAddStaParams pAddStaParams = NULL; uint32_t listenInterval = MLME_CFG_LISTEN_INTERVAL; - tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; uint32_t selfStaDot11Mode = 0; + struct bss_description *bss_desc = NULL; /* Sanity Checks */ - if (!pAddBssParams) { - pe_err("Invalid parameters"); + if (!add_bss_rsp) { + pe_err("add_bss_rsp is NULL"); goto end; } if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE != @@ -402,14 +394,13 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, goto end; } - sta = dph_add_hash_entry(mac, pAddBssParams->bssId, - DPH_STA_HASH_INDEX_PEER, - &pe_session->dph.dphHashTable); + sta = dph_add_hash_entry(mac, pe_session->bssId, + DPH_STA_HASH_INDEX_PEER, + &pe_session->dph.dphHashTable); if (!sta) { /* Could not add hash table entry */ - pe_err("could not add hash entry at DPH for"); - lim_print_mac_addr(mac, pAddBssParams->staContext.staMac, - LOGE); + pe_err("could not add hash entry at DPH for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pe_session->bssId)); goto end; } /* Prepare and send Reassociation request frame */ @@ -417,14 +408,14 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, #ifdef WLAN_FEATURE_ROAM_OFFLOAD if (pe_session->bRoamSynchInProgress != true) { #endif - mac->lim.limTimers.gLimReassocFailureTimer.sessionId = + mac->lim.lim_timers.gLimReassocFailureTimer.sessionId = pe_session->peSessionId; /* / Start reassociation failure timer */ MTRACE(mac_trace (mac, TRACE_CODE_TIMER_ACTIVATE, pe_session->peSessionId, eLIM_REASSOC_FAIL_TIMER)); if (tx_timer_activate - (&mac->lim.limTimers.gLimReassocFailureTimer) + (&mac->lim.lim_timers.gLimReassocFailureTimer) != TX_SUCCESS) { /* / Could not start reassoc failure timer. */ /* Log error */ @@ -467,15 +458,7 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, pe_debug("Set the mlm state: %d session: %d", pe_session->limMlmState, pe_session->peSessionId); - pe_session->bss_idx = (uint8_t)pAddBssParams->bss_idx; - /* Success, handle below */ - sta->bssId = pAddBssParams->bss_idx; - /* STA Index(genr by HAL) for the BSS entry is stored here */ - sta->staIndex = pAddBssParams->staContext.staIdx; - - rrm_cache_mgmt_tx_power(mac, pAddBssParams->txMgmtPower, - pe_session); pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams)); if (!pAddStaParams) @@ -486,60 +469,39 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, (uint8_t *)pe_session->self_mac_addr, sizeof(tSirMacAddr)); - qdf_mem_copy((uint8_t *) pAddStaParams->bssId, + qdf_mem_copy((uint8_t *)pAddStaParams->bssId, pe_session->bssId, sizeof(tSirMacAddr)); pAddStaParams->staType = STA_ENTRY_SELF; pAddStaParams->status = QDF_STATUS_SUCCESS; - pAddStaParams->respReqd = 1; /* Update PE session ID */ pAddStaParams->sessionId = pe_session->peSessionId; pAddStaParams->smesessionId = pe_session->smeSessionId; - /* This will indicate HAL to "allocate" a new STA index */ -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - if (pe_session->bRoamSynchInProgress != true) -#endif - pAddStaParams->staIdx = STA_INVALID_IDX; pAddStaParams->updateSta = false; - pAddStaParams->shortPreambleSupported = - (uint8_t) pe_session->beaconParams.fShortPreamble; + if (pe_session->lim_join_req) + bss_desc = &pe_session->lim_join_req->bssDescription; + lim_populate_peer_rate_set(mac, &pAddStaParams->supportedRates, NULL, - false, pe_session, NULL, NULL); + false, pe_session, NULL, NULL, NULL, + bss_desc); if (pe_session->htCapability) { pAddStaParams->htCapable = pe_session->htCapability; pAddStaParams->vhtCapable = pe_session->vhtCapability; pAddStaParams->ch_width = pe_session->ch_width; - pAddStaParams->greenFieldCapable = - lim_get_ht_capability(mac, eHT_GREENFIELD, - pe_session); + pAddStaParams->mimoPS = lim_get_ht_capability(mac, eHT_MIMO_POWER_SAVE, pe_session); - pAddStaParams->rifsMode = - lim_get_ht_capability(mac, eHT_RIFS_MODE, - pe_session); - pAddStaParams->lsigTxopProtection = - lim_get_ht_capability(mac, eHT_LSIG_TXOP_PROTECTION, - pe_session); pAddStaParams->maxAmpduDensity = lim_get_ht_capability(mac, eHT_MPDU_DENSITY, pe_session); pAddStaParams->maxAmpduSize = lim_get_ht_capability(mac, eHT_MAX_RX_AMPDU_FACTOR, pe_session); - pAddStaParams->maxAmsduSize = - lim_get_ht_capability(mac, eHT_MAX_AMSDU_LENGTH, - pe_session); - pAddStaParams->max_amsdu_num = - lim_get_ht_capability(mac, eHT_MAX_AMSDU_NUM, - pe_session); - pAddStaParams->fDsssCckMode40Mhz = - lim_get_ht_capability(mac, eHT_DSSS_CCK_MODE_40MHZ, - pe_session); pAddStaParams->fShortGI20Mhz = lim_get_ht_capability(mac, eHT_SHORT_GI_20MHZ, pe_session); @@ -558,11 +520,6 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, /* Lets save this for when we receive the Reassoc Rsp */ pe_session->ftPEContext.pAddStaReq = pAddStaParams; - if (pAddBssParams) { - qdf_mem_free(pAddBssParams); - pAddBssParams = NULL; - limMsgQ->bodyptr = NULL; - } #ifdef WLAN_FEATURE_ROAM_OFFLOAD if (pe_session->bRoamSynchInProgress) { pe_debug("LFR3:Prep and save AddStaReq for post-assoc-rsp"); @@ -580,12 +537,6 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, pe_session->pLimMlmReassocReq = NULL; } - if (pAddBssParams) { - qdf_mem_free(pAddBssParams); - pAddBssParams = NULL; - limMsgQ->bodyptr = NULL; - } - mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; /* Update PE session Id */ @@ -601,13 +552,13 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, void lim_process_mlm_ft_reassoc_req(struct mac_context *mac, tLimMlmReassocReq *reassoc_req) { - uint8_t chanNum = 0; struct pe_session *session; uint16_t caps; uint32_t val; - struct scheduler_msg msgQ = {0}; - QDF_STATUS retCode; + QDF_STATUS status; uint32_t teleBcnEn = 0; + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *mlme_obj; if (!reassoc_req) { pe_err("reassoc_req is NULL"); @@ -621,8 +572,6 @@ void lim_process_mlm_ft_reassoc_req(struct mac_context *mac, return; } - chanNum = session->currentOperChannel; - #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ lim_diag_event_report(mac, WLAN_PE_DIAG_REASSOCIATING, session, 0, 0); @@ -669,32 +618,48 @@ void lim_process_mlm_ft_reassoc_req(struct mac_context *mac, else val = mac->mlme_cfg->sap_cfg.listen_interval; - if (lim_set_link_state - (mac, eSIR_LINK_PREASSOC_STATE, session->bssId, - session->self_mac_addr, NULL, NULL) != QDF_STATUS_SUCCESS) { + status = wma_add_bss_peer_sta(session->self_mac_addr, session->bssId, + false); + + if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(reassoc_req); return; } reassoc_req->listenInterval = (uint16_t) val; - session->pLimMlmReassocReq = reassoc_req; - /* we need to defer the message until we get response back from HAL */ - SET_LIM_PROCESS_DEFD_MESGS(mac, false); + vdev = session->vdev; + if (!vdev) { + pe_err("vdev is NULL"); + qdf_mem_free(reassoc_req); + return; + } + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return; + } - msgQ.type = SIR_HAL_ADD_BSS_REQ; - msgQ.reserved = 0; - msgQ.bodyptr = session->ftPEContext.pAddBssReq; - msgQ.bodyval = 0; + status = lim_pre_vdev_start(mac, mlme_obj, session); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(reassoc_req); + return; + } + qdf_mem_copy(mlme_obj->mgmt.generic.bssid, session->bssId, + QDF_MAC_ADDR_SIZE); - pe_debug("Sending SIR_HAL_ADD_BSS_REQ"); - MTRACE(mac_trace_msg_tx(mac, session->peSessionId, msgQ.type)); - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { - qdf_mem_free(session->ftPEContext.pAddBssReq); - pe_err("Posting ADD_BSS_REQ to HAL failed, reason: %X", - retCode); + session->pLimMlmReassocReq = reassoc_req; + /* we need to defer the message until we get response back from HAL */ + SET_LIM_PROCESS_DEFD_MESGS(mac, false); + status = wma_add_bss_lfr2_vdev_start(session->vdev, + session->ftPEContext.pAddBssReq); + if (QDF_IS_STATUS_ERROR(status)) { + SET_LIM_PROCESS_DEFD_MESGS(mac, true); + pe_err("wma_add_bss_lfr2_vdev_start, reason: %X", status); + session->pLimMlmReassocReq = NULL; + qdf_mem_free(reassoc_req); } + qdf_mem_free(session->ftPEContext.pAddBssReq); session->ftPEContext.pAddBssReq = NULL; return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index f1f6b9a5f339f0e3b37ee3338cc93dd00d9d2221..71814103b5814a9937f87297f9190e8fe255202b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,33 +37,65 @@ #include "host_diag_core_log.h" #endif #include "wma_if.h" +#include "wma.h" #include "wlan_reg_services_api.h" #include "lim_process_fils.h" #include "wlan_mlme_public_struct.h" +#include "../../core/src/vdev_mgr_ops.h" +#include "wlan_pmo_ucfg_api.h" +#include "wlan_objmgr_vdev_obj.h" static void lim_process_mlm_auth_req(struct mac_context *, uint32_t *); static void lim_process_mlm_assoc_req(struct mac_context *, uint32_t *); static void lim_process_mlm_disassoc_req(struct mac_context *, uint32_t *); -static void lim_process_mlm_set_keys_req(struct mac_context *, uint32_t *); /* MLM Timeout event handler templates */ static void lim_process_auth_rsp_timeout(struct mac_context *, uint32_t); static void lim_process_periodic_join_probe_req_timer(struct mac_context *); static void lim_process_auth_retry_timer(struct mac_context *); -/** - * lim_process_sae_auth_timeout() - This function is called to process sae - * auth timeout - * @mac_ctx: Pointer to Global MAC structure - * - * @Return: None - */ -static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) +static void lim_fill_status_code(uint8_t frame_type, + enum tx_ack_status ack_status, + enum wlan_status_code *proto_status_code) +{ + if (frame_type == SIR_MAC_MGMT_AUTH) { + switch (ack_status) { + case LIM_TX_FAILED: + *proto_status_code = STATUS_AUTH_TX_FAIL; + break; + case LIM_ACK_RCD_FAILURE: + *proto_status_code = STATUS_AUTH_NO_ACK_RECEIVED; + break; + case LIM_ACK_RCD_SUCCESS: + *proto_status_code = STATUS_AUTH_NO_RESP_RECEIVED; + break; + default: + *proto_status_code = STATUS_UNSPECIFIED_FAILURE; + } + } else if (frame_type == SIR_MAC_MGMT_ASSOC_RSP) { + switch (ack_status) { + case LIM_TX_FAILED: + *proto_status_code = STATUS_ASSOC_TX_FAIL; + break; + case LIM_ACK_RCD_FAILURE: + *proto_status_code = STATUS_ASSOC_NO_ACK_RECEIVED; + break; + case LIM_ACK_RCD_SUCCESS: + *proto_status_code = STATUS_ASSOC_NO_RESP_RECEIVED; + break; + default: + *proto_status_code = STATUS_UNSPECIFIED_FAILURE; + } + } +} + +void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) { struct pe_session *session; + enum wlan_status_code proto_status_code; session = pe_find_session_by_session_id(mac_ctx, - mac_ctx->lim.limTimers.sae_auth_timer.sessionId); + mac_ctx->lim.lim_timers.sae_auth_timer.sessionId); if (!session) { pe_err("Session does not exist for given session id"); return; @@ -74,6 +107,9 @@ static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) switch (session->limMlmState) { case eLIM_MLM_WT_SAE_AUTH_STATE: + lim_fill_status_code(SIR_MAC_MGMT_AUTH, + mac_ctx->auth_ack_status, + &proto_status_code); /* * SAE authentication is not completed. Restore from * auth state. @@ -81,7 +117,7 @@ static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) if (session->opmode == QDF_STA_MODE) lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, - eSIR_MAC_UNSPEC_FAILURE_REASON, session); + proto_status_code, session); break; default: /* SAE authentication is timed out in unexpected state */ @@ -123,9 +159,6 @@ void lim_process_mlm_req_messages(struct mac_context *mac_ctx, case LIM_MLM_DISASSOC_REQ: lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr); break; - case LIM_MLM_SETKEYS_REQ: - lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr); - break; case SIR_LIM_JOIN_FAIL_TIMEOUT: lim_process_join_failure_timeout(mac_ctx); break; @@ -162,125 +195,18 @@ void lim_process_mlm_req_messages(struct mac_context *mac_ctx, } /* switch (msg->type) */ } -/** - * mlm_add_sta() - MLM add sta - * @mac_ctx: global MAC context - * @sta_param: Add sta params - * @bssid: BSSID - * @ht_capable: HT capability - * @session_entry: PE session entry - * - * This function is called to update station parameters - * - * Return: None - */ -static void mlm_add_sta(struct mac_context *mac_ctx, tpAddStaParams sta_param, - uint8_t *bssid, uint8_t ht_capable, struct pe_session *session_entry) +#ifdef WLAN_FEATURE_11W +static void update_rmfEnabled(struct bss_params *addbss_param, + struct pe_session *session) +{ + addbss_param->rmfEnabled = session->limRmfEnabled; +} +#else +static void update_rmfEnabled(struct bss_params *addbss_param, + struct pe_session *session) { - uint32_t val; - - sta_param->staType = STA_ENTRY_SELF; /* Identifying self */ - - qdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr)); - qdf_mem_copy(sta_param->staMac, session_entry->self_mac_addr, - sizeof(tSirMacAddr)); - - /* Configuration related parameters to be changed to support BT-AMP */ - - val = mac_ctx->mlme_cfg->sap_cfg.listen_interval; - sta_param->listenInterval = (uint16_t) val; - - sta_param->shortPreambleSupported = - mac_ctx->mlme_cfg->ht_caps.short_preamble; - - sta_param->assocId = 0; /* Is SMAC OK with this? */ - sta_param->wmmEnabled = 0; - sta_param->uAPSD = 0; - sta_param->maxSPLen = 0; - sta_param->us32MaxAmpduDuration = 0; - sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */ - - /* For Self STA get the LDPC capability from config.ini */ - sta_param->htLdpcCapable = - (session_entry->txLdpcIniFeatureEnabled & 0x01); - sta_param->vhtLdpcCapable = - ((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01); - - if (IS_DOT11_MODE_HT(session_entry->dot11mode)) { - sta_param->htCapable = ht_capable; - sta_param->greenFieldCapable = - lim_get_ht_capability(mac_ctx, eHT_GREENFIELD, - session_entry); - sta_param->ch_width = - lim_get_ht_capability(mac_ctx, - eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry); - sta_param->mimoPS = - (tSirMacHTMIMOPowerSaveState)lim_get_ht_capability( - mac_ctx, eHT_MIMO_POWER_SAVE, session_entry); - sta_param->rifsMode = - lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE, - session_entry); - sta_param->lsigTxopProtection = - lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION, - session_entry); - sta_param->maxAmpduDensity = - lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY, - session_entry); - sta_param->maxAmsduSize = - lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH, - session_entry); - sta_param->max_amsdu_num = - lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_NUM, - session_entry); - sta_param->fDsssCckMode40Mhz = - lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ, - session_entry); - sta_param->fShortGI20Mhz = - lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ, - session_entry); - sta_param->fShortGI40Mhz = - lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ, - session_entry); - } - if (session_entry->vhtCapability) { - sta_param->vhtCapable = true; - sta_param->vhtTxBFCapable = - session_entry->vht_config.su_beam_formee; - sta_param->vhtTxMUBformeeCapable = - session_entry->vht_config.mu_beam_formee; - sta_param->enable_su_tx_bformer = - session_entry->vht_config.su_beam_former; - } - - if (lim_is_session_he_capable(session_entry)) - lim_add_self_he_cap(sta_param, session_entry); - - /* - * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE - * capabilities - */ - if (session_entry->vhtCapability) { - sta_param->maxAmpduSize = - mac_ctx->mlme_cfg->vht_caps.vht_cap_info.ampdu_len_exponent; - } - sta_param->enableVhtpAid = session_entry->enableVhtpAid; - sta_param->enableAmpduPs = session_entry->enableAmpduPs; - sta_param->enableHtSmps = session_entry->enableHtSmps; - sta_param->htSmpsconfig = session_entry->htSmpsvalue; - sta_param->send_smps_action = session_entry->send_smps_action; - - lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL, - false, session_entry, NULL, NULL); - - pe_debug("GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d," - " SGI20: %d, SGI40%d", sta_param->greenFieldCapable, - sta_param->ch_width, sta_param->mimoPS, - sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz, - sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz); - - if (QDF_P2P_GO_MODE == session_entry->opmode) - sta_param->p2pCapableSta = 1; } +#endif /** * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ @@ -296,189 +222,75 @@ tSirResultCodes lim_mlm_add_bss(struct mac_context *mac_ctx, tLimMlmStartReq *mlm_start_req, struct pe_session *session) { - struct scheduler_msg msg_buf = {0}; - tpAddBssParams addbss_param = NULL; - struct wlan_mlme_qos *qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params; - uint32_t retcode; - bool is_ch_dfs = false; - - /* Package WMA_ADD_BSS_REQ message parameters */ - addbss_param = qdf_mem_malloc(sizeof(tAddBssParams)); - if (!addbss_param) - return eSIR_SME_RESOURCES_UNAVAILABLE; - - /* Fill in tAddBssParams members */ - qdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId, - sizeof(tSirMacAddr)); + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev = session->vdev; + uint8_t vdev_id = session->vdev_id; + QDF_STATUS status = QDF_STATUS_SUCCESS; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct bss_params *addbss_param = NULL; + + if (!wma) { + pe_err("Invalid wma handle"); + return eSIR_SME_INVALID_PARAMETERS; + } - /* Fill in tAddBssParams self_mac_addr */ - qdf_mem_copy(addbss_param->self_mac_addr, - session->self_mac_addr, sizeof(tSirMacAddr)); - - addbss_param->bssType = mlm_start_req->bssType; - if (mlm_start_req->bssType == eSIR_IBSS_MODE) - addbss_param->operMode = BSS_OPERATIONAL_MODE_STA; - else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE) - addbss_param->operMode = BSS_OPERATIONAL_MODE_AP; - else if (mlm_start_req->bssType == eSIR_NDI_MODE) - addbss_param->operMode = BSS_OPERATIONAL_MODE_NDI; - - addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported; - addbss_param->beaconInterval = mlm_start_req->beaconPeriod; - addbss_param->dtimPeriod = mlm_start_req->dtimPeriod; - addbss_param->wps_state = mlm_start_req->wps_state; - addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount; - addbss_param->cfParamSet.cfpPeriod = - mlm_start_req->cfParamSet.cfpPeriod; - addbss_param->cfParamSet.cfpMaxDuration = - mlm_start_req->cfParamSet.cfpMaxDuration; - addbss_param->cfParamSet.cfpDurRemaining = - mlm_start_req->cfParamSet.cfpDurRemaining; - - addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates; - if (addbss_param->rateSet.numRates > WLAN_SUPPORTED_RATES_IE_MAX_LEN) { - pe_warn("num of sup rates %d exceeding the limit %d, resetting", - addbss_param->rateSet.numRates, - WLAN_SUPPORTED_RATES_IE_MAX_LEN); - addbss_param->rateSet.numRates = WLAN_SUPPORTED_RATES_IE_MAX_LEN; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return eSIR_SME_INVALID_PARAMETERS; } - qdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate, - addbss_param->rateSet.numRates); - addbss_param->nwType = mlm_start_req->nwType; - addbss_param->htCapable = mlm_start_req->htCapable; - addbss_param->vhtCapable = session->vhtCapability; + qdf_mem_copy(mlme_obj->mgmt.generic.bssid, mlm_start_req->bssId, + QDF_MAC_ADDR_SIZE); if (lim_is_session_he_capable(session)) { - lim_update_bss_he_capable(mac_ctx, addbss_param); - lim_decide_he_op(mac_ctx, addbss_param, session); + lim_decide_he_op(mac_ctx, &mlme_obj->proto.he_ops_info.he_ops, + session); lim_update_usr_he_cap(mac_ctx, session); } - addbss_param->ch_width = session->ch_width; - addbss_param->ch_center_freq_seg0 = - session->ch_center_freq_seg0; - addbss_param->ch_center_freq_seg1 = - session->ch_center_freq_seg1; - addbss_param->htOperMode = mlm_start_req->htOperMode; - addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection; - addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet; - - addbss_param->currentOperChannel = mlm_start_req->channelNumber; -#ifdef WLAN_FEATURE_11W - addbss_param->rmfEnabled = session->limRmfEnabled; -#endif - - /* Update PE sessionId */ - addbss_param->sessionId = mlm_start_req->sessionId; - addbss_param->bss_idx = session->smeSessionId; - - - /* Send the SSID to HAL to enable SSID matching for IBSS */ - addbss_param->ssId.length = mlm_start_req->ssId.length; - if (addbss_param->ssId.length > WLAN_SSID_MAX_LEN) { - pe_err("Invalid ssid length %d, max length allowed %d", - addbss_param->ssId.length, - WLAN_SSID_MAX_LEN); - qdf_mem_free(addbss_param); - return eSIR_SME_INVALID_PARAMETERS; - } - qdf_mem_copy(addbss_param->ssId.ssId, - mlm_start_req->ssId.ssId, addbss_param->ssId.length); - addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden; - pe_debug("TRYING TO HIDE SSID %d", addbss_param->bHiddenSSIDEn); - /* CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed. */ - addbss_param->bProxyProbeRespEn = 0; - addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled; - - addbss_param->maxTxPower = session->maxTxPower; - - mlm_add_sta(mac_ctx, &addbss_param->staContext, - addbss_param->bssId, addbss_param->htCapable, - session); - - addbss_param->status = QDF_STATUS_SUCCESS; - addbss_param->respReqd = 1; - /* Set a new state for MLME */ session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, session->limMlmState)); - /* pass on the session persona to hal */ - addbss_param->halPersona = session->opmode; - - if (session->ch_width == CH_WIDTH_160MHZ) { - is_ch_dfs = true; - } else if (session->ch_width == CH_WIDTH_80P80MHZ) { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - mlm_start_req->channelNumber) == - CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac_ctx->pdev, - session->ch_center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS) - is_ch_dfs = true; - } else { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - mlm_start_req->channelNumber) == - CHANNEL_STATE_DFS) - is_ch_dfs = true; - } + status = lim_pre_vdev_start(mac_ctx, mlme_obj, session); + if (QDF_IS_STATUS_ERROR(status)) + goto send_fail_resp; - addbss_param->bSpectrumMgtEnabled = - session->spectrumMgtEnabled || is_ch_dfs; - addbss_param->extSetStaKeyParamValid = 0; - - addbss_param->dot11_mode = session->dot11mode; - addbss_param->nss = session->nss; - addbss_param->cac_duration_ms = mlm_start_req->cac_duration_ms; - addbss_param->dfs_regdomain = mlm_start_req->dfs_regdomain; - addbss_param->beacon_tx_rate = session->beacon_tx_rate; - if (QDF_IBSS_MODE == addbss_param->halPersona) { - if (!(mac_ctx->mlme_cfg)) { - pe_err("Mlme cfg NULL"); - return eSIR_SME_INVALID_PARAMETERS; - } - addbss_param->nss_2g = mac_ctx->vdev_type_nss_2g.ibss; - addbss_param->nss_5g = mac_ctx->vdev_type_nss_5g.ibss; - addbss_param->tx_aggregation_size = - qos_aggr->tx_aggregation_size; - addbss_param->tx_aggregation_size_be = - qos_aggr->tx_aggregation_size_be; - addbss_param->tx_aggregation_size_bk = - qos_aggr->tx_aggregation_size_bk; - addbss_param->tx_aggregation_size_vi = - qos_aggr->tx_aggregation_size_vi; - addbss_param->tx_aggregation_size_vo = - qos_aggr->tx_aggregation_size_vo; - addbss_param->rx_aggregation_size = - qos_aggr->rx_aggregation_size; - } - pe_debug("dot11_mode:%d nss value:%d", - addbss_param->dot11_mode, addbss_param->nss); - - if (cds_is_5_mhz_enabled()) { - addbss_param->ch_width = CH_WIDTH_5MHZ; - addbss_param->staContext.ch_width = CH_WIDTH_5MHZ; - } else if (cds_is_10_mhz_enabled()) { - addbss_param->ch_width = CH_WIDTH_10MHZ; - addbss_param->staContext.ch_width = CH_WIDTH_10MHZ; - } + addbss_param = qdf_mem_malloc(sizeof(struct bss_params)); + if (!addbss_param) + goto send_fail_resp; - msg_buf.type = WMA_ADD_BSS_REQ; - msg_buf.reserved = 0; - msg_buf.bodyptr = addbss_param; - msg_buf.bodyval = 0; - MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type)); - - pe_debug("Sending WMA_ADD_BSS_REQ..."); - retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf); - if (QDF_STATUS_SUCCESS != retcode) { - pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X", - retcode); - qdf_mem_free(addbss_param); - return eSIR_SME_HAL_SEND_MESSAGE_FAIL; - } + addbss_param->vhtCapable = mlm_start_req->htCapable; + addbss_param->htCapable = session->vhtCapability; + addbss_param->ch_width = session->ch_width; + update_rmfEnabled(addbss_param, session); + addbss_param->staContext.fShortGI20Mhz = + lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ, session); + addbss_param->staContext.fShortGI40Mhz = + lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ, session); + status = wma_pre_vdev_start_setup(vdev_id, addbss_param); + qdf_mem_free(addbss_param); + if (QDF_IS_STATUS_ERROR(status)) + goto send_fail_resp; + + if (session->wps_state == SAP_WPS_DISABLED) + ucfg_pmo_disable_wakeup_event(wma->psoc, vdev_id, + WOW_PROBE_REQ_WPS_IE_EVENT); + status = wma_vdev_pre_start(vdev_id, false); + if (QDF_IS_STATUS_ERROR(status)) + goto peer_cleanup; + status = vdev_mgr_start_send(mlme_obj, false); + if (QDF_IS_STATUS_ERROR(status)) + goto peer_cleanup; + wma_post_vdev_start_setup(vdev_id); + + return eSIR_SME_SUCCESS; + +peer_cleanup: + wma_remove_bss_peer_on_vdev_start_failure(wma, vdev_id); +send_fail_resp: + wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE); return eSIR_SME_SUCCESS; } @@ -545,33 +357,23 @@ void lim_process_mlm_start_req(struct mac_context *mac_ctx, * * Return: none */ -static void lim_post_join_set_link_state_callback(struct mac_context *mac, - void *callback_arg, bool status) +static void lim_post_join_set_link_state_callback( + struct mac_context *mac, + struct pe_session *session_entry, QDF_STATUS status) { - uint8_t chan_num, sec_chan_offset; - struct session_params *session_cb_param = - (struct session_params *)callback_arg; tLimMlmJoinCnf mlm_join_cnf; - struct pe_session *session_entry = pe_find_session_by_session_id(mac, - session_cb_param->session_id); if (!session_entry) { - pe_err("sessionId:%d does not exist", - session_cb_param->session_id); - qdf_mem_free(session_cb_param); + pe_err("sessionId is NULL"); return; } - qdf_mem_free(session_cb_param); - - if (!status) { + if (QDF_IS_STATUS_ERROR(status)) { pe_err("failed to find pe session for session id:%d", session_entry->peSessionId); goto failure; } - chan_num = session_entry->currentOperChannel; - sec_chan_offset = session_entry->htSecondaryChannelOffset; /* * store the channel switch session_entry in the lim * global variable @@ -579,12 +381,8 @@ static void lim_post_join_set_link_state_callback(struct mac_context *mac, session_entry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN; session_entry->pLimMlmReassocRetryReq = NULL; - lim_set_channel(mac, session_entry->currentOperChannel, - session_entry->ch_center_freq_seg0, - session_entry->ch_center_freq_seg1, - session_entry->ch_width, - session_entry->maxTxPower, - session_entry->peSessionId, 0, 0); + lim_send_switch_chnl_params(mac, session_entry); + return; failure: @@ -600,10 +398,8 @@ static void lim_post_join_set_link_state_callback(struct mac_context *mac, /** * lim_process_mlm_post_join_suspend_link() - This function is called after the * suspend link while joining off channel. - * * @mac_ctx: Pointer to Global MAC structure - * @status: status of suspend link. - * @ctx: passed while calling suspend link(session) + * @session: session * * This function does following: * Check for suspend state. @@ -616,54 +412,21 @@ static void lim_post_join_set_link_state_callback(struct mac_context *mac, */ static void lim_process_mlm_post_join_suspend_link(struct mac_context *mac_ctx, - QDF_STATUS status, - uint32_t *ctx) + struct pe_session *session) { - tLimMlmJoinCnf mlm_join_cnf; - struct pe_session *session = (struct pe_session *) ctx; - tSirLinkState lnk_state; - struct session_params *pe_session_param = NULL; + QDF_STATUS status; - if (QDF_STATUS_SUCCESS != status) { - pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join", - session->peSessionId); - } lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); /* assign appropriate sessionId to the timer object */ - mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId = + mac_ctx->lim.lim_timers.gLimJoinFailureTimer.sessionId = session->peSessionId; - lnk_state = eSIR_LINK_PREASSOC_STATE; - pe_session_param = qdf_mem_malloc(sizeof(struct session_params)); - if (!pe_session_param) - goto error; - - pe_session_param->session_id = session->peSessionId; - if (lim_set_link_state(mac_ctx, lnk_state, - session->pLimMlmJoinReq->bssDescription.bssId, - session->self_mac_addr, - lim_post_join_set_link_state_callback, - pe_session_param) != QDF_STATUS_SUCCESS) { - pe_err("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!", - session->peSessionId); - lim_print_mac_addr(mac_ctx, - session->pLimMlmJoinReq->bssDescription.bssId, LOGE); - mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; - session->limMlmState = eLIM_MLM_IDLE_STATE; - MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, - session->peSessionId, session->limMlmState)); - qdf_mem_free(pe_session_param); - goto error; - } + status = wma_add_bss_peer_sta(session->self_mac_addr, session->bssId, + false); + lim_post_join_set_link_state_callback(mac_ctx, session, status); return; -error: - mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; - mlm_join_cnf.sessionId = session->peSessionId; - mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; - lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, - (uint32_t *) &mlm_join_cnf); } /** @@ -714,29 +477,26 @@ void lim_process_mlm_join_req(struct mac_context *mac_ctx, (mlm_join_req->bssDescription.capabilityInfo) != SIR_MAC_GET_IBSS(mlm_join_req->bssDescription. capabilityInfo))) { - /* Hold onto Join request parameters */ - session->pLimMlmJoinReq = mlm_join_req; - lim_process_mlm_post_join_suspend_link(mac_ctx, - QDF_STATUS_SUCCESS, (uint32_t *)session); + lim_process_mlm_post_join_suspend_link(mac_ctx, session); return; - } else { - /** - * Should not have received JOIN req in states other than - * Idle state or on AP. - * Return join confirm with invalid parameters code. - */ - pe_err("Session:%d Unexpected Join req, role %d state %X", - session->peSessionId, GET_LIM_SYSTEM_ROLE(session), - session->limMlmState); - lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); } + /** + * Should not have received JOIN req in states other than + * Idle state or on AP. + * Return join confirm with invalid parameters code. + */ + pe_err("Session:%d Unexpected Join req, role %d state %X", + session->peSessionId, GET_LIM_SYSTEM_ROLE(session), + session->limMlmState); + lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); + error: qdf_mem_free(mlm_join_req); if (session) session->pLimMlmJoinReq = NULL; - mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmjoin_cnf.resultCode = eSIR_SME_PEER_CREATE_FAILED; mlmjoin_cnf.sessionId = sessionid; mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, @@ -861,11 +621,11 @@ static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, session->ssId.ssId, session->ssId.length); - pe_debug("vdev_id %d ssid %.*s "QDF_MAC_ADDR_STR, + pe_debug("vdev_id %d ssid %.*s "QDF_MAC_ADDR_FMT, sae_info->vdev_id, sae_info->ssid.length, sae_info->ssid.ssId, - QDF_MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes)); + QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes)); msg.type = eWNI_SME_TRIGGER_SAE; msg.bodyptr = sae_info; @@ -882,13 +642,13 @@ static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, session->limMlmState)); - mac_ctx->lim.limTimers.sae_auth_timer.sessionId = + mac_ctx->lim.lim_timers.sae_auth_timer.sessionId = session->peSessionId; /* Activate SAE auth timer */ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, session->peSessionId, eLIM_AUTH_SAE_TIMER)); - if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer) + if (tx_timer_activate(&mac_ctx->lim.lim_timers.sae_auth_timer) != TX_SUCCESS) { pe_err("could not start Auth SAE timer"); } @@ -939,10 +699,10 @@ static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) return; } - pe_debug("vdev %d Systemrole %d mlmstate %d from: " QDF_MAC_ADDR_STR "with authtype %d", + pe_debug("vdev %d Systemrole %d mlmstate %d from: " QDF_MAC_ADDR_FMT "with authtype %d", session->vdev_id, GET_LIM_SYSTEM_ROLE(session), session->limMlmState, - QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr), + QDF_MAC_ADDR_REF(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr), mac_ctx->lim.gpLimMlmAuthReq->authType); sir_copy_mac_addr(curr_bssid, session->bssId); @@ -965,8 +725,8 @@ static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) */ if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) { pe_debug("Already have pre-auth context with peer: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)); mlm_auth_cnf.resultCode = (tSirResultCodes) eSIR_MAC_SUCCESS_STATUS; goto end; @@ -1027,23 +787,23 @@ static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) host_log_wlan_auth_info(auth_frame_body.authAlgoNumber, auth_frame_body.authTransactionSeqNumber, auth_frame_body.authStatusCode); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; + mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; lim_send_auth_mgmt_frame(mac_ctx, &auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, LIM_NO_WEP_IN_FC, session); /* assign appropriate session_id to the timer object */ - mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id; + mac_ctx->lim.lim_timers.gLimAuthFailureTimer.sessionId = session_id; /* assign appropriate sessionId to the timer object */ - mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId = + mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId = session_id; lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); /* Activate Auth failure timer */ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, session->peSessionId, eLIM_AUTH_FAIL_TIMER)); lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_FAIL_TIMER); - if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) + if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer) != TX_SUCCESS) { pe_err("could not start Auth failure timer"); /* Cleanup as if auth timer expired */ @@ -1053,7 +813,7 @@ static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) session->peSessionId, eLIM_AUTH_RETRY_TIMER)); /* Activate Auth Retry timer */ if (tx_timer_activate - (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer) + (&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) != TX_SUCCESS) pe_err("could not activate Auth Retry timer"); } @@ -1075,6 +835,27 @@ static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) (uint32_t *) &mlm_auth_cnf); } +#ifdef WLAN_FEATURE_11W +static void lim_store_pmfcomeback_timerinfo(struct pe_session *session_entry) +{ + if (session_entry->opmode != QDF_STA_MODE || + !session_entry->limRmfEnabled) + return; + /* + * Store current MLM state in case ASSOC response returns with + * TRY_AGAIN_LATER return code. + */ + session_entry->pmf_retry_timer_info.lim_prev_mlm_state = + session_entry->limPrevMlmState; + session_entry->pmf_retry_timer_info.lim_mlm_state = + session_entry->limMlmState; +} +#else +static void lim_store_pmfcomeback_timerinfo(struct pe_session *session_entry) +{ +} +#endif /* WLAN_FEATURE_11W */ + /** * lim_process_mlm_assoc_req() - This function is called to process * MLM_ASSOC_REQ message from SME @@ -1123,9 +904,9 @@ static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg * Return Assoc confirm with Invalid parameters code. */ pe_warn("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= " - QDF_MAC_ADDR_STR, session_entry->limMlmState, + QDF_MAC_ADDR_FMT, session_entry->limMlmState, GET_LIM_SYSTEM_ROLE(session_entry), - QDF_MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr)); + QDF_MAC_ADDR_REF(mlm_assoc_req->peerMacAddr)); lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState); mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; @@ -1133,8 +914,9 @@ static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg } /* map the session entry pointer to the AssocFailureTimer */ - mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId = + mac_ctx->lim.lim_timers.gLimAssocFailureTimer.sessionId = mlm_assoc_req->sessionId; + lim_store_pmfcomeback_timerinfo(session_entry); session_entry->limPrevMlmState = session_entry->limMlmState; session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, @@ -1148,7 +930,7 @@ static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg /* Start association failure timer */ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER)); - if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer) + if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimAssocFailureTimer) != TX_SUCCESS) { pe_warn("SessionId:%d couldn't start Assoc failure timer", session_entry->peSessionId); @@ -1160,7 +942,7 @@ static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg end: /* Update PE session Id */ mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId; - /* Free up buffer allocated for assocReq */ + /* Free up buffer allocated for assoc_req */ qdf_mem_free(mlm_assoc_req); lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, (uint32_t *) &mlm_assoc_cnf); @@ -1227,9 +1009,9 @@ lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx, return; } - pe_debug("send disassoc rsp with ret code %d for" QDF_MAC_ADDR_STR, + pe_debug("send disassoc rsp with ret code %d for" QDF_MAC_ADDR_FMT, eSIR_SME_DEAUTH_STATUS, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_REF( mlm_disassocreq->peer_macaddr.bytes)); sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP; @@ -1249,17 +1031,6 @@ lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx, } break; - case eLIM_STA_IN_IBSS_ROLE: - break; - case eLIM_AP_ROLE: - case eLIM_P2P_DEVICE_GO: - if (true == - mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { - pe_err("CAC timer is running, drop disassoc from going out"); - mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS; - goto end; - } - break; default: break; } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ @@ -1283,8 +1054,8 @@ lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx, * Received LIM_MLM_DISASSOC_REQ for STA that does not * have context or in some transit state. */ - pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes)); + pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mlm_disassocreq->peer_macaddr.bytes)); if (stads) pe_err("Sta MlmState: %d", stads->mlmStaContext.mlmState); @@ -1423,7 +1194,7 @@ void lim_clean_up_disassoc_deauth_req(struct mac_context *mac_ctx, lim_process_disassoc_ack_timeout(mac_ctx); } else { if (tx_timer_running( - &mac_ctx->lim.limTimers.gLimDisassocAckTimer)) { + &mac_ctx->lim.lim_timers.gLimDisassocAckTimer)) { lim_deactivate_and_change_timer(mac_ctx, eLIM_DISASSOC_ACK_TIMER); } @@ -1442,7 +1213,7 @@ void lim_clean_up_disassoc_deauth_req(struct mac_context *mac_ctx, lim_process_deauth_ack_timeout(mac_ctx); } else { if (tx_timer_running( - &mac_ctx->lim.limTimers.gLimDeauthAckTimer)) { + &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) { lim_deactivate_and_change_timer(mac_ctx, eLIM_DEAUTH_ACK_TIMER); } @@ -1550,11 +1321,11 @@ lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, if (qdf_mem_cmp(mlm_deauth_req->peer_macaddr.bytes, curr_bssId, QDF_MAC_ADDR_SIZE)) { pe_err("received MLM_DEAUTH_REQ with invalid BSS id " - "Peer MAC: "QDF_MAC_ADDR_STR - " CFG BSSID Addr : "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + "Peer MAC: "QDF_MAC_ADDR_FMT + " CFG BSSID Addr : "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( mlm_deauth_req->peer_macaddr.bytes), - QDF_MAC_ADDR_ARRAY(curr_bssId)); + QDF_MAC_ADDR_REF(curr_bssId)); /* * Deauthentication response to host triggered * deauthentication @@ -1607,9 +1378,9 @@ lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, break; default: pe_warn("received MLM_DEAUTH_REQ with in state %d for peer " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session->limMlmState, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_REF( mlm_deauth_req->peer_macaddr.bytes)); lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); @@ -1624,16 +1395,6 @@ lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, pe_err("received MLM_DEAUTH_REQ IBSS Mode"); mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; goto end; - case eLIM_AP_ROLE: - case eLIM_P2P_DEVICE_GO: - if (true == - mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { - pe_err("CAC timer is running, drop disassoc from going out"); - mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; - goto end; - } - break; - default: break; } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ @@ -1658,9 +1419,9 @@ lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, */ pe_warn("received MLM_DEAUTH_REQ in mlme state %d for STA that " "does not have context, Addr=" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session->limMlmState, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_REF( mlm_deauth_req->peer_macaddr.bytes)); mlm_deauth_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED; @@ -1684,8 +1445,8 @@ lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, * received MLM_DEAUTH_REQ for STA that either has no context or * in some transit state */ - pe_warn("Invalid MLM_DEAUTH_REQ, Addr="QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes)); + pe_warn("Invalid MLM_DEAUTH_REQ, Addr="QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mlm_deauth_req->peer_macaddr.bytes)); /* Prepare and Send LIM_MLM_DEAUTH_CNF */ mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; goto end; @@ -1778,204 +1539,6 @@ void lim_process_mlm_deauth_req(struct mac_context *mac_ctx, uint32_t *msg_buf) (uint32_t *) msg_buf); } -/** - * lim_process_mlm_set_keys_req() - This function is called to process - * MLM_SETKEYS_REQ message from SME - * - * @mac_ctx: Pointer to Global MAC structure - * @msg_buf: A pointer to the MLM message buffer - * - * This function is called to process MLM_SETKEYS_REQ message from SME - * - * @Return: None - */ -static void -lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf) -{ - uint16_t aid; - uint16_t sta_idx = 0; - uint32_t default_key_id = 0; - struct qdf_mac_addr curr_bssid; - tpDphHashNode sta_ds; - tLimMlmSetKeysReq *mlm_set_keys_req; - tLimMlmSetKeysCnf mlm_set_keys_cnf; - struct pe_session *session; - - if (!msg_buf) { - pe_err("Buffer is Pointing to NULL"); - return; - } - - mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf; - if (mac_ctx->lim.gpLimMlmSetKeysReq) { - qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, - sizeof(*mlm_set_keys_req)); - qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); - mac_ctx->lim.gpLimMlmSetKeysReq = NULL; - } - /* Hold onto the SetKeys request parameters */ - mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req; - session = pe_find_session_by_session_id(mac_ctx, - mlm_set_keys_req->sessionId); - if (!session) { - pe_err("session does not exist for given sessionId"); - qdf_mem_zero(mlm_set_keys_req->key, - sizeof(mlm_set_keys_req->key)); - mlm_set_keys_req->numKeys = 0; - qdf_mem_free(mlm_set_keys_req); - mac_ctx->lim.gpLimMlmSetKeysReq = NULL; - return; - } - - pe_debug("Received MLM_SETKEYS_REQ with parameters:" - "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - ", - mlm_set_keys_req->aid, mlm_set_keys_req->edType, - mlm_set_keys_req->numKeys); - lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peer_macaddr.bytes, LOGD); - qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE); - - switch (GET_LIM_SYSTEM_ROLE(session)) { - case eLIM_STA_ROLE: - /* - * In case of TDLS, peerMac address need not be BssId. Skip this - * check if TDLS is enabled. - */ -#ifndef FEATURE_WLAN_TDLS - if ((!qdf_is_macaddr_broadcast( - &mlm_set_keys_req->peer_macaddr)) && - (!qdf_is_macaddr_equal(&mlm_set_keys_req->peer_macaddr, - &curr_bssid))) { - pe_debug("Received MLM_SETKEYS_REQ with invalid BSSID" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mlm_set_keys_req-> - peer_macaddr.bytes)); - /* - * Prepare and Send LIM_MLM_SETKEYS_CNF with error code - */ - mlm_set_keys_cnf.resultCode = - eSIR_SME_INVALID_PARAMETERS; - goto end; - } -#endif - break; - case eLIM_STA_IN_IBSS_ROLE: - /* - * update the IBSS PE session encrption type based on the - * key type - */ - session->encryptType = mlm_set_keys_req->edType; - break; - default: - break; - } - - /* - * Use the "unicast" parameter to determine if the "Group Keys" - * are being set. - * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast - * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set - */ - if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) { - pe_debug("Trying to set Group Keys...%d", - mlm_set_keys_req->sessionId); - /* - * When trying to set Group Keys for any security mode other - * than WEP, use the STA Index corresponding to the AP... - */ - switch (mlm_set_keys_req->edType) { - case eSIR_ED_CCMP: - case eSIR_ED_GCMP: - case eSIR_ED_GCMP_256: -#ifdef WLAN_FEATURE_11W - case eSIR_ED_AES_128_CMAC: - case eSIR_ED_AES_GMAC_128: - case eSIR_ED_AES_GMAC_256: -#endif - sta_idx = session->staId; - break; - default: - break; - } - } else { - pe_debug("Trying to set Unicast Keys..."); - /* - * Check if there exists a context for the - * peer entity for which keys need to be set. - */ - sta_ds = dph_lookup_hash_entry(mac_ctx, - mlm_set_keys_req->peer_macaddr.bytes, &aid, - &session->dph.dphHashTable); - if ((!sta_ds) || - ((sta_ds->mlmStaContext.mlmState != - eLIM_MLM_LINK_ESTABLISHED_STATE) && - !LIM_IS_AP_ROLE(session))) { - /* - * Received LIM_MLM_SETKEYS_REQ for STA that does not - * have context or in some transit state. - */ - pe_debug("Invalid MLM_SETKEYS_REQ, Addr = " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mlm_set_keys_req-> - peer_macaddr.bytes)); - /* Prepare and Send LIM_MLM_SETKEYS_CNF */ - mlm_set_keys_cnf.resultCode = - eSIR_SME_INVALID_PARAMETERS; - goto end; - } else { - sta_idx = sta_ds->staIndex; - } - } - - if ((mlm_set_keys_req->numKeys == 0) - && (mlm_set_keys_req->edType != eSIR_ED_NONE)) { - /* - * Broadcast/Multicast Keys (for WEP!!) are NOT sent - * via this interface!! This indicates to HAL that the WEP Keys - * need to be extracted from the CFG and applied to hardware - */ - default_key_id = 0xff; - } else if (mlm_set_keys_req->key[0].keyId && - ((mlm_set_keys_req->edType == eSIR_ED_WEP40) || - (mlm_set_keys_req->edType == eSIR_ED_WEP104))) { - /* - * If the Key Id is non zero and encryption mode is WEP, - * the key index is coming from the upper layers so that key - * only need to be used as the default tx key, This is being - * used only in case of WEP mode in HAL - */ - default_key_id = mlm_set_keys_req->key[0].keyId; - } else { - default_key_id = 0; - } - pe_debug("Trying to set keys for STA Index [%d], using default_key_id [%d]", - sta_idx, default_key_id); - - if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) { - session->limPrevMlmState = session->limMlmState; - session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE; - MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, - session->peSessionId, session->limMlmState)); - pe_debug("Trying to set Group Keys...%d", - session->peSessionId); - /* Package WMA_SET_BSSKEY_REQ message parameters */ - lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session); - - return; - } else { - /* - * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message - * parameters - */ - lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx, - (uint8_t) default_key_id, session, - true); - return; - } -end: - mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId; - lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf); -} - void lim_process_join_failure_timeout(struct mac_context *mac_ctx) { tLimMlmJoinCnf mlm_join_cnf; @@ -1986,7 +1549,7 @@ void lim_process_join_failure_timeout(struct mac_context *mac_ctx) struct pe_session *session; session = pe_find_session_by_session_id(mac_ctx, - mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId); + mac_ctx->lim.lim_timers.gLimJoinFailureTimer.sessionId); if (!session) { pe_err("Session Does not exist for given sessionID"); return; @@ -2008,12 +1571,12 @@ void lim_process_join_failure_timeout(struct mac_context *mac_ctx) eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); /* Issue MLM join confirm with timeout reason code */ pe_err("Join Failure Timeout, In eLIM_MLM_WT_JOIN_BEACON_STATE session:%d " - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT, session->peSessionId, - QDF_MAC_ADDR_ARRAY(session->bssId)); + QDF_MAC_ADDR_REF(session->bssId)); mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE; - mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + mlm_join_cnf.protStatusCode = STATUS_NO_NETWORK_FOUND; session->limMlmState = eLIM_MLM_IDLE_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, session->limMlmState)); @@ -2051,23 +1614,23 @@ static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ct tSirMacSSid ssid; session = pe_find_session_by_session_id(mac_ctx, - mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId); + mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer.sessionId); if (!session) { pe_err("session does not exist for given SessionId: %d", - mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer. + mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer. sessionId); return; } if ((true == - tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer)) + tx_timer_running(&mac_ctx->lim.lim_timers.gLimJoinFailureTimer)) && (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) { qdf_mem_copy(ssid.ssId, session->ssId.ssId, session->ssId.length); ssid.length = session->ssId.length; lim_send_probe_req_mgmt_frame(mac_ctx, &ssid, session->pLimMlmJoinReq->bssDescription.bssId, - session->currentOperChannel /*chanNum */, + session->curr_op_freq, session->self_mac_addr, session->dot11mode, &session->lim_join_req->addIEScan.length, session->lim_join_req->addIEScan.addIEdata); @@ -2075,7 +1638,7 @@ static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ct eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); /* Activate Join Periodic Probe Req timer */ if (tx_timer_activate( - &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != + &mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) { pe_warn("could not activate Periodic Join req failure timer"); return; @@ -2083,6 +1646,36 @@ static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ct } } +static void lim_handle_sae_auth_timeout(struct mac_context *mac_ctx, + struct pe_session *session_entry) +{ + struct sae_auth_retry *sae_retry; + + sae_retry = mlme_get_sae_auth_retry(session_entry->vdev); + if (!(sae_retry && sae_retry->sae_auth.data)) { + pe_debug("sae auth frame is not buffered vdev id %d", + session_entry->vdev_id); + return; + } + + pe_debug("retry sae auth for seq num %d vdev id %d", + mac_ctx->mgmtSeqNum, session_entry->vdev_id); + lim_send_frame(mac_ctx, session_entry->vdev_id, + sae_retry->sae_auth.data, sae_retry->sae_auth.len); + + sae_retry->sae_auth_max_retry--; + /* Activate Auth Retry timer if max_retries are not done */ + if (!sae_retry->sae_auth_max_retry || (tx_timer_activate( + &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) != + TX_SUCCESS)) + goto free_and_deactivate_timer; + + return; + +free_and_deactivate_timer: + lim_sae_auth_cleanup_retry(mac_ctx, session_entry->vdev_id); +} + /** * lim_process_auth_retry_timer()- function to Retry Auth when auth timeout * occurs @@ -2094,26 +1687,31 @@ static void lim_process_auth_retry_timer(struct mac_context *mac_ctx) { struct pe_session *session_entry; tAniAuthType auth_type; - tLimTimers *lim_timers = &mac_ctx->lim.limTimers; - uint16_t vdev_id = + tLimTimers *lim_timers = &mac_ctx->lim.lim_timers; + uint16_t pe_session_id = lim_timers->g_lim_periodic_auth_retry_timer.sessionId; - session_entry = pe_find_session_by_session_id(mac_ctx, vdev_id); + session_entry = pe_find_session_by_session_id(mac_ctx, pe_session_id); if (!session_entry) { - pe_err("session does not exist for vdev_id: %d", vdev_id); + pe_err("session does not exist for pe_session_id: %d", + pe_session_id); return; } - if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) && + /** For WPA3 SAE gLimAuthFailureTimer is not running hence + * we don't enter in below "if" block in case of wpa3 sae + */ + if (tx_timer_running(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer) && (session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) && - (LIM_AUTH_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) { + (LIM_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) { tSirMacAuthFrameBody auth_frame; /* * Send the auth retry only in case we have received ack failure * else just restart the retry timer. */ - if (LIM_AUTH_ACK_RCD_FAILURE == mac_ctx->auth_ack_status && + if (((mac_ctx->auth_ack_status == LIM_ACK_RCD_FAILURE) || + (mac_ctx->auth_ack_status == LIM_TX_FAILED)) && mac_ctx->lim.gpLimMlmAuthReq) { auth_type = mac_ctx->lim.gpLimMlmAuthReq->authType; @@ -2128,7 +1726,7 @@ static void lim_process_auth_retry_timer(struct mac_context *mac_ctx) SIR_MAC_AUTH_FRAME_1; auth_frame.authStatusCode = 0; pe_debug("Retry Auth"); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; + mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; lim_increase_fils_sequence_number(session_entry); lim_send_auth_mgmt_frame(mac_ctx, &auth_frame, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, @@ -2139,13 +1737,15 @@ static void lim_process_auth_retry_timer(struct mac_context *mac_ctx) /* Activate Auth Retry timer */ if (tx_timer_activate - (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer) - != TX_SUCCESS) { + (&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) + != TX_SUCCESS) pe_err("could not activate Auth Retry failure timer"); - return; - } + + return; } - return; + + /* Auth retry time out for wpa3 sae */ + lim_handle_sae_auth_timeout(mac_ctx, session_entry); } /*** lim_process_auth_retry_timer() ***/ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx) @@ -2153,12 +1753,13 @@ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx) /* fetch the pe_session based on the sessionId */ struct pe_session *session; uint32_t val; + enum wlan_status_code proto_status_code; #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM host_log_rssi_pkt_type *rssi_log = NULL; #endif session = pe_find_session_by_session_id(mac_ctx, - mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId); + mac_ctx->lim.lim_timers.gLimAuthFailureTimer.sessionId); if (!session) { pe_err("Session Does not exist for given sessionID"); return; @@ -2198,10 +1799,13 @@ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx) } mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val; } + lim_fill_status_code(SIR_MAC_MGMT_AUTH, + mac_ctx->auth_ack_status, + &proto_status_code); lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, - eSIR_MAC_UNSPEC_FAILURE_REASON, session); + proto_status_code, session); break; default: /* @@ -2254,14 +1858,14 @@ lim_process_auth_rsp_timeout(struct mac_context *mac_ctx, uint32_t auth_idx) if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) { if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) { pe_err("received AUTH rsp timeout in unexpected " - "state for MAC address: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr)); + "state for MAC address: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(auth_node->peerMacAddr)); } else { auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE; auth_node->fTimerStarted = 0; pe_debug("AUTH rsp timedout for MAC address " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(auth_node->peerMacAddr)); /* Change timer to reactivate it in future */ lim_deactivate_and_change_per_sta_id_timer(mac_ctx, eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx); @@ -2272,11 +1876,11 @@ lim_process_auth_rsp_timeout(struct mac_context *mac_ctx, uint32_t auth_idx) } void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, - uint32_t msg_type) + uint32_t msg_type) { - tLimMlmAssocCnf mlm_assoc_cnf; struct pe_session *session; + enum wlan_status_code proto_status_code; #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM host_log_rssi_pkt_type *rssi_log = NULL; #endif @@ -2288,10 +1892,10 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, if (msg_type == LIM_ASSOC) session_id = - mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId; + mac_ctx->lim.lim_timers.gLimAssocFailureTimer.sessionId; else session_id = - mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId; + mac_ctx->lim.lim_timers.gLimReassocFailureTimer.sessionId; session = pe_find_session_by_session_id(mac_ctx, session_id); if (!session) { @@ -2321,14 +1925,14 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, mlme_get_reconn_after_assoc_timeout_flag(mac_ctx->psoc, session->vdev_id)) { pe_debug("vdev: %d skip sending deauth on channel freq %d to BSSID: " - QDF_MAC_ADDR_STR, session->vdev_id, - session->currentOperChannel, - QDF_MAC_ADDR_ARRAY(session->bssId)); + QDF_MAC_ADDR_FMT, session->vdev_id, + session->curr_op_freq, + QDF_MAC_ADDR_REF(session->bssId)); } else { pe_debug("vdev: %d try sending deauth on channel freq %d to BSSID: " - QDF_MAC_ADDR_STR, session->vdev_id, - session->currentOperChannel, - QDF_MAC_ADDR_ARRAY(session->bssId)); + QDF_MAC_ADDR_FMT, session->vdev_id, + session->curr_op_freq, + QDF_MAC_ADDR_REF(session->bssId)); lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, session->bssId, session, false); @@ -2356,6 +1960,7 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, session->peSessionId, session->limMlmState)); /* Change timer for future activations */ lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); + lim_stop_pmfcomeback_timer(session); /* * Free up buffer allocated for JoinReq held by * MLM state machine @@ -2366,14 +1971,17 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, } /* To remove the preauth node in case of fail to associate */ if (lim_search_pre_auth_list(mac_ctx, session->bssId)) { - pe_debug("delete pre auth node for "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(session->bssId)); + pe_debug("delete pre auth node for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(session->bssId)); lim_delete_pre_auth_node(mac_ctx, session->bssId); } + lim_fill_status_code(SIR_MAC_MGMT_ASSOC_RSP, + mac_ctx->assoc_ack_status, + &proto_status_code); mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE; - mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + mlm_assoc_cnf.protStatusCode = proto_status_code; /* Update PE session Id */ mlm_assoc_cnf.sessionId = session->peSessionId; if (msg_type == LIM_ASSOC) { @@ -2403,38 +2011,3 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, session); } } - -/** - * lim_set_channel() - set channel api for lim - * - * @mac_ctx: Pointer to Global MAC structure - * @channel: power save state - * @ch_center_freq_seg0: center freq seq 0 - * @ch_center_freq_seg1: center freq seq 1 - * @ch_width: channel width - * @max_tx_power: max tx power - * @pe_session_id: pe session id - * - * set channel api for lim - * - * @Return: None - */ -void lim_set_channel(struct mac_context *mac_ctx, uint8_t channel, - uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width, int8_t max_tx_power, - uint8_t pe_session_id, uint32_t cac_duration_ms, - uint32_t dfs_regdomain) -{ - struct pe_session *pe_session; - - pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id); - - if (!pe_session) { - pe_err("Invalid PE session: %d", pe_session_id); - return; - } - lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0, - ch_center_freq_seg1, ch_width, - max_tx_power, pe_session_id, false, - cac_duration_ms, dfs_regdomain); -} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index a1bcf5599edb9739cb754cf26e717dc19303adfd..7621d0ae7a02bd648c393eaf0fcdc3278926879b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -41,7 +41,7 @@ #include "wlan_policy_mgr_api.h" #include "nan_datapath.h" #include "wlan_reg_services_api.h" -#include "wlan_pkt_capture_ucfg_api.h" +#include "wma.h" #define MAX_SUPPORTED_PEERS_WEP 16 @@ -153,8 +153,9 @@ void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf) struct pe_session *pe_session = NULL; tLimMlmStartCnf *pLimMlmStartCnf; uint8_t smesessionId; - uint8_t channelId; + uint32_t chan_freq, ch_cfreq1 = 0; uint8_t send_bcon_ind = false; + enum reg_wifi_band band; if (!msg_buf) { pe_err("Buffer is Pointing to NULL"); @@ -207,7 +208,6 @@ void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf) pe_session, smesessionId); if (pe_session && (((tLimMlmStartCnf *)msg_buf)->resultCode == eSIR_SME_SUCCESS)) { - channelId = pe_session->pLimStartBssReq->channelId; lim_ndi_mlme_vdev_up_transition(pe_session); /* We should start beacon transmission only if the channel @@ -215,30 +215,42 @@ void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf) * availability check is done. The PE will receive an explicit * request from upper layers to start the beacon transmission */ + chan_freq = pe_session->curr_op_freq; + band = wlan_reg_freq_to_band(pe_session->curr_op_freq); + if (pe_session->ch_center_freq_seg1) + ch_cfreq1 = wlan_reg_chan_band_to_freq( + mac->pdev, + pe_session->ch_center_freq_seg1, + BIT(band)); + if (!(LIM_IS_IBSS_ROLE(pe_session) || (LIM_IS_AP_ROLE(pe_session)))) return; if (pe_session->ch_width == CH_WIDTH_160MHZ) { send_bcon_ind = false; } else if (pe_session->ch_width == CH_WIDTH_80P80MHZ) { - if ((wlan_reg_get_channel_state(mac->pdev, channelId) - != CHANNEL_STATE_DFS) && - (wlan_reg_get_channel_state(mac->pdev, - pe_session->ch_center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) != - CHANNEL_STATE_DFS)) + if ((wlan_reg_get_channel_state_for_freq( + mac->pdev, chan_freq) != + CHANNEL_STATE_DFS) && + (wlan_reg_get_channel_state_for_freq( + mac->pdev, ch_cfreq1) != + CHANNEL_STATE_DFS)) send_bcon_ind = true; } else { - if (wlan_reg_get_channel_state(mac->pdev, channelId) + if (wlan_reg_get_channel_state_for_freq(mac->pdev, + chan_freq) != CHANNEL_STATE_DFS) send_bcon_ind = true; } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq)) + send_bcon_ind = true; + if (send_bcon_ind) { /* Configure beacon and send beacons to HAL */ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, - FL("Start Beacon with ssid %s Ch %d"), + "Start Beacon with ssid %s Ch freq %d", pe_session->ssId.ssId, - pe_session->currentOperChannel); + pe_session->curr_op_freq); lim_send_beacon(mac, pe_session); lim_enable_obss_detection_config(mac, pe_session); lim_send_obss_color_collision_cfg(mac, pe_session, @@ -286,8 +298,9 @@ void lim_process_mlm_join_cnf(struct mac_context *mac_ctx, /* Process Join confirm from MLM */ if (result_code == eSIR_SME_SUCCESS) { /* Setup hardware upfront */ - if (lim_sta_send_add_bss_pre_assoc(mac_ctx, false, - session_entry) == QDF_STATUS_SUCCESS) + if (lim_sta_send_add_bss_pre_assoc(mac_ctx, + session_entry) == + QDF_STATUS_SUCCESS) return; else result_code = eSIR_SME_REFUSED; @@ -404,6 +417,38 @@ static void lim_send_mlm_assoc_req(struct mac_context *mac_ctx, (uint32_t *) assoc_req); } +#ifdef WLAN_FEATURE_11W +/** + * lim_pmf_comeback_timer_callback() -PMF callback handler + * @context: Timer context + * + * This function is called to processes the PMF comeback + * callback + * + * Return: None + */ +void lim_pmf_comeback_timer_callback(void *context) +{ + struct comeback_timer_info *info = + (struct comeback_timer_info *)context; + struct mac_context *mac_ctx = info->mac; + struct pe_session *session; + + session = pe_find_session_by_vdev_id(mac_ctx, info->vdev_id); + if (!session) { + pe_err("no session found for vdev %d", info->vdev_id); + return; + } + + pe_info("comeback later timer expired. sending MLM ASSOC req for vdev %d", + session->vdev_id); + /* set MLM state such that ASSOC REQ packet will be sent out */ + session->limPrevMlmState = info->lim_prev_mlm_state; + session->limMlmState = info->lim_mlm_state; + lim_send_mlm_assoc_req(mac_ctx, session); +} +#endif /* WLAN_FEATURE_11W */ + /** * lim_process_mlm_auth_cnf()-Process Auth confirmation * @mac_ctx: Pointer to Global MAC structure @@ -647,14 +692,21 @@ void lim_fill_sme_assoc_ind_params( struct mac_context *mac_ctx, tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind, - struct pe_session *session_entry) + struct pe_session *session_entry, bool assoc_req_alloc) { sme_assoc_ind->length = sizeof(struct assoc_ind); sme_assoc_ind->sessionId = session_entry->smeSessionId; /* Required for indicating the frames to upper layer */ sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength; - sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr; + if (assoc_req_alloc && assoc_ind->assocReqLength) { + sme_assoc_ind->assocReqPtr = qdf_mem_malloc( + assoc_ind->assocReqLength); + qdf_mem_copy(sme_assoc_ind->assocReqPtr, assoc_ind->assocReqPtr, + assoc_ind->assocReqLength); + } else { + sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr; + } sme_assoc_ind->beaconPtr = session_entry->beacon; sme_assoc_ind->beaconLength = session_entry->bcnLen; @@ -768,7 +820,7 @@ void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf) pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND; lim_fill_sme_assoc_ind_params(mac, (tpLimMlmAssocInd)msg_buf, pSirSmeAssocInd, - pe_session); + pe_session, false); msg.type = eWNI_SME_ASSOC_IND; msg.bodyptr = pSirSmeAssocInd; msg.bodyval = 0; @@ -782,7 +834,7 @@ void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf) return; } - pSirSmeAssocInd->staId = sta->staIndex; + pSirSmeAssocInd->reassocReq = sta->mlmStaContext.subType; pSirSmeAssocInd->timingMeasCap = sta->timingMeasCap; MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG, @@ -946,8 +998,8 @@ static void lim_process_mlm_deauth_ind(struct mac_context *mac_ctx, deauth_ind->peerMacAddr, &session_id); if (!session) { - pe_err("session does not exist for Addr:" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(deauth_ind->peerMacAddr)); + pe_err("session does not exist for Addr:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(deauth_ind->peerMacAddr)); return; } role = GET_LIM_SYSTEM_ROLE(session); @@ -1179,41 +1231,20 @@ void lim_process_mlm_set_keys_cnf(struct mac_context *mac, uint32_t *msg_buf) pe_session, pe_session->smeSessionId); } /*** end lim_process_mlm_set_keys_cnf() ***/ -/** - * lim_join_result_callback() - Callback to handle join rsp - * @mac: Pointer to Global MAC structure - * @param: callback argument - * @status: status - * - * This callback function is used to delete PE session - * entry and send join response to sme. - * - * Return: None - */ -static void lim_join_result_callback(struct mac_context *mac, void *param, - bool status) +void lim_join_result_callback(struct mac_context *mac, + uint8_t vdev_id) { - join_params *link_state_params = (join_params *) param; struct pe_session *session; - uint8_t sme_session_id; - if (!link_state_params) { - pe_err("Link state params is NULL"); - return; - } - session = pe_find_session_by_session_id(mac, link_state_params-> - pe_session_id); + session = pe_find_session_by_vdev_id(mac, vdev_id); if (!session) { - qdf_mem_free(link_state_params); return; } - sme_session_id = session->smeSessionId; lim_send_sme_join_reassoc_rsp(mac, eWNI_SME_JOIN_RSP, - link_state_params->result_code, - link_state_params->prot_status_code, - session, sme_session_id); + session->result_code, + session->prot_status_code, + session, vdev_id); pe_delete_session(mac, session); - qdf_mem_free(link_state_params); } QDF_STATUS lim_sta_handle_connect_fail(join_params *param) @@ -1276,24 +1307,18 @@ QDF_STATUS lim_sta_handle_connect_fail(join_params *param) * failure should be sent to the upper layers. */ if (param->result_code != eSIR_SME_PEER_CREATE_FAILED) { - join_params *link_state_arg; - - link_state_arg = qdf_mem_malloc(sizeof(*link_state_arg)); - if (link_state_arg) { - link_state_arg->result_code = param->result_code; - link_state_arg->prot_status_code = - param->prot_status_code; - link_state_arg->pe_session_id = session->peSessionId; - } - if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE, - session->bssId, - session->self_mac_addr, - lim_join_result_callback, - link_state_arg) != QDF_STATUS_SUCCESS) { - qdf_mem_free(link_state_arg); - pe_err("Failed to set the LinkState"); + QDF_STATUS status; + + session->prot_status_code = param->prot_status_code; + session->result_code = param->result_code; + + status = wma_send_vdev_stop(session->smeSessionId); + if (QDF_IS_STATUS_ERROR(status)) { + lim_join_result_callback(mac_ctx, + session->smeSessionId); } - return QDF_STATUS_SUCCESS; + + return status; } @@ -1415,8 +1440,6 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, tpDphHashNode sta_ds; uint32_t msg_type = LIM_MLM_ASSOC_CNF; tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr; - struct pe_session *ft_session = NULL; - uint8_t ft_session_id; if (!add_sta_params) { pe_err("Encountered NULL Pointer"); @@ -1429,9 +1452,9 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, if (true == session_entry->fDeauthReceived) { pe_err("Received Deauth frame in ADD_STA_RESP state"); if (QDF_STATUS_SUCCESS == add_sta_params->status) { - pe_err("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA staIdx: %d limMlmState: %d", - add_sta_params->staIdx, - session_entry->limMlmState); + pe_err("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA limMlmState: %d bssid "QDF_MAC_ADDR_FMT, + session_entry->limMlmState, + QDF_MAC_ADDR_REF(add_sta_params->staMac)); if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) @@ -1446,7 +1469,6 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA; mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; - session_entry->staId = add_sta_params->staIdx; goto end; } } @@ -1460,23 +1482,6 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, (tSirResultCodes) eSIR_SME_REFUSED; goto end; } - if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) { - /* check if we have keys(PTK)to install in case of 11r */ - tpftPEContext ft_ctx = &session_entry->ftPEContext; - - ft_session = pe_find_session_by_bssid(mac_ctx, - session_entry->limReAssocbssId, &ft_session_id); - if (ft_session && - ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid - == true) { - tpLimMlmSetKeysReq pMlmStaKeys = - &ft_ctx->PreAuthKeyInfo.extSetStaKeyParam; - lim_send_set_sta_key_req(mac_ctx, pMlmStaKeys, - 0, 0, ft_session, false); - ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid = - false; - } - } /* * Update the DPH Hash Entry for this STA * with proper state info @@ -1495,14 +1500,6 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, session_entry->limMlmState)); - /* - * Storing the self StaIndex(Generated by HAL) in - * session context, instead of storing it in DPH Hash - * entry for Self STA. - * DPH entry for the self STA stores the sta index for - * the BSS entry to which the STA is associated - */ - session_entry->staId = add_sta_params->staIdx; #ifdef WLAN_DEBUG mac_ctx->lim.gLimNumLinkEsts++; @@ -1524,12 +1521,12 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, pe_debug("Send user cfg MU EDCA params to FW"); lim_send_edca_params(mac_ctx, mac_ctx->usr_mu_edca_params, - sta_ds->bssId, true); + session_entry->vdev_id, true); } else if (session_entry->mu_edca_present) { pe_debug("Send MU EDCA params to FW"); lim_send_edca_params(mac_ctx, session_entry->ap_mu_edca_params, - sta_ds->bssId, true); + session_entry->vdev_id, true); } } } else { @@ -1556,7 +1553,7 @@ void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, } void lim_process_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, + struct del_bss_resp *vdev_stop_rsp, struct pe_session *pe_session) { /* we need to process the deferred message since the initiating req. there might be nested request. */ @@ -1567,10 +1564,10 @@ void lim_process_mlm_del_bss_rsp(struct mac_context *mac, if (LIM_IS_AP_ROLE(pe_session) && (pe_session->statypeForBss == STA_ENTRY_SELF)) { - lim_process_ap_mlm_del_bss_rsp(mac, limMsgQ, pe_session); + lim_process_ap_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session); return; } - lim_process_sta_mlm_del_bss_rsp(mac, limMsgQ, pe_session); + lim_process_sta_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session); #ifdef WLAN_FEATURE_11W if (pe_session->limRmfEnabled) { @@ -1583,28 +1580,19 @@ void lim_process_mlm_del_bss_rsp(struct mac_context *mac, } void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, + struct del_bss_resp *vdev_stop_rsp, struct pe_session *pe_session) { - tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr; tpDphHashNode sta = dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER, &pe_session->dph.dphHashTable); tSirResultCodes status_code = eSIR_SME_SUCCESS; - if (!pDelBssParams) { + if (!vdev_stop_rsp) { pe_err("Invalid body pointer in message"); goto end; } - if (QDF_STATUS_SUCCESS == pDelBssParams->status) { - if (lim_set_link_state - (mac, eSIR_LINK_IDLE_STATE, pe_session->bssId, - pe_session->self_mac_addr, NULL, - NULL) != QDF_STATUS_SUCCESS) { - pe_err("Failure in setting link state to IDLE"); - status_code = eSIR_SME_REFUSED; - goto end; - } + if (vdev_stop_rsp->status == QDF_STATUS_SUCCESS) { if (!sta) { pe_err("DPH Entry for STA 1 missing"); status_code = eSIR_SME_REFUSED; @@ -1617,16 +1605,13 @@ void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac, status_code = eSIR_SME_REFUSED; goto end; } - pe_debug("STA AssocID %d MAC %pM", sta->assocId, sta->staAddr); + pe_debug("STA AssocID %d MAC "QDF_MAC_ADDR_FMT, sta->assocId, + QDF_MAC_ADDR_REF(sta->staAddr)); } else { pe_err("DEL BSS failed!"); status_code = eSIR_SME_STOP_BSS_FAILURE; } end: - if (0 != limMsgQ->bodyptr) { - qdf_mem_free(pDelBssParams); - limMsgQ->bodyptr = NULL; - } if (!sta) return; if ((LIM_IS_STA_ROLE(pe_session)) && @@ -1648,24 +1633,19 @@ void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac, } void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, + struct del_bss_resp *vdev_stop_rsp, struct pe_session *pe_session) { tSirResultCodes rc = eSIR_SME_SUCCESS; - QDF_STATUS status; - tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr; - tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (!pe_session) { pe_err("Session entry passed is NULL"); - if (pDelBss) { - qdf_mem_free(pDelBss); - limMsgQ->bodyptr = NULL; - } + if (vdev_stop_rsp) + qdf_mem_free(vdev_stop_rsp); return; } - if (!pDelBss) { + if (!vdev_stop_rsp) { pe_err("BSS: DEL_BSS_RSP with no body!"); rc = eSIR_SME_REFUSED; goto end; @@ -1681,18 +1661,11 @@ void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac, rc = eSIR_SME_REFUSED; goto end; } - if (pDelBss->status != QDF_STATUS_SUCCESS) { - pe_err("BSS: DEL_BSS_RSP error (%x) Bss %d", - pDelBss->status, pDelBss->bss_idx); + if (vdev_stop_rsp->status != QDF_STATUS_SUCCESS) { + pe_err("BSS: DEL_BSS_RSP error (%x)", vdev_stop_rsp->status); rc = eSIR_SME_STOP_BSS_FAILURE; goto end; } - status = lim_set_link_state(mac, eSIR_LINK_IDLE_STATE, nullBssid, - pe_session->self_mac_addr, NULL, NULL); - if (status != QDF_STATUS_SUCCESS) { - rc = eSIR_SME_REFUSED; - goto end; - } /** Softmac may send all the buffered packets right after resuming the transmission hence * to occupy the medium during non channel occupancy period. So resume the transmission after * HAL gives back the response. @@ -1705,11 +1678,6 @@ void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac, lim_send_sme_rsp(mac, eWNI_SME_STOP_BSS_RSP, rc, pe_session->smeSessionId); pe_delete_session(mac, pe_session); - - if (pDelBss) { - qdf_mem_free(pDelBss); - limMsgQ->bodyptr = NULL; - } } /** @@ -1810,20 +1778,20 @@ void lim_process_ap_mlm_del_sta_rsp(struct mac_context *mac_ctx, goto end; } - pe_debug("AP received the DEL_STA_RSP for assocID: %X", - del_sta_params->assocId); + pe_debug("AP received the DEL_STA_RSP for assocID: %X sta mac " + QDF_MAC_ADDR_FMT, del_sta_params->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); if ((eLIM_MLM_WT_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState) && (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState)) { - pe_err("Received unexpected WMA_DEL_STA_RSP in state %s for staId %d assocId %d", - lim_mlm_state_str(sta_ds->mlmStaContext.mlmState), - sta_ds->staIndex, sta_ds->assocId); + pe_err("Received unexpected WMA_DEL_STA_RSP in state %s for assocId %d", + lim_mlm_state_str(sta_ds->mlmStaContext.mlmState), + sta_ds->assocId); status_code = eSIR_SME_REFUSED; goto end; } - pe_debug("Deleted STA AssocID %d staId %d MAC", - sta_ds->assocId, sta_ds->staIndex); + pe_debug("Deleted STA AssocID %d", sta_ds->assocId); lim_print_mac_addr(mac_ctx, sta_ds->staAddr, LOGD); if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == sta_ds->mlmStaContext.mlmState) { @@ -1960,14 +1928,12 @@ void lim_process_ap_mlm_add_sta_rsp(struct mac_context *mac, pe_session); goto end; } - sta->bssId = pAddStaParams->bss_idx; - sta->staIndex = pAddStaParams->staIdx; sta->nss = pAddStaParams->nss; /* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */ sta->valid = 1; sta->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE; - pe_debug("AddStaRsp Success.STA AssocID %d staId %d MAC", - sta->assocId, sta->staIndex); + pe_debug("AddStaRsp Success.STA AssocID %d sta mac" QDF_MAC_ADDR_FMT, + sta->assocId, QDF_MAC_ADDR_REF(sta->staAddr)); lim_print_mac_addr(mac, sta->staAddr, LOGD); /* For BTAMP-AP, the flow sequence shall be: @@ -1992,81 +1958,36 @@ void lim_process_ap_mlm_add_sta_rsp(struct mac_context *mac, return; } -/** - * lim_process_ap_mlm_add_bss_rsp() - * - ***FUNCTION: - * This function is called to process a WMA_ADD_BSS_RSP from HAL. - * Upon receipt of this message from HAL, MLME - - * > Validates the result of WMA_ADD_BSS_REQ - * > Init other remaining LIM variables - * > Init the AID pool, for that BSSID - * > Init the Pre-AUTH list, for that BSSID - * > Create LIM timers, specific to that BSSID - * > Init DPH related parameters that are specific to that BSSID - * > TODO - When do we do the actual change channel? - * - ***LOGIC: - * SME sends eWNI_SME_START_BSS_REQ to LIM - * LIM sends LIM_MLM_START_REQ to MLME - * MLME sends WMA_ADD_BSS_REQ to HAL - * HAL responds with WMA_ADD_BSS_RSP to MLME - * MLME responds with LIM_MLM_START_CNF to LIM - * LIM responds with eWNI_SME_START_BSS_RSP to SME - * - ***ASSUMPTIONS: - * struct scheduler_msg.body is allocated by MLME during - * lim_process_mlm_start_req - * struct scheduler_msg.body will now be freed by this routine - * - ***NOTE: - * - * @param mac Pointer to Global MAC structure - * @param struct scheduler_msg The MsgQ header, which contains - * the response buffer - * - * @return None - */ static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ) + struct add_bss_rsp *add_bss_rsp) { tLimMlmStartCnf mlmStartCnf; struct pe_session *pe_session; uint8_t isWepEnabled = false; - tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; - if (!pAddBssParams) { + if (!add_bss_rsp) { pe_err("Encountered NULL Pointer"); - goto end; + return; } /* TBD: free the memory before returning, do it for all places where lookup fails. */ - pe_session = pe_find_session_by_session_id(mac, - pAddBssParams->sessionId); + pe_session = pe_find_session_by_vdev_id(mac, add_bss_rsp->vdev_id); if (!pe_session) { - pe_err("session does not exist for given sessionId"); - if (pAddBssParams) { - qdf_mem_free(pAddBssParams); - limMsgQ->bodyptr = NULL; - } + pe_err("session does not exist for vdev_id %d", + add_bss_rsp->vdev_id); return; } /* Update PE session Id */ - mlmStartCnf.sessionId = pAddBssParams->sessionId; - if (QDF_STATUS_SUCCESS == pAddBssParams->status) { + mlmStartCnf.sessionId = pe_session->peSessionId; + if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS"); - if (lim_set_link_state - (mac, eSIR_LINK_AP_STATE, pe_session->bssId, - pe_session->self_mac_addr, NULL, - NULL) != QDF_STATUS_SUCCESS) - goto end; /* Set MLME state */ pe_session->limMlmState = eLIM_MLM_BSS_STARTED_STATE; - pe_session->chainMask = pAddBssParams->chainMask; - pe_session->smpsMode = pAddBssParams->smpsMode; + pe_session->chainMask = add_bss_rsp->chain_mask; + pe_session->smpsMode = add_bss_rsp->smps_mode; MTRACE(mac_trace (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId, pe_session->limMlmState)); - if (eSIR_IBSS_MODE == pAddBssParams->bssType) { + if (eSIR_IBSS_MODE == pe_session->bssType) { /** IBSS is 'active' when we receive * Beacon frames from other STAs that are part of same IBSS. * Mark internal state as inactive until then. @@ -2075,11 +1996,10 @@ static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac, pe_session->statypeForBss = STA_ENTRY_PEER; /* to know session created for self/peer */ limResetHBPktCount(pe_session); } - pe_session->bss_idx = (uint8_t)pAddBssParams->bss_idx; pe_session->limSystemRole = eLIM_STA_IN_IBSS_ROLE; - if (eSIR_INFRA_AP_MODE == pAddBssParams->bssType) + if (eSIR_INFRA_AP_MODE == pe_session->bssType) pe_session->limSystemRole = eLIM_AP_ROLE; else pe_session->limSystemRole = eLIM_STA_IN_IBSS_ROLE; @@ -2106,7 +2026,7 @@ static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac, /* Start OLBC timer */ if (tx_timer_activate - (&mac->lim.limTimers.gLimUpdateOlbcCacheTimer) != + (&mac->lim.lim_timers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) { pe_err("tx_timer_activate failed"); } @@ -2122,77 +2042,39 @@ static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac, && (isWepEnabled)) mac->mlme_cfg->sap_cfg.assoc_sta_limit = MAX_SUPPORTED_PEERS_WEP; - pe_session->staId = pAddBssParams->staContext.staIdx; mlmStartCnf.resultCode = eSIR_SME_SUCCESS; } else { pe_err("WMA_ADD_BSS_REQ failed with status %d", - pAddBssParams->status); + add_bss_rsp->status); mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; } lim_send_start_bss_confirm(mac, &mlmStartCnf); -end: - if (0 != limMsgQ->bodyptr) { - qdf_mem_free(pAddBssParams); - limMsgQ->bodyptr = NULL; - } } -/** - * lim_process_ibss_mlm_add_bss_rsp() - * - ***FUNCTION: - * This function is called to process a WMA_ADD_BSS_RSP from HAL. - * Upon receipt of this message from HAL, MLME - - * > Validates the result of WMA_ADD_BSS_REQ - * > Init other remaining LIM variables - * > Init the AID pool, for that BSSID - * > Init the Pre-AUTH list, for that BSSID - * > Create LIM timers, specific to that BSSID - * > Init DPH related parameters that are specific to that BSSID - * > TODO - When do we do the actual change channel? - * - ***LOGIC: - * SME sends eWNI_SME_START_BSS_REQ to LIM - * LIM sends LIM_MLM_START_REQ to MLME - * MLME sends WMA_ADD_BSS_REQ to HAL - * HAL responds with WMA_ADD_BSS_RSP to MLME - * MLME responds with LIM_MLM_START_CNF to LIM - * LIM responds with eWNI_SME_START_BSS_RSP to SME - * - ***ASSUMPTIONS: - * struct scheduler_msg.body is allocated by MLME during - * lim_process_mlm_start_req - * struct scheduler_msg.body will now be freed by this routine - * - ***NOTE: - * - * @param mac Pointer to Global MAC structure - * @param struct scheduler_msg The MsgQ header, which contains - * the response buffer +#ifdef QCA_IBSS_SUPPORT +/* + * lim_process_ibss_mlm_add_bss_rsp: API to process add bss response + * in IBSS role + * @session_entry: pe session entry + * @auth_mode: auth mode needs to be updated * - * @return None + * Return: None */ static void lim_process_ibss_mlm_add_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, + struct add_bss_rsp *add_bss_rsp, struct pe_session *pe_session) { tLimMlmStartCnf mlmStartCnf; - tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; - if (!pAddBssParams) { - pe_err("Invalid body pointer in message"); - goto end; + if (!add_bss_rsp) { + pe_err("add_bss_rsp is NULL"); + return; } - if (QDF_STATUS_SUCCESS == pAddBssParams->status) { + if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS"); - if (lim_set_link_state - (mac, eSIR_LINK_IBSS_STATE, pe_session->bssId, - pe_session->self_mac_addr, NULL, - NULL) != QDF_STATUS_SUCCESS) - goto end; /* Set MLME state */ pe_session->limMlmState = eLIM_MLM_BSS_STARTED_STATE; MTRACE(mac_trace @@ -2204,7 +2086,6 @@ lim_process_ibss_mlm_add_bss_rsp(struct mac_context *mac, */ pe_session->limIbssActive = false; limResetHBPktCount(pe_session); - pe_session->bss_idx = (uint8_t)pAddBssParams->bss_idx; pe_session->limSystemRole = eLIM_STA_IN_IBSS_ROLE; pe_session->statypeForBss = STA_ENTRY_SELF; sch_edca_profile_update(mac, pe_session); @@ -2213,17 +2094,17 @@ lim_process_ibss_mlm_add_bss_rsp(struct mac_context *mac, /* Apply previously set configuration at HW */ lim_apply_configuration(mac, pe_session); - pe_session->staId = pAddBssParams->staContext.staIdx; mlmStartCnf.resultCode = eSIR_SME_SUCCESS; /* If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM */ if (true == mac->lim.gLimIbssCoalescingHappened) { - lim_ibss_add_bss_rsp_when_coalescing(mac, limMsgQ->bodyptr, - pe_session); - goto end; + lim_ibss_add_bss_rsp_when_coalescing(mac, + pe_session->curr_op_freq, + pe_session); + return; } } else { pe_err("WMA_ADD_BSS_REQ failed with status %d", - pAddBssParams->status); + add_bss_rsp->status); mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; } /* Send this message to SME, when ADD_BSS is initiated by SME */ @@ -2231,12 +2112,15 @@ lim_process_ibss_mlm_add_bss_rsp(struct mac_context *mac, /* Update PE session Id */ mlmStartCnf.sessionId = pe_session->peSessionId; lim_send_start_bss_confirm(mac, &mlmStartCnf); -end: - if (0 != limMsgQ->bodyptr) { - qdf_mem_free(pAddBssParams); - limMsgQ->bodyptr = NULL; - } } +#else +static inline void +lim_process_ibss_mlm_add_bss_rsp(struct mac_context *mac, + struct add_bss_rsp *add_bss_rsp, + struct pe_session *pe_session) +{ +} +#endif #ifdef WLAN_FEATURE_FILS_SK /* @@ -2261,47 +2145,32 @@ static void lim_update_fils_auth_mode(struct pe_session *session_entry, { } #endif -/** - * csr_neighbor_roam_handoff_req_hdlr - Processes handoff request - * @mac_ctx: Pointer to mac context - * @msg: message sent to HDD - * @session_entry: PE session handle - * - * This function is called to process a WMA_ADD_BSS_RSP from HAL. - * Upon receipt of this message from HAL if the state is pre assoc. - * - * Return: Null - */ -static void -lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, - struct scheduler_msg *msg, struct pe_session *session_entry) +void lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, + struct bss_params *add_bss_params, + struct pe_session *session_entry, + QDF_STATUS status) { - tpAddBssParams pAddBssParams = (tpAddBssParams) msg->bodyptr; tAniAuthType cfgAuthType, authMode; tLimMlmAuthReq *pMlmAuthReq; tpDphHashNode sta = NULL; - if (!pAddBssParams) { + if (!add_bss_params) { pe_err("Invalid body pointer in message"); goto joinFailure; } - if (QDF_STATUS_SUCCESS == pAddBssParams->status) { + if (QDF_IS_STATUS_SUCCESS(status)) { sta = dph_add_hash_entry(mac_ctx, - pAddBssParams->staContext.staMac, + add_bss_params->staContext.staMac, DPH_STA_HASH_INDEX_PEER, &session_entry->dph.dphHashTable); if (!sta) { /* Could not add hash table entry */ pe_err("could not add hash entry at DPH for"); lim_print_mac_addr(mac_ctx, - pAddBssParams->staContext.staMac, LOGE); + add_bss_params->staContext.staMac, LOGE); goto joinFailure; } - session_entry->bss_idx = (uint8_t)pAddBssParams->bss_idx; /* Success, handle below */ - sta->bssId = pAddBssParams->bss_idx; - /* STA Index(genr by HAL) for the BSS entry is stored here */ - sta->staIndex = pAddBssParams->staContext.staIdx; /* Trigger Authentication with AP */ cfgAuthType = mac_ctx->mlme_cfg->wep_params.auth_type; @@ -2328,8 +2197,6 @@ lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, pMlmAuthReq->sessionId = session_entry->peSessionId; session_entry->limPrevSmeState = session_entry->limSmeState; session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE; - /* remember staId in case of assoc timeout/failure handling */ - session_entry->staId = pAddBssParams->staContext.staIdx; MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, session_entry->peSessionId, @@ -2353,48 +2220,17 @@ lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, } -/** - * lim_process_sta_mlm_add_bss_rsp() - Process ADD BSS response - * @mac_ctx: Pointer to Global MAC structure - * @msg: The MsgQ header, which contains the response buffer - * - * This function is called to process a WMA_ADD_BSS_RSP from HAL. - * Upon receipt of this message from HAL, MLME - - * > Validates the result of WMA_ADD_BSS_REQ - * > Now, send an ADD_STA to HAL and ADD the "local" STA itself - * - * MLME had sent WMA_ADD_BSS_REQ to HAL - * HAL responded with WMA_ADD_BSS_RSP to MLME - * MLME now sends WMA_ADD_STA_REQ to HAL - * ASSUMPTIONS: - * struct scheduler_msg.body is allocated by MLME during - * lim_process_mlm_join_req - * struct scheduler_msg.body will now be freed by this routine - * - * Return: None - */ -static void -lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *msg, struct pe_session *session_entry) +static void lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, + struct add_bss_rsp *add_bss_rsp, + struct pe_session *session_entry) { - tpAddBssParams add_bss_params = (tpAddBssParams) msg->bodyptr; tLimMlmAssocCnf mlm_assoc_cnf; uint32_t msg_type = LIM_MLM_ASSOC_CNF; uint32_t sub_type = LIM_ASSOC; tpDphHashNode sta_ds = NULL; - uint16_t sta_idx = STA_INVALID_IDX; uint8_t update_sta = false; mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS; - - if (eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE == - session_entry->limMlmState) { - pe_debug("SessionId: %d lim_process_sta_add_bss_rsp_pre_assoc", - session_entry->peSessionId); - lim_process_sta_add_bss_rsp_pre_assoc(mac_ctx, msg, - session_entry); - goto end; - } if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState || (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == session_entry->limMlmState)) { @@ -2411,22 +2247,19 @@ lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, */ if (sir_compare_mac_addr(session_entry->bssId, session_entry->limReAssocbssId)) { - sta_idx = session_entry->staId; update_sta = true; } } - if (add_bss_params == 0) - goto end; - - if (QDF_STATUS_SUCCESS == add_bss_params->status) { + if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == session_entry->limMlmState) { pe_debug("Mlm=%d %d", session_entry->limMlmState, eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); - lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, msg, - session_entry); - goto end; + lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, + add_bss_rsp, + session_entry); + return; } /* Set MLME state */ @@ -2445,24 +2278,14 @@ lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; } else { - session_entry->bss_idx = - (uint8_t)add_bss_params->bss_idx; /* Success, handle below */ - sta_ds->bssId = add_bss_params->bss_idx; - /* - * STA Index(genr by HAL) for the BSS - * entry is stored here - */ - sta_ds->staIndex = add_bss_params->staContext.staIdx; /* Downgrade the EDCA parameters if needed */ lim_set_active_edca_params(mac_ctx, session_entry->gLimEdcaParams, session_entry); lim_send_edca_params(mac_ctx, session_entry->gLimEdcaParamsActive, - sta_ds->bssId, false); - rrm_cache_mgmt_tx_power(mac_ctx, - add_bss_params->txMgmtPower, session_entry); - if (lim_add_sta_self(mac_ctx, sta_idx, update_sta, + session_entry->vdev_id, false); + if (lim_add_sta_self(mac_ctx, update_sta, session_entry) != QDF_STATUS_SUCCESS) { /* Add STA context at HW */ pe_err("Session:%d could not Add Self" @@ -2489,54 +2312,22 @@ lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) { session_entry->limMlmState = eLIM_MLM_IDLE_STATE; - if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE, - session_entry->bssId, - session_entry->self_mac_addr, - NULL, NULL) != QDF_STATUS_SUCCESS) - pe_err("Failed to set the LinkState"); /* Update PE session Id */ mlm_assoc_cnf.sessionId = session_entry->peSessionId; lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf); } -end: - if (0 != msg->bodyptr) { - qdf_mem_free(add_bss_params); - msg->bodyptr = NULL; - } } -/** - * lim_process_mlm_add_bss_rsp() - Processes ADD BSS Response - * - * @mac_ctx - Pointer to Global MAC structure - * @msg - The MsgQ header, which contains the response buffer - * - * This function is called to process a WMA_ADD_BSS_RSP from HAL. - * Upon receipt of this message from HAL, MLME - - * Determines the "state" in which this message was received - * Forwards it to the appropriate callback - * - *LOGIC: - * WMA_ADD_BSS_RSP can be received by MLME while the LIM is - * in the following two states: - * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE - * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE - * Based on these two states, this API will determine where to - * route the message to - * - * Return None - */ -void lim_process_mlm_add_bss_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *msg) +void lim_handle_add_bss_rsp(struct mac_context *mac_ctx, + struct add_bss_rsp *add_bss_rsp) { tLimMlmStartCnf mlm_start_cnf; struct pe_session *session_entry; - tpAddBssParams add_bss_param = (tpAddBssParams) (msg->bodyptr); enum bss_type bss_type; - if (!add_bss_param) { - pe_err("Encountered NULL Pointer"); + if (!add_bss_rsp) { + pe_err("add_bss_rspis NULL"); return; } @@ -2549,25 +2340,23 @@ void lim_process_mlm_add_bss_rsp(struct mac_context *mac_ctx, */ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); /* Validate SME/LIM/MLME state */ - session_entry = pe_find_session_by_session_id(mac_ctx, - add_bss_param->sessionId); + session_entry = pe_find_session_by_vdev_id(mac_ctx, + add_bss_rsp->vdev_id); if (!session_entry) { - pe_err("SessionId:%d Session Doesn't exist", - add_bss_param->sessionId); - if (add_bss_param) { - qdf_mem_free(add_bss_param); - msg->bodyptr = NULL; - } - return; + pe_err("vdev id:%d Session Doesn't exist", + add_bss_rsp->vdev_id); + goto err; } bss_type = session_entry->bssType; /* update PE session Id */ mlm_start_cnf.sessionId = session_entry->peSessionId; if (eSIR_IBSS_MODE == bss_type) { - lim_process_ibss_mlm_add_bss_rsp(mac_ctx, msg, session_entry); + lim_process_ibss_mlm_add_bss_rsp(mac_ctx, add_bss_rsp, + session_entry); } else if (eSIR_NDI_MODE == session_entry->bssType) { - lim_process_ndi_mlm_add_bss_rsp(mac_ctx, msg, session_entry); + lim_process_ndi_mlm_add_bss_rsp(mac_ctx, add_bss_rsp, + session_entry); } else { if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) { if (eLIM_MLM_WT_ADD_BSS_RSP_STATE != @@ -2578,18 +2367,15 @@ void lim_process_mlm_add_bss_rsp(struct mac_context *mac_ctx, session_entry->limMlmState); mlm_start_cnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; - if (0 != msg->bodyptr) { - qdf_mem_free(add_bss_param); - msg->bodyptr = NULL; - } lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); - } else - lim_process_ap_mlm_add_bss_rsp(mac_ctx, msg); + } + lim_process_ap_mlm_add_bss_rsp(mac_ctx, + add_bss_rsp); } else { /* Called while processing assoc response */ - lim_process_sta_mlm_add_bss_rsp(mac_ctx, msg, - session_entry); + lim_process_sta_mlm_add_bss_rsp(mac_ctx, add_bss_rsp, + session_entry); } } @@ -2602,49 +2388,37 @@ void lim_process_mlm_add_bss_rsp(struct mac_context *mac_ctx, } } #endif +err: + qdf_mem_free(add_bss_rsp); } void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *msg) + uint8_t vdev_id) { struct pe_session *session_entry; - tpHalHiddenSsidVdevRestart hidden_ssid_vdev_restart; struct scheduler_msg message = {0}; QDF_STATUS status; - hidden_ssid_vdev_restart = (tpHalHiddenSsidVdevRestart)(msg->bodyptr); - - if (!hidden_ssid_vdev_restart) { - pe_err("NULL msg pointer"); - return; - } - - session_entry = pe_find_session_by_session_id(mac_ctx, - hidden_ssid_vdev_restart->pe_session_id); + pe_debug("hidden ssid resp for vdev_id:%d ", vdev_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session_entry) { - pe_err("SessionId:%d Session Doesn't exist", - hidden_ssid_vdev_restart->pe_session_id); - goto free_req; + pe_err("vdev_id:%d Session Doesn't exist", + vdev_id); + return; } /* Update beacon */ sch_set_fixed_beacon_fields(mac_ctx, session_entry); lim_send_beacon(mac_ctx, session_entry); message.type = eWNI_SME_HIDDEN_SSID_RESTART_RSP; - message.bodyval = hidden_ssid_vdev_restart->sessionId; + message.bodyval = vdev_id; status = scheduler_post_message(QDF_MODULE_ID_PE, QDF_MODULE_ID_SME, QDF_MODULE_ID_SME, &message); if (status != QDF_STATUS_SUCCESS) pe_err("Failed to post message %u", status); - -free_req: - if (hidden_ssid_vdev_restart) { - qdf_mem_free(hidden_ssid_vdev_restart); - msg->bodyptr = NULL; - } } /** @@ -2683,7 +2457,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, uint8_t resp_reqd = 1; struct sLimMlmSetKeysCnf mlm_set_key_cnf; uint8_t session_id = 0; - uint8_t sme_session_id; + uint8_t vdev_id; struct pe_session *session_entry; uint16_t key_len; uint16_t result_status; @@ -2696,44 +2470,23 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, return; } set_key_params = msg->bodyptr; - sme_session_id = set_key_params->smesessionId; - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - sme_session_id); + vdev_id = set_key_params->vdev_id; + session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session_entry) { - pe_err("session does not exist for given vdev_id %d", sme_session_id); + pe_err("session does not exist for given vdev_id %d", vdev_id); qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, mlm_set_key_cnf.peer_macaddr, 0, eSIR_SME_INVALID_SESSION, NULL, - sme_session_id); + vdev_id); return; } - if (!lim_is_set_key_req_converged() && - (session_entry->limMlmState != eLIM_MLM_WT_SET_STA_KEY_STATE)) { - pe_err("Received in unexpected limMlmState %X vdev %d pe_session_id %d", - session_entry->limMlmState, session_entry->vdev_id, - session_entry->peSessionId); - qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); - qdf_mem_free(msg->bodyptr); - msg->bodyptr = NULL; - lim_send_sme_set_context_rsp(mac_ctx, - mlm_set_key_cnf.peer_macaddr, - 0, eSIR_SME_INVALID_SESSION, NULL, - sme_session_id); - return; - } session_id = session_entry->peSessionId; - pe_debug("PE session ID %d, vdev id %d", session_id, sme_session_id); + pe_debug("PE session ID %d, vdev_id %d", session_id, vdev_id); result_status = set_key_params->status; - if (!lim_is_set_key_req_converged()) { - mlm_set_key_cnf.resultCode = result_status; - /* Restore MLME state */ - session_entry->limMlmState = session_entry->limPrevMlmState; - } - key_len = set_key_params->key[0].keyLength; if (result_status == eSIR_SME_SUCCESS && key_len) @@ -2760,9 +2513,8 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } else { - lim_copy_set_key_req_mac_addr( - &mlm_set_key_cnf.peer_macaddr, - &set_key_params->macaddr); + qdf_copy_macaddr(&mlm_set_key_cnf.peer_macaddr, + &set_key_params->macaddr); } mlm_set_key_cnf.sessionId = session_id; lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, @@ -2790,7 +2542,7 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, struct sLimMlmSetKeysCnf set_key_cnf; uint16_t result_status; uint8_t session_id = 0; - uint8_t sme_session_id; + uint8_t vdev_id; struct pe_session *session_entry; tpLimMlmSetKeysReq set_key_req; uint16_t key_len; @@ -2801,55 +2553,29 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, pe_err("msg bodyptr is null"); return; } - sme_session_id = ((tpSetBssKeyParams) msg->bodyptr)->smesessionId; - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - sme_session_id); + vdev_id = ((tpSetBssKeyParams) msg->bodyptr)->vdev_id; + session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session_entry) { - pe_err("session does not exist for given vdev %d", - sme_session_id); + pe_err("session does not exist for vdev_id %d", vdev_id); qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, 0, eSIR_SME_INVALID_SESSION, NULL, - sme_session_id); - return; - } - if (!lim_is_set_key_req_converged() && - (session_entry->limMlmState != eLIM_MLM_WT_SET_BSS_KEY_STATE) && - (session_entry->limMlmState != - eLIM_MLM_WT_SET_STA_BCASTKEY_STATE)) { - pe_err("Received in unexpected limMlmState %X vdev %d pe_session_id %d", - session_entry->limMlmState, session_entry->vdev_id, - session_entry->peSessionId); - qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); - qdf_mem_free(msg->bodyptr); - msg->bodyptr = NULL; - lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, - 0, eSIR_SME_INVALID_SESSION, NULL, - sme_session_id); + vdev_id); return; } session_id = session_entry->peSessionId; - pe_debug("PE session ID %d, SME session id %d", session_id, - sme_session_id); + pe_debug("PE session ID %d, vdev_id %d", session_id, vdev_id); if (eLIM_MLM_WT_SET_BSS_KEY_STATE == session_entry->limMlmState) { result_status = (uint16_t)(((tpSetBssKeyParams)msg->bodyptr)->status); key_len = ((tpSetBssKeyParams)msg->bodyptr)->key[0].keyLength; - } else if (lim_is_set_key_req_converged()) { + } else { result_status = (uint16_t)(((tpSetBssKeyParams)msg->bodyptr)->status); key_len = ((tpSetBssKeyParams)msg->bodyptr)->key[0].keyLength; - } else { - /* - * BCAST key also uses tpSetStaKeyParams. - * Done this way for readabilty. - */ - result_status = - (uint16_t)(((tpSetStaKeyParams)msg->bodyptr)->status); - key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength; } pe_debug("limMlmState %d status %d key_len %d", @@ -2860,11 +2586,6 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, else set_key_cnf.key_len_nonzero = false; - if (!lim_is_set_key_req_converged()) { - set_key_cnf.resultCode = result_status; - session_entry->limMlmState = session_entry->limPrevMlmState; - } - MTRACE(mac_trace (mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, session_entry->limMlmState)); @@ -2885,9 +2606,8 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } else { - lim_copy_set_key_req_mac_addr( - &set_key_cnf.peer_macaddr, - &((tpSetBssKeyParams)msg->bodyptr)->macaddr); + qdf_copy_macaddr(&set_key_cnf.peer_macaddr, + &((tpSetBssKeyParams)msg->bodyptr)->macaddr); } qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); @@ -2942,7 +2662,7 @@ static void lim_process_switch_channel_re_assoc_req(struct mac_context *mac, MTRACE(mac_trace (mac, TRACE_CODE_TIMER_ACTIVATE, pe_session->peSessionId, eLIM_REASSOC_FAIL_TIMER)); - if (tx_timer_activate(&mac->lim.limTimers.gLimReassocFailureTimer) + if (tx_timer_activate(&mac->lim.lim_timers.gLimReassocFailureTimer) != TX_SUCCESS) { pe_err("could not start Reassociation failure timer"); /* Return Reassoc confirm with */ @@ -3027,10 +2747,12 @@ static void lim_process_switch_channel_join_req( mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) { pe_err("Index %d Sessionid: %d Send deauth on " - "channel %d to BSSID: "QDF_MAC_ADDR_STR, apCount, - session_entry->peSessionId, session_entry->currentOperChannel, - QDF_MAC_ADDR_ARRAY(session_entry->pLimMlmJoinReq->bssDescription. - bssId)); + "channel freq %d to BSSID: " QDF_MAC_ADDR_FMT, + apCount, + session_entry->peSessionId, + session_entry->curr_op_freq, + QDF_MAC_ADDR_REF( + session_entry->pLimMlmJoinReq->bssDescription.bssId)); lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, session_entry->pLimMlmJoinReq->bssDescription.bssId, @@ -3067,11 +2789,11 @@ static void lim_process_switch_channel_join_req( eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); /* assign appropriate sessionId to the timer object */ - mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId = + mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer.sessionId = session_entry->peSessionId; - pe_debug("vdev %d Send Probe req on chan %d %.*s " QDF_MAC_ADDR_STR, session_entry->vdev_id, - session_entry->currentOperChannel, ssId.length, ssId.ssId, - QDF_MAC_ADDR_ARRAY( + pe_debug("vdev %d Send Probe req on freq %d %.*s " QDF_MAC_ADDR_FMT, session_entry->vdev_id, + session_entry->curr_op_freq, ssId.length, ssId.ssId, + QDF_MAC_ADDR_REF( session_entry->pLimMlmJoinReq->bssDescription.bssId)); /* @@ -3081,7 +2803,7 @@ static void lim_process_switch_channel_join_req( */ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER)); - if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimJoinFailureTimer) != + if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimJoinFailureTimer) != TX_SUCCESS) { pe_err("couldn't activate Join failure timer"); session_entry->limMlmState = session_entry->limPrevMlmState; @@ -3094,19 +2816,18 @@ static void lim_process_switch_channel_join_req( /* include additional IE if there is */ lim_send_probe_req_mgmt_frame(mac_ctx, &ssId, session_entry->pLimMlmJoinReq->bssDescription.bssId, - session_entry->currentOperChannel, session_entry->self_mac_addr, + session_entry->curr_op_freq, + session_entry->self_mac_addr, session_entry->dot11mode, &session_entry->lim_join_req->addIEScan.length, session_entry->lim_join_req->addIEScan.addIEdata); - if (session_entry->opmode == QDF_P2P_CLIENT_MODE) { - /* Activate Join Periodic Probe Req timer */ - if (tx_timer_activate - (&mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) - != TX_SUCCESS) { - pe_err("Periodic JoinReq timer activate failed"); - goto error; - } + /* Activate Join Periodic Probe Req timer */ + if (tx_timer_activate + (&mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer) + != TX_SUCCESS) { + pe_err("Periodic JoinReq timer activate failed"); + goto error; } return; @@ -3179,34 +2900,28 @@ static void lim_handle_mon_switch_channel_rsp(struct pe_session *session, * * @return None */ -void lim_process_switch_channel_rsp(struct mac_context *mac, void *body) +void lim_process_switch_channel_rsp(struct mac_context *mac, + struct vdev_start_response *rsp) { - tpSwitchChannelParams pChnlParams = NULL; QDF_STATUS status; uint16_t channelChangeReasonCode; - uint8_t peSessionId; struct pe_session *pe_session; /* we need to process the deferred message since the initiating req. there might be nested request. */ /* in the case of nested request the new request initiated from the response will take care of resetting */ /* the deffered flag. */ SET_LIM_PROCESS_DEFD_MESGS(mac, true); - pChnlParams = (tpSwitchChannelParams) body; - status = pChnlParams->status; - peSessionId = pChnlParams->peSessionId; + status = rsp->status; - pe_session = pe_find_session_by_session_id(mac, peSessionId); + pe_session = pe_find_session_by_vdev_id(mac, rsp->vdev_id); if (!pe_session) { pe_err("session does not exist for given sessionId"); - goto free; + return; } pe_session->ch_switch_in_progress = false; - /* HAL fills in the tx power used for mgmt frames in this field. */ - /* Store this value to use in TPC report IE. */ - rrm_cache_mgmt_tx_power(mac, pChnlParams->txMgmtPower, pe_session); channelChangeReasonCode = pe_session->channelChangeReasonCode; /* initialize it back to invalid id */ - pe_session->chainMask = pChnlParams->chainMask; - pe_session->smpsMode = pChnlParams->smpsMode; + pe_session->chainMask = rsp->chain_mask; + pe_session->smpsMode = rsp->smps_mode; pe_session->channelChangeReasonCode = 0xBAD; switch (channelChangeReasonCode) { case LIM_SWITCH_CHANNEL_REASSOC: @@ -3239,9 +2954,6 @@ void lim_process_switch_channel_rsp(struct mac_context *mac, void *body) pe_debug("Send p2p operating channel change conf action frame once first beacon is received on new channel"); pe_session->send_p2p_conf_frame = true; } - - if (ucfg_pkt_capture_get_pktcap_mode()) - ucfg_pkt_capture_record_channel(pe_session->vdev); break; case LIM_SWITCH_CHANNEL_SAP_DFS: /* Note: This event code specific to SAP mode @@ -3252,14 +2964,12 @@ void lim_process_switch_channel_rsp(struct mac_context *mac, void *body) * require completely different information for P2P unlike * SAP. */ - lim_send_sme_ap_channel_switch_resp(mac, pe_session, - pChnlParams); + lim_send_sme_ap_channel_switch_resp(mac, pe_session, rsp); /* If MCC upgrade/DBS downgrade happended during channel switch, * the policy manager connection table needs to be updated. */ policy_mgr_update_connection_info(mac->psoc, pe_session->smeSessionId); - policy_mgr_set_do_hw_mode_change_flag(mac->psoc, true); break; case LIM_SWITCH_CHANNEL_MONITOR: lim_handle_mon_switch_channel_rsp(pe_session, status); @@ -3269,13 +2979,10 @@ void lim_process_switch_channel_rsp(struct mac_context *mac, void *body) */ policy_mgr_update_connection_info(mac->psoc, pe_session->smeSessionId); - ucfg_pkt_capture_record_channel(pe_session->vdev); break; default: break; } -free: - qdf_mem_free(body); } QDF_STATUS lim_send_beacon_ind(struct mac_context *mac, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_req_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_req_frame.c index 45f1d75c3d9f7f6a3b30c73bac697b54b9a16b6f..57897920cbc8fd1afd357d735dad46860ef1e76f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_req_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_req_frame.c @@ -283,8 +283,8 @@ lim_process_probe_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (sir_convert_probe_req_frame2_struct(mac_ctx, body_ptr, frame_len, &probe_req) == QDF_STATUS_E_FAILURE) { pe_err("Parse error ProbeReq, length: %d, SA is: " - QDF_MAC_ADDR_STR, frame_len, - QDF_MAC_ADDR_ARRAY(mac_hdr->sa)); + QDF_MAC_ADDR_FMT, frame_len, + QDF_MAC_ADDR_REF(mac_hdr->sa)); return; } if (session->opmode == QDF_P2P_GO_MODE) { @@ -446,7 +446,8 @@ lim_indicate_probe_req_to_hdd(struct mac_context *mac, uint8_t *pBd, lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType, (uint8_t *) pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), - pe_session->smeSessionId, WMA_GET_RX_CH(pBd), + pe_session->smeSessionId, + WMA_GET_RX_FREQ(pBd), pe_session, WMA_GET_RX_RSSI_NORMALIZED(pBd), RXMGMT_FLAG_NONE); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c index f7a7958ee3995c035810cd5aa235e86423af307a..17d19332bf13b9d443670d150774edff1632c38d 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c @@ -108,6 +108,7 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info tSirProbeRespBeacon *probe_rsp; uint8_t qos_enabled = false; uint8_t wme_enabled = false; + uint32_t chan_freq = 0; if (!session_entry) { pe_err("session_entry is NULL"); @@ -135,9 +136,9 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info } frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info); - pe_debug("Probe Resp(len %d): " QDF_MAC_ADDR_STR " RSSI %d", + pe_debug("Probe Resp(len %d): " QDF_MAC_ADDR_FMT " RSSI %d", WMA_GET_RX_MPDU_LEN(rx_Packet_info), - QDF_MAC_ADDR_ARRAY(header->bssId), + QDF_MAC_ADDR_REF(header->bssId), (uint)abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(rx_Packet_info))); /* Get pointer to Probe Response frame body */ @@ -198,14 +199,16 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info } if (!LIM_IS_CONNECTION_ACTIVE(session_entry)) { pe_warn("Recved Probe Resp from AP,AP-alive"); - if (probe_rsp->HTInfo.present) + if (probe_rsp->HTInfo.present) { + chan_freq = + wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + probe_rsp->HTInfo.primaryChannel); + lim_received_hb_handler(mac_ctx, chan_freq, + session_entry); + } else lim_received_hb_handler(mac_ctx, - probe_rsp->HTInfo.primaryChannel, - session_entry); - else - lim_received_hb_handler(mac_ctx, - (uint8_t)probe_rsp->channelNumber, - session_entry); + probe_rsp->chan_freq, + session_entry); } if (LIM_IS_STA_ROLE(session_entry) && !wma_is_csa_offload_enabled()) { @@ -270,7 +273,7 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info session_entry); lim_send_edca_params(mac_ctx, session_entry->gLimEdcaParamsActive, - sta_ds->bssId, false); + session_entry->vdev_id, false); } else { pe_err("SelfEntry missing in Hash"); } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 84264ae711b06785485b23d67c621bc8c3df6945..d10581d1779c507bc7a3de391fb2cec980408a25 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -55,6 +55,8 @@ #include "lim_process_fils.h" #include "wlan_utility.h" #include +#include "../../core/src/vdev_mgr_ops.h" +#include "wma.h" /* SME REQ processing function templates */ static bool __lim_process_sme_sys_ready_ind(struct mac_context *, uint32_t *); @@ -63,7 +65,6 @@ static bool __lim_process_sme_start_bss_req(struct mac_context *, static void __lim_process_sme_disassoc_req(struct mac_context *, uint32_t *); static void __lim_process_sme_disassoc_cnf(struct mac_context *, uint32_t *); static void __lim_process_sme_deauth_req(struct mac_context *, uint32_t *); -static void __lim_process_sme_set_context_req(struct mac_context *, uint32_t *); static bool __lim_process_sme_stop_bss_req(struct mac_context *, struct scheduler_msg *pMsg); static void lim_process_sme_channel_change_request(struct mac_context *mac, @@ -545,7 +546,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu uint32_t auto_gen_bssid = false; uint8_t session_id; struct pe_session *session = NULL; - uint8_t sme_session_id = 0xFF; + uint8_t vdev_id = 0xFF; uint32_t chanwidth; struct vdev_type_nss *vdev_type_nss; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; @@ -567,7 +568,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu goto free; } qdf_mem_copy(sme_start_bss_req, msg_buf, size); - sme_session_id = sme_start_bss_req->sessionId; + vdev_id = sme_start_bss_req->vdev_id; if ((mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) || (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) { @@ -577,7 +578,8 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu ret_code = eSIR_SME_INVALID_PARAMETERS; goto free; } - + channel_number = wlan_reg_freq_to_chan(mac_ctx->pdev, + sme_start_bss_req->oper_ch_freq); /* * This is the place where PE is going to create a session. * If session is not existed, then create a new session @@ -594,7 +596,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu sme_start_bss_req->bssid.bytes, &session_id, mac_ctx->lim.maxStation, sme_start_bss_req->bssType, - sme_start_bss_req->sessionId, + sme_start_bss_req->vdev_id, sme_start_bss_req->bssPersona); if (!session) { pe_warn("Session Can not be created"); @@ -605,7 +607,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu /* Update the beacon/probe filter in mac_ctx */ lim_set_bcn_probe_filter(mac_ctx, session, &sme_start_bss_req->ssId, - sme_start_bss_req->channelId); + channel_number); } if (QDF_NDI_MODE != sme_start_bss_req->bssPersona) { @@ -654,16 +656,14 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu session->beaconParams.beaconInterval = sme_start_bss_req->beaconInterval; - /* Store the channel number in session Table */ - session->currentOperChannel = - sme_start_bss_req->channelId; + /* Store the oper freq in session Table */ + session->curr_op_freq = sme_start_bss_req->oper_ch_freq; /* Update the phymode */ session->gLimPhyMode = sme_start_bss_req->nwType; - session->maxTxPower = - lim_get_regulatory_max_transmit_power(mac_ctx, - session->currentOperChannel); + session->maxTxPower = wlan_reg_get_channel_reg_power_for_freq( + mac_ctx->pdev, session->curr_op_freq); /* Store the dot 11 mode in to the session Table */ session->dot11mode = sme_start_bss_req->dot11mode; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -678,6 +678,11 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu if (IS_DOT11_MODE_HE(session->dot11mode)) { lim_update_session_he_capable(mac_ctx, session); lim_copy_bss_he_cap(session, sme_start_bss_req); + } else if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) { + pe_err("Invalid oper_ch_freq %d for dot11mode %d", + session->curr_op_freq, session->dot11mode); + ret_code = eSIR_SME_INVALID_PARAMETERS; + goto free; } else { lim_strip_he_ies_from_add_ies(mac_ctx, session); } @@ -696,7 +701,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu (void *)&sme_start_bss_req->extendedRateSet, sizeof(tSirMacRateSet)); - if (IS_5G_CH(session->currentOperChannel)) + if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq)) vdev_type_nss = &mac_ctx->vdev_type_nss_5g; else vdev_type_nss = &mac_ctx->vdev_type_nss_2g; @@ -725,6 +730,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu break; case eSIR_NDI_MODE: + session->vdev_nss = vdev_type_nss->ndi; session->limSystemRole = eLIM_NDI_ROLE; break; @@ -758,13 +764,12 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu } } - if (!sme_start_bss_req->channelId && + if (!sme_start_bss_req->oper_ch_freq && sme_start_bss_req->bssType != eSIR_NDI_MODE) { pe_err("Received invalid eWNI_SME_START_BSS_REQ"); ret_code = eSIR_SME_INVALID_PARAMETERS; goto free; } - channel_number = sme_start_bss_req->channelId; #ifdef QCA_HT_2040_COEX if (sme_start_bss_req->obssEnabled) session->htSupportedChannelWidthSet = @@ -781,21 +786,13 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu session->vhtCapability || session->htCapability) { chanwidth = sme_start_bss_req->vht_channel_width; session->ch_width = chanwidth; - if (session->htSupportedChannelWidthSet) { - session->ch_center_freq_seg0 = - sme_start_bss_req->center_freq_seg0; - session->ch_center_freq_seg1 = - sme_start_bss_req->center_freq_seg1; - } else { - session->ch_center_freq_seg0 = 0; - session->ch_center_freq_seg1 = 0; - } + session->ch_center_freq_seg0 = + sme_start_bss_req->center_freq_seg0; + session->ch_center_freq_seg1 = + sme_start_bss_req->center_freq_seg1; + lim_update_he_bw_cap_mcs(session, NULL); } - if (session->vhtCapability && - (session->ch_width > CH_WIDTH_80MHZ)) { - session->nss = 1; - } /* Delete pre-auth list if any */ lim_delete_pre_auth_list(mac_ctx); @@ -888,7 +885,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu } } /* store the channel num in mlmstart req structure */ - mlm_start_req->channelNumber = session->currentOperChannel; + mlm_start_req->oper_ch_freq = session->curr_op_freq; mlm_start_req->cbMode = sme_start_bss_req->cbMode; mlm_start_req->beaconPeriod = session->beaconParams.beaconInterval; @@ -899,7 +896,9 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu if (LIM_IS_AP_ROLE(session)) { mlm_start_req->dtimPeriod = session->dtimPeriod; mlm_start_req->wps_state = session->wps_state; - + session->cac_duration_ms = + mlm_start_req->cac_duration_ms; + session->dfs_regdomain = mlm_start_req->dfs_regdomain; } else { val = mac_ctx->mlme_cfg->sap_cfg.dtim_interval; mlm_start_req->dtimPeriod = (uint8_t) val; @@ -930,13 +929,14 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu mlm_start_req->txChannelWidthSet = session->htRecommendedTxWidthSet; - session->limRFBand = lim_get_rf_band(channel_number); + session->limRFBand = lim_get_rf_band( + sme_start_bss_req->oper_ch_freq); /* Initialize 11h Enable Flag */ session->lim11hEnable = 0; if (mlm_start_req->bssType != eSIR_IBSS_MODE && (CHAN_HOP_ALL_BANDS_ENABLE || - BAND_5G == session->limRFBand)) { + REG_BAND_5G == session->limRFBand)) { session->lim11hEnable = mac_ctx->mlme_cfg->gen.enabled_11h; @@ -957,8 +957,8 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu session->limPrevSmeState = session->limSmeState; session->limSmeState = eLIM_SME_WT_START_BSS_STATE; - pe_debug("Chan %d width %d freq0 %d freq1 %d, dot11mode %d nss %d vendor vht %d", - session->currentOperChannel, session->ch_width, + pe_debug("Freq %d width %d freq0 %d freq1 %d, dot11mode %d nss %d vendor vht %d", + session->curr_op_freq, session->ch_width, session->ch_center_freq_seg0, session->ch_center_freq_seg1, session->dot11mode, session->vdev_nss, @@ -995,7 +995,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu session = NULL; } lim_send_sme_start_bss_rsp(mac_ctx, eWNI_SME_START_BSS_RSP, ret_code, - session, sme_session_id); + session, vdev_id); } /** @@ -1070,9 +1070,9 @@ static void lim_update_sae_config(struct pe_session *session, { session->sae_pmk_cached = sme_join_req->sae_pmk_cached; - pe_debug("pmk_cached %d for BSSID=" QDF_MAC_ADDR_STR, + pe_debug("pmk_cached %d for BSSID=" QDF_MAC_ADDR_FMT, session->sae_pmk_cached, - QDF_MAC_ADDR_ARRAY(sme_join_req->bssDescription.bssId)); + QDF_MAC_ADDR_REF(sme_join_req->bssDescription.bssId)); } #else static inline void lim_update_sae_config(struct pe_session *session, @@ -1157,28 +1157,19 @@ static QDF_STATUS lim_send_ft_reassoc_req(struct pe_session *session, } #ifdef WLAN_FEATURE_11W -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * lim_set_rmf_enabled() - set rmf enabled - * @mac: mac context - * @session: pe session - * @csr_join_req: csr join req - * - * Return: void - */ -static void lim_set_rmf_enabled(struct mac_context *mac, - struct pe_session *session, - struct join_req *csr_join_req) +bool +lim_get_vdev_rmf_capable(struct mac_context *mac, struct pe_session *session) { struct wlan_objmgr_vdev *vdev; uint16_t rsn_caps; + bool peer_rmf_capable = false; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, - csr_join_req->sessionId, + session->vdev_id, WLAN_LEGACY_SME_ID); if (!vdev) { pe_err("Invalid vdev"); - return; + return false; } rsn_caps = (uint16_t)wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP); @@ -1187,55 +1178,16 @@ static void lim_set_rmf_enabled(struct mac_context *mac, (1 << WLAN_CRYPTO_CIPHER_AES_GMAC) | (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256) | (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) && - (rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) && - (rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) - session->limRmfEnabled = 1; + (rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) + peer_rmf_capable = true; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - pe_debug("vdev %d limRmfEnabled %d rsn_caps 0x%x", - csr_join_req->sessionId, session->limRmfEnabled, + pe_debug("vdev %d peer_rmf_capable %d rsn_caps 0x%x", + session->vdev_id, peer_rmf_capable, rsn_caps); -} -#else -/** - * lim_set_rmf_enabled() - set rmf enabled - * @mac: mac context - * @session: pe session - * @csr_join_req: csr join req - * - * Return: void - */ -static void lim_set_rmf_enabled(struct mac_context *mac, - struct pe_session *session, - struct join_req *csr_join_req) -{ - if ((eSIR_ED_AES_128_CMAC == csr_join_req->MgmtEncryptionType) || - (eSIR_ED_AES_GMAC_128 == csr_join_req->MgmtEncryptionType) || - (eSIR_ED_AES_GMAC_256 == csr_join_req->MgmtEncryptionType)) - session->limRmfEnabled = 1; - else - session->limRmfEnabled = 0; - - session->mgmt_cipher_type = csr_join_req->MgmtEncryptionType; - pe_debug("mgmt encryption type %d limRmfEnabled %d", - csr_join_req->MgmtEncryptionType, session->limRmfEnabled); -} -#endif -#else -/** - * lim_set_rmf_enabled() - set rmf enabled - * @mac: mac context - * @session: pe session - * @csr_join_req: csr join req - * - * Return: void - */ -static inline void lim_set_rmf_enabled(struct mac_context *mac, - struct pe_session *session, - struct join_req *csr_join_req) -{ + return peer_rmf_capable; } #endif @@ -1258,8 +1210,9 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) tSirResultCodes ret_code = eSIR_SME_SUCCESS; uint32_t val = 0; uint8_t session_id; + uint8_t bss_chan_id; struct pe_session *session = NULL; - uint8_t sme_session_id = 0; + uint8_t vdev_id = 0; int8_t local_power_constraint = 0, reg_max = 0; uint16_t ie_len; const uint8_t *vendor_ie; @@ -1299,8 +1252,8 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) if (!lim_is_sme_join_req_valid(mac_ctx, sme_join_req)) { /* Received invalid eWNI_SME_JOIN_REQ */ /* Log the event */ - pe_warn("SessionId:%d JOIN REQ with invalid data", - sme_join_req->sessionId); + pe_warn("vdev_id:%d JOIN REQ with invalid data", + sme_join_req->vdev_id); ret_code = eSIR_SME_INVALID_PARAMETERS; goto end; } @@ -1317,16 +1270,18 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) /* check for the existence of start BSS session */ session = pe_find_session_by_bssid(mac_ctx, bss_desc->bssId, &session_id); + bss_chan_id = wlan_reg_freq_to_chan(mac_ctx->pdev, + bss_desc->chan_freq); if (session) { pe_err("Session(%d) Already exists for BSSID: " - QDF_MAC_ADDR_STR " in limSmeState = %X", + QDF_MAC_ADDR_FMT " in limSmeState = %X", session_id, - QDF_MAC_ADDR_ARRAY(bss_desc->bssId), + QDF_MAC_ADDR_REF(bss_desc->bssId), session->limSmeState); if (session->limSmeState == eLIM_SME_LINK_EST_STATE && - session->smeSessionId == sme_join_req->sessionId) { + session->smeSessionId == sme_join_req->vdev_id) { /* * Received eWNI_SME_JOIN_REQ for same * BSS as currently associated. @@ -1352,7 +1307,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session = pe_create_session(mac_ctx, bss_desc->bssId, &session_id, mac_ctx->lim.maxStation, eSIR_INFRASTRUCTURE_MODE, - sme_join_req->sessionId, + sme_join_req->vdev_id, sme_join_req->staPersona); if (!session) { pe_err("Session Can not be created"); @@ -1362,7 +1317,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) /* Update the beacon/probe filter in mac_ctx */ lim_set_bcn_probe_filter(mac_ctx, session, &sme_join_req->ssId, - bss_desc->channelId); + bss_chan_id); } session->max_amsdu_num = sme_join_req->max_amsdu_num; session->enable_session_twt_support = @@ -1427,9 +1382,8 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) */ session->supported_nss_1x1 = true; - /* Copy The channel Id to the session Table */ - session->currentOperChannel = bss_desc->channelId; - + /* Copy oper freq to the session Table */ + session->curr_op_freq = bss_desc->chan_freq; session->vhtCapability = IS_DOT11_MODE_VHT(session->dot11mode); if (session->vhtCapability) { @@ -1460,12 +1414,14 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == sme_join_req->cbMode) { session->ch_center_freq_seg0 = - session->currentOperChannel - 2; + wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq) - 2; session->ch_width = CH_WIDTH_40MHZ; } else if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY == sme_join_req->cbMode) { session->ch_center_freq_seg0 = - session->currentOperChannel + 2; + wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq) + 2; session->ch_width = CH_WIDTH_40MHZ; } else { session->ch_center_freq_seg0 = 0; @@ -1479,7 +1435,8 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) /* Record if management frames need to be protected */ - lim_set_rmf_enabled(mac_ctx, session, sme_join_req); + session->limRmfEnabled = + lim_get_vdev_rmf_capable(mac_ctx, session); #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM session->rssi = bss_desc->rssi; @@ -1579,8 +1536,8 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session->limCurrentBssCaps = session->lim_join_req->bssDescription.capabilityInfo; - reg_max = lim_get_regulatory_max_transmit_power(mac_ctx, - session->currentOperChannel); + reg_max = wlan_reg_get_channel_reg_power_for_freq( + mac_ctx->pdev, session->curr_op_freq); local_power_constraint = reg_max; lim_extract_ap_capability(mac_ctx, @@ -1596,9 +1553,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) tx_pwr_attr.ap_tx_power = local_power_constraint; tx_pwr_attr.ini_tx_power = mac_ctx->mlme_cfg->power.max_tx_power; - tx_pwr_attr.frequency = - wlan_reg_get_channel_freq(mac_ctx->pdev, - session->currentOperChannel); + tx_pwr_attr.frequency = session->curr_op_freq; session->maxTxPower = lim_get_max_tx_power(mac_ctx, &tx_pwr_attr); @@ -1622,11 +1577,10 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session->gUapsdPerAcTriggerEnableMask = 0; } - session->limRFBand = - lim_get_rf_band(session->currentOperChannel); + session->limRFBand = lim_get_rf_band(session->curr_op_freq); /* Initialize 11h Enable Flag */ - if (session->limRFBand == BAND_5G) + if (session->limRFBand == REG_BAND_5G) session->lim11hEnable = mac_ctx->mlme_cfg->gen.enabled_11h; else @@ -1651,13 +1605,15 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) /* Enable the spectrum management if this is a DFS channel */ if (session->country_info_present && - lim_isconnected_on_dfs_channel(mac_ctx, - session->currentOperChannel)) + lim_isconnected_on_dfs_channel( + mac_ctx, + wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq))) session->spectrumMgtEnabled = true; session->isOSENConnection = sme_join_req->isOSENConnection; - pe_debug("Chan %d width %d freq0 %d freq1 %d, Smps %d: mode %d action %d, nss 1x1 %d vdev_nss %d nss %d cbMode %d dot11mode %d subfer %d subfee %d csn %d is_cisco %d", - session->currentOperChannel, session->ch_width, + pe_debug("Freq %d width %d freq0 %d freq1 %d, Smps %d: mode %d action %d, nss 1x1 %d vdev_nss %d nss %d cbMode %d dot11mode %d subfer %d subfee %d csn %d is_cisco %d", + session->curr_op_freq, session->ch_width, session->ch_center_freq_seg0, session->ch_center_freq_seg1, session->enableHtSmps, session->htSmpsvalue, @@ -1689,7 +1645,7 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) } end: - sme_session_id = in_req->sessionId; + vdev_id = in_req->vdev_id; if (sme_join_req) { qdf_mem_free(sme_join_req); @@ -1703,10 +1659,10 @@ __lim_process_sme_join_req(struct mac_context *mac_ctx, void *msg_buf) session = NULL; } } - pe_debug("Send failure status on sessionid: %d with ret_code: %d", - sme_session_id, ret_code); + pe_debug("Send failure status on vdev_id: %d with ret_code: %d", + vdev_id, ret_code); lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, ret_code, - eSIR_MAC_UNSPEC_FAILURE_STATUS, session, sme_session_id); + eSIR_MAC_UNSPEC_FAILURE_STATUS, session, vdev_id); } uint8_t lim_get_max_tx_power(struct mac_context *mac, @@ -1757,12 +1713,12 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, tSirResultCodes ret_code = eSIR_SME_SUCCESS; struct pe_session *session_entry = NULL; uint8_t session_id; - uint8_t sme_session_id; + uint8_t vdev_id; int8_t local_pwr_constraint = 0, reg_max = 0; uint32_t tele_bcn_en = 0; QDF_STATUS status; - sme_session_id = in_req->sessionId; + vdev_id = in_req->vdev_id; reassoc_req = qdf_mem_malloc(in_req->length); if (!reassoc_req) { @@ -1790,8 +1746,7 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, LOGE); ret_code = eSIR_SME_INVALID_PARAMETERS; session_entry = - pe_find_session_by_sme_session_id(mac_ctx, - sme_session_id); + pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (session_entry) lim_handle_sme_join_result(mac_ctx, eSIR_SME_INVALID_PARAMETERS, @@ -1871,7 +1826,7 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, goto end; } - session_entry->smeSessionId = sme_session_id; + session_entry->vdev_id = vdev_id; mlm_reassoc_req = qdf_mem_malloc(sizeof(*mlm_reassoc_req)); if (!mlm_reassoc_req) { @@ -1905,9 +1860,8 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, session_entry->pLimReAssocReq->bssDescription.bssId, sizeof(tSirMacAddr)); - session_entry->limReassocChannelId = - session_entry->pLimReAssocReq->bssDescription.channelId; - + session_entry->lim_reassoc_chan_freq = + session_entry->pLimReAssocReq->bssDescription.chan_freq; session_entry->reAssocHtSupportedChannelWidthSet = (session_entry->pLimReAssocReq->cbMode) ? 1 : 0; session_entry->reAssocHtRecommendedTxWidthSet = @@ -1917,8 +1871,8 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, session_entry->limReassocBssCaps = session_entry->pLimReAssocReq->bssDescription.capabilityInfo; - reg_max = lim_get_regulatory_max_transmit_power(mac_ctx, - session_entry->currentOperChannel); + reg_max = wlan_reg_get_channel_reg_power_for_freq( + mac_ctx->pdev, session_entry->curr_op_freq); local_pwr_constraint = reg_max; lim_extract_ap_capability(mac_ctx, @@ -1984,8 +1938,9 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, /* Enable the spectrum management if this is a DFS channel */ if (session_entry->country_info_present && - lim_isconnected_on_dfs_channel(mac_ctx, - session_entry->currentOperChannel)) + lim_isconnected_on_dfs_channel( + mac_ctx, wlan_reg_freq_to_chan( + mac_ctx->pdev, session_entry->curr_op_freq))) session_entry->spectrumMgtEnabled = true; session_entry->limPrevSmeState = session_entry->limSmeState; @@ -2016,7 +1971,7 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, * extract session id from there, otherwise we'll use * the value already extracted from the message */ - sme_session_id = session_entry->smeSessionId; + vdev_id = session_entry->vdev_id; /* * Send Reassoc failure response to host @@ -2024,7 +1979,7 @@ static void __lim_process_sme_reassoc_req(struct mac_context *mac_ctx, */ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP, ret_code, eSIR_MAC_UNSPEC_FAILURE_STATUS, - session_entry, sme_session_id); + session_entry, vdev_id); } bool send_disassoc_frame = 1; @@ -2084,19 +2039,19 @@ static void __lim_process_sme_disassoc_req(struct mac_context *mac, &sessionId); if (!pe_session) { pe_err("session does not exist for given bssId " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(smeDisassocReq.bssid.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(smeDisassocReq.bssid.bytes)); retCode = eSIR_SME_INVALID_PARAMETERS; disassocTrigger = eLIM_HOST_DISASSOC; goto sendDisassoc; } pe_debug("vdev %d (session %d) Systemrole %d Reason: %u SmeState: %d limMlmState %d ho fail %d send OTA %d from: " - QDF_MAC_ADDR_STR, pe_session->vdev_id, pe_session->peSessionId, + QDF_MAC_ADDR_FMT, pe_session->vdev_id, pe_session->peSessionId, GET_LIM_SYSTEM_ROLE(pe_session), smeDisassocReq.reasonCode, pe_session->limSmeState, pe_session->limMlmState, smeDisassocReq.process_ho_fail, smeDisassocReq.doNotSendOverTheAir, - QDF_MAC_ADDR_ARRAY(smeDisassocReq.peer_macaddr.bytes)); + QDF_MAC_ADDR_REF(smeDisassocReq.peer_macaddr.bytes)); #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ lim_diag_event_report(mac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, pe_session, @@ -2263,7 +2218,7 @@ void __lim_process_sme_disassoc_cnf(struct mac_context *mac, uint32_t *msg_buf) if (!pe_session) { pe_err("session does not exist for given bssId"); status = lim_prepare_disconnect_done_ind(mac, &msg, - smeDisassocCnf.sme_session_id, + smeDisassocCnf.vdev_id, eSIR_SME_INVALID_SESSION, NULL); if (QDF_IS_STATUS_SUCCESS(status)) @@ -2345,8 +2300,8 @@ void __lim_process_sme_disassoc_cnf(struct mac_context *mac, uint32_t *msg_buf) &pe_session->dph.dphHashTable); if (!sta) { pe_err("DISASSOC_CNF for a STA with no context, addr= " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(smeDisassocCnf.peer_macaddr.bytes)); status = lim_prepare_disconnect_done_ind(mac, &msg, pe_session->smeSessionId, eSIR_SME_INVALID_PARAMETERS, @@ -2362,8 +2317,8 @@ void __lim_process_sme_disassoc_cnf(struct mac_context *mac, uint32_t *msg_buf) eLIM_MLM_WT_DEL_STA_RSP_STATE) || (sta->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) { - pe_err("No need of cleanup for addr:" QDF_MAC_ADDR_STR "as MLM state is %d", - QDF_MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes), + pe_err("No need of cleanup for addr:" QDF_MAC_ADDR_FMT "as MLM state is %d", + QDF_MAC_ADDR_REF(smeDisassocCnf.peer_macaddr.bytes), sta->mlmStaContext.mlmState); status = lim_prepare_disconnect_done_ind(mac, &msg, pe_session->smeSessionId, @@ -2407,10 +2362,10 @@ static void __lim_process_sme_deauth_req(struct mac_context *mac_ctx, tSirResultCodes ret_code = eSIR_SME_SUCCESS; struct pe_session *session_entry; uint8_t session_id; /* PE sessionId */ - uint8_t sme_session_id; + uint8_t vdev_id; qdf_mem_copy(&sme_deauth_req, msg_buf, sizeof(sme_deauth_req)); - sme_session_id = sme_deauth_req.sessionId; + vdev_id = sme_deauth_req.vdev_id; /* * We need to get a session first but we don't even know @@ -2436,16 +2391,16 @@ static void __lim_process_sme_deauth_req(struct mac_context *mac_ctx, goto send_deauth; } pe_debug("vdev %d (session %d) Systemrole %d reasoncode %u limSmestate %d limMlmState %d from " - QDF_MAC_ADDR_STR, sme_session_id, session_entry->peSessionId, + QDF_MAC_ADDR_FMT, vdev_id, session_entry->peSessionId, GET_LIM_SYSTEM_ROLE(session_entry), sme_deauth_req.reasonCode, session_entry->limSmeState, session_entry->limMlmState, - QDF_MAC_ADDR_ARRAY(sme_deauth_req.peer_macaddr.bytes)); + QDF_MAC_ADDR_REF(sme_deauth_req.peer_macaddr.bytes)); #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_DEAUTH_REQ_EVENT, session_entry, 0, sme_deauth_req.reasonCode); #endif /* FEATURE_WLAN_DIAG_SUPPORT */ - session_entry->smeSessionId = sme_session_id; + session_entry->vdev_id = vdev_id; switch (GET_LIM_SYSTEM_ROLE(session_entry)) { case eLIM_STA_ROLE: @@ -2578,150 +2533,7 @@ static void __lim_process_sme_deauth_req(struct mac_context *mac_ctx, send_deauth: lim_send_sme_deauth_ntf(mac_ctx, sme_deauth_req.peer_macaddr.bytes, - ret_code, deauth_trigger, 1, - sme_session_id); -} - -/** - * __lim_process_sme_set_context_req() - * - * @mac_ctx: Pointer to Global MAC structure - * @msg_buf: pointer to the SME message buffer - * - * This function is called to process SME_SETCONTEXT_REQ message - * from HDD or upper layer application. - * - * Return: None - */ - -static void -__lim_process_sme_set_context_req(struct mac_context *mac_ctx, - uint32_t *msg_buf) -{ - struct set_context_req *set_context_req; - tLimMlmSetKeysReq *mlm_set_key_req; - struct pe_session *session_entry; - uint8_t session_id; /* PE sessionID */ - uint8_t sme_session_id; - - if (!msg_buf) { - pe_err("Buffer is Pointing to NULL"); - return; - } - - set_context_req = qdf_mem_malloc(sizeof(*set_context_req)); - if (!set_context_req) - return; - qdf_mem_copy(set_context_req, msg_buf, - sizeof(*set_context_req)); - - qdf_mem_zero(msg_buf, sizeof(*set_context_req)); - sme_session_id = set_context_req->sessionId; - - if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) { - pe_warn("received invalid SME_SETCONTEXT_REQ message"); - goto end; - } - - if (set_context_req->keyMaterial.numKeys > - SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) { - pe_err("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS", - set_context_req->keyMaterial.numKeys); - lim_send_sme_set_context_rsp(mac_ctx, - set_context_req->peer_macaddr, 1, - eSIR_SME_INVALID_PARAMETERS, NULL, - sme_session_id); - goto end; - } - - session_entry = pe_find_session_by_bssid(mac_ctx, - set_context_req->bssid.bytes, &session_id); - if (!session_entry) { - pe_err("Session does not exist for given BSSID"); - lim_send_sme_set_context_rsp(mac_ctx, - set_context_req->peer_macaddr, 1, - eSIR_SME_INVALID_PARAMETERS, NULL, - sme_session_id); - goto end; - } -#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ - lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, - session_entry, 0, 0); -#endif /* FEATURE_WLAN_DIAG_SUPPORT */ - - if ((LIM_IS_STA_ROLE(session_entry) && - (session_entry->limSmeState == eLIM_SME_LINK_EST_STATE)) || - ((LIM_IS_IBSS_ROLE(session_entry) || - LIM_IS_AP_ROLE(session_entry)) && - (session_entry->limSmeState == eLIM_SME_NORMAL_STATE))) { - /* Trigger MLM_SETKEYS_REQ */ - mlm_set_key_req = qdf_mem_malloc(sizeof(tLimMlmSetKeysReq)); - if (!mlm_set_key_req) - goto end; - mlm_set_key_req->edType = set_context_req->keyMaterial.edType; - mlm_set_key_req->numKeys = - set_context_req->keyMaterial.numKeys; - if (mlm_set_key_req->numKeys > - SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) { - pe_err("no.of keys exceeded max num of default keys limit"); - qdf_mem_free(mlm_set_key_req); - goto end; - } - qdf_copy_macaddr(&mlm_set_key_req->peer_macaddr, - &set_context_req->peer_macaddr); - - qdf_mem_copy((uint8_t *) &mlm_set_key_req->key, - (uint8_t *) &set_context_req->keyMaterial.key, - sizeof(tSirKeys) * - (mlm_set_key_req->numKeys ? mlm_set_key_req-> - numKeys : 1)); - - mlm_set_key_req->sessionId = session_id; - mlm_set_key_req->smesessionId = sme_session_id; - pe_debug("received SETCONTEXT_REQ message sessionId=%d", - mlm_set_key_req->sessionId); - - if (((set_context_req->keyMaterial.edType == eSIR_ED_WEP40) || - (set_context_req->keyMaterial.edType == eSIR_ED_WEP104)) && - LIM_IS_AP_ROLE(session_entry)) { - if (set_context_req->keyMaterial.key[0].keyLength) { - uint8_t key_id; - - key_id = - set_context_req->keyMaterial.key[0].keyId; - qdf_mem_copy((uint8_t *) - &session_entry->WEPKeyMaterial[key_id], - (uint8_t *) &set_context_req->keyMaterial, - sizeof(tSirKeyMaterial)); - } else { - uint32_t i; - - for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; - i++) { - qdf_mem_copy((uint8_t *) - &mlm_set_key_req->key[i], - (uint8_t *)session_entry->WEPKeyMaterial[i].key, - sizeof(tSirKeys)); - } - } - } - lim_post_mlm_message(mac_ctx, LIM_MLM_SETKEYS_REQ, - (uint32_t *) mlm_set_key_req); - } else { - pe_err("rcvd unexpected SME_SETCONTEXT_REQ for role %d, state=%X", - GET_LIM_SYSTEM_ROLE(session_entry), - session_entry->limSmeState); - lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState); - - lim_send_sme_set_context_rsp(mac_ctx, - set_context_req->peer_macaddr, 1, - eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, - session_entry, sme_session_id); - } -end: - qdf_mem_zero(set_context_req, sizeof(*set_context_req)); - qdf_mem_free(set_context_req); - return; + ret_code, deauth_trigger, 1, vdev_id); } /** @@ -2800,6 +2612,8 @@ void lim_delete_all_peers(struct pe_session *session) } } lim_disconnect_complete(session, false); + if (mac_ctx->del_peers_ind_cb) + mac_ctx->del_peers_ind_cb(mac_ctx->psoc, session->vdev_id); } QDF_STATUS lim_sta_send_del_bss(struct pe_session *session) @@ -2817,7 +2631,7 @@ QDF_STATUS lim_sta_send_del_bss(struct pe_session *session) status = lim_del_bss(mac_ctx, sta_ds, 0, session); if (QDF_IS_STATUS_ERROR(status)) - pe_err("delBss failed for bss %d", session->bss_idx); + pe_err("delBss failed for bss %d", session->vdev_id); end: return status; @@ -2828,10 +2642,10 @@ QDF_STATUS lim_send_vdev_stop(struct pe_session *session) struct mac_context *mac_ctx = session->mac_ctx; QDF_STATUS status; - status = lim_del_bss(mac_ctx, NULL, session->bss_idx, session); + status = lim_del_bss(mac_ctx, NULL, session->vdev_id, session); if (QDF_IS_STATUS_ERROR(status)) { - pe_err("delBss failed for bss %d", session->bss_idx); + pe_err("delBss failed for bss %d", session->vdev_id); lim_send_stop_bss_failure_resp(mac_ctx, session); } @@ -2980,10 +2794,8 @@ static bool __lim_process_sme_stop_bss_req(struct mac_context *mac, } /*** end __lim_process_sme_stop_bss_req() ***/ void lim_process_sme_del_bss_rsp(struct mac_context *mac, - uint32_t body, struct pe_session *pe_session) + struct pe_session *pe_session) { - - (void)body; SET_LIM_PROCESS_DEFD_MESGS(mac, true); lim_ibss_delete(mac, pe_session); dph_hash_table_init(mac, &pe_session->dph.dphHashTable); @@ -3268,13 +3080,13 @@ __lim_process_sme_addts_req(struct mac_context *mac, uint32_t *msg_buf) timeout = mac->mlme_cfg->timeouts.addts_rsp_timeout; timeout = SYS_MS_TO_TICKS(timeout); - if (tx_timer_change(&mac->lim.limTimers.gLimAddtsRspTimer, timeout, 0) + if (tx_timer_change(&mac->lim.lim_timers.gLimAddtsRspTimer, timeout, 0) != TX_SUCCESS) { pe_err("AddtsRsp timer change failed!"); goto send_failure_addts_rsp; } mac->lim.gLimAddtsRspTimerCount++; - if (tx_timer_change_context(&mac->lim.limTimers.gLimAddtsRspTimer, + if (tx_timer_change_context(&mac->lim.lim_timers.gLimAddtsRspTimer, mac->lim.gLimAddtsRspTimerCount) != TX_SUCCESS) { pe_err("AddtsRsp timer change failed!"); @@ -3285,8 +3097,8 @@ __lim_process_sme_addts_req(struct mac_context *mac, uint32_t *msg_buf) eLIM_ADDTS_RSP_TIMER)); /* add the sessionId to the timer object */ - mac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId; - if (tx_timer_activate(&mac->lim.limTimers.gLimAddtsRspTimer) != + mac->lim.lim_timers.gLimAddtsRspTimer.sessionId = sessionId; + if (tx_timer_activate(&mac->lim.lim_timers.gLimAddtsRspTimer) != TX_SUCCESS) { pe_err("AddtsRsp timer activation failed!"); goto send_failure_addts_rsp; @@ -3337,8 +3149,8 @@ __lim_process_sme_delts_req(struct mac_context *mac, uint32_t *msg_buf) } pe_debug("Sent DELTS request to station with assocId = %d MacAddr = " - QDF_MAC_ADDR_STR, - pDeltsReq->aid, QDF_MAC_ADDR_ARRAY(peerMacAddr)); + QDF_MAC_ADDR_FMT, + pDeltsReq->aid, QDF_MAC_ADDR_REF(peerMacAddr)); lim_send_delts_req_action_frame(mac, peerMacAddr, pDeltsReq->req.wmeTspecPresent, @@ -3387,7 +3199,7 @@ __lim_process_sme_delts_req(struct mac_context *mac, uint32_t *msg_buf) &pe_session->dph.dphHashTable); if (sta) { lim_send_edca_params(mac, pe_session->gLimEdcaParamsActive, - sta->bssId, false); + pe_session->vdev_id, false); status = QDF_STATUS_SUCCESS; } else { pe_err("Self entry missing in Hash Table"); @@ -3409,7 +3221,7 @@ void lim_process_sme_addts_rsp_timeout(struct mac_context *mac, uint32_t param) struct pe_session *pe_session; pe_session = pe_find_session_by_session_id(mac, - mac->lim.limTimers.gLimAddtsRspTimer. + mac->lim.lim_timers.gLimAddtsRspTimer. sessionId); if (!pe_session) { pe_err("Session Does not exist for given sessionID"); @@ -3442,44 +3254,6 @@ void lim_process_sme_addts_rsp_timeout(struct mac_context *mac, uint32_t param) pe_session->smeSessionId); } -#ifndef QCA_SUPPORT_CP_STATS -/** - * __lim_process_sme_get_statistics_request() - Post WMA_GET_STATISTICS_REQ to - * wma - * @mac Pointer to Global MAC structure - * @msg_buf A pointer to the SME message buffer - * - * @Return None - */ -static void __lim_process_sme_get_statistics_request(struct mac_context *mac, - uint32_t *msg_buf) -{ - tpAniGetPEStatsReq pPEStatsReq; - struct scheduler_msg msgQ = {0}; - - pPEStatsReq = (tpAniGetPEStatsReq)msg_buf; - - msgQ.type = WMA_GET_STATISTICS_REQ; - - msgQ.reserved = 0; - msgQ.bodyptr = msg_buf; - msgQ.bodyval = 0; - MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type)); - - if (QDF_STATUS_SUCCESS != (wma_post_ctrl_msg(mac, &msgQ))) { - qdf_mem_free(msg_buf); - msg_buf = NULL; - pe_err("Unable to forward request"); - return; - } - - return; -} -#else -static void __lim_process_sme_get_statistics_request( - struct mac_context *mac_ctx, uint32_t *msg_buf) {} -#endif - #ifdef FEATURE_WLAN_ESE /** * __lim_process_sme_get_tsm_stats_request() - get tsm stats request @@ -3523,14 +3297,14 @@ static void lim_process_sme_set_addba_accept(struct mac_context *mac_ctx, } static void lim_process_sme_update_edca_params(struct mac_context *mac_ctx, - uint32_t sme_session_id) + uint32_t vdev_id) { struct pe_session *pe_session; tpDphHashNode sta_ds_ptr; - pe_session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id); + pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!pe_session) { - pe_err("Session does not exist: sme_id %d", sme_session_id); + pe_err("Session does not exist: vdev_id %d", vdev_id); return; } pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BE].no_ack = @@ -3546,27 +3320,86 @@ static void lim_process_sme_update_edca_params(struct mac_context *mac_ctx, if (sta_ds_ptr) lim_send_edca_params(mac_ctx, pe_session->gLimEdcaParamsActive, - sta_ds_ptr->bssId, false); + pe_session->vdev_id, false); else pe_err("Self entry missing in Hash Table"); } +/** + * lim_process_sme_update_session_edca_txq_params() + * Update the edca tx queue parameters for the vdev + * + * @mac_ctx: Pointer to Global MAC structure + * @msg_buf: Pointer to SME message buffer + * + * Return: None + */ +static void +lim_process_sme_update_session_edca_txq_params(struct mac_context *mac_ctx, + uint32_t *msg_buf) +{ + struct sir_update_session_txq_edca_param *msg; + struct pe_session *pe_session; + uint8_t ac; + + if (!msg_buf) { + pe_err("Buffer is Pointing to NULL"); + return; + } + + msg = (struct sir_update_session_txq_edca_param *)msg_buf; + + pe_session = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); + if (!pe_session) { + pe_warn("Session does not exist for given vdev_id %d", + msg->vdev_id); + return; + } + + ac = msg->txq_edca_params.aci.aci; + pe_debug("received SME Session tx queue update for vdev %d queue %d", + msg->vdev_id, ac); + + if ((!LIM_IS_AP_ROLE(pe_session)) || + (pe_session->limSmeState != eLIM_SME_NORMAL_STATE)) { + pe_err("Rcvd edca update req in state %X, in role %X", + pe_session->limSmeState, + GET_LIM_SYSTEM_ROLE(pe_session)); + return; + } + + pe_session->gLimEdcaParams[ac].cw.min = + msg->txq_edca_params.cw.min; + pe_session->gLimEdcaParams[ac].cw.max = + msg->txq_edca_params.cw.max; + pe_session->gLimEdcaParams[ac].aci.aci = + msg->txq_edca_params.aci.aci; + pe_session->gLimEdcaParams[ac].aci.aifsn = + msg->txq_edca_params.aci.aifsn; + pe_session->gLimEdcaParams[ac].txoplimit = + msg->txq_edca_params.txoplimit; + + lim_send_edca_params(mac_ctx, + pe_session->gLimEdcaParams, + pe_session->vdev_id, false); +} + static void lim_process_sme_update_mu_edca_params(struct mac_context *mac_ctx, - uint32_t sme_session_id) + uint32_t vdev_id) { struct pe_session *pe_session; tpDphHashNode sta_ds_ptr; - pe_session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id); + pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!pe_session) { - pe_err("Session does not exist: sme_id %d", sme_session_id); + pe_err("Session does not exist: vdev_id %d", vdev_id); return; } sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, &pe_session->dph.dphHashTable); if (sta_ds_ptr) lim_send_edca_params(mac_ctx, mac_ctx->usr_mu_edca_params, - sta_ds_ptr->bssId, true); + pe_session->vdev_id, true); else pe_err("Self entry missing in Hash Table"); } @@ -3581,7 +3414,7 @@ lim_process_sme_cfg_action_frm_in_tb_ppdu(struct mac_context *mac_ctx, return; } - lim_send_action_frm_tb_ppdu_cfg(mac_ctx, msg->session_id, msg->cfg); + lim_send_action_frm_tb_ppdu_cfg(mac_ctx, msg->vdev_id, msg->cfg); } static void lim_process_sme_update_config(struct mac_context *mac_ctx, @@ -3595,8 +3428,7 @@ static void lim_process_sme_update_config(struct mac_context *mac_ctx, return; } - pe_session = pe_find_session_by_sme_session_id(mac_ctx, - msg->sme_session_id); + pe_session = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); if (!pe_session) { pe_warn("Session does not exist for given BSSID"); return; @@ -3630,33 +3462,22 @@ void lim_send_vdev_restart(struct mac_context *mac, struct pe_session *pe_session, uint8_t sessionId) { - tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL; - struct scheduler_msg msgQ = {0}; - QDF_STATUS retCode = QDF_STATUS_SUCCESS; + struct vdev_mlme_obj *mlme_obj; if (!pe_session) { pe_err("Invalid parameters"); return; } - pHalHiddenSsidVdevRestart = - qdf_mem_malloc(sizeof(tHalHiddenSsidVdevRestart)); - if (!pHalHiddenSsidVdevRestart) + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); return; + } - pHalHiddenSsidVdevRestart->ssidHidden = pe_session->ssidHidden; - pHalHiddenSsidVdevRestart->sessionId = sessionId; - pHalHiddenSsidVdevRestart->pe_session_id = pe_session->peSessionId; + mlme_obj->mgmt.ap.hidden_ssid = pe_session->ssidHidden ? true : false; - msgQ.type = WMA_HIDDEN_SSID_VDEV_RESTART; - msgQ.bodyptr = pHalHiddenSsidVdevRestart; - msgQ.bodyval = 0; - - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { - pe_err("wma_post_ctrl_msg() failed"); - qdf_mem_free(pHalHiddenSsidVdevRestart); - } + vdev_mgr_start_send(mlme_obj, true); } /** @@ -3677,7 +3498,7 @@ static void __lim_process_roam_scan_offload_req(struct mac_context *mac_ctx, uint8_t *local_ie_buf; req_buffer = (struct roam_offload_scan_req *)msg_buf; - pe_session = pe_find_session_by_sme_session_id(mac_ctx, + pe_session = pe_find_session_by_vdev_id(mac_ctx, req_buffer->sessionId); local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN); @@ -3848,10 +3669,10 @@ static void __lim_process_sme_session_update(struct mac_context *mac_ctx, msg = (struct sir_update_session_param *) msg_buf; - session = pe_find_session_by_sme_session_id(mac_ctx, msg->session_id); + session = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); if (!session) { - pe_warn("Session does not exist for given sessionId %d", - msg->session_id); + pe_warn("Session does not exist for given vdev_id %d", + msg->vdev_id); return; } @@ -3919,7 +3740,7 @@ static void __lim_process_sme_change_bi(struct mac_context *mac, /* Update beacon */ sch_set_fixed_beacon_fields(mac, pe_session); - beaconParams.bss_idx = pe_session->bss_idx; + beaconParams.bss_idx = pe_session->vdev_id; /* Set change in beacon Interval */ beaconParams.beaconInterval = pChangeBIParams->beaconInterval; @@ -4010,7 +3831,6 @@ static void __lim_process_sme_set_ht2040_mode(struct mac_context *mac, (pe_session->htSecondaryChannelOffset == PHY_SINGLE_CHANNEL_CENTERED) ? eHT_CHANNEL_WIDTH_20MHZ : eHT_CHANNEL_WIDTH_40MHZ; - pHtOpMode->staId = staId; qdf_mem_copy(pHtOpMode->peer_mac, &sta->staAddr, sizeof(tSirMacAddr)); pHtOpMode->smesessionId = sessionId; @@ -4027,11 +3847,11 @@ static void __lim_process_sme_set_ht2040_mode(struct mac_context *mac, qdf_mem_free(pHtOpMode); return; } - pe_debug("Notified FW about OP mode: %d for staId=%d", - pHtOpMode->opMode, staId); + pe_debug("Notified FW about OP mode: %d", + pHtOpMode->opMode); } else - pe_debug("station %d does not support HT40", staId); + pe_debug("station does not support HT40"); } return; @@ -4292,18 +4112,16 @@ static void __lim_process_send_disassoc_frame(struct mac_context *mac_ctx, return; } - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - req->session_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, req->vdev_id); if (!session_entry) { pe_err("session does not exist for given bssId " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(req->peer_mac)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(req->peer_mac)); return; } - pe_debug("msg_type->%d len->%d sess_id->%d mac->" - QDF_MAC_ADDR_STR " reason->%d wait_for_ack->%d", - req->msg_type, req->length, req->session_id, - QDF_MAC_ADDR_ARRAY(req->peer_mac), req->reason, req->wait_for_ack); + pe_debug("msg_type %d len %d vdev_id %d mac: " QDF_MAC_ADDR_FMT " reason %d wait_for_ack %d", + req->msg_type, req->length, req->vdev_id, + QDF_MAC_ADDR_REF(req->peer_mac), req->reason, req->wait_for_ack); lim_send_disassoc_mgmt_frame(mac_ctx, req->reason, req->peer_mac, session_entry, req->wait_for_ack); @@ -4465,7 +4283,7 @@ static void lim_set_pdev_vht_ie(struct mac_context *mac_ctx, uint8_t pdev_id, * Return: None */ static void lim_process_set_vdev_ies_per_band(struct mac_context *mac_ctx, - uint32_t *msg_buf) + uint32_t *msg_buf) { struct sir_set_vdev_ies_per_band *p_msg = (struct sir_set_vdev_ies_per_band *)msg_buf; @@ -4478,8 +4296,9 @@ static void lim_process_set_vdev_ies_per_band(struct mac_context *mac_ctx, pe_debug("rcvd set vdev ie per band req vdev_id = %d", p_msg->vdev_id); /* intentionally using NULL here so that self capabilty are sent */ - if (lim_send_ies_per_band(mac_ctx, NULL, p_msg->vdev_id) != - QDF_STATUS_SUCCESS) + if (lim_send_ies_per_band(mac_ctx, NULL, p_msg->vdev_id, + p_msg->dot11_mode, p_msg->device_mode) != + QDF_STATUS_SUCCESS) pe_err("Unable to send HT/VHT Cap to FW"); } @@ -4539,12 +4358,12 @@ static void lim_process_sme_update_access_policy_vendor_ie( return; } update_vendor_ie = (struct sme_update_access_policy_vendor_ie *) msg; - pe_session_entry = pe_find_session_by_sme_session_id(mac_ctx, - update_vendor_ie->sme_session_id); + pe_session_entry = pe_find_session_by_vdev_id(mac_ctx, + update_vendor_ie->vdev_id); if (!pe_session_entry) { - pe_err("Session does not exist for given sme session id(%hu)", - update_vendor_ie->sme_session_id); + pe_err("Session does not exist for given vdev_id %d", + update_vendor_ie->vdev_id); return; } if (pe_session_entry->access_policy_vendor_ie) @@ -4624,11 +4443,11 @@ static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx, sme_disassoc_cnf.bssid.bytes, &session_id); if (!session) { - pe_err("session not found for bssid:%pM", - sme_disassoc_cnf.bssid.bytes); + pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sme_disassoc_cnf.bssid.bytes)); status = lim_prepare_disconnect_done_ind (mac_ctx, &err_msg, - sme_disassoc_cnf.sme_session_id, + sme_disassoc_cnf.vdev_id, eSIR_SME_INVALID_SESSION, NULL); @@ -4659,8 +4478,8 @@ static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx, disassoc_req.bssid.bytes, &session_id); if (!session) { - pe_err("session not found for bssid:%pM", - disassoc_req.bssid.bytes); + pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(disassoc_req.bssid.bytes)); lim_send_sme_disassoc_ntf(mac_ctx, disassoc_req.peer_macaddr.bytes, eSIR_SME_INVALID_PARAMETERS, @@ -4670,6 +4489,23 @@ static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx, return; } + /* In LFR2.0 roaming scenario, if association is not completed with + * new AP, there is possibality of trying to send disassoc in + * failure handling. So, if vdev is in INIT state send + * disassoc failure and cleanup session. + */ + if (QDF_IS_STATUS_SUCCESS( + wlan_vdev_mlme_is_init_state(session->vdev))) { + pe_err("vdev is in INIT state. Send failure."); + lim_send_sme_disassoc_ntf(mac_ctx, + disassoc_req.peer_macaddr.bytes, + eSIR_SME_INVALID_PARAMETERS, + eLIM_HOST_DISASSOC, 1, + disassoc_req.sessionId, session); + + return; + } + if (LIM_IS_STA_ROLE(session)) lim_process_disconnect_sta(session, msg); else @@ -4690,14 +4526,25 @@ static void lim_process_sme_deauth_req(struct mac_context *mac_ctx, sme_deauth_req.bssid.bytes, &session_id); if (!session) { - pe_err("session not found for bssid:%pM", - sme_deauth_req.bssid.bytes); + pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sme_deauth_req.bssid.bytes)); lim_send_sme_deauth_ntf(mac_ctx, sme_deauth_req.peer_macaddr.bytes, eSIR_SME_INVALID_PARAMETERS, eLIM_HOST_DEAUTH, 1, - sme_deauth_req.sessionId); + sme_deauth_req.vdev_id); + + return; + } + if (QDF_IS_STATUS_SUCCESS( + wlan_vdev_mlme_is_init_state(session->vdev))) { + pe_err("vdev is in INIT state. Send failure."); + lim_send_sme_deauth_ntf(mac_ctx, + sme_deauth_req.peer_macaddr.bytes, + eSIR_SME_INVALID_PARAMETERS, + eLIM_HOST_DEAUTH, 1, + sme_deauth_req.vdev_id); return; } @@ -4778,10 +4625,6 @@ bool lim_process_sme_req_messages(struct mac_context *mac, __lim_process_send_disassoc_frame(mac, msg_buf); break; - case eWNI_SME_SETCONTEXT_REQ: - __lim_process_sme_set_context_req(mac, msg_buf); - break; - case eWNI_SME_STOP_BSS_REQ: bufConsumed = __lim_process_sme_stop_bss_req(mac, pMsg); break; @@ -4808,14 +4651,6 @@ bool lim_process_sme_req_messages(struct mac_context *mac, lim_process_sme_addts_rsp_timeout(mac, pMsg->bodyval); break; - case eWNI_SME_GET_STATISTICS_REQ: - __lim_process_sme_get_statistics_request(mac, msg_buf); - /* - * HAL consumes msg_buf. It will be freed there. - * Set bufConsumed to false. - */ - bufConsumed = false; - break; #ifdef FEATURE_WLAN_ESE case eWNI_SME_GET_TSM_STATS_REQ: __lim_process_sme_get_tsm_stats_request(mac, msg_buf); @@ -4860,9 +4695,6 @@ bool lim_process_sme_req_messages(struct mac_context *mac, case eWNI_SME_FT_PRE_AUTH_REQ: bufConsumed = (bool) lim_process_ft_pre_auth_req(mac, pMsg); break; - case eWNI_SME_FT_UPDATE_KEY: - lim_process_ft_update_key(mac, msg_buf); - break; case eWNI_SME_FT_AGGR_QOS_REQ: lim_process_ft_aggr_qos_req(mac, msg_buf); @@ -4949,6 +4781,9 @@ bool lim_process_sme_req_messages(struct mac_context *mac, case WNI_SME_UPDATE_MU_EDCA_PARAMS: lim_process_sme_update_mu_edca_params(mac, pMsg->bodyval); break; + case eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS: + lim_process_sme_update_session_edca_txq_params(mac, msg_buf); + break; case WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU: lim_process_sme_cfg_action_frm_in_tb_ppdu(mac, (struct sir_cfg_action_frm_tb_ppdu *)msg_buf); @@ -5017,9 +4852,9 @@ static void lim_process_sme_start_beacon_req(struct mac_context *mac, uint32_t * */ lim_apply_configuration(mac, pe_session); QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, - FL("Start Beacon with ssid %s Ch %d"), + FL("Start Beacon with ssid %s Ch freq %d"), pe_session->ssId.ssId, - pe_session->currentOperChannel); + pe_session->curr_op_freq); lim_send_beacon(mac, pe_session); lim_enable_obss_detection_config(mac, pe_session); lim_send_obss_color_collision_cfg(mac, pe_session, @@ -5090,6 +4925,7 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, struct pe_session *session_entry; uint8_t session_id; /* PE session_id */ int8_t max_tx_pwr; + uint32_t target_freq; if (!msg_buf) { pe_err("msg_buf is NULL"); @@ -5097,8 +4933,10 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, } ch_change_req = (tpSirChanChangeRequest)msg_buf; - max_tx_pwr = lim_get_regulatory_max_transmit_power( - mac_ctx, ch_change_req->targetChannel); + target_freq = ch_change_req->target_chan_freq; + + max_tx_pwr = wlan_reg_get_channel_reg_power_for_freq( + mac_ctx->pdev, target_freq); if ((ch_change_req->messageType != eWNI_SME_CHANNEL_CHANGE_REQ) || (max_tx_pwr == WMA_MAX_TXPOWER_INVALID)) { @@ -5114,11 +4952,10 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, return; } - if ((session_entry->currentOperChannel == - ch_change_req->targetChannel) && - (session_entry->ch_width == ch_change_req->ch_width)) { - pe_err("Target channel and mode is same as current channel and mode channel %d and mode %d", - session_entry->currentOperChannel, session_entry->ch_width); + if (session_entry->curr_op_freq == target_freq && + session_entry->ch_width == ch_change_req->ch_width) { + pe_err("Target channel and mode is same as current channel and mode channel freq %d and mode %d", + session_entry->curr_op_freq, session_entry->ch_width); return; } @@ -5130,17 +4967,20 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, LIM_SWITCH_CHANNEL_MONITOR; pe_nofl_debug("SAP CSA: %d ---> %d, ch_bw %d, nw_type %d, dot11mode %d", - session_entry->currentOperChannel, - ch_change_req->targetChannel, + session_entry->curr_op_freq, target_freq, ch_change_req->ch_width, ch_change_req->nw_type, ch_change_req->dot11mode); - if (IS_DOT11_MODE_HE(ch_change_req->dot11mode)) { - if (wlan_reg_is_24ghz_ch(ch_change_req->targetChannel) && - !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) - session_entry->vhtCapability = 0; - else if (wlan_reg_is_5ghz_ch(ch_change_req->targetChannel)) - session_entry->vhtCapability = 1; + if (IS_DOT11_MODE_HE(ch_change_req->dot11mode) && + ((QDF_MONITOR_MODE == session_entry->opmode) || + lim_is_session_he_capable(session_entry))) { + lim_update_session_he_capable_chan_switch + (mac_ctx, session_entry, target_freq); + } else if (wlan_reg_is_6ghz_chan_freq(target_freq)) { + pe_debug("Invalid target_freq %d for dot11mode %d cur HE %d", + target_freq, ch_change_req->dot11mode, + lim_is_session_he_capable(session_entry)); + return; } /* Store the New Channel Params in session_entry */ @@ -5154,10 +4994,9 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, (ch_change_req->ch_width ? 1 : 0); session_entry->htRecommendedTxWidthSet = session_entry->htSupportedChannelWidthSet; - session_entry->currentOperChannel = - ch_change_req->targetChannel; - session_entry->limRFBand = - lim_get_rf_band(session_entry->currentOperChannel); + session_entry->curr_op_freq = target_freq; + session_entry->limRFBand = lim_get_rf_band( + session_entry->curr_op_freq); session_entry->cac_duration_ms = ch_change_req->cac_duration_ms; session_entry->dfs_regdomain = ch_change_req->dfs_regdomain; session_entry->maxTxPower = max_tx_pwr; @@ -5167,7 +5006,7 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx, /* Initialize 11h Enable Flag */ if (CHAN_HOP_ALL_BANDS_ENABLE || - session_entry->limRFBand == BAND_5G) + session_entry->limRFBand == REG_BAND_5G) session_entry->lim11hEnable = mac_ctx->mlme_cfg->gen.enabled_11h; else @@ -5278,6 +5117,7 @@ lim_update_add_ie_buffer(struct mac_context *mac, } +#ifdef QCA_IBSS_SUPPORT /** * lim_update_ibss_prop_add_ies() - update IBSS prop IE * @mac : Pointer to Global MAC structure @@ -5348,7 +5188,14 @@ lim_update_ibss_prop_add_ies(struct mac_context *mac, uint8_t **pDstData_buff, } return true; } - +#else +static bool +lim_update_ibss_prop_add_ies(struct mac_context *mac, uint8_t **pDstData_buff, + uint16_t *pDstDataLen, tSirModifyIE *pModifyIE) +{ + return false; +} +#endif /* * lim_process_modify_add_ies() - process modify additional IE req. * @@ -5380,8 +5227,8 @@ static void lim_process_modify_add_ies(struct mac_context *mac_ctx, if (!session_entry) { pe_err("Session not found for given bssid" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(modify_add_ies->modifyIE.bssid.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(modify_add_ies->modifyIE.bssid.bytes)); goto end; } if ((0 == modify_add_ies->modifyIE.ieBufferlength) || @@ -5471,8 +5318,8 @@ static void lim_process_update_add_ies(struct mac_context *mac_ctx, if (!session_entry) { pe_debug("Session not found for given bssid" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(update_ie->bssid.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(update_ie->bssid.bytes)); goto end; } addn_ie = &session_entry->add_ie_params; @@ -5571,34 +5418,22 @@ static void lim_process_update_add_ies(struct mac_context *mac_ctx, update_ie->pAdditionIEBuffer = NULL; } -/** - * send_extended_chan_switch_action_frame()- function to send ECSA - * action frame for each sta connected to SAP/GO and AP in case of - * STA . - * @mac_ctx: pointer to global mac structure - * @new_channel: new channel to switch to. - * @ch_bandwidth: BW of channel to calculate op_class - * @session_entry: pe session - * - * This function is called to send ECSA frame for STA/CLI and SAP/GO. - * - * Return: void - */ - -static void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, - uint16_t new_channel, uint8_t ch_bandwidth, - struct pe_session *session_entry) +void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, + uint16_t new_channel_freq, + enum phy_ch_width ch_bandwidth, + struct pe_session *session_entry) { - uint16_t op_class; + uint8_t op_class = 0; uint8_t switch_mode = 0, i; tpDphHashNode psta; uint8_t switch_count; + uint8_t new_channel = 0; - op_class = wlan_reg_dmn_get_opclass_from_channel( - mac_ctx->scan.countryCodeCurrent, - new_channel, - ch_bandwidth); - + op_class = + lim_op_class_from_bandwidth(mac_ctx, new_channel_freq, + ch_bandwidth, + session_entry->gLimChannelSwitch.sec_ch_offset); + new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq); if (LIM_IS_AP_ROLE(session_entry) && (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)) switch_mode = session_entry->gLimChannelSwitch.switchMode; @@ -5626,21 +5461,22 @@ static void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, } void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, - uint16_t new_channel, - uint8_t ch_bandwidth, + uint16_t new_channel_freq, + enum phy_ch_width ch_bandwidth, struct pe_session *session_entry) { - uint16_t op_class; + uint8_t op_class = 0, new_channel; uint8_t switch_mode = 0, i; uint8_t switch_count; tpDphHashNode psta; tpDphHashNode dph_node_array_ptr; dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray; - - op_class = wlan_reg_dmn_get_opclass_from_channel( - mac_ctx->scan.countryCodeCurrent, - new_channel, ch_bandwidth); + op_class = + lim_op_class_from_bandwidth(mac_ctx, new_channel_freq, + ch_bandwidth, + session_entry->gLimChannelSwitch.sec_ch_offset); + new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq); if (LIM_IS_AP_ROLE(session_entry) && (false == mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch)) @@ -5689,8 +5525,9 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, struct pe_session *session_entry = NULL; uint8_t session_id; tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch; - enum offset_t ch_offset; QDF_STATUS status; + enum phy_ch_width ch_width; + uint32_t target_ch_freq; if (!msg_buf) { pe_err("Buffer is Pointing to NULL"); @@ -5701,8 +5538,8 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, session_entry = pe_find_session_by_bssid(mac_ctx, dfs_csa_ie_req->bssid, &session_id); if (!session_entry) { - pe_err("Session not found for given BSSID" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(dfs_csa_ie_req->bssid)); + pe_err("Session not found for given BSSID" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(dfs_csa_ie_req->bssid)); return; } @@ -5714,14 +5551,21 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, /* target channel */ session_entry->gLimChannelSwitch.primaryChannel = - dfs_csa_ie_req->targetChannel; - + wlan_reg_freq_to_chan(mac_ctx->pdev, + dfs_csa_ie_req->target_chan_freq); + session_entry->gLimChannelSwitch.sw_target_freq = + dfs_csa_ie_req->target_chan_freq; + target_ch_freq = dfs_csa_ie_req->target_chan_freq; /* Channel switch announcement needs to be included in beacon */ session_entry->dfsIncludeChanSwIe = true; session_entry->gLimChannelSwitch.switchCount = dfs_csa_ie_req->ch_switch_beacon_cnt; - session_entry->gLimChannelSwitch.ch_width = - dfs_csa_ie_req->ch_params.ch_width; + ch_width = dfs_csa_ie_req->ch_params.ch_width; + if (ch_width >= CH_WIDTH_160MHZ && + wma_get_vht_ch_width() < WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { + ch_width = CH_WIDTH_80MHZ; + } + session_entry->gLimChannelSwitch.ch_width = ch_width; session_entry->gLimChannelSwitch.sec_ch_offset = dfs_csa_ie_req->ch_params.sec_ch_offset; if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false) @@ -5738,7 +5582,7 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, /* Now encode the Wider Ch BW element depending on the ch width */ wider_bw_ch_switch = &session_entry->gLimWiderBWChannelSwitch; - switch (dfs_csa_ie_req->ch_params.ch_width) { + switch (ch_width) { case CH_WIDTH_20MHZ: /* * Wide channel BW sublement in channel wrapper element is not @@ -5818,27 +5662,25 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, if (QDF_IS_STATUS_ERROR(status)) pe_err("cannot start ap_ecsa_timer"); - if (dfs_csa_ie_req->ch_params.ch_width == CH_WIDTH_80MHZ) - ch_offset = BW80; - else - ch_offset = dfs_csa_ie_req->ch_params.sec_ch_offset; - - pe_debug("IE count:%d chan:%d width:%d wrapper:%d ch_offset:%d", - session_entry->gLimChannelSwitch.switchCount, - session_entry->gLimChannelSwitch.primaryChannel, - session_entry->gLimChannelSwitch.ch_width, - session_entry->dfsIncludeChanWrapperIe, - ch_offset); + pe_debug("IE count:%d chan:%d freq %d width:%d wrapper:%d ch_offset:%d", + session_entry->gLimChannelSwitch.switchCount, + session_entry->gLimChannelSwitch.primaryChannel, + session_entry->gLimChannelSwitch.sw_target_freq, + session_entry->gLimChannelSwitch.ch_width, + session_entry->dfsIncludeChanWrapperIe, + session_entry->gLimChannelSwitch.sec_ch_offset); /* Send ECSA/CSA Action frame after updating the beacon */ - if (CHAN_HOP_ALL_BANDS_ENABLE) - lim_send_chan_switch_action_frame(mac_ctx, - session_entry->gLimChannelSwitch.primaryChannel, - ch_offset, session_entry); + if (CHAN_HOP_ALL_BANDS_ENABLE && + !WLAN_REG_IS_6GHZ_CHAN_FREQ(target_ch_freq)) + lim_send_chan_switch_action_frame + (mac_ctx, + session_entry->gLimChannelSwitch.primaryChannel, + ch_width, session_entry); else - send_extended_chan_switch_action_frame(mac_ctx, - session_entry->gLimChannelSwitch.primaryChannel, - ch_offset, session_entry); + send_extended_chan_switch_action_frame + (mac_ctx, target_ch_freq, ch_width, + session_entry); } /** @@ -5858,26 +5700,29 @@ static void lim_process_ext_change_channel(struct mac_context *mac_ctx, struct sir_sme_ext_cng_chan_req *ext_chng_channel = (struct sir_sme_ext_cng_chan_req *) msg; struct pe_session *session_entry = NULL; + uint32_t new_ext_chan_freq; if (!msg) { pe_err("Buffer is Pointing to NULL"); return; } session_entry = - pe_find_session_by_sme_session_id(mac_ctx, - ext_chng_channel->session_id); + pe_find_session_by_vdev_id(mac_ctx, ext_chng_channel->vdev_id); if (!session_entry) { - pe_err("Session not found for given session %d", - ext_chng_channel->session_id); + pe_err("Session not found for given vdev_id %d", + ext_chng_channel->vdev_id); return; } if (LIM_IS_AP_ROLE(session_entry)) { pe_err("not an STA/CLI session"); return; } - send_extended_chan_switch_action_frame(mac_ctx, - ext_chng_channel->new_channel, - 0, session_entry); + new_ext_chan_freq = + wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + ext_chng_channel->new_channel); + session_entry->gLimChannelSwitch.sec_ch_offset = 0; + send_extended_chan_switch_action_frame(mac_ctx, new_ext_chan_freq, 0, + session_entry); } /** @@ -5954,8 +5799,8 @@ static void lim_process_nss_update_request(struct mac_context *mac_ctx, nss_update_req_ptr = (struct sir_nss_update_request *)msg_buf; vdev_id = nss_update_req_ptr->vdev_id; - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - nss_update_req_ptr->vdev_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, + nss_update_req_ptr->vdev_id); if (!session_entry) { pe_err("Session not found for given session_id %d", nss_update_req_ptr->vdev_id); @@ -5976,6 +5821,11 @@ static void lim_process_nss_update_request(struct mac_context *mac_ctx, if ((nss_update_req_ptr->new_nss == NSS_1x1_MODE) && (session_entry->ch_width > CH_WIDTH_80MHZ)) session_entry->gLimOperatingMode.chanWidth = CH_WIDTH_80MHZ; + if (session_entry->gLimOperatingMode.chanWidth <= CH_WIDTH_160MHZ && + nss_update_req_ptr->ch_width < + session_entry->gLimOperatingMode.chanWidth) + session_entry->gLimOperatingMode.chanWidth = + nss_update_req_ptr->ch_width; pe_debug("ch width %d Rx NSS %d", session_entry->gLimOperatingMode.chanWidth, @@ -6161,7 +6011,7 @@ static void obss_color_collision_process_color_change(struct mac_context *mac_ct i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_bss_color; pe_debug("New bss color = %d", bss_color_index_array[i]); - he_bss_color.session_id = obss_color_info->vdev_id; + he_bss_color.vdev_id = obss_color_info->vdev_id; he_bss_color.bss_color = bss_color_index_array[i]; lim_process_set_he_bss_color(mac_ctx, (uint32_t *)&he_bss_color); @@ -6197,11 +6047,10 @@ void lim_process_set_he_bss_color(struct mac_context *mac_ctx, uint32_t *msg_buf } bss_color = (struct sir_set_he_bss_color *)msg_buf; - session_entry = pe_find_session_by_sme_session_id(mac_ctx, - bss_color->session_id); + session_entry = pe_find_session_by_vdev_id(mac_ctx, bss_color->vdev_id); if (!session_entry) { - pe_err("Session not found for given session_id %d", - bss_color->session_id); + pe_err("Session not found for given vdev_id %d", + bss_color->vdev_id); return; } @@ -6306,8 +6155,7 @@ void lim_process_obss_color_collision_info(struct mac_context *mac_ctx, } obss_color_info = (struct wmi_obss_color_collision_info *)msg_buf; - session = pe_find_session_by_sme_session_id(mac_ctx, - obss_color_info->vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, obss_color_info->vdev_id); if (!session) { pe_err("Session not found for given session_id %d", obss_color_info->vdev_id); @@ -6370,8 +6218,7 @@ void lim_send_csa_restart_req(struct mac_context *mac_ctx, uint8_t vdev_id) { struct pe_session *session; - session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id); - + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { pe_err("session not found for vdev id %d", vdev_id); return; @@ -6395,11 +6242,18 @@ void lim_add_roam_blacklist_ap(struct mac_context *mac_ctx, struct sir_rssi_disallow_lst entry; struct roam_blacklist_timeout *blacklist; + pe_debug("Received Blacklist event from FW num entries %d", + src_lst->num_entries); blacklist = &src_lst->roam_blacklist[0]; for (i = 0; i < src_lst->num_entries; i++) { entry.bssid = blacklist->bssid; entry.time_during_rejection = blacklist->received_time; + entry.reject_reason = blacklist->reject_reason; + entry.source = blacklist->source ? blacklist->source : + ADDED_BY_TARGET; + entry.original_timeout = blacklist->original_timeout; + entry.received_time = blacklist->received_time; /* If timeout = 0 and rssi = 0 ignore the entry */ if (!blacklist->timeout && !blacklist->rssi) { continue; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_tdls.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_tdls.c index eca4814bda45bc01afc138fad6f4382f628067a7..84b44b217c06798f61d4be86b92a834ef2aee330 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_tdls.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_tdls.c @@ -58,7 +58,6 @@ #include "lim_utils.h" #include "lim_security_utils.h" #include "dot11f.h" -#include "lim_sta_hash_api.h" #include "sch_api.h" #include "lim_send_messages.h" #include "utils_parser.h" @@ -203,12 +202,16 @@ static void populate_dot11f_tdls_offchannel_params( uint32_t band; uint8_t nss_2g; uint8_t nss_5g; + qdf_freq_t ch_freq; numChans = mac->mlme_cfg->reg.valid_channel_list_num; - qdf_mem_copy(validChan, mac->mlme_cfg->reg.valid_channel_list, - mac->mlme_cfg->reg.valid_channel_list_num); - if (IS_5G_CH(pe_session->currentOperChannel)) + for (i = 0; i < mac->mlme_cfg->reg.valid_channel_list_num; i++) { + validChan[i] = wlan_reg_freq_to_chan(mac->pdev, + mac->mlme_cfg->reg.valid_channel_freq_list[i]); + } + + if (wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq)) band = BAND_5G; else band = BAND_2G; @@ -220,10 +223,11 @@ static void populate_dot11f_tdls_offchannel_params( /* validating the channel list for DFS and 2G channels */ for (i = 0U; i < numChans; i++) { + ch_freq = wlan_reg_legacy_chan_to_freq(mac->pdev, validChan[i]); if ((band == BAND_5G) && (NSS_2x2_MODE == nss_5g) && (NSS_1x1_MODE == nss_2g) && - (wlan_reg_is_dfs_ch(mac->pdev, validChan[i]))) { + (wlan_reg_is_dfs_for_freq(mac->pdev, ch_freq))) { pe_debug("skipping channel: %d, nss_5g: %d, nss_2g: %d", validChan[i], nss_5g, nss_2g); continue; @@ -266,14 +270,14 @@ static void populate_dot11f_tdls_offchannel_params( op_class = wlan_reg_dmn_get_opclass_from_channel( mac->scan.countryCodeCurrent, - pe_session->currentOperChannel, + wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq), chanOffset); - pe_debug("countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d", - mac->scan.countryCodeCurrent, - pe_session->currentOperChannel, - pe_session->htSecondaryChannelOffset, - chanOffset, op_class); + pe_debug("countryCodeCurrent: %s, curr_op_freq: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d", + mac->scan.countryCodeCurrent, + pe_session->curr_op_freq, + pe_session->htSecondaryChannelOffset, + chanOffset, op_class); suppOperClasses->present = 1; suppOperClasses->classes[0] = op_class; @@ -420,12 +424,12 @@ static uint32_t lim_prepare_tdls_frame_header(struct mac_context *mac, uint8_t * (uint8_t *) (addr3), sizeof(tSirMacAddr)); pe_debug("Preparing TDLS frame header to %s A1:" - QDF_MAC_ADDR_STR", A2:"QDF_MAC_ADDR_STR", A3:" - QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_FMT", A2:"QDF_MAC_ADDR_FMT", A3:" + QDF_MAC_ADDR_FMT, (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT", - QDF_MAC_ADDR_ARRAY(pMacHdr->addr1), - QDF_MAC_ADDR_ARRAY(pMacHdr->addr2), - QDF_MAC_ADDR_ARRAY(pMacHdr->addr3)); + QDF_MAC_ADDR_REF(pMacHdr->addr1), + QDF_MAC_ADDR_REF(pMacHdr->addr2), + QDF_MAC_ADDR_REF(pMacHdr->addr3)); if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) { pMacHdr->qosControl.tid = tid; @@ -632,10 +636,10 @@ static QDF_STATUS lim_send_tdls_dis_req_frame(struct mac_context *mac, } #endif - pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_DISCOVERY_REQUEST, lim_trace_tdls_action_string(TDLS_DISCOVERY_REQUEST), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -678,7 +682,7 @@ static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac, vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info; - if (IS_5G_CH(pe_session->currentOperChannel)) + if (wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq)) nss = mac->vdev_type_nss_5g.tdls; else nss = mac->vdev_type_nss_2g.tdls; @@ -716,9 +720,10 @@ static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac, } pe_debug("HT present: %hu, Chan Width: %hu", htCap->present, htCap->supportedChannelWidthSet); - if (((pe_session->currentOperChannel <= SIR_11B_CHANNEL_END) && + + if ((WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq) && vht_cap_info->b24ghz_band) || - (pe_session->currentOperChannel >= SIR_11B_CHANNEL_END)) { + WLAN_REG_IS_5GHZ_CH_FREQ(pe_session->curr_op_freq)) { if (IS_DOT11_MODE_VHT(selfDot11Mode) && IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { /* Include VHT Capability IE */ @@ -829,7 +834,8 @@ static QDF_STATUS lim_send_tdls_dis_rsp_frame(struct mac_context *mac, if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, &tdlsDisRsp.SuppRates, &tdlsDisRsp.ExtSuppRates, - pe_session->currentOperChannel)) + wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq))) pe_err("could not populate supported data rates"); /* populate extended capability IE */ @@ -853,7 +859,7 @@ static QDF_STATUS lim_send_tdls_dis_rsp_frame(struct mac_context *mac, &tdlsDisRsp.SuppChannels, &tdlsDisRsp. SuppOperatingClasses); - if (mac->mlme_cfg->gen.band_capability != BAND_2G) { + if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { tdlsDisRsp.ht2040_bss_coexistence.present = 1; tdlsDisRsp.ht2040_bss_coexistence.info_request = 1; } @@ -935,10 +941,10 @@ static QDF_STATUS lim_send_tdls_dis_rsp_frame(struct mac_context *mac, qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe, addIeLen); } - pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_DISCOVERY_RESPONSE, lim_trace_tdls_action_string(TDLS_DISCOVERY_RESPONSE), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -980,9 +986,11 @@ static void populate_dotf_tdls_vht_aid(struct mac_context *mac, uint32_t selfDot tDot11fIEAID *Aid, struct pe_session *pe_session) { - if (((pe_session->currentOperChannel <= SIR_11B_CHANNEL_END) && + if (((wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq) <= + SIR_11B_CHANNEL_END) && mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) || - (pe_session->currentOperChannel >= SIR_11B_CHANNEL_END)) { + (wlan_reg_freq_to_chan(mac->pdev, pe_session->curr_op_freq) >= + SIR_11B_CHANNEL_END)) { if (IS_DOT11_MODE_VHT(selfDot11Mode) && IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { @@ -999,8 +1007,8 @@ static void populate_dotf_tdls_vht_aid(struct mac_context *mac, uint32_t selfDot } else { Aid->present = 0; pe_err("sta is NULL for " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peerMac.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peerMac.bytes)); } } } else { @@ -1138,7 +1146,8 @@ QDF_STATUS lim_send_tdls_link_setup_req_frame(struct mac_context *mac, if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, &tdlsSetupReq.SuppRates, &tdlsSetupReq.ExtSuppRates, - pe_session->currentOperChannel)) + wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq))) pe_err("could not populate supported data rates"); /* Populate extended capability IE */ @@ -1219,7 +1228,7 @@ QDF_STATUS lim_send_tdls_link_setup_req_frame(struct mac_context *mac, &tdlsSetupReq.SuppChannels, &tdlsSetupReq. SuppOperatingClasses); - if (mac->mlme_cfg->gen.band_capability != BAND_2G) { + if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { tdlsSetupReq.ht2040_bss_coexistence.present = 1; tdlsSetupReq.ht2040_bss_coexistence.info_request = 1; } @@ -1309,10 +1318,10 @@ QDF_STATUS lim_send_tdls_link_setup_req_frame(struct mac_context *mac, addIeLen); } - pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_SETUP_REQUEST, lim_trace_tdls_action_string(TDLS_SETUP_REQUEST), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -1500,12 +1509,12 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac, padLen - MIN_VENDOR_SPECIFIC_IE_SIZE); } #endif - pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_TEARDOWN, lim_trace_tdls_action_string(TDLS_TEARDOWN), ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" : "DIRECT"), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -1598,7 +1607,8 @@ static QDF_STATUS lim_send_tdls_setup_rsp_frame(struct mac_context *mac, if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac, &tdlsSetupRsp.SuppRates, &tdlsSetupRsp.ExtSuppRates, - pe_session->currentOperChannel)) + wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq))) pe_err("could not populate supported data rates"); /* Populate extended capability IE */ @@ -1671,7 +1681,7 @@ static QDF_STATUS lim_send_tdls_setup_rsp_frame(struct mac_context *mac, &tdlsSetupRsp.SuppChannels, &tdlsSetupRsp. SuppOperatingClasses); - if (mac->mlme_cfg->gen.band_capability != BAND_2G) { + if (mac->mlme_cfg->gen.band_capability != BIT(REG_BAND_2G)) { tdlsSetupRsp.ht2040_bss_coexistence.present = 1; tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1; } @@ -1761,10 +1771,10 @@ static QDF_STATUS lim_send_tdls_setup_rsp_frame(struct mac_context *mac, addIeLen); } - pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_SETUP_RESPONSE, lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -1968,10 +1978,10 @@ QDF_STATUS lim_send_tdls_link_setup_cnf_frame(struct mac_context *mac, } #endif - pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_STR, + pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT, TDLS_SETUP_CONFIRM, lim_trace_tdls_action_string(TDLS_SETUP_CONFIRM), - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + QDF_MAC_ADDR_REF(peer_mac.bytes)); mac->lim.tdls_frm_session_id = pe_session->smeSessionId; lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame, @@ -2177,7 +2187,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap; pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern; pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern; - pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1; + pDot11f->extended_nss_bw_supp = + uVHTCapabilityInfo.vhtCapInfo.extended_nss_bw_supp; pDot11f->rxMCSMap = add_sta_req->vht_cap.supp_mcs.rx_mcs_map; @@ -2185,6 +2196,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; pDot11f->rxHighSupDataRate = uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate; + pDot11f->max_nsts_total = + uVHTSupDataRateInfo.vhtRxsupDataRateInfo.max_nsts_total; pDot11f->txMCSMap = add_sta_req->vht_cap.supp_mcs.tx_mcs_map; @@ -2193,7 +2206,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, pDot11f->txSupDataRate = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate; - pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved; + pDot11f->vht_extended_nss_bw_cap = + uVHTSupDataRateInfo.vhtTxSupDataRateInfo.vht_extended_nss_bw_cap; lim_log_vht_cap(mac, pDot11f); @@ -2279,7 +2293,7 @@ lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx, } } - if (IS_5G_CH(session_entry->currentOperChannel)) + if (wlan_reg_is_5ghz_ch_freq(session_entry->curr_op_freq)) nss = mac_ctx->vdev_type_nss_5g.tdls; else nss = mac_ctx->vdev_type_nss_2g.tdls; @@ -2317,7 +2331,7 @@ lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx, } } lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps, - session_entry, nss); + session_entry, nss, NULL); /** * Set the erpEnabled bit if the phy is in G mode and at least * one A rate is supported @@ -2372,6 +2386,7 @@ static void lim_tdls_update_hash_node_info(struct mac_context *mac, pe_debug("sta->htSupportedChannelWidthSet: 0x%x", sta->htSupportedChannelWidthSet); + sta->ch_width = sta->htSupportedChannelWidthSet; sta->htMIMOPSState = htCaps->mimoPowerSave; sta->htMaxAmsduLength = htCaps->maximalAMSDUsize; sta->htAMpduDensity = htCaps->mpduDensity; @@ -2429,7 +2444,8 @@ static void lim_tdls_update_hash_node_info(struct mac_context *mac, */ if (pe_session->htSupportedChannelWidthSet) { cbMode = lim_select_cb_mode(sta, pe_session, - pe_session->currentOperChannel, + wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq), sta->vhtSupportedChannelWidthSet); if (sta->mlmStaContext.vhtCapability) @@ -2484,14 +2500,14 @@ static QDF_STATUS lim_tdls_setup_add_sta(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } if (sta && pAddStaReq->tdls_oper == TDLS_OPER_ADD) { - pe_err("TDLS entry for peer: "QDF_MAC_ADDR_STR " already exist, cannot add new entry", - QDF_MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes)); + pe_err("TDLS entry for peer: "QDF_MAC_ADDR_FMT " already exist, cannot add new entry", + QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); return QDF_STATUS_E_FAILURE; } if (sta && sta->staType != STA_ENTRY_TDLS_PEER) { - pe_err("Non TDLS entry for peer: "QDF_MAC_ADDR_STR " already exist", - QDF_MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes)); + pe_err("Non TDLS entry for peer: "QDF_MAC_ADDR_FMT " already exist", + QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); return QDF_STATUS_E_FAILURE; } @@ -2499,16 +2515,16 @@ static QDF_STATUS lim_tdls_setup_add_sta(struct mac_context *mac, aid = lim_assign_peer_idx(mac, pe_session); if (!aid) { - pe_err("No more free AID for peer: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes)); + pe_err("No more free AID for peer: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); return QDF_STATUS_E_FAILURE; } /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */ SET_PEER_AID_BITMAP(pe_session->peerAIDBitmap, aid); - pe_debug("Aid: %d, for peer: " QDF_MAC_ADDR_STR, - aid, QDF_MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes)); + pe_debug("Aid: %d, for peer: " QDF_MAC_ADDR_FMT, + aid, QDF_MAC_ADDR_REF(pAddStaReq->peermac.bytes)); sta = dph_get_hash_entry(mac, aid, &pe_session->dph.dphHashTable); @@ -2564,8 +2580,8 @@ static QDF_STATUS lim_tdls_del_sta(struct mac_context *mac, if (sta && sta->staType == STA_ENTRY_TDLS_PEER) status = lim_del_sta(mac, sta, resp_reqd, pe_session); else - pe_debug("TDLS peer "QDF_MAC_ADDR_STR" not found", - QDF_MAC_ADDR_ARRAY(peerMac.bytes)); + pe_debug("TDLS peer "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peerMac.bytes)); return status; } @@ -2591,9 +2607,7 @@ static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(struct mac_context *mac, add_sta_rsp->session_id = sessionId; add_sta_rsp->status_code = status; - if (sta) { - add_sta_rsp->sta_id = sta->staIndex; - } + if (peerMac) { qdf_mem_copy(add_sta_rsp->peermac.bytes, (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE); @@ -2630,9 +2644,8 @@ QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, uint16_t aid = 0; SET_LIM_PROCESS_DEFD_MESGS(mac, true); - pe_debug("staIdx: %d, staMac: "QDF_MAC_ADDR_STR, - pAddStaParams->staIdx, - QDF_MAC_ADDR_ARRAY(pAddStaParams->staMac)); + pe_debug("staMac: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pAddStaParams->staMac)); if (pAddStaParams->status != QDF_STATUS_SUCCESS) { QDF_ASSERT(0); @@ -2649,8 +2662,6 @@ QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, goto add_sta_error; } - sta->bssId = pAddStaParams->bss_idx; - sta->staIndex = pAddStaParams->staIdx; sta->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; sta->valid = 1; add_sta_error: @@ -2668,6 +2679,7 @@ QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, * @msg_type: Indicates message type * @result_code: Indicates the result of previously issued * eWNI_SME_msg_type_REQ message + * @vdev_id: vdev id * * This function is called by lim_process_sme_req_messages() to send * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP @@ -2679,7 +2691,7 @@ QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, static void lim_send_tdls_comp_mgmt_rsp(struct mac_context *mac_ctx, uint16_t msg_type, - tSirResultCodes result_code, uint8_t sme_session_id) + tSirResultCodes result_code, uint8_t vdev_id) { struct scheduler_msg msg = {0}; struct tdls_send_mgmt_rsp *sme_rsp; @@ -2693,7 +2705,7 @@ lim_send_tdls_comp_mgmt_rsp(struct mac_context *mac_ctx, uint16_t msg_type, return; sme_rsp->status_code = (enum legacy_result_code)result_code; - sme_rsp->session_id = sme_session_id; + sme_rsp->vdev_id = vdev_id; sme_rsp->psoc = mac_ctx->psoc; msg.type = msg_type; @@ -2856,10 +2868,6 @@ static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(struct mac_context *mac, del_sta_rsp->session_id = sessionId; del_sta_rsp->status_code = status; - if (sta) { - del_sta_rsp->sta_id = sta->staIndex; - } else - del_sta_rsp->sta_id = STA_INVALID_IDX; qdf_copy_macaddr(&del_sta_rsp->peermac, &peerMac); @@ -3029,8 +3037,8 @@ static void lim_check_aid_and_delete_peer(struct mac_context *p_mac, if (!stads) goto skip; - pe_debug("Deleting "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(stads->staAddr)); + pe_debug("Deleting "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(stads->staAddr)); if (!lim_is_roam_synch_in_progress(session_entry)) { lim_send_deauth_mgmt_frame(p_mac, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_prop_exts_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_prop_exts_utils.c index dc7d61fbb9d7dbd0824e35789dd025fb16d27a5e..e55cf3f88f5ed028b8550c50caa99cab2a3075f6 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -102,52 +102,61 @@ static inline void get_ese_version_ie_probe_response(struct mac_context *mac_ctx static void lim_extract_he_op(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) { - if (session->he_capable && beacon_struct->he_op.present) { - qdf_mem_copy(&session->he_op, &beacon_struct->he_op, - sizeof(session->he_op)); - pe_debug("he_op.bss_color %d", session->he_op.bss_color); - pe_debug("he_op.default_pe %d", session->he_op.default_pe); + uint8_t fw_vht_ch_wd; + uint8_t ap_bcon_ch_width; + uint8_t center_freq_diff; + + if (!session->he_capable) + return; + if (!beacon_struct->he_op.present) { + pe_debug("HE op not present in beacon"); + return; } -} + qdf_mem_copy(&session->he_op, &beacon_struct->he_op, + sizeof(session->he_op)); + pe_debug("he_op.bss_color %d", session->he_op.bss_color); + pe_debug("he_op.default_pe %d", session->he_op.default_pe); + if (!session->he_6ghz_band) + return; + if (!session->he_op.oper_info_6g_present) { + pe_debug("6GHz op not present in 6G beacon"); + return; + } + session->ch_width = session->he_op.oper_info_6g.info.ch_width; + session->ch_center_freq_seg0 = + session->he_op.oper_info_6g.info.center_freq_seg0; + session->ch_center_freq_seg1 = + session->he_op.oper_info_6g.info.center_freq_seg1; -static bool lim_check_he_80_mcs11_supp(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) { - uint16_t rx_mcs_map; - uint16_t tx_mcs_map; - rx_mcs_map = beacon_struct->he_cap.rx_he_mcs_map_lt_80; - tx_mcs_map = beacon_struct->he_cap.tx_he_mcs_map_lt_80; - if ((session->nss == NSS_1x1_MODE) && - ((HE_GET_MCS_4_NSS(rx_mcs_map, 1) == HE_MCS_0_11) || - (HE_GET_MCS_4_NSS(tx_mcs_map, 1) == HE_MCS_0_11))) - return true; - - if ((session->nss == NSS_2x2_MODE) && - ((HE_GET_MCS_4_NSS(rx_mcs_map, 2) == HE_MCS_0_11) || - (HE_GET_MCS_4_NSS(tx_mcs_map, 2) == HE_MCS_0_11))) - return true; + pe_debug("6G op info: ch_wd %d cntr_freq_seg0 %d cntr_freq_seg1 %d", + session->ch_width, session->ch_center_freq_seg0, + session->ch_center_freq_seg1); - return false; -} + if (!session->ch_center_freq_seg1) + return; -static void lim_check_he_ldpc_cap(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) -{ - if (session->he_capable && beacon_struct->he_cap.present) { - if (beacon_struct->he_cap.ldpc_coding) - return; - else if ((session->ch_width == CH_WIDTH_20MHZ) && - !lim_check_he_80_mcs11_supp(session, - beacon_struct)) - return; - session->he_capable = false; - pe_err("LDPC check failed for HE operation"); - if (session->vhtCapability) { - session->dot11mode = MLME_DOT11_MODE_11AC; - pe_debug("Update dot11mode to 11ac"); - } else { - session->dot11mode = MLME_DOT11_MODE_11N; - pe_debug("Update dot11mode to 11N"); - } + fw_vht_ch_wd = wma_get_vht_ch_width(); + if (fw_vht_ch_wd <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) { + session->ch_width = CH_WIDTH_80MHZ; + session->ch_center_freq_seg1 = 0; + return; + } + center_freq_diff = abs(session->ch_center_freq_seg1 - + session->ch_center_freq_seg0); + if (center_freq_diff == 8) { + ap_bcon_ch_width = CH_WIDTH_160MHZ; + } else if (center_freq_diff > 16) { + ap_bcon_ch_width = CH_WIDTH_80P80MHZ; + } else { + session->ch_width = CH_WIDTH_80MHZ; + session->ch_center_freq_seg1 = 0; + return; + } + + if ((ap_bcon_ch_width == CH_WIDTH_80P80MHZ) && + (fw_vht_ch_wd != WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)) { + session->ch_width = CH_WIDTH_80MHZ; + session->ch_center_freq_seg1 = 0; } } @@ -176,13 +185,80 @@ static void lim_check_is_he_mcs_valid(struct pe_session *session, } } +void lim_update_he_bw_cap_mcs(struct pe_session *session, + tSirProbeRespBeacon *beacon) +{ + uint8_t is_80mhz; + + if (!session->he_capable) + return; + + if ((session->opmode == QDF_STA_MODE || + session->opmode == QDF_P2P_CLIENT_MODE) && + beacon && beacon->he_cap.present) { + if (!beacon->he_cap.chan_width_2) + is_80mhz = 1; + else if (beacon->he_cap.chan_width_2 && + (*(uint16_t *)beacon->he_cap.rx_he_mcs_map_160 == + HE_MCS_ALL_DISABLED)) + is_80mhz = 1; + else + is_80mhz = 0; + } else { + is_80mhz = 1; + } + + if (session->ch_width <= CH_WIDTH_80MHZ && is_80mhz) { + session->he_config.chan_width_2 = 0; + session->he_config.chan_width_3 = 0; + } else if (session->ch_width == CH_WIDTH_160MHZ) { + session->he_config.chan_width_3 = 0; + } + /* Reset the > 20MHz caps for 20MHz connection */ + if (session->ch_width == CH_WIDTH_20MHZ) { + session->he_config.chan_width_0 = 0; + session->he_config.chan_width_1 = 0; + session->he_config.chan_width_2 = 0; + session->he_config.chan_width_3 = 0; + session->he_config.chan_width_4 = 0; + session->he_config.chan_width_5 = 0; + session->he_config.chan_width_6 = 0; + session->he_config.he_ppdu_20_in_40Mhz_2G = 0; + session->he_config.he_ppdu_20_in_160_80p80Mhz = 0; + session->he_config.he_ppdu_80_in_160_80p80Mhz = 0; + } + if (WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq)) { + session->he_config.chan_width_1 = 0; + session->he_config.chan_width_2 = 0; + session->he_config.chan_width_3 = 0; + session->he_config.chan_width_5 = 0; + session->he_config.chan_width_6 = 0; + } else { + session->he_config.chan_width_0 = 0; + session->he_config.chan_width_4 = 0; + session->he_config.chan_width_6 = 0; + } + if (!session->he_config.chan_width_2) { + session->he_config.bfee_sts_gt_80 = 0; + session->he_config.num_sounding_gt_80 = 0; + session->he_config.he_ppdu_20_in_160_80p80Mhz = 0; + session->he_config.he_ppdu_80_in_160_80p80Mhz = 0; + *(uint16_t *)session->he_config.rx_he_mcs_map_160 = + HE_MCS_ALL_DISABLED; + *(uint16_t *)session->he_config.tx_he_mcs_map_160 = + HE_MCS_ALL_DISABLED; + } + if (!session->he_config.chan_width_3) { + *(uint16_t *)session->he_config.rx_he_mcs_map_80_80 = + HE_MCS_ALL_DISABLED; + *(uint16_t *)session->he_config.tx_he_mcs_map_80_80 = + HE_MCS_ALL_DISABLED; + } +} #else static inline void lim_extract_he_op(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) {} -static void lim_check_he_ldpc_cap(struct pe_session *session, - tSirProbeRespBeacon *beacon_struct) -{} static void lim_check_is_he_mcs_valid(struct pe_session *session, tSirProbeRespBeacon *beacon_struct) { @@ -244,10 +320,48 @@ static inline bool lim_extract_adaptive_11r_cap(uint8_t *ie, uint16_t ie_len) } #endif -void -lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, - uint16_t ie_len, uint8_t *qos_cap, uint8_t *uapsd, - int8_t *local_constraint, struct pe_session *session) +static +void lim_update_ch_width_for_p2p_client(struct mac_context *mac, + struct pe_session *session, + uint32_t ch_freq) +{ + struct ch_params ch_params = {0}; + + /* + * Some IOT AP's/P2P-GO's (e.g. make: Wireless-AC 9560160MHz as P2P GO), + * send beacon with 20mhz and assoc resp with 80mhz and + * after assoc resp, next beacon also has 80mhz. + * Connection is expected to happen in better possible + * bandwidth(80MHz in this case). + * Start the vdev with max supported ch_width in order to support this. + * It'll be downgraded to appropriate ch_width or the same would be + * continued based on assoc resp. + * Restricting this check for p2p client and 5G only and this may be + * extended to STA based on wider testing results with multiple AP's. + * Limit it to 80MHz as 80+80 is channel specific and 160MHz is not + * supported in p2p. + */ + ch_params.ch_width = CH_WIDTH_80MHZ; + + wlan_reg_set_channel_params_for_freq(mac->pdev, ch_freq, 0, &ch_params); + if (ch_params.ch_width == CH_WIDTH_20MHZ) + ch_params.sec_ch_offset = PHY_SINGLE_CHANNEL_CENTERED; + + session->htSupportedChannelWidthSet = ch_params.sec_ch_offset ? 1 : 0; + session->htRecommendedTxWidthSet = session->htSupportedChannelWidthSet; + session->htSecondaryChannelOffset = ch_params.sec_ch_offset; + session->ch_width = ch_params.ch_width; + session->ch_center_freq_seg0 = ch_params.center_freq_seg0; + session->ch_center_freq_seg1 = ch_params.center_freq_seg1; + pe_debug("Start P2P_CLI in ch freq %d max supported ch_width: %u cbmode: %u seg0: %u, seg1: %u", + ch_freq, ch_params.ch_width, ch_params.sec_ch_offset, + session->ch_center_freq_seg0, session->ch_center_freq_seg1); +} + +void lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, + uint16_t ie_len, uint8_t *qos_cap, + uint8_t *uapsd, int8_t *local_constraint, + struct pe_session *session) { tSirProbeRespBeacon *beacon_struct; uint8_t ap_bcon_ch_width; @@ -257,6 +371,10 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, uint8_t vht_ch_wd; uint8_t center_freq_diff; struct s_ext_cap *ext_cap; + uint8_t chan_center_freq_seg1; + tDot11fIEVHTCaps *vht_caps; + uint8_t channel = 0; + struct mlme_vht_capabilities_info *mlme_vht_cap; beacon_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon)); if (!beacon_struct) @@ -274,6 +392,7 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, return; } + mlme_vht_cap = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; if (beacon_struct->wmeInfoPresent || beacon_struct->wmeEdcaPresent || beacon_struct->HTCaps.present) @@ -287,6 +406,7 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, mac_ctx->lim.htCapabilityPresentInBeacon = 0; vht_op = &beacon_struct->VHTOperation; + vht_caps = &beacon_struct->VHTCaps; if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) && vht_op->present && session->vhtCapability) { @@ -307,20 +427,37 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, !session->htSupportedChannelWidthSet) { if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable_txbf_20mhz) session->vht_config.su_beam_formee = 0; + + if (session->opmode == QDF_P2P_CLIENT_MODE && + !wlan_reg_is_24ghz_ch_freq(beacon_struct->chan_freq)) + lim_update_ch_width_for_p2p_client( + mac_ctx, session, + beacon_struct->chan_freq); + } else if (session->vhtCapabilityPresentInBeacon && vht_op->chanWidth) { /* If VHT is supported min 80 MHz support is must */ ap_bcon_ch_width = vht_op->chanWidth; - if ((ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) && - vht_op->chanCenterFreqSeg2) { + if (vht_caps->vht_extended_nss_bw_cap) { + if (!vht_caps->extended_nss_bw_supp) + chan_center_freq_seg1 = + vht_op->chan_center_freq_seg1; + else + chan_center_freq_seg1 = + beacon_struct->HTInfo.chan_center_freq_seg2; + } else { + chan_center_freq_seg1 = vht_op->chan_center_freq_seg1; + } + if (chan_center_freq_seg1 && + (ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)) { new_ch_width_dfn = true; - if (vht_op->chanCenterFreqSeg2 > - vht_op->chanCenterFreqSeg1) - center_freq_diff = vht_op->chanCenterFreqSeg2 - - vht_op->chanCenterFreqSeg1; + if (chan_center_freq_seg1 > + vht_op->chan_center_freq_seg0) + center_freq_diff = chan_center_freq_seg1 - + vht_op->chan_center_freq_seg0; else - center_freq_diff = vht_op->chanCenterFreqSeg1 - - vht_op->chanCenterFreqSeg2; + center_freq_diff = vht_op->chan_center_freq_seg0 - + chan_center_freq_seg1; if (center_freq_diff == 8) ap_bcon_ch_width = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; @@ -334,6 +471,21 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, fw_vht_ch_wd = wma_get_vht_ch_width(); vht_ch_wd = QDF_MIN(fw_vht_ch_wd, ap_bcon_ch_width); + + if ((vht_ch_wd > WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) && + (ap_bcon_ch_width == + WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) && + mlme_vht_cap->restricted_80p80_bw_supp) { + if ((chan_center_freq_seg1 == 138 && + vht_op->chan_center_freq_seg0 == 155) || + (vht_op->chan_center_freq_seg0 == 138 && + chan_center_freq_seg1 == 155)) + vht_ch_wd = + WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ; + else + vht_ch_wd = + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; + } /* * If the supported channel width is greater than 80MHz and * AP supports Nss > 1 in 160MHz mode then connect the STA @@ -348,22 +500,24 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, } /* * VHT OP IE old definition: - * vht_op->chanCenterFreqSeg1: center freq of 80MHz/160MHz/ + * vht_op->chan_center_freq_seg0: center freq of 80MHz/160MHz/ * primary 80 in 80+80MHz. * - * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * vht_op->chan_center_freq_seg1: center freq of secondary 80 * in 80+80MHz. * * VHT OP IE NEW definition: - * vht_op->chanCenterFreqSeg1: center freq of 80MHz/primary + * vht_op->chan_center_freq_seg0: center freq of 80MHz/primary * 80 in 80+80MHz/center freq of the 80 MHz channel segment * that contains the primary channel in 160MHz mode. * - * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * vht_op->chan_center_freq_seg1: center freq of secondary 80 * in 80+80MHz/center freq of 160MHz. */ - session->ch_center_freq_seg0 = vht_op->chanCenterFreqSeg1; - session->ch_center_freq_seg1 = vht_op->chanCenterFreqSeg2; + session->ch_center_freq_seg0 = vht_op->chan_center_freq_seg0; + session->ch_center_freq_seg1 = chan_center_freq_seg1; + channel = wlan_reg_freq_to_chan(mac_ctx->pdev, + beacon_struct->chan_freq); if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { /* DUT or AP supports only 160MHz */ if (ap_bcon_ch_width == @@ -371,10 +525,9 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, /* AP is in 160MHz mode */ if (!new_ch_width_dfn) { session->ch_center_freq_seg1 = - vht_op->chanCenterFreqSeg1; + vht_op->chan_center_freq_seg0; session->ch_center_freq_seg0 = - lim_get_80Mhz_center_channel( - beacon_struct->channelNumber); + lim_get_80Mhz_center_channel(channel); } } else { /* DUT supports only 160MHz and AP is @@ -383,20 +536,15 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, vht_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; session->ch_center_freq_seg1 = 0; session->ch_center_freq_seg0 = - lim_get_80Mhz_center_channel( - beacon_struct->channelNumber); + lim_get_80Mhz_center_channel(channel); } } else if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) { - session->ch_center_freq_seg0 = - lim_get_80Mhz_center_channel( - beacon_struct->channelNumber); + /* DUT or AP supports only 80MHz */ session->ch_center_freq_seg1 = 0; + session->ch_center_freq_seg0 = + lim_get_80Mhz_center_channel(channel); } session->ch_width = vht_ch_wd + 1; - if (CH_WIDTH_80MHZ < session->ch_width) { - session->vht_config.su_beam_former = 0; - session->nss = 1; - } } if (session->vhtCapability && @@ -418,8 +566,8 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, } } lim_check_is_he_mcs_valid(session, beacon_struct); - lim_check_he_ldpc_cap(session, beacon_struct); lim_extract_he_op(session, beacon_struct); + lim_update_he_bw_cap_mcs(session, beacon_struct); /* Extract the UAPSD flag from WMM Parameter element */ if (beacon_struct->wmeEdcaPresent) *uapsd = beacon_struct->edcaParams.qosInfo.uapsd; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_reassoc_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_reassoc_utils.c index b020be0330b20bfa4aabe2a7588b1d13b74a8610..f5a20f05629dd095378f73b3b21f7bf6da85169f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_reassoc_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_reassoc_utils.c @@ -35,7 +35,6 @@ #include "lim_assoc_utils.h" #include "lim_security_utils.h" #include "lim_ser_des_utils.h" -#include "lim_sta_hash_api.h" #include "lim_admit_control.h" #include "lim_send_messages.h" #include "lim_ibss_peer_mgmt.h" @@ -64,7 +63,7 @@ void lim_update_re_assoc_globals(struct mac_context *mac, tpSirAssocRsp pAssocRs /* Update the current Bss Information */ qdf_mem_copy(pe_session->bssId, pe_session->limReAssocbssId, sizeof(tSirMacAddr)); - pe_session->currentOperChannel = pe_session->limReassocChannelId; + pe_session->curr_op_freq = pe_session->lim_reassoc_chan_freq; pe_session->htSecondaryChannelOffset = pe_session->reAssocHtSupportedChannelWidthSet; pe_session->htRecommendedTxWidthSet = @@ -164,14 +163,15 @@ void lim_handle_del_bss_in_re_assoc_context(struct mac_context *mac, */ assocRsp = (tpSirAssocRsp) pe_session->limAssocResponseData; - lim_update_assoc_sta_datas(mac, sta, assocRsp, - pe_session); - lim_update_re_assoc_globals(mac, assocRsp, pe_session); bss_desc = &pe_session->pLimReAssocReq->bssDescription; lim_extract_ap_capabilities(mac, - (uint8_t *) bss_desc->ieFields, + (uint8_t *)bss_desc->ieFields, lim_get_ielen_from_bss_description(bss_desc), beacon_struct); + lim_update_assoc_sta_datas(mac, sta, assocRsp, + pe_session, beacon_struct); + lim_update_re_assoc_globals(mac, assocRsp, pe_session); + if (mac->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) lim_decide_sta_protection_on_assoc(mac, @@ -204,8 +204,6 @@ void lim_handle_del_bss_in_re_assoc_context(struct mac_context *mac, qdf_mem_free(beacon_struct); goto error; } - qdf_mem_free(assocRsp->sha384_ft_subelem.gtk); - qdf_mem_free(assocRsp->sha384_ft_subelem.igtk); qdf_mem_free(assocRsp); qdf_mem_free(beacon_struct); pe_session->limAssocResponseData = NULL; @@ -285,9 +283,6 @@ void lim_handle_add_bss_in_re_assoc_context(struct mac_context *mac, */ assocRsp = (tpSirAssocRsp) pe_session->limAssocResponseData; - lim_update_assoc_sta_datas(mac, sta, assocRsp, - pe_session); - lim_update_re_assoc_globals(mac, assocRsp, pe_session); lim_extract_ap_capabilities(mac, (uint8_t *) pe_session-> pLimReAssocReq->bssDescription. @@ -297,6 +292,9 @@ void lim_handle_add_bss_in_re_assoc_context(struct mac_context *mac, pLimReAssocReq-> bssDescription), pBeaconStruct); + lim_update_assoc_sta_datas(mac, sta, assocRsp, + pe_session, pBeaconStruct); + lim_update_re_assoc_globals(mac, assocRsp, pe_session); if (mac->lim.gLimProtectionControl != MLME_FORCE_POLICY_PROTECTION_DISABLE) lim_decide_sta_protection_on_assoc(mac, @@ -331,8 +329,6 @@ void lim_handle_add_bss_in_re_assoc_context(struct mac_context *mac, qdf_mem_free(pBeaconStruct); goto Error; } - qdf_mem_free(assocRsp->sha384_ft_subelem.gtk); - qdf_mem_free(assocRsp->sha384_ft_subelem.igtk); qdf_mem_free(assocRsp); pe_session->limAssocResponseData = NULL; qdf_mem_free(pBeaconStruct); @@ -473,13 +469,7 @@ lim_restore_pre_reassoc_state(struct mac_context *mac, /* 'Change' timer for future activations */ lim_deactivate_and_change_timer(mac, eLIM_REASSOC_FAIL_TIMER); - lim_set_channel(mac, pe_session->currentOperChannel, - pe_session->ch_center_freq_seg0, - pe_session->ch_center_freq_seg1, - pe_session->ch_width, - pe_session->maxTxPower, - pe_session->peSessionId, - 0, 0); + lim_send_switch_chnl_params(mac, pe_session); /* @ToDo:Need to Integrate the STOP the Dataxfer to AP from 11H code */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_roam_timer_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_roam_timer_utils.c index ba27e85b49ac7082242ab400c2863e352d20329d..4f0d67471fbd7ba48ae3f088a88663a255c4caf6 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_roam_timer_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_roam_timer_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -43,7 +43,7 @@ uint32_t lim_create_timers_host_roam(struct mac_context *mac_ctx) mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout); /* Create Association failure timer and activate it later */ if (tx_timer_create(mac_ctx, - &mac_ctx->lim.limTimers.gLimReassocFailureTimer, + &mac_ctx->lim.lim_timers.gLimReassocFailureTimer, "REASSOC FAILURE TIMEOUT", lim_assoc_failure_timer_handler, LIM_REASSOC, cfg_value, 0, TX_NO_ACTIVATE) != TX_SUCCESS) { pe_err("failed to create Reassoc timer"); @@ -52,7 +52,7 @@ uint32_t lim_create_timers_host_roam(struct mac_context *mac_ctx) cfg_value = 1000; cfg_value = SYS_MS_TO_TICKS(cfg_value); if (tx_timer_create(mac_ctx, - &mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer, + &mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer, "FT PREAUTH RSP TIMEOUT", lim_timer_handler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT, cfg_value, 0, TX_NO_ACTIVATE) != TX_SUCCESS) { @@ -62,13 +62,13 @@ uint32_t lim_create_timers_host_roam(struct mac_context *mac_ctx) return TX_SUCCESS; err_roam_timer: - tx_timer_delete(&mac_ctx->lim.limTimers.gLimReassocFailureTimer); + tx_timer_delete(&mac_ctx->lim.lim_timers.gLimReassocFailureTimer); return TX_TIMER_ERROR; } void lim_delete_timers_host_roam(struct mac_context *mac_ctx) { - tLimTimers *lim_timer = &mac_ctx->lim.limTimers; + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; /* Delete Reassociation failure timer. */ tx_timer_delete(&lim_timer->gLimReassocFailureTimer); @@ -78,7 +78,7 @@ void lim_delete_timers_host_roam(struct mac_context *mac_ctx) void lim_deactivate_timers_host_roam(struct mac_context *mac_ctx) { - tLimTimers *lim_timer = &mac_ctx->lim.limTimers; + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; /* Deactivate Reassociation failure timer. */ tx_timer_deactivate(&lim_timer->gLimReassocFailureTimer); @@ -104,21 +104,21 @@ void lim_deactivate_and_change_timer_host_roam(struct mac_context *mac_ctx, switch (timer_id) { case eLIM_REASSOC_FAIL_TIMER: if (tx_timer_deactivate - (&mac_ctx->lim.limTimers.gLimReassocFailureTimer) != + (&mac_ctx->lim.lim_timers.gLimReassocFailureTimer) != TX_SUCCESS) pe_warn("unable to deactivate Reassoc fail timer"); val = SYS_MS_TO_TICKS( mac_ctx->mlme_cfg->timeouts.reassoc_failure_timeout); if (tx_timer_change - (&mac_ctx->lim.limTimers.gLimReassocFailureTimer, val, + (&mac_ctx->lim.lim_timers.gLimReassocFailureTimer, val, 0) != TX_SUCCESS) pe_warn("unable to change Reassoc fail timer"); break; case eLIM_FT_PREAUTH_RSP_TIMER: if (tx_timer_deactivate - (&mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer) != + (&mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer) != TX_SUCCESS) { pe_err("Unable to deactivate Preauth Fail timer"); return; @@ -126,7 +126,7 @@ void lim_deactivate_and_change_timer_host_roam(struct mac_context *mac_ctx, val = 1000; val = SYS_MS_TO_TICKS(val); if (tx_timer_change( - &mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer, + &mac_ctx->lim.lim_timers.gLimFTPreAuthRspTimer, val, 0) != TX_SUCCESS) { pe_err("Unable to change Join Failure timer"); return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_scan_result_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_scan_result_utils.c index 8b6480c14f27c04a1adb9ec413d13f26f0feceae..fc764388c4f596e0dd51fb7cabd587b3eb4369b2 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_scan_result_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_scan_result_utils.c @@ -69,8 +69,7 @@ lim_collect_bss_description(struct mac_context *mac, uint8_t *pBody; uint32_t ieLen = 0; tpSirMacMgmtHdr pHdr; - uint8_t channelNum; - uint8_t rxChannel; + uint32_t chan_freq; uint8_t rfBand = 0; pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo); @@ -82,7 +81,6 @@ lim_collect_bss_description(struct mac_context *mac, } ieLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; - rxChannel = WMA_GET_RX_CH(pRxPacketInfo); pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo); rfBand = WMA_GET_RX_RFBAND(pRxPacketInfo); @@ -116,7 +114,7 @@ lim_collect_bss_description(struct mac_context *mac, if (!pBssDescr->beaconInterval) { pe_warn("Beacon Interval is ZERO, making it to default 100 " - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(pHdr->bssId)); + QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(pHdr->bssId)); pBssDescr->beaconInterval = 100; } /* @@ -132,15 +130,12 @@ lim_collect_bss_description(struct mac_context *mac, * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. */ - pBssDescr->channelId = lim_get_channel_from_beacon(mac, pBPR); - - pBssDescr->channelIdSelf = pBssDescr->channelId; - pBssDescr->rx_channel = rxChannel; + chan_freq = lim_get_channel_from_beacon(mac, pBPR); + pBssDescr->chan_freq = chan_freq; /* set the network type in bss description */ - channelNum = pBssDescr->channelId; pBssDescr->nwType = - lim_get_nw_type(mac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); + lim_get_nw_type(mac, chan_freq, SIR_MAC_MGMT_FRAME, pBPR); /* Copy RSSI & SINR from BD */ pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); @@ -148,16 +143,17 @@ lim_collect_bss_description(struct mac_context *mac, /* SINR no longer reported by HW */ pBssDescr->sinr = 0; - pe_debug(QDF_MAC_ADDR_STR " rssi: normalized: %d, absolute: %d", - QDF_MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->rssi, + pe_debug(QDF_MAC_ADDR_FMT " rssi: normalized: %d, absolute: %d", + QDF_MAC_ADDR_REF(pHdr->bssId), pBssDescr->rssi, pBssDescr->rssi_raw); pBssDescr->received_time = (uint64_t)qdf_mc_timer_get_system_time(); pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo); pBssDescr->seq_ctrl = pHdr->seqControl; - pe_debug("Received %s from BSSID: %pM tsf_delta = %u Seq Num: %x ssid:%.*s, rssi: %d", - pBssDescr->fProbeRsp ? "Probe Rsp" : "Beacon", pHdr->bssId, + pe_debug("Received %s from BSSID: "QDF_MAC_ADDR_FMT" tsf_delta = %u Seq Num: %x ssid:%.*s, rssi: %d", + pBssDescr->fProbeRsp ? "Probe Rsp" : "Beacon", + QDF_MAC_ADDR_REF(pHdr->bssId), pBssDescr->tsf_delta, ((pHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET) | pHdr->seqControl.seqNumLo), pBPR->ssId.length, pBPR->ssId.ssId, pBssDescr->rssi_raw); @@ -194,7 +190,7 @@ lim_collect_bss_description(struct mac_context *mac, pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen); /*set channel number in beacon in case it is not present */ - pBPR->channelNumber = pBssDescr->channelId; + pBPR->chan_freq = chan_freq; mac->lim.beacon_probe_rsp_cnt_per_scan++; return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c index 56835a173cf5c7c25b7def6dbf3930da006d1eaa..96c94d69d74fb0a20bf88b290bcad22a6ca198b1 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -363,8 +363,9 @@ void lim_delete_pre_auth_node(struct mac_context *mac, tSirMacAddr macAddr) mac->lim.pLimPreAuthList = pTempNode->next; - pe_debug("fRelease data for %d peer %pM", - pTempNode->authNodeIdx, macAddr); + pe_debug("fRelease data for %d peer "QDF_MAC_ADDR_FMT, + pTempNode->authNodeIdx, + QDF_MAC_ADDR_REF(macAddr)); lim_release_pre_auth_node(mac, pTempNode); return; @@ -458,16 +459,16 @@ lim_restore_from_auth_state(struct mac_context *mac, tSirResultCodes resultCode, * host have received the auth rsp and no longer auth * retry is needed also cancel the auth rety timer */ - mac->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS; + mac->auth_ack_status = LIM_ACK_RCD_SUCCESS; /* Auth retry and AUth failure timers are not started for SAE */ /* 'Change' timer for future activations */ - if (tx_timer_running(&mac->lim.limTimers. + if (tx_timer_running(&mac->lim.lim_timers. g_lim_periodic_auth_retry_timer)) lim_deactivate_and_change_timer(mac, eLIM_AUTH_RETRY_TIMER); /* 'Change' timer for future activations */ - if (tx_timer_running(&mac->lim.limTimers.gLimAuthFailureTimer)) + if (tx_timer_running(&mac->lim.lim_timers.gLimAuthFailureTimer)) lim_deactivate_and_change_timer(mac, eLIM_AUTH_FAIL_TIMER); @@ -516,6 +517,14 @@ lim_encrypt_auth_frame(struct mac_context *mac, uint8_t keyId, uint8_t *pKey, SIR_MAC_AUTH_FRAME_INFO_LEN + SIR_MAC_CHALLENGE_ID_LEN; keyLength += 3; + /* + * Make sure that IV is non-zero, because few IOT APs fails to decrypt + * auth sequence 3 encrypted frames if initialization vector value is 0 + */ + qdf_get_random_bytes(seed, SIR_MAC_WEP_IV_LENGTH); + while (!(*(uint32_t *)seed)) + qdf_get_random_bytes(seed, SIR_MAC_WEP_IV_LENGTH); + /* Bytes 3-7 of seed is key */ qdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3); @@ -752,270 +761,3 @@ void lim_post_sme_set_keys_cnf(struct mac_context *mac, lim_post_sme_message(mac, LIM_MLM_SETKEYS_CNF, (uint32_t *) mlmSetKeysCnf); } - -/** - * lim_send_set_bss_key_req() - * - ***FUNCTION: - * This function is called from lim_process_mlm_set_keys_req(), - * when PE is trying to setup the Group Keys related - * to a specified encryption type - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac Pointer to Global MAC structure - * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer - * @return none - */ -void lim_send_set_bss_key_req(struct mac_context *mac, - tLimMlmSetKeysReq *pMlmSetKeysReq, - struct pe_session *pe_session) -{ - struct scheduler_msg msgQ = {0}; - tpSetBssKeyParams pSetBssKeyParams = NULL; - tLimMlmSetKeysCnf mlmSetKeysCnf; - QDF_STATUS retCode; - - if (pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) { - pe_debug("numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS", - pMlmSetKeysReq->numKeys); - - /* Respond to SME with error code */ - mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; - goto end; - } - /* Package WMA_SET_BSSKEY_REQ message parameters */ - - pSetBssKeyParams = qdf_mem_malloc(sizeof(tSetBssKeyParams)); - if (!pSetBssKeyParams) { - /* Respond to SME with error code */ - mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; - goto end; - } - - /* Update the WMA_SET_BSSKEY_REQ parameters */ - pSetBssKeyParams->bss_idx = pe_session->bss_idx; - pSetBssKeyParams->encType = pMlmSetKeysReq->edType; - - pSetBssKeyParams->singleTidRc = - (uint8_t)(mac->mlme_cfg->sta.single_tid); - /* Update PE session Id */ - pSetBssKeyParams->sessionId = pe_session->peSessionId; - - pSetBssKeyParams->smesessionId = pMlmSetKeysReq->smesessionId; - - if (pMlmSetKeysReq->key[0].keyId && - ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || - (pMlmSetKeysReq->edType == eSIR_ED_WEP104)) - ) { - /* IF the key id is non-zero and encryption type is WEP, Send all the 4 - * keys to HAL with filling the key at right index in pSetBssKeyParams->key. */ - pSetBssKeyParams->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; - qdf_mem_copy((uint8_t *) &pSetBssKeyParams-> - key[pMlmSetKeysReq->key[0].keyId], - (uint8_t *) &pMlmSetKeysReq->key[0], - sizeof(pMlmSetKeysReq->key[0])); - - } else { - pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys; - qdf_mem_copy((uint8_t *) &pSetBssKeyParams->key, - (uint8_t *) &pMlmSetKeysReq->key, - sizeof(tSirKeys) * pMlmSetKeysReq->numKeys); - } - - SET_LIM_PROCESS_DEFD_MESGS(mac, false); - msgQ.type = WMA_SET_BSSKEY_REQ; - msgQ.reserved = 0; - msgQ.bodyptr = pSetBssKeyParams; - msgQ.bodyval = 0; - - pe_debug("Sending WMA_SET_BSSKEY_REQ..."); - MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { - pe_err("Posting SET_BSSKEY to HAL failed, reason=%X", - retCode); - - /* Respond to SME with LIM_MLM_SETKEYS_CNF */ - mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; - qdf_mem_zero(pSetBssKeyParams, sizeof(tSetBssKeyParams)); - qdf_mem_free(pSetBssKeyParams); - } else - return; /* Continue after WMA_SET_BSSKEY_RSP... */ - -end: - lim_post_sme_set_keys_cnf(mac, pMlmSetKeysReq, &mlmSetKeysCnf); - -} - -/** - * @function : lim_send_set_sta_key_req() - * - * @brief : This function is called from lim_process_mlm_set_keys_req(), - * when PE is trying to setup the Unicast Keys related - * to a specified STA with specified encryption type - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac Pointer to Global MAC structure - * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer - * @param staIdx STA index for which the keys are being set - * @param defWEPIdx The default WEP key index [0..3] - * @return none - */ -void lim_send_set_sta_key_req(struct mac_context *mac, - tLimMlmSetKeysReq *pMlmSetKeysReq, - uint16_t staIdx, - uint8_t defWEPIdx, - struct pe_session *pe_session, bool sendRsp) -{ - struct scheduler_msg msgQ = {0}; - tpSetStaKeyParams pSetStaKeyParams = NULL; - tLimMlmSetKeysCnf mlmSetKeysCnf; - QDF_STATUS retCode; - - /* Package WMA_SET_STAKEY_REQ message parameters */ - pSetStaKeyParams = qdf_mem_malloc(sizeof(tSetStaKeyParams)); - if (!pSetStaKeyParams) - goto fail; - - /* Update the WMA_SET_STAKEY_REQ parameters */ - pSetStaKeyParams->staIdx = staIdx; - pSetStaKeyParams->encType = pMlmSetKeysReq->edType; - - pSetStaKeyParams->singleTidRc = - (uint8_t)(mac->mlme_cfg->sta.single_tid); - /* Update PE session ID */ - pSetStaKeyParams->sessionId = pe_session->peSessionId; - - /** - * For WEP - defWEPIdx indicates the default WEP - * Key to be used for TX - * For all others, there's just one key that can - * be used and hence it is assumed that - * defWEPIdx = 0 (from the caller) - */ - - pSetStaKeyParams->defWEPIdx = defWEPIdx; - - pSetStaKeyParams->smesessionId = pMlmSetKeysReq->smesessionId; - qdf_copy_macaddr(&pSetStaKeyParams->peer_macaddr, - &pMlmSetKeysReq->peer_macaddr); - - if (sendRsp == true) { - /** Store the Previous MlmState*/ - pe_session->limPrevMlmState = pe_session->limMlmState; - SET_LIM_PROCESS_DEFD_MESGS(mac, false); - } - - if (LIM_IS_IBSS_ROLE(pe_session) - && !pMlmSetKeysReq->key[0].unicast) { - if (sendRsp == true) - pe_session->limMlmState = - eLIM_MLM_WT_SET_STA_BCASTKEY_STATE; - msgQ.type = WMA_SET_STA_BCASTKEY_REQ; - } else { - if (sendRsp == true) - pe_session->limMlmState = - eLIM_MLM_WT_SET_STA_KEY_STATE; - msgQ.type = WMA_SET_STAKEY_REQ; - } - MTRACE(mac_trace - (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId, - pe_session->limMlmState)); - - /** - * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP - * the Key[0] contains the KEY, so just copy that alone, - * for the case of WEP_STATIC the hal gets the key from cfg - */ - switch (pMlmSetKeysReq->edType) { - case eSIR_ED_WEP40: - case eSIR_ED_WEP104: - /* FIXME! Is this OK? */ - if (0 == pMlmSetKeysReq->numKeys) { - uint32_t i; - - for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) { - qdf_mem_copy((uint8_t *) &pSetStaKeyParams-> - key[i], - (uint8_t *) &pMlmSetKeysReq-> - key[i], sizeof(tSirKeys)); - } - pe_session->limMlmState = - eLIM_MLM_WT_SET_STA_KEY_STATE; - MTRACE(mac_trace - (mac, TRACE_CODE_MLM_STATE, - pe_session->peSessionId, - pe_session->limMlmState)); - } else { - /*This case the keys are coming from upper layer so need to fill the - * key at the default wep key index and send to the HAL */ - if (defWEPIdx < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) { - qdf_mem_copy((uint8_t *) &pSetStaKeyParams-> - key[defWEPIdx], - (uint8_t *) &pMlmSetKeysReq-> - key[0], - sizeof(pMlmSetKeysReq->key[0])); - pMlmSetKeysReq->numKeys = - SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; - } else { - pe_err("Wrong Key Index %d", defWEPIdx); - goto free_sta_key; - } - } - break; - case eSIR_ED_TKIP: - case eSIR_ED_CCMP: - case eSIR_ED_GCMP: - case eSIR_ED_GCMP_256: -#ifdef FEATURE_WLAN_WAPI - case eSIR_ED_WPI: -#endif - { - qdf_mem_copy((uint8_t *) &pSetStaKeyParams->key, - (uint8_t *) &pMlmSetKeysReq->key[0], - sizeof(tSirKeys)); - } - break; - default: - break; - } - - pSetStaKeyParams->sendRsp = sendRsp; - - msgQ.reserved = 0; - msgQ.bodyptr = pSetStaKeyParams; - msgQ.bodyval = 0; - - pe_debug("Sending WMA_SET_STAKEY_REQ..."); - MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type)); - retCode = wma_post_ctrl_msg(mac, &msgQ); - if (QDF_STATUS_SUCCESS != retCode) { - pe_err("Posting SET_STAKEY to HAL failed, reason=%X", - retCode); - goto free_sta_key; - } else - return; /* Continue after WMA_SET_STAKEY_RSP... */ - -free_sta_key: - qdf_mem_zero(pSetStaKeyParams, sizeof(tSetStaKeyParams)); - qdf_mem_free(pSetStaKeyParams); -fail: - /* Respond to SME with LIM_MLM_SETKEYS_CNF */ - mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; - if (sendRsp == true) - lim_post_sme_set_keys_cnf(mac, pMlmSetKeysReq, &mlmSetKeysCnf); -} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.h index 43c93084bcb90dfdc8df13b2566c2e7739d8e005..620f3ecc5ba4990627516df30a651b51b065557b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015, 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -49,17 +49,20 @@ struct tLimPreAuthNode; -uint8_t lim_is_auth_algo_supported(struct mac_context *, tAniAuthType, struct pe_session *); +uint8_t lim_is_auth_algo_supported(struct mac_context *, tAniAuthType, + struct pe_session *); /* MAC based authentication related functions */ void lim_init_pre_auth_list(struct mac_context *); void lim_delete_pre_auth_list(struct mac_context *); -struct tLimPreAuthNode *lim_search_pre_auth_list(struct mac_context *, tSirMacAddr); +struct tLimPreAuthNode *lim_search_pre_auth_list(struct mac_context *, + tSirMacAddr); void lim_add_pre_auth_node(struct mac_context *, struct tLimPreAuthNode *); void lim_delete_pre_auth_node(struct mac_context *, tSirMacAddr); -void lim_release_pre_auth_node(struct mac_context *mac, tpLimPreAuthNode pAuthNode); +void lim_release_pre_auth_node(struct mac_context *mac, + tpLimPreAuthNode pAuthNode); void lim_restore_from_auth_state(struct mac_context *, - tSirResultCodes, uint16_t, struct pe_session *); + tSirResultCodes, uint16_t, struct pe_session *); uint8_t lim_delete_open_auth_pre_auth_node(struct mac_context *mac_ctx); /* Encryption/Decryption related functions */ @@ -67,12 +70,9 @@ void lim_compute_crc32(uint8_t *, uint8_t *, uint16_t); void lim_rc4(uint8_t *, uint8_t *, uint8_t *, uint32_t, uint16_t); void lim_encrypt_auth_frame(struct mac_context *, uint8_t, uint8_t *, uint8_t *, uint8_t *, uint32_t); -uint8_t lim_decrypt_auth_frame(struct mac_context *, uint8_t *, uint8_t *, uint8_t *, - uint32_t, uint16_t); +uint8_t lim_decrypt_auth_frame(struct mac_context *, uint8_t *, uint8_t *, + uint8_t *, uint32_t, uint16_t); -void lim_send_set_bss_key_req(struct mac_context *, tLimMlmSetKeysReq *, struct pe_session *); -void lim_send_set_sta_key_req(struct mac_context *, tLimMlmSetKeysReq *, uint16_t, uint8_t, - struct pe_session *, bool sendRsp); void lim_post_sme_set_keys_cnf(struct mac_context *, tLimMlmSetKeysReq *, tLimMlmSetKeysCnf *); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_frames_host_roam.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_frames_host_roam.c index e9b844a712386b9e1a40a74f14d29826da95cfef..a70245d746262897e5a16a7dee69e18246b4733c 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_frames_host_roam.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_frames_host_roam.c @@ -30,7 +30,6 @@ #include "lim_security_utils.h" #include "lim_prop_exts_utils.h" #include "dot11f.h" -#include "lim_sta_hash_api.h" #include "sch_api.h" #include "lim_send_messages.h" #include "lim_assoc_utils.h" @@ -81,7 +80,7 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, uint8_t *add_ie; const uint8_t *wps_ie = NULL; uint8_t tx_flag = 0; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; bool vht_enabled = false; tpSirMacMgmtHdr mac_hdr; tftSMEContext *ft_sme_context; @@ -89,7 +88,7 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, if (!pe_session) return; - sme_sessionid = pe_session->smeSessionId; + vdev_id = pe_session->vdev_id; /* check this early to avoid unncessary operation */ if (!pe_session->pLimReAssocReq) @@ -279,7 +278,7 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, #endif } - ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext; + ft_sme_context = &mac_ctx->roam.roamSession[vdev_id].ftSmeContext; if (pe_session->htCapability && mac_ctx->lim.htCapabilityPresentInBeacon) { populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps); @@ -317,6 +316,8 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac_ctx, pe_session, &frm->he_cap); + populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, + &frm->he_6ghz_band_cap); } status = dot11f_get_packed_re_assoc_request_size(mac_ctx, frm, @@ -371,9 +372,9 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, pe_debug("*** Sending Re-Assoc Request length: %d %d to", bytes, payload); - if (pe_session->assocReq) { - qdf_mem_free(pe_session->assocReq); - pe_session->assocReq = NULL; + if (pe_session->assoc_req) { + qdf_mem_free(pe_session->assoc_req); + pe_session->assoc_req = NULL; pe_session->assocReqLen = 0; } @@ -383,13 +384,13 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, payload += add_ie_len; } - pe_session->assocReq = qdf_mem_malloc(payload); - if (pe_session->assocReq) { + pe_session->assoc_req = qdf_mem_malloc(payload); + if (pe_session->assoc_req) { /* * Store the Assoc request. This is sent to csr/hdd in * join cnf response. */ - qdf_mem_copy(pe_session->assocReq, + qdf_mem_copy(pe_session->assoc_req, frame + sizeof(tSirMacMgmtHdr), payload); pe_session->assocReqLen = payload; } @@ -408,30 +409,31 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, (uint8_t *) frame, (bytes + ft_ies_length)); if ((pe_session->ftPEContext.pFTPreAuthReq) && - (BAND_5G == lim_get_rf_band( - pe_session->ftPEContext.pFTPreAuthReq->preAuthchannelNum))) + (!wlan_reg_is_24ghz_ch_freq( + pe_session->ftPEContext.pFTPreAuthReq->pre_auth_channel_freq))) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; - else if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + else if (wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; - if (pe_session->assocReq) { - qdf_mem_free(pe_session->assocReq); - pe_session->assocReq = NULL; + if (pe_session->assoc_req) { + qdf_mem_free(pe_session->assoc_req); + pe_session->assoc_req = NULL; pe_session->assocReqLen = 0; } if (ft_ies_length) { - pe_session->assocReq = qdf_mem_malloc(ft_ies_length); - if (!pe_session->assocReq) { + pe_session->assoc_req = qdf_mem_malloc(ft_ies_length); + if (!pe_session->assoc_req) { pe_session->assocReqLen = 0; } else { /* * Store the FT IEs. This is sent to csr/hdd in * join cnf response. */ - qdf_mem_copy(pe_session->assocReq, - ft_sme_context->reassoc_ft_ies, ft_ies_length); + qdf_mem_copy(pe_session->assoc_req, + ft_sme_context->reassoc_ft_ies, + ft_ies_length); pe_session->assocReqLen = ft_ies_length; } } else { @@ -448,7 +450,7 @@ void lim_send_reassoc_req_with_ft_ies_mgmt_frame(struct mac_context *mac_ctx, qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) (bytes + ft_ies_length), TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, - lim_tx_complete, frame, tx_flag, sme_sessionid, + lim_tx_complete, frame, tx_flag, vdev_id, 0, RATEID_DEFAULT); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, pe_session->peSessionId, qdf_status)); @@ -489,12 +491,12 @@ void lim_send_retry_reassoc_req_frame(struct mac_context *mac, } /* Prepare and send Reassociation request frame */ /* start reassoc timer. */ - mac->lim.limTimers.gLimReassocFailureTimer.sessionId = + mac->lim.lim_timers.gLimReassocFailureTimer.sessionId = pe_session->peSessionId; /* Start reassociation failure timer */ MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE, pe_session->peSessionId, eLIM_REASSOC_FAIL_TIMER)); - if (tx_timer_activate(&mac->lim.limTimers.gLimReassocFailureTimer) + if (tx_timer_activate(&mac->lim.lim_timers.gLimReassocFailureTimer) != TX_SUCCESS) { /* Could not start reassoc failure timer. */ /* Log error */ @@ -693,6 +695,8 @@ void lim_send_reassoc_req_mgmt_frame(struct mac_context *mac, pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac, pe_session, &frm->he_cap); + populate_dot11f_he_6ghz_cap(mac, pe_session, + &frm->he_6ghz_band_cap); } nStatus = @@ -741,9 +745,9 @@ void lim_send_reassoc_req_mgmt_frame(struct mac_context *mac, pe_debug("*** Sending Re-Association Request length: %d" "to", nBytes); - if (pe_session->assocReq) { - qdf_mem_free(pe_session->assocReq); - pe_session->assocReq = NULL; + if (pe_session->assoc_req) { + qdf_mem_free(pe_session->assoc_req); + pe_session->assoc_req = NULL; pe_session->assocReqLen = 0; } @@ -753,17 +757,17 @@ void lim_send_reassoc_req_mgmt_frame(struct mac_context *mac, nPayload += nAddIELen; } - pe_session->assocReq = qdf_mem_malloc(nPayload); - if (pe_session->assocReq) { + pe_session->assoc_req = qdf_mem_malloc(nPayload); + if (pe_session->assoc_req) { /* Store the Assocrequest. It is sent to csr in joincnfrsp */ - qdf_mem_copy(pe_session->assocReq, + qdf_mem_copy(pe_session->assoc_req, pFrame + sizeof(tSirMacMgmtHdr), nPayload); pe_session->assocReqLen = nPayload; } - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; if (pe_session->opmode == QDF_P2P_CLIENT_MODE || diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_management_frames.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_management_frames.c index 8e4c8353cffb5709bd9e1a39c75bf8ab2b060180..5f6e5d1d21ecd722a1039ca32e35d4e5cbab2efb 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,7 +34,6 @@ #include "lim_security_utils.h" #include "lim_prop_exts_utils.h" #include "dot11f.h" -#include "lim_sta_hash_api.h" #include "sch_api.h" #include "lim_send_messages.h" #include "lim_assoc_utils.h" @@ -50,12 +50,14 @@ #include "sme_trace.h" #include "rrm_api.h" #include "qdf_crypto.h" +#include "parser_api.h" #include "wma_types.h" #include #include #include "lim_process_fils.h" #include "wlan_utility.h" +#include /** * @@ -145,7 +147,7 @@ void lim_populate_mac_header(struct mac_context *mac_ctx, uint8_t *buf, * @mac_ctx: Pointer to Global MAC structure * @ssid: SSID to be sent in Probe Request frame * @bssid: BSSID to be sent in Probe Request frame - * @channel: Channel # on which the Probe Request is going out + * @chan_freq: Channel frequency on which the Probe Request is going out * @self_macaddr: self MAC address * @dot11mode: self dotllmode * @additional_ielen: if non-zero, include additional_ie in the Probe Request @@ -168,7 +170,7 @@ QDF_STATUS lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, tSirMacSSid *ssid, tSirMacAddr bssid, - uint8_t channel, + qdf_freq_t chan_freq, tSirMacAddr self_macaddr, uint32_t dot11mode, uint16_t *additional_ielen, @@ -183,7 +185,7 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, uint8_t sessionid; const uint8_t *p2pie = NULL; uint8_t txflag = 0; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; bool is_vht_enabled = false; uint8_t txPower; uint16_t addn_ielen = 0; @@ -191,17 +193,19 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, tDot11fIEExtCap extracted_ext_cap; QDF_STATUS sir_status; const uint8_t *qcn_ie = NULL; + uint8_t channel; if (additional_ielen) addn_ielen = *additional_ielen; + channel = wlan_reg_freq_to_chan(mac_ctx->pdev, chan_freq); /* * The probe req should not send 11ac capabilities if band is * 2.4GHz, unless gEnableVhtFor24GHzBand is enabled in INI. So * if gEnableVhtFor24GHzBand is false and dot11mode is 11ac * set it to 11n. */ - if (wlan_reg_is_24ghz_ch(channel) && + if (wlan_reg_is_24ghz_ch_freq(chan_freq) && !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && (MLME_DOT11_MODE_11AC == dot11mode || MLME_DOT11_MODE_11AC_ONLY == dot11mode)) @@ -220,7 +224,7 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid); if (pesession) - sme_sessionid = pesession->smeSessionId; + vdev_id = pesession->vdev_id; /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */ /* and then hand it off to 'dot11f_pack_probe_request' (for */ @@ -266,13 +270,14 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession); populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0); - if (pesession) { /* Include HT Capability IE */ - if (pesession->htCapability) + if (pesession->htCapability && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps); } else { /* !pesession */ - if (IS_DOT11_MODE_HT(dot11mode)) + if (IS_DOT11_MODE_HT(dot11mode) && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps); } @@ -280,7 +285,7 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, * Set channelbonding information as "disabled" when tunned to a * 2.4 GHz channel */ - if (channel <= SIR_11B_CHANNEL_END) { + if (wlan_reg_is_24ghz_ch_freq(chan_freq)) { if (mac_ctx->roam.configParam.channelBondingMode24GHz == PHY_SINGLE_CHANNEL_CENTERED) { pr.HTCaps.supportedChannelWidthSet = @@ -293,13 +298,15 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, } if (pesession) { /* Include VHT Capability IE */ - if (pesession->vhtCapability) { + if (pesession->vhtCapability && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { populate_dot11f_vht_caps(mac_ctx, pesession, &pr.VHTCaps); is_vht_enabled = true; } } else { - if (IS_DOT11_MODE_VHT(dot11mode)) { + if (IS_DOT11_MODE_VHT(dot11mode) && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { populate_dot11f_vht_caps(mac_ctx, pesession, &pr.VHTCaps); is_vht_enabled = true; @@ -313,6 +320,8 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, lim_update_session_he_capable(mac_ctx, pesession); populate_dot11f_he_caps(mac_ctx, pesession, &pr.he_cap); + populate_dot11f_he_6ghz_cap(mac_ctx, pesession, + &pr.he_6ghz_band_cap); if (addn_ielen && additional_ie) { qdf_mem_zero((uint8_t *)&extracted_ext_cap, @@ -401,15 +410,15 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, additional_ie, addn_ielen); payload += addn_ielen; } - pe_nofl_debug("Probe req TX: vdev %d seq num %d to " QDF_MAC_ADDR_STR " len %d", - sme_sessionid, mac_ctx->mgmtSeqNum, - QDF_MAC_ADDR_ARRAY(bssid), + pe_nofl_debug("Probe req TX: vdev %d seq num %d to " QDF_MAC_ADDR_FMT " len %d", + vdev_id, mac_ctx->mgmtSeqNum, + QDF_MAC_ADDR_REF(bssid), (int)sizeof(tSirMacMgmtHdr) + payload); /* If this probe request is sent during P2P Search State, then we need * to send it at OFDM rate. */ - if ((BAND_5G == lim_get_rf_band(channel)) || + if ((REG_BAND_5G == lim_get_rf_band(chan_freq)) || /* * For unicast probe req mgmt from Join function we don't set * above variables. So we need to add one more check whether it @@ -422,7 +431,7 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx, wma_tx_frame(mac_ctx, packet, (uint16_t) sizeof(tSirMacMgmtHdr) + payload, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, - lim_tx_complete, frame, txflag, sme_sessionid, + lim_tx_complete, frame, txflag, vdev_id, 0, RATEID_DEFAULT); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { pe_err("could not send Probe Request frame!"); @@ -575,7 +584,7 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, uint8_t total_noalen = 0; uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; bool is_vht_enabled = false; tDot11fIEExtCap extracted_ext_cap = {0}; bool extracted_ext_cap_flag = false; @@ -598,7 +607,7 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, FL("CAC timer is running, probe response dropped")); return; } - sme_sessionid = pe_session->smeSessionId; + vdev_id = pe_session->vdev_id; frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse)); if (!frm) return; @@ -626,9 +635,12 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID); populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL, &frm->SuppRates, pe_session); + populate_dot11f_tpc_report(mac_ctx, &frm->TPCReport, pe_session); - populate_dot11f_ds_params(mac_ctx, &frm->DSParams, - pe_session->currentOperChannel); + populate_dot11f_ds_params( + mac_ctx, &frm->DSParams, + wlan_reg_freq_to_chan(mac_ctx->pdev, + pe_session->curr_op_freq)); populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session); if (LIM_IS_AP_ROLE(pe_session)) { @@ -694,6 +706,8 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, &frm->he_cap); populate_dot11f_he_operation(mac_ctx, pe_session, &frm->he_op); + populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, + &frm->he_6ghz_band_cap); } populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap, @@ -839,9 +853,9 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, addn_ie_len, p2p_ie, noa_ie, total_noalen, noa_stream, noalen); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; /* Queue Probe Response frame in high priority WQ */ @@ -850,7 +864,7 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, tx_flag, - sme_sessionid, 0, RATEID_DEFAULT); + vdev_id, 0, RATEID_DEFAULT); /* Pkt will be freed up by the callback */ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) @@ -1047,9 +1061,9 @@ lim_send_addts_req_action_frame(struct mac_context *mac, pe_debug("Sending an Add TS Request frame to"); lim_print_mac_addr(mac, peerMacAddr, LOGD); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -1138,6 +1152,15 @@ static QDF_STATUS lim_assoc_rsp_tx_complete( goto end; } + if (tx_complete != WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { + lim_send_disassoc_mgmt_frame(mac_ctx, + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON, + sta_ds->staAddr, + session_entry, false); + lim_trigger_sta_deletion(mac_ctx, sta_ds, session_entry); + goto free_buffers; + } + lim_assoc_ind = qdf_mem_malloc(sizeof(tLimMlmAssocInd)); if (!lim_assoc_ind) { pe_err("lim assoc ind is NULL"); @@ -1145,7 +1168,7 @@ static QDF_STATUS lim_assoc_rsp_tx_complete( } if (!lim_fill_lim_assoc_ind_params(lim_assoc_ind, mac_ctx, sta_ds, session_entry)) { - pe_err("lim assoc ind fill error");; + pe_err("lim assoc ind fill error"); goto lim_assoc_ind; } @@ -1158,20 +1181,20 @@ static QDF_STATUS lim_assoc_rsp_tx_complete( lim_fill_sme_assoc_ind_params( mac_ctx, lim_assoc_ind, sme_assoc_ind, - session_entry); + session_entry, true); qdf_mem_zero(&msg, sizeof(struct scheduler_msg)); msg.type = eWNI_SME_ASSOC_IND_UPPER_LAYER; msg.bodyptr = sme_assoc_ind; msg.bodyval = 0; - sme_assoc_ind->staId = sta_ds->staIndex; sme_assoc_ind->reassocReq = sta_ds->mlmStaContext.subType; sme_assoc_ind->timingMeasCap = sta_ds->timingMeasCap; - - mac_ctx->lim.sme_msg_callback(mac_ctx, &msg); + MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId, msg.type)); + lim_sys_process_mmh_msg_api(mac_ctx, &msg); qdf_mem_free(lim_assoc_ind); +free_buffers: if (assoc_req->assocReqFrame) { qdf_mem_free(assoc_req->assocReqFrame); assoc_req->assocReqFrame = NULL; @@ -1269,7 +1292,7 @@ lim_send_assoc_rsp_mgmt_frame( assoc_req = (tpSirAssocReq) pe_session->parsedAssocReq[sta->assocId]; /* - * populate P2P IE in AssocRsp when assocReq from the peer + * populate P2P IE in AssocRsp when assoc_req from the peer * includes P2P IE */ if (assoc_req && assoc_req->addIEPresent) @@ -1313,7 +1336,7 @@ lim_send_assoc_rsp_mgmt_frame( frm.HTCaps.shortGI40MHz = 0; populate_dot11f_ht_info(mac_ctx, &frm.HTInfo, - pe_session); + pe_session); } pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x", frm.HTCaps.supportedChannelWidthSet, @@ -1331,6 +1354,22 @@ lim_send_assoc_rsp_mgmt_frame( populate_dot11f_vht_operation(mac_ctx, pe_session, &frm.VHTOperation); is_vht = true; + } else if (sta->mlmStaContext.force_1x1 && + frm.HTCaps.present) { + /* + * WAR: In P2P GO mode, if the P2P client device + * is only HT capable and not VHT capable, but the P2P + * GO device is VHT capable and advertises 2x2 NSS with + * HT capablity client device, which results in IOT + * issues. + * When GO is operating in DBS mode, GO beacons + * advertise 2x2 capability but include OMN IE to + * indicate current operating mode of 1x1. But here + * peer device is only HT capable and will not + * understand OMN IE. + */ + frm.HTInfo.basicMCSSet[1] = 0; + frm.HTCaps.supportedMCSSet[1] = 0; } if (pe_session->vhtCapability && @@ -1360,6 +1399,8 @@ lim_send_assoc_rsp_mgmt_frame( &frm.he_cap); populate_dot11f_he_operation(mac_ctx, pe_session, &frm.he_op); + populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, + &frm.he_6ghz_band_cap); } #ifdef WLAN_FEATURE_11W if (eSIR_MAC_TRY_AGAIN_LATER == status_code) { @@ -1399,7 +1440,7 @@ lim_send_assoc_rsp_mgmt_frame( */ populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session); - beacon_params.bss_idx = pe_session->bss_idx; + beacon_params.bss_idx = pe_session->vdev_id; /* Send message to HAL about beacon parameter change. */ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) @@ -1498,8 +1539,9 @@ lim_send_assoc_rsp_mgmt_frame( status); } - pe_nofl_debug("Assoc rsp TX: vdev %d subtype %d to %pM seq num %d status %d aid %d", - pe_session->vdev_id, subtype, mac_hdr->da, + pe_nofl_debug("Assoc rsp TX: vdev %d subtype %d to "QDF_MAC_ADDR_FMT" seq num %d status %d aid %d", + pe_session->vdev_id, subtype, + QDF_MAC_ADDR_REF(mac_hdr->da), mac_ctx->mgmtSeqNum, status_code, aid); if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN) @@ -1512,10 +1554,9 @@ lim_send_assoc_rsp_mgmt_frame( sta->mlmStaContext.owe_ie, sta->mlmStaContext.owe_ie_len); - if ((BAND_5G == - lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -1670,9 +1711,9 @@ lim_send_delts_req_action_frame(struct mac_context *mac, pe_debug("Sending DELTS REQ (size %d) to ", nBytes); lim_print_mac_addr(mac, pMacHdr->da, LOGD); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -1714,15 +1755,22 @@ static QDF_STATUS lim_assoc_tx_complete_cnf(void *context, pe_nofl_info("Assoc req TX: %s", (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? - "success" : "fail"); + "success" : "fail"); if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { assoc_ack_status = ACKED; reason_code = QDF_STATUS_SUCCESS; - } else { + mac_ctx->assoc_ack_status = LIM_ACK_RCD_SUCCESS; + } else if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK) { assoc_ack_status = NOT_ACKED; reason_code = QDF_STATUS_E_FAILURE; + mac_ctx->assoc_ack_status = LIM_ACK_RCD_FAILURE; + } else { + assoc_ack_status = SENT_FAIL; + reason_code = QDF_STATUS_E_FAILURE; + mac_ctx->assoc_ack_status = LIM_TX_FAILED; } + if (buf) qdf_nbuf_free(buf); @@ -1841,7 +1889,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, const uint8_t *wps_ie = NULL; uint8_t power_caps = false; uint8_t tx_flag = 0; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; bool vht_enabled = false; tDot11fIEExtCap extr_ext_cap; bool extr_ext_flag = true, is_open_auth = false; @@ -1855,7 +1903,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, enum rateid min_rid = RATEID_DEFAULT; uint8_t *mbo_ie = NULL, *adaptive_11r_ie = NULL, *vendor_ies = NULL; uint8_t mbo_ie_len = 0, adaptive_11r_ie_len = 0, rsnx_ie_len = 0; - struct wlan_objmgr_peer *peer; + bool bss_mfp_capable; if (!pe_session) { pe_err("pe_session is NULL"); @@ -1863,7 +1911,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, return; } - sme_sessionid = pe_session->smeSessionId; + vdev_id = pe_session->vdev_id; /* check this early to avoid unncessary operation */ if (!pe_session->lim_join_req) { @@ -1872,11 +1920,28 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, return; } add_ie_len = pe_session->lim_join_req->addIEAssoc.length; - add_ie = pe_session->lim_join_req->addIEAssoc.addIEdata; + if (add_ie_len) { + add_ie = qdf_mem_malloc(add_ie_len); + if (!add_ie) { + qdf_mem_free(mlm_assoc_req); + return; + } else { + /* + * copy the additional ie to local, as this func modify + * the IE, these IE will be required in assoc/re-assoc + * retry. So do not modify the original IE. + */ + qdf_mem_copy(add_ie, pe_session->lim_join_req->addIEAssoc.addIEdata, + add_ie_len); + } + } else { + add_ie = NULL; + } frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest)); if (!frm) { qdf_mem_free(mlm_assoc_req); + qdf_mem_free(add_ie); return; } qdf_mem_zero((uint8_t *) frm, sizeof(tDot11fAssocRequest)); @@ -2065,9 +2130,13 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac_ctx, pe_session, &frm->he_cap); + populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, + &frm->he_6ghz_band_cap); } else if (pe_session->he_with_wep_tkip) { pe_debug("Populate HE IEs in Assoc Request with WEP/TKIP"); populate_dot11f_he_caps(mac_ctx, NULL, &frm->he_cap); + populate_dot11f_he_6ghz_cap(mac_ctx, pe_session, + &frm->he_6ghz_band_cap); } if (pe_session->lim_join_req->is11Rconnection) { @@ -2138,6 +2207,8 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap, false); } + + populate_dot11f_btm_caps(mac_ctx, pe_session, &frm->ExtCap); /* * TWT extended capabilities should be populated after the * intersection of beacon caps and self caps is done because @@ -2207,18 +2278,14 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, mbo_ie_len, is_open_auth); if (!is_open_auth) { - peer = wlan_objmgr_get_peer_by_mac( - mac_ctx->psoc, - mlm_assoc_req->peerMacAddr, - WLAN_MBO_ID); - if (peer && !mlme_get_peer_pmf_status(peer)) { + bss_mfp_capable = + lim_get_vdev_rmf_capable(mac_ctx, pe_session); + if (!bss_mfp_capable) { pe_debug("Peer doesn't support PMF, Don't add MBO IE"); qdf_mem_free(mbo_ie); mbo_ie = NULL; mbo_ie_len = 0; } - if (peer) - wlan_objmgr_peer_release_ref(peer, WLAN_MBO_ID); } } @@ -2345,9 +2412,9 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, adaptive_11r_ie, adaptive_11r_ie_len); payload = payload + adaptive_11r_ie_len; - if (pe_session->assocReq) { - qdf_mem_free(pe_session->assocReq); - pe_session->assocReq = NULL; + if (pe_session->assoc_req) { + qdf_mem_free(pe_session->assoc_req); + pe_session->assoc_req = NULL; pe_session->assocReqLen = 0; } @@ -2360,20 +2427,20 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, } } - pe_session->assocReq = qdf_mem_malloc(payload); - if (pe_session->assocReq) { + pe_session->assoc_req = qdf_mem_malloc(payload); + if (pe_session->assoc_req) { /* * Store the Assoc request. This is sent to csr/hdd in * join cnf response. */ - qdf_mem_copy(pe_session->assocReq, + qdf_mem_copy(pe_session->assoc_req, frame + sizeof(tSirMacMgmtHdr), payload); pe_session->assocReqLen = payload; } - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; if (pe_session->opmode == QDF_P2P_CLIENT_MODE || @@ -2384,8 +2451,9 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, pe_session->peSessionId, mac_hdr->fc.subType)); - pe_nofl_info("Assoc req TX: vdev %d to %pM seq num %d", pe_session->vdev_id, - pe_session->bssId, mac_ctx->mgmtSeqNum); + pe_nofl_rl_info("Assoc req TX: vdev %d to "QDF_MAC_ADDR_FMT" seq num %d", pe_session->vdev_id, + QDF_MAC_ADDR_REF(pe_session->bssId), + mac_ctx->mgmtSeqNum); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame, (uint16_t)(sizeof(tSirMacMgmtHdr) + payload)); @@ -2399,7 +2467,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, (uint16_t) (sizeof(tSirMacMgmtHdr) + payload), TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, lim_assoc_tx_complete_cnf, - tx_flag, sme_sessionid, false, 0, min_rid); + tx_flag, vdev_id, false, 0, min_rid); MTRACE(qdf_trace (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, pe_session->peSessionId, qdf_status)); @@ -2407,6 +2475,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { pe_err("Failed to send Association Request (%X)!", qdf_status); + mac_ctx->assoc_ack_status = LIM_TX_FAILED; lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT, pe_session, SENT_FAIL, QDF_STATUS_E_FAILURE); /* Pkt will be freed up by the callback */ @@ -2420,6 +2489,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx, /* Free up buffer allocated for mlm_assoc_req */ qdf_mem_free(adaptive_11r_ie); qdf_mem_free(mlm_assoc_req); + qdf_mem_free(add_ie); mlm_assoc_req = NULL; qdf_mem_free(frm); return; @@ -2443,12 +2513,10 @@ static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context, tSirMacMgmtHdr *mac_hdr; tDot11faddba_rsp rsp; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - uint8_t peer_id; - void *peer; uint32_t frame_len; QDF_STATUS status; uint8_t *data; + struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)params; if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) pe_debug("Add ba response successfully sent"); @@ -2480,15 +2548,8 @@ static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context, goto error; } - peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->da, &peer_id, - PEER_DEBUG_ID_WMA_ADDBA_REQ); - if (!peer) { - pe_debug("no PEER found for mac_addr:%pM", mac_hdr->da); - goto error; - } - cdp_addba_resp_tx_completion(soc, peer, rsp.addba_param_set.tid, - tx_complete); - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_ADDBA_REQ); + cdp_addba_resp_tx_completion(soc, mac_hdr->da, mgmt_params->vdev_id, + rsp.addba_param_set.tid, tx_complete); error: if (buf) qdf_nbuf_free(buf); @@ -2496,6 +2557,37 @@ static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context, return QDF_STATUS_SUCCESS; } +#define SAE_AUTH_ALGO_LEN 2 +#define SAE_AUTH_ALGO_OFFSET 0 +static bool lim_is_ack_for_sae_auth(qdf_nbuf_t buf) +{ + tpSirMacMgmtHdr mac_hdr; + uint16_t *sae_auth, min_len; + + if (!buf) { + pe_debug("buf is NULL"); + return false; + } + + min_len = sizeof(tSirMacMgmtHdr) + SAE_AUTH_ALGO_LEN; + if (qdf_nbuf_len(buf) < min_len) { + pe_debug("buf_len %d less than min_len %d", + (uint32_t)qdf_nbuf_len(buf), min_len); + return false; + } + + mac_hdr = (tpSirMacMgmtHdr)(qdf_nbuf_data(buf)); + if (mac_hdr->fc.subType == SIR_MAC_MGMT_AUTH) { + sae_auth = (uint16_t *)((uint8_t *)mac_hdr + + sizeof(tSirMacMgmtHdr)); + if (sae_auth[SAE_AUTH_ALGO_OFFSET] == + eSIR_AUTH_TYPE_SAE) + return true; + } + + return false; +} + /** * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air * @context: pointer to global mac @@ -2505,7 +2597,6 @@ static QDF_STATUS lim_addba_rsp_tx_complete_cnf(void *context, * * Return: This returns QDF_STATUS */ - static QDF_STATUS lim_auth_tx_complete_cnf(void *context, qdf_nbuf_t buf, uint32_t tx_complete, @@ -2514,20 +2605,31 @@ static QDF_STATUS lim_auth_tx_complete_cnf(void *context, struct mac_context *mac_ctx = (struct mac_context *)context; uint16_t auth_ack_status; uint16_t reason_code; + bool sae_auth_acked; - pe_nofl_info("Auth TX: %s", - (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? - "success" : "fail"); + pe_nofl_rl_info("Auth TX: %s", + (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? + "success" : "fail"); if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) { - mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS; + mac_ctx->auth_ack_status = LIM_ACK_RCD_SUCCESS; auth_ack_status = ACKED; reason_code = QDF_STATUS_SUCCESS; - /* 'Change' timer for future activations */ - lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); - } else { - mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE; + sae_auth_acked = lim_is_ack_for_sae_auth(buf); + /* + * 'Change' timer for future activations only if ack + * received is not for WPA SAE auth frames. + */ + if (!sae_auth_acked) + lim_deactivate_and_change_timer(mac_ctx, + eLIM_AUTH_RETRY_TIMER); + } else if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK) { + mac_ctx->auth_ack_status = LIM_ACK_RCD_FAILURE; auth_ack_status = NOT_ACKED; reason_code = QDF_STATUS_E_FAILURE; + } else { + mac_ctx->auth_ack_status = LIM_TX_FAILED; + auth_ack_status = SENT_FAIL; + reason_code = QDF_STATUS_E_FAILURE; } if (buf) @@ -2566,7 +2668,7 @@ lim_send_auth_mgmt_frame(struct mac_context *mac_ctx, void *packet; QDF_STATUS qdf_status, status; uint8_t tx_flag = 0; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; uint16_t ft_ies_length = 0; bool challenge_req = false; enum rateid min_rid = RATEID_DEFAULT; @@ -2577,7 +2679,7 @@ lim_send_auth_mgmt_frame(struct mac_context *mac_ctx, return; } - sme_sessionid = session->smeSessionId; + vdev_id = session->vdev_id; if (wep_challenge_len) { /* @@ -2814,20 +2916,20 @@ lim_send_auth_mgmt_frame(struct mac_context *mac_ctx, } } - pe_nofl_info("Auth TX: seq %d seq num %d status %d WEP %d to " QDF_MAC_ADDR_STR, + pe_nofl_info("Auth TX: seq %d seq num %d status %d WEP %d to " QDF_MAC_ADDR_FMT, auth_frame->authTransactionSeqNumber, mac_ctx->mgmtSeqNum, auth_frame->authStatusCode, mac_hdr->fc.wep, - QDF_MAC_ADDR_ARRAY(mac_hdr->da)); + QDF_MAC_ADDR_REF(mac_hdr->da)); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, frame, frame_len); if ((session->ftPEContext.pFTPreAuthReq) && - (BAND_5G == lim_get_rf_band( - session->ftPEContext.pFTPreAuthReq->preAuthchannelNum))) + (!wlan_reg_is_24ghz_ch_freq( + session->ftPEContext.pFTPreAuthReq->pre_auth_channel_freq))) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; - else if ((BAND_5G == lim_get_rf_band(session->currentOperChannel)) || - (session->opmode == QDF_P2P_CLIENT_MODE) || - (session->opmode == QDF_P2P_GO_MODE)) + else if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || + session->opmode == QDF_P2P_CLIENT_MODE || + session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; if (session->opmode == QDF_P2P_CLIENT_MODE || @@ -2837,28 +2939,28 @@ lim_send_auth_mgmt_frame(struct mac_context *mac_ctx, MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, session->peSessionId, mac_hdr->fc.subType)); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; + mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; min_rid = lim_get_min_session_txrate(session); lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr, session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); if (session->ftPEContext.pFTPreAuthReq) - ch_freq_tx_frame = cds_chan_to_freq( - session->ftPEContext.pFTPreAuthReq->preAuthchannelNum); + ch_freq_tx_frame = session->ftPEContext. + pFTPreAuthReq->pre_auth_channel_freq; qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, (uint16_t)frame_len, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, lim_auth_tx_complete_cnf, - tx_flag, sme_sessionid, false, + tx_flag, vdev_id, false, ch_freq_tx_frame, min_rid); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, session->peSessionId, qdf_status)); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { pe_err("*** Could not send Auth frame, retCode=%X ***", qdf_status); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE; + mac_ctx->auth_ack_status = LIM_TX_FAILED; lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT, session, SENT_FAIL, QDF_STATUS_E_FAILURE); /* Pkt will be freed up by the callback */ @@ -2877,7 +2979,7 @@ QDF_STATUS lim_send_deauth_cnf(struct mac_context *mac_ctx) deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; if (deauth_req) { if (tx_timer_running( - &mac_ctx->lim.limTimers.gLimDeauthAckTimer)) + &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) lim_deactivate_and_change_timer(mac_ctx, eLIM_DEAUTH_ACK_TIMER); @@ -2983,7 +3085,7 @@ QDF_STATUS lim_send_disassoc_cnf(struct mac_context *mac_ctx) disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; if (disassoc_req) { if (tx_timer_running( - &mac_ctx->lim.limTimers.gLimDisassocAckTimer)) + &mac_ctx->lim.lim_timers.gLimDisassocAckTimer)) lim_deactivate_and_change_timer(mac_ctx, eLIM_DISASSOC_ACK_TIMER); @@ -3103,6 +3205,10 @@ static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context, struct mac_context *mac_ctx = (struct mac_context *)context; QDF_STATUS status_code; struct scheduler_msg msg = {0}; + tLimMlmDeauthReq *deauth_req; + struct pe_session *session = NULL; + + deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; pe_debug("tx_complete = %s tx_success = %d", (tx_success == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ? @@ -3110,6 +3216,22 @@ static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context, if (buf) qdf_nbuf_free(buf); + if (deauth_req) + session = pe_find_session_by_session_id(mac_ctx, + deauth_req->sessionId); + if (tx_success != WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK && session && + session->deauth_retry.retry_cnt) { + if (tx_timer_running( + &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) + lim_deactivate_and_change_timer(mac_ctx, + eLIM_DEAUTH_ACK_TIMER); + lim_send_deauth_mgmt_frame(mac_ctx, + session->deauth_retry.reason_code, + session->deauth_retry.peer_macaddr.bytes, + session, true); + session->deauth_retry.retry_cnt--; + return QDF_STATUS_SUCCESS; + } msg.type = (uint16_t) WMA_DEAUTH_TX_COMP; msg.bodyptr = params; msg.bodyval = tx_success; @@ -3259,14 +3381,14 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac, &nPayload, discon_ie); mlme_free_self_disconnect_ies(pe_session->vdev); - pe_nofl_info("Disassoc TX: vdev %d seq %d reason %u and waitForAck %d to " QDF_MAC_ADDR_STR " From " QDF_MAC_ADDR_STR, + pe_nofl_info("Disassoc TX: vdev %d seq %d reason %u and waitForAck %d to " QDF_MAC_ADDR_FMT " From " QDF_MAC_ADDR_FMT, pe_session->vdev_id, mac->mgmtSeqNum, nReason, waitForAck, - QDF_MAC_ADDR_ARRAY(pMacHdr->da), - QDF_MAC_ADDR_ARRAY(pe_session->self_mac_addr)); + QDF_MAC_ADDR_REF(pMacHdr->da), + QDF_MAC_ADDR_REF(pe_session->self_mac_addr)); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; @@ -3291,15 +3413,21 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac, (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, pe_session->peSessionId, qdf_status)); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + pe_err("Failed to send disassoc frame"); + lim_send_disassoc_cnf(mac); + return; + } + val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); if (tx_timer_change - (&mac->lim.limTimers.gLimDisassocAckTimer, val, 0) + (&mac->lim.lim_timers.gLimDisassocAckTimer, val, 0) != TX_SUCCESS) { pe_err("Unable to change Disassoc ack Timer val"); return; } else if (TX_SUCCESS != - tx_timer_activate(&mac->lim.limTimers. + tx_timer_activate(&mac->lim.lim_timers. gLimDisassocAckTimer)) { pe_err("Unable to activate Disassoc ack Timer"); lim_deactivate_and_change_timer(mac, @@ -3447,14 +3575,14 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, &nPayload, discon_ie); mlme_free_self_disconnect_ies(pe_session->vdev); - pe_nofl_info("Deauth TX: vdev %d seq_num %d reason %u waitForAck %d to " QDF_MAC_ADDR_STR " from " QDF_MAC_ADDR_STR, - pe_session->vdev_id, mac->mgmtSeqNum, nReason, waitForAck, - QDF_MAC_ADDR_ARRAY(pMacHdr->da), - QDF_MAC_ADDR_ARRAY(pe_session->self_mac_addr)); + pe_nofl_rl_info("Deauth TX: vdev %d seq_num %d reason %u waitForAck %d to " QDF_MAC_ADDR_FMT " from " QDF_MAC_ADDR_FMT, + pe_session->vdev_id, mac->mgmtSeqNum, nReason, + waitForAck, QDF_MAC_ADDR_REF(pMacHdr->da), + QDF_MAC_ADDR_REF(pe_session->self_mac_addr)); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; @@ -3471,6 +3599,15 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, lim_diag_mgmt_tx_event_report(mac, pMacHdr, pe_session, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); + if (pe_session->opmode == QDF_STA_MODE && + mac->mlme_cfg->sta.deauth_retry_cnt && + !pe_session->deauth_retry.retry_cnt) { + pe_session->deauth_retry.retry_cnt = + mac->mlme_cfg->sta.deauth_retry_cnt; + pe_session->deauth_retry.reason_code = nReason; + qdf_mem_copy(pe_session->deauth_retry.peer_macaddr.bytes, + peer, QDF_MAC_ADDR_SIZE); + } /* Queue Disassociation frame in high priority WQ */ qdf_status = wma_tx_frameWithTxComplete(mac, pPacket, (uint16_t) nBytes, @@ -3497,12 +3634,12 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); if (tx_timer_change - (&mac->lim.limTimers.gLimDeauthAckTimer, val, 0) + (&mac->lim.lim_timers.gLimDeauthAckTimer, val, 0) != TX_SUCCESS) { pe_err("Unable to change Deauth ack Timer val"); return; } else if (TX_SUCCESS != - tx_timer_activate(&mac->lim.limTimers. + tx_timer_activate(&mac->lim.lim_timers. gLimDeauthAckTimer)) { pe_err("Unable to activate Deauth ack Timer"); lim_deactivate_and_change_timer(mac, @@ -3886,9 +4023,9 @@ lim_send_channel_switch_mgmt_frame(struct mac_context *mac, nStatus); } - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -3938,7 +4075,7 @@ lim_send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, void *packet; QDF_STATUS qdf_status; uint8_t txFlag = 0; - uint8_t sme_session_id = 0; + uint8_t vdev_id = 0; uint8_t ch_spacing; tLimWiderBWChannelSwitchInfo *wide_bw_ie; @@ -3947,7 +4084,7 @@ lim_send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } - sme_session_id = session_entry->smeSessionId; + vdev_id = session_entry->smeSessionId; qdf_mem_zero(&frm, sizeof(frm)); @@ -4025,13 +4162,13 @@ lim_send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, status); } - if ((BAND_5G == lim_get_rf_band(session_entry->currentOperChannel)) || - (session_entry->opmode == QDF_P2P_CLIENT_MODE) || - (session_entry->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq) || + session_entry->opmode == QDF_P2P_CLIENT_MODE || + session_entry->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; - pe_debug("ECSA frame to :"QDF_MAC_ADDR_STR" count %d mode %d chan %d op class %d", - QDF_MAC_ADDR_ARRAY(mac_hdr->da), + pe_debug("ECSA frame to :"QDF_MAC_ADDR_FMT" count %d mode %d chan %d op class %d", + QDF_MAC_ADDR_REF(mac_hdr->da), frm.ext_chan_switch_ann_action.switch_count, frm.ext_chan_switch_ann_action.switch_mode, frm.ext_chan_switch_ann_action.new_channel, @@ -4044,7 +4181,7 @@ lim_send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, - txFlag, sme_session_id, 0, + txFlag, vdev_id, 0, RATEID_DEFAULT); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, session_entry->peSessionId, qdf_status)); @@ -4105,14 +4242,14 @@ lim_p2p_oper_chan_change_confirm_action_frame(struct mac_context *mac_ctx, void *packet; QDF_STATUS qdf_status; uint8_t tx_flag = 0; - uint8_t sme_session_id = 0; + uint8_t vdev_id = 0; if (!session_entry) { pe_err("Session entry is NULL!!!"); return QDF_STATUS_E_FAILURE; } - sme_session_id = session_entry->smeSessionId; + vdev_id = session_entry->smeSessionId; qdf_mem_zero(&frm, sizeof(frm)); @@ -4177,15 +4314,14 @@ lim_p2p_oper_chan_change_confirm_action_frame(struct mac_context *mac_ctx, status); } - if ((BAND_5G == - lim_get_rf_band(session_entry->currentOperChannel)) || - (session_entry->opmode == QDF_P2P_CLIENT_MODE) || - (session_entry->opmode == QDF_P2P_GO_MODE)) { + if (!wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq) || + session_entry->opmode == QDF_P2P_CLIENT_MODE || + session_entry->opmode == QDF_P2P_GO_MODE) { tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; } - pe_debug("Send frame on channel %d to mac " - QDF_MAC_ADDR_STR, session_entry->currentOperChannel, - QDF_MAC_ADDR_ARRAY(peer)); + pe_debug("Send frame on channel freq %d to mac " + QDF_MAC_ADDR_FMT, session_entry->curr_op_freq, + QDF_MAC_ADDR_REF(peer)); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, session_entry->peSessionId, mac_hdr->fc.subType)); @@ -4195,7 +4331,7 @@ lim_p2p_oper_chan_change_confirm_action_frame(struct mac_context *mac_ctx, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, lim_oper_chan_change_confirm_tx_complete_cnf, - tx_flag, sme_session_id, false, 0, RATEID_DEFAULT); + tx_flag, vdev_id, false, 0, RATEID_DEFAULT); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, session_entry->peSessionId, qdf_status)); @@ -4313,9 +4449,9 @@ lim_send_neighbor_report_request_frame(struct mac_context *mac, pe_debug("Sending a Neighbor Report Request to"); lim_print_mac_addr(mac, peer, LOGD); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -4438,11 +4574,12 @@ lim_send_link_report_action_frame(struct mac_context *mac, nStatus); } - pe_warn("RRM: Sending Link Report to %pM on vdev[%d]", peer, vdev_id); + pe_warn("RRM: Sending Link Report to "QDF_MAC_ADDR_FMT" on vdev[%d]", + QDF_MAC_ADDR_REF(peer), vdev_id); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -4503,6 +4640,7 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac, smeSessionId = pe_session->smeSessionId; + frm->Category.category = ACTION_CATEGORY_RRM; frm->Action.action = RRM_RADIO_MEASURE_RPT; frm->DialogToken.token = dialog_token; @@ -4606,22 +4744,18 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac, nStatus); } - pe_debug("Sending Radio Measure Report to %pM", peer); - if (frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE) - pe_nofl_info("TX: [802.11 BCN_RPT] seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d", - (pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET | - pMacHdr->seqControl.seqNumLo), - dialog_token, frm->num_MeasurementReport, - is_last_report); - else - pe_nofl_info("TX: [802.11 RRM] seq_no:%d dialog_token %d num_report %d is_last_frm %d", - (pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET | - pMacHdr->seqControl.seqNumLo), - dialog_token, num_report, is_last_frame); - - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) || - (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) + pe_nofl_info("TX: %s seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d num_report: %d peer:"QDF_MAC_ADDR_FMT, + frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE ? + "[802.11 BCN_RPT]" : "[802.11 RRM]", + (pMacHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET | + pMacHdr->seqControl.seqNumLo), + dialog_token, frm->num_MeasurementReport, + is_last_report, num_report, + QDF_MAC_ADDR_REF(peer)); + + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -4634,7 +4768,7 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac, pe_session->peSessionId, qdf_status)); if (QDF_STATUS_SUCCESS != qdf_status) { pe_nofl_err("TX: [802.11 RRM] Send FAILED! err_status [%d]", - qdf_status); + qdf_status); status_code = QDF_STATUS_E_FAILURE; /* Pkt will be freed up by the callback */ } @@ -4687,7 +4821,7 @@ QDF_STATUS lim_send_sa_query_request_frame(struct mac_context *mac, uint8_t *tra /* 11w action field is : action: 0 --> SA Query Request action frame action: 1 --> SA Query Response action frame */ - frm.Action.action = SIR_MAC_SA_QUERY_REQ; + frm.Action.action = SA_QUERY_REQUEST; /* 11w SA Query Request transId */ qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2); @@ -4748,12 +4882,9 @@ QDF_STATUS lim_send_sa_query_request_frame(struct mac_context *mac, uint8_t *tra pe_debug("Sending an SA Query Request from "); lim_print_mac_addr(mac, pe_session->self_mac_addr, LOGD); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) -#ifdef WLAN_FEATURE_P2P - || (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE) -#endif - ) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; smeSessionId = pe_session->smeSessionId; @@ -4819,7 +4950,7 @@ QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, /*11w action field is : action: 0 --> SA query request action frame action: 1 --> SA query response action frame */ - frm.Action.action = SIR_MAC_SA_QUERY_RSP; + frm.Action.action = SA_QUERY_RESPONSE; /*11w SA query response transId is same as SA query request transId */ qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2); @@ -4879,12 +5010,9 @@ QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, pe_debug("Sending a SA Query Response to"); lim_print_mac_addr(mac, peer, LOGD); - if ((BAND_5G == lim_get_rf_band(pe_session->currentOperChannel)) -#ifdef WLAN_FEATURE_P2P - || (pe_session->opmode == QDF_P2P_CLIENT_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE) -#endif - ) + if (!wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) || + pe_session->opmode == QDF_P2P_CLIENT_MODE || + pe_session->opmode == QDF_P2P_GO_MODE) txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -4913,7 +5041,8 @@ QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, } /* End lim_send_sa_query_response_frame */ #endif -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) #ifdef WLAN_FEATURE_11AX #define IS_PE_SESSION_HE_MODE(_session) ((_session)->he_capable) #else @@ -4936,35 +5065,21 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, void *pkt_ptr = NULL; QDF_STATUS qdf_status; uint8_t tx_flag = 0; - uint8_t sme_sessionid = 0; + uint8_t vdev_id = 0; uint16_t buff_size, status_code, batimeout; - uint8_t peer_id, dialog_token; + uint8_t dialog_token; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer, *pdev; uint8_t he_frag = 0; tpDphHashNode sta_ds; uint16_t aid; bool he_cap = false; - sme_sessionid = session->smeSessionId; - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - pe_err("pdev is NULL"); - return QDF_STATUS_E_FAILURE; - } - - peer = cdp_peer_get_ref_by_addr(soc, pdev, peer_mac, &peer_id, - PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP); - if (!peer) { - pe_err("PEER [%pM] not found", peer_mac); - return QDF_STATUS_E_FAILURE; - } + vdev_id = session->vdev_id; - cdp_addba_responsesetup(soc, peer, tid, &dialog_token, - &status_code, &buff_size, &batimeout); + cdp_addba_responsesetup(soc, peer_mac, vdev_id, tid, + &dialog_token, &status_code, &buff_size, + &batimeout); - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP); qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); frm.Category.category = ACTION_CATEGORY_BACK; frm.Action.action = ADDBA_RESPONSE; @@ -5010,8 +5125,8 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, /* Enable RX AMSDU only in HE mode if supported */ if (mac_ctx->is_usr_cfg_amsdu_enabled && ((IS_PE_SESSION_HE_MODE(session) && - WLAN_REG_IS_24GHZ_CH(session->currentOperChannel)) || - WLAN_REG_IS_5GHZ_CH(session->currentOperChannel))) + WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq)) || + !WLAN_REG_IS_24GHZ_CH_FREQ(session->curr_op_freq))) frm.addba_param_set.amsdu_supp = amsdu_support; else frm.addba_param_set.amsdu_supp = 0; @@ -5031,11 +5146,13 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, } } - pe_debug("Sending a ADDBA Response from %pM to %pM", - session->self_mac_addr, peer_mac); - pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d", - tid, frm.DialogToken.token, frm.Status.status, - frm.addba_param_set.buff_size); + pe_debug("Sending a ADDBA Response from "QDF_MAC_ADDR_FMT" to "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(session->self_mac_addr), + QDF_MAC_ADDR_REF(peer_mac)); + pe_debug("tid %d dialog_token %d status %d buff_size %d amsdu_supp %d", + tid, frm.DialogToken.token, frm.Status.status, + frm.addba_param_set.buff_size, + frm.addba_param_set.amsdu_supp); pe_debug("addba_extn %d he_capable %d no_frag %d he_frag %d", addba_extn_present, lim_is_session_he_capable(session), @@ -5094,12 +5211,9 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, } - if ((BAND_5G == lim_get_rf_band(session->currentOperChannel)) -#ifdef WLAN_FEATURE_P2P - || (session->opmode == QDF_P2P_CLIENT_MODE) || - (session->opmode == QDF_P2P_GO_MODE) -#endif - ) + if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) || + session->opmode == QDF_P2P_CLIENT_MODE || + session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT, @@ -5110,7 +5224,7 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, ANI_TXDIR_TODS, 7, NULL, frame_ptr, lim_addba_rsp_tx_complete_cnf, - tx_flag, sme_sessionid, + tx_flag, vdev_id, false, 0, RATEID_DEFAULT); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, session->peSessionId, qdf_status)); @@ -5130,7 +5244,7 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx, /** * lim_delba_tx_complete_cnf() - Confirmation for Delba OTA * @context: pointer to global mac - * @buf: buffer which is nothing but entire Del BA frame + * @buf: netbuf of Del BA frame * @tx_complete : Sent status * @params; tx completion params * @@ -5145,24 +5259,18 @@ static QDF_STATUS lim_delba_tx_complete_cnf(void *context, tSirMacMgmtHdr *mac_hdr; struct sDot11fdelba_req frm; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *peer, *pdev; - uint8_t peer_id; uint32_t frame_len; QDF_STATUS status; uint8_t *data; + struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)params; - if (!mac_ctx || !buf || !soc) { + if (!mgmt_params || !mac_ctx || !buf || !soc) { pe_err("delba tx cnf invalid parameters"); goto error; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - pe_err("delba pdev is NULL"); - goto error; - } data = qdf_nbuf_data(buf); if (!data) { - pe_err("delba frame is NULL"); + pe_err("Delba frame is NULL"); goto error; } @@ -5177,18 +5285,12 @@ static QDF_STATUS lim_delba_tx_complete_cnf(void *context, status, frame_len); goto error; } - peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->da, &peer_id, - PEER_DEBUG_ID_WMA_DELBA_REQ); - if (!peer) { - pe_err("delba PEER [%pM] not found", mac_hdr->da); - goto error; - } - - pe_debug("delba ota done to %pM tid %d status %d", - mac_hdr->da, frm.delba_param_set.tid, tx_complete); - cdp_delba_tx_completion(soc, peer, frm.delba_param_set.tid, - tx_complete); - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ); + pe_debug("delba ota done vdev %d "QDF_MAC_ADDR_FMT" tid %d desc_id %d status %d", + mgmt_params->vdev_id, + QDF_MAC_ADDR_REF(mac_hdr->da), frm.delba_param_set.tid, + mgmt_params->desc_id, tx_complete); + cdp_delba_tx_completion(soc, mac_hdr->da, mgmt_params->vdev_id, + frm.delba_param_set.tid, tx_complete); error: if (buf) @@ -5211,13 +5313,13 @@ QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx, uint8_t *frame_ptr; uint8_t tx_flag = 0; - session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { pe_debug("delba invalid vdev id %d ", vdev_id); return QDF_STATUS_E_INVAL; } - pe_debug("send delba vdev %d %pM tid %d reason %d", vdev_id, - peer_macaddr, tid, reason_code); + pe_debug("send delba vdev %d "QDF_MAC_ADDR_FMT" tid %d reason %d", vdev_id, + QDF_MAC_ADDR_REF(peer_macaddr), tid, reason_code); qdf_mem_zero((uint8_t *)&frm, sizeof(frm)); frm.Category.category = ACTION_CATEGORY_BACK; frm.Action.action = DELBA; @@ -5262,15 +5364,16 @@ QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx, frame_ptr + sizeof(tSirMacMgmtHdr), payload_size, &payload_size); if (DOT11F_FAILED(status)) { - pe_err("Failed to pack a DELBA Response (0x%08x)", + pe_err("Failed to pack a DELBA (0x%08x)", status); qdf_status = QDF_STATUS_E_FAILURE; goto error_delba; } else if (DOT11F_WARNED(status)) { - pe_warn("There were warnings while packing DELBA Response (0x%08x)", + pe_warn("There were warnings while packing DELBA (0x%08x)", status); } - if (BAND_5G == lim_get_rf_band(session->currentOperChannel) || + if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq) || + wlan_reg_is_6ghz_chan_freq(session->curr_op_freq) || session->opmode == QDF_P2P_CLIENT_MODE || session->opmode == QDF_P2P_GO_MODE) tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; @@ -5298,40 +5401,38 @@ QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx, return qdf_status; } +#define WLAN_SAE_AUTH_TIMEOUT 1000 + /** * lim_tx_mgmt_frame() - Transmits Auth mgmt frame * @mac_ctx Pointer to Global MAC structure - * @mb_msg: Received message info + * @vdev_id: vdev id * @msg_len: Received message length * @packet: Packet to be transmitted * @frame: Received frame * * Return: None */ -static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, - struct sir_mgmt_msg *mb_msg, uint32_t msg_len, - void *packet, uint8_t *frame) +static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, uint8_t vdev_id, + uint32_t msg_len, void *packet, uint8_t *frame) { - tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data; QDF_STATUS qdf_status; - uint8_t sme_session_id = 0; struct pe_session *session; uint16_t auth_ack_status; enum rateid min_rid = RATEID_DEFAULT; - sme_session_id = mb_msg->session_id; - session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id); + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { cds_packet_free((void *)packet); - pe_err("session not found for given sme session %d", - sme_session_id); + pe_err("session not found for given vdev_id %d", + vdev_id); return; } qdf_mtrace(QDF_MODULE_ID_PE, QDF_MODULE_ID_WMA, TRACE_CODE_TX_MGMT, session->peSessionId, 0); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; + mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; min_rid = lim_get_min_session_txrate(session); qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet, @@ -5339,13 +5440,12 @@ static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, lim_auth_tx_complete_cnf, - 0, sme_session_id, false, 0, min_rid); + 0, vdev_id, false, 0, min_rid); MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, session->peSessionId, qdf_status)); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - pe_err("*** Could not send Auth frame (subType: %d), retCode=%X ***", - fc->subType, qdf_status); - mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE; + pe_err("Could not send Auth frame, retCode=%X", qdf_status); + mac_ctx->auth_ack_status = LIM_TX_FAILED; auth_ack_status = SENT_FAIL; lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT, session, auth_ack_status, QDF_STATUS_E_FAILURE); @@ -5353,35 +5453,112 @@ static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, } } -void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx, - struct scheduler_msg *msg) +static void +lim_handle_sae_auth_retry(struct mac_context *mac_ctx, uint8_t vdev_id, + uint8_t *frame, uint32_t frame_len) +{ + struct pe_session *session; + struct sae_auth_retry *sae_retry; + uint8_t retry_count = 0; + + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); + if (!session) { + pe_err("session not found for given vdev_id %d", + vdev_id); + return; + } + if (session->opmode != QDF_STA_MODE) + return; + + if (session->limMlmState == eLIM_MLM_WT_SAE_AUTH_STATE) + wlan_mlme_get_sae_auth_retry_count(mac_ctx->psoc, &retry_count); + else + wlan_mlme_get_sae_roam_auth_retry_count(mac_ctx->psoc, + &retry_count); + if (!retry_count) { + pe_debug("vdev %d: SAE Auth retry disabled", vdev_id); + return; + } + + sae_retry = mlme_get_sae_auth_retry(session->vdev); + if (!sae_retry) { + pe_err("sae retry pointer is NULL for vdev_id %d", + vdev_id); + return; + } + + if (sae_retry->sae_auth.data) + lim_sae_auth_cleanup_retry(mac_ctx, vdev_id); + + sae_retry->sae_auth.data = qdf_mem_malloc(frame_len); + if (!sae_retry->sae_auth.data) { + pe_err("failed to alloc memory for sae auth"); + return; + } + + pe_debug("SAE auth frame queued vdev_id %d seq_num %d", + vdev_id, mac_ctx->mgmtSeqNum); + qdf_mem_copy(sae_retry->sae_auth.data, frame, frame_len); + mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId = + session->peSessionId; + sae_retry->sae_auth.len = frame_len; + sae_retry->sae_auth_max_retry = retry_count; + + tx_timer_change( + &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer, + SYS_MS_TO_TICKS(WLAN_SAE_AUTH_TIMEOUT), 0); + /* Activate Auth Retry timer */ + if (tx_timer_activate( + &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) != + TX_SUCCESS) { + pe_err("failed to start periodic auth retry timer"); + lim_sae_auth_cleanup_retry(mac_ctx, vdev_id); + } +} + +void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf, + uint16_t buf_len) { - struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr; - uint32_t msg_len; - tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data; - uint8_t sme_session_id; QDF_STATUS qdf_status; uint8_t *frame; void *packet; - tpSirMacMgmtHdr mac_hdr; + tpSirMacFrameCtl fc = (tpSirMacFrameCtl)buf; + tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)buf; - msg_len = mb_msg->msg_len - sizeof(*mb_msg); pe_debug("sending fc->type: %d fc->subType: %d", - fc->type, fc->subType); - - sme_session_id = mb_msg->session_id; - mac_hdr = (tpSirMacMgmtHdr)mb_msg->data; + fc->type, fc->subType); lim_add_mgmt_seq_num(mac_ctx, mac_hdr); - - qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame, - (void **)&packet); + qdf_status = cds_packet_alloc(buf_len, (void **)&frame, + (void **)&packet); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { pe_err("call to bufAlloc failed for AUTH frame"); return; } - qdf_mem_copy(frame, mb_msg->data, msg_len); + qdf_mem_copy(frame, buf, buf_len); + lim_tx_mgmt_frame(mac_ctx, vdev_id, buf_len, packet, frame); +} + +void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx, + struct scheduler_msg *msg) +{ + struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr; + uint32_t msg_len; + tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data; + uint8_t vdev_id; + uint16_t auth_algo; + + msg_len = mb_msg->msg_len - sizeof(*mb_msg); + vdev_id = mb_msg->vdev_id; + + if (fc->subType == SIR_MAC_MGMT_AUTH) { + auth_algo = *(uint16_t *)(mb_msg->data + + sizeof(tSirMacMgmtHdr)); + if (auth_algo == eSIR_AUTH_TYPE_SAE) + lim_handle_sae_auth_retry(mac_ctx, vdev_id, + mb_msg->data, msg_len); + } - lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame); + lim_send_frame(mac_ctx, vdev_id, mb_msg->data, msg_len); } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.c index 470a9090f7b94b0e35ce4991426096a3fdea23eb..5b7c3a96832a583189c073e32abbeb830ebb13e3 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.c @@ -34,6 +34,8 @@ #include "host_diag_core_log.h" #endif /* FEATURE_WLAN_DIAG_SUPPORT */ #include "lim_utils.h" +#include "wma.h" +#include "../../core/src/vdev_mgr_ops.h" /** * lim_send_beacon_params() - updates bcn params to WMA @@ -75,7 +77,7 @@ QDF_STATUS lim_send_beacon_params(struct mac_context *mac, pe_session->peSessionId, msgQ.type)); } - pBcnParams->smeSessionId = pe_session->smeSessionId; + pBcnParams->vdev_id = pe_session->vdev_id; retCode = wma_post_ctrl_msg(mac, &msgQ); if (QDF_STATUS_SUCCESS != retCode) { qdf_mem_free(pBcnParams); @@ -86,144 +88,68 @@ QDF_STATUS lim_send_beacon_params(struct mac_context *mac, return retCode; } -/** - * lim_send_switch_chnl_params() - * - ***FUNCTION: - * This function is called to send Channel Switch Indication to WMA - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac pointer to Global Mac structure. - * @param chnlNumber New Channel Number to be switched to. - * @param ch_width an enum for channel width. - * @param localPowerConstraint 11h local power constraint value - * - * @return success if message send is ok, else false. - */ QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac, - uint8_t chnlNumber, - uint8_t ch_center_freq_seg0, - uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width, - int8_t maxTxPower, - uint8_t peSessionId, - uint8_t is_restart, - uint32_t cac_duration_ms, - uint32_t dfs_regdomain) + struct pe_session *session) { - tpSwitchChannelParams pChnlParams = NULL; - struct scheduler_msg msgQ = {0}; - struct pe_session *pe_session; + struct vdev_mlme_obj *mlme_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct vdev_start_response rsp = {0}; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - pe_session = pe_find_session_by_session_id(mac, peSessionId); - if (!pe_session) { - pe_err("Unable to get Session for session Id %d", - peSessionId); + if (!wma) { + pe_err("Invalid wma handle"); return QDF_STATUS_E_FAILURE; } - pChnlParams = qdf_mem_malloc(sizeof(tSwitchChannelParams)); - if (!pChnlParams) - return QDF_STATUS_E_NOMEM; - pChnlParams->channelNumber = chnlNumber; - pChnlParams->ch_center_freq_seg0 = ch_center_freq_seg0; - pChnlParams->ch_center_freq_seg1 = ch_center_freq_seg1; - pChnlParams->ch_width = ch_width; - qdf_mem_copy(pChnlParams->selfStaMacAddr, pe_session->self_mac_addr, - sizeof(tSirMacAddr)); - pChnlParams->maxTxPower = maxTxPower; - qdf_mem_copy(pChnlParams->bssId, pe_session->bssId, - sizeof(tSirMacAddr)); - pChnlParams->peSessionId = peSessionId; - pChnlParams->vhtCapable = pe_session->vhtCapability; - if (lim_is_session_he_capable(pe_session)) - lim_update_chan_he_capable(mac, pChnlParams); - pChnlParams->dot11_mode = pe_session->dot11mode; - pChnlParams->nss = pe_session->nss; - - /*Set DFS flag for DFS channel */ - if (ch_width == CH_WIDTH_160MHZ) { - pChnlParams->isDfsChannel = true; - } else if (ch_width == CH_WIDTH_80P80MHZ) { - pChnlParams->isDfsChannel = false; - if (wlan_reg_get_channel_state(mac->pdev, chnlNumber) == - CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac->pdev, - pChnlParams->ch_center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS) - pChnlParams->isDfsChannel = true; - } else { - if (wlan_reg_get_channel_state(mac->pdev, chnlNumber) == - CHANNEL_STATE_DFS) - pChnlParams->isDfsChannel = true; - else - pChnlParams->isDfsChannel = false; + if (!session) { + pe_err("session is NULL"); + return QDF_STATUS_E_FAILURE; } + if (!session->vdev) { + pe_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session->vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + status = lim_pre_vdev_start(mac, mlme_obj, session); + if (QDF_IS_STATUS_ERROR(status)) + goto send_resp; - pChnlParams->restart_on_chan_switch = is_restart; - pChnlParams->cac_duration_ms = cac_duration_ms; - pChnlParams->dfs_regdomain = dfs_regdomain; - pChnlParams->reduced_beacon_interval = - mac->sap.SapDfsInfo.reduced_beacon_interval; - - if (cds_is_5_mhz_enabled()) - pChnlParams->ch_width = CH_WIDTH_5MHZ; - else if (cds_is_10_mhz_enabled()) - pChnlParams->ch_width = CH_WIDTH_10MHZ; + session->ch_switch_in_progress = true; /* we need to defer the message until we * get the response back from WMA */ SET_LIM_PROCESS_DEFD_MESGS(mac, false); - msgQ.type = WMA_CHNL_SWITCH_REQ; - msgQ.reserved = 0; - msgQ.bodyptr = pChnlParams; - msgQ.bodyval = 0; - pe_debug("Sending CH_SWITCH_REQ, ch_width %d, ch_num %d, maxTxPower %d", - pChnlParams->ch_width, - pChnlParams->channelNumber, pChnlParams->maxTxPower); - MTRACE(mac_trace_msg_tx(mac, peSessionId, msgQ.type)); - if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(mac, &msgQ)) { - qdf_mem_free(pChnlParams); - pe_err("Posting CH_SWITCH_REQ to WMA failed"); - return QDF_STATUS_E_FAILURE; + + status = wma_pre_chan_switch_setup(session->vdev_id); + if (status != QDF_STATUS_SUCCESS) { + pe_err("failed status = %d", status); + goto send_resp; } - pe_session->ch_switch_in_progress = true; + status = vdev_mgr_start_send(mlme_obj, + mlme_is_chan_switch_in_progress(session->vdev)); + if (status != QDF_STATUS_SUCCESS) { + pe_err("failed status = %d", status); + goto send_resp; + } + wma_post_chan_switch_setup(session->vdev_id); + + return QDF_STATUS_SUCCESS; +send_resp: + rsp.status = status; + rsp.vdev_id = session->vdev_id; + + wma_handle_channel_switch_resp(wma, &rsp); return QDF_STATUS_SUCCESS; } -/** - * lim_send_edca_params() - * - ***FUNCTION: - * This function is called to send dynamically changing EDCA Parameters to WMA. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac pointer to Global Mac structure. - * @param tpUpdatedEdcaParams pointer to the structure which contains - * dynamically changing EDCA parameters. - * @param highPerformance If the peer is Airgo (taurus) then switch to highPerformance is true. - * - * @return success if message send is ok, else false. - */ QDF_STATUS lim_send_edca_params(struct mac_context *mac, - tSirMacEdcaParamRecord *pUpdatedEdcaParams, - uint16_t bss_idx, bool mu_edca) + tSirMacEdcaParamRecord *pUpdatedEdcaParams, + uint16_t vdev_id, bool mu_edca) { tEdcaParams *pEdcaParams = NULL; QDF_STATUS retCode = QDF_STATUS_SUCCESS; @@ -232,7 +158,7 @@ QDF_STATUS lim_send_edca_params(struct mac_context *mac, pEdcaParams = qdf_mem_malloc(sizeof(tEdcaParams)); if (!pEdcaParams) return QDF_STATUS_E_NOMEM; - pEdcaParams->bss_idx = bss_idx; + pEdcaParams->vdev_id = vdev_id; pEdcaParams->acbe = pUpdatedEdcaParams[QCA_WLAN_AC_BE]; pEdcaParams->acbk = pUpdatedEdcaParams[QCA_WLAN_AC_BK]; pEdcaParams->acvi = pUpdatedEdcaParams[QCA_WLAN_AC_VI]; @@ -351,49 +277,6 @@ void lim_set_active_edca_params(struct mac_context *mac_ctx, return; } -/** --------------------------------------------------------- - \fn lim_set_link_state - \brief LIM sends a message to WMA to set the link state - \param struct mac_context * mac - \param tSirLinkState state - \return None - -----------------------------------------------------------*/ -QDF_STATUS lim_set_link_state(struct mac_context *mac, tSirLinkState state, - tSirMacAddr bssId, tSirMacAddr self_mac_addr, - tpSetLinkStateCallback callback, - void *callbackArg) -{ - struct scheduler_msg msgQ = {0}; - QDF_STATUS retCode; - tpLinkStateParams pLinkStateParams = NULL; - /* Allocate memory. */ - pLinkStateParams = qdf_mem_malloc(sizeof(tLinkStateParams)); - if (!pLinkStateParams) - return QDF_STATUS_E_NOMEM; - pLinkStateParams->state = state; - pLinkStateParams->callback = callback; - pLinkStateParams->callbackArg = callbackArg; - - /* Copy Mac address */ - sir_copy_mac_addr(pLinkStateParams->bssid, bssId); - sir_copy_mac_addr(pLinkStateParams->self_mac_addr, self_mac_addr); - - msgQ.type = WMA_SET_LINK_STATE; - msgQ.reserved = 0; - msgQ.bodyptr = pLinkStateParams; - msgQ.bodyval = 0; - - MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type)); - - retCode = (uint32_t) wma_post_ctrl_msg(mac, &msgQ); - if (retCode != QDF_STATUS_SUCCESS) { - qdf_mem_free(pLinkStateParams); - pe_err("Posting link state %d failed, reason = %x", state, - retCode); - } - return retCode; -} - QDF_STATUS lim_send_mode_update(struct mac_context *mac, tUpdateVHTOpMode *pTempParam, struct pe_session *pe_session) @@ -411,8 +294,8 @@ QDF_STATUS lim_send_mode_update(struct mac_context *mac, msgQ.reserved = 0; msgQ.bodyptr = pVhtOpMode; msgQ.bodyval = 0; - pe_debug("Sending WMA_UPDATE_OP_MODE, op_mode %d, sta_id %d", - pVhtOpMode->opMode, pVhtOpMode->staId); + pe_debug("Sending WMA_UPDATE_OP_MODE, op_mode %d", + pVhtOpMode->opMode); if (!pe_session) MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type)); else @@ -591,17 +474,16 @@ QDF_STATUS lim_send_ht40_obss_scanind(struct mac_context *mac_ctx, { QDF_STATUS ret = QDF_STATUS_SUCCESS; struct obss_ht40_scanind *ht40_obss_scanind; - uint32_t channelnum; + uint32_t channelnum, chan_freq; struct scheduler_msg msg = {0}; - uint8_t chan_list[CFG_VALID_CHANNEL_LIST_LEN]; uint8_t channel24gnum, count; ht40_obss_scanind = qdf_mem_malloc(sizeof(struct obss_ht40_scanind)); if (!ht40_obss_scanind) return QDF_STATUS_E_FAILURE; QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, - "OBSS Scan Indication bss_idx- %d staId %d", - session->bss_idx, session->staId); + "OBSS Scan Indication bssid " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(session->bssId)); ht40_obss_scanind->cmd = HT40_OBSS_SCAN_PARAM_START; ht40_obss_scanind->scan_type = eSIR_ACTIVE_SCAN; @@ -622,26 +504,26 @@ QDF_STATUS lim_send_ht40_obss_scanind(struct mac_context *mac_ctx, ht40_obss_scanind->current_operatingclass = wlan_reg_dmn_get_opclass_from_channel( mac_ctx->scan.countryCodeCurrent, - session->currentOperChannel, + wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq), session->ch_width); channelnum = mac_ctx->mlme_cfg->reg.valid_channel_list_num; - qdf_mem_copy(chan_list, mac_ctx->mlme_cfg->reg.valid_channel_list, - channelnum); + /* Extract 24G channel list */ channel24gnum = 0; for (count = 0; count < channelnum && (channel24gnum < SIR_ROAM_MAX_CHANNELS); count++) { - if ((chan_list[count] > CHAN_ENUM_1) && - (chan_list[count] < CHAN_ENUM_14)) { - ht40_obss_scanind->channels[channel24gnum] = - chan_list[count]; + chan_freq = + mac_ctx->mlme_cfg->reg.valid_channel_freq_list[count]; + if (wlan_reg_is_24ghz_ch_freq(chan_freq)) { + ht40_obss_scanind->chan_freq_list[channel24gnum] = + chan_freq; channel24gnum++; } } ht40_obss_scanind->channel_count = channel24gnum; /* FW API requests BSS IDX */ - ht40_obss_scanind->self_sta_idx = session->staId; - ht40_obss_scanind->bss_id = session->bss_idx; + ht40_obss_scanind->bss_id = session->vdev_id; ht40_obss_scanind->fortymhz_intolerent = 0; ht40_obss_scanind->iefield_len = 0; msg.type = WMA_HT40_OBSS_SCAN_IND; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.h index 5284229536d3ac6a6f4f1c10d37985f659703dba..f114208e1ade22e857397d042417abffc36f7135 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_messages.h @@ -52,25 +52,29 @@ QDF_STATUS lim_set_membership(struct mac_context *mac, QDF_STATUS lim_set_user_pos(struct mac_context *mac, tUpdateUserPos *pTempParam, struct pe_session *pe_session); + +/** + * lim_send_switch_chnl_params() - change channel + * @mac: pointer to Global MAC structure + * @session: pe session + * + * Return: QDF_STATUS + */ QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac, - uint8_t chnlNumber, - uint8_t ch_center_freq_seg0, - uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width, - int8_t maxTxPower, - uint8_t peSessionId, - uint8_t is_restart, - uint32_t cac_duration_ms, - uint32_t dfs_regdomain); + struct pe_session *session); +/** + * lim_send_edca_params() - Send edsa params to firmware + * @mac: pointer to Global MAC structure + * @pUpdatedEdcaParams: updated edca params + * @vdev_id: vdev id + * @mu_edca: MU edca + * + * Return: QDF_STATUS + */ QDF_STATUS lim_send_edca_params(struct mac_context *mac, - tSirMacEdcaParamRecord *pUpdatedEdcaParams, - uint16_t bss_idx, bool mu_edca); -QDF_STATUS lim_set_link_state(struct mac_context *mac, tSirLinkState state, - tSirMacAddr bssId, tSirMacAddr selfMac, - tpSetLinkStateCallback callback, - void *callbackArg); - + tSirMacEdcaParamRecord *pUpdatedEdcaParams, + uint16_t vdev_id, bool mu_edca); /** * lim_set_active_edca_params() - Choose best EDCA parameters * @mac_ctx: pointer to Global Mac structure. diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 80746f51af9ecf371025d7486be1ee7381b4f213..4f10d98bd2f6d706c66132ba06a22f826bd0737e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -57,7 +57,7 @@ #include "wma.h" void lim_send_sme_rsp(struct mac_context *mac_ctx, uint16_t msg_type, - tSirResultCodes result_code, uint8_t sme_session_id) + tSirResultCodes result_code, uint8_t vdev_id) { struct scheduler_msg msg = {0}; tSirSmeRsp *sme_rsp; @@ -72,13 +72,12 @@ void lim_send_sme_rsp(struct mac_context *mac_ctx, uint16_t msg_type, sme_rsp->messageType = msg_type; sme_rsp->length = sizeof(tSirSmeRsp); sme_rsp->status_code = result_code; - sme_rsp->sessionId = sme_session_id; + sme_rsp->vdev_id = vdev_id; msg.type = msg_type; msg.bodyptr = sme_rsp; msg.bodyval = 0; - MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, - sme_session_id, msg.type)); + MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, vdev_id, msg.type)); #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ switch (msg_type) { @@ -201,15 +200,15 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, session_entry->bcnLen = 0; } - if (session_entry->assocReq) { + if (session_entry->assoc_req) { sme_join_rsp->assocReqLength = session_entry->assocReqLen; qdf_mem_copy(sme_join_rsp->frames + sme_join_rsp->beaconLength, - session_entry->assocReq, + session_entry->assoc_req, sme_join_rsp->assocReqLength); - qdf_mem_free(session_entry->assocReq); - session_entry->assocReq = NULL; + qdf_mem_free(session_entry->assoc_req); + session_entry->assoc_req = NULL; session_entry->assocReqLen = 0; } if (session_entry->assocRsp) { @@ -309,7 +308,7 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, if (mac_ctx->roam.configParam.is_force_1x1 && is_vendor_ap_1_present && (session_entry->nss == 2) && (mac_ctx->lteCoexAntShare == 0 || - IS_5G_CH(session_entry->currentOperChannel))) { + wlan_reg_is_5ghz_ch_freq(session_entry->curr_op_freq))) { /* SET vdev param */ pe_debug("sending SMPS intolrent vdev_param"); wma_cli_set_command(session_entry->smeSessionId, @@ -323,9 +322,9 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, session_entry->beacon = NULL; session_entry->bcnLen = 0; } - if (session_entry->assocReq) { - qdf_mem_free(session_entry->assocReq); - session_entry->assocReq = NULL; + if (session_entry->assoc_req) { + qdf_mem_free(session_entry->assoc_req); + session_entry->assoc_req = NULL; session_entry->assocReqLen = 0; } if (session_entry->assocRsp) { @@ -348,6 +347,20 @@ static void lim_handle_join_rsp_status(struct mac_context *mac_ctx, } } +#ifdef WLAN_FEATURE_11AX +static void lim_add_he_info(struct parsed_ies *parsed_ies, + struct join_rsp *sme_join_rsp) +{ + if (parsed_ies->he_operation.present) + sme_join_rsp->he_operation = parsed_ies->he_operation; +} +#else +static inline void lim_add_he_info(struct parsed_ies *parsed_ies, + struct join_rsp *sme_join_rsp) +{ +} +#endif + /** * lim_add_bss_info() - copy data from session entry to join rsp * @sta_ds: Station dph entry @@ -370,6 +383,7 @@ static void lim_add_bss_info(tpDphHashNode sta_ds, sme_join_rsp->ht_operation = parsed_ies->ht_operation; if (parsed_ies->vht_operation.present) sme_join_rsp->vht_operation = parsed_ies->vht_operation; + lim_add_he_info(parsed_ies, sme_join_rsp); } #ifdef WLAN_FEATURE_FILS_SK @@ -390,7 +404,7 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx, tSirResultCodes result_code, uint16_t prot_status_code, struct pe_session *session_entry, - uint8_t sme_session_id) + uint8_t vdev_id) { struct join_rsp *sme_join_rsp; uint32_t rsp_len; @@ -441,8 +455,6 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx, if (!sta_ds) { pe_err("Get Self Sta Entry fail"); } else { - /* Pass the peer's staId */ - sme_join_rsp->staId = sta_ds->staIndex; sme_join_rsp->timingMeasCap = sta_ds->timingMeasCap; #ifdef FEATURE_WLAN_TDLS @@ -484,7 +496,7 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx, sme_join_rsp->status_code = result_code; sme_join_rsp->protStatusCode = prot_status_code; - sme_join_rsp->sessionId = sme_session_id; + sme_join_rsp->vdev_id = vdev_id; lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, QDF_STATUS_SUCCESS, sme_join_rsp); @@ -545,8 +557,8 @@ void lim_send_sme_start_bss_rsp(struct mac_context *mac, (uint32_t *) &pSirSmeRsp->bssDescription. nwType, pe_session); - pSirSmeRsp->bssDescription.channelId = - pe_session->currentOperChannel; + pSirSmeRsp->bssDescription.chan_freq = + pe_session->curr_op_freq; if (!LIM_IS_NDI_ROLE(pe_session)) { curLen = pe_session->schBeaconOffsetBegin - ieOffset; @@ -596,8 +608,6 @@ void lim_send_sme_start_bss_rsp(struct mac_context *mac, pSirSmeRsp->length = size; pSirSmeRsp->sessionId = smesessionId; pSirSmeRsp->status_code = resultCode; - if (pe_session) - pSirSmeRsp->staId = pe_session->staId; /* else it will be always zero smeRsp StaID = 0 */ mmhMsg.type = msgType; mmhMsg.bodyptr = pSirSmeRsp; @@ -658,8 +668,8 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, * Duplicate entry is removed at LIM. * Initiate new entry for other session */ - pe_debug("Rcvd eLIM_DUPLICATE_ENTRY for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peerMacAddr)); + pe_debug("Rcvd eLIM_DUPLICATE_ENTRY for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peerMacAddr)); for (i = 0; i < mac->lim.maxBssId; i++) { session = &mac->lim.gpSession[i]; @@ -673,11 +683,7 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, break; } } - if (sta_ds -#ifdef WLAN_FEATURE_11W - && (!sta_ds->rmfEnabled) -#endif - ) { + if (sta_ds) { if (lim_add_sta(mac, sta_ds, false, session) != QDF_STATUS_SUCCESS) pe_err("could not Add STA with assocId: %d", @@ -705,8 +711,8 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, goto error; } pe_debug("send eWNI_SME_DISASSOC_RSP with retCode: %d for " - QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(peerMacAddr)); + QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(peerMacAddr)); pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP; pSirSmeDisassocRsp->length = sizeof(struct disassoc_rsp); pSirSmeDisassocRsp->sessionId = smesessionId; @@ -746,11 +752,11 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, goto error; } pe_debug("send eWNI_SME_DISASSOC_IND with retCode: %d for " - QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(peerMacAddr)); + QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(peerMacAddr)); pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; pSirSmeDisassocInd->length = sizeof(*pSirSmeDisassocInd); - pSirSmeDisassocInd->sessionId = smesessionId; + pSirSmeDisassocInd->vdev_id = smesessionId; pSirSmeDisassocInd->reasonCode = reasonCode; pSirSmeDisassocInd->status_code = reasonCode; qdf_mem_copy(pSirSmeDisassocInd->bssid.bytes, @@ -811,7 +817,7 @@ lim_send_sme_disassoc_ind(struct mac_context *mac, tpDphHashNode sta, pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; pSirSmeDisassocInd->length = sizeof(*pSirSmeDisassocInd); - pSirSmeDisassocInd->sessionId = pe_session->smeSessionId; + pSirSmeDisassocInd->vdev_id = pe_session->smeSessionId; pSirSmeDisassocInd->status_code = eSIR_SME_DEAUTH_STATUS; pSirSmeDisassocInd->reasonCode = sta->mlmStaContext.disassocReason; @@ -821,8 +827,6 @@ lim_send_sme_disassoc_ind(struct mac_context *mac, tpDphHashNode sta, qdf_mem_copy(pSirSmeDisassocInd->peer_macaddr.bytes, sta->staAddr, QDF_MAC_ADDR_SIZE); - pSirSmeDisassocInd->staId = sta->staIndex; - if (LIM_IS_STA_ROLE(pe_session)) pSirSmeDisassocInd->from_ap = lim_is_disconnect_from_ap(sta->mlmStaContext.cleanupTrigger); @@ -868,7 +872,7 @@ lim_send_sme_deauth_ind(struct mac_context *mac, tpDphHashNode sta, pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; pSirSmeDeauthInd->length = sizeof(*pSirSmeDeauthInd); - pSirSmeDeauthInd->sessionId = pe_session->smeSessionId; + pSirSmeDeauthInd->vdev_id = pe_session->smeSessionId; if (eSIR_INFRA_AP_MODE == pe_session->bssType) { pSirSmeDeauthInd->status_code = (tSirResultCodes) sta->mlmStaContext.cleanupTrigger; @@ -885,7 +889,6 @@ lim_send_sme_deauth_ind(struct mac_context *mac, tpDphHashNode sta, QDF_MAC_ADDR_SIZE); pSirSmeDeauthInd->reasonCode = sta->mlmStaContext.disassocReason; - pSirSmeDeauthInd->staId = sta->staIndex; if (eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON == sta->mlmStaContext.disassocReason) pSirSmeDeauthInd->rssi = sta->del_sta_ctx_rssi; @@ -934,8 +937,8 @@ lim_send_sme_tdls_del_sta_ind(struct mac_context *mac, tpDphHashNode sta, { struct tdls_event_info info; - pe_debug("Delete TDLS Peer "QDF_MAC_ADDR_STR "with reason code: %d", - QDF_MAC_ADDR_ARRAY(sta->staAddr), reasonCode); + pe_debug("Delete TDLS Peer "QDF_MAC_ADDR_FMT "with reason code: %d", + QDF_MAC_ADDR_REF(sta->staAddr), reasonCode); info.vdev_id = pe_session->smeSessionId; qdf_mem_copy(info.peermac.bytes, sta->staAddr, QDF_MAC_ADDR_SIZE); info.message_type = TDLS_PEER_DISCONNECTED; @@ -967,7 +970,7 @@ lim_send_sme_tdls_del_sta_ind(struct mac_context *mac, tpDphHashNode sta, */ void lim_send_sme_mgmt_tx_completion(struct mac_context *mac, - uint32_t sme_session_id, + uint32_t vdev_id, uint32_t txCompleteStatus) { struct scheduler_msg msg = {0}; @@ -980,7 +983,7 @@ lim_send_sme_mgmt_tx_completion(struct mac_context *mac, return; /* sessionId */ - mgmt_tx_completion_ind->session_id = sme_session_id; + mgmt_tx_completion_ind->vdev_id = vdev_id; mgmt_tx_completion_ind->tx_complete_status = txCompleteStatus; @@ -1061,8 +1064,8 @@ void lim_send_sme_deauth_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr, if (!pSirSmeDeauthRsp) return; pe_debug("send eWNI_SME_DEAUTH_RSP with retCode: %d for " - QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(peerMacAddr)); + QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(peerMacAddr)); pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP; pSirSmeDeauthRsp->length = sizeof(*pSirSmeDeauthRsp); pSirSmeDeauthRsp->status_code = reasonCode; @@ -1099,12 +1102,12 @@ void lim_send_sme_deauth_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr, if (!pSirSmeDeauthInd) return; pe_debug("send eWNI_SME_DEAUTH_IND with retCode: %d for " - QDF_MAC_ADDR_STR, - reasonCode, QDF_MAC_ADDR_ARRAY(peerMacAddr)); + QDF_MAC_ADDR_FMT, + reasonCode, QDF_MAC_ADDR_REF(peerMacAddr)); pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; pSirSmeDeauthInd->length = sizeof(*pSirSmeDeauthInd); pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; - pSirSmeDeauthInd->sessionId = smesessionId; + pSirSmeDeauthInd->vdev_id = smesessionId; pSirSmeDeauthInd->status_code = reasonCode; qdf_mem_copy(pSirSmeDeauthInd->bssid.bytes, pe_session->bssId, sizeof(tSirMacAddr)); @@ -1359,66 +1362,6 @@ lim_send_sme_delts_ind(struct mac_context *mac, struct delts_req_info *delts, lim_sys_process_mmh_msg_api(mac, &mmhMsg); } -#ifndef QCA_SUPPORT_CP_STATS -/** - * lim_send_sme_pe_statistics_rsp() - * - ***FUNCTION: - * This function is called to send 802.11 statistics response to HDD. - * This function posts the result back to HDD. This is a response to - * HDD's request for statistics. - * - ***PARAMS: - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac Pointer to Global MAC structure - * @param p80211Stats Statistics sent in response - * @param resultCode TODO: - * - * - * @return none - */ - -void -lim_send_sme_pe_statistics_rsp(struct mac_context *mac, uint16_t msgType, void *stats) -{ - struct scheduler_msg mmhMsg = {0}; - uint8_t sessionId; - tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats; - struct pe_session *pPeSessionEntry; - - /* Get the Session Id based on Sta Id */ - pPeSessionEntry = - pe_find_session_by_sta_id(mac, pPeStats->staId, &sessionId); - - /* Fill the Session Id */ - if (pPeSessionEntry) { - /* Fill the Session Id */ - pPeStats->sessionId = pPeSessionEntry->smeSessionId; - } - - pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP; - - /* msgType should be WMA_GET_STATISTICS_RSP */ - mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP; - - mmhMsg.bodyptr = stats; - mmhMsg.bodyval = 0; - MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); - lim_sys_process_mmh_msg_api(mac, &mmhMsg); - - return; - -} /*** end lim_send_sme_pe_statistics_rsp() ***/ -#endif - #ifdef FEATURE_WLAN_ESE /** * lim_send_sme_pe_ese_tsm_rsp() - send tsm response @@ -1447,8 +1390,8 @@ void lim_send_sme_pe_ese_tsm_rsp(struct mac_context *mac, /* Fill the Session Id */ pPeStats->sessionId = pPeSessionEntry->smeSessionId; } else { - pe_err("Session not found for the Sta id: %d", - pPeStats->staId); + pe_err("Session not found for the Sta peer:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pPeStats->bssid.bytes)); qdf_mem_free(pPeStats->tsmStatsReq); qdf_mem_free(pPeStats); return; @@ -1471,10 +1414,10 @@ void lim_send_sme_pe_ese_tsm_rsp(struct mac_context *mac, #endif /* FEATURE_WLAN_ESE */ +#ifdef QCA_IBSS_SUPPORT void lim_send_sme_ibss_peer_ind(struct mac_context *mac, tSirMacAddr peerMacAddr, - uint16_t staIndex, uint8_t *beacon, uint16_t beaconLen, uint16_t msgType, uint8_t sessionId) { @@ -1487,7 +1430,6 @@ lim_send_sme_ibss_peer_ind(struct mac_context *mac, qdf_mem_copy((uint8_t *) pNewPeerInd->peer_addr.bytes, peerMacAddr, QDF_MAC_ADDR_SIZE); - pNewPeerInd->staId = staIndex; pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen; pNewPeerInd->mesgType = msgType; pNewPeerInd->sessionId = sessionId; @@ -1504,6 +1446,7 @@ lim_send_sme_ibss_peer_ind(struct mac_context *mac, lim_sys_process_mmh_msg_api(mac, &mmhMsg); } +#endif /** * lim_process_csa_wbw_ie() - Process CSA Wide BW IE @@ -1661,8 +1604,8 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, pe_find_session_by_bssid(mac_ctx, csa_params->bssId, &session_id); if (!session_entry) { - pe_err("Session does not exists for %pM", - csa_params->bssId); + pe_err("Session does not exists for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(csa_params->bssId)); goto err; } @@ -1693,6 +1636,8 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, session_entry->gLimChannelSwitch.switchCount = 0; session_entry->gLimChannelSwitch.primaryChannel = csa_params->channel; + session_entry->gLimChannelSwitch.sw_target_freq = + csa_params->csa_chan_freq; session_entry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ; @@ -1703,7 +1648,7 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, chnl_switch_info = &session_entry->gLimWiderBWChannelSwitch; - if (WLAN_REG_IS_24GHZ_CH(csa_params->channel)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(csa_params->csa_chan_freq)) { channel_bonding_mode = mac_ctx->roam.configParam.channelBondingMode24GHz; } else { @@ -1720,8 +1665,9 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, session_entry->htSupportedChannelWidthSet = false; - if (session_entry->vhtCapability && channel_bonding_mode && - session_entry->htCapability) { + if (channel_bonding_mode && + ((session_entry->vhtCapability && session_entry->htCapability) || + lim_is_session_he_capable(session_entry))) { if ((csa_params->ies_present_flag & lim_wbw_ie_present) && (QDF_STATUS_SUCCESS == lim_process_csa_wbw_ie(mac_ctx, csa_params, chnl_switch_info, @@ -1741,15 +1687,29 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, } } else if (csa_params->ies_present_flag & lim_xcsa_ie_present) { - chan_space = + uint32_t fw_vht_ch_wd = wma_get_vht_ch_width(); + + if (wlan_reg_is_6ghz_op_class + (mac_ctx->pdev, csa_params->new_op_class)) { + chan_space = wlan_reg_get_op_class_width + (mac_ctx->pdev, + csa_params->new_op_class, true); + } else { + chan_space = wlan_reg_dmn_get_chanwidth_from_opclass( mac_ctx->scan.countryCodeCurrent, csa_params->channel, csa_params->new_op_class); + } + if (chan_space >= 160 && fw_vht_ch_wd < + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) + chan_space = 80; session_entry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; - - if (chan_space == 80) { + if (chan_space == 160) { + chnl_switch_info->newChanWidth = + CH_WIDTH_160MHZ; + } else if (chan_space == 80) { chnl_switch_info->newChanWidth = CH_WIDTH_80MHZ; session_entry->htSupportedChannelWidthSet = @@ -1856,24 +1816,25 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, session_entry->htSupportedChannelWidthSet = true; } } - pe_debug("new ch %d width: %d freq0 %d freq1 %d ht width %d", + pe_debug("new ch %d freq %d width: %d freq0 %d freq1 %d ht width %d", session_entry->gLimChannelSwitch.primaryChannel, + session_entry->gLimChannelSwitch.sw_target_freq, session_entry->gLimChannelSwitch.ch_width, session_entry->gLimChannelSwitch.ch_center_freq_seg0, session_entry->gLimChannelSwitch.ch_center_freq_seg1, session_entry->gLimChannelSwitch.sec_ch_offset); - if (session_entry->currentOperChannel == csa_params->channel && + if (session_entry->curr_op_freq == csa_params->csa_chan_freq && session_entry->ch_width == session_entry->gLimChannelSwitch.ch_width) { pe_debug("Ignore CSA, no change in ch and bw"); goto err; } - if (WLAN_REG_IS_24GHZ_CH(csa_params->channel) && - (session_entry->dot11mode == MLME_DOT11_MODE_11A)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(csa_params->csa_chan_freq) && + session_entry->dot11mode == MLME_DOT11_MODE_11A) session_entry->dot11mode = MLME_DOT11_MODE_11G; - else if (WLAN_REG_IS_5GHZ_CH(csa_params->channel) && + else if (WLAN_REG_IS_5GHZ_CH_FREQ(csa_params->csa_chan_freq) && ((session_entry->dot11mode == MLME_DOT11_MODE_11G) || (session_entry->dot11mode == MLME_DOT11_MODE_11G_ONLY))) session_entry->dot11mode = MLME_DOT11_MODE_11A; @@ -1908,18 +1869,17 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, \sa --------------------------------------------------------------------------*/ -void lim_handle_delete_bss_rsp(struct mac_context *mac, struct scheduler_msg *MsgQ) +void lim_handle_delete_bss_rsp(struct mac_context *mac, + struct del_bss_resp *del_bss_rsp) { struct pe_session *pe_session; - tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr); pe_session = - pe_find_session_by_session_id(mac, pDelBss->sessionId); + pe_find_session_by_vdev_id_and_state(mac, + del_bss_rsp->vdev_id, + eLIM_MLM_WT_DEL_BSS_RSP_STATE); if (!pe_session) { - pe_err("Session Does not exist for given sessionID: %d", - pDelBss->sessionId); - qdf_mem_free(MsgQ->bodyptr); - MsgQ->bodyptr = NULL; + qdf_mem_free(del_bss_rsp); return; } @@ -1931,14 +1891,15 @@ void lim_handle_delete_bss_rsp(struct mac_context *mac, struct scheduler_msg *Ms */ pe_session->process_ho_fail = false; if (LIM_IS_IBSS_ROLE(pe_session)) - lim_ibss_del_bss_rsp(mac, MsgQ->bodyptr, pe_session); + lim_ibss_del_bss_rsp(mac, del_bss_rsp, pe_session); else if (LIM_IS_UNKNOWN_ROLE(pe_session)) - lim_process_sme_del_bss_rsp(mac, MsgQ->bodyval, pe_session); + lim_process_sme_del_bss_rsp(mac, pe_session); else if (LIM_IS_NDI_ROLE(pe_session)) - lim_ndi_del_bss_rsp(mac, MsgQ->bodyptr, pe_session); + lim_ndi_del_bss_rsp(mac, del_bss_rsp, pe_session); else - lim_process_mlm_del_bss_rsp(mac, MsgQ, pe_session); + lim_process_mlm_del_bss_rsp(mac, del_bss_rsp, pe_session); + qdf_mem_free(del_bss_rsp); } /** ----------------------------------------------------------------- @@ -1983,8 +1944,8 @@ void lim_send_sme_max_assoc_exceeded_ntf(struct mac_context *mac, tSirMacAddr pe pSmeMaxAssocInd->sessionId = smesessionId; mmhMsg.type = pSmeMaxAssocInd->mesgType; mmhMsg.bodyptr = pSmeMaxAssocInd; - pe_debug("msgType: %s peerMacAddr "QDF_MAC_ADDR_STR "sme session id %d", - "eWNI_SME_MAX_ASSOC_EXCEEDED", QDF_MAC_ADDR_ARRAY(peerMacAddr), + pe_debug("msgType: %s peerMacAddr "QDF_MAC_ADDR_FMT "sme session id %d", + "eWNI_SME_MAX_ASSOC_EXCEEDED", QDF_MAC_ADDR_REF(peerMacAddr), pSmeMaxAssocInd->sessionId); MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG, smesessionId, mmhMsg.type)); @@ -2007,42 +1968,39 @@ void lim_send_sme_max_assoc_exceeded_ntf(struct mac_context *mac, tSirMacAddr pe void lim_send_sme_ap_channel_switch_resp(struct mac_context *mac, struct pe_session *pe_session, - tpSwitchChannelParams pChnlParams) + struct vdev_start_response *rsp) { struct scheduler_msg mmhMsg = {0}; - tpSwitchChannelParams pSmeSwithChnlParams; - uint8_t channelId; + struct sSirChanChangeResponse *chan_change_rsp; bool is_ch_dfs = false; enum phy_ch_width ch_width; - uint8_t ch_center_freq_seg1; + uint32_t ch_cfreq1 = 0; + enum reg_wifi_band band; qdf_runtime_pm_allow_suspend(&pe_session->ap_ecsa_runtime_lock); qdf_wake_lock_release(&pe_session->ap_ecsa_wakelock, 0); - pSmeSwithChnlParams = qdf_mem_malloc(sizeof(tSwitchChannelParams)); - if (!pSmeSwithChnlParams) + chan_change_rsp = + qdf_mem_malloc(sizeof(struct sSirChanChangeResponse)); + if (!chan_change_rsp) return; - qdf_mem_copy(pSmeSwithChnlParams, pChnlParams, - sizeof(tSwitchChannelParams)); - - channelId = pSmeSwithChnlParams->channelNumber; - ch_width = pSmeSwithChnlParams->ch_width; - ch_center_freq_seg1 = pSmeSwithChnlParams->ch_center_freq_seg1; - + chan_change_rsp->new_op_freq = pe_session->curr_op_freq; + chan_change_rsp->channelChangeStatus = rsp->status; /* * Pass the sme sessionID to SME instead * PE session ID. */ - pSmeSwithChnlParams->peSessionId = pe_session->smeSessionId; + chan_change_rsp->sessionId = rsp->vdev_id; mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP; - mmhMsg.bodyptr = (void *)pSmeSwithChnlParams; + mmhMsg.bodyptr = (void *)chan_change_rsp; mmhMsg.bodyval = 0; lim_sys_process_mmh_msg_api(mac, &mmhMsg); - if (QDF_IS_STATUS_ERROR(pChnlParams->status)) { - pe_err("failed to change sap channel to %u", channelId); + if (QDF_IS_STATUS_ERROR(rsp->status)) { + pe_err("failed to change sap freq to %u", + pe_session->curr_op_freq); return; } @@ -2052,35 +2010,42 @@ lim_send_sme_ap_channel_switch_resp(struct mac_context *mac, * channel, PE will receive an explicit request from * upper layers to start the beacon transmission . */ + ch_width = pe_session->ch_width; + band = wlan_reg_freq_to_band(pe_session->curr_op_freq); + if (pe_session->ch_center_freq_seg1) + ch_cfreq1 = wlan_reg_chan_band_to_freq( + mac->pdev, + pe_session->ch_center_freq_seg1, + BIT(band)); if (ch_width == CH_WIDTH_160MHZ) { is_ch_dfs = true; } else if (ch_width == CH_WIDTH_80P80MHZ) { - if (wlan_reg_get_channel_state(mac->pdev, channelId) == - CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac->pdev, - ch_center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS) + if (wlan_reg_get_channel_state_for_freq( + mac->pdev, + pe_session->curr_op_freq) == + CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + mac->pdev, + ch_cfreq1) == + CHANNEL_STATE_DFS) is_ch_dfs = true; } else { - if (wlan_reg_get_channel_state(mac->pdev, channelId) == - CHANNEL_STATE_DFS) + if (wlan_reg_get_channel_state_for_freq( + mac->pdev, + pe_session->curr_op_freq) == + CHANNEL_STATE_DFS) is_ch_dfs = true; } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq)) + is_ch_dfs = false; if (is_ch_dfs) { lim_sap_move_to_cac_wait_state(pe_session); } else { - if (channelId == pe_session->currentOperChannel) { - lim_apply_configuration(mac, pe_session); - lim_send_beacon(mac, pe_session); - } else { - pe_debug("Failed to Transmit Beacons on channel: %d after AP channel change response", - pe_session->bcnLen); - } - + lim_apply_configuration(mac, pe_session); + lim_send_beacon(mac, pe_session); lim_obss_send_detection_cfg(mac, pe_session, true); } return; @@ -2120,30 +2085,31 @@ lim_handle_bss_color_change_ie(struct mac_context *mac_ctx, /* handle bss color change IE */ if (LIM_IS_AP_ROLE(session) && - session->he_op.bss_col_disabled) { + session->he_op.bss_col_disabled && + session->he_bss_color_change.new_color) { + pe_debug("countdown: %d, new_color: %d", + session->he_bss_color_change.countdown, + session->he_bss_color_change.new_color); if (session->he_bss_color_change.countdown > 0) { session->he_bss_color_change.countdown--; } else { session->bss_color_changing = 0; qdf_mem_zero(&beacon_params, sizeof(beacon_params)); - if (session->he_bss_color_change.new_color != 0) { - session->he_op.bss_col_disabled = 0; - session->he_op.bss_color = - session->he_bss_color_change.new_color; - beacon_params.paramChangeBitmap |= - PARAM_BSS_COLOR_CHANGED; - beacon_params.bss_color_disabled = 0; - beacon_params.bss_color = - session->he_op.bss_color; - lim_send_beacon_params(mac_ctx, - &beacon_params, - session); - lim_send_obss_color_collision_cfg(mac_ctx, - session, - OBSS_COLOR_COLLISION_DETECTION); - } + session->he_op.bss_col_disabled = 0; + session->he_op.bss_color = + session->he_bss_color_change.new_color; + session->he_bss_color_change.new_color = 0; + beacon_params.paramChangeBitmap |= + PARAM_BSS_COLOR_CHANGED; + beacon_params.bss_color_disabled = 0; + beacon_params.bss_color = session->he_op.bss_color; + lim_send_beacon_params(mac_ctx, + &beacon_params, + session); + lim_send_obss_color_collision_cfg( + mac_ctx, session, + OBSS_COLOR_COLLISION_DETECTION); } - lim_send_bss_color_change_ie_update(mac_ctx, session); } } @@ -2164,7 +2130,7 @@ lim_process_beacon_tx_success_ind(struct mac_context *mac_ctx, uint16_t msgType, tpSirFirstBeaconTxCompleteInd bcn_ind = (tSirFirstBeaconTxCompleteInd *) event; - session = pe_find_session_by_bss_idx(mac_ctx, bcn_ind->bss_idx); + session = pe_find_session_by_vdev_id(mac_ctx, bcn_ind->bss_idx); if (!session) { pe_err("Session Does not exist for given session id"); return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h index c291ab368ff06f58cb270d153752b4882d31c32b..0c7255483394e3947878dea6e92b11c39bd48763 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h @@ -42,7 +42,7 @@ * @msg_type: Indicates message type * @result_code: Indicates the result of previously issued * eWNI_SME_msg_type_REQ message - * @sme_session_id: SME session associated with the request + * @vdev_id: vdev_id * * This function is called by lim_process_sme_req_messages() to send * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP @@ -52,7 +52,7 @@ * Return: None */ void lim_send_sme_rsp(struct mac_context *mac_ctx, uint16_t msg_type, - tSirResultCodes result_code, uint8_t sme_session_id); + tSirResultCodes result_code, uint8_t vdev_id); /** * lim_send_sme_start_bss_rsp() - Send Start BSS response @@ -78,7 +78,7 @@ void lim_send_sme_start_bss_rsp(struct mac_context *mac, * @result_code: Indicates the result of previously issued request * @prot_status_code: Protocol Status Code * @session_entry: PE Session Info - * @sme_session_id: SME Session ID + * @vdev_id: vdev_id * * This function is called by lim_process_sme_req_messages() to send * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications @@ -91,7 +91,7 @@ void lim_send_sme_join_reassoc_rsp(struct mac_context *mac_ctx, tSirResultCodes result_code, uint16_t prot_status_code, struct pe_session *session_entry, - uint8_t sme_session_id); + uint8_t vdev_id); /** * lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message @@ -140,7 +140,7 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, * @reasonCode: the reason for Deauthetication * @deauthTrigger: the trigger for Deauthetication * @aid: the STAID. This parameter is present only on AP. - * @smesessionId: ID of the SME session associated with the notification + * @vdev_id: vdev id * * This function is used for sending eWNI_SME_DEAUTH_RSP or * eWNI_SME_DEAUTH_IND to upper layers depending on deauthentication @@ -150,7 +150,7 @@ void lim_send_sme_disassoc_ntf(struct mac_context *mac, */ void lim_send_sme_deauth_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr, tSirResultCodes reasonCode, uint16_t deauthTrigger, - uint16_t aid, uint8_t smesessionId); + uint16_t aid, uint8_t vdev_id); void lim_send_sme_disassoc_ind(struct mac_context *, tpDphHashNode, struct pe_session *); void lim_send_sme_deauth_ind(struct mac_context *, tpDphHashNode, @@ -179,8 +179,15 @@ void lim_send_sme_set_context_rsp(struct mac_context *mac, struct pe_session *pe_session, uint8_t smesessionId); +/** + * lim_handle_delete_bss_rsp () - API to handle delete bss response + * @mac: global mac structure + * @del_bss_rsp: pointer to del bss response + * + * Return: None + */ void lim_handle_delete_bss_rsp(struct mac_context *mac, - struct scheduler_msg *MsgQ); + struct del_bss_resp *del_bss_rsp); void lim_handle_csa_offload_msg(struct mac_context *mac_ctx, struct scheduler_msg *msg); @@ -215,28 +222,46 @@ void lim_send_sme_delts_ind(struct mac_context *mac, struct delts_req_info *delts, uint16_t aid, struct pe_session *); -#ifdef QCA_SUPPORT_CP_STATS -static inline void lim_send_sme_pe_statistics_rsp(struct mac_context *mac, - uint16_t msgtype, void *stats) {} -#else -void lim_send_sme_pe_statistics_rsp(struct mac_context *mac, uint16_t msgtype, - void *stats); -#endif /* QCA_SUPPORT_CP_STATS */ - #ifdef FEATURE_WLAN_ESE void lim_send_sme_pe_ese_tsm_rsp(struct mac_context *mac, tAniGetTsmStatsRsp *pStats); #endif +#ifdef QCA_IBSS_SUPPORT +/* + * lim_send_sme_ibss_peer_ind() - API to send ibss peer ind to sme + * @mac_ctx: Global mac_ctx + * @peerMacAddr: peer mac address + * @staIndex: sta index + * @beacon: pionter to beacon + * @beaconLen: length of beacon buffer + * @msg_type: msg_type + * @sessionId: session id + * + * + * Return: none + */ void lim_send_sme_ibss_peer_ind(struct mac_context *mac, tSirMacAddr peerMacAddr, - uint16_t staIndex, uint8_t *beacon, + uint8_t *beacon, uint16_t beaconLen, uint16_t msgType, uint8_t sessionId); +#else +static inline void +lim_send_sme_ibss_peer_ind(struct mac_context *mac, + tSirMacAddr peerMacAddr, + uint16_t staIndex, + uint8_t *beacon, + uint16_t beaconLen, uint16_t msgType, + uint8_t sessionId) +{ +} +#endif + void lim_send_sme_max_assoc_exceeded_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr, uint8_t smesessionId); void lim_send_sme_ap_channel_switch_resp(struct mac_context *mac, struct pe_session *pe_session, - tpSwitchChannelParams pChnlParams); + struct vdev_start_response *rsp); /* * lim_process_beacon_tx_success_ind() - handle successful beacon transmission * indication from the FW This is a generic event generated by the FW afer the diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c index 3b1d6a48100c33fe3ebace5ba43daa1aa0657d94..eacb32ec1f93d43a6115037baabab688b3943ae0 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -228,7 +229,7 @@ static void pe_reset_protection_callback(void *ptr) pe_debug("protection changed, update beacon template"); /* update beacon fix params and send update to FW */ qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams)); - beacon_params.bss_idx = pe_session_entry->bss_idx; + beacon_params.bss_idx = pe_session_entry->vdev_id; beacon_params.fShortPreamble = pe_session_entry->beaconParams.fShortPreamble; beacon_params.beaconInterval = @@ -248,8 +249,8 @@ static void pe_reset_protection_callback(void *ptr) fLsigTXOPProtectionFullSupport; beacon_params.fRIFSMode = pe_session_entry->beaconParams.fRIFSMode; - beacon_params.smeSessionId = - pe_session_entry->smeSessionId; + beacon_params.vdev_id = + pe_session_entry->vdev_id; beacon_params.paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; bcn_prms_changed = true; } @@ -269,6 +270,41 @@ static void pe_reset_protection_callback(void *ptr) } } +#ifdef WLAN_FEATURE_11W +/** + * pe_init_pmf_comeback_timer: init PMF comeback timer + * @mac_ctx: pointer to global adapter context + * @session: pe session + * + * Return: void + */ +static void +pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx, struct pe_session *session) +{ + QDF_STATUS status; + + if (session->opmode != QDF_STA_MODE) + return; + + pe_debug("init pmf comeback timer for vdev %d", session->vdev_id); + session->pmf_retry_timer_info.mac = mac_ctx; + session->pmf_retry_timer_info.vdev_id = session->vdev_id; + session->pmf_retry_timer_info.retried = false; + status = qdf_mc_timer_init( + &session->pmf_retry_timer, QDF_TIMER_TYPE_SW, + lim_pmf_comeback_timer_callback, + (void *)&session->pmf_retry_timer_info); + if (!QDF_IS_STATUS_SUCCESS(status)) + pe_err("cannot init pmf comeback timer"); +} +#else +static inline void +pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx, struct pe_session *session, + uint8_t vdev_id) +{ +} +#endif + #ifdef WLAN_FEATURE_FILS_SK /** * pe_delete_fils_info: API to delete fils session info @@ -412,8 +448,8 @@ void lim_set_bcn_probe_filter(struct mac_context *mac_ctx, if (eSIR_INFRASTRUCTURE_MODE == bss_type) { filter->num_sta_sessions++; sir_copy_mac_addr(filter->sta_bssid[session_id], *bssid); - pe_debug("Set filter for STA Session %d bssid "QDF_MAC_ADDR_STR, - session_id, QDF_MAC_ADDR_ARRAY(*bssid)); + pe_debug("Set filter for STA Session %d bssid "QDF_MAC_ADDR_FMT, + session_id, QDF_MAC_ADDR_REF(*bssid)); } else if (eSIR_IBSS_MODE == bss_type) { if (!ibss_ssid) { pe_err("IBSS Type with NULL SSID"); @@ -515,7 +551,8 @@ void lim_update_bcn_probe_filter(struct mac_context *mac_ctx, filter = &mac_ctx->bcn_filter; if (eSIR_INFRA_AP_MODE == bss_type) { - filter->sap_channel[session_id] = session->currentOperChannel; + filter->sap_channel[session_id] = wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq); pe_debug("Updated SAP Filter for session %d channel %d", session_id, filter->sap_channel[session_id]); } else { @@ -609,8 +646,8 @@ struct pe_session *pe_create_session(struct mac_context *mac, session_ptr->is_session_obss_color_collision_det_enabled = mac->mlme_cfg->obss_ht40.obss_color_collision_offload_enabled; - pe_debug("Create PE session: %d opmode %d vdev_id %d BSSID: "QDF_MAC_ADDR_STR" Max No of STA: %d", - *sessionId, opmode, vdev_id, QDF_MAC_ADDR_ARRAY(bssid), + pe_debug("Create PE session: %d opmode %d vdev_id %d BSSID: "QDF_MAC_ADDR_FMT" Max No of STA: %d", + *sessionId, opmode, vdev_id, QDF_MAC_ADDR_REF(bssid), numSta); if (eSIR_INFRA_AP_MODE == bssType || eSIR_IBSS_MODE == bssType) { @@ -674,7 +711,11 @@ struct pe_session *pe_create_session(struct mac_context *mac, if (status != QDF_STATUS_SUCCESS) pe_err("cannot create ap_ecsa_timer"); } + if (session_ptr->opmode == QDF_STA_MODE) + session_ptr->is_session_obss_color_collision_det_enabled = + mac->mlme_cfg->obss_ht40.bss_color_collision_det_sta; pe_init_fils_info(session_ptr); + pe_init_pmf_comeback_timer(mac, session_ptr); session_ptr->ht_client_cnt = 0; /* following is invalid value since seq number is 12 bit */ session_ptr->prev_auth_seq_num = 0xFFFF; @@ -737,28 +778,38 @@ struct pe_session *pe_find_session_by_bssid(struct mac_context *mac, uint8_t *bs } -/** - * pe_find_session_by_bss_idx() - looks up the PE session given the bss_idx. - * - * This function returns the session context if the session - * corresponding to the given bss_idx is found in the PE session table. - * @mac: pointer to global adapter context - * @bss_idx: bss index of the session - * - * Return: pointer to the session context or NULL if session is not found. - */ -struct pe_session *pe_find_session_by_bss_idx(struct mac_context *mac, - uint8_t bss_idx) +struct pe_session *pe_find_session_by_vdev_id(struct mac_context *mac, + uint8_t vdev_id) { uint8_t i; for (i = 0; i < mac->lim.maxBssId; i++) { /* If BSSID matches return corresponding tables address */ if ((mac->lim.gpSession[i].valid) && - (mac->lim.gpSession[i].bss_idx == bss_idx)) + (mac->lim.gpSession[i].vdev_id == vdev_id)) + return &mac->lim.gpSession[i]; + } + pe_debug("Session lookup fails for vdev_id: %d", vdev_id); + + return NULL; +} + +struct pe_session +*pe_find_session_by_vdev_id_and_state(struct mac_context *mac, + uint8_t vdev_id, + enum eLimMlmStates lim_state) +{ + uint8_t i; + + for (i = 0; i < mac->lim.maxBssId; i++) { + if (mac->lim.gpSession[i].valid && + mac->lim.gpSession[i].vdev_id == vdev_id && + mac->lim.gpSession[i].limMlmState == lim_state) return &mac->lim.gpSession[i]; } - pe_debug("Session lookup fails for bss_idx: %d", bss_idx); + pe_debug("Session lookup fails for vdev_id: %d, mlm state: %d", + vdev_id, lim_state); + return NULL; } @@ -789,44 +840,24 @@ struct pe_session *pe_find_session_by_session_id(struct mac_context *mac, return NULL; } -/** - * pe_find_session_by_sta_id() - looks up the PE session given staid. - * @mac_ctx: pointer to global adapter context - * @staid: StaId of the session - * @session_id: session ID is returned here, if session is found. - * - * This function returns the session context and the session ID if the session - * corresponding to the given StaId is found in the PE session table. - * - * Return: session pointer - */ -struct pe_session * -pe_find_session_by_sta_id(struct mac_context *mac_ctx, - uint8_t staid, - uint8_t *session_id) +#ifdef WLAN_FEATURE_11W +static void lim_clear_pmfcomeback_timer(struct pe_session *session) { - uint8_t i, j; - struct pe_session *session_ptr; - struct dph_hash_table *dph_ptr; - - for (i = 0; i < mac_ctx->lim.maxBssId; i++) { - if (!mac_ctx->lim.gpSession[i].valid) - continue; - session_ptr = &mac_ctx->lim.gpSession[i]; - dph_ptr = &session_ptr->dph.dphHashTable; - for (j = 0; j < dph_ptr->size; j++) { - if (dph_ptr->pDphNodeArray[j].valid - && dph_ptr->pDphNodeArray[j].added - && staid == dph_ptr->pDphNodeArray[j].staIndex) { - *session_id = i; - return session_ptr; - } - } - } + if (session->opmode != QDF_STA_MODE) + return; - pe_debug("Session lookup fails for StaId: %d", staid); - return NULL; + pe_debug("deinit pmf comeback timer for vdev %d", session->vdev_id); + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state(&session->pmf_retry_timer)) + qdf_mc_timer_stop(&session->pmf_retry_timer); + qdf_mc_timer_destroy(&session->pmf_retry_timer); + session->pmf_retry_timer_info.retried = false; +} +#else +static void lim_clear_pmfcomeback_timer(struct pe_session *session) +{ } +#endif /** * pe_delete_session() - deletes the PE session given the session ID. @@ -843,18 +874,18 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) uint16_t n; TX_TIMER *timer_ptr; struct wlan_objmgr_vdev *vdev; - tpSirAssocRsp assoc_rsp; if (!session || (session && !session->valid)) { pe_debug("session already deleted or not valid"); return; } - pe_debug("Delete PE session: %d opmode: %d vdev_id: %d BSSID: "QDF_MAC_ADDR_STR, + pe_debug("Delete PE session: %d opmode: %d vdev_id: %d BSSID: "QDF_MAC_ADDR_FMT, session->peSessionId, session->opmode, session->vdev_id, - QDF_MAC_ADDR_ARRAY(session->bssId)); + QDF_MAC_ADDR_REF(session->bssId)); lim_reset_bcn_probe_filter(mac_ctx, session); + lim_sae_auth_cleanup_retry(mac_ctx, session->vdev_id); /* Restore default failure timeout */ if (session->defaultAuthFailureTimeout) { @@ -869,7 +900,7 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) } for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) { - timer_ptr = &mac_ctx->lim.limTimers.gpLimCnfWaitTimer[n]; + timer_ptr = &mac_ctx->lim.lim_timers.gpLimCnfWaitTimer[n]; if (session->peSessionId == timer_ptr->sessionId) if (true == tx_timer_running(timer_ptr)) tx_timer_deactivate(timer_ptr); @@ -931,9 +962,9 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) session->bcnLen = 0; } - if (session->assocReq) { - qdf_mem_free(session->assocReq); - session->assocReq = NULL; + if (session->assoc_req) { + qdf_mem_free(session->assoc_req); + session->assoc_req = NULL; session->assocReqLen = 0; } @@ -964,9 +995,6 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) session->parsedAssocReq = NULL; } if (session->limAssocResponseData) { - assoc_rsp = (tpSirAssocRsp) session->limAssocResponseData; - qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); - qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); qdf_mem_free(session->limAssocResponseData); session->limAssocResponseData = NULL; } @@ -1011,6 +1039,7 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session) session->add_ie_params.probeRespBCNDataLen = 0; } pe_delete_fils_info(session); + lim_clear_pmfcomeback_timer(session); session->valid = false; session->mac_ctx = NULL; @@ -1067,32 +1096,8 @@ struct pe_session *pe_find_session_by_peer_sta(struct mac_context *mac, uint8_t } } - pe_debug("Session lookup fails for Peer StaId: %pM", sa); - return NULL; -} - -/** - * pe_find_session_by_sme_session_id() - looks up the PE session for given sme - * session id - * @mac_ctx: pointer to global adapter context - * @sme_session_id: sme session id - * - * looks up the PE session for given sme session id - * - * Return: pe session entry for given sme session if found else NULL - */ -struct pe_session *pe_find_session_by_sme_session_id(struct mac_context *mac_ctx, - uint8_t sme_session_id) -{ - uint8_t i; - - for (i = 0; i < mac_ctx->lim.maxBssId; i++) { - if ((mac_ctx->lim.gpSession[i].valid) && - (mac_ctx->lim.gpSession[i].smeSessionId == - sme_session_id)) { - return &mac_ctx->lim.gpSession[i]; - } - } + pe_debug("Session lookup fails for Peer StaId: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sa)); return NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session_utils.c index 7b7cd2c8a728d4003f36b3a5ff7b5f2564b19ea0..64d99d21237bb1efc92db9211d4b92e3fef710e7 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,8 +61,8 @@ uint8_t lim_is_chan_switch_running(struct mac_context *mac_ctx) uint8_t lim_is_in_mcc(struct mac_context *mac_ctx) { uint8_t i; - uint8_t chan = 0; - uint8_t curr_oper_channel = 0; + uint32_t freq = 0; + uint32_t curr_oper_freq = 0; for (i = 0; i < mac_ctx->lim.maxBssId; i++) { /* @@ -70,13 +70,13 @@ uint8_t lim_is_in_mcc(struct mac_context *mac_ctx) * it is an off channel operation. */ if ((mac_ctx->lim.gpSession[i].valid)) { - curr_oper_channel = - mac_ctx->lim.gpSession[i].currentOperChannel; - if (curr_oper_channel == 0) + curr_oper_freq = + mac_ctx->lim.gpSession[i].curr_op_freq; + if (curr_oper_freq == 0) continue; - if (chan == 0) - chan = curr_oper_channel; - else if (chan != curr_oper_channel) + if (freq == 0) + freq = curr_oper_freq; + else if (freq != curr_oper_freq) return true; } } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sme_req_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sme_req_utils.c index 9f0c07c864409b34be1d4714398bb86524ee6096..c682624cf7accecdf7f2e6e65c4b74c668f80246 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sme_req_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sme_req_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -346,12 +346,9 @@ lim_is_bss_descr_valid_in_sme_req_message(struct mac_context *mac, { uint8_t valid = true; - if (QDF_IS_ADDR_BROADCAST(pBssDescr->bssId) || !pBssDescr->channelId) { + if (QDF_IS_ADDR_BROADCAST(pBssDescr->bssId) || !pBssDescr->chan_freq) valid = false; - goto end; - } -end: return valid; } /*** end lim_is_bss_descr_valid_in_sme_req_message() ***/ @@ -361,12 +358,6 @@ bool lim_is_sme_start_bss_req_valid(struct mac_context *mac_ctx, uint8_t i = 0; tSirMacRateSet *opr_rates = &start_bss_req->operationalRateSet; - pe_debug("Parsed START_BSS_REQ fields are bssType: %s (%d) channelId: %d SSID len: %d rsnIE len: %d nwType: %d rateset len: %d", - lim_bss_type_to_string(start_bss_req->bssType), - start_bss_req->bssType, start_bss_req->channelId, - start_bss_req->ssId.length, start_bss_req->rsnIE.length, - start_bss_req->nwType, opr_rates->numRates); - switch (start_bss_req->bssType) { case eSIR_INFRASTRUCTURE_MODE: /** diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.c deleted file mode 100644 index cc1f13f95fa8ed93a3ccb1d80cc6c8fd4b29f035..0000000000000000000000000000000000000000 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_sta_hash_api.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2011-2012, 2017-2019 The Linux Foundation. All rights reserved. - * - * 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. - */ - -/* - * - * lim_sta_hash_api.c: Provides access functions to get/set values of station hash entry fields. - * Author: Sunit Bhatia - * Date: 09/19/2006 - * History:- - * Date Modified by Modification Information - * - * -------------------------------------------------------------------------- - * - */ - -#include "lim_sta_hash_api.h" - -/** - * lim_get_sta_hash_bssidx() - * - ***FUNCTION: - * This function is called to Get the Bss Index of the currently associated Station. - * - ***LOGIC: - * - ***ASSUMPTIONS: - * NA - * - ***NOTE: - * NA - * - * @param mac pointer to Global Mac structure. - * @param assocId AssocID of the Station. - * @param bssidx pointer to the bss index, which will be returned by the function. - * - * @return success if GET operation is ok, else Failure. - */ - -QDF_STATUS lim_get_sta_hash_bssidx(struct mac_context *mac, uint16_t assocId, - uint8_t *bssidx, struct pe_session *pe_session) -{ - tpDphHashNode pSta = - dph_get_hash_entry(mac, assocId, &pe_session->dph.dphHashTable); - - if (!pSta) { - pe_err("invalid STA: %d", assocId); - return QDF_STATUS_E_NOENT; - } - - *bssidx = (uint8_t) pSta->bssId; - return QDF_STATUS_SUCCESS; -} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_timer_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_timer_utils.c index 76be4cc6d9991492d4a1ec6ffc714f4f53c10965..17e5cf5c524a114f203c25c0ba5e7f674782ffd1 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_timer_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_timer_utils.c @@ -56,7 +56,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) { uint32_t cfgValue; /* Create Channel Switch Timer */ - if (tx_timer_create(mac, &mac->lim.limTimers.gLimChannelSwitchTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimChannelSwitchTimer, "CHANNEL SWITCH TIMER", lim_channel_switch_timer_handler, 0, LIM_CHANNEL_SWITCH_TIMER_TICKS, @@ -68,7 +68,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.join_failure_timeout); /* Create Join failure timer and activate it later */ - if (tx_timer_create(mac, &mac->lim.limTimers.gLimJoinFailureTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimJoinFailureTimer, "JOIN FAILURE TIMEOUT", lim_timer_handler, SIR_LIM_JOIN_FAIL_TIMEOUT, cfgValue, 0, @@ -80,7 +80,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) } /* Send unicast probe req frame every 200 ms */ if (tx_timer_create(mac, - &mac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, + &mac->lim.lim_timers.gLimPeriodicJoinProbeReqTimer, "Periodic Join Probe Request Timer", lim_timer_handler, SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT, @@ -92,7 +92,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) /* Send Auth frame every 60 ms */ if ((tx_timer_create(mac, - &mac->lim.limTimers.g_lim_periodic_auth_retry_timer, + &mac->lim.lim_timers.g_lim_periodic_auth_retry_timer, "Periodic AUTH Timer", lim_timer_handler, SIR_LIM_AUTH_RETRY_TIMEOUT, SYS_MS_TO_TICKS(LIM_AUTH_RETRY_TIMER_MS), 0, @@ -104,7 +104,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.assoc_failure_timeout); /* Create Association failure timer and activate it later */ - if (tx_timer_create(mac, &mac->lim.limTimers.gLimAssocFailureTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimAssocFailureTimer, "ASSOC FAILURE TIMEOUT", lim_assoc_failure_timer_handler, LIM_ASSOC, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) { @@ -115,7 +115,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS(mac->mlme_cfg->timeouts.addts_rsp_timeout); /* Create Addts response timer and activate it later */ - if (tx_timer_create(mac, &mac->lim.limTimers.gLimAddtsRspTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimAddtsRspTimer, "ADDTS RSP TIMEOUT", lim_addts_response_timer_handler, SIR_LIM_ADDTS_RSP_TIMEOUT, @@ -127,7 +127,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.auth_failure_timeout); /* Create Auth failure timer and activate it later */ - if (tx_timer_create(mac, &mac->lim.limTimers.gLimAuthFailureTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimAuthFailureTimer, "AUTH FAILURE TIMEOUT", lim_timer_handler, SIR_LIM_AUTH_FAIL_TIMEOUT, @@ -139,7 +139,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) /* Change timer to reactivate it in future */ cfgValue = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.probe_after_hb_fail_timeout); - if (tx_timer_create(mac, &mac->lim.limTimers.gLimProbeAfterHBTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimProbeAfterHBTimer, "Probe after Heartbeat TIMEOUT", lim_timer_handler, SIR_LIM_PROBE_HB_FAILURE_TIMEOUT, @@ -153,7 +153,7 @@ static bool lim_create_non_ap_timers(struct mac_context *mac) * authentication. */ if ((tx_timer_create(mac, - &mac->lim.limTimers.sae_auth_timer, + &mac->lim.lim_timers.sae_auth_timer, "SAE AUTH Timer", lim_timer_handler, SIR_LIM_AUTH_SAE_TIMEOUT, SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS), 0, @@ -194,7 +194,7 @@ uint32_t lim_create_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS(cfgValue); for (i = 0; i < (mac->lim.maxStation + 1); i++) { if (tx_timer_create(mac, - &mac->lim.limTimers.gpLimCnfWaitTimer[i], + &mac->lim.lim_timers.gpLimCnfWaitTimer[i], "CNF_MISS_TIMEOUT", lim_cnf_wait_tmer_handler, (uint32_t) i, cfgValue, @@ -227,7 +227,7 @@ uint32_t lim_create_timers(struct mac_context *mac) cfgValue = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.olbc_detect_timeout); - if (tx_timer_create(mac, &mac->lim.limTimers.gLimUpdateOlbcCacheTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimUpdateOlbcCacheTimer, "OLBC UPDATE CACHE TIMEOUT", lim_update_olbc_cache_timer_handler, SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, cfgValue, @@ -238,7 +238,7 @@ uint32_t lim_create_timers(struct mac_context *mac) cfgValue = 1000; cfgValue = SYS_MS_TO_TICKS(cfgValue); - if (tx_timer_create(mac, &mac->lim.limTimers.gLimDisassocAckTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimDisassocAckTimer, "DISASSOC ACK TIMEOUT", lim_timer_handler, SIR_LIM_DISASSOC_ACK_TIMEOUT, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) { @@ -248,7 +248,7 @@ uint32_t lim_create_timers(struct mac_context *mac) cfgValue = 1000; cfgValue = SYS_MS_TO_TICKS(cfgValue); - if (tx_timer_create(mac, &mac->lim.limTimers.gLimDeauthAckTimer, + if (tx_timer_create(mac, &mac->lim.lim_timers.gLimDeauthAckTimer, "DISASSOC ACK TIMEOUT", lim_timer_handler, SIR_LIM_DEAUTH_ACK_TIMEOUT, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) { @@ -260,21 +260,21 @@ uint32_t lim_create_timers(struct mac_context *mac) err_timer: lim_delete_timers_host_roam(mac); - tx_timer_delete(&mac->lim.limTimers.gLimDeauthAckTimer); - tx_timer_delete(&mac->lim.limTimers.gLimDisassocAckTimer); - tx_timer_delete(&mac->lim.limTimers.gLimUpdateOlbcCacheTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimDeauthAckTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimDisassocAckTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimUpdateOlbcCacheTimer); while (((int32_t)-- i) >= 0) { - tx_timer_delete(&mac->lim.limTimers.gpLimCnfWaitTimer[i]); + tx_timer_delete(&mac->lim.lim_timers.gpLimCnfWaitTimer[i]); } - tx_timer_delete(&mac->lim.limTimers.gLimProbeAfterHBTimer); - tx_timer_delete(&mac->lim.limTimers.gLimAuthFailureTimer); - tx_timer_delete(&mac->lim.limTimers.gLimAddtsRspTimer); - tx_timer_delete(&mac->lim.limTimers.gLimAssocFailureTimer); - tx_timer_delete(&mac->lim.limTimers.gLimJoinFailureTimer); - tx_timer_delete(&mac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); - tx_timer_delete(&mac->lim.limTimers.g_lim_periodic_auth_retry_timer); - tx_timer_delete(&mac->lim.limTimers.gLimChannelSwitchTimer); - tx_timer_delete(&mac->lim.limTimers.sae_auth_timer); + tx_timer_delete(&mac->lim.lim_timers.gLimProbeAfterHBTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimAuthFailureTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimAddtsRspTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimAssocFailureTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimJoinFailureTimer); + tx_timer_delete(&mac->lim.lim_timers.gLimPeriodicJoinProbeReqTimer); + tx_timer_delete(&mac->lim.lim_timers.g_lim_periodic_auth_retry_timer); + tx_timer_delete(&mac->lim.lim_timers.gLimChannelSwitchTimer); + tx_timer_delete(&mac->lim.lim_timers.sae_auth_timer); if (mac->lim.gLimPreAuthTimerTable.pTable) { for (i = 0; i < mac->lim.gLimPreAuthTimerTable.numEntry; i++) @@ -515,7 +515,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_ADDTS_RSP_TIMER: mac->lim.gLimAddtsRspTimerCount++; - if (tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer) + if (tx_timer_deactivate(&mac->lim.lim_timers.gLimAddtsRspTimer) != TX_SUCCESS) { /* Could not deactivate AddtsRsp Timer */ /* Log error */ @@ -525,7 +525,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_JOIN_FAIL_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.gLimJoinFailureTimer) + (&mac->lim.lim_timers.gLimJoinFailureTimer) != TX_SUCCESS) { /** * Could not deactivate Join Failure @@ -537,7 +537,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.join_failure_timeout); - if (tx_timer_change(&mac->lim.limTimers.gLimJoinFailureTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimJoinFailureTimer, val, 0) != TX_SUCCESS) { /** * Could not change Join Failure @@ -550,7 +550,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) + (&mac->lim.lim_timers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) { /* Could not deactivate periodic join req Times. */ pe_err("Unable to deactivate periodic join request timer"); @@ -558,8 +558,8 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS); if (tx_timer_change - (&mac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, val, - 0) != TX_SUCCESS) { + (&mac->lim.lim_timers.gLimPeriodicJoinProbeReqTimer, + val, 0) != TX_SUCCESS) { /* Could not change periodic join req times. */ /* Log error */ pe_err("Unable to change periodic join request timer"); @@ -569,7 +569,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_AUTH_FAIL_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.gLimAuthFailureTimer) + (&mac->lim.lim_timers.gLimAuthFailureTimer) != TX_SUCCESS) { /* Could not deactivate Auth failure timer. */ /* Log error */ @@ -579,7 +579,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.auth_failure_timeout); - if (tx_timer_change(&mac->lim.limTimers.gLimAuthFailureTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimAuthFailureTimer, val, 0) != TX_SUCCESS) { /* Could not change Authentication failure timer. */ /* Log error */ @@ -591,17 +591,17 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_AUTH_RETRY_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.g_lim_periodic_auth_retry_timer) + (&mac->lim.lim_timers.g_lim_periodic_auth_retry_timer) != TX_SUCCESS) { /* Could not deactivate Auth Retry Timer. */ pe_err("Unable to deactivate Auth Retry timer"); } session_entry = pe_find_session_by_session_id(mac, - mac->lim.limTimers. + mac->lim.lim_timers. g_lim_periodic_auth_retry_timer.sessionId); if (!session_entry) { pe_debug("session does not exist for given SessionId : %d", - mac->lim.limTimers. + mac->lim.lim_timers. g_lim_periodic_auth_retry_timer.sessionId); break; } @@ -609,7 +609,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = (session_entry->beaconParams.beaconInterval * 3) / 5; val = SYS_MS_TO_TICKS(val); if (tx_timer_change - (&mac->lim.limTimers.g_lim_periodic_auth_retry_timer, + (&mac->lim.lim_timers.g_lim_periodic_auth_retry_timer, val, 0) != TX_SUCCESS) { /* Could not change Auth Retry timer. */ pe_err("Unable to change Auth Retry timer"); @@ -618,7 +618,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_ASSOC_FAIL_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.gLimAssocFailureTimer) != + (&mac->lim.lim_timers.gLimAssocFailureTimer) != TX_SUCCESS) { /* Could not deactivate Association failure timer. */ /* Log error */ @@ -628,7 +628,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.assoc_failure_timeout); - if (tx_timer_change(&mac->lim.limTimers.gLimAssocFailureTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimAssocFailureTimer, val, 0) != TX_SUCCESS) { /* Could not change Association failure timer. */ /* Log error */ @@ -639,7 +639,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_PROBE_AFTER_HB_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.gLimProbeAfterHBTimer) != + (&mac->lim.lim_timers.gLimProbeAfterHBTimer) != TX_SUCCESS) { /* Could not deactivate Heartbeat timer. */ /* Log error */ @@ -652,7 +652,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) val = SYS_MS_TO_TICKS( mac->mlme_cfg->timeouts.probe_after_hb_fail_timeout); - if (tx_timer_change(&mac->lim.limTimers.gLimProbeAfterHBTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimProbeAfterHBTimer, val, 0) != TX_SUCCESS) { /* Could not change HeartBeat timer. */ /* Log error */ @@ -665,8 +665,9 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) break; case eLIM_DISASSOC_ACK_TIMER: - if (tx_timer_deactivate - (&mac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) { + if (tx_timer_deactivate( + &mac->lim.lim_timers.gLimDisassocAckTimer) != + TX_SUCCESS) { /** ** Could not deactivate Join Failure ** timer. Log error. @@ -676,7 +677,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) } val = 1000; val = SYS_MS_TO_TICKS(val); - if (tx_timer_change(&mac->lim.limTimers.gLimDisassocAckTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimDisassocAckTimer, val, 0) != TX_SUCCESS) { /** * Could not change Join Failure @@ -688,7 +689,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) break; case eLIM_DEAUTH_ACK_TIMER: - if (tx_timer_deactivate(&mac->lim.limTimers.gLimDeauthAckTimer) + if (tx_timer_deactivate(&mac->lim.lim_timers.gLimDeauthAckTimer) != TX_SUCCESS) { /** ** Could not deactivate Join Failure @@ -699,7 +700,7 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) } val = 1000; val = SYS_MS_TO_TICKS(val); - if (tx_timer_change(&mac->lim.limTimers.gLimDeauthAckTimer, + if (tx_timer_change(&mac->lim.lim_timers.gLimDeauthAckTimer, val, 0) != TX_SUCCESS) { /** * Could not change Join Failure @@ -712,14 +713,14 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId) case eLIM_AUTH_SAE_TIMER: if (tx_timer_deactivate - (&mac->lim.limTimers.sae_auth_timer) + (&mac->lim.lim_timers.sae_auth_timer) != TX_SUCCESS) pe_err("Unable to deactivate SAE auth timer"); /* Change timer to reactivate it in future */ val = SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS); - if (tx_timer_change(&mac->lim.limTimers.sae_auth_timer, + if (tx_timer_change(&mac->lim.lim_timers.sae_auth_timer, val, 0) != TX_SUCCESS) pe_err("unable to change SAE auth timer"); @@ -767,7 +768,7 @@ lim_deactivate_and_change_per_sta_id_timer(struct mac_context *mac, uint32_t tim return; } - if (tx_timer_deactivate(&mac->lim.limTimers.gpLimCnfWaitTimer[staId]) + if (tx_timer_deactivate(&mac->lim.lim_timers.gpLimCnfWaitTimer[staId]) != TX_SUCCESS) { pe_err("unable to deactivate CNF wait timer"); } @@ -777,7 +778,7 @@ lim_deactivate_and_change_per_sta_id_timer(struct mac_context *mac, uint32_t tim val = SYS_MS_TO_TICKS(val); if (tx_timer_change - (&mac->lim.limTimers.gpLimCnfWaitTimer[staId], val, + (&mac->lim.lim_timers.gpLimCnfWaitTimer[staId], val, val) != TX_SUCCESS) { /* Could not change cnf timer. */ /* Log error */ @@ -851,9 +852,9 @@ lim_deactivate_and_change_per_sta_id_timer(struct mac_context *mac, uint32_t tim void lim_activate_cnf_timer(struct mac_context *mac, uint16_t staId, struct pe_session *pe_session) { - mac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId = + mac->lim.lim_timers.gpLimCnfWaitTimer[staId].sessionId = pe_session->peSessionId; - if (tx_timer_activate(&mac->lim.limTimers.gpLimCnfWaitTimer[staId]) + if (tx_timer_activate(&mac->lim.lim_timers.gpLimCnfWaitTimer[staId]) != TX_SUCCESS) { pe_err("could not activate cnf wait timer"); } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_trace.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_trace.c index abb301eedcd99de39d26d0cac9b062d29b554e82..3077b816a5bcd0d7a4ed5a6039dea58714c82012 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_trace.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_trace.c @@ -116,138 +116,138 @@ void lim_trace_dump(void *mac, tp_qdf_trace_record pRecord, switch (pRecord->code) { case TRACE_CODE_MLM_STATE: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "MLM State:", - lim_trace_get_mlm_state_string( - (uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "MLM State:", + lim_trace_get_mlm_state_string( + (uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_SME_STATE: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "SME State:", - lim_trace_get_sme_state_string( - (uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "SME State:", + lim_trace_get_sme_state_string( + (uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_TX_MGMT: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "TX Mgmt:", frameSubtypeStr[pRecord->data], - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "TX Mgmt:", frameSubtypeStr[pRecord->data], + pRecord->data); break; case TRACE_CODE_RX_MGMT: if (LIM_TRACE_MAX_SUBTYPES <= LIM_TRACE_GET_SUBTYPE(pRecord->data)) pe_nofl_debug("Wrong Subtype - %d", - LIM_TRACE_GET_SUBTYPE(pRecord->data)); + LIM_TRACE_GET_SUBTYPE(pRecord->data)); else pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(%d) SN: %d", - recIndex, pRecord->qtime, pRecord->time, - pRecord->session, "RX Mgmt:", - frameSubtypeStr[LIM_TRACE_GET_SUBTYPE + recIndex, pRecord->qtime, pRecord->time, + pRecord->session, "RX Mgmt:", + frameSubtypeStr[LIM_TRACE_GET_SUBTYPE (pRecord->data)], - LIM_TRACE_GET_SUBTYPE(pRecord->data), - LIM_TRACE_GET_SSN(pRecord->data)); + LIM_TRACE_GET_SUBTYPE(pRecord->data), + LIM_TRACE_GET_SSN(pRecord->data)); break; case TRACE_CODE_RX_MGMT_DROP: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(%d)", - recIndex, pRecord->qtime, pRecord->time, - pRecord->session, "Drop RX Mgmt:", - __lim_trace_get_mgmt_drop_reason_string( - (uint16_t) pRecord->data), - pRecord->data); + recIndex, pRecord->qtime, pRecord->time, + pRecord->session, "Drop RX Mgmt:", + __lim_trace_get_mgmt_drop_reason_string( + (uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_RX_MGMT_TSF: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s0x%x(%d)", - recIndex, pRecord->qtime, pRecord->time, - pRecord->session, "RX Mgmt TSF:", " ", - pRecord->data, pRecord->data); + recIndex, pRecord->qtime, pRecord->time, + pRecord->session, "RX Mgmt TSF:", " ", + pRecord->data, pRecord->data); break; case TRACE_CODE_TX_COMPLETE: pe_nofl_debug("%04d %012llu %s S%d %-14s %d", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "TX Complete", pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "TX Complete", pRecord->data); break; case TRACE_CODE_TX_SME_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "TX SME Msg:", - mac_trace_get_sme_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "TX SME Msg:", + mac_trace_get_sme_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_RX_SME_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - LIM_TRACE_GET_DEFRD_OR_DROPPED( - pRecord->data) ? "Def/Drp LIM Msg:" : "RX Sme Msg:", - mac_trace_get_sme_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED( + pRecord->data) ? "Def/Drp LIM Msg:" : "RX Sme Msg:", + mac_trace_get_sme_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_TX_WMA_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "TX WMA Msg:", - mac_trace_get_wma_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "TX WMA Msg:", + mac_trace_get_wma_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_RX_WMA_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - LIM_TRACE_GET_DEFRD_OR_DROPPED( - pRecord->data) ? "Def/Drp LIM Msg:" : "RX WMA Msg:", - mac_trace_get_wma_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED( + pRecord->data) ? "Def/Drp LIM Msg:" : "RX WMA Msg:", + mac_trace_get_wma_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_TX_LIM_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "TX LIM Msg:", - mac_trace_get_lim_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "TX LIM Msg:", + mac_trace_get_lim_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_RX_LIM_MSG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - LIM_TRACE_GET_DEFRD_OR_DROPPED( - pRecord->data) ? "Def/Drp LIM Msg:" : "RX LIM Msg", - mac_trace_get_lim_msg_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED( + pRecord->data) ? "Def/Drp LIM Msg:" : "RX LIM Msg", + mac_trace_get_lim_msg_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_TIMER_ACTIVATE: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "Timer Actvtd", - __lim_trace_get_timer_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "Timer Actvtd", + __lim_trace_get_timer_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_TIMER_DEACTIVATE: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", recIndex, - pRecord->qtime, pRecord->time, pRecord->session, - "Timer DeActvtd", - __lim_trace_get_timer_string((uint16_t) pRecord->data), - pRecord->data); + pRecord->qtime, pRecord->time, pRecord->session, + "Timer DeActvtd", + __lim_trace_get_timer_string((uint16_t)pRecord->data), + pRecord->data); break; case TRACE_CODE_INFO_LOG: pe_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", - recIndex, pRecord->qtime, pRecord->time, - pRecord->session, "INFORMATION_LOG", - mac_trace_get_info_log_string((uint16_t) pRecord->data), - pRecord->data); + recIndex, pRecord->qtime, pRecord->time, + pRecord->session, "INFORMATION_LOG", + mac_trace_get_info_log_string((uint16_t)pRecord->data), + pRecord->data); break; default: pe_nofl_debug("%04d %012llu %s S%d %-14s(%d) (0x%x)", - recIndex, pRecord->qtime, pRecord->time, - pRecord->session, "Unknown Code", - pRecord->code, pRecord->data); + recIndex, pRecord->qtime, pRecord->time, + pRecord->session, "Unknown Code", + pRecord->code, pRecord->data); break; } } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_types.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_types.h index 085f3d390e3d11c13e88f0dc183dfdb3f8cb5c95..cb6fe99cef80771d79f6509148a189170d8149bd 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_types.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_types.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -74,7 +75,6 @@ #define LIM_MLM_TSPEC_REQ (LIM_MLM_MSG_START + 20) #define LIM_MLM_TSPEC_CNF (LIM_MLM_MSG_START + 21) #define LIM_MLM_TSPEC_IND (LIM_MLM_MSG_START + 22) -#define LIM_MLM_SETKEYS_REQ (LIM_MLM_MSG_START + 23) #define LIM_MLM_SETKEYS_CNF (LIM_MLM_MSG_START + 24) #define LIM_MLM_LINK_TEST_STOP_REQ (LIM_MLM_MSG_START + 30) #define LIM_MLM_PURGE_STA_IND (LIM_MLM_MSG_START + 31) @@ -158,7 +158,7 @@ typedef struct sLimMlmStartReq { tSirMacBeaconInterval beaconPeriod; uint8_t dtimPeriod; tSirMacCfParamSet cfParamSet; - tSirMacChanNum channelNumber; + uint32_t oper_ch_freq; ePhyChanBondState cbMode; tSirMacRateSet rateSet; uint8_t sessionId; /* Added For BT-AMP Support */ @@ -341,7 +341,8 @@ typedef struct sLimMlmSetKeysCnf { bool lim_process_sme_req_messages(struct mac_context *, struct scheduler_msg *); void lim_process_mlm_req_messages(struct mac_context *, struct scheduler_msg *); void lim_process_mlm_rsp_messages(struct mac_context *, uint32_t, uint32_t *); -void lim_process_sme_del_bss_rsp(struct mac_context *, uint32_t, struct pe_session *); +void lim_process_sme_del_bss_rsp(struct mac_context *mac, + struct pe_session *pe_session); /** * lim_process_mlm_start_cnf(): called to processes MLM_START_CNF message from @@ -420,12 +421,24 @@ bool lim_fill_lim_assoc_ind_params( tpDphHashNode sta_ds, struct pe_session *session_entry); +/** + * lim_sae_auth_cleanup_retry() - API to cleanup sae auth frmae stored + * and deactivate the timer + * @mac_ctx: Pointer to mac context + * @vdev_id: vdev id + * + * Return: none + */ +void lim_sae_auth_cleanup_retry(struct mac_context *mac_ctx, + uint8_t vdev_id); + /** * lim_fill_sme_assoc_ind_params() - Initialize association indication * @mac_ctx: Pointer to Global MAC structure * @assoc_ind: PE association indication structure * @sme_assoc_ind: SME association indication * @session_entry: PE session entry + * @assoc_req_alloc: malloc memory for assoc_req or not * * Return: None */ @@ -433,7 +446,8 @@ void lim_fill_sme_assoc_ind_params( struct mac_context *mac_ctx, tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind, - struct pe_session *session_entry); + struct pe_session *session_entry, bool assoc_req_alloc); + /** * lim_send_mlm_assoc_ind() - Sends assoc indication to SME * @mac_ctx: Global Mac context @@ -446,8 +460,8 @@ lim_fill_sme_assoc_ind_params( * Return: QDF_STATUS */ QDF_STATUS lim_send_mlm_assoc_ind(struct mac_context *mac, - tpDphHashNode sta, - struct pe_session *pe_session); + tpDphHashNode sta, + struct pe_session *pe_session); void lim_process_assoc_rsp_frame(struct mac_context *, uint8_t *, uint8_t, struct pe_session *); void lim_process_disassoc_frame(struct mac_context *, uint8_t *, struct pe_session *); @@ -500,8 +514,8 @@ void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pRxMe void lim_populate_mac_header(struct mac_context *, uint8_t *, uint8_t, uint8_t, tSirMacAddr, tSirMacAddr); QDF_STATUS lim_send_probe_req_mgmt_frame(struct mac_context *, tSirMacSSid *, - tSirMacAddr, uint8_t, tSirMacAddr, - uint32_t, uint16_t *, uint8_t *); + tSirMacAddr, qdf_freq_t, tSirMacAddr, + uint32_t, uint16_t *, uint8_t *); /** * lim_send_probe_rsp_mgmt_frame() - Send probe response @@ -634,8 +648,15 @@ void lim_send_disassoc_mgmt_frame(struct mac_context *, uint16_t, tSirMacAddr, void lim_send_deauth_mgmt_frame(struct mac_context *, uint16_t, tSirMacAddr, struct pe_session *, bool waitForAck); +/** + * lim_process_mlm_update_hidden_ssid_rsp() - process hidden ssid response + * @mac_ctx: global mac context + * @vdev_id: vdev id + * + * Return: None + */ void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *msg); + uint8_t vdev_id); tSirResultCodes lim_mlm_add_bss(struct mac_context *, tLimMlmStartReq *, struct pe_session *pe_session); @@ -732,10 +753,8 @@ QDF_STATUS lim_process_sme_tdls_add_sta_req(struct mac_context *mac, QDF_STATUS lim_process_sme_tdls_del_sta_req(struct mac_context *mac, void *msg); -void lim_send_sme_mgmt_tx_completion( - struct mac_context *mac, - uint32_t sme_session_id, - uint32_t txCompleteStatus); +void lim_send_sme_mgmt_tx_completion(struct mac_context *mac, uint32_t vdev_id, + uint32_t txCompleteStatus); QDF_STATUS lim_delete_tdls_peers(struct mac_context *mac_ctx, struct pe_session *session_entry); QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg, struct pe_session *); @@ -795,14 +814,6 @@ void lim_tear_down_link_with_ap(struct mac_context *mac, /* / Function that defers the messages received */ uint32_t lim_defer_msg(struct mac_context *, struct scheduler_msg *); -/* / Function that Switches the Channel and sets the CB Mode */ -void lim_set_channel(struct mac_context *mac, uint8_t channel, - uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width, int8_t maxTxPower, - uint8_t peSessionId, uint32_t cac_duration_ms, - uint32_t dfs_regdomain); - - #ifdef ANI_SUPPORT_11H /* / Function that sends Measurement Report action frame */ QDF_STATUS lim_send_meas_report_frame(struct mac_context *, tpSirMacMeasReqActionFrame, @@ -813,33 +824,64 @@ QDF_STATUS lim_send_tpc_report_frame(struct mac_context *, tpSirMacTpcReqActionF tSirMacAddr, struct pe_session *pe_session); #endif -/* Function(s) to handle responses received from HAL */ -void lim_process_mlm_add_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ); +/** + * lim_handle_add_bss_rsp() - Handle add bss response + * @mac_ctx: mac context + * @add_bss_rsp: add bss rsp + * + * This function is called to handle all types of add bss rsp + * It will free memory of add_bss_rsp in the end after rsp is handled. + * + * Return: None + */ +void lim_handle_add_bss_rsp(struct mac_context *mac_ctx, + struct add_bss_rsp *add_bss_rsp); + void lim_process_mlm_add_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQt, struct pe_session *pe_session); void lim_process_mlm_del_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ); + +/** + * lim_process_mlm_del_bss_rsp () - API to process delete bss response + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to vdev stop response + * @pe_session: pointer to pe_session + * + * Return: None + */ void lim_process_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, - struct pe_session *); + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session); + void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ, struct pe_session *pe_session); void lim_process_sta_mlm_del_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ, struct pe_session *pe_session); + +/** + * lim_process_sta_mlm_del_bss_rsp() - handle del bss response of STA + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to vdev stop response + * @pe_session: pointer to pe_session + * + * Return: none + */ void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, + struct del_bss_resp *vdev_stop_rsp, struct pe_session *pe_session); + void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ); void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ); /* Function to process WMA_SWITCH_CHANNEL_RSP message */ -void lim_process_switch_channel_rsp(struct mac_context *mac, void *); +void lim_process_switch_channel_rsp(struct mac_context *mac, + struct vdev_start_response *rsp); /** * lim_sta_handle_connect_fail() - handle connect failure of STA @@ -849,7 +891,28 @@ void lim_process_switch_channel_rsp(struct mac_context *mac, void *); */ QDF_STATUS lim_sta_handle_connect_fail(join_params *param); +/** + * lim_join_result_callback() - Callback to handle join rsp + * @mac: Pointer to Global MAC structure + * @vdev_id: vdev id + * + * This callback function is used to delete PE session + * entry and send join response to sme. + * + * Return: None + */ +void lim_join_result_callback(struct mac_context *mac, + uint8_t vdev_id); + +#ifdef WLAN_FEATURE_HOST_ROAM QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param); +#else +static inline +QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif #ifdef WLAN_FEATURE_11W /* 11w send SA query request action frame */ @@ -1179,6 +1242,27 @@ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx); void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, uint32_t msg_type); +/** + * lim_process_sae_auth_timeout() - This function is called to process sae + * auth timeout + * @mac_ctx: Pointer to Global MAC structure + * + * @Return: None + */ +void lim_process_sae_auth_timeout(struct mac_context *mac_ctx); + +/** + * lim_send_frame() - API to send frame + * @mac_ctx Pointer to Global MAC structure + * @vdev_id: vdev id + * @buf: Pointer to SAE auth retry frame + * @buf_len: length of frame + * + * Return: None + */ +void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf, + uint16_t buf_len); + /** * lim_send_mgmt_frame_tx() - Sends mgmt frame * @mac_ctx Pointer to Global MAC structure @@ -1309,6 +1393,7 @@ void lim_process_assoc_cleanup(struct mac_context *mac_ctx, * @pmf_connection: flag indicating pmf connection * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above * @dup_entry: flag indicating if duplicate entry found + * @force_1x1: flag to indicate if the STA nss needs to be downgraded to 1x1 * * Return: void */ @@ -1320,5 +1405,22 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, enum ani_akm_type akm_type, bool pmf_connection, bool *assoc_req_copied, - bool dup_entry); + bool dup_entry, bool force_1x1); + +/** + * lim_process_sta_add_bss_rsp_pre_assoc - Processes handoff request + * @mac_ctx: Pointer to mac context + * @pAddBssParams: Bss params including rsp data + * @session_entry: PE session handle + * @status: Qdf status + * + * This function is called to process a WMA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL if the state is pre assoc. + * + * Return: Null + */ +void lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, + struct bss_params *add_bss_params, + struct pe_session *session_entry, + QDF_STATUS status); #endif /* __LIM_TYPES_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.c index 0b3c3a9d7667a0ff886080fbbdcd675d65b19eeb..f4ad67174fdd2bbdda221f8a3eec3319e2d3ffb0 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,7 +35,6 @@ #include "lim_send_messages.h" #include "lim_ser_des_utils.h" #include "lim_admit_control.h" -#include "lim_sta_hash_api.h" #include "dot11f.h" #include "dot11fdefs.h" #include "wmm_apsd.h" @@ -70,6 +70,7 @@ #include #include #include +#include "wlan_mlme_ucfg_api.h" #define ASCII_SPACE_CHARACTER 0x20 @@ -274,8 +275,6 @@ char *lim_msg_str(uint32_t msgType) return "eWNI_SME_JOIN_REQ"; case eWNI_SME_JOIN_RSP: return "eWNI_SME_JOIN_RSP"; - case eWNI_SME_SETCONTEXT_REQ: - return "eWNI_SME_SETCONTEXT_REQ"; case eWNI_SME_SETCONTEXT_RSP: return "eWNI_SME_SETCONTEXT_RSP"; case eWNI_SME_REASSOC_REQ: @@ -362,6 +361,8 @@ char *lim_msg_str(uint32_t msgType) return "eWNI_SME_SET_HW_MODE_RESP"; case eWNI_SME_HW_MODE_TRANS_IND: return "eWNI_SME_HW_MODE_TRANS_IND"; + case SIR_LIM_PROCESS_DEFERRED_QUEUE: + return "SIR_LIM_PROCESS_DEFERRED_QUEUE"; default: return "Unknown"; } @@ -477,7 +478,7 @@ QDF_STATUS lim_init_mlm(struct mac_context *mac) void lim_deactivate_timers(struct mac_context *mac_ctx) { uint32_t n; - tLimTimers *lim_timer = &mac_ctx->lim.limTimers; + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; lim_deactivate_timers_host_roam(mac_ctx); @@ -510,7 +511,7 @@ void lim_deactivate_timers(struct mac_context *mac_ctx) /* Deactivate Association failure timer. */ tx_timer_deactivate(&lim_timer->gLimAssocFailureTimer); - if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)) { + if (tx_timer_running(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer)) { pe_err("Auth failure timer running call the timeout API"); /* Cleanup as if auth timer expired */ lim_timer_handler(mac_ctx, SIR_LIM_AUTH_FAIL_TIMEOUT); @@ -544,9 +545,76 @@ void lim_deactivate_timers(struct mac_context *mac_ctx) } tx_timer_deactivate(&lim_timer->gLimDeauthAckTimer); + if (tx_timer_running(&lim_timer->sae_auth_timer)) { + pe_err("SAE Auth failure timer running call the timeout API"); + /* Cleanup as if SAE auth timer expired */ + lim_timer_handler(mac_ctx, SIR_LIM_AUTH_SAE_TIMEOUT); + } + tx_timer_deactivate(&lim_timer->sae_auth_timer); } +void lim_deactivate_timers_for_vdev(struct mac_context *mac_ctx, + uint8_t vdev_id) +{ + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; + struct pe_session *pe_session; + + pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); + if (!pe_session) { + pe_err("pe session invalid for vdev %d", vdev_id); + return; + } + pe_debug("pe limMlmState %s vdev %d", + lim_mlm_state_str(pe_session->limMlmState), + vdev_id); + switch (pe_session->limMlmState) { + case eLIM_MLM_WT_JOIN_BEACON_STATE: + if (tx_timer_running( + &lim_timer->gLimJoinFailureTimer)) { + pe_debug("Trigger Join failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimJoinFailureTimer); + lim_process_join_failure_timeout(mac_ctx); + } + break; + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + if (tx_timer_running( + &lim_timer->gLimAuthFailureTimer)) { + pe_debug("Trigger Auth failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimAuthFailureTimer); + lim_process_auth_failure_timeout(mac_ctx); + } + break; + case eLIM_MLM_WT_ASSOC_RSP_STATE: + if (tx_timer_running( + &lim_timer->gLimAssocFailureTimer)) { + pe_debug("Trigger Assoc failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimAssocFailureTimer); + lim_process_assoc_failure_timeout(mac_ctx, + LIM_ASSOC); + } + break; + case eLIM_MLM_WT_SAE_AUTH_STATE: + if (tx_timer_running(&lim_timer->sae_auth_timer)) { + pe_debug("Trigger SAE Auth failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->sae_auth_timer); + lim_process_sae_auth_timeout(mac_ctx); + } + break; + default: + return; + } +} + /** * lim_cleanup_mlm() - This function is called to cleanup @@ -565,7 +633,7 @@ void lim_cleanup_mlm(struct mac_context *mac_ctx) tLimTimers *lim_timer = NULL; if (mac_ctx->lim.gLimTimersCreated == 1) { - lim_timer = &mac_ctx->lim.limTimers; + lim_timer = &mac_ctx->lim.lim_timers; lim_deactivate_timers(mac_ctx); @@ -640,7 +708,7 @@ void lim_cleanup_mlm(struct mac_context *mac_ctx) void lim_print_mac_addr(struct mac_context *mac, tSirMacAddr macAddr, uint8_t logLevel) { - pe_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macAddr)); + pe_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(macAddr)); } /****** end lim_print_mac_addr() ******/ /* @@ -763,8 +831,8 @@ uint8_t lim_write_deferred_msg_q(struct mac_context *mac_ctx, * We reach the quota for management frames, * drop this one */ - pe_warn("Too many queue->MsgQ Msg: %d count: %d", - lim_msg->type, count); + pe_warn_rl("Too many queue->MsgQ Msg: %d count: %d", + lim_msg->type, count); /* Return error, caller knows what to do */ return TX_QUEUE_FULL; } @@ -882,7 +950,7 @@ void lim_handle_update_olbc_cache(struct mac_context *mac_ctx) return; } qdf_mem_zero((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams)); - beaconParams.bss_idx = pe_session->bss_idx; + beaconParams.bss_idx = pe_session->vdev_id; beaconParams.paramChangeBitmap = 0; /* @@ -939,7 +1007,7 @@ void lim_handle_update_olbc_cache(struct mac_context *mac_ctx) lim_send_beacon_params(mac_ctx, &beaconParams, pe_session); } /* Start OLBC timer */ - if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimUpdateOlbcCacheTimer) + if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) pe_err("tx_timer_activate failed"); } @@ -1083,7 +1151,7 @@ lim_decide_ap_protection(struct mac_context *mac, tSirMacAddr peerMacAddr, { uint16_t tmpAid; tpDphHashNode sta; - enum band_info rfBand = BAND_UNKNOWN; + enum reg_wifi_band rfBand = REG_BAND_UNKNOWN; uint32_t phyMode; tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; @@ -1100,7 +1168,7 @@ lim_decide_ap_protection(struct mac_context *mac, tSirMacAddr peerMacAddr, } lim_get_rf_band_new(mac, &rfBand, pe_session); /* if we are in 5 GHZ band */ - if (BAND_5G == rfBand) { + if (REG_BAND_5G == rfBand) { /* We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. */ /* HT20 case is common between both the bands and handled down as common code. */ if (true == pe_session->htCapability) { @@ -1113,7 +1181,7 @@ lim_decide_ap_protection(struct mac_context *mac, tSirMacAddr peerMacAddr, return; } } - } else if (BAND_2G == rfBand) { + } else if (REG_BAND_2G == rfBand) { lim_get_phy_mode(mac, &phyMode, pe_session); /* We are 11G. Check if we need protection from 11b Stations. */ @@ -1466,13 +1534,13 @@ lim_decide_sta_protection_on_assoc(struct mac_context *mac, tpSchBeaconStruct pBeaconStruct, struct pe_session *pe_session) { - enum band_info rfBand = BAND_UNKNOWN; + enum reg_wifi_band rfBand = REG_BAND_UNKNOWN; uint32_t phyMode = WNI_CFG_PHY_MODE_NONE; lim_get_rf_band_new(mac, &rfBand, pe_session); lim_get_phy_mode(mac, &phyMode, pe_session); - if (BAND_5G == rfBand) { + if (REG_BAND_5G == rfBand) { if ((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) || (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode)) { @@ -1484,7 +1552,7 @@ lim_decide_sta_protection_on_assoc(struct mac_context *mac, pe_session->beaconParams.ht20Coexist = true; } - } else if (BAND_2G == rfBand) { + } else if (REG_BAND_2G == rfBand) { /* spec 7.3.2.13 */ /* UseProtection will be set when nonERP STA is associated. */ /* NonERPPresent bit will be set when: */ @@ -1701,13 +1769,13 @@ lim_decide_sta_protection(struct mac_context *mac_ctx, struct pe_session *psession_entry) { - enum band_info rfband = BAND_UNKNOWN; + enum reg_wifi_band rfband = REG_BAND_UNKNOWN; uint32_t phy_mode = WNI_CFG_PHY_MODE_NONE; lim_get_rf_band_new(mac_ctx, &rfband, psession_entry); lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry); - if ((BAND_5G == rfband) && + if ((REG_BAND_5G == rfband) && /* we are HT capable. */ (true == psession_entry->htCapability) && (beacon_struct->HTInfo.present)) { @@ -1743,7 +1811,7 @@ lim_decide_sta_protection(struct mac_context *mac_ctx, false, beaconparams, psession_entry); } - } else if (BAND_2G == rfband) { + } else if (REG_BAND_2G == rfband) { lim_decide_sta_11bg_protection(mac_ctx, beacon_struct, beaconparams, psession_entry, phy_mode); } @@ -1821,7 +1889,7 @@ lim_decide_sta_protection(struct mac_context *mac_ctx, static void __lim_process_channel_switch_timeout(struct pe_session *pe_session) { struct mac_context *mac; - uint8_t channel; /* This is received and stored from channelSwitch Action frame */ + uint32_t channel_freq; if (!pe_session) { pe_err("Invalid pe session"); @@ -1846,7 +1914,7 @@ static void __lim_process_channel_switch_timeout(struct pe_session *pe_session) return; } - channel = pe_session->gLimChannelSwitch.primaryChannel; + channel_freq = pe_session->gLimChannelSwitch.sw_target_freq; /* Restore Channel Switch parameters to default */ pe_session->gLimChannelSwitch.switchTimeoutValue = 0; @@ -1857,7 +1925,7 @@ static void __lim_process_channel_switch_timeout(struct pe_session *pe_session) * Else, just don't bother to switch. Indicate HDD to look for a * better AP to associate */ - if (!lim_is_channel_valid_for_channel_switch(mac, channel)) { + if (!lim_is_channel_valid_for_channel_switch(mac, channel_freq)) { /* We need to restore pre-channelSwitch state on the STA */ if (lim_restore_pre_channel_switch_state(mac, pe_session) != QDF_STATUS_SUCCESS) { @@ -1866,34 +1934,28 @@ static void __lim_process_channel_switch_timeout(struct pe_session *pe_session) } /* - * If the channel-list that AP is asking us to switch is invalid - * then we cannot switch the channel. Just disassociate from AP. - * We will find a better AP !!! + * The channel switch request received from AP is carrying + * invalid channel. It's ok to ignore this channel switch + * request as it might be from spoof AP. If it's from genuine + * AP, it may lead to heart beat failure and result in + * disconnection. DUT can go ahead and reconnect to it/any + * other AP once it disconnects. */ - if ((pe_session->limMlmState == - eLIM_MLM_LINK_ESTABLISHED_STATE) && - (pe_session->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && - (pe_session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) { - pe_err("Invalid channel! Disconnect"); - lim_tear_down_link_with_ap(mac, - mac->lim.limTimers. - gLimChannelSwitchTimer.sessionId, - eSIR_MAC_UNSUPPORTED_CHANNEL_CSA, - eLIM_LINK_MONITORING_DISASSOC); - return; - } + pe_err("Invalid channel freq %u Ignore CSA request", + channel_freq); + return; } switch (pe_session->gLimChannelSwitch.state) { case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY: lim_switch_primary_channel(mac, pe_session->gLimChannelSwitch. - primaryChannel, pe_session); + sw_target_freq, pe_session); pe_session->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; break; case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY: lim_switch_primary_secondary_channel(mac, pe_session, - pe_session->gLimChannelSwitch.primaryChannel, + pe_session->gLimChannelSwitch.sw_target_freq, pe_session->gLimChannelSwitch.ch_center_freq_seg0, pe_session->gLimChannelSwitch.ch_center_freq_seg1, pe_session->gLimChannelSwitch.ch_width); @@ -1942,7 +2004,7 @@ void lim_process_channel_switch_timeout(struct mac_context *mac_ctx) session_entry = pe_find_session_by_session_id( mac_ctx, - mac_ctx->lim.limTimers.gLimChannelSwitchTimer.sessionId); + mac_ctx->lim.lim_timers.gLimChannelSwitchTimer.sessionId); if (!session_entry) { pe_err("Session does not exist for given sessionID"); return; @@ -1988,6 +2050,9 @@ lim_update_channel_switch(struct mac_context *mac_ctx, ch_switch_params = &psession_entry->gLimChannelSwitch; ch_switch_params->primaryChannel = chnl_switch->newChannel; + ch_switch_params->sw_target_freq = + wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + chnl_switch->newChannel); ch_switch_params->switchCount = chnl_switch->switchCount; ch_switch_params->switchTimeoutValue = SYS_MS_TO_TICKS(beacon_period) * (chnl_switch->switchCount); @@ -2042,12 +2107,13 @@ lim_update_channel_switch(struct mac_context *mac_ctx, if (QDF_STATUS_SUCCESS != lim_start_channel_switch(mac_ctx, psession_entry)) pe_warn("Could not start Channel Switch"); - pe_debug("session: %d primary chl: %d ch_width: %d count: %d (%d ticks)", - psession_entry->peSessionId, - psession_entry->gLimChannelSwitch.primaryChannel, - psession_entry->gLimChannelSwitch.ch_width, - psession_entry->gLimChannelSwitch.switchCount, - psession_entry->gLimChannelSwitch.switchTimeoutValue); + pe_debug("session: %d primary chl: %d freq %d ch_width: %d count: %d (%d ticks)", + psession_entry->peSessionId, + psession_entry->gLimChannelSwitch.primaryChannel, + psession_entry->gLimChannelSwitch.sw_target_freq, + psession_entry->gLimChannelSwitch.ch_width, + psession_entry->gLimChannelSwitch.switchCount, + psession_entry->gLimChannelSwitch.switchTimeoutValue); return; } @@ -2081,7 +2147,7 @@ void lim_cancel_dot11h_channel_switch(struct mac_context *mac, (mac, TRACE_CODE_TIMER_DEACTIVATE, pe_session->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); - if (tx_timer_deactivate(&mac->lim.limTimers.gLimChannelSwitchTimer) != + if (tx_timer_deactivate(&mac->lim.lim_timers.gLimChannelSwitchTimer) != QDF_STATUS_SUCCESS) { pe_err("tx_timer_deactivate failed!"); } @@ -2188,9 +2254,21 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status, { struct scheduler_msg mmhMsg = { 0 }; struct switch_channel_ind *pSirSmeSwitchChInd; + struct wlan_channel *des_chan; + struct vdev_mlme_obj *mlme_obj; - pe_session->currentOperChannel = pe_session->currentReqChannel; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return; + } + des_chan = mlme_obj->vdev->vdev_mlme.des_chan; + if (!des_chan) { + pe_err("des_chan is NULL"); + return; + } + pe_session->curr_op_freq = pe_session->curr_req_chan_freq; /* We need to restore pre-channelSwitch state on the STA */ if (lim_restore_pre_channel_switch_state(mac, pe_session) != QDF_STATUS_SUCCESS) { @@ -2205,17 +2283,21 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status, pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_IND; pSirSmeSwitchChInd->length = sizeof(*pSirSmeSwitchChInd); - pSirSmeSwitchChInd->newChannelId = - pe_session->gLimChannelSwitch.primaryChannel; + pSirSmeSwitchChInd->freq = des_chan->ch_freq; pSirSmeSwitchChInd->sessionId = pe_session->smeSessionId; - pSirSmeSwitchChInd->chan_params.ch_width = - pe_session->gLimChannelSwitch.ch_width; - pSirSmeSwitchChInd->chan_params.sec_ch_offset = + pSirSmeSwitchChInd->chan_params.ch_width = des_chan->ch_width; + if (des_chan->ch_width > CH_WIDTH_20MHZ) { + pSirSmeSwitchChInd->chan_params.sec_ch_offset = pe_session->gLimChannelSwitch.sec_ch_offset; - pSirSmeSwitchChInd->chan_params.center_freq_seg0 = - pe_session->gLimChannelSwitch.ch_center_freq_seg0; - pSirSmeSwitchChInd->chan_params.center_freq_seg1 = - pe_session->gLimChannelSwitch.ch_center_freq_seg1; + pSirSmeSwitchChInd->chan_params.center_freq_seg0 = + des_chan->ch_freq_seg1; + pSirSmeSwitchChInd->chan_params.mhz_freq_seg0 = + des_chan->ch_cfreq1; + pSirSmeSwitchChInd->chan_params.center_freq_seg1 = + des_chan->ch_freq_seg2; + pSirSmeSwitchChInd->chan_params.mhz_freq_seg1 = + des_chan->ch_cfreq2; + } pSirSmeSwitchChInd->status = status; qdf_mem_copy(pSirSmeSwitchChInd->bssid.bytes, pe_session->bssId, @@ -2232,83 +2314,49 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status, lim_switch_channel_vdev_started(pe_session); } -/** - * lim_switch_primary_channel() - * - ***FUNCTION: - * This function changes the current operating channel - * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL. - * - ***NOTE: - * @param mac Pointer to Global MAC structure - * @param newChannel new chnannel ID - * @return NONE - */ -void lim_switch_primary_channel(struct mac_context *mac, uint8_t newChannel, +void lim_switch_primary_channel(struct mac_context *mac, + uint32_t new_channel_freq, struct pe_session *pe_session) { - pe_debug("chan: %d --> chan: %d", - pe_session->currentOperChannel, newChannel); + pe_debug("freq: %d --> freq: %d", pe_session->curr_op_freq, + new_channel_freq); - pe_session->currentReqChannel = newChannel; - pe_session->limRFBand = lim_get_rf_band(newChannel); + pe_session->curr_req_chan_freq = new_channel_freq; + pe_session->curr_op_freq = pe_session->curr_req_chan_freq; + pe_session->ch_center_freq_seg0 = 0; + pe_session->ch_center_freq_seg1 = 0; + pe_session->ch_width = CH_WIDTH_20MHZ; + pe_session->limRFBand = lim_get_rf_band(pe_session->curr_req_chan_freq); pe_session->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION; mac->lim.gpchangeChannelCallback = lim_switch_channel_cback; mac->lim.gpchangeChannelData = NULL; - lim_send_switch_chnl_params(mac, newChannel, 0, 0, CH_WIDTH_20MHZ, - pe_session->maxTxPower, - pe_session->peSessionId, false, 0, 0); + lim_send_switch_chnl_params(mac, pe_session); return; } -/** - * lim_switch_primary_secondary_channel() - * - ***FUNCTION: - * This function changes the primary and secondary channel. - * If 11h is enabled and user provides a "new channel ID" - * that is different from the current operating channel, - * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL, - * assign notify LIM of such change. - * - ***NOTE: - * @param mac Pointer to Global MAC structure - * @param newChannel New chnannel ID (or current channel ID) - * @param subband CB secondary info: - * - eANI_CB_SECONDARY_NONE - * - eANI_CB_SECONDARY_UP - * - eANI_CB_SECONDARY_DOWN - * @return NONE - */ void lim_switch_primary_secondary_channel(struct mac_context *mac, - struct pe_session *pe_session, - uint8_t newChannel, - uint8_t ch_center_freq_seg0, - uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width) + struct pe_session *pe_session, + uint32_t new_channel_freq, + uint8_t ch_center_freq_seg0, + uint8_t ch_center_freq_seg1, + enum phy_ch_width ch_width) { /* Assign the callback to resume TX once channel is changed. */ - pe_session->currentReqChannel = newChannel; - pe_session->limRFBand = lim_get_rf_band(newChannel); + pe_session->curr_req_chan_freq = new_channel_freq; + pe_session->limRFBand = lim_get_rf_band(pe_session->curr_req_chan_freq); pe_session->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION; mac->lim.gpchangeChannelCallback = lim_switch_channel_cback; mac->lim.gpchangeChannelData = NULL; - lim_send_switch_chnl_params(mac, newChannel, ch_center_freq_seg0, - ch_center_freq_seg1, ch_width, - pe_session->maxTxPower, - pe_session->peSessionId, - false, 0, 0); - /* Store the new primary and secondary channel in session entries if different */ - if (pe_session->currentOperChannel != newChannel) { - pe_warn("chan: %d --> chan: %d", - pe_session->currentOperChannel, newChannel); - pe_session->currentOperChannel = newChannel; + if (pe_session->curr_op_freq != new_channel_freq) { + pe_warn("freq: %d --> freq: %d", pe_session->curr_op_freq, + new_channel_freq); + pe_session->curr_op_freq = new_channel_freq; } if (pe_session->htSecondaryChannelOffset != pe_session->gLimChannelSwitch.sec_ch_offset) { @@ -2329,6 +2377,12 @@ void lim_switch_primary_secondary_channel(struct mac_context *mac, pe_session->htSupportedChannelWidthSet; } + pe_session->ch_center_freq_seg0 = ch_center_freq_seg0; + pe_session->ch_center_freq_seg1 = ch_center_freq_seg1; + pe_session->ch_width = ch_width; + + lim_send_switch_chnl_params(mac, pe_session); + return; } @@ -3838,7 +3892,8 @@ static void lim_ht_switch_chnl_params(struct pe_session *pe_session) return; } - primary_channel = pe_session->currentOperChannel; + primary_channel = wlan_reg_freq_to_chan(mac->pdev, + pe_session->curr_op_freq); if (eHT_CHANNEL_WIDTH_40MHZ == pe_session->htRecommendedTxWidthSet) { ch_width = CH_WIDTH_40MHZ; @@ -3851,30 +3906,28 @@ static void lim_ht_switch_chnl_params(struct pe_session *pe_session) else ch_width = CH_WIDTH_20MHZ; } - pe_session->gLimChannelSwitch.primaryChannel = primary_channel; - pe_session->currentReqChannel = primary_channel; + pe_session->curr_req_chan_freq = pe_session->curr_op_freq; pe_session->ch_center_freq_seg0 = center_freq; pe_session->gLimChannelSwitch.ch_center_freq_seg0 = center_freq; + pe_session->gLimChannelSwitch.sw_target_freq = + pe_session->curr_op_freq; pe_session->ch_width = ch_width; pe_session->gLimChannelSwitch.ch_width = ch_width; pe_session->gLimChannelSwitch.sec_ch_offset = - pe_session->htSecondaryChannelOffset; + pe_session->htSecondaryChannelOffset; pe_session->gLimChannelSwitch.ch_center_freq_seg1 = 0; - pe_debug("HT IE changed: Primary Channel: %d center chan: %d Channel Width: %d", + pe_debug("HT IE changed: Primary Channel: %d center chan: %d Channel Width: %d cur op freq %d", primary_channel, center_freq, - pe_session->htRecommendedTxWidthSet); + pe_session->htRecommendedTxWidthSet, + pe_session->gLimChannelSwitch.sw_target_freq); pe_session->channelChangeReasonCode = LIM_SWITCH_CHANNEL_HT_WIDTH; mac->lim.gpchangeChannelCallback = lim_switch_channel_cback; mac->lim.gpchangeChannelData = NULL; - lim_send_switch_chnl_params(mac, primary_channel, - center_freq, 0, ch_width, - pe_session->maxTxPower, - pe_session->peSessionId, - true, 0, 0); + lim_send_switch_chnl_params(mac, pe_session); } static void lim_ht_switch_chnl_req(struct pe_session *session) @@ -3903,29 +3956,8 @@ static void lim_ht_switch_chnl_req(struct pe_session *session) } } -/** - * \brief This function updates lim global structure, if CB parameters in the BSS - * have changed, and sends an indication to HAL also with the - * updated HT Parameters. - * This function does not detect the change in the primary channel, that is done as part - * of channel Swtich IE processing. - * If STA is configured with '20Mhz only' mode, then this function does not do anything - * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz' - * - * - * \param mac Pointer to global MAC structure - * - * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or - * Probe Response - * - * \param bss_idx BSS Index of the Bss to which Station is associated. - * - * - */ - void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac, tDot11fIEHTInfo *pHTInfo, - uint8_t bss_idx, struct pe_session *pe_session) { /* If self capability is set to '20Mhz only', then do not change the CB mode. */ @@ -3933,8 +3965,8 @@ void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac, (mac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, pe_session)) return; - if (WLAN_REG_IS_24GHZ_CH(pe_session->currentOperChannel) && - pe_session->force_24ghz_in_ht20) { + if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq) && + pe_session->force_24ghz_in_ht20) { pe_debug("force_24ghz_in_ht20 is set and channel is 2.4 Ghz"); return; } @@ -3956,7 +3988,8 @@ void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac, } /* If channel mismatch the CSA will take care of this change */ - if (pHTInfo->primaryChannel != pe_session->currentOperChannel) { + if (pHTInfo->primaryChannel != wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq)) { pe_debug("Current channel doesnt match HT info ignore"); return; } @@ -4233,7 +4266,7 @@ lim_validate_delts_req(struct mac_context *mac_ctx, tpSirDeltsReq delts_req, } else if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) { /* send message to HAL to delete TS */ if (QDF_STATUS_SUCCESS != - lim_send_hal_msg_del_ts(mac_ctx, sta->staIndex, + lim_send_hal_msg_del_ts(mac_ctx, tspec_idx, delts_req->req, session->peSessionId, session->bssId)) { @@ -4264,7 +4297,7 @@ lim_validate_delts_req(struct mac_context *mac_ctx, tpSirDeltsReq delts_req, */ QDF_STATUS lim_post_sm_state_update(struct mac_context *mac, - uint16_t staIdx, tSirMacHTMIMOPowerSaveState state, + tSirMacHTMIMOPowerSaveState state, uint8_t *pPeerStaMac, uint8_t sessionId) { QDF_STATUS retCode = QDF_STATUS_SUCCESS; @@ -4280,7 +4313,6 @@ lim_post_sm_state_update(struct mac_context *mac, return QDF_STATUS_E_NOMEM; pMIMO_PSParams->htMIMOPSState = state; - pMIMO_PSParams->staIdx = staIdx; pMIMO_PSParams->fsendRsp = true; pMIMO_PSParams->sessionId = sessionId; qdf_mem_copy(pMIMO_PSParams->peerMac, pPeerStaMac, sizeof(tSirMacAddr)); @@ -4393,31 +4425,14 @@ void lim_add_channel_status_info(struct mac_context *p_mac, return; } -/** - * @function : lim_is_channel_valid_for_channel_switch() - * - * @brief : This function checks if the channel to which AP - * is expecting us to switch, is a valid channel for us. - * LOGIC: - * - * ASSUMPTIONS: - * NA - * - * NOTE: - * NA - * - * @param mac - Pointer to Global MAC structure - * @param channel - New channel to which we are expected to move - * @return None - */ -bool lim_is_channel_valid_for_channel_switch(struct mac_context *mac, uint8_t channel) +bool lim_is_channel_valid_for_channel_switch(struct mac_context *mac, + uint32_t channel_freq) { uint8_t index; - uint32_t validChannelListLen = CFG_VALID_CHANNEL_LIST_LEN; - tSirMacChanNum validChannelList[CFG_VALID_CHANNEL_LIST_LEN]; bool ok = false; - if (policy_mgr_is_chan_ok_for_dnbs(mac->psoc, channel, &ok)) { + if (policy_mgr_is_chan_ok_for_dnbs(mac->psoc, channel_freq, + &ok)) { pe_err("policy_mgr_is_chan_ok_for_dnbs() returned error"); return false; } @@ -4427,15 +4442,13 @@ bool lim_is_channel_valid_for_channel_switch(struct mac_context *mac, uint8_t ch return false; } - validChannelListLen = mac->mlme_cfg->reg.valid_channel_list_num; - qdf_mem_copy(validChannelList, mac->mlme_cfg->reg.valid_channel_list, - mac->mlme_cfg->reg.valid_channel_list_num); - for (index = 0; index < validChannelListLen; index++) { - if (validChannelList[index] != channel) + for (index = 0; index < mac->mlme_cfg->reg.valid_channel_list_num; index++) { + if (mac->mlme_cfg->reg.valid_channel_freq_list[index] != + channel_freq) continue; - ok = policy_mgr_is_valid_for_channel_switch(mac->psoc, - channel); + ok = policy_mgr_is_valid_for_channel_switch( + mac->psoc, channel_freq); return ok; } @@ -4508,30 +4521,20 @@ lim_prepare_for11h_channel_switch(struct mac_context *mac, struct pe_session *pe lim_stop_tx_and_switch_channel(mac, pe_session->peSessionId); } -/**---------------------------------------------------- - \fn lim_get_nw_type - - \brief Get type of the network from data packet or beacon - \param mac - \param channelNum - Channel number - \param type - Type of packet. - \param pBeacon - Pointer to beacon or probe response - - \return Network type a/b/g. - -----------------------------------------------------*/ -tSirNwType lim_get_nw_type(struct mac_context *mac, uint8_t channelNum, uint32_t type, +tSirNwType lim_get_nw_type(struct mac_context *mac, uint32_t chan_freq, uint32_t type, tpSchBeaconStruct pBeacon) { tSirNwType nwType = eSIR_11B_NW_TYPE; + /* Logic to be cleaned up for 11AC & 11AX */ if (type == SIR_MAC_DATA_FRAME) { - if ((channelNum > 0) && (channelNum < 15)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { nwType = eSIR_11G_NW_TYPE; } else { nwType = eSIR_11A_NW_TYPE; } } else { - if ((channelNum > 0) && (channelNum < 15)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { int i; /* 11b or 11g packet */ /* 11g iff extended Rate IE is present or */ @@ -4557,26 +4560,23 @@ tSirNwType lim_get_nw_type(struct mac_context *mac, uint8_t channelNum, uint32_t return nwType; } -/**--------------------------------------------------------- - \fn lim_get_channel_from_beacon - \brief To extract channel number from beacon - - \param mac - \param pBeacon - Pointer to beacon or probe rsp - \return channel number - -----------------------------------------------------------*/ -uint8_t lim_get_channel_from_beacon(struct mac_context *mac, tpSchBeaconStruct pBeacon) +uint32_t lim_get_channel_from_beacon(struct mac_context *mac, tpSchBeaconStruct pBeacon) { - uint8_t channelNum = 0; + uint8_t chan_freq = 0; - if (pBeacon->dsParamsPresent) - channelNum = pBeacon->channelNumber; + if (pBeacon->he_op.oper_info_6g_present) + chan_freq = wlan_reg_chan_band_to_freq(mac->pdev, + pBeacon->he_op.oper_info_6g.info.primary_ch, + BIT(REG_BAND_6G)); + else if (pBeacon->dsParamsPresent) + chan_freq = pBeacon->chan_freq; else if (pBeacon->HTInfo.present) - channelNum = pBeacon->HTInfo.primaryChannel; + chan_freq = wlan_reg_legacy_chan_to_freq(mac->pdev, + pBeacon->HTInfo.primaryChannel); else - channelNum = pBeacon->channelNumber; + chan_freq = pBeacon->chan_freq; - return channelNum; + return chan_freq; } void lim_set_tspec_uapsd_mask_per_session(struct mac_context *mac, @@ -4663,13 +4663,13 @@ void lim_handle_heart_beat_timeout_for_session(struct mac_context *mac_ctx, (psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) && (LIM_IS_STA_ROLE(psession_entry)) && (psession_entry->LimHBFailureStatus == true)) { - tLimTimers *lim_timer = &mac_ctx->lim.limTimers; + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; /* * Activate Probe After HeartBeat Timer incase HB * Failure detected */ pe_debug("Sending Probe for Session: %d", - psession_entry->bss_idx); + psession_entry->vdev_id); lim_deactivate_and_change_timer(mac_ctx, eLIM_PROBE_AFTER_HB_TIMER); MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 0, @@ -4813,10 +4813,11 @@ void lim_handle_heart_beat_failure_timeout(struct mac_context *mac_ctx) /* * Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer, * need not deactivate the timer - * tx_timer_deactivate(&mac->lim.limTimers.gLimProbeAfterHBTimer); + * tx_timer_deactivate(&mac->lim.lim_timers.gLimProbeAfterHBTimer); */ } +#ifdef QCA_IBSS_SUPPORT /* * This function assumes there will not be more than one IBSS session active at any time. */ @@ -4833,6 +4834,7 @@ struct pe_session *lim_is_ibss_session_active(struct mac_context *mac) return NULL; } +#endif struct pe_session *lim_is_ap_session_active(struct mac_context *mac) { @@ -4929,7 +4931,8 @@ static void lim_diag_fill_mgmt_event_report(struct mac_context *mac_ctx, length = WLAN_SSID_MAX_LEN; qdf_mem_copy(mgmt_event->ssid, session->ssId.ssId, length); mgmt_event->ssid_len = length; - mgmt_event->operating_channel = session->currentOperChannel; + mgmt_event->operating_channel = wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq); mgmt_event->result_code = result_code; mgmt_event->reason_code = reason_code; } @@ -4949,12 +4952,13 @@ void lim_diag_mgmt_tx_event_report(struct mac_context *mac_ctx, void *mgmt_hdr, lim_diag_fill_mgmt_event_report(mac_ctx, mac_hdr, session, result_code, reason_code, &mgmt_event); - pe_debug("TX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:%pM bssid:%pM channel:%d", + pe_debug("TX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:"QDF_MAC_ADDR_FMT" bssid:"QDF_MAC_ADDR_FMT" channel:%d", mgmt_event.mgmt_type, mgmt_event.mgmt_subtype, ((mac_hdr->seqControl.seqNumHi << 4) | mac_hdr->seqControl.seqNumLo), mgmt_event.ssid_len, mgmt_event.ssid, - mgmt_event.self_mac_addr, mgmt_event.bssid, + QDF_MAC_ADDR_REF(mgmt_event.self_mac_addr), + QDF_MAC_ADDR_REF(mgmt_event.bssid), mgmt_event.operating_channel); WLAN_HOST_DIAG_EVENT_REPORT(&mgmt_event, EVENT_WLAN_HOST_MGMT_TX_V2); } @@ -4973,12 +4977,13 @@ void lim_diag_mgmt_rx_event_report(struct mac_context *mac_ctx, void *mgmt_hdr, } lim_diag_fill_mgmt_event_report(mac_ctx, mac_hdr, session, result_code, reason_code, &mgmt_event); - pe_debug("RX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:%pM bssid:%pM channel:%d", + pe_debug("RX frame: type:%d sub_type:%d seq_num:%d ssid:%.*s selfmacaddr:"QDF_MAC_ADDR_FMT" bssid:"QDF_MAC_ADDR_FMT" channel:%d", mgmt_event.mgmt_type, mgmt_event.mgmt_subtype, ((mac_hdr->seqControl.seqNumHi << 4) | mac_hdr->seqControl.seqNumLo), mgmt_event.ssid_len, mgmt_event.ssid, - mgmt_event.self_mac_addr, mgmt_event.bssid, + QDF_MAC_ADDR_REF(mgmt_event.self_mac_addr), + QDF_MAC_ADDR_REF(mgmt_event.bssid), mgmt_event.operating_channel); WLAN_HOST_DIAG_EVENT_REPORT(&mgmt_event, EVENT_WLAN_HOST_MGMT_RX_V2); } @@ -5161,14 +5166,13 @@ void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param) } #endif -bool lim_check_vht_op_mode_change(struct mac_context *mac, struct pe_session *pe_session, - uint8_t chanWidth, uint8_t staId, - uint8_t *peerMac) +bool lim_check_vht_op_mode_change(struct mac_context *mac, + struct pe_session *pe_session, + uint8_t chanWidth, uint8_t *peerMac) { tUpdateVHTOpMode tempParam; tempParam.opMode = chanWidth; - tempParam.staId = staId; tempParam.smesessionId = pe_session->smeSessionId; qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr)); @@ -5193,7 +5197,7 @@ bool lim_send_he_ie_update(struct mac_context *mac_ctx, struct pe_session *pe_se #endif bool lim_set_nss_change(struct mac_context *mac, struct pe_session *pe_session, - uint8_t rxNss, uint8_t staId, uint8_t *peerMac) + uint8_t rxNss, uint8_t *peerMac) { tUpdateRxNss tempParam; @@ -5203,7 +5207,6 @@ bool lim_set_nss_change(struct mac_context *mac, struct pe_session *pe_session, } tempParam.rxNss = rxNss; - tempParam.staId = staId; tempParam.smesessionId = pe_session->smeSessionId; qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr)); @@ -5214,14 +5217,13 @@ bool lim_set_nss_change(struct mac_context *mac, struct pe_session *pe_session, bool lim_check_membership_user_position(struct mac_context *mac, struct pe_session *pe_session, - uint32_t membership, uint32_t userPosition, - uint8_t staId) + uint32_t membership, + uint32_t userPosition) { tUpdateMembership tempParamMembership; tUpdateUserPos tempParamUserPosition; tempParamMembership.membership = membership; - tempParamMembership.staId = staId; tempParamMembership.smesessionId = pe_session->smeSessionId; qdf_mem_copy(tempParamMembership.peer_mac, pe_session->bssId, sizeof(tSirMacAddr)); @@ -5229,7 +5231,6 @@ bool lim_check_membership_user_position(struct mac_context *mac, lim_set_membership(mac, &tempParamMembership, pe_session); tempParamUserPosition.userPos = userPosition; - tempParamUserPosition.staId = staId; tempParamUserPosition.smesessionId = pe_session->smeSessionId; qdf_mem_copy(tempParamUserPosition.peer_mac, pe_session->bssId, sizeof(tSirMacAddr)); @@ -5441,21 +5442,22 @@ void lim_set_vht_caps(struct mac_context *p_mac, struct pe_session *p_session_en vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap; vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern; vht_cap->txAntPattern = dot11_vht_cap.txAntPattern; - vht_cap->reserved1 = dot11_vht_cap.reserved1; + vht_cap->extended_nss_bw_supp = + dot11_vht_cap.extended_nss_bw_supp; /* Populate VHT MCS Information */ vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap; u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate = dot11_vht_cap.rxHighSupDataRate; - u_vht_data_rate_info.vht_rx_supp_rate.reserved = - dot11_vht_cap.reserved2; + u_vht_data_rate_info.vht_rx_supp_rate.max_nsts_total = + dot11_vht_cap.max_nsts_total; vht_mcs->rxHighest = u_vht_data_rate_info.u_value; vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap; u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate = dot11_vht_cap.txSupDataRate; - u_vht_data_rate_info.vht_tx_supp_rate.reserved = - dot11_vht_cap.reserved3; + u_vht_data_rate_info.vht_tx_supp_rate.vht_extended_nss_bw_cap = + dot11_vht_cap.vht_extended_nss_bw_cap; vht_mcs->txHighest = u_vht_data_rate_info.u_value; } } @@ -5554,7 +5556,7 @@ void lim_set_peer_twt_cap(struct pe_session *session, struct s_ext_cap *ext_cap) /** * lim_send_ie() - sends IE to wma * @mac_ctx: global MAC context - * @sme_session_id: sme session id + * @vdev_id: vdev_id * @eid: IE id * @band: band for which IE is intended * @buf: buffer containing IE @@ -5564,7 +5566,7 @@ void lim_set_peer_twt_cap(struct pe_session *session, struct s_ext_cap *ext_cap) * * Return: status of operation */ -static QDF_STATUS lim_send_ie(struct mac_context *mac_ctx, uint32_t sme_session_id, +static QDF_STATUS lim_send_ie(struct mac_context *mac_ctx, uint32_t vdev_id, uint8_t eid, enum cds_band_type band, uint8_t *buf, uint32_t len) { @@ -5577,7 +5579,7 @@ static QDF_STATUS lim_send_ie(struct mac_context *mac_ctx, uint32_t sme_session_ if (!ie_msg) return QDF_STATUS_E_NOMEM; - ie_msg->vdev_id = sme_session_id; + ie_msg->vdev_id = vdev_id; ie_msg->ie_id = eid; ie_msg->length = len; ie_msg->band = band; @@ -5610,10 +5612,11 @@ static QDF_STATUS lim_send_ie(struct mac_context *mac_ctx, uint32_t sme_session_ * * Return: true if enabled and false otherwise */ -static inline bool lim_get_rx_ldpc(struct mac_context *mac_ctx, enum channel_enum ch) +static inline bool lim_get_rx_ldpc(struct mac_context *mac_ctx, + enum channel_enum ch) { if (mac_ctx->mlme_cfg->ht_caps.ht_cap_info.adv_coding_cap && - wma_is_rx_ldpc_supported_for_channel(WLAN_REG_CH_NUM(ch))) + wma_is_rx_ldpc_supported_for_channel(wlan_reg_ch_to_freq(ch))) return true; else return false; @@ -5802,7 +5805,7 @@ static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx, DOT11F_IE_HTCAPS_MIN_LEN + 2); /* Get LDPC and over write for 2G */ p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx, - CHAN_ENUM_6); + CHAN_ENUM_2437); /* Get self cap for HT40 support in 2G */ if (mac_ctx->roam.configParam.channelBondingMode24GHz) { p_ht_cap->supportedChannelWidthSet = 1; @@ -5827,7 +5830,7 @@ static QDF_STATUS lim_send_ht_caps_ie(struct mac_context *mac_ctx, * Get LDPC and over write for 5G - using channel 64 because it * is available in all reg domains. */ - p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_64); + p_ht_cap->advCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_5320); /* Get self cap for HT40 support in 5G */ if (mac_ctx->roam.configParam.channelBondingMode5GHz) { p_ht_cap->supportedChannelWidthSet = 1; @@ -5878,7 +5881,7 @@ static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx, * Get LDPC and over write for 5G - using channel 64 because it * is available in all reg domains. */ - p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_64); + p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_5320); lim_populate_mcs_set_vht_per_vdev(mac_ctx, vht_caps, vdev_id, NSS_CHAINS_BAND_5GHZ); @@ -5897,7 +5900,7 @@ static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx, DOT11F_IE_VHTCAPS_MIN_LEN); /* Get LDPC and over write for 2G */ - p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_6); + p_vht_cap->ldpcCodingCap = lim_get_rx_ldpc(mac_ctx, CHAN_ENUM_2437); /* Self VHT 80/160/80+80 channel width for 2G is 0 */ p_vht_cap->supportedChannelWidthSet = 0; p_vht_cap->shortGI80MHz = 0; @@ -5915,57 +5918,38 @@ static QDF_STATUS lim_send_vht_caps_ie(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } -/** - * lim_send_ies_per_band() - gets ht and vht capability and send to firmware via - * wma - * @mac_ctx: global mac context - * @session: pe session. This can be NULL. In that case self cap will be sent - * @vdev_id: vdev for which IE is targeted - * - * This funciton gets ht and vht capability and send to firmware via wma - * - * Return: status of operation - */ QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx, - struct pe_session *session, - uint8_t vdev_id) + struct pe_session *session, uint8_t vdev_id, + enum csr_cfgdot11mode dot11_mode, + enum QDF_OPMODE device_mode) { - struct wlan_objmgr_vdev *vdev; - enum QDF_OPMODE device_mode; QDF_STATUS status_ht = QDF_STATUS_SUCCESS; QDF_STATUS status_vht = QDF_STATUS_SUCCESS; QDF_STATUS status_he = QDF_STATUS_SUCCESS; - vdev = wlan_objmgr_get_vdev_by_id_from_psoc( - mac_ctx->psoc, vdev_id, - WLAN_LEGACY_MAC_ID); - if (!vdev) { - pe_err("vdev is NULL"); - return QDF_STATUS_E_FAILURE; - } - device_mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); - /* * Note: Do not use Dot11f VHT structure, since 1 byte present flag in * it is causing weird padding errors. Instead use Sir Mac VHT struct * to send IE to wma. */ - if (is_dot11mode_support_ht_cap( - mac_ctx->roam.configParam.uCfgDot11Mode)) + if (is_dot11mode_support_ht_cap(dot11_mode)) status_ht = lim_send_ht_caps_ie(mac_ctx, session, device_mode, vdev_id); - if (is_dot11mode_support_vht_cap( - mac_ctx->roam.configParam.uCfgDot11Mode)) + if (is_dot11mode_support_vht_cap(dot11_mode)) status_vht = lim_send_vht_caps_ie(mac_ctx, session, device_mode, vdev_id); - if (is_dot11mode_support_he_cap( - mac_ctx->roam.configParam.uCfgDot11Mode)) + if (is_dot11mode_support_he_cap(dot11_mode)) { status_he = lim_send_he_caps_ie(mac_ctx, session, device_mode, vdev_id); + if (QDF_IS_STATUS_SUCCESS(status_he)) + status_he = lim_send_he_6g_band_caps_ie(mac_ctx, + session, + vdev_id); + } + if (QDF_IS_STATUS_SUCCESS(status_ht) && QDF_IS_STATUS_SUCCESS(status_vht) && QDF_IS_STATUS_SUCCESS(status_he)) @@ -6153,13 +6137,15 @@ void lim_del_pmf_sa_query_timer(struct mac_context *mac_ctx, struct pe_session * if (!sta_ds) continue; if (!sta_ds->rmfEnabled) { - pe_debug("no PMF timer for sta-idx:%d assoc-id:%d", - sta_ds->staIndex, sta_ds->assocId); + pe_debug("no PMF timer for assoc-id:%d sta mac" + QDF_MAC_ADDR_FMT, sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); continue; } - pe_debug("Deleting pmfSaQueryTimer for sta-idx:%d assoc-id:%d", - sta_ds->staIndex, sta_ds->assocId); + pe_debug("Deleting pmfSaQueryTimer for assoc-id:%d sta mac" + QDF_MAC_ADDR_FMT, sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); tx_timer_deactivate(&sta_ds->pmfSaQueryTimer); tx_timer_delete(&sta_ds->pmfSaQueryTimer); } @@ -6202,6 +6188,33 @@ QDF_STATUS lim_strip_supp_op_class_update_struct(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } +uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx, + uint16_t channel_freq, + enum phy_ch_width ch_bandwidth, + enum offset_t offset) +{ + uint8_t op_class = 0; + uint16_t ch_behav_limit = BEHAV_NONE; + uint8_t channel; + + if (ch_bandwidth == CH_WIDTH_40MHZ && + wlan_reg_is_24ghz_ch_freq(channel_freq)) { + if (offset == BW40_LOW_PRIMARY) + ch_behav_limit = BEHAV_BW40_LOW_PRIMARY; + else + ch_behav_limit = BEHAV_BW40_HIGH_PRIMARY; + } else if (ch_bandwidth == CH_WIDTH_80P80MHZ) { + ch_behav_limit = BEHAV_BW80_PLUS; + } + wlan_reg_freq_width_to_chan_op_class_auto + (mac_ctx->pdev, channel_freq, + ch_width_in_mhz(ch_bandwidth), + true, BIT(ch_behav_limit), &op_class, + &channel); + + return op_class; +} + /** * lim_update_extcap_struct() - poputlate the dot11f structure * @mac_ctx: global MAC context @@ -6337,20 +6350,8 @@ static void lim_send_action_frm_tb_ppdu_cfg_flush_cb(struct scheduler_msg *msg) } } -/** - * lim_send_action_frm_tb_ppdu_cfg() - sets action frame in TB PPDU cfg to FW - * @mac_ctx: global MAC context - * @session_id: SME session id - * @cfg: config setting - * - * Preapres the vendor action frame and send action frame in HE TB PPDU - * configuration to FW. - * - * Return: QDF_STATUS - */ QDF_STATUS lim_send_action_frm_tb_ppdu_cfg(struct mac_context *mac_ctx, - uint32_t session_id, - uint8_t cfg) + uint32_t vdev_id, uint8_t cfg) { tDot11fvendor_action_frame *frm; uint8_t frm_len = sizeof(*frm); @@ -6359,11 +6360,10 @@ QDF_STATUS lim_send_action_frm_tb_ppdu_cfg(struct mac_context *mac_ctx, struct scheduler_msg msg = {0}; uint8_t *data_buf; - session = pe_find_session_by_sme_session_id(mac_ctx, session_id); - + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { - pe_err("pe session does not exist for sme session id %d", - session_id); + pe_err("pe session does not exist for vdev_id %d", + vdev_id); return QDF_STATUS_E_FAILURE; } @@ -6383,7 +6383,7 @@ QDF_STATUS lim_send_action_frm_tb_ppdu_cfg(struct mac_context *mac_ctx, frm->vendor_action_subtype.subtype = 0xFF; - cfg_msg->vdev_id = session_id; + cfg_msg->vdev_id = vdev_id; cfg_msg->cfg = cfg; cfg_msg->frm_len = frm_len; cfg_msg->data = (uint8_t *)frm; @@ -6723,8 +6723,8 @@ bool lim_is_valid_frame(last_processed_msg *last_processed_frm, if (last_processed_frm->seq_num == seq_num && qdf_mem_cmp(last_processed_frm->sa, pHdr->sa, ETH_ALEN) == 0) { - pe_err("Duplicate frame from "QDF_MAC_ADDR_STR " Seq Number %d", - QDF_MAC_ADDR_ARRAY(pHdr->sa), seq_num); + pe_err("Duplicate frame from "QDF_MAC_ADDR_FMT " Seq Number %d", + QDF_MAC_ADDR_REF(pHdr->sa), seq_num); return false; } return true; @@ -6758,14 +6758,89 @@ void lim_update_last_processed_frame(last_processed_msg *last_processed_frm, last_processed_frm->seq_num = seq_num; } +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +static bool lim_support_6ghz_band_op_class(struct mac_context *mac_ctx, + tDot11fIESuppOperatingClasses * + op_class_ie) +{ + uint16_t i; + + if (!op_class_ie->present) + return false; + for (i = 0; i < op_class_ie->num_classes; i++) { + if (wlan_reg_is_6ghz_op_class(mac_ctx->pdev, + op_class_ie->classes[i])) + break; + } + if (i < op_class_ie->num_classes) + return true; + + return false; +} + +void lim_ap_check_6g_compatible_peer(struct mac_context *mac_ctx, + struct pe_session *session) +{ + uint16_t i; + tpDphHashNode sta_ds; + bool legacy_client_present = false; + + if (!LIM_IS_AP_ROLE(session)) + return; + + for (i = 1; i < session->dph.dphHashTable.size; i++) { + sta_ds = dph_get_hash_entry(mac_ctx, i, + &session->dph.dphHashTable); + if (!sta_ds) + continue; + if (sta_ds->staType != STA_ENTRY_PEER) + continue; + if (!lim_support_6ghz_band_op_class( + mac_ctx, &sta_ds->supp_operating_classes)) { + legacy_client_present = true; + pe_debug("peer "QDF_MAC_ADDR_FMT" 6ghz not supported", + QDF_MAC_ADDR_REF(sta_ds->staAddr)); + break; + } + pe_debug("peer "QDF_MAC_ADDR_FMT" 6ghz supported", + QDF_MAC_ADDR_REF(sta_ds->staAddr)); + } + if (legacy_client_present) + policy_mgr_set_ap_6ghz_capable( + mac_ctx->psoc, session->vdev_id, false, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT); + else + policy_mgr_set_ap_6ghz_capable( + mac_ctx->psoc, session->vdev_id, true, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT); +} +#endif + #ifdef WLAN_FEATURE_11AX -void lim_add_he_cap(tpAddStaParams add_sta_params, tpSirAssocReq assoc_req) +void lim_update_he_6ghz_band_caps(struct mac_context *mac, + tDot11fIEhe_6ghz_band_cap *he_6ghz_band_cap, + tpAddStaParams params) +{ + qdf_mem_copy(¶ms->he_6ghz_band_caps, he_6ghz_band_cap, + sizeof(tDot11fIEhe_6ghz_band_cap)); + + lim_log_he_6g_cap(mac, ¶ms->he_6ghz_band_caps); +} + +void lim_add_he_cap(struct mac_context *mac_ctx, struct pe_session *pe_session, + tpAddStaParams add_sta_params, tpSirAssocReq assoc_req) { if (!add_sta_params->he_capable || !assoc_req) return; qdf_mem_copy(&add_sta_params->he_config, &assoc_req->he_cap, sizeof(add_sta_params->he_config)); + + if (lim_is_he_6ghz_band(pe_session)) + lim_update_he_6ghz_band_caps(mac_ctx, + &assoc_req->he_6ghz_band_cap, + add_sta_params); + } void lim_add_self_he_cap(tpAddStaParams add_sta_params, struct pe_session *session) @@ -6857,7 +6932,7 @@ void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, struct pe_session *sessi lim_intersect_he_caps(rcvd_he, session_he, peer_he); } -void lim_intersect_ap_he_caps(struct pe_session *session, tpAddBssParams add_bss, +void lim_intersect_ap_he_caps(struct pe_session *session, struct bss_params *add_bss, tSchBeaconStruct *beacon, tpSirAssocRsp assoc_rsp) { tDot11fIEhe_cap *rcvd_he; @@ -6873,7 +6948,7 @@ void lim_intersect_ap_he_caps(struct pe_session *session, tpAddBssParams add_bss add_bss->staContext.he_capable = true; } -void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp) +void lim_add_bss_he_cap(struct bss_params *add_bss, tpSirAssocRsp assoc_rsp) { tDot11fIEhe_cap *he_cap; tDot11fIEhe_op *he_op; @@ -6889,13 +6964,97 @@ void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp) he_op, sizeof(*he_op)); } -void lim_add_bss_he_cfg(tpAddBssParams add_bss, struct pe_session *session) +void lim_add_bss_he_cfg(struct bss_params *add_bss, struct pe_session *session) { add_bss->he_sta_obsspd = session->he_sta_obsspd; } +void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams, + tDot11fIEhe_op *he_op, + struct pe_session *pe_session) +{ + if (!pe_session->he_6ghz_band) + return; + + if (!he_op->oper_info_6g_present) { + pe_debug("6G operation info not present in beacon"); + return; + } + if (!pe_session->ch_width) + return; + + pAddBssParams->ch_width = QDF_MIN(he_op->oper_info_6g.info.ch_width, + pe_session->ch_width); + + if (pAddBssParams->ch_width == CH_WIDTH_160MHZ) + pAddBssParams->ch_width = pe_session->ch_width; + pAddBssParams->staContext.ch_width = pAddBssParams->ch_width; +} + +static bool lim_check_is_bss_greater_than_4_nss_supp(struct pe_session * +session, + tDot11fIEhe_cap *he_cap) +{ + uint8_t i; + uint16_t mcs_map; +#define NSS_4 4 +#define NSS_8 8 + + if (!session->he_capable || !he_cap->present) + return false; + mcs_map = he_cap->rx_he_mcs_map_lt_80; + for (i = NSS_4; i < NSS_8; i++) { + if (((mcs_map >> (i * 2)) & 0x3) != 0x3) + return true; + } + + return false; +} + +static bool lim_check_he_80_mcs11_supp(struct pe_session *session, + tDot11fIEhe_cap *he_cap) +{ + uint16_t rx_mcs_map; + uint16_t tx_mcs_map; + + rx_mcs_map = he_cap->rx_he_mcs_map_lt_80; + tx_mcs_map = he_cap->tx_he_mcs_map_lt_80; + if ((session->nss == NSS_1x1_MODE) && + ((HE_GET_MCS_4_NSS(rx_mcs_map, 1) == HE_MCS_0_11) || + (HE_GET_MCS_4_NSS(tx_mcs_map, 1) == HE_MCS_0_11))) + return true; + + if ((session->nss == NSS_2x2_MODE) && + ((HE_GET_MCS_4_NSS(rx_mcs_map, 2) == HE_MCS_0_11) || + (HE_GET_MCS_4_NSS(tx_mcs_map, 2) == HE_MCS_0_11))) + return true; + + return false; +} + +/** + * lim_check_he_ldpc_cap() - set he ladpc coding to one if + * channel width is > 20 or mcs 10/11 bit are supported or + * nss is greater than 4. + * @beacon_struct: beacon structure + * @session: A pointer to session entry. + * + * Return: None + */ + +static void lim_check_and_force_he_ldpc_cap(struct pe_session *session, + tDot11fIEhe_cap *he_cap) +{ + if (!he_cap->ldpc_coding && + (session->ch_width > CH_WIDTH_20MHZ || + lim_check_he_80_mcs11_supp(session, he_cap) || + lim_check_is_bss_greater_than_4_nss_supp(session, he_cap))) + he_cap->ldpc_coding = 1; +} + void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, + tSchBeaconStruct *beacon) { tDot11fIEhe_cap *he_cap; @@ -6905,8 +7064,40 @@ void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, if (!he_cap->present) return; + /* setting lpdc_coding if any of assoc_rsp or beacon has ladpc_coding + * enabled + */ + if (beacon) + he_cap->ldpc_coding |= beacon->he_cap.ldpc_coding; + lim_check_and_force_he_ldpc_cap(session_entry, he_cap); qdf_mem_copy(&sta_ds->he_config, he_cap, sizeof(*he_cap)); +} + +void lim_update_stads_he_6ghz_op(struct pe_session *session, + tpDphHashNode sta_ds) +{ + tDot11fIEhe_cap *peer_he = &sta_ds->he_config; + enum phy_ch_width ch_width; + + if (!session->he_6ghz_band) + return; + if (!peer_he->present) { + pe_debug("HE cap not present in peer"); + return; + } + + if (peer_he->chan_width_3) + ch_width = CH_WIDTH_80P80MHZ; + else if (peer_he->chan_width_2) + ch_width = CH_WIDTH_160MHZ; + else if (peer_he->chan_width_1) + ch_width = CH_WIDTH_80MHZ; + else + ch_width = CH_WIDTH_20MHZ; + if (ch_width > session->ch_width) + ch_width = session->ch_width; + sta_ds->ch_width = ch_width; } void lim_update_usr_he_cap(struct mac_context *mac_ctx, struct pe_session *session) @@ -6962,13 +7153,13 @@ void lim_update_usr_he_cap(struct mac_context *mac_ctx, struct pe_session *sessi he_cap->su_beamformee, he_cap->mu_beamformer); } -void lim_decide_he_op(struct mac_context *mac_ctx, tpAddBssParams add_bss, +void lim_decide_he_op(struct mac_context *mac_ctx, uint32_t *mlme_he_ops, struct pe_session *session) { uint32_t val; uint8_t color; struct he_ops_network_endian *he_ops_from_ie; - tDot11fIEhe_op *he_ops = &add_bss->he_op; + tDot11fIEhe_op he_ops = {0}; struct add_ie_params *add_ie = &session->add_ie_params; uint8_t extracted_buff[DOT11F_IE_HE_OP_MAX_LEN + 2]; QDF_STATUS status; @@ -6987,34 +7178,36 @@ void lim_decide_he_op(struct mac_context *mac_ctx, tpAddBssParams add_bss, &extracted_buff[HE_OP_OUI_SIZE + 2]; if (he_ops_from_ie->bss_color) { - he_ops->bss_color = he_ops_from_ie->bss_color; + he_ops.bss_color = he_ops_from_ie->bss_color; } else { qdf_get_random_bytes(&color, sizeof(color)); /* make sure color is within 1-63*/ - he_ops->bss_color = (color % WNI_CFG_HE_OPS_BSS_COLOR_MAX) + 1; + he_ops.bss_color = (color % WNI_CFG_HE_OPS_BSS_COLOR_MAX) + 1; } - he_ops->default_pe = he_ops_from_ie->default_pe; - he_ops->twt_required = he_ops_from_ie->twt_required; - he_ops->txop_rts_threshold = he_ops_from_ie->txop_rts_threshold; - he_ops->partial_bss_col = he_ops_from_ie->partial_bss_col; - he_ops->bss_col_disabled = he_ops_from_ie->bss_col_disabled; + he_ops.default_pe = he_ops_from_ie->default_pe; + he_ops.twt_required = he_ops_from_ie->twt_required; + he_ops.txop_rts_threshold = he_ops_from_ie->txop_rts_threshold; + he_ops.partial_bss_col = he_ops_from_ie->partial_bss_col; + he_ops.bss_col_disabled = he_ops_from_ie->bss_col_disabled; val = mac_ctx->mlme_cfg->he_caps.he_ops_basic_mcs_nss; - *((uint16_t *)he_ops->basic_mcs_nss) = (uint16_t)val; + *((uint16_t *)he_ops.basic_mcs_nss) = (uint16_t)val; - qdf_mem_copy(&session->he_op, he_ops, sizeof(*he_ops)); + qdf_mem_copy(&session->he_op, &he_ops, sizeof(tDot11fIEhe_op)); pe_debug("HE Op: bss_color: 0x%0x, default_pe_duration: 0x%0x", - he_ops->bss_color, he_ops->default_pe); + he_ops.bss_color, he_ops.default_pe); pe_debug("He Op: twt_required: 0x%0x, txop_rts_threshold: 0x%0x", - he_ops->twt_required, he_ops->txop_rts_threshold); + he_ops.twt_required, he_ops.txop_rts_threshold); pe_debug("HE Op: partial_bss_color: 0x%0x", - he_ops->partial_bss_col); + he_ops.partial_bss_col); pe_debug("HE Op: BSS color disabled: 0x%0x", - he_ops->bss_col_disabled); + he_ops.bss_col_disabled); pe_debug("HE Op: Basic MCS NSS: 0x%04x", - *((uint16_t *)he_ops->basic_mcs_nss)); + *((uint16_t *)he_ops.basic_mcs_nss)); + + wma_update_vdev_he_ops(mlme_he_ops, &he_ops); } void lim_copy_bss_he_cap(struct pe_session *session, @@ -7029,30 +7222,6 @@ void lim_copy_join_req_he_cap(struct pe_session *session, { qdf_mem_copy(&(session->he_config), &(sme_join_req->he_config), sizeof(session->he_config)); - - if (session->ch_width <= CH_WIDTH_80MHZ) { - *(uint16_t *)session->he_config.rx_he_mcs_map_160 = - HE_MCS_ALL_DISABLED; - *(uint16_t *)session->he_config.tx_he_mcs_map_160 = - HE_MCS_ALL_DISABLED; - *(uint16_t *)session->he_config.rx_he_mcs_map_80_80 = - HE_MCS_ALL_DISABLED; - *(uint16_t *)session->he_config.tx_he_mcs_map_80_80 = - HE_MCS_ALL_DISABLED; - } - /* Reset the > 20MHz caps for 20MHz connection */ - if (session->ch_width == CH_WIDTH_20MHZ) { - session->he_config.chan_width_0 = 0; - session->he_config.chan_width_1 = 0; - session->he_config.chan_width_2 = 0; - session->he_config.chan_width_3 = 0; - session->he_config.chan_width_4 = 0; - session->he_config.chan_width_5 = 0; - session->he_config.chan_width_6 = 0; - session->he_config.he_ppdu_20_in_40Mhz_2G = 0; - session->he_config.he_ppdu_20_in_160_80p80Mhz = 0; - session->he_config.he_ppdu_80_in_160_80p80Mhz = 0; - } } void lim_log_he_cap(struct mac_context *mac, tDot11fIEhe_cap *he_cap) @@ -7161,7 +7330,8 @@ void lim_log_he_cap(struct mac_context *mac, tDot11fIEhe_cap *he_cap) &he_cap->ppet, HE_MAX_PPET_SIZE); } -void lim_log_he_op(struct mac_context *mac, tDot11fIEhe_op *he_ops) +void lim_log_he_op(struct mac_context *mac, tDot11fIEhe_op *he_ops, + struct pe_session *session) { pe_debug("bss_color 0x%x, default_pe_dur 0x%x, twt_req 0x%x, txop_rts_thres 0x%x, vht_op 0x%x", he_ops->bss_color, he_ops->default_pe, @@ -7172,13 +7342,37 @@ void lim_log_he_op(struct mac_context *mac, tDot11fIEhe_op *he_ops) he_ops->bss_col_disabled, *((uint16_t *)he_ops->basic_mcs_nss)); - if (he_ops->vht_oper_present) - pe_debug("VHT Info not present in HE Operation"); - else - pe_debug("VHT Info: chan_width: %d, center_freq0: %d, center_freq1: %d", - he_ops->vht_oper.info.chan_width, - he_ops->vht_oper.info.center_freq_seg0, - he_ops->vht_oper.info.center_freq_seg1); + if (!session->he_6ghz_band) { + if (!he_ops->vht_oper_present) + pe_debug("VHT Info not present in HE Operation"); + else + pe_debug("VHT Info: ch_bw %d cntr_freq0 %d cntr_freq1 %d", + he_ops->vht_oper.info.chan_width, + he_ops->vht_oper.info.center_freq_seg0, + he_ops->vht_oper.info.center_freq_seg1); + } else { + if (!he_ops->oper_info_6g_present) + pe_debug("6G op_info not present in HE Operation"); + else + pe_debug("6G_op_info:ch_bw %d cntr_freq0 %d cntr_freq1 %d dup_bcon %d, min_rate %d", + he_ops->oper_info_6g.info.ch_width, + he_ops->oper_info_6g.info.center_freq_seg0, + he_ops->oper_info_6g.info.center_freq_seg1, + he_ops->oper_info_6g.info.dup_bcon, + he_ops->oper_info_6g.info.min_rate); + } + +} + +void lim_log_he_6g_cap(struct mac_context *mac, + tDot11fIEhe_6ghz_band_cap *he_6g_cap) +{ + pe_debug("min_mpdu_space: %0d, max_mpdu_len_exp: %0x, max_mpdu_len %0x, smps %0x, rd %0x rx_ant_ptn %d tx_ant_ptn %d", + he_6g_cap->min_mpdu_start_spacing, + he_6g_cap->max_ampdu_len_exp, he_6g_cap->max_mpdu_len, + he_6g_cap->sm_pow_save, he_6g_cap->rd_responder, + he_6g_cap->rx_ant_pattern_consistency, + he_6g_cap->tx_ant_pattern_consistency); } #ifdef WLAN_FEATURE_11AX_BSS_COLOR @@ -7207,7 +7401,8 @@ void lim_update_sta_he_capable(struct mac_context *mac, pe_debug("he_capable: %d", add_sta_params->he_capable); } -void lim_update_bss_he_capable(struct mac_context *mac, tpAddBssParams add_bss) +void lim_update_bss_he_capable(struct mac_context *mac, + struct bss_params *add_bss) { add_bss->he_capable = true; pe_debug("he_capable: %d", add_bss->he_capable); @@ -7221,20 +7416,54 @@ void lim_update_stads_he_capable(tpDphHashNode sta_ds, tpSirAssocReq assoc_req) void lim_update_session_he_capable(struct mac_context *mac, struct pe_session *session) { session->he_capable = true; - pe_debug("he_capable: %d", session->he_capable); - if (wlan_reg_is_24ghz_ch(session->currentOperChannel) && + if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) { + session->htCapability = 0; + session->vhtCapability = 0; + session->he_6ghz_band = 1; + } + if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq) && !mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) session->vhtCapability = 0; + + pe_debug("he_capable: %d", session->he_capable); } -void lim_update_chan_he_capable(struct mac_context *mac, tpSwitchChannelParams chan) +void lim_update_session_he_capable_chan_switch(struct mac_context *mac, + struct pe_session *session, + uint32_t new_chan_freq) { - chan->he_capable = true; - pe_debug("he_capable: %d", chan->he_capable); + session->he_capable = true; + if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq) && + !wlan_reg_is_6ghz_chan_freq(new_chan_freq)) { + session->htCapability = 1; + session->vhtCapability = 1; + session->he_6ghz_band = 0; + } else if (!wlan_reg_is_6ghz_chan_freq(session->curr_op_freq) && + wlan_reg_is_6ghz_chan_freq(new_chan_freq)) { + session->htCapability = 0; + session->vhtCapability = 0; + session->he_6ghz_band = 1; + } + + /* + * If new channel is 2.4gh set VHT as per the b24ghz_band INI + * if new channel is 5Ghz set the vht, this will happen if we move from + * 2.4Ghz to 5Ghz. + */ + if (wlan_reg_is_24ghz_ch_freq(new_chan_freq) && + !mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) + session->vhtCapability = 0; + else if (wlan_reg_is_5ghz_ch_freq(new_chan_freq)) + session->vhtCapability = 1; + + pe_debug("he_capable: %d ht %d vht %d 6ghz_band %d new freq %d vht in 2.4gh %d", + session->he_capable, session->htCapability, + session->vhtCapability, session->he_6ghz_band, new_chan_freq, + mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band); } -void lim_set_he_caps(struct mac_context *mac, struct pe_session *session, uint8_t *ie_start, - uint32_t num_bytes) +void lim_set_he_caps(struct mac_context *mac, struct pe_session *session, + uint8_t *ie_start, uint32_t num_bytes) { const uint8_t *ie = NULL; tDot11fIEhe_cap dot11_cap; @@ -7341,15 +7570,72 @@ void lim_set_he_caps(struct mac_context *mac, struct pe_session *session, uint8_ he_cap->rx_he_mcs_map_lt_80 = dot11_cap.rx_he_mcs_map_lt_80; he_cap->tx_he_mcs_map_lt_80 = dot11_cap.tx_he_mcs_map_lt_80; - he_cap->rx_he_mcs_map_160 = + if (dot11_cap.chan_width_2) { + he_cap->rx_he_mcs_map_160 = *((uint16_t *)dot11_cap.rx_he_mcs_map_160); - he_cap->tx_he_mcs_map_160 = + he_cap->tx_he_mcs_map_160 = *((uint16_t *)dot11_cap.tx_he_mcs_map_160); - he_cap->rx_he_mcs_map_80_80 = + ie_start[1] += HE_CAP_160M_MCS_MAP_LEN; + } + if (dot11_cap.chan_width_3) { + he_cap->rx_he_mcs_map_80_80 = *((uint16_t *)dot11_cap.rx_he_mcs_map_80_80); - he_cap->tx_he_mcs_map_80_80 = + he_cap->tx_he_mcs_map_80_80 = *((uint16_t *)dot11_cap.tx_he_mcs_map_80_80); + ie_start[1] += HE_CAP_80P80_MCS_MAP_LEN; + } + } +} + +static void lim_intersect_he_ch_width_2g(struct mac_context *mac, + struct he_capability_info *he_cap) +{ + struct wlan_objmgr_psoc *psoc; + uint32_t cbm_24ghz; + QDF_STATUS ret; + + psoc = mac->psoc; + if (!psoc) + return; + + ret = ucfg_mlme_get_channel_bonding_24ghz(psoc, &cbm_24ghz); + if (QDF_IS_STATUS_ERROR(ret)) + return; + + pe_debug("channel bonding mode 2.4GHz %d", cbm_24ghz); + + if (!cbm_24ghz) { + /* B0: 40Mhz channel width in the 2.4GHz band */ + he_cap->chan_width = HE_CH_WIDTH_CLR_BIT(he_cap->chan_width, 0); + he_cap->he_ppdu_20_in_40Mhz_2G = 0; } + + pe_debug("HE cap: chan_width: 0x%07x he_ppdu_20_in_40Mhz_2G %d", + he_cap->chan_width, he_cap->he_ppdu_20_in_40Mhz_2G); +} + +static uint8_t lim_set_he_caps_ppet(struct mac_context *mac, uint8_t *ie, + enum cds_band_type band) +{ + uint8_t ppe_th[WNI_CFG_HE_PPET_LEN] = {0}; + /* Append at the end after ID + LEN + OUI + IE_Data */ + uint8_t offset = ie[1] + 1 + 1 + 1; + uint8_t num_ppe_th; + + if (band == CDS_BAND_2GHZ) + qdf_mem_copy(ppe_th, mac->mlme_cfg->he_caps.he_ppet_2g, + WNI_CFG_HE_PPET_LEN); + else if (band == CDS_BAND_5GHZ) + qdf_mem_copy(ppe_th, mac->mlme_cfg->he_caps.he_ppet_5g, + WNI_CFG_HE_PPET_LEN); + else + return 0; + + num_ppe_th = lim_truncate_ppet(ppe_th, WNI_CFG_HE_PPET_LEN); + + qdf_mem_copy(ie + offset, ppe_th, num_ppe_th); + + return num_ppe_th; } QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx, @@ -7357,22 +7643,23 @@ QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx, enum QDF_OPMODE device_mode, uint8_t vdev_id) { - uint8_t he_caps[SIR_MAC_HE_CAP_MIN_LEN + 3]; + uint8_t he_caps[SIR_MAC_HE_CAP_MIN_LEN + HE_CAP_OUI_LEN + + HE_CAP_160M_MCS_MAP_LEN + HE_CAP_80P80_MCS_MAP_LEN + + WNI_CFG_HE_PPET_LEN]; struct he_capability_info *he_cap; QDF_STATUS status_5g, status_2g; uint8_t he_cap_total_len = SIR_MAC_HE_CAP_MIN_LEN + HE_CAP_OUI_LEN + HE_CAP_160M_MCS_MAP_LEN + HE_CAP_80P80_MCS_MAP_LEN; + uint8_t num_ppe_th = 0; /* Sending only minimal info(no PPET) to FW now, update if required */ - qdf_mem_zero(he_caps, SIR_MAC_HE_CAP_MIN_LEN + 3); + qdf_mem_zero(he_caps, he_cap_total_len); he_caps[0] = DOT11F_EID_HE_CAP; he_caps[1] = SIR_MAC_HE_CAP_MIN_LEN; qdf_mem_copy(&he_caps[2], HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE); - lim_set_he_caps(mac_ctx, session, he_caps, - SIR_MAC_HE_CAP_MIN_LEN + 3); + lim_set_he_caps(mac_ctx, session, he_caps, he_cap_total_len); he_cap = (struct he_capability_info *) (&he_caps[2 + HE_CAP_OUI_SIZE]); - he_cap->ppet_present = 0; if(device_mode == QDF_NDI_MODE) { he_cap->su_beamformee = 0; he_cap->su_beamformer = 0; @@ -7384,16 +7671,27 @@ QDF_STATUS lim_send_he_caps_ie(struct mac_context *mac_ctx, he_cap->su_feedback_tone16 = 0; he_cap->mu_feedback_tone16 = 0; } + + if (he_cap->ppet_present) + num_ppe_th = lim_set_he_caps_ppet(mac_ctx, he_caps, + CDS_BAND_5GHZ); + status_5g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP, CDS_BAND_5GHZ, &he_caps[2], - SIR_MAC_HE_CAP_MIN_LEN + 1); + he_caps[1] + 1 + num_ppe_th); if (QDF_IS_STATUS_ERROR(status_5g)) pe_err("Unable send HE Cap IE for 5GHZ band, status: %d", status_5g); + lim_intersect_he_ch_width_2g(mac_ctx, he_cap); + + if (he_cap->ppet_present) + num_ppe_th = lim_set_he_caps_ppet(mac_ctx, he_caps, + CDS_BAND_2GHZ); + status_2g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP, CDS_BAND_2GHZ, &he_caps[2], - SIR_MAC_HE_CAP_MIN_LEN + 1); + he_caps[1] + 1 + num_ppe_th); if (QDF_IS_STATUS_ERROR(status_2g)) pe_err("Unable send HE Cap IE for 2GHZ band, status: %d", status_2g); @@ -7486,7 +7784,7 @@ QDF_STATUS lim_populate_he_mcs_set(struct mac_context *mac_ctx, if (session_entry->nss == NSS_2x2_MODE) { if (mac_ctx->lteCoexAntShare && - IS_24G_CH(session_entry->currentOperChannel)) { + wlan_reg_is_24ghz_ch_freq(session_entry->curr_op_freq)) { if (IS_2X2_CHAIN(session_entry->chainMask)) support_2x2 = true; else @@ -7551,6 +7849,47 @@ QDF_STATUS lim_populate_he_mcs_set(struct mac_context *mac_ctx, } #endif +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx, + struct pe_session *session, + uint8_t vdev_id) +{ + uint8_t he_6g_band_caps_ie[DOT11F_IE_HE_6GHZ_BAND_CAP_MIN_LEN + 3]; + tDot11fIEhe_6ghz_band_cap he_6g_band_cap; + QDF_STATUS status; + uint32_t size = 0; + uint32_t result; + + qdf_mem_zero(&he_6g_band_cap, sizeof(he_6g_band_cap)); + populate_dot11f_he_6ghz_cap(mac_ctx, session, &he_6g_band_cap); + if (!he_6g_band_cap.present) { + pe_debug("no HE 6g band cap for vdev %d", vdev_id); + return QDF_STATUS_SUCCESS; + } + + qdf_mem_zero(he_6g_band_caps_ie, sizeof(he_6g_band_caps_ie)); + result = dot11f_pack_ie_he_6ghz_band_cap(mac_ctx, &he_6g_band_cap, + he_6g_band_caps_ie, + sizeof(he_6g_band_caps_ie), + &size); + if (result != DOT11F_PARSE_SUCCESS) { + pe_err("pack erro for HE 6g band cap for vdev %d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + pe_debug("send HE 6ghz band cap: 0x%01x 0x%01x for vdev %d", + he_6g_band_caps_ie[3], he_6g_band_caps_ie[4], + vdev_id); + status = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_6GHZ_BAND_CAP, + CDS_BAND_5GHZ, &he_6g_band_caps_ie[2], + DOT11F_IE_HE_6GHZ_BAND_CAP_MIN_LEN + 1); + if (QDF_IS_STATUS_ERROR(status)) + pe_err("Unable send HE 6g band Cap IE for 5GHZ band, status: %d", + status); + + return status; +} +#endif + int lim_assoc_rej_get_remaining_delta(struct sir_rssi_disallow_lst *node) { @@ -7587,8 +7926,8 @@ lim_rem_blacklist_entry_with_lowest_delta(qdf_list_t *list) } if (oldest_node) { - pe_debug("remove node %pM with lowest delta %d", - oldest_node->bssid.bytes, + pe_debug("remove node "QDF_MAC_ADDR_FMT" with lowest delta %d", + QDF_MAC_ADDR_REF(oldest_node->bssid.bytes), lim_assoc_rej_get_remaining_delta(oldest_node)); qdf_list_remove_node(list, &oldest_node->node); qdf_mem_free(oldest_node); @@ -7608,7 +7947,10 @@ lim_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev, ap_info.reject_ap_type = DRIVER_RSSI_REJECT_TYPE; ap_info.rssi_reject_params.expected_rssi = entry->expected_rssi; ap_info.rssi_reject_params.retry_delay = entry->retry_delay; - + ap_info.reject_reason = entry->reject_reason; + ap_info.source = entry->source; + ap_info.rssi_reject_params.received_time = entry->received_time; + ap_info.rssi_reject_params.original_timeout = entry->original_timeout; /* Add this ap info to the rssi reject ap type in blacklist manager */ wlan_blm_add_bssid_to_reject_list(pdev, &ap_info); } @@ -7624,37 +7966,6 @@ void lim_decrement_pending_mgmt_count(struct mac_context *mac_ctx) qdf_spin_unlock(&mac_ctx->sys.bbt_mgmt_lock); } -struct csr_roam_session *lim_get_session_by_macaddr(struct mac_context *mac_ctx, - tSirMacAddr self_mac) -{ - int i = 0; - struct csr_roam_session *session; - - if (!mac_ctx || !self_mac) { - QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, - FL("Invalid arguments")); - return NULL; - } - - for (i = 0; i < mac_ctx->sme.max_intf_count; i++) { - session = CSR_GET_SESSION(mac_ctx, i); - if (!session) - continue; - else if (!qdf_mem_cmp(&session->self_mac_addr, - self_mac, sizeof(tSirMacAddr))) { - - QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, - FL("session %d exists with mac address " - QDF_MAC_ADDR_STR), session->sessionId, - QDF_MAC_ADDR_ARRAY(self_mac)); - - return session; - } - } - - return NULL; -} - bool lim_check_if_vendor_oui_match(struct mac_context *mac_ctx, uint8_t *oui, uint8_t oui_len, uint8_t *ie, uint8_t ie_len) @@ -7773,7 +8084,7 @@ enum rateid lim_get_min_session_txrate(struct pe_session *session) void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type, uint8_t *frame, uint32_t frame_len, - uint16_t session_id, uint32_t rx_channel, + uint16_t session_id, uint32_t rx_freq, struct pe_session *psession_entry, int8_t rx_rssi, enum rxmgmt_flags rx_flags) { @@ -7797,7 +8108,7 @@ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type sme_mgmt_frame->sessionId = session_id; sme_mgmt_frame->frameType = frame_type; sme_mgmt_frame->rxRssi = rx_rssi; - sme_mgmt_frame->rxChan = rx_channel; + sme_mgmt_frame->rx_freq = rx_freq; sme_mgmt_frame->rx_flags = rx_flags; qdf_mem_zero(sme_mgmt_frame->frameBuf, frame_len); @@ -7831,7 +8142,8 @@ void lim_process_ap_ecsa_timeout(void *data) { struct pe_session *session = (struct pe_session *)data; struct mac_context *mac_ctx; - uint8_t bcn_int, ch, ch_width; + uint8_t bcn_int, ch_width; + uint32_t ch_freq; QDF_STATUS status; if (!session || !session->valid) { @@ -7861,12 +8173,20 @@ void lim_process_ap_ecsa_timeout(void *data) /* Send the next beacon with updated CSA IE count */ lim_send_dfs_chan_sw_ie_update(mac_ctx, session); - ch = session->gLimChannelSwitch.primaryChannel; + ch_freq = session->gLimChannelSwitch.sw_target_freq; ch_width = session->gLimChannelSwitch.ch_width; - if (mac_ctx->mlme_cfg->dfs_cfg.dfs_beacon_tx_enhanced) - /* Send Action frame after updating beacon */ - lim_send_chan_switch_action_frame(mac_ctx, ch, ch_width, - session); + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_beacon_tx_enhanced) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { + send_extended_chan_switch_action_frame + (mac_ctx, ch_freq, ch_width, + session); + } else { + /* Send Action frame after updating beacon */ + lim_send_chan_switch_action_frame + (mac_ctx, ch_freq, ch_width, + session); + } + } /* Restart the timer */ if (session->beaconParams.beaconInterval) @@ -7969,13 +8289,7 @@ QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, lim_ht_switch_chnl_params(session); break; case LIM_SWITCH_CHANNEL_REASSOC: - lim_set_channel(session->mac_ctx, - session->limReassocChannelId, - session->ch_center_freq_seg0, - session->ch_center_freq_seg1, - session->ch_width, - session->maxTxPower, - session->peSessionId, 0, 0); + lim_send_switch_chnl_params(session->mac_ctx, session); break; default: break; @@ -8068,6 +8382,13 @@ void lim_send_beacon(struct mac_context *mac_ctx, struct pe_session *session) wlan_vdev_mlme_sm_deliver_evt(session->vdev, WLAN_VDEV_SM_EV_DFS_CAC_COMPLETED, sizeof(*session), session); + else if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch && + (wlan_vdev_mlme_get_substate(session->vdev) == + WLAN_VDEV_SS_SUSPEND_CSA_RESTART)) + wlan_vdev_mlme_sm_deliver_evt( + session->vdev, + WLAN_VDEV_SM_EV_CHAN_SWITCH_DISABLED, + sizeof(*session), session); else wlan_vdev_mlme_sm_deliver_evt(session->vdev, WLAN_VDEV_SM_EV_START_SUCCESS, @@ -8166,6 +8487,10 @@ QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme, if (op == BEACON_INIT) lim_send_beacon_ind(session->mac_ctx, session, REASON_DEFAULT); + else if (op == BEACON_UPDATE) + lim_send_beacon_ind(session->mac_ctx, + session, + REASON_CONFIG_UPDATE); else if (op == BEACON_CSA) lim_send_csa_restart_resp(session->mac_ctx, session); @@ -8248,12 +8573,7 @@ QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme, lim_send_vdev_restart(session->mac_ctx, session, session->smeSessionId); else - lim_set_channel(session->mac_ctx, session->currentOperChannel, - session->ch_center_freq_seg0, - session->ch_center_freq_seg1, - session->ch_width, session->maxTxPower, - session->peSessionId, session->cac_duration_ms, - session->dfs_regdomain); + lim_send_switch_chnl_params(session->mac_ctx, session); return QDF_STATUS_SUCCESS; } @@ -8293,14 +8613,7 @@ QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_E_INVAL; } - lim_set_channel(mac_ctx, session->currentOperChannel, - session->ch_center_freq_seg0, - session->ch_center_freq_seg1, - session->ch_width, - session->maxTxPower, - session->peSessionId, - session->cac_duration_ms, - session->dfs_regdomain); + lim_send_switch_chnl_params(mac_ctx, session); return QDF_STATUS_SUCCESS; } @@ -8327,73 +8640,6 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx, } } -/** - * lim_get_dot11d_transmit_power() - regulatory max transmit power - * @mac: pointer to mac data - * @channel: channel number - * - * Return: int8_t - power - */ -static int8_t -lim_get_dot11d_transmit_power(struct mac_context *mac, uint8_t channel) -{ - uint32_t cfg_length = 0; - int8_t max_tx_pwr = 0; - uint8_t *country_info = NULL; - uint8_t count = 0; - uint8_t first_channel; - uint8_t maxChannels; - - if (WLAN_REG_IS_5GHZ_CH(channel)) - cfg_length = mac->mlme_cfg->power.max_tx_power_5.len; - else if (WLAN_REG_IS_24GHZ_CH(channel)) - cfg_length = mac->mlme_cfg->power.max_tx_power_24.len; - else - return max_tx_pwr; - - country_info = qdf_mem_malloc(cfg_length); - if (!country_info) - goto error; - - if (WLAN_REG_IS_5GHZ_CH(channel)) { - if (cfg_length > CFG_MAX_TX_POWER_5_LEN) - goto error; - qdf_mem_copy(country_info, - mac->mlme_cfg->power.max_tx_power_5.data, - cfg_length); - } else if (WLAN_REG_IS_24GHZ_CH(channel)) { - if (cfg_length > CFG_MAX_TX_POWER_2_4_LEN) - goto error; - qdf_mem_copy(country_info, - mac->mlme_cfg->power.max_tx_power_24.data, - cfg_length); - } - - /* Identify the channel and maxtxpower */ - while (count <= (cfg_length - (sizeof(tSirMacChanInfo)))) { - first_channel = country_info[count++]; - maxChannels = country_info[count++]; - max_tx_pwr = country_info[count++]; - - if ((channel >= first_channel) && - (channel < (first_channel + maxChannels))) { - break; - } - } - -error: - if (country_info) - qdf_mem_free(country_info); - - return max_tx_pwr; -} - -int8_t lim_get_regulatory_max_transmit_power(struct mac_context *mac, - uint8_t channel) -{ - return lim_get_dot11d_transmit_power(mac, channel); -} - QDF_STATUS lim_get_capability_info(struct mac_context *mac, uint16_t *pcap, struct pe_session *pe_session) { @@ -8517,7 +8763,8 @@ void lim_flush_bssid(struct mac_context *mac_ctx, uint8_t *bssid) wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID); if (QDF_IS_STATUS_SUCCESS(status)) - pe_debug("Removed BSS entry:%pM from scan cache", bssid); + pe_debug("Removed BSS entry:"QDF_MAC_ADDR_FMT" from scan cache", + QDF_MAC_ADDR_REF(bssid)); if (filter) qdf_mem_free(filter); @@ -8535,3 +8782,239 @@ bool lim_is_sha384_akm(enum ani_akm_type akm) return false; } } + +QDF_STATUS lim_set_ch_phy_mode(struct wlan_objmgr_vdev *vdev, uint8_t dot11mode) +{ + struct vdev_mlme_obj *mlme_obj; + struct wlan_channel *des_chan; + uint32_t chan_mode; + enum phy_ch_width ch_width; + struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); + uint16_t bw_val; + enum reg_wifi_band band; + uint8_t band_mask; + enum channel_state ch_state; + uint32_t start_ch_freq; + + if (!mac_ctx) { + pe_err("Invalid mac context"); + return QDF_STATUS_E_FAILURE; + } + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + des_chan = vdev->vdev_mlme.des_chan; + /* + * Set ch_cfreq1 to ch_freq for 20Mhz. If BW is greater than 20 it + * will be updated from ch_freq_seg1. + */ + des_chan->ch_cfreq1 = des_chan->ch_freq; + band = wlan_reg_freq_to_band(des_chan->ch_freq); + band_mask = 1 << band; + ch_width = des_chan->ch_width; + bw_val = wlan_reg_get_bw_value(ch_width); + if (bw_val > 20) { + if (des_chan->ch_freq_seg1) { + des_chan->ch_cfreq1 = + wlan_reg_chan_band_to_freq(mac_ctx->pdev, + des_chan->ch_freq_seg1, + band_mask); + } else { + pe_err("Invalid cntr_freq for bw %d, drop to 20", + bw_val); + ch_width = CH_WIDTH_20MHZ; + bw_val = 20; + if (des_chan->ch_cfreq1) + des_chan->ch_freq_seg1 = + wlan_reg_freq_to_chan( + mac_ctx->pdev, + des_chan->ch_cfreq1); + } + } else if (des_chan->ch_cfreq1) { + des_chan->ch_freq_seg1 = + wlan_reg_freq_to_chan(mac_ctx->pdev, + des_chan->ch_cfreq1); + } + if (bw_val > 80) { + if (des_chan->ch_freq_seg2) { + des_chan->ch_cfreq2 = + wlan_reg_chan_band_to_freq(mac_ctx->pdev, + des_chan->ch_freq_seg2, + band_mask); + } else { + pe_err("Invalid cntr_freq for bw %d, drop to 80", + bw_val); + des_chan->ch_cfreq2 = 0; + des_chan->ch_freq_seg2 = 0; + ch_width = CH_WIDTH_80MHZ; + } + } else { + des_chan->ch_cfreq2 = 0; + des_chan->ch_freq_seg2 = 0; + } + + des_chan->ch_width = ch_width; + + des_chan->ch_flags = 0; + switch (ch_width) { + case CH_WIDTH_20MHZ: + des_chan->ch_flags |= IEEE80211_CHAN_VHT20; + break; + case CH_WIDTH_40MHZ: + des_chan->ch_flags |= IEEE80211_CHAN_VHT40PLUS; + break; + case CH_WIDTH_80MHZ: + des_chan->ch_flags |= IEEE80211_CHAN_VHT80; + break; + case CH_WIDTH_80P80MHZ: + des_chan->ch_flags |= IEEE80211_CHAN_VHT80_80; + break; + case CH_WIDTH_160MHZ: + des_chan->ch_flags |= IEEE80211_CHAN_VHT160; + break; + default: + break; + } + + if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq)) + des_chan->ch_flags |= IEEE80211_CHAN_2GHZ; + else + des_chan->ch_flags |= IEEE80211_CHAN_5GHZ; + + des_chan->ch_flagext = 0; + if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, des_chan->ch_freq)) + des_chan->ch_flagext |= IEEE80211_CHAN_DFS; + if (des_chan->ch_cfreq2) { + if (CH_WIDTH_80P80MHZ == des_chan->ch_width) + start_ch_freq = des_chan->ch_cfreq2 - 30; + else + start_ch_freq = des_chan->ch_freq; + + ch_state = wlan_reg_get_5g_bonded_channel_state_for_freq( + mac_ctx->pdev, start_ch_freq, + des_chan->ch_width); + if (CHANNEL_STATE_DFS == ch_state) + des_chan->ch_flagext |= IEEE80211_CHAN_DFS_CFREQ2; + } + + chan_mode = wma_chan_phy_mode(des_chan->ch_freq, ch_width, + dot11mode); + + if (chan_mode == WLAN_PHYMODE_AUTO || chan_mode == WLAN_PHYMODE_MAX) { + pe_err("Invalid phy mode!"); + return QDF_STATUS_E_FAILURE; + } + if (!des_chan->ch_cfreq1) { + pe_err("Invalid center freq1"); + return QDF_STATUS_E_FAILURE; + } + + if ((ch_width == CH_WIDTH_160MHZ || + ch_width == CH_WIDTH_80P80MHZ) && !des_chan->ch_cfreq2) { + pe_err("Invalid center freq2 for 160MHz"); + return QDF_STATUS_E_FAILURE; + } + /* Till conversion is not done in WMI we need to fill fw phy mode */ + mlme_obj->mgmt.generic.phy_mode = wma_host_to_fw_phymode(chan_mode); + des_chan->ch_phymode = chan_mode; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS lim_pre_vdev_start(struct mac_context *mac, + struct vdev_mlme_obj *mlme_obj, + struct pe_session *session) +{ + struct wlan_channel *des_chan; + enum reg_wifi_band band; + uint8_t band_mask; + struct ch_params ch_params = {0}; + qdf_freq_t sec_chan_freq = 0; + + band = wlan_reg_freq_to_band(session->curr_op_freq); + band_mask = 1 << band; + + ch_params.ch_width = session->ch_width; + ch_params.mhz_freq_seg0 = + wlan_reg_chan_band_to_freq(mac->pdev, + session->ch_center_freq_seg0, + band_mask); + + if (session->ch_center_freq_seg1) + ch_params.mhz_freq_seg1 = + wlan_reg_chan_band_to_freq(mac->pdev, + session->ch_center_freq_seg1, + band_mask); + + if (band == (REG_BAND_2G) && (ch_params.ch_width == CH_WIDTH_40MHZ)) { + if (ch_params.mhz_freq_seg0 == session->curr_op_freq + 10) + sec_chan_freq = session->curr_op_freq + 20; + if (ch_params.mhz_freq_seg0 == session->curr_op_freq - 10) + sec_chan_freq = session->curr_op_freq - 20; + } + + wlan_reg_set_channel_params_for_freq(mac->pdev, session->curr_op_freq, + sec_chan_freq, &ch_params); + + pe_debug("vdev id %d freq %d seg0 %d seg1 %d ch_width %d cac_duration_ms %d beacon_interval %d hidden_ssid: %d dtimPeriod %d slot_time %d bcn tx rate %d mhz seg0 %d mhz seg1 %d", + session->vdev_id, session->curr_op_freq, + ch_params.center_freq_seg0, + ch_params.center_freq_seg1, ch_params.ch_width, + session->cac_duration_ms, + session->beaconParams.beaconInterval, + session->ssidHidden, session->dtimPeriod, + session->shortSlotTimeSupported, + session->beacon_tx_rate, + ch_params.mhz_freq_seg0, + ch_params.mhz_freq_seg1); + /* Invalid channel width means no suitable channel bonding in current + * regdomain for requested channel frequency. Abort vdev start. + */ + if (ch_params.ch_width == CH_WIDTH_INVALID) { + pe_debug("abort vdev start invalid chan parameters"); + return QDF_STATUS_E_INVAL; + } + + des_chan = mlme_obj->vdev->vdev_mlme.des_chan; + des_chan->ch_freq = session->curr_op_freq; + des_chan->ch_width = ch_params.ch_width; + des_chan->ch_freq_seg1 = ch_params.center_freq_seg0; + des_chan->ch_freq_seg2 = ch_params.center_freq_seg1; + des_chan->ch_ieee = wlan_reg_freq_to_chan(mac->pdev, des_chan->ch_freq); + session->ch_width = ch_params.ch_width; + session->ch_center_freq_seg0 = ch_params.center_freq_seg0; + session->ch_center_freq_seg1 = ch_params.center_freq_seg1; + + mlme_obj->mgmt.generic.maxregpower = session->maxTxPower; + mlme_obj->proto.generic.beacon_interval = + session->beaconParams.beaconInterval; + if (mlme_obj->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_AP) { + mlme_obj->mgmt.ap.hidden_ssid = session->ssidHidden; + mlme_obj->mgmt.ap.cac_duration_ms = session->cac_duration_ms; + } + mlme_obj->proto.generic.dtim_period = session->dtimPeriod; + mlme_obj->proto.generic.slot_time = session->shortSlotTimeSupported; + mlme_obj->mgmt.rate_info.bcn_tx_rate = session->beacon_tx_rate; + + mlme_obj->proto.ht_info.allow_ht = !!session->htCapability; + mlme_obj->proto.vht_info.allow_vht = !!session->vhtCapability; + + if (cds_is_5_mhz_enabled()) + mlme_obj->mgmt.rate_info.quarter_rate = 1; + else if (cds_is_10_mhz_enabled()) + mlme_obj->mgmt.rate_info.half_rate = 1; + + if (session->nss == 2) { + mlme_obj->mgmt.chainmask_info.num_rx_chain = 2; + mlme_obj->mgmt.chainmask_info.num_tx_chain = 2; + } else { + mlme_obj->mgmt.chainmask_info.num_rx_chain = 1; + mlme_obj->mgmt.chainmask_info.num_tx_chain = 1; + } + wlan_vdev_mlme_set_ssid(mlme_obj->vdev, session->ssId.ssId, + session->ssId.length); + + return lim_set_ch_phy_mode(mlme_obj->vdev, session->dot11mode); +} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.h index 245e6bf26b1646f04da6700f29480f50e1468179..99a0a790ce371624825644c17d697562928beb22 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_utils.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -193,7 +194,7 @@ void lim_update_short_slot_time(struct mac_context *mac, tSirMacAddr peerMacAddr * @frame_len: Length og mgmt frame * @session_id: session id * @psession_entry: PE Session Entry - * @rx_channel: Channel of where packet is received + * @rx_freq: Frequency on which packet is received * @rx_rssi: rssi value * @rx_flags: RXMGMT flags to be set for the frame. Defined in enum rxmgmt_flags * @@ -204,7 +205,7 @@ void lim_update_short_slot_time(struct mac_context *mac, tSirMacAddr peerMacAddr */ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type, uint8_t *frame, uint32_t frame_len, - uint16_t session_id, uint32_t rx_channel, + uint16_t session_id, uint32_t rx_freq, struct pe_session *psession_entry, int8_t rx_rssi, enum rxmgmt_flags rx_flags); @@ -218,6 +219,19 @@ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type */ void lim_deactivate_timers(struct mac_context *mac_ctx); +/* + * lim_deactivate_timers_for_vdev() - Deactivate lim connection timers + * @mac_ctx: Pointer to global mac structure + * @vdev_id: vdev id + * + * This function is used to trigger timeout of lim connection timers to abort + * connect request. + * + * Return: None + */ +void lim_deactivate_timers_for_vdev(struct mac_context *mac_ctx, + uint8_t vdev_id); + /* * The below 'product' check tobe removed if 'Association' is * allowed in IBSS. @@ -280,10 +294,19 @@ void lim_decide_sta_protection(struct mac_context *mac, void lim_decide_sta_protection_on_assoc(struct mac_context *mac, tpSchBeaconStruct pBeaconStruct, struct pe_session *pe_session); + +/** + * lim_update_sta_run_time_ht_switch_chnl_params() - Process change in HT + * bandwidth + * @mac: pointer to Global MAC structure + * @pHTInfo: ht info IE + * @pe_session: pe session + * + * Return: none + */ void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac, - tDot11fIEHTInfo *pHTInfo, - uint8_t bss_idx, - struct pe_session *pe_session); + tDot11fIEHTInfo *pHTInfo, + struct pe_session *pe_session); /* Print MAC address utility function */ void lim_print_mac_addr(struct mac_context *, tSirMacAddr, uint8_t); @@ -322,13 +345,45 @@ QDF_STATUS lim_start_channel_switch(struct mac_context *mac, void lim_update_channel_switch(struct mac_context *, tpSirProbeRespBeacon, struct pe_session *pe_session); -void lim_switch_primary_channel(struct mac_context *, uint8_t, struct pe_session *); +/** + * lim_switch_primary_channel() - switch primary channel of session + * @mac: Global MAC structure + * @new_channel_freq: new chnannel freq in Mhz + * @pe_session: pe session context + * + * This function changes the current operating channel frequency. + * + * return NONE + */ +void lim_switch_primary_channel(struct mac_context *mac, + uint32_t new_channel_freq, + struct pe_session *pe_session); + +/** + * lim_switch_primary_secondary_channel() - switch primary and secondary + * channel of session + * @mac: Global MAC structure + * @pe_session: session context + * @new_channel_freq: new channel frequency (MHz) + * @ch_center_freq_seg0: channel center freq seg0 + * @ch_center_freq_seg1: channel center freq seg1 + * @ch_width: ch width of enum phy_ch_width + * + * This function changes the primary and secondary channel. + * If 11h is enabled and user provides a "new channel freq" + * that is different from the current operating channel, + * then we must set this new channel in session context and + * assign notify LIM of such change. + * + * @return NONE + */ void lim_switch_primary_secondary_channel(struct mac_context *mac, - struct pe_session *pe_session, - uint8_t newChannel, - uint8_t ch_center_freq_seg0, - uint8_t ch_center_freq_seg1, - enum phy_ch_width ch_width); + struct pe_session *pe_session, + uint32_t new_channel_freq, + uint8_t ch_center_freq_seg0, + uint8_t ch_center_freq_seg1, + enum phy_ch_width ch_width); + void lim_update_sta_run_time_ht_capability(struct mac_context *mac, tDot11fIEHTCaps *pHTCaps); void lim_update_sta_run_time_ht_info(struct mac_context *mac, @@ -336,8 +391,20 @@ void lim_update_sta_run_time_ht_info(struct mac_context *mac, struct pe_session *pe_session); void lim_cancel_dot11h_channel_switch(struct mac_context *mac, struct pe_session *pe_session); + +/** + * lim_is_channel_valid_for_channel_switch - check channel valid for switching + * @mac: Global mac context + * @channel_freq: channel freq (MHz) + * + * This function checks if the channel to which AP is expecting us to switch, + * is a valid channel for us. + * + * Return bool, true if channel is valid + */ bool lim_is_channel_valid_for_channel_switch(struct mac_context *mac, - uint8_t channel); + uint32_t channel_freq); + QDF_STATUS lim_restore_pre_channel_switch_state(struct mac_context *mac, struct pe_session *pe_session); @@ -366,29 +433,18 @@ lim_assoc_rej_get_remaining_delta(struct sir_rssi_disallow_lst *node); QDF_STATUS lim_rem_blacklist_entry_with_lowest_delta(qdf_list_t *list); -/** - * lim_get_session_by_macaddr() - api to find session based on MAC - * @mac_ctx: Pointer to global mac structure. - * @self_mac: MAC address. - * - * This function is used to get session for given MAC address. - * - * Return: session pointer if exists, NULL otherwise. - */ -struct csr_roam_session *lim_get_session_by_macaddr(struct mac_context *mac_ctx, - tSirMacAddr self_mac); - -static inline enum band_info lim_get_rf_band(uint8_t channel) +static inline enum reg_wifi_band lim_get_rf_band(uint32_t chan_freq) { - if ((channel >= SIR_11A_CHANNEL_BEGIN) && - (channel <= SIR_11A_CHANNEL_END)) - return BAND_5G; + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq)) + return REG_BAND_6G; - if ((channel >= SIR_11B_CHANNEL_BEGIN) && - (channel <= SIR_11B_CHANNEL_END)) - return BAND_2G; + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) + return REG_BAND_5G; - return BAND_UNKNOWN; + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) + return REG_BAND_2G; + + return REG_BAND_UNKNOWN; } static inline QDF_STATUS @@ -486,7 +542,6 @@ static inline uint32_t utils_power_xy(uint16_t base, uint16_t power) } QDF_STATUS lim_post_sm_state_update(struct mac_context *mac, - uint16_t StaIdx, tSirMacHTMIMOPowerSaveState MIMOPSState, uint8_t *pPeerStaMac, uint8_t sessionId); @@ -505,10 +560,30 @@ void lim_delete_dialogue_token_list(struct mac_context *mac); void lim_add_channel_status_info(struct mac_context *p_mac, struct lim_channel_status *channel_stat, uint8_t channel_id); -uint8_t lim_get_channel_from_beacon(struct mac_context *mac, - tpSchBeaconStruct pBeacon); -tSirNwType lim_get_nw_type(struct mac_context *mac, uint8_t channelNum, - uint32_t type, tpSchBeaconStruct pBeacon); + +/** + * lim_get_channel_from_beacon() - extract channel number + * from beacon and convert to channel frequency + * @mac: Pointer to Global MAC structure + * @pBeacon: Pointer to beacon or probe rsp + * + * Return: channel frequency + */ +uint32_t lim_get_channel_from_beacon(struct mac_context *mac, + tpSchBeaconStruct pBeacon); + +/** + * lim_get_nw_type() - Get type of the network from + * data packet or beacon + * @mac: Pointer to Global MAC structure + * @chan_freq: Channel frequency + * @type: Type of packet + * @pBeacon: Pointer to beacon or probe response + * + * Return: Network type a/b/g + */ +tSirNwType lim_get_nw_type(struct mac_context *mac, uint32_t chan_freq, + uint32_t type, tpSchBeaconStruct pBeacon); void lim_set_tspec_uapsd_mask_per_session(struct mac_context *mac, struct pe_session *pe_session, @@ -532,15 +607,74 @@ void lim_update_beacon(struct mac_context *mac); void lim_process_ap_mlm_add_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ, struct pe_session *pe_session); + +/** + * lim_process_ap_mlm_del_bss_rsp() - handle del bss response of AP + * @mac: Pointer to Global MAC structure + * @vdev_stop_rsp: pointer to vdev stop response + * @pe_session: pointer to pe_session + * + * Return: none + */ void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac, - struct scheduler_msg *limMsgQ, - struct pe_session *pe_session); + struct del_bss_resp *vdev_stop_rsp, + struct pe_session *pe_session); void lim_process_ap_mlm_del_sta_rsp(struct mac_context *mac, struct scheduler_msg *limMsgQ, struct pe_session *pe_session); +#ifdef QCA_IBSS_SUPPORT +/** + * lim_is_ibss_session_active() - API to check IBSS session active + * @mac: Pointer to Global MAC structure + * + * Return: Pointer to active IBSS pe_session else NULL + */ struct pe_session *lim_is_ibss_session_active(struct mac_context *mac); +#else +/** + * lim_is_ibss_session_active() - API to check IBSS session active + * @mac: Pointer to Global MAC structure + * + * This function is dummy. + * + * Return: NULL + */ +static inline +struct pe_session *lim_is_ibss_session_active(struct mac_context *mac) +{ + return NULL; +} +#endif + +/** + * ch_width_in_mhz() - API to get channel space in MHz + * + * For CH_WIDTH_80P80MHZ, the channel space is max channel space of one + * segment - 80MHz. + * + */ +static inline uint8_t ch_width_in_mhz(enum phy_ch_width ch_width) +{ + switch (ch_width) { + case CH_WIDTH_40MHZ: + return 40; + case CH_WIDTH_80MHZ: + return 80; + case CH_WIDTH_160MHZ: + return 160; + case CH_WIDTH_80P80MHZ: + return 80; + case CH_WIDTH_5MHZ: + return 5; + case CH_WIDTH_10MHZ: + return 10; + default: + return 20; + } +} + struct pe_session *lim_is_ap_session_active(struct mac_context *mac); void lim_handle_heart_beat_failure_timeout(struct mac_context *mac); @@ -566,17 +700,16 @@ uint32_t lim_get_max_rate_flags(struct mac_context *mac_ctx, bool lim_check_vht_op_mode_change(struct mac_context *mac, struct pe_session *pe_session, - uint8_t chanWidth, uint8_t staId, + uint8_t chanWidth, uint8_t *peerMac); #ifdef WLAN_FEATURE_11AX_BSS_COLOR bool lim_send_he_ie_update(struct mac_context *mac_ctx, struct pe_session *pe_session); #endif bool lim_set_nss_change(struct mac_context *mac, struct pe_session *pe_session, - uint8_t rxNss, uint8_t staId, uint8_t *peerMac); + uint8_t rxNss, uint8_t *peerMac); bool lim_check_membership_user_position(struct mac_context *mac, struct pe_session *pe_session, - uint32_t membership, uint32_t userPosition, - uint8_t staId); + uint32_t membership, uint32_t userPosition); /** * enum ack_status - Indicate TX status of ASSOC/AUTH @@ -745,6 +878,7 @@ bool lim_check_disassoc_deauth_ack_pending(struct mac_context *mac, #ifdef WLAN_FEATURE_11W void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param); +void lim_pmf_comeback_timer_callback(void *context); void lim_set_protected_bit(struct mac_context *mac, struct pe_session *pe_session, tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr); @@ -773,13 +907,28 @@ void lim_check_and_reset_protection_params(struct mac_context *mac_ctx); QDF_STATUS lim_send_ext_cap_ie(struct mac_context *mac_ctx, uint32_t session_id, tDot11fIEExtCap *extracted_extcap, bool merge); +/** + * lim_send_ies_per_band() - gets ht and vht capability and send to firmware via + * wma + * @mac_ctx: global mac context + * @session: pe session. This can be NULL. In that case self cap will be sent + * @vdev_id: vdev for which IE is targeted + * @dot11_mode: vdev dot11 mode + * @device_mode: device mode + * + * This funciton gets ht and vht capability and send to firmware via wma + * + * Return: status of operation + */ QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx, - struct pe_session *session, uint8_t vdev_id); + struct pe_session *session, uint8_t vdev_id, + enum csr_cfgdot11mode dot11_mode, + enum QDF_OPMODE device_mode); /** * lim_send_action_frm_tb_ppdu_cfg() - sets action frame in TB PPDU cfg to FW * @mac_ctx: global MAC context - * @session_id: SME session id + * @vdev_id: vdev id * @cfg: config setting * * Preapres the vendor action frame and send action frame in HE TB PPDU @@ -788,7 +937,7 @@ QDF_STATUS lim_send_ies_per_band(struct mac_context *mac_ctx, * Return: QDF_STATUS */ QDF_STATUS lim_send_action_frm_tb_ppdu_cfg(struct mac_context *mac_ctx, - uint32_t session_id, + uint32_t vdev_id, uint8_t cfg); void lim_update_extcap_struct(struct mac_context *mac_ctx, uint8_t *buf, @@ -809,6 +958,19 @@ void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src, * Return: none */ void lim_del_pmf_sa_query_timer(struct mac_context *mac_ctx, struct pe_session *pe_session); + +/** + * lim_get_vdev_rmf_capable() - get rmf capable - MFPC + * @mac: mac context + * @session: pe session + * + * Get intersection of local & peer (BSS) RSN caps + * and check MFPC bit. + * + * Return: bool + */ +bool lim_get_vdev_rmf_capable(struct mac_context *mac, + struct pe_session *session); #else /** * lim_del_pmf_sa_query_timer() - This function deletes SA query timer @@ -823,6 +985,13 @@ static inline void lim_del_pmf_sa_query_timer(struct mac_context *mac_ctx, struct pe_session *pe_session) { } + +static inline +bool lim_get_vdev_rmf_capable(struct mac_context *mac, + struct pe_session *session) +{ + return false; +} #endif /** @@ -922,7 +1091,7 @@ QDF_STATUS lim_strip_ie(struct mac_context *mac_ctx, * * Return: None */ -void lim_intersect_ap_he_caps(struct pe_session *session, tpAddBssParams add_bss, +void lim_intersect_ap_he_caps(struct pe_session *session, struct bss_params *add_bss, tSchBeaconStruct *pBeaconStruct, tpSirAssocRsp assoc_rsp); /** @@ -938,12 +1107,15 @@ void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, struct pe_session *sessi /** * lim_add_he_cap() - Copy HE capability into Add sta params + * @mac_ctx: Global MAC context + * @pe_session: pe session entry * @add_sta_params: pointer to add sta params * @assoc_req: pointer to Assoc request * * Return: None */ -void lim_add_he_cap(tpAddStaParams add_sta_params, tpSirAssocReq assoc_req); +void lim_add_he_cap(struct mac_context *mac_ctx, struct pe_session *pe_session, + tpAddStaParams add_sta_params, tpSirAssocReq assoc_req); /** * lim_add_self_he_cap() - Copy HE capability into add sta from PE session @@ -961,7 +1133,7 @@ void lim_add_self_he_cap(tpAddStaParams add_sta_params, struct pe_session *sessi * * Return: None */ -void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp); +void lim_add_bss_he_cap(struct bss_params *add_bss, tpSirAssocRsp assoc_rsp); /** * lim_add_bss_he_cfg() - Set HE config to BSS params @@ -970,7 +1142,7 @@ void lim_add_bss_he_cap(tpAddBssParams add_bss, tpSirAssocRsp assoc_rsp); * * Return: None */ -void lim_add_bss_he_cfg(tpAddBssParams add_bss, struct pe_session *session); +void lim_add_bss_he_cfg(struct bss_params *add_bss, struct pe_session *session); /** * lim_copy_bss_he_cap() - Copy HE capability into PE session from start bss @@ -982,6 +1154,17 @@ void lim_add_bss_he_cfg(tpAddBssParams add_bss, struct pe_session *session); void lim_copy_bss_he_cap(struct pe_session *session, struct start_bss_req *sme_start_bss_req); +/** + * lim_update_he_6gop_assoc_resp() - Update HE 6GHz op info to BSS params + * @add_bss: pointer to add bss params + * @he_op: Pointer to HE operation info IE + * @session: Pointer to Session entry struct + * + * Return: None + */ +void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams, + tDot11fIEhe_op *he_op, + struct pe_session *pe_session); /** * lim_copy_join_req_he_cap() - Copy HE capability to PE session from Join req * and update as per bandwidth supported @@ -993,16 +1176,30 @@ void lim_copy_bss_he_cap(struct pe_session *session, void lim_copy_join_req_he_cap(struct pe_session *session, struct join_req *sme_join_req); +/** + * lim_log_he_6g_cap() - Print HE 6G cap IE + * @mac: pointer to MAC context + * @he_6g_cap: pointer to HE 6G cap IE + * + * Print HE 6G caps stored as dot11f structure + * + * Return: None + */ +void lim_log_he_6g_cap(struct mac_context *mac, + tDot11fIEhe_6ghz_band_cap *he_6g_cap); + /** * lim_log_he_op() - Print HE Operation * @mac: pointer to MAC context * @he_op: pointer to HE Operation + * @session: pointer to PE session * * Print HE operation stored as dot11f structure * * Return: None */ -void lim_log_he_op(struct mac_context *mac, tDot11fIEhe_op *he_ops); +void lim_log_he_op(struct mac_context *mac, tDot11fIEhe_op *he_ops, + struct pe_session *session); #ifdef WLAN_FEATURE_11AX_BSS_COLOR /** @@ -1036,11 +1233,13 @@ void lim_log_he_cap(struct mac_context *mac, tDot11fIEhe_cap *he_cap); * @sta_ds: pointer to sta dph hash table entry * @assoc_rsp: pointer to assoc response * @session_entry: pointer to PE session + * @beacon: pointer to beacon * * Return: None */ void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry); + struct pe_session *session_entry, + tSchBeaconStruct *beacon); /** * lim_update_usr_he_cap() - Update HE capability based on userspace @@ -1055,14 +1254,14 @@ void lim_update_usr_he_cap(struct mac_context *mac_ctx, struct pe_session *sessi /** * lim_decide_he_op() - Determine HE operation elements * @mac_ctx: global mac context - * @he_ops: pointer to HE operation IE + * @he_ops: mlme he ops * @session: PE session entry * * Parse the HE Operation IE and populate the fields to be * sent to FW as part of add bss. */ -void lim_decide_he_op(struct mac_context *mac_ctx, tpAddBssParams add_bss, - struct pe_session *session); +void lim_decide_he_op(struct mac_context *mac_ctx, uint32_t *mlme_he_ops, + struct pe_session *session); /** * lim_update_sta_he_capable(): Update he_capable in add sta params @@ -1082,6 +1281,21 @@ static inline bool lim_is_session_he_capable(struct pe_session *session) return session->he_capable; } +/** + * lim_update_he_bw_cap_mcs(): Update he mcs map per bandwidth + * @session_entry: pointer to PE session + * @beacon: pointer to beacon + * + * Return: None + */ +void lim_update_he_bw_cap_mcs(struct pe_session *session, + tSirProbeRespBeacon *beacon); + +static inline bool lim_is_he_6ghz_band(struct pe_session *session) +{ + return session->he_6ghz_band; +} + /** * lim_get_session_he_frag_cap(): Get session HE fragmentation cap * @session: pointer to session @@ -1099,13 +1313,14 @@ static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds) } /** - * lim_update_bss_he_capable(): Update he_capable in add BSS params + * lim_update_bss_he_capable() - Update he_capable in add BSS params * @mac: pointer to MAC context * @add_bss: pointer to add BSS params * * Return: None */ -void lim_update_bss_he_capable(struct mac_context *mac, tpAddBssParams add_bss); +void lim_update_bss_he_capable(struct mac_context *mac, + struct bss_params *add_bss); /** * lim_update_stads_he_capable() - Update he_capable in sta ds context @@ -1126,13 +1341,18 @@ void lim_update_stads_he_capable(tpDphHashNode sta_ds, tpSirAssocReq assoc_req); void lim_update_session_he_capable(struct mac_context *mac, struct pe_session *session); /** - * lim_update_chan_he_capable(): Update he_capable in chan switch params + * lim_update_session_he_capable_chan_switch(): Update he_capable in PE session * @mac: pointer to MAC context - * @chan: pointer to channel switch params + * @session: pointer to PE session + * @new_chan_freq: new channel frequency Mhz + * + * Update session he capable during AP channel switching * * Return: None */ -void lim_update_chan_he_capable(struct mac_context *mac, tpSwitchChannelParams chan); +void lim_update_session_he_capable_chan_switch(struct mac_context *mac, + struct pe_session *session, + uint32_t new_chan_freq); /** * lim_set_he_caps() - update HE caps to be sent to FW as part of scan IE @@ -1180,8 +1400,36 @@ QDF_STATUS lim_populate_he_mcs_set(struct mac_context *mac_ctx, struct pe_session *session_entry, uint8_t nss); +/** + * lim_update_stads_he_6ghz_op() - Update sta ds channel info + * @session: pe session + * @sta_ds: pointer to sta ds struct + + * Update sta_ds channel width. + * + * Return: void + */ +void lim_update_stads_he_6ghz_op(struct pe_session *session, + tpDphHashNode sta_ds); + +/** + * lim_update_he_6ghz_band_caps() - Update he 6ghz band caps + * @mac_ctx: Global MAC context + * @pAssocRsp: contains the structured assoc/reassoc Response got from AP + * @add_bss: pointer to ADD BSS params + * + * Update 6ghz band caps based on HE capability + * + * Return: none + */ +void lim_update_he_6ghz_band_caps(struct mac_context *mac, + tDot11fIEhe_6ghz_band_cap *he_6ghz_band_cap, + tpAddStaParams params); + #else -static inline void lim_add_he_cap(tpAddStaParams add_sta_params, +static inline void lim_add_he_cap(struct mac_context *mac_ctx, + struct pe_session *pe_session, + tpAddStaParams add_sta_params, tpSirAssocReq assoc_req) { } @@ -1191,19 +1439,26 @@ static inline void lim_add_self_he_cap(tpAddStaParams add_sta_params, { } -static inline void lim_add_bss_he_cap(tpAddBssParams add_bss, +static inline void lim_add_bss_he_cap(struct bss_params *add_bss, tpSirAssocRsp assoc_rsp) { return; } -static inline void lim_add_bss_he_cfg(tpAddBssParams add_bss, +static inline void lim_add_bss_he_cfg(struct bss_params *add_bss, struct pe_session *session) { } +static inline void lim_update_he_6gop_assoc_resp( + struct bss_params *pAddBssParams, + tDot11fIEhe_op *he_op, + struct pe_session *pe_session) +{ +} + static inline void lim_intersect_ap_he_caps(struct pe_session *session, - tpAddBssParams add_bss, tSchBeaconStruct *pBeaconStruct, + struct bss_params *add_bss, tSchBeaconStruct *pBeaconStruct, tpSirAssocRsp assoc_rsp) { return; @@ -1215,7 +1470,7 @@ static inline void lim_intersect_sta_he_caps(tpSirAssocReq assoc_req, } static inline void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, - struct pe_session *session_entry) + struct pe_session *session_entry, tSchBeaconStruct *beacon) { return; } @@ -1226,7 +1481,7 @@ static inline void lim_update_usr_he_cap(struct mac_context *mac_ctx, } static inline void lim_decide_he_op(struct mac_context *mac_ctx, - tpAddBssParams add_bss, struct pe_session *session) + uint32_t *mlme_he_ops, struct pe_session *session) { } @@ -1242,7 +1497,8 @@ static inline void lim_copy_join_req_he_cap(struct pe_session *session, } static inline void lim_log_he_op(struct mac_context *mac, - tDot11fIEhe_op *he_ops) + tDot11fIEhe_op *he_ops, + struct pe_session *session) { } @@ -1262,6 +1518,16 @@ static inline bool lim_is_session_he_capable(struct pe_session *session) return false; } +static inline void lim_update_he_bw_cap_mcs(struct pe_session *session, + tSirProbeRespBeacon *beacon) +{ +} + +static inline bool lim_is_he_6ghz_band(struct pe_session *session) +{ + return false; +} + static inline uint8_t lim_get_session_he_frag_cap(struct pe_session *session) { return 0; @@ -1273,7 +1539,7 @@ static inline bool lim_is_sta_he_capable(tpDphHashNode sta_ds) } static inline void lim_update_bss_he_capable(struct mac_context *mac, - tpAddBssParams add_bss) + struct bss_params *add_bss) { } @@ -1287,8 +1553,10 @@ static inline void lim_update_session_he_capable(struct mac_context *mac, { } -static inline void lim_update_chan_he_capable(struct mac_context *mac, - tpSwitchChannelParams chan) +static inline +void lim_update_session_he_capable_chan_switch(struct mac_context *mac, + struct pe_session *session, + uint32_t new_chan_freq) { } @@ -1315,6 +1583,42 @@ QDF_STATUS lim_populate_he_mcs_set(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } +static inline void +lim_update_stads_he_6ghz_op(struct pe_session *session, + tpDphHashNode sta_ds) +{ +} + +static inline void +lim_update_he_6ghz_band_caps(struct mac_context *mac, + tDot11fIEhe_6ghz_band_cap *he_6ghz_band_cap, + tpAddStaParams params) +{ +} +#endif + +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +/** + * lim_send_he_6g_band_caps_ie() - Send HE 6ghz band caps to FW + * @mac_ctx: Global MAC context + * @session: session ptr + * @vdev_id: vdev id + * + * Send HE 6ghz band capabilities IE to firmware + * + * Return: QDF_STATUS_SUCCESS on success + */ +QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx, + struct pe_session *session, + uint8_t vdev_id); +#else +static inline +QDF_STATUS lim_send_he_6g_band_caps_ie(struct mac_context *mac_ctx, + struct pe_session *session, + uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} #endif /** @@ -1427,17 +1731,35 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx, * sta capability. * * @mac_ctx: pointer to global mac structure - * @new_channel: new channel to switch to. - * @ch_bandwidth: BW of channel to calculate op_class + * @new_channel_freq: new channel freq(Mhz) to switch to. + * @ch_bandwidth: ch bw of enum phy_ch_width * @session_entry: pe session * * Return: void */ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, - uint16_t new_channel, - uint8_t ch_bandwidth, + uint16_t new_channel_freq, + enum phy_ch_width ch_bandwidth, struct pe_session *session_entry); +/** + * send_extended_chan_switch_action_frame()- function to send ECSA + * action frame for each sta connected to SAP/GO and AP in case of + * STA . + * @mac_ctx: pointer to global mac structure + * @new_channel_freq: new channel to switch to. + * @ch_bandwidth: channel bw of type enum phy_ch_width + * @session_entry: pe session + * + * This function is called to send ECSA frame for STA/CLI and SAP/GO. + * + * Return: void + */ +void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, + uint16_t new_channel_freq, + enum phy_ch_width ch_bandwidth, + struct pe_session *session_entry); + /** * lim_process_obss_detection_ind() - Process obss detection indication * @mac_ctx: Pointer to Global MAC structure. @@ -1735,40 +2057,6 @@ QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *event); -#ifdef CRYPTO_SET_KEY_CONVERGED -static inline bool lim_is_set_key_req_converged(void) -{ - return true; -} - -static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst, - struct qdf_mac_addr *src) -{ - qdf_copy_macaddr(dst, src); -} -#else -static inline bool lim_is_set_key_req_converged(void) -{ - return false; -} - -static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst, - struct qdf_mac_addr *src) -{ -} -#endif - -/** - * lim_get_regulatory_max_transmit_power() - Get regulatory max transmit - * power on given channel - * @mac: pointer to mac data - * @channel: channel number - * - * Return: int8_t - power - */ -int8_t lim_get_regulatory_max_transmit_power(struct mac_context *mac, - uint8_t channel); - /** * lim_get_capability_info() - Get capability information * @mac: pointer to mac data @@ -1781,6 +2069,23 @@ int8_t lim_get_regulatory_max_transmit_power(struct mac_context *mac, QDF_STATUS lim_get_capability_info(struct mac_context *mac, uint16_t *pCap, struct pe_session *pe_session); +/** + * lim_op_class_from_bandwidth() - get op class from bandwidth + * @mac_ctx: mac context + * @channel_freq: channel frequency MHz + * @ch_bandwidth: channel bandwidth + * @offset: second channel offfset + * + * This API can get the operating class based on channel freq, + * bandwidth and second channel offset. + * + * Return: op class + */ +uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx, + uint16_t channel_freq, + enum phy_ch_width ch_bandwidth, + enum offset_t offset); + /** * lim_flush_bssid() - flush bssid from scan cache * @mac_ctx: pointer to mac data @@ -1800,4 +2105,41 @@ void lim_flush_bssid(struct mac_context *mac_ctx, uint8_t *bssid); */ bool lim_is_sha384_akm(enum ani_akm_type akm); + +/** + * lim_pre_vdev_start() - set set vdev params from session + * @mac: pointer to mac context + * @mlme_obj: vdev mlme obj + * @session: pointer to pe session + * + * Return: QDF_STATUS + */ +QDF_STATUS lim_pre_vdev_start(struct mac_context *mac, + struct vdev_mlme_obj *mlme_obj, + struct pe_session *session); + +/** + * lim_set_ch_phy_mode() - set channel phy mode + * @vdev: pointer to vdev + * + * Return: QDF_STATUS + */ +QDF_STATUS +lim_set_ch_phy_mode(struct wlan_objmgr_vdev *vdev, uint8_t dot11mode); + +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +/** + * lim_ap_check_6g_compatible_peer() - check all client support 6Ghz band + * @mac_ctx: mac context + * @session: pe session + * + * Return: void + */ +void lim_ap_check_6g_compatible_peer(struct mac_context *mac_ctx, + struct pe_session *session); +#else +static inline void lim_ap_check_6g_compatible_peer( + struct mac_context *mac_ctx, struct pe_session *session) +{} +#endif #endif /* __LIM_UTILS_H */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.c index c4a7174f6f87c5531d732912ded04a9375207a75..0c4868f3fee8050a0288871fdc6919a24f620a1d 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -50,14 +51,18 @@ static QDF_STATUS lim_add_ndi_peer(struct mac_context *mac_ctx, QDF_STATUS status; uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 }; + if (!wlan_is_vdev_id_up(mac_ctx->pdev, vdev_id)) { + pe_err_rl("NDI vdev is not up"); + return QDF_STATUS_E_FAILURE; + } + if (!qdf_mem_cmp(&zero_mac_addr, &peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE)) { pe_err("Failing to add peer with all zero mac addr"); return QDF_STATUS_E_FAILURE; } - session = pe_find_session_by_sme_session_id(mac_ctx, - vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session) { /* couldn't find session */ pe_err("Session not found for vdev_id: %d", vdev_id); @@ -72,8 +77,8 @@ static QDF_STATUS lim_add_ndi_peer(struct mac_context *mac_ctx, pe_err("NDI Peer already exists!!"); return QDF_STATUS_SUCCESS; } - pe_info("Need to create NDI Peer :" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_mac_addr.bytes)); + pe_info("Need to create NDI Peer :" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac_addr.bytes)); peer_idx = lim_assign_peer_idx(mac_ctx, session); if (!peer_idx) { @@ -136,10 +141,10 @@ static void lim_ndp_delete_peer_by_addr(struct mac_context *mac_ctx, uint8_t vde return; } - pe_info("deleting peer: "QDF_MAC_ADDR_STR" confirm rejected", - QDF_MAC_ADDR_ARRAY(peer_ndi_mac_addr.bytes)); + pe_info("deleting peer: "QDF_MAC_ADDR_FMT" confirm rejected", + QDF_MAC_ADDR_REF(peer_ndi_mac_addr.bytes)); - session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); if (!session || (session->bssType != eSIR_NDI_MODE)) { pe_err("PE session is NULL or non-NDI for sme session %d", vdev_id); @@ -200,17 +205,17 @@ static void lim_ndp_delete_peers(struct mac_context *mac_ctx, return; for (i = 0; i < num_peers; i++) { - pe_debug("ndp_map[%d]: MAC: " QDF_MAC_ADDR_STR " num_active %d", + pe_debug("ndp_map[%d]: MAC: " QDF_MAC_ADDR_FMT " num_active %d", i, - QDF_MAC_ADDR_ARRAY(ndp_map[i].peer_ndi_mac_addr.bytes), + QDF_MAC_ADDR_REF(ndp_map[i].peer_ndi_mac_addr.bytes), ndp_map[i].num_active_ndp_sessions); /* Do not delete a peer with active NDPs */ if (ndp_map[i].num_active_ndp_sessions > 0) continue; - session = pe_find_session_by_sme_session_id(mac_ctx, - ndp_map[i].vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, + ndp_map[i].vdev_id); if (!session || (session->bssType != eSIR_NDI_MODE)) { pe_err("PE session is NULL or non-NDI for sme session %d", ndp_map[i].vdev_id); @@ -305,15 +310,10 @@ void lim_process_ndi_del_sta_rsp(struct mac_context *mac_ctx, pe_err("DEL STA failed!"); goto skip_event; } - pe_info("Deleted STA AssocID %d staId %d MAC " QDF_MAC_ADDR_STR, - sta_ds->assocId, sta_ds->staIndex, - QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); + pe_info("Deleted STA AssocID %d MAC " QDF_MAC_ADDR_FMT, + sta_ds->assocId, + QDF_MAC_ADDR_REF(sta_ds->staAddr)); - /* - * Copy peer info in del peer indication before - * lim_delete_dph_hash_entry is called as this will be lost. - */ - peer_ind.sta_id = sta_ds->staIndex; qdf_mem_copy(&peer_ind.peer_mac_addr.bytes, sta_ds->staAddr, sizeof(tSirMacAddr)); lim_release_peer_idx(mac_ctx, sta_ds->assocId, pe_session); @@ -337,36 +337,26 @@ void lim_process_ndi_del_sta_rsp(struct mac_context *mac_ctx, lim_msg->bodyptr = NULL; } -/** - * lim_process_ndi_mlm_add_bss_rsp() - Process ADD_BSS response for NDI - * @mac_ctx: Pointer to Global MAC structure - * @lim_msgq: The MsgQ header, which contains the response buffer - * @session_entry: PE session - * - * Return: None - */ void lim_process_ndi_mlm_add_bss_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *lim_msgq, + struct add_bss_rsp *add_bss_rsp, struct pe_session *session_entry) { tLimMlmStartCnf mlm_start_cnf; - tpAddBssParams add_bss_params = (tpAddBssParams) lim_msgq->bodyptr; - if (!add_bss_params) { - pe_err("Invalid body pointer in message"); - goto end; + if (!add_bss_rsp) { + pe_err("add_bss_rsp is NULL"); + return; } - pe_debug("Status %d", add_bss_params->status); - if (QDF_STATUS_SUCCESS == add_bss_params->status) { + pe_debug("Status %d", add_bss_rsp->status); + if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { pe_debug("WDA_ADD_BSS_RSP returned QDF_STATUS_SUCCESS"); session_entry->limMlmState = eLIM_MLM_BSS_STARTED_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, session_entry->limMlmState)); - session_entry->bss_idx = (uint8_t)add_bss_params->bss_idx; + session_entry->vdev_id = add_bss_rsp->vdev_id; session_entry->limSystemRole = eLIM_NDI_ROLE; session_entry->statypeForBss = STA_ENTRY_SELF; - session_entry->staId = add_bss_params->staContext.staIdx; /* Apply previously set configuration at HW */ lim_apply_configuration(mac_ctx, session_entry); mlm_start_cnf.resultCode = eSIR_SME_SUCCESS; @@ -375,29 +365,18 @@ void lim_process_ndi_mlm_add_bss_rsp(struct mac_context *mac_ctx, lim_init_peer_idxpool(mac_ctx, session_entry); } else { pe_err("WDA_ADD_BSS_REQ failed with status %d", - add_bss_params->status); + add_bss_rsp->status); mlm_start_cnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; } mlm_start_cnf.sessionId = session_entry->peSessionId; lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); -end: - qdf_mem_free(lim_msgq->bodyptr); - lim_msgq->bodyptr = NULL; } -/** - * lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface - * @mac_ctx: handle to mac structure - * @msg: pointer to message - * @session_entry: session entry - * - * Return: None - */ void lim_ndi_del_bss_rsp(struct mac_context * mac_ctx, - void *msg, struct pe_session *session_entry) + struct del_bss_resp *del_bss, + struct pe_session *session_entry) { tSirResultCodes rc = eSIR_SME_SUCCESS; - tpDeleteBssParams del_bss = (tpDeleteBssParams) msg; SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); if (!del_bss) { @@ -405,33 +384,21 @@ void lim_ndi_del_bss_rsp(struct mac_context * mac_ctx, rc = eSIR_SME_STOP_BSS_FAILURE; goto end; } - session_entry = - pe_find_session_by_session_id(mac_ctx, del_bss->sessionId); + session_entry = pe_find_session_by_vdev_id(mac_ctx, del_bss->vdev_id); if (!session_entry) { pe_err("Session Does not exist for given sessionID"); goto end; } if (del_bss->status != QDF_STATUS_SUCCESS) { - pe_err("NDI: DEL_BSS_RSP error (%x) Bss %d", - del_bss->status, del_bss->bss_idx); + pe_err("NDI: DEL_BSS_RSP error (%x)", del_bss->status); rc = eSIR_SME_STOP_BSS_FAILURE; goto end; } - if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE, - session_entry->self_mac_addr, - session_entry->self_mac_addr, NULL, NULL) - != QDF_STATUS_SUCCESS) { - pe_err("NDI: DEL_BSS_RSP setLinkState failed"); - goto end; - } - session_entry->limMlmState = eLIM_MLM_IDLE_STATE; end: - if (del_bss) - qdf_mem_free(del_bss); /* Delete PE session once BSS is deleted */ if (session_entry) { lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP, @@ -475,7 +442,6 @@ static QDF_STATUS lim_send_sme_ndp_add_sta_rsp(struct mac_context *mac_ctx, qdf_mem_copy(new_peer_ind->peer_mac_addr.bytes, add_sta_rsp->staMac, sizeof(tSirMacAddr)); - new_peer_ind->sta_id = add_sta_rsp->staIdx; ucfg_nan_datapath_event_handler(psoc, vdev, NDP_NEW_PEER, new_peer_ind); qdf_mem_free(new_peer_ind); @@ -508,23 +474,22 @@ void lim_ndp_add_sta_rsp(struct mac_context *mac_ctx, struct pe_session *session &session->dph.dphHashTable); if (!sta_ds) { pe_err("NAN: ADD_STA_RSP for unknown MAC addr " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(add_sta_rsp->staMac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(add_sta_rsp->staMac)); qdf_mem_free(add_sta_rsp); return; } if (add_sta_rsp->status != QDF_STATUS_SUCCESS) { - pe_err("NAN: ADD_STA_RSP error %x for MAC addr: %pM", - add_sta_rsp->status, add_sta_rsp->staMac); + pe_err("NAN: ADD_STA_RSP error %x for MAC addr: "QDF_MAC_ADDR_FMT, + add_sta_rsp->status, + QDF_MAC_ADDR_REF(add_sta_rsp->staMac)); /* delete the sta_ds allocated during ADD STA */ lim_delete_dph_hash_entry(mac_ctx, add_sta_rsp->staMac, peer_idx, session); qdf_mem_free(add_sta_rsp); return; } - sta_ds->bssId = add_sta_rsp->bss_idx; - sta_ds->staIndex = add_sta_rsp->staIdx; sta_ds->valid = 1; sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; lim_send_sme_ndp_add_sta_rsp(mac_ctx, session, add_sta_rsp); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.h b/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.h index fbd130050dbc8fb8c7b37603f277a7cdbc3cf2c4..332a2d9cd0f9fc7150c396cc9238d2b780ca17c4 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.h +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/nan/nan_datapath.h @@ -33,14 +33,33 @@ struct peer_nan_datapath_map; +/** + * lim_process_ndi_mlm_add_bss_rsp() - Process ADD_BSS response for NDI + * @mac_ctx: Pointer to Global MAC structure + * @add_bss_rsp: Bss params including rsp data + * @session_entry: PE session + * + * Return: None + */ void lim_process_ndi_mlm_add_bss_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *lim_msg_q, + struct add_bss_rsp *add_bss_rsp, struct pe_session *session_entry); /* Handler for DEL BSS resp for NDI interface */ + +/** + * lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface + * @mac_ctx: handle to mac structure + * @del_bss: pointer to del bss response + * @session_entry: session entry + * + * Return: None + */ void lim_ndi_del_bss_rsp(struct mac_context * mac_ctx, - void *msg, struct pe_session *session_entry); + struct del_bss_resp *del_bss, + struct pe_session *session_entry); -void lim_ndp_add_sta_rsp(struct mac_context *mac_ctx, struct pe_session *session_entry, +void lim_ndp_add_sta_rsp(struct mac_context *mac_ctx, + struct pe_session *session_entry, tAddStaParams *add_sta_rsp); void lim_process_ndi_del_sta_rsp(struct mac_context *mac_ctx, @@ -57,24 +76,39 @@ void lim_ndp_delete_peers_by_addr_converged(uint8_t vdev_id, struct qdf_mac_addr peer_ndi_mac_addr); #else -static inline void lim_process_ndi_mlm_add_bss_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *lim_msg_q, - struct pe_session *session_entry) +static inline +void lim_process_ndi_mlm_add_bss_rsp(struct mac_context *mac_ctx, + struct add_bss_rsp *add_bss_rsp, + struct pe_session *session_entry) { } -static inline void lim_ndi_del_bss_rsp(struct mac_context *mac_ctx, - void *msg, struct pe_session *session_entry) + +/** + * lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface + * @mac_ctx: handle to mac structure + * @del_bss: pointer to del bss response + * @session_entry: session entry + * + * Return: None + */ +static inline +void lim_ndi_del_bss_rsp(struct mac_context *mac_ctx, + struct del_bss_resp *del_bss, + struct pe_session *session_entry) { } -static inline void lim_process_ndi_del_sta_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *lim_msg, - struct pe_session *pe_session) + +static inline +void lim_process_ndi_del_sta_rsp(struct mac_context *mac_ctx, + struct scheduler_msg *lim_msg, + struct pe_session *pe_session) { } -static inline void lim_ndp_add_sta_rsp(struct mac_context *mac_ctx, - struct pe_session *session_entry, - tAddStaParams *add_sta_rsp) +static inline +void lim_ndp_add_sta_rsp(struct mac_context *mac_ctx, + struct pe_session *session_entry, + tAddStaParams *add_sta_rsp) { } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/rrm/rrm_api.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/rrm/rrm_api.c index ca60416a9b765820d98515081eef33dcdf7df8d4..71b4235dbccf1e81980f1bffafd08cb2134d39d6 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/rrm/rrm_api.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/rrm/rrm_api.c @@ -202,6 +202,24 @@ QDF_STATUS rrm_set_max_tx_power_rsp(struct mac_context *mac, return retCode; } +/** + * rrm_calculate_and_fill_rcpi() - calculates and fills RCPI value + * @rcpi: pointer to hold calculated RCPI value + * @cur_rssi: value of current RSSI + * + * @return None + */ +static void rrm_calculate_and_fill_rcpi(uint8_t *rcpi, int8_t cur_rssi) +{ + /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */ + if (cur_rssi <= RCPI_LOW_RSSI_VALUE) + *rcpi = 0; + else if ((cur_rssi > RCPI_LOW_RSSI_VALUE) && (cur_rssi <= 0)) + *rcpi = CALCULATE_RCPI(cur_rssi); + else + *rcpi = RCPI_MAX_VALUE; +} + /* -------------------------------------------------------------------- */ /** * rrm_process_link_measurement_request @@ -245,7 +263,10 @@ rrm_process_link_measurement_request(struct mac_context *mac, LinkReport.txPower = lim_get_max_tx_power(mac, &tx_pwr_attr); - /* Use firmware updated max tx power if non zero */ + /** If firmware updated max tx power is non zero, respond to rrm link + * measurement request with min of firmware updated ap tx power and + * max power derived from lim_get_max_tx_power API. + */ mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev); if (mlme_obj && mlme_obj->mgmt.generic.tx_pwrlimit) LinkReport.txPower = QDF_MIN(LinkReport.txPower, @@ -271,14 +292,7 @@ rrm_process_link_measurement_request(struct mac_context *mac, pe_info("Received Link report frame with %d", currentRSSI); - /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */ - if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE) - LinkReport.rcpi = 0; - else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0)) - LinkReport.rcpi = CALCULATE_RCPI(currentRSSI); - else - LinkReport.rcpi = RCPI_MAX_VALUE; - + rrm_calculate_and_fill_rcpi(&LinkReport.rcpi, currentRSSI); LinkReport.rsni = WMA_GET_RX_SNR(pRxPacketInfo); pe_debug("Sending Link report frame"); @@ -379,7 +393,7 @@ rrm_process_neighbor_report_response(struct mac_context *mac, fMobilityDomain = pNeighborRep->NeighborReport[i].MobilityDomain; - if (!wlan_reg_is_6ghz_supported(mac->pdev) && + if (!wlan_reg_is_6ghz_supported(mac->psoc) && (wlan_reg_is_6ghz_op_class(mac->pdev, pNeighborRep->NeighborReport[i]. regulatoryClass))) { @@ -473,6 +487,44 @@ rrm_process_neighbor_report_req(struct mac_context *mac, return status; } +/** + * rrm_get_country_code_from_connected_profile() - Get country code + * from connected profile + * @mac: Mac context + * @pe_session: pe session + * @country_code: country code + * + * Return: void + */ +static inline void +rrm_get_country_code_from_connected_profile( + struct mac_context *mac, + struct pe_session *pe_session, + uint8_t country_code[WNI_CFG_COUNTRY_CODE_LEN]) +{ + uint8_t id; + uint8_t *country; + + qdf_mem_zero(country_code, sizeof(country_code[0]) * + WNI_CFG_COUNTRY_CODE_LEN); + if (!pe_session) { + pe_err("pe_session is NULL"); + return; + } + id = pe_session->smeSessionId; + if (!CSR_IS_SESSION_VALID(mac, id)) { + pe_err("smeSessionId %d is invalid", id); + return; + } + country = + mac->roam.roamSession[id].connectedProfile.country_code; + if (country[0]) + qdf_mem_copy(country_code, country, sizeof(country_code[0]) * + WNI_CFG_COUNTRY_CODE_LEN); + else + country_code[2] = OP_CLASS_GLOBAL; +} + #define ABS(x) ((x < 0) ? -x : x) /* -------------------------------------------------------------------- */ /** @@ -497,18 +549,23 @@ rrm_process_beacon_report_req(struct mac_context *mac, tDot11fIEMeasurementRequest *pBeaconReq, struct pe_session *pe_session) { - struct scheduler_msg mmhMsg = {0}; - tpSirBeaconReportReqInd pSmeBcnReportReq; - uint8_t num_channels = 0, num_APChanReport; + struct scheduler_msg mmh_msg = {0}; + tpSirBeaconReportReqInd psbrr; + uint8_t num_rpt, idx_rpt; uint16_t measDuration, maxMeasduration; int8_t maxDuration; uint8_t sign; tDot11fIEAPChannelReport *ie_ap_chan_rpt; - uint8_t buf_left, buf_cons; - uint16_t ch_ctr = 0, idx_rpt = 0; + uint8_t tmp_idx, buf_left, buf_cons; + uint16_t ch_ctr = 0; char ch_buf[RRM_CH_BUF_LEN]; char *tmp_buf = NULL; - uint8_t *ch_lst = NULL; + uint8_t country[WNI_CFG_COUNTRY_CODE_LEN]; + + if (!pe_session) { + pe_err("pe_session is NULL"); + return eRRM_INCAPABLE; + } if (pBeaconReq->measurement_request.Beacon.BeaconReporting.present && (pBeaconReq->measurement_request.Beacon.BeaconReporting. @@ -544,11 +601,11 @@ rrm_process_beacon_report_req(struct mac_context *mac, measDuration = pBeaconReq->measurement_request.Beacon.meas_duration; - pe_nofl_info("RX: [802.11 BCN_RPT] seq:%d SSID:%.*s BSSID:%pM Token:%d op_class:%d ch:%d meas_mode:%d meas_duration:%d max_dur: %d sign: %d max_meas_dur: %d", + pe_nofl_info("RX: [802.11 BCN_RPT] seq:%d SSID:%.*s BSSID:"QDF_MAC_ADDR_FMT" Token:%d op_class:%d ch:%d meas_mode:%d meas_duration:%d max_dur: %d sign: %d max_meas_dur: %d", mac->rrm.rrmPEContext.prev_rrm_report_seq_num, pBeaconReq->measurement_request.Beacon.SSID.num_ssid, pBeaconReq->measurement_request.Beacon.SSID.ssid, - pBeaconReq->measurement_request.Beacon.BSSID, + QDF_MAC_ADDR_REF(pBeaconReq->measurement_request.Beacon.BSSID), pBeaconReq->measurement_token, pBeaconReq->measurement_request.Beacon.regClass, pBeaconReq->measurement_request.Beacon.channel, @@ -581,7 +638,7 @@ rrm_process_beacon_report_req(struct mac_context *mac, pBeaconReq->measurement_request.Beacon. last_beacon_report_indication.last_fragment; pe_debug("RX: [802.11 BCN_RPT] Last Bcn Report in the req: %d", - pCurrentReq->request.Beacon.last_beacon_report_indication); + pCurrentReq->request.Beacon.last_beacon_report_indication); } else { pCurrentReq->request.Beacon.last_beacon_report_indication = 0; pe_debug("RX: [802.11 BCN_RPT] Last Bcn rpt ind not present"); @@ -607,116 +664,127 @@ rrm_process_beacon_report_req(struct mac_context *mac, pBeaconReq->measurement_request.Beacon. RequestedInfo.requested_eids, pCurrentReq->request.Beacon.reqIes.num); - pe_debug("RX: [802.11 BCN_RPT] Requested EIDs:[%d]", - pCurrentReq->request.Beacon.reqIes.num); } - if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) { - for (num_APChanReport = 0; - num_APChanReport < - pBeaconReq->measurement_request.Beacon.num_APChannelReport; - num_APChanReport++) - num_channels += - pBeaconReq->measurement_request.Beacon. - APChannelReport[num_APChanReport].num_channelList; - } /* Prepare the request to send to SME. */ - pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); - if (!pSmeBcnReportReq) + psbrr = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); + if (!psbrr) return eRRM_FAILURE; /* Alloc memory for pSmeBcnReportReq, will be freed by other modules */ - qdf_mem_copy(pSmeBcnReportReq->bssId, pe_session->bssId, + qdf_mem_copy(psbrr->bssId, pe_session->bssId, sizeof(tSirMacAddr)); - pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; - pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd); - pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token; - pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_11K; - pSmeBcnReportReq->randomizationInterval = + psbrr->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + psbrr->length = sizeof(tSirBeaconReportReqInd); + psbrr->uDialogToken = pBeaconReq->measurement_token; + psbrr->msgSource = eRRM_MSG_SOURCE_11K; + psbrr->randomizationInterval = SYS_TU_TO_MS(pBeaconReq->measurement_request.Beacon.randomization); - pSmeBcnReportReq->measurement_idx = pCurrentReq->measurement_idx; + psbrr->measurement_idx = pCurrentReq->measurement_idx; - if (!wlan_reg_is_6ghz_supported(mac->pdev) && + if (!wlan_reg_is_6ghz_supported(mac->psoc) && (wlan_reg_is_6ghz_op_class(mac->pdev, pBeaconReq->measurement_request.Beacon.regClass))) { pe_nofl_err("RX: [802.11 BCN_RPT] Ch belongs to 6 ghz spectrum, abort"); - qdf_mem_free(pSmeBcnReportReq); + qdf_mem_free(psbrr); return eRRM_FAILURE; } - pSmeBcnReportReq->channelInfo.regulatoryClass = - pBeaconReq->measurement_request.Beacon.regClass; - pSmeBcnReportReq->channelInfo.channelNum = + rrm_get_country_code_from_connected_profile(mac, pe_session, + country); + psbrr->channel_info.chan_num = pBeaconReq->measurement_request.Beacon.channel; - pSmeBcnReportReq->measurementDuration[0] = measDuration; - pSmeBcnReportReq->fMeasurementtype[0] = + psbrr->channel_info.reg_class = + pBeaconReq->measurement_request.Beacon.regClass; + if (psbrr->channel_info.chan_num && + psbrr->channel_info.chan_num != 255) { + psbrr->channel_info.chan_freq = + wlan_reg_country_chan_opclass_to_freq( + mac->pdev, + country, + psbrr->channel_info.chan_num, + psbrr->channel_info.reg_class, + false); + if (!psbrr->channel_info.chan_freq) { + pe_debug("invalid ch freq, chan_num %d", + psbrr->channel_info.chan_num); + qdf_mem_free(psbrr); + return eRRM_FAILURE; + } + } else { + psbrr->channel_info.chan_freq = 0; + } + sme_debug("opclass %d, ch %d freq %d AP's country code %c%c 0x%x index:%d", + psbrr->channel_info.reg_class, + psbrr->channel_info.chan_num, + psbrr->channel_info.chan_freq, + country[0], country[1], country[2], + psbrr->measurement_idx); + + psbrr->measurementDuration[0] = measDuration; + psbrr->fMeasurementtype[0] = pBeaconReq->measurement_request.Beacon.meas_mode; - qdf_mem_copy(pSmeBcnReportReq->macaddrBssid, + qdf_mem_copy(psbrr->macaddrBssid, pBeaconReq->measurement_request.Beacon.BSSID, sizeof(tSirMacAddr)); if (pBeaconReq->measurement_request.Beacon.SSID.present) { - pSmeBcnReportReq->ssId.length = + psbrr->ssId.length = pBeaconReq->measurement_request.Beacon.SSID.num_ssid; - qdf_mem_copy(pSmeBcnReportReq->ssId.ssId, + qdf_mem_copy(psbrr->ssId.ssId, pBeaconReq->measurement_request.Beacon.SSID.ssid, - pSmeBcnReportReq->ssId.length); + psbrr->ssId.length); } pCurrentReq->token = pBeaconReq->measurement_token; - pSmeBcnReportReq->channelList.numChannels = num_channels; - if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) { - uint8_t len; - ch_lst = pSmeBcnReportReq->channelList.channelNumber; - - for (num_APChanReport = 0; - num_APChanReport < - pBeaconReq->measurement_request.Beacon. - num_APChannelReport; num_APChanReport++) { - ie_ap_chan_rpt = &pBeaconReq->measurement_request. - Beacon.APChannelReport[num_APChanReport]; - if (!wlan_reg_is_6ghz_supported(mac->pdev) && + num_rpt = pBeaconReq->measurement_request.Beacon.num_APChannelReport; + for (idx_rpt = 0; idx_rpt < num_rpt; idx_rpt++) { + ie_ap_chan_rpt = + &pBeaconReq->measurement_request.Beacon.APChannelReport[idx_rpt]; + for (tmp_idx = 0; + tmp_idx < ie_ap_chan_rpt->num_channelList; + tmp_idx++) { + if (!wlan_reg_is_6ghz_supported(mac->psoc) && (wlan_reg_is_6ghz_op_class(mac->pdev, - ie_ap_chan_rpt->regulatoryClass))) { + ie_ap_chan_rpt->regulatoryClass))) { pe_nofl_err("RX: [802.11 BCN_RPT] Ch belongs to 6 ghz spectrum, abort"); - qdf_mem_free(pSmeBcnReportReq); + qdf_mem_free(psbrr); return eRRM_FAILURE; } - len = pBeaconReq->measurement_request.Beacon. - APChannelReport[num_APChanReport].num_channelList; - if (ch_ctr + len > - sizeof(pSmeBcnReportReq->channelList.channelNumber)) - break; + psbrr->channel_list.chan_freq_lst[ch_ctr++] = + wlan_reg_country_chan_opclass_to_freq( + mac->pdev, country, + ie_ap_chan_rpt->channelList[tmp_idx], + ie_ap_chan_rpt->regulatoryClass, true); - qdf_mem_copy(&ch_lst[ch_ctr], - pBeaconReq->measurement_request.Beacon. - APChannelReport[num_APChanReport]. - channelList, len); - - ch_ctr += len; - } - - buf_left = sizeof(ch_buf); - tmp_buf = ch_buf; - for (idx_rpt = 0; idx_rpt < ch_ctr; idx_rpt++) { - buf_cons = qdf_snprint(tmp_buf, buf_left, "%d ", - ch_lst[idx_rpt]); - buf_left -= buf_cons; - tmp_buf += buf_cons; + if (ch_ctr >= QDF_ARRAY_SIZE(psbrr->channel_list.chan_freq_lst)) + break; } + if (ch_ctr >= QDF_ARRAY_SIZE(psbrr->channel_list.chan_freq_lst)) + break; + } - if (ch_ctr) - pe_nofl_info("RX: [802.11 BCN_RPT] Ch-list:%s", ch_buf); + psbrr->channel_list.num_channels = ch_ctr; + buf_left = sizeof(ch_buf); + tmp_buf = ch_buf; + for (idx_rpt = 0; idx_rpt < ch_ctr; idx_rpt++) { + buf_cons = qdf_snprint(tmp_buf, buf_left, "%d ", + psbrr->channel_list.chan_freq_lst[idx_rpt]); + buf_left -= buf_cons; + tmp_buf += buf_cons; } + if (ch_ctr) + pe_nofl_info("RX: [802.11 BCN_RPT] Ch-list:%s", ch_buf); + /* Send request to SME. */ - mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND; - mmhMsg.bodyptr = pSmeBcnReportReq; + mmh_msg.type = eWNI_SME_BEACON_REPORT_REQ_IND; + mmh_msg.bodyptr = psbrr; MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG, - pe_session->peSessionId, mmhMsg.type)); - lim_sys_process_mmh_msg_api(mac, &mmhMsg); + pe_session->peSessionId, mmh_msg.type)); + lim_sys_process_mmh_msg_api(mac, &mmh_msg); return eRRM_SUCCESS; } @@ -853,9 +921,7 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, tSirMacRadioMeasureReport *report = NULL; tSirMacBeaconReport *beacon_report; struct bss_description *bss_desc; - tpRRMReq curr_req = - mac_ctx->rrm.rrmPEContext. - pCurrentReq[beacon_xmit_ind->measurement_idx]; + tpRRMReq curr_req; struct pe_session *session_entry; uint8_t session_id, counter; uint8_t i, j, offset = 0; @@ -863,7 +929,8 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, uint8_t report_index = 0; uint8_t rem_len = 0; uint8_t frag_id = 0; - uint8_t num_frames, num_reports_in_frame; + uint8_t num_frames, num_reports_in_frame, final_measurement_index; + bool is_last_measurement_frame; if (!beacon_xmit_ind) { @@ -871,6 +938,16 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } + if (beacon_xmit_ind->measurement_idx >= + QDF_ARRAY_SIZE(mac_ctx->rrm.rrmPEContext.pCurrentReq)) { + pe_err("Received measurement_idx is out of range: %u - %zu", + beacon_xmit_ind->measurement_idx, + QDF_ARRAY_SIZE(mac_ctx->rrm.rrmPEContext.pCurrentReq)); + return QDF_STATUS_E_FAILURE; + } + + curr_req = mac_ctx->rrm.rrmPEContext. + pCurrentReq[beacon_xmit_ind->measurement_idx]; if (!curr_req) { pe_err("Received report xmit while there is no request pending in PE"); status = QDF_STATUS_E_FAILURE; @@ -880,7 +957,15 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, pe_debug("Received beacon report xmit indication on idx:%d", beacon_xmit_ind->measurement_idx); - if ((beacon_xmit_ind->numBssDesc) || curr_req->sendEmptyBcnRpt) { + /* + * Send empty report only if all channels on a measurement index has + * no scan results or if the AP requests for last beacon report + * indication and last channel of the last index has empty report + */ + if (beacon_xmit_ind->numBssDesc || curr_req->sendEmptyBcnRpt || + (beacon_xmit_ind->fMeasureDone && + curr_req->request.Beacon.last_beacon_report_indication && + (mac_ctx->rrm.rrmPEContext.num_active_request - 1) == 0)) { beacon_xmit_ind->numBssDesc = (beacon_xmit_ind->numBssDesc == RRM_BCN_RPT_NO_BSS_INFO) ? RRM_BCN_RPT_MIN_RPT : beacon_xmit_ind->numBssDesc; @@ -888,8 +973,8 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, session_entry = pe_find_session_by_bssid(mac_ctx, beacon_xmit_ind->bssId, &session_id); if (!session_entry) { - pe_err("TX: [802.11 BCN_RPT] Session does not exist for bssId:%pM", - beacon_xmit_ind->bssId); + pe_err("TX: [802.11 BCN_RPT] Session does not exist for bssId:"QDF_MAC_ADDR_FMT"", + QDF_MAC_ADDR_REF(beacon_xmit_ind->bssId)); status = QDF_STATUS_E_FAILURE; goto end; } @@ -928,7 +1013,10 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, continue; beacon_report->regClass = beacon_xmit_ind->regClass; if (bss_desc) { - beacon_report->channel = bss_desc->channelId; + beacon_report->channel = + wlan_reg_freq_to_chan( + mac_ctx->pdev, + bss_desc->chan_freq); qdf_mem_copy(beacon_report->measStartTime, bss_desc->startTSF, sizeof(bss_desc->startTSF)); @@ -937,23 +1025,23 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, beacon_report->phyType = bss_desc->nwType; beacon_report->bcnProbeRsp = 1; beacon_report->rsni = bss_desc->sinr; - beacon_report->rcpi = bss_desc->rssi; + + rrm_calculate_and_fill_rcpi(&beacon_report->rcpi, + bss_desc->rssi); beacon_report->antennaId = 0; beacon_report->parentTSF = bss_desc->parentTSF; qdf_mem_copy(beacon_report->bssid, bss_desc->bssId, sizeof(tSirMacAddr)); } - pe_debug("TX: [802.11 BCN_RPT] requested reporting detail %d", + pe_debug("TX: [802.11 BCN_RPT] reporting detail requested %d", curr_req->request.Beacon.reportingDetail); - switch (curr_req->request.Beacon.reportingDetail) { case BEACON_REPORTING_DETAIL_NO_FF_IE: /* 0: No need to include any elements. */ break; case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE: /* 1: Include all FFs and Requested Ies. */ - if (!bss_desc) break; @@ -1011,28 +1099,34 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, pe_debug("TX: [802.11 BCN_RPT] No remaining IEs"); } - if (curr_req->request.Beacon. - last_beacon_report_indication) { - pe_debug("TX: [802.11 BCN_RPT] Setting last beacon report support"); + if (curr_req->request.Beacon.last_beacon_report_indication) beacon_report->last_bcn_report_ind_support = 1; - } + } - pe_debug("TX: [802.11 BCN_RPT] Total reports filled %d", i); + pe_debug("TX: [802.11 BCN_RPT] Total reports filled %d, last bcn_rpt ind:%d", + i , curr_req->request.Beacon.last_beacon_report_indication); + num_frames = i / RADIO_REPORTS_MAX_IN_A_FRAME; if (i % RADIO_REPORTS_MAX_IN_A_FRAME) num_frames++; + for (j = 0; j < num_frames; j++) { num_reports_in_frame = QDF_MIN((i - report_index), RADIO_REPORTS_MAX_IN_A_FRAME); + + final_measurement_index = + mac_ctx->rrm.rrmPEContext.num_active_request; + is_last_measurement_frame = + ((j == num_frames - 1) && + beacon_xmit_ind->fMeasureDone && + !(final_measurement_index - 1)); + lim_send_radio_measure_report_action_frame(mac_ctx, curr_req->dialog_token, num_reports_in_frame, - (j == num_frames - 1) ? true : false, + is_last_measurement_frame, &report[report_index], beacon_xmit_ind->bssId, session_entry); - pe_debug("Sending Action frame number %d", - num_reports_in_frame); - report_index += num_reports_in_frame; } curr_req->sendEmptyBcnRpt = false; @@ -1043,7 +1137,8 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, qdf_mem_free(beacon_xmit_ind->pBssDescription[counter]); if (beacon_xmit_ind->fMeasureDone) { - pe_debug("Measurement done."); + pe_debug("Measurement done idx:%d", + beacon_xmit_ind->measurement_idx); rrm_cleanup(mac_ctx, beacon_xmit_ind->measurement_idx); } @@ -1073,7 +1168,8 @@ rrm_process_beacon_request_failure(struct mac_context *mac, pReport->token = pCurrentReq->token; pReport->type = SIR_MAC_RRM_BEACON_TYPE; - pe_debug("status %d token %d", status, pReport->token); + pe_debug("Measurement index:%d status %d token %d", index, status, + pReport->token); switch (status) { case eRRM_REFUSED: @@ -1083,11 +1179,14 @@ rrm_process_beacon_request_failure(struct mac_context *mac, pReport->incapable = 1; break; default: - pe_err("RX [802.11 BCN_RPT] Beacon req processing failed no report sent"); + pe_err("RX [802.11 BCN_RPT] Beacon request processing failed no report sent"); qdf_mem_free(pReport); return; } + if (pCurrentReq->request.Beacon.last_beacon_report_indication) + pReport->report.beaconReport.last_bcn_report_ind_support = 1; + lim_send_radio_measure_report_action_frame(mac, pCurrentReq->dialog_token, 1, true, @@ -1121,57 +1220,38 @@ QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer, uint8_t *num_report, int index) { tRrmRetStatus rrm_status = eRRM_SUCCESS; - tpSirMacRadioMeasureReport report; + tpSirMacRadioMeasureReport report = NULL; tpRRMReq curr_req; + QDF_STATUS status = QDF_STATUS_SUCCESS; - if (index >= MAX_MEASUREMENT_REQUEST || - mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) { - if (!*radiomes_report) { - /* - * Allocate memory to send reports for - * any subsequent requests. - */ - *radiomes_report = qdf_mem_malloc(sizeof(*report) * - (rrm_req->num_MeasurementRequest - index)); - if (!*radiomes_report) - return QDF_STATUS_E_NOMEM; - pe_debug("rrm beacon type refused of %d report in beacon table", - *num_report); - } - report = *radiomes_report; - report[*num_report].refused = 1; - report[*num_report].type = SIR_MAC_RRM_BEACON_TYPE; - report[*num_report].token = - rrm_req->MeasurementRequest[index].measurement_token; - (*num_report)++; - return QDF_STATUS_SUCCESS; - } else { - curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq[index]; - if (curr_req) { - qdf_mem_free(curr_req); - mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; - } + if (index >= MAX_MEASUREMENT_REQUEST) { + status = rrm_reject_req(&report, rrm_req, num_report, index, + rrm_req->MeasurementRequest[0]. + measurement_type); + return status; + } - curr_req = qdf_mem_malloc(sizeof(*curr_req)); - if (!curr_req) { - qdf_mem_free(*radiomes_report); - mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; - return QDF_STATUS_E_NOMEM; - } - pe_debug("Processing Beacon Report request %d", index); - curr_req->dialog_token = rrm_req->DialogToken.token; - curr_req->token = rrm_req-> - MeasurementRequest[index].measurement_token; - curr_req->sendEmptyBcnRpt = true; - curr_req->measurement_idx = index; - mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req; - rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req, - &rrm_req->MeasurementRequest[index], session_entry); - if (eRRM_SUCCESS != rrm_status) { - rrm_process_beacon_request_failure(mac_ctx, - session_entry, peer, rrm_status, index); - rrm_cleanup(mac_ctx, index); - } + curr_req = qdf_mem_malloc(sizeof(*curr_req)); + if (!curr_req) { + mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; + return QDF_STATUS_E_NOMEM; + } + pe_debug("Processing Beacon Report request %d", index); + curr_req->dialog_token = rrm_req->DialogToken.token; + curr_req->token = + rrm_req->MeasurementRequest[index].measurement_token; + curr_req->sendEmptyBcnRpt = true; + curr_req->measurement_idx = index; + mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req; + mac_ctx->rrm.rrmPEContext.num_active_request++; + pe_debug("Processing Bcn Report req %d num_active_req:%d", + index, mac_ctx->rrm.rrmPEContext.num_active_request); + rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req, + &rrm_req->MeasurementRequest[index], session_entry); + if (eRRM_SUCCESS != rrm_status) { + rrm_process_beacon_request_failure(mac_ctx, + session_entry, peer, rrm_status, index); + rrm_cleanup(mac_ctx, index); } return QDF_STATUS_SUCCESS; @@ -1218,6 +1298,37 @@ QDF_STATUS update_rrm_report(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } +QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report, + tDot11fRadioMeasurementRequest *rrm_req, + uint8_t *num_report, uint8_t index, + uint8_t measurement_type) +{ + tpSirMacRadioMeasureReport report; + + if (!*radiomes_report) { + /* + * Allocate memory to send reports for + * any subsequent requests. + */ + *radiomes_report = qdf_mem_malloc(sizeof(*report) * + (rrm_req->num_MeasurementRequest - index)); + if (!*radiomes_report) + return QDF_STATUS_E_NOMEM; + + pe_debug("rrm beacon refused of %d report, index: %d in beacon table", + *num_report, index); + } + report = *radiomes_report; + report[*num_report].refused = 1; + report[*num_report].type = measurement_type; + report[*num_report].token = + rrm_req->MeasurementRequest[index].measurement_token; + (*num_report)++; + + return QDF_STATUS_SUCCESS; + +} + /* -------------------------------------------------------------------- */ /** * rrm_process_radio_measurement_request - Process rrm request @@ -1236,10 +1347,11 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx, tDot11fRadioMeasurementRequest *rrm_req, struct pe_session *session_entry) { - uint8_t i; + uint8_t i, index; QDF_STATUS status = QDF_STATUS_SUCCESS; tpSirMacRadioMeasureReport report = NULL; uint8_t num_report = 0; + bool reject = false; if (!rrm_req->num_MeasurementRequest) { report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport)); @@ -1271,6 +1383,39 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx, goto end; } + for (index = 0; index < MAX_MEASUREMENT_REQUEST; index++) { + if (mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) { + reject = true; + pe_debug("RRM req for index: %d is already in progress", + index); + break; + } + } + + if (reject) { + for (i = 0; i < rrm_req->num_MeasurementRequest; i++) { + status = + rrm_reject_req(&report, rrm_req, &num_report, i, + rrm_req->MeasurementRequest[i]. + measurement_type); + if (QDF_IS_STATUS_ERROR(status)) { + pe_debug("Fail to Reject rrm req for index: %d", + i); + return status; + } + } + + goto end; + } + + /* + * Clear global beacon_rpt_chan_list before processing every new + * beacon report request. + */ + qdf_mem_zero(mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_list, + sizeof(uint8_t) * MAX_NUM_CHANNELS); + mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_num = 0; + for (i = 0; i < rrm_req->num_MeasurementRequest; i++) { switch (rrm_req->MeasurementRequest[i].measurement_type) { case SIR_MAC_RRM_BEACON_TYPE: @@ -1350,22 +1495,12 @@ tpRRMCaps rrm_get_capabilities(struct mac_context *mac, struct pe_session *pe_se return &mac->rrm.rrmPEContext.rrmEnabledCaps; } -/* -------------------------------------------------------------------- */ /** - * rrm_initialize - * - * FUNCTION: - * Initialize RRM module - * - * LOGIC: - * - * ASSUMPTIONS: - * - * NOTE: + * rrm_initialize() - Initialize PE RRM parameters + * @mac: Pointer to mac context * - * @return None + * Return: QDF_STATUS */ - QDF_STATUS rrm_initialize(struct mac_context *mac) { tpRRMCaps pRRMCaps = &mac->rrm.rrmPEContext.rrmEnabledCaps; @@ -1379,6 +1514,7 @@ QDF_STATUS rrm_initialize(struct mac_context *mac) mac->rrm.rrmPEContext.rrmEnable = 0; mac->rrm.rrmPEContext.prev_rrm_report_seq_num = 0xFFFF; + mac->rrm.rrmPEContext.num_active_request = 0; qdf_mem_zero(pRRMCaps, sizeof(tRRMCaps)); pRRMCaps->LinkMeasurement = 1; @@ -1400,6 +1536,9 @@ void rrm_cleanup(struct mac_context *mac, uint8_t idx) { tpRRMReq cur_rrm_req = NULL; + mac->rrm.rrmPEContext.num_active_request--; + pe_debug("Beacon report cleanup idx:%d, num_active_request:%d", + idx, mac->rrm.rrmPEContext.num_active_request); cur_rrm_req = mac->rrm.rrmPEContext.pCurrentReq[idx]; if (!cur_rrm_req) return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_gen.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_gen.c index 99ddd7e9abf5aabcc3ce75be8d8a7e7b1c98551b..f1893b712c27b7294a9f3efc0be5a0c6e11f03aa 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_gen.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_gen.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -211,6 +212,7 @@ static void sch_get_csa_ecsa_count_offset(uint8_t *ie, uint32_t ie_len, offset += elem_len; ptr += (elem_len + 2); } + } /** @@ -248,6 +250,7 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess uint8_t *addn_ie = NULL; tDot11fIEExtCap extracted_extcap; bool extcap_present = true, addnie_present = false; + bool is_6ghz_chsw; bcn_1 = qdf_mem_malloc(sizeof(tDot11fBeacon1)); if (!bcn_1) @@ -304,7 +307,8 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL, &bcn_1->SuppRates, session); populate_dot11f_ds_params(mac_ctx, &bcn_1->DSParams, - session->currentOperChannel); + wlan_reg_freq_to_chan( + mac_ctx->pdev, session->curr_op_freq)); populate_dot11f_ibss_params(mac_ctx, &bcn_1->IBSSParams, session); offset = sizeof(tAniBeaconStruct); @@ -346,11 +350,14 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess session->schBeaconOffsetBegin); /* Initialize the 'new' fields at the end of the beacon */ - - if ((session->limSystemRole == eLIM_AP_ROLE) && + is_6ghz_chsw = + WLAN_REG_IS_6GHZ_CHAN_FREQ(session->curr_op_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ + (session->gLimChannelSwitch.sw_target_freq); + if (session->limSystemRole == eLIM_AP_ROLE && session->dfsIncludeChanSwIe == true) { if (!CHAN_HOP_ALL_BANDS_ENABLE || - session->lim_non_ecsa_cap_num == 0) { + session->lim_non_ecsa_cap_num == 0 || is_6ghz_chsw) { tDot11fIEext_chan_switch_ann *ext_csa = &bcn_2->ext_chan_switch_ann; populate_dot_11_f_ext_chann_switch_ann(mac_ctx, @@ -392,12 +399,15 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess * and SAP has instructed to announce channel switch IEs * in beacon and probe responses */ - populate_dot11f_chan_switch_ann(mac_ctx, - &bcn_2->ChanSwitchAnn, session); - pe_debug("csa: mode:%d chan:%d count:%d", - bcn_2->ChanSwitchAnn.switchMode, - bcn_2->ChanSwitchAnn.newChannel, - bcn_2->ChanSwitchAnn.switchCount); + if (!is_6ghz_chsw) { + populate_dot11f_chan_switch_ann + (mac_ctx, &bcn_2->ChanSwitchAnn, + session); + pe_debug("csa: mode:%d chan:%d count:%d", + bcn_2->ChanSwitchAnn.switchMode, + bcn_2->ChanSwitchAnn.newChannel, + bcn_2->ChanSwitchAnn.switchCount); + } /* * TODO: depending the CB mode, extended channel switch * announcement need to be called @@ -432,7 +442,7 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess } } } - if (mac_ctx->rrm.rrmConfig.rrm_enabled) + if (mac_ctx->rrm.rrmConfig.sap_rrm_enabled) populate_dot11f_rrm_ie(mac_ctx, &bcn_2->RRMEnabledCap, session); @@ -461,17 +471,19 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess populate_dot11f_vht_tx_power_env(mac_ctx, &bcn_2->vht_transmit_power_env, session->ch_width, - session->currentOperChannel); + session->curr_op_freq); populate_dot11f_qcn_ie(mac_ctx, &bcn_2->qcn_ie, QCN_IE_ATTR_ID_ALL); } if (lim_is_session_he_capable(session)) { - pe_warn("Populate HE IEs"); + pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac_ctx, session, &bcn_2->he_cap); populate_dot11f_he_operation(mac_ctx, session, &bcn_2->he_op); + populate_dot11f_he_6ghz_cap(mac_ctx, session, + &bcn_2->he_6ghz_band_cap); populate_dot11f_he_bss_color_change(mac_ctx, session, &bcn_2->bss_color_change); } @@ -894,6 +906,22 @@ void lim_update_probe_rsp_template_ie_bitmap_beacon2(struct mac_context *mac, sizeof(beacon2->he_op)); } + if (beacon2->he_6ghz_band_cap.present) { + set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, + DOT11F_EID_HE_6GHZ_BAND_CAP); + qdf_mem_copy((void *)&prb_rsp->he_6ghz_band_cap, + (void *)&beacon2->he_6ghz_band_cap, + sizeof(beacon2->he_6ghz_band_cap)); + } + + if (beacon2->TPCReport.present) { + set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, + WLAN_ELEMID_TPCREP); + qdf_mem_copy((void *)&prb_rsp->TPCReport, + (void *)&beacon2->TPCReport, + sizeof(beacon2->TPCReport)); + } + } void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos) diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c index 22c2a6db001419843af1ce0014fd7ecaa7ff361c..9065f7649a137ba2a712b55fc5dae05d255e81d8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -38,8 +38,6 @@ #include "lim_utils.h" #include "lim_send_messages.h" -#include "lim_sta_hash_api.h" - #include "rrm_api.h" #ifdef FEATURE_WLAN_DIAG_SUPPORT @@ -59,7 +57,7 @@ ap_beacon_process_5_ghz(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (!session->htCapability) return; - if (bcn_struct->channelNumber != session->currentOperChannel) + if (bcn_struct->chan_freq != session->curr_op_freq) return; /* 11a (non HT) AP overlaps or */ @@ -102,7 +100,7 @@ ap_beacon_process_24_ghz(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, /* We are 11G AP. */ if ((phy_mode == WNI_CFG_PHY_MODE_11G) && (false == session->htCapability)) { - if (bcn_struct->channelNumber != session->currentOperChannel) + if (bcn_struct->chan_freq != session->curr_op_freq) return; tmp_exp = (!bcn_struct->erpPresent && @@ -131,7 +129,7 @@ ap_beacon_process_24_ghz(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, if (!session->htCapability) return; - if (bcn_struct->channelNumber != session->currentOperChannel) + if (bcn_struct->chan_freq != session->curr_op_freq) return; tmp_exp = (!bcn_struct->erpPresent && !bcn_struct->HTInfo.present) || @@ -223,16 +221,16 @@ ap_beacon_process(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, tpUpdateBeaconParams bcn_prm, struct pe_session *session) { uint32_t phy_mode; - enum band_info rf_band = BAND_UNKNOWN; + enum reg_wifi_band rf_band = REG_BAND_UNKNOWN; /* Get RF band from session */ rf_band = session->limRFBand; lim_get_phy_mode(mac_ctx, &phy_mode, session); - if (BAND_5G == rf_band) + if (REG_BAND_5G == rf_band) ap_beacon_process_5_ghz(mac_ctx, rx_pkt_info, bcn_struct, bcn_prm, session, phy_mode); - else if (BAND_2G == rf_band) + else if (REG_BAND_2G == rf_band) ap_beacon_process_24_ghz(mac_ctx, rx_pkt_info, bcn_struct, bcn_prm, session, phy_mode); } @@ -316,14 +314,11 @@ static tSirMacHTChannelWidth get_operating_channel_width(tpDphHashNode stads) } /* - * sch_bcn_process_sta() - Process the received beacon frame for sta, - * bt_amp_sta - * + * sch_bcn_process_sta() - Process the received beacon frame for sta * @mac_ctx: mac_ctx * @bcn: beacon struct * @rx_pkt_info: received packet info * @session: pe session pointer - * @bss_idx: bss index * @beaconParams: update beacon params * @sendProbeReq: out flag to indicate if probe rsp is to be sent * @pMh: mac header @@ -336,7 +331,7 @@ static bool sch_bcn_process_sta(struct mac_context *mac_ctx, tpSchBeaconStruct bcn, uint8_t *rx_pkt_info, - struct pe_session *session, uint8_t *bss_idx, + struct pe_session *session, tUpdateBeaconParams *beaconParams, uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh) { @@ -353,10 +348,9 @@ sch_bcn_process_sta(struct mac_context *mac_ctx, * This is the Beacon received from the AP we're currently associated * with. Check if there are any changes in AP's capabilities */ - if ((uint8_t) bcn->channelNumber != session->currentOperChannel) { - pe_err("Channel Change from %d --> %d - Ignoring beacon!", - session->currentOperChannel, - bcn->channelNumber); + if (bcn->chan_freq != session->curr_op_freq) { + pe_err("Channel Change freq from %d --> %d - Ignoring beacon!", + session->curr_op_freq, bcn->chan_freq); return false; } @@ -370,11 +364,7 @@ sch_bcn_process_sta(struct mac_context *mac_ctx, } lim_detect_change_in_ap_capabilities(mac_ctx, bcn, session); - if (lim_get_sta_hash_bssidx(mac_ctx, DPH_STA_HASH_INDEX_PEER, bss_idx, - session) != QDF_STATUS_SUCCESS) - return false; - - beaconParams->bss_idx = *bss_idx; + beaconParams->bss_idx = session->vdev_id; qdf_mem_copy((uint8_t *) &session->lastBeaconTimeStamp, (uint8_t *) bcn->timeStamp, sizeof(uint64_t)); session->currentBssBeaconCnt++; @@ -447,7 +437,7 @@ sch_bcn_process_sta(struct mac_context *mac_ctx, session->gLimEdcaParams, session); lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive, - sta->bssId, false); + session->vdev_id, false); } else { pe_err("Self Entry missing in Hash Table"); } @@ -487,7 +477,7 @@ static void update_nss(struct mac_context *mac_ctx, tpDphHashNode sta_ds, sta_ds->vhtSupportedRxNss = beacon->OperatingMode.rxNSS + 1; lim_set_nss_change(mac_ctx, session_entry, - sta_ds->vhtSupportedRxNss, sta_ds->staIndex, + sta_ds->vhtSupportedRxNss, mgmt_hdr->sa); } } @@ -580,8 +570,8 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, ((oper_mode != bcn->OperatingMode.chanWidth) || (sta_ds->vhtSupportedRxNss != (bcn->OperatingMode.rxNSS + 1)))) { - pe_debug("received OpMode Chanwidth %d, staIdx = %d", - bcn->OperatingMode.chanWidth, sta_ds->staIndex); + pe_debug("received OpMode Chanwidth %d", + bcn->OperatingMode.chanWidth); pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x", mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2], mac_hdr->sa[3], @@ -622,7 +612,7 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, ch_width = eHT_CHANNEL_WIDTH_20MHZ; } lim_check_vht_op_mode_change(mac_ctx, session, - ch_width, sta_ds->staIndex, mac_hdr->sa); + ch_width, mac_hdr->sa); update_nss(mac_ctx, sta_ds, bcn, session, mac_hdr); } return; @@ -649,8 +639,8 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, if (!skip_opmode_update && (oper_mode != bcn->VHTOperation.chanWidth)) { - pe_debug("received VHTOP CHWidth %d staIdx = %d", - bcn->VHTOperation.chanWidth, sta_ds->staIndex); + pe_debug("received VHTOP CHWidth %d", + bcn->VHTOperation.chanWidth); pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x", mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2], mac_hdr->sa[3], @@ -690,19 +680,17 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, } } lim_check_vht_op_mode_change(mac_ctx, session, ch_width, - sta_ds->staIndex, mac_hdr->sa); + mac_hdr->sa); } } /* * sch_bcn_process_sta_ibss() - Process the received beacon frame - * for sta, bt_amp_sta and ibss - * + * for sta and ibss * @mac_ctx: mac_ctx * @bcn: beacon struct * @rx_pkt_info: received packet info * @session: pe session pointer - * @bss_idx: bss index * @beaconParams: update beacon params * @sendProbeReq: out flag to indicate if probe rsp is to be sent * @pMh: mac header @@ -716,7 +704,6 @@ sch_bcn_process_sta_ibss(struct mac_context *mac_ctx, tpSchBeaconStruct bcn, uint8_t *rx_pkt_info, struct pe_session *session, - uint8_t *bss_idx, tUpdateBeaconParams *beaconParams, uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh) { @@ -724,7 +711,7 @@ sch_bcn_process_sta_ibss(struct mac_context *mac_ctx, uint16_t aid; uint8_t cb_mode; - if (CHAN_ENUM_14 >= session->currentOperChannel) { + if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) { if (session->force_24ghz_in_ht20) cb_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; else @@ -735,8 +722,7 @@ sch_bcn_process_sta_ibss(struct mac_context *mac_ctx, /* check for VHT capability */ sta = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid, &session->dph.dphHashTable); - if ((!sta) || ((sta) && - (STA_INVALID_IDX == sta->staIndex))) + if ((!sta)) return; sch_bcn_update_opmode_change(mac_ctx, sta, session, bcn, pMh, cb_mode); @@ -813,12 +799,12 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, struct pe_session *session) { - uint8_t bss_idx = 0; tUpdateBeaconParams beaconParams; uint8_t sendProbeReq = false; tpSirMacMgmtHdr pMh = WMA_GET_RX_MAC_HEADER(rx_pkt_info); int8_t regMax = 0, maxTxPower = 0, local_constraint; struct lim_max_tx_pwr_attr tx_pwr_attr = {0}; + uint32_t chan_freq = 0; qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); beaconParams.paramChangeBitmap = 0; @@ -826,9 +812,9 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, if (LIM_IS_IBSS_ROLE(session)) { lim_handle_ibss_coalescing(mac_ctx, bcn, rx_pkt_info, session); } else if (LIM_IS_STA_ROLE(session)) { - if (false == sch_bcn_process_sta(mac_ctx, bcn, - rx_pkt_info, session, &bss_idx, - &beaconParams, &sendProbeReq, pMh)) + if (false == sch_bcn_process_sta(mac_ctx, bcn, rx_pkt_info, + session, &beaconParams, + &sendProbeReq, pMh)) return; } @@ -840,7 +826,7 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, bcn->VHTOperation.present)) && session->htCapability && bcn->HTInfo.present && !LIM_IS_IBSS_ROLE(session)) lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx, - &bcn->HTInfo, bss_idx, session); + &bcn->HTInfo, session); if ((LIM_IS_STA_ROLE(session) && !wma_is_csa_offload_enabled()) || LIM_IS_IBSS_ROLE(session)) { @@ -865,11 +851,11 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, if (LIM_IS_STA_ROLE(session) || LIM_IS_IBSS_ROLE(session)) sch_bcn_process_sta_ibss(mac_ctx, bcn, - rx_pkt_info, session, &bss_idx, + rx_pkt_info, session, &beaconParams, &sendProbeReq, pMh); /* Obtain the Max Tx power for the current regulatory */ - regMax = lim_get_regulatory_max_transmit_power( - mac_ctx, session->currentOperChannel); + regMax = wlan_reg_get_channel_reg_power_for_freq( + mac_ctx->pdev, session->curr_op_freq); local_constraint = regMax; @@ -887,9 +873,7 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, tx_pwr_attr.reg_max = regMax; tx_pwr_attr.ap_tx_power = local_constraint; tx_pwr_attr.ini_tx_power = mac_ctx->mlme_cfg->power.max_tx_power; - tx_pwr_attr.frequency = - wlan_reg_get_channel_freq(mac_ctx->pdev, - session->currentOperChannel); + tx_pwr_attr.frequency = session->curr_op_freq; maxTxPower = lim_get_max_tx_power(mac_ctx, &tx_pwr_attr); @@ -904,12 +888,12 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, } /* Indicate to LIM that Beacon is received */ - if (bcn->HTInfo.present) - lim_received_hb_handler(mac_ctx, - (uint8_t) bcn->HTInfo.primaryChannel, session); - else - lim_received_hb_handler(mac_ctx, (uint8_t) bcn->channelNumber, - session); + if (bcn->HTInfo.present) { + chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + bcn->HTInfo.primaryChannel); + lim_received_hb_handler(mac_ctx, chan_freq, session); + } else + lim_received_hb_handler(mac_ctx, bcn->chan_freq, session); /* * I don't know if any additional IE is required here. Currently, not @@ -917,7 +901,7 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx, */ if (sendProbeReq) lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId, - session->bssId, session->currentOperChannel, + session->bssId, session->curr_op_freq, session->self_mac_addr, session->dot11mode, NULL, NULL); if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) @@ -1052,7 +1036,7 @@ void sch_beacon_process_for_ap(struct mac_context *mac_ctx, qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams)); bcn_prm.paramChangeBitmap = 0; - bcn_prm.bss_idx = ap_session->bss_idx; + bcn_prm.bss_idx = ap_session->vdev_id; if (!ap_session->is_session_obss_color_collision_det_enabled) sch_check_bss_color_ie(mac_ctx, ap_session, @@ -1108,8 +1092,7 @@ void sch_send_beacon_report(struct mac_context *mac_ctx, qdf_mem_copy(&beacon_report.time_stamp, &beacon_struct->timeStamp, sizeof(qdf_time_t)); beacon_report.beacon_interval = beacon_struct->beaconInterval; - beacon_report.frequency = - cds_chan_to_freq(beacon_struct->channelNumber); + beacon_report.frequency = beacon_struct->chan_freq; beacon_report.ssid.length = beacon_struct->ssId.length; qdf_mem_copy(&beacon_report.ssid.ssid, @@ -1329,7 +1312,7 @@ QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx, struct obss_detection_cfg *cfg) { uint32_t phy_mode; - enum band_info rf_band = BAND_UNKNOWN; + enum reg_wifi_band rf_band = REG_BAND_UNKNOWN; struct obss_detection_cfg *cur_detect; if (!mac_ctx || !session || !cfg) { @@ -1365,7 +1348,7 @@ QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx, cur_detect->obss_ht_mixed_detect_mode, cur_detect->obss_ht_20mhz_detect_mode); - if (rf_band == BAND_2G) { + if (rf_band == REG_BAND_2G) { if ((phy_mode == WNI_CFG_PHY_MODE_11G || session->htCapability) && !session->gLim11bParams.protectionEnabled) { @@ -1427,7 +1410,7 @@ QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx, OBSS_OFFLOAD_DETECTION_DISABLED; } - if ((rf_band == BAND_5G) && session->htCapability) { + if ((rf_band == REG_BAND_5G) && session->htCapability) { if (!session->gLim11aParams.protectionEnabled) { if (!session->gLimOverlap11aParams.protectionEnabled) cfg->obss_11a_detect_mode = @@ -1441,7 +1424,7 @@ QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx, } } - if (((rf_band == BAND_2G) || (rf_band == BAND_5G)) && + if (((rf_band == REG_BAND_2G) || (rf_band == REG_BAND_5G)) && session->htCapability) { if (!session->gLimHt20Params.protectionEnabled) { @@ -1560,16 +1543,15 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, bool enable; struct pe_session *session; tUpdateBeaconParams bcn_prm; - enum band_info rf_band = BAND_UNKNOWN; + enum reg_wifi_band rf_band = REG_BAND_UNKNOWN; struct obss_detection_cfg *cur_detect; - pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " QDF_MAC_ADDR_STR, + pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " QDF_MAC_ADDR_FMT, obss_detection->vdev_id, obss_detection->reason, obss_detection->matched_detection_masks, - QDF_MAC_ADDR_ARRAY(obss_detection->matched_bssid_addr)); + QDF_MAC_ADDR_REF(obss_detection->matched_bssid_addr)); - session = pe_find_session_by_sme_session_id(mac_ctx, - obss_detection->vdev_id); + session = pe_find_session_by_vdev_id(mac_ctx, obss_detection->vdev_id); if (!session) { pe_err("Failed to get session for id %d", obss_detection->vdev_id); @@ -1627,7 +1609,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, if (OBSS_DETECTION_IS_11B_AP(detect_masks)) { if (reason != obss_cfg->obss_11b_ap_detect_mode || - rf_band != BAND_2G) + rf_band != REG_BAND_2G) goto wrong_detection; lim_enable11g_protection(mac_ctx, enable, true, @@ -1636,7 +1618,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, } if (OBSS_DETECTION_IS_11B_STA(detect_masks)) { if (reason != obss_cfg->obss_11b_sta_detect_mode || - rf_band != BAND_2G) + rf_band != REG_BAND_2G) goto wrong_detection; lim_enable11g_protection(mac_ctx, enable, true, @@ -1645,7 +1627,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, } if (OBSS_DETECTION_IS_11G_AP(detect_masks)) { if (reason != obss_cfg->obss_11g_ap_detect_mode || - rf_band != BAND_2G) + rf_band != REG_BAND_2G) goto wrong_detection; lim_enable_ht_protection_from11g(mac_ctx, enable, true, @@ -1654,7 +1636,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, } if (OBSS_DETECTION_IS_11A(detect_masks)) { if (reason != obss_cfg->obss_11a_detect_mode || - rf_band != BAND_5G) + rf_band != REG_BAND_5G) goto wrong_detection; lim_update_11a_protection(mac_ctx, enable, true, @@ -1664,7 +1646,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks)) { /* for 5GHz, we have only 11a detection, which covers legacy */ if (reason != obss_cfg->obss_ht_legacy_detect_mode || - rf_band != BAND_2G) + rf_band != REG_BAND_2G) goto wrong_detection; lim_enable_ht_protection_from11g(mac_ctx, enable, true, @@ -1674,7 +1656,7 @@ QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx, if (OBSS_DETECTION_IS_HT_MIXED(detect_masks)) { /* for 5GHz, we have only 11a detection, which covers ht mix */ if (reason != obss_cfg->obss_ht_mixed_detect_mode || - rf_band != BAND_2G) + rf_band != REG_BAND_2G) goto wrong_detection; lim_enable_ht_protection_from11g(mac_ctx, enable, true, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_message.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_message.c index 3a9b5711994b09b66e49e0b424c22746c66cc532..5582cd546f4946366e64b5c7c33213ff9f4d3539 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_message.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/sch/sch_message.c @@ -212,11 +212,11 @@ broadcast_wmm_of_concurrent_sta_session(struct mac_context *mac_ctx, */ if (!((mac_ctx->lim.gpSession[i].valid == true) && (mac_ctx->lim.gpSession[i].peSessionId != - session->peSessionId) - && (mac_ctx->lim.gpSession[i].currentOperChannel == - session->currentOperChannel) - && (mac_ctx->lim.gpSession[i].limSystemRole - == eLIM_STA_ROLE))) + session->peSessionId) && + (mac_ctx->lim.gpSession[i].curr_op_freq == + session->curr_op_freq) && + (mac_ctx->lim.gpSession[i].limSystemRole == + eLIM_STA_ROLE))) continue; concurrent_session = &(mac_ctx->lim.gpSession[i]); @@ -360,7 +360,7 @@ void sch_qos_update_local(struct mac_context *mac, struct pe_session *pe_session /* For AP, the bssID is stored in LIM Global context. */ lim_send_edca_params(mac, pe_session->gLimEdcaParams, - pe_session->bss_idx, false); + pe_session->vdev_id, false); } /** diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c index 92e53a0e2727b9b1ffaca30dedb087e03fe5701e..2e9f8490c6eaf2a5aac44a29fafde4aca499b21e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -71,6 +71,11 @@ static void umac_stop_complete_cb(void *user_data) } #endif +static inline QDF_STATUS umac_stop_flush_cb(struct scheduler_msg *msg) +{ + return QDF_STATUS_SUCCESS; +} + /** * umac_stop() - To post stop message to system module * @@ -95,6 +100,7 @@ QDF_STATUS umac_stop(void) /* Save the user callback and user data */ umac_stop_msg.callback = umac_stop_complete_cb; umac_stop_msg.bodyptr = (void *)&g_stop_evt; + umac_stop_msg.flush_callback = umac_stop_flush_cb; /* post the message.. */ qdf_status = scheduler_post_message(QDF_MODULE_ID_SYS, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/mac_init_api.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/mac_init_api.c index a55201dbbc50165bcf3bc554dd87ef6f12ee124e..7437189b1be6e12bc1741e35835b0a8bbeb1870f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/mac_init_api.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/mac_init_api.c @@ -34,6 +34,7 @@ #include "sys_entry_func.h" #include "mac_init_api.h" #include "wlan_mlme_main.h" +#include "wlan_psoc_mlme_api.h" #ifdef TRACE_RECORD #include "mac_trace.h" @@ -101,7 +102,7 @@ QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle, { struct mac_context *mac; QDF_STATUS status; - struct wlan_mlme_psoc_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_ext_obj; QDF_BUG(mac_handle); if (!mac_handle) @@ -125,13 +126,13 @@ QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle, } mac->psoc = psoc; - mlme_obj = mlme_get_psoc_obj(psoc); - if (!mlme_obj) { + mlme_ext_obj = wlan_psoc_mlme_get_ext_hdl(psoc); + if (!mlme_ext_obj) { pe_err("Failed to get MLME Obj"); status = QDF_STATUS_E_FAILURE; goto release_psoc_ref; } - mac->mlme_cfg = &mlme_obj->cfg; + mac->mlme_cfg = &mlme_ext_obj->cfg; *mac_handle = MAC_HANDLE(mac); @@ -185,3 +186,13 @@ QDF_STATUS mac_close(mac_handle_t mac_handle) return QDF_STATUS_SUCCESS; } + +void mac_register_sesssion_open_close_cb(mac_handle_t mac_handle, + csr_session_close_cb close_session, + csr_roam_complete_cb callback) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + mac->session_close_cb = close_session; + mac->session_roam_complete_cb = callback; +} diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c index acff9e12003c6c349f6aa8386b9a03981de534b7..c1457410fa7c8ec7df2e090b2547961d0f10a4c8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c @@ -116,24 +116,24 @@ QDF_STATUS sys_bbt_process_message_core(struct mac_context *mac_ctx, mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr); if (subtype == SIR_MAC_MGMT_ASSOC_REQ) { - pe_debug("ASSOC REQ frame allowed: da: " QDF_MAC_ADDR_STR ", sa: " QDF_MAC_ADDR_STR ", bssid: " QDF_MAC_ADDR_STR ", Assoc Req count so far: %d", - QDF_MAC_ADDR_ARRAY(mac_hdr->da), - QDF_MAC_ADDR_ARRAY(mac_hdr->sa), - QDF_MAC_ADDR_ARRAY(mac_hdr->bssId), + pe_debug("ASSOC REQ frame allowed: da: " QDF_MAC_ADDR_FMT ", sa: " QDF_MAC_ADDR_FMT ", bssid: " QDF_MAC_ADDR_FMT ", Assoc Req count so far: %d", + QDF_MAC_ADDR_REF(mac_hdr->da), + QDF_MAC_ADDR_REF(mac_hdr->sa), + QDF_MAC_ADDR_REF(mac_hdr->bssId), mac_ctx->sys.gSysFrameCount[type][subtype]); } if (subtype == SIR_MAC_MGMT_DEAUTH) { - pe_debug("DEAUTH frame allowed: da: " QDF_MAC_ADDR_STR ", sa: " QDF_MAC_ADDR_STR ", bssid: " QDF_MAC_ADDR_STR ", DEAUTH count so far: %d", - QDF_MAC_ADDR_ARRAY(mac_hdr->da), - QDF_MAC_ADDR_ARRAY(mac_hdr->sa), - QDF_MAC_ADDR_ARRAY(mac_hdr->bssId), + pe_debug("DEAUTH frame allowed: da: " QDF_MAC_ADDR_FMT ", sa: " QDF_MAC_ADDR_FMT ", bssid: " QDF_MAC_ADDR_FMT ", DEAUTH count so far: %d", + QDF_MAC_ADDR_REF(mac_hdr->da), + QDF_MAC_ADDR_REF(mac_hdr->sa), + QDF_MAC_ADDR_REF(mac_hdr->bssId), mac_ctx->sys.gSysFrameCount[type][subtype]); } if (subtype == SIR_MAC_MGMT_DISASSOC) { - pe_debug("DISASSOC frame allowed: da: " QDF_MAC_ADDR_STR ", sa: " QDF_MAC_ADDR_STR ", bssid: " QDF_MAC_ADDR_STR ", DISASSOC count so far: %d", - QDF_MAC_ADDR_ARRAY(mac_hdr->da), - QDF_MAC_ADDR_ARRAY(mac_hdr->sa), - QDF_MAC_ADDR_ARRAY(mac_hdr->bssId), + pe_debug("DISASSOC frame allowed: da: " QDF_MAC_ADDR_FMT ", sa: " QDF_MAC_ADDR_FMT ", bssid: " QDF_MAC_ADDR_FMT ", DISASSOC count so far: %d", + QDF_MAC_ADDR_REF(mac_hdr->da), + QDF_MAC_ADDR_REF(mac_hdr->sa), + QDF_MAC_ADDR_REF(mac_hdr->bssId), mac_ctx->sys.gSysFrameCount[type][subtype]); } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/dot11f.c index 955e02e9ad5c2afdd720379980d944e795061816..04141282c10bc149454dba51388d3715dda102dc 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -133,7 +133,7 @@ typedef struct sIEDefn { #define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \ do { \ if (!pSrc || IsBadReadPtr(pSrc, 4))\ - eturn DOT11F_BAD_INPUT_BUFFER; \ + return DOT11F_BAD_INPUT_BUFFER; \ if (!pBuf || IsBadWritePtr(pBuf, nBuf))\ return DOT11F_BAD_OUTPUT_BUFFER; \ if (!nBuf)\ @@ -2823,7 +2823,7 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, pDst->vhtLinkAdaptCap = tmp22__ >> 26 & 0x3; pDst->rxAntPattern = tmp22__ >> 28 & 0x1; pDst->txAntPattern = tmp22__ >> 29 & 0x1; - pDst->reserved1 = tmp22__ >> 30 & 0x3; + pDst->extended_nss_bw_supp = tmp22__ >> 30 & 0x3; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -2841,7 +2841,7 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, pBuf += 2; ielen -= 2; pDst->rxHighSupDataRate = tmp23__ >> 0 & 0x1fff; - pDst->reserved2 = tmp23__ >> 13 & 0x7; + pDst->max_nsts_total = tmp23__ >> 13 & 0x7; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -2857,7 +2857,8 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, framesntohs(pCtx, &tmp24__, pBuf, 0); pDst->txSupDataRate = tmp24__ >> 0 & 0x1fff; - pDst->reserved3 = tmp24__ >> 13 & 0x7; + pDst->vht_extended_nss_bw_cap = tmp24__ >> 13 & 0x1; + pDst->reserved = tmp24__ >> 14 & 0x3; (void)pCtx; return status; } /* End dot11f_unpack_ie_vht_caps. */ @@ -2889,7 +2890,7 @@ uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - pDst->chanCenterFreqSeg1 = *pBuf; + pDst->chan_center_freq_seg0 = *pBuf; pBuf += 1; ielen -= (uint8_t)1; if (unlikely(ielen < 1)) { @@ -2897,7 +2898,7 @@ uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - pDst->chanCenterFreqSeg2 = *pBuf; + pDst->chan_center_freq_seg1 = *pBuf; pBuf += 1; ielen -= (uint8_t)1; if (unlikely(ielen < 2)) { @@ -3800,6 +3801,54 @@ uint32_t dot11f_unpack_ie_aid(tpAniSirGlobal pCtx, #define SigIeAID (0x0029) +uint32_t dot11f_unpack_ie_BeaconReportStatus(tpAniSirGlobal pCtx, + uint8_t *pBuf, + uint8_t ielen, + tDot11fIEBeaconReportStatus *pDst, + bool append_ie) +{ + uint32_t status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) + return DOT11F_DUPLICATE_IE; + pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->sub_type = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->version = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->length = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->reason_code = *pBuf; + (void)pCtx; + return status; +} /* End dot11f_unpack_ie_BeaconReportStatus. */ + +#define SigIeBeaconReportStatus (0x002a) + + uint32_t dot11f_unpack_ie_cf_params(tpAniSirGlobal pCtx, uint8_t *pBuf, uint8_t ielen, @@ -3845,7 +3894,7 @@ uint32_t dot11f_unpack_ie_cf_params(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_cf_params. */ -#define SigIeCFParams (0x002a) +#define SigIeCFParams (0x002b) uint32_t dot11f_unpack_ie_challenge_text(tpAniSirGlobal pCtx, @@ -3870,7 +3919,7 @@ uint32_t dot11f_unpack_ie_challenge_text(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_challenge_text. */ -#define SigIeChallengeText (0x002b) +#define SigIeChallengeText (0x002c) uint32_t dot11f_unpack_ie_chan_switch_ann(tpAniSirGlobal pCtx, @@ -3910,7 +3959,7 @@ uint32_t dot11f_unpack_ie_chan_switch_ann(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_chan_switch_ann. */ -#define SigIeChanSwitchAnn (0x002c) +#define SigIeChanSwitchAnn (0x002d) static const tFFDefn FFS_ChannelSwitchWrapper[] = { @@ -3952,7 +4001,7 @@ uint32_t dot11f_unpack_ie_channel_switch_wrapper(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_channel_switch_wrapper. */ -#define SigIeChannelSwitchWrapper (0x002d) +#define SigIeChannelSwitchWrapper (0x002e) uint32_t dot11f_unpack_ie_country(tpAniSirGlobal pCtx, @@ -3990,10 +4039,10 @@ uint32_t dot11f_unpack_ie_country(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_country. */ -#define SigIeCountry (0x002e) +#define SigIeCountry (0x002f) -#define SigIeDSParams (0x002f) +#define SigIeDSParams (0x0030) uint32_t dot11f_unpack_ie_edca_param_set(tpAniSirGlobal pCtx, @@ -4153,7 +4202,7 @@ uint32_t dot11f_unpack_ie_edca_param_set(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_edca_param_set. */ -#define SigIeEDCAParamSet (0x0030) +#define SigIeEDCAParamSet (0x0031) uint32_t dot11f_unpack_ie_erp_info(tpAniSirGlobal pCtx, @@ -4182,7 +4231,7 @@ uint32_t dot11f_unpack_ie_erp_info(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_erp_info. */ -#define SigIeERPInfo (0x0031) +#define SigIeERPInfo (0x0032) uint32_t dot11f_unpack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx, @@ -4207,7 +4256,7 @@ uint32_t dot11f_unpack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_cckm_opaque. */ -#define SigIeESECckmOpaque (0x0032) +#define SigIeESECckmOpaque (0x0033) uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx, @@ -4242,7 +4291,7 @@ uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_rad_mgmt_cap. */ -#define SigIeESERadMgmtCap (0x0033) +#define SigIeESERadMgmtCap (0x0034) uint32_t dot11f_unpack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx, @@ -4282,7 +4331,7 @@ uint32_t dot11f_unpack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_traf_strm_met. */ -#define SigIeESETrafStrmMet (0x0034) +#define SigIeESETrafStrmMet (0x0035) uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx, @@ -4315,7 +4364,7 @@ uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_traf_strm_rate_set. */ -#define SigIeESETrafStrmRateSet (0x0035) +#define SigIeESETrafStrmRateSet (0x0036) uint32_t dot11f_unpack_ie_ese_txmit_power(tpAniSirGlobal pCtx, @@ -4347,7 +4396,7 @@ uint32_t dot11f_unpack_ie_ese_txmit_power(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_txmit_power. */ -#define SigIeESETxmitPower (0x0036) +#define SigIeESETxmitPower (0x0037) uint32_t dot11f_unpack_ie_ese_version(tpAniSirGlobal pCtx, @@ -4371,7 +4420,7 @@ uint32_t dot11f_unpack_ie_ese_version(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ese_version. */ -#define SigIeESEVersion (0x0037) +#define SigIeESEVersion (0x0038) uint32_t dot11f_unpack_ie_ext_cap(tpAniSirGlobal pCtx, @@ -4401,7 +4450,7 @@ uint32_t dot11f_unpack_ie_ext_cap(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ext_cap. */ -#define SigIeExtCap (0x0038) +#define SigIeExtCap (0x0039) uint32_t dot11f_unpack_ie_ext_supp_rates(tpAniSirGlobal pCtx, @@ -4434,7 +4483,7 @@ uint32_t dot11f_unpack_ie_ext_supp_rates(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ext_supp_rates. */ -#define SigIeExtSuppRates (0x0039) +#define SigIeExtSuppRates (0x003a) uint32_t dot11f_unpack_ie_fh_param_set(tpAniSirGlobal pCtx, @@ -4482,7 +4531,7 @@ uint32_t dot11f_unpack_ie_fh_param_set(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fh_param_set. */ -#define SigIeFHParamSet (0x003a) +#define SigIeFHParamSet (0x003b) uint32_t dot11f_unpack_ie_fh_params(tpAniSirGlobal pCtx, @@ -4514,7 +4563,7 @@ uint32_t dot11f_unpack_ie_fh_params(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fh_params. */ -#define SigIeFHParams (0x003b) +#define SigIeFHParams (0x003c) uint32_t dot11f_unpack_ie_fh_patt_table(tpAniSirGlobal pCtx, @@ -4571,7 +4620,7 @@ uint32_t dot11f_unpack_ie_fh_patt_table(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fh_patt_table. */ -#define SigIeFHPattTable (0x003c) +#define SigIeFHPattTable (0x003d) static const tFFDefn FFS_FTInfo[] = { @@ -4651,7 +4700,7 @@ uint32_t dot11f_unpack_ie_ft_info(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ft_info. */ -#define SigIeFTInfo (0x003d) +#define SigIeFTInfo (0x003e) uint32_t dot11f_unpack_ie_ht_caps(tpAniSirGlobal pCtx, @@ -4775,7 +4824,7 @@ uint32_t dot11f_unpack_ie_ht_caps(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ht_caps. */ -#define SigIeHTCaps (0x003e) +#define SigIeHTCaps (0x003f) uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx, @@ -4825,7 +4874,8 @@ uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx, pDst->nonGFDevicesPresent = tmp49__ >> 2 & 0x1; pDst->transmitBurstLimit = tmp49__ >> 3 & 0x1; pDst->obssNonHTStaPresent = tmp49__ >> 4 & 0x1; - pDst->reserved = tmp49__ >> 5 & 0x7ff; + pDst->chan_center_freq_seg2 = tmp49__ >> 5 & 0xff; + pDst->reserved = tmp49__ >> 13 & 0x7; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -4860,7 +4910,7 @@ uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ht_info. */ -#define SigIeHTInfo (0x003f) +#define SigIeHTInfo (0x0040) uint32_t dot11f_unpack_ie_ibss_params(tpAniSirGlobal pCtx, @@ -4884,7 +4934,7 @@ uint32_t dot11f_unpack_ie_ibss_params(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ibss_params. */ -#define SigIeIBSSParams (0x0040) +#define SigIeIBSSParams (0x0041) uint32_t dot11f_unpack_ie_link_identifier(tpAniSirGlobal pCtx, @@ -4924,7 +4974,7 @@ uint32_t dot11f_unpack_ie_link_identifier(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_link_identifier. */ -#define SigIeLinkIdentifier (0x0041) +#define SigIeLinkIdentifier (0x0042) static const tTLVDefn TLVS_MBO_IE[] = { @@ -4987,7 +5037,7 @@ uint32_t dot11f_unpack_ie_MBO_IE(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_MBO_IE. */ -#define SigIeMBO_IE (0x0042) +#define SigIeMBO_IE (0x0043) static const tFFDefn FFS_reportBeacon[] = { @@ -5322,7 +5372,7 @@ uint32_t dot11f_unpack_ie_measurement_report(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_measurement_report. */ -#define SigIeMeasurementReport (0x0043) +#define SigIeMeasurementReport (0x0044) static const tFFDefn FFS_measurement_requestBeacon[] = { @@ -5626,7 +5676,7 @@ uint32_t dot11f_unpack_ie_measurement_request(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_measurement_request. */ -#define SigIeMeasurementRequest (0x0044) +#define SigIeMeasurementRequest (0x0045) uint32_t dot11f_unpack_ie_mobility_domain(tpAniSirGlobal pCtx, @@ -5662,7 +5712,7 @@ uint32_t dot11f_unpack_ie_mobility_domain(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_mobility_domain. */ -#define SigIeMobilityDomain (0x0045) +#define SigIeMobilityDomain (0x0046) static const tFFDefn FFS_NeighborReport[] = { @@ -5784,7 +5834,7 @@ uint32_t dot11f_unpack_ie_neighbor_report(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_neighbor_report. */ -#define SigIeNeighborReport (0x0046) +#define SigIeNeighborReport (0x0047) uint32_t dot11f_unpack_ie_obss_scan_parameters(tpAniSirGlobal pCtx, @@ -5856,7 +5906,7 @@ uint32_t dot11f_unpack_ie_obss_scan_parameters(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_obss_scan_parameters. */ -#define SigIeOBSSScanParameters (0x0047) +#define SigIeOBSSScanParameters (0x0048) uint32_t dot11f_unpack_ie_operating_mode(tpAniSirGlobal pCtx, @@ -5878,14 +5928,15 @@ uint32_t dot11f_unpack_ie_operating_mode(tpAniSirGlobal pCtx, tmp58__ = *pBuf; pDst->chanWidth = tmp58__ >> 0 & 0x3; - pDst->reserved = tmp58__ >> 2 & 0x3; + pDst->vht_160_80p80_supp = tmp58__ >> 2 & 0x1; + pDst->no_ldpc = tmp58__ >> 3 & 0x1; pDst->rxNSS = tmp58__ >> 4 & 0x7; pDst->rxNSSType = tmp58__ >> 7 & 0x1; (void)pCtx; return status; } /* End dot11f_unpack_ie_operating_mode. */ -#define SigIeOperatingMode (0x0048) +#define SigIeOperatingMode (0x0049) static const tTLVDefn TLVS_P2PAssocReq[] = { @@ -5917,7 +5968,7 @@ uint32_t dot11f_unpack_ie_p2_p_assoc_req(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_assoc_req. */ -#define SigIeP2PAssocReq (0x0049) +#define SigIeP2PAssocReq (0x004a) static const tTLVDefn TLVS_P2PAssocRes[] = { @@ -5946,7 +5997,7 @@ uint32_t dot11f_unpack_ie_p2_p_assoc_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_assoc_res. */ -#define SigIeP2PAssocRes (0x004a) +#define SigIeP2PAssocRes (0x004b) static const tTLVDefn TLVS_P2PBeacon[] = { @@ -5978,7 +6029,7 @@ uint32_t dot11f_unpack_ie_p2_p_beacon(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_beacon. */ -#define SigIeP2PBeacon (0x004b) +#define SigIeP2PBeacon (0x004c) static const tTLVDefn TLVS_P2PBeaconProbeRes[] = { @@ -6020,7 +6071,7 @@ uint32_t dot11f_unpack_ie_p2_p_beacon_probe_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_beacon_probe_res. */ -#define SigIeP2PBeaconProbeRes (0x004c) +#define SigIeP2PBeaconProbeRes (0x004d) static const tTLVDefn TLVS_P2PDeAuth[] = { @@ -6046,7 +6097,7 @@ uint32_t dot11f_unpack_ie_p2_p_de_auth(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_de_auth. */ -#define SigIeP2PDeAuth (0x004d) +#define SigIeP2PDeAuth (0x004e) static const tTLVDefn TLVS_P2PDisAssoc[] = { @@ -6072,7 +6123,7 @@ uint32_t dot11f_unpack_ie_p2_p_dis_assoc(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_dis_assoc. */ -#define SigIeP2PDisAssoc (0x004e) +#define SigIeP2PDisAssoc (0x004f) uint32_t dot11f_unpack_ie_p2_pie_opaque(tpAniSirGlobal pCtx, @@ -6097,7 +6148,7 @@ uint32_t dot11f_unpack_ie_p2_pie_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_pie_opaque. */ -#define SigIeP2PIEOpaque (0x004f) +#define SigIeP2PIEOpaque (0x0050) static const tTLVDefn TLVS_P2PProbeReq[] = { @@ -6136,7 +6187,7 @@ uint32_t dot11f_unpack_ie_p2_p_probe_req(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_probe_req. */ -#define SigIeP2PProbeReq (0x0050) +#define SigIeP2PProbeReq (0x0051) static const tTLVDefn TLVS_P2PProbeRes[] = { @@ -6175,7 +6226,7 @@ uint32_t dot11f_unpack_ie_p2_p_probe_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_p2_p_probe_res. */ -#define SigIeP2PProbeRes (0x0051) +#define SigIeP2PProbeRes (0x0052) uint32_t dot11f_unpack_ie_pti_control(tpAniSirGlobal pCtx, @@ -6207,7 +6258,7 @@ uint32_t dot11f_unpack_ie_pti_control(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_pti_control. */ -#define SigIePTIControl (0x0052) +#define SigIePTIControl (0x0053) uint32_t dot11f_unpack_ie_pu_buffer_status(tpAniSirGlobal pCtx, @@ -6237,7 +6288,7 @@ uint32_t dot11f_unpack_ie_pu_buffer_status(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_pu_buffer_status. */ -#define SigIePUBufferStatus (0x0053) +#define SigIePUBufferStatus (0x0054) uint32_t dot11f_unpack_ie_power_caps(tpAniSirGlobal pCtx, @@ -6269,7 +6320,7 @@ uint32_t dot11f_unpack_ie_power_caps(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_power_caps. */ -#define SigIePowerCaps (0x0054) +#define SigIePowerCaps (0x0055) uint32_t dot11f_unpack_ie_power_constraints(tpAniSirGlobal pCtx, @@ -6293,7 +6344,7 @@ uint32_t dot11f_unpack_ie_power_constraints(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_power_constraints. */ -#define SigIePowerConstraints (0x0055) +#define SigIePowerConstraints (0x0056) uint32_t dot11f_unpack_ie_qbss_load(tpAniSirGlobal pCtx, @@ -6333,7 +6384,7 @@ uint32_t dot11f_unpack_ie_qbss_load(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qbss_load. */ -#define SigIeQBSSLoad (0x0056) +#define SigIeQBSSLoad (0x0057) uint32_t dot11f_unpack_ie_QComVendorIE(tpAniSirGlobal pCtx, @@ -6365,7 +6416,7 @@ uint32_t dot11f_unpack_ie_QComVendorIE(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_QComVendorIE. */ -#define SigIeQComVendorIE (0x0057) +#define SigIeQComVendorIE (0x0058) uint32_t dot11f_unpack_ie_qos_caps_ap(tpAniSirGlobal pCtx, @@ -6395,7 +6446,7 @@ uint32_t dot11f_unpack_ie_qos_caps_ap(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qos_caps_ap. */ -#define SigIeQOSCapsAp (0x0058) +#define SigIeQOSCapsAp (0x0059) uint32_t dot11f_unpack_ie_qos_caps_station(tpAniSirGlobal pCtx, @@ -6427,7 +6478,7 @@ uint32_t dot11f_unpack_ie_qos_caps_station(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qos_caps_station. */ -#define SigIeQOSCapsStation (0x0059) +#define SigIeQOSCapsStation (0x005a) uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx, @@ -6442,7 +6493,7 @@ uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx, return DOT11F_DUPLICATE_IE; pDst->present = 1; pDst->num_dscp_exceptions = (uint8_t)(ielen); - if (ielen > 60) { + if (ielen > 58) { pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; } @@ -6452,7 +6503,7 @@ uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qos_map_set. */ -#define SigIeQosMapSet (0x005a) +#define SigIeQosMapSet (0x005b) uint32_t dot11f_unpack_ie_quiet(tpAniSirGlobal pCtx, @@ -6500,7 +6551,7 @@ uint32_t dot11f_unpack_ie_quiet(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_quiet. */ -#define SigIeQuiet (0x005b) +#define SigIeQuiet (0x005c) uint32_t dot11f_unpack_ie_rcpiie(tpAniSirGlobal pCtx, @@ -6524,7 +6575,7 @@ uint32_t dot11f_unpack_ie_rcpiie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_rcpiie. */ -#define SigIeRCPIIE (0x005c) +#define SigIeRCPIIE (0x005d) static const tFFDefn FFS_RICDataDesc[] = { @@ -6600,7 +6651,7 @@ uint32_t dot11f_unpack_ie_ric_data_desc(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ric_data_desc. */ -#define SigIeRICDataDesc (0x005d) +#define SigIeRICDataDesc (0x005e) uint32_t dot11f_unpack_ie_rsn(tpAniSirGlobal pCtx, @@ -6734,7 +6785,6 @@ uint32_t dot11f_unpack_ie_rsn(tpAniSirGlobal pCtx, ielen -= (uint8_t)2; } if (!ielen) { - pDst->RSN_Cap_present = 0U; pDst->gp_mgmt_cipher_suite_present = 0U; pDst->pmkid_count = 0U; return 0U; @@ -6776,7 +6826,7 @@ uint32_t dot11f_unpack_ie_rsn(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_rsn. */ -#define SigIeRSN (0x005e) +#define SigIeRSN (0x005f) uint32_t dot11f_unpack_ie_rsniie(tpAniSirGlobal pCtx, @@ -6800,7 +6850,7 @@ uint32_t dot11f_unpack_ie_rsniie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_rsniie. */ -#define SigIeRSNIIE (0x005f) +#define SigIeRSNIIE (0x0060) uint32_t dot11f_unpack_ie_rsn_opaque(tpAniSirGlobal pCtx, @@ -6825,7 +6875,7 @@ uint32_t dot11f_unpack_ie_rsn_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_rsn_opaque. */ -#define SigIeRSNOpaque (0x0060) +#define SigIeRSNOpaque (0x0061) uint32_t dot11f_unpack_ie_supp_channels(tpAniSirGlobal pCtx, @@ -6850,7 +6900,7 @@ uint32_t dot11f_unpack_ie_supp_channels(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_supp_channels. */ -#define SigIeSuppChannels (0x0061) +#define SigIeSuppChannels (0x0062) uint32_t dot11f_unpack_ie_supp_operating_classes(tpAniSirGlobal pCtx, @@ -6875,7 +6925,7 @@ uint32_t dot11f_unpack_ie_supp_operating_classes(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_supp_operating_classes. */ -#define SigIeSuppOperatingClasses (0x0062) +#define SigIeSuppOperatingClasses (0x0063) uint32_t dot11f_unpack_ie_supp_rates(tpAniSirGlobal pCtx, @@ -6908,7 +6958,7 @@ uint32_t dot11f_unpack_ie_supp_rates(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_supp_rates. */ -#define SigIeSuppRates (0x0063) +#define SigIeSuppRates (0x0064) uint32_t dot11f_unpack_ie_tim(tpAniSirGlobal pCtx, @@ -6957,7 +7007,7 @@ uint32_t dot11f_unpack_ie_tim(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_tim. */ -#define SigIeTIM (0x0064) +#define SigIeTIM (0x0065) uint32_t dot11f_unpack_ie_tpc_report(tpAniSirGlobal pCtx, @@ -6989,7 +7039,7 @@ uint32_t dot11f_unpack_ie_tpc_report(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_tpc_report. */ -#define SigIeTPCReport (0x0065) +#define SigIeTPCReport (0x0066) uint32_t dot11f_unpack_ie_tpc_request(tpAniSirGlobal pCtx, @@ -7007,7 +7057,7 @@ uint32_t dot11f_unpack_ie_tpc_request(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_tpc_request. */ -#define SigIeTPCRequest (0x0066) +#define SigIeTPCRequest (0x0067) uint32_t dot11f_unpack_ie_time_advertisement(tpAniSirGlobal pCtx, @@ -7047,7 +7097,7 @@ uint32_t dot11f_unpack_ie_time_advertisement(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_time_advertisement. */ -#define SigIeTimeAdvertisement (0x0067) +#define SigIeTimeAdvertisement (0x0068) uint32_t dot11f_unpack_ie_timeout_interval(tpAniSirGlobal pCtx, @@ -7079,7 +7129,7 @@ uint32_t dot11f_unpack_ie_timeout_interval(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_timeout_interval. */ -#define SigIeTimeoutInterval (0x0068) +#define SigIeTimeoutInterval (0x0069) uint32_t dot11f_unpack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx, @@ -7135,7 +7185,7 @@ uint32_t dot11f_unpack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_vht_ext_bss_load. */ -#define SigIeVHTExtBssLoad (0x0069) +#define SigIeVHTExtBssLoad (0x006a) uint32_t dot11f_unpack_ie_vendor1_ie(tpAniSirGlobal pCtx, @@ -7153,7 +7203,7 @@ uint32_t dot11f_unpack_ie_vendor1_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_vendor1_ie. */ -#define SigIeVendor1IE (0x006a) +#define SigIeVendor1IE (0x006b) uint32_t dot11f_unpack_ie_vendor3_ie(tpAniSirGlobal pCtx, @@ -7171,7 +7221,7 @@ uint32_t dot11f_unpack_ie_vendor3_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_vendor3_ie. */ -#define SigIeVendor3IE (0x006b) +#define SigIeVendor3IE (0x006c) uint32_t dot11f_unpack_ie_wapi(tpAniSirGlobal pCtx, @@ -7286,7 +7336,7 @@ uint32_t dot11f_unpack_ie_wapi(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wapi. */ -#define SigIeWAPI (0x006c) +#define SigIeWAPI (0x006d) uint32_t dot11f_unpack_ie_wapi_opaque(tpAniSirGlobal pCtx, @@ -7311,7 +7361,7 @@ uint32_t dot11f_unpack_ie_wapi_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wapi_opaque. */ -#define SigIeWAPIOpaque (0x006d) +#define SigIeWAPIOpaque (0x006e) uint32_t dot11f_unpack_ie_wfatpc(tpAniSirGlobal pCtx, @@ -7343,7 +7393,7 @@ uint32_t dot11f_unpack_ie_wfatpc(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wfatpc. */ -#define SigIeWFATPC (0x006e) +#define SigIeWFATPC (0x006f) uint32_t dot11f_unpack_ie_wfdie_opaque(tpAniSirGlobal pCtx, @@ -7368,7 +7418,7 @@ uint32_t dot11f_unpack_ie_wfdie_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wfdie_opaque. */ -#define SigIeWFDIEOpaque (0x006f) +#define SigIeWFDIEOpaque (0x0070) uint32_t dot11f_unpack_ie_wmm_caps(tpAniSirGlobal pCtx, @@ -7410,7 +7460,7 @@ uint32_t dot11f_unpack_ie_wmm_caps(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wmm_caps. */ -#define SigIeWMMCaps (0x0070) +#define SigIeWMMCaps (0x0071) uint32_t dot11f_unpack_ie_wmm_info_ap(tpAniSirGlobal pCtx, @@ -7446,7 +7496,7 @@ uint32_t dot11f_unpack_ie_wmm_info_ap(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wmm_info_ap. */ -#define SigIeWMMInfoAp (0x0071) +#define SigIeWMMInfoAp (0x0072) uint32_t dot11f_unpack_ie_wmm_info_station(tpAniSirGlobal pCtx, @@ -7486,7 +7536,7 @@ uint32_t dot11f_unpack_ie_wmm_info_station(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wmm_info_station. */ -#define SigIeWMMInfoStation (0x0072) +#define SigIeWMMInfoStation (0x0073) uint32_t dot11f_unpack_ie_wmm_params(tpAniSirGlobal pCtx, @@ -7658,7 +7708,7 @@ uint32_t dot11f_unpack_ie_wmm_params(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wmm_params. */ -#define SigIeWMMParams (0x0073) +#define SigIeWMMParams (0x0074) uint32_t dot11f_unpack_ie_wpa(tpAniSirGlobal pCtx, @@ -7767,7 +7817,7 @@ uint32_t dot11f_unpack_ie_wpa(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wpa. */ -#define SigIeWPA (0x0074) +#define SigIeWPA (0x0075) uint32_t dot11f_unpack_ie_wpa_opaque(tpAniSirGlobal pCtx, @@ -7792,7 +7842,7 @@ uint32_t dot11f_unpack_ie_wpa_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wpa_opaque. */ -#define SigIeWPAOpaque (0x0075) +#define SigIeWPAOpaque (0x0076) static const tTLVDefn TLVS_WSC[] = { @@ -7883,7 +7933,7 @@ uint32_t dot11f_unpack_ie_wsc(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc. */ -#define SigIeWSC (0x0076) +#define SigIeWSC (0x0077) static const tTLVDefn TLVS_WscAssocReq[] = { @@ -7915,7 +7965,7 @@ uint32_t dot11f_unpack_ie_wsc_assoc_req(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_assoc_req. */ -#define SigIeWscAssocReq (0x0077) +#define SigIeWscAssocReq (0x0078) static const tTLVDefn TLVS_WscAssocRes[] = { @@ -7947,7 +7997,7 @@ uint32_t dot11f_unpack_ie_wsc_assoc_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_assoc_res. */ -#define SigIeWscAssocRes (0x0078) +#define SigIeWscAssocRes (0x0079) static const tTLVDefn TLVS_WscBeacon[] = { @@ -8000,7 +8050,7 @@ uint32_t dot11f_unpack_ie_wsc_beacon(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_beacon. */ -#define SigIeWscBeacon (0x0079) +#define SigIeWscBeacon (0x007a) static const tTLVDefn TLVS_WscBeaconProbeRes[] = { @@ -8078,7 +8128,7 @@ uint32_t dot11f_unpack_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_beacon_probe_res. */ -#define SigIeWscBeaconProbeRes (0x007a) +#define SigIeWscBeaconProbeRes (0x007b) uint32_t dot11f_unpack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx, @@ -8103,7 +8153,7 @@ uint32_t dot11f_unpack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_ie_opaque. */ -#define SigIeWscIEOpaque (0x007b) +#define SigIeWscIEOpaque (0x007c) static const tTLVDefn TLVS_WscProbeReq[] = { @@ -8176,7 +8226,7 @@ uint32_t dot11f_unpack_ie_wsc_probe_req(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_probe_req. */ -#define SigIeWscProbeReq (0x007c) +#define SigIeWscProbeReq (0x007d) static const tTLVDefn TLVS_WscProbeRes[] = { @@ -8254,7 +8304,7 @@ uint32_t dot11f_unpack_ie_wsc_probe_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_probe_res. */ -#define SigIeWscProbeRes (0x007d) +#define SigIeWscProbeRes (0x007e) static const tTLVDefn TLVS_WscReassocRes[] = { @@ -8286,7 +8336,7 @@ uint32_t dot11f_unpack_ie_wsc_reassoc_res(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_wsc_reassoc_res. */ -#define SigIeWscReassocRes (0x007e) +#define SigIeWscReassocRes (0x007f) uint32_t dot11f_unpack_ie_addba_extn_element(tpAniSirGlobal pCtx, @@ -8314,7 +8364,7 @@ uint32_t dot11f_unpack_ie_addba_extn_element(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_addba_extn_element. */ -#define SigIeaddba_extn_element (0x007f) +#define SigIeaddba_extn_element (0x0080) uint32_t dot11f_unpack_ie_bss_color_change(tpAniSirGlobal pCtx, @@ -8349,7 +8399,7 @@ uint32_t dot11f_unpack_ie_bss_color_change(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_bss_color_change. */ -#define SigIebss_color_change (0x0080) +#define SigIebss_color_change (0x0081) uint32_t dot11f_unpack_ie_dh_parameter_element(tpAniSirGlobal pCtx, @@ -8377,7 +8427,7 @@ uint32_t dot11f_unpack_ie_dh_parameter_element(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_dh_parameter_element. */ -#define SigIedh_parameter_element (0x0081) +#define SigIedh_parameter_element (0x0082) uint32_t dot11f_unpack_ie_esp_information(tpAniSirGlobal pCtx, @@ -8402,7 +8452,7 @@ uint32_t dot11f_unpack_ie_esp_information(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_esp_information. */ -#define SigIeesp_information (0x0082) +#define SigIeesp_information (0x0083) uint32_t dot11f_unpack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx, @@ -8450,7 +8500,7 @@ uint32_t dot11f_unpack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ext_chan_switch_ann. */ -#define SigIeext_chan_switch_ann (0x0083) +#define SigIeext_chan_switch_ann (0x0084) uint32_t dot11f_unpack_ie_fils_assoc_delay_info(tpAniSirGlobal pCtx, @@ -8474,7 +8524,7 @@ uint32_t dot11f_unpack_ie_fils_assoc_delay_info(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_assoc_delay_info. */ -#define SigIefils_assoc_delay_info (0x0084) +#define SigIefils_assoc_delay_info (0x0085) uint32_t dot11f_unpack_ie_fils_hlp_container(tpAniSirGlobal pCtx, @@ -8510,7 +8560,7 @@ uint32_t dot11f_unpack_ie_fils_hlp_container(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_hlp_container. */ -#define SigIefils_hlp_container (0x0085) +#define SigIefils_hlp_container (0x0086) uint32_t dot11f_unpack_ie_fils_indication(tpAniSirGlobal pCtx, @@ -8548,7 +8598,7 @@ uint32_t dot11f_unpack_ie_fils_indication(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_indication. */ -#define SigIefils_indication (0x0086) +#define SigIefils_indication (0x0087) uint32_t dot11f_unpack_ie_fils_kde(tpAniSirGlobal pCtx, @@ -8576,7 +8626,7 @@ uint32_t dot11f_unpack_ie_fils_kde(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_kde. */ -#define SigIefils_kde (0x0087) +#define SigIefils_kde (0x0088) uint32_t dot11f_unpack_ie_fils_key_confirmation(tpAniSirGlobal pCtx, @@ -8596,7 +8646,7 @@ uint32_t dot11f_unpack_ie_fils_key_confirmation(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_key_confirmation. */ -#define SigIefils_key_confirmation (0x0088) +#define SigIefils_key_confirmation (0x0089) uint32_t dot11f_unpack_ie_fils_nonce(tpAniSirGlobal pCtx, @@ -8620,7 +8670,7 @@ uint32_t dot11f_unpack_ie_fils_nonce(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_nonce. */ -#define SigIefils_nonce (0x0089) +#define SigIefils_nonce (0x008a) uint32_t dot11f_unpack_ie_fils_public_key(tpAniSirGlobal pCtx, @@ -8648,7 +8698,7 @@ uint32_t dot11f_unpack_ie_fils_public_key(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_public_key. */ -#define SigIefils_public_key (0x008a) +#define SigIefils_public_key (0x008b) uint32_t dot11f_unpack_ie_fils_session(tpAniSirGlobal pCtx, @@ -8672,7 +8722,7 @@ uint32_t dot11f_unpack_ie_fils_session(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_session. */ -#define SigIefils_session (0x008b) +#define SigIefils_session (0x008c) uint32_t dot11f_unpack_ie_fils_wrapped_data(tpAniSirGlobal pCtx, @@ -8692,7 +8742,7 @@ uint32_t dot11f_unpack_ie_fils_wrapped_data(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fils_wrapped_data. */ -#define SigIefils_wrapped_data (0x008c) +#define SigIefils_wrapped_data (0x008d) uint32_t dot11f_unpack_ie_fragment_ie(tpAniSirGlobal pCtx, @@ -8712,7 +8762,40 @@ uint32_t dot11f_unpack_ie_fragment_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_fragment_ie. */ -#define SigIefragment_ie (0x008d) +#define SigIefragment_ie (0x008e) + + +uint32_t dot11f_unpack_ie_he_6ghz_band_cap(tpAniSirGlobal pCtx, + uint8_t *pBuf, + uint8_t ielen, + tDot11fIEhe_6ghz_band_cap *pDst, + bool append_ie) +{ + uint32_t status = DOT11F_PARSE_SUCCESS; + uint16_t tmp77__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) + return DOT11F_DUPLICATE_IE; + pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + framesntohs(pCtx, &tmp77__, pBuf, 0); + pDst->min_mpdu_start_spacing = tmp77__ >> 0 & 0x7; + pDst->max_ampdu_len_exp = tmp77__ >> 3 & 0x7; + pDst->max_mpdu_len = tmp77__ >> 6 & 0x7; + pDst->sm_pow_save = tmp77__ >> 9 & 0x3; + pDst->rd_responder = tmp77__ >> 11 & 0x1; + pDst->rx_ant_pattern_consistency = tmp77__ >> 12 & 0x1; + pDst->tx_ant_pattern_consistency = tmp77__ >> 13 & 0x1; + pDst->reserved = tmp77__ >> 14 & 0x3; + (void)pCtx; + return status; +} /* End dot11f_unpack_ie_he_6ghz_band_cap. */ + +#define SigIehe_6ghz_band_cap (0x008f) uint32_t dot11f_unpack_ie_he_cap(tpAniSirGlobal pCtx, @@ -8722,11 +8805,11 @@ uint32_t dot11f_unpack_ie_he_cap(tpAniSirGlobal pCtx, bool append_ie) { uint32_t status = DOT11F_PARSE_SUCCESS; - uint32_t tmp77__; - uint16_t tmp78__; - uint32_t tmp79__; + uint32_t tmp78__; + uint16_t tmp79__; uint32_t tmp80__; - uint16_t tmp81__; + uint32_t tmp81__; + uint16_t tmp82__; (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) return DOT11F_DUPLICATE_IE; @@ -8736,134 +8819,134 @@ uint32_t dot11f_unpack_ie_he_cap(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - framesntohl(pCtx, &tmp77__, pBuf, 0); + framesntohl(pCtx, &tmp78__, pBuf, 0); pBuf += 4; ielen -= 4; - pDst->htc_he = tmp77__ >> 0 & 0x1; - pDst->twt_request = tmp77__ >> 1 & 0x1; - pDst->twt_responder = tmp77__ >> 2 & 0x1; - pDst->fragmentation = tmp77__ >> 3 & 0x3; - pDst->max_num_frag_msdu_amsdu_exp = tmp77__ >> 5 & 0x7; - pDst->min_frag_size = tmp77__ >> 8 & 0x3; - pDst->trigger_frm_mac_pad = tmp77__ >> 10 & 0x3; - pDst->multi_tid_aggr_rx_supp = tmp77__ >> 12 & 0x7; - pDst->he_link_adaptation = tmp77__ >> 15 & 0x3; - pDst->all_ack = tmp77__ >> 17 & 0x1; - pDst->trigd_rsp_sched = tmp77__ >> 18 & 0x1; - pDst->a_bsr = tmp77__ >> 19 & 0x1; - pDst->broadcast_twt = tmp77__ >> 20 & 0x1; - pDst->ba_32bit_bitmap = tmp77__ >> 21 & 0x1; - pDst->mu_cascade = tmp77__ >> 22 & 0x1; - pDst->ack_enabled_multitid = tmp77__ >> 23 & 0x1; - pDst->reserved = tmp77__ >> 24 & 0x1; - pDst->omi_a_ctrl = tmp77__ >> 25 & 0x1; - pDst->ofdma_ra = tmp77__ >> 26 & 0x1; - pDst->max_ampdu_len_exp_ext = tmp77__ >> 27 & 0x3; - pDst->amsdu_frag = tmp77__ >> 29 & 0x1; - pDst->flex_twt_sched = tmp77__ >> 30 & 0x1; - pDst->rx_ctrl_frame = tmp77__ >> 31 & 0x1; + pDst->htc_he = tmp78__ >> 0 & 0x1; + pDst->twt_request = tmp78__ >> 1 & 0x1; + pDst->twt_responder = tmp78__ >> 2 & 0x1; + pDst->fragmentation = tmp78__ >> 3 & 0x3; + pDst->max_num_frag_msdu_amsdu_exp = tmp78__ >> 5 & 0x7; + pDst->min_frag_size = tmp78__ >> 8 & 0x3; + pDst->trigger_frm_mac_pad = tmp78__ >> 10 & 0x3; + pDst->multi_tid_aggr_rx_supp = tmp78__ >> 12 & 0x7; + pDst->he_link_adaptation = tmp78__ >> 15 & 0x3; + pDst->all_ack = tmp78__ >> 17 & 0x1; + pDst->trigd_rsp_sched = tmp78__ >> 18 & 0x1; + pDst->a_bsr = tmp78__ >> 19 & 0x1; + pDst->broadcast_twt = tmp78__ >> 20 & 0x1; + pDst->ba_32bit_bitmap = tmp78__ >> 21 & 0x1; + pDst->mu_cascade = tmp78__ >> 22 & 0x1; + pDst->ack_enabled_multitid = tmp78__ >> 23 & 0x1; + pDst->reserved = tmp78__ >> 24 & 0x1; + pDst->omi_a_ctrl = tmp78__ >> 25 & 0x1; + pDst->ofdma_ra = tmp78__ >> 26 & 0x1; + pDst->max_ampdu_len_exp_ext = tmp78__ >> 27 & 0x3; + pDst->amsdu_frag = tmp78__ >> 29 & 0x1; + pDst->flex_twt_sched = tmp78__ >> 30 & 0x1; + pDst->rx_ctrl_frame = tmp78__ >> 31 & 0x1; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - framesntohs(pCtx, &tmp78__, pBuf, 0); + framesntohs(pCtx, &tmp79__, pBuf, 0); pBuf += 2; ielen -= 2; - pDst->bsrp_ampdu_aggr = tmp78__ >> 0 & 0x1; - pDst->qtp = tmp78__ >> 1 & 0x1; - pDst->a_bqr = tmp78__ >> 2 & 0x1; - pDst->spatial_reuse_param_rspder = tmp78__ >> 3 & 0x1; - pDst->ndp_feedback_supp = tmp78__ >> 4 & 0x1; - pDst->ops_supp = tmp78__ >> 5 & 0x1; - pDst->amsdu_in_ampdu = tmp78__ >> 6 & 0x1; - pDst->multi_tid_aggr_tx_supp = tmp78__ >> 7 & 0x7; - pDst->he_sub_ch_sel_tx_supp = tmp78__ >> 10 & 0x1; - pDst->ul_2x996_tone_ru_supp = tmp78__ >> 11 & 0x1; - pDst->om_ctrl_ul_mu_data_dis_rx = tmp78__ >> 12 & 0x1; - pDst->he_dynamic_smps = tmp78__ >> 13 & 0x1; - pDst->punctured_sounding_supp = tmp78__ >> 14 & 0x1; - pDst->ht_vht_trg_frm_rx_supp = tmp78__ >> 15 & 0x1; + pDst->bsrp_ampdu_aggr = tmp79__ >> 0 & 0x1; + pDst->qtp = tmp79__ >> 1 & 0x1; + pDst->a_bqr = tmp79__ >> 2 & 0x1; + pDst->spatial_reuse_param_rspder = tmp79__ >> 3 & 0x1; + pDst->ndp_feedback_supp = tmp79__ >> 4 & 0x1; + pDst->ops_supp = tmp79__ >> 5 & 0x1; + pDst->amsdu_in_ampdu = tmp79__ >> 6 & 0x1; + pDst->multi_tid_aggr_tx_supp = tmp79__ >> 7 & 0x7; + pDst->he_sub_ch_sel_tx_supp = tmp79__ >> 10 & 0x1; + pDst->ul_2x996_tone_ru_supp = tmp79__ >> 11 & 0x1; + pDst->om_ctrl_ul_mu_data_dis_rx = tmp79__ >> 12 & 0x1; + pDst->he_dynamic_smps = tmp79__ >> 13 & 0x1; + pDst->punctured_sounding_supp = tmp79__ >> 14 & 0x1; + pDst->ht_vht_trg_frm_rx_supp = tmp79__ >> 15 & 0x1; if (unlikely(ielen < 4)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - framesntohl(pCtx, &tmp79__, pBuf, 0); + framesntohl(pCtx, &tmp80__, pBuf, 0); pBuf += 4; ielen -= 4; - pDst->reserved2 = tmp79__ >> 0 & 0x1; - pDst->chan_width_0 = tmp79__ >> 1 & 0x1; - pDst->chan_width_1 = tmp79__ >> 2 & 0x1; - pDst->chan_width_2 = tmp79__ >> 3 & 0x1; - pDst->chan_width_3 = tmp79__ >> 4 & 0x1; - pDst->chan_width_4 = tmp79__ >> 5 & 0x1; - pDst->chan_width_5 = tmp79__ >> 6 & 0x1; - pDst->chan_width_6 = tmp79__ >> 7 & 0x1; - pDst->rx_pream_puncturing = tmp79__ >> 8 & 0xf; - pDst->device_class = tmp79__ >> 12 & 0x1; - pDst->ldpc_coding = tmp79__ >> 13 & 0x1; - pDst->he_1x_ltf_800_gi_ppdu = tmp79__ >> 14 & 0x1; - pDst->midamble_tx_rx_max_nsts = tmp79__ >> 15 & 0x3; - pDst->he_4x_ltf_3200_gi_ndp = tmp79__ >> 17 & 0x1; - pDst->tb_ppdu_tx_stbc_lt_80mhz = tmp79__ >> 18 & 0x1; - pDst->rx_stbc_lt_80mhz = tmp79__ >> 19 & 0x1; - pDst->doppler = tmp79__ >> 20 & 0x3; - pDst->ul_mu = tmp79__ >> 22 & 0x3; - pDst->dcm_enc_tx = tmp79__ >> 24 & 0x7; - pDst->dcm_enc_rx = tmp79__ >> 27 & 0x7; - pDst->ul_he_mu = tmp79__ >> 30 & 0x1; - pDst->su_beamformer = tmp79__ >> 31 & 0x1; + pDst->reserved2 = tmp80__ >> 0 & 0x1; + pDst->chan_width_0 = tmp80__ >> 1 & 0x1; + pDst->chan_width_1 = tmp80__ >> 2 & 0x1; + pDst->chan_width_2 = tmp80__ >> 3 & 0x1; + pDst->chan_width_3 = tmp80__ >> 4 & 0x1; + pDst->chan_width_4 = tmp80__ >> 5 & 0x1; + pDst->chan_width_5 = tmp80__ >> 6 & 0x1; + pDst->chan_width_6 = tmp80__ >> 7 & 0x1; + pDst->rx_pream_puncturing = tmp80__ >> 8 & 0xf; + pDst->device_class = tmp80__ >> 12 & 0x1; + pDst->ldpc_coding = tmp80__ >> 13 & 0x1; + pDst->he_1x_ltf_800_gi_ppdu = tmp80__ >> 14 & 0x1; + pDst->midamble_tx_rx_max_nsts = tmp80__ >> 15 & 0x3; + pDst->he_4x_ltf_3200_gi_ndp = tmp80__ >> 17 & 0x1; + pDst->tb_ppdu_tx_stbc_lt_80mhz = tmp80__ >> 18 & 0x1; + pDst->rx_stbc_lt_80mhz = tmp80__ >> 19 & 0x1; + pDst->doppler = tmp80__ >> 20 & 0x3; + pDst->ul_mu = tmp80__ >> 22 & 0x3; + pDst->dcm_enc_tx = tmp80__ >> 24 & 0x7; + pDst->dcm_enc_rx = tmp80__ >> 27 & 0x7; + pDst->ul_he_mu = tmp80__ >> 30 & 0x1; + pDst->su_beamformer = tmp80__ >> 31 & 0x1; if (unlikely(ielen < 4)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - framesntohl(pCtx, &tmp80__, pBuf, 0); + framesntohl(pCtx, &tmp81__, pBuf, 0); pBuf += 4; ielen -= 4; - pDst->su_beamformee = tmp80__ >> 0 & 0x1; - pDst->mu_beamformer = tmp80__ >> 1 & 0x1; - pDst->bfee_sts_lt_80 = tmp80__ >> 2 & 0x7; - pDst->bfee_sts_gt_80 = tmp80__ >> 5 & 0x7; - pDst->num_sounding_lt_80 = tmp80__ >> 8 & 0x7; - pDst->num_sounding_gt_80 = tmp80__ >> 11 & 0x7; - pDst->su_feedback_tone16 = tmp80__ >> 14 & 0x1; - pDst->mu_feedback_tone16 = tmp80__ >> 15 & 0x1; - pDst->codebook_su = tmp80__ >> 16 & 0x1; - pDst->codebook_mu = tmp80__ >> 17 & 0x1; - pDst->beamforming_feedback = tmp80__ >> 18 & 0x7; - pDst->he_er_su_ppdu = tmp80__ >> 21 & 0x1; - pDst->dl_mu_mimo_part_bw = tmp80__ >> 22 & 0x1; - pDst->ppet_present = tmp80__ >> 23 & 0x1; - pDst->srp = tmp80__ >> 24 & 0x1; - pDst->power_boost = tmp80__ >> 25 & 0x1; - pDst->he_ltf_800_gi_4x = tmp80__ >> 26 & 0x1; - pDst->max_nc = tmp80__ >> 27 & 0x7; - pDst->tb_ppdu_tx_stbc_gt_80mhz = tmp80__ >> 30 & 0x1; - pDst->rx_stbc_gt_80mhz = tmp80__ >> 31 & 0x1; + pDst->su_beamformee = tmp81__ >> 0 & 0x1; + pDst->mu_beamformer = tmp81__ >> 1 & 0x1; + pDst->bfee_sts_lt_80 = tmp81__ >> 2 & 0x7; + pDst->bfee_sts_gt_80 = tmp81__ >> 5 & 0x7; + pDst->num_sounding_lt_80 = tmp81__ >> 8 & 0x7; + pDst->num_sounding_gt_80 = tmp81__ >> 11 & 0x7; + pDst->su_feedback_tone16 = tmp81__ >> 14 & 0x1; + pDst->mu_feedback_tone16 = tmp81__ >> 15 & 0x1; + pDst->codebook_su = tmp81__ >> 16 & 0x1; + pDst->codebook_mu = tmp81__ >> 17 & 0x1; + pDst->beamforming_feedback = tmp81__ >> 18 & 0x7; + pDst->he_er_su_ppdu = tmp81__ >> 21 & 0x1; + pDst->dl_mu_mimo_part_bw = tmp81__ >> 22 & 0x1; + pDst->ppet_present = tmp81__ >> 23 & 0x1; + pDst->srp = tmp81__ >> 24 & 0x1; + pDst->power_boost = tmp81__ >> 25 & 0x1; + pDst->he_ltf_800_gi_4x = tmp81__ >> 26 & 0x1; + pDst->max_nc = tmp81__ >> 27 & 0x7; + pDst->tb_ppdu_tx_stbc_gt_80mhz = tmp81__ >> 30 & 0x1; + pDst->rx_stbc_gt_80mhz = tmp81__ >> 31 & 0x1; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - framesntohs(pCtx, &tmp81__, pBuf, 0); + framesntohs(pCtx, &tmp82__, pBuf, 0); pBuf += 2; ielen -= 2; - pDst->er_he_ltf_800_gi_4x = tmp81__ >> 0 & 0x1; - pDst->he_ppdu_20_in_40Mhz_2G = tmp81__ >> 1 & 0x1; - pDst->he_ppdu_20_in_160_80p80Mhz = tmp81__ >> 2 & 0x1; - pDst->he_ppdu_80_in_160_80p80Mhz = tmp81__ >> 3 & 0x1; - pDst->er_1x_he_ltf_gi = tmp81__ >> 4 & 0x1; - pDst->midamble_tx_rx_1x_he_ltf = tmp81__ >> 5 & 0x1; - pDst->dcm_max_bw = tmp81__ >> 6 & 0x3; - pDst->longer_than_16_he_sigb_ofdm_sym = tmp81__ >> 8 & 0x1; - pDst->non_trig_cqi_feedback = tmp81__ >> 9 & 0x1; - pDst->tx_1024_qam_lt_242_tone_ru = tmp81__ >> 10 & 0x1; - pDst->rx_1024_qam_lt_242_tone_ru = tmp81__ >> 11 & 0x1; - pDst->rx_full_bw_su_he_mu_compress_sigb = tmp81__ >> 12 & 0x1; - pDst->rx_full_bw_su_he_mu_non_cmpr_sigb = tmp81__ >> 13 & 0x1; - pDst->reserved3 = tmp81__ >> 14 & 0x3; + pDst->er_he_ltf_800_gi_4x = tmp82__ >> 0 & 0x1; + pDst->he_ppdu_20_in_40Mhz_2G = tmp82__ >> 1 & 0x1; + pDst->he_ppdu_20_in_160_80p80Mhz = tmp82__ >> 2 & 0x1; + pDst->he_ppdu_80_in_160_80p80Mhz = tmp82__ >> 3 & 0x1; + pDst->er_1x_he_ltf_gi = tmp82__ >> 4 & 0x1; + pDst->midamble_tx_rx_1x_he_ltf = tmp82__ >> 5 & 0x1; + pDst->dcm_max_bw = tmp82__ >> 6 & 0x3; + pDst->longer_than_16_he_sigb_ofdm_sym = tmp82__ >> 8 & 0x1; + pDst->non_trig_cqi_feedback = tmp82__ >> 9 & 0x1; + pDst->tx_1024_qam_lt_242_tone_ru = tmp82__ >> 10 & 0x1; + pDst->rx_1024_qam_lt_242_tone_ru = tmp82__ >> 11 & 0x1; + pDst->rx_full_bw_su_he_mu_compress_sigb = tmp82__ >> 12 & 0x1; + pDst->rx_full_bw_su_he_mu_non_cmpr_sigb = tmp82__ >> 13 & 0x1; + pDst->reserved3 = tmp82__ >> 14 & 0x3; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -8957,7 +9040,7 @@ uint32_t dot11f_unpack_ie_he_cap(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_he_cap. */ -#define SigIehe_cap (0x008e) +#define SigIehe_cap (0x0090) uint32_t dot11f_unpack_ie_he_op(tpAniSirGlobal pCtx, @@ -8967,9 +9050,10 @@ uint32_t dot11f_unpack_ie_he_op(tpAniSirGlobal pCtx, bool append_ie) { uint32_t status = DOT11F_PARSE_SUCCESS; - uint16_t tmp82__; - uint8_t tmp83__; + uint16_t tmp83__; uint8_t tmp84__; + uint8_t tmp85__; + uint8_t tmp86__; (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) return DOT11F_DUPLICATE_IE; @@ -8979,35 +9063,36 @@ uint32_t dot11f_unpack_ie_he_op(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - framesntohs(pCtx, &tmp82__, pBuf, 0); + framesntohs(pCtx, &tmp83__, pBuf, 0); pBuf += 2; ielen -= 2; - pDst->default_pe = tmp82__ >> 0 & 0x7; - pDst->twt_required = tmp82__ >> 3 & 0x1; - pDst->txop_rts_threshold = tmp82__ >> 4 & 0x3ff; - pDst->vht_oper_present = tmp82__ >> 14 & 0x1; - pDst->co_located_bss = tmp82__ >> 15 & 0x1; + pDst->default_pe = tmp83__ >> 0 & 0x7; + pDst->twt_required = tmp83__ >> 3 & 0x1; + pDst->txop_rts_threshold = tmp83__ >> 4 & 0x3ff; + pDst->vht_oper_present = tmp83__ >> 14 & 0x1; + pDst->co_located_bss = tmp83__ >> 15 & 0x1; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp83__ = *pBuf; + tmp84__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->er_su_disable = tmp83__ >> 0 & 0x1; - pDst->reserved2 = tmp83__ >> 1 & 0x7f; + pDst->er_su_disable = tmp84__ >> 0 & 0x1; + pDst->oper_info_6g_present = tmp84__ >> 1 & 0x1; + pDst->reserved2 = tmp84__ >> 2 & 0x3f; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp84__ = *pBuf; + tmp85__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->bss_color = tmp84__ >> 0 & 0x3f; - pDst->partial_bss_col = tmp84__ >> 6 & 0x1; - pDst->bss_col_disabled = tmp84__ >> 7 & 0x1; + pDst->bss_color = tmp85__ >> 0 & 0x3f; + pDst->partial_bss_col = tmp85__ >> 6 & 0x1; + pDst->bss_col_disabled = tmp85__ >> 7 & 0x1; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -9056,11 +9141,58 @@ uint32_t dot11f_unpack_ie_he_op(tpAniSirGlobal pCtx, ielen -= (uint8_t)1; break; } + switch (pDst->oper_info_6g_present) { + case 1: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->oper_info_6g.info.primary_ch = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + tmp86__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->oper_info_6g.info.ch_width = tmp86__ >> 0 & 0x3; + pDst->oper_info_6g.info.dup_bcon = tmp86__ >> 2 & 0x1; + pDst->oper_info_6g.info.reserved = tmp86__ >> 3 & 0x1f; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->oper_info_6g.info.center_freq_seg0 = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->oper_info_6g.info.center_freq_seg1 = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->oper_info_6g.info.min_rate = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + break; + } (void)pCtx; return status; } /* End dot11f_unpack_ie_he_op. */ -#define SigIehe_op (0x008f) +#define SigIehe_op (0x0091) uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, @@ -9070,7 +9202,7 @@ uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, bool append_ie) { uint32_t status = DOT11F_PARSE_SUCCESS; - uint8_t tmp85__; + uint8_t tmp87__; (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) return DOT11F_DUPLICATE_IE; @@ -9080,13 +9212,13 @@ uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp85__ = *pBuf; + tmp87__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->dgaf_dis = tmp85__ >> 0 & 0x1; - pDst->hs_id_present = tmp85__ >> 1 & 0x3; - pDst->reserved = tmp85__ >> 3 & 0x1; - pDst->release_num = tmp85__ >> 4 & 0xf; + pDst->dgaf_dis = tmp87__ >> 0 & 0x1; + pDst->hs_id_present = tmp87__ >> 1 & 0x3; + pDst->reserved = tmp87__ >> 3 & 0x1; + pDst->release_num = tmp87__ >> 4 & 0xf; if (!ielen) { return 0U; } else { @@ -9117,7 +9249,7 @@ uint32_t dot11f_unpack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_hs20vendor_ie. */ -#define SigIehs20vendor_ie (0x0090) +#define SigIehs20vendor_ie (0x0092) uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx, @@ -9127,7 +9259,7 @@ uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx, bool append_ie) { uint32_t status = DOT11F_PARSE_SUCCESS; - uint8_t tmp86__; + uint8_t tmp88__; (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) return DOT11F_DUPLICATE_IE; @@ -9137,18 +9269,18 @@ uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp86__ = *pBuf; - pDst->info_request = tmp86__ >> 0 & 0x1; - pDst->forty_mhz_intolerant = tmp86__ >> 1 & 0x1; - pDst->twenty_mhz_bsswidth_req = tmp86__ >> 2 & 0x1; - pDst->obss_scan_exemption_req = tmp86__ >> 3 & 0x1; - pDst->obss_scan_exemption_grant = tmp86__ >> 4 & 0x1; - pDst->unused = tmp86__ >> 5 & 0x7; + tmp88__ = *pBuf; + pDst->info_request = tmp88__ >> 0 & 0x1; + pDst->forty_mhz_intolerant = tmp88__ >> 1 & 0x1; + pDst->twenty_mhz_bsswidth_req = tmp88__ >> 2 & 0x1; + pDst->obss_scan_exemption_req = tmp88__ >> 3 & 0x1; + pDst->obss_scan_exemption_grant = tmp88__ >> 4 & 0x1; + pDst->unused = tmp88__ >> 5 & 0x7; (void)pCtx; return status; } /* End dot11f_unpack_ie_ht2040_bss_coexistence. */ -#define SigIeht2040_bss_coexistence (0x0091) +#define SigIeht2040_bss_coexistence (0x0093) uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx, @@ -9181,7 +9313,7 @@ uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_ht2040_bss_intolerant_report. */ -#define SigIeht2040_bss_intolerant_report (0x0092) +#define SigIeht2040_bss_intolerant_report (0x0094) uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, @@ -9191,14 +9323,14 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, bool append_ie) { uint32_t status = DOT11F_PARSE_SUCCESS; - uint8_t tmp87__; - uint8_t tmp88__; uint8_t tmp89__; uint8_t tmp90__; uint8_t tmp91__; uint8_t tmp92__; uint8_t tmp93__; uint8_t tmp94__; + uint8_t tmp95__; + uint8_t tmp96__; (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) return DOT11F_DUPLICATE_IE; @@ -9216,23 +9348,23 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp87__ = *pBuf; + tmp89__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acbe_aifsn = tmp87__ >> 0 & 0xf; - pDst->acbe_acm = tmp87__ >> 4 & 0x1; - pDst->acbe_aci = tmp87__ >> 5 & 0x3; - pDst->unused1 = tmp87__ >> 7 & 0x1; + pDst->acbe_aifsn = tmp89__ >> 0 & 0xf; + pDst->acbe_acm = tmp89__ >> 4 & 0x1; + pDst->acbe_aci = tmp89__ >> 5 & 0x3; + pDst->unused1 = tmp89__ >> 7 & 0x1; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp88__ = *pBuf; + tmp90__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acbe_acwmin = tmp88__ >> 0 & 0xf; - pDst->acbe_acwmax = tmp88__ >> 4 & 0xf; + pDst->acbe_acwmin = tmp90__ >> 0 & 0xf; + pDst->acbe_acwmax = tmp90__ >> 4 & 0xf; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -9246,23 +9378,23 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp89__ = *pBuf; + tmp91__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acbk_aifsn = tmp89__ >> 0 & 0xf; - pDst->acbk_acm = tmp89__ >> 4 & 0x1; - pDst->acbk_aci = tmp89__ >> 5 & 0x3; - pDst->unused2 = tmp89__ >> 7 & 0x1; + pDst->acbk_aifsn = tmp91__ >> 0 & 0xf; + pDst->acbk_acm = tmp91__ >> 4 & 0x1; + pDst->acbk_aci = tmp91__ >> 5 & 0x3; + pDst->unused2 = tmp91__ >> 7 & 0x1; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp90__ = *pBuf; + tmp92__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acbk_acwmin = tmp90__ >> 0 & 0xf; - pDst->acbk_acwmax = tmp90__ >> 4 & 0xf; + pDst->acbk_acwmin = tmp92__ >> 0 & 0xf; + pDst->acbk_acwmax = tmp92__ >> 4 & 0xf; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -9276,23 +9408,23 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp91__ = *pBuf; + tmp93__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acvi_aifsn = tmp91__ >> 0 & 0xf; - pDst->acvi_acm = tmp91__ >> 4 & 0x1; - pDst->acvi_aci = tmp91__ >> 5 & 0x3; - pDst->unused3 = tmp91__ >> 7 & 0x1; + pDst->acvi_aifsn = tmp93__ >> 0 & 0xf; + pDst->acvi_acm = tmp93__ >> 4 & 0x1; + pDst->acvi_aci = tmp93__ >> 5 & 0x3; + pDst->unused3 = tmp93__ >> 7 & 0x1; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp92__ = *pBuf; + tmp94__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acvi_acwmin = tmp92__ >> 0 & 0xf; - pDst->acvi_acwmax = tmp92__ >> 4 & 0xf; + pDst->acvi_acwmin = tmp94__ >> 0 & 0xf; + pDst->acvi_acwmax = tmp94__ >> 4 & 0xf; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -9306,23 +9438,23 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - tmp93__ = *pBuf; + tmp95__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acvo_aifsn = tmp93__ >> 0 & 0xf; - pDst->acvo_acm = tmp93__ >> 4 & 0x1; - pDst->acvo_aci = tmp93__ >> 5 & 0x3; - pDst->unused4 = tmp93__ >> 7 & 0x1; + pDst->acvo_aifsn = tmp95__ >> 0 & 0xf; + pDst->acvo_acm = tmp95__ >> 4 & 0x1; + pDst->acvo_aci = tmp95__ >> 5 & 0x3; + pDst->unused4 = tmp95__ >> 7 & 0x1; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; } - tmp94__ = *pBuf; + tmp96__ = *pBuf; pBuf += 1; ielen -= 1; - pDst->acvo_acwmin = tmp94__ >> 0 & 0xf; - pDst->acvo_acwmax = tmp94__ >> 4 & 0xf; + pDst->acvo_acwmin = tmp96__ >> 0 & 0xf; + pDst->acvo_acwmax = tmp96__ >> 4 & 0xf; if (unlikely(ielen < 1)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -9333,7 +9465,7 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_mu_edca_param_set. */ -#define SigIemu_edca_param_set (0x0093) +#define SigIemu_edca_param_set (0x0095) uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx, @@ -9353,7 +9485,7 @@ uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_osen_ie. */ -#define SigIeosen_ie (0x0094) +#define SigIeosen_ie (0x0096) static const tFFDefn FFS_qcn_ie[] = { @@ -9395,7 +9527,7 @@ uint32_t dot11f_unpack_ie_qcn_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qcn_ie. */ -#define SigIeqcn_ie (0x0095) +#define SigIeqcn_ie (0x0097) uint32_t dot11f_unpack_ie_roaming_consortium_sel(tpAniSirGlobal pCtx, @@ -9415,7 +9547,7 @@ uint32_t dot11f_unpack_ie_roaming_consortium_sel(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_roaming_consortium_sel. */ -#define SigIeroaming_consortium_sel (0x0096) +#define SigIeroaming_consortium_sel (0x0098) uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx, @@ -9439,7 +9571,7 @@ uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_sec_chan_offset_ele. */ -#define SigIesec_chan_offset_ele (0x0097) +#define SigIesec_chan_offset_ele (0x0099) static const tFFDefn FFS_vendor_vht_ie[] = { @@ -9488,7 +9620,7 @@ uint32_t dot11f_unpack_ie_vendor_vht_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_vendor_vht_ie. */ -#define SigIevendor_vht_ie (0x0098) +#define SigIevendor_vht_ie (0x009a) static const tFFDefn FFS_AddTSRequest[] = { @@ -9675,7 +9807,7 @@ static const tIEDefn IES_AssocRequest[] = { 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, 0, }, { offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, - present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + present), 0, "QosMapSet", 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0}, @@ -9751,6 +9883,10 @@ static const tIEDefn IES_AssocRequest[] = { { offsetof(tDot11fAssocRequest, he_cap), offsetof(tDot11fIEhe_cap, present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, + { offsetof(tDot11fAssocRequest, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fAssocRequest, osen_ie), offsetof(tDot11fIEosen_ie, present), 0, "osen_ie", 0, 6, 261, SigIeosen_ie, {80, 111, 154, 18, 0}, 4, DOT11F_EID_OSEN_IE, 0, 0, }, @@ -9876,7 +10012,7 @@ static const tIEDefn IES_AssocResponse[] = { 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, }, { offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, - present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + present), 0, "QosMapSet", 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fAssocResponse, fils_session), offsetof(tDot11fIEfils_session, present), 0, "fils_session", @@ -9912,8 +10048,12 @@ static const tIEDefn IES_AssocResponse[] = { present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fAssocResponse, he_op), offsetof(tDot11fIEhe_op, - present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + present), 0, "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fAssocResponse, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fAssocResponse, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -10205,8 +10345,12 @@ static const tIEDefn IES_Beacon[] = { "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fBeacon, he_op), offsetof(tDot11fIEhe_op, present), 0, - "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fBeacon, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fBeacon, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -10435,8 +10579,12 @@ static const tIEDefn IES_Beacon2[] = { "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fBeacon2, he_op), offsetof(tDot11fIEhe_op, present), 0, - "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fBeacon2, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fBeacon2, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -10661,8 +10809,12 @@ static const tIEDefn IES_BeaconIEs[] = { 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fBeaconIEs, he_op), offsetof(tDot11fIEhe_op, present), 0, - "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fBeaconIEs, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fBeaconIEs, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -11095,6 +11247,10 @@ static const tIEDefn IES_ProbeRequest[] = { { offsetof(tDot11fProbeRequest, he_cap), offsetof(tDot11fIEhe_cap, present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, + { offsetof(tDot11fProbeRequest, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; uint32_t dot11f_unpack_probe_request(tpAniSirGlobal pCtx, @@ -11306,8 +11462,12 @@ static const tIEDefn IES_ProbeResponse[] = { present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fProbeResponse, he_op), offsetof(tDot11fIEhe_op, - present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + present), 0, "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fProbeResponse, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fProbeResponse, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -11348,7 +11508,7 @@ static const tFFDefn FFS_QosMapConfigure[] = { static const tIEDefn IES_QosMapConfigure[] = { { offsetof(tDot11fQosMapConfigure, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 1, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; @@ -11383,6 +11543,10 @@ static const tIEDefn IES_RadioMeasurementReport[] = { offsetof(tDot11fRadioMeasurementReport, num_MeasurementReport), "MeasurementReport", 4, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREPORT, 0, 1, }, + { offsetof(tDot11fRadioMeasurementReport, BeaconReportStatus), + offsetof(tDot11fIEBeaconReportStatus, present), 0, "BeaconReportStatus", + 0, 10, 10, SigIeBeaconReportStatus, {0, 0, 15, 34, 0}, + 4, DOT11F_EID_BEACONREPORTSTATUS, 0, 0, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; uint32_t dot11f_unpack_radio_measurement_report(tpAniSirGlobal pCtx, @@ -11417,7 +11581,7 @@ static const tIEDefn IES_RadioMeasurementRequest[] = { { offsetof(tDot11fRadioMeasurementRequest, MeasurementRequest), offsetof(tDot11fIEMeasurementRequest, present), offsetof(tDot11fRadioMeasurementRequest, num_MeasurementRequest), - "MeasurementRequest", 2, 6, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, + "MeasurementRequest", 5, 6, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 0, 1, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; @@ -11490,6 +11654,10 @@ static const tIEDefn IES_ReAssocRequest[] = { offsetof(tDot11fReAssocRequest, num_RICDataDesc), "RICDataDesc", 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, 0, }, + { offsetof(tDot11fReAssocRequest, SuppOperatingClasses), + offsetof(tDot11fIESuppOperatingClasses, present), 0, + "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, 0, }, { offsetof(tDot11fReAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque", 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, @@ -11555,7 +11723,7 @@ static const tIEDefn IES_ReAssocRequest[] = { 0, DOT11F_EID_OPERATINGMODE, 0, 0, }, { offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fReAssocRequest, vendor_vht_ie), offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie", @@ -11568,6 +11736,10 @@ static const tIEDefn IES_ReAssocRequest[] = { { offsetof(tDot11fReAssocRequest, he_cap), offsetof(tDot11fIEhe_cap, present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, + { offsetof(tDot11fReAssocRequest, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; uint32_t dot11f_unpack_re_assoc_request(tpAniSirGlobal pCtx, @@ -11695,7 +11867,7 @@ static const tIEDefn IES_ReAssocResponse[] = { 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, }, { offsetof(tDot11fReAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fReAssocResponse, vendor_vht_ie), offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie", @@ -11705,8 +11877,12 @@ static const tIEDefn IES_ReAssocResponse[] = { present), 0, "he_cap", 0, 23, 56, SigIehe_cap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_CAP, 35, 0, }, { offsetof(tDot11fReAssocResponse, he_op), offsetof(tDot11fIEhe_op, - present), 0, "he_op", 0, 8, 12, SigIehe_op, {0, 0, 0, 0, 0}, + present), 0, "he_op", 0, 8, 17, SigIehe_op, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HE_OP, 36, 0, }, + { offsetof(tDot11fReAssocResponse, he_6ghz_band_cap), + offsetof(tDot11fIEhe_6ghz_band_cap, present), 0, "he_6ghz_band_cap", + 0, 4, 4, SigIehe_6ghz_band_cap, {0, 0, 0, 0, 0}, + 0, DOT11F_EID_HE_6GHZ_BAND_CAP, 59, 0, }, { offsetof(tDot11fReAssocResponse, bss_color_change), offsetof(tDot11fIEbss_color_change, present), 0, "bss_color_change", 0, 4, 4, SigIebss_color_change, {0, 0, 0, 0, 0}, @@ -13521,6 +13697,16 @@ static uint32_t unpack_core(tpAniSirGlobal pCtx, countOffset), append_ie); break; + case SigIeBeaconReportStatus: + status |= + dot11f_unpack_ie_BeaconReportStatus( + pCtx, pBufRemaining, len, + (tDot11fIEBeaconReportStatus *) + (pFrm + pIe->offset + + sizeof(tDot11fIEBeaconReportStatus) * + countOffset), + append_ie); + break; case SigIeCFParams: status |= dot11f_unpack_ie_cf_params( @@ -14527,6 +14713,16 @@ static uint32_t unpack_core(tpAniSirGlobal pCtx, countOffset), append_ie); break; + case SigIehe_6ghz_band_cap: + status |= + dot11f_unpack_ie_he_6ghz_band_cap( + pCtx, pBufRemaining, len, + (tDot11fIEhe_6ghz_band_cap *) + (pFrm + pIe->offset + + sizeof(tDot11fIEhe_6ghz_band_cap) * + countOffset), + append_ie); + break; case SigIehe_cap: status |= dot11f_unpack_ie_he_cap( @@ -15724,7 +15920,9 @@ uint32_t dot11f_get_packed_iersn(tpAniSirGlobal pCtx, if (pIe->pmkid_count) { *pnNeeded += 2; } else { - break; + if (pIe->gp_mgmt_cipher_suite_present) { + *pnNeeded += 2; + } } *pnNeeded += (pIe->pmkid_count * 16); if (pIe->gp_mgmt_cipher_suite_present) { @@ -15951,8 +16149,6 @@ uint32_t dot11f_get_packed_ie_he_op(tpAniSirGlobal pCtx, *pnNeeded += 1; break; } - } else { - break; } if (pIe->co_located_bss) { switch (pIe->co_located_bss) { @@ -15960,8 +16156,17 @@ uint32_t dot11f_get_packed_ie_he_op(tpAniSirGlobal pCtx, *pnNeeded += 1; break; } - } else { - break; + } + if (pIe->oper_info_6g_present) { + switch (pIe->oper_info_6g_present) { + case 1: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } } break; } @@ -16880,6 +17085,13 @@ static uint32_t get_packed_size_core(tpAniSirGlobal pCtx, (pFrm + pIe->offset + offset * i))-> present; break; + case SigIeBeaconReportStatus: + offset = sizeof(tDot11fIEBeaconReportStatus); + byteCount = 4; + pIePresent = ((tDot11fIEBeaconReportStatus *) + (pFrm + pIe->offset + offset * i))-> + present; + break; case SigIeCFParams: offset = sizeof(tDot11fIECFParams); byteCount = 6; @@ -17664,6 +17876,13 @@ static uint32_t get_packed_size_core(tpAniSirGlobal pCtx, (pFrm + pIe->offset + offset * i))-> present; break; + case SigIehe_6ghz_band_cap: + offset = sizeof(tDot11fIEhe_6ghz_band_cap); + byteCount = 2; + pIePresent = ((tDot11fIEhe_6ghz_band_cap *) + (pFrm + pIe->offset + offset * i))-> + present; + break; case SigIehe_cap: offset = sizeof(tDot11fIEhe_cap); status |= @@ -18091,25 +18310,25 @@ void dot11f_pack_ff_capabilities(tpAniSirGlobal pCtx, tDot11fFfCapabilities *pSrc, uint8_t *pBuf) { - uint16_t tmp95__; - tmp95__ = 0U; - tmp95__ |= (pSrc->ess << 0); - tmp95__ |= (pSrc->ibss << 1); - tmp95__ |= (pSrc->cfPollable << 2); - tmp95__ |= (pSrc->cfPollReq << 3); - tmp95__ |= (pSrc->privacy << 4); - tmp95__ |= (pSrc->shortPreamble << 5); - tmp95__ |= (pSrc->pbcc << 6); - tmp95__ |= (pSrc->channelAgility << 7); - tmp95__ |= (pSrc->spectrumMgt << 8); - tmp95__ |= (pSrc->qos << 9); - tmp95__ |= (pSrc->shortSlotTime << 10); - tmp95__ |= (pSrc->apsd << 11); - tmp95__ |= (pSrc->rrm << 12); - tmp95__ |= (pSrc->dsssOfdm << 13); - tmp95__ |= (pSrc->delayedBA << 14); - tmp95__ |= (pSrc->immediateBA << 15); - frameshtons(pCtx, pBuf, tmp95__, 0); + uint16_t tmp97__; + tmp97__ = 0U; + tmp97__ |= (pSrc->ess << 0); + tmp97__ |= (pSrc->ibss << 1); + tmp97__ |= (pSrc->cfPollable << 2); + tmp97__ |= (pSrc->cfPollReq << 3); + tmp97__ |= (pSrc->privacy << 4); + tmp97__ |= (pSrc->shortPreamble << 5); + tmp97__ |= (pSrc->pbcc << 6); + tmp97__ |= (pSrc->channelAgility << 7); + tmp97__ |= (pSrc->spectrumMgt << 8); + tmp97__ |= (pSrc->qos << 9); + tmp97__ |= (pSrc->shortSlotTime << 10); + tmp97__ |= (pSrc->apsd << 11); + tmp97__ |= (pSrc->rrm << 12); + tmp97__ |= (pSrc->dsssOfdm << 13); + tmp97__ |= (pSrc->delayedBA << 14); + tmp97__ |= (pSrc->immediateBA << 15); + frameshtons(pCtx, pBuf, tmp97__, 0); (void)pCtx; } /* End dot11f_pack_ff_capabilities. */ @@ -18173,13 +18392,13 @@ void dot11f_pack_ff_operating_mode(tpAniSirGlobal pCtx, tDot11fFfOperatingMode *pSrc, uint8_t *pBuf) { - uint8_t tmp96__; - tmp96__ = 0U; - tmp96__ |= (pSrc->chanWidth << 0); - tmp96__ |= (pSrc->reserved << 2); - tmp96__ |= (pSrc->rxNSS << 4); - tmp96__ |= (pSrc->rxNSSType << 7); - *pBuf = tmp96__; + uint8_t tmp98__; + tmp98__ = 0U; + tmp98__ |= (pSrc->chanWidth << 0); + tmp98__ |= (pSrc->reserved << 2); + tmp98__ |= (pSrc->rxNSS << 4); + tmp98__ |= (pSrc->rxNSSType << 7); + *pBuf = tmp98__; (void)pCtx; } /* End dot11f_pack_ff_operating_mode. */ @@ -18219,12 +18438,12 @@ void dot11f_pack_ff_sm_power_mode_set(tpAniSirGlobal pCtx, tDot11fFfSMPowerModeSet *pSrc, uint8_t *pBuf) { - uint8_t tmp97__; - tmp97__ = 0U; - tmp97__ |= (pSrc->PowerSave_En << 0); - tmp97__ |= (pSrc->Mode << 1); - tmp97__ |= (pSrc->reserved << 2); - *pBuf = tmp97__; + uint8_t tmp99__; + tmp99__ = 0U; + tmp99__ |= (pSrc->PowerSave_En << 0); + tmp99__ |= (pSrc->Mode << 1); + tmp99__ |= (pSrc->reserved << 2); + *pBuf = tmp99__; (void)pCtx; } /* End dot11f_pack_ff_sm_power_mode_set. */ @@ -18264,19 +18483,19 @@ void dot11f_pack_ff_ts_info(tpAniSirGlobal pCtx, tDot11fFfTSInfo *pSrc, uint8_t *pBuf) { - uint32_t tmp98__; - tmp98__ = 0U; - tmp98__ |= (pSrc->traffic_type << 0); - tmp98__ |= (pSrc->tsid << 1); - tmp98__ |= (pSrc->direction << 5); - tmp98__ |= (pSrc->access_policy << 7); - tmp98__ |= (pSrc->aggregation << 9); - tmp98__ |= (pSrc->psb << 10); - tmp98__ |= (pSrc->user_priority << 11); - tmp98__ |= (pSrc->tsinfo_ack_pol << 14); - tmp98__ |= (pSrc->schedule << 16); - tmp98__ |= (pSrc->unused << 17); - frameshtonl(pCtx, pBuf, tmp98__, 0); + uint32_t tmp100__; + tmp100__ = 0U; + tmp100__ |= (pSrc->traffic_type << 0); + tmp100__ |= (pSrc->tsid << 1); + tmp100__ |= (pSrc->direction << 5); + tmp100__ |= (pSrc->access_policy << 7); + tmp100__ |= (pSrc->aggregation << 9); + tmp100__ |= (pSrc->psb << 10); + tmp100__ |= (pSrc->user_priority << 11); + tmp100__ |= (pSrc->tsinfo_ack_pol << 14); + tmp100__ |= (pSrc->schedule << 16); + tmp100__ |= (pSrc->unused << 17); + frameshtonl(pCtx, pBuf, tmp100__, 0); (void)pCtx; } /* End dot11f_pack_ff_ts_info. */ @@ -18332,13 +18551,13 @@ void dot11f_pack_ff_addba_param_set(tpAniSirGlobal pCtx, tDot11fFfaddba_param_set *pSrc, uint8_t *pBuf) { - uint16_t tmp99__; - tmp99__ = 0U; - tmp99__ |= (pSrc->amsdu_supp << 0); - tmp99__ |= (pSrc->policy << 1); - tmp99__ |= (pSrc->tid << 2); - tmp99__ |= (pSrc->buff_size << 6); - frameshtons(pCtx, pBuf, tmp99__, 0); + uint16_t tmp101__; + tmp101__ = 0U; + tmp101__ |= (pSrc->amsdu_supp << 0); + tmp101__ |= (pSrc->policy << 1); + tmp101__ |= (pSrc->tid << 2); + tmp101__ |= (pSrc->buff_size << 6); + frameshtons(pCtx, pBuf, tmp101__, 0); (void)pCtx; } /* End dot11f_pack_ff_addba_param_set. */ @@ -18346,11 +18565,11 @@ void dot11f_pack_ff_ba_start_seq_ctrl(tpAniSirGlobal pCtx, tDot11fFfba_start_seq_ctrl *pSrc, uint8_t *pBuf) { - uint16_t tmp100__; - tmp100__ = 0U; - tmp100__ |= (pSrc->frag_number << 0); - tmp100__ |= (pSrc->ssn << 4); - frameshtons(pCtx, pBuf, tmp100__, 0); + uint16_t tmp102__; + tmp102__ = 0U; + tmp102__ |= (pSrc->frag_number << 0); + tmp102__ |= (pSrc->ssn << 4); + frameshtons(pCtx, pBuf, tmp102__, 0); (void)pCtx; } /* End dot11f_pack_ff_ba_start_seq_ctrl. */ @@ -18366,12 +18585,12 @@ void dot11f_pack_ff_delba_param_set(tpAniSirGlobal pCtx, tDot11fFfdelba_param_set *pSrc, uint8_t *pBuf) { - uint16_t tmp101__; - tmp101__ = 0U; - tmp101__ |= (pSrc->reserved << 0); - tmp101__ |= (pSrc->initiator << 11); - tmp101__ |= (pSrc->tid << 12); - frameshtons(pCtx, pBuf, tmp101__, 0); + uint16_t tmp103__; + tmp103__ = 0U; + tmp103__ |= (pSrc->reserved << 0); + tmp103__ |= (pSrc->initiator << 11); + tmp103__ |= (pSrc->tid << 12); + frameshtons(pCtx, pBuf, tmp103__, 0); (void)pCtx; } /* End dot11f_pack_ff_delba_param_set. */ @@ -18379,13 +18598,13 @@ void dot11f_pack_ff_ext_chan_switch_ann_action(tpAniSirGlobal pCtx, tDot11fFfext_chan_switch_ann_action *pSrc, uint8_t *pBuf) { - uint32_t tmp102__; - tmp102__ = 0U; - tmp102__ |= (pSrc->switch_mode << 0); - tmp102__ |= (pSrc->op_class << 8); - tmp102__ |= (pSrc->new_channel << 16); - tmp102__ |= (pSrc->switch_count << 24); - frameshtonl(pCtx, pBuf, tmp102__, 0); + uint32_t tmp104__; + tmp104__ = 0U; + tmp104__ |= (pSrc->switch_mode << 0); + tmp104__ |= (pSrc->op_class << 8); + tmp104__ |= (pSrc->new_channel << 16); + tmp104__ |= (pSrc->switch_count << 24); + frameshtonl(pCtx, pBuf, tmp104__, 0); (void)pCtx; } /* End dot11f_pack_ff_ext_chan_switch_ann_action. */ @@ -18488,7 +18707,7 @@ uint32_t dot11f_pack_tlv_version2(tpAniSirGlobal pCtx, uint8_t *pTlvLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp103__; + uint8_t tmp105__; nNeeded += 3; if (nNeeded > nBuf) return DOT11F_BUFFER_OVERFLOW; @@ -18497,13 +18716,13 @@ uint32_t dot11f_pack_tlv_version2(tpAniSirGlobal pCtx, pBuf += 1; *pnConsumed += 1; pTlvLen = pBuf; pBuf += 1; *pnConsumed += 1; - tmp103__ = 0U; - tmp103__ |= (pSrc->minor << 0); - tmp103__ |= (pSrc->major << 4); + tmp105__ = 0U; + tmp105__ |= (pSrc->minor << 0); + tmp105__ |= (pSrc->major << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp103__; + *pBuf = tmp105__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -19460,7 +19679,7 @@ uint32_t dot11f_pack_tlv_version(tpAniSirGlobal pCtx, uint8_t *pTlvLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp104__; + uint8_t tmp106__; nNeeded += 5; if (nNeeded > nBuf) return DOT11F_BUFFER_OVERFLOW; @@ -19469,13 +19688,13 @@ uint32_t dot11f_pack_tlv_version(tpAniSirGlobal pCtx, pBuf += 2; *pnConsumed += 2; pTlvLen = pBuf; pBuf += 2; *pnConsumed += 2; - tmp104__ = 0U; - tmp104__ |= (pSrc->minor << 0); - tmp104__ |= (pSrc->major << 4); + tmp106__ = 0U; + tmp106__ |= (pSrc->minor << 0); + tmp106__ |= (pSrc->major << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp104__; + *pBuf = tmp106__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -19704,7 +19923,7 @@ uint32_t dot11f_pack_tlv_oce_cap(tpAniSirGlobal pCtx, uint8_t *pTlvLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp105__; + uint8_t tmp107__; nNeeded += 3; if (nNeeded > nBuf) return DOT11F_BUFFER_OVERFLOW; @@ -19713,15 +19932,15 @@ uint32_t dot11f_pack_tlv_oce_cap(tpAniSirGlobal pCtx, pBuf += 1; *pnConsumed += 1; pTlvLen = pBuf; pBuf += 1; *pnConsumed += 1; - tmp105__ = 0U; - tmp105__ |= (pSrc->oce_release << 0); - tmp105__ |= (pSrc->is_sta_cfon << 3); - tmp105__ |= (pSrc->non_oce_ap_present << 4); - tmp105__ |= (pSrc->reserved << 5); + tmp107__ = 0U; + tmp107__ |= (pSrc->oce_release << 0); + tmp107__ |= (pSrc->is_sta_cfon << 3); + tmp107__ |= (pSrc->non_oce_ap_present << 4); + tmp107__ |= (pSrc->reserved << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp105__; + *pBuf = tmp107__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -19743,7 +19962,7 @@ uint32_t dot11f_pack_tlv_reduced_wan_metrics(tpAniSirGlobal pCtx, uint8_t *pTlvLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp106__; + uint8_t tmp108__; nNeeded += 3; if (nNeeded > nBuf) return DOT11F_BUFFER_OVERFLOW; @@ -19752,13 +19971,13 @@ uint32_t dot11f_pack_tlv_reduced_wan_metrics(tpAniSirGlobal pCtx, pBuf += 1; *pnConsumed += 1; pTlvLen = pBuf; pBuf += 1; *pnConsumed += 1; - tmp106__ = 0U; - tmp106__ |= (pSrc->downlink_av_cap << 0); - tmp106__ |= (pSrc->uplink_av_cap << 4); + tmp108__ = 0U; + tmp108__ |= (pSrc->downlink_av_cap << 0); + tmp108__ |= (pSrc->uplink_av_cap << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp106__; + *pBuf = tmp108__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -19928,7 +20147,7 @@ uint32_t dot11f_pack_ie_gtk(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp107__; + uint16_t tmp109__; nNeeded += (pSrc->num_key + 11); while (pSrc->present) { if (nNeeded > nBuf) @@ -19937,13 +20156,13 @@ uint32_t dot11f_pack_ie_gtk(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp107__ = 0U; - tmp107__ |= (pSrc->keyId << 0); - tmp107__ |= (pSrc->reserved << 2); + tmp109__ = 0U; + tmp109__ |= (pSrc->keyId << 0); + tmp109__ |= (pSrc->reserved << 2); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp107__, 0); + frameshtons(pCtx, pBuf, tmp109__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -20413,11 +20632,11 @@ uint32_t dot11f_pack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp108__; - uint8_t tmp109__; uint8_t tmp110__; uint8_t tmp111__; uint8_t tmp112__; + uint8_t tmp113__; + uint8_t tmp114__; nNeeded += 5; while (pSrc->present) { if (nNeeded > nBuf) @@ -20426,74 +20645,74 @@ uint32_t dot11f_pack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp108__ = 0U; - tmp108__ |= (pSrc->LinkMeasurement << 0); - tmp108__ |= (pSrc->NeighborRpt << 1); - tmp108__ |= (pSrc->parallel << 2); - tmp108__ |= (pSrc->repeated << 3); - tmp108__ |= (pSrc->BeaconPassive << 4); - tmp108__ |= (pSrc->BeaconActive << 5); - tmp108__ |= (pSrc->BeaconTable << 6); - tmp108__ |= (pSrc->BeaconRepCond << 7); + tmp110__ = 0U; + tmp110__ |= (pSrc->LinkMeasurement << 0); + tmp110__ |= (pSrc->NeighborRpt << 1); + tmp110__ |= (pSrc->parallel << 2); + tmp110__ |= (pSrc->repeated << 3); + tmp110__ |= (pSrc->BeaconPassive << 4); + tmp110__ |= (pSrc->BeaconActive << 5); + tmp110__ |= (pSrc->BeaconTable << 6); + tmp110__ |= (pSrc->BeaconRepCond << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp108__; + *pBuf = tmp110__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp109__ = 0U; - tmp109__ |= (pSrc->FrameMeasurement << 0); - tmp109__ |= (pSrc->ChannelLoad << 1); - tmp109__ |= (pSrc->NoiseHistogram << 2); - tmp109__ |= (pSrc->statistics << 3); - tmp109__ |= (pSrc->LCIMeasurement << 4); - tmp109__ |= (pSrc->LCIAzimuth << 5); - tmp109__ |= (pSrc->TCMCapability << 6); - tmp109__ |= (pSrc->triggeredTCM << 7); + tmp111__ = 0U; + tmp111__ |= (pSrc->FrameMeasurement << 0); + tmp111__ |= (pSrc->ChannelLoad << 1); + tmp111__ |= (pSrc->NoiseHistogram << 2); + tmp111__ |= (pSrc->statistics << 3); + tmp111__ |= (pSrc->LCIMeasurement << 4); + tmp111__ |= (pSrc->LCIAzimuth << 5); + tmp111__ |= (pSrc->TCMCapability << 6); + tmp111__ |= (pSrc->triggeredTCM << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp109__; + *pBuf = tmp111__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp110__ = 0U; - tmp110__ |= (pSrc->APChanReport << 0); - tmp110__ |= (pSrc->RRMMIBEnabled << 1); - tmp110__ |= (pSrc->operatingChanMax << 2); - tmp110__ |= (pSrc->nonOperatinChanMax << 5); + tmp112__ = 0U; + tmp112__ |= (pSrc->APChanReport << 0); + tmp112__ |= (pSrc->RRMMIBEnabled << 1); + tmp112__ |= (pSrc->operatingChanMax << 2); + tmp112__ |= (pSrc->nonOperatinChanMax << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp110__; + *pBuf = tmp112__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp111__ = 0U; - tmp111__ |= (pSrc->MeasurementPilot << 0); - tmp111__ |= (pSrc->MeasurementPilotEnabled << 3); - tmp111__ |= (pSrc->NeighborTSFOffset << 4); - tmp111__ |= (pSrc->RCPIMeasurement << 5); - tmp111__ |= (pSrc->RSNIMeasurement << 6); - tmp111__ |= (pSrc->BssAvgAccessDelay << 7); + tmp113__ = 0U; + tmp113__ |= (pSrc->MeasurementPilot << 0); + tmp113__ |= (pSrc->MeasurementPilotEnabled << 3); + tmp113__ |= (pSrc->NeighborTSFOffset << 4); + tmp113__ |= (pSrc->RCPIMeasurement << 5); + tmp113__ |= (pSrc->RSNIMeasurement << 6); + tmp113__ |= (pSrc->BssAvgAccessDelay << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp111__; + *pBuf = tmp113__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp112__ = 0U; - tmp112__ |= (pSrc->BSSAvailAdmission << 0); - tmp112__ |= (pSrc->AntennaInformation << 1); - tmp112__ |= (pSrc->fine_time_meas_rpt << 2); - tmp112__ |= (pSrc->lci_capability << 3); - tmp112__ |= (pSrc->reserved << 4); + tmp114__ = 0U; + tmp114__ |= (pSrc->BSSAvailAdmission << 0); + tmp114__ |= (pSrc->AntennaInformation << 1); + tmp114__ |= (pSrc->fine_time_meas_rpt << 2); + tmp114__ |= (pSrc->lci_capability << 3); + tmp114__ |= (pSrc->reserved << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp112__; + *pBuf = tmp114__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -20573,7 +20792,7 @@ uint32_t dot11f_pack_ie_schedule(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp113__; + uint16_t tmp115__; nNeeded += 14; while (pSrc->present) { if (nNeeded > nBuf) @@ -20582,15 +20801,15 @@ uint32_t dot11f_pack_ie_schedule(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp113__ = 0U; - tmp113__ |= (pSrc->aggregation << 0); - tmp113__ |= (pSrc->tsid << 1); - tmp113__ |= (pSrc->direction << 5); - tmp113__ |= (pSrc->reserved << 7); + tmp115__ = 0U; + tmp115__ |= (pSrc->aggregation << 0); + tmp115__ |= (pSrc->tsid << 1); + tmp115__ |= (pSrc->direction << 5); + tmp115__ |= (pSrc->reserved << 7); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp113__, 0); + frameshtons(pCtx, pBuf, tmp115__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -20817,9 +21036,9 @@ uint32_t dot11f_pack_ie_tspec(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp114__; - uint8_t tmp115__; uint16_t tmp116__; + uint8_t tmp117__; + uint16_t tmp118__; nNeeded += 55; while (pSrc->present) { if (nNeeded > nBuf) @@ -20828,39 +21047,39 @@ uint32_t dot11f_pack_ie_tspec(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp114__ = 0U; - tmp114__ |= (pSrc->traffic_type << 0); - tmp114__ |= (pSrc->tsid << 1); - tmp114__ |= (pSrc->direction << 5); - tmp114__ |= (pSrc->access_policy << 7); - tmp114__ |= (pSrc->aggregation << 9); - tmp114__ |= (pSrc->psb << 10); - tmp114__ |= (pSrc->user_priority << 11); - tmp114__ |= (pSrc->tsinfo_ack_pol << 14); + tmp116__ = 0U; + tmp116__ |= (pSrc->traffic_type << 0); + tmp116__ |= (pSrc->tsid << 1); + tmp116__ |= (pSrc->direction << 5); + tmp116__ |= (pSrc->access_policy << 7); + tmp116__ |= (pSrc->aggregation << 9); + tmp116__ |= (pSrc->psb << 10); + tmp116__ |= (pSrc->user_priority << 11); + tmp116__ |= (pSrc->tsinfo_ack_pol << 14); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp114__, 0); + frameshtons(pCtx, pBuf, tmp116__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp115__ = 0U; - tmp115__ |= (pSrc->schedule << 0); - tmp115__ |= (pSrc->unused << 1); + tmp117__ = 0U; + tmp117__ |= (pSrc->schedule << 0); + tmp117__ |= (pSrc->unused << 1); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp115__; + *pBuf = tmp117__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp116__ = 0U; - tmp116__ |= (pSrc->size << 0); - tmp116__ |= (pSrc->fixed << 15); + tmp118__ = 0U; + tmp118__ |= (pSrc->size << 0); + tmp118__ |= (pSrc->fixed << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp116__, 0); + frameshtons(pCtx, pBuf, tmp118__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -20924,9 +21143,9 @@ uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint32_t tmp117__; - uint16_t tmp118__; - uint16_t tmp119__; + uint32_t tmp119__; + uint16_t tmp120__; + uint16_t tmp121__; nNeeded += 12; while (pSrc->present) { if (nNeeded > nBuf) @@ -20935,57 +21154,58 @@ uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp117__ = 0U; - tmp117__ |= (pSrc->maxMPDULen << 0); - tmp117__ |= (pSrc->supportedChannelWidthSet << 2); - tmp117__ |= (pSrc->ldpcCodingCap << 4); - tmp117__ |= (pSrc->shortGI80MHz << 5); - tmp117__ |= (pSrc->shortGI160and80plus80MHz << 6); - tmp117__ |= (pSrc->txSTBC << 7); - tmp117__ |= (pSrc->rxSTBC << 8); - tmp117__ |= (pSrc->suBeamFormerCap << 11); - tmp117__ |= (pSrc->suBeamformeeCap << 12); - tmp117__ |= (pSrc->csnofBeamformerAntSup << 13); - tmp117__ |= (pSrc->numSoundingDim << 16); - tmp117__ |= (pSrc->muBeamformerCap << 19); - tmp117__ |= (pSrc->muBeamformeeCap << 20); - tmp117__ |= (pSrc->vhtTXOPPS << 21); - tmp117__ |= (pSrc->htcVHTCap << 22); - tmp117__ |= (pSrc->maxAMPDULenExp << 23); - tmp117__ |= (pSrc->vhtLinkAdaptCap << 26); - tmp117__ |= (pSrc->rxAntPattern << 28); - tmp117__ |= (pSrc->txAntPattern << 29); - tmp117__ |= (pSrc->reserved1 << 30); + tmp119__ = 0U; + tmp119__ |= (pSrc->maxMPDULen << 0); + tmp119__ |= (pSrc->supportedChannelWidthSet << 2); + tmp119__ |= (pSrc->ldpcCodingCap << 4); + tmp119__ |= (pSrc->shortGI80MHz << 5); + tmp119__ |= (pSrc->shortGI160and80plus80MHz << 6); + tmp119__ |= (pSrc->txSTBC << 7); + tmp119__ |= (pSrc->rxSTBC << 8); + tmp119__ |= (pSrc->suBeamFormerCap << 11); + tmp119__ |= (pSrc->suBeamformeeCap << 12); + tmp119__ |= (pSrc->csnofBeamformerAntSup << 13); + tmp119__ |= (pSrc->numSoundingDim << 16); + tmp119__ |= (pSrc->muBeamformerCap << 19); + tmp119__ |= (pSrc->muBeamformeeCap << 20); + tmp119__ |= (pSrc->vhtTXOPPS << 21); + tmp119__ |= (pSrc->htcVHTCap << 22); + tmp119__ |= (pSrc->maxAMPDULenExp << 23); + tmp119__ |= (pSrc->vhtLinkAdaptCap << 26); + tmp119__ |= (pSrc->rxAntPattern << 28); + tmp119__ |= (pSrc->txAntPattern << 29); + tmp119__ |= (pSrc->extended_nss_bw_supp << 30); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; - frameshtonl(pCtx, pBuf, tmp117__, 0); + frameshtonl(pCtx, pBuf, tmp119__, 0); *pnConsumed += 4; pBuf += 4; nBuf -= 4 ; frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0); *pnConsumed += 2; pBuf += 2; - tmp118__ = 0U; - tmp118__ |= (pSrc->rxHighSupDataRate << 0); - tmp118__ |= (pSrc->reserved2 << 13); + tmp120__ = 0U; + tmp120__ |= (pSrc->rxHighSupDataRate << 0); + tmp120__ |= (pSrc->max_nsts_total << 13); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp118__, 0); + frameshtons(pCtx, pBuf, tmp120__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0); *pnConsumed += 2; pBuf += 2; - tmp119__ = 0U; - tmp119__ |= (pSrc->txSupDataRate << 0); - tmp119__ |= (pSrc->reserved3 << 13); + tmp121__ = 0U; + tmp121__ |= (pSrc->txSupDataRate << 0); + tmp121__ |= (pSrc->vht_extended_nss_bw_cap << 13); + tmp121__ |= (pSrc->reserved << 14); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp119__, 0); + frameshtons(pCtx, pBuf, tmp121__, 0); *pnConsumed += 2; /* fieldsEndFlag = 1 */ nBuf -= 2 ; @@ -21018,10 +21238,10 @@ uint32_t dot11f_pack_ie_vht_operation(tpAniSirGlobal pCtx, *pBuf = pSrc->chanWidth; *pnConsumed += 1; pBuf += 1; - *pBuf = pSrc->chanCenterFreqSeg1; + *pBuf = pSrc->chan_center_freq_seg0; *pnConsumed += 1; pBuf += 1; - *pBuf = pSrc->chanCenterFreqSeg2; + *pBuf = pSrc->chan_center_freq_seg1; *pnConsumed += 1; pBuf += 1; frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0); @@ -21045,7 +21265,7 @@ uint32_t dot11f_pack_ie_wmm_schedule(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp120__; + uint16_t tmp122__; nNeeded += 15; while (pSrc->present) { if (nNeeded > nBuf) @@ -21067,15 +21287,15 @@ uint32_t dot11f_pack_ie_wmm_schedule(tpAniSirGlobal pCtx, *pBuf = pSrc->version; *pnConsumed += 1; pBuf += 1; - tmp120__ = 0U; - tmp120__ |= (pSrc->aggregation << 0); - tmp120__ |= (pSrc->tsid << 1); - tmp120__ |= (pSrc->direction << 5); - tmp120__ |= (pSrc->reserved << 7); + tmp122__ = 0U; + tmp122__ |= (pSrc->aggregation << 0); + tmp122__ |= (pSrc->tsid << 1); + tmp122__ |= (pSrc->direction << 5); + tmp122__ |= (pSrc->reserved << 7); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp120__, 0); + frameshtons(pCtx, pBuf, tmp122__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -21309,9 +21529,9 @@ uint32_t dot11f_pack_ie_wmmtspec(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp121__; - uint8_t tmp122__; uint16_t tmp123__; + uint8_t tmp124__; + uint16_t tmp125__; nNeeded += 38; while (pSrc->present) { if (nNeeded > nBuf) @@ -21333,39 +21553,39 @@ uint32_t dot11f_pack_ie_wmmtspec(tpAniSirGlobal pCtx, *pBuf = pSrc->version; *pnConsumed += 1; pBuf += 1; - tmp121__ = 0U; - tmp121__ |= (pSrc->traffic_type << 0); - tmp121__ |= (pSrc->tsid << 1); - tmp121__ |= (pSrc->direction << 5); - tmp121__ |= (pSrc->access_policy << 7); - tmp121__ |= (pSrc->aggregation << 9); - tmp121__ |= (pSrc->psb << 10); - tmp121__ |= (pSrc->user_priority << 11); - tmp121__ |= (pSrc->tsinfo_ack_pol << 14); + tmp123__ = 0U; + tmp123__ |= (pSrc->traffic_type << 0); + tmp123__ |= (pSrc->tsid << 1); + tmp123__ |= (pSrc->direction << 5); + tmp123__ |= (pSrc->access_policy << 7); + tmp123__ |= (pSrc->aggregation << 9); + tmp123__ |= (pSrc->psb << 10); + tmp123__ |= (pSrc->user_priority << 11); + tmp123__ |= (pSrc->tsinfo_ack_pol << 14); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp121__, 0); + frameshtons(pCtx, pBuf, tmp123__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp122__ = 0U; - tmp122__ |= (pSrc->tsinfo_rsvd << 0); - tmp122__ |= (pSrc->burst_size_defn << 7); + tmp124__ = 0U; + tmp124__ |= (pSrc->tsinfo_rsvd << 0); + tmp124__ |= (pSrc->burst_size_defn << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp122__; + *pBuf = tmp124__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp123__ = 0U; - tmp123__ |= (pSrc->size << 0); - tmp123__ |= (pSrc->fixed << 15); + tmp125__ = 0U; + tmp125__ |= (pSrc->size << 0); + tmp125__ |= (pSrc->fixed << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp123__, 0); + frameshtons(pCtx, pBuf, tmp125__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -21493,7 +21713,7 @@ uint32_t dot11f_pack_ie_beacon_report_frm_body_fragment_id(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp124__; + uint16_t tmp126__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -21502,14 +21722,14 @@ uint32_t dot11f_pack_ie_beacon_report_frm_body_fragment_id(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp124__ = 0U; - tmp124__ |= (pSrc->beacon_report_id << 0); - tmp124__ |= (pSrc->fragment_id_number << 8); - tmp124__ |= (pSrc->more_fragments << 15); + tmp126__ = 0U; + tmp126__ |= (pSrc->beacon_report_id << 0); + tmp126__ |= (pSrc->fragment_id_number << 8); + tmp126__ |= (pSrc->more_fragments << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp124__, 0); + frameshtons(pCtx, pBuf, tmp126__, 0); *pnConsumed += 2; /* fieldsEndFlag = 1 */ nBuf -= 2 ; @@ -21589,8 +21809,8 @@ uint32_t dot11f_pack_ie_neighbor_rpt(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp125__; - uint8_t tmp126__; + uint8_t tmp127__; + uint8_t tmp128__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_neighbor_rpt(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -21605,30 +21825,30 @@ uint32_t dot11f_pack_ie_neighbor_rpt(tpAniSirGlobal pCtx, DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); *pnConsumed += 6; pBuf += 6; - tmp125__ = 0U; - tmp125__ |= (pSrc->APReachability << 0); - tmp125__ |= (pSrc->Security << 2); - tmp125__ |= (pSrc->KeyScope << 3); - tmp125__ |= (pSrc->SpecMgmtCap << 4); - tmp125__ |= (pSrc->QosCap << 5); - tmp125__ |= (pSrc->apsd << 6); - tmp125__ |= (pSrc->rrm << 7); + tmp127__ = 0U; + tmp127__ |= (pSrc->APReachability << 0); + tmp127__ |= (pSrc->Security << 2); + tmp127__ |= (pSrc->KeyScope << 3); + tmp127__ |= (pSrc->SpecMgmtCap << 4); + tmp127__ |= (pSrc->QosCap << 5); + tmp127__ |= (pSrc->apsd << 6); + tmp127__ |= (pSrc->rrm << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp125__; + *pBuf = tmp127__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp126__ = 0U; - tmp126__ |= (pSrc->DelayedBA << 0); - tmp126__ |= (pSrc->ImmBA << 1); - tmp126__ |= (pSrc->MobilityDomain << 2); - tmp126__ |= (pSrc->reserved << 3); + tmp128__ = 0U; + tmp128__ |= (pSrc->DelayedBA << 0); + tmp128__ |= (pSrc->ImmBA << 1); + tmp128__ |= (pSrc->MobilityDomain << 2); + tmp128__ |= (pSrc->reserved << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp126__; + *pBuf = tmp128__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -21776,6 +21996,52 @@ uint32_t dot11f_pack_ie_aid(tpAniSirGlobal pCtx, return DOT11F_PARSE_SUCCESS; } /* End dot11f_pack_ie_aid. */ +uint32_t dot11f_pack_ie_BeaconReportStatus(tpAniSirGlobal pCtx, + tDot11fIEBeaconReportStatus *pSrc, + uint8_t *pBuf, + uint32_t nBuf, + uint32_t *pnConsumed) +{ + uint8_t *pIeLen = 0; + uint32_t nConsumedOnEntry = *pnConsumed; + uint32_t nNeeded = 0U; + nNeeded += 4; + while (pSrc->present) { + if (nNeeded > nBuf) + return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x22; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->sub_type; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->length; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reason_code; + *pnConsumed += 1; + /* fieldsEndFlag = 1 */ + break; + } + (void)pCtx; + if (pIeLen) { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11f_pack_ie_BeaconReportStatus. */ + uint32_t dot11f_pack_ie_cf_params(tpAniSirGlobal pCtx, tDot11fIECFParams *pSrc, uint8_t *pBuf, @@ -21991,14 +22257,14 @@ uint32_t dot11f_pack_ie_edca_param_set(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp127__; - uint8_t tmp128__; uint8_t tmp129__; uint8_t tmp130__; uint8_t tmp131__; uint8_t tmp132__; uint8_t tmp133__; uint8_t tmp134__; + uint8_t tmp135__; + uint8_t tmp136__; nNeeded += 18; while (pSrc->present) { if (nNeeded > nBuf) @@ -22013,100 +22279,100 @@ uint32_t dot11f_pack_ie_edca_param_set(tpAniSirGlobal pCtx, *pBuf = pSrc->reserved; *pnConsumed += 1; pBuf += 1; - tmp127__ = 0U; - tmp127__ |= (pSrc->acbe_aifsn << 0); - tmp127__ |= (pSrc->acbe_acm << 4); - tmp127__ |= (pSrc->acbe_aci << 5); - tmp127__ |= (pSrc->unused1 << 7); + tmp129__ = 0U; + tmp129__ |= (pSrc->acbe_aifsn << 0); + tmp129__ |= (pSrc->acbe_acm << 4); + tmp129__ |= (pSrc->acbe_aci << 5); + tmp129__ |= (pSrc->unused1 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp127__; + *pBuf = tmp129__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp128__ = 0U; - tmp128__ |= (pSrc->acbe_acwmin << 0); - tmp128__ |= (pSrc->acbe_acwmax << 4); + tmp130__ = 0U; + tmp130__ |= (pSrc->acbe_acwmin << 0); + tmp130__ |= (pSrc->acbe_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp128__; + *pBuf = tmp130__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp129__ = 0U; - tmp129__ |= (pSrc->acbk_aifsn << 0); - tmp129__ |= (pSrc->acbk_acm << 4); - tmp129__ |= (pSrc->acbk_aci << 5); - tmp129__ |= (pSrc->unused2 << 7); + tmp131__ = 0U; + tmp131__ |= (pSrc->acbk_aifsn << 0); + tmp131__ |= (pSrc->acbk_acm << 4); + tmp131__ |= (pSrc->acbk_aci << 5); + tmp131__ |= (pSrc->unused2 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp129__; + *pBuf = tmp131__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp130__ = 0U; - tmp130__ |= (pSrc->acbk_acwmin << 0); - tmp130__ |= (pSrc->acbk_acwmax << 4); + tmp132__ = 0U; + tmp132__ |= (pSrc->acbk_acwmin << 0); + tmp132__ |= (pSrc->acbk_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp130__; + *pBuf = tmp132__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp131__ = 0U; - tmp131__ |= (pSrc->acvi_aifsn << 0); - tmp131__ |= (pSrc->acvi_acm << 4); - tmp131__ |= (pSrc->acvi_aci << 5); - tmp131__ |= (pSrc->unused3 << 7); + tmp133__ = 0U; + tmp133__ |= (pSrc->acvi_aifsn << 0); + tmp133__ |= (pSrc->acvi_acm << 4); + tmp133__ |= (pSrc->acvi_aci << 5); + tmp133__ |= (pSrc->unused3 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp131__; + *pBuf = tmp133__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp132__ = 0U; - tmp132__ |= (pSrc->acvi_acwmin << 0); - tmp132__ |= (pSrc->acvi_acwmax << 4); + tmp134__ = 0U; + tmp134__ |= (pSrc->acvi_acwmin << 0); + tmp134__ |= (pSrc->acvi_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp132__; + *pBuf = tmp134__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp133__ = 0U; - tmp133__ |= (pSrc->acvo_aifsn << 0); - tmp133__ |= (pSrc->acvo_acm << 4); - tmp133__ |= (pSrc->acvo_aci << 5); - tmp133__ |= (pSrc->unused4 << 7); + tmp135__ = 0U; + tmp135__ |= (pSrc->acvo_aifsn << 0); + tmp135__ |= (pSrc->acvo_acm << 4); + tmp135__ |= (pSrc->acvo_aci << 5); + tmp135__ |= (pSrc->unused4 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp133__; + *pBuf = tmp135__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp134__ = 0U; - tmp134__ |= (pSrc->acvo_acwmin << 0); - tmp134__ |= (pSrc->acvo_acwmax << 4); + tmp136__ = 0U; + tmp136__ |= (pSrc->acvo_acwmin << 0); + tmp136__ |= (pSrc->acvo_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp134__; + *pBuf = tmp136__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -22131,7 +22397,7 @@ uint32_t dot11f_pack_ie_erp_info(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp135__; + uint8_t tmp137__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -22140,15 +22406,15 @@ uint32_t dot11f_pack_ie_erp_info(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp135__ = 0U; - tmp135__ |= (pSrc->non_erp_present << 0); - tmp135__ |= (pSrc->use_prot << 1); - tmp135__ |= (pSrc->barker_preamble << 2); - tmp135__ |= (pSrc->unused << 3); + tmp137__ = 0U; + tmp137__ |= (pSrc->non_erp_present << 0); + tmp137__ |= (pSrc->use_prot << 1); + tmp137__ |= (pSrc->barker_preamble << 2); + tmp137__ |= (pSrc->unused << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp135__; + *pBuf = tmp137__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -22207,7 +22473,7 @@ uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp136__; + uint8_t tmp138__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -22227,13 +22493,13 @@ uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx, *pBuf = pSrc->mgmt_state; *pnConsumed += 1; pBuf += 1; - tmp136__ = 0U; - tmp136__ |= (pSrc->mbssid_mask << 0); - tmp136__ |= (pSrc->reserved << 3); + tmp138__ = 0U; + tmp138__ |= (pSrc->mbssid_mask << 0); + tmp138__ |= (pSrc->reserved << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp136__; + *pBuf = tmp138__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -22584,7 +22850,7 @@ uint32_t dot11f_pack_ie_ft_info(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp137__; + uint16_t tmp139__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ieft_info(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -22596,13 +22862,13 @@ uint32_t dot11f_pack_ie_ft_info(tpAniSirGlobal pCtx, ++pBuf; --nBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; --nBuf; ++(*pnConsumed); - tmp137__ = 0U; - tmp137__ |= (pSrc->reserved << 0); - tmp137__ |= (pSrc->IECount << 8); + tmp139__ = 0U; + tmp139__ |= (pSrc->reserved << 0); + tmp139__ |= (pSrc->IECount << 8); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp137__, 0); + frameshtons(pCtx, pBuf, tmp139__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -22640,11 +22906,11 @@ uint32_t dot11f_pack_ie_ht_caps(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp138__; - uint8_t tmp139__; uint16_t tmp140__; - uint32_t tmp141__; - uint8_t tmp142__; + uint8_t tmp141__; + uint16_t tmp142__; + uint32_t tmp143__; + uint8_t tmp144__; nNeeded += (pSrc->num_rsvd + 26); while (pSrc->present) { if (nNeeded > nBuf) @@ -22653,92 +22919,92 @@ uint32_t dot11f_pack_ie_ht_caps(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp138__ = 0U; - tmp138__ |= (pSrc->advCodingCap << 0); - tmp138__ |= (pSrc->supportedChannelWidthSet << 1); - tmp138__ |= (pSrc->mimoPowerSave << 2); - tmp138__ |= (pSrc->greenField << 4); - tmp138__ |= (pSrc->shortGI20MHz << 5); - tmp138__ |= (pSrc->shortGI40MHz << 6); - tmp138__ |= (pSrc->txSTBC << 7); - tmp138__ |= (pSrc->rxSTBC << 8); - tmp138__ |= (pSrc->delayedBA << 10); - tmp138__ |= (pSrc->maximalAMSDUsize << 11); - tmp138__ |= (pSrc->dsssCckMode40MHz << 12); - tmp138__ |= (pSrc->psmp << 13); - tmp138__ |= (pSrc->stbcControlFrame << 14); - tmp138__ |= (pSrc->lsigTXOPProtection << 15); + tmp140__ = 0U; + tmp140__ |= (pSrc->advCodingCap << 0); + tmp140__ |= (pSrc->supportedChannelWidthSet << 1); + tmp140__ |= (pSrc->mimoPowerSave << 2); + tmp140__ |= (pSrc->greenField << 4); + tmp140__ |= (pSrc->shortGI20MHz << 5); + tmp140__ |= (pSrc->shortGI40MHz << 6); + tmp140__ |= (pSrc->txSTBC << 7); + tmp140__ |= (pSrc->rxSTBC << 8); + tmp140__ |= (pSrc->delayedBA << 10); + tmp140__ |= (pSrc->maximalAMSDUsize << 11); + tmp140__ |= (pSrc->dsssCckMode40MHz << 12); + tmp140__ |= (pSrc->psmp << 13); + tmp140__ |= (pSrc->stbcControlFrame << 14); + tmp140__ |= (pSrc->lsigTXOPProtection << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp138__, 0); + frameshtons(pCtx, pBuf, tmp140__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp139__ = 0U; - tmp139__ |= (pSrc->maxRxAMPDUFactor << 0); - tmp139__ |= (pSrc->mpduDensity << 2); - tmp139__ |= (pSrc->reserved1 << 5); + tmp141__ = 0U; + tmp141__ |= (pSrc->maxRxAMPDUFactor << 0); + tmp141__ |= (pSrc->mpduDensity << 2); + tmp141__ |= (pSrc->reserved1 << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp139__; + *pBuf = tmp141__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16); *pnConsumed += 16; pBuf += 16; - tmp140__ = 0U; - tmp140__ |= (pSrc->pco << 0); - tmp140__ |= (pSrc->transitionTime << 1); - tmp140__ |= (pSrc->reserved2 << 3); - tmp140__ |= (pSrc->mcsFeedback << 8); - tmp140__ |= (pSrc->reserved3 << 10); + tmp142__ = 0U; + tmp142__ |= (pSrc->pco << 0); + tmp142__ |= (pSrc->transitionTime << 1); + tmp142__ |= (pSrc->reserved2 << 3); + tmp142__ |= (pSrc->mcsFeedback << 8); + tmp142__ |= (pSrc->reserved3 << 10); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp140__, 0); + frameshtons(pCtx, pBuf, tmp142__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp141__ = 0U; - tmp141__ |= (pSrc->txBF << 0); - tmp141__ |= (pSrc->rxStaggeredSounding << 1); - tmp141__ |= (pSrc->txStaggeredSounding << 2); - tmp141__ |= (pSrc->rxZLF << 3); - tmp141__ |= (pSrc->txZLF << 4); - tmp141__ |= (pSrc->implicitTxBF << 5); - tmp141__ |= (pSrc->calibration << 6); - tmp141__ |= (pSrc->explicitCSITxBF << 8); - tmp141__ |= (pSrc->explicitUncompressedSteeringMatrix << 9); - tmp141__ |= (pSrc->explicitBFCSIFeedback << 10); - tmp141__ |= (pSrc->explicitUncompressedSteeringMatrixFeedback << 13); - tmp141__ |= (pSrc->explicitCompressedSteeringMatrixFeedback << 16); - tmp141__ |= (pSrc->csiNumBFAntennae << 19); - tmp141__ |= (pSrc->uncompressedSteeringMatrixBFAntennae << 21); - tmp141__ |= (pSrc->compressedSteeringMatrixBFAntennae << 23); - tmp141__ |= (pSrc->reserved4 << 25); + tmp143__ = 0U; + tmp143__ |= (pSrc->txBF << 0); + tmp143__ |= (pSrc->rxStaggeredSounding << 1); + tmp143__ |= (pSrc->txStaggeredSounding << 2); + tmp143__ |= (pSrc->rxZLF << 3); + tmp143__ |= (pSrc->txZLF << 4); + tmp143__ |= (pSrc->implicitTxBF << 5); + tmp143__ |= (pSrc->calibration << 6); + tmp143__ |= (pSrc->explicitCSITxBF << 8); + tmp143__ |= (pSrc->explicitUncompressedSteeringMatrix << 9); + tmp143__ |= (pSrc->explicitBFCSIFeedback << 10); + tmp143__ |= (pSrc->explicitUncompressedSteeringMatrixFeedback << 13); + tmp143__ |= (pSrc->explicitCompressedSteeringMatrixFeedback << 16); + tmp143__ |= (pSrc->csiNumBFAntennae << 19); + tmp143__ |= (pSrc->uncompressedSteeringMatrixBFAntennae << 21); + tmp143__ |= (pSrc->compressedSteeringMatrixBFAntennae << 23); + tmp143__ |= (pSrc->reserved4 << 25); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; - frameshtonl(pCtx, pBuf, tmp141__, 0); + frameshtonl(pCtx, pBuf, tmp143__, 0); *pnConsumed += 4; pBuf += 4; nBuf -= 4 ; - tmp142__ = 0U; - tmp142__ |= (pSrc->antennaSelection << 0); - tmp142__ |= (pSrc->explicitCSIFeedbackTx << 1); - tmp142__ |= (pSrc->antennaIndicesFeedbackTx << 2); - tmp142__ |= (pSrc->explicitCSIFeedback << 3); - tmp142__ |= (pSrc->antennaIndicesFeedback << 4); - tmp142__ |= (pSrc->rxAS << 5); - tmp142__ |= (pSrc->txSoundingPPDUs << 6); - tmp142__ |= (pSrc->reserved5 << 7); + tmp144__ = 0U; + tmp144__ |= (pSrc->antennaSelection << 0); + tmp144__ |= (pSrc->explicitCSIFeedbackTx << 1); + tmp144__ |= (pSrc->antennaIndicesFeedbackTx << 2); + tmp144__ |= (pSrc->explicitCSIFeedback << 3); + tmp144__ |= (pSrc->antennaIndicesFeedback << 4); + tmp144__ |= (pSrc->rxAS << 5); + tmp144__ |= (pSrc->txSoundingPPDUs << 6); + tmp144__ |= (pSrc->reserved5 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp142__; + *pBuf = tmp144__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -22763,9 +23029,9 @@ uint32_t dot11f_pack_ie_ht_info(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp143__; - uint16_t tmp144__; - uint16_t tmp145__; + uint8_t tmp145__; + uint16_t tmp146__; + uint16_t tmp147__; nNeeded += (pSrc->num_rsvd + 22); while (pSrc->present) { if (nNeeded > nBuf) @@ -22777,44 +23043,45 @@ uint32_t dot11f_pack_ie_ht_info(tpAniSirGlobal pCtx, *pBuf = pSrc->primaryChannel; *pnConsumed += 1; pBuf += 1; - tmp143__ = 0U; - tmp143__ |= (pSrc->secondaryChannelOffset << 0); - tmp143__ |= (pSrc->recommendedTxWidthSet << 2); - tmp143__ |= (pSrc->rifsMode << 3); - tmp143__ |= (pSrc->controlledAccessOnly << 4); - tmp143__ |= (pSrc->serviceIntervalGranularity << 5); + tmp145__ = 0U; + tmp145__ |= (pSrc->secondaryChannelOffset << 0); + tmp145__ |= (pSrc->recommendedTxWidthSet << 2); + tmp145__ |= (pSrc->rifsMode << 3); + tmp145__ |= (pSrc->controlledAccessOnly << 4); + tmp145__ |= (pSrc->serviceIntervalGranularity << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp143__; + *pBuf = tmp145__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp144__ = 0U; - tmp144__ |= (pSrc->opMode << 0); - tmp144__ |= (pSrc->nonGFDevicesPresent << 2); - tmp144__ |= (pSrc->transmitBurstLimit << 3); - tmp144__ |= (pSrc->obssNonHTStaPresent << 4); - tmp144__ |= (pSrc->reserved << 5); + tmp146__ = 0U; + tmp146__ |= (pSrc->opMode << 0); + tmp146__ |= (pSrc->nonGFDevicesPresent << 2); + tmp146__ |= (pSrc->transmitBurstLimit << 3); + tmp146__ |= (pSrc->obssNonHTStaPresent << 4); + tmp146__ |= (pSrc->chan_center_freq_seg2 << 5); + tmp146__ |= (pSrc->reserved << 13); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp144__, 0); + frameshtons(pCtx, pBuf, tmp146__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp145__ = 0U; - tmp145__ |= (pSrc->basicSTBCMCS << 0); - tmp145__ |= (pSrc->dualCTSProtection << 7); - tmp145__ |= (pSrc->secondaryBeacon << 8); - tmp145__ |= (pSrc->lsigTXOPProtectionFullSupport << 9); - tmp145__ |= (pSrc->pcoActive << 10); - tmp145__ |= (pSrc->pcoPhase << 11); - tmp145__ |= (pSrc->reserved2 << 12); + tmp147__ = 0U; + tmp147__ |= (pSrc->basicSTBCMCS << 0); + tmp147__ |= (pSrc->dualCTSProtection << 7); + tmp147__ |= (pSrc->secondaryBeacon << 8); + tmp147__ |= (pSrc->lsigTXOPProtectionFullSupport << 9); + tmp147__ |= (pSrc->pcoActive << 10); + tmp147__ |= (pSrc->pcoPhase << 11); + tmp147__ |= (pSrc->reserved2 << 12); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp145__, 0); + frameshtons(pCtx, pBuf, tmp147__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -22954,9 +23221,9 @@ uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp146__; - uint8_t tmp147__; uint8_t tmp148__; + uint8_t tmp149__; + uint8_t tmp150__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_measurement_report(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -22971,15 +23238,15 @@ uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx, *pBuf = pSrc->token; *pnConsumed += 1; pBuf += 1; - tmp146__ = 0U; - tmp146__ |= (pSrc->late << 0); - tmp146__ |= (pSrc->incapable << 1); - tmp146__ |= (pSrc->refused << 2); - tmp146__ |= (pSrc->unused << 3); + tmp148__ = 0U; + tmp148__ |= (pSrc->late << 0); + tmp148__ |= (pSrc->incapable << 1); + tmp148__ |= (pSrc->refused << 2); + tmp148__ |= (pSrc->unused << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp146__; + *pBuf = tmp148__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -22998,17 +23265,17 @@ uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx, frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0); *pnConsumed += 2; pBuf += 2; - tmp147__ = 0U; - tmp147__ |= (pSrc->report.Basic.bss << 0); - tmp147__ |= (pSrc->report.Basic.ofdm_preamble << 1); - tmp147__ |= (pSrc->report.Basic.unid_signal << 2); - tmp147__ |= (pSrc->report.Basic.rader << 3); - tmp147__ |= (pSrc->report.Basic.unmeasured << 4); - tmp147__ |= (pSrc->report.Basic.unused << 5); + tmp149__ = 0U; + tmp149__ |= (pSrc->report.Basic.bss << 0); + tmp149__ |= (pSrc->report.Basic.ofdm_preamble << 1); + tmp149__ |= (pSrc->report.Basic.unid_signal << 2); + tmp149__ |= (pSrc->report.Basic.rader << 3); + tmp149__ |= (pSrc->report.Basic.unmeasured << 4); + tmp149__ |= (pSrc->report.Basic.unused << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp147__; + *pBuf = tmp149__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -23075,13 +23342,13 @@ uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx, frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0); *pnConsumed += 2; pBuf += 2; - tmp148__ = 0U; - tmp148__ |= (pSrc->report.Beacon.condensed_PHY << 0); - tmp148__ |= (pSrc->report.Beacon.reported_frame_type << 7); + tmp150__ = 0U; + tmp150__ |= (pSrc->report.Beacon.condensed_PHY << 0); + tmp150__ |= (pSrc->report.Beacon.reported_frame_type << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp148__; + *pBuf = tmp150__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -23130,7 +23397,7 @@ uint32_t dot11f_pack_ie_measurement_request(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp149__; + uint8_t tmp151__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_measurement_request(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -23145,17 +23412,17 @@ uint32_t dot11f_pack_ie_measurement_request(tpAniSirGlobal pCtx, *pBuf = pSrc->measurement_token; *pnConsumed += 1; pBuf += 1; - tmp149__ = 0U; - tmp149__ |= (pSrc->parallel << 0); - tmp149__ |= (pSrc->enable << 1); - tmp149__ |= (pSrc->request << 2); - tmp149__ |= (pSrc->report << 3); - tmp149__ |= (pSrc->durationMandatory << 4); - tmp149__ |= (pSrc->unused << 5); + tmp151__ = 0U; + tmp151__ |= (pSrc->parallel << 0); + tmp151__ |= (pSrc->enable << 1); + tmp151__ |= (pSrc->request << 2); + tmp151__ |= (pSrc->report << 3); + tmp151__ |= (pSrc->durationMandatory << 4); + tmp151__ |= (pSrc->unused << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp149__; + *pBuf = tmp151__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -23269,7 +23536,7 @@ uint32_t dot11f_pack_ie_mobility_domain(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp150__; + uint8_t tmp152__; nNeeded += 3; while (pSrc->present) { if (nNeeded > nBuf) @@ -23281,14 +23548,14 @@ uint32_t dot11f_pack_ie_mobility_domain(tpAniSirGlobal pCtx, frameshtons(pCtx, pBuf, pSrc->MDID, 0); *pnConsumed += 2; pBuf += 2; - tmp150__ = 0U; - tmp150__ |= (pSrc->overDSCap << 0); - tmp150__ |= (pSrc->resourceReqCap << 1); - tmp150__ |= (pSrc->reserved << 2); + tmp152__ = 0U; + tmp152__ |= (pSrc->overDSCap << 0); + tmp152__ |= (pSrc->resourceReqCap << 1); + tmp152__ |= (pSrc->reserved << 2); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp150__; + *pBuf = tmp152__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -23310,8 +23577,8 @@ uint32_t dot11f_pack_ie_neighbor_report(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp151__; - uint8_t tmp152__; + uint8_t tmp153__; + uint8_t tmp154__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_neighbor_report(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -23326,30 +23593,30 @@ uint32_t dot11f_pack_ie_neighbor_report(tpAniSirGlobal pCtx, DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); *pnConsumed += 6; pBuf += 6; - tmp151__ = 0U; - tmp151__ |= (pSrc->APReachability << 0); - tmp151__ |= (pSrc->Security << 2); - tmp151__ |= (pSrc->KeyScope << 3); - tmp151__ |= (pSrc->SpecMgmtCap << 4); - tmp151__ |= (pSrc->QosCap << 5); - tmp151__ |= (pSrc->apsd << 6); - tmp151__ |= (pSrc->rrm << 7); + tmp153__ = 0U; + tmp153__ |= (pSrc->APReachability << 0); + tmp153__ |= (pSrc->Security << 2); + tmp153__ |= (pSrc->KeyScope << 3); + tmp153__ |= (pSrc->SpecMgmtCap << 4); + tmp153__ |= (pSrc->QosCap << 5); + tmp153__ |= (pSrc->apsd << 6); + tmp153__ |= (pSrc->rrm << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp151__; + *pBuf = tmp153__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp152__ = 0U; - tmp152__ |= (pSrc->DelayedBA << 0); - tmp152__ |= (pSrc->ImmBA << 1); - tmp152__ |= (pSrc->MobilityDomain << 2); - tmp152__ |= (pSrc->reserved << 3); + tmp154__ = 0U; + tmp154__ |= (pSrc->DelayedBA << 0); + tmp154__ |= (pSrc->ImmBA << 1); + tmp154__ |= (pSrc->MobilityDomain << 2); + tmp154__ |= (pSrc->reserved << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp152__; + *pBuf = tmp154__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -23437,7 +23704,7 @@ uint32_t dot11f_pack_ie_operating_mode(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp153__; + uint8_t tmp155__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -23446,15 +23713,16 @@ uint32_t dot11f_pack_ie_operating_mode(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp153__ = 0U; - tmp153__ |= (pSrc->chanWidth << 0); - tmp153__ |= (pSrc->reserved << 2); - tmp153__ |= (pSrc->rxNSS << 4); - tmp153__ |= (pSrc->rxNSSType << 7); + tmp155__ = 0U; + tmp155__ |= (pSrc->chanWidth << 0); + tmp155__ |= (pSrc->vht_160_80p80_supp << 2); + tmp155__ |= (pSrc->no_ldpc << 3); + tmp155__ |= (pSrc->rxNSS << 4); + tmp155__ |= (pSrc->rxNSSType << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp153__; + *pBuf = tmp155__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -23929,7 +24197,7 @@ uint32_t dot11f_pack_ie_pu_buffer_status(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp154__; + uint8_t tmp156__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -23938,16 +24206,16 @@ uint32_t dot11f_pack_ie_pu_buffer_status(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp154__ = 0U; - tmp154__ |= (pSrc->ac_bk_traffic_aval << 0); - tmp154__ |= (pSrc->ac_be_traffic_aval << 1); - tmp154__ |= (pSrc->ac_vi_traffic_aval << 2); - tmp154__ |= (pSrc->ac_vo_traffic_aval << 3); - tmp154__ |= (pSrc->reserved << 4); + tmp156__ = 0U; + tmp156__ |= (pSrc->ac_bk_traffic_aval << 0); + tmp156__ |= (pSrc->ac_be_traffic_aval << 1); + tmp156__ |= (pSrc->ac_vi_traffic_aval << 2); + tmp156__ |= (pSrc->ac_vo_traffic_aval << 3); + tmp156__ |= (pSrc->reserved << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp154__; + *pBuf = tmp156__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -24103,7 +24371,7 @@ uint32_t dot11f_pack_ie_qos_caps_ap(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp155__; + uint8_t tmp157__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -24112,16 +24380,16 @@ uint32_t dot11f_pack_ie_qos_caps_ap(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp155__ = 0U; - tmp155__ |= (pSrc->count << 0); - tmp155__ |= (pSrc->qack << 4); - tmp155__ |= (pSrc->qreq << 5); - tmp155__ |= (pSrc->txopreq << 6); - tmp155__ |= (pSrc->reserved << 7); + tmp157__ = 0U; + tmp157__ |= (pSrc->count << 0); + tmp157__ |= (pSrc->qack << 4); + tmp157__ |= (pSrc->qreq << 5); + tmp157__ |= (pSrc->txopreq << 6); + tmp157__ |= (pSrc->reserved << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp155__; + *pBuf = tmp157__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -24143,7 +24411,7 @@ uint32_t dot11f_pack_ie_qos_caps_station(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp156__; + uint8_t tmp158__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -24152,18 +24420,18 @@ uint32_t dot11f_pack_ie_qos_caps_station(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp156__ = 0U; - tmp156__ |= (pSrc->acvo_uapsd << 0); - tmp156__ |= (pSrc->acvi_uapsd << 1); - tmp156__ |= (pSrc->acbk_uapsd << 2); - tmp156__ |= (pSrc->acbe_uapsd << 3); - tmp156__ |= (pSrc->qack << 4); - tmp156__ |= (pSrc->max_sp_length << 5); - tmp156__ |= (pSrc->more_data_ack << 7); + tmp158__ = 0U; + tmp158__ |= (pSrc->acvo_uapsd << 0); + tmp158__ |= (pSrc->acvi_uapsd << 1); + tmp158__ |= (pSrc->acbk_uapsd << 2); + tmp158__ |= (pSrc->acbe_uapsd << 3); + tmp158__ |= (pSrc->qack << 4); + tmp158__ |= (pSrc->max_sp_length << 5); + tmp158__ |= (pSrc->more_data_ack << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp156__; + *pBuf = tmp158__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -24361,7 +24629,11 @@ uint32_t dot11f_pack_ie_rsn(tpAniSirGlobal pCtx, *pnConsumed += 2; pBuf += 2; } else { - break; + if (pSrc->gp_mgmt_cipher_suite_present) { + frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0); + *pnConsumed += 2; + pBuf += 2; + } } DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->pmkid), (pSrc->pmkid_count * 16)); *pnConsumed += (pSrc->pmkid_count * 16); @@ -24804,7 +25076,7 @@ uint32_t dot11f_pack_ie_wapi(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp157__; + uint16_t tmp159__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_iewapi(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -24834,13 +25106,13 @@ uint32_t dot11f_pack_ie_wapi(tpAniSirGlobal pCtx, DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4); *pnConsumed += 4; pBuf += 4; - tmp157__ = 0U; - tmp157__ |= (pSrc->preauth << 0); - tmp157__ |= (pSrc->reserved << 1); + tmp159__ = 0U; + tmp159__ |= (pSrc->preauth << 0); + tmp159__ |= (pSrc->reserved << 1); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp157__, 0); + frameshtons(pCtx, pBuf, tmp159__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -24980,7 +25252,7 @@ uint32_t dot11f_pack_ie_wmm_caps(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp158__; + uint8_t tmp160__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -25002,16 +25274,16 @@ uint32_t dot11f_pack_ie_wmm_caps(tpAniSirGlobal pCtx, *pBuf = pSrc->version; *pnConsumed += 1; pBuf += 1; - tmp158__ = 0U; - tmp158__ |= (pSrc->reserved << 0); - tmp158__ |= (pSrc->qack << 4); - tmp158__ |= (pSrc->queue_request << 5); - tmp158__ |= (pSrc->txop_request << 6); - tmp158__ |= (pSrc->more_ack << 7); + tmp160__ = 0U; + tmp160__ |= (pSrc->reserved << 0); + tmp160__ |= (pSrc->qack << 4); + tmp160__ |= (pSrc->queue_request << 5); + tmp160__ |= (pSrc->txop_request << 6); + tmp160__ |= (pSrc->more_ack << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp158__; + *pBuf = tmp160__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -25033,7 +25305,7 @@ uint32_t dot11f_pack_ie_wmm_info_ap(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp159__; + uint8_t tmp161__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -25055,14 +25327,14 @@ uint32_t dot11f_pack_ie_wmm_info_ap(tpAniSirGlobal pCtx, *pBuf = pSrc->version; *pnConsumed += 1; pBuf += 1; - tmp159__ = 0U; - tmp159__ |= (pSrc->param_set_count << 0); - tmp159__ |= (pSrc->reserved << 4); - tmp159__ |= (pSrc->uapsd << 7); + tmp161__ = 0U; + tmp161__ |= (pSrc->param_set_count << 0); + tmp161__ |= (pSrc->reserved << 4); + tmp161__ |= (pSrc->uapsd << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp159__; + *pBuf = tmp161__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -25084,7 +25356,7 @@ uint32_t dot11f_pack_ie_wmm_info_station(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp160__; + uint8_t tmp162__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -25106,18 +25378,18 @@ uint32_t dot11f_pack_ie_wmm_info_station(tpAniSirGlobal pCtx, *pBuf = pSrc->version; *pnConsumed += 1; pBuf += 1; - tmp160__ = 0U; - tmp160__ |= (pSrc->acvo_uapsd << 0); - tmp160__ |= (pSrc->acvi_uapsd << 1); - tmp160__ |= (pSrc->acbk_uapsd << 2); - tmp160__ |= (pSrc->acbe_uapsd << 3); - tmp160__ |= (pSrc->reserved1 << 4); - tmp160__ |= (pSrc->max_sp_length << 5); - tmp160__ |= (pSrc->reserved2 << 7); + tmp162__ = 0U; + tmp162__ |= (pSrc->acvo_uapsd << 0); + tmp162__ |= (pSrc->acvi_uapsd << 1); + tmp162__ |= (pSrc->acbk_uapsd << 2); + tmp162__ |= (pSrc->acbe_uapsd << 3); + tmp162__ |= (pSrc->reserved1 << 4); + tmp162__ |= (pSrc->max_sp_length << 5); + tmp162__ |= (pSrc->reserved2 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp160__; + *pBuf = tmp162__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -25139,14 +25411,14 @@ uint32_t dot11f_pack_ie_wmm_params(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp161__; - uint8_t tmp162__; uint8_t tmp163__; uint8_t tmp164__; uint8_t tmp165__; uint8_t tmp166__; uint8_t tmp167__; uint8_t tmp168__; + uint8_t tmp169__; + uint8_t tmp170__; nNeeded += 19; while (pSrc->present) { if (nNeeded > nBuf) @@ -25174,100 +25446,100 @@ uint32_t dot11f_pack_ie_wmm_params(tpAniSirGlobal pCtx, *pBuf = pSrc->reserved2; *pnConsumed += 1; pBuf += 1; - tmp161__ = 0U; - tmp161__ |= (pSrc->acbe_aifsn << 0); - tmp161__ |= (pSrc->acbe_acm << 4); - tmp161__ |= (pSrc->acbe_aci << 5); - tmp161__ |= (pSrc->unused1 << 7); + tmp163__ = 0U; + tmp163__ |= (pSrc->acbe_aifsn << 0); + tmp163__ |= (pSrc->acbe_acm << 4); + tmp163__ |= (pSrc->acbe_aci << 5); + tmp163__ |= (pSrc->unused1 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp161__; + *pBuf = tmp163__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp162__ = 0U; - tmp162__ |= (pSrc->acbe_acwmin << 0); - tmp162__ |= (pSrc->acbe_acwmax << 4); + tmp164__ = 0U; + tmp164__ |= (pSrc->acbe_acwmin << 0); + tmp164__ |= (pSrc->acbe_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp162__; + *pBuf = tmp164__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp163__ = 0U; - tmp163__ |= (pSrc->acbk_aifsn << 0); - tmp163__ |= (pSrc->acbk_acm << 4); - tmp163__ |= (pSrc->acbk_aci << 5); - tmp163__ |= (pSrc->unused2 << 7); + tmp165__ = 0U; + tmp165__ |= (pSrc->acbk_aifsn << 0); + tmp165__ |= (pSrc->acbk_acm << 4); + tmp165__ |= (pSrc->acbk_aci << 5); + tmp165__ |= (pSrc->unused2 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp163__; + *pBuf = tmp165__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp164__ = 0U; - tmp164__ |= (pSrc->acbk_acwmin << 0); - tmp164__ |= (pSrc->acbk_acwmax << 4); + tmp166__ = 0U; + tmp166__ |= (pSrc->acbk_acwmin << 0); + tmp166__ |= (pSrc->acbk_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp164__; + *pBuf = tmp166__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp165__ = 0U; - tmp165__ |= (pSrc->acvi_aifsn << 0); - tmp165__ |= (pSrc->acvi_acm << 4); - tmp165__ |= (pSrc->acvi_aci << 5); - tmp165__ |= (pSrc->unused3 << 7); + tmp167__ = 0U; + tmp167__ |= (pSrc->acvi_aifsn << 0); + tmp167__ |= (pSrc->acvi_acm << 4); + tmp167__ |= (pSrc->acvi_aci << 5); + tmp167__ |= (pSrc->unused3 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp165__; + *pBuf = tmp167__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp166__ = 0U; - tmp166__ |= (pSrc->acvi_acwmin << 0); - tmp166__ |= (pSrc->acvi_acwmax << 4); + tmp168__ = 0U; + tmp168__ |= (pSrc->acvi_acwmin << 0); + tmp168__ |= (pSrc->acvi_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp166__; + *pBuf = tmp168__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); *pnConsumed += 2; pBuf += 2; - tmp167__ = 0U; - tmp167__ |= (pSrc->acvo_aifsn << 0); - tmp167__ |= (pSrc->acvo_acm << 4); - tmp167__ |= (pSrc->acvo_aci << 5); - tmp167__ |= (pSrc->unused4 << 7); + tmp169__ = 0U; + tmp169__ |= (pSrc->acvo_aifsn << 0); + tmp169__ |= (pSrc->acvo_acm << 4); + tmp169__ |= (pSrc->acvo_aci << 5); + tmp169__ |= (pSrc->unused4 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp167__; + *pBuf = tmp169__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp168__ = 0U; - tmp168__ |= (pSrc->acvo_acwmin << 0); - tmp168__ |= (pSrc->acvo_acwmax << 4); + tmp170__ = 0U; + tmp170__ |= (pSrc->acvo_acwmin << 0); + tmp170__ |= (pSrc->acvo_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp168__; + *pBuf = tmp170__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -25824,7 +26096,7 @@ uint32_t dot11f_pack_ie_addba_extn_element(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp169__; + uint8_t tmp171__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -25833,14 +26105,14 @@ uint32_t dot11f_pack_ie_addba_extn_element(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp169__ = 0U; - tmp169__ |= (pSrc->no_fragmentation << 0); - tmp169__ |= (pSrc->he_frag_operation << 1); - tmp169__ |= (pSrc->reserved << 3); + tmp171__ = 0U; + tmp171__ |= (pSrc->no_fragmentation << 0); + tmp171__ |= (pSrc->he_frag_operation << 1); + tmp171__ |= (pSrc->reserved << 3); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp169__; + *pBuf = tmp171__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -25862,7 +26134,7 @@ uint32_t dot11f_pack_ie_bss_color_change(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp170__; + uint8_t tmp172__; nNeeded += 2; while (pSrc->present) { if (nNeeded > nBuf) @@ -25876,13 +26148,13 @@ uint32_t dot11f_pack_ie_bss_color_change(tpAniSirGlobal pCtx, *pBuf = pSrc->countdown; *pnConsumed += 1; pBuf += 1; - tmp170__ = 0U; - tmp170__ |= (pSrc->new_color << 0); - tmp170__ |= (pSrc->reserved << 6); + tmp172__ = 0U; + tmp172__ |= (pSrc->new_color << 0); + tmp172__ |= (pSrc->reserved << 6); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp170__; + *pBuf = tmp172__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -26075,7 +26347,7 @@ uint32_t dot11f_pack_ie_fils_indication(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp171__; + uint16_t tmp173__; nNeeded += (pSrc->num_variable_data + 2); while (pSrc->present) { if (nNeeded > nBuf) @@ -26084,20 +26356,20 @@ uint32_t dot11f_pack_ie_fils_indication(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp171__ = 0U; - tmp171__ |= (pSrc->public_key_identifiers_cnt << 0); - tmp171__ |= (pSrc->realm_identifiers_cnt << 3); - tmp171__ |= (pSrc->is_ip_config_supported << 6); - tmp171__ |= (pSrc->is_cache_id_present << 7); - tmp171__ |= (pSrc->is_hessid_present << 8); - tmp171__ |= (pSrc->is_fils_sk_auth_supported << 9); - tmp171__ |= (pSrc->is_fils_sk_auth_pfs_supported << 10); - tmp171__ |= (pSrc->is_pk_auth_supported << 11); - tmp171__ |= (pSrc->reserved << 12); + tmp173__ = 0U; + tmp173__ |= (pSrc->public_key_identifiers_cnt << 0); + tmp173__ |= (pSrc->realm_identifiers_cnt << 3); + tmp173__ |= (pSrc->is_ip_config_supported << 6); + tmp173__ |= (pSrc->is_cache_id_present << 7); + tmp173__ |= (pSrc->is_hessid_present << 8); + tmp173__ |= (pSrc->is_fils_sk_auth_supported << 9); + tmp173__ |= (pSrc->is_fils_sk_auth_pfs_supported << 10); + tmp173__ |= (pSrc->is_pk_auth_supported << 11); + tmp173__ |= (pSrc->reserved << 12); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp171__, 0); + frameshtons(pCtx, pBuf, tmp173__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -26334,6 +26606,51 @@ uint32_t dot11f_pack_ie_fragment_ie(tpAniSirGlobal pCtx, return DOT11F_PARSE_SUCCESS; } /* End dot11f_pack_ie_fragment_ie. */ +uint32_t dot11f_pack_ie_he_6ghz_band_cap(tpAniSirGlobal pCtx, + tDot11fIEhe_6ghz_band_cap *pSrc, + uint8_t *pBuf, + uint32_t nBuf, + uint32_t *pnConsumed) +{ + uint8_t *pIeLen = 0; + uint32_t nConsumedOnEntry = *pnConsumed; + uint32_t nNeeded = 0U; + uint16_t tmp174__; + nNeeded += 2; + while (pSrc->present) { + if (nNeeded > nBuf) + return DOT11F_BUFFER_OVERFLOW; + *pBuf = 255; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 59; + ++pBuf; ++(*pnConsumed); + tmp174__ = 0U; + tmp174__ |= (pSrc->min_mpdu_start_spacing << 0); + tmp174__ |= (pSrc->max_ampdu_len_exp << 3); + tmp174__ |= (pSrc->max_mpdu_len << 6); + tmp174__ |= (pSrc->sm_pow_save << 9); + tmp174__ |= (pSrc->rd_responder << 11); + tmp174__ |= (pSrc->rx_ant_pattern_consistency << 12); + tmp174__ |= (pSrc->tx_ant_pattern_consistency << 13); + tmp174__ |= (pSrc->reserved << 14); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + + frameshtons(pCtx, pBuf, tmp174__, 0); + *pnConsumed += 2; + /* fieldsEndFlag = 1 */ + nBuf -= 2 ; + break; + } + (void)pCtx; + if (pIeLen) { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11f_pack_ie_he_6ghz_band_cap. */ + uint32_t dot11f_pack_ie_he_cap(tpAniSirGlobal pCtx, tDot11fIEhe_cap *pSrc, uint8_t *pBuf, @@ -26343,11 +26660,11 @@ uint32_t dot11f_pack_ie_he_cap(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint32_t tmp172__; - uint16_t tmp173__; - uint32_t tmp174__; uint32_t tmp175__; uint16_t tmp176__; + uint32_t tmp177__; + uint32_t tmp178__; + uint16_t tmp179__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_he_cap(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -26361,136 +26678,136 @@ uint32_t dot11f_pack_ie_he_cap(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); *pBuf = 35; ++pBuf; ++(*pnConsumed); - tmp172__ = 0U; - tmp172__ |= (pSrc->htc_he << 0); - tmp172__ |= (pSrc->twt_request << 1); - tmp172__ |= (pSrc->twt_responder << 2); - tmp172__ |= (pSrc->fragmentation << 3); - tmp172__ |= (pSrc->max_num_frag_msdu_amsdu_exp << 5); - tmp172__ |= (pSrc->min_frag_size << 8); - tmp172__ |= (pSrc->trigger_frm_mac_pad << 10); - tmp172__ |= (pSrc->multi_tid_aggr_rx_supp << 12); - tmp172__ |= (pSrc->he_link_adaptation << 15); - tmp172__ |= (pSrc->all_ack << 17); - tmp172__ |= (pSrc->trigd_rsp_sched << 18); - tmp172__ |= (pSrc->a_bsr << 19); - tmp172__ |= (pSrc->broadcast_twt << 20); - tmp172__ |= (pSrc->ba_32bit_bitmap << 21); - tmp172__ |= (pSrc->mu_cascade << 22); - tmp172__ |= (pSrc->ack_enabled_multitid << 23); - tmp172__ |= (pSrc->reserved << 24); - tmp172__ |= (pSrc->omi_a_ctrl << 25); - tmp172__ |= (pSrc->ofdma_ra << 26); - tmp172__ |= (pSrc->max_ampdu_len_exp_ext << 27); - tmp172__ |= (pSrc->amsdu_frag << 29); - tmp172__ |= (pSrc->flex_twt_sched << 30); - tmp172__ |= (pSrc->rx_ctrl_frame << 31); + tmp175__ = 0U; + tmp175__ |= (pSrc->htc_he << 0); + tmp175__ |= (pSrc->twt_request << 1); + tmp175__ |= (pSrc->twt_responder << 2); + tmp175__ |= (pSrc->fragmentation << 3); + tmp175__ |= (pSrc->max_num_frag_msdu_amsdu_exp << 5); + tmp175__ |= (pSrc->min_frag_size << 8); + tmp175__ |= (pSrc->trigger_frm_mac_pad << 10); + tmp175__ |= (pSrc->multi_tid_aggr_rx_supp << 12); + tmp175__ |= (pSrc->he_link_adaptation << 15); + tmp175__ |= (pSrc->all_ack << 17); + tmp175__ |= (pSrc->trigd_rsp_sched << 18); + tmp175__ |= (pSrc->a_bsr << 19); + tmp175__ |= (pSrc->broadcast_twt << 20); + tmp175__ |= (pSrc->ba_32bit_bitmap << 21); + tmp175__ |= (pSrc->mu_cascade << 22); + tmp175__ |= (pSrc->ack_enabled_multitid << 23); + tmp175__ |= (pSrc->reserved << 24); + tmp175__ |= (pSrc->omi_a_ctrl << 25); + tmp175__ |= (pSrc->ofdma_ra << 26); + tmp175__ |= (pSrc->max_ampdu_len_exp_ext << 27); + tmp175__ |= (pSrc->amsdu_frag << 29); + tmp175__ |= (pSrc->flex_twt_sched << 30); + tmp175__ |= (pSrc->rx_ctrl_frame << 31); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; - frameshtonl(pCtx, pBuf, tmp172__, 0); + frameshtonl(pCtx, pBuf, tmp175__, 0); *pnConsumed += 4; pBuf += 4; nBuf -= 4 ; - tmp173__ = 0U; - tmp173__ |= (pSrc->bsrp_ampdu_aggr << 0); - tmp173__ |= (pSrc->qtp << 1); - tmp173__ |= (pSrc->a_bqr << 2); - tmp173__ |= (pSrc->spatial_reuse_param_rspder << 3); - tmp173__ |= (pSrc->ndp_feedback_supp << 4); - tmp173__ |= (pSrc->ops_supp << 5); - tmp173__ |= (pSrc->amsdu_in_ampdu << 6); - tmp173__ |= (pSrc->multi_tid_aggr_tx_supp << 7); - tmp173__ |= (pSrc->he_sub_ch_sel_tx_supp << 10); - tmp173__ |= (pSrc->ul_2x996_tone_ru_supp << 11); - tmp173__ |= (pSrc->om_ctrl_ul_mu_data_dis_rx << 12); - tmp173__ |= (pSrc->he_dynamic_smps << 13); - tmp173__ |= (pSrc->punctured_sounding_supp << 14); - tmp173__ |= (pSrc->ht_vht_trg_frm_rx_supp << 15); + tmp176__ = 0U; + tmp176__ |= (pSrc->bsrp_ampdu_aggr << 0); + tmp176__ |= (pSrc->qtp << 1); + tmp176__ |= (pSrc->a_bqr << 2); + tmp176__ |= (pSrc->spatial_reuse_param_rspder << 3); + tmp176__ |= (pSrc->ndp_feedback_supp << 4); + tmp176__ |= (pSrc->ops_supp << 5); + tmp176__ |= (pSrc->amsdu_in_ampdu << 6); + tmp176__ |= (pSrc->multi_tid_aggr_tx_supp << 7); + tmp176__ |= (pSrc->he_sub_ch_sel_tx_supp << 10); + tmp176__ |= (pSrc->ul_2x996_tone_ru_supp << 11); + tmp176__ |= (pSrc->om_ctrl_ul_mu_data_dis_rx << 12); + tmp176__ |= (pSrc->he_dynamic_smps << 13); + tmp176__ |= (pSrc->punctured_sounding_supp << 14); + tmp176__ |= (pSrc->ht_vht_trg_frm_rx_supp << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp173__, 0); + frameshtons(pCtx, pBuf, tmp176__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp174__ = 0U; - tmp174__ |= (pSrc->reserved2 << 0); - tmp174__ |= (pSrc->chan_width_0 << 1); - tmp174__ |= (pSrc->chan_width_1 << 2); - tmp174__ |= (pSrc->chan_width_2 << 3); - tmp174__ |= (pSrc->chan_width_3 << 4); - tmp174__ |= (pSrc->chan_width_4 << 5); - tmp174__ |= (pSrc->chan_width_5 << 6); - tmp174__ |= (pSrc->chan_width_6 << 7); - tmp174__ |= (pSrc->rx_pream_puncturing << 8); - tmp174__ |= (pSrc->device_class << 12); - tmp174__ |= (pSrc->ldpc_coding << 13); - tmp174__ |= (pSrc->he_1x_ltf_800_gi_ppdu << 14); - tmp174__ |= (pSrc->midamble_tx_rx_max_nsts << 15); - tmp174__ |= (pSrc->he_4x_ltf_3200_gi_ndp << 17); - tmp174__ |= (pSrc->tb_ppdu_tx_stbc_lt_80mhz << 18); - tmp174__ |= (pSrc->rx_stbc_lt_80mhz << 19); - tmp174__ |= (pSrc->doppler << 20); - tmp174__ |= (pSrc->ul_mu << 22); - tmp174__ |= (pSrc->dcm_enc_tx << 24); - tmp174__ |= (pSrc->dcm_enc_rx << 27); - tmp174__ |= (pSrc->ul_he_mu << 30); - tmp174__ |= (pSrc->su_beamformer << 31); + tmp177__ = 0U; + tmp177__ |= (pSrc->reserved2 << 0); + tmp177__ |= (pSrc->chan_width_0 << 1); + tmp177__ |= (pSrc->chan_width_1 << 2); + tmp177__ |= (pSrc->chan_width_2 << 3); + tmp177__ |= (pSrc->chan_width_3 << 4); + tmp177__ |= (pSrc->chan_width_4 << 5); + tmp177__ |= (pSrc->chan_width_5 << 6); + tmp177__ |= (pSrc->chan_width_6 << 7); + tmp177__ |= (pSrc->rx_pream_puncturing << 8); + tmp177__ |= (pSrc->device_class << 12); + tmp177__ |= (pSrc->ldpc_coding << 13); + tmp177__ |= (pSrc->he_1x_ltf_800_gi_ppdu << 14); + tmp177__ |= (pSrc->midamble_tx_rx_max_nsts << 15); + tmp177__ |= (pSrc->he_4x_ltf_3200_gi_ndp << 17); + tmp177__ |= (pSrc->tb_ppdu_tx_stbc_lt_80mhz << 18); + tmp177__ |= (pSrc->rx_stbc_lt_80mhz << 19); + tmp177__ |= (pSrc->doppler << 20); + tmp177__ |= (pSrc->ul_mu << 22); + tmp177__ |= (pSrc->dcm_enc_tx << 24); + tmp177__ |= (pSrc->dcm_enc_rx << 27); + tmp177__ |= (pSrc->ul_he_mu << 30); + tmp177__ |= (pSrc->su_beamformer << 31); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; - frameshtonl(pCtx, pBuf, tmp174__, 0); + frameshtonl(pCtx, pBuf, tmp177__, 0); *pnConsumed += 4; pBuf += 4; nBuf -= 4 ; - tmp175__ = 0U; - tmp175__ |= (pSrc->su_beamformee << 0); - tmp175__ |= (pSrc->mu_beamformer << 1); - tmp175__ |= (pSrc->bfee_sts_lt_80 << 2); - tmp175__ |= (pSrc->bfee_sts_gt_80 << 5); - tmp175__ |= (pSrc->num_sounding_lt_80 << 8); - tmp175__ |= (pSrc->num_sounding_gt_80 << 11); - tmp175__ |= (pSrc->su_feedback_tone16 << 14); - tmp175__ |= (pSrc->mu_feedback_tone16 << 15); - tmp175__ |= (pSrc->codebook_su << 16); - tmp175__ |= (pSrc->codebook_mu << 17); - tmp175__ |= (pSrc->beamforming_feedback << 18); - tmp175__ |= (pSrc->he_er_su_ppdu << 21); - tmp175__ |= (pSrc->dl_mu_mimo_part_bw << 22); - tmp175__ |= (pSrc->ppet_present << 23); - tmp175__ |= (pSrc->srp << 24); - tmp175__ |= (pSrc->power_boost << 25); - tmp175__ |= (pSrc->he_ltf_800_gi_4x << 26); - tmp175__ |= (pSrc->max_nc << 27); - tmp175__ |= (pSrc->tb_ppdu_tx_stbc_gt_80mhz << 30); - tmp175__ |= (pSrc->rx_stbc_gt_80mhz << 31); + tmp178__ = 0U; + tmp178__ |= (pSrc->su_beamformee << 0); + tmp178__ |= (pSrc->mu_beamformer << 1); + tmp178__ |= (pSrc->bfee_sts_lt_80 << 2); + tmp178__ |= (pSrc->bfee_sts_gt_80 << 5); + tmp178__ |= (pSrc->num_sounding_lt_80 << 8); + tmp178__ |= (pSrc->num_sounding_gt_80 << 11); + tmp178__ |= (pSrc->su_feedback_tone16 << 14); + tmp178__ |= (pSrc->mu_feedback_tone16 << 15); + tmp178__ |= (pSrc->codebook_su << 16); + tmp178__ |= (pSrc->codebook_mu << 17); + tmp178__ |= (pSrc->beamforming_feedback << 18); + tmp178__ |= (pSrc->he_er_su_ppdu << 21); + tmp178__ |= (pSrc->dl_mu_mimo_part_bw << 22); + tmp178__ |= (pSrc->ppet_present << 23); + tmp178__ |= (pSrc->srp << 24); + tmp178__ |= (pSrc->power_boost << 25); + tmp178__ |= (pSrc->he_ltf_800_gi_4x << 26); + tmp178__ |= (pSrc->max_nc << 27); + tmp178__ |= (pSrc->tb_ppdu_tx_stbc_gt_80mhz << 30); + tmp178__ |= (pSrc->rx_stbc_gt_80mhz << 31); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; - frameshtonl(pCtx, pBuf, tmp175__, 0); + frameshtonl(pCtx, pBuf, tmp178__, 0); *pnConsumed += 4; pBuf += 4; nBuf -= 4 ; - tmp176__ = 0U; - tmp176__ |= (pSrc->er_he_ltf_800_gi_4x << 0); - tmp176__ |= (pSrc->he_ppdu_20_in_40Mhz_2G << 1); - tmp176__ |= (pSrc->he_ppdu_20_in_160_80p80Mhz << 2); - tmp176__ |= (pSrc->he_ppdu_80_in_160_80p80Mhz << 3); - tmp176__ |= (pSrc->er_1x_he_ltf_gi << 4); - tmp176__ |= (pSrc->midamble_tx_rx_1x_he_ltf << 5); - tmp176__ |= (pSrc->dcm_max_bw << 6); - tmp176__ |= (pSrc->longer_than_16_he_sigb_ofdm_sym << 8); - tmp176__ |= (pSrc->non_trig_cqi_feedback << 9); - tmp176__ |= (pSrc->tx_1024_qam_lt_242_tone_ru << 10); - tmp176__ |= (pSrc->rx_1024_qam_lt_242_tone_ru << 11); - tmp176__ |= (pSrc->rx_full_bw_su_he_mu_compress_sigb << 12); - tmp176__ |= (pSrc->rx_full_bw_su_he_mu_non_cmpr_sigb << 13); - tmp176__ |= (pSrc->reserved3 << 14); + tmp179__ = 0U; + tmp179__ |= (pSrc->er_he_ltf_800_gi_4x << 0); + tmp179__ |= (pSrc->he_ppdu_20_in_40Mhz_2G << 1); + tmp179__ |= (pSrc->he_ppdu_20_in_160_80p80Mhz << 2); + tmp179__ |= (pSrc->he_ppdu_80_in_160_80p80Mhz << 3); + tmp179__ |= (pSrc->er_1x_he_ltf_gi << 4); + tmp179__ |= (pSrc->midamble_tx_rx_1x_he_ltf << 5); + tmp179__ |= (pSrc->dcm_max_bw << 6); + tmp179__ |= (pSrc->longer_than_16_he_sigb_ofdm_sym << 8); + tmp179__ |= (pSrc->non_trig_cqi_feedback << 9); + tmp179__ |= (pSrc->tx_1024_qam_lt_242_tone_ru << 10); + tmp179__ |= (pSrc->rx_1024_qam_lt_242_tone_ru << 11); + tmp179__ |= (pSrc->rx_full_bw_su_he_mu_compress_sigb << 12); + tmp179__ |= (pSrc->rx_full_bw_su_he_mu_non_cmpr_sigb << 13); + tmp179__ |= (pSrc->reserved3 << 14); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp176__, 0); + frameshtons(pCtx, pBuf, tmp179__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; @@ -26544,9 +26861,10 @@ uint32_t dot11f_pack_ie_he_op(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint16_t tmp177__; - uint8_t tmp178__; - uint8_t tmp179__; + uint16_t tmp180__; + uint8_t tmp181__; + uint8_t tmp182__; + uint8_t tmp183__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_he_op(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -26560,37 +26878,38 @@ uint32_t dot11f_pack_ie_he_op(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); *pBuf = 36; ++pBuf; ++(*pnConsumed); - tmp177__ = 0U; - tmp177__ |= (pSrc->default_pe << 0); - tmp177__ |= (pSrc->twt_required << 3); - tmp177__ |= (pSrc->txop_rts_threshold << 4); - tmp177__ |= (pSrc->vht_oper_present << 14); - tmp177__ |= (pSrc->co_located_bss << 15); + tmp180__ = 0U; + tmp180__ |= (pSrc->default_pe << 0); + tmp180__ |= (pSrc->twt_required << 3); + tmp180__ |= (pSrc->txop_rts_threshold << 4); + tmp180__ |= (pSrc->vht_oper_present << 14); + tmp180__ |= (pSrc->co_located_bss << 15); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; - frameshtons(pCtx, pBuf, tmp177__, 0); + frameshtons(pCtx, pBuf, tmp180__, 0); *pnConsumed += 2; pBuf += 2; nBuf -= 2 ; - tmp178__ = 0U; - tmp178__ |= (pSrc->er_su_disable << 0); - tmp178__ |= (pSrc->reserved2 << 1); + tmp181__ = 0U; + tmp181__ |= (pSrc->er_su_disable << 0); + tmp181__ |= (pSrc->oper_info_6g_present << 1); + tmp181__ |= (pSrc->reserved2 << 2); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp178__; + *pBuf = tmp181__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp179__ = 0U; - tmp179__ |= (pSrc->bss_color << 0); - tmp179__ |= (pSrc->partial_bss_col << 6); - tmp179__ |= (pSrc->bss_col_disabled << 7); + tmp182__ = 0U; + tmp182__ |= (pSrc->bss_color << 0); + tmp182__ |= (pSrc->partial_bss_col << 6); + tmp182__ |= (pSrc->bss_col_disabled << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp179__; + *pBuf = tmp182__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -26611,19 +26930,44 @@ uint32_t dot11f_pack_ie_he_op(tpAniSirGlobal pCtx, pBuf += 1; break; } - } else { - break; } if (pSrc->co_located_bss) { switch (pSrc->co_located_bss) { case 1: *pBuf = pSrc->maxbssid_ind.info.data; *pnConsumed += 1; + pBuf += 1; + break; + } + } + if (pSrc->oper_info_6g_present) { + switch (pSrc->oper_info_6g_present) { + case 1: + *pBuf = pSrc->oper_info_6g.info.primary_ch; + *pnConsumed += 1; + pBuf += 1; + tmp183__ = 0U; + tmp183__ |= (pSrc->oper_info_6g.info.ch_width << 0); + tmp183__ |= (pSrc->oper_info_6g.info.dup_bcon << 2); + tmp183__ |= (pSrc->oper_info_6g.info.reserved << 3); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + + *pBuf = tmp183__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->oper_info_6g.info.center_freq_seg0; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->oper_info_6g.info.center_freq_seg1; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->oper_info_6g.info.min_rate; + *pnConsumed += 1; /* fieldsEndFlag = 1 */ break; } - } else { - break; } break; } @@ -26643,7 +26987,7 @@ uint32_t dot11f_pack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp180__; + uint8_t tmp184__; uint32_t status = DOT11F_PARSE_SUCCESS; status = dot11f_get_packed_ie_hs20vendor_ie(pCtx, pSrc, &nNeeded); if (!DOT11F_SUCCEEDED(status)) @@ -26663,15 +27007,15 @@ uint32_t dot11f_pack_ie_hs20vendor_ie(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); *pBuf = 0x10; ++pBuf; ++(*pnConsumed); - tmp180__ = 0U; - tmp180__ |= (pSrc->dgaf_dis << 0); - tmp180__ |= (pSrc->hs_id_present << 1); - tmp180__ |= (pSrc->reserved << 3); - tmp180__ |= (pSrc->release_num << 4); + tmp184__ = 0U; + tmp184__ |= (pSrc->dgaf_dis << 0); + tmp184__ |= (pSrc->hs_id_present << 1); + tmp184__ |= (pSrc->reserved << 3); + tmp184__ |= (pSrc->release_num << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp180__; + *pBuf = tmp184__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -26709,7 +27053,7 @@ uint32_t dot11f_pack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp181__; + uint8_t tmp185__; nNeeded += 1; while (pSrc->present) { if (nNeeded > nBuf) @@ -26718,17 +27062,17 @@ uint32_t dot11f_pack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); pIeLen = pBuf; ++pBuf; ++(*pnConsumed); - tmp181__ = 0U; - tmp181__ |= (pSrc->info_request << 0); - tmp181__ |= (pSrc->forty_mhz_intolerant << 1); - tmp181__ |= (pSrc->twenty_mhz_bsswidth_req << 2); - tmp181__ |= (pSrc->obss_scan_exemption_req << 3); - tmp181__ |= (pSrc->obss_scan_exemption_grant << 4); - tmp181__ |= (pSrc->unused << 5); + tmp185__ = 0U; + tmp185__ |= (pSrc->info_request << 0); + tmp185__ |= (pSrc->forty_mhz_intolerant << 1); + tmp185__ |= (pSrc->twenty_mhz_bsswidth_req << 2); + tmp185__ |= (pSrc->obss_scan_exemption_req << 3); + tmp185__ |= (pSrc->obss_scan_exemption_grant << 4); + tmp185__ |= (pSrc->unused << 5); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp181__; + *pBuf = tmp185__; *pnConsumed += 1; /* fieldsEndFlag = 1 */ nBuf -= 1 ; @@ -26782,14 +27126,14 @@ uint32_t dot11f_pack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, uint8_t *pIeLen = 0; uint32_t nConsumedOnEntry = *pnConsumed; uint32_t nNeeded = 0U; - uint8_t tmp182__; - uint8_t tmp183__; - uint8_t tmp184__; - uint8_t tmp185__; uint8_t tmp186__; uint8_t tmp187__; uint8_t tmp188__; uint8_t tmp189__; + uint8_t tmp190__; + uint8_t tmp191__; + uint8_t tmp192__; + uint8_t tmp193__; nNeeded += 13; while (pSrc->present) { if (nNeeded > nBuf) @@ -26803,100 +27147,100 @@ uint32_t dot11f_pack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, *pBuf = pSrc->qos; *pnConsumed += 1; pBuf += 1; - tmp182__ = 0U; - tmp182__ |= (pSrc->acbe_aifsn << 0); - tmp182__ |= (pSrc->acbe_acm << 4); - tmp182__ |= (pSrc->acbe_aci << 5); - tmp182__ |= (pSrc->unused1 << 7); + tmp186__ = 0U; + tmp186__ |= (pSrc->acbe_aifsn << 0); + tmp186__ |= (pSrc->acbe_acm << 4); + tmp186__ |= (pSrc->acbe_aci << 5); + tmp186__ |= (pSrc->unused1 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp182__; + *pBuf = tmp186__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp183__ = 0U; - tmp183__ |= (pSrc->acbe_acwmin << 0); - tmp183__ |= (pSrc->acbe_acwmax << 4); + tmp187__ = 0U; + tmp187__ |= (pSrc->acbe_acwmin << 0); + tmp187__ |= (pSrc->acbe_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp183__; + *pBuf = tmp187__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; *pBuf = pSrc->acbe_muedca_timer; *pnConsumed += 1; pBuf += 1; - tmp184__ = 0U; - tmp184__ |= (pSrc->acbk_aifsn << 0); - tmp184__ |= (pSrc->acbk_acm << 4); - tmp184__ |= (pSrc->acbk_aci << 5); - tmp184__ |= (pSrc->unused2 << 7); + tmp188__ = 0U; + tmp188__ |= (pSrc->acbk_aifsn << 0); + tmp188__ |= (pSrc->acbk_acm << 4); + tmp188__ |= (pSrc->acbk_aci << 5); + tmp188__ |= (pSrc->unused2 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp184__; + *pBuf = tmp188__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp185__ = 0U; - tmp185__ |= (pSrc->acbk_acwmin << 0); - tmp185__ |= (pSrc->acbk_acwmax << 4); + tmp189__ = 0U; + tmp189__ |= (pSrc->acbk_acwmin << 0); + tmp189__ |= (pSrc->acbk_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp185__; + *pBuf = tmp189__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; *pBuf = pSrc->acbk_muedca_timer; *pnConsumed += 1; pBuf += 1; - tmp186__ = 0U; - tmp186__ |= (pSrc->acvi_aifsn << 0); - tmp186__ |= (pSrc->acvi_acm << 4); - tmp186__ |= (pSrc->acvi_aci << 5); - tmp186__ |= (pSrc->unused3 << 7); + tmp190__ = 0U; + tmp190__ |= (pSrc->acvi_aifsn << 0); + tmp190__ |= (pSrc->acvi_acm << 4); + tmp190__ |= (pSrc->acvi_aci << 5); + tmp190__ |= (pSrc->unused3 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp186__; + *pBuf = tmp190__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp187__ = 0U; - tmp187__ |= (pSrc->acvi_acwmin << 0); - tmp187__ |= (pSrc->acvi_acwmax << 4); + tmp191__ = 0U; + tmp191__ |= (pSrc->acvi_acwmin << 0); + tmp191__ |= (pSrc->acvi_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp187__; + *pBuf = tmp191__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; *pBuf = pSrc->acvi_muedca_timer; *pnConsumed += 1; pBuf += 1; - tmp188__ = 0U; - tmp188__ |= (pSrc->acvo_aifsn << 0); - tmp188__ |= (pSrc->acvo_acm << 4); - tmp188__ |= (pSrc->acvo_aci << 5); - tmp188__ |= (pSrc->unused4 << 7); + tmp192__ = 0U; + tmp192__ |= (pSrc->acvo_aifsn << 0); + tmp192__ |= (pSrc->acvo_acm << 4); + tmp192__ |= (pSrc->acvo_aci << 5); + tmp192__ |= (pSrc->unused4 << 7); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp188__; + *pBuf = tmp192__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; - tmp189__ = 0U; - tmp189__ |= (pSrc->acvo_acwmin << 0); - tmp189__ |= (pSrc->acvo_acwmax << 4); + tmp193__ = 0U; + tmp193__ |= (pSrc->acvo_acwmin << 0); + tmp193__ |= (pSrc->acvo_acwmax << 4); if (unlikely(nBuf < 1)) return DOT11F_INCOMPLETE_IE; - *pBuf = tmp189__; + *pBuf = tmp193__; *pnConsumed += 1; pBuf += 1; nBuf -= 1 ; @@ -28474,6 +28818,14 @@ static uint32_t pack_core(tpAniSirGlobal pCtx, sizeof(tDot11fIEAID) * i), pBufRemaining, nBufRemaining, &len); break; + case SigIeBeaconReportStatus: + status |= + dot11f_pack_ie_BeaconReportStatus( + pCtx, (tDot11fIEBeaconReportStatus *) + (pSrc + pIe->offset + + sizeof(tDot11fIEBeaconReportStatus) * i), + pBufRemaining, nBufRemaining, &len); + break; case SigIeCFParams: status |= dot11f_pack_ie_cf_params( @@ -29274,6 +29626,14 @@ static uint32_t pack_core(tpAniSirGlobal pCtx, sizeof(tDot11fIEfragment_ie) * i), pBufRemaining, nBufRemaining, &len); break; + case SigIehe_6ghz_band_cap: + status |= + dot11f_pack_ie_he_6ghz_band_cap( + pCtx, (tDot11fIEhe_6ghz_band_cap *) + (pSrc + pIe->offset + + sizeof(tDot11fIEhe_6ghz_band_cap) * i), + pBufRemaining, nBufRemaining, &len); + break; case SigIehe_cap: status |= dot11f_pack_ie_he_cap( diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 709f53e12e9ba4a173ecc957492b52102112fba4..af14f4632df042b2c9a195a4379c320956e1fd4f 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -216,7 +216,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_SYS_READY_IND); CASE_RETURN_STRING(eWNI_SME_JOIN_REQ); CASE_RETURN_STRING(eWNI_SME_JOIN_RSP); - CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_REQ); CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_RSP); CASE_RETURN_STRING(eWNI_SME_REASSOC_REQ); CASE_RETURN_STRING(eWNI_SME_REASSOC_RSP); @@ -245,9 +244,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_DELTS_REQ); CASE_RETURN_STRING(eWNI_SME_DELTS_RSP); CASE_RETURN_STRING(eWNI_SME_DELTS_IND); - CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_REQ); - CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_RSP); - CASE_RETURN_STRING(eWNI_SME_GET_RSSI_REQ); CASE_RETURN_STRING(eWNI_SME_ASSOC_IND_UPPER_LAYER); CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND); CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF); @@ -260,11 +256,8 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND); CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND); CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND); - CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_RSP); - CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_RSP); CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_REQ); CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_RSP); - CASE_RETURN_STRING(eWNI_SME_FT_UPDATE_KEY); CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ); CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP); #if defined FEATURE_WLAN_ESE @@ -362,7 +355,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ); CASE_RETURN_STRING(eWNI_SME_ROAM_INIT_PARAM); CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND); - CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_IND); CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND); CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND); CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE); @@ -394,19 +386,15 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) switch (wma_msg) { CASE_RETURN_STRING(WMA_ADD_STA_REQ); CASE_RETURN_STRING(WMA_ADD_STA_RSP); - CASE_RETURN_STRING(WMA_ADD_STA_SELF_RSP); CASE_RETURN_STRING(WMA_DELETE_STA_REQ); CASE_RETURN_STRING(WMA_DELETE_STA_RSP); CASE_RETURN_STRING(WMA_ADD_BSS_REQ); - CASE_RETURN_STRING(WMA_ADD_BSS_RSP); CASE_RETURN_STRING(WMA_DELETE_BSS_REQ); CASE_RETURN_STRING(WMA_DELETE_BSS_HO_FAIL_REQ); CASE_RETURN_STRING(WMA_DELETE_BSS_RSP); CASE_RETURN_STRING(WMA_DELETE_BSS_HO_FAIL_RSP); CASE_RETURN_STRING(WMA_SEND_BEACON_REQ); - CASE_RETURN_STRING(WMA_SET_BSSKEY_REQ); CASE_RETURN_STRING(WMA_SET_BSSKEY_RSP); - CASE_RETURN_STRING(WMA_SET_STAKEY_REQ); CASE_RETURN_STRING(WMA_SET_STAKEY_RSP); CASE_RETURN_STRING(WMA_UPDATE_EDCA_PROFILE_IND); @@ -422,9 +410,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(WMA_IBSS_STA_ADD); CASE_RETURN_STRING(WMA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND); - CASE_RETURN_STRING(WMA_SET_LINK_STATE); - CASE_RETURN_STRING(WMA_SET_LINK_STATE_RSP); - CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_REQ); CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_RSP); CASE_RETURN_STRING(WMA_ADD_TS_RSP); CASE_RETURN_STRING(WMA_DPU_MIC_ERROR); @@ -446,8 +431,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(WMA_ENABLE_UAPSD_REQ); CASE_RETURN_STRING(WMA_DISABLE_UAPSD_REQ); - CASE_RETURN_STRING(WMA_GET_STATISTICS_REQ); - CASE_RETURN_STRING(WMA_GET_STATISTICS_RSP); CASE_RETURN_STRING(WMA_SET_KEY_DONE); CASE_RETURN_STRING(WMA_BTC_SET_CFG); @@ -459,8 +442,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) #ifdef WLAN_NS_OFFLOAD CASE_RETURN_STRING(WMA_SET_NS_OFFLOAD); #endif /* WLAN_NS_OFFLOAD */ - CASE_RETURN_STRING(WMA_ADD_STA_SELF_REQ); - CASE_RETURN_STRING(WMA_DEL_STA_SELF_REQ); CASE_RETURN_STRING(WMA_WLAN_SUSPEND_IND); CASE_RETURN_STRING(WMA_WLAN_RESUME_REQ); #ifdef WLAN_FEATURE_EXTWOW_SUPPORT @@ -581,7 +562,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) #ifdef WLAN_FEATURE_ROAM_OFFLOAD CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_IND); #endif - CASE_RETURN_STRING(WMA_HIDDEN_SSID_VDEV_RESTART); CASE_RETURN_STRING(WMA_UPDATE_RX_NSS); #ifdef WLAN_FEATURE_NAN CASE_RETURN_STRING(WMA_NAN_REQUEST); @@ -627,7 +607,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) #ifdef WLAN_FEATURE_GPIO_LED_FLASHING CASE_RETURN_STRING(WMA_LED_FLASHING_REQ); #endif - CASE_RETURN_STRING(WMA_PROCESS_FW_EVENT); #ifdef FEATURE_AP_MCC_CH_AVOIDANCE CASE_RETURN_STRING(WMA_UPDATE_Q2Q_IE_IND); #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ @@ -705,7 +684,6 @@ uint8_t *mac_trace_get_lim_msg_string(uint16_t lim_msg) CASE_RETURN_STRING(LIM_MLM_DEAUTH_IND); CASE_RETURN_STRING(LIM_MLM_TSPEC_REQ); CASE_RETURN_STRING(LIM_MLM_TSPEC_CNF); - CASE_RETURN_STRING(LIM_MLM_SETKEYS_REQ); CASE_RETURN_STRING(LIM_MLM_SETKEYS_CNF); CASE_RETURN_STRING(LIM_MLM_LINK_TEST_STOP_REQ); CASE_RETURN_STRING(LIM_MLM_PURGE_STA_IND); diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 3a4707f994297ca2b6239fd39c6f672f67cb4678..ded1da91f41fe8ffef7d6a19a8837d40635ac5d6 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -45,6 +45,7 @@ #include "wlan_mlme_public_struct.h" #include "wlan_mlme_ucfg_api.h" #include "wlan_mlme_api.h" +#include "wlan_crypto_global_api.h" #define RSN_OUI_SIZE 4 /* ////////////////////////////////////////////////////////////////////// */ @@ -179,29 +180,32 @@ void populate_dot_11_f_ext_chann_switch_ann(struct mac_context *mac_ptr, struct pe_session *session_entry) { uint8_t ch_offset; + uint32_t sw_target_freq; + uint8_t primary_channel; + enum phy_ch_width ch_width; - if (session_entry->gLimChannelSwitch.ch_width == CH_WIDTH_80MHZ) - ch_offset = BW80; - else - ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset; + ch_width = session_entry->gLimChannelSwitch.ch_width; + ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset; dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode; - dot_11_ptr->new_reg_class = wlan_reg_dmn_get_opclass_from_channel( - mac_ptr->scan.countryCodeCurrent, - session_entry->gLimChannelSwitch.primaryChannel, - ch_offset); + sw_target_freq = session_entry->gLimChannelSwitch.sw_target_freq; + primary_channel = session_entry->gLimChannelSwitch.primaryChannel; + dot_11_ptr->new_reg_class = + lim_op_class_from_bandwidth(mac_ptr, sw_target_freq, ch_width, + ch_offset); dot_11_ptr->new_channel = session_entry->gLimChannelSwitch.primaryChannel; dot_11_ptr->switch_count = session_entry->gLimChannelSwitch.switchCount; dot_11_ptr->present = 1; - pe_debug("country:%s chan:%d width:%d reg:%d off:%d", - mac_ptr->scan.countryCodeCurrent, - session_entry->gLimChannelSwitch.primaryChannel, - session_entry->gLimChannelSwitch.ch_width, - dot_11_ptr->new_reg_class, - session_entry->gLimChannelSwitch.sec_ch_offset); + pe_debug("country:%s chan:%d freq %d width:%d reg:%d off:%d", + mac_ptr->scan.countryCodeCurrent, + session_entry->gLimChannelSwitch.primaryChannel, + sw_target_freq, + session_entry->gLimChannelSwitch.ch_width, + dot_11_ptr->new_reg_class, + session_entry->gLimChannelSwitch.sec_ch_offset); } void @@ -231,30 +235,31 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr, tDot11fIESuppOperatingClasses *dot_11_ptr, struct pe_session *session_entry) { - uint8_t ch_bandwidth; + uint8_t ch_offset; if (session_entry->ch_width == CH_WIDTH_80MHZ) { - ch_bandwidth = BW80; + ch_offset = BW80; } else { switch (session_entry->htSecondaryChannelOffset) { case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: - ch_bandwidth = BW40_HIGH_PRIMARY; + ch_offset = BW40_HIGH_PRIMARY; break; case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: - ch_bandwidth = BW40_LOW_PRIMARY; + ch_offset = BW40_LOW_PRIMARY; break; default: - ch_bandwidth = BW20; + ch_offset = BW20; break; } } wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes, &dot_11_ptr->classes[1]); - dot_11_ptr->classes[0] = wlan_reg_dmn_get_opclass_from_channel( - mac_ptr->scan.countryCodeCurrent, - session_entry->currentOperChannel, - ch_bandwidth); + dot_11_ptr->classes[0] = + lim_op_class_from_bandwidth(mac_ptr, + session_entry->curr_op_freq, + session_entry->ch_width, + ch_offset); dot_11_ptr->num_classes++; dot_11_ptr->present = 1; } @@ -262,7 +267,7 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr, void populate_dot11f_vht_tx_power_env(struct mac_context *mac, tDot11fIEvht_transmit_power_env *pDot11f, - enum phy_ch_width ch_width, uint8_t chan) + enum phy_ch_width ch_width, uint32_t chan_freq) { uint8_t num_tx_power, i, tx_power; int reg_max; @@ -289,7 +294,7 @@ populate_dot11f_vht_tx_power_env(struct mac_context *mac, return; } - reg_max = lim_get_regulatory_max_transmit_power(mac, chan); + reg_max = wlan_reg_get_channel_reg_power_for_freq(mac->pdev, chan_freq); /* in 0.5 dB steps */ reg_max *= 2; @@ -373,60 +378,119 @@ populate_dot11f_avoid_channel_ie(struct mac_context *mac_ctx, dot11f->present = true; dot11f->type = QCOM_VENDOR_IE_MCC_AVOID_CH; - dot11f->channel = pe_session->currentOperChannel; + dot11f->channel = wlan_reg_freq_to_chan( + mac_ctx->pdev, pe_session->curr_op_freq); } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ QDF_STATUS populate_dot11f_country(struct mac_context *mac, - tDot11fIECountry *pDot11f, struct pe_session *pe_session) + tDot11fIECountry *ctry_ie, struct pe_session *pe_session) { - uint32_t len; - enum band_info rfBand; - uint8_t temp[CFG_MAX_STR_LEN], code[3]; + uint8_t code[REG_ALPHA2_LEN + 1]; + qdf_freq_t cur_triplet_freq; + uint8_t cur_triplet_num_chans; + uint8_t cur_triplet_tx_power; + bool cur_triplet_valid; + enum reg_wifi_band cur_triplet_band; + int chan_enum; + struct regulatory_channel *cur_chan_list; + QDF_STATUS status; + + cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list)); + if (!cur_chan_list) + return QDF_STATUS_E_NOMEM; - if (pe_session->lim11dEnabled) { - lim_get_rf_band_new(mac, &rfBand, pe_session); - if (rfBand == BAND_5G) { - len = mac->mlme_cfg->power.max_tx_power_5.len; - qdf_mem_copy(temp, - mac->mlme_cfg->power.max_tx_power_5.data, - len); - } else { - len = mac->mlme_cfg->power.max_tx_power_24.len; - qdf_mem_copy(temp, - mac->mlme_cfg->power.max_tx_power_24.data, - len); - } + status = wlan_reg_get_current_chan_list(mac->pdev, cur_chan_list); + if (status != QDF_STATUS_SUCCESS) { + pe_err("failed to get cur_chan list"); + qdf_mem_free(cur_chan_list); + return status; + } - if (3 > len) { - /* no limit on tx power, cannot include the IE because at least */ - /* one (channel,num,tx power) must be present */ - return QDF_STATUS_SUCCESS; + wlan_reg_read_current_country(mac->psoc, code); + qdf_mem_copy(ctry_ie->country, code, REG_ALPHA2_LEN); + + /* advertise global operating class */ + ctry_ie->country[REG_ALPHA2_LEN] = 0x04; + + cur_triplet_valid = false; + ctry_ie->num_triplets = 0; + for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { + if (wlan_reg_is_6ghz_chan_freq( + cur_chan_list[chan_enum].center_freq)) { + if (cur_triplet_valid) { + ctry_ie->triplets[ctry_ie->num_triplets][0] = + wlan_reg_freq_to_chan(mac->pdev, + cur_triplet_freq); + ctry_ie->triplets[ctry_ie->num_triplets][1] = + cur_triplet_num_chans; + ctry_ie->triplets[ctry_ie->num_triplets][2] = + cur_triplet_tx_power; + ctry_ie->num_triplets++; + cur_triplet_valid = false; + } + break; } - wlan_reg_read_current_country(mac->psoc, code); - - qdf_mem_copy(pDot11f->country, code, 2); - - /* a wi-fi agile multiband AP shall include a country */ - /* element in all beacon and probe response frames */ - /* where the last octet of country string field is */ - /* set to 0x04 */ - if (mac->mlme_cfg->oce.oce_sap_enabled) - pDot11f->country[2] = 0x04; - - if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) { - pe_err("len:%d is out of bounds, resetting", len); - len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + if (cur_chan_list[chan_enum].chan_flags & + REGULATORY_CHAN_DISABLED) { + if (cur_triplet_valid) { + ctry_ie->triplets[ctry_ie->num_triplets][0] = + wlan_reg_freq_to_chan(mac->pdev, + cur_triplet_freq); + ctry_ie->triplets[ctry_ie->num_triplets][1] = + cur_triplet_num_chans; + ctry_ie->triplets[ctry_ie->num_triplets][2] = + cur_triplet_tx_power; + ctry_ie->num_triplets++; + cur_triplet_valid = false; + } + continue; } - pDot11f->num_triplets = (uint8_t) (len / 3); - qdf_mem_copy((uint8_t *) pDot11f->triplets, temp, len); + if (cur_triplet_valid) { + if ((cur_chan_list[chan_enum].tx_power == + cur_triplet_tx_power) && + (cur_triplet_band == + wlan_reg_freq_to_band(cur_chan_list[chan_enum].center_freq))) + cur_triplet_num_chans++; + else { + ctry_ie->triplets[ctry_ie->num_triplets][0] = + wlan_reg_freq_to_chan(mac->pdev, + cur_triplet_freq); + ctry_ie->triplets[ctry_ie->num_triplets][1] = + cur_triplet_num_chans; + ctry_ie->triplets[ctry_ie->num_triplets][2] = + cur_triplet_tx_power; + ctry_ie->num_triplets++; + + cur_triplet_freq = + cur_chan_list[chan_enum].center_freq; + cur_triplet_num_chans = 1; + cur_triplet_tx_power = + cur_chan_list[chan_enum].tx_power; + cur_triplet_band = wlan_reg_freq_to_band(cur_triplet_freq); + } + } else { + cur_triplet_freq = cur_chan_list[chan_enum].center_freq; + cur_triplet_num_chans = 1; + cur_triplet_tx_power = + cur_chan_list[chan_enum].tx_power; + cur_triplet_band = wlan_reg_freq_to_band(cur_triplet_freq); + cur_triplet_valid = true; + } + } - pDot11f->present = 1; + if (ctry_ie->num_triplets == 0) { + /* at-least one triplet should be present */ + qdf_mem_free(cur_chan_list); + return QDF_STATUS_SUCCESS; } + ctry_ie->present = 1; + + qdf_mem_free(cur_chan_list); return QDF_STATUS_SUCCESS; } /* End populate_dot11f_country. */ @@ -531,10 +595,10 @@ populate_dot11f_erp_info(struct mac_context *mac, tDot11fIEERPInfo *pDot11f, struct pe_session *pe_session) { uint32_t val; - enum band_info rfBand = BAND_UNKNOWN; + enum reg_wifi_band rfBand = REG_BAND_UNKNOWN; lim_get_rf_band_new(mac, &rfBand, pe_session); - if (BAND_2G == rfBand) { + if (REG_BAND_2G == rfBand) { pDot11f->present = 1; val = pe_session->cfgProtection.fromllb; @@ -718,12 +782,13 @@ populate_dot11f_ht_caps(struct mac_context *mac, mac->mlme_cfg->rates.disable_high_ht_mcs_2x2; if (pe_session->nss == NSS_1x1_MODE) { pDot11f->supportedMCSSet[1] = 0; - } else if (IS_24G_CH(pe_session->currentOperChannel) && + } else if (wlan_reg_is_24ghz_ch_freq( + pe_session->curr_op_freq) && disable_high_ht_mcs_2x2 && (pe_session->opmode == QDF_STA_MODE)) { - pe_debug("Disabling high HT MCS [%d]", - disable_high_ht_mcs_2x2); - pDot11f->supportedMCSSet[1] = + pe_debug("Disabling high HT MCS [%d]", + disable_high_ht_mcs_2x2); + pDot11f->supportedMCSSet[1] = (pDot11f->supportedMCSSet[1] >> disable_high_ht_mcs_2x2); } @@ -841,10 +906,10 @@ static void lim_log_vht_operation(struct mac_context *mac, { #ifdef DUMP_MGMT_CNTNTS pe_debug("chanWidth: %d", pDot11f->chanWidth); - pe_debug("chanCenterFreqSeg1: %d", - pDot11f->chanCenterFreqSeg1); - pe_debug("chanCenterFreqSeg2: %d", - pDot11f->chanCenterFreqSeg2); + pe_debug("chan_center_freq_seg0: %d", + pDot11f->chan_center_freq_seg0); + pe_debug("chan_center_freq_seg1: %d", + pDot11f->chan_center_freq_seg1); pe_debug("basicMCSSet: %d", pDot11f->basicMCSSet); #endif /* DUMP_MGMT_CNTNTS */ } @@ -905,6 +970,11 @@ populate_dot11f_vht_caps(struct mac_context *mac, nCfgValue = 0; /* With VHT it suffices if we just examine HT */ if (pe_session) { + if (lim_is_he_6ghz_band(pe_session)) { + pDot11f->present = 0; + return QDF_STATUS_SUCCESS; + } + if (pe_session->ht_config.ht_rx_ldpc) pDot11f->ldpcCodingCap = pe_session->vht_config.ldpc_coding; @@ -952,6 +1022,8 @@ populate_dot11f_vht_caps(struct mac_context *mac, pDot11f->rxAntPattern = pe_session->vht_config.rx_antpattern; pDot11f->txAntPattern = pe_session->vht_config.tx_antpattern; + pDot11f->extended_nss_bw_supp = + pe_session->vht_config.extended_nss_bw_supp; pDot11f->maxAMPDULenExp = pe_session->vht_config.max_ampdu_lenexp; @@ -1005,12 +1077,17 @@ populate_dot11f_vht_caps(struct mac_context *mac, nCfgValue = vht_cap_info->link_adap_cap; pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003); + pDot11f->extended_nss_bw_supp = + vht_cap_info->extended_nss_bw_supp; } + pDot11f->max_nsts_total = vht_cap_info->max_nsts_total; + pDot11f->vht_extended_nss_bw_cap = + vht_cap_info->vht_extended_nss_bw_cap; + nCfgValue = vht_cap_info->mu_bformer; pDot11f->muBeamformerCap = (nCfgValue & 0x0001); - pDot11f->reserved1 = 0; nCfgValue = vht_cap_info->rx_mcs_map; pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF); @@ -1018,15 +1095,12 @@ populate_dot11f_vht_caps(struct mac_context *mac, nCfgValue = vht_cap_info->rx_supp_data_rate; pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF); - pDot11f->reserved2 = 0; - nCfgValue = vht_cap_info->tx_mcs_map; pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF); nCfgValue = vht_cap_info->tx_supp_data_rate; pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF); - pDot11f->reserved3 = 0; if (pe_session) { if (pe_session->nss == NSS_1x1_MODE) { pDot11f->txMCSMap |= DISABLE_NSS2_MCS; @@ -1065,22 +1139,25 @@ populate_dot11f_vht_operation(struct mac_context *mac, struct pe_session *pe_session, tDot11fIEVHTOperation *pDot11f) { + if (!pe_session || !pe_session->vhtCapability) + return QDF_STATUS_SUCCESS; + pDot11f->present = 1; if (pe_session->ch_width > CH_WIDTH_40MHZ) { pDot11f->chanWidth = 1; - pDot11f->chanCenterFreqSeg1 = + pDot11f->chan_center_freq_seg0 = pe_session->ch_center_freq_seg0; if (pe_session->ch_width == CH_WIDTH_80P80MHZ || pe_session->ch_width == CH_WIDTH_160MHZ) - pDot11f->chanCenterFreqSeg2 = + pDot11f->chan_center_freq_seg1 = pe_session->ch_center_freq_seg1; else - pDot11f->chanCenterFreqSeg2 = 0; + pDot11f->chan_center_freq_seg1 = 0; } else { pDot11f->chanWidth = 0; - pDot11f->chanCenterFreqSeg1 = 0; - pDot11f->chanCenterFreqSeg2 = 0; + pDot11f->chan_center_freq_seg0 = 0; + pDot11f->chan_center_freq_seg1 = 0; } pDot11f->basicMCSSet = @@ -1197,7 +1274,8 @@ populate_dot11f_ht_info(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } - pDot11f->primaryChannel = pe_session->currentOperChannel; + pDot11f->primaryChannel = wlan_reg_freq_to_chan( + mac->pdev, pe_session->curr_op_freq); pDot11f->secondaryChannelOffset = pe_session->htSecondaryChannelOffset; @@ -1712,8 +1790,8 @@ populate_dot11f_tpc_report(struct mac_context *mac, nSirStatus); return QDF_STATUS_E_FAILURE; } - tx_power = lim_get_regulatory_max_transmit_power( - mac, pe_session->currentOperChannel); + tx_power = wlan_reg_get_channel_reg_power_for_freq( + mac->pdev, pe_session->curr_op_freq); pDot11f->tx_power = tx_power; pDot11f->link_margin = 0; pDot11f->present = 1; @@ -2397,11 +2475,17 @@ QDF_STATUS sir_convert_probe_frame2_struct(struct mac_context *mac, sizeof(tDot11fIEHTInfo)); } - if (pr->DSParams.present) { + if (pr->he_op.oper_info_6g_present) { + pProbeResp->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev, + pr->he_op.oper_info_6g.info.primary_ch, + BIT(REG_BAND_6G)); + } else if (pr->DSParams.present) { pProbeResp->dsParamsPresent = 1; - pProbeResp->channelNumber = pr->DSParams.curr_channel; + pProbeResp->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, pr->DSParams.curr_channel); } else if (pr->HTInfo.present) { - pProbeResp->channelNumber = pr->HTInfo.primaryChannel; + pProbeResp->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, pr->HTInfo.primaryChannel); } if (pr->RSNOpaque.present) { @@ -2710,6 +2794,19 @@ sir_convert_assoc_req_frame2_struct(struct mac_context *mac, ext_cap->timing_meas, ext_cap->fine_time_meas_initiator, ext_cap->fine_time_meas_responder); } + if (ar->SuppOperatingClasses.present) { + uint8_t num_classes = ar->SuppOperatingClasses.num_classes; + + if (num_classes > sizeof(ar->SuppOperatingClasses.classes)) + num_classes = + sizeof(ar->SuppOperatingClasses.classes); + qdf_mem_copy(&pAssocReq->supp_operating_classes, + &ar->SuppOperatingClasses, + sizeof(tDot11fIESuppOperatingClasses)); + QDF_TRACE_HEX_DUMP( + QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, + ar->SuppOperatingClasses.classes, num_classes); + } pAssocReq->vendor_vht_ie.present = ar->vendor_vht_ie.present; if (ar->vendor_vht_ie.present) { @@ -2732,6 +2829,12 @@ sir_convert_assoc_req_frame2_struct(struct mac_context *mac, QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, &pAssocReq->he_cap, sizeof(tDot11fIEhe_cap)); } + if (ar->he_6ghz_band_cap.present) { + qdf_mem_copy(&pAssocReq->he_6ghz_band_cap, + &ar->he_6ghz_band_cap, + sizeof(tDot11fIEhe_6ghz_band_cap)); + pe_debug("Received Assoc Req with HE Band Capability IE"); + } qdf_mem_free(ar); return QDF_STATUS_SUCCESS; @@ -3207,6 +3310,13 @@ sir_convert_assoc_resp_frame2_struct(struct mac_context *mac, pAssocRsp->he_op.bss_col_disabled); } + if (ar->he_6ghz_band_cap.present) { + pe_debug("11AX: HE Band Capability IE present"); + qdf_mem_copy(&pAssocRsp->he_6ghz_band_cap, + &ar->he_6ghz_band_cap, + sizeof(tDot11fIEhe_6ghz_band_cap)); + } + if (ar->mu_edca_param_set.present) { pe_debug("11AX: HE MU EDCA param IE present"); pAssocRsp->mu_edca_present = true; @@ -3375,7 +3485,19 @@ sir_convert_reassoc_req_frame2_struct(struct mac_context *mac, convert_wfd_opaque(mac, &pAssocReq->addIE, &ar->WFDIEOpaque); } #endif - + if (ar->SuppOperatingClasses.present) { + uint8_t num_classes = ar->SuppOperatingClasses.num_classes; + + if (num_classes > sizeof(ar->SuppOperatingClasses.classes)) + num_classes = + sizeof(ar->SuppOperatingClasses.classes); + qdf_mem_copy(&pAssocReq->supp_operating_classes, + &ar->SuppOperatingClasses, + sizeof(tDot11fIESuppOperatingClasses)); + QDF_TRACE_HEX_DUMP( + QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, + ar->SuppOperatingClasses.classes, num_classes); + } if (ar->VHTCaps.present) { qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps, sizeof(tDot11fIEVHTCaps)); @@ -3400,6 +3522,12 @@ sir_convert_reassoc_req_frame2_struct(struct mac_context *mac, qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap, sizeof(tDot11fIEhe_cap)); } + if (ar->he_6ghz_band_cap.present) { + qdf_mem_copy(&pAssocReq->he_6ghz_band_cap, + &ar->he_6ghz_band_cap, + sizeof(tDot11fIEhe_6ghz_band_cap)); + } + qdf_mem_free(ar); return QDF_STATUS_SUCCESS; @@ -3856,11 +3984,19 @@ sir_parse_beacon_ie(struct mac_context *mac, sizeof(tDot11fIEHTInfo)); } - if (pBies->DSParams.present) { + if (pBies->he_op.oper_info_6g_present) { + pBeaconStruct->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev, + pBies->he_op.oper_info_6g.info.primary_ch, + BIT(REG_BAND_6G)); + } else if (pBies->DSParams.present) { pBeaconStruct->dsParamsPresent = 1; - pBeaconStruct->channelNumber = pBies->DSParams.curr_channel; + pBeaconStruct->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, + pBies->DSParams.curr_channel); } else if (pBies->HTInfo.present) { - pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel; + pBeaconStruct->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, + pBies->HTInfo.primaryChannel); } if (pBies->RSN.present) { @@ -4016,12 +4152,10 @@ sir_convert_beacon_frame2_struct(struct mac_context *mac, uint32_t status, nPayload; uint8_t *pPayload; tpSirMacMgmtHdr pHdr; - uint8_t mappedRXCh; pPayload = WMA_GET_RX_MPDU_DATA(pFrame); nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame); pHdr = WMA_GET_RX_MAC_HEADER(pFrame); - mappedRXCh = WMA_GET_RX_CH(pFrame); /* Zero-init our [out] parameter, */ qdf_mem_zero((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon)); @@ -4179,13 +4313,21 @@ sir_convert_beacon_frame2_struct(struct mac_context *mac, } - if (pBeacon->DSParams.present) { + if (pBeacon->he_op.oper_info_6g_present) { + pBeaconStruct->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev, + pBeacon->he_op.oper_info_6g.info.primary_ch, + BIT(REG_BAND_6G)); + } else if (pBeacon->DSParams.present) { pBeaconStruct->dsParamsPresent = 1; - pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel; + pBeaconStruct->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, + pBeacon->DSParams.curr_channel); } else if (pBeacon->HTInfo.present) { - pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel; + pBeaconStruct->chan_freq = + wlan_reg_legacy_chan_to_freq(mac->pdev, + pBeacon->HTInfo.primaryChannel); } else { - pBeaconStruct->channelNumber = mappedRXCh; + pBeaconStruct->chan_freq = WMA_GET_RX_FREQ(pFrame); pe_debug_rl("In Beacon No Channel info"); } @@ -5769,7 +5911,7 @@ QDF_STATUS populate_dot11f_rrm_ie(struct mac_context *mac, void populate_mdie(struct mac_context *mac, tDot11fIEMobilityDomain *pDot11f, - uint8_t mdie[SIR_MDIE_SIZE]) + uint8_t mdie[]) { pDot11f->present = 1; pDot11f->MDID = (uint16_t) ((mdie[1] << 8) | (mdie[0])); @@ -5877,8 +6019,10 @@ QDF_STATUS populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx, tDot11fTimingAdvertisementFrame *frame) { - uint32_t val, len; + uint32_t val, len, j = 0; uint8_t temp[CFG_MAX_STR_LEN], code[3]; + tSirMacChanInfo *max_tx_power_data; + int32_t rem_length = 0, copied_length = 0; /* Capabilities */ val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled; @@ -5905,14 +6049,28 @@ populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx, /* Country */ len = mac_ctx->mlme_cfg->power.max_tx_power_5.len; - qdf_mem_copy(temp, mac_ctx->mlme_cfg->power.max_tx_power_5.data, len); + max_tx_power_data = + (tSirMacChanInfo *)mac_ctx->mlme_cfg->power.max_tx_power_5.data; + rem_length = len; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + temp[copied_length++] = + (uint8_t)wlan_reg_freq_to_chan( + mac_ctx->pdev, + max_tx_power_data[j].first_freq); + + temp[copied_length++] = max_tx_power_data[j].numChannels; + temp[copied_length++] = max_tx_power_data[j].maxTxPower; + j++; + rem_length -= (sizeof(tSirMacChanInfo)); + } + wlan_reg_read_current_country(mac_ctx->psoc, code); qdf_mem_copy(&frame->Country, code, 2); - if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) - len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + if (copied_length > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) + copied_length = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; - frame->Country.num_triplets = (uint8_t)(len / 3); - qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, len); + frame->Country.num_triplets = (uint8_t)(copied_length / 3); + qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, copied_length); frame->Country.present = 1; /* PowerConstraints */ @@ -5955,14 +6113,14 @@ QDF_STATUS populate_dot11f_he_caps(struct mac_context *mac_ctx, struct pe_sessio if (he_cap->ppet_present) { value = WNI_CFG_HE_PPET_LEN; /* if session is present, populate PPET based on band */ - if (IS_5G_CH(session->currentOperChannel)) - qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, - mac_ctx->mlme_cfg->he_caps.he_ppet_5g, - value); + if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) + qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, + mac_ctx->mlme_cfg->he_caps.he_ppet_5g, + value); else - qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, - mac_ctx->mlme_cfg->he_caps.he_ppet_2g, - value); + qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, + mac_ctx->mlme_cfg->he_caps.he_ppet_2g, + value); ppet = he_cap->ppet.ppe_threshold.ppe_th; he_cap->ppet.ppe_threshold.num_ppe_th = @@ -5988,24 +6146,78 @@ populate_dot11f_he_operation(struct mac_context *mac_ctx, { qdf_mem_copy(he_op, &session->he_op, sizeof(*he_op)); - he_op->vht_oper_present = 1; he_op->present = 1; - if (session->ch_width > CH_WIDTH_40MHZ) { - he_op->vht_oper.info.chan_width = 1; - he_op->vht_oper.info.center_freq_seg0 = - session->ch_center_freq_seg0; - if (session->ch_width == CH_WIDTH_80P80MHZ || - session->ch_width == CH_WIDTH_160MHZ) - he_op->vht_oper.info.center_freq_seg1 = - session->ch_center_freq_seg1; - else + if (!session->he_6ghz_band) { + he_op->vht_oper_present = 1; + if (session->ch_width > CH_WIDTH_40MHZ) { + he_op->vht_oper.info.chan_width = 1; + he_op->vht_oper.info.center_freq_seg0 = + session->ch_center_freq_seg0; + if (session->ch_width == CH_WIDTH_80P80MHZ || + session->ch_width == CH_WIDTH_160MHZ) + he_op->vht_oper.info.center_freq_seg1 = + session->ch_center_freq_seg1; + else + he_op->vht_oper.info.center_freq_seg1 = 0; + } else { + he_op->vht_oper.info.chan_width = 0; + he_op->vht_oper.info.center_freq_seg0 = 0; he_op->vht_oper.info.center_freq_seg1 = 0; + } } else { - he_op->vht_oper.info.chan_width = 0; - he_op->vht_oper.info.center_freq_seg0 = 0; - he_op->vht_oper.info.center_freq_seg1 = 0; + he_op->oper_info_6g_present = 1; + he_op->oper_info_6g.info.ch_width = session->ch_width; + he_op->oper_info_6g.info.center_freq_seg0 = + session->ch_center_freq_seg0; + if (session->ch_width == CH_WIDTH_80P80MHZ || + session->ch_width == CH_WIDTH_160MHZ) { + he_op->oper_info_6g.info.center_freq_seg1 = + session->ch_center_freq_seg1; + he_op->oper_info_6g.info.ch_width = CH_WIDTH_160MHZ; + } else { + he_op->oper_info_6g.info.center_freq_seg1 = 0; + } + he_op->oper_info_6g.info.primary_ch = + wlan_reg_freq_to_chan(mac_ctx->pdev, + session->curr_op_freq); + he_op->oper_info_6g.info.dup_bcon = 0; + he_op->oper_info_6g.info.min_rate = 0; } - lim_log_he_op(mac_ctx, he_op); + lim_log_he_op(mac_ctx, he_op, session); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +populate_dot11f_he_6ghz_cap(struct mac_context *mac_ctx, + struct pe_session *session, + tDot11fIEhe_6ghz_band_cap *he_6g_cap) +{ + struct mlme_ht_capabilities_info *ht_cap_info; + struct mlme_vht_capabilities_info *vht_cap_info; + + if (session && !session->he_6ghz_band) + return QDF_STATUS_SUCCESS; + + ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info; + vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; + + he_6g_cap->present = 1; + he_6g_cap->min_mpdu_start_spacing = + mac_ctx->mlme_cfg->ht_caps.ampdu_params.mpdu_density; + if (session) + he_6g_cap->max_ampdu_len_exp = + session->vht_config.max_ampdu_lenexp; + else + he_6g_cap->max_ampdu_len_exp = + vht_cap_info->ampdu_len_exponent & 0x7; + he_6g_cap->max_mpdu_len = vht_cap_info->ampdu_len; + he_6g_cap->sm_pow_save = ht_cap_info->mimo_power_save; + he_6g_cap->rd_responder = 0; + he_6g_cap->rx_ant_pattern_consistency = 0; + he_6g_cap->tx_ant_pattern_consistency = 0; + + lim_log_he_6g_cap(mac_ctx, he_6g_cap); return QDF_STATUS_SUCCESS; } @@ -6066,4 +6278,28 @@ QDF_STATUS populate_dot11f_twt_extended_caps(struct mac_context *mac_ctx, } #endif +QDF_STATUS populate_dot11f_btm_caps(struct mac_context *mac_ctx, + struct pe_session *pe_session, + struct sDot11fIEExtCap *dot11f) +{ + struct s_ext_cap *p_ext_cap; + uint32_t fw_akm_bitmap; + bool sae_can_roam; + + dot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; + p_ext_cap = (struct s_ext_cap *)dot11f->bytes; + fw_akm_bitmap = mac_ctx->mlme_cfg->lfr.fw_akm_bitmap; + sae_can_roam = (((fw_akm_bitmap) & (1 << AKM_SAE)) ? true : false); + + if (pe_session->connected_akm == ANI_AKM_TYPE_SAE && + !sae_can_roam) { + p_ext_cap->bss_transition = 0; + pe_debug("Disable btm cap for SAE roam not supported"); + } + + dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f); + + return QDF_STATUS_SUCCESS; +} + /* parser_api.c ends here. */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/utils_parser.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/utils_parser.c index 48d342430e831e371f9941e9e162d6f9b9fe4d70..c4b8cc82ed404b80fc46fa0488ed48af4bc81152 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/utils_parser.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/legacy/src/utils/src/utils_parser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -650,35 +650,35 @@ void convert_wmm_schedule(struct mac_context *mac, pOld->specInterval = pNew->spec_interval; } -void convert_qos_mapset_frame(struct mac_context *mac, struct qos_map_set *Qos, - tDot11fIEQosMapSet *dot11fIE) +void convert_qos_mapset_frame(struct mac_context *mac, struct qos_map_set *qos, + tDot11fIEQosMapSet *dot11f_ie) { uint8_t i, j = 0; - uint8_t qos_dscp_sz, dot11_dscp_sz; + uint8_t dot11_dscp_exception_sz; - qos_dscp_sz = (sizeof(Qos->dscp_exceptions)/2); - dot11_dscp_sz = sizeof(dot11fIE->dscp_exceptions); - if (dot11fIE->num_dscp_exceptions > QOS_MAP_LEN_MAX) - dot11fIE->num_dscp_exceptions = QOS_MAP_LEN_MAX; - if (dot11fIE->num_dscp_exceptions < QOS_MAP_LEN_MIN) + if (dot11f_ie->num_dscp_exceptions < DOT11F_IE_QOSMAPSET_MIN_LEN || + dot11f_ie->num_dscp_exceptions % 2) { + pe_debug("Invalid num_dscp_exceptions %d", + dot11f_ie->num_dscp_exceptions); return; - Qos->num_dscp_exceptions = - (dot11fIE->num_dscp_exceptions - QOS_MAP_LEN_MIN) / 2; - - for (i = 0; - i < Qos->num_dscp_exceptions && - i < qos_dscp_sz && j < dot11_dscp_sz; - i++) { - Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j]; - j++; - Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j]; - j++; } - for (i = 0; i < 8 && j < dot11_dscp_sz; i++) { - Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j]; - j++; - Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j]; - j++; + + dot11_dscp_exception_sz = dot11f_ie->num_dscp_exceptions - + DOT11F_IE_QOSMAPSET_MIN_LEN; + qos->num_dscp_exceptions = dot11_dscp_exception_sz / 2; + if (qos->num_dscp_exceptions > QOS_MAP_MAX_EX) + qos->num_dscp_exceptions = QOS_MAP_MAX_EX; + + for (i = 0; i < qos->num_dscp_exceptions && + j < dot11_dscp_exception_sz - 1; i++) { + qos->dscp_exceptions[i][0] = dot11f_ie->dscp_exceptions[j++]; + qos->dscp_exceptions[i][1] = dot11f_ie->dscp_exceptions[j++]; + } + + for (i = 0; i < QOS_MAP_RANGE_NUM && + j < dot11f_ie->num_dscp_exceptions - 1; i++) { + qos->dscp_range[i][0] = dot11f_ie->dscp_exceptions[j++]; + qos->dscp_range[i][1] = dot11f_ie->dscp_exceptions[j++]; } } diff --git a/drivers/staging/qcacld-3.0/core/pld/inc/pld_common.h b/drivers/staging/qcacld-3.0/core/pld/inc/pld_common.h index 738ef3cc2ccb3aca3a1c2a7936d7d38ef83fe9a4..e648a76b9f6efb795fbee4d00db1273dc44691ef 100644 --- a/drivers/staging/qcacld-3.0/core/pld/inc/pld_common.h +++ b/drivers/staging/qcacld-3.0/core/pld/inc/pld_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -24,7 +24,7 @@ #include #include -#if IS_ENABLED(CONFIG_CNSS_UTILS) || IS_ENABLED(CONFIG_CNSS_UTILS_MODULE) +#ifdef CONFIG_CNSS_UTILS #include #endif @@ -38,7 +38,7 @@ #define TOTAL_DUMP_SIZE 0x00200000 -#if IS_ENABLED(CONFIG_WCNSS_MEM_PRE_ALLOC) +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC #include #endif @@ -51,6 +51,7 @@ * @PLD_BUS_TYPE_USB : USB bus * @PLD_BUS_TYPE_SNOC_FW_SIM : SNOC FW SIM bus * @PLD_BUS_TYPE_PCIE_FW_SIM : PCIE FW SIM bus + * @PLD_BUS_TYPE_IPCI : IPCI bus */ enum pld_bus_type { PLD_BUS_TYPE_NONE = -1, @@ -60,6 +61,7 @@ enum pld_bus_type { PLD_BUS_TYPE_USB, PLD_BUS_TYPE_SNOC_FW_SIM, PLD_BUS_TYPE_PCIE_FW_SIM, + PLD_BUS_TYPE_IPCI, }; #define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024) @@ -72,6 +74,7 @@ enum pld_bus_type { * @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth * @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth * @PLD_BUS_WIDTH_VERY_HIGH: vote for very high bus bandwidth + * @PLD_BUS_WIDTH_LOW_LATENCY: vote for low latency bus bandwidth */ enum pld_bus_width_type { PLD_BUS_WIDTH_NONE, @@ -80,6 +83,7 @@ enum pld_bus_width_type { PLD_BUS_WIDTH_MEDIUM, PLD_BUS_WIDTH_HIGH, PLD_BUS_WIDTH_VERY_HIGH, + PLD_BUS_WIDTH_LOW_LATENCY, }; #define PLD_MAX_FILE_NAME NAME_MAX @@ -113,10 +117,12 @@ struct pld_fw_files { * enum pld_platform_cap_flag - platform capability flag * @PLD_HAS_EXTERNAL_SWREG: has external regulator * @PLD_HAS_UART_ACCESS: has UART access + * @PLD_HAS_DRV_SUPPORT: has PCIe DRV support */ enum pld_platform_cap_flag { PLD_HAS_EXTERNAL_SWREG = 0x01, PLD_HAS_UART_ACCESS = 0x02, + PLD_HAS_DRV_SUPPORT = 0x04, }; /** @@ -140,6 +146,7 @@ enum pld_uevent { PLD_FW_DOWN, PLD_FW_CRASHED, PLD_FW_RECOVERY_START, + PLD_FW_HANG_EVENT, }; /** @@ -153,6 +160,10 @@ struct pld_uevent_data { struct { bool crashed; } fw_down; + struct { + void *hang_event_data; + u16 hang_event_data_len; + } hang_data; }; }; @@ -264,6 +275,8 @@ struct pld_wlan_enable_cfg { * @PLD_EPPING: EPPING mode * @PLD_WALTEST: WAL test mode, FW standalone test mode * @PLD_OFF: OFF mode + * @PLD_COLDBOOT_CALIBRATION: Cold Boot Calibration Mode + * @PLD_FTM_COLDBOOT_CALIBRATION: Cold Boot Calibration for FTM Mode */ enum pld_driver_mode { PLD_MISSION, @@ -271,7 +284,8 @@ enum pld_driver_mode { PLD_EPPING, PLD_WALTEST, PLD_OFF, - PLD_COLDBOOT_CALIBRATION = 7 + PLD_COLDBOOT_CALIBRATION = 7, + PLD_FTM_COLDBOOT_CALIBRATION = 10 }; /** @@ -329,6 +343,18 @@ enum pld_recovery_reason { PLD_REASON_LINK_DOWN }; +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +/** + * enum pld_wlan_time_sync_trigger_type - WLAN time sync trigger type + * @PLD_TRIGGER_POSITIVE_EDGE: Positive edge trigger + * @PLD_TRIGGER_NEGATIVE_EDGE: Negative edge trigger + */ +enum pld_wlan_time_sync_trigger_type { + PLD_TRIGGER_POSITIVE_EDGE, + PLD_TRIGGER_NEGATIVE_EDGE +}; +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ + /** * struct pld_driver_ops - driver callback functions * @probe: required operation, will be called when device is detected @@ -403,7 +429,7 @@ 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); + enum pld_driver_mode mode); int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode); int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode); void pld_get_default_fw_files(struct pld_fw_files *pfw_files); @@ -413,10 +439,18 @@ int pld_get_fw_files_for_target(struct device *dev, int pld_prevent_l1(struct device *dev); void pld_allow_l1(struct device *dev); void pld_is_pci_link_down(struct device *dev); +void pld_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len); int pld_shadow_control(struct device *dev, bool enable); void pld_schedule_recovery_work(struct device *dev, enum pld_recovery_reason reason); -#if IS_ENABLED(CONFIG_CNSS_UTILS) || IS_ENABLED(CONFIG_CNSS_UTILS_MODULE) + +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +int pld_get_audio_wlan_timestamp(struct device *dev, + enum pld_wlan_time_sync_trigger_type type, + uint64_t *ts); +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ + +#ifdef CONFIG_CNSS_UTILS /** * pld_set_wlan_unsafe_channel() - Set unsafe channel * @dev: device @@ -609,6 +643,15 @@ void *pld_get_fw_ptr(struct device *dev); int pld_auto_suspend(struct device *dev); int pld_auto_resume(struct device *dev); int pld_force_wake_request(struct device *dev); + +/** + * pld_force_wake_request_sync() - Request to awake MHI synchronously + * @dev: device + * @timeout_us: timeout in micro-sec request to wake + * + * Return: 0 for success + * Non zero failure code for errors + */ int pld_force_wake_request_sync(struct device *dev, int timeout_us); int pld_is_device_awake(struct device *dev); int pld_force_wake_release(struct device *dev); @@ -753,7 +796,7 @@ int pld_srng_free_irq(struct device *dev, int irq, void *ctx); void pld_srng_enable_irq(struct device *dev, int irq); /** - * pld_disable_irq() - Disable IRQ for SRNG + * pld_srng_disable_irq() - Disable IRQ for SRNG * @dev: device * @irq: IRQ number * @@ -804,7 +847,7 @@ int pld_pci_read_config_dword(struct pci_dev *pdev, int offset, uint32_t *val); * Non zero failure code for errors */ int pld_pci_write_config_dword(struct pci_dev *pdev, int offset, uint32_t val); -#if IS_ENABLED(CONFIG_WCNSS_MEM_PRE_ALLOC) && defined(FEATURE_SKB_PRE_ALLOC) +#if defined(CONFIG_WCNSS_MEM_PRE_ALLOC) && defined(FEATURE_SKB_PRE_ALLOC) /** * pld_nbuf_pre_alloc() - get allocated nbuf from platform driver. diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_common.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_common.c index 831c6fbffc6509839dac148b61a0a5979c6f5fbd..fa37778f15348946cdb5104dc41b81c4b485e0a5 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_common.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,13 +34,18 @@ #ifdef CONFIG_PLD_SNOC_ICNSS #include #endif +#ifdef CONFIG_PLD_IPCI_ICNSS +#include +#endif #include "pld_pcie.h" +#include "pld_ipci.h" #include "pld_pcie_fw_sim.h" #include "pld_snoc_fw_sim.h" #include "pld_snoc.h" #include "pld_sdio.h" #include "pld_usb.h" +#include "qwlan_version.h" #define PLD_PCIE_REGISTERED BIT(0) #define PLD_SNOC_REGISTERED BIT(1) @@ -48,6 +53,8 @@ #define PLD_USB_REGISTERED BIT(3) #define PLD_SNOC_FW_SIM_REGISTERED BIT(4) #define PLD_PCIE_FW_SIM_REGISTERED BIT(5) +#define PLD_IPCI_REGISTERED BIT(6) + #define PLD_BUS_MASK 0xf static struct pld_context *pld_ctx; @@ -312,8 +319,17 @@ int pld_register_driver(struct pld_driver_ops *ops) } pld_context->pld_driver_state |= PLD_USB_REGISTERED; + ret = pld_ipci_register_driver(); + if (ret) { + pr_err("Fail to register ipci driver\n"); + goto fail_ipci; + } + pld_context->pld_driver_state |= PLD_IPCI_REGISTERED; + return ret; +fail_ipci: + pld_usb_unregister_driver(); fail_usb: pld_pcie_fw_sim_unregister_driver(); fail_pcie_fw_sim: @@ -362,6 +378,7 @@ void pld_unregister_driver(void) pld_snoc_unregister_driver(); pld_sdio_unregister_driver(); pld_usb_unregister_driver(); + pld_ipci_unregister_driver(); pld_context->pld_driver_state = 0; @@ -373,7 +390,6 @@ void pld_unregister_driver(void) * @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. @@ -382,31 +398,36 @@ void pld_unregister_driver(void) * 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) + enum pld_driver_mode mode) { int ret = 0; struct device *ifdev; switch (pld_get_bus_type(dev)) { case PLD_BUS_TYPE_PCIE: - ret = pld_pcie_wlan_enable(dev, config, mode, host_version); + ret = pld_pcie_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; case PLD_BUS_TYPE_SNOC: - ret = pld_snoc_wlan_enable(dev, config, mode, host_version); + ret = pld_snoc_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; case PLD_BUS_TYPE_SNOC_FW_SIM: ret = pld_snoc_fw_sim_wlan_enable(dev, config, mode, - host_version); + QWLAN_VERSIONSTR); break; case PLD_BUS_TYPE_PCIE_FW_SIM: ret = pld_pcie_fw_sim_wlan_enable(dev, config, mode, - host_version); + QWLAN_VERSIONSTR); break; case PLD_BUS_TYPE_SDIO: + ret = pld_sdio_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; case PLD_BUS_TYPE_USB: ifdev = pld_get_if_dev(dev); - ret = pld_usb_wlan_enable(ifdev, config, mode, host_version); + ret = pld_usb_wlan_enable(ifdev, config, mode, + QWLAN_VERSIONSTR); + break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_wlan_enable(dev, config, mode, QWLAN_VERSIONSTR); break; default: ret = -EINVAL; @@ -445,6 +466,9 @@ int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_wlan_disable(dev, mode); + break; default: ret = -EINVAL; break; @@ -478,6 +502,9 @@ int pld_set_fw_log_mode(struct device *dev, u8 fw_log_mode) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_set_fw_log_mode(dev, fw_log_mode); + break; default: ret = -EINVAL; break; @@ -541,6 +568,7 @@ int pld_get_fw_files_for_target(struct device *dev, case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: ret = pld_sdio_get_fw_files_for_target(pfw_files, @@ -624,6 +652,35 @@ void pld_is_pci_link_down(struct device *dev) break; case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: + break; + default: + pr_err("Invalid device type\n"); + break; + } +} + +/** + * pld_get_bus_reg_dump() - Get bus reg dump + * @dev: device + * @buffer: buffer for hang data + * @len: len of hang data + * + * Get pci reg dump for hang data. + * + * Return: void + */ +void pld_get_bus_reg_dump(struct device *dev, uint8_t *buf, uint32_t len) +{ + switch (pld_get_bus_type(dev)) { + case PLD_BUS_TYPE_PCIE_FW_SIM: + break; + case PLD_BUS_TYPE_PCIE: + pld_pcie_get_reg_dump(dev, buf, len); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type\n"); @@ -650,6 +707,7 @@ void pld_schedule_recovery_work(struct device *dev, case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type\n"); @@ -683,6 +741,8 @@ int pld_wlan_pm_control(struct device *dev, bool vote) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: ret = -EINVAL; break; @@ -709,6 +769,7 @@ void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: mem = pld_sdio_get_virt_ramdump_mem(dev, size); @@ -730,6 +791,7 @@ void pld_release_virt_ramdump_mem(struct device *dev, void *address) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: pld_sdio_release_virt_ramdump_mem(address); @@ -759,6 +821,8 @@ void pld_device_crashed(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: pld_sdio_device_crashed(dev); break; @@ -786,6 +850,8 @@ void pld_device_self_recovery(struct device *dev, case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: pld_sdio_device_self_recovery(dev); break; @@ -812,6 +878,7 @@ void pld_intr_notify_q6(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type\n"); @@ -838,6 +905,8 @@ void pld_request_pm_qos(struct device *dev, u32 qos_val) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: /* To do Add call cns API */ break; @@ -867,6 +936,8 @@ void pld_remove_pm_qos(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: /* To do Add call cns API */ break; @@ -898,6 +969,8 @@ int pld_request_bus_bandwidth(struct device *dev, int bandwidth) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: /* To do Add call cns API */ break; @@ -933,6 +1006,8 @@ int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: break; default: @@ -970,6 +1045,8 @@ int pld_get_sha_hash(struct device *dev, const u8 *data, case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: break; default: @@ -997,6 +1074,7 @@ void *pld_get_fw_ptr(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1027,6 +1105,8 @@ int pld_auto_suspend(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: break; default: @@ -1056,6 +1136,8 @@ int pld_auto_resume(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: break; default: @@ -1087,6 +1169,7 @@ int pld_force_wake_request(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type %d\n", type); @@ -1097,14 +1180,6 @@ int pld_force_wake_request(struct device *dev) return ret; } -/** - * pld_force_wake_request_sync() - Request to awake MHI synchronously - * @dev: device - * @timeout_us: timeout in micro-sec request to wake - * - * Return: 0 for success - * Non zero failure code for errors - */ int pld_force_wake_request_sync(struct device *dev, int timeout_us) { int ret = 0; @@ -1119,6 +1194,7 @@ int pld_force_wake_request_sync(struct device *dev, int timeout_us) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type %d\n", type); @@ -1151,6 +1227,7 @@ int pld_is_device_awake(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type %d\n", type); @@ -1182,6 +1259,7 @@ int pld_force_wake_release(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type %d\n", type); @@ -1222,6 +1300,8 @@ int pld_ce_request_irq(struct device *dev, unsigned int ce_id, case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; + case PLD_BUS_TYPE_IPCI: + break; default: ret = -EINVAL; break; @@ -1253,6 +1333,8 @@ int pld_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: break; + case PLD_BUS_TYPE_IPCI: + break; default: ret = -EINVAL; break; @@ -1279,6 +1361,7 @@ void pld_enable_irq(struct device *dev, unsigned int ce_id) break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1306,6 +1389,7 @@ void pld_disable_irq(struct device *dev, unsigned int ce_id) break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1344,6 +1428,9 @@ int pld_get_soc_info(struct device *dev, struct pld_soc_info *info) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_get_soc_info(dev, info); + break; default: ret = -EINVAL; break; @@ -1375,6 +1462,8 @@ int pld_get_ce_id(struct device *dev, int irq) break; case PLD_BUS_TYPE_PCIE_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; default: ret = -EINVAL; break; @@ -1401,6 +1490,8 @@ int pld_get_irq(struct device *dev, int ce_id) case PLD_BUS_TYPE_SNOC_FW_SIM: ret = pld_snoc_fw_sim_get_irq(dev, ce_id); break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: default: @@ -1426,6 +1517,7 @@ void pld_lock_pm_sem(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1452,6 +1544,7 @@ void pld_release_pm_sem(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1481,6 +1574,7 @@ void pld_lock_reg_window(struct device *dev, unsigned long *flags) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1510,6 +1604,7 @@ void pld_unlock_reg_window(struct device *dev, unsigned long *flags) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_SDIO: break; @@ -1545,6 +1640,9 @@ int pld_power_on(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_power_on(dev); break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_power_on(dev); + break; default: pr_err("Invalid device type\n"); break; @@ -1577,6 +1675,9 @@ int pld_power_off(struct device *dev) case PLD_BUS_TYPE_SNOC: ret = pld_snoc_power_off(dev); break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_power_off(dev); + break; default: pr_err("Invalid device type\n"); break; @@ -1615,6 +1716,7 @@ int pld_athdiag_read(struct device *dev, uint32_t offset, case PLD_BUS_TYPE_USB: case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: break; default: ret = -EINVAL; @@ -1654,6 +1756,7 @@ int pld_athdiag_write(struct device *dev, uint32_t offset, case PLD_BUS_TYPE_USB: case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: break; default: ret = -EINVAL; @@ -1685,6 +1788,8 @@ void *pld_smmu_get_domain(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: pr_err("Not supported on type %d\n", type); @@ -1715,6 +1820,8 @@ void *pld_smmu_get_mapping(struct device *dev) case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_PCIE: ptr = pld_pcie_smmu_get_mapping(dev); break; @@ -1750,6 +1857,8 @@ int pld_smmu_map(struct device *dev, phys_addr_t paddr, case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_PCIE: ret = pld_pcie_smmu_map(dev, paddr, iova_addr, size); break; @@ -1782,11 +1891,13 @@ int pld_smmu_unmap(struct device *dev, case PLD_BUS_TYPE_SNOC: ret = pld_snoc_smmu_unmap(dev, iova_addr, size); break; + case PLD_BUS_TYPE_PCIE: + ret = pld_pcie_smmu_unmap(dev, iova_addr, size); + break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: - case PLD_BUS_TYPE_PCIE: + case PLD_BUS_TYPE_IPCI: pr_err("Not supported on type %d\n", type); - ret = -ENODEV; break; default: pr_err("Invalid device type %d\n", type); @@ -1837,6 +1948,12 @@ int pld_get_user_msi_assignment(struct device *dev, char *user_name, pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_get_user_msi_assignment(dev, user_name, + num_vectors, + user_base_data, + base_vector); + break; default: pr_err("Invalid device type %d\n", type); ret = -EINVAL; @@ -1882,6 +1999,8 @@ int pld_srng_request_irq(struct device *dev, int irq, irq_handler_t handler, pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type %d\n", type); ret = -EINVAL; @@ -1922,6 +2041,8 @@ int pld_srng_free_irq(struct device *dev, int irq, void *dev_data) pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type %d\n", type); ret = -EINVAL; @@ -1952,6 +2073,8 @@ void pld_srng_enable_irq(struct device *dev, int irq) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type\n"); break; @@ -1979,6 +2102,8 @@ void pld_srng_disable_irq(struct device *dev, int irq) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type\n"); break; @@ -2003,6 +2128,9 @@ int pld_pci_read_config_word(struct pci_dev *pdev, int offset, uint16_t *val) case PLD_BUS_TYPE_SNOC_FW_SIM: break; case PLD_BUS_TYPE_PCIE_FW_SIM: + ret = pld_pcie_fw_sim_read_config_word(&pdev->dev, offset, val); + break; + case PLD_BUS_TYPE_IPCI: break; case PLD_BUS_TYPE_PCIE: ret = pci_read_config_word(pdev, offset, val); @@ -2041,6 +2169,8 @@ int pld_pci_write_config_word(struct pci_dev *pdev, int offset, uint16_t val) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type\n"); break; @@ -2073,6 +2203,8 @@ int pld_pci_read_config_dword(struct pci_dev *pdev, int offset, uint32_t *val) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type\n"); break; @@ -2105,6 +2237,8 @@ int pld_pci_write_config_dword(struct pci_dev *pdev, int offset, uint32_t val) break; case PLD_BUS_TYPE_SDIO: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type\n"); break; @@ -2140,6 +2274,9 @@ int pld_get_msi_irq(struct device *dev, unsigned int vector) pr_err("Not supported on type %d\n", type); ret = -ENODEV; break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_get_msi_irq(dev, vector); + break; default: pr_err("Invalid device type %d\n", type); ret = -EINVAL; @@ -2176,6 +2313,9 @@ void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low, case PLD_BUS_TYPE_SNOC_FW_SIM: pr_err("Not supported on type %d\n", type); break; + case PLD_BUS_TYPE_IPCI: + pld_ipci_get_msi_address(dev, msi_addr_low, msi_addr_high); + break; default: pr_err("Invalid device type %d\n", type); break; @@ -2204,6 +2344,7 @@ int pld_is_drv_connected(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: break; default: pr_err("Invalid device type %d\n", type); @@ -2235,6 +2376,8 @@ unsigned int pld_socinfo_get_serial_number(struct device *dev) break; case PLD_BUS_TYPE_SNOC_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; default: pr_err("Invalid device type %d\n", type); break; @@ -2262,6 +2405,8 @@ int pld_is_qmi_disable(struct device *dev) break; case PLD_BUS_TYPE_SNOC_FW_SIM: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_PCIE: case PLD_BUS_TYPE_SDIO: @@ -2312,6 +2457,9 @@ int pld_is_fw_down(struct device *dev) ifdev = pld_get_if_dev(dev); ret = pld_usb_is_fw_down(ifdev); break; + case PLD_BUS_TYPE_IPCI: + ret = pld_ipci_is_fw_down(dev); + break; default: pr_err("Invalid device type %d\n", type); ret = -EINVAL; @@ -2344,6 +2492,8 @@ int pld_force_assert_target(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SDIO: return -EINVAL; + case PLD_BUS_TYPE_IPCI: + return pld_ipci_force_assert_target(dev); default: pr_err("Invalid device type %d\n", type); return -EINVAL; @@ -2370,6 +2520,7 @@ int pld_collect_rddm(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: return 0; default: pr_err("Invalid device type %d\n", type); @@ -2397,6 +2548,7 @@ int pld_qmi_send_get(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: return 0; default: pr_err("Invalid device type %d\n", type); @@ -2424,6 +2576,7 @@ int pld_qmi_send_put(struct device *dev) case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: return 0; default: pr_err("Invalid device type %d\n", type); @@ -2457,6 +2610,7 @@ int pld_qmi_send(struct device *dev, int type, void *cmd, case PLD_BUS_TYPE_SNOC: case PLD_BUS_TYPE_SDIO: case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: return -EINVAL; default: pr_err("Invalid device type %d\n", bus_type); @@ -2484,6 +2638,7 @@ bool pld_is_fw_dump_skipped(struct device *dev) break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: default: break; } @@ -2501,6 +2656,7 @@ int pld_is_pdr(struct device *dev) break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: default: break; } @@ -2518,6 +2674,7 @@ int pld_is_fw_rejuvenate(struct device *dev) break; case PLD_BUS_TYPE_PCIE_FW_SIM: case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_IPCI: default: break; } @@ -2538,6 +2695,8 @@ bool pld_have_platform_driver_support(struct device *dev) case PLD_BUS_TYPE_SNOC_FW_SIM: case PLD_BUS_TYPE_SNOC: break; + case PLD_BUS_TYPE_IPCI: + break; case PLD_BUS_TYPE_SDIO: ret = pld_sdio_platform_driver_support(); break; @@ -2560,23 +2719,28 @@ int pld_idle_shutdown(struct device *dev, type = pld_get_bus_type(dev); switch (type) { - case PLD_BUS_TYPE_SDIO: - case PLD_BUS_TYPE_USB: - case PLD_BUS_TYPE_SNOC: - errno = shutdown_cb(dev); - break; - case PLD_BUS_TYPE_PCIE: - errno = pld_pcie_idle_shutdown(dev); - break; - case PLD_BUS_TYPE_PCIE_FW_SIM: - errno = pld_pcie_fw_sim_idle_shutdown(dev); - break; - case PLD_BUS_TYPE_SNOC_FW_SIM: - errno = pld_snoc_fw_sim_idle_shutdown(dev); - break; - default: - pr_err("Invalid device type %d\n", type); - break; + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + errno = shutdown_cb(dev); + break; + case PLD_BUS_TYPE_SNOC: + errno = pld_snoc_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_PCIE: + errno = pld_pcie_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + errno = pld_pcie_fw_sim_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_shutdown(dev); + break; + case PLD_BUS_TYPE_IPCI: + errno = pld_ipci_idle_shutdown(dev); + break; + default: + pr_err("Invalid device type %d\n", type); + break; } return errno; @@ -2593,24 +2757,68 @@ int pld_idle_restart(struct device *dev, type = pld_get_bus_type(dev); switch (type) { - case PLD_BUS_TYPE_SDIO: - case PLD_BUS_TYPE_USB: - case PLD_BUS_TYPE_SNOC: - errno = restart_cb(dev); - break; - case PLD_BUS_TYPE_PCIE: - errno = pld_pcie_idle_restart(dev); - break; - case PLD_BUS_TYPE_PCIE_FW_SIM: - errno = pld_pcie_fw_sim_idle_restart(dev); - break; - case PLD_BUS_TYPE_SNOC_FW_SIM: - errno = pld_snoc_fw_sim_idle_restart(dev); - break; - default: - pr_err("Invalid device type %d\n", type); - break; + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + errno = restart_cb(dev); + break; + case PLD_BUS_TYPE_SNOC: + errno = pld_snoc_idle_restart(dev); + break; + case PLD_BUS_TYPE_PCIE: + errno = pld_pcie_idle_restart(dev); + break; + case PLD_BUS_TYPE_PCIE_FW_SIM: + errno = pld_pcie_fw_sim_idle_restart(dev); + break; + case PLD_BUS_TYPE_SNOC_FW_SIM: + errno = pld_snoc_fw_sim_idle_restart(dev); + break; + case PLD_BUS_TYPE_IPCI: + errno = pld_ipci_idle_restart(dev); + break; + default: + pr_err("Invalid device type %d\n", type); + break; } return errno; } + +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +/** + * pld_get_audio_wlan_timestamp() - Get audio timestamp + * @dev: device pointer + * @type: trigger type + * @ts: audio timestamp + * + * This API can be used to get audio timestamp. + * + * Return: 0 if trigger to get audio timestamp is successful + * Non zero failure code for errors + */ +int pld_get_audio_wlan_timestamp(struct device *dev, + enum pld_wlan_time_sync_trigger_type type, + uint64_t *ts) +{ + int ret = 0; + enum pld_bus_type bus_type; + + bus_type = pld_get_bus_type(dev); + switch (bus_type) { + case PLD_BUS_TYPE_SNOC: + ret = pld_snoc_get_audio_wlan_timestamp(dev, type, ts); + break; + case PLD_BUS_TYPE_PCIE: + case PLD_BUS_TYPE_SNOC_FW_SIM: + case PLD_BUS_TYPE_PCIE_FW_SIM: + case PLD_BUS_TYPE_SDIO: + case PLD_BUS_TYPE_USB: + case PLD_BUS_TYPE_IPCI: + break; + default: + ret = -EINVAL; + break; + } + return ret; +} +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.c new file mode 100644 index 0000000000000000000000000000000000000000..a55a7f186f99fbb50b1991a62a6ec9d2d02a699a --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#include +#include +#include +#include + +#ifdef CONFIG_PLD_IPCI_ICNSS +#include +#endif + +#include "pld_internal.h" +#include "pld_ipci.h" + +#ifdef CONFIG_PLD_IPCI_ICNSS +/** + * pld_ipci_probe() - Probe function for platform driver + * @dev: device + * + * The probe function will be called when platform device + * is detected. + * + * Return: int + */ +static int pld_ipci_probe(struct device *dev) +{ + struct pld_context *pld_context; + int ret = 0; + + pld_context = pld_get_global_context(); + if (!pld_context) { + ret = -ENODEV; + goto out; + } + + ret = pld_add_dev(pld_context, dev, NULL, PLD_BUS_TYPE_IPCI); + if (ret) + goto out; + + return pld_context->ops->probe(dev, PLD_BUS_TYPE_IPCI, + NULL, NULL); + +out: + return ret; +} + +/** + * pld_ipci_remove() - Remove function for platform device + * @dev: device + * + * The remove function will be called when platform device + * is disconnected + * + * Return: void + */ +static void pld_ipci_remove(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + + if (!pld_context) + return; + + pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC); + + pld_del_dev(pld_context, dev); +} + +/** + * pld_ipci_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_ipci_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_IPCI, + NULL, NULL); + + return -ENODEV; +} + +/** + * pld_ipci_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_ipci_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_IPCI); +} + +/** + * pld_ipci_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_ipci_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_IPCI); +} + +/** + * pld_ipci_pm_suspend() - PM suspend callback function for power management + * @dev: device + * + * This function is to suspend the platform device when power management + * is enabled. + * + * Return: void + */ +static int pld_ipci_pm_suspend(struct device *dev) +{ + struct pld_context *pld_context; + pm_message_t state; + + state.event = PM_EVENT_SUSPEND; + pld_context = pld_get_global_context(); + return pld_context->ops->suspend(dev, PLD_BUS_TYPE_IPCI, state); +} + +/** + * pld_ipci_pm_resume() - PM 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_ipci_pm_resume(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + return pld_context->ops->resume(dev, PLD_BUS_TYPE_IPCI); +} + +/** + * pld_ipci_suspend_noirq() - Complete the actions started by suspend() + * @dev: device + * + * Complete the actions started by suspend(). Carry out any + * additional operations required for suspending the device that might be + * racing with its driver's interrupt handler, which is guaranteed not to + * run while suspend_noirq() is being executed. + * + * Return: 0 for success + * Non zero failure code for errors + */ +static int pld_ipci_suspend_noirq(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (pld_context->ops->suspend_noirq) + return pld_context->ops->suspend_noirq(dev, PLD_BUS_TYPE_IPCI); + return 0; +} + +/** + * pld_ipci_resume_noirq() - Prepare for the execution of resume() + * @pdev: device + * + * Prepare for the execution of resume() by carrying out any + * operations required for resuming the device that might be racing with + * its driver's interrupt handler, which is guaranteed not to run while + * resume_noirq() is being executed. + * + * Return: 0 for success + * Non zero failure code for errors + */ +static int pld_ipci_resume_noirq(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (pld_context->ops->resume_noirq) + return pld_context->ops->resume_noirq(dev, PLD_BUS_TYPE_IPCI); + + return 0; +} + +static int pld_ipci_uevent(struct device *dev, + struct icnss_uevent_data *uevent) +{ + struct pld_context *pld_context; + struct icnss_uevent_fw_down_data *uevent_data = NULL; + struct pld_uevent_data data = {0}; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (!pld_context->ops->uevent) + goto out; + + if (!uevent) + return -EINVAL; + + switch (uevent->uevent) { + case ICNSS_UEVENT_FW_CRASHED: + data.uevent = PLD_FW_CRASHED; + break; + case ICNSS_UEVENT_FW_DOWN: + if (!uevent->data) + return -EINVAL; + uevent_data = (struct icnss_uevent_fw_down_data *)uevent->data; + data.uevent = PLD_FW_DOWN; + data.fw_down.crashed = uevent_data->crashed; + break; + default: + goto out; + } + + pld_context->ops->uevent(dev, &data); +out: + return 0; +} + +#ifdef MULTI_IF_NAME +#define PLD_IPCI_OPS_NAME "pld_ipci_" MULTI_IF_NAME +#else +#define PLD_IPCI_OPS_NAME "pld_ipci" +#endif + +struct icnss_driver_ops pld_ipci_ops = { + .name = PLD_IPCI_OPS_NAME, + .probe = pld_ipci_probe, + .remove = pld_ipci_remove, + .shutdown = pld_ipci_shutdown, + .reinit = pld_ipci_reinit, + .crash_shutdown = pld_ipci_crash_shutdown, + .pm_suspend = pld_ipci_pm_suspend, + .pm_resume = pld_ipci_pm_resume, + .suspend_noirq = pld_ipci_suspend_noirq, + .resume_noirq = pld_ipci_resume_noirq, + .uevent = pld_ipci_uevent, +}; + +/** + * pld_ipci_register_driver() - Register platform device callback functions + * + * Return: int + */ +int pld_ipci_register_driver(void) +{ + return icnss_register_driver(&pld_ipci_ops); +} + +/** + * pld_ipci_unregister_driver() - Unregister platform device callback functions + * + * Return: void + */ +void pld_ipci_unregister_driver(void) +{ + icnss_unregister_driver(&pld_ipci_ops); +} + +/** + * pld_ipci_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_ipci_wlan_enable(struct device *dev, 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; + + if (!dev) + return -ENODEV; + + 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(dev, &cfg, icnss_mode, host_version); +} + +/** + * pld_ipci_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_ipci_wlan_disable(struct device *dev, enum pld_driver_mode mode) +{ + if (!dev) + return -ENODEV; + + return icnss_wlan_disable(dev, ICNSS_OFF); +} + +/** + * pld_ipci_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_ipci_get_soc_info(struct device *dev, struct pld_soc_info *info) +{ + int errno; + struct icnss_soc_info icnss_info = {0}; + + if (!info || !dev) + return -ENODEV; + + errno = icnss_get_soc_info(dev, &icnss_info); + if (errno) + return errno; + + info->v_addr = icnss_info.v_addr; + info->p_addr = icnss_info.p_addr; + info->chip_id = icnss_info.chip_id; + info->chip_family = icnss_info.chip_family; + info->board_id = icnss_info.board_id; + info->soc_id = icnss_info.soc_id; + info->fw_version = icnss_info.fw_version; + strlcpy(info->fw_build_timestamp, icnss_info.fw_build_timestamp, + sizeof(info->fw_build_timestamp)); + + return 0; +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.h b/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.h new file mode 100644 index 0000000000000000000000000000000000000000..8de7006803c2ae2af8945d3fc21edacf22a61b4f --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_ipci.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef __PLD_IPCI_H__ +#define __PLD_IPCI_H__ + +#ifdef CONFIG_PLD_IPCI_ICNSS +#include +#endif +#include "pld_internal.h" + +#ifndef CONFIG_PLD_IPCI_ICNSS +static inline int pld_ipci_register_driver(void) +{ + return 0; +} + +static inline void pld_ipci_unregister_driver(void) +{ +} + +static inline int pld_ipci_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version) +{ + return 0; +} + +static inline int pld_ipci_wlan_disable(struct device *dev, + enum pld_driver_mode mode) +{ + return 0; +} + +static inline int pld_ipci_get_soc_info(struct device *dev, + struct pld_soc_info *info) +{ + return 0; +} + +static inline int pld_ipci_power_on(struct device *dev) +{ + return 0; +} + +static inline int pld_ipci_power_off(struct device *dev) +{ + return 0; +} + +static inline int pld_ipci_idle_restart(struct device *dev) +{ + return 0; +} + +static inline int pld_ipci_idle_shutdown(struct device *dev) +{ + return 0; +} + +static inline int pld_ipci_force_assert_target(struct device *dev) +{ + return -EINVAL; +} + +static inline int pld_ipci_get_user_msi_assignment(struct device *dev, + char *user_name, + int *num_vectors, + uint32_t *user_base_data, + uint32_t *base_vector) +{ + return 0; +} + +static inline int pld_ipci_get_msi_irq(struct device *dev, unsigned int vector) +{ + return 0; +} + +static inline void pld_ipci_get_msi_address(struct device *dev, + uint32_t *msi_addr_low, + uint32_t *msi_addr_high) +{ +} + +static inline int pld_ipci_is_fw_down(struct device *dev) +{ + return 0; +} + +static inline int pld_ipci_set_fw_log_mode(struct device *dev, u8 fw_log_mode) +{ + return 0; +} + +#else +int pld_ipci_register_driver(void); +void pld_ipci_unregister_driver(void); +int pld_ipci_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version); +int pld_ipci_wlan_disable(struct device *dev, enum pld_driver_mode mode); +int pld_ipci_get_soc_info(struct device *dev, struct pld_soc_info *info); + +static inline int pld_ipci_power_on(struct device *dev) +{ + return icnss_power_on(dev); +} + +static inline int pld_ipci_power_off(struct device *dev) +{ + return icnss_power_off(dev); +} + +static inline int pld_ipci_idle_restart(struct device *dev) +{ + return icnss_idle_restart(dev); +} + +static inline int pld_ipci_idle_shutdown(struct device *dev) +{ + return icnss_idle_shutdown(dev); +} + +static inline int pld_ipci_force_assert_target(struct device *dev) +{ + return icnss_trigger_recovery(dev); +} + +static inline int pld_ipci_get_user_msi_assignment(struct device *dev, + char *user_name, + int *num_vectors, + uint32_t *user_base_data, + uint32_t *base_vector) +{ + return icnss_get_user_msi_assignment(dev, user_name, num_vectors, + user_base_data, base_vector); +} + +static inline int pld_ipci_get_msi_irq(struct device *dev, unsigned int vector) +{ + return icnss_get_msi_irq(dev, vector); +} + +static inline void pld_ipci_get_msi_address(struct device *dev, + uint32_t *msi_addr_low, + uint32_t *msi_addr_high) +{ + icnss_get_msi_address(dev, msi_addr_low, msi_addr_high); +} + +static inline int pld_ipci_is_fw_down(struct device *dev) +{ + return icnss_is_fw_down(); +} + +static inline int pld_ipci_set_fw_log_mode(struct device *dev, u8 fw_log_mode) +{ + return icnss_set_fw_log_mode(dev, fw_log_mode); +} + +#endif +#endif diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.c index ab91ddb0834ab59582347bb47af5210e2151e55a..d3a17dff765bca93937dd82a96b7719db26a44f1 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -91,6 +91,7 @@ static void pld_pcie_remove(struct pci_dev *pdev) return; osif_psoc_sync_unregister(&pdev->dev); + osif_psoc_sync_wait_for_ops(psoc_sync); pld_context = pld_get_global_context(); @@ -241,7 +242,7 @@ static void pld_pcie_notify_handler(struct pci_dev *pdev, int state) static void pld_pcie_uevent(struct pci_dev *pdev, uint32_t status) { struct pld_context *pld_context; - struct pld_uevent_data data; + struct pld_uevent_data data = {0}; pld_context = pld_get_global_context(); if (!pld_context) @@ -265,6 +266,51 @@ static void pld_pcie_uevent(struct pci_dev *pdev, uint32_t status) return; } +/** + * pld_pcie_update_event() - update wlan driver status callback function + * @pdev: PCIE device + * @cnss_uevent_data: driver uevent data + * + * This function will be called when platform driver wants to update wlan + * driver's status. + * + * Return: void + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +static int pld_pcie_update_event(struct pci_dev *pdev, + struct cnss_uevent_data *uevent_data) +{ + struct pld_context *pld_context; + struct pld_uevent_data data = {0}; + struct cnss_hang_event *hang_event; + + pld_context = pld_get_global_context(); + + if (!pld_context || !uevent_data) + return -EINVAL; + + switch (uevent_data->status) { + case CNSS_HANG_EVENT: + if (!uevent_data->data) + return -EINVAL; + hang_event = (struct cnss_hang_event *)uevent_data->data; + data.uevent = PLD_FW_HANG_EVENT; + data.hang_data.hang_event_data = hang_event->hang_event_data; + data.hang_data.hang_event_data_len = + hang_event->hang_event_data_len; + break; + default: + goto out; + } + + if (pld_context->ops->uevent) + pld_context->ops->uevent(&pdev->dev, &data); + +out: + return 0; +} +#endif + #ifdef FEATURE_RUNTIME_PM /** * pld_pcie_runtime_suspend() - PM runtime suspend @@ -535,6 +581,9 @@ struct cnss_wlan_driver pld_pcie_ops = { .crash_shutdown = pld_pcie_crash_shutdown, .modem_status = pld_pcie_notify_handler, .update_status = pld_pcie_uevent, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) + .update_event = pld_pcie_update_event, +#endif #ifdef CONFIG_PM .suspend = pld_pcie_suspend, .resume = pld_pcie_resume, diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.h b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.h index b53195ef7a9e650a5b2e2d746bb0bb9c351d4e4d..1b64336bcc780d9b590db32524116336ddfefc1d 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.h +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie.h @@ -37,7 +37,7 @@ #endif -#ifndef CONFIG_PLD_PCIE_CNSS +#if !defined(HIF_PCI) || defined(CONFIG_PLD_PCIE_FW_SIM) static inline int pld_pcie_register_driver(void) { return 0; @@ -153,6 +153,12 @@ pld_pcie_smmu_map(struct device *dev, return 0; } +static inline int +pld_pcie_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size) +{ + return 0; +} + static inline int pld_pcie_get_fw_files_for_target(struct device *dev, struct pld_fw_files *pfw_files, @@ -175,6 +181,12 @@ static inline void pld_pcie_link_down(struct device *dev) { } +static inline int pld_pcie_get_reg_dump(struct device *dev, uint8_t *buf, + uint32_t len) +{ + return 0; +} + static inline int pld_pcie_is_fw_down(struct device *dev) { return 0; @@ -438,6 +450,20 @@ pld_pcie_smmu_map(struct device *dev, return cnss_smmu_map(dev, paddr, iova_addr, size); } +#ifdef CONFIG_SMMU_S1_UNMAP +static inline int +pld_pcie_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size) +{ + return cnss_smmu_unmap(dev, iova_addr, size); +} +#else /* !CONFIG_SMMU_S1_UNMAP */ +static inline int +pld_pcie_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size) +{ + return 0; +} +#endif /* CONFIG_SMMU_S1_UNMAP */ + static inline int pld_pcie_prevent_l1(struct device *dev) { return cnss_pci_prevent_l1(dev); @@ -453,6 +479,21 @@ static inline void pld_pcie_link_down(struct device *dev) cnss_pci_link_down(dev); } +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0))) +static inline int pld_pcie_get_reg_dump(struct device *dev, uint8_t *buf, + uint32_t len) +{ + return cnss_pci_get_reg_dump(dev, buf, len); +} +#else +static inline int pld_pcie_get_reg_dump(struct device *dev, uint8_t *buf, + uint32_t len) +{ + return 0; +} +#endif + static inline int pld_pcie_is_fw_down(struct device *dev) { return cnss_pci_is_device_down(dev); @@ -578,7 +619,7 @@ static inline int pld_pcie_idle_shutdown(struct device *dev) static inline int pld_pcie_force_assert_target(struct device *dev) { - return cnss_force_fw_assert(dev); + return cnss_force_collect_rddm(dev); } static inline int pld_pcie_get_user_msi_assignment(struct device *dev, diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.c index 46f9ac281fe0663deecb6bfe60847a957951fdb9..ed4bf30651ed55dced2817c1138751923db1d30d 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -236,7 +236,7 @@ static void pld_pcie_fw_sim_notify_handler(struct pci_dev *pdev, int state) static void pld_pcie_fw_sim_uevent(struct pci_dev *pdev, uint32_t status) { struct pld_context *pld_context; - struct pld_uevent_data data; + struct pld_uevent_data data = {0}; pld_context = pld_get_global_context(); if (!pld_context) diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.h b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.h index 0eed0d5ab743dd46c8b77bc226b09fee5196a94c..566e54db0950c6143567bea23446c7a08519eaa4 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.h +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_pcie_fw_sim.h @@ -97,6 +97,12 @@ static inline int pld_pcie_fw_sim_request_irq(struct device *dev, int irq, return 0; } +static inline int pld_pcie_fw_sim_read_config_word(struct device *dev, + int offset, uint16_t *val) +{ + return 0; +} + static inline int pld_pcie_fw_sim_free_irq(struct device *dev, unsigned int ce_id, void *ctx) { @@ -169,6 +175,12 @@ static inline int pld_pcie_fw_sim_request_irq(struct device *dev, int irq, irqflags, devname, dev_data); } +static inline int pld_pcie_fw_sim_read_config_word(struct device *dev, + int offset, uint16_t *val) +{ + return cnss_fw_sim_read_config_word(dev, offset, val); +} + static inline int pld_pcie_fw_sim_free_irq(struct device *dev, int irq, void *dev_data) { diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.c index 356c58948047881391f8ea8c1afcde11885b860c..7b8553d1e9bbae9130e5235d09d3d55314942190 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -25,6 +25,9 @@ #ifdef CONFIG_PLD_SDIO_CNSS #include #endif +#ifdef CONFIG_PLD_SDIO_CNSS2 +#include +#endif #include "pld_common.h" #include "pld_internal.h" @@ -286,7 +289,79 @@ static struct sdio_device_id pld_sdio_id_table[] = { {}, }; -#ifdef CONFIG_PLD_SDIO_CNSS +#ifdef CONFIG_PLD_SDIO_CNSS2 +/** + * pld_sdio_reinit() - SSR re-initialize function for SDIO device + * @sdio_func: pointer to sdio device function + * @id: SDIO device ID + * + * During subsystem restart(SSR), this function will be called to + * re-initialize SDIO device. + * + * Return: int + */ +static int pld_sdio_reinit(struct sdio_func *sdio_func, + const struct sdio_device_id *id) +{ + /* TODO */ + return -ENODEV; +} + +/** + * pld_sdio_shutdown() - SSR shutdown function for SDIO device + * @sdio_func: pointer to sdio device function + * + * During SSR, this function will be called to shutdown SDIO device. + * + * Return: void + */ +static void pld_sdio_shutdown(struct sdio_func *sdio_func) +{ + /* TODO */ +} + +/** + * pld_sdio_crash_shutdown() - Crash shutdown function for SDIO device + * @sdio_func: pointer to sdio device function + * + * This function will be called when a crash is detected, it will shutdown + * the SDIO device. + * + * Return: void + */ +static void pld_sdio_crash_shutdown(struct sdio_func *sdio_func) +{ + /* TODO */ +} + +static void pld_sdio_uevent(struct sdio_func *sdio_func, uint32_t status) +{ + struct pld_context *pld_context; + struct device *dev = &sdio_func->dev; + struct pld_uevent_data data = {0}; + + pld_context = pld_get_global_context(); + + if (!pld_context) + return; + + switch (status) { + case CNSS_RECOVERY: + data.uevent = PLD_FW_RECOVERY_START; + break; + case CNSS_FW_DOWN: + data.uevent = PLD_FW_DOWN; + break; + default: + goto out; + } + + if (pld_context->ops->uevent) + pld_context->ops->uevent(dev, &data); +out: + return; +} + struct cnss_sdio_wlan_driver pld_sdio_ops = { .name = "pld_sdio", .id_table = pld_sdio_id_table, @@ -295,6 +370,7 @@ struct cnss_sdio_wlan_driver pld_sdio_ops = { .reinit = pld_sdio_reinit, .shutdown = pld_sdio_shutdown, .crash_shutdown = pld_sdio_crash_shutdown, + .update_status = pld_sdio_uevent, #ifdef CONFIG_PM .suspend = pld_sdio_suspend, .resume = pld_sdio_resume, @@ -320,6 +396,40 @@ void pld_sdio_unregister_driver(void) { cnss_sdio_wlan_unregister_driver(&pld_sdio_ops); } + +/** + * pld_sdio_wlan_enable() - Enable WLAN + * @dev: device + * @config: NA + * @mode: WLAN mode + * @host_version: host software version + * + * This function enables WLAN FW. It passed + * WLAN mode and host software version to FW. + * + * Return: 0 for success + * Non zero failure code for errors + */ +int pld_sdio_wlan_enable(struct device *dev, 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; + + 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(dev, &cfg, cnss_mode, host_version); +} + #else #ifdef CONFIG_PM diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.h b/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.h index 354eec1a795e0e59765b4c641a01c0f9a4c6631e..66bd846f0359f3730b94cdfb311e62af118d6eaf 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.h +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_sdio.h @@ -192,6 +192,71 @@ static inline void pld_hif_sdio_release_ramdump_mem(unsigned long *address) { } #else +#ifdef CONFIG_PLD_SDIO_CNSS2 +#include + +/** + * pld_sdio_get_sdio_al_client_handle() - Get the sdio al client handle + * @func: SDIO function pointer + * + * Return: On success return client handle from al via cnss, else NULL + */ +static inline struct sdio_al_client_handle *pld_sdio_get_sdio_al_client_handle +( +struct sdio_func *func +) +{ + if (!func) + return NULL; + + return cnss_sdio_wlan_get_sdio_al_client_handle(func); +} + +/** + * pld_sdio_register_sdio_al_channel() - Register channel with sdio al + * @al_client: SDIO al client handle + * @ch_data: SDIO client channel data + * + * Return: Channel handle on success, else null + */ +static inline struct sdio_al_channel_handle *pld_sdio_register_sdio_al_channel +( +struct sdio_al_client_handle *al_client, +struct sdio_al_channel_data *ch_data +) +{ + if (!al_client || !ch_data) + return NULL; + + return cnss_sdio_wlan_register_sdio_al_channel(ch_data); +} + +/** + * pld_sdio_unregister_sdio_al_channel() - Unregister the sdio al channel + * @ch_handle: SDIO al channel handle + * + * Return: None + */ +static inline void pld_sdio_unregister_sdio_al_channel +( +struct sdio_al_channel_handle *ch_handle +) +{ + cnss_sdio_wlan_unregister_sdio_al_channel(ch_handle); +} + +int pld_sdio_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, const char *host_version); +#else +static inline int pld_sdio_wlan_enable(struct device *dev, + struct pld_wlan_enable_cfg *config, + enum pld_driver_mode mode, + const char *host_version) +{ + return 0; +} +#endif /* CONFIG_PLD_SDIO_CNSS2 */ + /** * pld_hif_sdio_get_virt_ramdump_mem() - Get virtual ramdump memory * @dev: device diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.c index df9b160eee199ab22672f9503b23594c96358583..a5e7c8c804865a55f4f4522991d4b285ef4bfd1a 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +30,46 @@ #include "osif_psoc_sync.h" #ifdef CONFIG_PLD_SNOC_ICNSS +/** + * + *pld_snoc_idle_restart_cb() - Perform idle restart + * @pdev: platform device + * + *This function will be called if there is an idle restart request + * + * Return: int + **/ +static int pld_snoc_idle_restart_cb(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->idle_restart) + return pld_context->ops->idle_restart(dev, PLD_BUS_TYPE_SNOC); + + return -ENODEV; +} + +/** + * pld_snoc_idle_shutdown_cb() - Perform idle shutdown + * @pdev: PCIE device + * @id: PCIE device ID + * + * This function will be called if there is an idle shutdown request + * + * Return: int + */ +static int pld_snoc_idle_shutdown_cb(struct device *dev) +{ + struct pld_context *pld_context; + + pld_context = pld_get_global_context(); + if (pld_context->ops->shutdown) + return pld_context->ops->idle_shutdown(dev, PLD_BUS_TYPE_SNOC); + + return -ENODEV; +} + /** * pld_snoc_probe() - Probe function for platform driver * @dev: device @@ -240,12 +280,69 @@ static int pld_snoc_resume_noirq(struct device *dev) return 0; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) +static int pld_update_hang_evt_data(struct icnss_uevent_hang_data *evt_data, + struct pld_uevent_data *data) +{ + if (!evt_data || !data) + return -EINVAL; + + data->hang_data.hang_event_data = evt_data->hang_event_data; + data->hang_data.hang_event_data_len = evt_data->hang_event_data_len; + return 0; +} + +static int pld_snoc_uevent(struct device *dev, + struct icnss_uevent_data *uevent) +{ + struct pld_context *pld_context; + struct icnss_uevent_fw_down_data *fw_down_data = NULL; + struct icnss_uevent_hang_data *hang_data = NULL; + struct pld_uevent_data data = {0}; + + pld_context = pld_get_global_context(); + if (!pld_context) + return -EINVAL; + + if (!pld_context->ops->uevent) + goto out; + + if (!uevent) + return -EINVAL; + + switch (uevent->uevent) { + case ICNSS_UEVENT_FW_CRASHED: + data.uevent = PLD_FW_CRASHED; + break; + case ICNSS_UEVENT_FW_DOWN: + if (!uevent->data) + return -EINVAL; + fw_down_data = (struct icnss_uevent_fw_down_data *)uevent->data; + data.uevent = PLD_FW_DOWN; + data.fw_down.crashed = fw_down_data->crashed; + break; + case ICNSS_UEVENT_HANG_DATA: + if (!uevent->data) + return -EINVAL; + hang_data = (struct icnss_uevent_hang_data *)uevent->data; + data.uevent = PLD_FW_HANG_EVENT; + pld_update_hang_evt_data(hang_data, &data); + break; + default: + goto out; + } + + pld_context->ops->uevent(dev, &data); +out: + return 0; +} +#else static int pld_snoc_uevent(struct device *dev, struct icnss_uevent_data *uevent) { struct pld_context *pld_context; - struct icnss_uevent_fw_down_data *uevent_data = NULL; - struct pld_uevent_data data; + struct icnss_uevent_fw_down_data *fw_down_data = NULL; + struct pld_uevent_data data = {0}; pld_context = pld_get_global_context(); if (!pld_context) @@ -264,9 +361,9 @@ static int pld_snoc_uevent(struct device *dev, case ICNSS_UEVENT_FW_DOWN: if (!uevent->data) return -EINVAL; - uevent_data = (struct icnss_uevent_fw_down_data *)uevent->data; + fw_down_data = (struct icnss_uevent_fw_down_data *)uevent->data; data.uevent = PLD_FW_DOWN; - data.fw_down.crashed = uevent_data->crashed; + data.fw_down.crashed = fw_down_data->crashed; break; default: goto out; @@ -276,6 +373,7 @@ static int pld_snoc_uevent(struct device *dev, out: return 0; } +#endif #ifdef MULTI_IF_NAME #define PLD_SNOC_OPS_NAME "pld_snoc_" MULTI_IF_NAME @@ -295,6 +393,8 @@ struct icnss_driver_ops pld_snoc_ops = { .suspend_noirq = pld_snoc_suspend_noirq, .resume_noirq = pld_snoc_resume_noirq, .uevent = pld_snoc_uevent, + .idle_restart = pld_snoc_idle_restart_cb, + .idle_shutdown = pld_snoc_idle_shutdown_cb, }; /** diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.h b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.h index 5b9acd2ecb8e42ee488c670f899adf22f67c185b..ab4221967e66b863873f8995ccb8eee8fcd3e5e9 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.h +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -157,6 +157,27 @@ static inline int pld_snoc_is_fw_rejuvenate(void) static inline void pld_snoc_block_shutdown(bool status) { } + +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +static inline int +pld_snoc_get_audio_wlan_timestamp(struct device *dev, + enum pld_wlan_time_sync_trigger_type type, + uint64_t *ts) +{ + return 0; +} +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ + +static inline int pld_snoc_idle_restart(struct device *dev) +{ + return 0; +} + +static inline int pld_snoc_idle_shutdown(struct device *dev) +{ + return 0; +} + #else int pld_snoc_register_driver(void); void pld_snoc_unregister_driver(void); @@ -166,6 +187,29 @@ int pld_snoc_wlan_enable(struct device *dev, int pld_snoc_wlan_disable(struct device *dev, enum pld_driver_mode mode); int pld_snoc_get_soc_info(struct device *dev, struct pld_soc_info *info); +#ifdef FEATURE_WLAN_TIME_SYNC_FTM +/** + * pld_snoc_get_audio_wlan_timestamp() - Get audio timestamp + * @dev: device + * @type: trigger type + * @ts: timestamp + * + * Return audio timestamp to the ts. + * + * Return: 0 for success + * Non zero failure code for errors + */ +static inline int +pld_snoc_get_audio_wlan_timestamp(struct device *dev, + enum pld_wlan_time_sync_trigger_type type, + uint64_t *ts) +{ + if (!dev) + return -ENODEV; + + return 0; +} +#endif /* FEATURE_WLAN_TIME_SYNC_FTM */ static inline int pld_snoc_ce_request_irq(struct device *dev, unsigned int ce_id, irqreturn_t (*handler)(int, void *), @@ -316,5 +360,15 @@ static inline void pld_snoc_block_shutdown(bool status) { icnss_block_shutdown(status); } + +static inline int pld_snoc_idle_restart(struct device *dev) +{ + return icnss_idle_restart(dev); +} + +static inline int pld_snoc_idle_shutdown(struct device *dev) +{ + return icnss_idle_shutdown(dev); +} #endif #endif diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc_fw_sim.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc_fw_sim.c index 94c235971d9e483f5b8800142ac95cf14fb85ab4..54d38c377352715aecd053166dbbefe7d889ece8 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc_fw_sim.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_snoc_fw_sim.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -229,7 +229,7 @@ static int pld_snoc_fw_sim_uevent(struct device *dev, { struct pld_context *pld_context; struct icnss_uevent_fw_down_data *uevent_data = NULL; - struct pld_uevent_data data; + struct pld_uevent_data data = {0}; pld_context = pld_get_global_context(); if (!pld_context) diff --git a/drivers/staging/qcacld-3.0/core/pld/src/pld_usb.c b/drivers/staging/qcacld-3.0/core/pld/src/pld_usb.c index 2f91f9c5cd996227245feb355268c0da9601d328..c50d34c641da1acc06d8603febc6b43cec0be40d 100644 --- a/drivers/staging/qcacld-3.0/core/pld/src/pld_usb.c +++ b/drivers/staging/qcacld-3.0/core/pld/src/pld_usb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -225,7 +225,7 @@ static void pld_usb_shutdown(struct usb_interface *interface) static void pld_usb_uevent(struct usb_interface *interface, uint32_t status) { struct pld_context *pld_context; - struct pld_uevent_data data; + struct pld_uevent_data data = {0}; struct usb_device *pdev = interface_to_usbdev(interface); pld_context = pld_get_global_context(); diff --git a/drivers/staging/qcacld-3.0/core/sap/inc/sap_api.h b/drivers/staging/qcacld-3.0/core/sap/inc/sap_api.h index d25e1329e6458c13d39ebe9cb2cd75b3ba7e930b..5f3eff964c34e7a2a670ca9574886345114fe287 100644 --- a/drivers/staging/qcacld-3.0/core/sap/inc/sap_api.h +++ b/drivers/staging/qcacld-3.0/core/sap/inc/sap_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -229,7 +229,7 @@ typedef enum { * -------------------------------------------------------------------------*/ typedef struct sap_StartBssCompleteEvent_s { uint8_t status; - uint8_t operatingChannel; + uint32_t operating_chan_freq; enum phy_ch_width ch_width; uint16_t staId; /* self StaID */ uint8_t sessionId; /* SoftAP SME session ID */ @@ -298,6 +298,7 @@ typedef struct sap_StationDisassocCompleteEvent_s { int tx_rate; int rx_rate; uint32_t rx_mc_bc_cnt; + uint32_t rx_retry_cnt; } tSap_StationDisassocCompleteEvent; typedef struct sap_StationSetKeyCompleteEvent_s { @@ -338,38 +339,41 @@ typedef struct sap_MaxAssocExceededEvent_s { /** * sap_acs_ch_selected_s - the structure to hold the selected channels - * @pri_channel: Holds the ACS selected primary channel - * @sec_channel: Holds the ACS selected secondary channel + * @pri_chan_freq: Holds the ACS selected primary channel frequency + * @ht_sec_ch_freq: Holds the ACS selected secondary ht channel frequency + * @vht_seg0_center_ch: Holds the ACS selected center channel of vht seg0 + * @vht_seg1_center_ch: Holds the ACS selected center channel of vht seg1 + * @ch_width: Holds the ACS selected channel bandwidth * * Holds the primary and secondary channel selected by ACS and is * used to send it to the HDD. */ struct sap_ch_selected_s { - uint16_t pri_ch; - uint16_t ht_sec_ch; - uint16_t vht_seg0_center_ch; - uint16_t vht_seg1_center_ch; + uint32_t pri_ch_freq; + uint32_t ht_sec_ch_freq; + uint16_t vht_seg0_center_ch_freq; + uint16_t vht_seg1_center_ch_freq; uint16_t ch_width; }; /** * struct sap_acs_scan_complete_event - acs scan complete event * @status: status of acs scan - * @channellist: acs scan channels + * @freq_list: acs scan channel frequency list * @num_of_channels: number of channels */ struct sap_acs_scan_complete_event { uint8_t status; - uint8_t *channellist; + uint32_t *freq_list; uint8_t num_of_channels; }; /** * struct sap_ch_change_ind - channel change indication - * @new_chan: channel to change + * @new_chan_freq: channel frequency to change to */ struct sap_ch_change_ind { - uint16_t new_chan; + uint32_t new_chan_freq; }; /* @@ -426,31 +430,31 @@ struct sap_acs_cfg { /* ACS Algo Input */ uint8_t acs_mode; eCsrPhyMode hw_mode; - uint8_t start_ch; - uint8_t end_ch; - uint8_t *ch_list; + uint32_t start_ch_freq; + uint32_t end_ch_freq; + uint32_t *freq_list; uint8_t ch_list_count; - uint8_t *master_ch_list; + uint32_t *master_freq_list; uint8_t master_ch_list_count; #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE uint8_t skip_scan_status; - uint8_t skip_scan_range1_stch; - uint8_t skip_scan_range1_endch; - uint8_t skip_scan_range2_stch; - uint8_t skip_scan_range2_endch; + uint32_t skip_scan_range1_stch; + uint32_t skip_scan_range1_endch; + uint32_t skip_scan_range2_stch; + uint32_t skip_scan_range2_endch; #endif uint16_t ch_width; - uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; - uint8_t pcl_channels_weight_list[QDF_MAX_NUM_CHAN]; + uint32_t pcl_chan_freq[NUM_CHANNELS]; + uint8_t pcl_channels_weight_list[NUM_CHANNELS]; uint32_t pcl_ch_count; uint8_t is_ht_enabled; uint8_t is_vht_enabled; /* ACS Algo Output */ - uint8_t pri_ch; - uint8_t ht_sec_ch; - uint8_t vht_seg0_center_ch; - uint8_t vht_seg1_center_ch; + uint32_t pri_ch_freq; + uint32_t ht_sec_ch_freq; + uint32_t vht_seg0_center_ch_freq; + uint32_t vht_seg1_center_ch_freq; uint32_t band; }; @@ -476,8 +480,8 @@ struct sap_config { bool ieee80211d; /* Specify if 11D is enabled or disabled */ struct qdf_mac_addr deny_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */ struct qdf_mac_addr self_macaddr; /* self macaddress or BSSID */ - uint8_t channel; /* Operation channel */ - uint8_t sec_ch; + uint32_t chan_freq; /* Operation channel frequency */ + uint32_t sec_ch_freq; struct ch_params ch_params; uint32_t ch_width_orig; uint8_t max_num_sta; /* maximum number of STAs in station table */ @@ -561,13 +565,13 @@ typedef struct sSapDfsInfo { qdf_mc_timer_t sap_dfs_cac_timer; uint8_t sap_radar_found_status; /* - * New channel to move to when a Radar is + * New channel frequency to move to when a Radar is * detected on current Channel */ - uint8_t target_channel; + uint32_t target_chan_freq; uint8_t ignore_cac; eSapDfsCACState_t cac_state; - uint8_t user_provided_target_channel; + uint32_t user_provided_target_chan_freq; /* * Requests for Channel Switch Announcement IE @@ -863,9 +867,9 @@ QDF_STATUS wlan_sap_get_pre_cac_vdev_id(mac_handle_t handle, uint8_t *vdev_id); * wlansap_check_cc_intf() - Get interfering concurrent channel * @sap_ctx: SAP context pointer * - * Determine if a Concurrent Channel is interfering. + * Determine if a concurrent channel is interfering. * - * Return: Channel number of the interfering channel, or 0 if none. + * Return: Channel freq (Mhz) of the interfering channel, or 0 if none. */ uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx); #endif @@ -915,7 +919,7 @@ QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx, /** * wlansap_set_channel_change_with_csa() - Set channel change with CSA * @sap_ctx: Pointer to SAP context - * @targetChannel: Target channel + * @target_chan_freq: Target channel frequncy * @target_bw: Target bandwidth * @strict: if true switch to the requested channel always, fail * otherwise @@ -926,22 +930,10 @@ QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx, * Return: QDF_STATUS */ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, - uint32_t targetChannel, + uint32_t target_chan_freq, enum phy_ch_width target_bw, bool strict); -/** - * wlansap_set_key_sta() - set keys for a stations. - * @sap_ctx: Pointer to the SAP context - * @key_info : tCsrRoamSetKey structure for the station - * - * This api function provides for Ap App/HDD to set key for a station. - * - * Return: The QDF_STATUS code associated with performing the operation - * QDF_STATUS_SUCCESS: Success - */ -QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx, - tCsrRoamSetKey *key_info); /** * wlan_sap_getstation_ie_information() - RSNIE Population @@ -980,6 +972,18 @@ QDF_STATUS wlansap_get_acl_accept_list(struct sap_context *sap_ctx, struct qdf_mac_addr *pAcceptList, uint8_t *nAcceptList); +/** + * wlansap_is_channel_present_in_acs_list() - Freq present in ACS list or not + * @freq: Frequency to be searched + * @ch_freq_list: channel frequency list. + * @ch_count: Channel frequency list count + * + * Return: True is found, false otherwise + */ +bool wlansap_is_channel_present_in_acs_list(uint32_t freq, + uint32_t *ch_freq_list, + uint8_t ch_count); + /** * wlansap_get_acl_deny_list() - Get ACL deny list * @sap_ctx: Pointer to the SAP context @@ -1050,13 +1054,13 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, * */ QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, - uint8_t target_channel); + uint32_t target_chan_freq); /** * wlansap_get_sec_channel() - get the secondary sap channel * @sec_ch_offset: secondary channel offset. - * @op_channel: Operating sap channel. - * @sec_channel: channel to be filled. + * @op_chan_freq: Operating sap channel frequency. + * @sec_chan_freq: channel frequency to be filled. * * This API will get the secondary sap channel from the offset, and * operating channel. @@ -1065,8 +1069,8 @@ QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, * */ void wlansap_get_sec_channel(uint8_t sec_ch_offset, - uint8_t op_channel, - uint8_t *sec_channel); + uint32_t op_chan_freq, + uint32_t *sec_chan_freq); /** * wlansap_start_beacon_req() - Send Start Beaconing Request @@ -1157,7 +1161,7 @@ QDF_STATUS wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle); /** * wlansap_set_dfs_target_chnl() - Set target channel * @mac_handle: Opaque handle for the global MAC context - * @target_channel: target channel to be set + * @target_chan_freq: target channel frequency to be set * * This API is used to set next target chnl as provided channel. * you can provide any valid channel to this API. @@ -1165,7 +1169,7 @@ QDF_STATUS wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle); * Return: The QDF_STATUS code associated with performing the operation */ QDF_STATUS wlansap_set_dfs_target_chnl(mac_handle_t mac_handle, - uint8_t target_channel); + uint32_t target_chan_freq); /** * wlan_sap_get_roam_profile() - Returns sap roam profile. @@ -1235,7 +1239,7 @@ void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx, void sap_config_acs_result(mac_handle_t mac_handle, struct sap_context *sap_ctx, - uint32_t sec_ch); + uint32_t sec_ch_freq); QDF_STATUS wlansap_update_sap_config_add_ie(struct sap_config *config, const uint8_t *pAdditionIEBuffer, @@ -1246,10 +1250,10 @@ QDF_STATUS wlansap_reset_sap_config_add_ie(struct sap_config *config, eUpdateIEsType updateType); void wlansap_extend_to_acs_range(mac_handle_t mac_handle, - uint8_t *startChannelNum, - uint8_t *endChannelNum, - uint8_t *bandStartChannel, - uint8_t *bandEndChannel); + uint32_t *start_ch_freq, + uint32_t *end_ch_freq, + uint32_t *bandStartChannel, + uint32_t *bandEndChannel); /** * wlansap_set_dfs_nol() - Set dfs nol @@ -1269,6 +1273,20 @@ static inline QDF_STATUS wlansap_set_dfs_nol(struct sap_context *sap_ctx, } #endif +/** + * wlan_sap_set_dfs_pri_multiplier() - Set dfs_pri_multiplier + * @mac_handle: Opaque handle to the global MAC context + * + * Return: none + */ +#ifdef DFS_PRI_MULTIPLIER +void wlan_sap_set_dfs_pri_multiplier(mac_handle_t mac_handle); +#else +static inline void wlan_sap_set_dfs_pri_multiplier(mac_handle_t mac_handle) +{ +} +#endif + /** * wlan_sap_set_vendor_acs() - Set vendor specific acs in sap context * @sap_context: SAP context @@ -1408,15 +1426,24 @@ QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx, /** * wlansap_filter_ch_based_acs() -filter out channel based on acs * @sap_ctx: sap context - * @ch_list: pointer to channel list + * @ch_freq_list: pointer to channel frequency list * @ch_cnt: channel number of channel list * * Return: QDF_STATUS */ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, - uint8_t *ch_list, + uint32_t *ch_freq_list, uint32_t *ch_cnt); +/** + * wlansap_is_6ghz_included_in_acs_range() - check 6ghz channel included in + * ACS range + * @sap_ctx: sap context + * + * Return: QDF_STATUS + */ +bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx); + /** * wlansap_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP * restart @@ -1426,10 +1453,10 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, * unsafe channels. So, the PCL is validated with the ACS range to provide * a safe channel for the SAP to restart. * - * Return: Channel number to restart SAP in case of success. In case of any + * Return: Chan freq num to restart SAP in case of success. In case of any * failure, the channel number returned is zero. */ -uint8_t +uint32_t wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx); /** @@ -1440,9 +1467,25 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx); * avoid conflict with modem N79. * Sap/p2p go channel restore to 5G channel when 5G band enabled. * - * Return - restart channel + * Return - restart channel in MHZ */ -uint8_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); +qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); + +/** + * sap_acquire_vdev_ref() - Increment reference count for vdev object + * @psoc: Object Manager PSoC object + * @sap_ctx: to store vdev object pointer + * @session_id: used to get vdev object + * + * This function is used to increment vdev object reference count and store + * vdev pointer in sap_ctx. + * + * Return: QDF_STATUS_SUCCESS - If able to get vdev object reference + * else qdf status failure codes + */ +QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc, + struct sap_context *sap_ctx, + uint8_t session_id); /** * sap_dump_acs_channel() - dump acs channel list @@ -1454,6 +1497,13 @@ uint8_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); */ void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg); +/** + * sap_release_vdev_ref() - Decrement reference count for vdev object + * @sap_ctx: for which vdev reference is to be decremented + * + * Return: None + */ +void sap_release_vdev_ref(struct sap_context *sap_ctx); #ifdef __cplusplus } #endif diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_api_link_cntl.c b/drivers/staging/qcacld-3.0/core/sap/src/sap_api_link_cntl.c index 120f37514dc22c2acc0250354fef7c73081be70f..f1ff2232f9ac22d28d79d8ba5299c613f2ea9e20 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_api_link_cntl.c +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_api_link_cntl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -95,34 +95,38 @@ void sap_config_acs_result(mac_handle_t mac_handle, struct sap_context *sap_ctx, - uint32_t sec_ch) + uint32_t sec_ch_freq) { - uint32_t channel = sap_ctx->acs_cfg->pri_ch; struct ch_params ch_params = {0}; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); ch_params.ch_width = sap_ctx->acs_cfg->ch_width; - wlan_reg_set_channel_params(mac_ctx->pdev, channel, sec_ch, - &ch_params); + wlan_reg_set_channel_params_for_freq( + mac_ctx->pdev, sap_ctx->acs_cfg->pri_ch_freq, + sec_ch_freq, &ch_params); sap_ctx->acs_cfg->ch_width = ch_params.ch_width; - if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_40MHZ) - sap_ctx->acs_cfg->vht_seg0_center_ch = - ch_params.center_freq_seg0; + if (sap_ctx->acs_cfg->ch_width > CH_WIDTH_40MHZ || + WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->acs_cfg->pri_ch_freq)) + sap_ctx->acs_cfg->vht_seg0_center_ch_freq = + ch_params.mhz_freq_seg0; else - sap_ctx->acs_cfg->vht_seg0_center_ch = 0; + sap_ctx->acs_cfg->vht_seg0_center_ch_freq = 0; - if (sap_ctx->acs_cfg->ch_width == CH_WIDTH_80P80MHZ) - sap_ctx->acs_cfg->vht_seg1_center_ch = - ch_params.center_freq_seg1; + if (sap_ctx->acs_cfg->ch_width == CH_WIDTH_80P80MHZ || + (sap_ctx->acs_cfg->ch_width == CH_WIDTH_160MHZ)) + sap_ctx->acs_cfg->vht_seg1_center_ch_freq = + ch_params.mhz_freq_seg1; else - sap_ctx->acs_cfg->vht_seg1_center_ch = 0; + sap_ctx->acs_cfg->vht_seg1_center_ch_freq = 0; if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq - 20; else if (ch_params.sec_ch_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq + 20; else - sap_ctx->acs_cfg->ht_sec_ch = 0; + sap_ctx->acs_cfg->ht_sec_ch_freq = 0; } /** @@ -199,7 +203,7 @@ static inline void wlansap_send_acs_success_event(struct sap_context *sap_ctx, } #endif -static uint8_t +static uint32_t wlansap_calculate_chan_from_scan_result(mac_handle_t mac_handle, struct sap_context *sap_ctx, uint32_t scan_id) @@ -207,7 +211,7 @@ wlansap_calculate_chan_from_scan_result(mac_handle_t mac_handle, struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); qdf_list_t *list = NULL; struct scan_filter *filter; - uint8_t oper_channel = SAP_CHANNEL_NOT_SELECTED; + uint32_t oper_channel = SAP_CHANNEL_NOT_SELECTED; filter = qdf_mem_malloc(sizeof(*filter)); @@ -253,15 +257,15 @@ wlansap_filter_unsafe_ch(struct wlan_objmgr_psoc *psoc, * the acs channel list before chosing one of them as a default channel */ for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) { - if (!policy_mgr_is_safe_channel(psoc, - sap_ctx->acs_cfg->ch_list[i])) { - sap_debug("unsafe ch %d removed from acs list", - sap_ctx->acs_cfg->ch_list[i]); + if (!policy_mgr_is_safe_channel( + psoc, sap_ctx->acs_cfg->freq_list[i])) { + sap_debug("unsafe freq %d removed from acs list", + sap_ctx->acs_cfg->freq_list[i]); continue; } /* Add only safe channels to the acs cfg ch list */ - sap_ctx->acs_cfg->ch_list[num_safe_ch++] = - sap_ctx->acs_cfg->ch_list[i]; + sap_ctx->acs_cfg->freq_list[num_safe_ch++] = + sap_ctx->acs_cfg->freq_list[i]; } sap_debug("Updated ACS ch list len %d", num_safe_ch); @@ -277,23 +281,23 @@ wlan_sap_filter_non_preferred_channels(struct wlan_objmgr_pdev *pdev, bool preferred_freq_found = false; for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) { - if (sap_ctx->acs_cfg->ch_list[i] == 12 || - sap_ctx->acs_cfg->ch_list[i] == 13 || - sap_ctx->acs_cfg->ch_list[i] == 14) { - sap_debug("Skip channel %d if preferred channel present", - sap_ctx->acs_cfg->ch_list[i]); + if (sap_ctx->acs_cfg->freq_list[i] == 2467 || + sap_ctx->acs_cfg->freq_list[i] == 2472 || + sap_ctx->acs_cfg->freq_list[i] == 2477) { + sap_debug("Skip freq %d if preferred freq present", + sap_ctx->acs_cfg->freq_list[i]); continue; } - sap_ctx->acs_cfg->ch_list[num_ch++] = - sap_ctx->acs_cfg->ch_list[i]; + sap_ctx->acs_cfg->freq_list[num_ch++] = + sap_ctx->acs_cfg->freq_list[i]; preferred_freq_found = true; } if (!preferred_freq_found) { - sap_debug("No preferred ch, list unchanged"); + sap_debug("No preferred freq, list unchanged"); return; } - sap_debug("preferred channel found updated ACS ch list len %d", + sap_debug("preferred frequencies found updated ACS ch list len %d", num_ch); sap_ctx->acs_cfg->ch_list_count = num_ch; } @@ -304,7 +308,7 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, uint32_t scanid, eCsrScanStatus scan_status) { - uint8_t oper_channel = SAP_CHANNEL_NOT_SELECTED; + uint32_t oper_channel = SAP_CHANNEL_NOT_SELECTED; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); host_log_acs_scan_done(acs_scan_done_status_str(scan_status), @@ -314,19 +318,18 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, wlansap_filter_unsafe_ch(mac_ctx->psoc, sap_ctx); wlan_sap_filter_non_preferred_channels(mac_ctx->pdev, sap_ctx); - if (!sap_ctx->acs_cfg->ch_list_count) { oper_channel = sap_select_default_oper_chan(mac_ctx, sap_ctx->acs_cfg); - sap_ctx->channel = oper_channel; - sap_ctx->acs_cfg->pri_ch = oper_channel; - sap_config_acs_result(mac_handle, sap_ctx, 0); + sap_ctx->chan_freq = oper_channel; + sap_ctx->acs_cfg->pri_ch_freq = oper_channel; + sap_config_acs_result(mac_handle, sap_ctx, + sap_ctx->acs_cfg->ht_sec_ch_freq); sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; sap_ctx->sap_status = eSAP_STATUS_SUCCESS; goto close_session; } - if (eCSR_SCAN_SUCCESS != scan_status) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("CSR scan_status = eCSR_SCAN_ABORT/FAILURE (%d), choose default channel"), @@ -334,10 +337,10 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, oper_channel = sap_select_default_oper_chan(mac_ctx, sap_ctx->acs_cfg); - sap_ctx->channel = oper_channel; - sap_ctx->acs_cfg->pri_ch = oper_channel; + sap_ctx->chan_freq = oper_channel; + sap_ctx->acs_cfg->pri_ch_freq = oper_channel; sap_config_acs_result(mac_handle, sap_ctx, - sap_ctx->acs_cfg->ht_sec_ch); + sap_ctx->acs_cfg->ht_sec_ch_freq); sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; sap_ctx->sap_status = eSAP_STATUS_SUCCESS; goto close_session; @@ -351,30 +354,27 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, if (oper_channel == SAP_CHANNEL_NOT_SELECTED) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, FL("No suitable channel, so select default channel")); - sap_ctx->channel = - sap_select_default_oper_chan(mac_ctx, - sap_ctx->acs_cfg); - sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; - } else { - /* Valid Channel Found from scan results. */ - sap_ctx->acs_cfg->pri_ch = oper_channel; - sap_ctx->channel = oper_channel; + oper_channel = sap_select_default_oper_chan(mac_ctx, + sap_ctx->acs_cfg); } + + sap_ctx->chan_freq = oper_channel; + sap_ctx->acs_cfg->pri_ch_freq = oper_channel; sap_config_acs_result(mac_handle, sap_ctx, - sap_ctx->acs_cfg->ht_sec_ch); + sap_ctx->acs_cfg->ht_sec_ch_freq); sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; sap_ctx->sap_status = eSAP_STATUS_SUCCESS; close_session: #ifdef SOFTAP_CHANNEL_RANGE - if (sap_ctx->channelList) { + if (sap_ctx->freq_list) { /* * Always free up the memory for * channel selection whatever * the result */ - qdf_mem_free(sap_ctx->channelList); - sap_ctx->channelList = NULL; + qdf_mem_free(sap_ctx->freq_list); + sap_ctx->freq_list = NULL; sap_ctx->num_of_channel = 0; } #endif @@ -403,14 +403,15 @@ wlansap_roam_process_ch_change_success(struct mac_context *mac_ctx, struct sap_sm_event sap_event; QDF_STATUS qdf_status; bool is_ch_dfs = false; + uint32_t target_chan_freq; /* * Channel change is successful. If the new channel is a DFS channel, * then we will to perform channel availability check for 60 seconds */ - sap_nofl_debug("sapdfs: SAP CSA: chan to [%d] state %d", - mac_ctx->sap.SapDfsInfo.target_channel, + sap_nofl_debug("sapdfs: SAP CSA: freq to [%d] state %d", + mac_ctx->sap.SapDfsInfo.target_chan_freq, sap_ctx->fsm_state); - sap_ctx->channel = mac_ctx->sap.SapDfsInfo.target_channel; + target_chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq; /* If SAP is not in starting or started state don't proceed further */ if (sap_ctx->fsm_state == SAP_INIT || @@ -424,21 +425,26 @@ wlansap_roam_process_ch_change_success(struct mac_context *mac_ctx, if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { is_ch_dfs = true; } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == - CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->ch_params.center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS) + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + target_chan_freq) == + CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_ctx->ch_params.mhz_freq_seg1) == + CHANNEL_STATE_DFS) is_ch_dfs = true; } else { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == - CHANNEL_STATE_DFS) + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + target_chan_freq) == + CHANNEL_STATE_DFS) is_ch_dfs = true; } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) + is_ch_dfs = false; + sap_ctx->chan_freq = target_chan_freq; /* check if currently selected channel is a DFS channel */ if (is_ch_dfs && sap_ctx->pre_cac_complete) { /* Start beaconing on the new pre cac channel */ @@ -553,9 +559,9 @@ wlansap_roam_process_dfs_chansw_update(mac_handle_t mac_handle, * should continue to operate in the same mode as it is operating * currently. For e.g. 20/40/80 MHz operation */ - if (mac_ctx->sap.SapDfsInfo.target_channel) - wlan_reg_set_channel_params(mac_ctx->pdev, - mac_ctx->sap.SapDfsInfo.target_channel, + if (mac_ctx->sap.SapDfsInfo.target_chan_freq) + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + mac_ctx->sap.SapDfsInfo.target_chan_freq, 0, &sap_ctx->ch_params); /* @@ -590,7 +596,7 @@ wlansap_roam_process_dfs_chansw_update(mac_handle_t mac_handle, * change the channel */ qdf_status = wlansap_channel_change_request(sap_ctx, - mac_ctx->sap.SapDfsInfo.target_channel); + mac_ctx->sap.SapDfsInfo.target_chan_freq); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) *ret_status = QDF_STATUS_E_FAILURE; return; @@ -640,7 +646,7 @@ wlansap_roam_process_dfs_chansw_update(mac_handle_t mac_handle, * change the channel */ qdf_status = wlansap_channel_change_request(sap_context, - mac_ctx->sap.SapDfsInfo.target_channel); + mac_ctx->sap.SapDfsInfo.target_chan_freq); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("post chnl chng req failed, sap[%pK]"), @@ -787,16 +793,16 @@ wlansap_roam_process_infra_assoc_ind(struct sap_context *sap_ctx, (void *) eSAP_STATUS_SUCCESS); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_STR") fail"), - roam_result, QDF_MAC_ADDR_ARRAY( + FL("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_FMT") fail"), + roam_result, QDF_MAC_ADDR_REF( csr_roam_info->peerMac.bytes)); *ret_status = QDF_STATUS_E_FAILURE; } } else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, - FL("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_STR") not allowed"), + FL("CSR roam_result = (%d) MAC ("QDF_MAC_ADDR_FMT") not allowed"), roam_result, - QDF_MAC_ADDR_ARRAY(csr_roam_info->peerMac.bytes)); + QDF_MAC_ADDR_REF(csr_roam_info->peerMac.bytes)); *ret_status = QDF_STATUS_E_FAILURE; } return; @@ -812,15 +818,15 @@ static void wlansap_update_vendor_acs_chan(struct mac_context *mac_ctx, return; } - mac_ctx->sap.SapDfsInfo.target_channel = - sap_ctx->dfs_vendor_channel; + mac_ctx->sap.SapDfsInfo.target_chan_freq = + wlan_reg_chan_to_freq(mac_ctx->pdev, sap_ctx->dfs_vendor_channel); mac_ctx->sap.SapDfsInfo.new_chanWidth = sap_ctx->dfs_vendor_chan_bw; mac_ctx->sap.SapDfsInfo.new_ch_params.ch_width = sap_ctx->dfs_vendor_chan_bw; - if (mac_ctx->sap.SapDfsInfo.target_channel != 0) { + if (mac_ctx->sap.SapDfsInfo.target_chan_freq != 0) { mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; sap_cac_reset_notify(MAC_HANDLE(mac_ctx)); @@ -961,8 +967,8 @@ QDF_STATUS wlansap_roam_callback(void *ctx, case eCSR_ROAM_DFS_RADAR_IND: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "Received Radar Indication on sap ch %d, session %d", - sap_ctx->channel, sap_ctx->sessionId); + "Rcvd Radar Indication on sap ch freq %d, session %d", + sap_ctx->chan_freq, sap_ctx->sessionId); if (!policy_mgr_get_dfs_master_dynamic_enabled( mac_ctx->psoc, sap_ctx->sessionId)) { @@ -982,11 +988,12 @@ QDF_STATUS wlansap_roam_callback(void *ctx, } if (!sap_chan_bond_dfs_sub_chan( - sap_ctx, sap_ctx->channel, + sap_ctx, wlan_reg_freq_to_chan(mac_ctx->pdev, + sap_ctx->chan_freq), PHY_CHANNEL_BONDING_STATE_MAX)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "Ignore Radar event for sap ch %d", - sap_ctx->channel); + "Ignore Radar event for sap ch freq%d", + sap_ctx->chan_freq); goto EXIT; } @@ -1012,22 +1019,22 @@ QDF_STATUS wlansap_roam_callback(void *ctx, FL("sapdfs: Indicate eSAP_DFS_RADAR_DETECT to HDD")); sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_RADAR_DETECT, (void *) eSAP_STATUS_SUCCESS); - mac_ctx->sap.SapDfsInfo.target_channel = - sap_indicate_radar(sap_ctx); + mac_ctx->sap.SapDfsInfo.target_chan_freq = + wlan_reg_chan_to_freq(mac_ctx->pdev, sap_indicate_radar(sap_ctx)); /* if there is an assigned next channel hopping */ - if (0 < mac_ctx->sap.SapDfsInfo.user_provided_target_channel) { - mac_ctx->sap.SapDfsInfo.target_channel = - mac_ctx->sap.SapDfsInfo.user_provided_target_channel; - mac_ctx->sap.SapDfsInfo.user_provided_target_channel = + if (0 < mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq) { + mac_ctx->sap.SapDfsInfo.target_chan_freq = + mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq; + mac_ctx->sap.SapDfsInfo.user_provided_target_chan_freq = 0; } /* if external acs enabled */ if (sap_ctx->vendor_acs_dfs_lte_enabled && - !mac_ctx->sap.SapDfsInfo.target_channel) { + !mac_ctx->sap.SapDfsInfo.target_chan_freq) { /* Return from here, processing will be done later */ goto EXIT; } - if (mac_ctx->sap.SapDfsInfo.target_channel != 0) { + if (mac_ctx->sap.SapDfsInfo.target_chan_freq != 0) { mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; sap_cac_reset_notify(mac_handle); @@ -1049,7 +1056,9 @@ QDF_STATUS wlansap_roam_callback(void *ctx, profile = &sap_context->csr_roamProfile; if (!wlan_reg_is_passive_or_disable_ch( mac_ctx->pdev, - profile->operationChannel)) + wlan_reg_freq_to_chan( + mac_ctx->pdev, + profile->op_freq))) continue; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, @@ -1068,8 +1077,6 @@ QDF_STATUS wlansap_roam_callback(void *ctx, case eCSR_ROAM_SET_CHANNEL_RSP: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("Received set channel response")); - /* SAP channel change request processing is completed */ - sap_ctx->is_chan_change_inprogress = false; break; case eCSR_ROAM_CAC_COMPLETE_IND: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -1293,10 +1300,16 @@ QDF_STATUS wlansap_roam_callback(void *ctx, wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx, csr_roam_info, &qdf_ret_status); - qdf_ret_status = - sap_signal_hdd_event(sap_ctx, csr_roam_info, - eSAP_CHANNEL_CHANGE_RESP, - (void *)QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(qdf_ret_status)) + qdf_ret_status = + sap_signal_hdd_event(sap_ctx, csr_roam_info, + eSAP_CHANNEL_CHANGE_RESP, + (void *)eSAP_STATUS_FAILURE); + else + qdf_ret_status = + sap_signal_hdd_event(sap_ctx, csr_roam_info, + eSAP_CHANNEL_CHANGE_RESP, + (void *)QDF_STATUS_SUCCESS); break; case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE: /* This is much more serious issue, we have to vacate the @@ -1333,19 +1346,10 @@ void sap_scan_event_callback(struct wlan_objmgr_vdev *vdev, { uint32_t scan_id; uint8_t session_id; - QDF_STATUS status; bool success = false; eCsrScanStatus scan_status = eCSR_SCAN_FAILURE; mac_handle_t mac_handle; - - session_id = wlan_vdev_get_id(vdev); - scan_id = event->scan_id; - mac_handle = cds_get_context(QDF_MODULE_ID_SME); - if (!mac_handle) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, - FL("invalid MAC handle")); - return; - } + QDF_STATUS status; /* * It may happen that the SAP was deleted before the scan @@ -1362,6 +1366,15 @@ void sap_scan_event_callback(struct wlan_objmgr_vdev *vdev, } wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); + session_id = wlan_vdev_get_id(vdev); + scan_id = event->scan_id; + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + if (!mac_handle) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL, + FL("invalid MAC handle")); + return; + } + qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SAP, event->type, event->vdev_id, event->scan_id); diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.c b/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.c index 9502332b4cf3a09a4bd8eb82eea2313d471be6e8..9a94a404c60b145cace4384d09bb10361fd344a1 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.c +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -66,10 +66,13 @@ #define SET_ACS_BAND(acs_band, sap_ctx) \ { \ - if (sap_ctx->acs_cfg->start_ch <= 14 && \ - sap_ctx->acs_cfg->end_ch <= 14) \ + if (sap_ctx->acs_cfg->start_ch_freq <= \ + WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484) && \ + sap_ctx->acs_cfg->end_ch_freq <= \ + WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484)) \ acs_band = eCSR_DOT11_MODE_11g; \ - else if (sap_ctx->acs_cfg->start_ch >= 14)\ + else if (sap_ctx->acs_cfg->start_ch_freq >= \ + WLAN_REG_CH_TO_FREQ(CHAN_ENUM_2484))\ acs_band = eCSR_DOT11_MODE_11a; \ else \ acs_band = eCSR_DOT11_MODE_abg; \ @@ -277,10 +280,9 @@ sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx, * * Return: void */ -static void sap_process_avoid_ie(mac_handle_t mac_handle, - struct sap_context *sap_ctx, - qdf_list_t *scan_list, - tSapChSelSpectInfo *spect_info) +static void +sap_process_avoid_ie(mac_handle_t mac_handle, struct sap_context *sap_ctx, + qdf_list_t *scan_list, tSapChSelSpectInfo *spect_info) { const uint8_t *temp_ptr = NULL; uint8_t i = 0; @@ -289,12 +291,14 @@ static void sap_process_avoid_ie(mac_handle_t mac_handle, tSapSpectChInfo *spect_ch = NULL; qdf_list_node_t *cur_lst = NULL, *next_lst = NULL; struct scan_cache_node *cur_node = NULL; + uint32_t chan_freq; mac_ctx = MAC_CONTEXT(mac_handle); spect_ch = spect_info->pSpectCh; if (scan_list) qdf_list_peek_front(scan_list, &cur_lst); + while (cur_lst) { cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); @@ -317,34 +321,36 @@ static void sap_process_avoid_ie(mac_handle_t mac_handle, } sap_ctx->sap_detected_avoid_ch_ie.present = 1; - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_DEBUG, - "Q2Q IE - avoid ch %d", - avoid_ch_ie->channel); + + chan_freq = + wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, + avoid_ch_ie->channel); + + sap_debug("Q2Q-IE avoid freq = %d", chan_freq); /* add this channel to to_avoid channel list */ - sap_check_n_add_channel(sap_ctx, - avoid_ch_ie->channel); + sap_check_n_add_channel(sap_ctx, avoid_ch_ie->channel); sap_check_n_add_overlapped_chnls(sap_ctx, - avoid_ch_ie->channel); + avoid_ch_ie->channel); /* * Mark weight of these channel present in IE to MAX * so that ACS logic will to avoid thse channels */ - for (i = 0; i < spect_info->numSpectChans; i++) - if (spect_ch[i].chNum == avoid_ch_ie->channel) { - /* - * weight is set more than max so that, - * in the case of other channels being - * assigned max weight due to noise, - * they may be preferred over channels - * with Q2Q IE. - */ - spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1; - spect_ch[i].weight_copy = - SAP_ACS_WEIGHT_MAX + 1; - break; - } - } /* if (temp_ptr) */ + for (i = 0; i < spect_info->numSpectChans; i++) { + if (spect_ch[i].chan_freq != chan_freq) + continue; + /* + * weight is set more than max so that, + * in the case of other channels being + * assigned max weight due to noise, + * they may be preferred over channels + * with Q2Q IE. + */ + spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1; + spect_ch[i].weight_copy = + SAP_ACS_WEIGHT_MAX + 1; + break; + } + } qdf_list_peek_next(scan_list, cur_lst, &next_lst); cur_lst = next_lst; @@ -353,42 +359,9 @@ static void sap_process_avoid_ie(mac_handle_t mac_handle, } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ -/** - * sap_channel_in_acs_channel_list() - check if channel in acs channel list - * @channel_num: channel to check - * @sap_ctx: struct ptSapContext - * @spect_info_params: strcut tSapChSelSpectInfo - * - * This function checks if specified channel is in the configured ACS channel - * list. - * - * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED - */ -uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num, - struct sap_context *sap_ctx, - tSapChSelSpectInfo *spect_info_params) -{ - uint8_t i = 0; - - if ((!sap_ctx->acs_cfg->master_ch_list) || - (!spect_info_params)) - return channel_num; - - if (channel_num > 0 && channel_num <= 252) { - for (i = 0; i < sap_ctx->acs_cfg->master_ch_list_count; i++) { - if ((sap_ctx->acs_cfg->master_ch_list[i]) == - channel_num) - return channel_num; - } - return SAP_CHANNEL_NOT_SELECTED; - } else { - return SAP_CHANNEL_NOT_SELECTED; - } -} - /** * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel - * @best_chnl: best channel already calculated among all the chanels + * @best_ch_freq: best chan freq already calculated among all the chanels * @sap_ctx: sap context * @spectinfo_param: Pointer to tSapChSelSpectInfo structure * @@ -396,46 +369,26 @@ uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num, * If channel list not configured then returns the best channel calculated * among all the channel list. * - * Return: uint8_t best channel + * Return: uint32_t best channel frequency */ static -uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl, +uint32_t sap_select_preferred_channel_from_channel_list(uint32_t best_ch_freq, struct sap_context *sap_ctx, tSapChSelSpectInfo *spectinfo_param) { - uint8_t i = 0; - struct mac_context *mac_ctx = sme_get_mac_context(); - - if (!mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "pmac Global Context is NULL"); - return SAP_CHANNEL_NOT_SELECTED; - } - /* * If Channel List is not Configured don't do anything * Else return the Best Channel from the Channel List */ - if ((!sap_ctx->acs_cfg->ch_list) || - (!spectinfo_param) || - (0 == sap_ctx->acs_cfg->ch_list_count)) - return best_chnl; + if ((!sap_ctx->acs_cfg->freq_list) || + (!spectinfo_param) || + (!sap_ctx->acs_cfg->ch_list_count)) + return best_ch_freq; - if (best_chnl <= 0 || best_chnl > 252) - return SAP_CHANNEL_NOT_SELECTED; - - /* Select the best channel from allowed list */ - for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) { - if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) && - !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) && - policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "Best channel so far is: %d", - best_chnl); - return best_chnl; - } - } + if (wlansap_is_channel_present_in_acs_list(best_ch_freq, + sap_ctx->acs_cfg->freq_list, + sap_ctx->acs_cfg->ch_list_count)) + return best_ch_freq; return SAP_CHANNEL_NOT_SELECTED; } @@ -456,14 +409,11 @@ static bool sap_chan_sel_init(mac_handle_t mac_handle, struct sap_context *sap_ctx) { tSapSpectChInfo *pSpectCh = NULL; - uint8_t *pChans = NULL; + uint32_t *pChans = NULL; uint16_t channelnum = 0; struct mac_context *mac = MAC_CONTEXT(mac_handle); - bool chSafe = true; bool include_dfs_ch = true; - uint8_t chan_num; - bool sta_sap_scc_on_dfs_chan = - policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc); + uint8_t sta_sap_scc_on_dfs_chnl_config_value; pSpectInfoParams->numSpectChans = mac->scan.base_channels.numChannels; @@ -477,8 +427,10 @@ static bool sap_chan_sel_init(mac_handle_t mac_handle, /* Initialize the pointers in the DfsParams to the allocated memory */ pSpectInfoParams->pSpectCh = pSpectCh; - pChans = mac->scan.base_channels.channelList; + pChans = mac->scan.base_channels.channel_freq_list; + policy_mgr_get_sta_sap_scc_on_dfs_chnl(mac->psoc, + &sta_sap_scc_on_dfs_chnl_config_value); #if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) if (sap_ctx->dfs_ch_disable == true) include_dfs_ch = false; @@ -491,73 +443,67 @@ static bool sap_chan_sel_init(mac_handle_t mac_handle, for (channelnum = 0; channelnum < pSpectInfoParams->numSpectChans; channelnum++, pChans++, pSpectCh++) { - chSafe = true; + uint8_t channel; + + channel = wlan_reg_freq_to_chan(mac->pdev, *pChans); - pSpectCh->chNum = *pChans; + pSpectCh->chan_freq = *pChans; /* Initialise for all channels */ pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; - /* Initialise 20MHz for all the Channels */ - pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise max ACS weight for all channels */ pSpectCh->weight = SAP_ACS_WEIGHT_MAX; /* check if the channel is in NOL blacklist */ if (sap_dfs_is_channel_in_nol_list( - sap_ctx, *pChans, + sap_ctx, channel, PHY_SINGLE_CHANNEL_CENTERED)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s, Ch %d is in NOL list", __func__, - *pChans); - chSafe = false; + channel); continue; } - if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) { - if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) { - chSafe = false; + if (!include_dfs_ch || + (sta_sap_scc_on_dfs_chnl_config_value == + PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED && + !policy_mgr_is_sta_sap_scc(mac->psoc, + pSpectCh->chan_freq))) { + if (wlan_reg_is_dfs_for_freq(mac->pdev, + pSpectCh->chan_freq)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d", - __func__, *pChans, include_dfs_ch, - sta_sap_scc_on_dfs_chan); + "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chnl_config_value %d", + __func__, channel, include_dfs_ch, + sta_sap_scc_on_dfs_chnl_config_value); continue; } } if (!policy_mgr_is_safe_channel(mac->psoc, *pChans)) - chSafe = false; + continue; /* OFDM rates are not supported on channel 14 */ - if (*pChans == 14 && - eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) { + if (channel == 14 && + eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) continue; - } /* Skip DSRC channels */ - if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans)) + if (wlan_reg_is_dsrc_chan(mac->pdev, channel)) continue; - if (!mac->mlme_cfg->reg.etsi13_srd_chan_in_master_mode && - wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans)) + /* + * Skip the channels which are not in ACS config from user + * space + */ + if (!wlansap_is_channel_present_in_acs_list(*pChans, + sap_ctx->acs_cfg->freq_list, + sap_ctx->acs_cfg->ch_list_count)) continue; - if (true == chSafe) { - pSpectCh->valid = true; - for (chan_num = 0; chan_num < sap_ctx->num_of_channel; - chan_num++) { - if (pSpectCh->chNum != - sap_ctx->channelList[chan_num]) - continue; - - /* - * Initialize ACS weight to 0 for channels - * present in sap context scan channel list - */ - pSpectCh->weight = 0; - break; - } - } + pSpectCh->valid = true; + pSpectCh->weight = 0; } + return true; } @@ -632,9 +578,9 @@ uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi, * Return: chan status info */ static struct lim_channel_status *sap_get_channel_status - (struct mac_context *p_mac, uint32_t channel_id) + (struct mac_context *p_mac, uint32_t chan_freq) { - return csr_get_channel_status(p_mac, channel_id); + return csr_get_channel_status(p_mac, chan_freq); } /** @@ -866,24 +812,6 @@ uint32_t sap_weight_channel_status(struct sap_context *sap_ctx, sap_weight_channel_txpwr_tput(sap_ctx, channel_stat); } -/** - * sap_check_channels_same_band() - Check if two channels belong to same band - * @ch_num1: channel number - * @ch_num2: channel number - * - * Return: true if both channels belong to same band else false - */ -static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2) -{ - if ((ch_num1 <= SIR_11B_CHANNEL_END && - ch_num2 <= SIR_11B_CHANNEL_END) || - (ch_num1 >= SIR_11A_CHANNEL_BEGIN && - ch_num2 >= SIR_11A_CHANNEL_BEGIN)) - return true; - - return false; -} - /** * sap_update_rssi_bsscount() - updates bss count and rssi effect. * @@ -907,11 +835,10 @@ static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset, int32_t rssi, rsssi_effect; pExtSpectCh = (pSpectCh + offset); - if (pExtSpectCh && - pExtSpectCh >= spectch_start && + if (pExtSpectCh && pExtSpectCh >= spectch_start && pExtSpectCh < spectch_end) { - if (!sap_check_channels_same_band(pSpectCh->chNum, - pExtSpectCh->chNum)) + if (!WLAN_REG_IS_SAME_BAND_FREQS(pSpectCh->chan_freq, + pExtSpectCh->chan_freq)) return; ++pExtSpectCh->bssCount; switch (offset) { @@ -964,58 +891,6 @@ static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset, } } -/** - * sap_upd_chan_spec_params() - sap_upd_chan_spec_params - * updates channel parameters obtained from Beacon - * @pBeaconStruct Beacon strucutre populated by parse_beacon function - * @channelWidth Channel width - * @secondaryChannelOffset Secondary Channel Offset - * @vhtSupport If channel supports VHT - * @centerFreq Central frequency for the given channel. - * - * sap_upd_chan_spec_params updates the spectrum channels based on the - * pBeaconStruct obtained from Beacon IE - * - * Return: NA. - */ - -static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct, - uint16_t *channelWidth, - uint16_t *secondaryChannelOffset, - uint16_t *vhtSupport, - uint16_t *centerFreq, - uint16_t *centerFreq_2) -{ - if (!pBeaconStruct) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("pBeaconStruct is NULL")); - return; - } - - if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) { - *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet; - *secondaryChannelOffset = - pBeaconStruct->HTInfo.secondaryChannelOffset; - if (!pBeaconStruct->VHTOperation.present) - return; - *vhtSupport = pBeaconStruct->VHTOperation.present; - if (pBeaconStruct->VHTOperation.chanWidth) { - *centerFreq = - pBeaconStruct->VHTOperation.chanCenterFreqSeg1; - *centerFreq_2 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg2; - /* - * LHS follows tSirMacHTChannelWidth, while RHS follows - * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following - * adjustment - */ - *channelWidth = - pBeaconStruct->VHTOperation.chanWidth + 1; - - } - } -} - /** * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect. * @@ -1075,84 +950,72 @@ static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch, uint16_t chan_width, uint16_t sec_chan_offset, - uint16_t center_freq, - uint16_t center_freq_2, - uint8_t channel_id, + uint32_t ch_freq0, + uint32_t ch_freq1, + uint32_t op_chan_freq, tSapSpectChInfo *spectch_start, tSapSpectChInfo *spectch_end) { uint16_t num_ch; int32_t offset = 0; - if (!spect_ch) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("spect_ch is NULL")); - return; - } - - /* Updating the received ChannelWidth */ - if (spect_ch->channelWidth != chan_width) - spect_ch->channelWidth = chan_width; - /* If received ChannelWidth is other than HT20, - * we need to update the extension channel Params as well - * chan_width == 0, HT20 - * chan_width == 1, HT40 - * chan_width == 2, VHT80 - * chan_width == 3, VHT160 - */ + sap_debug("freq = %d, ch width = %d, ch_freq0 = %d ch_freq1 = %d", + op_chan_freq, chan_width, ch_freq0, ch_freq1); - switch (spect_ch->channelWidth) { - case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */ + switch (chan_width) { + case eHT_CHANNEL_WIDTH_40MHZ: switch (sec_chan_offset) { /* Above the Primary Channel */ case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: sap_update_rssi_bsscount(spect_ch, 1, false, - spectch_start, spectch_end); + spectch_start, spectch_end); return; /* Below the Primary channel */ case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: sap_update_rssi_bsscount(spect_ch, -1, false, - spectch_start, spectch_end); + spectch_start, spectch_end); return; } return; - case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */ + case eHT_CHANNEL_WIDTH_80MHZ: + case eHT_CHANNEL_WIDTH_80P80MHZ: num_ch = 3; - if ((center_freq - channel_id) == 6) { + if ((ch_freq0 - op_chan_freq) == 30) { offset = 1; - } else if ((center_freq - channel_id) == 2) { + } else if ((ch_freq0 - op_chan_freq) == 10) { offset = -1; - } else if ((center_freq - channel_id) == -2) { + } else if ((ch_freq0 - op_chan_freq) == -10) { offset = -2; - } else if ((center_freq - channel_id) == -6) { + } else if ((ch_freq0 - op_chan_freq) == -30) { offset = -3; } break; - case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */ + case eHT_CHANNEL_WIDTH_160MHZ: num_ch = 7; - if ((center_freq - channel_id) == 14) + if ((ch_freq0 - op_chan_freq) == 70) offset = 1; - else if ((center_freq - channel_id) == 10) + else if ((ch_freq0 - op_chan_freq) == 50) offset = -1; - else if ((center_freq - channel_id) == 6) + else if ((ch_freq0 - op_chan_freq) == 30) offset = -2; - else if ((center_freq - channel_id) == 2) + else if ((ch_freq0 - op_chan_freq) == 10) offset = -3; - else if ((center_freq - channel_id) == -2) + else if ((ch_freq0 - op_chan_freq) == -10) offset = -4; - else if ((center_freq - channel_id) == -6) + else if ((ch_freq0 - op_chan_freq) == -30) offset = -5; - else if ((center_freq - channel_id) == -10) + else if ((ch_freq0 - op_chan_freq) == -50) offset = -6; - else if ((center_freq - channel_id) == -14) + else if ((ch_freq0 - op_chan_freq) == -70) offset = -7; break; default: return; } - sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch, - spectch_start, spectch_end); + + sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch, spectch_start, + spectch_end); } /** @@ -1179,7 +1042,7 @@ static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch, return; } - switch (spect_ch->chNum) { + switch (wlan_freq_to_chan(spect_ch->chan_freq)) { case CHANNEL_1: sap_update_rssi_bsscount(spect_ch, 1, true, spectch_start, spectch_end); @@ -1330,18 +1193,74 @@ static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch, * true: channel is in PCL, * false: channel is not in PCL */ -static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel) +static bool ch_in_pcl(struct sap_context *sap_ctx, uint32_t ch_freq) { uint32_t i; for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) { - if (channel == sap_ctx->acs_cfg->pcl_channels[i]) + if (ch_freq == sap_ctx->acs_cfg->pcl_chan_freq[i]) return true; } return false; } +/** + * sap_upd_chan_spec_params() - sap_upd_chan_spec_params + * updates channel parameters obtained from Beacon + * @scan_entry: Beacon strucutre populated by scan + * @ch_width: Channel width + * @sec_ch_offset: Secondary Channel Offset + * @center_freq0: Central frequency 0 for the given channel + * @center_freq1: Central frequency 1 for the given channel + * + * sap_upd_chan_spec_params updates the spectrum channels based on the + * scan_entry + * + * Return: NA. + */ +static void +sap_upd_chan_spec_params(struct scan_cache_node *scan_entry, + tSirMacHTChannelWidth *ch_width, + uint16_t *sec_ch_offset, + uint32_t *center_freq0, + uint32_t *center_freq1) +{ + enum wlan_phymode phy_mode; + struct channel_info *chan; + + phy_mode = util_scan_entry_phymode(scan_entry->entry); + chan = util_scan_entry_channel(scan_entry->entry); + + if (IS_WLAN_PHYMODE_160MHZ(phy_mode)) { + if (phy_mode == WLAN_PHYMODE_11AC_VHT80_80 || + phy_mode == WLAN_PHYMODE_11AXA_HE80_80) { + *ch_width = eHT_CHANNEL_WIDTH_80P80MHZ; + *center_freq0 = chan->cfreq0; + *center_freq1 = chan->cfreq1; + } else { + *ch_width = eHT_CHANNEL_WIDTH_160MHZ; + if (chan->cfreq1) + *center_freq0 = chan->cfreq1; + else + *center_freq0 = chan->cfreq0; + } + + } else if (IS_WLAN_PHYMODE_80MHZ(phy_mode)) { + *ch_width = eHT_CHANNEL_WIDTH_80MHZ; + *center_freq0 = chan->cfreq0; + } else if (IS_WLAN_PHYMODE_40MHZ(phy_mode)) { + if (chan->cfreq0 > chan->chan_freq) + *sec_ch_offset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + else + *sec_ch_offset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + *ch_width = eHT_CHANNEL_WIDTH_40MHZ; + *center_freq0 = chan->cfreq0; + } else { + *ch_width = eHT_CHANNEL_WIDTH_20MHZ; + } +} + /** * sap_compute_spect_weight() - Compute spectrum weight * @pSpectInfoParams: Pointer to the tSpectInfoParams structure @@ -1360,17 +1279,12 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, { int8_t rssi = 0; uint8_t chn_num = 0; - uint8_t channel_id = 0; tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh; - uint32_t operatingBand; - uint16_t channelWidth; + tSirMacHTChannelWidth ch_width = 0; uint16_t secondaryChannelOffset; - uint16_t centerFreq; + uint32_t center_freq0, center_freq1; uint8_t i; bool found; - uint16_t centerFreq_2 = 0; - uint16_t vhtSupport; - tSirProbeRespBeacon *bcn_struct; struct mac_context *mac = MAC_CONTEXT(mac_handle); tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh; tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh + @@ -1379,117 +1293,61 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, struct scan_cache_node *cur_node = NULL; uint32_t normalized_weight; uint8_t normalize_factor; - - bcn_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon)); - if (!bcn_struct) - return; + uint32_t chan_freq; + struct acs_weight *weight_list = + mac->mlme_cfg->acs.normalize_weight_chan; + struct acs_weight_range *range_list = + mac->mlme_cfg->acs.normalize_weight_range; + bool freq_present_in_list = false; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s, Computing spectral weight", __func__); - /** - * Soft AP specific channel weight calculation using DFS formula - */ - SET_ACS_BAND(operatingBand, sap_ctx); - if (scan_list) qdf_list_peek_front(scan_list, &cur_lst); while (cur_lst) { - uint32_t ie_len = 0; - uint8_t *ie_ptr; - cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); pSpectCh = pSpectInfoParams->pSpectCh; /* Defining the default values, so that any value will hold the default values */ - channelWidth = eHT_CHANNEL_WIDTH_20MHZ; + secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED; - vhtSupport = 0; - centerFreq = 0; - - ie_len = util_scan_entry_ie_len(cur_node->entry); - ie_ptr = util_scan_entry_ie_data(cur_node->entry); - qdf_mem_zero((uint8_t *)bcn_struct, - sizeof(tSirProbeRespBeacon)); - - if ((sir_parse_beacon_ie(mac, bcn_struct, ie_ptr, ie_len)) == - QDF_STATUS_SUCCESS) - sap_upd_chan_spec_params( - bcn_struct, - &channelWidth, - &secondaryChannelOffset, - &vhtSupport, ¢erFreq, - ¢erFreq_2); + center_freq0 = 0; + center_freq1 = 0; + + chan_freq = + util_scan_entry_channel_frequency(cur_node->entry); + + sap_upd_chan_spec_params(cur_node, &ch_width, + &secondaryChannelOffset, + ¢er_freq0, ¢er_freq1); /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */ for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans; chn_num++) { - channel_id = - util_scan_entry_channel_num(cur_node->entry); + if (chan_freq != pSpectCh->chan_freq) { + pSpectCh++; + continue; + } - if (pSpectCh && (channel_id == pSpectCh->chNum)) { - if (pSpectCh->rssiAgr < - cur_node->entry->rssi_raw) - pSpectCh->rssiAgr = - cur_node->entry->rssi_raw; + if (pSpectCh->rssiAgr < cur_node->entry->rssi_raw) + pSpectCh->rssiAgr = cur_node->entry->rssi_raw; - ++pSpectCh->bssCount; /* Increment the count of BSS */ + ++pSpectCh->bssCount; - /* - * Connsidering the Extension Channel - * only in a channels - */ - switch (operatingBand) { - case eCSR_DOT11_MODE_11a: - sap_interference_rssi_count_5G( - pSpectCh, channelWidth, - secondaryChannelOffset, - centerFreq, - centerFreq_2, - channel_id, - spectch_start, - spectch_end); - break; - - case eCSR_DOT11_MODE_11g: - sap_interference_rssi_count(pSpectCh, - spectch_start, spectch_end); - break; - - case eCSR_DOT11_MODE_abg: - if (pSpectCh->chNum >= - SIR_11A_CHANNEL_BEGIN) - sap_interference_rssi_count_5G( - pSpectCh, channelWidth, - secondaryChannelOffset, - centerFreq, - centerFreq_2, - channel_id, - spectch_start, - spectch_end); - else - sap_interference_rssi_count( - pSpectCh, - spectch_start, - spectch_end); - break; - } + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) + sap_interference_rssi_count(pSpectCh, + spectch_start, spectch_end); + else + sap_interference_rssi_count_5G( + pSpectCh, ch_width, secondaryChannelOffset, + center_freq0, center_freq1, chan_freq, + spectch_start, spectch_end); + + pSpectCh++; + break; - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, channel_id=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, ChannelWidth %d, secondaryChanOffset %d, center frequency %d", - __func__, - channel_id, - cur_node->entry->rssi_raw, - pSpectCh->bssCount, - pSpectCh->channelWidth, - secondaryChannelOffset, centerFreq); - pSpectCh++; - break; - } else { - pSpectCh++; - } } qdf_list_peek_next(scan_list, cur_lst, &next_lst); @@ -1497,14 +1355,9 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, next_lst = NULL; } - qdf_mem_free(bcn_struct); - /* Calculate the weights for all channels in the spectrum pSpectCh */ pSpectCh = pSpectInfoParams->pSpectCh; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Spectrum Channels Weight", __func__); - for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans); chn_num++) { @@ -1514,7 +1367,7 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, */ rssi = (int8_t) pSpectCh->rssiAgr; - if (ch_in_pcl(sap_ctx, pSpectCh->chNum)) + if (ch_in_pcl(sap_ctx, pSpectCh->chan_freq)) rssi -= PCL_RSSI_DISCOUNT; if (rssi < SOFTAP_MIN_RSSI) @@ -1536,7 +1389,7 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, */ found = false; for (i = 0; i < sap_ctx->num_of_channel; i++) { - if (pSpectCh->chNum == sap_ctx->channelList[i]) { + if (pSpectCh->chan_freq == sap_ctx->freq_list[i]) { /* Scan channel was included in ACS scan list */ found = true; break; @@ -1549,7 +1402,7 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, (sapweight_rssi_count(sap_ctx, rssi, pSpectCh->bssCount) + sap_weight_channel_status( sap_ctx, sap_get_channel_status(mac, - pSpectCh->chNum))); + pSpectCh->chan_freq))); else { pSpectCh->weight = SAP_ACS_WEIGHT_MAX; pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; @@ -1557,35 +1410,59 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, pSpectCh->bssCount = SOFTAP_MIN_COUNT; } - if (wlan_reg_is_dfs_ch(mac->pdev, - pSpectCh->chNum)) { + chan_freq = pSpectCh->chan_freq; + + if (wlan_reg_is_dfs_for_freq(mac->pdev, chan_freq)) { normalize_factor = MLME_GET_DFS_CHAN_WEIGHT( mac->mlme_cfg->acs.np_chan_weightage); + freq_present_in_list = true; + } + /* Check if the freq is present in range list */ + for (i = 0; i < mac->mlme_cfg->acs.num_weight_range; i++) { + if (chan_freq >= range_list[i].start_freq && + chan_freq <= range_list[i].end_freq) { + normalize_factor = + range_list[i].normalize_weight; + sap_debug("Range list, freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + /* Check if user wants a special factor for this freq */ + + for (i = 0; i < mac->mlme_cfg->acs.normalize_weight_num_chan; + i++) { + if (chan_freq == weight_list[i].chan_freq) { + normalize_factor = + weight_list[i].normalize_weight; + sap_debug("freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + if (freq_present_in_list) { normalized_weight = ((SAP_ACS_WEIGHT_MAX - pSpectCh->weight) * (100 - normalize_factor)) / 100; - sap_debug("DFS ch %d old weight %d new weight %d", - pSpectCh->chNum, pSpectCh->weight, + sap_debug("freq %d old weight %d new weight %d", + chan_freq, pSpectCh->weight, pSpectCh->weight + normalized_weight); pSpectCh->weight += normalized_weight; - + freq_present_in_list = false; } + if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX) pSpectCh->weight = SAP_ACS_WEIGHT_MAX; pSpectCh->weight_copy = pSpectCh->weight; debug_info: - /* ------ Debug Info ------ */ - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d", - __func__, pSpectCh->chNum, pSpectCh->weight, - pSpectCh->rssiAgr, rssi, pSpectCh->bssCount); - host_log_acs_chan_spect_weight(pSpectCh->chNum, - (uint16_t)pSpectCh->weight, - pSpectCh->rssiAgr, - pSpectCh->bssCount); - /* ------ Debug Info ------ */ + sap_debug("freq = %d, weight = %d rssi = %d bss count = %d", + pSpectCh->chan_freq, pSpectCh->weight, + pSpectCh->rssiAgr, pSpectCh->bssCount); + pSpectCh++; } sap_clear_channel_status(mac); @@ -1668,176 +1545,131 @@ static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams) } /** - * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap - * @channel_bitmap: Pointer to the chan_bonding_bitmap structure - * @spect_info_params: Pointer to the tSapChSelSpectInfo structure - * - * Return: none - */ -static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap, - tSapChSelSpectInfo *spec_info_params) -{ - uint8_t i, j; - tSapSpectChInfo *spec_info; - int start_channel = 0; - - channel_bitmap->chanBondingSet[0].startChannel = - acs_ht80_channels[0].chStartNum; - channel_bitmap->chanBondingSet[1].startChannel = - acs_ht80_channels[1].chStartNum; - channel_bitmap->chanBondingSet[2].startChannel = - acs_ht80_channels[2].chStartNum; - channel_bitmap->chanBondingSet[3].startChannel = - acs_ht80_channels[3].chStartNum; - channel_bitmap->chanBondingSet[4].startChannel = - acs_ht80_channels[4].chStartNum; - channel_bitmap->chanBondingSet[5].startChannel = - acs_ht80_channels[5].chStartNum; - - spec_info = spec_info_params->pSpectCh; - for (j = 0; j < spec_info_params->numSpectChans; j++) { - for (i = 0; i < MAX_80MHZ_BANDS; i++) { - start_channel = - channel_bitmap->chanBondingSet[i].startChannel; - if (spec_info[j].chNum >= start_channel && - (spec_info[j].chNum <= start_channel + 12)) { - channel_bitmap->chanBondingSet[i].channelMap |= - 1 << ((spec_info[j].chNum - - start_channel)/4); - break; - } - } - } -} - -/** - * sap_sort_chl_weight_ht80() - to sort the channels with the least weight + * sap_sort_chl_weight_80_mhz() - to sort the channels with the least weight * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure - * * Function to sort the channels with the least weight first for HT80 channels * * Return: none */ -static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams) +static void sap_sort_chl_weight_80_mhz(struct mac_context *mac_ctx, + tSapChSelSpectInfo *pSpectInfoParams) { - uint8_t i, j, n; + uint8_t i, j; tSapSpectChInfo *pSpectInfo; uint8_t minIdx; - int start_channel = 0; - chan_bonding_bitmap *channel_bitmap; - - channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap)); - if (!channel_bitmap) - return; + struct ch_params acs_ch_params; + int8_t center_freq_diff; + uint32_t combined_weight; + uint32_t min_ch_weight; pSpectInfo = pSpectInfoParams->pSpectCh; - /* for each HT80 channel, calculate the combined weight of the - four 20MHz weight */ - for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) { - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == - acs_ht80_channels[i].chStartNum) - break; + + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { + + if (pSpectInfo[j].weight_calc_done) + continue; + + acs_ch_params.ch_width = CH_WIDTH_80MHZ; + + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + pSpectInfo[j].chan_freq, + 0, &acs_ch_params); + + /* Check if the freq supports 80 Mhz */ + if (acs_ch_params.ch_width != CH_WIDTH_80MHZ) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4; + pSpectInfo[j].weight_calc_done = true; + continue; } - if (j == pSpectInfoParams->numSpectChans) + + center_freq_diff = acs_ch_params.mhz_freq_seg0 - + pSpectInfo[j].chan_freq; + + /* This channel frequency does not have all channels */ + if (center_freq_diff != 30) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4; + pSpectInfo[j].weight_calc_done = true; + continue; + } + + /* no other freq left for 80 Mhz operation in spectrum */ + if (j + 3 > pSpectInfoParams->numSpectChans) continue; - if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) && - ((pSpectInfo[j].chNum + 8) == - pSpectInfo[j + 2].chNum) && - ((pSpectInfo[j].chNum + 12) == - pSpectInfo[j + 3].chNum))) { + /* Check whether all frequencies are present for 80 Mhz */ + + if (!(((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq) && + ((pSpectInfo[j].chan_freq + 40) == + pSpectInfo[j + 2].chan_freq) && + ((pSpectInfo[j].chan_freq + 60) == + pSpectInfo[j + 3].chan_freq))) { /* * some channels does not exist in pSectInfo array, * skip this channel and those in the same HT80 width */ pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4; - if ((pSpectInfo[j].chNum + 4) == - pSpectInfo[j + 1].chNum) + pSpectInfo[j].weight_calc_done = true; + if ((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq) { pSpectInfo[j + 1].weight = SAP_ACS_WEIGHT_MAX * 4; - if ((pSpectInfo[j].chNum + 8) == - pSpectInfo[j + 2].chNum) + pSpectInfo[j +1].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 40) == + pSpectInfo[j + 2].chan_freq) { pSpectInfo[j + 2].weight = SAP_ACS_WEIGHT_MAX * 4; - if ((pSpectInfo[j].chNum + 12) == - pSpectInfo[j + 3].chNum) + pSpectInfo[j +2].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 60) == + pSpectInfo[j + 3].chan_freq) { pSpectInfo[j + 3].weight = SAP_ACS_WEIGHT_MAX * 4; + pSpectInfo[j +3].weight_calc_done = true; + } + continue; } - /*found the channel, add the 4 adjacent channels' weight */ - acs_ht80_channels[i].weight = pSpectInfo[j].weight + - pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight + - pSpectInfo[j + 3].weight; - /* find best channel among 4 channels as the primary channel */ - if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) < - (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) { - /* lower 2 channels are better choice */ - if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight) - minIdx = 0; - else - minIdx = 1; - } else if (pSpectInfo[j + 2].weight <= - pSpectInfo[j + 3].weight) { - /* upper 2 channels are better choice */ - minIdx = 2; - } else { - minIdx = 3; - } - /* - * set all 4 channels to max value first, then reset the - * best channel as the selected primary channel, update its - * weightage with the combined weight value - */ - for (n = 0; n < 4; n++) - pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4; + /* We have 4 channels to calculate cumulative weight */ - pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight; - } + combined_weight = pSpectInfo[j].weight + + pSpectInfo[j + 1].weight + + pSpectInfo[j + 2].weight + + pSpectInfo[j + 3].weight; - /* - * mark the weight of the channel that can't satisfy 80MHZ - * as max value, so that it will be sorted to the bottom - */ - set_ht80_chl_bit(channel_bitmap, pSpectInfoParams); - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - for (i = 0; i < MAX_80MHZ_BANDS; i++) { - start_channel = - channel_bitmap->chanBondingSet[i].startChannel; - if (pSpectInfo[j].chNum >= start_channel && - (pSpectInfo[j].chNum <= - start_channel + 12) && - channel_bitmap->chanBondingSet[i].channelMap != - SAP_80MHZ_MASK) - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4; + min_ch_weight = pSpectInfo[j].weight; + minIdx = 0; + + for (i = 0; i < 4; i++) { + if (min_ch_weight > pSpectInfo[j + i].weight) { + min_ch_weight = pSpectInfo[j + i].weight; + minIdx = i; + } + pSpectInfo[j + i].weight = SAP_ACS_WEIGHT_MAX * 4; + pSpectInfo[j + i].weight_calc_done = true; } - } - /* - * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels - * and channel 165 as they cannot be part of a 80Mhz channel bonding. - */ - pSpectInfo = pSpectInfoParams->pSpectCh; - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) && - pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) || - (pSpectInfo[j].chNum >= CHANNEL_165)) - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4; + pSpectInfo[j + minIdx].weight = combined_weight; + + sap_debug("best freq = %d for 80mhz center freq %d combined weight = %d", + pSpectInfo[j + minIdx].chan_freq, + acs_ch_params.mhz_freq_seg0, + combined_weight); } sap_sort_chl_weight(pSpectInfoParams); pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Channel=%d Weight= %d rssi=%d bssCount=%d"), - pSpectInfo->chNum, pSpectInfo->weight, - pSpectInfo->rssiAgr, pSpectInfo->bssCount); + sap_debug("freq = %d weight = %d rssi = %d bss count = %d", + pSpectInfo->chan_freq, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; } - qdf_mem_free(channel_bitmap); } /** @@ -1848,139 +1680,159 @@ static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams) * * Return: none */ -static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams) +static void sap_sort_chl_weight_160_mhz(struct mac_context *mac_ctx, + tSapChSelSpectInfo *pSpectInfoParams) { - uint8_t i, j, n, idx; + uint8_t i, j; tSapSpectChInfo *pSpectInfo; uint8_t minIdx; + struct ch_params acs_ch_params; + int8_t center_freq_diff; + uint32_t combined_weight; + uint32_t min_ch_weight; pSpectInfo = pSpectInfoParams->pSpectCh; - /* for each VHT160 channel, calculate the combined weight of the - 8 20MHz weight */ - for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) { - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == - acs_vht160_channels[i].chStartNum) - break; + + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { + + if (pSpectInfo[j].weight_calc_done) + continue; + + acs_ch_params.ch_width = CH_WIDTH_160MHZ; + + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + pSpectInfo[j].chan_freq, + 0, &acs_ch_params); + + /* Check if the freq supports 160 Mhz */ + if (acs_ch_params.ch_width != CH_WIDTH_160MHZ) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8; + pSpectInfo[j].weight_calc_done = true; + continue; } - if (j == pSpectInfoParams->numSpectChans) + + center_freq_diff = acs_ch_params.mhz_freq_seg1 - + pSpectInfo[j].chan_freq; + + /* This channel frequency does not have all channels */ + if (center_freq_diff != 70) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8; + pSpectInfo[j].weight_calc_done = true; continue; + } - if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) && - ((pSpectInfo[j].chNum + 8) == - pSpectInfo[j + 2].chNum) && - ((pSpectInfo[j].chNum + 12) == - pSpectInfo[j + 3].chNum) && - ((pSpectInfo[j].chNum + 16) == - pSpectInfo[j + 4].chNum) && - ((pSpectInfo[j].chNum + 20) == - pSpectInfo[j + 5].chNum) && - ((pSpectInfo[j].chNum + 24) == - pSpectInfo[j + 6].chNum) && - ((pSpectInfo[j].chNum + 28) == - pSpectInfo[j + 7].chNum))) { + /* no other freq left for 160 Mhz operation in spectrum */ + if (j + 7 > pSpectInfoParams->numSpectChans) + continue; + + /* Check whether all frequencies are present for 160 Mhz */ + + if (!(((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq) && + ((pSpectInfo[j].chan_freq + 40) == + pSpectInfo[j + 2].chan_freq) && + ((pSpectInfo[j].chan_freq + 60) == + pSpectInfo[j + 3].chan_freq) && + ((pSpectInfo[j].chan_freq + 80) == + pSpectInfo[j + 4].chan_freq) && + ((pSpectInfo[j].chan_freq + 100) == + pSpectInfo[j + 5].chan_freq) && + ((pSpectInfo[j].chan_freq + 120) == + pSpectInfo[j + 6].chan_freq) && + ((pSpectInfo[j].chan_freq + 140) == + pSpectInfo[j + 7].chan_freq))) { /* * some channels does not exist in pSectInfo array, * skip this channel and those in the same VHT160 width */ pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 4) == - pSpectInfo[j + 1].chNum) + pSpectInfo[j].weight_calc_done = true; + if ((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq) { pSpectInfo[j + 1].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 8) == - pSpectInfo[j + 2].chNum) + pSpectInfo[j + 1].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 40) == + pSpectInfo[j + 2].chan_freq) { pSpectInfo[j + 2].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 12) == - pSpectInfo[j + 3].chNum) + pSpectInfo[j + 2].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 60) == + pSpectInfo[j + 3].chan_freq) { pSpectInfo[j + 3].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 16) == - pSpectInfo[j + 4].chNum) + pSpectInfo[j + 3].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 80) == + pSpectInfo[j + 4].chan_freq) { pSpectInfo[j + 4].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 20) == - pSpectInfo[j + 5].chNum) + pSpectInfo[j + 4].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 100) == + pSpectInfo[j + 5].chan_freq) { pSpectInfo[j + 5].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 24) == - pSpectInfo[j + 6].chNum) + pSpectInfo[j + 5].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 120) == + pSpectInfo[j + 6].chan_freq) { pSpectInfo[j + 6].weight = SAP_ACS_WEIGHT_MAX * 8; - if ((pSpectInfo[j].chNum + 28) == - pSpectInfo[j + 7].chNum) + pSpectInfo[j + 6].weight_calc_done = true; + } + if ((pSpectInfo[j].chan_freq + 140) == + pSpectInfo[j + 7].chan_freq) { pSpectInfo[j + 7].weight = SAP_ACS_WEIGHT_MAX * 8; + pSpectInfo[j + 7].weight_calc_done = true; + } + continue; } - /*found the channel, add the 7 adjacent channels' weight */ - acs_vht160_channels[i].weight = pSpectInfo[j].weight + - pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight + - pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight + - pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight + - pSpectInfo[j + 7].weight; - - /* find best channel among 8 channels as the primary channel */ - if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight + - pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) > - (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight + - pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight)) - idx = 4; - else - idx = 0; - /* find best channel among 4 channels as the primary channel */ - if ((pSpectInfo[j + idx].weight + - pSpectInfo[j + idx + 1].weight) < - (pSpectInfo[j + idx + 2].weight + - pSpectInfo[j + idx + 3].weight)) { - /* lower 2 channels are better choice */ - if (pSpectInfo[j + idx].weight < - pSpectInfo[j + idx + 1].weight) - minIdx = 0 + idx; - else - minIdx = 1 + idx; - } else if (pSpectInfo[j + idx + 2].weight <= - pSpectInfo[j + idx + 3].weight) { - /* upper 2 channels are better choice */ - minIdx = 2 + idx; - } else { - minIdx = 3 + idx; - } - /* - * set all 8 channels to max value first, then reset the - * best channel as the selected primary channel, update its - * weightage with the combined weight value - */ - for (n = 0; n < 8; n++) - pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8; - pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight; - } + /* We have 8 channels to calculate cumulative weight */ - /* - * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels - * and channel 132-173 as they cannot be part of a 160Mhz channel - * bonding. - */ - pSpectInfo = pSpectInfoParams->pSpectCh; - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) && - pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) || - (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) && - pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173))) - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8; + combined_weight = pSpectInfo[j].weight + + pSpectInfo[j + 1].weight + + pSpectInfo[j + 2].weight + + pSpectInfo[j + 3].weight + + pSpectInfo[j + 4].weight + + pSpectInfo[j + 5].weight + + pSpectInfo[j + 6].weight + + pSpectInfo[j + 7].weight; + + min_ch_weight = pSpectInfo[j].weight; + minIdx = 0; + + for (i = 0; i < 8; i++) { + if (min_ch_weight > pSpectInfo[j + i].weight) { + min_ch_weight = pSpectInfo[j + i].weight; + minIdx = i; + } + pSpectInfo[j + i].weight = SAP_ACS_WEIGHT_MAX * 8; + pSpectInfo[j + i].weight_calc_done = true; + } + + pSpectInfo[j + minIdx].weight = combined_weight; + + sap_debug("best freq = %d for 160mhz center freq %d combined weight = %d", + pSpectInfo[j + minIdx].chan_freq, + acs_ch_params.mhz_freq_seg1, + combined_weight); } sap_sort_chl_weight(pSpectInfoParams); pSpectInfo = pSpectInfoParams->pSpectCh; for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Channel=%d Weight= %d rssi=%d bssCount=%d"), - pSpectInfo->chNum, pSpectInfo->weight, - pSpectInfo->rssiAgr, pSpectInfo->bssCount); + sap_debug("freq = %d weight = %d rssi = %d bss count = %d", + pSpectInfo->chan_freq, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; } } @@ -1992,8 +1844,8 @@ static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams) * * Return: none */ -static void sap_allocate_max_weight_ht40_24_g( - tSapChSelSpectInfo *spect_info_params) +static void +sap_allocate_max_weight_40_mhz_24_g(tSapChSelSpectInfo *spect_info_params) { tSapSpectChInfo *spect_info; uint8_t j; @@ -2004,8 +1856,7 @@ static void sap_allocate_max_weight_ht40_24_g( */ spect_info = spect_info_params->pSpectCh; for (j = 0; j < spect_info_params->numSpectChans; j++) { - if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) && - spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14))) + if (WLAN_REG_IS_24GHZ_CH_FREQ(spect_info[j].chan_freq)) spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2; } } @@ -2017,8 +1868,8 @@ static void sap_allocate_max_weight_ht40_24_g( * * Return: none */ -static void sap_allocate_max_weight_ht40_5_g( - tSapChSelSpectInfo *spect_info_params) +static void +sap_allocate_max_weight_40_mhz(tSapChSelSpectInfo *spect_info_params) { tSapSpectChInfo *spect_info; uint8_t j; @@ -2029,8 +1880,8 @@ static void sap_allocate_max_weight_ht40_5_g( */ spect_info = spect_info_params->pSpectCh; for (j = 0; j < spect_info_params->numSpectChans; j++) { - if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) && - spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173))) + if (WLAN_REG_IS_5GHZ_CH_FREQ(spect_info[j].chan_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(spect_info[j].chan_freq)) spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2; } } @@ -2043,13 +1894,16 @@ static void sap_allocate_max_weight_ht40_5_g( * * Return: none */ -static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams, - v_REGDOMAIN_t domain) +static void sap_sort_chl_weight_ht40_24_g(struct mac_context *mac_ctx, + tSapChSelSpectInfo *pSpectInfoParams, + v_REGDOMAIN_t domain) { uint8_t i, j; tSapSpectChInfo *pSpectInfo; uint32_t tmpWeight1, tmpWeight2; uint32_t ht40plus2gendch = 0; + uint32_t channel; + uint32_t chan_freq; pSpectInfo = pSpectInfoParams->pSpectCh; /* @@ -2058,14 +1912,15 @@ static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams, */ for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) { for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == - acs_ht40_channels24_g[i].chStartNum) + channel = wlan_freq_to_chan(pSpectInfo[j].chan_freq); + if (channel == acs_ht40_channels24_g[i].chStartNum) break; } if (j == pSpectInfoParams->numSpectChans) continue; - if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) { + if (!((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 4].chan_freq)) { pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; continue; } @@ -2073,7 +1928,8 @@ static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams, * check if there is another channel combination possiblity * e.g., {1, 5} & {5, 9} */ - if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) { + if ((pSpectInfo[j + 4].chan_freq + 20) == + pSpectInfo[j + 8].chan_freq) { /* need to compare two channel pairs */ tmpWeight1 = pSpectInfo[j].weight + pSpectInfo[j + 4].weight; @@ -2143,132 +1999,142 @@ static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams, else ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END; for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) { + chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, i); for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == i && - ((pSpectInfo[j].chNum + 4) != - pSpectInfo[j+4].chNum) && - ((pSpectInfo[j].chNum - 4) != - pSpectInfo[j-4].chNum)) + if (pSpectInfo[j].chan_freq == chan_freq && + ((pSpectInfo[j].chan_freq + 20) != + pSpectInfo[j + 4].chan_freq) && + ((pSpectInfo[j].chan_freq - 20) != + pSpectInfo[j - 4].chan_freq)) pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; } } for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) { + chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, i); for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == i && - (pSpectInfo[j].chNum - 4) != - pSpectInfo[j-4].chNum) + if (pSpectInfo[j].chan_freq == chan_freq && + (pSpectInfo[j].chan_freq - 20) != + pSpectInfo[j - 4].chan_freq) pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; } } pSpectInfo = pSpectInfoParams->pSpectCh; for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", - __func__, pSpectInfo->chNum, pSpectInfo->weight, + sap_debug("freq = %d weight = %d rssi = %d bss count = %d", + pSpectInfo->chan_freq, pSpectInfo->weight, pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; } sap_sort_chl_weight(pSpectInfoParams); } -/*========================================================================== - FUNCTION sap_sort_chl_weight_ht40_5_g +static void sap_sort_chl_weight_40_mhz(struct mac_context *mac_ctx, + tSapChSelSpectInfo *pSpectInfoParams) +{ + uint8_t i, j; + tSapSpectChInfo *pSpectInfo; + uint8_t minIdx; + struct ch_params acs_ch_params; + int8_t center_freq_diff; + uint32_t combined_weight; + uint32_t min_ch_weight; - DESCRIPTION - Function to sort the channels with the least weight first for HT40 channels + pSpectInfo = pSpectInfoParams->pSpectCh; - DEPENDENCIES - NA. + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - PARAMETERS + if (WLAN_REG_IS_24GHZ_CH_FREQ(pSpectInfo[j].chan_freq)) + continue; - IN - pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + if (pSpectInfo[j].weight_calc_done) + continue; - RETURN VALUE - void : NULL + acs_ch_params.ch_width = CH_WIDTH_40MHZ; - SIDE EFFECTS - ============================================================================*/ -static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams) -{ - uint8_t i, j; - tSapSpectChInfo *pSpectInfo; + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + pSpectInfo[j].chan_freq, + 0, &acs_ch_params); - pSpectInfo = pSpectInfoParams->pSpectCh; - /*for each HT40 channel, calculate the combined weight of the - two 20MHz weight */ - for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) { - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum == - acs_ht40_channels5_g[i].chStartNum) - break; + /* Check if the freq supports 40 Mhz */ + if (acs_ch_params.ch_width != CH_WIDTH_40MHZ) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; + pSpectInfo[j].weight_calc_done = true; + continue; } - if (j == pSpectInfoParams->numSpectChans) + + center_freq_diff = acs_ch_params.mhz_freq_seg0 - + pSpectInfo[j].chan_freq; + + /* This channel frequency does not have all channels */ + if (center_freq_diff != 10) { + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; + pSpectInfo[j].weight_calc_done = true; continue; + } - /* found the channel, add the two adjacent channels' weight */ - if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) { - acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight + - pSpectInfo[j + 1].weight; - /* select better of the adjact channel as the primary channel */ - if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) { - pSpectInfo[j].weight = - acs_ht40_channels5_g[i].weight; - /* mark the adjacent channel's weight as max value so - that it will be sorted to the bottom */ + /* no other freq left for 40 Mhz operation in spectrum */ + if (j + 1 > pSpectInfoParams->numSpectChans) + continue; + + /* Check whether all frequencies are present for 40 Mhz */ + + if (!((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq)) { + /* + * some channels does not exist in pSectInfo array, + * skip this channel and those in the same 40 width + */ + pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; + pSpectInfo[j].weight_calc_done = true; + + if ((pSpectInfo[j].chan_freq + 20) == + pSpectInfo[j + 1].chan_freq) { pSpectInfo[j + 1].weight = SAP_ACS_WEIGHT_MAX * 2; - } else { - pSpectInfo[j + 1].weight = - acs_ht40_channels5_g[i].weight; - /* mark the adjacent channel's weight as max value so - that it will be sorted to the bottom */ - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; + pSpectInfo[j +1].weight_calc_done = true; } - } else - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; - } + continue; + } - /* - *Every channel should be checked. Add the check for the omissive - * channel. Mark the channel whose combination can't satisfy 40MHZ - * as max value, so that it will be sorted to the bottom - */ - for (j = 1; j < pSpectInfoParams->numSpectChans; j++) { - for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) { - if (pSpectInfo[j].chNum == - (acs_ht40_channels5_g[i].chStartNum + - 4) && - pSpectInfo[j - 1].chNum != - acs_ht40_channels5_g[i].chStartNum) { - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; - break; + /* We have 2 channels to calculate cumulative weight */ + + combined_weight = pSpectInfo[j].weight + + pSpectInfo[j + 1].weight; + + min_ch_weight = pSpectInfo[j].weight; + minIdx = 0; + + for (i = 0; i < 2; i++) { + if (min_ch_weight > pSpectInfo[j + i].weight) { + min_ch_weight = pSpectInfo[j + i].weight; + minIdx = i; } + pSpectInfo[j + i].weight = SAP_ACS_WEIGHT_MAX * 2; + pSpectInfo[j + i].weight_calc_done = true; } - } - /* avoid channel 165 by setting its weight to max */ - pSpectInfo = pSpectInfoParams->pSpectCh; - for (j = 0; j < pSpectInfoParams->numSpectChans; j++) { - if (pSpectInfo[j].chNum >= CHANNEL_165) { - pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2; - break; - } + + pSpectInfo[j + minIdx].weight = combined_weight; + + sap_debug("best freq = %d for 40mhz center freq %d combined weight = %d", + pSpectInfo[j + minIdx].chan_freq, + acs_ch_params.mhz_freq_seg0, + combined_weight); } + sap_sort_chl_weight(pSpectInfoParams); + pSpectInfo = pSpectInfoParams->pSpectCh; for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", - __func__, pSpectInfo->chNum, pSpectInfo->weight, + sap_debug("freq = %d weight = %d rssi = %d bss count = %d", + pSpectInfo->chan_freq, pSpectInfo->weight, pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; } - - sap_sort_chl_weight(pSpectInfoParams); } /*========================================================================== @@ -2291,19 +2157,16 @@ static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams) SIDE EFFECTS ============================================================================*/ -static void sap_sort_chl_weight_all(struct sap_context *sap_ctx, +static void sap_sort_chl_weight_all(struct mac_context *mac_ctx, + struct sap_context *sap_ctx, tSapChSelSpectInfo *pSpectInfoParams, uint32_t operatingBand, v_REGDOMAIN_t domain) { tSapSpectChInfo *pSpectCh = NULL; uint32_t j = 0; -#ifndef SOFTAP_CHANNEL_RANGE - uint32_t i = 0; -#endif pSpectCh = pSpectInfoParams->pSpectCh; -#ifdef SOFTAP_CHANNEL_RANGE switch (sap_ctx->acs_cfg->ch_width) { case CH_WIDTH_40MHZ: @@ -2313,19 +2176,21 @@ static void sap_sort_chl_weight_all(struct sap_context *sap_ctx, * or 11abg to avoid selection in ACS algorithm for starting SAP */ if (eCSR_DOT11_MODE_11g == operatingBand) { - sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain); - sap_allocate_max_weight_ht40_5_g(pSpectInfoParams); + sap_allocate_max_weight_40_mhz(pSpectInfoParams); + sap_sort_chl_weight_ht40_24_g(mac_ctx, + pSpectInfoParams, + domain); } else { - sap_allocate_max_weight_ht40_24_g(pSpectInfoParams); - sap_sort_chl_weight_ht40_5_g(pSpectInfoParams); + sap_allocate_max_weight_40_mhz_24_g(pSpectInfoParams); + sap_sort_chl_weight_40_mhz(mac_ctx, pSpectInfoParams); } break; case CH_WIDTH_80MHZ: case CH_WIDTH_80P80MHZ: - sap_sort_chl_weight_ht80(pSpectInfoParams); + sap_sort_chl_weight_80_mhz(mac_ctx, pSpectInfoParams); break; case CH_WIDTH_160MHZ: - sap_sort_chl_weight_vht160(pSpectInfoParams); + sap_sort_chl_weight_160_mhz(mac_ctx, pSpectInfoParams); break; case CH_WIDTH_20MHZ: default: @@ -2333,34 +2198,10 @@ static void sap_sort_chl_weight_all(struct sap_context *sap_ctx, sap_sort_chl_weight(pSpectInfoParams); } -#else - /* Sorting the channels as per weights */ - for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) { - minWeightIndex = i; - for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) { - if (pSpectCh[j].weight < - pSpectCh[minWeightIndex].weight) { - minWeightIndex = j; - } - } - if (minWeightIndex != i) { - qdf_mem_copy(&temp, &pSpectCh[minWeightIndex], - sizeof(*pSpectCh)); - qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], - sizeof(*pSpectCh)); - qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh)); - } - } -#endif - - /* For testing */ - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "In %s, Sorted Spectrum Channels Weight", __func__); pSpectCh = pSpectInfoParams->pSpectCh; for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", - __func__, pSpectCh->chNum, pSpectCh->weight, + sap_debug("Freq = %d weight = %d rssi aggr = %d bss count = %d", + pSpectCh->chan_freq, pSpectCh->weight, pSpectCh->rssiAgr, pSpectCh->bssCount); pSpectCh++; } @@ -2385,7 +2226,7 @@ static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch) return false; } -uint8_t sap_select_channel(mac_handle_t mac_handle, +uint32_t sap_select_channel(mac_handle_t mac_handle, struct sap_context *sap_ctx, qdf_list_t *scan_list) { @@ -2397,33 +2238,20 @@ uint8_t sap_select_channel(mac_handle_t mac_handle, uint32_t ht40plus2gendch = 0; v_REGDOMAIN_t domain; uint8_t country[CDS_COUNTRY_CODE_LEN + 1]; -#ifdef SOFTAP_CHANNEL_RANGE uint8_t count; - uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0; -#endif + uint32_t operating_band = 0; struct mac_context *mac_ctx; + uint32_t best_chan_freq = 0; mac_ctx = MAC_CONTEXT(mac_handle); - /* - * If ACS weight is not enabled on noise_floor/channel_free/tx_power, - * then skip acs process if no bss found. - */ - if ((!scan_list || !qdf_list_size(scan_list)) && - !(sap_ctx->auto_channel_select_weight & 0xffff00)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("No external AP present")); - - return sap_select_default_oper_chan(mac_ctx, - sap_ctx->acs_cfg); - } - /* Initialize the structure pointed by spect_info */ if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("Ch Select initialization failed")); return SAP_CHANNEL_NOT_SELECTED; } + /* Compute the weight of the entire spectrum in the operating band */ sap_compute_spect_weight(spect_info, mac_handle, scan_list, sap_ctx); @@ -2434,128 +2262,97 @@ uint8_t sap_select_channel(mac_handle_t mac_handle, wlan_reg_read_current_country(mac_ctx->psoc, country); wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER); -#ifdef SOFTAP_CHANNEL_RANGE - start_ch_num = sap_ctx->acs_cfg->start_ch; - end_ch_num = sap_ctx->acs_cfg->end_ch; + SET_ACS_BAND(operating_band, sap_ctx); /* Sort the ch lst as per the computed weights, lesser weight first. */ - sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain); + sap_sort_chl_weight_all(mac_ctx, sap_ctx, spect_info, operating_band, + domain); /*Loop till get the best channel in the given range */ for (count = 0; count < spect_info->numSpectChans; count++) { - if ((start_ch_num > spect_info->pSpectCh[count].chNum) || - (end_ch_num < spect_info->pSpectCh[count].chNum)) + best_chan_freq = spect_info->pSpectCh[count].chan_freq; + /* check if best_ch_num is in preferred channel list */ + best_chan_freq = + sap_select_preferred_channel_from_channel_list( + best_chan_freq, sap_ctx, spect_info); + /* if not in preferred ch lst, go to nxt best ch */ + if (best_chan_freq == SAP_CHANNEL_NOT_SELECTED) continue; - if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) { - best_ch_num = spect_info->pSpectCh[count].chNum; - /* check if best_ch_num is in preferred channel list */ - best_ch_num = - sap_select_preferred_channel_from_channel_list( - best_ch_num, sap_ctx, spect_info); - /* if not in preferred ch lst, go to nxt best ch */ - if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) - continue; - #ifdef FEATURE_AP_MCC_CH_AVOIDANCE - /* - * Weight of the channels(device's AP is operating) - * increased to MAX+1 so that they will be chosen only - * when there is no other best channel to choose - */ - if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) { - best_ch_num = SAP_CHANNEL_NOT_SELECTED; - continue; - } -#endif - - best_ch_weight = - spect_info->pSpectCh[count].weight_copy; - } - - if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) - continue; - - if (operating_band != eCSR_DOT11_MODE_11g) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO_HIGH, - "operating_band %d", operating_band); + /* + * Weight of the channels(device's AP is operating) + * increased to MAX+1 so that they will be chosen only + * when there is no other best channel to choose + */ + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(best_chan_freq) && + sap_check_in_avoid_ch_list(sap_ctx, + wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq))) { + best_chan_freq = SAP_CHANNEL_NOT_SELECTED; continue; } +#endif /* Give preference to Non-overlap channels */ - if (false == sap_is_ch_non_overlap(sap_ctx, - spect_info->pSpectCh[count].chNum)) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO_HIGH, - FL("ch: %d skipped as its overlapping ch"), - spect_info->pSpectCh[count].chNum); + if (WLAN_REG_IS_24GHZ_CH_FREQ(best_chan_freq) && + !sap_is_ch_non_overlap(sap_ctx, + wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq))) { + sap_debug("freq %d is overlapping, skipped", + best_chan_freq); continue; } - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, - spect_info->pSpectCh[count].chNum) && - policy_mgr_disallow_mcc(mac_ctx->psoc, - spect_info->pSpectCh[count].chNum)) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO_HIGH, - "No DFS MCC"); - continue; - } - - if (spect_info->pSpectCh[count].weight_copy > best_ch_weight) - continue; - - tmp_ch_num = spect_info->pSpectCh[count].chNum; - tmp_ch_num = sap_channel_in_acs_channel_list( - tmp_ch_num, sap_ctx, spect_info); - if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED) - continue; + best_ch_weight = spect_info->pSpectCh[count].weight; + sap_debug("Freq = %d selected as best frequency weight = %d", + best_chan_freq, best_ch_weight); - best_ch_num = tmp_ch_num; break; } -#else - /* Sort the ch lst as per the computed weights, lesser weight first. */ - sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info); - /* Get the first channel in sorted array as best 20M Channel */ - best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum; - /* Select Best Channel from Channel List if Configured */ - best_ch_num = sap_select_preferred_channel_from_channel_list( - best_ch_num, sap_ctx, spect_info); -#endif /* * in case the best channel seleted is not in PCL and there is another * channel which has same weightage and is in PCL, choose the one in * PCL */ - for (count = 0; count < spect_info->numSpectChans; count++) { - if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) || - (spect_info->pSpectCh[count].weight != best_ch_weight)) - continue; + if (!ch_in_pcl(sap_ctx, best_chan_freq)) { + uint32_t cal_chan_freq, cal_chan_weight; + for (count = 0; count < spect_info->numSpectChans; count++) { + cal_chan_freq = spect_info->pSpectCh[count].chan_freq; + cal_chan_weight = spect_info->pSpectCh[count].weight; + /* skip pcl channel whose weight is bigger than best */ + if (!ch_in_pcl(sap_ctx, cal_chan_freq) || + (cal_chan_weight > best_ch_weight)) + continue; - if (sap_select_preferred_channel_from_channel_list( - spect_info->pSpectCh[count].chNum, sap_ctx, spect_info) - == SAP_CHANNEL_NOT_SELECTED) - continue; + if (best_chan_freq == cal_chan_freq) + continue; -#ifdef FEATURE_AP_MCC_CH_AVOIDANCE - if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) - continue; -#endif - best_ch_num = spect_info->pSpectCh[count].chNum; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("change best channel to %d in PCL"), best_ch_num); - break; + if (sap_select_preferred_channel_from_channel_list( + cal_chan_freq, sap_ctx, + spect_info) + == SAP_CHANNEL_NOT_SELECTED) + continue; + + best_chan_freq = cal_chan_freq; + sap_debug("Changed best freq to %d Preferred freq", + best_chan_freq); + + break; + } } - sap_ctx->acs_cfg->pri_ch = best_ch_num; + sap_ctx->acs_cfg->pri_ch_freq = best_chan_freq; + + /* Below code is for 2.4Ghz freq, so freq to channel is safe here */ + /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */ if ((operating_band != eCSR_DOT11_MODE_11g) || (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ)) goto sap_ch_sel_end; + + best_ch_num = wlan_reg_freq_to_chan(mac_ctx->pdev, best_chan_freq); + if (REGDOMAIN_FCC == domain) ht40plus2gendch = HT40PLUS_2G_FCC_CH_END; else @@ -2568,38 +2365,33 @@ uint8_t sap_select_channel(mac_handle_t mac_handle, weight_below = weight_above = SAP_ACS_WEIGHT_MAX; pspect_info = spect_info->pSpectCh; for (i = 0; i < spect_info->numSpectChans; i++) { - if (pspect_info[i].chNum == (best_ch_num - 4)) + if (pspect_info[i].chan_freq == (best_chan_freq - 20)) weight_below = pspect_info[i].weight; - if (pspect_info[i].chNum == (best_ch_num + 4)) + if (pspect_info[i].chan_freq == (best_ch_num + 20)) weight_above = pspect_info[i].weight; } if (weight_below < weight_above) - sap_ctx->acs_cfg->ht_sec_ch = - sap_ctx->acs_cfg->pri_ch - 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq - 20; else - sap_ctx->acs_cfg->ht_sec_ch = - sap_ctx->acs_cfg->pri_ch + 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq + 20; } else if (best_ch_num >= 1 && best_ch_num <= 4) { - sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq + 20; } else if (best_ch_num >= ht40plus2gendch && best_ch_num <= HT40MINUS_2G_CH_END) { - sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4; + sap_ctx->acs_cfg->ht_sec_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq - 20; } else if (best_ch_num == 14) { - sap_ctx->acs_cfg->ht_sec_ch = 0; + sap_ctx->acs_cfg->ht_sec_ch_freq = 0; } - sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch; + sap_ctx->sec_ch_freq = sap_ctx->acs_cfg->ht_sec_ch_freq; sap_ch_sel_end: /* Free all the allocated memory */ sap_chan_sel_exit(spect_info); - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num); - host_log_acs_best_chan(best_ch_num, best_ch_weight); - - if (best_ch_num > 0 && best_ch_num <= 252) - return best_ch_num; - else - return SAP_CHANNEL_NOT_SELECTED; + return best_chan_freq; } diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.h b/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.h index e038f989848be5c5fe681a51eb435bdb3d1dc341..5dddc4aba00c69b1999dbc89a474c8a44b75bf36 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.h +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_ch_select.h @@ -102,29 +102,14 @@ typedef enum { #define SAP_40MHZ_MASK_L 0x03 #define SAP_40MHZ_MASK_H 0x0C -/* - * structs for holding channel bonding bitmap - * used for finding new channel when SAP is on - * DFS channel and radar is detected. - */ -typedef struct sChannelBondingInfo { - uint8_t channelMap:4; - uint8_t rsvd:4; - uint8_t startChannel; -} tChannelBondingInfo; - -typedef struct __chan_bonding_bitmap { - tChannelBondingInfo chanBondingSet[MAX_80MHZ_BANDS]; -} chan_bonding_bitmap; - typedef struct { - uint16_t chNum; /* Channel Number */ - uint16_t channelWidth; /* Channel Width */ + uint32_t chan_freq; uint16_t bssCount; /* bss found in scanresult for this channel */ int32_t rssiAgr; /* Max value of rssi among all BSS(es) from scanresult for this channel */ uint32_t weight; /* Weightage of this channel */ uint32_t weight_copy; /* copy of the orignal weight */ bool valid; /* Is this a valid center frequency for regulatory domain */ + bool weight_calc_done; } tSapSpectChInfo; /* tDfsSpectChInfo; */ /** diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c b/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c index f81ce56036a3892337c4f3821ac51d02b48fe543..3a43f338d99ea9e389ab5ff67bfdb3e0440e2258 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -81,9 +81,9 @@ * Static Function Declarations and Definitions * -------------------------------------------------------------------------*/ #ifdef SOFTAP_CHANNEL_RANGE -static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, - uint8_t **ch_list, - uint8_t *num_ch); +static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, + uint32_t **freq_list, + uint8_t *num_ch); #endif /*========================================================================== @@ -218,7 +218,7 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) ch_params->ch_width = ch_wd; if (sap_ctx->acs_cfg) { acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode; - acs_info.channel_list = sap_ctx->acs_cfg->master_ch_list; + acs_info.chan_freq_list = sap_ctx->acs_cfg->master_freq_list; acs_info.num_of_channel = sap_ctx->acs_cfg->master_ch_list_count; } else { @@ -236,8 +236,8 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) sap_operating_chan_preferred_location == 2) flag |= DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; - if (QDF_IS_STATUS_ERROR(utils_dfs_get_random_channel( - pdev, flag, ch_params, &hw_mode, &ch, &acs_info))) { + if (QDF_IS_STATUS_ERROR(utils_dfs_get_vdev_random_channel( + pdev, sap_ctx->vdev, flag, ch_params, &hw_mode, &ch, &acs_info))) { /* No available channel found */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("No available channel found!!!")); @@ -262,7 +262,7 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) /** * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding. - * @sap_ctx: sap context + * @sap_ctx: sap context. * * Check if the current SAP operating channel is bonded to weather radar * channel in ETSI domain. @@ -272,7 +272,8 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) static bool sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx) { - if (IS_CH_BONDING_WITH_WEATHER_CH(sap_ctx->channel) && + if (IS_CH_BONDING_WITH_WEATHER_CH(wlan_freq_to_chan( + sap_ctx->chan_freq)) && (sap_ctx->ch_params.ch_width != CH_WIDTH_20MHZ)) return true; @@ -448,7 +449,7 @@ void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx, if (*dfs_region != DFS_ETSI_REGION) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - FL("sapdfs: default cac duration")); + FL("sapdfs: default cac duration")); return; } @@ -476,16 +477,13 @@ void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx, void sap_dfs_set_current_channel(void *ctx) { struct sap_context *sap_ctx = ctx; - uint32_t ic_flags = 0; - uint16_t ic_flagext = 0; - uint8_t ic_ieee = sap_ctx->channel; - uint16_t ic_freq = utils_dfs_chan_to_freq(sap_ctx->channel); uint8_t vht_seg0 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; uint8_t vht_seg1 = sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; struct wlan_objmgr_pdev *pdev; struct mac_context *mac_ctx; uint32_t use_nol = 0; int error; + bool is_dfs; mac_ctx = sap_get_mac_context(); if (!mac_ctx) { @@ -500,54 +498,25 @@ void sap_dfs_set_current_channel(void *ctx) return; } - switch (sap_ctx->csr_roamProfile.ch_params.ch_width) { - case CH_WIDTH_20MHZ: - ic_flags |= IEEE80211_CHAN_VHT20; - break; - case CH_WIDTH_40MHZ: - ic_flags |= IEEE80211_CHAN_VHT40PLUS; - break; - case CH_WIDTH_80MHZ: - ic_flags |= IEEE80211_CHAN_VHT80; - break; - case CH_WIDTH_80P80MHZ: - ic_flags |= IEEE80211_CHAN_VHT80_80; - break; - case CH_WIDTH_160MHZ: - ic_flags |= IEEE80211_CHAN_VHT160; - break; - default: - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid channel width=%d"), - sap_ctx->csr_roamProfile.ch_params.ch_width); - return; - } - - if (WLAN_REG_IS_24GHZ_CH(sap_ctx->channel)) - ic_flags |= IEEE80211_CHAN_2GHZ; - else - ic_flags |= IEEE80211_CHAN_5GHZ; - - if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) { - ic_flagext |= IEEE80211_CHAN_DFS; - tgt_dfs_set_current_channel(pdev, ic_freq, ic_flags, ic_flagext, - ic_ieee, vht_seg0, vht_seg1); - } + is_dfs = wlan_reg_is_dfs_for_freq(pdev, sap_ctx->chan_freq); QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - FL("freq=%d, channel=%d, seg0=%d, seg1=%d, flags=0x%x, ext flags=0x%x"), - ic_freq, ic_ieee, vht_seg0, vht_seg1, ic_flags, ic_flagext); + FL("freq=%d, dfs %d seg0=%d, seg1=%d, bw %d"), + sap_ctx->chan_freq, is_dfs, vht_seg0, vht_seg1, + sap_ctx->csr_roamProfile.ch_params.ch_width); - if (wlan_reg_is_dfs_ch(pdev, sap_ctx->channel)) { + if (is_dfs) { if (policy_mgr_concurrent_beaconing_sessions_running( mac_ctx->psoc)) { - uint16_t con_ch; + uint16_t con_ch_freq; mac_handle_t handle = MAC_HANDLE(mac_ctx); - con_ch = + con_ch_freq = sme_get_beaconing_concurrent_operation_channel( handle, sap_ctx->sessionId); - if (!con_ch || !wlan_reg_is_dfs_ch(pdev, con_ch)) + if (!con_ch_freq || + !wlan_reg_is_dfs_for_freq(pdev, + con_ch_freq)) tgt_dfs_get_radars(pdev); } else { tgt_dfs_get_radars(pdev); @@ -614,9 +583,17 @@ sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context, return false; } + pdev = mac_ctx->pdev; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("null pdev")); + return false; + } + /* get the bonded channels */ - if (channel_number == sap_context->channel && chan_bondState >= - PHY_CHANNEL_BONDING_STATE_MAX) + if ((channel_number == wlan_reg_freq_to_chan(pdev, + sap_context->chan_freq)) && + chan_bondState >= PHY_CHANNEL_BONDING_STATE_MAX) num_channels = sap_ch_params_to_bonding_channels( &sap_context->ch_params, channels); else @@ -624,13 +601,6 @@ sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context, channel_number, channels, MAX_BONDED_CHANNELS, chan_bondState); - pdev = mac_ctx->pdev; - if (!pdev) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("null pdev")); - return false; - } - /* check for NOL, first on will break the loop */ for (i = 0; i < num_channels; i++) { ch_state = wlan_reg_get_channel_state(pdev, channels[i]); @@ -674,8 +644,9 @@ sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, return true; /* get the bonded channels */ - if (channel_number == sap_context->channel && bond_state >= - PHY_CHANNEL_BONDING_STATE_MAX) + if ((channel_number == wlan_reg_freq_to_chan(pdev, + sap_context->chan_freq)) && + bond_state >= PHY_CHANNEL_BONDING_STATE_MAX) num_channels = sap_ch_params_to_bonding_channels( &sap_context->ch_params, channels); else @@ -695,25 +666,25 @@ sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, return false; } -uint8_t sap_select_default_oper_chan(struct mac_context *mac_ctx, - struct sap_acs_cfg *acs_cfg) +uint32_t sap_select_default_oper_chan(struct mac_context *mac_ctx, + struct sap_acs_cfg *acs_cfg) { uint16_t i; + uint32_t freq0 = 0, freq1 = 0, freq2 = 0, default_freq; if (!acs_cfg) return 0; - if (!acs_cfg->ch_list_count || !acs_cfg->ch_list) { + if (!acs_cfg->ch_list_count || !acs_cfg->freq_list) { if (mac_ctx->mlme_cfg->acs.force_sap_start) { sap_debug("SAP forced, freq selected %d", - acs_cfg->master_ch_list[0]); - return acs_cfg->master_ch_list[0]; + acs_cfg->master_freq_list[0]); + return acs_cfg->master_freq_list[0]; } else { sap_debug("No channel left for operation"); return 0; } } - /* * There could be both 2.4Ghz and 5ghz channels present in the list * based upon the Hw mode received from hostapd, it is always better @@ -722,19 +693,56 @@ uint8_t sap_select_default_oper_chan(struct mac_context *mac_ctx, * rare in 2.4ghz band, so 5ghz should be preferred. If we get a 5Ghz * chan in the acs cfg ch list , we should go for that first else the * default channel can be 2.4ghz. + * Add check regulatory channel state before select the channel. */ for (i = 0; i < acs_cfg->ch_list_count; i++) { - if (WLAN_CHAN_IS_5GHZ(acs_cfg->ch_list[i])) { - sap_debug("default channel chosen as %d", - acs_cfg->ch_list[i]); - return acs_cfg->ch_list[i]; + enum channel_state state = + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, acs_cfg->freq_list[i]); + if (!freq0 && state == CHANNEL_STATE_ENABLE && + WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) { + freq0 = acs_cfg->freq_list[i]; + break; + } else if (!freq1 && state == CHANNEL_STATE_DFS && + WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) { + freq1 = acs_cfg->freq_list[i]; + } else if (!freq2 && state == CHANNEL_STATE_ENABLE) { + freq2 = acs_cfg->freq_list[i]; } } + default_freq = freq0; + if (!default_freq) + default_freq = freq1; + if (!default_freq) + default_freq = freq2; + if (!default_freq) + default_freq = acs_cfg->freq_list[0]; - sap_debug("default channel chosen as %d", acs_cfg->ch_list[0]); + sap_debug("default freq %d chosen from %d %d %d %d", default_freq, + freq0, freq1, freq2, acs_cfg->freq_list[0]); + + return default_freq; +} + +static bool is_mcc_preferred(struct sap_context *sap_context, + uint32_t con_ch_freq) +{ + /* + * If SAP ACS channel list is 1-11 and STA is on non-preferred + * channel i.e. 12, 13, 14 then MCC is unavoidable. This is because + * if SAP is started on 12,13,14 some clients may not be able to + * join dependending on their regulatory country. + */ + if ((con_ch_freq >= 2467) && (con_ch_freq <= 2484) && + (sap_context->acs_cfg->start_ch_freq >= 2412 && + sap_context->acs_cfg->end_ch_freq <= 2462)) { + sap_debug("conc ch freq %d & sap acs ch list is 1-11, prefer mcc", + con_ch_freq); + return true; + } - return acs_cfg->ch_list[0]; + return false; } QDF_STATUS @@ -744,10 +752,8 @@ sap_validate_chan(struct sap_context *sap_context, { QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; struct mac_context *mac_ctx; - bool is_dfs; - bool is_safe; mac_handle_t mac_handle; - uint8_t con_ch; + uint32_t con_ch_freq; bool sta_sap_scc_on_dfs_chan; uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK; uint32_t sta_sap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK; @@ -763,12 +769,11 @@ sap_validate_chan(struct sap_context *sap_context, return QDF_STATUS_E_FAULT; } - if (!sap_context->channel) { + if (!sap_context->chan_freq) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("Invalid channel")); return QDF_STATUS_E_FAILURE; } - go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc); if (sap_context->vdev && !go_force_scc && (wlan_vdev_mlme_get_opmode(sap_context->vdev) == QDF_P2P_GO_MODE)) @@ -778,76 +783,9 @@ sap_validate_chan(struct sap_context *sap_context, if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || ((concurrent_state & sta_sap_bit_mask) == sta_sap_bit_mask) || ((concurrent_state & sta_go_bit_mask) == sta_go_bit_mask)) { - con_ch = - sme_get_beaconing_concurrent_operation_channel( - mac_handle, sap_context->sessionId); -#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE - if (con_ch && sap_context->channel != con_ch && - wlan_reg_is_dfs_ch(mac_ctx->pdev, - sap_context->channel)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, - FL("MCC DFS not supported in AP_AP Mode")); - return QDF_STATUS_E_ABORTED; - } -#endif -#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH - if (con_ch && (sap_context->cc_switch_mode != - QDF_MCC_TO_SCC_SWITCH_DISABLE)) { - /* - * For ACS request ,the sap_ctx->channel is 0, - * we skip below overlap checking. When the ACS - * finish and SAPBSS start, the sap_ctx->channel - * will not be 0. Then the overlap checking will be - * reactivated.If we use sap_ctx->channel = 0 - * to perform the overlap checking, an invalid overlap - * channel con_ch could becreated. That may cause - * SAP start failed. - */ - con_ch = sme_check_concurrent_channel_overlap( - mac_handle, - sap_context->channel, - sap_context->csr_roamProfile.phyMode, - sap_context->cc_switch_mode); - - sta_sap_scc_on_dfs_chan = - policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( - mac_ctx->psoc); - - if (sap_context->cc_switch_mode == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) - sta_sap_scc_on_dfs_chan = false; - - is_dfs = wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch); - is_safe = policy_mgr_is_safe_channel( - mac_ctx->psoc, con_ch); - - if (con_ch && is_safe && - (!is_dfs || (is_dfs && sta_sap_scc_on_dfs_chan))) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - "%s: Override ch %d to %d due to CC Intf", - __func__, sap_context->channel, con_ch); - sap_context->channel = con_ch; - if (WLAN_REG_IS_24GHZ_CH(con_ch)) - sap_context->ch_params.ch_width = - CH_WIDTH_20MHZ; - wlan_reg_set_channel_params(mac_ctx->pdev, - sap_context->channel, 0, - &sap_context->ch_params); - } - } -#endif - } - - if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) == - (QDF_STA_MASK | QDF_SAP_MASK)) || - ((sap_context->cc_switch_mode == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && - (policy_mgr_get_concurrency_mode(mac_ctx->psoc) == - (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, - sap_context->channel)) { + if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + sap_context->chan_freq)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, FL("DFS not supported in STA_AP Mode")); return QDF_STATUS_E_ABORTED; @@ -856,20 +794,20 @@ sap_validate_chan(struct sap_context *sap_context, #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH if (sap_context->cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_DISABLE) { - con_ch = sme_check_concurrent_channel_overlap( + con_ch_freq = sme_check_concurrent_channel_overlap( mac_handle, - sap_context->channel, + sap_context->chan_freq, sap_context->csr_roamProfile.phyMode, sap_context->cc_switch_mode); QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("After check overlap: con_ch:%d"), - con_ch); + con_ch_freq); if (sap_context->cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) { if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( - mac_ctx->psoc, &con_ch, - sap_context->channel, + mac_ctx->psoc, &con_ch_freq, + sap_context->chan_freq, sap_context->sessionId))) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, @@ -879,56 +817,63 @@ sap_validate_chan(struct sap_context *sap_context, } QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("After check concurrency: con_ch:%d"), - con_ch); + con_ch_freq); sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( mac_ctx->psoc); - if (con_ch && + if (con_ch_freq && (policy_mgr_sta_sap_scc_on_lte_coex_chan( mac_ctx->psoc) || - policy_mgr_is_safe_channel(mac_ctx->psoc, - con_ch)) && - (!wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch) || - sta_sap_scc_on_dfs_chan)) { + policy_mgr_is_safe_channel( + mac_ctx->psoc, con_ch_freq)) && + (!wlan_reg_is_dfs_for_freq( + mac_ctx->pdev, con_ch_freq) || + sta_sap_scc_on_dfs_chan)) { + if (is_mcc_preferred(sap_context, con_ch_freq)) + goto validation_done; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s: Override ch %d to %d due to CC Intf", - __func__, sap_context->channel, con_ch); - sap_context->channel = con_ch; - if (WLAN_REG_IS_24GHZ_CH(con_ch)) + "%s: Override ch freq %d to %d due to CC Intf", + __func__, sap_context->chan_freq, + con_ch_freq); + sap_context->chan_freq = con_ch_freq; + if (WLAN_REG_IS_24GHZ_CH_FREQ( + sap_context->chan_freq)) sap_context->ch_params.ch_width = CH_WIDTH_20MHZ; - wlan_reg_set_channel_params(mac_ctx->pdev, - sap_context->channel, 0, - &sap_context->ch_params); + wlan_reg_set_channel_params_for_freq( + mac_ctx->pdev, + sap_context->chan_freq, + 0, + &sap_context->ch_params); } } #endif } - validation_done: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("for configured channel, Ch= %d"), - sap_context->channel); + FL("for configured channel, Ch_freq = %d"), + sap_context->chan_freq); + if (check_for_connection_update) { /* This wait happens in the hostapd context. The event * is set in the MC thread context. */ qdf_status = policy_mgr_update_and_wait_for_connection_update( - mac_ctx->psoc, - sap_context->sessionId, - sap_context->channel, - POLICY_MGR_UPDATE_REASON_START_AP); + mac_ctx->psoc, sap_context->sessionId, + sap_context->chan_freq, + POLICY_MGR_UPDATE_REASON_START_AP); if (QDF_IS_STATUS_ERROR(qdf_status)) return qdf_status; } if (pre_start_bss) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - FL("ACS end due to Ch override. Sel Ch = %d"), - sap_context->channel); - sap_context->acs_cfg->pri_ch = sap_context->channel; + FL("ACS end due to Ch override. Sel Ch freq = %d"), + sap_context->chan_freq); + sap_context->acs_cfg->pri_ch_freq = sap_context->chan_freq; sap_context->acs_cfg->ch_width = sap_context->ch_width_orig; sap_config_acs_result(mac_handle, sap_context, 0); @@ -945,10 +890,10 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) struct scan_start_request *req; struct wlan_objmgr_vdev *vdev = NULL; uint8_t i; - uint8_t *channel_list = NULL; + uint32_t *freq_list = NULL; uint8_t num_of_channels = 0; mac_handle_t mac_handle; - uint8_t con_ch; + uint32_t con_ch_freq; uint8_t vdev_id; uint32_t scan_id; @@ -966,7 +911,7 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) FL("Invalid MAC context")); return QDF_STATUS_E_FAILURE; } - if (sap_context->channel) + if (sap_context->chan_freq) return sap_validate_chan(sap_context, true, false); if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || @@ -977,10 +922,10 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) policy_mgr_mode_specific_connection_count(mac_ctx->psoc, PM_P2P_GO_MODE, NULL)))) { - con_ch = sme_get_beaconing_concurrent_operation_channel( + con_ch_freq = sme_get_beaconing_concurrent_operation_channel( mac_handle, sap_context->sessionId); #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE - if (con_ch) + if (con_ch_freq) sap_context->dfs_ch_disable = true; #endif } @@ -1002,21 +947,22 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) if (sap_context->acs_cfg->skip_scan_status != eSAP_SKIP_ACS_SCAN) { #endif - if (sap_context->channelList) { - qdf_mem_free(sap_context->channelList); - sap_context->channelList = NULL; + + if (sap_context->freq_list) { + qdf_mem_free(sap_context->freq_list); + sap_context->freq_list = NULL; sap_context->num_of_channel = 0; } - sap_get_channel_list(sap_context, &channel_list, - &num_of_channels); + + sap_get_freq_list(sap_context, &freq_list, &num_of_channels); if (!num_of_channels) { - sap_err("No channel sutiable for ACS, SAP failed"); + sap_err("No freq sutiable for SAP in current list, SAP failed"); return QDF_STATUS_E_FAILURE; } req = qdf_mem_malloc(sizeof(*req)); if (!req) { - qdf_mem_free(channel_list); + qdf_mem_free(freq_list); return QDF_STATUS_E_NOMEM; } @@ -1027,7 +973,7 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) if (!vdev) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("Invalid vdev objmgr")); - qdf_mem_free(channel_list); + qdf_mem_free(freq_list); qdf_mem_free(req); return QDF_STATUS_E_INVAL; } @@ -1044,9 +990,8 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) req->scan_req.chan_list.num_chan = num_of_channels; for (i = 0; i < num_of_channels; i++) - req->scan_req.chan_list.chan[i].freq = - wlan_chan_to_freq(channel_list[i]); - sap_context->channelList = channel_list; + req->scan_req.chan_list.chan[i].freq = freq_list[i]; + sap_context->freq_list = freq_list; sap_context->num_of_channel = num_of_channels; /* Set requestType to Full scan */ @@ -1057,17 +1002,16 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context) FL("scan request fail %d!!!"), qdf_ret_status); QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("SAP Configuring default channel, Ch=%d"), - sap_context->channel); - sap_context->channel = sap_select_default_oper_chan( - mac_ctx, sap_context->acs_cfg); - - if (sap_context->channelList) { - sap_context->channel = - sap_context->channelList[0]; - qdf_mem_free(sap_context-> - channelList); - sap_context->channelList = NULL; + FL("SAP Configuring default ch, Ch_freq=%d"), + sap_context->chan_freq); + sap_context->chan_freq = sap_select_default_oper_chan( + mac_ctx, sap_context->acs_cfg); + + if (sap_context->freq_list) { + sap_context->chan_freq = + sap_context->freq_list[0]; + qdf_mem_free(sap_context->freq_list); + sap_context->freq_list = NULL; sap_context->num_of_channel = 0; } /* @@ -1135,8 +1079,10 @@ sap_find_valid_concurrent_session(mac_handle_t mac_handle) static QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle) { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct sap_context *sap_ctx; - if (sap_find_valid_concurrent_session(mac_handle)) { + sap_ctx = sap_find_valid_concurrent_session(mac_handle); + if (sap_ctx && WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, "conc session exists, no need to clear dfs struct"); return QDF_STATUS_SUCCESS; @@ -1155,12 +1101,11 @@ static QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle) } mac_ctx->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; sap_cac_reset_notify(mac_handle); - qdf_mem_zero(&mac_ctx->sap, sizeof(mac_ctx->sap)); return QDF_STATUS_SUCCESS; } -QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, +QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc, struct sap_context *sap_ctx, uint8_t session_id) { @@ -1172,8 +1117,7 @@ QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, return QDF_STATUS_E_FAULT; } - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, - session_id, + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, WLAN_LEGACY_SAP_ID); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -1189,10 +1133,16 @@ void sap_release_vdev_ref(struct sap_context *sap_ctx) { struct wlan_objmgr_vdev *vdev; + if (!sap_ctx) { + sap_debug("Invalid SAP pointer"); + return; + } + vdev = sap_ctx->vdev; - sap_ctx->vdev = NULL; - if (vdev) + if (vdev) { + sap_ctx->vdev = NULL; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); + } } QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, @@ -1201,7 +1151,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); int i; - QDF_STATUS status; sapctx->sessionId = session_id; sapctx->is_pre_cac_on = false; @@ -1214,14 +1163,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, mac_ctx->sap.sapCtxList[i].sap_context = NULL; } - status = sap_acquire_vdev_ref(mac_ctx, sapctx, session_id); - if (!QDF_IS_STATUS_SUCCESS(status)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("sap context init failed for session_id: %u"), - session_id); - return status; - } - mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx; mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = sapctx->csr_roamProfile.csrPersona; @@ -1241,18 +1182,14 @@ QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle, if (sapctx->sessionId >= SAP_MAX_NUM_SESSION) return QDF_STATUS_E_FAILURE; - sap_release_vdev_ref(sapctx); - mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL; mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = QDF_MAX_NO_OF_MODE; sap_clear_global_dfs_param(mac_handle); sap_free_roam_profile(&sapctx->csr_roamProfile); + sap_err("Set sapCtxList null for session %d", sapctx->sessionId); qdf_mem_zero(sapctx, sizeof(*sapctx)); sapctx->sessionId = WLAN_UMAC_VDEV_ID_MAX; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s: Initializing State: %d, sap_ctx value = %pK", __func__, - sapctx->fsm_state, sapctx); return QDF_STATUS_SUCCESS; } @@ -1333,8 +1270,8 @@ static void sap_handle_acs_scan_event(struct sap_context *sap_context, sap_event->sapevt.sap_acs_scan_comp.status = status; sap_event->sapevt.sap_acs_scan_comp.num_of_channels = sap_context->num_of_channel; - sap_event->sapevt.sap_acs_scan_comp.channellist = - sap_context->channelList; + sap_event->sapevt.sap_acs_scan_comp.freq_list = + sap_context->freq_list; } #else static void sap_handle_acs_scan_event(struct sap_context *sap_context, @@ -1556,7 +1493,7 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, FL("(eSAP_START_BSS_EVENT): staId = %d"), bss_complete->staId); - bss_complete->operatingChannel = (uint8_t) sap_ctx->channel; + bss_complete->operating_chan_freq = sap_ctx->chan_freq; bss_complete->ch_width = sap_ctx->ch_params.ch_width; break; case eSAP_DFS_CAC_START: @@ -1578,15 +1515,17 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, sap_ap_event.sapHddEventCode = sap_hddevent; acs_selected = &sap_ap_event.sapevt.sap_ch_selected; if (eSAP_STATUS_SUCCESS == (eSapStatus)context) { - acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch; - acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch; + acs_selected->pri_ch_freq = + sap_ctx->acs_cfg->pri_ch_freq; + acs_selected->ht_sec_ch_freq = + sap_ctx->acs_cfg->ht_sec_ch_freq; acs_selected->ch_width = sap_ctx->acs_cfg->ch_width; - acs_selected->vht_seg0_center_ch = - sap_ctx->acs_cfg->vht_seg0_center_ch; - acs_selected->vht_seg1_center_ch = - sap_ctx->acs_cfg->vht_seg1_center_ch; + acs_selected->vht_seg0_center_ch_freq = + sap_ctx->acs_cfg->vht_seg0_center_ch_freq; + acs_selected->vht_seg1_center_ch_freq = + sap_ctx->acs_cfg->vht_seg1_center_ch_freq; } else if (eSAP_STATUS_FAILURE == (eSapStatus)context) { - acs_selected->pri_ch = 0; + acs_selected->pri_ch_freq = 0; } break; @@ -1653,7 +1592,6 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, /* also fill up the channel info from the csr_roamInfo */ chaninfo = &reassoc_complete->chan_info; - chaninfo->chan_id = csr_roaminfo->chan_info.chan_id; chaninfo->mhz = csr_roaminfo->chan_info.mhz; chaninfo->info = csr_roaminfo->chan_info.info; chaninfo->band_center_freq1 = @@ -1717,6 +1655,7 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, disassoc_comp->rx_rate = csr_roaminfo->rx_rate; disassoc_comp->tx_rate = csr_roaminfo->tx_rate; disassoc_comp->rx_mc_bc_cnt = csr_roaminfo->rx_mc_bc_cnt; + disassoc_comp->rx_retry_cnt = csr_roaminfo->rx_retry_cnt; disassoc_comp->reason_code = csr_roaminfo->disassoc_reason; break; @@ -1814,23 +1753,23 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS * follows pri AP */ - sap_ctx->acs_cfg->pri_ch = sap_ctx->channel; + sap_ctx->acs_cfg->pri_ch_freq = sap_ctx->chan_freq; sap_ctx->acs_cfg->ch_width = sap_ctx->csr_roamProfile.ch_params.ch_width; sap_config_acs_result(MAC_HANDLE(mac_ctx), sap_ctx, - sap_ctx->secondary_ch); + sap_ctx->sec_ch_freq); sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; acs_selected = &sap_ap_event.sapevt.sap_ch_selected; - acs_selected->pri_ch = sap_ctx->channel; - acs_selected->ht_sec_ch = sap_ctx->secondary_ch; + acs_selected->pri_ch_freq = sap_ctx->chan_freq; + acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq; acs_selected->ch_width = - sap_ctx->csr_roamProfile.ch_params.ch_width; - acs_selected->vht_seg0_center_ch = - sap_ctx->csr_roamProfile.ch_params.center_freq_seg0; - acs_selected->vht_seg1_center_ch = - sap_ctx->csr_roamProfile.ch_params.center_freq_seg1; + sap_ctx->acs_cfg->ch_width; + acs_selected->vht_seg0_center_ch_freq = + sap_ctx->acs_cfg->vht_seg0_center_ch_freq; + acs_selected->vht_seg1_center_ch_freq = + sap_ctx->acs_cfg->vht_seg1_center_ch_freq; break; case eSAP_ECSA_CHANGE_CHAN_IND: @@ -1844,8 +1783,8 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, "In %s, SAP event callback event = %s", __func__, "eSAP_ECSA_CHANGE_CHAN_IND"); sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND; - sap_ap_event.sapevt.sap_chan_cng_ind.new_chan = - csr_roaminfo->target_channel; + sap_ap_event.sapevt.sap_chan_cng_ind.new_chan_freq = + csr_roaminfo->target_chan_freq; break; case eSAP_DFS_NEXT_CHANNEL_REQ: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -1856,14 +1795,23 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, case eSAP_STOP_BSS_DUE_TO_NO_CHNL: sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - FL("stopping session_id:%d, bssid:%pM, channel:%d"), - sap_ctx->sessionId, sap_ctx->self_mac_addr, - sap_ctx->channel); + FL("stopping session_id:%d, bssid:"QDF_MAC_ADDR_FMT", chan_freq:%d"), + sap_ctx->sessionId, + QDF_MAC_ADDR_REF(sap_ctx->self_mac_addr), + sap_ctx->chan_freq); break; case eSAP_CHANNEL_CHANGE_RESP: sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_RESP; - sap_ap_event.sapevt.ch_change_rsp_status = (QDF_STATUS)context; + acs_selected = &sap_ap_event.sapevt.sap_ch_selected; + acs_selected->pri_ch_freq = sap_ctx->chan_freq; + acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq; + acs_selected->ch_width = + sap_ctx->csr_roamProfile.ch_params.ch_width; + acs_selected->vht_seg0_center_ch_freq = + sap_ctx->csr_roamProfile.ch_params.mhz_freq_seg0; + acs_selected->vht_seg1_center_ch_freq = + sap_ctx->csr_roamProfile.ch_params.mhz_freq_seg1; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", __func__, "eSAP_CHANNEL_CHANGE_RESP"); @@ -1882,6 +1830,44 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, } +bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx) +{ + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + struct mac_context *mac_ctx; + mac_handle_t mac_handle; + + if (!sap_ctx) { + sap_err("Invalid sap context"); + return false; + } + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + if (!mac_handle) { + sap_err("invalid mac_handle"); + return false; + } + + mac_ctx = MAC_CONTEXT(mac_handle); + if (!mac_ctx) { + sap_err("Invalid MAC context"); + return false; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, + sap_ctx->sessionId, + WLAN_DFS_ID); + if (!vdev) { + sap_err("vdev is NULL for vdev_id: %u", sap_ctx->sessionId); + return false; + } + + status = wlan_vdev_is_dfs_cac_wait(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); + + return QDF_IS_STATUS_SUCCESS(status); +} + /** * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state * @handle: Global MAC handle @@ -1952,6 +1938,7 @@ static QDF_STATUS sap_cac_start_notify(mac_handle_t mac_handle) uint8_t intf = 0; struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; + qdf_freq_t ch_freq; for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) { struct sap_context *sap_context = @@ -1965,8 +1952,9 @@ static QDF_STATUS sap_cac_start_notify(mac_handle_t mac_handle) (false == sap_context->isCacStartNotified)) { /* Don't start CAC for non-dfs channel, its violation */ profile = &sap_context->csr_roamProfile; - if (!wlan_reg_is_dfs_ch(mac->pdev, - profile->operationChannel)) + ch_freq = profile->op_freq; + if (!wlan_reg_is_dfs_for_freq(mac->pdev, + ch_freq)) continue; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]", @@ -2040,7 +2028,7 @@ static QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle, uint8_t intf; struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - uint8_t chan; + uint32_t freq; /* * eSAP_DFS_CHANNEL_CAC_END: @@ -2062,8 +2050,11 @@ static QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle, sap_context = mac->sap.sapCtxList[intf].sap_context; /* Don't check CAC for non-dfs channel */ profile = &sap_context->csr_roamProfile; - chan = profile->operationChannel; - if (!wlan_reg_chan_has_dfs_attribute(mac->pdev, chan)) + freq = profile->op_freq; + if (CHANNEL_STATE_DFS != + wlan_reg_get_5g_bonded_channel_state_for_freq(mac->pdev, + freq, + profile->ch_params.ch_width)) continue; /* If this is an end notification of a pre cac, the @@ -2106,8 +2097,8 @@ static QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle, * (both without substates) */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, - "sapdfs: channel[%d] from state %s => %s", - sap_context->channel, "SAP_STARTING", + "sapdfs: chan_freq[%d] from state %s => %s", + sap_context->chan_freq, "SAP_STARTING", "SAP_STARTED"); sap_context->fsm_state = SAP_STARTED; @@ -2139,27 +2130,24 @@ static QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle, } /** - * sap_goto_starting() - Trigger softap start + * sap_validate_dfs_nol() - Validate SAP channel with NOL list * @sap_ctx: SAP context - * @sap_event: SAP event buffer - * @mac_ctx: global MAC context - * @mac_handle: Opaque handle to the global MAC context + * @sap_ctx: MAC context * - * This function triggers start of softap. Before starting, it can select - * new channel if given channel has leakage or if given channel in DFS_NOL. + * Function will be called to validate SAP channel and bonded sub channels + * included in DFS NOL or not. * - * Return: QDF_STATUS + * Return: QDF_STATUS_SUCCESS for NOT in NOL */ -static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, - struct sap_sm_event *sap_event, - struct mac_context *mac_ctx, - mac_handle_t mac_handle) +static QDF_STATUS sap_validate_dfs_nol(struct sap_context *sap_ctx, + struct mac_context *mac_ctx) { - QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; bool b_leak_chan = false; uint8_t temp_chan; + uint8_t sap_chan; - temp_chan = sap_ctx->channel; + sap_chan = wlan_reg_freq_to_chan(mac_ctx->pdev, sap_ctx->chan_freq); + temp_chan = sap_chan; utils_dfs_mark_leaking_ch(mac_ctx->pdev, sap_ctx->ch_params.ch_width, 1, &temp_chan); @@ -2168,12 +2156,12 @@ static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, * if selelcted channel has leakage to channels * in NOL, the temp_chan will be reset */ - b_leak_chan = (temp_chan != sap_ctx->channel); + b_leak_chan = (temp_chan != sap_chan); /* * check if channel is in DFS_NOL or if the channel * has leakage to the channels in NOL */ - if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel, + if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_chan, PHY_CHANNEL_BONDING_STATE_MAX) || b_leak_chan) { uint8_t ch; @@ -2192,14 +2180,46 @@ static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, } QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("channel %d is in NOL, Start Bss on new chan %d"), - sap_ctx->channel, ch); + FL("ch_freq %d is in NOL, Start Bss on new chan %d"), + sap_ctx->chan_freq, ch); - sap_ctx->channel = ch; - wlan_reg_set_channel_params(mac_ctx->pdev, - sap_ctx->channel, - sap_ctx->secondary_ch, - &sap_ctx->ch_params); + sap_ctx->chan_freq = wlan_reg_chan_to_freq(mac_ctx->pdev, ch); + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + sap_ctx->chan_freq, + sap_ctx->sec_ch_freq, + &sap_ctx->ch_params); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * sap_goto_starting() - Trigger softap start + * @sap_ctx: SAP context + * @sap_event: SAP event buffer + * @mac_ctx: global MAC context + * @mac_handle: Opaque handle to the global MAC context + * + * This function triggers start of softap. Before starting, it can select + * new channel if given channel has leakage or if given channel in DFS_NOL. + * + * Return: QDF_STATUS + */ +static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, + struct sap_sm_event *sap_event, + struct mac_context *mac_ctx, + mac_handle_t mac_handle) +{ + QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; + + /* + * check if channel is in DFS_NOL or if the channel + * has leakage to the channels in NOL. + */ + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) { + qdf_status = sap_validate_dfs_nol(sap_ctx, mac_ctx); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + return qdf_status; } /* @@ -2209,28 +2229,36 @@ static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, * override AP2 ACS scan result with AP1 DFS channel */ if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc)) { + uint32_t con_ch_freq; uint16_t con_ch; - con_ch = sme_get_beaconing_concurrent_operation_channel( + con_ch_freq = sme_get_beaconing_concurrent_operation_channel( mac_handle, sap_ctx->sessionId); + con_ch = wlan_reg_freq_to_chan(mac_ctx->pdev, con_ch_freq); /* Overwrite second AP's channel with first only when: * 1. If operating mode is single mac * 2. or if 2nd AP is coming up on 5G band channel */ if ((!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) || - WLAN_REG_IS_5GHZ_CH(sap_ctx->channel)) && - con_ch && wlan_reg_is_dfs_ch(mac_ctx->pdev, con_ch)) { - sap_ctx->channel = con_ch; - wlan_reg_set_channel_params(mac_ctx->pdev, - sap_ctx->channel, 0, + WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq)) && + con_ch && + wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + con_ch_freq)) { + sap_ctx->chan_freq = con_ch_freq; + wlan_reg_set_channel_params_for_freq( + mac_ctx->pdev, + con_ch_freq, 0, &sap_ctx->ch_params); } } - if (sap_ctx->channel > 14 && + if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq) && (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g || sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g_ONLY)) sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) && + (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11a)) + sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11g; /* * Transition from SAP_INIT to SAP_STARTING @@ -2244,26 +2272,19 @@ static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx, /* Specify the channel */ sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels = 1; - sap_ctx->csr_roamProfile.ChannelInfo.ChannelList = - &sap_ctx->csr_roamProfile.operationChannel; - sap_ctx->csr_roamProfile.operationChannel = - (uint8_t)sap_ctx->channel; - sap_ctx->csr_roamProfile.ch_params.ch_width = - sap_ctx->ch_params.ch_width; - sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = - sap_ctx->ch_params.center_freq_seg0; - sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = - sap_ctx->ch_params.center_freq_seg1; - sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = - sap_ctx->ch_params.sec_ch_offset; + sap_ctx->csr_roamProfile.ChannelInfo.freq_list = + &sap_ctx->csr_roamProfile.op_freq; + sap_ctx->csr_roamProfile.op_freq = sap_ctx->chan_freq; + + sap_ctx->csr_roamProfile.ch_params = sap_ctx->ch_params; sap_get_cac_dur_dfs_region(sap_ctx, &sap_ctx->csr_roamProfile.cac_duration_ms, &sap_ctx->csr_roamProfile.dfs_regdomain); sap_ctx->csr_roamProfile.beacon_tx_rate = sap_ctx->beacon_tx_rate; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("notify hostapd about channel selection: %d"), - sap_ctx->channel); + FL("notify hostapd about chan freq selection: %d"), + sap_ctx->chan_freq); sap_signal_hdd_event(sap_ctx, NULL, eSAP_CHANNEL_CHANGE_EVENT, (void *)eSAP_STATUS_SUCCESS); @@ -2336,31 +2357,21 @@ static QDF_STATUS sap_fsm_state_init(struct sap_context *sap_ctx, * request so, set the third to false. */ qdf_status = sap_validate_chan(sap_ctx, false, true); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + if (QDF_IS_STATUS_ERROR(qdf_status)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("channel is not valid!")); goto exit; } - /* Transition from SAP_INIT to SAP_STARTING */ - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("new from state %s => %s: session:%d"), - "SAP_INIT", "SAP_STARTING", - sap_ctx->sessionId); - qdf_status = sap_goto_starting(sap_ctx, sap_event, mac_ctx, mac_handle); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - FL("sap_goto_starting failed")); + if (QDF_IS_STATUS_ERROR(qdf_status)) + sap_err("sap_goto_starting failed"); } else if (msg == eSAP_DFS_CHANNEL_CAC_START) { qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx, mac_handle); } else { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("in state %s, event msg %d"), - "SAP_INIT", msg); + sap_err("in state %s, event msg %d", "SAP_INIT", msg); } exit: @@ -2379,14 +2390,14 @@ static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx, { uint8_t intf; - if (mac_ctx->sap.SapDfsInfo.target_channel) { - wlan_reg_set_channel_params(mac_ctx->pdev, - mac_ctx->sap.SapDfsInfo.target_channel, 0, + if (mac_ctx->sap.SapDfsInfo.target_chan_freq) { + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, + mac_ctx->sap.SapDfsInfo.target_chan_freq, 0, &sap_ctx->ch_params); } else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid target channel %d"), - mac_ctx->sap.SapDfsInfo.target_channel); + FL("Invalid target channel freq %d"), + mac_ctx->sap.SapDfsInfo.target_chan_freq); return QDF_STATUS_E_FAILURE; } @@ -2403,7 +2414,8 @@ static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx, profile = &t_sap_ctx->csr_roamProfile; if (!wlan_reg_is_passive_or_disable_ch( mac_ctx->pdev, - profile->operationChannel)) + wlan_reg_freq_to_chan(mac_ctx->pdev, + profile->op_freq))) continue; t_sap_ctx->is_chan_change_inprogress = true; /* @@ -2415,7 +2427,7 @@ static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx, * sap_radar_found_status is set to 1 */ wlansap_channel_change_request(t_sap_ctx, - mac_ctx->sap.SapDfsInfo.target_channel); + mac_ctx->sap.SapDfsInfo.target_chan_freq); } } @@ -2423,7 +2435,7 @@ static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx, } /** - * sap_fsm_handle_start_failure() - handle start failure or stop during cac wait + * sap_fsm_handle_start_failure() - handle sap start failure * @sap_ctx: SAP context * @msg: event msg * @mac_handle: Opaque handle to the global MAC context @@ -2436,13 +2448,9 @@ static QDF_STATUS sap_fsm_handle_start_failure(struct sap_context *sap_ctx, { QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - if (msg == eSAP_HDD_STOP_INFRA_BSS && - (QDF_IS_STATUS_SUCCESS(wlan_vdev_is_dfs_cac_wait(sap_ctx->vdev)) || - QDF_IS_STATUS_SUCCESS( - wlan_vdev_is_restart_progress(sap_ctx->vdev)))) { + if (msg == eSAP_HDD_STOP_INFRA_BSS) { /* Transition from SAP_STARTING to SAP_STOPPING */ - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("In cac wait state from state %s => %s"), + sap_debug("SAP start is in progress, state from state %s => %s", "SAP_STARTING", "SAP_STOPPING"); /* * Stop the CAC timer only in following conditions @@ -2480,6 +2488,43 @@ static QDF_STATUS sap_fsm_handle_start_failure(struct sap_context *sap_ctx, return qdf_status; } +/** + * sap_propagate_cac_events() - Indicate CAC START/END event + * @sap_ctx: SAP context + * + * This function is to indicate CAC START/END event if CAC process + * is skipped. + * + * Return: void + */ +static void sap_propagate_cac_events(struct sap_context *sap_ctx) +{ + QDF_STATUS qdf_status; + + qdf_status = sap_signal_hdd_event(sap_ctx, NULL, + eSAP_DFS_CAC_START, + (void *) + eSAP_STATUS_SUCCESS); + if (qdf_status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_SAP, + QDF_TRACE_LEVEL_DEBUG, + "failed to indicate CAC START vdev %d", + sap_ctx->sessionId); + return; + } + + qdf_status = sap_signal_hdd_event(sap_ctx, NULL, + eSAP_DFS_CAC_END, + (void *) + eSAP_STATUS_SUCCESS); + if (qdf_status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_SAP, + QDF_TRACE_LEVEL_DEBUG, + "failed to indicate CAC End vdev %d", + sap_ctx->sessionId); + } +} + /** * sap_fsm_state_starting() - utility function called from sap fsm * @sap_ctx: SAP context @@ -2502,6 +2547,9 @@ static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, tSapDfsInfo *sap_dfs_info; QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; uint8_t is_dfs = false; + uint32_t sap_chan_freq; + uint32_t ch_cfreq1 = 0; + enum reg_wifi_band band; if (msg == eSAP_MAC_START_BSS_SUCCESS) { /* @@ -2509,36 +2557,58 @@ static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, * (both without substates) */ sap_debug("Chan %d %s => %s ch_width %d", - sap_ctx->channel, "SAP_STARTING", "SAP_STARTED", + sap_ctx->chan_freq, "SAP_STARTING", "SAP_STARTED", sap_ctx->ch_params.ch_width); sap_ctx->fsm_state = SAP_STARTED; - /* Action code for transition */ - qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, - eSAP_START_BSS_EVENT, - (void *) eSAP_STATUS_SUCCESS); + if (sap_ctx->is_chan_change_inprogress) { + /* SAP channel change request processing is completed */ + qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, + eSAP_CHANNEL_CHANGE_EVENT, + (void *)eSAP_STATUS_SUCCESS); + sap_ctx->is_chan_change_inprogress = false; + } else { + /* Action code for transition */ + qdf_status = sap_signal_hdd_event(sap_ctx, roam_info, + eSAP_START_BSS_EVENT, + (void *) eSAP_STATUS_SUCCESS); + } + sap_chan_freq = sap_ctx->chan_freq; + band = wlan_reg_freq_to_band(sap_ctx->chan_freq); + if (sap_ctx->ch_params.center_freq_seg1) + ch_cfreq1 = wlan_reg_chan_band_to_freq( + mac_ctx->pdev, + sap_ctx->ch_params.center_freq_seg1, + BIT(band)); + /* * The upper layers have been informed that AP is up and * running, however, the AP is still not beaconing, until * CAC is done if the operating channel is DFS */ if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { - is_dfs = true; + is_dfs = wlan_reg_get_5g_bonded_channel_state_for_freq( + mac_ctx->pdev, sap_chan_freq, + CH_WIDTH_160MHZ) == CHANNEL_STATE_DFS; } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_chan_freq) == CHANNEL_STATE_DFS || - wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->ch_params.center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + ch_cfreq1) == CHANNEL_STATE_DFS) is_dfs = true; } else { - if (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == - CHANNEL_STATE_DFS) + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_chan_freq) == + CHANNEL_STATE_DFS) is_dfs = true; } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) + is_dfs = false; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("is_dfs %d"), is_dfs); @@ -2560,6 +2630,16 @@ static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("skip cac timer")); + /* + * If hostapd starts AP on dfs channel, + * hostapd will wait for CAC START/CAC END + * event and finish AP start process. + * If we skip CAC timer, we will need to + * indicate the CAC event even though driver + * doesn't perform CAC. + */ + sap_propagate_cac_events(sap_ctx); + wlansap_start_beacon_req(sap_ctx); } } @@ -2569,8 +2649,7 @@ static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx, mac_handle); } else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) { /* The operating channel has changed, update hostapd */ - sap_ctx->channel = - (uint8_t) mac_ctx->sap.SapDfsInfo.target_channel; + sap_ctx->chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq; sap_ctx->fsm_state = SAP_STARTED; @@ -2606,6 +2685,34 @@ static inline QDF_STATUS sap_fsm_send_csa_restart_req(struct mac_context *mac_ctx, struct sap_context *sap_ctx) { + QDF_STATUS status; + + status = policy_mgr_check_and_set_hw_mode_for_channel_switch( + mac_ctx->psoc, sap_ctx->sessionId, + mac_ctx->sap.SapDfsInfo.target_chan_freq, + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP); + + /* + * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW + * mode change was required but driver failed to set HW + * mode so ignore CSA for the channel. + */ + if (status == QDF_STATUS_E_FAILURE) { + sap_err("HW change required but failed to set hw mode"); + return status; + } + + /* + * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode + * change was required and was successfully requested so + * the channel switch will continue after HW mode change + * completion. + */ + if (QDF_IS_STATUS_SUCCESS(status)) { + sap_info("Channel change will continue after HW mode change"); + return QDF_STATUS_SUCCESS; + } + return sme_csa_restart(mac_ctx, sap_ctx->sessionId); } @@ -2638,10 +2745,10 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, qdf_status = sap_goto_stopping(sap_ctx); } else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) { uint8_t intf; - if (!mac_ctx->sap.SapDfsInfo.target_channel) { + if (!mac_ctx->sap.SapDfsInfo.target_chan_freq) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid target channel %d"), - mac_ctx->sap.SapDfsInfo.target_channel); + FL("Invalid target channel freq %d"), + mac_ctx->sap.SapDfsInfo.target_chan_freq); return qdf_status; } @@ -2668,7 +2775,9 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx, profile = &temp_sap_ctx->csr_roamProfile; if (!wlan_reg_is_passive_or_disable_ch( mac_ctx->pdev, - profile->operationChannel)) + wlan_reg_freq_to_chan( + mac_ctx->pdev, + profile->op_freq))) continue; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, @@ -2721,6 +2830,13 @@ sap_fsm_state_stopping(struct sap_context *sap_ctx, qdf_status = sap_signal_hdd_event(sap_ctx, NULL, eSAP_STOP_BSS_EVENT, (void *)eSAP_STATUS_SUCCESS); + } else if (msg == eSAP_HDD_STOP_INFRA_BSS) { + /* + * In case the SAP is already in stopping case and + * we get a STOP request, return success. + */ + sap_debug("SAP already in Stopping state"); + qdf_status = QDF_STATUS_SUCCESS; } else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("in state %s, invalid event msg %d"), @@ -2864,8 +2980,7 @@ sapconvert_to_csr_profile(struct sap_config *config, eCsrRoamBssType bssType, profile->nWPAReqIELength = 0; if (profile->pRSNReqIE) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - FL("pRSNReqIE already allocated.")); + sap_debug("pRSNReqIE already allocated."); qdf_mem_free(profile->pRSNReqIE); profile->pRSNReqIE = NULL; } @@ -2900,7 +3015,6 @@ sapconvert_to_csr_profile(struct sap_config *config, eCsrRoamBssType bssType, sap_err("Get ap UAPSD enabled/disabled failed"); profile->ApUapsdEnable = sap_uapsd; - sap_debug("Uapsd %d", sap_uapsd); /* Enable protection parameters */ profile->protEnabled = ucfg_mlme_is_ap_prot_enabled(mac_ctx->psoc); @@ -2911,15 +3025,11 @@ sapconvert_to_csr_profile(struct sap_config *config, eCsrRoamBssType bssType, sap_err("Get ap obss protection failed"); profile->obssProtEnabled = ap_obss_prot; - sap_debug("ProtEnabled = %d", profile->protEnabled); - sap_debug("OBSSProtEnabled = %d", profile->obssProtEnabled); - qdf_status = ucfg_mlme_get_ap_protection_mode(mac_ctx->psoc, &ap_prot); if (QDF_IS_STATUS_ERROR(qdf_status)) sap_err("Get ap protection mode failed using default value"); profile->cfg_protection = ap_prot; - sap_debug("cfg_protection = %d", profile->cfg_protection); /* country code */ if (config->countryCode[0]) qdf_mem_copy(profile->countryCode, config->countryCode, @@ -2999,7 +3109,6 @@ sapconvert_to_csr_profile(struct sap_config *config, eCsrRoamBssType bssType, if (mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) profile->chan_switch_hostapd_rate_enabled = false; } - sap_debug("rate_enabled %d", profile->chan_switch_hostapd_rate_enabled); return eSAP_STATUS_SUCCESS; } @@ -3174,8 +3283,8 @@ void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size) for (i = 0; i < size; i++) { macArray = (macList + i)->bytes; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "** ACL entry %i - " QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY(macArray)); + "** ACL entry %i - " QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(macArray)); } return; } @@ -3193,8 +3302,8 @@ QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx, if (sap_search_mac_list (sap_ctx->denyMacList, sap_ctx->nDenyMac, peerMac, NULL)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Peer " QDF_MAC_ADDR_STR " in deny list", - __func__, QDF_MAC_ADDR_ARRAY(peerMac)); + "In %s, Peer " QDF_MAC_ADDR_FMT " in deny list", + __func__, QDF_MAC_ADDR_REF(peerMac)); return QDF_STATUS_E_FAILURE; } /* A new station CAN associate, unless in deny list. Less stringent mode */ @@ -3204,9 +3313,9 @@ QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx, /* A new station CANNOT associate, unless in accept list. More stringent mode */ if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Peer " QDF_MAC_ADDR_STR + "In %s, Peer " QDF_MAC_ADDR_FMT " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", - __func__, QDF_MAC_ADDR_ARRAY(peerMac)); + __func__, QDF_MAC_ADDR_REF(peerMac)); return QDF_STATUS_E_FAILURE; } @@ -3217,9 +3326,9 @@ QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx, sap_signal_hdd_event(sap_ctx, NULL, eSAP_UNKNOWN_STA_JOIN, (void *) peerMac); QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "In %s, Peer " QDF_MAC_ADDR_STR + "In %s, Peer " QDF_MAC_ADDR_FMT " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", - __func__, QDF_MAC_ADDR_ARRAY(peerMac)); + __func__, QDF_MAC_ADDR_REF(peerMac)); return QDF_STATUS_E_FAILURE; } return QDF_STATUS_SUCCESS; @@ -3242,7 +3351,7 @@ void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg) for (i = 0; i < acs_cfg->ch_list_count; i++) len += qdf_scnprintf(chan_buff + len, buf_len - len, - " %d", acs_cfg->ch_list[i]); + " %d", acs_cfg->freq_list[i]); sap_nofl_debug("ACS freq list[%d]:%s", acs_cfg->ch_list_count, chan_buff); @@ -3251,70 +3360,81 @@ void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg) #ifdef SOFTAP_CHANNEL_RANGE /** - * sap_get_channel_list() - get the list of channels + * sap_get_freq_list() - get the list of channel frequency * @sap_ctx: sap context - * @ch_list: pointer to channel list array + * @freq_list: pointer to channel list array * @num_ch: pointer to number of channels. * - * This function populates the list of channels for scanning. + * This function populates the list of channel frequency for scanning. * * Return: QDF_STATUS */ -static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, - uint8_t **ch_list, - uint8_t *num_ch) +static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx, + uint32_t **freq_list, + uint8_t *num_ch) { uint8_t loop_count; - uint8_t *list; + uint32_t *list; uint8_t ch_count; uint8_t dfs_master_enable; - uint8_t start_ch_num, band_start_ch; - uint8_t end_ch_num, band_end_ch; + uint32_t start_ch_freq, band_start_ch; + uint32_t end_ch_freq, band_end_ch; uint32_t en_lte_coex; struct mac_context *mac_ctx; - tSapChSelSpectInfo spect_info_obj = { NULL, 0 }; uint16_t ch_width; + uint8_t normalize_factor = 100; + uint32_t chan_freq; + struct acs_weight *weight_list; + struct acs_weight_range *range_list; + bool freq_present_in_list = false; + uint8_t i; + bool srd_chan_enabled; + enum QDF_OPMODE vdev_opmode; mac_ctx = sap_get_mac_context(); if (!mac_ctx) { QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context"); *num_ch = 0; - *ch_list = NULL; + *freq_list = NULL; return QDF_STATUS_E_FAULT; } + weight_list = mac_ctx->mlme_cfg->acs.normalize_weight_chan; + range_list = mac_ctx->mlme_cfg->acs.normalize_weight_range; + dfs_master_enable = mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable; if (sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) dfs_master_enable = false; - start_ch_num = sap_ctx->acs_cfg->start_ch; - end_ch_num = sap_ctx->acs_cfg->end_ch; + start_ch_freq = sap_ctx->acs_cfg->start_ch_freq; + end_ch_freq = sap_ctx->acs_cfg->end_ch_freq; ch_width = sap_ctx->acs_cfg->ch_width; + sap_debug("startChannel %d, EndChannel %d, ch_width %d, HW:%d", - start_ch_num, end_ch_num, ch_width, + start_ch_freq, end_ch_freq, ch_width, sap_ctx->acs_cfg->hw_mode); wlansap_extend_to_acs_range(MAC_HANDLE(mac_ctx), - &start_ch_num, &end_ch_num, + &start_ch_freq, &end_ch_freq, &band_start_ch, &band_end_ch); sap_debug("expanded startChannel %d,EndChannel %d band_start_ch %d, band_end_ch %d", - start_ch_num, end_ch_num, band_start_ch, band_end_ch); + start_ch_freq, end_ch_freq, band_start_ch, band_end_ch); en_lte_coex = mac_ctx->mlme_cfg->sap_cfg.enable_lte_coex; /* Check if LTE coex is enabled and 2.4GHz is selected */ - if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) && - (band_end_ch == CHAN_ENUM_14)) { + if (en_lte_coex && (band_start_ch == CHAN_ENUM_2412) && + (band_end_ch == CHAN_ENUM_2484)) { /* Set 2.4GHz upper limit to channel 9 for LTE COEX */ - band_end_ch = CHAN_ENUM_9; + band_end_ch = CHAN_ENUM_2452; } /* Allocate the max number of channel supported */ - list = qdf_mem_malloc(NUM_5GHZ_CHANNELS + NUM_24GHZ_CHANNELS); + list = qdf_mem_malloc((NUM_CHANNELS) * sizeof(uint32_t)); if (!list) { *num_ch = 0; - *ch_list = NULL; + *freq_list = NULL; return QDF_STATUS_E_NOMEM; } @@ -3322,9 +3442,11 @@ static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, ch_count = 0; for (loop_count = band_start_ch; loop_count <= band_end_ch; loop_count++) { + chan_freq = WLAN_REG_CH_TO_FREQ(loop_count); + /* go to next channel if rf_channel is out of range */ - if ((start_ch_num > WLAN_REG_CH_NUM(loop_count)) || - (end_ch_num < WLAN_REG_CH_NUM(loop_count))) + if (start_ch_freq > WLAN_REG_CH_TO_FREQ(loop_count) || + end_ch_freq < WLAN_REG_CH_TO_FREQ(loop_count)) continue; /* * go to next channel if none of these condition pass @@ -3332,117 +3454,161 @@ static QDF_STATUS sap_get_channel_list(struct sap_context *sap_ctx, * - DFS scan disable but chan in CHANNEL_STATE_ENABLE */ if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) && - wlan_reg_get_channel_state(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count))) + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count))) || ((false == mac_ctx->scan.fEnableDFSChnlScan) && (CHANNEL_STATE_ENABLE == - wlan_reg_get_channel_state(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count))) + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count))) ))) continue; /* check if the channel is in NOL blacklist */ - if (sap_dfs_is_channel_in_nol_list(sap_ctx, - WLAN_REG_CH_NUM(loop_count), - PHY_SINGLE_CHANNEL_CENTERED)) { - sap_debug("Ch %d in NOL list", - WLAN_REG_CH_NUM(loop_count)); - continue; + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(WLAN_REG_CH_TO_FREQ( + loop_count))) { + if (sap_dfs_is_channel_in_nol_list( + sap_ctx, + WLAN_REG_CH_NUM(loop_count), + PHY_SINGLE_CHANNEL_CENTERED)) { + sap_debug("Ch %d in NOL list", + WLAN_REG_CH_NUM(loop_count)); + continue; + } } - /* Skip DSRC channels */ - if (wlan_reg_is_dsrc_chan(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count))) + if (wlan_reg_is_dsrc_freq(WLAN_REG_CH_TO_FREQ(loop_count))) continue; /* * Skip the channels which are not in ACS config from user * space */ - if (SAP_CHANNEL_NOT_SELECTED == - sap_channel_in_acs_channel_list( - WLAN_REG_CH_NUM(loop_count), - sap_ctx, &spect_info_obj)) + if (!wlansap_is_channel_present_in_acs_list( + chan_freq, + sap_ctx->acs_cfg->freq_list, + sap_ctx->acs_cfg->ch_list_count)) continue; /* Dont scan DFS channels in case of MCC disallowed * As it can result in SAP starting on DFS channel * resulting MCC on DFS channel */ - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count)) && - (policy_mgr_disallow_mcc(mac_ctx->psoc, - WLAN_REG_CH_NUM(loop_count)) || - !dfs_master_enable)) - continue; - /* Dont scan ETSI13 SRD channels if the ETSI13 SRD channels - * are not enabled in master mode - */ - if (!wlan_reg_is_etsi13_srd_chan_allowed_master_mode(mac_ctx-> - pdev) && - wlan_reg_is_etsi13_srd_chan(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count))) + if (wlan_reg_is_dfs_for_freq( + mac_ctx->pdev, + WLAN_REG_CH_TO_FREQ(loop_count))) { + if (!dfs_master_enable) + continue; + else if (policy_mgr_disallow_mcc( + mac_ctx->psoc, + WLAN_REG_CH_TO_FREQ(loop_count))) + continue; + normalize_factor = + MLME_GET_DFS_CHAN_WEIGHT( + mac_ctx->mlme_cfg->acs.np_chan_weightage); + freq_present_in_list = true; + } + + vdev_opmode = wlan_vdev_mlme_get_opmode(sap_ctx->vdev); + wlan_mlme_get_srd_master_mode_for_vdev(mac_ctx->psoc, + vdev_opmode, + &srd_chan_enabled); + + if (!srd_chan_enabled && + wlan_reg_is_etsi13_srd_chan_for_freq(mac_ctx->pdev, + WLAN_REG_CH_TO_FREQ(loop_count))) { + sap_debug("vdev opmode %d not allowed on SRD freq %d", + vdev_opmode, WLAN_REG_CH_TO_FREQ(loop_count)); continue; + } - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, - WLAN_REG_CH_NUM(loop_count)) && - !MLME_GET_DFS_CHAN_WEIGHT( - mac_ctx->mlme_cfg->acs.np_chan_weightage)) { - sap_debug("DFS ch with np weight 0, skipping"); + /* Check if the freq is present in range list */ + for (i = 0; i < mac_ctx->mlme_cfg->acs.num_weight_range; i++) { + if (chan_freq >= range_list[i].start_freq && + chan_freq <= range_list[i].end_freq) { + normalize_factor = + range_list[i].normalize_weight; + sap_debug("Range list, freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + for (i = 0; + i < mac_ctx->mlme_cfg->acs.normalize_weight_num_chan; + i++) { + if (chan_freq == weight_list[i].chan_freq) { + normalize_factor = + weight_list[i].normalize_weight; + sap_debug("freq %d normalize weight factor %d", + chan_freq, normalize_factor); + freq_present_in_list = true; + } + } + + /* This would mean that the user does not want this freq */ + if (freq_present_in_list && !normalize_factor) { + sap_debug("chan_freq %d ecluded normalize weight 0", + chan_freq); + freq_present_in_list = false; continue; } #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE - uint8_t ch; - - ch = WLAN_REG_CH_NUM(loop_count); if ((sap_ctx->acs_cfg->skip_scan_status == eSAP_DO_PAR_ACS_SCAN)) { - if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch && - ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) || - (ch >= sap_ctx->acs_cfg->skip_scan_range2_stch && - ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) { - list[ch_count] = - WLAN_REG_CH_NUM(loop_count); - ch_count++; - sap_debug("%d %d added to ACS ch range", ch_count, ch); - } else { - sap_debug("%d %d skipped from ACS ch range", - ch_count, ch); - } + uint32_t ch_freq; + + ch_freq = WLAN_REG_CH_TO_FREQ(loop_count); + if ((ch_freq >= + sap_ctx->acs_cfg->skip_scan_range1_stch && + ch_freq <= + sap_ctx->acs_cfg->skip_scan_range1_endch) || + (ch_freq >= + sap_ctx->acs_cfg->skip_scan_range2_stch && + ch_freq <= + sap_ctx->acs_cfg->skip_scan_range2_endch)) { + list[ch_count] = + WLAN_REG_CH_TO_FREQ(loop_count); + ch_count++; + sap_debug("%d %d added to ACS ch range", + ch_count, ch_freq); + } else { + sap_debug("%d %d skipped from ACS ch range", + ch_count, ch_freq); + } } else { - list[ch_count] = - WLAN_REG_CH_NUM(loop_count); + list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count); ch_count++; - sap_debug("%d %d added to ACS ch range", ch_count, ch); + sap_debug("%d added to ACS ch range", ch_count); } #else - list[ch_count] = WLAN_REG_CH_NUM(loop_count); + list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count); ch_count++; #endif } - if (0 == ch_count) { + if (!ch_count) { sap_info("No active channels present for the current region"); /* * LTE COEX: channel range outside the restricted 2.4GHz * band limits */ - if (en_lte_coex && (start_ch_num > band_end_ch)) + if (en_lte_coex && + start_ch_freq > WLAN_REG_CH_TO_FREQ(band_end_ch)) sap_info("SAP can't be started as due to LTE COEX"); } /* return the channel list and number of channels to scan */ *num_ch = ch_count; if (ch_count != 0) { - *ch_list = list; + *freq_list = list; } else { - *ch_list = NULL; + *freq_list = NULL; qdf_mem_free(list); return QDF_STATUS_SUCCESS; } for (loop_count = 0; loop_count < ch_count; loop_count++) { - sap_ctx->acs_cfg->ch_list[loop_count] = list[loop_count]; + sap_ctx->acs_cfg->freq_list[loop_count] = list[loop_count]; } sap_ctx->acs_cfg->ch_list_count = ch_count; sap_dump_acs_channel(sap_ctx->acs_cfg); @@ -3477,7 +3643,7 @@ uint8_t sap_indicate_radar(struct sap_context *sap_ctx) mac->sap.SapDfsInfo.csaIERequired = true; if (mac->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) - return sap_ctx->channel; + return wlan_reg_freq_to_chan(mac->pdev, sap_ctx->chan_freq); /* set the Radar Found flag in SapDfsInfo */ mac->sap.SapDfsInfo.sap_radar_found_status = true; @@ -3547,8 +3713,8 @@ void sap_dfs_cac_timer_callback(void *data) * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, - "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%pK]", - sap_ctx->channel, sap_ctx); + "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_chan_freq = %d on sapctx[%pK]", + sap_ctx->chan_freq, sap_ctx); sap_event.event = eSAP_DFS_CHANNEL_CAC_END; sap_event.params = 0; @@ -3630,8 +3796,8 @@ static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx) cac_dur = cac_dur / 100; #endif QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, - "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH-%d, CAC_DUR-%d sec", - sap_ctx->channel, cac_dur / 1000); + "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH freq %d, CAC_DUR-%d sec", + sap_ctx->chan_freq, cac_dur / 1000); qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer, QDF_TIMER_TYPE_SW, @@ -3765,13 +3931,16 @@ bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle, struct mac_context *mac = MAC_CONTEXT(mac_handle); struct sap_context *sap_ctx; uint8_t intf = 0, scc_dfs_counter = 0; + qdf_freq_t ch_freq; + ch_freq = wlan_reg_legacy_chan_to_freq(mac->pdev, + given_sapctx->csr_roamProfile.op_freq); /* * current SAP persona's channel itself is not DFS, so no need to check * what other persona's channel is */ - if (!wlan_reg_is_dfs_ch(mac->pdev, - given_sapctx->csr_roamProfile.operationChannel)) { + if (!wlan_reg_is_dfs_for_freq(mac->pdev, + ch_freq)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("skip this loop as provided channel is non-dfs")); return false; @@ -3787,8 +3956,8 @@ bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle, /* if same SAP contexts then skip to next context */ if (sap_ctx == given_sapctx) continue; - if (given_sapctx->csr_roamProfile.operationChannel == - sap_ctx->csr_roamProfile.operationChannel) + if (given_sapctx->csr_roamProfile.op_freq == + sap_ctx->csr_roamProfile.op_freq) scc_dfs_counter++; } diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_internal.h b/drivers/staging/qcacld-3.0/core/sap/src/sap_internal.h index 6d2692cafb33bfe3b9b8c34d2c3f833b3467a19e..b9be0ea29c57c41a9611d3d4f5301f002ae59ce6 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_internal.h +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -122,9 +122,9 @@ struct sap_avoid_channels_info { struct sap_context { - /* Include the current channel of AP */ - uint32_t channel; - uint32_t secondary_ch; + /* Include the current channel frequency of AP */ + uint32_t chan_freq; + uint32_t sec_ch_freq; /* Include the SME(CSR) sessionId here */ uint8_t sessionId; @@ -167,11 +167,11 @@ struct sap_context { uint32_t nStaWPARSnReqIeLength; uint8_t pStaWpaRsnReqIE[MAX_ASSOC_IND_IE_LEN]; - uint8_t *channelList; + uint32_t *freq_list; uint8_t num_of_channel; uint16_t ch_width_orig; struct ch_params ch_params; - uint32_t chan_id_before_switch_band; + uint32_t chan_freq_before_switch_band; enum phy_ch_width chan_width_before_switch_band; uint32_t auto_channel_select_weight; bool enableOverLapCh; @@ -225,6 +225,7 @@ struct sap_context { bool dfs_cac_offload; bool is_chan_change_inprogress; qdf_list_t owe_pending_assoc_ind_list; + uint32_t freq_before_ch_switch; }; /*---------------------------------------------------------------------------- @@ -291,9 +292,9 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle, * Runs a algorithm to select the best channel to operate in based on BSS * rssi and bss count on each channel * - * Returns: channel number if success, 0 otherwise + * Returns: channel frequency if success, 0 otherwise */ -uint8_t sap_select_channel(mac_handle_t mac_handle, struct sap_context *sap_ctx, +uint32_t sap_select_channel(mac_handle_t mac_handle, struct sap_context *sap_ctx, qdf_list_t *scan_list); QDF_STATUS @@ -454,10 +455,10 @@ static inline uint8_t sap_indicate_radar(struct sap_context *sap_ctx) * range configuration when ACS scan fails due to some reasons, such as scan * timeout, etc. * - * Return: Selected operating channel number + * Return: Selected operating channel frequency */ -uint8_t sap_select_default_oper_chan(struct mac_context *mac_ctx, - struct sap_acs_cfg *acs_cfg); +uint32_t sap_select_default_oper_chan(struct mac_context *mac_ctx, + struct sap_acs_cfg *acs_cfg); /* * sap_is_dfs_cac_wait_state() - check if sap is in cac wait state @@ -465,28 +466,7 @@ uint8_t sap_select_default_oper_chan(struct mac_context *mac_ctx, * * Return: true if sap is in cac wait state */ -static inline bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx) -{ - if (!sap_ctx) - return false; - - return QDF_IS_STATUS_SUCCESS(wlan_vdev_is_dfs_cac_wait(sap_ctx->vdev)); -} - -/** - * sap_channel_in_acs_channel_list() - check if channel in acs channel list - * @channel_num: channel to check - * @sap_ctx: struct ptSapContext - * @spect_info_params: strcut tSapChSelSpectInfo - * - * This function checks if specified channel is in the configured ACS channel - * list. - * - * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED - */ -uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num, - struct sap_context *sap_ctx, - tSapChSelSpectInfo *spect_info_params); +bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx); /** * sap_chan_bond_dfs_sub_chan - check bonded channel includes dfs sub chan @@ -502,29 +482,4 @@ bool sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, uint8_t channel_number, ePhyChanBondState bond_state); - -/** - * sap_acquire_vdev_ref() - Increment reference count for vdev object - * @mac: mac handle - * @sap_ctx: to store vdev object pointer - * @session_id: used to get vdev object - * - * This function is used to increment vdev object reference count and store - * vdev pointer in sap_ctx. - * - * Return: QDF_STATUS_SUCCESS - If able to get vdev object reference - * else qdf status failure codes - */ -QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, - struct sap_context *sap_ctx, - uint8_t session_id); - -/** - * sap_release_vdev_ref() - Decrement reference count for vdev object - * @sap_ctx: for which vdev reference is to be decremented - * - * Return: None - */ -void sap_release_vdev_ref(struct sap_context *sap_ctx); - #endif diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_module.c b/drivers/staging/qcacld-3.0/core/sap/src/sap_module.c index ec6c78c3b539a35110d823d72d5050b9864f5685..90973e7c885708a94f7a1e13ac1f7b5b553e807f 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_module.c +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_module.c @@ -55,7 +55,6 @@ #include "cfg_ucfg_api.h" #include "wlan_mlme_ucfg_api.h" #include "wlan_mlme_vdev_mgr_interface.h" -#include "sap_ch_select.h" #define SAP_DEBUG static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION]; @@ -192,9 +191,9 @@ void wlansap_context_put(struct sap_context *ctx) for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { if (gp_sap_ctx[i] == ctx) { if (qdf_atomic_dec_and_test(&sap_ctx_ref_count[i])) { - if (ctx->channelList) { - qdf_mem_free(ctx->channelList); - ctx->channelList = NULL; + if (ctx->freq_list) { + qdf_mem_free(ctx->freq_list); + ctx->freq_list = NULL; ctx->num_of_channel = 0; } qdf_mem_free(ctx); @@ -219,7 +218,6 @@ struct sap_context *sap_create_ctx(void) return NULL; /* Clean up SAP control block, initialize all values */ - /* Save the SAP context pointer */ status = wlansap_save_context(sap_ctx); if (QDF_IS_STATUS_ERROR(status)) { @@ -379,9 +377,9 @@ QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx) } ucfg_scan_unregister_requester(mac->psoc, sap_ctx->req_id); - if (sap_ctx->channelList) { - qdf_mem_free(sap_ctx->channelList); - sap_ctx->channelList = NULL; + if (sap_ctx->freq_list) { + qdf_mem_free(sap_ctx->freq_list); + sap_ctx->freq_list = NULL; sap_ctx->num_of_channel = 0; } sap_free_roam_profile(&sap_ctx->csr_roamProfile); @@ -463,7 +461,7 @@ bool wlansap_is_channel_leaking_in_nol(struct sap_context *sap_ctx, uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx) { struct mac_context *mac; - uint16_t intf_ch; + uint16_t intf_ch_freq; eCsrPhyMode phy_mode; mac = sap_get_mac_context(); @@ -472,11 +470,12 @@ uint16_t wlansap_check_cc_intf(struct sap_context *sap_ctx) return 0; } phy_mode = sap_ctx->csr_roamProfile.phyMode; - intf_ch = sme_check_concurrent_channel_overlap(MAC_HANDLE(mac), - sap_ctx->channel, - phy_mode, - sap_ctx->cc_switch_mode); - return intf_ch; + intf_ch_freq = sme_check_concurrent_channel_overlap( + MAC_HANDLE(mac), + sap_ctx->chan_freq, + phy_mode, + sap_ctx->cc_switch_mode); + return intf_ch_freq; } #endif @@ -519,7 +518,7 @@ wlansap_set_scan_acs_channel_params(struct sap_config *config, } /* Channel selection is auto or configured */ - psap_ctx->channel = config->channel; + psap_ctx->chan_freq = config->chan_freq; psap_ctx->dfs_mode = config->acs_dfs_mode; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH psap_ctx->cc_switch_mode = config->cc_switch_mode; @@ -539,7 +538,7 @@ wlansap_set_scan_acs_channel_params(struct sap_config *config, psap_ctx->enableOverLapCh = config->enOverLapCh; psap_ctx->acs_cfg = &config->acs_cfg; psap_ctx->ch_width_orig = config->acs_cfg.ch_width; - psap_ctx->secondary_ch = config->sec_ch; + psap_ctx->sec_ch_freq = config->sec_ch_freq; /* * Set the BSSID to your "self MAC Addr" read @@ -627,19 +626,19 @@ bool wlan_sap_get_ch_params(struct sap_context *sap_ctx, */ #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle, - uint16_t sap_ch, + uint32_t sap_ch_freq, struct sap_context *sap_context) { return sme_validate_sap_channel_switch( mac_handle, - sap_ch, + sap_ch_freq, sap_context->csr_roamProfile.phyMode, sap_context->cc_switch_mode, sap_context->sessionId); } #else static bool wlan_sap_validate_channel_switch(mac_handle_t mac_handle, - uint16_t sap_ch, + uint32_t sap_ch_freq, struct sap_context *sap_context) { return true; @@ -659,6 +658,24 @@ void wlan_sap_set_sap_ctx_acs_cfg(struct sap_context *sap_ctx, sap_ctx->acs_cfg = &sap_config->acs_cfg; } +#ifdef WLAN_CONV_CRYPTO_SUPPORTED +static inline QDF_STATUS +wlansap_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, + uint8_t *ie_ptr, + uint16_t ie_len) +{ + return wlan_set_vdev_crypto_prarams_from_ie(vdev, ie_ptr, ie_len); +} +#else +static inline QDF_STATUS +wlansap_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev, + uint8_t *ie_ptr, + uint16_t ie_len) +{ + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, sap_event_cb sap_event_cb, struct sap_config *config, void *user_context) @@ -672,27 +689,29 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, int sap_chanswitch_beacon_cnt; bool sap_chanswitch_mode; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - FL("sap_ctx=%pK"), sap_ctx); - if (!sap_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Invalid SAP pointer", - __func__); + sap_info("Invalid SAP context"); return QDF_STATUS_E_FAULT; } pmac = sap_get_mac_context(); if (!pmac) { - sap_err("Invalid MAC context"); + sap_err("Invalid sap MAC context"); qdf_status = QDF_STATUS_E_INVAL; goto fail; } sap_ctx->fsm_state = SAP_INIT; + qdf_status = wlansap_set_vdev_crypto_prarams_from_ie( + sap_ctx->vdev, + config->RSNWPAReqIE, + config->RSNWPAReqIELength); + if (QDF_IS_STATUS_ERROR(qdf_status)) + sap_debug("Failed to set crypto params from IE"); + /* Channel selection is auto or configured */ - sap_ctx->channel = config->channel; + sap_ctx->chan_freq = config->chan_freq; sap_ctx->dfs_mode = config->acs_dfs_mode; sap_ctx->ch_params.ch_width = config->ch_params.ch_width; sap_ctx->ch_params.center_freq_seg0 = @@ -713,13 +732,11 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, sap_err("get_auto_channel_weight failed"); sap_ctx->auto_channel_select_weight = auto_channel_select_weight; - sap_debug("auto_channel_select_weight %d", - sap_ctx->auto_channel_select_weight); sap_ctx->user_context = user_context; sap_ctx->enableOverLapCh = config->enOverLapCh; sap_ctx->acs_cfg = &config->acs_cfg; - sap_ctx->secondary_ch = config->sec_ch; + sap_ctx->sec_ch_freq = config->sec_ch_freq; sap_ctx->dfs_cac_offload = config->dfs_cac_offload; sap_ctx->isCacEndNotified = false; sap_ctx->is_chan_change_inprogress = false; @@ -754,16 +771,14 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, sap_chanswitch_beacon_cnt; pmac->sap.SapDfsInfo.sap_ch_switch_mode = sap_chanswitch_beacon_cnt; - sap_debug("sap_chanswitch_beacon_cnt:%d", sap_chanswitch_beacon_cnt); qdf_status = ucfg_mlme_get_sap_channel_switch_mode( pmac->psoc, &sap_chanswitch_mode); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + if (QDF_IS_STATUS_ERROR(qdf_status)) sap_err("ucfg_mlme_get_sap_channel_switch_mode, set def"); - pmac->sap.SapDfsInfo.sap_ch_switch_mode = sap_chanswitch_mode; - sap_debug("sap_chanswitch_mode:%d", sap_chanswitch_mode); + pmac->sap.SapDfsInfo.sap_ch_switch_mode = sap_chanswitch_mode; pmac->sap.sapCtxList[sap_ctx->sessionId].sap_context = sap_ctx; pmac->sap.sapCtxList[sap_ctx->sessionId].sapPersona = sap_ctx->csr_roamProfile.csrPersona; @@ -776,7 +791,11 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, pmac->sap.SapDfsInfo.reduced_beacon_interval = reduced_beacon_interval; - sap_debug("reduced_beacon_interval %d", reduced_beacon_interval); + sap_debug("SAP: auth ch select weight:%d chswitch bcn cnt:%d chswitch mode:%d reduced bcn intv:%d", + sap_ctx->auto_channel_select_weight, + sap_chanswitch_beacon_cnt, + pmac->sap.SapDfsInfo.sap_ch_switch_mode, + pmac->sap.SapDfsInfo.reduced_beacon_interval); /* Copy MAC filtering settings to sap context */ sap_ctx->eSapMacAddrAclMode = config->SapMacaddr_acl; @@ -954,9 +973,9 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, } if (qdf_mem_cmp(sap_ctx->bssid.bytes, peer_sta_mac, QDF_MAC_ADDR_SIZE) == 0) { - sap_err("requested peer mac is" QDF_MAC_ADDR_STR + sap_err("requested peer mac is" QDF_MAC_ADDR_FMT "our own SAP BSSID. Do not blacklist or whitelist this BSSID", - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAULT; } QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, @@ -982,10 +1001,10 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, peer_sta_mac, &staBLIndex); if (sta_white_list && sta_black_list) { - sap_err("Peer mac " QDF_MAC_ADDR_STR + sap_err("Peer mac " QDF_MAC_ADDR_FMT " found in white and black lists." "Initial lists passed incorrect. Cannot execute this command.", - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAILURE; } @@ -999,15 +1018,15 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, /* if list is already at max, return failure */ if (sap_ctx->nAcceptMac == MAX_ACL_MAC_ADDRESS) { sap_err("White list is already maxed out. Cannot accept " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAILURE; } if (sta_white_list) { /* Do nothing if already present in white list. Just print a warning */ sap_warn("MAC address already present in white list " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_SUCCESS; } if (sta_black_list) { @@ -1017,7 +1036,7 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, &sap_ctx->nDenyMac, staBLIndex); } - sap_info("... Now add to the white list"); + sap_debug("... Now add to the white list"); sap_add_mac_to_acl(sap_ctx->acceptMacList, &sap_ctx->nAcceptMac, peer_sta_mac); @@ -1048,8 +1067,8 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, sap_ctx->nDenyMac); } else { sap_warn("MAC address to be deleted is not present in the white list " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAILURE; } } else { @@ -1066,15 +1085,15 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, /* if list is already at max, return failure */ if (sap_ctx->nDenyMac == MAX_ACL_MAC_ADDRESS) { sap_err("Black list is already maxed out. Cannot accept " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAILURE; } if (sta_black_list) { /* Do nothing if already present in white list */ sap_warn("MAC address already present in black list " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_SUCCESS; } if (sta_white_list) { @@ -1111,8 +1130,8 @@ QDF_STATUS wlansap_modify_acl(struct sap_context *sap_ctx, sap_ctx->nDenyMac); } else { sap_warn("MAC address to be deleted is not present in the black list " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_sta_mac)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_sta_mac)); return QDF_STATUS_E_FAILURE; } } else { @@ -1188,7 +1207,7 @@ QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx, */ static QDF_STATUS wlansap_update_csa_channel_params(struct sap_context *sap_context, - uint32_t channel) + uint32_t chan_freq) { struct mac_context *mac_ctx; uint32_t max_fw_bw; @@ -1199,7 +1218,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, return QDF_STATUS_E_FAULT; } - if (channel <= CHAN_ENUM_14) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { /* * currently OBSS scan is done in hostapd, so to avoid * SAP coming up in HT40 on channel switch we are @@ -1283,22 +1302,8 @@ static char *sap_get_csa_reason_str(enum sap_csa_reason_code reason) } } -/** - * wlansap_set_channel_change_with_csa() - Set channel change with CSA - * @sap_ctx: Pointer to SAP context - * @targetChannel: Target channel - * @target_bw: Target bandwidth - * @strict: if true switch to the requested channel always, - * SCC/MCC check will be ignored, - * fail otherwise - * - * This api function does a channel change to the target channel specified. - * CSA IE is included in the beacons before doing a channel change. - * - * Return: QDF_STATUS - */ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, - uint32_t targetChannel, + uint32_t target_chan_freq, enum phy_ch_width target_bw, bool strict) { @@ -1321,12 +1326,13 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, } mac_handle = MAC_HANDLE(mac); - if (strict && !policy_mgr_is_safe_channel(mac->psoc, targetChannel)) { - sap_err("%u is unsafe channel", targetChannel); + if (strict && !policy_mgr_is_safe_channel( + mac->psoc, target_chan_freq)) { + sap_err("%u is unsafe channel freq", target_chan_freq); return QDF_STATUS_E_FAULT; } sap_nofl_debug("SAP CSA: %d ---> %d conn on 5GHz:%d, csa_reason:%s(%d) strict %d vdev %d", - sap_ctx->channel, targetChannel, + sap_ctx->chan_freq, target_chan_freq, policy_mgr_is_any_mode_active_on_band_along_with_session( mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5), sap_get_csa_reason_str(sap_ctx->csa_reason), @@ -1338,10 +1344,10 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, * Now, validate if the passed channel is valid in the * current regulatory domain. */ - if (sap_ctx->channel != targetChannel && - ((wlan_reg_get_channel_state(mac->pdev, targetChannel) == + if (sap_ctx->chan_freq != target_chan_freq && + ((wlan_reg_get_channel_state_for_freq(mac->pdev, target_chan_freq) == CHANNEL_STATE_ENABLE) || - (wlan_reg_get_channel_state(mac->pdev, targetChannel) == + (wlan_reg_get_channel_state_for_freq(mac->pdev, target_chan_freq) == CHANNEL_STATE_DFS && (!policy_mgr_is_any_mode_active_on_band_along_with_session( mac->psoc, sap_ctx->sessionId, @@ -1353,11 +1359,11 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, */ if (!strict) { valid = wlan_sap_validate_channel_switch(mac_handle, - targetChannel, + target_chan_freq, sap_ctx); if (!valid) { - sap_err("Channel switch to %u is not allowed due to concurrent channel interference", - targetChannel); + sap_err("Channel freq switch to %u is not allowed due to concurrent channel interference", + target_chan_freq); return QDF_STATUS_E_FAULT; } } @@ -1369,13 +1375,14 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, */ if (sap_ctx->fsm_state == SAP_STARTED) { status = wlansap_update_csa_channel_params(sap_ctx, - targetChannel); + target_chan_freq); if (status != QDF_STATUS_SUCCESS) return status; hw_mode_status = policy_mgr_check_and_set_hw_mode_for_channel_switch( - mac->psoc, sap_ctx->sessionId, targetChannel, + mac->psoc, sap_ctx->sessionId, + target_chan_freq, POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP); /* @@ -1399,7 +1406,7 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, * Copy the requested target channel * to sap context. */ - mac->sap.SapDfsInfo.target_channel = targetChannel; + mac->sap.SapDfsInfo.target_chan_freq = target_chan_freq; mac->sap.SapDfsInfo.new_ch_params.ch_width = mac->sap.SapDfsInfo.new_chanWidth; @@ -1428,7 +1435,7 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, new_ch_params.ch_width, target_bw); } - wlan_reg_set_channel_params(mac->pdev, targetChannel, + wlan_reg_set_channel_params_for_freq(mac->pdev, target_chan_freq, 0, &mac->sap.SapDfsInfo.new_ch_params); /* * Set the CSA IE required flag. @@ -1472,8 +1479,8 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, } } else { - sap_err("Channel = %d is not valid in the current" - "regulatory domain", targetChannel); + sap_err("Channel freq = %d is not valid in the current" + "regulatory domain", target_chan_freq); return QDF_STATUS_E_FAULT; } @@ -1481,56 +1488,6 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, return QDF_STATUS_SUCCESS; } -#ifdef CRYPTO_SET_KEY_CONVERGED -static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx, - tCsrRoamSetKey *set_key_info) -{ - struct wlan_crypto_key *crypto_key; - - crypto_key = wlan_crypto_get_key(sap_ctx->vdev, 0); - if (!crypto_key) { - sap_err("Crypto KEY is NULL"); - return QDF_STATUS_E_FAILURE; - } - - return ucfg_crypto_set_key_req(sap_ctx->vdev, crypto_key, - WLAN_CRYPTO_KEY_TYPE_UNICAST); -} -#else -static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx, - tCsrRoamSetKey *set_key_info) -{ - uint32_t roam_id = INVALID_ROAM_ID; - struct mac_context *mac; - - mac = sap_get_mac_context(); - if (!mac) { - QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context"); - return QDF_STATUS_E_FAULT; - } - - return sme_roam_set_key(MAC_HANDLE(mac), sap_ctx->sessionId, - set_key_info, &roam_id); -} -#endif - -QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx, - tCsrRoamSetKey *set_key_info) -{ - QDF_STATUS qdf_status; - - if (!sap_ctx) { - sap_err("Invalid SAP pointer"); - return QDF_STATUS_E_FAULT; - } - - qdf_status = wlan_sap_set_key_helper(sap_ctx, set_key_info); - if (qdf_status != QDF_STATUS_SUCCESS) - qdf_status = QDF_STATUS_E_FAULT; - - return qdf_status; -} - QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx, uint32_t *len, uint8_t *buf) { @@ -1550,9 +1507,8 @@ QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx, qdf_mem_copy(buf, sap_ctx->pStaWpaRsnReqIE, sap_ctx->nStaWPARSnReqIeLength); - sap_info("WPAIE: "QDF_MAC_ADDR_STR"", - buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5]); + sap_info("WPAIE: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(buf)); qdf_status = QDF_STATUS_SUCCESS; } } @@ -1686,18 +1642,18 @@ QDF_STATUS wlan_sap_get_pre_cac_vdev_id(mac_handle_t handle, uint8_t *vdev_id) } void wlansap_get_sec_channel(uint8_t sec_ch_offset, - uint8_t op_channel, - uint8_t *sec_channel) + uint32_t op_chan_freq, + uint32_t *sec_chan_freq) { switch (sec_ch_offset) { case LOW_PRIMARY_CH: - *sec_channel = op_channel + 4; + *sec_chan_freq = op_chan_freq + 20; break; case HIGH_PRIMARY_CH: - *sec_channel = op_channel - 4; + *sec_chan_freq = op_chan_freq - 20; break; default: - *sec_channel = 0; + *sec_chan_freq = 0; } } @@ -1707,28 +1663,36 @@ wlansap_set_cac_required_for_chan(struct mac_context *mac_ctx, { bool is_ch_dfs = false; bool cac_required; + uint32_t chan_freq; uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t sta_cnt, i; + chan_freq = sap_ctx->chan_freq; if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) { is_ch_dfs = true; } else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) { - if ((wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == - CHANNEL_STATE_DFS) || - (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->ch_params.center_freq_seg1 - - SIR_80MHZ_START_CENTER_CH_DIFF) == - CHANNEL_STATE_DFS)) + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_ctx->chan_freq) == + CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_ctx->ch_params.mhz_freq_seg1) == + CHANNEL_STATE_DFS) + is_ch_dfs = true; + } else { + if (wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + sap_ctx->chan_freq) == + CHANNEL_STATE_DFS) is_ch_dfs = true; - } else if (wlan_reg_get_channel_state(mac_ctx->pdev, - sap_ctx->channel) == - CHANNEL_STATE_DFS) { - is_ch_dfs = true; } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) + is_ch_dfs = false; + sap_debug("vdev id %d chan %d is_ch_dfs %d pre_cac_complete %d ignore_cac %d cac_state %d", - sap_ctx->sessionId, sap_ctx->channel, is_ch_dfs, + sap_ctx->sessionId, chan_freq, is_ch_dfs, sap_ctx->pre_cac_complete, mac_ctx->sap.SapDfsInfo.ignore_cac, mac_ctx->sap.SapDfsInfo.cac_state); @@ -1742,12 +1706,12 @@ wlansap_set_cac_required_for_chan(struct mac_context *mac_ctx, if (cac_required) { sta_cnt = policy_mgr_get_mode_specific_conn_info(mac_ctx->psoc, - chan_list, + freq_list, vdev_id_list, PM_STA_MODE); for (i = 0; i < sta_cnt; i++) { - if (sap_ctx->channel == chan_list[i]) { + if (sap_ctx->chan_freq == freq_list[i]) { sap_debug("STA vdev id %d exists, ignore CAC", vdev_id_list[i]); cac_required = false; @@ -1759,14 +1723,14 @@ wlansap_set_cac_required_for_chan(struct mac_context *mac_ctx, } QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, - uint8_t target_channel) + uint32_t target_chan_freq) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac_ctx; eCsrPhyMode phy_mode; struct ch_params *ch_params; - if (!target_channel) { + if (!target_chan_freq) { sap_err("channel 0 requested"); return QDF_STATUS_E_FAULT; } @@ -1785,44 +1749,40 @@ QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, phy_mode = sap_ctx->csr_roamProfile.phyMode; /* Update phy_mode if the target channel is in the other band */ - if (WLAN_CHAN_IS_5GHZ(target_channel) && + if (WLAN_REG_IS_5GHZ_CH_FREQ(target_chan_freq) && ((phy_mode == eCSR_DOT11_MODE_11g) || (phy_mode == eCSR_DOT11_MODE_11g_ONLY))) phy_mode = eCSR_DOT11_MODE_11a; - else if (WLAN_CHAN_IS_2GHZ(target_channel) && + else if (WLAN_REG_IS_24GHZ_CH_FREQ(target_chan_freq) && (phy_mode == eCSR_DOT11_MODE_11a)) phy_mode = eCSR_DOT11_MODE_11g; sap_ctx->csr_roamProfile.phyMode = phy_mode; if (sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels == 0 || - !sap_ctx->csr_roamProfile.ChannelInfo.ChannelList) { + !sap_ctx->csr_roamProfile.ChannelInfo.freq_list) { sap_err("Invalid channel list"); return QDF_STATUS_E_FAULT; } - sap_ctx->csr_roamProfile.ChannelInfo.ChannelList[0] = target_channel; + sap_ctx->csr_roamProfile.ChannelInfo.freq_list[0] = target_chan_freq; + /* * We are getting channel bonding mode from sapDfsInfor structure * because we've implemented channel width fallback mechanism for DFS * which will result in channel width changing dynamically. */ ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params; - wlan_reg_set_channel_params(mac_ctx->pdev, target_channel, + wlan_reg_set_channel_params_for_freq(mac_ctx->pdev, target_chan_freq, 0, ch_params); sap_ctx->ch_params = *ch_params; + sap_ctx->freq_before_ch_switch = sap_ctx->chan_freq; /* Update the channel as this will be used to * send event to supplicant */ - sap_ctx->channel = target_channel; - wlansap_get_sec_channel(ch_params->sec_ch_offset, target_channel, - (uint8_t *)(&sap_ctx->secondary_ch)); - sap_ctx->csr_roamProfile.ch_params.ch_width = ch_params->ch_width; - sap_ctx->csr_roamProfile.ch_params.sec_ch_offset = - ch_params->sec_ch_offset; - sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 = - ch_params->center_freq_seg0; - sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 = - ch_params->center_freq_seg1; + sap_ctx->chan_freq = target_chan_freq; + wlansap_get_sec_channel(ch_params->sec_ch_offset, sap_ctx->chan_freq, + &sap_ctx->sec_ch_freq); + sap_ctx->csr_roamProfile.ch_params = *ch_params; sap_dfs_set_current_channel(sap_ctx); wlansap_set_cac_required_for_chan(mac_ctx, sap_ctx); @@ -1831,15 +1791,10 @@ QDF_STATUS wlansap_channel_change_request(struct sap_context *sap_ctx, ch_params, &sap_ctx->csr_roamProfile); - sap_info("chan:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d", - sap_ctx->channel, phy_mode, ch_params->ch_width, - ch_params->sec_ch_offset, ch_params->center_freq_seg0, - ch_params->center_freq_seg1); - - if (QDF_IS_STATUS_SUCCESS(status)) - sap_signal_hdd_event(sap_ctx, NULL, - eSAP_CHANNEL_CHANGE_EVENT, - (void *) eSAP_STATUS_SUCCESS); + sap_debug("chan_freq:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d", + sap_ctx->chan_freq, phy_mode, ch_params->ch_width, + ch_params->sec_ch_offset, ch_params->center_freq_seg0, + ch_params->center_freq_seg1); return status; } @@ -1891,19 +1846,19 @@ QDF_STATUS wlansap_dfs_send_csa_ie_request(struct sap_context *sap_ctx) mac->sap.SapDfsInfo.new_ch_params.ch_width = mac->sap.SapDfsInfo.new_chanWidth; - wlan_reg_set_channel_params(mac->pdev, - mac->sap.SapDfsInfo.target_channel, + wlan_reg_set_channel_params_for_freq(mac->pdev, + mac->sap.SapDfsInfo.target_chan_freq, 0, &mac->sap.SapDfsInfo.new_ch_params); - sap_info("chan:%d req:%d width:%d off:%d", - mac->sap.SapDfsInfo.target_channel, - mac->sap.SapDfsInfo.csaIERequired, - mac->sap.SapDfsInfo.new_ch_params.ch_width, - mac->sap.SapDfsInfo.new_ch_params.sec_ch_offset); + sap_debug("chan freq:%d req:%d width:%d off:%d", + mac->sap.SapDfsInfo.target_chan_freq, + mac->sap.SapDfsInfo.csaIERequired, + mac->sap.SapDfsInfo.new_ch_params.ch_width, + mac->sap.SapDfsInfo.new_ch_params.sec_ch_offset); return sme_roam_csa_ie_request(MAC_HANDLE(mac), sap_ctx->bssid, - mac->sap.SapDfsInfo.target_channel, + mac->sap.SapDfsInfo.target_chan_freq, mac->sap.SapDfsInfo.csaIERequired, &mac->sap.SapDfsInfo.new_ch_params); } @@ -1947,7 +1902,7 @@ bool sap_is_auto_channel_select(struct sap_context *sapcontext) sap_err("Invalid SAP pointer"); return false; } - return sapcontext->channel == AUTO_CHANNEL_SELECT; + return sapcontext->chan_freq == AUTO_CHANNEL_SELECT; } #ifdef FEATURE_AP_MCC_CH_AVOIDANCE @@ -2032,7 +1987,7 @@ wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle) status = QDF_STATUS_SUCCESS; } else { - sap_err("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location"); + sap_debug("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location"); status = QDF_STATUS_E_FAULT; } @@ -2041,7 +1996,7 @@ wlansap_set_dfs_preferred_channel_location(mac_handle_t mac_handle) } QDF_STATUS wlansap_set_dfs_target_chnl(mac_handle_t mac_handle, - uint8_t target_channel) + uint32_t target_chan_freq) { struct mac_context *mac = NULL; @@ -2051,11 +2006,11 @@ QDF_STATUS wlansap_set_dfs_target_chnl(mac_handle_t mac_handle, sap_err("Invalid mac_handle pointer"); return QDF_STATUS_E_FAULT; } - if (target_channel > 0) { - mac->sap.SapDfsInfo.user_provided_target_channel = - target_channel; + if (target_chan_freq > 0) { + mac->sap.SapDfsInfo.user_provided_target_chan_freq = + target_chan_freq; } else { - mac->sap.SapDfsInfo.user_provided_target_channel = 0; + mac->sap.SapDfsInfo.user_provided_target_chan_freq = 0; } return QDF_STATUS_SUCCESS; @@ -2182,6 +2137,42 @@ wlansap_reset_sap_config_add_ie(struct sap_config *config, return QDF_STATUS_SUCCESS; } +#define ACS_WLAN_20M_CH_INC 20 +#define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC +#define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3) + +#ifdef CONFIG_BAND_6GHZ +static void wlansap_update_start_range_6ghz( + uint32_t *start_ch_freq, uint32_t *bandStartChannel) +{ + *bandStartChannel = CHAN_ENUM_5945; + *start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) > + wlan_reg_ch_to_freq(CHAN_ENUM_5945) ? + (*start_ch_freq - ACS_5G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_5945); +} + +static void wlansap_update_end_range_6ghz( + uint32_t *end_ch_freq, uint32_t *bandEndChannel) +{ + *bandEndChannel = CHAN_ENUM_7105; + *end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= + wlan_reg_ch_to_freq(CHAN_ENUM_7105) ? + (*end_ch_freq + ACS_5G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_7105); +} +#else +static void wlansap_update_start_range_6ghz( + uint32_t *start_ch_freq, uint32_t *bandStartChannel) +{ +} + +static void wlansap_update_end_range_6ghz( + uint32_t *end_ch_freq, uint32_t *bandEndChannel) +{ +} +#endif + /*========================================================================== FUNCTION wlansap_extend_to_acs_range @@ -2190,26 +2181,22 @@ wlansap_reset_sap_config_add_ie(struct sap_config *config, DEPENDENCIES PARAMETERS IN /OUT - *startChannelNum : ACS extend start ch - *endChannelNum : ACS extended End ch - *bandStartChannel: Band start ch - *bandEndChannel : Band end ch + * start_ch_freq : ACS extend start ch + * end_ch_freq : ACS extended End ch + * bandStartChannel: Band start ch + * bandEndChannel : Band end ch RETURN VALUE NONE SIDE EFFECTS ============================================================================*/ void wlansap_extend_to_acs_range(mac_handle_t mac_handle, - uint8_t *startChannelNum, - uint8_t *endChannelNum, - uint8_t *bandStartChannel, - uint8_t *bandEndChannel) + uint32_t *start_ch_freq, + uint32_t *end_ch_freq, + uint32_t *bandStartChannel, + uint32_t *bandEndChannel) { -#define ACS_WLAN_20M_CH_INC 4 -#define ACS_2G_EXTEND ACS_WLAN_20M_CH_INC -#define ACS_5G_EXTEND (ACS_WLAN_20M_CH_INC * 3) - - uint8_t tmp_startChannelNum = 0, tmp_endChannelNum = 0; + uint32_t tmp_start_ch_freq = 0, tmp_end_ch_freq = 0; struct mac_context *mac_ctx; mac_ctx = MAC_CONTEXT(mac_handle); @@ -2217,53 +2204,81 @@ void wlansap_extend_to_acs_range(mac_handle_t mac_handle, sap_err("Invalid mac_ctx"); return; } - if (*startChannelNum <= 14 && *endChannelNum <= 14) { - *bandStartChannel = CHAN_ENUM_1; - *bandEndChannel = CHAN_ENUM_14; - tmp_startChannelNum = *startChannelNum > 5 ? - (*startChannelNum - ACS_2G_EXTEND) : 1; - tmp_endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ? - (*endChannelNum + ACS_2G_EXTEND) : 14; - } else if (*startChannelNum >= 36 && *endChannelNum >= 36) { - *bandStartChannel = CHAN_ENUM_36; - *bandEndChannel = CHAN_ENUM_173; - tmp_startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ? - (*startChannelNum - ACS_5G_EXTEND) : 36; - tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= - WNI_CFG_CURRENT_CHANNEL_STAMAX ? - (*endChannelNum + ACS_5G_EXTEND) : - WNI_CFG_CURRENT_CHANNEL_STAMAX; + if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) { + *bandStartChannel = CHAN_ENUM_2412; + tmp_start_ch_freq = *start_ch_freq > + wlan_reg_ch_to_freq(CHAN_ENUM_2432) ? + (*start_ch_freq - ACS_2G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_2412); + } else if (*start_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5865)) { + *bandStartChannel = CHAN_ENUM_5180; + tmp_start_ch_freq = (*start_ch_freq - ACS_5G_EXTEND) > + wlan_reg_ch_to_freq(CHAN_ENUM_5180) ? + (*start_ch_freq - ACS_5G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_5180); + } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*start_ch_freq)) { + tmp_start_ch_freq = *start_ch_freq; + wlansap_update_start_range_6ghz(&tmp_start_ch_freq, + bandStartChannel); } else { - *bandStartChannel = CHAN_ENUM_1; - *bandEndChannel = CHAN_ENUM_173; - tmp_startChannelNum = *startChannelNum > 5 ? - (*startChannelNum - ACS_2G_EXTEND) : 1; - tmp_endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= - WNI_CFG_CURRENT_CHANNEL_STAMAX ? - (*endChannelNum + ACS_5G_EXTEND) : - WNI_CFG_CURRENT_CHANNEL_STAMAX; - } + *bandStartChannel = CHAN_ENUM_2412; + tmp_start_ch_freq = *start_ch_freq > + wlan_reg_ch_to_freq(CHAN_ENUM_2432) ? + (*start_ch_freq - ACS_2G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_2412); + sap_err("unexpected start freq %d", + *start_ch_freq); + } + + if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) { + *bandEndChannel = CHAN_ENUM_2484; + tmp_end_ch_freq = (*end_ch_freq + ACS_2G_EXTEND) <= + wlan_reg_ch_to_freq(CHAN_ENUM_2484) ? + (*end_ch_freq + ACS_2G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_2484); + } else if (*end_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_5865)) { + *bandEndChannel = CHAN_ENUM_5865; + tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= + wlan_reg_ch_to_freq(CHAN_ENUM_5865) ? + (*end_ch_freq + ACS_5G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_5865); + } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(*end_ch_freq)) { + tmp_end_ch_freq = *end_ch_freq; + wlansap_update_end_range_6ghz(&tmp_end_ch_freq, + bandEndChannel); + } else { + *bandEndChannel = CHAN_ENUM_5865; + tmp_end_ch_freq = (*end_ch_freq + ACS_5G_EXTEND) <= + wlan_reg_ch_to_freq(CHAN_ENUM_5865) ? + (*end_ch_freq + ACS_5G_EXTEND) : + wlan_reg_ch_to_freq(CHAN_ENUM_5865); + sap_err("unexpected end freq %d", *end_ch_freq); + } + *start_ch_freq = tmp_start_ch_freq; + *end_ch_freq = tmp_end_ch_freq; /* Note if the ACS range include only DFS channels, do not cross range * Active scanning in adjacent non DFS channels results in transmission * spikes in DFS specturm channels which is due to emission spill. * Remove the active channels from extend ACS range for DFS only range */ - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, *startChannelNum)) { - while (!wlan_reg_is_dfs_ch(mac_ctx->pdev, - tmp_startChannelNum) && - tmp_startChannelNum < *startChannelNum) - tmp_startChannelNum += ACS_WLAN_20M_CH_INC; + if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *start_ch_freq)) { + while (!wlan_reg_is_dfs_for_freq( + mac_ctx->pdev, + tmp_start_ch_freq) && + tmp_start_ch_freq < *start_ch_freq) + tmp_start_ch_freq += ACS_WLAN_20M_CH_INC; - *startChannelNum = tmp_startChannelNum; + *start_ch_freq = tmp_start_ch_freq; } - if (wlan_reg_is_dfs_ch(mac_ctx->pdev, *endChannelNum)) { - while (!wlan_reg_is_dfs_ch(mac_ctx->pdev, - tmp_endChannelNum) && - tmp_endChannelNum > *endChannelNum) - tmp_endChannelNum -= ACS_WLAN_20M_CH_INC; + if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, *end_ch_freq)) { + while (!wlan_reg_is_dfs_for_freq( + mac_ctx->pdev, + tmp_end_ch_freq) && + tmp_end_ch_freq > *end_ch_freq) + tmp_end_ch_freq -= ACS_WLAN_20M_CH_INC; - *endChannelNum = tmp_endChannelNum; + *end_ch_freq = tmp_end_ch_freq; } } @@ -2339,9 +2354,9 @@ void wlansap_populate_del_sta_params(const uint8_t *mac, else params->subtype = SIR_MAC_MGMT_DEAUTH; - sap_debug("Delete STA with RC:%hu subtype:%hhu MAC::" QDF_MAC_ADDR_STR, + sap_debug("Delete STA with RC:%hu subtype:%hhu MAC::" QDF_MAC_ADDR_FMT, params->reason_code, params->subtype, - QDF_MAC_ADDR_ARRAY(params->peerMacAddr.bytes)); + QDF_MAC_ADDR_REF(params->peerMacAddr.bytes)); } void sap_undo_acs(struct sap_context *sap_ctx, struct sap_config *sap_cfg) @@ -2355,20 +2370,20 @@ void sap_undo_acs(struct sap_context *sap_ctx, struct sap_config *sap_cfg) if (!acs_cfg) return; - if (acs_cfg->ch_list) { - sap_debug("Clearing ACS cfg channel list"); - qdf_mem_free(acs_cfg->ch_list); - acs_cfg->ch_list = NULL; + if (acs_cfg->freq_list) { + sap_debug("Clearing ACS cfg ch freq list"); + qdf_mem_free(acs_cfg->freq_list); + acs_cfg->freq_list = NULL; } - if (acs_cfg->master_ch_list) { - sap_debug("Clearing master ACS cfg channel list"); - qdf_mem_free(acs_cfg->master_ch_list); - acs_cfg->master_ch_list = NULL; + if (acs_cfg->master_freq_list) { + sap_debug("Clearing master ACS cfg chan freq list"); + qdf_mem_free(acs_cfg->master_freq_list); + acs_cfg->master_freq_list = NULL; } - if (sap_ctx->channelList) { + if (sap_ctx->freq_list) { sap_debug("Clearing sap context ch freq list"); - qdf_mem_free(sap_ctx->channelList); - sap_ctx->channelList = NULL; + qdf_mem_free(sap_ctx->freq_list); + sap_ctx->freq_list = NULL; } acs_cfg->ch_list_count = 0; acs_cfg->master_ch_list_count = 0; @@ -2442,7 +2457,8 @@ QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context, * So send selected channel to HDD */ sap_err("Scan Req Failed/ACS Overridden"); - sap_err("Selected channel = %d", sap_context->channel); + sap_err("Selected channel frequency = %d", + sap_context->chan_freq); return sap_signal_hdd_event(sap_context, NULL, eSAP_ACS_CHANNEL_SELECTED, @@ -2476,6 +2492,19 @@ void wlan_sap_enable_phy_error_logs(mac_handle_t mac_handle, sizeof(uint32_t), NULL, NULL, &error); } +#ifdef DFS_PRI_MULTIPLIER +void wlan_sap_set_dfs_pri_multiplier(mac_handle_t mac_handle) +{ + int error; + + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + + tgt_dfs_control(mac_ctx->pdev, DFS_SET_PRI_MULTIPILER, + &mac_ctx->mlme_cfg->dfs_cfg.dfs_pri_multiplier, + sizeof(uint32_t), NULL, NULL, &error); +} +#endif + uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx) { return wlan_sap_get_vht_ch_width(sap_ctx); @@ -2510,7 +2539,7 @@ void wlansap_cleanup_cac_timer(struct sap_context *sap_ctx) struct mac_context *mac; if (!sap_ctx) { - sap_err("Invalid SAP context"); + sap_debug("Invalid SAP context"); return; } @@ -2688,37 +2717,39 @@ QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx, return status; } -static bool wlansap_is_channel_present_in_acs_list(uint8_t ch, uint8_t *ch_list, - uint8_t ch_count) +bool wlansap_is_channel_present_in_acs_list(uint32_t freq, + uint32_t *ch_freq_list, + uint8_t ch_count) { uint8_t i; - for (i = 0; i < ch_count; i++) - if (ch_list[i] == ch) + for(i = 0; i < ch_count; i++) + if (ch_freq_list[i] == freq) return true; return false; } QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, - uint8_t *ch_list, + uint32_t *ch_freq_list, uint32_t *ch_cnt) { size_t ch_index; size_t target_ch_cnt = 0; - if (!sap_ctx || !ch_list || !ch_cnt || - !sap_ctx->acs_cfg->master_ch_list || + if (!sap_ctx || !ch_freq_list || !ch_cnt || + !sap_ctx->acs_cfg->master_freq_list || !sap_ctx->acs_cfg->master_ch_list_count) { sap_err("NULL parameters"); return QDF_STATUS_E_FAULT; } for (ch_index = 0; ch_index < *ch_cnt; ch_index++) { - if (wlansap_is_channel_present_in_acs_list(ch_list[ch_index], - sap_ctx->acs_cfg->master_ch_list, + if (wlansap_is_channel_present_in_acs_list( + ch_freq_list[ch_index], + sap_ctx->acs_cfg->master_freq_list, sap_ctx->acs_cfg->master_ch_list_count)) - ch_list[target_ch_cnt++] = ch_list[ch_index]; + ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index]; } *ch_cnt = target_ch_cnt; @@ -2726,6 +2757,25 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, return QDF_STATUS_SUCCESS; } +bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx) +{ + uint32_t i; + uint32_t *ch_freq_list; + + if (!sap_ctx || !sap_ctx->acs_cfg || + !sap_ctx->acs_cfg->master_freq_list || + !sap_ctx->acs_cfg->master_ch_list_count) { + sap_err("NULL parameters"); + return false; + } + ch_freq_list = sap_ctx->acs_cfg->master_freq_list; + for (i = 0; i < sap_ctx->acs_cfg->master_ch_list_count; i++) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i])) + return true; + } + return false; +} + #if defined(FEATURE_WLAN_CH_AVOID) /** * wlansap_get_safe_channel() - Get safe channel from current regulatory @@ -2734,16 +2784,17 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, * This function is used to get safe channel from current regulatory valid * channels to restart SAP if failed to get safe channel from PCL. * - * Return: Channel number to restart SAP in case of success. In case of any + * Return: Chan freq num to restart SAP in case of success. In case of any * failure, the channel number returned is zero. */ -static uint8_t +static uint32_t wlansap_get_safe_channel(struct sap_context *sap_ctx) { struct mac_context *mac; - struct sir_pcl_list pcl = {0}; + uint32_t pcl_freqs[NUM_CHANNELS]; QDF_STATUS status; mac_handle_t mac_handle; + uint32_t pcl_len = 0; if (!sap_ctx) { sap_err("NULL parameter"); @@ -2758,36 +2809,33 @@ wlansap_get_safe_channel(struct sap_context *sap_ctx) mac_handle = MAC_HANDLE(mac); /* get the channel list for current domain */ - status = policy_mgr_get_valid_chans(mac->psoc, - pcl.pcl_list, - &pcl.pcl_len); + status = policy_mgr_get_valid_chans(mac->psoc, pcl_freqs, &pcl_len); if (QDF_IS_STATUS_ERROR(status)) { sap_err("Error in getting valid channels"); return INVALID_CHANNEL_ID; } - status = wlansap_filter_ch_based_acs(sap_ctx, - pcl.pcl_list, - &pcl.pcl_len); + status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs, &pcl_len); + if (QDF_IS_STATUS_ERROR(status)) { sap_err("failed to filter ch from acs %d", status); return INVALID_CHANNEL_ID; } - if (pcl.pcl_len) { + if (pcl_len) { status = policy_mgr_get_valid_chans_from_range(mac->psoc, - pcl.pcl_list, - &pcl.pcl_len, + pcl_freqs, + &pcl_len, PM_SAP_MODE); if (QDF_IS_STATUS_ERROR(status)) { sap_err("failed to get valid channel: %d", status); return INVALID_CHANNEL_ID; } - if (pcl.pcl_len) { + if (pcl_len) { sap_debug("select %d from valid channel list", - pcl.pcl_list[0]); - return pcl.pcl_list[0]; + pcl_freqs[0]); + return pcl_freqs[0]; } } @@ -2811,13 +2859,15 @@ wlansap_get_safe_channel(struct sap_context *sap_ctx) } #endif -uint8_t +uint32_t wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) { struct mac_context *mac; struct sir_pcl_list pcl = {0}; + uint32_t pcl_freqs[NUM_CHANNELS] = {0}; QDF_STATUS status; mac_handle_t mac_handle; + uint32_t pcl_len = 0; if (!sap_ctx) { sap_err("NULL parameter"); @@ -2837,7 +2887,7 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) } status = policy_mgr_get_pcl_for_existing_conn( - mac->psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, + mac->psoc, PM_SAP_MODE, pcl_freqs, &pcl_len, pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list), false); if (QDF_IS_STATUS_ERROR(status)) { @@ -2845,19 +2895,18 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) return INVALID_CHANNEL_ID; } - if (pcl.pcl_len) { - status = wlansap_filter_ch_based_acs(sap_ctx, - pcl.pcl_list, - &pcl.pcl_len); + if (pcl_len) { + status = wlansap_filter_ch_based_acs(sap_ctx, pcl_freqs, + &pcl_len); if (QDF_IS_STATUS_ERROR(status)) { sap_err("failed to filter ch from acs %d", status); return INVALID_CHANNEL_ID; } - if (pcl.pcl_len) { - sap_debug("select %d from valid channel list", - pcl.pcl_list[0]); - return pcl.pcl_list[0]; + if (pcl_len) { + sap_debug("select %d from valid ch freq list", + pcl_freqs[0]); + return pcl_freqs[0]; } sap_debug("no safe channel from PCL found in ACS range"); } else { @@ -2872,15 +2921,15 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) return wlansap_get_safe_channel(sap_ctx); } -static uint8_t wlansap_get_2g_first_safe_chan(struct sap_context *sap_ctx) +static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx) { uint32_t i; - uint8_t chan; + uint32_t freq; enum channel_state state; struct regulatory_channel *cur_chan_list; struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_psoc *psoc; - uint8_t *acs_chan_list; + uint32_t *acs_freq_list; uint8_t acs_list_count; pdev = sap_ctx->vdev->vdev_objmgr.wlan_pdev; @@ -2889,46 +2938,47 @@ static uint8_t wlansap_get_2g_first_safe_chan(struct sap_context *sap_ctx) cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(struct regulatory_channel)); if (!cur_chan_list) - return CHANNEL_6; + return TWOG_CHAN_6_IN_MHZ; if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { - chan = CHANNEL_6; + freq = TWOG_CHAN_6_IN_MHZ; goto err; } - acs_chan_list = sap_ctx->acs_cfg->master_ch_list; + acs_freq_list = sap_ctx->acs_cfg->master_freq_list; acs_list_count = sap_ctx->acs_cfg->master_ch_list_count; for (i = 0; i < NUM_CHANNELS; i++) { - chan = cur_chan_list[i].center_freq; - state = wlan_reg_get_channel_state(pdev, chan); + freq = cur_chan_list[i].center_freq; + state = wlan_reg_get_channel_state_for_freq(pdev, freq); if (state != CHANNEL_STATE_DISABLE && state != CHANNEL_STATE_INVALID && - wlan_reg_is_24ghz_ch(chan) && - policy_mgr_is_safe_channel(psoc, chan) && - wlansap_is_channel_present_in_acs_list(chan, - acs_chan_list, + wlan_reg_is_24ghz_ch_freq(freq) && + policy_mgr_is_safe_channel(psoc, freq) && + wlansap_is_channel_present_in_acs_list(freq, + acs_freq_list, acs_list_count)) { - sap_debug("find a 2g channel: %d", chan); + sap_debug("find a 2g channel: %d", freq); goto err; } } - chan = CHANNEL_6; + freq = TWOG_CHAN_6_IN_MHZ; err: qdf_mem_free(cur_chan_list); - return chan; + return freq; } -uint8_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx) +qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx) { - uint8_t restart_chan; + uint32_t restart_freq; enum phy_ch_width restart_ch_width; - uint8_t intf_ch; + uint16_t intf_ch_freq; uint32_t phy_mode; struct mac_context *mac; uint8_t cc_mode; - enum band_info sap_band; + uint8_t vdev_id; + enum reg_wifi_band sap_band; enum band_info band; if (!sap_ctx) { @@ -2939,44 +2989,41 @@ uint8_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx) return 0; mac = cds_get_context(QDF_MODULE_ID_PE); - if (!mac || !mac->pdev) + if (!mac) { + sap_err("Invalid MAC context"); return 0; - if (ucfg_reg_get_curr_band(mac->pdev, &band) != QDF_STATUS_SUCCESS) { + } + + if (ucfg_reg_get_band(mac->pdev, &band) != QDF_STATUS_SUCCESS) { sap_err("Failed to get current band config"); return 0; } - if (!sap_ctx->channel) - return 0; - sap_band = sap_ctx->channel <= 14 ? BAND_2G : BAND_5G; + sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq); sap_debug("SAP/Go current band: %d, pdev band capability: %d", sap_band, band); - if (sap_band == BAND_5G && band == BAND_2G) { - sap_ctx->chan_id_before_switch_band = sap_ctx->channel; + if (sap_band == REG_BAND_5G && band == BIT(REG_BAND_2G)) { + sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq; sap_ctx->chan_width_before_switch_band = sap_ctx->ch_params.ch_width; sap_debug("Save chan info before switch: %d, width: %d", - sap_ctx->channel, sap_ctx->ch_params.ch_width); - restart_chan = wlansap_get_2g_first_safe_chan(sap_ctx); - if (restart_chan == 0) { + sap_ctx->chan_freq, sap_ctx->ch_params.ch_width); + restart_freq = wlansap_get_2g_first_safe_chan_freq(sap_ctx); + if (restart_freq == 0) { sap_debug("use default chan 6"); - restart_chan = CHANNEL_6; + restart_freq = TWOG_CHAN_6_IN_MHZ; } restart_ch_width = sap_ctx->ch_params.ch_width; if (restart_ch_width > CH_WIDTH_40MHZ) { sap_debug("set 40M when switch SAP to 2G"); restart_ch_width = CH_WIDTH_40MHZ; } - } else if (sap_band == BAND_2G && - (band == BAND_ALL || band == BAND_5G)) { - if (sap_ctx->chan_id_before_switch_band == 0) + } else if (sap_band == REG_BAND_2G && (band & BIT(REG_BAND_5G))) { + if (sap_ctx->chan_freq_before_switch_band == 0) return 0; - restart_chan = sap_ctx->chan_id_before_switch_band; + restart_freq = sap_ctx->chan_freq_before_switch_band; restart_ch_width = sap_ctx->chan_width_before_switch_band; - sap_debug("Restore chan: %d, width: %d", - restart_chan, restart_ch_width); - sap_ctx->chan_id_before_switch_band = 0; - sap_ctx->chan_width_before_switch_band = CH_WIDTH_INVALID; - + sap_debug("Restore chan freq: %d, width: %d", + restart_freq, restart_ch_width); } else { sap_debug("No need switch SAP/Go channel"); return 0; @@ -2984,13 +3031,16 @@ uint8_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx) cc_mode = sap_ctx->cc_switch_mode; phy_mode = sap_ctx->csr_roamProfile.phyMode; - intf_ch = sme_check_concurrent_channel_overlap(MAC_HANDLE(mac), - restart_chan, + intf_ch_freq = sme_check_concurrent_channel_overlap( + MAC_HANDLE(mac), + restart_freq, phy_mode, cc_mode); - if (intf_ch) - restart_chan = intf_ch; - sap_debug("CSA target ch: %d", restart_chan); + if (intf_ch_freq) + restart_freq = intf_ch_freq; + vdev_id = sap_ctx->vdev->vdev_objmgr.vdev_id; + sap_debug("vdev: %d, CSA target freq: %d", vdev_id, restart_freq); - return restart_chan; + return restart_freq; } + diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h index 361d41d3c98f602ecfa32baf605f93a9750cf374..a19e54e845a26ab357151edafec9c7931020dc12 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -196,7 +197,7 @@ typedef enum { typedef struct tagCsrChannelInfo { uint8_t numOfChannels; - uint8_t *ChannelList; /* it will be an array of channels */ + uint32_t *freq_list; } tCsrChannelInfo, *tpCsrChannelInfo; typedef enum { @@ -266,62 +267,11 @@ typedef struct tagCsrEseCckmIe { typedef struct sCsrChannel_ { uint8_t numChannels; - uint8_t channelList[CFG_VALID_CHANNEL_LIST_LEN]; + uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; } sCsrChannel; -typedef struct tagCsrScanResultFilter { - tCsrBSSIDs BSSIDs; - tCsrSSIDs SSIDs; - tCsrChannelInfo ChannelInfo; - tCsrAuthList authType; - tCsrEncryptionList EncryptionType; - /* - * eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type. - * If caller doesn't case, put all supported encryption types in here - */ - tCsrEncryptionList mcEncryptionType; - eCsrRoamBssType BSSType; - /* its a bit mask of all the needed phy mode defined in eCsrPhyMode */ - eCsrPhyMode phyMode; - /* - * If countryCode[0] is not 0, countryCode is checked - * independent of fCheckUnknownCountryCode - */ - uint8_t countryCode[CFG_COUNTRY_CODE_LEN]; - uint8_t uapsd_mask; - /* For WPS filtering if true => auth and ecryption should be ignored */ - bool bWPSAssociation; - bool bOSENAssociation; - /* - * For measurement reports --> if set, only SSID, - * BSSID and channel is considered for filtering. - */ - bool fMeasurement; - struct mobility_domain_info mdid; - bool p2pResult; -#ifdef WLAN_FEATURE_11W - /* Management Frame Protection */ - bool MFPEnabled; - uint8_t MFPRequired; - uint8_t MFPCapable; -#endif - /* The following flag is used to distinguish the - * roaming case while building the scan filter and - * applying it on to the scan results. This is mainly - * used to support whitelist ssid feature. - */ - uint8_t scan_filter_for_roam; - struct sCsrChannel_ pcl_channels; - struct qdf_mac_addr bssid_hint; - enum QDF_OPMODE csrPersona; - bool realm_check; - uint8_t fils_realm[2]; - bool force_rsne_override; - qdf_time_t age_threshold; -} tCsrScanResultFilter; - typedef struct sCsrChnPower_ { - uint8_t firstChannel; + uint32_t first_chan_freq; uint8_t numChannels; uint8_t maxtxPower; } sCsrChnPower; @@ -625,8 +575,9 @@ typedef enum { * For both 11a and 11g mode. */ #define CSR_CB_CHANNEL_GAP 4 -#define CSR_CB_CENTER_CHANNEL_OFFSET 2 -#define CSR_SEC_CHANNEL_OFFSET 4 +/* Considering 5 MHz Channel BW */ +#define CSR_CB_CENTER_CHANNEL_OFFSET 10 +#define CSR_SEC_CHANNEL_OFFSET 20 /* WEP keysize (in bits) */ @@ -683,13 +634,6 @@ typedef enum { } eCsrRoamWmmUserModeType; -typedef enum { - eCSR_REQUESTER_MIN = 0, - eCSR_DIAG, - eCSR_UMA_GAN, - eCSR_HDD -} eCsrStatsRequesterType; - typedef struct tagPmkidCandidateInfo { struct qdf_mac_addr BSSID; bool preAuthSupported; @@ -703,10 +647,6 @@ typedef struct tagPmkidCacheInfo { uint8_t ssid_len; uint8_t ssid[WLAN_SSID_MAX_LEN]; uint8_t cache_id[CACHE_ID_LEN]; - struct mobility_domain_info mdid; -#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) - bool single_pmk_supported; -#endif } tPmkidCacheInfo; #ifdef FEATURE_WLAN_WAPI @@ -773,7 +713,8 @@ struct csr_roam_profile { tAniEdType mgmt_encryption_type; tCsrKeys Keys; tCsrChannelInfo ChannelInfo; - uint8_t operationChannel; + uint32_t op_freq; + uint32_t freq_hint; struct ch_params ch_params; /* If this is 0, SME will fill in for caller. */ uint16_t beaconInterval; @@ -827,9 +768,9 @@ struct csr_roam_profile { uint16_t beacon_tx_rate; tSirMacRateSet supported_rates; tSirMacRateSet extended_rates; + bool require_h2e; struct qdf_mac_addr bssid_hint; bool force_24ghz_in_ht20; - bool require_h2e; uint32_t cac_duration_ms; uint32_t dfs_regdomain; #ifdef WLAN_FEATURE_FILS_SK @@ -857,7 +798,7 @@ typedef struct tagCsrRoamConnectedProfile { tSirMacSSid SSID; bool handoffPermitted; bool ssidHidden; - uint8_t operationChannel; + uint32_t op_freq; struct qdf_mac_addr bssid; uint16_t beaconInterval; eCsrRoamBssType BSSType; @@ -970,8 +911,8 @@ struct csr_config_params { eCsrRoamWmmUserModeType WMMSupportMode; bool Is11eSupportEnabled; bool ProprietaryRatesEnabled; - uint8_t AdHocChannel24; - uint8_t AdHocChannel5G; + uint32_t ad_hoc_ch_freq_5g; + uint32_t ad_hoc_ch_freq_2g; /* * this number minus one is the number of times a scan doesn't find it * before it is removed @@ -1035,6 +976,9 @@ struct csr_config_params { uint32_t roam_dense_min_aps; int8_t roam_bg_scan_bad_rssi_thresh; uint8_t roam_bad_rssi_thresh_offset_2g; + uint32_t roam_data_rssi_threshold_triggers; + int32_t roam_data_rssi_threshold; + uint32_t rx_data_inactivity_time; struct csr_sta_roam_policy_params sta_roam_policy_params; bool enable_bcast_probe_rsp; bool is_fils_enabled; @@ -1112,16 +1056,12 @@ struct csr_roam_info { uint16_t tsmRoamDelay; struct ese_bcn_report_rsp *pEseBcnReportRsp; #endif - void *pRemainCtx; - uint32_t roc_scan_id; - uint32_t rxChan; #ifdef FEATURE_WLAN_TDLS /* * TDLS parameters to check whether TDLS * and TDLS channel switch is allowed in the * AP network */ - uint8_t staType; bool tdls_prohibited; /* per ExtCap in Assoc/Reassoc resp */ bool tdls_chan_swit_prohibited; /* per ExtCap in Assoc/Reassoc resp */ #endif @@ -1151,7 +1091,7 @@ struct csr_roam_info { uint8_t subnet_change_status; #endif struct oem_channel_info chan_info; - uint8_t target_channel; + uint32_t target_chan_freq; #ifdef WLAN_FEATURE_NAN union { @@ -1165,6 +1105,9 @@ struct csr_roam_info { tDot11fIEhs20vendor_ie hs20vendor_ie; tDot11fIEVHTOperation vht_operation; tDot11fIEHTInfo ht_operation; +#ifdef WLAN_FEATURE_11AX + tDot11fIEhe_op he_operation; +#endif bool reassoc; bool ampdu; bool sgi_enable; @@ -1189,6 +1132,7 @@ struct csr_roam_info { int rx_rate; tSirMacCapabilityInfo capability_info; uint32_t rx_mc_bc_cnt; + uint32_t rx_retry_cnt; #ifdef WLAN_FEATURE_SAE struct sir_sae_info *sae_info; #endif @@ -1326,14 +1270,14 @@ typedef enum { typedef struct tagCsrHandoffRequest { struct qdf_mac_addr bssid; - uint8_t channel; + uint32_t ch_freq; uint8_t src; /* To check if its a REASSOC or a FASTREASSOC IOCTL */ } tCsrHandoffRequest; #ifdef FEATURE_WLAN_ESE typedef struct tagCsrEseBeaconReqParams { uint16_t measurementToken; - uint8_t channel; + uint32_t ch_freq; uint8_t scanMode; uint16_t measurementDuration; } tCsrEseBeaconReqParams, *tpCsrEseBeaconReqParams; @@ -1363,7 +1307,8 @@ struct wep_update_default_key_idx { uint8_t default_idx; }; -typedef QDF_STATUS (*csr_roam_complete_cb)(void *context, +typedef QDF_STATUS (*csr_roam_complete_cb)(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, struct csr_roam_info *param, uint32_t roam_id, eRoamCmdStatus roam_status, @@ -1439,9 +1384,6 @@ typedef QDF_STATUS (*csr_session_close_cb)(uint8_t session_id); #define CSR_IS_FW_FT_FILS_SUPPORTED(fw_akm_bitmap) \ (((fw_akm_bitmap) & (1 << AKM_FT_FILS)) ? true : false) -#define CSR_IS_FW_SUITEB_ROAM_SUPPORTED(fw_akm_bitmap) \ - (((fw_akm_bitmap) & (1 << AKM_SUITEB)) ? true : false) - QDF_STATUS csr_set_channels(struct mac_context *mac, struct csr_config_params *pParam); @@ -1449,14 +1391,12 @@ QDF_STATUS csr_set_channels(struct mac_context *mac, const char *get_e_roam_cmd_status_str(eRoamCmdStatus val); const char *get_e_csr_roam_result_str(eCsrRoamResult val); const char *csr_phy_mode_str(eCsrPhyMode phy_mode); -typedef void (*tCsrStatsCallback)(void *stats, void *pContext); -typedef void (*tCsrRssiCallback)(int8_t rssi, uint32_t staId, void *pContext); #ifdef FEATURE_WLAN_ESE typedef void (*tCsrTsmStatsCallback)(tAniTrafStrmMetrics tsmMetrics, - uint32_t staId, void *pContext); + void *pContext); #endif /* FEATURE_WLAN_ESE */ -typedef void (*tCsrSnrCallback)(int8_t snr, uint32_t staId, void *pContext); +typedef void (*tCsrSnrCallback)(int8_t snr, void *pContext); /** * csr_roam_issue_ft_preauth_req() - Initiate Preauthentication request @@ -1490,10 +1430,6 @@ QDF_STATUS csr_continue_lfr2_connect(struct mac_context *mac, } #endif -#ifdef FEATURE_MONITOR_MODE_SUPPORT -typedef void (*csr_session_monitor_mode_cb)(uint8_t vdev_id); -#endif - typedef void (*csr_readyToSuspendCallback)(void *pContext, bool suspended); #ifdef WLAN_FEATURE_EXTWOW_SUPPORT typedef void (*csr_readyToExtWoWCallback)(void *pContext, bool status); @@ -1515,6 +1451,8 @@ typedef void (*sme_get_raom_scan_ch_callback)( struct roam_scan_ch_resp *roam_ch, void *context); +#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ + defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) /** * csr_packetdump_timer_stop() - stops packet dump timer * @@ -1525,15 +1463,29 @@ typedef void (*sme_get_raom_scan_ch_callback)( */ void csr_packetdump_timer_stop(void); +/** + * csr_packetdump_timer_start() - start packet dump timer + * + * This function is used to start packet dump timer + * + * Return: None + * + */ +void csr_packetdump_timer_start(void); +#else +static inline void csr_packetdump_timer_stop(void) {} +static inline void csr_packetdump_timer_start(void) {} +#endif + /** * csr_get_channel_status() - get chan info via channel number * @mac: Pointer to Global MAC structure - * @channel_id: channel id + * @chan_freq: channel frequency * * Return: chan status info */ struct lim_channel_status * -csr_get_channel_status(struct mac_context *mac, uint32_t channel_id); +csr_get_channel_status(struct mac_context *mac, uint32_t chan_freq); /** * csr_clear_channel_status() - clear chan info @@ -1565,6 +1517,8 @@ QDF_STATUS csr_send_roam_offload_init_msg(struct mac_context *mac, uint32_t vdev_id, bool enable); +typedef void (*csr_ani_callback)(int8_t *ani, void *context); + #ifdef WLAN_FEATURE_11W /** * csr_update_pmf_cap_from_connected_profile() - Update pmf cap from profile @@ -1577,9 +1531,8 @@ void csr_update_pmf_cap_from_connected_profile(tCsrRoamConnectedProfile *profile, struct scan_filter *filter); #else -static inline void +void csr_update_pmf_cap_from_connected_profile(tCsrRoamConnectedProfile *profile, - struct scan_filter *filter) -{} + struct scan_filter *filter); #endif #endif diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_host_scan_roam.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_host_scan_roam.h new file mode 100644 index 0000000000000000000000000000000000000000..292c93d74b547584d7ea4ba0a0c494d7ab9a6cf9 --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_host_scan_roam.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * + * 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. + */ + +#ifndef CSR_HOST_SCAN_ROAM_H +#define CSR_HOST_SCAN_ROAM_H + +#ifdef WLAN_FEATURE_HOST_ROAM +/** + * csr_roam_issue_reassociate() - Issue Reassociate + * @mac: Global MAC Context + * @vdev_id: SME vdev ID + * @bss_desc: BSS Descriptor + * @ies: Pointer to the IE's + * @roam_profile: Roaming profile + * + * Return: Success or Failure + */ +QDF_STATUS +csr_roam_issue_reassociate(struct mac_context *mac, uint32_t vdev_id, + struct bss_description *bss_desc, + tDot11fBeaconIEs *bcn_ies, + struct csr_roam_profile *roam_profile); + +/** + * csr_roam_issue_reassociate_cmd() - Issue the reassociate command + * @mac: Global MAC Context + * @vdev_id: SME vdev ID + * + * Return: Success or Failure status + */ +QDF_STATUS +csr_roam_issue_reassociate_cmd(struct mac_context *mac, uint32_t vdev_id); + +/** + * csr_neighbor_roam_process_scan_results() - build roaming candidate list + * + * @mac_ctx: The handle returned by mac_open. + * @sessionid: Session information + * @scan_results_list: List obtained from csr_scan_get_result() + * + * This function applies various candidate checks like LFR, 11r, preauth, ESE + * and builds a roamable AP list. It applies age limit only if no suitable + * recent candidates are found. + * + * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid]. + * + * Return: void + */ +void +csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, + uint8_t vdev_id, + tScanResultHandle *scan_results_list); +/** + * csr_neighbor_roam_trigger_handoff() - Start roaming + * @mac_ctx: Global MAC Context + * @vdev_id: SME vdev ID + * + * Return: None + */ +void csr_neighbor_roam_trigger_handoff(struct mac_context *mac_ctx, + uint8_t vdev_id); +/** + * csr_neighbor_roam_process_scan_complete() - Post process the scan results + * @mac: Global MAC Context + * @vdev_id: SME vdev ID + * + * Return: Success or Failure + */ +QDF_STATUS csr_neighbor_roam_process_scan_complete(struct mac_context *mac, + uint8_t vdev_id); + +/** + * csr_neighbor_roam_candidate_found_ind_hdlr() - Handle roam candidate found + * indication from firmware + * @mac_ctx: Pointer to Global MAC structure + * @msg_buf: pointer to msg buff + * + * This function is called by CSR as soon as TL posts the candidate + * found indication to SME via MC thread + * + * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise + */ +QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(struct mac_context *mac, + void *msg_buf); + +/** + * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list + * @mac_ctx: The handle returned by mac_open. + * @llist: Neighbor Roam BSS List to be emptied + * + * Empties and frees all the nodes in the roamable AP list + * + * Return: none + */ +void csr_neighbor_roam_free_roamable_bss_list(struct mac_context *mac_ctx, + tDblLinkList *llist); + +/** + * csr_neighbor_roam_remove_roamable_ap_list_entry() - Remove roamable + * candidate APs from list + * @mac_ctx: Pointer to Global MAC structure + * @list: The list from which the entry should be removed + * @neigh_entry: Neighbor Roam BSS Node to be removed + * + * This function removes a given entry from the given list + * + * Return: true if successfully removed, else false + */ +bool csr_neighbor_roam_remove_roamable_ap_list_entry(struct mac_context *mac, + tDblLinkList *list, tpCsrNeighborRoamBSSInfo neigh_entry); + +/** + * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list + * @mac_ctx - The handle returned by mac_open. + * @plist - The list from which the entry should be returned + * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned + * + * Gets the entry next to passed entry. If NULL is passed, return the entry + * in the head of the list + * + * Return: Neighbor Roam BSS Node to be returned + */ +tpCsrNeighborRoamBSSInfo +csr_neighbor_roam_next_roamable_ap(struct mac_context *mac_ctx, + tDblLinkList *llist, + tpCsrNeighborRoamBSSInfo neighbor_entry); + +/** + * csr_neighbor_roam_request_handoff() - Handoff to a different AP + * @mac_ctx: Pointer to Global MAC structure + * @vdev_id: vdev id + * + * This function triggers actual switching from one AP to the new AP. + * It issues disassociate with reason code as Handoff and CSR as a part of + * handling disassoc rsp, issues reassociate to the new AP + * + * Return: none + */ +void +csr_neighbor_roam_request_handoff(struct mac_context *mac, uint8_t vdev_id); + +/** + * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming + * @mac: mac context + * @session_id: vdev Id + * @hand_off_node: AP node that is the handoff candidate returned + * + * This function returns the best possible AP for handoff. For 11R case, it + * returns the 1st entry from pre-auth done list. For non-11r case, it returns + * the 1st entry from roamable AP list + * + * Return: true if able find handoff AP, false otherwise + */ +bool +csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, + tpCsrNeighborRoamBSSInfo hand_off_node, + uint8_t vdev_id); + +/** + * csr_neighbor_roam_is_handoff_in_progress() - Check whether roam handoff is + * in progress + * @mac_ctx: Pointer to Global MAC structure + * @vdev_id: vdev id + * + * This function returns whether handoff is in progress or not based on + * the current neighbor roam state + * + * Return: true if reassoc in progress, false otherwise + */ +bool csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, + uint8_t vdev_id); + +/** + * csr_neighbor_roam_free_neighbor_roam_bss_node() - Free Roam BSS node + * @mac_ctx: Pointer to Global MAC structure + * @roam_bss_node: Neighbor Roam BSS Node to be freed + * + * This function frees all the internal pointers CSR NeighborRoam BSS Info + * and also frees the node itself + * + * Return: None + */ +void +csr_neighbor_roam_free_neighbor_roam_bss_node(struct mac_context *mac, + tpCsrNeighborRoamBSSInfo roam_bss_node); + +#else +static inline QDF_STATUS +csr_roam_issue_reassociate(struct mac_context *mac, uint32_t vdev_id, + struct bss_description *bss_desc, + tDot11fBeaconIEs *bcn_ies, + struct csr_roam_profile *roam_profile) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline void +csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, + uint8_t vdev_id, + tScanResultHandle *scan_results_list) +{} + +static inline void +csr_neighbor_roam_trigger_handoff(struct mac_context *mac_ctx, uint8_t vdev_id) +{} + +static inline void +csr_neighbor_roam_request_handoff(struct mac_context *mac, uint8_t vdev_id) +{} + +static inline bool +csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, + tpCsrNeighborRoamBSSInfo pHandoffNode, + uint8_t vdev_id) +{ + return false; +} + +static inline void +csr_neighbor_roam_free_roamable_bss_list(struct mac_context *mac_ctx, + tDblLinkList *llist) +{} + +static inline QDF_STATUS +csr_neighbor_roam_process_scan_complete(struct mac_context *mac, + uint8_t vdev_id) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +csr_roam_issue_reassociate_cmd(struct mac_context *mac, uint32_t vdev_id) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline bool +csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, + uint8_t vdev_id) +{ + return false; +} + +static inline QDF_STATUS +csr_neighbor_roam_candidate_found_ind_hdlr(struct mac_context *mac, + void *msg_buf) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif /* WLAN_FEATURE_HOST_ROAM */ +#endif /* CSR_HOST_SCAN_ROAM_H */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h index 7a2d68ff30d5bf585d8b1510055441c5a5d5741a..92615cdfacfd7cd65a382d47fbf5276e18f7af7a 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h @@ -35,6 +35,7 @@ #include "sir_types.h" #include "wlan_mlme_public_struct.h" +#include "csr_host_scan_roam.h" #define CSR_NUM_RSSI_CAT 15 #define CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME 3 @@ -179,14 +180,6 @@ enum csr_roam_wmstatus_changetypes { eCsrDeauthenticated }; -enum csr_roam_stats_classtypes { - eCsrSummaryStats = 0, - eCsrGlobalClassAStats, - eCsrGlobalClassDStats, - csr_per_chain_rssi_stats, - eCsrMaxStats -}; - enum csr_diagwlan_status_eventsubtype { eCSR_WLAN_STATUS_CONNECT = 0, eCSR_WLAN_STATUS_DISCONNECT @@ -206,14 +199,14 @@ enum csr_diagwlan_status_eventreason { struct csr_channel { uint8_t numChannels; - uint8_t channelList[CFG_VALID_CHANNEL_LIST_LEN]; + uint32_t channel_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; }; struct bss_config_param { eCsrMediaAccessType qosType; tSirMacSSid SSID; enum csr_cfgdot11mode uCfgDot11Mode; - enum band_info band; + enum reg_wifi_band band; tAniAuthType authType; eCsrEncryptionType encType; uint32_t uShortSlotTime; @@ -238,7 +231,7 @@ struct csr_roamstart_bssparams { ePhyChanBondState cbMode; tSirMacRateSet operationalRateSet; tSirMacRateSet extendedRateSet; - uint8_t operationChn; + uint32_t operation_chan_freq; struct ch_params ch_params; enum csr_cfgdot11mode uCfgDot11Mode; uint8_t privacy; @@ -353,8 +346,8 @@ struct csr_config { bool mcc_rts_cts_prot_enable; bool mcc_bcast_prob_resp_enable; uint8_t fAllowMCCGODiffBI; - uint8_t AdHocChannel24; - uint8_t AdHocChannel5G; + uint32_t ad_hoc_ch_freq_2g; + uint32_t ad_hoc_ch_freq_5g; /* each RSSI category has one value */ uint32_t BssPreferValue[CSR_NUM_RSSI_CAT]; int RSSICat[CSR_NUM_RSSI_CAT]; @@ -403,7 +396,7 @@ struct csr_config { struct csr_channel_powerinfo { tListElem link; - uint8_t firstChannel; + uint32_t first_chan_freq; uint8_t numChannels; uint8_t txPower; uint8_t interChannelOffset; @@ -479,36 +472,6 @@ struct csr_roam_connectedinfo { uint8_t staId; }; -#ifndef QCA_SUPPORT_CP_STATS -struct csr_pestats_reqinfo { - tListElem link; /* list links */ - uint32_t statsMask; - bool rspPending; - uint8_t staId; - uint8_t numClient; - struct mac_context *mac; - uint8_t sessionId; -}; - -struct csr_statsclient_reqinfo { - tListElem link; /* list links */ - eCsrStatsRequesterType requesterId; - tCsrStatsCallback callback; - void *pContext; - uint32_t statsMask; - struct csr_pestats_reqinfo *pPeStaEntry; - uint8_t staId; - qdf_mc_timer_t timer; - bool timerExpired; - struct mac_context *mac; /* TODO: Confirm this change BTAMP */ - uint8_t sessionId; -}; - -struct csr_tlstats_reqinfo { - uint8_t numClient; -}; -#endif /* QCA_SUPPORT_CP_STATS */ - #ifdef WLAN_FEATURE_ROAM_OFFLOAD enum csr_roamoffload_authstatus { /* reassociation is done but couldn't finish security handshake */ @@ -580,12 +543,7 @@ struct csr_roam_session { /* For BT-AMP station, this serve as BSSID for self-BSS. */ struct qdf_mac_addr self_mac_addr; - csr_session_open_cb session_open_cb; - csr_session_close_cb session_close_cb; - csr_roam_complete_cb callback; - void *pContext; eCsrConnectState connectState; - struct rsn_caps rsn_caps; tCsrRoamConnectedProfile connectedProfile; struct csr_roam_connectedinfo connectedInfo; struct csr_roam_connectedinfo prev_assoc_ap_info; @@ -595,11 +553,6 @@ struct csr_roam_session { uint16_t curr_cache_idx; /* the index in pmkidcache to write next to */ tPmkidCacheInfo PmkidCacheInfo[CSR_MAX_PMKID_ALLOWED]; uint8_t cJoinAttemps; - /* - * This may or may not have the up-to-date valid channel list. It is - * used to get CFG_VALID_CHANNEL_LIST and not alloc memory all time - */ - tSirMacChanNum validChannelList[CFG_VALID_CHANNEL_LIST_LEN]; int32_t sPendingCommands; /* 0 means CSR is ok to low power */ #ifdef FEATURE_WLAN_WAPI uint16_t NumBkidCache; @@ -661,7 +614,6 @@ struct csr_roam_session { bool isPrevApInfoValid; tSirMacSSid prevApSSID; struct qdf_mac_addr prevApBssid; - uint8_t prevOpChannel; uint16_t clientDissSecs; uint32_t roamTS1; tCsrEseCckmIe suppCckmIeInfo; @@ -701,9 +653,7 @@ struct csr_roam_session { bool discon_in_progress; bool is_adaptive_11r_connection; struct csr_disconnect_stats disconnect_stats; -#ifdef FEATURE_MONITOR_MODE_SUPPORT - csr_session_monitor_mode_cb session_monitor_mode_cb; -#endif + qdf_mc_timer_t join_retry_timer; }; struct csr_roamstruct { @@ -715,19 +665,10 @@ struct csr_roamstruct { * This may or may not have the up-to-date valid channel list. It is * used to get CFG_VALID_CHANNEL_LIST and not alloc mem all time */ - tSirMacChanNum validChannelList[CFG_VALID_CHANNEL_LIST_LEN]; + uint32_t valid_ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; uint32_t numValidChannels; /* total number of channels in CFG */ int32_t sPendingCommands; qdf_mc_timer_t hTimerWaitForKey; /* support timeout for WaitForKey */ -#ifndef QCA_SUPPORT_CP_STATS - tCsrSummaryStatsInfo summaryStatsInfo; - tCsrGlobalClassAStatsInfo classAStatsInfo; - tCsrGlobalClassDStatsInfo classDStatsInfo; - struct csr_per_chain_rssi_stats_info per_chain_rssi_stats; - tDblLinkList statsClientReqList; - tDblLinkList peStatsReqList; - struct csr_tlstats_reqinfo tlStatsReqInfo; -#endif struct csr_timer_info WaitForKeyTimerInfo; struct csr_roam_session *roamSession; tCsrNeighborRoamControlInfo neighborRoamInfo[WLAN_MAX_VDEVS]; @@ -740,7 +681,10 @@ struct csr_roamstruct { uint32_t deauthRspStatus; uint8_t *pReassocResp; /* reassociation response from new AP */ uint16_t reassocRespLen; /* length of reassociation response */ +#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ + defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) qdf_mc_timer_t packetdump_timer; +#endif spinlock_t roam_state_lock; }; @@ -836,21 +780,45 @@ struct csr_roamstruct { ((eCSR_DOT11_MODE_11ac == phy_mode) || \ (eCSR_DOT11_MODE_11ac_ONLY == phy_mode)) +#define CSR_IS_DOT11_MODE_11N(dot11mode) \ + ((dot11mode == eCSR_CFG_DOT11_MODE_AUTO) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11N) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AC) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11N_ONLY) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) + +#define CSR_IS_DOT11_MODE_11AC(dot11mode) \ + ((dot11mode == eCSR_CFG_DOT11_MODE_AUTO) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AC) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) + +#define CSR_IS_DOT11_MODE_11AX(dot11mode) \ + ((dot11mode == eCSR_CFG_DOT11_MODE_AUTO) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX) || \ + (dot11mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) +/* Get number of bits from the index bit */ +#define CSR_GET_BITS(_val, _index, _num_bits) \ + (((_val) >> (_index)) & ((1 << (_num_bits)) - 1)) /* * this function returns true if the NIC is operating exclusively in * the 2.4 GHz band, meaning. it is NOT operating in the 5.0 GHz band. */ #define CSR_IS_24_BAND_ONLY(mac) \ - (BAND_2G == (mac)->mlme_cfg->gen.band) + (BIT(REG_BAND_2G) == (mac)->mlme_cfg->gen.band) #define CSR_IS_5G_BAND_ONLY(mac) \ - (BAND_5G == (mac)->mlme_cfg->gen.band) + (BIT(REG_BAND_5G) == (mac)->mlme_cfg->gen.band) #define CSR_IS_RADIO_DUAL_BAND(mac) \ - (BAND_ALL == (mac)->mlme_cfg->gen.band_capability) + ((BIT(REG_BAND_2G) | BIT(REG_BAND_5G)) == \ + (mac)->mlme_cfg->gen.band_capability) #define CSR_IS_RADIO_BG_ONLY(mac) \ - (BAND_2G == (mac)->mlme_cfg->gen.band_capability) + (BIT(REG_BAND_2G) == (mac)->mlme_cfg->gen.band_capability) /* * this function returns true if the NIC is operating exclusively in the 5.0 GHz @@ -877,8 +845,7 @@ struct csr_roamstruct { #define CSR_IS_OPERATING_BG_BAND(mac) \ (CSR_IS_OPEARTING_DUAL_BAND((mac)) || \ CSR_IS_RADIO_BG_ONLY((mac)) || CSR_IS_24_BAND_ONLY((mac))) -#define CSR_GET_BAND(ch_num) \ - ((WLAN_REG_IS_24GHZ_CH(ch_num)) ? BAND_2G : BAND_5G) + #define CSR_IS_ROAMING(pSession) \ ((CSR_IS_LOSTLINK_ROAMING((pSession)->roamingReason)) || \ (eCsrDynamicRoaming == (pSession)->roamingReason) || \ @@ -896,6 +863,22 @@ struct csr_roamstruct { #define CSR_GET_SUBNET_STATUS(roam_reason) (0) #endif +/** + * csr_get_vdev_dot11_mode() - get the supported dot11mode by vdev + * @mac_ctx: pointer to global mac structure + * @device_mode: vdev mode + * @curr_dot11_mode: Current dot11 mode + * + * The function return the min of supported dot11 mode and vdev type dot11mode + * for given vdev type. + * + * Return:csr_cfgdot11mode + */ +enum csr_cfgdot11mode +csr_get_vdev_dot11_mode(struct mac_context *mac, + enum QDF_OPMODE device_mode, + enum csr_cfgdot11mode curr_dot11_mode); + QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac); QDF_STATUS csr_scan_filter_results(struct mac_context *mac); @@ -910,17 +893,66 @@ void csr_set_global_cfgs(struct mac_context *mac); void csr_set_default_dot11_mode(struct mac_context *mac); bool csr_is_conn_state_disconnected(struct mac_context *mac, uint32_t sessionId); -bool csr_is_conn_state_connected_ibss(struct mac_context *mac, - uint32_t sessionId); -bool csr_is_conn_state_disconnected_ibss(struct mac_context *mac, - uint32_t sessionId); bool csr_is_conn_state_connected_infra(struct mac_context *mac, uint32_t sessionId); bool csr_is_conn_state_connected(struct mac_context *mac, uint32_t sessionId); bool csr_is_conn_state_infra(struct mac_context *mac, uint32_t sessionId); + +#ifdef QCA_IBSS_SUPPORT +/** + * csr_is_conn_state_ibss() - get the connection state for ibss session + * @mac_ctx: pointer to global mac structure + * @sessionId: session id + * + * + * Return: true if IBSS connected/disconnected state, else flase + */ bool csr_is_conn_state_ibss(struct mac_context *mac, uint32_t sessionId); + +/** + * csr_is_conn_state_connected_ibss() - get the connected state for ibss + * @mac_ctx: pointer to global mac structure + * @sessionId: session id + * + * + * Return: true if IBSS connected state, else false + */ +bool csr_is_conn_state_connected_ibss(struct mac_context *mac, + uint32_t sessionId); + +/** + * csr_is_conn_state_connected_ibss() - get the connected state for ibss + * @mac_ctx: pointer to global mac structure + * @sessionId: session id + * + * + * Return: true if IBSS disconnected state, else false + */ +bool csr_is_conn_state_disconnected_ibss(struct mac_context *mac, + uint32_t sessionId); +#else +static inline bool +csr_is_conn_state_ibss(struct mac_context *mac, uint32_t sessionId) +{ + return false; +} + +static inline bool +csr_is_conn_state_connected_ibss(struct mac_context *mac, uint32_t sessionId) +{ + return false; +} + +static inline bool +csr_is_conn_state_disconnected_ibss(struct mac_context *mac, + uint32_t sessionId) +{ + return false; +} +#endif + bool csr_is_conn_state_wds(struct mac_context *mac, uint32_t sessionId); bool csr_is_conn_state_connected_wds(struct mac_context *mac, uint32_t sessionId); @@ -947,15 +979,8 @@ bool csr_is_valid_mc_concurrent_session(struct mac_context *mac, struct bss_description *bss_desc); bool csr_is_conn_state_connected_infra_ap(struct mac_context *mac, uint32_t sessionId); -QDF_STATUS csr_get_statistics(struct mac_context *mac, - eCsrStatsRequesterType requesterId, - uint32_t statsMask, tCsrStatsCallback callback, - uint8_t staId, void *pContext, uint8_t sessionId); -QDF_STATUS csr_get_rssi(struct mac_context *mac, tCsrRssiCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI, - void *pContext); QDF_STATUS csr_get_snr(struct mac_context *mac, tCsrSnrCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext); + struct qdf_mac_addr bssId, void *pContext); QDF_STATUS csr_get_config_param(struct mac_context *mac, struct csr_config_params *pParam); QDF_STATUS csr_change_default_config_param(struct mac_context *mac, @@ -978,25 +1003,35 @@ uint8_t csr_construct_wapi_ie(struct mac_context *mac, uint32_t sessionId, void csr_set_cfg_privacy(struct mac_context *mac, struct csr_roam_profile *pProfile, bool fPrivacy); -uint8_t csr_get_infra_operation_channel(struct mac_context *mac, - uint8_t sessionId); + +/** + * csr_get_infra_operation_chan_freq() - get operating chan freq of + * given vdev id + * @mac_ctx: Pointer to mac context + * @vdev_id: vdev id + * + * Return: chan freq of given vdev id + */ +uint32_t csr_get_infra_operation_chan_freq( + struct mac_context *mac, uint8_t vdev_id); + bool csr_is_session_client_and_connected(struct mac_context *mac, uint8_t sessionId); /** - * csr_get_concurrent_operation_channel() - To get concurrent operating channel + * csr_get_concurrent_operation_freq() - To get concurrent operating freq * @mac_ctx: Pointer to mac context * - * This routine will return operating channel on FIRST BSS that is + * This routine will return operating freq on FIRST BSS that is * active/operating to be used for concurrency mode. * If other BSS is not up or not connected it will return 0 * - * Return: uint8_t + * Return: uint32_t */ -uint8_t csr_get_concurrent_operation_channel(struct mac_context *mac_ctx); +uint32_t csr_get_concurrent_operation_freq(struct mac_context *mac_ctx); /** * csr_get_beaconing_concurrent_channel() - To get concurrent operating channel - * of beaconing interface + * frequency of beaconing interface * @mac_ctx: Pointer to mac context * @vdev_id_to_skip: channel of which vdev id to skip * @@ -1004,15 +1039,15 @@ uint8_t csr_get_concurrent_operation_channel(struct mac_context *mac_ctx); * and will skip the channel of vdev_id_to_skip. * If other no reqested mode is active it will return 0 * - * Return: uint8_t + * Return: uint32_t */ -uint8_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, - uint8_t vdev_id_to_skip); +uint32_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, + uint8_t vdev_id_to_skip); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH uint16_t csr_check_concurrent_channel_overlap( struct mac_context *mac, - uint16_t sap_ch, eCsrPhyMode sap_phymode, + uint32_t sap_ch_freq, eCsrPhyMode sap_phymode, uint8_t cc_switch_mode); #endif QDF_STATUS csr_roam_copy_connect_profile(struct mac_context *mac, @@ -1028,7 +1063,6 @@ bool csr_roam_is_ese_assoc(struct mac_context *mac, uint32_t sessionId); bool csr_roam_is_ese_ini_feature_enabled(struct mac_context *mac); QDF_STATUS csr_get_tsm_stats(struct mac_context *mac, tCsrTsmStatsCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext, uint8_t tid); #endif @@ -1038,12 +1072,10 @@ bool csr_roam_is_fast_roam_enabled(struct mac_context *mac, uint32_t sessionId); bool csr_roam_is_roam_offload_scan_enabled( struct mac_context *mac); -bool csr_is_channel_present_in_list(uint8_t *pChannelList, - int numChannels, - uint8_t channel); -QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList, - int numChannels, - uint8_t channel); +bool csr_is_channel_present_in_list(uint32_t *pChannelList, + int numChannels, uint32_t chan_freq); +QDF_STATUS csr_add_to_channel_list_front(uint32_t *pChannelList, + int numChannels, uint32_t chan_freq); #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) QDF_STATUS csr_roam_offload_scan_rsp_hdlr(struct mac_context *mac, struct roam_offload_scan_rsp *scanOffloadRsp); @@ -1072,7 +1104,7 @@ QDF_STATUS csr_roam_start_beacon_req(struct mac_context *mac, QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac, struct qdf_mac_addr bssid, - uint8_t targetChannel, + uint32_t target_chan_freq, uint8_t csaIeReqd, struct ch_params *ch_params); QDF_STATUS csr_roam_modify_add_ies(struct mac_context *mac, @@ -1098,6 +1130,15 @@ csr_rso_save_ap_to_scan_cache(struct mac_context *mac, struct roam_offload_synch_ind *roam_synch_ind, struct bss_description *bss_desc_ptr); +/** + * csr_process_ho_fail_ind - This function will process the Hand Off Failure + * indication received from the firmware. It will trigger a disconnect on + * the session which the firmware reported a hand off failure. + * @mac: Pointer to global Mac + * @msg_buf: Pointer to wma Ho fail indication message + * + * Return: None + */ void csr_process_ho_fail_ind(struct mac_context *mac, void *msg_buf); #endif #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR @@ -1114,12 +1155,6 @@ static inline void csr_roaming_report_diag_event( QDF_STATUS csr_get_channels_and_power(struct mac_context *mac); -bool csr_nonscan_active_ll_is_list_empty( - struct mac_context *mac_ctx, - bool inter_locked); -bool csr_nonscan_pending_ll_is_list_empty( - struct mac_context *mac_ctx, - bool inter_locked); bool csr_nonscan_active_ll_remove_entry( struct mac_context *mac_ctx, tListElem *pEntryToRemove, bool inter_locked); @@ -1129,16 +1164,6 @@ tListElem *csr_nonscan_active_ll_peek_head( tListElem *csr_nonscan_pending_ll_peek_head( struct mac_context *mac_ctx, bool inter_locked); -tListElem *csr_nonscan_active_ll_remove_head( - struct mac_context *mac_ctx, - bool inter_locked); -tListElem *csr_nonscan_pending_ll_remove_head( - struct mac_context *mac_ctx, - bool inter_locked); -uint32_t csr_nonscan_pending_ll_count( - struct mac_context *mac_ctx); -uint32_t csr_nonscan_active_ll_count( - struct mac_context *mac_ctx); tListElem *csr_nonscan_pending_ll_next( struct mac_context *mac_ctx, tListElem *entry, bool inter_locked); @@ -1182,12 +1207,6 @@ void csr_roam_substate_change( struct mac_context *mac, enum csr_roam_substate NewSubstate, uint32_t sessionId); -void csr_neighbor_roam_process_scan_results( - struct mac_context *mac_ctx, - uint8_t sessionid, tScanResultHandle *scan_results_list); - -void csr_neighbor_roam_trigger_handoff(struct mac_context *mac_ctx, - uint8_t session_id); bool csr_is_ndi_started(struct mac_context *mac_ctx, uint32_t session_id); QDF_STATUS csr_roam_update_config( @@ -1197,9 +1216,9 @@ QDF_STATUS csr_roam_update_config( /** * csr_is_mcc_channel() - check if using the channel results into MCC * @mac_ctx: pointer to global MAC context - * @channel : channel number to check for MCC scenario + * @chan_freq: channel frequency to check for MCC scenario * * Return : true if channel causes MCC, else false */ -bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint8_t channel); +bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint32_t chan_freq); #endif diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_neighbor_roam.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_neighbor_roam.h index 08e417f8ab20a705789a76bebfc4a49b6967f50e..922045cd6ad477c6156b9b66f5632ca04d0ba38e 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_neighbor_roam.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_neighbor_roam.h @@ -101,12 +101,6 @@ typedef struct sCsrPreauthFailListInfo { tSirMacAddr macAddress[MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS]; } tCsrPreauthFailListInfo, *tpCsrPreauthFailListInfo; -typedef struct sCsrNeighborReportBssInfo { - uint8_t channelNum; - uint8_t neighborScore; - tSirMacAddr neighborBssId; -} tCsrNeighborReportBssInfo, *tpCsrNeighborReportBssInfo; - typedef struct sCsr11rAssocNeighborInfo { bool preauthRspPending; bool neighborRptPending; @@ -131,7 +125,7 @@ typedef struct sCsrNeighborRoamControlInfo { eCsrNeighborRoamState prevNeighborRoamState; tCsrNeighborRoamCfgParams cfgParams; struct qdf_mac_addr currAPbssid; /* current assoc AP */ - uint8_t currAPoperationChannel; /* current assoc AP */ + uint32_t curr_ap_op_chan_freq; /* current assoc AP */ tCsrNeighborRoamChannelInfo roamChannelInfo; uint8_t currentNeighborLookupThreshold; uint8_t currentOpportunisticThresholdDiff; @@ -170,8 +164,6 @@ QDF_STATUS csr_neighbor_roam_indicate_disconnect(struct mac_context *mac, uint8_t sessionId); QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId); void csr_neighbor_roam_close(struct mac_context *mac, uint8_t sessionId); -QDF_STATUS csr_neighbor_roam_prepare_scan_profile_filter(struct mac_context *mac, - tCsrScanResultFilter *pScanFilter, uint8_t sessionId); QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(struct mac_context *mac, uint8_t sessionId, QDF_STATUS limStatus); bool csr_neighbor_roam_is11r_assoc(struct mac_context *mac, uint8_t sessionId); @@ -180,22 +172,6 @@ void csr_neighbor_roam_tranistion_preauth_done_to_disconnected( struct mac_context *mac, uint8_t sessionId); bool csr_neighbor_roam_state_preauth_done(struct mac_context *mac, uint8_t sessionId); -QDF_STATUS csr_roam_issue_reassociate_cmd(struct mac_context *mac, - uint32_t sessionId); -void csr_neighbor_roam_free_roamable_bss_list(struct mac_context *mac_ctx, - tDblLinkList *llist); -bool csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, - tpCsrNeighborRoamBSSInfo pHandoffNode, uint8_t sessionId); -QDF_STATUS csr_roam_issue_reassociate(struct mac_context *mac, - uint32_t sessionId, struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile); -void csr_neighbor_roam_request_handoff(struct mac_context *mac, uint8_t sessionId); -QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(struct mac_context *mac, - void *pMsg); -QDF_STATUS csr_neighbor_roam_process_scan_complete(struct mac_context *mac, - uint8_t sessionId); -bool csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, - uint8_t sessionId); void csr_neighbor_roam_reset_preauth_control_info( struct mac_context *mac_ctx, uint8_t session_id); void csr_neighbor_roam_purge_preauth_failed_list(struct mac_context *mac); @@ -205,52 +181,15 @@ static inline bool csr_neighbor_roam_state_preauth_done(struct mac_context *mac, { return false; } -static inline QDF_STATUS csr_roam_issue_reassociate_cmd(struct mac_context *mac, - uint32_t sessionId) -{ - return QDF_STATUS_E_NOSUPPORT; -} -static inline QDF_STATUS csr_roam_issue_reassociate(struct mac_context *mac, - uint32_t sessionId, struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile) -{ - return QDF_STATUS_E_NOSUPPORT; -} -static inline QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr( - struct mac_context *mac, void *pMsg) -{ - return QDF_STATUS_E_NOSUPPORT; -} -static inline QDF_STATUS csr_neighbor_roam_process_scan_complete( - struct mac_context *mac, uint8_t sessionId) -{ - return QDF_STATUS_E_NOSUPPORT; -} static inline void csr_neighbor_roam_tranistion_preauth_done_to_disconnected( struct mac_context *mac, uint8_t sessionId) {} -static inline void csr_neighbor_roam_free_roamable_bss_list( - struct mac_context *mac_ctx, tDblLinkList *llist) -{} -static inline void csr_neighbor_roam_request_handoff(struct mac_context *mac, - uint8_t sessionId) -{} static inline void csr_neighbor_roam_reset_preauth_control_info( struct mac_context *mac_ctx, uint8_t session_id) {} static inline void csr_neighbor_roam_purge_preauth_failed_list( struct mac_context *mac) {} -static inline bool csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, - tpCsrNeighborRoamBSSInfo pHandoffNode, uint8_t sessionId) -{ - return false; -} -static inline bool csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, - uint8_t sessionId) -{ - return false; -} #endif bool csr_neighbor_middle_of_roaming(struct mac_context *mac, uint8_t sessionId); QDF_STATUS csr_neighbor_roam_update_config(struct mac_context *mac_ctx, @@ -259,14 +198,14 @@ QDF_STATUS csr_neighbor_roam_update_fast_roaming_enabled(struct mac_context *mac uint8_t sessionId, const bool fastRoamEnabled); QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band( struct mac_context *mac, uint8_t sessionId, - uint8_t *pInputChannelList, + uint32_t *input_chan_freq_list, uint8_t inputNumOfChannels, - uint8_t *pOutputChannelList, + uint32_t *out_chan_freq_list, uint8_t *pMergedOutputNumOfChannels); QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac, - uint8_t *pInputChannelList, + uint32_t *pinput_chan_freq_list, uint8_t inputNumOfChannels, - uint8_t *pOutputChannelList, + uint32_t *out_chan_freq_list, uint8_t outputNumOfChannels, uint8_t *pMergedOutputNumOfChannels); void csr_roam_reset_roam_params(struct mac_context *mac_ptr); @@ -476,7 +415,7 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx, * @mac_handle: handle returned by mac_open * @profile: current connected profile * @bssid: bssid to look for in scan cache - * @channel: channel on which reassoc should be send + * @ch_freq: channel on which reassoc should be send * @vdev_id: vdev id * @connected_bssid: bssid of currently connected profile * @@ -484,23 +423,9 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx, */ QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, + const tSirMacAddr bssid, uint32_t ch_freq, uint8_t vdev_id, const tSirMacAddr connected_bssid); -/** - * csr_process_roam_auth_offload_callback() - API to trigger the - * WPA3 pre-auth event for candidate AP received from firmware. - * @vdev_id: vdev id - * @roam_bssid: Candidate BSSID to roam - * - * This function calls the hdd_sme_roam_callback with reason - * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant. - */ -QDF_STATUS -csr_process_roam_auth_offload_callback(struct mac_context *mac_ctx, - uint8_t vdev_id, - struct qdf_mac_addr roam_bssid); - #ifdef WLAN_FEATURE_FIPS /** * csr_roam_pmkid_req_callback() - Registered CSR Callback function to handle @@ -543,15 +468,6 @@ static inline QDF_STATUS csr_roam_synch_callback(struct mac_context *mac, return QDF_STATUS_E_NOSUPPORT; } -static inline -QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, - struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, - uint8_t vdev_id, const tSirMacAddr connected_bssid) -{ - return QDF_STATUS_SUCCESS; -} - static inline QDF_STATUS csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id, @@ -560,12 +476,13 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx, return QDF_STATUS_E_NOSUPPORT; } -static inline QDF_STATUS -csr_process_roam_auth_offload_callback(struct mac_context *mac_ctx, - uint8_t vdev_id, - struct qdf_mac_addr roam_bssid) +static inline +QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, + struct csr_roam_profile *profile, + const tSirMacAddr bssid, uint32_t ch_freq, + uint8_t vdev_id, const tSirMacAddr connected_bssid) { - return QDF_STATUS_E_NOSUPPORT; + return QDF_STATUS_SUCCESS; } static inline QDF_STATUS @@ -578,13 +495,6 @@ csr_roam_pmkid_req_callback(uint8_t vdev_id, void csr_neighbor_roam_state_transition(struct mac_context *mac_ctx, uint8_t newstate, uint8_t session); uint8_t *csr_neighbor_roam_state_to_string(uint8_t state); -tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap( - struct mac_context *mac_ctx, tDblLinkList *llist, - tpCsrNeighborRoamBSSInfo neighbor_entry); -bool csr_neighbor_roam_remove_roamable_ap_list_entry(struct mac_context *mac, - tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry); -void csr_neighbor_roam_free_neighbor_roam_bss_node(struct mac_context *mac, - tpCsrNeighborRoamBSSInfo neighborRoamBSSNode); QDF_STATUS csr_neighbor_roam_issue_preauth_req(struct mac_context *mac, uint8_t sessionId); bool csr_neighbor_roam_is_preauth_candidate(struct mac_context *mac, diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_support.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_support.h index e743b31745f13d26919cd02ae18903118b3d2841..e8c25ef37f2df1590403481d1b1679aeac6da506 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_support.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_support.h @@ -229,8 +229,36 @@ csr_get_qos_from_bss_desc(struct mac_context *mac_ctx, bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len); bool csr_is_infra_bss_desc(struct bss_description *pSirBssDesc); + +#ifdef QCA_IBSS_SUPPORT +/** + * csr_is_ibss_bss_desc() - API to check bss desc of ibss type + * @pSirBssDesc: pointer to pSirBssDesc structure + * + * Return: true if bss desc of ibss type, else false + */ bool csr_is_ibss_bss_desc(struct bss_description *pSirBssDesc); -bool csr_is_privacy(struct bss_description *pSirBssDesc); + +/** + * csr_is_ibss_bss_desc() - API to check bss desc of ibss type + * @bssType: bss type + * + * Return: true if bss type is ibss type, else false + */ +bool csr_is_bss_type_ibss(eCsrRoamBssType bssType); +#else +static inline +bool csr_is_bss_type_ibss(eCsrRoamBssType bssType) +{ + return false; +} + +static inline +bool csr_is_ibss_bss_desc(struct bss_description *pSirBssDesc) +{ + return false; +} +#endif tSirResultCodes csr_get_de_auth_rsp_status_code(struct deauth_rsp *pSmeRsp); uint32_t csr_get_frag_thresh(struct mac_context *mac_ctx); uint32_t csr_get_rts_thresh(struct mac_context *mac_ctx); @@ -241,18 +269,6 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, struct bss_description *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe); -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT -static inline -bool csr_lookup_pmkid(struct mac_context *mac, uint32_t sessionId, - tPmkidCacheInfo *pmk_cache) -{ - return false; -} -#else -bool csr_lookup_pmkid(struct mac_context *mac, uint32_t sessionId, - tPmkidCacheInfo *pmk_cache); -#endif - uint8_t csr_construct_wpa_ie(struct mac_context *mac, uint8_t session_id, struct csr_roam_profile *pProfile, struct bss_description *pSirBssDesc, @@ -304,17 +320,7 @@ bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate); bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate); tAniEdType csr_translate_encrypt_type_to_ed_type( eCsrEncryptionType EncryptType); -/* - * pIes shall contain IEs from pSirBssDesc. - * It shall be returned from function csr_get_parsed_bss_description_ies - */ -bool csr_is_security_match(struct mac_context *mac_ctx, tCsrAuthList *auth_type, - tCsrEncryptionList *uc_enc_type, - tCsrEncryptionList *mc_enc_type, bool *mfp_enabled, - uint8_t *mfp_required, uint8_t *mfp_capable, - struct bss_description *bss_desc, - tDot11fBeaconIEs *ies_ptr, uint8_t session_id); -bool csr_is_bss_type_ibss(eCsrRoamBssType bssType); + bool csr_is_bssid_match(struct qdf_mac_addr *pProfBssid, struct qdf_mac_addr *BssBssid); void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap); @@ -353,7 +359,7 @@ QDF_STATUS csr_reassoc(struct mac_context *mac, uint32_t sessionId, /** * csr_validate_mcc_beacon_interval() - to validate the mcc beacon interval * @mac_ctx: pointer to mac context - * @chnl_id: channel number + * @ch_freq: channel frequency * @bcn_interval: provided beacon interval * @cur_session_id: current session id * @cur_bss_persona: Current BSS persona @@ -363,7 +369,7 @@ QDF_STATUS csr_reassoc(struct mac_context *mac, uint32_t sessionId, * Return: QDF_STATUS */ QDF_STATUS csr_validate_mcc_beacon_interval(struct mac_context *mac_ctx, - uint8_t chnl_id, + uint32_t ch_freq, uint16_t *bcn_interval, uint32_t cur_session_id, enum QDF_OPMODE cur_bss_persona); diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h index d981f7a2c3ab372b1036925c750425642a15ba66..a44e8e8c15d1a8b4eae1ad516371db8e47dc9fa1 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_api.h @@ -50,11 +50,6 @@ Preprocessor definitions and constants ------------------------------------------------------------------------*/ -#define SME_SUMMARY_STATS (1 << eCsrSummaryStats) -#define SME_GLOBAL_CLASSA_STATS (1 << eCsrGlobalClassAStats) -#define SME_GLOBAL_CLASSD_STATS (1 << eCsrGlobalClassDStats) -#define SME_PER_CHAIN_RSSI_STATS (1 << csr_per_chain_rssi_stats) - #define sme_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_SME, params) #define sme_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_SME, params) #define sme_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_SME, params) @@ -108,16 +103,16 @@ #define SME_CMD_TIMEOUT_VALUE (SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE + 1000) /* Disconnect timeout = vdev stop + bss peer delete + 1 sec */ -#define SME_CMD_VDEV_DISCONNECT_TIMEOUT (SIR_VDEV_STOP_REQUEST_TIMEOUT + \ +#define SME_CMD_VDEV_DISCONNECT_TIMEOUT (STOP_RESPONSE_TIMER + \ SIR_DELETE_STA_TIMEOUT + 1000) #define SME_DISCONNECT_TIMEOUT (SME_CMD_VDEV_DISCONNECT_TIMEOUT + 1000) /* AP start timeout = vdev start + 2 sec */ -#define SME_CMD_VDEV_START_BSS_TIMEOUT (SIR_VDEV_START_REQUEST_TIMEOUT + 2000) +#define SME_CMD_VDEV_START_BSS_TIMEOUT (START_RESPONSE_TIMER + 2000) #define SME_CMD_START_BSS_TIMEOUT (SME_CMD_VDEV_START_BSS_TIMEOUT + 1000) /* AP stop timeout = vdev stop + self peer delete + 1 sec */ -#define SME_CMD_STOP_BSS_CMD_TIMEOUT (SIR_VDEV_STOP_REQUEST_TIMEOUT + \ +#define SME_CMD_STOP_BSS_CMD_TIMEOUT (STOP_RESPONSE_TIMER + \ SIR_DELETE_STA_TIMEOUT + 1000) #define SME_CMD_STOP_BSS_TIMEOUT (SME_CMD_STOP_BSS_CMD_TIMEOUT + 1000) @@ -125,8 +120,10 @@ #define SME_CMD_PEER_DISCONNECT_TIMEOUT (SIR_DELETE_STA_TIMEOUT + 1000) #define SME_PEER_DISCONNECT_TIMEOUT (SME_CMD_PEER_DISCONNECT_TIMEOUT + 1000) +#define SME_CMD_GET_DISCONNECT_STATS_TIMEOUT 200 + /* Roam cmds timeout = vdev start + peer assoc + 1 sec */ -#define SME_CMD_ROAM_CMD_TIMEOUT (SIR_VDEV_START_REQUEST_TIMEOUT + \ +#define SME_CMD_ROAM_CMD_TIMEOUT (START_RESPONSE_TIMER + \ SIR_PEER_ASSOC_TIMEOUT + 1000) #define SME_CMD_ADD_DEL_TS_TIMEOUT (4 * 1000) @@ -138,7 +135,7 @@ #define SME_CMD_POLICY_MGR_CMD_TIMEOUT (SIR_VDEV_PLCY_MGR_TIMEOUT + 1000) #define SME_POLICY_MGR_CMD_TIMEOUT (SME_CMD_POLICY_MGR_CMD_TIMEOUT + 1000) -#define SME_VDEV_DELETE_CMD_TIMEOUT (SIR_VDEV_DELETE_REQUEST_TIMEOUT + 2000) +#define SME_VDEV_DELETE_CMD_TIMEOUT (DELETE_RESPONSE_TIMER + 2000) #define SME_CMD_VDEV_CREATE_DELETE_TIMEOUT QDF_MAX(13000, \ SME_VDEV_DELETE_CMD_TIMEOUT + 1) @@ -215,28 +212,10 @@ struct sme_5g_band_pref_params { /** * struct sme_session_params: Session creation params passed by HDD layer - * @session_open_cb: callback to be registered with SME for opening the session - * @session_close_cb: callback to be registered with SME for closing the session - * @callback: callback to be invoked for roaming events - * @callback_ctx: user-supplied context to be passed back on roaming events - * @self_mac_addr: Self mac address - * @sme_session_id: SME session id - * @type_of_persona: person type - * @subtype_of_persona: sub type of persona - * @session_mon_mode_cb: callback registered with SME for monitor mode vdev up + * @vdev: pointer to vdev object */ struct sme_session_params { - csr_session_open_cb session_open_cb; - csr_session_close_cb session_close_cb; - csr_roam_complete_cb callback; - void *callback_ctx; - uint8_t *self_mac_addr; - uint8_t sme_session_id; - uint32_t type_of_persona; - uint32_t subtype_of_persona; -#ifdef FEATURE_MONITOR_MODE_SUPPORT - csr_session_monitor_mode_cb session_monitor_mode_cb; -#endif + struct wlan_objmgr_vdev *vdev; }; #define MAX_CANDIDATE_INFO 10 @@ -380,36 +359,43 @@ sme_nss_chains_update(mac_handle_t mac_handle, uint8_t vdev_id); /** - * sme_open_session() - Open a session for given persona + * sme_vdev_create() - Create vdev for given persona + * @mac_handle: The handle returned by mac_open + * @vdev_params: params required for vdev creation * - * This is a synchronous API. For any protocol stack related activity - * requires session to be opened. This API needs to be called to open - * the session in SME module. + * This API will create the object manager vdev and in the same + * context vdev mlme object manager notification is invoked, which + * will send the vdev create to the firmware. * - * mac_handle: The handle returned by mac_open. - * params: to initialize the session open params + * If the vdev creation is successful the following object is referenced + * by below modules: + * 1) WLAN_OBJMGR_ID + * 2) WLAN_LEGACY_SME_ID + * 3) WLAN_LEGACY_WMA_ID * - * Return: - * QDF_STATUS_SUCCESS - session is opened. - * Other status means SME is failed to open the session. + * Return: Newly created Vdev object or NULL incase in any error */ -QDF_STATUS sme_open_session(mac_handle_t mac_handle, - struct sme_session_params *params); +struct wlan_objmgr_vdev *sme_vdev_create(mac_handle_t mac_handle, + struct wlan_vdev_create_params *vdev_params); + /** - * sme_close_session() - Close a session for given persona + * sme_vdev_delete() - Delete vdev for given id + * @mac_handle: The handle returned by mac_open. + * @vdev: VDEV Object * - * This is a synchronous API. This API needs to be called to close the session + * This is a synchronous API. This API needs to be called to delete vdev * in SME module before terminating the session completely. * - * mac_handle: The handle returned by mac_open. - * session_id: A previous opened session's ID. + * The following modules releases their reference to the vdev object: + * 1) WLAN_LEGACY_WMA_ID + * 2) WLAN_LEGACY_SME_ID * - * Return: - * QDF_STATUS_SUCCESS - session is closed. - * Other status means SME is failed to open the session. + * Return: QDF_STATUS_SUCCESS - vdev is deleted. + * QDF_STATUS_E_INVAL when failed to delete vdev. */ -QDF_STATUS sme_close_session(mac_handle_t mac_handle, uint8_t sessionId); +QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, + struct wlan_objmgr_vdev *vdev); /** * sme_cleanup_session() - clean up sme session info for vdev @@ -504,16 +490,41 @@ void sme_purge_pdev_all_ser_cmd_list(mac_handle_t mac_handle); QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg); QDF_STATUS sme_mc_process_handler(struct scheduler_msg *msg); -QDF_STATUS sme_scan_get_result(mac_handle_t mac_handle, uint8_t sessionId, - tCsrScanResultFilter *pFilter, - tScanResultHandle *phResult); +/* + * sme_scan_get_result() - Return scan results based on filter + * @mac: Pointer to Global MAC structure + * @vdev_id: vdev_id + * @filter: If pFilter is NULL, all cached results are returned + * @phResult: an object for the result. + * + * Return QDF_STATUS + */ +QDF_STATUS sme_scan_get_result(mac_handle_t mac_handle, uint8_t vdev_id, + struct scan_filter *filter, + tScanResultHandle *phResult); QDF_STATUS sme_get_ap_channel_from_scan_cache( struct csr_roam_profile *profile, tScanResultHandle *scan_cache, - uint8_t *ap_chnl_id); + uint32_t *ap_ch_freq); +/** + * sme_get_ap_channel_from_scan() - a wrapper function to get + * AP's channel id from + * CSR by filtering the + * result which matches + * our roam profile. + * @profile: SAP profile + * @ap_ch_freq: pointer to channel id of SAP. Fill the value after finding the + * best ap from scan cache. + * + * This function is written to get AP's channel id from CSR by filtering + * the result which matches our roam profile. This is a synchronous call. + * + * Return: QDF_STATUS. + */ QDF_STATUS sme_get_ap_channel_from_scan(void *profile, - tScanResultHandle *scan_cache, - uint8_t *ap_chnl_id); + tScanResultHandle *scan_cache, + uint32_t *ap_ch_freq); + tCsrScanResultInfo *sme_scan_result_get_first(mac_handle_t, tScanResultHandle hScanResult); tCsrScanResultInfo *sme_scan_result_get_next(mac_handle_t, @@ -549,10 +560,6 @@ QDF_STATUS sme_roam_get_connect_profile(mac_handle_t mac_handle, uint8_t sessionId, tCsrRoamConnectedProfile *pProfile); void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile); -QDF_STATUS sme_roam_set_pmkid_cache(mac_handle_t mac_handle, uint8_t sessionId, - tPmkidCacheInfo *pPMKIDCache, - uint32_t numItems, - bool update_entire_cache); #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** @@ -614,6 +621,14 @@ sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle, { return QDF_STATUS_E_FAILURE; } + +static inline +QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId, + uint8_t *psk_pmk, size_t pmk_len, + bool update_to_fw) +{ + return QDF_STATUS_SUCCESS; +} #endif /** @@ -658,23 +673,13 @@ QDF_STATUS sme_roam_get_wpa_rsn_rsp_ie(mac_handle_t mac_handle, QDF_STATUS sme_get_config_param(mac_handle_t mac_handle, struct sme_config_params *pParam); -#ifndef QCA_SUPPORT_CP_STATS -QDF_STATUS sme_get_statistics(mac_handle_t mac_handle, - eCsrStatsRequesterType requesterId, - uint32_t statsMask, tCsrStatsCallback callback, - uint8_t staId, void *pContext, uint8_t sessionId); -#endif -QDF_STATUS sme_get_rssi(mac_handle_t mac_handle, - tCsrRssiCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI, - void *pContext); QDF_STATUS sme_get_snr(mac_handle_t mac_handle, - tCsrSnrCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext); + tCsrSnrCallback callback, + struct qdf_mac_addr bssId, void *pContext); #ifdef FEATURE_WLAN_ESE QDF_STATUS sme_get_tsm_stats(mac_handle_t mac_handle, tCsrTsmStatsCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, + struct qdf_mac_addr bssId, void *pContext, uint8_t tid); QDF_STATUS sme_set_cckm_ie(mac_handle_t mac_handle, uint8_t sessionId, @@ -719,8 +724,6 @@ void sme_deregister_oem_data_rsp_callback(mac_handle_t mac_handle) #endif -QDF_STATUS sme_roam_set_key(mac_handle_t mac_handle, uint8_t sessionId, - tCsrRoamSetKey *pSetKey, uint32_t *pRoamId); QDF_STATUS sme_get_country_code(mac_handle_t mac_handle, uint8_t *pBuf, uint8_t *pbLen); @@ -756,12 +759,18 @@ QDF_STATUS sme_neighbor_report_request(mac_handle_t mac_handle, /** * sme_oem_data_cmd() - the wrapper to send oem data cmd to wma * @mac_handle: Opaque handle to the global MAC context. + * @@oem_data_event_handler_cb: callback to be registered * @oem_data: the pointer of oem data + * @vdev id: vdev id to fetch adapter * * Return: QDF_STATUS */ QDF_STATUS sme_oem_data_cmd(mac_handle_t mac_handle, - struct oem_data *oem_data); + void (*oem_data_event_handler_cb) + (const struct oem_data *oem_event_data, + uint8_t vdev_id), + struct oem_data *oem_data, + uint8_t vdev_id); #endif #ifdef FEATURE_OEM_DATA_SUPPORT @@ -785,7 +794,7 @@ QDF_STATUS sme_set_host_offload(mac_handle_t mac_handle, uint8_t sessionId, QDF_STATUS sme_set_keep_alive(mac_handle_t mac_handle, uint8_t sessionId, struct keep_alive_req *pRequest); QDF_STATUS sme_get_operation_channel(mac_handle_t mac_handle, - uint32_t *pChannel, + uint32_t *chan_freq, uint8_t sessionId); QDF_STATUS sme_register_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId, uint16_t frameType, uint8_t *matchData, @@ -806,7 +815,7 @@ QDF_STATUS sme_configure_app_type2_params(mac_handle_t mac_handle, #endif /** * sme_get_beaconing_concurrent_operation_channel() - To get concurrent - * operating channel of beaconing interface + * operating channel frequency of beaconing interface * @mac_handle: Pointer to mac context * @vdev_id_to_skip: channel of which vdev id to skip * @@ -814,25 +823,55 @@ QDF_STATUS sme_configure_app_type2_params(mac_handle_t mac_handle, * and will skip the channel of vdev_id_to_skip. * If other no reqested mode is active it will return 0 * - * Return: uint8_t + * Return: uint32_t */ -uint8_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle, +uint32_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle, uint8_t vdev_id_to_skip); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * sme_check_concurrent_channel_overlap() - Get interfering concurrent channel + * @mac_handle: SAP context pointer + * @sap_ch_freq: SAP home channel frequency + * @sapPhyMode: sap phymode + * @cc_switch_mode: force scc channel switch mode + * + * Determine if a concurrent channel is interfering. + * + * Return: Channel freq (Mhz) of the interfering channel, or 0 if none. + */ uint16_t sme_check_concurrent_channel_overlap(mac_handle_t mac_handle, - uint16_t sap_ch, + uint16_t sap_ch_freq, eCsrPhyMode sapPhyMode, uint8_t cc_switch_mode); #endif -QDF_STATUS sme_get_cfg_valid_channels(uint8_t *aValidChannels, - uint32_t *len); + +/** + * sme_get_cfg_valid_channels() - To get valid channel list + * @valid_ch_freq: pointer to array which save the valid channel list + * @len: the length of the valid channel list + * + * Return: QDF status + */ +QDF_STATUS sme_get_cfg_valid_channels(uint32_t *valid_ch_freq, uint32_t *len); + #ifdef WLAN_FEATURE_PACKET_FILTERING QDF_STATUS sme_8023_multicast_list(mac_handle_t mac_handle, uint8_t sessionId, tpSirRcvFltMcAddrList pMulticastAddrs); #endif /* WLAN_FEATURE_PACKET_FILTERING */ -bool sme_is_channel_valid(mac_handle_t mac_handle, uint8_t channel); uint16_t sme_chn_to_freq(uint8_t chanNum); -bool sme_is_channel_valid(mac_handle_t mac_handle, uint8_t channel); + +/* + * sme_is_channel_valid() - validate a channel against current regdmn + * To check if the channel is valid for currently established domain + * This is a synchronous API. + * + * mac_handle - The handle returned by mac_open. + * chan_freq - channel to verify + * + * Return: true/false, true if channel is valid + */ +bool sme_is_channel_valid(mac_handle_t mac_handle, uint32_t chan_freq); + QDF_STATUS sme_set_max_tx_power(mac_handle_t mac_handle, struct qdf_mac_addr pBssid, struct qdf_mac_addr pSelfMacAddress, int8_t dB); @@ -1096,7 +1135,7 @@ QDF_STATUS sme_get_roam_rssi_diff(mac_handle_t mac_handle, uint8_t vdev_id, uint8_t *rssi_diff); QDF_STATUS sme_change_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t *pChannelList, + uint32_t *channel_freq_list, uint8_t numChannels); /** @@ -1118,23 +1157,23 @@ sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, uint32_t freq_list_type); QDF_STATUS sme_set_ese_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t *pChannelList, + uint32_t *chan_freq_list, uint8_t numChannels); QDF_STATUS sme_get_roam_scan_channel_list(mac_handle_t mac_handle, - uint8_t *pChannelList, + uint32_t *freq_list, uint8_t *pNumChannels, uint8_t sessionId); /** - * sme_dump_chan_list() - Dump the channels from given chan info - * @chan_info: Contains the channel list and number of frequencies + * sme_dump_freq_list() - Dump the frequencies from given chan info + * @chan_info: Contains the frequency list and number of frequencies * - * Extract number of channels and channel list from chan_info and print + * Extract number of frequencies and frequency list from chan_info and print * to the logs. * * Return: None */ -void sme_dump_chan_list(tCsrChannelInfo *chan_info); +void sme_dump_freq_list(tCsrChannelInfo *chan_info); bool sme_get_is_ese_feature_enabled(mac_handle_t mac_handle); bool sme_get_wes_mode(mac_handle_t mac_handle); bool sme_get_roam_scan_control(mac_handle_t mac_handle); @@ -1154,9 +1193,10 @@ QDF_STATUS sme_del_periodic_tx_ptrn(mac_handle_t mac_handle, QDF_STATUS sme_send_rate_update_ind(mac_handle_t mac_handle, tSirRateUpdateInd *rateUpdateParams); QDF_STATUS sme_roam_del_pmkid_from_cache(mac_handle_t mac_handle, - uint8_t sessionId, - tPmkidCacheInfo *pmksa, - bool flush_cache); + uint8_t vdev_id, + struct wlan_crypto_pmksa *pmksa, + bool set_pmk); + void sme_get_command_q_status(mac_handle_t mac_handle); #ifdef FEATURE_WLAN_RMC @@ -1165,11 +1205,35 @@ QDF_STATUS sme_disable_rmc(mac_handle_t mac_handle, uint32_t sessionId); QDF_STATUS sme_send_rmc_action_period(mac_handle_t mac_handle, uint32_t sessionId); #endif + +#ifdef QCA_IBSS_SUPPORT +/* + * sme_request_ibss_peer_info() - request ibss peer info + * @mac_handle: Opaque handle to the global MAC context + * @cb_context: Pointer to user data + * @peer_info_cb: Peer info callback + * @allPeerInfoReqd: All peer info required or not + * @staIdx: sta index + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_request_ibss_peer_info(mac_handle_t mac_handle, + void *cb_context, + ibss_peer_info_cb peer_info_cb, + bool allPeerInfoReqd, + uint8_t *mac_addr); +#else +static inline QDF_STATUS sme_request_ibss_peer_info(mac_handle_t mac_handle, void *cb_context, ibss_peer_info_cb peer_info_cb, bool allPeerInfoReqd, - uint8_t staIdx); + uint8_t *mac_addr) +{ + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS sme_send_cesium_enable_ind(mac_handle_t mac_handle, uint32_t sessionId); @@ -1201,14 +1265,26 @@ int sme_update_ht_config(mac_handle_t mac_handle, uint8_t sessionId, int16_t sme_get_ht_config(mac_handle_t mac_handle, uint8_t session_id, uint16_t ht_capab); #ifdef QCA_HT_2040_COEX -QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, uint16_t staId, +QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, struct qdf_mac_addr macAddrSTA, uint8_t sessionId, uint8_t channel_type); QDF_STATUS sme_set_ht2040_mode(mac_handle_t mac_handle, uint8_t sessionId, uint8_t channel_type, bool obssEnabled); #endif -QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint8_t chanId, + +/** + * sme_get_reg_info() - To get tx power information + * @mac_handle: Opaque handle to the global MAC context + * @chan_freq: channel freq + * @regInfo1: first reg info to fill + * @regInfo2: second reg info to fill + * + * This routine will give you tx power information + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint32_t chan_freq, uint32_t *regInfo1, uint32_t *regInfo2); #ifdef FEATURE_WLAN_CH_AVOID @@ -1245,9 +1321,12 @@ QDF_STATUS sme_roam_start_beacon_req(mac_handle_t mac_handle, uint8_t dfsCacWaitStatus); /** - * sme_csa_restart() - request CSA IE transmission from PE - * @mac_ctx: mac context - * @session_id: SAP session id + * sme_roam_csa_ie_request() - request CSA IE transmission from PE + * @mac_handle: handle returned by mac_open + * @bssid: SAP bssid + * @target_chan_freq: target channel frequency information + * @csaIeReqd: CSA IE Request + * @ch_params: channel information * * Return: QDF_STATUS */ @@ -1255,7 +1334,7 @@ QDF_STATUS sme_csa_restart(struct mac_context *mac_ctx, uint8_t session_id); QDF_STATUS sme_roam_csa_ie_request(mac_handle_t mac_handle, struct qdf_mac_addr bssid, - uint8_t targetChannel, uint8_t csaIeReqd, + uint32_t target_chan_freq, uint8_t csaIeReqd, struct ch_params *ch_params); /** @@ -1382,10 +1461,21 @@ QDF_STATUS sme_update_dfs_scan_mode(mac_handle_t mac_handle, uint8_t allowDFSChannelRoam); uint8_t sme_get_dfs_scan_mode(mac_handle_t mac_handle); +/** + * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band + * @mac_handle: Opaque handle to the global MAC context + * @wifi_band: RF band information + * @valid_chan_list: output array to store channel info + * @valid_chan_len: output number of channels + * + * SME API to fetch all valid channels filtered by band + * + * Return: QDF_STATUS + */ QDF_STATUS sme_get_valid_channels_by_band(mac_handle_t mac_handle, - uint8_t wifiBand, - uint32_t *aValidChannels, - uint8_t *pNumChannels); + uint8_t wifi_band, + uint32_t *valid_chan_list, + uint8_t *valid_chan_len); #ifdef FEATURE_WLAN_EXTSCAN /** @@ -1524,6 +1614,7 @@ QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle, return QDF_STATUS_SUCCESS; } #endif /* FEATURE_WLAN_EXTSCAN */ +QDF_STATUS sme_abort_roam_scan(mac_handle_t mac_handle, uint8_t sessionId); /** * sme_get_vht_ch_width() - SME API to get the max supported FW chan width @@ -1532,7 +1623,6 @@ QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle, */ uint32_t sme_get_vht_ch_width(void); -QDF_STATUS sme_abort_roam_scan(mac_handle_t mac_handle, uint8_t sessionId); #ifdef WLAN_FEATURE_LINK_LAYER_STATS QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle, tSirLLStatsClearReq * pclearStatsReq); @@ -1677,7 +1767,6 @@ QDF_STATUS sme_send_flush_logs_cmd_to_fw(void); /** * sme_enable_uapsd_for_ac() - enable uapsd for access category request to WMA - * @sta_id: station id * @ac: access category * @tid: tid value * @pri: user priority @@ -1690,8 +1779,7 @@ QDF_STATUS sme_send_flush_logs_cmd_to_fw(void); * * Return: QDF status */ -QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id, - sme_ac_enum_type ac, uint8_t tid, +QDF_STATUS sme_enable_uapsd_for_ac(sme_ac_enum_type ac, uint8_t tid, uint8_t pri, uint32_t srvc_int, uint32_t sus_int, enum sme_qos_wmm_dir_type dir, @@ -1700,15 +1788,12 @@ QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id, /** * sme_disable_uapsd_for_ac() - disable uapsd access category request to WMA - * @sta_id: station id * @ac: access category * @sessionId: session id * * Return: QDF status */ -QDF_STATUS sme_disable_uapsd_for_ac(uint8_t sta_id, - sme_ac_enum_type ac, - uint32_t sessionId); +QDF_STATUS sme_disable_uapsd_for_ac(sme_ac_enum_type ac, uint32_t sessionId); #ifdef FEATURE_RSSI_MONITOR QDF_STATUS sme_set_rssi_monitoring(mac_handle_t mac_handle, @@ -1755,7 +1840,7 @@ bool sme_is_any_session_in_connected_state(mac_handle_t mac_handle); QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg); QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg); QDF_STATUS sme_nss_update_request(uint32_t vdev_id, - uint8_t new_nss, + uint8_t new_nss, uint8_t ch_width, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, @@ -1822,7 +1907,7 @@ void sme_update_tgt_services(mac_handle_t mac_handle, struct wma_tgt_services *cfg); bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, - uint16_t sap_ch, eCsrPhyMode sap_phy_mode, + uint32_t sap_ch_freq, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode, uint8_t session_id); @@ -2017,7 +2102,7 @@ sme_apf_read_work_memory(mac_handle_t mac_handle, #endif /* FEATURE_WLAN_APF */ uint32_t sme_get_wni_dot11_mode(mac_handle_t mac_handle); -QDF_STATUS sme_create_mon_session(mac_handle_t mac_handle, tSirMacAddr bss_id, +QDF_STATUS sme_create_mon_session(mac_handle_t mac_handle, uint8_t *bssid, uint8_t vdev_id); /** @@ -2030,7 +2115,17 @@ QDF_STATUS sme_create_mon_session(mac_handle_t mac_handle, tSirMacAddr bss_id, */ QDF_STATUS sme_delete_mon_session(mac_handle_t mac_handle, uint8_t vdev_id); -void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id); +/** + * sme_set_vdev_ies_per_band() - sends the per band IEs to vdev + * @mac_handle: Opaque handle to the global MAC context + * @vdev_id: vdev_id for which IE is targeted + * @device_mode: vdev mode + * + * Return: None + */ +void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, + enum QDF_OPMODE device_mode); + void sme_set_pdev_ht_vht_ies(mac_handle_t mac_handle, bool enable2x2); /** @@ -2205,6 +2300,24 @@ QDF_STATUS sme_set_lost_link_info_cb(mac_handle_t mac_handle, QDF_STATUS sme_update_new_channel_event(mac_handle_t mac_handle, uint8_t session_id); #ifdef WLAN_POWER_DEBUG +/** + * sme_reset_power_debug_stats_cb() - SME API to reset Power debug stats cb + * @mac_handle: Opaque handle to the global MAC context + * + * Resets the power stats callback and context to NULL + * + * Return: None + */ +void sme_reset_power_debug_stats_cb(mac_handle_t mac_handle); + +/** + * sme_power_debug_stats_req() - SME API to collect Power debug stats + * @mac_handle: Opaque handle to the global MAC context + * @callback_fn: Pointer to the callback function for Power stats event + * @power_stats_context: Pointer to context + * + * Return: QDF_STATUS + */ QDF_STATUS sme_power_debug_stats_req( mac_handle_t mac_handle, void (*callback_fn)(struct power_stats_response *response, @@ -2276,6 +2389,20 @@ QDF_STATUS sme_set_nud_debug_stats_cb(mac_handle_t mac_handle, void (*cb)(void *, struct rsp_stats *, void *context), void *context); +/** + * sme_set_del_peers_ind_callback() - Register del peers ind callback + * @mac_handle - MAC global handle + * @callback_routine - callback routine from HDD + * + * This API is invoked by HDD to register its callback to mac + * + * Return: QDF_STATUS + */ +void +sme_set_del_peers_ind_callback(mac_handle_t mac_handle, + void (*callback)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id)); + /** * sme_set_chan_info_callback() - Register chan info callback * @mac_handle - MAC global handle @@ -2311,7 +2438,7 @@ QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle, * @bssid: bssid to look for in scan cache * @frame_buf: frame buffer to populate * @frame_len: length of constructed frame - * @channel: Pointer to channel info to be filled + * @ch_freq: Pointer to channel freq info to be filled * * Return: QDF_STATUS */ @@ -2319,7 +2446,7 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, struct csr_roam_profile *profile, const tSirMacAddr bssid, uint8_t **frame_buf, uint32_t *frame_len, - int *channel); + uint32_t *ch_freq); #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** @@ -2327,7 +2454,7 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, * @mac_handle: handle returned by mac_open * @profile: current connected profile * @bssid: bssid to look for in scan cache - * @channel: channel on which reassoc should be send + * @ch_freq: channel on which reassoc should be send * @vdev_id: vdev id * @connected_bssid: bssid of currently connected profile * @@ -2335,7 +2462,7 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, */ QDF_STATUS sme_fast_reassoc(mac_handle_t mac_handle, struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, + const tSirMacAddr bssid, uint32_t ch_freq, uint8_t vdev_id, const tSirMacAddr connected_bssid); /** @@ -2351,7 +2478,7 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id); static inline QDF_STATUS sme_fast_reassoc(mac_handle_t mac_handle, struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, + const tSirMacAddr bssid, uint32_t ch_freq, uint8_t vdev_id, const tSirMacAddr connected_bssid) { return QDF_STATUS_SUCCESS; @@ -2364,15 +2491,6 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id) } #endif -/** - * sme_congestion_register_callback() - registers congestion callback - * @mac_handle: Opaque handle to the global MAC context - * @congestion_cb: congestion callback - * - * Return: QDF_STATUS - */ -QDF_STATUS sme_congestion_register_callback(mac_handle_t mac_handle, - congestion_cb congestion_cb); /** * sme_register_tx_queue_cb(): Register tx queue callback @@ -2543,23 +2661,6 @@ int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id); QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id, uint32_t param_val); -/** - * sme_get_peer_info() - sme api to get peer info - * @mac_handle: Opaque handle to the global MAC context - * @req: peer info request struct send to wma - * @context: context of callback function - * @callbackfn: hdd callback function when receive response - * - * This function will send WMA_GET_PEER_INFO to WMA - * - * Return: QDF_STATUS_SUCCESS or non-zero on failure - */ -QDF_STATUS sme_get_peer_info(mac_handle_t mac_handle, - struct sir_peer_info_req req, - void *context, - void (*callbackfn)(struct sir_peer_info_resp *param, - void *pcontext)); - /** * sme_get_peer_info_ext() - sme api to get peer ext info * @mac_handle: Opaque handle to the global MAC context @@ -2630,7 +2731,7 @@ QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle, /** * sme_get_valid_channels() - sme api to get valid channels for * current regulatory domain - * @chan_list: list of the valid channels + * @ch_freq_list: list of the valid channel frequencies * @list_len: length of the channel list * * This function will get valid channels for current regulatory @@ -2638,7 +2739,7 @@ QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle, * * Return: QDF_STATUS_SUCCESS or non-zero on failure */ -QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len); +QDF_STATUS sme_get_valid_channels(uint32_t *ch_freq_list, uint32_t *list_len); /** * sme_get_mac_context() - sme api to get the pmac context @@ -2727,6 +2828,21 @@ QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, tPmkidCacheInfo *pmk_cache_info, bool is_add); +/** + * sme_clear_sae_single_pmk_info() - Clear sae_single_pmk onfo + * @psoc: Psoc object + * @session_id: session id + * @pmk_cache_info: pmk cache info + * + * This function will clear sae_single_pmk info while processing delete pmk + * command from userspace. + * + * Return: None + */ +void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + tPmkidCacheInfo *pmk_cache_info); + /** * sme_send_hlp_ie_info() - API to send HLP IE info to fw * @mac_handle: Opaque handle to the global MAC context @@ -3422,6 +3538,20 @@ static inline int sme_update_he_twt_req_support(mac_handle_t mac_handle, #endif +/** + * sme_update_session_txq_edca_params() - sets the configured + * internal EDCA params values + * + * @mac_handle: Opaque handle to the global MAC context + * @session_id: session id + * @txq_edca_params: edca parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_update_session_txq_edca_params(mac_handle_t mac_handle, uint8_t session_id, + tSirMacEdcaParamRecord *txq_edca_params); + /** * sme_is_sta_key_exchange_in_progress() - checks whether the STA/P2P client * session has key exchange in progress @@ -3438,7 +3568,7 @@ bool sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle, /* * sme_validate_channel_list() - Validate the given channel list * @mac_handle: Opaque handle to the global MAC context - * @chan_list: Pointer to the channel list + * @chan_freq_list: Pointer to the channel list * @num_channels: number of channels present in the chan_list * * Validates the given channel list with base channels in mac context @@ -3446,7 +3576,7 @@ bool sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle, * Return: True if all channels in the list are valid, false otherwise */ bool sme_validate_channel_list(mac_handle_t mac_handle, - uint8_t *chan_list, + uint32_t *chan_freq_list, uint8_t num_channels); /** * sme_set_amsdu() - set amsdu enable/disable based on user cfg @@ -3795,14 +3925,29 @@ QDF_STATUS sme_motion_det_base_line_enable( * * Return: QDF_STATUS_SUCCESS or non-zero on failure */ - QDF_STATUS sme_set_md_host_evt_cb ( mac_handle_t mac_handle, QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_evt *event), void *hdd_ctx ); + +/** + * sme_set_md_bl_evt_cb - Register/set motion detection baseline callback + * @mac_handle: mac handle + * @callback_fn: callback function pointer + * @hdd_ctx: hdd context + * + * Return: QDF_STATUS_SUCCESS or non-zero on failure + */ +QDF_STATUS sme_set_md_bl_evt_cb +( + mac_handle_t mac_handle, + QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_bl_evt *event), + void *hdd_ctx +); #endif /* WLAN_FEATURE_MOTION_DETECTION */ + #ifdef FW_THERMAL_THROTTLE_SUPPORT /** * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle @@ -3907,12 +4052,6 @@ QDF_STATUS sme_register_bcn_recv_pause_ind_cb(mac_handle_t mac_handle, QDF_STATUS sme_set_disconnect_ies(mac_handle_t mac_handle, uint8_t vdev_id, uint8_t *ie_data, uint16_t ie_len); -void sme_freq_to_chan_list( - struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, - uint32_t *freq_list, - uint32_t chan_list_len); - void sme_chan_to_freq_list( struct wlan_objmgr_pdev *pdev, uint32_t *freq_list, @@ -3986,42 +4125,35 @@ QDF_STATUS sme_get_full_roam_scan_period(mac_handle_t mac_handle, uint8_t vdev_id, uint32_t *full_roam_scan_period); -#ifdef FEATURE_OEM_DATA /** - * sme_set_oem_data_event_handler_cb() - Register oem data event handler - * callback + * sme_check_for_duplicate_session() - check for duplicate session * @mac_handle: Opaque handle to the MAC context - * @oem_data_event_handler_cb: callback to be registered + * @peer_addr: Peer device mac address + * + * Check for duplicate mac address is available on other vdev. * * Return: QDF_STATUS */ -QDF_STATUS sme_set_oem_data_event_handler_cb( - mac_handle_t mac_handle, - void (*oem_data_event_handler_cb) - (const struct oem_data *oem_event_data)); - -/** - * sme_reset_oem_data_event_handler_cb() - De-register oem data event handler - * @mac_handle: Handler return by mac_open +QDF_STATUS sme_check_for_duplicate_session(mac_handle_t mac_handle, + uint8_t *peer_addr); +#ifdef FEATURE_ANI_LEVEL_REQUEST +/* + * sme_get_ani_level() - + * A wrapper function that client calls to register a callback to get ani level * - * This function De-registers the OEM data event handler callback to SME + * @mac_handle - pointer to mac handle + * @freqs - frequencies for which ANI level has to be fetched + * @num_freqs - number of frequencies + * @callback - SME sends back the ani level using the callback + * @context - user context to be passed back along with the callback * - * Return: None + * Return: QDF_STATUS */ -void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle); -#else -static inline QDF_STATUS sme_set_oem_data_event_handler_cb( - mac_handle_t mac_handle, - void (*oem_data_event_handler_cb) - (void *oem_event_data)) -{ - return QDF_STATUS_SUCCESS; -} - -static inline void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle) -{ -} -#endif +QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs, + uint8_t num_freqs, void (*callback)( + struct wmi_host_ani_level_event *ani, uint8_t num, + void *context), void *context); +#endif /* FEATURE_ANI_LEVEL_REQUEST */ /** * sme_get_prev_connected_bss_ies() - Get the previous connected AP IEs @@ -4038,4 +4170,38 @@ static inline void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle) QDF_STATUS sme_get_prev_connected_bss_ies(mac_handle_t mac_handle, uint8_t vdev_id, uint8_t **ies, uint32_t *ie_len); + +#ifdef FEATURE_MONITOR_MODE_SUPPORT +/** + * sme_set_monitor_mode_cb() - Register monitor mode vdev up operation callback + * @mac_handle: Opaque handle to the MAC context + * @monitor_mode_cb: callback to be registered + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle, + void (*monitor_mode_cb)(uint8_t vdev_id)); + +/* + * sme_process_monitor_mode_vdev_up_evt() - Handle vdev up completion + * @vdev_id: vdev id + * + * Return: QDF_STATUS. + */ +QDF_STATUS sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id); +#else +static inline +QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle, + void (*monitor_mode_cb)(uint8_t vdev_id)) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id) +{ + return QDF_STATUS_E_FAILURE; +} +#endif + #endif /* #if !defined( __SME_API_H ) */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h index 481783eaf9180ef22571b94c880991aa04604281..8a67bea4d9ad20414c5103488db5d00d617fd4d0 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, 2018, 2019 The Linux Foundation. + * Copyright (c) 2013-2016, 2018, 2019-2020 The Linux Foundation. * All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for @@ -55,11 +55,10 @@ typedef struct sFTSMEContext { /* Pre-Auth info */ tFTIEStates FTState; /* The state of FT in the current 11rAssoc */ tSirMacAddr preAuthbssId; /* BSSID to preauth to */ - uint32_t smeSessionId; + uint32_t vdev_id; /* Saved pFTPreAuthRsp */ tpSirFTPreAuthRsp psavedFTPreAuthRsp; bool setFTPreAuthState; - bool setFTPTKState; /* Time to trigger reassoc once pre-auth is successful */ qdf_mc_timer_t preAuthReassocIntvlTimer; bool addMDIE; @@ -115,7 +114,4 @@ void sme_preauth_reassoc_intvl_timer_callback(void *context); void sme_set_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId, bool state); bool sme_get_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId); -bool sme_get_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId); -void sme_set_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId, - bool state); #endif diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_inside.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_inside.h index f004a800536e144508539e35d950a71a6f733428..d9ffedcf9fc86f0586f142b5110d9f10b822a788 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_inside.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_inside.h @@ -61,6 +61,7 @@ typedef struct sGenericQosCmd { /** * struct s_nss_update_cmd - Format of nss update request * @new_nss: new nss value + * @ch_width: new channel width - optional * @session_id: Session ID * @set_hw_mode_cb: HDD nss update callback * @context: Adapter context @@ -70,6 +71,7 @@ typedef struct sGenericQosCmd { */ struct s_nss_update_cmd { uint32_t new_nss; + uint32_t ch_width; uint32_t session_id; void *nss_update_cb; void *context; @@ -78,11 +80,20 @@ struct s_nss_update_cmd { uint32_t original_vdev_id; }; +/** + * struct sir_disconnect_stats_cmd: command structure to get disconnect stats + * @peer_mac_addr: MAC address of the peer disconnected + * + */ +struct sir_disconnect_stats_cmd { + struct qdf_mac_addr peer_mac_addr; +}; + typedef struct tagSmeCmd { tListElem Link; eSmeCommandType command; uint32_t cmd_id; - uint32_t sessionId; + uint32_t vdev_id; union { struct roam_cmd roamCmd; struct wmstatus_changecmd wmStatusChangeCmd; @@ -92,6 +103,7 @@ typedef struct tagSmeCmd { struct s_nss_update_cmd nss_update_cmd; struct policy_mgr_dual_mac_config set_dual_mac_cmd; struct sir_antenna_mode_param set_antenna_mode_cmd; + struct sir_disconnect_stats_cmd disconnect_stats_cmd; } u; } tSmeCmd; @@ -142,29 +154,38 @@ void csr_roam_wm_status_change_complete(struct mac_context *mac_ctx, uint8_t session_id); void csr_roam_process_wm_status_change_command(struct mac_context *mac, tSmeCmd *pCommand); + /** - * csr_process_del_sta_session_command() - Post WMA_DEL_STA_SELF_REQ to wma - * + * csr_roam_get_disconnect_stats_complete() - Remove get disconnect stats + * command from SME active command list * @mac_ctx: global mac context - * @sme_command: received Delete Self station request command + * This API removes get disconnect stats command from SME active command list + * if present. * - * This API sends the WMA_DEL_STA_SELF_REQ msg to WMA. + * Return: void + */ +void csr_roam_get_disconnect_stats_complete(struct mac_context *mac_ctx); + +/** + * csr_roam_process_get_disconnect_stats_command() - Process get disconnect + * stats + * @mac_ctx: global mac context + * @pCommand: Command to be processed * - * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE + * Return: void */ -QDF_STATUS csr_process_del_sta_session_command(struct mac_context *mac_ctx, - tSmeCmd *sme_command); +void csr_roam_process_get_disconnect_stats_command(struct mac_context *mac, + tSmeCmd *cmd); void csr_reinit_roam_cmd(struct mac_context *mac, tSmeCmd *pCommand); -void csr_reinit_wm_status_change_cmd(struct mac_context *mac, tSmeCmd *pCommand); -QDF_STATUS csr_roam_send_set_key_cmd(struct mac_context *mac_ctx, - uint32_t session_id, struct setkey_cmd *set_key_cmd); -QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint8_t chnNum); +void csr_reinit_wm_status_change_cmd(struct mac_context *mac, + tSmeCmd *pCommand); +QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint32_t freq); QDF_STATUS sme_acquire_global_lock(struct sme_context *sme); QDF_STATUS sme_release_global_lock(struct sme_context *sme); -QDF_STATUS csr_process_add_sta_session_rsp(struct mac_context *mac, uint8_t *pMsg); -QDF_STATUS csr_process_del_sta_session_rsp(struct mac_context *mac, uint8_t *pMsg); +QDF_STATUS +csr_process_vdev_del_rsp(struct mac_context *mac, uint8_t *pmsg); /** * csr_flush_cfg_bg_scan_roam_channel_list() - Flush the channel list @@ -178,20 +199,20 @@ void csr_flush_cfg_bg_scan_roam_channel_list(tCsrChannelInfo *channel_info); * csr_create_bg_scan_roam_channel_list() - Create roam scan chan list * @mac: global mac context * @channel_info: Channel list to be populated for roam scan - * @chan_list: Channel list to be populated from + * @chan_freq_list: Channel list to be populated from * @num_chan: Number of channels * * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE */ QDF_STATUS csr_create_bg_scan_roam_channel_list(struct mac_context *mac, tCsrChannelInfo *channel_info, - const uint8_t *chan_list, + const uint32_t *chan_freq_list, const uint8_t num_chan); #ifdef FEATURE_WLAN_ESE QDF_STATUS csr_create_roam_scan_channel_list(struct mac_context *mac, uint8_t sessionId, - uint8_t *pChannelList, + uint32_t *chan_freq_list, uint8_t numChannels, const enum band_info band); #endif @@ -201,23 +222,4 @@ void csr_process_set_dual_mac_config(struct mac_context *mac, tSmeCmd *command); void csr_process_set_antenna_mode(struct mac_context *mac, tSmeCmd *command); void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command); void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command); - -#ifdef FEATURE_MONITOR_MODE_SUPPORT -QDF_STATUS csr_process_monitor_mode_vdev_up_evt(struct mac_context *mac, - uint8_t vdev_id); - -void csr_monitor_mode_register_callback(struct csr_roam_session *session, - struct sme_session_params *session_param); -#else -static inline QDF_STATUS -csr_process_monitor_mode_vdev_up_evt(struct mac_context *mac, uint8_t vdev_id) -{ - return QDF_STATUS_E_FAILURE; -} - -static inline void -csr_monitor_mode_register_callback(struct csr_roam_session *session, - struct sme_session_params *session_param) {} -#endif - #endif /* #if !defined( __SMEINSIDE_H ) */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h index f11b83137eb6f1c67bab88304a3d8e9ae9706665..0411b499449be29c3a34035622abfce3956a8577 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_internal.h @@ -51,7 +51,7 @@ typedef enum eSmeCommandType { eSmeCsrCommandMask = 0x10000, eSmeCommandRoam, eSmeCommandWmStatusChange, - e_sme_command_del_sta_session, + eSmeCommandGetdisconnectStats, /* QOS */ eSmeQosCommandMask = 0x40000, /* To identify Qos commands */ eSmeCommandAddTs, @@ -226,15 +226,6 @@ typedef void (*pwr_save_fail_cb)(hdd_handle_t hdd_handle, typedef void (*bt_activity_info_cb)(hdd_handle_t hdd_handle, uint32_t bt_activity); -/** - * typedef congestion_cb - congestion callback function - * @hdd_handle: HDD handle registered with SME - * @congestion: Current congestion value - * @vdev_id: ID of the vdev for which congestion is being reported - */ -typedef void (*congestion_cb)(hdd_handle_t hdd_handle, uint32_t congestion, - uint32_t vdev_id); - /** * typedef rso_cmd_status_cb - RSO command status callback function * @hdd_handle: HDD handle registered with SME @@ -289,6 +280,7 @@ typedef void (*sme_get_isolation_cb)(struct sir_isolation_resp *param, #ifdef WLAN_FEATURE_MOTION_DETECTION typedef QDF_STATUS (*md_host_evt_cb)(void *hdd_ctx, struct sir_md_evt *event); +typedef QDF_STATUS (*md_bl_evt_cb)(void *hdd_ctx, struct sir_md_bl_evt *event); #endif /* WLAN_FEATURE_MOTION_DETECTION */ struct sme_context { @@ -311,6 +303,9 @@ struct sme_context { void *power_debug_stats_context; void (*power_stats_resp_callback)(struct power_stats_response *rsp, void *callback_context); + void (*sme_power_debug_stats_callback)( + struct mac_context *mac, + struct power_stats_response *response); #endif #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS void *beacon_stats_context; @@ -327,10 +322,7 @@ struct sme_context { /* linkspeed callback */ sme_link_speed_cb link_speed_cb; void *link_speed_context; - /* get peer info callback */ - void (*pget_peer_info_ind_cb)(struct sir_peer_info_resp *param, - void *pcontext); - void *pget_peer_info_cb_context; + /* get extended peer info callback */ void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param, void *pcontext); @@ -365,7 +357,6 @@ struct sme_context { bool (*get_connection_info_cb)(uint8_t *session_id, enum scan_reject_states *reason); rso_cmd_status_cb rso_cmd_status_cb; - congestion_cb congestion_cb; pwr_save_fail_cb chip_power_save_fail_cb; bt_activity_info_cb bt_activity_info_cb; void *get_arp_stats_context; @@ -385,6 +376,7 @@ struct sme_context { #endif #ifdef WLAN_FEATURE_MOTION_DETECTION md_host_evt_cb md_host_evt_cb; + md_bl_evt_cb md_bl_evt_cb; void *md_ctx; #endif /* WLAN_FEATURE_MOTION_DETECTION */ /* hidden ssid rsp callback */ @@ -402,10 +394,15 @@ struct sme_context { #endif #ifdef FEATURE_OEM_DATA void (*oem_data_event_handler_cb) - (const struct oem_data *oem_event_data); + (const struct oem_data *oem_event_data, + uint8_t vdev_id); + uint8_t oem_data_vdev_id; #endif sme_get_raom_scan_ch_callback roam_scan_ch_callback; void *roam_scan_ch_get_context; +#ifdef FEATURE_MONITOR_MODE_SUPPORT + void (*monitor_mode_cb)(uint8_t vdev_id); +#endif }; #endif /* #if !defined( __SMEINTERNAL_H ) */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_qos_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_qos_api.h index e06816db3486fadd28edad637dc68e50f732f5d4..09d4993f151f6d82bfa8c1a2c69d554f5ec09f83 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_qos_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_qos_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -196,6 +196,22 @@ struct sme_qos_wmmtspecinfo { uint16_t medium_time; }; +static inline enum sme_qos_wmmuptype qca_wlan_ac_to_sme_qos(u8 priority) +{ + switch (priority) { + case QCA_WLAN_AC_BE: + return SME_QOS_WMM_UP_BE; + case QCA_WLAN_AC_BK: + return SME_QOS_WMM_UP_BK; + case QCA_WLAN_AC_VI: + return SME_QOS_WMM_UP_VI; + case QCA_WLAN_AC_VO: + return SME_QOS_WMM_UP_VO; + default: + return SME_QOS_WMM_UP_BE; + } +} + /* External APIs */ typedef QDF_STATUS (*sme_QosCallback)(mac_handle_t mac_handle, void *HDDcontext, struct sme_qos_wmmtspecinfo *pCurrentQoSInfo, diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_trace.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_trace.h index f84642bc35bc673a3507966ab4f6dacacf5dabd1..51440838679ab81a25c2d389032940f4cf914c7f 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_trace.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_trace.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -69,8 +69,6 @@ enum { TRACE_CODE_SME_RX_HDD_EXIT_WOWL, TRACE_CODE_SME_RX_HDD_SET_KEY, TRACE_CODE_SME_RX_HDD_REMOVE_KEY, - TRACE_CODE_SME_RX_HDD_GET_STATS, - TRACE_CODE_SME_RX_HDD_GET_RSSI, TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c index a524a499e7f76245fbbc9601701e79cd8606e3eb..fb5e97231b9c52d176c8e93a7cb5ff63fe08052b 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c @@ -389,11 +389,6 @@ static void dump_csr_command_info(struct mac_context *mac, tSmeCmd *pCmd) pCmd->u.wmStatusChangeCmd.Type); break; - case e_sme_command_del_sta_session: - sme_debug("Issue del STA command for session:%d", - pCmd->sessionId); - break; - default: sme_debug("default: Unhandled command %d", pCmd->command); @@ -469,8 +464,8 @@ tSmeCmd *sme_get_command_buffer(struct mac_context *mac) if (pRetCmd) { qdf_mem_zero((uint8_t *)&pRetCmd->command, sizeof(pRetCmd->command)); - qdf_mem_zero((uint8_t *)&pRetCmd->sessionId, - sizeof(pRetCmd->sessionId)); + qdf_mem_zero((uint8_t *)&pRetCmd->vdev_id, + sizeof(pRetCmd->vdev_id)); qdf_mem_zero((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u)); } @@ -522,9 +517,11 @@ QDF_STATUS sme_ser_handle_active_cmd(struct wlan_serialization_command *cmd) csr_roam_process_wm_status_change_command(mac_ctx, sme_cmd); break; - case e_sme_command_del_sta_session: - csr_process_del_sta_session_command(mac_ctx, sme_cmd); + case eSmeCommandGetdisconnectStats: + csr_roam_process_get_disconnect_stats_command(mac_ctx, + sme_cmd); break; + case eSmeCommandAddTs: case eSmeCommandDelTs: #ifndef WLAN_MDM_CODE_REDUCTION_OPT @@ -602,27 +599,27 @@ QDF_STATUS sme_ser_cmd_callback(struct wlan_serialization_command *cmd, #ifdef WLAN_FEATURE_MEMDUMP_ENABLE /** - * sme_get_sessionid_from_activelist() - gets session id + * sme_get_sessionid_from_activelist() - gets vdev_id * @mac: mac context * * This function is used to get session id from sme command * active list * - * Return: returns session id + * Return: returns vdev_id */ static uint32_t sme_get_sessionid_from_activelist(struct mac_context *mac) { tListElem *entry; tSmeCmd *command; - uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; + uint32_t vdev_id = WLAN_UMAC_VDEV_ID_MAX; entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); if (entry) { command = GET_BASE_ADDR(entry, tSmeCmd, Link); - session_id = command->sessionId; + vdev_id = command->vdev_id; } - return session_id; + return vdev_id; } /** @@ -702,6 +699,59 @@ static void sme_register_debug_callback(void) } #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ +#ifdef WLAN_POWER_DEBUG +static void sme_power_debug_stats_cb(struct mac_context *mac, + struct power_stats_response *response) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + if (mac->sme.power_stats_resp_callback) + mac->sme.power_stats_resp_callback( + response, + mac->sme.power_debug_stats_context); + else + sme_err("Null hdd cb"); + mac->sme.power_stats_resp_callback = NULL; + mac->sme.power_debug_stats_context = NULL; + sme_release_global_lock(&mac->sme); + } +} + +static void sme_register_power_debug_stats_cb(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = sme_acquire_global_lock(&mac->sme); + + if (QDF_IS_STATUS_SUCCESS(status)) { + mac->sme.sme_power_debug_stats_callback = + sme_power_debug_stats_cb; + sme_release_global_lock(&mac->sme); + } +} + +static void sme_unregister_power_debug_stats_cb(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + mac->sme.sme_power_debug_stats_callback = NULL; + sme_release_global_lock(&mac->sme); + } +} +#else +static inline void sme_register_power_debug_stats_cb(struct mac_context *mac) +{ +} + +static inline void sme_unregister_power_debug_stats_cb(struct mac_context *mac) +{ +} +#endif + /* Global APIs */ /** @@ -758,6 +808,7 @@ QDF_STATUS sme_open(mac_handle_t mac_handle) } sme_trace_init(mac); sme_register_debug_callback(); + sme_register_power_debug_stats_cb(mac); return status; } @@ -1133,10 +1184,11 @@ sme_register_bcn_report_pe_cb(mac_handle_t mac_handle, beacon_report_cb cb) } #endif -QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len) +QDF_STATUS sme_get_valid_channels(uint32_t *ch_freq_list, uint32_t *list_len) { struct mac_context *mac_ctx = sme_get_mac_context(); uint32_t num_valid_chan; + uint8_t i; if (!mac_ctx) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -1153,8 +1205,10 @@ QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len) num_valid_chan = *list_len; } *list_len = num_valid_chan; - qdf_mem_copy(chan_list, mac_ctx->mlme_cfg->reg.valid_channel_list, - *list_len); + for (i = 0; i < *list_len; i++) { + ch_freq_list[i] = + mac_ctx->mlme_cfg->reg.valid_channel_freq_list[i]; + } return QDF_STATUS_SUCCESS; } @@ -1162,7 +1216,7 @@ QDF_STATUS sme_get_valid_channels(uint8_t *chan_list, uint32_t *list_len) #ifdef WLAN_CONV_SPECTRAL_ENABLE static QDF_STATUS sme_register_spectral_cb(struct mac_context *mac_ctx) { - struct spectral_legacy_cbacks spectral_cb; + struct spectral_legacy_cbacks spectral_cb = {0}; QDF_STATUS status; spectral_cb.vdev_get_chan_freq = sme_get_oper_chan_freq; @@ -1201,7 +1255,6 @@ QDF_STATUS sme_start(mac_handle_t mac_handle) break; } sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; - sme_cbacks.sme_get_valid_channels = sme_get_valid_channels; sme_cbacks.sme_nss_update_request = sme_nss_update_request; sme_cbacks.sme_pdev_set_hw_mode = sme_pdev_set_hw_mode; sme_cbacks.sme_pdev_set_pcl = sme_pdev_set_pcl; @@ -1400,7 +1453,7 @@ static QDF_STATUS sme_extended_change_channel_ind(struct mac_context *mac_ctx, if (!roam_info) return QDF_STATUS_E_NOMEM; session_id = ext_chan_ind->session_id; - roam_info->target_channel = ext_chan_ind->new_channel; + roam_info->target_chan_freq = ext_chan_ind->new_chan_freq; roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND; roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND; sme_debug("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]", @@ -1471,11 +1524,12 @@ QDF_STATUS sme_set_plm_request(mac_handle_t mac_handle, QDF_STATUS status; bool ret = false; struct mac_context *mac = MAC_CONTEXT(mac_handle); - uint8_t ch_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t count, valid_count = 0; struct scheduler_msg msg = {0}; struct csr_roam_session *session; struct plm_req_params *body; + uint32_t ch_freq; if (!req) return QDF_STATUS_E_FAILURE; @@ -1512,20 +1566,20 @@ QDF_STATUS sme_set_plm_request(mac_handle_t mac_handle, goto send_plm_start; /* validating channel numbers */ for (count = 0; count < body->plm_num_ch; count++) { - uint8_t ch = body->plm_ch_list[count]; - - ret = csr_is_supported_channel(mac, ch); + ch_freq = body->plm_ch_freq_list[count]; + ret = csr_is_supported_channel(mac, ch_freq); if (!ret) { /* Not supported, ignore the channel */ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("Unsupported channel %d ignored for PLM"), - ch); + FL("Unsupported freq %d ignored for PLM"), + ch_freq); continue; } - if (ch > 14) { + if (ch_freq > 2477) { enum channel_state state = - wlan_reg_get_channel_state(mac->pdev, ch); + wlan_reg_get_channel_state_for_freq( + mac->pdev, ch_freq); if (state == CHANNEL_STATE_DFS) { /* DFS channel is provided, no PLM bursts can be @@ -1534,17 +1588,17 @@ QDF_STATUS sme_set_plm_request(mac_handle_t mac_handle, QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, FL("DFS channel %d ignored for PLM"), - ch); + ch_freq); continue; } } - ch_list[valid_count++] = ch; + ch_freq_list[valid_count++] = ch_freq; } /* End of for () */ /* Copying back the valid channel list to plm struct */ - qdf_mem_zero(body->plm_ch_list, body->plm_num_ch); + qdf_mem_zero(body->plm_ch_freq_list, body->plm_num_ch); if (valid_count) - qdf_mem_copy(body->plm_ch_list, ch_list, valid_count); + qdf_mem_copy(body->plm_ch_freq_list, ch_freq_list, valid_count); /* All are invalid channels, FW need to send the PLM * report with "incapable" bit set. */ @@ -1643,56 +1697,56 @@ QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle, { QDF_STATUS status; struct mac_context *mac = MAC_CONTEXT(mac_handle); - tpSirBeaconReportReqInd pSmeBcnReportReq = NULL; - const tCsrEseBeaconReqParams *pBeaconReq = NULL; + tpSirBeaconReportReqInd sme_bcn_rpt_req = NULL; + const tCsrEseBeaconReqParams *bcn_req = NULL; uint8_t counter = 0; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext[0]; + struct csr_roam_session *session = CSR_GET_SESSION(mac, sessionId); + tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext[0]; - if (pSmeRrmContext->eseBcnReqInProgress == true) { + if (sme_rrm_ctx->eseBcnReqInProgress == true) { sme_err("A Beacon Report Req is already in progress"); return QDF_STATUS_E_RESOURCES; } /* Store the info in RRM context */ - qdf_mem_copy(&pSmeRrmContext->eseBcnReqInfo, in_req, + qdf_mem_copy(&sme_rrm_ctx->eseBcnReqInfo, in_req, sizeof(tCsrEseBeaconReq)); /* Prepare the request to send to SME. */ - pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); - if (!pSmeBcnReportReq) + sme_bcn_rpt_req = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); + if (!sme_bcn_rpt_req) return QDF_STATUS_E_NOMEM; - pSmeRrmContext->eseBcnReqInProgress = true; + sme_rrm_ctx->eseBcnReqInProgress = true; sme_debug("Sending Beacon Report Req to SME"); - pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; - pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd); - qdf_mem_copy(pSmeBcnReportReq->bssId, - pSession->connectedProfile.bssid.bytes, + sme_bcn_rpt_req->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + sme_bcn_rpt_req->length = sizeof(tSirBeaconReportReqInd); + qdf_mem_copy(sme_bcn_rpt_req->bssId, + session->connectedProfile.bssid.bytes, sizeof(tSirMacAddr)); - pSmeBcnReportReq->channelInfo.channelNum = 255; - pSmeBcnReportReq->channelList.numChannels = in_req->numBcnReqIe; - pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; - pSmeBcnReportReq->measurement_idx = 0; + sme_bcn_rpt_req->channel_info.chan_num = 255; + sme_bcn_rpt_req->channel_list.num_channels = in_req->numBcnReqIe; + sme_bcn_rpt_req->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; + sme_bcn_rpt_req->measurement_idx = 0; for (counter = 0; counter < in_req->numBcnReqIe; counter++) { - pBeaconReq = &in_req->bcnReq[counter]; - pSmeBcnReportReq->fMeasurementtype[counter] = - pBeaconReq->scanMode; - pSmeBcnReportReq->measurementDuration[counter] = - SYS_TU_TO_MS(pBeaconReq->measurementDuration); - pSmeBcnReportReq->channelList.channelNumber[counter] = - pBeaconReq->channel; + bcn_req = &in_req->bcnReq[counter]; + sme_bcn_rpt_req->fMeasurementtype[counter] = + bcn_req->scanMode; + sme_bcn_rpt_req->measurementDuration[counter] = + SYS_TU_TO_MS(bcn_req->measurementDuration); + sme_bcn_rpt_req->channel_list.chan_freq_lst[counter] = + bcn_req->ch_freq; } - status = sme_rrm_process_beacon_report_req_ind(mac, pSmeBcnReportReq); + status = sme_rrm_process_beacon_report_req_ind(mac, sme_bcn_rpt_req); if (status != QDF_STATUS_SUCCESS) - pSmeRrmContext->eseBcnReqInProgress = false; + sme_rrm_ctx->eseBcnReqInProgress = false; - qdf_mem_free(pSmeBcnReportReq); + qdf_mem_free(sme_bcn_rpt_req); return status; } @@ -1712,7 +1766,7 @@ QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle, */ QDF_STATUS sme_get_tsm_stats(mac_handle_t mac_handle, tCsrTsmStatsCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, + struct qdf_mac_addr bssId, void *pContext, uint8_t tid) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -1721,50 +1775,18 @@ QDF_STATUS sme_get_tsm_stats(mac_handle_t mac_handle, status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { status = csr_get_tsm_stats(mac, callback, - staId, bssId, pContext, + bssId, pContext, tid); sme_release_global_lock(&mac->sme); } return status; } -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -QDF_STATUS sme_get_roam_scan_ch(mac_handle_t mac_handle, - uint8_t vdev_id, void *pcontext) -{ - struct scheduler_msg msg = {0}; - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_ERROR(status)) - return QDF_STATUS_E_FAILURE; - - msg.type = WMA_ROAM_SCAN_CH_REQ; - msg.bodyval = vdev_id; - mac->sme.roam_scan_ch_get_context = pcontext; - - if (scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, - &msg)) { - sme_err("Posting message %d failed", - WMA_ROAM_SCAN_CH_REQ); - mac->sme.roam_scan_ch_get_context = NULL; - sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_FAILURE; - } - - sme_release_global_lock(&mac->sme); - return QDF_STATUS_SUCCESS; -} -#endif - /** * sme_set_ese_roam_scan_channel_list() - To set ese roam scan channel list * @mac_handle: Opaque handle to the global MAC context * @sessionId: sme session id - * @pChannelList: Output channel list + * @chan_freq_list: Output channel list * @numChannels: Output number of channels * * This routine is called to set ese roam scan channel list. @@ -1774,17 +1796,18 @@ QDF_STATUS sme_get_roam_scan_ch(mac_handle_t mac_handle, */ QDF_STATUS sme_set_ese_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t *pChannelList, + uint32_t *chan_freq_list, uint8_t numChannels) { struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS status = QDF_STATUS_SUCCESS; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; tpCsrChannelInfo curchnl_list_info = NULL; - uint8_t oldChannelList[CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; - uint8_t newChannelList[128] = { 0 }; + uint8_t oldChannelList[CFG_VALID_CHANNEL_LIST_LEN * 5] = { 0 }; + uint8_t newChannelList[CFG_VALID_CHANNEL_LIST_LEN * 5] = { 0 }; uint8_t i = 0, j = 0; enum band_info band = -1; + uint32_t band_bitmap; if (sessionId >= WLAN_MAX_VDEVS) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -1800,24 +1823,25 @@ QDF_STATUS sme_set_ese_roam_scan_channel_list(mac_handle_t mac_handle, if (!QDF_IS_STATUS_SUCCESS(status)) return status; - if (curchnl_list_info->ChannelList) { + if (curchnl_list_info->freq_list) { for (i = 0; i < curchnl_list_info->numOfChannels; i++) { j += snprintf(oldChannelList + j, sizeof(oldChannelList) - j, "%d", - curchnl_list_info->ChannelList[i]); + curchnl_list_info->freq_list[i]); } } - ucfg_reg_get_band(mac->pdev, &band); + ucfg_reg_get_band(mac->pdev, &band_bitmap); + band = wlan_reg_band_bitmap_to_band_info(band_bitmap); status = csr_create_roam_scan_channel_list(mac, sessionId, - pChannelList, numChannels, + chan_freq_list, numChannels, band); if (QDF_IS_STATUS_SUCCESS(status)) { - if (curchnl_list_info->ChannelList) { + if (curchnl_list_info->freq_list) { j = 0; for (i = 0; i < curchnl_list_info->numOfChannels; i++) { j += snprintf(newChannelList + j, sizeof(newChannelList) - j, "%d", - curchnl_list_info->ChannelList[i]); + curchnl_list_info->freq_list[i]); } } QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -1836,6 +1860,46 @@ QDF_STATUS sme_set_ese_roam_scan_channel_list(mac_handle_t mac_handle, #endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS sme_get_roam_scan_ch(mac_handle_t mac_handle, + uint8_t vdev_id, void *pcontext) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; + + msg.type = WMA_ROAM_SCAN_CH_REQ; + msg.bodyval = vdev_id; + mac->sme.roam_scan_ch_get_context = pcontext; + + if (scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &msg)) { + sme_err("Posting message %d failed", + WMA_ROAM_SCAN_CH_REQ); + mac->sme.roam_scan_ch_get_context = NULL; + sme_release_global_lock(&mac->sme); + return QDF_STATUS_E_FAILURE; + } + + sme_release_global_lock(&mac->sme); + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef QCA_IBSS_SUPPORT +/** + * sme_ibss_peer_info_response_handler() - Handler for ibss peer info + * @mac: Global MAC pointer + * @sme_ibss_peer_info_response_handler: ibss peer info params + * + * Return: QDF_STATUS + */ static QDF_STATUS sme_ibss_peer_info_response_handler(struct mac_context *mac, tpSirIbssGetPeerInfoRspParams @@ -1859,6 +1923,63 @@ QDF_STATUS sme_ibss_peer_info_response_handler(struct mac_context *mac, return QDF_STATUS_SUCCESS; } +QDF_STATUS sme_request_ibss_peer_info(mac_handle_t mac_handle, void *cb_context, + ibss_peer_info_cb peer_info_cb, + bool allPeerInfoReqd, uint8_t *mac_addr) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct scheduler_msg message = {0}; + tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams; + struct ibss_peer_info_cb_info *cb_info; + + status = sme_acquire_global_lock(&mac->sme); + if (status == QDF_STATUS_SUCCESS) { + cb_info = &mac->sme.peer_info_cb_info; + cb_info->peer_info_cb = peer_info_cb; + cb_info->peer_info_cb_context = cb_context; + + pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *) + qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams)); + if (!pIbssInfoReqParams) { + sme_release_global_lock(&mac->sme); + return QDF_STATUS_E_NOMEM; + } + pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd; + qdf_mem_copy(pIbssInfoReqParams->peer_mac.bytes, mac_addr, + QDF_MAC_ADDR_SIZE); + + message.type = WMA_GET_IBSS_PEER_INFO_REQ; + message.bodyptr = pIbssInfoReqParams; + message.reserved = 0; + + qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &message); + if (qdf_status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + "%s: Post WMA_GET_IBSS_PEER_INFO_REQ MSG failed", + __func__); + qdf_mem_free(pIbssInfoReqParams); + qdf_status = QDF_STATUS_E_FAILURE; + } + sme_release_global_lock(&mac->sme); + } + + return qdf_status; +} +#else +static inline +QDF_STATUS sme_ibss_peer_info_response_handler(struct mac_context *mac, + tpSirIbssGetPeerInfoRspParams + pIbssPeerInfoParams) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * sme_process_dual_mac_config_resp() - Process set Dual mac config response * @mac: Global MAC pointer @@ -2037,8 +2158,6 @@ static QDF_STATUS sme_process_antenna_mode_resp(struct mac_context *mac, QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct sir_peer_info *peer_stats; - struct sir_peer_info_resp *peer_info_rsp; if (!pMsg) { sme_err("Empty message for SME"); @@ -2088,19 +2207,9 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) sme_err("Empty message for: %d", pMsg->type); } break; - case eWNI_SME_ADD_STA_SELF_RSP: + case eWNI_SME_VDEV_DELETE_RSP: if (pMsg->bodyptr) { - status = csr_process_add_sta_session_rsp(mac, - pMsg->bodyptr); - qdf_mem_free(pMsg->bodyptr); - } else { - sme_err("Empty message for: %d", pMsg->type); - } - break; - case eWNI_SME_DEL_STA_SELF_RSP: - if (pMsg->bodyptr) { - status = csr_process_del_sta_session_rsp(mac, - pMsg->bodyptr); + status = csr_process_vdev_del_rsp(mac, pMsg->bodyptr); qdf_mem_free(pMsg->bodyptr); } else { sme_err("Empty message for: %d", pMsg->type); @@ -2115,7 +2224,6 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) sme_err("Empty message for: %d", pMsg->type); } break; - #ifdef WLAN_FEATURE_11W case eWNI_SME_UNPROT_MGMT_FRM_IND: if (pMsg->bodyptr) { @@ -2190,23 +2298,6 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) status = sme_stats_ext_event(mac, pMsg->bodyptr); qdf_mem_free(pMsg->bodyptr); break; - case eWNI_SME_GET_PEER_INFO_IND: - if (mac->sme.pget_peer_info_ind_cb) - mac->sme.pget_peer_info_ind_cb(pMsg->bodyptr, - mac->sme.pget_peer_info_cb_context); - if (pMsg->bodyptr) { - peer_info_rsp = (struct sir_peer_info_resp *) - (pMsg->bodyptr); - peer_stats = (struct sir_peer_info *) - (peer_info_rsp->info); - if (peer_stats) { - mac->peer_rssi = peer_stats[0].rssi; - mac->peer_txrate = peer_stats[0].tx_rate; - mac->peer_rxrate = peer_stats[0].rx_rate; - } - } - qdf_mem_free(pMsg->bodyptr); - break; case eWNI_SME_GET_PEER_INFO_EXT_IND: if (mac->sme.pget_peer_info_ext_ind_cb) mac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr, @@ -2252,9 +2343,8 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) if (pSnrReq) { if (pSnrReq->snrCallback) { ((tCsrSnrCallback) - (pSnrReq->snrCallback)) - (pSnrReq->snr, pSnrReq->staId, - pSnrReq->pDevContext); + (pSnrReq->snrCallback))(pSnrReq->snr, + pSnrReq->pDevContext); } qdf_mem_free(pSnrReq); } @@ -2383,8 +2473,7 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) qdf_mem_free(pMsg->bodyptr); break; case eWNI_SME_MONITOR_MODE_VDEV_UP: - status = csr_process_monitor_mode_vdev_up_evt(mac, - pMsg->bodyval); + status = sme_process_monitor_mode_vdev_up_evt(pMsg->bodyval); break; default: @@ -2534,6 +2623,8 @@ QDF_STATUS sme_close(mac_handle_t mac_handle) if (!mac) return QDF_STATUS_E_FAILURE; + sme_unregister_power_debug_stats_cb(mac); + status = csr_close(mac); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err("csr_close failed with status: %d", status); @@ -2594,29 +2685,19 @@ QDF_STATUS sme_remove_bssid_from_scan_list(mac_handle_t mac_handle, return status; } - -/* - * sme_scan_get_result - * A wrapper function to request scan results from CSR. - * This is a synchronous call - * - * pFilter - If pFilter is NULL, all cached results are returned - * phResult - an object for the result. - * Return QDF_STATUS - */ -QDF_STATUS sme_scan_get_result(mac_handle_t mac_handle, uint8_t sessionId, - tCsrScanResultFilter *pFilter, +QDF_STATUS sme_scan_get_result(mac_handle_t mac_handle, uint8_t vdev_id, + struct scan_filter *filter, tScanResultHandle *phResult) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); MTRACE(qdf_trace(QDF_MODULE_ID_SME, - TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, vdev_id, 0)); status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_scan_get_result(mac, pFilter, phResult); + status = csr_scan_get_result(mac, filter, phResult); sme_release_global_lock(&mac->sme); } @@ -2639,29 +2720,17 @@ QDF_STATUS sme_scan_get_result_for_bssid(mac_handle_t mac_handle, return status; } -/** - * sme_get_ap_channel_from_scan() - a wrapper function to get - * AP's channel id from - * CSR by filtering the - * result which matches - * our roam profile. - * @profile: SAP profile - * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the - * best ap from scan cache. - * - * This function is written to get AP's channel id from CSR by filtering - * the result which matches our roam profile. This is a synchronous call. - * - * Return: QDF_STATUS. - */ QDF_STATUS sme_get_ap_channel_from_scan(void *profile, tScanResultHandle *scan_cache, - uint8_t *ap_chnl_id) + uint32_t *ap_ch_freq) { - return sme_get_ap_channel_from_scan_cache((struct csr_roam_profile *) + QDF_STATUS status; + + status = sme_get_ap_channel_from_scan_cache((struct csr_roam_profile *) profile, scan_cache, - ap_chnl_id); + ap_ch_freq); + return status; } /** @@ -2669,7 +2738,7 @@ QDF_STATUS sme_get_ap_channel_from_scan(void *profile, * channel id from CSR by filtering the * result which matches our roam profile. * @profile: SAP adapter - * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the + * @ap_ch_freq: pointer to channel freq of SAP. Fill the value after finding the * best ap from scan cache. * * This function is written to get AP's channel id from CSR by filtering @@ -2679,11 +2748,11 @@ QDF_STATUS sme_get_ap_channel_from_scan(void *profile, */ QDF_STATUS sme_get_ap_channel_from_scan_cache( struct csr_roam_profile *profile, tScanResultHandle *scan_cache, - uint8_t *ap_chnl_id) + uint32_t *ap_ch_freq) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac_ctx = sme_get_mac_context(); - tCsrScanResultFilter *scan_filter = NULL; + struct scan_filter *scan_filter; tScanResultHandle filtered_scan_result = NULL; struct bss_description first_ap_profile; @@ -2692,34 +2761,24 @@ QDF_STATUS sme_get_ap_channel_from_scan_cache( FL("mac_ctx is NULL")); return QDF_STATUS_E_FAILURE; } - scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); if (!scan_filter) return QDF_STATUS_E_FAILURE; qdf_mem_zero(&first_ap_profile, sizeof(struct bss_description)); if (!profile) { - scan_filter->EncryptionType.numEntries = 1; - scan_filter->EncryptionType.encryptionType[0] - = eCSR_ENCRYPT_TYPE_NONE; + /* No encryption */ + scan_filter->num_of_enc_type = 1; + scan_filter->enc_type[0] = WLAN_ENCRYPT_TYPE_NONE; } else { /* Here is the profile we need to connect to */ - status = csr_roam_prepare_filter_from_profile(mac_ctx, - profile, - scan_filter); + status = csr_roam_get_scan_filter_from_profile(mac_ctx, + profile, + scan_filter, + false); } - if (QDF_STATUS_SUCCESS == status) { - /* Save the WPS info */ - if (profile) { - scan_filter->bWPSAssociation = - profile->bWPSAssociation; - scan_filter->bOSENAssociation = - profile->bOSENAssociation; - } else { - scan_filter->bWPSAssociation = 0; - scan_filter->bOSENAssociation = 0; - } - } else { + if (QDF_IS_STATUS_ERROR(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, FL("Preparing the profile filter failed")); qdf_mem_free(scan_filter); @@ -2733,19 +2792,19 @@ QDF_STATUS sme_get_ap_channel_from_scan_cache( csr_get_bssdescr_from_scan_handle(filtered_scan_result, &first_ap_profile); *scan_cache = filtered_scan_result; - if (0 != first_ap_profile.channelId) { - *ap_chnl_id = first_ap_profile.channelId; + if (first_ap_profile.chan_freq) { + *ap_ch_freq = first_ap_profile.chan_freq; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("Found best AP & its on chnl[%d]"), - first_ap_profile.channelId); + FL("Found best AP & its on freq[%d]"), + first_ap_profile.chan_freq); } else { /* * This means scan result is empty * so set the channel to zero, caller should * take of zero channel id case. */ - *ap_chnl_id = 0; + *ap_ch_freq = 0; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, FL("Scan is empty, set chnl to 0")); @@ -2755,13 +2814,12 @@ QDF_STATUS sme_get_ap_channel_from_scan_cache( sme_err("Failed to get scan get result"); status = QDF_STATUS_E_FAILURE; } - csr_free_scan_filter(mac_ctx, scan_filter); sme_release_global_lock(&mac_ctx->sme); } else { - csr_free_scan_filter(mac_ctx, scan_filter); status = QDF_STATUS_E_FAILURE; } qdf_mem_free(scan_filter); + return status; } @@ -3156,69 +3214,31 @@ void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile) csr_roam_free_connect_profile(profile); } -/* - * sme_roam_set_pmkid_cache() - - * A wrapper function to request CSR to return the PMKID candidate list - * This is a synchronous call. - - * pPMKIDCache - caller allocated buffer point to an array of - * tPmkidCacheInfo - * numItems - a variable that has the number of tPmkidCacheInfo - * allocated when retruning, this is either the number needed - * or number of items put into pPMKIDCache - * update_entire_cache - this bool value specifies if the entire pmkid - * cache should be overwritten or should it be - * updated entry by entry. - * Return QDF_STATUS - when fail, it usually means the buffer allocated is not - * big enough and pNumItems has the number of - * tPmkidCacheInfo. - * \Note: pNumItems is a number of tPmkidCacheInfo, - * not sizeof(tPmkidCacheInfo) * something - */ -QDF_STATUS sme_roam_set_pmkid_cache(mac_handle_t mac_handle, uint8_t sessionId, - tPmkidCacheInfo *pPMKIDCache, - uint32_t numItems, bool update_entire_cache) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - - MTRACE(qdf_trace(QDF_MODULE_ID_SME, - TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId, - numItems)); - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(status)) { - if (CSR_IS_SESSION_VALID(mac, sessionId)) - status = csr_roam_set_pmkid_cache(mac, sessionId, - pPMKIDCache, - numItems, update_entire_cache); - else - status = QDF_STATUS_E_INVAL; - sme_release_global_lock(&mac->sme); - } - - return status; -} - QDF_STATUS sme_roam_del_pmkid_from_cache(mac_handle_t mac_handle, - uint8_t sessionId, - tPmkidCacheInfo *pmksa, - bool flush_cache) + uint8_t vdev_id, + struct wlan_crypto_pmksa *pmksa, + bool set_pmk) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); + struct wlan_objmgr_vdev *vdev; MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, - sessionId, flush_cache)); - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(status)) { - if (CSR_IS_SESSION_VALID(mac, sessionId)) - status = csr_roam_del_pmkid_from_cache(mac, sessionId, - pmksa, flush_cache); - else - status = QDF_STATUS_E_INVAL; - sme_release_global_lock(&mac->sme); + vdev_id, set_pmk)); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Vdev[%d] is NULL!", vdev_id); + return QDF_STATUS_E_FAILURE; } + + status = wlan_crypto_set_del_pmksa(vdev, pmksa, set_pmk); + if (QDF_IS_STATUS_ERROR(status)) + sme_err("Delete PMK entry failed"); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return status; } @@ -3488,75 +3508,6 @@ QDF_STATUS sme_oem_get_capability(mac_handle_t mac_handle, } #endif -/** - * sme_roam_set_key() - To set encryption key. - * @mac_handle: mac_handle global context - * @session_id: session id - * @set_key: pointer to a caller allocated object of tCsrSetContextInfo - * @ptr_roam_id: Upon success return, this is the id caller can use to - * identify the request in roamcallback - * - * This function should be called only when connected. This is an asynchronous - * API. - * - * Return: Status of operation - */ -QDF_STATUS sme_roam_set_key(mac_handle_t mac_handle, uint8_t session_id, - tCsrRoamSetKey *set_key, uint32_t *ptr_roam_id) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - uint32_t roam_id; - struct csr_roam_session *session = NULL; - struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; - - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_KEY, - session_id, 0)); - if (set_key->keyLength > CSR_MAX_KEY_LEN) { - sme_err("Invalid key length: %d", set_key->keyLength); - return QDF_STATUS_E_FAILURE; - } - /*Once Setkey is done, we can go in BMPS */ - if (set_key->keyLength) - ps_global_info->remain_in_power_active_till_dhcp = false; - - status = sme_acquire_global_lock(&mac_ctx->sme); - if (!QDF_IS_STATUS_SUCCESS(status)) - return status; - - roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam); - if (ptr_roam_id) - *ptr_roam_id = roam_id; - - sme_debug("keyLength: %d", set_key->keyLength); - - sme_debug("Session_id: %d roam_id: %d", session_id, roam_id); - session = CSR_GET_SESSION(mac_ctx, session_id); - if (!session) { - sme_err("session %d not found", session_id); - sme_release_global_lock(&mac_ctx->sme); - return QDF_STATUS_E_FAILURE; - } - if (CSR_IS_INFRA_AP(&session->connectedProfile) - && set_key->keyDirection == eSIR_TX_DEFAULT) { - if ((eCSR_ENCRYPT_TYPE_WEP40 == set_key->encType) - || (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == - set_key->encType)) { - session->pCurRoamProfile->negotiatedUCEncryptionType = - eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; - } - if ((eCSR_ENCRYPT_TYPE_WEP104 == set_key->encType) - || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == - set_key->encType)) { - session->pCurRoamProfile->negotiatedUCEncryptionType = - eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; - } - } - status = csr_roam_set_key(mac_ctx, session_id, set_key, roam_id); - sme_release_global_lock(&mac_ctx->sme); - return status; -} - /** * sme_roam_set_default_key_index - To set default wep key idx * @mac_handle: Opaque handle to the global MAC context @@ -3597,41 +3548,6 @@ QDF_STATUS sme_roam_set_default_key_index(mac_handle_t mac_handle, return QDF_STATUS_SUCCESS; } - -/** - * sme_get_rssi() - API to retrieve current RSSI - * @mac_handle: Opaque handle to the global MAC context - * @callback: SME sends back the requested stats using the callback - * @staId: The station ID for which the RSSI is requested for - * @bssid: The bssid of the connected session - * @lastRSSI: RSSI value at time of request. In case fw cannot provide - * RSSI, do not hold up but return this value. - * @pContext: user context to be passed back along with the callback - * - * A wrapper function that client calls to register a callback to get RSSI - * - * Return: QDF_STATUS - */ -QDF_STATUS sme_get_rssi(mac_handle_t mac_handle, - tCsrRssiCallback callback, uint8_t staId, - struct qdf_mac_addr bssId, int8_t lastRSSI, - void *pContext) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - - MTRACE(qdf_trace(QDF_MODULE_ID_SME, - TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION, 0)); - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_get_rssi(mac, callback, - staId, bssId, lastRSSI, - pContext); - sme_release_global_lock(&mac->sme); - } - return status; -} - /* * sme_get_snr() - * A wrapper function that client calls to register a callback to get SNR @@ -3644,59 +3560,19 @@ QDF_STATUS sme_get_rssi(mac_handle_t mac_handle, */ QDF_STATUS sme_get_snr(mac_handle_t mac_handle, tCsrSnrCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext) + struct qdf_mac_addr bssId, void *pContext) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_get_snr(mac, callback, staId, bssId, pContext); + status = csr_get_snr(mac, callback, bssId, pContext); sme_release_global_lock(&mac->sme); } return status; } -#ifndef QCA_SUPPORT_CP_STATS -/* - * sme_get_statistics() - - * A wrapper function that client calls to register a callback to get - * different PHY level statistics from CSR. - * - * requesterId - different client requesting for statistics, - * HDD, UMA/GAN etc - * statsMask - The different category/categories of stats requester - * is looking for - * callback - SME sends back the requested stats using the callback - * periodicity - If requester needs periodic update in millisec, 0 means - * it's an one time request - * cache - If requester is happy with cached stats - * staId - The station ID for which the stats is requested for - * pContext - user context to be passed back along with the callback - * sessionId - sme session interface - * Return QDF_STATUS - */ -QDF_STATUS sme_get_statistics(mac_handle_t mac_handle, - eCsrStatsRequesterType requesterId, - uint32_t statsMask, tCsrStatsCallback callback, - uint8_t staId, void *pContext, uint8_t sessionId) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_get_statistics(mac, requesterId, statsMask, - callback, staId, pContext, - sessionId); - sme_release_global_lock(&mac->sme); - } - - return status; - -} -#endif - QDF_STATUS sme_get_link_status(mac_handle_t mac_handle, csr_link_status_callback callback, void *context, uint8_t session_id) @@ -4102,10 +3978,15 @@ QDF_STATUS sme_oem_req_cmd(mac_handle_t mac_handle, #ifdef FEATURE_OEM_DATA QDF_STATUS sme_oem_data_cmd(mac_handle_t mac_handle, - struct oem_data *oem_data) + void (*oem_data_event_handler_cb) + (const struct oem_data *oem_event_data, + uint8_t vdev_id), + struct oem_data *oem_data, + uint8_t vdev_id) { QDF_STATUS status; void *wma_handle; + struct mac_context *mac = MAC_CONTEXT(mac_handle); SME_ENTER(); wma_handle = cds_get_context(QDF_MODULE_ID_WMA); @@ -4114,6 +3995,12 @@ QDF_STATUS sme_oem_data_cmd(mac_handle_t mac_handle, return QDF_STATUS_E_FAILURE; } + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + mac->sme.oem_data_event_handler_cb = oem_data_event_handler_cb; + mac->sme.oem_data_vdev_id = vdev_id; + sme_release_global_lock(&mac->sme); + } status = wma_start_oem_data_cmd(wma_handle, oem_data); if (!QDF_IS_STATUS_SUCCESS(status)) sme_err("fail to call wma_start_oem_data_cmd."); @@ -4684,65 +4571,89 @@ sme_nss_chains_update(mac_handle_t mac_handle, return status; } -QDF_STATUS sme_open_session(mac_handle_t mac_handle, - struct sme_session_params *params) +struct wlan_objmgr_vdev *sme_vdev_create(mac_handle_t mac_handle, + struct wlan_vdev_create_params *vdev_params) { QDF_STATUS status = QDF_STATUS_E_INVAL; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - struct cdp_pdev *pdev; - ol_txrx_peer_handle peer; - uint8_t peer_id; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); + uint8_t vdev_id; + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *vdev_mlme; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s: type=%d, session_id %d subType=%d addr:%pM", - __func__, params->type_of_persona, - params->sme_session_id, params->subtype_of_persona, - params->self_mac_addr); + sme_debug("addr:"QDF_MAC_ADDR_FMT" opmode:%d", + QDF_MAC_ADDR_REF(vdev_params->macaddr), + vdev_params->opmode); - pdev = cds_get_context(QDF_MODULE_ID_TXRX); + vdev = wlan_objmgr_vdev_obj_create(mac_ctx->pdev, vdev_params); + if (!vdev) { + sme_err("Failed to create vdev object"); + return NULL; + } - if (!pdev) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Failed to get pdev handler", __func__); - return status; + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_SME_ID) != + QDF_STATUS_SUCCESS) { + wlan_objmgr_vdev_obj_delete(vdev); + return NULL; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + sme_err("Failed to get vdev mlme obj!"); + QDF_BUG(0); + goto vdev_obj_del; + } + + vdev_id = wlan_vdev_get_id(vdev); + status = wma_post_vdev_create_setup(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to setup wma for vdev: %d", vdev_id); + goto vdev_obj_del; } - status = sme_acquire_global_lock(&mac_ctx->sme); - if (QDF_IS_STATUS_ERROR(status)) - return status; + status = csr_setup_vdev_session(vdev_mlme); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to setup CSR layer for vdev: %d", vdev_id); + goto cleanup_wma; + } - peer = cdp_peer_find_by_addr(soc, pdev, params->self_mac_addr, - &peer_id); - if (peer) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Peer=%d exist with same MAC", - __func__, peer_id); - status = QDF_STATUS_E_INVAL; - } else { - status = csr_roam_open_session(mac_ctx, params); + status = mlme_vdev_self_peer_create(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to create vdev selfpeer for vdev:%d", vdev_id); + goto csr_cleanup_vdev_session; } - sme_release_global_lock(&mac_ctx->sme); + MTRACE(qdf_trace(QDF_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION, + vdev_id, 0)); - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION, - params->sme_session_id, 0)); + return vdev; - return status; +csr_cleanup_vdev_session: + csr_cleanup_vdev_session(mac_ctx, vdev_id); +cleanup_wma: + wma_cleanup_vdev(vdev); +vdev_obj_del: + wlan_objmgr_vdev_obj_delete(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return NULL; } -QDF_STATUS sme_close_session(mac_handle_t mac_handle, uint8_t session_id) +QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, + struct wlan_objmgr_vdev *vdev) { QDF_STATUS status; struct mac_context *mac = MAC_CONTEXT(mac_handle); + uint8_t vdev_id = wlan_vdev_get_id(vdev); MTRACE(qdf_trace(QDF_MODULE_ID_SME, - TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, session_id, 0)); + TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, vdev_id, 0)); status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_roam_close_session(mac, session_id, false); + status = csr_roam_vdev_delete(mac, vdev_id, false); sme_release_global_lock(&mac->sme); } + /* Release the reference acquired during vdev create */ + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return status; } @@ -4754,7 +4665,7 @@ void sme_cleanup_session(mac_handle_t mac_handle, uint8_t vdev_id) status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_ERROR(status)) return; - csr_cleanup_session(mac, vdev_id); + csr_cleanup_vdev_session(mac, vdev_id); sme_release_global_lock(&mac->sme); } @@ -4885,7 +4796,7 @@ QDF_STATUS sme_set_keep_alive(mac_handle_t mac_handle, uint8_t session_id, * QDF_STATUS_E_FAILURE */ QDF_STATUS sme_get_operation_channel(mac_handle_t mac_handle, - uint32_t *pChannel, + uint32_t *chan_freq, uint8_t sessionId) { struct mac_context *mac = MAC_CONTEXT(mac_handle); @@ -4902,7 +4813,7 @@ QDF_STATUS sme_get_operation_channel(mac_handle_t mac_handle, eCSR_BSS_TYPE_INFRA_AP) || (pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)) { - *pChannel = pSession->connectedProfile.operationChannel; + *chan_freq = pSession->connectedProfile.op_freq; return QDF_STATUS_SUCCESS; } } @@ -5067,14 +4978,14 @@ QDF_STATUS sme_deregister_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId, /** * sme_prepare_mgmt_tx() - Prepares mgmt frame * @mac_handle: The handle returned by mac_open - * @session_id: session id + * @vdev_id: vdev id * @buf: pointer to frame * @len: frame length * * Return: QDF_STATUS */ static QDF_STATUS sme_prepare_mgmt_tx(mac_handle_t mac_handle, - uint8_t session_id, + uint8_t vdev_id, const uint8_t *buf, uint32_t len) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -5091,7 +5002,7 @@ static QDF_STATUS sme_prepare_mgmt_tx(mac_handle_t mac_handle, } else { msg->type = eWNI_SME_SEND_MGMT_FRAME_TX; msg->msg_len = msg_len; - msg->session_id = session_id; + msg->vdev_id = vdev_id; msg->data = (uint8_t *)msg + sizeof(*msg); qdf_mem_copy(msg->data, buf, len); @@ -5270,46 +5181,44 @@ QDF_STATUS sme_configure_app_type2_params(mac_handle_t mac_handle, } #endif -uint8_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle, - uint8_t vdev_id_to_skip) +uint32_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle, + uint8_t vdev_id_to_skip) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); - uint8_t channel = 0; + uint32_t chan_freq = 0; status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - channel = csr_get_beaconing_concurrent_channel(mac, + chan_freq = csr_get_beaconing_concurrent_channel(mac, vdev_id_to_skip); - sme_info("Other Concurrent Channel: %d skipped vdev_id %d", - channel, vdev_id_to_skip); + sme_info("Other Concurrent Chan_freq: %d skipped vdev_id %d", + chan_freq, vdev_id_to_skip); sme_release_global_lock(&mac->sme); } - return channel; + return chan_freq; } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH uint16_t sme_check_concurrent_channel_overlap(mac_handle_t mac_handle, - uint16_t sap_ch, + uint16_t sap_ch_freq, eCsrPhyMode sapPhyMode, uint8_t cc_switch_mode) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); - uint16_t channel = 0; + uint16_t intf_ch_freq = 0; status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - channel = - csr_check_concurrent_channel_overlap(mac, sap_ch, - sapPhyMode, - cc_switch_mode); + intf_ch_freq = csr_check_concurrent_channel_overlap( + mac, sap_ch_freq, sapPhyMode, cc_switch_mode); sme_release_global_lock(&mac->sme); } - return channel; + return intf_ch_freq; } #endif @@ -5398,11 +5307,12 @@ QDF_STATUS sme_set_tsf_gpio(mac_handle_t mac_handle, uint32_t pinvalue) } #endif -QDF_STATUS sme_get_cfg_valid_channels(uint8_t *aValidChannels, - uint32_t *len) +QDF_STATUS sme_get_cfg_valid_channels(uint32_t *valid_ch_freq, uint32_t *len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac_ctx = sme_get_mac_context(); + uint32_t *valid_ch_freq_list; + uint32_t i; if (!mac_ctx) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -5410,13 +5320,23 @@ QDF_STATUS sme_get_cfg_valid_channels(uint8_t *aValidChannels, return QDF_STATUS_E_FAILURE; } + valid_ch_freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * + sizeof(uint32_t)); + if (!valid_ch_freq_list) + return QDF_STATUS_E_NOMEM; + status = sme_acquire_global_lock(&mac_ctx->sme); if (QDF_IS_STATUS_SUCCESS(status)) { status = csr_get_cfg_valid_channels(mac_ctx, - aValidChannels, len); + valid_ch_freq_list, len); sme_release_global_lock(&mac_ctx->sme); } + for (i = 0; i < *len; i++) + valid_ch_freq[i] = valid_ch_freq_list[i]; + + qdf_mem_free(valid_ch_freq_list); + return status; } @@ -5467,45 +5387,6 @@ sme_handle_generic_change_country_code(struct mac_context *mac_ctx, void *msg_buf) { QDF_STATUS status = QDF_STATUS_SUCCESS; - v_REGDOMAIN_t reg_domain_id = 0; - bool user_ctry_priority = - mac_ctx->mlme_cfg->sap_cfg.country_code_priority; - tAniGenericChangeCountryCodeReq *msg = msg_buf; - - if (SOURCE_11D != mac_ctx->reg_hint_src) { - if (SOURCE_DRIVER != mac_ctx->reg_hint_src) { - if (user_ctry_priority) - mac_ctx->mlme_cfg->gen.enabled_11d = false; - else { - if (mac_ctx->mlme_cfg->gen.enabled_11d && - mac_ctx->scan.countryCode11d[0] != 0) { - - sme_debug("restore 11d"); - - status = - csr_get_regulatory_domain_for_country( - mac_ctx, - mac_ctx->scan.countryCode11d, - ®_domain_id, - SOURCE_11D); - return QDF_STATUS_E_FAILURE; - } - } - } - } else { - /* if kernel gets invalid country code; it - * resets the country code to world - */ - if (('0' != msg->countryCode[0]) || - ('0' != msg->countryCode[1])) - qdf_mem_copy(mac_ctx->scan.countryCode11d, - msg->countryCode, - CFG_COUNTRY_CODE_LEN); - } - - qdf_mem_copy(mac_ctx->scan.countryCodeCurrent, - msg->countryCode, - CFG_COUNTRY_CODE_LEN); /* get the channels based on new cc */ status = csr_get_channel_and_power_list(mac_ctx); @@ -5515,21 +5396,14 @@ sme_handle_generic_change_country_code(struct mac_context *mac_ctx, return status; } + sme_disconnect_connected_sessions(mac_ctx, + eSIR_MAC_UNSPEC_FAILURE_REASON); + /* reset info based on new cc, and we are done */ csr_apply_channel_power_info_wrapper(mac_ctx); csr_scan_filter_results(mac_ctx); - /* scans after the country is set by User hints or - * Country IE - */ - mac_ctx->scan.curScanType = eSIR_ACTIVE_SCAN; - - mac_ctx->reg_hint_src = SOURCE_UNKNOWN; - - sme_disconnect_connected_sessions(mac_ctx, - eSIR_MAC_UNSPEC_FAILURE_REASON); - return QDF_STATUS_SUCCESS; } @@ -5558,20 +5432,28 @@ QDF_STATUS sme_update_channel_list(mac_handle_t mac_handle) return status; } -static bool -sme_search_in_base_ch_lst(struct mac_context *mac_ctx, uint8_t curr_ch) +/** + * sme_search_in_base_ch_freq_lst() - is given ch_freq in base ch freq + * @mac_ctx: mac global context + * @chan_freq: current channel freq + * + * Return: true if given ch_freq is in base ch freq + */ +static bool sme_search_in_base_ch_freq_lst( + struct mac_context *mac_ctx, uint32_t chan_freq) { uint8_t i; struct csr_channel *ch_lst_info; ch_lst_info = &mac_ctx->scan.base_channels; for (i = 0; i < ch_lst_info->numChannels; i++) { - if (ch_lst_info->channelList[i] == curr_ch) + if (ch_lst_info->channel_freq_list[i] == chan_freq) return true; } return false; } + /** * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session * if channel is not supported @@ -5587,18 +5469,18 @@ static void sme_disconnect_connected_sessions(struct mac_context *mac_ctx, enum eSirMacReasonCodes reason) { uint8_t session_id, found = false; - uint8_t curr_ch; + uint32_t chan_freq; for (session_id = 0; session_id < WLAN_MAX_VDEVS; session_id++) { if (!csr_is_session_client_and_connected(mac_ctx, session_id)) continue; found = false; /* Session is connected.Check the channel */ - curr_ch = csr_get_infra_operation_channel(mac_ctx, - session_id); + chan_freq = csr_get_infra_operation_chan_freq( + mac_ctx, session_id); sme_debug("Current Operating channel : %d, session :%d", - curr_ch, session_id); - found = sme_search_in_base_ch_lst(mac_ctx, curr_ch); + chan_freq, session_id); + found = sme_search_in_base_ch_freq_lst(mac_ctx, chan_freq); if (!found) { sme_debug("Disconnect Session: %d", session_id); csr_roam_disconnect(mac_ctx, session_id, @@ -5673,16 +5555,7 @@ QDF_STATUS sme_8023_multicast_list(mac_handle_t mac_handle, uint8_t sessionId, } #endif /* WLAN_FEATURE_PACKET_FILTERING */ -/* - * sme_is_channel_valid() - - * To check if the channel is valid for currently established domain - * This is a synchronous API. - * - * mac_handle - The handle returned by mac_open. - * channel - channel to verify - * Return true/false, true if channel is valid - */ -bool sme_is_channel_valid(mac_handle_t mac_handle, uint8_t channel) +bool sme_is_channel_valid(mac_handle_t mac_handle, uint32_t chan_freq) { QDF_STATUS status = QDF_STATUS_E_FAILURE; bool valid = false; @@ -5691,7 +5564,7 @@ bool sme_is_channel_valid(mac_handle_t mac_handle, uint8_t channel) status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - valid = csr_roam_is_channel_valid(mac, channel); + valid = csr_roam_is_channel_valid(mac, chan_freq); sme_release_global_lock(&mac->sme); } @@ -5904,7 +5777,7 @@ QDF_STATUS sme_update_session_param(mac_handle_t mac_handle, uint8_t session_id, else { msg->message_type = eWNI_SME_SESSION_UPDATE_PARAM; msg->length = len; - msg->session_id = session_id; + msg->vdev_id = session_id; msg->param_type = param_type; msg->param_val = param_val; status = umac_send_mb_message_to_mac(msg); @@ -5926,7 +5799,6 @@ QDF_STATUS sme_update_roam_scan_n_probes(mac_handle_t mac_handle, sme_err("Invalid vdev_id: %d", vdev_id); return QDF_STATUS_E_INVAL; } - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES, vdev_id, 0)); @@ -5941,8 +5813,7 @@ QDF_STATUS sme_update_roam_scan_n_probes(mac_handle_t mac_handle, neighbor_roam_info->cfgParams.roam_scan_n_probes = probes; if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) - csr_roam_update_cfg(mac, vdev_id, - REASON_NPROBES_CHANGED); + csr_roam_update_cfg(mac, vdev_id, REASON_NPROBES_CHANGED); sme_release_global_lock(&mac->sme); return status; @@ -5997,7 +5868,7 @@ sme_update_roam_scan_home_away_time(mac_handle_t mac_handle, uint8_t vdev_id, * sme_ext_change_channel()- function to post send ECSA * action frame to csr. * @mac_handle: Opaque handle to the global MAC context - * @channel: new channel to switch + * @channel freq: new channel freq to switch * @session_id: senssion it should be sent on. * * This function is called to post ECSA frame to csr. @@ -6475,6 +6346,7 @@ QDF_STATUS sme_config_fast_roaming(mac_handle_t mac_handle, uint8_t session_id, struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); enum roam_offload_state state; QDF_STATUS status; + bool supplicant_disabled_roaming; /* * supplicant_disabled_roaming flag is altered when supplicant sends @@ -6493,6 +6365,13 @@ QDF_STATUS sme_config_fast_roaming(mac_handle_t mac_handle, uint8_t session_id, return QDF_STATUS_E_FAILURE; } + supplicant_disabled_roaming = + mlme_get_supplicant_disabled_roaming(mac_ctx->psoc, + session_id); + if (!is_fast_roam_enabled && supplicant_disabled_roaming) { + sme_debug("ROAM: RSO disabled by wpa supplicant already"); + return QDF_STATUS_E_ALREADY; + } mlme_set_supplicant_disabled_roaming(mac_ctx->psoc, session_id, !is_fast_roam_enabled); @@ -6588,10 +6467,9 @@ QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t session_id, return QDF_STATUS_E_FAILURE; } - if (reason == REASON_DRIVER_DISABLED && requestor) { - mlme_set_operations_bitmap(mac_ctx->psoc, session_id, requestor, - false); - } + if (reason == REASON_DRIVER_DISABLED && requestor) + mlme_set_operations_bitmap(mac_ctx->psoc, session_id, + requestor, false); status = csr_post_roam_state_change(mac_ctx, session_id, ROAM_RSO_STOPPED, @@ -7522,7 +7400,7 @@ QDF_STATUS sme_get_roam_rssi_diff(mac_handle_t mac_handle, uint8_t vdev_id, return QDF_STATUS_SUCCESS; } -void sme_dump_chan_list(tCsrChannelInfo *chan_info) +void sme_dump_freq_list(tCsrChannelInfo *chan_info) { uint8_t *channel_list; uint8_t i = 0, j = 0; @@ -7532,11 +7410,11 @@ void sme_dump_chan_list(tCsrChannelInfo *chan_info) if (!channel_list) return; - if (chan_info->ChannelList) { + if (chan_info->freq_list) { for (i = 0; i < chan_info->numOfChannels; i++) { if (j < buflen) j += snprintf(channel_list + j, buflen - j, - "%d ", chan_info->ChannelList[i]); + "%d ", chan_info->freq_list[i]); else break; } @@ -7546,21 +7424,56 @@ void sme_dump_chan_list(tCsrChannelInfo *chan_info) qdf_mem_free(channel_list); } +static bool sme_validate_freq_list(mac_handle_t mac_handle, + uint32_t *freq_list, + uint8_t num_channels) +{ + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + uint8_t i = 0, j; + bool found; + struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels; + + if (!freq_list || !num_channels) { + sme_err("Freq list empty %pK or num_channels is 0", freq_list); + return false; + } + + while (i < num_channels) { + found = false; + for (j = 0; j < ch_lst_info->numChannels; j++) { + if (ch_lst_info->channel_freq_list[j] == freq_list[i]) { + found = true; + break; + } + } + + if (!found) { + sme_debug("Invalid frequency %u", freq_list[i]); + return false; + } + + i++; + } + + return true; +} + static uint8_t -csr_append_pref_chan_list(tCsrChannelInfo *chan_info, uint8_t *channel_list, +csr_append_pref_chan_list(tCsrChannelInfo *chan_info, uint32_t *freq_list, uint8_t num_chan) { - uint8_t i = 0; + uint8_t i = 0, j = 0; for (i = 0; i < chan_info->numOfChannels; i++) { - if (csr_is_channel_present_in_list( - channel_list, num_chan, chan_info->ChannelList[i])) - continue; + for (j = 0; j < num_chan; j++) + if (chan_info->freq_list[i] == freq_list[j]) + break; - if (num_chan >= SIR_ROAM_MAX_CHANNELS) + if (j < num_chan) + continue; + if (num_chan == SIR_ROAM_MAX_CHANNELS) break; - - channel_list[num_chan++] = chan_info->ChannelList[i]; + freq_list[num_chan++] = chan_info->freq_list[i]; } return num_chan; @@ -7586,42 +7499,28 @@ sme_update_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t vdev_id, { QDF_STATUS status = QDF_STATUS_SUCCESS; struct mac_context *mac = MAC_CONTEXT(mac_handle); - uint8_t *channel_list, pref_chan_cnt = 0; - - channel_list = qdf_mem_malloc(SIR_MAX_SUPPORTED_CHANNEL_LIST); - if (!channel_list) - return QDF_STATUS_E_NOMEM; + uint16_t pref_chan_cnt = 0; if (chan_info->numOfChannels) { sme_debug("Current channels:"); - sme_dump_chan_list(chan_info); - } - - sme_freq_to_chan_list(mac->pdev, channel_list, freq_list, num_chan); - if (!sme_validate_channel_list(mac_handle, channel_list, num_chan)) { - sme_err("List contains invalid channel(s)"); - status = QDF_STATUS_E_INVAL; - goto out; + sme_dump_freq_list(chan_info); } - pref_chan_cnt = csr_append_pref_chan_list(chan_info, channel_list, + pref_chan_cnt = csr_append_pref_chan_list(chan_info, freq_list, num_chan); num_chan = pref_chan_cnt; csr_flush_cfg_bg_scan_roam_channel_list(chan_info); - csr_create_bg_scan_roam_channel_list(mac, chan_info, channel_list, + csr_create_bg_scan_roam_channel_list(mac, chan_info, freq_list, num_chan); - sme_debug("New channels:"); - sme_dump_chan_list(chan_info); + sme_dump_freq_list(chan_info); sme_debug("Updated roam scan channels - roam state is %d", mac->roam.neighborRoamInfo[vdev_id].neighborRoamState); if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) status = csr_roam_update_cfg(mac, vdev_id, REASON_CHANNEL_LIST_CHANGED); -out: - qdf_mem_free(channel_list); return status; } @@ -7630,7 +7529,7 @@ sme_update_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t vdev_id, * sme_change_roam_scan_channel_list() - to change scan channel list * @mac_handle: Opaque handle to the global MAC context * @sessionId: sme session id - * @channel_list: Output channel list + * @channel_freq_list: Output channel list * @numChannels: Output number of channels * * This routine is called to Change roam scan channel list. @@ -7640,14 +7539,14 @@ sme_update_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t vdev_id, */ QDF_STATUS sme_change_roam_scan_channel_list(mac_handle_t mac_handle, uint8_t sessionId, - uint8_t *channel_list, + uint32_t *channel_freq_list, uint8_t numChannels) { struct mac_context *mac = MAC_CONTEXT(mac_handle); QDF_STATUS status = QDF_STATUS_SUCCESS; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; - uint8_t oldChannelList[CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; - uint8_t newChannelList[CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; + uint8_t oldChannelList[CFG_VALID_CHANNEL_LIST_LEN * 5] = { 0 }; + uint8_t newChannelList[CFG_VALID_CHANNEL_LIST_LEN * 5] = { 0 }; uint8_t i = 0, j = 0; tCsrChannelInfo *chan_info; @@ -7665,29 +7564,28 @@ QDF_STATUS sme_change_roam_scan_channel_list(mac_handle_t mac_handle, } chan_info = &pNeighborRoamInfo->cfgParams.specific_chan_info; - if (chan_info->ChannelList) { + if (chan_info->freq_list) { for (i = 0; i < chan_info->numOfChannels; i++) { if (j < sizeof(oldChannelList)) j += snprintf(oldChannelList + j, sizeof(oldChannelList) - - j, "%d", - chan_info->ChannelList[i]); + j, " %d", + chan_info->freq_list[i]); else break; } } csr_flush_cfg_bg_scan_roam_channel_list(chan_info); - csr_create_bg_scan_roam_channel_list(mac, chan_info, channel_list, + csr_create_bg_scan_roam_channel_list(mac, chan_info, channel_freq_list, numChannels); sme_set_roam_scan_control(mac_handle, sessionId, 1); - if (chan_info->ChannelList) { + if (chan_info->freq_list) { j = 0; for (i = 0; i < chan_info->numOfChannels; i++) { if (j < sizeof(newChannelList)) j += snprintf(newChannelList + j, sizeof(newChannelList) - - j, " %d", - chan_info->ChannelList[i]); + j, " %d", chan_info->freq_list[i]); else break; } @@ -7720,6 +7618,11 @@ sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, return QDF_STATUS_E_INVAL; } + if (!sme_validate_freq_list(mac_handle, freq_list, num_chan)) { + sme_err("List contains invalid channel(s)"); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_ERROR(status)) { sme_err("Failed to acquire SME lock"); @@ -7727,23 +7630,23 @@ sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, } neighbor_roam_info = &mac->roam.neighborRoamInfo[vdev_id]; - if (neighbor_roam_info->cfgParams.specific_chan_info.numOfChannels) { + if (neighbor_roam_info->cfgParams.specific_chan_info.numOfChannels && + freq_list_type == QCA_PREFERRED_SCAN_FREQ_LIST) { sme_err("Specific channel list is already configured"); sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_PERM; + return QDF_STATUS_E_INVAL; } + sme_debug("frequency list type %d", freq_list_type); if (freq_list_type == QCA_PREFERRED_SCAN_FREQ_LIST) { - sme_debug("Preferred frequency list: "); channel_info = &neighbor_roam_info->cfgParams.pref_chan_info; + status = sme_update_roam_scan_channel_list( + mac_handle, vdev_id, channel_info, + freq_list, num_chan); } else { - goto out; + status = sme_change_roam_scan_channel_list(mac_handle, vdev_id, + freq_list, num_chan); } - - status = sme_update_roam_scan_channel_list(mac_handle, vdev_id, - channel_info, freq_list, - num_chan); -out: sme_release_global_lock(&mac->sme); return status; @@ -7752,7 +7655,7 @@ sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, /** * sme_get_roam_scan_channel_list() - To get roam scan channel list * @mac_handle: Opaque handle to the global MAC context - * @pChannelList: Output channel list + * @freq_list: Output channel freq list * @pNumChannels: Output number of channels * @sessionId: Session Identifier * @@ -7761,17 +7664,16 @@ sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, * Return: QDF_STATUS */ QDF_STATUS sme_get_roam_scan_channel_list(mac_handle_t mac_handle, - uint8_t *pChannelList, uint8_t *pNumChannels, + uint32_t *freq_list, uint8_t *pNumChannels, uint8_t sessionId) { int i = 0, chan_cnt = 0; - uint8_t *pOutPtr = pChannelList; struct mac_context *mac = MAC_CONTEXT(mac_handle); tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; - struct csr_channel *occupied_ch_lst = - &mac->scan.occupiedChannels[sessionId]; QDF_STATUS status = QDF_STATUS_SUCCESS; tCsrChannelInfo *chan_info; + struct csr_channel *occupied_ch_lst = + &mac->scan.occupiedChannels[sessionId]; if (sessionId >= WLAN_MAX_VDEVS) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -7783,45 +7685,43 @@ QDF_STATUS sme_get_roam_scan_channel_list(mac_handle_t mac_handle, status = sme_acquire_global_lock(&mac->sme); if (!QDF_IS_STATUS_SUCCESS(status)) return status; + chan_info = &pNeighborRoamInfo->cfgParams.specific_chan_info; if (chan_info->numOfChannels) { *pNumChannels = chan_info->numOfChannels; - for (chan_cnt = 0; chan_cnt < (*pNumChannels) && - chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN; chan_cnt++) - pOutPtr[chan_cnt] = chan_info->ChannelList[chan_cnt]; + for (i = 0; i < (*pNumChannels) && + i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) + freq_list[i] = chan_info->freq_list[i]; - *pNumChannels = chan_cnt; + *pNumChannels = i; } else { chan_info = &pNeighborRoamInfo->cfgParams.pref_chan_info; + *pNumChannels = chan_info->numOfChannels; if (chan_info->numOfChannels) { - *pNumChannels = chan_info->numOfChannels; for (chan_cnt = 0; chan_cnt < (*pNumChannels) && chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN; chan_cnt++) - pOutPtr[chan_cnt] = - chan_info->ChannelList[chan_cnt]; + freq_list[chan_cnt] = + chan_info->freq_list[chan_cnt]; } if (occupied_ch_lst->numChannels) { for (i = 0; i < occupied_ch_lst->numChannels && - chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) { - if (csr_is_channel_present_in_list( - pOutPtr, chan_cnt, - occupied_ch_lst->channelList[i])) - continue; - pOutPtr[chan_cnt++] = - occupied_ch_lst->channelList[i]; - } + chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) + freq_list[chan_cnt++] = + occupied_ch_lst->channel_freq_list[i]; } + *pNumChannels = chan_cnt; if (!(chan_info->numOfChannels || occupied_ch_lst->numChannels)) { sme_err("Roam Scan channel list is NOT yet initialized"); + *pNumChannels = 0; status = QDF_STATUS_E_INVAL; } } - sme_release_global_lock(&mac->sme); + sme_release_global_lock(&mac->sme); return status; } @@ -7948,56 +7848,6 @@ QDF_STATUS sme_get_link_speed(mac_handle_t mac_handle, return status; } -QDF_STATUS -sme_get_peer_info(mac_handle_t mac_handle, - struct sir_peer_info_req req, - void *context, - void (*callbackfn)(struct sir_peer_info_resp *param, - void *pcontext)) -{ - - QDF_STATUS status; - QDF_STATUS qdf_status; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - struct scheduler_msg message = {0}; - - status = sme_acquire_global_lock(&mac->sme); - if (QDF_STATUS_SUCCESS == status) { - if (!callbackfn) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: Indication Call back is NULL", - __func__); - sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_FAILURE; - } - - mac->sme.pget_peer_info_ind_cb = callbackfn; - mac->sme.pget_peer_info_cb_context = context; - - /* serialize the req through MC thread */ - message.bodyptr = qdf_mem_malloc(sizeof(req)); - if (!message.bodyptr) { - sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_NOMEM; - } - qdf_mem_copy(message.bodyptr, &req, sizeof(req)); - message.type = WMA_GET_PEER_INFO; - message.reserved = 0; - qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, - &message); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: Post get peer info msg fail", __func__); - qdf_mem_free(message.bodyptr); - status = QDF_STATUS_E_FAILURE; - } - sme_release_global_lock(&mac->sme); - } - return status; -} - QDF_STATUS sme_get_peer_info_ext(mac_handle_t mac_handle, struct sir_peer_info_ext_req *req, void *context, @@ -8318,63 +8168,6 @@ QDF_STATUS sme_send_rmc_action_period(mac_handle_t mac_handle, } #endif /* FEATURE_WLAN_RMC */ -/* - * sme_request_ibss_peer_info() - request ibss peer info - * @mac_handle: Opaque handle to the global MAC context - * @cb_context: Pointer to user data - * @peer_info_cb: Peer info callback - * @allPeerInfoReqd: All peer info required or not - * @staIdx: sta index - * - * Return: QDF_STATUS - */ -QDF_STATUS sme_request_ibss_peer_info(mac_handle_t mac_handle, void *cb_context, - ibss_peer_info_cb peer_info_cb, - bool allPeerInfoReqd, uint8_t staIdx) -{ - QDF_STATUS status = QDF_STATUS_E_FAILURE; - QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - struct scheduler_msg message = {0}; - tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams; - struct ibss_peer_info_cb_info *cb_info; - - status = sme_acquire_global_lock(&mac->sme); - if (QDF_STATUS_SUCCESS == status) { - cb_info = &mac->sme.peer_info_cb_info; - cb_info->peer_info_cb = peer_info_cb; - cb_info->peer_info_cb_context = cb_context; - - pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *) - qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams)); - if (!pIbssInfoReqParams) { - sme_release_global_lock(&mac->sme); - return QDF_STATUS_E_NOMEM; - } - pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd; - pIbssInfoReqParams->staIdx = staIdx; - - message.type = WMA_GET_IBSS_PEER_INFO_REQ; - message.bodyptr = pIbssInfoReqParams; - message.reserved = 0; - - qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, - &message); - if (QDF_STATUS_SUCCESS != qdf_status) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: Post WMA_GET_IBSS_PEER_INFO_REQ MSG failed", - __func__); - qdf_mem_free(pIbssInfoReqParams); - qdf_status = QDF_STATUS_E_FAILURE; - } - sme_release_global_lock(&mac->sme); - } - - return qdf_status; -} - /* * sme_send_cesium_enable_ind() - * Used to send proprietary cesium enable indication to fw @@ -8463,7 +8256,7 @@ void sme_get_command_q_status(mac_handle_t mac_handle) } /* if(pTempCmd) */ sme_err("Currently smeCmdPendingList has %d commands", - csr_nonscan_pending_ll_count(mac)); + wlan_serialization_get_pending_list_count(mac->psoc, false)); } @@ -8526,7 +8319,7 @@ QDF_STATUS sme_notify_modem_power_state(mac_handle_t mac_handle, uint32_t value) } #ifdef QCA_HT_2040_COEX -QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, uint16_t staId, +QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, struct qdf_mac_addr macAddrSTA, uint8_t sessionId, uint8_t channel_type) @@ -8559,7 +8352,6 @@ QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, uint16_t staId, return QDF_STATUS_E_FAILURE; } - pHtOpMode->staId = staId, qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes, sizeof(tSirMacAddr)); pHtOpMode->smesessionId = sessionId; @@ -8579,8 +8371,8 @@ QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, uint16_t staId, } QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "%s: Notified FW about OP mode: %d for staId=%d", - __func__, pHtOpMode->opMode, staId); + "%s: Notified FW about OP mode: %d", + __func__, pHtOpMode->opMode); return QDF_STATUS_SUCCESS; } @@ -9025,7 +8817,7 @@ QDF_STATUS sme_send_rate_update_ind(mac_handle_t mac_handle, /** * sme_update_access_policy_vendor_ie() - update vendor ie and access policy. * @mac_handle: Pointer to the mac context - * @session_id: sme session id + * @vdev_id: vdev_id * @vendor_ie: vendor ie * @access_policy: vendor ie access policy * @@ -9034,7 +8826,7 @@ QDF_STATUS sme_send_rate_update_ind(mac_handle_t mac_handle, * Return: success or failure. */ QDF_STATUS sme_update_access_policy_vendor_ie(mac_handle_t mac_handle, - uint8_t session_id, + uint8_t vdev_id, uint8_t *vendor_ie, int access_policy) { @@ -9054,12 +8846,10 @@ QDF_STATUS sme_update_access_policy_vendor_ie(mac_handle_t mac_handle, qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie)); - msg->sme_session_id = session_id; + msg->vdev_id = vdev_id; msg->access_policy = access_policy; - sme_debug("sme_session_id: %hu, access_policy: %d", session_id, - access_policy); - + sme_debug("vdev_id: %hu, access_policy: %d", vdev_id, access_policy); status = umac_send_mb_message_to_mac(msg); return status; @@ -9102,18 +8892,7 @@ QDF_STATUS sme_update_sta_inactivity_timeout(mac_handle_t mac_handle, return QDF_STATUS_SUCCESS; } -/** - * sme_get_reg_info() - To get registration info - * @mac_handle: Opaque handle to the global MAC context - * @chanId: channel id - * @regInfo1: first reg info to fill - * @regInfo2: second reg info to fill - * - * This routine will give you reg info - * - * Return: QDF_STATUS - */ -QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint8_t chanId, +QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint32_t chan_freq, uint32_t *regInfo1, uint32_t *regInfo2) { struct mac_context *mac = MAC_CONTEXT(mac_handle); @@ -9128,7 +8907,7 @@ QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint8_t chanId, return status; for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) { - if (mac->scan.defaultPowerTable[i].chan_num == chanId) { + if (mac->scan.defaultPowerTable[i].center_freq == chan_freq) { SME_SET_CHANNEL_REG_POWER(*regInfo1, mac->scan.defaultPowerTable[i].tx_power); @@ -9395,50 +9174,33 @@ static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac, QDF_STATUS status = QDF_STATUS_SUCCESS; struct csr_roam_info *roam_info; eCsrRoamResult roamResult; - tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) msg_buf; - uint32_t SessionId = pChnlParams->peSessionId; + uint8_t session_id; roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return QDF_STATUS_E_NOMEM; roam_info->channelChangeRespEvent = - qdf_mem_malloc(sizeof(tSirChanChangeResponse)); - if (!roam_info->channelChangeRespEvent) { - status = QDF_STATUS_E_NOMEM; - qdf_mem_free(roam_info); - return status; - } - if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) { - roam_info->channelChangeRespEvent->sessionId = SessionId; - roam_info->channelChangeRespEvent->newChannelNumber = - pChnlParams->channelNumber; - - if (pChnlParams->status == QDF_STATUS_SUCCESS) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", - SessionId); - roam_info->channelChangeRespEvent->channelChangeStatus = - 1; - roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; - } else { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", - SessionId); - roam_info->channelChangeRespEvent->channelChangeStatus = - 0; - roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; - } + (struct sSirChanChangeResponse *)msg_buf; - csr_roam_call_callback(mac, SessionId, roam_info, 0, - eCSR_ROAM_SET_CHANNEL_RSP, roamResult); + session_id = roam_info->channelChangeRespEvent->sessionId; + if (roam_info->channelChangeRespEvent->channelChangeStatus == + QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", + session_id); + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; } else { - status = QDF_STATUS_E_FAILURE; - sme_err("Invalid Channel Change Resp Message: %d", - status); + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", + session_id); + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; } - qdf_mem_free(roam_info->channelChangeRespEvent); + + csr_roam_call_callback(mac, session_id, roam_info, 0, + eCSR_ROAM_SET_CHANNEL_RSP, roamResult); + qdf_mem_free(roam_info); return status; @@ -9483,19 +9245,9 @@ QDF_STATUS sme_csa_restart(struct mac_context *mac_ctx, uint8_t session_id) return status; } -/** - * sme_roam_csa_ie_request() - request CSA IE transmission from PE - * @mac_handle: handle returned by mac_open - * @bssid: SAP bssid - * @targetChannel: target channel information - * @csaIeReqd: CSA IE Request - * @ch_params: channel information - * - * Return: QDF_STATUS - */ QDF_STATUS sme_roam_csa_ie_request(mac_handle_t mac_handle, struct qdf_mac_addr bssid, - uint8_t targetChannel, uint8_t csaIeReqd, + uint32_t target_chan_freq, uint8_t csaIeReqd, struct ch_params *ch_params) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -9504,7 +9256,7 @@ QDF_STATUS sme_roam_csa_ie_request(mac_handle_t mac_handle, status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { status = csr_roam_send_chan_sw_ie_request(mac, bssid, - targetChannel, csaIeReqd, ch_params); + target_chan_freq, csaIeReqd, ch_params); sme_release_global_lock(&mac->sme); } return status; @@ -10107,124 +9859,117 @@ QDF_STATUS sme_abort_roam_scan(mac_handle_t mac_handle, uint8_t sessionId) return status; } -/** - * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band - * @mac_handle: Opaque handle to the global MAC context - * @wifiBand: RF band information - * @aValidChannels: output array to store channel info - * @pNumChannels: output number of channels - * - * SME API to fetch all valid channels filtered by band - * - * Return: QDF_STATUS - */ QDF_STATUS sme_get_valid_channels_by_band(mac_handle_t mac_handle, - uint8_t wifiBand, - uint32_t *aValidChannels, - uint8_t *pNumChannels) + uint8_t wifi_band, + uint32_t *valid_chan_list, + uint8_t *valid_chan_len) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t chanList[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; - uint8_t numChannels = 0; + uint32_t chan_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint8_t num_channels = 0; uint8_t i = 0; - uint32_t totValidChannels = CFG_VALID_CHANNEL_LIST_LEN; + uint32_t valid_channels = CFG_VALID_CHANNEL_LIST_LEN; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - if (!aValidChannels || !pNumChannels) { + if (!valid_chan_list || !valid_chan_len) { sme_err("Output channel list/NumChannels is NULL"); return QDF_STATUS_E_INVAL; } - if (wifiBand >= WIFI_BAND_MAX) { - sme_err("Invalid wifiBand: %d", wifiBand); + if (wifi_band >= WIFI_BAND_MAX) { + sme_err("Invalid wifi Band: %d", wifi_band); return QDF_STATUS_E_INVAL; } - status = sme_get_cfg_valid_channels(&chanList[0], - &totValidChannels); + status = sme_get_cfg_valid_channels(&chan_freq_list[0], + &valid_channels); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err("Fail to get valid channel list (err=%d)", status); return status; } - switch (wifiBand) { + switch (wifi_band) { case WIFI_BAND_UNSPECIFIED: sme_debug("Unspec Band, return all %d valid channels", - totValidChannels); - numChannels = totValidChannels; - for (i = 0; i < totValidChannels; i++) - aValidChannels[i] = cds_chan_to_freq(chanList[i]); + valid_channels); + num_channels = valid_channels; + for (i = 0; i < valid_channels; i++) + valid_chan_list[i] = chan_freq_list[i]; break; case WIFI_BAND_BG: sme_debug("WIFI_BAND_BG (2.4 GHz)"); - for (i = 0; i < totValidChannels; i++) { - if (WLAN_REG_IS_24GHZ_CH(chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; case WIFI_BAND_A: sme_debug("WIFI_BAND_A (5 GHz without DFS)"); - for (i = 0; i < totValidChannels; i++) { - if (WLAN_REG_IS_5GHZ_CH(chanList[i]) && - !wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) && + !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; case WIFI_BAND_ABG: sme_debug("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)"); - for (i = 0; i < totValidChannels; i++) { - if ((WLAN_REG_IS_24GHZ_CH(chanList[i]) || - WLAN_REG_IS_5GHZ_CH(chanList[i])) && - !wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if ((WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) || + WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) && + !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; case WIFI_BAND_A_DFS_ONLY: sme_debug("WIFI_BAND_A_DFS (5 GHz DFS only)"); - for (i = 0; i < totValidChannels; i++) { - if (WLAN_REG_IS_5GHZ_CH(chanList[i]) && - wlan_reg_is_dfs_ch(mac_ctx->pdev, chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) && + wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; case WIFI_BAND_A_WITH_DFS: sme_debug("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)"); - for (i = 0; i < totValidChannels; i++) { - if (WLAN_REG_IS_5GHZ_CH(chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; case WIFI_BAND_ABG_WITH_DFS: sme_debug("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)"); - for (i = 0; i < totValidChannels; i++) { - if (WLAN_REG_IS_24GHZ_CH(chanList[i]) || - WLAN_REG_IS_5GHZ_CH(chanList[i])) - aValidChannels[numChannels++] = - cds_chan_to_freq(chanList[i]); + for (i = 0; i < valid_channels; i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) || + WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) + valid_chan_list[num_channels++] = + chan_freq_list[i]; } break; default: - sme_err("Unknown wifiBand: %d", wifiBand); + sme_err("Unknown wifi Band: %d", wifi_band); return QDF_STATUS_E_INVAL; } - *pNumChannels = numChannels; + *valid_chan_len = num_channels; return status; } #ifdef FEATURE_WLAN_EXTSCAN + QDF_STATUS sme_ext_scan_get_capabilities(mac_handle_t mac_handle, struct extscan_capabilities_params *params) @@ -10983,19 +10728,25 @@ QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle, FL("sme_acquire_global_lock error")); qdf_mem_free(thresh); } - return status; + return status; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_POWER_DEBUG +void sme_reset_power_debug_stats_cb(mac_handle_t mac_handle) +{ + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + mac_ctx->sme.power_debug_stats_context = NULL; + mac_ctx->sme.power_stats_resp_callback = NULL; + sme_release_global_lock(&mac_ctx->sme); + } } -#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ - -#ifdef WLAN_POWER_DEBUG -/** - * sme_power_debug_stats_req() - SME API to collect Power debug stats - * @callback_fn: Pointer to the callback function for Power stats event - * @power_stats_context: Pointer to context - * - * Return: QDF_STATUS - */ QDF_STATUS sme_power_debug_stats_req( mac_handle_t mac_handle, void (*callback_fn)(struct power_stats_response *response, @@ -11014,6 +10765,12 @@ QDF_STATUS sme_power_debug_stats_req( return QDF_STATUS_E_FAILURE; } + if (mac_ctx->sme.power_debug_stats_context || + mac_ctx->sme.power_stats_resp_callback) { + sme_err("Already one power stats req in progress"); + sme_release_global_lock(&mac_ctx->sme); + return QDF_STATUS_E_ALREADY; + } mac_ctx->sme.power_debug_stats_context = power_stats_context; mac_ctx->sme.power_stats_resp_callback = callback_fn; msg.bodyptr = NULL; @@ -11329,7 +11086,7 @@ QDF_STATUS sme_enable_dfs_chan_scan(mac_handle_t mac_handle, uint8_t dfs_flag) * Return: true if there is no channel interference else return false */ bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, - uint16_t sap_ch, + uint32_t sap_ch_freq, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode, uint8_t session_id) @@ -11337,7 +11094,7 @@ bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id); - uint16_t intf_channel = 0; + uint16_t intf_channel_freq = 0; if (!session) return false; @@ -11345,9 +11102,8 @@ bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, session->ch_switch_in_progress = true; status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - intf_channel = csr_check_concurrent_channel_overlap(mac, sap_ch, - sap_phy_mode, - cc_switch_mode); + intf_channel_freq = csr_check_concurrent_channel_overlap( + mac, sap_ch_freq, sap_phy_mode, cc_switch_mode); sme_release_global_lock(&mac->sme); } else { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -11357,7 +11113,7 @@ bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, } session->ch_switch_in_progress = false; - return (intf_channel == 0) ? true : false; + return (intf_channel_freq == 0) ? true : false; } #endif @@ -11581,8 +11337,7 @@ QDF_STATUS sme_send_flush_logs_cmd_to_fw(void) return status; } -QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id, - sme_ac_enum_type ac, uint8_t tid, +QDF_STATUS sme_enable_uapsd_for_ac(sme_ac_enum_type ac, uint8_t tid, uint8_t pri, uint32_t srvc_int, uint32_t sus_int, enum sme_qos_wmm_dir_type dir, @@ -11639,9 +11394,7 @@ QDF_STATUS sme_enable_uapsd_for_ac(uint8_t sta_id, return QDF_STATUS_SUCCESS; } -QDF_STATUS sme_disable_uapsd_for_ac(uint8_t sta_id, - sme_ac_enum_type ac, - uint32_t sessionId) +QDF_STATUS sme_disable_uapsd_for_ac(sme_ac_enum_type ac, uint32_t sessionId) { void *wma_handle; enum uapsd_ac access_category; @@ -11803,6 +11556,7 @@ void sme_update_he_cap_nss(mac_handle_t mac_handle, uint8_t session_id, if (!nss || (nss > 2)) { sme_err("invalid Nss value %d", nss); + return; } csr_session = CSR_GET_SESSION(mac_ctx, session_id); if (!csr_session) { @@ -12099,8 +11853,8 @@ int sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id) omi_data.ch_bw, omi_data.tx_nsts, omi_data.rx_nss, omi_data.ul_mu_dis, omi_data.omi_in_vht, omi_data.omi_in_he); qdf_mem_copy(¶m_val, &omi_data, sizeof(omi_data)); - sme_debug("param val %08X, bssid:"QDF_MAC_ADDR_STR, param_val, - QDF_MAC_ADDR_ARRAY(session->connectedProfile.bssid.bytes)); + sme_debug("param val %08X, bssid:"QDF_MAC_ADDR_FMT, param_val, + QDF_MAC_ADDR_REF(session->connectedProfile.bssid.bytes)); status = wma_set_peer_param(wma_handle, session->connectedProfile.bssid.bytes, WMI_PEER_PARAM_XMIT_OMI, @@ -12213,7 +11967,7 @@ int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, uint8_t session_id, return -EIO; cfg_msg->type = WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU; - cfg_msg->session_id = session_id; + cfg_msg->vdev_id = session_id; cfg_msg->cfg = cfg_val; msg.bodyptr = cfg_msg; @@ -12242,11 +11996,15 @@ int sme_update_he_tx_bfee_nsts(mac_handle_t mac_handle, uint8_t session_id, sme_err("No session for id %d", session_id); return -EINVAL; } - if (cfg_in_range(CFG_HE_BFEE_STS_LT80, cfg_val)) + if (cfg_in_range(CFG_HE_BFEE_STS_LT80, cfg_val)) { mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_lt_80 = cfg_val; - else + mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_gt_80 = + cfg_val; + } else { return -EINVAL; + } + csr_update_session_he_cap(mac_ctx, session); return 0; @@ -12408,6 +12166,38 @@ int sme_update_he_twt_req_support(mac_handle_t mac_handle, uint8_t session_id, } #endif +QDF_STATUS +sme_update_session_txq_edca_params(mac_handle_t mac_handle, + uint8_t session_id, + tSirMacEdcaParamRecord *txq_edca_params) +{ + QDF_STATUS status; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct sir_update_session_txq_edca_param *msg; + + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_AGAIN; + + msg = qdf_mem_malloc(sizeof(*msg)); + if (!msg) + return QDF_STATUS_E_NOMEM; + + msg->message_type = eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS; + msg->vdev_id = session_id; + qdf_mem_copy(&msg->txq_edca_params, txq_edca_params, + sizeof(tSirMacEdcaParamRecord)); + msg->length = sizeof(*msg); + + status = umac_send_mb_message_to_mac(msg); + + sme_release_global_lock(&mac_ctx->sme); + if (status != QDF_STATUS_SUCCESS) + return QDF_STATUS_E_IO; + + return QDF_STATUS_SUCCESS; +} + /** * sme_set_nud_debug_stats_cb() - set nud debug stats callback * @mac_handle: Opaque handle to the global MAC context @@ -12566,26 +12356,31 @@ QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle) return sme_set_rssi_threshold_breached_cb(mac_handle, NULL); } -static enum band_info sme_get_connected_roaming_vdev_band(void) +/** + * sme_get_connected_roaming_vdev_band_mask() - get connected vdev band mask + * + * Return: reg wifi band mask + */ +static uint32_t sme_get_connected_roaming_vdev_band_mask(void) { - enum band_info band = BAND_ALL; + uint32_t band_mask = REG_BAND_MASK_ALL; struct mac_context *mac = sme_get_mac_context(); struct csr_roam_session *session; - uint8_t session_id, channel; + uint8_t session_id; if (!mac) { sme_debug("MAC Context is NULL"); - return band; + return band_mask; } session_id = csr_get_roam_enabled_sta_sessionid(mac); if (session_id != WLAN_UMAC_VDEV_ID_MAX) { session = CSR_GET_SESSION(mac, session_id); - channel = session->connectedProfile.operationChannel; - band = csr_get_rf_band(channel); - return band; + band_mask = BIT(wlan_reg_freq_to_band( + session->connectedProfile.op_freq)); + return band_mask; } - return band; + return band_mask; } /* @@ -12618,10 +12413,10 @@ QDF_STATUS sme_pdev_set_pcl(struct policy_mgr_pcl_list *msg) if (!req_msg) return QDF_STATUS_E_NOMEM; - req_msg->band = BAND_ALL; + req_msg->band_mask = REG_BAND_MASK_ALL; if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac)) { - req_msg->band = sme_get_connected_roaming_vdev_band(); - sme_debug("Connected STA band %d", req_msg->band); + req_msg->band_mask = sme_get_connected_roaming_vdev_band_mask(); + sme_debug("Connected STA band mask%d", req_msg->band_mask); } for (i = 0; i < msg->pcl_len; i++) { req_msg->chan_weights.pcl_list[i] = msg->pcl_list[i]; @@ -12685,7 +12480,7 @@ QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg) } cmd->command = e_sme_command_set_hw_mode; - cmd->sessionId = msg.session_id; + cmd->vdev_id = msg.session_id; cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index; cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb; cmd->u.set_hw_mode_cmd.reason = msg.reason; @@ -12709,6 +12504,7 @@ QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg) * @mac_handle: Handle returned by macOpen * @vdev_id: the session id * @new_nss: the new nss value + * @ch_width: channel width, optional value * @cback: hdd callback * @next_action: next action to happen at policy mgr after beacon update * @original_vdev_id: original request hwmode change vdev id @@ -12717,7 +12513,8 @@ QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg) * Return: QDF_STATUS_SUCCESS on successful posting */ QDF_STATUS sme_nss_update_request(uint32_t vdev_id, - uint8_t new_nss, policy_mgr_nss_update_cback cback, + uint8_t new_nss, uint8_t ch_width, + policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason, uint32_t original_vdev_id) @@ -12740,8 +12537,9 @@ QDF_STATUS sme_nss_update_request(uint32_t vdev_id, } cmd->command = e_sme_command_nss_update; /* Sessionized modules may require this info */ - cmd->sessionId = vdev_id; + cmd->vdev_id = vdev_id; cmd->u.nss_update_cmd.new_nss = new_nss; + cmd->u.nss_update_cmd.ch_width = ch_width; cmd->u.nss_update_cmd.session_id = vdev_id; cmd->u.nss_update_cmd.nss_update_cb = cback; cmd->u.nss_update_cmd.context = psoc; @@ -12798,10 +12596,10 @@ QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg) sme_debug("set_dual_mac_config scan_config: %x fw_mode_config: %x", cmd->u.set_dual_mac_cmd.scan_config, cmd->u.set_dual_mac_cmd.fw_mode_config); - csr_queue_sme_command(mac, cmd, false); + status = csr_queue_sme_command(mac, cmd, false); sme_release_global_lock(&mac->sme); - return QDF_STATUS_SUCCESS; + return status; } #ifdef FEATURE_LFR_SUBNET_DETECTION @@ -13344,7 +13142,7 @@ void sme_send_disassoc_req_frame(mac_handle_t mac_handle, uint8_t session_id, msg->msg_type = eWNI_SME_SEND_DISASSOC_FRAME; msg->length = sizeof(*msg); - msg->session_id = session_id; + msg->vdev_id = session_id; qdf_mem_copy(msg->peer_mac, peer_mac, QDF_MAC_ADDR_SIZE); msg->reason = reason; msg->wait_for_ack = wait_for_ack; @@ -13519,6 +13317,21 @@ QDF_STATUS sme_delete_mon_session(mac_handle_t mac_handle, uint8_t vdev_id) return status; } +void +sme_set_del_peers_ind_callback(mac_handle_t mac_handle, + void (*callback)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id)) +{ + struct mac_context *mac; + + if (!mac_handle) { + QDF_ASSERT(0); + return; + } + mac = MAC_CONTEXT(mac_handle); + mac->del_peers_ind_cb = callback; +} + void sme_set_chan_info_callback(mac_handle_t mac_handle, void (*callback)(struct scan_chan_info *chan_info)) { @@ -13532,27 +13345,28 @@ void sme_set_chan_info_callback(mac_handle_t mac_handle, mac->chan_info_cb = callback; } -/** - * sme_set_vdev_ies_per_band() - sends the per band IEs to vdev - * @mac_handle: Opaque handle to the global MAC context - * @vdev_id: vdev_id for which IE is targeted - * - * Return: None - */ -void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id) +void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, + enum QDF_OPMODE device_mode) { struct sir_set_vdev_ies_per_band *p_msg; QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + enum csr_cfgdot11mode curr_dot11_mode = + mac_ctx->roam.configParam.uCfgDot11Mode; p_msg = qdf_mem_malloc(sizeof(*p_msg)); if (!p_msg) return; + p_msg->vdev_id = vdev_id; + p_msg->device_mode = device_mode; + p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, device_mode, + curr_dot11_mode); p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND; p_msg->len = sizeof(*p_msg); - sme_debug("sending eWNI_SME_SET_VDEV_IES_PER_BAND: vdev_id: %d", - vdev_id); + sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d", + vdev_id, p_msg->dot11_mode, device_mode); status = umac_send_mb_message_to_mac(p_msg); if (QDF_STATUS_SUCCESS != status) sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail"); @@ -13705,7 +13519,7 @@ QDF_STATUS sme_set_he_bss_color(mac_handle_t mac_handle, uint8_t session_id, bss_color_msg->message_type = eWNI_SME_SET_HE_BSS_COLOR; bss_color_msg->length = len; - bss_color_msg->session_id = session_id; + bss_color_msg->vdev_id = session_id; bss_color_msg->bss_color = bss_color; return umac_send_mb_message_to_mac(bss_color_msg); } @@ -13794,14 +13608,7 @@ QDF_STATUS sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle, void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, uint8_t *nss_5g) { - struct mac_context *mac_ctx = sme_get_mac_context(); - - if (!mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("Invalid MAC context")); - return; - } - csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g); + csr_get_vdev_type_nss(dev_mode, nss_2g, nss_5g); } /** @@ -13812,7 +13619,7 @@ void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode, * skipped or not * @skip_unsafe_channels: Param to tell if driver needs to * skip unsafe channels or not. - * @param session_id: sme_session_id + * @vdev_id: vdev_id * @sap_operating_band: Band on which SAP is operating * * sme_update_sta_roam_policy update sta rome policies to csr @@ -13824,7 +13631,7 @@ void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode, QDF_STATUS sme_update_sta_roam_policy(mac_handle_t mac_handle, enum sta_roam_policy_dfs_mode dfs_mode, bool skip_unsafe_channels, - uint8_t session_id, + uint8_t vdev_id, uint8_t sap_operating_band) { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); @@ -13862,7 +13669,7 @@ QDF_STATUS sme_update_sta_roam_policy(mac_handle_t mac_handle, if (mac_ctx->mlme_cfg->lfr.roam_scan_offload_enabled) { status = sme_acquire_global_lock(&mac_ctx->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_update_cfg(mac_ctx, session_id, + csr_roam_update_cfg(mac_ctx, vdev_id, REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED); sme_release_global_lock(&mac_ctx->sme); } @@ -13934,7 +13741,7 @@ QDF_STATUS sme_set_default_scan_ie(mac_handle_t mac_handle, uint16_t session_id, else { set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE; set_ie_params->length = sizeof(*set_ie_params); - set_ie_params->session_id = session_id; + set_ie_params->vdev_id = session_id; set_ie_params->ie_len = ie_len; qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len); status = umac_send_mb_message_to_mac(set_ie_params); @@ -14192,43 +13999,37 @@ QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle, int8_t *rssi, int8_t *snr) { struct bss_description *bss_descp; - tCsrScanResultFilter *scan_filter; + struct scan_filter *scan_filter; struct scan_result_list *bss_list; tScanResultHandle result_handle = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); if (!scan_filter) { status = QDF_STATUS_E_NOMEM; - goto free_scan_flter; + goto exit; } - status = csr_roam_prepare_filter_from_profile(mac_ctx, - profile, scan_filter); + status = csr_roam_get_scan_filter_from_profile(mac_ctx, + profile, scan_filter, + false); if (QDF_STATUS_SUCCESS != status) { sme_err("prepare_filter failed"); - goto free_scan_flter; + qdf_mem_free(scan_filter); + goto exit; } /* update filter to get scan result with just target BSSID */ - if (!scan_filter->BSSIDs.bssid) { - scan_filter->BSSIDs.bssid = - qdf_mem_malloc(sizeof(struct qdf_mac_addr)); - if (!scan_filter->BSSIDs.bssid) { - status = QDF_STATUS_E_NOMEM; - goto free_scan_flter; - } - } - - scan_filter->BSSIDs.numOfBSSIDs = 1; - qdf_mem_copy(scan_filter->BSSIDs.bssid[0].bytes, + scan_filter->num_of_bssid = 1; + qdf_mem_copy(scan_filter->bssid_list[0].bytes, bssid, sizeof(struct qdf_mac_addr)); status = csr_scan_get_result(mac_ctx, scan_filter, &result_handle); + qdf_mem_free(scan_filter); if (QDF_STATUS_SUCCESS != status) { sme_debug("parse_scan_result failed"); - goto free_scan_flter; + goto exit; } bss_list = (struct scan_result_list *)result_handle; @@ -14236,7 +14037,7 @@ QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle, if (!bss_descp) { sme_err("unable to fetch bss descriptor"); status = QDF_STATUS_E_FAULT; - goto free_scan_flter; + goto exit; } sme_debug("snr: %d, rssi: %d, raw_rssi: %d", @@ -14247,13 +14048,7 @@ QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle, if (snr) *snr = bss_descp->sinr; -free_scan_flter: - /* free scan filter and exit */ - if (scan_filter) { - csr_free_scan_filter(mac_ctx, scan_filter); - qdf_mem_free(scan_filter); - } - +exit: if (result_handle) csr_scan_result_purge(mac_ctx, result_handle); @@ -14264,47 +14059,42 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, struct csr_roam_profile *profile, const tSirMacAddr bssid, uint8_t **frame_buf, uint32_t *frame_len, - int *channel) + uint32_t *ch_freq) { QDF_STATUS status = QDF_STATUS_SUCCESS; tScanResultHandle result_handle = NULL; - tCsrScanResultFilter *scan_filter; + struct scan_filter *scan_filter; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); struct bss_description *bss_descp; struct scan_result_list *bss_list; uint32_t ie_len; - scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); if (!scan_filter) { status = QDF_STATUS_E_NOMEM; - goto free_scan_flter; + goto exit; } - status = csr_roam_prepare_filter_from_profile(mac_ctx, - profile, scan_filter); + status = csr_roam_get_scan_filter_from_profile(mac_ctx, + profile, scan_filter, + false); if (QDF_IS_STATUS_ERROR(status)) { sme_err("prepare_filter failed"); status = QDF_STATUS_E_FAULT; - goto free_scan_flter; + qdf_mem_free(scan_filter); + goto exit; } /* update filter to get scan result with just target BSSID */ - if (!scan_filter->BSSIDs.bssid) { - scan_filter->BSSIDs.bssid = - qdf_mem_malloc(sizeof(struct qdf_mac_addr)); - if (!scan_filter->BSSIDs.bssid) { - status = QDF_STATUS_E_NOMEM; - goto free_scan_flter; - } - } - scan_filter->BSSIDs.numOfBSSIDs = 1; - qdf_mem_copy(scan_filter->BSSIDs.bssid[0].bytes, + scan_filter->num_of_bssid = 1; + qdf_mem_copy(scan_filter->bssid_list[0].bytes, bssid, sizeof(struct qdf_mac_addr)); status = csr_scan_get_result(mac_ctx, scan_filter, &result_handle); + qdf_mem_free(scan_filter); if (QDF_STATUS_SUCCESS != status) { sme_err("parse_scan_result failed"); status = QDF_STATUS_E_FAULT; - goto free_scan_flter; + goto exit; } bss_list = (struct scan_result_list *)result_handle; @@ -14312,7 +14102,7 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, if (!bss_descp) { sme_err("unable to fetch bss descriptor"); status = QDF_STATUS_E_FAULT; - goto free_scan_flter; + goto exit; } /** @@ -14328,27 +14118,22 @@ QDF_STATUS sme_get_beacon_frm(mac_handle_t mac_handle, */ ie_len = bss_descp->length + sizeof(bss_descp->length) - (uint16_t)(offsetof(struct bss_description, ieFields[0])); - sme_debug("found bss_descriptor ie_len: %d channel %d", - ie_len, bss_descp->channelId); + sme_debug("found bss_descriptor ie_len: %d frequency %d", + ie_len, bss_descp->chan_freq); /* include mac header and fixed params along with IEs in frame */ *frame_len = SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET + ie_len; *frame_buf = qdf_mem_malloc(*frame_len); if (!*frame_buf) { status = QDF_STATUS_E_NOMEM; - goto free_scan_flter; + goto exit; } sme_prepare_beacon_from_bss_descp(*frame_buf, bss_descp, bssid, ie_len); - if (!*channel) - *channel = bss_descp->channelId; -free_scan_flter: - /* free scan filter and exit */ - if (scan_filter) { - csr_free_scan_filter(mac_ctx, scan_filter); - qdf_mem_free(scan_filter); - } + if (!*ch_freq) + *ch_freq = bss_descp->chan_freq; +exit: if (result_handle) csr_scan_result_purge(mac_ctx, result_handle); @@ -14439,30 +14224,59 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id) QDF_STATUS sme_fast_reassoc(mac_handle_t mac_handle, struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, - uint8_t vdev_id, const tSirMacAddr connected_bssid) + const tSirMacAddr bssid, uint32_t ch_freq, + uint8_t vdev_id, + const tSirMacAddr connected_bssid) { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct mac_context *mac = MAC_CONTEXT(mac_handle); if (!mac) return QDF_STATUS_E_FAILURE; + if (!CSR_IS_SESSION_VALID(mac, vdev_id)) { sme_err("Invalid vdev_id: %d", vdev_id); return QDF_STATUS_E_INVAL; } + if (QDF_IS_STATUS_ERROR(sme_acquire_global_lock(&mac->sme))) return QDF_STATUS_E_FAILURE; - status = csr_fast_reassoc(mac_handle, profile, bssid, channel, vdev_id, + status = csr_fast_reassoc(mac_handle, profile, bssid, ch_freq, vdev_id, connected_bssid); sme_release_global_lock(&mac->sme); return status; } + #endif +void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + tPmkidCacheInfo *pmk_cache_info) +{ + struct wlan_crypto_pmksa *pmksa; + struct wlan_objmgr_vdev *vdev; + tPmkidCacheInfo pmk_to_del; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return; + } + pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache_info->BSSID); + if (!pmksa) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return; + } + qdf_mem_copy(&pmk_to_del.pmk, pmksa->pmk, pmksa->pmk_len); + pmk_to_del.pmk_len = pmksa->pmk_len; + csr_clear_sae_single_pmk(psoc, session_id, &pmk_to_del); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); +} + QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, uint8_t session_id, tPmkidCacheInfo *pmk_cache_info, @@ -14481,6 +14295,7 @@ QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, if (!pmk_cache_info) { pmk_cache->is_flush_all = true; + csr_clear_sae_single_pmk(psoc, session_id, NULL); goto send_flush_cmd; } @@ -14741,22 +14556,6 @@ void sme_store_pdev(mac_handle_t mac_handle, struct wlan_objmgr_pdev *pdev) pdev->pdev_nif.pdev_fw_caps |= SUPPORTED_CRYPTO_CAPS; } -QDF_STATUS sme_congestion_register_callback(mac_handle_t mac_handle, - congestion_cb congestion_cb) -{ - QDF_STATUS status; - struct mac_context *mac = MAC_CONTEXT(mac_handle); - - status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(status)) { - mac->sme.congestion_cb = congestion_cb; - sme_release_global_lock(&mac->sme); - sme_debug("congestion callback set"); - } - - return status; -} - QDF_STATUS sme_register_tx_queue_cb(mac_handle_t mac_handle, tx_queue_cb tx_queue_cb) { @@ -15058,11 +14857,12 @@ void sme_add_qcn_ie(mac_handle_t mac_handle, uint8_t *ie_data, uint16_t *ie_len) { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - uint8_t qcn_ie[] = {WLAN_ELEMID_VENDOR, 8, - 0x8C, 0xFD, 0xF0, 0x1, QCN_IE_VERSION_SUBATTR_ID, - QCN_IE_VERSION_SUBATTR_DATA_LEN, - QCN_IE_VERSION_SUPPORTED, - QCN_IE_SUBVERSION_SUPPORTED}; + static const uint8_t qcn_ie[] = {WLAN_ELEMID_VENDOR, 8, + 0x8C, 0xFD, 0xF0, 0x1, + QCN_IE_VERSION_SUBATTR_ID, + QCN_IE_VERSION_SUBATTR_DATA_LEN, + QCN_IE_VERSION_SUPPORTED, + QCN_IE_SUBVERSION_SUPPORTED}; if (!mac_ctx->mlme_cfg->sta.qcn_ie_support) { sme_debug("QCN IE is not supported"); @@ -15101,6 +14901,8 @@ static bool sme_get_status_for_candidate(mac_handle_t mac_handle, struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); struct wlan_mlme_mbo *mbo_cfg; int8_t current_rssi_mcc_thres; + uint32_t bss_chan_freq, conn_bss_chan_freq; + bool bss_chan_safe, conn_bss_chan_safe; if (!(mac_ctx->mlme_cfg)) { pe_err("mlme cfg is NULL"); @@ -15116,14 +14918,16 @@ static bool sme_get_status_for_candidate(mac_handle_t mac_handle, */ if ((bss_desc->rssi < mbo_cfg->mbo_candidate_rssi_thres) && (conn_bss_desc->rssi > mbo_cfg->mbo_current_rssi_thres)) { - sme_err("Candidate BSS "QDF_MAC_ADDR_STR" has LOW RSSI(%d), hence reject", - QDF_MAC_ADDR_ARRAY(bss_desc->bssId), bss_desc->rssi); + sme_err("Candidate BSS "QDF_MAC_ADDR_FMT" has LOW RSSI(%d), hence reject", + QDF_MAC_ADDR_REF(bss_desc->bssId), bss_desc->rssi); info->status = QCA_STATUS_REJECT_LOW_RSSI; return true; } if (trans_reason == MBO_TRANSITION_REASON_LOAD_BALANCING || trans_reason == MBO_TRANSITION_REASON_TRANSITIONING_TO_PREMIUM_AP) { + bss_chan_freq = bss_desc->chan_freq; + conn_bss_chan_freq = conn_bss_desc->chan_freq; /* * MCC rejection * If moving to candidate's channel will result in MCC scenario @@ -15133,9 +14937,9 @@ static bool sme_get_status_for_candidate(mac_handle_t mac_handle, */ current_rssi_mcc_thres = mbo_cfg->mbo_current_rssi_mcc_thres; if ((conn_bss_desc->rssi > current_rssi_mcc_thres) && - csr_is_mcc_channel(mac_ctx, bss_desc->channelId)) { - sme_err("Candidate BSS "QDF_MAC_ADDR_STR" causes MCC, hence reject", - QDF_MAC_ADDR_ARRAY(bss_desc->bssId)); + csr_is_mcc_channel(mac_ctx, bss_chan_freq)) { + sme_err("Candidate BSS "QDF_MAC_ADDR_FMT" causes MCC, hence reject", + QDF_MAC_ADDR_REF(bss_desc->bssId)); info->status = QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY; return true; @@ -15148,12 +14952,12 @@ static bool sme_get_status_for_candidate(mac_handle_t mac_handle, * less than mbo_candidate_rssi_btc_thres, then reject the * candidate with MBO reason code 2. */ - if (WLAN_REG_IS_5GHZ_CH(conn_bss_desc->channelId) && - WLAN_REG_IS_24GHZ_CH(bss_desc->channelId) && + if (WLAN_REG_IS_5GHZ_CH_FREQ(conn_bss_chan_freq) && + WLAN_REG_IS_24GHZ_CH_FREQ(bss_chan_freq) && is_bt_in_progress && (bss_desc->rssi < mbo_cfg->mbo_candidate_rssi_btc_thres)) { - sme_err("Candidate BSS "QDF_MAC_ADDR_STR" causes BT coex, hence reject", - QDF_MAC_ADDR_ARRAY(bss_desc->bssId)); + sme_err("Candidate BSS "QDF_MAC_ADDR_FMT" causes BT coex, hence reject", + QDF_MAC_ADDR_REF(bss_desc->bssId)); info->status = QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED; return true; @@ -15164,13 +14968,15 @@ static bool sme_get_status_for_candidate(mac_handle_t mac_handle, * If moving to candidate's channel can cause LTE coex, then * reject the candidate with MBO reason code 5. */ - if (policy_mgr_is_safe_channel(mac_ctx->psoc, - conn_bss_desc->channelId) && - !(policy_mgr_is_safe_channel(mac_ctx->psoc, - bss_desc->channelId))) { + conn_bss_chan_safe = policy_mgr_is_safe_channel( + mac_ctx->psoc, conn_bss_chan_freq); + bss_chan_safe = policy_mgr_is_safe_channel( + mac_ctx->psoc, bss_chan_freq); + + if (conn_bss_chan_safe && !bss_chan_safe) { sme_err("High interference expected if transitioned to BSS " - QDF_MAC_ADDR_STR" hence reject", - QDF_MAC_ADDR_ARRAY(bss_desc->bssId)); + QDF_MAC_ADDR_FMT" hence reject", + QDF_MAC_ADDR_REF(bss_desc->bssId)); info->status = QCA_STATUS_REJECT_HIGH_INTERFERENCE; return true; @@ -15221,8 +15027,8 @@ QDF_STATUS sme_get_bss_transition_status(mac_handle_t mac_handle, &info[i].bssid, res); if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_err("BSS "QDF_MAC_ADDR_STR" not present in scan list", - QDF_MAC_ADDR_ARRAY(info[i].bssid.bytes)); + sme_err("BSS "QDF_MAC_ADDR_FMT" not present in scan list", + QDF_MAC_ADDR_REF(info[i].bssid.bytes)); info[i].status = QCA_STATUS_REJECT_UNKNOWN; continue; } @@ -15277,11 +15083,10 @@ void sme_enable_roaming_on_connected_sta(mac_handle_t mac_handle, int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev) { - uint8_t vdev_id, chan; + uint8_t vdev_id; struct csr_roam_session *session; struct mac_context *mac_ctx; mac_handle_t mac_handle; - int16_t freq = 0; if (!vdev) { sme_err("Invalid vdev id is passed"); @@ -15301,11 +15106,8 @@ int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev) } session = CSR_GET_SESSION(mac_ctx, vdev_id); - chan = csr_get_infra_operation_channel(mac_ctx, vdev_id); - if (chan) - freq = cds_chan_to_freq(chan); - return freq; + return csr_get_infra_operation_chan_freq(mac_ctx, vdev_id); } enum phy_ch_width sme_get_oper_ch_width(struct wlan_objmgr_vdev *vdev) @@ -15394,15 +15196,15 @@ QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, sae_msg->message_type = eWNI_SME_SEND_SAE_MSG; sae_msg->length = sizeof(*sae_msg); - sae_msg->session_id = session_id; + sae_msg->vdev_id = session_id; sae_msg->sae_status = sae_status; qdf_mem_copy(sae_msg->peer_mac_addr, peer_mac_addr.bytes, QDF_MAC_ADDR_SIZE); - sme_debug("SAE: sae_status %d session_id %d Peer: " - QDF_MAC_ADDR_STR, sae_msg->sae_status, - sae_msg->session_id, - QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr)); + sme_debug("SAE: sae_status %d vdev_id %d Peer: " + QDF_MAC_ADDR_FMT, sae_msg->sae_status, + sae_msg->vdev_id, + QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr)); sch_msg.type = eWNI_SME_SEND_SAE_MSG; sch_msg.bodyptr = sae_msg; @@ -15475,7 +15277,7 @@ bool sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle, } bool sme_validate_channel_list(mac_handle_t mac_handle, - uint8_t *chan_list, + uint32_t *chan_freq_list, uint8_t num_channels) { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); @@ -15484,22 +15286,24 @@ bool sme_validate_channel_list(mac_handle_t mac_handle, bool found; struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels; - if (!chan_list || !num_channels) { - sme_err("Chan list empty %pK or num_channels is 0", chan_list); + if (!chan_freq_list || !num_channels) { + sme_err("Chan list empty %pK or num_channels is 0", + chan_freq_list); return false; } while (i < num_channels) { found = false; for (j = 0; j < ch_lst_info->numChannels; j++) { - if (ch_lst_info->channelList[j] == chan_list[i]) { + if (ch_lst_info->channel_freq_list[j] == + chan_freq_list[i]) { found = true; break; } } if (!found) { - sme_debug("Invalid channel %d", chan_list[i]); + sme_debug("Invalid channel %d", chan_freq_list[i]); return false; } @@ -15536,6 +15340,7 @@ void sme_set_he_testbed_def(mac_handle_t mac_handle, uint8_t vdev_id) mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_80_in_160_80p80Mhz = 0; mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_tx = 0; mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_rx = 0; + mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_mu = 0; mac_ctx->mlme_cfg->he_caps.dot11_he_cap.max_nc = 0; mac_ctx->mlme_cfg->he_caps.dot11_he_cap.trigger_frm_mac_pad = QCA_WLAN_HE_16US_OF_PROCESS_TIME; @@ -15749,22 +15554,15 @@ void sme_update_score_config(mac_handle_t mac_handle, mlme_scoring_cfg->oce_wan_scoring.score_pcnt15_to_12; } -void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id) +static void +__sme_enable_fw_module_log_level(uint8_t *enable_fw_module_log_level, + uint8_t enable_fw_module_log_level_num, + int vdev_id, int param_id) { - QDF_STATUS status; - struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - uint8_t *enable_fw_module_log_level; - uint8_t enable_fw_module_log_level_num; uint8_t count = 0; uint32_t value = 0; int ret; - status = ucfg_fwol_get_enable_fw_module_log_level( - mac_ctx->psoc, &enable_fw_module_log_level, - &enable_fw_module_log_level_num); - if (QDF_IS_STATUS_ERROR(status)) - return; - while (count < enable_fw_module_log_level_num) { /* * FW module log level input array looks like @@ -15795,9 +15593,7 @@ void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id) value = enable_fw_module_log_level[count] << 16; value |= enable_fw_module_log_level[count + 1]; - ret = sme_cli_set_command(vdev_id, - WMI_DBGLOG_MOD_LOG_LEVEL, - value, DBG_CMD); + ret = sme_cli_set_command(vdev_id, param_id, value, DBG_CMD); if (ret != 0) sme_err("Failed to enable FW module log level %d ret %d", value, ret); @@ -15806,7 +15602,62 @@ void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id) } } +void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id) +{ + QDF_STATUS status; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + uint8_t *enable_fw_module_log_level; + uint8_t enable_fw_module_log_level_num; + + status = ucfg_fwol_get_enable_fw_module_log_level( + mac_ctx->psoc, &enable_fw_module_log_level, + &enable_fw_module_log_level_num); + if (QDF_IS_STATUS_ERROR(status)) + return; + __sme_enable_fw_module_log_level(enable_fw_module_log_level, + enable_fw_module_log_level_num, + vdev_id, + WMI_DBGLOG_MOD_LOG_LEVEL); + + enable_fw_module_log_level_num = 0; + status = ucfg_fwol_wow_get_enable_fw_module_log_level( + mac_ctx->psoc, &enable_fw_module_log_level, + &enable_fw_module_log_level_num); + if (QDF_IS_STATUS_ERROR(status)) + return; + __sme_enable_fw_module_log_level(enable_fw_module_log_level, + enable_fw_module_log_level_num, + vdev_id, + WMI_DBGLOG_MOD_WOW_LOG_LEVEL); +} + #ifdef WLAN_FEATURE_MOTION_DETECTION +/** + * sme_set_md_bl_evt_cb - Register/set motion detection baseline callback + * @mac_handle: mac handle + * @callback_fn: callback function pointer + * @hdd_ctx: hdd context + * + * Return: QDF_STATUS_SUCCESS or non-zero on failure + */ +QDF_STATUS sme_set_md_bl_evt_cb( + mac_handle_t mac_handle, + QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_bl_evt *event), + void *hdd_ctx +) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + + qdf_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(qdf_status)) { + mac->sme.md_bl_evt_cb = callback_fn; + mac->sme.md_ctx = hdd_ctx; + sme_release_global_lock(&mac->sme); + } + return qdf_status; +} + /** * sme_set_md_host_evt_cb - Register/set motion detection callback * @mac_handle: mac handle @@ -16292,19 +16143,6 @@ QDF_STATUS sme_set_disconnect_ies(mac_handle_t mac_handle, uint8_t vdev_id, return QDF_STATUS_SUCCESS; } -void sme_freq_to_chan_list( - struct wlan_objmgr_pdev *pdev, - uint8_t *chan_list, - uint32_t *freq_list, - uint32_t chan_list_len) -{ - uint32_t count; - - for (count = 0; count < chan_list_len; count++) - chan_list[count] = - (uint8_t)wlan_reg_freq_to_chan(pdev, freq_list[count]); -} - void sme_chan_to_freq_list( struct wlan_objmgr_pdev *pdev, uint32_t *freq_list, @@ -16425,9 +16263,8 @@ QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle, cfg_params->roam_inactive_data_packet_count = 0; cfg_params->roam_scan_inactivity_time = 0; - csr_roam_offload_scan(mac, vdev_id, - ROAM_SCAN_OFFLOAD_UPDATE_CFG, - REASON_ROAM_CONTROL_CONFIG_ENABLED); + csr_roam_update_cfg(mac, vdev_id, + REASON_ROAM_CONTROL_CONFIG_ENABLED); } sme_release_global_lock(&mac->sme); @@ -16491,41 +16328,57 @@ sme_get_full_roam_scan_period(mac_handle_t mac_handle, uint8_t vdev_id, return status; } -#ifdef FEATURE_OEM_DATA -QDF_STATUS sme_set_oem_data_event_handler_cb( - mac_handle_t mac_handle, - void (*oem_data_event_handler_cb) - (const struct oem_data *oem_event_data)) +QDF_STATUS sme_check_for_duplicate_session(mac_handle_t mac_handle, + uint8_t *peer_addr) { - struct mac_context *mac = MAC_CONTEXT(mac_handle); - QDF_STATUS qdf_status; + QDF_STATUS status = QDF_STATUS_E_INVAL; + bool peer_exist = false; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - qdf_status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) { - mac->sme.oem_data_event_handler_cb = oem_data_event_handler_cb; - sme_release_global_lock(&mac->sme); + if (!soc) { + sme_err("Failed to get soc handle"); + return QDF_STATUS_E_INVAL; } - return qdf_status; + + if (QDF_STATUS_SUCCESS != sme_acquire_global_lock(&mac_ctx->sme)) + return status; + + peer_exist = cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, peer_addr); + if (peer_exist) { + sme_err("Peer exists with same MAC"); + status = QDF_STATUS_E_EXISTS; + } else { + status = QDF_STATUS_SUCCESS; + } + sme_release_global_lock(&mac_ctx->sme); + + return status; } -void sme_reset_oem_data_event_handler_cb(mac_handle_t mac_handle) +#ifdef FEATURE_ANI_LEVEL_REQUEST +QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs, + uint8_t num_freqs, void (*callback)( + struct wmi_host_ani_level_event *ani, uint8_t num, + void *context), void *context) { - struct mac_context *pmac; - QDF_STATUS qdf_status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + void *wma_handle; - if (!mac_handle) { - sme_err("mac_handle is not valid"); - return; + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + sme_err("wma handle is NULL"); + return QDF_STATUS_E_FAILURE; } - pmac = MAC_CONTEXT(mac_handle); - qdf_status = sme_acquire_global_lock(&pmac->sme); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) { - pmac->sme.oem_data_event_handler_cb = NULL; - sme_release_global_lock(&pmac->sme); - } + mac->ani_params.ani_level_cb = callback; + mac->ani_params.context = context; + + status = wma_send_ani_level_request(wma_handle, freqs, num_freqs); + return status; } -#endif +#endif /* FEATURE_ANI_LEVEL_REQUEST */ QDF_STATUS sme_get_prev_connected_bss_ies(mac_handle_t mac_handle, uint8_t vdev_id, @@ -16573,3 +16426,46 @@ QDF_STATUS sme_get_prev_connected_bss_ies(mac_handle_t mac_handle, sme_release_global_lock(&mac->sme); return status; } + +#ifdef FEATURE_MONITOR_MODE_SUPPORT + +QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle, + void (*monitor_mode_cb)(uint8_t vdev_id)) +{ + QDF_STATUS qdf_status; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + qdf_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + sme_err("Failed to acquire sme lock; status: %d", qdf_status); + return qdf_status; + } + mac->sme.monitor_mode_cb = monitor_mode_cb; + sme_release_global_lock(&mac->sme); + + return qdf_status; +} + +QDF_STATUS sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id) +{ + mac_handle_t mac_handle; + struct mac_context *mac; + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + if (!mac_handle) { + sme_err("mac_handle is not valid"); + return QDF_STATUS_E_INVAL; + } + + mac = MAC_CONTEXT(mac_handle); + + if (mac->sme.monitor_mode_cb) + mac->sme.monitor_mode_cb(vdev_id); + else { + sme_warn_rl("monitor_mode_cb is not registered"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c index d93470c7a7acd4854ad897ab732e0b6a0e3aa3a5..63c353a71e5614e2250bbd5c1f22ce076cf93843 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -221,93 +221,6 @@ void sme_set_ft_ies(mac_handle_t mac_handle, uint32_t session_id, sme_release_global_lock(&mac_ctx->sme); } -/** - * sme_ft_send_update_key_ind() - To send key update indication for FT session - * @mac: pointer to MAC context - * @session_id: sme session id - * @ftkey_info: FT key information - * - * To send key update indication for FT session - * - * Return: QDF_STATUS - */ -static -QDF_STATUS sme_ft_send_update_key_ind(struct mac_context *mac, uint32_t session_id, - tCsrRoamSetKey *ftkey_info) -{ - tSirFTUpdateKeyInfo *msg; - uint16_t msglen; - QDF_STATUS status = QDF_STATUS_E_FAILURE; - tSirKeyMaterial *keymaterial = NULL; - tAniEdType ed_type; - - sme_debug("keyLength: %d", ftkey_info->keyLength); - - if (ftkey_info->keyLength > CSR_MAX_KEY_LEN) { - sme_err("invalid keyLength: %d", ftkey_info->keyLength); - return QDF_STATUS_E_FAILURE; - } - msglen = sizeof(tSirFTUpdateKeyInfo); - - msg = qdf_mem_malloc(msglen); - if (!msg) - return QDF_STATUS_E_NOMEM; - - msg->messageType = eWNI_SME_FT_UPDATE_KEY; - msg->length = msglen; - - keymaterial = &msg->keyMaterial; - keymaterial->length = ftkey_info->keyLength; - ed_type = csr_translate_encrypt_type_to_ed_type(ftkey_info->encType); - keymaterial->edType = ed_type; - keymaterial->numKeys = 1; - keymaterial->key[0].keyId = ftkey_info->keyId; - keymaterial->key[0].unicast = (uint8_t) true; - keymaterial->key[0].keyDirection = ftkey_info->keyDirection; - - qdf_mem_copy(&keymaterial->key[0].keyRsc, - ftkey_info->keyRsc, WLAN_CRYPTO_RSC_SIZE); - keymaterial->key[0].paeRole = ftkey_info->paeRole; - keymaterial->key[0].keyLength = ftkey_info->keyLength; - - if (ftkey_info->keyLength) - qdf_mem_copy(&keymaterial->key[0].key, ftkey_info->Key, - ftkey_info->keyLength); - - qdf_copy_macaddr(&msg->bssid, &ftkey_info->peerMac); - msg->smeSessionId = session_id; - sme_debug("BSSID = " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(msg->bssid.bytes)); - status = umac_send_mb_message_to_mac(msg); - - return status; -} - -bool sme_get_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId) -{ - struct mac_context *mac = MAC_CONTEXT(mac_handle); - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("pSession is NULL"); - return false; - } - return pSession->ftSmeContext.setFTPTKState; -} - -void sme_set_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId, - bool state) -{ - struct mac_context *mac = MAC_CONTEXT(mac_handle); - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("pSession is NULL"); - return; - } - pSession->ftSmeContext.setFTPTKState = state; -} - QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id) { struct mac_context *mac = MAC_CONTEXT(mac_handle); @@ -348,63 +261,6 @@ QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id) return status; } -QDF_STATUS sme_ft_update_key(mac_handle_t mac_handle, uint32_t sessionId, - tCsrRoamSetKey *pFTKeyInfo) -{ - struct mac_context *mac = MAC_CONTEXT(mac_handle); - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - QDF_STATUS status = QDF_STATUS_E_FAILURE; - - if (!pSession) { - sme_err("pSession is NULL"); - return QDF_STATUS_E_FAILURE; - } - - if (!pFTKeyInfo) { - sme_err("pFTKeyInfo is NULL"); - return QDF_STATUS_E_FAILURE; - } - - status = sme_acquire_global_lock(&mac->sme); - if (!(QDF_IS_STATUS_SUCCESS(status))) - return QDF_STATUS_E_FAILURE; - - sme_debug("FT update key is received in state %d", - pSession->ftSmeContext.FTState); - - /* Global Station FT State */ - switch (pSession->ftSmeContext.FTState) { - case eFT_SET_KEY_WAIT: - if (sme_get_ft_pre_auth_state(mac_handle, sessionId) == true) { - status = sme_ft_send_update_key_ind(mac, sessionId, - pFTKeyInfo); - if (status != 0) { - sme_err("Key set failure: %d", status); - pSession->ftSmeContext.setFTPTKState = false; - status = QDF_STATUS_FT_PREAUTH_KEY_FAILED; - } else { - pSession->ftSmeContext.setFTPTKState = true; - status = QDF_STATUS_FT_PREAUTH_KEY_SUCCESS; - sme_debug("Key set success"); - } - sme_set_ft_pre_auth_state(mac_handle, sessionId, false); - } - - pSession->ftSmeContext.FTState = eFT_START_READY; - sme_debug("state changed to %d status %d", - pSession->ftSmeContext.FTState, status); - break; - - default: - sme_debug("Unhandled state:%d", pSession->ftSmeContext.FTState); - status = QDF_STATUS_E_FAILURE; - break; - } - sme_release_global_lock(&mac->sme); - - return status; -} - /* * HDD Interface to SME. SME now sends the Auth 2 and RIC IEs up to the * supplicant. The supplicant will then proceed to send down the @@ -573,7 +429,6 @@ void sme_ft_reset(mac_handle_t mac_handle, uint32_t sessionId) pSession->ftSmeContext.psavedFTPreAuthRsp = NULL; } pSession->ftSmeContext.setFTPreAuthState = false; - pSession->ftSmeContext.setFTPTKState = false; qdf_mem_zero(pSession->ftSmeContext.preAuthbssId, QDF_MAC_ADDR_SIZE); diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_power_save.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_power_save.c index 850b8d615eee2b35ffd65ea42d5c8c47ba8df09c..403b76d830351c159c350913efd773030c5e75c6 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_power_save.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_power_save.c @@ -166,6 +166,7 @@ sme_ps_enable_ps_req_params(struct mac_context *mac_ctx, uint32_t vdev_id) wma_enable_sta_ps_mode(enable_ps_req_params); qdf_mem_free(enable_ps_req_params); + sme_debug("Powersave Enable sent to FW"); ps_param->ps_state = ps_state; @@ -390,8 +391,6 @@ QDF_STATUS sme_ps_enable_disable(mac_handle_t mac_handle, uint32_t session_id, * In non associated state driver wont handle the power save * But kernel expects return status success even * in the disconnected state. - * TODO: If driver to remember the ps state to further use - * after connection. */ if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) status = QDF_STATUS_SUCCESS; @@ -751,6 +750,7 @@ QDF_STATUS sme_ps_enable_auto_ps_timer(mac_handle_t mac_handle, struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; struct ps_params *ps_param = &ps_global_info->ps_params[session_id]; QDF_STATUS qdf_status; + QDF_TIMER_STATE cur_state; if (!timeout && !mac_ctx->usr_cfg_ps_enable) { sme_debug("auto_ps_timer called with timeout 0; ignore"); @@ -759,8 +759,15 @@ QDF_STATUS sme_ps_enable_auto_ps_timer(mac_handle_t mac_handle, if (!timeout) timeout = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE; - sme_debug("Start auto_ps_timer for %d ms", timeout); + cur_state = + qdf_mc_timer_get_current_state(&ps_param->auto_ps_enable_timer); + if (cur_state == QDF_TIMER_STATE_STARTING || + cur_state == QDF_TIMER_STATE_RUNNING) { + sme_debug("auto_ps_timer is already started: %d", cur_state); + return QDF_STATUS_SUCCESS; + } + sme_debug("Start auto_ps_timer for %d ms", timeout); qdf_status = qdf_mc_timer_start(&ps_param->auto_ps_enable_timer, timeout); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { @@ -772,6 +779,7 @@ QDF_STATUS sme_ps_enable_auto_ps_timer(mac_handle_t mac_handle, return QDF_STATUS_E_FAILURE; } } + return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_trace.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_trace.c index a84a6977dfcf082780d6f9b4a3cb95380b79fad0..f09ad8a6d00ca3b06951d29ebfb4948a6ac0ac7b 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_trace.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_trace.c @@ -85,8 +85,6 @@ static uint8_t *sme_trace_get_rx_msg_string(uint32_t code) CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXIT_WOWL); CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_KEY); CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMOVE_KEY); - CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_STATS); - CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_RSSI); CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE); CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE); CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY); @@ -161,7 +159,6 @@ static uint8_t *sme_trace_get_command_string(uint32_t command) CASE_RETURN_STRING(eSmeCsrCommandMask); CASE_RETURN_STRING(eSmeCommandRoam); CASE_RETURN_STRING(eSmeCommandWmStatusChange); - CASE_RETURN_STRING(e_sme_command_del_sta_session); CASE_RETURN_STRING(eSmeQosCommandMask); CASE_RETURN_STRING(eSmeCommandAddTs); CASE_RETURN_STRING(eSmeCommandDelTs); @@ -180,31 +177,31 @@ static void sme_trace_dump(void *mac_ctx, tp_qdf_trace_record record, switch (record->code) { case TRACE_CODE_SME_COMMAND: sme_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", - rec_index, record->qtime, record->time, record->session, - "SME COMMAND:", - sme_trace_get_command_string(record->data), - record->data); + rec_index, record->qtime, record->time, + record->session, "SME COMMAND:", + sme_trace_get_command_string(record->data), + record->data); break; case TRACE_CODE_SME_TX_WMA_MSG: sme_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", - rec_index, record->qtime, record->time, record->session, - "TX WMA Msg:", - mac_trace_get_wma_msg_string((uint16_t)record->data), - record->data); + rec_index, record->qtime, record->time, + record->session, "TX WMA Msg:", + mac_trace_get_wma_msg_string((uint16_t)record->data), + record->data); break; case TRACE_CODE_SME_RX_WMA_MSG: sme_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", - rec_index, record->qtime, record->time, record->session, - "RX WMA Msg:", - mac_trace_get_sme_msg_string((uint16_t)record->data), - record->data); + rec_index, record->qtime, record->time, record->session, + "RX WMA Msg:", + mac_trace_get_sme_msg_string((uint16_t)record->data), + record->data); break; default: sme_nofl_debug("%04d %012llu %s S%d %-14s %-30s(0x%x)", - rec_index, record->qtime, record->time, record->session, - "RX HDD MSG:", - sme_trace_get_rx_msg_string(record->code), - record->data); + rec_index, record->qtime, record->time, record->session, + "RX HDD MSG:", + sme_trace_get_rx_msg_string(record->code), + record->data); break; } } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c index d3e4294abb35a1380aadaa84da7a99f04267f1bc..f7164f231239443ff9d4eadc932f8d3d76813f43 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,8 +68,9 @@ #include "wlan_scan_utils_api.h" #include "wlan_p2p_cfg_api.h" #include "cfg_nan_api.h" +#include "nan_ucfg_api.h" -#include "wlan_pkt_capture_ucfg_api.h" +#include #define RSN_AUTH_KEY_MGMT_SAE WLAN_RSN_SEL(WLAN_AKM_SAE) #define MAX_PWR_FCC_CHAN_12 8 @@ -183,9 +184,9 @@ static QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } - sme_debug("vdev_id %d "QDF_MAC_ADDR_STR"", + sme_debug("vdev_id %d "QDF_MAC_ADDR_FMT, sae_info->vdev_id, - QDF_MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes)); + QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes)); session_id = sae_info->vdev_id; if (session_id == WLAN_UMAC_VDEV_ID_MAX) @@ -229,8 +230,6 @@ enum mgmt_auth_type diag_auth_type_from_csr_type(enum csr_akm_type authtype) n = AUTH_WPA_PSK; break; case eCSR_AUTH_TYPE_RSN: - case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256: - case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384: #ifdef WLAN_FEATURE_11W case eCSR_AUTH_TYPE_RSN_8021X_SHA256: #endif @@ -386,27 +385,26 @@ enum mgmt_bss_type diag_persona_from_csr_type(enum QDF_OPMODE persona) } #endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */ -static const uint8_t -csr_start_ibss_channels50[CSR_NUM_IBSS_START_CHAN_50] = { 36, 44, 52, 56, 140 }; -static const uint8_t -csr_start_ibss_channels24[CSR_NUM_IBSS_START_CHANNELS_24] = { 1, 6, 11 }; +static const uint32_t +csr_start_ibss_channels50[CSR_NUM_IBSS_START_CHAN_50] = + { 5180, 5220, 5260, 5280, 5700 }; +static const uint32_t +csr_start_ibss_channels24[CSR_NUM_IBSS_START_CHANNELS_24] = + { 2412, 2437, 2462 }; -static const uint8_t -social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 }; +static const uint32_t +social_channel_freq[MAX_SOCIAL_CHANNELS] = { 2412, 2437, 2462 }; static void init_config_param(struct mac_context *mac); static bool csr_roam_process_results(struct mac_context *mac, tSmeCmd *pCommand, enum csr_roamcomplete_result Result, void *Context); -static QDF_STATUS csr_roam_start_ibss(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - bool *pfSameIbss); static void csr_roam_update_connected_profile_from_new_bss(struct mac_context *mac, uint32_t sessionId, struct new_bss_info * pNewBss); static ePhyChanBondState csr_get_cb_mode_from_ies(struct mac_context *mac, - uint8_t primaryChn, + uint32_t primary_ch_freq, tDot11fBeaconIEs *pIes); static void csr_roaming_state_config_cnf_processor(struct mac_context *mac, @@ -437,53 +435,15 @@ static QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac, struct csr_roam_connectedinfo * pConnectedInfo); -static QDF_STATUS csr_send_mb_set_context_req_msg(struct mac_context *mac, - uint32_t sessionId, - struct qdf_mac_addr peer_macaddr, - uint8_t numKeys, - tAniEdType edType, bool fUnicast, - tAniKeyDirection aniKeyDirection, - uint8_t keyId, uint8_t keyLength, - uint8_t *pKey, uint8_t paeRole, - uint8_t *pKeyRsc); static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid); static void csr_roam_link_down(struct mac_context *mac, uint32_t sessionId); -#ifndef QCA_SUPPORT_CP_STATS -static QDF_STATUS csr_send_mb_stats_req_msg(struct mac_context *mac, - uint32_t statsMask, uint8_t staId, - uint8_t sessionId); -/* pStaEntry is no longer invalid upon the return of this function. */ -static void csr_roam_remove_stat_list_entry(struct mac_context *mac, - tListElem *pEntry); -struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list( - struct mac_context *mac, tDblLinkList *pStaList, - struct csr_statsclient_reqinfo * - pStaEntry); -static void csr_roam_report_statistics(struct mac_context *mac, - uint32_t statsMask, tCsrStatsCallback callback, uint8_t staId, - void *pContext); -tListElem *csr_roam_check_client_req_list( - struct mac_context *mac, uint32_t statsMask); -static void csr_roam_remove_entry_from_pe_stats_req_list( - struct mac_context *mac, struct csr_pestats_reqinfo *pPeStaEntry); -tListElem *csr_roam_find_in_pe_stats_req_list( - struct mac_context *mac, - uint32_t statsMask); -static QDF_STATUS csr_roam_dereg_statistics_req(struct mac_context *mac); -#else -static QDF_STATUS csr_roam_dereg_statistics_req(struct mac_context *mac) -{ - return QDF_STATUS_SUCCESS; -} -#endif static enum csr_cfgdot11mode csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac, struct csr_roam_profile *pProfile, - uint8_t operationChn, - enum band_info *pBand); + uint32_t bss_op_ch_freq, + enum reg_wifi_band *pBand); static QDF_STATUS csr_roam_get_qos_info_from_bss( struct mac_context *mac, struct bss_description *bss_desc); -static uint32_t csr_find_ibss_session(struct mac_context *mac); static uint32_t csr_find_session_by_type(struct mac_context *, enum QDF_OPMODE); static bool csr_is_conn_allow_2g_band(struct mac_context *mac, @@ -495,10 +455,6 @@ static QDF_STATUS csr_roam_start_wds(struct mac_context *mac, struct csr_roam_profile *pProfile, struct bss_description *bss_desc); static void csr_init_session(struct mac_context *mac, uint32_t sessionId); -static QDF_STATUS csr_roam_issue_set_key_command(struct mac_context *mac, - uint32_t sessionId, - tCsrRoamSetKey *pSetKey, - uint32_t roamId); static QDF_STATUS csr_roam_get_qos_info_from_bss(struct mac_context *mac, @@ -559,936 +515,1403 @@ static inline void csr_roam_free_globals(void) } #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */ -static void csr_roam_de_init_globals(struct mac_context *mac) -{ - uint8_t i; - - for (i = 0; i < WLAN_MAX_VDEVS; i++) { - if (mac->roam.roamSession[i].pCurRoamProfile) - csr_release_profile(mac, - mac->roam.roamSession[i]. - pCurRoamProfile); - csr_release_profile(mac, - &mac->roam.roamSession[i]. - stored_roam_profile.profile); - } - csr_roam_free_globals(); - mac->roam.roamSession = NULL; -} - -#ifdef QCA_SUPPORT_CP_STATS -static QDF_STATUS csr_open_stats_ll(struct mac_context *mac_ctx) +/* Returns whether handoff is currently in progress or not */ +static +bool csr_roam_is_handoff_in_progress(struct mac_context *mac, uint8_t sessionId) { - return QDF_STATUS_SUCCESS; + return csr_neighbor_roam_is_handoff_in_progress(mac, sessionId); } -static void csr_close_stats_ll(struct mac_context *mac_ctx) {} -#else -static QDF_STATUS csr_open_stats_ll(struct mac_context *mac_ctx) +static QDF_STATUS +csr_roam_issue_disassociate(struct mac_context *mac, uint32_t sessionId, + enum csr_roam_substate NewSubstate, + bool fMICFailure) { - QDF_STATUS status; - - status = csr_ll_open(&mac_ctx->roam.statsClientReqList); - if (QDF_IS_STATUS_ERROR(status)) - return status; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct qdf_mac_addr bssId = QDF_MAC_ADDR_BCAST_INIT; + uint16_t reasonCode; + struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - return csr_ll_open(&mac_ctx->roam.peStatsReqList); -} + if (!pSession) { + sme_err("session %d not found", sessionId); + return QDF_STATUS_E_FAILURE; + } -static void csr_close_stats_ll(struct mac_context *mac_ctx) -{ - csr_ll_close(&mac_ctx->roam.statsClientReqList); - csr_ll_close(&mac_ctx->roam.peStatsReqList); -} -#endif + if (fMICFailure) { + reasonCode = eSIR_MAC_MIC_FAILURE_REASON; + } else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) { + reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON; + } else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) { + reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON; + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED; + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON and set back NewSubstate"); + } else { + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + } + if ((csr_roam_is_handoff_in_progress(mac, sessionId)) && + (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) { + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &mac->roam.neighborRoamInfo[sessionId]; + qdf_copy_macaddr(&bssId, + pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs. + bssid); + } else if (pSession->pConnectBssDesc) { + qdf_mem_copy(&bssId.bytes, pSession->pConnectBssDesc->bssId, + sizeof(struct qdf_mac_addr)); + } -QDF_STATUS csr_open(struct mac_context *mac) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t i; + sme_debug("Disassociate Bssid " QDF_MAC_ADDR_FMT " subState: %s reason: %d", + QDF_MAC_ADDR_REF(bssId.bytes), + mac_trace_getcsr_roam_sub_state(NewSubstate), + reasonCode); - do { - /* Initialize CSR Roam Globals */ - status = csr_roam_init_globals(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) - break; + csr_roam_substate_change(mac, NewSubstate, sessionId); - for (i = 0; i < WLAN_MAX_VDEVS; i++) - csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, i); + status = csr_send_mb_disassoc_req_msg(mac, sessionId, bssId.bytes, + reasonCode); - init_config_param(mac); - status = csr_scan_open(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_free_globals(); - break; - } - status = csr_roam_open(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_free_globals(); - break; - } - mac->roam.nextRoamId = 1; /* Must not be 0 */ - status = csr_open_stats_ll(mac); - if (QDF_IS_STATUS_ERROR(status)) { - csr_roam_free_globals(); - break; + if (QDF_IS_STATUS_SUCCESS(status)) { + csr_roam_link_down(mac, sessionId); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + /* no need to tell QoS that we are disassociating, it will be + * taken care off in assoc req for HO + */ + if (eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) { + /* notify QoS module that disassoc happening */ + sme_qos_csr_event_ind(mac, (uint8_t)sessionId, + SME_QOS_CSR_DISCONNECT_REQ, NULL); } - } while (0); +#endif + } else { + sme_warn("csr_send_mb_disassoc_req_msg failed status: %d", + status); + } return status; } -QDF_STATUS csr_init_chan_list(struct mac_context *mac, uint8_t *alpha2) +/* This function assumes that we only support one IBSS session. + * We cannot use BSSID to identify session because for IBSS, + * the bssid changes. + */ +#ifdef QCA_IBSS_SUPPORT +static uint32_t csr_find_ibss_session(struct mac_context *mac) { - QDF_STATUS status; - - mac->scan.countryCodeDefault[0] = alpha2[0]; - mac->scan.countryCodeDefault[1] = alpha2[1]; - mac->scan.countryCodeDefault[2] = alpha2[2]; - - sme_debug("init time country code %.2s", mac->scan.countryCodeDefault); - - mac->scan.domainIdDefault = 0; - mac->scan.domainIdCurrent = 0; - - qdf_mem_copy(mac->scan.countryCodeCurrent, - mac->scan.countryCodeDefault, CFG_COUNTRY_CODE_LEN); - qdf_mem_copy(mac->scan.countryCodeElected, - mac->scan.countryCodeDefault, CFG_COUNTRY_CODE_LEN); - status = csr_get_channel_and_power_list(mac); + uint32_t i, nRet = WLAN_UMAC_VDEV_ID_MAX; + struct csr_roam_session *pSession; - return status; + for (i = 0; i < WLAN_MAX_VDEVS; i++) { + if (CSR_IS_SESSION_VALID(mac, i)) { + pSession = CSR_GET_SESSION(mac, i); + if (pSession->pCurRoamProfile && + (csr_is_bss_type_ibss + (pSession->connectedProfile.BSSType))) { + /* Found it */ + nRet = i; + break; + } + } + } + return nRet; } -QDF_STATUS csr_set_channels(struct mac_context *mac, - struct csr_config_params *pParam) +static QDF_STATUS +csr_roam_start_ibss(struct mac_context *mac, uint32_t sessionId, + struct csr_roam_profile *pProfile, + bool *pfSameIbss) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t index = 0; + bool fSameIbss = false; - qdf_mem_copy(pParam->Csr11dinfo.countryCode, - mac->scan.countryCodeCurrent, CFG_COUNTRY_CODE_LEN); - for (index = 0; index < mac->scan.base_channels.numChannels; - index++) { - pParam->Csr11dinfo.Channels.channelList[index] = - mac->scan.base_channels.channelList[index]; - pParam->Csr11dinfo.ChnPower[index].firstChannel = - mac->scan.base_channels.channelList[index]; - pParam->Csr11dinfo.ChnPower[index].numChannels = 1; - pParam->Csr11dinfo.ChnPower[index].maxtxPower = - mac->scan.defaultPowerTable[index].tx_power; - } - pParam->Csr11dinfo.Channels.numChannels = - mac->scan.base_channels.numChannels; + if (csr_is_conn_state_ibss(mac, sessionId)) { + /* Check if any profile parameter has changed ? If any profile + * parameter has changed then stop old BSS and start a new one + * with new parameters + */ + if (csr_is_same_profile(mac, + &mac->roam.roamSession[sessionId]. + connectedProfile, pProfile)) + fSameIbss = true; + else + status = csr_roam_issue_stop_bss(mac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING); - return status; -} + } else if (csr_is_conn_state_connected_infra(mac, sessionId)) + /* Disassociate from the connected Infrastructure network... */ + status = csr_roam_issue_disassociate(mac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, + false); + else { + struct bss_config_param *pBssConfig; -QDF_STATUS csr_close(struct mac_context *mac) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; + pBssConfig = qdf_mem_malloc(sizeof(struct bss_config_param)); + if (!pBssConfig) + status = QDF_STATUS_E_NOMEM; + else + status = QDF_STATUS_SUCCESS; + if (QDF_IS_STATUS_SUCCESS(status)) { + /* there is no Bss description before we start an IBSS + * so we need to adopt all Bss configuration parameters + * from the Profile. + */ + status = csr_roam_prepare_bss_config_from_profile(mac, + pProfile, + pBssConfig, + NULL); + if (QDF_IS_STATUS_SUCCESS(status)) { + /* save dotMode */ + mac->roam.roamSession[sessionId].bssParams. + uCfgDot11Mode = pBssConfig->uCfgDot11Mode; + /* Prepare some more parameters for this IBSS */ + csr_roam_prepare_bss_params(mac, sessionId, + pProfile, NULL, + pBssConfig, NULL); + status = csr_roam_set_bss_config_cfg(mac, + sessionId, + pProfile, NULL, + pBssConfig, + NULL, false); + } - csr_roam_close(mac); - csr_scan_close(mac); - csr_close_stats_ll(mac); - /* DeInit Globals */ - csr_roam_de_init_globals(mac); + qdf_mem_free(pBssConfig); + } /* Allocate memory */ + } + + if (pfSameIbss) + *pfSameIbss = fSameIbss; return status; } -static int8_t csr_find_channel_pwr(struct channel_power * - pdefaultPowerTable, - uint8_t ChannelNum) +static void +csr_roam_chk_lnk_ibss_new_peer_ind(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) { - uint8_t i; - /* TODO: if defaultPowerTable is guaranteed to be in ascending */ - /* order of channel numbers, we can employ binary search */ - for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) { - if (pdefaultPowerTable[i].chan_num == ChannelNum) - return pdefaultPowerTable[i].tx_power; - } - /* could not find the channel list in default list */ - /* this should not have occurred */ - QDF_ASSERT(0); - return 0; -} + struct csr_roam_session *session; + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; + struct csr_roam_info *roam_info = NULL; + tSmeIbssPeerInd *pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + host_log_ibss_pkt_type *pIbssLog; -/** - * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy - * order for 5 Ghz preference and DFS channels. - * @mac_ctx: pointer to mac context. - * @chan_list: channel list updated with greedy channel order. - * @num_channel: Number of channels in list - * - * To allow Early Stop Roaming Scan feature to co-exist with 5G preference, - * this function moves 5G channels ahead of 2G channels. This function can - * also move 2G channels, ahead of DFS channel or vice versa. Order is - * maintained among same category channels - * - * Return: None - */ -static void csr_roam_arrange_ch_list(struct mac_context *mac_ctx, - tSirUpdateChanParam *chan_list, uint8_t num_channel) -{ - bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx); - bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx); - int i, j = 0; - tSirUpdateChanParam *tmp_list = NULL; + WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, + LOG_WLAN_IBSS_C); + if (pIbssLog) { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN; + qdf_copy_macaddr(&pIbssLog->peer_macaddr, + &pIbssPeerInd->peer_addr); + WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); + } +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - if (!prefer_5g) + sessionId = csr_find_ibss_session(mac_ctx); + if (WLAN_UMAC_VDEV_ID_MAX == sessionId) return; - - tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel); - if (!tmp_list) + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", sessionId); return; - - /* Fist copy Non-DFS 5g channels */ - for (i = 0; i < num_channel; i++) { - if (WLAN_REG_IS_5GHZ_CH(chan_list[i].chanId) && - !wlan_reg_is_dfs_ch(mac_ctx->pdev, - chan_list[i].chanId)) { - qdf_mem_copy(&tmp_list[j++], - &chan_list[i], sizeof(tSirUpdateChanParam)); - chan_list[i].chanId = INVALID_CHANNEL_ID; - } } - if (prefer_dfs) { - /* next copy DFS channels (remaining channels in 5G) */ - for (i = 0; i < num_channel; i++) { - if (WLAN_REG_IS_5GHZ_CH(chan_list[i].chanId)) { - qdf_mem_copy(&tmp_list[j++], &chan_list[i], - sizeof(tSirUpdateChanParam)); - chan_list[i].chanId = INVALID_CHANNEL_ID; - } + /* + * Issue the set Context request to LIM to establish the Unicast STA + * context for the new peer... + */ + if (!session->pConnectBssDesc) { + sme_warn("CSR: connected BSS is empty"); + goto callback_and_free; + } + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + goto callback_and_free; + qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr); + qdf_mem_copy(&roam_info->bssid, session->pConnectBssDesc->bssId, + sizeof(struct qdf_mac_addr)); + if (pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) { + roam_info->pbFrames = qdf_mem_malloc((pIbssPeerInd->mesgLen - + sizeof(tSmeIbssPeerInd))); + if (!roam_info->pbFrames) { + status = QDF_STATUS_E_NOMEM; + } else { + status = QDF_STATUS_SUCCESS; + roam_info->nBeaconLength = pIbssPeerInd->mesgLen - + sizeof(tSmeIbssPeerInd); + qdf_mem_copy(roam_info->pbFrames, + ((uint8_t *)pIbssPeerInd) + + sizeof(tSmeIbssPeerInd), + roam_info->nBeaconLength); } - } else { - /* next copy 2G channels */ - for (i = 0; i < num_channel; i++) { - if (WLAN_REG_IS_24GHZ_CH(chan_list[i].chanId)) { - qdf_mem_copy(&tmp_list[j++], &chan_list[i], - sizeof(tSirUpdateChanParam)); - chan_list[i].chanId = INVALID_CHANNEL_ID; - } + roam_info->bss_desc = qdf_mem_malloc( + session->pConnectBssDesc->length); + if (!roam_info->bss_desc) { + status = QDF_STATUS_E_NOMEM; + } else { + status = QDF_STATUS_SUCCESS; + qdf_mem_copy(roam_info->bss_desc, + session->pConnectBssDesc, + session->pConnectBssDesc->length); } } - /* copy rest of the channels in same order to tmp list */ - for (i = 0; i < num_channel; i++) { - if (chan_list[i].chanId != INVALID_CHANNEL_ID) { - qdf_mem_copy(&tmp_list[j++], &chan_list[i], - sizeof(tSirUpdateChanParam)); - chan_list[i].chanId = INVALID_CHANNEL_ID; - } + if (eCSR_ENCRYPT_TYPE_NONE == + session->connectedProfile.EncryptionType) { + /* NO keys. these key parameters don't matter */ + csr_issue_set_context_req_helper(mac_ctx, + session->pCurRoamProfile, + sessionId, + &pIbssPeerInd->peer_addr.bytes, + false, true, eSIR_TX_RX, + 0, 0, NULL); + } + +callback_and_free: + /* send up the sec type for the new peer */ + if (roam_info) + roam_info->u.pConnectedProfile = &session->connectedProfile; + csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_RESULT_IBSS_NEW_PEER); + if (roam_info) { + qdf_mem_free(roam_info->pbFrames); + qdf_mem_free(roam_info->bss_desc); + qdf_mem_free(roam_info); } - /* copy tmp list to original channel list buffer */ - qdf_mem_copy(chan_list, tmp_list, - sizeof(tSirUpdateChanParam) * num_channel); - qdf_mem_free(tmp_list); } -/** - * csr_roam_sort_channel_for_early_stop() - Sort the channels - * @mac_ctx: mac global context - * @chan_list: Original channel list from the upper layers - * @num_channel: Number of original channels - * - * For Early stop scan feature, the channel list should be in an order, - * where-in there is a maximum chance to detect an AP in the initial - * channels in the list so that the scanning can be stopped early as the - * feature demands. - * Below fixed greedy channel list has been provided - * based on most of the enterprise wifi installations across the globe. - * - * Identify all the greedy channels within the channel list from user space. - * Identify all the non-greedy channels in the user space channel list. - * Merge greedy channels followed by non-greedy channels back into the - * chan_list. - * - * Return: None - */ -static void csr_roam_sort_channel_for_early_stop(struct mac_context *mac_ctx, - tSirUpdateChanList *chan_list, uint8_t num_channel) +static void +csr_roam_chk_lnk_ibss_peer_departed_ind(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) { - tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy; - uint8_t i, j; - static const uint8_t fixed_greedy_chan_list[] = {1, 6, 11, 36, 48, 40, - 44, 10, 2, 9, 149, 157, 161, 3, 4, 8, 153, 165, 7, 5, 136, 140, - 52, 116, 56, 104, 64, 60, 100, 120, 13, 14, 112, 132, 151, 155}; - uint8_t num_fixed_greedy_chan; - uint8_t num_greedy_chan = 0; - uint8_t num_non_greedy_chan = 0; - uint8_t match_found = false; - uint32_t buf_size; + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + struct csr_roam_info *roam_info; + tSmeIbssPeerInd *pIbssPeerInd; - buf_size = sizeof(tSirUpdateChanList) + - (sizeof(tSirUpdateChanParam) * num_channel); - chan_list_greedy = qdf_mem_malloc(buf_size); - chan_list_non_greedy = qdf_mem_malloc(buf_size); - if (!chan_list_greedy || !chan_list_non_greedy) - goto scan_list_sort_error; - /* - * fixed_greedy_chan_list is an evaluated channel list based on most of - * the enterprise wifi deployments and the order of the channels - * determines the highest possibility of finding an AP. - * chan_list is the channel list provided by upper layers based on the - * regulatory domain. - */ - num_fixed_greedy_chan = sizeof(fixed_greedy_chan_list)/sizeof(uint8_t); - /* - * Browse through the chan_list and put all the non-greedy channels - * into a separate list by name chan_list_non_greedy - */ - for (i = 0; i < num_channel; i++) { - for (j = 0; j < num_fixed_greedy_chan; j++) { - if (chan_list->chanParam[i].chanId == - fixed_greedy_chan_list[j]) { - match_found = true; - break; - } - } - if (!match_found) { - qdf_mem_copy( - &chan_list_non_greedy->chanParam[num_non_greedy_chan], - &chan_list->chanParam[i], - sizeof(tSirUpdateChanParam)); - num_non_greedy_chan++; - } else { - match_found = false; - } + if (!msg_ptr) { + sme_err("IBSS peer ind. message is NULL"); + return; } - /* - * Browse through the fixed_greedy_chan_list and put all the greedy - * channels in the chan_list into a separate list by name - * chan_list_greedy - */ - for (i = 0; i < num_fixed_greedy_chan; i++) { - for (j = 0; j < num_channel; j++) { - if (fixed_greedy_chan_list[i] == - chan_list->chanParam[j].chanId) { - qdf_mem_copy( - &chan_list_greedy->chanParam[num_greedy_chan], - &chan_list->chanParam[j], - sizeof(tSirUpdateChanParam)); - num_greedy_chan++; - break; + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + pIbssPeerInd = (tSmeIbssPeerInd *)msg_ptr; + sessionId = csr_find_ibss_session(mac_ctx); + if (WLAN_UMAC_VDEV_ID_MAX != sessionId) { +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + host_log_ibss_pkt_type *pIbssLog; + + WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, + LOG_WLAN_IBSS_C); + if (pIbssLog) { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE; + if (pIbssPeerInd) { + qdf_copy_macaddr(&pIbssLog->peer_macaddr, + &pIbssPeerInd->peer_addr); } + WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); } +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + sme_debug("CSR: Peer departed notification from LIM"); + qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr); + csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); } - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - "greedy=%d, non-greedy=%d, tot=%d", - num_greedy_chan, num_non_greedy_chan, num_channel); - if ((num_greedy_chan + num_non_greedy_chan) != num_channel) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, - "incorrect sorting of channels"); - goto scan_list_sort_error; - } - /* Copy the Greedy channels first */ - i = 0; - qdf_mem_copy(&chan_list->chanParam[i], - &chan_list_greedy->chanParam[i], - num_greedy_chan * sizeof(tSirUpdateChanParam)); - /* Copy the remaining Non Greedy channels */ - i = num_greedy_chan; - j = 0; - qdf_mem_copy(&chan_list->chanParam[i], - &chan_list_non_greedy->chanParam[j], - num_non_greedy_chan * sizeof(tSirUpdateChanParam)); - - /* Update channel list for 5g preference and allow DFS roam */ - csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel); -scan_list_sort_error: - qdf_mem_free(chan_list_greedy); - qdf_mem_free(chan_list_non_greedy); + qdf_mem_free(roam_info); } -/** - * csr_emu_chan_req() - update the required channel list for emulation - * @channel: channel number to check - * - * To reduce scan time during emulation platforms, this function - * restricts the scanning to be done on selected channels - * - * Return: QDF_STATUS enumeration - */ -#ifdef QCA_WIFI_NAPIER_EMULATION -#define SCAN_CHAN_LIST_5G_LEN 6 -#define SCAN_CHAN_LIST_2G_LEN 3 -static const uint8_t -csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 36, 44, 52, 56, 140, 149 }; -static const uint8_t -csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 1, 6, 11 }; -static QDF_STATUS csr_emu_chan_req(uint32_t channel) +static uint32_t +csr_roam_get_ibss_start_chan_freq50(struct mac_context *mac) { - int i; + uint32_t ch_freq = 0; + uint32_t idx; + uint32_t id_Valid_ch; + bool fFound = false; + uint32_t len = sizeof(mac->roam.valid_ch_freq_list); - if (WLAN_REG_IS_24GHZ_CH(channel)) { - for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) { - if (csr_scan_chan_list_2g[i] == channel) - return QDF_STATUS_SUCCESS; + if (mac->roam.configParam.ad_hoc_ch_freq_5g) { + ch_freq = mac->roam.configParam.ad_hoc_ch_freq_5g; + if (!csr_roam_is_channel_valid(mac, ch_freq)) + ch_freq = 0; + } + if (0 == ch_freq + && + QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(mac, + mac->roam.valid_ch_freq_list, &len))) { + for (idx = 0; (idx < CSR_NUM_IBSS_START_CHAN_50) && !fFound; + idx++) { + for (id_Valid_ch = 0; + (id_Valid_ch < len) && !fFound; + id_Valid_ch++) { + if (csr_start_ibss_channels50[idx] == + mac->roam.valid_ch_freq_list[id_Valid_ch]) { + fFound = true; + ch_freq = + csr_start_ibss_channels50[idx]; + } + } } - } else if (WLAN_REG_IS_5GHZ_CH(channel)) { - for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) { - if (csr_scan_chan_list_5g[i] == channel) - return QDF_STATUS_SUCCESS; + /* + * this is rare, but if it does happen, + * we find anyone in 11a bandwidth and + * return the first 11a channel found! + */ + if (!fFound) { + for (id_Valid_ch = 0; id_Valid_ch < len; + id_Valid_ch++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ( + mac->roam.valid_ch_freq_list[id_Valid_ch])) { + /* the max channel# in 11g is 14 */ + if (id_Valid_ch < + CSR_NUM_IBSS_START_CHAN_50) { + ch_freq = + mac->roam.valid_ch_freq_list + [id_Valid_ch]; + } + break; + } + } } - } - return QDF_STATUS_E_FAILURE; -} -#else -static QDF_STATUS csr_emu_chan_req(uint32_t channel_num) -{ - return QDF_STATUS_SUCCESS; + } /* if */ + + return ch_freq; } -#endif -#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY -static void csr_add_len_of_social_channels(struct mac_context *mac, - uint8_t *num_chan) +static uint32_t +csr_roam_get_ibss_start_chan_freq24(struct mac_context *mac) { - uint8_t i; - uint8_t no_chan = *num_chan; + uint32_t ch_freq = 2412; + uint32_t idx; + uint32_t id_Valid_ch; + bool fFound = false; + uint32_t len = sizeof(mac->roam.valid_ch_freq_list); - sme_debug("add len of social channels, before adding - num_chan:%hu", - *num_chan); - if (CSR_IS_5G_BAND_ONLY(mac)) { - for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { - if (wlan_reg_get_channel_state( - mac->pdev, social_channel[i]) == - CHANNEL_STATE_ENABLE) - no_chan++; - } + if (mac->roam.configParam.ad_hoc_ch_freq_2g) { + ch_freq = mac->roam.configParam.ad_hoc_ch_freq_2g; + if (!csr_roam_is_channel_valid(mac, ch_freq)) + ch_freq = 0; } - *num_chan = no_chan; - sme_debug("after adding - num_chan:%hu", *num_chan); -} - -static void csr_add_social_channels(struct mac_context *mac, - tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, - uint8_t *num_chan) -{ - uint8_t i; - uint8_t no_chan = *num_chan; - sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list, - *num_chan); - if (CSR_IS_5G_BAND_ONLY(mac)) { - for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { - if (wlan_reg_get_channel_state(mac->pdev, - social_channel[i]) != CHANNEL_STATE_ENABLE) - continue; - chan_list->chanParam[no_chan].chanId = - social_channel[i]; - chan_list->chanParam[no_chan].pwr = - csr_find_channel_pwr(pScan->defaultPowerTable, - social_channel[i]); - chan_list->chanParam[no_chan].dfsSet = false; - if (cds_is_5_mhz_enabled()) - chan_list->chanParam[no_chan].quarter_rate - = 1; - else if (cds_is_10_mhz_enabled()) - chan_list->chanParam[no_chan].half_rate = 1; - no_chan++; + if (0 == ch_freq + && + QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(mac, + mac->roam.valid_ch_freq_list, + &len))) { + for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_24) && !fFound; + idx++) { + for (id_Valid_ch = 0; + (id_Valid_ch < len) && !fFound; + id_Valid_ch++) { + if (csr_start_ibss_channels24[idx] == + mac->roam.valid_ch_freq_list[id_Valid_ch]) { + fFound = true; + ch_freq = + csr_start_ibss_channels24[idx]; + } + } } - sme_debug("after adding -num_chan %hu", no_chan); } - *num_chan = no_chan; + + return ch_freq; } #else -static void csr_add_len_of_social_channels(struct mac_context *mac, - uint8_t *num_chan) +static inline uint32_t +csr_roam_get_ibss_start_chan_freq50(struct mac_context *mac) { - sme_debug("skip adding len of social channels"); + return 0; } -static void csr_add_social_channels(struct mac_context *mac, - tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, - uint8_t *num_chan) + +static inline uint32_t +csr_roam_get_ibss_start_chan_freq24(struct mac_context *mac) { - sme_debug("skip social channels"); + return 0; } -#endif -/** - * csr_scan_event_handler() - callback for scan event - * @vdev: wlan objmgr vdev pointer - * @event: scan event - * @arg: global mac context pointer - * - * Return: void - */ -static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev, - struct scan_event *event, - void *arg) +static inline void +csr_roam_chk_lnk_ibss_new_peer_ind(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) { - bool success = false; - QDF_STATUS lock_status; - struct mac_context *mac = arg; - - if (!mac) - return; +} - if (!util_is_scan_completed(event, &success)) - return; +static void +csr_roam_chk_lnk_ibss_peer_departed_ind(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) +{ +} - lock_status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_ERROR(lock_status)) - return; +static QDF_STATUS +csr_roam_start_ibss(struct mac_context *mac, uint32_t sessionId, + struct csr_roam_profile *pProfile, + bool *pfSameIbss) +{ + return QDF_STATUS_SUCCESS; +} - if (mac->scan.pending_channel_list_req) - csr_update_channel_list(mac); - sme_release_global_lock(&mac->sme); +static inline uint32_t +csr_find_ibss_session(struct mac_context *mac) +{ + return WLAN_MAX_VDEVS; } +#endif -QDF_STATUS csr_update_channel_list(struct mac_context *mac) +static void csr_roam_de_init_globals(struct mac_context *mac) { - tSirUpdateChanList *pChanList; - struct csr_scanstruct *pScan = &mac->scan; - uint8_t numChan = pScan->base_channels.numChannels; - uint8_t num_channel = 0; - uint32_t bufLen; - struct scheduler_msg msg = {0}; uint8_t i; - uint8_t channel_state; - uint16_t unsafe_chan[NUM_CHANNELS]; - uint16_t unsafe_chan_cnt = 0; - uint16_t cnt = 0; - uint8_t channel; - bool is_unsafe_chan; - bool is_5mhz_enabled; - bool is_10mhz_enabled; - enum scm_scan_status scan_status; - QDF_STATUS lock_status; - - qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); - if (!qdf_ctx) { - sme_err("qdf_ctx is NULL"); - return QDF_STATUS_E_FAILURE; + for (i = 0; i < WLAN_MAX_VDEVS; i++) { + if (mac->roam.roamSession[i].pCurRoamProfile) + csr_release_profile(mac, + mac->roam.roamSession[i]. + pCurRoamProfile); + csr_release_profile(mac, + &mac->roam.roamSession[i]. + stored_roam_profile.profile); } + csr_roam_free_globals(); + mac->roam.roamSession = NULL; +} - lock_status = sme_acquire_global_lock(&mac->sme); - if (QDF_IS_STATUS_ERROR(lock_status)) - return lock_status; +QDF_STATUS csr_open(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t i; - if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { - scan_status = ucfg_scan_get_pdev_status(mac->pdev); - if (scan_status == SCAN_IS_ACTIVE || - scan_status == SCAN_IS_ACTIVE_AND_PENDING) { - mac->scan.pending_channel_list_req = true; - sme_release_global_lock(&mac->sme); - sme_debug("scan in progress postpone channel list req "); - return QDF_STATUS_SUCCESS; - } - mac->scan.pending_channel_list_req = false; - } - sme_release_global_lock(&mac->sme); + do { + /* Initialize CSR Roam Globals */ + status = csr_roam_init_globals(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) + break; - pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, - &unsafe_chan_cnt, - sizeof(unsafe_chan)); + for (i = 0; i < WLAN_MAX_VDEVS; i++) + csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, i); - csr_add_len_of_social_channels(mac, &numChan); + init_config_param(mac); + status = csr_scan_open(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) { + csr_roam_free_globals(); + break; + } + status = csr_roam_open(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) { + csr_roam_free_globals(); + break; + } + mac->roam.nextRoamId = 1; /* Must not be 0 */ + } while (0); - bufLen = sizeof(tSirUpdateChanList) + - (sizeof(tSirUpdateChanParam) * (numChan)); + return status; +} - csr_init_operating_classes(mac); - pChanList = qdf_mem_malloc(bufLen); - if (!pChanList) - return QDF_STATUS_E_NOMEM; +QDF_STATUS csr_init_chan_list(struct mac_context *mac, uint8_t *alpha2) +{ + QDF_STATUS status; - is_5mhz_enabled = cds_is_5_mhz_enabled(); - if (is_5mhz_enabled) - sme_nofl_debug("quarter_rate enabled"); - is_10mhz_enabled = cds_is_10_mhz_enabled(); - if (is_10mhz_enabled) - sme_nofl_debug("half_rate enabled"); + mac->scan.countryCodeDefault[0] = alpha2[0]; + mac->scan.countryCodeDefault[1] = alpha2[1]; + mac->scan.countryCodeDefault[2] = alpha2[2]; - for (i = 0; i < pScan->base_channels.numChannels; i++) { - struct csr_sta_roam_policy_params *roam_policy = - &mac->roam.configParam.sta_roam_policy; - if (QDF_STATUS_SUCCESS != - csr_emu_chan_req(pScan->base_channels.channelList[i])) - continue; + sme_debug("init time country code %.2s", mac->scan.countryCodeDefault); - /* Scan is not performed on DSRC channels*/ - if (wlan_reg_is_dsrc_chan(mac->pdev, - pScan->base_channels.channelList[i])) - continue; + mac->scan.domainIdDefault = 0; + mac->scan.domainIdCurrent = 0; - channel = pScan->base_channels.channelList[i]; + qdf_mem_copy(mac->scan.countryCodeCurrent, + mac->scan.countryCodeDefault, CFG_COUNTRY_CODE_LEN); + qdf_mem_copy(mac->scan.countryCodeElected, + mac->scan.countryCodeDefault, CFG_COUNTRY_CODE_LEN); + status = csr_get_channel_and_power_list(mac); - channel_state = wlan_reg_get_channel_state(mac->pdev, - pScan->base_channels.channelList[i]); - if ((CHANNEL_STATE_ENABLE == channel_state) || - mac->scan.fEnableDFSChnlScan) { - if ((mac->roam.configParam.sta_roam_policy.dfs_mode == - CSR_STA_ROAM_POLICY_DFS_DISABLED) && - (channel_state == CHANNEL_STATE_DFS)) { - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_DEBUG, - FL("skip dfs channel %d"), - channel); - continue; - } - if (mac->roam.configParam.sta_roam_policy. - skip_unsafe_channels && - unsafe_chan_cnt) { - is_unsafe_chan = false; - for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) { - if (unsafe_chan[cnt] == channel) { - is_unsafe_chan = true; - break; - } - } - if ((is_unsafe_chan) && - ((WLAN_REG_IS_24GHZ_CH(channel) && - roam_policy->sap_operating_band == - BAND_2G) || - (WLAN_REG_IS_5GHZ_CH(channel) && - roam_policy->sap_operating_band == - BAND_5G))) { - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_DEBUG, - FL("ignoring unsafe channel %d"), - channel); - continue; - } - } - pChanList->chanParam[num_channel].chanId = - pScan->base_channels.channelList[i]; - pChanList->chanParam[num_channel].pwr = - csr_find_channel_pwr(pScan->defaultPowerTable, - pChanList->chanParam[num_channel].chanId); - - if (pScan->fcc_constraint) { - if (12 == pChanList->chanParam[num_channel]. - chanId) { - pChanList->chanParam[num_channel].pwr = - MAX_PWR_FCC_CHAN_12; - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_DEBUG, - "txpow for channel 12 is %d", - MAX_PWR_FCC_CHAN_12); - } - if (13 == pChanList->chanParam[num_channel]. - chanId) { - pChanList->chanParam[num_channel].pwr = - MAX_PWR_FCC_CHAN_13; - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_DEBUG, - "txpow for channel 13 is %d", - MAX_PWR_FCC_CHAN_13); - } - } - - - if (CHANNEL_STATE_ENABLE == channel_state) - pChanList->chanParam[num_channel].dfsSet = - false; - else - pChanList->chanParam[num_channel].dfsSet = - true; - pChanList->chanParam[num_channel].quarter_rate = - is_5mhz_enabled; + return status; +} - pChanList->chanParam[num_channel].half_rate = - is_10mhz_enabled; +QDF_STATUS csr_set_channels(struct mac_context *mac, + struct csr_config_params *pParam) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t index = 0; - num_channel++; - } + qdf_mem_copy(pParam->Csr11dinfo.countryCode, + mac->scan.countryCodeCurrent, CFG_COUNTRY_CODE_LEN); + for (index = 0; index < mac->scan.base_channels.numChannels; + index++) { + pParam->Csr11dinfo.Channels.channel_freq_list[index] = + mac->scan.base_channels.channel_freq_list[index]; + pParam->Csr11dinfo.ChnPower[index].first_chan_freq = + mac->scan.base_channels.channel_freq_list[index]; + pParam->Csr11dinfo.ChnPower[index].numChannels = 1; + pParam->Csr11dinfo.ChnPower[index].maxtxPower = + mac->scan.defaultPowerTable[index].tx_power; } + pParam->Csr11dinfo.Channels.numChannels = + mac->scan.base_channels.numChannels; - csr_add_social_channels(mac, pChanList, pScan, &num_channel); - - if (mac->mlme_cfg->lfr.early_stop_scan_enable) - csr_roam_sort_channel_for_early_stop(mac, pChanList, - num_channel); - else - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("Early Stop Scan Feature not supported")); - - if ((mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_AUTO) || - (mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_11AC) || - (mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_11AC_ONLY)) { - pChanList->vht_en = true; - if (mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) - pChanList->vht_24_en = true; - } - if ((mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_AUTO) || - (mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_11N) || - (mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_11N_ONLY)) { - pChanList->ht_en = true; - } - if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) || - (mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) || - (mac->roam.configParam.uCfgDot11Mode == - eCSR_CFG_DOT11_MODE_11AX_ONLY)) - pChanList->he_en = true; + return status; +} - msg.type = WMA_UPDATE_CHAN_LIST_REQ; - msg.reserved = 0; - msg.bodyptr = pChanList; - pChanList->numChan = num_channel; - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, - NO_SESSION, msg.type)); - if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, - &msg)) { - qdf_mem_free(pChanList); - return QDF_STATUS_E_FAILURE; - } +QDF_STATUS csr_close(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; - return QDF_STATUS_SUCCESS; + csr_roam_close(mac); + csr_scan_close(mac); + /* DeInit Globals */ + csr_roam_de_init_globals(mac); + return status; } -#ifdef QCA_SUPPORT_CP_STATS -static void csr_init_tl_stats(struct mac_context *mac_ctx) {} -#else -static void csr_init_tl_stats(struct mac_context *mac_ctx) +static int8_t +csr_find_channel_pwr(struct channel_power *pdefaultPowerTable, + uint32_t chan_freq) { - mac_ctx->roam.tlStatsReqInfo.numClient = 0; + uint8_t i; + /* TODO: if defaultPowerTable is guaranteed to be in ascending */ + /* order of channel numbers, we can employ binary search */ + for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) { + if (pdefaultPowerTable[i].center_freq == chan_freq) + return pdefaultPowerTable[i].tx_power; + } + /* could not find the channel list in default list */ + /* this should not have occurred */ + QDF_ASSERT(0); + return 0; } -#endif /* QCA_SUPPORT_CP_STATS */ -QDF_STATUS csr_start(struct mac_context *mac) +/** + * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy + * order for 5 Ghz preference and DFS channels. + * @mac_ctx: pointer to mac context. + * @chan_list: channel list updated with greedy channel order. + * @num_channel: Number of channels in list + * + * To allow Early Stop Roaming Scan feature to co-exist with 5G preference, + * this function moves 5G channels ahead of 2G channels. This function can + * also move 2G channels, ahead of DFS channel or vice versa. Order is + * maintained among same category channels + * + * Return: None + */ +static void csr_roam_arrange_ch_list(struct mac_context *mac_ctx, + tSirUpdateChanParam *chan_list, uint8_t num_channel) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t i; + bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx); + bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx); + int i, j = 0; + tSirUpdateChanParam *tmp_list = NULL; - do { - for (i = 0; i < WLAN_MAX_VDEVS; i++) - csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, i); + if (!prefer_5g) + return; - status = csr_roam_start(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) - break; + tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel); + if (!tmp_list) + return; - mac->roam.sPendingCommands = 0; - for (i = 0; i < WLAN_MAX_VDEVS; i++) - status = csr_neighbor_roam_init(mac, i); - csr_init_tl_stats(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_warn("Couldn't Init HO control blk"); - break; + /* Fist copy Non-DFS 5g channels */ + for (i = 0; i < num_channel; i++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq) && + !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, + chan_list[i].freq)) { + qdf_mem_copy(&tmp_list[j++], + &chan_list[i], sizeof(tSirUpdateChanParam)); + chan_list[i].freq = 0; } - /* Register with scan component */ - mac->scan.requester_id = ucfg_scan_register_requester( - mac->psoc, - "CSR", csr_scan_callback, mac); - - if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { - status = ucfg_scan_register_event_handler(mac->pdev, - csr_scan_event_handler, mac); - - if (QDF_IS_STATUS_ERROR(status)) - sme_err("scan event registration failed "); + } + if (prefer_dfs) { + /* next copy DFS channels (remaining channels in 5G) */ + for (i = 0; i < num_channel; i++) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq)) { + qdf_mem_copy(&tmp_list[j++], &chan_list[i], + sizeof(tSirUpdateChanParam)); + chan_list[i].freq = 0; + } } - } while (0); - return status; + } else { + /* next copy 2G channels */ + for (i = 0; i < num_channel; i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_list[i].freq)) { + qdf_mem_copy(&tmp_list[j++], &chan_list[i], + sizeof(tSirUpdateChanParam)); + chan_list[i].freq = 0; + } + } + } + /* copy rest of the channels in same order to tmp list */ + for (i = 0; i < num_channel; i++) { + if (chan_list[i].freq) { + qdf_mem_copy(&tmp_list[j++], &chan_list[i], + sizeof(tSirUpdateChanParam)); + chan_list[i].freq = 0; + } + } + /* copy tmp list to original channel list buffer */ + qdf_mem_copy(chan_list, tmp_list, + sizeof(tSirUpdateChanParam) * num_channel); + qdf_mem_free(tmp_list); } -QDF_STATUS csr_stop(struct mac_context *mac) +/** + * csr_roam_sort_channel_for_early_stop() - Sort the channels + * @mac_ctx: mac global context + * @chan_list: Original channel list from the upper layers + * @num_channel: Number of original channels + * + * For Early stop scan feature, the channel list should be in an order, + * where-in there is a maximum chance to detect an AP in the initial + * channels in the list so that the scanning can be stopped early as the + * feature demands. + * Below fixed greedy channel list has been provided + * based on most of the enterprise wifi installations across the globe. + * + * Identify all the greedy channels within the channel list from user space. + * Identify all the non-greedy channels in the user space channel list. + * Merge greedy channels followed by non-greedy channels back into the + * chan_list. + * + * Return: None + */ +static void csr_roam_sort_channel_for_early_stop(struct mac_context *mac_ctx, + tSirUpdateChanList *chan_list, uint8_t num_channel) { - uint32_t sessionId; - - if (mac->mlme_cfg->reg.enable_pending_chan_list_req) - ucfg_scan_unregister_event_handler(mac->pdev, - csr_scan_event_handler, - mac); - ucfg_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN); - ucfg_scan_unregister_requester(mac->psoc, mac->scan.requester_id); + tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy; + uint8_t i, j; + static const uint32_t fixed_greedy_freq_list[] = {2412, 2437, 2462, + 5180, 5240, 5200, 5220, 2457, 2417, 2452, 5745, 5785, 5805, + 2422, 2427, 2447, 5765, 5825, 2442, 2432, 5680, 5700, 5260, + 5580, 5280, 5520, 5320, 5300, 5500, 5600, 2472, 2484, 5560, + 5660, 5755, 5775}; + uint8_t num_fixed_greedy_chan; + uint8_t num_greedy_chan = 0; + uint8_t num_non_greedy_chan = 0; + uint8_t match_found = false; + uint32_t buf_size; - /* - * purge all serialization commnad if there are any pending to make - * sure memory and vdev ref are freed. + buf_size = sizeof(tSirUpdateChanList) + + (sizeof(tSirUpdateChanParam) * num_channel); + chan_list_greedy = qdf_mem_malloc(buf_size); + chan_list_non_greedy = qdf_mem_malloc(buf_size); + if (!chan_list_greedy || !chan_list_non_greedy) + goto scan_list_sort_error; + /* + * fixed_greedy_freq_list is an evaluated freq list based on most of + * the enterprise wifi deployments and the order of the channels + * determines the highest possibility of finding an AP. + * chan_list is the channel list provided by upper layers based on the + * regulatory domain. */ - csr_purge_pdev_all_ser_cmd_list(mac); - for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) - csr_roam_close_session(mac, sessionId, true); + num_fixed_greedy_chan = sizeof(fixed_greedy_freq_list) / + sizeof(uint32_t); + /* + * Browse through the chan_list and put all the non-greedy channels + * into a separate list by name chan_list_non_greedy + */ + for (i = 0; i < num_channel; i++) { + for (j = 0; j < num_fixed_greedy_chan; j++) { + if (chan_list->chanParam[i].freq == + fixed_greedy_freq_list[j]) { + match_found = true; + break; + } + } + if (!match_found) { + qdf_mem_copy( + &chan_list_non_greedy->chanParam[num_non_greedy_chan], + &chan_list->chanParam[i], + sizeof(tSirUpdateChanParam)); + num_non_greedy_chan++; + } else { + match_found = false; + } + } + /* + * Browse through the fixed_greedy_chan_list and put all the greedy + * channels in the chan_list into a separate list by name + * chan_list_greedy + */ + for (i = 0; i < num_fixed_greedy_chan; i++) { + for (j = 0; j < num_channel; j++) { + if (fixed_greedy_freq_list[i] == + chan_list->chanParam[j].freq) { + qdf_mem_copy( + &chan_list_greedy->chanParam[num_greedy_chan], + &chan_list->chanParam[j], + sizeof(tSirUpdateChanParam)); + num_greedy_chan++; + break; + } + } + } + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, + "greedy=%d, non-greedy=%d, tot=%d", + num_greedy_chan, num_non_greedy_chan, num_channel); + if ((num_greedy_chan + num_non_greedy_chan) != num_channel) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "incorrect sorting of channels"); + goto scan_list_sort_error; + } + /* Copy the Greedy channels first */ + i = 0; + qdf_mem_copy(&chan_list->chanParam[i], + &chan_list_greedy->chanParam[i], + num_greedy_chan * sizeof(tSirUpdateChanParam)); + /* Copy the remaining Non Greedy channels */ + i = num_greedy_chan; + j = 0; + qdf_mem_copy(&chan_list->chanParam[i], + &chan_list_non_greedy->chanParam[j], + num_non_greedy_chan * sizeof(tSirUpdateChanParam)); - for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) - csr_neighbor_roam_close(mac, sessionId); - for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) - if (CSR_IS_SESSION_VALID(mac, sessionId)) - ucfg_scan_flush_results(mac->pdev, NULL); + /* Update channel list for 5g preference and allow DFS roam */ + csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel); +scan_list_sort_error: + qdf_mem_free(chan_list_greedy); + qdf_mem_free(chan_list_non_greedy); +} - /* Reset the domain back to the deault */ - mac->scan.domainIdCurrent = mac->scan.domainIdDefault; +/** + * csr_emu_chan_req() - update the required channel list for emulation + * @channel: channel number to check + * + * To reduce scan time during emulation platforms, this function + * restricts the scanning to be done on selected channels + * + * Return: QDF_STATUS enumeration + */ +#ifdef QCA_WIFI_NAPIER_EMULATION +#define SCAN_CHAN_LIST_5G_LEN 6 +#define SCAN_CHAN_LIST_2G_LEN 3 +static const uint8_t +csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 5180, 5220, 5260, 5280, 5700, 5745 }; +static const uint8_t +csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 2412, 2437, 2462 }; +static QDF_STATUS csr_emu_chan_req(uint32_t channel) +{ + int i; - for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) { - csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, sessionId); - csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, - sessionId); + if (WLAN_REG_IS_24GHZ_CH_FREQ(channel)) { + for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) { + if (csr_scan_chan_list_2g[i] == channel) + return QDF_STATUS_SUCCESS; + } + } else if (WLAN_REG_IS_5GHZ_CH_FREQ(channel)) { + for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) { + if (csr_scan_chan_list_5g[i] == channel) + return QDF_STATUS_SUCCESS; + } } - + return QDF_STATUS_E_FAILURE; +} +#else +static QDF_STATUS csr_emu_chan_req(uint32_t channel_num) +{ return QDF_STATUS_SUCCESS; } +#endif -QDF_STATUS csr_ready(struct mac_context *mac) +#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY +static void csr_add_len_of_social_channels(struct mac_context *mac, + uint8_t *num_chan) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - /* If the gScanAgingTime is set to '0' then scan results aging timeout - * based on timer feature is not enabled - */ - status = csr_apply_channel_and_power_list(mac); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("csr_apply_channel_and_power_list failed status: %d", - status); + uint8_t i; + uint8_t no_chan = *num_chan; - return status; + sme_debug("add len of social channels, before adding - num_chan:%hu", + *num_chan); + if (CSR_IS_5G_BAND_ONLY(mac)) { + for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { + if (wlan_reg_get_channel_state_for_freq( + mac->pdev, social_channel_freq[i]) == + CHANNEL_STATE_ENABLE) + no_chan++; + } + } + *num_chan = no_chan; + sme_debug("after adding - num_chan:%hu", *num_chan); } -void csr_set_default_dot11_mode(struct mac_context *mac) +static void csr_add_social_channels(struct mac_context *mac, + tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, + uint8_t *num_chan) { - mac->mlme_cfg->dot11_mode.dot11_mode = - csr_translate_to_wni_cfg_dot11_mode(mac, - mac->roam.configParam.uCfgDot11Mode); -} + uint8_t i; + uint8_t no_chan = *num_chan; -void csr_set_global_cfgs(struct mac_context *mac) + sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list, + *num_chan); + if (CSR_IS_5G_BAND_ONLY(mac)) { + for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { + if (wlan_reg_get_channel_state_for_freq( + mac->pdev, social_channel_freq[i]) != + CHANNEL_STATE_ENABLE) + continue; + chan_list->chanParam[no_chan].freq = + social_channel_freq[i]; + chan_list->chanParam[no_chan].pwr = + csr_find_channel_pwr(pScan->defaultPowerTable, + social_channel_freq[i]); + chan_list->chanParam[no_chan].dfsSet = false; + if (cds_is_5_mhz_enabled()) + chan_list->chanParam[no_chan].quarter_rate + = 1; + else if (cds_is_10_mhz_enabled()) + chan_list->chanParam[no_chan].half_rate = 1; + no_chan++; + } + sme_debug("after adding -num_chan %hu", no_chan); + } + *num_chan = no_chan; +} +#else +static void csr_add_len_of_social_channels(struct mac_context *mac, + uint8_t *num_chan) { - wlan_mlme_set_frag_threshold(mac->psoc, csr_get_frag_thresh(mac)); - wlan_mlme_set_rts_threshold(mac->psoc, csr_get_rts_thresh(mac)); - /* For now we will just use the 5GHz CB mode ini parameter to decide - * whether CB supported or not in Probes when there is no session - * Once session is established we will use the session related params - * stored in PE session for CB mode - */ - if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_5GHZ, - mac->roam.configParam.channelBondingMode5GHz)) - ucfg_mlme_set_channel_bonding_5ghz(mac->psoc, - mac->roam.configParam. - channelBondingMode5GHz); - if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_24GHZ, - mac->roam.configParam.channelBondingMode24GHz)) - ucfg_mlme_set_channel_bonding_24ghz(mac->psoc, - mac->roam.configParam. - channelBondingMode24GHz); - - if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD, - mac->roam.configParam.HeartbeatThresh24)) - mac->mlme_cfg->timeouts.heart_beat_threshold = - mac->roam.configParam.HeartbeatThresh24; - else - mac->mlme_cfg->timeouts.heart_beat_threshold = - cfg_default(CFG_HEART_BEAT_THRESHOLD); - - /* Update the operating mode to configured value during - * initialization, So that client can advertise full - * capabilities in Probe request frame. - */ - csr_set_default_dot11_mode(mac); + sme_debug("skip adding len of social channels"); } +static void csr_add_social_channels(struct mac_context *mac, + tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, + uint8_t *num_chan) +{ + sme_debug("skip social channels"); +} +#endif /** - * csr_packetdump_timer_handler() - packet dump timer - * handler - * @pv: user data - * - * This function is used to handle packet dump timer - * - * Return: None + * csr_scan_event_handler() - callback for scan event + * @vdev: wlan objmgr vdev pointer + * @event: scan event + * @arg: global mac context pointer * + * Return: void */ -static void csr_packetdump_timer_handler(void *pv) -{ - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "%s Invoking packetdump deregistration API", __func__); - wlan_deregister_txrx_packetdump(); -} - -void csr_packetdump_timer_stop(void) +static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg) { - QDF_STATUS status; - mac_handle_t mac_handle; - struct mac_context *mac; + bool success = false; + QDF_STATUS lock_status; + struct mac_context *mac = arg; - mac_handle = cds_get_context(QDF_MODULE_ID_SME); - mac = MAC_CONTEXT(mac_handle); - if (!mac) { - QDF_ASSERT(0); + if (!mac) return; - } - status = qdf_mc_timer_stop(&mac->roam.packetdump_timer); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("cannot stop packetdump timer"); -} + if (!util_is_scan_completed(event, &success)) + return; -static QDF_STATUS csr_roam_open(struct mac_context *mac) + lock_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(lock_status)) + return; + + if (mac->scan.pending_channel_list_req) + csr_update_channel_list(mac); + sme_release_global_lock(&mac->sme); +} + +QDF_STATUS csr_update_channel_list(struct mac_context *mac) +{ + tSirUpdateChanList *pChanList; + struct csr_scanstruct *pScan = &mac->scan; + uint8_t numChan = pScan->base_channels.numChannels; + uint8_t num_channel = 0; + uint32_t bufLen; + struct scheduler_msg msg = {0}; + uint8_t i; + uint8_t channel_state; + uint16_t unsafe_chan[NUM_CHANNELS]; + uint16_t unsafe_chan_cnt = 0; + uint16_t cnt = 0; + uint32_t channel_freq; + bool is_unsafe_chan; + bool is_same_band; + bool is_5mhz_enabled; + bool is_10mhz_enabled; + enum scm_scan_status scan_status; + QDF_STATUS lock_status; + + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + if (!qdf_ctx) { + sme_err("qdf_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + + lock_status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_ERROR(lock_status)) + return lock_status; + + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { + scan_status = ucfg_scan_get_pdev_status(mac->pdev); + if (scan_status == SCAN_IS_ACTIVE || + scan_status == SCAN_IS_ACTIVE_AND_PENDING) { + mac->scan.pending_channel_list_req = true; + sme_release_global_lock(&mac->sme); + sme_debug("scan in progress postpone channel list req "); + return QDF_STATUS_SUCCESS; + } + mac->scan.pending_channel_list_req = false; + } + sme_release_global_lock(&mac->sme); + + pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, + &unsafe_chan_cnt, + sizeof(unsafe_chan)); + + csr_add_len_of_social_channels(mac, &numChan); + + bufLen = sizeof(tSirUpdateChanList) + + (sizeof(tSirUpdateChanParam) * (numChan)); + + csr_init_operating_classes(mac); + pChanList = qdf_mem_malloc(bufLen); + if (!pChanList) + return QDF_STATUS_E_NOMEM; + + is_5mhz_enabled = cds_is_5_mhz_enabled(); + if (is_5mhz_enabled) + sme_nofl_debug("quarter_rate enabled"); + is_10mhz_enabled = cds_is_10_mhz_enabled(); + if (is_10mhz_enabled) + sme_nofl_debug("half_rate enabled"); + + for (i = 0; i < pScan->base_channels.numChannels; i++) { + struct csr_sta_roam_policy_params *roam_policy = + &mac->roam.configParam.sta_roam_policy; + if (QDF_STATUS_SUCCESS != + csr_emu_chan_req(pScan->base_channels.channel_freq_list[i])) + continue; + + channel_freq = pScan->base_channels.channel_freq_list[i]; + /* Scan is not performed on DSRC channels*/ + if (wlan_reg_is_dsrc_freq(channel_freq)) + continue; + + channel_state = + wlan_reg_get_channel_state_for_freq( + mac->pdev, channel_freq); + if ((CHANNEL_STATE_ENABLE == channel_state) || + mac->scan.fEnableDFSChnlScan) { + if ((mac->roam.configParam.sta_roam_policy.dfs_mode == + CSR_STA_ROAM_POLICY_DFS_DISABLED) && + (channel_state == CHANNEL_STATE_DFS)) { + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_DEBUG, + FL("skip dfs channel frequency %d"), + channel_freq); + continue; + } + if (mac->roam.configParam.sta_roam_policy. + skip_unsafe_channels && + unsafe_chan_cnt) { + is_unsafe_chan = false; + for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) { + if (unsafe_chan[cnt] == channel_freq) { + is_unsafe_chan = true; + break; + } + } + is_same_band = + (WLAN_REG_IS_24GHZ_CH_FREQ( + channel_freq) && + roam_policy->sap_operating_band == + BAND_2G) || + (WLAN_REG_IS_5GHZ_CH_FREQ( + channel_freq) && + roam_policy->sap_operating_band == + BAND_5G); + if (is_unsafe_chan && is_same_band) { + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_DEBUG, + FL("ignoring unsafe channel freq %d"), + channel_freq); + continue; + } + } + pChanList->chanParam[num_channel].freq = + pScan->base_channels.channel_freq_list[i]; + pChanList->chanParam[num_channel].pwr = + csr_find_channel_pwr( + pScan->defaultPowerTable, + pScan->base_channels.channel_freq_list[i]); + + if (pScan->fcc_constraint) { + if (2467 == + pScan->base_channels.channel_freq_list[i]) { + pChanList->chanParam[num_channel].pwr = + MAX_PWR_FCC_CHAN_12; + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_DEBUG, + "txpow for channel 12 is %d", + MAX_PWR_FCC_CHAN_12); + } + if (2472 == + pScan->base_channels.channel_freq_list[i]) { + pChanList->chanParam[num_channel].pwr = + MAX_PWR_FCC_CHAN_13; + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_DEBUG, + "txpow for channel 13 is %d", + MAX_PWR_FCC_CHAN_13); + } + } + + if (!ucfg_is_nan_allowed_on_freq(mac->pdev, + pChanList->chanParam[num_channel].freq)) + pChanList->chanParam[num_channel].nan_disabled = + true; + + if (CHANNEL_STATE_ENABLE != channel_state) + pChanList->chanParam[num_channel].dfsSet = + true; + + pChanList->chanParam[num_channel].quarter_rate = + is_5mhz_enabled; + + pChanList->chanParam[num_channel].half_rate = + is_10mhz_enabled; + + num_channel++; + } + } + + csr_add_social_channels(mac, pChanList, pScan, &num_channel); + + if (mac->mlme_cfg->lfr.early_stop_scan_enable) + csr_roam_sort_channel_for_early_stop(mac, pChanList, + num_channel); + else + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("Early Stop Scan Feature not supported")); + + if ((mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_AUTO) || + (mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_11AC) || + (mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_11AC_ONLY)) { + pChanList->vht_en = true; + if (mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) + pChanList->vht_24_en = true; + } + if ((mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_AUTO) || + (mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_11N) || + (mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_11N_ONLY)) { + pChanList->ht_en = true; + } + if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) || + (mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) || + (mac->roam.configParam.uCfgDot11Mode == + eCSR_CFG_DOT11_MODE_11AX_ONLY)) + pChanList->he_en = true; + + msg.type = WMA_UPDATE_CHAN_LIST_REQ; + msg.reserved = 0; + msg.bodyptr = pChanList; + pChanList->numChan = num_channel; + MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, + NO_SESSION, msg.type)); + if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, + &msg)) { + qdf_mem_free(pChanList); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS csr_start(struct mac_context *mac) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t i; - struct csr_roam_session *pSession; do { - for (i = 0; i < WLAN_MAX_VDEVS; i++) { - pSession = CSR_GET_SESSION(mac, i); - pSession->roamingTimerInfo.mac = mac; - pSession->roamingTimerInfo.vdev_id = - WLAN_UMAC_VDEV_ID_MAX; - } - mac->roam.WaitForKeyTimerInfo.mac = mac; - mac->roam.WaitForKeyTimerInfo.vdev_id = - WLAN_UMAC_VDEV_ID_MAX; - status = qdf_mc_timer_init(&mac->roam.hTimerWaitForKey, - QDF_TIMER_TYPE_SW, - csr_roam_wait_for_key_time_out_handler, - &mac->roam.WaitForKeyTimerInfo); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_err("cannot allocate memory for WaitForKey time out timer"); + for (i = 0; i < WLAN_MAX_VDEVS; i++) + csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, i); + + status = csr_roam_start(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) break; - } - status = qdf_mc_timer_init(&mac->roam.packetdump_timer, - QDF_TIMER_TYPE_SW, csr_packetdump_timer_handler, - mac); + + mac->roam.sPendingCommands = 0; + for (i = 0; i < WLAN_MAX_VDEVS; i++) + status = csr_neighbor_roam_init(mac, i); if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_err("cannot allocate memory for packetdump timer"); + sme_warn("Couldn't Init HO control blk"); break; } - spin_lock_init(&mac->roam.roam_state_lock); + /* Register with scan component */ + mac->scan.requester_id = ucfg_scan_register_requester( + mac->psoc, + "CSR", csr_scan_callback, mac); + + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { + status = ucfg_scan_register_event_handler(mac->pdev, + csr_scan_event_handler, mac); + + if (QDF_IS_STATUS_ERROR(status)) + sme_err("scan event registration failed "); + } } while (0); return status; } -static QDF_STATUS csr_roam_close(struct mac_context *mac) +QDF_STATUS csr_stop(struct mac_context *mac) { uint32_t sessionId; + if (mac->mlme_cfg->reg.enable_pending_chan_list_req) + ucfg_scan_unregister_event_handler(mac->pdev, + csr_scan_event_handler, + mac); + ucfg_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN); + ucfg_scan_unregister_requester(mac->psoc, mac->scan.requester_id); + /* * purge all serialization commnad if there are any pending to make * sure memory and vdev ref are freed. */ csr_purge_pdev_all_ser_cmd_list(mac); for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) - csr_roam_close_session(mac, sessionId, true); - - qdf_mc_timer_stop(&mac->roam.hTimerWaitForKey); - qdf_mc_timer_destroy(&mac->roam.hTimerWaitForKey); - qdf_mc_timer_stop(&mac->roam.packetdump_timer); - qdf_mc_timer_destroy(&mac->roam.packetdump_timer); - return QDF_STATUS_SUCCESS; -} + csr_roam_vdev_delete(mac, sessionId, true); -QDF_STATUS csr_roam_start(struct mac_context *mac) -{ - (void)mac; - return QDF_STATUS_SUCCESS; -} + for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) + csr_neighbor_roam_close(mac, sessionId); + for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) + if (CSR_IS_SESSION_VALID(mac, sessionId)) + ucfg_scan_flush_results(mac->pdev, NULL); + + /* Reset the domain back to the deault */ + mac->scan.domainIdCurrent = mac->scan.domainIdDefault; + + for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) { + csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, sessionId); + csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, + sessionId); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS csr_ready(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + /* If the gScanAgingTime is set to '0' then scan results aging timeout + * based on timer feature is not enabled + */ + status = csr_apply_channel_and_power_list(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) + sme_err("csr_apply_channel_and_power_list failed status: %d", + status); + + return status; +} + +void csr_set_default_dot11_mode(struct mac_context *mac) +{ + mac->mlme_cfg->dot11_mode.dot11_mode = + csr_translate_to_wni_cfg_dot11_mode(mac, + mac->roam.configParam.uCfgDot11Mode); +} + +void csr_set_global_cfgs(struct mac_context *mac) +{ + wlan_mlme_set_frag_threshold(mac->psoc, csr_get_frag_thresh(mac)); + wlan_mlme_set_rts_threshold(mac->psoc, csr_get_rts_thresh(mac)); + /* For now we will just use the 5GHz CB mode ini parameter to decide + * whether CB supported or not in Probes when there is no session + * Once session is established we will use the session related params + * stored in PE session for CB mode + */ + if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_5GHZ, + mac->roam.configParam.channelBondingMode5GHz)) + ucfg_mlme_set_channel_bonding_5ghz(mac->psoc, + mac->roam.configParam. + channelBondingMode5GHz); + if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_24GHZ, + mac->roam.configParam.channelBondingMode24GHz)) + ucfg_mlme_set_channel_bonding_24ghz(mac->psoc, + mac->roam.configParam. + channelBondingMode24GHz); + + if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD, + mac->roam.configParam.HeartbeatThresh24)) + mac->mlme_cfg->timeouts.heart_beat_threshold = + mac->roam.configParam.HeartbeatThresh24; + else + mac->mlme_cfg->timeouts.heart_beat_threshold = + cfg_default(CFG_HEART_BEAT_THRESHOLD); + + /* Update the operating mode to configured value during + * initialization, So that client can advertise full + * capabilities in Probe request frame. + */ + csr_set_default_dot11_mode(mac); +} + +#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ + defined(FEATURE_PKTLOG) && !defined(REMOVE_PKT_LOG) +/** + * csr_packetdump_timer_handler() - packet dump timer + * handler + * @pv: user data + * + * This function is used to handle packet dump timer + * + * Return: None + * + */ +static void csr_packetdump_timer_handler(void *pv) +{ + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "%s Invoking packetdump deregistration API", __func__); + wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); +} + +void csr_packetdump_timer_start(void) +{ + QDF_STATUS status; + mac_handle_t mac_handle; + struct mac_context *mac; + QDF_TIMER_STATE cur_state; + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + mac = MAC_CONTEXT(mac_handle); + if (!mac) { + QDF_ASSERT(0); + return; + } + cur_state = qdf_mc_timer_get_current_state(&mac->roam.packetdump_timer); + if (cur_state == QDF_TIMER_STATE_STARTING || + cur_state == QDF_TIMER_STATE_STARTING) { + sme_debug("packetdump_timer is already started: %d", cur_state); + return; + } + + status = qdf_mc_timer_start(&mac->roam.packetdump_timer, + (PKT_DUMP_TIMER_DURATION * + QDF_MC_TIMER_TO_SEC_UNIT) / + QDF_MC_TIMER_TO_MS_UNIT); + if (!QDF_IS_STATUS_SUCCESS(status)) + sme_debug("cannot start packetdump timer status: %d", status); +} + +void csr_packetdump_timer_stop(void) +{ + QDF_STATUS status; + mac_handle_t mac_handle; + struct mac_context *mac; + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + mac = MAC_CONTEXT(mac_handle); + if (!mac) { + QDF_ASSERT(0); + return; + } + + status = qdf_mc_timer_stop(&mac->roam.packetdump_timer); + if (!QDF_IS_STATUS_SUCCESS(status)) + sme_err("cannot stop packetdump timer"); +} + +static QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!mac) { + QDF_ASSERT(0); + return -EINVAL; + } + + status = qdf_mc_timer_init(&mac->roam.packetdump_timer, + QDF_TIMER_TYPE_SW, + csr_packetdump_timer_handler, + mac); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("cannot allocate memory for packetdump timer"); + return status; + } + + return status; +} + +static void csr_packetdump_timer_deinit(struct mac_context *mac) +{ + if (!mac) { + QDF_ASSERT(0); + return; + } + + qdf_mc_timer_stop(&mac->roam.packetdump_timer); + qdf_mc_timer_destroy(&mac->roam.packetdump_timer); +} +#else +static inline QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void csr_packetdump_timer_deinit(struct mac_context *mac) {} +#endif + +static QDF_STATUS csr_roam_open(struct mac_context *mac) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t i; + struct csr_roam_session *pSession; + + do { + for (i = 0; i < WLAN_MAX_VDEVS; i++) { + pSession = CSR_GET_SESSION(mac, i); + pSession->roamingTimerInfo.mac = mac; + pSession->roamingTimerInfo.vdev_id = + WLAN_UMAC_VDEV_ID_MAX; + } + mac->roam.WaitForKeyTimerInfo.mac = mac; + mac->roam.WaitForKeyTimerInfo.vdev_id = + WLAN_UMAC_VDEV_ID_MAX; + status = qdf_mc_timer_init(&mac->roam.hTimerWaitForKey, + QDF_TIMER_TYPE_SW, + csr_roam_wait_for_key_time_out_handler, + &mac->roam.WaitForKeyTimerInfo); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("cannot allocate memory for WaitForKey time out timer"); + break; + } + status = csr_packetdump_timer_init(mac); + if (!QDF_IS_STATUS_SUCCESS(status)) + break; + + spin_lock_init(&mac->roam.roam_state_lock); + } while (0); + return status; +} + +static QDF_STATUS csr_roam_close(struct mac_context *mac) +{ + uint32_t sessionId; + + /* + * purge all serialization commnad if there are any pending to make + * sure memory and vdev ref are freed. + */ + csr_purge_pdev_all_ser_cmd_list(mac); + for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) + csr_roam_vdev_delete(mac, sessionId, true); + + qdf_mc_timer_stop(&mac->roam.hTimerWaitForKey); + qdf_mc_timer_destroy(&mac->roam.hTimerWaitForKey); + csr_packetdump_timer_deinit(mac); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS csr_roam_start(struct mac_context *mac) +{ + (void)mac; + return QDF_STATUS_SUCCESS; +} void csr_roam_stop(struct mac_context *mac, uint32_t sessionId) { csr_roam_stop_roaming_timer(mac, sessionId); - /* deregister the clients requesting stats from PE/TL & also stop - * the corresponding timers - */ - csr_roam_dereg_statistics_req(mac); } QDF_STATUS csr_roam_copy_connect_profile(struct mac_context *mac, @@ -1530,7 +1953,7 @@ QDF_STATUS csr_roam_copy_connect_profile(struct mac_context *mac, pProfile->EncryptionType = connected_prof->EncryptionType; pProfile->mcEncryptionType = connected_prof->mcEncryptionType; pProfile->BSSType = connected_prof->BSSType; - pProfile->operationChannel = connected_prof->operationChannel; + pProfile->op_freq = connected_prof->op_freq; qdf_mem_copy(&pProfile->bssid, &connected_prof->bssid, sizeof(struct qdf_mac_addr)); qdf_mem_copy(&pProfile->SSID, &connected_prof->SSID, @@ -1738,9 +2161,10 @@ static void init_config_param(struct mac_context *mac) void csr_flush_cfg_bg_scan_roam_channel_list(tCsrChannelInfo *channel_info) { - if (channel_info->ChannelList) { - qdf_mem_free(channel_info->ChannelList); - channel_info->ChannelList = NULL; + /* Free up the memory first (if required) */ + if (channel_info->freq_list) { + qdf_mem_free(channel_info->freq_list); + channel_info->freq_list = NULL; channel_info->numOfChannels = 0; } } @@ -1770,55 +2194,56 @@ csr_flush_roam_scan_chan_lists(struct mac_context *mac, uint8_t vdev_id) QDF_STATUS csr_create_bg_scan_roam_channel_list(struct mac_context *mac, tCsrChannelInfo *channel_info, - const uint8_t *pChannelList, - const uint8_t numChannels) + const uint32_t *chan_freq_list, + const uint8_t num_chan) { QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t i; - channel_info->ChannelList = - qdf_mem_malloc(sizeof(uint32_t) * numChannels); - if (!channel_info->ChannelList) + channel_info->freq_list = qdf_mem_malloc(sizeof(uint32_t) * num_chan); + if (!channel_info->freq_list) return QDF_STATUS_E_NOMEM; - channel_info->numOfChannels = numChannels; - qdf_mem_copy(channel_info->ChannelList, pChannelList, numChannels); + channel_info->numOfChannels = num_chan; + for (i = 0; i < num_chan; i++) + channel_info->freq_list[i] = chan_freq_list[i]; return status; } #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) /** - * csr_check_band_channel_match() - check if passed band and channel match - * parameters - * @band: band to match with channel - * @channel: channel to match with band + * csr_check_band_freq_match() - check if passed band and ch freq match + * @band: band to match with channel frequency + * @freq: freq to match with band * * Return: bool if match else false */ static bool -csr_check_band_channel_match(enum band_info band, uint8_t channel) +csr_check_band_freq_match(enum band_info band, uint32_t freq) { - if (BAND_ALL == band) + if (band == BAND_ALL) return true; - if (BAND_2G == band && WLAN_REG_IS_24GHZ_CH(channel)) + if (band == BAND_2G && WLAN_REG_IS_24GHZ_CH_FREQ(freq)) return true; - if (BAND_5G == band && WLAN_REG_IS_5GHZ_CH(channel)) + if (band == BAND_5G && WLAN_REG_IS_5GHZ_CH_FREQ(freq)) return true; return false; } + /** * is_dfs_unsafe_extra_band_chan() - check if dfs unsafe or extra band channel * @mac_ctx: MAC context - * @chan: channel freq to check + * @freq: channel freq to check * @band: band for intra band check .*. * Return: bool if match else false */ static bool -is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint8_t chan, +is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint32_t freq, enum band_info band) { uint16_t unsafe_chan[NUM_CHANNELS]; @@ -1836,7 +2261,7 @@ is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint8_t chan, ROAMING_DFS_CHANNEL_DISABLED || mac_ctx->roam.configParam.sta_roam_policy.dfs_mode == CSR_STA_ROAM_POLICY_DFS_DISABLED) && - (wlan_reg_is_dfs_ch(mac_ctx->pdev, chan))) + (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, freq))) return true; pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, @@ -1846,20 +2271,20 @@ is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint8_t chan, unsafe_chan_cnt) { is_unsafe_chan = false; for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) { - if (unsafe_chan[cnt] == chan) { + if (unsafe_chan[cnt] == freq) { is_unsafe_chan = true; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - ("ignoring unsafe channel chan %d"), - chan); + ("ignoring unsafe channel freq %d"), + freq); return true; } } } - if (!csr_check_band_channel_match(band, chan)) { + if (!csr_check_band_freq_match(band, freq)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - ("ignoring non-intra band chan %d"), - chan); + ("ignoring non-intra band freq %d"), + freq); return true; } @@ -1872,7 +2297,7 @@ is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint8_t chan, * csr_create_roam_scan_channel_list() - create roam scan channel list * @mac: Global mac pointer * @sessionId: session id - * @pChannelList: pointer to channel list + * @chan_freq_list: pointer to channel list * @numChannels: number of channels * @band: band enumeration * @@ -1888,7 +2313,7 @@ is_dfs_unsafe_extra_band_chan(struct mac_context *mac_ctx, uint8_t chan, */ QDF_STATUS csr_create_roam_scan_channel_list(struct mac_context *mac, uint8_t sessionId, - uint8_t *pChannelList, + uint32_t *chan_freq_list, uint8_t numChannels, const enum band_info band) { @@ -1896,12 +2321,12 @@ QDF_STATUS csr_create_roam_scan_channel_list(struct mac_context *mac, tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &mac->roam.neighborRoamInfo[sessionId]; - uint8_t outNumChannels = 0; + uint8_t out_num_chan = 0; uint8_t inNumChannels = numChannels; - uint8_t *inPtr = pChannelList; + uint32_t *in_ptr = chan_freq_list; uint8_t i = 0; - uint8_t ChannelList[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; - uint8_t tmpChannelList[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t csr_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; + uint32_t tmp_chan_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; uint8_t mergedOutputNumOfChannels = 0; tpCsrChannelInfo currChannelListInfo @@ -1915,34 +2340,34 @@ QDF_STATUS csr_create_roam_scan_channel_list(struct mac_context *mac, if (mac->scan.occupiedChannels[sessionId].numChannels) { csr_neighbor_roam_merge_channel_lists(mac, &mac->scan. occupiedChannels[sessionId]. - channelList[0], mac->scan. + channel_freq_list[0], mac->scan. occupiedChannels[sessionId]. - numChannels, inPtr, + numChannels, in_ptr, inNumChannels, &mergedOutputNumOfChannels); inNumChannels = mergedOutputNumOfChannels; } if (BAND_2G == band) { for (i = 0; i < inNumChannels; i++) { - if (WLAN_REG_IS_24GHZ_CH(inPtr[i]) - && csr_roam_is_channel_valid(mac, inPtr[i])) { - ChannelList[outNumChannels++] = inPtr[i]; + if (WLAN_REG_IS_24GHZ_CH_FREQ(in_ptr[i]) && + csr_roam_is_channel_valid(mac, in_ptr[i])) { + csr_freq_list[out_num_chan++] = in_ptr[i]; } } } else if (BAND_5G == band) { for (i = 0; i < inNumChannels; i++) { /* Add 5G Non-DFS channel */ - if (WLAN_REG_IS_5GHZ_CH(inPtr[i]) && - csr_roam_is_channel_valid(mac, inPtr[i]) && - !wlan_reg_is_dfs_ch(mac->pdev, inPtr[i])) { - ChannelList[outNumChannels++] = inPtr[i]; + if (WLAN_REG_IS_5GHZ_CH_FREQ(in_ptr[i]) && + csr_roam_is_channel_valid(mac, in_ptr[i]) && + !wlan_reg_is_dfs_for_freq(mac->pdev, in_ptr[i])) { + csr_freq_list[out_num_chan++] = in_ptr[i]; } } } else if (BAND_ALL == band) { for (i = 0; i < inNumChannels; i++) { - if (csr_roam_is_channel_valid(mac, inPtr[i]) && - !wlan_reg_is_dfs_ch(mac->pdev, inPtr[i])) { - ChannelList[outNumChannels++] = inPtr[i]; + if (csr_roam_is_channel_valid(mac, in_ptr[i]) && + !wlan_reg_is_dfs_for_freq(mac->pdev, in_ptr[i])) { + csr_freq_list[out_num_chan++] = in_ptr[i]; } } } else { @@ -1959,30 +2384,33 @@ QDF_STATUS csr_create_roam_scan_channel_list(struct mac_context *mac, * list are already filtered for 2.4G channels, hence ignore this check */ if ((BAND_ALL == band) && CSR_IS_ROAM_INTRA_BAND_ENABLED(mac)) { - csr_neighbor_roam_channels_filter_by_current_band(mac, - sessionId, - ChannelList, - outNumChannels, - tmpChannelList, - &outNumChannels); - qdf_mem_copy(ChannelList, tmpChannelList, outNumChannels); + csr_neighbor_roam_channels_filter_by_current_band( + mac, + sessionId, + csr_freq_list, + out_num_chan, + tmp_chan_freq_list, + &out_num_chan); } /* Prepare final roam scan channel list */ - if (outNumChannels) { + if (out_num_chan) { /* Clear the channel list first */ - if (currChannelListInfo->ChannelList) { - qdf_mem_free(currChannelListInfo->ChannelList); - currChannelListInfo->ChannelList = NULL; + if (currChannelListInfo->freq_list) { + qdf_mem_free(currChannelListInfo->freq_list); + currChannelListInfo->freq_list = NULL; currChannelListInfo->numOfChannels = 0; } - currChannelListInfo->ChannelList - = qdf_mem_malloc(outNumChannels * sizeof(uint8_t)); - if (!currChannelListInfo->ChannelList) { + currChannelListInfo->freq_list = + qdf_mem_malloc(out_num_chan * sizeof(uint32_t)); + if (!currChannelListInfo->freq_list) { currChannelListInfo->numOfChannels = 0; return QDF_STATUS_E_NOMEM; } - qdf_mem_copy(currChannelListInfo->ChannelList, - ChannelList, outNumChannels); + for (i = 0; i < out_num_chan; i++) + currChannelListInfo->freq_list[i] = + tmp_chan_freq_list[i]; + + currChannelListInfo->numOfChannels = out_num_chan; } return status; } @@ -2038,8 +2466,6 @@ static void csr_tsm_stats_rsp_processor(struct mac_context *mac, void *pMsg) ((tCsrTsmStatsCallback) (reqBkp->tsmStatsCallback))(pTsmStatsRsp-> tsmMetrics, - pTsmStatsRsp-> - staId, reqBkp-> pDevContext); reqBkp->tsmStatsCallback = NULL; @@ -2082,8 +2508,8 @@ static void csr_send_ese_adjacent_ap_rep_ind(struct mac_context *mac, return; roamTS2 = qdf_mc_timer_get_system_time(); roam_info->tsmRoamDelay = roamTS2 - pSession->roamTS1; - sme_debug("Bssid(" QDF_MAC_ADDR_STR ") Roaming Delay(%u ms)", - QDF_MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes), + sme_debug("Bssid(" QDF_MAC_ADDR_FMT ") Roaming Delay(%u ms)", + QDF_MAC_ADDR_REF(pSession->connectedProfile.bssid.bytes), roam_info->tsmRoamDelay); pe_session = pe_find_session_by_bssid(mac, @@ -2116,7 +2542,6 @@ static void csr_send_ese_adjacent_ap_rep_ind(struct mac_context *mac, */ QDF_STATUS csr_get_tsm_stats(struct mac_context *mac, tCsrTsmStatsCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext, uint8_t tid) { @@ -2130,7 +2555,6 @@ QDF_STATUS csr_get_tsm_stats(struct mac_context *mac, /* need to initiate a stats request to PE */ pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ; pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq); - pMsg->staId = staId; pMsg->tid = tid; qdf_copy_macaddr(&pMsg->bssId, &bssId); pMsg->tsmStatsCallback = callback; @@ -2164,20 +2588,20 @@ csr_fetch_ch_lst_from_received_list(struct mac_context *mac_ctx, { uint8_t i = 0; uint8_t num_channels = 0; - uint8_t *ch_lst = NULL; + uint32_t *freq_lst = NULL; enum band_info band = BAND_ALL; if (curr_ch_lst_info->numOfChannels == 0) return; - ch_lst = curr_ch_lst_info->ChannelList; + freq_lst = curr_ch_lst_info->freq_list; for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) { - if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_lst, band)) { - ch_lst++; + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *freq_lst, band)) { + freq_lst++; continue; } - req_buf->ConnectedNetwork.ChannelCache[num_channels++] = *ch_lst; - ch_lst++; + req_buf->ConnectedNetwork.chan_freq_cache[num_channels++] = *freq_lst; + freq_lst++; } req_buf->ConnectedNetwork.ChannelCount = num_channels; req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC; @@ -2385,11 +2809,36 @@ uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState) } #ifdef WLAN_FEATURE_11AX -#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _channelid) \ - (_req)->he_config.bfee_sts_lt_80 = WLAN_CHAN_IS_2GHZ((_channelid)) ? \ - (_pmac)->he_cap_2g.bfee_sts_lt_80 : \ - (_pmac)->he_cap_5g.bfee_sts_lt_80 +#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _ch_freq) \ + csr_revise_req_he_cap_per_band(&(_req)->he_config, _pmac, _ch_freq) +static void +csr_revise_req_he_cap_per_band(tDot11fIEhe_cap *he_config, + struct mac_context *mac, + uint32_t ch_freq) +{ + if (wlan_reg_is_24ghz_ch_freq(ch_freq)) { + he_config->bfee_sts_lt_80 = + mac->he_cap_2g.bfee_sts_lt_80; + } else { + he_config->bfee_sts_lt_80 = + mac->he_cap_5g.bfee_sts_lt_80; + + he_config->num_sounding_lt_80 = + mac->he_cap_5g.num_sounding_lt_80; + if (he_config->chan_width_2 || + he_config->chan_width_3) { + he_config->bfee_sts_gt_80 = + mac->he_cap_5g.bfee_sts_gt_80; + he_config->num_sounding_gt_80 = + mac->he_cap_5g.num_sounding_gt_80; + he_config->he_ppdu_20_in_160_80p80Mhz = + mac->he_cap_5g.he_ppdu_20_in_160_80p80Mhz; + he_config->he_ppdu_80_in_160_80p80Mhz = + mac->he_cap_5g.he_ppdu_80_in_160_80p80Mhz; + } + } +} /** * csr_join_req_copy_he_cap() - Copy HE cap into CSR Join Req @@ -2466,7 +2915,7 @@ void csr_update_session_he_cap(struct mac_context *mac_ctx, } #else -#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _channelid) /* no op */ +#define CSR_REVISE_REQ_HE_CAP_PER_BAND(_req, _pmac, _ch_freq) /* no op */ static inline void csr_join_req_copy_he_cap(struct join_req *csr_join_req, @@ -2582,8 +3031,11 @@ QDF_STATUS csr_change_default_config_param(struct mac_context *mac, pParam->HeartbeatThresh50; mac->roam.configParam.ProprietaryRatesEnabled = pParam->ProprietaryRatesEnabled; - mac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24; - mac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G; + mac->roam.configParam.ad_hoc_ch_freq_5g = + pParam->ad_hoc_ch_freq_5g; + mac->roam.configParam.ad_hoc_ch_freq_2g = + pParam->ad_hoc_ch_freq_2g; + mac->roam.configParam.wep_tkip_in_he = pParam->wep_tkip_in_he; mac->roam.configParam.uCfgDot11Mode = @@ -2734,8 +3186,8 @@ QDF_STATUS csr_get_config_param(struct mac_context *mac, pParam->phyMode = cfg_params->phyMode; pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50; pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled; - pParam->AdHocChannel24 = cfg_params->AdHocChannel24; - pParam->AdHocChannel5G = cfg_params->AdHocChannel5G; + pParam->ad_hoc_ch_freq_5g = cfg_params->ad_hoc_ch_freq_5g; + pParam->ad_hoc_ch_freq_2g = cfg_params->ad_hoc_ch_freq_2g; pParam->bCatRssiOffset = cfg_params->bCatRssiOffset; pParam->statsReqPeriodicity = cfg_params->statsReqPeriodicity; pParam->statsReqPeriodicityInPS = cfg_params->statsReqPeriodicityInPS; @@ -2761,6 +3213,12 @@ QDF_STATUS csr_get_config_param(struct mac_context *mac, cfg_params->roam_params.bg_scan_bad_rssi_thresh; pParam->roam_bad_rssi_thresh_offset_2g = cfg_params->roam_params.roam_bad_rssi_thresh_offset_2g; + pParam->roam_data_rssi_threshold_triggers = + cfg_params->roam_params.roam_data_rssi_threshold_triggers; + pParam->roam_data_rssi_threshold = + cfg_params->roam_params.roam_data_rssi_threshold; + pParam->rx_data_inactivity_time = + cfg_params->roam_params.rx_data_inactivity_time; pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1; pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2; @@ -2806,15 +3264,15 @@ static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz) for ( ; idx < ch_lst->numChannels; idx++) { if (is_24_GHz) { - if (WLAN_REG_IS_24GHZ_CH(ch_lst->channelList[idx])) { - ch_lst->channelList[num_channels] = - ch_lst->channelList[idx]; + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) { + ch_lst->channel_freq_list[num_channels] = + ch_lst->channel_freq_list[idx]; num_channels++; } } else { - if (WLAN_REG_IS_5GHZ_CH(ch_lst->channelList[idx])) { - ch_lst->channelList[num_channels] = - ch_lst->channelList[idx]; + if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) { + ch_lst->channel_freq_list[num_channels] = + ch_lst->channel_freq_list[idx]; num_channels++; } } @@ -2829,9 +3287,9 @@ static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz) * channel in the structure. */ if (ch_lst->numChannels > num_channels) { - qdf_mem_zero(&ch_lst->channelList[num_channels], - sizeof(ch_lst->channelList[0]) * - (ch_lst->numChannels - num_channels)); + qdf_mem_zero(&ch_lst->channel_freq_list[num_channels], + sizeof(ch_lst->channel_freq_list[0]) * + (ch_lst->numChannels - num_channels)); } ch_lst->numChannels = num_channels; } @@ -2861,8 +3319,8 @@ void csr_prune_channel_list_for_mode(struct mac_context *mac_ctx, csr_prune_ch_list(ch_lst, false); } -#define INFRA_AP_DEFAULT_CHANNEL 6 -QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint8_t chnNum) +#define INFRA_AP_DEFAULT_CHAN_FREQ 2437 +QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint32_t freq) { uint8_t index = 0; QDF_STATUS status = QDF_STATUS_E_NOSUPPORT; @@ -2870,7 +3328,8 @@ QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint8_t chnNum) /* regulatory check */ for (index = 0; index < mac->scan.base_channels.numChannels; index++) { - if (mac->scan.base_channels.channelList[index] == chnNum) { + if (mac->scan.base_channels.channel_freq_list[index] == + freq){ status = QDF_STATUS_SUCCESS; break; } @@ -2878,7 +3337,7 @@ QDF_STATUS csr_is_valid_channel(struct mac_context *mac, uint8_t chnNum) if (QDF_STATUS_SUCCESS != status) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("channel %d is not available"), chnNum); + FL("freq %d is not available"), freq); } return status; @@ -2891,7 +3350,8 @@ QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac) QDF_STATUS qdf_status; uint8_t Index = 0; - qdf_status = wlan_reg_get_channel_list_with_power(mac->pdev, + qdf_status = wlan_reg_get_channel_list_with_power_for_freq( + mac->pdev, mac->scan.defaultPowerTable, &num20MHzChannelsFound); @@ -2906,8 +3366,8 @@ QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac) /* Move the channel list to the global data */ /* structure -- this will be used as the scan list */ for (Index = 0; Index < num20MHzChannelsFound; Index++) - mac->scan.base_channels.channelList[Index] = - mac->scan.defaultPowerTable[Index].chan_num; + mac->scan.base_channels.channel_freq_list[Index] = + mac->scan.defaultPowerTable[Index].center_freq; mac->scan.base_channels.numChannels = num20MHzChannelsFound; } @@ -2946,8 +3406,8 @@ static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11din ps11dinfo->Channels.numChannels)) { mac->scan.base_channels.numChannels = ps11dinfo->Channels.numChannels; - qdf_mem_copy(mac->scan.base_channels.channelList, - ps11dinfo->Channels.channelList, + qdf_mem_copy(mac->scan.base_channels.channel_freq_list, + ps11dinfo->Channels.channel_freq_list, ps11dinfo->Channels.numChannels); } else { /* No change */ @@ -2974,8 +3434,7 @@ static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11din pChanInfoStart = pChanInfo; for (index = 0; index < ps11dinfo->Channels.numChannels; index++) { - pChanInfo->firstChanNum = - ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq; pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; pChanInfo->maxTxPower = @@ -3037,8 +3496,7 @@ QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, for (index = 0; index < ps11dinfo->Channels.numChannels; index++) { - pChanInfo->firstChanNum = - ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq; pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; pChanInfo->maxTxPower = @@ -3064,7 +3522,7 @@ QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, * list * * @mac_ctx: pointer to global mac - * @session_id: session id for the cmd + * @vdev_id: vdev_id for the cmd * @list: pending list from which cmd needs to be removed * @command: cmd to be removed, can be NULL * @roam_reason: cmd with reason to be removed @@ -3075,7 +3533,7 @@ QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, */ static void csr_roam_remove_duplicate_pending_cmd_from_list( struct mac_context *mac_ctx, - uint32_t session_id, + uint32_t vdev_id, tSmeCmd *command, enum csr_roam_reason roam_reason) { tListElem *entry, *next_entry; @@ -3100,7 +3558,7 @@ static void csr_roam_remove_duplicate_pending_cmd_from_list( * eCsrHddIssued (connect) remove all connect (non disconenct) * commands. */ - if ((command && (command->sessionId == dup_cmd->sessionId) && + if ((command && (command->vdev_id == dup_cmd->vdev_id) && ((command->command == dup_cmd->command) && /* * This peermac check is required for Softap/GO @@ -3118,7 +3576,7 @@ static void csr_roam_remove_duplicate_pending_cmd_from_list( (eCsrHddIssued == command->u.roamCmd.roamReason)))) || /* OR if pCommand is NULL */ - ((session_id == dup_cmd->sessionId) && + ((vdev_id == dup_cmd->vdev_id) && (eSmeCommandRoam == dup_cmd->command) && ((eCsrForcedDisassoc == roam_reason) || (eCsrHddIssued == roam_reason && @@ -3135,7 +3593,7 @@ static void csr_roam_remove_duplicate_pending_cmd_from_list( while ((entry = csr_ll_remove_head(&local_list, LL_ACCESS_NOLOCK))) { dup_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); /* Tell caller that the command is cancelled */ - csr_roam_call_callback(mac_ctx, dup_cmd->sessionId, NULL, + csr_roam_call_callback(mac_ctx, dup_cmd->vdev_id, NULL, dup_cmd->u.roamCmd.roamId, eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE); csr_release_command(mac_ctx, dup_cmd); @@ -3182,8 +3640,8 @@ static void csr_roam_populate_channels(tDot11fBeaconIEs *beacon_ies, ePhyChanBondState phy_state; if (beacon_ies->VHTOperation.present) { - *chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1; - *chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2; + *chan1 = beacon_ies->VHTOperation.chan_center_freq_seg0; + *chan2 = beacon_ies->VHTOperation.chan_center_freq_seg1; roam_info->chan_info.info = MODE_11AC_VHT80; } else if (beacon_ies->HTInfo.present) { if (beacon_ies->HTInfo.recommendedTxWidthSet == @@ -3297,15 +3755,102 @@ static const char *csr_get_encr_type_str(uint8_t encr_type) } } -static void csr_dump_connection_stats(struct mac_context *mac_ctx, - struct csr_roam_session *session, - struct csr_roam_info *roam_info, - eRoamCmdStatus u1, eCsrRoamResult u2) +static const uint8_t *csr_get_akm_str(uint8_t akm) { - struct tagCsrRoamConnectedProfile *conn_profile; - struct csr_roam_profile *profile; - WLAN_HOST_DIAG_EVENT_DEF(conn_stats, - struct host_event_wlan_connection_stats); + switch (akm) { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + return "Open"; + case eCSR_AUTH_TYPE_SHARED_KEY: + return "Shared Key"; + case eCSR_AUTH_TYPE_SAE: + return "SAE"; + case eCSR_AUTH_TYPE_WPA: + return "WPA"; + case eCSR_AUTH_TYPE_WPA_PSK: + return "WPA-PSK"; + case eCSR_AUTH_TYPE_WPA_NONE: + return "WPA-NONE"; + case eCSR_AUTH_TYPE_RSN: + return "EAP 802.1x"; + case eCSR_AUTH_TYPE_RSN_PSK: + return "WPA2-PSK"; + case eCSR_AUTH_TYPE_FT_RSN: + return "FT-802.1x"; + case eCSR_AUTH_TYPE_FT_RSN_PSK: + return "FT-PSK"; + case eCSR_AUTH_TYPE_CCKM_WPA: + return "WPA-CCKM"; + case eCSR_AUTH_TYPE_CCKM_RSN: + return "RSN-CCKM"; + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + return "PSK-SHA256"; + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: + return "EAP 802.1x-SHA256"; + case eCSR_AUTH_TYPE_FILS_SHA256: + return "FILS-SHA256"; + case eCSR_AUTH_TYPE_FILS_SHA384: + return "FILS-SHA384"; + case eCSR_AUTH_TYPE_FT_FILS_SHA256: + return "FILS-SHA256"; + case eCSR_AUTH_TYPE_FT_FILS_SHA384: + return "FILS-SHA384"; + case eCSR_AUTH_TYPE_DPP_RSN: + return "DPP"; + case eCSR_AUTH_TYPE_OWE: + return "OWE"; + case eCSR_AUTH_TYPE_SUITEB_EAP_SHA256: + return "EAP Suite-B SHA256"; + case eCSR_AUTH_TYPE_SUITEB_EAP_SHA384: + return "EAP Suite-B SHA384"; + case eCSR_AUTH_TYPE_OSEN: + return "OSEN"; + case eCSR_AUTH_TYPE_FT_SAE: + return "FT-SAE"; + case eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384: + return "FT-Suite-B SHA384"; + default: + return "NONE"; + } +} + +/** + * csr_get_sta_ap_intersected_nss - Get the intersected NSS capability between + * sta and connected AP. + * @mac_ctx: Pointer to mac context + * @vdev_id: Vdev id + * + * Return: NSS value + */ +static uint8_t +csr_get_sta_ap_intersected_nss(struct mac_context *mac_ctx, uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + uint8_t intrsct_nss; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, + WLAN_LEGACY_MAC_ID); + if (!vdev) { + pe_warn("vdev not found for id: %d", vdev_id); + return 0; + } + wlan_vdev_obj_lock(vdev); + intrsct_nss = wlan_vdev_mlme_get_nss(vdev); + wlan_vdev_obj_unlock(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + return intrsct_nss; +} + +static void +csr_connect_info(struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct csr_roam_info *roam_info, + eCsrRoamResult u2) +{ + struct tagCsrRoamConnectedProfile *conn_profile; + struct csr_roam_profile *profile; + WLAN_HOST_DIAG_EVENT_DEF(conn_stats, + struct host_event_wlan_connection_stats); if (!session || !session->pCurRoamProfile || !roam_info) return; @@ -3334,7 +3879,11 @@ static void csr_dump_connection_stats(struct mac_context *mac_ctx, diag_dot11_mode_from_csr_type(conn_profile->dot11Mode); conn_stats.bss_type = diag_persona_from_csr_type(session->pCurRoamProfile->csrPersona); - conn_stats.operating_channel = conn_profile->operationChannel; + if (conn_profile->op_freq) + conn_stats.operating_channel = + wlan_reg_freq_to_chan(mac_ctx->pdev, + conn_profile->op_freq); + conn_stats.qos_capability = conn_profile->qosConnection; conn_stats.auth_type = diag_auth_type_from_csr_type(conn_profile->AuthType); @@ -3342,19 +3891,21 @@ static void csr_dump_connection_stats(struct mac_context *mac_ctx, diag_enc_type_from_csr_type(conn_profile->EncryptionType); conn_stats.result_code = (u2 == eCSR_ROAM_RESULT_ASSOCIATED) ? 1 : 0; conn_stats.reason_code = 0; + conn_stats.op_freq = conn_profile->op_freq; sme_nofl_debug("+---------CONNECTION INFO START------------+"); - sme_nofl_debug("VDEV-ID: %d self_mac:%pM", session->sessionId, - session->self_mac_addr.bytes); - sme_nofl_debug("ssid: %.*s bssid: %pM RSSI: %d dBm", + sme_nofl_debug("VDEV-ID: %d self_mac:"QDF_MAC_ADDR_FMT, session->vdev_id, + QDF_MAC_ADDR_REF(session->self_mac_addr.bytes)); + sme_nofl_debug("ssid: %.*s bssid: "QDF_MAC_ADDR_FMT" RSSI: %d dBm", conn_stats.ssid_len, conn_stats.ssid, - conn_stats.bssid, conn_stats.rssi); - sme_nofl_debug("Channel : %d channel_bw: %s dot11Mode: %s", - conn_stats.operating_channel, + QDF_MAC_ADDR_REF(conn_stats.bssid), conn_stats.rssi); + sme_nofl_debug("Channel Freq: %d channel_bw: %s dot11Mode: %s", conn_stats.op_freq, csr_get_ch_width_str(conn_stats.chnl_bw), csr_get_dot11_mode_str(conn_stats.dot11mode)); sme_nofl_debug("AKM: %s Encry-type: %s", - csr_get_auth_type_str(conn_profile->AuthType), + csr_get_akm_str(conn_profile->AuthType), csr_get_encr_type_str(conn_stats.encryption_type)); + sme_nofl_debug("DUT_NSS: %d | Intersected NSS:%d", session->vdev_nss, + csr_get_sta_ap_intersected_nss(mac_ctx, session->vdev_id)); sme_nofl_debug("Qos enable: %d | Associated: %s", conn_stats.qos_capability, (conn_stats.result_code ? "yes" : "no")); @@ -3381,11 +3932,12 @@ void csr_get_sta_cxn_info(struct mac_context *mac_ctx, if (!session || !session->pCurRoamProfile || !conn_profile) return; - if (!conn_profile->operationChannel) + if (!conn_profile->op_freq) return; qdf_mem_set(buf, buf_sz, '\0'); len += qdf_scnprintf(buf + len, buf_sz - len, - "\n\tbssid: %pM", conn_profile->bssid.bytes); + "\n\tbssid: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(conn_profile->bssid.bytes)); len += qdf_scnprintf(buf + len, buf_sz - len, "\n\tssid: %.*s", conn_profile->SSID.length, conn_profile->SSID.ssId); @@ -3406,7 +3958,7 @@ void csr_get_sta_cxn_info(struct mac_context *mac_ctx, len += qdf_scnprintf(buf + len, buf_sz - len, "\n\tbss_type: %s", csr_get_persona(type)); len += qdf_scnprintf(buf + len, buf_sz - len, - "\n\tchnl: %d", conn_profile->operationChannel); + "\n\tch_freq: %d", conn_profile->op_freq); len += qdf_scnprintf(buf + len, buf_sz - len, "\n\tQoS: %d", conn_profile->qosConnection); authtype = diag_auth_type_from_csr_type(conn_profile->AuthType); @@ -3439,10 +3991,10 @@ void csr_get_sta_cxn_info(struct mac_context *mac_ctx, ((hw_mode != 0) ? "yes" : "no")); } #else -static void csr_dump_connection_stats(struct mac_context *mac_ctx, - struct csr_roam_session *session, - struct csr_roam_info *roam_info, - eRoamCmdStatus u1, eCsrRoamResult u2) +static void csr_connect_info(struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct csr_roam_info *roam_info, + eCsrRoamResult u2) {} #endif @@ -3452,7 +4004,7 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, uint32_t roamId, eRoamCmdStatus u1, eCsrRoamResult u2) { - QDF_STATUS ret, status = QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_SUCCESS; #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR WLAN_HOST_DIAG_EVENT_DEF(connectionStatus, @@ -3461,6 +4013,7 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, struct csr_roam_session *pSession; tDot11fBeaconIEs *beacon_ies = NULL; uint8_t chan1, chan2; + uint32_t chan_freq; if (!CSR_IS_SESSION_VALID(mac, sessionId)) { sme_err("Session ID: %d is not valid", sessionId); @@ -3500,16 +4053,12 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, roam_info->chan_info.band_center_freq2 = 0; roam_info->chan_info.info = 0; } - roam_info->chan_info.chan_id = - roam_info->u.pConnectedProfile->operationChannel; - roam_info->chan_info.mhz = - cds_chan_to_freq(roam_info->chan_info.chan_id); + roam_info->chan_info.mhz = roam_info->u.pConnectedProfile->op_freq; + chan_freq = roam_info->chan_info.mhz; roam_info->chan_info.reg_info_1 = - (csr_get_cfg_max_tx_power(mac, - roam_info->chan_info.chan_id) << 16); + (csr_get_cfg_max_tx_power(mac, chan_freq) << 16); roam_info->chan_info.reg_info_2 = - (csr_get_cfg_max_tx_power(mac, - roam_info->chan_info.chan_id) << 8); + (csr_get_cfg_max_tx_power(mac, chan_freq) << 8); qdf_mem_free(beacon_ies); } else if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED) && (pSession->bRefAssocStartCnt)) { @@ -3526,25 +4075,18 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, pSession->bRefAssocStartCnt--; } else if (roam_info && (u1 == eCSR_ROAM_SET_CHANNEL_RSP) && (u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS)) { - pSession->connectedProfile.operationChannel = - roam_info->channelChangeRespEvent->newChannelNumber; - } else if (u1 == eCSR_ROAM_SESSION_OPENED) { - ret = (u2 == eCSR_ROAM_RESULT_SUCCESS) ? - QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; - - if (pSession->session_open_cb) - pSession->session_open_cb(sessionId, ret); - else - sme_err("session_open_cb is not registered"); + pSession->connectedProfile.op_freq = + roam_info->channelChangeRespEvent->new_op_freq; } + if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1) - csr_dump_connection_stats(mac, pSession, roam_info, u1, u2); + csr_connect_info(mac, pSession, roam_info, u2); - if (pSession->callback) { + if (mac->session_roam_complete_cb) { if (roam_info) roam_info->sessionId = (uint8_t) sessionId; - status = pSession->callback(pSession->pContext, roam_info, - roamId, u1, u2); + status = mac->session_roam_complete_cb(mac->psoc, sessionId, roam_info, + roamId, u1, u2); } /* * EVENT_WLAN_STATUS_V2: eCSR_ROAM_ASSOCIATION_COMPLETION, @@ -3565,7 +4107,9 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, connectionStatus.rssi = roam_info->bss_desc->rssi * (-1); connectionStatus.channel = - roam_info->bss_desc->channelId; + wlan_reg_freq_to_chan( + mac->pdev, + roam_info->bss_desc->chan_freq); } mac->mlme_cfg->sta.current_rssi = connectionStatus.rssi; @@ -3636,81 +4180,6 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, return status; } -/* Returns whether handoff is currently in progress or not */ -static -bool csr_roam_is_handoff_in_progress(struct mac_context *mac, uint8_t sessionId) -{ - return csr_neighbor_roam_is_handoff_in_progress(mac, sessionId); -} - -static -QDF_STATUS csr_roam_issue_disassociate(struct mac_context *mac, uint32_t sessionId, - enum csr_roam_substate NewSubstate, - bool fMICFailure) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct qdf_mac_addr bssId = QDF_MAC_ADDR_BCAST_INIT; - uint16_t reasonCode; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("session %d not found", sessionId); - return QDF_STATUS_E_FAILURE; - } - - if (fMICFailure) { - reasonCode = eSIR_MAC_MIC_FAILURE_REASON; - } else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) { - reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON; - } else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) { - reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON; - NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED; - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON and set back NewSubstate"); - } else { - reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; - } - if ((csr_roam_is_handoff_in_progress(mac, sessionId)) && - (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) { - tpCsrNeighborRoamControlInfo pNeighborRoamInfo = - &mac->roam.neighborRoamInfo[sessionId]; - qdf_copy_macaddr(&bssId, - pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs. - bssid); - } else if (pSession->pConnectBssDesc) { - qdf_mem_copy(&bssId.bytes, pSession->pConnectBssDesc->bssId, - sizeof(struct qdf_mac_addr)); - } - - sme_debug("Disassociate Bssid " QDF_MAC_ADDR_STR " subState: %s reason: %d", - QDF_MAC_ADDR_ARRAY(bssId.bytes), - mac_trace_getcsr_roam_sub_state(NewSubstate), reasonCode); - - csr_roam_substate_change(mac, NewSubstate, sessionId); - - status = csr_send_mb_disassoc_req_msg(mac, sessionId, bssId.bytes, - reasonCode); - - if (QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_link_down(mac, sessionId); -#ifndef WLAN_MDM_CODE_REDUCTION_OPT - /* no need to tell QoS that we are disassociating, it will be - * taken care off in assoc req for HO - */ - if (eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) { - /* notify QoS module that disassoc happening */ - sme_qos_csr_event_ind(mac, (uint8_t) sessionId, - SME_QOS_CSR_DISCONNECT_REQ, NULL); - } -#endif - } else { - sme_warn("csr_send_mb_disassoc_req_msg failed status: %d", - status); - } - - return status; -} - static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd, struct qdf_mac_addr peer_macaddr) { @@ -3752,7 +4221,7 @@ csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx, entry = csr_nonscan_pending_ll_peek_head(mac_ctx, LL_ACCESS_NOLOCK); while (entry) { sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if ((sme_cmd->sessionId == vdev_id) && + if ((sme_cmd->vdev_id == vdev_id) && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr)) return true; entry = csr_nonscan_pending_ll_next(mac_ctx, entry, @@ -3821,12 +4290,32 @@ csr_is_deauth_disassoc_already_active(struct mac_context *mac_ctx, peer_macaddr); if (ret) - sme_debug("Deauth/Disassoc already in progress for %pM", - peer_macaddr.bytes); + sme_debug("Deauth/Disassoc already in progress for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_macaddr.bytes)); return ret; } +static void csr_roam_issue_disconnect_stats(struct mac_context *mac, + uint32_t session_id, + struct qdf_mac_addr peer_mac) +{ + tSmeCmd *cmd; + + cmd = csr_get_command_buffer(mac); + if (!cmd) { + sme_err(" fail to get command buffer"); + return; + } + + cmd->command = eSmeCommandGetdisconnectStats; + cmd->vdev_id = session_id; + qdf_mem_copy(&cmd->u.disconnect_stats_cmd.peer_mac_addr, &peer_mac, + QDF_MAC_ADDR_SIZE); + if (QDF_IS_STATUS_ERROR(csr_queue_sme_command(mac, cmd, true))) + sme_err("fail to queue get disconnect stats"); +} + /** * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station * @sessionId: Session Id for Soft AP @@ -3856,13 +4345,18 @@ QDF_STATUS csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac, break; } pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta; qdf_mem_copy(pCommand->u.roamCmd.peerMac, p_del_sta_params->peerMacAddr.bytes, sizeof(pCommand->u.roamCmd.peerMac)); pCommand->u.roamCmd.reason = (tSirMacReasonCodes)p_del_sta_params->reason_code; + + csr_roam_issue_disconnect_stats( + mac, sessionId, + p_del_sta_params->peerMacAddr); + status = csr_queue_sme_command(mac, pCommand, true); if (!QDF_IS_STATUS_SUCCESS(status)) sme_err("fail to send message status: %d", status); @@ -3898,13 +4392,17 @@ QDF_STATUS csr_roam_issue_deauth_sta_cmd(struct mac_context *mac, break; } pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta; qdf_mem_copy(pCommand->u.roamCmd.peerMac, pDelStaParams->peerMacAddr.bytes, sizeof(tSirMacAddr)); pCommand->u.roamCmd.reason = (tSirMacReasonCodes)pDelStaParams->reason_code; + + csr_roam_issue_disconnect_stats(mac, sessionId, + pDelStaParams->peerMacAddr); + status = csr_queue_sme_command(mac, pCommand, true); if (!QDF_IS_STATUS_SUCCESS(status)) sme_err("fail to send message status: %d", status); @@ -3930,8 +4428,8 @@ QDF_STATUS csr_roam_issue_deauth(struct mac_context *mac, uint32_t sessionId, qdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId, sizeof(struct qdf_mac_addr)); } - sme_debug("Deauth to Bssid " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(bssId.bytes)); + sme_debug("Deauth to Bssid " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssId.bytes)); csr_roam_substate_change(mac, NewSubstate, sessionId); status = @@ -3941,8 +4439,8 @@ QDF_STATUS csr_roam_issue_deauth(struct mac_context *mac, uint32_t sessionId, csr_roam_link_down(mac, sessionId); else { sme_err("csr_send_mb_deauth_req_msg failed with status %d Session ID: %d" - QDF_MAC_ADDR_STR, status, sessionId, - QDF_MAC_ADDR_ARRAY(bssId.bytes)); + QDF_MAC_ADDR_FMT, status, sessionId, + QDF_MAC_ADDR_REF(bssId.bytes)); } return status; @@ -4021,10 +4519,16 @@ QDF_STATUS csr_roam_prepare_bss_config(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } } - if (WLAN_REG_IS_5GHZ_CH(bss_desc->channelId)) - pBssConfig->band = BAND_5G; + + if (WLAN_REG_IS_5GHZ_CH_FREQ(bss_desc->chan_freq)) + pBssConfig->band = REG_BAND_5G; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(bss_desc->chan_freq)) + pBssConfig->band = REG_BAND_2G; + else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(bss_desc->chan_freq)) + pBssConfig->band = REG_BAND_6G; else - pBssConfig->band = BAND_2G; + return QDF_STATUS_E_FAILURE; + /* phymode */ if (csr_is_phy_mode_match(mac, pProfile->phyMode, bss_desc, pProfile, &cfgDot11Mode, pIes)) { @@ -4035,7 +4539,7 @@ QDF_STATUS csr_roam_prepare_bss_config(struct mac_context *mac, * 2.4Ghz and to 11a mode for 5Ghz */ sme_warn("Can not find match phy mode"); - if (BAND_2G == pBssConfig->band) { + if (REG_BAND_2G == pBssConfig->band) { if (mac->roam.configParam.phyMode & (eCSR_DOT11_MODE_11b | eCSR_DOT11_MODE_11b_ONLY)) { pBssConfig->uCfgDot11Mode = @@ -4044,8 +4548,11 @@ QDF_STATUS csr_roam_prepare_bss_config(struct mac_context *mac, pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; } - } else { + } else if (pBssConfig->band == REG_BAND_5G) { pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } else if (pBssConfig->band == REG_BAND_6G) { + pBssConfig->uCfgDot11Mode = + eCSR_CFG_DOT11_MODE_11AX_ONLY; } } @@ -4136,12 +4643,12 @@ QDF_STATUS csr_roam_prepare_bss_config(struct mac_context *mac, (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC_ONLY) || (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) || (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX_ONLY)) - pBssConfig->cbMode = csr_get_cb_mode_from_ies(mac, - bss_desc->channelId, pIes); + pBssConfig->cbMode = csr_get_cb_mode_from_ies( + mac, bss_desc->chan_freq, pIes); else pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED; - if (WLAN_REG_IS_24GHZ_CH(bss_desc->channelId) && + if (WLAN_REG_IS_24GHZ_CH_FREQ(bss_desc->chan_freq) && pProfile->force_24ghz_in_ht20) { pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED; sme_debug("force_24ghz_in_ht20 is set so set cbmode to 0"); @@ -4156,7 +4663,7 @@ QDF_STATUS csr_roam_prepare_bss_config_from_profile( struct bss_description *bss_desc) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t operationChannel = 0; + uint32_t bss_op_ch_freq = 0; uint8_t qAPisEnabled = false; /* SSID */ pBssConfig->SSID.length = 0; @@ -4179,13 +4686,15 @@ QDF_STATUS csr_roam_prepare_bss_config_from_profile( pProfile->EncryptionType.encryptionType[0]) pBssConfig->BssCap.privacy = 1; - pBssConfig->band = mac->mlme_cfg->gen.band; + /* Update when 6G support is added for IBSS / NDI */ + pBssConfig->band = (mac->mlme_cfg->gen.band == BAND_2G ? + REG_BAND_2G : REG_BAND_5G); /* phymode */ - if (pProfile->ChannelInfo.ChannelList) - operationChannel = pProfile->ChannelInfo.ChannelList[0]; - pBssConfig->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(mac, - pProfile, operationChannel, - &pBssConfig->band); + if (pProfile->ChannelInfo.freq_list) + bss_op_ch_freq = pProfile->ChannelInfo.freq_list[0]; + pBssConfig->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss( + mac, pProfile, bss_op_ch_freq, + &pBssConfig->band); /* QOS */ /* Is this correct to always set to this // *** */ if (pBssConfig->BssCap.ess == 1) { @@ -4245,7 +4754,8 @@ QDF_STATUS csr_roam_prepare_bss_config_from_profile( pBssConfig->f11hSupport = false; pBssConfig->uPowerLimit = 0; /* heartbeat */ - if (BAND_5G == pBssConfig->band) { + if (REG_BAND_5G == pBssConfig->band || + REG_BAND_6G == pBssConfig->band) { pBssConfig->uHeartBeatThresh = mac->roam.configParam.HeartbeatThresh50; } else { @@ -4727,7 +5237,7 @@ static void csr_set_cfg_rate_set_from_profile(struct mac_context *mac, SIR_MAC_RATE_5_5, SIR_MAC_RATE_11} } }; enum csr_cfgdot11mode cfgDot11Mode; - enum band_info band; + enum reg_wifi_band band; /* leave enough room for the max number of rates */ uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX]; qdf_size_t OperationalRatesLength = 0; @@ -4735,20 +5245,20 @@ static void csr_set_cfg_rate_set_from_profile(struct mac_context *mac, uint8_t ExtendedOperationalRates [CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; qdf_size_t ExtendedOperationalRatesLength = 0; - uint8_t operationChannel = 0; + uint32_t bss_op_ch_freq = 0; - if (pProfile->ChannelInfo.ChannelList) - operationChannel = pProfile->ChannelInfo.ChannelList[0]; + if (pProfile->ChannelInfo.freq_list) + bss_op_ch_freq = pProfile->ChannelInfo.freq_list[0]; cfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(mac, pProfile, - operationChannel, - &band); + bss_op_ch_freq, + &band); /* For 11a networks, the 11a rates go into the Operational Rate set. * For 11b and 11g networks, the 11b rates appear in the Operational * Rate set. In either case, we can blindly put the rates we support * into our Operational Rate set (including the basic rates, which we * have already verified are supported earlier in the roaming decision). */ - if (BAND_5G == band) { + if (REG_BAND_5G == band) { /* 11a rates into the Operational Rate Set. */ OperationalRatesLength = DefaultSupportedRates11a.supportedRateSet.numRates * @@ -4813,7 +5323,7 @@ static void csr_roam_ccm_cfg_set_callback(struct mac_context *mac, return; } pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); - sessionId = pCommand->sessionId; + sessionId = pCommand->vdev_id; #ifdef WLAN_FEATURE_ROAM_OFFLOAD pSession = &mac->roam.roamSession[sessionId]; if (pSession->roam_synch_in_progress) { @@ -4838,8 +5348,9 @@ QDF_STATUS csr_roam_set_bss_config_cfg(struct mac_context *mac, uint32_t session bool resetCountry) { uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; - uint8_t channel = 0; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); + uint32_t chan_freq = 0; + if (!pSession) { sme_err("session %d not found", sessionId); return QDF_STATUS_E_FAILURE; @@ -4873,22 +5384,17 @@ QDF_STATUS csr_roam_set_bss_config_cfg(struct mac_context *mac, uint32_t session /* short slot time */ mac->mlme_cfg->feature_flags.enable_short_slot_time_11g = pBssConfig->uShortSlotTime; - /* 11d */ - if (pBssConfig->f11hSupport) - mac->mlme_cfg->gen.enabled_11d = pBssConfig->f11hSupport; - else - mac->mlme_cfg->gen.enabled_11d = pProfile->ieee80211d; mac->mlme_cfg->power.local_power_constraint = pBssConfig->uPowerLimit; /* CB */ if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_IBSS(pProfile)) - channel = pProfile->operationChannel; + chan_freq = pProfile->op_freq; else if (bss_desc) - channel = bss_desc->channelId; - if (0 != channel) { + chan_freq = bss_desc->chan_freq; + if (0 != chan_freq) { /* for now if we are on 2.4 Ghz, CB will be always disabled */ - if (WLAN_REG_IS_24GHZ_CH(channel)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; else cfgCb = pBssConfig->cbMode; @@ -5322,15 +5828,13 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, enum csr_join_state *roam_state, struct scan_result_list *bss_list) { - uint8_t conc_channel = 0; - uint32_t temp_vdev_id; + uint32_t conc_freq = 0, chan_freq, temp_vdev_id; bool status = false; struct tag_csrscan_result *scan_result = NULL; tCsrScanResultInfo *result = NULL; enum QDF_OPMODE op_mode; struct wlan_objmgr_vdev *vdev; enum policy_mgr_con_mode mode; - uint8_t chan_id; QDF_STATUS qdf_status; eCsrPhyMode self_phymode = mac_ctx->roam.configParam.phyMode; tDot11fBeaconIEs *bcn_ies; @@ -5387,8 +5891,9 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, (struct qdf_mac_addr *) &result->BssDescriptor.bssId, &temp_vdev_id); if (QDF_IS_STATUS_SUCCESS(qdf_status)) { - sme_info("vdev_id %d already connected to %pM. select next bss for vdev_id %d", - temp_vdev_id, result->BssDescriptor.bssId, + sme_info("vdev_id %d already connected to "QDF_MAC_ADDR_FMT". select next bss for vdev_id %d", + temp_vdev_id, + QDF_MAC_ADDR_REF(result->BssDescriptor.bssId), vdev_id); *roam_state = eCsrStopRoamingDueToConcurrency; status = true; @@ -5398,15 +5903,16 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, continue; } - chan_id = result->BssDescriptor.channelId; + chan_freq = result->BssDescriptor.chan_freq; mode = policy_mgr_convert_device_mode_to_qdf_type(op_mode); /* If concurrency is not allowed select next bss */ if (!policy_mgr_is_concurrency_allowed(mac_ctx->psoc, mode, - chan_id, + chan_freq, HW_MODE_20_MHZ)) { - sme_err("Concurrency not allowed for this channel %d bssid %pM, selecting next", - chan_id, result->BssDescriptor.bssId); + sme_err("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next", + chan_freq, + QDF_MAC_ADDR_REF(result->BssDescriptor.bssId)); *roam_state = eCsrStopRoamingDueToConcurrency; status = true; *roam_bss_entry = csr_ll_next(&bss_list->List, @@ -5419,11 +5925,11 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, * check if channel is allowed for current hw mode, if not fetch * next BSS. */ - if (!policy_mgr_is_hwmode_set_for_given_chnl(mac_ctx->psoc, - result->BssDescriptor.channelId)) { - sme_err("HW mode is not properly set for channel %d BSSID %pM", - result->BssDescriptor.channelId, - result->BssDescriptor.bssId); + if (!policy_mgr_is_hwmode_set_for_given_chnl( + mac_ctx->psoc, result->BssDescriptor.chan_freq)) { + sme_err("HW mode isn't properly set, freq %d BSSID "QDF_MAC_ADDR_FMT, + result->BssDescriptor.chan_freq, + QDF_MAC_ADDR_REF(result->BssDescriptor.bssId)); *roam_state = eCsrStopRoamingDueToConcurrency; status = true; *roam_bss_entry = csr_ll_next(&bss_list->List, @@ -5434,33 +5940,32 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx, if (policy_mgr_concurrent_open_sessions_running(mac_ctx->psoc) && !csr_is_valid_mc_concurrent_session(mac_ctx, vdev_id, &result->BssDescriptor)) { - conc_channel = csr_get_concurrent_operation_channel( + conc_freq = csr_get_concurrent_operation_freq( mac_ctx); - sme_debug("csr Conc Channel: %d", conc_channel); - - if (conc_channel) { - if ((conc_channel == - result->BssDescriptor.channelId) || - (policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) - && !WLAN_REG_IS_SAME_BAND_CHANNELS( - conc_channel, - result->BssDescriptor.channelId))) { + sme_debug("csr Conc Channel freq: %d", conc_freq); + + if (conc_freq) { + if ((conc_freq == chan_freq) || + (policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) + && !WLAN_REG_IS_SAME_BAND_FREQS( + conc_freq, chan_freq))) { /* * make this 0 because we do not want the below * check to pass as we don't want to connect on * other channel */ - sme_debug("Conc chnl match: %d", - conc_channel); - conc_channel = 0; + sme_debug("Conc chnl freq match: %d", + conc_freq); + conc_freq = 0; } } } /* Ok to roam this */ - if (!conc_channel && - QDF_IS_STATUS_SUCCESS(csr_roam_should_roam(mac_ctx, - vdev_id, &result->BssDescriptor, roam_id))) { + if (!conc_freq && + QDF_IS_STATUS_SUCCESS(csr_roam_should_roam(mac_ctx, + vdev_id, &result->BssDescriptor, + roam_id))) { status = false; break; } @@ -5667,7 +6172,7 @@ static enum csr_join_state csr_roam_join_next_bss(struct mac_context *mac_ctx, (struct scan_result_list *) cmd->u.roamCmd.hBSSList; bool done = false; struct csr_roam_info *roam_info = NULL; - uint32_t session_id = cmd->sessionId; + uint32_t session_id = cmd->vdev_id; struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile; struct csr_roam_joinstatus *join_status; @@ -5768,7 +6273,7 @@ static QDF_STATUS csr_roam(struct mac_context *mac, tSmeCmd *pCommand, QDF_STATUS status = QDF_STATUS_SUCCESS; enum csr_join_state RoamState; enum csr_roam_substate substate; - uint32_t sessionId = pCommand->sessionId; + uint32_t sessionId = pCommand->vdev_id; /* Attept to join a Bss... */ RoamState = csr_roam_join_next_bss(mac, pCommand, use_same_bss); @@ -5853,7 +6358,7 @@ QDF_STATUS csr_process_ft_reassoc_roam_command(struct mac_context *mac, struct bss_description *bss_desc = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; - sessionId = pCommand->sessionId; + sessionId = pCommand->vdev_id; pSession = CSR_GET_SESSION(mac, sessionId); if (!pSession) { @@ -5995,20 +6500,27 @@ static void csr_get_peer_rssi_cb(struct stats_event *ev, void *cookie) { struct mac_context *mac = (struct mac_context *)cookie; - if (!mac) + if (!mac) { + sme_err("Invalid mac ctx"); return; + } + if (!ev->peer_stats) { sme_debug("%s no peer stats\n", __func__); - return; + goto disconnect_stats_complete; } + mac->peer_rssi = ev->peer_stats->peer_rssi; mac->peer_txrate = ev->peer_stats->tx_rate; mac->peer_rxrate = ev->peer_stats->rx_rate; if (!ev->peer_extended_stats) { sme_debug("%s no peer extended stats\n", __func__); - return; + goto disconnect_stats_complete; } mac->rx_mc_bc_cnt = ev->peer_extended_stats->rx_mc_bc_cnt; + +disconnect_stats_complete: + csr_roam_get_disconnect_stats_complete(mac); } static void csr_get_peer_rssi(struct mac_context *mac, uint32_t session_id, @@ -6033,10 +6545,12 @@ static void csr_get_peer_rssi(struct mac_context *mac, uint32_t session_id, vdev, TYPE_PEER_STATS, &info); - sme_debug("peer_mac" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(peer_mac.bytes)); + sme_debug("peer_mac" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac.bytes)); if (QDF_IS_STATUS_ERROR(status)) sme_err("stats req failed: %d", status); + + wma_get_rx_retry_cnt(mac, session_id, info.peer_mac_addr); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); } } @@ -6044,9 +6558,8 @@ static void csr_get_peer_rssi(struct mac_context *mac, uint32_t session_id, QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) { QDF_STATUS lock_status, status = QDF_STATUS_SUCCESS; - uint32_t sessionId = pCommand->sessionId; + uint32_t sessionId = pCommand->vdev_id; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - struct qdf_mac_addr peer_mac; if (!pSession) { sme_err("session %d not found", sessionId); @@ -6135,10 +6648,6 @@ QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) sme_debug("Disassociate issued with reason: %d", pCommand->u.roamCmd.reason); - qdf_mem_copy(&peer_mac, &pCommand->u.roamCmd.peerMac, - QDF_MAC_ADDR_SIZE); - csr_get_peer_rssi(mac, sessionId, peer_mac); - status = csr_send_mb_disassoc_req_msg(mac, sessionId, pCommand->u.roamCmd.peerMac, pCommand->u.roamCmd.reason); @@ -6152,10 +6661,6 @@ QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) sme_debug("Deauth issued with reason: %d", pCommand->u.roamCmd.reason); - qdf_mem_copy(&peer_mac, &pCommand->u.roamCmd.peerMac, - QDF_MAC_ADDR_SIZE); - csr_get_peer_rssi(mac, sessionId, peer_mac); - status = csr_send_mb_deauth_req_msg(mac, sessionId, pCommand->u.roamCmd.peerMac, pCommand->u.roamCmd.reason); @@ -6307,8 +6812,6 @@ static QDF_STATUS csr_roam_save_params(struct mac_context *mac_ctx, (eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type) || (eCSR_AUTH_TYPE_FT_SAE == auth_type) || (eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384 == auth_type) || - (eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 == auth_type) || - (eCSR_AUTH_TYPE_SUITEB_EAP_SHA384 == auth_type) || #if defined WLAN_FEATURE_11W (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == auth_type) || (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == auth_type) || @@ -6492,8 +6995,6 @@ csr_roam_save_security_rsp_ie(struct mac_context *mac, (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) || (eCSR_AUTH_TYPE_FT_SAE == authType) || (eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384 == authType) - || (eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 == authType) - || (eCSR_AUTH_TYPE_SUITEB_EAP_SHA384 == authType) #ifdef FEATURE_WLAN_WAPI || (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) || (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType) @@ -6567,14 +7068,14 @@ void csr_update_scan_entry_associnfo(struct mac_context *mac_ctx, } qdf_copy_macaddr(&bss.bssid, &conn_profile->bssid); - bss.chan = conn_profile->operationChannel; + bss.freq = conn_profile->op_freq; bss.ssid.length = conn_profile->SSID.length; qdf_mem_copy(&bss.ssid.ssid, &conn_profile->SSID.ssId, bss.ssid.length); - sme_debug("Update MLME info in scan database. bssid %pM ssid:%.*s chan %d state: %d", - bss.bssid.bytes, bss.ssid.length, bss.ssid.ssid, bss.chan, - state); + sme_debug("Update MLME info in scan database. bssid "QDF_MAC_ADDR_FMT" ssid:%.*s freq %d state: %d", + QDF_MAC_ADDR_REF(bss.bssid.bytes), bss.ssid.length, + bss.ssid.ssid, bss.freq, state); mlme.assoc_state = state; status = ucfg_scan_update_mlme_by_bssinfo(mac_ctx->pdev, &bss, &mlme); if (QDF_IS_STATUS_ERROR(status)) @@ -6722,7 +7223,7 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, tSmeCmd *cmd, void *context, enum csr_roamcomplete_result res) { - uint32_t session_id = cmd->sessionId; + uint32_t session_id = cmd->vdev_id; struct csr_roam_session *session; struct csr_roam_info *roam_info; QDF_STATUS status; @@ -6906,6 +7407,7 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, roam_info->tx_rate = mac_ctx->peer_txrate; roam_info->rx_rate = mac_ctx->peer_rxrate; roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; + roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt; csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, session_id); @@ -6947,7 +7449,7 @@ static void csr_roam_process_results_default(struct mac_context *mac_ctx, static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx, tSmeCmd *cmd, void *context) { - uint32_t session_id = cmd->sessionId; + uint32_t session_id = cmd->vdev_id; struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile; struct csr_roam_session *session; struct bss_description *bss_desc = NULL; @@ -7052,8 +7554,10 @@ static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx, if (bss_desc) { qdf_mem_copy(ibss_log->bssid.bytes, bss_desc->bssId, QDF_MAC_ADDR_SIZE); + ibss_log->op_freq = bss_desc->chan_freq; ibss_log->operatingChannel = - bss_desc->channelId; + wlan_reg_freq_to_chan(mac_ctx->pdev, + ibss_log->op_freq); } bi = mac_ctx->mlme_cfg->sap_cfg.beacon_interval; /* U8 is not enough for BI */ @@ -7079,11 +7583,11 @@ static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx, */ if (!CSR_IS_IBSS(session->pCurRoamProfile)) { /* NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req_helper(mac_ctx, - session_id, - profile->negotiatedMCEncryptionType, - bss_desc, &bcast_mac, false, - false, eSIR_TX_RX, 0, 0, NULL, 0); + csr_issue_set_context_req_helper(mac_ctx, + profile, session_id, + &bcast_mac, false, + false, eSIR_TX_RX, + 0, 0, NULL); } } if (CSR_IS_IBSS(session->pCurRoamProfile) && @@ -7250,7 +7754,6 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx, struct bss_description *bss_desc, struct join_rsp *join_rsp) { - tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; QDF_STATUS status; if (!join_rsp || !join_rsp->fils_join_rsp) { @@ -7265,28 +7768,24 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx, goto process_fils_join_rsp_fail; } - status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id, - profile->negotiatedUCEncryptionType, - bss_desc, &(bss_desc->bssId), true, - true, eSIR_TX_RX, 0, - roam_info->fils_join_rsp->tk_len, - roam_info->fils_join_rsp->tk, 0); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_debug("Set context for unicast fail"); + status = csr_issue_set_context_req_helper(mac_ctx, profile, + session_id, &bss_desc->bssId, true, + true, eSIR_TX_RX, 0, + roam_info->fils_join_rsp->tk_len, + roam_info->fils_join_rsp->tk); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Set context for unicast fail"); goto process_fils_join_rsp_fail; } - status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id, - profile->negotiatedMCEncryptionType, - bss_desc, &bcast_mac, true, false, - eSIR_RX_ONLY, 2, - roam_info->fils_join_rsp->gtk_len, - roam_info->fils_join_rsp->gtk, 0); - if (!QDF_IS_STATUS_SUCCESS(status)) { + status = csr_issue_set_context_req_helper(mac_ctx, profile, + session_id, &bss_desc->bssId, true, false, + eSIR_RX_ONLY, 2, roam_info->fils_join_rsp->gtk_len, + roam_info->fils_join_rsp->gtk); + if (QDF_IS_STATUS_ERROR(status)) { sme_err("Set context for bcast fail"); goto process_fils_join_rsp_fail; } - return; process_fils_join_rsp_fail: @@ -7303,6 +7802,19 @@ static inline void csr_process_fils_join_rsp(struct mac_context *mac_ctx, {} #endif +#ifdef WLAN_FEATURE_11AX +static void csr_roam_process_he_info(struct join_rsp *sme_join_rsp, + struct csr_roam_info *roam_info) +{ + roam_info->he_operation = sme_join_rsp->he_operation; +} +#else +static inline void csr_roam_process_he_info(struct join_rsp *sme_join_rsp, + struct csr_roam_info *roam_info) +{ +} +#endif + static void csr_update_tx_pwr_to_fw(struct mac_context *mac_ctx, uint8_t vdev_id) { @@ -7336,7 +7848,7 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, sme_QosAssocInfo assoc_info; uint32_t key_timeout_interval = 0; uint8_t acm_mask = 0; /* HDD needs ACM mask in assoc rsp callback */ - uint32_t session_id = cmd->sessionId; + uint32_t session_id = cmd->vdev_id; struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile; struct csr_roam_session *session; struct bss_description *bss_desc = NULL; @@ -7352,8 +7864,6 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; struct join_rsp *join_rsp = context; uint32_t len; - enum csr_akm_type akm_type; - uint8_t mdie_present; if (!join_rsp) { sme_err("join_rsp is NULL"); @@ -7475,15 +7985,12 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, * Issue the set Context request to LIM to establish * the Unicast STA context */ - if (!QDF_IS_STATUS_SUCCESS( - csr_roam_issue_set_context_req_helper(mac_ctx, - session_id, - profile->negotiatedUCEncryptionType, - bss_desc, &(bss_desc->bssId), - false, true, - eSIR_TX_RX, 0, 0, NULL, 0))) { + if (QDF_IS_STATUS_ERROR( + csr_issue_set_context_req_helper(mac_ctx, + profile, session_id, &bss_desc->bssId, + false, true, eSIR_TX_RX, 0, 0, NULL))) { /* NO keys. these key parameters don't matter */ - sme_err("Set context for unicast fail"); + sme_debug("Set context for unicast fail"); csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, session_id); } @@ -7492,11 +7999,11 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, * to establish the Broadcast STA context * NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req_helper(mac_ctx, - session_id, - profile->negotiatedMCEncryptionType, - bss_desc, &bcast_mac, false, false, - eSIR_TX_RX, 0, 0, NULL, 0); + csr_issue_set_context_req_helper(mac_ctx, profile, + session_id, &bcast_mac, + false, false, + eSIR_TX_RX, 0, 0, + NULL); } else if (CSR_IS_AUTH_TYPE_FILS(profile->negotiatedAuthType) && join_rsp->is_fils_connection) { roam_info->is_fils_connection = true; @@ -7559,17 +8066,6 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, #endif csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); - - akm_type = session->connectedProfile.AuthType; - mdie_present = - session->connectedProfile.mdid.mdie_present; - if (akm_type == eCSR_AUTH_TYPE_FT_SAE && - mdie_present) { - sme_debug("FT-SAE: Update MDID in PMK cache"); - csr_update_pmk_cache_ft(mac_ctx, - session_id, NULL); - } - len = join_rsp->assocReqLength + join_rsp->assocRspLength + join_rsp->beaconLength; @@ -7642,6 +8138,7 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx, roam_info->hs20vendor_ie = join_rsp->hs20vendor_ie; roam_info->ht_operation = join_rsp->ht_operation; roam_info->vht_operation = join_rsp->vht_operation; + csr_roam_process_he_info(join_rsp, roam_info); } else { if (cmd->u.roamCmd.fReassoc) { roam_info->fReassocReq = @@ -7765,7 +8262,7 @@ static bool csr_roam_process_results(struct mac_context *mac_ctx, tSmeCmd *cmd, bool release_cmd = true; struct bss_description *bss_desc = NULL; struct csr_roam_info *roam_info; - uint32_t session_id = cmd->sessionId; + uint32_t session_id = cmd->vdev_id; struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); struct csr_roam_profile *profile = &cmd->u.roamCmd.roamProfile; eRoamCmdStatus roam_status; @@ -8075,19 +8572,21 @@ QDF_STATUS csr_roam_copy_profile(struct mac_context *mac, qdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, pSrcProfile->nAddIEAssocLength); } - if (pSrcProfile->ChannelInfo.ChannelList) { - pDstProfile->ChannelInfo.ChannelList = - qdf_mem_malloc(pSrcProfile->ChannelInfo. - numOfChannels); - if (!pDstProfile->ChannelInfo.ChannelList) { + if (pSrcProfile->ChannelInfo.freq_list) { + pDstProfile->ChannelInfo.freq_list = + qdf_mem_malloc(sizeof(uint32_t) * + pSrcProfile->ChannelInfo.numOfChannels); + if (!pDstProfile->ChannelInfo.freq_list) { + pDstProfile->ChannelInfo.numOfChannels = 0; status = QDF_STATUS_E_NOMEM; goto end; } pDstProfile->ChannelInfo.numOfChannels = pSrcProfile->ChannelInfo.numOfChannels; - qdf_mem_copy(pDstProfile->ChannelInfo.ChannelList, - pSrcProfile->ChannelInfo.ChannelList, - pSrcProfile->ChannelInfo.numOfChannels); + qdf_mem_copy(pDstProfile->ChannelInfo.freq_list, + pSrcProfile->ChannelInfo.freq_list, + sizeof(uint32_t) * + pSrcProfile->ChannelInfo.numOfChannels); } pDstProfile->AuthType = pSrcProfile->AuthType; pDstProfile->akm_list = pSrcProfile->akm_list; @@ -8224,13 +8723,14 @@ QDF_STATUS csr_roam_copy_connected_profile(struct mac_context *mac, qdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, pSrcProfile->nAddIEAssocLength); } - pDstProfile->ChannelInfo.ChannelList = qdf_mem_malloc(1); - if (!pDstProfile->ChannelInfo.ChannelList) { + pDstProfile->ChannelInfo.freq_list = qdf_mem_malloc(sizeof(uint32_t)); + if (!pDstProfile->ChannelInfo.freq_list) { + pDstProfile->ChannelInfo.numOfChannels = 0; status = QDF_STATUS_E_NOMEM; goto end; } pDstProfile->ChannelInfo.numOfChannels = 1; - pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel; + pDstProfile->ChannelInfo.freq_list[0] = pSrcProfile->op_freq; pDstProfile->AuthType.numEntries = 1; pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType; pDstProfile->negotiatedAuthType = pSrcProfile->AuthType; @@ -8308,7 +8808,7 @@ QDF_STATUS csr_roam_issue_connect(struct mac_context *mac, uint32_t sessionId, } pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.hBSSList = hBSSList; pCommand->u.roamCmd.roamId = roamId; pCommand->u.roamCmd.roamReason = reason; @@ -8362,7 +8862,7 @@ QDF_STATUS csr_roam_issue_reassoc(struct mac_context *mac, uint32_t sessionId, if (QDF_IS_STATUS_SUCCESS(status)) pCommand->u.roamCmd.fReleaseProfile = true; pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.roamId = roamId; pCommand->u.roamCmd.roamReason = reason; /* We need to free the BssList when the command is done */ @@ -8463,8 +8963,8 @@ static void csr_roam_print_candidate_aps(tScanResultHandle results) while (entry) { bss_desc = GET_BASE_ADDR(entry, struct tag_csrscan_result, Link); - sme_nofl_debug(QDF_MAC_ADDR_STR " score: %d", - QDF_MAC_ADDR_ARRAY(bss_desc->Result.BssDescriptor.bssId), + sme_nofl_debug(QDF_MAC_ADDR_FMT " score: %d", + QDF_MAC_ADDR_REF(bss_desc->Result.BssDescriptor.bssId), bss_desc->bss_score); entry = csr_ll_next(&bss_list->List, entry, @@ -8478,12 +8978,13 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, { QDF_STATUS status = QDF_STATUS_SUCCESS; tScanResultHandle hBSSList; - tCsrScanResultFilter *pScanFilter; + struct scan_filter *filter; uint32_t roamId = 0; bool fCallCallback = false; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); struct bss_description *first_ap_profile; - uint8_t channel_id = 0; + enum QDF_OPMODE opmode = QDF_STA_MODE; + uint32_t ch_freq; if (!pSession) { sme_err("session does not exist for given sessionId: %d", @@ -8533,41 +9034,31 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, mac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; - pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); - if (!pScanFilter) { + filter = qdf_mem_malloc(sizeof(*filter)); + if (!filter) { status = QDF_STATUS_E_NOMEM; - goto end; + goto error; } /* Try to connect to any BSS */ if (!pProfile) { /* No encryption */ - pScanFilter->EncryptionType.numEntries = 1; - pScanFilter->EncryptionType.encryptionType[0] = - eCSR_ENCRYPT_TYPE_NONE; + filter->num_of_enc_type = 1; + filter->enc_type[0] = WLAN_ENCRYPT_TYPE_NONE; } else { /* Here is the profile we need to connect to */ - status = csr_roam_prepare_filter_from_profile(mac, - pProfile, pScanFilter); + status = csr_roam_get_scan_filter_from_profile(mac, pProfile, + filter, false); + opmode = pProfile->csrPersona; } roamId = GET_NEXT_ROAM_ID(&mac->roam); if (pRoamId) *pRoamId = roamId; if (!QDF_IS_STATUS_SUCCESS(status)) { - qdf_mem_free(pScanFilter); - goto end; + qdf_mem_free(filter); + goto error; } - /*Save the WPS info */ - if (pProfile) { - pScanFilter->bWPSAssociation = - pProfile->bWPSAssociation; - pScanFilter->bOSENAssociation = - pProfile->bOSENAssociation; - } else { - pScanFilter->bWPSAssociation = 0; - pScanFilter->bOSENAssociation = 0; - } if (pProfile && CSR_IS_INFRA_AP(pProfile)) { /* This can be started right away */ status = csr_roam_issue_connect(mac, sessionId, pProfile, NULL, @@ -8579,22 +9070,23 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, } else sme_debug("Connect request to proceed for sap mode"); - csr_free_scan_filter(mac, pScanFilter); - qdf_mem_free(pScanFilter); - goto end; + qdf_mem_free(filter); + goto error; } - status = csr_scan_get_result(mac, pScanFilter, &hBSSList); + status = csr_scan_get_result(mac, filter, &hBSSList); + qdf_mem_free(filter); csr_roam_print_candidate_aps(hBSSList); if (QDF_IS_STATUS_SUCCESS(status)) { /* check if set hw mode needs to be done */ - if ((pScanFilter->csrPersona == QDF_STA_MODE) || - (pScanFilter->csrPersona == QDF_P2P_CLIENT_MODE)) { + if ((opmode == QDF_STA_MODE) || + (opmode == QDF_P2P_CLIENT_MODE)) { bool ok; csr_get_bssdescr_from_scan_handle(hBSSList, - first_ap_profile); - status = policy_mgr_is_chan_ok_for_dnbs(mac->psoc, - first_ap_profile->channelId, &ok); + first_ap_profile); + status = policy_mgr_is_chan_ok_for_dnbs( + mac->psoc, + first_ap_profile->chan_freq, &ok); if (QDF_IS_STATUS_ERROR(status)) { sme_debug("policy_mgr_is_chan_ok_for_dnbs():error:%d", status); @@ -8603,21 +9095,21 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, goto error; } if (!ok) { - sme_debug("chan:%d not ok for DNBS", - first_ap_profile->channelId); + sme_debug("freq:%d not ok for DNBS", + first_ap_profile->chan_freq); csr_scan_result_purge(mac, hBSSList); fCallCallback = true; status = QDF_STATUS_E_INVAL; goto error; } - channel_id = csr_get_channel_for_hw_mode_change + ch_freq = csr_get_channel_for_hw_mode_change (mac, hBSSList, sessionId); - if (!channel_id) - channel_id = first_ap_profile->channelId; + if (!ch_freq) + ch_freq = first_ap_profile->chan_freq; - status = policy_mgr_handle_conc_multiport(mac->psoc, - sessionId, channel_id, + status = policy_mgr_handle_conc_multiport( + mac->psoc, sessionId, ch_freq, POLICY_MGR_UPDATE_REASON_NORMAL_STA); if ((QDF_IS_STATUS_SUCCESS(status)) && (!csr_wait_for_connection_update(mac, true))) { @@ -8672,15 +9164,6 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, } error: - if (pProfile) - /* - * we need to free memory for filter - * if profile exists - */ - csr_free_scan_filter(mac, pScanFilter); - - qdf_mem_free(pScanFilter); -end: /* tell the caller if we fail to trigger a join request */ if (fCallCallback) { csr_roam_call_callback(mac, sessionId, NULL, roamId, @@ -8716,12 +9199,6 @@ csr_roam_reassoc(struct mac_context *mac_ctx, uint32_t session_id, sme_err("No profile specified"); return QDF_STATUS_E_FAILURE; } - - if (!session) { - sme_err("Session_id invalid %d", session_id); - return QDF_STATUS_E_FAILURE; - } - sme_debug( "called BSSType = %s (%d) authtype = %d encryType = %d", sme_bss_type_to_string(profile->BSSType), @@ -8782,7 +9259,7 @@ QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, QDF_STATUS status = QDF_STATUS_SUCCESS; bool fComplete = false; enum csr_roam_substate NewSubstate; - uint32_t sessionId = pCommand->sessionId; + uint32_t sessionId = pCommand->vdev_id; if (CSR_IS_WAIT_FOR_KEY(mac, sessionId)) { sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE"); @@ -8792,7 +9269,7 @@ QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, } /* change state to 'Roaming'... */ csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, sessionId); - mlme_set_discon_reason_n_from_ap(mac->psoc, pCommand->sessionId, false, + mlme_set_discon_reason_n_from_ap(mac->psoc, pCommand->vdev_id, false, pCommand->u.roamCmd.disconnect_reason); if (csr_is_conn_state_ibss(mac, sessionId)) { /* If we are in an IBSS, then stop the IBSS... */ @@ -8872,6 +9349,37 @@ QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, return status; } +static void csr_abort_connect_request_timers( + struct mac_context *mac, uint32_t vdev_id) +{ + struct scheduler_msg msg; + QDF_STATUS status; + enum QDF_OPMODE op_mode; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, + vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Vdev ref error"); + return; + } + op_mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + + if (op_mode != QDF_STA_MODE && + op_mode != QDF_P2P_CLIENT_MODE) + return; + qdf_mem_zero(&msg, sizeof(msg)); + msg.bodyval = vdev_id; + msg.type = eWNI_SME_ABORT_CONN_TIMER; + status = scheduler_post_message(QDF_MODULE_ID_MLME, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) + sme_debug("msg eWNI_SME_ABORT_CONN_TIMER post fail"); +} + QDF_STATUS csr_roam_issue_disassociate_cmd(struct mac_context *mac, uint32_t sessionId, eCsrRoamDisconnectReason reason, @@ -8893,10 +9401,12 @@ QDF_STATUS csr_roam_issue_disassociate_cmd(struct mac_context *mac, csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, sessionId); } + csr_abort_connect_request_timers(mac, sessionId); + pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; - sme_debug("Disassociate reason: %d, sessionId: %d", - reason, sessionId); + pCommand->vdev_id = (uint8_t) sessionId; + sme_debug("Disassociate reason: %d, vdev_id: %d", + reason, sessionId); switch (reason) { case eCSR_DISCONNECT_REASON_MIC_ERROR: pCommand->u.roamCmd.roamReason = @@ -8956,7 +9466,7 @@ QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac, uint32_t session sessionId); } pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.roamReason = eCsrStopBss; status = csr_queue_sme_command(mac, pCommand, fHighPriority); if (!QDF_IS_STATUS_SUCCESS(status)) @@ -8999,6 +9509,20 @@ QDF_STATUS csr_roam_disconnect_internal(struct mac_context *mac, uint32_t sessio return status; } +#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) +static void +csr_disable_roaming_offload(struct mac_context *mac_ctx, uint32_t vdev_id) +{ + sme_stop_roaming(MAC_HANDLE(mac_ctx), vdev_id, + REASON_DRIVER_DISABLED, + RSO_INVALID_REQUESTOR); +} +#else +static inline void +csr_disable_roaming_offload(struct mac_context *mac_ctx, uint32_t session_id) +{} +#endif + QDF_STATUS csr_roam_disconnect(struct mac_context *mac_ctx, uint32_t session_id, eCsrRoamDisconnectReason reason, tSirMacReasonCodes mac_reason) @@ -9011,7 +9535,10 @@ QDF_STATUS csr_roam_disconnect(struct mac_context *mac_ctx, uint32_t session_id, } session->discon_in_progress = true; + csr_roam_cancel_roaming(mac_ctx, session_id); + csr_disable_roaming_offload(mac_ctx, session_id); + csr_roam_remove_duplicate_command(mac_ctx, session_id, NULL, eCsrForcedDisassoc); @@ -9087,7 +9614,7 @@ csr_roam_save_connected_information(struct mac_context *mac, #endif } /* Save bssid */ - pConnectProfile->operationChannel = pSirBssDesc->channelId; + pConnectProfile->op_freq = pSirBssDesc->chan_freq; pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval; if (!pConnectProfile->beaconInterval) sme_err("ERROR: Beacon interval is ZERO"); @@ -9184,8 +9711,7 @@ csr_roam_save_connected_information(struct mac_context *mac, } -bool is_disconnect_pending(struct mac_context *pmac, - uint8_t sessionid) +bool is_disconnect_pending(struct mac_context *pmac, uint8_t vdev_id) { tListElem *entry = NULL; tListElem *next_entry = NULL; @@ -9199,7 +9725,7 @@ bool is_disconnect_pending(struct mac_context *pmac, command = GET_BASE_ADDR(entry, tSmeCmd, Link); if (command && CSR_IS_DISCONNECT_COMMAND(command) && - command->sessionId == sessionid){ + command->vdev_id == vdev_id){ disconnect_cmd_exist = true; break; } @@ -9212,27 +9738,25 @@ bool is_disconnect_pending(struct mac_context *pmac, #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) static void csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac, - struct qdf_mac_addr *bssid, + struct bss_description *bss_desc, uint8_t vdev_id) { - struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); - tPmkidCacheInfo *cached_pmksa; - uint8_t i; + struct wlan_objmgr_vdev *vdev; - if (!session) { - sme_err("session %d not found", vdev_id); + if (!bss_desc->is_single_pmk) return; - } - for (i = 0; i < session->NumPmkidCache; i++) { - cached_pmksa = &session->PmkidCacheInfo[i]; - if (cached_pmksa->single_pmk_supported && - !qdf_is_macaddr_equal(&cached_pmksa->BSSID, bssid)) { - sme_debug("Deleting other BSS PMK cache entry"); - csr_roam_del_pmk_cache_entry(session, cached_pmksa, i); - i--; - } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("vdev is NULL"); + return; } + + wlan_crypto_selective_clear_sae_single_pmk_entries(vdev, + (struct qdf_mac_addr *)bss_desc->bssId); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); } static void @@ -9240,24 +9764,29 @@ csr_delete_current_bss_sae_single_pmk_entry(struct mac_context *mac, struct bss_description *bss_desc, uint8_t vdev_id) { - tPmkidCacheInfo *pmksa; + struct wlan_objmgr_vdev *vdev; + struct wlan_crypto_pmksa pmksa; if (!bss_desc->is_single_pmk) return; - pmksa = qdf_mem_malloc(sizeof(*pmksa)); - if (pmksa) { - qdf_copy_macaddr(&pmksa->BSSID, - (struct qdf_mac_addr *)bss_desc->bssId); - csr_roam_del_pmkid_from_cache(mac, vdev_id, pmksa, false); - qdf_mem_zero(pmksa, sizeof(*pmksa)); - qdf_mem_free(pmksa); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("vdev is NULL"); + return; } + + qdf_copy_macaddr(&pmksa.bssid, + (struct qdf_mac_addr *)bss_desc->bssId); + wlan_crypto_set_del_pmksa(vdev, &pmksa, false); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); } #else static inline void csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac, - struct qdf_mac_addr *bssid, + struct bss_description *bss_desc, uint8_t vdev_id) {} @@ -9275,25 +9804,25 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, tSmeCmd *pCommand = NULL; mac_handle_t mac_handle = MAC_HANDLE(mac); struct csr_roam_session *session_ptr; - struct scan_result_list *bss_list = NULL; struct csr_roam_profile *profile = NULL; struct csr_roam_connectedinfo *prev_connect_info; - tPmkidCacheInfo *pmksa_entry; + struct wlan_crypto_pmksa *pmksa; uint32_t len = 0, roamId = 0, reason_code = 0; bool is_dis_pending; bool use_same_bss = false; + uint8_t max_retry_count = 1; bool retry_same_bss = false; bool attempt_next_bss = true; - tPmkidCacheInfo pmk_cache; + enum csr_akm_type auth_type = eCSR_AUTH_TYPE_NONE; if (!pSmeJoinRsp) { sme_err("Sme Join Response is NULL"); return; } - session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId); + session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->vdev_id); if (!session_ptr) { - sme_err("session %d not found", pSmeJoinRsp->sessionId); + sme_err("session %d not found", pSmeJoinRsp->vdev_id); return; } @@ -9330,7 +9859,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason) { #ifndef WLAN_MDM_CODE_REDUCTION_OPT - sme_qos_csr_event_ind(mac, pSmeJoinRsp->sessionId, + sme_qos_csr_event_ind(mac, pSmeJoinRsp->vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); #endif } @@ -9353,16 +9882,13 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * On successful connection to sae single pmk AP, * clear all the single pmk AP. */ - if (pCommand && pCommand->u.roamCmd.pLastRoamBss && - pCommand->u.roamCmd.pLastRoamBss->is_single_pmk) - csr_clear_other_bss_sae_single_pmk_entry( - mac, - (struct qdf_mac_addr *) - pCommand->u.roamCmd.pLastRoamBss->bssId, - pSmeJoinRsp->sessionId); + if (pCommand && pCommand->u.roamCmd.pLastRoamBss) + csr_clear_other_bss_sae_single_pmk_entry(mac, + pCommand->u.roamCmd.pLastRoamBss, + pSmeJoinRsp->vdev_id); csr_roam_complete(mac, eCsrJoinSuccess, (void *)pSmeJoinRsp, - pSmeJoinRsp->sessionId); + pSmeJoinRsp->vdev_id); return; } @@ -9373,8 +9899,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, if (pCommand) { roamId = pCommand->u.roamCmd.roamId; profile = &pCommand->u.roamCmd.roamProfile; - bss_list = - (struct scan_result_list *)pCommand->u.roamCmd.hBSSList; + auth_type = profile->AuthType.authType[0]; } reason_code = pSmeJoinRsp->protStatusCode; @@ -9385,6 +9910,14 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, pSmeJoinRsp->status_code, pSmeJoinRsp->status_code, reason_code); + is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); + /* + * if userspace has issued disconnection or we have reached mac tries, + * driver should not continue for next connection. + */ + if (is_dis_pending || + session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT) + attempt_next_bss = false; /* * Delete the PMKID of the BSSID for which the assoc reject is * received from the AP due to invalid PMKID reason. @@ -9394,40 +9927,47 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * AP. */ if (reason_code == eSIR_MAC_INVALID_PMKID) { - - pmksa_entry = qdf_mem_malloc(sizeof(*pmksa_entry)); - if (!pmksa_entry) + pmksa = qdf_mem_malloc(sizeof(*pmksa)); + if (!pmksa) return; - sme_warn("Assoc reject from BSSID:%pM due to invalid PMKID", - session_ptr->joinFailStatusCode.bssId); - qdf_mem_copy(pmksa_entry->BSSID.bytes, + sme_warn("Assoc reject from BSSID:"QDF_MAC_ADDR_FMT" due to invalid PMKID", + QDF_MAC_ADDR_REF(session_ptr->joinFailStatusCode.bssId)); + qdf_mem_copy(pmksa->bssid.bytes, &session_ptr->joinFailStatusCode.bssId, sizeof(tSirMacAddr)); sme_roam_del_pmkid_from_cache(mac_handle, session_ptr->vdev_id, - pmksa_entry, false); - qdf_mem_free(pmksa_entry); + pmksa, false); + qdf_mem_free(pmksa); retry_same_bss = true; } - is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); - /* - * if userspace has issued disconnection or we have reached mac tries, - * driver should not continue for next connection. - */ - if (is_dis_pending || - session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT) - attempt_next_bss = false; - if (pSmeJoinRsp->messageType == eWNI_SME_JOIN_RSP && pSmeJoinRsp->status_code == eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE && (mlme_get_reconn_after_assoc_timeout_flag(mac->psoc, - pSmeJoinRsp->sessionId) || - (profile && (profile->AuthType.authType[0] == eCSR_AUTH_TYPE_SAE || - profile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_SAE) && - bss_list && (csr_ll_count(&bss_list->List) == - session_ptr->join_bssid_count)))) + pSmeJoinRsp->vdev_id) || + (auth_type == eCSR_AUTH_TYPE_SAE || + auth_type == eCSR_AUTH_TYPE_FT_SAE))) { retry_same_bss = true; + if (auth_type == eCSR_AUTH_TYPE_SAE || + auth_type == eCSR_AUTH_TYPE_FT_SAE) + wlan_mlme_get_sae_assoc_retry_count(mac->psoc, + &max_retry_count); + } + + if (pSmeJoinRsp->messageType == eWNI_SME_JOIN_RSP && + pSmeJoinRsp->status_code == eSIR_SME_JOIN_TIMEOUT_RESULT_CODE && + pCommand && pCommand->u.roamCmd.hBSSList) { + struct scan_result_list *bss_list = + (struct scan_result_list *)pCommand->u.roamCmd.hBSSList; + + if (csr_ll_count(&bss_list->List) == 1) { + retry_same_bss = true; + sme_err("retry_same_bss is set"); + wlan_mlme_get_sae_assoc_retry_count(mac->psoc, + &max_retry_count); + } + } if (attempt_next_bss && retry_same_bss && pCommand && pCommand->u.roamCmd.pRoamBssEntry) { @@ -9437,10 +9977,12 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, struct tag_csrscan_result, Link); /* Retry with same BSSID without PMKID */ - if (!scan_result->retry_count) { - sme_info("Retry once with same BSSID, status %d reason %d", - pSmeJoinRsp->status_code, reason_code); - scan_result->retry_count = 1; + if (scan_result->retry_count < max_retry_count) { + sme_info("Retry once with same BSSID, status %d reason %d auth_type %d retry count %d max count %d", + pSmeJoinRsp->status_code, reason_code, + auth_type, scan_result->retry_count, + max_retry_count); + scan_result->retry_count++; use_same_bss = true; } } @@ -9449,33 +9991,28 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * If connection fails with Single PMK bssid, clear this pmk * entry, Flush in case if we are not trying again with same AP */ - qdf_mem_copy(&pmk_cache.BSSID.bytes, - &pCommand->u.roamCmd.pLastRoamBss->bssId, - sizeof(pmk_cache.BSSID.bytes)); - if (!use_same_bss && pCommand && pCommand->u.roamCmd.pLastRoamBss) { + if (!use_same_bss && pCommand && pCommand->u.roamCmd.pLastRoamBss) csr_delete_current_bss_sae_single_pmk_entry( mac, pCommand->u.roamCmd.pLastRoamBss, - pSmeJoinRsp->sessionId); - csr_clear_sae_single_pmk(mac, pSmeJoinRsp->sessionId, - &pmk_cache); - } + pSmeJoinRsp->vdev_id); + /* If Join fails while Handoff is in progress, indicate * disassociated event to supplicant to reconnect */ - if (csr_roam_is_handoff_in_progress(mac, pSmeJoinRsp->sessionId)) { - csr_roam_call_callback(mac, pSmeJoinRsp->sessionId, NULL, + if (csr_roam_is_handoff_in_progress(mac, pSmeJoinRsp->vdev_id)) { + csr_roam_call_callback(mac, pSmeJoinRsp->vdev_id, NULL, roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); /* Should indicate neighbor roam algorithm about the * connect failure here */ - csr_neighbor_roam_indicate_connect(mac, pSmeJoinRsp->sessionId, + csr_neighbor_roam_indicate_connect(mac, pSmeJoinRsp->vdev_id, QDF_STATUS_E_FAILURE); } if (pCommand && attempt_next_bss) { - csr_roam(mac, pCommand, use_same_bss); - return; + csr_roam(mac, pCommand, use_same_bss); + return; } /* @@ -9500,7 +10037,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, csr_roam_call_callback(mac, session_ptr->sessionId, NULL, roamId, eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_NOT_ASSOCIATED); - csr_roam_complete(mac, eCsrNothingToJoin, NULL, pSmeJoinRsp->sessionId); + csr_roam_complete(mac, eCsrNothingToJoin, NULL, pSmeJoinRsp->vdev_id); } static QDF_STATUS csr_roam_issue_join(struct mac_context *mac, uint32_t sessionId, @@ -9538,7 +10075,7 @@ csr_roam_reissue_roam_command(struct mac_context *mac, uint8_t session_id) sme_err("Active cmd, is not a roaming CMD"); return; } - sessionId = pCommand->sessionId; + sessionId = pCommand->vdev_id; pSession = CSR_GET_SESSION(mac, sessionId); if (!pSession) { @@ -9587,7 +10124,7 @@ csr_roam_reissue_roam_command(struct mac_context *mac, uint8_t session_id) } bool csr_is_roam_command_waiting_for_session(struct mac_context *mac, - uint32_t sessionId) + uint32_t vdev_id) { bool fRet = false; tListElem *pEntry; @@ -9597,7 +10134,7 @@ bool csr_is_roam_command_waiting_for_session(struct mac_context *mac, if (pEntry) { pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); if ((eSmeCommandRoam == pCommand->command) - && (sessionId == pCommand->sessionId)) { + && (vdev_id == pCommand->vdev_id)) { fRet = true; } } @@ -9607,7 +10144,7 @@ bool csr_is_roam_command_waiting_for_session(struct mac_context *mac, while (pEntry) { pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); if ((eSmeCommandRoam == pCommand->command) - && (sessionId == pCommand->sessionId)) { + && (vdev_id == pCommand->vdev_id)) { fRet = true; break; } @@ -9621,8 +10158,7 @@ bool csr_is_roam_command_waiting_for_session(struct mac_context *mac, static void csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, - tSmeCmd *cmd, - uint8_t sme_session_id) + tSmeCmd *cmd, uint8_t vdev_id) { struct tag_csrscan_result *scan_result = NULL; struct bss_description *bss_desc = NULL; @@ -9636,7 +10172,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, sme_err("given sme cmd is null"); return; } - session_id = cmd->sessionId; + session_id = cmd->vdev_id; session = CSR_GET_SESSION(mac_ctx, session_id); if (!session) { @@ -9647,8 +10183,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, if (CSR_IS_ROAMING(session) && session->fCancelRoaming) { /* the roaming is cancelled. Simply complete the command */ sme_warn("Roam command canceled"); - csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL, - sme_session_id); + csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL, vdev_id); return; } @@ -9673,7 +10208,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, sme_err("CSR start BSS failed"); /* We need to complete the command */ csr_roam_complete(mac_ctx, eCsrStartBssFailure, NULL, - sme_session_id); + vdev_id); } return; } @@ -9681,8 +10216,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, if (!cmd->u.roamCmd.pRoamBssEntry) { sme_err("pRoamBssEntry is NULL"); /* We need to complete the command */ - csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL, - sme_session_id); + csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL, vdev_id); return; } @@ -9786,19 +10320,18 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; struct csr_roam_session *csr_session; - if (pSmeJoinRsp->sessionId >= WLAN_MAX_VDEVS) { - sme_err("Invalid session ID received %d", - pSmeJoinRsp->sessionId); + if (pSmeJoinRsp->vdev_id >= WLAN_MAX_VDEVS) { + sme_err("Invalid session ID received %d", pSmeJoinRsp->vdev_id); return; } pNeighborRoamInfo = - &mac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId]; + &mac->roam.neighborRoamInfo[pSmeJoinRsp->vdev_id]; if (eSIR_SME_SUCCESS == pSmeJoinRsp->status_code) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "CSR SmeReassocReq Successful"); result = eCsrReassocSuccess; - csr_session = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId); + csr_session = CSR_GET_SESSION(mac, pSmeJoinRsp->vdev_id); if (csr_session) { if (pSmeJoinRsp->nss < csr_session->nss) { csr_session->nss = pSmeJoinRsp->nss; @@ -9815,17 +10348,17 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac * processing the result in csr_roam_process_results() */ if (csr_roam_is_handoff_in_progress(mac, - pSmeJoinRsp->sessionId)) { + pSmeJoinRsp->vdev_id)) { /* Need to dig more on indicating events to * SME QoS module */ - sme_qos_csr_event_ind(mac, pSmeJoinRsp->sessionId, + sme_qos_csr_event_ind(mac, pSmeJoinRsp->vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); csr_roam_complete(mac, result, pSmeJoinRsp, - pSmeJoinRsp->sessionId); + pSmeJoinRsp->vdev_id); } else { csr_roam_complete(mac, result, NULL, - pSmeJoinRsp->sessionId); + pSmeJoinRsp->vdev_id); } } /* Should we handle this similar to handling the join failure? Is it ok @@ -9855,10 +10388,10 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac if (!roam_info) return; mlme_set_discon_reason_n_from_ap(mac->psoc, - pSmeJoinRsp->sessionId, false, + pSmeJoinRsp->vdev_id, false, eSIR_MAC_HOST_TRIGGERED_ROAM_FAILURE); csr_roam_call_callback(mac, - pSmeJoinRsp->sessionId, + pSmeJoinRsp->vdev_id, roam_info, roam_id, eCSR_ROAM_FT_REASSOC_FAILED, eCSR_ROAM_RESULT_SUCCESS); @@ -9873,7 +10406,7 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac * were trying to reassoc. */ csr_roam_complete(mac, eCsrJoinFailure, NULL, - pSmeJoinRsp->sessionId); + pSmeJoinRsp->vdev_id); qdf_mem_free(roam_info); return; } @@ -9887,11 +10420,11 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac */ if (!QDF_IS_STATUS_SUCCESS (csr_roam_issue_disassociate - (mac, pSmeJoinRsp->sessionId, + (mac, pSmeJoinRsp->vdev_id, eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false))) { csr_roam_complete(mac, eCsrJoinFailure, NULL, - pSmeJoinRsp->sessionId); + pSmeJoinRsp->vdev_id); } } } @@ -9916,20 +10449,20 @@ static void csr_roam_roaming_state_stop_bss_rsp_processor(struct mac_context *ma } } #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - mac->roam.roamSession[pSmeRsp->sessionId].connectState = + mac->roam.roamSession[pSmeRsp->vdev_id].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; - if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac, pSmeRsp->sessionId)) { + if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac, pSmeRsp->vdev_id)) { profile = - mac->roam.roamSession[pSmeRsp->sessionId].pCurRoamProfile; + mac->roam.roamSession[pSmeRsp->vdev_id].pCurRoamProfile; if (profile && CSR_IS_CONN_NDI(profile)) { result_code = eCsrStopBssSuccess; if (pSmeRsp->status_code != eSIR_SME_SUCCESS) result_code = eCsrStopBssFailure; } - csr_roam_complete(mac, result_code, NULL, pSmeRsp->sessionId); + csr_roam_complete(mac, result_code, NULL, pSmeRsp->vdev_id); } else if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(mac, - pSmeRsp->sessionId)) { - csr_roam_reissue_roam_command(mac, pSmeRsp->sessionId); + pSmeRsp->vdev_id)) { + csr_roam_reissue_roam_command(mac, pSmeRsp->vdev_id); } } @@ -9993,15 +10526,10 @@ static void csr_post_roam_failure(struct mac_context *mac_ctx, uint32_t session_id, struct csr_roam_info *roam_info, - struct tagCsrScanResultFilter *scan_filter, struct csr_roam_profile *cur_roam_profile) { QDF_STATUS status; - if (scan_filter) { - csr_free_scan_filter(mac_ctx, scan_filter); - qdf_mem_free(scan_filter); - } if (cur_roam_profile) qdf_mem_free(cur_roam_profile); @@ -10034,7 +10562,6 @@ csr_post_roam_failure(struct mac_context *mac_ctx, * csr_check_profile_in_scan_cache() - finds if roam profile is present in scan * cache or not * @mac: mac global context - * @scan_filter: out param, scan filter * @neighbor_roam_info: roam info struct * @hBSSList: scan result * @@ -10042,26 +10569,28 @@ csr_post_roam_failure(struct mac_context *mac_ctx, */ static bool csr_check_profile_in_scan_cache(struct mac_context *mac_ctx, - tCsrScanResultFilter **scan_filter, tpCsrNeighborRoamControlInfo neighbor_roam_info, tScanResultHandle *hBSSList) { QDF_STATUS status; - *scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); - if (!*scan_filter) + struct scan_filter *scan_filter; + + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); + if (!scan_filter) return false; - (*scan_filter)->scan_filter_for_roam = 1; - status = csr_roam_prepare_filter_from_profile(mac_ctx, + status = csr_roam_get_scan_filter_from_profile(mac_ctx, &neighbor_roam_info->csrNeighborRoamProfile, - *scan_filter); + scan_filter, true); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err( "failed to prepare scan filter, status %d", status); + qdf_mem_free(scan_filter); return false; } - status = csr_scan_get_result(mac_ctx, *scan_filter, hBSSList); + status = csr_scan_get_result(mac_ctx, scan_filter, hBSSList); + qdf_mem_free(scan_filter); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err( "csr_scan_get_result failed, status %d", @@ -10102,12 +10631,6 @@ QDF_STATUS csr_roam_lfr2_issue_connect(struct mac_context *mac, NULL); csr_roam_copy_profile(mac, cur_roam_profile, session->pCurRoamProfile); - /* - * After ensuring that the roam profile is in the scan - * result list, and session->pCurRoamProfile is saved, - * dequeue the command from the active list. - */ - csr_dequeue_command(mac); /* make sure to put it at the head of the cmd queue */ status = csr_roam_issue_connect(mac, session_id, cur_roam_profile, hbss_list, @@ -10145,6 +10668,13 @@ QDF_STATUS csr_continue_lfr2_connect(struct mac_context *mac, if (!scan_handle_roam_ap) goto POST_ROAM_FAILURE; + if ((mac->roam.roamSession[session_id].connectState == + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) || + (mac->roam.roamSession[session_id].connectState == + eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTING)) { + goto purge_scan_result; + } + status = csr_roam_lfr2_issue_connect(mac, session_id, scan_handle_roam_ap, roam_id); @@ -10152,11 +10682,12 @@ QDF_STATUS csr_continue_lfr2_connect(struct mac_context *mac, qdf_mem_free(roam_info); return status; } + +purge_scan_result: csr_scan_result_purge(mac, scan_handle_roam_ap); POST_ROAM_FAILURE: - csr_post_roam_failure(mac, session_id, roam_info, - NULL, NULL); + csr_post_roam_failure(mac, session_id, roam_info, NULL); qdf_mem_free(roam_info); return status; } @@ -10166,12 +10697,12 @@ void csr_handle_disassoc_ho(struct mac_context *mac, uint32_t session_id) { uint32_t roam_id = 0; struct csr_roam_info *roam_info; - struct tagCsrScanResultFilter *scan_filter = NULL; struct sCsrNeighborRoamControlInfo *neighbor_roam_info = NULL; struct scan_result_list *scan_handle_roam_ap; struct sCsrNeighborRoamBSSInfo *bss_node; QDF_STATUS status; + csr_dequeue_command(mac); roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return; @@ -10183,8 +10714,7 @@ void csr_handle_disassoc_ho(struct mac_context *mac, uint32_t session_id) * First ensure if the roam profile is in the scan cache. * If not, post a reassoc failure and disconnect. */ - if (!csr_check_profile_in_scan_cache(mac, &scan_filter, - neighbor_roam_info, + if (!csr_check_profile_in_scan_cache(mac, neighbor_roam_info, (tScanResultHandle *)&scan_handle_roam_ap)) goto POST_ROAM_FAILURE; @@ -10211,23 +10741,23 @@ void csr_handle_disassoc_ho(struct mac_context *mac, uint32_t session_id) sme_debug("LFR2DBG: bss_node is NULL"); goto POST_ROAM_FAILURE; } + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "LFR2DBG: preauthed bss_node->pBssDescription BSSID"\ - QDF_MAC_ADDR_STR",Ch:%d", - QDF_MAC_ADDR_ARRAY(bss_node->pBssDescription->bssId), - (int)bss_node->pBssDescription->channelId); - - status = policy_mgr_handle_conc_multiport(mac->psoc, session_id, - bss_node->pBssDescription->channelId, - POLICY_MGR_UPDATE_REASON_LFR2_ROAM); + QDF_MAC_ADDR_FMT",freq:%d", + QDF_MAC_ADDR_REF(bss_node->pBssDescription->bssId), + bss_node->pBssDescription->chan_freq); + + status = policy_mgr_handle_conc_multiport( + mac->psoc, session_id, + bss_node->pBssDescription->chan_freq, + POLICY_MGR_UPDATE_REASON_LFR2_ROAM); if (QDF_IS_STATUS_SUCCESS(status)) { mac->roam.neighborRoamInfo[session_id].scan_res_lfr2_roam_ap = scan_handle_roam_ap; /*if hw_mode change is required then handle roam * issue connect in mode change response handler */ - csr_free_scan_filter(mac, scan_filter); - qdf_mem_free(scan_filter); qdf_mem_free(roam_info); return; } else if (status == QDF_STATUS_E_FAILURE) @@ -10237,8 +10767,6 @@ void csr_handle_disassoc_ho(struct mac_context *mac, uint32_t session_id) scan_handle_roam_ap, roam_id); if (QDF_IS_STATUS_SUCCESS(status)) { - csr_free_scan_filter(mac, scan_filter); - qdf_mem_free(scan_filter); qdf_mem_free(roam_info); return; } @@ -10247,7 +10775,7 @@ void csr_handle_disassoc_ho(struct mac_context *mac, uint32_t session_id) POST_ROAM_FAILURE: mlme_set_discon_reason_n_from_ap(mac->psoc, session_id, false, eSIR_MAC_HOST_TRIGGERED_ROAM_FAILURE); - csr_post_roam_failure(mac, session_id, roam_info, scan_filter, NULL); + csr_post_roam_failure(mac, session_id, roam_info, NULL); qdf_mem_free(roam_info); } #else @@ -10403,6 +10931,7 @@ csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx, roam_info->rx_rate = mac_ctx->peer_rxrate; roam_info->disassoc_reason = discon_ind->reason_code; roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; + roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, WLAN_LEGACY_SME_ID); @@ -10468,14 +10997,14 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf) case eWNI_SME_JOIN_RSP: /* in Roaming state, process the Join response message... */ - if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(mac, pSmeRsp->sessionId)) + if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(mac, pSmeRsp->vdev_id)) /* We sent a JOIN_REQ */ csr_roam_join_rsp_processor(mac, (struct join_rsp *)pSmeRsp); break; case eWNI_SME_REASSOC_RSP: /* or the Reassociation response message... */ - if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(mac, pSmeRsp->sessionId)) + if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(mac, pSmeRsp->vdev_id)) csr_roam_roaming_state_reassoc_rsp_processor(mac, (struct join_rsp *)pSmeRsp); break; @@ -10485,35 +11014,35 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf) break; case eWNI_SME_DISASSOC_RSP: /* or the Disassociate response message... */ - if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(mac, pSmeRsp->sessionId) + if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(mac, pSmeRsp->vdev_id) || CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(mac, - pSmeRsp->sessionId) + pSmeRsp->vdev_id) || CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(mac, - pSmeRsp->sessionId) + pSmeRsp->vdev_id) || CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(mac, - pSmeRsp->sessionId) + pSmeRsp->vdev_id) || CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(mac, - pSmeRsp->sessionId) + pSmeRsp->vdev_id) || CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(mac, - pSmeRsp->sessionId)) { + pSmeRsp->vdev_id)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "eWNI_SME_DISASSOC_RSP subState = %s", mac_trace_getcsr_roam_sub_state( - mac->roam.curSubState[pSmeRsp->sessionId])); + mac->roam.curSubState[pSmeRsp->vdev_id])); csr_roam_roaming_state_disassoc_rsp_processor(mac, (struct disassoc_rsp *) pSmeRsp); } break; case eWNI_SME_DEAUTH_RSP: /* or the Deauthentication response message... */ - if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(mac, pSmeRsp->sessionId)) + if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(mac, pSmeRsp->vdev_id)) csr_roam_roaming_state_deauth_rsp_processor(mac, (struct deauth_rsp *) pSmeRsp); break; case eWNI_SME_START_BSS_RSP: /* or the Start BSS response message... */ if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(mac, - pSmeRsp->sessionId)) + pSmeRsp->vdev_id)) csr_roam_roaming_state_start_bss_rsp_processor(mac, (struct start_bss_rsp *)pSmeRsp); break; @@ -10527,26 +11056,13 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf) if (!roam_info) break; - roam_info->staId = (uint8_t) pIbssPeerInd->staId; qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr); - csr_roam_call_callback(mac, pSmeRsp->sessionId, roam_info, 0, + csr_roam_call_callback(mac, pSmeRsp->vdev_id, roam_info, 0, eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); qdf_mem_free(roam_info); roam_info = NULL; break; - case eWNI_SME_GET_RSSI_REQ: - { - tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *)msg_buf; - - if (pGetRssiReq->rssiCallback) - ((tCsrRssiCallback) pGetRssiReq->rssiCallback) - (pGetRssiReq->lastRSSI, pGetRssiReq->staId, - pGetRssiReq->pDevContext); - else - sme_err("pGetRssiReq->rssiCallback is NULL"); - } - break; case eWNI_SME_TRIGGER_SAE: sme_debug("Invoke SAE callback"); csr_sae_callback(mac, pSmeRsp); @@ -10567,9 +11083,9 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf) sme_debug("Unexpected message type: %d[0x%X] received in substate %s", pSmeRsp->messageType, pSmeRsp->messageType, mac_trace_getcsr_roam_sub_state( - mac->roam.curSubState[pSmeRsp->sessionId])); + mac->roam.curSubState[pSmeRsp->vdev_id])); /* If we are connected, check the link status change */ - if (!csr_is_conn_state_disconnected(mac, pSmeRsp->sessionId)) + if (!csr_is_conn_state_disconnected(mac, pSmeRsp->vdev_id)) csr_roam_check_for_link_status_change(mac, pSmeRsp); break; } @@ -10580,10 +11096,6 @@ void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *msg_buf) tSirSmeRsp *pSirMsg = (tSirSmeRsp *)msg_buf; switch (pSirMsg->messageType) { - case eWNI_SME_GET_STATISTICS_RSP: - sme_debug("Stats rsp from PE"); - csr_roam_stats_rsp_processor(mac, pSirMsg); - break; case eWNI_SME_UPPER_LAYER_ASSOC_CNF: { struct csr_roam_session *pSession; @@ -10697,11 +11209,200 @@ void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *msg_buf) } } -#ifdef CRYPTO_SET_KEY_CONVERGED +/** + * csr_update_wep_key_peer_macaddr() - Update wep key peer mac addr + * @vdev: vdev object + * @crypto_key: crypto key info + * @unicast: uncast or broadcast + * @mac_addr: peer mac address + * + * Update peer mac address to key context before set wep key to target. + * + * Return void + */ +static void +csr_update_wep_key_peer_macaddr(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_key *crypto_key, + bool unicast, + struct qdf_mac_addr *mac_addr) +{ + if (!crypto_key || !vdev) { + sme_err("vdev or crytpo_key null"); + return; + } + + if (unicast) { + qdf_mem_copy(&crypto_key->macaddr, mac_addr, + QDF_MAC_ADDR_SIZE); + } else { + if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE || + vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE) + qdf_mem_copy(&crypto_key->macaddr, mac_addr, + QDF_MAC_ADDR_SIZE); + else + qdf_mem_copy(&crypto_key->macaddr, + vdev->vdev_mlme.macaddr, + QDF_MAC_ADDR_SIZE); + } +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +static void +csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct set_context_rsp *pRsp) +{ + WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent, + host_event_wlan_security_payload_type); + if (eCSR_ENCRYPT_TYPE_NONE == + session->connectedProfile.EncryptionType) + return; + qdf_mem_zero(&setKeyEvent, + sizeof(host_event_wlan_security_payload_type)); + if (qdf_is_macaddr_group(&pRsp->peer_macaddr)) + setKeyEvent.eventId = + WLAN_SECURITY_EVENT_SET_BCAST_RSP; + else + setKeyEvent.eventId = + WLAN_SECURITY_EVENT_SET_UNICAST_RSP; + setKeyEvent.encryptionModeMulticast = + (uint8_t) diag_enc_type_from_csr_type( + session->connectedProfile.mcEncryptionType); + setKeyEvent.encryptionModeUnicast = + (uint8_t) diag_enc_type_from_csr_type( + session->connectedProfile.EncryptionType); + qdf_mem_copy(setKeyEvent.bssid, session->connectedProfile.bssid.bytes, + QDF_MAC_ADDR_SIZE); + setKeyEvent.authMode = + (uint8_t) diag_auth_type_from_csr_type( + session->connectedProfile.AuthType); + if (eSIR_SME_SUCCESS != pRsp->status_code) + setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); +} +#else /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ +static void +csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct set_context_rsp *pRsp) +{ +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + +static void +csr_roam_chk_lnk_set_ctx_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +{ + struct csr_roam_session *session; + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; + struct csr_roam_info *roam_info; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + struct set_context_rsp *pRsp = (struct set_context_rsp *)msg_ptr; + + if (!pRsp) { + sme_err("set key response is NULL"); + return; + } + + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + sessionId = pRsp->sessionId; + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", sessionId); + qdf_mem_free(roam_info); + return; + } + + csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp); + + if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) { + csr_roam_stop_wait_for_key_timer(mac_ctx); + /* We are done with authentication, whethere succeed or not */ + csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, + sessionId); + /* We do it here because this linkup function is not called + * after association when a key needs to be set. + */ + if (csr_is_conn_state_connected_infra(mac_ctx, sessionId)) + csr_roam_link_up(mac_ctx, + session->connectedProfile.bssid); + } + if (eSIR_SME_SUCCESS == pRsp->status_code) { + qdf_copy_macaddr(&roam_info->peerMac, &pRsp->peer_macaddr); + /* Make sure we install the GTK before indicating to HDD as + * authenticated. This is to prevent broadcast packets go out + * after PTK and before GTK. + */ + if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) { + /* + * OBSS SCAN Indication will be sent to Firmware + * to start OBSS Scan + */ + if (mac_ctx->obss_scan_offload && + wlan_reg_is_24ghz_ch_freq( + session->connectedProfile.op_freq) && + (session->connectState == + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED) && + session->pCurRoamProfile && + (QDF_P2P_CLIENT_MODE == + session->pCurRoamProfile->csrPersona || + (QDF_STA_MODE == + session->pCurRoamProfile->csrPersona))) { + struct sme_obss_ht40_scanind_msg *msg; + + msg = qdf_mem_malloc(sizeof( + struct sme_obss_ht40_scanind_msg)); + if (!msg) { + qdf_mem_free(roam_info); + return; + } + + msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND; + msg->length = + sizeof(struct sme_obss_ht40_scanind_msg); + qdf_copy_macaddr(&msg->mac_addr, + &session->connectedProfile.bssid); + status = umac_send_mb_message_to_mac(msg); + } + result = eCSR_ROAM_RESULT_AUTHENTICATED; + } else { + result = eCSR_ROAM_RESULT_NONE; + } + } else { + result = eCSR_ROAM_RESULT_FAILURE; + sme_err( + "CSR: setkey command failed(err=%d) PeerMac " + QDF_MAC_ADDR_FMT, + pRsp->status_code, + QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes)); + } + /* keeping roam_id = 0 as nobody is using roam_id for set_key */ + csr_roam_call_callback(mac_ctx, sessionId, roam_info, + 0, eCSR_ROAM_SET_KEY_COMPLETE, result); + /* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS + * can go ahead and initiate the TSPEC if any are pending + */ + sme_qos_csr_event_ind(mac_ctx, (uint8_t)sessionId, + SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL); +#ifdef FEATURE_WLAN_ESE + /* Send Adjacent AP repot to new AP. */ + if (result == eCSR_ROAM_RESULT_AUTHENTICATED && + session->isPrevApInfoValid && + session->connectedProfile.isESEAssoc) { + csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session); + session->isPrevApInfoValid = false; + } +#endif + qdf_mem_free(roam_info); +} + static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, uint32_t session_id, bool add_key, bool unicast, - uint8_t key_idx) + uint8_t key_idx, + struct qdf_mac_addr *mac_addr) { enum wlan_crypto_cipher_type cipher; struct wlan_crypto_key *crypto_key; @@ -10718,6 +11419,8 @@ static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, if (IS_WEP_CIPHER(cipher)) { wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast); crypto_key = wlan_crypto_get_key(vdev, wep_key_idx); + csr_update_wep_key_peer_macaddr(vdev, crypto_key, unicast, + mac_addr); } else { crypto_key = wlan_crypto_get_key(vdev, key_idx); } @@ -10726,7 +11429,7 @@ static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d", session_id, cipher, unicast, key_idx, wep_key_idx, add_key); - if (!IS_WEP_CIPHER(cipher)) + if (!IS_WEP_CIPHER(cipher) && !add_key) return QDF_STATUS_E_INVAL; return ucfg_crypto_set_key_req(vdev, crypto_key, (unicast ? @@ -10734,25 +11437,61 @@ static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, WLAN_CRYPTO_KEY_TYPE_GROUP)); } -static QDF_STATUS csr_roam_store_fils_key(struct wlan_objmgr_vdev *vdev, - bool unicast, uint8_t key_id, - uint16_t key_length, uint8_t *key, - tSirMacAddr *bssid) +static enum wlan_crypto_cipher_type +csr_encr_to_cipher_type(eCsrEncryptionType encr_type) +{ + switch (encr_type) { + case eCSR_ENCRYPT_TYPE_WEP40: + return WLAN_CRYPTO_CIPHER_WEP_40; + case eCSR_ENCRYPT_TYPE_WEP104: + return WLAN_CRYPTO_CIPHER_WEP_104; + case eCSR_ENCRYPT_TYPE_TKIP: + return WLAN_CRYPTO_CIPHER_TKIP; + case eCSR_ENCRYPT_TYPE_AES: + return WLAN_CRYPTO_CIPHER_AES_CCM; + case eCSR_ENCRYPT_TYPE_AES_CMAC: + return WLAN_CRYPTO_CIPHER_AES_CMAC; + case eCSR_ENCRYPT_TYPE_AES_GMAC_128: + return WLAN_CRYPTO_CIPHER_AES_GMAC; + case eCSR_ENCRYPT_TYPE_AES_GMAC_256: + return WLAN_CRYPTO_CIPHER_AES_GMAC_256; + case eCSR_ENCRYPT_TYPE_AES_GCMP: + return WLAN_CRYPTO_CIPHER_AES_GCM; + case eCSR_ENCRYPT_TYPE_AES_GCMP_256: + return WLAN_CRYPTO_CIPHER_AES_GCM_256; + default: + return WLAN_CRYPTO_CIPHER_NONE; + } +} + +#ifdef WLAN_FEATURE_FILS_SK +static QDF_STATUS +csr_roam_store_fils_key(struct wlan_objmgr_vdev *vdev, + bool unicast, uint8_t key_id, + uint16_t key_length, uint8_t *key, + tSirMacAddr *bssid, + eCsrEncryptionType encr_type) { struct wlan_crypto_key *crypto_key = NULL; - uint8_t key_index = 0; QDF_STATUS status; + /* + * key index is the FW key index. + * Key_id is for host crypto component key storage index + */ + uint8_t key_index = 0; if (unicast) key_index = 0; else - key_index = 1; - crypto_key = wlan_crypto_get_key(vdev, key_index); + key_index = 2; + + crypto_key = wlan_crypto_get_key(vdev, key_id); if (!crypto_key) { crypto_key = qdf_mem_malloc(sizeof(*crypto_key)); if (!crypto_key) return QDF_STATUS_E_INVAL; - status = wlan_crypto_save_key(vdev, key_index, crypto_key); + + status = wlan_crypto_save_key(vdev, key_id, crypto_key); if (QDF_IS_STATUS_ERROR(status)) { sme_err("Failed to save key"); qdf_mem_free(crypto_key); @@ -10760,6 +11499,8 @@ static QDF_STATUS csr_roam_store_fils_key(struct wlan_objmgr_vdev *vdev, } } qdf_mem_zero(crypto_key, sizeof(*crypto_key)); + /* TODO add support for FILS cipher translation in OSIF */ + crypto_key->cipher_type = csr_encr_to_cipher_type(encr_type); crypto_key->keylen = key_length; crypto_key->keyix = key_index; sme_debug("key_len %d, unicast %d", key_length, unicast); @@ -10768,20 +11509,29 @@ static QDF_STATUS csr_roam_store_fils_key(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +#else +static inline +QDF_STATUS csr_roam_store_fils_key(struct wlan_objmgr_vdev *vdev, + bool unicast, uint8_t key_id, + uint16_t key_length, uint8_t *key, + tSirMacAddr *bssid, + eCsrEncryptionType encr_type) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif -QDF_STATUS csr_roam_issue_set_context_req_helper( - struct mac_context *mac_ctx, - uint32_t session_id, - eCsrEncryptionType encr_type, - struct bss_description *bss_descr, - tSirMacAddr *bssid, bool addkey, - bool unicast, - tAniKeyDirection key_direction, - uint8_t key_id, uint16_t key_length, - uint8_t *key, uint8_t pae_role) +QDF_STATUS +csr_issue_set_context_req_helper(struct mac_context *mac_ctx, + struct csr_roam_profile *profile, + uint32_t session_id, tSirMacAddr *bssid, + bool addkey, bool unicast, + tAniKeyDirection key_direction, uint8_t key_id, + uint16_t key_length, uint8_t *key) { enum wlan_crypto_cipher_type cipher; struct wlan_objmgr_vdev *vdev; + struct set_context_rsp install_key_rsp; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id, WLAN_LEGACY_MAC_ID); @@ -10789,681 +11539,422 @@ QDF_STATUS csr_roam_issue_set_context_req_helper( sme_err("VDEV object not found for session_id %d", session_id); return QDF_STATUS_E_INVAL; } + cipher = wlan_crypto_get_cipher(vdev, unicast, key_id); - if (cipher == WLAN_CRYPTO_CIPHER_FILS_AEAD) + if (addkey && !IS_WEP_CIPHER(cipher) && + (profile && csr_is_fils_connection(profile))) csr_roam_store_fils_key(vdev, unicast, key_id, key_length, - key, bssid); + key, bssid, + profile->negotiatedMCEncryptionType); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); - return csr_roam_issue_set_context_req(mac_ctx, session_id, addkey, - unicast, key_id); -} - -#else -static QDF_STATUS -csr_roam_issue_set_context_req(struct mac_context *mac, uint32_t sessionId, - eCsrEncryptionType EncryptType, - struct bss_description *pBssDescription, - tSirMacAddr *bssId, bool addKey, bool fUnicast, - tAniKeyDirection aniKeyDirection, uint8_t keyId, - uint16_t keyLength, uint8_t *pKey, - uint8_t paeRole) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - tAniEdType edType; - - sme_debug("sessionId: %d EncryptType: %d", sessionId, EncryptType); + /* + * For open mode authentication, send dummy install key response to + * send OBSS scan and QOS event. + */ + if (profile && + profile->negotiatedUCEncryptionType == eCSR_ENCRYPT_TYPE_NONE) { + if (unicast) + return QDF_STATUS_SUCCESS; - if (eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType) - EncryptType = eCSR_ENCRYPT_TYPE_NONE; + install_key_rsp.length = sizeof(install_key_rsp); + install_key_rsp.status_code = eSIR_SME_SUCCESS; + install_key_rsp.sessionId = session_id; + qdf_mem_copy(install_key_rsp.peer_macaddr.bytes, bssid, + QDF_MAC_ADDR_SIZE); - edType = csr_translate_encrypt_type_to_ed_type(EncryptType); + csr_roam_chk_lnk_set_ctx_rsp(mac_ctx, + (tSirSmeRsp *)&install_key_rsp); - /* - * Allow 0 keys to be set for the non-WPA encrypt types. For WPA encrypt - * types, the num keys must be non-zero or LIM will reject the set - * context (assumes the SET_CONTEXT does not occur until the keys are - * distrubuted). - */ - if (CSR_IS_ENC_TYPE_STATIC(EncryptType) || addKey) { - tCsrRoamSetKey setKey; - - setKey.encType = EncryptType; - setKey.keyDirection = aniKeyDirection; - qdf_mem_copy(&setKey.peerMac, bssId, sizeof(struct - qdf_mac_addr)); - /* 0 for supplicant */ - setKey.paeRole = paeRole; - /* Key index */ - setKey.keyId = keyId; - setKey.keyLength = keyLength; - if (keyLength) - qdf_mem_copy(setKey.Key, pKey, keyLength); - status = csr_roam_issue_set_key_command(mac, sessionId, - &setKey, 0); + return QDF_STATUS_SUCCESS; } - return status; -} -QDF_STATUS csr_roam_issue_set_context_req_helper( - struct mac_context *mac_ctx, - uint32_t session_id, - eCsrEncryptionType encr_type, - struct bss_description *bss_descr, - tSirMacAddr *bssid, bool addkey, - bool unicast, - tAniKeyDirection key_direction, - uint8_t key_id, uint16_t key_length, - uint8_t *key, uint8_t pae_role) -{ - return csr_roam_issue_set_context_req(mac_ctx, session_id, encr_type, - bss_descr, bssid, addkey, - unicast, key_direction, key_id, - key_length, key, pae_role); + return csr_roam_issue_set_context_req(mac_ctx, session_id, addkey, + unicast, key_id, + (struct qdf_mac_addr *)bssid); } -#endif -/** - * csr_update_key_cmd() - update key info in set key command - * @mac_ctx: mac global context - * @session: roam session - * @set_key: input set key command - * @set_key_cmd: set key command to update - * @is_key_valid: indicates if key is valid - * - * This function will validate the key length, adjust if too long. It will - * update is_key_valid flag to false if some error has occurred key are local. +#ifdef WLAN_FEATURE_FILS_SK +/* + * csr_create_fils_realm_hash: API to create hash using realm + * @fils_con_info: fils connection info obtained from supplicant + * @tmp_hash: pointer to new hash * - * Return: status of operation + * Return: None */ -static QDF_STATUS -csr_update_key_cmd(struct mac_context *mac_ctx, struct csr_roam_session *session, - tCsrRoamSetKey *set_key, struct setkey_cmd *set_key_cmd, - bool *is_key_valid) +static bool +csr_create_fils_realm_hash(struct cds_fils_connection_info *fils_con_info, + uint8_t *tmp_hash) { - switch (set_key->encType) { - case eCSR_ENCRYPT_TYPE_WEP40: - case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: - /* KeyLength maybe 0 for static WEP */ - if (set_key->keyLength) { - if (set_key->keyLength < WLAN_CRYPTO_KEY_WEP40_LEN) { - sme_warn("Invalid WEP40 keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } + uint8_t *hash; + uint8_t *data[1]; - set_key_cmd->keyLength = WLAN_CRYPTO_KEY_WEP40_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - WLAN_CRYPTO_KEY_WEP40_LEN); - } - *is_key_valid = true; - break; - case eCSR_ENCRYPT_TYPE_WEP104: - case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: - /* KeyLength maybe 0 for static WEP */ - if (set_key->keyLength) { - if (set_key->keyLength < WLAN_CRYPTO_KEY_WEP104_LEN) { - sme_warn("Invalid WEP104 keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } + if (!fils_con_info->realm_len) + return false; - set_key_cmd->keyLength = WLAN_CRYPTO_KEY_WEP104_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - WLAN_CRYPTO_KEY_WEP104_LEN); - } - *is_key_valid = true; - break; - case eCSR_ENCRYPT_TYPE_TKIP: - if (set_key->keyLength < CSR_TKIP_KEY_LEN) { - sme_warn("Invalid TKIP keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_TKIP_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_TKIP_KEY_LEN); - *is_key_valid = true; - break; - case eCSR_ENCRYPT_TYPE_AES: - if (set_key->keyLength < CSR_AES_KEY_LEN) { - sme_warn("Invalid AES/CCMP keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_KEY_LEN); - *is_key_valid = true; - break; - case eCSR_ENCRYPT_TYPE_AES_GCMP: - if (set_key->keyLength < CSR_AES_GCMP_KEY_LEN) { - sme_warn( - "Invalid AES_GCMP keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_GCMP_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_GCMP_KEY_LEN); - *is_key_valid = true; - break; - case eCSR_ENCRYPT_TYPE_AES_GCMP_256: - if (set_key->keyLength < CSR_AES_GCMP_256_KEY_LEN) { - sme_warn( - "Invalid AES_GCMP_256 keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_GCMP_256_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_GCMP_256_KEY_LEN); - *is_key_valid = true; - break; -#ifdef FEATURE_WLAN_WAPI - case eCSR_ENCRYPT_TYPE_WPI: - if (set_key->keyLength < CSR_WAPI_KEY_LEN) { - sme_warn("Invalid WAPI keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_WAPI_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_WAPI_KEY_LEN); - if (session->pCurRoamProfile) { - session->pCurRoamProfile->negotiatedUCEncryptionType = - eCSR_ENCRYPT_TYPE_WPI; - } else { - sme_err("pCurRoamProfile is NULL"); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - *is_key_valid = true; - break; -#endif /* FEATURE_WLAN_WAPI */ -#ifdef FEATURE_WLAN_ESE - case eCSR_ENCRYPT_TYPE_KRK: - /* no need to enqueue KRK key request, since they are local */ - *is_key_valid = false; - if (set_key->keyLength < CSR_KRK_KEY_LEN) { - sme_warn("Invalid KRK keylength [= %d]", - set_key->keyLength); - return QDF_STATUS_E_INVAL; - } - qdf_mem_copy(session->eseCckmInfo.krk, set_key->Key, - CSR_KRK_KEY_LEN); - session->eseCckmInfo.reassoc_req_num = 1; - session->eseCckmInfo.krk_plumbed = true; - break; -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - case eCSR_ENCRYPT_TYPE_BTK: - /* no need to enqueue KRK key request, since they are local */ - *is_key_valid = false; - if (set_key->keyLength < SIR_BTK_KEY_LEN) { - sme_warn("LFR3:Invalid BTK keylength [= %d]", - set_key->keyLength); - return QDF_STATUS_E_INVAL; - } - qdf_mem_copy(session->eseCckmInfo.btk, set_key->Key, - SIR_BTK_KEY_LEN); - /* - * KRK and BTK are updated by upper layer back to back. Send - * updated KRK and BTK together to FW here. - */ - csr_roam_update_cfg(mac_ctx, session->sessionId, - REASON_ROAM_PSK_PMK_CHANGED); - break; -#endif -#endif /* FEATURE_WLAN_ESE */ -#ifdef WLAN_FEATURE_11W - /* Check for 11w BIP */ - case eCSR_ENCRYPT_TYPE_AES_CMAC: - if (set_key->keyLength < CSR_AES_KEY_LEN) { - sme_warn("Invalid AES/CCMP keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_KEY_LEN); - *is_key_valid = true; - break; + hash = qdf_mem_malloc(SHA256_DIGEST_SIZE); + if (!hash) + return false; - case eCSR_ENCRYPT_TYPE_AES_GMAC_128: - if (set_key->keyLength < CSR_AES_GMAC_128_KEY_LEN) { - sme_warn("Invalid AES GMAC 128 keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_GMAC_128_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_GMAC_128_KEY_LEN); - *is_key_valid = true; - break; + data[0] = fils_con_info->realm; + qdf_get_hash(SHA256_CRYPTO_TYPE, 1, data, + &fils_con_info->realm_len, hash); + qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, + hash, SHA256_DIGEST_SIZE); + qdf_mem_copy(tmp_hash, hash, 2); + qdf_mem_free(hash); + return true; +} - case eCSR_ENCRYPT_TYPE_AES_GMAC_256: - if (set_key->keyLength < CSR_AES_GMAC_256_KEY_LEN) { - sme_warn("Invalid AES GMAC 256 keylength [= %d]", - set_key->keyLength); - *is_key_valid = false; - return QDF_STATUS_E_INVAL; - } - set_key_cmd->keyLength = CSR_AES_GMAC_256_KEY_LEN; - qdf_mem_copy(set_key_cmd->Key, set_key->Key, - CSR_AES_GMAC_256_KEY_LEN); - *is_key_valid = true; - break; +static void csr_update_fils_scan_filter(struct scan_filter *filter, + struct csr_roam_profile *profile) +{ + if (profile->fils_con_info && + profile->fils_con_info->is_fils_connection) { + uint8_t realm_hash[2]; -#endif /* WLAN_FEATURE_11W */ - default: - /* for open security also we want to enqueue command */ - *is_key_valid = true; - return QDF_STATUS_SUCCESS; - } /* end of switch */ - return QDF_STATUS_SUCCESS; + sme_debug("creating realm based on fils info %d", + profile->fils_con_info->is_fils_connection); + filter->fils_scan_filter.realm_check = + csr_create_fils_realm_hash(profile->fils_con_info, + realm_hash); + if (filter->fils_scan_filter.realm_check) + qdf_mem_copy(filter->fils_scan_filter.fils_realm, + realm_hash, REAM_HASH_LEN); + } } +#else +static void csr_update_fils_scan_filter(struct scan_filter *filter, + struct csr_roam_profile *profile) +{ } +#endif -static QDF_STATUS csr_roam_issue_set_key_command( -struct mac_context *mac_ctx, uint32_t session_id, - tCsrRoamSetKey *set_key, - uint32_t roam_id) +static inline void csr_copy_ssids(struct wlan_ssid *ssid, tSirMacSSid *from) { - QDF_STATUS status = QDF_STATUS_E_INVAL; - bool is_key_valid = true; - struct setkey_cmd set_key_cmd; -#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_WAPI) - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); + ssid->length = from->length; + if (ssid->length > WLAN_SSID_MAX_LEN) + ssid->length = WLAN_SSID_MAX_LEN; + qdf_mem_copy(ssid->ssid, from->ssId, ssid->length); +} - if (!session) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "session %d not found", session_id); - return QDF_STATUS_E_FAILURE; - } -#endif /* FEATURE_WLAN_ESE */ +void csr_copy_ssids_from_roam_params(struct roam_ext_params *roam_params, + struct scan_filter *filter) +{ + uint8_t i; - qdf_mem_zero(&set_key_cmd, sizeof(struct setkey_cmd)); - /* - * following function will validate the key length, Adjust if too long. - * for static WEP the keys are not set thru' SetContextReq - * - * it will update bool is_key_valid, to false if some error has occurred - * key are local. enqueue sme command only if is_key_valid is true - * status is indication of success or failure and will be returned to - * called of current function if command is not enqueued due to key req - * being local - */ - status = csr_update_key_cmd(mac_ctx, session, set_key, - &set_key_cmd, &is_key_valid); - if (is_key_valid) { - set_key_cmd.roamId = roam_id; - set_key_cmd.encType = set_key->encType; - set_key_cmd.keyDirection = set_key->keyDirection; - qdf_copy_macaddr(&set_key_cmd.peermac, - &set_key->peerMac); - /* 0 for supplicant */ - set_key_cmd.paeRole = set_key->paeRole; - set_key_cmd.keyId = set_key->keyId; - qdf_mem_copy(set_key_cmd.keyRsc, set_key->keyRsc, - WLAN_CRYPTO_RSC_SIZE); - /* - * Always put set key to the head of the Q because it is the - * only thing to get executed in case of WT_KEY state - */ - sme_debug("set key req for session-%d authtype-%d", - session_id, set_key->encType); - status = csr_roam_send_set_key_cmd(mac_ctx, session_id, - &set_key_cmd); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("fail to send message status = %d", status); - } - return status; + if (!roam_params->num_ssid_allowed_list) + return; + + filter->num_of_ssid = roam_params->num_ssid_allowed_list; + if (filter->num_of_ssid > WLAN_SCAN_FILTER_NUM_SSID) + filter->num_of_ssid = WLAN_SCAN_FILTER_NUM_SSID; + for (i = 0; i < filter->num_of_ssid; i++) + csr_copy_ssids(&filter->ssid_list[i], + &roam_params->ssid_allowed_list[i]); } -QDF_STATUS csr_roam_send_set_key_cmd(struct mac_context *mac_ctx, - uint32_t session_id, - struct setkey_cmd *set_key_cmd) +static void csr_copy_ssids_from_profile(tCsrSSIDs *ssid_list, + struct scan_filter *filter) { - QDF_STATUS status; - uint8_t num_keys = (set_key_cmd->keyLength) ? 1 : 0; - tAniEdType ed_type = csr_translate_encrypt_type_to_ed_type( - set_key_cmd->encType); - bool unicast = (set_key_cmd->peermac.bytes[0] == 0xFF) ? false : true; -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params; - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - - WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent, - host_event_wlan_security_payload_type); + uint8_t i; - if (!session) { - sme_err("session %d not found", session_id); - return QDF_STATUS_E_FAILURE; - } + filter->num_of_ssid = ssid_list->numOfSSIDs; + if (filter->num_of_ssid > WLAN_SCAN_FILTER_NUM_SSID) + filter->num_of_ssid = WLAN_SCAN_FILTER_NUM_SSID; + for (i = 0; i < filter->num_of_ssid; i++) + csr_copy_ssids(&filter->ssid_list[i], + &ssid_list->SSIDList[i].SSID); +} - if (eSIR_ED_NONE != ed_type) { - qdf_mem_zero(&setKeyEvent, - sizeof(host_event_wlan_security_payload_type)); - if (qdf_is_macaddr_group(&set_key_cmd->peermac)) { - setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_BCAST_REQ; - setKeyEvent.encryptionModeMulticast = - (uint8_t) diag_enc_type_from_csr_type( - set_key_cmd->encType); - setKeyEvent.encryptionModeUnicast = - (uint8_t) diag_enc_type_from_csr_type(session-> - connectedProfile. - EncryptionType); - } else { - setKeyEvent.eventId = - WLAN_SECURITY_EVENT_SET_UNICAST_REQ; - setKeyEvent.encryptionModeUnicast = - (uint8_t) diag_enc_type_from_csr_type( - set_key_cmd->encType); - setKeyEvent.encryptionModeMulticast = - (uint8_t) diag_enc_type_from_csr_type(session-> - connectedProfile. - mcEncryptionType); - } - qdf_mem_copy(setKeyEvent.bssid, - session->connectedProfile.bssid.bytes, - QDF_MAC_ADDR_SIZE); - if (CSR_IS_ENC_TYPE_STATIC(set_key_cmd->encType)) { - /* It has to be static WEP here */ - setKeyEvent.keyId = wep_params->wep_default_key_id; - } else { - setKeyEvent.keyId = set_key_cmd->keyId; - } - setKeyEvent.authMode = - (uint8_t) diag_auth_type_from_csr_type(session-> - connectedProfile. - AuthType); - WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); - } -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - if (csr_is_set_key_allowed(mac_ctx, session_id)) { - status = csr_send_mb_set_context_req_msg(mac_ctx, session_id, - set_key_cmd->peermac, - num_keys, ed_type, unicast, - set_key_cmd->keyDirection, - set_key_cmd->keyId, - set_key_cmd->keyLength, - set_key_cmd->Key, - set_key_cmd->paeRole, - set_key_cmd->keyRsc); - } else { - sme_warn(" cannot process not connected"); - /* Set this status so the error handling take - * care of the case. - */ - status = QDF_STATUS_CSR_WRONG_STATE; - } - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_err(" error status %d", status); - csr_roam_call_callback(mac_ctx, session_id, NULL, - set_key_cmd->roamId, - eCSR_ROAM_SET_KEY_COMPLETE, - eCSR_ROAM_RESULT_FAILURE); -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - if (eSIR_ED_NONE != ed_type) { - if (qdf_is_macaddr_group(&set_key_cmd->peermac)) - setKeyEvent.eventId = - WLAN_SECURITY_EVENT_SET_BCAST_RSP; - else - setKeyEvent.eventId = - WLAN_SECURITY_EVENT_SET_UNICAST_RSP; - setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; - WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, - EVENT_WLAN_SECURITY); - } -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - } - return status; +#ifdef WLAN_ADAPTIVE_11R +static void +csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx, + struct scan_filter *filter) +{ + filter->enable_adaptive_11r = + mac_ctx->mlme_cfg->lfr.enable_adaptive_11r; +} +#else +static inline void +csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx, + struct scan_filter *filter) +{ + filter->enable_adaptive_11r = false; } +#endif -QDF_STATUS csr_roam_set_key(struct mac_context *mac, uint32_t sessionId, - tCsrRoamSetKey *pSetKey, uint32_t roamId) +void csr_update_connect_n_roam_cmn_filter(struct mac_context *mac_ctx, + struct scan_filter *filter, + enum QDF_OPMODE opmode) { + enum policy_mgr_con_mode pm_mode; + uint32_t num_entries = 0, pcl_freq_list[NUM_CHANNELS] = {0}; QDF_STATUS status; - if (!csr_is_set_key_allowed(mac, sessionId)) { - status = QDF_STATUS_CSR_WRONG_STATE; - } else { - status = csr_roam_issue_set_key_command(mac, sessionId, - pSetKey, roamId); + /* enable bss scoring for only STA mode */ + if (opmode == QDF_STA_MODE) + filter->bss_scoring_required = true; + + csr_update_adaptive_11r_scan_filter(mac_ctx, filter); + + if (filter->num_of_bssid) + return; + + if (policy_mgr_map_concurrency_mode(&opmode, &pm_mode)) { + status = policy_mgr_get_pcl(mac_ctx->psoc, pm_mode, + pcl_freq_list, &num_entries, + filter->pcl_weight_list, + NUM_CHANNELS); + if (QDF_IS_STATUS_ERROR(status)) + return; + qdf_mem_copy(filter->pcl_freq_list, pcl_freq_list, + num_entries * sizeof(pcl_freq_list[0])); + filter->num_of_pcl_channels = num_entries; } - return status; } -#ifdef WLAN_FEATURE_FILS_SK -/* - * csr_create_fils_realm_hash: API to create hash using realm - * @fils_con_info: fils connection info obtained from supplicant - * @tmp_hash: pointer to new hash +#ifdef FEATURE_WLAN_WAPI +/** + * csr_update_phy_mode: Updates phy mode for wapi + * @profile: Source profile + * @phy_mode: phy_mode to be modified * * Return: None */ -static bool -csr_create_fils_realm_hash(struct cds_fils_connection_info *fils_con_info, - uint8_t *tmp_hash) +static void csr_update_phy_mode(struct csr_roam_profile *profile, + uint32_t *phy_mode) { - uint8_t *hash; - uint8_t *data[1]; + /* + * check if user asked for WAPI with 11n or auto mode, in that + * case modify the phymode to 11g + */ + if (csr_is_profile_wapi(profile)) { + if (*phy_mode & eCSR_DOT11_MODE_11n) + *phy_mode &= ~eCSR_DOT11_MODE_11n; + if (*phy_mode & eCSR_DOT11_MODE_AUTO) + *phy_mode &= ~eCSR_DOT11_MODE_AUTO; + if (!*phy_mode) + *phy_mode = eCSR_DOT11_MODE_11g; + } +} +#else +static inline +void csr_update_phy_mode(struct csr_roam_profile *profile, uint32_t *phy_mode) +{} +#endif - if (!fils_con_info->realm_len) - return false; +/** + * csr_convert_dotllmod_phymode: Convert eCsrPhyMode to wlan_phymode + * @dotllmode: phy mode + * + * Return: returns enum wlan_phymode + */ +static enum wlan_phymode csr_convert_dotllmod_phymode(eCsrPhyMode dotllmode) +{ + enum wlan_phymode con_phy_mode; - hash = qdf_mem_malloc(SHA256_DIGEST_SIZE); - if (!hash) - return false; + switch (dotllmode) { + case eCSR_DOT11_MODE_abg: + con_phy_mode = WLAN_PHYMODE_AUTO; + break; + case eCSR_DOT11_MODE_11a: + con_phy_mode = WLAN_PHYMODE_11A; + break; + case eCSR_DOT11_MODE_11b: + con_phy_mode = WLAN_PHYMODE_11B; + break; + case eCSR_DOT11_MODE_11g: + con_phy_mode = WLAN_PHYMODE_11G; + break; + case eCSR_DOT11_MODE_11n: + con_phy_mode = WLAN_PHYMODE_11NA_HT20; + break; + case eCSR_DOT11_MODE_11g_ONLY: + con_phy_mode = WLAN_PHYMODE_11G; + break; + case eCSR_DOT11_MODE_11n_ONLY: + con_phy_mode = WLAN_PHYMODE_11NA_HT20; + break; + case eCSR_DOT11_MODE_11b_ONLY: + con_phy_mode = WLAN_PHYMODE_11B; + break; + case eCSR_DOT11_MODE_11ac: + con_phy_mode = WLAN_PHYMODE_11AC_VHT160; + break; + case eCSR_DOT11_MODE_11ac_ONLY: + con_phy_mode = WLAN_PHYMODE_11AC_VHT160; + break; + case eCSR_DOT11_MODE_AUTO: + con_phy_mode = WLAN_PHYMODE_AUTO; + break; + case eCSR_DOT11_MODE_11ax: + con_phy_mode = WLAN_PHYMODE_11AXA_HE160; + break; + case eCSR_DOT11_MODE_11ax_ONLY: + con_phy_mode = WLAN_PHYMODE_11AXA_HE160; + break; + default: + con_phy_mode = WLAN_PHYMODE_AUTO; + break; + } - data[0] = fils_con_info->realm; - qdf_get_hash(SHA256_CRYPTO_TYPE, 1, data, - &fils_con_info->realm_len, hash); - qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - hash, SHA256_DIGEST_SIZE); - qdf_mem_copy(tmp_hash, hash, 2); - qdf_mem_free(hash); - return true; + return con_phy_mode; } -/* - * csr_update_fils_scan_filter: update scan filter in case of fils session - * @scan_fltr: pointer to scan filer - * @profile: csr profile pointer +#ifdef WLAN_FEATURE_11W + +/** + * csr_update_pmf_cap_from_profile: Updates PMF cap + * @profile: Source profile + * @filter: scan filter * * Return: None */ -static void csr_update_fils_scan_filter(tCsrScanResultFilter *scan_fltr, - struct csr_roam_profile *profile) +static void csr_update_pmf_cap_from_profile(struct csr_roam_profile *profile, + struct scan_filter *filter) { - if (profile->fils_con_info && - profile->fils_con_info->is_fils_connection) { - uint8_t realm_hash[2]; - - sme_debug("creating realm based on fils info %d", - profile->fils_con_info->is_fils_connection); - scan_fltr->realm_check = csr_create_fils_realm_hash( - profile->fils_con_info, realm_hash); - memcpy(scan_fltr->fils_realm, realm_hash, - sizeof(uint8_t) * 2); - } - + if (profile->MFPCapable || profile->MFPEnabled) + filter->pmf_cap = WLAN_PMF_CAPABLE; + if (profile->MFPRequired) + filter->pmf_cap = WLAN_PMF_REQUIRED; } #else -static void csr_update_fils_scan_filter(tCsrScanResultFilter *scan_fltr, - struct csr_roam_profile *profile) -{ } +static inline +void csr_update_pmf_cap_from_profile(struct csr_roam_profile *profile, + struct scan_filter *filter) +{} #endif -/* - * Prepare a filter base on a profile for parsing the scan results. - * Upon successful return, caller MUST call csr_free_scan_filter on - *pScanFilter when it is done with the filter. - */ QDF_STATUS -csr_roam_prepare_filter_from_profile(struct mac_context *mac_ctx, - struct csr_roam_profile *profile, - tCsrScanResultFilter *scan_fltr) +csr_roam_get_scan_filter_from_profile(struct mac_context *mac_ctx, + struct csr_roam_profile *profile, + struct scan_filter *filter, + bool is_roam) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t size = 0; - uint8_t idx = 0; - tCsrChannelInfo *fltr_ch_info = &scan_fltr->ChannelInfo; - tCsrChannelInfo *profile_ch_info = &profile->ChannelInfo; + tCsrChannelInfo *ch_info; struct roam_ext_params *roam_params; uint8_t i; + uint32_t phy_mode; + if (!filter || !profile) { + sme_err("filter or profile is NULL"); + return QDF_STATUS_E_FAILURE; + } roam_params = &mac_ctx->roam.configParam.roam_params; + qdf_mem_zero(filter, sizeof(*filter)); if (profile->BSSIDs.numOfBSSIDs) { - size = sizeof(struct qdf_mac_addr) * profile->BSSIDs. - numOfBSSIDs; - scan_fltr->BSSIDs.bssid = qdf_mem_malloc(size); - if (!scan_fltr->BSSIDs.bssid) { - status = QDF_STATUS_E_NOMEM; - goto free_filter; - } - scan_fltr->BSSIDs.numOfBSSIDs = profile->BSSIDs.numOfBSSIDs; - qdf_mem_copy(scan_fltr->BSSIDs.bssid, - profile->BSSIDs.bssid, size); + filter->num_of_bssid = profile->BSSIDs.numOfBSSIDs; + if (filter->num_of_bssid > WLAN_SCAN_FILTER_NUM_BSSID) + filter->num_of_bssid = WLAN_SCAN_FILTER_NUM_BSSID; + for (i = 0; i < filter->num_of_bssid; i++) + qdf_mem_copy(filter->bssid_list[i].bytes, + profile->BSSIDs.bssid[i].bytes, + QDF_MAC_ADDR_SIZE); } if (profile->SSIDs.numOfSSIDs) { - scan_fltr->SSIDs.numOfSSIDs = profile->SSIDs.numOfSSIDs; - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - ("No of Allowed List:%d"), - roam_params->num_ssid_allowed_list); - if (scan_fltr->scan_filter_for_roam - && roam_params->num_ssid_allowed_list) { - scan_fltr->SSIDs.numOfSSIDs = - roam_params->num_ssid_allowed_list; - size = sizeof(tCsrSSIDInfo) * - scan_fltr->SSIDs.numOfSSIDs; - scan_fltr->SSIDs.SSIDList = qdf_mem_malloc(size); - if (!scan_fltr->SSIDs.SSIDList) - status = QDF_STATUS_E_FAILURE; - else - status = QDF_STATUS_SUCCESS; - if (!QDF_IS_STATUS_SUCCESS(status)) - goto free_filter; - for (i = 0; - i < roam_params->num_ssid_allowed_list; - i++) { - qdf_mem_copy((void *) - scan_fltr->SSIDs.SSIDList[i].SSID.ssId, - roam_params->ssid_allowed_list[i].ssId, - roam_params->ssid_allowed_list[i].length); - scan_fltr->SSIDs.SSIDList[i].SSID.length = - roam_params->ssid_allowed_list[i].length; - scan_fltr->SSIDs.SSIDList[i].handoffPermitted = - 1; - scan_fltr->SSIDs.SSIDList[i].ssidHidden = 0; - } - } else { - size = sizeof(tCsrSSIDInfo) * - profile->SSIDs.numOfSSIDs; - scan_fltr->SSIDs.SSIDList = qdf_mem_malloc(size); - if (!scan_fltr->SSIDs.SSIDList) { - status = QDF_STATUS_E_NOMEM; - goto free_filter; - } - qdf_mem_copy(scan_fltr->SSIDs.SSIDList, - profile->SSIDs.SSIDList, size); - } + if (is_roam && roam_params->num_ssid_allowed_list) + csr_copy_ssids_from_roam_params(roam_params, filter); + else + csr_copy_ssids_from_profile(&profile->SSIDs, filter); } - if (!profile_ch_info->ChannelList - || (profile_ch_info->ChannelList[0] == 0)) { - fltr_ch_info->numOfChannels = 0; - fltr_ch_info->ChannelList = NULL; - } else if (profile_ch_info->numOfChannels) { - fltr_ch_info->numOfChannels = 0; - fltr_ch_info->ChannelList = - qdf_mem_malloc(sizeof(*(fltr_ch_info->ChannelList)) * - profile_ch_info->numOfChannels); - if (!fltr_ch_info->ChannelList) { - status = QDF_STATUS_E_NOMEM; - goto free_filter; - } - - for (idx = 0; idx < profile_ch_info->numOfChannels; idx++) { + ch_info = &profile->ChannelInfo; + if (ch_info->numOfChannels && ch_info->freq_list && + ch_info->freq_list[0]) { + filter->num_of_channels = 0; + for (i = 0; i < ch_info->numOfChannels; i++) { + if (filter->num_of_channels >= NUM_CHANNELS) { + sme_err("max allowed channel(%d) reached", + filter->num_of_channels); + break; + } if (csr_roam_is_channel_valid(mac_ctx, - profile_ch_info->ChannelList[idx])) { - fltr_ch_info-> - ChannelList[fltr_ch_info->numOfChannels] - = profile_ch_info->ChannelList[idx]; - fltr_ch_info->numOfChannels++; + ch_info->freq_list[i])) { + filter->chan_freq_list[filter->num_of_channels] = + ch_info->freq_list[i]; + filter->num_of_channels++; } else { - sme_debug( - "Channel (%d) is invalid", - profile_ch_info->ChannelList[idx]); + sme_debug("freq (%d) is invalid", + ch_info->freq_list[i]); } } - } else { - sme_err("Channel list empty"); - status = QDF_STATUS_E_FAILURE; - goto free_filter; - } - scan_fltr->uapsd_mask = profile->uapsd_mask; - scan_fltr->authType = profile->AuthType; - scan_fltr->EncryptionType = profile->EncryptionType; - scan_fltr->mcEncryptionType = profile->mcEncryptionType; - scan_fltr->BSSType = profile->BSSType; - scan_fltr->phyMode = profile->phyMode; -#ifdef FEATURE_WLAN_WAPI - /* - * check if user asked for WAPI with 11n or auto mode, in that - * case modify the phymode to 11g - */ - if (csr_is_profile_wapi(profile)) { - if (scan_fltr->phyMode & eCSR_DOT11_MODE_11n) - scan_fltr->phyMode &= ~eCSR_DOT11_MODE_11n; - if (scan_fltr->phyMode & eCSR_DOT11_MODE_AUTO) - scan_fltr->phyMode &= ~eCSR_DOT11_MODE_AUTO; - if (!scan_fltr->phyMode) - scan_fltr->phyMode = eCSR_DOT11_MODE_11g; } -#endif /* FEATURE_WLAN_WAPI */ - /*Save the WPS info */ - scan_fltr->bWPSAssociation = profile->bWPSAssociation; - scan_fltr->bOSENAssociation = profile->bOSENAssociation; - if (profile->countryCode[0]) { + + if (profile->force_rsne_override) { + sme_debug("force_rsne_override set auth type and enctype to any and ignore pmf cap"); + filter->num_of_auth = 1; + filter->auth_type[0] = WLAN_AUTH_TYPE_ANY; + filter->num_of_enc_type = 1; + filter->enc_type[0] = WLAN_ENCRYPT_TYPE_ANY; + filter->num_of_mc_enc_type = 1; + filter->mc_enc_type[0] = WLAN_ENCRYPT_TYPE_ANY; + + filter->ignore_pmf_cap = true; + } else { + filter->num_of_auth = + profile->AuthType.numEntries; + if (filter->num_of_auth > WLAN_NUM_OF_SUPPORT_AUTH_TYPE) + filter->num_of_auth = WLAN_NUM_OF_SUPPORT_AUTH_TYPE; + for (i = 0; i < filter->num_of_auth; i++) + filter->auth_type[i] = + csr_covert_auth_type_new( + profile->AuthType.authType[i]); + filter->num_of_enc_type = + profile->EncryptionType.numEntries; + if (filter->num_of_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE) + filter->num_of_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE; + for (i = 0; i < filter->num_of_enc_type; i++) + filter->enc_type[i] = + csr_covert_enc_type_new( + profile->EncryptionType.encryptionType[i]); + filter->num_of_mc_enc_type = + profile->mcEncryptionType.numEntries; + if (filter->num_of_mc_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE) + filter->num_of_mc_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE; + for (i = 0; i < filter->num_of_mc_enc_type; i++) + filter->mc_enc_type[i] = + csr_covert_enc_type_new( + profile->mcEncryptionType.encryptionType[i]); + } + + if (profile->BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE) + filter->bss_type = WLAN_TYPE_BSS; + else if (profile->BSSType == eCSR_BSS_TYPE_IBSS || + profile->BSSType == eCSR_BSS_TYPE_START_IBSS) + filter->bss_type = WLAN_TYPE_IBSS; + else + filter->bss_type = WLAN_TYPE_ANY; + + phy_mode = profile->phyMode; + csr_update_phy_mode(profile, &phy_mode); + + filter->dot11_mode = csr_convert_dotllmod_phymode(phy_mode); + if (profile->bWPSAssociation || profile->bOSENAssociation) + filter->ignore_auth_enc_type = true; + if (profile->countryCode[0]) /* * This causes the matching function to use countryCode as one * of the criteria. */ - qdf_mem_copy(scan_fltr->countryCode, profile->countryCode, + qdf_mem_copy(filter->country, profile->countryCode, CFG_COUNTRY_CODE_LEN); - } - scan_fltr->mdid = profile->mdid; - qdf_mem_copy(scan_fltr->bssid_hint.bytes, - profile->bssid_hint.bytes, QDF_MAC_ADDR_SIZE); -#ifdef WLAN_FEATURE_11W - /* Management Frame Protection */ - scan_fltr->MFPEnabled = profile->MFPEnabled; - scan_fltr->MFPRequired = profile->MFPRequired; - scan_fltr->MFPCapable = profile->MFPCapable; -#endif - scan_fltr->csrPersona = profile->csrPersona; - csr_update_fils_scan_filter(scan_fltr, profile); - scan_fltr->force_rsne_override = profile->force_rsne_override; + filter->mobility_domain = profile->mdid.mobility_domain; + qdf_mem_copy(filter->bssid_hint.bytes, profile->bssid_hint.bytes, + QDF_MAC_ADDR_SIZE); -free_filter: - if (!QDF_IS_STATUS_SUCCESS(status)) - csr_free_scan_filter(mac_ctx, scan_fltr); + csr_update_pmf_cap_from_profile(profile, filter); - return status; + csr_update_fils_scan_filter(filter, profile); + + csr_update_connect_n_roam_cmn_filter(mac_ctx, filter, + profile->csrPersona); + + return QDF_STATUS_SUCCESS; } static @@ -11473,6 +11964,12 @@ bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId { bool fCommandQueued = false; tSmeCmd *pCommand; + struct qdf_mac_addr peer_mac; + struct csr_roam_session *session; + + session = CSR_GET_SESSION(mac, sessionId); + if (!session) + return false; do { /* Validate the type is ok... */ @@ -11491,19 +11988,31 @@ bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId sessionId); } pCommand->command = eSmeCommandWmStatusChange; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.wmStatusChangeCmd.Type = Type; if (eCsrDisassociated == Type) { qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u. DisassocIndMsg, pSmeRsp, sizeof(pCommand->u.wmStatusChangeCmd.u. DisassocIndMsg)); + qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd. + u.DisassocIndMsg.peer_macaddr, + QDF_MAC_ADDR_SIZE); + } else { qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u. DeauthIndMsg, pSmeRsp, sizeof(pCommand->u.wmStatusChangeCmd.u. DeauthIndMsg)); + qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd. + u.DeauthIndMsg.peer_macaddr, + QDF_MAC_ADDR_SIZE); } + + if (CSR_IS_INFRA_AP(&session->connectedProfile)) + csr_roam_issue_disconnect_stats(mac, sessionId, + peer_mac); + if (QDF_IS_STATUS_SUCCESS (csr_queue_sme_command(mac, pCommand, false))) fCommandQueued = true; @@ -11518,55 +12027,6 @@ bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId return fCommandQueued; } -static QDF_STATUS csr_send_snr_request(void *pGetRssiReq) -{ - void *wma_handle; - - wma_handle = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma_handle) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "wma_handle is NULL"); - return QDF_STATUS_E_FAILURE; - } - - if (QDF_STATUS_SUCCESS != - wma_send_snr_request(wma_handle, pGetRssiReq)) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "Failed to Trigger wma stats request"); - return QDF_STATUS_E_FAILURE; - } - - /* dont send success, otherwise call back - * will released with out values - */ - return QDF_STATUS_E_BUSY; -} - -static void csr_update_rssi(struct mac_context *mac, void *pMsg) -{ - int8_t rssi = 0; - tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsg; - QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - - if (pGetRssiReq) { - qdf_status = csr_send_snr_request(pGetRssiReq); - - if (pGetRssiReq->rssiCallback) { - if (qdf_status != QDF_STATUS_E_BUSY) - ((tCsrRssiCallback) (pGetRssiReq->rssiCallback)) - (rssi, pGetRssiReq->staId, - pGetRssiReq->pDevContext); - else - sme_debug("rssi request is posted. waiting for reply"); - } else { - sme_err("GetRssiReq->rssiCallback is NULL"); - return; - } - } else - sme_err("pGetRssiReq is NULL"); - -} - static void csr_update_snr(struct mac_context *mac, void *pMsg) { tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg; @@ -11601,8 +12061,8 @@ static QDF_STATUS csr_send_reset_ap_caps_changed(struct mac_context *mac, pMsg->length = len; qdf_copy_macaddr(&pMsg->bssId, bssId); sme_debug( - "CSR reset caps change for Bssid= " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pMsg->bssId.bytes)); + "CSR reset caps change for Bssid= " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pMsg->bssId.bytes)); status = umac_send_mb_message_to_mac(pMsg); } else { sme_err("Memory allocation failed"); @@ -11716,1279 +12176,1006 @@ csr_convert_csr_to_ani_akm_type(enum csr_akm_type akm_type) return ANI_AKM_TYPE_OSEN; default: ani_akm = ANI_AKM_TYPE_UNKNOWN; - } - - if (ani_akm == ANI_AKM_TYPE_UNKNOWN) - ani_akm = csr_convert_sae_akm_to_ani(akm_type); - - if (ani_akm == ANI_AKM_TYPE_UNKNOWN) - ani_akm = csr_convert_ese_akm_to_ani(akm_type); - - return ani_akm; -} - -/** - * csr_translate_akm_type() - Convert ani_akm_type value to equivalent - * enum csr_akm_type - * @akm_type: value of type ani_akm_type - * - * Return: enum csr_akm_type value - */ -static enum csr_akm_type csr_translate_akm_type(enum ani_akm_type akm_type) -{ - enum csr_akm_type csr_akm_type; - - switch (akm_type) - { - case ANI_AKM_TYPE_NONE: - csr_akm_type = eCSR_AUTH_TYPE_NONE; - break; -#ifdef WLAN_FEATURE_SAE - case ANI_AKM_TYPE_SAE: - csr_akm_type = eCSR_AUTH_TYPE_SAE; - break; -#endif - case ANI_AKM_TYPE_WPA: - csr_akm_type = eCSR_AUTH_TYPE_WPA; - break; - case ANI_AKM_TYPE_WPA_PSK: - csr_akm_type = eCSR_AUTH_TYPE_WPA_PSK; - break; - case ANI_AKM_TYPE_RSN: - csr_akm_type = eCSR_AUTH_TYPE_RSN; - break; - case ANI_AKM_TYPE_RSN_PSK: - csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK; - break; - case ANI_AKM_TYPE_FT_RSN: - csr_akm_type = eCSR_AUTH_TYPE_FT_RSN; - break; - case ANI_AKM_TYPE_FT_RSN_PSK: - csr_akm_type = eCSR_AUTH_TYPE_FT_RSN_PSK; - break; -#ifdef FEATURE_WLAN_ESE - case ANI_AKM_TYPE_CCKM: - csr_akm_type = eCSR_AUTH_TYPE_CCKM_RSN; - break; -#endif - case ANI_AKM_TYPE_RSN_PSK_SHA256: - csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; - break; - case ANI_AKM_TYPE_RSN_8021X_SHA256: - csr_akm_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; - break; - case ANI_AKM_TYPE_FILS_SHA256: - csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA256; - break; - case ANI_AKM_TYPE_FILS_SHA384: - csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA384; - break; - case ANI_AKM_TYPE_FT_FILS_SHA256: - csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA256; - break; - case ANI_AKM_TYPE_FT_FILS_SHA384: - csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA384; - break; - case ANI_AKM_TYPE_DPP_RSN: - csr_akm_type = eCSR_AUTH_TYPE_DPP_RSN; - break; - case ANI_AKM_TYPE_OWE: - csr_akm_type = eCSR_AUTH_TYPE_OWE; - break; - case ANI_AKM_TYPE_SUITEB_EAP_SHA256: - csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256; - break; - case ANI_AKM_TYPE_SUITEB_EAP_SHA384: - csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384; - break; - case ANI_AKM_TYPE_OSEN: - csr_akm_type = eCSR_AUTH_TYPE_OSEN; - break; - default: - csr_akm_type = eCSR_AUTH_TYPE_UNKNOWN; - } - - return csr_akm_type; -} - -static bool csr_is_sae_akm_present(tDot11fIERSN * const rsn_ie) -{ - uint16_t i; - - if (rsn_ie->akm_suite_cnt > 6) { - sme_debug("Invalid akm_suite_cnt in Rx RSN IE"); - return false; - } - - for (i = 0; i < rsn_ie->akm_suite_cnt; i++) { - if (LE_READ_4(rsn_ie->akm_suite[i]) == RSN_AUTH_KEY_MGMT_SAE) { - sme_debug("SAE AKM present"); - return true; - } - } - return false; -} - -static bool csr_is_sae_peer_allowed(struct mac_context *mac_ctx, - struct assoc_ind *assoc_ind, - struct csr_roam_session *session, - tSirMacAddr peer_mac_addr, - tDot11fIERSN *rsn_ie, - enum mac_status_code *mac_status_code) -{ - bool is_allowed = false; - - /* Allow the peer if it's SAE authenticated */ - if (assoc_ind->is_sae_authenticated) - return true; - - /* Allow the peer with valid PMKID */ - if (!rsn_ie->pmkid_count) { - *mac_status_code = eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; - sme_debug("No PMKID present in RSNIE; Tried to use SAE AKM after non-SAE authentication"); - } else if (csr_is_pmkid_found_for_peer(mac_ctx, session, peer_mac_addr, - &rsn_ie->pmkid[0][0], - rsn_ie->pmkid_count)) { - sme_debug("Valid PMKID found for SAE peer"); - is_allowed = true; - } else { - *mac_status_code = eSIR_MAC_INVALID_PMKID; - sme_debug("No valid PMKID found for SAE peer"); - } - - return is_allowed; -} - -static QDF_STATUS -csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac, - struct assoc_ind *ind, - QDF_STATUS status, - uint8_t vdev_id) -{ - struct scheduler_msg msg = {0}; - tSirSmeAssocIndToUpperLayerCnf *cnf; - - cnf = qdf_mem_malloc(sizeof(*cnf)); - if (!cnf) - return QDF_STATUS_E_NOMEM; - - cnf->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF; - cnf->length = sizeof(*cnf); - cnf->sessionId = vdev_id; - - if (QDF_IS_STATUS_SUCCESS(status)) - cnf->status_code = eSIR_SME_SUCCESS; - else - cnf->status_code = eSIR_SME_ASSOC_REFUSED; - qdf_mem_copy(&cnf->bssId, &ind->bssId, sizeof(cnf->bssId)); - qdf_mem_copy(&cnf->peerMacAddr, &ind->peerMacAddr, - sizeof(cnf->peerMacAddr)); - cnf->aid = ind->staId; - cnf->wmmEnabledSta = ind->wmmEnabledSta; - cnf->rsnIE = ind->rsnIE; -#ifdef FEATURE_WLAN_WAPI - cnf->wapiIE = ind->wapiIE; -#endif - cnf->addIE = ind->addIE; - cnf->reassocReq = ind->reassocReq; - cnf->timingMeasCap = ind->timingMeasCap; - cnf->chan_info = ind->chan_info; - cnf->ampdu = ind->ampdu; - cnf->sgi_enable = ind->sgi_enable; - cnf->tx_stbc = ind->tx_stbc; - cnf->ch_width = ind->ch_width; - cnf->mode = ind->mode; - cnf->rx_stbc = ind->rx_stbc; - cnf->max_supp_idx = ind->max_supp_idx; - cnf->max_ext_idx = ind->max_ext_idx; - cnf->max_mcs_idx = ind->max_mcs_idx; - cnf->rx_mcs_map = ind->rx_mcs_map; - cnf->tx_mcs_map = ind->tx_mcs_map; - cnf->ecsa_capable = ind->ecsa_capable; - if (ind->HTCaps.present) - cnf->ht_caps = ind->HTCaps; - if (ind->VHTCaps.present) - cnf->vht_caps = ind->VHTCaps; - cnf->capability_info = ind->capability_info; - cnf->he_caps_present = ind->he_caps_present; - if (ind->assocReqPtr) { - if (ind->assocReqLength < MAX_ASSOC_REQ_IE_LEN) { - cnf->ies = qdf_mem_malloc(ind->assocReqLength); - if (!cnf->ies) { - qdf_mem_free(cnf); - return QDF_STATUS_E_NOMEM; - } - cnf->ies_len = ind->assocReqLength; - qdf_mem_copy(cnf->ies, ind->assocReqPtr, - cnf->ies_len); - } else { - sme_err("Assoc Ie length is too long"); - } - } - - msg.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; - msg.bodyptr = cnf; - sys_process_mmh_msg(mac, &msg); - - return QDF_STATUS_SUCCESS; -} - -static void -csr_roam_chk_lnk_assoc_ind_upper_layer( - struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) -{ - uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; - struct assoc_ind *assoc_ind; - QDF_STATUS status; - - assoc_ind = (struct assoc_ind *)msg_ptr; - status = csr_roam_get_session_id_from_bssid( - mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId, - &session_id); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_debug("Couldn't find session_id for given BSSID"); - return; - } - csr_send_assoc_ind_to_upper_layer_cnf_msg( - mac_ctx, assoc_ind, status, session_id); -} - -static void -csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) -{ - struct csr_roam_session *session; - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; - QDF_STATUS status; - struct csr_roam_info *roam_info; - struct assoc_ind *pAssocInd; - enum mac_status_code mac_status_code = eSIR_MAC_SUCCESS_STATUS; - enum csr_akm_type csr_akm_type; - - sme_debug("Receive WNI_SME_ASSOC_IND from SME"); - pAssocInd = (struct assoc_ind *) msg_ptr; - status = csr_roam_get_session_id_from_bssid(mac_ctx, - (struct qdf_mac_addr *) pAssocInd->bssId, - &sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_debug("Couldn't find session_id for given BSSID"); - return; - } - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", sessionId); - return; - } - csr_akm_type = csr_translate_akm_type(pAssocInd->akm_type); - - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - /* Required for indicating the frames to upper layer */ - roam_info->assocReqLength = pAssocInd->assocReqLength; - roam_info->assocReqPtr = pAssocInd->assocReqPtr; - roam_info->beaconPtr = pAssocInd->beaconPtr; - roam_info->beaconLength = pAssocInd->beaconLength; - roam_info->status_code = eSIR_SME_SUCCESS; - roam_info->u.pConnectedProfile = &session->connectedProfile; - roam_info->staId = (uint8_t)pAssocInd->staId; - roam_info->rsnIELen = (uint8_t)pAssocInd->rsnIE.length; - roam_info->prsnIE = pAssocInd->rsnIE.rsnIEdata; -#ifdef FEATURE_WLAN_WAPI - roam_info->wapiIELen = (uint8_t)pAssocInd->wapiIE.length; - roam_info->pwapiIE = pAssocInd->wapiIE.wapiIEdata; -#endif - roam_info->addIELen = (uint8_t)pAssocInd->addIE.length; - roam_info->paddIE = pAssocInd->addIE.addIEdata; - qdf_mem_copy(roam_info->peerMac.bytes, - pAssocInd->peerMacAddr, - sizeof(tSirMacAddr)); - qdf_mem_copy(roam_info->bssid.bytes, - pAssocInd->bssId, - sizeof(struct qdf_mac_addr)); - roam_info->wmmEnabledSta = pAssocInd->wmmEnabledSta; - roam_info->timingMeasCap = pAssocInd->timingMeasCap; - roam_info->ecsa_capable = pAssocInd->ecsa_capable; - qdf_mem_copy(&roam_info->chan_info, - &pAssocInd->chan_info, - sizeof(struct oem_channel_info)); - - if (pAssocInd->HTCaps.present) - qdf_mem_copy(&roam_info->ht_caps, - &pAssocInd->HTCaps, - sizeof(tDot11fIEHTCaps)); - if (pAssocInd->VHTCaps.present) - qdf_mem_copy(&roam_info->vht_caps, - &pAssocInd->VHTCaps, - sizeof(tDot11fIEVHTCaps)); - roam_info->capability_info = pAssocInd->capability_info; - roam_info->he_caps_present = pAssocInd->he_caps_present; - - if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile)) { - if (session->pCurRoamProfile && - CSR_IS_ENC_TYPE_STATIC( - session->pCurRoamProfile->negotiatedUCEncryptionType)) { - /* NO keys... these key parameters don't matter. */ - csr_roam_issue_set_context_req_helper(mac_ctx, - sessionId, - session->pCurRoamProfile-> - negotiatedUCEncryptionType, - session->pConnectBssDesc, - &roam_info->peerMac.bytes, - false, true, eSIR_TX_RX, 0, 0, NULL, 0); - roam_info->fAuthRequired = false; - } else { - roam_info->fAuthRequired = true; - } - if (csr_akm_type == eCSR_AUTH_TYPE_OWE) { - roam_info->owe_pending_assoc_ind = qdf_mem_malloc( - sizeof(*pAssocInd)); - if (roam_info->owe_pending_assoc_ind) - qdf_mem_copy(roam_info->owe_pending_assoc_ind, - pAssocInd, sizeof(*pAssocInd)); - } - status = csr_roam_call_callback(mac_ctx, sessionId, - roam_info, 0, eCSR_ROAM_INFRA_IND, - eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND); - if (!QDF_IS_STATUS_SUCCESS(status)) { - /* Refused due to Mac filtering */ - roam_info->status_code = eSIR_SME_ASSOC_REFUSED; - } else if (pAssocInd->rsnIE.length && WLAN_ELEMID_RSN == - pAssocInd->rsnIE.rsnIEdata[0]) { - tDot11fIERSN rsn_ie = {0}; - - if (dot11f_unpack_ie_rsn(mac_ctx, - pAssocInd->rsnIE.rsnIEdata + 2, - pAssocInd->rsnIE.length - 2, - &rsn_ie, false) - != DOT11F_PARSE_SUCCESS || - (csr_is_sae_akm_present(&rsn_ie) && - !csr_is_sae_peer_allowed(mac_ctx, pAssocInd, - session, - pAssocInd->peerMacAddr, - &rsn_ie, - &mac_status_code))) { - status = QDF_STATUS_E_INVAL; - roam_info->status_code = - eSIR_SME_ASSOC_REFUSED; - sme_debug("SAE peer not allowed: Status: %d", - mac_status_code); - } - } - } - - if (csr_akm_type != eCSR_AUTH_TYPE_OWE) { - if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) && - roam_info->status_code != eSIR_SME_ASSOC_REFUSED) - pAssocInd->need_assoc_rsp_tx_cb = true; - /* Send Association completion message to PE */ - status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status, - mac_status_code); - } - - qdf_mem_free(roam_info); -} - -static void -csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) -{ - struct csr_roam_session *session; - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; - QDF_STATUS status; - struct disassoc_ind *pDisassocInd; - tSmeCmd *cmd; - - cmd = qdf_mem_malloc(sizeof(*cmd)); - if (!cmd) - return; - - /* - * Check if AP dis-associated us because of MIC failure. If so, - * then we need to take action immediately and not wait till the - * the WmStatusChange requests is pushed and processed - */ - pDisassocInd = (struct disassoc_ind *)msg_ptr; - status = csr_roam_get_session_id_from_bssid(mac_ctx, - &pDisassocInd->bssid, &sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) { - sme_err("Session Id not found for BSSID "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pDisassocInd->bssid.bytes)); - qdf_mem_free(cmd); - return; - } - - if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, - pDisassocInd->peer_macaddr)) { - qdf_mem_free(cmd); - return; - } - - sme_nofl_info("disassoc from peer " QDF_MAC_ADDR_STR - "reason: %d status: %d vid: %d", - QDF_MAC_ADDR_ARRAY(pDisassocInd->peer_macaddr.bytes), - pDisassocInd->reasonCode, - pDisassocInd->status_code, sessionId); - /* - * If we are in neighbor preauth done state then on receiving - * disassoc or deauth we dont roam instead we just disassoc - * from current ap and then go to disconnected state - * This happens for ESE and 11r FT connections ONLY. - */ - if (csr_roam_is11r_assoc(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); -#ifdef FEATURE_WLAN_ESE - if (csr_roam_is_ese_assoc(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); -#endif - if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session: %d not found", sessionId); - qdf_mem_free(cmd); - return; - } - - csr_update_scan_entry_associnfo(mac_ctx, - session, SCAN_ENTRY_CON_STATE_NONE); - - /* Update the disconnect stats */ - session->disconnect_stats.disconnection_cnt++; - session->disconnect_stats.disassoc_by_peer++; - - if (csr_is_conn_state_infra(mac_ctx, sessionId)) - session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; -#ifndef WLAN_MDM_CODE_REDUCTION_OPT - sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId, - SME_QOS_CSR_DISCONNECT_IND, NULL); -#endif - csr_roam_link_down(mac_ctx, sessionId); - csr_roam_issue_wm_status_change(mac_ctx, sessionId, - eCsrDisassociated, msg_ptr); - if (CSR_IS_INFRA_AP(&session->connectedProfile)) { - /* - * STA/P2P client got disassociated so remove any pending - * deauth commands in sme pending list - */ - cmd->command = eSmeCommandRoam; - cmd->sessionId = (uint8_t) sessionId; - cmd->u.roamCmd.roamReason = eCsrForcedDeauthSta; - qdf_mem_copy(cmd->u.roamCmd.peerMac, - pDisassocInd->peer_macaddr.bytes, - QDF_MAC_ADDR_SIZE); - csr_roam_remove_duplicate_command(mac_ctx, sessionId, cmd, - eCsrForcedDeauthSta); - } - qdf_mem_free(cmd); -} + } -static void -csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) -{ - struct csr_roam_session *session; - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; - QDF_STATUS status; - struct deauth_ind *pDeauthInd; + if (ani_akm == ANI_AKM_TYPE_UNKNOWN) + ani_akm = csr_convert_sae_akm_to_ani(akm_type); - pDeauthInd = (struct deauth_ind *)msg_ptr; - sme_debug("DEAUTH Indication from MAC for session %d bssid %pM", - pDeauthInd->sessionId, pDeauthInd->bssid.bytes); + if (ani_akm == ANI_AKM_TYPE_UNKNOWN) + ani_akm = csr_convert_ese_akm_to_ani(akm_type); - status = csr_roam_get_session_id_from_bssid(mac_ctx, - &pDeauthInd->bssid, - &sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) - return; + return ani_akm; +} - if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, - pDeauthInd->peer_macaddr)) - return; - /* If we are in neighbor preauth done state then on receiving - * disassoc or deauth we dont roam instead we just disassoc - * from current ap and then go to disconnected state - * This happens for ESE and 11r FT connections ONLY. - */ - if (csr_roam_is11r_assoc(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); +/** + * csr_translate_akm_type() - Convert ani_akm_type value to equivalent + * enum csr_akm_type + * @akm_type: value of type ani_akm_type + * + * Return: enum csr_akm_type value + */ +static enum csr_akm_type csr_translate_akm_type(enum ani_akm_type akm_type) +{ + enum csr_akm_type csr_akm_type; + + switch (akm_type) + { + case ANI_AKM_TYPE_NONE: + csr_akm_type = eCSR_AUTH_TYPE_NONE; + break; +#ifdef WLAN_FEATURE_SAE + case ANI_AKM_TYPE_SAE: + csr_akm_type = eCSR_AUTH_TYPE_SAE; + break; +#endif + case ANI_AKM_TYPE_WPA: + csr_akm_type = eCSR_AUTH_TYPE_WPA; + break; + case ANI_AKM_TYPE_WPA_PSK: + csr_akm_type = eCSR_AUTH_TYPE_WPA_PSK; + break; + case ANI_AKM_TYPE_RSN: + csr_akm_type = eCSR_AUTH_TYPE_RSN; + break; + case ANI_AKM_TYPE_RSN_PSK: + csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK; + break; + case ANI_AKM_TYPE_FT_RSN: + csr_akm_type = eCSR_AUTH_TYPE_FT_RSN; + break; + case ANI_AKM_TYPE_FT_RSN_PSK: + csr_akm_type = eCSR_AUTH_TYPE_FT_RSN_PSK; + break; #ifdef FEATURE_WLAN_ESE - if (csr_roam_is_ese_assoc(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); + case ANI_AKM_TYPE_CCKM: + csr_akm_type = eCSR_AUTH_TYPE_CCKM_RSN; + break; #endif - if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) && - (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) - csr_neighbor_roam_tranistion_preauth_done_to_disconnected( - mac_ctx, sessionId); - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", sessionId); - return; - } - - csr_update_scan_entry_associnfo(mac_ctx, - session, SCAN_ENTRY_CON_STATE_NONE); - /* Update the disconnect stats */ - switch (pDeauthInd->reasonCode) { - case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: - session->disconnect_stats.disconnection_cnt++; - session->disconnect_stats.peer_kickout++; + case ANI_AKM_TYPE_RSN_PSK_SHA256: + csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; break; - case eSIR_MAC_UNSPEC_FAILURE_REASON: - case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: - case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: - case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: - case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: - case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON: - session->disconnect_stats.disconnection_cnt++; - session->disconnect_stats.deauth_by_peer++; + case ANI_AKM_TYPE_RSN_8021X_SHA256: + csr_akm_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; break; - case eSIR_MAC_BEACON_MISSED: - session->disconnect_stats.disconnection_cnt++; - session->disconnect_stats.bmiss++; + case ANI_AKM_TYPE_FILS_SHA256: + csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA256; break; - default: - /* Unknown reason code */ + case ANI_AKM_TYPE_FILS_SHA384: + csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA384; + break; + case ANI_AKM_TYPE_FT_FILS_SHA256: + csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA256; + break; + case ANI_AKM_TYPE_FT_FILS_SHA384: + csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA384; + break; + case ANI_AKM_TYPE_DPP_RSN: + csr_akm_type = eCSR_AUTH_TYPE_DPP_RSN; + break; + case ANI_AKM_TYPE_OWE: + csr_akm_type = eCSR_AUTH_TYPE_OWE; break; + case ANI_AKM_TYPE_SUITEB_EAP_SHA256: + csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256; + break; + case ANI_AKM_TYPE_SUITEB_EAP_SHA384: + csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384; + break; + case ANI_AKM_TYPE_OSEN: + csr_akm_type = eCSR_AUTH_TYPE_OSEN; + break; + default: + csr_akm_type = eCSR_AUTH_TYPE_UNKNOWN; } - if (csr_is_conn_state_infra(mac_ctx, sessionId)) - session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; -#ifndef WLAN_MDM_CODE_REDUCTION_OPT - sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId, - SME_QOS_CSR_DISCONNECT_IND, NULL); -#endif - csr_roam_link_down(mac_ctx, sessionId); - csr_roam_issue_wm_status_change(mac_ctx, sessionId, - eCsrDeauthenticated, - msg_ptr); + return csr_akm_type; } -static void -csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +static bool csr_is_sae_akm_present(tDot11fIERSN * const rsn_ie) { - struct csr_roam_session *session; - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; - uint16_t ie_len; - QDF_STATUS status; - struct switch_channel_ind *pSwitchChnInd; - struct csr_roam_info *roam_info; - tSirMacDsParamSetIE *ds_params_ie; - tDot11fIEHTInfo *ht_info_ie; + uint16_t i; - /* in case of STA, the SWITCH_CHANNEL originates from its AP */ - sme_debug("eWNI_SME_SWITCH_CHL_IND from SME"); - pSwitchChnInd = (struct switch_channel_ind *)msg_ptr; - /* Update with the new channel id. The channel id is hidden in the - * status_code. - */ - status = csr_roam_get_session_id_from_bssid(mac_ctx, - &pSwitchChnInd->bssid, &sessionId); - if (QDF_IS_STATUS_ERROR(status)) - return; + if (rsn_ie->akm_suite_cnt > 6) { + sme_debug("Invalid akm_suite_cnt in Rx RSN IE"); + return false; + } - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", sessionId); - return; + for (i = 0; i < rsn_ie->akm_suite_cnt; i++) { + if (LE_READ_4(rsn_ie->akm_suite[i]) == RSN_AUTH_KEY_MGMT_SAE) { + sme_debug("SAE AKM present"); + return true; + } } + return false; +} - if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) { - sme_err("Channel switch failed"); - csr_roam_disconnect_internal(mac_ctx, sessionId, - eCSR_DISCONNECT_REASON_DEAUTH, - eSIR_MAC_CHANNEL_SWITCH_FAILED); - return; +static bool csr_is_sae_peer_allowed(struct mac_context *mac_ctx, + struct assoc_ind *assoc_ind, + struct csr_roam_session *session, + tSirMacAddr peer_mac_addr, + tDot11fIERSN *rsn_ie, + enum mac_status_code *mac_status_code) +{ + bool is_allowed = false; + + /* Allow the peer if it's SAE authenticated */ + if (assoc_ind->is_sae_authenticated) + return true; + + /* Allow the peer with valid PMKID */ + if (!rsn_ie->pmkid_count) { + *mac_status_code = eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + sme_debug("No PMKID present in RSNIE; Tried to use SAE AKM after non-SAE authentication"); + } else if (csr_is_pmkid_found_for_peer(mac_ctx, session, peer_mac_addr, + &rsn_ie->pmkid[0][0], + rsn_ie->pmkid_count)) { + sme_debug("Valid PMKID found for SAE peer"); + is_allowed = true; + } else { + *mac_status_code = eSIR_MAC_INVALID_PMKID; + sme_debug("No valid PMKID found for SAE peer"); } - session->connectedProfile.operationChannel = - (uint8_t) pSwitchChnInd->newChannelId; - /* Update the occupied channel list with the new switched channel */ - csr_init_occupied_channels_list(mac_ctx, sessionId); + return is_allowed; +} - if (session->pConnectBssDesc) { - session->pConnectBssDesc->channelId = - (uint8_t) pSwitchChnInd->newChannelId; +static QDF_STATUS +csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac, + struct assoc_ind *ind, + QDF_STATUS status, + uint8_t vdev_id) +{ + struct scheduler_msg msg = {0}; + tSirSmeAssocIndToUpperLayerCnf *cnf; - ie_len = csr_get_ielen_from_bss_description( - session->pConnectBssDesc); - ds_params_ie = (tSirMacDsParamSetIE *)wlan_get_ie_ptr_from_eid( - DOT11F_EID_DSPARAMS, - (uint8_t *)session->pConnectBssDesc->ieFields, - ie_len); - if (ds_params_ie) - ds_params_ie->channelNumber = - (uint8_t)pSwitchChnInd->newChannelId; + cnf = qdf_mem_malloc(sizeof(*cnf)); + if (!cnf) + return QDF_STATUS_E_NOMEM; - ht_info_ie = (tDot11fIEHTInfo *)wlan_get_ie_ptr_from_eid( - DOT11F_EID_HTINFO, - (uint8_t *)session->pConnectBssDesc->ieFields, - ie_len); - if (ht_info_ie) { - ht_info_ie->primaryChannel = - (uint8_t)pSwitchChnInd->newChannelId; - ht_info_ie->secondaryChannelOffset = - pSwitchChnInd->chan_params.sec_ch_offset; + cnf->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF; + cnf->length = sizeof(*cnf); + cnf->sessionId = vdev_id; + + if (QDF_IS_STATUS_SUCCESS(status)) + cnf->status_code = eSIR_SME_SUCCESS; + else + cnf->status_code = eSIR_SME_ASSOC_REFUSED; + qdf_mem_copy(&cnf->bssId, &ind->bssId, sizeof(cnf->bssId)); + qdf_mem_copy(&cnf->peerMacAddr, &ind->peerMacAddr, + sizeof(cnf->peerMacAddr)); + cnf->aid = ind->staId; + cnf->wmmEnabledSta = ind->wmmEnabledSta; + cnf->rsnIE = ind->rsnIE; +#ifdef FEATURE_WLAN_WAPI + cnf->wapiIE = ind->wapiIE; +#endif + cnf->addIE = ind->addIE; + cnf->reassocReq = ind->reassocReq; + cnf->timingMeasCap = ind->timingMeasCap; + cnf->chan_info = ind->chan_info; + cnf->ampdu = ind->ampdu; + cnf->sgi_enable = ind->sgi_enable; + cnf->tx_stbc = ind->tx_stbc; + cnf->ch_width = ind->ch_width; + cnf->mode = ind->mode; + cnf->rx_stbc = ind->rx_stbc; + cnf->max_supp_idx = ind->max_supp_idx; + cnf->max_ext_idx = ind->max_ext_idx; + cnf->max_mcs_idx = ind->max_mcs_idx; + cnf->rx_mcs_map = ind->rx_mcs_map; + cnf->tx_mcs_map = ind->tx_mcs_map; + cnf->ecsa_capable = ind->ecsa_capable; + if (ind->HTCaps.present) + cnf->ht_caps = ind->HTCaps; + if (ind->VHTCaps.present) + cnf->vht_caps = ind->VHTCaps; + cnf->capability_info = ind->capability_info; + cnf->he_caps_present = ind->he_caps_present; + if (ind->assocReqPtr) { + if (ind->assocReqLength < MAX_ASSOC_REQ_IE_LEN) { + cnf->ies = qdf_mem_malloc(ind->assocReqLength); + if (!cnf->ies) { + qdf_mem_free(cnf); + return QDF_STATUS_E_NOMEM; + } + cnf->ies_len = ind->assocReqLength; + qdf_mem_copy(cnf->ies, ind->assocReqPtr, + cnf->ies_len); + } else { + sme_err("Assoc Ie length is too long"); } } - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - roam_info->chan_info.chan_id = pSwitchChnInd->newChannelId; - roam_info->chan_info.ch_width = pSwitchChnInd->chan_params.ch_width; - roam_info->chan_info.sec_ch_offset = - pSwitchChnInd->chan_params.sec_ch_offset; - roam_info->chan_info.band_center_freq1 = - pSwitchChnInd->chan_params.center_freq_seg0; - roam_info->chan_info.band_center_freq2 = - pSwitchChnInd->chan_params.center_freq_seg1; - - if (CSR_IS_PHY_MODE_11ac(mac_ctx->roam.configParam.phyMode)) - roam_info->mode = SIR_SME_PHY_MODE_VHT; - else if (CSR_IS_PHY_MODE_11n(mac_ctx->roam.configParam.phyMode)) - roam_info->mode = SIR_SME_PHY_MODE_HT; - else - roam_info->mode = SIR_SME_PHY_MODE_LEGACY; + msg.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; + msg.bodyptr = cnf; + sys_process_mmh_msg(mac, &msg); - status = csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, - eCSR_ROAM_STA_CHANNEL_SWITCH, - eCSR_ROAM_RESULT_NONE); - qdf_mem_free(roam_info); + return QDF_STATUS_SUCCESS; } static void -csr_roam_chk_lnk_deauth_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_assoc_ind_upper_layer( + struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { - struct csr_roam_session *session; - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; + struct assoc_ind *assoc_ind; QDF_STATUS status; - struct csr_roam_info *roam_info; - struct deauth_rsp *pDeauthRsp = (struct deauth_rsp *) msg_ptr; - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - sme_debug("eWNI_SME_DEAUTH_RSP from SME"); - sessionId = pDeauthRsp->sessionId; - if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { - qdf_mem_free(roam_info); + assoc_ind = (struct assoc_ind *)msg_ptr; + status = csr_roam_get_session_id_from_bssid( + mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId, + &session_id); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_debug("Couldn't find session_id for given BSSID"); return; } - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (CSR_IS_INFRA_AP(&session->connectedProfile)) { - roam_info->u.pConnectedProfile = &session->connectedProfile; - qdf_copy_macaddr(&roam_info->peerMac, - &pDeauthRsp->peer_macaddr); - roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; - roam_info->status_code = pDeauthRsp->status_code; - status = csr_roam_call_callback(mac_ctx, sessionId, - roam_info, 0, - eCSR_ROAM_LOSTLINK, - eCSR_ROAM_RESULT_FORCED); - } - qdf_mem_free(roam_info); + csr_send_assoc_ind_to_upper_layer_cnf_msg( + mac_ctx, assoc_ind, status, session_id); + /*in the association response tx compete case, + *memory for assoc_ind->assocReqPtr will be malloced + *in the lim_assoc_rsp_tx_complete -> lim_fill_sme_assoc_ind_params + *and then assoc_ind will pass here, so after using it + *in the csr_send_assoc_ind_to_upper_layer_cnf_msg and + *then free the memroy here. + */ + if (assoc_ind->assocReqLength != 0 && assoc_ind->assocReqPtr) + qdf_mem_free(assoc_ind->assocReqPtr); } static void -csr_roam_chk_lnk_disassoc_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; QDF_STATUS status; struct csr_roam_info *roam_info; - /* - * session id is invalid here so cant use it to access the array - * curSubstate as index - */ - struct disassoc_rsp *pDisassocRsp = (struct disassoc_rsp *) msg_ptr; + struct assoc_ind *pAssocInd; + enum mac_status_code mac_status_code = eSIR_MAC_SUCCESS_STATUS; + enum csr_akm_type csr_akm_type; - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - sme_debug("eWNI_SME_DISASSOC_RSP from SME "); - sessionId = pDisassocRsp->sessionId; - if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { - qdf_mem_free(roam_info); + sme_debug("Receive WNI_SME_ASSOC_IND from SME"); + pAssocInd = (struct assoc_ind *) msg_ptr; + status = csr_roam_get_session_id_from_bssid(mac_ctx, + (struct qdf_mac_addr *) pAssocInd->bssId, + &sessionId); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_debug("Couldn't find session_id for given BSSID"); return; } session = CSR_GET_SESSION(mac_ctx, sessionId); - if (CSR_IS_INFRA_AP(&session->connectedProfile)) { - roam_info->u.pConnectedProfile = &session->connectedProfile; - qdf_copy_macaddr(&roam_info->peerMac, - &pDisassocRsp->peer_macaddr); - roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; - roam_info->status_code = pDisassocRsp->status_code; - status = csr_roam_call_callback(mac_ctx, sessionId, - roam_info, 0, - eCSR_ROAM_LOSTLINK, - eCSR_ROAM_RESULT_FORCED); - } - qdf_mem_free(roam_info); -} - -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR -static void -csr_roam_diag_mic_fail(struct mac_context *mac_ctx, uint32_t sessionId) -{ - WLAN_HOST_DIAG_EVENT_DEF(secEvent, - host_event_wlan_security_payload_type); - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { sme_err("session %d not found", sessionId); return; } - qdf_mem_zero(&secEvent, sizeof(host_event_wlan_security_payload_type)); - secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR; - secEvent.encryptionModeMulticast = - (uint8_t) diag_enc_type_from_csr_type( - session->connectedProfile.mcEncryptionType); - secEvent.encryptionModeUnicast = - (uint8_t) diag_enc_type_from_csr_type( - session->connectedProfile.EncryptionType); - secEvent.authMode = - (uint8_t) diag_auth_type_from_csr_type( - session->connectedProfile.AuthType); - qdf_mem_copy(secEvent.bssid, session->connectedProfile.bssid.bytes, - QDF_MAC_ADDR_SIZE); - WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); -} -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + csr_akm_type = csr_translate_akm_type(pAssocInd->akm_type); -static void -csr_roam_chk_lnk_mic_fail_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) -{ - uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; - QDF_STATUS status; - struct csr_roam_info *roam_info; - struct mic_failure_ind *mic_ind = (struct mic_failure_ind *)msg_ptr; - eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + /* Required for indicating the frames to upper layer */ + roam_info->assocReqLength = pAssocInd->assocReqLength; + roam_info->assocReqPtr = pAssocInd->assocReqPtr; + roam_info->beaconPtr = pAssocInd->beaconPtr; + roam_info->beaconLength = pAssocInd->beaconLength; + roam_info->status_code = eSIR_SME_SUCCESS; + roam_info->u.pConnectedProfile = &session->connectedProfile; + roam_info->staId = (uint8_t)pAssocInd->staId; + roam_info->rsnIELen = (uint8_t)pAssocInd->rsnIE.length; + roam_info->prsnIE = pAssocInd->rsnIE.rsnIEdata; +#ifdef FEATURE_WLAN_WAPI + roam_info->wapiIELen = (uint8_t)pAssocInd->wapiIE.length; + roam_info->pwapiIE = pAssocInd->wapiIE.wapiIEdata; +#endif + roam_info->addIELen = (uint8_t)pAssocInd->addIE.length; + roam_info->paddIE = pAssocInd->addIE.addIEdata; + qdf_mem_copy(roam_info->peerMac.bytes, + pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + qdf_mem_copy(roam_info->bssid.bytes, + pAssocInd->bssId, + sizeof(struct qdf_mac_addr)); + roam_info->wmmEnabledSta = pAssocInd->wmmEnabledSta; + roam_info->timingMeasCap = pAssocInd->timingMeasCap; + roam_info->ecsa_capable = pAssocInd->ecsa_capable; + qdf_mem_copy(&roam_info->chan_info, + &pAssocInd->chan_info, + sizeof(struct oem_channel_info)); + + if (pAssocInd->HTCaps.present) + qdf_mem_copy(&roam_info->ht_caps, + &pAssocInd->HTCaps, + sizeof(tDot11fIEHTCaps)); + if (pAssocInd->VHTCaps.present) + qdf_mem_copy(&roam_info->vht_caps, + &pAssocInd->VHTCaps, + sizeof(tDot11fIEVHTCaps)); + roam_info->capability_info = pAssocInd->capability_info; + roam_info->he_caps_present = pAssocInd->he_caps_present; + + if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile)) { + if (session->pCurRoamProfile && + CSR_IS_ENC_TYPE_STATIC( + session->pCurRoamProfile->negotiatedUCEncryptionType)) { + /* NO keys... these key parameters don't matter. */ + csr_issue_set_context_req_helper(mac_ctx, + session->pCurRoamProfile, sessionId, + &roam_info->peerMac.bytes, false, true, + eSIR_TX_RX, 0, 0, NULL); + roam_info->fAuthRequired = false; + } else { + roam_info->fAuthRequired = true; + } + if (csr_akm_type == eCSR_AUTH_TYPE_OWE) { + roam_info->owe_pending_assoc_ind = qdf_mem_malloc( + sizeof(*pAssocInd)); + if (roam_info->owe_pending_assoc_ind) + qdf_mem_copy(roam_info->owe_pending_assoc_ind, + pAssocInd, sizeof(*pAssocInd)); + } + status = csr_roam_call_callback(mac_ctx, sessionId, + roam_info, 0, eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND); + if (!QDF_IS_STATUS_SUCCESS(status)) { + /* Refused due to Mac filtering */ + roam_info->status_code = eSIR_SME_ASSOC_REFUSED; + } else if (pAssocInd->rsnIE.length && WLAN_ELEMID_RSN == + pAssocInd->rsnIE.rsnIEdata[0]) { + tDot11fIERSN rsn_ie = {0}; + + if (dot11f_unpack_ie_rsn(mac_ctx, + pAssocInd->rsnIE.rsnIEdata + 2, + pAssocInd->rsnIE.length - 2, + &rsn_ie, false) + != DOT11F_PARSE_SUCCESS || + (csr_is_sae_akm_present(&rsn_ie) && + !csr_is_sae_peer_allowed(mac_ctx, pAssocInd, + session, + pAssocInd->peerMacAddr, + &rsn_ie, + &mac_status_code))) { + status = QDF_STATUS_E_INVAL; + roam_info->status_code = + eSIR_SME_ASSOC_REFUSED; + sme_debug("SAE peer not allowed: Status: %d", + mac_status_code); + } + } + } - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - status = csr_roam_get_session_id_from_bssid(mac_ctx, - &mic_ind->bssId, &sessionId); - if (QDF_IS_STATUS_SUCCESS(status)) { - roam_info->u.pMICFailureInfo = &mic_ind->info; - if (mic_ind->info.multicast) - result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP; - else - result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; - csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, - eCSR_ROAM_MIC_ERROR_IND, result); + if (csr_akm_type != eCSR_AUTH_TYPE_OWE) { + if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) && + roam_info->status_code != eSIR_SME_ASSOC_REFUSED) + pAssocInd->need_assoc_rsp_tx_cb = true; + /* Send Association completion message to PE */ + status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status, + mac_status_code); } -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - csr_roam_diag_mic_fail(mac_ctx, sessionId); -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + qdf_mem_free(roam_info); } static void -csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { + struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; QDF_STATUS status; - struct csr_roam_info *roam_info; - tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr; + struct disassoc_ind *pDisassocInd; + tSmeCmd *cmd; - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) + cmd = qdf_mem_malloc(sizeof(*cmd)); + if (!cmd) return; - sme_debug("WPS PBC Probe request Indication from SME"); + /* + * Check if AP dis-associated us because of MIC failure. If so, + * then we need to take action immediately and not wait till the + * the WmStatusChange requests is pushed and processed + */ + pDisassocInd = (struct disassoc_ind *)msg_ptr; status = csr_roam_get_session_id_from_bssid(mac_ctx, - &pProbeReqInd->bssid, &sessionId); - if (QDF_IS_STATUS_SUCCESS(status)) { - roam_info->u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq; - csr_roam_call_callback(mac_ctx, sessionId, roam_info, - 0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, - eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND); + &pDisassocInd->bssid, &sessionId); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("Session Id not found for BSSID "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes)); + qdf_mem_free(cmd); + return; } - qdf_mem_free(roam_info); -} -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR -static void -csr_roam_diag_joined_new_bss(struct mac_context *mac_ctx, - struct new_bss_info *pNewBss) -{ - host_log_ibss_pkt_type *pIbssLog; - uint32_t bi; + if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, + pDisassocInd->peer_macaddr)) { + qdf_mem_free(cmd); + return; + } - WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, - LOG_WLAN_IBSS_C); - if (!pIbssLog) + sme_nofl_info("disassoc from peer " QDF_MAC_ADDR_FMT + "reason: %d status: %d vid %d", + QDF_MAC_ADDR_REF(pDisassocInd->peer_macaddr.bytes), + pDisassocInd->reasonCode, + pDisassocInd->status_code, sessionId); + /* + * If we are in neighbor preauth done state then on receiving + * disassoc or deauth we dont roam instead we just disassoc + * from current ap and then go to disconnected state + * This happens for ESE and 11r FT connections ONLY. + */ + if (csr_roam_is11r_assoc(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); +#ifdef FEATURE_WLAN_ESE + if (csr_roam_is_ese_assoc(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); +#endif + if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session: %d not found", sessionId); + qdf_mem_free(cmd); return; - pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING; - if (pNewBss) { - qdf_copy_macaddr(&pIbssLog->bssid, &pNewBss->bssId); - if (pNewBss->ssId.length > HOST_LOG_MAX_SSID_SIZE) - pNewBss->ssId.length = HOST_LOG_MAX_SSID_SIZE; - qdf_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId, - pNewBss->ssId.length); - pIbssLog->operatingChannel = pNewBss->channelNumber; } - bi = mac_ctx->mlme_cfg->sap_cfg.beacon_interval; - /* U8 is not enough for beacon interval */ - pIbssLog->beaconInterval = (uint8_t) bi; - WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); + + csr_update_scan_entry_associnfo(mac_ctx, + session, SCAN_ENTRY_CON_STATE_NONE); + + /* Update the disconnect stats */ + session->disconnect_stats.disconnection_cnt++; + session->disconnect_stats.disassoc_by_peer++; + + if (csr_is_conn_state_infra(mac_ctx, sessionId)) + session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId, + SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csr_roam_link_down(mac_ctx, sessionId); + csr_roam_issue_wm_status_change(mac_ctx, sessionId, + eCsrDisassociated, msg_ptr); + if (CSR_IS_INFRA_AP(&session->connectedProfile)) { + /* + * STA/P2P client got disassociated so remove any pending + * deauth commands in sme pending list + */ + cmd->command = eSmeCommandRoam; + cmd->vdev_id = (uint8_t) sessionId; + cmd->u.roamCmd.roamReason = eCsrForcedDeauthSta; + qdf_mem_copy(cmd->u.roamCmd.peerMac, + pDisassocInd->peer_macaddr.bytes, + QDF_MAC_ADDR_SIZE); + csr_roam_remove_duplicate_command(mac_ctx, sessionId, cmd, + eCsrForcedDeauthSta); + } + qdf_mem_free(cmd); } -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ static void -csr_roam_chk_lnk_wm_status_change_ntf(struct mac_context *mac_ctx, - tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; QDF_STATUS status; - struct csr_roam_info *roam_info; - struct wm_status_change_ntf *pStatusChangeMsg; - struct ap_new_caps *pApNewCaps; - eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; - tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - struct new_bss_info *pNewBss; - eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED; - - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - pStatusChangeMsg = (struct wm_status_change_ntf *) msg_ptr; - switch (pStatusChangeMsg->statusChangeCode) { - case eSIR_SME_IBSS_ACTIVE: - sessionId = csr_find_ibss_session(mac_ctx); - if (WLAN_UMAC_VDEV_ID_MAX == sessionId) - break; - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", - sessionId); - goto out; - } - session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED; - if (session->pConnectBssDesc) { - qdf_mem_copy(&roam_info->bssid, - session->pConnectBssDesc->bssId, - sizeof(struct qdf_mac_addr)); - roam_info->u.pConnectedProfile = - &session->connectedProfile; - } else { - sme_err("CSR: connected BSS is empty"); - } - result = eCSR_ROAM_RESULT_IBSS_CONNECT; - roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; - break; + struct deauth_ind *pDeauthInd; - case eSIR_SME_IBSS_INACTIVE: - sessionId = csr_find_ibss_session(mac_ctx); - if (WLAN_UMAC_VDEV_ID_MAX != sessionId) { - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", sessionId); - goto out; - } - session->connectState = - eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; - result = eCSR_ROAM_RESULT_IBSS_INACTIVE; - roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; - } - break; + pDeauthInd = (struct deauth_ind *)msg_ptr; + sme_debug("DEAUTH Indication from MAC for vdev_id %d bssid "QDF_MAC_ADDR_FMT, + pDeauthInd->vdev_id, + QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes)); - case eSIR_SME_JOINED_NEW_BSS: - /* IBSS coalescing. */ - sme_debug("CSR: eSIR_SME_JOINED_NEW_BSS received from PE"); - sessionId = csr_find_ibss_session(mac_ctx); - if (WLAN_UMAC_VDEV_ID_MAX == sessionId) - break; - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", - sessionId); - goto out; - } - /* update the connection state information */ - pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo; -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - csr_roam_diag_joined_new_bss(mac_ctx, pNewBss); -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - csr_roam_update_connected_profile_from_new_bss(mac_ctx, - sessionId, - pNewBss); + status = csr_roam_get_session_id_from_bssid(mac_ctx, + &pDeauthInd->bssid, + &sessionId); + if (!QDF_IS_STATUS_SUCCESS(status)) + return; - if ((eCSR_ENCRYPT_TYPE_NONE == - session->connectedProfile.EncryptionType)) { - csr_roam_issue_set_context_req_helper(mac_ctx, - sessionId, - session->connectedProfile.EncryptionType, - session->pConnectBssDesc, - &Broadcastaddr, false, false, - eSIR_TX_RX, 0, 0, NULL, 0); - } - result = eCSR_ROAM_RESULT_IBSS_COALESCED; - roamStatus = eCSR_ROAM_IBSS_IND; - qdf_mem_copy(&roam_info->bssid, &pNewBss->bssId, - sizeof(struct qdf_mac_addr)); - /* This BSSID is the real BSSID, save it */ - if (session->pConnectBssDesc) - qdf_mem_copy(session->pConnectBssDesc->bssId, - &pNewBss->bssId, sizeof(struct qdf_mac_addr)); - break; + if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, + pDeauthInd->peer_macaddr)) + return; + /* If we are in neighbor preauth done state then on receiving + * disassoc or deauth we dont roam instead we just disassoc + * from current ap and then go to disconnected state + * This happens for ESE and 11r FT connections ONLY. + */ + if (csr_roam_is11r_assoc(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); +#ifdef FEATURE_WLAN_ESE + if (csr_roam_is_ese_assoc(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); +#endif + if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) && + (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId))) + csr_neighbor_roam_tranistion_preauth_done_to_disconnected( + mac_ctx, sessionId); + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", sessionId); + return; + } - /* - * detection by LIM that the capabilities of the associated - * AP have changed. - */ - case eSIR_SME_AP_CAPS_CHANGED: - pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps; - sme_debug("CSR handling eSIR_SME_AP_CAPS_CHANGED"); - status = csr_roam_get_session_id_from_bssid(mac_ctx, - &pApNewCaps->bssId, &sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) - break; - if (eCSR_ROAMING_STATE_JOINED == - sme_get_current_roam_state(MAC_HANDLE(mac_ctx), sessionId) - && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC - == mac_ctx->roam.curSubState[sessionId]) - || (eCSR_ROAM_SUBSTATE_NONE == - mac_ctx->roam.curSubState[sessionId]) - || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC - == mac_ctx->roam.curSubState[sessionId]) - || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC == - mac_ctx->roam.curSubState[sessionId]))) { - sme_warn("Calling csr_roam_disconnect_internal"); - csr_roam_disconnect_internal(mac_ctx, sessionId, - eCSR_DISCONNECT_REASON_UNSPECIFIED, - eSIR_MAC_UNSPEC_FAILURE_REASON); - } else { - sme_warn("Skipping the new scan as CSR is in state: %s and sub-state: %s", - mac_trace_getcsr_roam_state( - mac_ctx->roam.curState[sessionId]), - mac_trace_getcsr_roam_sub_state( - mac_ctx->roam.curSubState[sessionId])); - /* We ignore the caps change event if CSR is not in full - * connected state. Send one event to PE to reset - * limSentCapsChangeNtf Once limSentCapsChangeNtf set - * 0, lim can send sub sequent CAPS change event - * otherwise lim cannot send any CAPS change events to - * SME - */ - csr_send_reset_ap_caps_changed(mac_ctx, - &pApNewCaps->bssId); - } + csr_update_scan_entry_associnfo(mac_ctx, + session, SCAN_ENTRY_CON_STATE_NONE); + /* Update the disconnect stats */ + switch (pDeauthInd->reasonCode) { + case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: + session->disconnect_stats.disconnection_cnt++; + session->disconnect_stats.peer_kickout++; + break; + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: + case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: + case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON: + session->disconnect_stats.disconnection_cnt++; + session->disconnect_stats.deauth_by_peer++; + break; + case eSIR_MAC_BEACON_MISSED: + session->disconnect_stats.disconnection_cnt++; + session->disconnect_stats.bmiss++; break; - default: - roamStatus = eCSR_ROAM_FAILED; - result = eCSR_ROAM_RESULT_NONE; + /* Unknown reason code */ break; - } /* end switch on statusChangeCode */ - if (eCSR_ROAM_RESULT_NONE != result) { - csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, - roamStatus, result); } -out: - qdf_mem_free(roam_info); + + if (csr_is_conn_state_infra(mac_ctx, sessionId)) + session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId, + SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csr_roam_link_down(mac_ctx, sessionId); + csr_roam_issue_wm_status_change(mac_ctx, sessionId, + eCsrDeauthenticated, + msg_ptr); } static void -csr_roam_chk_lnk_ibss_new_peer_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + uint16_t ie_len; QDF_STATUS status; - struct csr_roam_info *roam_info = NULL; - tSmeIbssPeerInd *pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr; -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - host_log_ibss_pkt_type *pIbssLog; - - WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, - LOG_WLAN_IBSS_C); - if (pIbssLog) { - pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN; - qdf_copy_macaddr(&pIbssLog->peer_macaddr, - &pIbssPeerInd->peer_addr); - WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); - } -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + struct switch_channel_ind *pSwitchChnInd; + struct csr_roam_info *roam_info; + tSirMacDsParamSetIE *ds_params_ie; + tDot11fIEHTInfo *ht_info_ie; - sessionId = csr_find_ibss_session(mac_ctx); - if (WLAN_UMAC_VDEV_ID_MAX == sessionId) + /* in case of STA, the SWITCH_CHANNEL originates from its AP */ + sme_debug("eWNI_SME_SWITCH_CHL_IND from SME"); + pSwitchChnInd = (struct switch_channel_ind *)msg_ptr; + /* Update with the new channel id. The channel id is hidden in the + * status_code. + */ + status = csr_roam_get_session_id_from_bssid(mac_ctx, + &pSwitchChnInd->bssid, &sessionId); + if (QDF_IS_STATUS_ERROR(status)) return; + session = CSR_GET_SESSION(mac_ctx, sessionId); if (!session) { sme_err("session %d not found", sessionId); return; } - /* - * Issue the set Context request to LIM to establish the Unicast STA - * context for the new peer... - */ - if (!session->pConnectBssDesc) { - sme_warn("CSR: connected BSS is empty"); - goto callback_and_free; + + if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) { + sme_err("Channel switch failed"); + csr_roam_disconnect_internal(mac_ctx, sessionId, + eCSR_DISCONNECT_REASON_DEAUTH, + eSIR_MAC_CHANNEL_SWITCH_FAILED); + return; } - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - goto callback_and_free; - qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr); - qdf_mem_copy(&roam_info->bssid, session->pConnectBssDesc->bssId, - sizeof(struct qdf_mac_addr)); - if (pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) { - roam_info->pbFrames = qdf_mem_malloc((pIbssPeerInd->mesgLen - - sizeof(tSmeIbssPeerInd))); - if (!roam_info->pbFrames) { - status = QDF_STATUS_E_NOMEM; - } else { - status = QDF_STATUS_SUCCESS; - roam_info->nBeaconLength = pIbssPeerInd->mesgLen - - sizeof(tSmeIbssPeerInd); - qdf_mem_copy(roam_info->pbFrames, - ((uint8_t *)pIbssPeerInd) + - sizeof(tSmeIbssPeerInd), - roam_info->nBeaconLength); - } - roam_info->staId = (uint8_t)pIbssPeerInd->staId; - roam_info->bss_desc = qdf_mem_malloc( - session->pConnectBssDesc->length); - if (!roam_info->bss_desc) { - status = QDF_STATUS_E_NOMEM; - } else { - status = QDF_STATUS_SUCCESS; - qdf_mem_copy(roam_info->bss_desc, - session->pConnectBssDesc, - session->pConnectBssDesc->length); + session->connectedProfile.op_freq = pSwitchChnInd->freq; + + /* Update the occupied channel list with the new switched channel */ + csr_init_occupied_channels_list(mac_ctx, sessionId); + + if (session->pConnectBssDesc) { + session->pConnectBssDesc->chan_freq = pSwitchChnInd->freq; + + ie_len = csr_get_ielen_from_bss_description( + session->pConnectBssDesc); + ds_params_ie = (tSirMacDsParamSetIE *)wlan_get_ie_ptr_from_eid( + DOT11F_EID_DSPARAMS, + (uint8_t *)session->pConnectBssDesc->ieFields, + ie_len); + if (ds_params_ie) + ds_params_ie->channelNumber = + wlan_reg_freq_to_chan(mac_ctx->pdev, + pSwitchChnInd->freq); + + ht_info_ie = (tDot11fIEHTInfo *)wlan_get_ie_ptr_from_eid( + DOT11F_EID_HTINFO, + (uint8_t *)session->pConnectBssDesc->ieFields, + ie_len); + if (ht_info_ie) { + ht_info_ie->primaryChannel = + wlan_reg_freq_to_chan(mac_ctx->pdev, + pSwitchChnInd->freq); + ht_info_ie->secondaryChannelOffset = + pSwitchChnInd->chan_params.sec_ch_offset; } } - if ((eCSR_ENCRYPT_TYPE_NONE == - session->connectedProfile.EncryptionType)) { - /* NO keys. these key parameters don't matter */ - csr_roam_issue_set_context_req_helper(mac_ctx, sessionId, - session->connectedProfile.EncryptionType, - session->pConnectBssDesc, - &pIbssPeerInd->peer_addr.bytes, - false, true, eSIR_TX_RX, 0, 0, NULL, 0); + + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + roam_info->chan_info.mhz = pSwitchChnInd->freq; + roam_info->chan_info.ch_width = pSwitchChnInd->chan_params.ch_width; + roam_info->chan_info.sec_ch_offset = + pSwitchChnInd->chan_params.sec_ch_offset; + roam_info->chan_info.band_center_freq1 = + pSwitchChnInd->chan_params.mhz_freq_seg0; + roam_info->chan_info.band_center_freq2 = + pSwitchChnInd->chan_params.mhz_freq_seg1; + + switch (session->bssParams.uCfgDot11Mode) { + case eCSR_CFG_DOT11_MODE_11N: + case eCSR_CFG_DOT11_MODE_11N_ONLY: + roam_info->mode = SIR_SME_PHY_MODE_HT; + break; + case eCSR_CFG_DOT11_MODE_11AC: + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + case eCSR_CFG_DOT11_MODE_11AX: + case eCSR_CFG_DOT11_MODE_11AX_ONLY: + roam_info->mode = SIR_SME_PHY_MODE_VHT; + break; + default: + roam_info->mode = SIR_SME_PHY_MODE_LEGACY; + break; } -callback_and_free: - /* send up the sec type for the new peer */ - if (roam_info) - roam_info->u.pConnectedProfile = &session->connectedProfile; - csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, - eCSR_ROAM_CONNECT_STATUS_UPDATE, - eCSR_ROAM_RESULT_IBSS_NEW_PEER); - if (roam_info) { - qdf_mem_free(roam_info->pbFrames); - qdf_mem_free(roam_info->bss_desc); + status = csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, + eCSR_ROAM_STA_CHANNEL_SWITCH, + eCSR_ROAM_RESULT_NONE); + qdf_mem_free(roam_info); +} + +static void +csr_roam_chk_lnk_deauth_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +{ + struct csr_roam_session *session; + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; + struct csr_roam_info *roam_info; + struct deauth_rsp *pDeauthRsp = (struct deauth_rsp *) msg_ptr; + + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + sme_debug("eWNI_SME_DEAUTH_RSP from SME"); + sessionId = pDeauthRsp->sessionId; + if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { qdf_mem_free(roam_info); + return; + } + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (CSR_IS_INFRA_AP(&session->connectedProfile)) { + roam_info->u.pConnectedProfile = &session->connectedProfile; + qdf_copy_macaddr(&roam_info->peerMac, + &pDeauthRsp->peer_macaddr); + roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; + roam_info->status_code = pDeauthRsp->status_code; + status = csr_roam_call_callback(mac_ctx, sessionId, + roam_info, 0, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_FORCED); } + qdf_mem_free(roam_info); } static void -csr_roam_chk_lnk_ibss_peer_departed_ind(struct mac_context *mac_ctx, - tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_disassoc_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { + struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; struct csr_roam_info *roam_info; - tSmeIbssPeerInd *pIbssPeerInd; + /* + * session id is invalid here so cant use it to access the array + * curSubstate as index + */ + struct disassoc_rsp *pDisassocRsp = (struct disassoc_rsp *) msg_ptr; - if (!msg_ptr) { - sme_err("IBSS peer ind. message is NULL"); - return; - } roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return; - pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr; - sessionId = csr_find_ibss_session(mac_ctx); - if (WLAN_UMAC_VDEV_ID_MAX != sessionId) { -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - host_log_ibss_pkt_type *pIbssLog; - - WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, - LOG_WLAN_IBSS_C); - if (pIbssLog) { - pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE; - if (pIbssPeerInd) { - qdf_copy_macaddr(&pIbssLog->peer_macaddr, - &pIbssPeerInd->peer_addr); - } - WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); - } -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - sme_debug("CSR: Peer departed notification from LIM"); - roam_info->staId = (uint8_t)pIbssPeerInd->staId; - qdf_copy_macaddr(&roam_info->peerMac, &pIbssPeerInd->peer_addr); - csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, - eCSR_ROAM_CONNECT_STATUS_UPDATE, - eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); + sme_debug("eWNI_SME_DISASSOC_RSP from SME "); + sessionId = pDisassocRsp->sessionId; + if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { + qdf_mem_free(roam_info); + return; + } + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (CSR_IS_INFRA_AP(&session->connectedProfile)) { + roam_info->u.pConnectedProfile = &session->connectedProfile; + qdf_copy_macaddr(&roam_info->peerMac, + &pDisassocRsp->peer_macaddr); + roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; + roam_info->status_code = pDisassocRsp->status_code; + status = csr_roam_call_callback(mac_ctx, sessionId, + roam_info, 0, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_FORCED); } qdf_mem_free(roam_info); } #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR static void -csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, - struct csr_roam_session *session, - struct set_context_rsp *pRsp) +csr_roam_diag_mic_fail(struct mac_context *mac_ctx, uint32_t sessionId) { - WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent, + WLAN_HOST_DIAG_EVENT_DEF(secEvent, host_event_wlan_security_payload_type); - if (eCSR_ENCRYPT_TYPE_NONE == - session->connectedProfile.EncryptionType) + struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId); + + if (!session) { + sme_err("session %d not found", sessionId); return; - qdf_mem_zero(&setKeyEvent, - sizeof(host_event_wlan_security_payload_type)); - if (qdf_is_macaddr_group(&pRsp->peer_macaddr)) - setKeyEvent.eventId = - WLAN_SECURITY_EVENT_SET_BCAST_RSP; - else - setKeyEvent.eventId = - WLAN_SECURITY_EVENT_SET_UNICAST_RSP; - setKeyEvent.encryptionModeMulticast = + } + qdf_mem_zero(&secEvent, sizeof(host_event_wlan_security_payload_type)); + secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR; + secEvent.encryptionModeMulticast = (uint8_t) diag_enc_type_from_csr_type( session->connectedProfile.mcEncryptionType); - setKeyEvent.encryptionModeUnicast = + secEvent.encryptionModeUnicast = (uint8_t) diag_enc_type_from_csr_type( session->connectedProfile.EncryptionType); - qdf_mem_copy(setKeyEvent.bssid, session->connectedProfile.bssid.bytes, - QDF_MAC_ADDR_SIZE); - setKeyEvent.authMode = + secEvent.authMode = (uint8_t) diag_auth_type_from_csr_type( - session->connectedProfile.AuthType); - if (eSIR_SME_SUCCESS != pRsp->status_code) - setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; - WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); -} -#else /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ -static void -csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, - struct csr_roam_session *session, - struct set_context_rsp *pRsp) -{ + session->connectedProfile.AuthType); + qdf_mem_copy(secEvent.bssid, session->connectedProfile.bssid.bytes, + QDF_MAC_ADDR_SIZE); + WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); } #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ static void -csr_roam_chk_lnk_set_ctx_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +csr_roam_chk_lnk_mic_fail_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { - struct csr_roam_session *session; uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; QDF_STATUS status; struct csr_roam_info *roam_info; - eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; - struct set_context_rsp *pRsp = (struct set_context_rsp *)msg_ptr; - + struct mic_failure_ind *mic_ind = (struct mic_failure_ind *)msg_ptr; + eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; - if (!pRsp) { - sme_err("set key response is NULL"); + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) return; + status = csr_roam_get_session_id_from_bssid(mac_ctx, + &mic_ind->bssId, &sessionId); + if (QDF_IS_STATUS_SUCCESS(status)) { + roam_info->u.pMICFailureInfo = &mic_ind->info; + if (mic_ind->info.multicast) + result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP; + else + result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, + eCSR_ROAM_MIC_ERROR_IND, result); } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + csr_roam_diag_mic_fail(mac_ctx, sessionId); +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + qdf_mem_free(roam_info); +} + +static void +csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +{ + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; + struct csr_roam_info *roam_info; + tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr; roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) return; - sessionId = pRsp->sessionId; - session = CSR_GET_SESSION(mac_ctx, sessionId); - if (!session) { - sme_err("session %d not found", sessionId); - qdf_mem_free(roam_info); - return; + sme_debug("WPS PBC Probe request Indication from SME"); + + status = csr_roam_get_session_id_from_bssid(mac_ctx, + &pProbeReqInd->bssid, &sessionId); + if (QDF_IS_STATUS_SUCCESS(status)) { + roam_info->u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq; + csr_roam_call_callback(mac_ctx, sessionId, roam_info, + 0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, + eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND); } + qdf_mem_free(roam_info); +} - csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +static void +csr_roam_diag_joined_new_bss(struct mac_context *mac_ctx, + struct new_bss_info *pNewBss) +{ + host_log_ibss_pkt_type *pIbssLog; + uint32_t bi; - if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) { - csr_roam_stop_wait_for_key_timer(mac_ctx); - /* We are done with authentication, whethere succeed or not */ - csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, - sessionId); - /* We do it here because this linkup function is not called - * after association when a key needs to be set. - */ - if (csr_is_conn_state_connected_infra(mac_ctx, sessionId)) - csr_roam_link_up(mac_ctx, - session->connectedProfile.bssid); + WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type, + LOG_WLAN_IBSS_C); + if (!pIbssLog) + return; + pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING; + if (pNewBss) { + qdf_copy_macaddr(&pIbssLog->bssid, &pNewBss->bssId); + if (pNewBss->ssId.length > HOST_LOG_MAX_SSID_SIZE) + pNewBss->ssId.length = HOST_LOG_MAX_SSID_SIZE; + qdf_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId, + pNewBss->ssId.length); + pIbssLog->op_freq = pNewBss->freq; + pIbssLog->operatingChannel = wlan_reg_freq_to_chan + (mac_ctx->pdev, + pIbssLog->op_freq); } - if (eSIR_SME_SUCCESS == pRsp->status_code) { - qdf_copy_macaddr(&roam_info->peerMac, &pRsp->peer_macaddr); - /* Make sure we install the GTK before indicating to HDD as - * authenticated. This is to prevent broadcast packets go out - * after PTK and before GTK. - */ - if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) { - /* - * OBSS SCAN Indication will be sent to Firmware - * to start OBSS Scan - */ - if (mac_ctx->obss_scan_offload && - CSR_IS_CHANNEL_24GHZ( - session->connectedProfile.operationChannel) - && (session->connectState == - eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED) - && session->pCurRoamProfile - && ((QDF_P2P_CLIENT_MODE == - session->pCurRoamProfile->csrPersona) - || (QDF_STA_MODE == - session->pCurRoamProfile->csrPersona))) { - struct sme_obss_ht40_scanind_msg *msg; + bi = mac_ctx->mlme_cfg->sap_cfg.beacon_interval; + /* U8 is not enough for beacon interval */ + pIbssLog->beaconInterval = (uint8_t) bi; + WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + +static void +csr_roam_chk_lnk_wm_status_change_ntf(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) +{ + struct csr_roam_session *session; + uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; + QDF_STATUS status; + struct csr_roam_info *roam_info; + struct wm_status_change_ntf *pStatusChangeMsg; + struct ap_new_caps *pApNewCaps; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + struct new_bss_info *pNewBss; + eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED; + + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + pStatusChangeMsg = (struct wm_status_change_ntf *) msg_ptr; + switch (pStatusChangeMsg->statusChangeCode) { + case eSIR_SME_IBSS_ACTIVE: + sessionId = csr_find_ibss_session(mac_ctx); + if (WLAN_UMAC_VDEV_ID_MAX == sessionId) + break; + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", + sessionId); + goto out; + } + session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED; + if (session->pConnectBssDesc) { + qdf_mem_copy(&roam_info->bssid, + session->pConnectBssDesc->bssId, + sizeof(struct qdf_mac_addr)); + roam_info->u.pConnectedProfile = + &session->connectedProfile; + } else { + sme_err("CSR: connected BSS is empty"); + } + result = eCSR_ROAM_RESULT_IBSS_CONNECT; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + break; + + case eSIR_SME_IBSS_INACTIVE: + sessionId = csr_find_ibss_session(mac_ctx); + if (WLAN_UMAC_VDEV_ID_MAX != sessionId) { + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", sessionId); + goto out; + } + session->connectState = + eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; + result = eCSR_ROAM_RESULT_IBSS_INACTIVE; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + } + break; - msg = qdf_mem_malloc(sizeof( - struct sme_obss_ht40_scanind_msg)); - if (!msg) { - qdf_mem_free(roam_info); - return; - } + case eSIR_SME_JOINED_NEW_BSS: + /* IBSS coalescing. */ + sme_debug("CSR: eSIR_SME_JOINED_NEW_BSS received from PE"); + sessionId = csr_find_ibss_session(mac_ctx); + if (WLAN_UMAC_VDEV_ID_MAX == sessionId) + break; + session = CSR_GET_SESSION(mac_ctx, sessionId); + if (!session) { + sme_err("session %d not found", + sessionId); + goto out; + } + /* update the connection state information */ + pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + csr_roam_diag_joined_new_bss(mac_ctx, pNewBss); +#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ + csr_roam_update_connected_profile_from_new_bss(mac_ctx, + sessionId, + pNewBss); - msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND; - msg->length = - sizeof(struct sme_obss_ht40_scanind_msg); - qdf_copy_macaddr(&msg->mac_addr, - &session->connectedProfile.bssid); - status = umac_send_mb_message_to_mac(msg); - } - result = eCSR_ROAM_RESULT_AUTHENTICATED; - } else { - result = eCSR_ROAM_RESULT_NONE; + if ((eCSR_ENCRYPT_TYPE_NONE == + session->connectedProfile.EncryptionType)) { + csr_issue_set_context_req_helper(mac_ctx, + session->pCurRoamProfile, sessionId, + &Broadcastaddr, false, false, + eSIR_TX_RX, 0, 0, NULL); } - } else { - result = eCSR_ROAM_RESULT_FAILURE; - sme_err( - "CSR: setkey command failed(err=%d) PeerMac " - QDF_MAC_ADDR_STR, - pRsp->status_code, - QDF_MAC_ADDR_ARRAY(pRsp->peer_macaddr.bytes)); - } - /* keeping roam_id = 0 as nobody is using roam_id for set_key */ - csr_roam_call_callback(mac_ctx, sessionId, roam_info, - 0, eCSR_ROAM_SET_KEY_COMPLETE, result); - /* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS - * can go ahead and initiate the TSPEC if any are pending + result = eCSR_ROAM_RESULT_IBSS_COALESCED; + roamStatus = eCSR_ROAM_IBSS_IND; + qdf_mem_copy(&roam_info->bssid, &pNewBss->bssId, + sizeof(struct qdf_mac_addr)); + /* This BSSID is the real BSSID, save it */ + if (session->pConnectBssDesc) + qdf_mem_copy(session->pConnectBssDesc->bssId, + &pNewBss->bssId, sizeof(struct qdf_mac_addr)); + break; + + /* + * detection by LIM that the capabilities of the associated + * AP have changed. */ - sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId, - SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL); -#ifdef FEATURE_WLAN_ESE - /* Send Adjacent AP repot to new AP. */ - if (result == eCSR_ROAM_RESULT_AUTHENTICATED - && session->isPrevApInfoValid - && session->connectedProfile.isESEAssoc) { - csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session); - session->isPrevApInfoValid = false; + case eSIR_SME_AP_CAPS_CHANGED: + pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps; + sme_debug("CSR handling eSIR_SME_AP_CAPS_CHANGED"); + status = csr_roam_get_session_id_from_bssid(mac_ctx, + &pApNewCaps->bssId, &sessionId); + if (!QDF_IS_STATUS_SUCCESS(status)) + break; + if (eCSR_ROAMING_STATE_JOINED == + sme_get_current_roam_state(MAC_HANDLE(mac_ctx), sessionId) + && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC + == mac_ctx->roam.curSubState[sessionId]) + || (eCSR_ROAM_SUBSTATE_NONE == + mac_ctx->roam.curSubState[sessionId]) + || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC + == mac_ctx->roam.curSubState[sessionId]) + || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC == + mac_ctx->roam.curSubState[sessionId]))) { + sme_warn("Calling csr_roam_disconnect_internal"); + csr_roam_disconnect_internal(mac_ctx, sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED, + eSIR_MAC_UNSPEC_FAILURE_REASON); + } else { + sme_warn("Skipping the new scan as CSR is in state: %s and sub-state: %s", + mac_trace_getcsr_roam_state( + mac_ctx->roam.curState[sessionId]), + mac_trace_getcsr_roam_sub_state( + mac_ctx->roam.curSubState[sessionId])); + /* We ignore the caps change event if CSR is not in full + * connected state. Send one event to PE to reset + * limSentCapsChangeNtf Once limSentCapsChangeNtf set + * 0, lim can send sub sequent CAPS change event + * otherwise lim cannot send any CAPS change events to + * SME + */ + csr_send_reset_ap_caps_changed(mac_ctx, + &pApNewCaps->bssId); + } + break; + + default: + roamStatus = eCSR_ROAM_FAILED; + result = eCSR_ROAM_RESULT_NONE; + break; + } /* end switch on statusChangeCode */ + if (eCSR_ROAM_RESULT_NONE != result) { + csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0, + roamStatus, result); } -#endif +out: qdf_mem_free(roam_info); - return; } - static void csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { @@ -13061,20 +13248,12 @@ void csr_roam_check_for_link_status_change(struct mac_context *mac, case eWNI_SME_SETCONTEXT_RSP: csr_roam_chk_lnk_set_ctx_rsp(mac, pSirMsg); break; - case eWNI_SME_GET_STATISTICS_RSP: - sme_debug("Stats rsp from PE"); - csr_roam_stats_rsp_processor(mac, pSirMsg); - break; #ifdef FEATURE_WLAN_ESE case eWNI_SME_GET_TSM_STATS_RSP: sme_debug("TSM Stats rsp from PE"); csr_tsm_stats_rsp_processor(mac, pSirMsg); break; #endif /* FEATURE_WLAN_ESE */ - case eWNI_SME_GET_RSSI_REQ: - sme_debug("GetRssiReq from self"); - csr_update_rssi(mac, pSirMsg); - break; case eWNI_SME_GET_SNR_REQ: sme_debug("GetSnrReq from self"); csr_update_snr(mac, pSirMsg); @@ -13337,194 +13516,63 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); QDF_STATUS status = QDF_STATUS_E_FAILURE; - if (!pSession) { - sme_err("session not found"); - return; - } - - sme_debug("WaitForKey timer expired in state: %s sub-state: %s", - mac_trace_get_neighbour_roam_state(mac->roam. - neighborRoamInfo[vdev_id]. - neighborRoamState), - mac_trace_getcsr_roam_sub_state(mac->roam. - curSubState[vdev_id])); - spin_lock(&mac->roam.roam_state_lock); - if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) { - /* Change the substate so command queue is unblocked. */ - if (vdev_id < WLAN_MAX_VDEVS) - mac->roam.curSubState[vdev_id] = - eCSR_ROAM_SUBSTATE_NONE; - spin_unlock(&mac->roam.roam_state_lock); - - if (csr_neighbor_roam_is_handoff_in_progress(mac, vdev_id)) { - /* - * Enable heartbeat timer when hand-off is in progress - * and Key Wait timer expired. - */ - sme_debug("Enabling HB timer after WaitKey expiry nHBCount: %d)", - mac->roam.configParam.HeartbeatThresh24); - if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD, - mac->roam.configParam. - HeartbeatThresh24)) - mac->mlme_cfg->timeouts.heart_beat_threshold = - mac->roam.configParam.HeartbeatThresh24; - else - mac->mlme_cfg->timeouts.heart_beat_threshold = - cfg_default(CFG_HEART_BEAT_THRESHOLD); - } - sme_debug("SME pre-auth state timeout"); - - status = sme_acquire_global_lock(&mac->sme); - if (csr_is_conn_state_connected_infra(mac, vdev_id)) { - csr_roam_link_up(mac, - pSession->connectedProfile.bssid); - if (QDF_IS_STATUS_SUCCESS(status)) { - csr_roam_disconnect(mac, vdev_id, - eCSR_DISCONNECT_REASON_UNSPECIFIED, - eSIR_MAC_KEY_TIMEOUT); - } - } else { - sme_err("session not found"); - } - sme_release_global_lock(&mac->sme); - } else { - spin_unlock(&mac->roam.roam_state_lock); - } - -} - -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, - struct csr_roam_profile *profile, - const tSirMacAddr bssid, int channel, - uint8_t vdev_id, const tSirMacAddr connected_bssid) -{ - QDF_STATUS status; - struct wma_roam_invoke_cmd *fastreassoc; - struct scheduler_msg msg = {0}; - struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - struct csr_roam_session *session; - struct wlan_objmgr_vdev *vdev; - struct mlme_roam_after_data_stall *vdev_roam_params; - bool roam_control_bitmap; - - session = CSR_GET_SESSION(mac_ctx, vdev_id); - if (!session) { - sme_err("session %d not found", vdev_id); - return QDF_STATUS_E_FAILURE; - } - - if (!csr_is_conn_state_connected(mac_ctx, vdev_id)) { - sme_debug("Not in connected state, Roam Invoke not sent"); - return QDF_STATUS_E_FAILURE; - } - - roam_control_bitmap = mlme_get_operations_bitmap(mac_ctx->psoc, - vdev_id); - if (roam_control_bitmap || - !MLME_IS_ROAM_INITIALIZED(mac_ctx->psoc, vdev_id)) { - sme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]", - vdev_id, roam_control_bitmap); - return QDF_STATUS_E_FAILURE; - } - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, - WLAN_LEGACY_SME_ID); - - if (!vdev) { - sme_err("vdev is NULL, aborting roam invoke"); - return QDF_STATUS_E_NULL_VALUE; - } - - vdev_roam_params = mlme_get_roam_invoke_params(vdev); - - if (!vdev_roam_params) { - sme_err("Invalid vdev roam params, aborting roam invoke"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return QDF_STATUS_E_NULL_VALUE; - } - - if (vdev_roam_params->roam_invoke_in_progress) { - sme_debug("Roaming in progress set by source = %d, aborting this roam invoke", - vdev_roam_params->source); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return QDF_STATUS_E_FAILURE; - } - - fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc)); - if (!fastreassoc) { - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return QDF_STATUS_E_NOMEM; - } - /* if both are same then set the flag */ - if (!qdf_mem_cmp(connected_bssid, bssid, ETH_ALEN)) { - fastreassoc->is_same_bssid = true; - sme_debug("bssid same, bssid[%pM]", bssid); - } - fastreassoc->vdev_id = vdev_id; - fastreassoc->bssid[0] = bssid[0]; - fastreassoc->bssid[1] = bssid[1]; - fastreassoc->bssid[2] = bssid[2]; - fastreassoc->bssid[3] = bssid[3]; - fastreassoc->bssid[4] = bssid[4]; - fastreassoc->bssid[5] = bssid[5]; - - status = sme_get_beacon_frm(mac_handle, profile, bssid, - &fastreassoc->frame_buf, - &fastreassoc->frame_len, - &channel); - - if (!channel) { - sme_err("channel retrieval from BSS desc fails!"); - qdf_mem_free(fastreassoc->frame_buf); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; - qdf_mem_free(fastreassoc); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return QDF_STATUS_E_FAULT; + if (!pSession) { + sme_err("session not found"); + return; } - fastreassoc->channel = channel; - if (QDF_STATUS_SUCCESS != status) { - sme_warn("sme_get_beacon_frm failed"); - qdf_mem_free(fastreassoc->frame_buf); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; - } + sme_debug("WaitForKey timer expired in state: %s sub-state: %s", + mac_trace_get_neighbour_roam_state(mac->roam. + neighborRoamInfo[vdev_id]. + neighborRoamState), + mac_trace_getcsr_roam_sub_state(mac->roam. + curSubState[vdev_id])); + spin_lock(&mac->roam.roam_state_lock); + if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) { + /* Change the substate so command queue is unblocked. */ + if (vdev_id < WLAN_MAX_VDEVS) + mac->roam.curSubState[vdev_id] = + eCSR_ROAM_SUBSTATE_NONE; + spin_unlock(&mac->roam.roam_state_lock); - if (csr_is_auth_type_ese(mac_ctx->roam.roamSession[vdev_id]. - connectedProfile.AuthType)) { - sme_debug("Beacon is not required for ESE"); - if (fastreassoc->frame_len) { - qdf_mem_free(fastreassoc->frame_buf); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; + if (csr_neighbor_roam_is_handoff_in_progress(mac, vdev_id)) { + /* + * Enable heartbeat timer when hand-off is in progress + * and Key Wait timer expired. + */ + sme_debug("Enabling HB timer after WaitKey expiry nHBCount: %d)", + mac->roam.configParam.HeartbeatThresh24); + if (cfg_in_range(CFG_HEART_BEAT_THRESHOLD, + mac->roam.configParam. + HeartbeatThresh24)) + mac->mlme_cfg->timeouts.heart_beat_threshold = + mac->roam.configParam.HeartbeatThresh24; + else + mac->mlme_cfg->timeouts.heart_beat_threshold = + cfg_default(CFG_HEART_BEAT_THRESHOLD); } - } + sme_debug("SME pre-auth state timeout"); - msg.type = eWNI_SME_ROAM_INVOKE; - msg.reserved = 0; - msg.bodyptr = fastreassoc; - status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_PE, - QDF_MODULE_ID_PE, &msg); - if (QDF_IS_STATUS_ERROR(status)) { - sme_err("Not able to post ROAM_INVOKE_CMD message to PE"); - qdf_mem_free(fastreassoc->frame_buf); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; - qdf_mem_free(fastreassoc); + status = sme_acquire_global_lock(&mac->sme); + if (csr_is_conn_state_connected_infra(mac, vdev_id)) { + csr_roam_link_up(mac, + pSession->connectedProfile.bssid); + if (QDF_IS_STATUS_SUCCESS(status)) { + csr_roam_disconnect(mac, vdev_id, + eCSR_DISCONNECT_REASON_UNSPECIFIED, + eSIR_MAC_KEY_TIMEOUT); + } + } else { + sme_err("session not found"); + } + sme_release_global_lock(&mac->sme); } else { - vdev_roam_params->roam_invoke_in_progress = true; - vdev_roam_params->source = USERSPACE_INITIATED; - sme_debug("Trigger roaming for vdev id %d source = USERSPACE_INITIATED", - session->sessionId); + spin_unlock(&mac->roam.roam_state_lock); } - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return status; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * csr_roam_roaming_offload_timer_action() - API to start/stop the timer * @mac_ctx: MAC Context @@ -13633,30 +13681,30 @@ QDF_STATUS csr_roam_stop_wait_for_key_timer(struct mac_context *mac) return qdf_mc_timer_stop(&mac->roam.hTimerWaitForKey); } -void csr_roam_completion(struct mac_context *mac, uint32_t sessionId, +void csr_roam_completion(struct mac_context *mac, uint32_t vdev_id, struct csr_roam_info *roam_info, tSmeCmd *pCommand, eCsrRoamResult roamResult, bool fSuccess) { eRoamCmdStatus roamStatus = csr_get_roam_complete_status(mac, - sessionId); + vdev_id); uint32_t roamId = 0; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); + struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); if (!pSession) { - sme_err("session: %d not found ", sessionId); + sme_err("session: %d not found ", vdev_id); return; } if (pCommand) { roamId = pCommand->u.roamCmd.roamId; - if (sessionId != pCommand->sessionId) { - QDF_ASSERT(sessionId == pCommand->sessionId); + if (vdev_id != pCommand->vdev_id) { + QDF_ASSERT(vdev_id == pCommand->vdev_id); return; } } if (eCSR_ROAM_ROAMING_COMPLETION == roamStatus) /* if success, force roaming completion */ - csr_roam_complete_roaming(mac, sessionId, fSuccess, + csr_roam_complete_roaming(mac, vdev_id, fSuccess, roamResult); else { if (pSession->bRefAssocStartCnt != 0) { @@ -13665,7 +13713,7 @@ void csr_roam_completion(struct mac_context *mac, uint32_t sessionId, } sme_debug("indicates association completion roamResult: %d", roamResult); - csr_roam_call_callback(mac, sessionId, roam_info, roamId, + csr_roam_call_callback(mac, vdev_id, roam_info, roamId, roamStatus, roamResult); } } @@ -13714,12 +13762,10 @@ QDF_STATUS csr_roam_lost_link(struct mac_context *mac, uint32_t sessionId, pSession->joinFailStatusCode.reasonCode = 1; } - if (type == eWNI_SME_DISASSOC_IND || type == eWNI_SME_DEAUTH_IND) - csr_get_peer_rssi(mac, sessionId, roam_info->peerMac); - mlme_set_discon_reason_n_from_ap(mac->psoc, sessionId, from_ap, pSession->joinFailStatusCode.reasonCode); + csr_roam_call_callback(mac, sessionId, NULL, 0, eCSR_ROAM_LOSTLINK_DETECTED, result); @@ -13752,6 +13798,28 @@ QDF_STATUS csr_roam_lost_link(struct mac_context *mac, uint32_t sessionId, return status; } +void csr_roam_get_disconnect_stats_complete(struct mac_context *mac) +{ + tListElem *entry; + tSmeCmd *cmd; + + entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); + if (!entry) { + sme_err("NO commands are ACTIVE ..."); + return; + } + + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + if (cmd->command != eSmeCommandGetdisconnectStats) { + sme_err("Get disconn stats cmd is not ACTIVE ..."); + return; + } + + if (csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK)) + csr_release_command(mac, cmd); + else + sme_err("Failed to release command"); +} void csr_roam_wm_status_change_complete(struct mac_context *mac, uint8_t session_id) @@ -13779,20 +13847,27 @@ void csr_roam_wm_status_change_complete(struct mac_context *mac, } } +void csr_roam_process_get_disconnect_stats_command(struct mac_context *mac, + tSmeCmd *cmd) +{ + csr_get_peer_rssi(mac, cmd->vdev_id, + cmd->u.disconnect_stats_cmd.peer_mac_addr); +} + void csr_roam_process_wm_status_change_command( struct mac_context *mac, tSmeCmd *pCommand) { QDF_STATUS status = QDF_STATUS_E_FAILURE; tSirSmeRsp *pSirSmeMsg; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, - pCommand->sessionId); + pCommand->vdev_id); if (!pSession) { - sme_err("session %d not found", pCommand->sessionId); + sme_err("session %d not found", pCommand->vdev_id); goto end; } sme_debug("session:%d, CmdType : %d", - pCommand->sessionId, pCommand->u.wmStatusChangeCmd.Type); + pCommand->vdev_id, pCommand->u.wmStatusChangeCmd.Type); switch (pCommand->u.wmStatusChangeCmd.Type) { case eCsrDisassociated: @@ -13800,7 +13875,7 @@ void csr_roam_process_wm_status_change_command( (tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u. DisassocIndMsg; status = - csr_roam_lost_link(mac, pCommand->sessionId, + csr_roam_lost_link(mac, pCommand->vdev_id, eWNI_SME_DISASSOC_IND, pSirSmeMsg); break; case eCsrDeauthenticated: @@ -13808,7 +13883,7 @@ void csr_roam_process_wm_status_change_command( (tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u. DeauthIndMsg; status = - csr_roam_lost_link(mac, pCommand->sessionId, + csr_roam_lost_link(mac, pCommand->vdev_id, eWNI_SME_DEAUTH_IND, pSirSmeMsg); break; default: @@ -13823,50 +13898,16 @@ void csr_roam_process_wm_status_change_command( * As status returned is not success, there is nothing else * left to do so release WM status change command here. */ - csr_roam_wm_status_change_complete(mac, pCommand->sessionId); - } -} - -QDF_STATUS csr_process_del_sta_session_command(struct mac_context *mac_ctx, - tSmeCmd *sme_command) -{ - struct del_sta_self_params *del_sta_self_req; - struct scheduler_msg msg = {0}; - QDF_STATUS status; - - del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params)); - if (!del_sta_self_req) - return QDF_STATUS_E_NOMEM; - - qdf_mem_copy(del_sta_self_req->self_mac_addr, - sme_command->u.delStaSessionCmd.self_mac_addr, - sizeof(tSirMacAddr)); - - del_sta_self_req->session_id = sme_command->sessionId; - del_sta_self_req->sme_callback = - sme_command->u.delStaSessionCmd.session_close_cb; - del_sta_self_req->sme_ctx = sme_command->u.delStaSessionCmd.context; - msg.type = WMA_DEL_STA_SELF_REQ; - msg.reserved = 0; - msg.bodyptr = del_sta_self_req; - msg.bodyval = 0; - - sme_debug("sending WMA_DEL_STA_SELF_REQ"); - status = wma_post_ctrl_msg(mac_ctx, &msg); - if (status != QDF_STATUS_SUCCESS) { - sme_err("wma_post_ctrl_msg failed"); - qdf_mem_free(del_sta_self_req); - return QDF_STATUS_E_FAILURE; + csr_roam_wm_status_change_complete(mac, pCommand->vdev_id); } - return QDF_STATUS_SUCCESS; } /** * csr_compute_mode_and_band() - computes dot11mode - * @mac: mac global context - * @dot11_mode: out param, do11 mode calculated - * @band: out param, band caclculated - * @opr_ch: operating channels + * @mac: mac global context + * @dot11_mode: out param, do11 mode calculated + * @band: out param, band caclculated + * @opr_ch_freq: operating channel freq in MHz * * This function finds dot11 mode based on current mode, operating channel and * fw supported modes. @@ -13876,27 +13917,27 @@ QDF_STATUS csr_process_del_sta_session_command(struct mac_context *mac_ctx, static void csr_compute_mode_and_band(struct mac_context *mac_ctx, enum csr_cfgdot11mode *dot11_mode, - enum band_info *band, - uint8_t opr_ch) + enum reg_wifi_band *band, + uint32_t opr_ch_freq) { bool vht_24_ghz = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band; switch (mac_ctx->roam.configParam.uCfgDot11Mode) { case eCSR_CFG_DOT11_MODE_11A: *dot11_mode = eCSR_CFG_DOT11_MODE_11A; - *band = BAND_5G; + *band = REG_BAND_5G; break; case eCSR_CFG_DOT11_MODE_11B: *dot11_mode = eCSR_CFG_DOT11_MODE_11B; - *band = BAND_2G; + *band = REG_BAND_2G; break; case eCSR_CFG_DOT11_MODE_11G: *dot11_mode = eCSR_CFG_DOT11_MODE_11G; - *band = BAND_2G; + *band = REG_BAND_2G; break; case eCSR_CFG_DOT11_MODE_11N: *dot11_mode = eCSR_CFG_DOT11_MODE_11N; - *band = CSR_GET_BAND(opr_ch); + *band = wlan_reg_freq_to_band(opr_ch_freq); break; case eCSR_CFG_DOT11_MODE_11AC: if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { @@ -13904,7 +13945,8 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * If the operating channel is in 2.4 GHz band, check * for INI item to disable VHT operation in 2.4 GHz band */ - if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz) + if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && + !vht_24_ghz) /* Disable 11AC operation */ *dot11_mode = eCSR_CFG_DOT11_MODE_11N; else @@ -13912,7 +13954,7 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, } else { *dot11_mode = eCSR_CFG_DOT11_MODE_11N; } - *band = CSR_GET_BAND(opr_ch); + *band = wlan_reg_freq_to_band(opr_ch_freq); break; case eCSR_CFG_DOT11_MODE_11AC_ONLY: if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { @@ -13920,7 +13962,8 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * If the operating channel is in 2.4 GHz band, check * for INI item to disable VHT operation in 2.4 GHz band */ - if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz) + if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && + !vht_24_ghz) /* Disable 11AC operation */ *dot11_mode = eCSR_CFG_DOT11_MODE_11N; else @@ -13928,7 +13971,7 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, } else { *dot11_mode = eCSR_CFG_DOT11_MODE_11N; } - *band = CSR_GET_BAND(opr_ch); + *band = wlan_reg_freq_to_band(opr_ch_freq); break; case eCSR_CFG_DOT11_MODE_11AX: case eCSR_CFG_DOT11_MODE_11AX_ONLY: @@ -13939,7 +13982,8 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * If the operating channel is in 2.4 GHz band, check * for INI item to disable VHT operation in 2.4 GHz band */ - if (WLAN_REG_IS_24GHZ_CH(opr_ch) && !vht_24_ghz) + if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && + !vht_24_ghz) /* Disable 11AC operation */ *dot11_mode = eCSR_CFG_DOT11_MODE_11N; else @@ -13947,7 +13991,7 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, } else { *dot11_mode = eCSR_CFG_DOT11_MODE_11N; } - *band = CSR_GET_BAND(opr_ch); + *band = wlan_reg_freq_to_band(opr_ch_freq); break; case eCSR_CFG_DOT11_MODE_AUTO: if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) { @@ -13958,8 +14002,8 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * check for INI item to disable VHT operation * in 2.4 GHz band */ - if (WLAN_REG_IS_24GHZ_CH(opr_ch) - && !vht_24_ghz) + if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && + !vht_24_ghz) /* Disable 11AC operation */ *dot11_mode = eCSR_CFG_DOT11_MODE_11N; else @@ -13967,16 +14011,17 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, } else { *dot11_mode = eCSR_CFG_DOT11_MODE_11N; } - *band = CSR_GET_BAND(opr_ch); + *band = wlan_reg_freq_to_band(opr_ch_freq); break; default: /* * Global dot11 Mode setting is 11a/b/g. use the channel number * to determine the Mode setting. */ - if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch) { - *band = mac_ctx->mlme_cfg->gen.band; - if (BAND_2G == *band) { + if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch_freq) { + *band = (mac_ctx->mlme_cfg->gen.band == BAND_2G ? + REG_BAND_2G : REG_BAND_5G); + if (REG_BAND_2G == *band) { /* * See reason in else if ( WLAN_REG_IS_24GHZ_CH * (opr_ch) ) to pick 11B @@ -13984,10 +14029,10 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, *dot11_mode = eCSR_CFG_DOT11_MODE_11B; } else { /* prefer 5GHz */ - *band = BAND_5G; + *band = REG_BAND_5G; *dot11_mode = eCSR_CFG_DOT11_MODE_11A; } - } else if (WLAN_REG_IS_24GHZ_CH(opr_ch)) { + } else if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq)) { /* * WiFi tests require IBSS networks to start in 11b mode * without any change to the default parameter settings @@ -14006,11 +14051,11 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * to force it. */ *dot11_mode = eCSR_CFG_DOT11_MODE_11B; - *band = BAND_2G; + *band = REG_BAND_2G; } else { /* else, it's a 5.0GHz channel. Set mode to 11a. */ *dot11_mode = eCSR_CFG_DOT11_MODE_11A; - *band = BAND_5G; + *band = REG_BAND_5G; } break; } /* switch */ @@ -14021,8 +14066,8 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, * information. * @mac_ctx: mac global context * @profile: bss profile + * @bss_op_ch_freq:operating channel freq in MHz * @band: out param, band caclculated - * @opr_ch: operating channels * * This function finds dot11 mode based on current mode, operating channel and * fw supported modes. The only tricky part is that if phyMode is set to 11abg, @@ -14034,16 +14079,21 @@ csr_compute_mode_and_band(struct mac_context *mac_ctx, static enum csr_cfgdot11mode csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac_ctx, struct csr_roam_profile *profile, - uint8_t opr_chn, - enum band_info *p_band) + uint32_t bss_op_ch_freq, + enum reg_wifi_band *p_band) { - enum band_info band; -enum csr_cfgdot11mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode; + enum reg_wifi_band band = REG_BAND_2G; + uint8_t opr_freq = 0; + enum csr_cfgdot11mode curr_mode = + mac_ctx->roam.configParam.uCfgDot11Mode; enum csr_cfgdot11mode cfg_dot11_mode = - csr_get_cfg_dot11_mode_from_csr_phy_mode(profile, + csr_get_cfg_dot11_mode_from_csr_phy_mode( + profile, (eCsrPhyMode) profile->phyMode, mac_ctx->roam.configParam.ProprietaryRatesEnabled); + if (bss_op_ch_freq) + opr_freq = bss_op_ch_freq; /* * If the global setting for dot11Mode is set to auto/abg, we overwrite * the setting in the profile. @@ -14054,30 +14104,29 @@ enum csr_cfgdot11mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode; || (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode) || (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) { csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode, - &band, opr_chn); + &band, bss_op_ch_freq); } /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */ else { /* dot11 mode is set, lets pick the band */ - if (eCSR_OPERATING_CHANNEL_AUTO == opr_chn) { + if (0 == opr_freq) { /* channel is Auto also. */ - band = mac_ctx->mlme_cfg->gen.band; - if (BAND_ALL == band) { + if (mac_ctx->mlme_cfg->gen.band == BAND_ALL) { /* prefer 5GHz */ - band = BAND_5G; + band = REG_BAND_5G; } } else{ - band = CSR_GET_BAND(opr_chn); + band = wlan_reg_freq_to_band(bss_op_ch_freq); } } if (p_band) *p_band = band; - if (opr_chn == 14) { + if (opr_freq == 2484 && wlan_reg_is_24ghz_ch_freq(bss_op_ch_freq)) { sme_err("Switching to Dot11B mode"); cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B; } - if (IS_24G_CH(opr_chn) && + if (wlan_reg_is_24ghz_ch_freq(bss_op_ch_freq) && !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode || eCSR_CFG_DOT11_MODE_11AC_ONLY == cfg_dot11_mode)) @@ -14094,12 +14143,13 @@ enum csr_cfgdot11mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode; (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode) || (eCSR_CFG_DOT11_MODE_11AX == cfg_dot11_mode))) { /* We cannot do 11n here */ - if (WLAN_REG_IS_24GHZ_CH(opr_chn)) + if (wlan_reg_is_24ghz_ch_freq(bss_op_ch_freq)) cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G; else cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A; } - sme_debug("dot11mode: %d", cfg_dot11_mode); + sme_debug("dot11mode: %d phyMode %d fw sup AX %d", cfg_dot11_mode, + profile->phyMode, IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)); return cfg_dot11_mode; } @@ -14138,56 +14188,60 @@ QDF_STATUS csr_roam_issue_stop_bss(struct mac_context *mac, return status; } -/* pNumChan is a caller allocated space with the sizeof pChannels */ -QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac, uint8_t *pChannels, - uint32_t *pNumChan) +QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac, + uint32_t *ch_freq_list, + uint32_t *num_ch_freq) { uint8_t num_chan_temp = 0; int i; + uint32_t *valid_ch_freq_list = + mac->mlme_cfg->reg.valid_channel_freq_list; - *pNumChan = (uint32_t)mac->mlme_cfg->reg.valid_channel_list_num; - qdf_mem_copy(pChannels, mac->mlme_cfg->reg.valid_channel_list, - *pNumChan); + *num_ch_freq = mac->mlme_cfg->reg.valid_channel_list_num; - for (i = 0; i < *pNumChan; i++) { - if (!wlan_reg_is_dsrc_chan(mac->pdev, pChannels[i])) { - pChannels[num_chan_temp] = pChannels[i]; + for (i = 0; i < *num_ch_freq; i++) { + if (!wlan_reg_is_dsrc_freq(valid_ch_freq_list[i])) { + ch_freq_list[num_chan_temp] = valid_ch_freq_list[i]; num_chan_temp++; } } - *pNumChan = num_chan_temp; + *num_ch_freq = num_chan_temp; return QDF_STATUS_SUCCESS; } -int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel) +int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint32_t ch_freq) { uint32_t cfg_length = 0; int8_t maxTxPwr = 0; - uint8_t *pCountryInfo = NULL; + tSirMacChanInfo *pCountryInfo = NULL; uint8_t count = 0; - uint8_t firstChannel; uint8_t maxChannels; + int32_t rem_length = 0; - if (WLAN_REG_IS_5GHZ_CH(channel)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) { cfg_length = mac->mlme_cfg->power.max_tx_power_5.len; - } else if (WLAN_REG_IS_24GHZ_CH(channel)) { + } else if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { cfg_length = mac->mlme_cfg->power.max_tx_power_24.len; - } else + } else if (wlan_reg_is_6ghz_chan_freq(ch_freq)) { + return wlan_reg_get_channel_reg_power_for_freq(mac->pdev, + ch_freq); + } else { return maxTxPwr; + } pCountryInfo = qdf_mem_malloc(cfg_length); if (!pCountryInfo) goto error; - if (WLAN_REG_IS_5GHZ_CH(channel)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) { if (cfg_length > CFG_MAX_TX_POWER_5_LEN) goto error; qdf_mem_copy(pCountryInfo, mac->mlme_cfg->power.max_tx_power_5.data, cfg_length); - } else if (WLAN_REG_IS_24GHZ_CH(channel)) { + } else if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { if (cfg_length > CFG_MAX_TX_POWER_2_4_LEN) goto error; qdf_mem_copy(pCountryInfo, @@ -14196,13 +14250,15 @@ int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel) } /* Identify the channel and maxtxpower */ - while (count <= (cfg_length - (sizeof(tSirMacChanInfo)))) { - firstChannel = pCountryInfo[count++]; - maxChannels = pCountryInfo[count++]; - maxTxPwr = pCountryInfo[count++]; - - if ((channel >= firstChannel) && - (channel < (firstChannel + maxChannels))) { + rem_length = cfg_length; + while (rem_length >= (sizeof(tSirMacChanInfo))) { + maxChannels = pCountryInfo[count].numChannels; + maxTxPwr = pCountryInfo[count].maxTxPower; + count++; + rem_length -= (sizeof(tSirMacChanInfo)); + + if (ch_freq >= pCountryInfo[count].first_freq && + ch_freq < (pCountryInfo[count].first_freq + maxChannels)) { break; } } @@ -14214,38 +14270,38 @@ int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel) return maxTxPwr; } -bool csr_roam_is_channel_valid(struct mac_context *mac, uint8_t channel) +bool csr_roam_is_channel_valid(struct mac_context *mac, uint32_t chan_freq) { - bool fValid = false; - uint32_t idxValidChannels; - uint32_t len = sizeof(mac->roam.validChannelList); + bool valid = false; + uint32_t id_valid_ch; + uint32_t len = sizeof(mac->roam.valid_ch_freq_list); if (QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(mac, - mac->roam.validChannelList, &len))) { - for (idxValidChannels = 0; (idxValidChannels < len); - idxValidChannels++) { - if (channel == - mac->roam.validChannelList[idxValidChannels]) { - fValid = true; + mac->roam.valid_ch_freq_list, &len))) { + for (id_valid_ch = 0; (id_valid_ch < len); + id_valid_ch++) { + if (chan_freq == + mac->roam.valid_ch_freq_list[id_valid_ch]) { + valid = true; break; } } } mac->roam.numValidChannels = len; - return fValid; + return valid; } /* This function check and validate whether the NIC can do CB (40MHz) */ static ePhyChanBondState csr_get_cb_mode_from_ies(struct mac_context *mac, - uint8_t chan, + uint32_t ch_freq, tDot11fBeaconIEs *pIes) { ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED; - uint8_t sec_ch = 0; + uint32_t sec_ch_freq = 0; uint32_t ChannelBondingMode; struct ch_params ch_params = {0}; - if (WLAN_REG_IS_24GHZ_CH(chan)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { ChannelBondingMode = mac->roam.configParam.channelBondingMode24GHz; } else { @@ -14285,10 +14341,10 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(struct mac_context *mac, * value of supported channel width and recommended tx width as per * standard */ - sme_debug("chan %d scws %u rtws %u sco %u", chan, - pIes->HTCaps.supportedChannelWidthSet, - pIes->HTInfo.recommendedTxWidthSet, - pIes->HTInfo.secondaryChannelOffset); + sme_debug("ch freq %d scws %u rtws %u sco %u", ch_freq, + pIes->HTCaps.supportedChannelWidthSet, + pIes->HTInfo.recommendedTxWidthSet, + pIes->HTInfo.secondaryChannelOffset); if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ) eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset; @@ -14297,10 +14353,10 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(struct mac_context *mac, switch (eRet) { case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: - sec_ch = chan + CSR_SEC_CHANNEL_OFFSET; + sec_ch_freq = ch_freq + CSR_SEC_CHANNEL_OFFSET; break; case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: - sec_ch = chan - CSR_SEC_CHANNEL_OFFSET; + sec_ch_freq = ch_freq - CSR_SEC_CHANNEL_OFFSET; break; default: break; @@ -14308,12 +14364,12 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(struct mac_context *mac, if (eRet != PHY_SINGLE_CHANNEL_CENTERED) { ch_params.ch_width = CH_WIDTH_40MHZ; - wlan_reg_set_channel_params(mac->pdev, chan, - sec_ch, &ch_params); + wlan_reg_set_channel_params_for_freq(mac->pdev, ch_freq, + sec_ch_freq, &ch_params); if (ch_params.ch_width == CH_WIDTH_20MHZ || ch_params.sec_ch_offset != eRet) { - sme_err("chan %d :: Supported HT BW %d and cbmode %d, APs HT BW %d and cbmode %d, so switch to 20Mhz", - chan, ch_params.ch_width, + sme_err("ch freq %d :: Supported HT BW %d and cbmode %d, APs HT BW %d and cbmode %d, so switch to 20Mhz", + ch_freq, ch_params.ch_width, ch_params.sec_ch_offset, pIes->HTInfo.recommendedTxWidthSet, eRet); eRet = PHY_SINGLE_CHANNEL_CENTERED; @@ -14360,24 +14416,14 @@ bool csr_is_same_profile(struct mac_context *mac, { uint32_t i; bool fCheck = false; - tCsrScanResultFilter *pScanFilter = NULL; - QDF_STATUS status = QDF_STATUS_SUCCESS; if (!(pProfile1 && pProfile2)) return fCheck; - pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); - if (!pScanFilter) - return fCheck; - - status = csr_roam_prepare_filter_from_profile(mac, pProfile2, - pScanFilter); - if (!(QDF_IS_STATUS_SUCCESS(status))) - goto free_scan_filter; - for (i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) { + for (i = 0; i < pProfile2->SSIDs.numOfSSIDs; i++) { fCheck = csr_is_ssid_match(mac, - pScanFilter->SSIDs.SSIDList[i].SSID.ssId, - pScanFilter->SSIDs.SSIDList[i].SSID.length, + pProfile2->SSIDs.SSIDList[i].SSID.ssId, + pProfile2->SSIDs.SSIDList[i].SSID.length, pProfile1->SSID.ssId, pProfile1->SSID.length, false); @@ -14385,7 +14431,7 @@ bool csr_is_same_profile(struct mac_context *mac, break; } if (!fCheck) - goto free_scan_filter; + goto exit; if (!csr_is_auth_in_list(mac, &pProfile2->AuthType, pProfile1->AuthType) @@ -14393,20 +14439,18 @@ bool csr_is_same_profile(struct mac_context *mac, || !csr_is_encryption_in_list(mac, &pProfile2->EncryptionType, pProfile1->EncryptionType)) { fCheck = false; - goto free_scan_filter; + goto exit; } if (pProfile1->mdid.mdie_present || pProfile2->mdid.mdie_present) { if (pProfile1->mdid.mobility_domain != pProfile2->mdid.mobility_domain) { fCheck = false; - goto free_scan_filter; + goto exit; } } /* Match found */ fCheck = true; -free_scan_filter: - csr_free_scan_filter(mac, pScanFilter); - qdf_mem_free(pScanFilter); +exit: return fCheck; } @@ -14451,105 +14495,6 @@ static bool csr_roam_is_same_profile_keys(struct mac_context *mac, return fCheck; } -/* IBSS */ - -static uint8_t csr_roam_get_ibss_start_channel_number50(struct mac_context *mac) -{ - uint8_t channel = 0; - uint32_t idx; - uint32_t idxValidChannels; - bool fFound = false; - uint32_t len = sizeof(mac->roam.validChannelList); - - if (eCSR_OPERATING_CHANNEL_ANY != mac->roam.configParam. - AdHocChannel5G) { - channel = mac->roam.configParam.AdHocChannel5G; - if (!csr_roam_is_channel_valid(mac, channel)) - channel = 0; - } - if (0 == channel - && - QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels - (mac, (uint8_t *) mac->roam. - validChannelList, &len))) { - for (idx = 0; (idx < CSR_NUM_IBSS_START_CHAN_50) && !fFound; - idx++) { - for (idxValidChannels = 0; - (idxValidChannels < len) && !fFound; - idxValidChannels++) { - if (csr_start_ibss_channels50[idx] == - mac->roam. - validChannelList[idxValidChannels]) { - fFound = true; - channel = - csr_start_ibss_channels50[idx]; - } - } - } - /* - * this is rare, but if it does happen, - * we find anyone in 11a bandwidth and - * return the first 11a channel found! - */ - if (!fFound) { - for (idxValidChannels = 0; idxValidChannels < len; - idxValidChannels++) { - if (WLAN_REG_IS_5GHZ_CH(mac->roam. - validChannelList[idxValidChannels])) { - /* the max channel# in 11g is 14 */ - if (idxValidChannels < - CSR_NUM_IBSS_START_CHAN_50) { - channel = - mac->roam.validChannelList - [idxValidChannels]; - } - break; - } - } - } - } /* if */ - - return channel; -} - -static uint8_t csr_roam_get_ibss_start_channel_number24(struct mac_context *mac) -{ - uint8_t channel = 1; - uint32_t idx; - uint32_t idxValidChannels; - bool fFound = false; - uint32_t len = sizeof(mac->roam.validChannelList); - - if (eCSR_OPERATING_CHANNEL_ANY != mac->roam.configParam. - AdHocChannel24) { - channel = mac->roam.configParam.AdHocChannel24; - if (!csr_roam_is_channel_valid(mac, channel)) - channel = 0; - } - - if (0 == channel - && - QDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(mac, - (uint8_t *) mac->roam.validChannelList, - &len))) { - for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_24) && !fFound; - idx++) { - for (idxValidChannels = 0; - (idxValidChannels < len) && !fFound; - idxValidChannels++) { - if (csr_start_ibss_channels24[idx] == - mac->roam. - validChannelList[idxValidChannels]) { - fFound = true; - channel = - csr_start_ibss_channels24[idx]; - } - } - } - } - - return channel; -} /** * csr_populate_basic_rates() - populates OFDM or CCK rates * @rates: rate struct to populate @@ -14619,7 +14564,7 @@ csr_populate_basic_rates(tSirMacRateSet *rate_set, bool is_ofdm_rates, */ static tSirNwType csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode, - enum band_info band) + enum reg_wifi_band band) { switch (dot11_mode) { case eCSR_CFG_DOT11_MODE_11G: @@ -14634,7 +14579,7 @@ csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode, * Because LIM only verifies it against 11a, 11b or 11g, set * only 11g or 11a here */ - if (BAND_2G == band) + if (REG_BAND_2G == band) return eSIR_11G_NW_TYPE; else return eSIR_11A_NW_TYPE; @@ -14709,20 +14654,22 @@ csr_roam_get_bss_start_parms(struct mac_context *mac, struct csr_roamstart_bssparams *pParam, bool skip_hostapd_rate) { - enum band_info band; - uint8_t opr_ch = 0; + enum reg_wifi_band band; + uint32_t opr_ch_freq = 0; tSirNwType nw_type; - uint8_t tmp_opr_ch = 0; + uint32_t tmp_opr_ch_freq = 0; uint8_t h2e; tSirMacRateSet *opr_rates = &pParam->operationalRateSet; tSirMacRateSet *ext_rates = &pParam->extendedRateSet; - if (pProfile->ChannelInfo.numOfChannels - && pProfile->ChannelInfo.ChannelList) - tmp_opr_ch = pProfile->ChannelInfo.ChannelList[0]; + if (pProfile->ChannelInfo.numOfChannels && + pProfile->ChannelInfo.freq_list) + tmp_opr_ch_freq = pProfile->ChannelInfo.freq_list[0]; - pParam->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(mac, - pProfile, tmp_opr_ch, &band); + pParam->uCfgDot11Mode = + csr_roam_get_phy_mode_band_for_bss(mac, pProfile, + tmp_opr_ch_freq, + &band); if (((pProfile->csrPersona == QDF_P2P_CLIENT_MODE) || (pProfile->csrPersona == QDF_P2P_GO_MODE)) @@ -14748,7 +14695,7 @@ csr_roam_get_bss_start_parms(struct mac_context *mac, pProfile->extended_rates.numRates)) { csr_populate_supported_rates_from_hostapd(opr_rates, ext_rates, pProfile); - pParam->operationChn = tmp_opr_ch; + pParam->operation_chan_freq = tmp_opr_ch_freq; } else { switch (nw_type) { default: @@ -14758,12 +14705,12 @@ csr_roam_get_bss_start_parms(struct mac_context *mac, return QDF_STATUS_E_INVAL; case eSIR_11A_NW_TYPE: csr_populate_basic_rates(opr_rates, true, true); - if (eCSR_OPERATING_CHANNEL_ANY != tmp_opr_ch) { - opr_ch = tmp_opr_ch; + if (eCSR_OPERATING_CHANNEL_ANY != tmp_opr_ch_freq) { + opr_ch_freq = tmp_opr_ch_freq; break; } - opr_ch = csr_roam_get_ibss_start_channel_number50(mac); - if (0 == opr_ch && + opr_ch_freq = csr_roam_get_ibss_start_chan_freq50(mac); + if (0 == opr_ch_freq && CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) && CSR_IS_PHY_MODE_DUAL_BAND( mac->roam.configParam.phyMode)) { @@ -14774,19 +14721,18 @@ csr_roam_get_bss_start_parms(struct mac_context *mac, * always picks 11a for AUTO */ nw_type = eSIR_11B_NW_TYPE; - opr_ch = - csr_roam_get_ibss_start_channel_number24(mac); - csr_populate_basic_rates(opr_rates, false, - true); + opr_ch_freq = + csr_roam_get_ibss_start_chan_freq24(mac); + csr_populate_basic_rates(opr_rates, false, true); } break; case eSIR_11B_NW_TYPE: csr_populate_basic_rates(opr_rates, false, true); - if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch) - opr_ch = - csr_roam_get_ibss_start_channel_number24(mac); + if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch_freq) + opr_ch_freq = + csr_roam_get_ibss_start_chan_freq24(mac); else - opr_ch = tmp_opr_ch; + opr_ch_freq = tmp_opr_ch_freq; break; case eSIR_11G_NW_TYPE: /* For P2P Client and P2P GO, disable 11b rates */ @@ -14801,14 +14747,14 @@ csr_roam_get_bss_start_parms(struct mac_context *mac, csr_populate_basic_rates(ext_rates, true, false); } - if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch) - opr_ch = - csr_roam_get_ibss_start_channel_number24(mac); + if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch_freq) + opr_ch_freq = + csr_roam_get_ibss_start_chan_freq24(mac); else - opr_ch = tmp_opr_ch; + opr_ch_freq = tmp_opr_ch_freq; break; } - pParam->operationChn = opr_ch; + pParam->operation_chan_freq = opr_ch_freq; } if (pProfile->require_h2e) { @@ -14852,7 +14798,7 @@ csr_roam_get_bss_start_parms_from_bss_desc( pParam->sirNwType = bss_desc->nwType; pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED; - pParam->operationChn = bss_desc->channelId; + pParam->operation_chan_freq = bss_desc->chan_freq; qdf_mem_copy(&pParam->bssid, bss_desc->bssId, sizeof(struct qdf_mac_addr)); @@ -14896,8 +14842,9 @@ csr_roam_get_bss_start_parms_from_bss_desc( qdf_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid, pParam->ssId.length); } - pParam->cbMode = csr_get_cb_mode_from_ies(mac, pParam->operationChn, - pIes); + pParam->cbMode = + csr_get_cb_mode_from_ies(mac, pParam->operation_chan_freq, + pIes); } static void csr_roam_determine_max_rate_for_ad_hoc(struct mac_context *mac, @@ -14926,7 +14873,7 @@ QDF_STATUS csr_roam_issue_start_bss(struct mac_context *mac, uint32_t sessionId, uint32_t roamId) { QDF_STATUS status = QDF_STATUS_SUCCESS; - enum band_info band; + enum reg_wifi_band band; /* Set the roaming substate to 'Start BSS attempt'... */ csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId); @@ -14955,7 +14902,10 @@ QDF_STATUS csr_roam_issue_start_bss(struct mac_context *mac, uint32_t sessionId, else pIbssLog->channelSetting = SPECIFIED; - pIbssLog->operatingChannel = pParam->operationChn; + pIbssLog->op_freq = pParam->operation_chan_freq; + pIbssLog->operatingChannel = + wlan_reg_freq_to_chan(mac->pdev, + pIbssLog->op_freq); WLAN_HOST_DIAG_LOG_REPORT(pIbssLog); } } @@ -14971,10 +14921,10 @@ QDF_STATUS csr_roam_issue_start_bss(struct mac_context *mac, uint32_t sessionId, pParam->dtimPeriod = pProfile->dtimPeriod; pParam->ApUapsdEnable = pProfile->ApUapsdEnable; pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden; - if (CSR_IS_INFRA_AP(pProfile) && (pParam->operationChn != 0)) { - if (csr_is_valid_channel(mac, pParam->operationChn) != + if (CSR_IS_INFRA_AP(pProfile) && (pParam->operation_chan_freq != 0)) { + if (csr_is_valid_channel(mac, pParam->operation_chan_freq) != QDF_STATUS_SUCCESS) { - pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL; + pParam->operation_chan_freq = INFRA_AP_DEFAULT_CHAN_FREQ; pParam->ch_params.ch_width = CH_WIDTH_20MHZ; } } @@ -14985,8 +14935,7 @@ QDF_STATUS csr_roam_issue_start_bss(struct mac_context *mac, uint32_t sessionId, pParam->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(mac, pProfile, - pParam-> - operationChn, + pParam->operation_chan_freq, &band); pParam->bssPersona = pProfile->csrPersona; @@ -15040,7 +14989,6 @@ void csr_roam_prepare_bss_params(struct mac_context *mac, uint32_t sessionId, struct bss_config_param *pBssConfig, tDot11fBeaconIEs *pIes) { - uint8_t Channel; ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); bool skip_hostapd_rate = !pProfile->chan_switch_hostapd_rate_enabled; @@ -15075,20 +15023,19 @@ void csr_roam_prepare_bss_params(struct mac_context *mac, uint32_t sessionId, qdf_mem_zero(&pSession->bssParams.bssid, sizeof(struct qdf_mac_addr)); } - Channel = pSession->bssParams.operationChn; - /* Set operating channel in pProfile which will be used */ + /* Set operating frequency in pProfile which will be used */ /* in csr_roam_set_bss_config_cfg() to determine channel bonding */ /* mode and will be configured in CFG later */ - pProfile->operationChannel = Channel; + pProfile->op_freq = pSession->bssParams.operation_chan_freq; - if (Channel == 0) + if (pProfile->op_freq == 0) sme_err("CSR cannot find a channel to start IBSS"); else { csr_roam_determine_max_rate_for_ad_hoc(mac, &pSession->bssParams. operationalRateSet); if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS(pProfile)) { - if (WLAN_REG_IS_24GHZ_CH(Channel)) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(pProfile->op_freq)) { cbMode = mac->roam.configParam. channelBondingMode24GHz; @@ -15104,72 +15051,6 @@ void csr_roam_prepare_bss_params(struct mac_context *mac, uint32_t sessionId, } } -static QDF_STATUS csr_roam_start_ibss(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - bool *pfSameIbss) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - bool fSameIbss = false; - - if (csr_is_conn_state_ibss(mac, sessionId)) { - /* Check if any profile parameter has changed ? If any profile - * parameter has changed then stop old BSS and start a new one - * with new parameters - */ - if (csr_is_same_profile(mac, - &mac->roam.roamSession[sessionId]. - connectedProfile, pProfile)) - fSameIbss = true; - else - status = csr_roam_issue_stop_bss(mac, sessionId, - eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING); - - } else if (csr_is_conn_state_connected_infra(mac, sessionId)) - /* Disassociate from the connected Infrastructure network... */ - status = csr_roam_issue_disassociate(mac, sessionId, - eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, - false); - else { - struct bss_config_param *pBssConfig; - - pBssConfig = qdf_mem_malloc(sizeof(struct bss_config_param)); - if (!pBssConfig) - status = QDF_STATUS_E_NOMEM; - else - status = QDF_STATUS_SUCCESS; - if (QDF_IS_STATUS_SUCCESS(status)) { - /* there is no Bss description before we start an IBSS - * so we need to adopt all Bss configuration parameters - * from the Profile. - */ - status = csr_roam_prepare_bss_config_from_profile(mac, - pProfile, - pBssConfig, - NULL); - if (QDF_IS_STATUS_SUCCESS(status)) { - /* save dotMode */ - mac->roam.roamSession[sessionId].bssParams. - uCfgDot11Mode = pBssConfig->uCfgDot11Mode; - /* Prepare some more parameters for this IBSS */ - csr_roam_prepare_bss_params(mac, sessionId, - pProfile, NULL, - pBssConfig, NULL); - status = csr_roam_set_bss_config_cfg(mac, - sessionId, - pProfile, NULL, - pBssConfig, - NULL, false); - } - - qdf_mem_free(pBssConfig); - } /* Allocate memory */ - } - - if (pfSameIbss) - *pfSameIbss = fSameIbss; - return status; -} - static void csr_roam_update_connected_profile_from_new_bss(struct mac_context *mac, uint32_t sessionId, struct new_bss_info *pNewBss) @@ -15182,9 +15063,8 @@ static void csr_roam_update_connected_profile_from_new_bss(struct mac_context *m } if (pNewBss) { - /* Set the operating channel. */ - pSession->connectedProfile.operationChannel = - pNewBss->channelNumber; + /* Set the operating frequency. */ + pSession->connectedProfile.op_freq = pNewBss->freq; /* move the BSSId from the BSS description into the connected * state information. */ @@ -15240,176 +15120,6 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId, } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR -static void -csr_roam_diag_set_pmkid(struct csr_roam_session *pSession) -{ - WLAN_HOST_DIAG_EVENT_DEF(secEvent, - host_event_wlan_security_payload_type); - qdf_mem_zero(&secEvent, - sizeof(host_event_wlan_security_payload_type)); - secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE; - secEvent.encryptionModeMulticast = - (uint8_t) diag_enc_type_from_csr_type( - pSession->connectedProfile.mcEncryptionType); - secEvent.encryptionModeUnicast = - (uint8_t) diag_enc_type_from_csr_type( - pSession->connectedProfile.EncryptionType); - qdf_mem_copy(secEvent.bssid, - pSession->connectedProfile.bssid.bytes, - QDF_MAC_ADDR_SIZE); - secEvent.authMode = (uint8_t) diag_auth_type_from_csr_type( - pSession->connectedProfile.AuthType); - WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); -} -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -/** - * csr_update_session_psk_pmk - API to update PMK in csr session - * @pSession: pointer to session - * @pmksa: pointer to PMKSA struct - * - * Return : None - */ -static void -csr_update_session_psk_pmk(struct csr_roam_session *session, - tPmkidCacheInfo *pmksa) -{ - /* For SAE authentication, pmk will be sent over the - * set PMKSA vendor command. The set PMKSA command is sent - * after SAE authentication is complete, before association - * completion itself. So csr_roam_session will not be having - * any parameters at this point. This pmk received is not - * updated to csr session and when RSO update command is sent, - * empty pmk will be sent, resulting in SAE roming failure. So - * copy the pmk into csr session so that correct pmk will be - * sent in RSO command. - */ - qdf_mem_copy(session->psk_pmk, pmksa->pmk, pmksa->pmk_len); - session->pmk_len = pmksa->pmk_len; -} -#else -static inline void -csr_update_session_psk_pmk(struct csr_roam_session *session, - tPmkidCacheInfo *pmksa) -{} -#endif - -/** - * csr_update_pmk_cache - API to update PMK cache - * @pSession: pointer to session - * @pmksa: pointer to PMKSA struct - * - * Return : None - */ -static void csr_update_pmk_cache(struct csr_roam_session *session, - tPmkidCacheInfo *pmksa) -{ - uint16_t cache_idx = session->curr_cache_idx; - - /* Add entry to the cache */ - if (!pmksa->ssid_len) { - qdf_copy_macaddr( - &session->PmkidCacheInfo[cache_idx].BSSID, - &pmksa->BSSID); - session->PmkidCacheInfo[cache_idx].ssid_len = 0; - } else { - qdf_mem_copy(session->PmkidCacheInfo[cache_idx].ssid, - pmksa->ssid, pmksa->ssid_len); - session->PmkidCacheInfo[cache_idx].ssid_len = - pmksa->ssid_len; - qdf_mem_copy(session->PmkidCacheInfo[cache_idx].cache_id, - pmksa->cache_id, CACHE_ID_LEN); - - } - qdf_mem_copy( - session->PmkidCacheInfo[cache_idx].PMKID, - pmksa->PMKID, PMKID_LEN); - - if (pmksa->pmk_len) { - qdf_mem_copy(session->PmkidCacheInfo[cache_idx].pmk, - pmksa->pmk, pmksa->pmk_len); - - csr_update_session_psk_pmk(session, pmksa); - } - - session->PmkidCacheInfo[cache_idx].pmk_len = pmksa->pmk_len; - - /* Increment the CSR local cache index */ - if (cache_idx < (CSR_MAX_PMKID_ALLOWED - 1)) - session->curr_cache_idx++; - else { - sme_debug("max value reached, setting current index as 0"); - session->curr_cache_idx = 0; - } - - session->NumPmkidCache++; - if (session->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) { - sme_debug("setting num pmkid cache to %d", - CSR_MAX_PMKID_ALLOWED); - session->NumPmkidCache = CSR_MAX_PMKID_ALLOWED; - } -} - -QDF_STATUS -csr_roam_set_pmkid_cache(struct mac_context *mac, uint32_t sessionId, - tPmkidCacheInfo *pPMKIDCache, uint32_t numItems, - bool update_entire_cache) -{ - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - uint32_t i = 0; - tPmkidCacheInfo *pmksa; - enum csr_akm_type akm_type; - - if (!pSession) { - sme_err("session %d not found", sessionId); - return QDF_STATUS_E_FAILURE; - } - - sme_debug("numItems = %d", numItems); - - if (numItems > CSR_MAX_PMKID_ALLOWED) - return QDF_STATUS_E_INVAL; - -#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR - csr_roam_diag_set_pmkid(pSession); -#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ - - if (update_entire_cache) { - if (numItems && pPMKIDCache) { - pSession->NumPmkidCache = (uint16_t) numItems; - qdf_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache, - sizeof(tPmkidCacheInfo) * numItems); - pSession->curr_cache_idx = (uint16_t)numItems; - } - return QDF_STATUS_SUCCESS; - } - - for (i = 0; i < numItems; i++) { - pmksa = &pPMKIDCache[i]; - - /* Delete the entry if present */ - csr_roam_del_pmkid_from_cache(mac, sessionId, - pmksa, false); - /* Update new entry */ - csr_update_pmk_cache(pSession, pmksa); - - akm_type = pSession->connectedProfile.AuthType; - if ((akm_type == eCSR_AUTH_TYPE_FT_RSN || - akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA256 || - akm_type == eCSR_AUTH_TYPE_FT_FILS_SHA384 || - akm_type == eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384) && - pSession->connectedProfile.mdid.mdie_present) { - sme_debug("Auth type is %d update the MDID in cache", - akm_type); - csr_update_pmk_cache_ft(mac, - sessionId, pmksa->cache_id); - } - } - return QDF_STATUS_SUCCESS; -} - #ifdef WLAN_FEATURE_ROAM_OFFLOAD static void csr_mem_zero_psk_pmk(struct csr_roam_session *session) { @@ -15423,65 +15133,31 @@ static void csr_mem_zero_psk_pmk(struct csr_roam_session *session) #endif #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) -void csr_set_sae_single_pmk_bss_cap(struct csr_roam_session *session, - bool single_pmk_capable_bss, - struct qdf_mac_addr *bssid) -{ - tPmkidCacheInfo *cached_pmksa; - uint8_t i; - - for (i = 0; i < session->NumPmkidCache; i++) { - cached_pmksa = &session->PmkidCacheInfo[i]; - if (qdf_is_macaddr_equal(&cached_pmksa->BSSID, bssid)) { - cached_pmksa->single_pmk_supported = - single_pmk_capable_bss; - sme_debug("Updated single pmk bss capability = %d " - "at index = %d", single_pmk_capable_bss, i); - } - } -} - -void csr_clear_sae_single_pmk(struct mac_context *mac, +void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, tPmkidCacheInfo *pmk_cache) { struct wlan_objmgr_vdev *vdev; + uint32_t keymgmt; struct mlme_pmk_info pmk_info; - struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); - uint8_t i; - tPmkidCacheInfo *pmk_to_del; - if (!session) { - sme_err("session %d not found", vdev_id); - return; - } - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_LEGACY_SME_ID); if (!vdev) { sme_err("vdev is NULL"); return; } - if (!pmk_cache) { - wlan_mlme_clear_sae_single_pmk_info(vdev, NULL); + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + if (!(keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE))) { wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return; } - for (i = 0; i < session->NumPmkidCache; i++) { - pmk_to_del = &session->PmkidCacheInfo[i]; - if (qdf_is_macaddr_equal(&pmk_cache->BSSID, - &pmk_to_del->BSSID)) { - sme_debug("Matching BSSID: " QDF_MAC_ADDR_STR " to cached BSSID:" - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pmk_cache->BSSID.bytes), - QDF_MAC_ADDR_ARRAY(pmk_to_del->BSSID.bytes)); - /* clear sae_single pmk */ - qdf_mem_copy(&pmk_info.pmk, pmk_to_del->pmk, - pmk_to_del->pmk_len); - pmk_info.pmk_len = pmk_to_del->pmk_len; - wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info); - break; - } + if (pmk_cache) { + qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len); + pmk_info.pmk_len = pmk_cache->pmk_len; + wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info); + } else { + wlan_mlme_clear_sae_single_pmk_info(vdev, NULL); } wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); } @@ -15508,11 +15184,11 @@ csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac, } /* - * Mark the AP as single PMK capable in PMK Cache + * Mark the AP as single PMK capable in Crypto Table */ - csr_set_sae_single_pmk_bss_cap(session, true, - (struct qdf_mac_addr *) - session->pConnectBssDesc->bssId); + wlan_crypto_set_sae_single_pmk_bss_cap(vdev, + (struct qdf_mac_addr *)session->pConnectBssDesc->bssId, + true); pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); if (!pmk_info) { @@ -15529,118 +15205,8 @@ csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac, qdf_mem_zero(pmk_info, sizeof(*pmk_info)); qdf_mem_free(pmk_info); } - -void -csr_set_sae_single_pmk_info(struct csr_roam_session *session, - tPmkidCacheInfo *roam_sync_pmksa) -{ - tPmkidCacheInfo *cached_pmksa; - int i; - - for (i = 0; i < session->NumPmkidCache; i++) { - cached_pmksa = &session->PmkidCacheInfo[i]; - if (qdf_is_macaddr_equal(&roam_sync_pmksa->BSSID, - &cached_pmksa->BSSID) && - roam_sync_pmksa->single_pmk_supported && - roam_sync_pmksa->pmk_len) { - cached_pmksa->single_pmk_supported = - roam_sync_pmksa->single_pmk_supported; - cached_pmksa->pmk_len = - roam_sync_pmksa->pmk_len; - qdf_mem_copy(cached_pmksa->pmk, - roam_sync_pmksa->pmk, - roam_sync_pmksa->pmk_len); - } - } -} #endif -void csr_update_pmk_cache_ft(struct mac_context *mac, - uint32_t vdev_id, uint8_t *cache_id) -{ - struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); - tPmkidCacheInfo *cached_pmksa; - uint16_t mobility_domain; - uint16_t session_mdid; - uint8_t mdie_present; - uint8_t i; - - if (!session) { - sme_err("session %d not found", vdev_id); - return; - } - - session_mdid = session->connectedProfile.mdid.mobility_domain; - for (i = 0; i < session->NumPmkidCache; i++) { - cached_pmksa = &session->PmkidCacheInfo[i]; - mdie_present = cached_pmksa->mdid.mdie_present; - mobility_domain = cached_pmksa->mdid.mobility_domain; - /* - * Update the MDID for the matching BSSID pmksa entry - * and Delete the other PMKSA cache entries that has - * the same MDID - */ - if (qdf_is_macaddr_equal(&cached_pmksa->BSSID, - &session->connectedProfile.bssid)) { - sme_debug("PMK cached entry found, updating the MDID"); - cached_pmksa->mdid.mdie_present = 1; - cached_pmksa->mdid.mobility_domain = session_mdid; - } else if (cached_pmksa->ssid_len && - (!qdf_mem_cmp(cached_pmksa->ssid, - session->connectedProfile.SSID.ssId, - session-> - connectedProfile.SSID.length)) && - (!qdf_mem_cmp(cached_pmksa->cache_id, - cache_id, CACHE_ID_LEN))) { - sme_debug("PMK cached entry found, updating the MDID"); - cached_pmksa->mdid.mdie_present = 1; - cached_pmksa->mdid.mobility_domain = session_mdid; - } else if (mdie_present && (mobility_domain == session_mdid)) { - sme_debug("MDID has matched, Delete the PMKSA entry"); - /* Free the matched mobility domain entry from cache */ - csr_roam_del_pmk_cache_entry(session, cached_pmksa, i); - i--; - } - } -} - -void csr_roam_del_pmk_cache_entry(struct csr_roam_session *session, - tPmkidCacheInfo *cached_pmksa, u32 del_idx) -{ - u32 curr_idx; - u32 i; - - /* Clear this - matched entry */ - qdf_mem_zero(cached_pmksa, sizeof(tPmkidCacheInfo)); - /* Match Found, Readjust the other entries */ - curr_idx = session->curr_cache_idx; - if (del_idx < curr_idx) { - for (i = del_idx; i < (curr_idx - 1); i++) { - qdf_mem_copy(&session->PmkidCacheInfo[i], - &session->PmkidCacheInfo[i + 1], - sizeof(tPmkidCacheInfo)); - } - - session->curr_cache_idx--; - qdf_mem_zero(&session->PmkidCacheInfo[session->curr_cache_idx], - sizeof(tPmkidCacheInfo)); - } else if (del_idx > curr_idx) { - for (i = del_idx; i > (curr_idx); i--) { - qdf_mem_copy(&session->PmkidCacheInfo[i], - &session->PmkidCacheInfo[i - 1], - sizeof(tPmkidCacheInfo)); - } - - qdf_mem_zero(&session->PmkidCacheInfo[session->curr_cache_idx], - sizeof(tPmkidCacheInfo)); - } - - /* Decrement the count since an entry is been deleted */ - session->NumPmkidCache--; - sme_debug("PMKID at index=%d deleted, current index=%d cache count=%d", - del_idx, session->curr_cache_idx, session->NumPmkidCache); -} - QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, uint32_t sessionId, tPmkidCacheInfo *pmksa, @@ -15649,10 +15215,9 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); bool fMatchFound = false; uint32_t Index; + uint32_t curr_idx; tPmkidCacheInfo *cached_pmksa; - u32 del_idx; - u8 del_pmk[CSR_RSN_MAX_PMK_LEN] = {0}; - + uint32_t i; if (!pSession) { sme_err("session %d not found", sessionId); @@ -15670,7 +15235,7 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, qdf_mem_zero(pSession->PmkidCacheInfo, sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED); /* flush single_pmk_info information */ - csr_clear_sae_single_pmk(mac, pSession->vdev_id, NULL); + csr_clear_sae_single_pmk(mac->psoc, pSession->vdev_id, NULL); pSession->NumPmkidCache = 0; pSession->curr_cache_idx = 0; csr_mem_zero_psk_pmk(pSession); @@ -15678,7 +15243,7 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, } /* clear single_pmk_info information */ - csr_clear_sae_single_pmk(mac, pSession->vdev_id, pmksa); + csr_clear_sae_single_pmk(mac->psoc, pSession->vdev_id, pmksa); /* !flush_cache - so look up in the cache */ for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) { @@ -15696,41 +15261,47 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, fMatchFound = 1; if (fMatchFound) { - /* copy the PMK of matched BSSID */ - qdf_mem_copy(del_pmk, cached_pmksa->pmk, - cached_pmksa->pmk_len); - - /* Free the matched entry to address null pmk_len case*/ - csr_roam_del_pmk_cache_entry(pSession, cached_pmksa, - Index); - - /* Search for matching PMK in session PMK cache */ - for (del_idx = 0; del_idx != pSession->NumPmkidCache; - del_idx++) { - cached_pmksa = - &pSession->PmkidCacheInfo[del_idx]; - if (cached_pmksa->pmk_len && (!qdf_mem_cmp - (cached_pmksa->pmk, del_pmk, - cached_pmksa->pmk_len))) { - /* Delete the matched PMK cache entry */ - csr_roam_del_pmk_cache_entry( - pSession, cached_pmksa, - del_idx); - /* Search again from current index as we - * re-adjusted entries by one position - */ - del_idx--; - } - } - /* reset stored pmk */ - qdf_mem_zero(del_pmk, CSR_RSN_MAX_PMK_LEN); - + /* Clear this - matched entry */ + qdf_mem_zero(cached_pmksa, + sizeof(tPmkidCacheInfo)); break; } } - if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) + if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) { sme_debug("No such PMKSA entry exists"); + return QDF_STATUS_SUCCESS; + } + + /* Match Found, Readjust the other entries */ + curr_idx = pSession->curr_cache_idx; + if (Index < curr_idx) { + for (i = Index; i < (curr_idx - 1); i++) { + qdf_mem_copy(&pSession->PmkidCacheInfo[i], + &pSession->PmkidCacheInfo[i + 1], + sizeof(tPmkidCacheInfo)); + } + + pSession->curr_cache_idx--; + qdf_mem_zero(&pSession->PmkidCacheInfo + [pSession->curr_cache_idx], + sizeof(tPmkidCacheInfo)); + } else if (Index > curr_idx) { + for (i = Index; i > (curr_idx); i--) { + qdf_mem_copy(&pSession->PmkidCacheInfo[i], + &pSession->PmkidCacheInfo[i - 1], + sizeof(tPmkidCacheInfo)); + } + + qdf_mem_zero(&pSession->PmkidCacheInfo + [pSession->curr_cache_idx], + sizeof(tPmkidCacheInfo)); + } + + /* Decrement the count since an entry has been deleted */ + pSession->NumPmkidCache--; + sme_debug("PMKID at index=%d deleted, current index=%d cache count=%d", + Index, pSession->curr_cache_idx, pSession->NumPmkidCache); return QDF_STATUS_SUCCESS; } @@ -15902,17 +15473,18 @@ static void csr_add_supported_5Ghz_channels(struct mac_context *mac_ctx, return; } - size = sizeof(mac_ctx->roam.validChannelList); + size = sizeof(mac_ctx->roam.valid_ch_freq_list); if (QDF_IS_STATUS_SUCCESS (csr_get_cfg_valid_channels(mac_ctx, - (uint8_t *) mac_ctx->roam.validChannelList, - &size))) { + mac_ctx->roam.valid_ch_freq_list, + &size))) { for (i = 0, j = 0; i < size; i++) { /* Only add 5ghz channels.*/ - if (WLAN_REG_IS_5GHZ_CH - (mac_ctx->roam.validChannelList[i])) { - chan_list[j] - = mac_ctx->roam.validChannelList[i]; + if (WLAN_REG_IS_5GHZ_CH_FREQ + (mac_ctx->roam.valid_ch_freq_list[i])) { + chan_list[j] = + wlan_reg_freq_to_chan(mac_ctx->pdev, + mac_ctx->roam.valid_ch_freq_list[i]); j++; if (supp_chan_ie) { @@ -15941,7 +15513,7 @@ static void csr_add_supported_5Ghz_channels(struct mac_context *mac_ctx, * Return: QDF_STATUS */ static QDF_STATUS csr_set_ldpc_exception(struct mac_context *mac_ctx, - struct csr_roam_session *session, uint8_t channel, + struct csr_roam_session *session, uint32_t ch_freq, bool usr_cfg_rx_ldpc) { if (!mac_ctx) { @@ -15954,16 +15526,16 @@ static QDF_STATUS csr_set_ldpc_exception(struct mac_context *mac_ctx, "session is NULL"); return QDF_STATUS_E_FAILURE; } - if (usr_cfg_rx_ldpc && wma_is_rx_ldpc_supported_for_channel(channel)) { + if (usr_cfg_rx_ldpc && wma_is_rx_ldpc_supported_for_channel(ch_freq)) { session->ht_config.ht_rx_ldpc = 1; session->vht_config.ldpc_coding = 1; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "LDPC enable for chnl[%d]", channel); + "LDPC enable for ch freq[%d]", ch_freq); } else { session->ht_config.ht_rx_ldpc = 0; session->vht_config.ldpc_coding = 0; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "LDPC disable for chnl[%d]", channel); + "LDPC disable for ch freq[%d]", ch_freq); } return QDF_STATUS_SUCCESS; } @@ -16032,7 +15604,8 @@ csr_validate_and_update_fils_info(struct mac_context *mac, struct join_req *csr_join_req, uint8_t vdev_id) { - tPmkidCacheInfo pmkid_cache; + uint8_t cache_id[CACHE_ID_LEN] = {0}; + struct qdf_mac_addr bssid; if (!profile->fils_con_info) return QDF_STATUS_SUCCESS; @@ -16044,24 +15617,23 @@ csr_validate_and_update_fils_info(struct mac_context *mac, return QDF_STATUS_SUCCESS; } - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); - pmkid_cache.ssid_len = csr_join_req->ssId.length; - qdf_mem_copy(pmkid_cache.ssid, &csr_join_req->ssId.ssId, - csr_join_req->ssId.length); - if (bss_desc->fils_info_element.is_cache_id_present) { - qdf_mem_copy(pmkid_cache.cache_id, - bss_desc->fils_info_element.cache_id, + qdf_mem_copy(cache_id, bss_desc->fils_info_element.cache_id, CACHE_ID_LEN); - sme_debug("FILS_PMKSA: cache_id[0]:%d, cache_id[1]:%d", - pmkid_cache.cache_id[0], pmkid_cache.cache_id[1]); + cache_id[0], cache_id[1]); } + qdf_mem_copy(bssid.bytes, + csr_join_req->bssDescription.bssId, + QDF_MAC_ADDR_SIZE); + if ((!profile->fils_con_info->r_rk_length || !profile->fils_con_info->key_nai_length) && - !bss_desc->fils_info_element.is_cache_id_present && - !csr_lookup_pmkid(mac, vdev_id, &pmkid_cache)) + !bss_desc->fils_info_element.is_cache_id_present && + !csr_lookup_fils_pmkid(mac, vdev_id, cache_id, + csr_join_req->ssId.ssId, + csr_join_req->ssId.length, &bssid)) return QDF_STATUS_E_FAILURE; qdf_mem_copy(&csr_join_req->fils_con_info, @@ -16093,7 +15665,6 @@ static void csr_update_sae_config(struct join_req *csr_join_req, struct mac_context *mac, struct csr_roam_session *session) { tPmkidCacheInfo *pmkid_cache; - uint32_t index; pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); if (!pmkid_cache) @@ -16104,18 +15675,18 @@ static void csr_update_sae_config(struct join_req *csr_join_req, QDF_MAC_ADDR_SIZE); csr_join_req->sae_pmk_cached = - csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache, &index); + csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache); qdf_mem_free(pmkid_cache); if (!csr_join_req->sae_pmk_cached) return; - sme_debug("Found for BSSID=" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(csr_join_req->bssDescription.bssId)); + sme_debug("Found for BSSID=" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(csr_join_req->bssDescription.bssId)); } #else -static void csr_update_sae_config(struct join_req *csr_join_req, +static inline void csr_update_sae_config(struct join_req *csr_join_req, struct mac_context *mac, struct csr_roam_session *session) { } #endif @@ -16131,34 +15702,45 @@ static void csr_update_sae_config(struct join_req *csr_join_req, */ static uint8_t csr_get_nss_supported_by_sta_and_ap(tDot11fIEVHTCaps *vht_caps, tDot11fIEHTCaps *ht_caps, + tDot11fIEhe_cap *he_cap, uint32_t dot11_mode) { - bool vht_capability, ht_capability; + bool vht_capability, ht_capability, he_capability; vht_capability = IS_DOT11_MODE_VHT(dot11_mode); ht_capability = IS_DOT11_MODE_HT(dot11_mode); + he_capability = IS_DOT11_MODE_HE(dot11_mode); - if (vht_capability && vht_caps->present) { + if (he_capability && he_cap->present) { + if ((he_cap->rx_he_mcs_map_lt_80 & 0xC0) != 0xC0) + return NSS_4x4_MODE; + + if ((he_cap->rx_he_mcs_map_lt_80 & 0x30) != 0x30) + return NSS_3x3_MODE; + + if ((he_cap->rx_he_mcs_map_lt_80 & 0x0C) != 0x0C) + return NSS_2x2_MODE; + } else if (vht_capability && vht_caps->present) { if ((vht_caps->rxMCSMap & 0xC0) != 0xC0) - return 4; + return NSS_4x4_MODE; if ((vht_caps->rxMCSMap & 0x30) != 0x30) - return 3; + return NSS_3x3_MODE; if ((vht_caps->rxMCSMap & 0x0C) != 0x0C) - return 2; + return NSS_2x2_MODE; } else if (ht_capability && ht_caps->present) { if (ht_caps->supportedMCSSet[3]) - return 4; + return NSS_4x4_MODE; if (ht_caps->supportedMCSSet[2]) - return 3; + return NSS_3x3_MODE; if (ht_caps->supportedMCSSet[1]) - return 2; + return NSS_2x2_MODE; } - return 1; + return NSS_1x1_MODE; } /** @@ -16269,6 +15851,25 @@ csr_get_adaptive_11r_enabled(struct mac_context *mac) } #endif +static QDF_STATUS csr_check_and_validate_6g_ap(struct mac_context *mac_ctx, + struct bss_description *bss, + struct join_req *csr_join_req, + tDot11fBeaconIEs *ie) +{ + tDot11fIEhe_op *he_op = &ie->he_op; + + if (!wlan_reg_is_6ghz_chan_freq(bss->chan_freq)) + return QDF_STATUS_SUCCESS; + + if (!he_op->oper_info_6g_present) { + sme_err(QDF_MAC_ADDR_FMT" Invalid 6GHZ AP BSS description IE", + QDF_MAC_ADDR_REF(bss->bssId)); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + #ifdef WLAN_FEATURE_11AX static void csr_handle_iot_ap_no_common_he_rates(struct mac_context *mac, struct csr_roam_session *session, @@ -16333,6 +15934,19 @@ csr_update_sae_single_pmk_ap_cap(struct mac_context *mac, } #endif +static void csr_get_basic_rates(tSirMacRateSet *b_rates, uint32_t chan_freq) +{ + /* + * Some IOT APs don't send supported rates in + * probe resp, hence add BSS basic rates in + * supported rates IE of assoc request. + */ + if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) + csr_populate_basic_rates(b_rates, false, true); + else if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) + csr_populate_basic_rates(b_rates, true, true); +} + /** * The communication between HDD and LIM is thru mailbox (MB). * Both sides will access the data structure "struct join_req". @@ -16351,6 +15965,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, { QDF_STATUS status = QDF_STATUS_SUCCESS; uint8_t acm_mask = 0, uapsd_mask; + uint32_t bss_freq; uint16_t msgLen, ieLen; tSirMacRateSet OpRateSet; tSirMacRateSet ExRateSet; @@ -16361,13 +15976,12 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, struct join_req *csr_join_req; tSirMacCapabilityInfo *pAP_capabilityInfo; bool fTmp; - int8_t pwrLimit = 0; + int8_t pwr_limit = 0; struct ps_global_info *ps_global_info = &mac->sme.ps_global_info; struct ps_params *ps_param = &ps_global_info->ps_params[sessionId]; uint8_t ese_config = 0; tpCsrNeighborRoamControlInfo neigh_roam_info; uint32_t value = 0, value1 = 0; - QDF_STATUS packetdump_timer_status; bool is_vendor_ap_present; struct vdev_type_nss *vdev_type_nss; struct action_oui_search_attr vendor_ap_search_attr; @@ -16390,11 +16004,12 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, return QDF_STATUS_E_FAILURE; } neigh_roam_info = &mac->roam.neighborRoamInfo[sessionId]; + bss_freq = pBssDescription->chan_freq; if ((eWNI_SME_REASSOC_REQ == messageType) || - WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId)) { + WLAN_REG_IS_5GHZ_CH_FREQ(bss_freq)) { pSession->disable_hi_rssi = true; - sme_debug("Disabling HI_RSSI, AP channel=%d, rssi=%d", - pBssDescription->channelId, pBssDescription->rssi); + sme_debug("Disabling HI_RSSI, AP freq=%d, rssi=%d", + pBssDescription->chan_freq, pBssDescription->rssi); } else { pSession->disable_hi_rssi = false; } @@ -16438,9 +16053,14 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, if (!QDF_IS_STATUS_SUCCESS(status)) break; + status = csr_check_and_validate_6g_ap(mac, pBssDescription, + csr_join_req, pIes); + if (!QDF_IS_STATUS_SUCCESS(status)) + break; + csr_join_req->messageType = messageType; csr_join_req->length = msgLen; - csr_join_req->sessionId = (uint8_t) sessionId; + csr_join_req->vdev_id = (uint8_t) sessionId; if (pIes->SSID.present && !csr_is_nullssid(pIes->SSID.ssid, pIes->SSID.num_ssid)) { @@ -16459,12 +16079,12 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, qdf_mem_copy(&csr_join_req->self_mac_addr, &pSession->self_mac_addr, sizeof(tSirMacAddr)); - sme_nofl_info("vdev-%d: Connecting to %.*s " QDF_MAC_ADDR_STR - " rssi: %d channel: %d akm %d cipher: uc %d mc %d, CC: %c%c", + sme_nofl_info("vdev-%d: Connecting to %.*s " QDF_MAC_ADDR_FMT + " rssi: %d freq: %d akm %d cipher: uc %d mc %d, CC: %c%c", sessionId, csr_join_req->ssId.length, csr_join_req->ssId.ssId, - QDF_MAC_ADDR_ARRAY(pBssDescription->bssId), - pBssDescription->rssi, pBssDescription->channelId, + QDF_MAC_ADDR_REF(pBssDescription->bssId), + pBssDescription->rssi, pBssDescription->chan_freq, pProfile->negotiatedAuthType, pProfile->negotiatedUCEncryptionType, pProfile->negotiatedMCEncryptionType, @@ -16485,7 +16105,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, csr_update_sae_single_pmk_ap_cap(mac, pBssDescription, sessionId, akm); - if (pBssDescription->channelId <= 14 && + if (bss_freq <= 2484 && !mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && dot11mode == MLME_DOT11_MODE_11AC) { /* Need to disable VHT operation in 2.4 GHz band */ @@ -16508,15 +16128,15 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, vendor_ap_search_attr.mac_addr = &pBssDescription->bssId[0]; vendor_ap_search_attr.nss = csr_get_nss_supported_by_sta_and_ap( &pIes->VHTCaps, &pIes->HTCaps, - dot11mode); + &pIes->he_cap, dot11mode); vendor_ap_search_attr.ht_cap = pIes->HTCaps.present; vendor_ap_search_attr.vht_cap = pIes->VHTCaps.present; vendor_ap_search_attr.enable_2g = - IS_24G_CH(pBssDescription->channelId); + wlan_reg_is_24ghz_ch_freq(bss_freq); vendor_ap_search_attr.enable_5g = - IS_5G_CH(pBssDescription->channelId); + wlan_reg_is_5ghz_ch_freq(bss_freq); - if (IS_5G_CH(pBssDescription->channelId)) + if (wlan_reg_is_5ghz_ch_freq(bss_freq)) vdev_type_nss = &mac->vdev_type_nss_5g; else vdev_type_nss = &mac->vdev_type_nss_2g; @@ -16539,7 +16159,9 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, if (!force_max_nss) ap_nss = csr_get_nss_supported_by_sta_and_ap( &pIes->VHTCaps, - &pIes->HTCaps, dot11mode); + &pIes->HTCaps, + &pIes->he_cap, + dot11mode); if (!force_max_nss && pSession->nss > ap_nss) { pSession->nss = ap_nss; pSession->vdev_nss = pSession->nss; @@ -16675,9 +16297,13 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, qdf_mem_copy(&csr_join_req->operationalRateSet. rate, OpRateSet.rate, OpRateSet.numRates); - } else - csr_join_req->operationalRateSet.numRates = 0; + } else if (pProfile->phyMode == eCSR_DOT11_MODE_AUTO) { + tSirMacRateSet b_rates = {0}; + csr_get_basic_rates(&b_rates, + pBssDescription->chan_freq); + csr_join_req->operationalRateSet = b_rates; + } /* ExtendedRateSet */ if (ExRateSet.numRates) { csr_join_req->extendedRateSet.numRates = @@ -16685,8 +16311,15 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, qdf_mem_copy(&csr_join_req->extendedRateSet. rate, ExRateSet.rate, ExRateSet.numRates); - } else + } else { csr_join_req->extendedRateSet.numRates = 0; + } + } else if (pProfile->phyMode == eCSR_DOT11_MODE_AUTO) { + tSirMacRateSet b_rates = {0}; + + csr_get_basic_rates(&b_rates, + pBssDescription->chan_freq); + csr_join_req->operationalRateSet = b_rates; } else { csr_join_req->operationalRateSet.numRates = 0; csr_join_req->extendedRateSet.numRates = 0; @@ -17016,7 +16649,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, (uint8_t)mac->mlme_cfg->ht_caps.tx_ldpc_enable; if ((csr_is11h_supported(mac)) && - (WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId)) && + (WLAN_REG_IS_5GHZ_CH_FREQ(bss_freq)) && (pIes->Country.present) && (!mac->mlme_cfg->sap_cfg.country_code_priority)) { csr_save_to_channel_power2_g_5_g(mac, @@ -17034,7 +16667,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, if (eSIR_INFRASTRUCTURE_MODE == csr_join_req->bsstype || !policy_mgr_is_dbs_enable(mac->psoc)) csr_set_ldpc_exception(mac, pSession, - pBssDescription->channelId, + bss_freq, mac->mlme_cfg->ht_caps. ht_cap_info.adv_coding_cap); csr_join_req->ht_config = pSession->ht_config; @@ -17050,8 +16683,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, if (!mac->usr_cfg_tx_bfee_nsts) CSR_REVISE_REQ_HE_CAP_PER_BAND(csr_join_req, mac, - pBssDescription-> - channelId); + bss_freq); } value = mac->mlme_cfg->vht_caps.vht_cap_info.su_bformee; @@ -17177,10 +16809,9 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, * assoc IE's to FW which is used for LFR3 roaming * ie. used in reassociation requests from FW. */ - pwrLimit = csr_get_cfg_max_tx_power(mac, - pBssDescription->channelId); - if (0 != pwrLimit && pwrLimit < MAX_TX_PWR_CAP) - csr_join_req->powerCap.maxTxPower = pwrLimit; + pwr_limit = csr_get_cfg_max_tx_power(mac, bss_freq); + if (0 != pwr_limit && pwr_limit < MAX_TX_PWR_CAP) + csr_join_req->powerCap.maxTxPower = pwr_limit; else csr_join_req->powerCap.maxTxPower = MAX_TX_PWR_CAP; @@ -17216,17 +16847,15 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, if (mac->roam.configParam.conc_custom_rule1) { if ((0 == mac->roam.configParam. is_sta_connection_in_5gz_enabled) && - WLAN_REG_IS_5GHZ_CH(pBssDescription-> - channelId)) { + WLAN_REG_IS_5GHZ_CH_FREQ(bss_freq)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "STA-conn on 5G isn't allowed"); status = QDF_STATUS_E_FAILURE; break; } - if (!WLAN_REG_IS_5GHZ_CH(pBssDescription->channelId) && - (false == csr_is_conn_allow_2g_band(mac, - pBssDescription->channelId))) { + if (!WLAN_REG_IS_5GHZ_CH_FREQ(bss_freq) && + csr_is_conn_allow_2g_band(mac, bss_freq) == false) { status = QDF_STATUS_E_FAILURE; break; } @@ -17240,9 +16869,8 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, * by this time P2PGO's channel is same as STA's channel. */ if (mac->roam.configParam.conc_custom_rule2 && - !WLAN_REG_IS_24GHZ_CH(pBssDescription->channelId) && - (!csr_is_conn_allow_5g_band(mac, - pBssDescription->channelId))) { + !WLAN_REG_IS_24GHZ_CH_FREQ(bss_freq) && + (!csr_is_conn_allow_5g_band(mac, bss_freq))) { status = QDF_STATUS_E_FAILURE; break; } @@ -17264,17 +16892,9 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, break; } - if (pProfile->csrPersona == QDF_STA_MODE) { - wlan_register_txrx_packetdump(); - packetdump_timer_status = qdf_mc_timer_start( - &mac->roam.packetdump_timer, - (PKT_DUMP_TIMER_DURATION * - QDF_MC_TIMER_TO_SEC_UNIT)/ - QDF_MC_TIMER_TO_MS_UNIT); - if (!QDF_IS_STATUS_SUCCESS(packetdump_timer_status)) - sme_debug("cannot start packetdump timer status: %d", - packetdump_timer_status); - } + if (pProfile->csrPersona == QDF_STA_MODE) + wlan_register_txrx_packetdump(OL_TXRX_PDEV_ID); + #ifndef WLAN_MDM_CODE_REDUCTION_OPT if (eWNI_SME_JOIN_REQ == messageType) { /* Notify QoS module that join happening */ @@ -17387,8 +17007,8 @@ QDF_STATUS csr_send_chng_mcc_beacon_interval(struct mac_context *mac, qdf_copy_macaddr(&pMsg->bssid, &pSession->self_mac_addr); sme_debug("CSR Attempting to change BI for Bssid= " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pMsg->bssid.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); pMsg->sessionId = sessionId; sme_debug("session %d BeaconInterval %d", sessionId, @@ -17430,8 +17050,8 @@ QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId, qdf_copy_macaddr(&pMsg->bssid, &pSession->self_mac_addr); sme_debug( "CSR Attempting to set HT20/40 mode for Bssid= " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pMsg->bssid.bytes)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); pMsg->sessionId = sessionId; sme_debug(" session %d HT20/40 mode %d", sessionId, cbMode); @@ -17444,13 +17064,13 @@ QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId, #endif QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac, - uint32_t sessionId, + uint32_t vdev_id, tSirMacAddr bssId, uint16_t reasonCode) { struct deauth_req *pMsg; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); + struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); - if (!CSR_IS_SESSION_VALID(mac, sessionId)) + if (!CSR_IS_SESSION_VALID(mac, vdev_id)) return QDF_STATUS_E_FAILURE; pMsg = qdf_mem_malloc(sizeof(*pMsg)); @@ -17459,7 +17079,7 @@ QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac, pMsg->messageType = eWNI_SME_DEAUTH_REQ; pMsg->length = sizeof(*pMsg); - pMsg->sessionId = sessionId; + pMsg->vdev_id = vdev_id; if ((pSession->pCurRoamProfile) && (CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) { @@ -17499,7 +17119,7 @@ QDF_STATUS csr_send_mb_disassoc_cnf_msg(struct mac_context *mac, pMsg->messageType = eWNI_SME_DISASSOC_CNF; pMsg->status_code = eSIR_SME_SUCCESS; pMsg->length = sizeof(*pMsg); - pMsg->sme_session_id = pDisassocInd->sessionId; + pMsg->vdev_id = pDisassocInd->vdev_id; qdf_copy_macaddr(&pMsg->peer_macaddr, &pDisassocInd->peer_macaddr); status = QDF_STATUS_SUCCESS; @@ -17537,7 +17157,7 @@ QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac, pMsg->messageType = eWNI_SME_DEAUTH_CNF; pMsg->status_code = eSIR_SME_SUCCESS; pMsg->length = sizeof(*pMsg); - pMsg->sme_session_id = pDeauthInd->sessionId; + pMsg->vdev_id = pDeauthInd->vdev_id; qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid); status = QDF_STATUS_SUCCESS; if (!QDF_IS_STATUS_SUCCESS(status)) { @@ -17608,87 +17228,6 @@ QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac, return status; } -QDF_STATUS csr_send_mb_set_context_req_msg(struct mac_context *mac, - uint32_t sessionId, - struct qdf_mac_addr peer_macaddr, - uint8_t numKeys, - tAniEdType edType, bool fUnicast, - tAniKeyDirection aniKeyDirection, - uint8_t keyId, uint8_t keyLength, - uint8_t *pKey, uint8_t paeRole, - uint8_t *pKeyRsc) -{ - struct set_context_req *pMsg; - struct scheduler_msg msg = {0}; - uint16_t msgLen; - QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("Session_id invalid %d", sessionId); - return status; - } - - sme_debug("keylength: %d Encry type: %d", keyLength, edType); - do { - if ((1 != numKeys) && (0 != numKeys)) - break; - /* - * All of these fields appear in every SET_CONTEXT message. - * Below we'll add in the size for each key set. Since we only - * support up to one key, we always allocate memory for 1 key. - */ - msgLen = sizeof(*pMsg); - - pMsg = qdf_mem_malloc(msgLen); - if (!pMsg) - return QDF_STATUS_E_NOMEM; - pMsg->messageType = eWNI_SME_SETCONTEXT_REQ; - pMsg->length = msgLen; - pMsg->sessionId = (uint8_t) sessionId; - qdf_copy_macaddr(&pMsg->peer_macaddr, &peer_macaddr); - qdf_copy_macaddr(&pMsg->bssid, - &pSession->connectedProfile.bssid); - - /** - * Set the pMsg->keyMaterial.length field - * (this length is defined as all data that follows the - * edType field in the tSirKeyMaterial keyMaterial; field). - * - * NOTE: This keyMaterial.length contains the length of a - * MAX size key, though the keyLength can be shorter than this - * max size. Is LIM interpreting this ok ? - */ - pMsg->keyMaterial.length = - sizeof(pMsg->keyMaterial.numKeys) + - (numKeys * sizeof(pMsg->keyMaterial.key)); - pMsg->keyMaterial.edType = edType; - pMsg->keyMaterial.numKeys = numKeys; - pMsg->keyMaterial.key[0].keyId = keyId; - pMsg->keyMaterial.key[0].unicast = fUnicast; - pMsg->keyMaterial.key[0].keyDirection = aniKeyDirection; - qdf_mem_copy(pMsg->keyMaterial.key[0].keyRsc, - pKeyRsc, WLAN_CRYPTO_RSC_SIZE); - /* 0 is Supplicant */ - pMsg->keyMaterial.key[0].paeRole = paeRole; - pMsg->keyMaterial.key[0].keyLength = keyLength; - if (keyLength && pKey) - qdf_mem_copy(pMsg->keyMaterial.key[0].key, - pKey, keyLength); - - msg.type = eWNI_SME_SETCONTEXT_REQ; - msg.bodyptr = pMsg; - status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_PE, - QDF_MODULE_ID_PE, &msg); - if (QDF_IS_STATUS_ERROR(status)) { - qdf_mem_zero(pMsg, msgLen); - qdf_mem_free(pMsg); - } - } while (0); - return status; -} - QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t sessionId, eCsrRoamBssType bssType, struct csr_roamstart_bssparams *pParam, @@ -17711,7 +17250,7 @@ QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t return QDF_STATUS_E_NOMEM; pMsg->messageType = eWNI_SME_START_BSS_REQ; - pMsg->sessionId = sessionId; + pMsg->vdev_id = sessionId; pMsg->length = sizeof(*pMsg); qdf_copy_macaddr(&pMsg->bssid, &pParam->bssid); /* self_mac_addr */ @@ -17724,7 +17263,8 @@ QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t else wTmp = MLME_CFG_BEACON_INTERVAL_DEF; - csr_validate_mcc_beacon_interval(mac, pParam->operationChn, + csr_validate_mcc_beacon_interval(mac, + pParam->operation_chan_freq, &wTmp, sessionId, pParam->bssPersona); /* Update the beacon Interval */ pParam->beaconInterval = wTmp; @@ -17737,7 +17277,7 @@ QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t #endif pMsg->bssType = csr_translate_bsstype_to_mac_type(bssType); qdf_mem_copy(&pMsg->ssId, &pParam->ssId, sizeof(pParam->ssId)); - pMsg->channelId = pParam->operationChn; + pMsg->oper_ch_freq = pParam->operation_chan_freq; /* What should we really do for the cbmode. */ pMsg->cbMode = (ePhyChanBondState) pParam->cbMode; pMsg->vht_channel_width = pParam->ch_params.ch_width; @@ -17767,7 +17307,7 @@ QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t if (eSIR_IBSS_MODE == pMsg->bssType || !policy_mgr_is_dbs_enable(mac->psoc)) csr_set_ldpc_exception(mac, pSession, - pMsg->channelId, + pParam->operation_chan_freq, mac->mlme_cfg->ht_caps. ht_cap_info.adv_coding_cap); @@ -17810,7 +17350,7 @@ QDF_STATUS csr_send_mb_start_bss_req_msg(struct mac_context *mac, uint32_t csr_start_bss_copy_he_cap(pMsg, pSession); /* change the HE caps like sts per band */ CSR_REVISE_REQ_HE_CAP_PER_BAND(pMsg, mac, - pParam->operationChn); + pParam->operation_chan_freq); } pMsg->add_ie_params = pParam->add_ie_params; @@ -17873,31 +17413,6 @@ QDF_STATUS csr_reassoc(struct mac_context *mac, uint32_t sessionId, return status; } -static QDF_STATUS csr_roam_session_opened(struct mac_context *mac, - QDF_STATUS qdf_status, - uint32_t sessionId) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct csr_roam_info *roam_info; - - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return QDF_STATUS_E_NOMEM; - - if (QDF_IS_STATUS_ERROR(qdf_status)) { - status = csr_roam_call_callback(mac, sessionId, roam_info, 0, - eCSR_ROAM_SESSION_OPENED, - eCSR_ROAM_RESULT_FAILURE); - } else { - status = csr_roam_call_callback(mac, sessionId, roam_info, 0, - eCSR_ROAM_SESSION_OPENED, - eCSR_ROAM_RESULT_SUCCESS); - } - - qdf_mem_free(roam_info); - return status; -} - /** * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini * @mac: mac_context. @@ -17925,66 +17440,43 @@ static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac, wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); } -QDF_STATUS csr_process_add_sta_session_rsp(struct mac_context *mac, uint8_t *pMsg) +static void csr_send_set_ie(uint8_t type, uint8_t sub_type, + uint8_t vdev_id) { - struct add_sta_self_params *rsp; struct send_extcap_ie *msg; QDF_STATUS status; - if (!pMsg) { - sme_err("in %s msg ptr is NULL", __func__); - return QDF_STATUS_E_FAILURE; - } - rsp = (struct add_sta_self_params *) pMsg; - sme_debug("Add Sta self rsp status = %d", rsp->status); - - if (QDF_IS_STATUS_SUCCESS(rsp->status)) { - if ((WMI_VDEV_TYPE_STA == rsp->type || - (WMI_VDEV_TYPE_AP == rsp->type && - WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) { - sme_debug("send SET IE msg to PE"); - msg = qdf_mem_malloc(sizeof(*msg)); - if (!msg) - return QDF_STATUS_E_NOMEM; - - msg->msg_type = eWNI_SME_SET_IE_REQ; - msg->session_id = rsp->session_id; - msg->length = sizeof(*msg); - status = umac_send_mb_message_to_mac(msg); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("Failed to send down the set IE req "); - } - } - - csr_roam_session_opened(mac, rsp->status, rsp->session_id); + sme_debug("send SET IE msg to PE"); - if (QDF_IS_STATUS_SUCCESS(rsp->status) && - rsp->type == WMI_VDEV_TYPE_STA) { - csr_store_oce_cfg_flags_in_vdev(mac, mac->pdev, - rsp->session_id); - wlan_mlme_update_oce_flags(mac->pdev); + if (!(type == WLAN_VDEV_MLME_TYPE_STA || + (type == WLAN_VDEV_MLME_TYPE_AP && + sub_type == WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE))) { + sme_debug("Failed to send set IE req for vdev_%d", vdev_id); + return; } - if (QDF_IS_STATUS_ERROR(rsp->status)) - csr_cleanup_session(mac, rsp->session_id); - return QDF_STATUS_SUCCESS; -} + msg = qdf_mem_malloc(sizeof(*msg)); + if (!msg) + return; -/** - * csr_get_vdev_type_nss() - gets the nss value based on vdev type - * @mac_ctx: Pointer to Global MAC structure - * @dev_mode: current device operating mode. - * @nss2g: Pointer to the 2G Nss parameter. - * @nss5g: Pointer to the 5G Nss parameter. - * - * Fills the 2G and 5G Nss values based on device mode. - * - * Return: None - */ -void csr_get_vdev_type_nss(struct mac_context *mac_ctx, - enum QDF_OPMODE dev_mode, - uint8_t *nss_2g, uint8_t *nss_5g) + msg->msg_type = eWNI_SME_SET_IE_REQ; + msg->session_id = vdev_id; + msg->length = sizeof(*msg); + status = umac_send_mb_message_to_mac(msg); + if (!QDF_IS_STATUS_SUCCESS(status)) + sme_debug("Failed to send set IE req for vdev_%d", vdev_id); +} + +void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, + uint8_t *nss_5g) { + struct mac_context *mac_ctx = sme_get_mac_context(); + + if (!mac_ctx) { + sme_err("Invalid MAC context"); + return; + } + switch (dev_mode) { case QDF_STA_MODE: *nss_2g = mac_ctx->vdev_type_nss_2g.sta; @@ -18029,157 +17521,71 @@ void csr_get_vdev_type_nss(struct mac_context *mac_ctx, break; } sme_debug("mode - %d: nss_2g - %d, 5g - %d", - dev_mode, *nss_2g, *nss_5g); -} - -static -QDF_STATUS csr_issue_add_sta_for_session_req(struct mac_context *mac, - uint32_t sessionId, - tSirMacAddr sessionMacAddr, - uint32_t type, uint32_t subType) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct add_sta_self_params *add_sta_self_req; - struct wlan_mlme_qos *qos_aggr = &mac->mlme_cfg->qos_mlme_params; - uint8_t nss_2g; - uint8_t nss_5g; - struct scheduler_msg msg = {0}; - - add_sta_self_req = qdf_mem_malloc(sizeof(struct add_sta_self_params)); - if (!add_sta_self_req) - return QDF_STATUS_E_NOMEM; - - if (!(mac->mlme_cfg)) { - pe_err("Mlme cfg NULL"); - return QDF_STATUS_E_FAILURE; - } - - csr_get_vdev_type_nss(mac, mac->sme.curr_device_mode, - &nss_2g, &nss_5g); - qdf_mem_copy(add_sta_self_req->self_mac_addr, sessionMacAddr, - sizeof(tSirMacAddr)); - add_sta_self_req->curr_device_mode = mac->sme.curr_device_mode; - add_sta_self_req->session_id = sessionId; - add_sta_self_req->type = type; - add_sta_self_req->sub_type = subType; - add_sta_self_req->nss_2g = nss_2g; - add_sta_self_req->nss_5g = nss_5g; - - add_sta_self_req->tx_aggregation_size = qos_aggr->tx_aggregation_size; - add_sta_self_req->tx_aggregation_size_be = - qos_aggr->tx_aggregation_size_be; - add_sta_self_req->tx_aggregation_size_bk = - qos_aggr->tx_aggregation_size_bk; - add_sta_self_req->tx_aggregation_size_vi = - qos_aggr->tx_aggregation_size_vi; - add_sta_self_req->tx_aggregation_size_vo = - qos_aggr->tx_aggregation_size_vo; - - add_sta_self_req->rx_aggregation_size = qos_aggr->rx_aggregation_size; - add_sta_self_req->tx_aggr_sw_retry_threshold_be = - qos_aggr->tx_aggr_sw_retry_threshold_be; - add_sta_self_req->tx_aggr_sw_retry_threshold_bk = - qos_aggr->tx_aggr_sw_retry_threshold_bk; - add_sta_self_req->tx_aggr_sw_retry_threshold_vi = - qos_aggr->tx_aggr_sw_retry_threshold_vi; - add_sta_self_req->tx_aggr_sw_retry_threshold_vo = - qos_aggr->tx_aggr_sw_retry_threshold_vo; - add_sta_self_req->tx_aggr_sw_retry_threshold = - qos_aggr->tx_aggr_sw_retry_threshold; - add_sta_self_req->tx_non_aggr_sw_retry_threshold_be = - qos_aggr->tx_non_aggr_sw_retry_threshold_be; - add_sta_self_req->tx_non_aggr_sw_retry_threshold_bk = - qos_aggr->tx_non_aggr_sw_retry_threshold_bk; - add_sta_self_req->tx_non_aggr_sw_retry_threshold_vi = - qos_aggr->tx_non_aggr_sw_retry_threshold_vi; - add_sta_self_req->tx_non_aggr_sw_retry_threshold_vo = - qos_aggr->tx_non_aggr_sw_retry_threshold_vo; - add_sta_self_req->tx_non_aggr_sw_retry_threshold = - qos_aggr->tx_non_aggr_sw_retry_threshold; - - add_sta_self_req->enable_bcast_probe_rsp = - mac->mlme_cfg->oce.enable_bcast_probe_rsp; - add_sta_self_req->fils_max_chan_guard_time = - mac->mlme_cfg->sta.fils_max_chan_guard_time; - add_sta_self_req->pkt_err_disconn_th = - mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh; - add_sta_self_req->oce_feature_bitmap = - mac->mlme_cfg->oce.feature_bitmap; - - msg.type = WMA_ADD_STA_SELF_REQ; - msg.reserved = 0; - msg.bodyptr = add_sta_self_req; - msg.bodyval = 0; - - sme_debug( - "Send WMA_ADD_STA_SELF_REQ for selfMac=" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(add_sta_self_req->self_mac_addr)); - status = scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, &msg); - - if (status != QDF_STATUS_SUCCESS) { - sme_err("wma_post_ctrl_msg failed"); - qdf_mem_free(add_sta_self_req); - add_sta_self_req = NULL; - } - return status; + dev_mode, *nss_2g, *nss_5g); } -QDF_STATUS csr_roam_open_session(struct mac_context *mac_ctx, - struct sme_session_params *session_param) +QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme) { QDF_STATUS status; uint32_t existing_session_id; struct mlme_ht_capabilities_info *ht_cap_info; struct csr_roam_session *session; struct mlme_vht_capabilities_info *vht_cap_info; + u8 vdev_id; + struct qdf_mac_addr *mac_addr; + mac_handle_t mac_handle; + struct mac_context *mac_ctx; + struct wlan_objmgr_vdev *vdev; + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + mac_ctx = MAC_CONTEXT(mac_handle); + if (!mac_ctx) { + QDF_ASSERT(0); + return QDF_STATUS_E_INVAL; + } if (!(mac_ctx->mlme_cfg)) { - pe_err("invalid mlme cfg"); + sme_err("invalid mlme cfg"); return QDF_STATUS_E_FAILURE; } vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; + vdev = vdev_mlme->vdev; + + vdev_id = wlan_vdev_get_id(vdev); + mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev); + /* check to see if the mac address already belongs to a session */ - status = csr_roam_get_session_id_from_bssid(mac_ctx, - (struct qdf_mac_addr *)session_param->self_mac_addr, - &existing_session_id); + status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr, + &existing_session_id); if (QDF_IS_STATUS_SUCCESS(status)) { - sme_err("Session %d exists with mac address " QDF_MAC_ADDR_STR, + sme_err("Session %d exists with mac address "QDF_MAC_ADDR_FMT, existing_session_id, - QDF_MAC_ADDR_ARRAY(session_param->self_mac_addr)); + QDF_MAC_ADDR_REF(mac_addr->bytes)); return QDF_STATUS_E_FAILURE; } /* attempt to retrieve session for Id */ - session = CSR_GET_SESSION(mac_ctx, session_param->sme_session_id); + session = CSR_GET_SESSION(mac_ctx, vdev_id); if (!session) { - sme_err("Session does not exist for interface %d", - session_param->sme_session_id); + sme_err("Session does not exist for interface %d", vdev_id); return QDF_STATUS_E_FAILURE; } /* check to see if the session is already active */ if (session->sessionActive) { - sme_err("Cannot re-open active session with Id %d", - session_param->sme_session_id); + sme_err("Cannot re-open active session with Id %d", vdev_id); return QDF_STATUS_E_FAILURE; } session->sessionActive = true; - session->sessionId = session_param->sme_session_id; + session->sessionId = vdev_id; /* Initialize FT related data structures only in STA mode */ sme_ft_open(MAC_HANDLE(mac_ctx), session->sessionId); - session->session_open_cb = session_param->session_open_cb; - session->session_close_cb = session_param->session_close_cb; - session->callback = session_param->callback; - session->pContext = session_param->callback_ctx; - csr_monitor_mode_register_callback(session, session_param); - qdf_mem_copy(&session->self_mac_addr, session_param->self_mac_addr, + qdf_mem_copy(&session->self_mac_addr, mac_addr, sizeof(struct qdf_mac_addr)); status = qdf_mc_timer_init(&session->hTimerRoaming, QDF_TIMER_TYPE_SW, @@ -18199,6 +17605,11 @@ QDF_STATUS csr_roam_open_session(struct mac_context *mac_ctx, return status; } + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("timer init failed for join failure timer"); + return status; + } + ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info; session->ht_config.ht_rx_ldpc = ht_cap_info->adv_coding_cap; session->ht_config.ht_tx_stbc = ht_cap_info->tx_stbc; @@ -18236,65 +17647,51 @@ QDF_STATUS csr_roam_open_session(struct mac_context *mac_ctx, * Do not advertise requester role for SAP & responder role * for STA */ - csr_init_session_twt_cap(session, session_param->type_of_persona); + csr_init_session_twt_cap(session, vdev_mlme->mgmt.generic.type); + + csr_send_set_ie(vdev_mlme->mgmt.generic.type, + vdev_mlme->mgmt.generic.subtype, + wlan_vdev_get_id(vdev)); - return csr_issue_add_sta_for_session_req(mac_ctx, - session_param->sme_session_id, - session_param->self_mac_addr, - session_param->type_of_persona, - session_param->subtype_of_persona); + if (vdev_mlme->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_STA) { + csr_store_oce_cfg_flags_in_vdev(mac_ctx, mac_ctx->pdev, + wlan_vdev_get_id(vdev)); + wlan_mlme_update_oce_flags(mac_ctx->pdev); + } + + return status; } -QDF_STATUS csr_process_del_sta_session_rsp(struct mac_context *mac_ctx, - uint8_t *pMsg) +QDF_STATUS csr_process_vdev_del_rsp(struct mac_context *mac_ctx, + uint8_t *pmsg) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct del_sta_self_params *rsp; - uint8_t sessionId; - tListElem *entry; - tSmeCmd *sme_command; + struct del_vdev_params *rsp; + uint8_t vdev_id; - if (!pMsg) { + if (!pmsg) { sme_err("msg ptr is NULL"); return status; } - entry = csr_nonscan_active_ll_peek_head(mac_ctx, LL_ACCESS_LOCK); - if (!entry) { - sme_err("NO commands are ACTIVE"); - return status; - } - - sme_command = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (e_sme_command_del_sta_session != sme_command->command) { - sme_err("No Del sta session command ACTIVE"); - return status; - } - - rsp = (struct del_sta_self_params *) pMsg; - sessionId = rsp->session_id; - sme_debug("Del Sta rsp status = %d", rsp->status); + rsp = (struct del_vdev_params *)pmsg; + vdev_id = rsp->vdev_id; + sme_debug("vdev delete rsp status = %d", rsp->status); /* * This session is done. This will also flush all the pending command * for this vdev, as vdev is deleted and no command should be sent - * for this vdev. Active cmnd is e_sme_command_del_sta_session and will + * for this vdev. Active cmnd is e_sme_command_del_vdev and will * be removed anyway next. */ - csr_cleanup_session(mac_ctx, sessionId); - - /* Remove this command out of the non scan active list */ - if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry, - LL_ACCESS_LOCK)) { - csr_release_command(mac_ctx, sme_command); - } + csr_cleanup_vdev_session(mac_ctx, vdev_id); if (rsp->sme_callback) { status = sme_release_global_lock(&mac_ctx->sme); if (!QDF_IS_STATUS_SUCCESS(status)) sme_debug("Failed to Release Lock"); else { - rsp->sme_callback(rsp->session_id); + rsp->sme_callback(rsp->vdev_id); status = sme_acquire_global_lock(&mac_ctx->sme); if (!QDF_IS_STATUS_SUCCESS(status)) return status; @@ -18304,98 +17701,106 @@ QDF_STATUS csr_process_del_sta_session_rsp(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } - static QDF_STATUS -csr_issue_del_sta_for_session_req(struct mac_context *mac_ctx, uint32_t session_id, - tSirMacAddr session_mac_addr, - csr_session_close_cb callback, - void *context) +csr_issue_vdev_del_req(struct mac_context *mac_ctx, uint8_t vdev_id, + tSirMacAddr session_mac_addr, + csr_session_close_cb callback, + void *context) { QDF_STATUS status = QDF_STATUS_SUCCESS; - tSmeCmd *sme_command; + struct del_vdev_params *del_vdev_req; + struct scheduler_msg msg = {0}; - sme_command = csr_get_command_buffer(mac_ctx); - if (!sme_command) { - status = QDF_STATUS_E_RESOURCES; - } else { - sme_command->command = e_sme_command_del_sta_session; - sme_command->sessionId = (uint8_t)session_id; - sme_command->u.delStaSessionCmd.session_close_cb = callback; - sme_command->u.delStaSessionCmd.context = context; - qdf_mem_copy(sme_command->u.delStaSessionCmd.self_mac_addr, - session_mac_addr, sizeof(tSirMacAddr)); - status = csr_queue_sme_command(mac_ctx, sme_command, false); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("fail to send message status = %d", status); + del_vdev_req = qdf_mem_malloc(sizeof(struct del_vdev_params)); + if (!del_vdev_req) + return QDF_STATUS_E_NOMEM; + + qdf_mem_copy(del_vdev_req->self_mac_addr, + session_mac_addr, sizeof(tSirMacAddr)); + + del_vdev_req->vdev_id = vdev_id; + del_vdev_req->sme_callback = callback; + del_vdev_req->sme_ctx = context; + msg.type = eWNI_SME_VDEV_DELETE_REQ; + msg.reserved = 0; + msg.bodyptr = del_vdev_req; + msg.bodyval = 0; + + sme_debug("sending eWNI_SME_VDEV_DELETE_REQ"); + status = scheduler_post_message( + QDF_MODULE_ID_SME, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); + if (status != QDF_STATUS_SUCCESS) { + sme_err("wma_post_ctrl_msg failed"); + qdf_mem_free(del_vdev_req); + return QDF_STATUS_E_FAILURE; } + return QDF_STATUS_SUCCESS; return status; } -void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId) +void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id) { - if (CSR_IS_SESSION_VALID(mac, sessionId)) { + if (CSR_IS_SESSION_VALID(mac, vdev_id)) { struct csr_roam_session *pSession = CSR_GET_SESSION(mac, - sessionId); + vdev_id); - if (!pSession) { - sme_err("Session_ID Invalid %d", sessionId); - return; - } - csr_roam_stop(mac, sessionId); + csr_roam_stop(mac, vdev_id); /* Clean up FT related data structures */ - sme_ft_close(MAC_HANDLE(mac), sessionId); - csr_free_connect_bss_desc(mac, sessionId); - sme_reset_key(MAC_HANDLE(mac), sessionId); + sme_ft_close(MAC_HANDLE(mac), vdev_id); + csr_free_connect_bss_desc(mac, vdev_id); + sme_reset_key(MAC_HANDLE(mac), vdev_id); csr_reset_cfg_privacy(mac); - csr_flush_roam_scan_chan_lists(mac, sessionId); + csr_flush_roam_scan_chan_lists(mac, vdev_id); csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(mac, &pSession->connectedInfo); csr_roam_free_connected_info(mac, &pSession->prev_assoc_ap_info); qdf_mc_timer_destroy(&pSession->hTimerRoaming); qdf_mc_timer_destroy(&pSession->roaming_offload_timer); - csr_purge_vdev_pending_ser_cmd_list(mac, sessionId); - csr_init_session(mac, sessionId); + csr_purge_vdev_pending_ser_cmd_list(mac, vdev_id); + csr_init_session(mac, vdev_id); } } -QDF_STATUS csr_roam_close_session(struct mac_context *mac_ctx, - uint32_t session_id, bool sync) +QDF_STATUS csr_roam_vdev_delete(struct mac_context *mac_ctx, + uint8_t vdev_id, bool cleanup) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct csr_roam_session *session; - if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) + if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) return QDF_STATUS_E_INVAL; - session = CSR_GET_SESSION(mac_ctx, session_id); + session = CSR_GET_SESSION(mac_ctx, vdev_id); /* Vdev going down stop roaming */ session->fCancelRoaming = true; - if (sync) { - csr_cleanup_session(mac_ctx, session_id); + if (cleanup) { + csr_cleanup_vdev_session(mac_ctx, vdev_id); return status; } - if (CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) { + if (CSR_IS_WAIT_FOR_KEY(mac_ctx, vdev_id)) { sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE"); csr_roam_stop_wait_for_key_timer(mac_ctx); csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, - session_id); + vdev_id); } /* * Flush only scan commands. Non scan commands should go in sequence * as expected by firmware and should not be flushed. */ - csr_purge_vdev_all_scan_ser_cmd_list(mac_ctx, session_id); - if (!session->session_close_cb) { + csr_purge_vdev_all_scan_ser_cmd_list(mac_ctx, vdev_id); + if (!mac_ctx->session_close_cb) { sme_err("no close session callback registered"); return QDF_STATUS_E_FAILURE; } - status = csr_issue_del_sta_for_session_req(mac_ctx, - session_id, session->self_mac_addr.bytes, - session->session_close_cb, NULL); + status = csr_issue_vdev_del_req(mac_ctx, vdev_id, + session->self_mac_addr.bytes, + mac_ctx->session_close_cb, NULL); return status; } @@ -18408,8 +17813,6 @@ static void csr_init_session(struct mac_context *mac, uint32_t sessionId) pSession->sessionActive = false; pSession->sessionId = WLAN_UMAC_VDEV_ID_MAX; - pSession->callback = NULL; - pSession->pContext = NULL; pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; csr_saved_scan_cmd_free_fields(mac, pSession); csr_free_roam_profile(mac, sessionId); @@ -18457,442 +17860,84 @@ QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac, struct qdf_mac_addr *bssid, uint32_t *pSessionId) { - QDF_STATUS status = QDF_STATUS_E_FAILURE; - uint32_t i; - - for (i = 0; i < WLAN_MAX_VDEVS; i++) { - if (CSR_IS_SESSION_VALID(mac, i)) { - if (qdf_is_macaddr_equal(bssid, - &mac->roam.roamSession[i].connectedProfile. - bssid)) { - /* Found it */ - status = QDF_STATUS_SUCCESS; - *pSessionId = i; - break; - } - } - } - return status; -} - -/* This function assumes that we only support one IBSS session. - * We cannot use BSSID to identify session because for IBSS, - * the bssid changes. - */ -static uint32_t csr_find_ibss_session(struct mac_context *mac) -{ - uint32_t i, nRet = WLAN_UMAC_VDEV_ID_MAX; - struct csr_roam_session *pSession; - - for (i = 0; i < WLAN_MAX_VDEVS; i++) { - if (CSR_IS_SESSION_VALID(mac, i)) { - pSession = CSR_GET_SESSION(mac, i); - if (pSession->pCurRoamProfile - && - (csr_is_bss_type_ibss - (pSession->connectedProfile.BSSType))) { - /* Found it */ - nRet = i; - break; - } - } - } - return nRet; -} - -static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid) -{ - uint32_t sessionId = 0; - - /* - * Update the current BSS info in ho control block based on connected - * profile info from pmac global structure - */ - - sme_debug("WLAN link UP with AP= " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(bssid.bytes)); - /* Indicate the neighbor roal algorithm about the connect indication */ - csr_roam_get_session_id_from_bssid(mac, &bssid, - &sessionId); - csr_neighbor_roam_indicate_connect(mac, sessionId, - QDF_STATUS_SUCCESS); -} - -static void csr_roam_link_down(struct mac_context *mac, uint32_t sessionId) -{ - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("session %d not found", sessionId); - return; - } - /* Only to handle the case for Handover on infra link */ - if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) - return; - /* - * Incase of station mode, immediately stop data transmission whenever - * link down is detected. - */ - if (csr_roam_is_sta_mode(mac, sessionId) - && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(mac, sessionId) - && !csr_roam_is11r_assoc(mac, sessionId)) { - sme_debug("Inform Link lost for session %d", - sessionId); - csr_roam_call_callback(mac, sessionId, NULL, 0, - eCSR_ROAM_LOSTLINK, - eCSR_ROAM_RESULT_LOSTLINK); - } - /* deregister the clients requesting stats from PE/TL & also stop the - * corresponding timers - */ - csr_roam_dereg_statistics_req(mac); - /* Indicate the neighbor roal algorithm about the disconnect - * indication - */ - csr_neighbor_roam_indicate_disconnect(mac, sessionId); - - /* Remove this code once SLM_Sessionization is supported */ - /* BMPS_WORKAROUND_NOT_NEEDED */ - if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && - csr_is_infra_ap_started(mac) && - mac->roam.configParam.doBMPSWorkaround) { - mac->roam.configParam.doBMPSWorkaround = 0; - } - -} - -#ifndef QCA_SUPPORT_CP_STATS -QDF_STATUS csr_send_mb_stats_req_msg(struct mac_context *mac, uint32_t statsMask, - uint8_t staId, uint8_t sessionId) -{ - tAniGetPEStatsReq *pMsg; - QDF_STATUS status = QDF_STATUS_SUCCESS; - - pMsg = qdf_mem_malloc(sizeof(tAniGetPEStatsReq)); - if (!pMsg) - return QDF_STATUS_E_NOMEM; - - /* need to initiate a stats request to PE */ - pMsg->msgType = eWNI_SME_GET_STATISTICS_REQ; - pMsg->msgLen = (uint16_t) sizeof(tAniGetPEStatsReq); - pMsg->staId = staId; - pMsg->statsMask = statsMask; - pMsg->sessionId = sessionId; - status = umac_send_mb_message_to_mac(pMsg); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_debug("Failed to send down the stats req "); - - return status; -} - -/** - * csr_update_stats() - updates correct stats struct in mac_ctx - * @mac: mac global context - * @stats_type: stats type - * @sme_stats_rsp: stats rsp msg packet - * @stats: input stats data buffer to fill in mac_ctx struct - * @length: out param - stats length - * - * This function fills corresponding stats struct in mac_cts based on stats type - * passed - * - * Return: void - */ -static void -csr_update_stats(struct mac_context *mac, uint8_t stats_type, - tAniGetPEStatsRsp *sme_stats_rsp, - uint8_t **stats, uint32_t *length) -{ - switch (stats_type) { - case eCsrSummaryStats: - sme_debug("summary stats"); - qdf_mem_copy((uint8_t *) &mac->roam.summaryStatsInfo, *stats, - sizeof(tCsrSummaryStatsInfo)); - *stats += sizeof(tCsrSummaryStatsInfo); - *length -= sizeof(tCsrSummaryStatsInfo); - break; - case eCsrGlobalClassAStats: - sme_debug("ClassA stats"); - qdf_mem_copy((uint8_t *) &mac->roam.classAStatsInfo, *stats, - sizeof(tCsrGlobalClassAStatsInfo)); - *stats += sizeof(tCsrGlobalClassAStatsInfo); - *length -= sizeof(tCsrGlobalClassAStatsInfo); - break; - case csr_per_chain_rssi_stats: - sme_debug("csrRoamStatsRspProcessor:Per Chain RSSI stats"); - qdf_mem_copy((uint8_t *)&mac->roam.per_chain_rssi_stats, - *stats, sizeof(struct csr_per_chain_rssi_stats_info)); - *stats += sizeof(struct csr_per_chain_rssi_stats_info); - *length -= sizeof(struct csr_per_chain_rssi_stats_info); - break; - default: - sme_warn("unknown stats type"); - break; - } -} - -/** - * csr_roam_stats_rsp_processor() - processes stats rsp msg - * @mac mac global context - * @pSirMsg: incoming message - * - * Return: void - */ -void csr_roam_stats_rsp_processor(struct mac_context *mac, tSirSmeRsp *pSirMsg) -{ - tAniGetPEStatsRsp *pSmeStatsRsp; - tListElem *pEntry = NULL; - struct csr_statsclient_reqinfo *pTempStaEntry = NULL; - struct csr_pestats_reqinfo *pPeStaEntry = NULL; - uint32_t tempMask = 0; - uint8_t counter = 0; - uint8_t *pStats = NULL; - uint32_t length = 0; - int8_t rssi = 0, snr = 0; - uint32_t *pRssi = NULL, *pSnr = NULL; - uint32_t linkCapacity; - - pSmeStatsRsp = (tAniGetPEStatsRsp *) pSirMsg; - if (pSmeStatsRsp->rc) { - sme_warn("stats rsp from PE shows failure"); - goto post_update; - } - tempMask = pSmeStatsRsp->statsMask; - pStats = ((uint8_t *) &pSmeStatsRsp->statsMask) + - sizeof(pSmeStatsRsp->statsMask); - /* - * subtract all statistics from this length, and after processing the - * entire 'stat' part of the message, if the length is not zero, then - * rssi is piggy packed in this 'stats' message. - */ - length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp); - /* new stats info from PE, fill up the stats strucutres in PMAC */ - while (tempMask) { - if (tempMask & 1) - csr_update_stats(mac, counter, pSmeStatsRsp, - &pStats, &length); - tempMask >>= 1; - counter++; - } - if (length != 0) { - pRssi = (uint32_t *) pStats; - rssi = (int8_t) *pRssi; - pStats += sizeof(uint32_t); - length -= sizeof(uint32_t); - } else - /* If riva is not sending rssi, continue to use the hack */ - rssi = RSSI_HACK_BMPS; - - if (length != 0) { - linkCapacity = *(uint32_t *) pStats; - pStats += sizeof(uint32_t); - length -= sizeof(uint32_t); - } else - linkCapacity = 0; - - if (length != 0) { - pSnr = (uint32_t *) pStats; - snr = (int8_t) *pSnr; - } else - snr = SNR_HACK_BMPS; - -post_update: - /* make sure to update the pe stats req list */ - pEntry = csr_roam_find_in_pe_stats_req_list(mac, - pSmeStatsRsp->statsMask); - if (pEntry) { - pPeStaEntry = GET_BASE_ADDR(pEntry, - struct csr_pestats_reqinfo, link); - pPeStaEntry->rspPending = false; - - } - /* check the one timer cases */ - pEntry = csr_roam_check_client_req_list(mac, pSmeStatsRsp->statsMask); - if (pEntry) { - pTempStaEntry = - GET_BASE_ADDR(pEntry, - struct csr_statsclient_reqinfo, link); - if (pTempStaEntry->timerExpired) { - /* send up the stats report */ - csr_roam_report_statistics(mac, - pTempStaEntry->statsMask, - pTempStaEntry->callback, - pTempStaEntry->staId, - pTempStaEntry->pContext); - /* also remove from the client list */ - csr_roam_remove_stat_list_entry(mac, pEntry); - pTempStaEntry = NULL; - } - } -} - -tListElem *csr_roam_find_in_pe_stats_req_list( - struct mac_context *mac, uint32_t statsMask) -{ - tListElem *pEntry = NULL; - struct csr_pestats_reqinfo *pTempStaEntry = NULL; - - pEntry = csr_ll_peek_head(&mac->roam.peStatsReqList, LL_ACCESS_LOCK); - if (!pEntry) { - sme_debug("List empty, no request to PE"); - return NULL; - } - while (pEntry) { - pTempStaEntry = GET_BASE_ADDR(pEntry, struct csr_pestats_reqinfo, link); - if (pTempStaEntry->statsMask == statsMask) - break; - pEntry = - csr_ll_next(&mac->roam.peStatsReqList, pEntry, - LL_ACCESS_NOLOCK); - } - return pEntry; -} - -static -tListElem *csr_roam_checkn_update_client_req_list( -struct mac_context *mac, struct csr_statsclient_reqinfo *pStaEntry, - bool update) -{ - tListElem *pEntry; - struct csr_statsclient_reqinfo *pTempStaEntry; - - pEntry = csr_ll_peek_head(&mac->roam.statsClientReqList, - LL_ACCESS_LOCK); - if (!pEntry) { - /* list empty */ - sme_debug("List empty, no request from upper layer client(s)"); - return NULL; - } - while (pEntry) { - pTempStaEntry = - GET_BASE_ADDR(pEntry, - struct csr_statsclient_reqinfo, link); - if ((pTempStaEntry->requesterId == pStaEntry->requesterId) - && (pTempStaEntry->statsMask == pStaEntry->statsMask)) { - if (update) { - pTempStaEntry->callback = pStaEntry->callback; - pTempStaEntry->pContext = pStaEntry->pContext; - } - break; - } - pEntry = - csr_ll_next(&mac->roam.statsClientReqList, pEntry, - LL_ACCESS_NOLOCK); - } - return pEntry; -} - -tListElem *csr_roam_check_client_req_list(struct mac_context *mac, - uint32_t statsMask) -{ - tListElem *pEntry; - struct csr_statsclient_reqinfo *pTempStaEntry; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t i; - pEntry = csr_ll_peek_head(&mac->roam.statsClientReqList, - LL_ACCESS_LOCK); - if (!pEntry) { - /* list empty */ - sme_debug("List empty, no request from upper layer client(s)"); - return NULL; - } - while (pEntry) { - pTempStaEntry = - GET_BASE_ADDR(pEntry, - struct csr_statsclient_reqinfo, link); - if ((pTempStaEntry-> - statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) { - break; + for (i = 0; i < WLAN_MAX_VDEVS; i++) { + if (CSR_IS_SESSION_VALID(mac, i)) { + if (qdf_is_macaddr_equal(bssid, + &mac->roam.roamSession[i].connectedProfile. + bssid)) { + /* Found it */ + status = QDF_STATUS_SUCCESS; + *pSessionId = i; + break; + } } - pEntry = - csr_ll_next(&mac->roam.statsClientReqList, pEntry, - LL_ACCESS_NOLOCK); } - return pEntry; + return status; } -struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list( - struct mac_context *mac, tDblLinkList *pStaList, - struct csr_statsclient_reqinfo * - pStaEntry) +static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid) { - struct csr_statsclient_reqinfo *pNewStaEntry = NULL; + uint32_t sessionId = 0; + /* - * if same entity requested for same set of stats with different - * callback update it + * Update the current BSS info in ho control block based on connected + * profile info from pmac global structure */ - if (!csr_roam_checkn_update_client_req_list(mac, pStaEntry, - true)) { - - pNewStaEntry = qdf_mem_malloc(sizeof(struct csr_statsclient_reqinfo)); - if (!pNewStaEntry) - return NULL; - - pNewStaEntry->callback = pStaEntry->callback; - pNewStaEntry->pContext = pStaEntry->pContext; - pNewStaEntry->requesterId = pStaEntry->requesterId; - pNewStaEntry->statsMask = pStaEntry->statsMask; - pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry; - pNewStaEntry->mac = pStaEntry->mac; - pNewStaEntry->staId = pStaEntry->staId; - pNewStaEntry->timerExpired = pStaEntry->timerExpired; - csr_ll_insert_tail(pStaList, &pNewStaEntry->link, - LL_ACCESS_LOCK); - } - return pNewStaEntry; + sme_debug("WLAN link UP with AP= " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid.bytes)); + /* Indicate the neighbor roal algorithm about the connect indication */ + csr_roam_get_session_id_from_bssid(mac, &bssid, + &sessionId); + csr_neighbor_roam_indicate_connect(mac, sessionId, + QDF_STATUS_SUCCESS); } -#endif /* QCA_SUPPORT_CP_STATS */ -QDF_STATUS csr_get_rssi(struct mac_context *mac, - tCsrRssiCallback callback, - uint8_t staId, - struct qdf_mac_addr bssId, - int8_t lastRSSI, void *pContext) +static void csr_roam_link_down(struct mac_context *mac, uint32_t sessionId) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct scheduler_msg msg = {0}; - uint32_t sessionId; - tAniGetRssiReq *pMsg; - - status = csr_roam_get_session_id_from_bssid(mac, &bssId, &sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) { - callback(lastRSSI, staId, pContext); - sme_err("Failed to get SessionId"); - return QDF_STATUS_E_FAILURE; - } + struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - pMsg = qdf_mem_malloc(sizeof(tAniGetRssiReq)); - if (!pMsg) { - return QDF_STATUS_E_NOMEM; + if (!pSession) { + sme_err("session %d not found", sessionId); + return; } - - pMsg->msgType = eWNI_SME_GET_RSSI_REQ; - pMsg->msgLen = (uint16_t) sizeof(tAniGetRssiReq); - pMsg->sessionId = sessionId; - pMsg->staId = staId; - pMsg->rssiCallback = callback; - pMsg->pDevContext = pContext; + /* Only to handle the case for Handover on infra link */ + if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) + return; /* - * store RSSI at time of calling, so that if RSSI request cannot - * be sent to firmware, this value can be used to return immediately + * Incase of station mode, immediately stop data transmission whenever + * link down is detected. */ - pMsg->lastRSSI = lastRSSI; - msg.type = eWNI_SME_GET_RSSI_REQ; - msg.bodyptr = pMsg; - msg.reserved = 0; - if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, - &msg)) { - qdf_mem_free((void *)pMsg); - status = QDF_STATUS_E_FAILURE; + if (csr_roam_is_sta_mode(mac, sessionId) + && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(mac, sessionId) + && !csr_roam_is11r_assoc(mac, sessionId)) { + sme_debug("Inform Link lost for session %d", + sessionId); + csr_roam_call_callback(mac, sessionId, NULL, 0, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_LOSTLINK); } - return status; + /* Indicate the neighbor roal algorithm about the disconnect + * indication + */ + csr_neighbor_roam_indicate_disconnect(mac, sessionId); + + /* Remove this code once SLM_Sessionization is supported */ + /* BMPS_WORKAROUND_NOT_NEEDED */ + if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + csr_is_infra_ap_started(mac) && + mac->roam.configParam.doBMPSWorkaround) { + mac->roam.configParam.doBMPSWorkaround = 0; + } + } QDF_STATUS csr_get_snr(struct mac_context *mac, tCsrSnrCallback callback, - uint8_t staId, struct qdf_mac_addr bssId, void *pContext) + struct qdf_mac_addr bssId, void *pContext) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct scheduler_msg msg = {0}; @@ -18913,7 +17958,6 @@ QDF_STATUS csr_get_snr(struct mac_context *mac, pMsg->msgType = eWNI_SME_GET_SNR_REQ; pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq); pMsg->sessionId = sessionId; - pMsg->staId = staId; pMsg->snrCallback = callback; pMsg->pDevContext = pContext; msg.type = eWNI_SME_GET_SNR_REQ; @@ -18931,141 +17975,6 @@ QDF_STATUS csr_get_snr(struct mac_context *mac, return status; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * csr_deregister_client_request() - deregisters a get stats request - * @mac_ctx: mac global context - * @sta_entry: stats request entry - * - * Return: status of operation - */ -static QDF_STATUS -csr_deregister_client_request(struct mac_context *mac_ctx, - struct csr_statsclient_reqinfo *sta_entry) -{ - QDF_STATUS status; - tListElem *entry = NULL; - struct csr_statsclient_reqinfo *ptr_sta_entry = NULL; - - entry = csr_roam_checkn_update_client_req_list(mac_ctx, sta_entry, - false); - if (!entry) { - sme_err("callback is empty in the request & couldn't find any existing request in statsClientReqList"); - return QDF_STATUS_E_FAILURE; - } - /* clean up & return */ - ptr_sta_entry = GET_BASE_ADDR(entry, - struct csr_statsclient_reqinfo, link); - if (ptr_sta_entry->pPeStaEntry) { - ptr_sta_entry->pPeStaEntry->numClient--; - /* check if we need to delete the entry from peStatsReqList */ - if (!ptr_sta_entry->pPeStaEntry->numClient) - csr_roam_remove_entry_from_pe_stats_req_list(mac_ctx, - ptr_sta_entry->pPeStaEntry); - } - /* check if we need to stop the tl stats timer too */ - mac_ctx->roam.tlStatsReqInfo.numClient--; - qdf_mc_timer_stop(&ptr_sta_entry->timer); - /* Destroy the qdf timer... */ - status = qdf_mc_timer_destroy(&ptr_sta_entry->timer); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err( - "failed to destroy Client req timer"); - - csr_roam_remove_stat_list_entry(mac_ctx, entry); - return QDF_STATUS_SUCCESS; -} - -/** - * csr_insert_stats_request_to_list() - inserts request to existing list - * @mac_ctx: mac global context - * @sta_entry: stats request entry - * - * Return: status of operation - */ -static QDF_STATUS -csr_insert_stats_request_to_list(struct mac_context *mac_ctx, - struct csr_statsclient_reqinfo *sta_entry) -{ -struct csr_statsclient_reqinfo *ptr_sta_entry = csr_roam_insert_entry_into_list( - mac_ctx, &mac_ctx->roam.statsClientReqList, - sta_entry); - if (!ptr_sta_entry) { - sme_err("Failed to insert req in statsClientReqList"); - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS csr_get_statistics(struct mac_context *mac, - eCsrStatsRequesterType requesterId, - uint32_t statsMask, - tCsrStatsCallback callback, - uint8_t staId, - void *pContext, - uint8_t sessionId) -{ - struct csr_statsclient_reqinfo staEntry; - QDF_STATUS status = QDF_STATUS_SUCCESS; - bool insertInClientList = false; - uint32_t temp_mask = 0; - - if (csr_is_all_session_disconnected(mac)) - return QDF_STATUS_E_FAILURE; - - if (csr_neighbor_middle_of_roaming(mac, sessionId)) { - sme_debug("in the middle of roaming states"); - return QDF_STATUS_E_FAILURE; - } - - if ((!statsMask) && (!callback)) { - sme_err("statsMask & callback empty in the request"); - return QDF_STATUS_E_FAILURE; - } - /* for the search list method for deregister */ - staEntry.requesterId = requesterId; - staEntry.statsMask = statsMask; - /* requester wants to deregister or just an error */ - if ((statsMask) && (!callback)) - return csr_deregister_client_request(mac, &staEntry); - - /* add the request in the client req list */ - staEntry.callback = callback; - staEntry.pContext = pContext; - staEntry.pPeStaEntry = NULL; - staEntry.staId = staId; - staEntry.mac = mac; - staEntry.timerExpired = false; - staEntry.sessionId = sessionId; - - temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats); - if (temp_mask) { - /* send down a req */ - status = csr_send_mb_stats_req_msg(mac, - temp_mask, staId, sessionId); - if (!QDF_IS_STATUS_SUCCESS(status)) - sme_err("failed to send down stats req"); - /* - * so that when the stats rsp comes back from PE we - * respond to upper layer right away - */ - staEntry.timerExpired = true; - insertInClientList = true; - } - /* if looking for stats from TL only */ - if (!insertInClientList) { - /* return the stats */ - csr_roam_report_statistics(mac, statsMask, callback, - staId, pContext); - return QDF_STATUS_SUCCESS; - } - if (insertInClientList) - return csr_insert_stats_request_to_list(mac, &staEntry); - - return QDF_STATUS_SUCCESS; -} -#endif /* QCA_SUPPORT_CP_STATS */ - #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * csr_roam_set_key_mgmt_offload() - enable/disable key mgmt offload @@ -19276,6 +18185,8 @@ csr_update_roam_scan_offload_request(struct mac_context *mac_ctx, mac_ctx->mlme_cfg->lfr.roam_force_rssi_trigger); csr_update_roam_req_adaptive_11r(session, mac_ctx, req_buf); + req_buf->enable_ft_im_roaming = + mac_ctx->mlme_cfg->lfr.enable_ft_im_roaming; /* fill bss load triggered roam related configs */ req_buf->bss_load_trig_enabled = mac_ctx->mlme_cfg->lfr.bss_load_trig.enabled; @@ -19415,36 +18326,38 @@ csr_populate_roam_chan_list(struct mac_context *mac_ctx, tCsrChannelInfo *src) { enum band_info band; + uint32_t band_cap; uint8_t i = 0; uint8_t num_channels = 0; - uint8_t *ch_lst = src->ChannelList; + uint32_t *freq_lst = src->freq_list; /* * The INI channels need to be filtered with respect to the current band * that is supported. */ - band = mac_ctx->mlme_cfg->gen.band_capability; - if ((BAND_2G != band) && (BAND_5G != band) - && (BAND_ALL != band)) { + band_cap = mac_ctx->mlme_cfg->gen.band_capability; + if (!band_cap) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "Invalid band(%d), roam scan offload req aborted", - band); + "Invalid band_cap(%d), roam scan offload req aborted", + band_cap); return QDF_STATUS_E_FAILURE; } + band = wlan_reg_band_bitmap_to_band_info(band_cap); + num_channels = dst->ChannelCount; for (i = 0; i < src->numOfChannels; i++) { - if (csr_is_channel_present_in_list(dst->ChannelCache, - num_channels, *ch_lst)) { - ch_lst++; + if (csr_is_channel_present_in_list(dst->chan_freq_cache, + num_channels, *freq_lst)) { + freq_lst++; continue; } - if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_lst, band)) { - ch_lst++; + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *freq_lst, band)) { + freq_lst++; continue; } - dst->ChannelCache[num_channels++] = *ch_lst; - ch_lst++; + dst->chan_freq_cache[num_channels++] = *freq_lst; + freq_lst++; } dst->ChannelCount = num_channels; @@ -19503,17 +18416,22 @@ csr_fetch_ch_lst_from_occupied_lst(struct mac_context *mac_ctx, { uint8_t i = 0; uint8_t num_channels = 0; - uint8_t op_chan; + uint32_t op_freq; struct csr_roam_session *session; - uint8_t *ch_lst; + uint32_t *ch_lst; enum band_info band = BAND_ALL; session = &mac_ctx->roam.roamSession[session_id]; - ch_lst = mac_ctx->scan.occupiedChannels[session_id].channelList; - op_chan = session->connectedProfile.operationChannel; + ch_lst = mac_ctx->scan.occupiedChannels[session_id].channel_freq_list; + op_freq = session->connectedProfile.op_freq; if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) { - band = csr_get_rf_band(op_chan); + if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) + band = BAND_5G; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) + band = BAND_2G; + else + band = BAND_UNKNOWN; } for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels; i++) { @@ -19521,7 +18439,7 @@ csr_fetch_ch_lst_from_occupied_lst(struct mac_context *mac_ctx, ch_lst++; continue; } - req_buf->ConnectedNetwork.ChannelCache[num_channels++] = *ch_lst; + req_buf->ConnectedNetwork.chan_freq_cache[num_channels++] = *ch_lst; ch_lst++; } req_buf->ConnectedNetwork.ChannelCount = num_channels; @@ -19544,40 +18462,43 @@ csr_fetch_valid_ch_lst(struct mac_context *mac_ctx, { QDF_STATUS status; uint32_t host_channels = 0; - uint8_t *ch_lst = NULL; + uint32_t *ch_freq_list = NULL; uint8_t i = 0, num_channels = 0; enum band_info band = BAND_ALL; - uint8_t op_chan; + uint32_t op_freq; struct csr_roam_session *session; session = &mac_ctx->roam.roamSession[session_id]; - op_chan = session->connectedProfile.operationChannel; + op_freq = session->connectedProfile.op_freq; if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) { - band = csr_get_rf_band(op_chan); + if (WLAN_REG_IS_5GHZ_CH_FREQ(op_freq)) + band = BAND_5G; + else if (WLAN_REG_IS_24GHZ_CH_FREQ(op_freq)) + band = BAND_2G; + else + band = BAND_UNKNOWN; } - - host_channels = sizeof(mac_ctx->roam.validChannelList); + host_channels = sizeof(mac_ctx->roam.valid_ch_freq_list); status = csr_get_cfg_valid_channels(mac_ctx, - mac_ctx->roam.validChannelList, + mac_ctx->roam.valid_ch_freq_list, &host_channels); if (!QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "Failed to get the valid channel list"); return status; } - - ch_lst = mac_ctx->roam.validChannelList; + ch_freq_list = mac_ctx->roam.valid_ch_freq_list; mac_ctx->roam.numValidChannels = host_channels; for (i = 0; i < mac_ctx->roam.numValidChannels; i++) { - if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_lst, + if (is_dfs_unsafe_extra_band_chan(mac_ctx, *ch_freq_list, band)) { - ch_lst++; + ch_freq_list++; continue; } - req_buf->ConnectedNetwork.ChannelCache[num_channels++] = - *ch_lst; - ch_lst++; + req_buf->ConnectedNetwork.chan_freq_cache[num_channels++] = + *ch_freq_list; + ch_freq_list++; } req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC; req_buf->ConnectedNetwork.ChannelCount = num_channels; @@ -19612,7 +18533,7 @@ csr_add_ch_lst_from_roam_scan_list(struct mac_context *mac_ctx, sme_err("Failed to copy channels to roam list"); return status; } - sme_dump_chan_list(pref_chan_info); + sme_dump_freq_list(pref_chan_info); req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC; return QDF_STATUS_SUCCESS; @@ -19633,26 +18554,100 @@ csr_rso_command_fill_11w_params(struct mac_context *mac_ctx, struct roam_offload_scan_req *rso_req) { tSirRoamNetworkType *network_cfg = &rso_req->ConnectedNetwork; - tCsrRoamConnectedProfile session_connected_profile = - mac_ctx->roam.roamSession[session_id].connectedProfile; tAniEdType group_mgmt_cipher; - network_cfg->mfp_enabled = session_connected_profile.MFPEnabled; - group_mgmt_cipher = session_connected_profile.mgmt_encryption_type; + struct wlan_objmgr_vdev *vdev; + uint16_t rsn_caps; + bool peer_rmf_capable = false; + uint32_t keymgmt; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, + session_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return; + } + + rsn_caps = (uint16_t)wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_RSN_CAP); + if (wlan_crypto_vdev_has_mgmtcipher(vdev, + (1 << WLAN_CRYPTO_CIPHER_AES_GMAC) | + (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256) | + (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) && + (rsn_caps & + WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) + peer_rmf_capable = true; + + network_cfg->mfp_enabled = peer_rmf_capable; + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MGMT_CIPHER); + + if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) { + group_mgmt_cipher = eSIR_ED_AES_128_CMAC; + } else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC)) { + group_mgmt_cipher = eSIR_ED_AES_GMAC_128; + } else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256)) { + group_mgmt_cipher = eSIR_ED_AES_GMAC_256; + } else { + group_mgmt_cipher = eSIR_ED_NONE; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + if (network_cfg->mfp_enabled) network_cfg->gp_mgmt_cipher_suite = group_mgmt_cipher; else network_cfg->gp_mgmt_cipher_suite = eSIR_ED_NONE; + + pe_debug("gp_mgmt_cipher_suite %d", network_cfg->gp_mgmt_cipher_suite); } +static void csr_fill_pmf_caps(uint16_t *rsn_caps, + tCsrRoamConnectedProfile *profile) +{ + *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; + *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; + if (profile->MFPRequired) + *rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; + if (profile->MFPCapable) + *rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; +} #else static inline void csr_rso_command_fill_11w_params(struct mac_context *mac_ctx, uint8_t session_id, struct roam_offload_scan_req *rso_req) {} + +static inline +void csr_fill_pmf_caps(uint16_t *rsn_caps, tCsrRoamConnectedProfile *profile) +{ + *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; + *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; +} #endif +static void +csr_rso_command_fill_rsn_caps(struct mac_context *mac_ctx, uint8_t vdev_id, + uint16_t *rsn_caps, + tCsrRoamConnectedProfile *profile) +{ + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return; + } + + *rsn_caps = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP); + csr_fill_pmf_caps(rsn_caps, profile); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); +} + /** * csr_update_btm_offload_config() - Update btm config param to fw * @mac_ctx: Global mac ctx @@ -19693,15 +18688,15 @@ static void csr_update_btm_offload_config(struct mac_context *mac_ctx, session->pConnectBssDesc->bssId, WLAN_LEGACY_SME_ID); if (!peer) { - sme_debug("Peer of peer_mac %pM not found", - session->pConnectBssDesc->bssId); + sme_debug("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(session->pConnectBssDesc->bssId)); return; } is_pmf_enabled = mlme_get_peer_pmf_status(peer); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID); - sme_debug("get is_pmf_enabled %d for %pM", is_pmf_enabled, - session->pConnectBssDesc->bssId); + sme_debug("get is_pmf_enabled %d for "QDF_MAC_ADDR_FMT, is_pmf_enabled, + QDF_MAC_ADDR_REF(session->pConnectBssDesc->bssId)); /* If peer does not support PMF in case of OCE/MBO * Connection, Disable BTM offload to firmware. @@ -19800,9 +18795,11 @@ csr_create_roam_scan_offload_request(struct mac_context *mac_ctx, req_buf->ConnectedNetwork.mcencryption = mac_ctx->roam.roamSession[session_id]. connectedProfile.mcEncryptionType; - /* Copy the RSN capabilities in roam offload request from session*/ - req_buf->rsn_caps = session->rsn_caps; + /* Copy the self RSN capabilities in roam offload request */ + csr_rso_command_fill_rsn_caps(mac_ctx, session_id, + (uint16_t *)&req_buf->rsn_caps, + &mac_ctx->roam.roamSession[session_id].connectedProfile); csr_rso_command_fill_11w_params(mac_ctx, session_id, req_buf); req_buf->delay_before_vdev_stop = @@ -19846,6 +18843,9 @@ csr_create_roam_scan_offload_request(struct mac_context *mac_ctx, mac_ctx->mlme_cfg->trig_min_rssi[DEAUTH_MIN_RSSI]; req_buf->min_rssi_params[BMISS_MIN_RSSI] = mac_ctx->mlme_cfg->trig_min_rssi[BMISS_MIN_RSSI]; + req_buf->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM] = + mac_ctx->mlme_cfg->trig_min_rssi[MIN_RSSI_2G_TO_5G_ROAM]; + req_buf->score_delta_param[IDLE_ROAM_TRIGGER] = mac_ctx->mlme_cfg->trig_score_delta[IDLE_ROAM_TRIGGER]; req_buf->score_delta_param[BTM_ROAM_TRIGGER] = @@ -19931,7 +18931,7 @@ csr_create_roam_scan_offload_request(struct mac_context *mac_ctx, j += snprintf(ch_cache_str + j, sizeof(ch_cache_str) - j, " %d", req_buf->ConnectedNetwork. - ChannelCache[i]); + chan_freq_cache[i]); } else break; } @@ -20229,8 +19229,8 @@ csr_add_rssi_reject_ap_list(struct mac_context *mac_ctx, for (i = 0; i < roam_params->num_rssi_rejection_ap; i++) { roam_params->rssi_reject_bssid_list[i] = reject_list[i]; - sme_debug("BSSID %pM expected rssi %d remaining duration %d", - roam_params->rssi_reject_bssid_list[i].bssid.bytes, + sme_debug("BSSID "QDF_MAC_ADDR_FMT" expected rssi %d remaining duration %d", + QDF_MAC_ADDR_REF(roam_params->rssi_reject_bssid_list[i].bssid.bytes), roam_params->rssi_reject_bssid_list[i].expected_rssi, roam_params->rssi_reject_bssid_list[i].reject_duration); } @@ -20281,7 +19281,7 @@ csr_roam_send_rso_cmd(struct mac_context *mac_ctx, static void csr_append_assoc_ies(struct mac_context *mac_ctx, struct roam_offload_scan_req *req_buf, uint8_t ie_id, uint8_t ie_len, - uint8_t *ie_data) + const uint8_t *ie_data) { tSirAddie *assoc_ie = &req_buf->assoc_ie; @@ -20370,16 +19370,19 @@ static void csr_update_driver_assoc_ies(struct mac_context *mac_ctx, uint8_t supp_chan_ie[DOT11F_IE_SUPPCHANNELS_MAX_LEN], supp_chan_ie_len; #ifdef FEATURE_WLAN_ESE - uint8_t ese_ie[] = { 0x0, 0x40, 0x96, 0x3, ESE_VERSION_SUPPORTED}; + static const uint8_t ese_ie[] = {0x0, 0x40, 0x96, 0x3, + ESE_VERSION_SUPPORTED}; #endif - uint8_t qcn_ie[] = {0x8C, 0xFD, 0xF0, 0x1, QCN_IE_VERSION_SUBATTR_ID, - QCN_IE_VERSION_SUBATTR_DATA_LEN, - QCN_IE_VERSION_SUPPORTED, - QCN_IE_SUBVERSION_SUPPORTED}; + static const uint8_t qcn_ie[] = {0x8C, 0xFD, 0xF0, 0x1, + QCN_IE_VERSION_SUBATTR_ID, + QCN_IE_VERSION_SUBATTR_DATA_LEN, + QCN_IE_VERSION_SUPPORTED, + QCN_IE_SUBVERSION_SUPPORTED}; if (session->pConnectBssDesc) - max_tx_pwr_cap = csr_get_cfg_max_tx_power(mac_ctx, - session->pConnectBssDesc->channelId); + max_tx_pwr_cap = csr_get_cfg_max_tx_power( + mac_ctx, + session->pConnectBssDesc->chan_freq); if (max_tx_pwr_cap && max_tx_pwr_cap < MAX_TX_PWR_CAP) power_cap_ie_data[1] = max_tx_pwr_cap; @@ -20824,8 +19827,6 @@ csr_post_rso_stop(struct mac_context *mac, uint8_t vdev_id, uint16_t reason) status = csr_roam_send_rso_cmd(mac, vdev_id, req); if (QDF_IS_STATUS_ERROR(status)) { sme_err("ROAM: Post RSO stop failed, vdev_id: %d", vdev_id); - qdf_mem_zero(req, sizeof(*req)); - qdf_mem_free(req); return QDF_STATUS_E_FAULT; } roam_info->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP; @@ -21004,6 +20005,7 @@ csr_roam_switch_to_deinit(struct mac_context *mac, uint8_t vdev_id, uint8_t reason) { QDF_STATUS status; + bool sup_disabled_roam; enum roam_offload_state cur_state = mlme_get_roam_state(mac->psoc, vdev_id); switch (cur_state) { @@ -21011,6 +20013,28 @@ csr_roam_switch_to_deinit(struct mac_context *mac, uint8_t vdev_id, csr_roam_switch_to_rso_stop(mac, vdev_id, reason); break; case ROAM_RSO_STOPPED: + /* + * When Supplicant disabled roaming is set and roam invoke + * command is received from userspace, fw starts to roam. + * But meanwhile if a disassoc/deauth is received from AP or if + * NB disconnect is initiated while supplicant disabled roam, + * RSO stop with ROAM scan mode as 0 is not sent to firmware + * since the previous state was RSO_STOPPED. This could lead + * to firmware not sending peer unmap event for the current + * AP. To avoid this, if previous RSO stop was sent with + * ROAM scan mode as 4, send RSO stop with Roam scan mode as 0 + * and then switch to ROAM_DEINIT. + */ + sup_disabled_roam = + mlme_get_supplicant_disabled_roaming(mac->psoc, + vdev_id); + if (sup_disabled_roam) { + sme_debug("vdev[%d]: supplicant disabled roam. clear roam scan mode", + vdev_id); + csr_post_rso_stop(mac, vdev_id, REASON_DISCONNECTED); + } + break; + case ROAM_INIT: break; @@ -21029,6 +20053,7 @@ csr_roam_switch_to_deinit(struct mac_context *mac, uint8_t vdev_id, return status; mlme_set_roam_state(mac->psoc, vdev_id, ROAM_DEINIT); + mlme_clear_operations_bitmap(mac->psoc, vdev_id); if (reason != REASON_SUPPLICANT_INIT_ROAMING) csr_enable_roaming_on_connected_sta(mac, vdev_id); @@ -21106,7 +20131,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, struct roam_ext_params *roam_params_dst; struct roam_ext_params *roam_params_src; uint8_t temp_session_id; - uint8_t op_channel; bool prev_roaming_state; enum csr_akm_type roam_profile_akm = eCSR_AUTH_TYPE_UNKNOWN; uint32_t fw_akm_bitmap; @@ -21170,13 +20194,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, return QDF_STATUS_SUCCESS; } - if ((roam_profile_akm == eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 || - roam_profile_akm == eCSR_AUTH_TYPE_SUITEB_EAP_SHA384) && - !CSR_IS_FW_SUITEB_ROAM_SUPPORTED(fw_akm_bitmap)) { - sme_info("Roaming not supported for SUITEB connection"); - return QDF_STATUS_SUCCESS; - } - /* * If fw doesn't advertise FT SAE, FT-FILS or FT-Suite-B capability, * don't support roaming to that profile @@ -21290,6 +20307,12 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, mac_ctx->mlme_cfg->lfr.roam_bg_scan_client_bitmap; roam_params_dst->roam_bad_rssi_thresh_offset_2g = mac_ctx->mlme_cfg->lfr.roam_bg_scan_bad_rssi_offset_2g; + roam_params_dst->roam_data_rssi_threshold_triggers = + mac_ctx->mlme_cfg->lfr.roam_data_rssi_threshold_triggers; + roam_params_dst->roam_data_rssi_threshold = + mac_ctx->mlme_cfg->lfr.roam_data_rssi_threshold; + roam_params_dst->rx_data_inactivity_time = + mac_ctx->mlme_cfg->lfr.rx_data_inactivity_time; roam_params_dst->raise_rssi_thresh_5g = mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g; roam_params_dst->drop_rssi_thresh_5g = @@ -21315,7 +20338,6 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, roam_params_dst->dense_min_aps_cnt) roam_params_dst->initial_dense_status = true; - op_channel = session->connectedProfile.operationChannel; req_buf->hi_rssi_scan_max_count = roam_info->cfgParams.hi_rssi_scan_max_count; req_buf->hi_rssi_scan_delay = @@ -21371,218 +20393,36 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, prev_roaming_state); policy_mgr_set_pcl_for_existing_combo(mac_ctx->psoc, PM_STA_MODE); - return QDF_STATUS_E_FAILURE; - } - /* update the last sent cmd */ - roam_info->last_sent_cmd = command; - - return status; -} - -QDF_STATUS -csr_roam_offload_scan_rsp_hdlr(struct mac_context *mac, - struct roam_offload_scan_rsp *scanOffloadRsp) -{ - switch (scanOffloadRsp->reason) { - case 0: - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "Rsp for Roam Scan Offload with failure status"); - break; - case REASON_OS_REQUESTED_ROAMING_NOW: - csr_neighbor_roam_proceed_with_handoff_req(mac, - scanOffloadRsp->sessionId); - break; - - default: - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "Rsp for Roam Scan Offload with reason %d", - scanOffloadRsp->reason); - } - return QDF_STATUS_SUCCESS; -} -#endif - -#ifndef QCA_SUPPORT_CP_STATS -/* pStaEntry is no longer invalid upon the return of this function. */ -static void csr_roam_remove_stat_list_entry(struct mac_context *mac, - tListElem *pEntry) -{ - if (pEntry) { - if (csr_ll_remove_entry(&mac->roam.statsClientReqList, - pEntry, LL_ACCESS_LOCK)) - qdf_mem_free(GET_BASE_ADDR(pEntry, - struct csr_statsclient_reqinfo, link)); - } -} - -static void csr_roam_remove_entry_from_pe_stats_req_list( -struct mac_context *mac, struct csr_pestats_reqinfo *pPeStaEntry) -{ - tListElem *pEntry; - struct csr_pestats_reqinfo *pTempStaEntry; - - pEntry = csr_ll_peek_head(&mac->roam.peStatsReqList, LL_ACCESS_LOCK); - if (!pEntry) { - sme_err("List empty, no stats req for PE"); - return; - } - while (pEntry) { - pTempStaEntry = GET_BASE_ADDR(pEntry, - struct csr_pestats_reqinfo, link); - if (!pTempStaEntry - || (pTempStaEntry->statsMask != - pPeStaEntry->statsMask)) { - pEntry = csr_ll_next(&mac->roam.peStatsReqList, pEntry, - LL_ACCESS_NOLOCK); - continue; - } - sme_debug("Match found"); - if (csr_ll_remove_entry(&mac->roam.peStatsReqList, pEntry, - LL_ACCESS_LOCK)) { - qdf_mem_free(pTempStaEntry); - pTempStaEntry = NULL; - break; - } - pEntry = csr_ll_next(&mac->roam.peStatsReqList, pEntry, - LL_ACCESS_NOLOCK); - } /* end of while loop */ -} - -static void csr_roam_report_statistics(struct mac_context *mac, - uint32_t statsMask, - tCsrStatsCallback callback, uint8_t staId, - void *pContext) -{ - uint8_t stats[500]; - uint8_t *pStats = NULL; - uint32_t tempMask = 0; - uint8_t counter = 0; - - if (!callback) { - sme_err("Cannot report callback NULL"); - return; - } - if (!statsMask) { - sme_err("Cannot report statsMask is 0"); - return; - } - pStats = stats; - tempMask = statsMask; - while (tempMask) { - if (tempMask & 1) { - /* new stats info from PE, fill up the stats - * strucutres in PMAC - */ - switch (counter) { - case eCsrSummaryStats: - sme_debug("Summary stats"); - qdf_mem_copy(pStats, - (uint8_t *) &mac->roam. - summaryStatsInfo, - sizeof(tCsrSummaryStatsInfo)); - pStats += sizeof(tCsrSummaryStatsInfo); - break; - case eCsrGlobalClassAStats: - sme_debug("ClassA stats"); - qdf_mem_copy(pStats, - (uint8_t *) &mac->roam. - classAStatsInfo, - sizeof(tCsrGlobalClassAStatsInfo)); - pStats += sizeof(tCsrGlobalClassAStatsInfo); - break; - case eCsrGlobalClassDStats: - sme_debug("ClassD stats"); - qdf_mem_copy(pStats, - (uint8_t *) &mac->roam. - classDStatsInfo, - sizeof(tCsrGlobalClassDStatsInfo)); - pStats += sizeof(tCsrGlobalClassDStatsInfo); - break; - case csr_per_chain_rssi_stats: - sme_debug("Per Chain RSSI stats"); - qdf_mem_copy(pStats, - (uint8_t *)&mac->roam.per_chain_rssi_stats, - sizeof(struct csr_per_chain_rssi_stats_info)); - pStats += sizeof( - struct csr_per_chain_rssi_stats_info); - break; - default: - sme_err( - "Unknown stats type and counter %d", - counter); - break; - } - } - tempMask >>= 1; - counter++; + return QDF_STATUS_E_FAILURE; } - callback(stats, pContext); + /* update the last sent cmd */ + roam_info->last_sent_cmd = command; + + return status; } -static QDF_STATUS csr_roam_dereg_statistics_req( - struct mac_context *mac) +QDF_STATUS +csr_roam_offload_scan_rsp_hdlr(struct mac_context *mac, + struct roam_offload_scan_rsp *scanOffloadRsp) { - tListElem *pEntry = NULL; - tListElem *pPrevEntry = NULL; - struct csr_statsclient_reqinfo *pTempStaEntry = NULL; - QDF_STATUS status = QDF_STATUS_SUCCESS; + switch (scanOffloadRsp->reason) { + case 0: + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "Rsp for Roam Scan Offload with failure status"); + break; + case REASON_OS_REQUESTED_ROAMING_NOW: + csr_neighbor_roam_proceed_with_handoff_req(mac, + scanOffloadRsp->sessionId); + break; - pEntry = csr_ll_peek_head(&mac->roam.statsClientReqList, - LL_ACCESS_LOCK); - if (!pEntry) { - /* list empty */ - sme_debug("List empty, no request from upper layer client(s)"); - return status; - } - while (pEntry) { - if (pPrevEntry) { - pTempStaEntry = - GET_BASE_ADDR(pPrevEntry, - struct csr_statsclient_reqinfo, link); - /* send up the stats report */ - csr_roam_report_statistics(mac, - pTempStaEntry->statsMask, - pTempStaEntry->callback, - pTempStaEntry->staId, - pTempStaEntry->pContext); - csr_roam_remove_stat_list_entry(mac, pPrevEntry); - } - pTempStaEntry = - GET_BASE_ADDR(pEntry, struct csr_statsclient_reqinfo, link); - if (pTempStaEntry->pPeStaEntry) { - /* pPeStaEntry can be NULL */ - pTempStaEntry->pPeStaEntry->numClient--; - /* check if we need to delete the entry from - * peStatsReqList too - */ - if (!pTempStaEntry->pPeStaEntry->numClient) { - csr_roam_remove_entry_from_pe_stats_req_list( - mac, - pTempStaEntry-> - pPeStaEntry); - } - } - /* check if we need to stop the tl stats timer too */ - mac->roam.tlStatsReqInfo.numClient--; - pPrevEntry = pEntry; - pEntry = csr_ll_next(&mac->roam.statsClientReqList, pEntry, - LL_ACCESS_NOLOCK); - } - /* the last one */ - if (pPrevEntry) { - pTempStaEntry = - GET_BASE_ADDR(pPrevEntry, struct csr_statsclient_reqinfo, link); - /* send up the stats report */ - csr_roam_report_statistics(mac, pTempStaEntry->statsMask, - pTempStaEntry->callback, - pTempStaEntry->staId, - pTempStaEntry->pContext); - csr_roam_remove_stat_list_entry(mac, pPrevEntry); + default: + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + "Rsp for Roam Scan Offload with reason %d", + scanOffloadRsp->reason); } - return status; - + return QDF_STATUS_SUCCESS; } -#endif /* QCA_SUPPORT_CP_STATS */ +#endif tSmeCmd *csr_get_command_buffer(struct mac_context *mac) { @@ -21641,7 +20481,7 @@ void csr_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd) return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, - sme_cmd->sessionId, WLAN_LEGACY_SME_ID); + sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); if (!vdev) { sme_err("Invalid vdev"); return; @@ -21743,8 +20583,8 @@ enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd) case eSmeCommandWmStatusChange: cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE; break; - case e_sme_command_del_sta_session: - cmd_type = WLAN_SER_CMD_DEL_STA_SESSION; + case eSmeCommandGetdisconnectStats: + cmd_type = WLAN_SER_CMD_GET_DISCONNECT_STATS; break; case eSmeCommandAddTs: cmd_type = WLAN_SER_CMD_ADDTS; @@ -21801,8 +20641,9 @@ static void csr_fill_cmd_timeout(struct wlan_serialization_command *cmd) case WLAN_SER_CMD_FORCE_DEAUTH_STA: cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT; break; - case WLAN_SER_CMD_DEL_STA_SESSION: - cmd->cmd_timeout_duration = SME_VDEV_DELETE_CMD_TIMEOUT; + case WLAN_SER_CMD_GET_DISCONNECT_STATS: + cmd->cmd_timeout_duration = + SME_CMD_GET_DISCONNECT_STATS_TIMEOUT; break; case WLAN_SER_CMD_HDD_ISSUE_REASSOC_SAME_AP: case WLAN_SER_CMD_SME_ISSUE_REASSOC_SAME_AP: @@ -21859,9 +20700,9 @@ QDF_STATUS csr_set_serialization_params_to_cmd(struct mac_context *mac_ctx, return status; } cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, - sme_cmd->sessionId, WLAN_LEGACY_SME_ID); + sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); if (!cmd->vdev) { - sme_err("vdev is NULL for sme_session:%d", sme_cmd->sessionId); + sme_err("vdev is NULL for vdev_id:%d", sme_cmd->vdev_id); return status; } cmd->umac_cmd = sme_cmd; @@ -21889,7 +20730,7 @@ QDF_STATUS csr_queue_sme_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd, goto error; } - if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sme_cmd->sessionId)) { + if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sme_cmd->vdev_id)) { if (!CSR_IS_DISCONNECT_COMMAND(sme_cmd)) { sme_err("Can't process cmd(%d), waiting for key", sme_cmd->command); @@ -21950,7 +20791,7 @@ QDF_STATUS csr_roam_update_config(struct mac_context *mac_ctx, uint8_t session_i return QDF_STATUS_E_NOMEM; msg->messageType = eWNI_SME_UPDATE_CONFIG; - msg->sme_session_id = session_id; + msg->vdev_id = session_id; msg->capab = capab; msg->value = value; msg->length = sizeof(*msg); @@ -22010,7 +20851,7 @@ QDF_STATUS csr_handoff_request(struct mac_context *mac, pMsg->msgType = eWNI_SME_HANDOFF_REQ; pMsg->msgLen = (uint16_t) sizeof(tAniHandoffReq); pMsg->sessionId = sessionId; - pMsg->channel = pHandoffInfo->channel; + pMsg->ch_freq = pHandoffInfo->ch_freq; pMsg->handoff_src = pHandoffInfo->src; qdf_mem_copy(pMsg->bssid, pHandoffInfo->bssid.bytes, QDF_MAC_ADDR_SIZE); msg.type = eWNI_SME_HANDOFF_REQ; @@ -22069,12 +20910,12 @@ QDF_STATUS csr_roam_channel_change_req(struct mac_context *mac, msg->messageType = eWNI_SME_CHANNEL_CHANGE_REQ; msg->messageLen = sizeof(tSirChanChangeRequest); - msg->targetChannel = profile->ChannelInfo.ChannelList[0]; + msg->target_chan_freq = profile->ChannelInfo.freq_list[0]; msg->sec_ch_offset = ch_params->sec_ch_offset; msg->ch_width = profile->ch_params.ch_width; msg->dot11mode = csr_translate_to_wni_cfg_dot11_mode(mac, param.uCfgDot11Mode); - if (IS_24G_CH(msg->targetChannel) && + if (WLAN_REG_IS_24GHZ_CH_FREQ(msg->target_chan_freq) && !mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && (msg->dot11mode == MLME_DOT11_MODE_11AC || msg->dot11mode == MLME_DOT11_MODE_11AC_ONLY)) @@ -22162,7 +21003,7 @@ csr_roam_modify_add_ies(struct mac_context *mac, qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid); - pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId; + pModifyAddIEInd->modifyIE.vdev_id = pModifyIE->vdev_id; pModifyAddIEInd->modifyIE.notify = pModifyIE->notify; pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID; pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen; @@ -22225,7 +21066,7 @@ csr_roam_update_add_ies(struct mac_context *mac, qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid); - pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId; + pUpdateAddIEs->updateIE.vdev_id = pUpdateIE->vdev_id; pUpdateAddIEs->updateIE.append = pUpdateIE->append; pUpdateAddIEs->updateIE.notify = pUpdateIE->notify; pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength; @@ -22266,7 +21107,7 @@ QDF_STATUS csr_send_ext_change_channel(struct mac_context *mac_ctx, uint32_t cha msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL; msg->length = sizeof(*msg); msg->new_channel = channel; - msg->session_id = session_id; + msg->vdev_id = session_id; status = umac_send_mb_message_to_mac(msg); return status; } @@ -22293,7 +21134,7 @@ QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t session_id) * csr_roam_send_chan_sw_ie_request() - Request to transmit CSA IE * @mac_ctx: Global MAC context * @bssid: BSSID - * @target_channel: Channel on which to send the IE + * @target_chan_freq: Channel frequency on which to send the IE * @csa_ie_reqd: Include/Exclude CSA IE. * @ch_params: operating Channel related information * @@ -22304,7 +21145,7 @@ QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t session_id) **/ QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx, struct qdf_mac_addr bssid, - uint8_t target_channel, + uint32_t target_chan_freq, uint8_t csa_ie_reqd, struct ch_params *ch_params) { @@ -22318,7 +21159,7 @@ QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx, msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ; msg->msgLen = sizeof(tSirDfsCsaIeRequest); - msg->targetChannel = target_channel; + msg->target_chan_freq = target_chan_freq; msg->csaIeRequired = csa_ie_reqd; msg->ch_switch_beacon_cnt = mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt; @@ -22399,17 +21240,12 @@ void csr_roaming_report_diag_event(struct mac_context *mac_ctx, #endif #ifdef WLAN_FEATURE_ROAM_OFFLOAD -/* - * fn csr_process_ho_fail_ind - * brief This function will process the Hand Off Failure indication - * received from the firmware. It will trigger a disconnect on - * the session which the firmware reported a hand off failure - * param mac global structure - * param msg_buf - Contains the session ID for which the handler should apply - */ void csr_process_ho_fail_ind(struct mac_context *mac_ctx, void *msg_buf) { struct handoff_failure_ind *pSmeHOFailInd = msg_buf; + struct mlme_roam_after_data_stall *vdev_roam_params; + struct wlan_objmgr_vdev *vdev; + struct reject_ap_info ap_info; uint32_t sessionId; if (!pSmeHOFailInd) { @@ -22418,6 +21254,12 @@ void csr_process_ho_fail_ind(struct mac_context *mac_ctx, void *msg_buf) } sessionId = pSmeHOFailInd->vdev_id; + ap_info.bssid = pSmeHOFailInd->bssid; + ap_info.reject_ap_type = DRIVER_AVOID_TYPE; + ap_info.reject_reason = REASON_ROAM_HO_FAILURE; + ap_info.source = ADDED_BY_DRIVER; + wlan_blm_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info); + /* Roaming is supported only on Infra STA Mode. */ if (!csr_roam_is_sta_mode(mac_ctx, sessionId)) { @@ -22425,6 +21267,22 @@ void csr_process_ho_fail_ind(struct mac_context *mac_ctx, void *msg_buf) sessionId); return; } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, sessionId, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("LFR3: vdev is NULL"); + return; + } + + vdev_roam_params = mlme_get_roam_invoke_params(vdev); + if (vdev_roam_params) + vdev_roam_params->roam_invoke_in_progress = false; + else + sme_err("LFR3: Vdev roam params is NULL"); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + mac_ctx->sme.set_connection_info_cb(false); csr_roam_roaming_offload_timer_action(mac_ctx, 0, sessionId, ROAMING_OFFLOAD_TIMER_STOP); @@ -22464,31 +21322,27 @@ csr_update_op_class_array(struct mac_context *mac_ctx, uint8_t j = 0, idx = 0, class = 0; bool found = false; uint8_t num_channels = channel_info->numChannels; - uint8_t ch_bandwidth; + uint8_t ch_num; sme_debug("Num %s channels, %d", ch_name, num_channels); for (idx = 0; idx < num_channels && - *i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) { - for (ch_bandwidth = BW20; ch_bandwidth < BWALL; - ch_bandwidth++) { - class = wlan_reg_dmn_get_opclass_from_channel( - mac_ctx->scan.countryCodeCurrent, - channel_info->channelList[idx], - ch_bandwidth); - found = false; - for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; - j++) { - if (op_classes[j] == class) { - found = true; - break; - } + *i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) { + wlan_reg_freq_to_chan_op_class( + mac_ctx->pdev, channel_info->channel_freq_list[idx], + true, BIT(BEHAV_NONE), &class, &ch_num); + + found = false; + for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; j++) { + if (op_classes[j] == class) { + found = true; + break; } + } - if (!found) { - op_classes[*i] = class; - *i = *i + 1; - } + if (!found) { + op_classes[*i] = class; + *i = *i + 1; } } } @@ -22575,12 +21429,13 @@ csr_find_session_by_type(struct mac_context *mac_ctx, enum QDF_OPMODE type) * * Return: true or false. **/ -static bool csr_is_conn_allow_2g_band(struct mac_context *mac_ctx, uint32_t chnl) +static bool csr_is_conn_allow_2g_band(struct mac_context *mac_ctx, + uint32_t ch_freq) { uint32_t sap_session_id; struct csr_roam_session *sap_session; - if (0 == chnl) { + if (0 == ch_freq) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, FL("channel is zero, connection not allowed")); @@ -22590,14 +21445,8 @@ static bool csr_is_conn_allow_2g_band(struct mac_context *mac_ctx, uint32_t chnl sap_session_id = csr_find_session_by_type(mac_ctx, QDF_SAP_MODE); if (WLAN_UMAC_VDEV_ID_MAX != sap_session_id) { sap_session = CSR_GET_SESSION(mac_ctx, sap_session_id); - if (!sap_session) { - sme_err("Session_id invalid %d", sap_session_id); - return false; - } - - if ((0 != sap_session->bssParams.operationChn) && - (sap_session->bssParams.operationChn != chnl)) { - + if (0 != sap_session->bssParams.operation_chan_freq && + sap_session->bssParams.operation_chan_freq != ch_freq) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "Can't allow STA to connect, chnls not same"); return false; @@ -22619,12 +21468,13 @@ static bool csr_is_conn_allow_2g_band(struct mac_context *mac_ctx, uint32_t chnl * * Return: true or false. **/ -static bool csr_is_conn_allow_5g_band(struct mac_context *mac_ctx, uint32_t chnl) +static bool csr_is_conn_allow_5g_band(struct mac_context *mac_ctx, + uint32_t ch_freq) { uint32_t p2pgo_session_id; struct csr_roam_session *p2pgo_session; - if (0 == chnl) { + if (0 == ch_freq) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, FL("channel is zero, connection not allowed")); return false; @@ -22633,17 +21483,10 @@ static bool csr_is_conn_allow_5g_band(struct mac_context *mac_ctx, uint32_t chnl p2pgo_session_id = csr_find_session_by_type(mac_ctx, QDF_P2P_GO_MODE); if (WLAN_UMAC_VDEV_ID_MAX != p2pgo_session_id) { p2pgo_session = CSR_GET_SESSION(mac_ctx, p2pgo_session_id); - if (!p2pgo_session) { - sme_err("Session_id invalid %d", p2pgo_session_id); - return false; - } - - if ((0 != p2pgo_session->bssParams.operationChn) && - (eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED != - p2pgo_session->connectState) && - (p2pgo_session->bssParams.operationChn != - chnl)) { - + if (0 != p2pgo_session->bssParams.operation_chan_freq && + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED != + p2pgo_session->connectState && + p2pgo_session->bssParams.operation_chan_freq != ch_freq) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "Can't allow STA to connect, chnls not same"); return false; @@ -22938,11 +21781,11 @@ void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command) struct csr_roam_session *session; - if (!CSR_IS_SESSION_VALID(mac, command->sessionId)) { - sme_err("Invalid session id %d", command->sessionId); + if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) { + sme_err("Invalid session id %d", command->vdev_id); goto fail; } - session = CSR_GET_SESSION(mac, command->sessionId); + session = CSR_GET_SESSION(mac, command->vdev_id); len = sizeof(*msg); msg = qdf_mem_malloc(len); @@ -22956,6 +21799,7 @@ void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command) msg->msgLen = sizeof(*msg); msg->new_nss = command->u.nss_update_cmd.new_nss; + msg->ch_width = command->u.nss_update_cmd.ch_width; msg->vdev_id = command->u.nss_update_cmd.session_id; sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE"); @@ -23049,6 +21893,135 @@ void csr_update_fils_erp_seq_num(struct csr_roam_profile *roam_profile, {} #endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle, + struct csr_roam_profile *profile, + const tSirMacAddr bssid, uint32_t ch_freq, + uint8_t vdev_id, const tSirMacAddr connected_bssid) +{ + QDF_STATUS status; + struct wma_roam_invoke_cmd *fastreassoc; + struct scheduler_msg msg = {0}; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct csr_roam_session *session; + struct wlan_objmgr_vdev *vdev; + struct mlme_roam_after_data_stall *vdev_roam_params; + bool roam_control_bitmap; + + session = CSR_GET_SESSION(mac_ctx, vdev_id); + if (!session) { + sme_err("session %d not found", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + if (!csr_is_conn_state_connected(mac_ctx, vdev_id)) { + sme_debug("Not in connected state, Roam Invoke not sent"); + return QDF_STATUS_E_FAILURE; + } + + roam_control_bitmap = mlme_get_operations_bitmap(mac_ctx->psoc, + vdev_id); + if (roam_control_bitmap || + !MLME_IS_ROAM_INITIALIZED(mac_ctx->psoc, vdev_id)) { + sme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]", + vdev_id, roam_control_bitmap); + return QDF_STATUS_E_FAILURE; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + + if (!vdev) { + sme_err("vdev is NULL, aborting roam invoke"); + return QDF_STATUS_E_NULL_VALUE; + } + + vdev_roam_params = mlme_get_roam_invoke_params(vdev); + + if (!vdev_roam_params) { + sme_err("Invalid vdev roam params, aborting roam invoke"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return QDF_STATUS_E_NULL_VALUE; + } + + if (vdev_roam_params->roam_invoke_in_progress) { + sme_debug("Roaming already initiated by %d source", + vdev_roam_params->source); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return QDF_STATUS_E_FAILURE; + } + + fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc)); + if (!fastreassoc) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return QDF_STATUS_E_NOMEM; + } + /* if both are same then set the flag */ + if (!qdf_mem_cmp(connected_bssid, bssid, ETH_ALEN)) + fastreassoc->is_same_bssid = true; + + fastreassoc->vdev_id = vdev_id; + fastreassoc->bssid[0] = bssid[0]; + fastreassoc->bssid[1] = bssid[1]; + fastreassoc->bssid[2] = bssid[2]; + fastreassoc->bssid[3] = bssid[3]; + fastreassoc->bssid[4] = bssid[4]; + fastreassoc->bssid[5] = bssid[5]; + + status = sme_get_beacon_frm(mac_handle, profile, bssid, + &fastreassoc->frame_buf, + &fastreassoc->frame_len, + &ch_freq); + + if (!ch_freq) { + sme_err("channel retrieval from BSS desc fails!"); + qdf_mem_free(fastreassoc->frame_buf); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + qdf_mem_free(fastreassoc); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return QDF_STATUS_E_FAULT; + } + + fastreassoc->ch_freq = ch_freq; + if (QDF_STATUS_SUCCESS != status) { + sme_warn("sme_get_beacon_frm failed"); + qdf_mem_free(fastreassoc->frame_buf); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + } + + if (csr_is_auth_type_ese(mac_ctx->roam.roamSession[vdev_id]. + connectedProfile.AuthType)) { + sme_debug("Beacon is not required for ESE"); + if (fastreassoc->frame_len) { + qdf_mem_free(fastreassoc->frame_buf); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + } + } + + msg.type = eWNI_SME_ROAM_INVOKE; + msg.reserved = 0; + msg.bodyptr = fastreassoc; + status = scheduler_post_message(QDF_MODULE_ID_SME, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Not able to post ROAM_INVOKE_CMD message to PE"); + qdf_mem_free(fastreassoc->frame_buf); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + qdf_mem_free(fastreassoc); + } else { + vdev_roam_params->roam_invoke_in_progress = true; + vdev_roam_params->source = USERSPACE_INITIATED; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + + return status; +} #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) /** * csr_is_sae_single_pmk_vsie_ap() - check if the Roamed AP supports sae @@ -23096,46 +22069,33 @@ static bool csr_is_sae_single_pmk_vsie_ap(struct bss_description *bss_des) static void csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, struct csr_roam_session *session, - uint8_t vdev_id, uint8_t *psk_pmk, - uint8_t pmk_len) + uint8_t vdev_id) { struct wlan_objmgr_vdev *vdev; struct mlme_pmk_info *pmk_info; - tPmkidCacheInfo *pmkid_cache, *roam_sync_pmksa; - uint32_t pmkid_index; + tPmkidCacheInfo *pmkid_cache; + uint32_t keymgmt; bool val, lookup_success; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, WLAN_LEGACY_SME_ID); if (!vdev) { - sme_err("get vdev failed"); + mlme_err("get vdev failed"); return; } - if (session->connectedProfile.AuthType == eCSR_AUTH_TYPE_SAE) { + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + + if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) { val = csr_is_sae_single_pmk_vsie_ap(session->pConnectBssDesc); wlan_mlme_set_sae_single_pmk_bss_cap(mac_ctx->psoc, vdev_id, val); if (!val) goto end; - roam_sync_pmksa = qdf_mem_malloc(sizeof(*roam_sync_pmksa)); - if (roam_sync_pmksa) { - qdf_copy_macaddr(&roam_sync_pmksa->BSSID, - (struct qdf_mac_addr *) - &session->pConnectBssDesc->bssId); - roam_sync_pmksa->single_pmk_supported = true; - roam_sync_pmksa->pmk_len = pmk_len; - qdf_mem_copy(roam_sync_pmksa->pmk, psk_pmk, - roam_sync_pmksa->pmk_len); - /* update single pmk info for roamed ap to pmk table */ - csr_set_sae_single_pmk_info(session, - roam_sync_pmksa); - qdf_mem_zero(roam_sync_pmksa, sizeof(*roam_sync_pmksa)); - qdf_mem_free(roam_sync_pmksa); - } else { - goto end; - } + wlan_crypto_set_sae_single_pmk_bss_cap(vdev, + (struct qdf_mac_addr *)session->pConnectBssDesc->bssId, + true); pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); if (!pmkid_cache) @@ -23151,30 +22111,24 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, * single pmk entries. */ lookup_success = csr_lookup_pmkid_using_bssid(mac_ctx, session, - pmkid_cache, - &pmkid_index); + pmkid_cache); + qdf_mem_free(pmkid_cache); if (lookup_success) { - csr_clear_other_bss_sae_single_pmk_entry( - mac_ctx, - &session->connectedProfile.bssid, vdev_id); + wlan_crypto_selective_clear_sae_single_pmk_entries(vdev, + &session->connectedProfile.bssid); pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); - if (!pmk_info) { - qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); - qdf_mem_free(pmkid_cache); + if (!pmk_info) goto end; - } - qdf_mem_copy(pmk_info->pmk, pmkid_cache->pmk, + qdf_mem_copy(pmk_info->pmk, session->psk_pmk, session->pmk_len); - pmk_info->pmk_len = pmkid_cache->pmk_len; + pmk_info->pmk_len = session->pmk_len; wlan_mlme_update_sae_single_pmk(vdev, pmk_info); qdf_mem_zero(pmk_info, sizeof(*pmk_info)); qdf_mem_free(pmk_info); } - qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); - qdf_mem_free(pmkid_cache); } end: @@ -23184,13 +22138,14 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, static inline void csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx, struct csr_roam_session *session, - uint8_t vdev_id, uint8_t *psk_pmk, - uint8_t pmk_len) + uint8_t vdev_id) { } #endif -#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define IS_ROAM_REASON_STA_KICKOUT(reason) ((reason & 0xF) == \ + WMI_ROAM_TRIGGER_REASON_STA_KICKOUT) + static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, struct roam_offload_synch_ind *roam_synch_data, struct bss_description *bss_desc, enum sir_roam_op_code reason) @@ -23202,10 +22157,9 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, struct csr_roam_info *roam_info; tCsrRoamConnectedProfile *conn_profile = NULL; sme_QosAssocInfo assoc_info; - tpAddBssParams add_bss_params; + struct bss_params *add_bss_params; QDF_STATUS status = QDF_STATUS_SUCCESS; tPmkidCacheInfo *pmkid_cache; - uint32_t pmkid_index; uint16_t len; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH struct ht_profile *src_profile = NULL; @@ -23213,12 +22167,10 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, #endif struct wlan_objmgr_vdev *vdev; struct mlme_roam_after_data_stall *vdev_roam_params; - uint32_t chan_id; - struct wlan_crypto_pmksa *pmksa; - enum csr_akm_type akm_type; - uint8_t mdie_present; bool abort_host_scan_cap = false; wlan_scan_id scan_id; + struct wlan_crypto_pmksa *pmksa; + uint8_t ssid_offset; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id, WLAN_LEGACY_SME_ID); @@ -23313,13 +22265,14 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, case SIR_ROAMING_INVOKE_FAIL: sme_debug("Roaming triggered failed source %d nud behaviour %d", vdev_roam_params->source, mac_ctx->nud_fail_behaviour); + + /* Userspace roam req fail, disconnect with AP */ if (vdev_roam_params->source == USERSPACE_INITIATED || - mac_ctx->nud_fail_behaviour == DISCONNECT_AFTER_ROAM_FAIL) { - /* Userspace roam req fail, disconnect with AP */ + mac_ctx->nud_fail_behaviour == DISCONNECT_AFTER_ROAM_FAIL) csr_roam_disconnect(mac_ctx, session_id, - eCSR_DISCONNECT_REASON_DEAUTH, - eSIR_MAC_USER_TRIGGERED_ROAM_FAILURE); - } + eCSR_DISCONNECT_REASON_DEAUTH, + eSIR_MAC_USER_TRIGGERED_ROAM_FAILURE); + vdev_roam_params->roam_invoke_in_progress = false; goto end; case SIR_ROAM_SYNCH_PROPAGATION: @@ -23332,9 +22285,8 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, * roam sync to make sure the new AP is on 2G, or disconnect * the AP. */ - chan_id = wlan_reg_freq_to_chan(mac_ctx->pdev, - roam_synch_data->chan_freq); - if (wlan_reg_is_disable_ch(mac_ctx->pdev, chan_id)) { + if (wlan_reg_is_disable_for_freq(mac_ctx->pdev, + roam_synch_data->chan_freq)) { csr_roam_disconnect(mac_ctx, session_id, eCSR_DISCONNECT_REASON_DEAUTH, eSIR_MAC_OPER_CHANNEL_BAND_CHANGE); @@ -23363,21 +22315,13 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, mac_ctx->sme.set_connection_info_cb(false); session->roam_synch_in_progress = false; - if (ucfg_pkt_capture_get_pktcap_mode()) - ucfg_pkt_capture_record_channel(vdev); - - if (roam_synch_data->pmk_len) { - csr_check_and_set_sae_single_pmk_cap( - mac_ctx, session, - session_id, - roam_synch_data->pmk, - roam_synch_data->pmk_len); - } + csr_check_and_set_sae_single_pmk_cap(mac_ctx, session, + session_id); - if (WLAN_REG_IS_5GHZ_CH(bss_desc->channelId)) { + if (WLAN_REG_IS_5GHZ_CH_FREQ(bss_desc->chan_freq)) { session->disable_hi_rssi = true; - sme_debug("Disabling HI_RSSI, AP channel=%d, rssi=%d", - bss_desc->channelId, bss_desc->rssi); + sme_debug("Disabling HI_RSSI, AP freq=%d, rssi=%d", + bss_desc->chan_freq, bss_desc->rssi); } else { session->disable_hi_rssi = false; } @@ -23422,6 +22366,16 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, session->connectedProfile.bssid, BLM_AP_DISCONNECTED); + if (IS_ROAM_REASON_STA_KICKOUT(roam_synch_data->roamReason)) { + struct reject_ap_info ap_info; + + ap_info.bssid = session->connectedProfile.bssid; + ap_info.reject_ap_type = DRIVER_AVOID_TYPE; + ap_info.reject_reason = REASON_STA_KICKOUT; + ap_info.source = ADDED_BY_DRIVER; + wlan_blm_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info); + } + /* Remove old BSSID mlme info from scan cache */ csr_update_scan_entry_associnfo(mac_ctx, session, SCAN_ENTRY_CON_STATE_NONE); @@ -23464,21 +22418,12 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, * All other authentications - Host supplicant performs EAPOL * with AP after this point and sends new keys to the driver. * Driver starts wait_for_key timer for that purpose. - * Allow csr_lookup_pmkid_using_bssid() if akm is SAE/OWE since - * SAE/OWE roaming uses hybrid model and eapol is offloaded to - * supplicant unlike in WPA2 – 802.1x case, after 8 way handshake - * the __wlan_hdd_cfg80211_keymgmt_set_key ->sme_roam_set_psk_pmk() - * will get called after roam synch complete to update the - * session->psk_pmk, but in SAE/OWE roaming this sequence is not - * present and set_pmksa will come before roam synch indication & - * eapol. So the session->psk_pmk will be stale in PMKSA cached - * SAE/OWE roaming case. */ - if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED || - session->pCurRoamProfile->negotiatedAuthType == - eCSR_AUTH_TYPE_SAE || - session->pCurRoamProfile->negotiatedAuthType == - eCSR_AUTH_TYPE_OWE) { + if (roam_synch_data->authStatus + == CSR_ROAM_AUTH_STATUS_AUTHENTICATED) { + QDF_TRACE(QDF_MODULE_ID_SME, + QDF_TRACE_LEVEL_DEBUG, + FL("LFR3:Don't start waitforkey timer")); csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, session_id); /* @@ -23498,48 +22443,25 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, status = QDF_STATUS_E_NOMEM; goto end; } + qdf_copy_macaddr(&pmkid_cache->BSSID, &session->connectedProfile.bssid); - sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_STR - " AKM Type:%d", - QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes), - session->pCurRoamProfile->negotiatedAuthType); - akm_type = session->connectedProfile.AuthType; - mdie_present = session->connectedProfile.mdid.mdie_present; - + sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes)); if (csr_lookup_pmkid_using_bssid(mac_ctx, session, - pmkid_cache, - &pmkid_index)) { + pmkid_cache)) { session->pmk_len = pmkid_cache->pmk_len; qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk)); qdf_mem_copy(session->psk_pmk, pmkid_cache->pmk, session->pmk_len); - sme_debug("pmkid found for " QDF_MAC_ADDR_STR " at %d len %d", - QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes), - pmkid_index, (uint32_t)session->pmk_len); + sme_debug("pmkid found for " QDF_MAC_ADDR_FMT " len %d", + QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes), + (uint32_t)session->pmk_len); } else { - sme_debug("PMKID Not found in cache for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes)); - /* - * In FT roam when the CSR lookup fails then the PMK - * details from the roam sync indication will be updated - * to Session/PMK cache. This will result in having - * multiple PMK cache entries for the same MDID, So do - * not add the PMKSA cache entry for all FT-Roam. - */ - if (!csr_is_auth_type11r(mac_ctx, akm_type, - mdie_present) && - roam_synch_data->pmk_len) { - qdf_mem_copy(pmkid_cache->PMKID, - roam_synch_data->pmkid, PMKID_LEN); - qdf_mem_copy(pmkid_cache->pmk, - roam_synch_data->pmk, - roam_synch_data->pmk_len); - pmkid_cache->pmk_len = roam_synch_data->pmk_len; - - csr_update_pmk_cache(session, pmkid_cache); - + sme_debug("PMKID Not found in cache for " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pmkid_cache->BSSID.bytes)); + if (roam_synch_data->pmk_len) { pmksa = qdf_mem_malloc(sizeof(*pmksa)); if (!pmksa) { status = QDF_STATUS_E_NOMEM; @@ -23569,7 +22491,7 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, } } } - qdf_mem_zero(pmkid_cache, sizeof(*pmkid_cache)); + qdf_mem_zero(pmkid_cache, sizeof(pmkid_cache)); qdf_mem_free(pmkid_cache); } else { roam_info->fAuthRequired = true; @@ -23590,9 +22512,16 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, csr_neighbor_roam_state_transition(mac_ctx, eCSR_NEIGHBOR_ROAM_STATE_INIT, session_id); } + + if (roam_synch_data->is_ft_im_roam) { + ssid_offset = SIR_MAC_ASSOC_REQ_SSID_OFFSET; + } else { + ssid_offset = SIR_MAC_REASSOC_REQ_SSID_OFFSET; + } + roam_info->nBeaconLength = 0; roam_info->nAssocReqLength = roam_synch_data->reassoc_req_length - - SIR_MAC_HDR_LEN_3A - SIR_MAC_REASSOC_SSID_OFFSET; + SIR_MAC_HDR_LEN_3A - ssid_offset; roam_info->nAssocRspLength = roam_synch_data->reassocRespLength - SIR_MAC_HDR_LEN_3A; roam_info->pbFrames = qdf_mem_malloc(roam_info->nBeaconLength + @@ -23608,8 +22537,9 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, qdf_mem_copy(roam_info->pbFrames, (uint8_t *)roam_synch_data + roam_synch_data->reassoc_req_offset + - SIR_MAC_HDR_LEN_3A + SIR_MAC_REASSOC_SSID_OFFSET, + SIR_MAC_HDR_LEN_3A + ssid_offset, roam_info->nAssocReqLength); + qdf_mem_copy(roam_info->pbFrames + roam_info->nAssocReqLength, (uint8_t *)roam_synch_data + roam_synch_data->reassocRespOffset + @@ -23650,8 +22580,7 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, } conn_profile->vht_channel_width = roam_synch_data->join_rsp->vht_channel_width; - add_bss_params = (tpAddBssParams)roam_synch_data->add_bss_params; - session->connectedInfo.staId = add_bss_params->staContext.staIdx; + add_bss_params = (struct bss_params *)roam_synch_data->add_bss_params; roam_info->staId = session->connectedInfo.staId; roam_info->timingMeasCap = roam_synch_data->join_rsp->timingMeasCap; @@ -23805,10 +22734,21 @@ csr_roam_synch_callback(struct mac_context *mac_ctx, return status; } -QDF_STATUS -csr_process_roam_auth_offload_callback(struct mac_context *mac_ctx, - uint8_t vdev_id, - struct qdf_mac_addr roam_bssid) +#ifdef WLAN_FEATURE_SAE +/** + * csr_process_roam_auth_sae_callback() - API to trigger the + * WPA3 pre-auth event for candidate AP received from firmware. + * @mac_ctx: Global mac context pointer + * @vdev_id: vdev id + * @roam_bssid: Candidate BSSID to roam + * + * This function calls the hdd_sme_roam_callback with reason + * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant. + */ +static QDF_STATUS +csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, + uint8_t vdev_id, + struct qdf_mac_addr roam_bssid) { struct csr_roam_info *roam_info; struct sir_sae_info sae_info; @@ -23843,6 +22783,15 @@ csr_process_roam_auth_offload_callback(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } +#else +static inline QDF_STATUS +csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, + uint8_t vdev_id, + struct qdf_mac_addr roam_bssid) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif QDF_STATUS csr_roam_auth_offload_callback(struct mac_context *mac_ctx, @@ -23854,7 +22803,7 @@ csr_roam_auth_offload_callback(struct mac_context *mac_ctx, if (!QDF_IS_STATUS_SUCCESS(status)) return status; - status = csr_process_roam_auth_offload_callback(mac_ctx, vdev_id, bssid); + status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id, bssid); sme_release_global_lock(&mac_ctx->sme); @@ -23943,7 +22892,7 @@ csr_roam_update_cfg(struct mac_context *mac, uint8_t vdev_id, uint8_t reason) QDF_STATUS csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id) { - uint8_t op_ch[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint32_t sta_vdev_id = WLAN_INVALID_VDEV_ID; struct csr_roam_session *session; @@ -23954,7 +22903,8 @@ csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id) if (sta_vdev_id != WLAN_UMAC_VDEV_ID_MAX) return QDF_STATUS_E_FAILURE; - count = policy_mgr_get_mode_specific_conn_info(mac->psoc, op_ch, + count = policy_mgr_get_mode_specific_conn_info(mac->psoc, + op_ch_freq_list, vdev_id_list, PM_STA_MODE); @@ -23984,35 +22934,3 @@ csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id) return csr_post_roam_state_change(mac, sta_vdev_id, ROAM_RSO_STARTED, REASON_CTX_INIT); } - -#ifdef FEATURE_MONITOR_MODE_SUPPORT - -void csr_monitor_mode_register_callback(struct csr_roam_session *session, - struct sme_session_params *session_param) -{ - if (session_param->session_monitor_mode_cb) - session->session_monitor_mode_cb = - session_param->session_monitor_mode_cb; -} - -QDF_STATUS csr_process_monitor_mode_vdev_up_evt(struct mac_context *mac, - uint8_t vdev_id) -{ - struct csr_roam_session *session; - - if (!CSR_IS_SESSION_VALID(mac, vdev_id)) { - sme_err("vdev ID: %d is not valid", vdev_id); - return QDF_STATUS_E_FAILURE; - } - - session = CSR_GET_SESSION(mac, vdev_id); - if (session->session_monitor_mode_cb) - session->session_monitor_mode_cb(vdev_id); - else { - sme_warn_rl("session_monitor_mode_cb is not registered"); - return QDF_STATUS_E_FAILURE; - } - - return QDF_STATUS_SUCCESS; -} -#endif diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_scan.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_scan.c index 3499ca911e516c60d77f6ff86545c04bf1e6116c..6155600df38359c0f81b6d5edcbe15df38c972f9 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_scan.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_scan.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -51,14 +51,16 @@ #include "wlan_reg_services_api.h" #include "sch_api.h" #include "wlan_blm_api.h" +#include "qdf_crypto.h" +#include static void csr_set_cfg_valid_channel_list(struct mac_context *mac, - uint8_t *pChannelList, + uint32_t *pchan_freq_list, uint8_t NumChannels); static void csr_save_tx_power_to_cfg(struct mac_context *mac, tDblLinkList *pList, - enum band_info band); + uint32_t cfgId); static void csr_set_cfg_country_code(struct mac_context *mac, uint8_t *countryCode); @@ -66,7 +68,8 @@ static void csr_set_cfg_country_code(struct mac_context *mac, static void csr_purge_channel_power(struct mac_context *mac, tDblLinkList *pChannelList); -static bool csr_roam_is_valid_channel(struct mac_context *mac, uint8_t channel); +static bool csr_roam_is_valid_channel(struct mac_context *mac, + uint32_t ch_freq); /* pResult is invalid calling this function. */ void csr_free_scan_result_entry(struct mac_context *mac, @@ -118,7 +121,7 @@ QDF_STATUS csr_scan_handle_search_for_ssid(struct mac_context *mac_ctx, { QDF_STATUS status = QDF_STATUS_E_FAILURE; tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE; - tCsrScanResultFilter *pScanFilter = NULL; + struct scan_filter *filter; struct csr_roam_profile *profile; struct csr_roam_session *session; @@ -152,16 +155,19 @@ QDF_STATUS csr_scan_handle_search_for_ssid(struct mac_context *mac_ctx, } if (!profile) break; - pScanFilter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); - if (!pScanFilter) { + filter = qdf_mem_malloc(sizeof(*filter)); + if (!filter) { status = QDF_STATUS_E_NOMEM; break; } - status = csr_roam_prepare_filter_from_profile(mac_ctx, profile, - pScanFilter); - if (!QDF_IS_STATUS_SUCCESS(status)) + status = csr_roam_get_scan_filter_from_profile(mac_ctx, profile, + filter, false); + if (!QDF_IS_STATUS_SUCCESS(status)) { + qdf_mem_free(filter); break; - status = csr_scan_get_result(mac_ctx, pScanFilter, &hBSSList); + } + status = csr_scan_get_result(mac_ctx, filter, &hBSSList); + qdf_mem_free(filter); if (!QDF_IS_STATUS_SUCCESS(status)) break; if (mac_ctx->roam.roamSession[session_id].connectState == @@ -187,10 +193,7 @@ QDF_STATUS csr_scan_handle_search_for_ssid(struct mac_context *mac_ctx, eCSR_ROAM_ASSOCIATION_FAILURE, eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE); } - if (pScanFilter) { - csr_free_scan_filter(mac_ctx, pScanFilter); - qdf_mem_free(pScanFilter); - } + return status; } @@ -335,24 +338,24 @@ QDF_STATUS csr_scan_result_purge(struct mac_context *mac, /* Add the channel to the occupiedChannels array */ static void csr_add_to_occupied_channels(struct mac_context *mac, - uint8_t ch, + uint32_t ch_freq, uint8_t sessionId, struct csr_channel *occupied_ch, bool is_init_list) { QDF_STATUS status; uint8_t num_occupied_ch = occupied_ch->numChannels; - uint8_t *occupied_ch_lst = occupied_ch->channelList; + uint32_t *occupied_ch_lst = occupied_ch->channel_freq_list; if (is_init_list) mac->scan.roam_candidate_count[sessionId]++; if (csr_is_channel_present_in_list(occupied_ch_lst, - num_occupied_ch, ch)) + num_occupied_ch, ch_freq)) return; status = csr_add_to_channel_list_front(occupied_ch_lst, - num_occupied_ch, ch); + num_occupied_ch, ch_freq); if (QDF_IS_STATUS_SUCCESS(status)) { occupied_ch->numChannels++; if (occupied_ch->numChannels > @@ -386,7 +389,7 @@ static void csr_scan_add_result(struct mac_context *mac_ctx, frm_type = MGMT_PROBE_RESP; rx_param.pdev_id = 0; - rx_param.channel = bss_desc->channelId; + rx_param.chan_freq = bss_desc->chan_freq; rx_param.rssi = bss_desc->rssi; rx_param.tsf_delta = bss_desc->tsf_delta; @@ -448,9 +451,9 @@ csr_scan_save_bss_description(struct mac_context *mac, pCsrBssDescription->AgingCount = (int32_t) mac->roam.configParam.agingCount; sme_debug( - "Set Aging Count = %d for BSS " QDF_MAC_ADDR_STR " ", + "Set Aging Count = %d for BSS " QDF_MAC_ADDR_FMT " ", pCsrBssDescription->AgingCount, - QDF_MAC_ADDR_ARRAY(pCsrBssDescription->Result.BssDescriptor. + QDF_MAC_ADDR_REF(pCsrBssDescription->Result.BssDescriptor. bssId)); qdf_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc); @@ -511,27 +514,25 @@ QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac, pChannelInfo++; continue; } - pChannelSet->firstChannel = pChannelInfo->firstChanNum; + pChannelSet->first_chan_freq = pChannelInfo->first_freq; pChannelSet->numChannels = pChannelInfo->numChannels; /* * Now set the inter-channel offset based on the frequency band * the channel set lies in */ - if ((WLAN_REG_IS_24GHZ_CH(pChannelSet->firstChannel)) && - ((pChannelSet->firstChannel + - (pChannelSet->numChannels - 1)) <= - WLAN_REG_MAX_24GHZ_CH_NUM)) { - pChannelSet->interChannelOffset = 1; + if (WLAN_REG_IS_24GHZ_CH_FREQ(pChannelSet->first_chan_freq) && + (pChannelSet->first_chan_freq + 5 * (pChannelSet->numChannels - 1) <= + WLAN_REG_MAX_24GHZ_CHAN_FREQ)) { + pChannelSet->interChannelOffset = 5; f2GHzInfoFound = true; - } else if ((WLAN_REG_IS_5GHZ_CH(pChannelSet->firstChannel)) - && ((pChannelSet->firstChannel + - ((pChannelSet->numChannels - 1) * 4)) <= - WLAN_REG_MAX_5GHZ_CH_NUM)) { - pChannelSet->interChannelOffset = 4; + } else if (WLAN_REG_IS_5GHZ_CH_FREQ(pChannelSet->first_chan_freq) && + (pChannelSet->first_chan_freq + 20 * (pChannelSet->numChannels - 1) <= + WLAN_REG_MAX_5GHZ_CHAN_FREQ)) { + pChannelSet->interChannelOffset = 20; f2GHzInfoFound = false; } else { - sme_warn("Invalid Channel %d Present in Country IE", - pChannelSet->firstChannel); + sme_warn("Invalid Channel freq %d Present in Country IE", + pChannelSet->first_chan_freq); qdf_mem_free(pChannelSet); return QDF_STATUS_E_FAILURE; } @@ -553,8 +554,8 @@ QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac, LL_ACCESS_LOCK); } else { sme_debug( - "Adding 11B/G ch in 11A. 1st ch %d", - pChannelSet->firstChannel); + "Adding 11B/G ch in 11A. 1st ch freq %d", + pChannelSet->first_chan_freq); qdf_mem_free(pChannelSet); } } else { @@ -574,8 +575,8 @@ QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac, LL_ACCESS_LOCK); } else { sme_debug( - "Adding 11A ch in B/G. 1st ch %d", - pChannelSet->firstChannel); + "Adding 11A ch in B/G. 1st ch freq %d", + pChannelSet->first_chan_freq); qdf_mem_free(pChannelSet); } } @@ -606,13 +607,13 @@ void csr_apply_channel_power_info_to_fw(struct mac_context *mac_ctx, tempNumChannels = QDF_MIN(ch_lst->numChannels, CFG_VALID_CHANNEL_LIST_LEN); for (i = 0; i < tempNumChannels; i++) { - tmp_ch_lst.channelList[num_ch] = ch_lst->channelList[i]; + tmp_ch_lst.channel_freq_list[num_ch] = ch_lst->channel_freq_list[i]; num_ch++; } tmp_ch_lst.numChannels = num_ch; /* Store the channel+power info in the global place: Cfg */ csr_apply_power2_current(mac_ctx); - csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channelList, + csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channel_freq_list, tmp_ch_lst.numChannels); } else { sme_err("11D channel list is empty"); @@ -636,22 +637,17 @@ static void csr_diag_reset_country_information(struct mac_context *mac) qdf_mem_copy(p11dLog->countryCode, mac->scan.countryCodeCurrent, 3); p11dLog->numChannel = mac->scan.base_channels.numChannels; if (p11dLog->numChannel <= HOST_LOG_MAX_NUM_CHANNEL) { - qdf_mem_copy(p11dLog->Channels, - mac->scan.base_channels.channelList, - p11dLog->numChannel); for (Index = 0; Index < mac->scan.base_channels.numChannels; Index++) { + p11dLog->Channels[Index] = + wlan_reg_freq_to_chan(mac->pdev, mac->scan.base_channels.channel_freq_list[Index]); p11dLog->TxPwr[Index] = QDF_MIN( mac->scan.defaultPowerTable[Index].tx_power, mac->mlme_cfg->power.max_tx_power); } } - if (!mac->mlme_cfg->gen.enabled_11d) - p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED; - else - p11dLog->supportMultipleDomain = - WLAN_80211D_SUPPORT_MULTI_DOMAIN; + WLAN_HOST_DIAG_LOG_REPORT(p11dLog); } #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ @@ -702,8 +698,10 @@ static void csr_get_channel_power_info(struct mac_context *mac, for (idx = 0; (idx < ch_set->numChannels) && (chn_idx < *num_ch); idx++) { chn_pwr_info[chn_idx].chan_num = - (uint8_t) (ch_set->firstChannel - + (idx * ch_set->interChannelOffset)); + (uint8_t)wlan_reg_freq_to_chan( + mac->pdev, + ch_set->first_chan_freq + + idx * ch_set->interChannelOffset); chn_pwr_info[chn_idx++].tx_power = ch_set->txPower; } entry = csr_ll_next(list, entry, LL_ACCESS_NOLOCK); @@ -717,6 +715,7 @@ static void csr_diag_apply_country_info(struct mac_context *mac_ctx) host_log_802_11d_pkt_type *p11dLog; struct channel_power chnPwrInfo[CFG_VALID_CHANNEL_LIST_LEN]; uint32_t nChnInfo = CFG_VALID_CHANNEL_LIST_LEN, nTmp; + uint8_t i; WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type, LOG_WLAN_80211D_C); @@ -729,9 +728,10 @@ static void csr_diag_apply_country_info(struct mac_context *mac_ctx) if (p11dLog->numChannel > HOST_LOG_MAX_NUM_CHANNEL) goto diag_end; - qdf_mem_copy(p11dLog->Channels, - mac_ctx->scan.channels11d.channelList, - p11dLog->numChannel); + for (i = 0; i < p11dLog->numChannel; i++) + p11dLog->Channels[i] = + wlan_reg_freq_to_chan(mac_ctx->pdev, + mac_ctx->scan.channels11d.channel_freq_list[i]); csr_get_channel_power_info(mac_ctx, &mac_ctx->scan.channelPowerInfoList24, &nChnInfo, chnPwrInfo); @@ -806,7 +806,7 @@ void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f) tSirMacChanInfo *ch_info_start; int32_t max_ch_idx; bool tmp_bool; - uint8_t ch = 0; + uint32_t ch_freq = 0; max_ch_idx = (mac->scan.base_channels.numChannels < @@ -821,9 +821,9 @@ void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f) ch_info_start = chan_info; for (idx = 0; idx < max_ch_idx; idx++) { - ch = mac->scan.defaultPowerTable[idx].chan_num; - tmp_bool = (fill_5f && WLAN_REG_IS_5GHZ_CH(ch)) || - (!fill_5f && WLAN_REG_IS_24GHZ_CH(ch)); + ch_freq = mac->scan.defaultPowerTable[idx].center_freq; + tmp_bool = (fill_5f && WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) || + (!fill_5f && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)); if (!tmp_bool) continue; @@ -832,8 +832,8 @@ void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f) break; } - chan_info->firstChanNum = - mac->scan.defaultPowerTable[idx].chan_num; + chan_info->first_freq = + mac->scan.defaultPowerTable[idx].center_freq; chan_info->numChannels = 1; chan_info->maxTxPower = QDF_MIN(mac->scan.defaultPowerTable[idx].tx_power, @@ -848,14 +848,13 @@ void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f) qdf_mem_free(ch_info_start); } -bool csr_is_supported_channel(struct mac_context *mac, uint8_t channelId) +bool csr_is_supported_channel(struct mac_context *mac, uint32_t chan_freq) { bool fRet = false; uint32_t i; for (i = 0; i < mac->scan.base_channels.numChannels; i++) { - if (channelId == - mac->scan.base_channels.channelList[i]) { + if (chan_freq == mac->scan.base_channels.channel_freq_list[i]) { fRet = true; break; } @@ -939,10 +938,10 @@ static enum csr_scancomplete_nextcommand csr_scan_get_next_command_state(struct mac_context *mac_ctx, uint32_t session_id, eCsrScanStatus scan_status, - uint8_t *chan) + uint32_t *chan_freq) { enum csr_scancomplete_nextcommand NextCommand = eCsrNextScanNothing; - int8_t channel; + uint32_t chan_freq_ret; struct csr_roam_session *session; if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { @@ -953,17 +952,17 @@ csr_scan_get_next_command_state(struct mac_context *mac_ctx, switch (session->scan_info.scan_reason) { case eCsrScanForSsid: sme_debug("Resp for Scan For Ssid"); - channel = csr_scan_get_channel_for_hw_mode_change( + chan_freq_ret = csr_scan_get_channel_for_hw_mode_change( mac_ctx, session_id, session->scan_info.profile); - if ((!channel) || scan_status) { + if ((!chan_freq_ret) && scan_status) { NextCommand = eCsrNexteScanForSsidFailure; sme_err("next Scan For Ssid Failure %d %d", - channel, scan_status); + chan_freq_ret, scan_status); } else { NextCommand = eCsrNextCheckAllowConc; - *chan = channel; + *chan_freq = chan_freq_ret; sme_debug("next CheckAllowConc"); } break; @@ -1155,7 +1154,7 @@ static QDF_STATUS csr_save_profile(struct mac_context *mac_ctx, static void csr_handle_nxt_cmd(struct mac_context *mac_ctx, enum csr_scancomplete_nextcommand nxt_cmd, uint32_t session_id, - uint8_t chan) + uint32_t chan_freq) { QDF_STATUS status, ret; struct csr_roam_session *session; @@ -1169,11 +1168,11 @@ static void csr_handle_nxt_cmd(struct mac_context *mac_ctx, csr_scan_handle_search_for_ssid_failure(mac_ctx, session_id); break; case eCsrNextCheckAllowConc: - ret = policy_mgr_current_connections_update(mac_ctx->psoc, - session_id, chan, - POLICY_MGR_UPDATE_REASON_HIDDEN_STA); - sme_debug("chan: %d session: %d status: %d", - chan, session_id, ret); + ret = policy_mgr_current_connections_update( + mac_ctx->psoc, session_id, chan_freq, + POLICY_MGR_UPDATE_REASON_HIDDEN_STA); + sme_debug("channel freq: %d session: %d status: %d", + chan_freq, session_id, ret); status = csr_save_profile(mac_ctx, session_id); if (!QDF_IS_STATUS_SUCCESS(status)) { @@ -1183,7 +1182,7 @@ static void csr_handle_nxt_cmd(struct mac_context *mac_ctx, } if (QDF_STATUS_E_FAILURE == ret) { - sme_debug("conn update fail %d", chan); + sme_debug("conn update fail %d", chan_freq); csr_scan_handle_search_for_ssid_failure(mac_ctx, session_id); } else if ((QDF_STATUS_E_NOSUPPORT == ret) || @@ -1212,7 +1211,7 @@ void csr_scan_callback(struct wlan_objmgr_vdev *vdev, struct mac_context *mac_ctx; struct csr_roam_session *session; uint32_t session_id = 0; - uint8_t chan = 0; + uint32_t chan_freq = 0; QDF_STATUS status; bool success = false; @@ -1255,10 +1254,10 @@ void csr_scan_callback(struct wlan_objmgr_vdev *vdev, #endif NextCommand = csr_scan_get_next_command_state(mac_ctx, session_id, scan_status, - &chan); + &chan_freq); /* We reuse the command here instead reissue a new command */ csr_handle_nxt_cmd(mac_ctx, NextCommand, - session_id, chan); + session_id, chan_freq); sme_release_global_lock(&mac_ctx->sme); } @@ -1333,7 +1332,7 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id, uint32_t num_ssid = profile->SSIDs.numOfSSIDs; struct scan_start_request *req; struct wlan_objmgr_vdev *vdev; - uint8_t i, chan, num_chan = 0; + uint8_t i, num_chan = 0; uint8_t pdev_id; wlan_scan_id scan_id; struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); @@ -1420,16 +1419,24 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id, if (profile->ChannelInfo.numOfChannels) { for (i = 0; i < profile->ChannelInfo.numOfChannels; i++) { if (csr_roam_is_valid_channel(mac_ctx, - profile->ChannelInfo.ChannelList[i])) { - chan = profile->ChannelInfo.ChannelList[i]; + profile->ChannelInfo.freq_list[i])) { req->scan_req.chan_list.chan[num_chan].freq = - wlan_chan_to_freq(chan); + profile->ChannelInfo.freq_list[i]; num_chan++; } } req->scan_req.chan_list.num_chan = num_chan; } + /* Add freq hint for scan for ssid */ + if (!num_chan && profile->freq_hint && + csr_roam_is_valid_channel(mac_ctx, profile->freq_hint)) { + sme_debug("add freq hint %d", profile->freq_hint); + req->scan_req.chan_list.chan[0].freq = + profile->freq_hint; + req->scan_req.chan_list.num_chan = 1; + } + /* Extend it for multiple SSID */ if (profile->SSIDs.numOfSSIDs) { if (profile->SSIDs.SSIDList[0].SSID.length > WLAN_SSID_MAX_LEN) { @@ -1464,18 +1471,21 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id, } static void csr_set_cfg_valid_channel_list(struct mac_context *mac, - uint8_t *pChannelList, + uint32_t *pchan_freq_list, uint8_t NumChannels) { QDF_STATUS status; + uint8_t i; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s: dump valid channel list(NumChannels(%d))", __func__, NumChannels); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - pChannelList, NumChannels); - qdf_mem_copy(mac->mlme_cfg->reg.valid_channel_list, pChannelList, - NumChannels); + pchan_freq_list, NumChannels); + for (i = 0; i < NumChannels; i++) { + mac->mlme_cfg->reg.valid_channel_freq_list[i] = pchan_freq_list[i]; + } + mac->mlme_cfg->reg.valid_channel_list_num = NumChannels; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -1522,7 +1532,7 @@ static void csr_save_tx_power_to_cfg(struct mac_context *mac, while (pEntry) { ch_set = GET_BASE_ADDR(pEntry, struct csr_channel_powerinfo, link); - if (1 != ch_set->interChannelOffset) { + if (ch_set->interChannelOffset != 5) { /* * we keep the 5G channel sets internally with an * interchannel offset of 4. Expand these to the right @@ -1537,17 +1547,16 @@ static void csr_save_tx_power_to_cfg(struct mac_context *mac, * allocation */ sme_err( - "Buffer overflow, start %d, num %d, offset %d", - ch_set->firstChannel, + "Buffer overflow, start freq %d, num %d, offset %d", + ch_set->first_chan_freq, ch_set->numChannels, ch_set->interChannelOffset); break; } for (idx = 0; idx < ch_set->numChannels; idx++) { - ch_pwr_set->firstChanNum = (tSirMacChanNum) - (ch_set->firstChannel + (idx * - ch_set->interChannelOffset)); + ch_pwr_set->first_freq = + ch_set->first_chan_freq; ch_pwr_set->numChannels = 1; ch_pwr_set->maxTxPower = QDF_MIN(ch_set->txPower, @@ -1560,13 +1569,13 @@ static void csr_save_tx_power_to_cfg(struct mac_context *mac, if (cbLen + sizeof(tSirMacChanInfo) >= dataLen) { /* this entry will overflow our allocation */ sme_err( - "Buffer overflow, start %d, num %d, offset %d", - ch_set->firstChannel, + "Buffer overflow, start freq %d, num %d, offset %d", + ch_set->first_chan_freq, ch_set->numChannels, ch_set->interChannelOffset); break; } - ch_pwr_set->firstChanNum = ch_set->firstChannel; + ch_pwr_set->first_freq = ch_set->first_chan_freq; ch_pwr_set->numChannels = ch_set->numChannels; ch_pwr_set->maxTxPower = QDF_MIN(ch_set->txPower, mac->mlme_cfg->power.max_tx_power); @@ -1578,13 +1587,23 @@ static void csr_save_tx_power_to_cfg(struct mac_context *mac, } csr_ll_unlock(pList); if (band == BAND_2G) { - mac->mlme_cfg->power.max_tx_power_24.len = 3 * count; + mac->mlme_cfg->power.max_tx_power_24.len = + sizeof(tSirMacChanInfo) * count; + if (mac->mlme_cfg->power.max_tx_power_24.len > + CFG_MAX_TX_POWER_2_4_LEN) + mac->mlme_cfg->power.max_tx_power_24.len = + CFG_MAX_TX_POWER_2_4_LEN; qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_24.data, (uint8_t *)p_buf, mac->mlme_cfg->power.max_tx_power_24.len); } if (band == BAND_5G) { - mac->mlme_cfg->power.max_tx_power_5.len = 3 * count; + mac->mlme_cfg->power.max_tx_power_5.len = + sizeof(tSirMacChanInfo) * count; + if (mac->mlme_cfg->power.max_tx_power_5.len > + CFG_MAX_TX_POWER_5_LEN) + mac->mlme_cfg->power.max_tx_power_5.len = + CFG_MAX_TX_POWER_5_LEN; qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_5.data, (uint8_t *)p_buf, mac->mlme_cfg->power.max_tx_power_5.len); @@ -1690,14 +1709,14 @@ QDF_STATUS csr_scan_abort_mac_scan(struct mac_context *mac_ctx, return status; } -bool csr_roam_is_valid_channel(struct mac_context *mac, uint8_t channel) +bool csr_roam_is_valid_channel(struct mac_context *mac, uint32_t ch_freq) { bool fValid = false; uint32_t idx_valid_ch; uint32_t len = mac->roam.numValidChannels; for (idx_valid_ch = 0; (idx_valid_ch < len); idx_valid_ch++) { - if (channel == mac->roam.validChannelList[idx_valid_ch]) { + if (ch_freq == mac->roam.valid_ch_freq_list[idx_valid_ch]) { fValid = true; break; } @@ -1708,7 +1727,7 @@ bool csr_roam_is_valid_channel(struct mac_context *mac, uint8_t channel) QDF_STATUS csr_scan_create_entry_in_scan_cache(struct mac_context *mac, uint32_t sessionId, struct qdf_mac_addr bssid, - uint8_t channel) + uint32_t ch_freq) { QDF_STATUS status = QDF_STATUS_SUCCESS; struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); @@ -1718,10 +1737,10 @@ QDF_STATUS csr_scan_create_entry_in_scan_cache(struct mac_context *mac, if (!pSession) { return QDF_STATUS_E_FAILURE; } - sme_debug("Current bssid::"QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId)); - sme_debug("My bssid::"QDF_MAC_ADDR_STR" channel %d", - QDF_MAC_ADDR_ARRAY(bssid.bytes), channel); + sme_debug("Current bssid::"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pSession->pConnectBssDesc->bssId)); + sme_debug("My bssid::"QDF_MAC_ADDR_FMT" ch_freq %d", + QDF_MAC_ADDR_REF(bssid.bytes), ch_freq); size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length); @@ -1730,14 +1749,14 @@ QDF_STATUS csr_scan_create_entry_in_scan_cache(struct mac_context *mac, return QDF_STATUS_E_FAILURE; } pNewBssDescriptor = qdf_mem_malloc(size); - if (pNewBssDescriptor) + if (!pNewBssDescriptor) return QDF_STATUS_E_FAILURE; qdf_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size); /* change the BSSID & channel as passed */ qdf_mem_copy(pNewBssDescriptor->bssId, bssid.bytes, sizeof(tSirMacAddr)); - pNewBssDescriptor->channelId = channel; + pNewBssDescriptor->chan_freq = ch_freq; if (!csr_scan_append_bss_description(mac, pNewBssDescriptor)) { sme_err("csr_scan_append_bss_description failed"); status = QDF_STATUS_E_FAILURE; @@ -1785,8 +1804,8 @@ csr_rso_save_ap_to_scan_cache(struct mac_context *mac, bss_desc_ptr, (sizeof(struct bss_description) + length)); - sme_debug("LFR3:Add BSSID to scan cache" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(scan_res_ptr->Result.BssDescriptor.bssId)); + sme_debug("LFR3:Add BSSID to scan cache" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(scan_res_ptr->Result.BssDescriptor.bssId)); csr_scan_add_result(mac, scan_res_ptr); csr_free_scan_result_entry(mac, scan_res_ptr); return QDF_STATUS_SUCCESS; @@ -1872,7 +1891,7 @@ csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle, return bss_descr; } -uint8_t +uint32_t csr_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, tScanResultHandle result_handle, uint32_t session_id) @@ -1881,7 +1900,7 @@ csr_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, struct tag_csrscan_result *scan_result = NULL; struct scan_result_list *bss_list = (struct scan_result_list *)result_handle; - uint8_t channel_id = 0; + uint32_t ch_freq = 0; if (!bss_list) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, @@ -1929,85 +1948,71 @@ csr_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, scan_result = GET_BASE_ADDR(next_element, struct tag_csrscan_result, Link); + ch_freq = scan_result->Result.BssDescriptor.chan_freq; if (policy_mgr_is_hw_dbs_required_for_band( mac_ctx->psoc, HW_MODE_MAC_BAND_2G)) { - if (WLAN_REG_IS_24GHZ_CH - (scan_result->Result.BssDescriptor.channelId)) { - channel_id = - scan_result-> - Result.BssDescriptor.channelId; + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) break; - } } else { - if (WLAN_REG_IS_24GHZ_CH - (scan_result->Result.BssDescriptor.channelId) && + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && policy_mgr_is_any_mode_active_on_band_along_with_session (mac_ctx->psoc, - session_id, POLICY_MGR_BAND_5)) { - channel_id = - scan_result-> - Result.BssDescriptor.channelId; + session_id, POLICY_MGR_BAND_5)) break; - } - if (WLAN_REG_IS_5GHZ_CH - (scan_result->Result.BssDescriptor.channelId) && + if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && policy_mgr_is_any_mode_active_on_band_along_with_session (mac_ctx->psoc, - session_id, POLICY_MGR_BAND_24)) { - channel_id = - scan_result-> - Result.BssDescriptor.channelId; + session_id, POLICY_MGR_BAND_24)) break; - } } next_element = csr_ll_next(&bss_list->List, next_element, LL_ACCESS_NOLOCK); } end: - return channel_id; + return ch_freq; } -uint8_t +uint32_t csr_scan_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, uint32_t session_id, struct csr_roam_profile *profile) { tScanResultHandle result_handle = NULL; QDF_STATUS status; - uint8_t first_ap_ch = 0; - uint8_t candidate_chan; + uint32_t first_ap_ch_freq = 0, candidate_ch_freq; status = sme_get_ap_channel_from_scan_cache(profile, &result_handle, - &first_ap_ch); - if (status != QDF_STATUS_SUCCESS || !result_handle || !first_ap_ch) { + &first_ap_ch_freq); + if (status != QDF_STATUS_SUCCESS || !result_handle || + !first_ap_ch_freq) { if (result_handle) sme_scan_result_purge(result_handle); sme_err("fail get scan result: status %d first ap ch %d", - status, first_ap_ch); + status, first_ap_ch_freq); return 0; } - if (!policy_mgr_check_for_session_conc(mac_ctx->psoc, session_id, - first_ap_ch)) { + if (!policy_mgr_check_for_session_conc( + mac_ctx->psoc, session_id, first_ap_ch_freq)) { sme_scan_result_purge(result_handle); sme_err("Conc not allowed for the session %d ch %d", - session_id, first_ap_ch); + session_id, first_ap_ch_freq); return 0; } - candidate_chan = csr_get_channel_for_hw_mode_change(mac_ctx, - result_handle, - session_id); + candidate_ch_freq = csr_get_channel_for_hw_mode_change(mac_ctx, + result_handle, + session_id); sme_scan_result_purge(result_handle); - if (!candidate_chan) - candidate_chan = first_ap_ch; + if (!candidate_ch_freq) + candidate_ch_freq = first_ap_ch_freq; sme_debug("session %d hw mode check candidate_chan %d", session_id, - candidate_chan); + candidate_ch_freq); - return candidate_chan; + return candidate_ch_freq; } -static enum wlan_auth_type csr_covert_auth_type_new(enum csr_akm_type auth) +enum wlan_auth_type csr_covert_auth_type_new(enum csr_akm_type auth) { switch (auth) { case eCSR_AUTH_TYPE_NONE: @@ -2138,7 +2143,7 @@ static enum csr_akm_type csr_covert_auth_type_old(enum wlan_auth_type auth) } } -static enum wlan_enc_type csr_covert_enc_type_new(eCsrEncryptionType enc) +enum wlan_enc_type csr_covert_enc_type_new(eCsrEncryptionType enc) { switch (enc) { case eCSR_ENCRYPT_TYPE_NONE: @@ -2208,242 +2213,6 @@ static eCsrEncryptionType csr_covert_enc_type_old(enum wlan_enc_type enc) } } -#ifdef WLAN_FEATURE_11W -/** - * csr_update_pmf_cap: Updates PMF cap - * @src_filter: Source filter - * @dst_filter: Destination filter - * - * Return: None - */ -static void csr_update_pmf_cap(tCsrScanResultFilter *src_filter, - struct scan_filter *dst_filter) { - - if (src_filter->MFPCapable || src_filter->MFPEnabled) - dst_filter->pmf_cap = WLAN_PMF_CAPABLE; - if (src_filter->MFPRequired) - dst_filter->pmf_cap = WLAN_PMF_REQUIRED; -} -#else -static inline void csr_update_pmf_cap(tCsrScanResultFilter *src_filter, - struct scan_filter *dst_filter) -{} -#endif - -/** - * csr_convert_dotllmod_phymode: Convert eCsrPhyMode to wlan_phymode - * @dotllmode: phy mode - * - * Return: returns enum wlan_phymode - */ -static enum wlan_phymode csr_convert_dotllmod_phymode(eCsrPhyMode dotllmode) -{ - - enum wlan_phymode con_phy_mode; - - switch (dotllmode) { - case eCSR_DOT11_MODE_abg: - con_phy_mode = WLAN_PHYMODE_AUTO; - break; - case eCSR_DOT11_MODE_11a: - con_phy_mode = WLAN_PHYMODE_11A; - break; - case eCSR_DOT11_MODE_11b: - con_phy_mode = WLAN_PHYMODE_11B; - break; - case eCSR_DOT11_MODE_11g: - con_phy_mode = WLAN_PHYMODE_11G; - break; - case eCSR_DOT11_MODE_11n: - con_phy_mode = WLAN_PHYMODE_11NA_HT20; - break; - case eCSR_DOT11_MODE_11g_ONLY: - con_phy_mode = WLAN_PHYMODE_11G; - break; - case eCSR_DOT11_MODE_11n_ONLY: - con_phy_mode = WLAN_PHYMODE_11NA_HT20; - break; - case eCSR_DOT11_MODE_11b_ONLY: - con_phy_mode = WLAN_PHYMODE_11B; - break; - case eCSR_DOT11_MODE_11ac: - con_phy_mode = WLAN_PHYMODE_11AC_VHT160; - break; - case eCSR_DOT11_MODE_11ac_ONLY: - con_phy_mode = WLAN_PHYMODE_11AC_VHT160; - break; - case eCSR_DOT11_MODE_AUTO: - con_phy_mode = WLAN_PHYMODE_AUTO; - break; - case eCSR_DOT11_MODE_11ax: - con_phy_mode = WLAN_PHYMODE_11AXA_HE160; - break; - case eCSR_DOT11_MODE_11ax_ONLY: - con_phy_mode = WLAN_PHYMODE_11AXA_HE160; - break; - default: - con_phy_mode = WLAN_PHYMODE_AUTO; - break; - } - - return con_phy_mode; -} - -#ifdef WLAN_ADAPTIVE_11R -/** - * csr_update_adaptive_11r_scan_filter - Copy adaptive 11r ini to scan - * module - * @mac_ctx: Pointer to mac_context - * @scan_filter: Scan filter to be sent to scan module - * - * Return: None - */ -static void -csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx, - struct scan_filter *filter) -{ - filter->enable_adaptive_11r = - mac_ctx->mlme_cfg->lfr.enable_adaptive_11r; -} -#else -static inline void -csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx, - struct scan_filter *filter) -{ - filter->enable_adaptive_11r = false; -} -#endif - -static QDF_STATUS csr_prepare_scan_filter(struct mac_context *mac_ctx, - tCsrScanResultFilter *pFilter, - struct scan_filter *filter) -{ - int i; - uint32_t len = 0; - QDF_STATUS status; - enum policy_mgr_con_mode new_mode; - - filter->num_of_bssid = pFilter->BSSIDs.numOfBSSIDs; - if (filter->num_of_bssid > WLAN_SCAN_FILTER_NUM_BSSID) - filter->num_of_bssid = WLAN_SCAN_FILTER_NUM_BSSID; - for (i = 0; i < filter->num_of_bssid; i++) - qdf_mem_copy(filter->bssid_list[i].bytes, - pFilter->BSSIDs.bssid[i].bytes, - QDF_MAC_ADDR_SIZE); - - filter->age_threshold = pFilter->age_threshold; - - filter->num_of_ssid = pFilter->SSIDs.numOfSSIDs; - if (filter->num_of_ssid > WLAN_SCAN_FILTER_NUM_SSID) - filter->num_of_ssid = WLAN_SCAN_FILTER_NUM_SSID; - for (i = 0; i < filter->num_of_ssid; i++) { - filter->ssid_list[i].length = - pFilter->SSIDs.SSIDList[i].SSID.length; - qdf_mem_copy(filter->ssid_list[i].ssid, - pFilter->SSIDs.SSIDList[i].SSID.ssId, - filter->ssid_list[i].length); - } - - filter->num_of_channels = - pFilter->ChannelInfo.numOfChannels; - if (filter->num_of_channels > QDF_MAX_NUM_CHAN) - filter->num_of_channels = QDF_MAX_NUM_CHAN; - qdf_mem_copy(filter->channel_list, - pFilter->ChannelInfo.ChannelList, - filter->num_of_channels); - - if (pFilter->realm_check) { - filter->fils_scan_filter.realm_check = true; - qdf_mem_copy(filter->fils_scan_filter.fils_realm, - pFilter->fils_realm, REAM_HASH_LEN); - } - - if (pFilter->force_rsne_override) { - - sme_debug("force_rsne_override set auth type and enctype to any and ignore pmf cap"); - - filter->num_of_auth = 1; - filter->auth_type[0] = WLAN_AUTH_TYPE_ANY; - filter->num_of_enc_type = 1; - filter->enc_type[0] = WLAN_ENCRYPT_TYPE_ANY; - filter->num_of_mc_enc_type = 1; - filter->mc_enc_type[0] = WLAN_ENCRYPT_TYPE_ANY; - - filter->ignore_pmf_cap = true; - } else { - filter->num_of_auth = - pFilter->authType.numEntries; - if (filter->num_of_auth > WLAN_NUM_OF_SUPPORT_AUTH_TYPE) - filter->num_of_auth = WLAN_NUM_OF_SUPPORT_AUTH_TYPE; - for (i = 0; i < filter->num_of_auth; i++) - filter->auth_type[i] = - csr_covert_auth_type_new( - pFilter->authType.authType[i]); - filter->num_of_enc_type = - pFilter->EncryptionType.numEntries; - if (filter->num_of_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE) - filter->num_of_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE; - for (i = 0; i < filter->num_of_enc_type; i++) - filter->enc_type[i] = - csr_covert_enc_type_new( - pFilter->EncryptionType.encryptionType[i]); - filter->num_of_mc_enc_type = - pFilter->mcEncryptionType.numEntries; - if (filter->num_of_mc_enc_type > WLAN_NUM_OF_ENCRYPT_TYPE) - filter->num_of_mc_enc_type = WLAN_NUM_OF_ENCRYPT_TYPE; - for (i = 0; i < filter->num_of_mc_enc_type; i++) - filter->mc_enc_type[i] = - csr_covert_enc_type_new( - pFilter->mcEncryptionType.encryptionType[i]); - } - qdf_mem_copy(filter->country, pFilter->countryCode, - CFG_COUNTRY_CODE_LEN); - - if (pFilter->bWPSAssociation || pFilter->bOSENAssociation) - filter->ignore_auth_enc_type = true; - - filter->rrm_measurement_filter = pFilter->fMeasurement; - - filter->mobility_domain = pFilter->mdid.mobility_domain; - - filter->p2p_results = pFilter->p2pResult; - - csr_update_pmf_cap(pFilter, filter); - - if (pFilter->BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE) - filter->bss_type = WLAN_TYPE_BSS; - else if (pFilter->BSSType == eCSR_BSS_TYPE_IBSS || - pFilter->BSSType == eCSR_BSS_TYPE_START_IBSS) - filter->bss_type = WLAN_TYPE_IBSS; - else - filter->bss_type = WLAN_TYPE_ANY; - - filter->dot11_mode = csr_convert_dotllmod_phymode(pFilter->phyMode); - - // enable bss scoring for only STA mode - if (pFilter->csrPersona == QDF_STA_MODE) - filter->bss_scoring_required = true; - else - filter->bss_scoring_required = false; - - csr_update_adaptive_11r_scan_filter(mac_ctx, filter); - - if (!pFilter->BSSIDs.numOfBSSIDs) { - if (policy_mgr_map_concurrency_mode( - &pFilter->csrPersona, &new_mode)) { - status = policy_mgr_get_pcl(mac_ctx->psoc, new_mode, - filter->pcl_channel_list, &len, - filter->pcl_weight_list, QDF_MAX_NUM_CHAN); - filter->num_of_pcl_channels = (uint8_t)len; - } - } - qdf_mem_copy(filter->bssid_hint.bytes, - pFilter->bssid_hint.bytes, - QDF_MAC_ADDR_SIZE); - - return QDF_STATUS_SUCCESS; -} - #ifdef WLAN_FEATURE_FILS_SK /** * csr_update_bss_with_fils_data: Fill FILS params in bss desc from scan entry @@ -2566,12 +2335,14 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, enum channel_state ap_channel_state; ap_channel_state = - wlan_reg_get_channel_state(mac_ctx->pdev, - scan_entry->channel.chan_idx); + wlan_reg_get_channel_state_for_freq( + mac_ctx->pdev, + scan_entry->channel.chan_freq); if (ap_channel_state == CHANNEL_STATE_DISABLE || ap_channel_state == CHANNEL_STATE_INVALID) { - sme_err("BSS %pM channel %d invalid, not populating this BSSID", - scan_entry->bssid.bytes, scan_entry->channel.chan_idx); + sme_err("BSS "QDF_MAC_ADDR_FMT" channel %d invalid, not populating this BSSID", + QDF_MAC_ADDR_REF(scan_entry->bssid.bytes), + scan_entry->channel.chan_freq); return QDF_STATUS_E_INVAL; } @@ -2612,14 +2383,15 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, qdf_mem_copy(bss_desc->bssId, scan_entry->bssid.bytes, QDF_MAC_ADDR_SIZE); - bss_desc->scansystimensec = scan_entry->scan_entry_time; + bss_desc->scansystimensec = scan_entry->boottime_ns; qdf_mem_copy(bss_desc->timeStamp, scan_entry->tsf_info.data, 8); bss_desc->beaconInterval = scan_entry->bcn_int; bss_desc->capabilityInfo = scan_entry->cap_info.value; - if (WLAN_REG_IS_5GHZ_CH(scan_entry->channel.chan_idx)) + if (WLAN_REG_IS_5GHZ_CH_FREQ(scan_entry->channel.chan_freq) || + WLAN_REG_IS_6GHZ_CHAN_FREQ(scan_entry->channel.chan_freq)) bss_desc->nwType = eSIR_11A_NW_TYPE; else if (scan_entry->phy_mode == WLAN_PHYMODE_11B) bss_desc->nwType = eSIR_11B_NW_TYPE; @@ -2629,14 +2401,8 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, bss_desc->rssi = scan_entry->rssi_raw; bss_desc->rssi_raw = scan_entry->rssi_raw; - /* channelId what peer sent in beacon/probersp. */ - bss_desc->channelId = - scan_entry->channel.chan_idx; - /* channelId on which we are parked at. */ - /* used only in scan case. */ - bss_desc->channelIdSelf = - scan_entry->channel.chan_idx; - bss_desc->rx_channel = bss_desc->channelIdSelf; + /* channel frequency what peer sent in beacon/probersp. */ + bss_desc->chan_freq = scan_entry->channel.chan_freq; bss_desc->received_time = scan_entry->scan_entry_time; bss_desc->startTSF[0] = @@ -2689,12 +2455,6 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, } #endif csr_update_bss_with_fils_data(mac_ctx, scan_entry, bss_desc); - if (scan_entry->alt_wcn_ie.ptr) { - bss_desc->WscIeLen = scan_entry->alt_wcn_ie.len; - qdf_mem_copy(bss_desc->WscIeProbeRsp, - scan_entry->alt_wcn_ie.ptr, - scan_entry->alt_wcn_ie.len); - } *p_result = bss; return QDF_STATUS_SUCCESS; @@ -2763,13 +2523,12 @@ static void csr_remove_ap_with_assoc_disallowed(struct mac_context *mac_ctx, } QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, - tCsrScanResultFilter *pFilter, + struct scan_filter *filter, tScanResultHandle *results) { QDF_STATUS status; struct scan_result_list *ret_list = NULL; qdf_list_t *list = NULL; - struct scan_filter *filter = NULL; struct wlan_objmgr_pdev *pdev = NULL; uint32_t num_bss = 0; @@ -2783,28 +2542,14 @@ QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, return QDF_STATUS_E_INVAL; } - if (pFilter) { - filter = qdf_mem_malloc(sizeof(*filter)); - if (!filter) { - status = QDF_STATUS_E_NOMEM; - goto error; - } - - status = csr_prepare_scan_filter(mac_ctx, pFilter, filter); - if (QDF_IS_STATUS_ERROR(status)) { - sme_err("Prepare filter failed"); - goto error; - } - } - - list = ucfg_scan_get_result(pdev, - pFilter ? filter : NULL); + list = ucfg_scan_get_result(pdev, filter); if (list) { num_bss = qdf_list_size(list); sme_debug("num_entries %d", num_bss); } + /* Filter the scan list with the blacklist, rssi reject, avoided APs */ - if (pFilter && pFilter->csrPersona == QDF_STA_MODE) + if (filter && filter->bss_scoring_required) wlan_blm_filter_bssid(pdev, list); if (!list || (list && !qdf_list_size(list))) { @@ -2829,7 +2574,7 @@ QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, /* Fail or No one wants the result. */ csr_scan_result_purge(mac_ctx, (tScanResultHandle) ret_list); else { - if (pFilter && pFilter->csrPersona == QDF_STA_MODE) + if (filter && filter->bss_scoring_required) csr_remove_ap_with_assoc_disallowed(mac_ctx, ret_list); if (!csr_ll_count(&ret_list->List)) { @@ -2851,8 +2596,6 @@ QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, } error: - if (filter) - qdf_mem_free(filter); if (list) ucfg_scan_purge_results(list); if (pdev) @@ -2866,7 +2609,7 @@ QDF_STATUS csr_scan_get_result_for_bssid(struct mac_context *mac_ctx, tCsrScanResultInfo *res) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - tCsrScanResultFilter *scan_filter = NULL; + struct scan_filter *scan_filter; tScanResultHandle filtered_scan_result = NULL; tCsrScanResultInfo *scan_result; @@ -2876,18 +2619,13 @@ QDF_STATUS csr_scan_get_result_for_bssid(struct mac_context *mac_ctx, return QDF_STATUS_E_FAILURE; } - scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); if (!scan_filter) return QDF_STATUS_E_NOMEM; - scan_filter->BSSIDs.bssid = qdf_mem_malloc(sizeof(*bssid)); - if (!scan_filter->BSSIDs.bssid) { - status = QDF_STATUS_E_FAILURE; - goto free_filter; - } - - scan_filter->BSSIDs.numOfBSSIDs = 1; - qdf_mem_copy(scan_filter->BSSIDs.bssid, bssid, sizeof(*bssid)); + scan_filter->num_of_bssid = 1; + qdf_mem_copy(scan_filter->bssid_list[0].bytes, bssid->bytes, + QDF_MAC_ADDR_SIZE); status = csr_scan_get_result(mac_ctx, scan_filter, &filtered_scan_result); @@ -2915,7 +2653,6 @@ QDF_STATUS csr_scan_get_result_for_bssid(struct mac_context *mac_ctx, csr_scan_result_purge(mac_ctx, filtered_scan_result); free_filter: - csr_free_scan_filter(mac_ctx, scan_filter); if (scan_filter) qdf_mem_free(scan_filter); @@ -2955,7 +2692,8 @@ static inline void csr_flush_bssid(struct mac_context *mac_ctx, bssid, QDF_MAC_ADDR_SIZE); csr_flush_scan_results(mac_ctx, filter); - sme_debug("Removed BSS entry:%pM", bssid); + sme_debug("Removed BSS entry:"QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid)); if (filter) qdf_mem_free(filter); } @@ -2980,7 +2718,7 @@ static void csr_dump_occupied_chan_list(struct csr_channel *occupied_ch) for (idx = 0; idx < occupied_ch->numChannels; idx++) len += qdf_scnprintf(chan_buff + len, buff_len - len, " %d", - occupied_ch->channelList[idx]); + occupied_ch->channel_freq_list[idx]); sme_nofl_debug("Occupied chan list[%d]:%s", occupied_ch->numChannels, chan_buff); @@ -2996,17 +2734,15 @@ void csr_init_occupied_channels_list(struct mac_context *mac_ctx, qdf_list_node_t *next_lst = NULL; struct scan_cache_node *cur_node = NULL; struct scan_filter *filter; - tpCsrNeighborRoamControlInfo neighbor_roam_info; + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[sessionId]; tCsrRoamConnectedProfile *profile = NULL; - uint8_t ch; if (!(mac_ctx && mac_ctx->roam.roamSession && CSR_IS_SESSION_VALID(mac_ctx, sessionId))) { sme_debug("Invalid session"); return; } - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[sessionId]; - if (neighbor_roam_info->cfgParams.specific_chan_info.numOfChannels) { /* * Ini file contains neighbor scan channel list, hence NO need @@ -3052,7 +2788,8 @@ void csr_init_occupied_channels_list(struct mac_context *mac_ctx, mac_ctx->scan.roam_candidate_count[sessionId] = 0; csr_add_to_occupied_channels( - mac_ctx, profile->operationChannel, + mac_ctx, + profile->op_freq, sessionId, &mac_ctx->scan.occupiedChannels[sessionId], true); @@ -3073,9 +2810,8 @@ void csr_init_occupied_channels_list(struct mac_context *mac_ctx, while (cur_lst) { cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); - ch = cur_node->entry->channel.chan_idx; csr_add_to_occupied_channels( - mac_ctx, ch, + mac_ctx, cur_node->entry->channel.chan_freq, sessionId, &mac_ctx->scan.occupiedChannels[sessionId], true); @@ -3104,8 +2840,11 @@ void csr_init_occupied_channels_list(struct mac_context *mac_ctx, QDF_STATUS csr_scan_filter_results(struct mac_context *mac_ctx) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t len = sizeof(mac_ctx->roam.validChannelList); + uint32_t len = sizeof(mac_ctx->roam.valid_ch_freq_list); struct wlan_objmgr_pdev *pdev = NULL; + uint32_t i; + uint32_t ch_freq; + uint32_t valid_ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN]; pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc, 0, WLAN_LEGACY_MAC_ID); @@ -3114,7 +2853,7 @@ QDF_STATUS csr_scan_filter_results(struct mac_context *mac_ctx) return QDF_STATUS_E_INVAL; } status = csr_get_cfg_valid_channels(mac_ctx, - mac_ctx->roam.validChannelList, + mac_ctx->roam.valid_ch_freq_list, &len); /* Get valid channels list from CFG */ @@ -3125,8 +2864,15 @@ QDF_STATUS csr_scan_filter_results(struct mac_context *mac_ctx) } sme_debug("No of valid channel %d", len); - ucfg_scan_filter_valid_channel(pdev, - mac_ctx->roam.validChannelList, len); + /* This is a temporary conversion till the scm handles freq */ + + for (i = 0; i < len; i++) { + ch_freq = mac_ctx->roam.valid_ch_freq_list[i]; + valid_ch_freq_list[i] = ch_freq; + } + + ucfg_scan_filter_valid_channel(pdev, valid_ch_freq_list, len); + wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_cmd_process.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_cmd_process.c index 9e8fcc8bd0442aaef36b4e3f127b11234785b118..b4c217f844f155df8e3207a75510f6a52b11b9ce 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_cmd_process.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_cmd_process.c @@ -39,16 +39,15 @@ QDF_STATUS csr_msg_processor(struct mac_context *mac_ctx, void *msg_buf) { QDF_STATUS status = QDF_STATUS_SUCCESS; tSirSmeRsp *sme_rsp = (tSirSmeRsp *) msg_buf; - uint8_t session_id = sme_rsp->sessionId; + uint8_t vdev_id = sme_rsp->vdev_id; enum csr_roam_state cur_state; - cur_state = sme_get_current_roam_state(MAC_HANDLE(mac_ctx), session_id); + cur_state = sme_get_current_roam_state(MAC_HANDLE(mac_ctx), vdev_id); sme_debug("msg %d[0x%04X] recvd in curstate %s & substate %s id(%d)", sme_rsp->messageType, sme_rsp->messageType, mac_trace_getcsr_roam_state(cur_state), mac_trace_getcsr_roam_sub_state( - mac_ctx->roam.curSubState[session_id]), - session_id); + mac_ctx->roam.curSubState[vdev_id]), vdev_id); /* Process the message based on the state of the roaming states... */ switch (cur_state) { @@ -62,12 +61,6 @@ QDF_STATUS csr_msg_processor(struct mac_context *mac_ctx, void *msg_buf) break; default: - if (sme_rsp->messageType == - eWNI_SME_GET_STATISTICS_RSP) { - csr_roam_joined_state_msg_processor(mac_ctx, - msg_buf); - break; - } if (sme_rsp->messageType == eWNI_SME_UPPER_LAYER_ASSOC_CNF) { @@ -94,34 +87,22 @@ QDF_STATUS csr_msg_processor(struct mac_context *mac_ctx, void *msg_buf) sme_rsp->messageType, cur_state); csr_roam_check_for_link_status_change(mac_ctx, sme_rsp); - } else if (eWNI_SME_GET_RSSI_REQ == - sme_rsp->messageType) { - tAniGetRssiReq *pGetRssiReq = - (tAniGetRssiReq *) msg_buf; - if (!pGetRssiReq->rssiCallback) { - sme_err("rssiCallback is NULL"); - return status; - } - ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))( - pGetRssiReq->lastRSSI, - pGetRssiReq->staId, - pGetRssiReq->pDevContext); } else { sme_err("Message 0x%04X is not handled by CSR state is %d session Id %d", sme_rsp->messageType, cur_state, - session_id); + vdev_id); if (eWNI_SME_FT_PRE_AUTH_RSP == sme_rsp->messageType) { sme_err("Dequeue eSmeCommandRoam command with reason eCsrPerformPreauth"); csr_dequeue_roam_command(mac_ctx, - eCsrPerformPreauth, session_id); + eCsrPerformPreauth, vdev_id); } else if (eWNI_SME_REASSOC_RSP == sme_rsp->messageType) { sme_err("Dequeue eSmeCommandRoam command with reason eCsrSmeIssuedFTReassoc"); csr_dequeue_roam_command(mac_ctx, eCsrSmeIssuedFTReassoc, - session_id); + vdev_id); } } break; diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_host_scan_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_host_scan_roam.c index 0fb6061aa1ae732f26822ea3c50c0747caf3c73c..aeff8c70dd5de4e22c8a6f395e75121cae8160be 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_host_scan_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_host_scan_roam.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,40 +34,22 @@ #include "mac_trace.h" #include "wlan_policy_mgr_api.h" -/** - * csr_roam_issue_reassociate() - Issue Reassociate - * @mac: Global MAC Context - * @sessionId: SME Session ID - * @pSirBssDesc: BSS Descriptor - * @pIes: Pointer to the IE's - * @pProfile: Roaming profile - * - * Return: Success or Failure - */ -QDF_STATUS csr_roam_issue_reassociate(struct mac_context *mac, - uint32_t sessionId, struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, struct csr_roam_profile *pProfile) +QDF_STATUS csr_roam_issue_reassociate(struct mac_context *mac, uint32_t vdev_id, + struct bss_description *bss_desc, + tDot11fBeaconIEs *ies, + struct csr_roam_profile *roam_profile) { - csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, sessionId); + csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, vdev_id); /* Set the roaming substate to 'join attempt'... */ - csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, - sessionId); - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)")); + csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, vdev_id); + sme_debug("calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"); /* attempt to Join this BSS... */ - return csr_send_join_req_msg(mac, sessionId, pSirBssDesc, pProfile, - pIes, eWNI_SME_REASSOC_REQ); + return csr_send_join_req_msg(mac, vdev_id, bss_desc, roam_profile, ies, + eWNI_SME_REASSOC_REQ); } -/** - * csr_roam_issue_reassociate_cmd() - Issue the reassociate command - * @mac: Global MAC Context - * @sessionId: SME Session ID - * - * Return: Success or Failure status - */ -QDF_STATUS csr_roam_issue_reassociate_cmd(struct mac_context *mac, - uint32_t sessionId) +QDF_STATUS +csr_roam_issue_reassociate_cmd(struct mac_context *mac, uint32_t sessionId) { QDF_STATUS status = QDF_STATUS_SUCCESS; tSmeCmd *pCommand = NULL; @@ -134,7 +115,7 @@ QDF_STATUS csr_roam_issue_reassociate_cmd(struct mac_context *mac, sessionId); } pCommand->command = eSmeCommandRoam; - pCommand->sessionId = (uint8_t) sessionId; + pCommand->vdev_id = (uint8_t) sessionId; pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc; status = csr_queue_sme_command(mac, pCommand, fHighPriority); if (!QDF_IS_STATUS_SUCCESS(status)) @@ -144,30 +125,15 @@ QDF_STATUS csr_roam_issue_reassociate_cmd(struct mac_context *mac, return status; } -/** - * csr_neighbor_roam_process_scan_results() - build roaming candidate list - * - * @mac_ctx: The handle returned by mac_open. - * @sessionid: Session information - * @scan_results_list: List obtained from csr_scan_get_result() - * - * This function applies various candidate checks like LFR, 11r, preauth, ESE - * and builds a roamable AP list. It applies age limit only if no suitable - * recent candidates are found. - * - * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid]. - * - * Return: void - */ - void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, - uint8_t sessionid, tScanResultHandle *scan_results_list) + uint8_t sessionid, tScanResultHandle *scan_results_list) { tCsrScanResultInfo *scan_result; tpCsrNeighborRoamControlInfo n_roam_info = &mac_ctx->roam.neighborRoamInfo[sessionid]; tpCsrNeighborRoamBSSInfo bss_info; uint64_t age = 0; + uint32_t bss_chan_freq; uint8_t num_candidates = 0; uint8_t num_dropped = 0; /* @@ -201,11 +167,12 @@ void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, if (!scan_result) break; descr = &scan_result->BssDescriptor; + bss_chan_freq = descr->chan_freq; QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("Scan result: BSSID " QDF_MAC_ADDR_STR + FL("Scan result: BSSID " QDF_MAC_ADDR_FMT " (Rssi %d, Ch:%d)"), - QDF_MAC_ADDR_ARRAY(descr->bssId), - (int)abs(descr->rssi), descr->channelId); + QDF_MAC_ADDR_REF(descr->bssId), + (int)abs(descr->rssi), descr->chan_freq); if (!qdf_mem_cmp(descr->bssId, n_roam_info->currAPbssid.bytes, @@ -227,15 +194,14 @@ void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, if (policy_mgr_concurrent_open_sessions_running( mac_ctx->psoc) && !mac_ctx->roam.configParam.fenableMCCMode) { - uint8_t conc_channel; + uint32_t conc_freq; - conc_channel = - csr_get_concurrent_operation_channel(mac_ctx); - if (conc_channel && - (conc_channel != - scan_result->BssDescriptor.channelId)) { + conc_freq = + csr_get_concurrent_operation_freq(mac_ctx); + if (conc_freq && + (conc_freq != bss_chan_freq)) { sme_debug("MCC not supported so Ignore AP on channel %d", - scan_result->BssDescriptor.channelId); + descr->chan_freq); continue; } } @@ -245,11 +211,12 @@ void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, * have duplicates */ if ((n_roam_info->uOsRequestedHandoff) && - ((qdf_mem_cmp(descr->bssId, - n_roam_info->handoffReqInfo.bssid.bytes, - sizeof(tSirMacAddr))) - || (descr->channelId != - n_roam_info->handoffReqInfo.channel))) { + ((qdf_mem_cmp( + descr->bssId, + n_roam_info->handoffReqInfo.bssid.bytes, + sizeof(tSirMacAddr))) || + (descr->chan_freq != + n_roam_info->handoffReqInfo.ch_freq))) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "SKIP-not a candidate AP for OS requested roam"); @@ -283,15 +250,15 @@ void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, (qavail < n_roam_info->MinQBssLoadRequired)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "BSSID:" QDF_MAC_ADDR_STR "has no BW", - QDF_MAC_ADDR_ARRAY(descr->bssId)); + "BSSID:" QDF_MAC_ADDR_FMT "has no BW", + QDF_MAC_ADDR_REF(descr->bssId)); continue; } if (voadmitted && !qpresent) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "BSSID:" QDF_MAC_ADDR_STR "no LOAD IE", - QDF_MAC_ADDR_ARRAY(descr->bssId)); + "BSSID:" QDF_MAC_ADDR_FMT "no LOAD IE", + QDF_MAC_ADDR_REF(descr->bssId)); continue; } #endif /* FEATURE_WLAN_ESE */ @@ -376,58 +343,47 @@ void csr_neighbor_roam_process_scan_results(struct mac_context *mac_ctx, csr_scan_result_purge(mac_ctx, *scan_results_list); } -/** - * csr_neighbor_roam_trigger_handoff() - Start roaming - * @mac_ctx: Global MAC Context - * @session_id: SME Session ID - * - * Return: None - */ void csr_neighbor_roam_trigger_handoff(struct mac_context *mac_ctx, - uint8_t session_id) + uint8_t vdev_id) { - if (csr_roam_is_fast_roam_enabled(mac_ctx, session_id)) - csr_neighbor_roam_issue_preauth_req(mac_ctx, session_id); + if (csr_roam_is_fast_roam_enabled(mac_ctx, vdev_id)) + csr_neighbor_roam_issue_preauth_req(mac_ctx, vdev_id); else sme_err("Roaming is disabled"); } -/** - * csr_neighbor_roam_process_scan_complete() - Post process the scan results - * @mac: Global MAC Context - * @sessionId: SME Session ID - * - * Return: Success or Failure - */ QDF_STATUS csr_neighbor_roam_process_scan_complete(struct mac_context *mac, - uint8_t sessionId) + uint8_t sessionId) { tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &mac->roam.neighborRoamInfo[sessionId]; - tCsrScanResultFilter scanFilter; + struct scan_filter *filter; tScanResultHandle scanResult; uint32_t tempVal = 0; QDF_STATUS hstatus; - hstatus = csr_neighbor_roam_prepare_scan_profile_filter(mac, - &scanFilter, - sessionId); + filter = qdf_mem_malloc(sizeof(*filter)); + if (!filter) + return QDF_STATUS_E_NOMEM; + + hstatus = csr_neighbor_roam_get_scan_filter_from_profile(mac, + filter, + sessionId); sme_debug("Prepare scan to find neighbor AP filter status: %d", hstatus); if (QDF_STATUS_SUCCESS != hstatus) { sme_err("Scan Filter prep fail for Assoc %d Bail out", tempVal); + qdf_mem_free(filter); return QDF_STATUS_E_FAILURE; } - hstatus = csr_scan_get_result(mac, &scanFilter, &scanResult); + hstatus = csr_scan_get_result(mac, filter, &scanResult); + qdf_mem_free(filter); if (hstatus != QDF_STATUS_SUCCESS) sme_err("Get Scan Result status code %d", hstatus); /* Process the scan results and update roamable AP list */ csr_neighbor_roam_process_scan_results(mac, sessionId, &scanResult); - /* Free the scan filter */ - csr_free_scan_filter(mac, &scanFilter); - tempVal = csr_ll_count(&pNeighborRoamInfo->roamableAPList); if (tempVal) { @@ -456,19 +412,8 @@ QDF_STATUS csr_neighbor_roam_process_scan_complete(struct mac_context *mac, } -/** - * csr_neighbor_roam_candidate_found_ind_hdlr() - * - * @mac_ctx: Pointer to Global MAC structure - * @msg_buf: pointer to msg buff - * - * This function is called by CSR as soon as TL posts the candidate - * found indication to SME via MC thread - * - * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise - */ QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(struct mac_context *mac, - void *pMsg) + void *pMsg) { tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd = (tSirSmeCandidateFoundInd *) pMsg; @@ -502,15 +447,6 @@ QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(struct mac_context *mac, return status; } -/** - * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list - * @mac_ctx: The handle returned by mac_open. - * @llist: Neighbor Roam BSS List to be emptied - * - * Empties and frees all the nodes in the roamable AP list - * - * Return: none - */ void csr_neighbor_roam_free_roamable_bss_list(struct mac_context *mac_ctx, tDblLinkList *llist) { @@ -528,44 +464,21 @@ void csr_neighbor_roam_free_roamable_bss_list(struct mac_context *mac_ctx, } } -/** - * csr_neighbor_roam_remove_roamable_ap_list_entry() - * - * @mac_ctx: Pointer to Global MAC structure - * @pList: The list from which the entry should be removed - * @pNeighborEntry: Neighbor Roam BSS Node to be removed - * - * This function removes a given entry from the given list - * - * Return: true if successfully removed, else false - */ bool csr_neighbor_roam_remove_roamable_ap_list_entry(struct mac_context *mac, tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry) { - if (pList) { + if (pList) return csr_ll_remove_entry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK); - } sme_debug("Remove neigh BSS node from fail list. Current count: %d", - csr_ll_count(pList)); + csr_ll_count(pList)); return false; } -/** - * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list - * @mac_ctx - The handle returned by mac_open. - * @plist - The list from which the entry should be returned - * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned - * - * Gets the entry next to passed entry. If NULL is passed, return the entry - * in the head of the list - * - * Return: Neighbor Roam BSS Node to be returned - */ tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap( struct mac_context *mac_ctx, tDblLinkList *llist, tpCsrNeighborRoamBSSInfo neighbor_entry) @@ -587,34 +500,16 @@ tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap( return result; } - -/** - * csr_neighbor_roam_request_handoff() - Handoff to a different AP - * @mac_ctx: Pointer to Global MAC structure - * @session_id: Session ID - * - * This function triggers actual switching from one AP to the new AP. - * It issues disassociate with reason code as Handoff and CSR as a part of - * handling disassoc rsp, issues reassociate to the new AP - * - * Return: none - */ void csr_neighbor_roam_request_handoff(struct mac_context *mac_ctx, uint8_t session_id) { struct csr_roam_info *roam_info; - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - tpCsrNeighborRoamControlInfo neighbor_roam_info; + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[session_id]; tCsrNeighborRoamBSSInfo handoff_node; uint32_t roamid = 0; QDF_STATUS status; - if (!session) { - sme_err("Session_id invalid %d", session_id); - return; - } - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[session_id]; - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s session_id=%d", __func__, session_id); @@ -633,8 +528,8 @@ void csr_neighbor_roam_request_handoff(struct mac_context *mac_ctx, return; } QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("HANDOFF CANDIDATE BSSID "QDF_MAC_ADDR_STR), - QDF_MAC_ADDR_ARRAY(handoff_node.pBssDescription->bssId)); + FL("HANDOFF CANDIDATE BSSID "QDF_MAC_ADDR_FMT), + QDF_MAC_ADDR_REF(handoff_node.pBssDescription->bssId)); roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) @@ -668,8 +563,8 @@ void csr_neighbor_roam_request_handoff(struct mac_context *mac_ctx, } qdf_mem_copy(neighbor_roam_info->csrNeighborRoamProfile.BSSIDs.bssid, handoff_node.pBssDescription->bssId, sizeof(tSirMacAddr)); - neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = - handoff_node.pBssDescription->channelId; + neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.freq_list[0] = + handoff_node.pBssDescription->chan_freq; sme_debug("csr_roamHandoffRequested: disassociating with current AP"); @@ -695,24 +590,10 @@ void csr_neighbor_roam_request_handoff(struct mac_context *mac_ctx, } - -/** - * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming - * - * @mac: mac context - * @session_id: Session Id - * @hand_off_node: AP node that is the handoff candidate returned - * - * This function returns the best possible AP for handoff. For 11R case, it - * returns the 1st entry from pre-auth done list. For non-11r case, it returns - * the 1st entry from roamable AP list - * - * Return: true if able find handoff AP, false otherwise - */ - -bool csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, - tpCsrNeighborRoamBSSInfo hand_off_node, - uint8_t session_id) +bool +csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, + tpCsrNeighborRoamBSSInfo hand_off_node, + uint8_t session_id) { tpCsrNeighborRoamControlInfo ngbr_roam_info = &mac->roam.neighborRoamInfo[session_id]; @@ -767,19 +648,8 @@ bool csr_neighbor_roam_get_handoff_ap_info(struct mac_context *mac, return true; } -/** - * csr_neighbor_roam_is_handoff_in_progress() - * - * @mac_ctx: Pointer to Global MAC structure - * @session_id: Session ID - * - * This function returns whether handoff is in progress or not based on - * the current neighbor roam state - * - * Return: true if reassoc in progress, false otherwise - */ bool csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, - uint8_t sessionId) + uint8_t sessionId) { if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == mac->roam.neighborRoamInfo[sessionId].neighborRoamState) @@ -788,28 +658,18 @@ bool csr_neighbor_roam_is_handoff_in_progress(struct mac_context *mac, return false; } -/** - * csr_neighbor_roam_free_neighbor_roam_bss_node() - * - * @mac_ctx: Pointer to Global MAC structure - * @neighborRoamBSSNode: Neighbor Roam BSS Node to be freed - * - * This function frees all the internal pointers CSR NeighborRoam BSS Info - * and also frees the node itself - * - * Return: None - */ void csr_neighbor_roam_free_neighbor_roam_bss_node(struct mac_context *mac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode) { - if (neighborRoamBSSNode) { - if (neighborRoamBSSNode->pBssDescription) { - qdf_mem_free(neighborRoamBSSNode->pBssDescription); - neighborRoamBSSNode->pBssDescription = NULL; - } - qdf_mem_free(neighborRoamBSSNode); - neighborRoamBSSNode = NULL; + if (!neighborRoamBSSNode) + return; + + if (neighborRoamBSSNode->pBssDescription) { + qdf_mem_free(neighborRoamBSSNode->pBssDescription); + neighborRoamBSSNode->pBssDescription = NULL; } + qdf_mem_free(neighborRoamBSSNode); + neighborRoamBSSNode = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_inside_api.h b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_inside_api.h index a61f0b710a8d3e9127b58a1a524111ea1119a33a..070e489bbac502e16ee5a31203c6571d864ae25c 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_inside_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_inside_api.h @@ -51,7 +51,7 @@ #define CSR_MAX_BSSID_COUNT (SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE/5000) - 1 #define CSR_CUSTOM_CONC_GO_BI 100 extern uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE]; -bool csr_is_supported_channel(struct mac_context *mac, uint8_t channelId); +bool csr_is_supported_channel(struct mac_context *mac, uint32_t chan_freq); enum csr_scancomplete_nextcommand { eCsrNextScanNothing, @@ -159,16 +159,6 @@ QDF_STATUS csr_roam_save_connected_bss_desc(struct mac_context *mac, uint32_t sessionId, struct bss_description *bss_desc); -/* - * Prepare a filter base on a profile for parsing the scan results. - * Upon successful return, caller MUST call csr_free_scan_filter on - * pScanFilter when it is done with the filter. - */ -QDF_STATUS -csr_roam_prepare_filter_from_profile(struct mac_context *mac, - struct csr_roam_profile *pProfile, - tCsrScanResultFilter *pScanFilter); - QDF_STATUS csr_roam_copy_profile(struct mac_context *mac, struct csr_roam_profile *pDstProfile, struct csr_roam_profile *pSrcProfile); @@ -223,16 +213,31 @@ QDF_STATUS csr_roam_issue_reassoc(struct mac_context *mac, uint32_t sessionId, bool fImediate); void csr_roam_complete(struct mac_context *mac, enum csr_roamcomplete_result Result, void *Context, uint8_t session_id); + +/** + * csr_issue_set_context_req_helper - Function to fill unicast/broadcast keys + * request to set the keys to fw + * @mac: Poiner to mac context + * @profile: Pointer to connected profile + * @vdev_id: vdev id + * @bssid: Connected BSSID + * @addkey: Is add key request to crypto + * @unicast: Unicast(1) or broadcast key(0) + * @key_direction: Key used in TX or RX or both Tx and RX path + * @key_id: Key index + * @key_length: Key length + * @key: Pointer to the key + * + * Return: QDF_STATUS + */ QDF_STATUS -csr_roam_issue_set_context_req_helper(struct mac_context *mac, - uint32_t session_id, - eCsrEncryptionType encr_type, - struct bss_description *bss_descr, - tSirMacAddr *bssid, bool addkey, - bool unicast, - tAniKeyDirection key_direction, - uint8_t key_id, uint16_t key_length, - uint8_t *key, uint8_t pae_role); +csr_issue_set_context_req_helper(struct mac_context *mac, + struct csr_roam_profile *profile, + uint32_t session_id, + tSirMacAddr *bssid, bool addkey, + bool unicast, tAniKeyDirection key_direction, + uint8_t key_id, uint16_t key_length, + uint8_t *key); QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, tSmeCmd *pCommand, @@ -248,13 +253,6 @@ csr_roam_save_connected_information(struct mac_context *mac, void csr_roam_check_for_link_status_change(struct mac_context *mac, tSirSmeRsp *pSirMsg); -#ifndef QCA_SUPPORT_CP_STATS -void csr_roam_stats_rsp_processor(struct mac_context *mac, tSirSmeRsp *pSirMsg); -#else -static inline void csr_roam_stats_rsp_processor(struct mac_context *mac, - tSirSmeRsp *pSirMsg) {} -#endif /* QCA_SUPPORT_CP_STATS */ - QDF_STATUS csr_roam_issue_start_bss(struct mac_context *mac, uint32_t sessionId, struct csr_roamstart_bssparams *pParam, struct csr_roam_profile *pProfile, @@ -316,12 +314,34 @@ bool csr_is_phy_mode_match(struct mac_context *mac, uint32_t phyMode, struct csr_roam_profile *pProfile, enum csr_cfgdot11mode *pReturnCfgDot11Mode, tDot11fBeaconIEs *pIes); -bool csr_roam_is_channel_valid(struct mac_context *mac, uint8_t channel); -/* pNumChan is a caller allocated space with the sizeof pChannels */ -QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac, uint8_t *pChannels, - uint32_t *pNumChan); -int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint8_t channel); +/** + * csr_roam_is_channel_valid() - validate channel frequency + * @mac: mac context + * @chan_freq: channel frequency + * + * This function validates channel frequency present in valid channel + * list or not. + * + * Return: true or false + */ +bool csr_roam_is_channel_valid(struct mac_context *mac, uint32_t chan_freq); + +/** + * csr_get_cfg_valid_channels() - Get valid channel frequency list + * @mac: mac context + * @ch_freq_list: valid channel frequencies + * @num_ch_freq: valid channel nummber + * + * This function returns the valid channel frequencies. + * + * Return: QDF_STATUS_SUCCESS for success. + */ +QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac, + uint32_t *ch_freq_list, + uint32_t *num_ch_freq); + +int8_t csr_get_cfg_max_tx_power(struct mac_context *mac, uint32_t ch_freq); /* To free the last roaming profile */ void csr_free_roam_profile(struct mac_context *mac, uint32_t sessionId); @@ -331,10 +351,6 @@ void csr_free_connect_bss_desc(struct mac_context *mac, uint32_t sessionId); void csr_release_profile(struct mac_context *mac, struct csr_roam_profile *pProfile); -/* To free memory allocated inside scanFilter */ -void csr_free_scan_filter(struct mac_context *mac, tCsrScanResultFilter - *pScanFilter); - enum csr_cfgdot11mode csr_get_cfg_dot11_mode_from_csr_phy_mode(struct csr_roam_profile *pProfile, eCsrPhyMode phyMode, @@ -362,13 +378,30 @@ void csr_reset_pmkid_candidate_list(struct mac_context *mac, uint32_t sessionId) QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac, uint32_t tableSize, tSirMacChanInfo *channelTable); -QDF_STATUS csr_roam_set_key(struct mac_context *mac, uint32_t sessionId, - tCsrRoamSetKey *pSetKey, uint32_t roamId); -QDF_STATUS csr_roam_open_session(struct mac_context *mac, - struct sme_session_params *session_param); -QDF_STATUS csr_roam_close_session(struct mac_context *mac_ctx, - uint32_t session_id, bool sync); -void csr_cleanup_session(struct mac_context *mac, uint32_t sessionId); + +/* + * csr_roam_vdev_delete() - CSR api to delete vdev + * @mac_ctx: pointer to mac context + * @vdev_id: vdev id to be deleted. + * @cleanup: clean up vdev session on true + * + * Return QDF_STATUS + */ +QDF_STATUS csr_roam_vdev_delete(struct mac_context *mac_ctx, + uint8_t vdev_id, bool cleanup); + +/* + * csr_cleanup_vdev_session() - CSR api to cleanup vdev + * @mac_ctx: pointer to mac context + * @vdev_id: vdev id to be deleted. + * + * This API is used to clean up vdev information gathered during + * vdev was enabled. + * + * Return QDF_STATUS + */ +void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id); + QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac, struct qdf_mac_addr *bssid, uint32_t *pSessionId); @@ -376,15 +409,89 @@ enum csr_cfgdot11mode csr_find_best_phy_mode(struct mac_context *mac, uint32_t phyMode); /* - * csr_scan_get_result() - - * Return scan results. + * csr_copy_ssids_from_roam_params() - copy SSID from roam_params to scan filter + * @roam_params: roam params + * @filter: scan filter + * + * Return void + */ +void csr_copy_ssids_from_roam_params(struct roam_ext_params *roam_params, + struct scan_filter *filter); + +/* + * csr_update_connect_n_roam_cmn_filter() - update common scan filter + * @mac_ctx: pointer to mac context + * @filter: scan filter + * @opmode: opmode + * + * Return void + */ +void csr_update_connect_n_roam_cmn_filter(struct mac_context *mac_ctx, + struct scan_filter *filter, + enum QDF_OPMODE opmode); + +/* + * csr_covert_enc_type_new() - convert csr enc type to wlan enc type + * @enc: csr enc type + * + * Return enum wlan_enc_type + */ +enum wlan_enc_type csr_covert_enc_type_new(eCsrEncryptionType enc); + +/* + * csr_covert_auth_type_new() - convert csr auth type to wlan auth type + * @auth: csr auth type + * + * Return enum wlan_auth_type + */ +enum wlan_auth_type csr_covert_auth_type_new(enum csr_akm_type auth); + +/** + * csr_roam_get_scan_filter_from_profile() - prepare scan filter from + * given roam profile + * @mac: Pointer to Global MAC structure + * @profile: roam profile + * @filter: Populated scan filter based on the connected profile + * @is_roam: if filter is for roam + * + * This function creates a scan filter based on the roam profile. Based on this + * filter, scan results are obtained. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise + */ +QDF_STATUS +csr_roam_get_scan_filter_from_profile(struct mac_context *mac_ctx, + struct csr_roam_profile *profile, + struct scan_filter *filter, + bool is_roam); + +/** + * csr_neighbor_roam_get_scan_filter_from_profile() - prepare scan filter from + * connected profile + * @mac: Pointer to Global MAC structure + * @filter: Populated scan filter based on the connected profile + * @vdev_id: Session ID + * + * This function creates a scan filter based on the currently + * connected profile. Based on this filter, scan results are obtained + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise + */ +QDF_STATUS +csr_neighbor_roam_get_scan_filter_from_profile(struct mac_context *mac, + struct scan_filter *filter, + uint8_t vdev_id); +/* + * csr_scan_get_result() - Return scan results based on filter + * @mac: Pointer to Global MAC structure + * @filter: If pFilter is NULL, all cached results are returned + * @phResult: an object for the result. * - * pFilter - If pFilter is NULL, all cached results are returned - * phResult - an object for the result. * Return QDF_STATUS */ -QDF_STATUS csr_scan_get_result(struct mac_context *mac, tCsrScanResultFilter - *pFilter, tScanResultHandle *phResult); +QDF_STATUS csr_scan_get_result(struct mac_context *mac, + struct scan_filter *filter, + tScanResultHandle *phResult); /** * csr_scan_get_result_for_bssid - gets the scan result from scan cache for the @@ -474,9 +581,18 @@ void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand); bool csr_is_profile_wapi(struct csr_roam_profile *pProfile); #endif /* FEATURE_WLAN_WAPI */ -void csr_get_vdev_type_nss(struct mac_context *mac_ctx, - enum QDF_OPMODE dev_mode, - uint8_t *nss_2g, uint8_t *nss_5g); +/** + * csr_get_vdev_type_nss() - gets the nss value based on vdev type + * @dev_mode: current device operating mode. + * @nss2g: Pointer to the 2G Nss parameter. + * @nss5g: Pointer to the 5G Nss parameter. + * + * Fills the 2G and 5G Nss values based on device mode. + * + * Return: None + */ +void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, + uint8_t *nss_5g); #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR @@ -627,23 +743,6 @@ QDF_STATUS csr_roam_reassoc(struct mac_context *mac, uint32_t sessionId, tCsrRoamModifyProfileFields modProfileFields, uint32_t *pRoamId); -/* - * csr_roam_set_pmkid_cache() - - * return the PMKID candidate list - * - * pPMKIDCache - caller allocated buffer point to an array of tPmkidCacheInfo - * numItems - a variable that has the number of tPmkidCacheInfo allocated - * when retruning, this is either the number needed or number of items put - * into pPMKIDCache - * Return QDF_STATUS - when fail, it usually means the buffer allocated is not - * big enough and pNumItems has the number of tPmkidCacheInfo. - * \Note: pNumItems is a number of tPmkidCacheInfo, not - * sizeof(tPmkidCacheInfo) * something - */ -QDF_STATUS csr_roam_set_pmkid_cache(struct mac_context *mac, uint32_t sessionId, - tPmkidCacheInfo *pPMKIDCache, - uint32_t numItems, bool update_entire_cache); - #ifdef WLAN_FEATURE_ROAM_OFFLOAD /* * csr_get_pmk_info(): store PMK in pmk_cache @@ -825,16 +924,11 @@ QDF_STATUS csr_dequeue_roam_command(struct mac_context *mac, enum csr_roam_reason reason, uint8_t session_id); void csr_init_occupied_channels_list(struct mac_context *mac, uint8_t sessionId); -bool csr_neighbor_roam_connected_profile_match(struct mac_context *mac, - uint8_t sessionId, - struct tag_csrscan_result - *pResult, - tDot11fBeaconIEs *pIes); QDF_STATUS csr_scan_create_entry_in_scan_cache(struct mac_context *mac, uint32_t sessionId, struct qdf_mac_addr bssid, - uint8_t channel); + uint32_t ch_freq); QDF_STATUS csr_update_channel_list(struct mac_context *mac); QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, @@ -842,63 +936,24 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac, tPmkidCacheInfo *pmksa, bool flush_cache); -void csr_roam_del_pmk_cache_entry(struct csr_roam_session *session, - tPmkidCacheInfo *cached_pmksa, u32 del_idx); - -/** - * csr_update_pmk_cache_ft - API to update MDID in PMKSA cache entry - * @mac: Mac context - * @vdev_id: session ID - * @BSSID: Connecting AP MAC address - * @mdid: Connecting AP Mobility Domain ID - * - * Return: None - */ -void csr_update_pmk_cache_ft(struct mac_context *mac, - uint32_t vdev_id, uint8_t *cache_id); - #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) -/** - * csr_set_sae_single_pmk_bss_cap - API to set the peer SAE single pmk - * feature supported status - * @session: sme session pointer - * @single_pmk_capable_bss: Flag to indicate SAE single pmk supported BSSID or - * not - * @bssid: BSSID for which the flag is to be set - * - * Return : None - */ -void csr_set_sae_single_pmk_bss_cap(struct csr_roam_session *session, - bool single_pmk_capable_bss, - struct qdf_mac_addr *bssid); - /** * csr_clear_sae_single_pmk - API to clear single_pmk_info cache - * @pmac: mac context + * @psoc: psoc common object * @vdev_id: session id * @pmksa: pmk info * * Return : None */ -void csr_clear_sae_single_pmk(struct mac_context *mac, +void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, tPmkidCacheInfo *pmksa); void csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac, struct csr_roam_session *session, uint8_t vdev_id); - -void csr_set_sae_single_pmk_info(struct csr_roam_session *session, - tPmkidCacheInfo *roam_sync_pmksa); #else -static inline -void csr_set_sae_single_pmk_bss_cap(struct csr_roam_session *session, - bool single_pmk_capable_bss, - struct qdf_mac_addr *bssid) -{ -} - static inline void -csr_clear_sae_single_pmk(struct mac_context *mac, uint8_t vdev_id, +csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, tPmkidCacheInfo *pmksa) { } @@ -908,12 +963,6 @@ void csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac, struct csr_roam_session *session, uint8_t vdev_id) {} - -static inline void -csr_set_sae_single_pmk_info(struct csr_roam_session *session, - tPmkidCacheInfo *roam_sync_pmksa) -{ -} #endif QDF_STATUS csr_send_ext_change_channel(struct mac_context *mac_ctx, @@ -1020,14 +1069,27 @@ enum band_info csr_get_rf_band(uint8_t channel); * @mac: pointer to mac * @session: sme session pointer * @pmk_cache: pointer to pmk cache - * @index: index value needs to be seached * * Return: true if pmkid is found else false */ bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, struct csr_roam_session *session, - tPmkidCacheInfo *pmk_cache, - uint32_t *index); + tPmkidCacheInfo *pmk_cache); + +/** + * csr_lookup_fils_pmkid - Lookup FILS PMKID using ssid and cache id + * @mac: Pointer to mac context + * @vdev_id: vdev id + * @cache_id: FILS cache id + * @ssid: SSID pointer + * @ssid_len: SSID length + * @bssid: Pointer to the BSSID to lookup + * + * Return: True if lookup is successful + */ +bool csr_lookup_fils_pmkid(struct mac_context *mac, uint8_t vdev_id, + uint8_t *cache_id, uint8_t *ssid, + uint8_t ssid_len, struct qdf_mac_addr *bssid); /** * csr_is_pmkid_found_for_peer() - check if pmkid sent by peer is present in PMK cache. Used in SAP mode. @@ -1072,10 +1134,10 @@ static inline void csr_init_session_twt_cap(struct csr_roam_session *session, * This function is written to find out for any bss from scan * handle a HW mode change to DBS will be needed or not. * - * Return: AP channel for which DBS HW mode will be needed. 0 + * Return: AP channel freq for which DBS HW mode will be needed. 0 * means no HW mode change is needed. */ -uint8_t +uint32_t csr_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, tScanResultHandle result_handle, uint32_t session_id); @@ -1095,13 +1157,23 @@ csr_get_channel_for_hw_mode_change(struct mac_context *mac_ctx, * If there is no candidate AP which requires DBS, this function will return * the first Candidate AP's chan. * - * Return: AP channel for which HW mode change will be needed. 0 + * Return: AP channel freq for which HW mode change will be needed. 0 * means no candidate AP to connect. */ -uint8_t +uint32_t csr_scan_get_channel_for_hw_mode_change( struct mac_context *mac_ctx, uint32_t session_id, struct csr_roam_profile *profile); +/** + * csr_setup_vdev_session() - API to setup vdev mac session + * @vdev_mlme: vdev mlme private object + * + * This API setsup the vdev session for the mac layer + * + * Returns: QDF_STATUS + */ +QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme); + #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR /** diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_neighbor_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_neighbor_roam.c index 4868ba7fe4db5c6f240b13d74f871e70923f2c66..487e43f9f572ba1635c43f8d147772e493499353 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_neighbor_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_neighbor_roam.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -129,15 +128,9 @@ QDF_STATUS csr_neighbor_roam_update_fast_roaming_enabled(struct mac_context *mac const bool fast_roam_enabled) { QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - tpCsrNeighborRoamControlInfo neighbor_roam_info; - - if (!session) { - sme_err("session_id invalid %d", session_id); - return QDF_STATUS_E_FAILURE; - } + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[session_id]; - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[session_id]; switch (neighbor_roam_info->neighborRoamState) { case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED: qdf_status = sme_acquire_global_lock(&mac_ctx->sme); @@ -246,12 +239,9 @@ static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; rChInfo->currentChannelListInfo.numOfChannels = 0; - - if (rChInfo->currentChannelListInfo.ChannelList) - qdf_mem_free(rChInfo->currentChannelListInfo. - ChannelList); - - rChInfo->currentChannelListInfo.ChannelList = NULL; + if (rChInfo->currentChannelListInfo.freq_list) + qdf_mem_free(rChInfo->currentChannelListInfo.freq_list); + rChInfo->currentChannelListInfo.freq_list = NULL; } else { rChInfo->currentChanIndex = 0; } @@ -343,146 +333,90 @@ csr_update_pmf_cap_from_connected_profile(tCsrRoamConnectedProfile *profile, if (profile->MFPRequired) filter->pmf_cap = WLAN_PMF_REQUIRED; } +#else +void +csr_update_pmf_cap_from_connected_profile(tCsrRoamConnectedProfile *profile, + struct scan_filter *filter) +{} #endif -/** - * csr_neighbor_roam_prepare_scan_profile_filter() - * - * @mac_ctx: Pointer to Global MAC structure - * @session_id: Session ID - * @scan_filter: Populated scan filter based on the connected profile - * - * This function creates a scan filter based on the currently - * connected profile. Based on this filter, scan results are obtained - * - * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise - */ QDF_STATUS -csr_neighbor_roam_prepare_scan_profile_filter(struct mac_context *mac, - tCsrScanResultFilter *pScanFilter, - uint8_t sessionId) +csr_neighbor_roam_get_scan_filter_from_profile(struct mac_context *mac, + struct scan_filter *filter, + uint8_t vdev_id) { - tpCsrNeighborRoamControlInfo nbr_roam_info = - &mac->roam.neighborRoamInfo[sessionId]; - tCsrRoamConnectedProfile *pCurProfile = - &mac->roam.roamSession[sessionId].connectedProfile; - uint8_t i = 0; + tpCsrNeighborRoamControlInfo nbr_roam_info; + tCsrRoamConnectedProfile *profile; struct roam_ext_params *roam_params; + tCsrChannelInfo *chan_info; uint8_t num_ch = 0; + enum QDF_OPMODE opmode = QDF_STA_MODE; - QDF_ASSERT(pScanFilter); - if (!pScanFilter) + if (!filter) + return QDF_STATUS_E_FAILURE; + if (!CSR_IS_SESSION_VALID(mac, vdev_id)) return QDF_STATUS_E_FAILURE; - qdf_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter)); + qdf_mem_zero(filter, sizeof(*filter)); + nbr_roam_info = &mac->roam.neighborRoamInfo[vdev_id]; + profile = &mac->roam.roamSession[vdev_id].connectedProfile; roam_params = &mac->roam.configParam.roam_params; - /* We dont want to set BSSID based Filter */ - pScanFilter->BSSIDs.numOfBSSIDs = 0; - pScanFilter->scan_filter_for_roam = 1; + /* only for HDD requested handoff fill in the BSSID in the filter */ if (nbr_roam_info->uOsRequestedHandoff) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("OS Requested Handoff")); - pScanFilter->BSSIDs.numOfBSSIDs = 1; - pScanFilter->BSSIDs.bssid = - qdf_mem_malloc(sizeof(tSirMacAddr) * - pScanFilter->BSSIDs.numOfBSSIDs); - if (!pScanFilter->BSSIDs.bssid) - return QDF_STATUS_E_NOMEM; - - /* Populate the BSSID from handoff info received from HDD */ - for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) { - qdf_copy_macaddr(&pScanFilter->BSSIDs.bssid[i], - &nbr_roam_info->handoffReqInfo.bssid); - } + sme_debug("OS Requested Handoff"); + filter->num_of_bssid = 1; + qdf_mem_copy(filter->bssid_list[0].bytes, + &nbr_roam_info->handoffReqInfo.bssid.bytes, + QDF_MAC_ADDR_SIZE); } - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - FL("No of Allowed SSID List:%d"), - roam_params->num_ssid_allowed_list); - if (roam_params->num_ssid_allowed_list) { - pScanFilter->SSIDs.numOfSSIDs = - roam_params->num_ssid_allowed_list; - pScanFilter->SSIDs.SSIDList = - qdf_mem_malloc(sizeof(tCsrSSIDInfo) * - pScanFilter->SSIDs.numOfSSIDs); - if (!pScanFilter->SSIDs.SSIDList) { - qdf_mem_free(pScanFilter->BSSIDs.bssid); - pScanFilter->BSSIDs.bssid = NULL; - return QDF_STATUS_E_NOMEM; - } + sme_debug("No of Allowed SSID List:%d", + roam_params->num_ssid_allowed_list); - for (i = 0; i < roam_params->num_ssid_allowed_list; i++) { - pScanFilter->SSIDs.SSIDList[i].handoffPermitted = 1; - pScanFilter->SSIDs.SSIDList[i].ssidHidden = 0; - qdf_mem_copy((void *) - pScanFilter->SSIDs.SSIDList[i].SSID.ssId, - roam_params->ssid_allowed_list[i].ssId, - roam_params->ssid_allowed_list[i].length); - pScanFilter->SSIDs.SSIDList[i].SSID.length = - roam_params->ssid_allowed_list[i].length; - } + if (roam_params->num_ssid_allowed_list) { + csr_copy_ssids_from_roam_params(roam_params, filter); } else { - /* Populate all the information from the connected profile */ - pScanFilter->SSIDs.numOfSSIDs = 1; - pScanFilter->SSIDs.SSIDList = - qdf_mem_malloc(sizeof(tCsrSSIDInfo)); - if (!pScanFilter->SSIDs.SSIDList) { - qdf_mem_free(pScanFilter->BSSIDs.bssid); - pScanFilter->BSSIDs.bssid = NULL; - return QDF_STATUS_E_NOMEM; - } + filter->num_of_ssid = 1; - pScanFilter->SSIDs.SSIDList->handoffPermitted = 1; - pScanFilter->SSIDs.SSIDList->ssidHidden = 0; - pScanFilter->SSIDs.SSIDList->SSID.length = - pCurProfile->SSID.length; - qdf_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, - (void *)pCurProfile->SSID.ssId, - pCurProfile->SSID.length); + filter->ssid_list[0].length = profile->SSID.length; + if (filter->ssid_list[0].length > WLAN_SSID_MAX_LEN) + filter->ssid_list[0].length = WLAN_SSID_MAX_LEN; + qdf_mem_copy(filter->ssid_list[0].ssid, + profile->SSID.ssId, + filter->ssid_list[0].length); sme_debug("Filtering for SSID %.*s,length of SSID = %u", - pScanFilter->SSIDs.SSIDList->SSID.length, - pScanFilter->SSIDs.SSIDList->SSID.ssId, - pScanFilter->SSIDs.SSIDList->SSID.length); + filter->ssid_list[0].length, + filter->ssid_list[0].ssid, + filter->ssid_list[0].length); } - pScanFilter->authType.numEntries = 1; - pScanFilter->authType.authType[0] = pCurProfile->AuthType; - - pScanFilter->EncryptionType.numEntries = 1; /* This must be 1 */ - pScanFilter->EncryptionType.encryptionType[0] = - pCurProfile->EncryptionType; - - pScanFilter->mcEncryptionType.numEntries = 1; - pScanFilter->mcEncryptionType.encryptionType[0] = - pCurProfile->mcEncryptionType; - - pScanFilter->BSSType = pCurProfile->BSSType; - num_ch = - nbr_roam_info->roamChannelInfo.currentChannelListInfo.numOfChannels; + filter->num_of_auth = 1; + filter->auth_type[0] = csr_covert_auth_type_new(profile->AuthType); + filter->num_of_enc_type = 1; + filter->enc_type[0] = + csr_covert_enc_type_new(profile->EncryptionType); + filter->num_of_mc_enc_type = 1; + filter->mc_enc_type[0] = + csr_covert_enc_type_new(profile->mcEncryptionType); + + if (profile->BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE) + filter->bss_type = WLAN_TYPE_BSS; + else if (profile->BSSType == eCSR_BSS_TYPE_IBSS || + profile->BSSType == eCSR_BSS_TYPE_START_IBSS) + filter->bss_type = WLAN_TYPE_IBSS; + else + filter->bss_type = WLAN_TYPE_ANY; + + chan_info = &nbr_roam_info->roamChannelInfo.currentChannelListInfo; + num_ch = chan_info->numOfChannels; if (num_ch) { - /* - * We are intrested only in the scan results on channels we - * scanned - */ - pScanFilter->ChannelInfo.numOfChannels = num_ch; - pScanFilter->ChannelInfo.ChannelList = - qdf_mem_malloc(num_ch * sizeof(uint8_t)); - if (!pScanFilter->ChannelInfo.ChannelList) { - qdf_mem_free(pScanFilter->BSSIDs.bssid); - pScanFilter->BSSIDs.bssid = NULL; - qdf_mem_free(pScanFilter->SSIDs.SSIDList); - pScanFilter->SSIDs.SSIDList = NULL; - return QDF_STATUS_E_NOMEM; - } - for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++) { - pScanFilter->ChannelInfo.ChannelList[i] = - nbr_roam_info->roamChannelInfo.currentChannelListInfo. - ChannelList[i]; - } - } else { - pScanFilter->ChannelInfo.numOfChannels = 0; - pScanFilter->ChannelInfo.ChannelList = NULL; + filter->num_of_channels = num_ch; + if (filter->num_of_channels > NUM_CHANNELS) + filter->num_of_channels = NUM_CHANNELS; + qdf_mem_copy(filter->chan_freq_list, chan_info->freq_list, + filter->num_of_channels * + sizeof(filter->chan_freq_list[0])); } if (nbr_roam_info->is11rAssoc) @@ -490,13 +424,12 @@ csr_neighbor_roam_prepare_scan_profile_filter(struct mac_context *mac, * MDIE should be added as a part of profile. This should be * added as a part of filter as well */ - pScanFilter->mdid = pCurProfile->mdid; + filter->mobility_domain = profile->mdid.mobility_domain; + + csr_update_pmf_cap_from_connected_profile(profile, filter); + + csr_update_connect_n_roam_cmn_filter(mac, filter, opmode); -#ifdef WLAN_FEATURE_11W - pScanFilter->MFPEnabled = pCurProfile->MFPEnabled; - pScanFilter->MFPRequired = pCurProfile->MFPRequired; - pScanFilter->MFPCapable = pCurProfile->MFPCapable; -#endif return QDF_STATUS_SUCCESS; } @@ -518,9 +451,9 @@ enum band_info csr_get_rf_band(uint8_t channel) * * @mac_ctx: Pointer to Global MAC structure * @session_id: Session ID - * @input_ch_list: The input channel list + * @input_chan_freq_list: The input channel list * @input_num_of_ch: The number of channels in input channel list - * @output_ch_list: The output channel list + * @out_chan_freq_list: The output channel list * @output_num_of_ch: The number of channels in output channel list * @merged_output_num_of_ch: The final number of channels in the * output channel list. @@ -533,22 +466,22 @@ enum band_info csr_get_rf_band(uint8_t channel) QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(struct mac_context * mac, uint8_t sessionId, - uint8_t *pInputChannelList, + uint32_t *input_chan_freq_list, uint8_t inputNumOfChannels, - uint8_t *pOutputChannelList, + uint32_t *out_chan_freq_list, uint8_t * pMergedOutputNumOfChannels) { uint8_t i = 0; uint8_t numChannels = 0; - uint8_t currAPoperationChannel = - mac->roam.neighborRoamInfo[sessionId].currAPoperationChannel; + uint32_t curr_ap_op_chan_freq = + mac->roam.neighborRoamInfo[sessionId].curr_ap_op_chan_freq; /* Check for NULL pointer */ - if (!pInputChannelList) + if (!input_chan_freq_list) return QDF_STATUS_E_INVAL; /* Check for NULL pointer */ - if (!pOutputChannelList) + if (!out_chan_freq_list) return QDF_STATUS_E_INVAL; if (inputNumOfChannels > CFG_VALID_CHANNEL_LIST_LEN) { @@ -558,9 +491,11 @@ QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(struct mac_context return QDF_STATUS_E_INVAL; } for (i = 0; i < inputNumOfChannels; i++) { - if (csr_get_rf_band(currAPoperationChannel) == - csr_get_rf_band(pInputChannelList[i])) { - pOutputChannelList[numChannels] = pInputChannelList[i]; + if (WLAN_REG_IS_SAME_BAND_FREQS( + curr_ap_op_chan_freq, + input_chan_freq_list[i])) { + out_chan_freq_list[numChannels] = + input_chan_freq_list[i]; numChannels++; } } @@ -575,11 +510,10 @@ QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(struct mac_context * csr_neighbor_roam_channels_filter_by_current_band() * * @mac_ctx: Pointer to Global MAC structure - * @session_id: Session ID - * @input_ch_list: The additional channels to merge in to the - * "merged" channels list. + * @pinput_chan_freq_list: The additional channels to merge in + * to the "merged" channels list. * @input_num_of_ch: The number of additional channels. - * @output_ch_list: The place to put the "merged" channel list. + * @out_chan_freq_list: The place to put the "merged" channel list. * @output_num_of_ch: The original number of channels in the * "merged" channels list. * @merged_output_num_of_ch: The final number of channels in the @@ -593,9 +527,9 @@ QDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(struct mac_context * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise */ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac, - uint8_t *pInputChannelList, + uint32_t *pinput_chan_freq_list, uint8_t inputNumOfChannels, - uint8_t *pOutputChannelList, + uint32_t *out_chan_freq_list, uint8_t outputNumOfChannels, uint8_t * pMergedOutputNumOfChannels) @@ -605,11 +539,11 @@ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac, uint8_t numChannels = outputNumOfChannels; /* Check for NULL pointer */ - if (!pInputChannelList) + if (!pinput_chan_freq_list) return QDF_STATUS_E_INVAL; /* Check for NULL pointer */ - if (!pOutputChannelList) + if (!out_chan_freq_list) return QDF_STATUS_E_INVAL; if (inputNumOfChannels > CFG_VALID_CHANNEL_LIST_LEN) { @@ -629,17 +563,18 @@ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac, */ for (i = 0; i < inputNumOfChannels; i++) { for (j = 0; j < outputNumOfChannels; j++) { - if (pInputChannelList[i] == pOutputChannelList[j]) + if (pinput_chan_freq_list[i] + == out_chan_freq_list[j]) break; } if (j == outputNumOfChannels) { - if (pInputChannelList[i]) { + if (pinput_chan_freq_list[i]) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s: [INFOLOG] Adding extra %d to Neighbor channel list", - __func__, pInputChannelList[i]); - pOutputChannelList[numChannels] = - pInputChannelList[i]; + __func__, pinput_chan_freq_list[i]); + out_chan_freq_list[numChannels] = + pinput_chan_freq_list[i]; numChannels++; } } @@ -657,101 +592,6 @@ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac, return QDF_STATUS_SUCCESS; } -/** - * csr_neighbor_roam_is_ssid_and_security_match() - to match ssid/security - * @mac: Pointer to mac context - * @pCurProfile: pointer to current roam profile - * @bss_desc: pointer to bss description - * @pIes: pointer to local ies - * @session_id: Session ID - * - * This routine will be called to see if SSID and security parameters - * are matching. - * - * Return: bool - */ -static bool csr_neighbor_roam_is_ssid_and_security_match(struct mac_context *mac, - tCsrRoamConnectedProfile *pCurProfile, - struct bss_description *bss_desc, tDot11fBeaconIEs *pIes, - uint8_t session_id) -{ - tCsrAuthList authType; - tCsrEncryptionList uCEncryptionType; - tCsrEncryptionList mCEncryptionType; - bool fMatch = false; - - authType.numEntries = 1; - authType.authType[0] = pCurProfile->AuthType; - uCEncryptionType.numEntries = 1; - uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType; - mCEncryptionType.numEntries = 1; - mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType; - - /* Again, treat missing pIes as a non-match. */ - if (!pIes) - return false; - - /* Treat a missing SSID as a non-match. */ - if (!pIes->SSID.present) - return false; - - fMatch = csr_is_ssid_match(mac, - (void *)pCurProfile->SSID.ssId, - pCurProfile->SSID.length, - pIes->SSID.ssid, - pIes->SSID.num_ssid, true); - if (true == fMatch) { -#ifdef WLAN_FEATURE_11W - /* - * We are sending current connected APs profile setting - * if other AP doesn't have the same PMF setting as currently - * connected AP then we will have some issues in roaming. - * - * Make sure all the APs have same PMF settings to avoid - * any corner cases. - */ - fMatch = csr_is_security_match(mac, &authType, - &uCEncryptionType, &mCEncryptionType, - &pCurProfile->MFPEnabled, - &pCurProfile->MFPRequired, - &pCurProfile->MFPCapable, - bss_desc, pIes, session_id); -#else - fMatch = csr_is_security_match(mac, &authType, - &uCEncryptionType, - &mCEncryptionType, NULL, - NULL, NULL, bss_desc, - pIes, session_id); -#endif - return fMatch; - } else { - return fMatch; - } - -} - -bool csr_neighbor_roam_connected_profile_match(struct mac_context *mac, - uint8_t sessionId, - struct tag_csrscan_result - *pResult, - tDot11fBeaconIEs *pIes) -{ - tCsrRoamConnectedProfile *pCurProfile = NULL; - struct bss_description *bss_desc = &pResult->Result.BssDescriptor; - - if (!(mac->roam.roamSession && CSR_IS_SESSION_VALID(mac, sessionId))) - return false; - - pCurProfile = &mac->roam.roamSession[sessionId].connectedProfile; - - if (!pCurProfile) - return false; - - return csr_neighbor_roam_is_ssid_and_security_match(mac, pCurProfile, - bss_desc, pIes, - sessionId); -} - /** * csr_roam_reset_roam_params - API to reset the roaming parameters * @mac_ctx: Pointer to the global MAC structure @@ -826,9 +666,9 @@ QDF_STATUS csr_neighbor_roam_indicate_disconnect(struct mac_context *mac, } QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, FL("Disconn ind on session %d in state %d from bss :" - QDF_MAC_ADDR_STR), sessionId, + QDF_MAC_ADDR_FMT), sessionId, pNeighborRoamInfo->neighborRoamState, - QDF_MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes)); + QDF_MAC_ADDR_REF(pSession->connectedProfile.bssid.bytes)); /* * Free the current previous profile and move * the current profile to prev profile. @@ -852,8 +692,6 @@ QDF_STATUS csr_neighbor_roam_indicate_disconnect(struct mac_context *mac, sizeof(tSirMacSSid)); qdf_copy_macaddr(&pSession->prevApBssid, &pSession->connectedProfile.bssid); - pSession->prevOpChannel = - pSession->connectedProfile.operationChannel; pSession->isPrevApInfoValid = true; pSession->roamTS1 = qdf_mc_timer_get_system_time(); } @@ -966,8 +804,8 @@ static void csr_neighbor_roam_info_ctx_init(struct mac_context *mac, qdf_copy_macaddr(&ngbr_roam_info->currAPbssid, &session->connectedProfile.bssid); - ngbr_roam_info->currAPoperationChannel = - session->connectedProfile.operationChannel; + ngbr_roam_info->curr_ap_op_chan_freq = + session->connectedProfile.op_freq; ngbr_roam_info->currentNeighborLookupThreshold = ngbr_roam_info->cfgParams.neighborLookupThreshold; ngbr_roam_info->currentOpportunisticThresholdDiff = @@ -1262,22 +1100,25 @@ QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId) mac->mlme_cfg->lfr.neighbor_scan_channel_list_num; sme_debug("number of channels: %u", specific_chan_info->numOfChannels); if (specific_chan_info->numOfChannels != 0) { - specific_chan_info->ChannelList = - qdf_mem_malloc(specific_chan_info->numOfChannels); - - if (!specific_chan_info->ChannelList) { + specific_chan_info->freq_list = + qdf_mem_malloc(sizeof(uint32_t) * + specific_chan_info->numOfChannels); + if (!specific_chan_info->freq_list) { specific_chan_info->numOfChannels = 0; return QDF_STATUS_E_NOMEM; } + } else { - specific_chan_info->ChannelList = NULL; + specific_chan_info->freq_list = NULL; } /* Update the roam global structure from CFG */ - qdf_mem_copy(pNeighborRoamInfo->cfgParams.specific_chan_info. - ChannelList, - mac->mlme_cfg->lfr.neighbor_scan_channel_list, - mac->mlme_cfg->lfr.neighbor_scan_channel_list_num); + sme_chan_to_freq_list(mac->pdev, + specific_chan_info->freq_list, + mac->mlme_cfg->lfr.neighbor_scan_channel_list, + mac->mlme_cfg->lfr. + neighbor_scan_channel_list_num); + pNeighborRoamInfo->cfgParams.hi_rssi_scan_max_count = mac->mlme_cfg->lfr.roam_scan_hi_rssi_maxcount; pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_delta = @@ -1308,8 +1149,8 @@ QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId) status = csr_ll_open(&pNeighborRoamInfo->roamableAPList); if (QDF_STATUS_SUCCESS != status) { sme_err("LL Open of roam able AP List failed"); - qdf_mem_free(specific_chan_info->ChannelList); - specific_chan_info->ChannelList = NULL; + qdf_mem_free(specific_chan_info->freq_list); + specific_chan_info->freq_list = NULL; specific_chan_info->numOfChannels = 0; return QDF_STATUS_E_RESOURCES; } @@ -1318,15 +1159,14 @@ QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId) CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo. numOfChannels = 0; - pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.freq_list = NULL; pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false; status = csr_neighbor_roam_init11r_assoc_info(mac); if (QDF_STATUS_SUCCESS != status) { sme_err("LL Open of roam able AP List failed"); - qdf_mem_free(specific_chan_info->ChannelList); - specific_chan_info->ChannelList = NULL; + specific_chan_info->freq_list = NULL; specific_chan_info->numOfChannels = 0; csr_ll_close(&pNeighborRoamInfo->roamableAPList); return QDF_STATUS_E_RESOURCES; @@ -1352,6 +1192,8 @@ QDF_STATUS csr_neighbor_roam_init(struct mac_context *mac, uint8_t sessionId) */ void csr_neighbor_roam_close(struct mac_context *mac, uint8_t sessionId) { + tCsrChannelInfo *current_channel_list_info; + tCsrNeighborRoamCfgParams *cfg_params; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &mac->roam.neighborRoamInfo[sessionId]; @@ -1360,10 +1202,11 @@ void csr_neighbor_roam_close(struct mac_context *mac, uint8_t sessionId) sme_warn("Neighbor Roam Algorithm Already Closed"); return; } - - qdf_mem_free(pNeighborRoamInfo->cfgParams.specific_chan_info. - ChannelList); - pNeighborRoamInfo->cfgParams.specific_chan_info.ChannelList = NULL; + cfg_params = &pNeighborRoamInfo->cfgParams; + if (cfg_params->specific_chan_info.freq_list) + qdf_mem_free(cfg_params->specific_chan_info.freq_list); + pNeighborRoamInfo->cfgParams.specific_chan_info.freq_list = NULL; + pNeighborRoamInfo->cfgParams.specific_chan_info.numOfChannels = 0; /* Should free up the nodes in the list before closing the * double Linked list @@ -1372,18 +1215,15 @@ void csr_neighbor_roam_close(struct mac_context *mac, uint8_t sessionId) &pNeighborRoamInfo->roamableAPList); csr_ll_close(&pNeighborRoamInfo->roamableAPList); - if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo. - ChannelList) { - qdf_mem_free(pNeighborRoamInfo->roamChannelInfo. - currentChannelListInfo.ChannelList); - } + current_channel_list_info = + &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + if (current_channel_list_info->freq_list) + qdf_mem_free(current_channel_list_info->freq_list); - pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = - NULL; + current_channel_list_info->freq_list = NULL; pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; - pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo. - numOfChannels = 0; + current_channel_list_info->numOfChannels = 0; pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false; /* Free the profile.. */ @@ -1458,7 +1298,7 @@ static QDF_STATUS csr_neighbor_roam_process_handoff_req( uint8_t i = 0; uint8_t roam_now = 0; uint8_t roamable_ap_count = 0; - tCsrScanResultFilter scan_filter; + struct scan_filter *scan_filter; tScanResultHandle scan_result; if (!session) { @@ -1497,18 +1337,19 @@ static QDF_STATUS csr_neighbor_roam_process_handoff_req( } profile->ChannelInfo.numOfChannels = 1; - if (!profile->ChannelInfo.ChannelList) { - profile->ChannelInfo.ChannelList = - qdf_mem_malloc(sizeof(*profile-> - ChannelInfo.ChannelList) * - profile->ChannelInfo.numOfChannels); - if (!profile->ChannelInfo.ChannelList) { + if (!profile->ChannelInfo.freq_list) { + profile->ChannelInfo.freq_list = + qdf_mem_malloc(sizeof(*profile->ChannelInfo.freq_list) * + profile->ChannelInfo.numOfChannels); + if (!profile->ChannelInfo.freq_list) { + profile->ChannelInfo.numOfChannels = 0; status = QDF_STATUS_E_NOMEM; goto end; } } - profile->ChannelInfo.ChannelList[0] = - roam_ctrl_info->handoffReqInfo.channel; + + profile->ChannelInfo.freq_list[0] = + roam_ctrl_info->handoffReqInfo.ch_freq; /* * For User space connect requests, the scan has already been done. @@ -1517,17 +1358,22 @@ static QDF_STATUS csr_neighbor_roam_process_handoff_req( */ if (roam_ctrl_info->handoffReqInfo.src == CONNECT_CMD_USERSPACE) { sme_debug("Connect cmd with bssid within same ESS"); - status = csr_neighbor_roam_prepare_scan_profile_filter(mac_ctx, - &scan_filter, + scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); + if (!scan_filter) { + status = QDF_STATUS_E_NOMEM; + goto end; + } + status = csr_neighbor_roam_get_scan_filter_from_profile(mac_ctx, + scan_filter, session_id); sme_debug("Filter creation status: %d", status); - status = csr_scan_get_result(mac_ctx, &scan_filter, + status = csr_scan_get_result(mac_ctx, scan_filter, &scan_result); + qdf_mem_free(scan_filter); csr_neighbor_roam_process_scan_results(mac_ctx, session_id, &scan_result); roamable_ap_count = csr_ll_count( &roam_ctrl_info->roamableAPList); - csr_free_scan_filter(mac_ctx, &scan_filter); sme_debug("roam_now=%d, roamable_ap_count=%d", roam_now, roamable_ap_count); } @@ -1579,10 +1425,8 @@ QDF_STATUS csr_neighbor_roam_sssid_scan_done(struct mac_context *mac, if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err("Add an entry to csr scan cache"); hstatus = csr_scan_create_entry_in_scan_cache(mac, sessionId, - pNeighborRoamInfo-> - handoffReqInfo.bssid, - pNeighborRoamInfo-> - handoffReqInfo.channel); + pNeighborRoamInfo->handoffReqInfo.bssid, + pNeighborRoamInfo->handoffReqInfo.ch_freq); if (QDF_STATUS_SUCCESS != hstatus) { sme_err( "csr_scan_create_entry_in_scan_cache failed with status %d", @@ -1645,8 +1489,7 @@ QDF_STATUS csr_neighbor_roam_handoff_req_hdlr( sme_err("Received req has same BSSID as current AP!!"); return QDF_STATUS_E_FAILURE; } - roam_ctrl_info->handoffReqInfo.channel = - handoff_req->channel; + roam_ctrl_info->handoffReqInfo.ch_freq = handoff_req->ch_freq; roam_ctrl_info->handoffReqInfo.src = handoff_req->handoff_src; qdf_mem_copy(&roam_ctrl_info->handoffReqInfo.bssid.bytes, diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_roam_preauth.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_roam_preauth.c index a296a23b53c3592373b559356d66f00cc9db59c1..4a02b2b13644f3ef9d459985d41f0b353c2d835d 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_roam_preauth.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_roam_preauth.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -117,7 +116,7 @@ QDF_STATUS csr_roam_enqueue_preauth(struct mac_context *mac_ctx, } else { if (bss_desc) { command->command = eSmeCommandRoam; - command->sessionId = (uint8_t) session_id; + command->vdev_id = (uint8_t) session_id; command->u.roamCmd.roamReason = reason; command->u.roamCmd.pLastRoamBss = bss_desc; status = csr_queue_sme_command(mac_ctx, command, @@ -204,20 +203,13 @@ QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(struct mac_context *mac_ctx, uint8_t session_id, QDF_STATUS lim_status) { - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - tpCsrNeighborRoamControlInfo neighbor_roam_info; + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[session_id]; QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS preauth_processed = QDF_STATUS_SUCCESS; tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL; uint8_t reason; - if (!session) { - sme_err("session_id invalid %d", session_id); - preauth_processed = QDF_STATUS_E_FAILURE; - goto DEQ_PREAUTH; - } - - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[session_id]; if (false == neighbor_roam_info->FTRoamInfo.preauthRspPending) { /* * This can happen when we disconnect immediately @@ -249,11 +241,11 @@ QDF_STATUS csr_neighbor_roam_preauth_rsp_handler(struct mac_context *mac_ctx, NULL); if ((QDF_STATUS_SUCCESS == lim_status) && (preauth_rsp_node)) { sme_debug("Preauth completed successfully after %d tries", - neighbor_roam_info->FTRoamInfo.numPreAuthRetries); - sme_debug("After Pre-Auth: BSSID " QDF_MAC_ADDR_STR ", Ch:%d", - QDF_MAC_ADDR_ARRAY( + neighbor_roam_info->FTRoamInfo.numPreAuthRetries); + sme_debug("After Pre-Auth: BSSID " QDF_MAC_ADDR_FMT ", ChFq:%d", + QDF_MAC_ADDR_REF( preauth_rsp_node->pBssDescription->bssId), - (int)preauth_rsp_node->pBssDescription->channelId); + preauth_rsp_node->pBssDescription->chan_freq); csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id, preauth_rsp_node->pBssDescription->bssId, @@ -385,21 +377,13 @@ static QDF_STATUS csr_neighbor_roam_add_preauth_fail(struct mac_context *mac_ctx uint8_t session_id, tSirMacAddr bssid) { uint8_t i = 0; - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - tpCsrNeighborRoamControlInfo neighbor_roam_info; - uint8_t num_mac_addr; - - if (!session) { - sme_err("session_id invalid %d", session_id); - return QDF_STATUS_E_FAILURE; - } - - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[session_id]; - num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList. + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[session_id]; + uint8_t num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList. numMACAddress; - sme_warn("Added BSSID " QDF_MAC_ADDR_STR " to Preauth failed list", - QDF_MAC_ADDR_ARRAY(bssid)); + sme_warn("Added BSSID " QDF_MAC_ADDR_FMT " to Preauth failed list", + QDF_MAC_ADDR_REF(bssid)); for (i = 0; i < neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress; @@ -407,8 +391,8 @@ static QDF_STATUS csr_neighbor_roam_add_preauth_fail(struct mac_context *mac_ctx if (!qdf_mem_cmp( neighbor_roam_info->FTRoamInfo.preAuthFailList.macAddress[i], bssid, sizeof(tSirMacAddr))) { - sme_warn("BSSID "QDF_MAC_ADDR_STR" already fail list", - QDF_MAC_ADDR_ARRAY(bssid)); + sme_warn("BSSID "QDF_MAC_ADDR_FMT" already fail list", + QDF_MAC_ADDR_REF(bssid)); return QDF_STATUS_SUCCESS; } } @@ -453,8 +437,8 @@ bool csr_neighbor_roam_is_preauth_candidate(struct mac_context *mac, if (!qdf_mem_cmp(pNeighborRoamInfo->FTRoamInfo. preAuthFailList.macAddress[i], bssId, sizeof(tSirMacAddr))) { - sme_err("BSSID exists in fail list" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(bssId)); + sme_err("BSSID exists in fail list" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssId)); return false; } } @@ -507,7 +491,7 @@ static uint32_t csr_get_dot11_mode(struct mac_context *mac_ctx, ucfg_dot11_mode = cfg_dot11_mode; else { sme_err("Can not find match phy mode"); - if (WLAN_REG_IS_5GHZ_CH(bss_desc->channelId)) + if (WLAN_REG_IS_5GHZ_CH_FREQ(bss_desc->chan_freq)) ucfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A; else ucfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G; @@ -519,9 +503,9 @@ static uint32_t csr_get_dot11_mode(struct mac_context *mac_ctx, sme_debug("dot11mode %d ucfg_dot11_mode %d", dot11mode, ucfg_dot11_mode); - if (bss_desc->channelId <= 14 && - !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && - MLME_DOT11_MODE_11AC == dot11mode) { + if (bss_desc->chan_freq <= CDS_CHAN_14_FREQ && + !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && + MLME_DOT11_MODE_11AC == dot11mode) { /* Need to disable VHT operation in 2.4 GHz band */ dot11mode = MLME_DOT11_MODE_11N; } @@ -530,7 +514,7 @@ static uint32_t csr_get_dot11_mode(struct mac_context *mac_ctx, } QDF_STATUS csr_roam_issue_ft_preauth_req(struct mac_context *mac_ctx, - uint32_t session_id, + uint32_t vdev_id, struct bss_description *bss_desc) { tpSirFTPreAuthReq preauth_req; @@ -539,15 +523,14 @@ QDF_STATUS csr_roam_issue_ft_preauth_req(struct mac_context *mac_ctx, uint32_t dot11mode, buf_len; QDF_STATUS status; struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx, - session_id); + vdev_id); if (!csr_session) { - sme_err("Session does not exist for session id: %d", - session_id); + sme_err("Session does not exist for vdev_id: %d", vdev_id); return QDF_STATUS_E_FAILURE; } - dot11mode = csr_get_dot11_mode(mac_ctx, session_id, bss_desc); + dot11mode = csr_get_dot11_mode(mac_ctx, vdev_id, bss_desc); if (!dot11mode) { sme_err("dot11mode is zero"); return QDF_STATUS_E_FAILURE; @@ -566,9 +549,9 @@ QDF_STATUS csr_roam_issue_ft_preauth_req(struct mac_context *mac_ctx, } /* Save the SME Session ID. We need it while processing preauth resp */ - csr_session->ftSmeContext.smeSessionId = session_id; + csr_session->ftSmeContext.vdev_id = vdev_id; preauth_req->messageType = eWNI_SME_FT_PRE_AUTH_REQ; - preauth_req->preAuthchannelNum = bss_desc->channelId; + preauth_req->pre_auth_channel_freq = bss_desc->chan_freq; preauth_req->dot11mode = dot11mode; qdf_mem_copy((void *)&preauth_req->currbssId, @@ -579,8 +562,8 @@ QDF_STATUS csr_roam_issue_ft_preauth_req(struct mac_context *mac_ctx, qdf_mem_copy((void *)&preauth_req->self_mac_addr, (void *)&csr_session->self_mac_addr.bytes, sizeof(tSirMacAddr)); - if (csr_roam_is11r_assoc(mac_ctx, session_id) && - (mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType != + if (csr_roam_is11r_assoc(mac_ctx, vdev_id) && + (mac_ctx->roam.roamSession[vdev_id].connectedProfile.AuthType != eCSR_AUTH_TYPE_OPEN_SYSTEM)) { preauth_req->ft_ies_length = (uint16_t) csr_session->ftSmeContext.auth_ft_ies_length; @@ -607,9 +590,9 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, QDF_STATUS status = QDF_STATUS_SUCCESS; struct csr_roam_info *roam_info; enum csr_akm_type conn_Auth_type; - uint32_t session_id = preauth_rsp->smeSessionId; + uint32_t vdev_id = preauth_rsp->vdev_id; struct csr_roam_session *csr_session = CSR_GET_SESSION(mac_ctx, - session_id); + vdev_id); tDot11fAuthentication *p_auth = NULL; if (!csr_session) { @@ -617,10 +600,10 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, return; } status = csr_neighbor_roam_preauth_rsp_handler(mac_ctx, - preauth_rsp->smeSessionId, preauth_rsp->status); + preauth_rsp->vdev_id, preauth_rsp->status); if (status != QDF_STATUS_SUCCESS) { sme_err("Preauth was not processed: %d SessionID: %d", - status, session_id); + status, vdev_id); return; } @@ -629,13 +612,13 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, csr_session->ftSmeContext.FTState = eFT_AUTH_COMPLETE; csr_session->ftSmeContext.psavedFTPreAuthRsp = preauth_rsp; /* No need to notify qos module if this is a non 11r & ESE roam */ - if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId) + if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->vdev_id) #ifdef FEATURE_WLAN_ESE - || csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId) + || csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->vdev_id) #endif ) { sme_qos_csr_event_ind(mac_ctx, - csr_session->ftSmeContext.smeSessionId, + csr_session->ftSmeContext.vdev_id, SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL); } status = @@ -654,29 +637,29 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, qdf_mem_copy((void *)&csr_session->ftSmeContext.preAuthbssId, (void *)preauth_rsp->preAuthbssId, sizeof(struct qdf_mac_addr)); - if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId)) - csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId, + if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->vdev_id)) + csr_roam_call_callback(mac_ctx, preauth_rsp->vdev_id, NULL, 0, eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE); #ifdef FEATURE_WLAN_ESE - if (csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->smeSessionId)) { + if (csr_roam_is_ese_assoc(mac_ctx, preauth_rsp->vdev_id)) { csr_roam_read_tsf(mac_ctx, (uint8_t *)&roam_info->timestamp, - preauth_rsp->smeSessionId); + preauth_rsp->vdev_id); qdf_mem_copy((void *)&roam_info->bssid, (void *)preauth_rsp->preAuthbssId, sizeof(struct qdf_mac_addr)); - csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId, + csr_roam_call_callback(mac_ctx, preauth_rsp->vdev_id, roam_info, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY, 0); } #endif - if (csr_roam_is_fast_roam_enabled(mac_ctx, preauth_rsp->smeSessionId)) { + if (csr_roam_is_fast_roam_enabled(mac_ctx, preauth_rsp->vdev_id)) { /* Save the bssid from the received response */ qdf_mem_copy((void *)&roam_info->bssid, (void *)preauth_rsp->preAuthbssId, sizeof(struct qdf_mac_addr)); - csr_roam_call_callback(mac_ctx, preauth_rsp->smeSessionId, + csr_roam_call_callback(mac_ctx, preauth_rsp->vdev_id, roam_info, 0, eCSR_ROAM_PMK_NOTIFY, 0); } @@ -685,14 +668,14 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, /* If its an Open Auth, FT IEs are not provided by supplicant */ /* Hence populate them here */ conn_Auth_type = - mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType; + mac_ctx->roam.roamSession[vdev_id].connectedProfile.AuthType; csr_session->ftSmeContext.addMDIE = false; /* Done with it, init it. */ csr_session->ftSmeContext.psavedFTPreAuthRsp = NULL; - if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->smeSessionId) && + if (csr_roam_is11r_assoc(mac_ctx, preauth_rsp->vdev_id) && (conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) { uint16_t ft_ies_length; @@ -751,17 +734,12 @@ void csr_roam_ft_pre_auth_rsp_processor(struct mac_context *mac_ctx, QDF_STATUS csr_neighbor_roam_issue_preauth_req(struct mac_context *mac_ctx, uint8_t session_id) { - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - tpCsrNeighborRoamControlInfo neighbor_roam_info; + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac_ctx->roam.neighborRoamInfo[session_id]; QDF_STATUS status = QDF_STATUS_SUCCESS; tpCsrNeighborRoamBSSInfo neighbor_bss_node; - if (!session) { - sme_err("session_id invalid %d", session_id); - return QDF_STATUS_E_FAILURE; - } - neighbor_roam_info = &mac_ctx->roam.neighborRoamInfo[session_id]; if (false != neighbor_roam_info->FTRoamInfo.preauthRspPending) { /* This must not be true here */ QDF_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending == @@ -790,10 +768,9 @@ QDF_STATUS csr_neighbor_roam_issue_preauth_req(struct mac_context *mac_ctx, neighbor_bss_node->pBssDescription, eCsrPerformPreauth, true); - sme_debug("Before Pre-Auth: BSSID " QDF_MAC_ADDR_STR ", Ch:%d", - QDF_MAC_ADDR_ARRAY( - neighbor_bss_node->pBssDescription->bssId), - (int)neighbor_bss_node->pBssDescription->channelId); + sme_debug("Before Pre-Auth: BSSID " QDF_MAC_ADDR_FMT ", Ch:%d", + QDF_MAC_ADDR_REF(neighbor_bss_node->pBssDescription->bssId), + neighbor_bss_node->pBssDescription->chan_freq); if (QDF_STATUS_SUCCESS != status) { sme_err("Return failed preauth request status %d", diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c index 58abd4aa150aa7ff70f9e6d4f57a493734ac802b..68df7ebdb80ae02bcd2546223aed6055824cbb68 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -438,28 +437,6 @@ void csr_purge_pdev_all_ser_cmd_list(struct mac_context *mac_ctx) wlan_serialization_purge_all_pdev_cmd(mac_ctx->pdev); } -uint32_t csr_nonscan_active_ll_count(struct mac_context *mac_ctx) -{ - return wlan_serialization_get_active_list_count(mac_ctx->psoc, false); -} - -uint32_t csr_nonscan_pending_ll_count(struct mac_context *mac_ctx) -{ - return wlan_serialization_get_pending_list_count(mac_ctx->psoc, false); -} - -bool csr_nonscan_active_ll_is_list_empty(struct mac_context *mac_ctx, - bool inter_locked) -{ - return !wlan_serialization_get_active_list_count(mac_ctx->psoc, false); -} - -bool csr_nonscan_pending_ll_is_list_empty(struct mac_context *mac_ctx, - bool inter_locked) -{ - return !wlan_serialization_get_pending_list_count(mac_ctx->psoc, false); -} - tListElem *csr_nonscan_active_ll_peek_head(struct mac_context *mac_ctx, bool inter_locked) { @@ -504,18 +481,6 @@ bool csr_nonscan_active_ll_remove_entry(struct mac_context *mac_ctx, return false; } -tListElem *csr_nonscan_active_ll_remove_head(struct mac_context *mac_ctx, - bool inter_locked) -{ - return csr_nonscan_active_ll_peek_head(mac_ctx, inter_locked); -} - -tListElem *csr_nonscan_pending_ll_remove_head(struct mac_context *mac_ctx, - bool inter_locked) -{ - return csr_nonscan_pending_ll_peek_head(mac_ctx, inter_locked); -} - tListElem *csr_nonscan_pending_ll_next(struct mac_context *mac_ctx, tListElem *entry, bool inter_locked) { @@ -529,7 +494,7 @@ tListElem *csr_nonscan_pending_ll_next(struct mac_context *mac_ctx, cmd.cmd_type = csr_get_cmd_type(sme_cmd); cmd.vdev = wlan_objmgr_get_vdev_by_id_from_psoc_no_state( mac_ctx->psoc, - sme_cmd->sessionId, WLAN_LEGACY_SME_ID); + sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); tcmd = wlan_serialization_get_pending_list_next_node_using_psoc( mac_ctx->psoc, &cmd, false); if (cmd.vdev) @@ -584,20 +549,6 @@ static bool csr_is_conn_state(struct mac_context *mac_ctx, uint32_t session_id, return mac_ctx->roam.roamSession[session_id].connectState == state; } -bool csr_is_conn_state_connected_ibss(struct mac_context *mac_ctx, - uint32_t session_id) -{ - return csr_is_conn_state(mac_ctx, session_id, - eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED); -} - -bool csr_is_conn_state_disconnected_ibss(struct mac_context *mac_ctx, - uint32_t session_id) -{ - return csr_is_conn_state(mac_ctx, session_id, - eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED); -} - bool csr_is_conn_state_connected_infra(struct mac_context *mac_ctx, uint32_t session_id) { @@ -617,12 +568,54 @@ bool csr_is_conn_state_infra(struct mac_context *mac, uint32_t sessionId) return csr_is_conn_state_connected_infra(mac, sessionId); } +static tSirMacCapabilityInfo csr_get_bss_capabilities(struct bss_description * + pSirBssDesc) +{ + tSirMacCapabilityInfo dot11Caps; + + /* tSirMacCapabilityInfo is 16-bit */ + qdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo, + (uint16_t *) &dot11Caps); + + return dot11Caps; +} + +#ifdef QCA_IBSS_SUPPORT +bool csr_is_conn_state_connected_ibss(struct mac_context *mac_ctx, + uint32_t session_id) +{ + return csr_is_conn_state(mac_ctx, session_id, + eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED); +} + +bool csr_is_conn_state_disconnected_ibss(struct mac_context *mac_ctx, + uint32_t session_id) +{ + return csr_is_conn_state(mac_ctx, session_id, + eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED); +} + bool csr_is_conn_state_ibss(struct mac_context *mac, uint32_t sessionId) { return csr_is_conn_state_connected_ibss(mac, sessionId) || csr_is_conn_state_disconnected_ibss(mac, sessionId); } +bool csr_is_bss_type_ibss(eCsrRoamBssType bssType) +{ + return (bool) + (eCSR_BSS_TYPE_START_IBSS == bssType + || eCSR_BSS_TYPE_IBSS == bssType); +} + +bool csr_is_ibss_bss_desc(struct bss_description *pSirBssDesc) +{ + tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); + + return (bool) dot11Caps.ibss; +} +#endif + bool csr_is_conn_state_connected_wds(struct mac_context *mac_ctx, uint32_t session_id) { @@ -652,6 +645,66 @@ bool csr_is_conn_state_wds(struct mac_context *mac, uint32_t sessionId) csr_is_conn_state_disconnected_wds(mac, sessionId); } +enum csr_cfgdot11mode +csr_get_vdev_dot11_mode(struct mac_context *mac, + enum QDF_OPMODE device_mode, + enum csr_cfgdot11mode curr_dot11_mode) +{ + enum mlme_vdev_dot11_mode vdev_dot11_mode; + uint8_t dot11_mode_indx; + enum csr_cfgdot11mode dot11_mode = curr_dot11_mode; + uint32_t vdev_type_dot11_mode = + mac->mlme_cfg->dot11_mode.vdev_type_dot11_mode; + + sme_debug("curr_dot11_mode %d, vdev_dot11 %08X, dev_mode %d", + curr_dot11_mode, vdev_type_dot11_mode, device_mode); + + switch (device_mode) { + case QDF_STA_MODE: + dot11_mode_indx = STA_DOT11_MODE_INDX; + break; + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_DEVICE_MODE: + dot11_mode_indx = P2P_DEV_DOT11_MODE_INDX; + break; + case QDF_TDLS_MODE: + dot11_mode_indx = TDLS_DOT11_MODE_INDX; + break; + case QDF_NAN_DISC_MODE: + dot11_mode_indx = NAN_DISC_DOT11_MODE_INDX; + break; + case QDF_NDI_MODE: + dot11_mode_indx = NDI_DOT11_MODE_INDX; + break; + case QDF_OCB_MODE: + dot11_mode_indx = OCB_DOT11_MODE_INDX; + break; + default: + return dot11_mode; + } + vdev_dot11_mode = CSR_GET_BITS(vdev_type_dot11_mode, + dot11_mode_indx, 4); + if (vdev_dot11_mode == MLME_VDEV_DOT11_MODE_AUTO) + dot11_mode = curr_dot11_mode; + + if (CSR_IS_DOT11_MODE_11N(curr_dot11_mode) && + vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11N) + dot11_mode = eCSR_CFG_DOT11_MODE_11N; + + if (CSR_IS_DOT11_MODE_11AC(curr_dot11_mode) && + vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11AC) + dot11_mode = eCSR_CFG_DOT11_MODE_11AC; + + if (CSR_IS_DOT11_MODE_11AX(curr_dot11_mode) && + vdev_dot11_mode == MLME_VDEV_DOT11_MODE_11AX) + dot11_mode = eCSR_CFG_DOT11_MODE_11AX; + + sme_debug("INI vdev_dot11_mode %d new dot11_mode %d", + vdev_dot11_mode, dot11_mode); + + return dot11_mode; +} + static bool csr_is_conn_state_ap(struct mac_context *mac, uint32_t sessionId) { struct csr_roam_session *pSession; @@ -680,18 +733,20 @@ bool csr_is_any_session_in_connect_state(struct mac_context *mac) return false; } -uint8_t csr_get_infra_operation_channel(struct mac_context *mac, uint8_t sessionId) +uint32_t csr_get_infra_operation_chan_freq( + struct mac_context *mac, uint8_t vdev_id) { - uint8_t channel; + uint32_t chan_freq = 0; + struct csr_roam_session *session; - if (CSR_IS_SESSION_VALID(mac, sessionId)) { - channel = - mac->roam.roamSession[sessionId].connectedProfile. - operationChannel; - } else { - channel = 0; - } - return channel; + session = CSR_GET_SESSION(mac, vdev_id); + if (!session) + return chan_freq; + + if (CSR_IS_SESSION_VALID(mac, vdev_id)) + chan_freq = session->connectedProfile.op_freq; + + return chan_freq; } bool csr_is_session_client_and_connected(struct mac_context *mac, uint8_t sessionId) @@ -712,7 +767,7 @@ bool csr_is_session_client_and_connected(struct mac_context *mac, uint8_t sessio return false; } -uint8_t csr_get_concurrent_operation_channel(struct mac_context *mac_ctx) +uint32_t csr_get_concurrent_operation_freq(struct mac_context *mac_ctx) { struct csr_roam_session *session = NULL; uint8_t i = 0; @@ -733,13 +788,12 @@ uint8_t csr_get_concurrent_operation_channel(struct mac_context *mac_ctx) (persona == QDF_SAP_MODE)) && (session->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED))) - return session->connectedProfile.operationChannel; - + return session->connectedProfile.op_freq; } return 0; } -uint8_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, +uint32_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, uint8_t vdev_id_to_skip) { struct csr_roam_session *session = NULL; @@ -759,7 +813,7 @@ uint8_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, (persona == QDF_SAP_MODE)) && (session->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) - return session->connectedProfile.operationChannel; + return session->connectedProfile.op_freq; } return 0; @@ -771,19 +825,19 @@ uint8_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, /* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */ -#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2) -#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2) +#define CSR_GET_HT40_PLUS_CCH(och) ((och) + 10) +#define CSR_GET_HT40_MINUS_CCH(och) ((och) - 10) -#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6) -#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2) -#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2) -#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6) +#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och) + 30) +#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och) + 30) +#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och) - 10) +#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och) - 30) /** * csr_get_ch_from_ht_profile() - to get channel from HT profile * @mac: pointer to Mac context * @htp: pointer to HT profile - * @och: operating channel + * @och_freq: operating channel frequency * @cfreq: channel frequency * @hbw: half bandwidth * @@ -794,17 +848,17 @@ uint8_t csr_get_beaconing_concurrent_channel(struct mac_context *mac_ctx, */ static void csr_get_ch_from_ht_profile(struct mac_context *mac, tCsrRoamHTProfile *htp, - uint16_t och, uint16_t *cfreq, - uint16_t *hbw) + uint32_t och_freq, uint32_t *cfreq, + uint32_t *hbw) { - uint16_t cch, ch_bond; + uint32_t ch_bond; + struct ch_params chan_params = {0}; - if (och > 14) + if (!WLAN_REG_IS_24GHZ_CH_FREQ(och_freq)) ch_bond = mac->roam.configParam.channelBondingMode5GHz; else ch_bond = mac->roam.configParam.channelBondingMode24GHz; - cch = och; *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); if (!ch_bond) @@ -818,7 +872,6 @@ static void csr_get_ch_from_ht_profile(struct mac_context *mac, ); if (htp->vhtCapability) { - cch = htp->apCenterChan; if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) *hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL); else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) @@ -835,20 +888,29 @@ static void csr_get_ch_from_ht_profile(struct mac_context *mac, if (htp->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ) { *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); - if (htp->htSecondaryChannelOffset == - PHY_DOUBLE_CHANNEL_LOW_PRIMARY) - cch = CSR_GET_HT40_PLUS_CCH(och); - else if (htp->htSecondaryChannelOffset == - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) - cch = CSR_GET_HT40_MINUS_CCH(och); } else { - cch = och; *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); } } - ret: - *cfreq = cds_chan_to_freq(cch); + switch (*hbw * 2) { + case eCSR_BW_40MHz_VAL: + chan_params.ch_width = CH_WIDTH_40MHZ; + break; + case eCSR_BW_80MHz_VAL: + chan_params.ch_width = CH_WIDTH_80MHZ; + break; + case eCSR_BW_160MHz_VAL: + chan_params.ch_width = CH_WIDTH_160MHZ; + break; + default: + chan_params.ch_width = CH_WIDTH_20MHZ; + break; + } + wlan_reg_set_channel_params_for_freq(mac->pdev, och_freq, 0, + &chan_params); + + *cfreq = chan_params.mhz_freq_seg0; } /** @@ -865,8 +927,8 @@ static void csr_get_ch_from_ht_profile(struct mac_context *mac, * Return: none */ static void csr_calc_chb_for_sap_phymode(struct mac_context *mac_ctx, - uint16_t *sap_ch, eCsrPhyMode *sap_phymode, - uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb) + uint32_t *sap_ch, eCsrPhyMode *sap_phymode, + uint32_t *sap_cch, uint32_t *sap_hbw, uint8_t *chb) { if (*sap_phymode == eCSR_DOT11_MODE_11n || *sap_phymode == eCSR_DOT11_MODE_11n_ONLY) { @@ -925,10 +987,10 @@ static void csr_calc_chb_for_sap_phymode(struct mac_context *mac_ctx, * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP * @mac_ctx: pointer to mac context * @session: Current session - * @sap_ch: SAP/GO operating channel + * @sap_ch_freq: SAP/GO operating channel frequency * @sap_hbw: SAP/GO half bw * @sap_cfreq: SAP/GO channel frequency - * @intf_ch: concurrent SAP/GO operating channel + * @intf_ch_freq: concurrent SAP/GO operating channel frequency * @intf_hbw: concurrent SAP/GO half bw * @intf_cfreq: concurrent SAP/GO channel frequency * @@ -937,11 +999,16 @@ static void csr_calc_chb_for_sap_phymode(struct mac_context *mac_ctx, * * Return: none */ -static void csr_handle_conc_chnl_overlap_for_sap_go(struct mac_context *mac_ctx, +static void csr_handle_conc_chnl_overlap_for_sap_go( + struct mac_context *mac_ctx, struct csr_roam_session *session, - uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq, - uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq) + uint32_t *sap_ch_freq, uint32_t *sap_hbw, uint32_t *sap_cfreq, + uint32_t *intf_ch_freq, uint32_t *intf_hbw, + uint32_t *intf_cfreq) { + uint32_t op_chan_freq; + + op_chan_freq = session->connectedProfile.op_freq; /* * if conc_custom_rule1 is defined then we don't * want p2pgo to follow SAP's channel or SAP to @@ -949,25 +1016,24 @@ static void csr_handle_conc_chnl_overlap_for_sap_go(struct mac_context *mac_ctx, */ if (0 == mac_ctx->roam.configParam.conc_custom_rule1 && 0 == mac_ctx->roam.configParam.conc_custom_rule2) { - if (*sap_ch == 0) { - *sap_ch = session->connectedProfile.operationChannel; + if (*sap_ch_freq == 0) { + *sap_ch_freq = op_chan_freq; csr_get_ch_from_ht_profile(mac_ctx, &session->connectedProfile.ht_profile, - *sap_ch, sap_cfreq, sap_hbw); - } else if (*sap_ch != - session->connectedProfile.operationChannel) { - *intf_ch = session->connectedProfile.operationChannel; + *sap_ch_freq, sap_cfreq, sap_hbw); + } else if (*sap_ch_freq != op_chan_freq) { + *intf_ch_freq = op_chan_freq; csr_get_ch_from_ht_profile(mac_ctx, &session->connectedProfile.ht_profile, - *intf_ch, intf_cfreq, intf_hbw); + *intf_ch_freq, intf_cfreq, intf_hbw); } - } else if (*sap_ch == 0 && + } else if (*sap_ch_freq == 0 && (session->pCurRoamProfile->csrPersona == QDF_SAP_MODE)) { - *sap_ch = session->connectedProfile.operationChannel; + *sap_ch_freq = op_chan_freq; csr_get_ch_from_ht_profile(mac_ctx, &session->connectedProfile.ht_profile, - *sap_ch, sap_cfreq, sap_hbw); + *sap_ch_freq, sap_cfreq, sap_hbw); } } @@ -984,37 +1050,37 @@ static void csr_handle_conc_chnl_overlap_for_sap_go(struct mac_context *mac_ctx, * Return: uint16_t */ uint16_t csr_check_concurrent_channel_overlap(struct mac_context *mac_ctx, - uint16_t sap_ch, eCsrPhyMode sap_phymode, + uint32_t sap_ch_freq, eCsrPhyMode sap_phymode, uint8_t cc_switch_mode) { struct csr_roam_session *session = NULL; uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED; - uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0; - uint16_t sap_cfreq = 0; - uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch = 0; + uint32_t intf_ch_freq = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0; + uint32_t sap_cfreq = 0; + uint32_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq; QDF_STATUS status; if (mac_ctx->roam.configParam.cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) return 0; - if (sap_ch != 0) { - sap_cch = sap_ch; + if (sap_ch_freq != 0) { + sap_cfreq = sap_ch_freq; sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); - if (sap_ch > 14) + if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq)) chb = mac_ctx->roam.configParam.channelBondingMode5GHz; else chb = mac_ctx->roam.configParam.channelBondingMode24GHz; if (chb) - csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch, - &sap_phymode, &sap_cch, &sap_hbw, &chb); - sap_cfreq = cds_chan_to_freq(sap_cch); + csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch_freq, + &sap_phymode, &sap_cfreq, + &sap_hbw, &chb); } sme_debug("sap_ch:%d sap_phymode:%d sap_cch:%d sap_hbw:%d chb:%d", - sap_ch, sap_phymode, sap_cch, sap_hbw, chb); + sap_ch_freq, sap_phymode, sap_cfreq, sap_hbw, chb); for (i = 0; i < WLAN_MAX_VDEVS; i++) { if (!CSR_IS_SESSION_VALID(mac_ctx, i)) @@ -1028,12 +1094,12 @@ uint16_t csr_check_concurrent_channel_overlap(struct mac_context *mac_ctx, QDF_P2P_CLIENT_MODE)) && (session->connectState == eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) { - intf_ch = session->connectedProfile.operationChannel; + intf_ch_freq = session->connectedProfile.op_freq; csr_get_ch_from_ht_profile(mac_ctx, &session->connectedProfile.ht_profile, - intf_ch, &intf_cfreq, &intf_hbw); + intf_ch_freq, &intf_cfreq, &intf_hbw); sme_debug("%d: intf_ch:%d intf_cfreq:%d intf_hbw:%d", - i, intf_ch, intf_cfreq, intf_hbw); + i, intf_ch_freq, intf_cfreq, intf_hbw); } else if (((session->pCurRoamProfile->csrPersona == QDF_P2P_GO_MODE) || (session->pCurRoamProfile->csrPersona == @@ -1044,71 +1110,75 @@ uint16_t csr_check_concurrent_channel_overlap(struct mac_context *mac_ctx, continue; csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx, - session, &sap_ch, &sap_hbw, &sap_cfreq, - &intf_ch, &intf_hbw, &intf_cfreq); + session, &sap_ch_freq, &sap_hbw, + &sap_cfreq, &intf_ch_freq, &intf_hbw, + &intf_cfreq); } - if (intf_ch && ((intf_ch > 14 && sap_ch > 14) || - (intf_ch <= 14 && sap_ch <= 14))) + if (intf_ch_freq && + ((intf_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484) && + sap_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) || + (intf_ch_freq > wlan_reg_ch_to_freq(CHAN_ENUM_2484) && + sap_ch_freq > wlan_reg_ch_to_freq(CHAN_ENUM_2484)))) break; } sme_debug("intf_ch:%d sap_ch:%d cc_switch_mode:%d, dbs:%d", - intf_ch, sap_ch, cc_switch_mode, - policy_mgr_is_dbs_enable(mac_ctx->psoc)); - if (intf_ch && sap_ch != intf_ch && + intf_ch_freq, sap_ch_freq, cc_switch_mode, + policy_mgr_is_dbs_enable(mac_ctx->psoc)); + + if (intf_ch_freq && sap_ch_freq != intf_ch_freq && !policy_mgr_is_force_scc(mac_ctx->psoc)) { sap_lfreq = sap_cfreq - sap_hbw; sap_hfreq = sap_cfreq + sap_hbw; intf_lfreq = intf_cfreq - intf_hbw; intf_hfreq = intf_cfreq + intf_hbw; - sme_debug("SAP: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d", - sap_ch, cds_chan_to_freq(sap_ch), - cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2, - sap_lfreq, sap_hfreq, intf_ch, - cds_chan_to_freq(intf_ch), - cds_freq_to_chan(intf_cfreq), - intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq); + sme_debug("SAP: OCH: %03d CCH: %03d BW: %d LF: %d HF: %d INTF: OCH: %03d CF: %d BW: %d LF: %d HF: %d", + sap_ch_freq, sap_cfreq, sap_hbw * 2, + sap_lfreq, sap_hfreq, intf_ch_freq, + intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq); if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) || (sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) || ((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) || (intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq)))) - intf_ch = 0; - } else if (intf_ch && sap_ch != intf_ch && - (policy_mgr_is_force_scc(mac_ctx->psoc))) { - if (!((intf_ch <= 14 && sap_ch <= 14) || - (intf_ch > 14 && sap_ch > 14))) { + intf_ch_freq = 0; + } else if (intf_ch_freq && sap_ch_freq != intf_ch_freq && + (policy_mgr_is_force_scc(mac_ctx->psoc))) { + if (!((intf_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484) && + sap_ch_freq <= wlan_reg_ch_to_freq(CHAN_ENUM_2484)) || + (intf_ch_freq > wlan_reg_ch_to_freq(CHAN_ENUM_2484) && + sap_ch_freq > wlan_reg_ch_to_freq(CHAN_ENUM_2484)))) { if (policy_mgr_is_dbs_enable(mac_ctx->psoc) || cc_switch_mode == QDF_MCC_TO_SCC_WITH_PREFERRED_BAND) - intf_ch = 0; + intf_ch_freq = 0; } else if (cc_switch_mode == - QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { - status = - policy_mgr_get_sap_mandatory_channel( - mac_ctx->psoc, - &intf_ch); + QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { + status = policy_mgr_get_sap_mandatory_channel( + mac_ctx->psoc, + &intf_ch_freq); if (QDF_IS_STATUS_ERROR(status)) sme_err("no mandatory channel"); } - } else if ((intf_ch == sap_ch) && (cc_switch_mode == + } else if ((intf_ch_freq == sap_ch_freq) && (cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)) { - if (cds_chan_to_band(intf_ch) == CDS_BAND_2GHZ) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(intf_ch_freq)) { status = policy_mgr_get_sap_mandatory_channel( - mac_ctx->psoc, &intf_ch); + mac_ctx->psoc, &intf_ch_freq); if (QDF_IS_STATUS_ERROR(status)) sme_err("no mandatory channel"); } } - if (intf_ch == sap_ch) - intf_ch = 0; + if (intf_ch_freq == sap_ch_freq) + intf_ch_freq = 0; sme_debug("##Concurrent Channels %s Interfering", - intf_ch == 0 ? "Not" : "Are"); - return intf_ch; + intf_ch_freq == 0 ? "Not" : "Are"); + + return intf_ch_freq; } #endif @@ -1222,26 +1292,15 @@ bool csr_is_valid_mc_concurrent_session(struct mac_context *mac_ctx, pSession = CSR_GET_SESSION(mac_ctx, session_id); if (!pSession->pCurRoamProfile) return false; - if (QDF_STATUS_SUCCESS == csr_validate_mcc_beacon_interval(mac_ctx, - bss_descr->channelId, - &bss_descr->beaconInterval, session_id, - pSession->pCurRoamProfile->csrPersona)) + if (QDF_STATUS_SUCCESS == csr_validate_mcc_beacon_interval( + mac_ctx, + bss_descr->chan_freq, + &bss_descr->beaconInterval, session_id, + pSession->pCurRoamProfile->csrPersona)) return true; return false; } -static tSirMacCapabilityInfo csr_get_bss_capabilities(struct bss_description * - pSirBssDesc) -{ - tSirMacCapabilityInfo dot11Caps; - - /* tSirMacCapabilityInfo is 16-bit */ - qdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo, - (uint16_t *) &dot11Caps); - - return dot11Caps; -} - bool csr_is_infra_bss_desc(struct bss_description *pSirBssDesc) { tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); @@ -1249,13 +1308,6 @@ bool csr_is_infra_bss_desc(struct bss_description *pSirBssDesc) return (bool) dot11Caps.ess; } -bool csr_is_ibss_bss_desc(struct bss_description *pSirBssDesc) -{ - tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); - - return (bool) dot11Caps.ibss; -} - static bool csr_is_qos_bss_desc(struct bss_description *pSirBssDesc) { tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); @@ -1263,13 +1315,6 @@ static bool csr_is_qos_bss_desc(struct bss_description *pSirBssDesc) return (bool) dot11Caps.qos; } -bool csr_is_privacy(struct bss_description *pSirBssDesc) -{ - tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); - - return (bool) dot11Caps.privacy; -} - bool csr_is11h_supported(struct mac_context *mac) { return mac->mlme_cfg->gen.enabled_11h; @@ -1659,7 +1704,14 @@ QDF_STATUS csr_get_phy_mode_from_bss(struct mac_context *mac, phyMode = eCSR_DOT11_MODE_11ac; if (pIes->he_cap.present) phyMode = eCSR_DOT11_MODE_11ax; + } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ( + pBSSDescription->chan_freq)) { + if (pIes->he_cap.present) + phyMode = eCSR_DOT11_MODE_11ax; + else + sme_debug("Warning - 6Ghz AP no he cap"); } + *pPhyMode = phyMode; } @@ -1899,14 +1951,28 @@ bool csr_is_phy_mode_match(struct mac_context *mac, uint32_t phyMode, tDot11fBeaconIEs *pIes) { bool fMatch = false; - eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2; + eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO; + eCsrPhyMode phyMode2 = eCSR_DOT11_MODE_AUTO; enum csr_cfgdot11mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO; uint32_t bitMask, loopCount; + uint32_t bss_chan_freq; + + if (!pProfile) { + sme_err("profile not found"); + return fMatch; + } if (!QDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(mac, pSirBssDesc, &phyModeInBssDesc, pIes))) return fMatch; + bss_chan_freq = pSirBssDesc->chan_freq; + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(bss_chan_freq)) { + if (pReturnCfgDot11Mode) + *pReturnCfgDot11Mode = eCSR_CFG_DOT11_MODE_11AX; + return true; + } + if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) { if (eCSR_CFG_DOT11_MODE_ABG == mac->roam.configParam.uCfgDot11Mode) { @@ -1936,8 +2002,8 @@ bool csr_is_phy_mode_match(struct mac_context *mac, uint32_t phyMode, } fMatch = csr_get_phy_mode_in_use(mac, phyMode2, phyModeInBssDesc, - WLAN_REG_IS_5GHZ_CH( - pSirBssDesc->channelId), + !WLAN_REG_IS_24GHZ_CH_FREQ + (bss_chan_freq), &cfgDot11ModeToUse); } else { bitMask = 1; @@ -1947,39 +2013,39 @@ bool csr_is_phy_mode_match(struct mac_context *mac, uint32_t phyMode, if (0 != phyMode2 && csr_get_phy_mode_in_use(mac, phyMode2, phyModeInBssDesc, - WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId), + !WLAN_REG_IS_24GHZ_CH_FREQ(bss_chan_freq), &cfgDot11ModeToUse)) { fMatch = true; break; } } } + + cfgDot11ModeToUse = csr_get_vdev_dot11_mode(mac, pProfile->csrPersona, + cfgDot11ModeToUse); if (fMatch && pReturnCfgDot11Mode) { - if (pProfile) { - /* - * IEEE 11n spec (8.4.3): HT STA shall - * eliminate TKIP as a choice for the pairwise - * cipher suite if CCMP is advertised by the AP - * or if the AP included an HT capabilities - * element in its Beacons and Probe Response. - */ - if ((!CSR_IS_11n_ALLOWED( - pProfile->negotiatedUCEncryptionType)) - && ((eCSR_CFG_DOT11_MODE_11N == - cfgDot11ModeToUse) || - (eCSR_CFG_DOT11_MODE_11AC == - cfgDot11ModeToUse) || - (eCSR_CFG_DOT11_MODE_11AX == - cfgDot11ModeToUse))) { - /* We cannot do 11n here */ - if (!WLAN_REG_IS_5GHZ_CH - (pSirBssDesc->channelId)) { - cfgDot11ModeToUse = - eCSR_CFG_DOT11_MODE_11G; - } else { - cfgDot11ModeToUse = - eCSR_CFG_DOT11_MODE_11A; - } + /* + * IEEE 11n spec (8.4.3): HT STA shall + * eliminate TKIP as a choice for the pairwise + * cipher suite if CCMP is advertised by the AP + * or if the AP included an HT capabilities + * element in its Beacons and Probe Response. + */ + if ((!CSR_IS_11n_ALLOWED( + pProfile->negotiatedUCEncryptionType)) + && ((eCSR_CFG_DOT11_MODE_11N == + cfgDot11ModeToUse) || + (eCSR_CFG_DOT11_MODE_11AC == + cfgDot11ModeToUse) || + (eCSR_CFG_DOT11_MODE_11AX == + cfgDot11ModeToUse))) { + /* We cannot do 11n here */ + if (WLAN_REG_IS_24GHZ_CH_FREQ(bss_chan_freq)) { + cfgDot11ModeToUse = + eCSR_CFG_DOT11_MODE_11G; + } else { + cfgDot11ModeToUse = + eCSR_CFG_DOT11_MODE_11A; } } *pReturnCfgDot11Mode = cfgDot11ModeToUse; @@ -2272,7 +2338,7 @@ static uint16_t csr_calculate_mcc_beacon_interval(struct mac_context *mac, * Return: bool */ static bool csr_validate_p2pcli_bcn_intrvl(struct mac_context *mac_ctx, - uint8_t chnl_id, uint16_t *bcn_interval, uint32_t session_id, + uint32_t ch_freq, uint16_t *bcn_interval, uint32_t session_id, QDF_STATUS *status) { struct csr_roam_session *roamsession; @@ -2285,9 +2351,8 @@ static bool csr_validate_p2pcli_bcn_intrvl(struct mac_context *mac_ctx, sme_debug("Ignore Beacon Interval Validation..."); } else if (roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) { /* Check for P2P go scenario */ - if ((roamsession->bssParams.operationChn != chnl_id) - && (roamsession->bssParams.beaconInterval != - *bcn_interval)) { + if (roamsession->bssParams.operation_chan_freq != ch_freq && + roamsession->bssParams.beaconInterval != *bcn_interval) { sme_err("BcnIntrvl is diff can't connect to P2P_GO network"); *status = QDF_STATUS_E_FAILURE; return true; @@ -2310,7 +2375,7 @@ static bool csr_validate_p2pcli_bcn_intrvl(struct mac_context *mac_ctx, * Return: bool */ static bool csr_validate_p2pgo_bcn_intrvl(struct mac_context *mac_ctx, - uint8_t chnl_id, uint16_t *bcn_interval, + uint32_t ch_freq, uint16_t *bcn_interval, uint32_t session_id, QDF_STATUS *status) { struct csr_roam_session *roamsession; @@ -2327,13 +2392,13 @@ static bool csr_validate_p2pgo_bcn_intrvl(struct mac_context *mac_ctx, (roamsession->pCurRoamProfile->csrPersona == QDF_STA_MODE))) { /* check for P2P_client scenario */ - if ((conn_profile->operationChannel == 0) && - (conn_profile->beaconInterval == 0)) + if ((conn_profile->op_freq == 0) && + (conn_profile->beaconInterval == 0)) return false; if (csr_is_conn_state_connected_infra(mac_ctx, session_id) && - (conn_profile->operationChannel != chnl_id) && - (conn_profile->beaconInterval != *bcn_interval)) { + conn_profile->op_freq != ch_freq && + conn_profile->beaconInterval != *bcn_interval) { /* * Updated beaconInterval should be used only when * we are starting a new BSS not incase of @@ -2374,7 +2439,7 @@ static bool csr_validate_p2pgo_bcn_intrvl(struct mac_context *mac_ctx, * Return: bool */ static bool csr_validate_sta_bcn_intrvl(struct mac_context *mac_ctx, - uint8_t chnl_id, uint16_t *bcn_interval, + uint32_t ch_freq, uint16_t *bcn_interval, uint32_t session_id, QDF_STATUS *status) { struct csr_roam_session *roamsession; @@ -2391,15 +2456,15 @@ static bool csr_validate_sta_bcn_intrvl(struct mac_context *mac_ctx, sme_debug("Bcn Intrvl validation not require for STA/CLIENT"); return false; } - if ((roamsession->bssParams.bssPersona == QDF_SAP_MODE) && - (roamsession->bssParams.operationChn != chnl_id)) { + if (roamsession->bssParams.bssPersona == QDF_SAP_MODE && + roamsession->bssParams.operation_chan_freq != ch_freq) { /* * IF SAP has started and STA wants to connect * on different channel MCC should * MCC should not be enabled so making it * false to enforce on same channel */ - sme_err("*** MCC with SAP+STA sessions ****"); + sme_debug("*** MCC with SAP+STA sessions ****"); *status = QDF_STATUS_SUCCESS; return true; } @@ -2409,9 +2474,9 @@ static bool csr_validate_sta_bcn_intrvl(struct mac_context *mac_ctx, * beacon interval, * change the BI of the P2P-GO */ - if ((roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) && - (roamsession->bssParams.operationChn != chnl_id) && - (roamsession->bssParams.beaconInterval != *bcn_interval)) { + if (roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE && + roamsession->bssParams.operation_chan_freq != ch_freq && + roamsession->bssParams.beaconInterval != *bcn_interval) { /* if GO in MCC support diff beacon interval, return success */ if (cfg_param->fAllowMCCGODiffBI == 0x01) { *status = QDF_STATUS_SUCCESS; @@ -2472,7 +2537,7 @@ static bool csr_validate_sta_bcn_intrvl(struct mac_context *mac_ctx, } QDF_STATUS csr_validate_mcc_beacon_interval(struct mac_context *mac_ctx, - uint8_t chnl_id, + uint32_t ch_freq, uint16_t *bcn_interval, uint32_t cur_session_id, enum QDF_OPMODE cur_bss_persona) @@ -2494,15 +2559,16 @@ QDF_STATUS csr_validate_mcc_beacon_interval(struct mac_context *mac_ctx, switch (cur_bss_persona) { case QDF_STA_MODE: - is_done = csr_validate_sta_bcn_intrvl(mac_ctx, chnl_id, - bcn_interval, session_id, &status); + is_done = csr_validate_sta_bcn_intrvl( + mac_ctx, ch_freq, bcn_interval, + session_id, &status); if (true == is_done) return status; break; case QDF_P2P_CLIENT_MODE: is_done = csr_validate_p2pcli_bcn_intrvl(mac_ctx, - chnl_id, bcn_interval, session_id, + ch_freq, bcn_interval, session_id, &status); if (true == is_done) return status; @@ -2514,7 +2580,7 @@ QDF_STATUS csr_validate_mcc_beacon_interval(struct mac_context *mac_ctx, case QDF_P2P_GO_MODE: is_done = csr_validate_p2pgo_bcn_intrvl(mac_ctx, - chnl_id, bcn_interval, + ch_freq, bcn_interval, session_id, &status); if (true == is_done) return status; @@ -2617,35 +2683,9 @@ bool csr_is_profile_wapi(struct csr_roam_profile *pProfile) } return fWapiProfile; } - -static bool csr_is_wapi_oui_equal(struct mac_context *mac, uint8_t *Oui1, - uint8_t *Oui2) -{ - return !qdf_mem_cmp(Oui1, Oui2, CSR_WAPI_OUI_SIZE); -} - -static bool csr_is_wapi_oui_match(struct mac_context *mac, - uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE], - uint8_t cAllCyphers, uint8_t Cypher[], - uint8_t Oui[]) -{ - bool fYes = false; - uint8_t idx; - - for (idx = 0; idx < cAllCyphers; idx++) { - if (csr_is_wapi_oui_equal(mac, AllCyphers[idx], Cypher)) { - fYes = true; - break; - } - } - - if (fYes && Oui) - qdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE); - - return fYes; -} #endif /* FEATURE_WLAN_WAPI */ +#ifdef WLAN_FEATURE_11W static bool csr_is_wpa_oui_equal(struct mac_context *mac, uint8_t *Oui1, uint8_t *Oui2) { @@ -2672,563 +2712,40 @@ static bool csr_is_oui_match(struct mac_context *mac, return fYes; } -static bool csr_match_rsnoui_index(struct mac_context *mac, - uint8_t AllCyphers[][CSR_RSN_OUI_SIZE], - uint8_t cAllCyphers, uint8_t ouiIndex, - uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui); - -} - -#ifdef FEATURE_WLAN_WAPI -static bool csr_match_wapi_oui_index(struct mac_context *mac, - uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE], - uint8_t cAllCyphers, uint8_t ouiIndex, - uint8_t Oui[]) -{ - return csr_is_wapi_oui_match - (mac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui); - -} -#endif /* FEATURE_WLAN_WAPI */ - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -static bool csr_match_wpaoui_index(struct mac_context *mac, - uint8_t AllCyphers[][CSR_RSN_OUI_SIZE], - uint8_t cAllCyphers, uint8_t ouiIndex, - uint8_t Oui[]) -{ - if (ouiIndex < QDF_ARRAY_SIZE(csr_wpa_oui)) - return csr_is_oui_match - (mac, AllCyphers, cAllCyphers, - csr_wpa_oui[ouiIndex], Oui); - else - return false; -} -#endif - -#ifdef FEATURE_WLAN_WAPI -static bool csr_is_auth_wapi_cert(struct mac_context *mac, - uint8_t AllSuites[][CSR_WAPI_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_wapi_oui_match - (mac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui); -} - -static bool csr_is_auth_wapi_psk(struct mac_context *mac, - uint8_t AllSuites[][CSR_WAPI_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_wapi_oui_match - (mac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui); -} -#endif /* FEATURE_WLAN_WAPI */ - - -/* - * Function for 11R FT Authentication. We match the FT Authentication Cipher - * suite here. This matches for FT Auth with the 802.1X exchange. - */ -static bool csr_is_ft_auth_rsn(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui); -} - -/* - * Function for 11R FT Authentication. We match the FT Authentication Cipher - * suite here. This matches for FT Auth with the PSK. - */ -static bool csr_is_ft_auth_rsn_psk(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui); -} - - -#ifdef FEATURE_WLAN_ESE - -/* - * Function for ESE CCKM AKM Authentication. We match the CCKM AKM - * Authentication Key Management suite here. This matches for CCKM AKM Auth - * with the 802.1X exchange. - */ -static bool csr_is_ese_cckm_auth_rsn(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui); -} - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -static bool csr_is_ese_cckm_auth_wpa(struct mac_context *mac, - uint8_t AllSuites[][CSR_WPA_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui); -} -#endif - -#endif - -static bool csr_is_auth_rsn(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui); -} - -static bool csr_is_auth_rsn_psk(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui); -} - -#ifdef WLAN_FEATURE_11W -static bool csr_is_auth_rsn_psk_sha256(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui); -} -static bool csr_is_auth_rsn8021x_sha256(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui); -} -#endif - -#ifdef WLAN_FEATURE_FILS_SK /* - * csr_is_auth_fils_sha256() - check whether oui is fils sha256 + * csr_is_group_mgmt_gmac_128() - check whether oui is GMAC_128 * @mac: Global MAC context * @all_suites: pointer to all supported akm suites * @suite_count: all supported akm suites count * @oui: Oui needs to be matched * - * Return: True if OUI is FILS SHA256, false otherwise + * Return: True if OUI is GMAC_128, false otherwise */ -static bool csr_is_auth_fils_sha256(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) +static bool csr_is_group_mgmt_gmac_128(struct mac_context *mac, + uint8_t AllSuites[][CSR_RSN_OUI_SIZE], + uint8_t cAllSuites, uint8_t Oui[]) { - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FILS_SHA256], oui); + return csr_is_oui_match(mac, AllSuites, cAllSuites, + csr_group_mgmt_oui[ENUM_GMAC_128], Oui); } /* - * csr_is_auth_fils_sha384() - check whether oui is fils sha384 + * csr_is_group_mgmt_gmac_256() - check whether oui is GMAC_256 * @mac: Global MAC context * @all_suites: pointer to all supported akm suites * @suite_count: all supported akm suites count * @oui: Oui needs to be matched * - * Return: True if OUI is FILS SHA384, false otherwise + * Return: True if OUI is GMAC_256, false otherwise */ -static bool csr_is_auth_fils_sha384(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) +static bool csr_is_group_mgmt_gmac_256(struct mac_context *mac, + uint8_t AllSuites[][CSR_RSN_OUI_SIZE], + uint8_t cAllSuites, uint8_t Oui[]) { - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FILS_SHA384], oui); + return csr_is_oui_match(mac, AllSuites, cAllSuites, + csr_group_mgmt_oui[ENUM_GMAC_256], Oui); } - -/* - * csr_is_auth_fils_ft_sha256() - check whether oui is fils ft sha256 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is FT FILS SHA256, false otherwise - */ -static bool csr_is_auth_fils_ft_sha256(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FT_FILS_SHA256], oui); -} - -/* - * csr_is_auth_fils_ft_sha384() - check whether oui is fils ft sha384 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is FT FILS SHA384, false otherwise - */ -static bool csr_is_auth_fils_ft_sha384(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FT_FILS_SHA384], oui); -} -#endif - -/* - * csr_is_auth_dpp_rsn() - check whether oui is dpp rsn - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is dpp rsn, false otherwise - */ -static bool csr_is_auth_dpp_rsn(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_DPP_RSN], oui); -} - -/* - * csr_is_auth_wpa_owe() - check whether oui is OWE - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is OWE, false otherwise - */ -static bool csr_is_auth_wpa_owe(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match - (mac, all_suites, suite_count, csr_rsn_oui[ENUM_OWE], oui); -} - -/* - * csr_is_auth_suiteb_eap_256() - check whether oui is SuiteB EAP256 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is SuiteB EAP256, false otherwise - */ -static bool csr_is_auth_suiteb_eap_256(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_SUITEB_EAP256], oui); -} - -/* - * csr_is_auth_suiteb_eap_384() - check whether oui is SuiteB EAP384 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is SuiteB EAP384, false otherwise - */ -static bool csr_is_auth_suiteb_eap_384(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_SUITEB_EAP384], oui); -} - -/* - * csr_is_auth_ft_suiteb_eap_384() - check whether oui is SuiteB EAP384 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is FT SuiteB EAP384, false otherwise - */ -static -bool csr_is_auth_ft_suiteb_eap_384(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FT_SUITEB_SHA384], oui); -} - -#ifdef WLAN_FEATURE_SAE -/* - * csr_is_auth_wpa_sae() - check whether oui is SAE - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is SAE, false otherwise - */ -static bool csr_is_auth_wpa_sae(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - bool is_sae_auth; - - is_sae_auth = (csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_SAE], oui)); - return is_sae_auth; -} - -/* - * csr_is_auth_ft_sae() - check whether oui is SAE - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is FT-SAE, false otherwise - */ -static bool csr_is_auth_ft_sae(struct mac_context *mac, - uint8_t all_suites[][CSR_RSN_OUI_SIZE], - uint8_t suite_count, uint8_t oui[]) -{ - bool is_ft_sae_auth; - - is_ft_sae_auth = csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_FT_SAE], oui); - return is_ft_sae_auth; -} -#endif - -/* - * csr_is_auth_osen() - check whether oui is osen rsn - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is OSEN, false otherwise - */ -static bool csr_is_auth_osen(struct mac_context *mac, - u8 all_suites[][CSR_RSN_OUI_SIZE], - u8 suite_count, u8 oui[]) -{ - return csr_is_oui_match(mac, all_suites, suite_count, - csr_rsn_oui[ENUM_OSEN], oui); -} - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -static bool csr_is_auth_wpa(struct mac_context *mac, - uint8_t AllSuites[][CSR_WPA_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui); -} - -static bool csr_is_auth_wpa_psk(struct mac_context *mac, - uint8_t AllSuites[][CSR_WPA_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match - (mac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui); -} -#endif - -/* - * csr_is_group_mgmt_gmac_128() - check whether oui is GMAC_128 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is GMAC_128, false otherwise - */ -static bool csr_is_group_mgmt_gmac_128(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match(mac, AllSuites, cAllSuites, - csr_group_mgmt_oui[ENUM_GMAC_128], Oui); -} - -/* - * csr_is_group_mgmt_gmac_256() - check whether oui is GMAC_256 - * @mac: Global MAC context - * @all_suites: pointer to all supported akm suites - * @suite_count: all supported akm suites count - * @oui: Oui needs to be matched - * - * Return: True if OUI is GMAC_256, false otherwise - */ -static bool csr_is_group_mgmt_gmac_256(struct mac_context *mac, - uint8_t AllSuites[][CSR_RSN_OUI_SIZE], - uint8_t cAllSuites, uint8_t Oui[]) -{ - return csr_is_oui_match(mac, AllSuites, cAllSuites, - csr_group_mgmt_oui[ENUM_GMAC_256], Oui); -} - -static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType) -{ - uint8_t OUIIndex; - - switch (enType) { - case eCSR_ENCRYPT_TYPE_WEP40: - case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: - OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX; - break; - case eCSR_ENCRYPT_TYPE_WEP104: - case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: - OUIIndex = CSR_OUI_WEP104_INDEX; - break; - case eCSR_ENCRYPT_TYPE_TKIP: - OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX; - break; - case eCSR_ENCRYPT_TYPE_AES: - OUIIndex = CSR_OUI_AES_INDEX; - break; - case eCSR_ENCRYPT_TYPE_AES_GCMP: - OUIIndex = CSR_OUI_AES_GCMP_INDEX; - break; - case eCSR_ENCRYPT_TYPE_AES_GCMP_256: - OUIIndex = CSR_OUI_AES_GCMP_256_INDEX; - break; - case eCSR_ENCRYPT_TYPE_NONE: - OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX; - break; -#ifdef FEATURE_WLAN_WAPI - case eCSR_ENCRYPT_TYPE_WPI: - OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX; - break; -#endif /* FEATURE_WLAN_WAPI */ - default: /* HOWTO handle this? */ - OUIIndex = CSR_OUI_RESERVED_INDEX; - break; - } /* switch */ - - return OUIIndex; -} - -#ifdef WLAN_FEATURE_FILS_SK -/** - * csr_is_fils_auth() - update negotiated auth if matches to FILS auth type - * @mac_ctx: pointer to mac context - * @authsuites: auth suites - * @c_auth_suites: auth suites count - * @authentication: authentication - * @auth_type: authentication type list - * @index: current counter - * @neg_authtype: pointer to negotiated auth - * - * Return: None - */ -static void csr_is_fils_auth(struct mac_context *mac_ctx, - uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites, - uint8_t authentication[], tCsrAuthList *auth_type, - uint8_t index, enum csr_akm_type *neg_authtype) -{ - /* - * TODO Always try with highest security - * move this down once sha384 is validated - */ - if (csr_is_auth_fils_sha256(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FILS_SHA256 == - auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_FILS_SHA256; - } - if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_fils_sha384(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FILS_SHA384 == - auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_FILS_SHA384; - } - if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_fils_ft_sha256(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FT_FILS_SHA256 == - auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA256; - } - if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_fils_ft_sha384(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FT_FILS_SHA384 == - auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA384; - } - sme_debug("negotiated auth type is %d", *neg_authtype); -} -#else -static void csr_is_fils_auth(struct mac_context *mac_ctx, - uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites, - uint8_t authentication[], tCsrAuthList *auth_type, - uint8_t index, enum csr_akm_type *neg_authtype) -{ -} -#endif - -#ifdef WLAN_FEATURE_SAE -/** - * csr_check_sae_auth() - update negotiated auth and oui if matches to SAE auth - * type - * @mac_ctx: pointer to mac context - * @authsuites: auth suites - * @c_auth_suites: auth suites count - * @authentication: authentication - * @auth_type: authentication type list - * @index: current counter - * @neg_authtype: pointer to negotiated auth - * - * Return: None - */ -static void -csr_check_sae_auth(struct mac_context *mac_ctx, - uint8_t authsuites[][CSR_RSN_OUI_SIZE], - uint8_t c_auth_suites, - uint8_t authentication[], tCsrAuthList *auth_type, - uint8_t index, enum csr_akm_type *neg_authtype) -{ - if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_ft_sae(mac_ctx, authsuites, c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_FT_SAE == auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_FT_SAE; - if (eCSR_AUTH_TYPE_OPEN_SYSTEM == auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_OPEN_SYSTEM; - } - - if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_wpa_sae(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_SAE == auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_SAE; - if (eCSR_AUTH_TYPE_OPEN_SYSTEM == auth_type->authType[index]) - *neg_authtype = eCSR_AUTH_TYPE_OPEN_SYSTEM; - } - sme_debug("negotiated auth type is %d", *neg_authtype); -} -#else -static void csr_check_sae_auth(struct mac_context *mac_ctx, - uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites, - uint8_t authentication[], tCsrAuthList *auth_type, - uint8_t index, enum csr_akm_type *neg_authtype) -{ -} -#endif +#endif bool csr_is_pmkid_found_for_peer(struct mac_context *mac, struct csr_roam_session *session, @@ -3236,7 +2753,7 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac, uint8_t *pmkid, uint16_t pmkid_count) { - uint32_t i, index; + uint32_t i; uint8_t *session_pmkid; tPmkidCacheInfo *pmkid_cache; @@ -3247,7 +2764,7 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac, qdf_mem_copy(pmkid_cache->BSSID.bytes, peer_mac_addr, QDF_MAC_ADDR_SIZE); - if (!csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache, &index)) { + if (!csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache)) { qdf_mem_free(pmkid_cache); return false; } @@ -3267,715 +2784,61 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac, return false; } -/** - * csr_get_rsn_information() - to get RSN information - * @mac_ctx: pointer to global MAC context - * @auth_type: auth type - * @encr_type: encryption type - * @mc_encryption: multicast encryption type - * @rsn_ie: pointer to RSN IE - * @ucast_cipher: Unicast cipher - * @mcast_cipher: Multicast cipher - * @auth_suite: Authentication suite - * @capabilities: RSN capabilities - * @negotiated_authtype: Negotiated auth type - * @negotiated_mccipher: negotiated multicast cipher - * @gp_mgmt_cipher: group management cipher - * @mgmt_encryption_type: group management encryption type - * @adaptive_11r: is adaptive 11r connection - * - * This routine will get all RSN information - * - * Return: bool - */ -static bool csr_get_rsn_information(struct mac_context *mac_ctx, - tCsrAuthList *auth_type, - eCsrEncryptionType encr_type, - tCsrEncryptionList *mc_encryption, - tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher, - uint8_t *mcast_cipher, uint8_t *auth_suite, - struct rsn_caps *capabilities, - enum csr_akm_type *negotiated_authtype, - eCsrEncryptionType *negotiated_mccipher, - uint8_t *gp_mgmt_cipher, - tAniEdType *mgmt_encryption_type, - bool adaptive_11r) +bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, + struct csr_roam_session *session, + tPmkidCacheInfo *pmk_cache) { - bool acceptable_cipher = false; - bool group_mgmt_acceptable_cipher = false; - uint8_t c_ucast_cipher = 0; - uint8_t c_mcast_cipher = 0; - uint8_t c_group_mgmt_cipher = 0; - uint8_t c_auth_suites = 0, i; - uint8_t unicast[CSR_RSN_OUI_SIZE]; - uint8_t multicast[CSR_RSN_OUI_SIZE]; - uint8_t group_mgmt[CSR_RSN_OUI_SIZE]; - uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE]; - uint8_t authentication[CSR_RSN_OUI_SIZE]; - uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE]; - uint8_t group_mgmt_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE]; - enum csr_akm_type neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; - - if (!rsn_ie->present) - goto end; - c_mcast_cipher++; - qdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite, - CSR_RSN_OUI_SIZE); - c_ucast_cipher = - (uint8_t) (rsn_ie->pwise_cipher_suite_count); - - c_auth_suites = (uint8_t) (rsn_ie->akm_suite_cnt); - for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) { - qdf_mem_copy((void *)&authsuites[i], - (void *)&rsn_ie->akm_suite[i], CSR_RSN_OUI_SIZE); - } + struct wlan_crypto_pmksa *pmksa; + struct wlan_objmgr_vdev *vdev; - /* Check - Is requested unicast Cipher supported by the BSS. */ - acceptable_cipher = csr_match_rsnoui_index(mac_ctx, - rsn_ie->pwise_cipher_suites, c_ucast_cipher, - csr_get_oui_index_from_cipher(encr_type), - unicast); - - if (!acceptable_cipher) - goto end; - - /* unicast is supported. Pick the first matching Group cipher, if any */ - for (i = 0; i < mc_encryption->numEntries; i++) { - acceptable_cipher = csr_match_rsnoui_index(mac_ctx, - mccipher_arr, c_mcast_cipher, - csr_get_oui_index_from_cipher( - mc_encryption->encryptionType[i]), - multicast); - if (acceptable_cipher) - break; - } - if (!acceptable_cipher) - goto end; - - if (negotiated_mccipher) - *negotiated_mccipher = mc_encryption->encryptionType[i]; - - /* Group Management Cipher only for 11w */ - if (mgmt_encryption_type) { - c_group_mgmt_cipher++; - qdf_mem_copy(group_mgmt_arr, rsn_ie->gp_mgmt_cipher_suite, - CSR_RSN_OUI_SIZE); - if (csr_is_group_mgmt_gmac_128(mac_ctx, group_mgmt_arr, - c_group_mgmt_cipher, group_mgmt)) { - group_mgmt_acceptable_cipher = true; - *mgmt_encryption_type = eSIR_ED_AES_GMAC_128; - } else if (csr_is_group_mgmt_gmac_256(mac_ctx, group_mgmt_arr, - c_group_mgmt_cipher, group_mgmt)) { - group_mgmt_acceptable_cipher = true; - *mgmt_encryption_type = eSIR_ED_AES_GMAC_256; - } else { - /* Default is CMAC */ - group_mgmt_acceptable_cipher = true; - *mgmt_encryption_type = eSIR_ED_AES_128_CMAC; - qdf_mem_copy(group_mgmt, csr_group_mgmt_oui[ENUM_CMAC], - CSR_RSN_OUI_SIZE); - } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session->vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return false; } - /* Initializing with false as it has true value already */ - acceptable_cipher = false; - for (i = 0; i < auth_type->numEntries; i++) { - /* - * Ciphers are supported, Match authentication algorithm and - * pick first matching authtype. - */ - /* Set FILS as first preference */ - csr_is_fils_auth(mac_ctx, authsuites, c_auth_suites, - authentication, auth_type, i, &neg_authtype); - /* Changed the AKM suites according to order of preference */ - csr_check_sae_auth(mac_ctx, authsuites, c_auth_suites, - authentication, auth_type, i, &neg_authtype); - - if (neg_authtype == eCSR_AUTH_TYPE_UNKNOWN && - csr_is_auth_osen(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_OSEN == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_OSEN; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_dpp_rsn(mac_ctx, authsuites, - c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_DPP_RSN == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_DPP_RSN; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_ft_auth_rsn(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_FT_RSN; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) - && csr_is_ft_auth_rsn_psk(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_FT_RSN_PSK == - auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK; - } -#ifdef FEATURE_WLAN_ESE - /* ESE only supports 802.1X. No PSK. */ - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN; - } -#endif - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_rsn(mac_ctx, authsuites, - c_auth_suites, authentication)) { - /* - * For adaptive 11r connection send FT-802.1X akm in - * association request - */ - if (adaptive_11r && - eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) { - neg_authtype = eCSR_AUTH_TYPE_FT_RSN; - qdf_mem_copy(authentication, - csr_rsn_oui[FT_8021X_IDX], - CSR_WPA_OUI_SIZE); - } + pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache->BSSID); + if (!pmksa) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return false; + } + qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, sizeof(pmk_cache->PMKID)); + qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len); + pmk_cache->pmk_len = pmksa->pmk_len; + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_RSN; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_rsn_psk(mac_ctx, authsuites, - c_auth_suites, authentication)) { - /* - * For adaptive 11r connection send FT-PSK akm in - * association request - */ - if (adaptive_11r && - eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type->authType[i]) { - neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK; - qdf_mem_copy(authentication, - csr_rsn_oui[FT_PSK_IDX], - CSR_WPA_OUI_SIZE); - } + return true; +} - if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_RSN_PSK; - } -#ifdef WLAN_FEATURE_11W - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites, - c_auth_suites, authentication)) { - /* - * For adaptive 11r connection send AP advertises only - * PSK AKM. STA can choose FT-PSK akm in association - * request if FT capable. - */ - if (adaptive_11r && - eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type->authType[i]) { - neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK; - qdf_mem_copy(authentication, - csr_rsn_oui[FT_PSK_IDX], - CSR_WPA_OUI_SIZE); - } +bool csr_lookup_fils_pmkid(struct mac_context *mac, + uint8_t vdev_id, uint8_t *cache_id, + uint8_t *ssid, uint8_t ssid_len, + struct qdf_mac_addr *bssid) +{ + struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa; + struct wlan_objmgr_vdev *vdev; - if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == - auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_rsn8021x_sha256(mac_ctx, - authsuites, c_auth_suites, - authentication)) { - /* - * For adaptive 11r connection send FT-802.1x akm in - * association request - */ - if (adaptive_11r && - eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) { - neg_authtype = eCSR_AUTH_TYPE_FT_RSN; - qdf_mem_copy(authentication, - csr_rsn_oui[FT_8021X_IDX], - CSR_WPA_OUI_SIZE); - } - if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == - auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256; - } -#endif - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_wpa_owe(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_OWE == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_OWE; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_suiteb_eap_256(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 == - auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_suiteb_eap_384(mac_ctx, authsuites, - c_auth_suites, authentication)) { - if (eCSR_AUTH_TYPE_SUITEB_EAP_SHA384 == - auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_ft_suiteb_eap_384(mac_ctx, authsuites, - c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384 == - auth_type->authType[i]) - neg_authtype = - eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384; - } - - /* - * The 1st auth type in the APs RSN IE, to match stations - * connecting profiles auth type will cause us to exit this - * loop. This is added as some APs advertise multiple akms in - * the RSN IE - */ - if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) { - acceptable_cipher = true; - break; - } - } /* for */ -end: - if (acceptable_cipher) { - if (mcast_cipher) - qdf_mem_copy(mcast_cipher, multicast, - CSR_RSN_OUI_SIZE); - - if (ucast_cipher) - qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE); - - if (gp_mgmt_cipher && group_mgmt_acceptable_cipher) - qdf_mem_copy(gp_mgmt_cipher, group_mgmt, - CSR_RSN_OUI_SIZE); - - if (auth_suite) - qdf_mem_copy(auth_suite, authentication, - CSR_RSN_OUI_SIZE); - - if (negotiated_authtype) - *negotiated_authtype = neg_authtype; - - if (capabilities) { - /* Bit 0 Preauthentication */ - capabilities->PreAuthSupported = - (rsn_ie->RSN_Cap[0] >> 0) & 0x1; - /* Bit 1 No Pairwise */ - capabilities->NoPairwise = - (rsn_ie->RSN_Cap[0] >> 1) & 0x1; - /* Bit 2, 3 PTKSA Replay Counter */ - capabilities->PTKSAReplayCounter = - (rsn_ie->RSN_Cap[0] >> 2) & 0x3; - /* Bit 4, 5 GTKSA Replay Counter */ - capabilities->GTKSAReplayCounter = - (rsn_ie->RSN_Cap[0] >> 4) & 0x3; -#ifdef WLAN_FEATURE_11W - /* Bit 6 MFPR */ - capabilities->MFPRequired = - (rsn_ie->RSN_Cap[0] >> 6) & 0x1; - /* Bit 7 MFPC */ - capabilities->MFPCapable = - (rsn_ie->RSN_Cap[0] >> 7) & 0x1; -#else - /* Bit 6 MFPR */ - capabilities->MFPRequired = 0; - /* Bit 7 MFPC */ - capabilities->MFPCapable = 0; -#endif - /* remaining reserved */ - capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff; - } - } - return acceptable_cipher; -} - -#ifdef WLAN_FEATURE_11W -/** - * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability - * @mac: Global MAC Context - * @pFilterMFPEnabled: given by supplicant to us to specify what kind - * of connection supplicant is expecting to make - * if it is enabled then make PMF connection. - * if it is disabled then make normal connection. - * @pFilterMFPRequired: given by supplicant based on our configuration - * if it is 1 then we will require mandatory - * PMF connection and if it is 0 then we PMF - * connection is optional. - * @pFilterMFPCapable: given by supplicant based on our configuration - * if it 1 then we are PMF capable and if it 0 - * then we are not PMF capable. - * @pRSNIe: RSNIe from Beacon/probe response of - * neighbor AP against which we will compare - * our capabilities. - * - * This function is to match our current capabilities with the AP - * to which we are expecting make the connection. - * - * Return: if our PMF capabilities matches with AP then we - * will return true to indicate that we are good - * to make connection with it. Else we will return false - **/ -static bool -csr_is_pmf_capabilities_in_rsn_match(struct mac_context *mac, - bool *pFilterMFPEnabled, - uint8_t *pFilterMFPRequired, - uint8_t *pFilterMFPCapable, - tDot11fIERSN *pRSNIe) -{ - uint8_t apProfileMFPCapable = 0; - uint8_t apProfileMFPRequired = 0; - - if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable - && pFilterMFPRequired) { - /* Extracting MFPCapable bit from RSN Ie */ - apProfileMFPCapable = csr_is_mfpc_capable(pRSNIe); - apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1; - - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "pFilterMFPEnabled: %d pFilterMFPRequired: %d pFilterMFPCapable: %d apProfileMFPCapable: %d apProfileMFPRequired: %d", - *pFilterMFPEnabled, *pFilterMFPRequired, - *pFilterMFPCapable, apProfileMFPCapable, - apProfileMFPRequired); - - if (*pFilterMFPEnabled && *pFilterMFPCapable - && *pFilterMFPRequired && (apProfileMFPCapable == 0)) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "AP is not capable to make PMF connection"); - return false; - } else if (!(*pFilterMFPCapable) && - apProfileMFPCapable && apProfileMFPRequired) { - - /* - * In this case, AP with whom we trying to connect - * requires mandatory PMF connections and we are not - * capable so this AP is not good choice to connect - */ - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, - "AP needs PMF connection and we are not capable of pmf connection"); - return false; - } - } - return true; -} -#endif - -static bool csr_is_rsn_match(struct mac_context *mac_ctx, tCsrAuthList *pAuthType, - eCsrEncryptionType enType, - tCsrEncryptionList *pEnMcType, - bool *pMFPEnabled, uint8_t *pMFPRequired, - uint8_t *pMFPCapable, - tDot11fBeaconIEs *pIes, - enum csr_akm_type *negotiated_akm, - eCsrEncryptionType *pNegotiatedMCCipher) -{ - bool fRSNMatch = false; - - /* See if the cyphers in the Bss description match with the - * settings in the profile. - */ - fRSNMatch = csr_get_rsn_information(mac_ctx, pAuthType, enType, - pEnMcType, &pIes->RSN, NULL, NULL, - NULL, NULL, negotiated_akm, - pNegotiatedMCCipher, NULL, NULL, - false); -#ifdef WLAN_FEATURE_11W - /* If all the filter matches then finally checks for PMF capabilities */ - if (fRSNMatch) - fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(mac_ctx, - pMFPEnabled, - pMFPRequired, - pMFPCapable, - &pIes->RSN); -#endif - return fRSNMatch; -} - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * csr_lookup_pmkid_using_ssid() - lookup pmkid using ssid and cache_id - * @mac: pointer to mac - * @session: sme session pointer - * @pmk_cache: pointer to pmk cache - * @index: index value needs to be seached - * - * Return: true if pmkid is found else false - */ -static bool csr_lookup_pmkid_using_ssid(struct mac_context *mac, - struct csr_roam_session *session, - tPmkidCacheInfo *pmk_cache, - uint32_t *index) -{ - uint32_t i; - tPmkidCacheInfo *session_pmk; - - for (i = 0; i < session->NumPmkidCache; i++) { - session_pmk = &session->PmkidCacheInfo[i]; - sme_debug("match PMKID ssid %*.*s cache id %x %x ssid_len %d to ssid %s cache_id %x %x", - pmk_cache->ssid_len, pmk_cache->ssid_len, - pmk_cache->ssid, pmk_cache->cache_id[0], - pmk_cache->cache_id[1], pmk_cache->ssid_len, - session_pmk->ssid, - session_pmk->cache_id[0], session_pmk->cache_id[1]); - - if ((!qdf_mem_cmp(pmk_cache->ssid, session_pmk->ssid, - pmk_cache->ssid_len)) && - (!qdf_mem_cmp(session_pmk->cache_id, - pmk_cache->cache_id, CACHE_ID_LEN))) { - /* match found */ - *index = i; - sme_debug("PMKID found at index %d", i); - return true; - } - } - - return false; -} -#endif - -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT -bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, - struct csr_roam_session *session, - tPmkidCacheInfo *pmk_cache, - uint32_t *index) -{ - struct wlan_crypto_pmksa *pmksa; - struct wlan_objmgr_vdev *vdev; - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session->vdev_id, + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, WLAN_LEGACY_SME_ID); if (!vdev) { sme_err("Invalid vdev"); return false; } - pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache->BSSID); - if (!pmksa) { + bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, bssid); + fils_ssid_pmksa = + wlan_crypto_get_fils_pmksa(vdev, cache_id, ssid, ssid_len); + if (!fils_ssid_pmksa && !bssid_lookup_pmksa) { + sme_err("FILS_PMKSA: Lookup failed"); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return false; } - qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, sizeof(pmk_cache->PMKID)); - qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len); - pmk_cache->pmk_len = pmksa->pmk_len; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return true; } -#else -bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, - struct csr_roam_session *session, - tPmkidCacheInfo *pmk_cache, - uint32_t *index) -{ - uint32_t i; - tPmkidCacheInfo *session_pmk; - - for (i = 0; i < session->NumPmkidCache; i++) { - session_pmk = &session->PmkidCacheInfo[i]; - sme_debug("Matching BSSID: " QDF_MAC_ADDR_STR " to cached BSSID:" - QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(pmk_cache->BSSID.bytes), - QDF_MAC_ADDR_ARRAY(session_pmk->BSSID.bytes)); - if (qdf_is_macaddr_equal(&pmk_cache->BSSID, - &session_pmk->BSSID)) { - /* match found */ - *index = i; - sme_debug("PMKID found at index %d", i); - qdf_mem_copy(pmk_cache, session_pmk, - sizeof(tPmkidCacheInfo)); - return true; - } - } - - return false; -} -#endif - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * csr_lookup_pmkid() - lookup pmkid using bssid or ssid + cache_id - * @mac: pointer to mac - * @session: sme session pointer - * @pmk_cache: pointer to pmk cache - * @index: index value needs to be seached - * - * Return: true if pmkid is found else false - */ -bool csr_lookup_pmkid(struct mac_context *mac, uint32_t sessionId, - tPmkidCacheInfo *pmk_cache) -{ - bool fRC = false, fMatchFound = false; - uint32_t Index; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("session %d not found", sessionId); - return false; - } - - if (pmk_cache->ssid_len) { - /* Try to find based on cache_id and ssid first */ - fMatchFound = csr_lookup_pmkid_using_ssid(mac, pSession, - pmk_cache, &Index); - } - - /* If not able to find using cache id or ssid_len is not present */ - if (!fMatchFound) - fMatchFound = csr_lookup_pmkid_using_bssid(mac, - pSession, pmk_cache, &Index); - - if (!fMatchFound) { - sme_debug("no pmkid match found NumPmkidCache = %d", - pSession->NumPmkidCache); - return false; - } - - qdf_mem_copy(pmk_cache->PMKID, - pSession->PmkidCacheInfo[Index].PMKID, - PMKID_LEN); - - qdf_mem_copy(pmk_cache->pmk, - pSession->PmkidCacheInfo[Index].pmk, - pSession->PmkidCacheInfo[Index].pmk_len); - pmk_cache->pmk_len = pSession->PmkidCacheInfo[Index].pmk_len; - - fRC = true; - sme_debug("match = %d NumPmkidCache = %d", - fRC, pSession->NumPmkidCache); - - return fRC; -} -#endif - -#ifdef WLAN_FEATURE_FILS_SK -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/* - * csr_update_pmksa_for_cache_id: update tPmkidCacheInfo to lookup using - * ssid and cache id - * @bss_desc: bss description - * @profile: csr roam profile - * @pmkid_cache: pmksa cache - * - * Return: true if cache identifier present else false - */ -static bool csr_update_pmksa_for_cache_id(struct bss_description *bss_desc, - struct csr_roam_profile *profile, - tPmkidCacheInfo *pmkid_cache) -{ - if (!bss_desc->fils_info_element.is_cache_id_present) - return false; - - pmkid_cache->ssid_len = - profile->SSIDs.SSIDList[0].SSID.length; - qdf_mem_copy(pmkid_cache->ssid, - profile->SSIDs.SSIDList[0].SSID.ssId, - profile->SSIDs.SSIDList[0].SSID.length); - qdf_mem_copy(pmkid_cache->cache_id, - bss_desc->fils_info_element.cache_id, - CACHE_ID_LEN); - qdf_mem_copy(pmkid_cache->BSSID.bytes, - bss_desc->bssId, QDF_MAC_ADDR_SIZE); - - return true; - -} -#endif -/* - * csr_update_pmksa_to_profile: update pmk and pmkid to profile which will be - * used in case of fils session - * @profile: profile - * @pmkid_cache: pmksa cache - * - * Return: None - */ -static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile, - tPmkidCacheInfo *pmkid_cache) -{ - if (!profile->fils_con_info) - return; - - profile->fils_con_info->pmk_len = pmkid_cache->pmk_len; - qdf_mem_copy(profile->fils_con_info->pmk, - pmkid_cache->pmk, pmkid_cache->pmk_len); - qdf_mem_copy(profile->fils_con_info->pmkid, - pmkid_cache->PMKID, PMKID_LEN); - -} -#else -static inline -bool csr_update_pmksa_for_cache_id(struct bss_description *bss_desc, - struct csr_roam_profile *profile, - tPmkidCacheInfo *pmkid_cache) -{ - return false; -} - -static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile, - tPmkidCacheInfo *pmkid_cache) -{ -} -#endif -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT -uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *ap_ie, tCsrRSNIe *pRSNIe) -{ - struct wlan_objmgr_vdev *vdev; - uint8_t *rsn_ie_end = NULL; - uint8_t *rsn_ie = (uint8_t *)pRSNIe; - uint8_t ie_len = 0; - tDot11fBeaconIEs *local_ap_ie = ap_ie; - uint16_t rsn_cap = 0; - struct qdf_mac_addr bssid; - - if (!local_ap_ie && - (!QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies - (mac, pSirBssDesc, &local_ap_ie)))) - return ie_len; - - /* get AP RSN cap */ - qdf_mem_copy(&rsn_cap, local_ap_ie->RSN.RSN_Cap, sizeof(rsn_cap)); - if (!ap_ie && local_ap_ie) - /* locally allocated */ - qdf_mem_free(local_ap_ie); - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, sessionId, - WLAN_LEGACY_SME_ID); - if (!vdev) { - sme_err("Invalid vdev"); - return ie_len; - } - /* - * Use intersection of the RSN cap sent by user space and - * the AP, so that only common capability are enabled. - */ - rsn_cap &= (uint16_t)wlan_crypto_get_param(vdev, - WLAN_CRYPTO_PARAM_RSN_CAP); - wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP, rsn_cap); - qdf_mem_copy(bssid.bytes, pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE); - - /* - * TODO: Add support for Adaptive 11r connection after - * call to csr_get_rsn_information is added here - */ - rsn_ie_end = wlan_crypto_build_rsnie(vdev, rsn_ie, &bssid); - - if (rsn_ie_end) - ie_len = rsn_ie_end - rsn_ie; - - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - - return ie_len; -} -#else /** * csr_update_session_pmk() - Update the pmk len and pmk in the roam session * @session: pointer to the CSR Roam session @@ -3985,720 +2848,135 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD static void csr_update_session_pmk(struct csr_roam_session *session, - tPmkidCacheInfo *pmkid_cache) + struct wlan_crypto_pmksa *pmksa) { - session->pmk_len = pmkid_cache->pmk_len; + session->pmk_len = pmksa->pmk_len; qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk)); - qdf_mem_copy(session->psk_pmk, pmkid_cache->pmk, session->pmk_len); + qdf_mem_copy(session->psk_pmk, pmksa->pmk, session->pmk_len); } #else static inline void csr_update_session_pmk(struct csr_roam_session *session, - tPmkidCacheInfo *pmkid_cache) + struct wlan_crypto_pmksa *pmksa) { } #endif -uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe) -{ - uint32_t ret; - bool fRSNMatch; - uint8_t cbRSNIe = 0; - uint8_t UnicastCypher[CSR_RSN_OUI_SIZE]; - uint8_t MulticastCypher[CSR_RSN_OUI_SIZE]; - uint8_t gp_mgmt_cipher_suite[CSR_RSN_OUI_SIZE]; - uint8_t AuthSuite[CSR_RSN_OUI_SIZE]; - tCsrRSNAuthIe *pAuthSuite; - struct rsn_caps RSNCapabilities; - tCsrRSNPMKIe *pPMK; - tPmkidCacheInfo pmkid_cache; -#ifdef WLAN_FEATURE_11W - uint8_t *pGroupMgmtCipherSuite; -#endif - tDot11fBeaconIEs *pIesLocal = pIes; - enum csr_akm_type negAuthType = eCSR_AUTH_TYPE_UNKNOWN; - tDot11fIERSN rsn_ie = {0}; - struct csr_roam_session *session = CSR_GET_SESSION(mac, sessionId); - - if (!CSR_IS_SESSION_VALID(mac, sessionId) || !session) - return 0; - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); - qdf_mem_zero(&rsn_ie, sizeof(rsn_ie)); - - do { - if (!csr_is_profile_rsn(pProfile)) - break; - - if (!pIesLocal - && - (!QDF_IS_STATUS_SUCCESS - (csr_get_parsed_bss_description_ies - (mac, pSirBssDesc, &pIesLocal)))) { - break; - } - - /* - * Use intersection of the RSN cap sent by user space and - * the AP, so that only common capability are enabled. - */ - if (pProfile->pRSNReqIE && pProfile->nRSNReqIELength) { - ret = dot11f_unpack_ie_rsn(mac, - pProfile->pRSNReqIE + 2, - pProfile->nRSNReqIELength -2, &rsn_ie, false); - if (!DOT11F_FAILED(ret)) { - pIesLocal->RSN.RSN_Cap[0] = - pIesLocal->RSN.RSN_Cap[0] & - rsn_ie.RSN_Cap[0]; - pIesLocal->RSN.RSN_Cap[1] = - pIesLocal->RSN.RSN_Cap[1] & - rsn_ie.RSN_Cap[1]; - } - } - /* See if the cyphers in the Bss description match with the - * settings in the profile. - */ - fRSNMatch = csr_get_rsn_information(mac, &pProfile->AuthType, - pProfile->negotiatedUCEncryptionType, - &pProfile->mcEncryptionType, - &pIesLocal->RSN, UnicastCypher, - MulticastCypher, AuthSuite, - &RSNCapabilities, &negAuthType, NULL, - gp_mgmt_cipher_suite, - &pProfile->mgmt_encryption_type, - session->is_adaptive_11r_connection); - if (!fRSNMatch) - break; - - pRSNIe->IeHeader.ElementID = WLAN_ELEMID_RSN; - - pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED; - - qdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher, - sizeof(MulticastCypher)); - - pRSNIe->cUnicastCyphers = 1; - - qdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher, - sizeof(UnicastCypher)); - - pAuthSuite = - (tCsrRSNAuthIe *) (&pRSNIe-> - UnicastOui[pRSNIe->cUnicastCyphers]); - - pAuthSuite->cAuthenticationSuites = 1; - qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite, - sizeof(AuthSuite)); - - /* PreAuthSupported is an AP only capability */ - RSNCapabilities.PreAuthSupported = 0; - /* - * Use the Management Frame Protection values given by the - * supplicant, if AP and STA both are MFP capable. - */ -#ifdef WLAN_FEATURE_11W - if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) { - RSNCapabilities.MFPCapable = pProfile->MFPCapable; - RSNCapabilities.MFPRequired = pProfile->MFPRequired; - } else { - RSNCapabilities.MFPCapable = 0; - RSNCapabilities.MFPRequired = 0; - } -#endif - *(uint16_t *) (&pAuthSuite->AuthOui[1]) = - *((uint16_t *) (&RSNCapabilities)); - - pPMK = (tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1])) - + sizeof(uint16_t)); - - if (!csr_update_pmksa_for_cache_id(pSirBssDesc, - pProfile, &pmkid_cache)) - qdf_mem_copy(pmkid_cache.BSSID.bytes, - pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE); - /* Don't include the PMK SA IDs for CCKM associations. */ - if ( -#ifdef FEATURE_WLAN_ESE - (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) && -#endif - csr_lookup_pmkid(mac, sessionId, &pmkid_cache)) { - pPMK->cPMKIDs = 1; - - qdf_trace_hex_dump(QDF_MODULE_ID_PE, - QDF_TRACE_LEVEL_INFO, - pmkid_cache.pmk, pmkid_cache.pmk_len); - qdf_mem_copy(pPMK->PMKIDList[0].PMKID, - pmkid_cache.PMKID, - PMKID_LEN); - - /* - * If a PMK cache is found for the BSSID, then - * update the PMK in CSR session also as this - * will be sent to the FW during RSO. - */ - csr_update_session_pmk(session, &pmkid_cache); - - csr_update_pmksa_to_profile(pProfile, &pmkid_cache); - } else { - pPMK->cPMKIDs = 0; - } - session->rsn_caps = RSNCapabilities; - - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); - -#ifdef WLAN_FEATURE_11W - /* Advertise BIP in group cipher key management only if PMF is - * enabled and AP is capable. - */ - if (pProfile->MFPEnabled && - (RSNCapabilities.MFPCapable && pProfile->MFPCapable)) { - pGroupMgmtCipherSuite = - (uint8_t *) pPMK + sizeof(uint16_t) + - (pPMK->cPMKIDs * PMKID_LEN); - qdf_mem_copy(pGroupMgmtCipherSuite, - gp_mgmt_cipher_suite, CSR_RSN_OUI_SIZE); - } -#endif - host_log_rsn_info(UnicastCypher, MulticastCypher, - AuthSuite, gp_mgmt_cipher_suite); - - /* Add in the fixed fields plus 1 Unicast cypher, less the - * IE Header length Add in the size of the Auth suite (count - * plus a single OUI) Add in the RSN caps field. - * Add PMKID count and PMKID (if any) - * Add group management cipher suite - */ - pRSNIe->IeHeader.Length = - (uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) + - sizeof(*pAuthSuite) + - sizeof(struct rsn_caps)); - if (pPMK->cPMKIDs) - pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) + - (pPMK->cPMKIDs * - PMKID_LEN)); -#ifdef WLAN_FEATURE_11W - if (pProfile->MFPEnabled && - (RSNCapabilities.MFPCapable && pProfile->MFPCapable)) { - if (0 == pPMK->cPMKIDs) - pRSNIe->IeHeader.Length += sizeof(uint16_t); - pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE; - } -#endif - - /* return the size of the IE header (total) constructed... */ - cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader); - - } while (0); - - if (!pIes && pIesLocal) - /* locally allocated */ - qdf_mem_free(pIesLocal); - - return cbRSNIe; -} -#endif - -#ifdef FEATURE_WLAN_WAPI +#ifdef WLAN_FEATURE_FILS_SK /** - * csr_get_wapi_information() - to get WAPI information - * @mac_ctx: pointer to global MAC context - * @auth_type: auth type - * @encr_type: encryption type - * @mc_encryption: multicast encryption type - * @wapi_ie: pointer to WAPI IE - * @ucast_cipher: Unicast cipher - * @mcast_cipher: Multicast cipher - * @auth_suite: Authentication suite - * @negotiated_authtype: Negotiated auth type - * @negotiated_mccipher: negotiated multicast cipher - * - * This routine will get all WAPI information + * csr_update_pmksa_to_profile() - update pmk and pmkid to profile which will be + * used in case of fils session + * @profile: profile + * @pmkid_cache: pmksa cache * - * Return: bool + * Return: None */ -static bool csr_get_wapi_information(struct mac_context *mac_ctx, - tCsrAuthList *auth_type, - eCsrEncryptionType encr_type, - tCsrEncryptionList *mc_encryption, - tDot11fIEWAPI *wapi_ie, - uint8_t *ucast_cipher, - uint8_t *mcast_cipher, uint8_t *auth_suite, - enum csr_akm_type *negotiated_authtype, - eCsrEncryptionType *negotiated_mccipher) -{ - bool acceptable_cipher = false; - uint8_t c_ucast_cipher = 0; - uint8_t c_mcast_cipher = 0; - uint8_t c_auth_suites = 0, i; - uint8_t unicast[CSR_WAPI_OUI_SIZE]; - uint8_t multicast[CSR_WAPI_OUI_SIZE]; - uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE]; - uint8_t authentication[CSR_WAPI_OUI_SIZE]; - uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE]; - enum csr_akm_type neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; - uint8_t wapioui_idx = 0; - - if (!wapi_ie->present) - goto end; - - c_mcast_cipher++; - qdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite, - CSR_WAPI_OUI_SIZE); - c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count); - c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count); - for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++) - qdf_mem_copy((void *)&authsuites[i], - (void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE); - - wapioui_idx = csr_get_oui_index_from_cipher(encr_type); - if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) { - sme_err("Wapi OUI index = %d out of limit", - wapioui_idx); - acceptable_cipher = false; - goto end; - } - /* Check - Is requested unicast Cipher supported by the BSS. */ - acceptable_cipher = csr_match_wapi_oui_index(mac_ctx, - wapi_ie->unicast_cipher_suites, - c_ucast_cipher, wapioui_idx, unicast); - if (!acceptable_cipher) - goto end; - - /* unicast is supported. Pick the first matching Group cipher, if any */ - for (i = 0; i < mc_encryption->numEntries; i++) { - wapioui_idx = csr_get_oui_index_from_cipher( - mc_encryption->encryptionType[i]); - if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) { - sme_err("Wapi OUI index = %d out of limit", - wapioui_idx); - acceptable_cipher = false; - break; - } - acceptable_cipher = csr_match_wapi_oui_index(mac_ctx, - mccipher_arr, c_mcast_cipher, - wapioui_idx, multicast); - if (acceptable_cipher) - break; - } - if (!acceptable_cipher) - goto end; - - if (negotiated_mccipher) - *negotiated_mccipher = - mc_encryption->encryptionType[i]; - - /* - * Ciphers are supported, Match authentication algorithm and - * pick first matching authtype - */ - if (csr_is_auth_wapi_cert - (mac_ctx, authsuites, c_auth_suites, authentication)) { - neg_authtype = - eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; - } else if (csr_is_auth_wapi_psk(mac_ctx, authsuites, - c_auth_suites, authentication)) { - neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK; - } else { - acceptable_cipher = false; - neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; - } - - /* Caller doesn't care about auth type, or BSS doesn't match */ - if ((0 == auth_type->numEntries) || (false == acceptable_cipher)) - goto end; - - acceptable_cipher = false; - for (i = 0; i < auth_type->numEntries; i++) { - if (auth_type->authType[i] == neg_authtype) { - acceptable_cipher = true; - break; - } - } - -end: - if (acceptable_cipher) { - if (mcast_cipher) - qdf_mem_copy(mcast_cipher, multicast, - CSR_WAPI_OUI_SIZE); - if (ucast_cipher) - qdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE); - if (auth_suite) - qdf_mem_copy(auth_suite, authentication, - CSR_WAPI_OUI_SIZE); - if (negotiated_authtype) - *negotiated_authtype = neg_authtype; - } - return acceptable_cipher; -} - -static bool csr_is_wapi_match(struct mac_context *mac_ctx, tCsrAuthList *pAuthType, - eCsrEncryptionType enType, - tCsrEncryptionList *pEnMcType, - tDot11fBeaconIEs *pIes, - enum csr_akm_type *negotiated_akm, - eCsrEncryptionType *pNegotiatedMCCipher) -{ - bool fWapiMatch = false; - - /* See if the cyphers in the Bss description match with the - * settings in the profile. - */ - fWapiMatch = - csr_get_wapi_information(mac_ctx, pAuthType, enType, pEnMcType, - &pIes->WAPI, NULL, NULL, NULL, - negotiated_akm, pNegotiatedMCCipher); - - return fWapiMatch; -} - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -static bool csr_lookup_bkid(struct mac_context *mac, uint32_t sessionId, - uint8_t *pBSSId, uint8_t *pBKId) -{ - bool fRC = false, fMatchFound = false; - uint32_t Index; - struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - - if (!pSession) { - sme_err("session %d not found", sessionId); - return false; - } - - do { - for (Index = 0; Index < pSession->NumBkidCache; Index++) { - sme_debug("match BKID " QDF_MAC_ADDR_STR " to ", - QDF_MAC_ADDR_ARRAY(pBSSId)); - if (!qdf_mem_cmp - (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes, - sizeof(struct qdf_mac_addr))) { - /* match found */ - fMatchFound = true; - break; - } - } - - if (!fMatchFound) - break; - - qdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID, - CSR_WAPI_BKID_SIZE); - - fRC = true; - } while (0); - sme_debug( - "return match = %d mac->roam.NumBkidCache = %d", - fRC, pSession->NumBkidCache); - - return fRC; -} -#endif - -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT -uint8_t csr_construct_wapi_ie(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe) -{ - struct wlan_objmgr_vdev *vdev; - uint8_t *wapi_ie_end = NULL; - uint8_t *wapi_ie = (uint8_t *)pWapiIe; - uint8_t ie_len = 0; - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, sessionId, - WLAN_LEGACY_SME_ID); - if (!vdev) { - sme_err("Invalid vdev"); - return ie_len; - } - wapi_ie_end = wlan_crypto_build_wapiie(vdev, wapi_ie); - if (wapi_ie_end) - ie_len = wapi_ie_end - wapi_ie; - - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - - return ie_len; -} -#else -uint8_t csr_construct_wapi_ie(struct mac_context *mac, uint32_t sessionId, - struct csr_roam_profile *pProfile, - struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe) +static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile, + struct wlan_crypto_pmksa *pmksa) { - bool fWapiMatch = false; - uint8_t cbWapiIe = 0; - uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE]; - uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE]; - uint8_t AuthSuite[CSR_WAPI_OUI_SIZE]; - uint8_t BKId[CSR_WAPI_BKID_SIZE]; - uint8_t *pWapi = NULL; - bool fBKIDFound = false; - tDot11fBeaconIEs *pIesLocal = pIes; - - do { - if (!csr_is_profile_wapi(pProfile)) - break; - - if (!pIesLocal - && - (!QDF_IS_STATUS_SUCCESS - (csr_get_parsed_bss_description_ies - (mac, pSirBssDesc, &pIesLocal)))) { - break; - } - /* See if the cyphers in the Bss description match with the - * settings in the profile. - */ - fWapiMatch = - csr_get_wapi_information(mac, &pProfile->AuthType, - pProfile->negotiatedUCEncryptionType, - &pProfile->mcEncryptionType, - &pIesLocal->WAPI, UnicastCypher, - MulticastCypher, AuthSuite, NULL, - NULL); - if (!fWapiMatch) - break; - - qdf_mem_zero(pWapiIe, sizeof(tCsrWapiIe)); - - pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI; - - pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED; - - pWapiIe->cAuthenticationSuites = 1; - qdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite, - sizeof(AuthSuite)); - - pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]); - - *pWapi = (uint16_t) 1; /* cUnicastCyphers */ - pWapi += 2; - qdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher)); - pWapi += sizeof(UnicastCypher); - - qdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher)); - pWapi += sizeof(MulticastCypher); - - /* WAPI capabilities follows the Auth Suite (two octects) - * we shouldn't EVER be sending out "pre-auth supported". - * It is an AP only capability & since we already did a memset - * pWapiIe to 0, skip these fields - */ - pWapi += 2; - - fBKIDFound = - csr_lookup_bkid(mac, sessionId, pSirBssDesc->bssId, - &(BKId[0])); - - if (fBKIDFound) { - /* Do we need to change the endianness here */ - *pWapi = (uint16_t) 1; /* cBKIDs */ - pWapi += 2; - qdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE); - } else { - *pWapi = 0; - pWapi += 1; - *pWapi = 0; - pWapi += 1; - } - - /* Add in the IE fields except the IE header */ - /* Add BKID count and BKID (if any) */ - pWapiIe->IeHeader.Length = - (uint8_t) (sizeof(*pWapiIe) - - sizeof(pWapiIe->IeHeader)); - - /*2 bytes for BKID Count field */ - pWapiIe->IeHeader.Length += sizeof(uint16_t); - - if (fBKIDFound) - pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE; - - /* return the size of the IE header (total) constructed... */ - cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader); - - } while (0); - - if (!pIes && pIesLocal) - /* locally allocated */ - qdf_mem_free(pIesLocal); + if (!profile->fils_con_info) + return; - return cbWapiIe; + profile->fils_con_info->pmk_len = pmksa->pmk_len; + qdf_mem_copy(profile->fils_con_info->pmk, + pmksa->pmk, pmksa->pmk_len); + qdf_mem_copy(profile->fils_con_info->pmkid, + pmksa->pmkid, PMKID_LEN); +} +#else +static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile, + struct wlan_crypto_pmksa *pmksa) +{ } #endif -#endif /* FEATURE_WLAN_WAPI */ -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * csr_get_wpa_cyphers() - to get WPA cipher info - * @mac_ctx: pointer to mac context - * @auth_type: auth type - * @encr_type: encryption type - * @mc_encryption: multicast encryption type - * @wpa_ie: pointer to WPA IE - * @ucast_cipher: Unicast cipher - * @mcast_cipher: Multicast cipher - * @auth_suite: Authentication suite - * @negotiated_authtype: Negotiated auth type - * @negotiated_mccipher: negotiated multicast cipher - * - * This routine will get all WPA information - * - * Return: bool - */ -static bool csr_get_wpa_cyphers(struct mac_context *mac_ctx, tCsrAuthList *auth_type, - eCsrEncryptionType encr_type, - tCsrEncryptionList *mc_encryption, - tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher, - uint8_t *mcast_cipher, uint8_t *auth_suite, - enum csr_akm_type *negotiated_authtype, - eCsrEncryptionType *negotiated_mccipher) +uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId, + struct csr_roam_profile *pProfile, + struct bss_description *pSirBssDesc, + tDot11fBeaconIEs *ap_ie, tCsrRSNIe *pRSNIe) { - bool acceptable_cipher = false; - uint8_t c_ucast_cipher = 0; - uint8_t c_mcast_cipher = 0; - uint8_t c_auth_suites = 0; - uint8_t unicast[CSR_WPA_OUI_SIZE]; - uint8_t multicast[CSR_WPA_OUI_SIZE]; - uint8_t authentication[CSR_WPA_OUI_SIZE]; - uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE]; - uint8_t i; - uint8_t index; - enum csr_akm_type neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; + struct wlan_objmgr_vdev *vdev; + uint8_t *rsn_ie_end = NULL; + uint8_t *rsn_ie = (uint8_t *)pRSNIe; + uint8_t ie_len = 0; + tDot11fBeaconIEs *local_ap_ie = ap_ie; + uint16_t rsn_cap = 0, self_rsn_cap; + struct wlan_crypto_pmksa pmksa, *pmksa_peer; + struct csr_roam_session *session = &mac->roam.roamSession[sessionId]; - if (!wpa_ie->present) - goto end; - c_mcast_cipher = 1; - qdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE); - c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count); - c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count); + if (!local_ap_ie && + (!QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies + (mac, pSirBssDesc, &local_ap_ie)))) + return ie_len; - /* - * csr_match_wpaoui_index will provide the index of the - * array csr_wpa_oui to be read and determine if it is - * accepatable cipher or not. Below check ensures that - * the index will not be out of range of the array size. - */ - index = csr_get_oui_index_from_cipher(encr_type); - if (!(index < (sizeof(csr_wpa_oui)/CSR_WPA_OUI_SIZE))) { - sme_debug("Unacceptable index: %d", index); - goto end; - } + /* get AP RSN cap */ + qdf_mem_copy(&rsn_cap, local_ap_ie->RSN.RSN_Cap, sizeof(rsn_cap)); + if (!ap_ie && local_ap_ie) + /* locally allocated */ + qdf_mem_free(local_ap_ie); - sme_debug("kw_dbg: index: %d", index); - /* Check - Is requested unicast Cipher supported by the BSS. */ - acceptable_cipher = csr_match_wpaoui_index(mac_ctx, - wpa_ie->unicast_ciphers, c_ucast_cipher, - index, unicast); - if (!acceptable_cipher) - goto end; - /* unicast is supported. Pick the first matching Group cipher, if any */ - for (i = 0; i < mc_encryption->numEntries; i++) { - index = csr_get_oui_index_from_cipher( - mc_encryption->encryptionType[i]); - sme_debug("kw_dbg: index: %d", index); - if (!(index < (sizeof(csr_wpa_oui)/CSR_WPA_OUI_SIZE))) { - sme_debug("Unacceptable MC index: %d", index); - acceptable_cipher = false; - continue; - } - acceptable_cipher = csr_match_wpaoui_index(mac_ctx, - mccipher_arr, c_mcast_cipher, - index, multicast); - if (acceptable_cipher) - break; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, sessionId, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return ie_len; } - if (!acceptable_cipher) - goto end; - - if (negotiated_mccipher) - *negotiated_mccipher = mc_encryption->encryptionType[i]; - - /* Initializing with false as it has true value already */ - acceptable_cipher = false; - for (i = 0; i < auth_type->numEntries; i++) { - /* - * Ciphers are supported, Match authentication algorithm and - * pick first matching authtype - */ - if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_WPA; - } - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && - csr_is_auth_wpa_psk(mac_ctx, - wpa_ie->auth_suites, c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_WPA_PSK; - } -#ifdef FEATURE_WLAN_ESE - if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) - && csr_is_ese_cckm_auth_wpa(mac_ctx, - wpa_ie->auth_suites, c_auth_suites, - authentication)) { - if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i]) - neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA; - } -#endif /* FEATURE_WLAN_ESE */ - /* - * The 1st auth type in the APs WPA IE, to match stations - * connecting profiles auth type will cause us to exit this - * loop. This is added as some APs advertise multiple akms in - * the WPA IE - */ - if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) { - acceptable_cipher = true; - break; - } + self_rsn_cap = (uint16_t)wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_RSN_CAP); + /* If AP is capable then use self capability else set PMF as 0 */ + if (rsn_cap & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED && + pProfile->MFPCapable) { + self_rsn_cap |= WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; + if (pProfile->MFPRequired) + self_rsn_cap |= WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; + } else { + self_rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; + self_rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; } - -end: - if (acceptable_cipher) { - if (mcast_cipher) - qdf_mem_copy((uint8_t **) mcast_cipher, multicast, - CSR_WPA_OUI_SIZE); - - if (ucast_cipher) - qdf_mem_copy((uint8_t **) ucast_cipher, unicast, - CSR_WPA_OUI_SIZE); - - if (auth_suite) - qdf_mem_copy((uint8_t **) auth_suite, authentication, - CSR_WPA_OUI_SIZE); - - if (negotiated_authtype) - *negotiated_authtype = neg_authtype; + wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP, + self_rsn_cap); + qdf_mem_zero(&pmksa, sizeof(pmksa)); + if (pSirBssDesc->fils_info_element.is_cache_id_present) { + pmksa.ssid_len = + pProfile->SSIDs.SSIDList[0].SSID.length; + qdf_mem_copy(pmksa.ssid, + pProfile->SSIDs.SSIDList[0].SSID.ssId, + pProfile->SSIDs.SSIDList[0].SSID.length); + qdf_mem_copy(pmksa.cache_id, + pSirBssDesc->fils_info_element.cache_id, + CACHE_ID_LEN); + qdf_mem_copy(&pmksa.bssid, + pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE); + } else { + qdf_mem_copy(&pmksa.bssid, + pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE); } + pmksa_peer = wlan_crypto_get_peer_pmksa(vdev, &pmksa); + qdf_mem_zero(&pmksa, sizeof(pmksa)); + /* + * TODO: Add support for Adaptive 11r connection after + * call to csr_get_rsn_information is added here + */ + rsn_ie_end = wlan_crypto_build_rsnie_with_pmksa(vdev, rsn_ie, + pmksa_peer); + if (rsn_ie_end) + ie_len = rsn_ie_end - rsn_ie; - return acceptable_cipher; -} - -static bool csr_is_wpa_encryption_match(struct mac_context *mac, - tCsrAuthList *pAuthType, - eCsrEncryptionType enType, - tCsrEncryptionList *pEnMcType, - tDot11fBeaconIEs *pIes, - enum csr_akm_type *pNegotiatedAuthtype, - eCsrEncryptionType *pNegotiatedMCCipher) -{ - bool fWpaMatch = false; - - /* See if the cyphers in the Bss description match with the - * settings in the profile. + /* + * If a PMK cache is found for the BSSID, then + * update the PMK in CSR session also as this + * will be sent to the FW during RSO. */ - fWpaMatch = - csr_get_wpa_cyphers(mac, pAuthType, enType, pEnMcType, - &pIes->WPA, - NULL, NULL, NULL, pNegotiatedAuthtype, - pNegotiatedMCCipher); + if (pmksa_peer) { + csr_update_session_pmk(session, pmksa_peer); + csr_update_pmksa_to_profile(pProfile, pmksa_peer); + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return fWpaMatch; + return ie_len; } -#endif -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT uint8_t csr_construct_wpa_ie(struct mac_context *mac, uint8_t session_id, struct csr_roam_profile *pProfile, struct bss_description *pSirBssDesc, @@ -4723,87 +3001,31 @@ uint8_t csr_construct_wpa_ie(struct mac_context *mac, uint8_t session_id, return ie_len; } -#else -uint8_t csr_construct_wpa_ie(struct mac_context *mac, uint8_t session_id, - struct csr_roam_profile *pProfile, - struct bss_description *pSirBssDesc, - tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe) -{ - bool fWpaMatch; - uint8_t cbWpaIe = 0; - uint8_t UnicastCypher[CSR_WPA_OUI_SIZE]; - uint8_t MulticastCypher[CSR_WPA_OUI_SIZE]; - uint8_t AuthSuite[CSR_WPA_OUI_SIZE]; - tCsrWpaAuthIe *pAuthSuite; - tDot11fBeaconIEs *pIesLocal = pIes; - - do { - if (!csr_is_profile_wpa(pProfile)) - break; - - if (!pIesLocal - && - (!QDF_IS_STATUS_SUCCESS - (csr_get_parsed_bss_description_ies - (mac, pSirBssDesc, &pIesLocal)))) - break; - /* See if the cyphers in the Bss description match with the - * settings in the profile. - */ - fWpaMatch = - csr_get_wpa_cyphers(mac, &pProfile->AuthType, - pProfile->negotiatedUCEncryptionType, - &pProfile->mcEncryptionType, - &pIesLocal->WPA, UnicastCypher, - MulticastCypher, AuthSuite, NULL, NULL); - if (!fWpaMatch) - break; - - pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID; - qdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui)); - - pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED; - - qdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher, - sizeof(MulticastCypher)); - - pWpaIe->cUnicastCyphers = 1; - - qdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher, - sizeof(UnicastCypher)); - - pAuthSuite = - (tCsrWpaAuthIe *) (&pWpaIe-> - UnicastOui[pWpaIe->cUnicastCyphers]); - - pAuthSuite->cAuthenticationSuites = 1; - qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite, - sizeof(AuthSuite)); - - /* The WPA capabilities follows the Auth Suite (two octects)- - * this field is optional, and we always "send" zero, so just - * remove it. This is consistent with our assumptions in the - * frames compiler; c.f. bug 15234: - * http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 - * Add in the fixed fields plus 1 Unicast cypher, less the IE - * Header length Add in the size of the Auth suite (count plus - * a single OUI) - */ - pWpaIe->IeHeader.Length = - sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) + - sizeof(*pAuthSuite); - - /* return the size of the IE header (total) constructed... */ - cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader); +#ifdef FEATURE_WLAN_WAPI +uint8_t csr_construct_wapi_ie(struct mac_context *mac, uint32_t sessionId, + struct csr_roam_profile *pProfile, + struct bss_description *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe) +{ + struct wlan_objmgr_vdev *vdev; + uint8_t *wapi_ie_end = NULL; + uint8_t *wapi_ie = (uint8_t *)pWapiIe; + uint8_t ie_len = 0; - } while (0); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, sessionId, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Invalid vdev"); + return ie_len; + } + wapi_ie_end = wlan_crypto_build_wapiie(vdev, wapi_ie); + if (wapi_ie_end) + ie_len = wapi_ie_end - wapi_ie; - if (!pIes && pIesLocal) - /* locally allocated */ - qdf_mem_free(pIesLocal); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); - return cbWpaIe; + return ie_len; } #endif @@ -5087,411 +3309,6 @@ tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType) return edType; } -/** - * csr_validate_wep() - to validate wep - * @uc_encry_type: unicast encryption type - * @auth_list: Auth list - * @mc_encryption_list: multicast encryption type - * @negotiated_authtype: negotiated auth type - * @negotiated_mc_encry: negotiated mc encry type - * @bss_descr: BSS description - * @ie_ptr: IE pointer - * - * This function just checks whether HDD is giving correct values for - * Multicast cipher and Auth - * - * Return: bool - */ -static bool csr_validate_wep(struct mac_context *mac_ctx, - eCsrEncryptionType uc_encry_type, - tCsrAuthList *auth_list, - tCsrEncryptionList *mc_encryption_list, - struct bss_description *bss_descr, - tDot11fBeaconIEs *ie_ptr) -{ - uint32_t idx; - bool match = false; - uint8_t oui_index; - - /* If privacy bit is not set, consider no match */ - if (!csr_is_privacy(bss_descr)) - return match; - - for (idx = 0; idx < mc_encryption_list->numEntries; idx++) { - switch (mc_encryption_list->encryptionType[idx]) { - case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: - case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: - case eCSR_ENCRYPT_TYPE_WEP40: - case eCSR_ENCRYPT_TYPE_WEP104: - /* - * Multicast list may contain WEP40/WEP104. - * Check whether it matches UC. - */ - if (uc_encry_type == - mc_encryption_list->encryptionType[idx]) { - match = true; - } - break; - default: - match = false; - break; - } - if (match) - break; - } - - if (!match) - return match; - - for (idx = 0; idx < auth_list->numEntries; idx++) { - switch (auth_list->authType[idx]) { - case eCSR_AUTH_TYPE_OPEN_SYSTEM: - case eCSR_AUTH_TYPE_SHARED_KEY: - case eCSR_AUTH_TYPE_AUTOSWITCH: - match = true; - break; - default: - match = false; - } - if (match) - break; - } - - if (!match) - return match; - - if (!ie_ptr) - return match; - - /* - * In case of WPA / WPA2, check whether it supports WEP as well. - * Prepare the encryption type for WPA/WPA2 functions - */ - if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type) - uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40; - else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type) - uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104; - - /* else we can use the encryption type directly */ - if (ie_ptr->WPA.present) { - oui_index = csr_get_oui_index_from_cipher(uc_encry_type); - if (oui_index < QDF_ARRAY_SIZE(csr_wpa_oui)) - match = (!qdf_mem_cmp(ie_ptr->WPA.multicast_cipher, - csr_wpa_oui[oui_index], - CSR_WPA_OUI_SIZE)); - if (match) - return match; - } - if (ie_ptr->RSN.present) { - match = (!qdf_mem_cmp(ie_ptr->RSN.gp_cipher_suite, - csr_rsn_oui[csr_get_oui_index_from_cipher( - uc_encry_type)], - CSR_RSN_OUI_SIZE)); - } - - return match; -} - -#ifndef WLAN_CONV_CRYPTO_IE_SUPPORT -/** - * csr_validate_open_none() - Check if the security is matching - * @bss_desc: BSS Descriptor on which the check is done - * @mc_enc_type: Multicast encryption type - * @mc_cipher: Multicast Cipher - * @auth_type: Authentication type - * @neg_auth_type: Negotiated Auth type with the AP - * - * Return: Boolean value to tell if matched or not. - */ -static bool csr_validate_open_none(struct bss_description *bss_desc, - tCsrEncryptionList *mc_enc_type, - tCsrAuthList *auth_type) -{ - bool match; - uint8_t idx; - - /* - * for NO encryption, if the Bss description has the - * Privacy bit turned on, then encryption is required - * so we have to reject this Bss. - */ - if (csr_is_privacy(bss_desc)) - match = false; - else - match = true; - if (match) { - match = false; - /* Check MC cipher and Auth type requested. */ - for (idx = 0; idx < mc_enc_type->numEntries; idx++) { - if (eCSR_ENCRYPT_TYPE_NONE == - mc_enc_type->encryptionType[idx]) { - match = true; - break; - } - } - if (!match) - return match; - - match = false; - /* Check Auth list. It should contain AuthOpen. */ - for (idx = 0; idx < auth_type->numEntries; idx++) { - if ((eCSR_AUTH_TYPE_OPEN_SYSTEM == - auth_type->authType[idx]) || - (eCSR_AUTH_TYPE_AUTOSWITCH == - auth_type->authType[idx])) { - match = true; - break; - } - } - if (!match) - return match; - - } - return match; -} -#endif -/** - * csr_validate_any_default() - Check if the security is matching - * @mac_ctx: Global MAC context - * @auth_type: Authentication type - * @mc_enc_type: Multicast encryption type - * @mfp_enabled: Management frame protection feature - * @mfp_required: Management frame protection mandatory - * @mfp_capable: Device capable of MFP - * @ies_ptr: Pointer to the IE fields - * @neg_auth_type: Negotiated Auth type with the AP - * @bss_desc: BSS Descriptor - * @neg_uc_cipher: Negotiated unicast cipher suite - * @neg_mc_cipher: Negotiated multicast cipher - * - * Return: Boolean value to tell if matched or not. - */ -static bool csr_validate_any_default(struct mac_context *mac_ctx, - tCsrAuthList *auth_type, - tCsrEncryptionList *mc_enc_type, - bool *mfp_enabled, - uint8_t *mfp_required, - uint8_t *mfp_capable, - tDot11fBeaconIEs *ies_ptr, - enum csr_akm_type *neg_auth_type, - struct bss_description *bss_desc, - eCsrEncryptionType *uc_cipher, - eCsrEncryptionType *mc_cipher) -{ - bool match_any = false; - bool match = true; - /* It is allowed to match anything. Try the more secured ones first. */ - if (ies_ptr) { - /* Check GCMP-256 first */ - *uc_cipher = eCSR_ENCRYPT_TYPE_AES_GCMP_256; - match_any = csr_is_rsn_match(mac_ctx, auth_type, - *uc_cipher, mc_enc_type, mfp_enabled, - mfp_required, mfp_capable, ies_ptr, - neg_auth_type, mc_cipher); - /* Check GCMP second */ - *uc_cipher = eCSR_ENCRYPT_TYPE_AES_GCMP; - match_any = csr_is_rsn_match(mac_ctx, auth_type, - *uc_cipher, mc_enc_type, mfp_enabled, - mfp_required, mfp_capable, ies_ptr, - neg_auth_type, mc_cipher); - /* Check AES third */ - *uc_cipher = eCSR_ENCRYPT_TYPE_AES; - match_any = csr_is_rsn_match(mac_ctx, auth_type, - *uc_cipher, mc_enc_type, mfp_enabled, - mfp_required, mfp_capable, ies_ptr, - neg_auth_type, mc_cipher); - if (!match_any) { - /* Check TKIP */ - *uc_cipher = eCSR_ENCRYPT_TYPE_TKIP; - match_any = csr_is_rsn_match(mac_ctx, auth_type, - *uc_cipher, - mc_enc_type, mfp_enabled, mfp_required, - mfp_capable, ies_ptr, neg_auth_type, - mc_cipher); - } -#ifdef FEATURE_WLAN_WAPI - if (!match_any) { - /* Check WAPI */ - *uc_cipher = eCSR_ENCRYPT_TYPE_WPI; - match_any = csr_is_wapi_match(mac_ctx, auth_type, - *uc_cipher, mc_enc_type, ies_ptr, - neg_auth_type, mc_cipher); - } -#endif - } - if (match_any) - return match; - *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104; - if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, - bss_desc, ies_ptr)) - return match; - *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40; - if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, - bss_desc, ies_ptr)) - return match; - *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; - if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, - bss_desc, ies_ptr)) - return match; - *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; - if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, - bss_desc, ies_ptr)) - return match; - /* It must be open and no enc */ - if (csr_is_privacy(bss_desc)) { - match = false; - return match; - } - - if (neg_auth_type) - *neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; - if (mc_cipher) - *mc_cipher = eCSR_ENCRYPT_TYPE_NONE; - *uc_cipher = eCSR_ENCRYPT_TYPE_NONE; - return match; - -} - -/** - * csr_is_security_match() - Check if the security is matching - * @mac_ctx: Global MAC context - * @auth_type: Authentication type - * @uc_enc_type: Unicast Encryption type - * @mc_enc_type: Multicast encryption type - * @mfp_enabled: Management frame protection feature - * @mfp_required: Management frame protection mandatory - * @mfp_capable: Device capable of MFP - * @bss_desc: BSS Descriptor - * @ies_ptr: Pointer to the IE fields - * @session_id: Session Id - * - * Return: Boolean value to tell if matched or not. - */ -bool csr_is_security_match(struct mac_context *mac_ctx, tCsrAuthList *auth_type, - tCsrEncryptionList *uc_enc_type, - tCsrEncryptionList *mc_enc_type, bool *mfp_enabled, - uint8_t *mfp_required, uint8_t *mfp_capable, - struct bss_description *bss_desc, - tDot11fBeaconIEs *ies_ptr, uint8_t session_id) -{ - bool match = false; - uint8_t i; - eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN; - uint16_t ie_len; - - ie_len = (bss_desc->length + sizeof(bss_desc->length) - - GET_FIELD_OFFSET(struct bss_description, ieFields)); - - for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) { - uc_cipher = uc_enc_type->encryptionType[i]; - /* - * If the Bss description shows the Privacy bit is on, then we - * must have some sort of encryption configured for the profile - * to work. Don't attempt to join networks with Privacy bit - * set when profiles say NONE for encryption type. - */ - switch (uc_cipher) { - case eCSR_ENCRYPT_TYPE_NONE: -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT - if (csr_is_privacy(bss_desc)) - return false; - - match = wlan_crypto_check_open_none(mac_ctx->psoc, - session_id); -#else - match = csr_validate_open_none(bss_desc, mc_enc_type, - auth_type); -#endif - break; - - case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: - case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: - case eCSR_ENCRYPT_TYPE_WEP40: - case eCSR_ENCRYPT_TYPE_WEP104: - /* - * !! might want to check for WEP keys set in the - * Profile.... ? !! don't need to have the privacy bit - * in the Bss description. Many AP policies make - * legacy encryption 'optional' so we don't know if we - * can associate or not. The AP will reject if - * encryption is not allowed without the Privacy bit - * turned on. - */ -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT - if (!csr_is_privacy(bss_desc)) - return false; - - match = wlan_crypto_check_wep(mac_ctx->psoc, - session_id); -#else - match = csr_validate_wep(mac_ctx, uc_cipher, auth_type, - mc_enc_type, bss_desc, - ies_ptr); -#endif - - break; - case eCSR_ENCRYPT_TYPE_TKIP: - case eCSR_ENCRYPT_TYPE_AES: - case eCSR_ENCRYPT_TYPE_AES_GCMP: - case eCSR_ENCRYPT_TYPE_AES_GCMP_256: - if (!ies_ptr) { - match = false; - break; - } -#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT - match = wlan_crypto_check_rsn_match(mac_ctx->psoc, - session_id, - (uint8_t *) - &bss_desc->ieFields, - ie_len); - if (match) - break; - match = wlan_crypto_check_wpa_match(mac_ctx->psoc, - session_id, - (uint8_t *) - &bss_desc->ieFields, - ie_len); -#else - /* First check if there is a RSN match */ - match = csr_is_rsn_match(mac_ctx, auth_type, - uc_cipher, mc_enc_type, - mfp_enabled, mfp_required, - mfp_capable, ies_ptr, - NULL, NULL); - /* If not RSN, then check WPA match */ - if (!match) - match = csr_is_wpa_encryption_match( - mac_ctx, auth_type, - uc_cipher, mc_enc_type, - ies_ptr, - NULL, NULL); -#endif - break; -#ifdef FEATURE_WLAN_WAPI - case eCSR_ENCRYPT_TYPE_WPI: /* WAPI */ - if (ies_ptr) - match = csr_is_wapi_match(mac_ctx, auth_type, - uc_cipher, mc_enc_type, ies_ptr, - NULL, NULL); - else - match = false; - break; -#endif /* FEATURE_WLAN_WAPI */ - case eCSR_ENCRYPT_TYPE_ANY: - default: - match = csr_validate_any_default(mac_ctx, auth_type, - mc_enc_type, mfp_enabled, mfp_required, - mfp_capable, ies_ptr, - NULL, bss_desc, - &uc_cipher, NULL); - break; - } - - } - - return match; -} - bool csr_is_ssid_match(struct mac_context *mac, uint8_t *ssid1, uint8_t ssid1Len, uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired) { @@ -5592,13 +3409,6 @@ bool csr_is_bssid_match(struct qdf_mac_addr *pProfBssid, return fMatch; } -bool csr_is_bss_type_ibss(eCsrRoamBssType bssType) -{ - return (bool) - (eCSR_BSS_TYPE_START_IBSS == bssType - || eCSR_BSS_TYPE_IBSS == bssType); -} - /** * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported * @mac_ctx: pointer to mac context @@ -5924,32 +3734,15 @@ void csr_release_profile(struct mac_context *mac, struct csr_roam_profile *pProf qdf_mem_free(pProfile->pAddIEAssoc); pProfile->pAddIEAssoc = NULL; } - if (pProfile->ChannelInfo.ChannelList) { - qdf_mem_free(pProfile->ChannelInfo.ChannelList); - pProfile->ChannelInfo.ChannelList = NULL; + if (pProfile->ChannelInfo.freq_list) { + qdf_mem_free(pProfile->ChannelInfo.freq_list); + pProfile->ChannelInfo.freq_list = NULL; } csr_free_fils_profile_info(pProfile); qdf_mem_zero(pProfile, sizeof(struct csr_roam_profile)); } } -void csr_free_scan_filter(struct mac_context *mac, tCsrScanResultFilter - *pScanFilter) -{ - if (pScanFilter->BSSIDs.bssid) { - qdf_mem_free(pScanFilter->BSSIDs.bssid); - pScanFilter->BSSIDs.bssid = NULL; - } - if (pScanFilter->ChannelInfo.ChannelList) { - qdf_mem_free(pScanFilter->ChannelInfo.ChannelList); - pScanFilter->ChannelInfo.ChannelList = NULL; - } - if (pScanFilter->SSIDs.SSIDList) { - qdf_mem_free(pScanFilter->SSIDs.SSIDList); - pScanFilter->SSIDs.SSIDList = NULL; - } -} - void csr_free_roam_profile(struct mac_context *mac, uint32_t sessionId) { struct csr_roam_session *pSession = &mac->roam.roamSession[sessionId]; @@ -6157,10 +3950,6 @@ QDF_STATUS csr_set_modify_profile_fields(struct mac_context *mac, { struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); - if (!pSession) { - sme_err("Session_id invalid %d", sessionId); - return QDF_STATUS_E_INVAL; - } qdf_mem_copy(&pSession->connectedProfile.modifyProfileFields, pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields)); @@ -6210,7 +3999,7 @@ uint16_t sme_chn_to_freq(uint8_t chanNum) } struct lim_channel_status * -csr_get_channel_status(struct mac_context *mac, uint32_t channel_id) +csr_get_channel_status(struct mac_context *mac, uint32_t chan_freq) { uint8_t i; struct lim_scan_channel_status *channel_status; @@ -6222,10 +4011,10 @@ csr_get_channel_status(struct mac_context *mac, uint32_t channel_id) channel_status = &mac->lim.scan_channel_status; for (i = 0; i < channel_status->total_channel; i++) { entry = &channel_status->channel_status_list[i]; - if (entry->channel_id == channel_id) + if (entry->channelfreq == chan_freq) return entry; } - sme_err("Channel %d status info not exist", channel_id); + sme_err("Channel %d status info not exist", chan_freq); return NULL; } @@ -6243,8 +4032,8 @@ void csr_clear_channel_status(struct mac_context *mac) return; } -bool csr_is_channel_present_in_list(uint8_t *pChannelList, - int numChannels, uint8_t channel) +bool csr_is_channel_present_in_list(uint32_t *pChannelList, + int numChannels, uint32_t chan_freq) { int i = 0; @@ -6255,7 +4044,7 @@ bool csr_is_channel_present_in_list(uint8_t *pChannelList, /* Look for the channel in the list */ for (i = 0; (i < numChannels) && (i < CFG_VALID_CHANNEL_LIST_LEN); i++) { - if (pChannelList[i] == channel) + if (pChannelList[i] == chan_freq) return true; } @@ -6281,8 +4070,8 @@ const char *sme_bss_type_to_string(const uint8_t bss_type) } } -QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList, - int numChannels, uint8_t channel) +QDF_STATUS csr_add_to_channel_list_front(uint32_t *pChannelList, + int numChannels, uint32_t chan_freq) { int i = 0; @@ -6295,7 +4084,7 @@ QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList, pChannelList[i] = pChannelList[i - 1]; /* Now add the NEW channel...at the front */ - pChannelList[0] = channel; + pChannelList[0] = chan_freq; return QDF_STATUS_SUCCESS; } @@ -6378,16 +4167,18 @@ bool csr_is_ndi_started(struct mac_context *mac_ctx, uint32_t session_id) return eCSR_CONNECT_STATE_TYPE_NDI_STARTED == session->connectState; } -bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint8_t channel) +bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint32_t chan_freq) { struct csr_roam_session *session; enum QDF_OPMODE oper_mode; - uint8_t oper_channel = 0; + uint32_t oper_chan_freq = 0; uint8_t session_id; + bool hw_dbs_capable, same_band_freqs; - if (channel == 0) + if (chan_freq == 0) return false; + hw_dbs_capable = policy_mgr_is_hw_dbs_capable(mac_ctx->psoc); for (session_id = 0; session_id < WLAN_MAX_VDEVS; session_id++) { if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) { session = CSR_GET_SESSION(mac_ctx, session_id); @@ -6402,13 +4193,14 @@ bool csr_is_mcc_channel(struct mac_context *mac_ctx, uint8_t channel) (oper_mode == QDF_SAP_MODE)) && (session->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED))) - oper_channel = session->connectedProfile. - operationChannel; + oper_chan_freq = + session->connectedProfile.op_freq; + + same_band_freqs = WLAN_REG_IS_SAME_BAND_FREQS( + chan_freq, oper_chan_freq); - if (oper_channel && channel != oper_channel && - (!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) || - WLAN_REG_IS_SAME_BAND_CHANNELS(channel, - oper_channel))) + if (oper_chan_freq && chan_freq != oper_chan_freq && + (!hw_dbs_capable || same_band_freqs)) return true; } } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/nan/nan_datapath_api.c b/drivers/staging/qcacld-3.0/core/sme/src/nan/nan_datapath_api.c index bab45c92bebd84cf0f567bad797acad5701f5dfb..c15ac649b3b1c16f9ac1421b2221f5e415278884 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/nan/nan_datapath_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/nan/nan_datapath_api.c @@ -103,7 +103,7 @@ void csr_roam_save_ndi_connected_info(struct mac_context *mac_ctx, connect_profile->BSSType = roam_profile->BSSType; connect_profile->modifyProfileFields.uapsd_mask = roam_profile->uapsd_mask; - connect_profile->operationChannel = bssdesc->channelId; + connect_profile->op_freq = bssdesc->chan_freq; connect_profile->beaconInterval = 0; qdf_mem_copy(&connect_profile->Keys, &roam_profile->Keys, sizeof(roam_profile->Keys)); diff --git a/drivers/staging/qcacld-3.0/core/sme/src/qos/sme_qos.c b/drivers/staging/qcacld-3.0/core/sme/src/qos/sme_qos.c index 2317861c26bb81091ad2d85262a19107a6e5f900..e3b7449554e94c0213e808b6c8361b5cf6360d5e 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/qos/sme_qos.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/qos/sme_qos.c @@ -4714,6 +4714,55 @@ static QDF_STATUS sme_qos_process_reassoc_failure_ev(struct mac_context *mac, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#ifdef FEATURE_WLAN_ESE +static bool sme_qos_ft_handoff_required(struct mac_context *mac, + uint8_t session_id) +{ + struct csr_roam_session *csr_roam_session; + + if (csr_roam_is11r_assoc(mac, session_id)) + return true; + + csr_roam_session = CSR_GET_SESSION(mac, session_id); + + if (csr_roam_session && + csr_roam_session->roam_synch_in_progress && + csr_roam_is_ese_assoc(mac, session_id) && + csr_roam_session->connectedInfo.nTspecIeLength) + return true; + + return false; +} +#else +static inline bool sme_qos_ft_handoff_required(struct mac_context *mac, + uint8_t session_id) +{ + return csr_roam_is11r_assoc(mac, session_id) ? true : false; +} +#endif +#else +static inline bool sme_qos_ft_handoff_required(struct mac_context *mac, + uint8_t session_id) +{ + return false; +} +#endif + +#ifdef FEATURE_WLAN_ESE +static inline bool sme_qos_legacy_handoff_required(struct mac_context *mac, + uint8_t session_id) +{ + return csr_roam_is_ese_assoc(mac, session_id) ? false : true; +} +#else +static inline bool sme_qos_legacy_handoff_required(struct mac_context *mac, + uint8_t session_id) +{ + return true; +} +#endif + /* * sme_qos_process_handoff_assoc_req_ev() - Function to process the * SME_QOS_CSR_HANDOFF_ASSOC_REQ event indication from CSR @@ -4762,16 +4811,13 @@ static QDF_STATUS sme_qos_process_handoff_assoc_req_ev(struct mac_context *mac, break; } } -#ifdef WLAN_FEATURE_ROAM_OFFLOAD - if (csr_roam_is11r_assoc(mac, sessionId)) + + if (sme_qos_ft_handoff_required(mac, sessionId)) pSession->ftHandoffInProgress = true; -#endif + /* If FT handoff/ESE in progress, legacy handoff need not be enabled */ - if (!pSession->ftHandoffInProgress -#ifdef FEATURE_WLAN_ESE - && !csr_roam_is_ese_assoc(mac, sessionId) -#endif - ) + if (!pSession->ftHandoffInProgress && + sme_qos_legacy_handoff_required(mac, sessionId)) pSession->handoffRequested = true; /* this session no longer needs UAPSD */ @@ -7222,7 +7268,7 @@ static bool sme_qos_validate_requested_params(struct mac_context *mac, return true; } -static QDF_STATUS qos_issue_command(struct mac_context *mac, uint8_t sessionId, +static QDF_STATUS qos_issue_command(struct mac_context *mac, uint8_t vdev_id, eSmeCommandType cmdType, struct sme_qos_wmmtspecinfo *pQoSInfo, enum qca_wlan_ac_type ac, uint8_t tspec_mask) @@ -7239,7 +7285,7 @@ static QDF_STATUS qos_issue_command(struct mac_context *mac, uint8_t sessionId, break; } pCommand->command = cmdType; - pCommand->sessionId = sessionId; + pCommand->vdev_id = vdev_id; switch (cmdType) { case eSmeCommandAddTs: if (pQoSInfo) { @@ -7285,7 +7331,7 @@ bool qos_process_command(struct mac_context *mac, tSmeCmd *pCommand) case eSmeCommandAddTs: status = sme_qos_add_ts_req(mac, (uint8_t) - pCommand->sessionId, + pCommand->vdev_id, &pCommand->u.qosCmd.tspecInfo, pCommand->u.qosCmd.ac); if (QDF_IS_STATUS_SUCCESS(status)) @@ -7294,7 +7340,7 @@ bool qos_process_command(struct mac_context *mac, tSmeCmd *pCommand) case eSmeCommandDelTs: status = sme_qos_del_ts_req(mac, (uint8_t) - pCommand->sessionId, + pCommand->vdev_id, pCommand->u.qosCmd.ac, pCommand->u.qosCmd.tspec_mask); if (QDF_IS_STATUS_SUCCESS(status)) @@ -7481,13 +7527,11 @@ static QDF_STATUS sme_qos_request_reassoc(struct mac_context *mac, session = CSR_GET_SESSION(mac, sessionId); roam_profile = session->pCurRoamProfile; connected_profile = session->connectedProfile; - status = sme_fast_reassoc( - MAC_HANDLE(mac), - roam_profile, - connected_profile.bssid.bytes, - connected_profile.operationChannel, - sessionId, - connected_profile.bssid.bytes); + status = sme_fast_reassoc(MAC_HANDLE(mac), roam_profile, + connected_profile.bssid.bytes, + connected_profile.op_freq, + sessionId, + connected_profile.bssid.bytes); } else { status = csr_reassoc(mac, sessionId, pModFields, &pSession->roamID, fForce); diff --git a/drivers/staging/qcacld-3.0/core/sme/src/rrm/sme_rrm.c b/drivers/staging/qcacld-3.0/core/sme/src/rrm/sme_rrm.c index a67743a7ecf38425bf7fbe7ed1342ddda8c643f2..c9eec015039beadc3d7ff2897a5d9dfd42ca37f1 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/rrm/sme_rrm.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/rrm/sme_rrm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,6 +36,7 @@ #include "rrm_global.h" #include #include +#include #include /* Roam score for a neighbor AP will be calculated based on the below @@ -212,12 +213,12 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx, bss_desc, size); tmp_bss_desc[i] = beacon_rep->pBssDescription[i]; - sme_debug("RRM Result Bssid = " QDF_MAC_ADDR_STR - " chan= %d, rssi = -%d", - QDF_MAC_ADDR_ARRAY( - beacon_rep->pBssDescription[i]->bssId), - beacon_rep->pBssDescription[i]->channelId, - beacon_rep->pBssDescription[i]->rssi * (-1)); + sme_debug("RRM Result Bssid = " QDF_MAC_ADDR_FMT + " freq= %d, rssi = -%d", + QDF_MAC_ADDR_REF( + beacon_rep->pBssDescription[i]->bssId), + beacon_rep->pBssDescription[i]->chan_freq, + beacon_rep->pBssDescription[i]->rssi * (-1)); beacon_rep->numBssDesc++; if (++i >= SIR_BCN_REPORT_MAX_BSS_DESC) break; @@ -252,12 +253,13 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx, #ifdef FEATURE_WLAN_ESE /** * sme_ese_send_beacon_req_scan_results () - Send beacon report - * @mac_ctx Pointer to mac context + * @mac_ctx: Pointer to mac context * @measurement_index: Measurement request index - * @session_id - session id - * @result_arr scan results - * @msrmnt_status flag to indicate that the measurement is done. - * @bss_count number of bss found + * @session_id: session id + * @freq: channel frequency + * @result_arr: scan results + * @msrmnt_status: flag to indicate that the measurement is done. + * @bss_count: number of bss found * * This function sends up the scan results received as a part of * beacon request scanning. @@ -269,7 +271,7 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx, */ static QDF_STATUS sme_ese_send_beacon_req_scan_results( struct mac_context *mac_ctx, uint8_t measurement_index, - uint32_t session_id, uint8_t channel, + uint32_t session_id, uint32_t freq, tCsrScanResultInfo **result_arr, uint8_t msrmnt_status, uint8_t bss_count) { @@ -312,8 +314,7 @@ static QDF_STATUS sme_ese_send_beacon_req_scan_results( qdf_mem_zero(&bcn_rpt_rsp, sizeof(bcn_rpt_rsp)); for (i = 0; i < rrm_ctx->eseBcnReqInfo.numBcnReqIe; i++) { - if (rrm_ctx->eseBcnReqInfo.bcnReq[i].channel == - channel) { + if (rrm_ctx->eseBcnReqInfo.bcnReq[i].ch_freq == freq) { cur_meas_req = &rrm_ctx->eseBcnReqInfo.bcnReq[i]; break; @@ -322,8 +323,8 @@ static QDF_STATUS sme_ese_send_beacon_req_scan_results( if (cur_meas_req) bcn_report->measurementToken = cur_meas_req->measurementToken; - sme_debug("Channel: %d MeasToken: %d", channel, - bcn_report->measurementToken); + sme_debug("freq: %d MeasToken: %d", freq, + bcn_report->measurementToken); j = 0; while (cur_result) { @@ -335,8 +336,9 @@ static QDF_STATUS sme_ese_send_beacon_req_scan_results( ie_len = GET_IE_LEN_IN_BSS(bss_desc->length); bcn_rpt_fields = &bcn_report->bcnRepBssInfo[j].bcnReportFields; - bcn_rpt_fields->ChanNum = - bss_desc->channelId; + bcn_rpt_fields->ChanNum = wlan_reg_freq_to_chan( + mac_ctx->pdev, + bss_desc->chan_freq); bcn_report->bcnRepBssInfo[j].bcnReportFields.Spare = 0; if (cur_meas_req) bcn_rpt_fields->MeasDuration = @@ -363,9 +365,9 @@ static QDF_STATUS sme_ese_send_beacon_req_scan_results( continue; bcn_report->bcnRepBssInfo[j].ieLen = out_ie_len; - sme_debug("Bssid"QDF_MAC_ADDR_STR" Channel: %d Rssi: %d", - QDF_MAC_ADDR_ARRAY(bss_desc->bssId), - bss_desc->channelId, (-1) * bss_desc->rssi); + sme_debug("Bssid"QDF_MAC_ADDR_FMT" Freq:%d Rssi:%d", + QDF_MAC_ADDR_REF(bss_desc->bssId), + bss_desc->chan_freq, (-1) * bss_desc->rssi); bcn_report->numBss++; if (++j >= SIR_BCN_REPORT_MAX_BSS_DESC) break; @@ -423,7 +425,7 @@ void sme_reset_ese_bcn_req_in_progress(tpRrmSMEContext sme_rrm_ctx) * @mac_ctx: pointer to mac context * @measurement_index: Measurement request number * @num_chan: number of channels - * @chan_list: list of channels to fetch the result from + * @freq_list: list of channel frequencies to fetch the result from * @measurementdone: Flag to indicate measurement done or no * * This function is called to get the scan result from CSR and send the beacon @@ -434,11 +436,11 @@ void sme_reset_ese_bcn_req_in_progress(tpRrmSMEContext sme_rrm_ctx) static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, uint8_t measurement_index, uint8_t num_chan, - uint8_t *chan_list, + uint32_t *freq_list, uint8_t measurementdone) { mac_handle_t mac_handle = MAC_HANDLE(mac_ctx); - tCsrScanResultFilter filter; + struct scan_filter *filter; tScanResultHandle result_handle; tCsrScanResultInfo *scan_results, *next_result; tCsrScanResultInfo **scanresults_arr = NULL; @@ -452,27 +454,36 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, tSirScanType scan_type; struct csr_roam_session *session; - qdf_mem_zero(&filter, sizeof(filter)); - filter.BSSIDs.numOfBSSIDs = 1; - filter.BSSIDs.bssid = (struct qdf_mac_addr *)&rrm_ctx->bssId; - - if (rrm_ctx->ssId.length) { - filter.SSIDs.SSIDList = qdf_mem_malloc(sizeof(tCsrSSIDInfo)); - if (!filter.SSIDs.SSIDList) - return QDF_STATUS_E_NOMEM; + filter = qdf_mem_malloc(sizeof(*filter)); + if (!filter) + return QDF_STATUS_E_NOMEM; - filter.SSIDs.SSIDList->SSID.length = - rrm_ctx->ssId.length; - qdf_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, - rrm_ctx->ssId.ssId, rrm_ctx->ssId.length); - filter.SSIDs.numOfSSIDs = 1; + if (qdf_is_macaddr_zero(filter->bssid_list) || + qdf_is_macaddr_group(filter->bssid_list)) { + filter->num_of_bssid = 0; } else { - filter.SSIDs.numOfSSIDs = 0; + /* update filter to get scan result with just target BSSID */ + filter->num_of_bssid = 1; + qdf_mem_copy(filter->bssid_list[0].bytes, + rrm_ctx->bssId, sizeof(struct qdf_mac_addr)); } - filter.ChannelInfo.numOfChannels = num_chan; - filter.ChannelInfo.ChannelList = chan_list; - filter.fMeasurement = true; + if (rrm_ctx->ssId.length) { + filter->num_of_ssid = 1; + filter->ssid_list[0].length = rrm_ctx->ssId.length; + if (filter->ssid_list[0].length > WLAN_SSID_MAX_LEN) + filter->ssid_list[0].length = WLAN_SSID_MAX_LEN; + qdf_mem_copy(filter->ssid_list[0].ssid, + rrm_ctx->ssId.ssId, filter->ssid_list[0].length); + } + + filter->num_of_channels = num_chan; + if (filter->num_of_channels > NUM_CHANNELS) + filter->num_of_channels = NUM_CHANNELS; + qdf_mem_copy(filter->chan_freq_list, freq_list, + filter->num_of_channels * + sizeof(filter->chan_freq_list[0])); + filter->rrm_measurement_filter = true; if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource || eRRM_MSG_SOURCE_LEGACY_ESE == rrm_ctx->msgSource) @@ -481,9 +492,10 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, scan_type = rrm_ctx->measMode[0]; if (scan_type == eSIR_BEACON_TABLE) - filter.age_threshold = + filter->age_threshold = wlan_scan_get_aging_time(mac_ctx->psoc); + /* * In case this is beacon report request from last AP (before roaming) * following call to csr_roam_get_session_id_from_bssid will fail, @@ -495,10 +507,8 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, session_id = mac_ctx->roam.roamSession->sessionId; } status = sme_scan_get_result(mac_handle, (uint8_t)session_id, - &filter, &result_handle); - - if (filter.SSIDs.SSIDList) - qdf_mem_free(filter.SSIDs.SSIDList); + filter, &result_handle); + qdf_mem_free(filter); sme_debug("RRM Measurement Done %d for index:%d", measurementdone, measurement_index); @@ -522,7 +532,7 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource) status = sme_ese_send_beacon_req_scan_results(mac_ctx, measurement_index, session_id, - chan_list[0], NULL, + freq_list[0], NULL, measurementdone, 0); else #endif /* FEATURE_WLAN_ESE */ @@ -537,7 +547,7 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource) { status = sme_ese_send_beacon_req_scan_results(mac_ctx, measurement_index, session_id, - chan_list[0], NULL, + freq_list[0], NULL, measurementdone, 0); } else #endif /* FEATURE_WLAN_ESE */ @@ -628,7 +638,7 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx, if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource) status = sme_ese_send_beacon_req_scan_results(mac_ctx, measurement_index, session_id, - chan_list[0], scanresults_arr, + freq_list[0], scanresults_arr, measurementdone, counter); else #endif /* FEATURE_WLAN_ESE */ @@ -672,6 +682,8 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac, QDF_STATUS qdf_status; uint32_t session_id; bool valid_result = true; + uint8_t ch_idx, num_chan; + uint32_t *freq_list; /* * RRM scan response received after roaming to different AP. @@ -685,19 +697,20 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac, valid_result = false; } - - if (!pSmeRrmContext->channelList.ChannelList) { + /* if any more channels are pending, start a timer of a random value + * within randomization interval. + */ + freq_list = pSmeRrmContext->channelList.freq_list; + if (!freq_list) { sme_err("[802.11 RRM]: Global freq list is null"); pSmeRrmContext->channelList.numOfChannels = 0; sme_reset_ese_bcn_req_in_progress(pSmeRrmContext); return QDF_STATUS_E_FAILURE; } - /* if any more channels are pending, start a timer of a random value - * within randomization interval. - */ - if (((pSmeRrmContext->currentIndex + 1) < - pSmeRrmContext->channelList.numOfChannels) && valid_result) { + ch_idx = pSmeRrmContext->currentIndex; + num_chan = pSmeRrmContext->channelList.numOfChannels; + if (((ch_idx + 1) < num_chan) && valid_result) { if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state( &pSmeRrmContext->IterMeasTimer)) { @@ -712,21 +725,17 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac, sme_err("[802.11 RRM]: meas timer is already running"); sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx, - 1, &pSmeRrmContext->channelList. - ChannelList[pSmeRrmContext - ->currentIndex], true); - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + 1, &freq_list[ch_idx], true); + qdf_mem_free(pSmeRrmContext->channelList.freq_list); + pSmeRrmContext->channelList.freq_list = NULL; pSmeRrmContext->channelList.numOfChannels = 0; sme_reset_ese_bcn_req_in_progress(pSmeRrmContext); return QDF_STATUS_E_FAILURE; } sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx, - 1, &pSmeRrmContext->channelList. - ChannelList[pSmeRrmContext - ->currentIndex], - false); + 1, &freq_list[ch_idx], false); + /* Advance the current index. */ pSmeRrmContext->currentIndex++; /* start the timer to issue next request. */ @@ -741,8 +750,8 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac, qdf_status = qdf_mc_timer_start(&pSmeRrmContext->IterMeasTimer, interval); if (QDF_IS_STATUS_ERROR(qdf_status)) { - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + qdf_mem_free(pSmeRrmContext->channelList.freq_list); + pSmeRrmContext->channelList.freq_list = NULL; pSmeRrmContext->channelList.numOfChannels = 0; sme_reset_ese_bcn_req_in_progress(pSmeRrmContext); } @@ -752,12 +761,9 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac, * message to PE with measurement done flag set. */ sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx, - 1, &pSmeRrmContext->channelList. - ChannelList[pSmeRrmContext - ->currentIndex], - true); - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + 1, &freq_list[ch_idx], true); + qdf_mem_free(pSmeRrmContext->channelList.freq_list); + pSmeRrmContext->channelList.freq_list = NULL; pSmeRrmContext->channelList.numOfChannels = 0; sme_reset_ese_bcn_req_in_progress(pSmeRrmContext); } @@ -823,14 +829,14 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) tpRrmSMEContext sme_rrm_ctx = &mac_ctx->rrm.rrmSmeContext[idx]; uint32_t session_id; tSirScanType scan_type; - uint8_t *chan_list; uint8_t ch_idx; + uint32_t *freq_list; status = csr_roam_get_session_id_from_bssid(mac_ctx, &sme_rrm_ctx->sessionBssId, &session_id); if (status != QDF_STATUS_SUCCESS) { - sme_err("sme session ID not found for bssid= "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(sme_rrm_ctx->sessionBssId.bytes)); + sme_err("sme session ID not found for bssid= "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(sme_rrm_ctx->sessionBssId.bytes)); status = QDF_STATUS_E_FAILURE; goto send_ind; } @@ -855,7 +861,14 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) uint64_t current_time; struct scan_start_request *req; struct wlan_objmgr_vdev *vdev; - uint32_t chan_num; + uint32_t freq; + + if (!sme_rrm_ctx->channelList.numOfChannels || + !sme_rrm_ctx->channelList.freq_list) { + sme_err("[802.11 RRM]: Global freq list is null"); + status = QDF_STATUS_E_FAILURE; + goto send_ind; + } req = qdf_mem_malloc(sizeof(*req)); if (!req) { @@ -951,14 +964,13 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) /* set requestType to full scan */ req->scan_req.chan_list.num_chan = 1; - chan_num = sme_rrm_ctx->channelList.ChannelList[ + freq = sme_rrm_ctx->channelList.freq_list[ sme_rrm_ctx->currentIndex]; - req->scan_req.chan_list.chan[0].freq = - wlan_chan_to_freq(chan_num); - sme_debug("active duration %d passive %d On channel %d freq %d", + req->scan_req.chan_list.chan[0].freq = freq; + sme_debug("active duration %d passive %d On freq %d", req->scan_req.dwell_time_active, req->scan_req.dwell_time_passive, - chan_num, req->scan_req.chan_list.chan[0].freq); + req->scan_req.chan_list.chan[0].freq); /* * Fill RRM scan type for these requests. This is done * because in scan concurrency update params we update the @@ -983,9 +995,9 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) * pScanResult->timer >= rrm_scan_timer */ rrm_scan_timer = 0; - chan_list = sme_rrm_ctx->channelList.ChannelList; - if (!chan_list) { - sme_err("[802.11 RRM]: Global channel list is null"); + freq_list = sme_rrm_ctx->channelList.freq_list; + if (!freq_list) { + sme_err("[802.11 RRM]: Global freq list is null"); sme_reset_ese_bcn_req_in_progress(sme_rrm_ctx); status = QDF_STATUS_E_FAILURE; goto send_ind; @@ -996,7 +1008,7 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) if ((ch_idx + 1) < sme_rrm_ctx->channelList.numOfChannels) { sme_rrm_send_scan_result(mac_ctx, idx, 1, - &chan_list[ch_idx], + &freq_list[ch_idx], false); /* Advance the current index. */ sme_rrm_ctx->currentIndex++; @@ -1007,7 +1019,7 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) * measurement done flag set. */ sme_rrm_send_scan_result(mac_ctx, idx, 1, - &chan_list[ch_idx], + &freq_list[ch_idx], true); sme_reset_ese_bcn_req_in_progress(sme_rrm_ctx); goto free_ch_lst; @@ -1024,37 +1036,41 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx) send_ind: sme_rrm_send_beacon_report_xmit_ind(mac_ctx, idx, NULL, true, 0); free_ch_lst: - qdf_mem_free(sme_rrm_ctx->channelList.ChannelList); - sme_rrm_ctx->channelList.ChannelList = NULL; + qdf_mem_free(sme_rrm_ctx->channelList.freq_list); + sme_rrm_ctx->channelList.freq_list = NULL; + sme_rrm_ctx->channelList.numOfChannels = 0; return status; } -static QDF_STATUS sme_rrm_fill_scan_channels(uint8_t *country, +static QDF_STATUS sme_rrm_fill_scan_channels(struct mac_context *mac, + uint8_t *country, tpRrmSMEContext sme_rrm_context, - uint8_t reg_class, + uint8_t op_class, uint32_t num_channels) { uint32_t num_chan = 0; uint32_t i; + uint32_t *freq_list; + bool found; - /* List all the channels in the requested RC */ - wlan_reg_dmn_print_channels_in_opclass(country, reg_class); - + freq_list = sme_rrm_context->channelList.freq_list; + found = false; for (i = 0; i < num_channels; i++) { - if (wlan_reg_dmn_get_opclass_from_channel(country, - sme_rrm_context->channelList.ChannelList[i], - BWALL) == - reg_class) { - sme_rrm_context->channelList. - ChannelList[num_chan] = - sme_rrm_context->channelList.ChannelList[i]; + found = wlan_reg_country_opclass_freq_check(mac->pdev, + country, + op_class, + freq_list[i]); + if (found) { + freq_list[num_chan] = freq_list[i]; num_chan++; } + found = false; } + sme_rrm_context->channelList.numOfChannels = num_chan; if (sme_rrm_context->channelList.numOfChannels == 0) { - qdf_mem_free(sme_rrm_context->channelList.ChannelList); - sme_rrm_context->channelList.ChannelList = NULL; + qdf_mem_free(sme_rrm_context->channelList.freq_list); + sme_rrm_context->channelList.freq_list = NULL; sme_err("No channels populated with requested operation class and current country, Hence abort the rrm operation"); return QDF_STATUS_E_FAILURE; } @@ -1087,20 +1103,26 @@ static uint8_t *sme_rrm_get_meas_mode_string(uint8_t meas_mode) * Return : QDF_STATUS_SUCCESS - Validation is successful. */ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac, - void *msg_buf) + void *msg_buf) { - tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd)msg_buf; - tpRrmSMEContext pSmeRrmContext; - uint32_t len = 0, i = 0; + tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf; + tpRrmSMEContext sme_rrm_ctx; + uint32_t len = 0, i = 0, j = 0; uint8_t country[WNI_CFG_COUNTRY_CODE_LEN]; uint32_t session_id; struct csr_roam_session *session; QDF_STATUS status; + uint32_t num_chan, local_num_channel; + bool chan_valid; + uint32_t *rrm_freq_list, *local_rrm_freq_list; + uint32_t bcn_chan_freq, local_bcn_chan_freq; + tRrmPEContext rrm_context; - pSmeRrmContext = &mac->rrm.rrmSmeContext[pBeaconReq->measurement_idx]; + sme_rrm_ctx = &mac->rrm.rrmSmeContext[beacon_req->measurement_idx]; + rrm_context = mac->rrm.rrmPEContext; status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *) - pBeaconReq->bssId, + beacon_req->bssId, &session_id); if (QDF_IS_STATUS_ERROR(status)) { sme_err("sme session ID not found for bssid"); @@ -1121,141 +1143,203 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac, else country[2] = OP_CLASS_GLOBAL; - sme_debug("Request index:%d Reg class %d, AP's country code %c%c 0x%x Channel = %d", - pBeaconReq->measurement_idx, - pBeaconReq->channelInfo.regulatoryClass, + sme_debug("RRM_SCN: Index:%d Request Reg class %d, AP's country code %c%c 0x%x, channel = %d", + beacon_req->measurement_idx, + beacon_req->channel_info.reg_class, country[0], country[1], country[2], - pBeaconReq->channelInfo.channelNum); + beacon_req->channel_info.chan_num); - if (pBeaconReq->channelList.numChannels > - SIR_ESE_MAX_MEAS_IE_REQS) { + if (beacon_req->channel_list.num_channels > SIR_ESE_MAX_MEAS_IE_REQS) { sme_err("Beacon report request numChannels:%u exceeds max num channels", - pBeaconReq->channelList.numChannels); + beacon_req->channel_list.num_channels); status = QDF_STATUS_E_INVAL; goto cleanup; } /* section 11.10.8.1 (IEEE Std 802.11k-2008) */ /* channel 0 and 255 has special meaning. */ - if ((pBeaconReq->channelInfo.channelNum == 0) || - ((pBeaconReq->channelInfo.channelNum == 255) - && (pBeaconReq->channelList.numChannels == 0))) { + if ((beacon_req->channel_info.chan_num == 0) || + ((beacon_req->channel_info.chan_num == 255) && + (beacon_req->channel_list.num_channels == 0))) { /* Add all the channel in the regulatory domain. */ len = mac->mlme_cfg->reg.valid_channel_list_num; - if (pSmeRrmContext->channelList.ChannelList) { - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + if (sme_rrm_ctx->channelList.freq_list) { + qdf_mem_free(sme_rrm_ctx->channelList.freq_list); + sme_rrm_ctx->channelList.freq_list = NULL; } - pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len); - if (!pSmeRrmContext->channelList.ChannelList) { + sme_rrm_ctx->channelList.freq_list = + qdf_mem_malloc(sizeof(uint32_t) * len); + if (!sme_rrm_ctx->channelList.freq_list) { status = QDF_STATUS_E_NOMEM; + sme_rrm_ctx->channelList.numOfChannels = 0; goto cleanup; } - csr_get_cfg_valid_channels(mac, pSmeRrmContext->channelList. - ChannelList, &len); + csr_get_cfg_valid_channels( + mac, sme_rrm_ctx->channelList.freq_list, &len); - if (pBeaconReq->channelInfo.regulatoryClass) { - if (sme_rrm_fill_scan_channels(country, pSmeRrmContext, - pBeaconReq->channelInfo. - regulatoryClass, len) != + if (beacon_req->channel_info.reg_class) { + if (sme_rrm_fill_scan_channels( + mac, country, sme_rrm_ctx, + beacon_req->channel_info.reg_class, len) != QDF_STATUS_SUCCESS) goto cleanup; } else { - pSmeRrmContext->channelList.numOfChannels = len; + sme_rrm_ctx->channelList.numOfChannels = len; } } else { len = 0; - pSmeRrmContext->channelList.numOfChannels = 0; + sme_rrm_ctx->channelList.numOfChannels = 0; + num_chan = 0; /* If valid channel is present. We first Measure on the given * channel and if there are additional channels present in * APchannelreport, measure on these also. */ - if (pBeaconReq->channelInfo.channelNum != 255) + if (beacon_req->channel_info.chan_num != 255) len = 1; - len += pBeaconReq->channelList.numChannels; + len += beacon_req->channel_list.num_channels; - if (pSmeRrmContext->channelList.ChannelList) { - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + if (sme_rrm_ctx->channelList.freq_list) { + qdf_mem_free(sme_rrm_ctx->channelList.freq_list); + sme_rrm_ctx->channelList.freq_list = NULL; } - pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len); - if (!pSmeRrmContext->channelList.ChannelList) { + sme_rrm_ctx->channelList.freq_list = + qdf_mem_malloc(sizeof(uint32_t) * len); + if (!sme_rrm_ctx->channelList.freq_list) { + sme_rrm_ctx->channelList.numOfChannels = 0; status = QDF_STATUS_E_NOMEM; goto cleanup; } - if (pBeaconReq->channelInfo.channelNum != 255) { - if (csr_roam_is_channel_valid - (mac, pBeaconReq->channelInfo.channelNum)) - pSmeRrmContext->channelList. - ChannelList[pSmeRrmContext->channelList. - numOfChannels++] = - pBeaconReq->channelInfo.channelNum; - else + rrm_freq_list = sme_rrm_ctx->channelList.freq_list; + bcn_chan_freq = beacon_req->channel_info.chan_freq; + + if (beacon_req->channel_info.chan_num != 255) { + chan_valid = + csr_roam_is_channel_valid(mac, bcn_chan_freq); + + if (chan_valid) { + rrm_freq_list[num_chan] = bcn_chan_freq; + num_chan++; + } else { sme_err("Invalid channel: %d", - pBeaconReq->channelInfo.channelNum); + beacon_req->channel_info.chan_num); + } + } + + for (i = 0; i < beacon_req->channel_list.num_channels; i++) { + bcn_chan_freq = + beacon_req->channel_list.chan_freq_lst[i]; + chan_valid = + csr_roam_is_channel_valid(mac, bcn_chan_freq); + + if (chan_valid) { + rrm_freq_list[num_chan] = bcn_chan_freq; + num_chan++; + } + } + + sme_rrm_ctx->channelList.numOfChannels = num_chan; + } + + local_rrm_freq_list = sme_rrm_ctx->channelList.freq_list; + local_num_channel = 0; + for (i = 0; i < sme_rrm_ctx->channelList.numOfChannels; i++) { + local_bcn_chan_freq = local_rrm_freq_list[i]; + chan_valid = true; + + if (beacon_req->measurement_idx > 0) { + for (j = 0; j < rrm_context.beacon_rpt_chan_num; j ++) { + if (rrm_context.beacon_rpt_chan_list[j] == + local_bcn_chan_freq) { + /* + * Ignore this channel, As this is already + * included in previous request + */ + chan_valid = false; + break; + } + } } - for (i = 0; i < pBeaconReq->channelList.numChannels; i++) { - if (csr_roam_is_channel_valid(mac, pBeaconReq-> - channelList.channelNumber[i])) { - pSmeRrmContext->channelList. - ChannelList[pSmeRrmContext->channelList. - numOfChannels] = pBeaconReq->channelList. - channelNumber[i]; - pSmeRrmContext->channelList.numOfChannels++; + if (chan_valid) { + rrm_context. + beacon_rpt_chan_list[rrm_context.beacon_rpt_chan_num] = + local_bcn_chan_freq; + rrm_context.beacon_rpt_chan_num++; + + if (rrm_context.beacon_rpt_chan_num >= + MAX_NUM_CHANNELS) { + /* this should never happen */ + sme_err("Reset beacon_rpt_chan_num : %d", + rrm_context.beacon_rpt_chan_num); + rrm_context.beacon_rpt_chan_num = 0; } + local_rrm_freq_list[local_num_channel] = + local_bcn_chan_freq; + local_num_channel++; } } + if (local_num_channel == 0) + goto cleanup; + + sme_rrm_ctx->channelList.numOfChannels = local_num_channel; + /* Copy session bssid */ - qdf_mem_copy(pSmeRrmContext->sessionBssId.bytes, pBeaconReq->bssId, + qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, beacon_req->bssId, sizeof(tSirMacAddr)); /* copy measurement bssid */ - qdf_mem_copy(pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, + qdf_mem_copy(sme_rrm_ctx->bssId, beacon_req->macaddrBssid, sizeof(tSirMacAddr)); /* Copy ssid */ - qdf_mem_copy(&pSmeRrmContext->ssId, &pBeaconReq->ssId, + qdf_mem_copy(&sme_rrm_ctx->ssId, &beacon_req->ssId, sizeof(tAniSSID)); - pSmeRrmContext->token = pBeaconReq->uDialogToken; - pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass; - pSmeRrmContext->randnIntvl = - QDF_MAX(pBeaconReq->randomizationInterval, + sme_rrm_ctx->token = beacon_req->uDialogToken; + sme_rrm_ctx->regClass = beacon_req->channel_info.reg_class; + sme_rrm_ctx->randnIntvl = + QDF_MAX(beacon_req->randomizationInterval, mac->rrm.rrmConfig.max_randn_interval); - pSmeRrmContext->currentIndex = 0; - pSmeRrmContext->msgSource = pBeaconReq->msgSource; - qdf_mem_copy((uint8_t *) &pSmeRrmContext->measMode, - (uint8_t *) &pBeaconReq->fMeasurementtype, + sme_rrm_ctx->currentIndex = 0; + sme_rrm_ctx->msgSource = beacon_req->msgSource; + qdf_mem_copy((uint8_t *)&sme_rrm_ctx->measMode, + (uint8_t *)&beacon_req->fMeasurementtype, SIR_ESE_MAX_MEAS_IE_REQS); - qdf_mem_copy((uint8_t *) &pSmeRrmContext->duration, - (uint8_t *) &pBeaconReq->measurementDuration, + qdf_mem_copy((uint8_t *)&sme_rrm_ctx->duration, + (uint8_t *)&beacon_req->measurementDuration, SIR_ESE_MAX_MEAS_IE_REQS); sme_debug("token: %d randnIntvl: %d msgSource: %d measurementduration %d, rrm_ctx duration %d Meas_mode: %s", - pSmeRrmContext->token, pSmeRrmContext->randnIntvl, - pSmeRrmContext->msgSource, pBeaconReq->measurementDuration[0], - pSmeRrmContext->duration[0], sme_rrm_get_meas_mode_string( - pSmeRrmContext->measMode[0])); + sme_rrm_ctx->token, sme_rrm_ctx->randnIntvl, + sme_rrm_ctx->msgSource, beacon_req->measurementDuration[0], + sme_rrm_ctx->duration[0], + sme_rrm_get_meas_mode_string(sme_rrm_ctx->measMode[0])); - return sme_rrm_issue_scan_req(mac, pBeaconReq->measurement_idx); + return sme_rrm_issue_scan_req(mac, beacon_req->measurement_idx); cleanup: - if (pBeaconReq->msgSource == eRRM_MSG_SOURCE_11K) { + if (beacon_req->msgSource == eRRM_MSG_SOURCE_11K) { /* Copy session bssid */ - qdf_mem_copy(pSmeRrmContext->sessionBssId.bytes, - pBeaconReq->bssId, sizeof(tSirMacAddr)); + qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, + beacon_req->bssId, sizeof(tSirMacAddr)); /* copy measurement bssid */ - qdf_mem_copy(pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, + qdf_mem_copy(sme_rrm_ctx->bssId, beacon_req->macaddrBssid, sizeof(tSirMacAddr)); + sme_rrm_ctx->token = beacon_req->uDialogToken; + sme_rrm_ctx->regClass = + beacon_req->channel_info.reg_class; + sme_rrm_ctx->randnIntvl = + QDF_MAX(beacon_req->randomizationInterval, + mac->rrm.rrmConfig.max_randn_interval); + sme_rrm_send_beacon_report_xmit_ind(mac, - pSmeRrmContext->measurement_idx, NULL, true, 0); + sme_rrm_ctx->measurement_idx, NULL, true, 0); } return status; @@ -1538,8 +1622,8 @@ static QDF_STATUS sme_rrm_process_neighbor_report(struct mac_context *mac, sizeof(tSirNeighborBssDescription)); sme_debug("Received neighbor report with Neighbor BSSID: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY( + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF( neighbor_rpt->sNeighborBssDescription[i].bssId)); rrm_calculate_neighbor_ap_roam_score(mac, neighbor_rpt_desc); @@ -1549,9 +1633,9 @@ static QDF_STATUS sme_rrm_process_neighbor_report(struct mac_context *mac, mac, neighbor_rpt_desc, neighbor_rpt->measurement_idx); } else { - sme_err("Roam score of BSSID " QDF_MAC_ADDR_STR + sme_err("Roam score of BSSID " QDF_MAC_ADDR_FMT " is 0, Ignoring..", - QDF_MAC_ADDR_ARRAY(neighbor_rpt-> + QDF_MAC_ADDR_REF(neighbor_rpt-> sNeighborBssDescription[i]. bssId)); @@ -1662,6 +1746,8 @@ static void rrm_change_default_config_param(struct mac_context *mac) { mac->rrm.rrmConfig.rrm_enabled = mac->mlme_cfg->rrm_config.rrm_enabled; + mac->rrm.rrmConfig.sap_rrm_enabled = + mac->mlme_cfg->rrm_config.sap_rrm_enabled; mac->rrm.rrmConfig.max_randn_interval = mac->mlme_cfg->rrm_config.rrm_rand_interval; @@ -1757,9 +1843,9 @@ QDF_STATUS rrm_close(struct mac_context *mac) sme_err("Timer stop fail"); } - if (pSmeRrmContext->channelList.ChannelList) { - qdf_mem_free(pSmeRrmContext->channelList.ChannelList); - pSmeRrmContext->channelList.ChannelList = NULL; + if (pSmeRrmContext->channelList.freq_list) { + qdf_mem_free(pSmeRrmContext->channelList.freq_list); + pSmeRrmContext->channelList.freq_list = NULL; pSmeRrmContext->channelList.numOfChannels = 0; } diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h index 3cc4a4d5f12e7d73ce9e9fa19a7fdae526cf5b4b..afa63f0a540fe9dd2a26895117f156f45e182344 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h @@ -45,6 +45,7 @@ #include #include "wma_api.h" #include "wmi_unified_param.h" +#include "wmi.h" /* Platform specific configuration for max. no. of fragments */ #define QCA_OL_11AC_TX_MAX_FRAGS 2 @@ -172,10 +173,6 @@ #define WMA_BSS_STATUS_STARTED 0x1 #define WMA_BSS_STATUS_STOPPED 0x2 -#define WMA_TARGET_REQ_TYPE_VDEV_START 0x1 -#define WMA_TARGET_REQ_TYPE_VDEV_STOP 0x2 -#define WMA_TARGET_REQ_TYPE_VDEV_DEL 0x3 - #define WMA_PEER_ASSOC_CNF_START 0x01 #define WMA_PEER_ASSOC_TIMEOUT SIR_PEER_ASSOC_TIMEOUT @@ -190,9 +187,6 @@ #define WMA_PDEV_MAC_CFG_RESP 0x07 /* FW response timeout values in milli seconds */ -#define WMA_VDEV_START_REQUEST_TIMEOUT SIR_VDEV_START_REQUEST_TIMEOUT -#define WMA_VDEV_STOP_REQUEST_TIMEOUT SIR_VDEV_STOP_REQUEST_TIMEOUT -#define WMA_VDEV_DELETE_REQUEST_TIMEOUT SIR_VDEV_DELETE_REQUEST_TIMEOUT #define WMA_VDEV_PLCY_MGR_TIMEOUT SIR_VDEV_PLCY_MGR_TIMEOUT #define WMA_VDEV_HW_MODE_REQUEST_TIMEOUT WMA_VDEV_PLCY_MGR_TIMEOUT #define WMA_VDEV_DUAL_MAC_CFG_TIMEOUT WMA_VDEV_PLCY_MGR_TIMEOUT @@ -202,12 +196,6 @@ #define WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT WAKELOCK_DURATION_RECOMMENDED -#define WMA_TGT_INVALID_SNR (0) -#define WMA_TGT_IS_VALID_RSSI(x) ((x) != 0xFF) - -#define WMA_TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < WMA_TGT_MAX_SNR) -#define WMA_TGT_IS_INVALID_SNR(x) (!WMA_TGT_IS_VALID_SNR(x)) - #define WMA_TX_Q_RECHECK_TIMER_WAIT 2 /* 2 ms */ #define WMA_MAX_NUM_ARGS 8 @@ -395,6 +383,19 @@ ((hw_mode & WMA_HW_MODE_SBS_MODE_MASK) >> \ WMA_HW_MODE_SBS_MODE_BITPOS) +/* + * Extract 2G or 5G tx/rx chainmask + * format of txrx_chainmask (from wmi_service_ready_event_fixed_param): + * [7:0] - 2G band tx chain mask + * [15:8] - 2G band rx chain mask + * [23:16] - 5G band tx chain mask + * [31:24] - 5G band rx chain mask + */ +#define EXTRACT_TX_CHAIN_MASK_2G(chainmask) ((chainmask) & 0xFF) +#define EXTRACT_RX_CHAIN_MASK_2G(chainmask) (((chainmask) >> 8) & 0xFF) +#define EXTRACT_TX_CHAIN_MASK_5G(chainmask) (((chainmask) >> 16) & 0xFF) +#define EXTRACT_RX_CHAIN_MASK_5G(chainmask) (((chainmask) >> 24) & 0xFF) + /* * PROBE_REQ_TX_DELAY * param to specify probe request Tx delay for scans triggered on this VDEV @@ -420,9 +421,9 @@ typedef void (*txFailIndCallback)(uint8_t *peer_mac, uint8_t seqNo); * */ enum wma_rx_exec_ctx { - WMA_RX_WORK_CTX, - WMA_RX_TASKLET_CTX, - WMA_RX_SERIALIZER_CTX + WMA_RX_WORK_CTX = WMI_RX_WORK_CTX, + WMA_RX_TASKLET_CTX = WMI_RX_TASKLET_CTX, + WMA_RX_SERIALIZER_CTX = WMI_RX_SERIALIZER_CTX, }; /** @@ -631,7 +632,6 @@ struct wma_version_info { u_int32_t revision; }; -#ifdef WLAN_FEATURE_11W #define CMAC_IPN_LEN (6) #define WMA_IGTK_KEY_INDEX_4 (4) #define WMA_IGTK_KEY_INDEX_5 (5) @@ -646,15 +646,10 @@ typedef struct { /** * struct wma_igtk_key_t - GTK key - * @key_length: key length - * @key: key * @key_id: key id * @key_cipher: key type */ typedef struct { - uint16_t key_length; - uint8_t key[CSR_AES_GMAC_256_KEY_LEN]; - /* IPN is maintained per iGTK keyID * 0th index for iGTK keyID = 4; * 1st index for iGTK KeyID = 5 @@ -662,27 +657,6 @@ typedef struct { wma_igtk_ipn_t key_id[2]; uint32_t key_cipher; } wma_igtk_key_t; -#endif - -/** - * struct vdev_restart_params_t - vdev restart parameters - * @vdev_id: vdev id - * @ssid: ssid - * @flags: flags - * @requestor_id: requestor id - * @chan: channel - * @hidden_ssid_restart_in_progress: hidden ssid restart flag - * @ssidHidden: is ssid hidden or not - */ -typedef struct { - A_UINT32 vdev_id; - wmi_ssid ssid; - A_UINT32 flags; - A_UINT32 requestor_id; - A_UINT32 disable_hw_ack; - wmi_channel chan; - uint8_t ssidHidden; -} vdev_restart_params_t; struct roam_synch_frame_ind { uint32_t bcn_probe_rsp_len; @@ -708,11 +682,7 @@ struct wma_invalid_peer_params { /** * struct wma_txrx_node - txrx node * @vdev: pointer to vdev object - * @addr: mac address - * @bssid: bssid - * @handle: wma handle * @beacon: beacon info - * @vdev_restart_params: vdev restart parameters * @config: per vdev config parameters * @scan_info: scan info * @type: type @@ -724,9 +694,6 @@ struct wma_invalid_peer_params { * @llbCoexist: 11b coexist * @shortSlotTimeSupported: is short slot time supported or not * @dtimPeriod: DTIM period - * @chanmode: channel mode - * @vht_capable: VHT capablity flag - * @ht_capable: HT capablity flag * @mhz: channel frequency in KHz * @chan_width: channel bandwidth * @vdev_up: is vdev up or not @@ -737,15 +704,11 @@ struct wma_invalid_peer_params { * @key: GTK key * @uapsd_cached_val: uapsd cached value * @stats_rsp: stats response - * @fw_stats_set: fw stats value * @del_staself_req: delete sta self request * @bss_status: bss status - * @rate_flags: rate flags * @nss: nss value * @is_channel_switch: is channel switch * @pause_bitmap: pause bitmap - * @tx_power: tx power in dbm - * @max_tx_power: max tx power in dbm * @nwType: network type (802.11a/b/g/n/ac) * @staKeyParams: sta key parameters * @ps_enabled: is powersave enable/disable @@ -753,24 +716,16 @@ struct wma_invalid_peer_params { * @roam_synch_in_progress: flag is in progress or not * @plink_status_req: link status request * @psnr_req: snr request - * @delay_before_vdev_stop: delay * @tx_streams: number of tx streams can be used by the vdev - * @rx_streams: number of rx streams can be used by the vdev - * @chain_mask: chain mask can be used by the vdev * @mac_id: the mac on which vdev is on * @wep_default_key_idx: wep default index for group key * @arp_offload_req: cached arp offload request * @ns_offload_req: cached ns offload request - * @wow_stats: stat counters for WoW related events * @rcpi_req: rcpi request * @in_bmps: Whether bmps for this interface has been enabled - * @vdev_start_wakelock: wakelock to protect vdev start op with firmware - * @vdev_stop_wakelock: wakelock to protect vdev stop op with firmware * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware - * @vdev_start_runtime_wakelock: runtime pm wakelock for vdev start - * @vdev_stop_runtime_wakelock: runtime pm wakelock for vdev stop * @vdev_set_key_runtime_wakelock: runtime pm wakelock for set key - * @channel: channel + * @ch_freq: channel frequency * @roam_scan_stats_req: cached roam scan stats request * @wma_invalid_peer_params: structure storing invalid peer params * @invalid_peer_idx: invalid peer index @@ -778,11 +733,7 @@ struct wma_invalid_peer_params { */ struct wma_txrx_node { struct wlan_objmgr_vdev *vdev; - uint8_t addr[QDF_MAC_ADDR_SIZE]; - uint8_t bssid[QDF_MAC_ADDR_SIZE]; - struct cdp_vdev *handle; struct beacon_info *beacon; - vdev_restart_params_t vdev_restart_params; vdev_cli_config_t config; uint32_t type; uint32_t sub_type; @@ -793,63 +744,45 @@ struct wma_txrx_node { uint8_t llbCoexist; uint8_t shortSlotTimeSupported; uint8_t dtimPeriod; - WMI_HOST_WLAN_PHY_MODE chanmode; - uint8_t vht_capable; - uint8_t ht_capable; A_UINT32 mhz; enum phy_ch_width chan_width; bool vdev_active; uint64_t tsfadjust; - void *addBssStaContext; - uint8_t aid; + tAddStaParams *addBssStaContext; + uint16_t aid; uint8_t rmfEnabled; -#ifdef WLAN_FEATURE_11W wma_igtk_key_t key; -#endif /* WLAN_FEATURE_11W */ uint32_t uapsd_cached_val; - tAniGetPEStatsRsp *stats_rsp; - uint8_t fw_stats_set; void *del_staself_req; bool is_del_sta_defered; qdf_atomic_t bss_status; enum tx_rate_info rate_flags; uint8_t nss; uint16_t pause_bitmap; - int8_t tx_power; - int8_t max_tx_power; uint32_t nwType; - void *staKeyParams; + tSetStaKeyParams *staKeyParams; uint32_t peer_count; bool roam_synch_in_progress; void *plink_status_req; void *psnr_req; - uint8_t delay_before_vdev_stop; #ifdef FEATURE_WLAN_EXTSCAN bool extscan_in_progress; #endif uint32_t tx_streams; - uint32_t rx_streams; - uint32_t chain_mask; uint32_t mac_id; bool roaming_in_progress; int32_t roam_synch_delay; uint8_t wep_default_key_idx; -#ifndef QCA_SUPPORT_CP_STATS - struct sir_vdev_wow_stats wow_stats; -#endif struct sme_rcpi_req *rcpi_req; bool in_bmps; struct beacon_filter_param beacon_filter; bool beacon_filter_enabled; - qdf_wake_lock_t vdev_start_wakelock; - qdf_wake_lock_t vdev_stop_wakelock; qdf_wake_lock_t vdev_set_key_wakelock; - qdf_runtime_lock_t vdev_start_runtime_wakelock; - qdf_runtime_lock_t vdev_stop_runtime_wakelock; qdf_runtime_lock_t vdev_set_key_runtime_wakelock; struct roam_synch_frame_ind roam_synch_frame_ind; bool is_waiting_for_key; - uint8_t channel; + uint32_t ch_freq; + uint16_t ch_flagext; struct sir_roam_scan_stats *roam_scan_stats_req; struct wma_invalid_peer_params invalid_peers[INVALID_PEER_MAX_NUM]; uint8_t invalid_peer_idx; @@ -900,13 +833,13 @@ struct wma_ini_config { }; /** - * struct wmi_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID + * struct wma_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID * @num_channels: Number of channels - * @channel_list: Channel list + * @ch_freq_list: Channel Frequency list */ struct wma_valid_channels { uint8_t num_channels; - uint8_t channel_list[MAX_NUM_CHAN]; + uint32_t ch_freq_list[NUM_CHANNELS]; }; #ifdef FEATURE_WLM_STATS @@ -959,8 +892,6 @@ struct wma_wlm_stats_data { * @scan_id: scan id * @interfaces: txrx nodes(per vdev) * @pdevconfig: pdev related configrations - * @vdev_resp_queue: vdev response queue - * @vdev_respq_lock: vdev response queue lock * @wma_hold_req_queue: Queue use to serialize requests to firmware * @wma_hold_req_q_lock: Mutex for @wma_hold_req_queue * @vht_supp_mcs: VHT supported MCS @@ -970,7 +901,6 @@ struct wma_wlm_stats_data { * @pGetRssiReq: get RSSI request * @get_one_peer_info: When a "get peer info" request is active, is * the request for a single peer? - * @get_sta_peer_info: Is a "get peer info" request active? * @peer_macaddr: When @get_one_peer_info is true, the peer's mac address * @thermal_mgmt_info: Thermal mitigation related info * @enable_mc_list: To Check if Multicast list filtering is enabled in FW @@ -1007,10 +937,6 @@ struct wma_wlm_stats_data { * @old_hw_mode_index: Previous configured HW mode index * @new_hw_mode_index: Current configured HW mode index * @peer_authorized_cb: peer authorized hdd callback - * @wow_unspecified_wake_count: Number of wake events which did not - * correspond to known wake events. Note that known wake events are - * tracked on a per-vdev basis via the struct sir_vdev_wow_stats - * wow_stats in struct wma_txrx_node * @ocb_config_req: OCB request context * @self_gen_frm_pwr: Self-generated frame power * @tx_chain_mask_cck: Is the CCK tx chain mask enabled @@ -1054,8 +980,6 @@ struct wma_wlm_stats_data { * @dynamic_nss_chains_update: per vdev nss, chains update * @ito_repeat_count: Indicates ito repeated count * @wma_fw_time_sync_timer: timer used for firmware time sync - * @critical_events_in_flight: number of suspend-preventing events - * in flight * * @fw_therm_throt_support: FW Supports thermal throttling? * * This structure is the global wma context. It contains global wma @@ -1096,8 +1020,6 @@ typedef struct { uint32_t scan_id; struct wma_txrx_node *interfaces; pdev_cli_config_t pdevconfig; - qdf_list_t vdev_resp_queue; - qdf_spinlock_t vdev_respq_lock; qdf_list_t wma_hold_req_queue; qdf_spinlock_t wma_hold_req_q_lock; uint32_t vht_supp_mcs; @@ -1106,7 +1028,6 @@ typedef struct { uint8_t powersave_mode; void *pGetRssiReq; bool get_one_peer_info; - bool get_sta_peer_info; struct qdf_mac_addr peer_macaddr; t_thermal_mgmt thermal_mgmt_info; bool enable_mc_list; @@ -1145,7 +1066,6 @@ typedef struct { uint32_t old_hw_mode_index; uint32_t new_hw_mode_index; wma_peer_authorized_fp peer_authorized_cb; - uint32_t wow_unspecified_wake_count; struct sir_ocb_config *ocb_config_req; uint16_t self_gen_frm_pwr; bool tx_chain_mask_cck; @@ -1197,9 +1117,11 @@ typedef struct { bool dynamic_nss_chains_support; uint8_t ito_repeat_count; qdf_mc_timer_t wma_fw_time_sync_timer; - qdf_atomic_t critical_events_in_flight; bool fw_therm_throt_support; bool enable_tx_compl_tsf64; +#ifdef WLAN_FEATURE_PKT_CAPTURE + bool is_pktcapture_enabled; +#endif } t_wma_handle, *tp_wma_handle; /** @@ -1276,64 +1198,6 @@ struct wma_target_req { uint8_t type; }; -/** - * struct wma_vdev_start_req - vdev start request parameters - * @beacon_intval: beacon interval - * @dtim_period: dtim period - * @max_txpow: max tx power - * @chan_offset: channel offset - * @is_dfs: is dfs supported or not - * @vdev_id: vdev id - * @chan: channel - * @oper_mode: operating mode - * @ssid: ssid - * @hidden_ssid: hidden ssid - * @pmf_enabled: is pmf enabled or not - * @vht_capable: VHT capabality - * @ht_capable: HT capabality - * @dot11_mode: 802.11 mode - * @is_half_rate: is the channel operating at 10MHz - * @is_quarter_rate: is the channel operating at 5MHz - * @preferred_tx_streams: policy manager indicates the preferred - * number of transmit streams - * @preferred_rx_streams: policy manager indicates the preferred - * number of receive streams - * @beacon_tx_rate: beacon tx rate - * @he_capable: HE capability - * @he_ops: HE operation - * @cac_duration_ms: cac duration in milliseconds - * @dfs_regdomain: dfs region - */ -struct wma_vdev_start_req { - uint32_t beacon_intval; - uint32_t dtim_period; - int32_t max_txpow; - enum phy_ch_width chan_width; - bool is_dfs; - uint8_t vdev_id; - uint8_t chan; - uint8_t oper_mode; - tSirMacSSid ssid; - uint8_t hidden_ssid; - uint8_t pmf_enabled; - uint8_t vht_capable; - uint8_t ch_center_freq_seg0; - uint8_t ch_center_freq_seg1; - uint8_t ht_capable; - uint8_t dot11_mode; - bool is_half_rate; - bool is_quarter_rate; - uint32_t preferred_tx_streams; - uint32_t preferred_rx_streams; - uint16_t beacon_tx_rate; -#ifdef WLAN_FEATURE_11AX - bool he_capable; - uint32_t he_ops; -#endif - uint32_t cac_duration_ms; - uint32_t dfs_regdomain; -}; - /** * struct wma_set_key_params - set key parameters * @vdev_id: vdev id @@ -1599,6 +1463,14 @@ enum uapsd_ac { UAPSD_VO }; +/** + * wma_disable_uapsd_per_ac() - disable uapsd per ac + * @wmi_handle: wma handle + * @vdev_id: vdev id + * @ac: access category + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle, uint32_t vdev_id, enum uapsd_ac ac); @@ -1629,7 +1501,7 @@ enum uapsd_up { * struct wma_roam_invoke_cmd - roam invoke command * @vdev_id: vdev id * @bssid: mac address - * @channel: channel + * @ch_freq: channel frequency * @frame_len: frame length, includs mac header, fixed params and ies * @frame_buf: buffer contaning probe response or beacon * @is_same_bssid: flag to indicate if roaming is requested for same bssid @@ -1638,46 +1510,36 @@ enum uapsd_up { struct wma_roam_invoke_cmd { uint32_t vdev_id; uint8_t bssid[QDF_MAC_ADDR_SIZE]; - uint32_t channel; + uint32_t ch_freq; uint32_t frame_len; uint8_t *frame_buf; uint8_t is_same_bssid; bool forced_roaming; }; -/** - * struct wma_process_fw_event_params - fw event parameters - * @wmi_handle: wmi handle - * @evt_buf: event buffer - */ -typedef struct { - void *wmi_handle; - void *evt_buf; -} wma_process_fw_event_params; - -/** - * wma_process_fw_event_handler() - common event handler to serialize - * event processing through mc_thread - * @scn_handle: scn handle - * @ev: event buffer - * @rx_ctx: rx execution context - * - * Return: 0 on success, errno on failure - */ -int wma_process_fw_event_handler(ol_scn_t scn_handle, void *ev, - uint8_t rx_ctx); - A_UINT32 e_csr_auth_type_to_rsn_authmode(enum csr_akm_type authtype, eCsrEncryptionType encr); A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr); +/** + * wma_trigger_uapsd_params() - set trigger uapsd parameter + * @wmi_handle: wma handle + * @vdev_id: vdev id + * @trigger_uapsd_params: trigger uapsd parameters + * + * This function sets the trigger uapsd + * params such as service interval, delay + * interval and suspend interval which + * will be used by the firmware to send + * trigger frames periodically when there + * is no traffic on the transmit side. + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id, tp_wma_trigger_uapsd_params trigger_uapsd_params); -/* added to get average snr for both data and beacon */ -QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq); - void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle); void wma_log_completion_timeout(void *data); @@ -1714,21 +1576,11 @@ QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle, QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle, struct sir_antenna_mode_param *msg); -struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, - uint8_t vdev_id, - uint32_t msg_type, uint8_t type, - void *params, uint32_t timeout); struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma, uint8_t vdev_id, uint32_t msg_type, uint8_t type, void *params, uint32_t timeout); -QDF_STATUS wma_vdev_start(tp_wma_handle wma, - struct wma_vdev_start_req *req, bool isRestart); - -void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id, - uint8_t type); - int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params, uint32_t len); int wma_mgmt_tx_bundle_completion_handler(void *handle, @@ -1764,23 +1616,6 @@ QDF_STATUS wma_set_gateway_params(tp_wma_handle wma, QDF_STATUS wma_lro_config_cmd(void *handle, struct cdp_lro_hash_config *wma_lro_cmd); -void -wma_indicate_err(enum ol_rx_err_type err_type, - struct ol_error_info *err_info); - -/** - * wma_rx_mic_error_ind() - indicate mic error to the protocol stack - * @scn_handle: pdev handle from osif layer - * @vdev_id: vdev id - * @wh: pointer to ieee80211_frame structure - * - * This function indicates TKIP MIC errors encountered in the RX data path - * to the protocol stack - * - * Return: none - */ -void wma_rx_mic_error_ind(void *scn_handle, uint16_t vdev_id, void *wh); - QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma_handle, int32_t vdev_id); @@ -1894,12 +1729,10 @@ void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma, void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma, struct set_ie_param *ie_params); -QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, - uint8_t vdev_id, void *peer, - bool roam_synch_in_progress); +QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, + uint8_t vdev_id, bool no_fw_peer_delete); -QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, - struct cdp_vdev *vdev, uint8_t peer_addr[6], +QDF_STATUS wma_create_peer(tp_wma_handle wma, uint8_t peer_addr[6], u_int32_t peer_type, u_int8_t vdev_id, bool roam_synch_in_progress); @@ -1907,6 +1740,9 @@ QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id, uint32_t peer_id_cnt, uint16_t *peer_id_list); +bool wma_objmgr_peer_exist(tp_wma_handle wma, + uint8_t *peer_addr, uint8_t *peer_vdev_id); + /** * wma_get_cca_stats() - send request to fw to get CCA * @wmi_hdl: wma handle @@ -1918,8 +1754,36 @@ QDF_STATUS wma_get_cca_stats(tp_wma_handle wma_handle, uint8_t vdev_id); struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle); -WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width, - uint8_t dot11_mode); + +/** + * wma_chan_phy__mode() - get host phymode for channel + * @freq: channel freq + * @chan_width: maximum channel width possible + * @dot11_mode: maximum phy_mode possible + * + * Return: return host phymode + */ +enum wlan_phymode wma_chan_phy_mode(uint32_t freq, enum phy_ch_width chan_width, + uint8_t dot11_mode); + +/** + * wma_host_to_fw_phymode() - convert host to fw phymode + * @host_phymode: phymode to convert + * + * Return: one of the values defined in enum WMI_HOST_WLAN_PHY_MODE; + * or WMI_HOST_MODE_UNKNOWN if the conversion fails + */ +WMI_HOST_WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode); + +/** + * wma_fw_to_host_phymode() - convert fw to host phymode + * @phymode: phymode to convert + * + * Return: one of the values defined in enum wlan_phymode; + * or WLAN_PHYMODE_AUTO if the conversion fails + */ +enum wlan_phymode wma_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode); + #ifdef FEATURE_OEM_DATA_SUPPORT /** @@ -2040,14 +1904,7 @@ void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value) iface = &wma->interfaces[vdev_id]; if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return; - } - - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Interface is NULL", __func__); return; } @@ -2074,51 +1931,13 @@ uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id) iface = &wma->interfaces[vdev_id]; if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return 0; - } - - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Interface is NULL", __func__); return 0; } return iface->pause_bitmap; } -/** - * wma_vdev_get_dp_handle() - Get vdev datapth handle - * @vdev_id: the Id of the vdev to configure - * - * Return: Vdev datapath handle else NULL on error - */ -static inline -struct cdp_vdev *wma_vdev_get_vdev_dp_handle(uint8_t vdev_id) -{ - tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); - struct wma_txrx_node *iface; - - if (!wma) { - WMA_LOGE("%s: WMA context is invald!", __func__); - return NULL; - } - - if (vdev_id >= wma->max_bssid) - return NULL; - - iface = &wma->interfaces[vdev_id]; - - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return NULL; - } - - return iface->handle; -} - /** * wma_vdev_is_device_in_low_pwr_mode - is device in power save mode * @vdev_id: the Id of the vdev to configure @@ -2138,14 +1957,7 @@ static inline bool wma_vdev_is_device_in_low_pwr_mode(uint8_t vdev_id) iface = &wma->interfaces[vdev_id]; if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return 0; - } - - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle:NULL", - __func__); + WMA_LOGE("%s: Interface is NULL", __func__); return 0; } @@ -2175,7 +1987,7 @@ QDF_STATUS wma_vdev_get_dtim_period(uint8_t vdev_id, uint8_t *value) iface = &wma->interfaces[vdev_id]; - if (!iface || !iface->handle) + if (!iface) return QDF_STATUS_E_FAILURE; *value = iface->dtimPeriod; @@ -2205,13 +2017,43 @@ QDF_STATUS wma_vdev_get_beacon_interval(uint8_t vdev_id, uint16_t *value) iface = &wma->interfaces[vdev_id]; - if (!iface || !iface->handle) + if (!iface) return QDF_STATUS_E_FAILURE; *value = iface->beaconInterval; return QDF_STATUS_SUCCESS; } +/** + * wma_get_vdev_rate_flag - Get beacon rate flag from mlme + * @vdev_id: vdev index number + * @rate_flag: pointer to the value to fill out + * + * Note caller must verify return status before using value + * + * Return: QDF_STATUS_SUCCESS when fetched a valid value from mlme else + * QDF_STATUS_E_FAILURE + */ +static inline QDF_STATUS +wma_get_vdev_rate_flag(struct wlan_objmgr_vdev *vdev, uint32_t *rate_flag) +{ + struct vdev_mlme_obj *mlme_obj; + + if (!vdev) { + WMA_LOGE("%s vdev is NULL", __func__); + return QDF_STATUS_E_FAILURE; + } + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + WMA_LOGE("%s Failed to get mlme_obj", __func__); + return QDF_STATUS_E_FAILURE; + } + + *rate_flag = mlme_obj->mgmt.rate_info.rate_flags; + return QDF_STATUS_SUCCESS; +} + /** * wma_vdev_set_pause_bit() - Set a bit in vdev pause bitmap * @vdev_id: the Id of the vdev to configure @@ -2233,14 +2075,7 @@ void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) iface = &wma->interfaces[vdev_id]; if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return; - } - - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Interface is NULL", __func__); return; } @@ -2268,38 +2103,13 @@ void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) iface = &wma->interfaces[vdev_id]; if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); - return; - } - - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Interface is NULL", __func__); return; } iface->pause_bitmap &= ~(1 << bit_pos); } -/** - * wma_host_to_fw_phymode() - convert host to fw phymode - * @host_phymode: phymode to convert - * - * Return: one of the values defined in enum WMI_HOST_WLAN_PHY_MODE; - * or WMI_HOST_MODE_UNKNOWN if the conversion fails - */ -WMI_HOST_WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode); - -/** - * wma_fw_to_host_phymode() - convert fw to host phymode - * @phymode: phymode to convert - * - * Return: one of the values defined in enum wlan_phymode; - * or WLAN_PHYMODE_AUTO if the conversion fails - */ -enum wlan_phymode wma_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode); - /** * wma_process_roaming_config() - process roam request * @wma_handle: wma handle @@ -2605,8 +2415,6 @@ bool wma_is_roam_in_progress(uint32_t vdev_id); */ struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle); -#ifdef CRYPTO_SET_KEY_CONVERGED - /** * wma_set_peer_ucast_cipher() - Update unicast cipher fof the peer * @mac_addr: peer mac address @@ -2629,16 +2437,17 @@ void wma_set_peer_ucast_cipher(uint8_t *mac_addr, void wma_update_set_key(uint8_t session_id, bool pairwise, uint8_t key_index, enum wlan_crypto_cipher_type cipher_type); -#endif /** * wma_get_igtk() - Get the IGTK that was stored in the session earlier * @iface: Interface for which the key is being requested * @key_len: key length + * @igtk_key_idx: igtk key idx * * Return: Pointer to the key */ -uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len); +uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len, + uint16_t igtk_key_idx); #ifdef WLAN_FEATURE_MOTION_DETECTION /** @@ -2668,16 +2477,60 @@ int wma_motion_det_base_line_host_event_handler(void *handle, u_int8_t *event, #endif /* WLAN_FEATURE_MOTION_DETECTION */ /** - * wma_release_pending_vdev_refs() - release vdev ref taken by interface txrx - * node and delete all the peers attached to this vdev. + * wma_add_bss_peer_sta() - creat bss peer when sta connect + * @self_mac: self mac address + * @bssid: AP bssid + * @roam_sync: if roam sync is in progress + * + * Return: 0 on success, else error on failure + */ +QDF_STATUS wma_add_bss_peer_sta(uint8_t *self_mac, uint8_t *bssid, + bool roam_sync); + +/** + * wma_send_vdev_stop() - WMA api to send vdev stop to fw + * @vdev_id: vdev id + * + * Return: 0 on success, else error on failure + */ +QDF_STATUS wma_send_vdev_stop(uint8_t vdev_id); + +/** + * wma_pre_assoc_req() - wma pre assoc req when sta connect + * @add_bss: add bss param + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_pre_assoc_req(struct bss_params *add_bss); + +/** + * wma_add_bss_lfr3() - add bss during LFR3 offload roaming + * @wma: wma handler + * @add_bss: add bss param + * + * Return: None + */ +void wma_add_bss_lfr3(tp_wma_handle wma, struct bss_params *add_bss); + +#ifdef WLAN_FEATURE_HOST_ROAM +/** + * wma_add_bss_lfr2_vdev_start() - add bss and start vdev during host roaming + * @vdev: vdev in object manager + * @add_bss: add bss param * - * This API loop and release vdev ref taken by all iface and all the peers - * attached to the vdev, this need to be called on recovery to flush vdev - * and peer. + * Return: None + */ +QDF_STATUS wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev *vdev, + struct bss_params *add_bss); +#endif + +/** + * wma_send_peer_assoc_req() - wma send peer assoc req when sta connect + * @add_bss: add bss param * - * Return: void. + * Return: None */ -void wma_release_pending_vdev_refs(void); +QDF_STATUS wma_send_peer_assoc_req(struct bss_params *add_bss); /** * wma_get_rx_chainmask() - API to get rx chainmask from mac phy capability @@ -2691,4 +2544,97 @@ void wma_release_pending_vdev_refs(void); */ QDF_STATUS wma_get_rx_chainmask(uint8_t pdev_id, uint32_t *chainmask_2g, uint32_t *chainmask_5g); + +/** + * wma_handle_channel_switch_resp() - handle channel switch resp + * @wma: wma handle + * @rsp: response for channel switch + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, + struct vdev_start_response *rsp); + +/** + * wma_pre_chan_switch_setup() - handler before channel switch vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_pre_chan_switch_setup(uint8_t vdev_id); + +/** + * wma_post_chan_switch_setup() - handler after channel switch vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_post_chan_switch_setup(uint8_t vdev_id); + +/** + * wma_vdev_pre_start() - prepare vdev start + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart); + +/** + * wma_remove_bss_peer_on_vdev_start_failure() - remove the bss peers in case of + * vdev start request failure + * @wma: wma handle. + * @vdev_id: vdev id + * + * This API deletes the BSS peer created during ADD BSS in case of ADD BSS + * request sent to the FW fails. + * + * Return: None; + */ +void wma_remove_bss_peer_on_vdev_start_failure(tp_wma_handle wma, + uint8_t vdev_id); + +/** + * wma_send_add_bss_resp() - send add bss failure + * @wma: wma handle. + * @vdev_id: vdev id + * @status: status + * + * Return: None + */ +void wma_send_add_bss_resp(tp_wma_handle wma, uint8_t vdev_id, + QDF_STATUS status); + +/** + * wma_post_vdev_start_setup() - wma post vdev start handler + * @wma: wma handle. + * @vdev_id: vdev id + * + * Return: Success or Failure status + */ +QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id); + +/** + * wma_pre_vdev_start_setup() - wma pre vdev start handler + * @wma: wma handle. + * @vdev_id: vdev id + * @addbss_param: bss param + * + * Return: Success or Failure status + */ +QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, + struct bss_params *add_bss); + +#ifdef FEATURE_ANI_LEVEL_REQUEST +/** + * wma_send_ani_level_request() - Send get ani level cmd to WMI + * @wma_handle: wma handle. + * @freqs: pointer to channels for which ANI level has to be retrieved + * @num_freqs: number of channels in the above parameter + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_send_ani_level_request(tp_wma_handle wma_handle, + uint32_t *freqs, uint8_t num_freqs); +#endif /* FEATURE_ANI_LEVEL_REQUEST */ #endif + diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_api.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_api.h index 2ad563ee738dc47038d2a73f3d1b5cbf71d6b5f5..06432d71b89ff050d371b58859cf107c8ad5a38c 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_api.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_api.h @@ -132,6 +132,16 @@ int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev); int wma_cli_set2_command(int vdev_id, int param_id, int sval1, int sval2, int vpdev); +/** + * wma_get_fw_phy_mode_for_freq_cb() - Callback to get current PHY Mode. + * @freq: channel freq + * @chan_width: maximum channel width possible + * @phy_mode: firmware PHY Mode + * + * Return: None + */ +void wma_get_fw_phy_mode_for_freq_cb(uint32_t freq, uint32_t chan_width, + uint32_t *phy_mode); /** * wma_get_phy_mode_cb() - Callback to get current PHY Mode. * @chan: channel number @@ -140,7 +150,8 @@ int wma_cli_set2_command(int vdev_id, int param_id, int sval1, * * Return: None */ -void wma_get_phy_mode_cb(uint8_t chan, uint32_t chan_width, uint32_t *phy_mode); +void wma_get_phy_mode_cb(uint8_t chan, uint32_t chan_width, + enum wlan_phymode *phy_mode); QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value); @@ -154,6 +165,12 @@ QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, void *scan_chan_info); #endif +/** + * wma_get_vdev_address_by_vdev_id() - lookup MAC address from vdev ID + * @vdev_id: vdev id + * + * Return: mac address + */ uint8_t *wma_get_vdev_address_by_vdev_id(uint8_t vdev_id); struct wma_txrx_node *wma_get_interface_by_vdev_id(uint8_t vdev_id); QDF_STATUS wma_get_connection_info(uint8_t vdev_id, @@ -161,10 +178,6 @@ QDF_STATUS wma_get_connection_info(uint8_t vdev_id, QDF_STATUS wma_ndi_update_connection_info(uint8_t vdev_id, struct nan_datapath_channel_info *ndp_chan_info); -#ifdef WLAN_FEATURE_PKT_CAPTURE -int wma_get_rmf_status(uint8_t vdev_id); -#endif - bool wma_is_vdev_up(uint8_t vdev_id); void *wma_get_beacon_buffer_by_vdev_id(uint8_t vdev_id, uint32_t *buffer_size); @@ -179,7 +192,7 @@ void wma_update_intf_hw_mode_params(uint32_t vdev_id, uint32_t mac_id, void wma_set_dbs_capability_ut(uint32_t dbs); QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy, enum hw_mode_dbs_capab hw_mode, enum cds_band_type band); -bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel); +bool wma_is_rx_ldpc_supported_for_channel(uint32_t ch_freq); #ifdef WLAN_FEATURE_LINK_LAYER_STATS int wma_unified_radio_tx_mem_free(void *handle); @@ -264,9 +277,6 @@ static inline bool wma_is_p2p_lo_capable(void) } #endif bool wma_capability_enhanced_mcast_filter(void); -#ifndef QCA_SUPPORT_CP_STATS -QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats); -#endif void wma_process_pdev_hw_mode_trans_ind(void *wma, wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param, wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry, @@ -284,8 +294,6 @@ void wma_process_pdev_hw_mode_trans_ind(void *wma, */ QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle, uint32_t cts2self_for_p2p_go); -QDF_STATUS wma_set_tx_rx_aggregation_size - (struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size); #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** @@ -307,19 +315,42 @@ QDF_STATUS wma_get_roam_scan_ch(wmi_unified_t wma, #endif /** - * wma_set_tx_rx_aggregation_size_per_ac() - set aggregation size per ac - * @tx_rx_aggregation_size: the parameter for aggregation size + * wma_set_tx_rx_aggr_size() - set tx rx aggregation size + * @vdev_id: vdev id + * @tx_size: tx aggr size + * @rx_size: rx aggr size + * @aggr_type: aggregation type * - * This function try to set the aggregation size per AC. + * This function try to set the aggregation size. * * Return: QDF_STATUS enumeration */ -QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac - (struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size); +QDF_STATUS wma_set_tx_rx_aggr_size(uint8_t vdev_id, + uint32_t tx_size, + uint32_t rx_size, + wmi_vdev_custom_aggr_type_t aggr_type); +/** + * wma_set_tx_rx_aggr_size_per_ac() - set aggregation size per ac + * @wma_handle: pointer to wma handle. + * @vdev_id: vdev_id + * @qos_aggr: QoS data + * @aggr_type: aggregation type + * + * This function try to set the aggregation size per AC. + * + * Return: QDF_STATUS enumeration + */ +QDF_STATUS +wma_set_tx_rx_aggr_size_per_ac(WMA_HANDLE wma_handle, + uint8_t vdev_id, + struct wlan_mlme_qos *qos_aggr, + wmi_vdev_custom_aggr_type_t aggr_type); + /** * wma_set_sw_retry_threshold_per_ac() - set sw retry threshold per AC for tx * @handle: wma handle - * @tx_sw_retry_threshold: value needs to set to firmware + * @vdev_id: vdev id + * @qos_aggr: pointer to QOS TX/RX aggregation values * * This function sends WMI command to set the sw retry threshold per AC * for Tx. @@ -328,19 +359,20 @@ QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac */ QDF_STATUS wma_set_sw_retry_threshold_per_ac (WMA_HANDLE handle, - struct sir_set_tx_sw_retry_threshold *tx_sw_retry_threshold); + uint8_t vdev_id, struct wlan_mlme_qos *qos_aggr); /** * wma_set_sw_retry_threshold() - set sw retry threshold for tx * @vdev_id: vdev * @retry: retry number - * @param: for aggregation or non-aggregation + * @param_id: aggregrate sw retry threshold param id * * This function sends WMI command to set the sw retry threshold for Tx. * * Return: QDF_STATUS. */ QDF_STATUS wma_set_sw_retry_threshold(uint8_t vdev_id, uint32_t retry, - uint32_t param); + uint32_t param_id); + /** * wma_get_sar_limit() - get SAR limits from the target * @handle: wma handle @@ -379,13 +411,13 @@ QDF_STATUS wma_send_coex_config_cmd(WMA_HANDLE wma_handle, struct coex_config_params *coex_cfg_params); /** - * wma_set_qpower_config() - update qpower config in wma + * wma_set_power_config() - update power config in wma * @vdev_id: the Id of the vdev to configure - * @qpower: new qpower value + * @power: new power value * * Return: QDF_STATUS_SUCCESS on success, error number otherwise */ -QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower); +QDF_STATUS wma_set_power_config(uint8_t vdev_id, enum powersave_mode power); #ifdef FEATURE_WLAN_D0WOW static inline bool wma_d0_wow_is_supported(void) @@ -617,6 +649,17 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, */ QDF_STATUS wma_sta_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); +/** + * wma_post_vdev_create_setup() - Post vdev create setup + * @vdev: vdev obj + * + * This API is invoked after vded is created to perform post + * vdev create operations i.e. creating peer and setting vdev params. + * + * Return: SUCCESS on successful post vdev operations, FAILURE, if it + * fails due to any + */ +QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev); /** * wma_mon_mlme_vdev_start_continue() - VDEV start response handling @@ -674,6 +717,38 @@ QDF_STATUS wma_mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS wma_mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data); +/** + * wma_vdev_detach_callback() - VDEV delete response handler + * @rsp: pointer to vdev delete response + * + * This API proccesses vdev delete response and gives to upper layers + * + * Return: SUCCESS on successful completion of VDEV delete operation + * FAILURE, if it fails due to any + */ +QDF_STATUS wma_vdev_detach_callback(struct vdev_delete_response *rsp); + +/** + * wma_vdev_stop_resp_handler() - vdev stop response handler + * @handle: wma handle + * @cmd_param_info: event buffer + * @len: buffer length + * + * Return: 0 for success or error code + */ +QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme, + struct vdev_stop_response *rsp); + +/** + * wma_vdev_start_resp_handler() - vdev start response handler + * @vdev_mlme: vdev mlme obj + * @rsp: vdev start response + * + * Return: QDF status + */ +QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, + struct vdev_start_response *rsp); + #ifdef FEATURE_WLM_STATS /** * typedef wma_wlm_stats_cb() - Callback function for WLM stats @@ -724,4 +799,26 @@ int wma_wlm_stats_rsp(void *wma_ctx, uint8_t *event, uint32_t len); */ void wma_update_roam_offload_flag(void *handle, struct roam_init_params *params); + +/** + * wma_self_peer_create() - create self peer in objmgr + * @vdev_mlme: vdev mlme component private object + * + * Create the self peer in firmware for beaconing vdev's and create then + * object manager self-peer for the vdev. + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme); + +/** + * wma_cleanup_vdev() - cleanup wma layers vdev + * @vdev: Object manager vdev + * + * This function cleansup the wma layers vdev related data. + * + * Return: None + */ +void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev); + #endif /* WMA_API_H */ diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_he.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_he.h index 8ee1eb0bfcc355701b835924cb6080cdd95a6c9e..1bf80a93e27cdc016c925e57eb960c44a4ede25e 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_he.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_he.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -127,23 +127,12 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer, /** * wma_update_vdev_he_ops() - update he ops in vdev start request - * @req: pointer to vdev start request - * @add_bss: pointer to ADD BSS params + * @he_ops: target he ops + * @he_op: source he ops * * Return: None */ -void wma_update_vdev_he_ops(struct wma_vdev_start_req *req, - tpAddBssParams add_bss); - -/** - * wma_copy_vdev_start_he_ops() - copy HE ops from vdev start req to vdev start - * @params: pointer to vdev_start_params - * @req: pointer to vdev start request - * - * Return: None - */ -void wma_copy_vdev_start_he_ops(struct vdev_start_params *params, - struct wma_vdev_start_req *req); +void wma_update_vdev_he_ops(uint32_t *he_ops, tDot11fIEhe_op *he_op); #define DOT11AX_HEMU_MODE 0x30 #define HE_SUBFEE 0 @@ -176,12 +165,12 @@ void wma_set_he_txbf_cfg(struct mac_context *mac, uint8_t vdev_id); * wma_vdev_set_he_bss_params() - set HE OPs in vdev start * @wma: pointer to wma handle * @vdev_id: VDEV id - * @req: pointer to vdev start request + * @he_info: pointer to he info * * Return: None */ void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id, - struct wma_vdev_start_req *req); + struct vdev_mlme_he_ops_info *he_info); /** * wma_vdev_set_he_config() - set HE Config in vdev start @@ -192,23 +181,13 @@ void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id, * Return: None */ void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id, - tpAddBssParams add_bss); + struct bss_params *add_bss); static inline bool wma_is_peer_he_capable(tpAddStaParams params) { return params->he_capable; } -/** - * wma_update_vdev_he_capable() - update vdev start request he capability - * @req: pointer to vdev start request - * @params: pointer to chan switch params - * - * Return: None - */ -void wma_update_vdev_he_capable(struct wma_vdev_start_req *req, - tpSwitchChannelParams params); - /** * wma_update_he_ops_ie() - update the HE OPS IE to firmware * @wma: pointer to wma context @@ -300,13 +279,8 @@ static inline void wma_populate_peer_he_cap(struct peer_assoc_params *peer, { } -static inline void wma_update_vdev_he_ops(struct wma_vdev_start_req *req, - tpAddBssParams add_bss) -{ -} - -static inline void wma_copy_vdev_start_he_ops(struct vdev_start_params *params, - struct wma_vdev_start_req *req) +static inline +void wma_update_vdev_he_ops(uint32_t *he_ops, tDot11fIEhe_op *he_op) { } @@ -325,13 +299,14 @@ static inline QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, return QDF_STATUS_SUCCESS; } -static inline void wma_vdev_set_he_bss_params(tp_wma_handle wma, - uint8_t vdev_id, struct wma_vdev_start_req *req) +static inline +void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id, + struct vdev_mlme_he_ops_info *he_info) { } static inline void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id, - tpAddBssParams add_bss) + struct bss_params *add_bss) { } @@ -340,11 +315,6 @@ static inline bool wma_is_peer_he_capable(tpAddStaParams params) return false; } -static inline void wma_update_vdev_he_capable(struct wma_vdev_start_req *req, - tpSwitchChannelParams params) -{ -} - static inline void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id, uint32_t value) { diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_if.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_if.h index 7532419452f8c4d0de1a39065d6e1326c717d331..ab36d962fd19a4a81f74507fd8e157860c7c2657 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_if.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_if.h @@ -125,30 +125,21 @@ struct sAniProbeRspStruct { * @assocId: associd * @staType: 0 - Self, 1 other/remote, 2 - bssid * @staMac: MAC Address of STA - * @shortPreambleSupported: is short preamble supported or not * @listenInterval: Listen interval * @wmmEnabled: Support for 11e/WMM * @uAPSD: U-APSD Flags: 1b per AC * @maxSPLen: Max SP Length * @htCapable: 11n HT capable STA - * @greenFieldCapable: 11n Green Field preamble support * @txChannelWidthSet: TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz * @mimoPS: MIMO Power Save - * @rifsMode: RIFS mode: 0 - NA, 1 - Allowed - * @lsigTxopProtection: L-SIG TXOP Protection mechanism - * @us32MaxAmpduDuration: in units of 32 us - * @maxAmpduSize: 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k * @maxAmpduDensity: 3 : 0~7 : 2^(11nAMPDUdensity -4) * @maxAmsduSize: 1 : 3839 bytes, 0 : 7935 bytes - * @fDsssCckMode40Mhz: DSSS CCK supported 40MHz * @fShortGI40Mhz: short GI support for 40Mhz packets * @fShortGI20Mhz: short GI support for 20Mhz packets * @supportedRates: legacy supported rates * @status: QDF status * @staIdx: station index - * @bss_idx: BSSID of BSS to which the station is associated * @updateSta: pdate the existing STA entry, if this flag is set - * @respReqd: A flag to indicate to HAL if the response message is required * @rmfEnabled: Robust Management Frame (RMF) enabled/disabled * @encryptType: The unicast encryption type in the association * @sessionId: PE session id @@ -160,7 +151,6 @@ struct sAniProbeRspStruct { * @vhtTxBFCapable: txbf capable or not * @vhtTxMUBformeeCapable: Bformee capable or not * @enableVhtpAid: enable VHT AID - * @enableVhtGid: enable VHT GID * @enableAmpduPs: AMPDU power save * @enableHtSmps: enable HT SMPS * @htSmpsconfig: HT SMPS config @@ -178,8 +168,6 @@ struct sAniProbeRspStruct { * @peerAtimWindowLength: peer ATIM Window length * @nss: Return the number of spatial streams supported * @stbc_capable: stbc capable - * @max_amsdu_num: Maximum number of MSDUs in a tx aggregate frame - * @mbssid_info: Multiple bssid information * @no_ptk_4_way: Do not need 4-way handshake * * This structure contains parameter required for @@ -193,39 +181,22 @@ typedef struct { * This may or may not be required in production driver. */ uint8_t staType; - uint8_t shortPreambleSupported; tSirMacAddr staMac; uint16_t listenInterval; uint8_t wmmEnabled; uint8_t uAPSD; uint8_t maxSPLen; uint8_t htCapable; - /* 11n Green Field preamble support - * 0 - Not supported, 1 - Supported - * Add it to RA related fields of sta entry in HAL - */ - uint8_t greenFieldCapable; - uint8_t ch_width; - + enum phy_ch_width ch_width; tSirMacHTMIMOPowerSaveState mimoPS; - uint8_t rifsMode; - /* L-SIG TXOP Protection mechanism - * 0 - No Support, 1 - Supported - * SG - there is global field. - */ - uint8_t lsigTxopProtection; - uint8_t us32MaxAmpduDuration; uint8_t maxAmpduSize; uint8_t maxAmpduDensity; - uint8_t maxAmsduSize; - /* 11n Parameters */ /* HT STA should set it to 1 if it is enabled in BSS * HT STA should set it to 0 if AP does not support it. * This indication is sent to HAL and HAL uses this flag * to pickup up appropriate 40Mhz rates. */ - uint8_t fDsssCckMode40Mhz; uint8_t fShortGI40Mhz; uint8_t fShortGI20Mhz; struct supported_rates supportedRates; @@ -235,19 +206,7 @@ typedef struct { */ /* The return status of SIR_HAL_ADD_STA_REQ is reported here */ QDF_STATUS status; - /* Station index; valid only when 'status' field value is - * QDF_STATUS_SUCCESS - */ - uint8_t staIdx; - /* BSSID of BSS to which the station is associated. - * This should be filled back in by HAL, and sent back to LIM as part of - * the response message, so LIM can cache it in the station entry of - * hash table. When station is deleted, LIM will make use of this - * bss_idx to delete BSS from hal tables and from softmac. - */ - uint8_t bss_idx; uint8_t updateSta; - uint8_t respReqd; uint8_t rmfEnabled; uint32_t encryptType; uint8_t sessionId; @@ -255,11 +214,13 @@ typedef struct { uint8_t csaOffloadEnable; uint8_t vhtCapable; uint8_t vhtSupportedRxNss; + uint8_t vht_160mhz_nss; + uint8_t vht_80p80mhz_nss; + uint8_t vht_extended_nss_bw_cap; uint8_t vhtTxBFCapable; uint8_t enable_su_tx_bformer; uint8_t vhtTxMUBformeeCapable; uint8_t enableVhtpAid; - uint8_t enableVhtGid; uint8_t enableAmpduPs; uint8_t enableHtSmps; uint8_t htSmpsconfig; @@ -278,14 +239,13 @@ typedef struct { uint32_t peerAtimWindowLength; uint8_t nonRoamReassoc; uint32_t nss; - struct scan_mbssid_info mbssid_info; #ifdef WLAN_FEATURE_11AX bool he_capable; tDot11fIEhe_cap he_config; tDot11fIEhe_op he_op; + tDot11fIEhe_6ghz_band_cap he_6ghz_band_caps; #endif uint8_t stbc_capable; - uint8_t max_amsdu_num; #ifdef WLAN_SUPPORT_TWT uint8_t twt_requestor; uint8_t twt_responder; @@ -295,7 +255,6 @@ typedef struct { /** * struct tDeleteStaParams - parameters required for del sta request - * @staIdx: station index * @assocId: association index * @status: status * @respReqd: is response required @@ -305,7 +264,6 @@ typedef struct { * @staMac: station mac */ typedef struct { - uint16_t staIdx; uint16_t assocId; QDF_STATUS status; uint8_t respReqd; @@ -325,7 +283,6 @@ typedef struct { * @smesessionId: sme session id * @peerMacAddr: peer mac address * @status: status - * @sessionId: session id * @sendRsp: send response * @macaddr: MAC address of the peer * @@ -335,15 +292,13 @@ typedef struct { * a new key descriptor is created based on the key field. */ typedef struct { - uint16_t staIdx; tAniEdType encType; uint8_t defWEPIdx; tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; uint8_t singleTidRc; - uint8_t smesessionId; + uint8_t vdev_id; struct qdf_mac_addr peer_macaddr; QDF_STATUS status; - uint8_t sessionId; uint8_t sendRsp; struct qdf_mac_addr macaddr; } tSetStaKeyParams, *tpSetStaKeyParams; @@ -352,7 +307,7 @@ typedef struct { * struct sLimMlmSetKeysReq - set key request parameters * @peerMacAddr: peer mac address * @sessionId: PE session id - * @smesessionId: SME session id + * @vdev_id: vdev id * @aid: association id * @edType: Encryption/Decryption type * @numKeys: number of keys @@ -361,7 +316,7 @@ typedef struct { typedef struct sLimMlmSetKeysReq { struct qdf_mac_addr peer_macaddr; uint8_t sessionId; /* Added For BT-AMP Support */ - uint8_t smesessionId; /* Added for drivers based on wmi interface */ + uint8_t vdev_id; /* Added for drivers based on wmi interface */ uint16_t aid; tAniEdType edType; /* Encryption/Decryption type */ uint8_t numKeys; @@ -369,151 +324,78 @@ typedef struct sLimMlmSetKeysReq { } tLimMlmSetKeysReq, *tpLimMlmSetKeysReq; /** - * struct tAddBssParams - parameters required for add bss params + * struct struct bss_params - parameters required for add bss params * @bssId: MAC Address/BSSID - * @self_mac_addr: Self Mac Address - * @bssType: BSS type - * @operMode: AP - 0; STA - 1; * @nwType: network type * @shortSlotTimeSupported: is short slot time supported or not - * @llaCoexist: is 11a coexist or not * @llbCoexist: 11b coexist supported or not - * @llgCoexist: 11g coexist supported or not - * @ht20Coexist: HT20 coexist supported or not - * @fLsigTXOPProtectionFullSupport: TXOP protection supported or not - * @fRIFSMode: RIFS is supported or not * @beaconInterval: beacon interval * @dtimPeriod: DTIM period - * @cfParamSet: CF Param Set - * @rateSet: MAC Rate Set * @htCapable: Enable/Disable HT capabilities - * @obssProtEnabled: Enable/Disable OBSS protection * @rmfEnabled: RMF enabled/disabled - * @htOperMode: HT Operating Mode - * @HT Operating Mode: Dual CTS Protection: 0 - Unused, 1 - Used - * @txChannelWidthSet: TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz - * @currentOperChannel: Current Operating Channel - * @currentExtChannel: Current Extension Channel, if applicable * @staContext: sta context - * @status: status - * @bss_idx: BSS index allocated by HAL * @updateBss: update the existing BSS entry, if this flag is set - * @ssId: Add BSSID info for rxp filter - * @respReqd: send the response message to LIM only when this flag is set - * @sessionId: PE session id - * @txMgmtPower: tx power used for mgmt frames * @maxTxPower: max power to be used after applying the power constraint * @extSetStaKeyParamValid: Ext Bss Config Msg if set * @extSetStaKeyParam: SetStaKeyParams for ext bss msg - * @bHiddenSSIDEn: To Enable Hidden ssid. - * @bProxyProbeRespEn: To Enable Disable FW Proxy Probe Resp - * @halPersona: Persona for the BSS can be STA,AP,GO,CLIENT value * @bSpectrumMgtEnabled: Spectrum Management Capability, 1:Enabled, 0:Disabled. * @vhtCapable: VHT capablity - * @vhtTxChannelWidthSet: VHT tx channel width - * @reassocReq: Set only during roaming reassociation - * @chainMask: chain mask - * @smpsMode: SMPS mode - * @dot11_mode: 802.11 mode + * @ch_width: VHT tx channel width * @he_capable: HE Capability - * @cac_duration_ms: cac duration in milliseconds - * @dfs_regdomain: dfs region * @no_ptk_4_way: Do not need 4-way handshake */ -typedef struct { +struct bss_params { tSirMacAddr bssId; - tSirMacAddr self_mac_addr; - enum bss_type bssType; - uint8_t operMode; tSirNwType nwType; uint8_t shortSlotTimeSupported; - uint8_t llaCoexist; uint8_t llbCoexist; - uint8_t llgCoexist; - uint8_t ht20Coexist; - uint8_t llnNonGFCoexist; - uint8_t fLsigTXOPProtectionFullSupport; - uint8_t fRIFSMode; tSirMacBeaconInterval beaconInterval; uint8_t dtimPeriod; - tSirMacCfParamSet cfParamSet; - tSirMacRateSet rateSet; uint8_t htCapable; - uint8_t obssProtEnabled; uint8_t rmfEnabled; - tSirMacHTOperatingMode htOperMode; - uint8_t dualCTSProtection; - uint8_t txChannelWidthSet; - uint8_t currentOperChannel; tAddStaParams staContext; - QDF_STATUS status; - uint16_t bss_idx; /* HAL should update the existing BSS entry, if this flag is set. * PE will set this flag in case of reassoc, where we want to resue the * the old bssID and still return success. */ uint8_t updateBss; - tSirMacSSid ssId; - uint8_t respReqd; - uint8_t sessionId; - int8_t txMgmtPower; int8_t maxTxPower; uint8_t extSetStaKeyParamValid; tSetStaKeyParams extSetStaKeyParam; - - uint8_t bHiddenSSIDEn; - uint8_t bProxyProbeRespEn; - uint8_t halPersona; - uint8_t bSpectrumMgtEnabled; uint8_t vhtCapable; enum phy_ch_width ch_width; - uint8_t ch_center_freq_seg0; - uint8_t ch_center_freq_seg1; - uint8_t reassocReq; /* Set only during roaming reassociation */ - uint16_t chainMask; - uint16_t smpsMode; - uint8_t dot11_mode; uint8_t nonRoamReassoc; - uint8_t wps_state; - uint8_t nss; - uint8_t nss_2g; - uint8_t nss_5g; - uint16_t beacon_tx_rate; - uint32_t tx_aggregation_size; - uint32_t tx_aggregation_size_be; - uint32_t tx_aggregation_size_bk; - uint32_t tx_aggregation_size_vi; - uint32_t tx_aggregation_size_vo; - uint32_t rx_aggregation_size; #ifdef WLAN_FEATURE_11AX bool he_capable; - tDot11fIEhe_cap he_config; - tDot11fIEhe_op he_op; uint32_t he_sta_obsspd; #endif - uint32_t cac_duration_ms; - uint32_t dfs_regdomain; bool no_ptk_4_way; -} tAddBssParams, *tpAddBssParams; +}; /** - * struct tDeleteBssParams - params required for del bss request - * @bss_idx: BSSID + * struct add_bss_rsp - params required for add bss response + * @vdev_id: vdev_id * @status: QDF status - * @respReqd: response message to LIM only when this flag is set - * @sessionId: PE session id - * @bssid: BSSID mac address - * @smesessionId: sme session id + * @chain_mask: chain mask vdev start resp + * @smps_mode: smps mode in vdev start resp */ -typedef struct { - uint8_t bss_idx; +struct add_bss_rsp { + uint8_t vdev_id; QDF_STATUS status; - uint8_t respReqd; - uint8_t sessionId; - tSirMacAddr bssid; - uint8_t smesessionId; -} tDeleteBssParams, *tpDeleteBssParams; + uint32_t chain_mask; + uint8_t smps_mode; +}; + +/** + * struct struct del_bss_resp - params required for del bss response + * @status: QDF status + * @vdev_id: vdev_id + */ +struct del_bss_resp { + QDF_STATUS status; + uint8_t vdev_id; +}; typedef enum eDelStaReasonCode { HAL_DEL_STA_REASON_CODE_KEEP_ALIVE = 0x1, @@ -535,7 +417,6 @@ typedef enum eSmpsModeValue { /** * struct tDeleteStaContext - params required for delete sta request * @assocId: association id - * @staId: station id * @bssId: mac address * @addr2: mac address * @reasonCode: reason code @@ -545,7 +426,6 @@ typedef struct { bool is_tdls; uint8_t vdev_id; uint16_t assocId; - uint16_t staId; tSirMacAddr bssId; tSirMacAddr addr2; uint16_t reasonCode; @@ -621,25 +501,21 @@ typedef struct sSendProbeRespParams { /** * struct tSetBssKeyParams - BSS key parameters - * @bss_idx: BSSID index * @encType: encryption Type * @numKeys: number of keys * @key: key data * @singleTidRc: 1=Single TID based Replay Count, 0=Per TID based RC - * @smesessionId: sme session id + * @vdev_id: vdev id id * @status: return status of command - * @sessionId: PE session id * @macaddr: MAC address of the peer */ typedef struct { - uint8_t bss_idx; tAniEdType encType; uint8_t numKeys; tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; uint8_t singleTidRc; - uint8_t smesessionId; + uint8_t vdev_id; QDF_STATUS status; - uint8_t sessionId; struct qdf_mac_addr macaddr; } tSetBssKeyParams, *tpSetBssKeyParams; @@ -656,7 +532,7 @@ typedef struct { * @fLsigTXOPProtectionFullSupport: TXOP protection supported or not * @fRIFSMode: RIFS mode * @paramChangeBitmap: change bitmap - * @smeSessionId: SME session id + * @vdev_id: vdev_id */ typedef struct { uint8_t bss_idx; @@ -671,7 +547,7 @@ typedef struct { uint8_t fLsigTXOPProtectionFullSupport; uint8_t fRIFSMode; uint16_t paramChangeBitmap; - uint8_t smeSessionId; + uint8_t vdev_id; uint32_t bss_color; bool bss_color_disabled; } tUpdateBeaconParams, *tpUpdateBeaconParams; @@ -685,7 +561,6 @@ typedef struct { */ typedef struct { uint16_t opMode; - uint16_t staId; uint16_t smesessionId; tSirMacAddr peer_mac; } tUpdateVHTOpMode, *tpUpdateVHTOpMode; @@ -699,7 +574,6 @@ typedef struct { */ typedef struct { uint16_t rxNss; - uint16_t staId; uint16_t smesessionId; tSirMacAddr peer_mac; } tUpdateRxNss, *tpUpdateRxNss; @@ -713,7 +587,6 @@ typedef struct { */ typedef struct { uint32_t membership; - uint16_t staId; uint16_t smesessionId; tSirMacAddr peer_mac; } tUpdateMembership, *tpUpdateMembership; @@ -727,94 +600,13 @@ typedef struct { */ typedef struct { uint32_t userPos; - uint16_t staId; uint16_t smesessionId; tSirMacAddr peer_mac; } tUpdateUserPos, *tpUpdateUserPos; -/** - * struct tSwitchChannelParams - switch channel request parameter - * @channelNumber: channel number - * @localPowerConstraint: local power constraint - * @secondaryChannelOffset: scondary channel offset - * @peSessionId: PE session id - * @txMgmtPower: TX mgmt power - * @maxTxPower: max tx power - * @selfStaMacAddr: self mac address - * @bssId: bssid - * @status: QDF status - * @chainMask: chanin mask - * @smpsMode: SMPS mode - * @isDfsChannel: is DFS channel - * @vhtCapable: VHT capable - * @dot11_mode: 802.11 mode - * @cac_duration_ms: cac duration in milliseconds - * @dfs_regdomain: dfs region - */ -typedef struct { - uint8_t channelNumber; - uint8_t peSessionId; - int8_t txMgmtPower; - int8_t maxTxPower; - tSirMacAddr selfStaMacAddr; - /* the request has power constraints, this should be applied only to - * that session - * VO Wifi comment: BSSID is needed to identify which session issued - * this request. As the request has power constraints, this should be - * applied only to that session - * V IMP: Keep bssId field at the end of this msg. - * It is used to mantain backward compatbility by way of ignoring if - * using new host/old FW or old host/new FW since it is at the end of - * this struct - */ - tSirMacAddr bssId; - QDF_STATUS status; - uint16_t chainMask; - uint16_t smpsMode; - uint8_t isDfsChannel; - uint8_t vhtCapable; - enum phy_ch_width ch_width; - uint8_t ch_center_freq_seg0; - uint8_t ch_center_freq_seg1; - uint8_t dot11_mode; - - uint8_t restart_on_chan_switch; - uint8_t nss; -#ifdef WLAN_FEATURE_11AX - bool he_capable; -#endif - uint32_t cac_duration_ms; - uint32_t dfs_regdomain; - uint16_t reduced_beacon_interval; -} tSwitchChannelParams, *tpSwitchChannelParams; - -typedef void (*tpSetLinkStateCallback)(struct mac_context *mac, void *msgParam, - bool status); - -/** - * struct tLinkStateParams - link state parameters - * @bssid: BSSID - * @self_mac_addr: self mac address - * @state: link state - * @callback: callback function pointer - * @callbackArg: callback argument - * @session: session context - */ -typedef struct sLinkStateParams { - /* SIR_HAL_SET_LINK_STATE */ - tSirMacAddr bssid; - tSirMacAddr self_mac_addr; - tSirLinkState state; - tpSetLinkStateCallback callback; - void *callbackArg; - int ft; - void *session; - bool status; -} tLinkStateParams, *tpLinkStateParams; - /** * struct tEdcaParams - EDCA parameters - * @bss_idx: BSSID index + * @vdev_id: vdev id * @acbe: best effort access category * @acbk: Background access category * @acvi: video access category @@ -822,7 +614,7 @@ typedef struct sLinkStateParams { * @mu_edca_params: flag to indicate MU EDCA */ typedef struct { - uint16_t bss_idx; + uint16_t vdev_id; tSirMacEdcaParamRecord acbe; tSirMacEdcaParamRecord acbk; tSirMacEdcaParamRecord acvi; @@ -832,7 +624,6 @@ typedef struct { /** * struct tSetMIMOPS - MIMO power save related parameters - * @staIdx: station index * @htMIMOPSState: MIMO Power Save State * @status: response status * @fsendRsp: send response flag @@ -840,7 +631,6 @@ typedef struct { * @sessionId: session id */ typedef struct sSet_MIMOPS { - uint16_t staIdx; tSirMacHTMIMOPowerSaveState htMIMOPSState; QDF_STATUS status; uint8_t fsendRsp; @@ -879,60 +669,13 @@ typedef struct sMaxTxPowerPerBandParams { } tMaxTxPowerPerBandParams, *tpMaxTxPowerPerBandParams; /** - * struct add_sta_self_params - Add Sta Self params - * @self_mac_addr: self MAC Address - * @curr_device_mode: operating device mode - * @type: Vdev Type - * @sub_type: Vdev Sub Type - * @session_id: SME Session ID - * @nss_2g: vdev nss in 2.4G - * @nss_5g: vdev nss in 5G + * struct vdev_create_req_param - vdev create request params + * @vdev_id: vdev_id * @status: response status code - * @tx_aggregation_size: Tx aggregation size - * @rx_aggregation_size: Rx aggregation size - * @enable_bcast_probe_rsp: enable broadcast probe response - * @fils_max_chan_guard_time: FILS max channel guard time - * @pkt_err_disconn_th: packet drop threshold - * @tx_aggr_sw_retry_threshold_be: aggr sw retry threshold for be - * @tx_aggr_sw_retry_threshold_bk: aggr sw retry threshold for bk - * @tx_aggr_sw_retry_threshold_vi: aggr sw retry threshold for vi - * @tx_aggr_sw_retry_threshold_vo: aggr sw retry threshold for vo - * @tx_aggr_sw_retry_threshold: aggr sw retry threshold - * @tx_non_aggr_sw_retry_threshold_be: non aggr sw retry threshold for be - * @tx_non_aggr_sw_retry_threshold_bk: non aggr sw retry threshold for bk - * @tx_non_aggr_sw_retry_threshold_vi: non aggr sw retry threshold for vi - * @tx_non_aggr_sw_retry_threshold_vo: non aggr sw retry threshold for vo - * @tx_non_aggr_sw_retry_threshold: non aggr sw retry threshold */ -struct add_sta_self_params { - tSirMacAddr self_mac_addr; - enum QDF_OPMODE curr_device_mode; - uint32_t type; - uint32_t sub_type; - uint8_t session_id; - uint8_t nss_2g; - uint8_t nss_5g; - uint32_t status; - uint32_t tx_aggregation_size; - uint32_t tx_aggregation_size_be; - uint32_t tx_aggregation_size_bk; - uint32_t tx_aggregation_size_vi; - uint32_t tx_aggregation_size_vo; - uint32_t rx_aggregation_size; - bool enable_bcast_probe_rsp; - uint8_t fils_max_chan_guard_time; - uint16_t pkt_err_disconn_th; - uint8_t oce_feature_bitmap; - uint32_t tx_aggr_sw_retry_threshold_be; - uint32_t tx_aggr_sw_retry_threshold_bk; - uint32_t tx_aggr_sw_retry_threshold_vi; - uint32_t tx_aggr_sw_retry_threshold_vo; - uint32_t tx_aggr_sw_retry_threshold; - uint32_t tx_non_aggr_sw_retry_threshold_be; - uint32_t tx_non_aggr_sw_retry_threshold_bk; - uint32_t tx_non_aggr_sw_retry_threshold_vi; - uint32_t tx_non_aggr_sw_retry_threshold_vo; - uint32_t tx_non_aggr_sw_retry_threshold; +struct vdev_create_req_param { + uint32_t vdev_id; + QDF_STATUS status; }; /** @@ -967,15 +710,15 @@ struct set_dtim_params { #define DOT11_VHT_IE 2 /** - * struct del_sta_self_params - Del Sta Self params + * struct del_vdev_params - Del Sta Self params * @session_id: SME Session ID * @status: response status code * @sme_callback: callback to be called from WMA to SME * @sme_ctx: pointer to context provided by SME */ -struct del_sta_self_params { +struct del_vdev_params { tSirMacAddr self_mac_addr; - uint8_t session_id; + uint8_t vdev_id; uint32_t status; csr_session_close_cb sme_callback; void *sme_ctx; @@ -987,8 +730,7 @@ struct del_sta_self_params { * @generate_rsp: generate response to upper layers */ struct del_sta_self_rsp_params { - struct del_sta_self_params *self_sta_param; - uint8_t generate_rsp; + struct del_vdev_params *self_sta_param; }; /** @@ -1003,18 +745,6 @@ struct send_peer_unmap_conf_params { uint16_t *peer_id_list; }; -/** - * struct tHalHiddenSsidVdevRestart - hidden ssid vdev restart params - * @ssidHidden: is hidden ssid or not - * @sessionId: session id - */ -typedef struct tHalHiddenSsidVdevRestart { - uint8_t ssidHidden; - uint8_t sessionId; - uint16_t pe_session_id; -} tHalHiddenSsidVdevRestart, *tpHalHiddenSsidVdevRestart; - - /** * struct tDisableIntraBssFwd - intra bss forward parameters * @sessionId: session id @@ -1045,12 +775,18 @@ typedef struct sStatsExtRequest { * @timeout - time duration for which the bssid is blacklisted * @received_time - boot timestamp at which the firmware event was received * @rssi - rssi value for which the bssid is blacklisted + * @reject_reason: reason to add the BSSID to BLM + * @original_timeout: original timeout sent by the AP + * @source: Source of adding the BSSID to BLM */ struct roam_blacklist_timeout { struct qdf_mac_addr bssid; uint32_t timeout; qdf_time_t received_time; int32_t rssi; + enum blm_reject_ap_reason reject_reason; + uint32_t original_timeout; + enum blm_reject_ap_source source; }; /* diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h index 7cf141f692fc1a85408de5e5404963fca7b27bc2..7943cc4b0adf27d5e41836017c0fa8dae8224160 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,17 +32,10 @@ #define WMA_2_4_GHZ_MAX_FREQ 3000 -/* pdev vdev and peer stats*/ -#define FW_PDEV_STATS_SET 0x1 -#define FW_VDEV_STATS_SET 0x2 -#define FW_PEER_STATS_SET 0x4 -#define FW_RSSI_PER_CHAIN_STATS_SET 0x8 - /*AR9888/AR6320 noise floor approx value * similar to the mentioned the WMA */ #define WMA_TGT_NOISE_FLOOR_DBM (-96) -#define WMA_TGT_MAX_SNR (WMA_TGT_NOISE_FLOOR_DBM * (-1)) #define WMA_INVALID_PER_CHAIN_SNR (0x80) #define WMA_INVALID_PER_CHAIN_RSSI (0xFF) @@ -102,12 +95,14 @@ struct index_data_rate_type { * @ht20_rate: VHT20 supported rate table * @ht40_rate: VHT40 supported rate table * @ht80_rate: VHT80 supported rate table + * @ht160_rate: VHT160 supported rate table */ struct index_vht_data_rate_type { uint8_t mcs_index; uint16_t ht20_rate[2]; uint16_t ht40_rate[2]; uint16_t ht80_rate[2]; + uint16_t ht160_rate[2]; }; #ifdef WLAN_FEATURE_11AX @@ -118,12 +113,14 @@ struct index_vht_data_rate_type { * @supported_he80_rate: he80 rate * @supported_he40_rate: he40 rate * @supported_he20_rate: he20 rate + * @supported_he160_rate: he160 rate */ struct index_he_data_rate_type { uint8_t beacon_rate_index; uint16_t supported_he20_rate[MAX_HE_DCM_INDEX][3]; uint16_t supported_he40_rate[MAX_HE_DCM_INDEX][3]; uint16_t supported_he80_rate[MAX_HE_DCM_INDEX][3]; + uint16_t supported_he160_rate[MAX_HE_DCM_INDEX][3]; }; #endif @@ -389,7 +386,7 @@ QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle, QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, uint8_t chan_count, - uint8_t *chan_list, + uint32_t *chan_freq_list, uint8_t list_type, uint32_t vdev_id); A_UINT32 e_csr_auth_type_to_rsn_authmode(enum csr_akm_type authtype, @@ -410,8 +407,6 @@ QDF_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle, QDF_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle, uint32_t command, uint32_t vdev_id); -void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params); - #ifdef WLAN_FEATURE_ROAM_OFFLOAD void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts); #endif @@ -637,30 +632,66 @@ static inline bool wma_is_roam_synch_in_progress(tp_wma_handle wma, * wma_dev_if.c functions declarations */ -struct cdp_vdev *wma_find_vdev_by_addr(tp_wma_handle wma, uint8_t *addr, - uint8_t *vdev_id); - /** - * wma_find_vdev_by_id() - Returns vdev handle for given vdev id. - * @wma - wma handle - * @vdev_id - vdev ID + * wma_find_vdev_id_by_addr() - find vdev_id from mac address + * @wma: wma handle + * @addr: mac address + * @vdev_id: return vdev_id * - * Return: Returns vdev handle if given vdev id is valid. - * Otherwise returns NULL. + * Return: SUCCESS or FAILURE */ -static inline -struct cdp_vdev *wma_find_vdev_by_id(tp_wma_handle wma, uint8_t vdev_id) -{ - if (vdev_id >= wma->max_bssid) - return NULL; - - return wma->interfaces[vdev_id].handle; -} +QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr, + uint8_t *vdev_id); bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id); #ifdef QCA_IBSS_SUPPORT +/** + * wma_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not + * @wma: wma handle + * @vdev_id: vdev id + * + * Helper function to know whether given vdev id + * is in IBSS mode or not. + * + * Return: True/False + */ bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id); + +/** + * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw. + * @wma: wma handle + * @vdev_id: vdev id + * @peer_num_delta: peer number delta value + * + * Return: none + */ +void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, + uint8_t vdev_id, + int8_t peer_num_delta); + +/** + * wma_set_ibss_pwrsave_params() - set ibss power save parameter to fw + * @wma: wma handle + * @vdev_id: vdev id + * + * Return: 0 for success or error code. + */ +QDF_STATUS +wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id); + +/** + * wma_ibss_peer_info_event_handler() - IBSS peer info event handler + * @handle: wma handle + * @data: event data + * @len: length of data + * + * This function handles IBSS peer info event from FW. + * + * Return: 0 for success or error code + */ +int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, + uint32_t len); #else /** * wma_is_vdev_in_ibss_mode(): dummy function @@ -674,7 +705,66 @@ bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id) { return false; } -#endif + +/** + * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw. + * @wma: wma handle + * @vdev_id: vdev id + * @peer_num_delta: peer number delta value + * + * This function is dummy + * + * Return: none + */ +static inline void +wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, + uint8_t vdev_id, + int8_t peer_num_delta) +{ +} + +/** + * wma_ibss_peer_info_event_handler() - IBSS peer info event handler + * @handle: wma handle + * @data: event data + * @len: length of data + * + * This function is dummy + * + * Return: 0 for success or error code + */ +static inline int +wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, + uint32_t len) +{ + return 0; +} + +/** + * wma_set_ibss_pwrsave_params() - set ibss power save parameter to fw + * @wma: wma handle + * @vdev_id: vdev id + * + * This function is dummy + * + * Return: 0 for success or error code. + */ +static inline QDF_STATUS +wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* QCA_IBSS_SUPPORT */ + +/** + * wma_get_vdev_bssid() - Get BSSID from mlme_obj + * @vdev - pointer to vdev + * + * This API is used to get BSSID stored in vdev mlme object. + * + * Return: pointer to bssid on success else NULL. + */ +uint8_t *wma_get_vdev_bssid(struct wlan_objmgr_vdev *vdev); /** * wma_find_bssid_by_vdev_id() - Get the BSS ID corresponding to the vdev ID @@ -690,88 +780,61 @@ static inline uint8_t *wma_find_bssid_by_vdev_id(tp_wma_handle wma, if (vdev_id >= wma->max_bssid) return NULL; - return wma->interfaces[vdev_id].bssid; + return wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); } -struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid, - uint8_t *vdev_id); +/** + * wma_find_vdev_id_by_bssid() - Get the corresponding vdev_id from BSSID + * @wma - wma handle + * @bssid - bssid address + * @vdev_id - vdev ID + * + * Return: SUCCESS or FAILURE. + */ +QDF_STATUS wma_find_vdev_id_by_bssid(tp_wma_handle wma, uint8_t *bssid, + uint8_t *vdev_id); +/** + * wma_vdev_detach() - send vdev delete command to fw + * @wma_handle: wma handle + * @pdel_vdev_req_param: del vdev params + * + * Return: QDF status + */ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, - struct del_sta_self_params *pdel_sta_self_req_param, - uint8_t generateRsp); - -int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len); + struct del_vdev_params *pdel_vdev_req_param); QDF_STATUS wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id, uint32_t param_id, uint32_t param_value); -QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, - uint8_t vdev_id, void *peer, - bool roam_synch_in_progress); +QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, + uint8_t vdev_id, bool no_fw_peer_delete); QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma, struct send_peer_unmap_conf_params *msg); -QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, - struct cdp_vdev *vdev, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - uint32_t peer_type, uint8_t vdev_id, - bool roam_synch_in_progress); +QDF_STATUS wma_create_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint32_t peer_type, uint8_t vdev_id, + bool roam_synch_in_progress); /** * wma_send_del_bss_response() - send delete bss resp * @wma: wma handle - * @req: target request + * @resp: pointer to del bss response * * Return: none */ -void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req); - -/** - * wma_send_set_link_response() - send set link response - * @wma: wma handle - * @req: target request - * - * Return: none - */ -void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req); +void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp); /** * __wma_handle_vdev_stop_rsp() - vdev stop response handler - * @handle: wma handle - * @cmd_param_info: event buffer - * @len: buffer length + * @resp_event: pointer to response received * * Return: QDF_STATUS_SUCCESS for success or QDF_ERROR code */ QDF_STATUS -__wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event); - -/** - * wma_vdev_stop_resp_handler() - vdev stop response handler - * @handle: wma handle - * @cmd_param_info: event buffer - * @len: buffer length - * - * Return: 0 for success or error code - */ -int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len); - -struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, - struct add_sta_self_params *self_sta_req, - uint8_t generateRsp); - -QDF_STATUS wma_vdev_start(tp_wma_handle wma, struct wma_vdev_start_req *req, - bool isRestart); - -void wma_vdev_resp_timer(void *data); - -struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, - uint8_t vdev_id, - uint32_t msg_type, uint8_t type, - void *params, uint32_t timeout); +__wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event); void wma_hold_req_timer(void *data); struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma, @@ -779,36 +842,108 @@ struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma, uint8_t type, void *params, uint32_t timeout); -void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id, - uint8_t type); - -void wma_add_bss(tp_wma_handle wma, tpAddBssParams params); +/** + * wma_add_bss() - Add BSS request to fw as per opmode + * @wma: wma handle + * @params: add bss params + * + * Return: none + */ +void wma_add_bss(tp_wma_handle wma, struct bss_params *params); +/** + * wma_add_sta() - process add sta request as per opmode + * @wma: wma handle + * @add_Sta: add sta params + * + * Return: none + */ void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta); +/** + * wma_delete_sta() - process del sta request as per opmode + * @wma: wma handle + * @del_sta: delete sta params + * + * Return: none + */ void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta); -void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params); +/** + * wma_delete_bss() - process delete bss request from upper layer + * @wma: wma handle + * @vdev_id: vdev id + * + * Return: none + */ +void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id); int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type); +/** + * wma_set_vdev_intrabss_fwd() - set intra_fwd value to wni_in. + * @wma_handle: wma handle + * @pdis_intra_fwd: Pointer to DisableIntraBssFwd struct + * + * Return: none + */ void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle, tpDisableIntraBssFwd pdis_intra_fwd); -void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params); +/** + * wma_delete_bss_ho_fail() - process delete bss request for handoff failure + * @wma: wma handle + * @vdev_id: vdev id + * + * Delete BSS in case of ROAM_HO_FAIL processing is handled separately in + * this routine. It needs to be done without sending any commands to firmware + * because firmware has already stopped and deleted peer and vdev is down. + * Relevant logic is aggregated from other routines. It changes the host + * data structures without sending VDEV_STOP, PEER_FLUSH_TIDS, PEER_DELETE + * and VDEV_DOWN commands to firmware. + * + * Return: none + */ +void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id); uint32_t wma_get_bcn_rate_code(uint16_t rate); /* * wma_mgmt.c functions declarations */ -#ifdef CONFIG_WMI_BCN_OFFLOAD +#ifdef WLAN_WMI_BCN int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len); #endif +/** + * wma_peer_sta_kickout_event_handler() - kickout event handler + * @handle: wma handle + * @event: event data + * @len: data length + * + * Kickout event is received from firmware on observing beacon miss + * It handles kickout event for different modes and indicate to + * upper layers. + * + * Return: 0 for success or error code + */ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, uint32_t len); +/** + * wma_unified_bcntx_status_event_handler() - beacon tx status event handler + * @handle: wma handle + * @cmd_param_info: event data + * @len: data length + * + * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware. + * This event is generated by FW when the beacon transmission is offloaded + * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID + * The FW generates this event when the first successful beacon transmission + * after template update + * + * Return: 0 for success or error code + */ int wma_unified_bcntx_status_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); @@ -821,9 +956,16 @@ void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id, uint8_t *hostv4addr, uint8_t *destv4addr, uint8_t *destmac); -int wma_vdev_install_key_complete_event_handler(void *handle, - uint8_t *event, - uint32_t len); +/** + * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object + * @wma: wma handle + * @mac_addr: mac addr of peer + * @phymode: phymode value to set + * + * Return: None + */ +void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, uint8_t *mac_addr, + enum wlan_phymode phymode); QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, tSirNwType nw_type, @@ -839,50 +981,35 @@ void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id, void wma_process_update_beacon_params(tp_wma_handle wma, tUpdateBeaconParams *bcn_params); -void wma_update_rts_params(tp_wma_handle wma, uint32_t value); - -void wma_update_frag_params(tp_wma_handle wma, uint32_t value); - -void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, - uint8_t vdev_id, - int8_t peer_num_delta); - -#ifdef CRYPTO_SET_KEY_CONVERGED -static inline void wma_set_stakey(tp_wma_handle wma_handle, - tpSetStaKeyParams key_info) -{ -} - -static inline void wma_set_bsskey(tp_wma_handle wma_handle, - tpSetBssKeyParams key_info) -{ -} -#else /** - * wma_set_stakey() - set encryption key - * @wma_handle: wma handle - * @key_info: station key info - * - * This function sets encryption key for WEP/WPA/WPA2 - * encryption mode in firmware and send response to upper layer. + * wma_update_rts_params() - update cfg parameters to target + * @wma: wma handle + * @value: rts_threshold * * Return: none */ -void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info); +void wma_update_rts_params(tp_wma_handle wma, uint32_t value); /** - * wma_set_bsskey() - set encryption key to fw. - * @wma_handle: wma handle - * @key_info: key info + * wma_update_frag_params() - update cfg parameters to target + * @wma: wma handle + * @value: frag_threshold * * Return: none */ -void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info); -#endif +void wma_update_frag_params(tp_wma_handle wma, uint32_t value); QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle, tEdcaParams *edca_params); +/** + * wma_tbttoffset_update_event_handler() - tbtt offset update handler + * @handle: wma handle + * @event: event buffer + * @len: data length + * + * Return: 0 for success or error code + */ int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event, uint32_t len); @@ -918,9 +1045,6 @@ void wma_process_update_membership(tp_wma_handle wma_handle, void wma_process_update_userpos(tp_wma_handle wma_handle, tUpdateUserPos *userpos); -void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle, - tHalHiddenSsidVdevRestart *pReq); - /* * wma_power.c functions declarations */ @@ -937,9 +1061,6 @@ QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle, uint32_t vdev_id, uint32_t param, uint32_t value); -QDF_STATUS -wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id); - QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id, uint8_t *peer_addr, uint8_t uapsd_value, uint8_t max_sp); @@ -965,6 +1086,13 @@ void wma_disable_sta_ps_mode(tpDisablePsParams ps_req); */ void wma_send_max_tx_pwrlmt(WMA_HANDLE handle, uint8_t vdev_id); +/** + * wma_enable_uapsd_mode() - enable uapsd mode in fw + * @wma: wma handle + * @ps_req: power save request + * + * Return: none + */ void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req); void wma_disable_uapsd_mode(tp_wma_handle wma, tpDisableUapsdParams ps_req); @@ -997,9 +1125,40 @@ QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id, /* * wma_data.c functions declarations */ - +/** + * wma_set_bss_rate_flags() - set rate flags based on BSS capability + * @wma: pointer to wma handle + * @vdev_id: vdev id + * @add_bss: pointer to bss params + * + * Return: none + */ void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id, - tpAddBssParams add_bss); + struct bss_params *add_bss); + +/** + * wma_get_vht_rate_flags() - Return the VHT rate flags corresponding to the BW + * @ch_width: BW for which rate flags is required + * + * Return: Rate flags corresponding to ch_width + */ +enum tx_rate_info wma_get_vht_rate_flags(enum phy_ch_width ch_width); + +/** + * wma_get_ht_rate_flags() - Return the HT rate flags corresponding to the BW + * @ch_width: BW for which rate flags is required + * + * Return: Rate flags corresponding to ch_width + */ +enum tx_rate_info wma_get_ht_rate_flags(enum phy_ch_width ch_width); + +/** + * wma_get_he_rate_flags() - Return the HE rate flags corresponding to the BW + * @ch_width: BW for which rate flags is required + * + * Return: Rate flags corresponding to ch_width + */ +enum tx_rate_info wma_get_he_rate_flags(enum phy_ch_width ch_width); int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params); @@ -1028,8 +1187,16 @@ QDF_STATUS wma_set_mcc_channel_time_quota uint32_t adapter_1_chan_number, uint32_t adapter_1_quota, uint32_t adapter_2_chan_number); -void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params); - +/** + * wma_process_rate_update_indate() - rate update indication + * @wma: wma handle + * @pRateUpdateParams: Rate update params + * + * This function update rate & short GI interval to fw based on params + * send by SME. + * + * Return: QDF status + */ QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma, tSirRateUpdateInd * pRateUpdateParams); @@ -1041,6 +1208,17 @@ QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle); #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \ defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT) +/** + * wma_mcc_vdev_tx_pause_evt_handler() - pause event handler + * @handle: wma handle + * @event: event buffer + * @len: data length + * + * This function handle pause event from fw and pause/unpause + * vdev. + * + * Return: 0 for success or error code. + */ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, uint32_t len); #endif @@ -1069,9 +1247,6 @@ QDF_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle, int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event, uint32_t len); -int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, - uint32_t len); - int wma_fast_tx_fail_event_handler(void *handle, uint8_t *data, uint32_t len); @@ -1098,12 +1273,26 @@ int wma_smps_mode_to_force_mode_param(uint8_t smps_mode); #ifdef WLAN_FEATURE_LINK_LAYER_STATS void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle); +/** + * wma_process_ll_stats_clear_req() - clear link layer stats + * @wma: wma handle + * @clearReq: ll stats clear request command params + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ QDF_STATUS wma_process_ll_stats_clear_req (tp_wma_handle wma, const tpSirLLStatsClearReq clearReq); QDF_STATUS wma_process_ll_stats_set_req (tp_wma_handle wma, const tpSirLLStatsSetReq setReq); +/** + * wma_process_ll_stats_get_req() - link layer stats get request + * @wma:wma handle + * @getReq:ll stats get request command params + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ QDF_STATUS wma_process_ll_stats_get_req (tp_wma_handle wma, const tpSirLLStatsGetReq getReq); @@ -1117,6 +1306,14 @@ void wma_config_stats_ext_threshold(tp_wma_handle wma, void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus, uint8_t link_status); +/** + * wma_link_status_event_handler() - link status event handler + * @handle: wma handle + * @cmd_param_info: data from event + * @len: length + * + * Return: 0 for success or error code + */ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); @@ -1143,9 +1340,21 @@ QDF_STATUS wma_wni_cfg_dnld(tp_wma_handle wma_handle); int wma_unified_debug_print_event_handler(void *handle, uint8_t *datap, uint32_t len); -WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type, - uint8_t is_ht, uint8_t ch_width, - uint8_t is_vht, bool is_he); +/** + * wma_peer_phymode() - get phymode + * @nw_type: nw type + * @sta_type: sta type + * @is_ht: is ht supported + * @ch_width: supported channel width + * @is_vht: is vht supported + * @is_he: is HE supported + * + * Return: host phymode + */ +enum wlan_phymode +wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type, + uint8_t is_ht, uint8_t ch_width, + uint8_t is_vht, bool is_he); int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle, uint8_t vdev_id, uint32_t value); @@ -1153,13 +1362,6 @@ int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle, int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle, uint8_t vdev_id, uint32_t value); -#ifdef QCA_SUPPORT_CP_STATS -static inline void wma_get_stats_req(WMA_HANDLE handle, - struct sAniGetPEStatsReq *get_stats_param) {} -#else -void wma_get_stats_req(WMA_HANDLE handle, - struct sAniGetPEStatsReq *get_stats_param); -#endif /* * wma_features.c functions declarations */ @@ -1179,9 +1381,6 @@ QDF_STATUS wma_sar_register_event_handlers(WMA_HANDLE handle); void wma_process_link_status_req(tp_wma_handle wma, tAniGetLinkStatus *pGetLinkStatus); -QDF_STATUS wma_get_peer_info(WMA_HANDLE handle, - struct sir_peer_info_req *peer_info_req); - /** * wma_get_peer_info_ext() - get peer info * @handle: wma interface @@ -1444,8 +1643,6 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, struct vdev_ie_info *ie_info); int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); -int wma_vdev_delete_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len); int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); @@ -1543,20 +1740,6 @@ void wma_acquire_wakelock(qdf_wake_lock_t *wl, uint32_t msec); */ void wma_release_wakelock(qdf_wake_lock_t *wl); -/** - * wma_send_vdev_start_to_fw() - send the vdev start command to firmware - * @wma: a reference to the global WMA handle - * @params: the vdev start params to send to firmware - * - * Consumers should call wma_release_wakelock() upon receipt of the vdev start - * response from firmware to avoid power penalties. Alternatively, calling the - * matching vdev_up or vdev_down APIs will also release this lock. - * - * Return: QDF_STATUS - */ -QDF_STATUS -wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params); - /** * wma_send_vdev_stop_to_fw() - send the vdev stop command to firmware * @wma: a reference to the global WMA handle @@ -1571,20 +1754,6 @@ QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id); int wma_get_arp_stats_handler(void *handle, uint8_t *data, uint32_t data_len); -/** - * wma_send_vdev_up_to_fw() - send the vdev up command to firmware - * @wma: a reference to the global WMA handle - * @params: the vdev up params to send to firmware - * @bssid: the BssId to send to firmware - * - * This also releases the vdev start wakelock. - * - * Return: QDF_STATUS - */ -QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, - struct vdev_up_params *params, - uint8_t bssid[QDF_MAC_ADDR_SIZE]); - /** * wma_send_vdev_down_to_fw() - send the vdev down command to firmware * @wma: a reference to the global WMA handle @@ -1746,6 +1915,7 @@ static inline int wma_twt_disable_comp_event_handler(void *handle, return 0; } #endif + /** * wma_get_roam_scan_stats() - Get roam scan stats request * @handle: wma handle @@ -1756,18 +1926,6 @@ static inline int wma_twt_disable_comp_event_handler(void *handle, QDF_STATUS wma_get_roam_scan_stats(WMA_HANDLE handle, struct sir_roam_scan_stats *req); -/** - * wma_remove_peer_on_add_bss_failure() - remove the CDP peers in case of - * ADD BSS request failed - * @add_bss_params: Pointer to the Add BSS request params - * - * This API deletes the CDP peer created during ADD BSS in case of ADD BSS - * request sent to the FW fails. - * - * Return: None; - */ -void wma_remove_peer_on_add_bss_failure(tpAddBssParams add_bss_params); - /** * wma_roam_scan_stats_event_handler() - roam scan stats event handler * @handle: wma handle @@ -1782,13 +1940,13 @@ int wma_roam_scan_stats_event_handler(void *handle, uint8_t *event, /** * wma_send_vdev_down() - send del bss req to firmware * @wma: wma handle. - * @vdev_id: vdev ID of device for which MCC has to be checked + * @req: pointer to del bss response * * This function sends del bss resp to upper layer * * Return: none */ -void wma_send_vdev_down(tp_wma_handle wma, struct wma_target_req *req); +void wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *req); /** * wma_cold_boot_cal_event_handler() - Cold boot cal event handler @@ -1822,4 +1980,18 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len); */ QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma_handle, struct roam_triggers *triggers); + +/** + * wma_get_ani_level_evt_handler - event handler to fetch ani level + * @handle: the wma handle + * @event_buf: buffer with event + * @len: buffer length + * + * This function receives ani level from firmware and passes the event + * to upper layer + * + * Return: 0 on success + */ +int wma_get_ani_level_evt_handler(void *handle, uint8_t *event_buf, + uint32_t len); #endif diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_tgt_cfg.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_tgt_cfg.h index 9cab66be5dab44f19c3ceb0b2104a8a066415fef..cc809cfb4e9173c3230043ace33768b297b529eb 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_tgt_cfg.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_tgt_cfg.h @@ -157,7 +157,7 @@ struct board_info { * struct wma_tgt_cfg - target config * @target_fw_version: target fw version * @target_fw_vers_ext: target fw extended sub version - * @band_cap: band capability + * @band_cap: band capability bitmap * @reg_domain: reg domain * @eeprom_rd_ext: eeprom rd ext * @hw_macaddr: hw mcast addr @@ -177,11 +177,12 @@ struct board_info { * @obss_color_collision_offloaded: obss color collision offloaded to firmware * @sar_version: Version of SAR supported by firmware * @bcast_twt_support: braodcast twt support + * @restricted_80p80_bw_supp: Restricted 80+80MHz(165MHz BW) support */ struct wma_tgt_cfg { uint32_t target_fw_version; uint32_t target_fw_vers_ext; - uint8_t band_cap; + uint32_t band_cap; uint32_t reg_domain; uint32_t eeprom_rd_ext; struct qdf_mac_addr hw_macaddr; @@ -217,5 +218,6 @@ struct wma_tgt_cfg { enum sar_version sar_version; struct nan_tgt_caps nan_caps; bool bcast_twt_support; + bool restricted_80p80_bw_supp; }; #endif /* WMA_TGT_CFG_H */ diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma_types.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma_types.h index 38f7cfc0b6238052a8ed89bae858e5e4bb9a1a99..f695c39674fdad9c5f49b0e729c8116e0f46ee2a 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma_types.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma_types.h @@ -57,8 +57,8 @@ #define WMA_GET_RX_UNKNOWN_UCAST(pRxMeta) 0 -#define WMA_GET_RX_CH(pRxMeta) \ - (((t_packetmeta *)pRxMeta)->channel) +#define WMA_GET_RX_FREQ(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->frequency) #define WMA_GET_RX_FT_DONE(pRxMeta) 0 @@ -116,11 +116,9 @@ #define WMA_ADD_STA_REQ SIR_HAL_ADD_STA_REQ #define WMA_ADD_STA_RSP SIR_HAL_ADD_STA_RSP -#define WMA_ADD_STA_SELF_RSP SIR_HAL_ADD_STA_SELF_RSP #define WMA_DELETE_STA_REQ SIR_HAL_DELETE_STA_REQ #define WMA_DELETE_STA_RSP SIR_HAL_DELETE_STA_RSP #define WMA_ADD_BSS_REQ SIR_HAL_ADD_BSS_REQ -#define WMA_ADD_BSS_RSP SIR_HAL_ADD_BSS_RSP #define WMA_DELETE_BSS_REQ SIR_HAL_DELETE_BSS_REQ #define WMA_DELETE_BSS_HO_FAIL_REQ SIR_HAL_DELETE_BSS_HO_FAIL_REQ #define WMA_DELETE_BSS_RSP SIR_HAL_DELETE_BSS_RSP @@ -131,9 +129,7 @@ #define WMA_ROAM_BLACLIST_MSG SIR_HAL_ROAM_BLACKLIST_MSG #define WMA_SEND_PEER_UNMAP_CONF SIR_HAL_SEND_PEER_UNMAP_CONF -#define WMA_SET_BSSKEY_REQ SIR_HAL_SET_BSSKEY_REQ #define WMA_SET_BSSKEY_RSP SIR_HAL_SET_BSSKEY_RSP -#define WMA_SET_STAKEY_REQ SIR_HAL_SET_STAKEY_REQ #define WMA_SET_STAKEY_RSP SIR_HAL_SET_STAKEY_RSP #define WMA_UPDATE_EDCA_PROFILE_IND SIR_HAL_UPDATE_EDCA_PROFILE_IND @@ -152,8 +148,6 @@ #define WMA_IBSS_STA_ADD SIR_HAL_IBSS_STA_ADD #define WMA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND #define WMA_SET_LINK_STATE SIR_HAL_SET_LINK_STATE -#define WMA_SET_LINK_STATE_RSP SIR_HAL_SET_LINK_STATE_RSP -#define WMA_SET_STA_BCASTKEY_REQ SIR_HAL_SET_STA_BCASTKEY_REQ #define WMA_SET_STA_BCASTKEY_RSP SIR_HAL_SET_STA_BCASTKEY_RSP #define WMA_ADD_TS_RSP SIR_HAL_ADD_TS_RSP #define WMA_DPU_MIC_ERROR SIR_HAL_DPU_MIC_ERROR @@ -186,9 +180,6 @@ #define WMA_ENABLE_UAPSD_REQ SIR_HAL_ENABLE_UAPSD_REQ #define WMA_DISABLE_UAPSD_REQ SIR_HAL_DISABLE_UAPSD_REQ -/* / PE <-> HAL statistics messages */ -#define WMA_GET_STATISTICS_REQ SIR_HAL_GET_STATISTICS_REQ -#define WMA_GET_STATISTICS_RSP SIR_HAL_GET_STATISTICS_RSP #define WMA_SET_KEY_DONE SIR_HAL_SET_KEY_DONE /* / PE <-> HAL BTC messages */ @@ -211,8 +202,6 @@ #ifdef WLAN_NS_OFFLOAD #define WMA_SET_NS_OFFLOAD SIR_HAL_SET_NS_OFFLOAD #endif /* WLAN_NS_OFFLOAD */ -#define WMA_ADD_STA_SELF_REQ SIR_HAL_ADD_STA_SELF_REQ -#define WMA_DEL_STA_SELF_REQ SIR_HAL_DEL_STA_SELF_REQ #ifdef FEATURE_WLAN_TDLS #define WMA_SET_TDLS_LINK_ESTABLISH_REQ SIR_HAL_TDLS_LINK_ESTABLISH_REQ @@ -254,8 +243,6 @@ #define WMA_TX_FAIL_MONITOR_IND SIR_HAL_TX_FAIL_MONITOR_IND -#define WMA_HIDDEN_SSID_VDEV_RESTART SIR_HAL_HIDE_SSID_VDEV_RESTART - #ifdef WLAN_FEATURE_GTK_OFFLOAD #define WMA_GTK_OFFLOAD_REQ SIR_HAL_GTK_OFFLOAD_REQ #define WMA_GTK_OFFLOAD_GETINFO_REQ SIR_HAL_GTK_OFFLOAD_GETINFO_REQ @@ -334,7 +321,6 @@ #define WMA_DISASSOC_TX_COMP SIR_HAL_DISASSOC_TX_COMP #define WMA_DEAUTH_TX_COMP SIR_HAL_DEAUTH_TX_COMP -#define WMA_GET_PEER_INFO SIR_HAL_GET_PEER_INFO #define WMA_GET_PEER_INFO_EXT SIR_HAL_GET_PEER_INFO_EXT #define WMA_GET_ISOLATION SIR_HAL_GET_ISOLATION @@ -390,9 +376,6 @@ #define WMA_LED_FLASHING_REQ SIR_HAL_LED_FLASHING_REQ #endif -/* Message posted by wmi when wmi event is received from FW */ -#define WMA_PROCESS_FW_EVENT SIR_HAL_PROCESS_FW_EVENT - #ifdef FEATURE_AP_MCC_CH_AVOIDANCE #define WMA_UPDATE_Q2Q_IE_IND SIR_HAL_UPDATE_Q2Q_IE_IND #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ @@ -466,6 +449,8 @@ #define WMA_ROAM_INIT_PARAM SIR_HAL_INIT_ROAM_OFFLOAD_PARAM +#define WMA_DATA_STALL_TRIGGER 6 + /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 @@ -646,6 +631,17 @@ QDF_STATUS u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb); QDF_STATUS wma_set_idle_ps_config(void *wma_ptr, uint32_t idle_ps); QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req); +/** + * wma_get_rx_retry_cnt() - API to get rx retry count from data path + * @mac: pointer to mac context + * @vdev_id: vdev id + * @mac_addr: mac address of the remote station + * + * Return: none + */ +void wma_get_rx_retry_cnt(struct mac_context *mac, uint8_t vdev_id, + uint8_t *mac_addr); + /** * wma_set_wlm_latency_level() - set latency level to FW * @wma_ptr: wma handle @@ -660,7 +656,14 @@ QDF_STATUS wma_ds_peek_rx_packet_info (cds_pkt_t *vosDataBuff, void **ppRxHeader, bool bSwap); - +/** + * wma_tx_abort() - abort tx + * @vdev_id: vdev id + * + * In case of deauth host abort transmitting packet. + * + * Return: none + */ void wma_tx_abort(uint8_t vdev_id); /** @@ -672,10 +675,13 @@ void wma_tx_abort(uint8_t vdev_id); * @txDir: tx diection * @tid: TID * @tx_frm_download_comp_cb: tx download callback handler + * @pData: tx packet * @tx_frm_ota_comp_cb: OTA complition handler * @tx_flag: tx flag * @vdev_id: vdev id - * @tdlsFlag: tdls flag + * @tdls_flag: tdls flag + * @channel_freq: channel frequency + * @rid: rate id * * This function sends the frame corresponding to the * given vdev id. @@ -688,7 +694,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, wma_tx_dwnld_comp_callback tx_frm_download_comp_cb, void *pData, wma_tx_ota_comp_callback tx_frm_ota_comp_cb, - uint8_t tx_flag, uint8_t vdev_id, bool tdlsFlag, + uint8_t tx_flag, uint8_t vdev_id, bool tdls_flag, uint16_t channel_freq, enum rateid rid); /** diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c index a608b6a97301f85a13f93601375d4960168584de..21e94a15af4ba3b70761172d567e6cf5737fdd37 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -80,7 +79,6 @@ #include #include #include -#include "wlan_pkt_capture_ucfg_api.h" struct wma_search_rate { int32_t rate; @@ -557,8 +555,7 @@ static QDF_STATUS wma_fill_vht80_mcast_rate(uint32_t shortgi, */ static QDF_STATUS wma_fill_ht_mcast_rate(uint32_t shortgi, uint32_t chwidth, int32_t mbpsx10_rate, - uint8_t nss, WMI_HOST_WLAN_PHY_MODE chanmode, - uint8_t *rate, + uint8_t nss, uint8_t *rate, int32_t *streaming_rate) { int32_t ret = 0; @@ -592,7 +589,6 @@ static QDF_STATUS wma_fill_ht_mcast_rate(uint32_t shortgi, static QDF_STATUS wma_fill_vht_mcast_rate(uint32_t shortgi, uint32_t chwidth, int32_t mbpsx10_rate, uint8_t nss, - WMI_HOST_WLAN_PHY_MODE chanmode, uint8_t *rate, int32_t *streaming_rate) { @@ -628,8 +624,7 @@ static QDF_STATUS wma_fill_vht_mcast_rate(uint32_t shortgi, * Return: QDF status */ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, - WMI_HOST_WLAN_PHY_MODE chanmode, A_UINT32 mhz, - int32_t mbpsx10_rate, uint8_t nss, + A_UINT32 mhz, int32_t mbpsx10_rate, uint8_t nss, uint8_t *rate) { int32_t ret = 0; @@ -641,8 +636,8 @@ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, * (3) 540 < mbpsx10_rate <= 2000: use 1x1 HT/VHT * (4) 2000 < mbpsx10_rate: use 2x2 HT/VHT */ - WMA_LOGE("%s: Input: nss = %d, chanmode = %d, mbpsx10 = 0x%x, chwidth = %d, shortgi = %d", - __func__, nss, chanmode, mbpsx10_rate, chwidth, shortgi); + WMA_LOGE("%s: Input: nss = %d, mbpsx10 = 0x%x, chwidth = %d, shortgi = %d", + __func__, nss, mbpsx10_rate, chwidth, shortgi); if ((mbpsx10_rate & 0x40000000) && nss > 0) { /* bit 30 indicates user inputed nss, * bit 28 and 29 used to encode nss @@ -672,7 +667,7 @@ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, int32_t stream_rate = 0; ret = wma_fill_ht_mcast_rate(shortgi, chwidth, mbpsx10_rate, - nss, chanmode, &rate_ht, + nss, &rate_ht, &stream_rate_ht); if (ret != QDF_STATUS_SUCCESS) stream_rate_ht = 0; @@ -684,7 +679,7 @@ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, } /* capable doing 11AC mcast so that search vht tables */ ret = wma_fill_vht_mcast_rate(shortgi, chwidth, mbpsx10_rate, - nss, chanmode, &rate_vht, + nss, &rate_vht, &stream_rate_vht); if (ret != QDF_STATUS_SUCCESS) { if (stream_rate_ht != 0) @@ -716,8 +711,8 @@ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, } } ht_vht_done: - WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, freq = %d", - __func__, nss, chanmode, mhz); + WMA_LOGE("%s: NSS = %d, freq = %d", + __func__, nss, mhz); WMA_LOGD(" %s: input_rate = %d, chwidth = %d rate = 0x%x, streaming_rate = %d", __func__, mbpsx10_rate, chwidth, *rate, stream_rate); } else { @@ -727,13 +722,12 @@ static QDF_STATUS wma_encode_mc_rate(uint32_t shortgi, uint32_t chwidth, else *rate = 0xFF; - WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, input_rate = %d, rate = 0x%x", - __func__, nss, chanmode, mbpsx10_rate, *rate); + WMA_LOGE("%s: NSS = %d, input_rate = %d, rate = 0x%x", + __func__, nss, mbpsx10_rate, *rate); } return ret; } -#ifdef QCA_SUPPORT_CP_STATS /** * wma_cp_stats_set_rate_flag() - set rate flags within cp_stats priv object * @wma: wma handle @@ -746,6 +740,8 @@ static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id) struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_psoc *psoc = wma->psoc; struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + uint32_t rate_flag; + QDF_STATUS status; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_LEGACY_WMA_ID); @@ -755,93 +751,142 @@ static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id) return; } - ucfg_mc_cp_stats_set_rate_flags(vdev, iface->rate_flags); + status = wma_get_vdev_rate_flag(iface->vdev, &rate_flag); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s, vdev not found for id: %d", __func__, + vdev_id); + return; + } + ucfg_mc_cp_stats_set_rate_flags(vdev, rate_flag); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); } -#else -static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id) {} -#endif #ifdef WLAN_FEATURE_11AX /** * wma_set_bss_rate_flags_he() - set rate flags based on BSS capability - * @iface: txrx_node ctx + * @rate_flags: rate_flags pointer * @add_bss: add_bss params * * Return: QDF_STATUS */ -static QDF_STATUS wma_set_bss_rate_flags_he(struct wma_txrx_node *iface, - tpAddBssParams add_bss) +static QDF_STATUS wma_set_bss_rate_flags_he(enum tx_rate_info *rate_flags, + struct bss_params *add_bss) { if (!add_bss->he_capable) return QDF_STATUS_E_NOSUPPORT; - /*extend TX_RATE_HE160 in future*/ - if (add_bss->ch_width == CH_WIDTH_160MHZ || - add_bss->ch_width == CH_WIDTH_80P80MHZ || - add_bss->ch_width == CH_WIDTH_80MHZ) - iface->rate_flags |= TX_RATE_HE80; - - else if (add_bss->ch_width) - iface->rate_flags |= TX_RATE_HE40; - else - iface->rate_flags |= TX_RATE_HE20; + *rate_flags |= wma_get_he_rate_flags(add_bss->ch_width); - wma_debug("he_capable %d", add_bss->he_capable); + wma_debug("he_capable %d rate_flags 0x%x", add_bss->he_capable, + *rate_flags); return QDF_STATUS_SUCCESS; } + +static bool wma_get_bss_he_capable(struct bss_params *add_bss) +{ + return add_bss->he_capable; +} #else -static QDF_STATUS wma_set_bss_rate_flags_he(struct wma_txrx_node *iface, - tpAddBssParams add_bss) +static QDF_STATUS wma_set_bss_rate_flags_he(enum tx_rate_info *rate_flags, + struct bss_params *add_bss) { return QDF_STATUS_E_NOSUPPORT; } + +static bool wma_get_bss_he_capable(struct bss_params *add_bss) +{ + return false; +} #endif -/** - * wma_set_bss_rate_flags() - 11ax set rate flags based on BSS capability - * @iface: txrx_node ctx - * @add_bss: add_bss params - * - * Return: none - */ + +enum tx_rate_info wma_get_vht_rate_flags(enum phy_ch_width ch_width) +{ + enum tx_rate_info rate_flags = 0; + + if (ch_width == CH_WIDTH_80P80MHZ) + rate_flags |= TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 | + TX_RATE_VHT20; + if (ch_width == CH_WIDTH_160MHZ) + rate_flags |= TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 | + TX_RATE_VHT20; + if (ch_width == CH_WIDTH_80MHZ) + rate_flags |= TX_RATE_VHT80 | TX_RATE_VHT40 | TX_RATE_VHT20; + else if (ch_width) + rate_flags |= TX_RATE_VHT40 | TX_RATE_VHT20; + else + rate_flags |= TX_RATE_VHT20; + return rate_flags; +} + +enum tx_rate_info wma_get_ht_rate_flags(enum phy_ch_width ch_width) +{ + enum tx_rate_info rate_flags = 0; + + if (ch_width) + rate_flags |= TX_RATE_HT40 | TX_RATE_HT20; + else + rate_flags |= TX_RATE_HT20; + + return rate_flags; +} + +enum tx_rate_info wma_get_he_rate_flags(enum phy_ch_width ch_width) +{ + enum tx_rate_info rate_flags = 0; + + if (ch_width == CH_WIDTH_160MHZ || + ch_width == CH_WIDTH_80P80MHZ) + rate_flags |= TX_RATE_HE160 | TX_RATE_HE80 | TX_RATE_HE40 | + TX_RATE_HE20; + else if (ch_width == CH_WIDTH_80MHZ) + rate_flags |= TX_RATE_HE80 | TX_RATE_HE40 | TX_RATE_HE20; + else if (ch_width) + rate_flags |= TX_RATE_HE40 | TX_RATE_HE20; + else + rate_flags |= TX_RATE_HE20; + + return rate_flags; +} + void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id, - tpAddBssParams add_bss) + struct bss_params *add_bss) { struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + struct vdev_mlme_obj *vdev_mlme; + enum tx_rate_info *rate_flags; + - iface->rate_flags = 0; + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!vdev_mlme) { + WMA_LOGE("%s: Failed to get mlme obj for vdev_%d", + __func__, vdev_id); + return; + } + rate_flags = &vdev_mlme->mgmt.rate_info.rate_flags; + *rate_flags = 0; - if (QDF_STATUS_SUCCESS != wma_set_bss_rate_flags_he(iface, add_bss)) { + if (QDF_STATUS_SUCCESS != + wma_set_bss_rate_flags_he(rate_flags, add_bss)) { if (add_bss->vhtCapable) { - if (add_bss->ch_width == CH_WIDTH_80P80MHZ) - iface->rate_flags |= TX_RATE_VHT80; - if (add_bss->ch_width == CH_WIDTH_160MHZ) - iface->rate_flags |= TX_RATE_VHT80; - if (add_bss->ch_width == CH_WIDTH_80MHZ) - iface->rate_flags |= TX_RATE_VHT80; - else if (add_bss->ch_width) - iface->rate_flags |= TX_RATE_VHT40; - else - iface->rate_flags |= TX_RATE_VHT20; + *rate_flags = wma_get_vht_rate_flags(add_bss->ch_width); } /* avoid to conflict with htCapable flag */ else if (add_bss->htCapable) { - if (add_bss->ch_width) - iface->rate_flags |= TX_RATE_HT40; - else - iface->rate_flags |= TX_RATE_HT20; + *rate_flags |= wma_get_ht_rate_flags(add_bss->ch_width); } } + if (add_bss->staContext.fShortGI20Mhz || add_bss->staContext.fShortGI40Mhz) - iface->rate_flags |= TX_RATE_SGI; + *rate_flags |= TX_RATE_SGI; - if (!add_bss->htCapable && !add_bss->vhtCapable) - iface->rate_flags = TX_RATE_LEGACY; + if (!add_bss->htCapable && !add_bss->vhtCapable && + !wma_get_bss_he_capable(add_bss)) + *rate_flags = TX_RATE_LEGACY; wma_debug("capable: vht %u, ht %u, rate_flags %x, ch_width %d", add_bss->vhtCapable, add_bss->htCapable, - iface->rate_flags, add_bss->ch_width); + *rate_flags, add_bss->ch_width); wma_cp_stats_set_rate_flag(wma, vdev_id); } @@ -930,7 +975,6 @@ static void wma_data_tx_ack_work_handler(void *ack_work) void wma_data_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status) { - void *pdev; tp_wma_handle wma_handle = (tp_wma_handle) wma_context; if (!wma_handle) { @@ -938,10 +982,6 @@ wma_data_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status) return; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) - return; - /* * if netBuf does not match with pending nbuf then just free the * netbuf and do not call ack cb @@ -1014,8 +1054,9 @@ int wma_peer_state_change_event_handler(void *handle, { WMI_PEER_STATE_EVENTID_param_tlvs *param_buf; wmi_peer_state_event_fixed_param *event; - struct cdp_vdev *vdev; +#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL tp_wma_handle wma_handle = (tp_wma_handle) handle; +#endif if (!event_buff) { WMA_LOGE("%s: Received NULL event ptr from FW", __func__); @@ -1028,17 +1069,10 @@ int wma_peer_state_change_event_handler(void *handle, } event = param_buf->fixed_param; - vdev = wma_find_vdev_by_id(wma_handle, event->vdev_id); - if (!vdev) { - WMA_LOGD("%s: Couldn't find vdev for vdev_id: %d", - __func__, event->vdev_id); - return -EINVAL; - } if ((cdp_get_opmode(cds_get_context(QDF_MODULE_ID_SOC), - vdev) == - wlan_op_mode_sta) && - event->state == WMI_PEER_STATE_AUTHORIZED) { + event->vdev_id) == wlan_op_mode_sta) && + event->state == WMI_PEER_STATE_AUTHORIZED) { /* * set event so that hdd * can procced and unpause tx queue @@ -1213,142 +1247,39 @@ QDF_STATUS wma_set_mcc_channel_time_quota(tp_wma_handle wma, chan2_freq); } -/** - * wma_set_linkstate() - set wma linkstate - * @wma: wma handle - * @params: link state params - * - * Return: none - */ -void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) -{ - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - uint8_t vdev_id; - bool roam_synch_in_progress = false; - QDF_STATUS status; - struct wma_target_req *msg; - - params->status = true; - WMA_LOGD("%s: state %d selfmac %pM", __func__, - params->state, params->self_mac_addr); - if ((params->state != eSIR_LINK_PREASSOC_STATE) && - (params->state != eSIR_LINK_DOWN_STATE)) { - WMA_LOGD("%s: unsupported link state %d", - __func__, params->state); - params->status = false; - goto out; - } - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - params->status = false; - goto out; - } - - vdev = wma_find_vdev_by_addr(wma, params->self_mac_addr, &vdev_id); - if (!vdev) { - WMA_LOGP("%s: vdev not found for addr: %pM", - __func__, params->self_mac_addr); - params->status = false; - goto out; - } - - if (wma_is_vdev_in_ap_mode(wma, vdev_id)) { - WMA_LOGD("%s: Ignoring set link req in ap mode", __func__); - params->status = false; - goto out; - } - - if (params->state == eSIR_LINK_PREASSOC_STATE) { - if (wma_is_roam_synch_in_progress(wma, vdev_id)) - roam_synch_in_progress = true; - status = wma_create_peer(wma, pdev, vdev, params->bssid, - WMI_PEER_TYPE_DEFAULT, vdev_id, - roam_synch_in_progress); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Unable to create peer", __func__); - params->status = false; - } - if (roam_synch_in_progress) - return; - } else { - WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", - __func__, vdev_id); - cdp_fc_vdev_pause(soc, - wma->interfaces[vdev_id].handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); - msg = wma_fill_vdev_req(wma, vdev_id, - WMA_SET_LINK_STATE, - WMA_TARGET_REQ_TYPE_VDEV_STOP, params, - WMA_VDEV_STOP_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGP(FL("Failed to fill vdev request for vdev_id %d"), - vdev_id); - params->status = false; - status = QDF_STATUS_E_NOMEM; - goto out; - } - wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); - if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { - WMA_LOGP("%s: %d Failed to send vdev stop", - __func__, __LINE__); - params->status = false; - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP); - } else { - WMA_LOGP("%s: %d vdev stop sent vdev %d", - __func__, __LINE__, vdev_id); - /* - * Remove peer, Vdev down and sending set link - * response will be handled in vdev stop response - * handler - */ - return; - } - } -out: - wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); -} - -/** - * wma_process_rate_update_indate() - rate update indication - * @wma: wma handle - * @pRateUpdateParams: Rate update params - * - * This function update rate & short GI interval to fw based on params - * send by SME. - * - * Return: QDF status - */ QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma, tSirRateUpdateInd * pRateUpdateParams) { int32_t ret = 0; uint8_t vdev_id = 0; - void *pdev; int32_t mbpsx10_rate = -1; uint32_t paramId; uint8_t rate = 0; - uint32_t short_gi; + uint32_t short_gi, rate_flag; struct wma_txrx_node *intr = wma->interfaces; QDF_STATUS status; /* Get the vdev id */ - pdev = wma_find_vdev_by_addr(wma, pRateUpdateParams->bssid.bytes, - &vdev_id); - if (!pdev) { - WMA_LOGE("vdev handle is invalid for %pM", - pRateUpdateParams->bssid.bytes); + if (wma_find_vdev_id_by_addr(wma, pRateUpdateParams->bssid.bytes, + &vdev_id)) { + WMA_LOGE("vdev handle is invalid for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(pRateUpdateParams->bssid.bytes)); qdf_mem_free(pRateUpdateParams); return QDF_STATUS_E_INVAL; } short_gi = intr[vdev_id].config.shortgi; + + status = wma_get_vdev_rate_flag(intr[vdev_id].vdev, &rate_flag); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get rate_flag for VDEV_%d", + __func__, vdev_id); + qdf_mem_free(pRateUpdateParams); + return QDF_STATUS_E_INVAL; + } + if (short_gi == 0) - short_gi = (intr[vdev_id].rate_flags & TX_RATE_SGI) ? - true : false; + short_gi = (rate_flag & TX_RATE_SGI) ? true : false; /* first check if reliable TX mcast rate is used. If not check the bcast * Then is mcast. Mcast rate is saved in mcastDataRate24GHz */ @@ -1371,12 +1302,12 @@ QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma, WMA_LOGE("%s: dev_id = %d, dev_type = %d, dev_mode = %d,", __func__, vdev_id, intr[vdev_id].type, pRateUpdateParams->dev_mode); - WMA_LOGE("%s: mac = %pM, config.shortgi = %d, rate_flags = 0x%x", - __func__, pRateUpdateParams->bssid.bytes, - intr[vdev_id].config.shortgi, intr[vdev_id].rate_flags); + WMA_LOGE("%s: mac = "QDF_MAC_ADDR_FMT", config.shortgi = %d, rate_flags = 0x%x", + __func__, QDF_MAC_ADDR_REF(pRateUpdateParams->bssid.bytes), + intr[vdev_id].config.shortgi, rate_flag); ret = wma_encode_mc_rate(short_gi, intr[vdev_id].config.chwidth, - intr[vdev_id].chanmode, intr[vdev_id].mhz, - mbpsx10_rate, pRateUpdateParams->nss, &rate); + intr[vdev_id].mhz, mbpsx10_rate, + pRateUpdateParams->nss, &rate); if (ret != QDF_STATUS_SUCCESS) { WMA_LOGE("%s: Error, Invalid input rate value", __func__); qdf_mem_free(pRateUpdateParams); @@ -1418,11 +1349,15 @@ wma_mgmt_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status) tp_wma_handle wma_handle = (tp_wma_handle) wma_context; struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *) wma_handle->pdev; + struct wmi_mgmt_params mgmt_params = {}; uint16_t desc_id; + uint8_t vdev_id; desc_id = QDF_NBUF_CB_MGMT_TXRX_DESC_ID(netbuf); + vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id); - mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL); + mgmt_params.vdev_id = vdev_id; + mgmt_txrx_tx_completion_handler(pdev, desc_id, status, &mgmt_params); } /** @@ -1477,18 +1412,18 @@ QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle) struct cds_context *cds_handle = (struct cds_context *) (wma_handle->cds_context); - /* Get the txRx Pdev handle */ - struct cdp_pdev *txrx_pdev = cds_handle->pdev_txrx_ctx; + /* Get the txRx Pdev ID */ + uint8_t pdev_id = WMI_PDEV_ID_SOC; void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* Register for Tx Management Frames */ - cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0, - wma_mgmt_tx_dload_comp_hldr, - wma_mgmt_tx_ack_comp_hdlr, wma_handle); + cdp_mgmt_tx_cb_set(soc, pdev_id, 0, + wma_mgmt_tx_dload_comp_hldr, + wma_mgmt_tx_ack_comp_hdlr, wma_handle); /* Register callback to send PEER_UNMAP_RESPONSE cmd*/ if (cdp_cfg_get_peer_unmap_conf_support(soc)) - cdp_peer_unmap_sync_cb_set(soc, txrx_pdev, + cdp_peer_unmap_sync_cb_set(soc, pdev_id, wma_peer_unmap_conf_cb); /* Store the Mac Context */ @@ -1509,21 +1444,17 @@ QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle) { void *soc = cds_get_context(QDF_MODULE_ID_SOC); - /* Get the Vos Context */ - struct cds_context *cds_handle = - (struct cds_context *) (wma_handle->cds_context); - - /* Get the txRx Pdev handle */ - struct cdp_pdev *txrx_pdev = cds_handle->pdev_txrx_ctx; + /* Get the txRx Pdev ID */ + uint8_t pdev_id = WMI_PDEV_ID_SOC; if (!soc) { WMA_LOGE("%s:SOC context is NULL", __func__); return QDF_STATUS_E_FAILURE; } - if (txrx_pdev) { + if (pdev_id != OL_TXRX_INVALID_PDEV_ID) { /* Deregister with TxRx for Tx Mgmt completion call back */ - cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0, NULL, NULL, txrx_pdev); + cdp_mgmt_tx_cb_set(soc, pdev_id, 0, NULL, NULL, NULL); } /* Reset Tx Frm Callbacks */ @@ -1540,18 +1471,61 @@ QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle) #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \ defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT) +static void wma_process_vdev_tx_pause_evt(void *soc, + tp_wma_handle wma, + wmi_tx_pause_event_fixed_param *event, + uint8_t vdev_id) +{ + /* PAUSE action, add bitmap */ + if (event->action == ACTION_PAUSE) { + /* Exclude TDLS_OFFCHAN_CHOP from vdev based pauses */ + if (event->pause_type == PAUSE_TYPE_CHOP_TDLS_OFFCHAN) { + cdp_fc_vdev_pause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_FW, + event->pause_type); + } else { + /* + * Now only support per-dev pause so it is not + * necessary to pause a paused queue again. + */ + if (!wma_vdev_get_pause_bitmap(vdev_id)) + cdp_fc_vdev_pause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_FW, + event->pause_type); + + wma_vdev_set_pause_bit(vdev_id, + event->pause_type); + } + } + /* UNPAUSE action, clean bitmap */ + else if (event->action == ACTION_UNPAUSE) { + /* Exclude TDLS_OFFCHAN_CHOP from vdev based pauses */ + if (event->pause_type == PAUSE_TYPE_CHOP_TDLS_OFFCHAN) { + cdp_fc_vdev_unpause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_FW, + event->pause_type); + } else { + /* Handle unpause only if already paused */ + if (wma_vdev_get_pause_bitmap(vdev_id)) { + wma_vdev_clear_pause_bit(vdev_id, + event->pause_type); + + if (wma->interfaces[vdev_id].pause_bitmap) + return; + + /* PAUSE BIT MAP is cleared + * UNPAUSE VDEV + */ + cdp_fc_vdev_unpause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_FW, + event->pause_type); + } + } + } else { + WMA_LOGE("Not Valid Action Type %d", event->action); + } +} -/** - * wma_mcc_vdev_tx_pause_evt_handler() - pause event handler - * @handle: wma handle - * @event: event buffer - * @len: data length - * - * This function handle pause event from fw and pause/unpause - * vdev. - * - * Return: 0 for success or error code. - */ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, uint32_t len) { @@ -1589,50 +1563,17 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, if (!(vdev_map & 0x1)) { /* No Vdev */ } else { - if (!wma->interfaces[vdev_id].handle) { - WMA_LOGE("%s: invalid vdev ID %d", __func__, + if (!wma->interfaces[vdev_id].vdev) { + WMA_LOGE("%s: vdev is NULL for %d", __func__, vdev_id); /* Test Next VDEV */ vdev_map >>= 1; continue; } - /* PAUSE action, add bitmap */ - if (ACTION_PAUSE == wmi_event->action) { - /* - * Now only support per-dev pause so it is not - * necessary to pause a paused queue again. - */ - if (!wma_vdev_get_pause_bitmap(vdev_id)) - cdp_fc_vdev_pause(soc, - wma-> - interfaces[vdev_id].handle, - OL_TXQ_PAUSE_REASON_FW); - wma_vdev_set_pause_bit(vdev_id, - wmi_event->pause_type); - } - /* UNPAUSE action, clean bitmap */ - else if (ACTION_UNPAUSE == wmi_event->action) { - /* Handle unpause only if already paused */ - if (wma_vdev_get_pause_bitmap(vdev_id)) { - wma_vdev_clear_pause_bit(vdev_id, - wmi_event->pause_type); - - if (!wma->interfaces[vdev_id]. - pause_bitmap) { - /* PAUSE BIT MAP is cleared - * UNPAUSE VDEV - */ - cdp_fc_vdev_unpause(soc, - wma->interfaces[vdev_id] - .handle, - OL_TXQ_PAUSE_REASON_FW); - } - } - } else { - WMA_LOGE("Not Valid Action Type %d", - wmi_event->action); - } + wma_process_vdev_tx_pause_evt(soc, wma, + wmi_event, + vdev_id); WMA_LOGD ("vdev_id %d, pause_map 0x%x, pause type %d, action %d", @@ -1709,7 +1650,6 @@ QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma, struct t_bad_peer_txtcl_config *config) { /* Parameter sanity check */ - struct cdp_pdev *curr_pdev; void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!wma || !config) { @@ -1717,10 +1657,6 @@ QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma, return QDF_STATUS_E_FAILURE; } - curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!curr_pdev) - return QDF_STATUS_E_FAILURE; - WMA_LOGE("%s enable %d period %d txq limit %d\n", __func__, config->enable, config->period, @@ -1733,7 +1669,7 @@ QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma, int i = 0; cdp_bad_peer_txctl_set_setting(soc, - curr_pdev, + WMI_PDEV_ID_SOC, config->enable, config->period, config->txq_limit); @@ -1744,7 +1680,7 @@ QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma, threshold = config->threshold[i].thresh[0]; limit = config->threshold[i].txlimit; cdp_bad_peer_txctl_update_threshold(soc, - curr_pdev, + WMI_PDEV_ID_SOC, i, threshold, limit); @@ -1768,7 +1704,7 @@ QDF_STATUS wma_process_init_bad_peer_tx_ctl_info(tp_wma_handle wma, static QDF_STATUS wma_update_thermal_mitigation_to_fw(tp_wma_handle wma, u_int8_t thermal_level) { - struct thermal_mitigation_params therm_data; + struct thermal_mitigation_params therm_data = {0}; /* Check if vdev is in mcc, if in mcc set dc value as 10, else 100 */ therm_data.dc = 100; @@ -1777,7 +1713,8 @@ static QDF_STATUS wma_update_thermal_mitigation_to_fw(tp_wma_handle wma, wma->thermal_mgmt_info.throttle_duty_cycle_tbl[thermal_level]; therm_data.levelconf[0].priority = 0; - return wmi_unified_thermal_mitigation_param_cmd_send(wma, &therm_data); + return wmi_unified_thermal_mitigation_param_cmd_send(wma->wmi_handle, + &therm_data); } #else /* FW_THERMAL_THROTTLE_SUPPORT */ /** @@ -1839,7 +1776,6 @@ static QDF_STATUS wma_update_thermal_cfg_to_fw(tp_wma_handle wma) QDF_STATUS wma_process_init_thermal_info(tp_wma_handle wma, t_thermal_mgmt *pThermalParams) { - struct cdp_pdev *curr_pdev; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; #ifdef FW_THERMAL_THROTTLE_SUPPORT int i = 0; @@ -1850,10 +1786,6 @@ QDF_STATUS wma_process_init_thermal_info(tp_wma_handle wma, return QDF_STATUS_E_FAILURE; } - curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!curr_pdev) - return QDF_STATUS_E_FAILURE; - WMA_LOGD("TM enable %d period %d", pThermalParams->thermalMgmtEnabled, pThermalParams->throttlePeriod); @@ -1911,7 +1843,7 @@ QDF_STATUS wma_process_init_thermal_info(tp_wma_handle wma, if (!wma->fw_therm_throt_support) { cdp_throttle_init_period( cds_get_context(QDF_MODULE_ID_SOC), - curr_pdev, pThermalParams->throttlePeriod, + WMI_PDEV_ID_SOC, pThermalParams->throttlePeriod, &pThermalParams->throttle_duty_cycle_tbl[0]); } else { qdf_status = wma_update_thermal_mitigation_to_fw( @@ -1965,17 +1897,11 @@ static void wma_set_thermal_level_ind(u_int8_t level) QDF_STATUS wma_process_set_thermal_level(tp_wma_handle wma, uint8_t thermal_level) { - struct cdp_pdev *curr_pdev; - if (!wma) { WMA_LOGE("TM Invalid input"); return QDF_STATUS_E_FAILURE; } - curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!curr_pdev) - return QDF_STATUS_E_FAILURE; - WMA_LOGE("TM set level %d", thermal_level); /* Check if thermal mitigation is enabled */ @@ -1998,7 +1924,7 @@ QDF_STATUS wma_process_set_thermal_level(tp_wma_handle wma, wma->thermal_mgmt_info.thermalCurrLevel = thermal_level; cdp_throttle_set_level(cds_get_context(QDF_MODULE_ID_SOC), - curr_pdev, thermal_level); + WMI_PDEV_ID_SOC, thermal_level); /* Send SME SET_THERMAL_LEVEL_IND message */ wma_set_thermal_level_ind(thermal_level); @@ -2089,7 +2015,6 @@ int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event, uint32_t len) uint8_t thermal_level; t_thermal_cmd_params thermal_params; WMI_THERMAL_MGMT_EVENTID_param_tlvs *param_buf; - struct cdp_pdev *curr_pdev; if (!event || !handle) { WMA_LOGE("Invalid thermal mitigation event buffer"); @@ -2105,10 +2030,6 @@ int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event, uint32_t len) param_buf = (WMI_THERMAL_MGMT_EVENTID_param_tlvs *) event; - curr_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!curr_pdev) - return -EINVAL; - /* Check if thermal mitigation is enabled */ if (!wma->thermal_mgmt_info.thermalMgmtEnabled) { WMA_LOGE("Thermal mgmt is not enabled, ignoring event"); @@ -2135,7 +2056,7 @@ int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event, uint32_t len) if (!wma->fw_therm_throt_support) { /* Inform txrx */ cdp_throttle_set_level(cds_get_context(QDF_MODULE_ID_SOC), - curr_pdev, thermal_level); + WMI_PDEV_ID_SOC, thermal_level); } /* Send SME SET_THERMAL_LEVEL_IND message */ @@ -2166,22 +2087,12 @@ int wma_thermal_mgmt_evt_handler(void *handle, uint8_t *event, uint32_t len) return 0; } -/** - * wma_ibss_peer_info_event_handler() - IBSS peer info event handler - * @handle: wma handle - * @data: event data - * @len: length of data - * - * This function handles IBSS peer info event from FW. - * - * Return: 0 for success or error code - */ +#ifdef QCA_IBSS_SUPPORT int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, uint32_t len) { struct scheduler_msg cds_msg = {0}; wmi_peer_info *peer_info; - void *pdev; tSirIbssPeerInfoParams *pSmeRsp; uint32_t count, num_peers, status; tSirIbssGetPeerInfoRspParams *pRsp; @@ -2195,10 +2106,6 @@ int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, return 0; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) - return 0; - param_tlvs = (WMI_PEER_INFO_EVENTID_param_tlvs *) data; fix_param = param_tlvs->fixed_param; peer_info = param_tlvs->peer_info; @@ -2242,8 +2149,8 @@ int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, pSmeRsp->txRate = peer_info->data_rate; - wma_err("peer " QDF_MAC_ADDR_STR "rssi %d txRate %d", - QDF_MAC_ADDR_ARRAY(peer_mac), + wma_err("peer " QDF_MAC_ADDR_FMT "rssi %d txRate %d", + QDF_MAC_ADDR_REF(peer_mac), pSmeRsp->rssi, pSmeRsp->txRate); peer_info++; @@ -2273,6 +2180,7 @@ int wma_ibss_peer_info_event_handler(void *handle, uint8_t *data, return 0; } +#endif /** * wma_fast_tx_fail_event_handler() -tx failure event handler @@ -2470,14 +2378,21 @@ static void wma_update_tx_send_params(struct tx_send_params *tx_param, tx_param->preamble_type); } -#ifdef CRYPTO_SET_KEY_CONVERGED -uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len) +#ifdef WLAN_FEATURE_11W +uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len, + uint16_t igtk_key_idx) { struct wlan_crypto_key *crypto_key; - crypto_key = wlan_crypto_get_key(iface->vdev, WMA_IGTK_KEY_INDEX_4); + if (!(igtk_key_idx == WMA_IGTK_KEY_INDEX_4 || + igtk_key_idx == WMA_IGTK_KEY_INDEX_5)) { + wma_err("Invalid igtk_key_idx %d", igtk_key_idx); + *key_len = 0; + return NULL; + } + crypto_key = wlan_crypto_get_key(iface->vdev, igtk_key_idx); if (!crypto_key) { - wma_err("IGTK not found"); + wma_err("IGTK not found for igtk_idx %d", igtk_key_idx); *key_len = 0; return NULL; } @@ -2485,12 +2400,6 @@ uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len) return &crypto_key->keyval[0]; } -#else -uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len) -{ - *key_len = iface->key.key_length; - return iface->key.key; -} #endif QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, @@ -2498,7 +2407,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, wma_tx_dwnld_comp_callback tx_frm_download_comp_cb, void *pData, wma_tx_ota_comp_callback tx_frm_ota_comp_cb, - uint8_t tx_flag, uint8_t vdev_id, bool tdlsFlag, + uint8_t tx_flag, uint8_t vdev_id, bool tdls_flag, uint16_t channel_freq, enum rateid rid) { tp_wma_handle wma_handle = (tp_wma_handle) (wma_context); @@ -2506,7 +2415,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; int32_t is_high_latency; bool is_wmi_mgmt_tx = false; - struct cdp_vdev *txrx_vdev; enum frame_index tx_frm_index = GENERIC_NODOWNLD_NOACK_COMP_INDEX; tpSirMacFrameCtl pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(tx_frame)); uint8_t use_6mbps = 0; @@ -2516,6 +2424,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, uint8_t *pFrame = NULL; void *pPacket = NULL; uint16_t newFrmLen = 0; + uint8_t *igtk; + uint16_t key_len; #endif /* WLAN_FEATURE_11W */ struct wma_txrx_node *iface; struct mac_context *mac; @@ -2529,8 +2439,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, void *mac_addr; bool is_5g = false; uint8_t pdev_id; - uint8_t *igtk; - uint16_t key_len; if (!wma_handle) { WMA_LOGE("wma_handle is NULL"); @@ -2538,14 +2446,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, return QDF_STATUS_E_FAILURE; } iface = &wma_handle->interfaces[vdev_id]; - /* Get the vdev handle from vdev id */ - txrx_vdev = wma_handle->interfaces[vdev_id].handle; - - if (!txrx_vdev) { - WMA_LOGE("TxRx Vdev Handle is NULL"); - cds_packet_free((void *)tx_frame); - return QDF_STATUS_E_FAILURE; - } if (!soc) { WMA_LOGE("%s:SOC context is NULL", __func__); @@ -2553,7 +2453,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, return QDF_STATUS_E_FAILURE; } - cdp_hl_tdls_flag_reset(soc, txrx_vdev, false); + cdp_hl_tdls_flag_reset(soc, vdev_id, false); if (frmType >= TXRX_FRM_MAX) { WMA_LOGE("Invalid Frame Type Fail to send Frame"); @@ -2606,11 +2506,12 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, &mic_len, &hdr_len); if (QDF_IS_STATUS_ERROR(qdf_status)) { - cds_packet_free( - (void *)tx_frame); + cds_packet_free(( + void *)tx_frame); goto error; } } + newFrmLen = frmLen + hdr_len + mic_len; qdf_status = cds_packet_alloc((uint16_t) newFrmLen, @@ -2646,6 +2547,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, (qdf_nbuf_data(tx_frame)); } } else { + int8_t igtk_key_id; + /* Allocate extra bytes for MMIE */ newFrmLen = frmLen + IEEE80211_MMIE_LEN; qdf_status = cds_packet_alloc((uint16_t) newFrmLen, @@ -2669,16 +2572,23 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, qdf_mem_copy(pFrame, wh, sizeof(*wh)); qdf_mem_copy(pFrame + sizeof(*wh), pData + sizeof(*wh), frmLen - sizeof(*wh)); - igtk = wma_get_igtk(iface, &key_len); + igtk_key_id = + wlan_crypto_get_default_key_idx(iface->vdev, + true); + /* Get actual igtk key id adding 4 */ + igtk_key_id += WMA_IGTK_KEY_INDEX_4; + igtk = wma_get_igtk(iface, &key_len, igtk_key_id); if (!igtk) { - wma_alert("IGTK not present"); + wma_err_rl("IGTK not present for igtk_key_id %d", + igtk_key_id); cds_packet_free((void *)tx_frame); cds_packet_free((void *)pPacket); goto error; } - if (!cds_attach_mmie(igtk, - iface->key.key_id[0].ipn, - WMA_IGTK_KEY_INDEX_4, + if (!cds_attach_mmie(igtk, iface->key.key_id[ + igtk_key_id - + WMA_IGTK_KEY_INDEX_4].ipn, + igtk_key_id, pFrame, pFrame + newFrmLen, newFrmLen)) { wma_alert("Failed to attach MMIE"); @@ -2718,18 +2628,12 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, if (frmType == TXRX_FRM_802_11_DATA) { qdf_nbuf_t ret; qdf_nbuf_t skb = (qdf_nbuf_t) tx_frame; - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); struct wma_decap_info_t decap_info; struct ieee80211_frame *wh = (struct ieee80211_frame *)qdf_nbuf_data(skb); unsigned long curr_timestamp = qdf_mc_timer_get_system_ticks(); - if (!pdev) { - cds_packet_free((void *)tx_frame); - return QDF_STATUS_E_FAULT; - } - /* * 1) TxRx Module expects data input to be 802.3 format * So Decapsulation has to be done. @@ -2787,14 +2691,14 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, /* Send the Data frame to TxRx in Non Standard Path */ cdp_hl_tdls_flag_reset(soc, - txrx_vdev, tdlsFlag); + vdev_id, tdls_flag); ret = cdp_tx_non_std(soc, - txrx_vdev, + vdev_id, OL_TX_SPEC_NO_FREE, skb); cdp_hl_tdls_flag_reset(soc, - txrx_vdev, false); + vdev_id, false); if (ret) { WMA_LOGE("TxRx Rejected. Fail to do Tx"); @@ -2817,8 +2721,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, return QDF_STATUS_SUCCESS; } - ctrl_pdev = cdp_get_ctrl_pdev_from_vdev(soc, - txrx_vdev); + ctrl_pdev = cdp_get_ctrl_pdev_from_vdev(soc, vdev_id); if (!ctrl_pdev) { WMA_LOGE("ol_pdev_handle is NULL\n"); cds_packet_free((void *)tx_frame); @@ -2898,7 +2801,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, } } - if (wma_handle->interfaces[vdev_id].channel >= SIR_11A_CHANNEL_BEGIN) + if (wlan_reg_is_5ghz_ch_freq(wma_handle->interfaces[vdev_id].ch_freq)) is_5g = true; mgmt_param.tx_frame = tx_frame; @@ -2944,13 +2847,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, WLAN_MGMT_NB_ID); } - if (ucfg_pkt_capture_get_pktcap_mode() & PKT_CAPTURE_MODE_MGMT_ONLY) { - ucfg_pkt_capture_mgmt_tx(wma_handle->pdev, - tx_frame, - wma_handle->interfaces[vdev_id].mhz, - mgmt_param.tx_param.preamble_type); - } - status = wlan_mgmt_txrx_mgmt_frame_tx(peer, wma_handle->mac_context, (qdf_nbuf_t)tx_frame, NULL, tx_frm_ota_comp_cb, @@ -3114,6 +3010,7 @@ void ol_rx_err(void *pdev, uint8_t vdev_id, tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); struct mic_failure_ind *mic_err_ind; qdf_ether_header_t *eth_hdr; + uint8_t *bssid; struct scheduler_msg cds_msg = {0}; if (!wma) @@ -3132,8 +3029,15 @@ void ol_rx_err(void *pdev, uint8_t vdev_id, mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND; mic_err_ind->length = sizeof(*mic_err_ind); mic_err_ind->sessionId = vdev_id; + bssid = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + qdf_mem_free((void *)mic_err_ind); + return; + } qdf_copy_macaddr(&mic_err_ind->bssId, - (struct qdf_mac_addr *) &wma->interfaces[vdev_id].bssid); + (struct qdf_mac_addr *)bssid); qdf_mem_copy(mic_err_ind->info.taMacAddr, (struct qdf_mac_addr *) peer_mac_addr, sizeof(tSirMacAddr)); @@ -3163,20 +3067,13 @@ void ol_rx_err(void *pdev, uint8_t vdev_id, } } -/** - * wma_tx_abort() - abort tx - * @vdev_id: vdev id - * - * In case of deauth host abort transmitting packet. - * - * Return: none - */ void wma_tx_abort(uint8_t vdev_id) { #define PEER_ALL_TID_BITMASK 0xffffffff tp_wma_handle wma; uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK; struct wma_txrx_node *iface; + uint8_t *bssid; struct peer_flush_params param = {0}; wma = cds_get_context(QDF_MODULE_ID_WMA); @@ -3184,22 +3081,29 @@ void wma_tx_abort(uint8_t vdev_id) return; iface = &wma->interfaces[vdev_id]; - if (!iface->handle) { - WMA_LOGE("%s: Failed to get iface handle: %pK", - __func__, iface->handle); + if (!iface->vdev) { + WMA_LOGE("%s: iface->vdev is NULL", __func__); return; } - WMA_LOGD("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid); + + bssid = wma_get_vdev_bssid(iface->vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + return; + } + + WMA_LOGD("%s: vdevid %d bssid "QDF_MAC_ADDR_FMT, __func__, vdev_id, + QDF_MAC_ADDR_REF(bssid)); wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); - cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC), - iface->handle, - OL_TXQ_PAUSE_REASON_TX_ABORT); + cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC), vdev_id, + OL_TXQ_PAUSE_REASON_TX_ABORT, 0); /* Flush all TIDs except MGMT TID for this peer in Target */ peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); param.peer_tid_bitmap = peer_tid_bitmap; param.vdev_id = vdev_id; - wmi_unified_peer_flush_tids_send(wma->wmi_handle, iface->bssid, + wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid, ¶m); } @@ -3239,104 +3143,6 @@ QDF_STATUS wma_lro_config_cmd(void *handle, &wmi_lro_cmd); } -/** - * wma_indicate_err() - indicate an error to the protocol stack - * @err_type: error type - * @err_info: information associated with the error - * - * This function indicates an error encountered in the data path - * to the protocol stack - * - * Return: none - */ -void -wma_indicate_err( - enum ol_rx_err_type err_type, - struct ol_error_info *err_info) -{ - switch (err_type) { - case OL_RX_ERR_TKIP_MIC: - { - tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - struct mic_failure_ind *mic_err_ind; - struct scheduler_msg cds_msg = {0}; - uint8_t vdev_id; - - if (!wma) { - WMA_LOGE("%s: Failed to get wma context", - __func__); - return; - } - - mic_err_ind = qdf_mem_malloc(sizeof(*mic_err_ind)); - if (!mic_err_ind) - return; - - qdf_mem_zero((void *)mic_err_ind, - sizeof(*mic_err_ind)); - mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND; - mic_err_ind->length = sizeof(*mic_err_ind); - vdev_id = err_info->u.mic_err.vdev_id; - qdf_copy_macaddr(&mic_err_ind->bssId, - (struct qdf_mac_addr *) &wma->interfaces[vdev_id].bssid); - wma_err("MIC error: BSSID:"QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mic_err_ind->bssId.bytes)); - qdf_mem_copy(mic_err_ind->info.taMacAddr, - (struct qdf_mac_addr *) err_info->u.mic_err.ta, - sizeof(tSirMacAddr)); - qdf_mem_copy(mic_err_ind->info.srcMacAddr, - (struct qdf_mac_addr *) err_info->u.mic_err.sa, - sizeof(tSirMacAddr)); - qdf_mem_copy(mic_err_ind->info.dstMacAddr, - (struct qdf_mac_addr *) err_info->u.mic_err.da, - sizeof(tSirMacAddr)); - mic_err_ind->info.keyId = err_info->u.mic_err.key_id; - mic_err_ind->info.multicast = - IEEE80211_IS_MULTICAST(err_info->u.mic_err.da); - qdf_mem_copy(mic_err_ind->info.TSC, - (void *)&err_info-> - u.mic_err.pn, SIR_CIPHER_SEQ_CTR_SIZE); - - qdf_mem_zero(&cds_msg, sizeof(struct scheduler_msg)); - cds_msg.type = eWNI_SME_MIC_FAILURE_IND; - cds_msg.bodyptr = (void *) mic_err_ind; - if (QDF_STATUS_SUCCESS != - scheduler_post_message(QDF_MODULE_ID_WMA, - QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, - &cds_msg)) { - WMA_LOGE("%s: mic failure ind post to SME failed", - __func__); - qdf_mem_free((void *)mic_err_ind); - } - break; - } - default: - { - WMA_LOGE("%s: unhandled ol error type %d", __func__, err_type); - break; - } - } -} - -void wma_rx_mic_error_ind(void *scn_handle, uint16_t vdev_id, void *wh) -{ - struct ieee80211_frame *w = (struct ieee80211_frame *)wh; - struct ol_error_info err_info; - - err_info.u.mic_err.vdev_id = vdev_id; - qdf_mem_copy(err_info.u.mic_err.da, w->i_addr1, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(err_info.u.mic_err.ta, w->i_addr2, QDF_MAC_ADDR_SIZE); - - WMA_LOGD("MIC vdev_id %d\n", vdev_id); - wma_debug("MIC DA: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(err_info.u.mic_err.da)); - wma_debug("MIC TA: "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(err_info.u.mic_err.ta)); - - wma_indicate_err(OL_RX_ERR_TKIP_MIC, &err_info); -} - void wma_delete_invalid_peer_entries(uint8_t vdev_id, uint8_t *peer_mac_addr) { tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); @@ -3362,7 +3168,8 @@ void wma_delete_invalid_peer_entries(uint8_t vdev_id, uint8_t *peer_mac_addr) } } if (i == INVALID_PEER_MAX_NUM) - wma_debug("peer_mac_addr %pM is not found", peer_mac_addr); + wma_debug("peer_mac_addr "QDF_MAC_ADDR_FMT" is not found", + QDF_MAC_ADDR_REF(peer_mac_addr)); } else { qdf_mem_zero(iface->invalid_peers, sizeof(iface->invalid_peers)); @@ -3415,18 +3222,18 @@ uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh) /* send deauth */ WMA_LOGD("%s: vdev_id %d", __func__, vdev_id); - wma_debug(" RA: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(rx_inv_msg->ra)); - wma_debug(" TA: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(rx_inv_msg->ta)); + wma_debug(" RA: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(rx_inv_msg->ra)); + wma_debug(" TA: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(rx_inv_msg->ta)); wma_send_msg(wma, SIR_LIM_RX_INVALID_PEER, (void *)rx_inv_msg, 0); } else { wma_debug_rl("Ignore invalid peer indication as received more than once " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(rx_inv_msg->ta)); + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(rx_inv_msg->ta)); qdf_mem_free(rx_inv_msg); } @@ -3450,8 +3257,8 @@ int wma_dp_send_delba_ind(uint8_t vdev_id, uint8_t *peer_macaddr, qdf_mem_copy(req->peer_macaddr, peer_macaddr, QDF_MAC_ADDR_SIZE); req->tid = tid; req->reason_code = reason_code; - WMA_LOGD("req delba_ind vdev %d %pM tid %d reason %d", - vdev_id, peer_macaddr, tid, reason_code); + WMA_LOGD("req delba_ind vdev %d "QDF_MAC_ADDR_FMT" tid %d reason %d", + vdev_id, QDF_MAC_ADDR_REF(peer_macaddr), tid, reason_code); wma_send_msg_high_priority(wma, SIR_HAL_REQ_SEND_DELBA_REQ_IND, (void *)req, 0); diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c index febb4dad1f2407c1095eb432af1460d1c7625428..0e9a8cfd8c9332cd96952f3e63f90255dcb5a316 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -59,6 +60,10 @@ #include #include #include +#include +#ifdef WLAN_FEATURE_PKT_CAPTURE +#include +#endif /* WLAN_FEATURE_PKT_CAPTURE */ #include "wlan_policy_mgr_api.h" #include "wma_nan_datapath.h" @@ -71,7 +76,7 @@ #include #include "wlan_pmo_ucfg_api.h" #include "wlan_reg_services_api.h" - +#include #include "wma_he.h" #include "wlan_roam_debug.h" #include "wlan_ocb_ucfg_api.h" @@ -81,29 +86,32 @@ #include "wlan_mlme_public_struct.h" #include "wlan_mlme_api.h" #include "wlan_mlme_main.h" - -/** - * wma_find_vdev_by_addr() - find vdev_id from mac address - * @wma: wma handle - * @addr: mac address - * @vdev_id: return vdev_id - * - * Return: Returns vdev handle or NULL if mac address don't match - */ -struct cdp_vdev *wma_find_vdev_by_addr(tp_wma_handle wma, uint8_t *addr, - uint8_t *vdev_id) +#include "wlan_mlme_ucfg_api.h" +#include +#include "../../core/src/vdev_mgr_ops.h" +#include "wlan_utility.h" +#include +#include "wmi_unified_vdev_api.h" + +QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr, + uint8_t *vdev_id) { uint8_t i; + struct wlan_objmgr_vdev *vdev; for (i = 0; i < wma->max_bssid; i++) { + vdev = wma->interfaces[i].vdev; + if (!vdev) + continue; + if (qdf_is_macaddr_equal( - (struct qdf_mac_addr *) wma->interfaces[i].addr, - (struct qdf_mac_addr *) addr) == true) { + (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev), + (struct qdf_mac_addr *)addr) == true) { *vdev_id = i; - return wma->interfaces[i].handle; + return QDF_STATUS_SUCCESS; } } - return NULL; + return QDF_STATUS_E_FAILURE; } @@ -136,16 +144,6 @@ bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id) } #ifdef QCA_IBSS_SUPPORT -/** - * wma_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not - * @wma: wma handle - * @vdev_id: vdev id - * - * Helper function to know whether given vdev id - * is in IBSS mode or not. - * - * Return: True/False - */ bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id) { struct wma_txrx_node *intf = wma->interfaces; @@ -161,100 +159,88 @@ bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id) return false; } -#endif /* QCA_IBSS_SUPPORT */ /** - * wma_find_vdev_by_bssid() - Get the corresponding vdev_id from BSSID - * @wma - wma handle - * @vdev_id - vdev ID + * wma_send_peer_atim_window_len() - send peer atim window length + * @wma: wma handle + * @add_sta: add sta parameters + * + * This API sends the peer Atim Window length if IBSS + * power save is enabled by the firmware. * - * Return: fill vdev_id with appropriate vdev id and return vdev - * handle or NULL if not found. + * Return: none */ -struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid, - uint8_t *vdev_id) +static void +wma_send_peer_atim_window_len(tp_wma_handle wma, tpAddStaParams add_sta) { - int i; - - for (i = 0; i < wma->max_bssid; i++) { - if (qdf_is_macaddr_equal( - (struct qdf_mac_addr *) wma->interfaces[i].bssid, - (struct qdf_mac_addr *) bssid) == true) { - *vdev_id = i; - return wma->interfaces[i].handle; + if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId) && + wmi_service_enabled(wma->wmi_handle, + wmi_service_ibss_pwrsave)) { + /* + * If ATIM Window is present in the peer + * beacon then send it to firmware else + * configure Zero ATIM Window length to + * firmware. + */ + if (add_sta->atimIePresent) { + wma_set_peer_param(wma, add_sta->staMac, + WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, + add_sta->peerAtimWindowLength, + add_sta->smesessionId); + } else { + wma_set_peer_param(wma, add_sta->staMac, + WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, + 0, add_sta->smesessionId); } } - - return NULL; } +#else +static inline void +wma_send_peer_atim_window_len(tp_wma_handle wma, tpAddStaParams add_sta) +{ +} +#endif /* QCA_IBSS_SUPPORT */ -/** - * wma_get_txrx_vdev_subtype() - return sutype of vdev - * @type: vdev_subtype - * - * Return: return vdev subtype as enum wlan_op_subtype type - */ -static enum wlan_op_subtype wma_get_txrx_vdev_subtype(uint32_t subtype) +uint8_t *wma_get_vdev_bssid(struct wlan_objmgr_vdev *vdev) { - enum wlan_op_subtype vdev_subtype = wlan_op_subtype_none; + struct vdev_mlme_obj *mlme_obj; - switch (subtype) { - case WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE: - vdev_subtype = wlan_op_subtype_p2p_device; - break; - case WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT: - vdev_subtype = wlan_op_subtype_p2p_cli; - break; - case WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO: - vdev_subtype = wlan_op_subtype_p2p_go; - break; - default: - vdev_subtype = wlan_op_subtype_none; + if (!vdev) { + WMA_LOGE("%s vdev is NULL", __func__); + return NULL; + } + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + WMA_LOGE("%s Failed to get mlme_obj", __func__); + return NULL; } - return vdev_subtype; + return mlme_obj->mgmt.generic.bssid; } -/** - * wma_get_txrx_vdev_type() - return operating mode of vdev - * @type: vdev_type - * - * Return: return operating mode as enum wlan_op_mode type - */ -static enum wlan_op_mode wma_get_txrx_vdev_type(uint32_t type) +QDF_STATUS wma_find_vdev_id_by_bssid(tp_wma_handle wma, uint8_t *bssid, + uint8_t *vdev_id) { - enum wlan_op_mode vdev_type = wlan_op_mode_unknown; + int i; + uint8_t *bssid_addr; - switch (type) { - case WMI_VDEV_TYPE_AP: - vdev_type = wlan_op_mode_ap; - break; - case WMI_VDEV_TYPE_STA: - vdev_type = wlan_op_mode_sta; - break; -#ifdef QCA_IBSS_SUPPORT - case WMI_VDEV_TYPE_IBSS: - vdev_type = wlan_op_mode_ibss; - break; -#endif /* QCA_IBSS_SUPPORT */ - case WMI_VDEV_TYPE_OCB: - vdev_type = wlan_op_mode_ocb; - break; - case WMI_VDEV_TYPE_MONITOR: - vdev_type = wlan_op_mode_monitor; - break; - case WMI_VDEV_TYPE_NDI: - vdev_type = wlan_op_mode_ndi; - break; - case WMI_VDEV_TYPE_NAN: - vdev_type = wlan_op_mode_nan; - break; - default: - WMA_LOGE("Invalid vdev type %u", type); - vdev_type = wlan_op_mode_unknown; + for (i = 0; i < wma->max_bssid; i++) { + if (!wma->interfaces[i].vdev) + continue; + bssid_addr = wma_get_vdev_bssid(wma->interfaces[i].vdev); + if (!bssid_addr) + continue; + + if (qdf_is_macaddr_equal( + (struct qdf_mac_addr *)bssid_addr, + (struct qdf_mac_addr *)bssid) == true) { + *vdev_id = i; + return QDF_STATUS_SUCCESS; + } } - return vdev_type; + return QDF_STATUS_E_FAILURE; } /** @@ -441,188 +427,60 @@ static struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma, } /** - * wma_find_vdev_req_on_timer_expiry() - find target request by address - * @wma: wma handle - * @req: pointer to the target request - * - * On timer expiry, the pointer to the req message is received from the - * timer callback. Lookup the vdev_resp_queue for the request with the - * same address and return success if found. - * - * Return: QDF_STATUS - */ -static -QDF_STATUS wma_find_vdev_req_on_timer_expiry(tp_wma_handle wma, - struct wma_target_req *req) -{ - struct wma_target_req *req_msg = NULL; - bool found = false; - qdf_list_node_t *cur_node = NULL, *next_node = NULL; - QDF_STATUS status; - - qdf_spin_lock_bh(&wma->vdev_respq_lock); - if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue, - &next_node)) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGD(FL("unable to find req from vdev resp queue for %pK"), - req); - return QDF_STATUS_E_FAILURE; - } - - do { - cur_node = next_node; - req_msg = qdf_container_of(cur_node, struct wma_target_req, - node); - if (req_msg != req) - continue; - - found = true; - status = qdf_list_remove_node(&wma->vdev_resp_queue, - cur_node); - if (QDF_STATUS_SUCCESS != status) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGD(FL("Failed to target req for %pK"), req); - return QDF_STATUS_E_FAILURE; - } - break; - } while (QDF_STATUS_SUCCESS == - qdf_list_peek_next(&wma->vdev_resp_queue, - cur_node, &next_node)); - - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - if (!found) { - WMA_LOGD(FL("target request not found for req %pK"), - req); - return QDF_STATUS_E_INVAL; - } - - WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"), - req_msg->vdev_id, req_msg->type, req_msg->msg_type); - return QDF_STATUS_SUCCESS; -} - -/** - * wma_find_vdev_req() - find target request for vdev id - * @wma: wma handle - * @vdev_id: vdev id - * @type: request type - * @remove_req_from_list: flag to indicate remove req or not. - * - * Return: return target request if found or NULL. - */ -static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma, - uint8_t vdev_id, uint8_t type, - bool remove_req_from_list) -{ - struct wma_target_req *req_msg = NULL; - bool found = false; - qdf_list_node_t *node1 = NULL, *node2 = NULL; - QDF_STATUS status; - - qdf_spin_lock_bh(&wma->vdev_respq_lock); - if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue, - &node2)) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGD(FL("unable to get target req from vdev resp queue vdev_id: %d type: %d"), - vdev_id, type); - return NULL; - } - - do { - node1 = node2; - req_msg = qdf_container_of(node1, struct wma_target_req, node); - if (req_msg->vdev_id != vdev_id) - continue; - if (req_msg->type != type) - continue; - - found = true; - if (remove_req_from_list) { - status = qdf_list_remove_node(&wma->vdev_resp_queue, - node1); - if (QDF_STATUS_SUCCESS != status) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGD(FL( - "Failed to target req for vdev_id %d type %d"), - vdev_id, type); - return NULL; - } - } - break; - } while (QDF_STATUS_SUCCESS == - qdf_list_peek_next(&wma->vdev_resp_queue, - node1, &node2)); - - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - if (!found) { - WMA_LOGD(FL("target request not found for vdev_id %d type %d"), - vdev_id, type); - return NULL; - } - WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"), - vdev_id, type, req_msg->msg_type); - return req_msg; -} - -/** - * wma_send_del_sta_self_resp() - send del sta self resp to Upper layer - * @param: params of del sta resp + * wma_send_vdev_del_resp() - send vdev del resp to Upper layer + * @param: params of del vdev response * * Return: none */ -static inline void wma_send_del_sta_self_resp(struct del_sta_self_params *param) +static inline void wma_send_vdev_del_resp(struct del_vdev_params *param) { struct scheduler_msg sme_msg = {0}; QDF_STATUS status; - sme_msg.type = eWNI_SME_DEL_STA_SELF_RSP; + sme_msg.type = eWNI_SME_VDEV_DELETE_RSP; sme_msg.bodyptr = param; status = scheduler_post_message(QDF_MODULE_ID_WMA, QDF_MODULE_ID_SME, QDF_MODULE_ID_SME, &sme_msg); - if (!QDF_IS_STATUS_SUCCESS(status)) + if (!QDF_IS_STATUS_SUCCESS(status)) { qdf_mem_free(param); + wma_err("Fail to send vdev del resp"); + } } -/** - * wma_vdev_detach_callback() - send vdev detach response to upper layer - * @ctx: txrx node ptr - * - * Return: none - */ -static void wma_vdev_detach_callback(void *ctx) +QDF_STATUS wma_vdev_detach_callback(struct vdev_delete_response *rsp) { tp_wma_handle wma; - struct wma_txrx_node *iface = (struct wma_txrx_node *)ctx; - struct del_sta_self_params *param; - struct wma_target_req *req_msg; + struct wma_txrx_node *iface = NULL; + struct del_vdev_params *param; wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma || !iface->del_staself_req) { - WMA_LOGE("%s: wma %pK iface %pK", __func__, wma, - iface->del_staself_req); - return; + if (!wma) { + wma_err("wma handle is NULL for VDEV_%d", rsp->vdev_id); + return QDF_STATUS_E_FAILURE; } - param = (struct del_sta_self_params *) iface->del_staself_req; - iface->del_staself_req = NULL; - WMA_LOGD("%s: sending eWNI_SME_DEL_STA_SELF_RSP for vdev %d", - __func__, param->session_id); - if (!wmi_service_enabled(wma->wmi_handle, - wmi_service_sync_delete_cmds)) { - req_msg = wma_find_vdev_req(wma, param->session_id, - WMA_TARGET_REQ_TYPE_VDEV_DEL, - true); - if (req_msg) { - WMA_LOGD("%s: Found vdev request for vdev id %d", - __func__, param->session_id); - qdf_mc_timer_stop(&req_msg->event_timeout); - qdf_mc_timer_destroy(&req_msg->event_timeout); - qdf_mem_free(req_msg); - } + + /* Sanitize the vdev id*/ + if (rsp->vdev_id > wma->max_bssid) { + wma_err("vdev delete response with invalid vdev_id :%d", + rsp->vdev_id); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + iface = &wma->interfaces[rsp->vdev_id]; + + if (!iface->del_staself_req) { + wma_err(" iface handle is NULL for VDEV_%d", rsp->vdev_id); + return QDF_STATUS_E_FAILURE; } + wma_debug("vdev del response received for VDEV_%d", rsp->vdev_id); + param = (struct del_vdev_params *)iface->del_staself_req; + iface->del_staself_req = NULL; + if (iface->roam_scan_stats_req) { struct sir_roam_scan_stats *roam_scan_stats_req = iface->roam_scan_stats_req; @@ -636,100 +494,25 @@ static void wma_vdev_detach_callback(void *ctx) wma_vdev_init(iface); param->status = QDF_STATUS_SUCCESS; - wma_send_del_sta_self_resp(param); -} - - -/** - * wma_self_peer_remove() - Self peer remove handler - * @wma: wma handle - * @del_sta_self_req_param: vdev id - * @generate_vdev_rsp: request type - * - * Return: success if peer delete command sent to firmware, else failure. - */ - -static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle, - struct del_sta_self_params *del_sta_self_req_param, - uint8_t generate_vdev_rsp) -{ - void *peer; - struct cdp_pdev *pdev; - QDF_STATUS qdf_status; - uint8_t peer_id; - uint8_t vdev_id = del_sta_self_req_param->session_id; - struct wma_target_req *msg = NULL; - struct del_sta_self_rsp_params *sta_self_wmi_rsp; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - WMA_LOGD("P2P Device: removing self peer %pM", - del_sta_self_req_param->self_mac_addr); - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - qdf_status = QDF_STATUS_E_FAULT; - goto error; - } - - peer = cdp_peer_find_by_addr(soc, pdev, - del_sta_self_req_param->self_mac_addr, - &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - del_sta_self_req_param->self_mac_addr); - qdf_status = QDF_STATUS_E_FAULT; - goto error; - } - - qdf_status = wma_remove_peer(wma_handle, - del_sta_self_req_param->self_mac_addr, - vdev_id, peer, false); - if (QDF_IS_STATUS_ERROR(qdf_status)) { - WMA_LOGE(FL("wma_remove_peer is failed")); - goto error; - } + wma_send_vdev_del_resp(param); - if (wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_sync_delete_cmds)) { - sta_self_wmi_rsp = - qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params)); - if (!sta_self_wmi_rsp) { - qdf_status = QDF_STATUS_E_NOMEM; - goto error; - } - sta_self_wmi_rsp->self_sta_param = del_sta_self_req_param; - sta_self_wmi_rsp->generate_rsp = generate_vdev_rsp; - msg = wma_fill_hold_req(wma_handle, vdev_id, - WMA_DELETE_STA_REQ, - WMA_DEL_P2P_SELF_STA_RSP_START, - sta_self_wmi_rsp, - WMA_DELETE_STA_TIMEOUT); - if (!msg) { - WMA_LOGE(FL("Failed to allocate request for vdev_id %d"), - vdev_id); - wma_remove_req(wma_handle, vdev_id, - WMA_DEL_P2P_SELF_STA_RSP_START); - qdf_mem_free(sta_self_wmi_rsp); - qdf_status = QDF_STATUS_E_FAILURE; - goto error; - } - } return QDF_STATUS_SUCCESS; -error: - return qdf_status; } static void -wma_cdp_vdev_detach(ol_txrx_soc_handle soc, - tp_wma_handle wma_handle, - uint8_t vdev_id) +wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle, + uint8_t vdev_id) { struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; + struct wlan_objmgr_vdev *vdev = iface->vdev; + + if (!vdev) { + WMA_LOGE(FL("vdev is NULL")); + return; + } - cdp_vdev_detach(soc, - iface->handle, NULL, NULL); - iface->handle = NULL; + if (soc && wlan_vdev_get_id(vdev) != WLAN_INVALID_VDEV_ID) + cdp_vdev_detach(soc, vdev_id, NULL, NULL); } /** @@ -748,6 +531,7 @@ wma_release_vdev_ref(struct wma_txrx_node *iface) vdev = iface->vdev; + iface->vdev_active = false; iface->vdev = NULL; if (vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); @@ -774,170 +558,112 @@ static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma, iface->vdev_active = false; } +/** + * wma_handle_vdev_detach() - wma vdev detach handler + * @wma_handle: pointer to wma handle + * @del_vdev_req_param: pointer to del req param + * + * Return: none. + */ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, - struct del_sta_self_params *del_sta_self_req_param, - uint8_t generate_rsp) + struct del_vdev_params *del_vdev_req_param) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t vdev_id = del_sta_self_req_param->session_id; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint8_t vdev_id = del_vdev_req_param->vdev_id; struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; - struct wma_target_req *msg = NULL; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct vdev_mlme_obj *vdev_mlme; if (!soc) { WMA_LOGE("%s:SOC context is NULL", __func__); - status = QDF_STATUS_E_FAILURE; - goto out; + goto rel_ref; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!vdev_mlme) { + wma_err("Failed to get vdev mlme obj for vdev id %d", + del_vdev_req_param->vdev_id); + goto rel_ref; } if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) wma_handle_monitor_mode_vdev_detach(wma_handle, vdev_id); - status = wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id); + iface->del_staself_req = del_vdev_req_param; + wma_cdp_vdev_detach(soc, wma_handle, vdev_id); + wma_release_vdev_ref(iface); + + status = vdev_mgr_delete_send(vdev_mlme); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("Unable to remove an interface"); goto out; } - WMA_LOGD("vdev_id:%hu vdev_hdl:%pK", vdev_id, iface->handle); - if (!generate_rsp) { - WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id); - goto out; - } - - iface->del_staself_req = del_sta_self_req_param; - msg = wma_fill_vdev_req(wma_handle, vdev_id, WMA_DEL_STA_SELF_REQ, - WMA_TARGET_REQ_TYPE_VDEV_DEL, iface, - WMA_VDEV_DELETE_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d", - __func__, vdev_id); - status = QDF_STATUS_E_NOMEM; - iface->del_staself_req = NULL; - goto out; - } + return status; - /* Acquire wake lock only when you expect a response from firmware */ - if (wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_sync_delete_cmds)) { - wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock, - WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION); - } - WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id); - wma_release_vdev_ref(iface); +rel_ref: wma_cdp_vdev_detach(soc, wma_handle, vdev_id); - - /* - * send the response immediately if WMI_SERVICE_SYNC_DELETE_CMDS - * service is not supported by firmware - */ - if (!wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_sync_delete_cmds)) - wma_vdev_detach_callback(iface); - return status; -out: - WMA_LOGE("Call txrx detach callback for vdev %d, generate_rsp %u", - vdev_id, generate_rsp); wma_release_vdev_ref(iface); - wma_cdp_vdev_detach(soc, wma_handle, vdev_id); - +out: wma_vdev_deinit(iface); qdf_mem_zero(iface, sizeof(*iface)); wma_vdev_init(iface); - - del_sta_self_req_param->status = status; - if (generate_rsp) - wma_send_del_sta_self_resp(del_sta_self_req_param); return status; } /** - * wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR - * @wma_handle: WMA handle - * @iface: wma interface txrx node + * wma_self_peer_remove() - Self peer remove handler + * @wma: wma handle + * @del_vdev_req_param: vdev id + * @generate_vdev_rsp: request type * - * Return: none + * Return: success if peer delete command sent to firmware, else failure. */ -static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, - struct wma_txrx_node *iface) +static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle, + struct del_vdev_params *del_vdev_req) { - struct wlan_objmgr_vdev *vdev; - struct wlan_objmgr_peer *peer = NULL; - struct wlan_objmgr_peer *peer_next = NULL; - qdf_list_t *peer_list; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - if (!iface->vdev) - return; - - /* - * No need to take ref as if iface->vdev is valid then WMA already hold - * ref and this can be used diretly. ALso this API may get called after - * vdev deleted logically so taking ref for vdev will fail and peer - * wont be deleted for the vdev. - */ - vdev = iface->vdev; - - if (iface->handle) - wma_cdp_vdev_detach(soc, wma, wlan_vdev_get_id(vdev)); - - WMA_LOGI("%s: SSR: force cleanup peers in vdev(%d)", __func__, - wlan_vdev_get_id(vdev)); - iface->vdev_active = false; - - peer_list = &vdev->vdev_objmgr.wlan_peer_list; - if (!peer_list) { - WMA_LOGE("%s: peer_list is NULL", __func__); - return; - } + QDF_STATUS qdf_status; + uint8_t vdev_id = del_vdev_req->vdev_id; + struct wma_target_req *msg = NULL; + struct del_sta_self_rsp_params *sta_self_wmi_rsp; - /* - * We get refcount for each peer first, logically delete it and - * then release the refcount so that the peer is physically - * deleted. - */ - peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list, - WLAN_LEGACY_WMA_ID); - while (peer) { - WMA_LOGD("%s: Deleting Peer %pM", - __func__, peer->macaddr); - wlan_objmgr_peer_obj_delete(peer); - peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev, - peer_list, peer, WLAN_LEGACY_WMA_ID); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - peer = peer_next; - } - - /* Force delete all the peers, set the wma interface peer_count to 0 */ - iface->peer_count = 0; -} + wma_debug("P2P Device: removing self peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(del_vdev_req->self_mac_addr)); -static void wma_release_vdev_and_peer_ref(tp_wma_handle wma, - struct wma_txrx_node *iface) -{ - if (!iface) { - WMA_LOGE("iface is NULL"); - return; + qdf_status = wma_remove_peer(wma_handle, del_vdev_req->self_mac_addr, + vdev_id, false); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + wma_err("wma_remove_peer is failed"); + goto error; } - wma_force_objmgr_vdev_peer_cleanup(wma, iface); - wma_release_vdev_ref(iface); -} - -void wma_release_pending_vdev_refs(void) -{ - int i; - tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - - /* validate the wma_handle */ - if (!wma) { - WMA_LOGE("%s: Invalid wma handle", __func__); - return; + if (wmi_service_enabled(wma_handle->wmi_handle, + wmi_service_sync_delete_cmds)) { + sta_self_wmi_rsp = + qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params)); + if (!sta_self_wmi_rsp) { + qdf_status = QDF_STATUS_E_NOMEM; + goto error; + } + sta_self_wmi_rsp->self_sta_param = del_vdev_req; + msg = wma_fill_hold_req(wma_handle, vdev_id, + WMA_DELETE_STA_REQ, + WMA_DEL_P2P_SELF_STA_RSP_START, + sta_self_wmi_rsp, + WMA_DELETE_STA_TIMEOUT); + if (!msg) { + wma_err("Failed to allocate request for vdev_id %d", + vdev_id); + wma_remove_req(wma_handle, vdev_id, + WMA_DEL_P2P_SELF_STA_RSP_START); + qdf_mem_free(sta_self_wmi_rsp); + qdf_status = QDF_STATUS_E_FAILURE; + goto error; + } } - for (i = 0; i < wma->max_bssid; i++) - /* Release peer and vdev ref hold by wma if not already done */ - wma_release_vdev_and_peer_ref(wma, &wma->interfaces[i]); +error: + return qdf_status; } static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype) @@ -968,20 +694,23 @@ static void wma_remove_objmgr_peer(tp_wma_handle wma, uint8_t vdev_id, { struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_peer *obj_peer; + struct wlan_objmgr_vdev *obj_vdev; struct wlan_objmgr_pdev *obj_pdev; uint8_t pdev_id = 0; psoc = wma->psoc; if (!psoc) { - wma_err("psoc is NULL"); + WMA_LOGE("%s:PSOC is NULL", __func__); return; } - obj_pdev = wma->pdev; - if (!obj_pdev) { - wma_err("pdev is NULL"); + + obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_LEGACY_WMA_ID); + if (!obj_vdev) { + WMA_LOGE("Obj vdev not found. Unable to remove peer"); return; } - + obj_pdev = wlan_vdev_get_pdev(obj_vdev); pdev_id = wlan_objmgr_pdev_get_pdev_id(obj_pdev); obj_peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_addr, WLAN_LEGACY_WMA_ID); @@ -990,99 +719,117 @@ static void wma_remove_objmgr_peer(tp_wma_handle wma, uint8_t vdev_id, /* Unref to decrement ref happened in find_peer */ wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID); } else { - wma_err("Peer %pM not found", peer_addr); + WMA_LOGE("Peer "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_addr)); } + + wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID); } -/** - * wma_vdev_detach() - send vdev delete command to fw - * @wma_handle: wma handle - * @pdel_sta_self_req_param: del sta params - * @generateRsp: generate Response flag - * - * Return: QDF status - */ -QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, - struct del_sta_self_params *pdel_sta_self_req_param, - uint8_t generateRsp) +static QDF_STATUS wma_check_for_deffered_peer_delete(tp_wma_handle wma_handle, + struct del_vdev_params + *pdel_vdev_req_param) { QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t vdev_id = pdel_sta_self_req_param->session_id; + uint8_t vdev_id = pdel_vdev_req_param->vdev_id; struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; - struct wma_target_req *req_msg; + uint32_t vdev_stop_type; - if (!iface->handle) { - WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed", - vdev_id); - goto send_rsp; - } + if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) { + status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("Failed to get wma req msg_type for vdev_id: %d", + vdev_id); + status = QDF_STATUS_E_INVAL; + return status; + } - /* - * In SSR case or if FW is down we only need to clean up the host. - * There is no need to destroy vdev in firmware since it - * has already asserted. - * Cleanup the ObjMgr Peers for the current vdev and detach the - * CDP Vdev. - */ - if (!cds_is_target_ready()) { - wma_release_vdev_and_peer_ref(wma_handle, iface); - goto send_rsp; - } + if (vdev_stop_type != WMA_DELETE_BSS_REQ) { + status = QDF_STATUS_E_INVAL; + return status; + } - if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) { - req_msg = wma_find_vdev_req(wma_handle, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP, false); - if (!req_msg) - goto send_fail_rsp; - if (req_msg->msg_type != WMA_DELETE_BSS_REQ) - goto send_fail_rsp; - WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion", - vdev_id); - iface->del_staself_req = pdel_sta_self_req_param; + wma_debug("BSS is not yet stopped. Defering vdev(vdev id %x) deletion", + vdev_id); + iface->del_staself_req = pdel_vdev_req_param; iface->is_del_sta_defered = true; - return status; } - iface->is_del_sta_defered = false; + + return status; +} + +static QDF_STATUS wma_vdev_self_peer_delete(tp_wma_handle wma_handle, + struct del_vdev_params + *pdel_vdev_req_param) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t vdev_id = pdel_vdev_req_param->vdev_id; + struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; if (wma_vdev_uses_self_peer(iface->type, iface->sub_type)) { - status = wma_self_peer_remove(wma_handle, - pdel_sta_self_req_param, generateRsp); - if ((status != QDF_STATUS_SUCCESS) && generateRsp) { - WMA_LOGE("can't remove selfpeer, send rsp session: %d", - vdev_id); + status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("can't remove selfpeer, send rsp session: %d", + vdev_id); status = wma_handle_vdev_detach(wma_handle, - pdel_sta_self_req_param, - generateRsp); + pdel_vdev_req_param); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("Trigger recovery for vdev %d", - vdev_id); + wma_err("Trigger recovery for vdev %d", + vdev_id); cds_trigger_recovery(QDF_REASON_UNSPECIFIED); } return status; - } else if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("can't remove selfpeer, free msg session: %d", - vdev_id); - qdf_mem_free(pdel_sta_self_req_param); - pdel_sta_self_req_param = NULL; - return status; - } - if (!wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_sync_delete_cmds)) - status = wma_handle_vdev_detach(wma_handle, - pdel_sta_self_req_param, generateRsp); - } else { - if (iface->type == WMI_VDEV_TYPE_STA) { - wma_remove_objmgr_peer(wma_handle, vdev_id, - pdel_sta_self_req_param->self_mac_addr); } - status = wma_handle_vdev_detach(wma_handle, - pdel_sta_self_req_param, generateRsp); + } else if (iface->type == WMI_VDEV_TYPE_STA) { + wma_remove_objmgr_peer(wma_handle, vdev_id, + pdel_vdev_req_param->self_mac_addr); + } + + return status; +} + +QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, + struct del_vdev_params *pdel_vdev_req_param) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t vdev_id = pdel_vdev_req_param->vdev_id; + struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; + + if (!iface->vdev) { + WMA_LOGE("vdev %d is NULL", vdev_id); + goto send_rsp; + } + + status = wma_check_for_deffered_peer_delete(wma_handle, + pdel_vdev_req_param); + if (QDF_IS_STATUS_ERROR(status)) + goto send_fail_rsp; + + if (iface->is_del_sta_defered) + return status; + + iface->is_del_sta_defered = false; + + status = wma_vdev_self_peer_delete(wma_handle, pdel_vdev_req_param); + + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("Failed to send self peer delete:%d", status); + goto send_rsp; } - if (QDF_IS_STATUS_SUCCESS(status) && - iface->type != WMI_VDEV_TYPE_MONITOR) + if (iface->type != WMI_VDEV_TYPE_MONITOR) iface->vdev_active = false; + if (!wma_vdev_uses_self_peer(iface->type, iface->sub_type) || + !wmi_service_enabled(wma_handle->wmi_handle, + wmi_service_sync_delete_cmds)) { + status = wma_handle_vdev_detach(wma_handle, + pdel_vdev_req_param); + } + + if (QDF_IS_STATUS_ERROR(status)) + goto send_rsp; + return status; send_fail_rsp: @@ -1091,13 +838,9 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, status = QDF_STATUS_E_FAILURE; send_rsp: - if (generateRsp) { - pdel_sta_self_req_param->status = status; - wma_send_del_sta_self_resp(pdel_sta_self_req_param); - } else { - qdf_mem_free(pdel_sta_self_req_param); - pdel_sta_self_req_param = NULL; - } + pdel_vdev_req_param->status = status; + wma_send_vdev_del_resp(pdel_vdev_req_param); + return status; } @@ -1110,105 +853,108 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, * Return: none */ static void wma_send_start_resp(tp_wma_handle wma, - tpAddBssParams add_bss, - wmi_vdev_start_response_event_fixed_param * - resp_event) + struct add_bss_rsp *add_bss_rsp, + struct vdev_start_response *rsp) { - struct wma_txrx_node *iface = &wma->interfaces[resp_event->vdev_id]; + struct wma_txrx_node *iface = &wma->interfaces[rsp->vdev_id]; + QDF_STATUS status; - if (!resp_event->status && QDF_IS_STATUS_SUCCESS(add_bss->status)) { - add_bss->status = + if (QDF_IS_STATUS_SUCCESS(rsp->status) && + QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { + status = wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_START_RESP, - sizeof(*add_bss), add_bss); - if (QDF_IS_STATUS_SUCCESS(add_bss->status)) + sizeof(*add_bss_rsp), + add_bss_rsp); + if (QDF_IS_STATUS_SUCCESS(status)) return; + + add_bss_rsp->status = status; } /* Send vdev stop if vdev start was success */ - if (QDF_IS_STATUS_ERROR(add_bss->status) && - !resp_event->status) { + if (QDF_IS_STATUS_ERROR(add_bss_rsp->status) && + QDF_IS_STATUS_SUCCESS(rsp->status)) { wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_DOWN, - sizeof(*add_bss), add_bss); + sizeof(*add_bss_rsp), + add_bss_rsp); return; } - wma_remove_peer_on_add_bss_failure(add_bss); + wma_remove_bss_peer_on_vdev_start_failure(wma, rsp->vdev_id); WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"), - resp_event->vdev_id, add_bss->status); - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); + rsp->vdev_id, add_bss_rsp->status); + lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp); } /** * wma_vdev_start_rsp() - send vdev start response to upper layer * @wma: wma handle - * @add_bss: add bss params + * @vdev: vdev * @resp_event: response params * * Return: none */ -static void wma_vdev_start_rsp(tp_wma_handle wma, - tpAddBssParams add_bss, - wmi_vdev_start_response_event_fixed_param * - resp_event) +static void wma_vdev_start_rsp(tp_wma_handle wma, struct wlan_objmgr_vdev *vdev, + struct vdev_start_response *rsp) { struct beacon_info *bcn; + enum QDF_OPMODE opmode; + struct add_bss_rsp *add_bss_rsp; + + opmode = wlan_vdev_mlme_get_opmode(vdev); + + add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp)); + if (!add_bss_rsp) + return; + + add_bss_rsp->vdev_id = rsp->vdev_id; + add_bss_rsp->status = rsp->status; + add_bss_rsp->chain_mask = rsp->chain_mask; + add_bss_rsp->smps_mode = host_map_smps_mode(rsp->smps_mode); #ifdef QCA_IBSS_SUPPORT WMA_LOGD("%s: vdev start response received for %s mode", __func__, - add_bss->operMode == - BSS_OPERATIONAL_MODE_IBSS ? "IBSS" : "non-IBSS"); + opmode == QDF_IBSS_MODE ? "IBSS" : "non-IBSS"); #endif /* QCA_IBSS_SUPPORT */ - if (resp_event->status) { - add_bss->status = QDF_STATUS_E_FAILURE; + if (rsp->status) goto send_fail_resp; - } - if ((add_bss->operMode == BSS_OPERATIONAL_MODE_AP) + if ((opmode == QDF_P2P_GO_MODE) || + (opmode == QDF_SAP_MODE) #ifdef QCA_IBSS_SUPPORT - || (add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS) + || (opmode == QDF_IBSS_MODE) #endif /* QCA_IBSS_SUPPORT */ ) { - wma->interfaces[resp_event->vdev_id].beacon = + wma->interfaces[rsp->vdev_id].beacon = qdf_mem_malloc(sizeof(struct beacon_info)); - bcn = wma->interfaces[resp_event->vdev_id].beacon; + bcn = wma->interfaces[rsp->vdev_id].beacon; if (!bcn) { - add_bss->status = QDF_STATUS_E_NOMEM; + add_bss_rsp->status = QDF_STATUS_E_NOMEM; goto send_fail_resp; } bcn->buf = qdf_nbuf_alloc(NULL, SIR_MAX_BEACON_SIZE, 0, sizeof(uint32_t), 0); if (!bcn->buf) { qdf_mem_free(bcn); - add_bss->status = QDF_STATUS_E_FAILURE; + add_bss_rsp->status = QDF_STATUS_E_FAILURE; goto send_fail_resp; } bcn->seq_no = MIN_SW_SEQ; qdf_spinlock_create(&bcn->lock); - qdf_atomic_set(&wma->interfaces[resp_event->vdev_id].bss_status, + qdf_atomic_set(&wma->interfaces[rsp->vdev_id].bss_status, WMA_BSS_STATUS_STARTED); WMA_LOGD("%s: AP mode (type %d subtype %d) BSS is started", - __func__, wma->interfaces[resp_event->vdev_id].type, - wma->interfaces[resp_event->vdev_id].sub_type); - - WMA_LOGD("%s: Allocated beacon struct %pK, template memory %pK", - __func__, bcn, bcn->buf); + __func__, wma->interfaces[rsp->vdev_id].type, + wma->interfaces[rsp->vdev_id].sub_type); } - add_bss->status = QDF_STATUS_SUCCESS; - add_bss->bss_idx = resp_event->vdev_id; - add_bss->chainMask = resp_event->chain_mask; - if ((2 != resp_event->cfgd_rx_streams) || - (2 != resp_event->cfgd_tx_streams)) { - add_bss->nss = 1; - } - add_bss->smpsMode = host_map_smps_mode(resp_event->smps_mode); send_fail_resp: - wma_send_start_resp(wma, add_bss, resp_event); + wma_send_start_resp(wma, add_bss_rsp, rsp); } #ifdef FEATURE_AP_MCC_CH_AVOIDANCE @@ -1269,30 +1015,23 @@ static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add) * wma_handle_hidden_ssid_restart() - handle hidden ssid restart * @wma: wma handle * @iface: interfcae pointer - * @req: target req * * Return: none */ static void wma_handle_hidden_ssid_restart(tp_wma_handle wma, - struct wma_txrx_node *iface, - struct wma_target_req *req) + struct wma_txrx_node *iface) { - tpHalHiddenSsidVdevRestart hidden_ssid_restart = - (tpHalHiddenSsidVdevRestart)req->user_data; - WMA_LOGE("%s: vdev restart event recevied for hidden ssid set using IOCTL", - __func__); - wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_RESTART_RESP, - sizeof(*hidden_ssid_restart), - hidden_ssid_restart); + 0, NULL); } -static void wma_sap_peer_send_phymode(struct wlan_objmgr_vdev *vdev, - void *object, void *arg) +static void wma_peer_send_phymode(struct wlan_objmgr_vdev *vdev, + void *object, void *arg) { struct wlan_objmgr_peer *peer = object; enum wlan_phymode old_peer_phymode; + struct wlan_channel *vdev_chan; enum wlan_phymode new_phymode; tSirNwType nw_type; uint32_t fw_phymode; @@ -1300,7 +1039,6 @@ static void wma_sap_peer_send_phymode(struct wlan_objmgr_vdev *vdev, tp_wma_handle wma; uint8_t *peer_mac_addr; uint8_t vdev_id; - struct wma_txrx_node *intr; if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF) return; @@ -1312,29 +1050,31 @@ static void wma_sap_peer_send_phymode(struct wlan_objmgr_vdev *vdev, return; } - intr = wma->interfaces; old_peer_phymode = wlan_peer_get_phymode(peer); - vdev_id = wlan_vdev_get_id(vdev); + vdev_chan = wlan_vdev_mlme_get_des_chan(vdev); peer_mac_addr = wlan_peer_get_macaddr(peer); - if (WLAN_REG_IS_24GHZ_CH_FREQ(intr[vdev_id].mhz)) { - if (intr[vdev_id].chanmode == WMI_HOST_MODE_11B) + if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) { + if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B || + old_peer_phymode == WLAN_PHYMODE_11B) nw_type = eSIR_11B_NW_TYPE; else nw_type = eSIR_11G_NW_TYPE; } else { nw_type = eSIR_11A_NW_TYPE; } - fw_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER, - IS_WLAN_PHYMODE_HT(old_peer_phymode), - intr[vdev_id].chan_width, - IS_WLAN_PHYMODE_VHT(old_peer_phymode), - IS_WLAN_PHYMODE_HE(old_peer_phymode)); + new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER, + IS_WLAN_PHYMODE_HT(old_peer_phymode), + vdev_chan->ch_width, + IS_WLAN_PHYMODE_VHT(old_peer_phymode), + IS_WLAN_PHYMODE_HE(old_peer_phymode)); - new_phymode = wma_fw_to_host_phymode(fw_phymode); wlan_peer_set_phymode(peer, new_phymode); + fw_phymode = wma_host_to_fw_phymode(new_phymode); + vdev_id = wlan_vdev_get_id(vdev); + wma_set_peer_param(wma, peer_mac_addr, WMI_PEER_PHYMODE, fw_phymode, vdev_id); @@ -1343,262 +1083,286 @@ static void wma_sap_peer_send_phymode(struct wlan_objmgr_vdev *vdev, wma_set_peer_param(wma, peer_mac_addr, WMI_PEER_CHWIDTH, max_ch_width_supported, vdev_id); - wma_debug("old phymode %d new phymode %d bw %d macaddr "QDF_MAC_ADDR_STR, - old_peer_phymode, new_phymode, max_ch_width_supported, - QDF_MAC_ADDR_ARRAY(peer_mac_addr)); + wma_debug("FW phymode %d old phymode %d new phymode %d bw %d macaddr "QDF_MAC_ADDR_FMT, + fw_phymode, old_peer_phymode, new_phymode, + max_ch_width_supported, QDF_MAC_ADDR_REF(peer_mac_addr)); } -static void -wma_update_peer_phymode_sap(struct wlan_objmgr_vdev *vdev) +static +void wma_update_rate_flags_after_vdev_restart(tp_wma_handle wma, + struct wma_txrx_node *iface) { - wlan_objmgr_iterate_peerobj_list(vdev, - wma_sap_peer_send_phymode, - NULL, - WLAN_LEGACY_WMA_ID); + struct vdev_mlme_obj *vdev_mlme; + enum tx_rate_info rate_flags = 0; + enum wlan_phymode bss_phymode; + struct wlan_channel *des_chan; + + if (iface->type != WMI_VDEV_TYPE_STA) + return; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!vdev_mlme) + return; + + des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev); + bss_phymode = des_chan->ch_phymode; + + if (IS_WLAN_PHYMODE_HE(bss_phymode)) { + rate_flags = wma_get_he_rate_flags(des_chan->ch_width); + } else if (IS_WLAN_PHYMODE_VHT(bss_phymode)) { + rate_flags = wma_get_vht_rate_flags(des_chan->ch_width); + } else if (IS_WLAN_PHYMODE_HT(bss_phymode)) { + rate_flags = wma_get_ht_rate_flags(des_chan->ch_width); + } else { + rate_flags = TX_RATE_LEGACY; + } + + wma_debug("bss phymode %d rate_flags %x, ch_width %d", + bss_phymode, rate_flags, des_chan->ch_width); + ucfg_mc_cp_stats_set_rate_flags(iface->vdev, rate_flags); } -/** - * wma_handle_channel_switch_resp() - handle channel switch resp - * @wma: wma handle - * @resp_event: response from firmware - * @req: target req - * - * Return: QDF_STATUS - */ -static QDF_STATUS -wma_handle_channel_switch_resp(tp_wma_handle wma, - wmi_vdev_start_response_event_fixed_param - *resp_event, - struct wma_target_req *req) +QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma, + struct vdev_start_response *rsp) { enum wlan_vdev_sm_evt event; struct wma_txrx_node *iface; - tpSwitchChannelParams params = (tpSwitchChannelParams) req->user_data; - - if (!params) { - WMA_LOGE("%s: channel switch params is NULL for vdev %d", - __func__, resp_event->vdev_id); - policy_mgr_set_do_hw_mode_change_flag(wma->psoc, false); - return QDF_STATUS_E_FAILURE; - } - iface = &wma->interfaces[resp_event->vdev_id]; + iface = &wma->interfaces[rsp->vdev_id]; WMA_LOGD("%s: Send channel switch resp vdev %d status %d", - __func__, resp_event->vdev_id, resp_event->status); - params->chainMask = resp_event->chain_mask; - if ((resp_event->cfgd_rx_streams != 2) || - (resp_event->cfgd_tx_streams != 2)) - params->nss = 1; - - params->smpsMode = host_map_smps_mode(resp_event->smps_mode); - params->status = resp_event->status; + __func__, rsp->vdev_id, rsp->status); /* Indicate channel switch failure to LIM */ - if (QDF_IS_STATUS_ERROR(params->status) && + if (QDF_IS_STATUS_ERROR(rsp->status) && (iface->type == WMI_VDEV_TYPE_MONITOR || - wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) || + wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) || mlme_is_chan_switch_in_progress(iface->vdev))) { mlme_set_chan_switch_in_progress(iface->vdev, false); - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - (void *)params, 0); + lim_process_switch_channel_rsp(wma->mac_context, rsp); return QDF_STATUS_SUCCESS; } - if (QDF_IS_STATUS_SUCCESS(resp_event->status) && - iface->type == WMI_VDEV_TYPE_AP && - resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) - wma_update_peer_phymode_sap(iface->vdev); - - if ((QDF_IS_STATUS_SUCCESS(resp_event->status) && - (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) && - ((iface->type == WMI_VDEV_TYPE_STA) || - (iface->type == WMI_VDEV_TYPE_MONITOR))) || - ((resp_event->resp_type == WMI_VDEV_START_RESP_EVENT) && - (iface->type == WMI_VDEV_TYPE_MONITOR))) { - wmi_host_channel_width chanwidth; - int err; - - /* for CSA case firmware expects phymode before ch_wd */ - err = wma_set_peer_param(wma, iface->bssid, - WMI_PEER_PHYMODE, iface->chanmode, - resp_event->vdev_id); - chanwidth = wmi_get_ch_width_from_phy_mode(wma->wmi_handle, - iface->chanmode); - err = wma_set_peer_param(wma, iface->bssid, WMI_PEER_CHWIDTH, - chanwidth, resp_event->vdev_id); - wma_debug("vdev_id %d chanwidth %d chanmode %d", - resp_event->vdev_id, chanwidth, - iface->chanmode); - } - - if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) || + if (QDF_IS_STATUS_SUCCESS(rsp->status) && + rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT) { + wlan_objmgr_iterate_peerobj_list(iface->vdev, + wma_peer_send_phymode, NULL, + WLAN_LEGACY_WMA_ID); + wma_update_rate_flags_after_vdev_restart(wma, iface); + } + + if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) || mlme_is_chan_switch_in_progress(iface->vdev)) event = WLAN_VDEV_SM_EV_RESTART_RESP; else event = WLAN_VDEV_SM_EV_START_RESP; wlan_vdev_mlme_sm_deliver_evt(iface->vdev, event, - sizeof(*params), params); + sizeof(rsp), rsp); return QDF_STATUS_SUCCESS; } -/** - * wma_vdev_start_resp_handler() - vdev start response handler - * @handle: wma handle - * @cmd_param_info: event buffer - * @len: buffer length +/* + * wma_get_ratemask_type() - convert user input ratemask type to FW type + * @type: User input ratemask type maintained in HDD + * @fwtype: Value return arg for fw ratemask type value * - * Return: 0 for success or error code + * Return: FW configurable ratemask type */ -int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len) +static QDF_STATUS wma_get_ratemask_type(enum wlan_mlme_ratemask_type type, + uint8_t *fwtype) { - tp_wma_handle wma = (tp_wma_handle) handle; - WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; - wmi_vdev_start_response_event_fixed_param *resp_event; - struct wma_target_req *req_msg; + switch (type) { + case WLAN_MLME_RATEMASK_TYPE_CCK: + *fwtype = WMI_RATEMASK_TYPE_CCK; + break; + case WLAN_MLME_RATEMASK_TYPE_HT: + *fwtype = WMI_RATEMASK_TYPE_HT; + break; + case WLAN_MLME_RATEMASK_TYPE_VHT: + *fwtype = WMI_RATEMASK_TYPE_VHT; + break; + case WLAN_MLME_RATEMASK_TYPE_HE: + *fwtype = WMI_RATEMASK_TYPE_HE; + break; + default: + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, + struct vdev_start_response *rsp) +{ + tp_wma_handle wma; struct wma_txrx_node *iface; - struct vdev_up_params param = {0}; target_resource_config *wlan_res_cfg; - struct wlan_objmgr_psoc *psoc = wma->psoc; - struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_psoc *psoc; #ifdef FEATURE_AP_MCC_CH_AVOIDANCE struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); #endif QDF_STATUS status; + enum vdev_assoc_type assoc_type = VDEV_ASSOC; + struct vdev_mlme_obj *mlme_obj; + struct wlan_mlme_psoc_ext_obj *mlme_psoc_obj; + const struct wlan_mlme_ratemask *ratemask_cfg; + struct config_ratemask_params rparams = {0}; + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + wma_err("wma wma is NULL for VDEV_%d", rsp->vdev_id); + return QDF_STATUS_E_FAILURE; + } + psoc = wma->psoc; if (!psoc) { WMA_LOGE("%s: psoc is NULL", __func__); - return -EINVAL; + return QDF_STATUS_E_FAILURE; } + mlme_psoc_obj = mlme_get_psoc_ext_obj(psoc); + ratemask_cfg = &mlme_psoc_obj->cfg.ratemask_cfg; + #ifdef FEATURE_AP_MCC_CH_AVOIDANCE if (!mac_ctx) { WMA_LOGE("%s: Failed to get mac_ctx", __func__); - policy_mgr_set_do_hw_mode_change_flag( - psoc, false); - return -EINVAL; + return QDF_STATUS_E_FAILURE; } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ wlan_res_cfg = lmac_get_tgt_res_cfg(psoc); if (!wlan_res_cfg) { WMA_LOGE("%s: Wlan resource config is NULL", __func__); - return -EINVAL; + return QDF_STATUS_E_FAILURE; } - param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info; - if (!param_buf) { - WMA_LOGE("Invalid start response event buffer"); - policy_mgr_set_do_hw_mode_change_flag( - wma->psoc, false); - return -EINVAL; + if (rsp->vdev_id >= wma->max_bssid) { + WMA_LOGE("Invalid vdev id received from firmware"); + return QDF_STATUS_E_FAILURE; } - resp_event = param_buf->fixed_param; - if (!resp_event) { - WMA_LOGE("Invalid start response event buffer"); - policy_mgr_set_do_hw_mode_change_flag( - wma->psoc, false); - return -EINVAL; + if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) + tgt_dfs_radar_enable(wma->pdev, 0, 0, true); + + iface = &wma->interfaces[rsp->vdev_id]; + if (!iface->vdev) { + wma_err("Invalid vdev"); + return QDF_STATUS_E_FAILURE; } - if (resp_event->vdev_id >= wma->max_bssid) { - WMA_LOGE("Invalid vdev id received from firmware"); - return -EINVAL; - } - - if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) - tgt_dfs_radar_enable(wma->pdev, 0, 0, true); + if (rsp->status == QDF_STATUS_SUCCESS) { + wma->interfaces[rsp->vdev_id].tx_streams = + rsp->cfgd_tx_streams; - if (resp_event->status == QDF_STATUS_SUCCESS) { - wma->interfaces[resp_event->vdev_id].tx_streams = - resp_event->cfgd_tx_streams; - wma->interfaces[resp_event->vdev_id].rx_streams = - resp_event->cfgd_rx_streams; - wma->interfaces[resp_event->vdev_id].chain_mask = - resp_event->chain_mask; if (wlan_res_cfg->use_pdev_id) { - if (resp_event->pdev_id == WMI_PDEV_ID_SOC) { - WMA_LOGE("%s: soc level id received for mac id", - __func__); - return -EINVAL; + if (rsp->mac_id == OL_TXRX_PDEV_ID) { + wma_err("soc level id received for mac id"); + return -QDF_STATUS_E_INVAL; } - wma->interfaces[resp_event->vdev_id].mac_id = - WMA_PDEV_TO_MAC_MAP(resp_event->pdev_id); + wma->interfaces[rsp->vdev_id].mac_id = + WMA_PDEV_TO_MAC_MAP(rsp->mac_id); } else { - wma->interfaces[resp_event->vdev_id].mac_id = - resp_event->mac_id; + wma->interfaces[rsp->vdev_id].mac_id = + rsp->mac_id; } WMA_LOGD("%s: vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d", __func__, - resp_event->vdev_id, - wma->interfaces[resp_event->vdev_id].tx_streams, - wma->interfaces[resp_event->vdev_id].rx_streams, - wma->interfaces[resp_event->vdev_id].chain_mask, - wma->interfaces[resp_event->vdev_id].mac_id); - } - - iface = &wma->interfaces[resp_event->vdev_id]; - mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); - if (!mlme_obj) - return -EINVAL; - mlme_obj->mgmt.generic.tx_pwrlimit = resp_event->max_allowed_tx_power; - req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START, - true); + rsp->vdev_id, + rsp->cfgd_tx_streams, + rsp->cfgd_rx_streams, + rsp->chain_mask, + wma->interfaces[rsp->vdev_id].mac_id); - if (!req_msg) { - WMA_LOGE("%s: Failed to lookup request message for vdev %d", - __func__, resp_event->vdev_id); - policy_mgr_set_do_hw_mode_change_flag(wma->psoc, false); - return -EINVAL; + /* Fill bss_chan after vdev start */ + qdf_mem_copy(iface->vdev->vdev_mlme.bss_chan, + iface->vdev->vdev_mlme.des_chan, + sizeof(struct wlan_channel)); } - qdf_mc_timer_stop(&req_msg->event_timeout); - - if (wma_get_hidden_ssid_restart_in_progress(iface) && - wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) && - (req_msg->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART)) - wma_handle_hidden_ssid_restart(wma, iface, req_msg); #ifdef FEATURE_AP_MCC_CH_AVOIDANCE - if (resp_event->status == QDF_STATUS_SUCCESS + if (rsp->status == QDF_STATUS_SUCCESS && mac_ctx->sap.sap_channel_avoidance) - wma_find_mcc_ap(wma, resp_event->vdev_id, true); + wma_find_mcc_ap(wma, rsp->vdev_id, true); #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - if (req_msg->msg_type == WMA_CHNL_SWITCH_REQ) { + if (wma_get_hidden_ssid_restart_in_progress(iface) && + wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) { + wma_handle_hidden_ssid_restart(wma, iface); + return QDF_STATUS_SUCCESS; + } + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power; + if (iface->type == WMI_VDEV_TYPE_STA) + assoc_type = mlme_get_assoc_type(vdev_mlme->vdev); + + if (mlme_is_chan_switch_in_progress(iface->vdev) || + iface->type == WMI_VDEV_TYPE_MONITOR || + (iface->type == WMI_VDEV_TYPE_STA && + (assoc_type == VDEV_ASSOC || assoc_type == VDEV_REASSOC))) { status = wma_handle_channel_switch_resp(wma, - resp_event, req_msg); + rsp); if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; - } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) { - tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data; - - qdf_mem_copy(iface->bssid, bssParams->bssId, - QDF_MAC_ADDR_SIZE); - wma_vdev_start_rsp(wma, bssParams, resp_event); - } else if (req_msg->msg_type == WMA_OCB_SET_CONFIG_CMD) { - param.vdev_id = resp_event->vdev_id; - param.assoc_id = iface->aid; - if (wma_send_vdev_up_to_fw(wma, ¶m, iface->bssid) != - QDF_STATUS_SUCCESS) { + return QDF_STATUS_E_FAILURE; + } else if (iface->type == WMI_VDEV_TYPE_OCB) { + mlme_obj->proto.sta.assoc_id = iface->aid; + if (vdev_mgr_up_send(mlme_obj) != QDF_STATUS_SUCCESS) { WMA_LOGE(FL("failed to send vdev up")); - policy_mgr_set_do_hw_mode_change_flag( - wma->psoc, false); - return -EEXIST; + return QDF_STATUS_E_FAILURE; } ucfg_ocb_config_channel(wma->pdev); + } else { + struct qdf_mac_addr bss_peer; + + status = + mlme_get_vdev_bss_peer_mac_addr(iface->vdev, &bss_peer); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get bssid", __func__); + return QDF_STATUS_E_INVAL; + } + qdf_mem_copy(mlme_obj->mgmt.generic.bssid, bss_peer.bytes, + QDF_MAC_ADDR_SIZE); + wma_vdev_start_rsp(wma, vdev_mlme->vdev, rsp); } - if ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) && - wma_is_vdev_up(resp_event->vdev_id)) - wma_set_sap_keepalive(wma, resp_event->vdev_id); + if (iface->type == WMI_VDEV_TYPE_AP && wma_is_vdev_up(rsp->vdev_id)) + wma_set_sap_keepalive(wma, rsp->vdev_id); - qdf_mc_timer_destroy(&req_msg->event_timeout); - qdf_mem_free(req_msg); + /* Send ratemask to firmware */ + if ((ratemask_cfg->type > WLAN_MLME_RATEMASK_TYPE_NO_MASK) && + (ratemask_cfg->type < WLAN_MLME_RATEMASK_TYPE_MAX)) { + struct wmi_unified *wmi_handle = wma->wmi_handle; - return 0; + if (!wmi_handle) { + wma_err(FL("wmi_handle is null")); + return QDF_STATUS_E_INVAL; + } + + rparams.vdev_id = rsp->vdev_id; + status = wma_get_ratemask_type(ratemask_cfg->type, + &rparams.type); + + if (QDF_IS_STATUS_ERROR(status)) { + wma_err(FL("unable to map ratemask")); + /* don't fail, default rates will still work */ + return QDF_STATUS_SUCCESS; + } + + rparams.lower32 = ratemask_cfg->lower32; + rparams.higher32 = ratemask_cfg->higher32; + rparams.lower32_2 = ratemask_cfg->lower32_2; + rparams.higher32_2 = ratemask_cfg->higher32_2; + + status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle, + &rparams); + /* Only log failure. Do not abort */ + if (QDF_IS_STATUS_ERROR(status)) + wma_err(FL("failed to send ratemask")); + } + + return QDF_STATUS_SUCCESS; } bool wma_is_vdev_valid(uint32_t vdev_id) @@ -1641,7 +1405,7 @@ wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id, return QDF_STATUS_E_INVAL; } - param.if_id = if_id; + param.vdev_id = if_id; param.param_id = param_id; param.param_value = param_value; @@ -1678,16 +1442,19 @@ QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr, { tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx; struct peer_set_params param = {0}; - int err; + QDF_STATUS status; param.vdev_id = vdev_id; param.param_value = param_value; param.param_id = param_id; - err = wmi_set_peer_param_send(wma_handle->wmi_handle, peer_addr, - ¶m); - - return err; + status = wmi_set_peer_param_send(wma_handle->wmi_handle, + peer_addr, + ¶m); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("vdev_id: %d peer set failed, id %d, val %d", + vdev_id, param_id, param_value); + return status; } /** @@ -1802,8 +1569,8 @@ QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id, return qdf_status; } -static bool wma_objmgr_peer_exist(tp_wma_handle wma, uint8_t vdev_id, - uint8_t *peer_addr, uint8_t *peer_vdev_id) +bool wma_objmgr_peer_exist(tp_wma_handle wma, + uint8_t *peer_addr, uint8_t *peer_vdev_id) { struct wlan_objmgr_peer *peer; @@ -1823,34 +1590,29 @@ static bool wma_objmgr_peer_exist(tp_wma_handle wma, uint8_t vdev_id, /** * wma_remove_peer() - remove peer information from host driver and fw * @wma: wma handle - * @bssid: mac address + * @mac_addr: peer mac address, to be removed * @vdev_id: vdev id - * @peer: peer ptr - * @roam_synch_in_progress: roam in progress flag + * @no_fw_peer_delete: If true dont send peer delete to firmware * * Return: QDF_STATUS */ -QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, - uint8_t vdev_id, void *peer, - bool roam_synch_in_progress) +QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, + uint8_t vdev_id, bool no_fw_peer_delete) { #define PEER_ALL_TID_BITMASK 0xffffffff uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK; - uint8_t *peer_addr = bssid; + uint8_t *peer_addr = mac_addr; uint8_t peer_mac[QDF_MAC_ADDR_SIZE] = {0}; struct peer_flush_params param = {0}; - uint8_t *peer_mac_addr; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - void *vdev; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL; bool peer_unmap_conf_support_enabled; uint8_t peer_vdev_id; if (!wma->interfaces[vdev_id].peer_count) { - WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d", - __func__, bssid, vdev_id, + WMA_LOGE("%s: Can't remove peer with peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d", + __func__, QDF_MAC_ADDR_REF(peer_addr), vdev_id, wma->interfaces[vdev_id].peer_count); cds_trigger_recovery(QDF_REASON_UNSPECIFIED); return QDF_STATUS_E_INVAL; @@ -1862,70 +1624,39 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, return QDF_STATUS_E_INVAL; } - if (!peer) { - WMA_LOGE("%s: PEER is NULL for vdev_id: %d", __func__, vdev_id); - QDF_BUG(0); - return QDF_STATUS_E_INVAL; - } - - if (!wma_objmgr_peer_exist(wma, vdev_id, peer_addr, &peer_vdev_id)) { - wma_err("peer doesn't exist peer_addr %pM vdevid %d peer_count %d", - peer_addr, vdev_id, + if (!wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) { + wma_err("peer doesn't exist peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d", + QDF_MAC_ADDR_REF(peer_addr), vdev_id, wma->interfaces[vdev_id].peer_count); return QDF_STATUS_E_INVAL; } if (peer_vdev_id != vdev_id) { - wma_err("peer %pM is on vdev id %d but delete req on vdevid %d peer_count %d", - peer_addr, peer_vdev_id, vdev_id, + wma_err("peer "QDF_MAC_ADDR_FMT" is on vdev id %d but delete req on vdevid %d peer_count %d", + QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id, wma->interfaces[vdev_id].peer_count); return QDF_STATUS_E_INVAL; } peer_unmap_conf_support_enabled = cdp_cfg_get_peer_unmap_conf_support(soc); - peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer); - if (!peer_mac_addr) { - WMA_LOGE("%s: peer mac addr is NULL, Can't remove peer with peer_addr %pM vdevid %d peer_count %d", - __func__, bssid, vdev_id, - wma->interfaces[vdev_id].peer_count); - QDF_BUG(0); - return QDF_STATUS_E_INVAL; - } - if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) - vdev = cdp_get_mon_vdev_from_pdev(soc, pdev); - else - vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id); - if (!vdev) { - WMA_LOGE("%s vdev is null for peer peer->mac_addr %pM", - __func__, peer_mac_addr); - QDF_BUG(0); - return QDF_STATUS_E_INVAL; - } - - cdp_peer_teardown(soc, vdev, peer); + cdp_peer_teardown(soc, vdev_id, peer_addr); - if (roam_synch_in_progress) + if (no_fw_peer_delete) goto peer_detach; + /* Flush all TIDs except MGMT TID for this peer in Target */ peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); param.peer_tid_bitmap = peer_tid_bitmap; param.vdev_id = vdev_id; - if (!wmi_service_enabled(wma->wmi_handle, wmi_service_peer_delete_no_peer_flush_tids_cmd)) - wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid, - ¶m); - - if (wma_is_vdev_in_ibss_mode(wma, vdev_id)) { - WMA_LOGD("%s: bssid %pM peer->mac_addr %pM", __func__, - bssid, peer_mac_addr); - peer_addr = peer_mac_addr; - } + wmi_unified_peer_flush_tids_send(wma->wmi_handle, mac_addr, + ¶m); /* peer->ref_cnt is not visible in WMA */ wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND, - DEBUG_INVALID_PEER_ID, peer_addr, peer, + DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0); qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr, vdev_id); @@ -1938,33 +1669,33 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, } peer_detach: - WMA_LOGD("%s: vdev %pK is detaching %pK with peer_addr %pM vdevid %d peer_count %d", - __func__, vdev, peer, peer_mac_addr, vdev_id, + WMA_LOGD("%s: vdevid %d is detaching with peer_addr "QDF_MAC_ADDR_FMT" peer_count %d", + __func__, vdev_id, QDF_MAC_ADDR_REF(peer_addr), wma->interfaces[vdev_id].peer_count); /* Copy peer mac to find and delete objmgr peer */ - qdf_mem_copy(peer_mac, peer_mac_addr, QDF_MAC_ADDR_SIZE); - if (roam_synch_in_progress && + qdf_mem_copy(peer_mac, peer_addr, QDF_MAC_ADDR_SIZE); + if (no_fw_peer_delete && is_cdp_peer_detach_force_delete_supported(soc)) { if (!peer_unmap_conf_support_enabled) { - WMA_LOGD("%s: LFR3: trigger force delete for peer %pM", - __func__, peer_mac_addr); - cdp_peer_detach_force_delete(soc, peer); + WMA_LOGD("%s: LFR3: trigger force delete for peer "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(peer_addr)); + cdp_peer_detach_force_delete(soc, vdev_id, peer_addr); } else { - cdp_peer_delete_sync(soc, peer, + cdp_peer_delete_sync(soc, vdev_id, peer_addr, wma_peer_unmap_conf_cb, bitmap); } } else { - if (roam_synch_in_progress) { - WMA_LOGD("%s: LFR3: normal peer delete for peer %pM", - __func__, peer_mac_addr); + if (no_fw_peer_delete) { + WMA_LOGD("%s: LFR3: normal peer delete for peer "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(peer_addr)); } if (peer_unmap_conf_support_enabled) - cdp_peer_delete_sync(soc, peer, + cdp_peer_delete_sync(soc, vdev_id, peer_addr, wma_peer_unmap_conf_cb, bitmap); else - cdp_peer_delete(soc, peer, bitmap); + cdp_peer_delete(soc, vdev_id, peer_addr, bitmap); } wma_remove_objmgr_peer(wma, vdev_id, peer_mac); @@ -1975,43 +1706,6 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, return qdf_status; } -/** - * wma_find_duplicate_peer_on_other_vdev() - Find if same peer exist - * on other vdevs - * @wma: wma handle - * @pdev: txrx pdev ptr - * @vdev_id: vdev id of vdev on which the peer - * needs to be added - * @peer_mac: peer mac addr which needs to be added - * - * Check if peer with same MAC is present on vdev other then - * the provided vdev_id - * - * Return: true if same peer is present on vdev other then vdev_id - * else return false - */ -static bool wma_find_duplicate_peer_on_other_vdev(tp_wma_handle wma, - struct cdp_pdev *pdev, uint8_t vdev_id, uint8_t *peer_mac) -{ - int i; - uint8_t peer_id; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - for (i = 0; i < wma->max_bssid; i++) { - /* Need to check vdevs other than the vdev_id */ - if (vdev_id == i || - !wma->interfaces[i].handle) - continue; - if (cdp_peer_find_by_addr_and_vdev(soc, pdev, - wma->interfaces[i].handle, peer_mac, &peer_id)) { - WMA_LOGE("%s :Duplicate peer %pM (peer id %d) already exist on vdev %d", - __func__, peer_mac, peer_id, i); - return true; - } - } - return false; -} - /** * wma_get_peer_type() - Determine the type of peer(eg. STA/AP) and return it * @wma: wma handle @@ -2026,12 +1720,20 @@ static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id, { uint32_t obj_peer_type = 0; + struct wlan_objmgr_vdev *vdev; + uint8_t *addr; + + vdev = wma->interfaces[vdev_id].vdev; + if (!vdev) { + WMA_LOGE("Couldnt find vdev for VDEV_%d", vdev_id); + return obj_peer_type; + } + addr = wlan_vdev_mlme_get_macaddr(vdev); if (wma_peer_type == WMI_PEER_TYPE_TDLS) return WLAN_PEER_TDLS; - if (!qdf_mem_cmp(wma->interfaces[vdev_id].addr, peer_addr, - QDF_MAC_ADDR_SIZE)) { + if (!qdf_mem_cmp(addr, peer_addr, QDF_MAC_ADDR_SIZE)) { obj_peer_type = WLAN_PEER_SELF; } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) { if (wma->interfaces[vdev_id].sub_type == @@ -2074,6 +1776,17 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, struct wlan_objmgr_peer *obj_peer = NULL; struct wlan_objmgr_vdev *obj_vdev = NULL; struct wlan_objmgr_psoc *psoc = wma->psoc; + uint8_t peer_vdev_id; + + /* + * Check if peer with same MAC exist on any Vdev, If so avoid + * adding this peer. + */ + if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) { + wma_info("Peer "QDF_MAC_ADDR_FMT" already exist on vdev %d, current vdev %d", + QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id); + return NULL; + } obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr, wma_peer_type); @@ -2103,8 +1816,6 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, /** * wma_create_peer() - send peer create command to fw * @wma: wma handle - * @pdev: txrx pdev ptr - * @vdev: txrx vdev ptr * @peer_addr: peer mac addr * @peer_type: peer type * @vdev_id: vdev id @@ -2112,19 +1823,18 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, * * Return: QDF status */ -QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, - struct cdp_vdev *vdev, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - uint32_t peer_type, uint8_t vdev_id, - bool roam_synch_in_progress) +QDF_STATUS wma_create_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint32_t peer_type, uint8_t vdev_id, + bool roam_synch_in_progress) { - void *peer = NULL; struct peer_create_params param = {0}; uint8_t *mac_addr_raw; void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); struct wlan_objmgr_psoc *psoc = wma->psoc; target_resource_config *wlan_res_cfg; struct wlan_objmgr_peer *obj_peer = NULL; + QDF_STATUS status; if (!psoc) { WMA_LOGE("%s: psoc is NULL", __func__); @@ -2159,8 +1869,8 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, * Check if peer with same MAC exist on other Vdev, If so avoid * adding this peer, as it will cause FW to crash. */ - if (wma_find_duplicate_peer_on_other_vdev(wma, pdev, - vdev_id, peer_addr)) + if (cdp_find_peer_exist_on_other_vdev(dp_soc, vdev_id, peer_addr, + wma->max_bssid)) goto err; obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type); @@ -2172,21 +1882,23 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, * where the HTT peer map event is received before the peer object * is created in the data path */ - peer = cdp_peer_create(dp_soc, vdev, peer_addr, - (struct cdp_ctrl_objmgr_peer *)obj_peer); - if (!peer) { - WMA_LOGE("%s : Unable to attach peer %pM", __func__, peer_addr); + status = cdp_peer_create(dp_soc, vdev_id, peer_addr); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s : Unable to attach peer "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(peer_addr)); wlan_objmgr_peer_obj_delete(obj_peer); goto err; } - wlan_peer_set_dp_handle(obj_peer, peer); + if (peer_type == WMI_PEER_TYPE_TDLS) + cdp_peer_set_peer_as_tdls(dp_soc, vdev_id, peer_addr, true); if (roam_synch_in_progress) { - WMA_LOGD("%s: LFR3: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d", - __func__, peer, peer_addr, vdev_id, + WMA_LOGD("%s: LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d", + __func__, + QDF_MAC_ADDR_REF(peer_addr), vdev_id, wma->interfaces[vdev_id].peer_count); - cdp_peer_setup(dp_soc, vdev, peer); + cdp_peer_setup(dp_soc, vdev_id, peer_addr); return QDF_STATUS_SUCCESS; } param.peer_addr = peer_addr; @@ -2197,26 +1909,26 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, WMA_LOGE("%s : Unable to create peer in Target", __func__); if (cdp_cfg_get_peer_unmap_conf_support(dp_soc)) cdp_peer_delete_sync( - dp_soc, peer, + dp_soc, vdev_id, peer_addr, wma_peer_unmap_conf_cb, 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); else cdp_peer_delete( - dp_soc, peer, + dp_soc, vdev_id, peer_addr, 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); wlan_objmgr_peer_obj_delete(obj_peer); goto err; } - WMA_LOGD("%s: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d", - __func__, peer, peer_addr, vdev_id, + WMA_LOGD("%s: Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d", + __func__, QDF_MAC_ADDR_REF(peer_addr), vdev_id, wma->interfaces[vdev_id].peer_count); wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND, - DEBUG_INVALID_PEER_ID, peer_addr, peer, 0, 0); - cdp_peer_setup(dp_soc, vdev, peer); + DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0); + cdp_peer_setup(dp_soc, vdev_id, peer_addr); - mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev); + mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev_id); if (!mac_addr_raw) { WMA_LOGE("%s: peer mac addr is NULL", __func__); return QDF_STATUS_E_FAULT; @@ -2231,15 +1943,13 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, if (!key_info) { return QDF_STATUS_E_NOMEM; } - WMA_LOGD("%s: remote ibss peer %pM key clearing\n", __func__, - peer_addr); + WMA_LOGD("%s: remote ibss peer "QDF_MAC_ADDR_FMT" key clearing\n", + __func__, QDF_MAC_ADDR_REF(peer_addr)); qdf_mem_zero(key_info, sizeof(*key_info)); - key_info->smesessionId = vdev_id; + key_info->vdev_id = vdev_id; qdf_mem_copy(key_info->peer_macaddr.bytes, peer_addr, QDF_MAC_ADDR_SIZE); key_info->sendRsp = false; - - wma_set_stakey(wma, key_info); } return QDF_STATUS_SUCCESS; @@ -2248,39 +1958,11 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, return QDF_STATUS_E_FAILURE; } -/** - * wma_cleanup_target_req_param() - free param memory of target request - * @tgt_req: target request params - * - * Return: none - */ -static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req) -{ - WMA_LOGE("%s: Free target req user_data msg_type:%d", __func__, - tgt_req->msg_type); - if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ || - tgt_req->msg_type == WMA_DELETE_BSS_REQ || - tgt_req->msg_type == WMA_ADD_BSS_REQ) { - qdf_mem_free(tgt_req->user_data); - tgt_req->user_data = NULL; - } - - if (tgt_req->msg_type == WMA_SET_LINK_STATE && tgt_req->user_data) { - tpLinkStateParams params = - (tpLinkStateParams) tgt_req->user_data; - qdf_mem_free(params->callbackArg); - params->callbackArg = NULL; - qdf_mem_free(tgt_req->user_data); - tgt_req->user_data = NULL; - } -} - /** * wma_remove_bss_peer() - remove BSS peer * @wma: pointer to WMA handle - * @pdev: pointer to PDEV * @vdev_id: vdev id on which delete BSS request was received - * @params: pointer to Delete BSS params + * @vdev_stop_resp: pointer to Delete BSS response * * This function is called on receiving vdev stop response from FW or * vdev stop response timeout. In case of IBSS/NDI, use vdev's self MAC @@ -2289,42 +1971,38 @@ static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req) * * Return: 0 on success, ERROR code on failure */ -static int wma_remove_bss_peer(tp_wma_handle wma, void *pdev, uint32_t vdev_id, - tpDeleteBssParams params) +static int wma_remove_bss_peer(tp_wma_handle wma, uint32_t vdev_id, + struct del_bss_resp *vdev_stop_resp, + uint8_t type) { - void *peer, *vdev; - uint8_t peer_id; void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint8_t *mac_addr = NULL; struct wma_target_req *del_req; int ret_value = 0; QDF_STATUS qdf_status; - - vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id); - if (!vdev) { - WMA_LOGE(FL("vdev is NULL for vdev_id = %d"), vdev_id); - return -EINVAL; - } + struct qdf_mac_addr bssid; if (wma_is_vdev_in_ibss_mode(wma, vdev_id) || WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) { - mac_addr = cdp_get_vdev_mac_addr(soc, vdev); + mac_addr = cdp_get_vdev_mac_addr(soc, vdev_id); if (!mac_addr) { WMA_LOGE(FL("mac_addr is NULL for vdev_id = %d"), vdev_id); return -EINVAL; } } else { - mac_addr = params->bssid; - } - - peer = cdp_peer_find_by_addr(soc, pdev, mac_addr, &peer_id); - if (!peer) { - WMA_LOGE(FL("peer NULL for vdev_id = %d"), vdev_id); - return -EINVAL; + qdf_status = mlme_get_vdev_bss_peer_mac_addr( + wma->interfaces[vdev_id].vdev, + &bssid); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + WMA_LOGE(FL("Failed to get bssid for vdev_id: %d"), + vdev_id); + return -EINVAL; + } + mac_addr = bssid.bytes; } - qdf_status = wma_remove_peer(wma, mac_addr, vdev_id, peer, false); + qdf_status = wma_remove_peer(wma, mac_addr, vdev_id, false); if (QDF_IS_STATUS_ERROR(qdf_status)) { WMA_LOGE(FL("wma_remove_peer failed vdev_id:%d"), vdev_id); @@ -2337,13 +2015,13 @@ static int wma_remove_bss_peer(tp_wma_handle wma, void *pdev, uint32_t vdev_id, vdev_id); del_req = wma_fill_hold_req(wma, vdev_id, WMA_DELETE_STA_REQ, - WMA_DELETE_PEER_RSP, - params, + type, + vdev_stop_resp, WMA_DELETE_STA_TIMEOUT); if (!del_req) { WMA_LOGE(FL("Failed to allocate request. vdev_id %d"), vdev_id); - params->status = QDF_STATUS_E_NOMEM; + vdev_stop_resp->status = QDF_STATUS_E_NOMEM; ret_value = -EINVAL; } } @@ -2432,44 +2110,33 @@ wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id) {} #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ -void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req) -{ - tpLinkStateParams params = (tpLinkStateParams) req->user_data; - - wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); -} - -void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req) +void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp) { struct wma_txrx_node *iface; struct beacon_info *bcn; - tpDeleteBssParams params; uint8_t vdev_id; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - if (!req) { + if (!resp) { WMA_LOGE("%s req is NULL", __func__); return; } - vdev_id = req->vdev_id; + vdev_id = resp->vdev_id; iface = &wma->interfaces[vdev_id]; - if (!iface->handle) { - WMA_LOGE("%s vdev id %d is already deleted", + + if (!iface->vdev) { + WMA_LOGE("%s vdev id %d iface->vdev is NULL", __func__, vdev_id); - if (req->user_data) - qdf_mem_free(req->user_data); - req->user_data = NULL; + if (resp) + qdf_mem_free(resp); return; } - params = (tpDeleteBssParams)req->user_data; - - cdp_fc_vdev_flush(soc, iface->handle); + cdp_fc_vdev_flush(soc, vdev_id); WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", __func__, vdev_id); - cdp_fc_vdev_unpause(soc, iface->handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); + cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", @@ -2491,37 +2158,45 @@ void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req) * BSS REQ was timed out to stop the VDEV in this case no need * to send response to UMAC */ - if (params->status == QDF_STATUS_FW_MSG_TIMEDOUT) { - qdf_mem_free(req->user_data); - req->user_data = NULL; + if (resp->status == QDF_STATUS_FW_MSG_TIMEDOUT) { + qdf_mem_free(resp); WMA_LOGE("%s: DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)", __func__, vdev_id); } else { - params->status = QDF_STATUS_SUCCESS; + resp->status = QDF_STATUS_SUCCESS; wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, - (void *)params, 0); + (void *)resp, 0); } if (iface->del_staself_req && iface->is_del_sta_defered) { iface->is_del_sta_defered = false; WMA_LOGA("scheduling defered deletion (vdev id %x)", vdev_id); - wma_vdev_detach(wma, iface->del_staself_req, 1); + wma_vdev_detach(wma, iface->del_staself_req); } } -void wma_send_vdev_down(tp_wma_handle wma, struct wma_target_req *req) +void wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *resp) { uint8_t vdev_id; - struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id]; + struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id]; + uint32_t vdev_stop_type; + QDF_STATUS status; - if (!req) { + if (!resp) { WMA_LOGE("%s req is NULL", __func__); return; } - vdev_id = req->vdev_id; - if (req->msg_type != WMA_DELETE_BSS_HO_FAIL_REQ) { + vdev_id = resp->vdev_id; + status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s : Failed to get vdev stop type", __func__); + qdf_mem_free(resp); + return; + } + + if (vdev_stop_type != WMA_DELETE_BSS_HO_FAIL_REQ) { if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) WMA_LOGE("Failed to send vdev down cmd: vdev %d", @@ -2531,66 +2206,106 @@ void wma_send_vdev_down(tp_wma_handle wma, struct wma_target_req *req) } wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_DOWN_COMPLETE, - sizeof(*req), req); + sizeof(*resp), resp); } /** - * wma_send_vdev_down_bss() - handle vdev down req + * wma_send_vdev_down_req() - handle vdev down req * @wma: wma handle - * @req: target req + * @resp: pointer to vde del bss response * * Return: none */ -static void wma_send_vdev_down_bss(tp_wma_handle wma, - struct wma_target_req *req) +static void wma_send_vdev_down_req(tp_wma_handle wma, + struct del_bss_resp *resp) { - struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id]; + struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id]; wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_MLME_DOWN_REQ, - sizeof(*req), req); + sizeof(*resp), resp); +} + +#ifdef WLAN_FEATURE_11W +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ + qdf_mem_zero(&iface->key, sizeof(iface->key)); +} +#else +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ } +#endif +#ifdef WLAN_FEATURE_PKT_CAPTURE /** - * wma_handle_set_link_down_rsp() - handle link down rsp + * wma_set_packet_capture_mode() - set packet capture mode * @wma: wma handle - * @req: target req + * @vdev_id: vdev id + * @val: mode to set * - * Return: none + * Return: 0 on success, errno on failure */ -static void wma_handle_set_link_down_rsp(tp_wma_handle wma, - struct wma_target_req *req) +static int wma_set_packet_capture_mode( + tp_wma_handle wma_handle, + uint8_t vdev_id, + uint8_t val) { - struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id]; + int ret; - wlan_vdev_mlme_sm_deliver_evt(iface->vdev, - WLAN_VDEV_SM_EV_MLME_DOWN_REQ, - sizeof(*req), req); + ret = wma_cli_set_command(vdev_id, + WMI_VDEV_PARAM_PACKET_CAPTURE_MODE, + val, VDEV_CMD); + return ret; } -#ifdef WLAN_FEATURE_11W -static void wma_clear_iface_key(struct wma_txrx_node *iface) +/** + * wma_handle_packet_capture_mode() - handle packet capture mode + * @wma_handle: wma handle + * @vdev_id: vdev id + * @pdev_id: pdev id + * + * Return: none + */ +static void wma_handle_packet_capture_mode( + tp_wma_handle wma_handle, + uint8_t vdev_id, uint8_t pdev_id) { - qdf_mem_zero(&iface->key, sizeof(iface->key)); + QDF_STATUS status = QDF_STATUS_SUCCESS; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + + if (soc && cds_is_pktcapture_enabled() && + wma_handle->is_pktcapture_enabled && + (cds_get_pktcapture_mode() != PKT_CAPTURE_MODE_DISABLE)) { + uint8_t val = cds_get_pktcapture_mode(); + + status = wma_set_packet_capture_mode( + wma_handle, vdev_id, val); + + if (status != QDF_STATUS_SUCCESS) + WMA_LOGE("failed to set capture mode (err=%d)", + status); + else if (status == QDF_STATUS_SUCCESS) + cdp_set_packet_capture_mode(soc, pdev_id, val); + } } #else -static void wma_clear_iface_key(struct wma_txrx_node *iface) +static void wma_handle_packet_capture_mode( + tp_wma_handle wma_handle, + uint8_t vdev_id, uint8_t pdev_id) { } #endif QDF_STATUS -__wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) +__wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event) { tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); - struct wma_target_req *req_msg, *del_req; - struct cdp_pdev *pdev; - void *peer = NULL; - uint8_t peer_id; struct wma_txrx_node *iface; - int status = 0; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - QDF_STATUS qdf_status; + int status = QDF_STATUS_SUCCESS; + struct qdf_mac_addr bssid; + uint32_t vdev_stop_type; + struct del_bss_resp *vdev_stop_resp; if (!wma) { WMA_LOGE("%s: wma is null", __func__); @@ -2616,150 +2331,72 @@ __wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) resp_event->vdev_id); } + status = mlme_get_vdev_bss_peer_mac_addr(iface->vdev, &bssid); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get bssid", __func__); + return QDF_STATUS_E_INVAL; + } + /* Clear key information */ wma_clear_iface_key(iface); - qdf_runtime_pm_allow_suspend( - &iface->vdev_stop_runtime_wakelock); - wma_release_wakelock(&iface->vdev_stop_wakelock); - - req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP, true); - if (!req_msg) { - WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d", + status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get wma req msg type for vdev id %d", __func__, resp_event->vdev_id); return QDF_STATUS_E_INVAL; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: pdev is NULL", __func__); - status = -EINVAL; - wma_cleanup_target_req_param(req_msg); - qdf_mc_timer_stop(&req_msg->event_timeout); - goto free_req_msg; + vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp)); + if (!vdev_stop_resp) { + WMA_LOGE("%s: Failed to alloc vdev_stop_resp for vdev id %d", + __func__, resp_event->vdev_id); + return QDF_STATUS_E_NOMEM; } - qdf_mc_timer_stop(&req_msg->event_timeout); - if (req_msg->msg_type == WMA_DELETE_BSS_HO_FAIL_REQ) { - tpDeleteBssParams params = - (tpDeleteBssParams)req_msg->user_data; - - peer = cdp_peer_find_by_addr(soc, pdev, - params->bssid, &peer_id); - if (!peer) { - WMA_LOGE("%s: Failed to find peer %pM", __func__, - params->bssid); - status = QDF_STATUS_E_FAILURE; - goto free_req_msg; - } - - if (!iface->peer_count) { - WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d", - __func__, params->bssid, params->smesessionId, - iface->peer_count); - goto free_req_msg; - } + if (vdev_stop_type == WMA_DELETE_BSS_HO_FAIL_REQ) { + status = wma_remove_peer(wma, bssid.bytes, + resp_event->vdev_id, true); + if (QDF_IS_STATUS_ERROR(status)) + goto free_params; - if (peer) { - WMA_LOGD("%s: vdev %pK is peer_addr %pM to vdev_id %d, peer_count - %d", - __func__, peer, params->bssid, - params->smesessionId, iface->peer_count); - if (cdp_cfg_get_peer_unmap_conf_support(soc)) - cdp_peer_delete_sync(soc, peer, - wma_peer_unmap_conf_cb, - 1 << CDP_PEER_DELETE_NO_SPECIAL); - else - cdp_peer_delete(soc, peer, - 1 << CDP_PEER_DELETE_NO_SPECIAL); - wma_remove_objmgr_peer(wma, params->smesessionId, - params->bssid); - } - iface->peer_count--; - - WMA_LOGI("%s: Removed peer %pK with peer_addr %pM vdevid %d peer_count %d", - __func__, peer, params->bssid, params->smesessionId, - iface->peer_count); - wma_send_vdev_down_bss(wma, req_msg); - } else if (req_msg->msg_type == WMA_DELETE_BSS_REQ) { - tpDeleteBssParams params = - (tpDeleteBssParams) req_msg->user_data; - - if (!iface->handle) { - WMA_LOGE("%s vdev id %d is already deleted", - __func__, resp_event->vdev_id); - wma_cleanup_target_req_param(req_msg); - status = -EINVAL; - goto free_req_msg; - } + vdev_stop_resp->status = status; + vdev_stop_resp->vdev_id = resp_event->vdev_id; + wma_send_vdev_down_req(wma, vdev_stop_resp); + } else if (vdev_stop_type == WMA_DELETE_BSS_REQ || + vdev_stop_type == WMA_SET_LINK_STATE) { + uint8_t type; /* CCA is required only for sta interface */ if (iface->type == WMI_VDEV_TYPE_STA) wma_get_cca_stats(wma, resp_event->vdev_id); + if (vdev_stop_type == WMA_DELETE_BSS_REQ) + type = WMA_DELETE_PEER_RSP; + else + type = WMA_SET_LINK_PEER_RSP; - status = wma_remove_bss_peer(wma, pdev, resp_event->vdev_id, - params); + vdev_stop_resp->vdev_id = resp_event->vdev_id; + vdev_stop_resp->status = status; + status = wma_remove_bss_peer(wma, resp_event->vdev_id, + vdev_stop_resp, type); if (status) { WMA_LOGE("%s Del bss failed vdev:%d", __func__, resp_event->vdev_id); - wma_send_vdev_down_bss(wma, req_msg); - goto free_req_msg; + wma_send_vdev_down_req(wma, vdev_stop_resp); + return status; } if (wmi_service_enabled(wma->wmi_handle, wmi_service_sync_delete_cmds)) - goto free_req_msg; - - wma_send_vdev_down_bss(wma, req_msg); - } else if (req_msg->msg_type == WMA_SET_LINK_STATE) { - tpLinkStateParams params = - (tpLinkStateParams) req_msg->user_data; - - peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, - &peer_id); - if (peer) { - WMA_LOGP(FL("Deleting peer %pM vdev id %d"), - params->bssid, req_msg->vdev_id); - qdf_status = wma_remove_peer(wma, params->bssid, - req_msg->vdev_id, - peer, false); - if (QDF_IS_STATUS_ERROR(qdf_status)) { - WMA_LOGE(FL("wma_remove_peer failed")); - status = -EINVAL; - params->status = QDF_STATUS_E_FAILURE; - goto set_link_rsp; - } - if (wmi_service_enabled(wma->wmi_handle, - wmi_service_sync_delete_cmds)) { - WMA_LOGI(FL("Wait for the peer delete. vdev_id %d"), - req_msg->vdev_id); - del_req = wma_fill_hold_req(wma, - req_msg->vdev_id, - WMA_DELETE_STA_REQ, - WMA_SET_LINK_PEER_RSP, - params, - WMA_DELETE_STA_TIMEOUT); - if (!del_req) { - WMA_LOGE(FL("Failed to allocate request. vdev_id %d"), - req_msg->vdev_id); - params->status = QDF_STATUS_E_NOMEM; - } else { - goto free_req_msg; - } - } - } + return status; -set_link_rsp: - wma_handle_set_link_down_rsp(wma, req_msg); + wma_send_vdev_down_req(wma, vdev_stop_resp); } -free_req_msg: - qdf_mc_timer_destroy(&req_msg->event_timeout); - qdf_mem_free(req_msg); + return status; - if (status) - return QDF_STATUS_E_INVAL; - else - return QDF_STATUS_SUCCESS; +free_params: + qdf_mem_free(vdev_stop_resp); + return status; } /** @@ -2771,346 +2408,268 @@ __wma_handle_vdev_stop_rsp(wmi_vdev_stopped_event_fixed_param *resp_event) */ static QDF_STATUS wma_handle_vdev_stop_rsp(tp_wma_handle wma, - wmi_vdev_stopped_event_fixed_param *resp_event) + struct vdev_stop_response *resp_event) { struct wma_txrx_node *iface; iface = &wma->interfaces[resp_event->vdev_id]; - return wlan_vdev_mlme_sm_deliver_evt(iface->vdev, WLAN_VDEV_SM_EV_STOP_RESP, sizeof(*resp_event), resp_event); } -int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len) +QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme, + struct vdev_stop_response *rsp) { - tp_wma_handle wma = (tp_wma_handle) handle; - WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; - wmi_vdev_stopped_event_fixed_param *resp_event; - int32_t status = 0; - - WMA_LOGD("%s: Enter", __func__); + tp_wma_handle wma; + struct wma_txrx_node *iface = NULL; + QDF_STATUS status = QDF_STATUS_E_FAILURE; - param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info; - if (!param_buf) { - WMA_LOGE("Invalid event buffer"); - return -EINVAL; + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + wma_err("wma handle is NULL for VDEV_%d", rsp->vdev_id); + return status; } - resp_event = param_buf->fixed_param; + iface = &wma->interfaces[vdev_mlme->vdev->vdev_objmgr.vdev_id]; - if (resp_event->vdev_id >= wma->max_bssid) { + if (rsp->vdev_id >= wma->max_bssid) { WMA_LOGE("%s: Invalid vdev_id %d from FW", - __func__, resp_event->vdev_id); - return -EINVAL; + __func__, rsp->vdev_id); + return QDF_STATUS_E_INVAL; } - status = wma_handle_vdev_stop_rsp(wma, resp_event); - if (QDF_IS_STATUS_ERROR(status)) - return -EINVAL; + status = wma_handle_vdev_stop_rsp(wma, rsp); - return 0; + return status; } -/** - * wma_vdev_attach() - create vdev in fw - * @wma_handle: wma handle - * @self_sta_req: self sta request - * @generateRsp: generate response - * - * This function creates vdev in target and - * attach this vdev to txrx module. It also set - * vdev related params to fw. - * - * Return: txrx vdev handle - */ -struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, - struct add_sta_self_params *self_sta_req, - uint8_t generateRsp) +void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev) { - struct cdp_vdev *txrx_vdev_handle = NULL; - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - enum wlan_op_mode txrx_vdev_type; - enum wlan_op_subtype txrx_vdev_subtype; - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); - uint32_t cfg_val; - bool mcc_adapt_sch; - QDF_STATUS ret; - struct mlme_ht_capabilities_info *ht_cap_info; - struct scheduler_msg sme_msg = { 0 }; - struct vdev_create_params params = { 0 }; - u_int8_t vdev_id; - struct sir_set_tx_rx_aggregation_size tx_rx_aggregation_size; - struct sir_set_tx_sw_retry_threshold tx_sw_retry_threshold; + tp_wma_handle wma_handle; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wlan_objmgr_peer *obj_peer; - struct wlan_objmgr_vdev *vdev; - uint32_t retry; - uint8_t amsdu_val; + uint8_t vdev_id = wlan_vdev_get_id(vdev); + struct vdev_mlme_obj *vdev_mlme; - qdf_mem_zero(&tx_rx_aggregation_size, sizeof(tx_rx_aggregation_size)); - WMA_LOGD("mac %pM, vdev_id %hu, type %d, sub_type %d, nss 2g %d, 5g %d", - self_sta_req->self_mac_addr, self_sta_req->session_id, - self_sta_req->type, self_sta_req->sub_type, - self_sta_req->nss_2g, self_sta_req->nss_5g); - if (!mac) { - WMA_LOGE("%s: Failed to get mac", __func__); - status = QDF_STATUS_E_FAILURE; - goto end; + if (!soc) { + wma_err("SOC handle is NULL"); + return; } - vdev_id = self_sta_req->session_id; - if (wma_is_vdev_valid(vdev_id)) { - WMA_LOGE("%s: vdev %d already active", __func__, vdev_id); - status = QDF_STATUS_E_FAILURE; - goto end; - } + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + wma_err("WMA context is invalid"); + return; + } - params.if_id = self_sta_req->session_id; - params.type = self_sta_req->type; - params.subtype = self_sta_req->sub_type; - params.nss_2g = self_sta_req->nss_2g; - params.nss_5g = self_sta_req->nss_5g; + if (!wma_handle->interfaces[vdev_id].vdev) { + wma_err("vdev is NULL"); + return; + } - /* Create a vdev in target */ - ret = wmi_unified_vdev_create_send(wma_handle->wmi_handle, - self_sta_req->self_mac_addr, - ¶ms); - if (QDF_IS_STATUS_ERROR(ret)) { - WMA_LOGE("%s: Unable to add an interface for ath_dev", - __func__); - status = QDF_STATUS_E_FAILURE; - goto end; + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + wma_err("Failed to get vdev mlme obj for vdev id %d", vdev_id); + return; } - txrx_vdev_type = wma_get_txrx_vdev_type(self_sta_req->type); + wma_cdp_vdev_detach(soc, wma_handle, vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); + wma_handle->interfaces[vdev_id].vdev = NULL; + wma_handle->interfaces[vdev_id].vdev_active = false; +} - if (wlan_op_mode_unknown == txrx_vdev_type) { - WMA_LOGE("Failed to get txrx vdev type"); - wmi_unified_vdev_delete_send(wma_handle->wmi_handle, - self_sta_req->session_id); - status = QDF_STATUS_E_FAILURE; - goto end; +QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme) +{ + struct wlan_objmgr_peer *obj_peer; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; + tp_wma_handle wma_handle; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + wma_err("WMA context is invalid"); + return QDF_STATUS_E_FAILURE; + } + + if (wma_vdev_uses_self_peer(vdev_mlme->mgmt.generic.type, + vdev_mlme->mgmt.generic.subtype)) { + status = wma_create_peer(wma_handle, + vdev->vdev_mlme.macaddr, + WMI_PEER_TYPE_DEFAULT, + wlan_vdev_get_id(vdev), false); + if (QDF_IS_STATUS_ERROR(status)) + wma_err("Failed to create peer %d", status); + } else if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA) { + obj_peer = wma_create_objmgr_peer(wma_handle, + wlan_vdev_get_id(vdev), + vdev->vdev_mlme.macaddr, + WMI_PEER_TYPE_DEFAULT); + if (!obj_peer) { + wma_err("Failed to create obj mgr peer for self"); + status = QDF_STATUS_E_INVAL; + } } - txrx_vdev_subtype = wma_get_txrx_vdev_subtype(self_sta_req->sub_type); + return status; +} + +QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + uint32_t cfg_val; + bool mcc_adapt_sch = false; + QDF_STATUS ret; + struct mlme_ht_capabilities_info *ht_cap_info; + u_int8_t vdev_id; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_mlme_qos *qos_aggr; + struct vdev_mlme_obj *vdev_mlme; + tp_wma_handle wma_handle; + uint8_t amsdu_val; - txrx_vdev_handle = cdp_vdev_attach(soc, txrx_pdev, - self_sta_req->self_mac_addr, - vdev_id, txrx_vdev_type, - txrx_vdev_subtype); + if (!mac) { + WMA_LOGE("%s: Failed to get mac", __func__); + return QDF_STATUS_E_FAILURE; + } - WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %pK", vdev_id, - txrx_vdev_handle); + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + WMA_LOGE("%s: WMA context is invalid", __func__); + return QDF_STATUS_E_FAILURE; + } - if (!txrx_vdev_handle) { - WMA_LOGE("%s: cdp_vdev_attach failed", __func__); - status = QDF_STATUS_E_FAILURE; - wmi_unified_vdev_delete_send(wma_handle->wmi_handle, - self_sta_req->session_id); - goto end; + if (!soc) { + WMA_LOGE("%s: SOC context is invalid", __func__); + return QDF_STATUS_E_FAILURE; } + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_WMA_ID) != + QDF_STATUS_SUCCESS) + return QDF_STATUS_E_FAILURE; + + vdev_id = wlan_vdev_get_id(vdev); + wma_handle->interfaces[vdev_id].vdev = vdev; wma_handle->interfaces[vdev_id].vdev_active = true; - wma_handle->interfaces[vdev_id].handle = txrx_vdev_handle; - wma_vdev_update_pause_bitmap(vdev_id, 0); - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, vdev_id, - WLAN_LEGACY_WMA_ID); - if (!vdev) { - WMA_LOGE(FL("vdev obj is NULL for vdev_id: %u"), vdev_id); - status = QDF_STATUS_E_FAILURE; - wma_handle->interfaces[vdev_id].vdev_active = false; - wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id); + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + WMA_LOGE("%s: Failed to get vdev mlme obj!", __func__); goto end; } - wma_handle->interfaces[vdev_id].vdev = vdev; + wma_vdev_update_pause_bitmap(vdev_id, 0); + + wma_handle->interfaces[vdev_id].type = + vdev_mlme->mgmt.generic.type; + wma_handle->interfaces[vdev_id].sub_type = + vdev_mlme->mgmt.generic.subtype; - qdf_mem_copy(wma_handle->interfaces[vdev_id].addr, - self_sta_req->self_mac_addr, - sizeof(wma_handle->interfaces[vdev_id].addr)); + qos_aggr = &mac->mlme_cfg->qos_mlme_params; + status = wma_set_tx_rx_aggr_size(vdev_id, qos_aggr->tx_aggregation_size, + qos_aggr->rx_aggregation_size, + WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set aggregation sizes(status = %d)", + status); status = wlan_mlme_get_max_amsdu_num(wma_handle->psoc, &amsdu_val); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("failed to get amsdu aggr.size %d", status); } else { - - tx_rx_aggregation_size.tx_aggregation_size = - amsdu_val; - tx_rx_aggregation_size.rx_aggregation_size = - amsdu_val; - tx_rx_aggregation_size.vdev_id = vdev_id; - tx_rx_aggregation_size.aggr_type = - WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU; - status = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size); + status = wma_set_tx_rx_aggr_size(vdev_id, amsdu_val, + amsdu_val, + WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("failed to set amsdu aggr.size %d", status); } } + if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA) { + status = wma_set_tx_rx_aggr_size_per_ac( + wma_handle, vdev_id, + qos_aggr, + WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU); - tx_rx_aggregation_size.tx_aggregation_size = - self_sta_req->tx_aggregation_size; - tx_rx_aggregation_size.rx_aggregation_size = - self_sta_req->rx_aggregation_size; - tx_rx_aggregation_size.vdev_id = self_sta_req->session_id; - tx_rx_aggregation_size.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU; - - ret = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set aggregation sizes(err=%d)", ret); - - tx_rx_aggregation_size.tx_aggregation_size_be = - self_sta_req->tx_aggregation_size_be; - tx_rx_aggregation_size.tx_aggregation_size_bk = - self_sta_req->tx_aggregation_size_bk; - tx_rx_aggregation_size.tx_aggregation_size_vi = - self_sta_req->tx_aggregation_size_vi; - tx_rx_aggregation_size.tx_aggregation_size_vo = - self_sta_req->tx_aggregation_size_vo; - - tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_be = - self_sta_req->tx_aggr_sw_retry_threshold_be; - tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_bk = - self_sta_req->tx_aggr_sw_retry_threshold_bk; - tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_vi = - self_sta_req->tx_aggr_sw_retry_threshold_vi; - tx_sw_retry_threshold.tx_aggr_sw_retry_threshold_vo = - self_sta_req->tx_aggr_sw_retry_threshold_vo; - tx_sw_retry_threshold.tx_aggr_sw_retry_threshold = - self_sta_req->tx_aggr_sw_retry_threshold; - - tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_be = - self_sta_req->tx_non_aggr_sw_retry_threshold_be; - tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_bk = - self_sta_req->tx_non_aggr_sw_retry_threshold_bk; - tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_vi = - self_sta_req->tx_non_aggr_sw_retry_threshold_vi; - tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold_vo = - self_sta_req->tx_non_aggr_sw_retry_threshold_vo; - tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold = - self_sta_req->tx_non_aggr_sw_retry_threshold; - - tx_sw_retry_threshold.vdev_id = self_sta_req->session_id; - - - switch (self_sta_req->type) { - case WMI_VDEV_TYPE_STA: - ret = wma_set_tx_rx_aggregation_size_per_ac( - &tx_rx_aggregation_size); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("set aggr sizes per ac(err=%d) failed", ret); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set aggr size per ac(status = %d)", + status); - cfg_val = mac->mlme_cfg->sta.sta_keep_alive_period; - wma_set_sta_keep_alive(wma_handle, - self_sta_req->session_id, - SIR_KEEP_ALIVE_NULL_PKT, - cfg_val, NULL, NULL, NULL); + wma_set_sta_keep_alive( + wma_handle, vdev_id, + SIR_KEEP_ALIVE_NULL_PKT, + mac->mlme_cfg->sta.sta_keep_alive_period, + NULL, NULL, NULL); /* offload STA SA query related params to fwr */ if (wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_sta_pmf_offload)) { + wmi_service_sta_pmf_offload)) { wma_set_sta_sa_query_param(wma_handle, vdev_id); } - vdev_id = tx_sw_retry_threshold.vdev_id; - retry = tx_sw_retry_threshold.tx_aggr_sw_retry_threshold; - if (retry) { - ret = wma_set_sw_retry_threshold(vdev_id, retry, + status = wma_set_sw_retry_threshold( + vdev_id, + qos_aggr->tx_aggr_sw_retry_threshold, WMI_PDEV_PARAM_AGG_SW_RETRY_TH); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed set agg retry threshold"); - } - - retry = tx_sw_retry_threshold.tx_non_aggr_sw_retry_threshold; - if (retry) { - ret = wma_set_sw_retry_threshold(vdev_id, retry, - WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed set non-agg retry threshold"); - } + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set sw retry threshold (status = %d)", + status); - ret = wma_set_sw_retry_threshold_per_ac(wma_handle, - &tx_sw_retry_threshold); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set retry threshold(err=%d)", ret); - break; - } + status = wma_set_sw_retry_threshold( + vdev_id, + qos_aggr->tx_non_aggr_sw_retry_threshold, + WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set sw retry threshold tx non aggr(status = %d)", + status); - wma_handle->interfaces[vdev_id].type = self_sta_req->type; - wma_handle->interfaces[vdev_id].sub_type = self_sta_req->sub_type; - qdf_atomic_init(&wma_handle->interfaces[vdev_id].bss_status); + wma_handle_packet_capture_mode(wma_handle, vdev_id, + WMI_PDEV_ID_SOC); - if (wma_vdev_uses_self_peer(self_sta_req->type, - self_sta_req->sub_type)) { - ret = wma_create_peer(wma_handle, txrx_pdev, txrx_vdev_handle, - self_sta_req->self_mac_addr, - WMI_PEER_TYPE_DEFAULT, - self_sta_req->session_id, false); - if (QDF_IS_STATUS_ERROR(ret)) { - WMA_LOGE("%s: Failed to create peer", __func__); - status = QDF_STATUS_E_FAILURE; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - wmi_unified_vdev_delete_send(wma_handle->wmi_handle, - self_sta_req->session_id); - wma_handle->interfaces[vdev_id].vdev_active = false; - wma_cdp_vdev_detach(soc, wma_handle, vdev_id); - wma_handle->interfaces[vdev_id].vdev = NULL; - txrx_vdev_handle = NULL; - goto end; - } - } else if (self_sta_req->type == WMI_VDEV_TYPE_STA) { - obj_peer = wma_create_objmgr_peer(wma_handle, vdev_id, - self_sta_req->self_mac_addr, - WMI_PEER_TYPE_DEFAULT); - if (!obj_peer) { - WMA_LOGE("%s: Failed to create obj mgr peer for self sta", - __func__); - status = QDF_STATUS_E_FAILURE; - wmi_unified_vdev_delete_send(wma_handle->wmi_handle, - self_sta_req->session_id); - wma_handle->interfaces[vdev_id].vdev_active = false; - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - wma_handle->interfaces[vdev_id].vdev = NULL; - wma_cdp_vdev_detach(soc, wma_handle, vdev_id); - txrx_vdev_handle = NULL; - goto end; - } + status = wma_set_sw_retry_threshold_per_ac(wma_handle, vdev_id, + qos_aggr); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set sw retry threshold per ac(status = %d)", + status); } WMA_LOGD("Setting WMI_VDEV_PARAM_DISCONNECT_TH: %d", - self_sta_req->pkt_err_disconn_th); - ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id, - WMI_VDEV_PARAM_DISCONNECT_TH, - self_sta_req->pkt_err_disconn_th); - if (ret) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_DISCONNECT_TH"); - - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, - mac->roam.configParam.mcc_rts_cts_prot_enable); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI VDEV MCC_RTSCTS_PROTECTION_ENABLE"); + mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh); + status = wma_vdev_set_param( + wma_handle->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DISCONNECT_TH, + mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set DISCONNECT_TH(status = %d)", status); + + status = wma_vdev_set_param( + wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE, + mac->roam.configParam.mcc_rts_cts_prot_enable); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set MCC_RTSCTS_PROTECTION_ENABLE(status = %d)", + status); - ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id, + status = wma_vdev_set_param( + wma_handle->wmi_handle, vdev_id, WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE, mac->roam.configParam.mcc_bcast_prob_resp_enable); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI VDEV MCC_BROADCAST_PROBE_ENABLE"); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set MCC_BROADCAST_PROBE_ENABLE(status = %d)", + status); if (wlan_mlme_get_rts_threshold(mac->psoc, &cfg_val) == QDF_STATUS_SUCCESS) { - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_RTS_THRESHOLD, - cfg_val); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_RTS_THRESHOLD"); + status = wma_vdev_set_param(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_RTS_THRESHOLD, + cfg_val); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set RTS_THRESHOLD(status = %d)", + status); } else { WMA_LOGE("Fail to get val for rts threshold, leave unchanged"); } @@ -3118,55 +2677,51 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, if (wlan_mlme_get_frag_threshold(mac->psoc, &cfg_val) == QDF_STATUS_SUCCESS) { - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - cfg_val); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD"); + wma_vdev_set_param(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, + cfg_val); } else { WMA_LOGE("Fail to get val for frag threshold, leave unchanged"); } ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info; + status = wma_vdev_set_param(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_TX_STBC, + ht_cap_info->tx_stbc); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("failed to set TX_STBC(status = %d)", status); - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_TX_STBC, - ht_cap_info->tx_stbc); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_TX_STBC"); - - wma_set_vdev_mgmt_rate(wma_handle, self_sta_req->session_id); - + wma_set_vdev_mgmt_rate(wma_handle, vdev_id); if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) wma_set_he_txbf_cfg(mac, vdev_id); /* Initialize roaming offload state */ - if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && - (self_sta_req->sub_type == 0)) { + if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && + vdev_mlme->mgmt.generic.subtype == 0) { /* Pass down enable/disable bcast probe rsp to FW */ ret = wma_vdev_set_param( wma_handle->wmi_handle, - self_sta_req->session_id, + vdev_id, WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, - self_sta_req->enable_bcast_probe_rsp); + mac->mlme_cfg->oce.enable_bcast_probe_rsp); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE"); /* Pass down the FILS max channel guard time to FW */ ret = wma_vdev_set_param( wma_handle->wmi_handle, - self_sta_req->session_id, + vdev_id, WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, - self_sta_req->fils_max_chan_guard_time); + mac->mlme_cfg->sta.fils_max_chan_guard_time); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE("Failed to set WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME"); /* Pass down the Probe Request tx delay(in ms) to FW */ ret = wma_vdev_set_param( wma_handle->wmi_handle, - self_sta_req->session_id, + vdev_id, WMI_VDEV_PARAM_PROBE_DELAY, PROBE_REQ_TX_DELAY); if (QDF_IS_STATUS_ERROR(ret)) @@ -3175,37 +2730,35 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, /* Pass down the probe request tx time gap(in ms) to FW */ ret = wma_vdev_set_param( wma_handle->wmi_handle, - self_sta_req->session_id, + vdev_id, WMI_VDEV_PARAM_REPEAT_PROBE_TIME, PROBE_REQ_TX_TIME_GAP); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE("Failed to set WMI_VDEV_PARAM_REPEAT_PROBE_TIME"); } - if ((self_sta_req->type == WMI_VDEV_TYPE_STA || - self_sta_req->type == WMI_VDEV_TYPE_AP) && - self_sta_req->sub_type == 0) { - ret = wma_vdev_set_param(wma_handle->wmi_handle, - self_sta_req->session_id, - WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES, - self_sta_req->oce_feature_bitmap); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES"); + if ((vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA || + vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_AP) && + vdev_mlme->mgmt.generic.subtype == 0) { + wma_vdev_set_param(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES, + mac->mlme_cfg->oce.feature_bitmap); } /* Initialize BMISS parameters */ - if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && - (self_sta_req->sub_type == 0)) + if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && + vdev_mlme->mgmt.generic.subtype == 0) wma_roam_scan_bmiss_cnt(wma_handle, mac->mlme_cfg->lfr.roam_bmiss_first_bcnt, mac->mlme_cfg->lfr.roam_bmiss_final_bcnt, - self_sta_req->session_id); + vdev_id); if (policy_mgr_get_dynamic_mcc_adaptive_sch(mac->psoc, &mcc_adapt_sch) == QDF_STATUS_SUCCESS) { WMA_LOGD("%s: setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d", - __func__, mcc_adapt_sch); + __func__, mcc_adapt_sch); ret = wma_set_enable_disable_mcc_adaptive_scheduler(mcc_adapt_sch); if (QDF_IS_STATUS_ERROR(ret)) { @@ -3215,219 +2768,126 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, WMA_LOGE("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged"); } - if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && - (ucfg_pmo_is_apf_enabled(wma_handle->psoc))) { + if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA && + ucfg_pmo_is_apf_enabled(wma_handle->psoc)) { ret = wma_config_active_apf_mode(wma_handle, - self_sta_req->session_id); + vdev_id); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE("Failed to configure active APF mode"); } -end: - self_sta_req->status = status; + cdp_data_tx_cb_set(soc, vdev_id, + wma_data_tx_ack_comp_hdlr, + wma_handle); -#ifdef QCA_IBSS_SUPPORT - if (generateRsp) -#endif - { - sme_msg.type = eWNI_SME_ADD_STA_SELF_RSP; - sme_msg.bodyptr = self_sta_req; - sme_msg.bodyval = 0; - - status = scheduler_post_message(QDF_MODULE_ID_WMA, - QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, &sme_msg); - if (!QDF_IS_STATUS_SUCCESS(status)) { - WMA_LOGE("Failed to post eWNI_SME_ADD_STA_SELF_RSP"); - qdf_mem_free(self_sta_req); - } - } - return txrx_vdev_handle; + return QDF_STATUS_SUCCESS; + +end: + wma_cleanup_vdev(vdev); + return QDF_STATUS_E_FAILURE; } -uint32_t wma_get_bcn_rate_code(uint16_t rate) +enum mlme_bcn_tx_rate_code wma_get_bcn_rate_code(uint16_t rate) { /* rate in multiples of 100 Kbps */ switch (rate) { case WMA_BEACON_TX_RATE_1_M: - return WMI_BCN_TX_RATE_CODE_1_M; + return MLME_BCN_TX_RATE_CODE_1_M; case WMA_BEACON_TX_RATE_2_M: - return WMI_BCN_TX_RATE_CODE_2_M; + return MLME_BCN_TX_RATE_CODE_2_M; case WMA_BEACON_TX_RATE_5_5_M: - return WMI_BCN_TX_RATE_CODE_5_5_M; + return MLME_BCN_TX_RATE_CODE_5_5_M; case WMA_BEACON_TX_RATE_11_M: - return WMI_BCN_TX_RATE_CODE_11M; + return MLME_BCN_TX_RATE_CODE_11M; case WMA_BEACON_TX_RATE_6_M: - return WMI_BCN_TX_RATE_CODE_6_M; + return MLME_BCN_TX_RATE_CODE_6_M; case WMA_BEACON_TX_RATE_9_M: - return WMI_BCN_TX_RATE_CODE_9_M; + return MLME_BCN_TX_RATE_CODE_9_M; case WMA_BEACON_TX_RATE_12_M: - return WMI_BCN_TX_RATE_CODE_12_M; + return MLME_BCN_TX_RATE_CODE_12_M; case WMA_BEACON_TX_RATE_18_M: - return WMI_BCN_TX_RATE_CODE_18_M; + return MLME_BCN_TX_RATE_CODE_18_M; case WMA_BEACON_TX_RATE_24_M: - return WMI_BCN_TX_RATE_CODE_24_M; + return MLME_BCN_TX_RATE_CODE_24_M; case WMA_BEACON_TX_RATE_36_M: - return WMI_BCN_TX_RATE_CODE_36_M; + return MLME_BCN_TX_RATE_CODE_36_M; case WMA_BEACON_TX_RATE_48_M: - return WMI_BCN_TX_RATE_CODE_48_M; + return MLME_BCN_TX_RATE_CODE_48_M; case WMA_BEACON_TX_RATE_54_M: - return WMI_BCN_TX_RATE_CODE_54_M; + return MLME_BCN_TX_RATE_CODE_54_M; default: - return WMI_BCN_TX_RATE_CODE_1_M; + return MLME_BCN_TX_RATE_CODE_1_M; } } -/** - * wma_vdev_start() - send vdev start request to fw - * @wma: wma handle - * @req: vdev start params - * @isRestart: isRestart flag - * - * Return: QDF status - */ -QDF_STATUS wma_vdev_start(tp_wma_handle wma, - struct wma_vdev_start_req *req, bool isRestart) +QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart) { - struct vdev_start_params params = { 0 }; - wmi_vdev_start_request_cmd_fixed_param *cmd; - struct wma_txrx_node *intr = wma->interfaces; - struct mac_context *mac_ctx = NULL; - uint32_t temp_ssid_len = 0; - uint32_t temp_flags = 0; - uint32_t temp_chan_info = 0; - uint32_t temp_reg_info_1 = 0; - uint32_t temp_reg_info_2 = 0; - uint16_t bw_val; - struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id]; - struct wma_target_req *req_msg; - uint32_t chan_mode; - enum phy_ch_width ch_width; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *intr; + struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); struct wlan_mlme_nss_chains *ini_cfg; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev; + struct wlan_channel *des_chan; - ini_cfg = mlme_get_ini_vdev_config(iface->vdev); - if (!ini_cfg) { - wma_err("nss chain ini config NULL"); + if (!wma) { + wma_err("Invalid wma handle"); return QDF_STATUS_E_FAILURE; } - - mac_ctx = cds_get_context(QDF_MODULE_ID_PE); if (!mac_ctx) { - WMA_LOGE("%s: vdev start failed as mac_ctx is NULL", __func__); + wma_err("Invalid mac context"); return QDF_STATUS_E_FAILURE; } - - if (req->chan == 0) { - WMA_LOGE("%s: invalid channel: %d", __func__, req->chan); - QDF_ASSERT(0); - return QDF_STATUS_E_INVAL; - } - - params.channel.cfreq1 = cds_chan_to_freq(req->chan); - ch_width = req->chan_width; - bw_val = wlan_reg_get_bw_value(req->chan_width); - if (20 < bw_val) { - if (req->ch_center_freq_seg0) { - params.channel.cfreq1 = - cds_chan_to_freq(req->ch_center_freq_seg0); - } else { - WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 20", - __func__, bw_val); - params.channel.cfreq1 = cds_chan_to_freq(req->chan); - ch_width = CH_WIDTH_20MHZ; - bw_val = 20; - } + intr = wma->interfaces; + if (!intr) { + wma_err("Invalid interface"); + return QDF_STATUS_E_FAILURE; } - if (80 < bw_val) { - if (req->ch_center_freq_seg1) { - params.channel.cfreq2 = - cds_chan_to_freq(req->ch_center_freq_seg1); - } else { - WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 80", - __func__, bw_val); - params.channel.cfreq2 = 0; - ch_width = CH_WIDTH_80MHZ; - } - } else { - params.channel.cfreq2 = 0; + if (vdev_id >= WLAN_MAX_VDEVS) { + wma_err("Invalid vdev id"); + return QDF_STATUS_E_INVAL; } - chan_mode = wma_chan_phy_mode(req->chan, ch_width, - req->dot11_mode); - - if (chan_mode == MODE_UNKNOWN) { - WMA_LOGE("%s: invalid phy mode!", __func__); + vdev = intr[vdev_id].vdev; + if (!vdev) { + wma_err("Invalid vdev"); return QDF_STATUS_E_FAILURE; } - if (!params.channel.cfreq1) { - WMA_LOGE("%s: invalid center freq1", __func__); + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); return QDF_STATUS_E_FAILURE; } + des_chan = vdev->vdev_mlme.des_chan; - if (((ch_width == CH_WIDTH_160MHZ) || - (ch_width == CH_WIDTH_80P80MHZ)) && !params.channel.cfreq2) { - WMA_LOGE("%s: invalid center freq2 for 160MHz", __func__); + ini_cfg = mlme_get_ini_vdev_config(vdev); + if (!ini_cfg) { + wma_err("nss chain ini config NULL"); return QDF_STATUS_E_FAILURE; } - /* Fill channel info */ - params.channel.mhz = cds_chan_to_freq(req->chan); - params.channel.phy_mode = chan_mode; - - /* For Rome, only supports LFR2, not LFR3, for reassoc, need send vdev - * start cmd to F/W while vdev started first, then send reassoc frame - */ - if (!isRestart && - qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED && - wmi_service_enabled(wma->wmi_handle, wmi_service_roam_ho_offload)) { - req_msg = wma_find_vdev_req(wma, req->vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP, - false); - if (!req_msg || req_msg->msg_type != WMA_DELETE_BSS_REQ) { - WMA_LOGE("BSS is in started state before vdev start"); - cds_trigger_recovery(QDF_REASON_UNSPECIFIED); - } - } - WMA_LOGD("%s: Enter isRestart=%d vdev=%d", __func__, isRestart, - req->vdev_id); - params.vdev_id = req->vdev_id; - - intr[params.vdev_id].chanmode = params.channel.phy_mode; - intr[params.vdev_id].ht_capable = req->ht_capable; - intr[params.vdev_id].vht_capable = req->vht_capable; - intr[params.vdev_id].config.gtx_info.gtxRTMask[0] = + intr[vdev_id].config.gtx_info.gtxRTMask[0] = CFG_TGT_DEFAULT_GTX_HT_MASK; - intr[params.vdev_id].config.gtx_info.gtxRTMask[1] = + intr[vdev_id].config.gtx_info.gtxRTMask[1] = CFG_TGT_DEFAULT_GTX_VHT_MASK; - intr[params.vdev_id].config.gtx_info.gtxUsrcfg = + intr[vdev_id].config.gtx_info.gtxUsrcfg = mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg; - intr[params.vdev_id].config.gtx_info.gtxPERThreshold = + intr[vdev_id].config.gtx_info.gtxPERThreshold = CFG_TGT_DEFAULT_GTX_PER_THRESHOLD; - intr[params.vdev_id].config.gtx_info.gtxPERMargin = + intr[vdev_id].config.gtx_info.gtxPERMargin = CFG_TGT_DEFAULT_GTX_PER_MARGIN; - intr[params.vdev_id].config.gtx_info.gtxTPCstep = + intr[vdev_id].config.gtx_info.gtxTPCstep = CFG_TGT_DEFAULT_GTX_TPC_STEP; - intr[params.vdev_id].config.gtx_info.gtxTPCMin = + intr[vdev_id].config.gtx_info.gtxTPCMin = CFG_TGT_DEFAULT_GTX_TPC_MIN; - intr[params.vdev_id].config.gtx_info.gtxBWMask = + intr[vdev_id].config.gtx_info.gtxBWMask = CFG_TGT_DEFAULT_GTX_BW_MASK; - intr[params.vdev_id].mhz = params.channel.mhz; - intr[params.vdev_id].chan_width = ch_width; - intr[params.vdev_id].channel = req->chan; - - temp_chan_info &= 0xffffffc0; - temp_chan_info |= params.channel.phy_mode; - - /* Set half or quarter rate WMI flags */ - params.channel.half_rate = req->is_half_rate; - params.channel.quarter_rate = req->is_quarter_rate; - - if (req->is_half_rate) - temp_chan_info |= (1 << WMI_CHAN_FLAG_HALF_RATE); - else if (req->is_quarter_rate) - temp_chan_info |= (1 << WMI_CHAN_FLAG_QUARTER_RATE); + intr[vdev_id].mhz = des_chan->ch_freq; + intr[vdev_id].chan_width = des_chan->ch_width; + intr[vdev_id].ch_freq = des_chan->ch_freq; + intr[vdev_id].ch_flagext = des_chan->ch_flagext; /* * If the channel has DFS set, flip on radar reporting. @@ -3439,115 +2899,37 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, * If that is ever the case we would insert the decision whether to * enable the firmware flag here. */ - params.is_restart = isRestart; - params.cac_duration_ms = req->cac_duration_ms; - params.regdomain = req->dfs_regdomain; - if ((QDF_GLOBAL_MONITOR_MODE != cds_get_conparam()) && req->is_dfs) { - temp_chan_info |= (1 << WMI_CHAN_FLAG_DFS); - params.disable_hw_ack = true; - - /* - * If channel is DFS and operating in AP mode, - * set the WMI_CHAN_FLAG_DFS flag. - */ - if (wma_is_vdev_in_ap_mode(wma, params.vdev_id) == true) - params.channel.dfs_set = true; - } - - params.beacon_intval = req->beacon_intval; - params.dtim_period = req->dtim_period; - - if (req->beacon_tx_rate) { - WMA_LOGD("%s: beacon tx rate [%hu * 100 Kbps]", - __func__, req->beacon_tx_rate); - temp_flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT; + if (QDF_GLOBAL_MONITOR_MODE != cds_get_conparam() && + utils_is_dfs_chan_for_freq(wma->pdev, + wlan_reg_legacy_chan_to_freq(wma->pdev, + des_chan->ch_ieee))) + mlme_obj->mgmt.generic.disable_hw_ack = true; + + if (mlme_obj->mgmt.rate_info.bcn_tx_rate) { + wma_debug("beacon tx rate [%u * 100 Kbps]", + mlme_obj->mgmt.rate_info.bcn_tx_rate); /* * beacon_tx_rate is in multiples of 100 Kbps. * Convert the data rate to hw rate code. */ - params.bcn_tx_rate_code = - wma_get_bcn_rate_code(req->beacon_tx_rate); - } - - /* FIXME: Find out min, max and regulatory power levels */ - params.channel.maxregpower = req->max_txpow; - temp_reg_info_1 &= 0xff00ffff; - temp_reg_info_1 |= ((req->max_txpow&0xff) << 16); - - temp_reg_info_2 &= 0xffff00ff; - temp_reg_info_2 |= ((req->max_txpow&0xff)<<8); - - /* TODO: Handle regulatory class, max antenna */ - if (!isRestart) { - params.beacon_intval = req->beacon_intval; - params.dtim_period = req->dtim_period; - - /* Copy the SSID */ - if (req->ssid.length) { - params.ssid.length = req->ssid.length; - if (req->ssid.length < sizeof(cmd->ssid.ssid)) - temp_ssid_len = req->ssid.length; - else - temp_ssid_len = sizeof(cmd->ssid.ssid); - qdf_mem_copy(params.ssid.mac_ssid, req->ssid.ssId, - temp_ssid_len); - } + mlme_obj->mgmt.rate_info.bcn_tx_rate = + wma_get_bcn_rate_code(mlme_obj->mgmt.rate_info.bcn_tx_rate); + } - params.pmf_enabled = req->pmf_enabled; - if (req->pmf_enabled) - temp_flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; - } - - params.hidden_ssid = req->hidden_ssid; - if (req->hidden_ssid) - temp_flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; - - params.num_noa_descriptors = 0; - params.preferred_rx_streams = req->preferred_rx_streams; - params.preferred_tx_streams = req->preferred_tx_streams; - - wma_copy_vdev_start_he_ops(¶ms, req); - - /* Store vdev params in SAP mode which can be used in vdev restart */ - if (intr[req->vdev_id].type == WMI_VDEV_TYPE_AP && - intr[req->vdev_id].sub_type == 0) { - intr[req->vdev_id].vdev_restart_params.vdev_id = req->vdev_id; - intr[req->vdev_id].vdev_restart_params.ssid.ssid_len = - temp_ssid_len; - qdf_mem_copy(intr[req->vdev_id].vdev_restart_params.ssid.ssid, - params.ssid.mac_ssid, temp_ssid_len); - intr[req->vdev_id].vdev_restart_params.flags = temp_flags; - intr[req->vdev_id].vdev_restart_params.requestor_id = 0; - intr[req->vdev_id].vdev_restart_params.disable_hw_ack = - params.disable_hw_ack; - intr[req->vdev_id].vdev_restart_params.chan.mhz = - params.channel.mhz; - intr[req->vdev_id].vdev_restart_params.chan.band_center_freq1 = - params.channel.cfreq1; - intr[req->vdev_id].vdev_restart_params.chan.band_center_freq2 = - params.channel.cfreq2; - intr[req->vdev_id].vdev_restart_params.chan.info = - temp_chan_info; - intr[req->vdev_id].vdev_restart_params.chan.reg_info_1 = - temp_reg_info_1; - intr[req->vdev_id].vdev_restart_params.chan.reg_info_2 = - temp_reg_info_2; - } - - if (!isRestart) { + if (!restart) { WMA_LOGD("%s, vdev_id: %d, unpausing tx_ll_queue at VDEV_START", - __func__, params.vdev_id); + __func__, vdev_id); + cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), - wma->interfaces[params.vdev_id].handle, - 0xffffffff); - wma_vdev_update_pause_bitmap(params.vdev_id, 0); + vdev_id, 0xffffffff, 0); + wma_vdev_update_pause_bitmap(vdev_id, 0); } /* Send the dynamic nss chain params before vdev start to fw */ if (wma->dynamic_nss_chains_support) - wma_vdev_nss_chain_params_send(params.vdev_id, ini_cfg); + wma_vdev_nss_chain_params_send(vdev_id, ini_cfg); - return wma_send_vdev_start_to_fw(wma, ¶ms); + return QDF_STATUS_SUCCESS; } /** @@ -3581,8 +2963,8 @@ int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, } WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr); - WMA_LOGD(FL("peer assoc conf for vdev:%d mac=%pM"), - event->vdev_id, macaddr); + WMA_LOGD(FL("peer assoc conf for vdev:%d mac="QDF_MAC_ADDR_FMT), + event->vdev_id, QDF_MAC_ADDR_REF(macaddr)); req_msg = wma_find_req(wma, event->vdev_id, WMA_PEER_ASSOC_CNF_START); @@ -3606,31 +2988,15 @@ int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, } /* peer assoc conf event means the cmd succeeds */ - params->status = QDF_STATUS_SUCCESS; - WMA_LOGD(FL("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"), + params->status = event->status; + WMA_LOGD(FL("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d"), params->staType, params->smesessionId, - params->assocId, params->bssId, params->staIdx, + params->assocId, QDF_MAC_ADDR_REF(params->bssId), params->status); wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)params, 0); } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) { - tpAddBssParams params = (tpAddBssParams) req_msg->user_data; - - if (!params) { - WMA_LOGE(FL("add BSS params is NULL for vdev %d"), - event->vdev_id); - status = -EINVAL; - goto free_req_msg; - } - - /* peer assoc conf event means the cmd succeeds */ - params->status = QDF_STATUS_SUCCESS; - WMA_LOGD(FL("Send ADD BSS RSP: opermode: %d update_bss: %d nw_type: %d bssid: %pM staIdx %d status %d"), - params->operMode, - params->updateBss, params->nwType, params->bssId, - params->staContext.staIdx, params->status); - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, - (void *)params, 0); + wma_send_add_bss_resp(wma, event->vdev_id, event->status); } else { WMA_LOGE(FL("Unhandled request message type: %d"), req_msg->msg_type); @@ -3643,55 +3009,6 @@ int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, return status; } -/** - * wma_vdev_delete_handler() - vdev delete response handler - * @handle: wma handle - * @cmd_param_info: event buffer - * @len: buffer length - * - * Return: 0 for success or error code - */ -int wma_vdev_delete_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len) -{ - tp_wma_handle wma = (tp_wma_handle) handle; - WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf; - wmi_vdev_delete_cmd_fixed_param *event; - struct wma_target_req *req_msg; - int status = 0; - - param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info; - if (!param_buf) { - WMA_LOGE("Invalid vdev delete event buffer"); - return -EINVAL; - } - - event = (wmi_vdev_delete_cmd_fixed_param *)param_buf->fixed_param; - if (!event) { - WMA_LOGE("Invalid vdev delete event buffer"); - return -EINVAL; - } - - WMA_LOGD("%s Vdev delete resp vdev id %d", __func__, event->vdev_id); - req_msg = wma_find_vdev_req(wma, event->vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_DEL, true); - if (!req_msg) { - WMA_LOGD(FL("Vdev delete resp is not handled! vdev id %d"), - event->vdev_id); - return -EINVAL; - } - qdf_mc_timer_stop(&req_msg->event_timeout); - qdf_mc_timer_destroy(&req_msg->event_timeout); - - wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); - - /* Send response to upper layers */ - wma_vdev_detach_callback(req_msg->user_data); - qdf_mem_free(req_msg); - - return status; -} - /** * wma_peer_delete_handler() - peer delete response handler * @handle: wma handle @@ -3724,8 +3041,8 @@ int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info, } WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr); - WMA_LOGD(FL("Peer Delete Response, vdev %d Peer %pM"), - event->vdev_id, macaddr); + WMA_LOGD(FL("Peer Delete Response, vdev %d Peer "QDF_MAC_ADDR_FMT), + event->vdev_id, QDF_MAC_ADDR_REF(macaddr)); wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP, DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0); req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id, @@ -3755,23 +3072,28 @@ int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info, data = (struct del_sta_self_rsp_params *)req_msg->user_data; WMA_LOGD(FL("Calling vdev detach handler")); - wma_handle_vdev_detach(wma, data->self_sta_param, - data->generate_rsp); + status = wma_handle_vdev_detach(wma, data->self_sta_param); + if (QDF_IS_STATUS_ERROR(status)) { + data->self_sta_param->status = status; + wma_send_vdev_del_resp(data->self_sta_param); + } qdf_mem_free(data); - } else if (req_msg->type == WMA_SET_LINK_PEER_RSP) { - wma_handle_set_link_down_rsp(wma, req_msg); - } else if (req_msg->type == WMA_DELETE_PEER_RSP) { - wma_send_vdev_down_bss(wma, req_msg); + } else if (req_msg->type == WMA_SET_LINK_PEER_RSP || + req_msg->type == WMA_DELETE_PEER_RSP) { + wma_send_vdev_down_req(wma, req_msg->user_data); } qdf_mem_free(req_msg); + return status; } -static void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg) +static +void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg, + enum qdf_hang_reason reason) { WMA_LOGE("%s timed out, triggering recovery", mac_trace_get_wma_msg_string(wma_msg)); - cds_trigger_recovery(QDF_REASON_UNSPECIFIED); + qdf_trigger_self_recovery(NULL, reason); } static inline bool wma_crash_on_fw_timeout(bool crash_enabled) @@ -3827,37 +3149,40 @@ void wma_hold_req_timer(void *data) params->status = QDF_STATUS_E_TIMEOUT; WMA_LOGA(FL("WMA_ADD_STA_REQ timed out")); - WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"), - params->staMac, params->status); + WMA_LOGD(FL("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)"), + QDF_MAC_ADDR_REF(params->staMac), params->status); if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - WMA_ADD_STA_REQ); + WMA_ADD_STA_REQ, + QDF_AP_STA_CONNECT_REQ_TIMEOUT); wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)params, 0); } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) { - tpAddBssParams params = (tpAddBssParams) tgt_req->user_data; - params->status = QDF_STATUS_E_TIMEOUT; WMA_LOGA(FL("WMA_ADD_BSS_REQ timed out")); - WMA_LOGD(FL("Sending add bss rsp to umac (mac:%pM, status:%d)"), - params->self_mac_addr, params->status); + WMA_LOGD(FL("Sending add bss rsp to umac (vdev %d, status:%d)"), + tgt_req->vdev_id, QDF_STATUS_E_TIMEOUT); + if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - WMA_ADD_BSS_REQ); - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, - (void *)params, 0); + WMA_ADD_BSS_REQ, + QDF_STA_AP_CONNECT_REQ_TIMEOUT); + + wma_send_add_bss_resp(wma, tgt_req->vdev_id, + QDF_STATUS_E_TIMEOUT); } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && (tgt_req->type == WMA_DELETE_STA_RSP_START)) { tpDeleteStaParams params = (tpDeleteStaParams) tgt_req->user_data; params->status = QDF_STATUS_E_TIMEOUT; WMA_LOGE(FL("WMA_DEL_STA_REQ timed out")); - WMA_LOGE(FL("Sending del sta rsp to umac (mac:%pM, status:%d)"), - params->staMac, params->status); + WMA_LOGE(FL("Sending del sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)"), + QDF_MAC_ADDR_REF(params->staMac), params->status); if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - WMA_DELETE_STA_REQ); + WMA_DELETE_STA_REQ, + QDF_PEER_DELETION_TIMEDOUT); wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, (void *)params, 0); } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && @@ -3871,33 +3196,28 @@ void wma_hold_req_timer(void *data) if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - WMA_DELETE_STA_REQ); - wma_handle_vdev_detach(wma, del_sta->self_sta_param, - del_sta->generate_rsp); + WMA_DELETE_STA_REQ, + QDF_PEER_DELETION_TIMEDOUT); + status = wma_handle_vdev_detach(wma, del_sta->self_sta_param); + if (QDF_IS_STATUS_ERROR(status)) { + del_sta->self_sta_param->status = status; + wma_send_vdev_del_resp(del_sta->self_sta_param); + } qdf_mem_free(tgt_req->user_data); } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && - (tgt_req->type == WMA_SET_LINK_PEER_RSP)) { - tpLinkStateParams params = - (tpLinkStateParams) tgt_req->user_data; - - params->status = false; - WMA_LOGA(FL("wma delete peer for set link timed out")); - if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) - wma_trigger_recovery_assert_on_fw_timeout( - WMA_DELETE_STA_REQ); - wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, params, 0); - } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) && - (tgt_req->type == WMA_DELETE_PEER_RSP)) { - tpDeleteBssParams params = - (tpDeleteBssParams) tgt_req->user_data; + (tgt_req->type == WMA_SET_LINK_PEER_RSP || + tgt_req->type == WMA_DELETE_PEER_RSP)) { + struct del_bss_resp *params = + (struct del_bss_resp *)tgt_req->user_data; params->status = QDF_STATUS_E_TIMEOUT; WMA_LOGE(FL("wma delete peer for del bss req timed out")); if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - WMA_DELETE_STA_REQ); - wma_send_vdev_down_bss(wma, tgt_req); + WMA_DELETE_STA_REQ, + QDF_PEER_DELETION_TIMEDOUT); + wma_send_vdev_down_req(wma, params); } else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) && (tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) { struct sir_set_hw_mode_resp *params = @@ -3907,7 +3227,8 @@ void wma_hold_req_timer(void *data) if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - SIR_HAL_PDEV_SET_HW_MODE); + SIR_HAL_PDEV_SET_HW_MODE, + QDF_MAC_HW_MODE_CHANGE_TIMEOUT); if (!params) { WMA_LOGE(FL("Failed to allocate memory for params")); goto timer_destroy; @@ -3925,7 +3246,8 @@ void wma_hold_req_timer(void *data) WMA_LOGE(FL("set dual mac config timeout")); if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) wma_trigger_recovery_assert_on_fw_timeout( - SIR_HAL_PDEV_DUAL_MAC_CFG_REQ); + SIR_HAL_PDEV_DUAL_MAC_CFG_REQ, + QDF_MAC_HW_MODE_CONFIG_TIMEOUT); if (!resp) { WMA_LOGE(FL("Failed to allocate memory for resp")); goto timer_destroy; @@ -4014,388 +3336,59 @@ void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id, } /** - * wma_handle_channel_switch_req_timeout() - handle channel switch req timeout - * @wma: wma handler - * @tgt_req: target req + * wma_vdev_set_bss_params() - BSS set params functions + * @wma: wma handle + * @vdev_id: vdev id + * @beaconInterval: beacon interval + * @dtimPeriod: DTIM period + * @shortSlotTimeSupported: short slot time + * @llbCoexist: llbCoexist + * @maxTxPower: max tx power * * Return: none */ static void -wma_handle_channel_switch_req_timeout(tp_wma_handle wma, - struct wma_target_req *req) +wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id, + tSirMacBeaconInterval beaconInterval, + uint8_t dtimPeriod, uint8_t shortSlotTimeSupported, + uint8_t llbCoexist, int8_t maxTxPower) { - struct wma_txrx_node *iface; - tpSwitchChannelParams params = (tpSwitchChannelParams)req->user_data; + QDF_STATUS ret; + uint32_t slot_time; + struct wma_txrx_node *intr = wma->interfaces; - params->status = QDF_STATUS_E_TIMEOUT; - WMA_LOGA("%s: WMA_SWITCH_CHANNEL_REQ timedout", __func__); + /* Beacon Interval setting */ + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_BEACON_INTERVAL, + beaconInterval); - /* - * Trigger host crash if the flag is set or if the timeout - * is not due to fw down - */ - if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) - wma_trigger_recovery_assert_on_fw_timeout( - WMA_CHNL_SWITCH_REQ); - - iface = &wma->interfaces[req->vdev_id]; - mlme_set_chan_switch_in_progress(iface->vdev, false); - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - (void *)params, 0); -} - -/** - * wma_handle_cadd_bss_req_timeout() - handle add bss req timeout - * @wma: wma handler - * @req: target req - * - * Return: none - */ -static void -wma_handle_add_bss_req_timeout(tp_wma_handle wma, struct wma_target_req *req) -{ - struct wma_txrx_node *iface; - tpAddBssParams params = (tpAddBssParams)req->user_data; - - params->status = QDF_STATUS_E_TIMEOUT; - WMA_LOGA("%s: WMA_ADD_BSS_REQ timedout", __func__); - WMA_LOGD("%s: bssid %pM vdev_id %d", __func__, params->bssId, - req->vdev_id); - - if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) - wma_trigger_recovery_assert_on_fw_timeout(WMA_ADD_BSS_REQ); - - iface = &wma->interfaces[req->vdev_id]; - wlan_vdev_mlme_sm_deliver_evt(iface->vdev, - WLAN_VDEV_SM_EV_DOWN, - sizeof(*params), params); -} - -/** - * wma_vdev_resp_timer() - wma response timeout function - * @data: target request params - * - * Return: none - */ -void wma_vdev_resp_timer(void *data) -{ - tp_wma_handle wma; - struct wma_target_req *tgt_req = (struct wma_target_req *)data; - struct cdp_pdev *pdev; - uint8_t peer_id; - int status; - QDF_STATUS qdf_status; - void *peer; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wma_txrx_node *iface; - struct del_sta_self_params *del_sta_self_params; -#ifdef FEATURE_AP_MCC_CH_AVOIDANCE - struct mac_context *mac_ctx; -#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - - wma = cds_get_context(QDF_MODULE_ID_WMA); - - if (!wma) { - WMA_LOGE("%s: Failed to get wma", __func__); - wma_cleanup_target_req_param(tgt_req); - goto free_tgt_req; - } - - qdf_status = wma_find_vdev_req_on_timer_expiry(wma, tgt_req); - - if (QDF_IS_STATUS_ERROR(qdf_status)) { - /* - * if find request failed, then firmware rsp should have - * consumed the buffer. Do not free. - */ - WMA_LOGD("%s: Failed to lookup request message - %pK", - __func__, tgt_req); - return; - } - WMA_LOGA("%s: request %d is timed out for vdev_id - %d", __func__, - tgt_req->msg_type, tgt_req->vdev_id); - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - wma_cleanup_target_req_param(tgt_req); - qdf_mc_timer_stop(&tgt_req->event_timeout); - goto free_tgt_req; - } - -#ifdef FEATURE_AP_MCC_CH_AVOIDANCE - mac_ctx = cds_get_context(QDF_MODULE_ID_PE); - if (!mac_ctx) { - WMA_LOGE("%s: Failed to get mac_ctx", __func__); - wma_cleanup_target_req_param(tgt_req); - goto free_tgt_req; - } -#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - - if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ) { - - wma_handle_channel_switch_req_timeout(wma, tgt_req); - } else if (tgt_req->msg_type == WMA_DELETE_BSS_REQ) { - tpDeleteBssParams params = - (tpDeleteBssParams) tgt_req->user_data; - struct beacon_info *bcn; - - if (tgt_req->vdev_id >= wma->max_bssid) { - WMA_LOGE("%s: Invalid vdev_id %d", __func__, - tgt_req->vdev_id); - wma_cleanup_target_req_param(tgt_req); - qdf_mc_timer_stop(&tgt_req->event_timeout); - goto free_tgt_req; - } - - iface = &wma->interfaces[tgt_req->vdev_id]; - if (!iface->handle) { - WMA_LOGE("%s vdev id %d is already deleted", - __func__, tgt_req->vdev_id); - wma_cleanup_target_req_param(tgt_req); - qdf_mc_timer_stop(&tgt_req->event_timeout); - goto free_tgt_req; - } - /* - * Trigger host crash if the flag is set or if the timeout - * is not due to fw down - */ - if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) - wma_trigger_recovery_assert_on_fw_timeout( - WMA_DELETE_BSS_REQ); - - status = wma_remove_bss_peer(wma, pdev, tgt_req->vdev_id, - params); - if (status) { - WMA_LOGE("Del BSS failed call del bss response vdev_id:%d", tgt_req->vdev_id); - wma_send_vdev_down_bss(wma, tgt_req); - } - - if (wmi_service_enabled(wma->wmi_handle, - wmi_service_sync_delete_cmds)) - goto free_tgt_req; - - if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) != - QDF_STATUS_SUCCESS) { - WMA_LOGE("Failed to send vdev down cmd: vdev %d", - tgt_req->vdev_id); - } else { -#ifdef FEATURE_AP_MCC_CH_AVOIDANCE - if (mac_ctx->sap.sap_channel_avoidance) - wma_find_mcc_ap(wma, tgt_req->vdev_id, false); -#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - } - cdp_fc_vdev_flush(soc, iface->handle); - WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for WDA_DELETE_BSS_REQ timeout", - __func__, tgt_req->vdev_id); - cdp_fc_vdev_unpause(soc, iface->handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); - wma_vdev_clear_pause_bit(tgt_req->vdev_id, PAUSE_TYPE_HOST); - qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); - WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", - __func__, iface->type, iface->sub_type); - - bcn = wma->interfaces[tgt_req->vdev_id].beacon; - - if (bcn) { - WMA_LOGD("%s: Freeing beacon struct %pK, template memory %pK", - __func__, bcn, bcn->buf); - if (bcn->dma_mapped) - qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, - QDF_DMA_TO_DEVICE); - qdf_nbuf_free(bcn->buf); - qdf_mem_free(bcn); - wma->interfaces[tgt_req->vdev_id].beacon = NULL; - } - params->status = QDF_STATUS_E_TIMEOUT; - WMA_LOGA("%s: WMA_DELETE_BSS_REQ timedout", __func__); - wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, - (void *)params, 0); - if (iface->del_staself_req && iface->is_del_sta_defered) { - iface->is_del_sta_defered = false; - WMA_LOGA("scheduling defered deletion(vdev id %x)", - tgt_req->vdev_id); - wma_vdev_detach(wma, iface->del_staself_req, 1); - } - } else if (tgt_req->msg_type == WMA_DEL_STA_SELF_REQ) { - iface = (struct wma_txrx_node *)tgt_req->user_data; - del_sta_self_params = - (struct del_sta_self_params *) iface->del_staself_req; - - if (wmi_service_enabled(wma->wmi_handle, - wmi_service_sync_delete_cmds)) { - wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); - } - del_sta_self_params->status = QDF_STATUS_E_TIMEOUT; - - WMA_LOGA("%s: WMA_DEL_STA_SELF_REQ timedout", __func__); - - if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) { - wma_trigger_recovery_assert_on_fw_timeout( - WMA_DEL_STA_SELF_REQ); - } - wma_send_del_sta_self_resp(iface->del_staself_req); - iface->del_staself_req = NULL; - - wma_vdev_deinit(iface); - qdf_mem_zero(iface, sizeof(*iface)); - wma_vdev_init(iface); - } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) { - - wma_handle_add_bss_req_timeout(wma, tgt_req); - } else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) { - if (wma_get_hidden_ssid_restart_in_progress( - &wma->interfaces[tgt_req->vdev_id]) && - wma_is_vdev_in_ap_mode(wma, tgt_req->vdev_id)) { - - WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d", - tgt_req->vdev_id, tgt_req->type); - qdf_mem_free(tgt_req->user_data); - } - } else if (tgt_req->msg_type == WMA_SET_LINK_STATE) { - tpLinkStateParams params = - (tpLinkStateParams) tgt_req->user_data; - - peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id); - if (peer) { - WMA_LOGP(FL("Deleting peer %pM vdev id %d"), - params->bssid, tgt_req->vdev_id); - wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, - peer, false); - } - if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) != - QDF_STATUS_SUCCESS) { - WMA_LOGE("Failed to send vdev down cmd: vdev %d", - tgt_req->vdev_id); - } - params->status = QDF_STATUS_E_TIMEOUT; - WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__, - tgt_req->vdev_id); - wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); - } -free_tgt_req: - qdf_mc_timer_destroy(&tgt_req->event_timeout); - qdf_mem_free(tgt_req); -} - -/** - * wma_fill_vdev_req() - fill vdev request - * @wma: wma handle - * @msg_type: message type - * @type: request type - * @params: request params - * @timeout: timeout value - * - * Return: wma_target_req ptr - */ -struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, - uint8_t vdev_id, - uint32_t msg_type, uint8_t type, - void *params, uint32_t timeout) -{ - struct wma_target_req *req; - QDF_STATUS status; - - req = qdf_mem_malloc(sizeof(*req)); - if (!req) - return NULL; - - WMA_LOGD("%s: vdev_id %d msg %d", __func__, vdev_id, msg_type); - qdf_spin_lock_bh(&wma->vdev_respq_lock); - req->vdev_id = vdev_id; - req->msg_type = msg_type; - req->type = type; - req->user_data = params; - status = qdf_list_insert_back(&wma->vdev_resp_queue, &req->node); - if (QDF_STATUS_SUCCESS != status) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGE(FL("Failed add request in queue for vdev_id %d type %d"), - vdev_id, type); - qdf_mem_free(req); - return NULL; - } - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW, - wma_vdev_resp_timer, req); - qdf_mc_timer_start(&req->event_timeout, timeout); - return req; -} - -/** - * wma_remove_vdev_req() - remove vdev request - * @wma: wma handle - * @vdev_id: vdev id - * @type: type - * - * Return: none - */ -void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id, - uint8_t type) -{ - struct wma_target_req *req_msg; - - req_msg = wma_find_vdev_req(wma, vdev_id, type, true); - if (!req_msg) - return; - - qdf_mc_timer_stop(&req_msg->event_timeout); - qdf_mc_timer_destroy(&req_msg->event_timeout); - qdf_mem_free(req_msg); -} - -/** - * wma_vdev_set_bss_params() - BSS set params functions - * @wma: wma handle - * @vdev_id: vdev id - * @beaconInterval: beacon interval - * @dtimPeriod: DTIM period - * @shortSlotTimeSupported: short slot time - * @llbCoexist: llbCoexist - * @maxTxPower: max tx power - * - * Return: none - */ -static void -wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id, - tSirMacBeaconInterval beaconInterval, - uint8_t dtimPeriod, uint8_t shortSlotTimeSupported, - uint8_t llbCoexist, int8_t maxTxPower) -{ - QDF_STATUS ret; - uint32_t slot_time; - struct wma_txrx_node *intr = wma->interfaces; - - /* Beacon Interval setting */ - ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_BEACON_INTERVAL, - beaconInterval); - - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set WMI_VDEV_PARAM_BEACON_INTERVAL"); - ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id, - &intr[vdev_id].config.gtx_info); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); - ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_DTIM_PERIOD, - dtimPeriod); - intr[vdev_id].dtimPeriod = dtimPeriod; - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("failed to set WMI_VDEV_PARAM_BEACON_INTERVAL"); + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id, + &intr[vdev_id].config.gtx_info); + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DTIM_PERIOD, + dtimPeriod); + intr[vdev_id].dtimPeriod = dtimPeriod; + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); if (!maxTxPower) WMA_LOGW("Setting Tx power limit to 0"); - WMA_LOGD("Set maxTx pwr [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d", - maxTxPower); - ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_TX_PWRLIMIT, - maxTxPower); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("failed to set WMI_VDEV_PARAM_TX_PWRLIMIT"); - else - intr[vdev_id].max_tx_power = maxTxPower; - + wma_debug("Set max Tx power to %d", maxTxPower); + if (maxTxPower != INVALID_TXPOWER) { + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_PWRLIMIT, + maxTxPower); + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("failed to set WMI_VDEV_PARAM_TX_PWRLIMIT"); + else + mlme_set_max_reg_power(intr[vdev_id].vdev, maxTxPower); + } else { + wma_err("Invalid max Tx power"); + } /* Slot time */ if (shortSlotTimeSupported) slot_time = WMI_VDEV_SLOT_TIME_SHORT; @@ -4453,13 +3446,14 @@ wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac, wlan_objmgr_pdev_get_pdev_id(wma->pdev), peer_mac, WLAN_LEGACY_WMA_ID); if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", - peer_mac); + WMA_LOGE("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); return QDF_STATUS_E_INVAL; } mlme_set_peer_pmf_status(peer, is_pmf_enabled); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - WMA_LOGD("set is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac); + WMA_LOGD("set is_pmf_enabled %d for "QDF_MAC_ADDR_FMT, + is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac)); return QDF_STATUS_SUCCESS; } @@ -4476,635 +3470,477 @@ wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac, } #endif /* WLAN_FEATURE_11W */ -/** - * wma_add_bss_ap_mode() - process add bss request in ap mode - * @wma: wma handle - * @add_bss: add bss parameters - * - * Return: none - */ -static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss) +QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, + struct bss_params *add_bss) { - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - struct wma_vdev_start_req req; - void *peer; - struct wma_target_req *msg; - uint8_t vdev_id, peer_id; QDF_STATUS status; - int8_t maxTxPower; - struct policy_mgr_hw_mode_params hw_mode = {0}; void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct wma_txrx_node *iface; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct vdev_mlme_obj *mlme_obj; + uint8_t *mac_addr; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - goto send_fail_resp; + if (!soc) { + wma_err("Invalid soc"); + return QDF_STATUS_E_FAILURE; } + if (!wma) { + wma_err("Invalid wma handle"); + return QDF_STATUS_E_FAILURE; + } + iface = &wma->interfaces[vdev_id]; - vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id); - if (!vdev) { - wma_err("Failed to get vdev handle:"QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(add_bss->bssId)); - - goto send_fail_resp; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; } - if (SAP_WPS_DISABLED == add_bss->wps_state) - ucfg_pmo_disable_wakeup_event(wma->psoc, vdev_id, - WOW_PROBE_REQ_WPS_IE_EVENT); + wma_set_bss_rate_flags(wma, vdev_id, add_bss); - status = wma_create_peer(wma, pdev, vdev, add_bss->bssId, + if (wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_NDI_MODE || + wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_IBSS_MODE) + mac_addr = mlme_obj->mgmt.generic.bssid; + else + mac_addr = wlan_vdev_mlme_get_macaddr(iface->vdev); + + status = wma_create_peer(wma, mac_addr, WMI_PEER_TYPE_DEFAULT, vdev_id, false); if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create peer", __func__); - goto send_fail_resp; + wma_err("Failed to create peer"); + return status; } - peer = cdp_peer_find_by_addr(soc, pdev, - add_bss->bssId, &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - add_bss->bssId); - goto send_fail_resp; + if (!cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, mac_addr)) { + wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr)); + return QDF_STATUS_E_FAILURE; } - msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ, - WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s Failed to allocate vdev request vdev_id %d", - __func__, vdev_id); - goto peer_cleanup; + + iface->rmfEnabled = add_bss->rmfEnabled; + if (add_bss->rmfEnabled) + wma_set_mgmt_frame_protection(wma); + + if (wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_IBSS_MODE) { + tSetBssKeyParams key_info; + /* clear leftover ibss keys on bss peer */ + wma_debug("ibss bss key clearing"); + qdf_mem_zero(&key_info, sizeof(key_info)); + key_info.vdev_id = vdev_id; + key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + qdf_mem_copy(&wma->ibsskey_info, &key_info, + sizeof(tSetBssKeyParams)); + /* + * If IBSS Power Save is supported by firmware + * set the IBSS power save params to firmware. + */ + if (wmi_service_enabled(wma->wmi_handle, + wmi_service_ibss_pwrsave)) { + status = wma_set_ibss_pwrsave_params(wma, vdev_id); + } } + return status; +} - iface = &wma->interfaces[vdev_id]; +QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *intr; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev; + uint8_t bss_power; - add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer); + if (!wma) { + wma_err("Invalid wma handle"); + return QDF_STATUS_E_FAILURE; + } + intr = &wma->interfaces[vdev_id]; + if (!intr) { + wma_err("Invalid interface"); + return QDF_STATUS_E_FAILURE; + } + vdev = intr->vdev; + if (!vdev) { + wma_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NDI_MODE || + wlan_vdev_mlme_get_opmode(vdev) == QDF_IBSS_MODE) { + /* Initialize protection mode to no protection */ + wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PROTECTION_MODE, + IEEE80211_PROT_NONE); + return status; + } + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + /* Fill bss_chan after vdev start */ + qdf_mem_copy(vdev->vdev_mlme.bss_chan, + vdev->vdev_mlme.des_chan, + sizeof(struct wlan_channel)); - qdf_mem_zero(&req, sizeof(req)); - req.vdev_id = vdev_id; - req.chan = add_bss->currentOperChannel; - req.chan_width = add_bss->ch_width; - req.dot11_mode = add_bss->dot11_mode; + bss_power = wlan_reg_get_channel_reg_power_for_freq(wma->pdev, + vdev->vdev_mlme.bss_chan->ch_freq); + wma_vdev_set_bss_params(wma, vdev_id, + mlme_obj->proto.generic.beacon_interval, + mlme_obj->proto.generic.dtim_period, + mlme_obj->proto.generic.slot_time, + mlme_obj->proto.generic.protection_mode, + bss_power); + + wma_vdev_set_he_bss_params(wma, vdev_id, + &mlme_obj->proto.he_ops_info); + + return status; +} - if (add_bss->ch_width == CH_WIDTH_10MHZ) - req.is_half_rate = 1; - else if (add_bss->ch_width == CH_WIDTH_5MHZ) - req.is_quarter_rate = 1; +static QDF_STATUS wma_update_iface_params(tp_wma_handle wma, + struct bss_params *add_bss) +{ + struct wma_txrx_node *iface; + uint8_t vdev_id; - req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0; - req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1; - req.vht_capable = add_bss->vhtCapable; - wma_update_vdev_he_ops(&req, add_bss); + vdev_id = add_bss->staContext.smesessionId; + iface = &wma->interfaces[vdev_id]; + wma_set_bss_rate_flags(wma, vdev_id, add_bss); - req.max_txpow = add_bss->maxTxPower; - maxTxPower = add_bss->maxTxPower; + if (iface->addBssStaContext) + qdf_mem_free(iface->addBssStaContext); + iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams)); + if (!iface->addBssStaContext) + return QDF_STATUS_E_RESOURCES; + *iface->addBssStaContext = add_bss->staContext; + if (iface->staKeyParams) { + qdf_mem_free(iface->staKeyParams); + iface->staKeyParams = NULL; + } + if (add_bss->extSetStaKeyParamValid) { + iface->staKeyParams = + qdf_mem_malloc(sizeof(tSetStaKeyParams)); + if (!iface->staKeyParams) { + qdf_mem_free(iface->addBssStaContext); + iface->addBssStaContext = NULL; + return QDF_STATUS_E_RESOURCES; + } + *iface->staKeyParams = add_bss->extSetStaKeyParam; + } + /* Save parameters later needed by WMA_ADD_STA_REQ */ iface->rmfEnabled = add_bss->rmfEnabled; if (add_bss->rmfEnabled) - wma_set_mgmt_frame_protection(wma); + wma_set_peer_pmf_status(wma, add_bss->bssId, true); + iface->beaconInterval = add_bss->beaconInterval; + iface->llbCoexist = add_bss->llbCoexist; + iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported; + iface->nwType = add_bss->nwType; - req.dot11_mode = add_bss->dot11_mode; - req.beacon_intval = add_bss->beaconInterval; - req.dtim_period = add_bss->dtimPeriod; - req.beacon_tx_rate = add_bss->beacon_tx_rate; - req.hidden_ssid = add_bss->bHiddenSSIDEn; - req.is_dfs = add_bss->bSpectrumMgtEnabled; - req.oper_mode = BSS_OPERATIONAL_MODE_AP; - req.ssid.length = add_bss->ssId.length; - req.cac_duration_ms = add_bss->cac_duration_ms; - req.dfs_regdomain = add_bss->dfs_regdomain; - if (req.ssid.length > 0) - qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, - add_bss->ssId.length); - status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode); - if (!QDF_IS_STATUS_SUCCESS(status)) - WMA_LOGE("policy_mgr_get_current_hw_mode failed"); - - if (add_bss->nss == 2) { - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; - } else { - req.preferred_rx_streams = 1; - req.preferred_tx_streams = 1; - } + return QDF_STATUS_SUCCESS; +} - status = wma_vdev_start(wma, &req, false); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - goto peer_cleanup; +static inline +bool wma_cdp_find_peer_by_addr(uint8_t *peer_addr) +{ + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + uint8_t pdev_id = OL_TXRX_PDEV_ID; + + if (!soc || pdev_id == OL_TXRX_INVALID_PDEV_ID) { + WMA_LOGE("%s Failed to get pdev/soc", __func__); + return NULL; } - wma_vdev_set_bss_params(wma, vdev_id, - add_bss->beaconInterval, add_bss->dtimPeriod, - add_bss->shortSlotTimeSupported, - add_bss->llbCoexist, maxTxPower); + return cdp_find_peer_exist(soc, pdev_id, peer_addr); +} - wma_vdev_set_he_bss_params(wma, vdev_id, &req); - return; +static +QDF_STATUS wma_save_bss_params(tp_wma_handle wma, struct bss_params *add_bss) +{ + QDF_STATUS status; -peer_cleanup: - wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false); -send_fail_resp: - add_bss->status = QDF_STATUS_E_FAILURE; - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); + wma_vdev_set_he_config(wma, add_bss->staContext.smesessionId, add_bss); + if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) + status = QDF_STATUS_E_FAILURE; + else + status = QDF_STATUS_SUCCESS; + qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId, + sizeof(add_bss->staContext.staMac)); + + WMA_LOGD("%s: update_bss %d nw_type %d bssid "QDF_MAC_ADDR_FMT" status %d", + __func__, add_bss->updateBss, add_bss->nwType, + QDF_MAC_ADDR_REF(add_bss->bssId), status); + + return status; } -#ifdef QCA_IBSS_SUPPORT -/** - * wma_add_bss_ibss_mode() - process add bss request in IBSS mode - * @wma: wma handle - * @add_bss: add bss parameters - * - * Return: none - */ -static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) +QDF_STATUS wma_pre_assoc_req(struct bss_params *add_bss) { - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - struct wma_vdev_start_req req; - void *peer = NULL; - struct wma_target_req *msg; - uint8_t vdev_id, peer_id; QDF_STATUS status; - tSetBssKeyParams key_info; - struct policy_mgr_hw_mode_params hw_mode = {0}; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); + tp_wma_handle wma; - vdev = wma_find_vdev_by_addr(wma, add_bss->self_mac_addr, &vdev_id); - if (!vdev) { - WMA_LOGE("%s: vdev not found for vdev id %d.", - __func__, vdev_id); - goto send_fail_resp; + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + WMA_LOGE("Invalid wma"); + return QDF_STATUS_E_INVAL; } - WMA_LOGD("%s: add_bss->sessionId = %d", __func__, vdev_id); - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - goto send_fail_resp; - } - wma_set_bss_rate_flags(wma, vdev_id, add_bss); + status = wma_update_iface_params(wma, add_bss); + if (QDF_IS_STATUS_ERROR(status)) + return status; - /* create ibss bss peer */ - status = wma_create_peer(wma, pdev, vdev, add_bss->self_mac_addr, - WMI_PEER_TYPE_DEFAULT, vdev_id, - false); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create peer", __func__); - goto send_fail_resp; - } - WMA_LOGA("IBSS BSS peer created with mac %pM", - add_bss->self_mac_addr); + status = wma_save_bss_params(wma, add_bss); - peer = cdp_peer_find_by_addr(soc, pdev, - add_bss->self_mac_addr, &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - add_bss->self_mac_addr); - goto send_fail_resp; + return status; +} + +void wma_add_bss_lfr3(tp_wma_handle wma, struct bss_params *add_bss) +{ + QDF_STATUS status; + + status = wma_update_iface_params(wma, add_bss); + if (QDF_IS_STATUS_ERROR(status)) + return; + + if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) { + WMA_LOGE("%s Failed to find peer "QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(add_bss->bssId)); + return; } + WMA_LOGD("LFR3:%s: bssid "QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(add_bss->bssId)); +} - /* clear leftover ibss keys on bss peer */ - WMA_LOGD("%s: ibss bss key clearing", __func__); - qdf_mem_zero(&key_info, sizeof(key_info)); - key_info.smesessionId = vdev_id; - key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; - qdf_mem_copy(&wma->ibsskey_info, &key_info, sizeof(tSetBssKeyParams)); +#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) +static +QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id) +{ + void *soc = cds_get_context(QDF_MODULE_ID_SOC); - /* start ibss vdev */ + cdp_fc_vdev_pause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, 0); - add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS; + return QDF_STATUS_SUCCESS; +} +#else +static inline +QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif - msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ, - WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s Failed to allocate vdev request vdev_id %d", - __func__, vdev_id); - goto peer_cleanup; - } - WMA_LOGD("%s: vdev start request for IBSS enqueued", __func__); +void wma_send_add_bss_resp(tp_wma_handle wma, uint8_t vdev_id, + QDF_STATUS status) +{ + struct add_bss_rsp *add_bss_rsp; - add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer); + add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp)); + if (!add_bss_rsp) + return; - /* - * If IBSS Power Save is supported by firmware - * set the IBSS power save params to firmware. - */ - if (wmi_service_enabled(wma->wmi_handle, - wmi_service_ibss_pwrsave)) { - status = wma_set_ibss_pwrsave_params(wma, vdev_id); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to Set IBSS Power Save Params to firmware", - __func__); - goto peer_cleanup; - } + add_bss_rsp->vdev_id = vdev_id; + add_bss_rsp->status = status; + lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp); +} + +#ifdef WLAN_FEATURE_HOST_ROAM +QDF_STATUS wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev *vdev, + struct bss_params *add_bss) +{ + tp_wma_handle wma; + QDF_STATUS status; + struct vdev_mlme_obj *mlme_obj; + uint8_t vdev_id; + bool peer_exist = false; + + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma || !vdev) { + WMA_LOGE("Invalid wma or vdev"); + return QDF_STATUS_E_INVAL; } - qdf_mem_zero(&req, sizeof(req)); - req.vdev_id = vdev_id; - req.chan = add_bss->currentOperChannel; - req.chan_width = add_bss->ch_width; - req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0; - req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1; - req.vht_capable = add_bss->vhtCapable; -#if defined WLAN_FEATURE_VOWIF - req.max_txpow = add_bss->maxTxPower; -#else - req.max_txpow = 0; -#endif /* WLAN_FEATURE_VOWIF */ - req.beacon_intval = add_bss->beaconInterval; - req.dtim_period = add_bss->dtimPeriod; - req.hidden_ssid = add_bss->bHiddenSSIDEn; - req.is_dfs = add_bss->bSpectrumMgtEnabled; - req.oper_mode = BSS_OPERATIONAL_MODE_IBSS; - req.ssid.length = add_bss->ssId.length; - if (req.ssid.length > 0) - qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, - add_bss->ssId.length); - status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode); - if (!QDF_IS_STATUS_SUCCESS(status)) - WMA_LOGE("policy_mgr_get_current_hw_mode failed"); - - if (add_bss->nss == 2) { - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; - } else { - req.preferred_rx_streams = 1; - req.preferred_tx_streams = 1; + vdev_id = vdev->vdev_objmgr.vdev_id; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; } - WMA_LOGD("%s: chan %d chan_width %d", __func__, req.chan, - req.chan_width); - WMA_LOGD("%s: ssid = %s", __func__, req.ssid.ssId); + status = wma_update_iface_params(wma, add_bss); + if (QDF_IS_STATUS_ERROR(status)) + goto send_fail_resp; + + peer_exist = wma_cdp_find_peer_by_addr(mlme_obj->mgmt.generic.bssid); + if (!peer_exist) { + wma_err("Failed to find peer "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mlme_obj->mgmt.generic.bssid)); + goto send_fail_resp; + } - status = wma_vdev_start(wma, &req, false); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); + status = wma_vdev_pre_start(vdev_id, false); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("failed, status: %d", status); goto peer_cleanup; } - WMA_LOGD("%s: vdev start request for IBSS sent to target", __func__); - - /* Initialize protection mode to no protection */ - status = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_PROTECTION_MODE, - IEEE80211_PROT_NONE); + status = vdev_mgr_start_send(mlme_obj, false); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("failed, status: %d", status); + goto peer_cleanup; + } + status = wma_set_cdp_vdev_pause_reason(wma, vdev_id); if (QDF_IS_STATUS_ERROR(status)) - WMA_LOGE("Failed to initialize protection mode"); + goto peer_cleanup; - return; + /* ADD_BSS_RESP will be deferred to completion of VDEV_START */ + return QDF_STATUS_SUCCESS; peer_cleanup: - if (peer) - wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false); + if (peer_exist) + wma_remove_peer(wma, mlme_obj->mgmt.generic.bssid, vdev_id, + false); + send_fail_resp: - add_bss->status = QDF_STATUS_E_FAILURE; - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); + wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE); + + return QDF_STATUS_SUCCESS; } -#endif /* QCA_IBSS_SUPPORT */ +#endif -/** - * wma_add_bss_sta_mode() - process add bss request in sta mode - * @wma: wma handle - * @add_bss: add bss parameters - * - * Return: none - */ -static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss) +QDF_STATUS wma_send_peer_assoc_req(struct bss_params *add_bss) { - struct cdp_pdev *pdev; - struct wma_vdev_start_req req; struct wma_target_req *msg; - uint8_t vdev_id = 0, peer_id; - void *peer = NULL; + tp_wma_handle wma; + uint8_t vdev_id; + bool peer_exist; QDF_STATUS status; struct wma_txrx_node *iface; int pps_val = 0; - bool roam_synch_in_progress = false; + struct vdev_mlme_obj *mlme_obj; struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); - struct policy_mgr_hw_mode_params hw_mode = {0}; - bool peer_assoc_sent = false; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - if (!mac) { - WMA_LOGE("%s: Unable to get PE context", __func__); - goto send_fail_resp; + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + WMA_LOGE("Invalid wma"); + return QDF_STATUS_E_INVAL; } - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s Failed to get pdev", __func__); - goto send_fail_resp; + if (!mac) { + WMA_LOGE("Invalid mac context"); + return QDF_STATUS_E_INVAL; } vdev_id = add_bss->staContext.smesessionId; - iface = &wma->interfaces[vdev_id]; - - wma_set_bss_rate_flags(wma, vdev_id, add_bss); - if (add_bss->operMode) { - /* Save parameters later needed by WMA_ADD_STA_REQ */ - if (iface->addBssStaContext) - qdf_mem_free(iface->addBssStaContext); - iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams)); - if (!iface->addBssStaContext) - goto send_fail_resp; - qdf_mem_copy(iface->addBssStaContext, &add_bss->staContext, - sizeof(tAddStaParams)); - - if (iface->staKeyParams) { - qdf_mem_free(iface->staKeyParams); - iface->staKeyParams = NULL; - } - if (add_bss->extSetStaKeyParamValid) { - iface->staKeyParams = - qdf_mem_malloc(sizeof(tSetStaKeyParams)); - if (!iface->staKeyParams) - goto send_fail_resp; - - qdf_mem_copy(iface->staKeyParams, - &add_bss->extSetStaKeyParam, - sizeof(tSetStaKeyParams)); - } - /* Save parameters later needed by WMA_ADD_STA_REQ */ - iface->rmfEnabled = add_bss->rmfEnabled; - iface->beaconInterval = add_bss->beaconInterval; - iface->llbCoexist = add_bss->llbCoexist; - iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported; - iface->nwType = add_bss->nwType; - if (add_bss->rmfEnabled) - wma_set_peer_pmf_status(wma, add_bss->bssId, true); - if (add_bss->nonRoamReassoc) { - peer = cdp_peer_find_by_addr(soc, - pdev, add_bss->bssId, - &peer_id); - if (peer) { - add_bss->staContext.staIdx = - cdp_peer_get_local_peer_id(soc, peer); - goto send_bss_resp; - } - } - if (add_bss->reassocReq) { -#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) - struct cdp_vdev *vdev; -#endif - /* Called in preassoc state. BSSID peer is already - * added by set_linkstate - */ - peer = cdp_peer_find_by_addr(soc, - pdev, - add_bss->bssId, - &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - add_bss->bssId); - goto send_fail_resp; - } - if (wma_is_roam_synch_in_progress(wma, vdev_id)) { - add_bss->staContext.staIdx = - cdp_peer_get_local_peer_id(soc, peer); - WMA_LOGD("LFR3:%s: bssid %pM staIdx %d", - __func__, add_bss->bssId, - add_bss->staContext.staIdx); - return; - } - msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ, - WMA_TARGET_REQ_TYPE_VDEV_START, - add_bss, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s Failed to allocate vdev request vdev_id %d", - __func__, vdev_id); - goto peer_cleanup; - } + iface = &wma->interfaces[vdev_id]; + status = wma_update_iface_params(wma, add_bss); + if (QDF_IS_STATUS_ERROR(status)) + goto send_resp; - add_bss->staContext.staIdx = - cdp_peer_get_local_peer_id(soc, peer); - - qdf_mem_zero(&req, sizeof(req)); - req.vdev_id = vdev_id; - req.chan = add_bss->currentOperChannel; - req.chan_width = add_bss->ch_width; - - if (add_bss->ch_width == CH_WIDTH_10MHZ) - req.is_half_rate = 1; - else if (add_bss->ch_width == CH_WIDTH_5MHZ) - req.is_quarter_rate = 1; - - req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0; - req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1; - req.max_txpow = add_bss->maxTxPower; - req.beacon_intval = add_bss->beaconInterval; - req.dtim_period = add_bss->dtimPeriod; - req.hidden_ssid = add_bss->bHiddenSSIDEn; - req.is_dfs = add_bss->bSpectrumMgtEnabled; - req.ssid.length = add_bss->ssId.length; - req.oper_mode = BSS_OPERATIONAL_MODE_STA; - if (req.ssid.length > 0) - qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, - add_bss->ssId.length); - status = policy_mgr_get_current_hw_mode(wma->psoc, - &hw_mode); - if (!QDF_IS_STATUS_SUCCESS(status)) - WMA_LOGE("policy_mgr_get_current_hw_mode failed"); - - if (add_bss->nss == 2) { - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; - } else { - req.preferred_rx_streams = 1; - req.preferred_tx_streams = 1; - } + peer_exist = wma_cdp_find_peer_by_addr(add_bss->bssId); + if (add_bss->nonRoamReassoc && peer_exist) + goto send_resp; - status = wma_vdev_start(wma, &req, false); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - goto peer_cleanup; - } -#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) - vdev = wma_find_vdev_by_id(wma, vdev_id); - if (!vdev) { - WMA_LOGE("%s Invalid txrx vdev", __func__); - goto peer_cleanup; - } - cdp_fc_vdev_pause(soc, vdev, - OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); -#endif - /* ADD_BSS_RESP will be deferred to completion of - * VDEV_START - */ - return; - } - if (!add_bss->updateBss) - goto send_bss_resp; - /* Update peer state */ - if (add_bss->staContext.encryptType == eSIR_ED_NONE) { - WMA_LOGD("%s: Update peer(%pM) state into auth", - __func__, add_bss->bssId); - cdp_peer_state_update(soc, pdev, add_bss->bssId, - OL_TXRX_PEER_STATE_AUTH); - } else { -#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) - struct cdp_vdev *vdev; -#endif - WMA_LOGD("%s: Update peer(%pM) state into conn", - __func__, add_bss->bssId); - cdp_peer_state_update(soc, pdev, add_bss->bssId, - OL_TXRX_PEER_STATE_CONN); -#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) - peer = cdp_peer_find_by_addr(soc, pdev, add_bss->bssId, - &peer_id); - if (!peer) { - WMA_LOGE("%s:%d Failed to find peer %pM", - __func__, __LINE__, add_bss->bssId); - goto send_fail_resp; - } + if (!add_bss->updateBss) + goto send_resp; - vdev = wma_find_vdev_by_id(wma, vdev_id); - if (!vdev) { - WMA_LOGE("%s Invalid txrx vdev", __func__); - goto peer_cleanup; - } - cdp_fc_vdev_pause(soc, vdev, - OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); -#endif - } + if (!peer_exist) { + WMA_LOGE("%s: %d Failed to find peer "QDF_MAC_ADDR_FMT, + __func__, __LINE__, QDF_MAC_ADDR_REF(add_bss->bssId)); + status = QDF_STATUS_E_FAILURE; + goto send_resp; + } - wmi_unified_send_txbf(wma, &add_bss->staContext); - pps_val = ((mac->mlme_cfg->sta.enable_5g_ebt << 31) & - 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff); - status = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_PACKET_POWERSAVE, - pps_val); + if (add_bss->staContext.encryptType == eSIR_ED_NONE) { + WMA_LOGD("%s: Update peer("QDF_MAC_ADDR_FMT") state into auth", + __func__, QDF_MAC_ADDR_REF(add_bss->bssId)); + cdp_peer_state_update(soc, add_bss->bssId, + OL_TXRX_PEER_STATE_AUTH); + } else { + WMA_LOGD("%s: Update peer("QDF_MAC_ADDR_FMT") state into conn", + __func__, QDF_MAC_ADDR_REF(add_bss->bssId)); + cdp_peer_state_update(soc, add_bss->bssId, + OL_TXRX_PEER_STATE_CONN); + status = wma_set_cdp_vdev_pause_reason(wma, vdev_id); if (QDF_IS_STATUS_ERROR(status)) - WMA_LOGE("Failed to send wmi packet power save cmd"); - else - WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, status = %d", - pps_val, status); + goto send_resp; + } - add_bss->staContext.no_ptk_4_way = add_bss->no_ptk_4_way; + wmi_unified_send_txbf(wma, &add_bss->staContext); - status = wma_send_peer_assoc(wma, add_bss->nwType, - &add_bss->staContext); - if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("Failed to send peer assoc status:%d", status); - goto peer_cleanup; - } - peer_assoc_sent = true; + pps_val = ((mac->mlme_cfg->sta.enable_5g_ebt << 31) & + 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff); + status = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PACKET_POWERSAVE, + pps_val); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("Failed to send wmi packet power save cmd"); + else + WMA_LOGD("Sent packet power save %x", pps_val); - /* we just had peer assoc, so install key will be done later */ - if (add_bss->staContext.encryptType != eSIR_ED_NONE) - iface->is_waiting_for_key = true; + add_bss->staContext.no_ptk_4_way = add_bss->no_ptk_4_way; - if (add_bss->rmfEnabled) - wma_set_mgmt_frame_protection(wma); + status = wma_send_peer_assoc(wma, add_bss->nwType, + &add_bss->staContext); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("Failed to send peer assoc status:%d", status); + goto send_resp; + } - wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId, - add_bss->beaconInterval, - add_bss->dtimPeriod, - add_bss->shortSlotTimeSupported, - add_bss->llbCoexist, - add_bss->maxTxPower); + /* we just had peer assoc, so install key will be done later */ + if (add_bss->staContext.encryptType != eSIR_ED_NONE) + iface->is_waiting_for_key = true; - /* - * Store the bssid in interface table, bssid will - * be used during group key setting sta mode. - */ - qdf_mem_copy(iface->bssid, add_bss->bssId, QDF_MAC_ADDR_SIZE); + if (add_bss->rmfEnabled) + wma_set_mgmt_frame_protection(wma); + wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId, + add_bss->beaconInterval, + add_bss->dtimPeriod, + add_bss->shortSlotTimeSupported, + add_bss->llbCoexist, + add_bss->maxTxPower); + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!mlme_obj) { + WMA_LOGE("Failed to mlme obj"); + status = QDF_STATUS_E_FAILURE; + goto send_resp; } -send_bss_resp: + /* + * Store the bssid in interface table, bssid will + * be used during group key setting sta mode. + */ + qdf_mem_copy(mlme_obj->mgmt.generic.bssid, + add_bss->bssId, QDF_MAC_ADDR_SIZE); - wma_vdev_set_he_config(wma, vdev_id, add_bss); - if (!cdp_peer_find_by_addr(soc, pdev, add_bss->bssId, - &add_bss->staContext.staIdx)) - add_bss->status = QDF_STATUS_E_FAILURE; - else - add_bss->status = QDF_STATUS_SUCCESS; - add_bss->bss_idx = add_bss->staContext.smesessionId; - qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId, - sizeof(add_bss->staContext.staMac)); + wma_save_bss_params(wma, add_bss); if (!wmi_service_enabled(wma->wmi_handle, - wmi_service_peer_assoc_conf)) { - WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled")); - goto send_final_rsp; + wmi_service_peer_assoc_conf)) { + WMA_LOGI(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled")); + goto send_resp; } - /* In case of reassoc, peer assoc cmd will not be sent */ - if (!peer_assoc_sent) - goto send_final_rsp; - msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ, - WMA_PEER_ASSOC_CNF_START, add_bss, - WMA_PEER_ASSOC_TIMEOUT); + WMA_PEER_ASSOC_CNF_START, NULL, + WMA_PEER_ASSOC_TIMEOUT); if (!msg) { WMA_LOGE(FL("Failed to allocate request for vdev_id %d"), vdev_id); wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START); - goto peer_cleanup; + status = QDF_STATUS_E_FAILURE; + goto send_resp; } - return; - -send_final_rsp: - WMA_LOGD("%s: opermode %d update_bss %d nw_type %d bssid %pM staIdx %d status %d", - __func__, add_bss->operMode, - add_bss->updateBss, add_bss->nwType, add_bss->bssId, - add_bss->staContext.staIdx, add_bss->status); - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); - return; - -peer_cleanup: - if (peer) - wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, - roam_synch_in_progress); -send_fail_resp: - add_bss->status = QDF_STATUS_E_FAILURE; - if (!wma_is_roam_synch_in_progress(wma, vdev_id)) - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, - (void *)add_bss, 0); -} - -/** - * wma_add_bss() - Add BSS request to fw as per opmode - * @wma: wma handle - * @params: add bss params - * - * Return: none - */ -void wma_add_bss(tp_wma_handle wma, tpAddBssParams params) -{ - WMA_LOGD("%s: add_bss_param.halPersona = %d", - __func__, params->halPersona); - - switch (params->halPersona) { - - case QDF_SAP_MODE: - case QDF_P2P_GO_MODE: - wma_add_bss_ap_mode(wma, params); - break; - -#ifdef QCA_IBSS_SUPPORT - case QDF_IBSS_MODE: - wma_add_bss_ibss_mode(wma, params); - break; -#endif - case QDF_NDI_MODE: - wma_add_bss_ndi_mode(wma, params); - break; + return QDF_STATUS_SUCCESS; - default: - wma_add_bss_sta_mode(wma, params); - break; - } +send_resp: + wma_send_add_bss_resp(wma, vdev_id, status); + + return QDF_STATUS_SUCCESS; } /** @@ -5117,10 +3953,7 @@ void wma_add_bss(tp_wma_handle wma, tpAddBssParams params) static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) { enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN; - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - void *peer; - uint8_t peer_id; + uint8_t pdev_id = OL_TXRX_PDEV_ID; QDF_STATUS status; int32_t ret; struct wma_txrx_node *iface = NULL; @@ -5132,13 +3965,6 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) uint8_t *rate_pos; struct mac_context *mac = wma->mac_context; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to find pdev", __func__); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } /* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station * associates. First WMA_ADD_STA_REQ will have staType as * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF. @@ -5152,21 +3978,14 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) goto send_rsp; } - vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); - if (!vdev) { - WMA_LOGE("%s: Failed to find vdev", __func__); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } - iface = &wma->interfaces[add_sta->smesessionId]; - peer = cdp_peer_find_by_addr_and_vdev(soc, pdev, vdev, - add_sta->staMac, &peer_id); - if (peer) { + + if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, + add_sta->staMac)) { wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, - peer, false); - WMA_LOGE("%s: Peer already exists, Deleted peer with peer_addr %pM", - __func__, add_sta->staMac); + false); + WMA_LOGE("%s: Peer already exists, Deleted peer with peer_addr "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(add_sta->staMac)); } /* The code above only checks the peer existence on its own vdev. * Need to check whether the peer exists on other vDevs because firmware @@ -5174,36 +3993,32 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) * exists on the pDev. As this peer belongs to other vDevs, just return * here. */ - peer = cdp_peer_find_by_addr(soc, pdev, - add_sta->staMac, &peer_id); - if (peer) { - WMA_LOGE("%s: My vdev:%pK, but Peer exists on other vdev with peer_addr %pM and peer_id %d", - __func__, vdev, add_sta->staMac, peer_id); + if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) { + WMA_LOGE("%s: My vdev id %d, but Peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT, + __func__, add_sta->smesessionId, + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_FAILURE; goto send_rsp; } wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac); - status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, - WMI_PEER_TYPE_DEFAULT, add_sta->smesessionId, - false); + status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT, + add_sta->smesessionId, false); if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create peer for %pM", - __func__, add_sta->staMac); + WMA_LOGE("%s: Failed to create peer for "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = status; goto send_rsp; } - peer = cdp_peer_find_by_addr_and_vdev(soc, pdev, - vdev, - add_sta->staMac, &peer_id); - if (!peer) { - WMA_LOGE("%s: Failed to find peer handle using peer mac %pM", - __func__, add_sta->staMac); + if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, + add_sta->staMac)) { + WMA_LOGE("%s: Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, - peer, false); + false); goto send_rsp; } @@ -5259,7 +4074,7 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) wma_remove_req(wma, add_sta->smesessionId, WMA_PEER_ASSOC_CNF_START); wma_remove_peer(wma, add_sta->staMac, - add_sta->smesessionId, peer, false); + add_sta->smesessionId, false); peer_assoc_cnf = false; goto send_rsp; } @@ -5271,37 +4086,11 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) if (ret) { add_sta->status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, - peer, false); + false); goto send_rsp; } -#ifdef QCA_IBSS_SUPPORT - /* - * In IBSS mode send the peer - * Atim Window length if IBSS - * power save is enabled by the - * firmware. - */ - if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId) && - wmi_service_enabled(wma->wmi_handle, - wmi_service_ibss_pwrsave)) { - /* - * If ATIM Window is present in the peer - * beacon then send it to firmware else - * configure Zero ATIM Window length to - * firmware. - */ - if (add_sta->atimIePresent) { - wma_set_peer_param(wma, add_sta->staMac, - WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, - add_sta->peerAtimWindowLength, - add_sta->smesessionId); - } else { - wma_set_peer_param(wma, add_sta->staMac, - WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, - 0, add_sta->smesessionId); - } - } -#endif + + wma_send_peer_atim_window_len(wma, add_sta); if (add_sta->rmfEnabled) wma_set_peer_pmf_status(wma, add_sta->staMac, true); @@ -5310,20 +4099,19 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) add_sta->staMac, add_sta->uAPSD, add_sta->maxSPLen); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("Failed to set peer uapsd param for %pM", - add_sta->staMac); + WMA_LOGE("Failed to set peer uapsd param for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, add_sta->staMac, - add_sta->smesessionId, peer, false); + add_sta->smesessionId, false); goto send_rsp; } } - WMA_LOGD("%s: Moving peer %pM to state %d", - __func__, add_sta->staMac, state); - cdp_peer_state_update(soc, pdev, add_sta->staMac, state); + WMA_LOGD("%s: Moving peer "QDF_MAC_ADDR_FMT" to state %d", + __func__, QDF_MAC_ADDR_REF(add_sta->staMac), state); + cdp_peer_state_update(soc, add_sta->staMac, state); - add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer); add_sta->nss = iface->nss; add_sta->status = QDF_STATUS_SUCCESS; send_rsp: @@ -5333,9 +4121,9 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) return; } - WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"), + WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d"), add_sta->staType, add_sta->smesessionId, - add_sta->assocId, add_sta->bssId, add_sta->staIdx, + add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId), add_sta->status); wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0); } @@ -5351,35 +4139,18 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) */ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) { - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - void *peer; - uint8_t peer_id; QDF_STATUS status; int32_t ret; struct tdls_peer_update_state *peer_state; struct wma_target_req *msg; bool peer_assoc_cnf = false; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + uint8_t pdev_id = OL_TXRX_PDEV_ID; - WMA_LOGD("%s: staType: %d, staIdx: %d, updateSta: %d, bssId: %pM, staMac: %pM", - __func__, add_sta->staType, add_sta->staIdx, - add_sta->updateSta, add_sta->bssId, add_sta->staMac); - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to find pdev", __func__); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } - - vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); - if (!vdev) { - WMA_LOGE("%s: Failed to find vdev", __func__); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } + WMA_LOGD("%s: staType: %d, updateSta: %d, bssId: "QDF_MAC_ADDR_FMT", staMac: "QDF_MAC_ADDR_FMT, + __func__, add_sta->staType, + add_sta->updateSta, QDF_MAC_ADDR_REF(add_sta->bssId), + QDF_MAC_ADDR_REF(add_sta->staMac)); if (wma_is_roam_synch_in_progress(wma, add_sta->smesessionId) || wma_is_roam_in_progress(add_sta->smesessionId)) { @@ -5391,38 +4162,28 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) if (0 == add_sta->updateSta) { /* its a add sta request * */ - cdp_peer_copy_mac_addr_raw(soc, vdev, add_sta->bssId); + cdp_peer_copy_mac_addr_raw(soc, add_sta->smesessionId, + add_sta->bssId); - WMA_LOGD("%s: addSta, calling wma_create_peer for %pM, vdev_id %hu", - __func__, add_sta->staMac, add_sta->smesessionId); + WMA_LOGD("%s: addSta, calling wma_create_peer for "QDF_MAC_ADDR_FMT", vdev_id %hu", + __func__, QDF_MAC_ADDR_REF(add_sta->staMac), + add_sta->smesessionId); - status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, + status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_TDLS, add_sta->smesessionId, false); if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create peer for %pM", - __func__, add_sta->staMac); + WMA_LOGE("%s: Failed to create peer for "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = status; goto send_rsp; } - peer = cdp_peer_find_by_addr(soc, pdev, - add_sta->staMac, - &peer_id); - if (!peer) { - WMA_LOGE("%s: addSta, failed to find peer handle for mac %pM", - __func__, add_sta->staMac); - add_sta->status = QDF_STATUS_E_FAILURE; - cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id); - goto send_rsp; - } - - add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer); - WMA_LOGD("%s: addSta, after calling cdp_local_peer_id, staIdx: %d, staMac: %pM", - __func__, add_sta->staIdx, add_sta->staMac); + WMA_LOGD("%s: addSta, after calling cdp_local_peer_id, staMac: "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(add_sta->staMac)); peer_state = qdf_mem_malloc(sizeof(*peer_state)); - if (!peer_state) { + if (!peer_state) { add_sta->status = QDF_STATUS_E_NOMEM; goto send_rsp; } @@ -5433,21 +4194,6 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) &add_sta->staMac, sizeof(tSirMacAddr)); wma_update_tdls_peer_state(wma, peer_state); } else { - /* its a change sta request * */ - peer = - cdp_peer_find_by_addr(soc, pdev, - add_sta->staMac, - &peer_id); - if (!peer) { - WMA_LOGE("%s: changeSta,failed to find peer handle for mac %pM", - __func__, add_sta->staMac); - add_sta->status = QDF_STATUS_E_FAILURE; - - cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id); - - goto send_rsp; - } - if (wmi_service_enabled(wma->wmi_handle, wmi_service_peer_assoc_conf)) { WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled")); @@ -5462,7 +4208,7 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) wma_remove_req(wma, add_sta->smesessionId, WMA_PEER_ASSOC_CNF_START); wma_remove_peer(wma, add_sta->staMac, - add_sta->smesessionId, peer, false); + add_sta->smesessionId, false); peer_assoc_cnf = false; goto send_rsp; } @@ -5480,8 +4226,9 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) if (ret) { add_sta->status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, add_sta->staMac, - add_sta->smesessionId, peer, false); - cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id); + add_sta->smesessionId, false); + cdp_peer_add_last_real_peer(soc, pdev_id, + add_sta->smesessionId); wma_remove_req(wma, add_sta->smesessionId, WMA_PEER_ASSOC_CNF_START); peer_assoc_cnf = false; @@ -5495,9 +4242,9 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) if (peer_assoc_cnf) return; - WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"), + WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d"), add_sta->staType, add_sta->smesessionId, - add_sta->assocId, add_sta->bssId, add_sta->staIdx, + add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId), add_sta->status); wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0); } @@ -5552,9 +4299,7 @@ static void wma_send_bss_color_change_enable(tp_wma_handle wma, */ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) { - struct cdp_pdev *pdev; QDF_STATUS status = QDF_STATUS_SUCCESS; - void *peer; struct wma_txrx_node *iface; int8_t maxTxPower; int ret = 0; @@ -5570,45 +4315,30 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) } #endif - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Unable to get pdev", __func__); - goto out; - } - iface = &wma->interfaces[params->smesessionId]; if (params->staType != STA_ENTRY_SELF) { WMA_LOGE("%s: unsupported station type %d", __func__, params->staType); goto out; } - peer = cdp_peer_find_by_addr(soc, - pdev, - params->bssId, ¶ms->staIdx); - if (!peer) { - WMA_LOGE("%s: Peer is not present vdev id %d for %pM", __func__, - params->smesessionId, params->bssId); - status = QDF_STATUS_E_FAILURE; - goto out; - } if (params->nonRoamReassoc) { - cdp_peer_state_update(soc, pdev, params->bssId, - OL_TXRX_PEER_STATE_AUTH); + cdp_peer_state_update(soc, params->bssId, + OL_TXRX_PEER_STATE_AUTH); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); iface->aid = params->assocId; goto out; } if (wma_is_vdev_up(params->smesessionId)) { - WMA_LOGD("%s: vdev id %d is already UP for %pM", __func__, - params->smesessionId, params->bssId); + WMA_LOGD("%s: vdev id %d is already UP for "QDF_MAC_ADDR_FMT, + __func__, params->smesessionId, + QDF_MAC_ADDR_REF(params->bssId)); status = QDF_STATUS_E_FAILURE; goto out; } - if (peer && - (cdp_peer_state_get(soc, peer) == OL_TXRX_PEER_STATE_DISC)) { + if (cdp_peer_state_get(soc, params->smesessionId, + params->bssId) == OL_TXRX_PEER_STATE_DISC) { /* * This is the case for reassociation. * peer state update and peer_assoc is required since it @@ -5617,15 +4347,15 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) /* Update peer state */ if (params->encryptType == eSIR_ED_NONE) { - WMA_LOGD("%s: Update peer(%pM) state into auth", - __func__, params->bssId); - cdp_peer_state_update(soc, pdev, params->bssId, - OL_TXRX_PEER_STATE_AUTH); + WMA_LOGD("%s: Update peer("QDF_MAC_ADDR_FMT") state into auth", + __func__, QDF_MAC_ADDR_REF(params->bssId)); + cdp_peer_state_update(soc, params->bssId, + OL_TXRX_PEER_STATE_AUTH); } else { - WMA_LOGD("%s: Update peer(%pM) state into conn", - __func__, params->bssId); - cdp_peer_state_update(soc, pdev, params->bssId, - OL_TXRX_PEER_STATE_CONN); + WMA_LOGD("%s: Update peer("QDF_MAC_ADDR_FMT") state into conn", + __func__, QDF_MAC_ADDR_REF(params->bssId)); + cdp_peer_state_update(soc, params->bssId, + OL_TXRX_PEER_STATE_CONN); } if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) { @@ -5635,14 +4365,15 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) * skipping this operation, we are just executing the * following which are useful for LFR3.0 */ - cdp_peer_state_update(soc, pdev, params->bssId, - OL_TXRX_PEER_STATE_AUTH); + cdp_peer_state_update(soc, params->bssId, + OL_TXRX_PEER_STATE_AUTH); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); iface->aid = params->assocId; - WMA_LOGD("LFR3:statype %d vdev %d aid %d bssid %pM", + WMA_LOGD("LFR3:statype %d vdev %d aid %d bssid "QDF_MAC_ADDR_FMT, params->staType, params->smesessionId, - params->assocId, params->bssId); + params->assocId, + QDF_MAC_ADDR_REF(params->bssId)); return; } wmi_unified_send_txbf(wma, params); @@ -5659,8 +4390,8 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) params->status = QDF_STATUS_E_FAILURE; wma_remove_req(wma, params->smesessionId, WMA_PEER_ASSOC_CNF_START); - wma_remove_peer(wma, params->staMac, - params->smesessionId, peer, false); + wma_remove_peer(wma, params->bssId, + params->smesessionId, false); peer_assoc_cnf = false; goto out; } @@ -5683,7 +4414,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) if (ret) { status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, params->bssId, - params->smesessionId, peer, false); + params->smesessionId, false); goto out; } @@ -5691,14 +4422,6 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) wma_set_mgmt_frame_protection(wma); wma_set_peer_pmf_status(wma, params->bssId, true); } - - /* - * Set the PTK in 11r mode because we already have it. - */ - if (iface->staKeyParams) { - wma_set_stakey(wma, - (tpSetStaKeyParams) iface->staKeyParams); - } } maxTxPower = params->maxTxPower; wma_vdev_set_bss_params(wma, params->smesessionId, @@ -5798,9 +4521,9 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) return; params->status = status; - wma_debug("vdev_id %d aid %d staIdx %d sta mac " QDF_MAC_ADDR_STR " status %d", - params->smesessionId, params->assocId, params->staIdx, - QDF_MAC_ADDR_ARRAY(params->bssId), params->status); + wma_debug("vdev_id %d aid %d sta mac " QDF_MAC_ADDR_FMT " status %d", + params->smesessionId, params->assocId, + QDF_MAC_ADDR_REF(params->bssId), params->status); /* Don't send a response during roam sync operation */ if (!wma_is_roam_synch_in_progress(wma, params->smesessionId)) wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, @@ -5817,33 +4540,11 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) static void wma_delete_sta_req_ap_mode(tp_wma_handle wma, tpDeleteStaParams del_sta) { - struct cdp_pdev *pdev; - void *peer; struct wma_target_req *msg; - uint8_t *peer_mac_addr; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); QDF_STATUS qdf_status; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - del_sta->status = QDF_STATUS_E_FAILURE; - goto send_del_rsp; - } - - peer = cdp_peer_find_by_local_id(soc, - pdev, del_sta->staIdx); - if (!peer) { - WMA_LOGE("%s: Failed to get peer handle using peer id %d", - __func__, del_sta->staIdx); - del_sta->status = QDF_STATUS_E_FAILURE; - goto send_del_rsp; - } - peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer); - - qdf_status = wma_remove_peer(wma, peer_mac_addr, del_sta->smesessionId, - peer, false); + qdf_status = wma_remove_peer(wma, del_sta->staMac, + del_sta->smesessionId, false); if (QDF_IS_STATUS_ERROR(qdf_status)) { WMA_LOGE(FL("wma_remove_peer failed")); del_sta->status = QDF_STATUS_E_FAILURE; @@ -5901,21 +4602,14 @@ static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) goto send_del_rsp; } - if (wma_is_roam_synch_in_progress(wma, del_sta->smesessionId)) { - WMA_LOGE("%s: roaming in progress, reject del sta!", __func__); - del_sta->status = QDF_STATUS_E_PERM; - qdf_mem_free(peer_state); - goto send_del_rsp; - } - peer_state->peer_state = TDLS_PEER_STATE_TEARDOWN; peer_state->vdev_id = del_sta->smesessionId; peer_state->resp_reqd = del_sta->respReqd; qdf_mem_copy(&peer_state->peer_macaddr, &del_sta->staMac, sizeof(tSirMacAddr)); - WMA_LOGD("%s: sending tdls_peer_state for peer mac: %pM, peerState: %d", - __func__, peer_state->peer_macaddr, + WMA_LOGD("%s: sending tdls_peer_state for peer mac: "QDF_MAC_ADDR_FMT", peerState: %d", + __func__, QDF_MAC_ADDR_REF(peer_state->peer_macaddr), peer_state->peer_state); status = wma_update_tdls_peer_state(wma, peer_state); @@ -5977,8 +4671,6 @@ static void wma_delete_sta_req_sta_mode(tp_wma_handle wma, iface = &wma->interfaces[params->smesessionId]; iface->uapsd_cached_val = 0; - if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) - return; #ifdef FEATURE_WLAN_TDLS if (STA_ENTRY_TDLS_PEER == params->staType) { wma_del_tdls_sta(wma, params); @@ -6004,13 +4696,6 @@ static void wma_sap_allow_runtime_pm(tp_wma_handle wma) qdf_runtime_pm_allow_suspend(&wma->sap_prevent_runtime_pm_lock); } -/** - * wma_add_sta() - process add sta request as per opmode - * @wma: wma handle - * @add_Sta: add sta params - * - * Return: none - */ void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) { uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA; @@ -6022,7 +4707,8 @@ void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) return; } - wma_debug("Vdev %d BSSID %pM", add_sta->smesessionId, add_sta->bssId); + wma_debug("Vdev %d BSSID "QDF_MAC_ADDR_FMT, add_sta->smesessionId, + QDF_MAC_ADDR_REF(add_sta->bssId)); if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId)) oper_mode = BSS_OPERATIONAL_MODE_AP; @@ -6055,23 +4741,13 @@ void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) wma_sap_prevent_runtime_pm(wma); } -#ifdef QCA_IBSS_SUPPORT /* adjust heart beat thresold timer value for detecting ibss peer * departure */ if (oper_mode == BSS_OPERATIONAL_MODE_IBSS) wma_adjust_ibss_heart_beat_timer(wma, add_sta->smesessionId, 1); -#endif - } -/** - * wma_delete_sta() - process del sta request as per opmode - * @wma: wma handle - * @del_sta: delete sta params - * - * Return: none - */ void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) { uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA; @@ -6094,22 +4770,22 @@ void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) if (del_sta->staType == STA_ENTRY_NDI_PEER) oper_mode = BSS_OPERATIONAL_MODE_NDI; - WMA_LOGD(FL("oper_mode %d"), oper_mode); + wma_debug("oper_mode %d", oper_mode); + wma_debug("vdev_id %d status %d", + del_sta->smesessionId, del_sta->status); switch (oper_mode) { case BSS_OPERATIONAL_MODE_STA: - wma_delete_sta_req_sta_mode(wma, del_sta); if (wma_is_roam_synch_in_progress(wma, smesession_id)) { - WMA_LOGD(FL("LFR3: Del STA on vdev_id %d"), - del_sta->smesessionId); + wma_debug("LFR3: Del STA on vdev_id %d", + del_sta->smesessionId); qdf_mem_free(del_sta); return; } - if (!rsp_requested) { - WMA_LOGD(FL("vdev_id %d status %d"), - del_sta->smesessionId, del_sta->status); + wma_delete_sta_req_sta_mode(wma, del_sta); + if (!rsp_requested) qdf_mem_free(del_sta); - } + break; case BSS_OPERATIONAL_MODE_IBSS: /* IBSS shares AP code */ @@ -6146,66 +4822,35 @@ void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) wma_sap_allow_runtime_pm(wma); } -#ifdef QCA_IBSS_SUPPORT /* adjust heart beat thresold timer value for * detecting ibss peer departure */ if (oper_mode == BSS_OPERATIONAL_MODE_IBSS) wma_adjust_ibss_heart_beat_timer(wma, smesession_id, -1); -#endif } -/** - * wma_delete_bss_ho_fail() - process delete bss request for handoff failure - * @wma: wma handle - * @params: del bss parameters - * - * Delete BSS in case of ROAM_HO_FAIL processing is handled separately in - * this routine. It needs to be done without sending any commands to firmware - * because firmware has already stopped and deleted peer and vdev is down. - * Relevant logic is aggregated from other routines. It changes the host - * data structures without sending VDEV_STOP, PEER_FLUSH_TIDS, PEER_DELETE - * and VDEV_DOWN commands to firmware. - * - * Return: none - */ -void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params) +void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id) { - struct cdp_pdev *pdev; QDF_STATUS status = QDF_STATUS_SUCCESS; - struct cdp_vdev *txrx_vdev = NULL; struct wma_txrx_node *iface; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wma_target_req *msg; - wmi_vdev_stopped_event_fixed_param resp_event; - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s:Unable to get TXRX context", __func__); - goto fail_del_bss_ho_fail; - } + struct vdev_stop_response resp_event; + struct del_bss_resp *vdev_stop_resp; + uint8_t *bssid; - iface = &wma->interfaces[params->smesessionId]; - if (!iface || !iface->handle) { - WMA_LOGE("%s vdev id %d is already deleted", - __func__, params->smesessionId); + iface = &wma->interfaces[vdev_id]; + if (!iface) { + WMA_LOGE("%s iface for vdev_id %d is already deleted", + __func__, vdev_id); goto fail_del_bss_ho_fail; } - qdf_mem_zero(iface->bssid, QDF_MAC_ADDR_SIZE); - - txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId); - if (!txrx_vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); + bssid = wma_get_vdev_bssid(iface->vdev); + if (!bssid) { + WMA_LOGE("%s:Invalid bssid", __func__); status = QDF_STATUS_E_FAILURE; goto fail_del_bss_ho_fail; } - - /* Free the allocated stats response buffer for the the session */ - if (iface->stats_rsp) { - qdf_mem_free(iface->stats_rsp); - iface->stats_rsp = NULL; - } + qdf_mem_zero(bssid, QDF_MAC_ADDR_SIZE); if (iface->psnr_req) { qdf_mem_free(iface->psnr_req); @@ -6228,47 +4873,47 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params) } WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", - __func__, params->smesessionId); - cdp_fc_vdev_pause(soc, iface->handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); - wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); - - cdp_fc_vdev_flush(soc, iface->handle); + __func__, vdev_id); + cdp_fc_vdev_pause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); + wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); + cdp_fc_vdev_flush(soc, vdev_id); WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", - __func__, params->smesessionId); - cdp_fc_vdev_unpause(soc, iface->handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); - wma_vdev_clear_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); + __func__, vdev_id); + cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); + wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); - params->status = QDF_STATUS_SUCCESS; - msg = wma_fill_vdev_req(wma, params->smesessionId, - WMA_DELETE_BSS_HO_FAIL_REQ, - WMA_TARGET_REQ_TYPE_VDEV_STOP, params, - WMA_VDEV_STOP_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d", - __func__, params->smesessionId); - status = QDF_STATUS_E_NOMEM; + status = mlme_set_vdev_stop_type(iface->vdev, + WMA_DELETE_BSS_HO_FAIL_REQ); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to set wma req msg_type for vdev_id: %d", + __func__, vdev_id); goto fail_del_bss_ho_fail; } /* Try to use the vdev stop response path */ - resp_event.vdev_id = params->smesessionId; + resp_event.vdev_id = vdev_id; status = wma_handle_vdev_stop_rsp(wma, &resp_event); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("%s: Failed to handle vdev stop rsp for vdev_id %d", - __func__, params->smesessionId); + __func__, vdev_id); goto fail_del_bss_ho_fail; } return; + fail_del_bss_ho_fail: - params->status = status; + vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp)); + if (!vdev_stop_resp) { + WMA_LOGE("%s: Failed to alloc del bss resp ", __func__); + return; + } + vdev_stop_resp->vdev_id = vdev_id; + vdev_stop_resp->status = status; wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP, - (void *)params, 0); + (void *)vdev_stop_resp, 0); } /** @@ -6281,9 +4926,10 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params) static void wma_wait_tx_complete(tp_wma_handle wma, uint32_t session_id) { - struct cdp_pdev *pdev; - uint8_t max_wait_iterations = 0; + uint8_t max_wait_iterations = 0, delay = 0; + cdp_config_param_type val; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; if (!wma_is_vdev_valid(session_id)) { WMA_LOGE("%s: Vdev is not valid: %d", @@ -6291,96 +4937,87 @@ static void wma_wait_tx_complete(tp_wma_handle wma, return; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: pdev is not valid: %d", - __func__, session_id); - return; - } - max_wait_iterations = - wma->interfaces[session_id].delay_before_vdev_stop / - WMA_TX_Q_RECHECK_TIMER_WAIT; + status = ucfg_mlme_get_delay_before_vdev_stop(wma->psoc, &delay); + if (QDF_IS_STATUS_ERROR(status)) + wma_err("Failed to get delay before vdev stop"); - while (cdp_get_tx_pending(soc, pdev) && max_wait_iterations) { + max_wait_iterations = delay / WMA_TX_Q_RECHECK_TIMER_WAIT; + if (cdp_txrx_get_pdev_param(soc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_TX_PENDING, &val)) + return; + while (val.cdp_pdev_param_tx_pending && max_wait_iterations) { WMA_LOGW(FL("Waiting for outstanding packet to drain.")); qdf_wait_for_event_completion(&wma->tx_queue_empty_event, WMA_TX_Q_RECHECK_TIMER_WAIT); + if (cdp_txrx_get_pdev_param( + soc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_TX_PENDING, &val)) + return; max_wait_iterations--; } } -/** - * wma_delete_bss() - process delete bss request from upper layer - * @wma: wma handle - * @params: del bss parameters - * - * Return: none - */ -void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) +void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id) { - struct cdp_pdev *pdev; - void *peer = NULL; - struct wma_target_req *msg; + bool peer_exist = false; QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t peer_id; - struct cdp_vdev *txrx_vdev = NULL; + uint32_t tx_pending = 0; + cdp_config_param_type val; bool roam_synch_in_progress = false; struct wma_txrx_node *iface; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct qdf_mac_addr bssid; + struct del_bss_resp *params; + uint8_t *addr, *bssid_addr; + + iface = &wma->interfaces[vdev_id]; + if (!iface || !iface->vdev) { + WMA_LOGE("%s vdev id %d is already deleted", + __func__, vdev_id); + goto out; + } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); + status = mlme_get_vdev_bss_peer_mac_addr(iface->vdev, &bssid); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s vdev id %d : failed to get bssid", + __func__, vdev_id); + goto out; + } - if (!pdev) { - WMA_LOGE("%s:Unable to get TXRX context", __func__); + addr = wlan_vdev_mlme_get_macaddr(iface->vdev); + if (!addr) { + WMA_LOGE("%s vdev id %d : failed to get macaddr", + __func__, vdev_id); goto out; } - if (wma_is_vdev_in_ibss_mode(wma, params->smesessionId)) + if (wma_is_vdev_in_ibss_mode(wma, vdev_id)) /* in rome ibss case, self mac is used to create the bss peer */ - peer = cdp_peer_find_by_addr(soc, - pdev, - wma->interfaces[params->smesessionId].addr, - &peer_id); + peer_exist = wma_cdp_find_peer_by_addr(addr); else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, - params->smesessionId)) + vdev_id)) /* In ndi case, self mac is used to create the self peer */ - peer = cdp_peer_find_by_addr(soc, pdev, - wma->interfaces[params->smesessionId].addr, - &peer_id); + peer_exist = wma_cdp_find_peer_by_addr(addr); else - peer = cdp_peer_find_by_addr(soc, pdev, - params->bssid, - &peer_id); - - if (!peer) { - WMA_LOGE("%s: Failed to find peer %pM", __func__, - params->bssid); + peer_exist = wma_cdp_find_peer_by_addr(bssid.bytes); + if (!peer_exist) { + WMA_LOGE("%s: Failed to find peer "QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(bssid.bytes)); status = QDF_STATUS_E_FAILURE; goto out; } - - qdf_mem_zero(wma->interfaces[params->smesessionId].bssid, - QDF_MAC_ADDR_SIZE); - - txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId); - if (!txrx_vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); + bssid_addr = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); + if (!bssid_addr) { + WMA_LOGE("%s: Failed to bssid for vdev_%d", __func__, + vdev_id); status = QDF_STATUS_E_FAILURE; goto out; } + qdf_mem_zero(bssid_addr, + QDF_MAC_ADDR_SIZE); - iface = &wma->interfaces[params->smesessionId]; - if (!iface || !iface->handle) { - WMA_LOGE("%s vdev id %d is already deleted", - __func__, params->smesessionId); - goto out; - } - /*Free the allocated stats response buffer for the the session */ - if (iface->stats_rsp) { - qdf_mem_free(iface->stats_rsp); - iface->stats_rsp = NULL; - } - - wma_delete_invalid_peer_entries(params->smesessionId, NULL); + wma_delete_invalid_peer_entries(vdev_id, NULL); if (iface->psnr_req) { qdf_mem_free(iface->psnr_req); @@ -6402,61 +5039,71 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) qdf_mem_free(roam_scan_stats_req); } - if (wlan_op_mode_ibss == cdp_get_opmode(soc, txrx_vdev)) + if (wlan_op_mode_ibss == cdp_get_opmode(soc, vdev_id)) wma->ibss_started = 0; - if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) { + if (wma_is_roam_synch_in_progress(wma, vdev_id)) { roam_synch_in_progress = true; WMA_LOGD("LFR3:%s: Setting vdev_up to FALSE for session %d", - __func__, params->smesessionId); + __func__, vdev_id); goto detach_peer; } - msg = wma_fill_vdev_req(wma, params->smesessionId, WMA_DELETE_BSS_REQ, - WMA_TARGET_REQ_TYPE_VDEV_STOP, params, - WMA_VDEV_STOP_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d", - __func__, params->smesessionId); - status = QDF_STATUS_E_NOMEM; - goto detach_peer; + + status = mlme_set_vdev_stop_type(iface->vdev, + WMA_DELETE_BSS_REQ); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to set wma req msg_type for vdev_id: %d", + __func__, vdev_id); + goto out; } - WMA_LOGD(FL("Outstanding msdu packets: %d"), - cdp_get_tx_pending(soc, pdev)); - wma_wait_tx_complete(wma, params->smesessionId); + cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_TX_PENDING, &val); + tx_pending = val.cdp_pdev_param_tx_pending; + WMA_LOGD(FL("Outstanding msdu packets: %u"), tx_pending); + wma_wait_tx_complete(wma, vdev_id); - if (cdp_get_tx_pending(soc, pdev)) { - WMA_LOGD(FL("Outstanding msdu packets before VDEV_STOP : %d"), - cdp_get_tx_pending(soc, pdev)); + cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_TX_PENDING, &val); + if (tx_pending) { + WMA_LOGD(FL("Outstanding msdu packets before VDEV_STOP : %u"), + tx_pending); } WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", - __func__, params->smesessionId); - wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); - cdp_fc_vdev_pause(soc, - wma->interfaces[params->smesessionId].handle, - OL_TXQ_PAUSE_REASON_VDEV_STOP); + __func__, vdev_id); + wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); + cdp_fc_vdev_pause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); - if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) { + if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__); - wma_remove_vdev_req(wma, params->smesessionId, - WMA_TARGET_REQ_TYPE_VDEV_STOP); status = QDF_STATUS_E_FAILURE; + qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); goto detach_peer; - } - WMA_LOGD("%s: bssid %pM vdev_id %d", - __func__, params->bssid, params->smesessionId); + } + WMA_LOGD("%s: bssid "QDF_MAC_ADDR_FMT" vdev_id %d", + __func__, QDF_MAC_ADDR_REF(bssid.bytes), vdev_id); + return; + detach_peer: - wma_remove_peer(wma, params->bssid, params->smesessionId, peer, - roam_synch_in_progress); - if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) + wma_remove_peer(wma, bssid.bytes, vdev_id, + wma_is_roam_synch_in_progress(wma, vdev_id)); + if (wma_is_roam_synch_in_progress(wma, vdev_id)) return; out: + params = qdf_mem_malloc(sizeof(*params)); + if (!params) { + WMA_LOGE("%s vdev id %d : failed to alloc del bss resp", + __func__, vdev_id); + return; + } + params->vdev_id = vdev_id; params->status = status; - wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, (void *)params, 0); + wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, params, 0); } /** @@ -6481,26 +5128,40 @@ int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type) return -EFAULT; } -/** - * wma_set_vdev_intrabss_fwd() - set intra_fwd value to wni_in. - * @wma_handle: wma handle - * @pdis_intra_fwd: Pointer to DisableIntraBssFwd struct - * - * Return: none - */ void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle, tpDisableIntraBssFwd pdis_intra_fwd) { - struct cdp_vdev *txrx_vdev; + struct wlan_objmgr_vdev *vdev; WMA_LOGD("%s:intra_fwd:vdev(%d) intrabss_dis=%s", __func__, pdis_intra_fwd->sessionId, (pdis_intra_fwd->disableintrabssfwd ? "true" : "false")); - txrx_vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].handle; + vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].vdev; cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC), - txrx_vdev, - pdis_intra_fwd->disableintrabssfwd); + pdis_intra_fwd->sessionId, + pdis_intra_fwd->disableintrabssfwd); +} + +/** + * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle + * @scn_handle: opaque wma handle + * + * API to get pdev from scn handle + * + * Return: None + */ +static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle) +{ + tp_wma_handle wma_handle; + + if (!scn_handle) { + WMA_LOGE("invalid scn handle"); + return NULL; + } + wma_handle = (tp_wma_handle)scn_handle; + + return wma_handle->pdev; } void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev) @@ -6515,6 +5176,10 @@ void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev) } wma->pdev = pdev; + + target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle); + target_pdev_set_wmi_handle(wma->pdev->tgt_if_handle, + wma->wmi_handle); } /** @@ -6586,3 +5251,73 @@ QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr, return ret; } + +QDF_STATUS wma_add_bss_peer_sta(uint8_t *self_mac, uint8_t *bssid, + bool roam_synch) +{ + uint8_t vdev_id; + tp_wma_handle wma; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + WMA_LOGE("Invalid wma"); + goto err; + } + if (wma_find_vdev_id_by_addr(wma, self_mac, &vdev_id)) { + WMA_LOGE("vdev not found for addr: "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(self_mac)); + goto err; + } + status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT, + vdev_id, roam_synch); +err: + return status; +} + +QDF_STATUS wma_send_vdev_stop(uint8_t vdev_id) +{ + tp_wma_handle wma; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; + + wma = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma) { + WMA_LOGE("Invalid wma"); + return QDF_STATUS_E_FAILURE; + } + + WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", + __func__, vdev_id); + cdp_fc_vdev_pause(soc, vdev_id, + OL_TXQ_PAUSE_REASON_VDEV_STOP, 0); + + status = mlme_set_vdev_stop_type( + wma->interfaces[vdev_id].vdev, + WMA_SET_LINK_STATE); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGP(FL("Failed to set wma req msg_type for vdev_id %d"), + vdev_id); + return QDF_STATUS_E_FAILURE; + } + + wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); + + status = wma_send_vdev_stop_to_fw(wma, vdev_id); + if (QDF_IS_STATUS_ERROR(status)) { + struct vdev_stop_response resp_event; + + wma_info("vdev %d Failed to send vdev stop", vdev_id); + resp_event.vdev_id = vdev_id; + mlme_set_connection_fail(wma->interfaces[vdev_id].vdev, false); + wma_handle_vdev_stop_rsp(wma, &resp_event); + } + + /* + * Remove peer, Vdev down and sending set link + * response will be handled in vdev stop response + * handler + */ + + return QDF_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c index 0211dfaf854639a634b42767b8fc04d24fdd7e41..b689169a2204579c7fc64ca04e204d080cda57a1 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c @@ -69,6 +69,7 @@ #endif #include "wlan_scan_api.h" #include +#include "cdp_txrx_host_stats.h" /** * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE @@ -77,7 +78,6 @@ */ #define WMA_SET_VDEV_IE_SOURCE_HOST 0x0 - #if defined(FEATURE_WLAN_DIAG_SUPPORT) /** * qdf_wma_wow_wakeup_stats_event()- send wow wakeup stats @@ -87,7 +87,6 @@ * * Return: void. */ -#ifdef QCA_SUPPORT_CP_STATS static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma) { QDF_STATUS status; @@ -121,52 +120,6 @@ static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma) WLAN_HOST_DIAG_EVENT_REPORT(&wow_stats, EVENT_WLAN_POWERSAVE_WOW_STATS); } -#else /* QCA_SUPPORT_CP_STATS*/ -static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma) -{ - QDF_STATUS status; - struct sir_wake_lock_stats stats; - - WLAN_HOST_DIAG_EVENT_DEF(WowStats, - struct host_event_wlan_powersave_wow_stats); - - status = wma_get_wakelock_stats(&stats); - if (QDF_IS_STATUS_ERROR(status)) - return; - qdf_mem_zero(&WowStats, sizeof(WowStats)); - - WowStats.wow_bcast_wake_up_count = - stats.wow_bcast_wake_up_count; - WowStats.wow_ipv4_mcast_wake_up_count = - stats.wow_ipv4_mcast_wake_up_count; - WowStats.wow_ipv6_mcast_wake_up_count = - stats.wow_ipv6_mcast_wake_up_count; - WowStats.wow_ipv6_mcast_ra_stats = - stats.wow_ipv6_mcast_ra_stats; - WowStats.wow_ipv6_mcast_ns_stats = - stats.wow_ipv6_mcast_ns_stats; - WowStats.wow_ipv6_mcast_na_stats = - stats.wow_ipv6_mcast_na_stats; - WowStats.wow_pno_match_wake_up_count = - stats.wow_pno_match_wake_up_count; - WowStats.wow_pno_complete_wake_up_count = - stats.wow_pno_complete_wake_up_count; - WowStats.wow_gscan_wake_up_count = - stats.wow_gscan_wake_up_count; - WowStats.wow_low_rssi_wake_up_count = - stats.wow_low_rssi_wake_up_count; - WowStats.wow_rssi_breach_wake_up_count = - stats.wow_rssi_breach_wake_up_count; - WowStats.wow_icmpv4_count = - stats.wow_icmpv4_count; - WowStats.wow_icmpv6_count = - stats.wow_icmpv6_count; - WowStats.wow_oem_response_wake_up_count = - stats.wow_oem_response_wake_up_count; - - WLAN_HOST_DIAG_EVENT_REPORT(&WowStats, EVENT_WLAN_POWERSAVE_WOW_STATS); -} -#endif /* QCA_SUPPORT_CP_STATS */ #else static inline void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma) { @@ -239,49 +192,6 @@ static inline int wma_nan_rsp_handler_callback(void *handle, uint8_t *event, } #endif -/** - * wma_send_snr_request() - send request to fw to get RSSI stats - * @wma_handle: wma handle - * @pGetRssiReq: get RSSI request - * - * Return: QDF status - */ -QDF_STATUS wma_send_snr_request(tp_wma_handle wma_handle, - void *pGetRssiReq) -{ - tAniGetRssiReq *pRssiBkUp = NULL; - - /* command is in progress */ - if (wma_handle->pGetRssiReq) - return QDF_STATUS_SUCCESS; - - /* create a copy of csrRssiCallback to send rssi value - * after wmi event - */ - if (pGetRssiReq) { - pRssiBkUp = qdf_mem_malloc(sizeof(tAniGetRssiReq)); - if (!pRssiBkUp) { - wma_handle->pGetRssiReq = NULL; - return QDF_STATUS_E_NOMEM; - } - pRssiBkUp->sessionId = - ((tAniGetRssiReq *) pGetRssiReq)->sessionId; - pRssiBkUp->rssiCallback = - ((tAniGetRssiReq *) pGetRssiReq)->rssiCallback; - pRssiBkUp->pDevContext = - ((tAniGetRssiReq *) pGetRssiReq)->pDevContext; - wma_handle->pGetRssiReq = (void *)pRssiBkUp; - } - - if (wmi_unified_snr_request_cmd(wma_handle->wmi_handle)) { - WMA_LOGE("Failed to send host stats request to fw"); - qdf_mem_free(pRssiBkUp); - wma_handle->pGetRssiReq = NULL; - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; -} - /** * wma_get_snr() - get RSSI from fw * @psnr_req: request params @@ -313,7 +223,6 @@ QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req) return QDF_STATUS_E_NOMEM; qdf_mem_zero(psnr_req_bkp, sizeof(tAniGetSnrReq)); - psnr_req_bkp->staId = psnr_req->staId; psnr_req_bkp->pDevContext = psnr_req->pDevContext; psnr_req_bkp->snrCallback = psnr_req->snrCallback; intr->psnr_req = (void *)psnr_req_bkp; @@ -329,6 +238,34 @@ QDF_STATUS wma_get_snr(tAniGetSnrReq *psnr_req) return QDF_STATUS_SUCCESS; } +void wma_get_rx_retry_cnt(struct mac_context *mac, uint8_t vdev_id, + uint8_t *mac_addr) +{ + struct cdp_peer_stats *peer_stats; + QDF_STATUS status; + + peer_stats = qdf_mem_malloc(sizeof(*peer_stats)); + if (!peer_stats) { + wma_err("Failed to allocate memory for peer stats"); + return; + } + + status = cdp_host_get_peer_stats(cds_get_context(QDF_MODULE_ID_SOC), + vdev_id, mac_addr, peer_stats); + + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("Failed to get peer stats"); + goto exit; + } + + mac->rx_retry_cnt = peer_stats->rx.rx_retries; + wma_debug("Rx retry count %d, Peer" QDF_MAC_ADDR_FMT, mac->rx_retry_cnt, + QDF_MAC_ADDR_REF(mac_addr)); + +exit: + qdf_mem_free(peer_stats); +} + /** * wma_process_link_status_req() - process link status request from UMAC * @wma: wma handle @@ -593,19 +530,19 @@ QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE handle, return QDF_STATUS_E_FAILURE; } - if (!wma_find_vdev_by_addr(wma_handle, - ta_dhcp_ind->adapterMacAddr.bytes, - &vdev_id)) { + if (wma_find_vdev_id_by_addr(wma_handle, + ta_dhcp_ind->adapterMacAddr.bytes, + &vdev_id)) { WMA_LOGE("%s: Failed to find vdev id for DHCP indication", __func__); return QDF_STATUS_E_FAILURE; } - wma_debug("WMA --> WMI_PEER_SET_PARAM triggered by DHCP, msgType=%s, device_mode=%d, macAddr=" QDF_MAC_ADDR_STR, + wma_debug("WMA --> WMI_PEER_SET_PARAM triggered by DHCP, msgType=%s, device_mode=%d, macAddr=" QDF_MAC_ADDR_FMT, ta_dhcp_ind->msgType == WMA_DHCP_START_IND ? "WMA_DHCP_START_IND" : "WMA_DHCP_STOP_IND", ta_dhcp_ind->device_mode, - QDF_MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr.bytes)); + QDF_MAC_ADDR_REF(ta_dhcp_ind->peerMacAddr.bytes)); /* fill in values */ peer_set_param_fp.vdev_id = vdev_id; @@ -621,32 +558,24 @@ QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE handle, &peer_set_param_fp); } -/** - * wma_chan_phy__mode() - get WLAN_PHY_MODE for channel - * @chan: channel number - * @chan_width: maximum channel width possible - * @dot11_mode: maximum phy_mode possible - * - * Return: return WLAN_PHY_MODE - */ -WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width, - uint8_t dot11_mode) +enum wlan_phymode wma_chan_phy_mode(uint32_t freq, enum phy_ch_width chan_width, + uint8_t dot11_mode) { - WLAN_PHY_MODE phymode = MODE_UNKNOWN; + enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; uint16_t bw_val = wlan_reg_get_bw_value(chan_width); t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { WMA_LOGE("%s : wma_handle is NULL", __func__); - return MODE_UNKNOWN; + return WLAN_PHYMODE_AUTO; } if (chan_width >= CH_WIDTH_INVALID) { - WMA_LOGE("%s : Invalid channel width", __func__); - return MODE_UNKNOWN; + wma_err_rl("%s : Invalid channel width %d", __func__, chan_width); + return WLAN_PHYMODE_AUTO; } - if (WLAN_REG_IS_24GHZ_CH(chan)) { + if (wlan_reg_is_24ghz_ch_freq(freq)) { if (((CH_WIDTH_5MHZ == chan_width) || (CH_WIDTH_10MHZ == chan_width)) && ((MLME_DOT11_MODE_11B == dot11_mode) || @@ -655,49 +584,49 @@ WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width, (MLME_DOT11_MODE_ALL == dot11_mode) || (MLME_DOT11_MODE_11AC == dot11_mode) || (MLME_DOT11_MODE_11AX == dot11_mode))) - phymode = MODE_11G; + phymode = WLAN_PHYMODE_11G; else { switch (dot11_mode) { case MLME_DOT11_MODE_11B: if ((bw_val == 20) || (bw_val == 40)) - phymode = MODE_11B; + phymode = WLAN_PHYMODE_11B; break; case MLME_DOT11_MODE_11G: if ((bw_val == 20) || (bw_val == 40)) - phymode = MODE_11G; + phymode = WLAN_PHYMODE_11G; break; case MLME_DOT11_MODE_11G_ONLY: if ((bw_val == 20) || (bw_val == 40)) - phymode = MODE_11GONLY; + phymode = WLAN_PHYMODE_11G_ONLY; break; case MLME_DOT11_MODE_11N: case MLME_DOT11_MODE_11N_ONLY: if (bw_val == 20) - phymode = MODE_11NG_HT20; + phymode = WLAN_PHYMODE_11NG_HT20; else if (bw_val == 40) - phymode = MODE_11NG_HT40; + phymode = WLAN_PHYMODE_11NG_HT40; break; case MLME_DOT11_MODE_ALL: case MLME_DOT11_MODE_11AC: case MLME_DOT11_MODE_11AC_ONLY: if (bw_val == 20) - phymode = MODE_11AC_VHT20_2G; + phymode = WLAN_PHYMODE_11AC_VHT20_2G; else if (bw_val == 40) - phymode = MODE_11AC_VHT40_2G; + phymode = WLAN_PHYMODE_11AC_VHT40_2G; break; case MLME_DOT11_MODE_11AX: case MLME_DOT11_MODE_11AX_ONLY: if (20 == bw_val) - phymode = MODE_11AX_HE20_2G; + phymode = WLAN_PHYMODE_11AXG_HE20; else if (40 == bw_val) - phymode = MODE_11AX_HE40_2G; + phymode = WLAN_PHYMODE_11AXG_HE40; break; default: break; } } - } else if (wlan_reg_is_dsrc_chan(wma->pdev, chan)) - phymode = MODE_11A; + } else if (wlan_reg_is_dsrc_freq(freq)) + phymode = WLAN_PHYMODE_11A; else { if (((CH_WIDTH_5MHZ == chan_width) || (CH_WIDTH_10MHZ == chan_width)) && @@ -706,46 +635,46 @@ WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width, (MLME_DOT11_MODE_ALL == dot11_mode) || (MLME_DOT11_MODE_11AC == dot11_mode) || (MLME_DOT11_MODE_11AX == dot11_mode))) - phymode = MODE_11A; + phymode = WLAN_PHYMODE_11A; else { switch (dot11_mode) { case MLME_DOT11_MODE_11A: if (0 < bw_val) - phymode = MODE_11A; + phymode = WLAN_PHYMODE_11A; break; case MLME_DOT11_MODE_11N: case MLME_DOT11_MODE_11N_ONLY: if (bw_val == 20) - phymode = MODE_11NA_HT20; + phymode = WLAN_PHYMODE_11NA_HT20; else if (40 <= bw_val) - phymode = MODE_11NA_HT40; + phymode = WLAN_PHYMODE_11NA_HT40; break; case MLME_DOT11_MODE_ALL: case MLME_DOT11_MODE_11AC: case MLME_DOT11_MODE_11AC_ONLY: if (bw_val == 20) - phymode = MODE_11AC_VHT20; + phymode = WLAN_PHYMODE_11AC_VHT20; else if (bw_val == 40) - phymode = MODE_11AC_VHT40; + phymode = WLAN_PHYMODE_11AC_VHT40; else if (bw_val == 80) - phymode = MODE_11AC_VHT80; + phymode = WLAN_PHYMODE_11AC_VHT80; else if (chan_width == CH_WIDTH_160MHZ) - phymode = MODE_11AC_VHT160; + phymode = WLAN_PHYMODE_11AC_VHT160; else if (chan_width == CH_WIDTH_80P80MHZ) - phymode = MODE_11AC_VHT80_80; + phymode = WLAN_PHYMODE_11AC_VHT80_80; break; case MLME_DOT11_MODE_11AX: case MLME_DOT11_MODE_11AX_ONLY: if (20 == bw_val) - phymode = MODE_11AX_HE20; + phymode = WLAN_PHYMODE_11AXA_HE20; else if (40 == bw_val) - phymode = MODE_11AX_HE40; + phymode = WLAN_PHYMODE_11AXA_HE40; else if (80 == bw_val) - phymode = MODE_11AX_HE80; + phymode = WLAN_PHYMODE_11AXA_HE80; else if (CH_WIDTH_160MHZ == chan_width) - phymode = MODE_11AX_HE160; + phymode = WLAN_PHYMODE_11AXA_HE160; else if (CH_WIDTH_80P80MHZ == chan_width) - phymode = MODE_11AX_HE80_80; + phymode = WLAN_PHYMODE_11AXA_HE80_80; break; default: break; @@ -753,10 +682,10 @@ WLAN_PHY_MODE wma_chan_phy_mode(uint8_t chan, enum phy_ch_width chan_width, } } - WMA_LOGD("%s: phymode %d channel %d ch_width %d dot11_mode %d", - __func__, phymode, chan, chan_width, dot11_mode); + WMA_LOGD("%s: phymode %d freq %d ch_width %d dot11_mode %d", + __func__, phymode, freq, chan_width, dot11_mode); - QDF_ASSERT(MODE_UNKNOWN != phymode); + QDF_ASSERT(phymode != WLAN_PHYMODE_AUTO); return phymode; } @@ -788,8 +717,8 @@ QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, /* Copy the peer macaddress to the wma buffer */ WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr.bytes, &peer_macaddr); - WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x", - __func__, pLinkSpeed->peer_macaddr.bytes, + WMA_LOGD("%s: pLinkSpeed->peerMacAddr: "QDF_MAC_ADDR_FMT", peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x", + __func__, QDF_MAC_ADDR_REF(pLinkSpeed->peer_macaddr.bytes), peer_macaddr.mac_addr31to0, peer_macaddr.mac_addr47to32); if (wmi_unified_get_link_speed_cmd(wma_handle->wmi_handle, @@ -800,51 +729,6 @@ QDF_STATUS wma_get_link_speed(WMA_HANDLE handle, return QDF_STATUS_SUCCESS; } -QDF_STATUS wma_get_peer_info(WMA_HANDLE handle, - struct sir_peer_info_req *peer_info_req) -{ - tp_wma_handle wma_handle = (tp_wma_handle)handle; - wmi_request_stats_cmd_fixed_param *cmd; - wmi_buf_t wmi_buf; - uint32_t len; - uint8_t *buf_ptr; - - if (!wma_handle || !wma_handle->wmi_handle) { - WMA_LOGE("%s: WMA is closed, can not issue get rssi", - __func__); - return QDF_STATUS_E_INVAL; - } - - len = sizeof(wmi_request_stats_cmd_fixed_param); - wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); - if (!wmi_buf) - return QDF_STATUS_E_NOMEM; - - buf_ptr = (uint8_t *)wmi_buf_data(wmi_buf); - - cmd = (wmi_request_stats_cmd_fixed_param *)buf_ptr; - WMITLV_SET_HDR(&cmd->tlv_header, - WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, - WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param)); - - cmd->stats_id = WMI_REQUEST_PEER_STAT; - cmd->vdev_id = peer_info_req->sessionid; - WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes, - &cmd->peer_macaddr); - wma_handle->get_sta_peer_info = true; - - if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, - WMI_REQUEST_STATS_CMDID)) { - wmi_buf_free(wmi_buf); - return QDF_STATUS_E_FAILURE; - } - - qdf_mem_copy(&(wma_handle->peer_macaddr), - &(peer_info_req->peer_macaddr), - QDF_MAC_ADDR_SIZE); - return QDF_STATUS_SUCCESS; -} - QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle, struct sir_peer_info_ext_req *peer_info_req) { @@ -887,10 +771,10 @@ QDF_STATUS wma_get_peer_info_ext(WMA_HANDLE handle, return QDF_STATUS_E_FAILURE; } - WMA_LOGI("%s vdev_id %d, mac %pM, req_type %x, reset %x", + WMA_LOGI("%s vdev_id %d, mac "QDF_MAC_ADDR_FMT", req_type %x, reset %x", __func__, cmd->vdev_id, - peer_info_req->peer_macaddr.bytes, + QDF_MAC_ADDR_REF(peer_info_req->peer_macaddr.bytes), cmd->request_type, cmd->reset_after_request); @@ -1276,7 +1160,7 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len) csa_event = param_buf->fixed_param; WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]); - if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) { + if (wma_find_vdev_id_by_bssid(wma, bssid, &vdev_id)) { WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__); return -EINVAL; } @@ -1300,6 +1184,9 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len) csa_ie = (struct ieee80211_channelswitch_ie *) (&csa_event->csa_ie[0]); csa_offload_event->channel = csa_ie->newchannel; + csa_offload_event->csa_chan_freq = + wlan_reg_legacy_chan_to_freq(wma->pdev, + csa_ie->newchannel); csa_offload_event->switch_mode = csa_ie->switchmode; } else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) { xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *) @@ -1307,6 +1194,16 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len) csa_offload_event->channel = xcsa_ie->newchannel; csa_offload_event->switch_mode = xcsa_ie->switchmode; csa_offload_event->new_op_class = xcsa_ie->newClass; + if (wlan_reg_is_6ghz_op_class(wma->pdev, xcsa_ie->newClass)) { + csa_offload_event->csa_chan_freq = + wlan_reg_chan_band_to_freq + (wma->pdev, xcsa_ie->newchannel, + BIT(REG_BAND_6G)); + } else { + csa_offload_event->csa_chan_freq = + wlan_reg_legacy_chan_to_freq + (wma->pdev, xcsa_ie->newchannel); + } } else { WMA_LOGE("CSA Event error: No CSA IE present"); qdf_mem_free(csa_offload_event); @@ -1337,8 +1234,10 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len) csa_offload_event->ies_present_flag = csa_event->ies_present_flag; - WMA_LOGD("CSA: BSSID %pM chan %d flag 0x%x width = %d freq1 = %d freq2 = %d op class = %d", - csa_offload_event->bssId, csa_offload_event->channel, + WMA_LOGD("CSA: BSSID "QDF_MAC_ADDR_FMT" chan %d freq %d flag 0x%x width = %d freq1 = %d freq2 = %d op class = %d", + QDF_MAC_ADDR_REF(csa_offload_event->bssId), + csa_offload_event->channel, + csa_offload_event->csa_chan_freq, csa_event->ies_present_flag, csa_offload_event->new_ch_width, csa_offload_event->new_ch_freq_seg1, @@ -1498,7 +1397,7 @@ QDF_STATUS wma_start_oem_data_cmd(tp_wma_handle wma_handle, } #endif -#if !defined(REMOVE_PKT_LOG) +#if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) /** * wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target * @handle: wma handle @@ -1520,7 +1419,7 @@ QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle, return QDF_STATUS_SUCCESS; } -#endif /* REMOVE_PKT_LOG */ +#endif /* !REMOVE_PKT_LOG && FEATURE_PKTLOG */ /** * wma_wow_wake_reason_str() - Converts wow wakeup reason code to text format @@ -1652,7 +1551,6 @@ static const uint8_t *wma_wow_wake_reason_str(A_INT32 wake_reason) } } -#ifdef QCA_SUPPORT_CP_STATS static bool wma_wow_reason_has_stats(enum wake_reason_e reason) { switch (reason) { @@ -1754,124 +1652,6 @@ static void wma_print_wow_stats(t_wma_handle *wma, wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); wma_wow_stats_display(&stats); } -#else -/** - * wma_wow_stats_display() - display wow wake up stats - * @stats: per vdev stats counters - * - * Return: none - */ -static void wma_wow_stats_display(struct sir_vdev_wow_stats *stats) -{ - WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d", - stats->ucast, - stats->bcast, - stats->ipv4_mcast, - stats->ipv6_mcast, - stats->ipv6_mcast_ra, - stats->ipv6_mcast_ns, - stats->ipv6_mcast_na, - stats->pno_match, - stats->pno_complete, - stats->gscan, - stats->low_rssi, - stats->rssi_breach, - stats->icmpv4, - stats->icmpv6, - stats->oem_response); -} - -static void wma_print_wow_stats(t_wma_handle *wma, - WOW_EVENT_INFO_fixed_param *wake_info) -{ - struct sir_vdev_wow_stats *stats; - - switch (wake_info->wake_reason) { - case WOW_REASON_BPF_ALLOW: - case WOW_REASON_PATTERN_MATCH_FOUND: - case WOW_REASON_PACKET_FILTER_MATCH: - case WOW_REASON_RA_MATCH: - case WOW_REASON_NLOD: - case WOW_REASON_NLO_SCAN_COMPLETE: - case WOW_REASON_LOW_RSSI: - case WOW_REASON_EXTSCAN: - case WOW_REASON_RSSI_BREACH_EVENT: - case WOW_REASON_OEM_RESPONSE_EVENT: - case WOW_REASON_CHIP_POWER_FAILURE_DETECT: - case WOW_REASON_11D_SCAN: - break; -#ifdef WLAN_FEATURE_MOTION_DETECTION - case WOW_REASON_WLAN_MD: - case WOW_REASON_WLAN_BL: - break; -#endif /* WLAN_FEATURE_MOTION_DETECTION */ - default: - return; - } - - stats = &wma->interfaces[wake_info->vdev_id].wow_stats; - wma_wow_stats_display(stats); -} - -/** - * wma_inc_wow_stats() - maintain wow pattern match wake up stats - * @wma: wma handle, containing the stats counters - * @wake_info: the wake event information - * - * Return: none - */ -static void wma_inc_wow_stats(t_wma_handle *wma, - WOW_EVENT_INFO_fixed_param *wake_info) -{ - struct sir_vdev_wow_stats *stats; - - if (wake_info->wake_reason == WOW_REASON_UNSPECIFIED) { - wma->wow_unspecified_wake_count++; - return; - } - - stats = &wma->interfaces[wake_info->vdev_id].wow_stats; - switch (wake_info->wake_reason) { - case WOW_REASON_RA_MATCH: - stats->ipv6_mcast++; - stats->ipv6_mcast_ra++; - stats->icmpv6++; - break; - case WOW_REASON_NLOD: - stats->pno_match++; - break; - case WOW_REASON_NLO_SCAN_COMPLETE: - stats->pno_complete++; - break; - case WOW_REASON_LOW_RSSI: - stats->low_rssi++; - break; - case WOW_REASON_EXTSCAN: - stats->gscan++; - break; - case WOW_REASON_RSSI_BREACH_EVENT: - stats->rssi_breach++; - break; - case WOW_REASON_OEM_RESPONSE_EVENT: - stats->oem_response++; - break; - case WOW_REASON_11D_SCAN: - stats->scan_11d++; - break; - case WOW_REASON_CHIP_POWER_FAILURE_DETECT: - stats->pwr_save_fail_detected++; - break; -#ifdef WLAN_FEATURE_MOTION_DETECTION - case WOW_REASON_WLAN_MD: - stats->motion_detect++; - break; - case WOW_REASON_WLAN_BL: - stats->motion_detect_bl++; - break; -#endif /* WLAN_FEATURE_MOTION_DETECTION */ - } -} -#endif #ifdef FEATURE_WLAN_EXTSCAN /** @@ -2343,7 +2123,6 @@ static void wma_log_pkt_tcpv6(uint8_t *data, uint32_t length) WMA_LOGD("TCP_seq_num: %u", qdf_cpu_to_be16(seq_num)); } -#ifdef QCA_SUPPORT_CP_STATS static void wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle *wma, uint8_t vdev_id, uint8_t *dest_mac) @@ -2360,68 +2139,6 @@ static void wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle *wma, vdev_id, proto_subtype); } -#else -static void wma_wow_inc_wake_lock_stats_by_dst_addr(t_wma_handle *wma, - uint8_t vdev_id, - uint8_t *dest_mac) -{ - struct wma_txrx_node *vdev; - struct sir_vdev_wow_stats *stats; - - vdev = &wma->interfaces[vdev_id]; - stats = &vdev->wow_stats; - - switch (*dest_mac) { - case QDF_BCAST_MAC_ADDR: - stats->bcast++; - break; - case QDF_MCAST_IPV4_MAC_ADDR: - stats->ipv4_mcast++; - break; - case QDF_MCAST_IPV6_MAC_ADDR: - stats->ipv6_mcast++; - break; - default: - stats->ucast++; - break; - } -} - -static void wma_wow_inc_wake_lock_stats_by_protocol(t_wma_handle *wma, - uint8_t vdev_id, enum qdf_proto_subtype proto_subtype) -{ - struct wma_txrx_node *vdev; - struct sir_vdev_wow_stats *stats; - - vdev = &wma->interfaces[vdev_id]; - stats = &vdev->wow_stats; - - switch (proto_subtype) { - case QDF_PROTO_ICMP_RES: - stats->icmpv4++; - break; - case QDF_PROTO_ICMPV6_REQ: - case QDF_PROTO_ICMPV6_RES: - case QDF_PROTO_ICMPV6_RS: - stats->icmpv6++; - break; - case QDF_PROTO_ICMPV6_RA: - stats->icmpv6++; - stats->ipv6_mcast_ra++; - break; - case QDF_PROTO_ICMPV6_NS: - stats->icmpv6++; - stats->ipv6_mcast_ns++; - break; - case QDF_PROTO_ICMPV6_NA: - stats->icmpv6++; - stats->ipv6_mcast_na++; - break; - default: - break; - } -} -#endif /** * wma_wow_parse_data_pkt() - API to parse data buffer for data @@ -2451,8 +2168,8 @@ static void wma_wow_parse_data_pkt(t_wma_handle *wma, src_mac = data + QDF_NBUF_SRC_MAC_OFFSET; dest_mac = data + QDF_NBUF_DEST_MAC_OFFSET; - wma_info("Src_mac: " QDF_MAC_ADDR_STR ", Dst_mac: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(src_mac), QDF_MAC_ADDR_ARRAY(dest_mac)); + wma_info("Src_mac: " QDF_MAC_ADDR_FMT ", Dst_mac: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(src_mac), QDF_MAC_ADDR_REF(dest_mac)); wma_wow_inc_wake_lock_stats_by_dst_addr(wma, vdev_id, dest_mac); @@ -2542,9 +2259,9 @@ static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer, uint8_t to_from_ds, frag_num; uint32_t seq_num; - wma_err("RA: " QDF_MAC_ADDR_STR " TA: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr1), - QDF_MAC_ADDR_ARRAY(wh->i_addr2)); + wma_err("RA: " QDF_MAC_ADDR_FMT " TA: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr1), + QDF_MAC_ADDR_REF(wh->i_addr2)); WMA_LOGE("TO_DS: %u, FROM_DS: %u", wh->i_fc[1] & IEEE80211_FC1_DIR_TODS, @@ -2554,23 +2271,23 @@ static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer, switch (to_from_ds) { case IEEE80211_FC1_DIR_NODS: - wma_err("BSSID: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr3)); + wma_err("BSSID: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr3)); break; case IEEE80211_FC1_DIR_TODS: - wma_err("DA: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr3)); + wma_err("DA: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr3)); break; case IEEE80211_FC1_DIR_FROMDS: - wma_err("SA: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr3)); + wma_err("SA: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr3)); break; case IEEE80211_FC1_DIR_DSTODS: if (buf_len >= sizeof(struct ieee80211_frame_addr4)) - wma_err("DA: " QDF_MAC_ADDR_STR " SA: " - QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr3), - QDF_MAC_ADDR_ARRAY(wh->i_addr4)); + wma_err("DA: " QDF_MAC_ADDR_FMT " SA: " + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr3), + QDF_MAC_ADDR_REF(wh->i_addr4)); break; } @@ -2760,15 +2477,15 @@ static int wma_wake_event_packet( * dump event buffer which contains more info regarding * current page fault. */ - WMA_LOGD("PAGE_FAULT occurs during suspend:"); + wma_debug("PAGE_FAULT occurs during suspend: packet_len %u", + packet_len); qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, packet, packet_len); break; default: - WMA_LOGE("Wake reason %s(%u) is not a packet event", - wma_wow_wake_reason_str(wake_info->wake_reason), - wake_info->wake_reason); + WMA_LOGE("Wake reason %s is not a packet event", + wma_wow_wake_reason_str(wake_info->wake_reason)); return -EINVAL; } @@ -2805,10 +2522,7 @@ static int wma_wake_event_piggybacked( uint32_t wake_reason; uint32_t event_id; uint8_t *bssid; - uint8_t peer_id; - void *peer, *pdev; tpDeleteStaContext del_sta_ctx; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* * There are "normal" cases where a wake reason that usually contains a @@ -2822,9 +2536,13 @@ static int wma_wake_event_piggybacked( return 0; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - bssid = wma->interfaces[event_param->fixed_param->vdev_id].bssid; - peer = cdp_peer_find_by_addr(soc, pdev, bssid, &peer_id); + bssid = wma_get_vdev_bssid + (wma->interfaces[event_param->fixed_param->vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, event_param->fixed_param->vdev_id); + return 0; + } wake_reason = event_param->fixed_param->wake_reason; /* parse piggybacked event from param buffer */ @@ -2954,7 +2672,6 @@ static int wma_wake_event_piggybacked( del_sta_ctx->is_tdls = false; del_sta_ctx->vdev_id = event_param->fixed_param->vdev_id; - del_sta_ctx->staId = peer_id; qdf_mem_copy(del_sta_ctx->addr2, bssid, QDF_MAC_ADDR_SIZE); qdf_mem_copy(del_sta_ctx->bssId, bssid, QDF_MAC_ADDR_SIZE); del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE; @@ -2978,6 +2695,13 @@ static int wma_wake_event_piggybacked( return errno; } +static void wma_debug_assert_page_fault_wakeup(uint32_t reason) +{ + /* During DRV if page fault wake up then assert */ + if ((WOW_REASON_PAGE_FAULT == reason) && (qdf_is_drv_connected())) + QDF_DEBUG_PANIC("Unexpected page fault wake up detected during DRV wow"); +} + static void wma_wake_event_log_reason(t_wma_handle *wma, WOW_EVENT_INFO_fixed_param *wake_info) { @@ -2991,6 +2715,7 @@ static void wma_wake_event_log_reason(t_wma_handle *wma, wake_info->wake_reason, wake_info->vdev_id, wma_vdev_type_str(vdev->type)); + wma_debug_assert_page_fault_wakeup(wake_info->wake_reason); } else if (!wmi_get_runtime_pm_inprogress(wma->wmi_handle)) { WMA_LOGA("Non-WLAN triggered wakeup: %s (%d)", wma_wow_wake_reason_str(wake_info->wake_reason), @@ -3169,17 +2894,11 @@ static QDF_STATUS wma_set_tsm_interval(struct add_ts_param *req) * */ uint32_t interval_milliseconds; - struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - return QDF_STATUS_E_FAILURE; - } interval_milliseconds = (req->tsm_interval * 1024) / 1000; cdp_tx_set_compute_interval(cds_get_context(QDF_MODULE_ID_SOC), - pdev, + WMI_PDEV_ID_SOC, interval_milliseconds); return QDF_STATUS_SUCCESS; } @@ -3252,25 +2971,18 @@ QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler, * than required by TSM, hence different (6) size array used */ uint16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = { 0, }; - struct cdp_pdev *pdev = cds_get_context(QDF_MODULE_ID_TXRX); void *soc = cds_get_context(QDF_MODULE_ID_SOC); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - qdf_mem_free(pTsmStatsMsg); - return QDF_STATUS_E_INVAL; - } - /* get required values from data path APIs */ cdp_tx_delay(soc, - pdev, + WMI_PDEV_ID_SOC, &queue_delay_microsec, &tx_delay_microsec, tid); cdp_tx_delay_hist(soc, - pdev, + WMI_PDEV_ID_SOC, bin_values, tid); cdp_tx_packet_count(soc, - pdev, + WMI_PDEV_ID_SOC, &packet_count, &packet_loss_count, tid); @@ -3280,7 +2992,6 @@ QDF_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler, qdf_mem_free(pTsmStatsMsg); return QDF_STATUS_E_NOMEM; } - pTsmRspParams->staId = pStats->staId; qdf_copy_macaddr(&pTsmRspParams->bssid, &pStats->bssId); pTsmRspParams->rc = QDF_STATUS_E_FAILURE; pTsmRspParams->tsmStatsReq = pStats; @@ -3364,11 +3075,9 @@ QDF_STATUS wma_process_get_peer_info_req uint16_t len; wmi_buf_t buf; int32_t vdev_id; - struct cdp_pdev *pdev; - void *peer; + uint8_t pdev_id; void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; - uint8_t *peer_mac_raw; wmi_peer_info_req_cmd_fixed_param *p_get_peer_info_cmd; uint8_t bcast_mac[QDF_MAC_ADDR_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -3385,36 +3094,27 @@ QDF_STATUS wma_process_get_peer_info_req return QDF_STATUS_E_FAILURE; } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev context", __func__); + pdev_id = WMI_PDEV_ID_SOC; + if (pdev_id == OL_TXRX_INVALID_PDEV_ID) { + WMA_LOGE("%s: Failed to get pdev id", __func__); return QDF_STATUS_E_FAILURE; } - if (0xFF == pReq->staIdx) { + if (qdf_is_macaddr_broadcast(&pReq->peer_mac)) { /*get info for all peers */ qdf_mem_copy(peer_mac, bcast_mac, QDF_MAC_ADDR_SIZE); } else { /*get info for a single peer */ - peer = cdp_peer_find_by_local_id(soc, - pdev, pReq->staIdx); - if (!peer) { - WMA_LOGE("%s: Failed to get peer handle using peer id %d", - __func__, pReq->staIdx); - return QDF_STATUS_E_FAILURE; - } - peer_mac_raw = cdp_peer_get_peer_mac_addr(soc, peer); - if (!peer_mac_raw) { - WMA_LOGE("peer_mac_raw is NULL"); + if (!cdp_find_peer_exist(soc, pdev_id, pReq->peer_mac.bytes)) { + WMA_LOGE("%s: Failed to get peer handle using peer " + QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(pReq->peer_mac.bytes)); return QDF_STATUS_E_FAILURE; } - WMA_LOGE("%s: staIdx %d peer mac: 0x%2x:0x%2x:0x%2x:0x%2x:0x%2x:0x%2x", - __func__, pReq->staIdx, peer_mac_raw[0], - peer_mac_raw[1], peer_mac_raw[2], - peer_mac_raw[3], peer_mac_raw[4], - peer_mac_raw[5]); - qdf_mem_copy(peer_mac, peer_mac_raw, QDF_MAC_ADDR_SIZE); + WMA_LOGE("%s: peer mac: " QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(pReq->peer_mac.bytes)); + qdf_mem_copy(peer_mac, pReq->peer_mac.bytes, QDF_MAC_ADDR_SIZE); } len = sizeof(wmi_peer_info_req_cmd_fixed_param); @@ -3667,11 +3367,12 @@ QDF_STATUS wma_process_add_periodic_tx_ptrn_ind(WMA_HANDLE handle, return QDF_STATUS_E_INVAL; } - if (!wma_find_vdev_by_addr(wma_handle, - pattern->mac_address.bytes, - &vdev_id)) { - WMA_LOGE("%s: Failed to find vdev id for %pM", __func__, - pattern->mac_address.bytes); + if (wma_find_vdev_id_by_addr(wma_handle, + pattern->mac_address.bytes, + &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for "QDF_MAC_ADDR_FMT, + __func__, + QDF_MAC_ADDR_REF(pattern->mac_address.bytes)); return QDF_STATUS_E_INVAL; } @@ -3714,11 +3415,13 @@ QDF_STATUS wma_process_del_periodic_tx_ptrn_ind(WMA_HANDLE handle, return QDF_STATUS_E_INVAL; } - if (!wma_find_vdev_by_addr(wma_handle, - pDelPeriodicTxPtrnParams->mac_address.bytes, - &vdev_id)) { - WMA_LOGE("%s: Failed to find vdev id for %pM", __func__, - pDelPeriodicTxPtrnParams->mac_address.bytes); + if (wma_find_vdev_id_by_addr( + wma_handle, + pDelPeriodicTxPtrnParams->mac_address.bytes, + &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for "QDF_MAC_ADDR_FMT, + __func__, + QDF_MAC_ADDR_REF(pDelPeriodicTxPtrnParams->mac_address.bytes)); return QDF_STATUS_E_INVAL; } @@ -4124,12 +3827,8 @@ int wma_update_tdls_peer_state(WMA_HANDLE handle, { tp_wma_handle wma_handle = (tp_wma_handle) handle; uint32_t i; - struct cdp_pdev *pdev; - uint8_t peer_id; - void *peer, *vdev; void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct tdls_peer_params *peer_cap; - uint8_t *peer_mac_addr; int ret = 0; uint32_t *ch_mhz = NULL; size_t ch_mhz_len; @@ -4157,6 +3856,15 @@ int wma_update_tdls_peer_state(WMA_HANDLE handle, goto end_tdls_peer_state; } + + if (!wma_objmgr_peer_exist(wma_handle, + peer_state->peer_macaddr, NULL)) { + wma_err("peer:" QDF_MAC_ADDR_FMT "doesn't exist", + QDF_MAC_ADDR_REF(peer_state->peer_macaddr)); + ret = -EINVAL; + goto end_tdls_peer_state; + } + peer_cap = &peer_state->peer_cap; /* peer capability info is valid only when peer state is connected */ @@ -4177,25 +3885,9 @@ int wma_update_tdls_peer_state(WMA_HANDLE handle, } } - /* Make sure that peer exists before sending peer state cmd*/ - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to find pdev", __func__); - ret = -EIO; - goto end_tdls_peer_state; - } - - peer = cdp_peer_find_by_addr(soc, - pdev, - peer_state->peer_macaddr, - &peer_id); - if (!peer) { - WMA_LOGE("%s: Failed to get peer handle using peer mac %pM", - __func__, peer_state->peer_macaddr); - ret = -EIO; - goto end_tdls_peer_state; - } - vdev = cdp_peer_get_vdev(soc, peer); + cdp_peer_set_tdls_offchan_enabled(soc, peer_state->vdev_id, + peer_state->peer_macaddr, + !!peer_cap->peer_off_chan_support); if (wmi_unified_update_tdls_peer_state_cmd(wma_handle->wmi_handle, peer_state, @@ -4208,36 +3900,30 @@ int wma_update_tdls_peer_state(WMA_HANDLE handle, /* in case of teardown, remove peer from fw */ if (TDLS_PEER_STATE_TEARDOWN == peer_state->peer_state) { - peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer); - if (!peer_mac_addr) { - WMA_LOGE("peer_mac_addr is NULL"); - ret = -EIO; - goto end_tdls_peer_state; - } - restore_last_peer = cdp_peer_is_vdev_restore_last_peer( - soc, peer); + soc, + peer_state->vdev_id, + peer_state->peer_macaddr); - wma_debug("calling wma_remove_peer for peer " QDF_MAC_ADDR_STR + wma_debug("calling wma_remove_peer for peer " QDF_MAC_ADDR_FMT " vdevId: %d", - QDF_MAC_ADDR_ARRAY(peer_mac_addr), + QDF_MAC_ADDR_REF(peer_state->peer_macaddr), peer_state->vdev_id); - qdf_status = wma_remove_peer(wma_handle, peer_mac_addr, - peer_state->vdev_id, peer, false); + qdf_status = wma_remove_peer(wma_handle, + peer_state->peer_macaddr, + peer_state->vdev_id, false); if (QDF_IS_STATUS_ERROR(qdf_status)) { WMA_LOGE(FL("wma_remove_peer failed")); ret = -EINVAL; } - cdp_peer_update_last_real_peer(soc, - pdev, vdev, &peer_id, - restore_last_peer); + cdp_peer_update_last_real_peer(soc, WMI_PDEV_ID_SOC, + peer_state->vdev_id, + restore_last_peer); } if (TDLS_PEER_STATE_CONNECTED == peer_state->peer_state) { - peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer); - if (peer_mac_addr) - cdp_peer_state_update(soc, pdev, peer_mac_addr, - OL_TXRX_PEER_STATE_AUTH); + cdp_peer_state_update(soc, peer_state->peer_macaddr, + OL_TXRX_PEER_STATE_AUTH); } end_tdls_peer_state: @@ -4505,6 +4191,9 @@ QDF_STATUS wma_send_apf_enable_cmd(WMA_HANDLE handle, uint8_t vdev_id, return QDF_STATUS_E_INVAL; } + if (!wma_is_vdev_valid(vdev_id)) + return QDF_STATUS_E_INVAL; + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, WMI_SERVICE_BPF_OFFLOAD)) { WMA_LOGE(FL("APF cababilities feature bit not enabled")); @@ -4629,16 +4318,10 @@ QDF_STATUS wma_send_apf_read_work_memory_cmd(WMA_HANDLE handle, } #endif /* FEATURE_WLAN_APF */ -/** - * wma_set_tx_rx_aggregation_size() - sets tx rx aggregation sizes - * @tx_rx_aggregation_size: aggregation size parameters - * - * This function sets tx rx aggregation sizes - * - * Return: QDF_STATUS - */ -QDF_STATUS wma_set_tx_rx_aggregation_size( - struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size) +QDF_STATUS wma_set_tx_rx_aggr_size(uint8_t vdev_id, + uint32_t tx_size, + uint32_t rx_size, + wmi_vdev_custom_aggr_type_t aggr_type) { tp_wma_handle wma_handle; wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; @@ -4649,10 +4332,6 @@ QDF_STATUS wma_set_tx_rx_aggregation_size( wma_handle = cds_get_context(QDF_MODULE_ID_WMA); - if (!tx_rx_aggregation_size) { - WMA_LOGE("%s: invalid pointer", __func__); - return QDF_STATUS_E_INVAL; - } if (!wma_handle) { WMA_LOGE("%s: WMA context is invald!", __func__); @@ -4673,12 +4352,11 @@ QDF_STATUS wma_set_tx_rx_aggregation_size( WMITLV_GET_STRUCT_TLVLEN( wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); - cmd->vdev_id = tx_rx_aggregation_size->vdev_id; - cmd->tx_aggr_size = tx_rx_aggregation_size->tx_aggregation_size; - cmd->rx_aggr_size = tx_rx_aggregation_size->rx_aggregation_size; + cmd->vdev_id = vdev_id; + cmd->tx_aggr_size = tx_size; + cmd->rx_aggr_size = rx_size; /* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */ - if (tx_rx_aggregation_size->aggr_type == - WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU) + if (aggr_type == WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU) cmd->enable_bitmap |= 0x04; WMA_LOGD("tx aggr: %d rx aggr: %d vdev: %d enable_bitmap %d", @@ -4695,10 +4373,11 @@ QDF_STATUS wma_set_tx_rx_aggregation_size( return QDF_STATUS_SUCCESS; } -QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac( - struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size) +QDF_STATUS wma_set_tx_rx_aggr_size_per_ac(WMA_HANDLE handle, + uint8_t vdev_id, + struct wlan_mlme_qos *qos_aggr, + wmi_vdev_custom_aggr_type_t aggr_type) { - tp_wma_handle wma_handle; wmi_vdev_set_custom_aggr_size_cmd_fixed_param *cmd; int32_t len; wmi_buf_t buf; @@ -4706,23 +4385,17 @@ QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac( int ret; int queue_num; uint32_t tx_aggr_size[4]; - - wma_handle = cds_get_context(QDF_MODULE_ID_WMA); - - if (!tx_rx_aggregation_size) { - WMA_LOGE("%s: invalid pointer", __func__); - return QDF_STATUS_E_INVAL; - } + tp_wma_handle wma_handle = (tp_wma_handle)handle; if (!wma_handle) { WMA_LOGE("%s: WMA context is invald!", __func__); return QDF_STATUS_E_INVAL; } - tx_aggr_size[0] = tx_rx_aggregation_size->tx_aggregation_size_be; - tx_aggr_size[1] = tx_rx_aggregation_size->tx_aggregation_size_bk; - tx_aggr_size[2] = tx_rx_aggregation_size->tx_aggregation_size_vi; - tx_aggr_size[3] = tx_rx_aggregation_size->tx_aggregation_size_vo; + tx_aggr_size[0] = qos_aggr->tx_aggregation_size_be; + tx_aggr_size[1] = qos_aggr->tx_aggregation_size_bk; + tx_aggr_size[2] = qos_aggr->tx_aggregation_size_vi; + tx_aggr_size[3] = qos_aggr->tx_aggregation_size_vo; for (queue_num = 0; queue_num < 4; queue_num++) { if (tx_aggr_size[queue_num] == 0) @@ -4742,16 +4415,13 @@ QDF_STATUS wma_set_tx_rx_aggregation_size_per_ac( WMITLV_GET_STRUCT_TLVLEN( wmi_vdev_set_custom_aggr_size_cmd_fixed_param)); - cmd->vdev_id = tx_rx_aggregation_size->vdev_id; - cmd->rx_aggr_size = - tx_rx_aggregation_size->rx_aggregation_size; - + cmd->vdev_id = vdev_id; + cmd->rx_aggr_size = qos_aggr->rx_aggregation_size; cmd->tx_aggr_size = tx_aggr_size[queue_num]; /* bit 5: tx_ac_enable, if set, ac bitmap is valid. */ cmd->enable_bitmap = 0x20 | queue_num; /* bit 2 (aggr_type): TX Aggregation Type (0=A-MPDU, 1=A-MSDU) */ - if (tx_rx_aggregation_size->aggr_type == - WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU) + if (aggr_type == WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU) cmd->enable_bitmap |= 0x04; WMA_LOGD("queue_num: %d, tx aggr: %d rx aggr: %d vdev: %d, bitmap: %d", @@ -4817,23 +4487,15 @@ static QDF_STATUS wma_set_sw_retry_by_qos( return QDF_STATUS_SUCCESS; } -QDF_STATUS wma_set_sw_retry_threshold_per_ac( - WMA_HANDLE handle, - struct sir_set_tx_sw_retry_threshold *tx_sw_retry_threshold) +QDF_STATUS wma_set_sw_retry_threshold_per_ac(WMA_HANDLE handle, + uint8_t vdev_id, + struct wlan_mlme_qos *qos_aggr) { QDF_STATUS ret; - tp_wma_handle wma_handle; - uint8_t vdev_id; int retry_type, queue_num; uint32_t tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX][WMI_AC_MAX]; uint32_t sw_retry; - - wma_handle = (tp_wma_handle)handle; - - if (!tx_sw_retry_threshold) { - wma_err("%s: invalid pointer", __func__); - return QDF_STATUS_E_INVAL; - } + tp_wma_handle wma_handle = (tp_wma_handle)handle; if (!wma_handle) { wma_err("%s: WMA context is invalid!", __func__); @@ -4841,22 +4503,22 @@ QDF_STATUS wma_set_sw_retry_threshold_per_ac( } tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BE] = - tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_be; + qos_aggr->tx_aggr_sw_retry_threshold_be; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_BK] = - tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_bk; + qos_aggr->tx_aggr_sw_retry_threshold_bk; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VI] = - tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_vi; + qos_aggr->tx_aggr_sw_retry_threshold_vi; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_AGGR][WMI_AC_VO] = - tx_sw_retry_threshold->tx_aggr_sw_retry_threshold_vo; + qos_aggr->tx_aggr_sw_retry_threshold_vo; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BE] = - tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_be; + qos_aggr->tx_non_aggr_sw_retry_threshold_be; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_BK] = - tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_bk; + qos_aggr->tx_non_aggr_sw_retry_threshold_bk; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VI] = - tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_vi; + qos_aggr->tx_non_aggr_sw_retry_threshold_vi; tx_sw_retry[WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR][WMI_AC_VO] = - tx_sw_retry_threshold->tx_non_aggr_sw_retry_threshold_vo; + qos_aggr->tx_non_aggr_sw_retry_threshold_vo; retry_type = WMI_VDEV_CUSTOM_SW_RETRY_TYPE_NONAGGR; while (retry_type < WMI_VDEV_CUSTOM_SW_RETRY_TYPE_MAX) { @@ -4864,7 +4526,6 @@ QDF_STATUS wma_set_sw_retry_threshold_per_ac( if (tx_sw_retry[retry_type][queue_num] == 0) continue; - vdev_id = tx_sw_retry_threshold->vdev_id; sw_retry = tx_sw_retry[retry_type][queue_num]; ret = wma_set_sw_retry_by_qos(wma_handle, vdev_id, @@ -4904,65 +4565,6 @@ QDF_STATUS wma_set_sw_retry_threshold(uint8_t vdev_id, uint32_t retry, return QDF_STATUS_SUCCESS; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_get_wakelock_stats() - Populates wake lock stats - * @stats: non-null wakelock structure to populate - * - * This function collects wake lock stats - * - * Return: QDF_STATUS_SUCCESS on success, error value otherwise - */ -QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *stats) -{ - t_wma_handle *wma; - struct sir_vdev_wow_stats *vstats; - int i; - - if (!stats) { - WMA_LOGE("%s: invalid stats pointer", __func__); - return QDF_STATUS_E_INVAL; - } - - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s: invalid WMA context", __func__); - return QDF_STATUS_E_INVAL; - } - - /* ensure counters are zeroed */ - qdf_mem_zero(stats, sizeof(*stats)); - - /* populate global level stats */ - stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count; - - /* populate vdev level stats */ - for (i = 0; i < wma->max_bssid; ++i) { - if (!wma->interfaces[i].handle) - continue; - - vstats = &wma->interfaces[i].wow_stats; - - stats->wow_ucast_wake_up_count += vstats->ucast; - stats->wow_bcast_wake_up_count += vstats->bcast; - stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast; - stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast; - stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra; - stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns; - stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na; - stats->wow_icmpv4_count += vstats->icmpv4; - stats->wow_icmpv6_count += vstats->icmpv6; - stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach; - stats->wow_low_rssi_wake_up_count += vstats->low_rssi; - stats->wow_gscan_wake_up_count += vstats->gscan; - stats->wow_pno_complete_wake_up_count += vstats->pno_complete; - stats->wow_pno_match_wake_up_count += vstats->pno_match; - stats->wow_oem_response_wake_up_count += vstats->oem_response; - } - - return QDF_STATUS_SUCCESS; -} -#endif /** * wma_process_fw_test_cmd() - send unit test command to fw. @@ -5278,8 +4880,8 @@ int wma_unified_power_debug_stats_event_handler(void *handle, param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *) param_tlvs->fixed_param; - if (!mac || !mac->sme.power_stats_resp_callback) { - WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__); + if (!mac) { + wma_debug("NULL mac ptr"); return -EINVAL; } @@ -5331,8 +4933,10 @@ int wma_unified_power_debug_stats_event_handler(void *handle, qdf_mem_copy(power_stats_results->debug_registers, debug_registers, stats_registers_len); - mac->sme.power_stats_resp_callback(power_stats_results, - mac->sme.power_debug_stats_context); + if (mac->sme.sme_power_debug_stats_callback) + mac->sme.sme_power_debug_stats_callback(mac, + power_stats_results); + qdf_mem_free(power_stats_results); return 0; } @@ -5416,6 +5020,8 @@ int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, struct mac_context *mac = NULL; struct lim_channel_status *channel_status; bool snr_monitor_enabled; + struct wlan_objmgr_vdev *vdev; + enum QDF_OPMODE mode; if (wma && wma->cds_context) mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE); @@ -5425,20 +5031,19 @@ int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, return -EINVAL; } + param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf; + if (!param_buf) { + WMA_LOGE("Invalid chan info event buffer"); + return -EINVAL; + } + event = param_buf->fixed_param; + if (!event) { + WMA_LOGA("%s: Invalid fixed param", __func__); + return -EINVAL; + } + snr_monitor_enabled = wlan_scan_is_snr_monitor_enabled(mac->psoc); if (snr_monitor_enabled && mac->chan_info_cb) { - param_buf = - (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf; - if (!param_buf) { - WMA_LOGA("%s: Invalid chan info event", __func__); - return -EINVAL; - } - - event = param_buf->fixed_param; - if (!event) { - WMA_LOGA("%s: Invalid fixed param", __func__); - return -EINVAL; - } buf.tx_frame_count = event->tx_frame_cnt; buf.clock_freq = event->mac_clk_mhz; buf.cmd_flag = event->cmd_flags; @@ -5449,17 +5054,21 @@ int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, mac->chan_info_cb(&buf); } - if (mac->sap.acs_with_more_param && - mac->sme.curr_device_mode == QDF_SAP_MODE) { - param_buf = (WMI_CHAN_INFO_EVENTID_param_tlvs *) event_buf; - if (!param_buf) { - WMA_LOGE("Invalid chan info event buffer"); - return -EINVAL; - } - event = param_buf->fixed_param; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, event->vdev_id, + WLAN_LEGACY_WMA_ID); + + if (!vdev) { + wma_err("vdev not found for vdev %d", event->vdev_id); + return -EINVAL; + } + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); + + if (mac->sap.acs_with_more_param && mode == QDF_SAP_MODE) { channel_status = qdf_mem_malloc(sizeof(*channel_status)); if (!channel_status) return -ENOMEM; + wma_debug("freq %d nf %d rxcnt %u cyccnt %u tx_r %d tx_t %d", event->freq, event->noise_floor, event->rx_clear_count, event->cycle_count, @@ -5635,7 +5244,7 @@ int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf, qdf_mem_zero(&chain_rssi_result, sizeof(chain_rssi_result)); WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->macaddr, macaddr); - wma_debug("macaddr: " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); + wma_debug("macaddr: " QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(macaddr)); WMA_LOGD(FL("num_chains_valid: %d"), event->num_chains_valid); chain_rssi_result.num_chains_valid = event->num_chains_valid; @@ -5710,8 +5319,7 @@ int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event, return 0; } -#ifdef CRYPTO_SET_KEY_CONVERGED -static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, +static void wma_send_set_key_rsp(uint8_t vdev_id, bool pairwise, uint8_t key_index) { tSetStaKeyParams *key_info_uc; @@ -5726,7 +5334,7 @@ static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, - session_id, + vdev_id, WLAN_LEGACY_WMA_ID); if (!vdev) { wma_err("VDEV object not found"); @@ -5744,8 +5352,7 @@ static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, key_info_uc = qdf_mem_malloc(sizeof(*key_info_uc)); if (!key_info_uc) return; - key_info_uc->sessionId = session_id; - key_info_uc->smesessionId = session_id; + key_info_uc->vdev_id = vdev_id; key_info_uc->status = QDF_STATUS_SUCCESS; key_info_uc->key[0].keyLength = crypto_key->keylen; qdf_mem_copy(&key_info_uc->macaddr, &crypto_key->macaddr, @@ -5756,8 +5363,7 @@ static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise, key_info_mc = qdf_mem_malloc(sizeof(*key_info_mc)); if (!key_info_mc) return; - key_info_mc->sessionId = session_id; - key_info_mc->smesessionId = session_id; + key_info_mc->vdev_id = vdev_id; key_info_mc->status = QDF_STATUS_SUCCESS; key_info_mc->key[0].keyLength = crypto_key->keylen; qdf_mem_copy(&key_info_mc->macaddr, &bcast_mac, @@ -5803,7 +5409,8 @@ void wma_set_peer_ucast_cipher(uint8_t *mac_addr, wlan_objmgr_pdev_get_pdev_id(wma->pdev), mac_addr, WLAN_LEGACY_WMA_ID); if (!peer) { - wma_err("Peer of peer_mac %pM not found", mac_addr); + wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(mac_addr)); return; } cipher_cap = wma_cipher_to_cap(cipher); @@ -5816,8 +5423,9 @@ void wma_set_peer_ucast_cipher(uint8_t *mac_addr, set_val); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - wma_debug("Set unicast cipher %x and cap %x for %pM", 1 << cipher, - 1 << cipher_cap, mac_addr); + wma_debug("Set unicast cipher %x and cap %x for "QDF_MAC_ADDR_FMT, + 1 << cipher, 1 << cipher_cap, + QDF_MAC_ADDR_REF(mac_addr)); } static void wma_reset_ipn(struct wma_txrx_node *iface, uint8_t key_index) @@ -5841,8 +5449,10 @@ void wma_update_set_key(uint8_t session_id, bool pairwise, return; } iface = &wma->interfaces[session_id]; - if (!iface) - wma_info("iface not found for session id %d", session_id); + if (!iface) { + wma_err("iface not found for session id %d", session_id); + return; + } if (cipher_type == WLAN_CRYPTO_CIPHER_AES_GMAC || cipher_type == WLAN_CRYPTO_CIPHER_AES_GMAC_256 || @@ -5864,7 +5474,6 @@ void wma_update_set_key(uint8_t session_id, bool pairwise, wma_send_set_key_rsp(session_id, pairwise, key_index); } -#endif /* CRYPTO_SET_KEY_CONVERGED */ int wma_vdev_bss_color_collision_info_handler(void *handle, uint8_t *event, @@ -5904,3 +5513,50 @@ int wma_vdev_bss_color_collision_info_handler(void *handle, return 0; } + +#ifdef FEATURE_ANI_LEVEL_REQUEST +int wma_get_ani_level_evt_handler(void *handle, uint8_t *event_buf, + uint32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + struct wmi_host_ani_level_event *ani = NULL; + uint32_t num_freqs = 0; + QDF_STATUS status; + struct mac_context *pmac; + int ret = 0; + + pmac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE); + if (!pmac || !wma) { + WMA_LOGE(FL("Invalid pmac or wma")); + return -EINVAL; + } + + status = wmi_unified_extract_ani_level(wma->wmi_handle, event_buf, + &ani, &num_freqs); + + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to extract ani level", __func__); + return -EINVAL; + } + + if (!pmac->ani_params.ani_level_cb) { + WMA_LOGE(FL("Invalid ani_level_cb")); + ret = -EINVAL; + goto free; + } + + pmac->ani_params.ani_level_cb(ani, num_freqs, + pmac->ani_params.context); + +free: + qdf_mem_free(ani); + return ret; +} +#else +int wma_get_ani_level_evt_handler(void *handle, uint8_t *event_buf, + uint32_t len) +{ + return 0; +} +#endif + diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_he.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_he.c index 8fab02b68f6fc69c54e6afdfb4a1f1e1a237cf5c..5b5ce5ad481bbe981b17aa4d0cd20f86e7d4fcf7 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_he.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_he.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -346,7 +346,8 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t *mac_cap, * Return: none */ static void wma_derive_ext_he_cap(tDot11fIEhe_cap *he_cap, - tDot11fIEhe_cap *new_cap) + tDot11fIEhe_cap *new_cap, + bool is_5g_cap) { uint16_t mcs_1, mcs_2; @@ -516,22 +517,24 @@ static void wma_derive_ext_he_cap(tDot11fIEhe_cap *he_cap, mcs_1 = he_cap->tx_he_mcs_map_lt_80; mcs_2 = new_cap->tx_he_mcs_map_lt_80; he_cap->tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2); - mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_160); - mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_160); - *((uint16_t *)he_cap->rx_he_mcs_map_160) = - HE_INTERSECT_MCS(mcs_1, mcs_2); - mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_160); - mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_160); - *((uint16_t *)he_cap->tx_he_mcs_map_160) = - HE_INTERSECT_MCS(mcs_1, mcs_2); - mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_80_80); - mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_80_80); - *((uint16_t *)he_cap->rx_he_mcs_map_80_80) = - HE_INTERSECT_MCS(mcs_1, mcs_2); - mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_80_80); - mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_80_80); - *((uint16_t *)he_cap->tx_he_mcs_map_80_80) = - HE_INTERSECT_MCS(mcs_1, mcs_2); + if (is_5g_cap) { + mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_160); + mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_160); + *((uint16_t *)he_cap->rx_he_mcs_map_160) = + HE_INTERSECT_MCS(mcs_1, mcs_2); + mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_160); + mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_160); + *((uint16_t *)he_cap->tx_he_mcs_map_160) = + HE_INTERSECT_MCS(mcs_1, mcs_2); + mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_80_80); + mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_80_80); + *((uint16_t *)he_cap->rx_he_mcs_map_80_80) = + HE_INTERSECT_MCS(mcs_1, mcs_2); + mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_80_80); + mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_80_80); + *((uint16_t *)he_cap->tx_he_mcs_map_80_80) = + HE_INTERSECT_MCS(mcs_1, mcs_2); + } } void wma_print_he_cap(tDot11fIEhe_cap *he_cap) @@ -898,6 +901,7 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl, struct wlan_psoc_host_mac_phy_caps *mac_cap, *mac_phy_cap; tDot11fIEhe_cap he_cap_mac; tDot11fIEhe_cap tmp_he_cap = {0}; + bool is_5g_cap; qdf_mem_zero(&tgt_cfg->he_cap_2g, sizeof(tgt_cfg->he_cap_2g)); qdf_mem_zero(&tgt_cfg->he_cap_5g, sizeof(tgt_cfg->he_cap_5g)); @@ -905,6 +909,12 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl, mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); + if (!mac_phy_cap) { + WMA_LOGE(FL("Invalid MAC PHY capabilities handle")); + he_cap->present = false; + return; + } + if (!num_hw_modes) { WMA_LOGE(FL("No extended HE cap for current SOC")); he_cap->present = false; @@ -921,6 +931,7 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl, qdf_mem_zero(&he_cap_mac, sizeof(tDot11fIEhe_cap)); mac_cap = &mac_phy_cap[i]; + is_5g_cap = false; if (mac_cap->supported_bands & WLAN_2G_CAPABILITY) { wma_convert_he_cap(&he_cap_mac, mac_cap->he_cap_info_2G, @@ -938,9 +949,11 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl, if (he_cap_mac.present) { wma_derive_ext_he_cap(&tmp_he_cap, - &he_cap_mac); + &he_cap_mac, + is_5g_cap); wma_derive_ext_he_cap(&tgt_cfg->he_cap_2g, - &he_cap_mac); + &he_cap_mac, + is_5g_cap); } qdf_mem_zero(&he_cap_mac, @@ -953,17 +966,20 @@ void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl, mac_cap->tx_chain_mask_5G, mac_cap->rx_chain_mask_5G); WMA_LOGD(FL("5g phy: nss: %d, ru_idx_msk: %d"), - mac_cap->he_ppet2G.numss_m1, - mac_cap->he_ppet2G.ru_bit_mask); + mac_cap->he_ppet5G.numss_m1, + mac_cap->he_ppet5G.ru_bit_mask); wma_convert_he_ppet(tgt_cfg->ppet_5g, (struct wmi_host_ppe_threshold *) &mac_cap->he_ppet5G); + is_5g_cap = true; } if (he_cap_mac.present) { wma_derive_ext_he_cap(&tmp_he_cap, - &he_cap_mac); + &he_cap_mac, + is_5g_cap); wma_derive_ext_he_cap(&tgt_cfg->he_cap_5g, - &he_cap_mac); + &he_cap_mac, + is_5g_cap); } } @@ -1098,7 +1114,7 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer, uint8_t temp, i, chan_width; if (params->he_capable) - peer->peer_flags |= WMI_PEER_HE; + peer->he_flag = 1; else return; @@ -1254,6 +1270,10 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer, params->supportedRates.tx_he_mcs_map_80_80; } +#define HE2x2MCSMASK 0xc + + peer->peer_nss = ((params->supportedRates.rx_he_mcs_map_lt_80 & + HE2x2MCSMASK) == HE2x2MCSMASK) ? 1 : 2; for (i = 0; i < peer->peer_he_mcs_count; i++) WMA_LOGD(FL("[HE - MCS Map: %d] rx_mcs: 0x%x, tx_mcs: 0x%x"), i, peer->peer_he_rx_mcs_set[i], @@ -1277,50 +1297,55 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer, wma_print_he_mac_cap_w2(mac_cap[1]); wma_print_he_ppet(&peer->peer_ppet); - return; -} - -void wma_update_vdev_he_ops(struct wma_vdev_start_req *req, - tpAddBssParams add_bss) -{ - uint32_t he_ops = 0; - tDot11fIEhe_op *he_op = &add_bss->he_op; - - req->he_capable = add_bss->he_capable; - - WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color); - WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe); - WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required); - WMI_HEOPS_RTSTHLD_SET(he_ops, he_op->txop_rts_threshold); - WMI_HEOPS_PARTBSSCOLOR_SET(he_ops, he_op->partial_bss_col); - WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled); - - req->he_ops = he_ops; + if (params->he_6ghz_band_caps.present) { + peer->peer_he_caps_6ghz = + (params->he_6ghz_band_caps.min_mpdu_start_spacing << + HE_6G_MIN_MPDU_START_SAPCE_BIT_POS) | + (params->he_6ghz_band_caps.max_ampdu_len_exp << + HE_6G_MAX_AMPDU_LEN_EXP_BIT_POS) | + (params->he_6ghz_band_caps.max_mpdu_len << + HE_6G_MAX_MPDU_LEN_BIT_POS) | + (params->he_6ghz_band_caps.sm_pow_save << + HE_6G_SMPS_BIT_POS) | + (params->he_6ghz_band_caps.rd_responder << + HE_6G_RD_RESP_BIT_POS) | + (params->he_6ghz_band_caps.rx_ant_pattern_consistency << + HE_6G_RX_ANT_PATTERN_BIT_POS) | + (params->he_6ghz_band_caps.tx_ant_pattern_consistency << + HE_6G_TX_ANT_PATTERN_BIT_POS); + WMA_LOGD(FL("HE 6GHz band caps: %0x"), peer->peer_he_caps_6ghz); + } else { + WMA_LOGD(FL("HE 6GHz band caps not present")); + peer->peer_he_caps_6ghz = 0; + } } -void wma_copy_vdev_start_he_ops(struct vdev_start_params *params, - struct wma_vdev_start_req *req) +void wma_update_vdev_he_ops(uint32_t *he_ops, tDot11fIEhe_op *he_op) { - params->he_ops = req->he_ops; + WMI_HEOPS_COLOR_SET(*he_ops, he_op->bss_color); + WMI_HEOPS_DEFPE_SET(*he_ops, he_op->default_pe); + WMI_HEOPS_TWT_SET(*he_ops, he_op->twt_required); + WMI_HEOPS_RTSTHLD_SET(*he_ops, he_op->txop_rts_threshold); + WMI_HEOPS_PARTBSSCOLOR_SET(*he_ops, he_op->partial_bss_col); + WMI_HEOPS_BSSCOLORDISABLE_SET(*he_ops, he_op->bss_col_disabled); } void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id, - struct wma_vdev_start_req *req) + struct vdev_mlme_he_ops_info *he_info) { QDF_STATUS ret; - if (!req->he_capable) + if (!he_info->he_ops) return; - ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_HEOPS_0_31, req->he_ops); + WMI_VDEV_PARAM_HEOPS_0_31, he_info->he_ops); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE(FL("Failed to set HE OPs")); } void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id, - tpAddBssParams add_bss) + struct bss_params *add_bss) { QDF_STATUS ret; int8_t pd_min, pd_max, sec_ch_ed, tx_pwr; @@ -1337,12 +1362,6 @@ void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id, pd_min, pd_max, sec_ch_ed, tx_pwr); } -void wma_update_vdev_he_capable(struct wma_vdev_start_req *req, - tpSwitchChannelParams params) -{ - req->he_capable = params->he_capable; -} - QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id, tDot11fIEhe_op *he_op) { diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c index 3047096dcdbf60cd466c3a2cd555436f26034346..db1ee1bfa8a889249efbf02f5528eec1f9edf8ab 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -98,19 +97,20 @@ #include "init_cmd_api.h" #include "nan_ucfg_api.h" #include "wma_coex.h" +#include "target_if_vdev_mgr_rx_ops.h" +#include "wlan_tdls_cfg_api.h" #include "wlan_policy_mgr_i.h" +#include "target_if_psoc_timer_tx_ops.h" + #ifdef DIRECT_BUF_RX_ENABLE #include #endif -#include "wlan_pkt_capture_ucfg_api.h" - #define WMA_LOG_COMPLETION_TIMER 3000 /* 3 seconds */ #define WMI_TLV_HEADROOM 128 #define WMA_FW_TIME_SYNC_TIMER 60000 /* 1 min */ -uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg); static uint32_t g_fw_wlan_feat_caps; /** * wma_get_fw_wlan_feat_caps() - get fw feature capablity @@ -218,6 +218,20 @@ static uint32_t wma_get_number_of_tids_supported(uint8_t no_of_peers_supported, } #endif +#if (defined(IPA_DISABLE_OVERRIDE)) && (!defined(IPA_OFFLOAD)) +static void wma_set_ipa_disable_config( + target_resource_config *tgt_cfg) +{ + tgt_cfg->ipa_disable = true; +} +#else +static void wma_set_ipa_disable_config( + target_resource_config *tgt_cfg) +{ + tgt_cfg->ipa_disable = false; +} +#endif + #ifndef NUM_OF_ADDITIONAL_FW_PEERS #define NUM_OF_ADDITIONAL_FW_PEERS 2 #endif @@ -301,7 +315,7 @@ static void wma_set_default_tgt_config(tp_wma_handle wma_handle, tgt_cfg->max_frag_entries = CFG_TGT_MAX_FRAG_TABLE_ENTRIES; tgt_cfg->num_tdls_vdevs = CFG_TGT_NUM_TDLS_VDEVS; tgt_cfg->num_tdls_conn_table_entries = - CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES; + cfg_tdls_get_max_peer_count(wma_handle->psoc); tgt_cfg->beacon_tx_offload_max_vdev = CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV; tgt_cfg->num_multicast_filter_entries = @@ -328,6 +342,11 @@ static void wma_set_default_tgt_config(tp_wma_handle wma_handle, if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE_RAW; + + cfg_nan_get_ndp_max_sessions(wma_handle->psoc, + &tgt_cfg->max_ndp_sessions); + + wma_set_ipa_disable_config(tgt_cfg); } /** @@ -677,107 +696,14 @@ static void wma_process_send_addba_req(tp_wma_handle wma_handle, if (QDF_STATUS_SUCCESS != status) { WMA_LOGE(FL("Failed to process WMA_SEND_ADDBA_REQ")); } - wma_debug("sent ADDBA req to" QDF_MAC_ADDR_STR "tid %d buff_size %d", - QDF_MAC_ADDR_ARRAY(send_addba->mac_addr), + wma_debug("sent ADDBA req to" QDF_MAC_ADDR_FMT "tid %d buff_size %d", + QDF_MAC_ADDR_REF(send_addba->mac_addr), send_addba->param.tidno, send_addba->param.buffersize); qdf_mem_free(send_addba); } -/** - * wma_ipa_get_stat() - get IPA data path stats from FW - * - * Return: 0 on success, errno on failure - */ -#ifdef IPA_OFFLOAD -static int wma_ipa_get_stat(void) -{ - struct cdp_pdev *pdev; - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("pdev NULL for uc stat"); - return -EINVAL; - } - cdp_ipa_get_stat(cds_get_context(QDF_MODULE_ID_SOC), pdev); - - return 0; -} -#else -static int wma_ipa_get_stat(void) -{ - return 0; -} -#endif - -/** - * wma_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW - * @privcmd: private command - * - * Return: 0 on success, errno on failure - */ -#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING) -static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd) -{ - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *pdev; - uint8_t reset_stats = privcmd->param_value; - - WMA_LOGD("%s: reset_stats=%d", - "WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID", - reset_stats); - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("pdev NULL for uc get share stats"); - return -EINVAL; - } - cdp_ipa_uc_get_share_stats(soc, pdev, reset_stats); - - return 0; -} -#else -static int wma_ipa_uc_get_share_stats(wma_cli_set_cmd_t *privcmd) -{ - return 0; -} -#endif - -/** - * wma_ipa_uc_set_quota() - set quota limit to FW - * @privcmd: private command - * - * Return: 0 on success, errno on failure - */ -#if defined(IPA_OFFLOAD) && defined(FEATURE_METERING) -static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd) -{ - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *pdev; - uint64_t quota_bytes = privcmd->param_sec_value; - - quota_bytes <<= 32; - quota_bytes |= privcmd->param_value; - - WMA_LOGD("%s: quota_bytes=%llu", - "WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID", - quota_bytes); - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("pdev NULL for uc set quota"); - return -EINVAL; - } - cdp_ipa_uc_set_quota(soc, pdev, quota_bytes); - - return 0; -} -#else -static int wma_ipa_uc_set_quota(wma_cli_set_cmd_t *privcmd) -{ - return 0; -} -#endif - /** * wma_set_priv_cfg() - set private config parameters * @wma_handle: wma handle @@ -922,25 +848,6 @@ static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle, } break; - case WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID: - { - wma_ipa_get_stat(); - } - break; - - case WMA_VDEV_TXRX_GET_IPA_UC_SHARING_STATS_CMDID: - { - wma_ipa_uc_get_share_stats(privcmd); - } - break; - - case WMA_VDEV_TXRX_SET_IPA_UC_QUOTA_CMDID: - { - wma_ipa_uc_set_quota(privcmd); - - } - break; - default: WMA_LOGE("Invalid wma config command id:%d", privcmd->param_id); ret = -EINVAL; @@ -988,9 +895,7 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, struct pdev_params pdev_param; void *soc = cds_get_context(QDF_MODULE_ID_SOC); struct target_psoc_info *tgt_hdl; - struct sir_set_tx_rx_aggregation_size aggr; - qdf_mem_zero(&aggr, sizeof(aggr)); if (!mac) { WMA_LOGE("%s: Failed to get mac", __func__); return; @@ -1057,14 +962,9 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, break; case GEN_CMD: { - struct cdp_vdev *vdev = NULL; struct wma_txrx_node *intr = wma->interfaces; - - vdev = wma_find_vdev_by_id(wma, privcmd->param_vdev_id); - if (!vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); - return; - } + wmi_vdev_custom_aggr_type_t aggr_type = + WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU; WMA_LOGD("gen pid %d pval %d", privcmd->param_id, privcmd->param_value); @@ -1078,8 +978,8 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, } if (privcmd->param_id == GEN_VDEV_PARAM_AMPDU) { - ret = cdp_aggr_cfg(soc, vdev, - privcmd->param_value, 0); + ret = cdp_aggr_cfg(soc, privcmd->param_vdev_id, + privcmd->param_value, 0); if (ret) WMA_LOGE("cdp_aggr_cfg set ampdu failed ret %d", ret); @@ -1087,18 +987,14 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, intr[privcmd->param_vdev_id].config. ampdu = privcmd->param_value; - aggr.aggr_type = + aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU; - } else { - aggr.aggr_type = - WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU; } - aggr.vdev_id = vid; - aggr.tx_aggregation_size = privcmd->param_value; - aggr.rx_aggregation_size = privcmd->param_value; - - ret = wma_set_tx_rx_aggregation_size(&aggr); + ret = wma_set_tx_rx_aggr_size(vid, + privcmd->param_value, + privcmd->param_value, + aggr_type); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("set_aggr_size failed ret %d", ret); return; @@ -1171,6 +1067,13 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, WMA_LOGE("dbglog_module_log_enable failed ret %d", ret); break; + case WMI_DBGLOG_MOD_WOW_LOG_LEVEL: + ret = dbglog_set_mod_wow_log_lvl(wma->wmi_handle, + privcmd->param_value); + if (ret) + wma_err("WMI_DBGLOG_MOD_WOW_LOG_LEVEL failed ret %d", + ret); + break; case WMI_DBGLOG_TYPE: ret = dbglog_parser_type_init(wma->wmi_handle, privcmd->param_value); @@ -1554,10 +1457,7 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, break; case WMI_PDEV_PARAM_TXPOWER_LIMIT2G: wma->pdevconfig.txpow2g = privcmd->param_value; - if ((mac->mlme_cfg->gen.band_capability == - BAND_ALL) || - (mac->mlme_cfg->gen.band_capability == - BAND_2G)) + if (mac->mlme_cfg->gen.band_capability & BIT(REG_BAND_2G)) mac->mlme_cfg->power.current_tx_power_level = (uint8_t)privcmd->param_value; else @@ -1565,10 +1465,7 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma, break; case WMI_PDEV_PARAM_TXPOWER_LIMIT5G: wma->pdevconfig.txpow5g = privcmd->param_value; - if ((mac->mlme_cfg->gen.band_capability == - BAND_ALL) || - (mac->mlme_cfg->gen.band_capability == - BAND_5G)) + if (mac->mlme_cfg->gen.band_capability & BIT(REG_BAND_5G)) mac->mlme_cfg->power.current_tx_power_level = (uint8_t)privcmd->param_value; else @@ -1597,61 +1494,11 @@ uint32_t wma_critical_events_in_flight(void) t_wma_handle *wma; wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) + if (!wma || !wma->wmi_handle) { + WMA_LOGE("Invalid wma or wmi handle"); return 0; - - return qdf_atomic_read(&wma->critical_events_in_flight); -} - -static bool wma_event_is_critical(uint32_t event_id) -{ - switch (event_id) { - case WMI_ROAM_SYNCH_EVENTID: - return true; - default: - return false; } -} - -/** - * wma_process_fw_event() - process any fw event - * @wma: wma handle - * @buf: fw event buffer - * - * This function process any fw event to serialize it through mc thread. - * - * Return: none - */ -static int wma_process_fw_event(tp_wma_handle wma, - wma_process_fw_event_params *buf) -{ - struct wmi_unified *wmi_handle = (struct wmi_unified *)buf->wmi_handle; - uint32_t event_id = WMI_GET_FIELD(qdf_nbuf_data(buf->evt_buf), - WMI_CMD_HDR, COMMANDID); - - wmi_process_fw_event(wmi_handle, buf->evt_buf); - - if (wma_event_is_critical(event_id)) - qdf_atomic_dec(&wma->critical_events_in_flight); - - return 0; -} - -/** - * wmi_process_fw_event_tasklet_ctx() - process in tasklet context - * @ctx: handle to wmi - * @ev: wmi event buffer - * - * Event process by below function will be in tasket context, - * need to use this method only for time sensitive functions. - * - * Return: none - */ -static int wma_process_fw_event_tasklet_ctx(void *ctx, void *ev) -{ - wmi_process_fw_event(ctx, ev); - - return 0; + return wmi_critical_events_in_flight(wma->wmi_handle); } /** @@ -1694,16 +1541,6 @@ static void wma_discard_fw_event(struct scheduler_msg *msg) if (!msg->bodyptr) return; - switch (msg->type) { - case WMA_PROCESS_FW_EVENT: - qdf_nbuf_free(((wma_process_fw_event_params *)msg->bodyptr) - ->evt_buf); - break; - case WMA_SET_LINK_STATE: - qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg); - break; - } - qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; msg->bodyval = 0; @@ -1757,101 +1594,6 @@ wma_vdev_nss_chain_params_send(uint8_t vdev_id, &vdev_user_cfg); } -/** - * wma_process_fw_event_handler() - common event handler to serialize - * event processing through mc_thread - * @ctx: wmi context - * @ev: event buffer - * @rx_ctx: rx execution context - * - * Return: 0 on success, errno on failure - */ -static int wma_process_fw_event_mc_thread_ctx(void *ctx, void *ev) -{ - wma_process_fw_event_params *params_buf; - struct scheduler_msg cds_msg = { 0 }; - tp_wma_handle wma; - uint32_t event_id; - - params_buf = qdf_mem_malloc(sizeof(wma_process_fw_event_params)); - if (!params_buf) { - qdf_nbuf_free(ev); - return -ENOMEM; - } - - params_buf->wmi_handle = (struct wmi_unified *)ctx; - params_buf->evt_buf = ev; - - wma = cds_get_context(QDF_MODULE_ID_WMA); - event_id = WMI_GET_FIELD(qdf_nbuf_data(params_buf->evt_buf), - WMI_CMD_HDR, COMMANDID); - if (wma && wma_event_is_critical(event_id)) - qdf_atomic_inc(&wma->critical_events_in_flight); - - cds_msg.type = WMA_PROCESS_FW_EVENT; - cds_msg.bodyptr = params_buf; - cds_msg.bodyval = 0; - cds_msg.flush_callback = wma_discard_fw_event; - - if (QDF_STATUS_SUCCESS != - scheduler_post_message(QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, - QDF_MODULE_ID_WMA, &cds_msg)) { - qdf_nbuf_free(ev); - qdf_mem_free(params_buf); - return -EFAULT; - } - return 0; - -} - -int wma_process_fw_event_handler(ol_scn_t scn_handle, void *evt_buf, - uint8_t rx_ctx) -{ - int err = 0; - struct wmi_unified *wmi_handle; - struct wlan_objmgr_psoc *psoc; - struct target_psoc_info *tgt_hdl; - bool is_wmi_ready = false; - - psoc = target_if_get_psoc_from_scn_hdl(scn_handle); - if (!psoc) { - WMA_LOGE("psoc is null"); - return err; - } - - wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); - if (!wmi_handle) { - WMA_LOGE("wmi_handle is null"); - return err; - } - - tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); - if (!tgt_hdl) { - WMA_LOGE("target_psoc_info is null"); - return err; - } - - is_wmi_ready = target_psoc_get_wmi_ready(tgt_hdl); - if (!is_wmi_ready) { - WMA_LOGD("fw event recvd before ready event processed"); - WMA_LOGD("therefore use worker thread"); - wmi_process_fw_event_worker_thread_ctx(wmi_handle, evt_buf); - return err; - } - - if (rx_ctx == WMA_RX_SERIALIZER_CTX) { - err = wma_process_fw_event_mc_thread_ctx(wmi_handle, evt_buf); - } else if (rx_ctx == WMA_RX_TASKLET_CTX) { - wma_process_fw_event_tasklet_ctx(wmi_handle, evt_buf); - } else { - WMA_LOGE("%s: invalid wmi event execution context", __func__); - qdf_nbuf_free(evt_buf); - } - - return err; -} - /** * wma_antenna_isolation_event_handler() - antenna isolation event handler * @handle: wma handle @@ -1943,38 +1685,6 @@ static uint8_t wma_init_max_no_of_peers(tp_wma_handle wma_handle, return max_no_of_peers; } -/** - * wma_cleanup_vdev_resp_queue() - cleanup vdev response queue - * @wma: wma handle - * - * Return: none - */ -static void wma_cleanup_vdev_resp_queue(tp_wma_handle wma) -{ - struct wma_target_req *req_msg = NULL; - qdf_list_node_t *node1 = NULL; - - qdf_spin_lock_bh(&wma->vdev_respq_lock); - if (!qdf_list_size(&wma->vdev_resp_queue)) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - WMA_LOGD(FL("request queue maybe empty")); - return; - } - - WMA_LOGD(FL("Cleaning up vdev resp queue")); - - /* peek front, and then cleanup it in wma_vdev_resp_timer */ - while (qdf_list_peek_front(&wma->vdev_resp_queue, &node1) == - QDF_STATUS_SUCCESS) { - req_msg = qdf_container_of(node1, struct wma_target_req, node); - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - qdf_mc_timer_stop(&req_msg->event_timeout); - wma_vdev_resp_timer(req_msg); - qdf_spin_lock_bh(&wma->vdev_respq_lock); - } - qdf_spin_unlock_bh(&wma->vdev_respq_lock); -} - /** * wma_cleanup_hold_req() - cleanup hold request queue * @wma: wma handle @@ -2016,17 +1726,36 @@ static void wma_cleanup_hold_req(tp_wma_handle wma) static QDF_STATUS wma_cleanup_vdev_resp_and_hold_req(struct scheduler_msg *msg) { + tp_wma_handle wma; + if (!msg || !msg->bodyptr) { WMA_LOGE(FL("msg or body pointer is NULL")); return QDF_STATUS_E_INVAL; } - wma_cleanup_vdev_resp_queue(msg->bodyptr); - wma_cleanup_hold_req(msg->bodyptr); + wma = msg->bodyptr; + target_if_flush_psoc_vdev_timers(wma->psoc); + wma_cleanup_hold_req(wma); return QDF_STATUS_SUCCESS; } +/** + * wma_cleanup_vdev_resp_and_hold_req_flush_cb() - flush cb for the msg to clean + * up vdev resp and hold req + * @msg :scheduler msg + * + * As passed msg->bodyptr is wma in this case this is dummy flush cb so that + * driver doesnt try to free msg->bodyptr when this msg is flushed. + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +wma_cleanup_vdev_resp_and_hold_req_flush_cb(struct scheduler_msg *msg) +{ + return QDF_STATUS_SUCCESS; +} + /** * wma_shutdown_notifier_cb - Shutdown notifer call back * @priv : WMA handle @@ -2048,8 +1777,9 @@ static void wma_shutdown_notifier_cb(void *priv) ucfg_pmo_psoc_wakeup_host_event_received(wma_handle->psoc); wmi_stop(wma_handle->wmi_handle); - msg.bodyptr = priv; + msg.bodyptr = wma_handle; msg.callback = wma_cleanup_vdev_resp_and_hold_req; + msg.flush_callback = wma_cleanup_vdev_resp_and_hold_req_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_WMA, QDF_MODULE_ID_WMA, QDF_MODULE_ID_TARGET_IF, &msg); @@ -2067,7 +1797,6 @@ struct wma_version_info g_wmi_version_info; * * Return: None */ -#ifdef QCA_SUPPORT_CP_STATS static void wma_state_info_dump(char **buf_ptr, uint16_t *size) { uint8_t vdev_id; @@ -2077,6 +1806,8 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) struct wma_txrx_node *iface; struct wake_lock_stats stats; struct wlan_objmgr_vdev *vdev; + uint32_t rate_flag; + QDF_STATUS status; wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { @@ -2088,7 +1819,12 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { iface = &wma->interfaces[vdev_id]; - if (!iface->handle) + vdev = iface->vdev; + if (!vdev) + continue; + + status = wma_get_vdev_rate_flag(iface->vdev, &rate_flag); + if (QDF_IS_STATUS_ERROR(status)) continue; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, @@ -2116,21 +1852,14 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) "\tipv6_mcast_na %u\n" "\toem_response %u\n" "dtimPeriod %d\n" - "chanmode %d\n" - "vht_capable %d\n" - "ht_capable %d\n" "chan_width %d\n" "vdev_active %d\n" "vdev_up %d\n" "aid %d\n" "rate_flags %d\n" "nss %d\n" - "tx_power %d\n" - "max_tx_power %d\n" "nwType %d\n" - "tx_streams %d\n" - "rx_streams %d\n" - "chain_mask %d", + "tx_streams %d", vdev_id, stats.pno_match_wake_up_count, stats.pno_complete_wake_up_count, @@ -2148,124 +1877,20 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size) stats.ipv6_mcast_na_stats, stats.oem_response_wake_up_count, iface->dtimPeriod, - iface->chanmode, - iface->vht_capable, - iface->ht_capable, iface->chan_width, iface->vdev_active, wma_is_vdev_up(vdev_id), iface->aid, - iface->rate_flags, + rate_flag, iface->nss, - iface->tx_power, - iface->max_tx_power, iface->nwType, - iface->tx_streams, - iface->rx_streams, - iface->chain_mask); + iface->tx_streams); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); } *size -= len; *buf_ptr += len; } -#else /* QCA_SUPPORT_CP_STATS */ -static void wma_state_info_dump(char **buf_ptr, uint16_t *size) -{ - t_wma_handle *wma; - struct sir_vdev_wow_stats *stats; - uint16_t len = 0; - char *buf = *buf_ptr; - struct wma_txrx_node *iface; - uint8_t vdev_id; - - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s: WMA context is invald!", __func__); - return; - } - - WMA_LOGE("%s: size of buffer: %d", __func__, *size); - - for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { - iface = &wma->interfaces[vdev_id]; - if (!iface->handle) - continue; - - stats = &iface->wow_stats; - len += qdf_scnprintf(buf + len, *size - len, - "\n" - "vdev_id %d\n" - "WoW Stats\n" - "\tpno_match %u\n" - "\tpno_complete %u\n" - "\tgscan %u\n" - "\tlow_rssi %u\n" - "\trssi_breach %u\n" - "\tucast %u\n" - "\tbcast %u\n" - "\ticmpv4 %u\n" - "\ticmpv6 %u\n" - "\tipv4_mcast %u\n" - "\tipv6_mcast %u\n" - "\tipv6_mcast_ra %u\n" - "\tipv6_mcast_ns %u\n" - "\tipv6_mcast_na %u\n" - "\toem_response %u\n" - "dtimPeriod %d\n" - "chanmode %d\n" - "vht_capable %d\n" - "ht_capable %d\n" - "chan_width %d\n" - "vdev_active %d\n" - "vdev_up %d\n" - "aid %d\n" - "rate_flags %d\n" - "nss %d\n" - "tx_power %d\n" - "max_tx_power %d\n" - "nwType %d\n" - "tx_streams %d\n" - "rx_streams %d\n" - "chain_mask %d", - vdev_id, - stats->pno_match, - stats->pno_complete, - stats->gscan, - stats->low_rssi, - stats->rssi_breach, - stats->ucast, - stats->bcast, - stats->icmpv4, - stats->icmpv6, - stats->ipv4_mcast, - stats->ipv6_mcast, - stats->ipv6_mcast_ra, - stats->ipv6_mcast_ns, - stats->ipv6_mcast_na, - stats->oem_response, - iface->dtimPeriod, - iface->chanmode, - iface->vht_capable, - iface->ht_capable, - iface->chan_width, - iface->vdev_active, - wma_is_vdev_up(vdev_id), - iface->aid, - iface->rate_flags, - iface->nss, - iface->tx_power, - iface->max_tx_power, - iface->nwType, - iface->tx_streams, - iface->rx_streams, - iface->chain_mask); - } - - *size -= len; - *buf_ptr += len; -} -#endif /* QCA_SUPPORT_CP_STATS */ /** * wma_register_debug_callback() - registration function for wma layer @@ -2339,43 +1964,6 @@ static void wma_target_if_open(tp_wma_handle wma_handle) } -/** - * wma_target_if_close() - Detach UMAC modules' interface with wmi layer - * @wma_handle: wma handle - * - * Return: None - */ -static void wma_target_if_close(tp_wma_handle wma_handle) -{ - struct wlan_objmgr_psoc *psoc = wma_handle->psoc; - - if (!psoc) - return; - - wlan_global_lmac_if_close(psoc); -} - -/** - * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle - * @scn_handle: opaque wma handle - * - * API to get pdev from scn handle - * - * Return: None - */ -static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle) -{ - tp_wma_handle wma_handle; - - if (!scn_handle) { - WMA_LOGE("invalid scn handle"); - return NULL; - } - wma_handle = (tp_wma_handle)scn_handle; - - return wma_handle->pdev; -} - /** * wma_legacy_service_ready_event_handler() - legacy (ext)service ready handler * @event_id: event_id @@ -2438,12 +2026,17 @@ static int wma_flush_complete_evt_handler(void *handle, reason_code = wmi_event->reserved0; WMA_LOGD("Received reason code %d from FW", reason_code); - buf_ptr = (uint8_t *)wmi_event; - buf_ptr = buf_ptr + sizeof(wmi_debug_mesg_flush_complete_fixed_param) + - WMI_TLV_HDR_SIZE; - data_stall_event = (wmi_debug_mesg_fw_data_stall_param *) buf_ptr; + if (reason_code == WMA_DATA_STALL_TRIGGER) { + buf_ptr = (uint8_t *)wmi_event; + buf_ptr = buf_ptr + + sizeof(wmi_debug_mesg_flush_complete_fixed_param) + + WMI_TLV_HDR_SIZE; + data_stall_event = + (wmi_debug_mesg_fw_data_stall_param *)buf_ptr; + } - if (((data_stall_event->tlv_header & 0xFFFF0000) >> 16 == + if (reason_code == WMA_DATA_STALL_TRIGGER && + ((data_stall_event->tlv_header & 0xFFFF0000) >> 16 == WMITLV_TAG_STRUC_wmi_debug_mesg_fw_data_stall_param)) { /** * Log data stall info received from FW: @@ -2485,10 +2078,9 @@ static int wma_flush_complete_evt_handler(void *handle, data_stall_event->recovery_type); cdp_post_data_stall_event(soc, - cds_get_context(QDF_MODULE_ID_TXRX), DATA_STALL_LOG_INDICATOR_FIRMWARE, data_stall_event->data_stall_type, - 0XFF, + OL_TXRX_PDEV_ID, data_stall_event->vdev_id_bitmap, data_stall_event->recovery_type); } @@ -2995,10 +2587,6 @@ static int wma_unified_phyerr_rx_event_handler(void *handle, void wma_vdev_init(struct wma_txrx_node *vdev) { - qdf_wake_lock_create(&vdev->vdev_start_wakelock, "vdev_start"); - qdf_runtime_lock_init(&vdev->vdev_start_runtime_wakelock); - qdf_wake_lock_create(&vdev->vdev_stop_wakelock, "vdev_stop"); - qdf_runtime_lock_init(&vdev->vdev_stop_runtime_wakelock); qdf_wake_lock_create(&vdev->vdev_set_key_wakelock, "vdev_set_key"); qdf_runtime_lock_init(&vdev->vdev_set_key_runtime_wakelock); vdev->is_waiting_for_key = false; @@ -3026,10 +2614,8 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev) vdev->beacon = NULL; } - if (vdev->handle) { - WMA_LOGE("%s: vdev->handle not NULL", __func__); - vdev->handle = NULL; - } + if (vdev->vdev_active == true) + vdev->vdev_active = false; if (vdev->addBssStaContext) { qdf_mem_free(vdev->addBssStaContext); @@ -3041,16 +2627,6 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev) vdev->staKeyParams = NULL; } - if (vdev->del_staself_req) { - qdf_mem_free(vdev->del_staself_req); - vdev->del_staself_req = NULL; - } - - if (vdev->stats_rsp) { - qdf_mem_free(vdev->stats_rsp); - vdev->stats_rsp = NULL; - } - if (vdev->psnr_req) { qdf_mem_free(vdev->psnr_req); vdev->psnr_req = NULL; @@ -3086,10 +2662,6 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev) qdf_runtime_lock_deinit(&vdev->vdev_set_key_runtime_wakelock); qdf_wake_lock_destroy(&vdev->vdev_set_key_wakelock); - qdf_runtime_lock_deinit(&vdev->vdev_stop_runtime_wakelock); - qdf_wake_lock_destroy(&vdev->vdev_stop_wakelock); - qdf_runtime_lock_deinit(&vdev->vdev_start_runtime_wakelock); - qdf_wake_lock_destroy(&vdev->vdev_start_wakelock); vdev->is_waiting_for_key = false; } @@ -3110,19 +2682,7 @@ void wma_wmi_stop(void) wmi_stop(wma_handle->wmi_handle); } -#ifdef QCA_SUPPORT_CP_STATS -static void wma_register_stats_events(wmi_unified_t wmi_handle) {} -#else -static void wma_register_stats_events(wmi_unified_t wmi_handle) -{ - wmi_unified_register_event_handler(wmi_handle, - wmi_update_stats_event_id, - wma_stats_event_handler, - WMA_RX_SERIALIZER_CTX); -} -#endif - -#ifdef CONFIG_WMI_BCN_OFFLOAD +#ifdef WLAN_WMI_BCN static QDF_STATUS wma_register_swba_events(wmi_unified_t wmi_handle) { @@ -3181,13 +2741,13 @@ static void wma_register_md_events(tp_wma_handle wma_handle) } wmi_unified_register_event_handler(wma_handle->wmi_handle, - WMI_MOTION_DET_HOST_EVENTID, + wmi_motion_det_host_eventid, wma_motion_det_host_event_handler, WMA_RX_SERIALIZER_CTX); wmi_unified_register_event_handler( wma_handle->wmi_handle, - WMI_MOTION_DET_BASE_LINE_HOST_EVENTID, + wmi_motion_det_base_line_host_eventid, wma_motion_det_base_line_host_event_handler, WMA_RX_SERIALIZER_CTX); } @@ -3229,19 +2789,40 @@ struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle) return wma_handle->psoc; } -void wma_get_phy_mode_cb(uint8_t chan, uint32_t chan_width, uint32_t *phy_mode) +void wma_get_fw_phy_mode_for_freq_cb(uint32_t freq, uint32_t chan_width, + uint32_t *phy_mode) { uint32_t dot11_mode; + enum wlan_phymode host_phy_mode; struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); if (!mac) { wma_err("MAC context is NULL"); - *phy_mode = MODE_UNKNOWN; + *phy_mode = WLAN_PHYMODE_AUTO; return; } dot11_mode = mac->mlme_cfg->dot11_mode.dot11_mode; - *phy_mode = wma_chan_phy_mode(chan, chan_width, dot11_mode); + host_phy_mode = wma_chan_phy_mode(freq, chan_width, dot11_mode); + *phy_mode = wma_host_to_fw_phymode(host_phy_mode); +} + +void wma_get_phy_mode_cb(uint8_t chan, uint32_t chan_width, + enum wlan_phymode *phy_mode) +{ + uint32_t dot11_mode; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + uint32_t freq; + + if (!mac) { + wma_err("MAC context is NULL"); + *phy_mode = WLAN_PHYMODE_AUTO; + return; + } + + freq = wlan_reg_chan_to_freq(mac->pdev, chan); + dot11_mode = mac->mlme_cfg->dot11_mode.dot11_mode; + *phy_mode = wma_chan_phy_mode(freq, chan_width, dot11_mode); } #ifdef WLAN_FEATURE_NAN @@ -3260,23 +2841,6 @@ static void wma_register_nan_callbacks(tp_wma_handle wma_handle) } #endif -#ifdef WLAN_FEATURE_PKT_CAPTURE -static void -wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle) -{ - struct pkt_capture_callbacks cb_obj = {0}; - - cb_obj.get_rmf_status = wma_get_rmf_status; - - ucfg_pkt_capture_register_wma_callbacks(wma_handle->psoc, &cb_obj); -} -#else -static inline void -wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle) -{ -} -#endif - /** * wma_open() - Allocate wma context and initialize it. * @cds_context: cds context @@ -3303,7 +2867,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, bool val = 0; void *cds_context; target_resource_config *wlan_res_cfg; - uint8_t delay_before_vdev_stop; uint32_t self_gen_frm_pwr = 0; WMA_LOGD("%s: Enter", __func__); @@ -3383,21 +2946,17 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, * Allocate locally used params with its rx_ops member, * and free it immediately after used. */ - params = qdf_mem_malloc(sizeof(*params) + sizeof(struct wmi_rx_ops)); + params = qdf_mem_malloc(sizeof(*params)); if (!params) { qdf_status = QDF_STATUS_E_NOMEM; goto err_wma_handle; } - params->rx_ops = (struct wmi_rx_ops *)(params + 1); params->osdev = NULL; params->target_type = WMI_TLV_TARGET; params->use_cookie = false; params->psoc = psoc; params->max_commands = WMI_MAX_CMDS; - /* Attach mc_thread context processing function */ - params->rx_ops->wma_process_fw_event_handler_cbk = - wma_process_fw_event_handler; /* initialize tlv attach */ wmi_tlv_init(); @@ -3482,13 +3041,9 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, goto err_scn_context; } - for (i = 0; i < wma_handle->max_bssid; ++i) { + for (i = 0; i < wma_handle->max_bssid; ++i) wma_vdev_init(&wma_handle->interfaces[i]); - ucfg_mlme_get_delay_before_vdev_stop(wma_handle->psoc, - &delay_before_vdev_stop); - wma_handle->interfaces[i].delay_before_vdev_stop = - delay_before_vdev_stop; - } + /* Register the debug print event handler */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_debug_print_event_id, @@ -3558,35 +3113,17 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, goto err_event_init; } - qdf_list_create(&wma_handle->vdev_resp_queue, - MAX_ENTRY_VDEV_RESP_QUEUE); - qdf_spinlock_create(&wma_handle->vdev_respq_lock); qdf_list_create(&wma_handle->wma_hold_req_queue, MAX_ENTRY_HOLD_REQ_QUEUE); qdf_spinlock_create(&wma_handle->wma_hold_req_q_lock); qdf_atomic_init(&wma_handle->is_wow_bus_suspended); - /* Register vdev start response event handler */ - wmi_unified_register_event_handler(wma_handle->wmi_handle, - wmi_vdev_start_resp_event_id, - wma_vdev_start_resp_handler, - WMA_RX_SERIALIZER_CTX); - - /* Register vdev stop response event handler */ - wmi_unified_register_event_handler(wma_handle->wmi_handle, - wmi_vdev_stopped_event_id, - wma_vdev_stop_resp_handler, - WMA_RX_SERIALIZER_CTX); - /* register for STA kickout function */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_sta_kickout_event_id, wma_peer_sta_kickout_event_handler, WMA_RX_SERIALIZER_CTX); - /* register for stats event */ - wma_register_stats_events(wma_handle->wmi_handle); - /* register for stats response event */ wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_get_arp_stats_req_id, @@ -3697,12 +3234,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_handle->staDynamicDtim = ucfg_pmo_get_sta_dynamic_dtim(wma_handle->psoc); - /* register for install key completion event */ - wmi_unified_register_event_handler(wma_handle->wmi_handle, - wmi_vdev_install_key_complete_event_id, - wma_vdev_install_key_complete_event_handler, - WMA_RX_SERIALIZER_CTX); - #ifdef WLAN_FEATURE_STATS_EXT /* register for extended stats event */ wmi_unified_register_event_handler(wma_handle->wmi_handle, @@ -3736,10 +3267,15 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_roam_stats_event_handler, WMA_RX_SERIALIZER_CTX); - wmi_unified_register_event_handler( - wma_handle->wmi_handle, wmi_roam_scan_chan_list_id, - wma_roam_scan_chan_list_event_handler, - WMA_RX_SERIALIZER_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_roam_scan_chan_list_id, + wma_roam_scan_chan_list_event_handler, + WMA_RX_SERIALIZER_CTX); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_roam_blacklist_event_id, + wma_handle_btm_blacklist_event, + WMA_RX_SERIALIZER_CTX); wma_register_pmkid_req_event_handler(wma_handle); #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ @@ -3758,10 +3294,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wmi_peer_assoc_conf_event_id, wma_peer_assoc_conf_handler, WMA_RX_SERIALIZER_CTX); - wmi_unified_register_event_handler(wma_handle->wmi_handle, - wmi_vdev_delete_resp_event_id, - wma_vdev_delete_handler, - WMA_RX_SERIALIZER_CTX); wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_delete_response_event_id, wma_peer_delete_handler, @@ -3802,18 +3334,23 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_pdev_div_info_evt_handler, WMA_RX_WORK_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_get_ani_level_event_id, + wma_get_ani_level_evt_handler, + WMA_RX_WORK_CTX); wma_register_debug_callback(); wifi_pos_register_get_phy_mode_cb(wma_handle->psoc, wma_get_phy_mode_cb); + wifi_pos_register_get_fw_phy_mode_for_freq_cb( + wma_handle->psoc, + wma_get_fw_phy_mode_for_freq_cb); /* Register callback with PMO so PMO can update the vdev pause bitmap*/ pmo_register_pause_bitmap_notifier(wma_handle->psoc, wma_vdev_update_pause_bitmap); pmo_register_get_pause_bitmap(wma_handle->psoc, wma_vdev_get_pause_bitmap); - pmo_register_get_vdev_dp_handle(wma_handle->psoc, - wma_vdev_get_vdev_dp_handle); pmo_register_is_device_in_low_pwr_mode(wma_handle->psoc, wma_vdev_is_device_in_low_pwr_mode); pmo_register_get_dtim_period_callback(wma_handle->psoc, @@ -3822,7 +3359,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_vdev_get_beacon_interval); wma_cbacks.wma_get_connection_info = wma_get_connection_info; wma_register_nan_callbacks(wma_handle); - wma_register_pkt_capture_callbacks(wma_handle); qdf_status = policy_mgr_register_wma_cb(wma_handle->psoc, &wma_cbacks); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { WMA_LOGE("Failed to register wma cb with Policy Manager"); @@ -3864,7 +3400,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock); qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); - qdf_spinlock_destroy(&wma_handle->vdev_respq_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); err_event_init: wmi_unified_unregister_event_handler(wma_handle->wmi_handle, @@ -3970,6 +3505,7 @@ void wma_send_msg_by_priority(tp_wma_handle wma_handle, uint16_t msg_type, if (!QDF_IS_STATUS_SUCCESS(status)) { if (body_ptr) qdf_mem_free(body_ptr); + wma_err("Failed to send msg"); } } @@ -4004,8 +3540,8 @@ static int wma_set_base_macaddr_indicate(tp_wma_handle wma_handle, (uint8_t *)customAddr); if (err) return -EIO; - wma_debug("Base MAC Addr: " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY((*customAddr))); + wma_debug("Base MAC Addr: " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF((*customAddr))); return 0; } @@ -4115,7 +3651,7 @@ static int wma_pdev_set_hw_mode_resp_evt_handler(void *handle, vdev_id = vdev_mac_entry[i].vdev_id; pdev_id = vdev_mac_entry[i].pdev_id; - if (pdev_id == WMI_PDEV_ID_SOC) { + if (pdev_id == OL_TXRX_PDEV_ID) { WMA_LOGE("%s: soc level id received for mac id)", __func__); goto fail; @@ -4216,7 +3752,7 @@ void wma_process_pdev_hw_mode_trans_ind(void *handle, vdev_id = vdev_mac_entry[i].vdev_id; pdev_id = vdev_mac_entry[i].pdev_id; - if (pdev_id == WMI_PDEV_ID_SOC) { + if (pdev_id == OL_TXRX_PDEV_ID) { WMA_LOGE("%s: soc level id received for mac id)", __func__); return; @@ -4716,6 +4252,7 @@ QDF_STATUS wma_stop(void) QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; int i; struct mac_context *mac = NULL; + struct wlan_objmgr_vdev *vdev; wma_handle = cds_get_context(QDF_MODULE_ID_WMA); WMA_LOGD("%s: Enter", __func__); @@ -4753,13 +4290,13 @@ QDF_STATUS wma_stop(void) WMA_LOGE("Failed to destroy the log completion timer"); /* clean up ll-queue for all vdev */ for (i = 0; i < wma_handle->max_bssid; i++) { - if (wma_handle->interfaces[i].handle && - wma_is_vdev_up(i)) { - cdp_fc_vdev_flush( - cds_get_context(QDF_MODULE_ID_SOC), - wma_handle-> - interfaces[i].handle); - } + vdev = wma_handle->interfaces[i].vdev; + if (!vdev) + continue; + + if (wma_is_vdev_up(i)) + cdp_fc_vdev_flush(cds_get_context(QDF_MODULE_ID_SOC), + i); } if (!mac->mlme_cfg->gen.enable_remove_time_stamp_sync_cmd && @@ -4791,7 +4328,7 @@ QDF_STATUS wma_wmi_service_close(void) { void *cds_ctx; tp_wma_handle wma_handle; - int i; + uint8_t i; WMA_LOGD("%s: Enter", __func__); @@ -4936,12 +4473,10 @@ QDF_STATUS wma_close(void) qdf_event_destroy(&wma_handle->recovery_event); qdf_event_destroy(&wma_handle->tx_frm_download_comp_event); qdf_event_destroy(&wma_handle->tx_queue_empty_event); - wma_cleanup_vdev_resp_queue(wma_handle); wma_cleanup_hold_req(wma_handle); qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock); qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); - qdf_spinlock_destroy(&wma_handle->vdev_respq_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); if (wma_handle->pGetRssiReq) { @@ -4962,7 +4497,6 @@ QDF_STATUS wma_close(void) pmo_unregister_is_device_in_low_pwr_mode(wma_handle->psoc); pmo_unregister_get_pause_bitmap(wma_handle->psoc); pmo_unregister_pause_bitmap_notifier(wma_handle->psoc); - pmo_unregister_get_vdev_dp_handle(wma_handle->psoc); tgt_psoc_info = wlan_psoc_get_tgt_if_handle(wma_handle->psoc); init_deinit_free_num_units(wma_handle->psoc, tgt_psoc_info); @@ -4970,7 +4504,6 @@ QDF_STATUS wma_close(void) wlan_objmgr_psoc_release_ref(wma_handle->psoc, WLAN_LEGACY_WMA_ID); wma_handle->psoc = NULL; - wma_target_if_close(wma_handle); WMA_LOGD("%s: Exit", __func__); return QDF_STATUS_SUCCESS; @@ -5375,6 +4908,12 @@ static void wma_update_target_ext_ht_cap(struct target_psoc_info *tgt_hdl, total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl); mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return; + } + /* * for legacy device extended cap might not even come, so in that case * don't overwrite legacy values @@ -5542,7 +5081,12 @@ static void wma_update_target_ext_vht_cap(struct target_psoc_info *tgt_hdl, total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl); + mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return; + } /* * for legacy device extended cap might not even come, so in that case @@ -5601,28 +5145,37 @@ wma_update_sar_version(struct wlan_psoc_host_service_ext_param *param, * wma_update_hdd_band_cap() - update band cap which hdd understands * @supported_band: supported band which has been given by FW * @tgt_cfg: target configuration to be updated + * @psoc: psoc ptr * * Convert WMA given supported band to enum which HDD understands * * Return: None */ static void wma_update_hdd_band_cap(WMI_PHY_CAPABILITY supported_band, - struct wma_tgt_cfg *tgt_cfg) + struct wma_tgt_cfg *tgt_cfg, + struct wlan_objmgr_psoc *psoc) { switch (supported_band) { case WMI_11G_CAPABILITY: case WMI_11NG_CAPABILITY: - tgt_cfg->band_cap = BAND_2G; + tgt_cfg->band_cap = BIT(REG_BAND_2G); break; case WMI_11A_CAPABILITY: case WMI_11NA_CAPABILITY: case WMI_11AC_CAPABILITY: - tgt_cfg->band_cap = BAND_5G; + tgt_cfg->band_cap = BIT(REG_BAND_5G); break; case WMI_11AG_CAPABILITY: case WMI_11NAG_CAPABILITY: + case WMI_11AX_CAPABILITY: + tgt_cfg->band_cap = (BIT(REG_BAND_2G) | BIT(REG_BAND_5G)); + if (wlan_reg_is_6ghz_supported(psoc)) + tgt_cfg->band_cap |= BIT(REG_BAND_6G); + break; default: - tgt_cfg->band_cap = BAND_ALL; + tgt_cfg->band_cap = (BIT(REG_BAND_2G) | + BIT(REG_BAND_5G) | + BIT(REG_BAND_6G)); } } @@ -5683,6 +5236,25 @@ static void wma_update_obss_color_collision_support(tp_wma_handle wh, tgt_cfg->obss_color_collision_offloaded = false; } +/** + * wma_update_restricted_80p80_bw_support() - update restricted 80+80 supprot + * @wh: wma handle + * @tgt_cfg: target configuration to be updated + * + * Update restricted 80+80MHz (165MHz) BW support based on service bit. + * + * Return: None + */ +static void wma_update_restricted_80p80_bw_support(tp_wma_handle wh, + struct wma_tgt_cfg *tgt_cfg) +{ + if (wmi_service_enabled(wh->wmi_handle, + wmi_service_bw_165mhz_support)) + tgt_cfg->restricted_80p80_bw_supp = true; + else + tgt_cfg->restricted_80p80_bw_supp = false; +} + #ifdef WLAN_SUPPORT_GREEN_AP static void wma_green_ap_register_handlers(tp_wma_handle wma_handle) { @@ -5724,6 +5296,10 @@ static void wma_update_nan_target_caps(tp_wma_handle wma_handle, if (wmi_service_enabled(wma_handle->wmi_handle, wmi_service_nan_vdev)) tgt_cfg->nan_caps.nan_vdev_allowed = 1; + + if (wmi_service_enabled(wma_handle->wmi_handle, + wmi_service_sta_nan_ndi_four_port)) + tgt_cfg->nan_caps.sta_nan_ndi_ndi_allowed = 1; } #else static void wma_update_nan_target_caps(tp_wma_handle wma_handle, @@ -5818,10 +5394,15 @@ wma_is_dbs_mandatory(struct wlan_objmgr_psoc *psoc, total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return false; + } + for (i = 0; i < total_mac_phy_cnt; i++) { mac_cap = &mac_phy_cap[i]; - if (mac_cap->phy_id == 0) + if (mac_cap && (mac_cap->phy_id == 0)) supported_band |= mac_cap->supported_bands; } @@ -5922,7 +5503,7 @@ static int wma_update_hdd_cfg(tp_wma_handle wma_handle) tgt_cfg.dfs_cac_offload = wma_handle->is_dfs_offloaded; tgt_cfg.rcpi_enabled = wma_handle->rcpi_enabled; wma_update_hdd_band_cap(target_if_get_phy_capability(tgt_hdl), - &tgt_cfg); + &tgt_cfg, wma_handle->psoc); wma_update_sar_version(service_ext_param, &tgt_cfg); tgt_cfg.fine_time_measurement_cap = target_if_get_wmi_fw_sub_feat_caps(tgt_hdl); @@ -5936,7 +5517,7 @@ static int wma_update_hdd_cfg(tp_wma_handle wma_handle) wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg); wma_update_nan_target_caps(wma_handle, &tgt_cfg); wma_update_bcast_twt_support(wma_handle, &tgt_cfg); - + wma_update_restricted_80p80_bw_support(wma_handle, &tgt_cfg); /* Take the max of chains supported by FW, which will limit nss */ for (i = 0; i < tgt_hdl->info.total_mac_phy_cnt; i++) wma_fill_chain_cfg(tgt_hdl, i); @@ -5944,9 +5525,7 @@ static int wma_update_hdd_cfg(tp_wma_handle wma_handle) ret = wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg); if (ret) return -EINVAL; - target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle); - target_pdev_set_wmi_handle(wma_handle->pdev->tgt_if_handle, - wma_handle->wmi_handle); + wma_green_ap_register_handlers(wma_handle); return ret; @@ -6098,10 +5677,6 @@ static void wma_set_mlme_caps(struct wlan_objmgr_psoc *psoc) if (tgt_cap) akm_bitmap |= (1 << AKM_SAE); - tgt_cap = wmi_service_enabled(wma->wmi_handle, - wmi_service_suiteb_roam_support); - if (tgt_cap) - akm_bitmap |= (1 << AKM_SUITEB); status = mlme_set_tgt_wpa3_roam_cap(psoc, akm_bitmap); if (QDF_IS_STATUS_ERROR(status)) @@ -6398,7 +5973,8 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, goto free_hw_mode_list; } - cdp_mark_first_wakeup_packet(soc, + cdp_mark_first_wakeup_packet( + soc, OL_TXRX_PDEV_ID, wmi_service_enabled(wmi_handle, wmi_service_mark_first_wakeup_packet)); wma_handle->is_dfs_offloaded = @@ -6450,56 +6026,6 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, } -/** - * wma_get_phyid_for_given_band() - to get phyid for band - * - * @wma_handle: Pointer to wma handle -* @tgt_hdl: target psoc information - * @band: enum value of for 2G or 5G band - * @phyid: Pointer to phyid which needs to be filled - * - * This API looks in to the map to find out which particular phy supports - * provided band and return the idx (also called phyid) of that phy. Caller - * use this phyid to fetch various caps of that phy - * - * Return: QDF_STATUS - */ -static QDF_STATUS wma_get_phyid_for_given_band( - tp_wma_handle wma_handle, - struct target_psoc_info *tgt_hdl, - enum cds_band_type band, uint8_t *phyid) -{ - uint8_t idx, i, total_mac_phy_cnt; - struct wlan_psoc_host_mac_phy_caps *mac_phy_cap; - - if (!wma_handle) { - WMA_LOGE("Invalid wma handle"); - return QDF_STATUS_E_FAILURE; - } - - idx = 0; - *phyid = idx; - total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); - mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); - - for (i = 0; i < total_mac_phy_cnt; i++) { - if ((band == CDS_BAND_2GHZ) && - (WLAN_2G_CAPABILITY == mac_phy_cap[idx + i].supported_bands)) { - *phyid = idx + i; - WMA_LOGD("Select 2G capable phyid[%d]", *phyid); - return QDF_STATUS_SUCCESS; - } else if ((band == CDS_BAND_5GHZ) && - (WLAN_5G_CAPABILITY == mac_phy_cap[idx + i].supported_bands)) { - *phyid = idx + i; - WMA_LOGD("Select 5G capable phyid[%d]", *phyid); - return QDF_STATUS_SUCCESS; - } - } - WMA_LOGD("Using default single hw mode phyid[%d] total_mac_phy_cnt %d", - *phyid, total_mac_phy_cnt); - return QDF_STATUS_SUCCESS; -} - /** * wma_get_caps_for_phyidx_hwmode() - to fetch caps for given hw mode and band * @caps_per_phy: Pointer to capabilities structure which needs to be filled @@ -6518,8 +6044,10 @@ QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy, t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA); struct target_psoc_info *tgt_hdl; int ht_cap_info, vht_cap_info; - uint8_t phyid, our_hw_mode = hw_mode, num_hw_modes; + uint8_t our_hw_mode = hw_mode, num_hw_modes; struct wlan_psoc_host_mac_phy_caps *mac_phy_cap; + struct wlan_psoc_target_capability_info *tgt_cap_info; + uint8_t total_mac_phy_cnt, i; if (!wma_handle) { WMA_LOGE("Invalid wma handle"); @@ -6531,11 +6059,26 @@ QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy, WMA_LOGE("%s: target psoc info is NULL", __func__); return -EINVAL; } + if (!caps_per_phy) { + WMA_LOGE("Invalid caps pointer"); + return QDF_STATUS_E_FAILURE; + } ht_cap_info = target_if_get_ht_cap_info(tgt_hdl); vht_cap_info = target_if_get_vht_cap_info(tgt_hdl); num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl); mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + tgt_cap_info = target_psoc_get_target_caps(tgt_hdl); + + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return QDF_STATUS_E_FAILURE; + } + + if (!tgt_cap_info) { + WMA_LOGE("Invalid target capabilities handle"); + return QDF_STATUS_E_FAILURE; + } if (!num_hw_modes) { WMA_LOGD("Invalid number of hw modes, use legacy HT/VHT caps"); @@ -6548,6 +6091,14 @@ QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy, caps_per_phy->he_2g[1] = 0; caps_per_phy->he_5g[0] = 0; caps_per_phy->he_5g[1] = 0; + caps_per_phy->tx_chain_mask_2G = + EXTRACT_TX_CHAIN_MASK_2G(tgt_cap_info->txrx_chainmask); + caps_per_phy->rx_chain_mask_2G = + EXTRACT_RX_CHAIN_MASK_2G(tgt_cap_info->txrx_chainmask); + caps_per_phy->tx_chain_mask_5G = + EXTRACT_TX_CHAIN_MASK_5G(tgt_cap_info->txrx_chainmask); + caps_per_phy->rx_chain_mask_5G = + EXTRACT_RX_CHAIN_MASK_5G(tgt_cap_info->txrx_chainmask); return QDF_STATUS_SUCCESS; } @@ -6555,43 +6106,68 @@ QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy, if (!policy_mgr_is_dbs_enable(wma_handle->psoc)) our_hw_mode = HW_MODE_DBS_NONE; - if (!caps_per_phy) { - WMA_LOGE("Invalid caps pointer"); - return QDF_STATUS_E_FAILURE; - } + total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl); + for (i = 0; i < total_mac_phy_cnt; i++) { + if (our_hw_mode == HW_MODE_DBS && + mac_phy_cap[i].hw_mode_config_type != WMI_HW_MODE_DBS) + continue; - if (QDF_STATUS_SUCCESS != - wma_get_phyid_for_given_band(wma_handle, tgt_hdl, band, &phyid)) { - WMA_LOGE("Invalid phyid"); - return QDF_STATUS_E_FAILURE; + if ((band == CDS_BAND_2GHZ || band == CDS_BAND_ALL) && + (WLAN_2G_CAPABILITY & mac_phy_cap[i].supported_bands) && + !caps_per_phy->tx_chain_mask_2G) { + caps_per_phy->ht_2g = mac_phy_cap[i].ht_cap_info_2G; + caps_per_phy->vht_2g = mac_phy_cap[i].vht_cap_info_2G; + qdf_mem_copy(caps_per_phy->he_2g, + mac_phy_cap[i].he_cap_info_2G, + sizeof(caps_per_phy->he_2g)); + + caps_per_phy->tx_chain_mask_2G = + mac_phy_cap[i].tx_chain_mask_2G; + caps_per_phy->rx_chain_mask_2G = + mac_phy_cap[i].rx_chain_mask_2G; + + WMA_LOGD("Select 2G capable phyid[%d] chain %d %d ht 0x%x vht 0x%x", + i, + caps_per_phy->tx_chain_mask_2G, + caps_per_phy->rx_chain_mask_2G, + caps_per_phy->ht_2g, + caps_per_phy->vht_2g); + } + if ((band == CDS_BAND_5GHZ || band == CDS_BAND_ALL) && + (WLAN_5G_CAPABILITY & mac_phy_cap[i].supported_bands) && + !caps_per_phy->tx_chain_mask_5G) { + caps_per_phy->ht_5g = mac_phy_cap[i].ht_cap_info_5G; + caps_per_phy->vht_5g = mac_phy_cap[i].vht_cap_info_5G; + qdf_mem_copy(caps_per_phy->he_5g, + mac_phy_cap[i].he_cap_info_5G, + sizeof(caps_per_phy->he_5g)); + + caps_per_phy->tx_chain_mask_5G = + mac_phy_cap[i].tx_chain_mask_5G; + caps_per_phy->rx_chain_mask_5G = + mac_phy_cap[i].rx_chain_mask_5G; + + WMA_LOGD("Select 5G capable phyid[%d] chain %d %d ht 0x%x vht 0x%x", + i, + caps_per_phy->tx_chain_mask_5G, + caps_per_phy->rx_chain_mask_5G, + caps_per_phy->ht_5g, + caps_per_phy->vht_5g); + } } - caps_per_phy->ht_2g = mac_phy_cap[phyid].ht_cap_info_2G; - caps_per_phy->ht_5g = mac_phy_cap[phyid].ht_cap_info_5G; - caps_per_phy->vht_2g = mac_phy_cap[phyid].vht_cap_info_2G; - caps_per_phy->vht_5g = mac_phy_cap[phyid].vht_cap_info_5G; - qdf_mem_copy(caps_per_phy->he_2g, mac_phy_cap[phyid].he_cap_info_2G, - sizeof(caps_per_phy->he_2g)); - qdf_mem_copy(caps_per_phy->he_5g, mac_phy_cap[phyid].he_cap_info_5G, - sizeof(caps_per_phy->he_5g)); - - caps_per_phy->tx_chain_mask_2G = mac_phy_cap->tx_chain_mask_2G; - caps_per_phy->rx_chain_mask_2G = mac_phy_cap->rx_chain_mask_2G; - caps_per_phy->tx_chain_mask_5G = mac_phy_cap->tx_chain_mask_5G; - caps_per_phy->rx_chain_mask_5G = mac_phy_cap->rx_chain_mask_5G; - return QDF_STATUS_SUCCESS; } /** * wma_is_rx_ldpc_supported_for_channel() - to find out if ldpc is supported * - * @channel: Channel number for which it needs to check if rx ldpc is enabled + * @ch_freq: Channel freq for which it needs to check if rx ldpc is enabled * * This API takes channel number as argument and takes default hw mode as DBS * to check if rx LDPC support is enabled for that channel or no */ -bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel) +bool wma_is_rx_ldpc_supported_for_channel(uint32_t ch_freq) { t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA); struct target_psoc_info *tgt_hdl; @@ -6613,7 +6189,7 @@ bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel) num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl); - if (!WLAN_REG_IS_24GHZ_CH(channel)) + if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) band = CDS_BAND_5GHZ; else band = CDS_BAND_2GHZ; @@ -6632,7 +6208,7 @@ bool wma_is_rx_ldpc_supported_for_channel(uint32_t channel) if (0 == num_hw_modes) { status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_LDPC)); } else { - if (WLAN_REG_IS_24GHZ_CH(channel)) + if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_RX_LDPC)); else status = (!!(caps_per_phy.ht_5g & WMI_HT_CAP_RX_LDPC)); @@ -6726,15 +6302,23 @@ static void wma_print_populate_soc_caps(struct target_psoc_info *tgt_hdl) /* print number of hw modes */ WMA_LOGD("%s: num of hw modes [%d]", __func__, num_hw_modes); WMA_LOGD("%s: num mac_phy_cnt [%d]", __func__, total_mac_phy_cnt); + mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return; + } + WMA_LOGD("%s: <====== HW mode cap printing starts ======>", __func__); /* print cap of each hw mode */ for (i = 0; i < total_mac_phy_cnt; i++) { - WMA_LOGD("====>: hw mode id[%d], phy id[%d]", - mac_phy_cap[i].hw_mode_id, - mac_phy_cap[i].phy_id); - tmp = &mac_phy_cap[i]; - wma_print_mac_phy_capabilities(tmp, i); + if (&mac_phy_cap[i]) { + WMA_LOGD("====>: hw mode id[%d], phy id[%d]", + mac_phy_cap[i].hw_mode_id, + mac_phy_cap[i].phy_id); + tmp = &mac_phy_cap[i]; + wma_print_mac_phy_capabilities(tmp, i); + } } WMA_LOGD("%s: <====== HW mode cap printing ends ======>\n", __func__); } @@ -6884,6 +6468,12 @@ static QDF_STATUS wma_update_hw_mode_list(t_wma_handle *wma_handle, num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl); mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); tgt_cap_info = target_psoc_get_target_caps(tgt_hdl); + + if (!mac_phy_cap) { + WMA_LOGE("mac_phy_cap Null"); + return QDF_STATUS_E_FAILURE; + } + /* * This list was updated as part of service ready event. Re-populate * HW mode list from the device capabilities. @@ -6964,7 +6554,7 @@ static QDF_STATUS wma_update_hw_mode_list(t_wma_handle *wma_handle, static void wma_init_wifi_pos_dma_rings(t_wma_handle *wma_handle, uint8_t num_mac, void *buf) { - struct hif_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + struct hif_opaque_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); void *hal_soc; if (!hif_ctx) { @@ -7033,6 +6623,34 @@ static inline void wma_init_dbr_params(t_wma_handle *wma_handle) } #endif +/** + * wma_set_coex_res_cfg() - Set target COEX resource configuration. + * @wma_handle: pointer to wma global structure + * @wlan_res_cfg: Pointer to target resource configuration + * + * Return: none + */ +#ifdef FEATURE_COEX_CONFIG +static void wma_set_coex_res_cfg(t_wma_handle *wma_handle, + struct wmi_unified *wmi_handle, + target_resource_config *wlan_res_cfg) +{ + if (cfg_get(wma_handle->psoc, CFG_THREE_WAY_COEX_CONFIG_LEGACY) && + wmi_service_enabled(wmi_handle, + wmi_service_three_way_coex_config_legacy)) { + wlan_res_cfg->three_way_coex_config_legacy_en = true; + } else { + wlan_res_cfg->three_way_coex_config_legacy_en = false; + } +} +#else +static void wma_set_coex_res_cfg(t_wma_handle *wma_handle, + struct wmi_unified *wmi_handle, + target_resource_config *wlan_res_cfg) +{ +} +#endif + /** * wma_rx_service_ready_ext_event() - evt handler for sevice ready ext event. * @handle: wma handle @@ -7160,24 +6778,20 @@ int wma_rx_service_ready_ext_event(void *handle, uint8_t *event, * indicate 3 vdevs and firmware shall add 1 vdev for NAN. So decrement * the num_vdevs by 1. */ - if (ucfg_nan_is_vdev_creation_allowed(wma_handle->psoc)) { + if (ucfg_nan_is_vdev_creation_allowed(wma_handle->psoc) || + QDF_GLOBAL_FTM_MODE == cds_get_conparam()) { wlan_res_cfg->nan_separate_iface_support = true; } else { wlan_res_cfg->num_vdevs--; wma_update_num_peers_tids(wma_handle, wlan_res_cfg); } - if (ucfg_pkt_capture_get_mode(wma_handle->psoc) && - wmi_service_enabled(wmi_handle, - wmi_service_packet_capture_support)) - wlan_res_cfg->pktcapture_support = true; - else - wlan_res_cfg->pktcapture_support = false; - WMA_LOGD("%s: num_vdevs: %u", __func__, wlan_res_cfg->num_vdevs); wma_init_dbr_params(wma_handle); + wma_set_coex_res_cfg(wma_handle, wmi_handle, wlan_res_cfg); + return 0; } @@ -7302,8 +6916,6 @@ QDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle) WMA_READY_EVENTID_TIMEOUT); if (!tgt_hdl->info.wmi_ready) { wma_err("Error in pdev creation"); - if (!cds_is_driver_recovering() || !cds_is_fw_down()) - QDF_DEBUG_PANIC("FW ready event timed out"); return QDF_STATUS_E_INVAL; } @@ -7603,7 +7215,8 @@ static void wma_set_wifi_start_packet_stats(void *wma_handle, log_state = ATH_PKTLOG_ANI | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_RCFIND | ATH_PKTLOG_RX | ATH_PKTLOG_TX | ATH_PKTLOG_TEXT | ATH_PKTLOG_SW_EVENT; -#elif defined(QCA_WIFI_QCA6390) +#elif defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ + defined(QCA_WIFI_QCA6750) log_state = ATH_PKTLOG_RCFIND | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_TX | ATH_PKTLOG_LITE_T2H | ATH_PKTLOG_SW_EVENT | ATH_PKTLOG_RX; @@ -8443,7 +8056,7 @@ int wma_motion_det_host_event_handler(void *handle, uint8_t *event, motion_det_event_hdr->vdev_id, motion_det_event_hdr->status); md_event = qdf_mem_malloc(sizeof(*md_event)); - if (!event) + if (!md_event) return -ENOMEM; md_event->vdev_id = motion_det_event_hdr->vdev_id; @@ -8469,20 +8082,43 @@ int wma_motion_det_base_line_host_event_handler(void *handle, wmi_motion_det_base_line_event *motion_det_base_line_event_hdr; WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *param_buf = (WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *)event; + struct sir_md_bl_evt *md_bl_event; + struct mac_context *pmac = (struct mac_context *)cds_get_context( + QDF_MODULE_ID_PE); if (!param_buf) { - WMA_LOGE("Invalid motion det base line event buffer"); + WMA_LOGE("Invalid motion detection base line event buffer"); + return -EINVAL; + } + + if (!pmac || !pmac->sme.md_bl_evt_cb) { + WMA_LOGE("Invalid motion detection base line callback"); return -EINVAL; } motion_det_base_line_event_hdr = param_buf->fixed_param; - WMA_LOGA("motion host detect base line event received, vdev_id=%d", + WMA_LOGA("motion detection base line event received, vdev_id=%d", motion_det_base_line_event_hdr->vdev_id); WMA_LOGA("baseline_value=%d bl_max_corr_resv=%d bl_min_corr_resv=%d", motion_det_base_line_event_hdr->bl_baseline_value, motion_det_base_line_event_hdr->bl_max_corr_reserved, motion_det_base_line_event_hdr->bl_min_corr_reserved); + md_bl_event = qdf_mem_malloc(sizeof(*md_bl_event)); + if (!md_bl_event) + return -ENOMEM; + + md_bl_event->vdev_id = motion_det_base_line_event_hdr->vdev_id; + md_bl_event->bl_baseline_value = + motion_det_base_line_event_hdr->bl_baseline_value; + md_bl_event->bl_max_corr_reserved = + motion_det_base_line_event_hdr->bl_max_corr_reserved; + md_bl_event->bl_min_corr_reserved = + motion_det_base_line_event_hdr->bl_min_corr_reserved; + + pmac->sme.md_bl_evt_cb(pmac->sme.md_ctx, md_bl_event); + + qdf_mem_free(md_bl_event); return 0; } @@ -8716,10 +8352,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) { QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; tp_wma_handle wma_handle; - struct cdp_vdev *txrx_vdev_handle = NULL; - - extern uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg); - void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!msg) { WMA_LOGE("msg is NULL"); @@ -8742,61 +8374,17 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) } switch (msg->type) { - - /* Message posted by wmi for all control path related - * FW events to serialize through mc_thread. - */ - case WMA_PROCESS_FW_EVENT: - wma_process_fw_event(wma_handle, - (wma_process_fw_event_params *) msg->bodyptr); - qdf_mem_free(msg->bodyptr); - break; - #ifdef FEATURE_WLAN_ESE case WMA_TSM_STATS_REQ: WMA_LOGD("McThread: WMA_TSM_STATS_REQ"); wma_process_tsm_stats_req(wma_handle, (void *)msg->bodyptr); break; #endif /* FEATURE_WLAN_ESE */ - case WMA_ADD_STA_SELF_REQ: - txrx_vdev_handle = - wma_vdev_attach(wma_handle, - (struct add_sta_self_params *) msg-> - bodyptr, 1); - if (!txrx_vdev_handle) { - WMA_LOGE("Failed to attach vdev"); - } else { - /* Register with TxRx Module for Data Ack Complete Cb */ - if (soc) { - cdp_data_tx_cb_set(soc, txrx_vdev_handle, - wma_data_tx_ack_comp_hdlr, - wma_handle); - } else { - WMA_LOGE("%s: SOC context is NULL", __func__); - qdf_status = QDF_STATUS_E_FAILURE; - goto end; - } - } - break; - case WMA_DEL_STA_SELF_REQ: - wma_vdev_detach(wma_handle, - (struct del_sta_self_params *) msg->bodyptr, 1); - break; case WMA_UPDATE_CHAN_LIST_REQ: wma_update_channel_list(wma_handle, (tSirUpdateChanList *) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case WMA_SET_LINK_STATE: - wma_set_linkstate(wma_handle, (tpLinkStateParams) msg->bodyptr); - break; - case WMA_CHNL_SWITCH_REQ: - wma_set_channel(wma_handle, - (tpSwitchChannelParams) msg->bodyptr); - break; - case WMA_ADD_BSS_REQ: - wma_add_bss(wma_handle, (tpAddBssParams) msg->bodyptr); - break; case WMA_ADD_STA_REQ: wma_add_sta(wma_handle, (tpAddStaParams) msg->bodyptr); break; @@ -8806,21 +8394,14 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) (struct send_peer_unmap_conf_params *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case WMA_SET_BSSKEY_REQ: - wma_set_bsskey(wma_handle, (tpSetBssKeyParams) msg->bodyptr); - break; - case WMA_SET_STAKEY_REQ: - wma_set_stakey(wma_handle, (tpSetStaKeyParams) msg->bodyptr); - break; case WMA_DELETE_STA_REQ: wma_delete_sta(wma_handle, (tpDeleteStaParams) msg->bodyptr); break; case WMA_DELETE_BSS_HO_FAIL_REQ: - wma_delete_bss_ho_fail(wma_handle, - (tpDeleteBssParams) msg->bodyptr); + wma_delete_bss_ho_fail(wma_handle, msg->bodyval); break; case WMA_DELETE_BSS_REQ: - wma_delete_bss(wma_handle, (tpDeleteBssParams) msg->bodyptr); + wma_delete_bss(wma_handle, msg->bodyval); break; case WMA_UPDATE_EDCA_PROFILE_IND: wma_process_update_edca_param_req(wma_handle, @@ -8848,7 +8429,7 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) (struct set_ie_param *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; -#if !defined(REMOVE_PKT_LOG) +#if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG) case WMA_PKTLOG_ENABLE_REQ: wma_pktlog_wmi_send_cmd(wma_handle, (struct ath_pktlog_wmi_params *)msg->bodyptr); @@ -8889,10 +8470,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) qdf_mem_free(msg->bodyptr); break; #endif - case WMA_GET_STATISTICS_REQ: - wma_get_stats_req(wma_handle, - (tAniGetPEStatsReq *) msg->bodyptr); - break; case WMA_UPDATE_OP_MODE: wma_process_update_opmode(wma_handle, @@ -9047,10 +8624,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) (tDisableIntraBssFwd *) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case WMA_GET_PEER_INFO: - wma_get_peer_info(wma_handle, msg->bodyptr); - qdf_mem_free(msg->bodyptr); - break; case WMA_GET_PEER_INFO_EXT: wma_get_peer_info_ext(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); @@ -9070,10 +8643,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) qdf_mem_free(msg->bodyptr); break; #endif /* WLAN_FEATURE_STATS_EXT */ - case WMA_HIDDEN_SSID_VDEV_RESTART: - wma_hidden_ssid_vdev_restart(wma_handle, - (tHalHiddenSsidVdevRestart *) msg->bodyptr); - break; #ifdef WLAN_FEATURE_EXTWOW_SUPPORT case WMA_WLAN_EXT_WOW: wma_enable_ext_wow(wma_handle, @@ -9562,7 +9131,7 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, for (i = 0; i < wma_handle->saved_chan.num_channels; i++) { msg->chan_weights.saved_chan_list[i] = - wma_handle->saved_chan.channel_list[i]; + wma_handle->saved_chan.ch_freq_list[i]; } msg->chan_weights.saved_num_chan = wma_handle->saved_chan.num_channels; @@ -9575,14 +9144,15 @@ QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, msg->chan_weights.weighed_valid_list[i]); /* Dont allow roaming on 2G when 5G_ONLY configured */ if (((wma_handle->bandcapability == BAND_5G) || - (msg->band == BAND_5G)) && - (WLAN_REG_IS_24GHZ_CH( - msg->chan_weights.saved_chan_list[i]))) { + (msg->band_mask == BIT(REG_BAND_5G))) && + (WLAN_REG_IS_24GHZ_CH_FREQ( + msg->chan_weights.saved_chan_list[i]))) { msg->chan_weights.weighed_valid_list[i] = WEIGHT_OF_DISALLOWED_CHANNELS; } - if ((msg->band == BAND_2G) && - WLAN_REG_IS_5GHZ_CH(msg->chan_weights.saved_chan_list[i])) + if (msg->band_mask == BIT(REG_BAND_2G) && + !WLAN_REG_IS_24GHZ_CH_FREQ( + msg->chan_weights.saved_chan_list[i])) msg->chan_weights.weighed_valid_list[i] = WEIGHT_OF_DISALLOWED_CHANNELS; } @@ -9781,7 +9351,7 @@ QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle, WMITLV_GET_STRUCT_TLVLEN( wmi_pdev_set_antenna_mode_cmd_fixed_param)); - cmd->pdev_id = WMI_PDEV_ID_SOC; + cmd->pdev_id = OL_TXRX_PDEV_ID; /* Bits 0-15 is num of RX chains 16-31 is num of TX chains */ cmd->num_txrx_chains = msg->num_rx_chains; cmd->num_txrx_chains |= (msg->num_tx_chains << 16); @@ -9948,6 +9518,10 @@ QDF_STATUS wma_get_rx_chainmask(uint8_t pdev_id, uint32_t *chainmask_2g, (wma_handle->new_hw_mode_index < num_hw_modes)) hw_mode_idx = wma_handle->new_hw_mode_index; mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl); + if (!mac_phy_cap) { + WMA_LOGE("Invalid MAC PHY capabilities handle"); + return QDF_STATUS_E_FAILURE; + } for (idx = 0; idx < total_mac_phy_cnt; idx++) { if (mac_phy_cap[idx].hw_mode_id != hw_mode_idx) continue; @@ -9961,3 +9535,12 @@ QDF_STATUS wma_get_rx_chainmask(uint8_t pdev_id, uint32_t *chainmask_2g, return QDF_STATUS_SUCCESS; } + +#ifdef FEATURE_ANI_LEVEL_REQUEST +QDF_STATUS wma_send_ani_level_request(tp_wma_handle wma_handle, + uint32_t *freqs, uint8_t num_freqs) +{ + return wmi_unified_ani_level_cmd_send(wma_handle->wmi_handle, freqs, + num_freqs); +} +#endif diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c index 7456601cd7cde40a2471e41eacca479dd1186c54..ab23421d5b608332ecdaf56d65c1afe79b92e90a 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c @@ -1,6 +1,5 @@ /* * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -44,7 +43,7 @@ #include "lim_session_utils.h" #include "cds_utils.h" - +#include "wlan_blm_api.h" #if !defined(REMOVE_PKT_LOG) #include "pktlog_ac.h" #else @@ -79,7 +78,7 @@ #include "wmi_unified_bcn_api.h" #include #include -#include "wlan_pkt_capture_ucfg_api.h" +#include <../../core/src/vdev_mgr_ops.h> #if !defined(REMOVE_PKT_LOG) #include @@ -88,15 +87,13 @@ /** * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL * @wma: wma handle - * @pdev: txrx pdev * @vdev_id: vdev id * @param_buf: SWBA parameters * * Return: none */ -#ifdef CONFIG_WMI_BCN_OFFLOAD +#ifdef WLAN_WMI_BCN static void wma_send_bcn_buf_ll(tp_wma_handle wma, - struct cdp_pdev *pdev, uint8_t vdev_id, WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf) { @@ -253,7 +250,6 @@ static void wma_send_bcn_buf_ll(tp_wma_handle wma, #else static inline void wma_send_bcn_buf_ll(tp_wma_handle wma, - struct cdp_pdev *pdev, uint8_t vdev_id, WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf) { @@ -270,14 +266,13 @@ wma_send_bcn_buf_ll(tp_wma_handle wma, * * Return: 0 for success or error code */ -#ifdef CONFIG_WMI_BCN_OFFLOAD +#ifdef WLAN_WMI_BCN int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len) { tp_wma_handle wma = (tp_wma_handle) handle; WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; wmi_host_swba_event_fixed_param *swba_event; uint32_t vdev_map; - struct cdp_pdev *pdev; uint8_t vdev_id = 0; void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -289,12 +284,6 @@ int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len) swba_event = param_buf->fixed_param; vdev_map = swba_event->vdev_map; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: pdev is NULL", __func__); - return -EINVAL; - } - wma_debug("vdev_map = %d", vdev_map); for (; vdev_map && vdev_id < wma->max_bssid; vdev_id++, vdev_map >>= 1) { @@ -302,7 +291,7 @@ int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len) continue; if (!cdp_cfg_is_high_latency(soc, (struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG))) - wma_send_bcn_buf_ll(wma, pdev, vdev_id, param_buf); + wma_send_bcn_buf_ll(wma, vdev_id, param_buf); break; } return 0; @@ -330,58 +319,49 @@ void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id, } #endif -/** - * wma_peer_sta_kickout_event_handler() - kickout event handler - * @handle: wma handle - * @event: event data - * @len: data length - * - * Kickout event is received from firmware on observing beacon miss - * It handles kickout event for different modes and indicate to - * upper layers. - * - * Return: 0 for success or error code - */ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, uint32_t len) { tp_wma_handle wma = (tp_wma_handle) handle; WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; - uint8_t vdev_id, peer_id, macaddr[QDF_MAC_ADDR_SIZE]; - void *peer; - struct cdp_pdev *pdev; + uint8_t vdev_id, macaddr[QDF_MAC_ADDR_SIZE]; tpDeleteStaContext del_sta_ctx; struct ibss_peer_inactivity_ind *inactivity; + uint8_t *addr, *bssid; + struct wlan_objmgr_vdev *vdev; void *soc = cds_get_context(QDF_MODULE_ID_SOC); param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event; kickout_event = param_buf->fixed_param; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: pdev is NULL", __func__); - return -EINVAL; - } WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr); - peer = cdp_peer_find_by_addr(soc, pdev, macaddr, &peer_id); - if (!peer) { - WMA_LOGE("PEER [%pM] not found", macaddr); + if (cdp_peer_get_vdevid(soc, macaddr, &vdev_id) != + QDF_STATUS_SUCCESS) { + WMA_LOGE("Not able to find BSSID for peer ["QDF_MAC_ADDR_FMT"]", + QDF_MAC_ADDR_REF(macaddr)); return -EINVAL; } - - if (cdp_peer_get_vdevid(soc, peer, &vdev_id) != QDF_STATUS_SUCCESS) { - WMA_LOGE("Not able to find BSSID for peer [%pM]", macaddr); + vdev = wma->interfaces[vdev_id].vdev; + if (!vdev) { + WMA_LOGE("Not able to find vdev for VDEV_%d", vdev_id); return -EINVAL; } + addr = wlan_vdev_mlme_get_macaddr(vdev); - wma_nofl_info("STA kickout for %pM, on mac %pM, vdev %d, reason:%d", - macaddr, wma->interfaces[vdev_id].addr, + wma_nofl_info("STA kickout for "QDF_MAC_ADDR_FMT", on mac "QDF_MAC_ADDR_FMT", vdev %d, reason:%d", + QDF_MAC_ADDR_REF(macaddr), QDF_MAC_ADDR_REF(addr), vdev_id, kickout_event->reason); if (wma->interfaces[vdev_id].roaming_in_progress) { WMA_LOGE("Ignore STA kick out since roaming is in progress"); return -EINVAL; } + bssid = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + return -ENOMEM; + } switch (kickout_event->reason) { case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: @@ -390,8 +370,6 @@ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, WMA_LOGE("QDF MEM Alloc Failed for tSirIbssPeerInactivity"); return -ENOMEM; } - - inactivity->staIdx = peer_id; qdf_mem_copy(inactivity->peer_addr.bytes, macaddr, QDF_MAC_ADDR_SIZE); wma_send_msg(wma, WMA_IBSS_PEER_INACTIVITY_IND, @@ -402,22 +380,22 @@ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, del_sta_ctx = (tpDeleteStaContext) qdf_mem_malloc(sizeof(tDeleteStaContext)); if (!del_sta_ctx) { - WMA_LOGE("%s: mem alloc failed for struct del_sta_context for TDLS peer: %pM", - __func__, macaddr); + WMA_LOGE("%s: mem alloc failed for struct del_sta_context for TDLS peer: "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(macaddr)); return -ENOMEM; } del_sta_ctx->is_tdls = true; del_sta_ctx->vdev_id = vdev_id; - del_sta_ctx->staId = peer_id; qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].bssid, + qdf_mem_copy(del_sta_ctx->bssId, bssid, QDF_MAC_ADDR_SIZE); del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE; wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx, 0); goto exit_handler; #endif /* FEATURE_WLAN_TDLS */ + case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: /* * Default legacy value used by original firmware implementation @@ -426,7 +404,7 @@ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, (wma->interfaces[vdev_id].sub_type == 0 || wma->interfaces[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) && - !qdf_mem_cmp(wma->interfaces[vdev_id].bssid, + !qdf_mem_cmp(bssid, macaddr, QDF_MAC_ADDR_SIZE)) { wma_sta_kickout_event( HOST_STA_KICKOUT_REASON_UNSPECIFIED, vdev_id, macaddr); @@ -470,10 +448,8 @@ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, del_sta_ctx->is_tdls = false; del_sta_ctx->vdev_id = vdev_id; - del_sta_ctx->staId = peer_id; qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].addr, - QDF_MAC_ADDR_SIZE); + qdf_mem_copy(del_sta_ctx->bssId, addr, QDF_MAC_ADDR_SIZE); if (kickout_event->reason == WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT) del_sta_ctx->reasonCode = @@ -493,24 +469,11 @@ int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event, wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx, 0); wma_lost_link_info_handler(wma, vdev_id, del_sta_ctx->rssi); + exit_handler: return 0; } -/** - * wma_unified_bcntx_status_event_handler() - beacon tx status event handler - * @handle: wma handle - * @cmd_param_info: event data - * @len: data length - * - * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware. - * This event is generated by FW when the beacon transmission is offloaded - * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID - * The FW generates this event when the first successful beacon transmission - * after template update - * - * Return: 0 for success or error code - */ int wma_unified_bcntx_status_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len) @@ -538,8 +501,9 @@ int wma_unified_bcntx_status_event_handler(void *handle, /* Check for valid handle to ensure session is not * deleted in any race */ - if (!wma->interfaces[resp_event->vdev_id].handle) { - WMA_LOGE("%s: The session does not exist", __func__); + if (!wma->interfaces[resp_event->vdev_id].vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", + __func__, resp_event->vdev_id); return -EINVAL; } @@ -872,45 +836,6 @@ void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id, wmi_unified_set_sta_keep_alive_cmd(wma->wmi_handle, ¶ms); } -/** - * wma_vdev_install_key_complete_event_handler() - install key complete handler - * @handle: wma handle - * @event: event data - * @len: data length - * - * This event is sent by fw once WPA/WPA2 keys are installed in fw. - * - * Return: 0 for success or error code - */ -int wma_vdev_install_key_complete_event_handler(void *handle, - uint8_t *event, - uint32_t len) -{ - WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf = NULL; - wmi_vdev_install_key_complete_event_fixed_param *key_fp = NULL; - - if (!event) { - WMA_LOGE("%s: event param null", __func__); - return -EINVAL; - } - - param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *) event; - if (!param_buf) { - WMA_LOGE("%s: received null buf from target", __func__); - return -EINVAL; - } - - key_fp = param_buf->fixed_param; - if (!key_fp) { - WMA_LOGE("%s: received null event data from target", __func__); - return -EINVAL; - } - /* - * Do nothing for now. Completion of set key is already indicated to lim - */ - wma_debug("WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID"); - return 0; -} /* * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": * 0 for no restriction @@ -938,49 +863,6 @@ static inline uint8_t wma_parse_mpdudensity(uint8_t mpdudensity) return 0; } -#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) - -/** - * wma_unified_peer_state_update() - update peer state - * @pdev: pdev handle - * @sta_mac: pointer to sta mac addr - * @bss_addr: bss address - * @sta_type: sta entry type - * - * - * Return: None - */ -static void -wma_unified_peer_state_update( - struct cdp_pdev *pdev, - uint8_t *sta_mac, - uint8_t *bss_addr, - uint8_t sta_type) -{ - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - if (STA_ENTRY_TDLS_PEER == sta_type) - cdp_peer_state_update(soc, pdev, sta_mac, - OL_TXRX_PEER_STATE_AUTH); - else - cdp_peer_state_update(soc, pdev, bss_addr, - OL_TXRX_PEER_STATE_AUTH); -} -#else - -static inline void -wma_unified_peer_state_update( - struct cdp_pdev *pdev, - uint8_t *sta_mac, - uint8_t *bss_addr, - uint8_t sta_type) -{ - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - cdp_peer_state_update(soc, pdev, bss_addr, OL_TXRX_PEER_STATE_AUTH); -} -#endif - #define CFG_CTRL_MASK 0xFF00 #define CFG_DATA_MASK 0x00FF @@ -1257,17 +1139,8 @@ WMI_HOST_WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode) } } -/** - * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object - * @wma: wma handle - * @mac_addr: mac addr of peer - * @phymode: phymode value to set - * - * Return: None - */ -static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, - uint8_t *mac_addr, - WMI_HOST_WLAN_PHY_MODE phymode) +void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, uint8_t *mac_addr, + enum wlan_phymode phymode) { uint8_t pdev_id; struct wlan_objmgr_peer *peer; @@ -1280,7 +1153,7 @@ static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, return; wlan_peer_obj_lock(peer); - wlan_peer_set_phymode(peer, wma_fw_to_host_phymode(phymode)); + wlan_peer_set_phymode(peer, phymode); wlan_peer_obj_unlock(peer); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); } @@ -1328,19 +1201,19 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, tSirNwType nw_type, tpAddStaParams params) { - struct cdp_pdev *pdev; struct peer_assoc_params *cmd; int32_t ret, max_rates, i; uint8_t *rate_pos; wmi_rate_set peer_legacy_rates, peer_ht_rates; uint32_t num_peer_11b_rates = 0; uint32_t num_peer_11a_rates = 0; - uint32_t phymode; + enum wlan_phymode phymode, vdev_phymode; uint32_t peer_nss = 1; struct wma_txrx_node *intr = NULL; bool is_he; QDF_STATUS status; struct mac_context *mac = wma->mac_context; + struct wlan_channel *des_chan; cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params)); if (!cmd) { @@ -1350,14 +1223,6 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, intr = &wma->interfaces[params->smesessionId]; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - qdf_mem_free(cmd); - return QDF_STATUS_E_INVAL; - } - wma_mask_tx_ht_rate(wma, params->supportedRates.supportedMCSSet); qdf_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set)); @@ -1375,15 +1240,15 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, phymode = wma_peer_phymode(nw_type, params->staType, params->htCapable, params->ch_width, params->vhtCapable, is_he); - if ((phymode != MODE_11B) && (intr->type == WMI_VDEV_TYPE_AP) && - (phymode > intr->chanmode)) { + + des_chan = wlan_vdev_mlme_get_des_chan(intr->vdev); + vdev_phymode = des_chan->ch_phymode; + if ((intr->type == WMI_VDEV_TYPE_AP) && (phymode > vdev_phymode)) { wma_nofl_debug("Peer phymode %d is not allowed. Set it equal to sap/go phymode %d", - phymode, intr->chanmode); - phymode = intr->chanmode; + phymode, vdev_phymode); + phymode = vdev_phymode; } - wma_objmgr_set_peer_mlme_phymode(wma, params->staMac, phymode); - if (!mac->mlme_cfg->rates.disable_abg_rate_txdata) { /* Legacy Rateset */ rate_pos = (uint8_t *) peer_legacy_rates.rates; @@ -1403,8 +1268,8 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, } } - if ((phymode == MODE_11A && num_peer_11a_rates == 0) || - (phymode == MODE_11B && num_peer_11b_rates == 0)) { + if ((phymode == WLAN_PHYMODE_11A && num_peer_11a_rates == 0) || + (phymode == WLAN_PHYMODE_11B && num_peer_11b_rates == 0)) { WMA_LOGW("%s: Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d", __func__, phymode, num_peer_11b_rates, num_peer_11a_rates); @@ -1462,79 +1327,78 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, } else { qdf_mem_copy(cmd->peer_mac, params->bssId, sizeof(cmd->peer_mac)); - wma_objmgr_set_peer_mlme_phymode(wma, params->bssId, phymode); } + wma_objmgr_set_peer_mlme_phymode(wma, cmd->peer_mac, phymode); cmd->vdev_id = params->smesessionId; cmd->peer_new_assoc = 1; cmd->peer_associd = params->assocId; - /* - * The target only needs a subset of the flags maintained in the host. - * Just populate those flags and send it down - */ - cmd->peer_flags = 0; + cmd->is_wme_set = 1; if (params->wmmEnabled) - cmd->peer_flags |= WMI_PEER_QOS; + cmd->qos_flag = 1; if (params->uAPSD) { - cmd->peer_flags |= WMI_PEER_APSD; + cmd->apsd_flag = 1; wma_nofl_debug("Set WMI_PEER_APSD: uapsd Mask %d", params->uAPSD); } if (params->htCapable) { - cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_QOS); + cmd->ht_flag = 1; + cmd->qos_flag = 1; cmd->peer_rate_caps |= WMI_RC_HT_FLAG; - - if (params->ch_width) { - cmd->peer_flags |= WMI_PEER_40MHZ; - cmd->peer_rate_caps |= WMI_RC_CW40_FLAG; - if (params->fShortGI40Mhz) - cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; - } else if (params->fShortGI20Mhz) { - cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; - } } if (params->vhtCapable) { - cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_VHT | WMI_PEER_QOS); + cmd->ht_flag = 1; + cmd->qos_flag = 1; + cmd->vht_flag = 1; cmd->peer_rate_caps |= WMI_RC_HT_FLAG; } + if (params->ch_width) { + cmd->bw_40 = 1; + cmd->peer_rate_caps |= WMI_RC_CW40_FLAG; + if (params->fShortGI40Mhz) + cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; + } else if (params->fShortGI20Mhz) { + cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; + } + if (params->ch_width == CH_WIDTH_80MHZ) - cmd->peer_flags |= WMI_PEER_80MHZ; + cmd->bw_80 = 1; else if (params->ch_width == CH_WIDTH_160MHZ) - cmd->peer_flags |= WMI_PEER_160MHZ; + cmd->bw_160 = 1; else if (params->ch_width == CH_WIDTH_80P80MHZ) - cmd->peer_flags |= WMI_PEER_160MHZ; + cmd->bw_160 = 1; cmd->peer_vht_caps = params->vht_caps; if (params->p2pCapableSta) { - cmd->peer_flags |= WMI_PEER_IS_P2P_CAPABLE; + cmd->p2p_capable_sta = 1; wma_objmgr_set_peer_mlme_type(wma, params->staMac, WLAN_PEER_P2P_CLI); } if (params->rmfEnabled) - cmd->peer_flags |= WMI_PEER_PMF; + cmd->is_pmf_enabled = 1; if (params->stbc_capable) - cmd->peer_flags |= WMI_PEER_STBC; + cmd->stbc_flag = 1; if (params->htLdpcCapable || params->vhtLdpcCapable) - cmd->peer_flags |= WMI_PEER_LDPC; + cmd->ldpc_flag = 1; switch (params->mimoPS) { case eSIR_HT_MIMO_PS_STATIC: - cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; + cmd->static_mimops_flag = 1; break; case eSIR_HT_MIMO_PS_DYNAMIC: - cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; + cmd->dynamic_mimops_flag = 1; break; case eSIR_HT_MIMO_PS_NO_LIMIT: - cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; + cmd->spatial_mux_flag = 1; break; default: break; @@ -1543,7 +1407,7 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, wma_set_twt_peer_caps(params, cmd); #ifdef FEATURE_WLAN_TDLS if (STA_ENTRY_TDLS_PEER == params->staType) - cmd->peer_flags |= WMI_PEER_AUTH; + cmd->auth_flag = 1; #endif /* FEATURE_WLAN_TDLS */ if (params->wpa_rsn @@ -1552,7 +1416,7 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, #endif /* FEATURE_WLAN_WAPI */ ) { if (!params->no_ptk_4_way) - cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; + cmd->need_ptk_4_way = 1; wma_nofl_debug("Acquire set key wake lock for %d ms", WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT); wma_acquire_wakelock(&intr->vdev_set_key_wakelock, @@ -1561,10 +1425,7 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, &intr->vdev_set_key_runtime_wakelock); } if (params->wpa_rsn >> 1) - cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; - - wma_unified_peer_state_update(pdev, params->staMac, - params->bssId, params->staType); + cmd->need_gtk_2_way = 1; #ifdef FEATURE_WLAN_WAPI if (params->encryptType == eSIR_ED_WPI) { @@ -1639,23 +1500,49 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, ((1 << cmd->peer_nss) - 1)); WMI_VHT_MCS_NOTIFY_EXT_SS_SET(cmd->tx_mcs_set, 1); } + if (params->vht_extended_nss_bw_cap && + (params->vht_160mhz_nss || params->vht_80p80mhz_nss)) { + /* + * bit[2:0] : Represents value of Rx NSS for 160 MHz + * bit[5:3] : Represents value of Rx NSS for 80_80 MHz + * Extended NSS support + * bit[30:6]: Reserved + * bit[31] : MSB(0/1): 1 in case of valid data + */ + cmd->peer_bw_rxnss_override |= (1 << 31); + if (params->vht_160mhz_nss) + cmd->peer_bw_rxnss_override |= + (params->vht_160mhz_nss - 1); + if (params->vht_80p80mhz_nss) + cmd->peer_bw_rxnss_override |= + ((params->vht_80p80mhz_nss - 1) << 3); + wma_debug("peer_bw_rxnss_override %0X", + cmd->peer_bw_rxnss_override); + } } - wma_debug("rx_max_rate %d, rx_mcs %x, tx_max_rate %d, tx_mcs: %x num rates %d", + wma_debug("rx_max_rate %d, rx_mcs %x, tx_max_rate %d, tx_mcs: %x num rates %d need 4 way %d", cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate, - cmd->tx_mcs_set, peer_ht_rates.num_rates); + cmd->tx_mcs_set, peer_ht_rates.num_rates, + cmd->need_ptk_4_way); /* * Limit nss to max number of rf chain supported by target * Otherwise Fw will crash */ - if (cmd->peer_nss > WMA_MAX_NSS) + if (cmd->peer_nss > WMA_MAX_NSS) { + WMA_LOGE(FL("peer Nss %d is more than supported"), + cmd->peer_nss); cmd->peer_nss = WMA_MAX_NSS; + } wma_populate_peer_he_cap(cmd, params); + if (!wma_is_vdev_in_ap_mode(wma, params->smesessionId)) + intr->nss = cmd->peer_nss; + + /* Till conversion is not done in WMI we need to fill fw phy mode */ + cmd->peer_phymode = wma_host_to_fw_phymode(phymode); - intr->nss = cmd->peer_nss; - cmd->peer_phymode = phymode; status = wmi_unified_peer_assoc_send(wma->wmi_handle, cmd); if (QDF_IS_STATUS_ERROR(status)) @@ -1792,123 +1679,68 @@ wma_process_update_beacon_params(tp_wma_handle wma, return; } - if (bcn_params->smeSessionId >= wma->max_bssid) { - WMA_LOGE("Invalid vdev id %d", bcn_params->smeSessionId); + if (bcn_params->vdev_id >= wma->max_bssid) { + WMA_LOGE("Invalid vdev id %d", bcn_params->vdev_id); return; } if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) { - wma_update_beacon_interval(wma, bcn_params->smeSessionId, + wma_update_beacon_interval(wma, bcn_params->vdev_id, bcn_params->beaconInterval); } if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED) - wma_update_protection_mode(wma, bcn_params->smeSessionId, + wma_update_protection_mode(wma, bcn_params->vdev_id, bcn_params->llbCoexist); if (bcn_params->paramChangeBitmap & PARAM_BSS_COLOR_CHANGED) - wma_update_bss_color(wma, bcn_params->smeSessionId, + wma_update_bss_color(wma, bcn_params->vdev_id, bcn_params); } -/** - * wma_update_rts_params() - update cfg parameters to target - * @wma: wma handle - * @value: rts_threshold - * - * Return: none - */ void wma_update_rts_params(tp_wma_handle wma, uint32_t value) { uint8_t vdev_id; QDF_STATUS ret; + struct wlan_objmgr_vdev *vdev; for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { - if (wma->interfaces[vdev_id].handle != 0) { - ret = wma_vdev_set_param(wma->wmi_handle, - vdev_id, - WMI_VDEV_PARAM_RTS_THRESHOLD, - value); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Update cfg param fail for vdevId %d", - vdev_id); - } + vdev = wma->interfaces[vdev_id].vdev; + if (!vdev) + continue; + ret = wma_vdev_set_param(wma->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_RTS_THRESHOLD, + value); + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("Update cfg param fail for vdevId %d", + vdev_id); } } -/** - * wma_update_frag_params() - update cfg parameters to target - * @wma: wma handle - * @value: frag_threshold - * - * Return: none - */ void wma_update_frag_params(tp_wma_handle wma, uint32_t value) { uint8_t vdev_id; QDF_STATUS ret; + struct wlan_objmgr_vdev *vdev; for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { - if (wma->interfaces[vdev_id].handle != 0) { - ret = wma_vdev_set_param(wma->wmi_handle, - vdev_id, - WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - value); - if (QDF_IS_STATUS_ERROR(ret)) - WMA_LOGE("Update cfg params failed for vdevId %d", - vdev_id); - } - } -} - -#ifndef CRYPTO_SET_KEY_CONVERGED -/** - * wma_read_cfg_wepkey() - fill key_info for WEP key - * @wma_handle: wma handle - * @key_info: key_info ptr - * @def_key_idx: default key index - * @num_keys: number of keys - * @vdev: vdev pointer - * - * This function reads WEP keys from cfg and fills - * up key_info. - * - * Return: none - */ -static void wma_read_cfg_wepkey(tp_wma_handle wma_handle, - tSirKeys *key_info, uint32_t *def_key_idx, - uint8_t *num_keys, - struct wlan_objmgr_vdev *vdev) -{ - QDF_STATUS status; - qdf_size_t val = SIR_MAC_KEY_LENGTH; - uint8_t i, j; - struct mac_context *mac_ctx = wma_handle->mac_context; - - WMA_LOGD("Reading WEP keys from cfg"); - - /* NOTE:def_key_idx is initialized to 0 by the caller */ - *def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id; - - for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) { - status = mlme_get_wep_key(vdev, &mac_ctx->mlme_cfg->wep_params, - (MLME_WEP_DEFAULT_KEY_1 + - i), key_info[j].key, &val); - if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("WEP key is not configured at :%d", i); - } else { - key_info[j].keyId = i; - key_info[j].keyLength = (uint16_t) val; - j++; - } + vdev = wma->interfaces[vdev_id].vdev; + if (!vdev) + continue; + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, + value); + if (QDF_IS_STATUS_ERROR(ret)) + WMA_LOGE("Update cfg params failed for vdevId %d", + vdev_id); } - *num_keys = j; } -#endif #ifdef FEATURE_WLAN_WAPI #define WPI_IV_LEN 16 -#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) +#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \ + defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) /** * wma_fill_in_wapi_key_params() - update key parameters about wapi * @key_params: wma key parameters @@ -1987,291 +1819,6 @@ static inline void wma_fill_in_wapi_key_params( #endif #endif -#ifndef CRYPTO_SET_KEY_CONVERGED -/** - * wma_skip_bip_key_set() - skip the BIP key step or not - * @wma_handle: wma handle - * @iface: txrx node - * @key_cipher: key cipher - * - * if target not support the BIP key cipher, skip the set key command. - * - * Return: true to skip set key to target, otherwise set key to target - */ -static bool -wma_skip_bip_key_set(tp_wma_handle wma_handle, uint32_t key_cipher) -{ - if ((key_cipher == WMI_CIPHER_AES_GMAC || - key_cipher == WMI_CIPHER_BIP_GMAC_256) && - !wmi_service_enabled(wma_handle->wmi_handle, - wmi_service_gmac_offload_support)) - return true; - return false; -} - -static void wma_set_peer_unicast_cipher(tp_wma_handle wma, - struct set_key_params *params) -{ - struct wlan_objmgr_peer *peer; - - peer = wlan_objmgr_get_peer(wma->psoc, - wlan_objmgr_pdev_get_pdev_id(wma->pdev), - params->peer_mac, WLAN_LEGACY_WMA_ID); - if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", params->peer_mac); - return; - } - - wlan_peer_set_unicast_cipher(peer, params->key_cipher); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); -} - -/** - * wma_setup_install_key_cmd() - set key parameters - * @wma_handle: wma handle - * @key_params: key parameters - * @mode: op mode - * - * This function fills structure from information - * passed in key_params. - * - * Return: QDF_STATUS_SUCCESS - success - QDF_STATUS_E_FAILURE - failure - QDF_STATUS_E_NOMEM - invalid request - */ -static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, - struct wma_set_key_params - *key_params, uint8_t mode) -{ - struct set_key_params params; - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct wma_txrx_node *iface = NULL; - enum cdp_sec_type sec_type = cdp_sec_type_none; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_vdev *txrx_vdev; - uint32_t pn[4] = {0, 0, 0, 0}; - uint8_t peer_id; - struct cdp_peer *peer; - bool skip_set_key; - - if ((key_params->key_type == eSIR_ED_NONE && - key_params->key_len) || (key_params->key_type != eSIR_ED_NONE && - !key_params->key_len)) { - WMA_LOGE("%s:Invalid set key request", __func__); - return QDF_STATUS_E_NOMEM; - } - - if (!wma_handle) { - WMA_LOGE(FL("Invalid wma_handle for vdev_id: %d"), - key_params->vdev_id); - return QDF_STATUS_E_INVAL; - } - - if (!wma_is_vdev_valid(key_params->vdev_id)) { - WMA_LOGE("%s: vdev id:%d is not active ", __func__, - key_params->vdev_id); - return QDF_STATUS_E_INVAL; - } - - txrx_vdev = wma_find_vdev_by_id(wma_handle, - key_params->vdev_id); - peer = cdp_peer_find_by_addr(soc, txrx_pdev, - key_params->peer_mac, &peer_id); - iface = &wma_handle->interfaces[key_params->vdev_id]; - - params.vdev_id = key_params->vdev_id; - params.key_idx = key_params->key_idx; - qdf_mem_copy(params.peer_mac, key_params->peer_mac, QDF_MAC_ADDR_SIZE); - -#ifdef FEATURE_WLAN_WAPI - qdf_mem_zero(params.tx_iv, 16); - qdf_mem_zero(params.rx_iv, 16); -#endif - params.key_txmic_len = 0; - params.key_rxmic_len = 0; - qdf_mem_copy(¶ms.key_rsc_ctr, - &key_params->key_rsc[0], sizeof(uint64_t)); - params.key_flags = 0; - if (key_params->unicast) - params.key_flags |= PAIRWISE_USAGE; - else - params.key_flags |= GROUP_USAGE; - - switch (key_params->key_type) { - case eSIR_ED_NONE: - params.key_cipher = WMI_CIPHER_NONE; - sec_type = cdp_sec_type_none; - break; - case eSIR_ED_WEP40: - case eSIR_ED_WEP104: - params.key_cipher = WMI_CIPHER_WEP; - if (key_params->unicast && - params.key_idx == key_params->def_key_idx) { - WMA_LOGD("STA Mode: cmd->key_flags |= TX_USAGE"); - params.key_flags |= TX_USAGE; - } else if ((mode == wlan_op_mode_ap) && - (params.key_idx == key_params->def_key_idx)) { - WMA_LOGD("AP Mode: cmd->key_flags |= TX_USAGE"); - params.key_flags |= TX_USAGE; - } - sec_type = cdp_sec_type_wep104; - break; - case eSIR_ED_TKIP: - params.key_txmic_len = WMA_TXMIC_LEN; - params.key_rxmic_len = WMA_RXMIC_LEN; - params.key_cipher = WMI_CIPHER_TKIP; - sec_type = cdp_sec_type_tkip; - break; -#ifdef FEATURE_WLAN_WAPI - case eSIR_ED_WPI: - { - wma_fill_in_wapi_key_params(key_params, ¶ms, mode); - break; - } -#endif /* FEATURE_WLAN_WAPI */ - case eSIR_ED_CCMP: - params.key_cipher = WMI_CIPHER_AES_CCM; - sec_type = cdp_sec_type_aes_ccmp; - break; -#ifdef WLAN_FEATURE_11W - case eSIR_ED_AES_128_CMAC: - params.key_cipher = WMI_CIPHER_AES_CMAC; - break; - case eSIR_ED_AES_GMAC_128: - case eSIR_ED_AES_GMAC_256: - params.key_cipher = WMI_CIPHER_AES_GMAC; - break; -#endif /* WLAN_FEATURE_11W */ - /* Firmware uses length to detect GCMP 128/256*/ - case eSIR_ED_GCMP: - case eSIR_ED_GCMP_256: - params.key_cipher = WMI_CIPHER_AES_GCM; - break; - default: - /* TODO: MFP ? */ - WMA_LOGE("%s:Invalid encryption type:%d", __func__, - key_params->key_type); - status = QDF_STATUS_E_NOMEM; - goto end; - } - -#ifdef BIG_ENDIAN_HOST - { - /* for big endian host, copy engine byte_swap is enabled - * But the key data content is in network byte order - * Need to byte swap the key data content - so when copy engine - * does byte_swap - target gets key_data content in the correct - * order. - */ - int8_t i; - uint32_t *destp, *srcp; - - destp = (uint32_t *) params.key_data; - srcp = (uint32_t *) key_params->key_data; - for (i = 0; - i < roundup(key_params->key_len, sizeof(uint32_t)) / 4; - i++) { - *destp = le32_to_cpu(*srcp); - destp++; - srcp++; - } - } -#else - qdf_mem_copy((void *)params.key_data, - (const void *)key_params->key_data, key_params->key_len); -#endif /* BIG_ENDIAN_HOST */ - params.key_len = key_params->key_len; - -#ifdef WLAN_FEATURE_11W - iface = &wma_handle->interfaces[key_params->vdev_id]; - - if ((key_params->key_type == eSIR_ED_AES_128_CMAC) || - (key_params->key_type == eSIR_ED_AES_GMAC_128) || - (key_params->key_type == eSIR_ED_AES_GMAC_256)) { - if (iface) { - iface->key.key_length = key_params->key_len; - iface->key.key_cipher = params.key_cipher; - qdf_mem_copy(iface->key.key, - (const void *)key_params->key_data, - iface->key.key_length); - if ((params.key_idx == WMA_IGTK_KEY_INDEX_4) || - (params.key_idx == WMA_IGTK_KEY_INDEX_5)) - qdf_mem_zero(iface->key.key_id[params.key_idx - - WMA_IGTK_KEY_INDEX_4].ipn, - CMAC_IPN_LEN); - } - } -#endif /* WLAN_FEATURE_11W */ - - if (key_params->unicast) - wma_set_peer_unicast_cipher(wma_handle, ¶ms); - - WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d", - key_params->vdev_id, key_params->key_idx, - key_params->key_type, key_params->key_len); - WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d", - key_params->unicast, key_params->peer_mac, - key_params->def_key_idx); - WMA_LOGD("keyrsc param %llu", params.key_rsc_ctr); - - /* - * To prevent from any replay-attack, PN number provided by - * upper layer is used. - * - * Plumb the PN number to HW which will be used to evaluate whether - * incoming traffic is not replayed. - * - * supplicant would have some thing like following, example: - * - * num = 0x123456789ABCDEFF (64 bit number) - * uint8_t keyrsc[16] would look like following - * - * bit 0 7 15 23 31 39 47 55 63 - * +------+-------+-------+-------+-------+-------+-------+-------+ - * byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | - * +------+-------+-------+-------+-------+-------+-------+-------+ - * value| 0xFF | 0XDE | 0xBC | 0x9A | 0x78 | 0x56 | 0x34 | 0x12 | - * +------+-------+-------+-------+-------+-------+-------+-------+ - */ - qdf_mem_copy(&pn[0], - &key_params->key_rsc[0], sizeof(pn)); - wma_debug("key_type[%s] pn[%x:%x:%x:%x]", - (key_params->unicast) ? "unicast" : "group", - key_params->key_rsc[3], key_params->key_rsc[2], - key_params->key_rsc[1], key_params->key_rsc[0]); - cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn); - cdp_set_key_sec_type(soc, txrx_vdev, peer, - sec_type, - key_params->unicast); - cdp_set_key(soc, peer, key_params->unicast, - (uint32_t *)(key_params->key_data + - WMA_IV_KEY_LEN + - WMA_TXMIC_LEN)); - - skip_set_key = wma_skip_bip_key_set(wma_handle, params.key_cipher); - if (!skip_set_key) - status = wmi_unified_setup_install_key_cmd( - wma_handle->wmi_handle, ¶ms); - - if (!key_params->unicast) { - /* Its GTK release the wake lock */ - WMA_LOGD("Release set key wake lock"); - qdf_runtime_pm_allow_suspend( - &iface->vdev_set_key_runtime_wakelock); - wma_release_wakelock(&iface->vdev_set_key_wakelock); - } - - /* install key was requested */ - if (iface) - iface->is_waiting_for_key = false; - -end: - qdf_mem_zero(¶ms, sizeof(struct set_key_params)); - return status; -} -#endif - #ifdef QCA_IBSS_SUPPORT /** * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer @@ -2299,19 +1846,10 @@ static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num) return heart_beat_timer[peer_num - 1]; } -/** - * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw. - * @wma: wma handle - * @vdev_id: vdev id - * @peer_num_delta: peer number delta value - * - * Return: none - */ void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, uint8_t vdev_id, int8_t peer_num_delta) { - struct cdp_vdev *vdev; int16_t new_peer_num; uint16_t new_timer_value_sec; uint32_t new_timer_value_ms; @@ -2323,16 +1861,10 @@ void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, return; } - vdev = wma_find_vdev_by_id(wma, vdev_id); - if (!vdev) { - WMA_LOGE("vdev not found : vdev_id %d", vdev_id); - return; - } - /* adjust peer numbers */ - new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, vdev, - peer_num_delta - ); + new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev( + soc, vdev_id, + peer_num_delta); if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) { WMA_LOGE("new peer num %d out of valid boundary", new_peer_num); return; @@ -2340,7 +1872,7 @@ void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, /* reset timer value if all peers departed */ if (new_peer_num == 0) { - cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0); + cdp_set_ibss_vdev_heart_beat_timer(soc, vdev_id, 0); return; } @@ -2352,7 +1884,7 @@ void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, return; } if (new_timer_value_sec == - cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, + cdp_set_ibss_vdev_heart_beat_timer(soc, vdev_id, new_timer_value_sec)) { wma_nofl_debug("timer value %d stays same, no need to notify target", new_timer_value_sec); @@ -2374,365 +1906,6 @@ void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, } #endif /* QCA_IBSS_SUPPORT */ -#ifndef CRYPTO_SET_KEY_CONVERGED -void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) -{ - struct wma_set_key_params key_params; - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t i; - uint32_t def_key_idx = 0; - uint32_t wlan_opmode; - struct cdp_vdev *txrx_vdev; - uint8_t *mac_addr; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wlan_objmgr_vdev *vdev; - - WMA_LOGD("BSS key setup"); - txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); - if (!txrx_vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - wlan_opmode = cdp_get_opmode(soc, txrx_vdev); - - /* - * For IBSS, WMI expects the BSS key to be set per peer key - * So cache the BSS key in the wma_handle and re-use it when the - * STA key is been setup for a peer - */ - if (wlan_op_mode_ibss == wlan_opmode) { - key_info->status = QDF_STATUS_SUCCESS; - if (wma_handle->ibss_started > 0) - goto out; - WMA_LOGD("Caching IBSS Key"); - qdf_mem_copy(&wma_handle->ibsskey_info, key_info, - sizeof(tSetBssKeyParams)); - } - - qdf_mem_zero(&key_params, sizeof(key_params)); - key_params.vdev_id = key_info->smesessionId; - key_params.key_type = key_info->encType; - key_params.singl_tid_rc = key_info->singleTidRc; - key_params.unicast = false; - if (wlan_opmode == wlan_op_mode_sta) { - qdf_mem_copy(key_params.peer_mac, - wma_handle->interfaces[key_info->smesessionId].bssid, - QDF_MAC_ADDR_SIZE); - } else { - mac_addr = cdp_get_vdev_mac_addr(soc, - txrx_vdev); - if (!mac_addr) { - WMA_LOGE("%s: mac_addr is NULL for vdev with id %d", - __func__, key_info->smesessionId); - goto out; - } - /* vdev mac address will be passed for all other modes */ - qdf_mem_copy(key_params.peer_mac, mac_addr, - QDF_MAC_ADDR_SIZE); - WMA_LOGD("BSS Key setup with vdev_mac %pM\n", - mac_addr); - } - - if (key_info->numKeys == 0 && - (key_info->encType == eSIR_ED_WEP40 || - key_info->encType == eSIR_ED_WEP104)) { - vdev = - wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, - key_info->smesessionId, - WLAN_LEGACY_WMA_ID); - wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &key_info->numKeys, vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - } else if ((key_info->encType == eSIR_ED_WEP40) || - (key_info->encType == eSIR_ED_WEP104)) { - struct wma_txrx_node *intf = - &wma_handle->interfaces[key_info->smesessionId]; - key_params.def_key_idx = intf->wep_default_key_idx; - } - - for (i = 0; i < key_info->numKeys; i++) { - if (key_params.key_type != eSIR_ED_NONE && - !key_info->key[i].keyLength) - continue; - if (key_info->encType == eSIR_ED_WPI) { - key_params.key_idx = key_info->key[i].keyId; - key_params.def_key_idx = key_info->key[i].keyId; - } else - key_params.key_idx = key_info->key[i].keyId; - - key_params.key_len = key_info->key[i].keyLength; - qdf_mem_copy(key_params.key_rsc, - key_info->key[i].keyRsc, - WLAN_CRYPTO_RSC_SIZE); - if (key_info->encType == eSIR_ED_TKIP) { - qdf_mem_copy(key_params.key_data, - key_info->key[i].key, 16); - qdf_mem_copy(&key_params.key_data[16], - &key_info->key[i].key[24], 8); - qdf_mem_copy(&key_params.key_data[24], - &key_info->key[i].key[16], 8); - } else - qdf_mem_copy((void *)key_params.key_data, - (const void *)key_info->key[i].key, - key_info->key[i].keyLength); - - WMA_LOGD("%s: bss key[%d] length %d", __func__, i, - key_info->key[i].keyLength); - - status = wma_setup_install_key_cmd(wma_handle, &key_params, - wlan_opmode); - if (status == QDF_STATUS_E_NOMEM) { - WMA_LOGE("%s:Failed to setup install key buf", - __func__); - key_info->status = QDF_STATUS_E_NOMEM; - goto out; - } else if (status == QDF_STATUS_E_FAILURE) { - WMA_LOGE("%s:Failed to send install key command", - __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - } - - wma_handle->ibss_started++; - /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */ - key_info->status = QDF_STATUS_SUCCESS; - - qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params)); - -out: - wma_send_msg_high_priority(wma_handle, WMA_SET_BSSKEY_RSP, - (void *)key_info, 0); -} - -/** - * wma_set_ibsskey_helper() - cached IBSS key in wma handle - * @wma_handle: wma handle - * @key_info: set bss key info - * @peerMacAddr: peer mac address - * - * Return: none - */ -static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, - tpSetBssKeyParams key_info, - struct qdf_mac_addr peer_macaddr) -{ - struct wma_set_key_params key_params; - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t i; - uint32_t def_key_idx = 0; - struct cdp_vdev *txrx_vdev; - int opmode; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wlan_objmgr_vdev *vdev; - - WMA_LOGD("BSS key setup for peer"); - txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); - if (!txrx_vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); - key_info->status = QDF_STATUS_E_FAILURE; - return; - } - - qdf_mem_zero(&key_params, sizeof(key_params)); - opmode = cdp_get_opmode(soc, txrx_vdev); - qdf_mem_zero(&key_params, sizeof(key_params)); - key_params.vdev_id = key_info->smesessionId; - key_params.key_type = key_info->encType; - key_params.singl_tid_rc = key_info->singleTidRc; - key_params.unicast = false; - ASSERT(wlan_op_mode_ibss == opmode); - - qdf_mem_copy(key_params.peer_mac, peer_macaddr.bytes, - QDF_MAC_ADDR_SIZE); - - if (key_info->numKeys == 0 && - (key_info->encType == eSIR_ED_WEP40 || - key_info->encType == eSIR_ED_WEP104)) { - vdev = - wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, - key_info->smesessionId, - WLAN_LEGACY_WMA_ID); - wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &key_info->numKeys, vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - } else if ((key_info->encType == eSIR_ED_WEP40) || - (key_info->encType == eSIR_ED_WEP104)) { - struct wma_txrx_node *intf = - &wma_handle->interfaces[key_info->smesessionId]; - key_params.def_key_idx = intf->wep_default_key_idx; - } - - for (i = 0; i < key_info->numKeys; i++) { - if (key_params.key_type != eSIR_ED_NONE && - !key_info->key[i].keyLength) - continue; - key_params.key_idx = key_info->key[i].keyId; - key_params.key_len = key_info->key[i].keyLength; - if (key_info->encType == eSIR_ED_TKIP) { - qdf_mem_copy(key_params.key_data, - key_info->key[i].key, 16); - qdf_mem_copy(&key_params.key_data[16], - &key_info->key[i].key[24], 8); - qdf_mem_copy(&key_params.key_data[24], - &key_info->key[i].key[16], 8); - } else - qdf_mem_copy((void *)key_params.key_data, - (const void *)key_info->key[i].key, - key_info->key[i].keyLength); - - WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i, - key_info->key[i].keyLength); - - status = wma_setup_install_key_cmd(wma_handle, &key_params, - opmode); - if (status == QDF_STATUS_E_NOMEM) { - WMA_LOGE("%s:Failed to setup install key buf", - __func__); - return; - } else if (status == QDF_STATUS_E_FAILURE) { - WMA_LOGE("%s:Failed to send install key command", - __func__); - } - } -} - -void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) -{ - int32_t i; - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct cdp_pdev *txrx_pdev; - struct cdp_vdev *txrx_vdev; - void *peer; - uint8_t num_keys = 0, peer_id; - struct wma_set_key_params key_params; - uint32_t def_key_idx = 0; - int opmode; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct wlan_objmgr_vdev *vdev; - - WMA_LOGD("STA key setup"); - - /* Get the txRx Pdev handle */ - txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!txrx_pdev) { - WMA_LOGE("%s:Invalid txrx pdev handle", __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - - peer = cdp_peer_find_by_addr(soc, txrx_pdev, - key_info->peer_macaddr.bytes, - &peer_id); - if (!peer) { - WMA_LOGE("%s:Invalid peer for key setting", __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - - txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); - if (!txrx_vdev) { - WMA_LOGE("%s:TxRx Vdev Handle is NULL", __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - opmode = cdp_get_opmode(soc, txrx_vdev); - - if (key_info->defWEPIdx == WMA_INVALID_KEY_IDX && - (key_info->encType == eSIR_ED_WEP40 || - key_info->encType == eSIR_ED_WEP104) && - opmode != wlan_op_mode_ap) { - vdev = - wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, - key_info->smesessionId, - WLAN_LEGACY_WMA_ID); - wma_read_cfg_wepkey(wma_handle, key_info->key, - &def_key_idx, &num_keys, vdev); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - key_info->defWEPIdx = def_key_idx; - } else { - num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; - if (key_info->encType != eSIR_ED_NONE) { - for (i = 0; i < num_keys; i++) { - if (key_info->key[i].keyDirection == - eSIR_TX_DEFAULT) { - key_info->defWEPIdx = i; - break; - } - } - } - } - qdf_mem_zero(&key_params, sizeof(key_params)); - key_params.vdev_id = key_info->smesessionId; - key_params.key_type = key_info->encType; - key_params.singl_tid_rc = key_info->singleTidRc; - key_params.unicast = true; - key_params.def_key_idx = key_info->defWEPIdx; - qdf_mem_copy((void *)key_params.peer_mac, - (const void *)key_info->peer_macaddr.bytes, - QDF_MAC_ADDR_SIZE); - for (i = 0; i < num_keys; i++) { - if (key_params.key_type != eSIR_ED_NONE && - !key_info->key[i].keyLength) - continue; - if (key_info->encType == eSIR_ED_TKIP) { - qdf_mem_copy(key_params.key_data, - key_info->key[i].key, 16); - qdf_mem_copy(&key_params.key_data[16], - &key_info->key[i].key[24], 8); - qdf_mem_copy(&key_params.key_data[24], - &key_info->key[i].key[16], 8); - } else - qdf_mem_copy(key_params.key_data, key_info->key[i].key, - key_info->key[i].keyLength); - if (key_info->encType == eSIR_ED_WPI) { - key_params.key_idx = key_info->key[i].keyId; - key_params.def_key_idx = key_info->key[i].keyId; - } else - key_params.key_idx = i; - - key_params.key_len = key_info->key[i].keyLength; - status = wma_setup_install_key_cmd(wma_handle, &key_params, - opmode); - if (status == QDF_STATUS_E_NOMEM) { - WMA_LOGE("%s:Failed to setup install key buf", - __func__); - key_info->status = QDF_STATUS_E_NOMEM; - goto out; - } - - WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i, - key_info->key[i].keyLength); - - if (status == QDF_STATUS_E_FAILURE) { - WMA_LOGE("%s:Failed to send install key command", - __func__); - key_info->status = QDF_STATUS_E_FAILURE; - goto out; - } - } - - /* In IBSS mode, set the BSS KEY for this peer - * BSS key is supposed to be cache into wma_handle - */ - if (wlan_op_mode_ibss == opmode) { - wma_set_ibsskey_helper(wma_handle, &wma_handle->ibsskey_info, - key_info->peer_macaddr); - } - - /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */ - key_info->status = QDF_STATUS_SUCCESS; -out: - qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params)); - if (key_info->sendRsp) - wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP, - (void *)key_info, 0); - else - qdf_mem_free(key_info); -} -#endif - /** * wma_process_update_edca_param_req() - update EDCA params * @handle: wma handle @@ -2749,13 +1922,12 @@ QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle, struct wmi_host_wme_vparams wmm_param[QCA_WLAN_AC_ALL]; tSirMacEdcaParamRecord *edca_record; int ac; - struct cdp_pdev *pdev; struct ol_tx_wmm_param_t ol_tx_wmm_param; uint8_t vdev_id; QDF_STATUS status; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - vdev_id = edca_params->bss_idx; + vdev_id = edca_params->vdev_id; if (!wma_is_vdev_valid(vdev_id)) { WMA_LOGE("%s: vdev id:%d is not active ", __func__, vdev_id); goto fail; @@ -2796,12 +1968,7 @@ QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle, else if (status == QDF_STATUS_E_FAILURE) goto fail; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (pdev) - cdp_set_wmm_param(soc, (struct cdp_pdev *)pdev, - ol_tx_wmm_param); - else - QDF_ASSERT(0); + cdp_set_wmm_param(soc, WMI_PDEV_ID_SOC, ol_tx_wmm_param); return QDF_STATUS_SUCCESS; @@ -3018,14 +2185,6 @@ static QDF_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, uint8_t vdev_id, return QDF_STATUS_SUCCESS; } -/** - * wma_tbttoffset_update_event_handler() - tbtt offset update handler - * @handle: wma handle - * @event: event buffer - * @len: data length - * - * Return: 0 for success or error code - */ int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event, uint32_t len) { @@ -3059,7 +2218,10 @@ int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event, } for (; (if_id < wma->max_bssid && vdev_map); vdev_map >>= 1, if_id++) { - if (!(vdev_map & 0x1) || (!(intf[if_id].handle))) + if (!intf[if_id].vdev) + continue; + + if (!(vdev_map & 0x1)) continue; bcn = intf[if_id].beacon; @@ -3122,7 +2284,6 @@ static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle, void wma_send_probe_rsp_tmpl(tp_wma_handle wma, tpSendProbeRespParams probe_rsp_info) { - struct cdp_vdev *vdev; uint8_t vdev_id; struct sAniProbeRspStruct *probe_rsp; @@ -3138,9 +2299,8 @@ void wma_send_probe_rsp_tmpl(tp_wma_handle wma, return; } - vdev = wma_find_vdev_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id); - if (!vdev) { - WMA_LOGE(FL("failed to get vdev handle")); + if (wma_find_vdev_id_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id)) { + WMA_LOGE(FL("failed to get vdev id")); return; } @@ -3157,17 +2317,23 @@ void wma_send_probe_rsp_tmpl(tp_wma_handle wma, QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id) { - struct vdev_up_params param = {0}; QDF_STATUS status = QDF_STATUS_SUCCESS; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev; + struct wma_txrx_node *iface; + + iface = &wma->interfaces[vdev_id]; + vdev = iface->vdev; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + WMA_LOGE(FL("failed to get mlme_obj")); + return QDF_STATUS_E_INVAL; + } + mlme_obj->proto.sta.assoc_id = 0; - param.vdev_id = vdev_id; - param.assoc_id = 0; - status = wma_send_vdev_up_to_fw(wma, ¶m, - wma->interfaces[vdev_id].bssid); + status = vdev_mgr_up_send(mlme_obj); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE(FL("failed to send vdev up")); - policy_mgr_set_do_hw_mode_change_flag( - wma->psoc, false); return status; } wma_set_sap_keepalive(wma, vdev_id); @@ -3188,7 +2354,6 @@ QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id) */ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info) { - struct cdp_vdev *vdev; uint8_t vdev_id; QDF_STATUS status; uint8_t *p2p_ie; @@ -3196,9 +2361,8 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info) wma_nofl_debug("Beacon update reason %d", bcn_info->reason); beacon = (struct sAniBeaconStruct *) (bcn_info->beacon); - vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id); - if (!vdev) { - WMA_LOGE("%s : failed to get vdev handle", __func__); + if (wma_find_vdev_id_by_addr(wma, beacon->macHdr.sa, &vdev_id)) { + WMA_LOGE("%s : failed to get vdev id", __func__); status = QDF_STATUS_E_INVAL; goto send_rsp; } @@ -3368,11 +2532,11 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, QDF_STATUS ret; #if !defined(REMOVE_PKT_LOG) uint8_t vdev_id = 0; - struct cdp_vdev *txrx_vdev; ol_txrx_pktdump_cb packetdump_cb; void *soc = cds_get_context(QDF_MODULE_ID_SOC); enum tx_status pktdump_status; #endif + struct wmi_mgmt_params mgmt_params = {}; if (!wma_handle) { WMA_LOGE("%s: wma handle is NULL", __func__); @@ -3396,15 +2560,16 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, #if !defined(REMOVE_PKT_LOG) vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id); - txrx_vdev = wma_find_vdev_by_id(wma_handle, vdev_id); + mgmt_params.vdev_id = vdev_id; packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb; pktdump_status = wma_mgmt_pktdump_status_map(status); if (packetdump_cb) - packetdump_cb(soc, txrx_vdev, + packetdump_cb(soc, WMI_PDEV_ID_SOC, vdev_id, buf, pktdump_status, TX_MGMT_PKT); #endif - ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL); + ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status, + &mgmt_params); if (ret != QDF_STATUS_SUCCESS) { WMA_LOGE("%s: Failed to process mgmt tx completion", __func__); @@ -3414,26 +2579,6 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, return 0; } -/** - * wma_extract_mgmt_offload_event_params() - Extract mgmt event params - * @params: Management offload event params - * @hdr: Management header to extract - * - * Return: None - */ -static void wma_extract_mgmt_offload_event_params( - struct mgmt_offload_event_params *params, - wmi_mgmt_hdr *hdr) -{ - params->tsf_l32 = hdr->tsf_l32; - params->chan_freq = hdr->chan_freq; - params->rate_kbps = hdr->rate_kbps; - params->rssi = hdr->rssi; - params->buf_len = hdr->buf_len; - params->tx_status = hdr->tx_status; - params->tx_retry_cnt = hdr->tx_retry_cnt; -} - /** * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler * @handle: wma handle @@ -3448,7 +2593,7 @@ int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params, { tp_wma_handle wma_handle = (tp_wma_handle)handle; WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; - wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; + wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) cmpl_event_params; @@ -3458,21 +2603,8 @@ int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params, } cmpl_params = param_buf->fixed_param; - if (ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_MGMT_ONLY && param_buf->mgmt_hdr) { - struct mgmt_offload_event_params params = {0}; - - wma_extract_mgmt_offload_event_params( - ¶ms, - (wmi_mgmt_hdr *)param_buf->mgmt_hdr); - ucfg_pkt_capture_mgmt_tx_completion(wma_handle->pdev, - cmpl_params->desc_id, - cmpl_params->status, - ¶ms); - } - - wma_process_mgmt_tx_completion(wma_handle, cmpl_params->desc_id, - cmpl_params->status); + wma_process_mgmt_tx_completion(wma_handle, + cmpl_params->desc_id, cmpl_params->status); return 0; } @@ -3532,22 +2664,9 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf, return -EINVAL; } - for (i = 0; i < num_reports; i++) { - if (ucfg_pkt_capture_get_pktcap_mode() & - PKT_CAPTURE_MODE_MGMT_ONLY && param_buf->mgmt_hdr) { - struct mgmt_offload_event_params params = {0}; - - wma_extract_mgmt_offload_event_params( - ¶ms, - &((wmi_mgmt_hdr *)param_buf->mgmt_hdr)[i]); - ucfg_pkt_capture_mgmt_tx_completion( - wma_handle->pdev, desc_ids[i], - status[i], ¶ms); - } - + for (i = 0; i < num_reports; i++) wma_process_mgmt_tx_completion(wma_handle, - desc_ids[i], status[i]); - } + desc_ids[i], status[i]); return 0; } @@ -3568,41 +2687,34 @@ void wma_process_update_opmode(tp_wma_handle wma_handle, enum wlan_phymode peer_phymode; uint32_t fw_phymode; enum wlan_peer_type peer_type; - struct wma_txrx_node *iface; - - iface = &wma_handle->interfaces[update_vht_opmode->smesessionId]; - if (iface->type == WMI_VDEV_TYPE_STA) { - fw_phymode = iface->chanmode; - } else { - pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev); - peer = wlan_objmgr_get_peer(psoc, pdev_id, - update_vht_opmode->peer_mac, - WLAN_LEGACY_WMA_ID); - if (!peer) { - WMA_LOGE("peer object invalid"); - return; - } - - peer_type = wlan_peer_get_peer_type(peer); - if (peer_type == WLAN_PEER_SELF) { - WMA_LOGE("self peer wrongly used"); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - return; - } + pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev); + peer = wlan_objmgr_get_peer(psoc, pdev_id, + update_vht_opmode->peer_mac, + WLAN_LEGACY_WMA_ID); + if (!peer) { + WMA_LOGE("peer object invalid"); + return; + } - wlan_peer_obj_lock(peer); - peer_phymode = wlan_peer_get_phymode(peer); - wlan_peer_obj_unlock(peer); + peer_type = wlan_peer_get_peer_type(peer); + if (peer_type == WLAN_PEER_SELF) { + WMA_LOGE("self peer wrongly used"); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - - fw_phymode = wma_host_to_fw_phymode(peer_phymode); + return; } + wlan_peer_obj_lock(peer); + peer_phymode = wlan_peer_get_phymode(peer); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); + + fw_phymode = wma_host_to_fw_phymode(peer_phymode); + ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle, fw_phymode); - wma_debug("ch_width: %d, fw phymode: %d", - ch_width, fw_phymode); + wma_debug("ch_width: %d, fw phymode: %d peer_phymode %d", + ch_width, fw_phymode, peer_phymode); if (ch_width < update_vht_opmode->opMode) { WMA_LOGE("%s: Invalid peer bw update %d, self bw %d", __func__, update_vht_opmode->opMode, @@ -3768,80 +2880,6 @@ QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value) return ret; } -/** - * wma_hidden_ssid_vdev_restart() - vdev restart for hidden ssid - * @wma_handle: wma handle - * @pReq: hidden ssid vdev restart request - * - * Return: none - */ -void wma_hidden_ssid_vdev_restart(tp_wma_handle wma, - tHalHiddenSsidVdevRestart *pReq) -{ - struct wma_txrx_node *intr = wma->interfaces; - struct wma_target_req *msg; - struct hidden_ssid_vdev_restart_params params; - QDF_STATUS status; - uint8_t vdev_id; - - vdev_id = pReq->sessionId; - if ((vdev_id != intr[vdev_id].vdev_restart_params.vdev_id) - || !((intr[vdev_id].type == WMI_VDEV_TYPE_AP) - && (intr[vdev_id].sub_type == 0))) { - WMA_LOGE(FL("invalid vdev_id %d"), vdev_id); - return; - } - - intr[vdev_id].vdev_restart_params.ssidHidden = pReq->ssidHidden; - WMA_LOGD(FL("hidden ssid set using IOCTL for vdev %d ssid_hidden %d"), - vdev_id, pReq->ssidHidden); - - msg = wma_fill_vdev_req(wma, vdev_id, - WMA_HIDDEN_SSID_VDEV_RESTART, - WMA_TARGET_REQ_TYPE_VDEV_START, - pReq, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE(FL("Failed to fill vdev request, vdev_id %d"), - vdev_id); - qdf_mem_free(pReq); - return; - } - - params.vdev_id = vdev_id; - params.ssid_len = intr[vdev_id].vdev_restart_params.ssid.ssid_len; - qdf_mem_copy(params.ssid, - intr[vdev_id].vdev_restart_params.ssid.ssid, - params.ssid_len); - params.flags = intr[vdev_id].vdev_restart_params.flags; - if (intr[vdev_id].vdev_restart_params.ssidHidden) - params.flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; - else - params.flags &= (0xFFFFFFFE); - params.requestor_id = intr[vdev_id].vdev_restart_params.requestor_id; - params.disable_hw_ack = - intr[vdev_id].vdev_restart_params.disable_hw_ack; - - params.mhz = intr[vdev_id].vdev_restart_params.chan.mhz; - params.band_center_freq1 = - intr[vdev_id].vdev_restart_params.chan.band_center_freq1; - params.band_center_freq2 = - intr[vdev_id].vdev_restart_params.chan.band_center_freq2; - params.info = intr[vdev_id].vdev_restart_params.chan.info; - params.reg_info_1 = intr[vdev_id].vdev_restart_params.chan.reg_info_1; - params.reg_info_2 = intr[vdev_id].vdev_restart_params.chan.reg_info_2; - - status = wmi_unified_hidden_ssid_vdev_restart_send(wma->wmi_handle, - ¶ms); - if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE(FL("Failed to send vdev restart command")); - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - qdf_mem_free(pReq); - } -} - - #ifdef WLAN_FEATURE_11W /** @@ -3932,6 +2970,7 @@ wma_is_ccmp_pn_replay_attack(tp_wma_handle wma, struct ieee80211_frame *wh, return ret; } +#ifdef WLAN_FEATURE_11W /** * wma_process_bip() - process mmie in rmf frame * @wma_handle: wma handle @@ -3982,7 +3021,7 @@ int wma_process_bip(tp_wma_handle wma_handle, wma_debug("key_cipher %d key_id %d", iface->key.key_cipher, key_id); - igtk = wma_get_igtk(iface, &key_len); + igtk = wma_get_igtk(iface, &key_len, key_id); switch (iface->key.key_cipher) { case WMI_CIPHER_AES_CMAC: if (wmi_service_enabled(wma_handle->wmi_handle, @@ -4042,6 +3081,7 @@ int wma_process_bip(tp_wma_handle wma_handle, return 0; } +#endif /** * wma_process_rmf_frame() - process rmf frame @@ -4146,8 +3186,8 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr + rx_pkt->pkt_meta.mpdu_hdr_len; - wma_debug("BSSID: "QDF_MAC_ADDR_STR" tsf_delta: %u", - QDF_MAC_ADDR_ARRAY(wh->i_addr3), + wma_debug("BSSID: "QDF_MAC_ADDR_FMT" tsf_delta: %u", + QDF_MAC_ADDR_REF(wh->i_addr3), rx_pkt->pkt_meta.tsf_delta); } else { if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) || @@ -4187,14 +3227,14 @@ wma_get_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac) wlan_objmgr_pdev_get_pdev_id(wma->pdev), peer_mac, WLAN_LEGACY_WMA_ID); if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", - peer_mac); + WMA_LOGE("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); return false; } is_pmf_enabled = mlme_get_peer_pmf_status(peer); wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - wma_nofl_debug("get is_pmf_enabled %d for %pM", - is_pmf_enabled, peer_mac); + wma_nofl_debug("get is_pmf_enabled %d for "QDF_MAC_ADDR_FMT, + is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac)); return is_pmf_enabled; } @@ -4301,7 +3341,6 @@ int wma_form_rx_packet(qdf_nbuf_t buf, #if !defined(REMOVE_PKT_LOG) ol_txrx_pktdump_cb packetdump_cb; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_vdev *txrx_vdev; #endif static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1; static uint8_t limit_prints_load_unload = RATE_LIMIT - 1; @@ -4362,7 +3401,7 @@ int wma_form_rx_packet(qdf_nbuf_t buf, * Fill in meta information needed by pe/lim * TODO: Try to maintain rx metainfo as part of skb->data. */ - rx_pkt->pkt_meta.channel = mgmt_rx_params->channel; + rx_pkt->pkt_meta.frequency = mgmt_rx_params->chan_freq; rx_pkt->pkt_meta.scan_src = mgmt_rx_params->flags; /* @@ -4411,9 +3450,9 @@ int wma_form_rx_packet(qdf_nbuf_t buf, * If the mpdu_data_len is greater than Max (2k), drop the frame */ if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) { - wma_err("Data Len %d greater than max, dropping frame from "QDF_MAC_ADDR_STR, + wma_err("Data Len %d greater than max, dropping frame from "QDF_MAC_ADDR_FMT, rx_pkt->pkt_meta.mpdu_data_len, - QDF_MAC_ADDR_ARRAY(wh->i_addr3)); + QDF_MAC_ADDR_REF(wh->i_addr3)); qdf_nbuf_free(buf); qdf_mem_free(rx_pkt); return -EINVAL; @@ -4433,8 +3472,8 @@ int wma_form_rx_packet(qdf_nbuf_t buf, (mgt_subtype == MGMT_SUBTYPE_DISASSOC || mgt_subtype == MGMT_SUBTYPE_DEAUTH || mgt_subtype == MGMT_SUBTYPE_ACTION)) { - if (wma_find_vdev_by_bssid( - wma_handle, wh->i_addr3, &vdev_id)) { + if (wma_find_vdev_id_by_bssid(wma_handle, wh->i_addr3, + &vdev_id) == QDF_STATUS_SUCCESS) { status = wma_check_and_process_rmf_frame(wma_handle, vdev_id, &wh, @@ -4442,8 +3481,8 @@ int wma_form_rx_packet(qdf_nbuf_t buf, buf); if (status) return status; - } else if (wma_find_vdev_by_addr(wma_handle, wh->i_addr1, - &vdev_id)) { + } else if (wma_find_vdev_id_by_addr(wma_handle, wh->i_addr1, + &vdev_id) == QDF_STATUS_SUCCESS) { status = wma_check_and_process_rmf_frame(wma_handle, vdev_id, &wh, @@ -4463,8 +3502,8 @@ int wma_form_rx_packet(qdf_nbuf_t buf, if (mgmt_rx_params->buf_len <= (sizeof(struct ieee80211_frame) + offsetof(struct wlan_bcn_frame, ie))) { - wma_debug("Dropping frame from "QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(wh->i_addr3)); + wma_debug("Dropping frame from "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(wh->i_addr3)); cds_pkt_return_packet(rx_pkt); return -EINVAL; } @@ -4478,12 +3517,11 @@ int wma_form_rx_packet(qdf_nbuf_t buf, #if !defined(REMOVE_PKT_LOG) packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb; - txrx_vdev = wma_find_vdev_by_id(wma_handle, - rx_pkt->pkt_meta.session_id); if ((mgt_type == IEEE80211_FC0_TYPE_MGT && mgt_subtype != MGMT_SUBTYPE_BEACON) && packetdump_cb) - packetdump_cb(soc, txrx_vdev, rx_pkt->pkt_buf, + packetdump_cb(soc, mgmt_rx_params->pdev_id, + rx_pkt->pkt_meta.session_id, rx_pkt->pkt_buf, QDF_STATUS_SUCCESS, RX_MGMT_PKT); #endif return 0; @@ -4577,6 +3615,18 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data, return -EINVAL; } + if (!mgmt_rx_params->chan_freq) { + /* + * It indicates that FW is legacy and is operating on + * channel numbers and it also indicates that BAND_6G support + * is not there as BAND_6G works only on frequencies and channel + * numbers can be treated as unique. + */ + mgmt_rx_params->chan_freq = wlan_reg_legacy_chan_to_freq( + wma_handle->pdev, + mgmt_rx_params->channel); + } + mgmt_rx_params->pdev_id = 0; mgmt_rx_params->rx_params = NULL; @@ -4805,7 +3855,6 @@ QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)mgmt_tx_params; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - struct cdp_vdev *txrx_vdev; if (!mgmt_params) { WMA_LOGE("%s: mgmt_params ptr passed is NULL", __func__); @@ -4824,17 +3873,15 @@ QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } - txrx_vdev = wma_handle->interfaces[mgmt_params->vdev_id].handle; - if (wmi_service_enabled(wma_handle->wmi_handle, wmi_service_mgmt_tx_wmi)) { status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle, mgmt_params); - } else if (txrx_vdev) { + } else { QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf) = mgmt_params->desc_id; - ret = cdp_mgmt_send_ext(soc, txrx_vdev, buf, + ret = cdp_mgmt_send_ext(soc, mgmt_params->vdev_id, buf, mgmt_params->tx_type, mgmt_params->use_6mbps, mgmt_params->chanfreq); diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.c index 8c6d8edce8f130fc6e76cb1b0c656b091cb73aae..e367fd7616b84372a6145d6c14191ca95eadd70a 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -34,99 +34,6 @@ #include "cdp_txrx_misc.h" #include -/** - * wma_add_bss_ndi_mode() - Process BSS creation request while adding NaN - * Data interface - * @wma: wma handle - * @add_bss: Parameters for ADD_BSS command - * - * Sends VDEV_START command to firmware - * Return: None - */ -void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss) -{ - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - struct wma_vdev_start_req req; - void *peer = NULL; - struct wma_target_req *msg; - uint8_t vdev_id, peer_id; - QDF_STATUS status; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - WMA_LOGD("%s: enter", __func__); - vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id); - if (!vdev) { - WMA_LOGE("%s: Failed to find vdev", __func__); - goto send_fail_resp; - } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - goto send_fail_resp; - } - - wma_set_bss_rate_flags(wma, vdev_id, add_bss); - - status = wma_create_peer(wma, pdev, vdev, add_bss->self_mac_addr, - WMI_PEER_TYPE_DEFAULT, vdev_id, false); - if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Failed to create peer", __func__); - goto send_fail_resp; - } - - peer = cdp_peer_find_by_addr(soc, pdev, add_bss->self_mac_addr, - &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - add_bss->self_mac_addr); - goto send_fail_resp; - } - - msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ, - WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGE("%s Failed to allocate vdev request vdev_id %d", - __func__, vdev_id); - goto send_fail_resp; - } - - add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer); - - /* - * beacon_intval, dtim_period, hidden_ssid, is_dfs, ssid - * will be ignored for NDI device. - */ - qdf_mem_zero(&req, sizeof(req)); - req.vdev_id = vdev_id; - req.chan = add_bss->currentOperChannel; - req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0; - req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1; - req.vht_capable = add_bss->vhtCapable; - req.max_txpow = add_bss->maxTxPower; - req.oper_mode = add_bss->operMode; - - status = wma_vdev_start(wma, &req, false); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - goto send_fail_resp; - } - WMA_LOGD("%s: vdev start request for NDI sent to target", __func__); - - /* Initialize protection mode to no protection */ - wma_vdev_set_param(wma->wmi_handle, vdev_id, - WMI_VDEV_PARAM_PROTECTION_MODE, IEEE80211_PROT_NONE); - - return; - -send_fail_resp: - add_bss->status = QDF_STATUS_E_FAILURE; - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); -} - /** * wma_add_sta_ndi_mode() - Process ADD_STA for NaN Data path * @wma: wma handle @@ -138,39 +45,19 @@ void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss) void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta) { enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN; - struct cdp_pdev *pdev; - struct cdp_vdev *vdev; - void *peer; + uint8_t pdev_id = WMI_PDEV_ID_SOC; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - u_int8_t peer_id; QDF_STATUS status; struct wma_txrx_node *iface; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - WMA_LOGE(FL("Failed to find pdev")); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } + iface = &wma->interfaces[add_sta->smesessionId]; + wma_debug("vdev: %d, peer_mac_addr: "QDF_MAC_ADDR_FMT, + add_sta->smesessionId, QDF_MAC_ADDR_REF(add_sta->staMac)); - vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); - if (!vdev) { - WMA_LOGE(FL("Failed to find vdev")); - add_sta->status = QDF_STATUS_E_FAILURE; - goto send_rsp; - } - - iface = &wma->interfaces[cdp_get_vdev_id(soc, vdev)]; - wma_debug("vdev: %d, peer_mac_addr: "QDF_MAC_ADDR_STR, - add_sta->smesessionId, QDF_MAC_ADDR_ARRAY(add_sta->staMac)); - - peer = cdp_peer_find_by_addr_and_vdev(soc, - pdev, vdev, - add_sta->staMac, &peer_id); - if (peer) { - WMA_LOGE(FL("NDI peer already exists, peer_addr %pM"), - add_sta->staMac); + if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, + add_sta->staMac)) { + WMA_LOGE(FL("NDI peer already exists, peer_addr "QDF_MAC_ADDR_FMT), + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_EXISTS; goto send_rsp; } @@ -182,47 +69,42 @@ void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta) * exists on the pDev. As this peer belongs to other vDevs, just return * here. */ - peer = cdp_peer_find_by_addr(soc, - pdev, - add_sta->staMac, &peer_id); - if (peer) { - WMA_LOGE(FL("vdev:%d, peer exists on other vdev with peer_addr %pM and peer_id %d"), - cdp_get_vdev_id(soc, vdev), - add_sta->staMac, peer_id); + if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) { + WMA_LOGE(FL("peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT), + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_EXISTS; goto send_rsp; } - status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, + status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_NAN_DATA, add_sta->smesessionId, false); if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE(FL("Failed to create peer for %pM"), add_sta->staMac); + WMA_LOGE(FL("Failed to create peer for "QDF_MAC_ADDR_FMT), + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = status; goto send_rsp; } - peer = cdp_peer_find_by_addr_and_vdev(soc, - pdev, vdev, - add_sta->staMac, &peer_id); - if (!peer) { - WMA_LOGE(FL("Failed to find peer handle using peer mac %pM"), - add_sta->staMac); + if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId, + add_sta->staMac)) { + WMA_LOGE(FL("Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT), + QDF_MAC_ADDR_REF(add_sta->staMac)); add_sta->status = QDF_STATUS_E_FAILURE; wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, - peer, false); + false); goto send_rsp; } - WMA_LOGD(FL("Moving peer %pM to state %d"), add_sta->staMac, state); - cdp_peer_state_update(soc, pdev, add_sta->staMac, state); + WMA_LOGD(FL("Moving peer "QDF_MAC_ADDR_FMT" to state %d"), + QDF_MAC_ADDR_REF(add_sta->staMac), state); + cdp_peer_state_update(soc, add_sta->staMac, state); - add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer); add_sta->nss = iface->nss; add_sta->status = QDF_STATUS_SUCCESS; send_rsp: - WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"), - add_sta->staMac, add_sta->status); + WMA_LOGD(FL("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)"), + QDF_MAC_ADDR_REF(add_sta->staMac), add_sta->status); wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0); } @@ -238,31 +120,10 @@ void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta) void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, tpDeleteStaParams del_sta) { - struct cdp_pdev *pdev; - void *peer; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE(FL("Failed to get pdev")); - del_sta->status = QDF_STATUS_E_FAILURE; - goto send_del_rsp; - } - - peer = cdp_peer_find_by_local_id(cds_get_context(QDF_MODULE_ID_SOC), - pdev, del_sta->staIdx); - if (!peer) { - WMA_LOGE(FL("Failed to get peer handle using peer id %d"), - del_sta->staIdx); - del_sta->status = QDF_STATUS_E_FAILURE; - goto send_del_rsp; - } - - wma_remove_peer(wma, cdp_peer_get_peer_mac_addr(soc, peer), - del_sta->smesessionId, peer, false); + wma_remove_peer(wma, del_sta->staMac, + del_sta->smesessionId, false); del_sta->status = QDF_STATUS_SUCCESS; -send_del_rsp: if (del_sta->respReqd) { WMA_LOGD(FL("Sending del rsp to umac (status: %d)"), del_sta->status); diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.h b/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.h index c2aa1f395dc96aee7b1307341575e14cc30ddc47..d774512347c063aa04518bf86fc57add7af56040 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.h +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_nan_datapath.h @@ -61,8 +61,6 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle, tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled; } -void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss); - void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, tpDeleteStaParams del_sta); @@ -91,12 +89,6 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle, return; } -static inline void wma_add_bss_ndi_mode(tp_wma_handle wma, - tpAddBssParams add_bss) -{ - return; -} - static inline void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, tpDeleteStaParams del_sta) { diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_ocb.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_ocb.c index f7f048ad35a4435d4127b934518df23fd52c451b..6770c40cf61a2036dabce6c0d4695706c3424bde 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_ocb.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_ocb.c @@ -26,6 +26,8 @@ #include "cds_utils.h" #include "cds_api.h" #include "wlan_ocb_ucfg_api.h" +#include "lim_utils.h" +#include "../../core/src/vdev_mgr_ops.h" /** * wma_start_ocb_vdev() - start OCB vdev @@ -35,37 +37,46 @@ */ static QDF_STATUS wma_start_ocb_vdev(struct ocb_config *config) { - struct wma_target_req *msg; - struct wma_vdev_start_req req; QDF_STATUS status; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *mlme_obj; + struct wlan_channel *des_chan; + uint8_t dot11_mode; - qdf_mem_zero(&req, sizeof(req)); - msg = wma_fill_vdev_req(wma, config->vdev_id, - WMA_OCB_SET_CONFIG_CMD, - WMA_TARGET_REQ_TYPE_VDEV_START, - (void *)config, 1000); - if (!msg) { - WMA_LOGE(FL("Failed to fill vdev req %d"), config->vdev_id); + vdev = wma->interfaces[config->vdev_id].vdev; + if (!vdev) { + wma_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } - return QDF_STATUS_E_NOMEM; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + wma_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; } - req.chan = cds_freq_to_chan(config->channels[0].chan_freq); - req.vdev_id = msg->vdev_id; - if (cds_chan_to_band(req.chan) == CDS_BAND_2GHZ) - req.dot11_mode = MLME_DOT11_MODE_11G; + des_chan = vdev->vdev_mlme.des_chan; + + des_chan->ch_freq = config->channels[0].chan_freq; + if (wlan_reg_is_24ghz_ch_freq(des_chan->ch_freq)) + dot11_mode = MLME_DOT11_MODE_11G; else - req.dot11_mode = MLME_DOT11_MODE_11A; + dot11_mode = MLME_DOT11_MODE_11A; + des_chan->ch_ieee = + wlan_reg_freq_to_chan(wma->pdev, des_chan->ch_freq); - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; + status = lim_set_ch_phy_mode(vdev, dot11_mode); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_FAILURE; - status = wma_vdev_start(wma, &req, false); - if (status != QDF_STATUS_SUCCESS) { - wma_remove_vdev_req(wma, req.vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_START); - WMA_LOGE(FL("vdev_start failed, status = %d"), status); - } + mlme_obj->mgmt.chainmask_info.num_rx_chain = 2; + mlme_obj->mgmt.chainmask_info.num_tx_chain = 2; + + status = wma_vdev_pre_start(config->vdev_id, false); + if (status != QDF_STATUS_SUCCESS) + return status; + + status = vdev_mgr_start_send(mlme_obj, false); return status; } diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_power.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_power.c index cec59a12c1182db67e1b0c4e2fad0470573a7b2f..934e5f0acf4e262bc70d82e48120f4a003c6032e 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_power.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -111,12 +111,16 @@ QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle, WMA_LOGE("%s: wma is NULL", __func__); return QDF_STATUS_E_FAILURE; } + + if (!wma_is_vdev_valid(vdev_id)) + return QDF_STATUS_E_INVAL; + WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d", vdev_id, param, value); iface = &wma->interfaces[vdev_id]; sta_ps_param.vdev_id = vdev_id; - sta_ps_param.param = param; + sta_ps_param.param_id = param; sta_ps_param.value = value; status = wmi_unified_sta_ps_cmd_send(wmi_handle, &sta_ps_param); if (QDF_IS_STATUS_ERROR(status)) @@ -126,13 +130,6 @@ QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle, } #ifdef QCA_IBSS_SUPPORT -/** - * wma_set_ibss_pwrsave_params() - set ibss power save parameter to fw - * @wma: wma handle - * @vdev_id: vdev id - * - * Return: 0 for success or error code. - */ QDF_STATUS wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id) { @@ -268,21 +265,21 @@ QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id, break; } - WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for %pM", - uapsd, peer_addr); + WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for "QDF_MAC_ADDR_FMT, + uapsd, QDF_MAC_ADDR_REF(peer_addr)); param.vdev_id = vdev_id; param.param = WMI_AP_PS_PEER_PARAM_UAPSD; param.value = uapsd; ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr, ¶m); if (QDF_IS_STATUS_ERROR(ret)) { - WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for %pM", - peer_addr); + WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr)); return ret; } - WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for %pM", - max_sp_len, peer_addr); + WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for "QDF_MAC_ADDR_FMT, + max_sp_len, QDF_MAC_ADDR_REF(peer_addr)); param.vdev_id = vdev_id; param.param = WMI_AP_PS_PEER_PARAM_MAX_SP; @@ -290,8 +287,8 @@ QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id, ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr, ¶m); if (QDF_IS_STATUS_ERROR(ret)) { - WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for %pM", - peer_addr); + WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_addr)); return ret; } @@ -343,49 +340,53 @@ void wma_set_tx_power(WMA_HANDLE handle, tp_wma_handle wma_handle = (tp_wma_handle) handle; uint8_t vdev_id; QDF_STATUS ret = QDF_STATUS_E_FAILURE; - struct cdp_vdev *vdev; + int8_t max_reg_power; + struct wma_txrx_node *iface; if (tx_pwr_params->dev_mode == QDF_SAP_MODE || tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) { - vdev = wma_find_vdev_by_addr(wma_handle, - tx_pwr_params->bssId.bytes, - &vdev_id); + ret = wma_find_vdev_id_by_addr(wma_handle, + tx_pwr_params->bssId.bytes, + &vdev_id); } else { - vdev = wma_find_vdev_by_bssid(wma_handle, - tx_pwr_params->bssId.bytes, - &vdev_id); + ret = wma_find_vdev_id_by_bssid(wma_handle, + tx_pwr_params->bssId.bytes, + &vdev_id); } - if (!vdev) { - WMA_LOGE("vdev handle is invalid for %pM", - tx_pwr_params->bssId.bytes); + if (ret) { + WMA_LOGE("vdev id is invalid for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes)); qdf_mem_free(tx_pwr_params); return; } if (!wma_is_vdev_up(vdev_id)) { - WMA_LOGE("%s: vdev id %d is not up for %pM", __func__, vdev_id, - tx_pwr_params->bssId.bytes); + WMA_LOGE("%s: vdev id %d is not up for "QDF_MAC_ADDR_FMT, + __func__, vdev_id, + QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes)); qdf_mem_free(tx_pwr_params); return; } + iface = &wma_handle->interfaces[vdev_id]; if (tx_pwr_params->power == 0) { /* set to default. Since the app does not care the tx power * we keep the previous setting */ - wma_handle->interfaces[vdev_id].tx_power = 0; + mlme_set_tx_power(iface->vdev, tx_pwr_params->power); ret = 0; goto end; } - if (wma_handle->interfaces[vdev_id].max_tx_power != 0) { + + max_reg_power = mlme_get_max_reg_power(iface->vdev); + + if (max_reg_power != 0) { /* make sure tx_power less than max_tx_power */ - if (tx_pwr_params->power > - wma_handle->interfaces[vdev_id].max_tx_power) { - tx_pwr_params->power = - wma_handle->interfaces[vdev_id].max_tx_power; + if (tx_pwr_params->power > max_reg_power) { + tx_pwr_params->power = max_reg_power; } } - if (wma_handle->interfaces[vdev_id].tx_power != tx_pwr_params->power) { + if (mlme_get_tx_power(iface->vdev) != tx_pwr_params->power) { /* tx_power changed, Push the tx_power to FW */ WMA_LOGI("%s: Set TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d", @@ -394,8 +395,7 @@ void wma_set_tx_power(WMA_HANDLE handle, WMI_VDEV_PARAM_TX_PWRLIMIT, tx_pwr_params->power); if (ret == QDF_STATUS_SUCCESS) - wma_handle->interfaces[vdev_id].tx_power = - tx_pwr_params->power; + mlme_set_tx_power(iface->vdev, tx_pwr_params->power); } else { /* no tx_power change */ ret = QDF_STATUS_SUCCESS; @@ -445,20 +445,23 @@ void wma_set_max_tx_power(WMA_HANDLE handle, tp_wma_handle wma_handle = (tp_wma_handle) handle; uint8_t vdev_id; QDF_STATUS ret = QDF_STATUS_E_FAILURE; - struct cdp_vdev *vdev; int8_t prev_max_power; + int8_t max_reg_power; + struct wma_txrx_node *iface; - vdev = wma_find_vdev_by_addr(wma_handle, tx_pwr_params->bssId.bytes, - &vdev_id); - if (!vdev) { - /* not in SAP array. Try the station/p2p array */ - vdev = wma_find_vdev_by_bssid(wma_handle, - tx_pwr_params->bssId.bytes, - &vdev_id); - } - if (!vdev) { - WMA_LOGE("vdev handle is invalid for %pM", - tx_pwr_params->bssId.bytes); + if (tx_pwr_params->dev_mode == QDF_SAP_MODE || + tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) { + ret = wma_find_vdev_id_by_addr(wma_handle, + tx_pwr_params->bssId.bytes, + &vdev_id); + } else { + ret = wma_find_vdev_id_by_bssid(wma_handle, + tx_pwr_params->bssId.bytes, + &vdev_id); + } + if (ret) { + WMA_LOGE("vdev id is invalid for "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes)); qdf_mem_free(tx_pwr_params); return; } @@ -469,27 +472,30 @@ void wma_set_max_tx_power(WMA_HANDLE handle, return; } - if (wma_handle->interfaces[vdev_id].max_tx_power == - tx_pwr_params->power) { + iface = &wma_handle->interfaces[vdev_id]; + if (mlme_get_max_reg_power(iface->vdev) == tx_pwr_params->power) { ret = QDF_STATUS_SUCCESS; goto end; } - prev_max_power = wma_handle->interfaces[vdev_id].max_tx_power; - wma_handle->interfaces[vdev_id].max_tx_power = tx_pwr_params->power; - if (wma_handle->interfaces[vdev_id].max_tx_power == 0) { + prev_max_power = mlme_get_max_reg_power(iface->vdev); + + mlme_set_max_reg_power(iface->vdev, tx_pwr_params->power); + + max_reg_power = mlme_get_max_reg_power(iface->vdev); + + if (max_reg_power == 0) { ret = QDF_STATUS_SUCCESS; goto end; } WMA_LOGI("Set MAX TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d", - wma_handle->interfaces[vdev_id].max_tx_power); + max_reg_power); ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id, WMI_VDEV_PARAM_TX_PWRLIMIT, - wma_handle->interfaces[vdev_id].max_tx_power); + max_reg_power); if (ret == QDF_STATUS_SUCCESS) - wma_handle->interfaces[vdev_id].tx_power = - wma_handle->interfaces[vdev_id].max_tx_power; + mlme_set_tx_power(iface->vdev, max_reg_power); else - wma_handle->interfaces[vdev_id].max_tx_power = prev_max_power; + mlme_set_max_reg_power(iface->vdev, prev_max_power); end: qdf_mem_free(tx_pwr_params); if (QDF_IS_STATUS_ERROR(ret)) @@ -560,14 +566,14 @@ static inline uint32_t wma_get_uapsd_mask(tpUapsd_Params uapsd_params) * @wma: wma handle * @vdev_id: vdev id * @enable: enable/disable - * @qpower_config: qpower configuration + * @power_config: power configuration * * Return: QDF_STATUS_SUCCESS for success or error code */ static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma, uint32_t vdev_id, uint8_t enable, - enum powersave_qpower_mode qpower_config, + enum powersave_mode power_config, bool enable_ps) { QDF_STATUS ret; @@ -618,21 +624,21 @@ static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma, } /* - * QPower is enabled by default in Firmware - * So Disable QPower explicitly + * Advanced power save is enabled by default in Firmware + * So Disable advanced power save explicitly */ ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, WMI_STA_PS_ENABLE_QPOWER, - qpower_config); + power_config); if (QDF_IS_STATUS_ERROR(ret)) { - WMA_LOGE("%s(%d) QPower Failed vdevId %d", - qpower_config ? "Enable" : "Disable", - qpower_config, vdev_id); + WMA_LOGE("%s(%d) Power Failed vdevId %d", + power_config ? "Enable" : "Disable", + power_config, vdev_id); return ret; } - WMA_LOGD("QPower %s(%d) vdevId %d", - qpower_config ? "Enabled" : "Disabled", - qpower_config, vdev_id); + WMA_LOGD("Power %s(%d) vdevId %d", + power_config ? "Enabled" : "Disabled", + power_config, vdev_id); /* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD */ ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, @@ -710,48 +716,18 @@ static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma, return QDF_STATUS_SUCCESS; } -/** - * wma_get_qpower_config() - get qpower configuration - * @wma: WMA handle - * - * Power Save Offload configuration: - * 0 -> Power save offload is disabled - * 1 -> Legacy Power save enabled + Deep sleep Disabled - * 2 -> QPower enabled + Deep sleep Disabled - * 3 -> Legacy Power save enabled + Deep sleep Enabled - * 4 -> QPower enabled + Deep sleep Enabled - * 5 -> Duty cycling QPower enabled - * - * Return: enum powersave_qpower_mode with below values - * QPOWER_DISABLED if QPOWER is disabled - * QPOWER_ENABLED if QPOWER is enabled - * QPOWER_DUTY_CYCLING if DUTY CYCLING QPOWER is enabled - */ -static enum powersave_qpower_mode wma_get_qpower_config(tp_wma_handle wma) +static uint8_t wma_get_power_config(tp_wma_handle wma) { - switch (wma->powersave_mode) { - case PS_QPOWER_NODEEPSLEEP: - case PS_QPOWER_DEEPSLEEP: - WMA_LOGD("QPOWER is enabled in power save mode %d", - wma->powersave_mode); - return QPOWER_ENABLED; - case PS_DUTY_CYCLING_QPOWER: - WMA_LOGD("DUTY cycling QPOWER is enabled in power save mode %d", - wma->powersave_mode); - return QPOWER_DUTY_CYCLING; + WMA_LOGD("POWER mode is %d", wma->powersave_mode); - default: - WMA_LOGD("QPOWER is disabled in power save mode %d", - wma->powersave_mode); - return QPOWER_DISABLED; - } + return wma->powersave_mode; } void wma_enable_sta_ps_mode(tpEnablePsParams ps_req) { uint32_t vdev_id = ps_req->sessionid; QDF_STATUS ret; - enum powersave_qpower_mode qpower_config; + enum powersave_mode power_config; struct wma_txrx_node *iface; t_wma_handle *wma_handle; @@ -768,11 +744,11 @@ void wma_enable_sta_ps_mode(tpEnablePsParams ps_req) return; } - qpower_config = wma_get_qpower_config(wma_handle); + power_config = wma_get_power_config(wma_handle); if (eSIR_ADDON_NOTHING == ps_req->psSetting) { - if (qpower_config && iface->uapsd_cached_val) { - qpower_config = 0; - WMA_LOGD("Qpower is disabled"); + if (power_config && iface->uapsd_cached_val) { + power_config = 0; + WMA_LOGD("Advanced power save is disabled"); } WMA_LOGD("Enable Sta Mode Ps vdevId %d", vdev_id); ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle, @@ -784,7 +760,7 @@ void wma_enable_sta_ps_mode(tpEnablePsParams ps_req) } ret = wma_set_force_sleep(wma_handle, vdev_id, false, - qpower_config, true); + power_config, true); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Enable Sta Ps Failed vdevId %d", vdev_id); return; @@ -813,13 +789,13 @@ void wma_enable_sta_ps_mode(tpEnablePsParams ps_req) vdev_id, uapsd_val); } - if (qpower_config && iface->uapsd_cached_val) { - qpower_config = 0; + if (power_config && iface->uapsd_cached_val) { + power_config = 0; WMA_LOGD("Qpower is disabled"); } WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id); ret = wma_set_force_sleep(wma_handle, vdev_id, true, - qpower_config, true); + power_config, true); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Enable Forced Sleep Failed vdevId %d", @@ -896,7 +872,7 @@ void wma_disable_sta_ps_mode(tpDisablePsParams ps_req) } } -QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower) +QDF_STATUS wma_set_power_config(uint8_t vdev_id, enum powersave_mode power) { tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); @@ -905,31 +881,24 @@ QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower) return QDF_STATUS_E_INVAL; } - WMA_LOGI("configuring qpower: %d", qpower); - wma->powersave_mode = qpower; + WMA_LOGI("configuring power: %d", power); + wma->powersave_mode = power; return wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, WMI_STA_PS_ENABLE_QPOWER, - wma_get_qpower_config(wma)); + wma_get_power_config(wma)); } -/** - * wma_enable_uapsd_mode() - enable uapsd mode in fw - * @wma: wma handle - * @ps_req: power save request - * - * Return: none - */ void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req) { QDF_STATUS ret; uint32_t vdev_id = ps_req->sessionid; uint32_t uapsd_val = 0; - enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma); + enum powersave_mode power_config = wma_get_power_config(wma); struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; - if (!iface->handle) { - WMA_LOGE("vdev id %d is not active", vdev_id); + if (!iface->vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, vdev_id); return; } @@ -950,14 +919,14 @@ void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req) return; } - if (qpower_config && uapsd_val) { - qpower_config = 0; - WMA_LOGD("Disable Qpower %d", vdev_id); + if (power_config && uapsd_val) { + power_config = 0; + WMA_LOGD("Disable power %d", vdev_id); } iface->uapsd_cached_val = uapsd_val; WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id); ret = wma_set_force_sleep(wma, vdev_id, true, - qpower_config, ps_req->uapsdParams.enable_ps); + power_config, ps_req->uapsdParams.enable_ps); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Enable Forced Sleep Failed vdevId %d", vdev_id); return; @@ -977,7 +946,7 @@ void wma_disable_uapsd_mode(tp_wma_handle wma, { QDF_STATUS ret; uint32_t vdev_id = ps_req->sessionid; - enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma); + enum powersave_mode power_config = wma_get_power_config(wma); WMA_LOGD("Disable Uapsd vdevId %d", vdev_id); @@ -997,7 +966,7 @@ void wma_disable_uapsd_mode(tp_wma_handle wma, /* Re enable Sta Mode Powersave with proper configuration */ ret = wma_set_force_sleep(wma, vdev_id, false, - qpower_config, true); + power_config, true); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Disable Forced Sleep Failed vdevId %d", vdev_id); return; @@ -1043,26 +1012,12 @@ static QDF_STATUS wma_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle, return ret; } -/** - * wma_trigger_uapsd_params() - set trigger uapsd parameter - * @wmi_handle: wma handle - * @vdev_id: vdev id - * @trigger_uapsd_params: trigger uapsd parameters - * - * This function sets the trigger uapsd - * params such as service interval, delay - * interval and suspend interval which - * will be used by the firmware to send - * trigger frames periodically when there - * is no traffic on the transmit side. - * - * Return: QDF_STATUS_SUCCESS for success or error code. - */ QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id, tp_wma_trigger_uapsd_params trigger_uapsd_params) { QDF_STATUS ret; + uint8_t *bssid; struct sta_uapsd_params uapsd_trigger_param; WMA_LOGD("Trigger uapsd params vdev id %d", vdev_id); @@ -1091,8 +1046,14 @@ QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id, uapsd_trigger_param.delay_interval = trigger_uapsd_params->delay_interval; + bssid = wma_get_vdev_bssid(wma_handle->interfaces[vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + return QDF_STATUS_E_FAILURE; + } ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle, - vdev_id, wma_handle->interfaces[vdev_id].bssid, + vdev_id, bssid, &uapsd_trigger_param, 1); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Fail to send uapsd param cmd for vdevid %d ret = %d", @@ -1103,18 +1064,11 @@ QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id, return ret; } -/** - * wma_disable_uapsd_per_ac() - disable uapsd per ac - * @wmi_handle: wma handle - * @vdev_id: vdev id - * @ac: access category - * - * Return: QDF_STATUS_SUCCESS for success or error code. - */ QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle, uint32_t vdev_id, enum uapsd_ac ac) { QDF_STATUS ret; + uint8_t *bssid; struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; struct sta_uapsd_params uapsd_trigger_param; enum uapsd_up user_priority; @@ -1161,8 +1115,14 @@ QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle, uapsd_trigger_param.suspend_interval = 0; uapsd_trigger_param.delay_interval = 0; + bssid = wma_get_vdev_bssid(wma_handle->interfaces[vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + return QDF_STATUS_E_FAILURE; + } ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle, - vdev_id, wma_handle->interfaces[vdev_id].bssid, + vdev_id, bssid, &uapsd_trigger_param, 1); if (QDF_IS_STATUS_ERROR(ret)) { WMA_LOGE("Fail to send auto trig cmd for vdevid %d ret = %d", @@ -1293,7 +1253,7 @@ QDF_STATUS wma_process_tx_power_limits(WMA_HANDLE handle, return QDF_STATUS_SUCCESS; } -#ifdef CONFIG_WMI_BCN_OFFLOAD +#ifdef WLAN_WMI_BCN /** * wma_add_p2p_ie() - add p2p IE * @frm: ptr where p2p ie needs to add @@ -1358,14 +1318,6 @@ static void wma_update_beacon_noa_ie(struct beacon_info *bcn, bcn->noa_ie = buf + bcn->len; } - if (bcn->len + sizeof(struct p2p_ie) + new_noa_sub_ie_len > - SIR_MAX_BEACON_SIZE) { - wma_err("exceed max beacon length, bcn->len %d, new_noa_sub_ie_len %d, p2p len %u", - bcn->len, new_noa_sub_ie_len, - (uint32_t)sizeof(struct p2p_ie)); - return; - } - bcn->noa_sub_ie_len = new_noa_sub_ie_len; wma_add_p2p_ie(bcn->noa_ie); p2p_ie = (struct p2p_ie *)bcn->noa_ie; @@ -1554,9 +1506,9 @@ void wma_process_set_mimops_req(tp_wma_handle wma_handle, else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_NO_LIMIT) mimops->htMIMOPSState = WMI_PEER_MIMO_PS_NONE; - wma_debug("htMIMOPSState = %d, sessionId = %d peerMac <"QDF_MAC_ADDR_STR">", + wma_debug("htMIMOPSState = %d, sessionId = %d peerMac <"QDF_MAC_ADDR_FMT">", mimops->htMIMOPSState, mimops->sessionId, - QDF_MAC_ADDR_ARRAY(mimops->peerMac)); + QDF_MAC_ADDR_REF(mimops->peerMac)); wma_set_peer_param(wma_handle, mimops->peerMac, WMI_PEER_MIMO_PS_STATE, mimops->htMIMOPSState, diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c index 8fc9acec04afeaeb9dd2c949402a5fc551dce006..3ca5ec0350d9714a44fe309662ec1dafe2b94c15 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c @@ -35,6 +35,7 @@ #include "wni_cfg.h" #include #include +#include #include "qdf_nbuf.h" #include "qdf_types.h" @@ -78,8 +79,13 @@ #include #include #include +#include #include "wlan_blm_api.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT /* FEATURE_WLAN_DIAG_SUPPORT */ +#include "host_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + #ifdef FEATURE_WLAN_EXTSCAN #define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED @@ -151,29 +157,33 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, chan_list->vht_en, chan_list->vht_24_en); for (i = 0; i < chan_list->numChan; ++i) { - chan_p->mhz = - cds_chan_to_freq(chan_list->chanParam[i].chanId); + chan_p->mhz = chan_list->chanParam[i].freq; chan_p->cfreq1 = chan_p->mhz; chan_p->cfreq2 = 0; - wma_handle->saved_chan.channel_list[i] = - chan_list->chanParam[i].chanId; + wma_handle->saved_chan.ch_freq_list[i] = + chan_list->chanParam[i].freq; if (chan_list->chanParam[i].dfsSet) { chan_p->is_chan_passive = 1; chan_p->dfs_set = 1; } + if (chan_list->chanParam[i].nan_disabled) + chan_p->nan_disabled = 1; + if (chan_p->mhz < WMA_2_4_GHZ_MAX_FREQ) { chan_p->phy_mode = MODE_11G; if (chan_list->vht_en && chan_list->vht_24_en) chan_p->allow_vht = 1; } else { chan_p->phy_mode = MODE_11A; - if (chan_list->vht_en) + if (chan_list->vht_en && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_p->mhz))) chan_p->allow_vht = 1; } - if (chan_list->ht_en) + if (chan_list->ht_en && + !(WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_p->mhz))) chan_p->allow_ht = 1; if (chan_list->he_en) @@ -184,19 +194,22 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, else if (chan_list->chanParam[i].quarter_rate) chan_p->quarter_rate = 1; + if (wlan_reg_is_6ghz_psc_chan_freq( + chan_p->mhz)) + chan_p->psc_channel = 1; + /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ /*TODO: WMI_SET_CHANNEL_REG_CLASSID */ chan_p->maxregpower = chan_list->chanParam[i].pwr; ch_params.ch_width = CH_WIDTH_160MHZ; - wlan_reg_set_channel_params(wma_handle->pdev, - chan_list->chanParam[i].chanId, 0, - &ch_params); - chan_p->max_bw_supported = - wma_map_phy_ch_bw_to_wmi_channel_width( - ch_params.ch_width); + wlan_reg_set_channel_params_for_freq(wma_handle->pdev, + chan_p->mhz, 0, + &ch_params); + chan_p->max_bw_supported = + wma_map_phy_ch_bw_to_wmi_channel_width(ch_params.ch_width); chan_p++; } @@ -357,13 +370,14 @@ static void wma_roam_scan_offload_set_params( params->rct_validity_timer = roam_req->rct_validity_timer; params->is_adaptive_11r = roam_req->is_adaptive_11r_connection; params->is_sae_same_pmk = roam_req->is_sae_single_pmk; - wma_debug("qos_caps %d, qos_enabled %d, ho_delay_for_rx %d, roam_scan_mode %d roam_preauth: retrycount %d, no_ack_timeout %d SAE Single PMK:%d", + params->enable_ft_im_roaming = roam_req->enable_ft_im_roaming; + wma_debug("qos_caps %d, qos_enabled %d, ho_delay_for_rx %d, roam_scan_mode %d SAE single pmk %d roam_preauth: retrycount %d, no_ack_timeout %d", params->roam_offload_params.qos_caps, params->roam_offload_params.qos_enabled, params->roam_offload_params.ho_delay_for_rx, params->mode, + params->is_sae_same_pmk, params->roam_offload_params.roam_preauth_retry_count, - params->roam_offload_params.roam_preauth_no_ack_timeout, - params->is_sae_same_pmk); + params->roam_offload_params.roam_preauth_no_ack_timeout); } #else static void wma_roam_scan_offload_set_params( @@ -498,19 +512,28 @@ wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle, params.traffic_threshold = roam_params->traffic_threshold; params.initial_dense_status = roam_params->initial_dense_status; - if (db2dbm_enabled) + if (db2dbm_enabled) { params.bg_scan_bad_rssi_thresh = roam_params->bg_scan_bad_rssi_thresh; - else + params.roam_data_rssi_threshold = + roam_params->roam_data_rssi_threshold; + } else { params.bg_scan_bad_rssi_thresh = - roam_params->bg_scan_bad_rssi_thresh - - WMA_NOISE_FLOOR_DBM_DEFAULT; + roam_params->bg_scan_bad_rssi_thresh - + WMA_NOISE_FLOOR_DBM_DEFAULT; + params.roam_data_rssi_threshold = + roam_params->roam_data_rssi_threshold - + WMA_NOISE_FLOOR_DBM_DEFAULT; + } params.bg_scan_client_bitmap = roam_params->bg_scan_client_bitmap; params.roam_bad_rssi_thresh_offset_2g = roam_params->roam_bad_rssi_thresh_offset_2g; if (params.roam_bad_rssi_thresh_offset_2g) params.flags |= WMI_ROAM_BG_SCAN_FLAGS_2G_TO_5G_ONLY; + params.roam_data_rssi_threshold_triggers = + roam_params->roam_data_rssi_threshold_triggers; + params.rx_data_inactivity_time = roam_params->rx_data_inactivity_time; /* * The current Noise floor in firmware is -96dBm. Penalty/Boost @@ -618,6 +641,7 @@ wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle, roam_params->bg_scan_bad_rssi_thresh, roam_params->bg_scan_client_bitmap, roam_params->roam_bad_rssi_thresh_offset_2g); + return status; } @@ -690,7 +714,7 @@ QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle, * wma_roam_scan_offload_chan_list() - set roam offload channel list * @wma_handle: wma handle * @chan_count: channel count - * @chan_list: channel list + * @chan_freq_list: channel list * @list_type: list type * @vdev_id: vdev id * @@ -700,7 +724,7 @@ QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle, */ QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, uint8_t chan_count, - uint8_t *chan_list, + uint32_t *chan_freq_list, uint8_t list_type, uint32_t vdev_id) { QDF_STATUS status; @@ -729,7 +753,7 @@ QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, for (i = 0; ((i < chan_count) && (i < SIR_ROAM_MAX_CHANNELS)); i++) { - chan_list_mhz[i] = cds_chan_to_freq(chan_list[i]); + chan_list_mhz[i] = chan_freq_list[i]; if (chan_buff) len += qdf_scnprintf(chan_buff + len, buf_len - len, " %d", chan_list_mhz[i]); @@ -1309,6 +1333,23 @@ static QDF_STATUS wma_roam_scan_offload_ap_profile(tp_wma_handle wma_handle, roam_req->min_rssi_params[DEAUTH_MIN_RSSI]; ap_profile.min_rssi_params[BMISS_MIN_RSSI] = roam_req->min_rssi_params[BMISS_MIN_RSSI]; + ap_profile.min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM] = + roam_req->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM]; + if (!db2dbm_enabled) { + ap_profile.min_rssi_params[DEAUTH_MIN_RSSI].min_rssi -= + WMA_NOISE_FLOOR_DBM_DEFAULT; + ap_profile.min_rssi_params[DEAUTH_MIN_RSSI].min_rssi &= + 0x000000ff; + + ap_profile.min_rssi_params[BMISS_MIN_RSSI].min_rssi -= + WMA_NOISE_FLOOR_DBM_DEFAULT; + ap_profile.min_rssi_params[BMISS_MIN_RSSI].min_rssi &= + 0x000000ff; + ap_profile.min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi -= + WMA_NOISE_FLOOR_DBM_DEFAULT; + ap_profile.min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi &= + 0x000000ff; + } ap_profile.score_delta_param[IDLE_ROAM_TRIGGER] = roam_req->score_delta_param[IDLE_ROAM_TRIGGER]; @@ -1424,8 +1465,8 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle, } for (i = 0; i < params->num_bssid_black_list; i++) - wma_debug("Blacklist bssid[%d]:" QDF_MAC_ADDR_STR, i, - QDF_MAC_ADDR_ARRAY(params->bssid_avoid_list[i].bytes)); + wma_debug("Blacklist bssid[%d]:" QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(params->bssid_avoid_list[i].bytes)); qdf_mem_copy(params->bssid_favored, roam_params->bssid_favored, MAX_BSSID_FAVORED * sizeof(struct qdf_mac_addr)); qdf_mem_copy(params->bssid_favored_factor, @@ -1436,8 +1477,8 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle, sizeof(struct reject_ap_config_params)); for (i = 0; i < params->num_bssid_preferred_list; i++) - wma_debug("Preferred Bssid[%d]:"QDF_MAC_ADDR_STR" score: %d", i, - QDF_MAC_ADDR_ARRAY(params->bssid_favored[i].bytes), + wma_debug("Preferred Bssid[%d]:"QDF_MAC_ADDR_FMT" score: %d", i, + QDF_MAC_ADDR_REF(params->bssid_favored[i].bytes), params->bssid_favored_factor[i]); if (params->lca_disallow_config_present) { @@ -1576,15 +1617,27 @@ void wma_send_roam_bss_load_config(WMA_HANDLE handle, { QDF_STATUS status; tp_wma_handle wma_handle = (tp_wma_handle) handle; + bool db2dbm_enabled; if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("WMA is closed, cannot send bss load config"); return; } - WMA_LOGD("%s: Sending bss load trig params vdev %u bss_load_threshold %u bss_load_sample_time: %u", + db2dbm_enabled = wmi_service_enabled(wma_handle->wmi_handle, + wmi_service_hw_db2dbm_support); + if (!db2dbm_enabled) { + params->rssi_threshold_5ghz -= WMA_NOISE_FLOOR_DBM_DEFAULT; + params->rssi_threshold_5ghz &= 0x000000ff; + + params->rssi_threshold_24ghz -= WMA_NOISE_FLOOR_DBM_DEFAULT; + params->rssi_threshold_24ghz &= 0x000000ff; + } + + WMA_LOGD("%s: Bss load trig params vdev %u threshold %u sample_time: %u 5Ghz RSSI threshold:%d 2.4G rssi threshold:%d", __func__, params->vdev_id, params->bss_load_threshold, - params->bss_load_sample_time); + params->bss_load_sample_time, params->rssi_threshold_5ghz, + params->rssi_threshold_24ghz); status = wmi_unified_send_bss_load_config(wma_handle->wmi_handle, params); @@ -1688,6 +1741,7 @@ wma_send_idle_roam_params(tp_wma_handle wma_handle, struct roam_offload_scan_req *roam_req) { QDF_STATUS status; + bool db2dbm_enabled; if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("WMA is closed, cannot send idle roam params"); @@ -1707,6 +1761,14 @@ wma_send_idle_roam_params(tp_wma_handle wma_handle, break; } + db2dbm_enabled = wmi_service_enabled(wma_handle->wmi_handle, + wmi_service_hw_db2dbm_support); + if (!db2dbm_enabled) { + roam_req->idle_roam_params.conn_ap_min_rssi -= + WMA_NOISE_FLOOR_DBM_DEFAULT; + roam_req->idle_roam_params.conn_ap_min_rssi &= 0x000000ff; + } + status = wmi_unified_send_idle_roam_params(wma_handle->wmi_handle, &roam_req->idle_roam_params); if (QDF_IS_STATUS_ERROR(status)) @@ -1742,6 +1804,35 @@ wma_send_idle_roam_params(tp_wma_handle wma_handle, {} #endif +/* wma_set_vdev_roam_reason_vsie: set vdev param + *WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE + * + *@wma: wma handler + *@vdev_id: vdev id + *@is_roam_reason_vsie_enabled: enable_roam_reason_vsie ini value + * + * Return: Void + */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void wma_set_vdev_roam_reason_vsie(tp_wma_handle wma, uint8_t vdev_id, + bool is_roam_reason_vsie_enabled) +{ + int ret; + + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE, + is_roam_reason_vsie_enabled); + if (ret) + WMA_LOGE("Failed to set vdev param %d", + WMI_VDEV_PARAM_ENABLE_DISABLE_ROAM_REASON_VSIE); +} +#else +static void wma_set_vdev_roam_reason_vsie(tp_wma_handle wma, uint8_t vdev_id, + bool is_roam_reason_vsie_enabled) +{ +} +#endif + /** * wma_process_roaming_config() - process roam request * @wma_handle: wma handle @@ -1758,7 +1849,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, wmi_start_scan_cmd_fixed_param scan_params; struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); uint32_t mode = 0; - struct wma_txrx_node *intr = NULL; + uint8_t enable_roam_reason_vsie = 0; struct wmi_bss_load_config *bss_load_cfg; if (!mac) { @@ -1775,8 +1866,6 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, wma_handle->interfaces[roam_req->sessionId].roaming_in_progress = false; switch (roam_req->Command) { case ROAM_SCAN_OFFLOAD_START: - intr = &wma_handle->interfaces[roam_req->sessionId]; - intr->delay_before_vdev_stop = roam_req->delay_before_vdev_stop; /* * Scan/Roam threshold parameters are translated from * fields of struct roam_offload_scan_req to WMITLV @@ -1800,6 +1889,10 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, if (qdf_status != QDF_STATUS_SUCCESS) break; + wlan_mlme_get_roam_reason_vsie_status(wma_handle->psoc, + &enable_roam_reason_vsie); + wma_set_vdev_roam_reason_vsie(wma_handle, roam_req->sessionId, + enable_roam_reason_vsie); wma_set_roam_triggers(wma_handle, &roam_req->roam_triggers); /* Opportunistic scan runs on a timer, value set by @@ -1842,7 +1935,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, qdf_status = wma_roam_scan_offload_chan_list(wma_handle, roam_req->ConnectedNetwork.ChannelCount, - &roam_req->ConnectedNetwork.ChannelCache[0], + &roam_req->ConnectedNetwork.chan_freq_cache[0], roam_req->ChannelCacheType, roam_req->sessionId); if ((qdf_status != QDF_STATUS_SUCCESS) && @@ -2087,7 +2180,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, */ qdf_status = wma_roam_scan_offload_chan_list(wma_handle, roam_req->ConnectedNetwork.ChannelCount, - &roam_req->ConnectedNetwork.ChannelCache[0], + &roam_req->ConnectedNetwork.chan_freq_cache[0], roam_req->ChannelCacheType, roam_req->sessionId); /* @@ -2200,7 +2293,7 @@ void wma_process_roam_invoke(WMA_HANDLE handle, roaminvoke->vdev_id); goto free_frame_buf; } - ch_hz = (A_UINT32)cds_chan_to_freq(roaminvoke->channel); + ch_hz = roaminvoke->ch_freq; wmi_unified_roam_invoke_cmd(wma_handle->wmi_handle, (struct wmi_roam_invoke_cmd *)roaminvoke, ch_hz); @@ -2474,10 +2567,14 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, } else { wma_fill_data_synch_event(wma, roam_synch_ind_ptr, param_buf); } - chan = param_buf->chan; - if (chan) + if (chan) { roam_synch_ind_ptr->chan_freq = chan->mhz; + roam_synch_ind_ptr->phy_mode = + wma_fw_to_host_phymode(WMI_GET_CHANNEL_MODE(chan)); + } else { + roam_synch_ind_ptr->phy_mode = WLAN_PHYMODE_AUTO; + } key = param_buf->key; key_ft = param_buf->key_ext; @@ -2576,7 +2673,6 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, return 0; } -#ifdef CRYPTO_SET_KEY_CONVERGED static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, uint32_t uc_cipher, uint32_t cipher_cap, @@ -2593,7 +2689,8 @@ static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, wlan_objmgr_pdev_get_pdev_id(wma->pdev), peer_mac, WLAN_LEGACY_WMA_ID); if (!peer) { - wma_err("Peer of peer_mac %pM not found", peer_mac); + wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); return; } wlan_crypto_set_peer_param(peer, WLAN_CRYPTO_PARAM_CIPHER_CAP, @@ -2603,8 +2700,8 @@ static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - wma_debug("Set unicast cipher %x and cap %x for %pM", uc_cipher, - cipher_cap, peer_mac); + wma_debug("Set unicast cipher %x and cap %x for "QDF_MAC_ADDR_FMT, + uc_cipher, cipher_cap, QDF_MAC_ADDR_REF(peer_mac)); } static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, @@ -2621,7 +2718,8 @@ static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, wlan_objmgr_pdev_get_pdev_id(wma->pdev), peer_mac, WLAN_LEGACY_WMA_ID); if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", peer_mac); + WMA_LOGE("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found", + QDF_MAC_ADDR_REF(peer_mac)); return; } @@ -2636,60 +2734,6 @@ static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, *cipher_cap = cap; } -#else - -static void wma_update_roamed_peer_unicast_cipher(tp_wma_handle wma, - uint32_t uc_cipher, - uint32_t cipher_cap, - uint8_t *peer_mac) -{ - struct wlan_objmgr_peer *peer; - - if (!peer_mac) { - WMA_LOGE("peer_mac is NULL"); - return; - } - - peer = wlan_objmgr_get_peer(wma->psoc, - wlan_objmgr_pdev_get_pdev_id(wma->pdev), - peer_mac, WLAN_LEGACY_WMA_ID); - if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", peer_mac); - return; - } - - wlan_peer_set_unicast_cipher(peer, uc_cipher); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - - wma_debug("Set unicast cipher %d for %pM", uc_cipher, peer_mac); -} - -static void wma_get_peer_uc_cipher(tp_wma_handle wma, uint8_t *peer_mac, - uint32_t *uc_cipher, uint32_t *cipher_cap) -{ - uint32_t cipher; - struct wlan_objmgr_peer *peer; - - if (!peer_mac) { - WMA_LOGE("peer_mac is NULL"); - return; - } - peer = wlan_objmgr_get_peer(wma->psoc, - wlan_objmgr_pdev_get_pdev_id(wma->pdev), - peer_mac, WLAN_LEGACY_WMA_ID); - if (!peer) { - WMA_LOGE("Peer of peer_mac %pM not found", peer_mac); - return; - } - - cipher = wlan_peer_get_unicast_cipher(peer); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - - if (uc_cipher) - *uc_cipher = cipher; -} -#endif - /** * wma_roam_update_vdev() - Update the STA and BSS * @wma: Global WMA Handle @@ -2705,82 +2749,94 @@ static void wma_roam_update_vdev(tp_wma_handle wma, struct roam_offload_synch_ind *roam_synch_ind_ptr) { - tDeleteBssParams *del_bss_params; tDeleteStaParams *del_sta_params; - tLinkStateParams *set_link_params; tAddStaParams *add_sta_params; uint32_t uc_cipher = 0, cipher_cap = 0; - uint8_t vdev_id; + uint8_t vdev_id, *bssid; vdev_id = roam_synch_ind_ptr->roamed_vdev_id; wma->interfaces[vdev_id].nss = roam_synch_ind_ptr->nss; - del_bss_params = qdf_mem_malloc(sizeof(*del_bss_params)); - if (!del_bss_params) - return; del_sta_params = qdf_mem_malloc(sizeof(*del_sta_params)); if (!del_sta_params) { - qdf_mem_free(del_bss_params); return; } - set_link_params = qdf_mem_malloc(sizeof(*set_link_params)); - if (!set_link_params) { - qdf_mem_free(del_bss_params); - qdf_mem_free(del_sta_params); - return; - } add_sta_params = qdf_mem_malloc(sizeof(*add_sta_params)); if (!add_sta_params) { - qdf_mem_free(del_bss_params); qdf_mem_free(del_sta_params); - qdf_mem_free(set_link_params); return; } - qdf_mem_zero(del_bss_params, sizeof(*del_bss_params)); qdf_mem_zero(del_sta_params, sizeof(*del_sta_params)); - qdf_mem_zero(set_link_params, sizeof(*set_link_params)); qdf_mem_zero(add_sta_params, sizeof(*add_sta_params)); - del_bss_params->smesessionId = vdev_id; del_sta_params->smesessionId = vdev_id; - qdf_mem_copy(del_bss_params->bssid, wma->interfaces[vdev_id].bssid, - QDF_MAC_ADDR_SIZE); - set_link_params->state = eSIR_LINK_PREASSOC_STATE; - qdf_mem_copy(set_link_params->self_mac_addr, - roam_synch_ind_ptr->self_mac.bytes, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(set_link_params->bssid, roam_synch_ind_ptr->bssid.bytes, - QDF_MAC_ADDR_SIZE); add_sta_params->staType = STA_ENTRY_SELF; add_sta_params->smesessionId = vdev_id; qdf_mem_copy(&add_sta_params->bssId, &roam_synch_ind_ptr->bssid.bytes, - QDF_MAC_ADDR_SIZE); - add_sta_params->staIdx = STA_INVALID_IDX; + QDF_MAC_ADDR_SIZE); add_sta_params->assocId = roam_synch_ind_ptr->aid; + bssid = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev); + if (!bssid) { + WMA_LOGE("%s: Failed to get bssid for vdev_%d", + __func__, vdev_id); + return; + } + /* * Get uc cipher of old peer to update new peer as it doesnt * change in roaming */ - wma_get_peer_uc_cipher(wma, del_bss_params->bssid, &uc_cipher, - &cipher_cap); + wma_get_peer_uc_cipher(wma, bssid, + &uc_cipher, &cipher_cap); wma_delete_sta(wma, del_sta_params); - wma_delete_bss(wma, del_bss_params); - wma_set_linkstate(wma, set_link_params); + wma_delete_bss(wma, vdev_id); + wma_add_bss_peer_sta(roam_synch_ind_ptr->self_mac.bytes, + roam_synch_ind_ptr->bssid.bytes, true); /* Update new peer's uc cipher */ wma_update_roamed_peer_unicast_cipher(wma, uc_cipher, cipher_cap, roam_synch_ind_ptr->bssid.bytes); - wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params); + wma_add_bss_lfr3(wma, roam_synch_ind_ptr->add_bss_params); wma_add_sta(wma, add_sta_params); - qdf_mem_copy(wma->interfaces[vdev_id].bssid, - roam_synch_ind_ptr->bssid.bytes, QDF_MAC_ADDR_SIZE); - qdf_mem_free(del_bss_params); - qdf_mem_free(set_link_params); + qdf_mem_copy(bssid, roam_synch_ind_ptr->bssid.bytes, + QDF_MAC_ADDR_SIZE); qdf_mem_free(add_sta_params); } +static void wma_update_phymode_on_roam(tp_wma_handle wma, uint8_t *bssid, + wmi_channel *chan, + struct wma_txrx_node *iface) +{ + enum wlan_phymode bss_phymode; + struct wlan_channel *des_chan; + struct vdev_mlme_obj *vdev_mlme; + uint8_t channel; + + channel = wlan_freq_to_chan(iface->mhz); + if (chan) + bss_phymode = + wma_fw_to_host_phymode(WMI_GET_CHANNEL_MODE(chan)); + else + wma_get_phy_mode_cb(channel, iface->chan_width, &bss_phymode); + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev); + + des_chan->ch_phymode = bss_phymode; + if (!vdev_mlme) + return; + /* Till conversion is not done in WMI we need to fill fw phy mode */ + vdev_mlme->mgmt.generic.phy_mode = wma_host_to_fw_phymode(bss_phymode); + + /* update new phymode to peer */ + wma_objmgr_set_peer_mlme_phymode(wma, bssid, bss_phymode); + + WMA_LOGD("LFR3: new phymode %d", bss_phymode); +} + /** * wma_post_roam_sync_failure: Send roam sync failure ind to fw * @wma: wma handle @@ -2812,7 +2868,6 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, tp_wma_handle wma = (tp_wma_handle) handle; struct roam_offload_synch_ind *roam_synch_ind_ptr = NULL; struct bss_description *bss_desc_ptr = NULL; - uint8_t channel; uint16_t ie_len = 0; int status = -EINVAL; qdf_time_t roam_synch_received = qdf_get_system_timestamp(); @@ -2999,23 +3054,15 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event, roam_synch_ind_ptr->join_rsp->vht_channel_width; /* * update phy_mode in wma to avoid mismatch in phymode between host and - * firmware. The phymode stored in interface[vdev_id].chanmode is sent - * to firmware as part of opmode update during either - vht opmode + * firmware. The phymode stored in peer->peer_mlme.phymode is + * sent to firmware as part of opmode update during either - vht opmode * action frame received or during opmode change detected while * processing beacon. Any mismatch of this value with firmware phymode * results in firmware assert. */ - channel = wlan_freq_to_chan(wma->interfaces[synch_event->vdev_id].mhz); - if (param_buf->chan) { - wma->interfaces[synch_event->vdev_id].chanmode = - WMI_GET_CHANNEL_MODE(param_buf->chan); - } else { - wma_get_phy_mode_cb(channel, - wma->interfaces[synch_event->vdev_id]. - chan_width, - &wma->interfaces[synch_event->vdev_id]. - chanmode); - } + wma_update_phymode_on_roam(wma, roam_synch_ind_ptr->bssid.bytes, + param_buf->chan, + &wma->interfaces[synch_event->vdev_id]); wma->csr_roam_synch_cb(wma->mac_context, roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_COMPLETE); @@ -3306,9 +3353,10 @@ int wma_roam_auth_offload_event_handler(WMA_HANDLE handle, uint8_t *event, } vdev_id = rso_auth_start_ev->vdev_id; - wma_debug("Received Roam auth offload event for bss:%pM vdev_id:%d", - ap_bssid.bytes, vdev_id); + wma_debug("Received Roam auth offload event for bss:"QDF_MAC_ADDR_FMT" vdev_id:%d", + QDF_MAC_ADDR_REF(ap_bssid.bytes), vdev_id); + lim_sae_auth_cleanup_retry(mac_ctx, vdev_id); status = wma->csr_roam_auth_event_handle_cb(mac_ctx, vdev_id, ap_bssid); if (QDF_IS_STATUS_ERROR(status)) { wma_err_rl("Trigger pre-auth failed"); @@ -3429,10 +3477,14 @@ wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf) buf_left -= buf_cons; buf_cons = qdf_snprint(temp, buf_left, - "validity_interval: %d candidate_list_cnt: %d resp_status: %d", + "validity_interval: %d candidate_list_cnt: %d resp_status: %d, bss_termination_timeout: %d, mbo_assoc_retry_timeout: %d", roam_info->btm_trig_data.validity_interval, roam_info->btm_trig_data.candidate_list_count, - roam_info->btm_trig_data.btm_resp_status); + roam_info->btm_trig_data.btm_resp_status, + roam_info->btm_trig_data. + btm_bss_termination_timeout, + roam_info->btm_trig_data. + btm_mbo_assoc_retry_timeout); buf_left -= buf_cons; temp += buf_cons; return; @@ -3451,8 +3503,17 @@ wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf) return; case WMI_ROAM_TRIGGER_REASON_LOW_RSSI: case WMI_ROAM_TRIGGER_REASON_PERIODIC: - buf_cons = qdf_snprint(temp, buf_left, "Cur_rssi_threshold: %d", - roam_info->rssi_trig_data.threshold); + /* + * Use roam_info->current_rssi get the RSSI of current AP after + * roam scan is triggered. This avoids discrepency with the + * next rssi threshold value printed in roam scan details. + * roam_info->rssi_trig_data.threshold gives the rssi threshold + * for the Low Rssi/Periodic scan trigger. + */ + buf_cons = qdf_snprint(temp, buf_left, + " Cur_Rssi threshold:%d Current AP RSSI: %d", + roam_info->rssi_trig_data.threshold, + roam_info->current_rssi); temp += buf_cons; buf_left -= buf_cons; return; @@ -3503,25 +3564,29 @@ wma_log_roam_scan_candidates(struct wmi_roam_candidate_info *ap, uint8_t num_entries) { uint16_t i; - char time[TIME_STRING_LEN]; + char time[TIME_STRING_LEN], time2[TIME_STRING_LEN]; - WMA_LOGD("%40s%40s", LINE_STR, LINE_STR); - WMA_LOGI("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s", - "AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI", - "SCR", "CU%", "SCR", "TOT_SCR"); - WMA_LOGD("%40s%40s", LINE_STR, LINE_STR); + wma_nofl_info("%62s%62s", LINE_STR, LINE_STR); + wma_nofl_info("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s %7s %6s %12s %20s", + "AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI", + "SCR", "CU%", "SCR", "TOT_SCR", "BL_RSN", "BL_SRC", + "BL_TSTAMP", "BL_TIMEOUT(ms)"); + wma_nofl_info("%62s%62s", LINE_STR, LINE_STR); if (num_entries > MAX_ROAM_CANDIDATE_AP) num_entries = MAX_ROAM_CANDIDATE_AP; for (i = 0; i < num_entries; i++) { mlme_get_converted_timestamp(ap->timestamp, time); - WMA_LOGI(QDF_MAC_ADDR_STR " %17s %4d %-4s %4d %3d/%-4d %2d/%-4d %5d", - QDF_MAC_ADDR_ARRAY(ap->bssid.bytes), time, ap->freq, - ((ap->type == 0) ? "C_AP" : - ((ap->type == 2) ? "R_AP" : "P_AP")), - ap->etp, ap->rssi, ap->rssi_score, ap->cu_load, - ap->cu_score, ap->total_score); + mlme_get_converted_timestamp(ap->bl_timestamp, time2); + wma_nofl_info(QDF_MAC_ADDR_FMT " %17s %4d %-4s %4d %3d/%-4d %2d/%-4d %5d %7d %7d %17s %9d", + QDF_MAC_ADDR_REF(ap->bssid.bytes), time, + ap->freq, + ((ap->type == 0) ? "C_AP" : + ((ap->type == 2) ? "R_AP" : "P_AP")), + ap->etp, ap->rssi, ap->rssi_score, ap->cu_load, + ap->cu_score, ap->total_score, ap->bl_reason, + ap->bl_source, time2, ap->bl_original_timeout); ap++; } } @@ -3780,8 +3845,8 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, wma->wmi_handle, event, &roam_info->data_11kv, 0, 0); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Roam 11kv stats extract failed vdev %d", - __func__, vdev_id); + wma_debug_rl("%s: Roam 11kv stats extract failed vdev %d", + __func__, vdev_id); qdf_mem_free(roam_info); goto err; } @@ -3803,22 +3868,23 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, * details. */ status = wmi_unified_extract_roam_trigger_stats( - wma->wmi_handle, event, - &roam_info->trigger, i); + wma->wmi_handle, event, + &roam_info->trigger, i); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Extract roam trigger stats failed vdev%d", - __func__, vdev_id); + wma_debug_rl("%s: Extract roam trigger stats failed vdev %d at %d iteration", + __func__, vdev_id, i); qdf_mem_free(roam_info); return -EINVAL; } /* Roam scan related details - Scan channel, scan type .. */ status = wmi_unified_extract_roam_scan_stats( - wma->wmi_handle, event, &roam_info->scan, i, - num_chan, num_ap); + wma->wmi_handle, event, + &roam_info->scan, i, + num_chan, num_ap); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Roam scan stats extract failed vdev %d", - __func__, vdev_id); + wma_debug_rl("%s: Roam scan stats extract failed vdev %d at %d iteration", + __func__, vdev_id, i); qdf_mem_free(roam_info); return -EINVAL; } @@ -3827,11 +3893,11 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, /* Roam result - Success/Failure status, failure reason */ status = wmi_unified_extract_roam_result_stats( - wma->wmi_handle, event, - &roam_info->result, i); + wma->wmi_handle, event, + &roam_info->result, i); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Roam result stats extract failed vdev %d", - __func__, vdev_id); + wma_debug_rl("%s: Roam result stats extract failed vdev %d at %d iteration", + __func__, vdev_id, i); qdf_mem_free(roam_info); return -EINVAL; } @@ -3841,8 +3907,8 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, wma->wmi_handle, event, &roam_info->data_11kv, i, num_rpt); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Roam 11kv stats extract failed vdev %d", - __func__, vdev_id); + wma_debug_rl("%s: Roam 11kv stats extract failed vdev %d at %d iteration", + __func__, vdev_id, i); qdf_mem_free(roam_info); return -EINVAL; } @@ -3952,18 +4018,18 @@ QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle, * Instead of making another infra, send the RSN-CAPS in MSB of * beacon Caps. */ - roam_offload_params->capability = *((uint32_t *)(&roam_req->rsn_caps)); + roam_offload_params->capability = *((uint16_t *)(&roam_req->rsn_caps)); roam_offload_params->capability <<= RSN_CAPS_SHIFT; roam_offload_params->capability |= ((*pCfgValue16) & 0xFFFF); roam_offload_params->ht_caps_info = - *(uint32_t *)&mac->mlme_cfg->ht_caps.ht_cap_info; + *(uint16_t *)&mac->mlme_cfg->ht_caps.ht_cap_info; roam_offload_params->ampdu_param = - *(uint32_t *)&mac->mlme_cfg->ht_caps.ampdu_params; + *(uint8_t *)&mac->mlme_cfg->ht_caps.ampdu_params; roam_offload_params->ht_ext_cap = - *(uint32_t *)&mac->mlme_cfg->ht_caps.ext_cap_info; + *(uint16_t *)&mac->mlme_cfg->ht_caps.ext_cap_info; val_len = ROAM_OFFLOAD_NUM_MCS_SET; if (wlan_mlme_get_cfg_str((uint8_t *)roam_offload_params->mcsset, @@ -4077,7 +4143,8 @@ int wma_rssi_breached_event_handler(void *handle, WMA_LOGD("%s: req_id: %u vdev_id: %d curr_rssi: %d", __func__, rssi.request_id, rssi.session_id, rssi.curr_rssi); - WMA_LOGI("%s: curr_bssid: %pM", __func__, rssi.curr_bssid.bytes); + WMA_LOGI("%s: curr_bssid: "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(rssi.curr_bssid.bytes)); mac->sme.rssi_threshold_breached_cb(mac->hdd_handle, &rssi); WMA_LOGD("%s: Invoke HDD rssi breached callback", __func__); @@ -4100,17 +4167,14 @@ wma_roam_ho_fail_handler(tp_wma_handle wma, uint32_t vdev_id, struct handoff_failure_ind *ho_failure_ind; struct scheduler_msg sme_msg = { 0 }; QDF_STATUS qdf_status; - struct reject_ap_info ap_info; - - ap_info.bssid = bssid; - ap_info.reject_ap_type = DRIVER_AVOID_TYPE; - wlan_blm_add_bssid_to_reject_list(wma->pdev, &ap_info); ho_failure_ind = qdf_mem_malloc(sizeof(*ho_failure_ind)); if (!ho_failure_ind) return; ho_failure_ind->vdev_id = vdev_id; + ho_failure_ind->bssid = bssid; + sme_msg.type = eWNI_SME_HO_FAIL_IND; sme_msg.bodyptr = ho_failure_ind; sme_msg.bodyval = 0; @@ -4165,99 +4229,43 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id) } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ -/** - * wma_set_channel() - set channel - * @wma: wma handle - * @params: switch channel parameters - * - * Return: none - */ -void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) +QDF_STATUS wma_pre_chan_switch_setup(uint8_t vdev_id) { - struct wma_vdev_start_req req; - struct wma_target_req *msg; QDF_STATUS status = QDF_STATUS_SUCCESS; - uint8_t vdev_id, peer_id; - void *peer; - struct cdp_pdev *pdev; - struct wma_txrx_node *intr = wma->interfaces; - struct policy_mgr_hw_mode_params hw_mode = {0}; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *intr; uint16_t beacon_interval_ori; - enum wlan_vdev_sm_evt event; - - WMA_LOGD("%s: Enter", __func__); - if (!wma_find_vdev_by_addr(wma, params->selfStaMacAddr, &vdev_id)) { - WMA_LOGP("%s: Failed to find vdev id for %pM", - __func__, params->selfStaMacAddr); - status = QDF_STATUS_E_FAILURE; - goto send_resp; - } - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); - status = QDF_STATUS_E_FAILURE; - goto send_resp; - } - - peer = cdp_peer_find_by_addr(soc, - pdev, - intr[vdev_id].bssid, &peer_id); - - qdf_mem_zero(&req, sizeof(req)); - req.vdev_id = vdev_id; - req.chan = params->channelNumber; - req.chan_width = params->ch_width; - - if (params->ch_width == CH_WIDTH_10MHZ) - req.is_half_rate = 1; - else if (params->ch_width == CH_WIDTH_5MHZ) - req.is_quarter_rate = 1; - - req.vht_capable = params->vhtCapable; - req.ch_center_freq_seg0 = params->ch_center_freq_seg0; - req.ch_center_freq_seg1 = params->ch_center_freq_seg1; - req.dot11_mode = params->dot11_mode; - wma_update_vdev_he_capable(&req, params); - - WMA_LOGI(FL("vht_capable: %d, dot11_mode: %d"), - req.vht_capable, req.dot11_mode); - - status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode); - if (!QDF_IS_STATUS_SUCCESS(status)) - WMA_LOGE("policy_mgr_get_current_hw_mode failed"); - - if (params->nss == 2) { - req.preferred_rx_streams = 2; - req.preferred_tx_streams = 2; - } else { - req.preferred_rx_streams = 1; - req.preferred_tx_streams = 1; + bool restart; + uint16_t reduced_beacon_interval; + struct vdev_mlme_obj *mlme_obj; + struct wlan_objmgr_vdev *vdev; + + if (!wma) { + pe_err("wma is NULL"); + return QDF_STATUS_E_FAILURE; + } + intr = &wma->interfaces[vdev_id]; + if (!intr) { + pe_err("wma txrx node is NULL"); + return QDF_STATUS_E_FAILURE; + } + vdev = intr->vdev; + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!mlme_obj) { + pe_err("vdev component object is NULL"); + return QDF_STATUS_E_FAILURE; } - req.max_txpow = params->maxTxPower; - req.beacon_intval = 100; - req.dtim_period = 1; - req.is_dfs = params->isDfsChannel; - req.cac_duration_ms = params->cac_duration_ms; - req.dfs_regdomain = params->dfs_regdomain; + restart = + wma_get_channel_switch_in_progress(intr); + if (restart && intr->beacon_filter_enabled) + wma_remove_beacon_filter(wma, &intr->beacon_filter); - /* In case of AP mode, once radar is detected, we need to - * issuse VDEV RESTART, so we making is_channel_switch as - * true - */ - if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) || - (params->restart_on_chan_switch == true)) { - req.hidden_ssid = intr[vdev_id].vdev_restart_params.ssidHidden; - } + reduced_beacon_interval = + wma->mac_context->sap.SapDfsInfo.reduced_beacon_interval; + if (wma_is_vdev_in_ap_mode(wma, vdev_id) && reduced_beacon_interval) { - if (params->restart_on_chan_switch == true && - wma->interfaces[req.vdev_id].beacon_filter_enabled) - wma_remove_beacon_filter(wma, - &wma->interfaces[req.vdev_id].beacon_filter); - if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) && - (params->reduced_beacon_interval)) { /* Reduce the beacon interval just before the channel switch. * This would help in reducing the downtime on the STA side * (which is waiting for beacons from the AP to resume back @@ -4268,73 +4276,60 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) */ WMA_LOGD("%s: Changing beacon interval to %d", - __func__, params->reduced_beacon_interval); + __func__, reduced_beacon_interval); /* Add a timer to reset the beacon interval back*/ - beacon_interval_ori = req.beacon_intval; - req.beacon_intval = params->reduced_beacon_interval; + beacon_interval_ori = mlme_obj->proto.generic.beacon_interval; + mlme_obj->proto.generic.beacon_interval = + reduced_beacon_interval; if (wma_fill_beacon_interval_reset_req(wma, - req.vdev_id, + vdev_id, beacon_interval_ori, RESET_BEACON_INTERVAL_TIMEOUT)) { WMA_LOGD("%s: Failed to fill beacon interval reset req", - __func__); + __func__); } } - msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ, - WMA_TARGET_REQ_TYPE_VDEV_START, params, - WMA_VDEV_START_REQUEST_TIMEOUT); - if (!msg) { - WMA_LOGP("%s: Failed to fill channel switch request for vdev %d", - __func__, req.vdev_id); - status = QDF_STATUS_E_NOMEM; - goto send_resp; - } + status = wma_vdev_pre_start(vdev_id, restart); - status = wma_vdev_start(wma, &req, wma_get_channel_switch_in_progress( - &wma->interfaces[req.vdev_id])); - 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; - } + return status; +} +QDF_STATUS wma_post_chan_switch_setup(uint8_t vdev_id) +{ + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *intr; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct wlan_channel *des_chan; + cdp_config_param_type val; + + if (!wma) { + pe_err("wma is NULL"); + return QDF_STATUS_E_FAILURE; + } + intr = &wma->interfaces[vdev_id]; + if (!intr) { + pe_err("wma txrx node is NULL"); + return QDF_STATUS_E_FAILURE; + } /* * Record monitor mode channel here in case HW * indicate RX PPDU TLV with invalid channel number. */ - if (intr[vdev_id].type == WMI_VDEV_TYPE_MONITOR) - cdp_record_monitor_chan_num(soc, pdev, req.chan); - - return; -send_resp: - WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__, - params->channelNumber, params->ch_width, - params->maxTxPower, - status); - params->status = status; - - /* For non-STA START failure send channel switch resp */ - if (intr[vdev_id].type == WMI_VDEV_TYPE_MONITOR || - wma_is_vdev_in_ap_mode(wma, vdev_id) || - mlme_is_chan_switch_in_progress(intr[vdev_id].vdev)) { - mlme_set_chan_switch_in_progress(intr[vdev_id].vdev, false); - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - (void *)params, 0); - return; + if (intr->type == WMI_VDEV_TYPE_MONITOR) { + des_chan = intr->vdev->vdev_mlme.des_chan; + val.cdp_pdev_param_monitor_chan = des_chan->ch_ieee; + cdp_txrx_set_pdev_param(soc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_MONITOR_CHANNEL, val); + val.cdp_pdev_param_mon_freq = des_chan->ch_freq; + cdp_txrx_set_pdev_param(soc, + wlan_objmgr_pdev_get_pdev_id(wma->pdev), + CDP_MONITOR_FREQUENCY, val); } - - /* - * For STA START failure send WLAN_VDEV_SM_EV_START_RESP to move SM to - * proper state - */ - event = WLAN_VDEV_SM_EV_START_RESP; - wlan_vdev_mlme_sm_deliver_evt(intr[vdev_id].vdev, event, - sizeof(*params), params); + return QDF_STATUS_SUCCESS; } #ifdef FEATURE_WLAN_ESE @@ -4350,31 +4345,11 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) static QDF_STATUS wma_plm_start(tp_wma_handle wma, struct plm_req_params *params) { - uint32_t num_channels; - uint32_t *channel_list = NULL; - uint32_t i; QDF_STATUS status; WMA_LOGD("PLM Start"); - num_channels = params->plm_num_ch; - - if (num_channels) { - channel_list = qdf_mem_malloc(sizeof(uint32_t) * num_channels); - if (!channel_list) - return QDF_STATUS_E_FAILURE; - - for (i = 0; i < num_channels; i++) { - channel_list[i] = params->plm_ch_list[i]; - - if (channel_list[i] < WMA_NLO_FREQ_THRESH) - channel_list[i] = - cds_chan_to_freq(channel_list[i]); - } - } - status = wmi_unified_plm_start_cmd(wma->wmi_handle, params, - channel_list); - qdf_mem_free(channel_list); + status = wmi_unified_plm_start_cmd(wma->wmi_handle, params); if (QDF_IS_STATUS_ERROR(status)) return status; @@ -4551,12 +4526,6 @@ void wma_register_extscan_event_handler(tp_wma_handle wma_handle) wmi_passpoint_match_event_id, wma_passpoint_match_event_handler, WMA_RX_SERIALIZER_CTX); - - /* Register BTM reject list event handler */ - wmi_unified_register_event_handler(wma_handle->wmi_handle, - wmi_roam_blacklist_event_id, - wma_handle_btm_blacklist_event, - WMA_RX_SERIALIZER_CTX); } /** @@ -4996,7 +4965,7 @@ int wma_extscan_hotlist_match_event_handler(void *handle, return -ENOMEM; dest_ap = &dest_hotlist->ap[0]; - dest_hotlist->numOfAps = event->total_entries; + dest_hotlist->numOfAps = numap; dest_hotlist->requestId = event->config_request_id; if (event->first_entry_index + @@ -5180,8 +5149,7 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info, } if (total_scan_num_results > param_buf->num_bssid_list) { - WMA_LOGE("%s:total_scan_num_results %d, num_bssid_list %d", - __func__, + wma_err("total_scan_num_results %d, num_bssid_list %d", total_scan_num_results, param_buf->num_bssid_list); return -EINVAL; @@ -6018,6 +5986,7 @@ static void wma_invalid_roam_reason_handler(tp_wma_handle wma_handle, } else if (notif == WMI_ROAM_NOTIF_ROAM_ABORT) { wma_handle->interfaces[vdev_id].roaming_in_progress = false; op_code = SIR_ROAMING_ABORT; + lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id); } else { WMA_LOGD(FL("Invalid notif %d"), notif); return; @@ -6149,11 +6118,14 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, bssid.bytes[3] = wmi_event->notif_params >> 24 & 0xFF; bssid.bytes[4] = wmi_event->notif_params1 >> 0 & 0xFF; bssid.bytes[5] = wmi_event->notif_params1 >> 8 & 0xFF; - WMA_LOGE("mac addr to avoid %pM", bssid.bytes); + WMA_LOGE("mac addr to avoid "QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(bssid.bytes)); wma_handle_hw_mode_transition(wma_handle, param_buf); wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id, bssid); wma_handle->interfaces[wmi_event->vdev_id].roaming_in_progress = false; + lim_sae_auth_cleanup_retry(wma_handle->mac_context, + wmi_event->vdev_id); break; #endif case WMI_ROAM_REASON_INVALID: @@ -6169,6 +6141,8 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, if (!roam_synch_data) return -ENOMEM; + lim_sae_auth_cleanup_retry(wma_handle->mac_context, + wmi_event->vdev_id); roam_synch_data->roamed_vdev_id = wmi_event->vdev_id; wma_handle->csr_roam_synch_cb(wma_handle->mac_context, roam_synch_data, NULL, @@ -6266,6 +6240,7 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, int len = 0; uint8_t *buf_ptr, i; uint8_t *channel_list; + uint32_t *chan_freq_list; len += sizeof(wmi_obss_scan_enable_cmd_fixed_param); @@ -6276,6 +6251,10 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, len += WMI_TLV_HDR_SIZE; len += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t)); + /* length calculation for chan_freqs */ + len += WMI_TLV_HDR_SIZE; + len += sizeof(uint32_t) * req->channel_count; + WMA_LOGE("cmdlen %d vdev_id %d channel count %d iefield_len %d", len, req->bss_id, req->channel_count, req->iefield_len); @@ -6325,7 +6304,8 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, channel_list = (uint8_t *) buf_ptr; for (i = 0; i < req->channel_count; i++) { - channel_list[i] = req->channels[i]; + channel_list[i] = + wlan_reg_freq_to_chan(wma->pdev, req->chan_freq_list[i]); WMA_LOGD("Ch[%d]: %d ", i, channel_list[i]); } @@ -6335,6 +6315,20 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, qdf_roundup(1, sizeof(uint32_t))); buf_ptr += WMI_TLV_HDR_SIZE; + buf_ptr += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t)); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + sizeof(uint32_t) * req->channel_count); + buf_ptr += WMI_TLV_HDR_SIZE; + + chan_freq_list = (uint32_t *)buf_ptr; + for (i = 0; i < req->channel_count; i++) { + chan_freq_list[i] = req->chan_freq_list[i]; + WMA_LOGD("freq[%u]: %u ", i, chan_freq_list[i]); + } + + buf_ptr += sizeof(uint32_t) * req->channel_count; + status = wmi_unified_cmd_send(wma->wmi_handle, buf, len, WMI_OBSS_SCAN_ENABLE_CMDID); if (QDF_IS_STATUS_ERROR(status)) @@ -6343,6 +6337,38 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, return status; } +static enum blm_reject_ap_reason wma_get_reject_reason(uint32_t reason) +{ + switch(reason) { + case WMI_BL_REASON_NUD_FAILURE: + return REASON_NUD_FAILURE; + case WMI_BL_REASON_STA_KICKOUT: + return REASON_STA_KICKOUT; + case WMI_BL_REASON_ROAM_HO_FAILURE: + return REASON_ROAM_HO_FAILURE; + case WMI_BL_REASON_ASSOC_REJECT_POOR_RSSI: + return REASON_ASSOC_REJECT_POOR_RSSI; + case WMI_BL_REASON_ASSOC_REJECT_OCE: + return REASON_ASSOC_REJECT_OCE; + case WMI_BL_REASON_USERSPACE_BL: + return REASON_USERSPACE_BL; + case WMI_BL_REASON_USERSPACE_AVOID_LIST: + return REASON_USERSPACE_AVOID_LIST; + case WMI_BL_REASON_BTM_DIASSOC_IMMINENT: + return REASON_BTM_DISASSOC_IMMINENT; + case WMI_BL_REASON_BTM_BSS_TERMINATION: + return REASON_BTM_BSS_TERMINATION; + case WMI_BL_REASON_BTM_MBO_RETRY: + return REASON_BTM_MBO_RETRY; + case WMI_BL_REASON_REASSOC_RSSI_REJECT: + return REASON_REASSOC_RSSI_REJECT; + case WMI_BL_REASON_REASSOC_NO_MORE_STAS: + return REASON_REASSOC_NO_MORE_STAS; + default: + return REASON_UNKNOWN; + } +} + int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info, uint32_t len) { @@ -6402,9 +6428,11 @@ int wma_handle_btm_blacklist_event(void *handle, uint8_t *cmd_param_info, WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_list->bssid, roam_blacklist->bssid.bytes); roam_blacklist->timeout = src_list->timeout; - roam_blacklist->received_time = - qdf_do_div(qdf_get_monotonic_boottime(), - QDF_MC_TIMER_TO_MS_UNIT); + roam_blacklist->received_time = src_list->timestamp; + roam_blacklist->original_timeout = src_list->original_timeout; + roam_blacklist->reject_reason = + wma_get_reject_reason(src_list->reason); + roam_blacklist->source = src_list->source; roam_blacklist++; src_list++; } @@ -6428,7 +6456,7 @@ QDF_STATUS wma_set_roam_triggers(tp_wma_handle wma, void wma_register_pmkid_req_event_handler(tp_wma_handle wma_handle) { if (!wma_handle) { - WMA_LOGE("%s: pmkid req wma_handle is NULL", __func__); + wma_err("%s: pmkid req wma_handle is NULL", __func__); return; } @@ -6451,31 +6479,31 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event, QDF_STATUS status; if (!event) { - WMA_LOGE("%s: received null event from target", __func__); + wma_err("%s: received null event from target", __func__); return -EINVAL; } param_buf = (WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *)event; if (!param_buf) { - WMA_LOGE("%s: received null buf from target", __func__); + wma_err("%s: received null buf from target", __func__); return -EINVAL; } roam_pmkid_req_ev = param_buf->fixed_param; if (!roam_pmkid_req_ev) { - WMA_LOGE("%s: received null event data from target", __func__); + wma_err("%s: received null event data from target", __func__); return -EINVAL; } if (roam_pmkid_req_ev->vdev_id >= wma->max_bssid) { - WMA_LOGE("%s: received invalid vdev_id %d", + wma_err("%s: received invalid vdev_id %d", __func__, roam_pmkid_req_ev->vdev_id); return -EINVAL; } num_entries = param_buf->num_pmkid_request; if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) { - WMA_LOGE("%s: num bssid entries:%d exceeds maximum value", + wma_err("%s: num bssid entries:%d exceeds maximum value", __func__, num_entries); return -EINVAL; } @@ -6483,7 +6511,7 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event, src_list = param_buf->pmkid_request; if (len < (sizeof(*roam_pmkid_req_ev) + (num_entries * sizeof(*src_list)))) { - WMA_LOGE("%s: Invalid length:%d", __func__, len); + wma_err("%s: Invalid length:%d", __func__, len); return -EINVAL; } @@ -6499,12 +6527,12 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event, if (qdf_is_macaddr_zero(roam_bsslist) || qdf_is_macaddr_broadcast(roam_bsslist) || qdf_is_macaddr_group(roam_bsslist)) { - WMA_LOGE("%s: Invalid bssid", __func__); + wma_err("%s: Invalid bssid", __func__); qdf_mem_free(dst_list); return -EINVAL; } - WMA_LOGD("%s:Received pmkid fallback for bssid: %pM vdev_id:%d", - __func__, roam_bsslist->bytes, + WMA_LOGD("%s:Received pmkid fallback for bssid: "QDF_MAC_ADDR_FMT" vdev_id:%d", + __func__, QDF_MAC_ADDR_REF(roam_bsslist->bytes), roam_pmkid_req_ev->vdev_id); src_list++; } @@ -6513,7 +6541,7 @@ int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event, status = wma->csr_roam_pmkid_req_cb(roam_pmkid_req_ev->vdev_id, dst_list); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Pmkid request failed", __func__); + wma_err("%s: Pmkid request failed", __func__); qdf_mem_free(dst_list); return -EINVAL; } diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_twt.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_twt.c index 0ba47bcb19864c17cd0d4cf63938d5ba4f9b4072..84e88a6951f7fee78f5716de5abbb2d9356412db 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_twt.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_twt.c @@ -121,9 +121,9 @@ int wma_twt_disable_comp_event_handler(void *handle, uint8_t *event, void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd) { if (params->twt_requestor) - cmd->peer_flags |= WMI_PEER_TWT_REQ; + cmd->twt_requester = 1; if (params->twt_responder) - cmd->peer_flags |= WMI_PEER_TWT_RESP; + cmd->twt_responder = 1; } QDF_STATUS wma_twt_process_add_dialog( diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c index 15f979f37582246e04683375fe0cb6e0a0994553..67ed978263619811945a0f6b45e46805e13c8a45 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -63,6 +63,7 @@ #include #include "host_diag_core_log.h" #include +#include <../../core/src/vdev_mgr_ops.h> #include "cdp_txrx_misc.h" #include @@ -96,32 +97,32 @@ static struct index_data_rate_type mcs_nss2[] = { /* MCS Based VHT rate table */ /* MCS parameters with Nss = 1*/ static struct index_vht_data_rate_type vht_mcs_nss1[] = { - /* MCS L20 S20 L40 S40 L80 S80 */ - {0, {65, 72 }, {135, 150}, {293, 325} }, - {1, {130, 144}, {270, 300}, {585, 650} }, - {2, {195, 217}, {405, 450}, {878, 975} }, - {3, {260, 289}, {540, 600}, {1170, 1300} }, - {4, {390, 433}, {810, 900}, {1755, 1950} }, - {5, {520, 578}, {1080, 1200}, {2340, 2600} }, - {6, {585, 650}, {1215, 1350}, {2633, 2925} }, - {7, {650, 722}, {1350, 1500}, {2925, 3250} }, - {8, {780, 867}, {1620, 1800}, {3510, 3900} }, - {9, {865, 960}, {1800, 2000}, {3900, 4333} } + /* MCS L20 S20 L40 S40 L80 S80 L160 S160*/ + {0, {65, 72 }, {135, 150}, {293, 325}, {585, 650} }, + {1, {130, 144}, {270, 300}, {585, 650}, {1170, 1300} }, + {2, {195, 217}, {405, 450}, {878, 975}, {1755, 1950} }, + {3, {260, 289}, {540, 600}, {1170, 1300}, {2340, 2600} }, + {4, {390, 433}, {810, 900}, {1755, 1950}, {3510, 3900} }, + {5, {520, 578}, {1080, 1200}, {2340, 2600}, {4680, 5200} }, + {6, {585, 650}, {1215, 1350}, {2633, 2925}, {5265, 5850} }, + {7, {650, 722}, {1350, 1500}, {2925, 3250}, {5850, 6500} }, + {8, {780, 867}, {1620, 1800}, {3510, 3900}, {7020, 7800} }, + {9, {865, 960}, {1800, 2000}, {3900, 4333}, {7800, 8667} } }; /*MCS parameters with Nss = 2*/ static struct index_vht_data_rate_type vht_mcs_nss2[] = { - /* MCS L20 S20 L40 S40 L80 S80 */ - {0, {130, 144}, {270, 300}, { 585, 650} }, - {1, {260, 289}, {540, 600}, {1170, 1300} }, - {2, {390, 433}, {810, 900}, {1755, 1950} }, - {3, {520, 578}, {1080, 1200}, {2340, 2600} }, - {4, {780, 867}, {1620, 1800}, {3510, 3900} }, - {5, {1040, 1156}, {2160, 2400}, {4680, 5200} }, - {6, {1170, 1300}, {2430, 2700}, {5265, 5850} }, - {7, {1300, 1444}, {2700, 3000}, {5850, 6500} }, - {8, {1560, 1733}, {3240, 3600}, {7020, 7800} }, - {9, {1730, 1920}, {3600, 4000}, {7800, 8667} } + /* MCS L20 S20 L40 S40 L80 S80 L160 S160*/ + {0, {130, 144}, {270, 300}, { 585, 650}, {1170, 1300} }, + {1, {260, 289}, {540, 600}, {1170, 1300}, {2340, 2600} }, + {2, {390, 433}, {810, 900}, {1755, 1950}, {3510, 3900} }, + {3, {520, 578}, {1080, 1200}, {2340, 2600}, {4680, 5200} }, + {4, {780, 867}, {1620, 1800}, {3510, 3900}, {7020, 7800} }, + {5, {1040, 1156}, {2160, 2400}, {4680, 5200}, {9360, 10400} }, + {6, {1170, 1300}, {2430, 2700}, {5265, 5850}, {10530, 11700} }, + {7, {1300, 1444}, {2700, 3000}, {5850, 6500}, {11700, 13000} }, + {8, {1560, 1733}, {3240, 3600}, {7020, 7800}, {14040, 15600} }, + {9, {1730, 1920}, {3600, 4000}, {7800, 8667}, {15600, 17333} } }; #ifdef WLAN_FEATURE_11AX @@ -131,40 +132,52 @@ static struct index_he_data_rate_type he_mcs_nss1[] = { /* MCS, {dcm0:0.8/1.6/3.2}, {dcm1:0.8/1.6/3.2} */ {0, {{86, 81, 73 }, {43, 40, 36 } }, /* HE20 */ {{172, 163, 146 }, {86, 81, 73 } }, /* HE40 */ - {{360, 340, 306 }, {180, 170, 153} } }, /* HE80 */ + {{360, 340, 306 }, {180, 170, 153} }, /* HE80 */ + {{721, 681, 613 }, {360, 340, 306} } }, /* HE160/HE80+80 */ {1, {{172, 163, 146 }, {86, 81, 73 } }, {{344, 325, 293 }, {172, 163, 146} }, - {{721, 681, 613 }, {360, 340, 306} } }, + {{721, 681, 613 }, {360, 340, 306} }, + {{1441, 1361, 1225}, {721, 681, 613} } }, {2, {{258, 244, 219 }, {0} }, {{516, 488, 439 }, {0} }, - {{1081, 1021, 919 }, {0} } }, + {{1081, 1021, 919 }, {0} }, + {{2162, 2042, 1838}, {0} } }, {3, {{344, 325, 293 }, {172, 163, 146} }, {{688, 650, 585 }, {344, 325, 293} }, - {{1441, 1361, 1225}, {721, 681, 613} } }, + {{1441, 1361, 1225}, {721, 681, 613} }, + {{2882, 2722, 2450}, {1441, 1361, 1225} } }, {4, {{516, 488, 439 }, {258, 244, 219} }, {{1032, 975, 878 }, {516, 488, 439} }, - {{2162, 2042, 1838}, {1081, 1021, 919} } }, + {{2162, 2042, 1838}, {1081, 1021, 919} }, + {{4324, 4083, 3675}, {2162, 2042, 1838} } }, {5, {{688, 650, 585 }, {0} }, {{1376, 1300, 1170}, {0} }, - {{2882, 2722, 2450}, {0} } }, + {{2882, 2722, 2450}, {0} }, + {{5765, 5444, 4900}, {0} } }, {6, {{774, 731, 658 }, {0} }, {{1549, 1463, 1316}, {0} }, - {{3243, 3063, 2756}, {0} } }, + {{3243, 3063, 2756}, {0} }, + {{6485, 6125, 5513}, {0} } }, {7, {{860, 813, 731 }, {0} }, {{1721, 1625, 1463}, {0} }, - {{3603, 3403, 3063}, {0} } }, + {{3603, 3403, 3063}, {0} }, + {{7206, 6806, 6125}, {0} } }, {8, {{1032, 975, 878 }, {0} }, {{2065, 1950, 1755}, {0} }, - {{4324, 4083, 3675}, {0} } }, + {{4324, 4083, 3675}, {0} }, + {{8647, 8167, 7350}, {0} } }, {9, {{1147, 1083, 975 }, {0} }, {{2294, 2167, 1950}, {0} }, - {{4804, 4537, 4083}, {0} } }, + {{4804, 4537, 4083}, {0} }, + {{9607, 9074, 8166}, {0} } }, {10, {{1290, 1219, 1097}, {0} }, {{2581, 2438, 2194}, {0} }, - {{5404, 5104, 4594}, {0} } }, + {{5404, 5104, 4594}, {0} }, + {{10809, 10208, 9188}, {0} } }, {11, {{1434, 1354, 1219}, {0} }, {{2868, 2708, 2438}, {0} }, - {{6004, 5671, 5104}, {0} } } + {{6004, 5671, 5104}, {0} }, + {{12010, 11342, 10208}, {0} } } }; /*MCS parameters with Nss = 2*/ @@ -172,40 +185,52 @@ static struct index_he_data_rate_type he_mcs_nss2[] = { /* MCS, {dcm0:0.8/1.6/3.2}, {dcm1:0.8/1.6/3.2} */ {0, {{172, 163, 146 }, {86, 81, 73 } }, /* HE20 */ {{344, 325, 293 }, {172, 163, 146} }, /* HE40 */ - {{721, 681, 613 }, {360, 340, 306} } }, /* HE80 */ + {{721, 681, 613 }, {360, 340, 306} }, /* HE80 */ + {{1441, 1361, 1225}, {721, 681, 613} } }, /* HE160/HE80+80 */ {1, {{344, 325, 293 }, {172, 163, 146} }, {{688, 650, 585 }, {344, 325, 293} }, - {{1441, 1361, 1225}, {721, 681, 613} } }, + {{1441, 1361, 1225}, {721, 681, 613} }, + {{2882, 2722, 2450}, {1441, 1361, 1225} } }, {2, {{516, 488, 439 }, {0} }, {{1032, 975, 878 }, {0} }, - {{2162, 2042, 1838}, {0} } }, + {{2162, 2042, 1838}, {0} }, + {{4324, 4083, 3675}, {0} } }, {3, {{688, 650, 585 }, {344, 325, 293 } }, {{1376, 1300, 1170}, {688, 650, 585 } }, - {{2882, 2722, 2450}, {1441, 1361, 1225} } }, + {{2882, 2722, 2450}, {1441, 1361, 1225} }, + {{5765, 5444, 4900}, {2882, 2722, 2450} } }, {4, {{1032, 975, 878 }, {516, 488, 439 } }, {{2065, 1950, 1755}, {1032, 975, 878 } }, - {{4324, 4083, 3675}, {2162, 2042, 1838} } }, + {{4324, 4083, 3675}, {2162, 2042, 1838} }, + {{8647, 8167, 7350}, {4324, 4083, 3675} } }, {5, {{1376, 1300, 1170}, {0} }, {{2753, 2600, 2340}, {0} }, - {{5765, 5444, 4900}, {0} } }, + {{5765, 5444, 4900}, {0} }, + {{11529, 10889, 9800}, {0} } }, {6, {{1549, 1463, 1316}, {0} }, {{3097, 2925, 2633}, {0} }, - {{6485, 6125, 5513}, {0} } }, + {{6485, 6125, 5513}, {0} }, + {{12971, 12250, 11025}, {0} } }, {7, {{1721, 1625, 1463}, {0} }, {{3441, 3250, 2925}, {0} }, - {{7206, 6806, 6125}, {0} } }, + {{7206, 6806, 6125}, {0} }, + {{14412, 13611, 12250}, {0} } }, {8, {{2065, 1950, 1755}, {0} }, {{4129, 3900, 3510}, {0} }, - {{8647, 8167, 7350}, {0} } }, + {{8647, 8167, 7350}, {0} }, + {{17294, 16333, 14700}, {0} } }, {9, {{2294, 2167, 1950}, {0} }, {{4588, 4333, 3900}, {0} }, - {{9607, 9074, 8166}, {0} } }, + {{9607, 9074, 8166}, {0} }, + {{19215, 18148, 16333}, {0} } }, {10, {{2581, 2438, 2194}, {0} }, {{5162, 4875, 4388}, {0} }, - {{10809, 10208, 9188}, {0} } }, + {{10809, 10208, 9188}, {0} }, + {{21618, 20417, 18375}, {0} } }, {11, {{2868, 2708, 2438}, {0} }, {{5735, 5417, 4875}, {0} }, - {{12010, 11343, 10208}, {0} } } + {{12010, 11343, 10208}, {0} }, + {{24019, 22685, 20416}, {0} } } }; #endif @@ -239,8 +264,8 @@ void wma_swap_bytes(void *pv, uint32_t n) * wma_mcs_rate_match() - find the match mcs rate * @raw_rate: the rate to look up * @is_he: if it is he rate - * @nss1_rate: the nss1 rate - * @nss2_rate: the nss2 rate + * @nss1_rate: the nss1 rate + * @nss2_rate: the nss2 rate * @nss: the nss in use * @guard_interval: to get guard interval from rate * @@ -316,7 +341,7 @@ static uint16_t wma_match_he_rate(uint16_t raw_rate, uint16_t *nss2_rate; *p_index = 0; - if (!(rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 | + if (!(rate_flags & (TX_RATE_HE160 | TX_RATE_HE80 | TX_RATE_HE40 | TX_RATE_HE20))) return 0; @@ -325,7 +350,22 @@ static uint16_t wma_match_he_rate(uint16_t raw_rate, for (dcm_index = 0; dcm_index < dcm_index_max; dcm_index++) { - if (rate_flags & TX_RATE_HE80) { + if (rate_flags & TX_RATE_HE160) { + nss1_rate = &he_mcs_nss1[index]. + supported_he160_rate[dcm_index][0]; + nss2_rate = &he_mcs_nss2[index]. + supported_he160_rate[dcm_index][0]; + /* check for he160 nss1/2 rate set */ + match_rate = wma_mcs_rate_match(raw_rate, 1, + nss1_rate, + nss2_rate, + nss, + guard_interval); + if (match_rate) + goto rate_found; + } + + if (rate_flags & (TX_RATE_HE80 | TX_RATE_HE160)) { nss1_rate = &he_mcs_nss1[index]. supported_he80_rate[dcm_index][0]; nss2_rate = &he_mcs_nss2[index]. @@ -336,11 +376,14 @@ static uint16_t wma_match_he_rate(uint16_t raw_rate, nss2_rate, nss, guard_interval); - if (match_rate) + if (match_rate) { + *mcs_rate_flag &= ~TX_RATE_HE160; goto rate_found; + } } - if (rate_flags & (TX_RATE_HE40 | TX_RATE_HE80)) { + if (rate_flags & (TX_RATE_HE40 | TX_RATE_HE80 | + TX_RATE_HE160)) { nss1_rate = &he_mcs_nss1[index]. supported_he40_rate[dcm_index][0]; nss2_rate = &he_mcs_nss2[index]. @@ -353,13 +396,14 @@ static uint16_t wma_match_he_rate(uint16_t raw_rate, guard_interval); if (match_rate) { - *mcs_rate_flag &= ~TX_RATE_HE80; + *mcs_rate_flag &= ~(TX_RATE_HE80 | + TX_RATE_HE160); goto rate_found; } } if (rate_flags & (TX_RATE_HE80 | TX_RATE_HE40 | - TX_RATE_HE20)) { + TX_RATE_HE20 | TX_RATE_HE160)) { nss1_rate = &he_mcs_nss1[index]. supported_he20_rate[dcm_index][0]; nss2_rate = &he_mcs_nss2[index]. @@ -421,7 +465,18 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags, goto rate_found; for (index = 0; index < MAX_VHT_MCS_IDX; index++) { - if (rate_flags & TX_RATE_VHT80) { + if (rate_flags & TX_RATE_VHT160) { + nss1_rate = &vht_mcs_nss1[index].ht160_rate[0]; + nss2_rate = &vht_mcs_nss2[index].ht160_rate[0]; + /* check for vht160 nss1/2 rate set */ + match_rate = wma_mcs_rate_match(raw_rate, 0, + nss1_rate, + nss2_rate, + nss, guard_interval); + if (match_rate) + goto rate_found; + } + if (rate_flags & (TX_RATE_VHT80 | TX_RATE_VHT160)) { nss1_rate = &vht_mcs_nss1[index].ht80_rate[0]; nss2_rate = &vht_mcs_nss2[index].ht80_rate[0]; /* check for vht80 nss1/2 rate set */ @@ -429,10 +484,13 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags, nss1_rate, nss2_rate, nss, guard_interval); - if (match_rate) + if (match_rate) { + *mcs_rate_flag &= ~TX_RATE_VHT160; goto rate_found; + } } - if (rate_flags & (TX_RATE_VHT40 | TX_RATE_VHT80)) { + if (rate_flags & (TX_RATE_VHT40 | TX_RATE_VHT80 | + TX_RATE_VHT160)) { nss1_rate = &vht_mcs_nss1[index].ht40_rate[0]; nss2_rate = &vht_mcs_nss2[index].ht40_rate[0]; /* check for vht40 nss1/2 rate set */ @@ -446,7 +504,7 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags, } } if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 | - TX_RATE_VHT80)) { + TX_RATE_VHT80 | TX_RATE_VHT160)) { nss1_rate = &vht_mcs_nss1[index].ht20_rate[0]; nss2_rate = &vht_mcs_nss2[index].ht20_rate[0]; /* check for vht20 nss1/2 rate set */ @@ -510,54 +568,6 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags, return match_rate ? index : INVALID_MCS_IDX; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_peek_vdev_req() - peek what request message is queued for response. - * the function does not delete the node after found - * @wma: WMA handle - * @vdev_id: vdev ID - * @type: request message type - * - * Return: the request message found - */ -static struct wma_target_req *wma_peek_vdev_req(tp_wma_handle wma, - uint8_t vdev_id, uint8_t type) -{ - struct wma_target_req *req_msg = NULL; - bool found = false; - qdf_list_node_t *node1 = NULL, *node2 = NULL; - - qdf_spin_lock_bh(&wma->vdev_respq_lock); - if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue, - &node2)) { - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - return NULL; - } - - do { - node1 = node2; - req_msg = qdf_container_of(node1, struct wma_target_req, node); - if (req_msg->vdev_id != vdev_id) - continue; - if (req_msg->type != type) - continue; - - found = true; - break; - } while (QDF_STATUS_SUCCESS == qdf_list_peek_next(&wma->vdev_resp_queue, - node1, &node2)); - qdf_spin_unlock_bh(&wma->vdev_respq_lock); - if (!found) { - WMA_LOGE(FL("target request not found for vdev_id %d type %d"), - vdev_id, type); - return NULL; - } - WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"), - vdev_id, type, req_msg->msg_type); - return req_msg; -} -#endif /* QCA_SUPPORT_CP_STATS */ - void wma_lost_link_info_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi) { @@ -661,7 +671,6 @@ int wma_stats_ext_event_handler(void *handle, uint8_t *event_buf, uint32_t alloc_len; struct cdp_txrx_ext_stats ext_stats = {0}; struct cdp_soc_t *soc_hdl = cds_get_context(QDF_MODULE_ID_SOC); - void *pdev = cds_get_context(QDF_MODULE_ID_TXRX); wma_debug("%s: Posting stats ext event to SME", __func__); @@ -696,8 +705,7 @@ int wma_stats_ext_event_handler(void *handle, uint8_t *event_buf, qdf_mem_copy(stats_ext_event->event_data, buf_ptr, stats_ext_event->event_data_len); - cdp_txrx_ext_stats_request(soc_hdl, pdev, &ext_stats); - + cdp_txrx_ext_stats_request(soc_hdl, OL_TXRX_PDEV_ID, &ext_stats); qdf_mem_copy(stats_ext_event->event_data + stats_ext_event->event_data_len, &ext_stats, sizeof(struct cdp_txrx_ext_stats)); @@ -1609,12 +1617,10 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, size_t link_stats_results_size; bool excess_data = false; uint32_t buf_len = 0; - struct cdp_peer_stats *dp_stats = NULL; + struct cdp_peer_stats *dp_stats; void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; uint8_t mcs_index; - struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); - struct cdp_peer *peer; - uint8_t peer_id; struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); @@ -1712,6 +1718,12 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, qdf_mem_copy(link_stats_results->results, &fixed_param->num_peers, peer_stats_size); + dp_stats = qdf_mem_malloc(sizeof(*dp_stats)); + if (!dp_stats) { + WMA_LOGE("dp stats allocation failed"); + qdf_mem_free(link_stats_results); + return -ENOMEM; + } results = (uint8_t *) link_stats_results->results; t_peer_stats = (uint8_t *) peer_stats; @@ -1724,16 +1736,15 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, t_peer_stats + next_peer_offset, peer_info_size); next_res_offset += peer_info_size; - peer = cdp_peer_find_by_addr(dp_soc, txrx_pdev, + status = cdp_host_get_peer_stats(dp_soc, + link_stats_results->ifaceId, (uint8_t *)&peer_stats->peer_mac_address, - &peer_id); - if (peer) - dp_stats = cdp_host_get_peer_stats(dp_soc, peer); + dp_stats); /* Copy rate stats associated with this peer */ for (count = 0; count < peer_stats->num_rates; count++) { mcs_index = RATE_STAT_GET_MCS_INDEX(rate_stats->rate); - if (dp_stats) { + if (QDF_IS_STATUS_SUCCESS(status)) { if (rate_stats->rate && mcs_index < MAX_MCS) rate_stats->rx_mpdu = dp_stats->rx.rx_mpdu_cnt[mcs_index]; @@ -1752,6 +1763,7 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, peer_stats++; } + qdf_mem_free(dp_stats); /* call hdd callback with Link Layer Statistics * vdev_id/ifacId in link_stats_results will be * used to retrieve the correct HDD context @@ -2032,7 +2044,7 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, fixed_param = param_tlvs->fixed_param; if (fixed_param && !fixed_param->num_radio && !fixed_param->more_radio_events) { - WMA_LOGI("FW indicates dummy link radio stats"); + WMA_LOGD("FW indicates dummy link radio stats"); if (!wma_handle->link_stats_results) { wma_handle->link_stats_results = qdf_mem_malloc( sizeof(*link_stats_results)); @@ -2352,27 +2364,22 @@ void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle) } - -/** - * wma_process_ll_stats_clear_req() - clear link layer stats - * @wma: wma handle - * @clearReq: ll stats clear request command params - * - * Return: QDF_STATUS_SUCCESS for success or error code - */ QDF_STATUS wma_process_ll_stats_clear_req(tp_wma_handle wma, const tpSirLLStatsClearReq clearReq) { + uint8_t *addr; struct ll_stats_clear_params cmd = {0}; int ret; + struct wlan_objmgr_vdev *vdev; if (!clearReq || !wma) { WMA_LOGE("%s: input pointer is NULL", __func__); return QDF_STATUS_E_FAILURE; } - if (!wma->interfaces[clearReq->staId].handle) { - WMA_LOGE("%s: vdev_id %d handle is NULL", + vdev = wma->interfaces[clearReq->staId].vdev; + if (!vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, clearReq->staId); return QDF_STATUS_E_FAILURE; } @@ -2380,9 +2387,20 @@ QDF_STATUS wma_process_ll_stats_clear_req(tp_wma_handle wma, cmd.stop_req = clearReq->stopReq; cmd.vdev_id = clearReq->staId; cmd.stats_clear_mask = clearReq->statsClearReqMask; - qdf_mem_copy(cmd.peer_macaddr.bytes, - wma->interfaces[clearReq->staId].addr, - QDF_MAC_ADDR_SIZE); + + vdev = wma->interfaces[clearReq->staId].vdev; + if (!vdev) { + WMA_LOGE("%s: Failed to get vdev for vdev_%d", + __func__, clearReq->staId); + return QDF_STATUS_E_FAILURE; + } + addr = wlan_vdev_mlme_get_macaddr(vdev); + if (!addr) { + WMA_LOGE("%s: Failed to get macaddr for vdev_%d", + __func__, clearReq->staId); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(cmd.peer_macaddr.bytes, addr, QDF_MAC_ADDR_SIZE); ret = wmi_unified_process_ll_stats_clear_cmd(wma->wmi_handle, &cmd); if (ret) { WMA_LOGE("%s: Failed to send clear link stats req", __func__); @@ -2424,16 +2442,11 @@ QDF_STATUS wma_process_ll_stats_set_req(tp_wma_handle wma, return QDF_STATUS_SUCCESS; } -/** - * wma_process_ll_stats_get_req() - link layer stats get request - * @wma:wma handle - * @getReq:ll stats get request command params - * - * Return: QDF_STATUS_SUCCESS for success or error code - */ QDF_STATUS wma_process_ll_stats_get_req(tp_wma_handle wma, const tpSirLLStatsGetReq getReq) { + struct wlan_objmgr_vdev *vdev; + uint8_t *addr; struct ll_stats_get_params cmd = {0}; int ret; @@ -2451,10 +2464,20 @@ QDF_STATUS wma_process_ll_stats_get_req(tp_wma_handle wma, cmd.req_id = getReq->reqId; cmd.param_id_mask = getReq->paramIdMask; cmd.vdev_id = getReq->staId; - qdf_mem_copy(cmd.peer_macaddr.bytes, - wma->interfaces[getReq->staId].addr, - QDF_MAC_ADDR_SIZE); + vdev = wma->interfaces[getReq->staId].vdev; + if (!vdev) { + WMA_LOGE("%s: Failed to get vdev for vdev_%d", + __func__, getReq->staId); + return QDF_STATUS_E_FAILURE; + } + addr = wlan_vdev_mlme_get_macaddr(vdev); + if (!addr) { + WMA_LOGE("%s: Failed to get macaddr for vdev_%d", + __func__, getReq->staId); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(cmd.peer_macaddr.bytes, addr, QDF_MAC_ADDR_SIZE); ret = wmi_unified_process_ll_stats_get_cmd(wma->wmi_handle, &cmd); if (ret) { WMA_LOGE("%s: Failed to send get link stats request", __func__); @@ -2595,6 +2618,8 @@ int wma_unified_link_iface_stats_event_handler(void *handle, /* Copy roaming state */ iface_stat->info.roaming = link_stats->roam_state; + /* Copy time slicing duty cycle */ + iface_stat->info.time_slice_duty_cycle = 100; iface_ac_stats = &iface_stat->ac_stats[0]; for (count = 0; count < link_stats->num_ac; count++) { @@ -2779,315 +2804,8 @@ void wma_config_stats_ext_threshold(tp_wma_handle wma, if (QDF_IS_STATUS_ERROR(status)) wmi_buf_free(buf); } - #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_update_pdev_stats() - update pdev stats - * @wma: wma handle - * @pdev_stats: pdev stats - * - * Return: none - */ -static void wma_update_pdev_stats(tp_wma_handle wma, - wmi_pdev_stats *pdev_stats) -{ - tAniGetPEStatsRsp *stats_rsp_params; - uint32_t temp_mask; - uint8_t *stats_buf; - tCsrGlobalClassAStatsInfo *classa_stats = NULL; - struct wma_txrx_node *node; - uint8_t i; - - for (i = 0; i < wma->max_bssid; i++) { - node = &wma->interfaces[i]; - stats_rsp_params = node->stats_rsp; - if (stats_rsp_params) { - node->fw_stats_set |= FW_PDEV_STATS_SET; - WMA_LOGD("<---FW PDEV STATS received for vdevId:%d", i); - stats_buf = (uint8_t *) (stats_rsp_params + 1); - temp_mask = stats_rsp_params->statsMask; - if (temp_mask & (1 << eCsrSummaryStats)) - stats_buf += sizeof(tCsrSummaryStatsInfo); - - if (temp_mask & (1 << eCsrGlobalClassAStats)) { - classa_stats = - (tCsrGlobalClassAStatsInfo *) stats_buf; - classa_stats->max_pwr = pdev_stats->chan_tx_pwr; - } - } - } -} - -/** - * wma_vdev_stats_lost_link_helper() - helper function to extract - * lost link information from vdev statistics event while deleting BSS. - * @wma: WMA handle - * @vdev_stats: statistics information from firmware - * - * This is for informing HDD to collect lost link information while - * disconnection. Following conditions to check - * 1. vdev is up - * 2. bssid is zero. When handling DELETE_BSS request message, it sets bssid to - * zero, hence add the check here to indicate the event comes during deleting - * BSS - * 3. DELETE_BSS is the request message queued. Put this condition check on the - * last one as it consumes more resource searching entries in the list - * - * Return: none - */ -static void wma_vdev_stats_lost_link_helper(tp_wma_handle wma, - wmi_vdev_stats *vdev_stats) -{ - struct wma_txrx_node *node; - int8_t rssi; - struct wma_target_req *req_msg; - static const uint8_t zero_mac[QDF_MAC_ADDR_SIZE] = {0}; - bool db2dbm_enabled; - - if (vdev_stats->vdev_id >= wma->max_bssid) { - WMA_LOGE("%s: Invalid vdev_id %hu", - __func__, vdev_stats->vdev_id); - return; - } - - db2dbm_enabled = wlan_psoc_nif_fw_ext_cap_get(wma->psoc, - WLAN_SOC_CEXT_HW_DB2DBM); - node = &wma->interfaces[vdev_stats->vdev_id]; - if (wma_is_vdev_up(vdev_stats->vdev_id) && - !qdf_mem_cmp(node->bssid, zero_mac, QDF_MAC_ADDR_SIZE)) { - req_msg = wma_peek_vdev_req(wma, vdev_stats->vdev_id, - WMA_TARGET_REQ_TYPE_VDEV_STOP); - if ((!req_msg) || - (WMA_DELETE_BSS_REQ != req_msg->msg_type)) { - WMA_LOGD(FL("cannot find DELETE_BSS request message")); - return; - } - - WMA_LOGD(FL("get vdev id %d, beancon snr %d, data snr %d"), - vdev_stats->vdev_id, vdev_stats->vdev_snr.bcn_snr, - vdev_stats->vdev_snr.dat_snr); - - wlan_util_stats_get_rssi(db2dbm_enabled, - vdev_stats->vdev_snr.bcn_snr, - vdev_stats->vdev_snr.dat_snr, - &rssi); - - wma_lost_link_info_handler(wma, vdev_stats->vdev_id, rssi); - } -} - -/** - * wma_update_vdev_stats() - update vdev stats - * @wma: wma handle - * @vdev_stats: vdev stats - * - * Return: none - */ -static void wma_update_vdev_stats(tp_wma_handle wma, - wmi_vdev_stats *vdev_stats) -{ - tAniGetPEStatsRsp *stats_rsp_params; - tCsrSummaryStatsInfo *summary_stats = NULL; - uint8_t *stats_buf; - struct wma_txrx_node *node; - uint8_t i; - int8_t rssi = 0; - QDF_STATUS qdf_status; - tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) wma->pGetRssiReq; - struct scheduler_msg sme_msg = { 0 }; - int32_t bcn_snr, dat_snr; - bool db2dbm_enabled; - - if (vdev_stats->vdev_id >= wma->max_bssid) { - WMA_LOGE("%s: Invalid vdev_id %hu", - __func__, vdev_stats->vdev_id); - return; - } - - bcn_snr = vdev_stats->vdev_snr.bcn_snr; - dat_snr = vdev_stats->vdev_snr.dat_snr; - WMA_LOGD("vdev id %d beancon snr %d data snr %d", - vdev_stats->vdev_id, bcn_snr, dat_snr); - - db2dbm_enabled = wlan_psoc_nif_fw_ext_cap_get(wma->psoc, - WLAN_SOC_CEXT_HW_DB2DBM); - node = &wma->interfaces[vdev_stats->vdev_id]; - stats_rsp_params = node->stats_rsp; - if (stats_rsp_params) { - stats_buf = (uint8_t *) (stats_rsp_params + 1); - node->fw_stats_set |= FW_VDEV_STATS_SET; - WMA_LOGD("<---FW VDEV STATS received for vdevId:%d", - vdev_stats->vdev_id); - if (stats_rsp_params->statsMask & (1 << eCsrSummaryStats)) { - summary_stats = (tCsrSummaryStatsInfo *) stats_buf; - for (i = 0; i < 4; i++) { - summary_stats->tx_frm_cnt[i] = - vdev_stats->tx_frm_cnt[i]; - summary_stats->fail_cnt[i] = - vdev_stats->fail_cnt[i]; - summary_stats->multiple_retry_cnt[i] = - vdev_stats->multiple_retry_cnt[i]; - } - - summary_stats->rx_frm_cnt = vdev_stats->rx_frm_cnt; - summary_stats->rx_error_cnt = vdev_stats->rx_err_cnt; - summary_stats->rx_discard_cnt = - vdev_stats->rx_discard_cnt; - summary_stats->ack_fail_cnt = vdev_stats->ack_fail_cnt; - summary_stats->rts_succ_cnt = vdev_stats->rts_succ_cnt; - summary_stats->rts_fail_cnt = vdev_stats->rts_fail_cnt; - /* Update SNR and RSSI in SummaryStats */ - wlan_util_stats_get_rssi(db2dbm_enabled, - bcn_snr, dat_snr, - &summary_stats->rssi); - summary_stats->snr = summary_stats->rssi - - WMA_TGT_NOISE_FLOOR_DBM; - } - } - - if (pGetRssiReq && pGetRssiReq->sessionId == vdev_stats->vdev_id) { - wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr, dat_snr, - &rssi); - - WMA_LOGD("Average Rssi = %d, vdev id= %d", rssi, - pGetRssiReq->sessionId); - - /* update the average rssi value to UMAC layer */ - if (pGetRssiReq->rssiCallback) { - ((tCsrRssiCallback) (pGetRssiReq->rssiCallback))(rssi, - pGetRssiReq->staId, - pGetRssiReq->pDevContext); - } - - qdf_mem_free(pGetRssiReq); - wma->pGetRssiReq = NULL; - } - - if (node->psnr_req) { - tAniGetSnrReq *p_snr_req = node->psnr_req; - - if (WMA_TGT_IS_VALID_SNR(bcn_snr)) - p_snr_req->snr = bcn_snr; - else if (WMA_TGT_IS_VALID_SNR(dat_snr)) - p_snr_req->snr = dat_snr; - else - p_snr_req->snr = WMA_TGT_INVALID_SNR; - - sme_msg.type = eWNI_SME_SNR_IND; - sme_msg.bodyptr = p_snr_req; - sme_msg.bodyval = 0; - - qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA, - QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, - &sme_msg); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - WMA_LOGE("%s: Fail to post snr ind msg", __func__); - qdf_mem_free(p_snr_req); - } - - node->psnr_req = NULL; - } - wma_vdev_stats_lost_link_helper(wma, vdev_stats); -} - -/** - * wma_post_stats() - update stats to PE - * @wma: wma handle - * @node: txrx node - * - * Return: none - */ -static void wma_post_stats(tp_wma_handle wma, struct wma_txrx_node *node) -{ - /* send response to UMAC */ - wma_send_msg(wma, WMA_GET_STATISTICS_RSP, node->stats_rsp, 0); - node->stats_rsp = NULL; - node->fw_stats_set = 0; -} - -/** - * wma_update_peer_stats() - update peer stats - * @wma: wma handle - * @peer_stats: peer stats - * - * Return: none - */ -static void wma_update_peer_stats(tp_wma_handle wma, - wmi_peer_stats *peer_stats) -{ - tAniGetPEStatsRsp *stats_rsp_params; - tCsrGlobalClassAStatsInfo *classa_stats = NULL; - struct wma_txrx_node *node; - uint8_t *stats_buf, vdev_id, macaddr[QDF_MAC_ADDR_SIZE], mcsRateFlags; - uint32_t temp_mask; - uint8_t nss; - - WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr, &macaddr[0]); - if (!wma_find_vdev_by_bssid(wma, macaddr, &vdev_id)) - return; - - node = &wma->interfaces[vdev_id]; - stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp; - if (stats_rsp_params) { - node->fw_stats_set |= FW_PEER_STATS_SET; - WMA_LOGD("<-- FW PEER STATS received for vdevId:%d", vdev_id); - stats_buf = (uint8_t *) (stats_rsp_params + 1); - temp_mask = stats_rsp_params->statsMask; - if (temp_mask & (1 << eCsrSummaryStats)) - stats_buf += sizeof(tCsrSummaryStatsInfo); - - if (temp_mask & (1 << eCsrGlobalClassAStats)) { - classa_stats = (tCsrGlobalClassAStatsInfo *) stats_buf; - WMA_LOGD("peer tx rate:%d", peer_stats->peer_tx_rate); - WMA_LOGD("peer rx rate:%d", peer_stats->peer_rx_rate); - /* The linkspeed returned by fw is in kbps so convert - * it in to units of 500kbps which is expected by UMAC - */ - if (peer_stats->peer_tx_rate) { - classa_stats->tx_rate = - peer_stats->peer_tx_rate / 500; - } - - if (peer_stats->peer_rx_rate) { - classa_stats->rx_rate = - peer_stats->peer_rx_rate / 500; - } - - classa_stats->tx_rx_rate_flags = node->rate_flags; - if (!(node->rate_flags & TX_RATE_LEGACY)) { - nss = node->nss; - classa_stats->tx_mcs_index = - wma_get_mcs_idx( - (peer_stats->peer_tx_rate / - 100), node->rate_flags, - &nss, &mcsRateFlags); - classa_stats->tx_nss = nss; - classa_stats->tx_mcs_rate_flags = mcsRateFlags; - } - - if (!(node->rate_flags & TX_RATE_LEGACY)) { - nss = node->nss; - classa_stats->rx_mcs_index = - wma_get_mcs_idx( - (peer_stats->peer_rx_rate / - 100), node->rate_flags, - &nss, &mcsRateFlags); - classa_stats->rx_nss = nss; - classa_stats->rx_mcs_rate_flags = mcsRateFlags; - } - /* FW returns tx power in intervals of 0.5 dBm - * Convert it back to intervals of 1 dBm - */ - classa_stats->max_pwr = - roundup(classa_stats->max_pwr, 2) >> 1; - } - } -} -#endif /* WMA_GET_STATISTICS_RSP */ - /** * wma_post_link_status() - post link status to SME * @pGetLinkStatus: SME Link status @@ -3115,104 +2833,6 @@ void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus, } } -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_update_per_chain_rssi_stats() - to store per chain rssi stats - * @wma: wma handle - * @rssi_stats: rssi stats - * @rssi_per_chain_stats: buffer where rssi stats to be stored - * - * This function stores per chain rssi stats received from fw for all vdevs for - * which the stats were requested into a csr stats structure. - * - * Return: void - */ -static void wma_update_per_chain_rssi_stats(tp_wma_handle wma, - wmi_rssi_stats *rssi_stats, - struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats) -{ - int i; - int32_t bcn_snr, dat_snr; - bool db2dbm_enabled; - - db2dbm_enabled = wlan_psoc_nif_fw_ext_cap_get(wma->psoc, - WLAN_SOC_CEXT_HW_DB2DBM); - for (i = 0; i < NUM_CHAINS_MAX; i++) { - bcn_snr = rssi_stats->rssi_avg_beacon[i]; - dat_snr = rssi_stats->rssi_avg_data[i]; - WMA_LOGD("chain %d beacon snr %d data snr %d", - i, bcn_snr, dat_snr); - - wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr, dat_snr, - &rssi_per_chain_stats->rssi[i]); - - WMI_MAC_ADDR_TO_CHAR_ARRAY(&(rssi_stats->peer_macaddr), - rssi_per_chain_stats->peer_mac_addr); - } -} - -/** - * wma_update_rssi_stats() - to update rssi stats for all vdevs - * for which the stats were requested. - * @wma: wma handle - * @rssi_stats: rssi stats - * - * This function updates the rssi stats for all vdevs for which - * the stats were requested. - * - * Return: void - */ -static void wma_update_rssi_stats(tp_wma_handle wma, - wmi_rssi_stats *rssi_stats) -{ - tAniGetPEStatsRsp *stats_rsp_params; - struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats = NULL; - struct wma_txrx_node *node; - uint8_t *stats_buf; - uint32_t temp_mask; - uint8_t vdev_id; - - if (rssi_stats->vdev_id >= wma->max_bssid) { - WMA_LOGE("%s: Invalid vdev_id %hu", - __func__, rssi_stats->vdev_id); - return; - } - - vdev_id = rssi_stats->vdev_id; - node = &wma->interfaces[vdev_id]; - stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp; - if (stats_rsp_params) { - node->fw_stats_set |= FW_RSSI_PER_CHAIN_STATS_SET; - WMA_LOGD("<-- FW RSSI PER CHAIN STATS received for vdevId:%d", - vdev_id); - stats_buf = (uint8_t *) (stats_rsp_params + 1); - temp_mask = stats_rsp_params->statsMask; - - if (temp_mask & (1 << eCsrSummaryStats)) - stats_buf += sizeof(tCsrSummaryStatsInfo); - if (temp_mask & (1 << eCsrGlobalClassAStats)) - stats_buf += sizeof(tCsrGlobalClassAStatsInfo); - if (temp_mask & (1 << eCsrGlobalClassDStats)) - stats_buf += sizeof(tCsrGlobalClassDStatsInfo); - - if (temp_mask & (1 << csr_per_chain_rssi_stats)) { - rssi_per_chain_stats = - (struct csr_per_chain_rssi_stats_info *)stats_buf; - wma_update_per_chain_rssi_stats(wma, rssi_stats, - rssi_per_chain_stats); - } - } -} -#endif /* QCA_SUPPORT_CP_STATS */ - -/** - * wma_link_status_event_handler() - link status event handler - * @handle: wma handle - * @cmd_param_info: data from event - * @len: length - * - * Return: 0 for success or error code - */ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, uint32_t len) { @@ -3222,7 +2842,8 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, wmi_vdev_rate_ht_info *ht_info; struct wma_txrx_node *intr = wma->interfaces; uint8_t link_status = LINK_STATUS_LEGACY; - uint32_t i; + uint32_t i, rate_flag; + QDF_STATUS status; param_buf = (WMI_UPDATE_VDEV_RATE_STATS_EVENTID_param_tlvs *) cmd_param_info; @@ -3250,6 +2871,23 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, param_buf->num_ht_info); return -EINVAL; } + + if (!wma_is_vdev_valid(ht_info->vdevid)) { + wma_err("Invalid vdevid %d", ht_info->vdevid); + return -EINVAL; + } + + if (!intr[ht_info->vdevid].vdev) { + wma_err("Vdev is NULL"); + return -EINVAL; + } + + status = wma_get_vdev_rate_flag(intr[ht_info->vdevid].vdev, &rate_flag); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get rate flag", __func__); + return -EINVAL; + } + for (i = 0; (i < event->num_vdev_stats) && ht_info; i++) { WMA_LOGD("%s vdevId:%d tx_nss:%d rx_nss:%d tx_preamble:%d rx_preamble:%d", __func__, ht_info->vdevid, ht_info->tx_nss, @@ -3267,7 +2905,7 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info, if (intr[ht_info->vdevid].nss == 2) link_status |= LINK_SUPPORT_MIMO; - if (intr[ht_info->vdevid].rate_flags & + if (rate_flag & (TX_RATE_VHT20 | TX_RATE_VHT40 | TX_RATE_VHT80)) link_status |= LINK_SUPPORT_VHT; @@ -3315,298 +2953,6 @@ int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event) return 0; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_handle_sta_peer_info() - handle peer information in - * peer stats - * @num_peer_stats: peer number - * @peer_stats: peer stats received from firmware - * @peer_macaddr: the specified mac address - * @sapaddr: sap mac address - * - * This function will send eWNI_SME_GET_PEER_INFO_IND - * to sme with stations' information - * - */ -static void wma_handle_sta_peer_info(uint32_t num_peer_stats, - wmi_peer_stats *peer_stats, - struct qdf_mac_addr peer_macaddr, - uint8_t *sapaddr) -{ - QDF_STATUS qdf_status; - wmi_mac_addr temp_addr; - struct sir_peer_info_resp *peer_info; - struct scheduler_msg sme_msg = {0}; - uint32_t i; - uint32_t j = 0; - - if (!qdf_is_macaddr_broadcast(&peer_macaddr)) { - WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_macaddr.bytes, &temp_addr); - for (i = 0; i < num_peer_stats; i++) { - if ((((temp_addr.mac_addr47to32) & 0x0000ffff) == - ((peer_stats->peer_macaddr.mac_addr47to32) & - 0x0000ffff)) - && (temp_addr.mac_addr31to0 == - peer_stats->peer_macaddr.mac_addr31to0)) { - - break; - } - peer_stats = peer_stats + 1; - } - peer_info = qdf_mem_malloc(sizeof(*peer_info) + - sizeof(peer_info->info[0])); - if (!peer_info) - return; - - if (i < num_peer_stats) { - peer_info->count = 1; - WMI_MAC_ADDR_TO_CHAR_ARRAY(&(peer_stats->peer_macaddr), - peer_info->info[0].peer_macaddr.bytes); - peer_info->info[0].rssi = peer_stats->peer_rssi; - peer_info->info[0].tx_rate = peer_stats->peer_tx_rate; - peer_info->info[0].rx_rate = peer_stats->peer_rx_rate; - WMA_LOGD("%s peer %pM rssi %d tx_rate %d rx_rate %d", - __func__, - peer_info->info[0].peer_macaddr.bytes, - peer_stats->peer_rssi, - peer_stats->peer_tx_rate, - peer_stats->peer_rx_rate); - } else { - WMA_LOGE("%s: no match mac address", __func__); - peer_info->count = 0; - } - } else { - peer_info = qdf_mem_malloc(sizeof(*peer_info) + - num_peer_stats * sizeof(peer_info->info[0])); - if (!peer_info) - return; - - peer_info->count = num_peer_stats; - - for (i = 0; i < num_peer_stats; i++) { - WMI_MAC_ADDR_TO_CHAR_ARRAY(&(peer_stats->peer_macaddr), - peer_info->info[j].peer_macaddr.bytes); - peer_info->info[j].rssi = peer_stats->peer_rssi; - peer_info->info[j].tx_rate = peer_stats->peer_tx_rate; - peer_info->info[j].rx_rate = peer_stats->peer_rx_rate; - WMA_LOGD("%s peer %pM rssi %d tx_rate %d rx_rate %d", - __func__, - peer_info->info[j].peer_macaddr.bytes, - peer_stats->peer_rssi, - peer_stats->peer_tx_rate, - peer_stats->peer_rx_rate); - if (!qdf_mem_cmp(peer_info->info[j].peer_macaddr.bytes, - sapaddr, QDF_MAC_ADDR_SIZE)) { - peer_info->count = peer_info->count - 1; - } else { - j++; - } - peer_stats = peer_stats + 1; - } - WMA_LOGD("WDA send peer num %d", peer_info->count); - } - - sme_msg.type = eWNI_SME_GET_PEER_INFO_IND; - sme_msg.bodyptr = peer_info; - sme_msg.bodyval = 0; - - qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA, - QDF_MODULE_ID_SME, - QDF_MODULE_ID_SME, &sme_msg); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - WMA_LOGE("%s: Fail to post get rssi msg", __func__); - qdf_mem_free(peer_info); - } - - return; -} - -/** - * wma_stats_event_handler() - stats event handler - * @handle: wma handle - * @cmd_param_info: data from event - * @len: length - * - * Return: 0 for success or error code - */ -int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, - uint32_t len) -{ - tp_wma_handle wma = (tp_wma_handle) handle; - WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; - wmi_stats_event_fixed_param *event; - wmi_pdev_stats *pdev_stats; - wmi_vdev_stats *vdev_stats; - wmi_peer_stats *peer_stats; - wmi_rssi_stats *rssi_stats; - wmi_per_chain_rssi_stats *rssi_event; - struct wma_txrx_node *node; - uint8_t *temp; - uint32_t i; - uint32_t buf_len = 0; - bool excess_data = false; - wmi_congestion_stats *congestion_stats; - struct mac_context *mac; - - param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) cmd_param_info; - if (!param_buf) { - WMA_LOGA("%s: Invalid stats event", __func__); - return -EINVAL; - } - event = param_buf->fixed_param; - temp = (uint8_t *) param_buf->data; - - do { - if (event->num_pdev_stats > ((WMI_SVC_MSG_MAX_SIZE - - sizeof(*event)) / sizeof(*pdev_stats))) { - excess_data = true; - break; - } else { - buf_len += event->num_pdev_stats * sizeof(*pdev_stats); - } - - if (event->num_vdev_stats > ((WMI_SVC_MSG_MAX_SIZE - - sizeof(*event)) / sizeof(*vdev_stats))) { - excess_data = true; - break; - } else { - buf_len += event->num_vdev_stats * sizeof(*vdev_stats); - } - - if (event->num_peer_stats > ((WMI_SVC_MSG_MAX_SIZE - - sizeof(*event)) / sizeof(*peer_stats))) { - excess_data = true; - break; - } else { - buf_len += event->num_peer_stats * sizeof(*peer_stats); - } - - if (buf_len > param_buf->num_data) { - WMA_LOGE("%s: num_data: %d Invalid num_pdev_stats:%d or num_vdev_stats:%d or num_peer_stats:%d", - __func__, param_buf->num_data, - event->num_pdev_stats, - event->num_vdev_stats, event->num_peer_stats); - return -EINVAL; - } - - rssi_event = - (wmi_per_chain_rssi_stats *) param_buf->chain_stats; - if (rssi_event) { - if (rssi_event->num_per_chain_rssi_stats > - ((WMI_SVC_MSG_MAX_SIZE - sizeof(*event)) / - sizeof(*rssi_event))) { - excess_data = true; - break; - } else { - buf_len += sizeof(*rssi_event) * - rssi_event->num_per_chain_rssi_stats; - } - } - } while (0); - - if (excess_data || - (buf_len > WMI_SVC_MSG_MAX_SIZE - sizeof(*event))) { - WMA_LOGE("excess wmi buffer: stats pdev %d vdev %d peer %d", - event->num_pdev_stats, event->num_vdev_stats, - event->num_peer_stats); - return -EINVAL; - } - - if (event->num_pdev_stats > 0) { - for (i = 0; i < event->num_pdev_stats; i++) { - pdev_stats = (wmi_pdev_stats *) temp; - wma_update_pdev_stats(wma, pdev_stats); - temp += sizeof(wmi_pdev_stats); - } - } - - if (event->num_vdev_stats > 0) { - for (i = 0; i < event->num_vdev_stats; i++) { - vdev_stats = (wmi_vdev_stats *) temp; - wma_update_vdev_stats(wma, vdev_stats); - temp += sizeof(wmi_vdev_stats); - } - } - - if (event->num_peer_stats > 0) { - if (wma->get_sta_peer_info == true) { - wma_handle_sta_peer_info(event->num_peer_stats, - (wmi_peer_stats *)temp, - wma->peer_macaddr, - wma->myaddr); - } else { - for (i = 0; i < event->num_peer_stats; i++) { - peer_stats = (wmi_peer_stats *) temp; - wma_update_peer_stats(wma, peer_stats); - temp += sizeof(wmi_peer_stats); - } - } - } - - rssi_event = (wmi_per_chain_rssi_stats *) param_buf->chain_stats; - if (rssi_event) { - if (rssi_event->num_per_chain_rssi_stats > - param_buf->num_rssi_stats) { - WMA_LOGE("%s: Invalid num_per_chain_rssi_stats:%d", - __func__, rssi_event->num_per_chain_rssi_stats); - return -EINVAL; - } - if (((rssi_event->tlv_header & 0xFFFF0000) >> 16 == - WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats) && - ((rssi_event->tlv_header & 0x0000FFFF) == - WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats))) { - if (rssi_event->num_per_chain_rssi_stats > 0) { - temp = (uint8_t *) rssi_event; - temp += sizeof(*rssi_event); - - /* skip past struct array tlv header */ - temp += WMI_TLV_HDR_SIZE; - - for (i = 0; - i < rssi_event->num_per_chain_rssi_stats; - i++) { - rssi_stats = (wmi_rssi_stats *)temp; - wma_update_rssi_stats(wma, rssi_stats); - temp += sizeof(wmi_rssi_stats); - } - } - } - } - - congestion_stats = (wmi_congestion_stats *) param_buf->congestion_stats; - if (congestion_stats) { - if (((congestion_stats->tlv_header & 0xFFFF0000) >> 16 == - WMITLV_TAG_STRUC_wmi_congestion_stats) && - ((congestion_stats->tlv_header & 0x0000FFFF) == - WMITLV_GET_STRUCT_TLVLEN(wmi_congestion_stats))) { - mac = cds_get_context(QDF_MODULE_ID_PE); - if (!mac) { - WMA_LOGE("%s: Invalid mac", __func__); - return -EINVAL; - } - if (!mac->sme.congestion_cb) { - WMA_LOGE("%s: Callback not registered", - __func__); - return -EINVAL; - } - WMA_LOGI("%s: congestion %d", __func__, - congestion_stats->congestion); - mac->sme.congestion_cb(mac->hdd_handle, - congestion_stats->congestion, - congestion_stats->vdev_id); - } - } - - for (i = 0; i < wma->max_bssid; i++) { - node = &wma->interfaces[i]; - if (node->fw_stats_set & FW_PEER_STATS_SET) - wma_post_stats(wma, node); - } - - return 0; -} -#endif /* QCA_SUPPORT_CP_STATS */ - /** * wma_fill_peer_info() - fill SIR peer info from WMI peer info struct * @wma: wma interface @@ -3749,7 +3095,8 @@ static void dump_peer_stats_info(wmi_peer_stats_info_event_fixed_param *event, for (i = 0; i < event->num_peers; i++) { WMI_MAC_ADDR_TO_CHAR_ARRAY(&stats->peer_macaddr, mac); - WMA_LOGI("%s mac %pM", __func__, mac); + WMA_LOGI("%s mac "QDF_MAC_ADDR_FMT, __func__, + QDF_MAC_ADDR_REF(mac)); WMA_LOGI("%s tx_bytes %d %d tx_packets %d %d", __func__, stats->tx_bytes.low_32, @@ -3939,22 +3286,12 @@ int wma_unified_debug_print_event_handler(void *handle, uint8_t *datap, #endif /* BIG_ENDIAN_HOST */ } -/** - * wma_peer_phymode() - get phymode - * @nw_type: nw type - * @sta_type: sta type - * @is_ht: is ht supported - * @ch_width: supported channel width - * @is_vht: is vht supported - * @is_he: is HE supported - * - * Return: WLAN_PHY_MODE - */ -WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type, - uint8_t is_ht, uint8_t ch_width, - uint8_t is_vht, bool is_he) +enum wlan_phymode +wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type, + uint8_t is_ht, uint8_t ch_width, + uint8_t is_vht, bool is_he) { - WLAN_PHY_MODE phymode = MODE_UNKNOWN; + enum wlan_phymode phymode = WLAN_PHYMODE_AUTO; switch (nw_type) { case eSIR_11B_NW_TYPE: @@ -3962,65 +3299,71 @@ WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, uint8_t sta_type, if (STA_ENTRY_TDLS_PEER == sta_type) { if (is_vht) { if (CH_WIDTH_80MHZ == ch_width) - phymode = MODE_11AC_VHT80; + phymode = WLAN_PHYMODE_11AC_VHT80; else phymode = (CH_WIDTH_40MHZ == ch_width) ? - MODE_11AC_VHT40 : - MODE_11AC_VHT20; + WLAN_PHYMODE_11AC_VHT40 : + WLAN_PHYMODE_11AC_VHT20_2G; } else if (is_ht) { phymode = (CH_WIDTH_40MHZ == ch_width) ? - MODE_11NG_HT40 : MODE_11NG_HT20; + WLAN_PHYMODE_11NG_HT40 : + WLAN_PHYMODE_11NG_HT20; } else - phymode = MODE_11B; + phymode = WLAN_PHYMODE_11B; } else #endif /* FEATURE_WLAN_TDLS */ { - phymode = MODE_11B; + phymode = WLAN_PHYMODE_11B; if (is_ht || is_vht || is_he) WMA_LOGE("HT/VHT is enabled with 11B NW type"); } break; case eSIR_11G_NW_TYPE: if (!(is_ht || is_vht || is_he)) { - phymode = MODE_11G; + phymode = WLAN_PHYMODE_11G; break; } if (CH_WIDTH_40MHZ < ch_width) WMA_LOGE("80/160 MHz BW sent in 11G, configured 40MHz"); if (ch_width) - phymode = (is_he) ? MODE_11AX_HE40_2G : (is_vht) ? - MODE_11AC_VHT40_2G : MODE_11NG_HT40; + phymode = (is_he) ? WLAN_PHYMODE_11AXG_HE40 : (is_vht) ? + WLAN_PHYMODE_11AC_VHT40_2G : + WLAN_PHYMODE_11NG_HT40; else - phymode = (is_he) ? MODE_11AX_HE20_2G : (is_vht) ? - MODE_11AC_VHT20_2G : MODE_11NG_HT20; + phymode = (is_he) ? WLAN_PHYMODE_11AXG_HE20 : (is_vht) ? + WLAN_PHYMODE_11AC_VHT20_2G : + WLAN_PHYMODE_11NG_HT20; break; case eSIR_11A_NW_TYPE: if (!(is_ht || is_vht || is_he)) { - phymode = MODE_11A; + phymode = WLAN_PHYMODE_11A; break; } if (is_he) { if (ch_width == CH_WIDTH_160MHZ) - phymode = MODE_11AX_HE160; + phymode = WLAN_PHYMODE_11AXA_HE160; else if (ch_width == CH_WIDTH_80P80MHZ) - phymode = MODE_11AX_HE80_80; + phymode = WLAN_PHYMODE_11AXA_HE80_80; else if (ch_width == CH_WIDTH_80MHZ) - phymode = MODE_11AX_HE80; + phymode = WLAN_PHYMODE_11AXA_HE80; else phymode = (ch_width) ? - MODE_11AX_HE40 : MODE_11AX_HE20; + WLAN_PHYMODE_11AXA_HE40 : + WLAN_PHYMODE_11AXA_HE20; } else if (is_vht) { if (ch_width == CH_WIDTH_160MHZ) - phymode = MODE_11AC_VHT160; + phymode = WLAN_PHYMODE_11AC_VHT160; else if (ch_width == CH_WIDTH_80P80MHZ) - phymode = MODE_11AC_VHT80_80; + phymode = WLAN_PHYMODE_11AC_VHT80_80; else if (ch_width == CH_WIDTH_80MHZ) - phymode = MODE_11AC_VHT80; + phymode = WLAN_PHYMODE_11AC_VHT80; else phymode = (ch_width) ? - MODE_11AC_VHT40 : MODE_11AC_VHT20; + WLAN_PHYMODE_11AC_VHT40 : + WLAN_PHYMODE_11AC_VHT20; } else - phymode = (ch_width) ? MODE_11NA_HT40 : MODE_11NA_HT20; + phymode = (ch_width) ? WLAN_PHYMODE_11NA_HT40 : + WLAN_PHYMODE_11NA_HT20; break; default: WMA_LOGE("%s: Invalid nw type %d", __func__, nw_type); @@ -4044,7 +3387,6 @@ int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle, uint8_t vdev_id, uint32_t value) { struct ol_txrx_stats_req req; - struct cdp_vdev *vdev; void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!soc) { @@ -4052,14 +3394,9 @@ int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle, return -EINVAL; } - vdev = wma_find_vdev_by_id(wma_handle, vdev_id); - if (!vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); - return -EINVAL; - } qdf_mem_zero(&req, sizeof(req)); req.stats_type_reset_mask = value; - cdp_fw_stats_get(soc, vdev, &req, false, false); + cdp_fw_stats_get(soc, vdev_id, &req, false, false); return 0; } @@ -4110,7 +3447,6 @@ int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle, uint8_t vdev_id, uint32_t value) { struct ol_txrx_stats_req req; - struct cdp_vdev *vdev; uint32_t l_up_mask; void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -4119,12 +3455,6 @@ int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle, return -EINVAL; } - vdev = wma_find_vdev_by_id(wma_handle, vdev_id); - if (!vdev) { - WMA_LOGE("%s:Invalid vdev handle", __func__); - return -EINVAL; - } - if (wma_is_valid_fw_stats_cmd(value) == false) return -EINVAL; @@ -4135,134 +3465,11 @@ int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle, l_up_mask = 1 << (value - 1); req.stats_type_upload_mask = l_up_mask; - cdp_fw_stats_get(soc, vdev, &req, false, true); + cdp_fw_stats_get(soc, vdev_id, &req, false, true); return 0; } -#ifndef QCA_SUPPORT_CP_STATS -/** - * wma_get_stats_rsp_buf() - fill get stats response buffer - * @get_stats_param: get stats parameters - * - * Return: stats response buffer - */ -static tAniGetPEStatsRsp *wma_get_stats_rsp_buf - (tAniGetPEStatsReq *get_stats_param) -{ - tAniGetPEStatsRsp *stats_rsp_params; - uint32_t len, temp_mask; - - len = sizeof(tAniGetPEStatsRsp); - temp_mask = get_stats_param->statsMask; - - if (temp_mask & (1 << eCsrSummaryStats)) - len += sizeof(tCsrSummaryStatsInfo); - - if (temp_mask & (1 << eCsrGlobalClassAStats)) - len += sizeof(tCsrGlobalClassAStatsInfo); - - if (temp_mask & (1 << eCsrGlobalClassDStats)) - len += sizeof(tCsrGlobalClassDStatsInfo); - - if (temp_mask & (1 << csr_per_chain_rssi_stats)) - len += sizeof(struct csr_per_chain_rssi_stats_info); - - stats_rsp_params = qdf_mem_malloc(len); - if (!stats_rsp_params) { - QDF_ASSERT(0); - return NULL; - } - - stats_rsp_params->staId = get_stats_param->staId; - stats_rsp_params->statsMask = get_stats_param->statsMask; - stats_rsp_params->msgType = WMA_GET_STATISTICS_RSP; - stats_rsp_params->msgLen = len - sizeof(tAniGetPEStatsRsp); - stats_rsp_params->rc = QDF_STATUS_SUCCESS; - return stats_rsp_params; -} - -/** - * wma_get_stats_req() - get stats request - * @handle: wma handle - * @get_stats_param: stats params - * - * Return: none - */ -void wma_get_stats_req(WMA_HANDLE handle, - tAniGetPEStatsReq *get_stats_param) -{ - tp_wma_handle wma_handle = (tp_wma_handle) handle; - struct wma_txrx_node *node; - struct stats_request_params cmd = {0}; - tAniGetPEStatsRsp *pGetPEStatsRspParams; - - - WMA_LOGD("%s: Enter", __func__); - node = &wma_handle->interfaces[get_stats_param->sessionId]; - if (node->stats_rsp) { - pGetPEStatsRspParams = node->stats_rsp; - if (pGetPEStatsRspParams->staId == get_stats_param->staId && - pGetPEStatsRspParams->statsMask == - get_stats_param->statsMask) { - WMA_LOGD("Stats for staId %d with stats mask %d is pending.. ignore new request", - get_stats_param->staId, - get_stats_param->statsMask); - pGetPEStatsRspParams = - wma_get_stats_rsp_buf(get_stats_param); - if (!pGetPEStatsRspParams) { - WMA_LOGE("failed to allocate memory for stats response"); - goto end; - } - goto req_pending; - } else { - qdf_mem_free(node->stats_rsp); - node->stats_rsp = NULL; - node->fw_stats_set = 0; - } - } - - pGetPEStatsRspParams = wma_get_stats_rsp_buf(get_stats_param); - if (!pGetPEStatsRspParams) - goto end; - - node->fw_stats_set = 0; - if (node->stats_rsp) { - WMA_LOGD(FL("stats_rsp is not null, prev_value: %pK"), - node->stats_rsp); - qdf_mem_free(node->stats_rsp); - node->stats_rsp = NULL; - } - node->stats_rsp = pGetPEStatsRspParams; - wma_handle->get_sta_peer_info = false; - WMA_LOGD("stats_rsp allocated: %pK, sta_id: %d, mask: %d, vdev_id: %d", - node->stats_rsp, node->stats_rsp->staId, - node->stats_rsp->statsMask, get_stats_param->sessionId); - - cmd.vdev_id = get_stats_param->sessionId; - cmd.stats_id = get_stats_param->statsMask; - if (wmi_unified_stats_request_send(wma_handle->wmi_handle, - node->bssid, - &cmd)) { - WMA_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", - __func__); - goto failed; - } - - goto end; -failed: - node->stats_rsp = NULL; -req_pending: - pGetPEStatsRspParams->rc = QDF_STATUS_E_FAILURE; - /* send response to UMAC */ - wma_send_msg(wma_handle, WMA_GET_STATISTICS_RSP, pGetPEStatsRspParams, - 0); -end: - qdf_mem_free(get_stats_param); - WMA_LOGD("%s: Exit", __func__); -} -#endif /* QCA_SUPPORT_CP_STATS */ - /** * wma_get_cca_stats() - send request to fw to get CCA * @wma_handle: wma handle @@ -4337,15 +3544,10 @@ void *wma_get_beacon_buffer_by_vdev_id(uint8_t vdev_id, uint32_t *buffer_size) return buf; } -/** - * wma_get_vdev_address_by_vdev_id() - lookup MAC address from vdev ID - * @vdev_id: vdev id - * - * Return: mac address - */ uint8_t *wma_get_vdev_address_by_vdev_id(uint8_t vdev_id) { tp_wma_handle wma; + struct wlan_objmgr_vdev *vdev; wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { @@ -4357,8 +3559,12 @@ uint8_t *wma_get_vdev_address_by_vdev_id(uint8_t vdev_id) WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id); return NULL; } - - return wma->interfaces[vdev_id].addr; + vdev = wma->interfaces[vdev_id].vdev; + if (!vdev) { + WMA_LOGE("%s: Invalid vdev for vdev_id %u", __func__, vdev_id); + return NULL; + } + return wlan_vdev_mlme_get_macaddr(vdev); } QDF_STATUS wma_get_connection_info(uint8_t vdev_id, @@ -4376,6 +3582,7 @@ QDF_STATUS wma_get_connection_info(uint8_t vdev_id, conn_table_entry->mhz = wma_conn_table_entry->mhz; conn_table_entry->sub_type = wma_conn_table_entry->sub_type; conn_table_entry->type = wma_conn_table_entry->type; + conn_table_entry->ch_flagext = wma_conn_table_entry->ch_flagext; return QDF_STATUS_SUCCESS; } @@ -4434,21 +3641,6 @@ struct wma_txrx_node *wma_get_interface_by_vdev_id(uint8_t vdev_id) return &wma->interfaces[vdev_id]; } -#ifdef WLAN_FEATURE_PKT_CAPTURE -int wma_get_rmf_status(uint8_t vdev_id) -{ - struct wma_txrx_node *iface; - - iface = wma_get_interface_by_vdev_id(vdev_id); - if (!iface) { - WMA_LOGE("Unable to get wma interface"); - return -EINVAL; - } - - return iface->rmfEnabled; -} -#endif - /** * wma_update_intf_hw_mode_params() - Update WMA params * @vdev_id: VDEV id whose params needs to be updated @@ -4485,22 +3677,17 @@ void wma_update_intf_hw_mode_params(uint32_t vdev_id, uint32_t mac_id, return; } wma->interfaces[vdev_id].mac_id = mac_id; - if (mac_id == 0) { + if (mac_id == 0) wma->interfaces[vdev_id].tx_streams = hw_mode.mac0_tx_ss; - wma->interfaces[vdev_id].rx_streams = - hw_mode.mac0_rx_ss; - } else { + else wma->interfaces[vdev_id].tx_streams = hw_mode.mac1_tx_ss; - wma->interfaces[vdev_id].rx_streams = - hw_mode.mac1_tx_ss; - } - WMA_LOGD("%s: vdev %d, update tx ss:%d rx ss:%d mac %d hw_mode_id %d", + + WMA_LOGD("%s: vdev %d, update tx ss:%d mac %d hw_mode_id %d", __func__, vdev_id, wma->interfaces[vdev_id].tx_streams, - wma->interfaces[vdev_id].rx_streams, mac_id, cfgd_hw_mode_index); } @@ -4721,38 +3908,20 @@ void wma_release_wakelock(qdf_wake_lock_t *wl) qdf_runtime_pm_allow_suspend(&wma->wmi_cmd_rsp_runtime_lock); } -QDF_STATUS -wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params) -{ - QDF_STATUS status; - struct wma_txrx_node *vdev = &wma->interfaces[params->vdev_id]; - - if (!wma_is_vdev_valid(params->vdev_id)) { - WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id); - status = QDF_STATUS_E_FAILURE; - return status; - } - wma_acquire_wakelock(&vdev->vdev_start_wakelock, - WMA_VDEV_START_REQUEST_TIMEOUT); - qdf_runtime_pm_prevent_suspend(&vdev->vdev_start_runtime_wakelock); - status = wmi_unified_vdev_start_send(wma->wmi_handle, params); - if (QDF_IS_STATUS_ERROR(status)) { - qdf_runtime_pm_allow_suspend( - &vdev->vdev_start_runtime_wakelock); - wma_release_wakelock(&vdev->vdev_start_wakelock); - } - - return status; -} - QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + struct vdev_mlme_obj *vdev_mlme = NULL; if (!wma_is_vdev_valid(vdev_id)) { WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id); - status = QDF_STATUS_E_FAILURE; + return status; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!vdev_mlme) { + WMA_LOGE("Failed to get vdev mlme obj for vdev id %d", vdev_id); return status; } @@ -4765,16 +3934,8 @@ QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) qdf_mem_copy(mlme_get_dynamic_vdev_config(iface->vdev), mlme_get_ini_vdev_config(iface->vdev), sizeof(struct wlan_mlme_nss_chains)); - wma_acquire_wakelock(&iface->vdev_stop_wakelock, - WMA_VDEV_STOP_REQUEST_TIMEOUT); - qdf_runtime_pm_prevent_suspend( - &iface->vdev_stop_runtime_wakelock); - status = wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id); - if (QDF_IS_STATUS_ERROR(status)) { - qdf_runtime_pm_allow_suspend( - &iface->vdev_stop_runtime_wakelock); - wma_release_wakelock(&iface->vdev_stop_wakelock); - } + + status = vdev_mgr_stop_send(vdev_mlme); return status; } @@ -4887,13 +4048,22 @@ static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id, { QDF_STATUS status; uint32_t flag = 0; - bool bmiss_skip_full_scan; bool disable_4way_hs_offload; + bool bmiss_skip_full_scan; if (is_set) { flag = WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG | WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG; + wlan_mlme_get_4way_hs_offload(wma->psoc, + &disable_4way_hs_offload); + /* + * If 4-way HS offload is disabled then let supplicant handle + * 4way HS and firmware will still do LFR3.0 till reassoc phase. + */ + if (disable_4way_hs_offload) + flag |= WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE; + wlan_mlme_get_bmiss_skip_full_scan_value(wma->psoc, &bmiss_skip_full_scan); /* @@ -4904,15 +4074,6 @@ static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id, */ if (bmiss_skip_full_scan) flag |= WMI_ROAM_BMISS_FINAL_SCAN_TYPE_FLAG; - - wlan_mlme_get_4way_hs_offload(wma->psoc, - &disable_4way_hs_offload); - /* - * If 4-way HS offload is disabled then let supplicant handle - * 4way HS and firmware will still do LFR3.0 till reassoc phase. - */ - if (disable_4way_hs_offload) - flag |= WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE; } wma_debug("vdev_id:%d, is_set:%d, flag:%d", vdev_id, is_set, flag); @@ -4946,42 +4107,26 @@ void wma_update_roam_offload_flag(void *handle, wma_set_roam_offload_flag(wma, params->vdev_id, params->enable); } -QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, - struct vdev_up_params *params, - uint8_t bssid[QDF_MAC_ADDR_SIZE]) -{ - QDF_STATUS status; - struct wma_txrx_node *vdev; - - if (!wma_is_vdev_valid(params->vdev_id)) { - WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id); - return QDF_STATUS_E_FAILURE; - } - - vdev = &wma->interfaces[params->vdev_id]; - - status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params); - qdf_runtime_pm_allow_suspend(&vdev->vdev_start_runtime_wakelock); - wma_release_wakelock(&vdev->vdev_start_wakelock); - - return status; -} - QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id) { - QDF_STATUS status; - struct wma_txrx_node *vdev; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + struct vdev_mlme_obj *vdev_mlme; if (!wma_is_vdev_valid(vdev_id)) { WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id); - return QDF_STATUS_E_FAILURE; + return status; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); + if (!vdev_mlme) { + WMA_LOGE("Failed to get vdev mlme obj for vdev id %d", vdev_id); + return status; } - vdev = &wma->interfaces[vdev_id]; wma->interfaces[vdev_id].roaming_in_progress = false; - status = wmi_unified_vdev_down_send(wma->wmi_handle, vdev_id); - qdf_runtime_pm_allow_suspend(&vdev->vdev_start_runtime_wakelock); - wma_release_wakelock(&vdev->vdev_start_wakelock); + + status = vdev_mgr_down_send(vdev_mlme); return status; } @@ -5202,73 +4347,55 @@ QDF_STATUS wma_get_roam_scan_stats(WMA_HANDLE handle, return QDF_STATUS_SUCCESS; } -void wma_remove_peer_on_add_bss_failure(tpAddBssParams add_bss_params) +void wma_remove_bss_peer_on_vdev_start_failure(tp_wma_handle wma, + uint8_t vdev_id) { - tp_wma_handle wma; - struct cdp_pdev *pdev; - void *peer = NULL; - uint8_t peer_id; + uint8_t pdev_id = WMI_PDEV_ID_SOC; void *soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; + struct qdf_mac_addr bss_peer; + struct wma_txrx_node *iface; - WMA_LOGE("%s: ADD BSS failure %d", __func__, add_bss_params->status); + iface = &wma->interfaces[vdev_id]; - pdev = cds_get_context(QDF_MODULE_ID_TXRX); - if (!pdev) { - WMA_LOGE("%s: Failed to get pdev", __func__); + status = mlme_get_vdev_bss_peer_mac_addr(iface->vdev, &bss_peer); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get bssid", __func__); return; } - peer = cdp_peer_find_by_addr(soc, pdev, add_bss_params->bssId, - &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", - __func__, add_bss_params->bssId); - return; - } + WMA_LOGE("%s: ADD BSS failure for vdev %d", __func__, vdev_id); - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s wma handle is NULL", __func__); + if (!cdp_find_peer_exist(soc, pdev_id, bss_peer.bytes)) { + WMA_LOGE("%s Failed to find peer "QDF_MAC_ADDR_FMT, + __func__, QDF_MAC_ADDR_REF(bss_peer.bytes)); return; } - wma_remove_peer(wma, add_bss_params->bssId, add_bss_params->bss_idx, - peer, false); + + wma_remove_peer(wma, bss_peer.bytes, vdev_id, false); } QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { - struct vdev_up_params param; uint8_t vdev_id; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); QDF_STATUS status; struct wma_txrx_node *iface; - struct vdev_mlme_mbss_11ax *mbss_11ax = NULL; if (!wma) { WMA_LOGE("%s wma handle is NULL", __func__); return QDF_STATUS_E_INVAL; } vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); - param.vdev_id = vdev_id; iface = &wma->interfaces[vdev_id]; - param.assoc_id = iface->aid; + vdev_mlme->proto.sta.assoc_id = iface->aid; - mlme_get_mbssid_info(vdev_mlme->vdev, &mbss_11ax); - if (mbss_11ax) { - param.profile_idx = mbss_11ax->profile_idx; - param.profile_num = mbss_11ax->profile_num; - qdf_mem_copy(param.trans_bssid, - mbss_11ax->trans_bssid, - QDF_MAC_ADDR_SIZE); - } - status = wma_send_vdev_up_to_fw(wma, ¶m, iface->bssid); + status = vdev_mgr_up_send(vdev_mlme); if (QDF_IS_STATUS_ERROR(status)) { - WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM", - __func__, vdev_id, iface->bssid); - policy_mgr_set_do_hw_mode_change_flag( - wma->psoc, false); + WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d", + __func__, vdev_id); status = QDF_STATUS_E_FAILURE; } else { wma_set_vdev_mgmt_rate(wma, vdev_id); @@ -5298,11 +4425,11 @@ bool wma_get_channel_switch_in_progress(struct wma_txrx_node *iface) } static QDF_STATUS wma_vdev_send_start_resp(tp_wma_handle wma, - tpAddBssParams add_bss) + struct add_bss_rsp *add_bss_rsp) { WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"), - add_bss->bss_idx, add_bss->status); - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0); + add_bss_rsp->vdev_id, add_bss_rsp->status); + lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp); return QDF_STATUS_SUCCESS; } @@ -5313,10 +4440,13 @@ QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); enum vdev_assoc_type assoc_type; + if (!wma) { + wma_err("Invalid wma handle"); + return QDF_STATUS_E_FAILURE; + } if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev)) { - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - data, 0); mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false); + lim_process_switch_channel_rsp(wma->mac_context, data); return QDF_STATUS_SUCCESS; } @@ -5324,12 +4454,10 @@ QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, switch (assoc_type) { case VDEV_ASSOC: case VDEV_REASSOC: - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - data, 0); + lim_process_switch_channel_rsp(wma->mac_context, data); break; case VDEV_FT_REASSOC: - wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, - data, 0); + lim_handle_add_bss_rsp(wma->mac_context, data); break; default: WMA_LOGE(FL("assoc_type %d is invalid"), assoc_type); @@ -5366,6 +4494,7 @@ QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, tp_wma_handle wma; QDF_STATUS status = QDF_STATUS_SUCCESS; struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; + uint8_t vdev_id; wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { @@ -5374,14 +4503,15 @@ QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, } if (mlme_is_chan_switch_in_progress(vdev)) { - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, - data, 0); mlme_set_chan_switch_in_progress(vdev, false); + lim_process_switch_channel_rsp(wma->mac_context, data); } else if (ap_mlme_is_hidden_ssid_restart_in_progress(vdev)) { - wma_send_msg(wma, WMA_HIDDEN_SSID_RESTART_RSP, data, 0); + vdev_id = vdev->vdev_objmgr.vdev_id; + lim_process_mlm_update_hidden_ssid_rsp(wma->mac_context, + vdev_id); ap_mlme_set_hidden_ssid_restart_in_progress(vdev, false); } else { - status = wma_vdev_send_start_resp(wma, (tpAddBssParams)data); + status = wma_vdev_send_start_resp(wma, data); } return status; @@ -5391,7 +4521,7 @@ QDF_STATUS wma_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { return __wma_handle_vdev_stop_rsp( - (wmi_vdev_stopped_event_fixed_param *)data); + (struct vdev_stop_response *)data); } QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, @@ -5404,7 +4534,7 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_E_INVAL; } - wma_send_vdev_down(wma, (struct wma_target_req *)data); + wma_send_vdev_down(wma, data); return QDF_STATUS_SUCCESS; } @@ -5414,7 +4544,9 @@ wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { tp_wma_handle wma; - struct wma_target_req *req = (struct wma_target_req *)data; + QDF_STATUS status; + uint32_t vdev_stop_type; + struct del_bss_resp *resp = (struct del_bss_resp *)data; if (mlme_is_connection_fail(vdev_mlme->vdev) || mlme_get_vdev_start_failed(vdev_mlme->vdev)) { @@ -5424,28 +4556,41 @@ wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme, mlme_set_vdev_start_failed(vdev_mlme->vdev, false); return QDF_STATUS_SUCCESS; } + wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { WMA_LOGE("%s wma handle is NULL", __func__); - return QDF_STATUS_E_INVAL; + status = QDF_STATUS_E_INVAL; + goto end; } - if (req->msg_type == WMA_DELETE_BSS_HO_FAIL_REQ) { - tpDeleteBssParams params = - (tpDeleteBssParams)req->user_data; - params->status = QDF_STATUS_SUCCESS; + status = mlme_get_vdev_stop_type(wma->interfaces[resp->vdev_id].vdev, + &vdev_stop_type); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to get msg_type", __func__); + status = QDF_STATUS_E_INVAL; + goto end; + } + + if (vdev_stop_type == WMA_DELETE_BSS_HO_FAIL_REQ) { + resp->status = QDF_STATUS_SUCCESS; wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP, - (void *)params, 0); + (void *)resp, 0); return QDF_STATUS_SUCCESS; } - if (req->msg_type == WMA_SET_LINK_STATE || - req->type == WMA_SET_LINK_PEER_RSP) - wma_send_set_link_response(wma, req); - else - wma_send_del_bss_response(wma, req); + if (vdev_stop_type == WMA_SET_LINK_STATE) { + lim_join_result_callback(wma->mac_context, + wlan_vdev_get_id(vdev_mlme->vdev)); + } else { + wma_send_del_bss_response(wma, resp); + return QDF_STATUS_SUCCESS; + } - return QDF_STATUS_SUCCESS; +end: + qdf_mem_free(resp); + + return status; } QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, @@ -5453,7 +4598,7 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { tp_wma_handle wma; - tpAddBssParams bss_params = (tpAddBssParams)data; + struct add_bss_rsp *add_bss_rsp = data; wma = cds_get_context(QDF_MODULE_ID_WMA); if (!wma) { @@ -5461,13 +4606,13 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_E_INVAL; } - if (wma_send_vdev_stop_to_fw(wma, bss_params->bss_idx)) + if (wma_send_vdev_stop_to_fw(wma, add_bss_rsp->vdev_id)) WMA_LOGE(FL("Failed to send vdev stop for vdev id %d"), - bss_params->bss_idx); + add_bss_rsp->vdev_id); - wma_remove_peer_on_add_bss_failure(bss_params); + wma_remove_bss_peer_on_vdev_start_failure(wma, add_bss_rsp->vdev_id); - return wma_vdev_send_start_resp(wma, bss_params); + return wma_vdev_send_start_resp(wma, add_bss_rsp); } QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, @@ -5483,7 +4628,7 @@ QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev)) mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false); - wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, data, 0); + lim_process_switch_channel_rsp(wma->mac_context, data); return QDF_STATUS_SUCCESS; } @@ -5491,7 +4636,6 @@ QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, uint16_t data_len, void *data) { - struct vdev_up_params param; uint8_t vdev_id; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); QDF_STATUS status; @@ -5502,14 +4646,13 @@ QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme, return QDF_STATUS_E_INVAL; } vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); - param.vdev_id = vdev_id; iface = &wma->interfaces[vdev_id]; + vdev_mlme->proto.sta.assoc_id = 0; - status = wma_send_vdev_up_to_fw(wma, ¶m, iface->bssid); - + status = vdev_mgr_up_send(vdev_mlme); if (QDF_IS_STATUS_ERROR(status)) - WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM", - __func__, vdev_id, iface->bssid); + WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d", + __func__, vdev_id); return status; } @@ -5797,8 +4940,8 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len) oem_event_data.data_len = event->data_len; oem_event_data.data = param_buf->data; - - pmac->sme.oem_data_event_handler_cb(&oem_event_data); + pmac->sme.oem_data_event_handler_cb(&oem_event_data, + pmac->sme.oem_data_vdev_id); return QDF_STATUS_SUCCESS; } diff --git a/drivers/staging/qcacld-3.0/os_if/fw_offload/src/os_if_fwol.c b/drivers/staging/qcacld-3.0/os_if/fw_offload/src/os_if_fwol.c index db9b26c836c842a45972de7fae891e81b93651f9..90ee99744f5e56165f26f151c8db13200cc16c97 100644 --- a/drivers/staging/qcacld-3.0/os_if/fw_offload/src/os_if_fwol.c +++ b/drivers/staging/qcacld-3.0/os_if/fw_offload/src/os_if_fwol.c @@ -38,13 +38,13 @@ int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev, req.vdev_id = vdev->vdev_objmgr.vdev_id; req.en_dis = nla_get_u8(attr); if (req.en_dis > 1) { - cfg80211_err("Invalid elna_bypass value %d", req.en_dis); + osif_err("Invalid elna_bypass value %d", req.en_dis); return -EINVAL; } status = ucfg_fwol_set_elna_bypass(vdev, &req); if (!QDF_IS_STATUS_SUCCESS(status)) - cfg80211_err("Failed to set ELNA BYPASS, %d", status); + osif_err("Failed to set ELNA BYPASS, %d", status); return qdf_status_to_os_return(status); } @@ -69,7 +69,7 @@ os_if_fwol_get_elna_bypass_callback(void *context, request = osif_request_get(context); if (!request) { - cfg80211_err("Obsolete request"); + osif_err("Obsolete request"); return; } @@ -99,7 +99,7 @@ int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev, request = osif_request_alloc(¶ms); if (!request) { - cfg80211_err("Request allocation failure"); + osif_err("Request allocation failure"); return -ENOMEM; } cookie = osif_request_cookie(request); @@ -108,21 +108,21 @@ int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev, os_if_fwol_get_elna_bypass_callback, cookie); if (!QDF_IS_STATUS_SUCCESS(status)) { - cfg80211_err("Failed to get ELNA BYPASS, %d", status); + osif_err("Failed to get ELNA BYPASS, %d", status); ret = qdf_status_to_os_return(status); goto end; } ret = osif_request_wait_for_response(request); if (ret) { - cfg80211_err("Operation timed out"); + osif_err("Operation timed out"); goto end; } priv = osif_request_priv(request); if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS, priv->en_dis)) { - cfg80211_err("put fail"); + osif_err("put fail"); ret = -EINVAL; } @@ -140,7 +140,7 @@ int os_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev, status = ucfg_fwol_send_dscp_up_map_to_fw(vdev, dscp_to_up_map); if (!QDF_IS_STATUS_SUCCESS(status)) - cfg80211_err("Failed to send dscp_up_map to FW, %d", status); + osif_err("Failed to send dscp_up_map to FW, %d", status); return qdf_status_to_os_return(status); } diff --git a/drivers/staging/qcacld-3.0/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c b/drivers/staging/qcacld-3.0/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c index dc65abe56aea16aa377098fb687ba4dadce4e00c..2357ab1db4a7a45b7555f4b582fa305745a69fc8 100644 --- a/drivers/staging/qcacld-3.0/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c +++ b/drivers/staging/qcacld-3.0/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -66,18 +66,18 @@ wlan_cfg80211_send_interop_issues_ap_cb( uint32_t index, len; if (!data) { - cfg80211_err("Invalid result."); + osif_err("Invalid result."); return; } pdev = data->pdev; if (!pdev) { - cfg80211_err("pdev is null."); + osif_err("pdev is null."); return; } os_priv = wlan_pdev_get_ospriv(pdev); if (!os_priv) { - cfg80211_err("os_priv is null."); + osif_err("os_priv is null."); return; } @@ -86,17 +86,17 @@ wlan_cfg80211_send_interop_issues_ap_cb( skb = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, len, index, GFP_KERNEL); if (!skb) { - cfg80211_err("skb alloc failed"); + osif_err("skb alloc failed"); return; } - cfg80211_debug("interop issues ap mac:" QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(data->rap_addr.bytes)); + osif_debug("interop issues ap mac:" QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(data->rap_addr.bytes)); if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID, QDF_MAC_ADDR_SIZE, data->rap_addr.bytes)) { - cfg80211_err("nla put fail"); + osif_err("nla put fail"); kfree_skb(skb); return; } @@ -131,7 +131,7 @@ wlan_parse_interop_issues_ap(struct qdf_mac_addr *interop_issues_ap, nla_for_each_nested(curr_attr, attr, rem) { if (i == MAX_INTEROP_ISSUES_AP_NUM) { - cfg80211_err("Ignoring excess"); + osif_err("Ignoring excess"); break; } @@ -140,18 +140,18 @@ wlan_parse_interop_issues_ap(struct qdf_mac_addr *interop_issues_ap, nla_data(curr_attr), nla_len(curr_attr), interop_issues_ap_policy)) { - cfg80211_err("nla_parse failed"); + osif_err("nla_parse failed"); return -EINVAL; } if (!tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID]) { - cfg80211_err("attr addr failed"); + osif_err("attr addr failed"); return -EINVAL; } nla_memcpy(interop_issues_ap[i].bytes, tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID], QDF_MAC_ADDR_SIZE); - cfg80211_debug(QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(interop_issues_ap[i].bytes)); + osif_debug(QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(interop_issues_ap[i].bytes)); i++; } @@ -178,12 +178,24 @@ __wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy, struct nlattr *attr; uint32_t count = 0; struct wlan_interop_issues_ap_info interop_issues_ap = {0}; + struct wlan_objmgr_psoc *psoc; + + if (!adapter->vdev) { + osif_err("Invalid vdev"); + return -EINVAL; + } + + psoc = wlan_vdev_get_psoc(adapter->vdev); + if (!psoc) { + osif_err("Invalid psoc"); + return -EINVAL; + } if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX, data, data_len, interop_issues_ap_policy)) { - cfg80211_err("Invalid ATTR"); + osif_err("Invalid ATTR"); return -EINVAL; } @@ -196,14 +208,15 @@ __wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy, return -EINVAL; } - cfg80211_debug("Num of interop issues ap: %d", count); + osif_debug("Num of interop issues ap: %d", count); interop_issues_ap.count = count; + interop_issues_ap.detect_enable = true; /* * need to figure out a converged way of obtaining the vdev for * a given netdev that doesn't involve the legacy mechanism. */ - ucfg_set_interop_issues_ap_config(adapter->vdev, &interop_issues_ap); + ucfg_set_interop_issues_ap_config(psoc, &interop_issues_ap); return 0; } @@ -234,10 +247,20 @@ void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev) * cnss-daemon does not restart. */ uint8_t fmac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct wlan_interop_issues_ap_info interop_issues_ap = {0}; struct wlan_interop_issues_ap_event data; + struct wlan_objmgr_psoc *psoc; wlan_interop_issues_ap_register_cbk(pdev); + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + osif_err("Invalid psoc"); + return; + } + interop_issues_ap.detect_enable = true; + ucfg_set_interop_issues_ap_config(psoc, &interop_issues_ap); + data.pdev = pdev; qdf_mem_copy(data.rap_addr.bytes, fmac, QDF_MAC_ADDR_SIZE); diff --git a/drivers/staging/qcacld-3.0/os_if/nan/inc/os_if_nan.h b/drivers/staging/qcacld-3.0/os_if/nan/inc/os_if_nan.h index c04a753673a4b39df4fc58014d74a380aa33aa25..3c474fd489babff028e67a1a626eeeff4cba80bc 100644 --- a/drivers/staging/qcacld-3.0/os_if/nan/inc/os_if_nan.h +++ b/drivers/staging/qcacld-3.0/os_if/nan/inc/os_if_nan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -78,13 +78,11 @@ int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc, * @psoc: pointer to psoc object * @vdev_id: vdev id of ndi * @success: if create was success or failure - * @sta_id: sta_id of the NDI * * Return: None */ void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool success, - uint8_t sta_id); + uint8_t vdev_id, bool success); /** * os_if_nan_post_ndi_delete_rsp: os_if api to pos ndi delete rsp to umac nan @@ -148,34 +146,22 @@ static inline QDF_STATUS os_if_nan_set_ndp_delete_transaction_id( return ucfg_nan_set_ndp_delete_transaction_id(vdev, val); } -/** - * os_if_nan_legacy_req: os_if api to handle NAN requests attached to the vendor - * command QCA_NL80211_VENDOR_SUBCMD_NAN - * @psoc: pointer to psoc object - * @data: request data. contains vendor cmd tlvs - * @data_len: length of data - * - * Return: status of operation - */ -int os_if_nan_legacy_req(struct wlan_objmgr_psoc *psoc, const void *data, - int data_len); - /** * os_if_process_nan_req: os_if api to handle NAN requests attached to the * vendor command QCA_NL80211_VENDOR_SUBCMD_NAN_EXT * @psoc: pointer to psoc object + * @vdev_id: NAN vdev id * @data: request data. contains vendor cmd tlvs * @data_len: length of data * * Return: status of operation */ -int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, +int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, const void *data, int data_len); #else static inline void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool success, - uint8_t sta_id) + uint8_t vdev_id, bool success) { } diff --git a/drivers/staging/qcacld-3.0/os_if/nan/src/os_if_nan.c b/drivers/staging/qcacld-3.0/os_if/nan/src/os_if_nan.c index 4145d55318c300e292b8d6002a8b42c9b27579fa..b171d90a789a699e662b6d34afcee2104578d2d5 100644 --- a/drivers/staging/qcacld-3.0/os_if/nan/src/os_if_nan.c +++ b/drivers/staging/qcacld-3.0/os_if/nan/src/os_if_nan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -279,18 +279,18 @@ static int __os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *nan_vdev; struct nan_callbacks cb_obj; - cfg80211_debug("enter"); + osif_debug("enter"); nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); if (nan_vdev) { - cfg80211_err("NAN data interface %s is already present", - iface_name); + osif_err("NAN data interface %s is already present", + iface_name); wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID); return -EEXIST; } if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("transaction id is unavailable"); + osif_err("transaction id is unavailable"); return -EINVAL; } transaction_id = @@ -298,13 +298,13 @@ static int __os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc, status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Couldn't get ballback object"); + osif_err("Couldn't get ballback object"); return -EINVAL; } ret = cb_obj.ndi_open(iface_name); if (ret) { - cfg80211_err("ndi_open failed"); + osif_err("ndi_open failed"); return ret; } @@ -433,13 +433,13 @@ static int __os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *nan_vdev = NULL; if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("Transaction id is unavailable"); + osif_err("Transaction id is unavailable"); return -EINVAL; } nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); if (!nan_vdev) { - cfg80211_debug("Nan datapath interface is not present"); + osif_debug("Nan datapath interface is not present"); return -EINVAL; } @@ -455,12 +455,12 @@ static int __os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc, /* check if there are active peers on the adapter */ if (num_peers) - cfg80211_err("NDP peers active: %d, active NDPs may not be terminated", - num_peers); + osif_err("NDP peers active: %d, active NDPs may not be terminated", + num_peers); status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Couldn't get ballback object"); + osif_err("Couldn't get ballback object"); return -EINVAL; } @@ -523,7 +523,7 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, struct ndp_service_name *service_name) { if (!ncs_sk_type || !pmk || !passphrase || !service_name) { - cfg80211_err("out buffers for one ore more parameters is null"); + osif_err("out buffers for one ore more parameters is null"); return -EINVAL; } @@ -537,7 +537,7 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, qdf_mem_copy(pmk->pmk, nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]), pmk->pmk_len); - cfg80211_err("pmk len: %d", pmk->pmk_len); + osif_err("pmk len: %d", pmk->pmk_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, pmk->pmk, pmk->pmk_len); } @@ -548,7 +548,7 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, qdf_mem_copy(passphrase->passphrase, nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]), passphrase->passphrase_len); - cfg80211_err("passphrase len: %d", passphrase->passphrase_len); + osif_err("passphrase len: %d", passphrase->passphrase_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, passphrase->passphrase, passphrase->passphrase_len); @@ -561,8 +561,8 @@ static int os_if_nan_parse_security_params(struct nlattr **tb, nla_data( tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]), service_name->service_name_len); - cfg80211_err("service_name len: %d", - service_name->service_name_len); + osif_err("service_name len: %d", + service_name->service_name_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, service_name->service_name, service_name->service_name_len); @@ -604,12 +604,12 @@ static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); if (!nan_vdev) { - cfg80211_err("NAN data interface %s not available", iface_name); + osif_err("NAN data interface %s not available", iface_name); return -EINVAL; } if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { - cfg80211_err("Interface found is not NDI"); + osif_err("Interface found is not NDI"); ret = -EINVAL; goto initiator_req_failed; } @@ -618,20 +618,20 @@ static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, if (state == NAN_DATA_NDI_DELETED_STATE || state == NAN_DATA_NDI_DELETING_STATE || state == NAN_DATA_NDI_CREATING_STATE) { - cfg80211_err("Data request not allowed in NDI current state: %d", - state); + osif_err("Data request not allowed in NDI current state: %d", + state); ret = -EINVAL; goto initiator_req_failed; } if (!ucfg_nan_is_sta_ndp_concurrency_allowed(psoc, nan_vdev)) { - cfg80211_err("NDP creation not allowed"); + osif_err("NDP creation not allowed"); ret = -EOPNOTSUPP; goto initiator_req_failed; } if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("Transaction ID is unavailable"); + osif_err("Transaction ID is unavailable"); ret = -EINVAL; goto initiator_req_failed; } @@ -645,14 +645,14 @@ static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, req.channel_cfg = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]); } else { - cfg80211_err("Channel config is unavailable"); + osif_err("Channel config is unavailable"); ret = -EINVAL; goto initiator_req_failed; } } if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) { - cfg80211_err("NDP service instance ID is unavailable"); + osif_err("NDP service instance ID is unavailable"); ret = -EINVAL; goto initiator_req_failed; } @@ -663,7 +663,7 @@ static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE); if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) { - cfg80211_err("NDI peer discovery mac addr is unavailable"); + osif_err("NDI peer discovery mac addr is unavailable"); ret = -EINVAL; goto initiator_req_failed; } @@ -697,7 +697,7 @@ static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc, if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, &req.passphrase, &req.service_name)) { - cfg80211_err("inconsistent security params in request."); + osif_err("inconsistent security params in request."); ret = -EINVAL; goto initiator_req_failed; } @@ -769,7 +769,7 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, struct nan_datapath_responder_req req = {0}; if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { - cfg80211_err("ndp_rsp is unavailable"); + osif_err("ndp_rsp is unavailable"); return -EINVAL; } req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); @@ -778,19 +778,19 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, /* Check for an existing NAN interface */ nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name); if (!nan_vdev) { - cfg80211_err("NAN data iface %s not available", - iface_name); + osif_err("NAN data iface %s not available", + iface_name); return -ENODEV; } if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) { - cfg80211_err("Interface found is not NDI"); + osif_err("Interface found is not NDI"); ret = -ENODEV; goto responder_req_failed; } if (!ucfg_nan_is_sta_ndp_concurrency_allowed(psoc, nan_vdev)) { - cfg80211_err("NDP creation not allowed"); + osif_err("NDP creation not allowed"); ret = -EOPNOTSUPP; goto responder_req_failed; } @@ -800,12 +800,12 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, * may not send the iface name. Use the first NDI * in that case */ - cfg80211_debug("ndp rsp rejected, using first NDI"); + osif_debug("ndp rsp rejected, using first NDI"); nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc( psoc, QDF_NDI_MODE, WLAN_NAN_ID); if (!nan_vdev) { - cfg80211_err("NAN data iface is not available"); + osif_err("NAN data iface is not available"); return -ENODEV; } } @@ -814,14 +814,14 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, if (state == NAN_DATA_NDI_DELETED_STATE || state == NAN_DATA_NDI_DELETING_STATE || state == NAN_DATA_NDI_CREATING_STATE) { - cfg80211_err("Data request not allowed in current NDI state:%d", - state); + osif_err("Data request not allowed in current NDI state:%d", + state); ret = -EAGAIN; goto responder_req_failed; } if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("Transaction ID is unavailable"); + osif_err("Transaction ID is unavailable"); ret = -EINVAL; goto responder_req_failed; } @@ -829,7 +829,7 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) { - cfg80211_err("Instance ID is unavailable"); + osif_err("Instance ID is unavailable"); ret = -EINVAL; goto responder_req_failed; } @@ -843,7 +843,7 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), req.ndp_info.ndp_app_info_len); } else { - cfg80211_debug("NDP app info is unavailable"); + osif_debug("NDP app info is unavailable"); } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { @@ -852,7 +852,7 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, *((uint32_t *)req.ndp_config.ndp_cfg) = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); } else { - cfg80211_debug("NDP config data is unavailable"); + osif_debug("NDP config data is unavailable"); } if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) { @@ -871,23 +871,23 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc, req.protocol = nla_get_u8( tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]); } - cfg80211_debug("ipv6 addr present: %d, addr: %pI6", - req.is_ipv6_addr_present, req.ipv6_addr); - cfg80211_debug("port %d, present: %d protocol %d, present: %d", - req.port, req.is_port_present, req.protocol, - req.is_protocol_present); + osif_debug("ipv6 addr present: %d, addr: %pI6", + req.is_ipv6_addr_present, req.ipv6_addr); + osif_debug("port %d, present: %d protocol %d, present: %d", + req.port, req.is_port_present, req.protocol, + req.is_protocol_present); if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk, &req.passphrase, &req.service_name)) { - cfg80211_err("inconsistent security params in request."); + osif_err("inconsistent security params in request."); ret = -EINVAL; goto responder_req_failed; } - cfg80211_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d", - wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp, - req.ndp_instance_id, req.ndp_info.ndp_app_info_len, - req.ncs_sk_type); + osif_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d", + wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp, + req.ndp_instance_id, req.ndp_info.ndp_app_info_len, + req.ncs_sk_type); req.vdev = nan_vdev; status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ); @@ -947,14 +947,14 @@ static int __os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, struct nan_datapath_end_req req = {0}; if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("Transaction ID is unavailable"); + osif_err("Transaction ID is unavailable"); return -EINVAL; } req.transaction_id = nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { - cfg80211_err("NDP instance ID array is unavailable"); + osif_err("NDP instance ID array is unavailable"); return -EINVAL; } @@ -962,20 +962,20 @@ static int __os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc, nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) / sizeof(uint32_t); if (0 >= req.num_ndp_instances) { - cfg80211_err("Num NDP instances is 0"); + osif_err("Num NDP instances is 0"); return -EINVAL; } qdf_mem_copy(req.ndp_ids, nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]), req.num_ndp_instances * sizeof(uint32_t)); - cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d", - req.transaction_id); + osif_debug("sending ndp_end_req to SME, transaction_id: %d", + req.transaction_id); nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE, WLAN_NAN_ID); if (!nan_vdev) { - cfg80211_err("NAN data interface is not available"); + osif_err("NAN data interface is not available"); return -EINVAL; } @@ -1030,19 +1030,19 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, data, data_len, vendor_attr_policy)) { - cfg80211_err("Invalid NDP vendor command attributes"); + osif_err("Invalid NDP vendor command attributes"); return -EINVAL; } /* Parse and fetch NDP Command Type*/ if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) { - cfg80211_err("NAN datapath cmd type failed"); + osif_err("NAN datapath cmd type failed"); return -EINVAL; } ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]); if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { - cfg80211_err("attr transaction id failed"); + osif_err("attr transaction id failed"); return -EINVAL; } transaction_id = nla_get_u16( @@ -1050,11 +1050,11 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - cfg80211_debug("Transaction Id: %d NDPCmd: %d iface_name: %s", - transaction_id, ndp_cmd_type, iface_name); + osif_debug("Transaction Id: %u NDPCmd: %u iface_name: %s", + transaction_id, ndp_cmd_type, iface_name); } else { - cfg80211_debug("Transaction Id: %d NDPCmd: %d iface_name: unspecified", - transaction_id, ndp_cmd_type); + osif_debug("Transaction Id: %u NDPCmd: %u iface_name: unspecified", + transaction_id, ndp_cmd_type); } switch (ndp_cmd_type) { @@ -1064,24 +1064,24 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc, return os_if_nan_process_ndi_delete(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST: if (!is_ndp_allowed) { - cfg80211_err("Unsupported concurrency for NAN datapath"); + osif_err("Unsupported concurrency for NAN datapath"); return -EOPNOTSUPP; } return os_if_nan_process_ndp_initiator_req(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST: if (!is_ndp_allowed) { - cfg80211_err("Unsupported concurrency for NAN datapath"); + osif_err("Unsupported concurrency for NAN datapath"); return -EOPNOTSUPP; } return os_if_nan_process_ndp_responder_req(psoc, tb); case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST: if (!is_ndp_allowed) { - cfg80211_err("Unsupported concurrency for NAN datapath"); + osif_err("Unsupported concurrency for NAN datapath"); return -EOPNOTSUPP; } return os_if_nan_process_ndp_end_req(psoc, tb); default: - cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); + osif_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type); return -EINVAL; } @@ -1130,7 +1130,7 @@ static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!rsp) { - cfg80211_err("Invalid NDP Initator response"); + osif_err("Invalid NDP Initator response"); return; } @@ -1139,7 +1139,7 @@ static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1165,13 +1165,13 @@ static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev, rsp->reason)) goto ndp_initiator_rsp_nla_failed; - cfg80211_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d", - rsp->transaction_id, rsp->ndp_instance_id, rsp->status, - rsp->reason); + osif_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d", + rsp->transaction_id, rsp->ndp_instance_id, rsp->status, + rsp->reason); cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_initiator_rsp_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -1214,7 +1214,7 @@ static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!rsp) { - cfg80211_err("Invalid NDP Responder response"); + osif_err("Invalid NDP Responder response"); return; } @@ -1223,7 +1223,7 @@ static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1248,7 +1248,7 @@ static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev, cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_responder_rsp_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -1319,30 +1319,30 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!event) { - cfg80211_err("Invalid NDP Indication"); + osif_err("Invalid NDP Indication"); return; } - cfg80211_debug("NDP Indication, policy: %d", event->policy); + osif_debug("NDP Indication, policy: %d", event->policy); state = ucfg_nan_get_ndi_state(vdev); /* check if we are in middle of deleting/creating the interface */ if (state == NAN_DATA_NDI_DELETED_STATE || state == NAN_DATA_NDI_DELETING_STATE || state == NAN_DATA_NDI_CREATING_STATE) { - cfg80211_err("Data request not allowed in current NDI state: %d", - state); + osif_err("Data request not allowed in current NDI state: %d", + state); return; } ifname = os_if_ndi_get_if_name(vdev); if (!ifname) { - cfg80211_err("ifname is null"); + osif_err("ifname is null"); return; } ifname_len = qdf_str_len(ifname); if (ifname_len > IFNAMSIZ) { - cfg80211_err("ifname(%zu) too long", ifname_len); + osif_err("ifname(%zu) too long", ifname_len); return; } @@ -1353,7 +1353,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1410,8 +1410,8 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, event->scid.scid)) goto ndp_indication_nla_failed; - cfg80211_debug("csid: %d, scid_len: %d", - event->ncs_sk_type, event->scid.scid_len); + osif_debug("csid: %d, scid_len: %d", + event->ncs_sk_type, event->scid.scid_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG, event->scid.scid, event->scid.scid_len); @@ -1426,7 +1426,7 @@ static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev, cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_indication_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -1547,18 +1547,18 @@ os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!ndp_confirm) { - cfg80211_err("Invalid NDP Initator response"); + osif_err("Invalid NDP Initator response"); return; } ifname = os_if_ndi_get_if_name(vdev); if (!ifname) { - cfg80211_err("ifname is null"); + osif_err("ifname is null"); return; } ifname_len = qdf_str_len(ifname); if (ifname_len > IFNAMSIZ) { - cfg80211_err("ifname(%zu) too long", ifname_len); + osif_err("ifname(%zu) too long", ifname_len); return; } @@ -1567,7 +1567,7 @@ os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1629,14 +1629,14 @@ os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev, goto ndp_confirm_nla_failed; cfg80211_vendor_event(vendor_event, GFP_ATOMIC); - cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM rsp_code: %d, reason_code: %d", - ndp_confirm->ndp_instance_id, - ndp_confirm->peer_ndi_mac_addr.bytes, - ndp_confirm->rsp_code, ndp_confirm->reason_code); + osif_debug("NDP confim sent, ndp instance id: %d, peer addr: "QDF_MAC_ADDR_FMT" rsp_code: %d, reason_code: %d", + ndp_confirm->ndp_instance_id, + QDF_MAC_ADDR_REF(ndp_confirm->peer_ndi_mac_addr.bytes), + ndp_confirm->rsp_code, ndp_confirm->reason_code); return; ndp_confirm_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -1679,7 +1679,7 @@ static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!rsp) { - cfg80211_err("Invalid ndp end response"); + osif_err("Invalid ndp end response"); return; } @@ -1688,7 +1688,7 @@ static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1709,11 +1709,13 @@ static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev, rsp->transaction_id)) goto ndp_end_rsp_nla_failed; + osif_debug("NDP End rsp sent, transaction id: %u, status: %u, reason: %u", + rsp->transaction_id, rsp->status, rsp->reason); cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_end_rsp_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -1753,14 +1755,14 @@ static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!end_ind) { - cfg80211_err("Invalid ndp end indication"); + osif_err("Invalid ndp end indication"); return; } ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids * sizeof(*ndp_instance_array)); if (!ndp_instance_array) { - cfg80211_err("Failed to allocate ndp_instance_array"); + osif_err("Failed to allocate ndp_instance_array"); return; } for (i = 0; i < end_ind->num_ndp_ids; i++) @@ -1771,7 +1773,8 @@ static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + qdf_mem_free(ndp_instance_array); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -1789,7 +1792,7 @@ static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev, return; ndp_end_ind_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); qdf_mem_free(ndp_instance_array); } @@ -1812,29 +1815,29 @@ static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev, struct nan_callbacks cb_obj; if (!peer_ind) { - cfg80211_err("Invalid new NDP peer params"); + osif_err("Invalid new NDP peer params"); return; } status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("failed to get callbacks"); + osif_err("failed to get callbacks"); return; } - cfg80211_debug("vdev_id: %d, peer_mac: %pM", - vdev_id, peer_ind->peer_mac_addr.bytes); + osif_debug("vdev_id: %d, peer_mac: "QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(peer_ind->peer_mac_addr.bytes)); ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id, &peer_ind->peer_mac_addr, (active_peers == 0 ? true : false)); if (ret) { - cfg80211_err("new peer handling at HDD failed %d", ret); + osif_err("new peer handling at HDD failed %d", ret); return; } active_peers++; ucfg_nan_set_active_peers(vdev, active_peers); - cfg80211_debug("num_peers: %d", active_peers); + osif_debug("num_peers: %d", active_peers); } /** @@ -1855,16 +1858,16 @@ static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev, status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("failed to get callbacks"); + osif_err("failed to get callbacks"); return; } if (!peer_ind) { - cfg80211_err("Invalid new NDP peer params"); + osif_err("Invalid new NDP peer params"); return; } - cfg80211_debug("vdev_id: %d, peer_mac: %pM", - vdev_id, peer_ind->peer_mac_addr.bytes); + osif_debug("vdev_id: %d, peer_mac: "QDF_MAC_ADDR_FMT, + vdev_id, QDF_MAC_ADDR_REF(peer_ind->peer_mac_addr.bytes)); active_peers--; ucfg_nan_set_active_peers(vdev, active_peers); cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id, @@ -1924,7 +1927,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Couldn't get ballback object"); + osif_err("Couldn't get ballback object"); return; } @@ -1932,7 +1935,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, create_status = ndi_rsp->status; create_reason = ndi_rsp->reason; } else { - cfg80211_debug("Invalid ndi create response"); + osif_debug("Invalid ndi create response"); create_fail = true; } @@ -1945,7 +1948,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_KERNEL); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); create_fail = true; goto close_ndi; } @@ -1953,14 +1956,14 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, /* Sub vendor command */ if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) { - cfg80211_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"); + osif_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"); goto nla_put_failure; } /* Transaction id */ if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id)) { - cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); + osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); goto nla_put_failure; } @@ -1968,7 +1971,7 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, create_status)) { - cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); + osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); goto nla_put_failure; } @@ -1976,12 +1979,12 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason)) { - cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); + osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); goto nla_put_failure; } - cfg80211_debug("transaction id: %u status code: %u Reason: %u", - create_transaction_id, create_status, create_reason); + osif_debug("transaction id: %u status code: %u Reason: %u", + create_transaction_id, create_status, create_reason); cfg80211_vendor_event(vendor_event, GFP_KERNEL); @@ -1990,8 +1993,8 @@ static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc, cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev), ndi_rsp); } else { - cfg80211_err("NDI interface creation failed with reason %d", - create_reason); + osif_err("NDI interface creation failed with reason %d", + create_reason); goto close_ndi; } @@ -2021,21 +2024,21 @@ static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc, struct nan_callbacks cb_obj; if (!ndi_rsp) { - cfg80211_err("Invalid ndi delete response"); + osif_err("Invalid ndi delete response"); return; } status = ucfg_nan_get_callbacks(psoc, &cb_obj); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("Couldn't get ballback object"); + osif_err("Couldn't get ballback object"); return; } if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS) - cfg80211_debug("NDI BSS successfully stopped"); + osif_debug("NDI BSS successfully stopped"); else - cfg80211_debug("NDI BSS stop failed with reason %d", - ndi_rsp->reason); + osif_debug("NDI BSS stop failed with reason %d", + ndi_rsp->reason); ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason); ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status); @@ -2080,7 +2083,7 @@ static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event, int idx = 0; struct nlattr *ch_array, *ch_element; - cfg80211_debug("num_ch: %d", sch_update->num_channels); + osif_debug("num_ch: %d", sch_update->num_channels); if (!sch_update->num_channels) return QDF_STATUS_SUCCESS; @@ -2089,10 +2092,10 @@ static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event, return QDF_STATUS_E_FAULT; for (idx = 0; idx < sch_update->num_channels; idx++) { - cfg80211_debug("ch[%d]: freq: %d, width: %d, nss: %d", - idx, sch_update->ch[idx].freq, - sch_update->ch[idx].ch_width, - sch_update->ch[idx].nss); + osif_debug("ch[%d]: freq: %d, width: %d, nss: %d", + idx, sch_update->ch[idx].freq, + sch_update->ch[idx].ch_width, + sch_update->ch[idx].nss); ch_element = nla_nest_start(event, idx); if (!ch_element) return QDF_STATUS_E_FAULT; @@ -2138,18 +2141,18 @@ static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev, struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev); if (!sch_update) { - cfg80211_err("Invalid sch update params"); + osif_err("Invalid sch update params"); return; } ifname = os_if_ndi_get_if_name(vdev); if (!ifname) { - cfg80211_err("ifname is null"); + osif_err("ifname is null"); return; } ifname_len = qdf_str_len(ifname); if (ifname_len > IFNAMSIZ) { - cfg80211_err("ifname(%d) too long", ifname_len); + osif_err("ifname(%d) too long", ifname_len); return; } @@ -2158,7 +2161,7 @@ static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev, data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, GFP_ATOMIC); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } @@ -2189,18 +2192,18 @@ static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) goto ndp_sch_ind_nla_failed; - cfg80211_debug("Flags: %d, num_instance_id: %d", sch_update->flags, - sch_update->num_ndp_instances); + osif_debug("Flags: %d, num_instance_id: %d", sch_update->flags, + sch_update->num_ndp_instances); for (idx = 0; idx < sch_update->num_ndp_instances; idx++) - cfg80211_debug("ndp_instance[%d]: %d", idx, - sch_update->ndp_instances[idx]); + osif_debug("ndp_instance[%d]: %d", idx, + sch_update->ndp_instances[idx]); cfg80211_vendor_event(vendor_event, GFP_ATOMIC); return; ndp_sch_ind_nla_failed: - cfg80211_err("nla_put api failed"); + osif_err("nla_put api failed"); kfree_skb(vendor_event); } @@ -2220,13 +2223,13 @@ static void os_if_ndp_host_update_handler(struct wlan_objmgr_vdev *vdev, vdev_nan_obj = nan_get_vdev_priv_obj(vdev); if (!vdev_nan_obj) { - cfg80211_err("vdev_nan_obj is NULL"); + osif_err("vdev_nan_obj is NULL"); return; } request = osif_request_get(vdev_nan_obj->disable_context); if (!request) { - cfg80211_debug("Obsolete request"); + osif_debug("Obsolete request"); return; } @@ -2290,22 +2293,20 @@ int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc, } void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, bool success, - uint8_t sta_id) + uint8_t vdev_id, bool success) { struct nan_datapath_inf_create_rsp rsp = {0}; struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( psoc, vdev_id, WLAN_NAN_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } if (success) { rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS; rsp.reason = 0; - rsp.sta_id = sta_id; os_if_nan_datapath_event_handler(psoc, vdev, NAN_DATAPATH_INF_CREATE_RSP, &rsp); @@ -2326,7 +2327,7 @@ void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc( psoc, vdev_id, WLAN_NAN_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } @@ -2378,7 +2379,7 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) state = ucfg_nan_get_ndi_state(vdev); if (state != NAN_DATA_NDI_DELETING_STATE && state != NAN_DATA_DISCONNECTED_STATE) { - cfg80211_err("NDI interface deleted: state: %u", state); + osif_err("NDI interface deleted: state: %u", state); return; } @@ -2389,21 +2390,21 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) GFP_KERNEL); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); return; } /* Sub vendor command goes first */ if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) { - cfg80211_err("VENDOR_ATTR_NDP_SUBCMD put fail"); + osif_err("VENDOR_ATTR_NDP_SUBCMD put fail"); goto failure; } /* Transaction id */ if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, ucfg_nan_get_ndp_delete_transaction_id(vdev))) { - cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); + osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"); goto failure; } @@ -2411,7 +2412,7 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, ucfg_nan_get_ndi_delete_rsp_status(vdev))) { - cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); + osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"); goto failure; } @@ -2419,14 +2420,14 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev) if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, ucfg_nan_get_ndi_delete_rsp_reason(vdev))) { - cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); + osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"); goto failure; } - cfg80211_debug("delete transaction id: %u, status code: %u reason: %u", - ucfg_nan_get_ndp_delete_transaction_id(vdev), - ucfg_nan_get_ndi_delete_rsp_status(vdev), - ucfg_nan_get_ndi_delete_rsp_reason(vdev)); + osif_debug("delete transaction id: %u, status code: %u reason: %u", + ucfg_nan_get_ndp_delete_transaction_id(vdev), + ucfg_nan_get_ndi_delete_rsp_status(vdev), + ucfg_nan_get_ndi_delete_rsp_reason(vdev)); ucfg_nan_set_ndp_delete_transaction_id(vdev, 0); ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE); @@ -2458,7 +2459,7 @@ static void os_if_nan_discovery_event_handler(struct nan_event_params *nan_evt) */ pdev = wlan_objmgr_get_pdev_by_id(nan_evt->psoc, 0, WLAN_NAN_ID); if (!pdev) { - cfg80211_err("null pdev"); + osif_err("null pdev"); return; } os_priv = wlan_pdev_get_ospriv(pdev); @@ -2470,13 +2471,13 @@ static void os_if_nan_discovery_event_handler(struct nan_event_params *nan_evt) GFP_KERNEL); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); goto fail; } if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, nan_evt->buf_len, nan_evt->buf)) { - cfg80211_err("QCA_WLAN_VENDOR_ATTR_NAN put failed"); + osif_err("QCA_WLAN_VENDOR_ATTR_NAN put failed"); goto fail; } @@ -2504,7 +2505,7 @@ static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc, nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len); if (!nan_req) { - cfg80211_err("Request allocation failure"); + osif_err("Request allocation failure"); return -ENOMEM; } @@ -2516,48 +2517,14 @@ static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc, status = ucfg_nan_discovery_req(nan_req, NAN_GENERIC_REQ); if (QDF_IS_STATUS_SUCCESS(status)) - cfg80211_debug("Successfully sent a NAN request"); + osif_debug("Successfully sent a NAN request"); else - cfg80211_err("Unable to send a NAN request"); + osif_err("Unable to send a NAN request"); qdf_mem_free(nan_req); return qdf_status_to_os_return(status); } -int os_if_nan_legacy_req(struct wlan_objmgr_psoc *psoc, const void *data, - int data_len) -{ - struct nan_generic_req *nan_req; - QDF_STATUS status; - - if (data_len > NAN_CMD_MAX_SIZE) { - cfg80211_err("NAN request exceeding max allowed size"); - return -EINVAL; - } - - nan_req = qdf_mem_malloc(sizeof(*nan_req) + data_len); - if (!nan_req) - return -ENOMEM; - - nan_req->psoc = psoc; - nan_req->params.request_data_len = data_len; - qdf_mem_copy(nan_req->params.request_data, data, data_len); - - /* - * Send legacy NAN requests with type GENERIC, these will be treated as - * passthrough by the driver. These will not affect the NAN state - * machine or policy manager. - */ - status = ucfg_nan_discovery_req(nan_req, NAN_GENERIC_REQ); - - if (QDF_IS_STATUS_ERROR(status)) - cfg80211_err("Failed to post NAN request"); - - qdf_mem_free(nan_req); - - return qdf_status_to_os_return(status); -} - static int os_if_process_nan_disable_req(struct wlan_objmgr_psoc *psoc, struct nlattr **tb) { @@ -2577,14 +2544,13 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc, struct nlattr **tb) { uint32_t chan_freq_2g, chan_freq_5g = 0; - uint8_t nan_chan_2g; uint32_t buf_len; QDF_STATUS status; uint32_t fine_time_meas_cap; struct nan_enable_req *nan_req; if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]) { - cfg80211_err("NAN Social channel for 2.4Gz is unavailable!"); + osif_err("NAN Social channel for 2.4Gz is unavailable!"); return -EINVAL; } chan_freq_2g = @@ -2595,10 +2561,9 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc, nla_get_u32(tb[ QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ]); - nan_chan_2g = wlan_freq_to_chan(chan_freq_2g); - if (!ucfg_is_nan_enable_allowed(psoc, nan_chan_2g)) { - cfg80211_err("NAN Enable not allowed at this moment for channel %d", - nan_chan_2g); + if (!ucfg_is_nan_enable_allowed(psoc, chan_freq_2g)) { + osif_err("NAN Enable not allowed at this moment for channel %d", + chan_freq_2g); return -EINVAL; } @@ -2607,12 +2572,12 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc, nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len); if (!nan_req) { - cfg80211_err("Request allocation failure"); + osif_err("Request allocation failure"); return -ENOMEM; } - nan_req->social_chan_2g = wlan_freq_to_chan(chan_freq_2g); + nan_req->social_chan_2g_freq = chan_freq_2g; if (chan_freq_5g) - nan_req->social_chan_5g = wlan_freq_to_chan(chan_freq_5g); + nan_req->social_chan_5g_freq = chan_freq_5g; nan_req->psoc = psoc; nan_req->params.request_data_len = buf_len; @@ -2622,20 +2587,20 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc, nla_memcpy(nan_req->params.request_data, tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len); - cfg80211_debug("Sending NAN Enable Req. NAN Ch: %d %d", - nan_req->social_chan_2g, nan_req->social_chan_5g); + osif_debug("Sending NAN Enable Req. NAN Ch Freq: %d %d", + nan_req->social_chan_2g_freq, nan_req->social_chan_5g_freq); status = ucfg_nan_discovery_req(nan_req, NAN_ENABLE_REQ); if (QDF_IS_STATUS_SUCCESS(status)) - cfg80211_debug("Successfully sent NAN Enable request"); + osif_debug("Successfully sent NAN Enable request"); else - cfg80211_err("Unable to send NAN Enable request"); + osif_err("Unable to send NAN Enable request"); qdf_mem_free(nan_req); return qdf_status_to_os_return(status); } -int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, +int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, const void *data, int data_len) { uint32_t nan_subcmd; @@ -2643,12 +2608,12 @@ int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX, data, data_len, nan_attr_policy)) { - cfg80211_err("Invalid NAN vendor command attributes"); + osif_err("Invalid NAN vendor command attributes"); return -EINVAL; } if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]) { - cfg80211_err("NAN cmd data missing!"); + osif_err("NAN cmd data missing!"); return -EINVAL; } @@ -2658,8 +2623,10 @@ int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, * sure that HW mode is not set to DBS by NAN Enable request. NAN state * machine will remain unaffected in this case. */ - if (!ucfg_is_nan_dbs_supported(psoc)) + if (!ucfg_is_nan_dbs_supported(psoc)) { + policy_mgr_check_and_stop_opportunistic_timer(psoc, vdev_id); return os_if_nan_generic_req(psoc, tb); + } /* * Send all requests other than Enable/Disable as type GENERIC. @@ -2676,7 +2643,7 @@ int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ: return os_if_process_nan_disable_req(psoc, tb); default: - cfg80211_err("Unrecognized NAN subcmd type(%d)", nan_subcmd); + osif_err("Unrecognized NAN subcmd type(%d)", nan_subcmd); return -EINVAL; } } diff --git a/drivers/staging/qcacld-3.0/os_if/p2p/src/wlan_cfg80211_p2p.c b/drivers/staging/qcacld-3.0/os_if/p2p/src/wlan_cfg80211_p2p.c index 9d8fd353bcb275f70f479e22269714f4a2d5934d..ddeba7bf0d5166bfea02e8de25d45ff90d4f2bf1 100644 --- a/drivers/staging/qcacld-3.0/os_if/p2p/src/wlan_cfg80211_p2p.c +++ b/drivers/staging/qcacld-3.0/os_if/p2p/src/wlan_cfg80211_p2p.c @@ -53,54 +53,46 @@ static void wlan_p2p_rx_callback(void *user_data, struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; struct wireless_dev *wdev; - uint16_t freq; psoc = user_data; if (!psoc) { - cfg80211_err("psoc is null"); + osif_err("psoc is null"); return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rx_frame->vdev_id, WLAN_P2P_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is null"); + osif_err("osif_priv is null"); goto fail; } wdev = osif_priv->wdev; if (!wdev) { - cfg80211_err("wdev is null"); + osif_err("wdev is null"); goto fail; } - if (rx_frame->rx_chan <= MAX_NO_OF_2_4_CHANNELS) - freq = ieee80211_channel_to_frequency( - rx_frame->rx_chan, NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency( - rx_frame->rx_chan, NL80211_BAND_5GHZ); - - cfg80211_debug("Indicate frame over nl80211, idx:%d", - wdev->netdev->ifindex); + osif_debug("Indicate frame over nl80211, idx:%d", + wdev->netdev->ifindex); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, - NL80211_RXMGMT_FLAG_ANSWERED); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, - NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); #else - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC); #endif /* LINUX_VERSION_CODE */ fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); @@ -127,26 +119,26 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data, psoc = user_data; if (!psoc) { - cfg80211_err("psoc is null"); + osif_err("psoc is null"); return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_cnf->vdev_id, WLAN_P2P_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is null"); + osif_err("osif_priv is null"); goto fail; } wdev = osif_priv->wdev; if (!wdev) { - cfg80211_err("wireless dev is null"); + osif_err("wireless dev is null"); goto fail; } @@ -179,32 +171,32 @@ static void wlan_p2p_lo_event_callback(void *user_data, struct wireless_dev *wdev; struct sk_buff *vendor_event; - cfg80211_debug("user data:%pK, vdev id:%d, reason code:%d", - user_data, p2p_lo_event->vdev_id, - p2p_lo_event->reason_code); + osif_debug("user data:%pK, vdev id:%d, reason code:%d", + user_data, p2p_lo_event->vdev_id, + p2p_lo_event->reason_code); psoc = user_data; if (!psoc) { - cfg80211_err("psoc is null"); + osif_err("psoc is null"); return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, p2p_lo_event->vdev_id, WLAN_P2P_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is null"); + osif_err("osif_priv is null"); goto fail; } wdev = osif_priv->wdev; if (!wdev) { - cfg80211_err("wireless dev is null"); + osif_err("wireless dev is null"); goto fail; } @@ -213,14 +205,14 @@ static void wlan_p2p_lo_event_callback(void *user_data, QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX, GFP_KERNEL); if (!vendor_event) { - cfg80211_err("cfg80211_vendor_event_alloc failed"); + osif_err("cfg80211_vendor_event_alloc failed"); goto fail; } if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, p2p_lo_event->reason_code)) { - cfg80211_err("nla put failed"); + osif_err("nla put failed"); kfree_skb(vendor_event); goto fail; } @@ -261,38 +253,38 @@ static void wlan_p2p_event_callback(void *user_data, struct vdev_osif_priv *osif_priv; struct wireless_dev *wdev; - cfg80211_debug("user data:%pK, vdev id:%d, event type:%d", - user_data, p2p_event->vdev_id, p2p_event->roc_event); + osif_debug("user data:%pK, vdev id:%d, event type:%d", + user_data, p2p_event->vdev_id, p2p_event->roc_event); psoc = user_data; if (!psoc) { - cfg80211_err("psoc is null"); + osif_err("psoc is null"); return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, p2p_event->vdev_id, WLAN_P2P_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is null"); + osif_err("osif_priv is null"); goto fail; } wdev = osif_priv->wdev; if (!wdev) { - cfg80211_err("wireless dev is null"); + osif_err("wireless dev is null"); goto fail; } chan = ieee80211_get_channel(wdev->wiphy, wlan_chan_to_freq(p2p_event->chan)); if (!chan) { - cfg80211_err("channel conversion failed"); + osif_err("channel conversion failed"); goto fail; } @@ -304,7 +296,7 @@ static void wlan_p2p_event_callback(void *user_data, cfg80211_remain_on_channel_expired(wdev, p2p_event->cookie, chan, GFP_KERNEL); } else { - cfg80211_err("Invalid p2p event"); + osif_err("Invalid p2p event"); } fail: @@ -316,7 +308,7 @@ QDF_STATUS p2p_psoc_enable(struct wlan_objmgr_psoc *psoc) struct p2p_start_param start_param; if (!psoc) { - cfg80211_err("psoc null"); + osif_err("psoc null"); return QDF_STATUS_E_INVAL; } @@ -334,7 +326,7 @@ QDF_STATUS p2p_psoc_enable(struct wlan_objmgr_psoc *psoc) QDF_STATUS p2p_psoc_disable(struct wlan_objmgr_psoc *psoc) { if (!psoc) { - cfg80211_err("psoc null"); + osif_err("psoc null"); return QDF_STATUS_E_INVAL; } @@ -352,19 +344,19 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, int ret; if (!vdev) { - cfg80211_err("invalid vdev object"); + osif_err("invalid vdev object"); return -EINVAL; } if (!chan) { - cfg80211_err("invalid channel"); + osif_err("invalid channel"); return -EINVAL; } psoc = wlan_vdev_get_psoc(vdev); vdev_id = wlan_vdev_get_id(vdev); if (!psoc) { - cfg80211_err("psoc handle is NULL"); + osif_err("psoc handle is NULL"); return -EINVAL; } @@ -372,15 +364,15 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, roc_req.duration = duration; roc_req.vdev_id = (uint32_t)vdev_id; - ret = policy_mgr_is_chan_ok_for_dnbs(psoc, roc_req.chan, &ok); + ret = policy_mgr_is_chan_ok_for_dnbs(psoc, chan->center_freq, &ok); if (QDF_IS_STATUS_ERROR(ret)) { - cfg80211_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", - ret); + osif_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", + ret); return -EINVAL; } if (!ok) { - cfg80211_err("channel%d not OK for DNBS", roc_req.chan); + osif_err("channel%d not OK for DNBS", roc_req.chan); return -EINVAL; } @@ -394,13 +386,13 @@ int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_psoc *psoc; if (!vdev) { - cfg80211_err("invalid vdev object"); + osif_err("invalid vdev object"); return -EINVAL; } psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { - cfg80211_err("psoc handle is NULL"); + osif_err("psoc handle is NULL"); return -EINVAL; } @@ -420,19 +412,19 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, uint32_t channel = 0; if (!vdev) { - cfg80211_err("invalid vdev object"); + osif_err("invalid vdev object"); return -EINVAL; } if (chan) channel = (uint32_t)wlan_freq_to_chan(chan->center_freq); else - cfg80211_debug("NULL chan, set channel to 0"); + osif_debug("NULL chan, set channel to 0"); psoc = wlan_vdev_get_psoc(vdev); vdev_id = wlan_vdev_get_id(vdev); if (!psoc) { - cfg80211_err("psoc handle is NULL"); + osif_err("psoc handle is NULL"); return -EINVAL; } @@ -444,15 +436,16 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, int ret; bool ok; - ret = policy_mgr_is_chan_ok_for_dnbs(psoc, channel, &ok); + ret = policy_mgr_is_chan_ok_for_dnbs( + psoc, wlan_chan_to_freq(channel), &ok); if (QDF_IS_STATUS_ERROR(ret)) { - cfg80211_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", - ret); + osif_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", + ret); return -EINVAL; } if (!ok) { - cfg80211_err("Rejecting mgmt_tx for channel:%d as DNSC is set", - channel); + osif_err("Rejecting mgmt_tx for channel:%d as DNSC is set", + channel); return -EINVAL; } } @@ -476,13 +469,13 @@ int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_psoc *psoc; if (!vdev) { - cfg80211_err("invalid vdev object"); + osif_err("invalid vdev object"); return -EINVAL; } psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { - cfg80211_err("psoc handle is NULL"); + osif_err("psoc handle is NULL"); return -EINVAL; } diff --git a/drivers/staging/qcacld-3.0/os_if/tdls/inc/wlan_cfg80211_tdls.h b/drivers/staging/qcacld-3.0/os_if/tdls/inc/wlan_cfg80211_tdls.h index 29059b5bd26f96a5afa0395dcd9fe77b0854212d..1ba308dc8884b31dfe3d208e6db0a3f7dab3d021 100644 --- a/drivers/staging/qcacld-3.0/os_if/tdls/inc/wlan_cfg80211_tdls.h +++ b/drivers/staging/qcacld-3.0/os_if/tdls/inc/wlan_cfg80211_tdls.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -51,6 +52,7 @@ * @mgmt_tx_completion_status: Tdls mgmt frames TX completion status code * @tdls_user_cmd_len: tdls user command written buffer length * @tdls_antenna_switch_status: return status after antenna switch + * @tdls_user_cmd_in_progress: tdls user command progress status. */ struct osif_tdls_vdev { struct completion tdls_add_peer_comp; @@ -64,6 +66,7 @@ struct osif_tdls_vdev { uint32_t mgmt_tx_completion_status; uint32_t tdls_user_cmd_len; int tdls_antenna_switch_status; + bool tdls_user_cmd_in_progress; }; /** diff --git a/drivers/staging/qcacld-3.0/os_if/tdls/src/wlan_cfg80211_tdls.c b/drivers/staging/qcacld-3.0/os_if/tdls/src/wlan_cfg80211_tdls.c index ef8f401f5243c3a3f48c294233c5a97eb9b53c89..7136e946fb1ab7d68a7a97f3479ec12c7c89008b 100644 --- a/drivers/staging/qcacld-3.0/os_if/tdls/src/wlan_cfg80211_tdls.c +++ b/drivers/staging/qcacld-3.0/os_if/tdls/src/wlan_cfg80211_tdls.c @@ -33,12 +33,8 @@ #include #include #include -#include -#ifdef QCA_SUPPORT_CP_STATS #include "wlan_cfg80211_mc_cp_stats.h" -#endif - -#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS) +#include "sir_api.h" #define TDLS_MAX_NO_OF_2_4_CHANNELS 14 @@ -48,8 +44,9 @@ static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac) static const uint8_t temp_mac[QDF_MAC_ADDR_SIZE] = {0}; if (!qdf_mem_cmp(mac, temp_mac, QDF_MAC_ADDR_SIZE)) { - cfg80211_debug("Invalid Mac address " QDF_MAC_ADDR_STR " cmd declined.", - QDF_MAC_ADDR_ARRAY(mac)); + osif_debug("Invalid Mac address " QDF_MAC_ADDR_FMT + " cmd declined.", + QDF_MAC_ADDR_REF(mac)); return -EINVAL; } @@ -63,14 +60,14 @@ QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev) osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is NULL!"); + osif_err("osif_priv is NULL!"); return QDF_STATUS_E_FAULT; } - cfg80211_debug("initialize tdls os if layer private structure"); + osif_debug("initialize tdls os if layer private structure"); tdls_priv = qdf_mem_malloc(sizeof(*tdls_priv)); if (!tdls_priv) { - cfg80211_err("failed to allocate memory for tdls_priv"); + osif_err("failed to allocate memory for tdls_priv"); return QDF_STATUS_E_NOMEM; } init_completion(&tdls_priv->tdls_add_peer_comp); @@ -92,11 +89,11 @@ void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev) osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is NULL!"); + osif_err("osif_priv is NULL!"); return; } - cfg80211_debug("deinitialize tdls os if layer private structure"); + osif_debug("deinitialize tdls os if layer private structure"); if (osif_priv->osif_tdls) qdf_mem_free(osif_priv->osif_tdls); osif_priv->osif_tdls = NULL; @@ -117,7 +114,7 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_psoc *psoc) osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); goto release_ref; } tdls_priv = osif_priv->osif_tdls; @@ -125,23 +122,23 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_psoc *psoc) reinit_completion(&tdls_priv->tdls_teardown_comp); status = ucfg_tdls_teardown_links(psoc); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_teardown_links failed err %d", status); + osif_err("ucfg_tdls_teardown_links failed err %d", status); goto release_ref; } - cfg80211_debug("Wait for tdls teardown completion. Timeout %u ms", - WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); + osif_debug("Wait for tdls teardown completion. Timeout %u ms", + WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); rc = wait_for_completion_timeout( &tdls_priv->tdls_teardown_comp, msecs_to_jiffies(WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS)); if (0 == rc) { - cfg80211_err(" Teardown Completion timed out rc: %ld", rc); + osif_err(" Teardown Completion timed out rc: %ld", rc); goto release_ref; } - cfg80211_debug("TDLS teardown completion status %ld ", rc); + osif_debug("TDLS teardown completion status %ld ", rc); release_ref: wlan_objmgr_vdev_release_ref(vdev, @@ -163,12 +160,12 @@ hdd_notify_sta_connect(uint8_t session_id, QDF_STATUS status; if (!vdev) { - cfg80211_err("vdev is NULL"); + osif_err("vdev is NULL"); return; } status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("can't get vdev"); + osif_err("can't get vdev"); return; } @@ -188,13 +185,13 @@ void hdd_notify_sta_disconnect(uint8_t session_id, QDF_STATUS status; if (!vdev) { - cfg80211_err("vdev is NULL"); + osif_err("vdev is NULL"); return; } status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("can't get vdev"); + osif_err("can't get vdev"); return; } @@ -221,18 +218,18 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev, if (status) return status; - cfg80211_debug("Add TDLS peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); + osif_debug("Add TDLS peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req)); if (!add_peer_req) { - cfg80211_err("Failed to allocate tdls add peer request mem"); + osif_err("Failed to allocate tdls add peer request mem"); return -EINVAL; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif_tdls_vdev or osif_priv is NULL for the current vdev"); + osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev"); status = -EINVAL; goto error; } @@ -244,7 +241,7 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev, reinit_completion(&tdls_priv->tdls_add_peer_comp); status = ucfg_tdls_add_peer(vdev, add_peer_req); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_add_peer returned err %d", status); + osif_err("ucfg_tdls_add_peer returned err %d", status); status = -EIO; goto error; } @@ -253,14 +250,14 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev, &tdls_priv->tdls_add_peer_comp, msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); if (!rc) { - cfg80211_err("timeout for tdls add peer indication %ld", rc); + osif_err("timeout for tdls add peer indication %ld", rc); status = -EPERM; goto error; } if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) { - cfg80211_err("tdls add peer failed, status:%d", - tdls_priv->tdls_add_peer_status); + osif_err("tdls add peer failed, status:%d", + tdls_priv->tdls_add_peer_status); status = -EPERM; } error: @@ -311,11 +308,11 @@ tdls_calc_channels_from_staparams(struct tdls_update_peer_params *req_info, wifi_chan_index = ((dest_chans[j] <= WLAN_CHANNEL_14) ? 1 : 4); no_of_channels = src_chans[i + 1]; - cfg80211_debug("i:%d,j:%d,k:%d,[%d]:%d,index:%d,chans_num: %d", - i, j, k, j, - dest_chans[j], - wifi_chan_index, - no_of_channels); + osif_debug("i:%d,j:%d,k:%d,[%d]:%d,index:%d,chans_num: %d", + i, j, k, j, + dest_chans[j], + wifi_chan_index, + no_of_channels); for (k = 1; k <= no_of_channels && j < WLAN_MAC_MAX_SUPP_CHANNELS - 1; k++) { @@ -326,21 +323,21 @@ tdls_calc_channels_from_staparams(struct tdls_update_peer_params *req_info, else continue; - cfg80211_debug("i: %d, j: %d, k: %d, [%d]: %d", - i, j, k, j + 1, dest_chans[j + 1]); + osif_debug("i: %d, j: %d, k: %d, [%d]: %d", + i, j, k, j + 1, dest_chans[j + 1]); j += 1; } } num_unique_channels = j + 1; - cfg80211_debug("Unique Channel List: supported_channels "); + osif_debug("Unique Channel List: supported_channels "); for (i = 0; i < num_unique_channels; i++) - cfg80211_debug("[%d]: %d,", i, dest_chans[i]); + osif_debug("[%d]: %d,", i, dest_chans[i]); - if (MAX_CHANNEL < num_unique_channels) - num_unique_channels = MAX_CHANNEL; + if (num_unique_channels > NUM_CHANNELS) + num_unique_channels = NUM_CHANNELS; req_info->supported_channels_len = num_unique_channels; - cfg80211_debug("After removing duplcates supported_channels_len: %d", - req_info->supported_channels_len); + osif_debug("After removing duplcates supported_channels_len: %d", + req_info->supported_channels_len); } static void @@ -349,12 +346,12 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, { int i; - cfg80211_debug("sta cap %d, uapsd_queue %d, max_sp %d", - params->capability, - params->uapsd_queues, params->max_sp); + osif_debug("sta cap %d, uapsd_queue %d, max_sp %d", + params->capability, + params->uapsd_queues, params->max_sp); if (!req_info) { - cfg80211_err("reg_info is NULL"); + osif_err("reg_info is NULL"); return; } req_info->capability = params->capability; @@ -365,9 +362,9 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, tdls_calc_channels_from_staparams(req_info, params); if (params->supported_oper_classes_len > WLAN_MAX_SUPP_OPER_CLASSES) { - cfg80211_debug("received oper classes:%d, resetting it to max supported: %d", - params->supported_oper_classes_len, - WLAN_MAX_SUPP_OPER_CLASSES); + osif_debug("received oper classes:%d, resetting it to max supported: %d", + params->supported_oper_classes_len, + WLAN_MAX_SUPP_OPER_CLASSES); params->supported_oper_classes_len = WLAN_MAX_SUPP_OPER_CLASSES; } @@ -404,12 +401,12 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, qdf_mem_copy(req_info->supported_rates, params->supported_rates, req_info->supported_rates_len); - cfg80211_debug("Supported Rates with Length %d", - req_info->supported_rates_len); + osif_debug("Supported Rates with Length %d", + req_info->supported_rates_len); for (i = 0; i < req_info->supported_rates_len; i++) - cfg80211_debug("[%d]: %0x", i, - req_info->supported_rates[i]); + osif_debug("[%d]: %0x", i, + req_info->supported_rates[i]); } if (params->vht_capa) { @@ -422,7 +419,7 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))) req_info->is_qos_wmm_sta = true; if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) { - cfg80211_debug("TDLS peer pmf capable"); + osif_debug("TDLS peer pmf capable"); req_info->is_pmf = 1; } } @@ -442,19 +439,19 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev, if (status) return status; - cfg80211_debug("Update TDLS peer " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(mac)); + osif_debug("Update TDLS peer " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac)); req_info = qdf_mem_malloc(sizeof(*req_info)); if (!req_info) { - cfg80211_err("Failed to allocate tdls add peer request mem"); + osif_err("Failed to allocate tdls add peer request mem"); return -EINVAL; } wlan_cfg80211_tdls_extract_params(req_info, params); osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); status = -EINVAL; goto error; } @@ -465,7 +462,7 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev, reinit_completion(&tdls_priv->tdls_add_peer_comp); status = ucfg_tdls_update_peer(vdev, req_info); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_update_peer returned err %d", status); + osif_err("ucfg_tdls_update_peer returned err %d", status); status = -EIO; goto error; } @@ -474,14 +471,14 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev, &tdls_priv->tdls_add_peer_comp, msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); if (!rc) { - cfg80211_err("timeout for tdls update peer indication %ld", rc); + osif_err("timeout for tdls update peer indication %ld", rc); status = -EPERM; goto error; } if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) { - cfg80211_err("tdls update peer failed, status:%d", - tdls_priv->tdls_add_peer_status); + osif_err("tdls update peer failed, status:%d", + tdls_priv->tdls_add_peer_status); status = -EPERM; } error: @@ -540,11 +537,11 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, tdls_mode = TDLS_SUPPORT_IMP_MODE; return 0; default: - cfg80211_err("Invalid TDLS trigger mode"); + osif_err("Invalid TDLS trigger mode"); return -EINVAL; } - cfg80211_notice("cfg80211 tdls trigger mode %d", trigger_mode); + osif_notice("cfg80211 tdls trigger mode %d", trigger_mode); set_mode_params.source = TDLS_SET_MODE_SOURCE_USER; set_mode_params.tdls_mode = tdls_mode; set_mode_params.update_last = false; @@ -570,12 +567,12 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, return status; if (NL80211_TDLS_DISCOVERY_REQ == oper) { - cfg80211_warn( + osif_warn( "We don't support in-driver setup/teardown/discovery"); return -ENOTSUPP; } - cfg80211_debug("%s start", tdls_oper_to_str(oper)); + osif_debug("%s start", tdls_oper_to_str(oper)); cmd = tdls_oper_to_cmd(oper); switch (oper) { case NL80211_TDLS_ENABLE_LINK: @@ -583,8 +580,8 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, case NL80211_TDLS_SETUP: status = ucfg_tdls_oper(vdev, peer, cmd); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("%s fail %d", - tdls_oper_to_str(oper), status); + osif_err("%s fail %d", + tdls_oper_to_str(oper), status); status = -EIO; goto error; } @@ -593,7 +590,7 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); status = -EINVAL; goto error; } @@ -601,7 +598,7 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, reinit_completion(&tdls_priv->tdls_del_peer_comp); status = ucfg_tdls_oper(vdev, peer, cmd); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_disable_link fail %d", status); + osif_err("ucfg_tdls_disable_link fail %d", status); status = -EIO; goto error; } @@ -610,12 +607,12 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, &tdls_priv->tdls_del_peer_comp, msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA)); if (!rc) { - cfg80211_err("timeout for tdls disable link %ld", rc); + osif_err("timeout for tdls disable link %ld", rc); status = -EPERM; } break; default: - cfg80211_err("unsupported event %d", oper); + osif_err("unsupported event %d", oper); status = -ENOTSUPP; } @@ -630,60 +627,51 @@ void wlan_cfg80211_tdls_rx_callback(void *user_data, struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; struct wireless_dev *wdev; - uint16_t freq; psoc = user_data; if (!psoc) { - cfg80211_err("psoc is null"); + osif_err("psoc is null"); return; } vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rx_frame->vdev_id, WLAN_TDLS_NB_ID); if (!vdev) { - cfg80211_err("vdev is null"); + osif_err("vdev is null"); return; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv) { - cfg80211_err("osif_priv is null"); + osif_err("osif_priv is null"); goto fail; } wdev = osif_priv->wdev; if (!wdev) { - cfg80211_err("wdev is null"); + osif_err("wdev is null"); goto fail; } - if (rx_frame->rx_chan <= TDLS_MAX_NO_OF_2_4_CHANNELS) - freq = ieee80211_channel_to_frequency( - rx_frame->rx_chan, NL80211_BAND_2GHZ); - else - freq = ieee80211_channel_to_frequency( - rx_frame->rx_chan, NL80211_BAND_5GHZ); - - cfg80211_notice("Indicate frame over nl80211, vdev id:%d, idx:%d", - rx_frame->vdev_id, wdev->netdev->ifindex); + osif_notice("Indicate frame over nl80211, vdev id:%d, idx:%d", + rx_frame->vdev_id, wdev->netdev->ifindex); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, - NL80211_RXMGMT_FLAG_ANSWERED); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, - NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); #else - cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, - rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC); + cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC); #endif /* LINUX_VERSION_CODE */ fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } -#ifdef QCA_SUPPORT_CP_STATS static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev) { int ret = 0, i; @@ -694,7 +682,7 @@ static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev) vdev, bcast_mac.bytes, &ret); if (ret || !rssi_info) { - cfg80211_err("get peer rssi fail"); + osif_err("get peer rssi fail"); wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info); return; } @@ -705,11 +693,6 @@ static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev) wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info); } -#else -static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev) -{ -} -#endif int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, char *buf, int buflen) @@ -722,33 +705,56 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif_tdls_vdev or osif_priv is NULL for the current vdev"); + osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev"); return -EINVAL; } tdls_priv = osif_priv->osif_tdls; + /* + * We shouldn't use completion_done here for checking for completion + * as this will always return false, as tdls_user_cmd_comp.done will + * remain in init state always. So, the very first command will also + * not work. + * In general completion_done is used to check if there are multiple + * threads waiting on the complete event that's why it will return true + * only when tdls_user_cmd_comp.done is set with complete() + * In general completion_done will return true only when + * tdls_user_cmd_comp.done is set that will happen in complete(). + * Also, if there is already a thread waiting for wait_for_completion, + * this function will + * return true only after the wait timer is over or condition is + * met as wait_for_completion will hold out the hold lock and will + * will prevent completion_done from returning. + * Better to use a flag to determine command condition. + */ + if (tdls_priv->tdls_user_cmd_in_progress) { + osif_err("TDLS user cmd still in progress, reject this one"); + return -EBUSY; + } + + tdls_priv->tdls_user_cmd_in_progress = true; wlan_cfg80211_update_tdls_peers_rssi(vdev); reinit_completion(&tdls_priv->tdls_user_cmd_comp); status = ucfg_tdls_get_all_peers(vdev, buf, buflen); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_get_all_peers failed err %d", status); + osif_err("ucfg_tdls_get_all_peers failed err %d", status); len = scnprintf(buf, buflen, "\nucfg_tdls_send_mgmt failed\n"); goto error_get_tdls_peers; } - cfg80211_debug("Wait for tdls_user_cmd_comp. Timeout %u ms", - WAIT_TIME_FOR_TDLS_USER_CMD); + osif_debug("Wait for tdls_user_cmd_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_USER_CMD); rc = wait_for_completion_timeout( &tdls_priv->tdls_user_cmd_comp, msecs_to_jiffies(WAIT_TIME_FOR_TDLS_USER_CMD)); if (0 == rc) { - cfg80211_err("TDLS user cmd get all peers timed out rc %ld", - rc); + osif_err("TDLS user cmd get all peers timed out rc %ld", + rc); len = scnprintf(buf, buflen, "\nTDLS user cmd get all peers timed out\n"); goto error_get_tdls_peers; @@ -757,6 +763,7 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, len = tdls_priv->tdls_user_cmd_len; error_get_tdls_peers: + tdls_priv->tdls_user_cmd_in_progress = false; return len; } @@ -781,7 +788,7 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); return -EINVAL; } @@ -789,8 +796,8 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, /* make sure doesn't call send_mgmt() while it is pending */ if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) { - cfg80211_err(QDF_MAC_ADDR_STR " action %d couldn't sent, as one is pending. return EBUSY", - QDF_MAC_ADDR_ARRAY(peer_mac), action_code); + osif_err(QDF_MAC_ADDR_FMT " action %d couldn't sent, as one is pending. return EBUSY", + QDF_MAC_ADDR_REF(peer_mac), action_code); return -EBUSY; } @@ -827,14 +834,14 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, reinit_completion(&tdls_priv->tdls_mgmt_comp); status = ucfg_tdls_send_mgmt_frame(&mgmt_req); if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_send_mgmt failed err %d", status); + osif_err("ucfg_tdls_send_mgmt failed err %d", status); status = -EIO; tdls_priv->mgmt_tx_completion_status = false; goto error_mgmt_req; } - cfg80211_debug("Wait for tdls_mgmt_comp. Timeout %u ms", - WAIT_TIME_FOR_TDLS_MGMT); + osif_debug("Wait for tdls_mgmt_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_MGMT); rc = wait_for_completion_timeout( &tdls_priv->tdls_mgmt_comp, @@ -842,18 +849,18 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, if ((0 == rc) || (QDF_STATUS_SUCCESS != tdls_priv->mgmt_tx_completion_status)) { - cfg80211_err("%s rc %ld mgmtTxCompletionStatus %u", - !rc ? "Mgmt Tx Completion timed out" : - "Mgmt Tx Completion failed", - rc, tdls_priv->mgmt_tx_completion_status); + osif_err("%s rc %ld mgmtTxCompletionStatus %u", + !rc ? "Mgmt Tx Completion timed out" : + "Mgmt Tx Completion failed", + rc, tdls_priv->mgmt_tx_completion_status); tdls_priv->mgmt_tx_completion_status = false; status = -EINVAL; goto error_mgmt_req; } - cfg80211_debug("Mgmt Tx Completion status %ld TxCompletion %u", - rc, tdls_priv->mgmt_tx_completion_status); + osif_debug("Mgmt Tx Completion status %ld TxCompletion %u", + rc, tdls_priv->mgmt_tx_completion_status); if (TDLS_SETUP_RESPONSE == action_code || TDLS_SETUP_CONFIRM == action_code) { @@ -879,13 +886,13 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) unsigned long rc; if (!vdev) { - cfg80211_err("vdev is NULL"); + osif_err("vdev is NULL"); return -EAGAIN; } osif_priv = wlan_vdev_get_ospriv(vdev); if (!osif_priv || !osif_priv->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); ret = -EINVAL; goto error; } @@ -894,7 +901,7 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) reinit_completion(&tdls_priv->tdls_antenna_switch_comp); ret = ucfg_tdls_antenna_switch(vdev, mode); if (QDF_IS_STATUS_ERROR(ret)) { - cfg80211_err("ucfg_tdls_antenna_switch failed err %d", ret); + osif_err("ucfg_tdls_antenna_switch failed err %d", ret); ret = -EAGAIN; goto error; } @@ -903,13 +910,13 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) &tdls_priv->tdls_antenna_switch_comp, msecs_to_jiffies(WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH)); if (!rc) { - cfg80211_err("timeout for tdls antenna switch %ld", rc); + osif_err("timeout for tdls antenna switch %ld", rc); ret = -EAGAIN; goto error; } ret = tdls_priv->tdls_antenna_switch_status; - cfg80211_debug("tdls antenna switch status:%d", ret); + osif_debug("tdls antenna switch status:%d", ret); error: return ret; } @@ -933,7 +940,7 @@ wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind) osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - cfg80211_debug("Indication to request TDLS setup"); + osif_debug("Indication to request TDLS setup"); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, ind->peer_mac, NL80211_TDLS_SETUP, false, GFP_KERNEL); @@ -946,7 +953,7 @@ wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind) osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - cfg80211_debug("Teardown reason %d", ind->reason); + osif_debug("Teardown reason %d", ind->reason); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, ind->peer_mac, NL80211_TDLS_TEARDOWN, ind->reason, GFP_KERNEL); @@ -960,13 +967,13 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, struct osif_tdls_vdev *tdls_priv; if (!ind || !ind->vdev) { - cfg80211_err("ind: %pK", ind); + osif_err("ind: %pK", ind); return; } osif_vdev = wlan_vdev_get_ospriv(ind->vdev); if (!osif_vdev || !osif_vdev->osif_tdls) { - cfg80211_err("osif priv or tdls priv is NULL"); + osif_err("osif priv or tdls priv is NULL"); return; } diff --git a/drivers/staging/qcacld-3.0/uapi/linux/pktlog_ac_fmt.h b/drivers/staging/qcacld-3.0/uapi/linux/pktlog_ac_fmt.h index 47964ec60410d72995abf0639490b263b65648d7..c85f555454a86a93e433ae7f62c1fcefd86c32f4 100644 --- a/drivers/staging/qcacld-3.0/uapi/linux/pktlog_ac_fmt.h +++ b/drivers/staging/qcacld-3.0/uapi/linux/pktlog_ac_fmt.h @@ -141,8 +141,11 @@ enum { #define PKTLOG_TYPE_SMART_ANTENNA 9 #define PKTLOG_TYPE_SW_EVENT 10 #define PKTLOG_TYPE_PKT_DUMP 11 -/* From WIN definations */ +/* Command to process Monitor status ring (Rx) buffers */ +#define PKTLOG_TYPE_RX_STATBUF 22 +/* Command to process PPDU Tx buffers from CE */ #define PKTLOG_TYPE_LITE_T2H 23 +/* Command to process PPDU Rx buffers from Monitor status ring */ #define PKTLOG_TYPE_LITE_RX 24 #define PKTLOG_TYPE_MAX 25